From 874197d940def1edb9509a294916892096b8b558 Mon Sep 17 00:00:00 2001 From: ruby0b <106119328+ruby0b@users.noreply.github.com> Date: Fri, 10 Jan 2025 01:27:49 +0100 Subject: [PATCH 0001/1218] Linux: move the user home Archipelago dir to $XDG_DATA_HOME (#4347) This affects builds with non-writable installation directories. Instead of saving data in ~/Archipelago we now use $XDG_DATA_HOME/Archipelago (defaulting to ~/.local/share/Archipelago). If ~/Archipelago still exists we move it to the new location and link ~/Archipelago to it. Motivation: This follows the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/latest/) to at least some degree and doesn't clutter the user's home directory. --- Utils.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Utils.py b/Utils.py index 574c006b503d..43b3ef9c8ff9 100644 --- a/Utils.py +++ b/Utils.py @@ -152,8 +152,15 @@ def home_path(*path: str) -> str: if hasattr(home_path, 'cached_path'): pass elif sys.platform.startswith('linux'): - home_path.cached_path = os.path.expanduser('~/Archipelago') - os.makedirs(home_path.cached_path, 0o700, exist_ok=True) + xdg_data_home = os.getenv('XDG_DATA_HOME', os.path.expanduser('~/.local/share')) + home_path.cached_path = xdg_data_home + '/Archipelago' + if not os.path.isdir(home_path.cached_path): + legacy_home_path = os.path.expanduser('~/Archipelago') + if os.path.isdir(legacy_home_path): + os.renames(legacy_home_path, home_path.cached_path) + os.symlink(home_path.cached_path, legacy_home_path) + else: + os.makedirs(home_path.cached_path, 0o700, exist_ok=True) else: # not implemented home_path.cached_path = local_path() # this will generate the same exceptions we got previously From 894a8571ee1a3bbbdc16bb6a64192819779ba7b3 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 10 Jan 2025 20:21:02 +0100 Subject: [PATCH 0002/1218] kvui: add autocompleting new hint text input (#3535) Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> Co-authored-by: Silvris <58583688+Silvris@users.noreply.github.com> --- data/client.kv | 5 ++++ kvui.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/data/client.kv b/data/client.kv index 3455f2a23657..f0f31769e411 100644 --- a/data/client.kv +++ b/data/client.kv @@ -147,3 +147,8 @@ rectangle: self.x-2, self.y-2, self.width+4, self.height+4 : pos_hint: {'center_y': 0.5, 'center_x': 0.5} + + size_hint_y: None + height: dp(30) + multiline: False + write_tab: False diff --git a/kvui.py b/kvui.py index b2ab004e274a..f47e45b93c07 100644 --- a/kvui.py +++ b/kvui.py @@ -40,7 +40,7 @@ from kivy.base import ExceptionHandler, ExceptionManager from kivy.clock import Clock from kivy.factory import Factory -from kivy.properties import BooleanProperty, ObjectProperty +from kivy.properties import BooleanProperty, ObjectProperty, NumericProperty from kivy.metrics import dp from kivy.effects.scroll import ScrollEffect from kivy.uix.widget import Widget @@ -64,6 +64,7 @@ from kivy.uix.recycleview.layout import LayoutSelectionBehavior from kivy.animation import Animation from kivy.uix.popup import Popup +from kivy.uix.dropdown import DropDown from kivy.uix.image import AsyncImage fade_in_animation = Animation(opacity=0, duration=0) + Animation(opacity=1, duration=0.25) @@ -305,6 +306,50 @@ def apply_selection(self, rv, index, is_selected): """ Respond to the selection of items in the view. """ self.selected = is_selected + +class AutocompleteHintInput(TextInput): + min_chars = NumericProperty(3) + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.dropdown = DropDown() + self.dropdown.bind(on_select=lambda instance, x: setattr(self, 'text', x)) + self.bind(on_text_validate=self.on_message) + + def on_message(self, instance): + App.get_running_app().commandprocessor("!hint "+instance.text) + + def on_text(self, instance, value): + if len(value) >= self.min_chars: + self.dropdown.clear_widgets() + ctx: context_type = App.get_running_app().ctx + if not ctx.game: + return + item_names = ctx.item_names._game_store[ctx.game].values() + + def on_press(button: Button): + split_text = MarkupLabel(text=button.text).markup + return self.dropdown.select("".join(text_frag for text_frag in split_text + if not text_frag.startswith("["))) + lowered = value.lower() + for item_name in item_names: + try: + index = item_name.lower().index(lowered) + except ValueError: + pass # substring not found + else: + text = escape_markup(item_name) + text = text[:index] + "[b]" + text[index:index+len(value)]+"[/b]"+text[index+len(value):] + btn = Button(text=text, size_hint_y=None, height=dp(30), markup=True) + btn.bind(on_release=on_press) + self.dropdown.add_widget(btn) + if not self.dropdown.attach_to: + self.dropdown.open(self) + else: + self.dropdown.dismiss() + + class HintLabel(RecycleDataViewBehavior, BoxLayout): selected = BooleanProperty(False) striped = BooleanProperty(False) @@ -570,8 +615,10 @@ def connect_bar_validate(sender): # show Archipelago tab if other logging is present self.tabs.add_widget(panel) - hint_panel = self.add_client_tab("Hints", HintLog(self.json_to_kivy_parser)) + hint_panel = self.add_client_tab("Hints", HintLayout()) + self.hint_log = HintLog(self.json_to_kivy_parser) self.log_panels["Hints"] = hint_panel.content + hint_panel.content.add_widget(self.hint_log) if len(self.logging_pairs) == 1: self.tabs.default_tab_text = "Archipelago" @@ -698,7 +745,7 @@ def set_new_energy_link_value(self): def update_hints(self): hints = self.ctx.stored_data.get(f"_read_hints_{self.ctx.team}_{self.ctx.slot}", []) - self.log_panels["Hints"].refresh_hints(hints) + self.hint_log.refresh_hints(hints) # default F1 keybind, opens a settings menu, that seems to break the layout engine once closed def open_settings(self, *largs): @@ -753,6 +800,17 @@ def fix_heights(self): element.height = element.texture_size[1] +class HintLayout(BoxLayout): + orientation = "vertical" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + boxlayout = BoxLayout(orientation="horizontal", size_hint_y=None, height=dp(30)) + boxlayout.add_widget(Label(text="New Hint:", size_hint_x=None, size_hint_y=None, height=dp(30))) + boxlayout.add_widget(AutocompleteHintInput()) + self.add_widget(boxlayout) + + status_names: typing.Dict[HintStatus, str] = { HintStatus.HINT_FOUND: "Found", HintStatus.HINT_UNSPECIFIED: "Unspecified", @@ -769,6 +827,7 @@ def fix_heights(self): } + class HintLog(RecycleView): header = { "receiving": {"text": "[u]Receiving Player[/u]"}, From 043ba418ecbe73420cb0b8ebcc4960e1702db96d Mon Sep 17 00:00:00 2001 From: lordlou <87331798+lordlou@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:46:17 -0500 Subject: [PATCH 0003/1218] SM generate without rom (#3460) * - SM now displays message when getting an item outside for someone else (fills ROM item table) This is dependant on modifications done to sm_randomizer_rom project * First working MultiWorld SM * some missing things: - player name inject in ROM and get in client - end game get from ROM in client - send self item to server - add player names table in ROM * replaced CollectionState inheritance from SMBoolManager with a composition of an array of it (required to generation more than one SM world, which is still fails but is better) * - reenabled balancing * post rebase fixes * updated SmClient.py * + added VariaRandomizer LICENSE * + added sm_randomizer_rom project (which builds sm.ips) * Moved VariaRandomizer and sm_randomizer_rom projects inside worlds/sm and done some cleaning * properly revert change made to CollectionState and more cleaning * Fixed multiworld support patch not working with VariaRandomizer's * missing file commit * Fixed syntax error in unused code to satisfy Linter * Revert "Fixed multiworld support patch not working with VariaRandomizer's" This reverts commit fb3ca18528bb331995e3d3051648c8f84d04c08b. * many fixes and improovement - fixed seeded generation - fixed broken logic when more than one SM world - added missing rules for inter-area transitions - added basic patch presence for logic - added DoorManager init call to reflect present patches for logic - moved CollectionState addition out of BaseClasses into SM world - added condition to apply progitempool presorting only if SM world is present - set Bosses item id to None to prevent them going into multidata - now use get_game_players * first working (most of the time) progression generation for SM using VariaRandomizer's rules, items, locations and accessPoint (as regions) * first working single-world randomized SM rom patches * - SM now displays message when getting an item outside for someone else (fills ROM item table) This is dependant on modifications done to sm_randomizer_rom project * First working MultiWorld SM * some missing things: - player name inject in ROM and get in client - end game get from ROM in client - send self item to server - add player names table in ROM * replaced CollectionState inheritance from SMBoolManager with a composition of an array of it (required to generation more than one SM world, which is still fails but is better) * - reenabled balancing * post rebase fixes * updated SmClient.py * + added VariaRandomizer LICENSE * + added sm_randomizer_rom project (which builds sm.ips) * Moved VariaRandomizer and sm_randomizer_rom projects inside worlds/sm and done some cleaning * properly revert change made to CollectionState and more cleaning * Fixed multiworld support patch not working with VariaRandomizer's * missing file commit * Fixed syntax error in unused code to satisfy Linter * Revert "Fixed multiworld support patch not working with VariaRandomizer's" This reverts commit fb3ca18528bb331995e3d3051648c8f84d04c08b. * many fixes and improovement - fixed seeded generation - fixed broken logic when more than one SM world - added missing rules for inter-area transitions - added basic patch presence for logic - added DoorManager init call to reflect present patches for logic - moved CollectionState addition out of BaseClasses into SM world - added condition to apply progitempool presorting only if SM world is present - set Bosses item id to None to prevent them going into multidata - now use get_game_players * Fixed multiworld support patch not working with VariaRandomizer's Added stage_fill_hook to set morph first in progitempool Added back VariaRandomizer's standard patches * + added missing files from variaRandomizer project * + added missing variaRandomizer files (custom sprites) + started integrating VariaRandomizer options (WIP) * Some fixes for player and server name display - fixed player name of 16 characters reading too far in SM client - fixed 12 bytes SM player name limit (now 16) - fixed server name not being displayed in SM when using server cheat ( now displays RECEIVED FROM ARCHIPELAGO) - request: temporarly changed default seed names displayed in SM main menu to OWTCH * Fixed Goal completion not triggering in smClient * integrated VariaRandomizer's options into AP (WIP) - startAP is working - door rando is working - skillset is working * - fixed itemsounds.ips crash by always including nofanfare.ips into multiworld.ips (itemsounds is now always applied and "itemsounds" preset must always be "off") * skillset are now instanced per player instead of being a singleton class * RomPatches are now instanced per player instead of being a singleton class * DoorManager is now instanced per player instead of being a singleton class * - fixed the last bugs that prevented generation of >1 SM world * fixed crash when no skillset preset is specified in randoPreset (default to "casual") * maxDifficulty support and itemsounds removal - added support for maxDifficulty - removed itemsounds patch as its always applied from multiworld patch for now * Fixed bad merge * Post merge adaptation * fixed player name length fix that got lost with the merge * fixed generation with other game type than SM * added default randoPreset json for SM in playerSettings.yaml * fixed broken SM client following merge * beautified json skillset presets * Fixed ArchipelagoSmClient not building * Fixed conflict between mutliworld patch and beam_doors_plms patch - doorsColorsRando now working * SM generation now outputs APBP - Fixed paths for patches and presets when frozen * added missing file and fixed multithreading issue * temporarily set data_version = 0 * more work - added support for AP starting items - fixed client crash with gamemode being None - patch.py "compatible_version" is now 3 * commited missing asm files fixed start item reserve breaking game (was using bad write offset when patching) * Nothing item are now handled game-side. the game will now skip displaying a message box for received Nothing item (but the client will still receive it). fixed crash in SMClient when loosing connection to SNI * fixed No Energy Item missing its ID fixed Plando * merge post fixes * fixed start item Grapple, XRay and Reserve HUD, as well as graphic beams (except ice palette color) * fixed freeze in blue brinstar caused by Varia's custom PLM not being filled with proper Multiworld PLM address (altLocsAddresses) * fixed start item x-ray HUD display * Fixed start items being sent by the server (is all handled in ROM) Start items are now not removed from itempool anymore Nothing Item is now local_items so no player will ever pickup Nothing. Doing so reduces contribution of this world to the Multiworld the more Nothing there is though. Fixed crash (and possibly passing but broken) at generation where the static list of IPSPatches used by all SM worlds was being modified * fixed settings that could be applied to any SM players * fixed auth to server only using player name (now does as ALTTP to authenticate) * - fixed End Credits broken text * added non SM item name display * added all supported SM options in playerSettings.yaml * fixed locations needing a list of parent regions (now generate a region for each location with one-way exits to each (previously) parent region did some cleaning (mainly reverts on unnecessary core classes * minor setting fixes and tweaks - merged Area and lightArea settings - made missileQty, superQty and powerBombQty use value from 10 to 90 and divide value by float(10) when generating - fixed inverted layoutPatch setting * added option start_inventory_removes_from_pool fixed option names formatting fixed lint errors small code and repo cleanup * Hopefully fixed ROR2 that could not send any items * - fixed missing required change to ROR2 * fixed 0 hp when respawning without having ever saved (start items were not updating the save checksum) * fixed typo with doors_colors_rando * fixed checksum * added custom sprites for off-world items (progression or not) the original AP sprite was made with PierRoulette's SM Item Sprite Utility by ijwu * - added missing change following upstream merge - changed patch filename extension from apbp to apm3 so patch can be used with the new client * added morph placement options: early means local and sphere 1 * fixed failing unit tests * - fixed broken custom_preset options * - big cleanup to remove unnecessary or unsupported features * - more cleanup * - moved sm_randomizer_rom and all always applied patches into an external project that outputs basepatch.ips - small cleanup * - added comment to refer to project for generating basepatch.ips (https://github.com/lordlou/SMBasepatch) * fixed g4_skip patch that can be not applied if hud is enabled * - fixed off world sprite that can have broken graphics (restricted to use only first 2 palette) * - updated basepatch to reflect g4_skip removal - moved more asm files to SMBasepatch project * - tourian grey doors at baby metroid are now always flashing (allowing to go back if needed) * fixed wrong path if using built as exe * - cleaned exposed maxDifficulty options - removed always enabled Knows * Merged LttPClient and SMClient into SNIClient * added varia_custom Preset Option that fetch a preset (read from a new varia_custom_preset Option) from varia's web service * small doc precision * - added death_link support - fixed broken Goal Completion - post merge fix * - removed now useless presets * - fixed bad internal mapping with maxDiff - increases maxDiff if only Bosses is preventing beating the game * - added support for lowercase custom preset sections (knows, settings and controller) - fixed controller settings not applying to ROM * - fixed death loop when dying with Door rando, bomb or speed booster as starting items - varia's backup save should now be usable (automatically enabled when doing door rando) * -added docstring for generated yaml * fixed bad merge * fixed broken infinity max difficulty * commented debug prints * adjusted credits to mark progression speed and difficulty as Non Available * added support for more than 255 players (will print Archipelago for higher player number) * fixed missing cleanup * added support for 65535 different player names in ROM * fixed generations failing when only bosses are unreachable * - replaced setting maxDiff to infinity with a bool only affecting boss logics if only bosses are left to finish * fixed failling generations when using 'fun' settings Accessibility checks are forced to 'items' if restricted locations are used by VARIA following usage of 'fun' settings * fixed debug logger * removed unsupported "suits_restriction" option * fixed generations failing when only bosses are unreachable (using a less intrusive approach for AP) * - fixed deathlink emptying reserves - added death_link_survive option that lets player survive when receiving a deathlink if the have non-empty reserves * - merged death_link and death_link_survive options * fixed death_link * added a fallback default starting location instead of failing generation if an invalid one was chosen * added Nothing and NoEnergy as hint blacklist added missing NoEnergy as local items and removed it from progression * SM Varia can now generate without ROM * removed stage_assert_generate --- worlds/sm/Rom.py | 45 ++++++++++++++- worlds/sm/__init__.py | 30 ++++------ worlds/sm/variaRandomizer/randomizer.py | 26 +++------ worlds/sm/variaRandomizer/rom/ips.py | 19 ++++++- worlds/sm/variaRandomizer/rom/rom.py | 62 ++++++++++++++++++++- worlds/sm/variaRandomizer/rom/rompatcher.py | 9 +-- 6 files changed, 142 insertions(+), 49 deletions(-) diff --git a/worlds/sm/Rom.py b/worlds/sm/Rom.py index ac516ae48b75..c5b6645ed8ef 100644 --- a/worlds/sm/Rom.py +++ b/worlds/sm/Rom.py @@ -4,18 +4,59 @@ import json import Utils from Utils import read_snes_rom -from worlds.Files import APDeltaPatch +from worlds.Files import APPatchExtension, APProcedurePatch, APTokenMixin, APTokenTypes from .variaRandomizer.utils.utils import openFile SMJUHASH = '21f3e98df4780ee1c667b84e57d88675' SM_ROM_MAX_PLAYERID = 65535 SM_ROM_PLAYERDATA_COUNT = 202 -class SMDeltaPatch(APDeltaPatch): +class SMPatchExtensions(APPatchExtension): + game = "Super Metroid" + + @staticmethod + def write_crc(caller: APProcedurePatch, rom: bytes) -> bytes: + def checksum_mirror_sum(start, length, mask = 0x800000): + while not(length & mask) and mask: + mask >>= 1 + + part1 = sum(start[:mask]) & 0xFFFF + part2 = 0 + + next_length = length - mask + if next_length: + part2 = checksum_mirror_sum(start[mask:], next_length, mask >> 1) + + while (next_length < mask): + next_length += next_length + part2 += part2 + + return (part1 + part2) & 0xFFFF + + def write_bytes(buffer, startaddress: int, values): + buffer[startaddress:startaddress + len(values)] = values + + buffer = bytearray(rom) + crc = checksum_mirror_sum(buffer, len(buffer)) + inv = crc ^ 0xFFFF + write_bytes(buffer, 0x7FDC, [inv & 0xFF, (inv >> 8) & 0xFF, crc & 0xFF, (crc >> 8) & 0xFF]) + return bytes(buffer) + +class SMProcedurePatch(APProcedurePatch, APTokenMixin): hash = SMJUHASH game = "Super Metroid" patch_file_ending = ".apsm" + procedure = [ + ("apply_tokens", ["token_data.bin"]), + ("write_crc", []) + ] + + def write_tokens(self, patches): + for addr, data in patches.items(): + self.write_token(APTokenTypes.WRITE, addr, bytes(data)) + self.write_file("token_data.bin", self.get_token_binary()) + @classmethod def get_source_data(cls) -> bytes: return get_base_rom_bytes() diff --git a/worlds/sm/__init__.py b/worlds/sm/__init__.py index 160b7e4ec78b..5d53270d61a4 100644 --- a/worlds/sm/__init__.py +++ b/worlds/sm/__init__.py @@ -17,7 +17,7 @@ from .Options import SMOptions from .Client import SMSNIClient -from .Rom import get_base_rom_path, SM_ROM_MAX_PLAYERID, SM_ROM_PLAYERDATA_COUNT, SMDeltaPatch, get_sm_symbols +from .Rom import SM_ROM_MAX_PLAYERID, SM_ROM_PLAYERDATA_COUNT, SMProcedurePatch, get_sm_symbols import Utils from .variaRandomizer.logic.smboolmanager import SMBoolManager @@ -40,7 +40,7 @@ class RomFile(settings.SNESRomPath): """File name of the v1.0 J rom""" description = "Super Metroid (JU) ROM" copy_to = "Super Metroid (JU).sfc" - md5s = [SMDeltaPatch.hash] + md5s = [SMProcedurePatch.hash] rom_file: RomFile = RomFile(RomFile.copy_to) @@ -120,12 +120,6 @@ def __init__(self, world: MultiWorld, player: int): self.locations = {} super().__init__(world, player) - @classmethod - def stage_assert_generate(cls, multiworld: MultiWorld): - rom_file = get_base_rom_path() - if not os.path.exists(rom_file): - raise FileNotFoundError(rom_file) - def generate_early(self): Logic.factory('vanilla') @@ -802,23 +796,19 @@ def resolve_symbols_to_file_offset_based_dict(byte_edits_arr: List[ByteEdit]) -> romPatcher.end() def generate_output(self, output_directory: str): - self.variaRando.args.rom = get_base_rom_path() - outfilebase = self.multiworld.get_out_file_name_base(self.player) - outputFilename = os.path.join(output_directory, f"{outfilebase}.sfc") - try: - self.variaRando.PatchRom(outputFilename, self.APPrePatchRom, self.APPostPatchRom) - self.write_crc(outputFilename) + patcher = self.variaRando.PatchRom(self.APPrePatchRom, self.APPostPatchRom) self.rom_name = self.romName + + patch = SMProcedurePatch(player=self.player, player_name=self.multiworld.player_name[self.player]) + patch.write_tokens(patcher.romFile.getPatchDict()) + rom_path = os.path.join(output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}" + f"{patch.patch_file_ending}") + patch.write(rom_path) + except: raise - else: - patch = SMDeltaPatch(os.path.splitext(outputFilename)[0] + SMDeltaPatch.patch_file_ending, player=self.player, - player_name=self.multiworld.player_name[self.player], patched_path=outputFilename) - patch.write() finally: - if os.path.exists(outputFilename): - os.unlink(outputFilename) self.rom_name_available_event.set() # make sure threading continues and errors are collected def checksum_mirror_sum(self, start, length, mask = 0x800000): diff --git a/worlds/sm/variaRandomizer/randomizer.py b/worlds/sm/variaRandomizer/randomizer.py index 8a7a2ea0e2a5..22712aa44255 100644 --- a/worlds/sm/variaRandomizer/randomizer.py +++ b/worlds/sm/variaRandomizer/randomizer.py @@ -680,7 +680,7 @@ def forceArg(arg, value, msg, altValue=None, webArg=None, webValue=None): #dumpErrorMsg(args.output, self.randoExec.errorMsg) raise Exception("Can't generate " + self.fileName + " with the given parameters: {}".format(self.randoExec.errorMsg)) - def PatchRom(self, outputFilename, customPrePatchApply = None, customPostPatchApply = None): + def PatchRom(self, customPrePatchApply = None, customPostPatchApply = None) -> RomPatcher: args = self.args optErrMsgs = self.optErrMsgs @@ -758,9 +758,9 @@ def PatchRom(self, outputFilename, customPrePatchApply = None, customPostPatchAp # args.output is not None: generate local json named args.output if args.rom is not None: # patch local rom - romFileName = args.rom - shutil.copyfile(romFileName, outputFilename) - romPatcher = RomPatcher(settings=patcherSettings, romFileName=outputFilename, magic=args.raceMagic, player=self.player) + # romFileName = args.rom + # shutil.copyfile(romFileName, outputFilename) + romPatcher = RomPatcher(settings=patcherSettings, magic=args.raceMagic, player=self.player) else: romPatcher = RomPatcher(settings=patcherSettings, magic=args.raceMagic) @@ -779,24 +779,12 @@ def PatchRom(self, outputFilename, customPrePatchApply = None, customPostPatchAp #msg = randoExec.errorMsg msg = '' - if args.rom is None: # web mode - data = romPatcher.romFile.data - self.fileName = '{}.sfc'.format(self.fileName) - data["fileName"] = self.fileName - # error msg in json to be displayed by the web site - data["errorMsg"] = msg - # replaced parameters to update stats in database - if len(self.forcedArgs) > 0: - data["forcedArgs"] = self.forcedArgs - with open(outputFilename, 'w') as jsonFile: - json.dump(data, jsonFile) - else: # CLI mode - if msg != "": - print(msg) + return romPatcher + except Exception as e: import traceback traceback.print_exc(file=sys.stdout) - raise Exception("Error patching {}: ({}: {})".format(outputFilename, type(e).__name__, e)) + raise Exception("Error patching: ({}: {})".format(type(e).__name__, e)) #dumpErrorMsg(args.output, msg) # if stuck == True: diff --git a/worlds/sm/variaRandomizer/rom/ips.py b/worlds/sm/variaRandomizer/rom/ips.py index dd3f30a3ac0b..add187a86afe 100644 --- a/worlds/sm/variaRandomizer/rom/ips.py +++ b/worlds/sm/variaRandomizer/rom/ips.py @@ -21,10 +21,23 @@ def __init__(self, patchDict=None): def toDict(self): ret = {} for record in self.records: - if 'rle_count' in record: - ret[record['address']] = [int.from_bytes(record['data'],'little')]*record['rle_count'] + if record['address'] in ret.keys(): + if 'rle_count' in record: + if len(ret[record['address']]) > record['rle_count']: + ret[record['address']][:record['rle_count']] = [int.from_bytes(record['data'],'little')]*record['rle_count'] + else: + ret[record['address']] = [int.from_bytes(record['data'],'little')]*record['rle_count'] + else: + size = len(record['data']) + if len(ret[record['address']]) > size: + ret[record['address']][:size] = [int(b) for b in record['data']] + else: + ret[record['address']] = [int(b) for b in record['data']] else: - ret[record['address']] = [int(b) for b in record['data']] + if 'rle_count' in record: + ret[record['address']] = [int.from_bytes(record['data'],'little')]*record['rle_count'] + else: + ret[record['address']] = [int(b) for b in record['data']] return ret @staticmethod diff --git a/worlds/sm/variaRandomizer/rom/rom.py b/worlds/sm/variaRandomizer/rom/rom.py index 37c15698a2f6..f0f37b76a37e 100644 --- a/worlds/sm/variaRandomizer/rom/rom.py +++ b/worlds/sm/variaRandomizer/rom/rom.py @@ -86,7 +86,67 @@ def fillToNextBank(self): self.seek(self.maxAddress + BANK_SIZE - off - 1) self.writeByte(0xff) assert (self.maxAddress % BANK_SIZE) == 0 - + +class FakeROM(ROM): + # to have the same code for real ROM and the webservice + def __init__(self, data={}): + super(FakeROM, self).__init__() + self.data = data + self.ipsPatches = [] + + def write(self, bytes): + for byte in bytes: + self.data[self.address] = byte + self.inc() + + def read(self, byteCount): + bytes = [] + for i in range(byteCount): + bytes.append(self.data[self.address]) + self.inc() + + return bytes + + def ipsPatch(self, ipsPatches): + self.ipsPatches += ipsPatches + + # generate ips from self data + def ips(self): + groupedData = {} + startAddress = -1 + prevAddress = -1 + curData = [] + for address in sorted(self.data): + if address == prevAddress + 1: + curData.append(self.data[address]) + prevAddress = address + else: + if len(curData) > 0: + groupedData[startAddress] = curData + startAddress = address + prevAddress = address + curData = [self.data[startAddress]] + if startAddress != -1: + groupedData[startAddress] = curData + + return IPS_Patch(groupedData) + + # generate final IPS for web patching with first the IPS patches, then written data + def close(self): + self.mergedIPS = IPS_Patch() + for ips in self.ipsPatches: + self.mergedIPS.append(ips) + self.mergedIPS.append(self.ips()) + #patchData = mergedIPS.encode() + #self.data = {} + #self.data["ips"] = base64.b64encode(patchData).decode() + #if mergedIPS.truncate_length is not None: + # self.data["truncate_length"] = mergedIPS.truncate_length + #self.data["max_size"] = mergedIPS.max_size + + def getPatchDict(self): + return self.mergedIPS.toDict() + class RealROM(ROM): def __init__(self, name): super(RealROM, self).__init__() diff --git a/worlds/sm/variaRandomizer/rom/rompatcher.py b/worlds/sm/variaRandomizer/rom/rompatcher.py index 2dcf554a0065..a350764a9c0e 100644 --- a/worlds/sm/variaRandomizer/rom/rompatcher.py +++ b/worlds/sm/variaRandomizer/rom/rompatcher.py @@ -7,7 +7,7 @@ from ..utils.objectives import Objectives from ..graph.graph_utils import GraphUtils, getAccessPoint, locIdsByAreaAddresses, graphAreas from ..logic.logic import Logic -from ..rom.rom import RealROM, snes_to_pc, pc_to_snes +from ..rom.rom import FakeROM, snes_to_pc, pc_to_snes from ..rom.addresses import Addresses from ..rom.rom_patches import RomPatches from ..patches.patchaccess import PatchAccess @@ -52,10 +52,10 @@ class RomPatcher: def __init__(self, settings=None, romFileName=None, magic=None, player=0): self.log = log.get('RomPatcher') self.settings = settings - self.romFileName = romFileName + #self.romFileName = romFileName self.patchAccess = PatchAccess() self.race = None - self.romFile = RealROM(romFileName) + self.romFile = FakeROM() #if magic is not None: # from rom.race_mode import RaceModePatcher # self.race = RaceModePatcher(self, magic) @@ -312,7 +312,7 @@ def applyIPSPatches(self): self.applyStartAP(self.settings["startLocation"], plms, doors) self.applyPLMs(plms) except Exception as e: - raise Exception("Error patching {}. ({})".format(self.romFileName, e)) + raise Exception("Error patching. ({})".format(e)) def applyIPSPatch(self, patchName, patchDict=None, ipsDir=None): if patchDict is None: @@ -493,6 +493,7 @@ def appendRoomWord(w, data): def commitIPS(self): self.romFile.ipsPatch(self.ipsPatches) + self.ipsPatches = [] def writeSeed(self, seed): random.seed(seed) From 258ea10c529e3ed1b5bfecd19c8aae9e1a54dbf8 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Fri, 10 Jan 2025 15:49:13 -0500 Subject: [PATCH 0004/1218] TUNIC: Modify UT support to make a better pattern (#3860) * Modify UT support to make a better pattern * Handle keyerror for logic_rules option * Missed self.passthrough value setting * Less laziness for passthrough * Remove extra newline * Fix missing using_ut = True, also remove now unnecessary try except since 0.5.1 is out * New UT thing, it goes in this PR because it's been open for 5 months for a very very tiny change --- worlds/tunic/__init__.py | 49 ++++++++++++++++++-------------- worlds/tunic/er_scripts.py | 57 ++++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 51 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 8525a3fc437d..1c326f78bd43 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -90,6 +90,10 @@ class TunicWorld(World): item_link_locations: Dict[int, Dict[str, List[Tuple[int, str]]]] = {} player_item_link_locations: Dict[str, List[Location]] + using_ut: bool # so we can check if we're using UT only once + passthrough: Dict[str, Any] + ut_can_gen_without_yaml = True # class var that tells it to ignore the player yaml + def generate_early(self) -> None: if self.options.logic_rules >= LogicRules.option_no_major_glitches: self.options.laurels_zips.value = LaurelsZips.option_true @@ -113,23 +117,28 @@ def generate_early(self) -> None: # Universal tracker stuff, shouldn't do anything in standard gen if hasattr(self.multiworld, "re_gen_passthrough"): if "TUNIC" in self.multiworld.re_gen_passthrough: - passthrough = self.multiworld.re_gen_passthrough["TUNIC"] - self.options.start_with_sword.value = passthrough["start_with_sword"] - self.options.keys_behind_bosses.value = passthrough["keys_behind_bosses"] - self.options.sword_progression.value = passthrough["sword_progression"] - self.options.ability_shuffling.value = passthrough["ability_shuffling"] - self.options.laurels_zips.value = passthrough["laurels_zips"] - self.options.ice_grappling.value = passthrough["ice_grappling"] - self.options.ladder_storage.value = passthrough["ladder_storage"] - self.options.ladder_storage_without_items = passthrough["ladder_storage_without_items"] - self.options.lanternless.value = passthrough["lanternless"] - self.options.maskless.value = passthrough["maskless"] - self.options.hexagon_quest.value = passthrough["hexagon_quest"] - self.options.entrance_rando.value = passthrough["entrance_rando"] - self.options.shuffle_ladders.value = passthrough["shuffle_ladders"] + self.using_ut = True + self.passthrough = self.multiworld.re_gen_passthrough["TUNIC"] + self.options.start_with_sword.value = self.passthrough["start_with_sword"] + self.options.keys_behind_bosses.value = self.passthrough["keys_behind_bosses"] + self.options.sword_progression.value = self.passthrough["sword_progression"] + self.options.ability_shuffling.value = self.passthrough["ability_shuffling"] + self.options.laurels_zips.value = self.passthrough["laurels_zips"] + self.options.ice_grappling.value = self.passthrough["ice_grappling"] + self.options.ladder_storage.value = self.passthrough["ladder_storage"] + self.options.ladder_storage_without_items = self.passthrough["ladder_storage_without_items"] + self.options.lanternless.value = self.passthrough["lanternless"] + self.options.maskless.value = self.passthrough["maskless"] + self.options.hexagon_quest.value = self.passthrough["hexagon_quest"] + self.options.entrance_rando.value = self.passthrough["entrance_rando"] + self.options.shuffle_ladders.value = self.passthrough["shuffle_ladders"] self.options.fixed_shop.value = self.options.fixed_shop.option_false self.options.laurels_location.value = self.options.laurels_location.option_anywhere - self.options.combat_logic.value = passthrough["combat_logic"] + self.options.combat_logic.value = self.passthrough["combat_logic"] + else: + self.using_ut = False + else: + self.using_ut = False @classmethod def stage_generate_early(cls, multiworld: MultiWorld) -> None: @@ -331,12 +340,10 @@ def create_regions(self) -> None: self.ability_unlocks = randomize_ability_unlocks(self.random, self.options) # stuff for universal tracker support, can be ignored for standard gen - if hasattr(self.multiworld, "re_gen_passthrough"): - if "TUNIC" in self.multiworld.re_gen_passthrough: - passthrough = self.multiworld.re_gen_passthrough["TUNIC"] - self.ability_unlocks["Pages 24-25 (Prayer)"] = passthrough["Hexagon Quest Prayer"] - self.ability_unlocks["Pages 42-43 (Holy Cross)"] = passthrough["Hexagon Quest Holy Cross"] - self.ability_unlocks["Pages 52-53 (Icebolt)"] = passthrough["Hexagon Quest Icebolt"] + if self.using_ut: + self.ability_unlocks["Pages 24-25 (Prayer)"] = self.passthrough["Hexagon Quest Prayer"] + self.ability_unlocks["Pages 42-43 (Holy Cross)"] = self.passthrough["Hexagon Quest Holy Cross"] + self.ability_unlocks["Pages 52-53 (Icebolt)"] = self.passthrough["Hexagon Quest Icebolt"] # Ladders and Combat Logic uses ER rules with vanilla connections for easier maintenance if self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic: diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index aa5833b4db36..ed9fc0120ddc 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -177,7 +177,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal logic_tricks: Tuple[bool, int, int] = (laurels_zips, ice_grappling, ladder_storage) # marking that you don't immediately have laurels - if laurels_location == "10_fairies" and not hasattr(world.multiworld, "re_gen_passthrough"): + if laurels_location == "10_fairies" and not world.using_ut: has_laurels = False shop_count = 6 @@ -191,9 +191,8 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal break # If using Universal Tracker, restore portal_map. Could be cleaner, but it does not matter for UT even a little bit - if hasattr(world.multiworld, "re_gen_passthrough"): - if "TUNIC" in world.multiworld.re_gen_passthrough: - portal_map = portal_mapping.copy() + if world.using_ut: + portal_map = portal_mapping.copy() # create separate lists for dead ends and non-dead ends for portal in portal_map: @@ -232,25 +231,24 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal plando_connections = world.seed_groups[world.options.entrance_rando.value]["plando"] # universal tracker support stuff, don't need to care about region dependency - if hasattr(world.multiworld, "re_gen_passthrough"): - if "TUNIC" in world.multiworld.re_gen_passthrough: - plando_connections.clear() - # universal tracker stuff, won't do anything in normal gen - for portal1, portal2 in world.multiworld.re_gen_passthrough["TUNIC"]["Entrance Rando"].items(): - portal_name1 = "" - portal_name2 = "" - - for portal in portal_mapping: - if portal.scene_destination() == portal1: - portal_name1 = portal.name - # connected_regions.update(add_dependent_regions(portal.region, logic_rules)) - if portal.scene_destination() == portal2: - portal_name2 = portal.name - # connected_regions.update(add_dependent_regions(portal.region, logic_rules)) - # shops have special handling - if not portal_name2 and portal2 == "Shop, Previous Region_": - portal_name2 = "Shop Portal" - plando_connections.append(PlandoConnection(portal_name1, portal_name2, "both")) + if world.using_ut: + plando_connections.clear() + # universal tracker stuff, won't do anything in normal gen + for portal1, portal2 in world.passthrough["Entrance Rando"].items(): + portal_name1 = "" + portal_name2 = "" + + for portal in portal_mapping: + if portal.scene_destination() == portal1: + portal_name1 = portal.name + # connected_regions.update(add_dependent_regions(portal.region, logic_rules)) + if portal.scene_destination() == portal2: + portal_name2 = portal.name + # connected_regions.update(add_dependent_regions(portal.region, logic_rules)) + # shops have special handling + if not portal_name2 and portal2 == "Shop, Previous Region_": + portal_name2 = "Shop Portal" + plando_connections.append(PlandoConnection(portal_name1, portal_name2, "both")) non_dead_end_regions = set() for region_name, region_info in world.er_regions.items(): @@ -362,7 +360,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal # if we have plando connections, our connected regions may change somewhat connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks) - if fixed_shop and not hasattr(world.multiworld, "re_gen_passthrough"): + if fixed_shop and not world.using_ut: portal1 = None for portal in two_plus: if portal.scene_destination() == "Overworld Redux, Windmill_": @@ -392,7 +390,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal fail_count = 0 while len(connected_regions) < len(non_dead_end_regions): # if this is universal tracker, just break immediately and move on - if hasattr(world.multiworld, "re_gen_passthrough"): + if world.using_ut: break # if the connected regions length stays unchanged for too long, it's stuck in a loop # should, hopefully, only ever occur if someone plandos connections poorly @@ -445,9 +443,8 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal random_object.shuffle(two_plus) # for universal tracker, we want to skip shop gen - if hasattr(world.multiworld, "re_gen_passthrough"): - if "TUNIC" in world.multiworld.re_gen_passthrough: - shop_count = 0 + if world.using_ut: + shop_count = 0 for i in range(shop_count): portal1 = two_plus.pop() @@ -462,7 +459,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal # connect dead ends to random non-dead ends # none of the key events are in dead ends, so we don't need to do gate_before_switch while len(dead_ends) > 0: - if hasattr(world.multiworld, "re_gen_passthrough"): + if world.using_ut: break portal1 = two_plus.pop() portal2 = dead_ends.pop() @@ -470,7 +467,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal # then randomly connect the remaining portals to each other # every region is accessible, so gate_before_switch is not necessary while len(two_plus) > 1: - if hasattr(world.multiworld, "re_gen_passthrough"): + if world.using_ut: break portal1 = two_plus.pop() portal2 = two_plus.pop() From 96b500679d263859dc4efb2d3b56385bc65fd84b Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:40:50 -0500 Subject: [PATCH 0005/1218] LTTP: Add missing GT Pre-Moldorm Bomb Wall Logic (#4440) --- worlds/alttp/Rules.py | 4 ++-- worlds/alttp/test/dungeons/TestGanonsTower.py | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index a664f8ac9b79..386e0b0e9e11 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -592,9 +592,9 @@ def global_rules(multiworld: MultiWorld, player: int): lambda state: can_kill_most_things(state, player, 8) and has_fire_source(state, player) and state.multiworld.get_entrance('Ganons Tower Torch Rooms', player).parent_region.dungeon.bosses['middle'].can_defeat(state)) set_rule(multiworld.get_location('Ganons Tower - Mini Helmasaur Key Drop', player), lambda state: can_kill_most_things(state, player, 1)) set_rule(multiworld.get_location('Ganons Tower - Pre-Moldorm Chest', player), - lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 7)) + lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 7) and can_use_bombs(state, player)) set_rule(multiworld.get_entrance('Ganons Tower Moldorm Door', player), - lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 8)) + lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 8) and can_use_bombs(state, player)) set_rule(multiworld.get_entrance('Ganons Tower Moldorm Gap', player), lambda state: state.has('Hookshot', player) and state.multiworld.get_entrance('Ganons Tower Moldorm Gap', player).parent_region.dungeon.bosses['top'].can_defeat(state)) set_defeat_dungeon_boss_rule(multiworld.get_location('Agahnim 2', player)) diff --git a/worlds/alttp/test/dungeons/TestGanonsTower.py b/worlds/alttp/test/dungeons/TestGanonsTower.py index 08274d0fe7d9..4b8fc4c295b2 100644 --- a/worlds/alttp/test/dungeons/TestGanonsTower.py +++ b/worlds/alttp/test/dungeons/TestGanonsTower.py @@ -130,19 +130,21 @@ def testGanonsTower(self): ["Ganons Tower - Pre-Moldorm Chest", False, []], ["Ganons Tower - Pre-Moldorm Chest", False, [], ['Progressive Bow']], + ["Ganons Tower - Pre-Moldorm Chest", False, [], ['Bomb Upgrade (50)']], ["Ganons Tower - Pre-Moldorm Chest", False, [], ['Big Key (Ganons Tower)']], ["Ganons Tower - Pre-Moldorm Chest", False, [], ['Lamp', 'Fire Rod']], - ["Ganons Tower - Pre-Moldorm Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp']], - ["Ganons Tower - Pre-Moldorm Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod']], + ["Ganons Tower - Pre-Moldorm Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp']], + ["Ganons Tower - Pre-Moldorm Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod']], ["Ganons Tower - Validation Chest", False, []], ["Ganons Tower - Validation Chest", False, [], ['Hookshot']], ["Ganons Tower - Validation Chest", False, [], ['Progressive Bow']], + ["Ganons Tower - Validation Chest", False, [], ['Bomb Upgrade (50)']], ["Ganons Tower - Validation Chest", False, [], ['Big Key (Ganons Tower)']], ["Ganons Tower - Validation Chest", False, [], ['Lamp', 'Fire Rod']], ["Ganons Tower - Validation Chest", False, [], ['Progressive Sword', 'Hammer']], - ["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp', 'Hookshot', 'Progressive Sword']], - ["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Hookshot', 'Progressive Sword']], - ["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp', 'Hookshot', 'Hammer']], - ["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Hookshot', 'Hammer']], + ["Ganons Tower - Validation Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp', 'Hookshot', 'Progressive Sword']], + ["Ganons Tower - Validation Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Hookshot', 'Progressive Sword']], + ["Ganons Tower - Validation Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp', 'Hookshot', 'Hammer']], + ["Ganons Tower - Validation Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Hookshot', 'Hammer']], ]) \ No newline at end of file From 112bfe0933742e45c5c423e303235a9b8a433440 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Fri, 10 Jan 2025 16:48:15 -0500 Subject: [PATCH 0006/1218] TUNIC: Logic for Beneath the Vault Bridge Switch #4432 --- worlds/tunic/er_rules.py | 2 +- worlds/tunic/rules.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index 6e9ae551dba2..f7568df81e49 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -1675,7 +1675,7 @@ def set_er_location_rules(world: "TunicWorld") -> None: # Beneath the Vault set_rule(world.get_location("Beneath the Fortress - Bridge"), - lambda state: has_melee(state, player) or state.has_any({laurels, fire_wand}, player)) + lambda state: has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player)) # Quarry set_rule(world.get_location("Quarry - [Central] Above Ladder Dash Chest"), diff --git a/worlds/tunic/rules.py b/worlds/tunic/rules.py index 30b7cee9d07b..959376787d0e 100644 --- a/worlds/tunic/rules.py +++ b/worlds/tunic/rules.py @@ -323,7 +323,7 @@ def set_location_rules(world: "TunicWorld") -> None: # Beneath the Vault set_rule(world.get_location("Beneath the Fortress - Bridge"), - lambda state: has_melee(state, player) or state.has_any({laurels, fire_wand}, player)) + lambda state: has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player)) set_rule(world.get_location("Beneath the Fortress - Obscured Behind Waterfall"), lambda state: has_melee(state, player) and has_lantern(state, world)) From c2bd9df0f721cf71b154abe25e128bb9b3b8865e Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 10 Jan 2025 23:28:38 +0100 Subject: [PATCH 0007/1218] Subnautica: fix typo and remove no longer used logger (#4456) --- worlds/subnautica/__init__.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/worlds/subnautica/__init__.py b/worlds/subnautica/__init__.py index c3cf40a7c010..850c23c7dd24 100644 --- a/worlds/subnautica/__init__.py +++ b/worlds/subnautica/__init__.py @@ -1,6 +1,5 @@ from __future__ import annotations -import logging import itertools from typing import List, Dict, Any, cast @@ -10,13 +9,11 @@ from . import locations from . import creatures from . import options -from .items import item_table, group_items, items_by_type, ItemType +from .items import item_table, group_items from .rules import set_rules -logger = logging.getLogger("Subnautica") - -class SubnaticaWeb(WebWorld): +class SubnauticaWeb(WebWorld): tutorials = [Tutorial( "Multiworld Setup Guide", "A guide to setting up the Subnautica randomizer connected to an Archipelago Multiworld", @@ -38,7 +35,7 @@ class SubnauticaWorld(World): You must find a cure for yourself, build an escape rocket, and leave the planet. """ game = "Subnautica" - web = SubnaticaWeb() + web = SubnauticaWeb() item_name_to_id = {data.name: item_id for item_id, data in items.item_table.items()} location_name_to_id = all_locations From d97ee5d209245e436f141d4aae042c454ef631f0 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 10 Jan 2025 23:28:57 +0100 Subject: [PATCH 0008/1218] Core: update certifi (#4453) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 946546cb6961..cd045b874bdd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ schema>=0.7.7 kivy>=2.3.0 bsdiff4>=1.2.4 platformdirs>=4.2.2 -certifi>=2024.8.30 +certifi>=2024.12.14 cython>=3.0.11 cymem>=2.0.8 orjson>=3.10.7 From 29b34ca9fde17cbf697b691dd8136c55db322cc9 Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Fri, 10 Jan 2025 19:31:29 -0500 Subject: [PATCH 0009/1218] =?UTF-8?q?Pok=C3=A9mon=20R/B:=20Fix=20Route=201?= =?UTF-8?q?1-E=20to=20Route-12-W=20logic=20(#4435)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worlds/pokemon_rb/regions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/pokemon_rb/regions.py b/worlds/pokemon_rb/regions.py index 575f4a61ca6f..d4b8a8f50678 100644 --- a/worlds/pokemon_rb/regions.py +++ b/worlds/pokemon_rb/regions.py @@ -1718,7 +1718,7 @@ def create_regions(world): connect(multiworld, player, "Vermilion City", "Vermilion City-Dock", lambda state: state.has("S.S. Ticket", player)) connect(multiworld, player, "Vermilion City", "Route 11") connect(multiworld, player, "Route 12-N", "Route 12-S", lambda state: logic.can_surf(state, world, player)) - connect(multiworld, player, "Route 12-W", "Route 11-E", lambda state: state.has("Poke Flute", player)) + connect(multiworld, player, "Route 12-W", "Route 11-E") connect(multiworld, player, "Route 12-W", "Route 12-N", lambda state: state.has("Poke Flute", player)) connect(multiworld, player, "Route 12-W", "Route 12-S", lambda state: state.has("Poke Flute", player)) connect(multiworld, player, "Route 12-S", "Route 12-Grass", lambda state: logic.can_cut(state, world, player), one_way=True) From adcb2f59ca94bc472cd82f2eb3c96a53ce639cba Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 11 Jan 2025 22:16:01 +0100 Subject: [PATCH 0010/1218] MultiServer: Correct tying of Context.groups (#4460) --- MultiServer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MultiServer.py b/MultiServer.py index 0601e179152c..8aabdea3e2bf 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -444,7 +444,7 @@ def _load(self, decoded_obj: dict, game_data_packages: typing.Dict[str, typing.A self.slot_info = decoded_obj["slot_info"] self.games = {slot: slot_info.game for slot, slot_info in self.slot_info.items()} - self.groups = {slot: slot_info.group_members for slot, slot_info in self.slot_info.items() + self.groups = {slot: set(slot_info.group_members) for slot, slot_info in self.slot_info.items() if slot_info.type == SlotType.group} self.clients = {0: {}} From 70942eda8cec0f3a92bc1ebcb8dba2401f7ed90a Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sat, 11 Jan 2025 22:54:48 -0800 Subject: [PATCH 0011/1218] BizHawkClient: Fix version warning not falling through to regular execution (#4463) --- data/lua/connector_bizhawk_generic.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data/lua/connector_bizhawk_generic.lua b/data/lua/connector_bizhawk_generic.lua index 00021b241f9a..6c5af87e1a67 100644 --- a/data/lua/connector_bizhawk_generic.lua +++ b/data/lua/connector_bizhawk_generic.lua @@ -613,9 +613,11 @@ end) if bizhawk_major < 2 or (bizhawk_major == 2 and bizhawk_minor < 7) then print("Must use BizHawk 2.7.0 or newer") -elseif bizhawk_major > 2 or (bizhawk_major == 2 and bizhawk_minor > 9) then - print("Warning: This version of BizHawk is newer than this script. If it doesn't work, consider downgrading to 2.9.") else + if bizhawk_major > 2 or (bizhawk_major == 2 and bizhawk_minor > 10) then + print("Warning: This version of BizHawk is newer than this script. If it doesn't work, consider downgrading to 2.10.") + end + if emu.getsystemid() == "NULL" then print("No ROM is loaded. Please load a ROM.") while emu.getsystemid() == "NULL" do From 4edca0ce541daf9941a659290145213ce31bf0e9 Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sat, 11 Jan 2025 23:03:31 -0800 Subject: [PATCH 0012/1218] BizHawkClient: Add command to get size of memory domain (#4439) * Mega Man 2: Remove mm2 commands from client if rom size too small --- data/lua/connector_bizhawk_generic.lua | 23 +++++++++++++++++++++++ worlds/_bizhawk/__init__.py | 12 +++++++++++- worlds/mm2/client.py | 11 ++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/data/lua/connector_bizhawk_generic.lua b/data/lua/connector_bizhawk_generic.lua index 6c5af87e1a67..c2e8f91c0d97 100644 --- a/data/lua/connector_bizhawk_generic.lua +++ b/data/lua/connector_bizhawk_generic.lua @@ -121,6 +121,14 @@ Response: Expected Response Type: `HASH_RESPONSE` +- `MEMORY_SIZE` + Returns the size in bytes of the specified memory domain. + + Expected Response Type: `MEMORY_SIZE_RESPONSE` + + Additional Fields: + - `domain` (`string`): The name of the memory domain to check + - `GUARD` Checks a section of memory against `expected_data`. If the bytes starting at `address` do not match `expected_data`, the response will have `value` @@ -216,6 +224,12 @@ Response: Additional Fields: - `value` (`string`): The returned hash +- `MEMORY_SIZE_RESPONSE` + Contains the size in bytes of the specified memory domain. + + Additional Fields: + - `value` (`number`): The size of the domain in bytes + - `GUARD_RESPONSE` The result of an attempted `GUARD` request. @@ -376,6 +390,15 @@ request_handlers = { return res end, + ["MEMORY_SIZE"] = function (req) + local res = {} + + res["type"] = "MEMORY_SIZE_RESPONSE" + res["value"] = memory.getmemorydomainsize(req["domain"]) + + return res + end, + ["GUARD"] = function (req) local res = {} local expected_data = base64.decode(req["expected_data"]) diff --git a/worlds/_bizhawk/__init__.py b/worlds/_bizhawk/__init__.py index 3627f385c2d3..e7b8edc0b6d7 100644 --- a/worlds/_bizhawk/__init__.py +++ b/worlds/_bizhawk/__init__.py @@ -151,7 +151,7 @@ async def ping(ctx: BizHawkContext) -> None: async def get_hash(ctx: BizHawkContext) -> str: - """Gets the system name for the currently loaded ROM""" + """Gets the hash value of the currently loaded ROM""" res = (await send_requests(ctx, [{"type": "HASH"}]))[0] if res["type"] != "HASH_RESPONSE": @@ -160,6 +160,16 @@ async def get_hash(ctx: BizHawkContext) -> str: return res["value"] +async def get_memory_size(ctx: BizHawkContext, domain: str) -> int: + """Gets the size in bytes of the specified memory domain""" + res = (await send_requests(ctx, [{"type": "MEMORY_SIZE", "domain": domain}]))[0] + + if res["type"] != "MEMORY_SIZE_RESPONSE": + raise SyncError(f"Expected response of type MEMORY_SIZE_RESPONSE but got {res['type']}") + + return res["value"] + + async def get_system(ctx: BizHawkContext) -> str: """Gets the system name for the currently loaded ROM""" res = (await send_requests(ctx, [{"type": "SYSTEM"}]))[0] diff --git a/worlds/mm2/client.py b/worlds/mm2/client.py index aaa0813c763a..96c477757dcd 100644 --- a/worlds/mm2/client.py +++ b/worlds/mm2/client.py @@ -214,10 +214,19 @@ class MegaMan2Client(BizHawkClient): last_wily: Optional[int] = None # default to wily 1 async def validate_rom(self, ctx: "BizHawkClientContext") -> bool: - from worlds._bizhawk import RequestFailedError, read + from worlds._bizhawk import RequestFailedError, read, get_memory_size from . import MM2World try: + if (await get_memory_size(ctx.bizhawk_ctx, "PRG ROM")) < 0x3FFB0: + if "pool" in ctx.command_processor.commands: + ctx.command_processor.commands.pop("pool") + if "request" in ctx.command_processor.commands: + ctx.command_processor.commands.pop("request") + if "autoheal" in ctx.command_processor.commands: + ctx.command_processor.commands.pop("autoheal") + return False + game_name, version = (await read(ctx.bizhawk_ctx, [(0x3FFB0, 21, "PRG ROM"), (0x3FFC8, 3, "PRG ROM")])) if game_name[:3] != b"MM2" or version != bytes(MM2World.world_version): From 0fc722cb28b17b155de2d16baef487eaf711766b Mon Sep 17 00:00:00 2001 From: Jouramie <16137441+Jouramie@users.noreply.github.com> Date: Sun, 12 Jan 2025 11:01:02 -0500 Subject: [PATCH 0013/1218] Stardew Valley: Remove seasonal farming event, use regions instead (#4379) --- worlds/stardew_valley/__init__.py | 28 +++---------------- worlds/stardew_valley/logic/farming_logic.py | 15 +++++----- .../strings/ap_names/event_names.py | 4 --- worlds/stardew_valley/test/rules/TestTools.py | 5 +--- 4 files changed, 12 insertions(+), 40 deletions(-) diff --git a/worlds/stardew_valley/__init__.py b/worlds/stardew_valley/__init__.py index 6ba0e35e0a3a..9da650520f05 100644 --- a/worlds/stardew_valley/__init__.py +++ b/worlds/stardew_valley/__init__.py @@ -5,29 +5,23 @@ from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState from Options import PerGameCommonOptions from worlds.AutoWorld import World, WebWorld -from . import rules from .bundles.bundle_room import BundleRoom from .bundles.bundles import get_all_bundles -from .content import content_packs, StardewContent, unpack_content, create_content +from .content import StardewContent, create_content from .early_items import setup_early_items from .items import item_table, create_items, ItemData, Group, items_by_group, get_all_filler_items, remove_limited_amount_packs from .locations import location_table, create_locations, LocationData, locations_by_tag -from .logic.bundle_logic import BundleLogic from .logic.logic import StardewLogic -from .logic.time_logic import MAX_MONTHS from .options import StardewValleyOptions, SeasonRandomization, Goal, BundleRandomization, EnabledFillerBuffs, NumberOfMovementBuffs, \ - BuildingProgression, ExcludeGingerIsland, TrapItems, EntranceRandomization, FarmType, Walnutsanity + BuildingProgression, ExcludeGingerIsland, TrapItems, EntranceRandomization, FarmType from .options.forced_options import force_change_options_if_incompatible from .options.option_groups import sv_option_groups from .options.presets import sv_options_presets from .regions import create_regions from .rules import set_rules -from .stardew_rule import True_, StardewRule, HasProgressionPercent, true_ +from .stardew_rule import True_, StardewRule, HasProgressionPercent from .strings.ap_names.event_names import Event -from .strings.entrance_names import Entrance as EntranceName from .strings.goal_names import Goal as GoalName -from .strings.metal_names import Ore -from .strings.region_names import Region as RegionName, LogicRegion logger = logging.getLogger(__name__) @@ -159,7 +153,7 @@ def create_items(self): self.multiworld.itempool += created_items setup_early_items(self.multiworld, self.options, self.content, self.player, self.random) - self.setup_player_events() + self.setup_logic_events() self.setup_victory() # This is really a best-effort to get the total progression items count. It is mostly used to spread grinds across spheres are push back locations that @@ -199,20 +193,6 @@ def precollect_farm_type_items(self): if self.options.farm_type == FarmType.option_meadowlands and self.options.building_progression & BuildingProgression.option_progressive: self.multiworld.push_precollected(self.create_starting_item("Progressive Coop")) - def setup_player_events(self): - self.setup_action_events() - self.setup_logic_events() - - def setup_action_events(self): - spring_farming = LocationData(None, LogicRegion.spring_farming, Event.spring_farming) - self.create_event_location(spring_farming, true_, Event.spring_farming) - summer_farming = LocationData(None, LogicRegion.summer_farming, Event.summer_farming) - self.create_event_location(summer_farming, true_, Event.summer_farming) - fall_farming = LocationData(None, LogicRegion.fall_farming, Event.fall_farming) - self.create_event_location(fall_farming, true_, Event.fall_farming) - winter_farming = LocationData(None, LogicRegion.winter_farming, Event.winter_farming) - self.create_event_location(winter_farming, true_, Event.winter_farming) - def setup_logic_events(self): def register_event(name: str, region: str, rule: StardewRule): event_location = LocationData(None, region, name) diff --git a/worlds/stardew_valley/logic/farming_logic.py b/worlds/stardew_valley/logic/farming_logic.py index 88523bb85d8e..cb8a55e6b42f 100644 --- a/worlds/stardew_valley/logic/farming_logic.py +++ b/worlds/stardew_valley/logic/farming_logic.py @@ -10,17 +10,16 @@ from .tool_logic import ToolLogicMixin from .. import options from ..stardew_rule import StardewRule, True_, false_ -from ..strings.ap_names.event_names import Event from ..strings.fertilizer_names import Fertilizer -from ..strings.region_names import Region +from ..strings.region_names import Region, LogicRegion from ..strings.season_names import Season from ..strings.tool_names import Tool -farming_event_by_season = { - Season.spring: Event.spring_farming, - Season.summer: Event.summer_farming, - Season.fall: Event.fall_farming, - Season.winter: Event.winter_farming, +farming_region_by_season = { + Season.spring: LogicRegion.spring_farming, + Season.summer: LogicRegion.summer_farming, + Season.fall: LogicRegion.fall_farming, + Season.winter: LogicRegion.winter_farming, } @@ -54,7 +53,7 @@ def can_plant_and_grow_item(self, seasons: Union[str, Tuple[str]]) -> StardewRul if isinstance(seasons, str): seasons = (seasons,) - return self.logic.or_(*(self.logic.received(farming_event_by_season[season]) for season in seasons)) + return self.logic.or_(*(self.logic.region.can_reach(farming_region_by_season[season]) for season in seasons)) def has_island_farm(self) -> StardewRule: if self.options.exclude_ginger_island == options.ExcludeGingerIsland.option_false: diff --git a/worlds/stardew_valley/strings/ap_names/event_names.py b/worlds/stardew_valley/strings/ap_names/event_names.py index 449bb6720964..b7881b3bfd79 100644 --- a/worlds/stardew_valley/strings/ap_names/event_names.py +++ b/worlds/stardew_valley/strings/ap_names/event_names.py @@ -8,9 +8,5 @@ def event(name: str): class Event: victory = event("Victory") - spring_farming = event("Spring Farming") - summer_farming = event("Summer Farming") - fall_farming = event("Fall Farming") - winter_farming = event("Winter Farming") received_walnuts = event("Received Walnuts") diff --git a/worlds/stardew_valley/test/rules/TestTools.py b/worlds/stardew_valley/test/rules/TestTools.py index 5b8975f4e707..31dd5819165e 100644 --- a/worlds/stardew_valley/test/rules/TestTools.py +++ b/worlds/stardew_valley/test/rules/TestTools.py @@ -1,7 +1,7 @@ from collections import Counter from .. import SVTestBase -from ... import Event, options +from ... import options from ...options import ToolProgression, SeasonRandomization from ...strings.entrance_names import Entrance from ...strings.region_names import Region @@ -74,12 +74,10 @@ def test_old_master_cannoli(self): self.assert_rule_true(rule, self.multiworld.state) self.remove(fall) - self.remove(self.create_item(Event.fall_farming)) self.assert_rule_false(rule, self.multiworld.state) self.remove(tuesday) green_house = self.create_item("Greenhouse") - self.collect(self.create_item(Event.fall_farming)) self.multiworld.state.collect(green_house) self.assert_rule_false(rule, self.multiworld.state) @@ -88,7 +86,6 @@ def test_old_master_cannoli(self): self.assertTrue(self.multiworld.get_location("Old Master Cannoli", 1).access_rule(self.multiworld.state)) self.remove(green_house) - self.remove(self.create_item(Event.fall_farming)) self.assert_rule_false(rule, self.multiworld.state) self.remove(friday) From 9928639ce2c64414fd1a96a1d85d63d33d70e073 Mon Sep 17 00:00:00 2001 From: qwint Date: Sun, 12 Jan 2025 11:01:42 -0500 Subject: [PATCH 0014/1218] Docs: Fix Typo in Rich Text Options Flag Documentation (#4462) --- Options.py | 2 +- docs/options api.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Options.py b/Options.py index f4724e9747b0..135a1dcb5398 100644 --- a/Options.py +++ b/Options.py @@ -137,7 +137,7 @@ class Option(typing.Generic[T], metaclass=AssembleOptions): If this is False, the docstring is instead interpreted as plain text, and displayed as-is on the WebHost with whitespace preserved. - If this is None, it inherits the value of `World.rich_text_options_doc`. For + If this is None, it inherits the value of `WebWorld.rich_text_options_doc`. For backwards compatibility, this defaults to False, but worlds are encouraged to set it to True and use reStructuredText for their Option documentation. diff --git a/docs/options api.md b/docs/options api.md index d48a56d6c76d..453cbc7e2d36 100644 --- a/docs/options api.md +++ b/docs/options api.md @@ -95,7 +95,7 @@ user hovers over the yellow "(?)" icon, and included in the YAML templates gener The WebHost can display Option documentation either as plain text with all whitespace preserved (other than the base indentation), or as HTML generated from the standard Python [reStructuredText] format. Although plain text is the default for backwards compatibility, world authors are encouraged to write their Option documentation as -reStructuredText and enable rich text rendering by setting `World.rich_text_options_doc = True`. +reStructuredText and enable rich text rendering by setting `WebWorld.rich_text_options_doc = True`. [reStructuredText]: https://docutils.sourceforge.io/rst.html From 3f935aac13251d3e6780c127592b7542cc65f770 Mon Sep 17 00:00:00 2001 From: Justus Lind Date: Mon, 13 Jan 2025 03:59:16 +1000 Subject: [PATCH 0015/1218] Muse Dash: Change Data storage from a .txt file to a .py file and Filter Webhost Song Lists correctly (#4234) --- worlds/musedash/Items.py | 1 + worlds/musedash/MuseDashCollection.py | 98 +-- worlds/musedash/MuseDashData.py | 615 +++++++++++++++++++ worlds/musedash/MuseDashData.txt | 597 ------------------ worlds/musedash/Options.py | 29 +- worlds/musedash/__init__.py | 9 +- worlds/musedash/test/TestDifficultyRanges.py | 12 +- 7 files changed, 656 insertions(+), 705 deletions(-) create mode 100644 worlds/musedash/MuseDashData.py delete mode 100644 worlds/musedash/MuseDashData.txt diff --git a/worlds/musedash/Items.py b/worlds/musedash/Items.py index 63fd3aa51b94..027a9002d525 100644 --- a/worlds/musedash/Items.py +++ b/worlds/musedash/Items.py @@ -6,6 +6,7 @@ class SongData(NamedTuple): """Special data container to contain the metadata of each song to make filtering work.""" code: Optional[int] + uid: str album: str streamer_mode: bool easy: Optional[int] diff --git a/worlds/musedash/MuseDashCollection.py b/worlds/musedash/MuseDashCollection.py index 9e8c9214a1dd..64aa6ca49ae3 100644 --- a/worlds/musedash/MuseDashCollection.py +++ b/worlds/musedash/MuseDashCollection.py @@ -1,13 +1,9 @@ -from .Items import SongData, AlbumData -from typing import Dict, List, Set, Optional +from .Items import SongData +from .MuseDashData import SONG_DATA +from typing import Dict, List, Set from collections import ChainMap -def load_text_file(name: str) -> str: - import pkgutil - return pkgutil.get_data(__name__, name).decode() - - class MuseDashCollections: """Contains all the data of Muse Dash, loaded from MuseDashData.txt.""" STARTING_CODE = 2900000 @@ -33,15 +29,6 @@ class MuseDashCollections: "Rin Len's Mirrorland", # Paid DLC not included in Muse Plus ] - DIFF_OVERRIDES: List[str] = [ - "MuseDash ka nanika hi", - "Rush-Hour", - "Find this Month's Featured Playlist", - "PeroPero in the Universe", - "umpopoff", - "P E R O P E R O Brother Dance", - ] - REMOVED_SONGS = [ "CHAOS Glitch", "FM 17314 SUGAR RADIO", @@ -50,9 +37,7 @@ class MuseDashCollections: "Tsukuyomi Ni Naru Replaced", ] - album_items: Dict[str, AlbumData] = {} - album_locations: Dict[str, int] = {} - song_items: Dict[str, SongData] = {} + song_items = SONG_DATA song_locations: Dict[str, int] = {} trap_items: Dict[str, int] = { @@ -65,7 +50,7 @@ class MuseDashCollections: "Gray Scale Trap": STARTING_CODE + 7, "Nyaa SFX Trap": STARTING_CODE + 8, "Error SFX Trap": STARTING_CODE + 9, - "Focus Line Trap": STARTING_CODE + 10, + "Focus Line Trap": STARTING_CODE + 10, } sfx_trap_items: List[str] = [ @@ -85,65 +70,13 @@ class MuseDashCollections: "Extra Life": 1, } - item_names_to_id: ChainMap = ChainMap({}, filler_items, trap_items) - location_names_to_id: ChainMap = ChainMap(song_locations, album_locations) + item_names_to_id: ChainMap = ChainMap({k: v.code for k, v in SONG_DATA.items()}, filler_items, trap_items) + location_names_to_id: ChainMap = ChainMap(song_locations) def __init__(self) -> None: self.item_names_to_id[self.MUSIC_SHEET_NAME] = self.MUSIC_SHEET_CODE - item_id_index = self.STARTING_CODE + 50 - full_file = load_text_file("MuseDashData.txt") - seen_albums = set() - for line in full_file.splitlines(): - line = line.strip() - sections = line.split("|") - - album = sections[2] - if album not in seen_albums: - seen_albums.add(album) - self.album_items[album] = AlbumData(item_id_index) - item_id_index += 1 - - # Data is in the format 'Song|UID|Album|StreamerMode|EasyDiff|HardDiff|MasterDiff|SecretDiff' - song_name = sections[0] - # [1] is used in the client copy to make sure item id's match. - steamer_mode = sections[3] == "True" - - if song_name in self.DIFF_OVERRIDES: - # These songs use non-standard difficulty values. Which are being overriden with standard values. - # But also avoid filling any missing difficulties (i.e. 0s) with a difficulty value. - if sections[4] != '0': - diff_of_easy = 4 - else: - diff_of_easy = None - - if sections[5] != '0': - diff_of_hard = 7 - else: - diff_of_hard = None - - if sections[6] != '0': - diff_of_master = 10 - else: - diff_of_master = None - else: - diff_of_easy = self.parse_song_difficulty(sections[4]) - diff_of_hard = self.parse_song_difficulty(sections[5]) - diff_of_master = self.parse_song_difficulty(sections[6]) - - self.song_items[song_name] = SongData(item_id_index, album, steamer_mode, - diff_of_easy, diff_of_hard, diff_of_master) - item_id_index += 1 - - self.item_names_to_id.update({name: data.code for name, data in self.song_items.items()}) - self.item_names_to_id.update({name: data.code for name, data in self.album_items.items()}) - location_id_index = self.STARTING_CODE - for name in self.album_items.keys(): - self.album_locations[f"{name}-0"] = location_id_index - self.album_locations[f"{name}-1"] = location_id_index + 1 - location_id_index += 2 - for name in self.song_items.keys(): self.song_locations[f"{name}-0"] = location_id_index self.song_locations[f"{name}-1"] = location_id_index + 1 @@ -157,7 +90,7 @@ def get_songs_with_settings(self, dlc_songs: Set[str], streamer_mode_active: boo for songKey, songData in self.song_items.items(): if not self.song_matches_dlc_filter(songData, dlc_songs): continue - + if songKey in self.REMOVED_SONGS: continue @@ -193,18 +126,3 @@ def song_matches_dlc_filter(self, song: SongData, dlc_songs: Set[str]) -> bool: return True return False - - def parse_song_difficulty(self, difficulty: str) -> Optional[int]: - """Attempts to parse the song difficulty.""" - if len(difficulty) <= 0 or difficulty == "?" or difficulty == "¿": - return None - - # 0 is used as a filler and no songs actually have a 0 difficulty song. - if difficulty == "0": - return None - - # Curse the 2023 april fools update. Used on 3rd Avenue. - if difficulty == "〇": - return 10 - - return int(difficulty) diff --git a/worlds/musedash/MuseDashData.py b/worlds/musedash/MuseDashData.py new file mode 100644 index 000000000000..1700f956aa35 --- /dev/null +++ b/worlds/musedash/MuseDashData.py @@ -0,0 +1,615 @@ +from .Items import SongData +from typing import Dict + + +# Auto Generated +SONG_DATA: Dict[str, SongData] = { + "Magical Wonderland": SongData(2900051, "0-48", "Default Music", True, 1, 3, None), + "Iyaiya": SongData(2900052, "0-0", "Default Music", True, 1, 4, None), + "Wonderful Pain": SongData(2900053, "0-2", "Default Music", False, 1, 3, None), + "Breaking Dawn": SongData(2900054, "0-3", "Default Music", True, 2, 4, None), + "One-Way Subway": SongData(2900055, "0-4", "Default Music", True, 1, 4, None), + "Frost Land": SongData(2900056, "0-1", "Default Music", False, 1, 3, 6), + "Heart-Pounding Flight": SongData(2900057, "0-5", "Default Music", True, 2, 5, None), + "Pancake is Love": SongData(2900058, "0-29", "Default Music", True, 2, 4, 7), + "Shiguang Tuya": SongData(2900059, "0-6", "Default Music", True, 2, 5, None), + "Evolution": SongData(2900060, "0-37", "Default Music", False, 2, 4, 7), + "Dolphin and Broadcast": SongData(2900061, "0-7", "Default Music", True, 2, 5, None), + "Yuki no Shizuku Ame no Oto": SongData(2900062, "0-8", "Default Music", True, 2, 4, 6), + "Best One feat.tooko": SongData(2900063, "0-43", "Default Music", False, 3, 5, None), + "Candy-coloured Love Theory": SongData(2900064, "0-31", "Default Music", False, 2, 4, 6), + "Night Wander": SongData(2900065, "0-38", "Default Music", False, 3, 5, 7), + "Dohna Dohna no Uta": SongData(2900066, "0-46", "Default Music", False, 2, 4, 6), + "Spring Carnival": SongData(2900067, "0-9", "Default Music", False, 2, 4, 7), + "DISCO NIGHT": SongData(2900068, "0-30", "Default Music", True, 2, 4, 7), + "Koi no Moonlight": SongData(2900069, "0-49", "Default Music", False, 2, 5, 8), + "Lian Ai Audio Navigation": SongData(2900070, "0-10", "Default Music", False, 3, 5, 7), + "Lights of Muse": SongData(2900071, "0-11", "Default Music", True, 4, 6, 8), + "midstream jam": SongData(2900072, "0-12", "Default Music", False, 2, 5, 8), + "Nihao": SongData(2900073, "0-40", "Default Music", False, 3, 5, 7), + "Confession": SongData(2900074, "0-13", "Default Music", False, 3, 5, 8), + "Galaxy Striker": SongData(2900075, "0-32", "Default Music", False, 4, 7, 9), + "Departure Road": SongData(2900076, "0-14", "Default Music", True, 2, 5, 8), + "Bass Telekinesis": SongData(2900077, "0-15", "Default Music", False, 2, 5, 8), + "Cage of Almeria": SongData(2900078, "0-16", "Default Music", True, 3, 5, 7), + "Ira": SongData(2900079, "0-17", "Default Music", True, 4, 6, 8), + "Blackest Luxury Car": SongData(2900080, "0-18", "Default Music", True, 3, 6, 8), + "Medicine of Sing": SongData(2900081, "0-19", "Default Music", False, 3, 6, 8), + "irregulyze": SongData(2900082, "0-20", "Default Music", True, 3, 6, 8), + "I don't care about Christmas though": SongData(2900083, "0-47", "Default Music", False, 4, 6, 8), + "Imaginary World": SongData(2900084, "0-21", "Default Music", True, 4, 6, 8), + "Dysthymia": SongData(2900085, "0-22", "Default Music", True, 4, 7, 9), + "From the New World": SongData(2900086, "0-42", "Default Music", False, 2, 5, 7), + "NISEGAO": SongData(2900087, "0-33", "Default Music", True, 4, 7, 9), + "Say! Fanfare!": SongData(2900088, "0-44", "Default Music", False, 4, 6, 9), + "Star Driver": SongData(2900089, "0-34", "Default Music", True, 5, 7, 9), + "Formation": SongData(2900090, "0-23", "Default Music", True, 4, 6, 9), + "Shinsou Masui": SongData(2900091, "0-24", "Default Music", True, 4, 6, 10), + "Mezame Eurythmics": SongData(2900092, "0-50", "Default Music", False, 4, 6, 9), + "Shenri Kuaira -repeat-": SongData(2900093, "0-51", "Default Music", False, 5, 7, 9), + "Latitude": SongData(2900094, "0-25", "Default Music", True, 3, 6, 9), + "Aqua Stars": SongData(2900095, "0-39", "Default Music", False, 5, 7, 10), + "Funkotsu Saishin Casino": SongData(2900096, "0-26", "Default Music", False, 5, 7, 10), + "Clock Room & Spiritual World": SongData(2900097, "0-27", "Default Music", True, 4, 6, 9), + "INTERNET OVERDOSE": SongData(2900098, "0-52", "Default Music", False, 3, 6, 9), + "Tu Hua": SongData(2900099, "0-35", "Default Music", True, 4, 7, 9), + "Mujinku-Vacuum": SongData(2900100, "0-28", "Default Music", False, 5, 7, 11), + "MilK": SongData(2900101, "0-36", "Default Music", False, 5, 7, 9), + "umpopoff": SongData(2900102, "0-41", "Default Music", False, None, 7, None), + "Mopemope": SongData(2900103, "0-45", "Default Music", False, 4, 7, 9), + "The Happycore Idol": SongData(2900105, "43-0", "MD Plus Project", True, 2, 5, 7), + "Amatsumikaboshi": SongData(2900106, "43-1", "MD Plus Project", True, 4, 6, 8), + "ARIGA THESIS": SongData(2900107, "43-2", "MD Plus Project", True, 3, 6, 10), + "Night of Nights": SongData(2900108, "43-3", "MD Plus Project", False, 4, 7, 10), + "#Psychedelic_Meguro_River": SongData(2900109, "43-4", "MD Plus Project", False, 3, 6, 8), + "can you feel it": SongData(2900110, "43-5", "MD Plus Project", False, 4, 6, 8), + "Midnight O'clock": SongData(2900111, "43-6", "MD Plus Project", True, 3, 6, 8), + "Rin": SongData(2900112, "43-7", "MD Plus Project", True, 5, 7, 10), + "Smile-mileS": SongData(2900113, "43-8", "MD Plus Project", False, 6, 8, 10), + "Believing and Being": SongData(2900114, "43-9", "MD Plus Project", True, 4, 6, 9), + "Catalyst": SongData(2900115, "43-10", "MD Plus Project", False, 5, 7, 9), + "don't!stop!eroero!": SongData(2900116, "43-11", "MD Plus Project", True, 5, 7, 9), + "pa pi pu pi pu pi pa": SongData(2900117, "43-12", "MD Plus Project", False, 6, 8, 10), + "Sand Maze": SongData(2900118, "43-13", "MD Plus Project", True, 6, 8, 10), + "Diffraction": SongData(2900119, "43-14", "MD Plus Project", True, 5, 8, 10), + "AKUMU": SongData(2900120, "43-15", "MD Plus Project", False, 4, 6, 8), + "Queen Aluett": SongData(2900121, "43-16", "MD Plus Project", True, 7, 9, 11), + "DROPS": SongData(2900122, "43-17", "MD Plus Project", False, 2, 5, 8), + "Frightfully-insane Flan-chan's frightful song": SongData(2900123, "43-18", "MD Plus Project", False, 5, 7, 10), + "snooze": SongData(2900124, "43-19", "MD Plus Project", False, 5, 7, 10), + "Kuishinbo Hacker feat.Kuishinbo Akachan": SongData(2900125, "43-20", "MD Plus Project", True, 5, 7, 9), + "Inu no outa": SongData(2900126, "43-21", "MD Plus Project", True, 3, 5, 7), + "Prism Fountain": SongData(2900127, "43-22", "MD Plus Project", True, 7, 9, 11), + "Gospel": SongData(2900128, "43-23", "MD Plus Project", False, 4, 6, 9), + "East Ai Li Lovely": SongData(2900130, "62-0", "Happy Otaku Pack Vol.17", False, 2, 4, 7), + "Mori Umi no Fune": SongData(2900131, "62-1", "Happy Otaku Pack Vol.17", True, 5, 7, 9), + "Ooi": SongData(2900132, "62-2", "Happy Otaku Pack Vol.17", True, 5, 7, 10), + "Numatta!!": SongData(2900133, "62-3", "Happy Otaku Pack Vol.17", True, 5, 7, 9), + "SATELLITE": SongData(2900134, "62-4", "Happy Otaku Pack Vol.17", False, 5, 7, 9), + "Fantasia Sonata Colorful feat. V!C": SongData(2900135, "62-5", "Happy Otaku Pack Vol.17", True, 6, 8, 11), + "MuseDash ka nanika hi": SongData(2900137, "61-0", "Ola Dash", True, 4, 7, 10), + "Aleph-0": SongData(2900138, "61-1", "Ola Dash", True, 7, 9, 11), + "Buttoba Supernova": SongData(2900139, "61-2", "Ola Dash", False, 5, 7, 10), + "Rush-Hour": SongData(2900140, "61-3", "Ola Dash", False, 4, 7, 10), + "3rd Avenue": SongData(2900141, "61-4", "Ola Dash", False, 3, 5, 10), + "WORLDINVADER": SongData(2900142, "61-5", "Ola Dash", True, 5, 8, 10), + "N3V3R G3T OV3R": SongData(2900144, "60-0", "maimai DX Limited-time Suite", True, 4, 7, 10), + "Oshama Scramble!": SongData(2900145, "60-1", "maimai DX Limited-time Suite", True, 5, 7, 10), + "Valsqotch": SongData(2900146, "60-2", "maimai DX Limited-time Suite", True, 5, 9, 11), + "Paranormal My Mind": SongData(2900147, "60-3", "maimai DX Limited-time Suite", True, 5, 7, 9), + "Flower, snow and Drum'n'bass.": SongData(2900148, "60-4", "maimai DX Limited-time Suite", True, 5, 8, 10), + "Amenohoakari": SongData(2900149, "60-5", "maimai DX Limited-time Suite", True, 6, 8, 10), + "Boiling Blood": SongData(2900151, "59-0", "MSR Anthology", True, 5, 8, 10), + "ManiFesto": SongData(2900152, "59-1", "MSR Anthology", True, 4, 6, 9), + "Operation Blade": SongData(2900153, "59-2", "MSR Anthology", True, 3, 5, 7), + "Radiant": SongData(2900154, "59-3", "MSR Anthology", True, 3, 5, 8), + "Renegade": SongData(2900155, "59-4", "MSR Anthology", True, 3, 5, 8), + "Speed of Light": SongData(2900156, "59-5", "MSR Anthology", False, 1, 4, 7), + "Dossoles Holiday": SongData(2900157, "59-6", "MSR Anthology", True, 5, 7, 9), + "Autumn Moods": SongData(2900158, "59-7", "MSR Anthology", True, 3, 5, 7), + "People People": SongData(2900160, "58-0", "Nanahira Paradise", True, 5, 7, 9), + "Endless Error Loop": SongData(2900161, "58-1", "Nanahira Paradise", True, 4, 7, 9), + "Forbidden Pizza!": SongData(2900162, "58-2", "Nanahira Paradise", True, 5, 7, 9), + "Don't Make the Vocalist do Anything Insane": SongData(2900163, "58-3", "Nanahira Paradise", True, 5, 8, 9), + "Tokimeki*Meteostrike": SongData(2900165, "57-0", "Happy Otaku Pack Vol.16", True, 3, 6, 8), + "Down Low": SongData(2900166, "57-1", "Happy Otaku Pack Vol.16", True, 4, 6, 8), + "LOUDER MACHINE": SongData(2900167, "57-2", "Happy Otaku Pack Vol.16", True, 5, 7, 9), + "Sorewa mo Lovechu": SongData(2900168, "57-3", "Happy Otaku Pack Vol.16", True, 5, 7, 10), + "Rave_Tech": SongData(2900169, "57-4", "Happy Otaku Pack Vol.16", True, 5, 8, 10), + "Brilliant & Shining!": SongData(2900170, "57-5", "Happy Otaku Pack Vol.16", False, 5, 8, 10), + "Psyched Fevereiro": SongData(2900172, "56-0", "Give Up TREATMENT Vol.11", False, 5, 8, 10), + "Inferno City": SongData(2900173, "56-1", "Give Up TREATMENT Vol.11", False, 6, 8, 10), + "Paradigm Shift": SongData(2900174, "56-2", "Give Up TREATMENT Vol.11", False, 4, 7, 10), + "Snapdragon": SongData(2900175, "56-3", "Give Up TREATMENT Vol.11", False, 5, 7, 10), + "Prestige and Vestige": SongData(2900176, "56-4", "Give Up TREATMENT Vol.11", True, 6, 8, 11), + "Tiny Fate": SongData(2900177, "56-5", "Give Up TREATMENT Vol.11", False, 7, 9, 11), + "Tsuki ni Murakumo Hana ni Kaze": SongData(2900179, "55-0", "Touhou Mugakudan -II-", False, 3, 5, 7), + "Patchouli's - Best Hit GSK": SongData(2900180, "55-1", "Touhou Mugakudan -II-", False, 3, 5, 8), + "Monosugoi Space Shuttle de Koishi ga Monosugoi uta": SongData(2900181, "55-2", "Touhou Mugakudan -II-", False, 3, 5, 7), + "Kakoinaki Yo wa Ichigo no Tsukikage": SongData(2900182, "55-3", "Touhou Mugakudan -II-", False, 3, 6, 8), + "Psychedelic Kizakura Doumei": SongData(2900183, "55-4", "Touhou Mugakudan -II-", False, 4, 7, 10), + "Mischievous Sensation": SongData(2900184, "55-5", "Touhou Mugakudan -II-", False, 5, 7, 9), + "White Canvas": SongData(2900186, "54-0", "MEGAREX THE FUTURE", False, 3, 6, 8), + "Gloomy Flash": SongData(2900187, "54-1", "MEGAREX THE FUTURE", False, 5, 8, 10), + "Find this Month's Featured Playlist": SongData(2900188, "54-2", "MEGAREX THE FUTURE", False, 4, 7, 10), + "Sunday Night": SongData(2900189, "54-3", "MEGAREX THE FUTURE", False, 3, 6, 9), + "Goodbye Goodnight": SongData(2900190, "54-4", "MEGAREX THE FUTURE", False, 4, 6, 9), + "ENDLESS CIDER": SongData(2900191, "54-5", "MEGAREX THE FUTURE", False, 4, 6, 8), + "On And On!!": SongData(2900193, "53-0", "Happy Otaku Pack Vol.15", True, 4, 7, 9), + "Trip!": SongData(2900194, "53-1", "Happy Otaku Pack Vol.15", True, 3, 5, 7), + "Hoshi no otoshimono": SongData(2900195, "53-2", "Happy Otaku Pack Vol.15", False, 5, 7, 9), + "Plucky Race": SongData(2900196, "53-3", "Happy Otaku Pack Vol.15", True, 5, 8, 10), + "Fantasia Sonata Destiny": SongData(2900197, "53-4", "Happy Otaku Pack Vol.15", True, 3, 7, 10), + "Run through": SongData(2900198, "53-5", "Happy Otaku Pack Vol.15", False, 5, 8, 10), + "marooned night": SongData(2900200, "52-0", "MUSE RADIO FM103", False, 2, 4, 6), + "daydream girl": SongData(2900201, "52-1", "MUSE RADIO FM103", False, 3, 6, 8), + "Not Ornament": SongData(2900202, "52-2", "MUSE RADIO FM103", True, 3, 5, 8), + "Baby Pink": SongData(2900203, "52-3", "MUSE RADIO FM103", False, 3, 5, 8), + "I'm Here": SongData(2900204, "52-4", "MUSE RADIO FM103", False, 4, 6, 8), + "Masquerade Diary": SongData(2900206, "51-0", "Virtual Idol Production", True, 2, 5, 8), + "Reminiscence": SongData(2900207, "51-1", "Virtual Idol Production", True, 5, 7, 9), + "DarakuDatenshi": SongData(2900208, "51-2", "Virtual Idol Production", True, 3, 6, 9), + "D.I.Y.": SongData(2900209, "51-3", "Virtual Idol Production", False, 4, 6, 9), + "Boys in Virtual Land": SongData(2900210, "51-4", "Virtual Idol Production", False, 4, 7, 9), + "kui": SongData(2900211, "51-5", "Virtual Idol Production", True, 5, 7, 9), + "Nyan Cat": SongData(2900213, "50-0", "Nyanya Universe!", False, 4, 7, 9), + "PeroPero in the Universe": SongData(2900214, "50-1", "Nyanya Universe!", True, 4, 7, 10), + "In-kya Yo-kya Onmyoji": SongData(2900215, "50-2", "Nyanya Universe!", False, 6, 8, 10), + "KABOOOOOM!!!!": SongData(2900216, "50-3", "Nyanya Universe!", True, 4, 6, 8), + "Doppelganger": SongData(2900217, "50-4", "Nyanya Universe!", True, 5, 7, 9), + "Pray a LOVE": SongData(2900219, "49-0", "DokiDoki! Valentine!", False, 2, 5, 8), + "Love-Avoidance Addiction": SongData(2900220, "49-1", "DokiDoki! Valentine!", False, 3, 5, 7), + "Daisuki Dayo feat.Wotoha": SongData(2900221, "49-2", "DokiDoki! Valentine!", False, 5, 7, 10), + "glory day": SongData(2900223, "48-0", "DJMAX Reflect", False, 2, 5, 7), + "Bright Dream": SongData(2900224, "48-1", "DJMAX Reflect", False, 2, 4, 7), + "Groovin Up": SongData(2900225, "48-2", "DJMAX Reflect", False, 4, 6, 8), + "I Want You": SongData(2900226, "48-3", "DJMAX Reflect", False, 3, 6, 8), + "OBLIVION": SongData(2900227, "48-4", "DJMAX Reflect", False, 3, 6, 9), + "Elastic STAR": SongData(2900228, "48-5", "DJMAX Reflect", False, 4, 6, 8), + "U.A.D": SongData(2900229, "48-6", "DJMAX Reflect", False, 4, 6, 8), + "Jealousy": SongData(2900230, "48-7", "DJMAX Reflect", False, 3, 5, 7), + "Memory of Beach": SongData(2900231, "48-8", "DJMAX Reflect", False, 3, 6, 8), + "Don't Die": SongData(2900232, "48-9", "DJMAX Reflect", False, 6, 8, 10), + "Y CE Ver.": SongData(2900233, "48-10", "DJMAX Reflect", False, 4, 6, 9), + "Fancy Night": SongData(2900234, "48-11", "DJMAX Reflect", False, 4, 6, 8), + "Can We Talk": SongData(2900235, "48-12", "DJMAX Reflect", False, 4, 6, 8), + "Give Me 5": SongData(2900236, "48-13", "DJMAX Reflect", False, 2, 6, 8), + "Nightmare": SongData(2900237, "48-14", "DJMAX Reflect", False, 7, 9, 11), + "Haze of Autumn": SongData(2900239, "47-0", "Arcaea", True, 3, 6, 9), + "GIMME DA BLOOD": SongData(2900240, "47-1", "Arcaea", False, 3, 6, 9), + "Libertas": SongData(2900241, "47-2", "Arcaea", False, 4, 7, 10), + "Cyaegha": SongData(2900242, "47-3", "Arcaea", False, 5, 7, 9), + "Bang!!": SongData(2900244, "46-0", "Happy Otaku Pack Vol.14", False, 4, 6, 8), + "Paradise 2": SongData(2900245, "46-1", "Happy Otaku Pack Vol.14", False, 4, 6, 8), + "Symbol": SongData(2900246, "46-2", "Happy Otaku Pack Vol.14", False, 5, 7, 9), + "Nekojarashi": SongData(2900247, "46-3", "Happy Otaku Pack Vol.14", False, 5, 8, 10), + "A Philosophical Wanderer": SongData(2900248, "46-4", "Happy Otaku Pack Vol.14", False, 4, 6, 10), + "Isouten": SongData(2900249, "46-5", "Happy Otaku Pack Vol.14", True, 6, 8, 10), + "ONOMATO Pairing!!!": SongData(2900251, "45-0", "WACCA Horizon", False, 4, 6, 9), + "with U": SongData(2900252, "45-1", "WACCA Horizon", False, 6, 8, 10), + "Chariot": SongData(2900253, "45-2", "WACCA Horizon", False, 3, 6, 9), + "GASHATT": SongData(2900254, "45-3", "WACCA Horizon", False, 5, 7, 10), + "LIN NE KRO NE feat. lasah": SongData(2900255, "45-4", "WACCA Horizon", False, 6, 8, 10), + "ANGEL HALO": SongData(2900256, "45-5", "WACCA Horizon", False, 5, 8, 11), + "Party in the HOLLOWood": SongData(2900258, "44-0", "Happy Otaku Pack Vol.13", False, 3, 6, 8), + "Ying Ying da Zuozhan": SongData(2900259, "44-1", "Happy Otaku Pack Vol.13", True, 5, 7, 9), + "Howlin' Pumpkin": SongData(2900260, "44-2", "Happy Otaku Pack Vol.13", True, 4, 6, 8), + "Bad Apple!! feat. Nomico": SongData(2900262, "42-0", "Touhou Mugakudan -I-", False, 1, 3, 6), + "Iro wa Nioedo, Chirinuru wo": SongData(2900263, "42-1", "Touhou Mugakudan -I-", False, 2, 4, 7), + "Cirno's Perfect Math Class": SongData(2900264, "42-2", "Touhou Mugakudan -I-", False, 4, 7, 9), + "Hiiro Gekka Kyousai no Zetsu": SongData(2900265, "42-3", "Touhou Mugakudan -I-", False, 4, 6, 8), + "Flowery Moonlit Night": SongData(2900266, "42-4", "Touhou Mugakudan -I-", False, 3, 6, 8), + "Unconscious Requiem": SongData(2900267, "42-5", "Touhou Mugakudan -I-", False, 3, 6, 8), + "Super Battleworn Insomniac": SongData(2900269, "41-0", "7th Beat Games", True, 4, 7, 9), + "Bomb-Sniffing Pomeranian": SongData(2900270, "41-1", "7th Beat Games", True, 4, 6, 8), + "Rollerdisco Rumble": SongData(2900271, "41-2", "7th Beat Games", True, 4, 6, 9), + "Rose Garden": SongData(2900272, "41-3", "7th Beat Games", False, 5, 8, 9), + "EMOMOMO": SongData(2900273, "41-4", "7th Beat Games", True, 4, 7, 10), + "Heracles": SongData(2900274, "41-5", "7th Beat Games", False, 6, 8, 10), + "Rush-More": SongData(2900276, "40-0", "Happy Otaku Pack Vol.12", False, 4, 7, 9), + "Kill My Fortune": SongData(2900277, "40-1", "Happy Otaku Pack Vol.12", False, 5, 7, 10), + "Yosari Tsukibotaru Suminoborite": SongData(2900278, "40-2", "Happy Otaku Pack Vol.12", False, 5, 7, 9), + "JUMP! HardCandy": SongData(2900279, "40-3", "Happy Otaku Pack Vol.12", False, 3, 6, 8), + "Hibari": SongData(2900280, "40-4", "Happy Otaku Pack Vol.12", False, 3, 5, 8), + "OCCHOCO-REST-LESS": SongData(2900281, "40-5", "Happy Otaku Pack Vol.12", True, 4, 7, 9), + "See-Saw Day": SongData(2900283, "39-0", "MUSE RADIO FM102", True, 1, 3, 6), + "happy hour": SongData(2900284, "39-1", "MUSE RADIO FM102", True, 2, 4, 7), + "Seikimatsu no Natsu": SongData(2900285, "39-2", "MUSE RADIO FM102", True, 4, 6, 8), + "twinkle night": SongData(2900286, "39-3", "MUSE RADIO FM102", False, 3, 6, 8), + "ARUYA HARERUYA": SongData(2900287, "39-4", "MUSE RADIO FM102", False, 2, 5, 7), + "Blush": SongData(2900288, "39-5", "MUSE RADIO FM102", False, 2, 4, 7), + "Naked Summer": SongData(2900289, "39-6", "MUSE RADIO FM102", True, 4, 6, 8), + "BLESS ME": SongData(2900290, "39-7", "MUSE RADIO FM102", True, 2, 5, 7), + "FM 17314 SUGAR RADIO": SongData(2900291, "39-8", "MUSE RADIO FM102", True, None, None, None), + "NO ONE YES MAN": SongData(2900293, "38-0", "Phigros", False, 5, 7, 9), + "Snowfall, Merry Christmas": SongData(2900294, "38-1", "Phigros", False, 5, 8, 10), + "Igallta": SongData(2900295, "38-2", "Phigros", False, 6, 8, 10), + "Colored Glass": SongData(2900297, "37-0", "Cute Is Everything Vol.7", False, 1, 4, 7), + "Neonlights": SongData(2900298, "37-1", "Cute Is Everything Vol.7", False, 4, 7, 9), + "Hope for the flowers": SongData(2900299, "37-2", "Cute Is Everything Vol.7", False, 4, 7, 9), + "Seaside Cycling on May 30": SongData(2900300, "37-3", "Cute Is Everything Vol.7", False, 3, 6, 8), + "SKY HIGH": SongData(2900301, "37-4", "Cute Is Everything Vol.7", False, 2, 4, 6), + "Mousou Chu!!": SongData(2900302, "37-5", "Cute Is Everything Vol.7", False, 4, 7, 8), + "NightTheater": SongData(2900304, "36-0", "Give Up TREATMENT Vol.10", True, 6, 8, 11), + "Cutter": SongData(2900305, "36-1", "Give Up TREATMENT Vol.10", False, 4, 7, 10), + "bamboo": SongData(2900306, "36-2", "Give Up TREATMENT Vol.10", False, 6, 8, 10), + "enchanted love": SongData(2900307, "36-3", "Give Up TREATMENT Vol.10", False, 2, 6, 9), + "c.s.q.n.": SongData(2900308, "36-4", "Give Up TREATMENT Vol.10", False, 5, 8, 11), + "Booouncing!!": SongData(2900309, "36-5", "Give Up TREATMENT Vol.10", False, 5, 7, 10), + "PeroPeroGames goes Bankrupt": SongData(2900311, "35-0", "Happy Otaku Pack SP", True, 6, 8, 10), + "MARENOL": SongData(2900312, "35-1", "Happy Otaku Pack SP", False, 4, 7, 10), + "I am really good at Japanese style": SongData(2900313, "35-2", "Happy Otaku Pack SP", True, 6, 8, 10), + "Rush B": SongData(2900314, "35-3", "Happy Otaku Pack SP", True, 4, 7, 9), + "DataErr0r": SongData(2900315, "35-4", "Happy Otaku Pack SP", False, 5, 7, 9), + "Burn": SongData(2900316, "35-5", "Happy Otaku Pack SP", True, 4, 7, 9), + "ALiVE": SongData(2900318, "34-0", "HARDCORE TANO*C", False, 5, 7, 10), + "BATTLE NO.1": SongData(2900319, "34-1", "HARDCORE TANO*C", False, 5, 8, 10), + "Cthugha": SongData(2900320, "34-2", "HARDCORE TANO*C", False, 6, 8, 10), + "TWINKLE*MAGIC": SongData(2900321, "34-3", "HARDCORE TANO*C", False, 4, 7, 10), + "Comet Coaster": SongData(2900322, "34-4", "HARDCORE TANO*C", False, 6, 8, 10), + "XODUS": SongData(2900323, "34-5", "HARDCORE TANO*C", False, 7, 9, 11), + "Fireflies": SongData(2900325, "33-0", "cyTus", True, 1, 4, 7), + "Light up my love!!": SongData(2900326, "33-1", "cyTus", True, 3, 5, 7), + "Happiness Breeze": SongData(2900327, "33-2", "cyTus", True, 4, 6, 8), + "Chrome VOX": SongData(2900328, "33-3", "cyTus", True, 6, 8, 10), + "CHAOS": SongData(2900329, "33-4", "cyTus", True, 3, 6, 9), + "Saika": SongData(2900330, "33-5", "cyTus", True, 3, 5, 8), + "Standby for Action": SongData(2900331, "33-6", "cyTus", True, 4, 6, 8), + "Hydrangea": SongData(2900332, "33-7", "cyTus", True, 5, 7, 9), + "Amenemhat": SongData(2900333, "33-8", "cyTus", True, 6, 8, 10), + "Santouka": SongData(2900334, "33-9", "cyTus", True, 2, 5, 8), + "HEXENNACHTROCK-katashihaya-": SongData(2900335, "33-10", "cyTus", True, 4, 8, 10), + "Blah!!": SongData(2900336, "33-11", "cyTus", True, 5, 8, 11), + "CHAOS Glitch": SongData(2900337, "33-12", "cyTus", True, None, None, None), + "Preparara": SongData(2900339, "32-0", "Let's Do Bad Things Together", False, 1, 4, 6), + "Whatcha;Whatcha Doin'": SongData(2900340, "32-1", "Let's Do Bad Things Together", False, 3, 6, 9), + "Madara": SongData(2900341, "32-2", "Let's Do Bad Things Together", False, 4, 6, 9), + "pICARESq": SongData(2900342, "32-3", "Let's Do Bad Things Together", False, 4, 6, 8), + "Desastre": SongData(2900343, "32-4", "Let's Do Bad Things Together", False, 4, 6, 8), + "Shoot for the Moon": SongData(2900344, "32-5", "Let's Do Bad Things Together", False, 2, 5, 8), + "The 90's Decision": SongData(2900346, "31-0", "Happy Otaku Pack Vol.11", True, 5, 7, 9), + "Medusa": SongData(2900347, "31-1", "Happy Otaku Pack Vol.11", False, 4, 6, 8), + "Final Step!": SongData(2900348, "31-2", "Happy Otaku Pack Vol.11", False, 5, 7, 10), + "MAGENTA POTION": SongData(2900349, "31-3", "Happy Otaku Pack Vol.11", False, 4, 7, 9), + "Cross Ray": SongData(2900350, "31-4", "Happy Otaku Pack Vol.11", False, 3, 6, 9), + "Square Lake": SongData(2900351, "31-5", "Happy Otaku Pack Vol.11", False, 6, 8, 9), + "Girly Cupid": SongData(2900353, "30-0", "Cute Is Everything Vol.6", False, 3, 6, 8), + "sheep in the light": SongData(2900354, "30-1", "Cute Is Everything Vol.6", False, 2, 5, 8), + "Breaker city": SongData(2900355, "30-2", "Cute Is Everything Vol.6", False, 4, 6, 9), + "heterodoxy": SongData(2900356, "30-3", "Cute Is Everything Vol.6", False, 4, 6, 8), + "Computer Music Girl": SongData(2900357, "30-4", "Cute Is Everything Vol.6", False, 3, 5, 7), + "Focus Point": SongData(2900358, "30-5", "Cute Is Everything Vol.6", True, 2, 5, 7), + "Groove Prayer": SongData(2900360, "29-0", "Let' s GROOVE!", True, 3, 5, 7), + "FUJIN Rumble": SongData(2900361, "29-1", "Let' s GROOVE!", True, 5, 7, 10), + "Marry me, Nightmare": SongData(2900362, "29-2", "Let' s GROOVE!", False, 6, 8, 11), + "HG Makaizou Polyvinyl Shounen": SongData(2900363, "29-3", "Let' s GROOVE!", True, 4, 7, 9), + "Seizya no Ibuki": SongData(2900364, "29-4", "Let' s GROOVE!", True, 6, 8, 10), + "ouroboros -twin stroke of the end-": SongData(2900365, "29-5", "Let' s GROOVE!", True, 4, 6, 9), + "Heisha Onsha": SongData(2900367, "28-0", "Happy Otaku Pack Vol.10", False, 4, 6, 8), + "Ginevra": SongData(2900368, "28-1", "Happy Otaku Pack Vol.10", True, 5, 7, 10), + "Paracelestia": SongData(2900369, "28-2", "Happy Otaku Pack Vol.10", False, 5, 8, 10), + "un secret": SongData(2900370, "28-3", "Happy Otaku Pack Vol.10", False, 2, 4, 6), + "Good Life": SongData(2900371, "28-4", "Happy Otaku Pack Vol.10", False, 4, 6, 8), + "nini-nini-": SongData(2900372, "28-5", "Happy Otaku Pack Vol.10", False, 4, 7, 9), + "Can I friend you on Bassbook? lol": SongData(2900374, "27-0", "Nanahira Festival", False, 3, 6, 8), + "Gaming*Everything": SongData(2900375, "27-1", "Nanahira Festival", False, 5, 8, 11), + "Renji de haochi": SongData(2900376, "27-2", "Nanahira Festival", False, 5, 7, 9), + "You Make My Life 1UP": SongData(2900377, "27-3", "Nanahira Festival", False, 4, 6, 8), + "Newbies, Geeks, Internets": SongData(2900378, "27-4", "Nanahira Festival", False, 6, 8, 10), + "Onegai!Kon kon Oinarisama": SongData(2900379, "27-5", "Nanahira Festival", False, 3, 6, 9), + "Legend of Eastern Rabbit -SKY DEFENDER-": SongData(2900381, "26-0", "Give Up TREATMENT Vol.9", False, 4, 6, 9), + "ENERGY SYNERGY MATRIX": SongData(2900382, "26-1", "Give Up TREATMENT Vol.9", False, 6, 8, 10), + "Punai Punai Genso": SongData(2900383, "26-2", "Give Up TREATMENT Vol.9", False, 2, 7, 11), + "Better Graphic Animation": SongData(2900384, "26-3", "Give Up TREATMENT Vol.9", False, 5, 8, 11), + "Variant Cross": SongData(2900385, "26-4", "Give Up TREATMENT Vol.9", False, 4, 7, 10), + "Ultra Happy Miracle Bazoooooka!!": SongData(2900386, "26-5", "Give Up TREATMENT Vol.9", False, 7, 9, 11), + "tape/stop/night": SongData(2900388, "25-0", "MUSE RADIO FM101", True, 3, 5, 7), + "Pixel Galaxy": SongData(2900389, "25-1", "MUSE RADIO FM101", False, 2, 5, 8), + "Notice": SongData(2900390, "25-2", "MUSE RADIO FM101", False, 4, 7, 10), + "Strawberry Godzilla": SongData(2900391, "25-3", "MUSE RADIO FM101", True, 2, 5, 7), + "OKIMOCHI EXPRESSION": SongData(2900392, "25-4", "MUSE RADIO FM101", False, 4, 6, 10), + "Kimi to pool disco": SongData(2900393, "25-5", "MUSE RADIO FM101", False, 4, 6, 8), + "The Last Page": SongData(2900395, "24-0", "Happy Otaku Pack Vol.9", False, 3, 5, 7), + "IKAROS": SongData(2900396, "24-1", "Happy Otaku Pack Vol.9", False, 4, 7, 10), + "Tsukuyomi": SongData(2900397, "24-2", "Happy Otaku Pack Vol.9", False, 3, 6, 9), + "Future Stream": SongData(2900398, "24-3", "Happy Otaku Pack Vol.9", False, 4, 6, 8), + "FULi AUTO SHOOTER": SongData(2900399, "24-4", "Happy Otaku Pack Vol.9", True, 4, 7, 9), + "GOODFORTUNE": SongData(2900400, "24-5", "Happy Otaku Pack Vol.9", False, 5, 7, 9), + "The Dessert After Rain": SongData(2900402, "23-0", "Cute Is Everything Vol.5", True, 2, 4, 6), + "Confession Support Formula": SongData(2900403, "23-1", "Cute Is Everything Vol.5", False, 3, 5, 7), + "Omatsuri": SongData(2900404, "23-2", "Cute Is Everything Vol.5", False, 1, 3, 6), + "FUTUREPOP": SongData(2900405, "23-3", "Cute Is Everything Vol.5", True, 2, 5, 7), + "The Breeze": SongData(2900406, "23-4", "Cute Is Everything Vol.5", False, 1, 4, 6), + "I LOVE LETTUCE FRIED RICE!!": SongData(2900407, "23-5", "Cute Is Everything Vol.5", False, 3, 7, 9), + "The NightScape": SongData(2900409, "22-0", "Give Up TREATMENT Vol.8", False, 4, 7, 9), + "FREEDOM DiVE": SongData(2900410, "22-1", "Give Up TREATMENT Vol.8", False, 6, 8, 10), + "Phi": SongData(2900411, "22-2", "Give Up TREATMENT Vol.8", False, 5, 8, 10), + "Lueur de la nuit": SongData(2900412, "22-3", "Give Up TREATMENT Vol.8", False, 6, 8, 11), + "Creamy Sugary OVERDRIVE!!!": SongData(2900413, "22-4", "Give Up TREATMENT Vol.8", True, 4, 7, 10), + "Disorder": SongData(2900414, "22-5", "Give Up TREATMENT Vol.8", False, 5, 7, 11), + "Glimmer": SongData(2900416, "21-0", "Budget Is Burning: Nano Core", False, 2, 5, 8), + "EXIST": SongData(2900417, "21-1", "Budget Is Burning: Nano Core", False, 3, 5, 8), + "Irreplaceable": SongData(2900418, "21-2", "Budget Is Burning: Nano Core", False, 4, 6, 8), + "Moonlight Banquet": SongData(2900420, "20-0", "Happy Otaku Pack Vol.8", True, 2, 5, 8), + "Flashdance": SongData(2900421, "20-1", "Happy Otaku Pack Vol.8", False, 3, 6, 9), + "INFiNiTE ENERZY -Overdoze-": SongData(2900422, "20-2", "Happy Otaku Pack Vol.8", False, 4, 7, 9), + "One Way Street": SongData(2900423, "20-3", "Happy Otaku Pack Vol.8", False, 3, 6, 10), + "This Club is Not 4 U": SongData(2900424, "20-4", "Happy Otaku Pack Vol.8", False, 4, 7, 9), + "ULTRA MEGA HAPPY PARTY!!!": SongData(2900425, "20-5", "Happy Otaku Pack Vol.8", False, 5, 7, 10), + "INFINITY": SongData(2900427, "19-0", "Give Up TREATMENT Vol.7", True, 5, 8, 10), + "Punai Punai Senso": SongData(2900428, "19-1", "Give Up TREATMENT Vol.7", False, 2, 7, 11), + "Maxi": SongData(2900429, "19-2", "Give Up TREATMENT Vol.7", False, 5, 8, 10), + "YInMn Blue": SongData(2900430, "19-3", "Give Up TREATMENT Vol.7", False, 6, 8, 10), + "Plumage": SongData(2900431, "19-4", "Give Up TREATMENT Vol.7", False, 4, 7, 10), + "Dr.Techro": SongData(2900432, "19-5", "Give Up TREATMENT Vol.7", False, 7, 9, 11), + "SWEETSWEETSWEET": SongData(2900434, "18-0", "Cute Is Everything Vol.4", True, 2, 5, 7), + "Deep Blue and the Breaths of the Night": SongData(2900435, "18-1", "Cute Is Everything Vol.4", True, 2, 4, 6), + "Joy Connection": SongData(2900436, "18-2", "Cute Is Everything Vol.4", False, 3, 6, 8), + "Self Willed Girl Ver.B": SongData(2900437, "18-3", "Cute Is Everything Vol.4", True, 4, 6, 8), + "Just Disobedient": SongData(2900438, "18-4", "Cute Is Everything Vol.4", False, 3, 6, 8), + "Holy Sh*t Grass Snake": SongData(2900439, "18-5", "Cute Is Everything Vol.4", False, 2, 6, 9), + "Cotton Candy Wonderland": SongData(2900441, "17-0", "Happy Otaku Pack Vol.7", False, 2, 5, 8), + "Punai Punai Taiso": SongData(2900442, "17-1", "Happy Otaku Pack Vol.7", False, 2, 7, 10), + "Fly High": SongData(2900443, "17-2", "Happy Otaku Pack Vol.7", False, 3, 5, 7), + "prejudice": SongData(2900444, "17-3", "Happy Otaku Pack Vol.7", True, 4, 6, 9), + "The 89's Momentum": SongData(2900445, "17-4", "Happy Otaku Pack Vol.7", True, 5, 7, 9), + "energy night": SongData(2900446, "17-5", "Happy Otaku Pack Vol.7", True, 5, 7, 10), + "Future Dive": SongData(2900448, "16-0", "Give Up TREATMENT Vol.6", True, 4, 6, 9), + "Re End of a Dream": SongData(2900449, "16-1", "Give Up TREATMENT Vol.6", False, 5, 8, 11), + "Etude -Storm-": SongData(2900450, "16-2", "Give Up TREATMENT Vol.6", True, 6, 8, 10), + "Unlimited Katharsis": SongData(2900451, "16-3", "Give Up TREATMENT Vol.6", False, 4, 6, 10), + "Magic Knight Girl": SongData(2900452, "16-4", "Give Up TREATMENT Vol.6", False, 4, 7, 9), + "Eeliaas": SongData(2900453, "16-5", "Give Up TREATMENT Vol.6", False, 6, 9, 11), + "Magic Spell": SongData(2900455, "15-0", "Cute Is Everything Vol.3", True, 2, 5, 7), + "Colorful Star, Colored Drawing, Travel Poem": SongData(2900456, "15-1", "Cute Is Everything Vol.3", False, 3, 4, 6), + "Satell Knight": SongData(2900457, "15-2", "Cute Is Everything Vol.3", False, 3, 6, 8), + "Black River Feat.Mes": SongData(2900458, "15-3", "Cute Is Everything Vol.3", True, 1, 4, 6), + "I am sorry": SongData(2900459, "15-4", "Cute Is Everything Vol.3", False, 2, 5, 8), + "Ueta Tori Tachi": SongData(2900460, "15-5", "Cute Is Everything Vol.3", False, 3, 6, 8), + "Elysion's Old Mans": SongData(2900462, "14-0", "Happy Otaku Pack Vol.6", False, 3, 5, 8), + "AXION": SongData(2900463, "14-1", "Happy Otaku Pack Vol.6", False, 4, 5, 8), + "Amnesia": SongData(2900464, "14-2", "Happy Otaku Pack Vol.6", True, 3, 6, 9), + "Onsen Dai Sakusen": SongData(2900465, "14-3", "Happy Otaku Pack Vol.6", True, 4, 6, 8), + "Gleam stone": SongData(2900466, "14-4", "Happy Otaku Pack Vol.6", False, 4, 7, 9), + "GOODWORLD": SongData(2900467, "14-5", "Happy Otaku Pack Vol.6", False, 4, 7, 10), + "Instant Soluble Neon": SongData(2900469, "13-0", "Cute Is Everything Vol.2", True, 2, 4, 7), + "Retrospective Poem on the Planet": SongData(2900470, "13-1", "Cute Is Everything Vol.2", False, 3, 5, 7), + "I'm Gonna Buy! Buy! Buy!": SongData(2900471, "13-2", "Cute Is Everything Vol.2", True, 4, 6, 8), + "Dating Manifesto": SongData(2900472, "13-3", "Cute Is Everything Vol.2", True, 2, 4, 6), + "First Snow": SongData(2900473, "13-4", "Cute Is Everything Vol.2", True, 2, 3, 6), + "Xin Shang Huahai": SongData(2900474, "13-5", "Cute Is Everything Vol.2", False, 3, 6, 8), + "Gaikan Chrysalis": SongData(2900476, "12-0", "Give Up TREATMENT Vol.5", False, 4, 6, 8), + "Sterelogue": SongData(2900477, "12-1", "Give Up TREATMENT Vol.5", True, 5, 7, 10), + "Cheshire's Dance": SongData(2900478, "12-2", "Give Up TREATMENT Vol.5", True, 4, 7, 10), + "Skrik": SongData(2900479, "12-3", "Give Up TREATMENT Vol.5", True, 5, 7, 11), + "Soda Pop Canva5!": SongData(2900480, "12-4", "Give Up TREATMENT Vol.5", False, 5, 8, 10), + "RUBY LINTe": SongData(2900481, "12-5", "Give Up TREATMENT Vol.5", False, 5, 8, 11), + "Brave My Heart": SongData(2900483, "11-0", "Happy Otaku Pack Vol.5", True, 3, 5, 7), + "Sakura Fubuki": SongData(2900484, "11-1", "Happy Otaku Pack Vol.5", False, 4, 7, 10), + "8bit Adventurer": SongData(2900485, "11-2", "Happy Otaku Pack Vol.5", False, 6, 8, 10), + "Suffering of screw": SongData(2900486, "11-3", "Happy Otaku Pack Vol.5", False, 3, 5, 8), + "tiny lady": SongData(2900487, "11-4", "Happy Otaku Pack Vol.5", True, 4, 6, 9), + "Power Attack": SongData(2900488, "11-5", "Happy Otaku Pack Vol.5", False, 5, 7, 10), + "Destr0yer": SongData(2900490, "10-0", "Give Up TREATMENT Vol.4", False, 4, 7, 9), + "Noel": SongData(2900491, "10-1", "Give Up TREATMENT Vol.4", False, 5, 8, 10), + "Kyoukiranbu": SongData(2900492, "10-2", "Give Up TREATMENT Vol.4", False, 7, 9, 11), + "Two Phace": SongData(2900493, "10-3", "Give Up TREATMENT Vol.4", True, 4, 7, 10), + "Fly Again": SongData(2900494, "10-4", "Give Up TREATMENT Vol.4", False, 5, 7, 10), + "ouroVoros": SongData(2900495, "10-5", "Give Up TREATMENT Vol.4", False, 7, 9, 11), + "Leave It Alone": SongData(2900497, "9-0", "Happy Otaku Pack Vol.4", True, 2, 5, 8), + "Tsubasa no Oreta Tenshitachi no Requiem": SongData(2900498, "9-1", "Happy Otaku Pack Vol.4", False, 4, 7, 9), + "Chronomia": SongData(2900499, "9-2", "Happy Otaku Pack Vol.4", False, 5, 7, 10), + "Dandelion's Daydream": SongData(2900500, "9-3", "Happy Otaku Pack Vol.4", True, 5, 7, 8), + "Lorikeet Flat design": SongData(2900501, "9-4", "Happy Otaku Pack Vol.4", True, 5, 7, 10), + "GOODRAGE": SongData(2900502, "9-5", "Happy Otaku Pack Vol.4", False, 6, 9, 11), + "Altale": SongData(2900504, "8-0", "Give Up TREATMENT Vol.3", False, 3, 5, 7), + "Brain Power": SongData(2900505, "8-1", "Give Up TREATMENT Vol.3", False, 4, 7, 10), + "Berry Go!!": SongData(2900506, "8-2", "Give Up TREATMENT Vol.3", False, 3, 6, 9), + "Sweet* Witch* Girl*": SongData(2900507, "8-3", "Give Up TREATMENT Vol.3", False, 6, 8, 10), + "trippers feeling!": SongData(2900508, "8-4", "Give Up TREATMENT Vol.3", True, 5, 7, 9), + "Lilith ambivalence lovers": SongData(2900509, "8-5", "Give Up TREATMENT Vol.3", False, 5, 8, 10), + "Brave My Soul": SongData(2900511, "7-0", "Give Up TREATMENT Vol.2", False, 4, 6, 8), + "Halcyon": SongData(2900512, "7-1", "Give Up TREATMENT Vol.2", False, 4, 7, 10), + "Crimson Nightingale": SongData(2900513, "7-2", "Give Up TREATMENT Vol.2", True, 4, 7, 10), + "Invader": SongData(2900514, "7-3", "Give Up TREATMENT Vol.2", True, 3, 7, 11), + "Lyrith": SongData(2900515, "7-4", "Give Up TREATMENT Vol.2", False, 5, 7, 10), + "GOODBOUNCE": SongData(2900516, "7-5", "Give Up TREATMENT Vol.2", False, 4, 6, 9), + "Out of Sense": SongData(2900518, "6-0", "Budget Is Burning Vol.1", False, 3, 5, 8), + "My Life Is For You": SongData(2900519, "6-1", "Budget Is Burning Vol.1", False, 2, 4, 7), + "Etude -Sunset-": SongData(2900520, "6-2", "Budget Is Burning Vol.1", True, 5, 7, 9), + "Goodbye Boss": SongData(2900521, "6-3", "Budget Is Burning Vol.1", False, 4, 6, 8), + "Stargazer": SongData(2900522, "6-4", "Budget Is Burning Vol.1", True, 2, 5, 8), + "Lys Tourbillon": SongData(2900523, "6-5", "Budget Is Burning Vol.1", True, 4, 6, 8), + "Thirty Million Persona": SongData(2900525, "5-0", "Happy Otaku Pack Vol.3", False, 2, 4, 6), + "conflict": SongData(2900526, "5-1", "Happy Otaku Pack Vol.3", False, 2, 6, 9), + "Enka Dance Music": SongData(2900527, "5-2", "Happy Otaku Pack Vol.3", False, 3, 5, 7), + "XING": SongData(2900528, "5-3", "Happy Otaku Pack Vol.3", True, 4, 6, 8), + "Amakakeru Soukyuu no Serenade": SongData(2900529, "5-4", "Happy Otaku Pack Vol.3", False, 3, 6, 9), + "Gift box": SongData(2900530, "5-5", "Happy Otaku Pack Vol.3", False, 5, 7, 10), + "MUSEDASH!!!!": SongData(2900532, "4-0", "Happy Otaku Pack Vol.2", False, 2, 6, 9), + "Imprinting": SongData(2900533, "4-1", "Happy Otaku Pack Vol.2", False, 3, 6, 9), + "Skyward": SongData(2900534, "4-2", "Happy Otaku Pack Vol.2", True, 4, 7, 10), + "La nuit de vif": SongData(2900535, "4-3", "Happy Otaku Pack Vol.2", True, 2, 5, 8), + "Bit-alize": SongData(2900536, "4-4", "Happy Otaku Pack Vol.2", False, 3, 6, 8), + "GOODTEK": SongData(2900537, "4-5", "Happy Otaku Pack Vol.2", False, 4, 6, 9), + "Maharajah": SongData(2900539, "3-0", "Happy Otaku Pack Vol.1", False, 1, 3, 6), + "keep on running": SongData(2900540, "3-1", "Happy Otaku Pack Vol.1", False, 5, 7, 9), + "Kafig": SongData(2900541, "3-2", "Happy Otaku Pack Vol.1", True, 4, 6, 8), + "-+": SongData(2900542, "3-3", "Happy Otaku Pack Vol.1", True, 4, 6, 8), + "Tenri Kaku Jou": SongData(2900543, "3-4", "Happy Otaku Pack Vol.1", True, 3, 6, 9), + "Adjudicatorz-DanZai-": SongData(2900544, "3-5", "Happy Otaku Pack Vol.1", False, 3, 7, 10), + "Oriens": SongData(2900546, "2-0", "Give Up TREATMENT Vol.1", True, 3, 7, 9), + "PUPA": SongData(2900547, "2-1", "Give Up TREATMENT Vol.1", False, 6, 8, 11), + "Luna Express 2032": SongData(2900548, "2-2", "Give Up TREATMENT Vol.1", False, 4, 6, 8), + "Ukiyoe Yokochou": SongData(2900549, "2-3", "Give Up TREATMENT Vol.1", False, 6, 7, 9), + "Alice in Misanthrope": SongData(2900550, "2-4", "Give Up TREATMENT Vol.1", False, 5, 7, 10), + "GOODMEN": SongData(2900551, "2-5", "Give Up TREATMENT Vol.1", False, 5, 7, 10), + "Sunshine and Rainbow after August Rain": SongData(2900553, "1-0", "Cute Is Everything Vol.1", False, 2, 5, 8), + "Magical Number": SongData(2900554, "1-1", "Cute Is Everything Vol.1", False, 2, 5, 8), + "Dreaming Girl": SongData(2900555, "1-2", "Cute Is Everything Vol.1", False, 2, 5, 6), + "Daruma-san Fell Over": SongData(2900556, "1-3", "Cute Is Everything Vol.1", False, 3, 4, 6), + "Different": SongData(2900557, "1-4", "Cute Is Everything Vol.1", False, 1, 3, 6), + "The Future of the Phantom": SongData(2900558, "1-5", "Cute Is Everything Vol.1", False, 1, 3, 5), + "Doki Doki Jump!": SongData(2900560, "63-0", "MUSE RADIO FM104", True, 3, 5, 7), + "Centennial Streamers High": SongData(2900561, "63-1", "MUSE RADIO FM104", False, 4, 7, 9), + "Love Patrol": SongData(2900562, "63-2", "MUSE RADIO FM104", True, 3, 5, 7), + "Mahorova": SongData(2900563, "63-3", "MUSE RADIO FM104", True, 3, 5, 8), + "Yoru no machi": SongData(2900564, "63-4", "MUSE RADIO FM104", True, 1, 4, 7), + "INTERNET YAMERO": SongData(2900565, "63-5", "MUSE RADIO FM104", True, 6, 8, 10), + "Abracadabra": SongData(2900566, "43-24", "MD Plus Project", False, 6, 8, 10), + "Squalldecimator feat. EZ-Ven": SongData(2900567, "43-25", "MD Plus Project", True, 5, 7, 9), + "Amateras Rhythm": SongData(2900568, "43-26", "MD Plus Project", True, 6, 8, 11), + "Record one's Dream": SongData(2900569, "43-27", "MD Plus Project", False, 4, 7, 10), + "Lunatic": SongData(2900570, "43-28", "MD Plus Project", True, 5, 8, 10), + "Jiumeng": SongData(2900571, "43-29", "MD Plus Project", True, 3, 6, 8), + "The Day We Become Family": SongData(2900572, "43-30", "MD Plus Project", True, 3, 5, 8), + "Sutori ma FIRE!?!?": SongData(2900574, "64-0", "COSMIC RADIO PEROLIST", True, 3, 5, 8), + "Tanuki Step": SongData(2900575, "64-1", "COSMIC RADIO PEROLIST", True, 5, 7, 10), + "Space Stationery": SongData(2900576, "64-2", "COSMIC RADIO PEROLIST", True, 5, 7, 10), + "Songs Are Judged 90% by Chorus feat. Mameko": SongData(2900577, "64-3", "COSMIC RADIO PEROLIST", True, 6, 8, 10), + "Kawai Splendid Space Thief": SongData(2900578, "64-4", "COSMIC RADIO PEROLIST", False, 6, 8, 10), + "Night City Runway": SongData(2900579, "64-5", "COSMIC RADIO PEROLIST", True, 4, 6, 8), + "Chaos Shotgun feat. ChumuNote": SongData(2900580, "64-6", "COSMIC RADIO PEROLIST", True, 6, 8, 10), + "mew mew magical summer": SongData(2900581, "64-7", "COSMIC RADIO PEROLIST", False, 5, 8, 10), + "BrainDance": SongData(2900583, "65-0", "NeonAbyss", True, 3, 6, 9), + "My Focus!": SongData(2900584, "65-1", "NeonAbyss", True, 5, 7, 10), + "ABABABA BURST": SongData(2900585, "65-2", "NeonAbyss", True, 5, 7, 9), + "ULTRA HIGHER": SongData(2900586, "65-3", "NeonAbyss", True, 4, 7, 10), + "Silver Bullet": SongData(2900587, "43-31", "MD Plus Project", True, 5, 7, 10), + "Random": SongData(2900588, "43-32", "MD Plus Project", True, 4, 7, 9), + "OTOGE-BOSS-KYOKU-CHAN": SongData(2900589, "43-33", "MD Plus Project", False, 6, 8, 10), + "Crow Rabbit": SongData(2900590, "43-34", "MD Plus Project", True, 7, 9, 11), + "SyZyGy": SongData(2900591, "43-35", "MD Plus Project", True, 6, 8, 10), + "Mermaid Radio": SongData(2900592, "43-36", "MD Plus Project", True, 3, 5, 7), + "Helixir": SongData(2900593, "43-37", "MD Plus Project", False, 6, 8, 10), + "Highway Cruisin'": SongData(2900594, "43-38", "MD Plus Project", False, 3, 5, 8), + "JACK PT BOSS": SongData(2900595, "43-39", "MD Plus Project", False, 6, 8, 10), + "Time Capsule": SongData(2900596, "43-40", "MD Plus Project", False, 7, 9, 11), + "39 Music!": SongData(2900598, "66-0", "Miku in Museland", False, 3, 5, 8), + "Hand in Hand": SongData(2900599, "66-1", "Miku in Museland", False, 1, 3, 6), + "Cynical Night Plan": SongData(2900600, "66-2", "Miku in Museland", False, 4, 6, 8), + "God-ish": SongData(2900601, "66-3", "Miku in Museland", False, 4, 7, 10), + "Darling Dance": SongData(2900602, "66-4", "Miku in Museland", False, 4, 7, 9), + "Hatsune Creation Myth": SongData(2900603, "66-5", "Miku in Museland", False, 6, 8, 10), + "The Vampire": SongData(2900604, "66-6", "Miku in Museland", False, 4, 6, 9), + "Future Eve": SongData(2900605, "66-7", "Miku in Museland", False, 4, 8, 11), + "Unknown Mother Goose": SongData(2900606, "66-8", "Miku in Museland", False, 4, 8, 10), + "Shun-ran": SongData(2900607, "66-9", "Miku in Museland", False, 4, 7, 9), + "NICE TYPE feat. monii": SongData(2900608, "43-41", "MD Plus Project", True, 3, 6, 8), + "Rainy Angel": SongData(2900610, "67-0", "Happy Otaku Pack Vol.18", True, 4, 6, 9), + "Gullinkambi": SongData(2900611, "67-1", "Happy Otaku Pack Vol.18", True, 4, 7, 10), + "RakiRaki Rebuilders!!!": SongData(2900612, "67-2", "Happy Otaku Pack Vol.18", True, 5, 7, 10), + "Laniakea": SongData(2900613, "67-3", "Happy Otaku Pack Vol.18", False, 5, 8, 10), + "OTTAMA GAZER": SongData(2900614, "67-4", "Happy Otaku Pack Vol.18", True, 5, 8, 10), + "Sleep Tight feat.Macoto": SongData(2900615, "67-5", "Happy Otaku Pack Vol.18", True, 3, 5, 8), + "New York Back Raise": SongData(2900617, "68-0", "Gambler's Tricks", True, 6, 8, 10), + "slic.hertz": SongData(2900618, "68-1", "Gambler's Tricks", True, 5, 7, 9), + "Fuzzy-Navel": SongData(2900619, "68-2", "Gambler's Tricks", True, 6, 8, 10), + "Swing Edge": SongData(2900620, "68-3", "Gambler's Tricks", True, 4, 8, 10), + "Twisted Escape": SongData(2900621, "68-4", "Gambler's Tricks", True, 5, 8, 10), + "Swing Sweet Twee Dance": SongData(2900622, "68-5", "Gambler's Tricks", False, 4, 7, 10), + "Sanyousei SAY YA!!!": SongData(2900623, "43-42", "MD Plus Project", False, 4, 6, 8), + "YUKEMURI TAMAONSEN II": SongData(2900624, "43-43", "MD Plus Project", False, 3, 6, 9), + "Samayoi no mei Amatsu": SongData(2900626, "69-0", "Touhou Mugakudan -III-", False, 4, 6, 9), + "INTERNET SURVIVOR": SongData(2900627, "69-1", "Touhou Mugakudan -III-", False, 5, 8, 10), + "Shuki*RaiRai": SongData(2900628, "69-2", "Touhou Mugakudan -III-", False, 5, 7, 9), + "HELLOHELL": SongData(2900629, "69-3", "Touhou Mugakudan -III-", False, 4, 7, 10), + "Calamity Fortune": SongData(2900630, "69-4", "Touhou Mugakudan -III-", True, 6, 8, 10), + "Tsurupettan": SongData(2900631, "69-5", "Touhou Mugakudan -III-", True, 2, 5, 8), + "Twilight Poems": SongData(2900632, "43-44", "MD Plus Project", True, 3, 6, 8), + "All My Friends feat. RANASOL": SongData(2900633, "43-45", "MD Plus Project", True, 4, 7, 9), + "Heartache": SongData(2900634, "43-46", "MD Plus Project", True, 5, 7, 10), + "Blue Lemonade": SongData(2900635, "43-47", "MD Plus Project", True, 3, 6, 8), + "Haunted Dance": SongData(2900636, "43-48", "MD Plus Project", False, 6, 9, 11), + "Hey Vincent.": SongData(2900637, "43-49", "MD Plus Project", True, 6, 8, 10), + "Meteor feat. TEA": SongData(2900638, "43-50", "MD Plus Project", True, 3, 6, 9), + "Narcissism Angel": SongData(2900639, "43-51", "MD Plus Project", True, 1, 3, 6), + "AlterLuna": SongData(2900640, "43-52", "MD Plus Project", True, 6, 8, 11), + "Niki Tousen": SongData(2900641, "43-53", "MD Plus Project", True, 6, 8, 10), + "Rettou Joutou": SongData(2900643, "70-0", "Rin Len's Mirrorland", False, 4, 7, 9), + "Telecaster B-Boy": SongData(2900644, "70-1", "Rin Len's Mirrorland", False, 5, 7, 10), + "Iya Iya Iya": SongData(2900645, "70-2", "Rin Len's Mirrorland", False, 2, 4, 7), + "Nee Nee Nee": SongData(2900646, "70-3", "Rin Len's Mirrorland", False, 4, 6, 8), + "Chaotic Love Revolution": SongData(2900647, "70-4", "Rin Len's Mirrorland", False, 4, 6, 8), + "Dance of the Corpses": SongData(2900648, "70-5", "Rin Len's Mirrorland", False, 2, 5, 8), + "Bitter Choco Decoration": SongData(2900649, "70-6", "Rin Len's Mirrorland", False, 3, 6, 9), + "Dance Robot Dance": SongData(2900650, "70-7", "Rin Len's Mirrorland", False, 4, 7, 10), + "Sweet Devil": SongData(2900651, "70-8", "Rin Len's Mirrorland", False, 5, 7, 9), + "Someday'z Coming": SongData(2900652, "70-9", "Rin Len's Mirrorland", False, 5, 7, 9), + "Yume Ou Mono Yo Secret": SongData(2900653, "0-53", "Default Music", True, 6, 8, 10), + "Yume Ou Mono Yo": SongData(2900654, "0-54", "Default Music", True, 1, 4, None), + "Sweet Dream VIVINOS": SongData(2900656, "71-0", "Valentine Stage", False, 1, 4, 7), + "Ruler Of My Heart VIVINOS": SongData(2900657, "71-1", "Valentine Stage", False, 2, 4, 6), + "Reality Show": SongData(2900658, "71-2", "Valentine Stage", False, 5, 7, 10), + "SIG feat.Tobokegao": SongData(2900659, "71-3", "Valentine Stage", True, 3, 6, 8), + "Rose Love": SongData(2900660, "71-4", "Valentine Stage", True, 2, 4, 7), + "Euphoria": SongData(2900661, "71-5", "Valentine Stage", True, 1, 3, 6), + "P E R O P E R O Brother Dance": SongData(2900663, "72-0", "Legends of Muse Warriors", True, None, 7, None), + "PA PPA PANIC": SongData(2900664, "72-1", "Legends of Muse Warriors", False, 4, 8, 10), + "How To Make Music Game Song!": SongData(2900665, "72-2", "Legends of Muse Warriors", True, 6, 8, 10), + "Re Re": SongData(2900666, "72-3", "Legends of Muse Warriors", True, 7, 9, 11), + "Marmalade Twins": SongData(2900667, "72-4", "Legends of Muse Warriors", True, 5, 8, 10), + "DOMINATOR": SongData(2900668, "72-5", "Legends of Muse Warriors", True, 7, 9, 11), + "Teshikani TESHiKANi": SongData(2900669, "72-6", "Legends of Muse Warriors", True, 5, 7, 9), + "Urban Magic": SongData(2900671, "73-0", "Happy Otaku Pack Vol.19", True, 3, 5, 7), + "Maid's Prank": SongData(2900672, "73-1", "Happy Otaku Pack Vol.19", True, 5, 7, 10), + "Dance Dance Good Night Dance": SongData(2900673, "73-2", "Happy Otaku Pack Vol.19", True, 2, 4, 7), + "Ops Limone": SongData(2900674, "73-3", "Happy Otaku Pack Vol.19", True, 5, 8, 11), + "NOVA": SongData(2900675, "73-4", "Happy Otaku Pack Vol.19", True, 6, 8, 10), + "Heaven's Gradius": SongData(2900676, "73-5", "Happy Otaku Pack Vol.19", True, 6, 8, 10), + "Ray Tuning": SongData(2900678, "74-0", "CHUNITHM COURSE MUSE", True, 6, 8, 10), + "World Vanquisher": SongData(2900679, "74-1", "CHUNITHM COURSE MUSE", True, 6, 8, 10), + "Tsukuyomi Ni Naru Replaced": SongData(2900680, "74-2", "CHUNITHM COURSE MUSE", True, 5, 7, 9), + "The wheel to the right": SongData(2900681, "74-3", "CHUNITHM COURSE MUSE", True, 5, 7, 9), + "Climax": SongData(2900682, "74-4", "CHUNITHM COURSE MUSE", True, 4, 8, 11), + "Spider's Thread": SongData(2900683, "74-5", "CHUNITHM COURSE MUSE", True, 5, 8, 10), + "HIT ME UP": SongData(2900684, "43-54", "MD Plus Project", True, 4, 6, 8), + "Test Me feat. Uyeon": SongData(2900685, "43-55", "MD Plus Project", True, 3, 5, 9), + "Assault TAXI": SongData(2900686, "43-56", "MD Plus Project", True, 4, 7, 10), + "No": SongData(2900687, "43-57", "MD Plus Project", False, 4, 6, 9), + "Pop it": SongData(2900688, "43-58", "MD Plus Project", True, 1, 3, 6), + "HEARTBEAT! KyunKyun!": SongData(2900689, "43-59", "MD Plus Project", True, 4, 6, 9), + "SUPERHERO": SongData(2900691, "75-0", "Novice Rider Pack", False, 2, 4, 7), + "Highway_Summer": SongData(2900692, "75-1", "Novice Rider Pack", True, 2, 4, 6), + "Mx. Black Box": SongData(2900693, "75-2", "Novice Rider Pack", True, 5, 7, 9), + "Sweet Encounter": SongData(2900694, "75-3", "Novice Rider Pack", True, 2, 4, 7), + "Echo over you... Secret": SongData(2900695, "0-55", "Default Music", False, 6, 8, 10), + "Echo over you...": SongData(2900696, "0-56", "Default Music", False, 1, 4, None), + "Tsukuyomi Ni Naru": SongData(2900697, "74-6", "CHUNITHM COURSE MUSE", True, 5, 8, 10), + "disco light": SongData(2900699, "76-0", "MUSE RADIO FM105", True, 5, 7, 9), + "room light feat.chancylemon": SongData(2900700, "76-1", "MUSE RADIO FM105", True, 3, 5, 7), + "Invisible": SongData(2900701, "76-2", "MUSE RADIO FM105", True, 3, 5, 8), + "Christmas Season-LLABB": SongData(2900702, "76-3", "MUSE RADIO FM105", True, 1, 4, 7), + "Hyouryu": SongData(2900704, "77-0", "Let's Rhythm Jam!", False, 6, 8, 10), + "The Whole Rest": SongData(2900705, "77-1", "Let's Rhythm Jam!", False, 5, 8, 10), + "Hydra": SongData(2900706, "77-2", "Let's Rhythm Jam!", False, 4, 7, 11), + "Pastel Lines": SongData(2900707, "77-3", "Let's Rhythm Jam!", False, 3, 6, 9), + "LINK x LIN#S": SongData(2900708, "77-4", "Let's Rhythm Jam!", False, 3, 6, 9), + "Arcade ViruZ": SongData(2900709, "77-5", "Let's Rhythm Jam!", False, 6, 8, 11), + "Eve Avenir": SongData(2900711, "78-0", "Endless Pirouette", True, 6, 8, 10), + "Silverstring": SongData(2900712, "78-1", "Endless Pirouette", True, 5, 7, 10), + "Melusia": SongData(2900713, "78-2", "Endless Pirouette", False, 5, 7, 10), + "Devil's Castle": SongData(2900714, "78-3", "Endless Pirouette", True, 4, 7, 10), + "Abatement": SongData(2900715, "78-4", "Endless Pirouette", True, 6, 8, 10), + "Azalea": SongData(2900716, "78-5", "Endless Pirouette", False, 4, 8, 10), + "Brightly World": SongData(2900717, "78-6", "Endless Pirouette", True, 6, 8, 10), + "We'll meet in every world ***": SongData(2900718, "78-7", "Endless Pirouette", True, 7, 9, 11), + "Collapsar": SongData(2900719, "78-8", "Endless Pirouette", True, 7, 9, 10), + "Parousia": SongData(2900720, "78-9", "Endless Pirouette", False, 6, 8, 10), + "Gunners in the Rain": SongData(2900722, "79-0", "Ensemble Arcanum", False, 5, 8, 10), + "Halzion": SongData(2900723, "79-1", "Ensemble Arcanum", False, 2, 5, 8), + "SHOWTIME!!": SongData(2900724, "79-2", "Ensemble Arcanum", False, 6, 8, 10), + "Achromic Riddle": SongData(2900725, "79-3", "Ensemble Arcanum", False, 6, 8, 10), + "karanosu": SongData(2900726, "79-4", "Ensemble Arcanum", False, 3, 6, 8), + "Necromantic": SongData(2900727, "43-60", "MD Plus Project", False, 6, 8, 10), + "Saishuu kichiku imouto Flandre-S": SongData(2900729, "80-0", "Touhou Mugakudan -IV-", False, 6, 8, 10), + "Kachoufuugetsu": SongData(2900730, "80-1", "Touhou Mugakudan -IV-", False, 2, 6, 8), + "Maid heart is a puppet": SongData(2900731, "80-2", "Touhou Mugakudan -IV-", False, 5, 7, 9), + "Trance dance anarchy": SongData(2900732, "80-3", "Touhou Mugakudan -IV-", False, 4, 7, 10), + "fairy stage": SongData(2900733, "80-4", "Touhou Mugakudan -IV-", False, 4, 6, 9), + "Scarlet Police on Ghetto Patrol": SongData(2900734, "80-5", "Touhou Mugakudan -IV-", False, 5, 7, 10), + "Unwelcome School": SongData(2900735, "81-0", "MD-level Tactical Training Blu-ray", False, 6, 8, 10), + "Usagi Flap": SongData(2900736, "81-1", "MD-level Tactical Training Blu-ray", False, 3, 6, 8), + "RE Aoharu": SongData(2900737, "81-2", "MD-level Tactical Training Blu-ray", False, 3, 5, 8), + "Operation*DOTABATA!": SongData(2900738, "81-3", "MD-level Tactical Training Blu-ray", False, 5, 7, 10), +} diff --git a/worlds/musedash/MuseDashData.txt b/worlds/musedash/MuseDashData.txt deleted file mode 100644 index d913449ed540..000000000000 --- a/worlds/musedash/MuseDashData.txt +++ /dev/null @@ -1,597 +0,0 @@ -Magical Wonderland|0-48|Default Music|True|1|3|0| -Iyaiya|0-0|Default Music|True|1|4|0| -Wonderful Pain|0-2|Default Music|False|1|3|0| -Breaking Dawn|0-3|Default Music|True|2|4|0| -One-Way Subway|0-4|Default Music|True|1|4|0| -Frost Land|0-1|Default Music|False|1|3|6| -Heart-Pounding Flight|0-5|Default Music|True|2|5|0| -Pancake is Love|0-29|Default Music|True|2|4|7| -Shiguang Tuya|0-6|Default Music|True|2|5|0| -Evolution|0-37|Default Music|False|2|4|7| -Dolphin and Broadcast|0-7|Default Music|True|2|5|0| -Yuki no Shizuku Ame no Oto|0-8|Default Music|True|2|4|6| -Best One feat.tooko|0-43|Default Music|False|3|5|0| -Candy-coloured Love Theory|0-31|Default Music|False|2|4|6| -Night Wander|0-38|Default Music|False|3|5|7| -Dohna Dohna no Uta|0-46|Default Music|False|2|4|6| -Spring Carnival|0-9|Default Music|False|2|4|7| -DISCO NIGHT|0-30|Default Music|True|2|4|7| -Koi no Moonlight|0-49|Default Music|False|2|5|8| -Lian Ai Audio Navigation|0-10|Default Music|False|3|5|7| -Lights of Muse|0-11|Default Music|True|4|6|8|10 -midstream jam|0-12|Default Music|False|2|5|8| -Nihao|0-40|Default Music|False|3|5|7| -Confession|0-13|Default Music|False|3|5|8| -Galaxy Striker|0-32|Default Music|False|4|7|9| -Departure Road|0-14|Default Music|True|2|5|8| -Bass Telekinesis|0-15|Default Music|False|2|5|8| -Cage of Almeria|0-16|Default Music|True|3|5|7| -Ira|0-17|Default Music|True|4|6|8| -Blackest Luxury Car|0-18|Default Music|True|3|6|8| -Medicine of Sing|0-19|Default Music|False|3|6|8| -irregulyze|0-20|Default Music|True|3|6|8| -I don't care about Christmas though|0-47|Default Music|False|4|6|8| -Imaginary World|0-21|Default Music|True|4|6|8|10 -Dysthymia|0-22|Default Music|True|4|7|9| -From the New World|0-42|Default Music|False|2|5|7| -NISEGAO|0-33|Default Music|True|4|7|9| -Say! Fanfare!|0-44|Default Music|False|4|6|9| -Star Driver|0-34|Default Music|True|5|7|9| -Formation|0-23|Default Music|True|4|6|9| -Shinsou Masui|0-24|Default Music|True|4|6|10| -Mezame Eurythmics|0-50|Default Music|False|4|6|9| -Shenri Kuaira -repeat-|0-51|Default Music|False|5|7|9| -Latitude|0-25|Default Music|True|3|6|9| -Aqua Stars|0-39|Default Music|False|5|7|10| -Funkotsu Saishin Casino|0-26|Default Music|False|5|7|10| -Clock Room & Spiritual World|0-27|Default Music|True|4|6|9| -INTERNET OVERDOSE|0-52|Default Music|False|3|6|9| -Tu Hua|0-35|Default Music|True|4|7|9| -Mujinku-Vacuum|0-28|Default Music|False|5|7|11| -MilK|0-36|Default Music|False|5|7|9| -umpopoff|0-41|Default Music|False|0|?|0| -Mopemope|0-45|Default Music|False|4|7|9|11 -The Happycore Idol|43-0|MD Plus Project|True|2|5|7| -Amatsumikaboshi|43-1|MD Plus Project|True|4|6|8|10 -ARIGA THESIS|43-2|MD Plus Project|True|3|6|10| -Night of Nights|43-3|MD Plus Project|False|4|7|10| -#Psychedelic_Meguro_River|43-4|MD Plus Project|False|3|6|8| -can you feel it|43-5|MD Plus Project|False|4|6|8|9 -Midnight O'clock|43-6|MD Plus Project|True|3|6|8| -Rin|43-7|MD Plus Project|True|5|7|10| -Smile-mileS|43-8|MD Plus Project|False|6|8|10| -Believing and Being|43-9|MD Plus Project|True|4|6|9| -Catalyst|43-10|MD Plus Project|False|5|7|9| -don't!stop!eroero!|43-11|MD Plus Project|True|5|7|9| -pa pi pu pi pu pi pa|43-12|MD Plus Project|False|6|8|10| -Sand Maze|43-13|MD Plus Project|True|6|8|10|11 -Diffraction|43-14|MD Plus Project|True|5|8|10| -AKUMU|43-15|MD Plus Project|False|4|6|8| -Queen Aluett|43-16|MD Plus Project|True|7|9|11| -DROPS|43-17|MD Plus Project|False|2|5|8| -Frightfully-insane Flan-chan's frightful song|43-18|MD Plus Project|False|5|7|10| -snooze|43-19|MD Plus Project|False|5|7|10| -Kuishinbo Hacker feat.Kuishinbo Akachan|43-20|MD Plus Project|True|5|7|9| -Inu no outa|43-21|MD Plus Project|True|3|5|7| -Prism Fountain|43-22|MD Plus Project|True|7|9|11| -Gospel|43-23|MD Plus Project|False|4|6|9| -East Ai Li Lovely|62-0|Happy Otaku Pack Vol.17|False|2|4|7| -Mori Umi no Fune|62-1|Happy Otaku Pack Vol.17|True|5|7|9| -Ooi|62-2|Happy Otaku Pack Vol.17|True|5|7|10| -Numatta!!|62-3|Happy Otaku Pack Vol.17|True|5|7|9| -SATELLITE|62-4|Happy Otaku Pack Vol.17|False|5|7|9|10 -Fantasia Sonata Colorful feat. V!C|62-5|Happy Otaku Pack Vol.17|True|6|8|11| -MuseDash ka nanika hi|61-0|Ola Dash|True|?|?|¿| -Aleph-0|61-1|Ola Dash|True|7|9|11| -Buttoba Supernova|61-2|Ola Dash|False|5|7|10|11 -Rush-Hour|61-3|Ola Dash|False|IG|Jh|a2|Eh -3rd Avenue|61-4|Ola Dash|False|3|5|〇| -WORLDINVADER|61-5|Ola Dash|True|5|8|10|11 -N3V3R G3T OV3R|60-0|maimai DX Limited-time Suite|True|4|7|10| -Oshama Scramble!|60-1|maimai DX Limited-time Suite|True|5|7|10| -Valsqotch|60-2|maimai DX Limited-time Suite|True|5|9|11| -Paranormal My Mind|60-3|maimai DX Limited-time Suite|True|5|7|9| -Flower, snow and Drum'n'bass.|60-4|maimai DX Limited-time Suite|True|5|8|10|? -Amenohoakari|60-5|maimai DX Limited-time Suite|True|6|8|10| -Boiling Blood|59-0|MSR Anthology|True|5|8|10| -ManiFesto|59-1|MSR Anthology|True|4|6|9| -Operation Blade|59-2|MSR Anthology|True|3|5|7| -Radiant|59-3|MSR Anthology|True|3|5|8| -Renegade|59-4|MSR Anthology|True|3|5|8| -Speed of Light|59-5|MSR Anthology|False|1|4|7| -Dossoles Holiday|59-6|MSR Anthology|True|5|7|9| -Autumn Moods|59-7|MSR Anthology|True|3|5|7| -People People|58-0|Nanahira Paradise|True|5|7|9|11 -Endless Error Loop|58-1|Nanahira Paradise|True|4|7|9| -Forbidden Pizza!|58-2|Nanahira Paradise|True|5|7|9| -Don't Make the Vocalist do Anything Insane|58-3|Nanahira Paradise|True|5|8|9| -Tokimeki*Meteostrike|57-0|Happy Otaku Pack Vol.16|True|3|6|8| -Down Low|57-1|Happy Otaku Pack Vol.16|True|4|6|8| -LOUDER MACHINE|57-2|Happy Otaku Pack Vol.16|True|5|7|9| -Sorewa mo Lovechu|57-3|Happy Otaku Pack Vol.16|True|5|7|10| -Rave_Tech|57-4|Happy Otaku Pack Vol.16|True|5|8|10| -Brilliant & Shining!|57-5|Happy Otaku Pack Vol.16|False|5|8|10| -Psyched Fevereiro|56-0|Give Up TREATMENT Vol.11|False|5|8|10| -Inferno City|56-1|Give Up TREATMENT Vol.11|False|6|8|10| -Paradigm Shift|56-2|Give Up TREATMENT Vol.11|False|4|7|10| -Snapdragon|56-3|Give Up TREATMENT Vol.11|False|5|7|10| -Prestige and Vestige|56-4|Give Up TREATMENT Vol.11|True|6|8|11| -Tiny Fate|56-5|Give Up TREATMENT Vol.11|False|7|9|11| -Tsuki ni Murakumo Hana ni Kaze|55-0|Touhou Mugakudan -2-|False|3|5|7| -Patchouli's - Best Hit GSK|55-1|Touhou Mugakudan -2-|False|3|5|8| -Monosugoi Space Shuttle de Koishi ga Monosugoi uta|55-2|Touhou Mugakudan -2-|False|3|5|7|11 -Kakoinaki Yo wa Ichigo no Tsukikage|55-3|Touhou Mugakudan -2-|False|3|6|8| -Psychedelic Kizakura Doumei|55-4|Touhou Mugakudan -2-|False|4|7|10| -Mischievous Sensation|55-5|Touhou Mugakudan -2-|False|5|7|9| -White Canvas|54-0|MEGAREX THE FUTURE|False|3|6|8| -Gloomy Flash|54-1|MEGAREX THE FUTURE|False|5|8|10| -Find this Month's Featured Playlist|54-2|MEGAREX THE FUTURE|False|?|?|¿| -Sunday Night|54-3|MEGAREX THE FUTURE|False|3|6|9| -Goodbye Goodnight|54-4|MEGAREX THE FUTURE|False|4|6|9| -ENDLESS CIDER|54-5|MEGAREX THE FUTURE|False|4|6|8| -On And On!!|53-0|Happy Otaku Pack Vol.15|True|4|7|9|11 -Trip!|53-1|Happy Otaku Pack Vol.15|True|3|5|7| -Hoshi no otoshimono|53-2|Happy Otaku Pack Vol.15|False|5|7|9| -Plucky Race|53-3|Happy Otaku Pack Vol.15|True|5|8|10|11 -Fantasia Sonata Destiny|53-4|Happy Otaku Pack Vol.15|True|3|7|10| -Run through|53-5|Happy Otaku Pack Vol.15|False|5|8|10| -marooned night|52-0|MUSE RADIO FM103|False|2|4|6| -daydream girl|52-1|MUSE RADIO FM103|False|3|6|8| -Not Ornament|52-2|MUSE RADIO FM103|True|3|5|8| -Baby Pink|52-3|MUSE RADIO FM103|False|3|5|8| -I'm Here|52-4|MUSE RADIO FM103|False|4|6|8| -Masquerade Diary|51-0|Virtual Idol Production|True|2|5|8| -Reminiscence|51-1|Virtual Idol Production|True|5|7|9| -DarakuDatenshi|51-2|Virtual Idol Production|True|3|6|9| -D.I.Y.|51-3|Virtual Idol Production|False|4|6|9| -Boys in Virtual Land|51-4|Virtual Idol Production|False|4|7|9| -kui|51-5|Virtual Idol Production|True|5|7|9|11 -Nyan Cat|50-0|Nyanya Universe!|False|4|7|9| -PeroPero in the Universe|50-1|Nyanya Universe!|True|?|?|¿| -In-kya Yo-kya Onmyoji|50-2|Nyanya Universe!|False|6|8|10| -KABOOOOOM!!!!|50-3|Nyanya Universe!|True|4|6|8| -Doppelganger|50-4|Nyanya Universe!|True|5|7|9|12 -Pray a LOVE|49-0|DokiDoki! Valentine!|False|2|5|8| -Love-Avoidance Addiction|49-1|DokiDoki! Valentine!|False|3|5|7| -Daisuki Dayo feat.Wotoha|49-2|DokiDoki! Valentine!|False|5|7|10| -glory day|48-0|DJMAX Reflect|False|2|5|7| -Bright Dream|48-1|DJMAX Reflect|False|2|4|7| -Groovin Up|48-2|DJMAX Reflect|False|4|6|8| -I Want You|48-3|DJMAX Reflect|False|3|6|8| -OBLIVION|48-4|DJMAX Reflect|False|3|6|9| -Elastic STAR|48-5|DJMAX Reflect|False|4|6|8| -U.A.D|48-6|DJMAX Reflect|False|4|6|8|10 -Jealousy|48-7|DJMAX Reflect|False|3|5|7| -Memory of Beach|48-8|DJMAX Reflect|False|3|6|8| -Don't Die|48-9|DJMAX Reflect|False|6|8|10| -Y CE Ver.|48-10|DJMAX Reflect|False|4|6|9| -Fancy Night|48-11|DJMAX Reflect|False|4|6|8| -Can We Talk|48-12|DJMAX Reflect|False|4|6|8| -Give Me 5|48-13|DJMAX Reflect|False|2|6|8| -Nightmare|48-14|DJMAX Reflect|False|7|9|11| -Haze of Autumn|47-0|Arcaea|True|3|6|9| -GIMME DA BLOOD|47-1|Arcaea|False|3|6|9| -Libertas|47-2|Arcaea|False|4|7|10| -Cyaegha|47-3|Arcaea|False|5|7|9|11 -Bang!!|46-0|Happy Otaku Pack Vol.14|False|4|6|8| -Paradise 2|46-1|Happy Otaku Pack Vol.14|False|4|6|8| -Symbol|46-2|Happy Otaku Pack Vol.14|False|5|7|9| -Nekojarashi|46-3|Happy Otaku Pack Vol.14|False|5|8|10|11 -A Philosophical Wanderer|46-4|Happy Otaku Pack Vol.14|False|4|6|10| -Isouten|46-5|Happy Otaku Pack Vol.14|True|6|8|10|11 -ONOMATO Pairing!!!|45-0|WACCA Horizon|False|4|6|9| -with U|45-1|WACCA Horizon|False|6|8|10|11 -Chariot|45-2|WACCA Horizon|False|3|6|9| -GASHATT|45-3|WACCA Horizon|False|5|7|10| -LIN NE KRO NE feat. lasah|45-4|WACCA Horizon|False|6|8|10| -ANGEL HALO|45-5|WACCA Horizon|False|5|8|11| -Party in the HOLLOWood|44-0|Happy Otaku Pack Vol.13|False|3|6|8| -Ying Ying da Zuozhan|44-1|Happy Otaku Pack Vol.13|True|5|7|9| -Howlin' Pumpkin|44-2|Happy Otaku Pack Vol.13|True|4|6|8| -Bad Apple!! feat. Nomico|42-0|Touhou Mugakudan -1-|False|1|3|6|8 -Iro wa Nioedo, Chirinuru wo|42-1|Touhou Mugakudan -1-|False|2|4|7| -Cirno's Perfect Math Class|42-2|Touhou Mugakudan -1-|False|4|7|9| -Hiiro Gekka Kyousai no Zetsu|42-3|Touhou Mugakudan -1-|False|4|6|8| -Flowery Moonlit Night|42-4|Touhou Mugakudan -1-|False|3|6|8| -Unconscious Requiem|42-5|Touhou Mugakudan -1-|False|3|6|8| -Super Battleworn Insomniac|41-0|7th Beat Games|True|4|7|9|? -Bomb-Sniffing Pomeranian|41-1|7th Beat Games|True|4|6|8| -Rollerdisco Rumble|41-2|7th Beat Games|True|4|6|9| -Rose Garden|41-3|7th Beat Games|False|5|8|9| -EMOMOMO|41-4|7th Beat Games|True|4|7|10| -Heracles|41-5|7th Beat Games|False|6|8|10|? -Rush-More|40-0|Happy Otaku Pack Vol.12|False|4|7|9| -Kill My Fortune|40-1|Happy Otaku Pack Vol.12|False|5|7|10| -Yosari Tsukibotaru Suminoborite|40-2|Happy Otaku Pack Vol.12|False|5|7|9| -JUMP! HardCandy|40-3|Happy Otaku Pack Vol.12|False|3|6|8| -Hibari|40-4|Happy Otaku Pack Vol.12|False|3|5|8| -OCCHOCO-REST-LESS|40-5|Happy Otaku Pack Vol.12|True|4|7|9| -See-Saw Day|39-0|MUSE RADIO FM102|True|1|3|6| -happy hour|39-1|MUSE RADIO FM102|True|2|4|7| -Seikimatsu no Natsu|39-2|MUSE RADIO FM102|True|4|6|8| -twinkle night|39-3|MUSE RADIO FM102|False|3|6|8| -ARUYA HARERUYA|39-4|MUSE RADIO FM102|False|2|5|7| -Blush|39-5|MUSE RADIO FM102|False|2|4|7| -Naked Summer|39-6|MUSE RADIO FM102|True|4|6|8| -BLESS ME|39-7|MUSE RADIO FM102|True|2|5|7| -FM 17314 SUGAR RADIO|39-8|MUSE RADIO FM102|True|?|?|?| -NO ONE YES MAN|38-0|Phigros|False|5|7|9| -Snowfall, Merry Christmas|38-1|Phigros|False|5|8|10| -Igallta|38-2|Phigros|False|6|8|10|11 -Colored Glass|37-0|Cute Is Everything Vol.7|False|1|4|7| -Neonlights|37-1|Cute Is Everything Vol.7|False|4|7|9| -Hope for the flowers|37-2|Cute Is Everything Vol.7|False|4|7|9| -Seaside Cycling on May 30|37-3|Cute Is Everything Vol.7|False|3|6|8| -SKY HIGH|37-4|Cute Is Everything Vol.7|False|2|4|6| -Mousou Chu!!|37-5|Cute Is Everything Vol.7|False|4|7|8| -NightTheater|36-0|Give Up TREATMENT Vol.10|True|6|8|11| -Cutter|36-1|Give Up TREATMENT Vol.10|False|4|7|10| -bamboo|36-2|Give Up TREATMENT Vol.10|False|6|8|10|11 -enchanted love|36-3|Give Up TREATMENT Vol.10|False|2|6|9| -c.s.q.n.|36-4|Give Up TREATMENT Vol.10|False|5|8|11| -Booouncing!!|36-5|Give Up TREATMENT Vol.10|False|5|7|10| -PeroPeroGames goes Bankrupt|35-0|Happy Otaku Pack SP|True|6|8|10| -MARENOL|35-1|Happy Otaku Pack SP|False|4|7|10| -I am really good at Japanese style|35-2|Happy Otaku Pack SP|True|6|8|10| -Rush B|35-3|Happy Otaku Pack SP|True|4|7|9| -DataErr0r|35-4|Happy Otaku Pack SP|False|5|7|9|? -Burn|35-5|Happy Otaku Pack SP|True|4|7|9| -ALiVE|34-0|HARDCORE TANO*C|False|5|7|10| -BATTLE NO.1|34-1|HARDCORE TANO*C|False|5|8|10|11 -Cthugha|34-2|HARDCORE TANO*C|False|6|8|10|11 -TWINKLE*MAGIC|34-3|HARDCORE TANO*C|False|4|7|10|11 -Comet Coaster|34-4|HARDCORE TANO*C|False|6|8|10|11 -XODUS|34-5|HARDCORE TANO*C|False|7|9|11|12 -Fireflies|33-0|cyTus|True|1|4|7| -Light up my love!!|33-1|cyTus|True|3|5|7| -Happiness Breeze|33-2|cyTus|True|4|6|8|9 -Chrome VOX|33-3|cyTus|True|6|8|10|11 -CHAOS|33-4|cyTus|True|3|6|9| -Saika|33-5|cyTus|True|3|5|8| -Standby for Action|33-6|cyTus|True|4|6|8| -Hydrangea|33-7|cyTus|True|5|7|9| -Amenemhat|33-8|cyTus|True|6|8|10| -Santouka|33-9|cyTus|True|2|5|8| -HEXENNACHTROCK-katashihaya-|33-10|cyTus|True|4|8|10| -Blah!!|33-11|cyTus|True|5|8|11| -CHAOS Glitch|33-12|cyTus|True|0|?|0| -Preparara|32-0|Let's Do Bad Things Together|False|1|4|6| -Whatcha;Whatcha Doin'|32-1|Let's Do Bad Things Together|False|3|6|9| -Madara|32-2|Let's Do Bad Things Together|False|4|6|9| -pICARESq|32-3|Let's Do Bad Things Together|False|4|6|8| -Desastre|32-4|Let's Do Bad Things Together|False|4|6|8| -Shoot for the Moon|32-5|Let's Do Bad Things Together|False|2|5|8| -The 90's Decision|31-0|Happy Otaku Pack Vol.11|True|5|7|9| -Medusa|31-1|Happy Otaku Pack Vol.11|False|4|6|8|10 -Final Step!|31-2|Happy Otaku Pack Vol.11|False|5|7|10| -MAGENTA POTION|31-3|Happy Otaku Pack Vol.11|False|4|7|9| -Cross Ray|31-4|Happy Otaku Pack Vol.11|False|3|6|9| -Square Lake|31-5|Happy Otaku Pack Vol.11|False|6|8|9|11 -Girly Cupid|30-0|Cute Is Everything Vol.6|False|3|6|8| -sheep in the light|30-1|Cute Is Everything Vol.6|False|2|5|8| -Breaker city|30-2|Cute Is Everything Vol.6|False|4|6|9| -heterodoxy|30-3|Cute Is Everything Vol.6|False|4|6|8| -Computer Music Girl|30-4|Cute Is Everything Vol.6|False|3|5|7| -Focus Point|30-5|Cute Is Everything Vol.6|True|2|5|7| -Groove Prayer|29-0|Let' s GROOVE!|True|3|5|7| -FUJIN Rumble|29-1|Let' s GROOVE!|True|5|7|10|11 -Marry me, Nightmare|29-2|Let' s GROOVE!|False|6|8|11| -HG Makaizou Polyvinyl Shounen|29-3|Let' s GROOVE!|True|4|7|9|10 -Seizya no Ibuki|29-4|Let' s GROOVE!|True|6|8|10| -ouroboros -twin stroke of the end-|29-5|Let' s GROOVE!|True|4|6|9|12 -Heisha Onsha|28-0|Happy Otaku Pack Vol.10|False|4|6|8| -Ginevra|28-1|Happy Otaku Pack Vol.10|True|5|7|10|10 -Paracelestia|28-2|Happy Otaku Pack Vol.10|False|5|8|10| -un secret|28-3|Happy Otaku Pack Vol.10|False|2|4|6| -Good Life|28-4|Happy Otaku Pack Vol.10|False|4|6|8| -nini-nini-|28-5|Happy Otaku Pack Vol.10|False|4|7|9| -Can I friend you on Bassbook? lol|27-0|Nanahira Festival|False|3|6|8| -Gaming*Everything|27-1|Nanahira Festival|False|5|8|11| -Renji de haochi|27-2|Nanahira Festival|False|5|7|9| -You Make My Life 1UP|27-3|Nanahira Festival|False|4|6|8| -Newbies, Geeks, Internets|27-4|Nanahira Festival|False|6|8|10| -Onegai!Kon kon Oinarisama|27-5|Nanahira Festival|False|3|6|9| -Legend of Eastern Rabbit -SKY DEFENDER-|26-0|Give Up TREATMENT Vol.9|False|4|6|9| -ENERGY SYNERGY MATRIX|26-1|Give Up TREATMENT Vol.9|False|6|8|10| -Punai Punai Genso|26-2|Give Up TREATMENT Vol.9|False|2|7|11| -Better Graphic Animation|26-3|Give Up TREATMENT Vol.9|False|5|8|11| -Variant Cross|26-4|Give Up TREATMENT Vol.9|False|4|7|10| -Ultra Happy Miracle Bazoooooka!!|26-5|Give Up TREATMENT Vol.9|False|7|9|11| -tape/stop/night|25-0|MUSE RADIO FM101|True|3|5|7| -Pixel Galaxy|25-1|MUSE RADIO FM101|False|2|5|8| -Notice|25-2|MUSE RADIO FM101|False|4|7|10| -Strawberry Godzilla|25-3|MUSE RADIO FM101|True|2|5|7| -OKIMOCHI EXPRESSION|25-4|MUSE RADIO FM101|False|4|6|10| -Kimi to pool disco|25-5|MUSE RADIO FM101|False|4|6|8| -The Last Page|24-0|Happy Otaku Pack Vol.9|False|3|5|7| -IKAROS|24-1|Happy Otaku Pack Vol.9|False|4|7|10| -Tsukuyomi|24-2|Happy Otaku Pack Vol.9|False|3|6|9| -Future Stream|24-3|Happy Otaku Pack Vol.9|False|4|6|8| -FULi AUTO SHOOTER|24-4|Happy Otaku Pack Vol.9|True|4|7|9| -GOODFORTUNE|24-5|Happy Otaku Pack Vol.9|False|5|7|9| -The Dessert After Rain|23-0|Cute Is Everything Vol.5|True|2|4|6| -Confession Support Formula|23-1|Cute Is Everything Vol.5|False|3|5|7| -Omatsuri|23-2|Cute Is Everything Vol.5|False|1|3|6| -FUTUREPOP|23-3|Cute Is Everything Vol.5|True|2|5|7| -The Breeze|23-4|Cute Is Everything Vol.5|False|1|4|6| -I LOVE LETTUCE FRIED RICE!!|23-5|Cute Is Everything Vol.5|False|3|7|9| -The NightScape|22-0|Give Up TREATMENT Vol.8|False|4|7|9| -FREEDOM DiVE|22-1|Give Up TREATMENT Vol.8|False|6|8|10|12 -Phi|22-2|Give Up TREATMENT Vol.8|False|5|8|10| -Lueur de la nuit|22-3|Give Up TREATMENT Vol.8|False|6|8|11| -Creamy Sugary OVERDRIVE!!!|22-4|Give Up TREATMENT Vol.8|True|4|7|10| -Disorder|22-5|Give Up TREATMENT Vol.8|False|5|7|11| -Glimmer|21-0|Budget Is Burning: Nano Core|False|2|5|8| -EXIST|21-1|Budget Is Burning: Nano Core|False|3|5|8| -Irreplaceable|21-2|Budget Is Burning: Nano Core|False|4|6|8| -Moonlight Banquet|20-0|Happy Otaku Pack Vol.8|True|2|5|8| -Flashdance|20-1|Happy Otaku Pack Vol.8|False|3|6|9| -INFiNiTE ENERZY -Overdoze-|20-2|Happy Otaku Pack Vol.8|False|4|7|9|10 -One Way Street|20-3|Happy Otaku Pack Vol.8|False|3|6|10| -This Club is Not 4 U|20-4|Happy Otaku Pack Vol.8|False|4|7|9| -ULTRA MEGA HAPPY PARTY!!!|20-5|Happy Otaku Pack Vol.8|False|5|7|10| -INFINITY|19-0|Give Up TREATMENT Vol.7|True|5|8|10| -Punai Punai Senso|19-1|Give Up TREATMENT Vol.7|False|2|7|11| -Maxi|19-2|Give Up TREATMENT Vol.7|False|5|8|10| -YInMn Blue|19-3|Give Up TREATMENT Vol.7|False|6|8|10| -Plumage|19-4|Give Up TREATMENT Vol.7|False|4|7|10| -Dr.Techro|19-5|Give Up TREATMENT Vol.7|False|7|9|11| -SWEETSWEETSWEET|18-0|Cute Is Everything Vol.4|True|2|5|7| -Deep Blue and the Breaths of the Night|18-1|Cute Is Everything Vol.4|True|2|4|6| -Joy Connection|18-2|Cute Is Everything Vol.4|False|3|6|8| -Self Willed Girl Ver.B|18-3|Cute Is Everything Vol.4|True|4|6|8| -Just Disobedient|18-4|Cute Is Everything Vol.4|False|3|6|8| -Holy Sh*t Grass Snake|18-5|Cute Is Everything Vol.4|False|2|6|9| -Cotton Candy Wonderland|17-0|Happy Otaku Pack Vol.7|False|2|5|8| -Punai Punai Taiso|17-1|Happy Otaku Pack Vol.7|False|2|7|10| -Fly High|17-2|Happy Otaku Pack Vol.7|False|3|5|7| -prejudice|17-3|Happy Otaku Pack Vol.7|True|4|6|9| -The 89's Momentum|17-4|Happy Otaku Pack Vol.7|True|5|7|9| -energy night|17-5|Happy Otaku Pack Vol.7|True|5|7|10| -Future Dive|16-0|Give Up TREATMENT Vol.6|True|4|6|9| -Re End of a Dream|16-1|Give Up TREATMENT Vol.6|False|5|8|11| -Etude -Storm-|16-2|Give Up TREATMENT Vol.6|True|6|8|10| -Unlimited Katharsis|16-3|Give Up TREATMENT Vol.6|False|4|6|10| -Magic Knight Girl|16-4|Give Up TREATMENT Vol.6|False|4|7|9| -Eeliaas|16-5|Give Up TREATMENT Vol.6|False|6|9|11| -Magic Spell|15-0|Cute Is Everything Vol.3|True|2|5|7| -Colorful Star, Colored Drawing, Travel Poem|15-1|Cute Is Everything Vol.3|False|3|4|6| -Satell Knight|15-2|Cute Is Everything Vol.3|False|3|6|8| -Black River Feat.Mes|15-3|Cute Is Everything Vol.3|True|1|4|6| -I am sorry|15-4|Cute Is Everything Vol.3|False|2|5|8| -Ueta Tori Tachi|15-5|Cute Is Everything Vol.3|False|3|6|8| -Elysion's Old Mans|14-0|Happy Otaku Pack Vol.6|False|3|5|8| -AXION|14-1|Happy Otaku Pack Vol.6|False|4|5|8| -Amnesia|14-2|Happy Otaku Pack Vol.6|True|3|6|9| -Onsen Dai Sakusen|14-3|Happy Otaku Pack Vol.6|True|4|6|8| -Gleam stone|14-4|Happy Otaku Pack Vol.6|False|4|7|9| -GOODWORLD|14-5|Happy Otaku Pack Vol.6|False|4|7|10| -Instant Soluble Neon|13-0|Cute Is Everything Vol.2|True|2|4|7| -Retrospective Poem on the Planet|13-1|Cute Is Everything Vol.2|False|3|5|7| -I'm Gonna Buy! Buy! Buy!|13-2|Cute Is Everything Vol.2|True|4|6|8| -Dating Manifesto|13-3|Cute Is Everything Vol.2|True|2|4|6| -First Snow|13-4|Cute Is Everything Vol.2|True|2|3|6| -Xin Shang Huahai|13-5|Cute Is Everything Vol.2|False|3|6|8| -Gaikan Chrysalis|12-0|Give Up TREATMENT Vol.5|False|4|6|8| -Sterelogue|12-1|Give Up TREATMENT Vol.5|True|5|7|10| -Cheshire's Dance|12-2|Give Up TREATMENT Vol.5|True|4|7|10| -Skrik|12-3|Give Up TREATMENT Vol.5|True|5|7|11| -Soda Pop Canva5!|12-4|Give Up TREATMENT Vol.5|False|5|8|10| -RUBY LINTe|12-5|Give Up TREATMENT Vol.5|False|5|8|11| -Brave My Heart|11-0|Happy Otaku Pack Vol.5|True|3|5|7| -Sakura Fubuki|11-1|Happy Otaku Pack Vol.5|False|4|7|10| -8bit Adventurer|11-2|Happy Otaku Pack Vol.5|False|6|8|10| -Suffering of screw|11-3|Happy Otaku Pack Vol.5|False|3|5|8| -tiny lady|11-4|Happy Otaku Pack Vol.5|True|4|6|9| -Power Attack|11-5|Happy Otaku Pack Vol.5|False|5|7|10| -Destr0yer|10-0|Give Up TREATMENT Vol.4|False|4|7|9| -Noel|10-1|Give Up TREATMENT Vol.4|False|5|8|10| -Kyoukiranbu|10-2|Give Up TREATMENT Vol.4|False|7|9|11| -Two Phace|10-3|Give Up TREATMENT Vol.4|True|4|7|10| -Fly Again|10-4|Give Up TREATMENT Vol.4|False|5|7|10| -ouroVoros|10-5|Give Up TREATMENT Vol.4|False|7|9|11| -Leave It Alone|9-0|Happy Otaku Pack Vol.4|True|2|5|8| -Tsubasa no Oreta Tenshitachi no Requiem|9-1|Happy Otaku Pack Vol.4|False|4|7|9| -Chronomia|9-2|Happy Otaku Pack Vol.4|False|5|7|10| -Dandelion's Daydream|9-3|Happy Otaku Pack Vol.4|True|5|7|8| -Lorikeet Flat design|9-4|Happy Otaku Pack Vol.4|True|5|7|10| -GOODRAGE|9-5|Happy Otaku Pack Vol.4|False|6|9|11| -Altale|8-0|Give Up TREATMENT Vol.3|False|3|5|7|10 -Brain Power|8-1|Give Up TREATMENT Vol.3|False|4|7|10| -Berry Go!!|8-2|Give Up TREATMENT Vol.3|False|3|6|9| -Sweet* Witch* Girl*|8-3|Give Up TREATMENT Vol.3|False|6|8|10|? -trippers feeling!|8-4|Give Up TREATMENT Vol.3|True|5|7|9|11 -Lilith ambivalence lovers|8-5|Give Up TREATMENT Vol.3|False|5|8|10| -Brave My Soul|7-0|Give Up TREATMENT Vol.2|False|4|6|8| -Halcyon|7-1|Give Up TREATMENT Vol.2|False|4|7|10| -Crimson Nightingale|7-2|Give Up TREATMENT Vol.2|True|4|7|10| -Invader|7-3|Give Up TREATMENT Vol.2|True|3|7|11| -Lyrith|7-4|Give Up TREATMENT Vol.2|False|5|7|10| -GOODBOUNCE|7-5|Give Up TREATMENT Vol.2|False|4|6|9| -Out of Sense|6-0|Budget Is Burning Vol.1|False|3|5|8| -My Life Is For You|6-1|Budget Is Burning Vol.1|False|2|4|7| -Etude -Sunset-|6-2|Budget Is Burning Vol.1|True|5|7|9| -Goodbye Boss|6-3|Budget Is Burning Vol.1|False|4|6|8| -Stargazer|6-4|Budget Is Burning Vol.1|True|2|5|8|9 -Lys Tourbillon|6-5|Budget Is Burning Vol.1|True|4|6|8| -Thirty Million Persona|5-0|Happy Otaku Pack Vol.3|False|2|4|6| -conflict|5-1|Happy Otaku Pack Vol.3|False|2|6|9|10 -Enka Dance Music|5-2|Happy Otaku Pack Vol.3|False|3|5|7| -XING|5-3|Happy Otaku Pack Vol.3|True|4|6|8|9 -Amakakeru Soukyuu no Serenade|5-4|Happy Otaku Pack Vol.3|False|3|6|9| -Gift box|5-5|Happy Otaku Pack Vol.3|False|5|7|10| -MUSEDASH!!!!|4-0|Happy Otaku Pack Vol.2|False|2|6|9|0 -Imprinting|4-1|Happy Otaku Pack Vol.2|False|3|6|9|0 -Skyward|4-2|Happy Otaku Pack Vol.2|True|4|7|10|0 -La nuit de vif|4-3|Happy Otaku Pack Vol.2|True|2|5|8|0 -Bit-alize|4-4|Happy Otaku Pack Vol.2|False|3|6|8|0 -GOODTEK|4-5|Happy Otaku Pack Vol.2|False|4|6|9|? -Maharajah|3-0|Happy Otaku Pack Vol.1|False|1|3|6| -keep on running|3-1|Happy Otaku Pack Vol.1|False|5|7|9| -Kafig|3-2|Happy Otaku Pack Vol.1|True|4|6|8| --+|3-3|Happy Otaku Pack Vol.1|True|4|6|8| -Tenri Kaku Jou|3-4|Happy Otaku Pack Vol.1|True|3|6|9| -Adjudicatorz-DanZai-|3-5|Happy Otaku Pack Vol.1|False|3|7|10| -Oriens|2-0|Give Up TREATMENT Vol.1|True|3|7|9| -PUPA|2-1|Give Up TREATMENT Vol.1|False|6|8|11| -Luna Express 2032|2-2|Give Up TREATMENT Vol.1|False|4|6|8| -Ukiyoe Yokochou|2-3|Give Up TREATMENT Vol.1|False|6|7|9| -Alice in Misanthrope|2-4|Give Up TREATMENT Vol.1|False|5|7|10| -GOODMEN|2-5|Give Up TREATMENT Vol.1|False|5|7|10| -Sunshine and Rainbow after August Rain|1-0|Cute Is Everything Vol.1|False|2|5|8| -Magical Number|1-1|Cute Is Everything Vol.1|False|2|5|8| -Dreaming Girl|1-2|Cute Is Everything Vol.1|False|2|5|6| -Daruma-san Fell Over|1-3|Cute Is Everything Vol.1|False|3|4|6| -Different|1-4|Cute Is Everything Vol.1|False|1|3|6| -The Future of the Phantom|1-5|Cute Is Everything Vol.1|False|1|3|5| -Doki Doki Jump!|63-0|MUSE RADIO FM104|True|3|5|7| -Centennial Streamers High|63-1|MUSE RADIO FM104|False|4|7|9| -Love Patrol|63-2|MUSE RADIO FM104|True|3|5|7| -Mahorova|63-3|MUSE RADIO FM104|True|3|5|8| -Yoru no machi|63-4|MUSE RADIO FM104|True|1|4|7| -INTERNET YAMERO|63-5|MUSE RADIO FM104|True|6|8|10| -Abracadabra|43-24|MD Plus Project|False|6|8|10| -Squalldecimator feat. EZ-Ven|43-25|MD Plus Project|True|5|7|9| -Amateras Rhythm|43-26|MD Plus Project|True|6|8|11| -Record one's Dream|43-27|MD Plus Project|False|4|7|10| -Lunatic|43-28|MD Plus Project|True|5|8|10| -Jiumeng|43-29|MD Plus Project|True|3|6|8| -The Day We Become Family|43-30|MD Plus Project|True|3|5|8| -Sutori ma FIRE!?!?|64-0|COSMIC RADIO PEROLIST|True|3|5|8| -Tanuki Step|64-1|COSMIC RADIO PEROLIST|True|5|7|10|11 -Space Stationery|64-2|COSMIC RADIO PEROLIST|True|5|7|10| -Songs Are Judged 90% by Chorus feat. Mameko|64-3|COSMIC RADIO PEROLIST|True|6|8|10| -Kawai Splendid Space Thief|64-4|COSMIC RADIO PEROLIST|False|6|8|10|11 -Night City Runway|64-5|COSMIC RADIO PEROLIST|True|4|6|8| -Chaos Shotgun feat. ChumuNote|64-6|COSMIC RADIO PEROLIST|True|6|8|10| -mew mew magical summer|64-7|COSMIC RADIO PEROLIST|False|5|8|10|11 -BrainDance|65-0|NeonAbyss|True|3|6|9| -My Focus!|65-1|NeonAbyss|True|5|7|10| -ABABABA BURST|65-2|NeonAbyss|True|5|7|9| -ULTRA HIGHER|65-3|NeonAbyss|True|4|7|10| -Silver Bullet|43-31|MD Plus Project|True|5|7|10| -Random|43-32|MD Plus Project|True|4|7|9| -OTOGE-BOSS-KYOKU-CHAN|43-33|MD Plus Project|False|6|8|10|11 -Crow Rabbit|43-34|MD Plus Project|True|7|9|11| -SyZyGy|43-35|MD Plus Project|True|6|8|10|11 -Mermaid Radio|43-36|MD Plus Project|True|3|5|7| -Helixir|43-37|MD Plus Project|False|6|8|10| -Highway Cruisin'|43-38|MD Plus Project|False|3|5|8| -JACK PT BOSS|43-39|MD Plus Project|False|6|8|10| -Time Capsule|43-40|MD Plus Project|False|7|9|11| -39 Music!|66-0|Miku in Museland|False|3|5|8| -Hand in Hand|66-1|Miku in Museland|False|1|3|6| -Cynical Night Plan|66-2|Miku in Museland|False|4|6|8| -God-ish|66-3|Miku in Museland|False|4|7|10| -Darling Dance|66-4|Miku in Museland|False|4|7|9| -Hatsune Creation Myth|66-5|Miku in Museland|False|6|8|10|11 -The Vampire|66-6|Miku in Museland|False|4|6|9| -Future Eve|66-7|Miku in Museland|False|4|8|11| -Unknown Mother Goose|66-8|Miku in Museland|False|4|8|10| -Shun-ran|66-9|Miku in Museland|False|4|7|9| -NICE TYPE feat. monii|43-41|MD Plus Project|True|3|6|8| -Rainy Angel|67-0|Happy Otaku Pack Vol.18|True|4|6|9|11 -Gullinkambi|67-1|Happy Otaku Pack Vol.18|True|4|7|10| -RakiRaki Rebuilders!!!|67-2|Happy Otaku Pack Vol.18|True|5|7|10| -Laniakea|67-3|Happy Otaku Pack Vol.18|False|5|8|10| -OTTAMA GAZER|67-4|Happy Otaku Pack Vol.18|True|5|8|10| -Sleep Tight feat.Macoto|67-5|Happy Otaku Pack Vol.18|True|3|5|8| -New York Back Raise|68-0|Gambler's Tricks|True|6|8|10| -slic.hertz|68-1|Gambler's Tricks|True|5|7|9| -Fuzzy-Navel|68-2|Gambler's Tricks|True|6|8|10|11 -Swing Edge|68-3|Gambler's Tricks|True|4|8|10| -Twisted Escape|68-4|Gambler's Tricks|True|5|8|10|11 -Swing Sweet Twee Dance|68-5|Gambler's Tricks|False|4|7|10| -Sanyousei SAY YA!!!|43-42|MD Plus Project|False|4|6|8| -YUKEMURI TAMAONSEN II|43-43|MD Plus Project|False|3|6|9| -Samayoi no mei Amatsu|69-0|Touhou Mugakudan -3-|False|4|6|9| -INTERNET SURVIVOR|69-1|Touhou Mugakudan -3-|False|5|8|10| -Shuki*RaiRai|69-2|Touhou Mugakudan -3-|False|5|7|9| -HELLOHELL|69-3|Touhou Mugakudan -3-|False|4|7|10| -Calamity Fortune|69-4|Touhou Mugakudan -3-|True|6|8|10|11 -Tsurupettan|69-5|Touhou Mugakudan -3-|True|2|5|8| -Twilight Poems|43-44|MD Plus Project|True|3|6|8| -All My Friends feat. RANASOL|43-45|MD Plus Project|True|4|7|9| -Heartache|43-46|MD Plus Project|True|5|7|10| -Blue Lemonade|43-47|MD Plus Project|True|3|6|8| -Haunted Dance|43-48|MD Plus Project|False|6|9|11| -Hey Vincent.|43-49|MD Plus Project|True|6|8|10| -Meteor feat. TEA|43-50|MD Plus Project|True|3|6|9| -Narcissism Angel|43-51|MD Plus Project|True|1|3|6| -AlterLuna|43-52|MD Plus Project|True|6|8|11|12 -Niki Tousen|43-53|MD Plus Project|True|6|8|10|12 -Rettou Joutou|70-0|Rin Len's Mirrorland|False|4|7|9| -Telecaster B-Boy|70-1|Rin Len's Mirrorland|False|5|7|10| -Iya Iya Iya|70-2|Rin Len's Mirrorland|False|2|4|7| -Nee Nee Nee|70-3|Rin Len's Mirrorland|False|4|6|8| -Chaotic Love Revolution|70-4|Rin Len's Mirrorland|False|4|6|8| -Dance of the Corpses|70-5|Rin Len's Mirrorland|False|2|5|8| -Bitter Choco Decoration|70-6|Rin Len's Mirrorland|False|3|6|9| -Dance Robot Dance|70-7|Rin Len's Mirrorland|False|4|7|10| -Sweet Devil|70-8|Rin Len's Mirrorland|False|5|7|9| -Someday'z Coming|70-9|Rin Len's Mirrorland|False|5|7|9| -Yume Ou Mono Yo Secret|0-53|Default Music|True|6|8|10| -Yume Ou Mono Yo|0-54|Default Music|True|1|4|0| -Sweet Dream VIVINOS|71-0|Valentine Stage|False|1|4|7| -Ruler Of My Heart VIVINOS|71-1|Valentine Stage|False|2|4|6| -Reality Show|71-2|Valentine Stage|False|5|7|10| -SIG feat.Tobokegao|71-3|Valentine Stage|True|3|6|8| -Rose Love|71-4|Valentine Stage|True|2|4|7| -Euphoria|71-5|Valentine Stage|True|1|3|6| -P E R O P E R O Brother Dance|72-0|Legends of Muse Warriors|True|0|?|0| -PA PPA PANIC|72-1|Legends of Muse Warriors|False|4|8|10| -How To Make Music Game Song!|72-2|Legends of Muse Warriors|True|6|8|10|11 -Re Re|72-3|Legends of Muse Warriors|True|7|9|11|12 -Marmalade Twins|72-4|Legends of Muse Warriors|True|5|8|10| -DOMINATOR|72-5|Legends of Muse Warriors|True|7|9|11| -Teshikani TESHiKANi|72-6|Legends of Muse Warriors|True|5|7|9| -Urban Magic|73-0|Happy Otaku Pack Vol.19|True|3|5|7| -Maid's Prank|73-1|Happy Otaku Pack Vol.19|True|5|7|10| -Dance Dance Good Night Dance|73-2|Happy Otaku Pack Vol.19|True|2|4|7| -Ops Limone|73-3|Happy Otaku Pack Vol.19|True|5|8|11| -NOVA|73-4|Happy Otaku Pack Vol.19|True|6|8|10| -Heaven's Gradius|73-5|Happy Otaku Pack Vol.19|True|6|8|10| -Ray Tuning|74-0|CHUNITHM COURSE MUSE|True|6|8|10| -World Vanquisher|74-1|CHUNITHM COURSE MUSE|True|6|8|10|11 -Tsukuyomi Ni Naru Replaced|74-2|CHUNITHM COURSE MUSE|True|5|7|9| -The wheel to the right|74-3|CHUNITHM COURSE MUSE|True|5|7|9|11 -Climax|74-4|CHUNITHM COURSE MUSE|True|4|8|11|11 -Spider's Thread|74-5|CHUNITHM COURSE MUSE|True|5|8|10|12 -HIT ME UP|43-54|MD Plus Project|True|4|6|8| -Test Me feat. Uyeon|43-55|MD Plus Project|True|3|5|9| -Assault TAXI|43-56|MD Plus Project|True|4|7|10| -No|43-57|MD Plus Project|False|4|6|9| -Pop it|43-58|MD Plus Project|True|1|3|6| -HEARTBEAT! KyunKyun!|43-59|MD Plus Project|True|4|6|9| -SUPERHERO|75-0|Novice Rider Pack|False|2|4|7| -Highway_Summer|75-1|Novice Rider Pack|True|2|4|6| -Mx. Black Box|75-2|Novice Rider Pack|True|5|7|9| -Sweet Encounter|75-3|Novice Rider Pack|True|2|4|7| -Echo over you... Secret|0-55|Default Music|False|6|8|10| -Echo over you...|0-56|Default Music|False|1|4|0| -Tsukuyomi Ni Naru|74-6|CHUNITHM COURSE MUSE|True|5|8|10| -disco light|76-0|MUSE RADIO FM105|True|5|7|9| -room light feat.chancylemon|76-1|MUSE RADIO FM105|True|3|5|7| -Invisible|76-2|MUSE RADIO FM105|True|3|5|8| -Christmas Season-LLABB|76-3|MUSE RADIO FM105|True|1|4|7| -Hyouryu|77-0|Let's Rhythm Jam!|False|6|8|10| -The Whole Rest|77-1|Let's Rhythm Jam!|False|5|8|10|11 -Hydra|77-2|Let's Rhythm Jam!|False|4|7|11| -Pastel Lines|77-3|Let's Rhythm Jam!|False|3|6|9| -LINK x LIN#S|77-4|Let's Rhythm Jam!|False|3|6|9| -Arcade ViruZ|77-5|Let's Rhythm Jam!|False|6|8|11| -Eve Avenir|78-0|Endless Pirouette|True|6|8|10| -Silverstring|78-1|Endless Pirouette|True|5|7|10| -Melusia|78-2|Endless Pirouette|False|5|7|10|11 -Devil's Castle|78-3|Endless Pirouette|True|4|7|10| -Abatement|78-4|Endless Pirouette|True|6|8|10|11 -Azalea|78-5|Endless Pirouette|False|4|8|10| -Brightly World|78-6|Endless Pirouette|True|6|8|10| -We'll meet in every world ***|78-7|Endless Pirouette|True|7|9|11| -Collapsar|78-8|Endless Pirouette|True|7|9|10|11 -Parousia|78-9|Endless Pirouette|False|6|8|10| -Gunners in the Rain|79-0|Ensemble Arcanum|False|5|8|10| -Halzion|79-1|Ensemble Arcanum|False|2|5|8| -SHOWTIME!!|79-2|Ensemble Arcanum|False|6|8|10| -Achromic Riddle|79-3|Ensemble Arcanum|False|6|8|10|11 -karanosu|79-4|Ensemble Arcanum|False|3|6|8| diff --git a/worlds/musedash/Options.py b/worlds/musedash/Options.py index b8c969c39b0f..9f729c2d03e2 100644 --- a/worlds/musedash/Options.py +++ b/worlds/musedash/Options.py @@ -1,13 +1,14 @@ -from Options import Toggle, Range, Choice, DeathLink, ItemSet, OptionSet, PerGameCommonOptions, OptionGroup, Removed +from Options import Toggle, Range, Choice, DeathLink, OptionSet, PerGameCommonOptions, OptionGroup, Removed from dataclasses import dataclass from .MuseDashCollection import MuseDashCollections +from .MuseDashData import SONG_DATA class DLCMusicPacks(OptionSet): """ Choose which DLC Packs will be included in the pool of chooseable songs. - + Note: The [Just As Planned] DLC contains all [Muse Plus] songs. """ display_name = "DLC Packs" @@ -17,7 +18,7 @@ class DLCMusicPacks(OptionSet): class StreamerModeEnabled(Toggle): """ In Muse Dash, an option named 'Streamer Mode' removes songs which may trigger copyright issues when streaming. - + If this is enabled, only songs available under Streamer Mode will be available for randomization. """ display_name = "Streamer Mode Only Songs" @@ -69,7 +70,7 @@ class DifficultyMode(Choice): class DifficultyModeOverrideMin(Range): """ Ensures that 1 difficulty has at least 1 this value or higher per song. - + Note: Difficulty Mode must be set to Manual. """ display_name = "Manual Difficulty Min" @@ -82,7 +83,7 @@ class DifficultyModeOverrideMin(Range): class DifficultyModeOverrideMax(Range): """ Ensures that 1 difficulty has at least 1 this value or lower per song. - + Note: Difficulty Mode must be set to Manual. """ display_name = "Manual Difficulty Max" @@ -114,7 +115,7 @@ class GradeNeeded(Choice): class MusicSheetCountPercentage(Range): """ Controls how many music sheets are added to the pool based on the number of songs, including starting songs. - + Higher numbers leads to more consistent game lengths, but will cause individual music sheets to be less important. """ range_start = 10 @@ -137,7 +138,7 @@ class ChosenTraps(OptionSet): - Traps last the length of a song, or until you die. - VFX Traps consist of visual effects that play over the song. (i.e. Grayscale.) - SFX Traps consist of changing your sfx setting to one possibly more annoying sfx. - + Note: SFX traps are only available if [Just as Planned] DLC songs are enabled. """ display_name = "Chosen Traps" @@ -152,24 +153,26 @@ class TrapCountPercentage(Range): display_name = "Trap Percentage" -class IncludeSongs(ItemSet): +class SongSet(OptionSet): + valid_keys = SONG_DATA.keys() + + +class IncludeSongs(SongSet): """ These songs will be guaranteed to show up within the seed. - You must have the DLC enabled to play these songs. - Difficulty options will not affect these songs. - If there are too many included songs, this will act as a whitelist ignoring song difficulty. """ - verify_item_name = True display_name = "Include Songs" -class ExcludeSongs(ItemSet): +class ExcludeSongs(SongSet): """ These songs will be guaranteed to not show up within the seed. - + Note: Does not affect songs within the "Include Songs" list. """ - verify_item_name = True display_name = "Exclude Songs" @@ -211,7 +214,7 @@ class MuseDashOptions(PerGameCommonOptions): death_link: DeathLink include_songs: IncludeSongs exclude_songs: ExcludeSongs - + # Removed allow_just_as_planned_dlc_songs: Removed available_trap_types: Removed diff --git a/worlds/musedash/__init__.py b/worlds/musedash/__init__.py index be2eec2f87b8..d793308a7c0e 100644 --- a/worlds/musedash/__init__.py +++ b/worlds/musedash/__init__.py @@ -63,6 +63,11 @@ class MuseDashWorld(World): item_name_to_id = {name: code for name, code in md_collection.item_names_to_id.items()} location_name_to_id = {name: code for name, code in md_collection.location_names_to_id.items()} + item_name_groups = { + "Songs": {name for name in md_collection.song_items.keys()}, + "Filler Items": {name for name in md_collection.filler_items.keys()}, + "Traps": {name for name in md_collection.trap_items.keys()} + } # Working Data victory_song_name: str = "" @@ -179,10 +184,6 @@ def create_item(self, name: str) -> Item: if trap: return MuseDashFixedItem(name, ItemClassification.trap, trap, self.player) - album = self.md_collection.album_items.get(name) - if album: - return MuseDashSongItem(name, self.player, album) - song = self.md_collection.song_items[name] return MuseDashSongItem(name, self.player, song) diff --git a/worlds/musedash/test/TestDifficultyRanges.py b/worlds/musedash/test/TestDifficultyRanges.py index a9c36985afae..27798243a559 100644 --- a/worlds/musedash/test/TestDifficultyRanges.py +++ b/worlds/musedash/test/TestDifficultyRanges.py @@ -1,7 +1,17 @@ from . import MuseDashTestBase +from typing import List class DifficultyRanges(MuseDashTestBase): + DIFF_OVERRIDES: List[str] = [ + "MuseDash ka nanika hi", + "Rush-Hour", + "Find this Month's Featured Playlist", + "PeroPero in the Universe", + "umpopoff", + "P E R O P E R O Brother Dance", + ] + def test_all_difficulty_ranges(self) -> None: muse_dash_world = self.get_world() dlc_set = {x for x in muse_dash_world.md_collection.DLC} @@ -63,7 +73,7 @@ def test_range(input_range, lower, upper): def test_songs_have_difficulty(self) -> None: muse_dash_world = self.get_world() - for song_name in muse_dash_world.md_collection.DIFF_OVERRIDES: + for song_name in self.DIFF_OVERRIDES: song = muse_dash_world.md_collection.song_items[song_name] # Some songs are weird and have less than the usual 3 difficulties. From 172ad4e57d440809685462927454252609ea45fa Mon Sep 17 00:00:00 2001 From: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> Date: Sun, 12 Jan 2025 13:00:20 -0500 Subject: [PATCH 0016/1218] Adventure: Optimize imports (#4300) --- worlds/adventure/Options.py | 5 ++--- worlds/adventure/Regions.py | 2 +- worlds/adventure/Rom.py | 8 ++++---- worlds/adventure/__init__.py | 23 ++++++----------------- 4 files changed, 13 insertions(+), 25 deletions(-) diff --git a/worlds/adventure/Options.py b/worlds/adventure/Options.py index e6a8e4c20200..4b3f30df242d 100644 --- a/worlds/adventure/Options.py +++ b/worlds/adventure/Options.py @@ -1,9 +1,8 @@ from __future__ import annotations -from typing import Dict - from dataclasses import dataclass -from Options import Choice, Option, DefaultOnToggle, DeathLink, Range, Toggle, PerGameCommonOptions + +from Options import Choice, DefaultOnToggle, DeathLink, Range, Toggle, PerGameCommonOptions class FreeincarnateMax(Range): diff --git a/worlds/adventure/Regions.py b/worlds/adventure/Regions.py index 4e4dd1e7baa1..a0a04be2aa30 100644 --- a/worlds/adventure/Regions.py +++ b/worlds/adventure/Regions.py @@ -1,6 +1,6 @@ from BaseClasses import MultiWorld, Region, Entrance, LocationProgressType from Options import PerGameCommonOptions -from .Locations import location_table, LocationData, AdventureLocation, dragon_room_to_region +from .Locations import location_table, AdventureLocation, dragon_room_to_region def connect(world: MultiWorld, player: int, source: str, target: str, rule: callable = lambda state: True, diff --git a/worlds/adventure/Rom.py b/worlds/adventure/Rom.py index 643f7a6c766c..4d56cd19e529 100644 --- a/worlds/adventure/Rom.py +++ b/worlds/adventure/Rom.py @@ -2,14 +2,14 @@ import json import os import zipfile -from typing import Optional, Any +from typing import Any + +import bsdiff4 import Utils -from .Locations import AdventureLocation, LocationData from settings import get_settings from worlds.Files import APPatch, AutoPatchRegister - -import bsdiff4 +from .Locations import LocationData ADVENTUREHASH: str = "157bddb7192754a45372be196797f284" diff --git a/worlds/adventure/__init__.py b/worlds/adventure/__init__.py index 4fde1482cfe1..9dab2ffcef6a 100644 --- a/worlds/adventure/__init__.py +++ b/worlds/adventure/__init__.py @@ -1,35 +1,24 @@ -import base64 import copy -import itertools import math import os -import settings import typing -from enum import IntFlag -from typing import Any, ClassVar, Dict, List, Optional, Set, Tuple +from typing import ClassVar, Dict, Optional, Tuple -from BaseClasses import Entrance, Item, ItemClassification, MultiWorld, Region, Tutorial, \ - LocationProgressType +import settings +from BaseClasses import Item, ItemClassification, MultiWorld, Tutorial, LocationProgressType from Utils import __version__ -from Options import AssembleOptions from worlds.AutoWorld import WebWorld, World -from Fill import fill_restrictive -from worlds.generic.Rules import add_rule, set_rule -from .Options import DragonRandoType, DifficultySwitchA, DifficultySwitchB, \ - AdventureOptions -from .Rom import get_base_rom_bytes, get_base_rom_path, AdventureDeltaPatch, apply_basepatch, \ - AdventureAutoCollectLocation +from worlds.LauncherComponents import Component, components, SuffixIdentifier from .Items import item_table, ItemData, nothing_item_id, event_table, AdventureItem, standard_item_max from .Locations import location_table, base_location_id, LocationData, get_random_room_in_regions from .Offsets import static_item_data_location, items_ram_start, static_item_element_size, item_position_table, \ static_first_dragon_index, connector_port_offset, yorgle_speed_data_location, grundle_speed_data_location, \ rhindle_speed_data_location, item_ram_addresses, start_castle_values, start_castle_offset +from .Options import DragonRandoType, DifficultySwitchA, DifficultySwitchB, AdventureOptions from .Regions import create_regions +from .Rom import get_base_rom_bytes, get_base_rom_path, AdventureDeltaPatch, apply_basepatch, AdventureAutoCollectLocation from .Rules import set_rules - -from worlds.LauncherComponents import Component, components, SuffixIdentifier - # Adventure components.append(Component('Adventure Client', 'AdventureClient', file_identifier=SuffixIdentifier('.apadvn'))) From 1f966ee705e576f385c71b3a19d013a0995f0df1 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Sun, 12 Jan 2025 12:01:16 -0600 Subject: [PATCH 0017/1218] BizhawkClient: set metadata from patch file (#4346) --- worlds/_bizhawk/context.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/worlds/_bizhawk/context.py b/worlds/_bizhawk/context.py index 2a3965a54fcd..8d029f92ec71 100644 --- a/worlds/_bizhawk/context.py +++ b/worlds/_bizhawk/context.py @@ -231,12 +231,14 @@ async def _run_game(rom: str): ) -async def _patch_and_run_game(patch_file: str): +def _patch_and_run_game(patch_file: str): try: metadata, output_file = Patch.create_rom_file(patch_file) Utils.async_start(_run_game(output_file)) + return metadata except Exception as exc: logger.exception(exc) + return {} def launch(*launch_args) -> None: @@ -245,6 +247,11 @@ async def main(): parser.add_argument("patch_file", default="", type=str, nargs="?", help="Path to an Archipelago patch file") args = parser.parse_args(launch_args) + if args.patch_file != "": + metadata = _patch_and_run_game(args.patch_file) + if "server" in metadata: + args.connect = metadata["server"] + ctx = BizHawkClientContext(args.connect, args.password) ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop") @@ -252,9 +259,6 @@ async def main(): ctx.run_gui() ctx.run_cli() - if args.patch_file != "": - Utils.async_start(_patch_and_run_game(args.patch_file)) - watcher_task = asyncio.create_task(_game_watcher(ctx), name="GameWatcher") try: From 4c734b467fe087f2c6e2676a3d16c4191cddbb37 Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Mon, 13 Jan 2025 02:32:59 -0500 Subject: [PATCH 0018/1218] LTTP: Shop and Arrow fixes (#4067) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/alttp/Bosses.py | 4 +- worlds/alttp/ItemPool.py | 5 +-- worlds/alttp/Items.py | 6 +-- worlds/alttp/Shops.py | 3 +- worlds/alttp/StateHelpers.py | 47 +++++++++++--------- worlds/alttp/test/dungeons/TestMiseryMire.py | 2 +- 6 files changed, 38 insertions(+), 29 deletions(-) diff --git a/worlds/alttp/Bosses.py b/worlds/alttp/Bosses.py index 965a86db008a..02970edb9f55 100644 --- a/worlds/alttp/Bosses.py +++ b/worlds/alttp/Bosses.py @@ -119,7 +119,9 @@ def KholdstareDefeatRule(state, player: int) -> bool: def VitreousDefeatRule(state, player: int) -> bool: - return can_shoot_arrows(state, player) or has_melee_weapon(state, player) + return ((can_shoot_arrows(state, player) and can_use_bombs(state, player, 10)) + or can_shoot_arrows(state, player, 35) or state.has("Silver Bow", player) + or has_melee_weapon(state, player)) def TrinexxDefeatRule(state, player: int) -> bool: diff --git a/worlds/alttp/ItemPool.py b/worlds/alttp/ItemPool.py index c6c1770414db..77d02f9770cc 100644 --- a/worlds/alttp/ItemPool.py +++ b/worlds/alttp/ItemPool.py @@ -484,8 +484,7 @@ def cut_item(items, item_to_cut, minimum_items): if multiworld.randomize_cost_types[player]: # Heart and Arrow costs require all Heart Container/Pieces and Arrow Upgrades to be advancement items for logic for item in items: - if (item.name in ("Boss Heart Container", "Sanctuary Heart Container", "Piece of Heart") - or "Arrow Upgrade" in item.name): + if item.name in ("Boss Heart Container", "Sanctuary Heart Container", "Piece of Heart"): item.classification = ItemClassification.progression else: # Otherwise, logic has some branches where having 4 hearts is one possible requirement (of several alternatives) @@ -713,7 +712,7 @@ def place_item(loc, item): pool.remove("Rupees (20)") if retro_bow: - replace = {'Single Arrow', 'Arrows (10)', 'Arrow Upgrade (+5)', 'Arrow Upgrade (+10)', 'Arrow Upgrade (50)'} + replace = {'Single Arrow', 'Arrows (10)', 'Arrow Upgrade (+5)', 'Arrow Upgrade (+10)', 'Arrow Upgrade (70)'} pool = ['Rupees (5)' if item in replace else item for item in pool] if world.small_key_shuffle[player] == small_key_shuffle.option_universal: pool.extend(diff.universal_keys) diff --git a/worlds/alttp/Items.py b/worlds/alttp/Items.py index cb44f35d58f1..7e36d7a35ede 100644 --- a/worlds/alttp/Items.py +++ b/worlds/alttp/Items.py @@ -110,9 +110,9 @@ def as_init_dict(self) -> typing.Dict[str, typing.Any]: 'Crystal 7': ItemData(IC.progression, 'Crystal', (0x08, 0x34, 0x64, 0x40, 0x7C, 0x06), None, None, None, None, None, None, "a blue crystal"), 'Single Arrow': ItemData(IC.filler, None, 0x43, 'a lonely arrow\nsits here.', 'and the arrow', 'stick-collecting kid', 'sewing needle for sale', 'fungus for arrow', 'archer boy sews again', 'an arrow'), 'Arrows (10)': ItemData(IC.filler, None, 0x44, 'This will give\nyou ten shots\nwith your bow!', 'and the arrow pack','stick-collecting kid', 'sewing kit for sale', 'fungus for arrows', 'archer boy sews again','ten arrows'), - 'Arrow Upgrade (+10)': ItemData(IC.useful, None, 0x54, 'increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'), - 'Arrow Upgrade (+5)': ItemData(IC.useful, None, 0x53, 'increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'), - 'Arrow Upgrade (70)': ItemData(IC.useful, None, 0x4D, 'increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'), + 'Arrow Upgrade (+10)': ItemData(IC.progression_skip_balancing, None, 0x54, 'increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'), + 'Arrow Upgrade (+5)': ItemData(IC.progression_skip_balancing, None, 0x53, 'increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'), + 'Arrow Upgrade (70)': ItemData(IC.progression_skip_balancing, None, 0x4D, 'increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'), 'Single Bomb': ItemData(IC.filler, None, 0x27, 'I make things\ngo BOOM! But\njust once.', 'and the explosion', 'the bomb-holding kid', 'firecracker for sale', 'blend fungus into bomb', '\'splosion boy explodes again', 'a bomb'), 'Bombs (3)': ItemData(IC.filler, None, 0x28, 'I make things\ngo triple\nBOOM!!!', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'three bombs'), 'Bombs (10)': ItemData(IC.filler, None, 0x31, 'I make things\ngo BOOM! Ten\ntimes!', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'ten bombs'), diff --git a/worlds/alttp/Shops.py b/worlds/alttp/Shops.py index db2b5b680c1d..055eb2da934b 100644 --- a/worlds/alttp/Shops.py +++ b/worlds/alttp/Shops.py @@ -170,7 +170,8 @@ def push_shop_inventories(multiworld): # Retro Bow arrows will already have been pushed if (not multiworld.retro_bow[location.player]) or ((item_name, location.item.player) != ("Single Arrow", location.player)): - location.shop.push_inventory(location.shop_slot, item_name, location.shop_price, + location.shop.push_inventory(location.shop_slot, item_name, + round(location.shop_price * get_price_modifier(location.item)), 1, location.item.player if location.item.player != location.player else 0, location.shop_price_type) location.shop_price = location.shop.inventory[location.shop_slot]["price"] = min(location.shop_price, diff --git a/worlds/alttp/StateHelpers.py b/worlds/alttp/StateHelpers.py index 964a77fefbaf..8661632b836e 100644 --- a/worlds/alttp/StateHelpers.py +++ b/worlds/alttp/StateHelpers.py @@ -15,18 +15,18 @@ def can_bomb_clip(state: CollectionState, region: LTTPRegion, player: int) -> bo def can_buy_unlimited(state: CollectionState, item: str, player: int) -> bool: return any(shop.region.player == player and shop.has_unlimited(item) and shop.region.can_reach(state) for - shop in state.multiworld.shops) + shop in state.multiworld.shops) def can_buy(state: CollectionState, item: str, player: int) -> bool: return any(shop.region.player == player and shop.has(item) and shop.region.can_reach(state) for - shop in state.multiworld.shops) + shop in state.multiworld.shops) -def can_shoot_arrows(state: CollectionState, player: int) -> bool: +def can_shoot_arrows(state: CollectionState, player: int, count: int = 0) -> bool: if state.multiworld.retro_bow[player]: return (state.has('Bow', player) or state.has('Silver Bow', player)) and can_buy(state, 'Single Arrow', player) - return state.has('Bow', player) or state.has('Silver Bow', player) + return (state.has('Bow', player) or state.has('Silver Bow', player)) and can_hold_arrows(state, player, count) def has_triforce_pieces(state: CollectionState, player: int) -> bool: @@ -61,13 +61,13 @@ def heart_count(state: CollectionState, player: int) -> int: # Warning: This only considers items that are marked as advancement items diff = state.multiworld.worlds[player].difficulty_requirements return min(state.count('Boss Heart Container', player), diff.boss_heart_container_limit) \ - + state.count('Sanctuary Heart Container', player) \ + + state.count('Sanctuary Heart Container', player) \ + min(state.count('Piece of Heart', player), diff.heart_piece_limit) // 4 \ - + 3 # starting hearts + + 3 # starting hearts def can_extend_magic(state: CollectionState, player: int, smallmagic: int = 16, - fullrefill: bool = False): # This reflects the total magic Link has, not the total extra he has. + fullrefill: bool = False): # This reflects the total magic Link has, not the total extra he has. basemagic = 8 if state.has('Magic Upgrade (1/4)', player): basemagic = 32 @@ -84,11 +84,18 @@ def can_extend_magic(state: CollectionState, player: int, smallmagic: int = 16, def can_hold_arrows(state: CollectionState, player: int, quantity: int): - arrows = 30 + ((state.count("Arrow Upgrade (+5)", player) * 5) + (state.count("Arrow Upgrade (+10)", player) * 10) - + (state.count("Bomb Upgrade (50)", player) * 50)) - # Arrow Upgrade (+5) beyond the 6th gives +10 - arrows += max(0, ((state.count("Arrow Upgrade (+5)", player) - 6) * 10)) - return min(70, arrows) >= quantity + if state.multiworld.worlds[player].options.shuffle_capacity_upgrades: + if quantity == 0: + return True + if state.has("Arrow Upgrade (70)", player): + arrows = 70 + else: + arrows = (30 + (state.count("Arrow Upgrade (+5)", player) * 5) + + (state.count("Arrow Upgrade (+10)", player) * 10)) + # Arrow Upgrade (+5) beyond the 6th gives +10 + arrows += max(0, ((state.count("Arrow Upgrade (+5)", player) - 6) * 10)) + return min(70, arrows) >= quantity + return quantity <= 30 or state.has("Capacity Upgrade Shop", player) def can_use_bombs(state: CollectionState, player: int, quantity: int = 1) -> bool: @@ -146,19 +153,19 @@ def can_get_good_bee(state: CollectionState, player: int) -> bool: def can_retrieve_tablet(state: CollectionState, player: int) -> bool: return state.has('Book of Mudora', player) and (has_beam_sword(state, player) or (state.multiworld.swordless[player] and - state.has("Hammer", player))) + state.has("Hammer", player))) def has_sword(state: CollectionState, player: int) -> bool: return state.has('Fighter Sword', player) \ - or state.has('Master Sword', player) \ - or state.has('Tempered Sword', player) \ - or state.has('Golden Sword', player) + or state.has('Master Sword', player) \ + or state.has('Tempered Sword', player) \ + or state.has('Golden Sword', player) def has_beam_sword(state: CollectionState, player: int) -> bool: return state.has('Master Sword', player) or state.has('Tempered Sword', player) or state.has('Golden Sword', - player) + player) def has_melee_weapon(state: CollectionState, player: int) -> bool: @@ -171,9 +178,9 @@ def has_fire_source(state: CollectionState, player: int) -> bool: def can_melt_things(state: CollectionState, player: int) -> bool: return state.has('Fire Rod', player) or \ - (state.has('Bombos', player) and - (state.multiworld.swordless[player] or - has_sword(state, player))) + (state.has('Bombos', player) and + (state.multiworld.swordless[player] or + has_sword(state, player))) def has_misery_mire_medallion(state: CollectionState, player: int) -> bool: diff --git a/worlds/alttp/test/dungeons/TestMiseryMire.py b/worlds/alttp/test/dungeons/TestMiseryMire.py index ca74e9365ee6..90b7055b764a 100644 --- a/worlds/alttp/test/dungeons/TestMiseryMire.py +++ b/worlds/alttp/test/dungeons/TestMiseryMire.py @@ -77,5 +77,5 @@ def testMiseryMire(self): ["Misery Mire - Boss", False, [], ['Bomb Upgrade (+5)', 'Bomb Upgrade (+10)', 'Bomb Upgrade (50)']], ["Misery Mire - Boss", True, ['Bomb Upgrade (+5)', 'Big Key (Misery Mire)', 'Lamp', 'Cane of Somaria', 'Progressive Sword', 'Pegasus Boots']], ["Misery Mire - Boss", True, ['Bomb Upgrade (+5)', 'Big Key (Misery Mire)', 'Lamp', 'Cane of Somaria', 'Hammer', 'Pegasus Boots']], - ["Misery Mire - Boss", True, ['Bomb Upgrade (+5)', 'Big Key (Misery Mire)', 'Lamp', 'Cane of Somaria', 'Progressive Bow', 'Pegasus Boots']], + ["Misery Mire - Boss", True, ['Bomb Upgrade (+5)', 'Big Key (Misery Mire)', 'Lamp', 'Cane of Somaria', 'Progressive Bow', 'Arrow Upgrade (+5)', 'Pegasus Boots']], ]) \ No newline at end of file From 0f1c119c76b78e894ca7c21dc14ed14a3ca0e5a5 Mon Sep 17 00:00:00 2001 From: Sam Merritt Date: Mon, 13 Jan 2025 00:52:21 -0800 Subject: [PATCH 0019/1218] Factorio: improve error message for config validation (#4421) --- worlds/factorio/Options.py | 14 +++++++-- worlds/factorio/test_file_validation.py | 39 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 worlds/factorio/test_file_validation.py diff --git a/worlds/factorio/Options.py b/worlds/factorio/Options.py index 72f438778b60..0fa75e1b8bfa 100644 --- a/worlds/factorio/Options.py +++ b/worlds/factorio/Options.py @@ -3,13 +3,23 @@ from dataclasses import dataclass import typing -from schema import Schema, Optional, And, Or +from schema import Schema, Optional, And, Or, SchemaError from Options import Choice, OptionDict, OptionSet, DefaultOnToggle, Range, DeathLink, Toggle, \ StartInventoryPool, PerGameCommonOptions, OptionGroup # schema helpers -FloatRange = lambda low, high: And(Or(int, float), lambda f: low <= f <= high) +class FloatRange: + def __init__(self, low, high): + self._low = low + self._high = high + + def validate(self, value): + if not isinstance(value, (float, int)): + raise SchemaError(f"should be instance of float or int, but was {value!r}") + if not self._low <= value <= self._high: + raise SchemaError(f"{value} is not between {self._low} and {self._high}") + LuaBool = Or(bool, And(int, lambda n: n in (0, 1))) diff --git a/worlds/factorio/test_file_validation.py b/worlds/factorio/test_file_validation.py new file mode 100644 index 000000000000..df56ec608c17 --- /dev/null +++ b/worlds/factorio/test_file_validation.py @@ -0,0 +1,39 @@ +"""Tests for error messages from YAML validation.""" + +import os +import unittest + +import WebHostLib.check + +FACTORIO_YAML=""" +game: Factorio +Factorio: + world_gen: + autoplace_controls: + coal: + richness: 1 + frequency: {} + size: 1 +""" + +def yamlWithFrequency(f): + return FACTORIO_YAML.format(f) + + +class TestFileValidation(unittest.TestCase): + def test_out_of_range(self): + results, _ = WebHostLib.check.roll_options({"bob.yaml": yamlWithFrequency(1000)}) + self.assertIn("between 0 and 6", results["bob.yaml"]) + + def test_bad_non_numeric(self): + results, _ = WebHostLib.check.roll_options({"bob.yaml": yamlWithFrequency("not numeric")}) + self.assertIn("float", results["bob.yaml"]) + self.assertIn("int", results["bob.yaml"]) + + def test_good_float(self): + results, _ = WebHostLib.check.roll_options({"bob.yaml": yamlWithFrequency(1.0)}) + self.assertIs(results["bob.yaml"], True) + + def test_good_int(self): + results, _ = WebHostLib.check.roll_options({"bob.yaml": yamlWithFrequency(1)}) + self.assertIs(results["bob.yaml"], True) From f9cc19e150d7e8210372615402d15c10be31864e Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Mon, 13 Jan 2025 09:52:10 -0600 Subject: [PATCH 0020/1218] Fill: Crash if there are remaining unfilled locations (#2830) --- Fill.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Fill.py b/Fill.py index a040794fd1c6..0da2d5def978 100644 --- a/Fill.py +++ b/Fill.py @@ -571,6 +571,26 @@ def mark_for_locking(location: Location): print_data = {"items": items_counter, "locations": locations_counter} logging.info(f"Per-Player counts: {print_data})") + more_locations = locations_counter - items_counter + more_items = items_counter - locations_counter + for player in multiworld.player_ids: + if more_locations[player]: + logging.error( + f"Player {multiworld.get_player_name(player)} had {more_locations[player]} more locations than items.") + elif more_items[player]: + logging.warning( + f"Player {multiworld.get_player_name(player)} had {more_items[player]} more items than locations.") + if unfilled: + raise FillError( + f"Unable to fill all locations.\n" + + f"Unfilled locations({len(unfilled)}): {unfilled}" + ) + else: + logging.warning( + f"Unable to place all items.\n" + + f"Unplaced items({len(unplaced)}): {unplaced}" + ) + def flood_items(multiworld: MultiWorld) -> None: # get items to distribute From 93e8613da7a39fb3bd87cf132993f6c304e3d4cc Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 13 Jan 2025 11:08:46 -0500 Subject: [PATCH 0021/1218] HK: Abstract and default grub counts (#4336) --- worlds/hk/__init__.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/worlds/hk/__init__.py b/worlds/hk/__init__.py index bcd904521db1..7e9b7442a746 100644 --- a/worlds/hk/__init__.py +++ b/worlds/hk/__init__.py @@ -181,6 +181,7 @@ class HKWorld(World): charm_costs: typing.List[int] cached_filler_items = {} grub_count: int + grub_player_count: typing.Dict[int, int] def __init__(self, multiworld, player): super(HKWorld, self).__init__(multiworld, player) @@ -190,7 +191,6 @@ def __init__(self, multiworld, player): self.ranges = {} self.created_shop_items = 0 self.vanilla_shop_costs = deepcopy(vanilla_shop_costs) - self.grub_count = 0 def generate_early(self): options = self.options @@ -204,7 +204,14 @@ def generate_early(self): mini.value = min(mini.value, maxi.value) self.ranges[term] = mini.value, maxi.value self.multiworld.push_precollected(HKItem(starts[options.StartLocation.current_key], - True, None, "Event", self.player)) + True, None, "Event", self.player)) + + # defaulting so completion condition isn't incorrect before pre_fill + self.grub_count = ( + 46 if options.GrubHuntGoal == GrubHuntGoal.special_range_names["all"] + else options.GrubHuntGoal + ) + self.grub_player_count = {self.player: self.grub_count} def white_palace_exclusions(self): exclusions = set() @@ -469,25 +476,20 @@ def set_rules(self): elif goal == Goal.option_godhome_flower: multiworld.completion_condition[player] = lambda state: state.count("Godhome_Flower_Quest", player) elif goal == Goal.option_grub_hunt: - pass # will set in stage_pre_fill() + multiworld.completion_condition[player] = lambda state: self.can_grub_goal(state) else: # Any goal multiworld.completion_condition[player] = lambda state: _hk_siblings_ending(state, player) and \ - _hk_can_beat_radiance(state, player) and state.count("Godhome_Flower_Quest", player) + _hk_can_beat_radiance(state, player) and state.count("Godhome_Flower_Quest", player) and \ + self.can_grub_goal(state) set_rules(self) + def can_grub_goal(self, state: CollectionState) -> bool: + return all(state.has("Grub", owner, count) for owner, count in self.grub_player_count.items()) + @classmethod def stage_pre_fill(cls, multiworld: "MultiWorld"): - def set_goal(player, grub_rule: typing.Callable[[CollectionState], bool]): - world = multiworld.worlds[player] - - if world.options.Goal == "grub_hunt": - multiworld.completion_condition[player] = grub_rule - else: - old_rule = multiworld.completion_condition[player] - multiworld.completion_condition[player] = lambda state: old_rule(state) and grub_rule(state) - worlds = [world for world in multiworld.get_game_worlds(cls.game) if world.options.Goal in ["any", "grub_hunt"]] if worlds: grubs = [item for item in multiworld.get_items() if item.name == "Grub"] @@ -525,13 +527,13 @@ def set_goal(player, grub_rule: typing.Callable[[CollectionState], bool]): for player, grub_player_count in per_player_grubs_per_player.items(): if player in all_grub_players: - set_goal(player, lambda state, g=grub_player_count: all(state.has("Grub", owner, count) for owner, count in g.items())) + multiworld.worlds[player].grub_player_count = grub_player_count for world in worlds: if world.player not in all_grub_players: world.grub_count = world.options.GrubHuntGoal.value player = world.player - set_goal(player, lambda state, p=player, c=world.grub_count: state.has("Grub", p, c)) + world.grub_player_count = {player: world.grub_count} def fill_slot_data(self): slot_data = {} From 4cb8fa3cdd435ee646b56c06747d581d57126de8 Mon Sep 17 00:00:00 2001 From: Louis M Date: Mon, 13 Jan 2025 14:09:39 -0500 Subject: [PATCH 0022/1218] Aquaria: Fixing itemlink not working (#4473) --- worlds/aquaria/__init__.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/worlds/aquaria/__init__.py b/worlds/aquaria/__init__.py index 1f7b956bb34b..54158b280bf4 100644 --- a/worlds/aquaria/__init__.py +++ b/worlds/aquaria/__init__.py @@ -93,7 +93,7 @@ class AquariaWorld(World): options: AquariaOptions "Every options of the world" - regions: AquariaRegions + regions: AquariaRegions | None "Used to manage Regions" exclude: List[str] @@ -101,10 +101,17 @@ class AquariaWorld(World): def __init__(self, multiworld: MultiWorld, player: int): """Initialisation of the Aquaria World""" super(AquariaWorld, self).__init__(multiworld, player) - self.regions = AquariaRegions(multiworld, player) + self.regions = None self.ingredients_substitution = [] self.exclude = [] + def generate_early(self) -> None: + """ + Run before any general steps of the MultiWorld other than options. Useful for getting and adjusting option + results and determining layouts for entrance rando etc. start inventory gets pushed after this step. + """ + self.regions = AquariaRegions(self.multiworld, self.player) + def create_regions(self) -> None: """ Create every Region in `regions` From 20119e3162f17d8af060377986921cee54836e59 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:35:01 -0500 Subject: [PATCH 0023/1218] Faxanadu: Fix generations with itemlinks (#4395) --- worlds/faxanadu/__init__.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/worlds/faxanadu/__init__.py b/worlds/faxanadu/__init__.py index c4ae1ccaa198..ca17c0675982 100644 --- a/worlds/faxanadu/__init__.py +++ b/worlds/faxanadu/__init__.py @@ -44,8 +44,13 @@ class FaxanaduWorld(World): location_name_to_id = {loc.name: loc.id for loc in Locations.locations if loc.id is not None} def __init__(self, world: MultiWorld, player: int): - self.filler_ratios: Dict[str, int] = {} - + self.filler_ratios: Dict[str, int] = { + item.name: item.count + for item in Items.items + if item.classification in [ItemClassification.filler, ItemClassification.trap] + } + # Remove poison by default to respect itemlinking + self.filler_ratios["Poison"] = 0 super().__init__(world, player) def create_regions(self): @@ -160,19 +165,13 @@ def create_items(self) -> None: for i in range(item.progression_count): itempool.append(FaxanaduItem(item.name, ItemClassification.progression, item.id, self.player)) - # Set up filler ratios - self.filler_ratios = { - item.name: item.count - for item in Items.items - if item.classification in [ItemClassification.filler, ItemClassification.trap] - } - + # Adjust filler ratios # If red potions are locked in shops, remove the count from the ratio. self.filler_ratios["Red Potion"] -= red_potion_in_shop_count - # Remove poisons if not desired - if not self.options.include_poisons: - self.filler_ratios["Poison"] = 0 + # Add poisons if desired + if self.options.include_poisons: + self.filler_ratios["Poison"] = self.item_name_to_item["Poison"].count # Randomly add fillers to the pool with ratios based on og game occurrence counts. filler_count = len(Locations.locations) - len(itempool) - prefilled_count From 6220963195c5b12edea12d46057a657cc5f73f64 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:35:44 -0500 Subject: [PATCH 0024/1218] Tests: No Creating Items/Locations/Regions in __init__ (#4474) --- test/general/test_implemented.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/general/test_implemented.py b/test/general/test_implemented.py index 756cfa8bb67d..7abf9959936a 100644 --- a/test/general/test_implemented.py +++ b/test/general/test_implemented.py @@ -117,3 +117,12 @@ def test_explicit_indirect_conditions_spheres(self): f"\nUnexpectedly reachable locations in sphere {sphere_num}:" f"\n{reachable_only_with_explicit}") self.fail("Unreachable") + + def test_no_items_or_locations_or_regions_submitted_in_init(self): + """Test that worlds don't submit items/locations/regions to the multiworld in __init__""" + for game_name, world_type in AutoWorldRegister.world_types.items(): + with self.subTest("Game", game=game_name): + multiworld = setup_solo_multiworld(world_type, ()) + self.assertEqual(len(multiworld.itempool), 0) + self.assertEqual(len(multiworld.get_locations()), 0) + self.assertEqual(len(multiworld.get_regions()), 0) From ffd0c8b3413727ab46692339c4e3e69fda2780dc Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 13 Jan 2025 19:34:56 -0500 Subject: [PATCH 0025/1218] Blasphemous: Move Locality Changes Earlier (#4422) --- worlds/blasphemous/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/worlds/blasphemous/__init__.py b/worlds/blasphemous/__init__.py index a967fbac9289..4b151f41f860 100644 --- a/worlds/blasphemous/__init__.py +++ b/worlds/blasphemous/__init__.py @@ -103,6 +103,9 @@ def generate_early(self): if not self.options.wall_climb_shuffle: self.multiworld.push_precollected(self.create_item("Wall Climb Ability")) + if self.options.thorn_shuffle == "local_only": + self.options.local_items.value.add("Thorn Upgrade") + if not self.options.boots_of_pleading: self.disabled_locations.append("RE401") @@ -200,9 +203,6 @@ def create_items(self): if not self.options.skill_randomizer: self.place_items_from_dict(skill_dict) - - if self.options.thorn_shuffle == "local_only": - self.options.local_items.value.add("Thorn Upgrade") def place_items_from_set(self, location_set: Set[str], name: str): From 0f1dc6e19c1682b2bd3cdf6d900620a8c3dbde71 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Mon, 13 Jan 2025 19:35:29 -0500 Subject: [PATCH 0026/1218] Codeowners: @threeandthreee as LADX maintainer #4216 --- docs/CODEOWNERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 1d70531e9974..c4cb83e42f38 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -99,6 +99,9 @@ # Lingo /worlds/lingo/ @hatkirby +# Links Awakening DX +/worlds/ladx/ @threeandthreee + # Lufia II Ancient Cave /worlds/lufia2ac/ @el-u /worlds/lufia2ac/docs/ @wordfcuk @el-u @@ -236,9 +239,6 @@ # Final Fantasy (1) # /worlds/ff1/ -# Links Awakening DX -# /worlds/ladx/ - # Ocarina of Time # /worlds/oot/ From 0f3818e7115a37f4e18d17a1c71e8eb3e0972cf8 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Tue, 14 Jan 2025 04:45:59 -0500 Subject: [PATCH 0027/1218] Utils: Visualize Regions showing the reachable regions in color (#4436) * Utils with coloring * Update example use * Update Utils.py Co-authored-by: Doug Hoskisson --------- Co-authored-by: Doug Hoskisson --- Utils.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Utils.py b/Utils.py index 43b3ef9c8ff9..8f5ba1a0f84f 100644 --- a/Utils.py +++ b/Utils.py @@ -940,7 +940,7 @@ def freeze_support() -> None: def visualize_regions(root_region: Region, file_name: str, *, show_entrance_names: bool = False, show_locations: bool = True, show_other_regions: bool = True, - linetype_ortho: bool = True) -> None: + linetype_ortho: bool = True, regions_to_highlight: set[Region] | None = None) -> None: """Visualize the layout of a world as a PlantUML diagram. :param root_region: The region from which to start the diagram from. (Usually the "Menu" region of your world.) @@ -956,16 +956,22 @@ def visualize_regions(root_region: Region, file_name: str, *, Items without ID will be shown in italics. :param show_other_regions: (default True) If enabled, regions that can't be reached by traversing exits are shown. :param linetype_ortho: (default True) If enabled, orthogonal straight line parts will be used; otherwise polylines. + :param regions_to_highlight: Regions that will be highlighted in green if they are reachable. Example usage in World code: from Utils import visualize_regions - visualize_regions(self.multiworld.get_region("Menu", self.player), "my_world.puml") + state = self.multiworld.get_all_state(False) + state.update_reachable_regions(self.player) + visualize_regions(self.get_region("Menu"), "my_world.puml", show_entrance_names=True, + regions_to_highlight=state.reachable_regions[self.player]) Example usage in Main code: from Utils import visualize_regions for player in multiworld.player_ids: visualize_regions(multiworld.get_region("Menu", player), f"{multiworld.get_out_file_name_base(player)}.puml") """ + if regions_to_highlight is None: + regions_to_highlight = set() assert root_region.multiworld, "The multiworld attribute of root_region has to be filled" from BaseClasses import Entrance, Item, Location, LocationProgressType, MultiWorld, Region from collections import deque @@ -1018,7 +1024,7 @@ def visualize_locations(region: Region) -> None: uml.append(f"\"{fmt(region)}\" : {{field}} {lock}{fmt(location)}") def visualize_region(region: Region) -> None: - uml.append(f"class \"{fmt(region)}\"") + uml.append(f"class \"{fmt(region)}\" {'#00FF00' if region in regions_to_highlight else ''}") if show_locations: visualize_locations(region) visualize_exits(region) From 04928bd83d6835c5e169d3f35fdc0a7bb6f2a2ae Mon Sep 17 00:00:00 2001 From: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> Date: Tue, 14 Jan 2025 04:49:30 -0500 Subject: [PATCH 0028/1218] DKC3: Remove unused variables and imports #4302 --- worlds/dkc3/Client.py | 3 +-- worlds/dkc3/Items.py | 2 +- worlds/dkc3/Options.py | 3 +-- worlds/dkc3/Regions.py | 5 ++--- worlds/dkc3/Rom.py | 3 +-- worlds/dkc3/Rules.py | 4 ++-- worlds/dkc3/__init__.py | 8 +++----- 7 files changed, 11 insertions(+), 17 deletions(-) diff --git a/worlds/dkc3/Client.py b/worlds/dkc3/Client.py index ee2bd1dbdfb8..40216e81e37a 100644 --- a/worlds/dkc3/Client.py +++ b/worlds/dkc3/Client.py @@ -1,5 +1,4 @@ import logging -import asyncio from NetUtils import ClientStatus, color from worlds.AutoSNIClient import SNIClient @@ -32,7 +31,7 @@ async def deathlink_kill_player(self, ctx): async def validate_rom(self, ctx): - from SNIClient import snes_buffered_write, snes_flush_writes, snes_read + from SNIClient import snes_read rom_name = await snes_read(ctx, DKC3_ROMHASH_START, ROMHASH_SIZE) if rom_name is None or rom_name == bytes([0] * ROMHASH_SIZE) or rom_name[:2] != b"D3": diff --git a/worlds/dkc3/Items.py b/worlds/dkc3/Items.py index 358873cd2010..e6cac91ea90f 100644 --- a/worlds/dkc3/Items.py +++ b/worlds/dkc3/Items.py @@ -1,6 +1,6 @@ import typing -from BaseClasses import Item, ItemClassification +from BaseClasses import Item from .Names import ItemName diff --git a/worlds/dkc3/Options.py b/worlds/dkc3/Options.py index b114a503b982..3f220bce446d 100644 --- a/worlds/dkc3/Options.py +++ b/worlds/dkc3/Options.py @@ -1,7 +1,6 @@ from dataclasses import dataclass -import typing -from Options import Choice, Range, Toggle, DeathLink, DefaultOnToggle, OptionGroup, PerGameCommonOptions +from Options import Choice, Range, Toggle, DefaultOnToggle, OptionGroup, PerGameCommonOptions class Goal(Choice): diff --git a/worlds/dkc3/Regions.py b/worlds/dkc3/Regions.py index ae505b78d84b..6e968dbe1e30 100644 --- a/worlds/dkc3/Regions.py +++ b/worlds/dkc3/Regions.py @@ -1,10 +1,9 @@ import typing -from BaseClasses import MultiWorld, Region, Entrance -from .Items import DKC3Item +from BaseClasses import Region, Entrance +from worlds.AutoWorld import World from .Locations import DKC3Location from .Names import LocationName, ItemName -from worlds.AutoWorld import World def create_regions(world: World, active_locations): diff --git a/worlds/dkc3/Rom.py b/worlds/dkc3/Rom.py index 0dc722a73868..fb8bc2b122a4 100644 --- a/worlds/dkc3/Rom.py +++ b/worlds/dkc3/Rom.py @@ -2,7 +2,6 @@ from Utils import read_snes_rom from worlds.AutoWorld import World from worlds.Files import APDeltaPatch -from .Locations import lookup_id_to_name, all_locations from .Levels import level_list, level_dict USHASH = '120abf304f0c40fe059f6a192ed4f947' @@ -436,7 +435,7 @@ class LocalRom: - def __init__(self, file, patch=True, vanillaRom=None, name=None, hash=None): + def __init__(self, file, name=None, hash=None): self.name = name self.hash = hash self.orig_buffer = None diff --git a/worlds/dkc3/Rules.py b/worlds/dkc3/Rules.py index cc45e4ef3ad5..3d68aefb716a 100644 --- a/worlds/dkc3/Rules.py +++ b/worlds/dkc3/Rules.py @@ -1,8 +1,8 @@ import math +from worlds.AutoWorld import World +from worlds.generic.Rules import add_rule from .Names import LocationName, ItemName -from worlds.AutoWorld import LogicMixin, World -from worlds.generic.Rules import add_rule, set_rule def set_rules(world: World): diff --git a/worlds/dkc3/__init__.py b/worlds/dkc3/__init__.py index de6fb4a44a03..1dabeb0539d2 100644 --- a/worlds/dkc3/__init__.py +++ b/worlds/dkc3/__init__.py @@ -1,15 +1,13 @@ import dataclasses -import os -import typing import math +import os import threading +import typing +import settings from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification from Options import PerGameCommonOptions -import Patch -import settings from worlds.AutoWorld import WebWorld, World - from .Client import DKC3SNIClient from .Items import DKC3Item, ItemData, item_table, inventory_table, junk_table from .Levels import level_list From dae9d4c575d17d5ced32153d5209b0272e4085b8 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 14 Jan 2025 12:34:40 -0500 Subject: [PATCH 0029/1218] LTTP: Fix Itemlinks (#4479) --- worlds/alttp/Items.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/alttp/Items.py b/worlds/alttp/Items.py index 7e36d7a35ede..5f081e65fc8b 100644 --- a/worlds/alttp/Items.py +++ b/worlds/alttp/Items.py @@ -7,7 +7,7 @@ def GetBeemizerItem(world, player: int, item): item_name = item if isinstance(item, str) else item.name - if item_name not in trap_replaceable: + if item_name not in trap_replaceable or player in world.groups: return item # first roll - replaceable item should be replaced, within beemizer_total_chance From 79e6beeec3fe11e5f7df716d9ddec3847f4755f6 Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Tue, 14 Jan 2025 12:47:12 -0500 Subject: [PATCH 0030/1218] Stardew Valley: Update Mod Content (#4416) --- worlds/stardew_valley/data/craftable_data.py | 10 +++++++- worlds/stardew_valley/data/locations.csv | 6 ++++- worlds/stardew_valley/locations.py | 9 +++++++- worlds/stardew_valley/options/options.py | 23 +++++++++++-------- .../stardew_valley/strings/craftable_names.py | 4 ++++ .../test/TestNumberLocations.py | 9 ++++---- worlds/stardew_valley/test/__init__.py | 7 ++++++ 7 files changed, 52 insertions(+), 16 deletions(-) diff --git a/worlds/stardew_valley/data/craftable_data.py b/worlds/stardew_valley/data/craftable_data.py index 713db4732075..1bb4b2bea73b 100644 --- a/worlds/stardew_valley/data/craftable_data.py +++ b/worlds/stardew_valley/data/craftable_data.py @@ -11,7 +11,7 @@ from ..strings.crop_names import Fruit, Vegetable from ..strings.currency_names import Currency from ..strings.fertilizer_names import Fertilizer, RetainingSoil, SpeedGro -from ..strings.fish_names import Fish, WaterItem, ModTrash +from ..strings.fish_names import Fish, WaterItem, ModTrash, Trash from ..strings.flower_names import Flower from ..strings.food_names import Meal from ..strings.forageable_names import Forageable, SVEForage, DistantLandsForageable, Mushroom @@ -378,4 +378,12 @@ def create_recipe(name: str, ingredients: Dict[str, int], source: RecipeSource, advanced_recycling_machine = skill_recipe(ModMachine.advanced_recycling_machine, ModSkill.binning, 9, {MetalBar.iridium: 5, ArtisanGood.battery_pack: 2, MetalBar.quartz: 10}, ModNames.binning_skill) +coppper_slot_machine = skill_recipe(ModMachine.copper_slot_machine, ModSkill.luck, 2, {MetalBar.copper: 15, Material.stone: 1, Material.wood: 1, + Material.fiber: 1, Material.sap: 1, Loot.slime: 1, + Forageable.salmonberry: 1, Material.clay: 1, Trash.joja_cola: 1}, ModNames.luck_skill) + +gold_slot_machine = skill_recipe(ModMachine.gold_slot_machine, ModSkill.luck, 4, {MetalBar.gold: 15, ModMachine.copper_slot_machine: 1}, ModNames.luck_skill) +iridium_slot_machine = skill_recipe(ModMachine.iridium_slot_machine, ModSkill.luck, 4, {MetalBar.iridium: 15, ModMachine.gold_slot_machine: 1}, ModNames.luck_skill) +radioactive_slot_machine = skill_recipe(ModMachine.radioactive_slot_machine, ModSkill.luck, 4, {MetalBar.radioactive: 15, ModMachine.iridium_slot_machine: 1}, ModNames.luck_skill) + all_crafting_recipes_by_name = {recipe.item: recipe for recipe in all_crafting_recipes} diff --git a/worlds/stardew_valley/data/locations.csv b/worlds/stardew_valley/data/locations.csv index 680ddfcbacbf..43883b86f8ac 100644 --- a/worlds/stardew_valley/data/locations.csv +++ b/worlds/stardew_valley/data/locations.csv @@ -2935,6 +2935,10 @@ id,region,name,tags,mod_name 7433,Farm,Craft Composter,CRAFTSANITY,Binning Skill 7434,Farm,Craft Recycling Bin,CRAFTSANITY,Binning Skill 7435,Farm,Craft Advanced Recycling Machine,CRAFTSANITY,Binning Skill +7440,Farm,Craft Copper Slot Machine,"CRAFTSANITY",Luck Skill +7441,Farm,Craft Gold Slot Machine,"CRAFTSANITY",Luck Skill +7442,Farm,Craft Iridium Slot Machine,"CRAFTSANITY",Luck Skill +7443,Farm,Craft Radioactive Slot Machine,"CRAFTSANITY",Luck Skill 7451,Adventurer's Guild,Magic Elixir Recipe,"CHEFSANITY,CHEFSANITY_PURCHASE",Magic 7452,Adventurer's Guild,Travel Core Recipe,CRAFTSANITY,Magic 7453,Alesia Shop,Haste Elixir Recipe,CRAFTSANITY,Stardew Valley Expanded @@ -3241,7 +3245,7 @@ id,region,name,tags,mod_name 8199,Shipping,Shipsanity: Hardwood Display,SHIPSANITY,Archaeology 8200,Shipping,Shipsanity: Wooden Display,SHIPSANITY,Archaeology 8201,Shipping,Shipsanity: Dwarf Gadget: Infinite Volcano Simulation,"SHIPSANITY,GINGER_ISLAND",Archaeology -8202,Shipping,Shipsanity: Water Shifter,SHIPSANITY,Archaeology +8202,Shipping,Shipsanity: Water Shifter,"SHIPSANITY,DEPRECATED",Archaeology 8203,Shipping,Shipsanity: Brown Amanita,"SHIPSANITY,SHIPSANITY_FULL_SHIPMENT",Distant Lands - Witch Swamp Overhaul 8204,Shipping,Shipsanity: Swamp Herb,"SHIPSANITY,SHIPSANITY_FULL_SHIPMENT",Distant Lands - Witch Swamp Overhaul 8205,Shipping,Shipsanity: Void Mint Seeds,SHIPSANITY,Distant Lands - Witch Swamp Overhaul diff --git a/worlds/stardew_valley/locations.py b/worlds/stardew_valley/locations.py index b3a8db6f0341..02c8a5441c52 100644 --- a/worlds/stardew_valley/locations.py +++ b/worlds/stardew_valley/locations.py @@ -110,6 +110,8 @@ class LocationTags(enum.Enum): MAGIC_LEVEL = enum.auto() ARCHAEOLOGY_LEVEL = enum.auto() + DEPRECATED = enum.auto() + @dataclass(frozen=True) class LocationData: @@ -519,6 +521,10 @@ def create_locations(location_collector: StardewLocationCollector, location_collector(location_data.name, location_data.code, location_data.region) +def filter_deprecated_locations(locations: Iterable[LocationData]) -> Iterable[LocationData]: + return [location for location in locations if LocationTags.DEPRECATED not in location.tags] + + def filter_farm_type(options: StardewValleyOptions, locations: Iterable[LocationData]) -> Iterable[LocationData]: # On Meadowlands, "Feeding Animals" replaces "Raising Animals" if options.farm_type == FarmType.option_meadowlands: @@ -549,7 +555,8 @@ def filter_modded_locations(options: StardewValleyOptions, locations: Iterable[L def filter_disabled_locations(options: StardewValleyOptions, content: StardewContent, locations: Iterable[LocationData]) -> Iterable[LocationData]: - locations_farm_filter = filter_farm_type(options, locations) + locations_deprecated_filter = filter_deprecated_locations(locations) + locations_farm_filter = filter_farm_type(options, locations_deprecated_filter) locations_island_filter = filter_ginger_island(options, locations_farm_filter) locations_qi_filter = filter_qi_order_locations(options, locations_island_filter) locations_masteries_filter = filter_masteries_locations(content, locations_qi_filter) diff --git a/worlds/stardew_valley/options/options.py b/worlds/stardew_valley/options/options.py index db949718834e..f66ec3bdad80 100644 --- a/worlds/stardew_valley/options/options.py +++ b/worlds/stardew_valley/options/options.py @@ -757,6 +757,14 @@ class Gifting(Toggle): default = 1 +all_mods = {ModNames.deepwoods, ModNames.tractor, ModNames.big_backpack, + ModNames.luck_skill, ModNames.magic, ModNames.socializing_skill, ModNames.archaeology, + ModNames.cooking_skill, ModNames.binning_skill, ModNames.juna, + ModNames.jasper, ModNames.alec, ModNames.yoba, ModNames.eugene, + ModNames.wellwick, ModNames.ginger, ModNames.shiko, ModNames.delores, + ModNames.ayeisha, ModNames.riley, ModNames.skull_cavern_elevator, ModNames.sve, ModNames.distant_lands, + ModNames.alecto, ModNames.lacey, ModNames.boarding_house} + # These mods have been disabled because either they are not updated for the current supported version of Stardew Valley, # or we didn't find the time to validate that they work or fix compatibility issues if they do. # Once a mod is validated to be functional, it can simply be removed from this list @@ -766,8 +774,7 @@ class Gifting(Toggle): ModNames.wellwick, ModNames.shiko, ModNames.delores, ModNames.riley, ModNames.boarding_house} -if 'unittest' in sys.modules.keys() or 'pytest' in sys.modules.keys(): - disabled_mods = {} +enabled_mods = all_mods.difference(disabled_mods) class Mods(OptionSet): @@ -775,13 +782,11 @@ class Mods(OptionSet): visibility = Visibility.all & ~Visibility.simple_ui internal_name = "mods" display_name = "Mods" - valid_keys = {ModNames.deepwoods, ModNames.tractor, ModNames.big_backpack, - ModNames.luck_skill, ModNames.magic, ModNames.socializing_skill, ModNames.archaeology, - ModNames.cooking_skill, ModNames.binning_skill, ModNames.juna, - ModNames.jasper, ModNames.alec, ModNames.yoba, ModNames.eugene, - ModNames.wellwick, ModNames.ginger, ModNames.shiko, ModNames.delores, - ModNames.ayeisha, ModNames.riley, ModNames.skull_cavern_elevator, ModNames.sve, ModNames.distant_lands, - ModNames.alecto, ModNames.lacey, ModNames.boarding_house}.difference(disabled_mods) + valid_keys = enabled_mods + # In tests, we keep even the disabled mods active, because we expect some of them to eventually get updated for SV 1.6 + # In that case, we want to maintain content and logic for them, and therefore keep testing them + if 'unittest' in sys.modules.keys() or 'pytest' in sys.modules.keys(): + valid_keys = all_mods class BundlePlando(OptionSet): diff --git a/worlds/stardew_valley/strings/craftable_names.py b/worlds/stardew_valley/strings/craftable_names.py index 83445c702c32..891330c3ae51 100644 --- a/worlds/stardew_valley/strings/craftable_names.py +++ b/worlds/stardew_valley/strings/craftable_names.py @@ -201,6 +201,10 @@ class ModMachine: composter = "Composter" recycling_bin = "Recycling Bin" advanced_recycling_machine = "Advanced Recycling Machine" + copper_slot_machine = "Copper Slot Machine" + gold_slot_machine = "Gold Slot Machine" + iridium_slot_machine = "Iridium Slot Machine" + radioactive_slot_machine = "Radioactive Slot Machine" class ModFloor: diff --git a/worlds/stardew_valley/test/TestNumberLocations.py b/worlds/stardew_valley/test/TestNumberLocations.py index ef552c10e8d5..a1c6a96741a1 100644 --- a/worlds/stardew_valley/test/TestNumberLocations.py +++ b/worlds/stardew_valley/test/TestNumberLocations.py @@ -1,5 +1,6 @@ from . import SVTestBase, allsanity_no_mods_6_x_x, \ - allsanity_mods_6_x_x, minimal_locations_maximal_items, minimal_locations_maximal_items_with_island, get_minsanity_options, default_6_x_x + allsanity_mods_6_x_x, minimal_locations_maximal_items, minimal_locations_maximal_items_with_island, get_minsanity_options, default_6_x_x, \ + allsanity_mods_6_x_x_exclude_disabled from .. import location_table from ..items import Group, item_table @@ -70,7 +71,7 @@ class TestAllSanitySettingsHasAllExpectedLocations(SVTestBase): options = allsanity_no_mods_6_x_x() def test_allsanity_without_mods_has_at_least_locations(self): - expected_locations = 2238 + expected_locations = 2256 real_locations = self.get_real_locations() number_locations = len(real_locations) print(f"Stardew Valley - Allsanity Locations without mods: {number_locations}") @@ -83,10 +84,10 @@ def test_allsanity_without_mods_has_at_least_locations(self): class TestAllSanityWithModsSettingsHasAllExpectedLocations(SVTestBase): - options = allsanity_mods_6_x_x() + options = allsanity_mods_6_x_x_exclude_disabled() def test_allsanity_with_mods_has_at_least_locations(self): - expected_locations = 3096 + expected_locations = 2908 real_locations = self.get_real_locations() number_locations = len(real_locations) print(f"Stardew Valley - Allsanity Locations with all mods: {number_locations}") diff --git a/worlds/stardew_valley/test/__init__.py b/worlds/stardew_valley/test/__init__.py index de0ed97882e3..880a3fda5ca0 100644 --- a/worlds/stardew_valley/test/__init__.py +++ b/worlds/stardew_valley/test/__init__.py @@ -13,6 +13,7 @@ from .options.utils import fill_namespace_with_default, parse_class_option_keys, fill_dataclass_with_default from .. import StardewValleyWorld, options, StardewItem from ..options import StardewValleyOption +from ..options.options import enabled_mods logger = logging.getLogger(__name__) @@ -98,6 +99,12 @@ def allsanity_mods_6_x_x(): return allsanity +def allsanity_mods_6_x_x_exclude_disabled(): + allsanity = allsanity_no_mods_6_x_x() + allsanity.update({options.Mods.internal_name: frozenset(enabled_mods)}) + return allsanity + + def get_minsanity_options(): return { options.ArcadeMachineLocations.internal_name: options.ArcadeMachineLocations.option_disabled, From b91a7ac6fbfc0060c5262402669e2e84c56d9fcd Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:52:58 -0500 Subject: [PATCH 0031/1218] LADX: Move Locality Changes Earlier (#4478) --- worlds/ladx/__init__.py | 47 ++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/worlds/ladx/__init__.py b/worlds/ladx/__init__.py index b8de6da812df..09a25eb1cd09 100644 --- a/worlds/ladx/__init__.py +++ b/worlds/ladx/__init__.py @@ -140,6 +140,28 @@ def convert_ap_options_to_ladxr_logic(self): self.ladxr_logic = LADXRLogic(configuration_options=self.ladxr_settings, world_setup=world_setup) self.ladxr_itempool = LADXRItemPool(self.ladxr_logic, self.ladxr_settings, self.random).toDict() + def generate_early(self) -> None: + self.dungeon_item_types = { + } + for dungeon_item_type in ["maps", "compasses", "small_keys", "nightmare_keys", "stone_beaks", "instruments"]: + option_name = "shuffle_" + dungeon_item_type + option: DungeonItemShuffle = getattr(self.options, option_name) + + self.dungeon_item_types[option.ladxr_item] = option.value + + # The color dungeon does not contain an instrument + num_items = 8 if dungeon_item_type == "instruments" else 9 + + # For any and different world, set item rule instead + if option.value == DungeonItemShuffle.option_own_world: + self.options.local_items.value |= { + ladxr_item_to_la_item_name[f"{option.ladxr_item}{i}"] for i in range(1, num_items + 1) + } + elif option.value == DungeonItemShuffle.option_different_world: + self.options.non_local_items.value |= { + ladxr_item_to_la_item_name[f"{option.ladxr_item}{i}"] for i in range(1, num_items + 1) + } + def create_regions(self) -> None: # Initialize self.convert_ap_options_to_ladxr_logic() @@ -185,32 +207,9 @@ def create_event(self, event: str): def create_items(self) -> None: exclude = [item.name for item in self.multiworld.precollected_items[self.player]] - dungeon_item_types = { - - } - self.prefill_original_dungeon = [ [], [], [], [], [], [], [], [], [] ] self.prefill_own_dungeons = [] self.pre_fill_items = [] - # For any and different world, set item rule instead - - for dungeon_item_type in ["maps", "compasses", "small_keys", "nightmare_keys", "stone_beaks", "instruments"]: - option_name = "shuffle_" + dungeon_item_type - option: DungeonItemShuffle = getattr(self.options, option_name) - - dungeon_item_types[option.ladxr_item] = option.value - - # The color dungeon does not contain an instrument - num_items = 8 if dungeon_item_type == "instruments" else 9 - - if option.value == DungeonItemShuffle.option_own_world: - self.options.local_items.value |= { - ladxr_item_to_la_item_name[f"{option.ladxr_item}{i}"] for i in range(1, num_items + 1) - } - elif option.value == DungeonItemShuffle.option_different_world: - self.options.non_local_items.value |= { - ladxr_item_to_la_item_name[f"{option.ladxr_item}{i}"] for i in range(1, num_items + 1) - } # option_original_dungeon = 0 # option_own_dungeons = 1 # option_own_world = 2 @@ -238,7 +237,7 @@ def create_items(self) -> None: if isinstance(item.item_data, DungeonItemData): item_type = item.item_data.ladxr_id[:-1] - shuffle_type = dungeon_item_types[item_type] + shuffle_type = self.dungeon_item_types[item_type] if item.item_data.dungeon_item_type == DungeonItemType.INSTRUMENT and shuffle_type == ShuffleInstruments.option_vanilla: # Find instrument, lock From bedf746f1d90f128072034dedc3b6603541befe7 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Tue, 14 Jan 2025 21:37:10 +0100 Subject: [PATCH 0032/1218] MultiServer: Revert hints being created for already found locations #4367 --- MultiServer.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 8aabdea3e2bf..c3f62e156114 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -743,16 +743,17 @@ def notify_hints(self, team: int, hints: typing.List[Hint], only_new: bool = Fal concerns[player].append(data) if not hint.local and data not in concerns[hint.finding_player]: concerns[hint.finding_player].append(data) - # remember hints in all cases - - # since hints are bidirectional, finding player and receiving player, - # we can check once if hint already exists - if hint not in self.hints[team, hint.finding_player]: - self.hints[team, hint.finding_player].add(hint) - new_hint_events.add(hint.finding_player) - for player in self.slot_set(hint.receiving_player): - self.hints[team, player].add(hint) - new_hint_events.add(player) + + # only remember hints that were not already found at the time of creation + if not hint.found: + # since hints are bidirectional, finding player and receiving player, + # we can check once if hint already exists + if hint not in self.hints[team, hint.finding_player]: + self.hints[team, hint.finding_player].add(hint) + new_hint_events.add(hint.finding_player) + for player in self.slot_set(hint.receiving_player): + self.hints[team, player].add(hint) + new_hint_events.add(player) self.logger.info("Notice (Team #%d): %s" % (team + 1, format_hint(self, team, hint))) for slot in new_hint_events: From 01df35f2152365bff0c82ebfb51f126e3b7af554 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 14 Jan 2025 22:24:46 +0100 Subject: [PATCH 0033/1218] Factorio: fix Evolution Trap crashing bound server (#4366) --- worlds/factorio/data/mod_template/control.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/worlds/factorio/data/mod_template/control.lua b/worlds/factorio/data/mod_template/control.lua index 40903250461c..87669beaf199 100644 --- a/worlds/factorio/data/mod_template/control.lua +++ b/worlds/factorio/data/mod_template/control.lua @@ -717,8 +717,10 @@ TRAP_TABLE = { game.surfaces["nauvis"].build_enemy_base(game.forces["player"].get_spawn_position(game.get_surface(1)), 25) end, ["Evolution Trap"] = function () - game.forces["enemy"].evolution_factor = game.forces["enemy"].evolution_factor + (TRAP_EVO_FACTOR * (1 - game.forces["enemy"].evolution_factor)) - game.print({"", "New evolution factor:", game.forces["enemy"].evolution_factor}) + local new_factor = game.forces["enemy"].get_evolution_factor("nauvis") + + (TRAP_EVO_FACTOR * (1 - game.forces["enemy"].get_evolution_factor("nauvis"))) + game.forces["enemy"].set_evolution_factor(new_factor, "nauvis") + game.print({"", "New evolution factor:", new_factor}) end, ["Teleport Trap"] = function () for _, player in ipairs(game.forces["player"].players) do From 207a76d1b5e123656ae2c547482a544467c7dba5 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:39:13 -0500 Subject: [PATCH 0034/1218] OoT: Two Bugfixes (#4389) --- worlds/oot/Patches.py | 2 +- worlds/oot/__init__.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/worlds/oot/Patches.py b/worlds/oot/Patches.py index 561d7c3f7b6e..cd940e052a2b 100644 --- a/worlds/oot/Patches.py +++ b/worlds/oot/Patches.py @@ -2200,7 +2200,7 @@ def update_scrub_text(message, text_replacement, default_price, price, item_name elif world.shuffle_bosses != 'off': vanilla_reward = world.get_location(boss_name).vanilla_item vanilla_reward_location = world.multiworld.find_item(vanilla_reward, world.player) # hinted_dungeon_reward_locations[vanilla_reward.name] - area = HintArea.at(vanilla_reward_location).text(world.clearer_hints, preposition=True) + area = HintArea.at(vanilla_reward_location).text(world.hint_rng, world.clearer_hints, preposition=True) compass_message = "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for %s\x05\x40!\x01The %s can be found\x01%s!\x09" % (dungeon_name, vanilla_reward, area) else: boss_location = next(filter(lambda loc: loc.type == 'Boss', world.get_entrance(f'{dungeon} Boss Door -> {boss_name} Boss Room').connected_region.locations)) diff --git a/worlds/oot/__init__.py b/worlds/oot/__init__.py index 975902ae6e64..3de55f68243b 100644 --- a/worlds/oot/__init__.py +++ b/worlds/oot/__init__.py @@ -582,8 +582,7 @@ def load_regions_from_json(self, file_path): new_exit = OOTEntrance(self.player, self.multiworld, '%s -> %s' % (new_region.name, exit), new_region) new_exit.vanilla_connected_region = exit new_exit.rule_string = rule - if self.options.logic_rules != 'no_logic': - self.parser.parse_spot_rule(new_exit) + self.parser.parse_spot_rule(new_exit) if new_exit.never: logger.debug('Dropping unreachable exit: %s', new_exit.name) else: From 1eefe23f1101e4d1c795b599f44ca2b4b9d04531 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Wed, 15 Jan 2025 15:13:29 -0500 Subject: [PATCH 0035/1218] Lingo: Add speed boost mode (#3989) * Add speed boost mode * Update generated.dat * Modify the actual trap weights option when speed boost mode is on * EOF newline * Update generated.dat --- worlds/lingo/__init__.py | 12 +++++++++--- worlds/lingo/data/generated.dat | Bin 149485 -> 149504 bytes worlds/lingo/data/ids.yaml | 1 + worlds/lingo/items.py | 1 + worlds/lingo/options.py | 10 ++++++++++ worlds/lingo/test/TestOptions.py | 9 ++++++++- worlds/lingo/utils/assign_ids.rb | 3 +++ 7 files changed, 32 insertions(+), 4 deletions(-) diff --git a/worlds/lingo/__init__.py b/worlds/lingo/__init__.py index 2a61a71f5fce..141fca0743bc 100644 --- a/worlds/lingo/__init__.py +++ b/worlds/lingo/__init__.py @@ -128,6 +128,9 @@ def create_items(self): pool.append(self.create_item("Puzzle Skip")) if traps: + if self.options.speed_boost_mode: + self.options.trap_weights.value["Slowness Trap"] = 0 + total_weight = sum(self.options.trap_weights.values()) if total_weight == 0: @@ -171,7 +174,7 @@ def fill_slot_data(self): "death_link", "victory_condition", "shuffle_colors", "shuffle_doors", "shuffle_paintings", "shuffle_panels", "enable_pilgrimage", "sunwarp_access", "mastery_achievements", "level_2_requirement", "location_checks", "early_color_hallways", "pilgrimage_allows_roof_access", "pilgrimage_allows_paintings", "shuffle_sunwarps", - "group_doors" + "group_doors", "speed_boost_mode" ] slot_data = { @@ -188,5 +191,8 @@ def fill_slot_data(self): return slot_data def get_filler_item_name(self) -> str: - filler_list = [":)", "The Feeling of Being Lost", "Wanderlust", "Empty White Hallways"] - return self.random.choice(filler_list) + if self.options.speed_boost_mode: + return "Speed Boost" + else: + filler_list = [":)", "The Feeling of Being Lost", "Wanderlust", "Empty White Hallways"] + return self.random.choice(filler_list) diff --git a/worlds/lingo/data/generated.dat b/worlds/lingo/data/generated.dat index 8b159d4ae4ac7c565e2372b1cc43d7a349b2ca7c..646ce3b5d7430dad51aa01a3a3f0e73b62106884 100644 GIT binary patch delta 2672 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 diff --git a/worlds/lingo/data/ids.yaml b/worlds/lingo/data/ids.yaml index 13b77145ea2c..0a43592d3fc2 100644 --- a/worlds/lingo/data/ids.yaml +++ b/worlds/lingo/data/ids.yaml @@ -17,6 +17,7 @@ special_items: Iceland Trap: 444411 Atbash Trap: 444412 Puzzle Skip: 444413 + Speed Boost: 444680 panels: Starting Room: HI: 444400 diff --git a/worlds/lingo/items.py b/worlds/lingo/items.py index 78b288e7c2df..7e75cc76c739 100644 --- a/worlds/lingo/items.py +++ b/worlds/lingo/items.py @@ -85,6 +85,7 @@ def load_item_data(): "The Feeling of Being Lost": ItemClassification.filler, "Wanderlust": ItemClassification.filler, "Empty White Hallways": ItemClassification.filler, + "Speed Boost": ItemClassification.filler, **{trap_name: ItemClassification.trap for trap_name in TRAP_ITEMS}, "Puzzle Skip": ItemClassification.useful, } diff --git a/worlds/lingo/options.py b/worlds/lingo/options.py index 2d6e9967dfc4..f9d04f68fc8e 100644 --- a/worlds/lingo/options.py +++ b/worlds/lingo/options.py @@ -232,6 +232,14 @@ class TrapWeights(OptionDict): default = {trap_name: 1 for trap_name in TRAP_ITEMS} +class SpeedBoostMode(Toggle): + """ + If on, the player's default speed is halved, as if affected by a Slowness Trap. Speed Boosts are added to + the item pool, which temporarily return the player to normal speed. Slowness Traps are removed from the pool. + """ + display_name = "Speed Boost Mode" + + class PuzzleSkipPercentage(Range): """Replaces junk items with puzzle skips, at the specified rate.""" display_name = "Puzzle Skip Percentage" @@ -260,6 +268,7 @@ class DeathLink(Toggle): Level2Requirement, TrapPercentage, TrapWeights, + SpeedBoostMode, PuzzleSkipPercentage, ]) ] @@ -287,6 +296,7 @@ class LingoOptions(PerGameCommonOptions): shuffle_postgame: ShufflePostgame trap_percentage: TrapPercentage trap_weights: TrapWeights + speed_boost_mode: SpeedBoostMode puzzle_skip_percentage: PuzzleSkipPercentage death_link: DeathLink start_inventory_from_pool: StartInventoryPool diff --git a/worlds/lingo/test/TestOptions.py b/worlds/lingo/test/TestOptions.py index bd8ed81d7a12..224dbe0f7573 100644 --- a/worlds/lingo/test/TestOptions.py +++ b/worlds/lingo/test/TestOptions.py @@ -59,4 +59,11 @@ class TestShuffleSunwarpsAccess(LingoTestBase): "victory_condition": "pilgrimage", "shuffle_sunwarps": "true", "sunwarp_access": "individual" - } \ No newline at end of file + } + + +class TestSpeedBoostMode(LingoTestBase): + options = { + "location_checks": "insanity", + "speed_boost_mode": "true", + } diff --git a/worlds/lingo/utils/assign_ids.rb b/worlds/lingo/utils/assign_ids.rb index f7de3d03f582..bcb8018ebcc3 100644 --- a/worlds/lingo/utils/assign_ids.rb +++ b/worlds/lingo/utils/assign_ids.rb @@ -216,3 +216,6 @@ end File.write(outputpath, old_generated.to_yaml) + +puts "Next item ID: #{next_item_id}" +puts "Next location ID: #{next_location_id}" From 9dac7d9cc3bf313127f02d1a6d2ba9bd01a451ee Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 15 Jan 2025 21:50:20 +0100 Subject: [PATCH 0036/1218] MultiServer: update InvalidPacket text for location scouts (#4485) --- MultiServer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MultiServer.py b/MultiServer.py index c3f62e156114..81426cb132d8 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1888,7 +1888,8 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): for location in args["locations"]: if type(location) is not int: await ctx.send_msgs(client, - [{'cmd': 'InvalidPacket', "type": "arguments", "text": 'LocationScouts', + [{'cmd': 'InvalidPacket', "type": "arguments", + "text": 'Locations has to be a list of integers', "original_cmd": cmd}]) return From b7baaed39112d9a5e1c5b17b1914bf5205328535 Mon Sep 17 00:00:00 2001 From: Silent <110704408+silent-destroyer@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:17:07 -0500 Subject: [PATCH 0037/1218] TUNIC: Grass Randomizer (#3913) * Fix certain items not being added to slot data * Change where items get added to slot data * Add initial grass randomizer stuff * Fix rules * Update grass.py Improve location names * Remove wand and gun from logic * Update __init__.py * Fix logic for two pieces of grass in atoll * Make early bushes only contain grass * Backport changes to grass rando (#20) * Backport changes to grass rando * add_rule instead of set_rule for the special cases, add special cases for back of swamp laurels area cause I should've made a new region for the swamp upper entrance * Remove item name group for grass * Update grass rando option descriptions - Also ignore grass fill for single player games * Ignore grass fill option for solo rando * Update er_rules.py * Fix pre fill issue * Remove duplicate option * Add excluded grass locations back * Hide grass fill option from simple ui options page * Check for start with sword before setting grass rules * Update worlds/tunic/options.py Co-authored-by: Scipio Wright * Exclude grass from get_filler_item_name - non-grass rando games were accidentally seeing grass items get shuffled in as filler, which is funny but probably shouldn't happen * Update worlds/tunic/__init__.py Co-authored-by: Scipio Wright * Apply suggestions from code review Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: Scipio Wright * change the rest of grass_fill to local_fill * Filter out grass from filler_items * remove -> discard * Update worlds/tunic/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * change has_stick to has_melee * Update grass list with combat logic regions * More fixes from combat logic merge * Fix some dumb stuff (#21) * Reorganize pre fill for grass * Update option value passthrough * Update __init__.py * Fix region name * Make separate pools for the grass and non-grass fills (#22) * Make separate pools for the grass and non-grass fills * Update worlds/tunic/__init__.py Co-authored-by: Scipio Wright * Fix those things in the PR (#23) * Use excludable property Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --------- Co-authored-by: Scipio Wright Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/tunic/__init__.py | 120 +- worlds/tunic/er_data.py | 14 +- worlds/tunic/er_rules.py | 40 +- worlds/tunic/er_scripts.py | 6 +- worlds/tunic/grass.py | 7944 ++++++++++++++++++++++++++++++++++++ worlds/tunic/items.py | 3 +- worlds/tunic/locations.py | 25 +- worlds/tunic/options.py | 32 +- 8 files changed, 8156 insertions(+), 28 deletions(-) create mode 100644 worlds/tunic/grass.py diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 1c326f78bd43..09279dd1bd86 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -1,19 +1,20 @@ -from typing import Dict, List, Any, Tuple, TypedDict, ClassVar, Union +from typing import Dict, List, Any, Tuple, TypedDict, ClassVar, Union, Set from logging import warning from BaseClasses import Region, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState from .items import (item_name_to_id, item_table, item_name_groups, fool_tiers, filler_items, slot_data_item_names, combat_items) -from .locations import location_table, location_name_groups, location_name_to_id, hexagon_locations +from .locations import location_table, location_name_groups, standard_location_name_to_id, hexagon_locations, sphere_one from .rules import set_location_rules, set_region_rules, randomize_ability_unlocks, gold_hexagon from .er_rules import set_er_location_rules from .regions import tunic_regions from .er_scripts import create_er_regions +from .grass import grass_location_table, grass_location_name_to_id, grass_location_name_groups, excluded_grass_locations from .er_data import portal_mapping, RegionInfo, tunic_er_regions from .options import (TunicOptions, EntranceRando, tunic_option_groups, tunic_option_presets, TunicPlandoConnections, LaurelsLocation, LogicRules, LaurelsZips, IceGrappling, LadderStorage) from .combat_logic import area_data, CombatState from worlds.AutoWorld import WebWorld, World -from Options import PlandoConnection +from Options import PlandoConnection, OptionError from decimal import Decimal, ROUND_HALF_UP from settings import Group, Bool @@ -22,7 +23,11 @@ class TunicSettings(Group): class DisableLocalSpoiler(Bool): """Disallows the TUNIC client from creating a local spoiler log.""" + class LimitGrassRando(Bool): + """Limits the impact of Grass Randomizer on the multiworld by disallowing local_fill percentages below 95.""" + disable_local_spoiler: Union[DisableLocalSpoiler, bool] = False + limit_grass_rando: Union[LimitGrassRando, bool] = True class TunicWeb(WebWorld): @@ -73,10 +78,13 @@ class TunicWorld(World): settings: ClassVar[TunicSettings] item_name_groups = item_name_groups location_name_groups = location_name_groups + location_name_groups.update(grass_location_name_groups) item_name_to_id = item_name_to_id - location_name_to_id = location_name_to_id + location_name_to_id = standard_location_name_to_id.copy() + location_name_to_id.update(grass_location_name_to_id) + player_location_table: Dict[str, int] ability_unlocks: Dict[str, int] slot_data_items: List[TunicItem] tunic_portal_pairs: Dict[str, str] @@ -85,6 +93,11 @@ class TunicWorld(World): shop_num: int = 1 # need to make it so that you can walk out of shops, but also that they aren't all connected er_regions: Dict[str, RegionInfo] # absolutely needed so outlet regions work + # for the local_fill option + fill_items: List[TunicItem] + fill_locations: List[TunicLocation] + amount_to_local_fill: int + # so we only loop the multiworld locations once # if these are locations instead of their info, it gives a memory leak error item_link_locations: Dict[int, Dict[str, List[Tuple[int, str]]]] = {} @@ -132,6 +145,7 @@ def generate_early(self) -> None: self.options.hexagon_quest.value = self.passthrough["hexagon_quest"] self.options.entrance_rando.value = self.passthrough["entrance_rando"] self.options.shuffle_ladders.value = self.passthrough["shuffle_ladders"] + self.options.grass_randomizer.value = self.passthrough.get("grass_randomizer", 0) self.options.fixed_shop.value = self.options.fixed_shop.option_false self.options.laurels_location.value = self.options.laurels_location.option_anywhere self.options.combat_logic.value = self.passthrough["combat_logic"] @@ -140,6 +154,22 @@ def generate_early(self) -> None: else: self.using_ut = False + self.player_location_table = standard_location_name_to_id.copy() + + if self.options.local_fill == -1: + if self.options.grass_randomizer: + self.options.local_fill.value = 95 + else: + self.options.local_fill.value = 0 + + if self.options.grass_randomizer: + if self.settings.limit_grass_rando and self.options.local_fill < 95 and self.multiworld.players > 1: + raise OptionError(f"TUNIC: Player {self.player_name} has their Local Fill option set too low. " + f"They must either bring it above 95% or the host needs to disable limit_grass_rando " + f"in their host.yaml settings") + + self.player_location_table.update(grass_location_name_to_id) + @classmethod def stage_generate_early(cls, multiworld: MultiWorld) -> None: tunic_worlds: Tuple[TunicWorld] = multiworld.get_game_worlds("TUNIC") @@ -245,6 +275,14 @@ def create_items(self) -> None: self.get_location("Secret Gathering Place - 10 Fairy Reward").place_locked_item(laurels) items_to_create["Hero's Laurels"] = 0 + if self.options.grass_randomizer: + items_to_create["Grass"] = len(grass_location_table) + tunic_items.append(self.create_item("Glass Cannon", ItemClassification.progression)) + items_to_create["Glass Cannon"] = 0 + for grass_location in excluded_grass_locations: + self.get_location(grass_location).place_locked_item(self.create_item("Grass")) + items_to_create["Grass"] -= len(excluded_grass_locations) + if self.options.keys_behind_bosses: for rgb_hexagon, location in hexagon_locations.items(): hex_item = self.create_item(gold_hexagon if self.options.hexagon_quest else rgb_hexagon) @@ -332,8 +370,73 @@ def remove_filler(amount: int) -> None: if tunic_item.name in slot_data_item_names: self.slot_data_items.append(tunic_item) + # pull out the filler so that we can place it manually during pre_fill + self.fill_items = [] + if self.options.local_fill > 0 and self.multiworld.players > 1: + # skip items marked local or non-local, let fill deal with them in its own way + # discard grass from non_local if it's meant to be limited + if self.settings.limit_grass_rando: + self.options.non_local_items.value.discard("Grass") + all_filler: List[TunicItem] = [] + non_filler: List[TunicItem] = [] + for tunic_item in tunic_items: + if (tunic_item.excludable + and tunic_item.name not in self.options.local_items + and tunic_item.name not in self.options.non_local_items): + all_filler.append(tunic_item) + else: + non_filler.append(tunic_item) + self.amount_to_local_fill = int(self.options.local_fill.value * len(all_filler) / 100) + self.fill_items += all_filler[:self.amount_to_local_fill] + del all_filler[:self.amount_to_local_fill] + tunic_items = all_filler + non_filler + self.multiworld.itempool += tunic_items + def pre_fill(self) -> None: + self.fill_locations = [] + + if self.options.local_fill > 0 and self.multiworld.players > 1: + # we need to reserve a couple locations so that we don't fill up every sphere 1 location + reserved_locations: Set[str] = set(self.random.sample(sphere_one, 2)) + viable_locations = [loc for loc in self.multiworld.get_unfilled_locations(self.player) + if loc.name not in reserved_locations + and loc.name not in self.options.priority_locations.value] + + if len(viable_locations) < self.amount_to_local_fill: + raise OptionError(f"TUNIC: Not enough locations for local_fill option for {self.player_name}. " + f"This is likely due to excess plando or priority locations.") + + self.fill_locations += viable_locations + + @classmethod + def stage_pre_fill(cls, multiworld: MultiWorld) -> None: + tunic_fill_worlds: List[TunicWorld] = [world for world in multiworld.get_game_worlds("TUNIC") + if world.options.local_fill.value > 0] + if tunic_fill_worlds: + grass_fill: List[TunicItem] = [] + non_grass_fill: List[TunicItem] = [] + grass_fill_locations: List[Location] = [] + non_grass_fill_locations: List[Location] = [] + for world in tunic_fill_worlds: + if world.options.grass_randomizer: + grass_fill.extend(world.fill_items) + grass_fill_locations.extend(world.fill_locations) + else: + non_grass_fill.extend(world.fill_items) + non_grass_fill_locations.extend(world.fill_locations) + + multiworld.random.shuffle(grass_fill) + multiworld.random.shuffle(non_grass_fill) + multiworld.random.shuffle(grass_fill_locations) + multiworld.random.shuffle(non_grass_fill_locations) + + for filler_item in grass_fill: + multiworld.push_item(grass_fill_locations.pop(), filler_item, collect=False) + + for filler_item in non_grass_fill: + multiworld.push_item(non_grass_fill_locations.pop(), filler_item, collect=False) + def create_regions(self) -> None: self.tunic_portal_pairs = {} self.er_portal_hints = {} @@ -346,7 +449,8 @@ def create_regions(self) -> None: self.ability_unlocks["Pages 52-53 (Icebolt)"] = self.passthrough["Hexagon Quest Icebolt"] # Ladders and Combat Logic uses ER rules with vanilla connections for easier maintenance - if self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic: + if (self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic + or self.options.grass_randomizer): portal_pairs = create_er_regions(self) if self.options.entrance_rando: # these get interpreted by the game to tell it which entrances to connect @@ -362,7 +466,7 @@ def create_regions(self) -> None: region = self.get_region(region_name) region.add_exits(exits) - for location_name, location_id in self.location_name_to_id.items(): + for location_name, location_id in self.player_location_table.items(): region = self.get_region(location_table[location_name].region) location = TunicLocation(self.player, location_name, location_id, region) region.locations.append(location) @@ -375,7 +479,8 @@ def create_regions(self) -> None: def set_rules(self) -> None: # same reason as in create_regions, could probably be put into create_regions - if self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic: + if (self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic + or self.options.grass_randomizer): set_er_location_rules(self) else: set_region_rules(self) @@ -463,6 +568,7 @@ def fill_slot_data(self) -> Dict[str, Any]: "maskless": self.options.maskless.value, "entrance_rando": int(bool(self.options.entrance_rando.value)), "shuffle_ladders": self.options.shuffle_ladders.value, + "grass_randomizer": self.options.grass_randomizer.value, "combat_logic": self.options.combat_logic.value, "Hexagon Quest Prayer": self.ability_unlocks["Pages 24-25 (Prayer)"], "Hexagon Quest Holy Cross": self.ability_unlocks["Pages 42-43 (Holy Cross)"], diff --git a/worlds/tunic/er_data.py b/worlds/tunic/er_data.py index 1dc06d586d6f..f1a428cce1b5 100644 --- a/worlds/tunic/er_data.py +++ b/worlds/tunic/er_data.py @@ -629,14 +629,16 @@ class DeadEnd(IntEnum): "Beneath the Well Back": RegionInfo("Sewer"), # the back two portals, and all 4 upper chests "West Garden before Terry": RegionInfo("Archipelagos Redux"), # the lower entry point, near hero grave "West Garden after Terry": RegionInfo("Archipelagos Redux"), # after Terry, up until next chompignons + "West Garden West Combat": RegionInfo("Archipelagos Redux"), # for grass rando basically "West Garden at Dagger House": RegionInfo("Archipelagos Redux"), # just outside magic dagger house - "West Garden South Checkpoint": RegionInfo("Archipelagos Redux"), + "West Garden South Checkpoint": RegionInfo("Archipelagos Redux"), # the checkpoint and the blue lines area "Magic Dagger House": RegionInfo("archipelagos_house", dead_end=DeadEnd.all_cats), - "West Garden Portal": RegionInfo("Archipelagos Redux", dead_end=DeadEnd.restricted, outlet_region="West Garden by Portal"), + "West Garden Portal": RegionInfo("Archipelagos Redux", dead_end=DeadEnd.restricted, + outlet_region="West Garden by Portal"), "West Garden by Portal": RegionInfo("Archipelagos Redux", dead_end=DeadEnd.restricted), "West Garden Portal Item": RegionInfo("Archipelagos Redux", dead_end=DeadEnd.restricted), "West Garden Laurels Exit Region": RegionInfo("Archipelagos Redux"), - "West Garden before Boss": RegionInfo("Archipelagos Redux"), # main west garden + "West Garden before Boss": RegionInfo("Archipelagos Redux"), # up the ladder before garden knight "West Garden after Boss": RegionInfo("Archipelagos Redux"), "West Garden Hero's Grave Region": RegionInfo("Archipelagos Redux", outlet_region="West Garden before Terry"), "Ruined Atoll": RegionInfo("Atoll Redux"), @@ -1165,8 +1167,10 @@ class DeadEnd(IntEnum): "West Garden after Terry": { "West Garden before Terry": [], - "West Garden South Checkpoint": + "West Garden West Combat": [], + "West Garden South Checkpoint": + [["Hyperdash"]], "West Garden Laurels Exit Region": [["LS1"]], }, @@ -1176,6 +1180,8 @@ class DeadEnd(IntEnum): "West Garden at Dagger House": [], "West Garden after Terry": + [["Hyperdash"]], + "West Garden West Combat": [], }, "West Garden before Boss": { diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index f7568df81e49..08b088f7e4a7 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -1,12 +1,13 @@ from typing import Dict, FrozenSet, Tuple, TYPE_CHECKING from worlds.generic.Rules import set_rule, add_rule, forbid_item +from BaseClasses import Region, CollectionState from .options import IceGrappling, LadderStorage, CombatLogic from .rules import (has_ability, has_sword, has_melee, has_ice_grapple_logic, has_lantern, has_mask, can_ladder_storage, laurels_zip, bomb_walls) from .er_data import Portal, get_portal_outlet_region from .ladder_storage_data import ow_ladder_groups, region_ladders, easy_ls, medium_ls, hard_ls from .combat_logic import has_combat_reqs -from BaseClasses import Region, CollectionState +from .grass import set_grass_location_rules if TYPE_CHECKING: from . import TunicWorld @@ -555,7 +556,6 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Dark Tomb Upper"].connect( connecting_region=regions["Dark Tomb Entry Point"]) - # ice grapple through the wall, get the little secret sound to trigger regions["Dark Tomb Upper"].connect( connecting_region=regions["Dark Tomb Main"], rule=lambda state: has_ladder("Ladder in Dark Tomb", state, world) @@ -577,11 +577,24 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: wg_after_to_before_terry = regions["West Garden after Terry"].connect( connecting_region=regions["West Garden before Terry"]) - regions["West Garden after Terry"].connect( - connecting_region=regions["West Garden South Checkpoint"]) - wg_checkpoint_to_after_terry = regions["West Garden South Checkpoint"].connect( + wg_after_terry_to_west_combat = regions["West Garden after Terry"].connect( + connecting_region=regions["West Garden West Combat"]) + regions["West Garden West Combat"].connect( connecting_region=regions["West Garden after Terry"]) + wg_checkpoint_to_west_combat = regions["West Garden South Checkpoint"].connect( + connecting_region=regions["West Garden West Combat"]) + regions["West Garden West Combat"].connect( + connecting_region=regions["West Garden South Checkpoint"]) + + # if not laurels, it goes through the west combat region instead + regions["West Garden after Terry"].connect( + connecting_region=regions["West Garden South Checkpoint"], + rule=lambda state: state.has(laurels, player)) + regions["West Garden South Checkpoint"].connect( + connecting_region=regions["West Garden after Terry"], + rule=lambda state: state.has(laurels, player)) + wg_checkpoint_to_dagger = regions["West Garden South Checkpoint"].connect( connecting_region=regions["West Garden at Dagger House"]) regions["West Garden at Dagger House"].connect( @@ -1402,12 +1415,16 @@ def ls_connect(origin_name: str, portal_sdt: str) -> None: set_rule(wg_after_to_before_terry, lambda state: state.has_any({laurels, ice_dagger}, player) or has_combat_reqs("West Garden", state, player)) - # laurels through, probably to the checkpoint, or just fight - set_rule(wg_checkpoint_to_after_terry, - lambda state: state.has(laurels, player) or has_combat_reqs("West Garden", state, player)) - set_rule(wg_checkpoint_to_before_boss, + + set_rule(wg_after_terry_to_west_combat, + lambda state: has_combat_reqs("West Garden", state, player)) + set_rule(wg_checkpoint_to_west_combat, lambda state: has_combat_reqs("West Garden", state, player)) + # maybe a little too generous? probably fine though + set_rule(wg_checkpoint_to_before_boss, + lambda state: state.has(laurels, player) or has_combat_reqs("West Garden", state, player)) + add_rule(btv_front_to_main, lambda state: has_combat_reqs("Beneath the Vault", state, player)) add_rule(btv_back_to_main, @@ -1528,6 +1545,9 @@ def ls_connect(origin_name: str, portal_sdt: str) -> None: def set_er_location_rules(world: "TunicWorld") -> None: player = world.player + if world.options.grass_randomizer: + set_grass_location_rules(world) + forbid_item(world.get_location("Secret Gathering Place - 20 Fairy Reward"), fairies, player) # Ability Shuffle Exclusive Rules @@ -1852,6 +1872,8 @@ def combat_logic_to_loc(loc_name: str, combat_req_area: str, set_instead: bool = combat_logic_to_loc("West Garden - [Central Lowlands] Chest Beneath Faeries", "West Garden") combat_logic_to_loc("West Garden - [Central Lowlands] Chest Beneath Save Point", "West Garden") combat_logic_to_loc("West Garden - [West Highlands] Upper Left Walkway", "West Garden") + combat_logic_to_loc("West Garden - [Central Highlands] Holy Cross (Blue Lines)", "West Garden") + combat_logic_to_loc("West Garden - [Central Highlands] Behind Guard Captain", "West Garden") # with combat logic on, I presume the player will want to be able to see to avoid the spiders set_rule(world.get_location("Beneath the Fortress - Bridge"), diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index ed9fc0120ddc..4cd0f49ddf9b 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -1,6 +1,6 @@ from typing import Dict, List, Set, Tuple, TYPE_CHECKING from BaseClasses import Region, ItemClassification, Item, Location -from .locations import location_table +from .locations import all_locations from .er_data import Portal, portal_mapping, traversal_requirements, DeadEnd, RegionInfo from .er_rules import set_er_region_rules from Options import PlandoConnection @@ -53,8 +53,8 @@ def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]: set_er_region_rules(world, regions, portal_pairs) - for location_name, location_id in world.location_name_to_id.items(): - region = regions[location_table[location_name].er_region] + for location_name, location_id in world.player_location_table.items(): + region = regions[all_locations[location_name].er_region] location = TunicERLocation(world.player, location_name, location_id, region) region.locations.append(location) diff --git a/worlds/tunic/grass.py b/worlds/tunic/grass.py new file mode 100644 index 000000000000..592b2938b118 --- /dev/null +++ b/worlds/tunic/grass.py @@ -0,0 +1,7944 @@ +from typing import Dict, NamedTuple, Optional, TYPE_CHECKING, Set + +from BaseClasses import CollectionState +from worlds.generic.Rules import set_rule, add_rule +from .rules import has_sword, has_melee +if TYPE_CHECKING: + from . import TunicWorld + + +class TunicLocationData(NamedTuple): + region: str + er_region: str # entrance rando region + location_group: Optional[str] = None + + +location_base_id = 509342400 + +grass_location_table: Dict[str, TunicLocationData] = { + "Overworld - Overworld Grass (576) (7.0, 4.0, -223.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (572) (6.0, 4.0, -223.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (574) (7.0, 4.0, -224.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (568) (5.0, 4.0, -223.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (562) (4.0, 4.0, -223.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (570) (6.0, 4.0, -224.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (569) (5.0, 4.0, -225.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (566) (5.0, 4.0, -224.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (563) (4.0, 4.0, -224.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (564) (4.0, 4.0, -225.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (573) (6.0, 4.0, -225.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (577) (7.0, 4.0, -225.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (578) (3.0, 4.0, -223.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (575) (2.0, 4.0, -223.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (579) (3.0, 4.0, -224.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (571) (2.0, 4.0, -224.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (583) (-2.4, 4.0, -224.4)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (580) (-3.4, 4.0, -224.4)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (581) (-2.4, 4.0, -225.4)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (582) (-3.4, 4.0, -225.4)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (586) (-3.4, 4.0, -219.6)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (584) (-3.4, 4.0, -218.6)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (585) (-2.4, 4.0, -219.6)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (587) (-2.4, 4.0, -218.6)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (615) (13.0, 8.0, -217.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (616) (14.0, 8.0, -217.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (614) (13.0, 8.0, -216.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (613) (14.0, 8.0, -216.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (142) (13.0, 8.0, -224.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (141) (13.0, 8.0, -226.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (140) (13.0, 8.0, -228.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (591) (-8.0, 12.0, -212.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (590) (-8.0, 12.0, -212.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (589) (-9.0, 12.0, -212.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (588) (-9.0, 12.0, -213.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (592) (-8.0, 12.0, -213.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (606) (8.0, 12.0, -208.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (607) (8.0, 12.0, -209.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (608) (9.0, 12.0, -208.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (605) (9.0, 12.0, -209.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (600) (12.0, 12.0, -199.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (598) (12.0, 12.0, -200.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (599) (13.0, 12.0, -199.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (597) (13.0, 12.0, -200.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (602) (12.0, 12.0, -198.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (603) (13.0, 12.0, -197.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (601) (13.0, 12.0, -198.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (604) (12.0, 12.0, -197.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (593) (8.0, 12.0, -190.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (596) (9.0, 12.0, -190.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (594) (9.0, 12.0, -189.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (595) (8.0, 12.0, -189.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (612) (-8.0, 12.0, -188.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (609) (-8.0, 12.0, -189.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (610) (-9.0, 12.0, -188.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (611) (-9.0, 12.0, -189.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (895) (-6.0, 12.0, -134.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (894) (-6.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (891) (-6.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (892) (-7.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (889) (-7.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (893) (-7.0, 12.0, -134.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (899) (-7.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (905) (-8.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (890) (-6.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (906) (-9.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (907) (-10.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (908) (-10.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (898) (-15.0, 12.0, -134.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (897) (-15.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (909) (-14.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (887) (-15.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (900) (-16.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (888) (-16.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (896) (-16.0, 12.0, -134.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (901) (-17.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (886) (-16.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (904) (-17.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (902) (-18.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (903) (-18.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (334) (-20.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (322) (-20.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (320) (-20.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (321) (-21.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (332) (-21.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (323) (-21.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (337) (-22.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (336) (-22.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (339) (-23.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (338) (-23.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (335) (-20.0, 12.0, -134.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (333) (-21.0, 12.0, -134.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (349) (-21.0, 12.0, -141.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (344) (-22.0, 12.0, -142.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (346) (-23.0, 12.0, -142.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (345) (-22.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (347) (-23.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (340) (-20.0, 12.0, -142.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (343) (-21.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (342) (-21.0, 12.0, -142.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (356) (-21.0, 12.0, -144.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (353) (-19.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (351) (-20.0, 12.0, -141.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (358) (-20.0, 12.0, -144.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (341) (-20.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (348) (-21.0, 12.0, -140.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (354) (-18.0, 12.0, -142.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (352) (-19.0, 12.0, -142.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (350) (-20.0, 12.0, -140.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (359) (-20.0, 12.0, -145.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (357) (-21.0, 12.0, -145.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (355) (-18.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (131) (13.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (130) (13.0, 12.0, -141.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (129) (15.0, 12.0, -141.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (372) (14.5, 12.0, -139.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (128) (13.0, 12.0, -139.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (375) (14.5, 12.0, -138.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (373) (15.5, 12.0, -139.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (379) (16.5, 12.0, -138.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (376) (16.5, 12.0, -139.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (374) (15.5, 12.0, -138.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (369) (15.5, 12.0, -137.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (368) (14.5, 12.0, -137.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (366) (13.5, 12.0, -136.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (365) (13.5, 12.0, -137.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (371) (14.5, 12.0, -136.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (364) (12.5, 12.0, -137.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (367) (12.5, 12.0, -136.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (361) (13.5, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (127) (15.0, 12.0, -135.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (370) (15.5, 12.0, -136.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (362) (13.5, 12.0, -134.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (363) (12.5, 12.0, -134.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (360) (12.5, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (388) (16.5, 12.0, -137.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (389) (17.5, 12.0, -137.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (378) (17.5, 12.0, -138.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (377) (17.5, 12.0, -139.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (391) (16.5, 12.0, -136.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (392) (18.5, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (390) (17.5, 12.0, -136.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (385) (17.5, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (384) (16.5, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (386) (17.5, 12.0, -134.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (387) (16.5, 12.0, -134.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (382) (17.5, 12.0, -140.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (383) (16.5, 12.0, -140.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (381) (17.5, 12.0, -141.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (395) (18.5, 12.0, -134.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (394) (19.5, 12.0, -134.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (285) (19.5, 12.0, -132.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (279) (19.5, 12.0, -133.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (124) (18.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (393) (19.5, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (397) (20.5, 12.0, -134.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (282) (20.5, 12.0, -133.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (284) (20.5, 12.0, -132.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (289) (21.5, 12.0, -134.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (287) (21.5, 12.0, -133.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (281) (22.5, 12.0, -132.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (278) (22.5, 12.0, -133.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (286) (21.5, 12.0, -132.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (267) (21.5, 12.0, -131.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (126) (20.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (125) (18.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (283) (22.5, 12.0, -134.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (277) (23.5, 12.0, -132.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (276) (23.5, 12.0, -133.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (271) (22.5, 12.0, -131.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (269) (24.5, 12.0, -132.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (268) (24.5, 12.0, -133.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (266) (24.5, 12.0, -131.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (270) (24.5, 12.0, -130.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (275) (23.5, 12.0, -131.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (274) (23.5, 12.0, -130.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (272) (22.5, 12.0, -130.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (273) (21.5, 12.0, -130.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (396) (20.5, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (288) (21.5, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (280) (22.5, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (380) (16.5, 12.0, -141.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (262) (44.0, 12.0, -145.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (264) (45.0, 12.0, -144.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (263) (45.0, 12.0, -145.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (255) (39.5, 12.0, -151.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (256) (39.5, 12.0, -150.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (251) (39.5, 12.0, -152.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (254) (38.5, 12.0, -151.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (252) (38.5, 12.0, -152.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (257) (38.5, 12.0, -150.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (261) (40.5, 12.0, -152.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (258) (40.5, 12.0, -153.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (250) (39.5, 12.0, -153.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (260) (41.5, 12.0, -152.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (259) (41.5, 12.0, -153.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (253) (38.5, 12.0, -153.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (106) (47.0, 12.0, -147.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (31) (48.0, 12.0, -153.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (249) (50.5, 12.0, -153.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (245) (50.5, 12.0, -151.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (247) (50.5, 12.0, -152.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (242) (50.5, 12.0, -150.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (246) (51.5, 12.0, -152.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (244) (51.5, 12.0, -151.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (248) (51.5, 12.0, -153.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (17) (53.0, 12.0, -153.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (16) (53.0, 12.0, -151.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (243) (51.5, 12.0, -150.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (30) (51.0, 12.0, -149.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (32) (55.0, 12.0, -153.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (28) (55.0, 12.0, -149.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (13) (53.0, 12.0, -149.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (11) (53.0, 12.0, -147.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (27) (55.0, 12.0, -147.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (29) (51.0, 12.0, -147.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (33) (55.0, 12.0, -157.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (876) (68.0, 12.0, -156.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (878) (69.0, 12.0, -155.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (877) (69.0, 12.0, -154.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (879) (70.0, 12.0, -155.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (880) (70.0, 12.0, -154.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (873) (67.0, 12.0, -156.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (875) (68.0, 12.0, -157.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (874) (67.0, 12.0, -157.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (184) (69.5, 12.0, -157.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (183) (71.5, 12.0, -155.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (182) (71.5, 12.0, -157.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (871) (74.0, 12.0, -155.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (185) (73.5, 12.0, -157.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (870) (73.0, 12.0, -155.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (869) (73.0, 12.0, -154.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (872) (74.0, 12.0, -154.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (195) (65.5, 12.0, -157.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (950) (75.0, 12.0, -156.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (951) (75.0, 12.0, -157.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (953) (76.0, 12.0, -156.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (952) (76.0, 12.0, -157.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (194) (73.5, 12.0, -150.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (954) (76.5, 12.0, -150.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (189) (75.5, 12.0, -148.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (193) (73.5, 12.0, -148.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (955) (76.5, 12.0, -151.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (867) (78.5, 12.0, -151.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (866) (77.5, 12.0, -151.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (861) (79.5, 12.0, -150.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (862) (79.5, 12.0, -151.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (868) (78.5, 12.0, -150.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (865) (77.5, 12.0, -150.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (964) (78.5, 12.0, -156.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (965) (78.5, 12.0, -157.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (967) (79.5, 12.0, -156.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (966) (79.5, 12.0, -157.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (960) (80.5, 12.0, -156.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (962) (81.5, 12.0, -157.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (956) (80.5, 12.0, -158.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (961) (80.5, 12.0, -157.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (963) (81.5, 12.0, -156.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (957) (80.5, 12.0, -159.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (959) (81.5, 12.0, -158.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (958) (81.5, 12.0, -159.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (930) (84.5, 12.0, -158.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (933) (85.5, 12.0, -158.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (913) (86.5, 12.0, -155.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (40) (87.0, 12.0, -157.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (39) (87.0, 12.0, -159.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (41) (89.0, 12.0, -157.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (914) (87.5, 12.0, -155.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (48) (89.0, 12.0, -155.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (915) (87.5, 12.0, -154.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (912) (86.5, 12.0, -154.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (42) (91.0, 12.0, -157.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (47) (91.0, 12.0, -155.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (940) (89.5, 12.0, -153.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (938) (88.5, 12.0, -152.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (939) (88.5, 12.0, -153.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (941) (89.5, 12.0, -152.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (943) (88.5, 12.0, -151.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (944) (89.5, 12.0, -151.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (945) (89.5, 12.0, -150.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (942) (88.5, 12.0, -150.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (948) (89.5, 12.0, -149.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (949) (89.5, 12.0, -148.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (947) (88.5, 12.0, -149.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (946) (88.5, 12.0, -148.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (934) (94.5, 12.0, -154.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (85) (93.0, 12.0, -155.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (43) (93.0, 12.0, -157.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (935) (94.5, 12.0, -155.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (936) (95.5, 12.0, -155.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (84) (95.0, 12.0, -157.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (937) (95.5, 12.0, -154.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (932) (85.5, 12.0, -159.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (928) (85.5, 12.0, -161.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (929) (85.5, 12.0, -160.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (916) (84.5, 12.0, -160.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (931) (84.5, 12.0, -159.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (38) (87.0, 12.0, -161.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (310) (86.5, 12.0, -162.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (917) (84.5, 12.0, -161.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (313) (87.5, 12.0, -162.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (311) (86.5, 12.0, -163.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (312) (87.5, 12.0, -163.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (980) (86.5, 12.0, -170.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (981) (86.5, 12.0, -171.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (982) (87.5, 12.0, -171.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (983) (87.5, 12.0, -170.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (968) (86.5, 12.0, -174.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (969) (86.5, 12.0, -175.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (979) (85.5, 12.0, -174.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (971) (87.5, 12.0, -174.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (970) (87.5, 12.0, -175.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (975) (87.5, 12.0, -176.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (978) (85.5, 12.0, -175.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (976) (84.5, 12.0, -174.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (977) (84.5, 12.0, -175.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (972) (86.5, 12.0, -176.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (973) (86.5, 12.0, -177.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (974) (87.5, 12.0, -177.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (619) (-3.0, 20.0, -126.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (621) (-4.0, 20.0, -126.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (626) (-5.0, 20.0, -126.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (623) (-5.0, 20.0, -127.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (624) (-6.0, 20.0, -126.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (622) (-3.0, 20.0, -127.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (620) (-4.0, 20.0, -127.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (452) (-3.0, 20.0, -128.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (451) (-3.0, 20.0, -129.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (625) (-6.0, 20.0, -127.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (627) (-14.0, 20.0, -126.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (630) (-14.0, 20.0, -127.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (629) (-15.0, 20.0, -126.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (628) (-15.0, 20.0, -127.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (423) (-9.0, 20.0, -116.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (449) (-8.0, 20.0, -118.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (415) (-8.0, 20.0, -116.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (446) (-8.0, 20.0, -117.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (448) (-7.0, 20.0, -117.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (447) (-7.0, 20.0, -118.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (425) (-10.0, 20.0, -116.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (417) (-7.0, 20.0, -116.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (411) (-7.0, 20.0, -115.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (413) (-8.0, 20.0, -115.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (424) (-9.0, 20.0, -115.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (422) (-10.0, 20.0, -115.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (840) (14.0, 20.0, -117.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (844) (16.0, 20.0, -118.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (841) (16.0, 20.0, -117.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (838) (15.0, 20.0, -117.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (839) (15.0, 20.0, -116.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (837) (14.0, 20.0, -116.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (843) (17.0, 20.0, -117.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (833) (14.0, 20.0, -114.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (836) (14.0, 20.0, -115.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (834) (15.0, 20.0, -115.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (835) (15.0, 20.0, -114.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (831) (19.5, 20.0, -128.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (830) (19.5, 20.0, -129.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (829) (18.5, 20.0, -128.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (832) (18.5, 20.0, -129.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (821) (20.5, 20.0, -128.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (828) (20.5, 20.0, -127.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (822) (21.5, 20.0, -129.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (826) (21.5, 20.0, -127.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (823) (21.5, 20.0, -128.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (824) (20.5, 20.0, -129.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (825) (20.5, 20.0, -126.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (827) (21.5, 20.0, -126.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (536) (8.0, 28.0, -94.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (508) (9.0, 28.0, -94.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (534) (7.0, 28.0, -94.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (506) (10.0, 28.0, -94.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (509) (10.0, 28.0, -93.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (507) (9.0, 28.0, -93.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (535) (8.0, 28.0, -93.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (537) (7.0, 28.0, -93.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (500) (12.0, 28.0, -95.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (503) (12.0, 28.0, -96.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (504) (12.0, 28.0, -97.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (498) (13.0, 28.0, -95.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (505) (13.0, 28.0, -96.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (502) (13.0, 28.0, -97.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (499) (12.0, 28.0, -94.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (501) (13.0, 28.0, -94.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (517) (7.0, 28.0, -99.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (515) (8.0, 28.0, -99.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (514) (7.0, 28.0, -100.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (516) (8.0, 28.0, -100.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (484) (12.0, 28.0, -102.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (483) (12.0, 28.0, -103.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (491) (11.0, 28.0, -104.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (485) (13.0, 28.0, -102.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (489) (12.0, 28.0, -104.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (482) (13.0, 28.0, -103.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (486) (12.0, 28.0, -105.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (488) (13.0, 28.0, -105.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (487) (13.0, 28.0, -104.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (492) (11.0, 28.0, -105.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (493) (10.0, 28.0, -104.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (490) (10.0, 28.0, -105.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (513) (9.0, 28.0, -106.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (511) (10.0, 28.0, -106.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (512) (10.0, 28.0, -107.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (510) (9.0, 28.0, -107.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (495) (8.0, 28.0, -104.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (496) (8.0, 28.0, -105.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (497) (7.0, 28.0, -104.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (494) (7.0, 28.0, -105.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (520) (-4.0, 28.0, -94.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (521) (-5.0, 28.0, -93.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (525) (-5.0, 28.0, -95.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (518) (-5.0, 28.0, -94.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (519) (-4.0, 28.0, -93.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (523) (-6.0, 28.0, -95.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (631) (-7.0, 28.0, -95.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (522) (-5.0, 28.0, -96.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (524) (-6.0, 28.0, -96.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (632) (-7.0, 28.0, -96.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (533) (-7.0, 28.0, -97.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (633) (-8.0, 28.5, -95.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (634) (-8.0, 28.0, -96.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (531) (-8.0, 28.0, -97.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (532) (-8.0, 28.0, -98.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (530) (-7.0, 28.0, -98.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (769) (-8.5, 28.0, -105.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (772) (-8.5, 28.0, -104.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (770) (-9.5, 28.0, -104.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (771) (-9.5, 28.0, -105.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (758) (-7.5, 28.0, -107.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (760) (-6.5, 28.0, -107.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (754) (-5.5, 28.0, -107.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (757) (-6.5, 28.0, -108.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (755) (-5.5, 28.0, -108.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (764) (-6.5, 28.0, -109.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (753) (-4.5, 28.0, -108.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (756) (-4.5, 28.0, -107.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (765) (-2.5, 28.0, -107.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (168) (-3.0, 28.0, -109.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (767) (-3.5, 28.0, -107.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (766) (-3.5, 28.0, -106.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (768) (-2.5, 28.0, -106.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (169) (-5.0, 28.0, -111.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (166) (-3.0, 28.0, -111.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (167) (-5.0, 28.0, -113.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (116) (-3.0, 28.0, -113.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (761) (-6.5, 28.0, -110.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (762) (-7.5, 28.0, -109.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (759) (-7.5, 28.0, -108.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (763) (-7.5, 28.0, -110.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (151) (-21.0, 28.0, -109.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (170) (-21.0, 28.0, -111.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (171) (-19.0, 28.0, -113.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (149) (-23.0, 28.0, -107.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (24) (-25.0, 28.0, -109.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (138) (-25.0, 28.0, -111.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (148) (-25.0, 28.0, -113.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (172) (-23.0, 28.0, -113.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (25) (-25.0, 28.0, -107.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (150) (-21.0, 28.0, -107.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (26) (-19.0, 28.0, -107.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (23) (-19.0, 28.0, -105.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (9) (-19.0, 28.0, -103.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (471) (-16.0, 36.0, -87.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (472) (-16.0, 36.0, -86.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (470) (-17.0, 36.0, -86.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (473) (-17.0, 36.0, -87.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (468) (-17.0, 36.0, -88.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (466) (-16.0, 36.0, -88.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (474) (-15.0, 36.0, -88.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (467) (-17.0, 36.0, -89.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (469) (-16.0, 36.0, -89.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (477) (-15.0, 36.0, -89.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (475) (-14.0, 36.0, -89.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (476) (-14.0, 36.0, -88.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (459) (-4.0, 36.0, -75.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (460) (-4.0, 36.0, -74.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (458) (-3.0, 36.0, -74.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (461) (-3.0, 36.0, -75.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (457) (-4.0, 36.0, -73.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (455) (-3.0, 36.0, -73.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (456) (-3.0, 36.0, -72.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (454) (-4.0, 36.0, -72.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (463) (-9.0, 36.0, -70.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (465) (-8.0, 36.0, -70.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (462) (-8.0, 36.0, -69.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (464) (-9.0, 36.0, -69.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (567) (-7.0, 36.0, -68.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (617) (-7.0, 36.0, -67.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (618) (-6.0, 36.0, -68.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (565) (-6.0, 36.0, -67.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (792) (-14.5, 36.0, -63.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (789) (-14.5, 36.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (790) (-15.5, 36.0, -63.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (791) (-15.5, 36.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (180) (-13.0, 36.0, -61.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (776) (-12.5, 36.0, -59.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (779) (-11.5, 36.0, -60.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (778) (-11.5, 36.0, -61.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (777) (-10.5, 36.0, -60.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (780) (-10.5, 36.0, -61.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (774) (-13.5, 36.0, -59.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (178) (-11.0, 36.0, -59.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (773) (-12.5, 36.0, -58.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (775) (-13.5, 36.0, -58.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (785) (-14.5, 36.0, -58.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (788) (-14.5, 36.0, -59.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (786) (-15.5, 36.0, -59.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (179) (-13.0, 36.0, -57.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (177) (-11.0, 36.0, -57.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (174) (-13.0, 36.0, -55.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (784) (-14.5, 36.0, -57.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (781) (-14.5, 36.0, -56.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (176) (-15.0, 36.0, -55.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (783) (-15.5, 36.0, -56.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (782) (-15.5, 36.0, -57.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (787) (-15.5, 36.0, -58.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (173) (-11.0, 36.0, -55.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (181) (-17.0, 36.0, -58.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (800) (-16.5, 36.0, -53.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (175) (-15.0, 36.0, -53.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (797) (-16.5, 36.0, -52.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (136) (-15.0, 36.0, -51.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (796) (-16.5, 36.0, -51.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (793) (-16.5, 36.0, -50.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (794) (-17.5, 36.0, -51.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (799) (-17.5, 36.0, -52.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (798) (-17.5, 36.0, -53.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (135) (-15.0, 36.0, -49.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (134) (-17.0, 36.0, -49.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (795) (-17.5, 36.0, -50.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (132) (-15.0, 36.0, -47.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (133) (-17.0, 36.0, -47.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (437) (11.0, 36.0, -72.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (434) (11.0, 36.0, -71.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (435) (10.0, 36.0, -72.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (433) (10.0, 36.0, -70.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (436) (10.0, 36.0, -71.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (432) (11.0, 36.0, -70.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (441) (9.0, 36.0, -72.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (438) (9.0, 36.0, -71.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (440) (8.0, 36.0, -71.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (439) (8.0, 36.0, -72.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (445) (8.0, 36.0, -74.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (442) (8.0, 36.0, -73.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (430) (10.0, 36.0, -69.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (431) (11.0, 36.0, -69.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (444) (7.0, 36.0, -73.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (443) (7.0, 36.0, -74.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (652) (28.0, 36.0, -110.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (647) (27.0, 36.0, -112.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (648) (26.0, 36.0, -112.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (654) (28.0, 36.0, -111.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (646) (28.0, 36.0, -112.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (645) (28.0, 36.0, -113.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (649) (27.0, 36.0, -113.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (653) (29.0, 36.0, -111.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (643) (29.0, 36.0, -113.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (644) (29.0, 36.0, -112.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (651) (29.0, 36.0, -110.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (650) (26.0, 36.0, -113.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (845) (-4.5, 44.0, -68.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (847) (-3.5, 44.0, -68.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (846) (-4.5, 44.0, -69.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (848) (-3.5, 44.0, -69.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (850) (9.5, 44.0, -65.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (856) (7.5, 44.0, -66.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (853) (8.5, 44.0, -65.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (854) (8.5, 44.0, -66.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (859) (7.5, 44.0, -67.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (860) (7.5, 44.0, -68.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (857) (8.5, 44.0, -67.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (858) (8.5, 44.0, -68.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (849) (9.5, 44.0, -64.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (851) (10.5, 44.0, -64.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (852) (10.5, 44.0, -65.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (855) (7.5, 44.0, -65.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (410) (-6.0, 44.0, -64.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (416) (-6.0, 44.0, -65.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (421) (-4.0, 44.0, -63.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (407) (-6.0, 44.0, -63.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (420) (-5.0, 44.0, -63.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (403) (-6.0, 44.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (409) (-7.0, 44.0, -63.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (418) (-5.0, 44.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (412) (-7.0, 44.0, -64.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (405) (-7.0, 44.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (400) (-7.0, 44.0, -61.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (414) (-7.0, 44.0, -65.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (402) (-8.0, 44.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (399) (-8.0, 44.0, -61.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (406) (-8.0, 44.0, -63.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (401) (-6.0, 44.0, -61.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (404) (-9.0, 44.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (408) (-9.0, 44.0, -63.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (426) (-8.0, 44.0, -60.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (398) (-9.0, 44.0, -61.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (429) (-8.0, 44.0, -59.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (428) (-9.0, 44.0, -59.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (427) (-9.0, 44.0, -60.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (667) (-6.0, 44.0, -50.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (669) (-5.0, 44.0, -50.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (668) (-5.0, 44.0, -51.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (670) (-6.0, 44.0, -51.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (665) (-6.0, 44.0, -48.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (666) (-5.0, 44.0, -48.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (664) (-6.0, 44.0, -47.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (663) (-5.0, 44.0, -47.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (672) (8.0, 44.0, -48.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (674) (7.0, 44.0, -48.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (671) (7.0, 44.0, -47.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (677) (6.0, 44.0, -48.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (676) (6.0, 44.0, -49.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (675) (5.0, 44.0, -48.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (678) (5.0, 44.0, -49.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (673) (8.0, 44.0, -47.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (5) (12.0, 44.0, -6.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (4) (13.0, 44.0, -6.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (3) (12.0, 44.0, -5.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1) (13.0, 44.0, -5.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (6) (11.0, 44.0, -5.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (13.0, 44.0, -4.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (2) (12.0, 44.0, -4.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (7) (11.0, 44.0, -4.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (30) (10.0, 44.0, -4.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1137) (8.0, 46.0, -2.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1135) (9.0, 46.0, -2.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1138) (9.0, 46.0, -3.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1136) (8.0, 46.0, -1.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1134) (9.0, 46.0, -1.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1139) (-4.0, 46.0, -1.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1141) (-4.0, 46.0, -2.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1142) (-5.0, 46.0, -2.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1140) (-5.0, 46.0, -1.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (26) (-6.5, 44.0, -5.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (27) (-6.5, 44.0, -4.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (24) (-7.5, 44.0, -5.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (25) (-7.5, 44.0, -4.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (28) (-8.5, 44.0, -6.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (22) (-8.5, 44.0, -5.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (21) (-8.5, 44.0, -4.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (29) (-9.5, 44.0, -6.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (18) (-8.5, 44.0, -10.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (11) (-8.5, 44.0, -12.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (13) (-8.5, 44.0, -11.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (19) (-9.5, 44.0, -10.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (12) (-9.5, 44.0, -11.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (15) (-7.5, 44.0, -12.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (9) (-9.5, 44.0, -12.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (8) (-9.5, 44.0, -13.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (10) (-8.5, 44.0, -13.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (16) (-6.5, 44.0, -12.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (17) (-6.5, 44.0, -13.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (14) (-7.5, 44.0, -13.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (698) (-32.0, 38.0, -49.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (699) (-31.0, 38.0, -49.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (697) (-32.0, 38.0, -50.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (700) (-31.0, 38.0, -50.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (696) (-32.5, 38.0, -46.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (693) (-33.5, 38.5, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (695) (-33.5, 38.0, -46.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (694) (-33.5, 38.5, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (691) (-34.5, 38.0, -46.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (692) (-34.5, 38.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (560) (-32.0, 40.0, -33.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (554) (-31.0, 40.0, -34.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (553) (-31.0, 40.0, -33.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (555) (-30.0, 40.0, -34.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (557) (-31.0, 40.0, -35.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (550) (-31.0, 40.0, -32.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (552) (-30.0, 40.0, -33.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (551) (-30.0, 40.0, -32.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (559) (-32.0, 40.0, -32.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (558) (-33.0, 40.0, -32.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (561) (-33.0, 40.0, -33.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (139) (-31.0, 40.0, -28.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (145) (-33.0, 40.0, -30.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (143) (-33.0, 40.0, -28.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (556) (-30.0, 40.0, -35.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (137) (-39.0, 40.0, -28.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (93) (-41.0, 40.0, -28.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (94) (-39.0, 40.0, -33.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (479) (-38.5, 40.0, -34.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (480) (-38.5, 40.0, -35.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (478) (-39.5, 40.0, -34.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (190) (-37.0, 40.0, -33.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (481) (-39.5, 40.0, -35.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (-41.0, 40.0, -37.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (6) (-39.0, 40.0, -37.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (1) (-41.0, 40.0, -39.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (4) (-39.0, 40.0, -39.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (2) (-41.0, 40.0, -41.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (7) (-39.0, 40.0, -41.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (128) (-39.5, 40.0, -43.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (130) (-39.5, 40.0, -42.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (5) (-41.0, 40.0, -43.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (545) (-37.5, 40.0, -41.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (538) (-37.5, 40.0, -42.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (131) (-38.5, 40.0, -43.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (126) (-38.5, 40.0, -42.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (544) (-36.5, 40.0, -41.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (542) (-37.5, 40.0, -40.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (543) (-36.5, 40.0, -40.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (541) (-37.5, 40.0, -43.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (540) (-36.5, 40.0, -43.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (539) (-36.5, 40.0, -42.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (546) (-35.5, 40.0, -42.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (548) (-34.5, 40.0, -43.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (549) (-35.5, 40.0, -43.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (547) (-34.5, 40.0, -42.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (191) (-38.0, 40.0, -45.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (689) (-40.0, 40.0, -44.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (687) (-41.0, 40.0, -44.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (690) (-40.0, 40.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (688) (-41.0, 40.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (117) (-42.5, 40.0, -41.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (114) (-42.5, 40.0, -40.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (98) (-43.0, 40.0, -39.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (116) (-43.5, 40.0, -40.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (115) (-43.5, 40.0, -41.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (121) (-44.5, 40.0, -41.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (113) (-44.5, 40.0, -39.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (118) (-44.5, 40.0, -40.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (192) (-43.0, 40.0, -43.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (110) (-44.5, 40.0, -38.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (95) (-43.0, 40.0, -37.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (96) (-45.0, 40.0, -37.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (112) (-45.5, 40.0, -38.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (111) (-45.5, 40.0, -39.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (124) (-46.5, 40.0, -38.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (97) (-47.0, 40.0, -37.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (122) (-47.5, 40.0, -38.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (123) (-46.5, 40.0, -39.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (125) (-47.5, 40.0, -39.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (134) (-46.5, 40.0, -40.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (120) (-45.5, 40.0, -40.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (119) (-45.5, 40.0, -41.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (108) (-48.5, 40.0, -37.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (109) (-49.5, 40.0, -37.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (136) (-47.5, 40.0, -40.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (135) (-47.5, 40.0, -41.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (137) (-46.5, 40.0, -41.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (196) (-47.3, 40.0, -43.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (133) (-49.0, 40.0, -44.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (686) (-50.0, 40.0, -43.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (685) (-51.0, 40.0, -42.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (684) (-52.0, 40.0, -42.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (683) (-52.0, 40.0, -43.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (682) (-51.0, 40.0, -43.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (680) (-52.0, 40.0, -44.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (127) (-50.0, 40.0, -44.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (129) (-51.0, 40.0, -44.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (450) (-51.0, 40.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (681) (-52.0, 40.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (453) (-50.0, 40.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (679) (-49.0, 40.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (115) (-53.5, 40.0, -43.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (8) (-51.0, 40.0, -39.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (99) (-51.0, 40.0, -37.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (106) (-49.5, 40.0, -36.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (3) (-53.0, 40.0, -37.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (107) (-48.5, 40.0, -36.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (138) (-71.5, 40.0, -38.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (141) (-71.5, 40.0, -39.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (140) (-72.5, 40.0, -38.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (139) (-72.5, 40.0, -39.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (102) (-72.0, 40.0, -41.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (105) (-72.0, 40.0, -43.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (104) (-74.0, 40.0, -41.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (101) (-74.0, 40.0, -39.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (153) (-76.5, 40.0, -41.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (145) (-75.5, 40.0, -39.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (152) (-75.5, 40.0, -40.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (151) (-75.5, 40.0, -41.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (143) (-76.5, 40.0, -39.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (150) (-76.5, 40.0, -40.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (103) (-74.0, 40.0, -43.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (144) (-76.5, 40.0, -38.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (142) (-75.5, 40.0, -38.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (100) (-76.0, 40.0, -37.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (147) (-77.5, 40.0, -37.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (148) (-77.5, 40.0, -36.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (149) (-78.5, 40.0, -37.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (146) (-78.5, 40.0, -36.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (156) (-82.5, 40.0, -36.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (155) (-82.5, 40.0, -37.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (154) (-83.5, 40.0, -36.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (157) (-83.5, 40.0, -37.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (907) (-48.5, 43.0, 20.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (908) (-48.5, 43.0, 21.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (905) (-49.5, 43.0, 21.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (906) (-49.5, 43.0, 20.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (911) (-53.8, 43.0, 20.3)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (909) (-53.8, 43.0, 21.3)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (910) (-54.8, 43.0, 21.3)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (819) (-52.0, 28.0, -52.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (817) (-51.0, 28.0, -52.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (818) (-52.0, 28.0, -53.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (820) (-51.0, 28.0, -53.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (813) (-46.5, 28.0, -61.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (816) (-46.5, 28.0, -62.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (814) (-47.5, 28.0, -62.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (815) (-47.5, 28.0, -61.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (807) (-44.0, 28.0, -62.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (803) (-45.0, 28.0, -64.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (806) (-44.0, 28.0, -63.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (801) (-44.0, 28.0, -64.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (805) (-43.0, 28.0, -62.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (808) (-43.0, 28.0, -63.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (811) (-42.0, 28.0, -63.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (809) (-41.0, 28.0, -63.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (810) (-42.0, 28.0, -64.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (812) (-41.0, 28.0, -64.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (804) (-44.0, 28.0, -65.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (802) (-45.0, 28.0, -65.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (529) (-35.0, 28.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (527) (-34.0, 28.0, -61.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (528) (-34.0, 28.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (526) (-35.0, 28.0, -61.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (641) (-32.0, 28.0, -65.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (642) (-32.0, 28.0, -66.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (640) (-31.0, 28.0, -65.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (636) (-30.0, 28.0, -65.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (639) (-31.0, 28.0, -66.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (637) (-29.0, 28.0, -66.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (635) (-29.0, 28.0, -65.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (638) (-30.0, 28.0, -66.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (744) (-32.5, 28.0, -85.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (741) (-32.5, 28.0, -86.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (158) (-32.0, 28.0, -84.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (742) (-31.5, 28.0, -85.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (743) (-31.5, 28.0, -86.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (748) (-29.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (745) (-30.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (746) (-30.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (163) (-30.0, 28.0, -88.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (162) (-30.0, 28.0, -86.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (747) (-29.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (750) (-30.5, 28.0, -90.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (749) (-30.5, 28.0, -89.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (751) (-29.5, 28.0, -89.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (752) (-29.5, 28.0, -90.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (165) (-57.5, 28.0, -64.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (162) (-57.5, 28.0, -63.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (164) (-58.5, 28.0, -63.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (163) (-58.5, 28.0, -64.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (176) (-59.5, 28.0, -65.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (173) (-59.5, 28.0, -64.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (170) (-59.5, 28.0, -63.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (159) (-59.5, 28.0, -62.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (172) (-60.5, 28.0, -63.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (174) (-60.5, 28.0, -65.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (171) (-60.5, 28.0, -64.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (175) (-59.5, 28.0, -66.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (177) (-60.5, 28.0, -66.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (112) (-56.0, 28.0, -64.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (110) (-58.0, 28.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (111) (-56.0, 28.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (160) (-59.5, 28.0, -61.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (169) (-59.5, 28.0, -60.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (108) (-58.0, 28.0, -60.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (158) (-60.5, 28.0, -61.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (161) (-60.5, 28.0, -62.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (109) (-56.0, 28.0, -60.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (107) (-58.0, 28.0, -58.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (166) (-59.5, 28.0, -59.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (168) (-60.5, 28.0, -59.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (167) (-60.5, 28.0, -60.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (180) (-61.5, 28.0, -61.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (178) (-62.5, 28.0, -61.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (179) (-61.5, 28.0, -62.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (181) (-62.5, 28.0, -62.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (713) (-62.5, 28.0, -74.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (714) (-62.5, 28.0, -75.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (715) (-63.5, 28.0, -74.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (716) (-63.5, 28.0, -75.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (711) (-66.0, 28.0, -76.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (710) (-66.0, 28.0, -77.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (712) (-67.0, 28.0, -76.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (709) (-67.0, 28.0, -77.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (160) (-61.5, 28.0, -81.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (157) (-59.5, 28.0, -81.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (156) (-59.5, 28.0, -79.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (154) (-57.5, 28.0, -79.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (159) (-61.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (155) (-59.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (152) (-57.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (153) (-57.5, 28.0, -81.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (727) (-63.0, 28.0, -83.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (725) (-64.0, 28.0, -83.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (728) (-64.0, 28.0, -84.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (726) (-63.0, 28.0, -84.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (722) (-63.0, 28.0, -86.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (723) (-63.0, 28.0, -85.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (721) (-64.0, 28.0, -85.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (717) (-62.0, 28.0, -85.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (720) (-62.0, 28.0, -86.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (719) (-61.0, 28.0, -85.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (724) (-64.0, 28.0, -86.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (718) (-61.0, 28.0, -86.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (234) (-69.5, 28.0, -96.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (236) (-68.5, 28.0, -96.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (237) (-69.5, 28.0, -97.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (230) (-69.5, 28.0, -98.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (240) (-67.5, 28.0, -98.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (232) (-68.5, 28.0, -98.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (235) (-68.5, 28.0, -97.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (233) (-69.5, 28.0, -99.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (231) (-68.5, 28.0, -99.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (239) (-67.5, 28.0, -99.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (241) (-66.5, 28.0, -99.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (238) (-66.5, 28.0, -98.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (739) (-71.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (737) (-72.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (734) (-73.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (735) (-73.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (733) (-74.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (736) (-74.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (740) (-72.5, 28.0, -85.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (738) (-71.5, 28.0, -85.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (731) (-74.5, 28.0, -85.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (729) (-75.5, 28.0, -85.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (732) (-75.5, 28.0, -86.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (730) (-74.5, 28.0, -86.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (227) (-83.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (229) (-84.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (228) (-83.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (226) (-84.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (222) (-85.5, 28.0, -85.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (119) (-86.0, 28.0, -82.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (122) (-86.0, 28.0, -84.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (224) (-86.5, 28.0, -85.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (211) (-87.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (208) (-87.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (210) (-88.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (209) (-88.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (223) (-86.5, 28.0, -86.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (161) (-88.0, 28.0, -86.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (225) (-85.5, 28.0, -86.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (217) (-89.5, 28.0, -86.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (186) (-88.0, 28.0, -88.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (165) (-88.0, 28.0, -88.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (164) (-86.0, 28.0, -88.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (203) (-89.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (218) (-89.5, 28.0, -85.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (214) (-89.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (216) (-90.5, 28.0, -85.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (215) (-90.5, 28.0, -84.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (202) (-90.5, 28.0, -83.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (219) (-90.5, 28.0, -86.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (207) (-89.5, 28.0, -82.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (198) (-89.5, 28.0, -81.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (123) (-88.0, 28.0, -82.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (213) (-89.5, 28.0, -80.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (199) (-90.5, 28.0, -82.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (121) (-88.0, 28.0, -80.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (200) (-89.5, 28.0, -79.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (212) (-90.5, 28.0, -79.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (201) (-90.5, 28.0, -80.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (206) (-90.5, 28.0, -81.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (220) (-91.5, 28.0, -81.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (205) (-91.5, 28.0, -82.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (221) (-92.5, 28.0, -82.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (204) (-92.5, 28.0, -81.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (120) (-86.0, 28.0, -80.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (118) (-88.0, 28.0, -78.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (703) (-78.0, 28.0, -75.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (704) (-78.0, 28.0, -76.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (705) (-77.0, 28.0, -74.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (702) (-77.0, 28.0, -75.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (701) (-77.0, 28.0, -76.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (706) (-76.0, 28.0, -74.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (708) (-77.0, 28.0, -73.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (707) (-76.0, 28.0, -73.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (117) (-57.0, 28.0, -47.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (114) (-55.0, 28.0, -45.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Bush (113) (-57.0, 28.0, -45.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (183) (-58.5, 28.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (184) (-58.5, 28.0, -44.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (185) (-59.5, 28.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (197) (-60.5, 28.0, -46.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (196) (-61.5, 28.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (195) (-61.5, 28.0, -46.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (194) (-60.5, 28.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (190) (-62.5, 28.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (193) (-62.5, 28.0, -46.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (191) (-63.5, 28.0, -46.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (182) (-59.5, 28.0, -44.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (192) (-63.5, 28.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (189) (-64.5, 28.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (186) (-64.5, 28.0, -44.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (187) (-65.5, 28.0, -45.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (188) (-65.5, 28.0, -44.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (-132.0, 28.0, -52.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (3) (-132.0, 28.0, -53.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1) (-133.0, 28.0, -52.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (2) (-131.0, 28.0, -52.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (5) (-120.5, 28.0, -52.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (4) (-119.5, 28.0, -52.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (7) (-119.5, 28.0, -51.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (8) (-117.5, 28.0, -55.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (6) (-116.5, 28.0, -55.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (9) (-116.5, 28.0, -54.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1083) (-86.5, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1082) (-85.5, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1084) (-85.5, 12.0, -130.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1085) (-86.5, 12.0, -130.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1087) (-87.5, 12.0, -130.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1089) (-88.5, 12.0, -130.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1086) (-87.5, 12.0, -129.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1088) (-88.5, 12.0, -129.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1080) (-89.0, 12.0, -143.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1081) (-90.0, 12.0, -143.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1078) (-89.0, 12.0, -144.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1075) (-88.0, 12.0, -144.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1079) (-90.0, 12.0, -144.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1074) (-87.0, 12.0, -144.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1077) (-88.0, 12.0, -145.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1076) (-87.0, 12.0, -145.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1070) (-78.0, 12.0, -142.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1072) (-77.0, 12.0, -143.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1071) (-77.0, 12.0, -142.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1073) (-78.0, 12.0, -143.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (294) (-64.0, 12.0, -144.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (292) (-64.0, 12.0, -145.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (290) (-64.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (74) (-65.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (293) (-63.0, 12.0, -144.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (132) (-63.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (291) (-63.0, 12.0, -145.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (77) (-64.0, 12.0, -142.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (76) (-63.0, 12.0, -142.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (73) (-65.0, 12.0, -142.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (75) (-66.0, 12.0, -143.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (70) (-66.0, 12.0, -142.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1093) (-55.0, 12.0, -136.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1092) (-54.0, 12.0, -136.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1090) (-55.0, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1091) (-54.0, 12.0, -135.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1056) (-68.0, 12.0, -134.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1054) (-69.0, 12.0, -134.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1050) (-67.0, 12.0, -134.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1057) (-68.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1052) (-66.0, 12.0, -134.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1053) (-66.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1051) (-67.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1060) (-68.0, 12.5, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1055) (-69.0, 12.0, -133.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1058) (-69.0, 12.5, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1062) (-70.0, 12.5, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1061) (-68.0, 12.5, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1059) (-69.0, 12.5, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1063) (-70.0, 12.5, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1065) (-71.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1064) (-71.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1047) (-72.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1068) (-72.0, 13.0, -129.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1067) (-72.0, 12.5, -130.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1048) (-72.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1066) (-73.0, 12.5, -130.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1069) (-73.0, 12.5, -129.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1046) (-73.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1044) (-74.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1043) (-74.0, 12.0, -130.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1049) (-73.0, 12.0, -132.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1045) (-75.0, 12.0, -131.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (1042) (-75.0, 12.0, -130.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (842) (17.0, 20.0, -118.5)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Grass (419) (-4.0, 44.0, -62.0)": TunicLocationData("Overworld", "Overworld"), + "Overworld - Overworld Swamp Lower Entry Grass (1103) (80.5, 2.7, -175.6)": TunicLocationData( + "Overworld Swamp Lower Entry", "Overworld Swamp Lower Entry"), + "Overworld - Overworld Swamp Lower Entry Grass (1102) (80.5, 2.7, -174.6)": TunicLocationData( + "Overworld Swamp Lower Entry", "Overworld Swamp Lower Entry"), + "Overworld - Overworld Swamp Lower Entry Grass (1100) (79.5, 2.1, -174.6)": TunicLocationData( + "Overworld Swamp Lower Entry", "Overworld Swamp Lower Entry"), + "Overworld - Overworld Swamp Lower Entry Grass (1101) (79.5, 2.1, -175.6)": TunicLocationData( + "Overworld Swamp Lower Entry", "Overworld Swamp Lower Entry"), + "Overworld - Overworld Swamp Lower Entry Grass (1096) (78.4, 2.2, -171.6)": TunicLocationData( + "Overworld Swamp Lower Entry", "Overworld Swamp Lower Entry"), + "Overworld - Overworld Swamp Lower Entry Grass (1097) (77.5, 2.0, -171.6)": TunicLocationData( + "Overworld Swamp Lower Entry", "Overworld Swamp Lower Entry"), + "Overworld - Overworld Swamp Lower Entry Grass (1099) (77.4, 2.2, -170.6)": TunicLocationData( + "Overworld Swamp Lower Entry", "Overworld Swamp Lower Entry"), + "Overworld - Overworld Swamp Lower Entry Grass (1098) (78.5, 2.6, -170.6)": TunicLocationData( + "Overworld Swamp Lower Entry", "Overworld Swamp Lower Entry"), + "Overworld - After Ruined Passage Grass (327) (53.0, 20.0, -144.0)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (296) (52.0, 20.0, -144.0)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (297) (51.0, 20.0, -144.0)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (326) (54.0, 20.0, -144.0)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (295) (52.0, 20.0, -145.0)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (265) (51.0, 20.0, -145.0)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (325) (53.0, 20.0, -145.0)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (298) (54.0, 20.0, -145.0)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (661) (47.5, 20.0, -142.5)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (328) (47.5, 20.0, -141.5)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (662) (46.5, 20.0, -142.5)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - After Ruined Passage Grass (660) (46.5, 20.0, -141.5)": TunicLocationData("After Ruined Passage", + "After Ruined Passage"), + "Overworld - Above Ruined Passage Grass (31) (66.0, 28.0, -120.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (29) (67.0, 28.0, -120.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (28) (67.0, 28.0, -119.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (26) (67.0, 28.0, -118.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (30) (66.0, 28.0, -119.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (21) (67.0, 28.0, -116.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (27) (67.0, 28.0, -117.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (25) (66.0, 28.0, -117.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (24) (66.0, 28.0, -118.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (20) (67.0, 28.0, -115.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (23) (66.0, 28.0, -116.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (22) (66.0, 28.0, -115.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (12) (56.0, 28.0, -126.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (10) (56.0, 28.0, -128.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (13) (56.0, 28.0, -127.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (14) (55.0, 28.0, -126.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (15) (55.0, 28.0, -127.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (5) (55.0, 28.0, -128.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (11) (57.0, 28.0, -128.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (9) (57.0, 28.0, -129.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (8) (56.0, 28.0, -129.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (18) (54.0, 28.0, -127.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (4) (54.0, 28.0, -128.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (6) (54.0, 28.0, -129.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (17) (53.0, 28.0, -126.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (16) (53.0, 28.0, -127.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (3) (53.0, 28.0, -128.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (2) (53.0, 28.0, -129.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (1) (52.0, 28.0, -128.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (52.0, 28.0, -129.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (7) (55.0, 28.0, -129.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - Above Ruined Passage Grass (19) (54.0, 28.0, -126.0)": TunicLocationData("Above Ruined Passage", + "Above Ruined Passage"), + "Overworld - East Overworld Grass (1118) (98.5, 36.0, -136.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1119) (98.5, 36.0, -137.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1116) (99.5, 36.0, -136.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1115) (98.5, 36.0, -139.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1114) (98.5, 36.0, -138.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1112) (99.5, 36.0, -138.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1117) (99.5, 36.0, -137.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1113) (99.5, 36.0, -139.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1109) (95.0, 36.0, -127.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1104) (95.0, 36.0, -128.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1108) (95.0, 36.0, -126.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1111) (94.0, 36.0, -127.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1110) (94.0, 36.0, -126.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1106) (94.0, 36.0, -128.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1107) (94.0, 36.0, -129.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1105) (95.0, 36.0, -129.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (331) (86.0, 36.0, -128.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (329) (85.0, 36.0, -128.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (655) (85.0, 36.0, -129.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (657) (84.0, 36.0, -129.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (658) (84.0, 36.0, -128.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (330) (86.0, 36.0, -129.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (656) (83.0, 36.0, -128.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (659) (83.0, 36.0, -129.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1120) (86.0, 36.0, -123.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1124) (86.0, 36.0, -122.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1126) (83.0, 36.0, -120.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1127) (82.0, 36.0, -120.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (309) (81.5, 36.0, -118.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (308) (81.5, 36.0, -119.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (307) (80.5, 36.0, -118.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (324) (80.5, 36.0, -119.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (305) (79.5, 36.0, -118.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (304) (79.5, 36.0, -119.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (300) (79.5, 36.0, -121.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (301) (79.5, 36.0, -120.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1128) (82.0, 36.0, -121.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (303) (78.5, 36.0, -118.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (306) (78.5, 36.0, -119.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (299) (78.5, 36.0, -120.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1122) (77.5, 36.0, -120.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1123) (77.5, 36.0, -121.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1121) (76.5, 36.0, -121.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (302) (78.5, 36.0, -121.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Bush (18) (82.5, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (20) (82.5, 44.0, -111.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (92) (84.5, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (19) (82.5, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (78) (79.0, 44.0, -112.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (83) (80.0, 44.0, -112.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (85) (80.0, 44.0, -113.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (84) (81.0, 44.0, -112.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (80) (79.0, 44.0, -113.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (87) (82.0, 44.0, -112.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (82) (81.0, 44.0, -113.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (86) (83.0, 44.0, -113.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (89) (82.0, 44.0, -113.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (88) (83.0, 44.0, -112.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (81) (78.0, 44.0, -112.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (52) (76.0, 44.0, -113.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (50) (76.0, 44.0, -112.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (53) (75.0, 44.0, -112.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (79) (78.0, 44.0, -113.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (51) (75.0, 44.0, -113.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (57) (78.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (21) (80.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (56) (76.5, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (54) (76.5, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (55) (75.5, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (57) (75.5, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (103) (90.0, 44.0, -113.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (105) (90.0, 44.0, -112.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (102) (91.0, 44.0, -112.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (104) (91.0, 44.0, -113.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Bush (44) (93.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (45) (95.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (1150) (94.5, 44.0, -111.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1149) (95.5, 44.0, -111.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1151) (94.5, 44.0, -110.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Bush (50) (97.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (56) (97.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (1148) (95.5, 44.0, -110.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (96) (94.5, 44.0, -109.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (95) (93.5, 44.0, -109.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (101) (95.5, 44.0, -109.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (94) (94.5, 44.0, -108.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (97) (93.5, 44.0, -108.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (99) (95.5, 44.0, -108.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (46) (95.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (22) (93.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (90) (91.5, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (55) (97.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (49) (97.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (92) (91.5, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (91) (90.5, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (93) (90.5, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (46) (71.0, 44.0, -110.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (15) (72.5, 44.0, -111.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (48) (71.0, 44.0, -111.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (61) (70.5, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (10) (70.5, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (49) (70.0, 44.0, -110.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (62) (69.0, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (63) (68.5, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (65) (68.0, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (58) (67.0, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (45) (68.0, 44.0, -111.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (43) (68.0, 44.0, -110.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (44) (69.0, 44.0, -110.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (42) (69.0, 44.0, -111.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (47) (70.0, 44.0, -111.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (64) (69.0, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (63) (68.0, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (60) (67.0, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (59) (66.0, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (61) (66.0, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (60) (66.5, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (83) (64.5, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (62) (66.5, 44.0, -111.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (80) (66.5, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (58) (58.0, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (30) (56.5, 44.0, -109.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (59) (58.0, 44.0, -111.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (34) (56.5, 44.0, -110.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (36) (56.5, 44.0, -111.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (14) (58.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (32) (56.5, 44.0, -108.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (64) (56.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (37) (55.5, 44.0, -110.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (31) (55.5, 44.0, -108.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (33) (55.5, 44.0, -109.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (35) (55.5, 44.0, -111.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (38) (54.5, 44.0, -110.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (40) (54.5, 44.0, -111.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (41) (53.5, 44.0, -110.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (81) (54.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (39) (53.5, 44.0, -111.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (26) (52.5, 44.0, -111.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (65) (54.0, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (28) (52.5, 44.0, -110.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (16) (52.5, 44.0, -108.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (14) (52.5, 44.0, -109.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (17) (51.5, 44.0, -109.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (27) (51.5, 44.0, -110.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (29) (51.5, 44.0, -111.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (12) (58.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (66) (54.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (11) (52.5, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (12) (51.5, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (15) (51.5, 44.0, -108.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (24) (50.5, 44.0, -108.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (18) (50.5, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (22) (50.5, 44.0, -109.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (25) (49.5, 44.0, -109.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (21) (49.5, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (23) (49.5, 44.0, -108.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (13) (51.5, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (10) (52.5, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (20) (50.5, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (19) (49.5, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (69) (48.0, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (68) (48.0, 44.0, -111.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (67) (48.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (72) (46.0, 44.0, -111.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (70) (46.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (71) (46.0, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (76) (44.0, 44.0, -111.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (73) (44.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (66) (46.5, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (69) (45.5, 44.0, -107.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (67) (45.5, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (82) (44.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (68) (46.5, 44.0, -106.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (79) (42.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (78) (42.0, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (74) (40.0, 44.0, -109.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (77) (42.0, 44.0, -111.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (75) (42.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (88) (40.0, 44.0, -107.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (1006) (33.5, 44.0, -109.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1008) (33.5, 44.0, -108.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Bush (89) (33.0, 44.0, -111.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (72) (34.5, 44.0, -112.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Bush (90) (33.0, 44.0, -113.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (984) (35.5, 44.0, -112.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (985) (34.5, 44.0, -113.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (71) (35.5, 44.0, -113.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (1009) (32.5, 44.0, -109.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1007) (32.5, 44.0, -108.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (986) (31.5, 44.0, -109.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Bush (91) (31.0, 44.0, -111.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (989) (30.5, 44.0, -109.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (987) (30.5, 44.0, -108.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (988) (31.5, 44.0, -108.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1000) (31.5, 44.0, -106.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (998) (31.5, 44.0, -107.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1001) (30.5, 44.0, -107.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (999) (30.5, 44.0, -106.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1005) (30.5, 44.0, -105.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1002) (31.5, 44.0, -105.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1004) (31.5, 44.0, -104.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1003) (30.5, 44.0, -104.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (993) (36.5, 44.0, -105.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (990) (37.5, 44.0, -105.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (991) (36.5, 44.0, -104.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (992) (37.5, 44.0, -104.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (994) (37.5, 44.0, -103.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (996) (37.5, 44.0, -102.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (997) (36.5, 44.0, -103.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (995) (36.5, 44.0, -102.5)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (881) (27.8, 44.0, -74.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (864) (28.8, 44.0, -75.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (863) (28.8, 44.0, -74.0)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (1012) (23.5, 44.0, -98.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1011) (22.5, 44.0, -98.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1013) (22.5, 44.0, -99.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (1010) (23.5, 44.0, -99.0)": TunicLocationData("East Overworld", + "East Overworld"), + "Overworld - East Overworld Grass (319) (36.5, 44.0, -40.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (318) (35.5, 44.0, -40.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (315) (35.5, 44.0, -41.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (316) (34.5, 44.0, -41.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (882) (65.3, 44.0, -15.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (317) (65.3, 44.0, -14.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - East Overworld Grass (883) (64.3, 44.0, -14.5)": TunicLocationData("East Overworld", "East Overworld"), + "Overworld - Upper Overworld Grass (904) (30.3, 66.0, 26.5)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (901) (29.3, 66.0, 27.3)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (903) (29.3, 66.0, 26.5)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (902) (28.3, 66.0, 27.3)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (898) (17.5, 66.0, 25.3)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (899) (17.5, 66.0, 26.3)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (900) (16.5, 66.0, 26.3)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (897) (16.5, 66.0, 25.3)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (927) (-30.8, 66.0, 34.3)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (924) (-30.8, 66.0, 35.3)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (925) (-31.8, 66.0, 34.3)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (926) (-31.8, 66.0, 35.3)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (922) (-40.3, 66.0, 33.5)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (919) (-40.3, 66.0, 34.5)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (923) (-41.3, 66.0, 33.5)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (918) (-40.3, 66.0, 35.5)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (921) (-41.3, 66.0, 35.5)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Upper Overworld Grass (920) (-41.3, 66.0, 34.5)": TunicLocationData("Upper Overworld", + "Upper Overworld"), + "Overworld - Overworld at Patrol Cave Grass (1094) (65.0, 44.0, 17.5)": TunicLocationData( + "Overworld at Patrol Cave", "Overworld at Patrol Cave"), + "Overworld - Overworld at Patrol Cave Grass (885) (65.0, 44.0, 18.5)": TunicLocationData("Overworld at Patrol Cave", + "Overworld at Patrol Cave"), + "Overworld - Overworld at Patrol Cave Grass (314) (66.0, 44.0, 19.5)": TunicLocationData("Overworld at Patrol Cave", + "Overworld at Patrol Cave"), + "Overworld - Overworld at Patrol Cave Grass (1095) (66.0, 44.0, 18.5)": TunicLocationData( + "Overworld at Patrol Cave", "Overworld at Patrol Cave"), + "Overworld - Overworld at Patrol Cave Grass (884) (65.0, 44.0, 19.5)": TunicLocationData("Overworld at Patrol Cave", + "Overworld at Patrol Cave"), + "Overworld - Overworld at Patrol Cave Grass (888) (57.0, 44.0, 18.3)": TunicLocationData("Overworld at Patrol Cave", + "Overworld at Patrol Cave"), + "Overworld - Overworld at Patrol Cave Grass (887) (57.0, 44.0, 19.3)": TunicLocationData("Overworld at Patrol Cave", + "Overworld at Patrol Cave"), + "Overworld - Overworld at Patrol Cave Grass (893) (56.0, 44.0, 19.3)": TunicLocationData("Overworld at Patrol Cave", + "Overworld at Patrol Cave"), + "Overworld - Overworld at Patrol Cave Grass (892) (56.0, 44.0, 18.3)": TunicLocationData("Overworld at Patrol Cave", + "Overworld at Patrol Cave"), + "Overworld - Overworld above Patrol Cave Grass (895) (44.0, 55.0, 23.5)": TunicLocationData( + "Overworld above Patrol Cave", "Overworld above Patrol Cave"), + "Overworld - Overworld above Patrol Cave Grass (896) (43.0, 55.0, 23.5)": TunicLocationData( + "Overworld above Patrol Cave", "Overworld above Patrol Cave"), + "Overworld - Overworld above Patrol Cave Grass (886) (37.3, 55.0, 23.5)": TunicLocationData( + "Overworld above Patrol Cave", "Overworld above Patrol Cave"), + "Overworld - Overworld above Patrol Cave Grass (889) (37.3, 55.0, 22.5)": TunicLocationData( + "Overworld above Patrol Cave", "Overworld above Patrol Cave"), + "Overworld - Overworld above Patrol Cave Grass (891) (36.3, 55.0, 23.5)": TunicLocationData( + "Overworld above Patrol Cave", "Overworld above Patrol Cave"), + "Overworld - Overworld above Patrol Cave Grass (890) (36.3, 55.0, 22.5)": TunicLocationData( + "Overworld above Patrol Cave", "Overworld above Patrol Cave"), + "Overworld - Overworld above Patrol Cave Grass (894) (35.3, 55.0, 23.5)": TunicLocationData( + "Overworld above Patrol Cave", "Overworld above Patrol Cave"), + "Overworld - Overworld to West Garden from Furnace Grass (1145) (-182.5, 4.0, -45.5)": TunicLocationData( + "West Garden", "Overworld to West Garden from Furnace"), + "Overworld - Overworld to West Garden from Furnace Grass (1143) (-181.5, 4.0, -44.5)": TunicLocationData( + "West Garden", "Overworld to West Garden from Furnace"), + "Overworld - Overworld to West Garden from Furnace Grass (1144) (-182.5, 4.0, -44.5)": TunicLocationData( + "West Garden", "Overworld to West Garden from Furnace"), + "Overworld - Overworld to West Garden from Furnace Grass (1146) (-183.5, 4.0, -45.5)": TunicLocationData( + "West Garden", "Overworld to West Garden from Furnace"), + "Overworld - Overworld to West Garden from Furnace Grass (1147) (-183.5, 4.0, -44.5)": TunicLocationData( + "West Garden", "Overworld to West Garden from Furnace"), + "Overworld - Overworld Beach Grass (1032) (-118.5, 3.5, -144.0)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1031) (-118.5, 3.5, -143.0)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1036) (-118.5, 3.5, -142.0)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1033) (-119.5, 3.5, -144.0)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1037) (-119.5, 3.5, -142.0)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1034) (-119.5, 3.5, -141.0)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1030) (-119.5, 3.5, -143.0)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1035) (-118.5, 3.5, -141.0)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1023) (-118.5, 3.5, -136.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1024) (-118.5, 3.5, -137.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1025) (-119.5, 3.5, -137.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1027) (-118.5, 3.5, -134.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1028) (-118.5, 3.5, -135.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1022) (-119.5, 3.5, -136.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1029) (-119.5, 3.5, -135.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1026) (-119.5, 3.5, -134.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1016) (-120.5, 3.5, -135.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1017) (-121.5, 3.5, -135.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1040) (-118.5, 3.5, -131.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1041) (-119.5, 3.5, -131.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1015) (-120.5, 3.5, -134.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1038) (-119.5, 3.5, -130.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1020) (-120.5, 3.5, -133.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1019) (-120.5, 3.5, -132.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1018) (-121.5, 3.5, -132.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1021) (-121.5, 3.5, -133.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1014) (-121.5, 3.5, -134.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1039) (-118.5, 3.5, -130.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1131) (-167.0, 1.0, -88.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1125) (-166.0, 1.0, -87.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1130) (-167.0, 1.0, -87.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1129) (-166.0, 1.0, -86.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1132) (-168.0, 1.0, -88.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Overworld - Overworld Beach Grass (1133) (-168.0, 1.0, -87.5)": TunicLocationData("Overworld Beach", + "Overworld Beach"), + "Stick House - Stick House Grass (1) (14.0, 0.0, 9.0)": TunicLocationData("Stick House", "Stick House"), + "Stick House - Stick House Grass (4) (15.0, 0.0, 10.0)": TunicLocationData("Stick House", "Stick House"), + "Stick House - Stick House Grass (3) (15.0, 0.0, 8.0)": TunicLocationData("Stick House", "Stick House"), + "Stick House - Stick House Grass (15.0, 0.0, 9.0)": TunicLocationData("Stick House", "Stick House"), + "Stick House - Stick House Grass (2) (14.0, 0.0, 10.0)": TunicLocationData("Stick House", "Stick House"), + "Ruined Passage - Ruined Passage Grass (2) (186.5, 16.8, 40.3)": TunicLocationData("Ruined Passage", + "Ruined Passage"), + "Ruined Passage - Ruined Passage Grass (4) (187.7, 16.5, 39.3)": TunicLocationData("Ruined Passage", + "Ruined Passage"), + "Ruined Passage - Ruined Passage Grass (1) (187.7, 16.8, 40.3)": TunicLocationData("Ruined Passage", + "Ruined Passage"), + "Ruined Passage - Ruined Passage Grass (3) (186.5, 17.0, 41.5)": TunicLocationData("Ruined Passage", + "Ruined Passage"), + "Ruined Passage - Ruined Passage Grass (187.7, 17.0, 41.4)": TunicLocationData("Ruined Passage", "Ruined Passage"), + "Forest Belltower - Forest Belltower Upper Grass (65) (592.5, 62.0, 114.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (64) (593.5, 62.0, 114.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (62) (592.5, 62.0, 115.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (66) (591.5, 62.0, 114.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (56) (593.5, 62.0, 115.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (68) (591.5, 62.0, 115.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (72) (600.8, 62.3, 112.5)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (74) (601.8, 62.3, 112.5)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (75) (601.8, 62.3, 113.5)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (70) (600.8, 62.3, 114.5)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (73) (600.8, 62.3, 113.5)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (67) (599.8, 62.3, 114.5)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (69) (599.8, 62.3, 115.5)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (71) (600.8, 62.3, 115.5)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (55) (601.5, 62.0, 107.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (54) (601.5, 62.0, 106.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (52) (602.5, 62.0, 106.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (53) (602.5, 62.0, 107.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (58) (603.5, 62.0, 108.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (60) (602.5, 62.0, 108.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (59) (603.5, 62.0, 109.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (61) (602.5, 62.0, 109.3)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (79) (602.8, 62.0, 102.1)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (76) (603.8, 62.0, 103.1)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (78) (603.8, 62.0, 102.1)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (77) (602.8, 62.0, 103.1)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (593.0, 14.0, 91.0)": TunicLocationData("Forest Belltower Upper", + "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (3) (592.0, 14.0, 91.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (10) (591.0, 14.0, 91.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (1) (593.0, 14.0, 90.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (2) (592.0, 14.0, 90.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (9) (591.0, 14.0, 90.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (11) (590.0, 14.0, 91.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (8) (590.0, 14.0, 90.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (7) (592.0, 14.0, 89.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (6) (592.0, 14.0, 88.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (5) (593.0, 14.0, 89.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (4) (593.0, 14.0, 88.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (35) (589.0, 14.0, 84.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (30) (589.0, 14.0, 85.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (31) (589.0, 14.0, 86.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (29) (588.0, 14.0, 85.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (39) (591.0, 14.0, 84.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (36) (590.0, 14.0, 84.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (28) (588.0, 14.0, 86.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (34) (589.0, 14.0, 83.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (33) (588.0, 14.0, 83.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (32) (588.0, 14.0, 84.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (37) (590.0, 14.0, 83.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (43) (589.0, 14.0, 82.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (38) (591.0, 14.0, 83.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (40) (588.0, 14.0, 82.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (41) (588.0, 14.0, 81.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (42) (589.0, 14.0, 81.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (50) (583.0, 14.0, 92.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (13) (584.0, 14.0, 92.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (51) (583.0, 14.0, 93.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (14) (585.0, 14.0, 92.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (15) (585.0, 14.0, 93.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (12) (584.0, 14.0, 93.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (49) (582.0, 14.0, 92.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (48) (582.0, 14.0, 93.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (47) (581.0, 14.0, 93.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (46) (581.0, 14.0, 92.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (44) (580.0, 14.0, 93.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (45) (580.0, 14.0, 92.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (27) (592.0, 14.0, 76.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (20) (593.0, 14.0, 78.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (21) (593.0, 14.0, 77.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (24) (591.0, 14.0, 76.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (19) (594.0, 14.0, 76.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (22) (594.0, 14.0, 77.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (16) (593.0, 14.0, 76.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (17) (593.0, 14.0, 75.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (23) (594.0, 14.0, 78.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (26) (592.0, 14.0, 75.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (18) (594.0, 14.0, 75.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Upper Grass (25) (591.0, 14.0, 75.0)": TunicLocationData( + "Forest Belltower Upper", "Forest Belltower Upper"), + "Forest Belltower - Forest Belltower Main Bush (3) (469.0, 38.0, 118.0)": TunicLocationData("Forest Belltower Main", + "Forest Belltower Main"), + "Forest Belltower - Forest Belltower Main Bush (4) (467.0, 38.0, 118.0)": TunicLocationData("Forest Belltower Main", + "Forest Belltower Main"), + "Forest Belltower - Forest Belltower Main Bush (469.0, 38.0, 120.0)": TunicLocationData("Forest Belltower Main", + "Forest Belltower Main"), + "Forest Belltower - Forest Belltower Main Bush (1) (467.0, 38.0, 120.0)": TunicLocationData("Forest Belltower Main", + "Forest Belltower Main"), + "Forest Belltower - Forest Belltower Main Bush (8) (465.0, 38.0, 119.0)": TunicLocationData("Forest Belltower Main", + "Forest Belltower Main"), + "Forest Belltower - Forest Belltower Main Bush (7) (477.0, 38.0, 117.0)": TunicLocationData("Forest Belltower Main", + "Forest Belltower Main"), + "Forest Belltower - Forest Belltower Main Bush (6) (476.0, 38.0, 119.0)": TunicLocationData("Forest Belltower Main", + "Forest Belltower Main"), + "Forest Belltower - Forest Belltower Main Bush (5) (460.0, 38.0, 116.0)": TunicLocationData("Forest Belltower Main", + "Forest Belltower Main"), + "East Forest - East Forest Grass (486) (78.0, 8.0, 71.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (488) (78.0, 8.0, 72.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (482) (77.0, 8.0, 73.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (487) (79.0, 8.0, 71.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (489) (79.0, 8.0, 72.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (483) (78.0, 8.0, 73.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (484) (77.0, 8.0, 74.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (485) (78.0, 8.0, 74.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (454) (82.5, 8.0, 62.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (457) (83.5, 8.0, 62.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (455) (82.5, 8.0, 63.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (456) (83.5, 8.0, 63.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (450) (80.8, 4.0, 56.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (453) (81.8, 4.0, 56.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (451) (80.8, 4.0, 57.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (448) (83.3, 4.0, 54.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (447) (82.3, 4.0, 54.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (452) (81.8, 4.0, 57.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (446) (82.3, 4.0, 53.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (449) (83.3, 4.0, 53.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (458) (78.8, 0.0, 47.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (357) (84.0, 0.0, 48.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (356) (84.0, 0.0, 47.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (367) (83.0, 0.0, 50.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (366) (83.0, 0.0, 51.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (365) (82.0, 0.0, 51.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (359) (85.0, 0.0, 47.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (358) (85.0, 0.0, 48.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (361) (87.0, 0.0, 46.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (74) (86.5, 0.0, 48.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (363) (88.0, 0.0, 45.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (362) (88.0, 0.0, 46.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (360) (87.0, 0.0, 45.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (461) (77.8, 0.0, 47.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (460) (77.8, 0.0, 46.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (459) (78.8, 0.0, 46.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (389) (71.5, 0.0, 38.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (387) (70.5, 0.0, 37.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (388) (70.5, 0.0, 38.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (390) (71.5, 0.0, 37.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (393) (71.5, 0.0, 36.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (392) (70.5, 0.0, 36.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (391) (70.5, 0.0, 35.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (394) (71.5, 0.0, 35.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (396) (71.5, 0.0, 34.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (397) (72.5, 0.0, 34.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (81) (69.0, 0.0, 37.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (80) (69.0, 0.0, 39.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (401) (69.5, 0.0, 35.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (439) (67.5, 0.0, 37.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (400) (68.5, 0.0, 35.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (399) (68.5, 0.0, 34.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (440) (67.5, 0.0, 36.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (82) (67.0, 0.0, 35.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (402) (69.5, 0.0, 34.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (438) (66.5, 0.0, 36.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (443) (67.5, 0.0, 33.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (445) (66.5, 0.0, 33.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (442) (66.5, 0.0, 32.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (444) (67.5, 0.0, 32.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (436) (67.5, 0.0, 38.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (435) (67.5, 0.0, 39.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (379) (68.5, 0.0, 40.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (380) (68.5, 0.0, 41.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (382) (69.5, 0.0, 40.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (381) (69.5, 0.0, 41.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (437) (66.5, 0.0, 39.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (434) (66.5, 0.0, 38.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (441) (66.5, 0.0, 37.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (375) (68.5, 0.0, 42.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (376) (68.5, 0.0, 43.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (432) (67.5, 0.0, 43.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (433) (67.5, 0.0, 42.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (378) (69.5, 0.0, 42.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (377) (69.5, 0.0, 43.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (383) (70.5, 0.0, 42.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (418) (67.5, 0.0, 44.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (429) (67.5, 0.0, 44.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (78) (69.0, 0.0, 45.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (428) (67.5, 0.0, 45.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (417) (67.5, 0.0, 45.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (431) (66.5, 0.0, 42.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (427) (66.5, 0.0, 44.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (430) (66.5, 0.0, 43.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (415) (66.5, 0.0, 44.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (384) (70.5, 0.0, 43.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (386) (71.5, 0.0, 42.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (385) (71.5, 0.0, 43.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (371) (70.5, 0.0, 44.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (374) (71.5, 0.0, 44.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (373) (71.5, 0.0, 45.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (372) (70.5, 0.0, 45.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (76) (69.0, 0.0, 47.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (77) (71.0, 0.0, 47.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (416) (66.5, 0.0, 45.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (364) (72.5, 0.0, 46.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (370) (73.5, 0.0, 46.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (369) (73.5, 0.0, 47.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (368) (72.5, 0.0, 47.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (79) (67.0, 0.0, 47.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (422) (65.5, 0.0, 46.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (421) (65.5, 0.0, 47.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (83) (65.0, 0.0, 45.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (419) (64.5, 0.0, 46.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (420) (64.5, 0.0, 47.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (426) (67.5, 0.0, 48.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (423) (66.5, 0.0, 48.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (425) (67.5, 0.0, 49.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (424) (66.5, 0.0, 49.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (398) (72.5, 0.0, 33.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (395) (71.5, 0.0, 33.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (404) (72.5, 0.0, 32.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (405) (73.5, 0.0, 32.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (413) (72.5, 0.0, 30.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (403) (72.5, 0.0, 31.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (412) (71.5, 0.0, 30.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (406) (73.5, 0.0, 31.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (408) (73.5, 0.0, 30.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (411) (71.5, 0.0, 29.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (414) (72.5, 0.0, 29.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (407) (73.5, 0.0, 29.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (409) (74.5, 0.0, 30.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (410) (74.5, 0.0, 29.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (341) (100.3, 0.0, 30.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (340) (100.3, 0.0, 29.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (343) (101.3, 0.0, 29.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (342) (101.3, 0.0, 30.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (345) (102.3, 0.0, 30.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (346) (103.3, 0.0, 30.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (352) (103.3, 0.0, 31.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (347) (103.3, 0.0, 29.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (344) (102.3, 0.0, 29.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (350) (105.3, 0.0, 30.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (351) (105.3, 0.0, 29.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (348) (104.3, 0.0, 29.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (349) (104.3, 0.0, 30.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (355) (104.3, 0.0, 31.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (354) (104.3, 0.0, 32.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (353) (103.3, 0.0, 32.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (463) (106.5, 0.0, 46.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (465) (106.5, 0.0, 45.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (462) (107.5, 0.0, 45.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (339) (109.8, 0.0, 47.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (464) (107.5, 0.0, 46.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (336) (108.8, 0.0, 47.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (337) (108.8, 0.0, 48.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (338) (109.8, 0.0, 48.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (330) (104.3, 0.0, 49.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (331) (104.3, 0.0, 48.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (328) (103.3, 0.0, 48.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (329) (103.3, 0.0, 49.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (327) (102.3, 0.0, 48.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (326) (102.3, 0.0, 49.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (324) (101.3, 0.0, 48.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (325) (101.3, 0.0, 49.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (72) (101.8, 0.0, 50.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (71) (99.5, 0.0, 50.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (67) (97.5, 0.0, 50.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (316) (97.0, 0.0, 49.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (323) (96.0, 0.0, 50.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (317) (98.0, 0.0, 49.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (73) (99.5, 0.0, 48.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (318) (98.0, 0.0, 48.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (333) (98.0, 0.0, 47.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (319) (97.0, 0.0, 48.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (334) (99.0, 0.0, 47.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (332) (98.0, 0.0, 46.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (335) (99.0, 0.0, 46.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (322) (96.0, 0.0, 51.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (321) (95.0, 0.0, 51.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (320) (95.0, 0.0, 50.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (309) (127.3, 0.0, 43.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (308) (128.3, 0.0, 43.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (70) (129.3, 0.0, 43.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (306) (128.3, 0.0, 44.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (307) (127.2, 0.0, 44.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (278) (131.8, 0.0, 38.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (280) (131.8, 0.0, 37.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (279) (132.8, 0.0, 38.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (281) (132.8, 0.0, 37.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (276) (133.8, 0.0, 37.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (274) (133.8, 0.0, 38.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (284) (133.8, 0.0, 39.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (285) (134.8, 0.0, 39.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (277) (134.8, 0.0, 37.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (275) (134.8, 0.0, 38.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (283) (134.8, 0.0, 40.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (282) (133.8, 0.0, 40.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (271) (133.8, 0.0, 36.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (270) (132.8, 0.0, 36.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (273) (133.8, 0.0, 35.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (272) (132.8, 0.0, 35.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (267) (131.8, 0.0, 34.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (69) (133.3, 0.0, 34.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (66) (135.3, 0.0, 36.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (266) (130.8, 0.0, 34.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (269) (131.8, 0.0, 33.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (255) (132.8, 0.0, 32.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (262) (131.8, 0.0, 32.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (252) (133.8, 0.0, 32.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (268) (130.8, 0.0, 33.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (68) (135.3, 0.0, 32.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (265) (130.8, 0.0, 32.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (264) (131.8, 0.0, 31.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (254) (132.8, 0.0, 31.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (253) (133.8, 0.0, 31.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (260) (132.8, 0.0, 29.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (261) (132.8, 0.0, 30.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (256) (134.8, 0.0, 30.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (258) (134.8, 0.0, 29.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (259) (133.8, 0.0, 30.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (257) (133.8, 0.0, 29.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (299) (135.8, 0.0, 27.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (263) (130.8, 0.0, 31.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (295) (135.8, 0.0, 25.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (301) (135.8, 0.0, 26.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (294) (134.8, 0.0, 25.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (300) (134.8, 0.0, 26.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (296) (134.8, 0.0, 24.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (298) (134.8, 0.0, 27.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (302) (131.8, 0.0, 23.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (304) (131.8, 0.0, 22.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (290) (133.8, 0.0, 23.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (303) (132.8, 0.0, 23.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (305) (132.8, 0.0, 22.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (292) (133.8, 0.0, 22.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (297) (135.8, 0.0, 24.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (291) (134.8, 0.0, 23.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (289) (134.8, 0.0, 20.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (293) (134.8, 0.0, 22.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (287) (134.8, 0.0, 21.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (286) (133.8, 0.0, 21.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (288) (133.8, 0.0, 20.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (466) (117.5, 0.0, 13.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (469) (117.5, 0.0, 12.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (470) (117.5, 0.0, 11.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (468) (116.5, 0.0, 13.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (467) (116.5, 0.0, 12.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (472) (116.5, 0.0, 11.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (471) (116.5, 0.0, 10.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (473) (117.5, 0.0, 10.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (315) (109.3, -1.3, 0.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (310) (110.3, -0.8, 2.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (314) (110.3, -1.3, 0.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (313) (108.3, 0.0, 3.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (311) (108.3, 0.0, 4.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (312) (107.3, 0.0, 3.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (497) (105.8, 0.0, 8.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (501) (103.5, 0.0, 7.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (502) (103.5, 0.0, 6.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (495) (104.8, 0.0, 8.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (493) (105.8, 0.0, 10.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (494) (105.8, 0.0, 9.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (496) (104.8, 0.0, 9.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (498) (103.5, 0.0, 8.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (490) (105.8, 0.0, 11.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (491) (104.8, 0.0, 10.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (492) (104.8, 0.0, 11.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (505) (103.5, 0.0, 5.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (499) (102.5, 0.0, 7.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (504) (102.5, 0.0, 6.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (500) (102.5, 0.0, 8.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (503) (102.5, 0.0, 5.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (507) (87.3, -4.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (509) (88.3, -4.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (513) (86.3, -4.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (506) (88.3, -4.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (508) (87.3, -4.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (510) (86.3, -4.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (512) (85.3, -4.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (511) (77.3, -4.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (514) (77.3, -4.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (516) (76.3, -4.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (515) (76.3, -4.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (519) (88.5, -4.0, -11.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (520) (88.5, -4.0, -12.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (524) (89.8, -4.0, -10.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (517) (89.5, -4.0, -12.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (518) (89.5, -4.0, -11.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (523) (89.8, -4.0, -9.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (521) (90.8, -4.0, -10.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (522) (90.8, -4.0, -9.8)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (89) (131.5, 0.0, -5.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (87) (132.5, 0.0, -6.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (84) (132.5, 0.0, -7.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (85) (133.5, 0.0, -7.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (88) (130.5, 0.0, -5.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (86) (133.5, 0.0, -6.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (78) (133.5, 0.0, -4.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (77) (133.5, 0.0, -5.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (76) (132.5, 0.0, -5.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (90) (131.5, 0.0, -4.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (91) (130.5, 0.0, -4.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (79) (132.5, 0.0, -4.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (80) (132.5, 0.0, -3.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (93) (131.5, 0.0, -2.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (92) (130.5, 0.0, -2.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (83) (132.5, 0.0, -2.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (94) (131.5, 0.0, -1.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (95) (130.5, 0.0, -1.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (81) (133.5, 0.0, -3.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (43) (135.0, 0.0, -5.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (82) (133.5, 0.0, -2.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (44) (135.0, 0.0, -7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (58) (137.5, 0.0, -7.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (73) (137.5, 0.0, -8.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (74) (136.5, 0.0, -8.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (75) (136.5, 0.0, -9.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (59) (136.5, 0.0, -7.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (56) (137.5, 0.0, -6.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (57) (136.5, 0.0, -6.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (98) (135.5, 0.0, -12.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (46) (135.0, 0.0, -11.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (99) (134.5, 0.0, -12.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (96) (134.5, 0.0, -13.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (55) (136.5, 0.0, -11.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (52) (136.5, 0.0, -10.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (97) (135.5, 0.0, -13.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (33) (137.0, 0.0, -13.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (32) (139.0, 0.0, -13.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (54) (137.5, 0.0, -11.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (38) (139.0, 0.0, -11.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (53) (137.5, 0.0, -10.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (72) (137.5, 0.0, -9.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (29) (141.0, 0.0, -13.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (68) (142.5, 0.0, -10.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (35) (141.0, 0.0, -11.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (70) (139.5, 0.0, -9.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (37) (141.0, 0.0, -9.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (65) (139.5, 0.0, -8.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (71) (138.5, 0.0, -9.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (66) (138.5, 0.0, -8.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (42) (143.0, 0.0, -9.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (63) (142.5, 0.0, -7.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (60) (143.5, 0.0, -7.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (62) (142.5, 0.0, -6.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (39) (141.0, 0.0, -7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (69) (143.5, 0.0, -10.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (67) (144.5, 0.0, -8.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (64) (144.5, 0.0, -9.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (41) (145.0, 0.0, -7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (61) (143.5, 0.0, -6.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (40) (143.0, 0.0, -5.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (102) (135.5, 0.0, -18.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (100) (134.5, 0.0, -19.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (103) (134.5, 0.0, -18.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (101) (135.5, 0.0, -19.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (34) (137.0, 0.0, -19.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (107) (138.5, 0.0, -20.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (31) (139.0, 0.0, -19.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (104) (138.5, 0.0, -21.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (106) (139.5, 0.0, -20.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (105) (139.5, 0.0, -21.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (36) (141.0, 0.0, -21.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (30) (141.0, 0.0, -19.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (115) (138.0, 0.0, -24.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (112) (138.0, 0.0, -25.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (114) (139.0, 0.0, -24.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (113) (139.0, 0.0, -25.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (111) (140.5, 0.0, -26.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (118) (133.5, 0.0, -26.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (117) (133.5, 0.0, -27.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (119) (132.5, 0.0, -26.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (116) (132.5, 0.0, -27.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (110) (141.5, 0.0, -26.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (108) (140.5, 0.0, -27.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (109) (141.5, 0.0, -27.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (123) (142.5, 0.0, -28.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (120) (142.5, 0.0, -29.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (122) (143.5, 0.0, -28.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (121) (143.5, 0.0, -29.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (244) (135.5, 8.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (247) (135.5, 8.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (246) (134.5, 8.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (245) (134.5, 8.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (250) (140.5, 8.0, -2.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (249) (140.5, 8.0, -3.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (251) (141.5, 8.0, -3.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (248) (141.5, 8.0, -2.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (213) (147.5, 8.0, 0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (215) (146.5, 8.0, 0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (212) (146.5, 8.0, 1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (203) (146.5, 8.0, 2.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (207) (143.5, 8.0, 4.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (61) (143.0, 8.0, 3.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (237) (141.5, 8.0, 2.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (205) (142.5, 8.0, 4.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (238) (141.5, 8.0, 3.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (239) (140.5, 8.0, 2.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (236) (140.5, 8.0, 3.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (1) (141.0, 8.0, 5.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (7) (139.0, 8.0, 5.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (206) (142.5, 8.0, 5.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (204) (143.5, 8.0, 5.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (60) (145.0, 8.0, 5.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (3) (143.0, 8.0, 9.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (2) (141.0, 8.0, 7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (242) (137.5, 8.0, 5.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (5) (137.0, 8.0, 7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (4) (139.0, 8.0, 7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (240) (136.5, 8.0, 5.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (243) (136.5, 8.0, 4.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (241) (137.5, 8.0, 4.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (137.0, 8.0, 9.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (6) (135.0, 8.0, 7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (211) (144.5, 8.0, 6.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (208) (144.5, 8.0, 7.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (209) (145.5, 8.0, 6.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (210) (145.5, 8.0, 7.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (56) (149.0, 8.0, 5.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (59) (147.0, 8.0, 5.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (58) (147.0, 8.0, 7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (15) (149.0, 8.0, 7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (9) (145.0, 8.0, 9.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (201) (146.5, 8.0, 3.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (200) (147.5, 8.0, 3.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (202) (147.5, 8.0, 2.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (57) (149.0, 8.0, 3.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (63) (151.0, 8.0, 1.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (214) (147.5, 8.0, 1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (62) (149.0, 8.0, 1.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (224) (153.5, 8.0, 1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (225) (152.5, 8.0, 0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (226) (152.5, 8.0, 1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (65) (151.0, 8.0, 5.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (64) (151.0, 8.0, 3.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (17) (153.0, 8.0, 7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (16) (151.0, 8.0, 7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (18) (155.0, 8.0, 7.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (233) (157.5, 8.0, 10.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (20) (155.0, 8.0, 9.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (235) (156.5, 8.0, 10.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (232) (156.5, 8.0, 11.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (23) (155.0, 8.0, 11.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (22) (153.0, 8.0, 11.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (19) (153.0, 8.0, 9.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (234) (157.5, 8.0, 11.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (230) (154.5, 8.0, 1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (228) (155.5, 8.0, 1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (229) (154.5, 8.0, 0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (227) (153.5, 8.0, 0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (231) (155.5, 8.0, 0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (218) (149.5, 8.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (217) (149.5, 8.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (219) (148.5, 8.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (216) (148.5, 8.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (221) (150.5, 8.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (222) (150.5, 8.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (220) (151.5, 8.0, -0.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (223) (151.5, 8.0, -1.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (546) (167.0, 7.8, -23.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (545) (167.0, 7.8, -22.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (543) (166.0, 7.8, -22.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (544) (166.0, 7.8, -23.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (167) (130.0, 24.0, 52.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (164) (130.0, 24.0, 53.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (165) (131.0, 24.0, 52.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (166) (131.0, 24.0, 53.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (135) (125.5, 24.0, 52.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (133) (124.5, 24.0, 52.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (49) (123.0, 24.0, 53.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (131) (121.5, 24.0, 52.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (128) (121.5, 24.0, 53.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (129) (120.5, 24.0, 52.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (176) (119.5, 24.0, 47.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (178) (118.5, 24.0, 47.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (177) (118.5, 24.0, 46.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (179) (119.5, 24.0, 46.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (134) (124.5, 24.0, 53.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (132) (125.5, 24.0, 53.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (137) (124.5, 24.0, 56.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (139) (125.5, 24.0, 56.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (48) (123.0, 24.0, 57.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (45) (121.0, 24.0, 55.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (130) (120.5, 24.0, 53.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (149) (119.5, 24.0, 54.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (145) (119.5, 24.0, 56.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (47) (121.0, 24.0, 57.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (150) (119.5, 24.0, 55.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (146) (119.5, 24.0, 57.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (144) (118.5, 24.0, 57.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (147) (118.5, 24.0, 56.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (148) (118.5, 24.0, 55.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (173) (117.5, 24.0, 56.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (151) (118.5, 24.0, 54.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (174) (117.5, 24.0, 57.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (172) (116.5, 24.0, 57.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (175) (116.5, 24.0, 56.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Bush (50) (115.0, 24.0, 57.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (170) (113.5, 24.0, 57.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (126) (113.5, 24.0, 58.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (125) (113.5, 24.0, 59.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (169) (113.5, 24.0, 56.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (127) (112.5, 24.0, 58.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (124) (112.5, 24.0, 59.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (168) (112.5, 24.0, 57.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (171) (112.5, 24.0, 56.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (141) (121.5, 24.0, 58.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (155) (123.5, 24.0, 58.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (153) (122.5, 24.0, 58.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (142) (121.5, 24.0, 59.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (152) (123.5, 24.0, 59.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (154) (122.5, 24.0, 59.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (143) (120.5, 24.0, 58.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (140) (120.5, 24.0, 59.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (159) (126.0, 24.0, 62.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (163) (128.0, 24.0, 60.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (157) (125.0, 24.0, 62.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (161) (127.0, 24.0, 60.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (162) (127.0, 24.0, 61.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (160) (128.0, 24.0, 61.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (156) (126.0, 24.0, 63.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (158) (125.0, 24.0, 63.0)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (136) (125.5, 24.0, 57.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (138) (124.5, 24.0, 57.5)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (476) (130.0, 0.0, 8.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (474) (131.0, 0.0, 8.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (477) (131.0, 0.0, 7.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (475) (130.0, 0.0, 7.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (479) (132.5, 0.0, 9.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (481) (133.5, 0.0, 9.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (478) (133.5, 0.0, 10.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Grass (480) (132.5, 0.0, 10.3)": TunicLocationData("East Forest", "East Forest"), + "East Forest - East Forest Dance Fox Spot Grass (548) (95.5, 16.0, 75.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (550) (96.5, 16.0, 75.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (547) (95.5, 16.0, 76.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (549) (96.5, 16.0, 76.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (180) (88.0, 16.0, 65.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (181) (88.0, 16.0, 64.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (182) (87.0, 16.0, 64.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (183) (87.0, 16.0, 65.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Bush (52) (89.5, 16.0, 64.5)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Bush (55) (89.5, 16.0, 62.5)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (189) (85.0, 16.0, 61.5)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (190) (84.0, 16.0, 60.5)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (188) (84.0, 16.0, 61.5)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (191) (85.0, 16.0, 60.5)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Bush (51) (89.5, 16.0, 60.5)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Bush (54) (95.5, 16.0, 62.5)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Bush (53) (95.5, 16.0, 64.5)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (197) (91.5, 16.0, 56.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (198) (90.5, 16.0, 55.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (196) (90.5, 16.0, 56.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (199) (91.5, 16.0, 55.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (187) (90.5, 16.0, 54.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (184) (91.5, 16.0, 54.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (186) (91.5, 16.0, 53.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (185) (90.5, 16.0, 53.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (194) (92.5, 16.0, 53.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (192) (92.5, 16.0, 54.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (193) (93.5, 16.0, 54.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - East Forest Dance Fox Spot Grass (195) (93.5, 16.0, 53.0)": TunicLocationData( + "East Forest Dance Fox Spot", "East Forest Dance Fox Spot"), + "East Forest - Lower Forest Grass (528) (86.5, -12.0, -15.3)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (529) (87.5, -12.0, -16.3)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (525) (87.5, -12.0, -15.3)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (527) (86.5, -12.0, -14.3)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (526) (87.5, -12.0, -14.3)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (533) (86.0, -20.3, -21.8)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (530) (87.0, -20.3, -21.8)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (531) (87.0, -20.3, -20.8)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (532) (86.0, -20.3, -20.8)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Bush (14) (99.0, -26.0, -53.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Bush (8) (99.0, -26.0, -49.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Bush (13) (99.0, -26.0, -51.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Bush (10) (104.0, -26.0, -49.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (1) (98.0, -26.0, -57.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (15) (98.0, -26.0, -56.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (12) (98.0, -26.0, -55.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (16) (97.0, -26.0, -57.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (13) (99.0, -26.0, -56.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (99.0, -26.0, -57.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (14) (99.0, -26.0, -55.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (31) (105.0, -26.0, -50.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (26) (105.0, -26.0, -51.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (29) (106.0, -26.0, -50.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (24) (106.0, -26.0, -51.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (23) (106.0, -26.0, -54.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (27) (106.0, -26.0, -52.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (20) (106.0, -26.0, -53.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (22) (105.0, -26.0, -53.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (25) (105.0, -26.0, -52.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (28) (105.0, -26.0, -55.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (21) (105.0, -26.0, -54.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (30) (106.0, -26.0, -55.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (5) (99.0, -26.0, -60.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Bush (24) (105.0, -26.0, -61.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Bush (26) (105.0, -26.0, -59.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Bush (25) (107.0, -26.0, -59.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (38) (109.0, -26.0, -59.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (37) (109.0, -26.0, -60.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (39) (110.0, -26.0, -60.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (36) (110.0, -26.0, -59.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (35) (112.0, -26.0, -60.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (41) (112.0, -26.0, -62.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (42) (112.0, -26.0, -61.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (40) (111.0, -26.0, -61.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (33) (111.0, -26.0, -60.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (43) (111.0, -26.0, -62.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (32) (112.0, -26.0, -59.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (34) (111.0, -26.0, -59.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (6) (99.0, -26.0, -59.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (2) (98.0, -26.0, -58.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (7) (98.0, -26.0, -60.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (4) (98.0, -26.0, -59.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (3) (99.0, -26.0, -58.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (10) (99.0, -26.0, -61.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (9) (99.0, -26.0, -62.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (8) (98.0, -26.0, -61.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (11) (98.0, -26.0, -62.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (19) (97.0, -26.0, -58.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (17) (96.0, -26.0, -58.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (18) (96.0, -26.0, -57.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (50) (99.0, -26.0, -66.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (48) (98.0, -26.0, -66.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (44) (96.0, -26.0, -66.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (46) (97.0, -26.0, -66.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (45) (97.0, -26.0, -67.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (47) (96.0, -26.0, -67.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (49) (99.0, -26.0, -67.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (51) (98.0, -26.0, -67.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Bush (27) (91.0, -26.0, -52.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Bush (28) (91.0, -26.0, -54.0)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (68) (100.3, -30.5, -69.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (73) (100.3, -30.5, -70.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (65) (100.3, -30.5, -68.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (67) (101.3, -30.5, -69.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (74) (101.3, -30.5, -70.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (66) (101.3, -30.5, -68.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (71) (99.3, -30.5, -69.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (70) (99.3, -30.5, -68.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (69) (98.3, -30.5, -68.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (72) (98.3, -30.5, -69.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (75) (101.3, -30.5, -71.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (534) (100.3, -30.5, -71.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (541) (85.3, -30.5, -52.8)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (536) (88.8, -30.5, -55.3)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (535) (87.8, -30.5, -55.3)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (542) (84.3, -30.5, -52.8)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (540) (85.3, -30.5, -51.8)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (539) (84.3, -30.5, -51.8)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (538) (87.8, -30.5, -56.3)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (537) (88.8, -30.5, -56.3)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (53) (142.8, -26.0, -52.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (54) (142.8, -26.0, -51.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (52) (141.8, -26.0, -52.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (55) (141.8, -26.0, -51.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (56) (141.8, -26.0, -35.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (57) (142.8, -26.0, -35.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (60) (141.8, -26.0, -34.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (59) (142.8, -26.0, -34.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (62) (130.5, -26.0, -34.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (63) (130.5, -26.0, -33.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (64) (129.5, -26.0, -33.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "East Forest - Lower Forest Grass (61) (129.5, -26.0, -34.5)": TunicLocationData("Lower Forest", "Lower Forest"), + "Guardhouse 1 - Guard House 1 West Grass (40) (129.0, 0.0, 50.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (44) (127.0, 0.0, 52.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (46) (127.0, 0.0, 51.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (36) (127.0, 0.0, 50.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (45) (128.0, 0.0, 51.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (47) (128.0, 0.0, 52.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (39) (128.0, 0.0, 50.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (43) (130.0, 0.0, 50.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (32) (125.0, 0.0, 49.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (34) (125.0, 0.0, 50.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (33) (126.0, 0.0, 50.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (35) (126.0, 0.0, 49.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (38) (127.0, 0.0, 49.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (42) (129.0, 0.0, 49.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (37) (128.0, 0.0, 49.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (41) (130.0, 0.0, 49.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (24) (118.0, 0.0, 55.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (26) (118.0, 0.0, 56.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (30) (118.0, 0.0, 54.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (27) (119.0, 0.0, 55.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (25) (119.0, 0.0, 56.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (29) (119.0, 0.0, 54.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (31) (119.0, 0.0, 53.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (28) (118.0, 0.0, 53.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (22) (130.0, 0.0, 69.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (9) (128.0, 0.0, 69.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (10) (128.0, 0.0, 68.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (21) (129.0, 0.0, 70.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (20) (129.0, 0.0, 69.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (11) (127.0, 0.0, 68.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (14) (133.0, 0.0, 72.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (15) (132.0, 0.0, 71.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (12) (132.0, 0.0, 72.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (23) (130.0, 0.0, 70.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (8) (127.0, 0.0, 69.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (13) (133.0, 0.0, 71.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (18) (134.0, 0.0, 73.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (16) (133.0, 0.0, 73.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (19) (134.0, 0.0, 74.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (17) (133.0, 0.0, 74.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (3) (116.0, 16.0, 78.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (1) (117.0, 16.0, 79.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (2) (117.0, 16.0, 78.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (116.0, 16.0, 79.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (5) (117.0, 16.0, 74.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (7) (118.0, 16.0, 73.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (4) (118.0, 16.0, 74.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 1 - Guard House 1 West Grass (6) (117.0, 16.0, 73.0)": TunicLocationData("Guard House 1 West", + "Guard House 1 West"), + "Guardhouse 2 - Guard House 2 Upper Grass (25) (150.5, 0.0, -15.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (11) (150.5, 0.0, -13.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (26) (150.5, 0.0, -14.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (24) (151.5, 0.0, -14.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (9) (151.5, 0.0, -13.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (27) (151.5, 0.0, -15.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Bush (7) (155.0, 0.0, -17.0)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Bush (5) (153.0, 0.0, -15.0)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Bush (6) (153.0, 0.0, -17.0)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (7) (152.5, 0.0, -13.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (6) (153.5, 0.0, -12.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (5) (153.5, 0.0, -13.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (1) (154.5, 0.0, -12.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (2) (154.5, 0.0, -13.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Bush (4) (155.0, 0.0, -15.0)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (155.5, 0.0, -12.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (3) (155.5, 0.0, -13.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (32) (156.5, 0.0, -14.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Bush (9) (153.0, 0.0, -11.0)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (4) (152.5, 0.0, -12.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (10) (151.5, 0.0, -12.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (13) (151.5, 0.0, -9.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Bush (8) (151.0, 0.0, -11.0)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (8) (150.5, 0.0, -12.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (15) (150.5, 0.0, -9.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (35) (156.5, 0.0, -15.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (29) (155.5, 0.0, -19.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (30) (155.5, 0.0, -18.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (31) (154.5, 0.0, -19.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (28) (154.5, 0.0, -18.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (33) (157.5, 0.0, -15.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (34) (157.5, 0.0, -14.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Bush (3) (157.0, 0.0, -13.0)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (37) (157.5, 0.0, -11.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (38) (157.5, 0.0, -10.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (39) (156.5, 0.0, -11.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (36) (156.5, 0.0, -10.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Bush (2) (155.0, 0.0, -11.0)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (41) (154.5, 0.0, -9.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (43) (155.5, 0.0, -9.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (40) (155.5, 0.0, -8.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (42) (154.5, 0.0, -8.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (14) (151.5, 0.0, -8.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (19) (151.5, 0.0, -7.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (16) (151.5, 0.0, -6.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (18) (150.5, 0.0, -6.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Bush (153.0, 0.0, -7.0)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Bush (1) (153.0, 0.0, -9.0)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (17) (150.5, 0.0, -7.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (12) (150.5, 0.0, -8.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (23) (149.5, 0.0, -7.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (20) (149.5, 0.0, -6.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (22) (148.5, 0.0, -6.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Guardhouse 2 - Guard House 2 Upper Grass (21) (148.5, 0.0, -7.5)": TunicLocationData("Guard House 2 Upper after bushes", + "Guard House 2 Upper after bushes"), + "Forest Grave Path - Forest Grave Path Main Bush (110) (-70.0, -4.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (112) (-66.0, -4.0, -181.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (111) (-64.0, -4.0, -181.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (113) (-64.0, -4.0, -183.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (76) (-62.8, -4.0, -182.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (82) (-59.8, -4.0, -181.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (83) (-60.8, -4.0, -181.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (78) (-61.8, -4.0, -181.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (77) (-61.8, -4.0, -182.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (79) (-62.8, -4.0, -181.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (119) (-65.0, -4.0, -193.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (118) (-65.0, -4.0, -195.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (120) (-63.0, -4.0, -195.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (90) (-59.5, -4.0, -187.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (121) (-59.0, -4.0, -197.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (122) (-57.0, -4.0, -191.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (91) (-58.5, -4.0, -187.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (86) (-57.5, -4.0, -189.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (89) (-57.5, -4.0, -188.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (87) (-56.5, -4.0, -189.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (88) (-56.5, -4.0, -188.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (106) (-53.0, -4.0, -191.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (107) (-55.0, -4.0, -191.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (104) (-53.0, -4.0, -187.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (115) (-55.0, -4.0, -187.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (108) (-55.0, -4.0, -189.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (105) (-53.0, -4.0, -189.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (117) (-55.0, -4.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (109) (-57.0, -4.0, -187.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (92) (-58.5, -4.0, -186.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (93) (-59.5, -4.0, -186.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (103) (-53.0, -4.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (81) (-52.5, -4.0, -181.8)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (116) (-53.0, -4.0, -183.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (85) (-53.5, -4.0, -180.8)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (80) (-53.5, -4.0, -181.8)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (84) (-52.5, -4.0, -180.8)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (133) (-45.0, 0.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (136) (-43.0, 0.0, -189.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (135) (-43.0, 0.0, -187.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (42) (-42.5, 0.0, -190.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (47) (-41.5, 0.0, -188.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (56) (-41.5, 0.0, -187.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (44) (-41.5, 0.0, -189.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (45) (-40.5, 0.0, -189.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (33) (-46.5, 0.0, -185.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (134) (-43.0, 0.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (43) (-43.5, 0.0, -190.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (34) (-46.5, 0.0, -184.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (35) (-47.5, 0.0, -184.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (32) (-47.5, 0.0, -185.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (59) (-41.5, 0.0, -186.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (137) (-41.0, 0.0, -191.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (40) (-43.5, 0.0, -191.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (138) (-43.0, 0.0, -193.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (41) (-42.5, 0.0, -191.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (61) (-40.5, 0.0, -195.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (36) (-41.5, 0.0, -193.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (39) (-41.5, 0.0, -192.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (60) (-41.5, 0.0, -195.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (63) (-41.5, 0.0, -194.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (62) (-40.5, 0.0, -194.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (38) (-40.5, 0.0, -192.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (37) (-40.5, 0.0, -193.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (53) (-38.5, 0.0, -189.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (50) (-38.5, 0.0, -190.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (49) (-38.5, 0.0, -191.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (48) (-39.5, 0.0, -191.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (52) (-39.5, 0.0, -189.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (51) (-39.5, 0.0, -190.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (46) (-40.5, 0.0, -188.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (54) (-38.5, 0.0, -188.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (55) (-39.5, 0.0, -188.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (57) (-40.5, 0.0, -187.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (58) (-40.5, 0.0, -186.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (141) (-47.0, 0.0, -195.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (139) (-43.0, 0.0, -195.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (140) (-45.0, 0.0, -195.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (66) (-43.0, 0.0, -200.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (67) (-44.0, 0.0, -200.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (64) (-44.0, 0.0, -201.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (65) (-43.0, 0.0, -201.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (68) (-40.0, 0.0, -201.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (71) (-40.0, 0.0, -200.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (70) (-39.0, 0.0, -200.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (69) (-39.0, 0.0, -201.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (75) (-31.5, 0.0, -192.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (72) (-31.5, 0.0, -193.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (73) (-30.5, 0.0, -193.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (74) (-30.5, 0.0, -192.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (147) (-35.0, 0.0, -185.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (146) (-33.0, 0.0, -185.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (28) (-33.5, 0.0, -184.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (29) (-32.5, 0.0, -184.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (23) (-31.5, 0.0, -184.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (20) (-31.5, 0.0, -185.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (21) (-30.5, 0.0, -185.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (26) (-32.5, 0.0, -181.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (30) (-32.5, 0.0, -183.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (25) (-32.5, 0.0, -182.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (31) (-33.5, 0.0, -183.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (24) (-33.5, 0.0, -182.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (27) (-33.5, 0.0, -181.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (148) (-35.0, 0.0, -183.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (22) (-30.5, 0.0, -184.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (12) (-29.5, 0.0, -185.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (13) (-28.5, 0.0, -185.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (10) (-27.5, 0.0, -186.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (11) (-27.5, 0.0, -187.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (15) (-29.5, 0.0, -184.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (3) (-23.5, 0.0, -187.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (132) (-25.0, 0.0, -187.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (8) (-26.5, 0.0, -187.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (9) (-26.5, 0.0, -186.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (130) (-25.0, 0.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (131) (-27.0, 0.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (14) (-28.5, 0.0, -184.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (-23.5, 0.0, -186.5)": TunicLocationData("Forest Grave Path Main", + "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (2) (-22.5, 0.0, -187.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (1) (-22.5, 0.0, -186.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (126) (-19.0, 0.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (6) (-20.5, 0.0, -185.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (4) (-20.5, 0.0, -184.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (7) (-21.5, 0.0, -185.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (5) (-21.5, 0.0, -184.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (129) (-23.0, 0.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (19) (-17.5, 0.0, -186.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (16) (-17.5, 0.0, -187.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (18) (-16.5, 0.0, -186.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (17) (-16.5, 0.0, -187.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (125) (-15.0, 0.0, -187.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (124) (-15.0, 0.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (123) (-17.0, 0.0, -185.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (127) (-14.0, 0.0, -194.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (116) (-23.8, -4.3, -205.8)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (97) (-27.3, -6.3, -210.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (96) (-26.3, -6.3, -210.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (117) (-22.8, -4.3, -205.8)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (119) (-22.8, -4.3, -204.8)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (95) (-26.3, -6.3, -211.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (118) (-23.8, -4.3, -204.8)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (123) (-20.5, -4.3, -208.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (121) (-20.5, -4.3, -209.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (114) (-15.5, -4.3, -212.3)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (112) (-15.5, -4.3, -213.3)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (115) (-14.5, -4.3, -212.3)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (113) (-14.5, -4.3, -213.3)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (110) (-13.5, -4.3, -213.3)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (111) (-12.5, -4.3, -213.3)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (109) (-12.5, -4.3, -212.3)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (108) (-13.5, -4.3, -212.3)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (106) (-24.3, -6.2, -215.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (102) (-24.3, -6.3, -214.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (103) (-23.3, -6.3, -214.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (99) (-25.3, -6.3, -213.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (101) (-26.3, -6.3, -212.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (98) (-26.3, -6.3, -213.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (94) (-27.3, -6.3, -211.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (107) (-23.3, -6.3, -215.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (105) (-24.3, -6.3, -213.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (100) (-25.3, -6.3, -212.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Grass (104) (-23.3, -6.3, -213.5)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (144) (-21.5, 8.0, -179.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (145) (-23.5, 8.0, -179.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path Main Bush (149) (-25.5, 8.0, -179.0)": TunicLocationData( + "Forest Grave Path Main", "Forest Grave Path Main"), + "Forest Grave Path - Forest Grave Path by Grave Grass (58) (8.5, 4.0, -190.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (57) (8.5, 4.0, -191.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (102) (9.0, 4.0, -189.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (59) (9.5, 4.0, -191.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (56) (9.5, 4.0, -190.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (52) (12.5, 4.0, -190.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (55) (12.5, 4.0, -191.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (54) (13.5, 4.0, -190.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (53) (13.5, 4.0, -191.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (47) (14.5, 4.0, -189.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (44) (14.5, 4.0, -188.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (49) (13.5, 4.0, -189.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (50) (13.5, 4.0, -188.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (51) (12.5, 4.0, -189.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (48) (12.5, 4.0, -188.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (100) (11.0, 4.0, -189.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (99) (15.0, 4.0, -191.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (45) (15.5, 4.0, -189.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (7) (16.5, 4.0, -190.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (5) (16.5, 4.0, -191.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (21) (19.5, 4.0, -193.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (30) (19.5, 4.0, -194.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (22) (19.5, 4.0, -192.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (14) (18.5, 4.0, -191.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (20) (18.5, 4.0, -192.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (28) (18.5, 4.0, -194.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (23) (18.5, 4.0, -193.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (98) (17.0, 4.0, -193.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (6) (17.5, 4.0, -191.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (9) (19.5, 4.0, -188.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (15) (19.5, 4.0, -191.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (11) (19.5, 4.0, -189.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (13) (19.5, 4.0, -190.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (8) (18.5, 4.0, -188.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (12) (18.5, 4.0, -190.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (10) (18.5, 4.0, -189.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (2) (17.5, 4.0, -189.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (4) (17.5, 4.0, -190.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (1) (17.5, 4.0, -188.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (3) (16.5, 4.0, -189.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (97) (17.0, 4.0, -187.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (16.5, 4.0, -188.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (46) (15.5, 4.0, -188.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (89) (21.0, 4.0, -195.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (31) (18.5, 4.0, -195.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (29) (19.5, 4.0, -195.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (26) (23.5, 4.0, -192.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (25) (23.5, 4.0, -193.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (90) (23.0, 4.0, -195.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (27) (22.5, 4.0, -193.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (24) (22.5, 4.0, -192.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (88) (21.0, 4.0, -193.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (75) (21.0, 4.0, -191.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (71) (21.0, 4.0, -189.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (37) (22.5, 4.0, -187.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (91) (25.0, 4.0, -195.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (93) (29.0, 4.0, -195.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (92) (27.0, 4.0, -195.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (35) (23.5, 4.0, -185.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (33) (22.5, 4.0, -185.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (38) (22.5, 4.0, -186.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (36) (23.5, 4.0, -186.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (39) (23.5, 4.0, -187.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (95) (27.0, 4.0, -185.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (96) (25.0, 4.0, -185.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (32) (23.5, 4.0, -184.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (40) (21.5, 4.0, -184.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (43) (21.5, 4.0, -185.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (34) (22.5, 4.0, -184.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (42) (20.5, 4.0, -184.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (41) (20.5, 4.0, -185.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Bush (94) (29.0, 4.0, -185.0)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (17) (17.5, 4.0, -184.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (19) (17.5, 4.0, -185.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (16) (16.5, 4.0, -184.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "Forest Grave Path - Forest Grave Path by Grave Grass (18) (16.5, 4.0, -185.5)": TunicLocationData( + "Forest Grave Path by Grave", "Forest Grave Path by Grave"), + "West Garden - West Garden Grass (297) (-115.0, 4.0, 159.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (300) (-113.8, 4.0, 159.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (296) (-115.0, 4.0, 160.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (298) (-116.0, 4.0, 160.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (187) (-125.5, 4.0, 160.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (189) (-124.5, 4.0, 160.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (185) (-131.0, 4.0, 160.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (206) (-131.0, 4.0, 159.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (188) (-131.0, 4.0, 159.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (186) (-132.0, 4.0, 160.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (218) (-131.8, 2.3, 151.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (219) (-131.8, 1.8, 150.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (217) (-130.5, 2.3, 151.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (216) (-130.5, 2.8, 152.8)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (241) (-161.6, 2.0, 124.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (192) (-158.0, 1.5, 122.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (191) (-158.0, 1.5, 123.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (193) (-157.0, 1.5, 122.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (190) (-157.0, 1.5, 123.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (239) (-159.7, 1.5, 117.7)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (235) (-159.8, 1.5, 116.7)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (236) (-160.8, 1.5, 116.7)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (237) (-161.8, 1.5, 116.7)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (194) (-165.4, 2.0, 121.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (196) (-162.5, 2.0, 123.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (238) (-162.5, 2.0, 124.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (195) (-165.4, 2.0, 120.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (240) (-162.5, 2.0, 125.4)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (20) (-162.0, 10.0, 139.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (18) (-160.0, 10.0, 139.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (19) (-160.0, 10.0, 141.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (295) (-159.5, 9.8, 160.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (21) (-180.0, 10.0, 139.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (23) (-180.0, 10.0, 141.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (22) (-178.0, 10.0, 139.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (212) (-174.5, 2.0, 123.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (213) (-174.5, 2.0, 124.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (214) (-174.5, 2.0, 125.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (215) (-175.5, 2.0, 124.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (24) (-185.0, 1.9, 143.9)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (198) (-185.0, 2.5, 148.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (197) (-185.0, 2.5, 149.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (202) (-185.0, 2.5, 150.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (201) (-186.0, 2.5, 150.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (200) (-186.0, 2.5, 149.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (216) (-192.3, 1.0, 145.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (217) (-192.3, 1.0, 146.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (211) (-193.3, 0.9, 145.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (406) (-190.8, 1.3, 149.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (405) (-189.8, 1.3, 149.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (25) (-196.0, 0.8, 152.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (203) (-198.5, 1.0, 150.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (199) (-198.5, 1.0, 151.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (205) (-199.5, 1.0, 151.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (204) (-199.5, 1.0, 150.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (213) (-196.0, 4.0, 160.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (214) (-197.0, 4.0, 159.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (212) (-197.0, 4.0, 160.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (211) (-198.0, 4.0, 160.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (215) (-198.0, 4.0, 159.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (31) (-250.5, 4.0, 147.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (34) (-251.5, 4.0, 147.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (10) (-253.5, 3.8, 150.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (7) (-252.5, 3.8, 150.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (8) (-253.5, 3.8, 151.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (40) (-261.0, 4.0, 151.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (42) (-261.0, 4.0, 150.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (37) (-262.0, 4.0, 151.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (36) (-263.0, 4.0, 151.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (35) (-262.0, 4.0, 150.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (38) (-263.0, 4.0, 150.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (5) (-256.1, 4.0, 160.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (4) (-255.1, 4.0, 160.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (6) (-256.1, 4.0, 161.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (3) (-255.1, 4.0, 161.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (11) (-262.5, 4.0, 172.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (13) (-262.5, 4.0, 173.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (12) (-263.5, 4.0, 173.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (14) (-263.5, 4.0, 172.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (18) (-256.0, 4.0, 173.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (17) (-255.0, 4.0, 174.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (15) (-255.0, 4.0, 173.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (16) (-256.0, 4.0, 174.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (22) (-260.5, 4.0, 177.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (19) (-259.5, 4.0, 177.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (21) (-259.5, 4.0, 178.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (20) (-260.5, 4.0, 178.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (75) (-254.0, 4.0, 183.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (30) (-253.0, 4.0, 183.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (28) (-253.0, 4.0, 181.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (29) (-252.0, 4.0, 181.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (26) (-265.3, 4.0, 167.8)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (27) (-267.3, 4.0, 167.8)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Bush (28) (-271.8, 4.0, 162.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (41) (-278.0, 1.0, 168.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (39) (-278.0, 1.0, 167.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (207) (-310.8, 1.3, 164.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (210) (-310.8, 1.3, 165.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (209) (-312.0, 1.3, 165.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (208) (-312.0, 1.3, 164.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (103) (-323.5, 4.0, 128.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (101) (-323.5, 4.0, 129.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (102) (-324.5, 4.0, 129.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (104) (-324.5, 4.0, 128.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (95) (-332.0, 4.0, 127.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (348) (-331.0, 4.0, 128.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (94) (-331.0, 4.0, 127.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (343) (-331.0, 4.0, 129.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (353) (-330.1, 4.0, 129.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (354) (-330.1, 4.0, 128.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (344) (-332.0, 4.0, 129.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (347) (-332.0, 4.0, 128.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (349) (-333.0, 4.0, 129.3)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (90) (-323.5, 4.0, 113.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (89) (-323.5, 4.0, 112.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (92) (-322.5, 4.0, 113.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (93) (-322.5, 4.0, 112.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (91) (-324.5, 4.0, 113.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (1) (-324.5, 4.0, 112.5)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (115) (-334.0, 4.0, 109.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (116) (-333.0, 4.0, 109.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (117) (-334.0, 4.0, 108.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (100) (-339.5, 4.0, 114.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (99) (-339.5, 4.0, 115.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (98) (-340.5, 4.0, 115.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (171) (-348.5, 4.0, 124.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (167) (-348.5, 4.0, 123.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (114) (-349.5, 4.0, 123.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (170) (-349.5, 4.0, 124.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (168) (-348.5, 4.0, 122.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (169) (-349.5, 4.0, 122.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (341) (-345.6, 4.0, 127.3)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (119) (-348.5, 4.0, 129.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (120) (-348.5, 4.0, 128.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (118) (-349.5, 4.0, 129.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (340) (-344.6, 4.0, 126.3)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (338) (-345.6, 4.0, 126.3)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (342) (-344.6, 4.0, 127.3)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (346) (-342.6, 4.0, 127.3)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (345) (-343.6, 4.0, 127.3)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (44) (-325.0, 4.0, 88.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (45) (-325.0, 4.0, 87.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (74) (-327.9, 4.0, 88.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (73) (-326.9, 4.0, 88.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (49) (-326.0, 4.0, 88.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (48) (-326.0, 4.0, 87.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (43) (-324.0, 4.0, 88.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (46) (-324.0, 4.0, 87.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (51) (-324.5, 4.0, 78.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (54) (-324.5, 4.0, 77.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (52) (-323.5, 4.0, 77.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (53) (-323.5, 4.0, 78.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (397) (-328.9, 4.0, 68.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (398) (-329.9, 4.0, 67.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (396) (-327.9, 4.0, 67.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (395) (-327.9, 4.0, 68.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (393) (-328.9, 4.0, 67.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (55) (-342.5, 4.0, 78.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (57) (-341.5, 4.0, 78.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (56) (-341.5, 4.0, 77.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (58) (-342.5, 4.0, 77.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (97) (-346.8, 4.0, 72.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (394) (-346.8, 4.0, 73.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (392) (-345.8, 4.0, 72.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (96) (-345.8, 4.0, 71.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (76) (-346.8, 4.0, 71.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Bush (30) (-285.5, 0.5, 74.9)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Bush (29) (-283.4, 0.5, 74.9)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (153) (-295.5, 0.8, 70.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (264) (-295.5, 0.8, 69.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (152) (-296.5, 0.8, 70.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (154) (-296.5, 0.8, 69.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Bush (32) (-291.4, 0.5, 69.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Bush (33) (-293.1, 0.5, 67.1)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Bush (31) (-289.5, 0.5, 69.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (133) (-261.0, 0.3, 61.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (132) (-261.0, 0.3, 62.3)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (135) (-262.3, 0.3, 62.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (134) (-262.3, 0.3, 61.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (429) (-249.3, 4.0, 113.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (427) (-250.3, 4.0, 112.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (426) (-250.3, 4.0, 113.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (425) (-251.3, 4.0, 113.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (428) (-249.3, 4.0, 112.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (424) (-251.3, 4.0, 112.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (434) (-241.3, 4.0, 117.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (435) (-240.3, 4.0, 117.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (431) (-241.3, 4.0, 118.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (430) (-240.3, 4.0, 118.5)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (141) (-273.5, 0.0, 37.8)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (140) (-272.5, 0.0, 37.8)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (142) (-273.5, 0.3, 36.8)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (180) (-275.8, 0.8, 37.8)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (177) (-275.8, 0.8, 38.8)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (221) (-274.8, 0.6, 37.8)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (219) (-271.9, 0.0, 35.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (220) (-271.9, 0.3, 34.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (218) (-270.9, 0.0, 35.4)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (139) (-283.0, 2.0, 41.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (138) (-284.0, 2.0, 41.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (137) (-284.0, 2.0, 42.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (136) (-283.0, 2.0, 42.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (126) (-308.5, 2.0, 39.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (355) (-308.5, 2.0, 42.1)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (127) (-308.5, 2.0, 40.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (352) (-308.5, 2.0, 41.1)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (351) (-309.5, 2.0, 41.1)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (124) (-309.5, 2.0, 40.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (125) (-309.5, 2.0, 39.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (350) (-309.5, 2.0, 42.1)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (359) (-300.4, 2.0, 24.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (356) (-301.4, 2.0, 24.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (357) (-301.4, 2.0, 23.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (358) (-300.4, 2.0, 23.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (112) (-322.0, 2.0, 43.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (110) (-322.0, 2.0, 44.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (113) (-321.0, 2.0, 43.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (108) (-321.0, 2.0, 45.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (109) (-321.0, 2.0, 44.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (111) (-322.0, 2.0, 45.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (360) (-323.0, 2.0, 45.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (414) (-337.8, 2.0, 44.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (413) (-338.8, 2.0, 44.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (412) (-338.8, 2.0, 45.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (411) (-337.8, 2.0, 45.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (416) (-343.8, 2.0, 42.3)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (415) (-344.8, 2.0, 42.3)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (106) (-359.0, 1.5, 45.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (105) (-359.0, 1.5, 46.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (407) (-358.0, 1.8, 46.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (408) (-358.0, 1.8, 45.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (409) (-358.0, 1.8, 47.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (410) (-359.0, 1.5, 47.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (107) (-360.0, 1.3, 45.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (123) (-322.5, 1.8, 14.8)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (121) (-321.5, 1.8, 15.8)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (122) (-322.5, 1.8, 15.8)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (251) (-313.8, 2.0, 12.3)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (250) (-313.8, 2.0, 13.3)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (253) (-312.8, 2.0, 13.3)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (173) (-308.5, 2.0, 14.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (172) (-309.5, 2.0, 14.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (175) (-309.5, 2.0, 13.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (252) (-310.6, 2.0, 13.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (128) (-308.5, 2.0, -4.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (130) (-309.5, 2.0, -5.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (129) (-309.5, 2.0, -4.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (364) (-291.4, 2.0, -6.9)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (365) (-291.4, 2.0, -5.8)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (363) (-292.4, 2.0, -6.9)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (362) (-292.4, 2.0, -5.9)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (361) (-293.4, 2.0, -5.9)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (249) (-287.3, 2.0, -8.9)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (254) (-286.3, 2.0, -8.9)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (255) (-286.3, 2.0, -9.9)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (256) (-285.3, 1.8, -9.9)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (257) (-285.3, 1.8, -8.8)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (367) (-284.3, 1.5, -10.8)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (368) (-283.3, 1.4, -10.8)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (369) (-283.3, 1.4, -9.6)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (366) (-284.3, 1.5, -9.8)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (131) (-279.0, 2.0, -4.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (143) (-278.0, 2.0, -4.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (146) (-278.0, 2.0, -5.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (145) (-277.0, 2.0, -5.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (144) (-277.0, 2.0, -4.5)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (374) (-245.5, 1.0, 1.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (371) (-243.5, 1.0, 1.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (373) (-244.5, 1.0, 2.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (372) (-244.5, 1.0, 1.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (375) (-245.5, 1.0, 2.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (149) (-246.5, 1.0, 3.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (148) (-245.5, 1.0, 3.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (150) (-246.5, 1.0, 4.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (147) (-245.5, 1.0, 4.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (370) (-243.5, 1.0, 2.0)": TunicLocationData("none", "West Garden West Combat"), + "West Garden - West Garden Grass (377) (-256.8, 1.9, 16.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (376) (-256.8, 1.9, 15.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (378) (-257.8, 1.9, 15.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (382) (-256.8, 1.9, 17.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (379) (-257.8, 1.9, 16.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (380) (-257.8, 1.9, 17.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (384) (-255.8, 1.9, 17.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (386) (-254.8, 1.9, 17.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (383) (-256.8, 1.9, 18.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (381) (-257.8, 1.9, 18.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (229) (-234.6, 8.0, 8.6)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (230) (-234.6, 8.0, 7.6)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (225) (-233.6, 8.0, 7.6)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (227) (-233.6, 8.0, 8.6)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (228) (-233.6, 8.0, 9.6)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (181) (-240.5, 8.0, 5.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (184) (-240.5, 8.0, 4.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (182) (-241.5, 8.0, 5.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (183) (-241.5, 8.0, 4.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (223) (-228.5, 8.0, 37.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (226) (-228.5, 8.0, 36.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (419) (-228.5, 8.0, 35.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (417) (-227.5, 8.0, 36.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (25) (-226.0, 8.0, 35.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (423) (-226.5, 8.0, 36.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (222) (-227.5, 8.0, 37.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (418) (-227.5, 8.0, 35.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (420) (-225.5, 8.0, 36.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (421) (-225.5, 8.0, 37.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (422) (-226.5, 8.0, 37.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (224) (-229.5, 8.0, 37.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (26) (-224.3, 8.0, 36.8)": TunicLocationData("none", "West Garden South Checkpoint"), + # these 4 are above the magic dagger house, choosing south checkpoint based on vibes + "West Garden - West Garden Grass (157) (-193.0, 8.0, 40.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (156) (-192.0, 8.0, 40.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (151) (-192.0, 8.0, 41.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (158) (-193.0, 8.0, 41.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (248) (-197.4, 1.0, 22.3)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (245) (-195.4, 1.0, 23.3)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (246) (-196.4, 1.0, 23.3)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (247) (-197.4, 1.0, 23.3)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (162) (-206.5, 1.0, 28.0)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (159) (-205.5, 1.0, 28.0)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (160) (-206.5, 1.0, 29.0)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (161) (-205.5, 1.0, 29.0)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (163) (-211.5, 1.0, 35.0)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (166) (-212.5, 1.0, 35.0)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (165) (-211.5, 1.0, 36.0)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (164) (-212.5, 1.0, 36.0)": TunicLocationData("none", "West Garden at Dagger House"), + "West Garden - West Garden Grass (318) (-243.8, 8.0, 72.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (319) (-244.8, 8.0, 72.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (313) (-247.5, 8.0, 67.8)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (62) (-244.0, 8.0, 65.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (61) (-245.0, 8.0, 64.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (64) (-244.0, 8.0, 64.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (63) (-245.0, 8.0, 65.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (314) (-246.5, 8.0, 68.8)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (317) (-244.8, 8.0, 71.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (315) (-247.5, 8.0, 68.8)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (320) (-243.8, 8.0, 71.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (316) (-246.5, 8.0, 67.8)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (50) (-247.5, 8.0, 83.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (59) (-246.5, 8.0, 83.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (47) (-247.5, 8.0, 84.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (60) (-246.5, 8.0, 84.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (65) (-226.0, 8.0, 67.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (68) (-225.0, 8.0, 67.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (67) (-226.0, 8.0, 68.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (66) (-225.0, 8.0, 68.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (69) (-226.0, 8.0, 72.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (72) (-225.0, 8.0, 72.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (71) (-226.0, 8.0, 73.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (70) (-225.0, 8.0, 73.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (303) (-215.3, 8.0, 83.8)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (17) (-215.0, 8.0, 85.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (27) (-217.0, 8.0, 81.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (24) (-217.0, 8.0, 87.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (301) (-215.3, 8.0, 82.8)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (13) (-213.0, 8.0, 83.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (304) (-214.3, 8.0, 82.8)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (302) (-214.3, 8.0, 83.8)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (16) (-211.0, 8.0, 85.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (12) (-213.0, 8.0, 85.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (14) (-213.0, 8.0, 87.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (15) (-211.0, 8.0, 87.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (309) (-203.5, 8.0, 86.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (11) (-203.0, 8.0, 85.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (312) (-202.5, 8.0, 86.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (2) (-199.0, 8.0, 83.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (308) (-200.5, 8.0, 84.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (305) (-201.5, 8.0, 84.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (307) (-201.5, 8.0, 85.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (-199.0, 8.0, 87.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (306) (-200.5, 8.0, 85.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (7) (-201.0, 8.0, 87.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (310) (-202.5, 8.0, 87.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (311) (-203.5, 8.0, 87.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (1) (-199.0, 8.0, 85.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (4) (-197.0, 8.0, 85.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (5) (-197.0, 8.0, 83.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (3) (-197.0, 8.0, 87.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (6) (-197.0, 8.0, 81.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (10) (-191.0, 8.0, 81.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (8) (-191.0, 8.0, 87.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Bush (9) (-193.0, 8.0, 87.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (333) (-226.0, 8.0, 92.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (336) (-225.0, 8.0, 92.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (334) (-225.0, 8.0, 93.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (339) (-226.0, 8.0, 97.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (337) (-225.0, 8.0, 97.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (335) (-225.0, 8.0, 98.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (329) (-229.3, 8.0, 101.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (332) (-228.3, 8.0, 101.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (331) (-229.3, 8.0, 102.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (328) (-229.3, 8.0, 103.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (330) (-228.3, 8.0, 102.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (325) (-230.3, 8.0, 103.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (326) (-229.3, 8.0, 104.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (327) (-230.3, 8.0, 104.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (321) (-232.8, 8.0, 109.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (324) (-231.8, 8.0, 109.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (323) (-232.8, 8.0, 110.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (322) (-231.8, 8.0, 110.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (399) (-233.8, 8.0, 111.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (400) (-234.8, 8.0, 111.3)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (84) (-244.0, 8.0, 101.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (81) (-245.0, 8.0, 101.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (82) (-244.0, 8.0, 100.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (83) (-245.0, 8.0, 100.5)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (77) (-247.5, 8.0, 98.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (80) (-246.5, 8.0, 98.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (79) (-247.5, 8.0, 97.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (78) (-246.5, 8.0, 97.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (88) (-246.5, 8.0, 109.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (85) (-247.5, 8.0, 109.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (86) (-246.5, 8.0, 110.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (87) (-247.5, 8.0, 110.0)": TunicLocationData("none", "West Garden South Checkpoint"), + "West Garden - West Garden Grass (283) (-225.4, 20.0, 172.9)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (284) (-225.4, 20.0, 173.9)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (282) (-226.4, 20.0, 172.9)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (285) (-226.4, 20.0, 173.9)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (279) (-222.3, 20.0, 177.6)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (278) (-222.3, 20.0, 178.6)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (32) (-221.3, 20.0, 178.8)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (33) (-221.3, 20.0, 177.8)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (280) (-221.3, 20.0, 176.6)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (275) (-222.3, 20.0, 179.8)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (9) (-221.3, 20.0, 179.8)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (281) (-223.3, 20.0, 179.8)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (385) (-246.6, 20.0, 172.0)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (294) (-247.6, 20.0, 172.0)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (291) (-247.6, 20.0, 173.0)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (290) (-247.6, 20.0, 174.0)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (292) (-246.6, 20.0, 174.0)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (293) (-246.6, 20.0, 173.0)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (287) (-244.8, 20.0, 176.0)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (288) (-244.8, 20.0, 175.0)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (286) (-245.8, 20.0, 175.0)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (289) (-245.8, 20.0, 176.0)": TunicLocationData("none", "West Garden before Boss"), + "West Garden - West Garden Grass (-287.0, 4.0, 117.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (2) (-287.0, 4.0, 118.0)": TunicLocationData("none", "West Garden before Terry"), + "West Garden - West Garden Grass (174) (-243.9, 0.5, 52.1)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (262) (-244.8, 0.5, 51.3)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (263) (-244.8, 0.5, 52.3)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (179) (-334.0, 4.0, 103.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (176) (-335.0, 4.0, 103.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Grass (178) (-334.0, 4.0, 102.0)": TunicLocationData("none", "West Garden after Terry"), + "West Garden - West Garden Portal Grass (243) (-202.5, 8.0, -19.9)": TunicLocationData("none", "West Garden Portal"), + "West Garden - West Garden Portal Grass (244) (-203.4, 8.0, -20.9)": TunicLocationData("none", "West Garden Portal"), + "West Garden - West Garden Portal Grass (242) (-203.6, 8.0, -19.9)": TunicLocationData("none", "West Garden Portal"), + "West Garden - West Garden Portal Grass (233) (-197.4, 8.0, -20.9)": TunicLocationData("none", "West Garden Portal"), + "West Garden - West Garden Portal Grass (232) (-198.4, 8.0, -19.9)": TunicLocationData("none", "West Garden Portal"), + "West Garden - West Garden Portal Grass (234) (-197.4, 8.0, -19.9)": TunicLocationData("none", "West Garden Portal"), + "West Garden - West Garden Portal Grass (231) (-196.4, 8.0, -19.9)": TunicLocationData("none", "West Garden Portal"), + "West Garden - West Garden Laurels Exit Grass (261) (-182.8, 2.0, 75.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (259) (-183.8, 2.0, 75.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (258) (-184.8, 2.0, 75.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (260) (-183.8, 2.0, 74.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (404) (-172.1, 2.0, 80.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (402) (-172.1, 2.0, 82.5)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (299) (-172.1, 2.0, 81.5)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (403) (-173.4, 2.0, 81.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (401) (-173.4, 2.0, 82.5)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (269) (-162.5, 2.0, 75.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (267) (-161.3, 2.0, 75.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (268) (-161.3, 2.0, 74.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (273) (-152.8, 2.0, 73.5)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (271) (-154.0, 2.0, 72.5)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (272) (-152.8, 2.0, 72.5)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (270) (-154.0, 2.0, 71.3)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (274) (-137.0, 2.0, 75.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (277) (-136.0, 2.0, 74.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "West Garden - West Garden Laurels Exit Grass (276) (-136.0, 2.0, 75.0)": TunicLocationData("none", "West Garden Laurels Exit Region"), + "Ruined Atoll - Ruined Atoll Grass beach (132) (-17.0, 0.3, 59.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (133) (-17.0, 0.3, 60.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (131) (-16.0, 0.0, 59.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (130) (-16.0, 0.0, 60.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (129) (-15.0, 0.0, 60.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (134) (-15.0, 0.3, 61.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (139) (-20.0, 0.5, 47.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (140) (-20.0, 0.5, 48.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (138) (-19.0, 0.0, 46.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (137) (-19.0, 0.0, 47.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (136) (-19.0, 0.0, 48.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (141) (-20.0, 0.5, 49.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (135) (-19.0, 0.0, 49.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (109) (-30.3, 2.0, 40.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (106) (-31.3, 2.0, 40.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (107) (-31.3, 1.8, 39.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (110) (-32.3, 2.0, 39.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (108) (-30.3, 1.8, 39.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (111) (-31.3, 1.5, 38.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (123) (-27.8, 1.5, 61.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (121) (-27.8, 1.5, 62.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (118) (-27.8, 1.5, 63.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (122) (-26.8, 1.8, 62.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (117) (-26.8, 1.8, 63.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (115) (-26.8, 2.0, 64.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (114) (-25.8, 2.3, 64.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (113) (-25.8, 2.8, 65.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (112) (-26.8, 2.3, 65.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (119) (-27.8, 1.8, 64.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (120) (-27.8, 1.8, 65.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (179) (-30.3, 0.0, 23.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (176) (-31.3, 0.0, 22.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (178) (-31.3, 0.0, 23.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (177) (-30.3, 0.3, 22.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (174) (-31.3, 0.5, 21.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (180) (-30.3, 0.3, 21.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (182) (-32.0, 0.5, 17.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (183) (-31.0, 0.8, 17.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (184) (-31.0, 0.8, 16.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (185) (-32.0, 0.5, 16.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (186) (-32.0, 0.5, 15.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (187) (-33.0, 0.3, 15.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (126) (-29.3, 2.0, 3.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (116) (-28.3, 2.0, 3.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (128) (-28.3, 2.3, 4.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (127) (-29.3, 2.3, 4.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (143) (-27.3, 2.3, 5.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (142) (-28.3, 2.3, 5.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (147) (-26.3, 2.3, 5.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (146) (-26.3, 2.3, 6.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (145) (-27.3, 2.3, 6.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (171) (-34.3, 0.0, -6.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (170) (-34.3, 0.0, -7.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (156) (-33.3, 0.5, -8.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (173) (-33.3, 0.5, -7.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (172) (-33.3, 0.5, -6.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (157) (-34.3, 0.0, -8.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (144) (-32.3, 0.5, -8.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (125) (-32.3, 0.5, -9.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (155) (-32.3, 0.5, -8.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (124) (-33.3, 0.5, -9.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (152) (-19.3, 1.5, -5.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (151) (-19.3, 1.5, -4.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (158) (-17.3, 1.3, -6.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (159) (-17.3, 1.5, -5.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (161) (-16.3, 1.3, -5.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (153) (-20.3, 1.5, -5.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (150) (-20.3, 1.5, -4.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (149) (-21.3, 1.8, -4.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (154) (-21.3, 1.8, -5.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (148) (-22.3, 2.0, -4.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (166) (-16.3, 1.3, -8.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (169) (-15.3, 1.5, -9.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (162) (-16.3, 1.3, -7.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (165) (-15.3, 1.5, -8.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (163) (-15.3, 1.5, -7.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (160) (-16.3, 1.3, -6.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (164) (-15.3, 1.3, -6.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (168) (-14.3, 1.8, -9.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (167) (-14.3, 1.8, -8.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (181) (-20.5, 0.5, -16.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (188) (-19.5, 0.5, -16.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (189) (-19.5, 0.5, -17.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (175) (-20.5, 0.3, -17.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (192) (-20.5, 0.0, -18.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (190) (-21.5, 0.3, -17.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (191) (-21.5, -0.3, -18.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (21) (32.0, 0.9, 9.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (81) (30.0, 0.8, 7.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (82) (31.0, 0.8, 7.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (79) (31.0, 0.8, 9.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (19) (31.0, 0.6, 10.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (80) (30.0, 0.8, 9.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (83) (29.0, 0.8, 7.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (84) (29.0, 0.8, 8.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (20) (32.0, 0.8, 10.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (75) (41.0, 0.5, 9.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (77) (41.0, 0.5, 8.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (22) (42.0, 0.5, 9.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (78) (42.0, 0.5, 8.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (23) (42.0, 0.3, 10.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (76) (41.0, 0.5, 10.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (74) (42.0, 0.5, 11.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (25) (43.0, 0.3, 11.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (26) (43.0, 0.3, 10.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (91) (21.0, 1.3, 41.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (89) (22.0, 1.3, 40.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (28) (23.0, 1.0, 41.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (27) (23.0, 1.3, 40.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (93) (22.0, 1.0, 42.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (90) (22.0, 1.3, 41.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (92) (21.0, 1.0, 42.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (24) (24.0, 1.3, 40.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (29) (15.5, 0.8, 47.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (30) (15.5, 0.8, 48.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (33) (15.5, 0.8, 49.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (34) (15.5, 0.8, 50.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (31) (14.5, 0.8, 48.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (32) (14.5, 0.8, 49.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (86) (10.5, 3.0, 64.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (14) (9.5, 3.0, 64.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (35) (9.5, 2.5, 63.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (85) (8.5, 2.5, 63.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (15) (8.5, 3.0, 64.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (87) (24.0, 1.5, 64.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (18) (25.0, 1.5, 64.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (16) (25.0, 1.5, 65.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (17) (24.0, 1.5, 65.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (88) (23.0, 2.0, 65.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (237) (-99.0, 0.3, 61.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (393) (-100.0, 0.0, 62.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (226) (-100.0, 0.0, 61.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (228) (-99.0, 0.3, 60.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (227) (-100.0, 0.0, 60.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (390) (-99.0, 0.3, 59.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (260) (-83.7, 2.0, 19.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (261) (-83.7, 1.8, 18.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (259) (-82.5, 1.5, 18.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (257) (-82.5, 1.8, 19.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (258) (-81.2, 1.3, 18.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (256) (-81.2, 1.5, 19.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (255) (-80.5, 1.5, 14.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (254) (-80.5, 1.8, 13.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (249) (-79.5, 2.0, 12.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (248) (-79.5, 1.8, 13.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (251) (-80.5, 1.8, 11.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (252) (-80.5, 1.8, 12.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (247) (-79.5, 1.8, 14.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (246) (-79.5, 1.5, 15.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (253) (-79.5, 2.0, 10.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (250) (-79.5, 2.0, 11.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (264) (-53.8, 1.3, 14.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (265) (-53.8, 1.0, 13.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (263) (-52.8, 1.0, 14.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (266) (-53.8, 0.8, 12.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (262) (-52.8, 0.5, 13.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (267) (-53.3, 1.3, 20.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (270) (-54.3, 1.8, 20.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (268) (-53.3, 1.0, 21.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (269) (-54.3, 1.5, 21.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (272) (-69.5, 1.8, -23.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (273) (-69.5, 1.8, -23.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (271) (-69.5, 1.8, -22.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (274) (-70.2, 1.0, -33.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (275) (-70.2, 0.8, -34.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (277) (-69.2, 1.0, -33.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (278) (-69.2, 0.5, -34.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (276) (-69.2, 1.0, -34.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (279) (-68.2, 0.5, -34.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (193) (-88.2, 1.8, -52.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (194) (-88.2, 1.8, -53.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (195) (-88.2, 2.0, -54.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (197) (-87.2, 1.8, -53.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (196) (-87.2, 1.8, -54.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (192) (-97.2, 1.5, -66.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (191) (-96.5, 1.5, -66.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (189) (-96.5, 1.5, -67.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (190) (-95.5, 1.5, -67.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (187) (-95.5, 1.5, -68.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (188) (-96.5, 1.5, -68.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (186) (-95.5, 1.5, -69.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (185) (-96.0, 1.8, -72.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (184) (-96.0, 2.0, -73.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (183) (-96.5, 2.0, -73.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (169) (-100.5, 1.5, -74.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (165) (-99.5, 1.5, -75.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (167) (-101.5, 1.3, -75.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (168) (-101.5, 1.3, -74.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (170) (-102.5, 1.3, -74.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (166) (-100.5, 1.5, -75.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (176) (-103.5, 1.0, -68.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (172) (-103.5, 1.3, -69.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (179) (-102.5, 1.3, -67.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (180) (-101.5, 1.3, -67.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (181) (-101.5, 1.3, -66.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (177) (-103.5, 1.0, -67.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (182) (-102.5, 1.3, -66.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (171) (-103.5, 1.3, -70.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (173) (-104.5, 1.3, -69.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (175) (-104.5, 1.0, -68.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (178) (-104.5, 1.0, -67.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (174) (-104.5, 1.3, -70.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (153) (-98.0, 1.8, -80.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (156) (-99.0, 1.8, -80.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (148) (-96.7, 1.8, -82.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (151) (-96.7, 1.8, -83.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (152) (-96.7, 1.8, -84.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (150) (-95.7, 1.8, -83.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (149) (-95.7, 1.8, -82.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (155) (-95.7, 1.8, -84.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (154) (-95.7, 1.8, -85.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (145) (-91.5, 3.0, -87.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (146) (-91.5, 3.3, -86.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (144) (-90.5, 3.3, -87.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (143) (-89.5, 3.5, -87.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (147) (-90.5, 3.8, -86.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (142) (-89.5, 4.0, -86.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (158) (-102.8, 1.0, -91.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (157) (-102.8, 1.0, -92.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (159) (-104.0, 1.0, -92.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (160) (-104.0, 1.0, -93.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (161) (-102.0, 1.8, -97.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (162) (-101.0, 1.8, -97.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (163) (-102.0, 0.8, -98.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (122) (-85.7, 2.8, -94.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (141) (-85.5, 3.3, -89.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (139) (-85.5, 3.3, -90.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (140) (-84.5, 3.3, -90.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (121) (-84.7, 3.0, -94.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (118) (-83.7, 3.3, -94.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (120) (-84.7, 2.8, -95.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (119) (-83.7, 2.8, -95.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (125) (-78.2, 3.5, -94.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (128) (-78.2, 3.3, -95.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (127) (-78.2, 3.0, -96.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (126) (-79.2, 3.0, -96.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (123) (-79.2, 3.5, -95.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (124) (-79.2, 3.5, -94.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (113) (-83.7, 1.3, -104.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (114) (-83.7, 0.8, -105.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (115) (-82.7, 0.8, -105.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (112) (-82.7, 1.3, -104.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (109) (-80.7, 1.3, -104.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (116) (-80.7, 1.5, -103.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (111) (-81.7, 1.3, -104.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (117) (-81.7, 1.5, -103.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (17) (-37.0, 1.9, -82.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (18) (-36.0, 1.9, -82.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (22) (-35.0, 1.9, -82.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (24) (-35.0, 1.9, -81.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (20) (-36.0, 1.9, -81.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (19) (-37.0, 1.9, -81.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (21) (-34.0, 1.9, -81.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (27) (-34.0, 1.9, -80.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (23) (-34.0, 1.9, -82.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (26) (-35.0, 1.9, -80.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (28) (-35.0, 1.9, -79.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (25) (-34.0, 2.4, -79.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (30) (-29.0, 1.9, -85.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (31) (-28.0, 1.9, -85.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (38) (-28.0, 1.9, -86.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (39) (-28.0, 2.4, -87.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (32) (-29.0, 1.9, -84.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (35) (-27.0, 1.9, -85.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (37) (-27.0, 1.9, -86.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (40) (-27.0, 2.3, -87.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (29) (-28.0, 1.9, -84.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (34) (-27.0, 1.9, -84.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (33) (-26.0, 1.9, -84.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (36) (-26.0, 1.9, -85.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (80) (-26.2, 3.6, -74.6)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (78) (-26.2, 3.6, -73.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (81) (-25.2, 3.1, -74.6)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (77) (-25.2, 3.1, -73.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (79) (-27.3, 4.4, -73.6)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (82) (-24.1, 2.4, -73.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (10) (-14.0, 2.7, -76.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (9) (-14.0, 2.9, -77.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (1) (-12.0, 2.9, -77.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (4) (-13.0, 2.9, -77.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (3) (-13.0, 2.9, -76.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (8) (-13.0, 2.9, -78.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (2) (-12.0, 2.9, -78.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (-12.0, 2.9, -76.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (7) (-11.0, 3.1, -78.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (12) (-11.0, 2.8, -79.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (5) (-12.0, 2.9, -79.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (11) (-11.0, 2.6, -80.9)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (6) (-12.0, 2.4, -80.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (90) (-10.0, 1.9, -95.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (93) (-10.0, 1.9, -96.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (94) (-10.0, 1.9, -97.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (83) (-9.0, 1.9, -96.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (89) (-9.0, 1.9, -95.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (86) (-9.0, 1.9, -97.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (87) (-9.0, 1.9, -98.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (84) (-8.0, 1.9, -96.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (88) (-8.0, 1.9, -98.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (91) (-7.0, 1.9, -96.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (92) (-7.0, 1.9, -97.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (85) (-8.0, 1.9, -97.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (95) (-18.8, 0.8, -97.4)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (96) (-18.8, 0.9, -96.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (98) (-17.8, 0.9, -97.4)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (97) (-17.7, 1.1, -96.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (101) (-18.0, 0.7, -98.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (100) (-18.9, 0.6, -98.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (99) (-19.9, 0.7, -97.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (164) (-101.0, 1.5, -98.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (74) (-89.5, 7.8, -82.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (75) (-89.5, 7.8, -81.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (70) (-84.5, 8.0, -84.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (71) (-84.5, 8.0, -85.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (73) (-82.5, 8.0, -85.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (69) (-82.5, 8.0, -84.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (68) (-83.5, 8.0, -84.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (72) (-83.5, 8.0, -85.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (65) (-82.5, 8.0, -83.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (66) (-82.5, 8.0, -84.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (64) (-83.5, 8.0, -83.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (67) (-83.5, 8.0, -84.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (63) (-85.7, 13.3, -70.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (60) (-88.5, 12.8, -72.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (62) (-85.7, 13.8, -69.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (58) (-88.5, 13.3, -70.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (59) (-88.5, 12.8, -71.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (78) (-81.7, 15.0, -61.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (77) (-82.7, 15.0, -61.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (76) (-83.7, 15.0, -61.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (202) (-83.0, 15.0, -62.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (203) (-84.0, 15.0, -62.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (79) (-79.7, 18.3, -78.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (80) (-79.7, 18.0, -79.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (87) (-77.5, 25.0, -69.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (88) (-77.5, 25.0, -70.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (86) (-78.5, 25.0, -69.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (85) (-70.2, 25.0, -77.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (83) (-71.2, 25.0, -78.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (82) (-70.2, 25.0, -78.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (81) (-69.2, 25.0, -78.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (84) (-69.2, 25.0, -77.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (297) (-99.0, 0.8, 7.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (296) (-98.0, 0.8, 7.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (103) (-8.0, 1.8, -40.4)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (102) (-8.0, 1.8, -39.4)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (104) (-9.0, 1.8, -40.4)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (197) (-11.3, 1.5, -30.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (196) (-12.3, 1.3, -30.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (195) (-12.3, 1.0, -31.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (199) (-12.3, 1.0, -29.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (194) (-13.3, 0.8, -31.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (193) (-13.3, 0.8, -30.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (198) (-11.3, 1.3, -29.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (201) (-12.0, 0.0, -46.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (202) (-12.0, 0.3, -45.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (204) (-13.0, 0.0, -46.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (200) (-11.0, 0.0, -46.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (203) (-11.0, 0.3, -45.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (206) (-30.0, 0.3, -33.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (205) (-30.0, 0.3, -32.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (207) (-29.0, 0.0, -33.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (208) (-29.0, 0.0, -32.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (245) (48.0, 1.0, 51.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (242) (48.0, 0.8, 52.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (244) (47.3, 0.8, 51.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (243) (48.0, 0.8, 53.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (240) (47.3, 0.5, 53.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (241) (47.3, 0.8, 52.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (231) (46.3, 0.5, 53.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (239) (47.3, 0.5, 54.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (238) (46.3, 0.5, 54.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (235) (64.8, 0.8, 53.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (229) (64.8, 0.8, 54.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (234) (65.8, 0.5, 53.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (232) (65.8, 0.8, 54.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (233) (62.8, 0.8, 54.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (230) (63.8, 0.8, 54.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (236) (62.8, 0.8, 55.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (223) (68.5, 1.5, 52.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (224) (68.5, 1.5, 51.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (220) (69.5, 2.0, 52.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (221) (69.5, 2.0, 51.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (222) (68.5, 1.8, 53.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (219) (69.5, 2.0, 53.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (5) (53.5, 6.0, 70.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (4) (53.5, 6.0, 70.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (23) (52.5, 6.0, 70.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (25) (55.8, 6.0, 72.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (27) (56.8, 6.0, 74.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (26) (56.8, 6.0, 73.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (24) (55.8, 6.0, 73.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (43) (67.8, 5.8, 82.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (42) (68.8, 5.8, 82.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (33) (67.8, 5.8, 83.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (35) (69.8, 5.8, 83.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (41) (69.8, 5.8, 82.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (34) (68.8, 5.8, 83.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (49) (69.8, 5.8, 84.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (50) (70.8, 5.8, 84.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (46) (74.8, 5.8, 82.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (45) (75.8, 5.8, 82.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (44) (76.8, 5.8, 82.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (48) (76.8, 5.8, 83.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (47) (75.8, 5.8, 83.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (113) (72.5, 2.8, 87.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (111) (71.5, 2.8, 86.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (112) (72.5, 2.8, 86.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (114) (71.5, 2.8, 87.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (115) (70.5, 2.8, 87.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (110) (70.5, 2.8, 86.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (90) (69.8, 12.8, 80.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (30) (59.8, 7.8, 62.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (31) (58.8, 7.8, 62.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (32) (58.8, 8.0, 61.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (29) (59.8, 8.0, 61.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (28) (59.8, 8.3, 60.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (38) (68.5, 11.8, 59.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (39) (67.5, 11.8, 60.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (37) (68.5, 11.8, 60.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (108) (61.8, 12.8, 67.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (109) (61.8, 12.8, 68.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (89) (69.8, 12.8, 79.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (51) (68.8, 12.8, 79.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (91) (68.8, 12.8, 80.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (106) (64.5, 13.5, 63.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (107) (65.5, 14.0, 63.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (92) (64.5, 13.5, 64.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (200) (69.8, 15.8, 62.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (198) (70.8, 16.0, 62.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (95) (78.5, 18.8, 64.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (94) (79.5, 18.8, 64.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (93) (79.5, 18.8, 65.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (104) (75.5, 20.8, 66.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (105) (74.5, 20.8, 66.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (97) (63.8, 20.8, 69.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (96) (62.8, 20.8, 69.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (98) (62.8, 20.8, 68.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (103) (68.8, 20.8, 77.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (102) (69.8, 20.8, 77.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (99) (68.8, 20.8, 78.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (100) (69.8, 20.8, 78.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (101) (70.8, 20.8, 78.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (215) (72.3, 0.3, 26.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (216) (72.3, 0.3, 25.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (214) (73.3, 0.3, 26.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (217) (68.5, 1.3, 15.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (211) (68.5, 1.0, 14.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (212) (69.5, 1.3, 14.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (209) (69.5, 1.3, 13.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (213) (69.5, 1.3, 15.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (210) (68.5, 1.0, 13.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (218) (69.5, 1.3, 16.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (62.0, 2.0, 5.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (1) (62.0, 2.0, 4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (2) (63.0, 2.5, 4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (73) (54.5, 0.5, -1.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (72) (53.5, 0.5, -1.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (5) (54.5, 1.0, -2.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (6) (53.5, 0.5, -2.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (7) (53.5, 0.5, -3.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (70) (52.5, 0.5, -3.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (71) (52.5, 0.5, -2.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (4) (54.5, 0.5, -3.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (8) (54.5, 0.5, -4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (10) (55.5, 1.0, -3.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (9) (55.5, 0.5, -4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (382) (83.5, 3.3, 69.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (381) (83.5, 3.3, 70.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (379) (82.5, 3.5, 69.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (380) (82.5, 3.5, 70.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (372) (85.0, 3.3, 75.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (371) (85.0, 3.3, 76.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (370) (84.0, 3.5, 76.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (373) (84.0, 3.5, 77.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (374) (84.0, 3.5, 78.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (369) (84.0, 3.5, 75.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (378) (83.0, 4.0, 77.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (375) (84.0, 3.3, 79.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (377) (83.0, 4.0, 78.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (376) (83.0, 3.8, 79.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (368) (89.0, 2.0, 79.9)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (367) (88.0, 2.0, 79.9)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (366) (88.0, 2.3, 78.9)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (364) (89.0, 2.3, 78.9)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (365) (90.0, 2.3, 78.9)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (389) (92.6, 1.9, 72.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (388) (92.6, 2.2, 71.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (383) (93.6, 1.4, 72.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (384) (93.6, 1.9, 71.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (386) (94.6, 1.9, 70.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (385) (94.6, 1.7, 71.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (387) (93.6, 1.9, 70.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (357) (98.5, 3.5, 67.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (356) (99.5, 3.5, 67.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (360) (100.5, 3.5, 67.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (358) (99.5, 3.3, 68.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (359) (100.5, 3.3, 68.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (363) (102.5, 3.3, 67.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (355) (102.5, 3.5, 65.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (361) (103.5, 3.0, 65.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (362) (103.5, 2.8, 67.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (292) (68.3, 0.8, -39.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (293) (68.3, 0.8, -40.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (294) (69.5, 1.0, -41.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (290) (69.3, 1.0, -39.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (289) (69.3, 1.3, -40.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (291) (69.3, 0.8, -38.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (295) (70.3, 1.0, -41.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (287) (60.0, 1.0, -29.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (288) (60.0, 1.3, -28.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (286) (59.0, 0.8, -29.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (284) (59.0, 1.0, -28.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (285) (59.0, 1.3, -27.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (282) (58.0, 1.3, -27.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (283) (58.0, 0.8, -28.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (94) (36.5, 1.3, -20.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (36) (37.5, 1.3, -20.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (96) (37.5, 1.3, -21.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (95) (36.5, 1.3, -19.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (37) (37.5, 1.1, -19.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (38) (38.5, 0.9, -20.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (97) (38.5, 1.3, -21.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (50) (21.4, 0.8, -33.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (51) (21.4, 0.8, -34.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (60) (21.4, 0.8, -32.4)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (48) (20.4, 0.4, -34.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (59) (20.4, 0.4, -35.6)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (49) (20.4, 0.4, -33.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (63) (25.0, 0.5, -42.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (64) (24.0, 0.0, -42.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (61) (25.0, 0.4, -43.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (65) (24.0, 0.0, -43.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (62) (25.0, 0.5, -44.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (103) (26.0, 0.6, -44.4)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (104) (26.0, 0.5, -43.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (101) (33.5, 0.8, -38.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (100) (33.5, 0.8, -37.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (99) (32.5, 0.8, -36.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (67) (34.5, 0.6, -37.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (102) (34.5, 0.8, -38.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (66) (34.5, 0.6, -36.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (68) (33.5, 0.8, -36.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (98) (32.5, 0.8, -35.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (69) (33.5, 0.8, -35.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (46) (36.0, 0.1, -49.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (45) (36.0, 0.1, -48.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (47) (35.0, 0.3, -48.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (41) (33.5, 2.6, -72.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (40) (34.5, 3.1, -71.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (39) (34.5, 3.1, -72.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (42) (34.5, 3.1, -73.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (43) (39.0, 2.5, -74.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (44) (40.0, 2.5, -74.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (105) (40.0, 2.5, -74.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (54) (41.4, 1.3, -87.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (56) (40.4, 1.3, -86.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (55) (42.4, 1.0, -87.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (53) (41.4, 1.3, -86.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (52) (42.4, 1.0, -86.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (58) (41.5, 1.1, -85.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (57) (40.4, 1.3, -85.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (105) (30.3, 2.0, -106.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (107) (31.3, 2.0, -106.3)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (110) (30.5, 0.3, -109.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (106) (30.5, 0.5, -108.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (280) (31.5, 1.0, -108.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (108) (31.5, 1.0, -108.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (281) (31.5, 0.3, -109.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (61) (19.1, 2.1, -100.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (59) (19.1, 2.1, -101.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (63) (18.1, 2.1, -100.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (62) (18.1, 2.1, -99.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (64) (19.1, 2.0, -99.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (60) (18.1, 2.1, -101.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (44) (17.1, 2.1, -101.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (41) (16.1, 2.1, -101.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (45) (17.1, 2.1, -102.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (43) (16.1, 2.1, -103.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (42) (16.1, 2.1, -102.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (58) (18.1, 2.1, -102.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (46) (17.1, 2.1, -103.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (57) (19.1, 2.1, -102.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (48) (16.1, 2.1, -104.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (47) (17.1, 2.1, -104.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (52) (18.1, 2.1, -97.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (50) (18.1, 2.1, -96.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (53) (18.1, 2.1, -95.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (55) (18.1, 2.1, -94.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (54) (17.1, 2.1, -95.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (49) (17.1, 2.1, -97.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (51) (17.1, 2.1, -96.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (56) (17.1, 2.1, -94.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (66) (16.1, 2.1, -110.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (68) (16.1, 2.1, -111.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (65) (17.1, 2.1, -110.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (67) (17.1, 2.1, -111.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (72) (18.1, 2.1, -111.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (71) (18.1, 2.1, -110.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (73) (18.1, 2.1, -109.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (74) (19.1, 2.1, -109.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (70) (19.1, 2.1, -110.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (76) (18.1, 2.1, -108.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (75) (19.1, 2.1, -108.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (69) (19.1, 2.1, -111.1)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (130) (-3.5, 0.5, -116.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (131) (-3.5, 0.5, -117.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (129) (-2.5, 0.3, -116.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (132) (-2.5, 0.3, -117.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (133) (-2.5, 0.3, -118.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (138) (8.0, 0.5, -124.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (137) (8.0, 0.0, -125.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (135) (10.0, 0.5, -124.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (136) (9.0, 0.0, -125.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (134) (9.0, 0.5, -124.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (395) (67.8, 2.5, -80.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (394) (67.8, 2.5, -79.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (391) (66.8, 2.5, -79.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (397) (68.8, 2.5, -79.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (396) (66.8, 2.5, -80.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (392) (65.8, 2.5, -79.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (400) (63.3, 2.8, -74.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (399) (64.3, 3.0, -74.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (401) (63.3, 2.8, -73.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (398) (64.3, 3.0, -73.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (402) (62.3, 2.5, -73.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (405) (60.5, 1.3, -68.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (404) (59.5, 0.5, -68.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (406) (60.5, 1.3, -69.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (403) (59.5, 0.5, -69.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (407) (61.5, 1.5, -69.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (325) (-111.8, 1.3, 2.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (323) (-111.8, 1.3, 1.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (316) (-110.5, 1.3, 3.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (319) (-111.5, 1.3, 4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (317) (-111.5, 1.3, 3.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (318) (-110.5, 1.3, 4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (321) (-112.3, 1.3, 4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (320) (-112.3, 1.3, 3.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (326) (-112.8, 1.3, 2.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (327) (-113.5, 1.3, 2.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (324) (-112.8, 1.3, 1.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (322) (-113.5, 1.3, 1.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (328) (-112.0, 0.8, -2.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (329) (-112.0, 0.5, -3.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (333) (-111.3, 0.8, -2.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (331) (-111.3, 0.5, -3.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (330) (-110.3, 0.5, -3.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (332) (-110.3, 0.8, -2.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (334) (-111.0, 0.3, -4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (337) (-110.3, 0.3, -4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (354) (-113.0, 0.3, -4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (353) (-112.0, 0.3, -4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (336) (-109.3, 0.3, -4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (338) (-109.3, -0.3, -5.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (339) (-110.3, -0.3, -5.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (335) (-111.0, -0.3, -5.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (350) (-112.0, -0.3, -5.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (349) (-113.8, 0.3, -4.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (351) (-113.0, -0.3, -5.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (352) (-113.8, -0.3, -5.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (314) (-112.3, 0.8, 6.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (315) (-112.3, 0.8, 7.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (313) (-111.5, 0.8, 6.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (311) (-111.5, 0.8, 7.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (310) (-110.5, 0.8, 7.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (306) (-110.5, 0.8, 8.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (312) (-110.5, 0.8, 6.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (307) (-109.5, 0.8, 8.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (308) (-111.5, 0.8, 8.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (300) (-107.5, 0.0, 10.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (301) (-107.5, 0.3, 9.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (304) (-108.3, 0.0, 10.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (299) (-108.5, 0.0, 10.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (303) (-110.5, 0.3, 9.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (302) (-109.5, 0.3, 9.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (305) (-109.5, 0.0, 10.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (298) (-108.5, 0.3, 9.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (341) (-113.5, 0.8, 10.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (344) (-113.5, 0.5, 11.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (346) (-113.5, 0.8, 9.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (309) (-111.5, 0.5, 9.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (345) (-112.5, 0.8, 9.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (342) (-112.5, 0.8, 8.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (340) (-112.5, 0.8, 10.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (347) (-114.3, 0.8, 8.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (348) (-114.3, 0.8, 9.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass beach (343) (-113.5, 0.8, 8.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (191) (-89.5, 6.5, 53.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (190) (-89.5, 6.5, 54.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (189) (-88.5, 6.5, 54.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (188) (-88.5, 6.5, 53.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (197) (-87.0, 13.0, 75.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (194) (-87.0, 13.0, 74.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (184) (-86.0, 13.0, 73.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (183) (-86.0, 13.0, 74.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (181) (-86.0, 13.0, 75.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (185) (-84.7, 13.0, 73.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (182) (-83.0, 13.0, 72.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (199) (-83.0, 13.0, 70.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (201) (-84.0, 13.0, 70.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (135) (-83.5, 13.0, 58.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (128) (-82.5, 13.0, 57.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (130) (-82.5, 13.0, 58.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (147) (-86.0, 13.0, 54.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (132) (-82.5, 13.0, 60.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (134) (-83.5, 13.0, 59.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (131) (-82.5, 13.0, 59.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (136) (-78.5, 13.0, 56.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (139) (-79.5, 13.0, 55.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (133) (-79.5, 13.0, 56.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (138) (-80.5, 13.0, 55.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (137) (-80.5, 13.0, 56.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (143) (-85.0, 13.0, 53.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (142) (-86.0, 13.0, 53.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (145) (-87.0, 13.0, 53.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (146) (-87.0, 13.0, 54.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (140) (-85.0, 13.0, 52.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (141) (-86.0, 13.0, 52.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (144) (-84.0, 13.0, 52.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (192) (-70.5, 13.0, 56.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (186) (-69.5, 13.0, 56.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (187) (-69.5, 13.0, 55.8)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (123) (-82.5, 13.0, 44.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (126) (-82.5, 13.0, 45.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (121) (-83.5, 13.0, 45.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (124) (-83.5, 13.0, 44.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (125) (-83.5, 13.0, 43.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (151) (-82.5, 13.0, 27.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (152) (-82.5, 13.0, 26.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (150) (-81.5, 13.0, 27.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (148) (-81.5, 13.0, 25.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (149) (-81.5, 13.0, 26.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (154) (-79.0, 13.0, 23.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (153) (-78.0, 13.0, 23.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (161) (-68.0, 13.0, 26.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (162) (-68.0, 13.0, 27.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (165) (-69.0, 13.0, 27.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (164) (-69.0, 13.0, 28.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (163) (-68.0, 13.0, 28.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (166) (-68.0, 13.0, 29.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (167) (-63.0, 13.0, 24.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (168) (-62.0, 13.0, 24.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (170) (-61.0, 13.0, 25.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (169) (-62.0, 13.0, 25.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (172) (-62.0, 13.0, 26.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (178) (-61.0, 13.0, 43.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (175) (-60.0, 13.0, 43.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (177) (-61.0, 13.0, 44.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (174) (-59.0, 13.0, 42.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (173) (-59.0, 13.0, 43.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (171) (-59.0, 13.0, 44.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (176) (-60.0, 13.0, 44.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (159) (-83.5, 8.0, 23.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (160) (-83.5, 8.0, 24.5)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (158) (-83.5, 8.0, 22.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (155) (-82.5, 8.0, 24.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (157) (-82.5, 8.0, 22.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Grass (156) (-82.5, 8.0, 23.0)": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (413) (-10.3, 0.3, 128.5)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (414) (-10.3, 0.3, 127.5)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (412) (-11.3, 0.0, 129.5)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (411) (-11.3, 0.0, 128.5)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (410) (-11.3, 0.0, 127.5)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (408) (-4.0, 1.0, 118.0)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (13) (-4.0, 1.0, 116.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (12) (-3.0, 1.0, 116.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (409) (-3.0, 0.8, 115.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (11) (-3.0, 1.0, 117.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (3) (-3.0, 1.0, 118.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass (129) (32.5, 0.8, 84.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass (179) (33.5, 0.8, 84.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass (180) (34.5, 0.8, 84.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass (195) (33.5, 0.3, 85.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass (193) (35.3, 0.8, 84.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass (196) (34.5, 0.3, 85.8)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (418) (54.5, 0.8, 78.3)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (419) (54.5, 0.8, 77.3)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (417) (55.8, 0.8, 78.3)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (416) (55.8, 1.0, 77.3)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Lower Entry Area Grass beach (415) (56.8, 0.8, 78.3)": TunicLocationData( + "Ruined Atoll Lower Entry Area", "Ruined Atoll Lower Entry Area"), + "Ruined Atoll - Ruined Atoll Frog Mouth Grass (20) (87.5, 12.5, 59.0)": TunicLocationData("Ruined Atoll Frog Mouth", + "Ruined Atoll Frog Mouth"), + "Ruined Atoll - Ruined Atoll Frog Mouth Grass (17) (86.5, 12.5, 59.0)": TunicLocationData("Ruined Atoll Frog Mouth", + "Ruined Atoll Frog Mouth"), + "Ruined Atoll - Ruined Atoll Frog Mouth Grass (16) (86.5, 12.5, 60.0)": TunicLocationData("Ruined Atoll Frog Mouth", + "Ruined Atoll Frog Mouth"), + "Ruined Atoll - Ruined Atoll Frog Mouth Grass (21) (87.5, 12.5, 60.0)": TunicLocationData("Ruined Atoll Frog Mouth", + "Ruined Atoll Frog Mouth"), + "Ruined Atoll - Ruined Atoll Frog Mouth Grass (15) (91.5, 12.5, 58.0)": TunicLocationData("Ruined Atoll Frog Mouth", + "Ruined Atoll Frog Mouth"), + "Ruined Atoll - Ruined Atoll Frog Mouth Grass (14) (91.5, 12.5, 57.0)": TunicLocationData("Ruined Atoll Frog Mouth", + "Ruined Atoll Frog Mouth"), + "Ruined Atoll - Ruined Atoll Frog Mouth Grass (13) (92.5, 12.5, 57.0)": TunicLocationData("Ruined Atoll Frog Mouth", + "Ruined Atoll Frog Mouth"), + "Ruined Atoll - Ruined Atoll Frog Mouth Grass (12) (92.5, 12.5, 58.0)": TunicLocationData("Ruined Atoll Frog Mouth", + "Ruined Atoll Frog Mouth"), + "Ruined Atoll - Ruined Atoll Frog Mouth Grass (10) (93.5, 12.5, 57.0)": TunicLocationData("Ruined Atoll Frog Mouth", + "Ruined Atoll Frog Mouth"), + "Ruined Atoll - Ruined Atoll Frog Mouth Grass (11) (93.5, 12.5, 58.0)": TunicLocationData("Ruined Atoll Frog Mouth", + "Ruined Atoll Frog Mouth"), + "Frog Stairway - Frog Stairs Upper Grass (24) (187.0, 106.0, -65.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (23) (188.0, 106.0, -65.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (22) (189.0, 106.0, -64.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (20) (188.0, 106.0, -64.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (17) (187.0, 106.0, -64.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (14) (191.0, 106.0, -64.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (12) (192.0, 106.0, -63.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (15) (191.0, 106.0, -63.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (13) (192.0, 106.0, -64.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (25) (192.0, 106.0, -65.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (16) (189.0, 106.0, -63.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (21) (188.0, 106.0, -63.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (10) (193.0, 106.0, -64.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (11) (193.0, 106.0, -63.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (26) (193.0, 106.0, -62.0)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Upper Grass (27) (196.6, 106.0, -62.5)": TunicLocationData("Frog Stairs Upper", + "Frog Stairs Upper"), + "Frog Stairway - Frog Stairs Lower Grass (9) (179.8, 61.9, -67.1)": TunicLocationData("Frog Stairs Lower", + "Frog Stairs Lower"), + "Frog Stairway - Frog Stairs Lower Grass (8) (178.6, 61.9, -67.1)": TunicLocationData("Frog Stairs Lower", + "Frog Stairs Lower"), + "Frog Stairway - Frog Stairs Lower Grass (7) (204.4, 58.1, -94.1)": TunicLocationData("Frog Stairs Lower", + "Frog Stairs Lower"), + "Frog Stairway - Frog Stairs Lower Grass (5) (205.5, 58.1, -94.1)": TunicLocationData("Frog Stairs Lower", + "Frog Stairs Lower"), + "Frog Stairway - Frog Stairs Lower Grass (6) (205.5, 58.1, -93.0)": TunicLocationData("Frog Stairs Lower", + "Frog Stairs Lower"), + "Frog Stairway - Frog Stairs Lower Grass (2) (205.5, 54.0, -77.0)": TunicLocationData("Frog Stairs Lower", + "Frog Stairs Lower"), + "Frog Stairway - Frog Stairs Lower Grass (205.5, 54.0, -76.0)": TunicLocationData("Frog Stairs Lower", + "Frog Stairs Lower"), + "Frog Stairway - Frog Stairs Lower Grass (1) (204.5, 54.0, -76.0)": TunicLocationData("Frog Stairs Lower", + "Frog Stairs Lower"), + "Frog Stairway - Frog Stairs Lower Grass (4) (201.4, 54.3, -71.3)": TunicLocationData("Frog Stairs Lower", + "Frog Stairs Lower"), + "Frog Stairway - Frog Stairs Lower Grass (3) (200.4, 54.3, -71.3)": TunicLocationData("Frog Stairs Lower", + "Frog Stairs Lower"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (77) (-8.8, -4.0, -169.5)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (78) (-7.8, -4.0, -169.5)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (81) (-7.8, -4.0, -168.5)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (80) (-6.8, -4.0, -168.5)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (79) (-6.8, -4.0, -169.5)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Bush (8) (-7.3, -4.0, -171.0)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (25) (-5.5, -4.0, -150.0)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (28) (-4.5, -4.0, -151.0)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (26) (-4.5, -4.0, -150.0)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (24) (-3.3, -4.0, -149.0)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (23) (-4.5, -4.0, -149.0)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (22) (-8.3, -4.0, -138.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (21) (-7.3, -4.0, -138.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (18) (-7.3, -4.0, -137.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (20) (-8.3, -4.0, -137.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (13) (-2.0, -4.0, -137.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (17) (-1.0, -4.0, -138.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (14) (-1.0, -4.0, -137.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (16) (0.0, -4.0, -138.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (15) (0.0, -4.0, -137.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Bush (6) (-18.0, -4.0, -145.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (12) (-18.3, -4.0, -144.0)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (10) (-17.0, -4.0, -142.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (11) (-18.3, -4.0, -142.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (76) (-17.3, -4.0, -151.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (74) (-17.3, -4.0, -152.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (438) (-18.3, -4.0, -150.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (75) (-18.3, -4.0, -151.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (73) (-18.3, -4.0, -152.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (32) (-2.5, -4.0, -156.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (29) (-1.5, -4.0, -156.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (31) (-2.5, -4.0, -157.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from East Forest Grass (30) (-1.5, -4.0, -157.8)": TunicLocationData( + "Fortress Exterior from East Forest", "Fortress Exterior from East Forest"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (44) (-26.8, -5.0, -135.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (39) (-26.8, -5.0, -134.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (38) (-26.8, -5.0, -133.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (41) (-28.8, -5.0, -134.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (37) (-27.8, -5.0, -133.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (40) (-27.8, -5.0, -134.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (43) (-27.8, -5.0, -135.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (42) (-28.8, -5.0, -135.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (49) (-21.5, -5.0, -133.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (47) (-20.5, -5.0, -134.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (48) (-21.5, -5.0, -132.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (46) (-20.5, -5.0, -133.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (45) (-20.5, -5.0, -132.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (34) (-16.8, -5.5, -126.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (27) (-17.8, -5.6, -125.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (33) (-17.8, -5.5, -126.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (19) (-16.8, -5.5, -125.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (154) (-20.0, -4.5, -118.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (155) (-19.0, -4.5, -118.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (153) (-20.0, -4.5, -117.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (152) (-19.0, -4.5, -117.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (157) (-26.0, -5.0, -116.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (156) (-26.0, -5.0, -117.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (158) (-25.0, -5.0, -117.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (160) (-26.0, -5.0, -118.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (159) (-25.0, -5.0, -118.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (58) (-24.5, -4.5, -110.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (57) (-24.5, -4.5, -109.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (56) (-24.5, -4.5, -108.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (55) (-25.5, -4.5, -108.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (54) (-25.5, -4.5, -109.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (59) (-25.5, -4.5, -110.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (53) (-26.5, -4.5, -109.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (52) (-18.5, -4.3, -109.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (50) (-18.5, -4.3, -108.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (51) (-19.5, -4.3, -108.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (67) (-14.5, 0.0, -94.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (63) (-15.5, 0.0, -93.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (66) (-13.5, 0.0, -94.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (64) (-14.5, 0.0, -93.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (69) (-16.5, 0.0, -93.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (1) (-17.3, 0.0, -95.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (62) (-15.5, 0.0, -92.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (68) (-16.5, 0.0, -92.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (60) (-13.5, 0.0, -92.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (65) (-13.5, 0.0, -93.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (61) (-14.5, 0.0, -92.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (-12.0, 0.0, -94.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (3) (-7.3, 0.0, -102.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (2) (-9.3, 0.0, -102.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (4) (-7.3, 0.0, -104.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (72) (-5.8, 0.0, -91.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (70) (-4.8, 0.0, -90.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (71) (-5.8, 0.0, -90.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (8) (9.0, 0.0, -90.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (7) (8.0, 0.0, -90.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (9) (7.0, 0.0, -89.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (5) (9.0, 0.0, -89.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (6) (8.0, 0.0, -89.8)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (5) (4.8, 0.0, -90.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (84) (1.8, 0.0, -74.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (122) (3.0, 0.0, -74.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (82) (-1.8, 0.0, -74.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (86) (-1.8, 0.0, -75.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (83) (-2.8, 0.0, -74.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (87) (-2.8, 0.0, -75.3)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (85) (-2.6, 0.0, -71.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (88) (-3.6, 0.0, -71.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (89) (-2.6, 0.0, -70.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (11) (-15.5, 0.0, -70.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (7) (-17.5, 0.0, -68.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (9) (-15.5, 0.0, -68.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (164) (-26.0, 0.0, -74.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (163) (-25.0, 0.0, -74.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (168) (-24.3, 0.0, -74.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (167) (-23.3, 0.0, -74.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (162) (-25.0, 0.0, -75.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (161) (-26.0, 0.0, -75.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (166) (-23.3, 0.0, -75.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (165) (-24.3, 0.0, -75.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (102) (-26.0, 0.0, -82.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (13) (-28.5, 0.0, -83.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (103) (-24.0, 0.0, -83.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (101) (-25.0, 0.0, -82.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (100) (-25.0, 0.0, -83.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (99) (-26.0, 0.0, -83.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (12) (-30.5, 0.0, -85.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Bush (10) (-28.5, 0.0, -85.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (110) (-34.0, 0.0, -85.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (111) (-35.0, 0.0, -84.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (109) (-35.0, 0.0, -85.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (106) (-21.0, 0.0, -85.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (107) (-20.0, 0.0, -85.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (104) (-20.0, 0.0, -86.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (105) (-21.0, 0.0, -86.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (108) (-19.0, 0.0, -86.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (93) (-41.5, 0.0, -61.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (92) (-40.5, 0.0, -61.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (90) (-41.5, 0.0, -60.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (91) (-40.5, 0.0, -60.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (97) (-52.0, 0.0, -63.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (95) (-52.0, 0.0, -62.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (96) (-51.0, 0.0, -62.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (94) (-53.0, 0.0, -62.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (98) (-53.0, 0.0, -63.5)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (2) (11.0, 9.0, -92.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (3) (11.0, 9.0, -93.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior from Overworld Grass (4) (10.0, 9.0, -92.0)": TunicLocationData( + "Fortress Exterior from Overworld", "Fortress Exterior from Overworld"), + "Fortress Courtyard - Fortress Exterior near cave Grass (113) (-54.0, 0.0, -34.0)": TunicLocationData( + "Fortress Exterior near cave", "Fortress Exterior near cave"), + "Fortress Courtyard - Fortress Exterior near cave Grass (112) (-54.0, 0.0, -33.0)": TunicLocationData( + "Fortress Exterior near cave", "Fortress Exterior near cave"), + "Fortress Courtyard - Fortress Exterior near cave Grass (114) (-55.0, 0.0, -33.0)": TunicLocationData( + "Fortress Exterior near cave", "Fortress Exterior near cave"), + "Fortress Courtyard - Fortress Exterior near cave Grass (115) (-50.0, 0.0, -43.5)": TunicLocationData( + "Fortress Exterior near cave", "Fortress Exterior near cave"), + "Fortress Courtyard - Fortress Exterior near cave Grass (116) (-50.0, 0.0, -44.5)": TunicLocationData( + "Fortress Exterior near cave", "Fortress Exterior near cave"), + "Fortress Courtyard - Fortress Courtyard Grass (355) (-14.0, 0.0, -30.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (353) (-14.0, 0.0, -30.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (346) (-13.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (348) (-13.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (344) (-13.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (349) (-12.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (347) (-12.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (354) (-15.0, 0.0, -30.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (342) (-15.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (352) (-15.0, 0.0, -30.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (340) (-15.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (350) (-15.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (341) (-14.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (343) (-14.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (351) (-14.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (345) (-12.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (339) (-14.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (325) (-13.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (324) (-13.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (315) (-16.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (309) (-16.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (317) (-16.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (316) (-17.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (314) (-17.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (321) (-14.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (323) (-14.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (313) (-14.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (311) (-14.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (319) (-14.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (310) (-15.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (312) (-15.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (318) (-15.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (338) (-15.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (320) (-15.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (322) (-15.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (300) (-17.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (304) (-17.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (302) (-17.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (305) (-16.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (301) (-16.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (303) (-16.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (306) (-15.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (307) (-15.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (308) (-17.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (295) (-16.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (293) (-16.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (288) (-14.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (289) (-14.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (283) (-15.0, 0.0, -19.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (287) (-15.0, 0.0, -20.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (285) (-15.0, 0.0, -20.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (272) (-18.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (278) (-18.0, 0.0, -19.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (291) (-18.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (280) (-18.0, 0.0, -20.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (274) (-16.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (284) (-16.0, 0.0, -20.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (282) (-16.0, 0.0, -19.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (286) (-16.0, 0.0, -20.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (276) (-16.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (281) (-17.0, 0.0, -20.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (294) (-17.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (279) (-17.0, 0.0, -19.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (273) (-17.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (292) (-17.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (290) (-19.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (296) (-19.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (299) (-18.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (297) (-18.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (298) (-19.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (277) (-15.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (275) (-15.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (135) (-14.8, 0.0, -6.5)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (133) (-13.8, 0.0, -6.5)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (134) (-13.8, 0.0, -7.5)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (132) (-12.8, 0.0, -7.5)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (131) (-12.8, 0.0, -6.5)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (367) (-29.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (365) (-29.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (363) (-29.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (368) (-28.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (369) (-27.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (373) (-27.0, 0.0, -30.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (371) (-27.0, 0.0, -30.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (362) (-30.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (364) (-30.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (366) (-30.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (356) (-30.0, 0.0, -30.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (357) (-29.0, 0.0, -30.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (361) (-29.0, 0.0, -31.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (359) (-29.0, 0.0, -31.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (358) (-30.0, 0.0, -31.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (360) (-30.0, 0.0, -31.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (372) (-28.0, 0.0, -30.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (370) (-28.0, 0.0, -30.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (117) (-15.9, 2.9, -44.6)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (120) (-14.9, 3.1, -45.6)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (118) (-14.9, 3.1, -44.6)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (121) (-13.8, 3.4, -44.6)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (328) (7.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (334) (4.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (336) (4.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (335) (5.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (337) (5.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (333) (6.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (332) (6.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (327) (9.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (329) (8.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (331) (8.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (330) (7.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (264) (12.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (262) (12.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (226) (12.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (249) (11.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (326) (9.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (246) (10.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (248) (10.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (247) (11.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (254) (12.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (260) (12.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (252) (12.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (256) (10.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (257) (11.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (228) (12.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (236) (12.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (227) (13.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (237) (13.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (229) (13.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (261) (13.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (259) (11.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (258) (10.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (238) (12.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (239) (13.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (270) (16.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (268) (16.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (233) (15.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (245) (15.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (241) (15.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (243) (15.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (235) (15.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (244) (14.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (232) (14.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (234) (14.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (240) (14.0, 0.0, -28.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (242) (14.0, 0.0, -29.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (269) (17.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (267) (17.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (271) (17.0, 0.0, -27.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (266) (16.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (224) (16.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (222) (16.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (231) (15.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (219) (15.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (230) (14.0, 0.0, -26.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (218) (14.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (265) (13.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (263) (13.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (220) (16.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (217) (15.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (209) (15.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (216) (14.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (208) (14.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (255) (13.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (253) (13.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (207) (15.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (210) (16.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (214) (16.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (212) (16.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (198) (18.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (223) (17.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (221) (17.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (225) (17.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (196) (18.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (195) (21.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (193) (21.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (191) (21.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (194) (20.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (190) (20.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (200) (20.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (192) (20.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (183) (19.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (197) (19.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (185) (19.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (189) (19.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (187) (19.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (184) (18.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (186) (18.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (182) (18.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (188) (18.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (215) (17.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (213) (17.0, 0.0, -23.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (211) (17.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (176) (18.0, 0.0, -19.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (180) (18.0, 0.0, -20.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (174) (18.0, 0.0, -19.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (179) (17.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (35) (17.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (171) (17.0, 0.0, -19.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (169) (17.0, 0.0, -20.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (16.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (36) (16.0, 0.0, -20.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (178) (16.0, 0.0, -21.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (170) (16.0, 0.0, -19.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (206) (14.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (251) (13.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (250) (12.0, 0.0, -22.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (199) (19.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (181) (19.0, 0.0, -20.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (173) (19.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (177) (19.0, 0.0, -19.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (175) (19.0, 0.0, -19.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (172) (18.0, 0.0, -18.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (202) (20.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (204) (20.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (201) (21.0, 0.0, -24.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (203) (21.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (205) (21.0, 0.0, -25.0)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (126) (26.8, 0.0, -15.8)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (127) (25.8, 0.0, -15.8)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (125) (26.8, 0.0, -14.8)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (128) (25.8, 0.0, -14.8)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (119) (-21.8, 2.0, -51.3)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (130) (-20.8, 2.0, -50.3)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (129) (-20.8, 2.0, -51.3)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (124) (16.5, 0.0, -6.5)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Grass (123) (17.5, 0.0, -6.5)": TunicLocationData("Fortress Courtyard", + "Fortress Courtyard"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (421) (32.5, 8.0, -41.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (143) (32.5, 8.0, -42.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (145) (32.5, 8.0, -43.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (419) (32.5, 8.0, -41.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (382) (36.5, 8.0, -39.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (384) (36.5, 8.0, -39.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (380) (36.5, 8.0, -38.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (383) (37.5, 8.0, -39.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (385) (37.5, 8.0, -39.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (381) (37.5, 8.0, -38.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (144) (31.5, 8.0, -43.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (142) (31.5, 8.0, -42.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (141) (37.5, 8.0, -35.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (375) (37.5, 8.0, -36.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (379) (37.5, 8.0, -37.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (377) (37.5, 8.0, -37.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (374) (36.5, 8.0, -36.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (376) (36.5, 8.0, -37.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (140) (36.5, 8.0, -35.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (378) (36.5, 8.0, -37.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (431) (35.5, 8.0, -38.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (429) (35.5, 8.0, -37.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (433) (35.5, 8.0, -38.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (432) (34.5, 8.0, -38.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (430) (34.5, 8.0, -38.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (415) (32.5, 8.0, -39.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (413) (32.5, 8.0, -39.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (408) (32.5, 8.0, -36.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (411) (32.5, 8.0, -38.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (409) (32.5, 8.0, -37.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (405) (32.5, 8.0, -35.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (407) (31.5, 8.0, -37.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (404) (31.5, 8.0, -36.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (423) (34.5, 8.0, -35.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (427) (34.5, 8.0, -36.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (428) (34.5, 8.0, -37.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (425) (34.5, 8.0, -36.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (424) (33.5, 8.0, -36.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (422) (33.5, 8.0, -35.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (426) (33.5, 8.0, -36.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (416) (31.5, 8.0, -40.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (414) (31.5, 8.0, -39.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (412) (31.5, 8.0, -39.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (410) (31.5, 8.0, -38.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (417) (32.5, 8.0, -40.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (420) (31.5, 8.0, -41.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (418) (31.5, 8.0, -41.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (138) (36.5, 8.0, -34.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (137) (37.5, 8.0, -34.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (136) (37.5, 8.0, -33.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (139) (36.5, 8.0, -33.5)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (406) (31.5, 8.0, -35.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (396) (36.5, 8.0, -22.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (394) (36.5, 8.0, -22.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (389) (36.5, 8.0, -20.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (398) (36.5, 8.0, -23.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (392) (36.5, 8.0, -21.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (397) (37.5, 8.0, -22.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (391) (37.5, 8.0, -20.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (395) (37.5, 8.0, -22.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (393) (37.5, 8.0, -21.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (401) (37.5, 8.0, -24.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (399) (37.5, 8.0, -23.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (436) (37.5, 8.0, -25.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (403) (37.5, 8.0, -24.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (400) (36.5, 8.0, -24.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (402) (36.5, 8.0, -24.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (437) (36.5, 8.0, -25.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (390) (37.5, 8.0, -19.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (387) (37.5, 8.0, -18.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (388) (36.5, 8.0, -18.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (386) (36.5, 8.0, -19.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (435) (37.5, 8.0, -26.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (434) (36.5, 8.0, -26.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (150) (31.8, 8.0, -9.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (146) (31.8, 8.0, -7.8)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (147) (32.8, 8.0, -7.8)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (149) (32.8, 8.0, -6.8)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (151) (32.8, 8.0, -9.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (148) (31.8, 8.0, -6.8)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Fortress Courtyard - Fortress Courtyard Upper Grass (1) (72.0, 8.0, -29.0)": TunicLocationData( + "Fortress Courtyard Upper", "Fortress Courtyard Upper"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (12) (-94.8, 7.0, 41.0)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (14) (-94.8, 7.0, 42.0)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (15) (-95.8, 7.0, 41.0)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (13) (-95.8, 7.0, 42.0)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (23) (-60.5, -1.0, 38.5)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (20) (-59.5, -1.0, 38.5)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (21) (-60.5, -1.0, 39.5)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (22) (-59.5, -1.0, 39.5)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (10) (-42.0, -1.0, 17.0)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (9) (-41.0, -1.0, 17.0)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (11) (-42.0, -1.0, 18.0)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (8) (-41.0, -1.0, 18.0)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (4) (-3.3, 7.0, 63.8)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (5) (-3.3, 7.0, 62.8)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (6) (-4.3, 7.0, 63.8)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (7) (-4.3, 7.0, 62.8)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (2) (6.3, 7.0, 66.3)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (3) (5.3, 7.0, 66.3)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (1) (6.3, 7.0, 67.3)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - Eastern Vault Fortress Grass (5.3, 7.0, 67.3)": TunicLocationData( + "Eastern Vault Fortress", "Eastern Vault Fortress"), + "Fortress Grave Path - Fortress Grave Path Grass (90) (122.0, 0.0, -40.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (88) (121.0, 0.0, -40.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (89) (122.0, 0.0, -41.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (91) (121.0, 0.0, -41.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (95) (121.0, 0.0, -42.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (92) (121.0, 0.0, -43.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (93) (122.0, 0.0, -42.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (94) (122.0, 0.0, -43.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (44) (132.0, 0.0, -42.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (72) (132.0, 0.0, -45.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (85) (131.0, 0.0, -45.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (46) (133.0, 0.0, -42.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (74) (133.0, 0.0, -45.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (47) (132.0, 0.0, -41.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (56) (134.0, 0.0, -43.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (51) (134.0, 0.0, -42.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (59) (134.0, 0.0, -44.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (49) (135.0, 0.0, -42.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (48) (134.0, 0.0, -41.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (45) (133.0, 0.0, -41.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (43) (132.0, 0.0, -40.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (52) (134.0, 0.0, -40.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (41) (133.0, 0.0, -40.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (87) (130.0, 0.0, -45.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (86) (131.0, 0.0, -46.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (84) (130.0, 0.0, -46.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (83) (130.0, 0.0, -48.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (80) (130.0, 0.0, -47.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (75) (132.0, 0.0, -46.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (82) (131.0, 0.0, -47.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (81) (131.0, 0.0, -48.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (77) (133.0, 0.0, -47.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (73) (133.0, 0.0, -46.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (76) (132.0, 0.0, -48.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (79) (132.0, 0.0, -47.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (60) (134.0, 0.0, -46.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (63) (134.0, 0.0, -45.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (78) (133.0, 0.0, -48.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (62) (135.0, 0.0, -46.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (64) (136.0, 0.0, -46.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (67) (136.0, 0.0, -47.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (68) (136.0, 0.0, -45.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (61) (135.0, 0.0, -45.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (57) (135.0, 0.0, -44.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (109) (136.0, 0.0, -48.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (65) (137.0, 0.0, -47.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (66) (137.0, 0.0, -46.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (70) (137.0, 0.0, -45.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (71) (136.0, 0.0, -44.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (69) (137.0, 0.0, -44.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (58) (135.0, 0.0, -43.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (108) (137.0, 0.0, -48.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (110) (136.0, 0.0, -49.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (111) (137.0, 0.0, -49.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (112) (138.0, 0.0, -49.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (115) (138.0, 0.0, -48.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (113) (139.0, 0.0, -48.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (118) (140.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (119) (139.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (114) (139.0, 0.0, -49.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (117) (139.0, 0.0, -51.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (116) (138.0, 0.0, -51.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (120) (138.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (130) (143.0, 0.0, -51.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (129) (143.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (128) (142.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (131) (142.0, 0.0, -51.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (167) (141.5, 0.0, -47.5)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (121) (141.0, 0.0, -51.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (122) (141.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (165) (141.5, 0.0, -46.5)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (166) (140.5, 0.0, -46.5)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (123) (140.0, 0.0, -51.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (124) (144.0, 0.0, -51.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (127) (144.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (50) (135.0, 0.0, -41.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (54) (135.0, 0.0, -40.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (53) (135.0, 0.0, -39.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (55) (134.0, 0.0, -39.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (42) (133.0, 0.0, -39.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (35) (132.0, 0.0, -38.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (40) (132.0, 0.0, -39.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (34) (133.0, 0.0, -37.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (33) (133.0, 0.0, -38.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (17) (137.0, 0.0, -34.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (38) (133.0, 0.0, -36.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (29) (134.0, 0.0, -34.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (31) (134.0, 0.0, -35.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (26) (134.0, 0.0, -36.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (27) (135.0, 0.0, -35.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (25) (135.0, 0.0, -34.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (28) (135.0, 0.0, -33.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (30) (135.0, 0.0, -36.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (16) (136.0, 0.0, -33.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (23) (136.0, 0.0, -34.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (37) (133.0, 0.0, -35.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (36) (132.0, 0.0, -36.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (39) (132.0, 0.0, -35.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (32) (132.0, 0.0, -37.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (22) (137.0, 0.0, -33.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (24) (134.0, 0.0, -33.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (12) (139.0, 0.0, -31.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (21) (137.0, 0.0, -32.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (14) (138.0, 0.0, -32.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (15) (139.0, 0.0, -32.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (3) (139.0, 0.0, -30.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (2) (138.0, 0.0, -30.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (1) (138.0, 0.0, -29.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (13) (138.0, 0.0, -31.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (18) (137.0, 0.0, -31.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (20) (136.0, 0.0, -32.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (19) (136.0, 0.0, -31.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (139.0, 0.0, -29.0)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (125) (145.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (126) (145.0, 0.0, -51.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (132) (146.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (135) (146.0, 0.0, -49.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (133) (147.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (137) (149.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (139) (148.0, 0.0, -50.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (143) (150.0, 0.0, -47.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (140) (150.0, 0.0, -48.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (145) (149.0, 0.0, -47.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (138) (149.0, 0.0, -49.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (146) (149.0, 0.0, -48.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (147) (148.0, 0.0, -48.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (136) (148.0, 0.0, -49.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (144) (148.0, 0.0, -47.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (134) (147.0, 0.0, -49.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (141) (151.0, 0.0, -47.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (142) (151.0, 0.0, -48.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (148) (151.0, 0.0, -46.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (149) (151.0, 0.0, -45.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (153) (151.0, 0.0, -41.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (152) (151.0, 0.0, -42.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (150) (151.0, 0.0, -43.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (151) (151.0, 0.0, -44.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (164) (150.0, 0.0, -43.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (169) (149.0, 0.0, -43.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (170) (149.0, 0.0, -44.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (168) (150.0, 0.0, -44.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (154) (151.0, 0.0, -39.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (155) (151.0, 0.0, -40.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (157) (151.0, 0.0, -37.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (159) (151.0, 0.0, -36.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (156) (151.0, 0.0, -38.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (162) (150.0, 0.0, -37.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (163) (150.0, 0.0, -36.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (160) (151.0, 0.0, -34.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (158) (151.0, 0.0, -35.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (161) (151.0, 0.0, -33.0)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (4) (148.5, 0.0, -31.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (7) (148.5, 0.0, -32.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (5) (147.5, 0.0, -31.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (6) (147.5, 0.0, -32.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (106) (150.5, 0.0, -31.5)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (107) (149.5, 0.0, -32.5)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (104) (149.5, 0.0, -31.5)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (99) (162.5, 0.0, -49.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (9) (162.5, 0.0, -50.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (96) (162.5, 0.0, -48.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (10) (162.5, 0.0, -51.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (11) (163.5, 0.0, -51.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (8) (163.5, 0.0, -50.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (97) (163.5, 0.0, -49.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (102) (163.5, 0.0, -47.5)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (98) (163.5, 0.0, -48.5)": TunicLocationData("Fortress Grave Path", + "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (101) (163.5, 0.0, -46.5)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (100) (162.5, 0.0, -47.5)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Grass (103) (162.5, 0.0, -46.5)": TunicLocationData( + "Fortress Grave Path", "Fortress Grave Path Combat"), + "Fortress Grave Path - Fortress Grave Path Dusty Entrance Grass (172) (184.5, -1.0, -12.5)": TunicLocationData( + "Fortress Grave", "Fortress Grave Path Dusty Entrance Region"), + "Fortress Grave Path - Fortress Grave Path Dusty Entrance Grass (105) (185.5, -1.0, -13.5)": TunicLocationData( + "Fortress Grave", "Fortress Grave Path Dusty Entrance Region"), + "Fortress Grave Path - Fortress Grave Path Dusty Entrance Grass (171) (185.5, -1.0, -12.5)": TunicLocationData( + "Fortress Grave", "Fortress Grave Path Dusty Entrance Region"), + "Fortress Arena - Fortress Arena Grass (91) (2.0, -4.0, 26.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (90) (3.0, -4.0, 26.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (92) (2.0, -4.0, 25.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (89) (3.0, -4.0, 25.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (60) (2.0, 8.0, 155.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (61) (2.0, 8.0, 154.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (63) (3.0, 8.0, 154.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (62) (3.0, 8.0, 155.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (57) (4.0, 8.0, 154.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (53) (7.0, 8.0, 155.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (52) (7.0, 8.0, 156.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (54) (6.0, 8.0, 156.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (55) (6.0, 8.0, 155.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (59) (5.0, 8.0, 154.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (58) (5.0, 8.0, 155.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (56) (4.0, 8.0, 155.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (25) (3.0, 8.0, 172.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (24) (3.0, 8.0, 173.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (7) (4.0, 8.0, 172.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (17) (4.0, 8.0, 170.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (16) (4.0, 8.0, 171.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (3) (4.0, 8.0, 173.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (6) (5.0, 8.0, 172.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (27) (2.0, 8.0, 172.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (26) (2.0, 8.0, 173.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (9) (6.0, 8.0, 170.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (32) (6.0, 8.0, 169.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (8) (6.0, 8.0, 171.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (19) (5.0, 8.0, 170.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (18) (5.0, 8.0, 171.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (12) (8.0, 8.0, 171.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (10) (7.0, 8.0, 171.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (2) (5.0, 8.0, 173.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (29) (5.0, 8.0, 176.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (28) (5.0, 8.0, 177.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (1) (5.0, 8.0, 174.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (5.0, 8.0, 175.0)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (35) (4.0, 8.0, 176.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (34) (4.0, 8.0, 177.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (4) (4.0, 8.0, 174.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (5) (4.0, 8.0, 175.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (20) (3.0, 8.0, 175.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (21) (3.0, 8.0, 174.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (22) (2.0, 8.0, 175.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (23) (2.0, 8.0, 174.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (33) (6.0, 8.0, 168.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (31) (7.0, 8.0, 168.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (11) (7.0, 8.0, 170.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (30) (7.0, 8.0, 169.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (13) (8.0, 8.0, 170.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (15) (9.0, 8.0, 170.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (14) (9.0, 8.0, 171.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (37) (11.0, 8.0, 173.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (39) (12.0, 8.0, 173.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (38) (12.0, 8.0, 174.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (36) (11.0, 8.0, 174.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (68) (5.0, 8.0, 183.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (71) (5.0, 8.0, 182.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (70) (4.0, 8.0, 183.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (69) (4.0, 8.0, 182.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (66) (3.0, 8.0, 182.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (67) (2.0, 8.0, 182.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (75) (5.0, 8.0, 184.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (65) (3.0, 8.0, 183.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (64) (2.0, 8.0, 183.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (72) (5.0, 8.0, 185.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (74) (4.0, 8.0, 185.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (73) (4.0, 8.0, 184.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (78) (-3.0, 8.0, 187.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (77) (-3.0, 8.0, 186.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (85) (-4.0, 8.0, 184.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (86) (-4.0, 8.0, 185.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (83) (-3.0, 8.0, 184.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (80) (-3.0, 8.0, 185.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (79) (-2.0, 8.0, 186.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (82) (-2.0, 8.0, 185.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (81) (-2.0, 8.0, 184.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (76) (-2.0, 8.0, 187.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (84) (-5.0, 8.0, 185.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (87) (-5.0, 8.0, 184.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (50) (-14.0, 8.0, 173.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (48) (-13.0, 8.0, 173.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (40) (-12.0, 8.0, 173.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (44) (-12.0, 8.0, 175.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (45) (-12.0, 8.0, 174.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (47) (-11.0, 8.0, 174.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (42) (-11.0, 8.0, 173.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (46) (-11.0, 8.0, 175.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (49) (-13.0, 8.0, 172.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (51) (-14.0, 8.0, 172.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (43) (-11.0, 8.0, 172.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (41) (-12.0, 8.0, 172.0)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-12.4, 8.0, 190.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-11.4, 8.0, 190.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-11.4, 8.0, 191.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-12.4, 8.0, 191.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-12.4, 8.0, 192.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-11.4, 8.0, 192.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-12.4, 8.0, 193.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-11.4, 8.0, 193.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-14.4, 8.0, 194.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-14.4, 8.0, 192.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-14.4, 8.0, 193.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-14.4, 8.0, 195.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-13.4, 8.0, 195.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-13.4, 8.0, 193.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-13.4, 8.0, 192.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-13.4, 8.0, 194.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-2.8, 8.0, 194.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-3.8, 8.0, 194.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-2.8, 8.0, 195.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-3.8, 8.0, 195.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-2.8, 8.0, 199.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-4.8, 8.0, 200.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-3.8, 8.0, 199.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-3.8, 8.0, 200.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-2.8, 8.0, 200.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-1.8, 8.0, 200.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-1.8, 8.0, 199.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-0.8, 8.0, 199.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-3.8, 8.0, 202.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-3.8, 8.0, 201.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-4.8, 8.0, 202.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-4.8, 8.0, 201.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (-0.8, 8.0, 200.5)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (4.6, 8.0, 196.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (1.6, 8.0, 198.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (3.6, 8.0, 196.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (3.6, 8.0, 197.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (4.6, 8.0, 199.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (4.6, 8.0, 198.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (3.6, 8.0, 198.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (3.6, 8.0, 199.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (2.6, 8.0, 199.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (2.6, 8.0, 198.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (1.6, 8.0, 199.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (4.6, 8.0, 197.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (5.6, 8.0, 194.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (6.6, 8.0, 194.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (8.6, 8.0, 194.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (8.6, 8.0, 193.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (9.6, 8.0, 194.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (9.6, 8.0, 193.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (6.6, 8.0, 193.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (9.6, 8.0, 191.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (9.6, 8.0, 192.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (10.6, 8.0, 191.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (10.6, 8.0, 192.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (11.6, 8.0, 194.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (11.6, 8.0, 193.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (10.6, 8.0, 193.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (10.6, 8.0, 194.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (13.6, 8.0, 190.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (13.6, 8.0, 191.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (14.6, 8.0, 191.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (14.6, 8.0, 190.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (15.6, 8.0, 189.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (15.6, 8.0, 190.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (16.6, 8.0, 190.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (16.6, 8.0, 189.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (21.6, 8.0, 189.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (21.6, 8.0, 188.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (22.6, 8.0, 189.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (22.6, 8.0, 188.4)": TunicLocationData("Fortress Arena", "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (94) (-13.0, 8.0, 223.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (96) (-12.0, 8.0, 224.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (99) (-12.0, 8.0, 223.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (97) (-11.0, 8.0, 223.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (98) (-11.0, 8.0, 224.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (103) (-12.0, 8.0, 225.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (100) (-12.0, 8.0, 226.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (101) (-11.0, 8.0, 225.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (102) (-11.0, 8.0, 226.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (88) (-14.0, 8.0, 223.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (93) (-13.0, 8.0, 222.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (95) (-14.0, 8.0, 222.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (117) (-38.5, 8.0, 218.3)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (120) (-38.5, 8.0, 217.3)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (116) (-38.5, 8.0, 219.3)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (121) (-38.5, 8.0, 216.3)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (118) (-39.5, 8.0, 219.3)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (122) (-39.5, 8.0, 217.3)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (119) (-39.5, 8.0, 218.3)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (123) (-39.5, 8.0, 216.3)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (108) (-33.3, 8.0, 208.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (112) (-35.3, 8.0, 209.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (114) (-36.3, 8.0, 209.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (113) (-35.3, 8.0, 208.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (115) (-36.3, 8.0, 208.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (109) (-33.3, 8.0, 207.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (107) (-34.3, 8.0, 205.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (110) (-34.3, 8.0, 208.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (111) (-34.3, 8.0, 207.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (106) (-34.3, 8.0, 206.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (105) (-33.3, 8.0, 205.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Fortress Arena - Fortress Arena Grass (104) (-33.3, 8.0, 206.8)": TunicLocationData("Fortress Arena", + "Fortress Arena"), + "Quarry - Quarry Back Grass (26) (-50.3, 31.8, 74.3)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (27) (-49.3, 31.8, 74.3)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (20) (-50.3, 31.8, 75.3)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (21) (-49.3, 31.8, 75.3)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (22) (-50.3, 31.8, 76.3)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (23) (-49.3, 31.8, 76.3)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (13) (-44.0, 28.0, 59.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (14) (-45.0, 28.0, 60.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (12) (-45.0, 28.0, 59.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (15) (-44.0, 28.0, 60.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (6) (-40.0, 28.0, 59.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (7) (-39.0, 28.0, 59.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (11) (-37.0, 28.0, 58.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (9) (-37.0, 28.0, 57.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (4) (-40.0, 28.0, 60.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (5) (-39.0, 28.0, 60.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (2) (-38.0, 28.0, 59.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (8) (-38.0, 28.0, 57.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (10) (-38.0, 28.0, 58.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (3) (-37.0, 28.0, 59.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (-37.0, 28.0, 60.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (1) (-38.0, 28.0, 60.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (17) (-23.3, 28.0, 55.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (16) (-24.3, 28.0, 55.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (18) (-24.3, 28.0, 56.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (19) (-23.3, 28.0, 56.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (29) (-57.5, -4.5, 16.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (38) (-56.5, -4.0, 16.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (34) (-56.5, -4.0, 16.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (28) (-57.5, -4.5, 15.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (24) (-58.5, -4.5, 15.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (25) (-58.5, -4.5, 16.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (37) (-55.5, -4.0, 16.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (41) (-55.5, -4.0, 16.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (40) (-56.5, -4.0, 15.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (36) (-56.5, -4.0, 15.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (39) (-55.5, -4.0, 15.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (35) (-55.5, -4.0, 15.0)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (32) (-57.5, -12.0, 11.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (30) (-57.5, -12.0, 10.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (33) (-56.5, -12.0, 10.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (31) (-56.5, -12.0, 11.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (44) (-51.0, -12.0, 11.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (43) (-49.5, -12.0, 11.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (47) (-49.5, -12.0, 12.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (49) (-52.0, -12.0, 12.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (48) (-51.0, -12.0, 12.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (50) (-52.0, -12.0, 13.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (46) (-48.5, -12.0, 11.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (45) (-48.5, -12.0, 12.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Quarry - Quarry Back Grass (42) (-50.3, -12.0, 13.5)": TunicLocationData("Quarry Back", "Quarry Back"), + "Swamp - Swamp Front Grass swamp (36) (-100.0, -0.3, -10.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (37) (-100.0, -0.5, -9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (35) (-99.0, -0.5, -9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (38) (-99.0, -0.8, -10.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (40) (-88.3, 0.3, -18.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (41) (-87.3, -0.3, -19.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (34) (-87.3, 0.5, -18.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (31) (-89.5, -0.3, -10.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (32) (-89.5, -0.5, -9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (33) (-88.5, -0.8, -10.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (30) (-88.5, -0.5, -9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (39) (-88.3, 0.5, -19.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (27) (-82.3, 0.3, -14.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (28) (-82.3, 0.3, -13.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (29) (-81.3, -0.5, -14.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (26) (-81.3, -0.3, -13.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (24) (-80.3, 0.3, -12.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (23) (-80.3, 0.3, -13.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (22) (-79.3, -0.3, -12.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (25) (-79.3, -0.5, -13.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (56) (-83.3, 0.3, -21.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (54) (-82.3, 0.5, -21.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (57) (-82.3, -1.0, -22.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (55) (-83.3, 0.0, -22.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (43) (-77.3, -1.3, -6.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (45) (-76.3, -1.8, -6.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (42) (-76.3, -1.5, -5.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (44) (-77.3, -1.3, -5.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (19) (-73.5, 0.3, -18.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (21) (-72.5, 0.5, -18.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (18) (-72.5, -0.3, -17.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (20) (-73.5, 0.3, -17.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (15) (-61.8, 0.3, -22.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (16) (-61.8, 0.3, -21.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (17) (-60.8, -0.5, -22.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (14) (-60.8, -0.3, -21.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (60) (-64.0, -1.0, -27.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (58) (-63.0, -1.0, -27.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (61) (-63.0, -1.3, -28.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (59) (-64.0, -1.5, -28.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (63) (-62.0, -0.5, -29.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (64) (-62.0, -0.5, -28.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (449) (-58.5, -0.8, -16.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (451) (-57.5, -0.8, -16.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (448) (-57.5, -1.0, -15.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (450) (-58.5, -0.8, -15.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (445) (-51.5, 0.0, -9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (447) (-50.5, -0.3, -9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (446) (-51.5, 0.0, -8.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (444) (-50.5, -0.5, -8.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (432) (-55.8, -0.5, -2.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (430) (-56.8, -0.5, -2.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (431) (-56.8, -0.5, -1.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (429) (-55.8, -0.8, -1.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (437) (-60.8, -0.3, -2.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (439) (-61.8, 0.0, -2.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (438) (-61.8, 0.0, -3.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (436) (-62.8, -0.3, -4.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (433) (-62.8, -0.5, -3.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (434) (-63.8, -0.3, -4.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (435) (-63.8, -0.3, -3.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (48) (-61.0, -1.0, -8.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (47) (-61.0, -1.3, -9.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (46) (-60.0, -1.3, -8.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (441) (-61.0, -0.3, 5.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (443) (-60.0, -0.3, 5.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (440) (-60.0, -0.5, 6.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (442) (-61.0, -0.3, 6.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (204) (-70.0, -0.3, 11.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (206) (-69.0, -0.3, 11.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (207) (-69.3, -0.3, 12.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (212) (-70.3, 0.0, 12.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (183) (-70.0, -1.3, 7.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (185) (-71.0, -1.0, 8.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (187) (-72.0, -1.0, 8.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (175) (-72.5, 0.5, 13.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (176) (-72.5, 0.5, 14.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (181) (-69.0, -1.3, 7.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (174) (-71.5, 0.5, 14.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (172) (-71.5, 0.0, 13.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (186) (-72.0, -1.3, 7.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (180) (-69.0, -1.5, 6.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (182) (-70.0, -1.5, 6.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (184) (-71.0, -1.3, 7.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (266) (-77.8, -1.3, 11.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (267) (-78.0, -1.3, 12.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (268) (-78.5, -1.3, 12.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (265) (-78.8, -1.5, 11.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (165) (-84.0, -0.5, 5.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (167) (-84.0, 0.0, 4.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (166) (-83.0, -0.5, 5.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (56) (-83.0, -0.5, 4.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (169) (-75.3, -0.8, 21.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (171) (-75.3, -0.3, 20.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (168) (-74.3, -0.8, 20.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (170) (-74.3, -0.8, 21.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (199) (-73.8, -0.3, 24.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (196) (-72.8, -0.8, 24.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (197) (-73.8, -0.8, 25.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (198) (-72.8, -0.8, 25.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (200) (-78.3, -1.0, 27.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (203) (-79.3, -0.5, 27.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (201) (-79.3, -0.8, 28.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (202) (-78.3, -0.5, 28.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (192) (-64.3, -0.5, 25.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (194) (-64.3, -0.3, 26.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (205) (-66.3, -0.3, 26.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (211) (-65.3, -0.3, 25.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (195) (-65.3, -0.3, 25.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (193) (-65.3, -0.3, 26.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (209) (-66.3, -0.3, 27.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (208) (-67.3, -0.3, 27.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (210) (-67.3, -0.3, 26.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (178) (-62.3, -0.3, 13.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (179) (-62.3, -0.3, 14.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (177) (-61.3, -0.3, 14.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (173) (-61.3, -0.3, 13.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (191) (-59.0, -0.3, 20.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (188) (-58.0, -0.8, 20.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (190) (-58.0, -0.8, 21.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (189) (-59.0, -0.8, 21.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (52) (-58.0, 0.0, -35.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (50) (-57.0, -0.3, -35.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (51) (-58.0, -0.3, -36.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (7) (-54.3, -1.3, -38.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (53) (-57.0, -0.8, -36.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (10) (-53.5, 0.0, -30.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (13) (-52.5, -0.5, -31.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (11) (-53.5, 0.0, -29.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (9) (-52.5, -0.3, -29.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (12) (-52.5, -0.5, -30.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (5) (-53.3, -1.5, -38.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (4) (-51.0, -1.5, -37.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1) (-51.0, -1.0, -36.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (8) (-53.3, -2.0, -39.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (6) (-54.3, -1.8, -39.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (3) (-50.0, -1.8, -37.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (2) (-50.0, -1.3, -36.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (272) (-46.5, -1.0, -11.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (271) (-46.5, -1.0, -12.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (270) (-45.5, -1.0, -11.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (269) (-45.5, -1.3, -12.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (273) (-44.5, -1.5, -13.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (275) (-43.5, -1.5, -12.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (274) (-43.5, -1.5, -13.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (276) (-44.5, -1.5, -12.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (284) (-36.5, -0.8, -5.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (281) (-36.5, -1.0, -7.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (283) (-35.5, -0.8, -5.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (282) (-35.5, -1.0, -7.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (280) (-35.3, -1.3, -8.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (278) (-34.3, -1.3, -9.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (279) (-34.3, -1.3, -8.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (277) (-35.3, -1.3, -9.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (234) (-21.0, -0.5, -14.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (236) (-21.0, -0.5, -15.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (235) (-20.0, -0.5, -14.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (233) (-20.0, -0.5, -15.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (307) (-24.0, -0.5, -22.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (341) (-24.0, -0.5, -21.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (344) (-22.0, -0.5, -22.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (345) (-21.0, -0.5, -22.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (308) (-25.0, -0.5, -21.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (342) (-25.0, -0.5, -22.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (343) (-21.0, -0.5, -23.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (346) (-22.0, -0.5, -23.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (108) (-12.5, -2.0, -19.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (110) (-12.5, -1.8, -20.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (107) (-11.5, -1.8, -20.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (109) (-11.5, -2.0, -19.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (350) (-12.5, -0.5, -28.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (348) (-12.5, -0.3, -27.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (349) (-11.5, -0.3, -27.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (347) (-11.5, -0.5, -28.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (78) (-6.3, 0.0, -21.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (80) (-6.3, 0.0, -22.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (79) (-5.3, 0.0, -21.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (77) (-5.3, 0.0, -22.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (76) (-5.3, 0.0, -20.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (73) (-4.3, 0.0, -20.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (75) (-4.3, 0.0, -19.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (74) (-5.3, 0.0, -19.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (238) (-3.3, -1.0, -31.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (239) (-2.3, -1.0, -31.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (240) (-3.3, -1.3, -32.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (243) (-3.3, -1.5, -33.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (237) (-2.3, -1.3, -32.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (242) (-4.3, -1.5, -33.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (241) (-3.3, -1.8, -34.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (244) (-4.3, -1.8, -34.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (21) (4.3, -2.0, -18.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (24) (3.3, -2.0, -18.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (23) (4.3, -1.8, -17.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (22) (3.3, -1.8, -17.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (69) (2.8, -0.3, -14.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (28) (8.5, -1.8, -17.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (26) (8.5, -1.5, -16.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (25) (9.5, -1.8, -17.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (32) (9.5, -1.3, -15.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (27) (9.5, -1.5, -16.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (35) (12.5, -1.3, -15.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (33) (12.5, -1.5, -16.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (36) (11.5, -1.5, -16.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (34) (11.5, -1.3, -15.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (29) (10.5, -1.3, -15.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (31) (10.5, -1.0, -14.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (30) (9.5, -1.0, -14.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (112) (15.3, 0.3, -4.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (114) (15.3, 0.3, -5.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (111) (16.3, 0.3, -5.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (113) (16.3, 0.3, -4.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (118) (19.5, 0.0, -5.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (116) (19.5, 0.0, -4.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (38) (14.0, 0.0, -10.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (37) (15.0, 0.0, -11.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (39) (15.0, 0.0, -10.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (40) (14.0, 0.0, -11.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (115) (20.5, 0.0, -5.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (117) (20.5, 0.0, -4.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (123) (21.8, 0.0, -9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (124) (21.8, 0.0, -8.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (381) (21.8, 0.0, -17.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (379) (21.8, 0.0, -18.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (376) (19.8, 0.0, -27.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (378) (19.8, -0.3, -28.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (375) (20.8, 0.0, -28.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (377) (20.8, 0.0, -27.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (372) (16.0, -1.3, -32.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (373) (17.0, -1.3, -32.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (367) (17.0, -1.3, -33.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (374) (16.0, -1.5, -33.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (6.3, 0.0, -4.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1) (6.3, 0.0, -5.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (4) (5.3, 0.0, -5.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (2) (5.3, 0.0, -5.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (3) (5.3, 0.0, -4.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (62) (-2.3, 0.0, -10.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (63) (-1.3, 0.0, -10.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (61) (-1.3, 0.0, -11.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (64) (-2.3, 0.0, -11.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (68) (-0.3, 0.0, -11.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (66) (-0.3, 0.0, -10.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (67) (0.8, 0.0, -10.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (65) (0.8, 0.0, -11.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (70) (1.8, 0.0, -13.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (72) (1.8, 0.0, -14.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (71) (2.8, -0.3, -13.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (59) (-4.5, 0.0, -5.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (57) (-4.5, 0.0, -6.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (58) (-5.5, 0.0, -5.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (60) (-5.5, 0.0, -6.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (53) (-6.5, 0.0, -5.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (55) (-6.5, 0.0, -4.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (54) (-7.5, 0.0, -4.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (47) (-10.8, 0.0, 2.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (48) (-11.8, 0.0, 1.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (46) (-11.8, 0.0, 2.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (45) (-10.8, 0.0, 1.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (16) (-7.3, 0.0, 4.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (13) (-6.3, 0.0, 4.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (15) (-6.3, 0.0, 5.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (14) (-7.3, 0.0, 5.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (17) (-8.5, 0.0, 8.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (49) (-11.8, 0.0, 3.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (51) (-11.8, 0.0, 4.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (52) (-12.8, 0.0, 3.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (50) (-12.8, 0.0, 4.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (20) (-9.5, 0.0, 8.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (19) (-8.5, 0.0, 9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (18) (-9.5, 0.0, 9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (12) (-2.5, 0.0, 10.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (44) (-1.5, 0.0, 8.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (42) (-1.5, 0.0, 9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (41) (-0.5, 0.0, 8.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (43) (-0.5, 0.0, 9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (9) (-3.5, 0.0, 10.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (7) (1.5, 0.0, 10.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (5) (1.5, 0.0, 9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (6) (0.5, 0.0, 10.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (8) (0.5, 0.0, 9.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (10) (-2.5, 0.0, 11.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (11) (-3.5, 0.0, 11.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (82) (13.8, 0.0, 5.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (91) (14.8, 0.0, 7.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (81) (14.8, 0.0, 4.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (84) (14.8, 0.0, 5.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (83) (13.8, 0.0, 4.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (88) (16.8, 0.0, 6.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (85) (16.8, 0.0, 5.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (87) (15.8, 0.0, 5.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (86) (15.8, 0.0, 6.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (92) (15.8, 0.0, 8.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (89) (15.8, 0.0, 7.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (90) (14.8, 0.0, 8.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (101) (19.5, 0.0, 5.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (98) (20.5, 0.0, 5.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (99) (19.5, 0.0, 6.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (102) (20.5, 0.0, 6.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (97) (21.5, 0.0, 8.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (100) (21.5, 0.0, 9.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (93) (21.5, 0.0, 10.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (95) (20.5, 0.0, 10.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (94) (20.5, 0.0, 11.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (96) (21.5, 0.0, 11.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (135) (20.8, 0.0, 26.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (138) (21.8, 0.0, 26.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (136) (21.8, 0.0, 27.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (137) (20.8, 0.0, 27.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (140) (15.5, 0.0, 26.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (141) (14.5, 0.0, 26.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (142) (15.5, 0.0, 25.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (139) (14.5, 0.0, 25.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (718) (21.0, -0.5, 30.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (719) (21.0, -0.5, 31.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (721) (22.0, -0.5, 30.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (720) (22.0, -0.5, 31.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (717) (22.0, -0.5, 32.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (714) (21.0, -0.5, 32.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (716) (22.0, -0.5, 33.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (715) (21.0, -0.5, 33.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (705) (15.8, -0.5, 43.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (704) (15.8, -0.5, 44.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (702) (14.8, -0.5, 43.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (703) (14.8, -0.5, 44.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (708) (13.8, -0.5, 44.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (709) (13.8, -0.5, 43.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (707) (12.8, -0.5, 44.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (706) (12.8, -0.5, 43.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (134) (6.5, -0.5, 34.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (132) (6.5, -0.5, 35.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (133) (5.5, -0.5, 35.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (131) (5.5, -0.5, 34.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (149) (2.1, -0.9, 33.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (148) (3.1, -0.9, 33.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (150) (3.1, -1.1, 32.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (147) (2.1, -1.1, 32.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (130) (5.3, -1.0, 31.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (126) (6.3, -1.3, 30.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (129) (6.3, -1.0, 31.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (127) (5.3, -1.3, 30.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (125) (5.3, -1.8, 29.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (128) (6.3, -1.8, 29.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (151) (4.4, -0.5, 42.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (158) (2.5, -0.5, 44.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (156) (2.5, -0.5, 45.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (153) (4.4, -0.5, 43.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (152) (5.4, -0.5, 43.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (161) (-0.4, -0.5, 45.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (157) (1.5, -0.5, 45.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (155) (1.5, -0.5, 44.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (160) (0.6, -0.5, 45.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (154) (5.4, -0.5, 42.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (162) (-5.6, -0.5, 38.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (164) (-5.6, -0.5, 37.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (159) (-6.6, -0.5, 37.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (163) (-6.6, -0.5, 38.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (146) (-2.3, -1.6, 31.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (145) (-1.3, -0.9, 32.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (144) (-2.3, -1.6, 32.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (143) (-1.3, -1.6, 31.4)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (120) (1.5, -1.8, 21.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (121) (2.5, -1.8, 21.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (122) (1.5, -1.8, 20.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (119) (2.5, -1.8, 20.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (411) (-18.8, -0.8, 16.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (409) (-18.8, -0.3, 17.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (405) (-17.8, -0.3, 15.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (410) (-19.8, -0.3, 17.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (412) (-19.8, -0.5, 16.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (406) (-18.8, -0.3, 15.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (408) (-18.8, -0.5, 14.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (407) (-17.8, -0.8, 14.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (415) (-22.0, -0.8, 17.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (413) (-22.0, -0.3, 18.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (414) (-23.0, -0.3, 18.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (416) (-23.0, -0.5, 17.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (400) (-24.5, -0.5, 22.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (398) (-24.5, -0.3, 23.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (399) (-23.5, -0.8, 22.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (397) (-23.5, -0.3, 23.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (401) (-25.5, -0.8, 15.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (402) (-26.5, -0.8, 15.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (403) (-25.5, -1.3, 14.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (404) (-26.5, -1.3, 14.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (393) (-31.8, -1.0, 22.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (395) (-31.8, -1.5, 21.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (396) (-32.8, -1.8, 21.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (394) (-32.8, -1.5, 22.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (389) (-30.3, -0.3, 32.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (391) (-30.3, -0.3, 31.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (452) (-31.3, -0.3, 30.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (454) (-31.3, -0.3, 29.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (390) (-31.3, -0.5, 32.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (392) (-31.3, -0.5, 31.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (453) (-32.3, -0.3, 30.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (455) (-32.3, -0.5, 29.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (458) (-34.8, -1.0, 32.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (456) (-34.8, -1.3, 33.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (457) (-35.8, -1.3, 33.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (459) (-35.8, -1.3, 32.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (461) (-44.0, -0.3, 26.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (460) (-43.0, -0.3, 26.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (463) (-44.0, -0.8, 25.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (462) (-43.0, -0.3, 25.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (224) (-42.5, -1.0, 42.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (221) (-42.5, -0.5, 43.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (223) (-41.5, -0.3, 43.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (222) (-41.5, -0.8, 42.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (326) (-43.5, -1.3, 47.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (327) (-43.5, -1.0, 48.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (328) (-44.5, -1.3, 47.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (325) (-44.5, -0.8, 48.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (228) (-29.3, -0.5, 44.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (226) (-28.3, -0.8, 44.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (225) (-29.3, -0.8, 45.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (227) (-28.3, -0.8, 45.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (388) (-27.8, -0.5, 37.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (387) (-27.8, -0.3, 38.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (386) (-26.8, -0.5, 38.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (385) (-26.8, -0.8, 37.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (230) (-22.5, -1.0, 41.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (231) (-22.5, -0.5, 42.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (232) (-23.5, -0.8, 41.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (229) (-23.5, -0.3, 42.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (422) (-18.3, -0.8, 45.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (421) (-18.3, -1.3, 44.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (424) (-19.3, -0.5, 44.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (423) (-19.3, 0.0, 45.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (219) (-41.0, -1.5, 14.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (217) (-42.0, -1.5, 14.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (220) (-42.0, -1.5, 13.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (218) (-41.0, -2.0, 13.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (215) (-48.5, -1.8, 18.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (213) (-49.5, -1.8, 18.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (216) (-49.5, -1.8, 17.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (214) (-48.5, -2.3, 17.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (286) (-51.0, -1.8, 24.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (292) (-51.0, -1.8, 23.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (289) (-50.0, -1.8, 24.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (287) (-50.0, -2.3, 23.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (320) (-53.0, -1.8, 24.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (318) (-52.0, -2.3, 24.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (317) (-53.0, -1.8, 25.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (319) (-52.0, -1.8, 25.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (338) (-51.0, -0.5, 38.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (337) (-52.0, 0.3, 39.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (339) (-51.0, 0.0, 39.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (340) (-52.0, -0.5, 38.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (330) (-48.0, -0.8, 45.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (332) (-49.0, -0.8, 45.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (334) (-50.0, -0.5, 44.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (333) (-51.0, 0.0, 45.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (336) (-51.0, -0.5, 44.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (335) (-50.0, -0.3, 45.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (329) (-49.0, -0.3, 46.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (331) (-48.0, -0.5, 46.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (104) (-11.3, -1.5, -10.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (106) (-11.3, -1.8, -11.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (103) (-10.3, -1.8, -11.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (105) (-10.3, -1.5, -10.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (248) (0.3, 0.0, -44.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (245) (1.3, 0.0, -44.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (247) (1.3, -0.3, -43.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (249) (-0.8, -0.3, -45.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (251) (-0.8, 0.0, -44.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (252) (-1.8, -0.3, -45.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (250) (-1.8, 0.3, -44.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (365) (1.3, -0.5, -49.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (366) (0.3, -0.5, -50.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (364) (0.3, 0.0, -49.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (246) (0.3, 0.0, -43.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (254) (-7.3, -0.5, -49.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (253) (-6.3, -0.8, -50.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (255) (-6.3, -0.5, -49.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (256) (-7.3, -1.0, -50.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (257) (-1.5, -1.8, -60.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (258) (-1.5, -1.8, -61.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (259) (-0.5, -1.8, -60.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (260) (-0.5, -1.5, -61.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (261) (-5.0, -0.5, -66.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (262) (-5.0, -0.5, -67.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (263) (-4.0, -0.5, -66.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (264) (-4.0, -0.3, -67.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (467) (10.8, -0.5, -55.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (465) (10.8, -0.3, -54.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (359) (11.0, -1.0, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (358) (12.0, -0.5, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (357) (12.0, -0.8, -62.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (466) (11.8, -0.5, -54.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (464) (11.8, -0.5, -55.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (362) (10.0, -1.3, -62.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (361) (10.0, -1.5, -63.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (356) (11.0, -1.0, -62.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (363) (9.0, -1.8, -62.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (360) (9.0, -1.8, -63.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (368) (13.0, -1.5, -66.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (371) (13.0, -1.5, -65.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (370) (14.0, -1.0, -65.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (369) (14.0, -1.3, -66.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (354) (21.0, 0.0, -66.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (355) (22.0, 0.0, -65.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (353) (22.0, 0.0, -66.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (382) (21.2, -0.2, -63.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (383) (21.2, -0.5, -62.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (380) (20.2, -0.7, -63.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (384) (20.2, -0.5, -62.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (351) (21.0, 0.0, -67.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (352) (22.0, 0.0, -67.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (316) (20.8, -0.3, -72.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (313) (20.8, -0.6, -73.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (315) (21.8, -0.3, -72.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (314) (21.8, -0.6, -73.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (545) (34.8, 0.0, -92.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (546) (34.8, -0.5, -93.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (542) (35.8, -0.5, -93.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (543) (35.8, -0.3, -92.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (571) (30.8, 0.0, -88.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (572) (30.8, 0.0, -87.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (574) (29.8, 0.0, -88.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (573) (29.8, 0.3, -87.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (541) (27.5, -0.3, -88.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (544) (26.5, -0.5, -88.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (529) (25.5, -0.8, -88.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (530) (25.5, -0.8, -87.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (531) (24.5, -0.5, -87.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (532) (24.5, -0.8, -88.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (538) (27.5, -0.3, -89.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (539) (26.5, -0.3, -89.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (533) (25.5, -0.8, -90.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (534) (25.5, -0.8, -89.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (535) (24.5, -0.5, -89.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (540) (26.5, -0.5, -90.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (537) (27.5, -0.3, -90.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (536) (24.5, -0.8, -90.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (578) (33.3, 0.0, -80.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (575) (34.3, 0.0, -80.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (570) (34.3, 0.0, -82.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (569) (34.3, 0.3, -81.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (567) (35.3, 0.0, -82.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (568) (35.3, 0.0, -81.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (576) (34.3, 0.0, -79.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (577) (33.3, 0.3, -79.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (549) (27.5, 0.3, -81.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (548) (28.5, 0.0, -81.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (547) (28.5, 0.0, -82.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (550) (27.5, 0.0, -82.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (525) (25.8, 0.0, -79.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (521) (26.8, 0.0, -77.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (524) (25.8, 0.0, -77.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (523) (25.8, 0.3, -76.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (522) (26.8, 0.0, -76.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (526) (25.8, 0.0, -78.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (527) (24.8, 0.3, -78.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (528) (24.8, 0.0, -79.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (579) (34.0, 0.0, -74.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (580) (34.0, 0.0, -73.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (581) (33.0, 0.3, -73.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (582) (33.0, 0.0, -74.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (520) (31.0, 0.0, -70.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (517) (32.0, 0.0, -70.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (518) (32.0, 0.0, -69.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (497) (27.0, 0.0, -71.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (555) (33.5, 0.0, -67.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (556) (33.5, 0.0, -66.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (561) (34.5, 0.3, -67.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (562) (34.5, 0.0, -68.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (559) (35.5, 0.0, -68.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (560) (35.5, 0.0, -67.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (516) (30.0, 0.0, -66.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (510) (29.0, 0.0, -66.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (509) (29.0, 0.0, -67.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (558) (32.5, 0.0, -67.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (519) (31.0, 0.3, -69.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (514) (31.0, 0.0, -65.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (513) (31.0, 0.0, -66.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (505) (29.0, 0.0, -69.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (506) (29.0, 0.0, -68.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (512) (28.0, 0.0, -67.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (507) (28.0, 0.3, -68.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (508) (28.0, 0.0, -69.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (498) (27.0, 0.0, -70.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (515) (30.0, 0.3, -65.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (511) (28.0, 0.3, -66.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (502) (27.0, 0.0, -68.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (557) (32.5, 0.3, -66.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (501) (27.0, 0.0, -69.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (503) (26.0, 0.3, -68.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (504) (26.0, 0.0, -69.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (499) (26.0, 0.3, -70.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (500) (26.0, 0.0, -71.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (551) (37.8, 0.0, -65.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (552) (37.8, 0.0, -64.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (554) (36.8, 0.0, -65.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (553) (36.8, 0.3, -64.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (566) (41.5, 2.5, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (584) (40.5, 2.0, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (565) (41.5, 3.0, -60.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (564) (42.5, 3.0, -60.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (563) (42.5, 2.5, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (615) (44.3, 0.5, -66.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (613) (45.3, 1.0, -65.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (612) (45.3, 0.5, -66.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (614) (44.3, 1.3, -65.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (585) (47.8, 0.5, -66.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (583) (47.8, 0.3, -67.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (587) (46.8, 0.3, -67.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (586) (46.8, 0.8, -66.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (496) (43.0, -1.0, -71.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (493) (44.0, -1.0, -71.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (495) (43.0, -0.5, -70.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (490) (46.0, -1.0, -71.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (486) (46.0, -1.3, -72.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (491) (45.0, -0.8, -71.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (492) (45.0, -1.3, -72.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (494) (44.0, -0.8, -70.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (468) (46.0, -0.5, -83.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (470) (46.0, -0.8, -82.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (471) (45.0, -0.5, -83.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (469) (45.0, -0.5, -82.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (672) (49.8, 0.0, -90.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (673) (49.8, -0.3, -91.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (670) (50.8, -0.3, -90.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (671) (50.8, -0.3, -91.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (668) (51.8, 0.0, -91.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (669) (51.8, -0.3, -92.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (666) (52.8, -0.3, -91.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (667) (52.8, -0.3, -92.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (618) (54.3, -0.3, -95.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (619) (54.3, -0.5, -96.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (616) (55.3, -0.5, -96.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (617) (55.3, -0.5, -95.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (674) (46.3, -0.3, -95.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (676) (45.3, 0.0, -95.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (675) (46.3, -0.3, -96.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (677) (45.3, -0.3, -96.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (682) (58.0, -0.5, -78.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (683) (58.0, -0.5, -79.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (680) (59.0, 0.0, -79.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (681) (59.0, -0.3, -80.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (685) (57.0, -0.5, -79.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (679) (60.0, -0.3, -80.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (678) (60.0, -0.3, -79.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (684) (57.0, -0.3, -78.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (591) (57.3, -0.8, -76.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (588) (57.3, -0.8, -77.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (599) (56.3, -1.0, -77.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (598) (56.3, -0.8, -76.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (600) (56.8, -0.5, -72.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (601) (56.8, -0.5, -71.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (603) (55.8, -0.8, -72.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (602) (55.8, -0.5, -71.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (607) (60.8, -0.3, -68.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (606) (60.8, 0.3, -67.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (611) (62.8, 0.3, -67.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (605) (61.8, 0.3, -67.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (604) (61.8, -0.3, -68.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (608) (63.8, 0.3, -67.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (610) (62.8, 0.8, -66.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (609) (63.8, 0.8, -66.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (693) (66.8, 0.5, -66.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (690) (67.8, 0.5, -66.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (691) (67.8, 0.8, -65.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (686) (66.8, 1.0, -64.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (692) (66.8, 1.0, -65.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (687) (66.8, 1.0, -63.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (688) (65.8, 1.3, -63.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (689) (65.8, 1.0, -64.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (592) (55.3, 1.3, -65.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (597) (56.3, 1.3, -65.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (596) (57.3, 1.3, -65.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (589) (53.3, 1.5, -64.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (595) (54.3, 1.3, -65.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (594) (54.3, 1.8, -64.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (593) (55.3, 1.5, -64.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (590) (52.3, 1.8, -64.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (699) (77.0, 0.8, -71.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (701) (76.0, 0.5, -71.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (700) (76.0, 1.0, -70.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (698) (77.0, 1.0, -70.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (694) (73.0, 0.0, -68.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (695) (73.0, 0.0, -69.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (697) (72.0, 0.0, -69.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (696) (72.0, 0.3, -68.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1489) (89.0, -0.8, -73.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (664) (90.0, -1.0, -74.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (665) (90.0, -1.5, -75.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (663) (91.0, -1.3, -74.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1486) (90.0, -0.8, -73.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (660) (92.0, -1.3, -74.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1481) (93.0, -0.8, -73.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (661) (92.0, -1.0, -73.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (662) (91.0, -0.8, -73.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1380) (94.0, -0.8, -73.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1479) (93.0, -0.3, -72.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1478) (94.0, -0.8, -72.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1487) (90.0, -0.8, -72.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1488) (89.0, -0.3, -72.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (658) (96.0, -1.3, -81.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (657) (97.0, -1.5, -81.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (659) (96.0, -1.5, -82.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (656) (97.0, -1.5, -82.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (655) (109.5, -1.5, -85.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (652) (110.5, -1.5, -85.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (654) (109.5, -1.3, -84.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (653) (110.5, -1.5, -84.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (638) (116.3, -0.3, -88.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (639) (116.3, -0.5, -89.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (637) (117.3, -0.5, -88.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (636) (117.3, -0.5, -89.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (649) (111.8, -0.5, -94.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (650) (110.8, -0.3, -94.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (648) (111.8, -0.5, -95.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (651) (110.8, -0.5, -95.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (645) (107.0, -0.3, -98.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (647) (106.0, -0.5, -99.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (646) (106.0, -0.3, -98.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (644) (107.0, -0.5, -99.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (641) (105.0, -0.5, -95.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (642) (104.0, -0.3, -95.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (643) (104.0, -0.5, -96.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (640) (105.0, -0.5, -96.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (478) (117.5, 0.0, -78.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (479) (117.5, -0.3, -79.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (483) (116.5, -0.3, -77.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (476) (118.5, -0.3, -79.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (480) (117.5, -0.3, -77.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (477) (118.5, -0.3, -78.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (475) (118.5, -0.3, -77.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (482) (116.5, 0.0, -76.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (485) (115.5, -0.3, -77.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (474) (118.5, 0.0, -76.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (481) (117.5, -0.3, -76.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (484) (115.5, 0.0, -76.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (472) (119.5, -0.3, -77.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (473) (119.5, -0.3, -76.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (633) (128.0, -1.0, -85.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (632) (128.0, -1.3, -86.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (634) (127.0, -0.8, -85.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (635) (127.0, -1.3, -86.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (628) (122.5, -0.3, -82.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (629) (122.5, -0.3, -81.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (630) (121.5, 0.0, -81.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (631) (121.5, -0.3, -82.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (489) (135.8, -2.0, -90.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (488) (135.8, -1.8, -89.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (487) (136.8, -2.0, -89.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (733) (163.8, -0.8, -85.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (732) (163.8, -0.3, -84.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (730) (164.8, -0.8, -85.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (731) (164.8, -0.5, -84.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (737) (165.0, -0.3, -80.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (734) (166.0, -0.3, -80.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (729) (167.5, -0.3, -82.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (727) (168.5, -0.5, -81.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (726) (168.5, -0.5, -82.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (728) (167.5, 0.0, -81.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (735) (166.0, -0.5, -79.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (736) (165.0, -0.3, -79.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (725) (146.3, -1.3, -79.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (724) (146.3, -0.8, -78.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (723) (147.3, -1.0, -78.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (722) (147.3, -1.3, -79.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1087) (131.0, 4.3, -85.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1081) (132.0, 4.0, -85.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1398) (133.0, 4.3, -84.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1395) (131.0, 4.0, -86.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1079) (132.0, 4.0, -86.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1396) (134.0, 4.0, -85.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1399) (133.0, 4.0, -85.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1397) (134.0, 4.0, -84.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1403) (138.3, 4.0, -77.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1400) (139.3, 4.0, -77.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1402) (138.3, 4.3, -76.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1401) (139.3, 4.0, -76.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1415) (132.3, 4.0, -73.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1412) (133.3, 4.0, -73.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1413) (133.3, 4.0, -72.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1414) (132.3, 4.3, -72.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1417) (131.3, 4.0, -72.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1416) (131.3, 4.0, -73.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1418) (130.3, 4.3, -72.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1419) (130.3, 4.0, -73.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1420) (129.3, 4.0, -72.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1421) (128.3, 4.3, -72.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1408) (139.8, 4.0, -69.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1409) (139.8, 4.0, -68.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1407) (140.8, 4.0, -69.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1404) (141.8, 4.0, -69.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1515) (141.8, 4.3, -70.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1411) (138.8, 4.0, -69.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1511) (142.8, 4.0, -70.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1516) (142.8, 4.0, -71.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1517) (141.8, 4.0, -71.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1405) (141.8, 4.0, -68.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1406) (140.8, 4.3, -68.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1410) (138.8, 4.3, -68.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1425) (131.0, 7.8, -69.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1424) (132.0, 7.8, -68.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1423) (132.0, 7.8, -69.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1422) (131.0, 7.8, -68.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1518) (127.3, 7.8, -62.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1520) (127.3, 7.8, -61.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1519) (126.3, 7.8, -61.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1521) (126.3, 7.8, -62.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1432) (116.8, 7.8, -64.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1427) (114.8, 7.8, -65.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1428) (114.8, 7.8, -64.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1431) (115.8, 7.8, -64.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1426) (113.8, 7.8, -64.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1429) (113.8, 7.8, -65.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1430) (112.8, 7.8, -64.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1438) (105.3, 7.8, -62.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1439) (105.3, 7.8, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1436) (106.3, 7.8, -62.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1437) (104.3, 7.8, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1435) (107.3, 7.8, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1434) (107.3, 7.8, -62.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1433) (106.3, 7.8, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1441) (94.1, 7.8, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1440) (93.1, 7.8, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1456) (86.5, 7.8, -60.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1455) (86.5, 7.8, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1457) (85.5, 7.8, -61.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1454) (85.5, 7.8, -60.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1444) (88.0, 7.8, -66.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1442) (87.0, 7.8, -66.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1445) (87.0, 7.8, -67.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1524) (89.0, 7.8, -67.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1443) (88.0, 7.8, -67.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1522) (93.1, 7.8, -66.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1525) (93.1, 7.8, -67.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1523) (94.1, 7.8, -67.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1451) (73.5, 4.0, -61.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1452) (73.5, 4.0, -60.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1450) (72.5, 4.0, -60.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1453) (72.5, 4.0, -61.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1449) (82.3, 4.0, -65.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1447) (83.3, 4.0, -65.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1446) (82.3, 4.0, -64.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1448) (83.3, 4.0, -64.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1480) (96.0, 4.0, -68.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1485) (97.0, 4.0, -69.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1482) (97.0, 4.0, -68.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1484) (98.0, 4.0, -68.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1483) (98.0, 4.0, -69.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1319) (123.5, 12.0, -46.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1321) (122.5, 12.0, -46.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1322) (122.5, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1320) (121.5, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1317) (124.5, 12.0, -46.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1316) (123.5, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1323) (121.5, 12.0, -46.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1318) (124.5, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1512) (114.9, 12.0, -48.7)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1513) (114.9, 12.0, -47.7)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1514) (113.9, 12.0, -48.7)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1295) (136.8, 12.0, -53.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1296) (136.8, 12.0, -52.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1297) (135.8, 12.0, -53.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1298) (137.8, 12.0, -52.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1294) (135.8, 12.0, -52.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1299) (138.8, 12.0, -52.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1300) (140.0, 12.0, -58.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1302) (141.0, 12.0, -58.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1303) (140.0, 12.0, -59.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1301) (141.0, 12.0, -59.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1307) (146.3, 12.0, -53.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1304) (146.3, 12.0, -52.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1306) (147.3, 12.0, -52.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1305) (147.3, 12.0, -53.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1309) (144.8, 12.0, -62.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1310) (144.8, 12.0, -61.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1308) (143.8, 12.0, -61.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1311) (143.8, 12.0, -62.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1312) (133.3, 12.0, -65.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1315) (133.3, 12.0, -66.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1313) (134.3, 12.0, -66.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1314) (134.3, 12.0, -65.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1327) (96.8, 12.0, -46.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1326) (97.8, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1325) (97.8, 12.0, -46.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1329) (99.8, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1328) (98.8, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1324) (96.8, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1331) (104.8, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1330) (103.8, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1335) (84.0, 12.0, -46.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1332) (84.0, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1333) (85.0, 12.0, -46.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1334) (85.0, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1369) (68.5, 12.0, -58.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1372) (68.5, 12.0, -59.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1371) (69.5, 12.0, -58.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1370) (69.5, 12.0, -59.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1375) (65.0, 12.0, -60.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1373) (64.0, 12.0, -60.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1374) (65.0, 12.0, -61.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1376) (64.0, 12.0, -61.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1348) (60.0, 12.0, -50.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1345) (60.0, 12.0, -49.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1346) (61.0, 12.0, -50.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1347) (61.0, 12.0, -49.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1343) (53.3, 12.0, -49.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1344) (54.3, 12.0, -49.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1341) (51.3, 12.0, -49.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1342) (52.3, 12.0, -49.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1340) (50.3, 12.0, -49.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1337) (49.3, 12.0, -50.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1338) (49.3, 12.0, -49.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1336) (48.3, 12.0, -49.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1339) (48.3, 12.0, -50.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1367) (51.5, 12.0, -62.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1368) (50.5, 12.0, -63.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1365) (50.5, 12.0, -62.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1366) (51.5, 12.0, -63.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1363) (37.3, 12.0, -58.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1361) (36.3, 12.0, -58.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1364) (36.3, 12.0, -59.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1362) (37.3, 12.0, -59.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1356) (33.3, 12.0, -54.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1353) (33.3, 12.0, -53.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1354) (34.3, 12.0, -54.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1355) (34.3, 12.0, -53.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1351) (33.3, 12.0, -51.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1350) (33.3, 12.0, -52.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1349) (32.3, 12.0, -51.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1352) (32.3, 12.0, -52.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1359) (31.0, 12.0, -44.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1358) (31.0, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1357) (30.0, 12.0, -44.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1360) (30.0, 12.0, -45.5)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1390) (42.3, 12.0, -34.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1387) (42.3, 12.0, -33.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1388) (43.3, 12.0, -34.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1389) (43.3, 12.0, -33.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1392) (40.0, 12.0, -26.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1394) (39.0, 12.0, -26.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1393) (40.0, 12.0, -25.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1391) (39.0, 12.0, -25.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1385) (31.8, 7.5, -29.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1383) (31.8, 7.5, -26.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1382) (31.8, 7.5, -27.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1384) (30.8, 7.5, -27.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1381) (30.8, 7.5, -26.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (1386) (31.8, 7.5, -28.3)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (425) (-85.0, -0.3, -11.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (428) (-85.0, -0.5, -12.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (427) (-86.0, 0.0, -11.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (426) (-86.0, 0.0, -12.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (623) (70.5, -0.5, -92.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (620) (71.5, -0.5, -92.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (622) (70.5, -0.3, -91.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (621) (71.5, -0.3, -91.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (741) (76.8, -0.8, -98.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (742) (77.8, -0.5, -98.0)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (627) (67.0, -1.0, -83.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (624) (68.0, -1.0, -83.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (625) (68.0, -1.5, -82.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Front Grass swamp (626) (67.0, -1.0, -82.8)": TunicLocationData("Swamp Front", "Swamp Front"), + "Swamp - Swamp Mid Grass swamp (925) (34.5, 0.0, -7.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (922) (35.5, 0.0, -7.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (924) (34.5, 0.3, -6.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (923) (35.5, 0.3, -6.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (920) (42.3, -0.3, -7.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (921) (42.3, -0.8, -8.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (918) (43.3, -1.0, -8.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (919) (43.3, -0.8, -7.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (914) (45.3, -1.3, -7.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (916) (44.3, -0.5, -6.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (917) (44.3, -1.0, -7.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (915) (45.3, -1.0, -6.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (908) (47.8, -0.8, 6.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (909) (47.8, -1.0, 5.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (906) (48.8, -1.3, 5.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (907) (48.8, -1.3, 6.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (905) (51.5, -1.8, 13.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (902) (51.5, -0.5, 15.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (903) (51.5, -1.0, 14.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (900) (52.5, -1.0, 14.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (904) (52.5, -1.8, 13.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (897) (54.5, -0.5, 16.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (896) (54.5, -0.8, 15.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (898) (53.5, -0.3, 16.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (901) (52.5, -0.8, 15.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (899) (53.5, -0.8, 15.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (926) (39.0, 0.0, 10.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (927) (39.0, 0.3, 11.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (931) (38.0, 0.0, 13.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (930) (38.0, 0.0, 12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (928) (38.0, 0.3, 11.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (932) (37.0, 0.3, 13.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (933) (37.0, 0.0, 12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (929) (38.0, 0.0, 10.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (935) (39.8, 0.0, 25.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (934) (39.8, 0.0, 24.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (936) (38.8, 0.3, 25.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (937) (38.8, 0.0, 24.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (893) (63.5, 0.0, 12.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (895) (62.5, 0.0, 11.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (894) (62.5, 0.3, 12.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (889) (61.5, 0.0, 11.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (890) (60.5, 0.3, 11.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (891) (60.5, 0.0, 10.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (892) (63.5, 0.0, 11.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (888) (61.5, 0.0, 10.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (881) (60.5, 0.0, -4.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (880) (60.5, 0.0, -5.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (884) (61.5, 0.0, -3.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (887) (60.5, 0.0, -3.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (886) (60.5, 0.3, -2.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (885) (61.5, 0.0, -2.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (883) (59.5, -0.3, -5.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (882) (59.5, 0.0, -4.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (877) (67.0, 0.0, -12.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (874) (68.0, 0.3, -11.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (875) (68.0, 0.0, -12.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (873) (69.0, 0.0, -11.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (872) (69.0, 0.0, -12.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (878) (66.0, 0.3, -12.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (879) (66.0, -0.3, -13.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (876) (67.0, -0.3, -13.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (743) (82.5, 0.0, -3.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (738) (83.5, 0.0, -3.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (740) (82.5, 0.3, -2.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (739) (83.5, 0.0, -2.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (910) (77.5, 0.0, 1.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (911) (77.5, 0.0, 2.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (913) (76.5, 0.0, 1.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (912) (76.5, 0.3, 2.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (756) (76.0, -1.3, 6.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (754) (77.0, -1.0, 8.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (755) (77.0, -1.3, 7.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (757) (76.0, -1.3, 7.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (759) (75.0, -1.3, 6.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (758) (75.0, -1.3, 7.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (752) (78.0, -1.0, 7.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (753) (78.0, -1.3, 8.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (786) (95.8, 0.3, 15.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (785) (96.8, 0.0, 15.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (784) (96.8, 0.0, 14.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (787) (95.8, 0.0, 14.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (776) (100.8, 0.0, 14.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (777) (100.8, 0.0, 15.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (779) (99.8, 0.0, 14.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (778) (99.8, 0.3, 15.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (788) (97.3, 0.0, 19.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (789) (97.3, 0.0, 20.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (791) (96.3, 0.0, 19.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (790) (96.3, 0.3, 20.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (792) (98.3, 0.0, 22.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (796) (103.0, 0.0, 22.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (795) (103.0, 0.0, 21.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (798) (102.0, 0.0, 21.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (793) (98.3, 0.0, 23.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (794) (97.3, 0.3, 23.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (782) (101.8, 0.3, 16.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (781) (102.8, 0.0, 16.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (783) (101.8, 0.0, 15.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (780) (102.8, 0.0, 15.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (833) (108.5, 0.0, 20.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (830) (109.5, 0.0, 20.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (831) (109.5, 0.0, 21.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (832) (108.5, 0.3, 21.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (945) (112.3, 0.3, 12.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (946) (112.3, 0.0, 11.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (944) (113.3, 0.0, 12.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (943) (113.3, 0.0, 11.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (772) (114.3, 0.0, 9.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (771) (112.3, 0.0, 7.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (770) (112.3, 0.3, 8.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (774) (113.3, 0.3, 10.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (775) (113.3, 0.0, 9.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (768) (113.3, 0.0, 7.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (769) (113.3, 0.0, 8.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (773) (114.3, 0.0, 10.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (767) (104.5, 0.0, 3.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (766) (104.5, 0.3, 4.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (765) (105.5, 0.0, 4.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (764) (105.5, 0.0, 3.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (761) (103.5, 0.0, 3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (762) (102.5, 0.3, 3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (763) (102.5, 0.0, 2.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (760) (103.5, 0.0, 2.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (971) (104.8, 0.3, -12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (970) (105.8, 0.0, -12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (967) (106.8, 0.3, -9.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (963) (106.8, 0.3, -11.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (968) (106.8, 0.0, -10.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (961) (107.8, 0.0, -12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (964) (106.8, 0.0, -12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (969) (105.8, 0.0, -13.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (972) (104.8, 0.0, -13.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (965) (107.8, 0.0, -10.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (962) (107.8, 0.0, -11.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (966) (107.8, 0.0, -9.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (747) (88.3, 0.0, -12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (744) (89.3, 0.0, -12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (745) (89.3, 0.0, -11.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (746) (88.3, 0.3, -11.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (751) (94.5, 0.0, -10.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (748) (95.5, 0.0, -10.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (749) (95.5, 0.0, -9.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (750) (94.5, 0.3, -9.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (975) (118.5, 0.3, -12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (976) (118.5, 0.0, -13.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (974) (119.5, 0.0, -12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (973) (119.5, 0.0, -13.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (856) (120.8, -1.5, -1.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (857) (120.8, -1.5, -0.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (859) (119.8, -1.0, -1.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (858) (119.8, -0.8, -0.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (871) (126.0, -1.8, 0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (868) (127.0, -1.8, 0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (869) (127.0, -1.8, 1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (870) (126.0, -1.5, 1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (951) (132.3, -0.3, 11.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (952) (132.3, -0.3, 12.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (947) (130.3, -0.5, 11.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (953) (131.3, -0.3, 12.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (954) (131.3, -0.5, 11.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (852) (128.5, -1.0, 8.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (948) (130.3, -0.5, 12.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (949) (129.3, -0.5, 12.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (950) (129.3, -0.8, 11.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (853) (127.5, -1.0, 8.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (851) (128.5, -1.0, 7.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (854) (127.5, -1.3, 7.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (855) (126.5, -1.3, 7.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (988) (140.0, -1.3, 6.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (985) (141.0, -1.3, 6.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (986) (140.0, -1.0, 7.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (987) (141.0, -1.0, 7.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (862) (134.3, -1.0, -4.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (861) (135.3, -0.8, -4.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (865) (133.3, -1.5, -3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (864) (133.3, -1.5, -4.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (867) (132.3, -1.8, -4.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (866) (132.3, -1.8, -3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (860) (135.3, -0.8, -5.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (863) (134.3, -1.0, -5.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (982) (139.3, 0.3, -10.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (984) (139.3, 0.0, -11.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (983) (140.3, 0.0, -10.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (979) (139.3, 0.0, -12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (980) (138.3, 0.0, -13.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (978) (138.3, 0.3, -12.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (981) (140.3, 0.0, -11.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (977) (139.3, 0.0, -13.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (960) (151.0, 0.0, -3.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (956) (152.0, 0.5, -3.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (955) (151.0, 0.0, -1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (959) (151.0, 0.3, -2.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (958) (150.0, 0.0, -1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (957) (150.0, 0.3, -0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1238) (160.3, 1.8, -12.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1244) (159.3, 0.3, -14.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1245) (160.3, 0.3, -14.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1243) (160.3, 0.8, -13.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1237) (161.3, 2.3, -11.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1236) (160.3, 2.5, -11.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1235) (162.0, 3.8, -5.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1239) (162.0, 3.8, -4.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1201) (162.0, 3.8, -0.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1222) (162.0, 3.8, 0.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1223) (161.0, 3.8, -0.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1221) (161.0, 4.0, 0.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1227) (156.5, 3.8, 2.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1224) (157.5, 3.8, 2.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1228) (158.5, 3.8, 3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1226) (157.5, 3.8, 3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1225) (156.5, 4.0, 3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1232) (148.8, 3.8, 15.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1233) (148.8, 3.8, 14.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1231) (149.8, 3.8, 14.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1229) (149.8, 3.8, 15.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1230) (148.8, 4.0, 16.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (837) (145.0, 0.0, 17.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (836) (145.0, 0.3, 18.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (844) (145.0, 0.0, 20.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (843) (145.0, 0.0, 19.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (845) (144.0, 0.3, 20.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (846) (144.0, 0.0, 19.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1234) (145.3, 0.0, 15.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (847) (145.3, 0.0, 13.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (848) (145.3, 0.0, 14.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (849) (144.3, 0.3, 14.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (850) (144.3, 0.0, 13.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (834) (146.0, 0.0, 17.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (835) (146.0, 0.0, 18.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (842) (142.3, 1.0, 23.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (841) (141.3, 1.0, 24.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (838) (142.3, 1.3, 24.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (839) (142.3, 1.8, 25.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (840) (141.3, 1.8, 25.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (828) (132.5, 1.5, 35.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (829) (132.5, 1.0, 34.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (826) (133.5, 1.3, 34.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (827) (133.5, 1.3, 35.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (822) (131.5, -0.3, 44.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (818) (131.5, 0.0, 43.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (823) (130.5, 0.3, 44.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (824) (130.5, 0.0, 43.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (825) (129.5, 0.3, 44.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (819) (126.3, 0.0, 41.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (821) (126.3, 0.0, 42.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (815) (124.3, 0.0, 41.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (820) (125.3, 0.3, 41.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (814) (124.3, 0.0, 40.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (817) (123.3, -0.3, 40.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (816) (123.3, 0.0, 41.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (812) (120.5, -0.3, 33.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (810) (121.5, -0.3, 32.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (811) (121.5, -0.3, 33.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (808) (119.5, 0.0, 31.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (813) (120.5, -0.5, 32.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (807) (120.5, 0.0, 31.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (806) (120.5, 0.0, 30.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (809) (119.5, -0.3, 30.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (804) (120.8, 0.3, 26.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (805) (120.8, 0.0, 25.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (802) (121.8, 0.0, 25.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (803) (121.8, 0.0, 26.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (800) (122.8, 0.3, 25.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (801) (122.8, 0.0, 24.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (797) (123.8, 0.0, 24.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (799) (123.8, 0.0, 25.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1379) (88.3, -0.5, 43.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1458) (88.3, -0.8, 44.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1377) (89.3, -0.8, 42.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1378) (89.3, -0.8, 43.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1459) (88.3, -0.8, 45.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1462) (90.8, 0.0, 55.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1463) (90.8, -0.3, 54.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1460) (91.8, -0.3, 54.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1461) (91.8, -0.3, 55.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1466) (88.3, -0.5, 71.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1467) (88.3, -0.8, 70.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1465) (89.3, -0.5, 71.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1464) (89.3, -0.5, 70.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1468) (88.3, -0.3, 82.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1471) (87.3, -0.3, 82.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1469) (88.3, -0.3, 83.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1470) (87.3, 0.0, 83.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1476) (86.5, -0.3, 88.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1477) (86.5, -0.3, 89.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1472) (86.5, -0.3, 90.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1474) (85.5, 0.0, 91.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1475) (85.5, -0.3, 90.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1261) (156.8, 4.0, -60.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1264) (156.8, 4.0, -61.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1262) (157.8, 4.0, -61.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1208) (160.8, 7.5, 15.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1207) (160.8, 7.5, 16.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1216) (158.8, 7.5, 18.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1203) (163.8, 7.5, 14.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1202) (162.8, 7.5, 15.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1204) (162.8, 7.5, 14.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1206) (161.8, 7.5, 15.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1205) (161.8, 7.5, 16.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1210) (161.8, 7.5, 17.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1209) (161.8, 7.5, 18.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1212) (160.8, 7.5, 17.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1211) (160.8, 7.5, 18.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1214) (159.8, 7.5, 18.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1213) (159.8, 7.5, 19.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1215) (158.8, 7.5, 19.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1200) (163.0, 7.5, 9.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1198) (163.0, 7.5, 10.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1199) (164.0, 7.5, 9.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1197) (164.0, 7.5, 10.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1219) (155.3, 7.5, 11.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1217) (156.3, 7.5, 11.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1218) (156.3, 7.5, 10.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1220) (155.3, 7.5, 10.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1240) (165.8, 7.5, 2.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1241) (165.8, 7.5, 1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1270) (157.0, 15.8, -43.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1272) (157.0, 15.8, -42.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1273) (158.0, 15.8, -42.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1269) (157.0, 15.8, -44.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1268) (156.0, 15.8, -43.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1271) (156.0, 15.8, -44.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1248) (168.5, 15.8, -40.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1246) (169.5, 15.8, -40.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1247) (169.5, 15.8, -39.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1242) (168.5, 15.8, -39.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1249) (168.5, 15.8, -50.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1252) (168.5, 15.8, -51.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1251) (169.5, 15.8, -50.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1250) (169.5, 15.8, -51.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1255) (172.3, 15.8, -54.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1253) (171.3, 15.8, -54.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1256) (171.3, 15.8, -55.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1254) (172.3, 15.8, -55.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1257) (166.8, 15.8, -58.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1260) (166.8, 15.8, -59.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1259) (167.8, 15.8, -58.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1258) (167.8, 15.8, -59.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1266) (158.5, 15.8, -57.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1265) (158.5, 15.8, -58.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1263) (157.5, 15.8, -57.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1267) (157.5, 15.8, -58.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1285) (140.5, 15.8, -45.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1282) (140.5, 15.8, -44.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1283) (141.5, 15.8, -45.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1284) (141.5, 15.8, -44.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1288) (132.5, 15.8, -48.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1293) (129.5, 15.8, -48.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1290) (129.5, 15.8, -47.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1289) (131.5, 15.8, -49.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1286) (131.5, 15.8, -48.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1291) (130.5, 15.8, -48.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1292) (130.5, 15.8, -47.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1287) (132.5, 15.8, -49.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1281) (169.5, 15.8, -28.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1275) (168.3, 15.8, -26.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1279) (170.5, 15.8, -28.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1280) (170.5, 15.8, -27.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1278) (169.5, 15.8, -27.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1276) (168.3, 15.8, -25.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1277) (167.3, 15.8, -26.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1274) (167.3, 15.8, -25.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1167) (170.0, 15.8, -18.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1169) (170.0, 15.8, -19.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1166) (171.0, 15.8, -18.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1168) (171.0, 15.8, -19.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1163) (171.0, 15.8, -20.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1165) (171.0, 15.8, -21.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1164) (172.0, 15.8, -21.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1162) (172.0, 15.8, -20.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1148) (183.8, 15.8, -18.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1161) (180.0, 15.8, -14.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1157) (181.0, 15.8, -13.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1160) (181.0, 15.8, -14.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1159) (180.0, 15.8, -13.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1146) (183.8, 15.8, -17.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1152) (184.8, 15.8, -20.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1150) (184.8, 15.8, -19.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1145) (184.8, 15.8, -17.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1147) (184.8, 15.8, -18.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1151) (185.8, 15.8, -20.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1149) (185.8, 15.8, -19.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1156) (187.8, 15.8, -24.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1154) (188.8, 15.8, -24.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1158) (187.8, 15.8, -25.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1155) (192.8, 15.8, -15.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1153) (192.8, 15.8, -14.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1093) (192.0, 15.8, -9.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1098) (193.0, 15.8, -8.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1099) (193.0, 15.8, -9.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1094) (193.0, 15.8, -9.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1102) (193.0, 15.8, -5.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1101) (193.0, 15.8, -4.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1096) (192.0, 15.8, -10.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1095) (193.0, 15.8, -10.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1097) (193.0, 15.8, -2.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1018) (193.0, 15.8, -1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1100) (193.0, 15.8, -3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1019) (192.0, 15.8, -1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1017) (193.0, 15.8, -0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1022) (193.0, 15.8, 0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1027) (192.0, 15.8, 2.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1023) (192.0, 15.8, 0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1020) (192.0, 15.8, 1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1016) (192.0, 15.8, -0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1026) (193.0, 15.8, 2.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1021) (193.0, 15.8, 1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1133) (190.0, 15.8, 1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1135) (190.0, 15.8, 0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1136) (189.0, 15.8, 0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1134) (189.0, 15.8, 1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1137) (185.3, 15.8, -0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1139) (185.3, 15.8, -1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1028) (191.0, 15.8, 3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1029) (191.0, 15.8, 2.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1025) (193.0, 15.8, 3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1024) (192.0, 15.8, 3.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1031) (193.0, 15.8, 5.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1032) (193.0, 15.8, 4.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1138) (184.3, 15.8, -0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1140) (184.3, 15.8, -1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1131) (173.0, 15.8, -1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1127) (171.0, 15.8, -0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1130) (172.0, 15.8, -0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1132) (172.0, 15.8, -1.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1129) (173.0, 15.8, -0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1142) (176.8, 15.8, -7.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1141) (177.8, 15.8, -7.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1143) (177.8, 15.8, -8.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1144) (176.8, 15.8, -8.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1128) (170.0, 15.8, -0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1125) (171.0, 15.8, 0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1126) (170.0, 15.8, 0.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1121) (177.8, 15.8, 5.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1123) (177.8, 15.8, 4.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1122) (176.8, 15.8, 5.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1124) (176.8, 15.8, 4.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1010) (173.8, 15.8, 9.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1011) (172.8, 15.8, 9.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1013) (175.8, 15.8, 11.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1014) (175.8, 15.8, 10.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1012) (174.8, 15.8, 11.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1015) (174.8, 15.8, 10.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1008) (172.8, 15.8, 10.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1009) (173.8, 15.8, 10.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1001) (168.3, 15.8, 15.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1003) (169.3, 15.8, 15.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1006) (168.3, 15.8, 14.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (999) (168.3, 15.8, 17.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1000) (168.3, 15.8, 16.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1004) (169.3, 15.8, 16.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1005) (169.3, 15.8, 17.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1007) (167.3, 15.8, 14.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1002) (167.3, 15.8, 15.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1188) (164.3, 15.8, 21.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1186) (163.3, 15.8, 22.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1189) (163.3, 15.8, 21.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1110) (180.8, 15.8, 13.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1109) (180.8, 15.8, 14.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1107) (181.8, 15.8, 14.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1108) (181.8, 15.8, 13.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1105) (181.3, 15.8, 11.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1103) (182.3, 15.8, 11.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1112) (182.8, 15.8, 15.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1111) (182.8, 15.8, 16.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1114) (181.8, 15.8, 15.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1113) (181.8, 15.8, 16.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1106) (181.3, 15.8, 10.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1104) (182.3, 15.8, 10.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1115) (182.3, 15.8, 9.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1116) (181.3, 15.8, 9.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1117) (187.8, 15.8, 10.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1118) (186.8, 15.8, 10.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1120) (186.8, 15.8, 9.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1119) (187.8, 15.8, 9.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1036) (192.0, 15.8, 13.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1039) (192.0, 15.8, 12.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1042) (189.3, 15.8, 16.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1043) (188.3, 15.8, 16.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1040) (193.0, 15.8, 11.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1038) (193.0, 15.8, 12.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1037) (193.0, 15.8, 13.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1034) (193.0, 15.8, 14.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1033) (193.0, 15.8, 15.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1030) (192.0, 15.8, 15.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1035) (192.0, 15.8, 14.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1047) (187.0, 15.8, 18.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1048) (186.0, 15.8, 18.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1041) (188.3, 15.8, 17.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1045) (187.0, 15.8, 19.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1046) (186.0, 15.8, 19.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1044) (186.0, 15.8, 20.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Bush (1) (182.3, 16.0, 33.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Bush (184.3, 16.0, 33.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1173) (184.8, 15.8, 30.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1170) (184.8, 15.8, 31.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1171) (185.8, 15.8, 31.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1172) (185.8, 15.8, 30.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1088) (188.8, 15.8, 33.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1078) (187.8, 15.8, 32.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1077) (186.8, 15.8, 32.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1075) (186.8, 15.8, 33.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1074) (186.8, 15.8, 34.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1080) (186.8, 15.8, 31.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1076) (185.8, 15.8, 33.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1073) (185.8, 15.8, 34.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1072) (185.8, 15.8, 35.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1069) (185.8, 15.8, 36.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1059) (184.8, 15.8, 37.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1051) (184.8, 15.8, 35.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1050) (184.8, 15.8, 36.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1057) (183.8, 15.8, 38.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1052) (183.8, 15.8, 35.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1060) (183.8, 15.8, 37.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1049) (183.8, 15.8, 36.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1055) (182.8, 15.8, 35.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1054) (182.8, 15.8, 36.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1053) (181.8, 15.8, 36.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1056) (181.8, 15.8, 35.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1176) (179.5, 15.8, 36.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1071) (186.8, 15.8, 35.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1070) (186.8, 15.8, 36.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1092) (187.8, 15.8, 35.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1085) (188.8, 15.8, 34.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1086) (189.8, 15.8, 34.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1090) (188.8, 15.8, 36.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1091) (188.8, 15.8, 35.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1089) (187.8, 15.8, 36.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1067) (186.8, 15.8, 39.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1066) (186.8, 15.8, 40.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1068) (185.8, 15.8, 39.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1062) (184.8, 15.8, 40.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1058) (184.8, 15.8, 38.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1063) (184.8, 15.8, 39.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1064) (183.8, 15.8, 39.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1061) (183.8, 15.8, 40.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1065) (185.8, 15.8, 40.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1175) (179.5, 15.8, 37.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1177) (178.5, 15.8, 36.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1174) (178.5, 15.8, 37.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Bush (2) (178.3, 16.0, 39.0)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1179) (176.8, 15.8, 40.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1180) (176.8, 15.8, 39.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1178) (175.8, 15.8, 40.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1181) (175.8, 15.8, 39.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1192) (169.0, 15.8, 38.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1191) (170.0, 15.8, 38.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1190) (170.0, 15.8, 39.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1187) (169.0, 15.8, 39.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1183) (165.3, 15.8, 33.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1182) (164.3, 15.8, 33.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1185) (164.3, 15.8, 32.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1184) (165.3, 15.8, 32.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1510) (165.0, 16.5, 42.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1509) (166.0, 16.0, 42.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1508) (166.0, 16.0, 43.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1507) (165.0, 16.5, 43.5)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1196) (153.8, 15.8, 40.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1195) (154.8, 15.8, 40.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1194) (154.8, 15.8, 41.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1193) (153.8, 15.8, 41.8)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1505) (148.0, 15.8, 31.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1504) (148.0, 15.8, 30.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1503) (147.0, 15.8, 31.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Swamp Mid Grass swamp (1506) (147.0, 15.8, 30.3)": TunicLocationData("Swamp Mid", "Swamp Mid"), + "Swamp - Back of Swamp Grass swamp (1494) (83.8, -0.3, 129.5)": TunicLocationData("Back of Swamp", "Back of Swamp"), + "Swamp - Back of Swamp Grass swamp (1495) (83.8, -0.3, 130.5)": TunicLocationData("Back of Swamp", "Back of Swamp"), + "Swamp - Back of Swamp Grass swamp (1496) (82.8, 0.0, 130.5)": TunicLocationData("Back of Swamp", "Back of Swamp"), + "Swamp - Back of Swamp Grass swamp (1497) (82.8, -0.3, 129.5)": TunicLocationData("Back of Swamp", "Back of Swamp"), + "Swamp - Back of Swamp Grass swamp (1501) (82.8, -0.3, 131.5)": TunicLocationData("Back of Swamp", "Back of Swamp"), + "Swamp - Back of Swamp Grass swamp (1498) (83.8, -0.3, 131.5)": TunicLocationData("Back of Swamp", "Back of Swamp"), + "Swamp - Back of Swamp Grass swamp (1499) (83.8, -0.3, 132.5)": TunicLocationData("Back of Swamp", "Back of Swamp"), + "Swamp - Back of Swamp Grass swamp (1500) (83.0, -1.0, 141.5)": TunicLocationData("Back of Swamp", "Back of Swamp"), + "Swamp - Back of Swamp Grass swamp (1502) (83.0, -1.0, 142.5)": TunicLocationData("Back of Swamp", "Back of Swamp"), + "Swamp - Back of Swamp Laurels Area Grass swamp (991) (34.5, 8.3, 31.8)": TunicLocationData( + "Back of Swamp Laurels Area", "Back of Swamp Laurels Area"), + "Swamp - Back of Swamp Laurels Area Grass swamp (992) (34.5, 8.0, 30.8)": TunicLocationData( + "Back of Swamp Laurels Area", "Back of Swamp Laurels Area"), + "Swamp - Back of Swamp Laurels Area Grass swamp (989) (35.5, 8.0, 30.8)": TunicLocationData( + "Back of Swamp Laurels Area", "Back of Swamp Laurels Area"), + "Swamp - Back of Swamp Laurels Area Grass swamp (990) (35.5, 8.0, 31.8)": TunicLocationData( + "Back of Swamp Laurels Area", "Back of Swamp Laurels Area"), + "Swamp - Back of Swamp Laurels Area Grass swamp (995) (32.5, 8.3, 31.8)": TunicLocationData( + "Back of Swamp Laurels Area", "Back of Swamp Laurels Area"), + "Swamp - Back of Swamp Laurels Area Grass swamp (994) (33.5, 8.0, 31.8)": TunicLocationData( + "Back of Swamp Laurels Area", "Back of Swamp Laurels Area"), +} + +excluded_grass_locations = { + "Overworld - Overworld Bush (7) (-39.0, 40.0, -41.0)", + "Overworld - Overworld Bush (2) (-41.0, 40.0, -41.0)", + "Overworld - Overworld Bush (16) (53.0, 12.0, -151.0)", + "Overworld - Overworld Bush (9) (-19.0, 28.0, -103.0)", + "Overworld - Overworld Bush (23) (-19.0, 28.0, -105.0)", + "Overworld - Overworld Bush (26) (-19.0, 28.0, -107.0)", + "Overworld - Overworld Bush (47) (91.0, 12.0, -155.0)", + "Overworld - Overworld Bush (42) (91.0, 12.0, -157.0)", + "Overworld - East Overworld Bush (58) (58.0, 44.0, -109.0)", + "Overworld - East Overworld Bush (62) (66.5, 44.0, -111.0)", + "Overworld - East Overworld Bush (64) (56.0, 44.0, -107.0)", +} + +grass_location_name_to_id: Dict[str, int] = {name: location_base_id + 302 + index for index, name in enumerate(grass_location_table)} + +grass_location_name_groups: Dict[str, Set[str]] = {} +for loc_name, loc_data in grass_location_table.items(): + loc_group_name = loc_name.split(" - ", 1)[0] + " Grass" + grass_location_name_groups.setdefault(loc_group_name, set()).add(loc_name) + + +def can_break_grass(state: CollectionState, world: "TunicWorld") -> bool: + player = world.player + # no gun or wand because they're extremely tedious + return (has_sword(state, player) + or (has_melee(state, player) and state.has("Glass Cannon", player))) + + +def set_grass_location_rules(world: "TunicWorld") -> None: + player = world.player + + if not world.options.start_with_sword: + for location in grass_location_table.keys(): + set_rule(world.get_location(location), + lambda state: can_break_grass(state, world)) + + set_rule(world.get_location("Fortress Courtyard - Fortress Courtyard Upper Grass (1) (72.0, 8.0, -29.0)"), + lambda state: state.has("Magic Wand", player)) + + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (325) (-111.8, 1.3, 2.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (323) (-111.8, 1.3, 1.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (316) (-110.5, 1.3, 3.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (319) (-111.5, 1.3, 4.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (317) (-111.5, 1.3, 3.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (318) (-110.5, 1.3, 4.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (321) (-112.3, 1.3, 4.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (320) (-112.3, 1.3, 3.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (326) (-112.8, 1.3, 2.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (327) (-113.5, 1.3, 2.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (324) (-112.8, 1.3, 1.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (322) (-113.5, 1.3, 1.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (328) (-112.0, 0.8, -2.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (329) (-112.0, 0.5, -3.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (333) (-111.3, 0.8, -2.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (331) (-111.3, 0.5, -3.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (330) (-110.3, 0.5, -3.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (332) (-110.3, 0.8, -2.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (334) (-111.0, 0.3, -4.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (337) (-110.3, 0.3, -4.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (354) (-113.0, 0.3, -4.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (353) (-112.0, 0.3, -4.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (336) (-109.3, 0.3, -4.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (338) (-109.3, -0.3, -5.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (339) (-110.3, -0.3, -5.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (335) (-111.0, -0.3, -5.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (350) (-112.0, -0.3, -5.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (349) (-113.8, 0.3, -4.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (351) (-113.0, -0.3, -5.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (352) (-113.8, -0.3, -5.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (314) (-112.3, 0.8, 6.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (315) (-112.3, 0.8, 7.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (313) (-111.5, 0.8, 6.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (311) (-111.5, 0.8, 7.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (310) (-110.5, 0.8, 7.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (306) (-110.5, 0.8, 8.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (312) (-110.5, 0.8, 6.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (307) (-109.5, 0.8, 8.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (308) (-111.5, 0.8, 8.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (300) (-107.5, 0.0, 10.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (301) (-107.5, 0.3, 9.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (304) (-108.3, 0.0, 10.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (299) (-108.5, 0.0, 10.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (303) (-110.5, 0.3, 9.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (302) (-109.5, 0.3, 9.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (305) (-109.5, 0.0, 10.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (298) (-108.5, 0.3, 9.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (341) (-113.5, 0.8, 10.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (344) (-113.5, 0.5, 11.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (346) (-113.5, 0.8, 9.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (309) (-111.5, 0.5, 9.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (345) (-112.5, 0.8, 9.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (342) (-112.5, 0.8, 8.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (340) (-112.5, 0.8, 10.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (347) (-114.3, 0.8, 8.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (348) (-114.3, 0.8, 9.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (343) (-113.5, 0.8, 8.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (297) (-99.0, 0.8, 7.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass beach (296) (-98.0, 0.8, 7.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (191) (-89.5, 6.5, 53.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (190) (-89.5, 6.5, 54.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (189) (-88.5, 6.5, 54.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (188) (-88.5, 6.5, 53.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (197) (-87.0, 13.0, 75.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (194) (-87.0, 13.0, 74.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (184) (-86.0, 13.0, 73.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (183) (-86.0, 13.0, 74.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (181) (-86.0, 13.0, 75.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (185) (-84.7, 13.0, 73.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (182) (-83.0, 13.0, 72.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (199) (-83.0, 13.0, 70.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (201) (-84.0, 13.0, 70.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (135) (-83.5, 13.0, 58.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (128) (-82.5, 13.0, 57.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (130) (-82.5, 13.0, 58.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (147) (-86.0, 13.0, 54.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (132) (-82.5, 13.0, 60.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (134) (-83.5, 13.0, 59.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (131) (-82.5, 13.0, 59.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (136) (-78.5, 13.0, 56.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (139) (-79.5, 13.0, 55.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (133) (-79.5, 13.0, 56.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (138) (-80.5, 13.0, 55.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (137) (-80.5, 13.0, 56.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (143) (-85.0, 13.0, 53.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (142) (-86.0, 13.0, 53.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (145) (-87.0, 13.0, 53.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (146) (-87.0, 13.0, 54.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (140) (-85.0, 13.0, 52.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (141) (-86.0, 13.0, 52.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (144) (-84.0, 13.0, 52.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (192) (-70.5, 13.0, 56.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (186) (-69.5, 13.0, 56.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (187) (-69.5, 13.0, 55.8)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (123) (-82.5, 13.0, 44.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (126) (-82.5, 13.0, 45.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (121) (-83.5, 13.0, 45.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (124) (-83.5, 13.0, 44.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (125) (-83.5, 13.0, 43.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (151) (-82.5, 13.0, 27.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (152) (-82.5, 13.0, 26.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (150) (-81.5, 13.0, 27.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (148) (-81.5, 13.0, 25.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (149) (-81.5, 13.0, 26.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (154) (-79.0, 13.0, 23.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (153) (-78.0, 13.0, 23.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (161) (-68.0, 13.0, 26.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (162) (-68.0, 13.0, 27.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (165) (-69.0, 13.0, 27.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (164) (-69.0, 13.0, 28.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (163) (-68.0, 13.0, 28.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (166) (-68.0, 13.0, 29.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (167) (-63.0, 13.0, 24.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (168) (-62.0, 13.0, 24.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (170) (-61.0, 13.0, 25.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (169) (-62.0, 13.0, 25.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (172) (-62.0, 13.0, 26.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (178) (-61.0, 13.0, 43.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (175) (-60.0, 13.0, 43.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (177) (-61.0, 13.0, 44.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (174) (-59.0, 13.0, 42.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (173) (-59.0, 13.0, 43.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (171) (-59.0, 13.0, 44.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (176) (-60.0, 13.0, 44.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (159) (-83.5, 8.0, 23.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (160) (-83.5, 8.0, 24.5)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (158) (-83.5, 8.0, 22.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (155) (-82.5, 8.0, 24.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (157) (-82.5, 8.0, 22.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Ruined Atoll - Ruined Atoll Grass (156) (-82.5, 8.0, 23.0)"), lambda state: state.has_any(("Hero's Laurels", "Magic Orb"), player)) + add_rule(world.get_location("Frog Stairway - Frog Stairs Lower Grass (9) (179.8, 61.9, -67.1)"), lambda state: state.has("Magic Orb", player)) + add_rule(world.get_location("Frog Stairway - Frog Stairs Lower Grass (8) (178.6, 61.9, -67.1)"), lambda state: state.has("Magic Orb", player)) + add_rule(world.get_location("Frog Stairway - Frog Stairs Lower Grass (7) (204.4, 58.1, -94.1)"), lambda state: state.has("Magic Orb", player)) + add_rule(world.get_location("Frog Stairway - Frog Stairs Lower Grass (5) (205.5, 58.1, -94.1)"), lambda state: state.has("Magic Orb", player)) + add_rule(world.get_location("Frog Stairway - Frog Stairs Lower Grass (6) (205.5, 58.1, -93.0)"), lambda state: state.has("Magic Orb", player)) + add_rule(world.get_location("Frog Stairway - Frog Stairs Lower Grass (2) (205.5, 54.0, -77.0)"), lambda state: state.has("Magic Orb", player)) + add_rule(world.get_location("Frog Stairway - Frog Stairs Lower Grass (205.5, 54.0, -76.0)"), lambda state: state.has("Magic Orb", player)) + add_rule(world.get_location("Frog Stairway - Frog Stairs Lower Grass (1) (204.5, 54.0, -76.0)"), lambda state: state.has("Magic Orb", player)) + add_rule(world.get_location("Frog Stairway - Frog Stairs Lower Grass (4) (201.4, 54.3, -71.3)"), lambda state: state.has("Magic Orb", player)) + add_rule(world.get_location("Frog Stairway - Frog Stairs Lower Grass (3) (200.4, 54.3, -71.3)"), lambda state: state.has("Magic Orb", player)) + add_rule(world.get_location("West Garden - West Garden Grass (207) (-310.8, 1.3, 164.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Grass (210) (-310.8, 1.3, 165.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Grass (209) (-312.0, 1.3, 165.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Grass (208) (-312.0, 1.3, 164.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Grass (174) (-243.9, 0.5, 52.1)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Grass (262) (-244.8, 0.5, 51.3)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Grass (263) (-244.8, 0.5, 52.3)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Swamp - Back of Swamp Laurels Area Grass swamp (991) (34.5, 8.3, 31.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Swamp - Back of Swamp Laurels Area Grass swamp (992) (34.5, 8.0, 30.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Swamp - Back of Swamp Laurels Area Grass swamp (989) (35.5, 8.0, 30.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Swamp - Back of Swamp Laurels Area Grass swamp (990) (35.5, 8.0, 31.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Swamp - Back of Swamp Laurels Area Grass swamp (995) (32.5, 8.3, 31.8)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("Swamp - Back of Swamp Laurels Area Grass swamp (994) (33.5, 8.0, 31.8)"), lambda state: state.has("Hero's Laurels", player)) diff --git a/worlds/tunic/items.py b/worlds/tunic/items.py index f30c1d5d248a..729bfd441172 100644 --- a/worlds/tunic/items.py +++ b/worlds/tunic/items.py @@ -166,6 +166,7 @@ class TunicItemData(NamedTuple): "Ladders in Library": TunicItemData(IC.progression, 0, 148, "Ladders"), "Ladders in Lower Quarry": TunicItemData(IC.progression, 0, 149, "Ladders"), "Ladders in Swamp": TunicItemData(IC.progression, 0, 150, "Ladders"), + "Grass": TunicItemData(IC.filler, 0, 151), } # items to be replaced by fool traps @@ -214,7 +215,7 @@ class TunicItemData(NamedTuple): item_name_to_id: Dict[str, int] = {name: item_base_id + data.item_id_offset for name, data in item_table.items()} -filler_items: List[str] = [name for name, data in item_table.items() if data.classification == IC.filler] +filler_items: List[str] = [name for name, data in item_table.items() if data.classification == IC.filler and name != "Grass"] def get_item_group(item_name: str) -> str: diff --git a/worlds/tunic/locations.py b/worlds/tunic/locations.py index c44852e8aab8..d0c4f860e47f 100644 --- a/worlds/tunic/locations.py +++ b/worlds/tunic/locations.py @@ -1,4 +1,5 @@ -from typing import Dict, NamedTuple, Set, Optional +from typing import Dict, NamedTuple, Set, Optional, List +from .grass import grass_location_table class TunicLocationData(NamedTuple): @@ -320,7 +321,27 @@ class TunicLocationData(NamedTuple): "Blue Questagon": "Rooted Ziggurat Lower - Hexagon Blue", } -location_name_to_id: Dict[str, int] = {name: location_base_id + index for index, name in enumerate(location_table)} +sphere_one: List[str] = [ + "Overworld - [Central] Chest Across From Well", + "Overworld - [Northwest] Chest Near Quarry Gate", + "Overworld - [Northwest] Shadowy Corner Chest", + "Overworld - [Southwest] Chest Guarded By Turret", + "Overworld - [Southwest] South Chest Near Guard", + "Overworld - [Southwest] Obscured in Tunnel to Beach", + "Overworld - [Northwest] Chest Near Turret", + "Overworld - [Northwest] Page By Well", + "Overworld - [West] Chest Behind Moss Wall", + "Overworld - [Southwest] Key Pickup", + "Overworld - [West] Key Pickup", + "Overworld - [West] Obscured Behind Windmill", + "Overworld - [West] Obscured Near Well", + "Overworld - [West] Page On Teleporter" +] + +standard_location_name_to_id: Dict[str, int] = {name: location_base_id + index for index, name in enumerate(location_table)} + +all_locations = location_table.copy() +all_locations.update(grass_location_table) location_name_groups: Dict[str, Set[str]] = {} for loc_name, loc_data in location_table.items(): diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index 24247a6cfdcf..9a04a137b044 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Dict, Any from Options import (DefaultOnToggle, Toggle, StartInventoryPool, Choice, Range, TextChoice, PlandoConnections, - PerGameCommonOptions, OptionGroup, Visibility) + PerGameCommonOptions, OptionGroup, Visibility, NamedRange) from .er_data import portal_mapping @@ -154,6 +154,33 @@ class ShuffleLadders(Toggle): display_name = "Shuffle Ladders" +class GrassRandomizer(Toggle): + """ + Turns over 6,000 blades of grass and bushes in the game into checks. + """ + internal_name = "grass_randomizer" + display_name = "Grass Randomizer" + + +class LocalFill(NamedRange): + """ + Choose the percentage of your filler/trap items that will be kept local or distributed to other TUNIC players with this option enabled. + If you have Grass Randomizer enabled, this option must be set to 95% or higher to avoid flooding the item pool. The host can remove this restriction by turning off the limit_grass_rando setting in host.yaml. + This option defaults to 95% if you have Grass Randomizer enabled, and to 0% otherwise. + This option ignores items placed in your local_items or non_local_items. + This option does nothing in single player games. + """ + internal_name = "local_fill" + display_name = "Local Fill Percent" + range_start = 0 + range_end = 100 + special_range_names = { + "default": -1 + } + default = -1 + visibility = Visibility.template | Visibility.complex_ui | Visibility.spoiler + + class TunicPlandoConnections(PlandoConnections): """ Generic connection plando. Format is: @@ -278,12 +305,13 @@ class TunicOptions(PerGameCommonOptions): combat_logic: CombatLogic lanternless: Lanternless maskless: Maskless + grass_randomizer: GrassRandomizer + local_fill: LocalFill laurels_zips: LaurelsZips ice_grappling: IceGrappling ladder_storage: LadderStorage ladder_storage_without_items: LadderStorageWithoutItems plando_connections: TunicPlandoConnections - logic_rules: LogicRules From b7621a0923c78dc3062da25c859a7f70cea56064 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Wed, 15 Jan 2025 18:52:12 -0500 Subject: [PATCH 0038/1218] TLoZ: Fix typo in setup guide (#4486) --- worlds/tloz/docs/multiworld_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/tloz/docs/multiworld_en.md b/worlds/tloz/docs/multiworld_en.md index 366531e2e43a..e09d188ba4af 100644 --- a/worlds/tloz/docs/multiworld_en.md +++ b/worlds/tloz/docs/multiworld_en.md @@ -40,7 +40,7 @@ guide: [Basic Multiworld Setup Guide](/tutorial/Archipelago/setup/en) ### Where do I get a config file? The Player Options page on the website allows you to configure your personal options and export a config file from -them. Player options page: [The Legend of Zelda Player Sptions Page](/games/The%20Legend%20of%20Zelda/player-options) +them. Player options page: [The Legend of Zelda Player Options Page](/games/The%20Legend%20of%20Zelda/player-options) ### Verifying your config file From 902d03d447344f06397633255f2cf3f50d484203 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Wed, 15 Jan 2025 21:42:19 -0500 Subject: [PATCH 0039/1218] LADX: Stabilize Item Pool Option (#3935) Co-authored-by: Scipio Wright Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/ladx/LADXR/itempool.py | 6 ++++-- worlds/ladx/Options.py | 9 +++++++++ worlds/ladx/__init__.py | 13 ++++++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/worlds/ladx/LADXR/itempool.py b/worlds/ladx/LADXR/itempool.py index 50314883378a..68f3e54ecba9 100644 --- a/worlds/ladx/LADXR/itempool.py +++ b/worlds/ladx/LADXR/itempool.py @@ -68,10 +68,12 @@ class ItemPool: - def __init__(self, logic, settings, rnd): + def __init__(self, logic, settings, rnd, stabilize_item_pool: bool): self.__pool = {} self.__setup(logic, settings) - self.__randomizeRupees(settings, rnd) + + if not stabilize_item_pool: + self.__randomizeRupees(settings, rnd) def add(self, item, count=1): self.__pool[item] = self.__pool.get(item, 0) + count diff --git a/worlds/ladx/Options.py b/worlds/ladx/Options.py index d92bd931867d..a35bb870fd91 100644 --- a/worlds/ladx/Options.py +++ b/worlds/ladx/Options.py @@ -527,6 +527,13 @@ class InGameHints(DefaultOnToggle): display_name = "In-game Hints" +class StabilizeItemPool(DefaultOffToggle): + """ + By default, rupees in the item pool may be randomly swapped with bombs, arrows, powders, or capacity upgrades. This option disables that swapping, which is useful for plando. + """ + display_name = "Stabilize Item Pool" + + class ForeignItemIcons(Choice): """ Choose how to display foreign items. @@ -562,6 +569,7 @@ class ForeignItemIcons(Choice): TrendyGame, InGameHints, NagMessages, + StabilizeItemPool, Quickswap, HardMode, BootsControls @@ -631,6 +639,7 @@ class LinksAwakeningOptions(PerGameCommonOptions): no_flash: NoFlash in_game_hints: InGameHints overworld: Overworld + stabilize_item_pool: StabilizeItemPool warp_improvements: Removed additional_warp_points: Removed diff --git a/worlds/ladx/__init__.py b/worlds/ladx/__init__.py index 09a25eb1cd09..f20b7f8018aa 100644 --- a/worlds/ladx/__init__.py +++ b/worlds/ladx/__init__.py @@ -138,7 +138,8 @@ def convert_ap_options_to_ladxr_logic(self): world_setup = LADXRWorldSetup() world_setup.randomize(self.ladxr_settings, self.random) self.ladxr_logic = LADXRLogic(configuration_options=self.ladxr_settings, world_setup=world_setup) - self.ladxr_itempool = LADXRItemPool(self.ladxr_logic, self.ladxr_settings, self.random).toDict() + self.ladxr_itempool = LADXRItemPool(self.ladxr_logic, self.ladxr_settings, self.random, bool(self.options.stabilize_item_pool)).toDict() + def generate_early(self) -> None: self.dungeon_item_types = { @@ -225,7 +226,7 @@ def create_items(self) -> None: for _ in range(count): if item_name in exclude: exclude.remove(item_name) # this is destructive. create unique list above - self.multiworld.itempool.append(self.create_item("Nothing")) + self.multiworld.itempool.append(self.create_item(self.get_filler_item_name())) else: item = self.create_item(item_name) @@ -499,8 +500,14 @@ def remove(self, state, item: Item) -> bool: state.prog_items[self.player]["RUPEES"] -= self.rupees[item.name] return change + # Same fill choices and weights used in LADXR.itempool.__randomizeRupees + filler_choices = ("Bomb", "Single Arrow", "10 Arrows", "Magic Powder", "Medicine") + filler_weights = ( 10, 5, 10, 10, 1) + def get_filler_item_name(self) -> str: - return "Nothing" + if self.options.stabilize_item_pool: + return "Nothing" + return self.random.choices(self.filler_choices, self.filler_weights)[0] def fill_slot_data(self): slot_data = {} From c7810823e89af0275bb6a091b3961cca00347324 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:35:07 +0100 Subject: [PATCH 0040/1218] Core: Fix crash when trying to log an exception (#4313) * Fix crash when trying to log an exception In https://github.com/ArchipelagoMW/Archipelago/pull/3028, we added a new logging filter which checked `record.msg`. However, you can pass whatever you want into a logging call. In this case, what we missed was https://github.com/ArchipelagoMW/Archipelago/blob/ecc3094c70b3ee1f3e18d9299c03198564ec261a/MultiServer.py#L530C1-L530C37, where we pass an Exception object as the message. This currently causes a crash with the new filter. The logging module supports this. It has no typing and can handle passing objects as messages just fine. What you're supposed to use, as far as I understand it, is `record.getMessage()` instead of `record.msg`. * Update Utils.py Co-authored-by: Doug Hoskisson --------- Co-authored-by: Doug Hoskisson --- Utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Utils.py b/Utils.py index 8f5ba1a0f84f..0aa81af1502e 100644 --- a/Utils.py +++ b/Utils.py @@ -521,8 +521,8 @@ def __init__(self, filter_name: str, condition: typing.Callable[[logging.LogReco def filter(self, record: logging.LogRecord) -> bool: return self.condition(record) - file_handler.addFilter(Filter("NoStream", lambda record: not getattr(record, "NoFile", False))) - file_handler.addFilter(Filter("NoCarriageReturn", lambda record: '\r' not in record.msg)) + file_handler.addFilter(Filter("NoStream", lambda record: not getattr(record, "NoFile", False))) + file_handler.addFilter(Filter("NoCarriageReturn", lambda record: '\r' not in record.getMessage())) root_logger.addHandler(file_handler) if sys.stdout: formatter = logging.Formatter(fmt='[%(asctime)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S') From 5c56dc03578c24ecb443fa314824d200b3d38911 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 17 Jan 2025 01:27:36 +0100 Subject: [PATCH 0041/1218] SoE: fix logic for drain cave with OoB (#4496) Also adds py3.13 compat and missing hash for sdist --- worlds/soe/requirements.txt | 73 +++++++++++++++++++------------------ worlds/soe/test/test_oob.py | 45 +++++++++++++++++++---- 2 files changed, 75 insertions(+), 43 deletions(-) diff --git a/worlds/soe/requirements.txt b/worlds/soe/requirements.txt index 4bcacb33c33c..7d1bae0d6a7b 100644 --- a/worlds/soe/requirements.txt +++ b/worlds/soe/requirements.txt @@ -1,36 +1,37 @@ -pyevermizer==0.48.0 \ - --hash=sha256:069ce348e480e04fd6208cfd0f789c600b18d7c34b5272375b95823be191ed57 \ - --hash=sha256:58164dddaba2f340b0a8b4f39605e9dac46d8b0ffb16120e2e57bef2bfc1d683 \ - --hash=sha256:115dd09d38a10f11d4629b340dfd75e2ba4089a1ff9e9748a11619829e02c876 \ - --hash=sha256:b5e79cfe721e75cd7dec306b5eecd6385ce059e31ef7523ba7f677e22161ec6f \ - --hash=sha256:382882fa9d641b9969a6c3ed89449a814bdabcb6b17b558872d95008a6cc908b \ - --hash=sha256:92f67700e9132064a90858d391dd0b8fb111aff6dfd472befed57772d89ae567 \ - --hash=sha256:fe4c453b7dbd5aa834b81f9a7aedb949a605455650b938b8b304d8e5a7edcbf7 \ - --hash=sha256:c6bdbc45daf73818f763ed59ad079f16494593395d806f772dd62605c722b3e9 \ - --hash=sha256:bb09f45448fdfd28566ae6fcc38c35a6632f4c31a9de2483848f6ce17b2359b5 \ - --hash=sha256:00a8b9014744bd1528d0d39c33ede7c0d1713ad797a331cebb33d377a5bc1064 \ - --hash=sha256:64ee69edc0a7d3b3caded78f2e46975f9beaff1ff8feaf29b87da44c45f38d7d \ - --hash=sha256:9211bdb1313e9f4869ed5bdc61f3831d39679bd08bb4087f1c1e5475d9e3018b \ - --hash=sha256:4a57821e422a1d75fe3307931a78db7a65e76955f8e401c4b347db6570390d09 \ - --hash=sha256:04670cee0a0b913f24d2b9a1e771781560e2485bda31e6cd372a08421cf85cfa \ - --hash=sha256:971fe77d0a20a1db984020ad253b613d0983f5e23ff22cba60ee5ac00d8128de \ - --hash=sha256:127265fdb49f718f54706bf15604af1cec23590afd00d423089dea4331dcfc61 \ - --hash=sha256:d47576360337c1a23f424cd49944a8d68fc4f3338e00719c9f89972c84604bef \ - --hash=sha256:879659603e51130a0de8d9885d815a2fa1df8bd6cebe6d520d1c6002302adfdb \ - --hash=sha256:6a91bfc53dd130db6424adf8ac97a1133e97b4157ed00f889d8cbd26a2a4b340 \ - --hash=sha256:f3bf35fc5eef4cda49d2de77339fc201dd3206660a3dc15db005625b15bb806c \ - --hash=sha256:e7c8d5bf59a3c16db20411bc5d8e9c9087a30b6b4edf1b5ed9f4c013291427e4 \ - --hash=sha256:054a4d84ffe75448d41e88e1e0642ef719eb6111be5fe608e71e27a558c59069 \ - --hash=sha256:e6f141ca367469c69ba7fbf65836c479ec6672c598cfcb6b39e8098c60d346bc \ - --hash=sha256:6e65eb88f0c1ff4acde1c13b24ce649b0fe3d1d3916d02d96836c781a5022571 \ - --hash=sha256:e61e8f476b6da809cf38912755ed8bb009665f589e913eb8df877e9fa763024b \ - --hash=sha256:7e7c5484c0a2e3da6064de3f73d8d988d6703db58ab0be4730cbbf1a82319237 \ - --hash=sha256:9033b954e5f4878fd94af6d2056c78e3316115521fb1c24a4416d5cbf2ad66ad \ - --hash=sha256:824c623fff8ae4da176306c458ad63ad16a06a495a16db700665eca3c115924f \ - --hash=sha256:8e31031409a8386c6a63b79d480393481badb3ba29f32ff7a0db2b4abed20ac8 \ - --hash=sha256:7dbb7bb13e1e94f69f7ccdbcf4d35776424555fce5af1ca29d0256f91fdf087a \ - --hash=sha256:3a24e331b259407b6912d6e0738aa8a675831db3b7493fcf54dc17cb0cb80d37 \ - --hash=sha256:fdda06662a994271e96633cba100dd92b2fcd524acef8b2f664d1aaa14503cbd \ - --hash=sha256:0f0fc81bef3dbb78ba6a7622dd4296f23c59825968a0bb0448beb16eb3397cc2 \ - --hash=sha256:e07cbef776a7468669211546887357cc88e9afcf1578b23a4a4f2480517b15d9 \ - --hash=sha256:e442212695bdf60e455673b7b9dd83a5d4b830d714376477093d2c9054d92832 +pyevermizer==0.48.1 \ + --hash=sha256:db85cb4760abfde9d4b566d4613f2eddb8c2ff6f1c202ca0c2c5800bd62c9507 \ + --hash=sha256:1c67d0dff0a42b9a037cdb138c0c7b2c776d8d7425830e7fd32f7ebf8f35ac00 \ + --hash=sha256:d417f5b0407b063496aca43a65389e3308b6d0933c1d7907f7ecc8a00057903b \ + --hash=sha256:abf6560204128783239c8f0fb15059a7c2ff453812f85fb8567766706b7839cc \ + --hash=sha256:39e0cba1de1bc108c5b770ebe0fcbf3f6cb05575daf6bebe78c831c74848d101 \ + --hash=sha256:a16054ce0d904749ef27ede375c0ca8f420831e28c4e84c67361e8181207f00d \ + --hash=sha256:e6de509e4943bcde3e207a3640cad8efe3d8183740b63dc3cdbf5013db0f618b \ + --hash=sha256:e9269cf1290ab2967eaac0bc24e658336fb0e1f6612efce8d7ef0e76c1c26200 \ + --hash=sha256:f69e244229a110183d36b6a43ca557e716016d17e11265dca4070b8857afdb8d \ + --hash=sha256:118d059b8ccd246dafb0a51d0aa8e4543c172f9665378983b9f43c680487732e \ + --hash=sha256:185210c68b16351b3add4896ecfc26fe3867dadee9022f6a256e13093cca4a3b \ + --hash=sha256:10e281612c38bbec11d35f5c09f5a5174fb884cc60e6f16b6790d854e4346678 \ + --hash=sha256:9fc7d7e986243a96e96c1c05a386eb5d2ae4faef1ba810ab7e9e63dd83e86c2b \ + --hash=sha256:c26eafc2230dca9e91aaf925a346532586d0f448456437ea4ce5054e15653fd8 \ + --hash=sha256:8f96ffc5cfbe17b5c08818052be6f96906a1c9d3911e7bc4fbefee9b9ffa8f15 \ + --hash=sha256:e40948cbcaab27aa4febb58054752f83357e81f4a6f088da22a71c4ec9aa7ef2 \ + --hash=sha256:d59369cafa5df0fd2ce5cd5656c926e2fc0226a5a67a003d95497d56a0728dd3 \ + --hash=sha256:345a25675d92aada5d94bc3f3d3e2946efd940a7228628bf8c05d2853ddda86d \ + --hash=sha256:c0aa5054178c5e9900bfcf393c2bffdc69921d165521a3e9e5271528b01ef442 \ + --hash=sha256:719d417fc21778d5036c9d25b7ce55582ab6f49da63ab93ec17d75ea6042364c \ + --hash=sha256:28e220939850cfd8da16743365b28fa36d5bfc1dc58564789ae415e014ebc354 \ + --hash=sha256:770e582000abf64dc7f0c62672e4a1f64729bb20695664c59e29d238398cb865 \ + --hash=sha256:61d451b6f7d76fd435a5e9d2df111533e6e43da397a457f310151917318bd175 \ + --hash=sha256:1c8b596e246bb8437c7fc6c9bb8d9c2c70bd9942f09b06ada02d2fabe596fa0b \ + --hash=sha256:617f3eb0938e71a07b16477529f97fdf64487875462eb2edba6c9820b9686c0a \ + --hash=sha256:98d655a256040a3ae6305145a9692a5483ddcfb9b9bbdb78d43f5e93e002a3ae \ + --hash=sha256:d565bde7b1eb873badeedc2c9f327b4e226702b571aab2019778d46aa4509572 \ + --hash=sha256:e04b89d6edf6ffdbf5c725b0cbf7375c87003378da80e6666818a2b6d59d3fc9 \ + --hash=sha256:cc35e72f2a9e438786451f54532ce663ca63aedc3b4a43532f4ee97b45a71ed1 \ + --hash=sha256:2e4640a975bf324e75f15edd6450e63db8228e2046b893bbdc47d896d5aec890 \ + --hash=sha256:752716024255f13f96e40877b932694a517100a382a13f76c0bed3116b77f6d6 \ + --hash=sha256:d36518349132cf2f3f4e5a6b0294db0b40f395daa620b0938227c2c8f5b1213e \ + --hash=sha256:b5bca6e7fe5dcccd1e8757db4fb20d4bd998ed2b0f4b9ed26f7407c0a9b48d9f \ + --hash=sha256:4663b727d2637ce7713e3db7b68828ca7dc6f03482f4763a055156f3fd16e026 \ + --hash=sha256:7732bec7ffb29337418e62f15dc924e229faf09c55b079ad3f46f47eedc10c0d \ + --hash=sha256:b83a7a4df24800f82844f6acc6d43cd4673de0c24c9041ab56e57f518defa5a1 \ diff --git a/worlds/soe/test/test_oob.py b/worlds/soe/test/test_oob.py index 3c1a2829de8e..0878fd56e376 100644 --- a/worlds/soe/test/test_oob.py +++ b/worlds/soe/test/test_oob.py @@ -12,13 +12,13 @@ def test_oob_access(self) -> None: # some locations that just need a weapon + OoB oob_reachable = [ "Aquagoth", "Sons of Sth.", "Mad Monk", "Magmar", # OoB can use volcano shop to skip rock skip - "Levitate", "Fireball", "Drain", "Speed", + "Levitate", "Fireball", "Speed", "E. Crustacia #107", "Energy Core #285", "Vanilla Gauge #57", ] # some locations that should still be unreachable oob_unreachable = [ "Tiny", "Rimsala", - "Barrier", "Call Up", "Reflect", "Force Field", "Stop", # Stop guy doesn't spawn for the other entrances + "Barrier", "Drain", "Call Up", "Reflect", "Force Field", "Stop", # Stop guy only spawns from one entrance "Pyramid bottom #118", "Tiny's hideout #160", "Tiny's hideout #161", "Greenhouse #275", ] # OoB + Diamond Eyes @@ -31,11 +31,42 @@ def test_oob_access(self) -> None: "Tiny's hideout #161", ] - self.assertLocationReachability(reachable=oob_reachable, unreachable=oob_unreachable, satisfied=False) - self.collect_by_name("Gladiator Sword") - self.assertLocationReachability(reachable=oob_reachable, unreachable=oob_unreachable, satisfied=in_logic) - self.collect_by_name("Diamond Eye") - self.assertLocationReachability(reachable=de_reachable, unreachable=de_unreachable, satisfied=in_logic) + with self.subTest("No items", oob_logic=in_logic): + self.assertLocationReachability(reachable=oob_reachable, unreachable=oob_unreachable, satisfied=False) + with self.subTest("Cutting Weapon", oob_logic=in_logic): + self.collect_by_name("Gladiator Sword") + self.assertLocationReachability(reachable=oob_reachable, unreachable=oob_unreachable, satisfied=in_logic) + with self.subTest("Cutting Weapon + DEs", oob_logic=in_logic): + self.collect_by_name("Diamond Eye") + self.assertLocationReachability(reachable=de_reachable, unreachable=de_unreachable, satisfied=in_logic) + + def test_real_axe(self) -> None: + in_logic = self.options["out_of_bounds"] == "logic" + + # needs real Bronze Axe+, regardless of OoB + real_axe_required = [ + "Drain", + "Drain Cave #180", + "Drain Cave #181", + ] + also_des_required = [ + "Double Drain", + ] + + with self.subTest("No Axe", oob_logic=in_logic): + self.collect_by_name("Gladiator Sword") + self.assertLocationReachability(reachable=real_axe_required, satisfied=False) + with self.subTest("Bronze Axe", oob_logic=in_logic): + self.collect_by_name("Bronze Axe") + self.assertLocationReachability(reachable=real_axe_required, satisfied=True) + with self.subTest("Knight Basher", oob_logic=in_logic): + self.remove_by_name("Bronze Axe") + self.collect_by_name("Knight Basher") + self.assertLocationReachability(reachable=real_axe_required, satisfied=True) + self.assertLocationReachability(reachable=also_des_required, satisfied=False) + with self.subTest("Knight Basher + DEs", oob_logic=in_logic): + self.collect_by_name("Diamond Eye") + self.assertLocationReachability(reachable=also_des_required, satisfied=True) def test_oob_goal(self) -> None: # still need Energy Core with OoB if sequence breaks are not in logic From 9d4bd6eebd6e45331cd19c16e6114f1a4cd777fd Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 17 Jan 2025 01:53:50 +0100 Subject: [PATCH 0042/1218] pytest: only check tests/ and worlds/ (#4500) This allows having failing tests in CI in worlds_disabled and allows moving worlds there to disable tests. --- pytest.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pytest.ini b/pytest.ini index 33e0bab8a98f..f16ab34ec0e2 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,3 +2,6 @@ python_files = test_*.py Test*.py # TODO: remove Test* once all worlds have been ported python_classes = Test python_functions = test +testpaths = + tests + worlds From 78904151b0f81f3ce77cc94b78cb23c5fefba77c Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 17 Jan 2025 02:10:48 +0100 Subject: [PATCH 0043/1218] Test: fix typo in pytest.ini (#4502) The typo disabled a bunch of tests :S --- pytest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index f16ab34ec0e2..cd8fd8dfce37 100644 --- a/pytest.ini +++ b/pytest.ini @@ -3,5 +3,5 @@ python_files = test_*.py Test*.py # TODO: remove Test* once all worlds have bee python_classes = Test python_functions = test testpaths = - tests + test worlds From 90f80ce1c18b2577b2ce6a6e4b21f00cb4c46d99 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Fri, 17 Jan 2025 02:10:41 +0000 Subject: [PATCH 0044/1218] AHiT: Various logic fixes (#4492) * Fix Director boss photo logic The rules were being added to for the "Director" boss in `set_enemy_rules()`, which didn't exist because the boss created was called "Conductor" instead. The name of the boss has been changed to "Director", to match, because it is more accurate due to DJ Grooves possibly being the boss instead of The Conductor. The missing logic was the `Hookshot Badge` requirement, however, the boss events are only used as part of the `Camera Tourist - All Clear` location, which requires every boss event to be reachable, and the Toxic Flower boss also has a `Hookshot Badge` requirement, so the missing `Hookshot Badge` for the Director boss had no effect on logic. The boss event locations are hidden from spoiler output, so to get a spoiler showing the Director boss event accessed before having `Hookshot Badge`, spoiler output had to be modified to also show the hidden locations. Example sphere from playthrough that should not be possible because it gets the `Hookshot Badge` and the `Conductor` event (now renamed to `Director`) in the same sphere: ``` 5: { Act Completion (Time Rift - Dead Bird Studio): Relic (Crayon Box) Conductor - Dead Bird Studio Basement: Conductor Dead Bird Studio (Rift) - Page: Behind Cardboard Planet: Time Piece Dead Bird Studio (Rift) - Page: Near Time Rift Gate: Hookshot Badge Picture Perfect - Hats Buy Building: Metro Ticket - Blue Snatcher - Your Contract has Expired: Snatcher } ``` * Add missing Hookshot + Painting logic for Toilet boss picture Includes the Hard logic of crossing the gap with a cherry bridge instead of hookshot and the expert logic of being able to skip the boss firewall with a cherry hover. * Fix Alpine Skyline - Goat Outpost Horn region `Alpine Skyline - Goat Outpost Horn` is accessible from The Illness has Spread, but was being added to the region that is only accessible from Alpine Free Roam. `Alpine Skyline - Goat Outpost Horn` has been moved to the region that is accessible from both The Illness has Spread and Alpine Free Roam. * Add missing HitType.umbrella logic for Top of HQ Coin in Beat the Heat Like Heating up Mafia Town, the cannon to the Mafia HQ area only opens once all the faucets have been turned off by hitting them. This requires the Umbrella when umbrella logic is enabled, but the Snatcher Coin on top of Mafia HQ was missing this requirement when accessed from Beat the Heat. * Add missing Main Objective requirement for auto-completed Bonus Stamps When a Main Objective is not excluded, but the bonuses are excluded, the bonuses auto-complete once the Main Objective is completed. The requirement to complete the Main Objective was missing, so the logic was incorrectly awarding bonus stamps as soon as a Contract was unlocked, even when it was not possible to complete the Main Objective of that Contract. * Add missing Hookshot requirement for The Arctic Cruise - Toilet from Bon Voyage! `The Arctic Cruise - Toilet` is accessed from the `Cruise Ship` region, but it is only present in the Ship Shape and Bon Voyage! acts. Ship Shape and Rock the Boat can access `Cruise Ship` without any items, but Bon Voyage! requires the Hookshot Badge to reach `Cruise Ship`. With how the logic was set up, it was incorrectly giving access to `The Arctic Cruise - Toilet` if the player had access to Bon Voyage! but only had access to `Cruise Ship` through Rock the Boat. * Fix Expert logic Rush Hour-only ticket skips The code was checking `if not world.options.NoTicketSkips:`, but that would only be `True` for `False`. For "rush_hour" (for Rush Hour-only ticket skips), it would be `False`, causing Rush Hour-only ticket skips to act as if ticket skips were disabled. * Remove Mystifying Time Mesa: Zipline gaining Hookshot requirement in moderate logic Alpine Skyline - Mystifying Time Mesa: Zipline does not normally require Hookshot Badge because it is an implied requirement due to only being accessible from Alpine Free Roam which does require Hookshot Badge. In normal logic difficulty, the location does not have an explicit Hookshot Badge requirement, but moderate logic was adding a Hookshot Badge requirement. This extraneous Hookshot Badge requirement has been removed. * Fix Act Completion (Queen Vanessa's Manor) not being accessible with Dweller Mask/Brewing Hat It was logically requiring the Umbrella hit type only, whereas all the other locations in Queen Vanessa's Manor require the Dweller Bell hit type which additionally allows Dweller Mask or Brewing Hat. * Remove Dweller Mask requirement for Subcon Forest - Tall Tree Hookshot Swing The Dweller Mask is not used in the intended vanilla route to get this item, so this requirement seems to have been a mistake. * Remove unused SDJ option for Subcon Forest - Long Tree Climb Chest Hard logic can already reach this location with nothing (other than paintings), so the "or" logic of being able to perform an SDJ was unused. * Require any non-HUMT Mafia Town act for Hot Air Balloon with nothing Two buckets/beach balls are required to bucket/ball hover, but there is only a single beach ball accessible in Heating Up Mafia Town, and no accessible buckets. There is an alternative strategy for Top of Lighthouse that only requires a single beach ball, so that location can still be reached with nothing from Heating Up Mafia Town. * Use `get_difficulty()` helper in `set_enemy_rules` Co-authored-by: Exempt-Medic <60412657+exempt-medic@users.noreply.github.com> --------- Co-authored-by: Exempt-Medic <60412657+exempt-medic@users.noreply.github.com> --- worlds/ahit/DeathWishRules.py | 18 +++++++++++++++--- worlds/ahit/Locations.py | 7 +++---- worlds/ahit/Rules.py | 14 +++++++------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/worlds/ahit/DeathWishRules.py b/worlds/ahit/DeathWishRules.py index 1432ef5c0d75..76723d393199 100644 --- a/worlds/ahit/DeathWishRules.py +++ b/worlds/ahit/DeathWishRules.py @@ -141,9 +141,12 @@ def set_dw_rules(world: "HatInTimeWorld"): add_dw_rules(world, all_clear) add_rule(main_stamp, main_objective.access_rule) add_rule(all_clear, main_objective.access_rule) - # Only set bonus stamp rules if we don't auto complete bonuses + # Only set bonus stamp rules to require All Clear if we don't auto complete bonuses if not world.options.DWAutoCompleteBonuses and not world.is_bonus_excluded(all_clear.name): add_rule(bonus_stamps, all_clear.access_rule) + else: + # As soon as the Main Objective is completed, the bonuses auto-complete. + add_rule(bonus_stamps, main_objective.access_rule) if world.options.DWShuffle: for i in range(len(world.dw_shuffle)-1): @@ -343,6 +346,7 @@ def create_enemy_events(world: "HatInTimeWorld"): def set_enemy_rules(world: "HatInTimeWorld"): no_tourist = "Camera Tourist" in world.excluded_dws or "Camera Tourist" in world.excluded_bonuses + difficulty = get_difficulty(world) for enemy, regions in hit_list.items(): if no_tourist and enemy in bosses: @@ -372,6 +376,14 @@ def set_enemy_rules(world: "HatInTimeWorld"): or state.has("Zipline Unlock - The Lava Cake Path", world.player) or state.has("Zipline Unlock - The Windmill Path", world.player)) + elif enemy == "Toilet": + if area == "Toilet of Doom": + # The boss firewall is in the way and can only be skipped on Expert logic using a cherry hover. + add_rule(event, lambda state: has_paintings(state, world, 1, allow_skip=difficulty == Difficulty.EXPERT)) + if difficulty < Difficulty.HARD: + # Hard logic and above can cross the boss arena gap with a cherry bridge. + add_rule(event, lambda state: can_use_hookshot(state, world)) + elif enemy == "Director": if area == "Dead Bird Studio Basement": add_rule(event, lambda state: can_use_hookshot(state, world)) @@ -430,7 +442,7 @@ def set_enemy_rules(world: "HatInTimeWorld"): # Bosses "Mafia Boss": ["Down with the Mafia!", "Encore! Encore!", "Boss Rush"], - "Conductor": ["Dead Bird Studio Basement", "Killing Two Birds", "Boss Rush"], + "Director": ["Dead Bird Studio Basement", "Killing Two Birds", "Boss Rush"], "Toilet": ["Toilet of Doom", "Boss Rush"], "Snatcher": ["Your Contract has Expired", "Breaching the Contract", "Boss Rush", @@ -454,7 +466,7 @@ def set_enemy_rules(world: "HatInTimeWorld"): bosses = [ "Mafia Boss", - "Conductor", + "Director", "Toilet", "Snatcher", "Toxic Flower", diff --git a/worlds/ahit/Locations.py b/worlds/ahit/Locations.py index 9954514e8f3b..b34e6bb4a759 100644 --- a/worlds/ahit/Locations.py +++ b/worlds/ahit/Locations.py @@ -264,7 +264,6 @@ def get_location_names() -> Dict[str, int]: required_hats=[HatType.DWELLER], paintings=3), "Subcon Forest - Tall Tree Hookshot Swing": LocData(2000324766, "Subcon Forest Area", - required_hats=[HatType.DWELLER], hookshot=True, paintings=3), @@ -323,7 +322,7 @@ def get_location_names() -> Dict[str, int]: "Alpine Skyline - The Twilight Path": LocData(2000334434, "Alpine Skyline Area", required_hats=[HatType.DWELLER]), "Alpine Skyline - The Twilight Bell: Wide Purple Platform": LocData(2000336478, "The Twilight Bell"), "Alpine Skyline - The Twilight Bell: Ice Platform": LocData(2000335826, "The Twilight Bell"), - "Alpine Skyline - Goat Outpost Horn": LocData(2000334760, "Alpine Skyline Area"), + "Alpine Skyline - Goat Outpost Horn": LocData(2000334760, "Alpine Skyline Area (TIHS)", hookshot=True), "Alpine Skyline - Windy Passage": LocData(2000334776, "Alpine Skyline Area (TIHS)", hookshot=True), "Alpine Skyline - The Windmill: Inside Pon Cluster": LocData(2000336395, "The Windmill"), "Alpine Skyline - The Windmill: Entrance": LocData(2000335783, "The Windmill"), @@ -407,7 +406,7 @@ def get_location_names() -> Dict[str, int]: hit_type=HitType.umbrella_or_brewing, hookshot=True, paintings=1), "Act Completion (Queen Vanessa's Manor)": LocData(2000312017, "Queen Vanessa's Manor", - hit_type=HitType.umbrella, paintings=1), + hit_type=HitType.dweller_bell, paintings=1), "Act Completion (Mail Delivery Service)": LocData(2000312032, "Mail Delivery Service", required_hats=[HatType.SPRINT]), @@ -878,7 +877,7 @@ def get_location_names() -> Dict[str, int]: dlc_flags=HatDLC.death_wish), "Snatcher Coin - Top of HQ (DW: BTH)": LocData(0, "Beat the Heat", snatcher_coin="Snatcher Coin - Top of HQ", - dlc_flags=HatDLC.death_wish), + hit_type=HitType.umbrella, dlc_flags=HatDLC.death_wish), "Snatcher Coin - Top of Tower": LocData(0, "Mafia Town Area (HUMT)", snatcher_coin="Snatcher Coin - Top of Tower", dlc_flags=HatDLC.death_wish), diff --git a/worlds/ahit/Rules.py b/worlds/ahit/Rules.py index 183248a0e6d7..6753b8eb8147 100644 --- a/worlds/ahit/Rules.py +++ b/worlds/ahit/Rules.py @@ -414,7 +414,7 @@ def set_moderate_rules(world: "HatInTimeWorld"): # Moderate: Mystifying Time Mesa time trial without hats set_rule(world.multiworld.get_location("Alpine Skyline - Mystifying Time Mesa: Zipline", world.player), - lambda state: can_use_hookshot(state, world)) + lambda state: True) # Moderate: Goat Refinery from TIHS with Sprint only add_rule(world.multiworld.get_location("Alpine Skyline - Goat Refinery", world.player), @@ -493,9 +493,6 @@ def set_hard_rules(world: "HatInTimeWorld"): lambda state: has_paintings(state, world, 3, True)) # SDJ - add_rule(world.multiworld.get_location("Subcon Forest - Long Tree Climb Chest", world.player), - lambda state: can_use_hat(state, world, HatType.SPRINT) and has_paintings(state, world, 2), "or") - add_rule(world.multiworld.get_location("Act Completion (Time Rift - Curly Tail Trail)", world.player), lambda state: can_use_hat(state, world, HatType.SPRINT), "or") @@ -533,7 +530,10 @@ def set_expert_rules(world: "HatInTimeWorld"): # Expert: Mafia Town - Above Boats, Top of Lighthouse, and Hot Air Balloon with nothing set_rule(world.multiworld.get_location("Mafia Town - Above Boats", world.player), lambda state: True) set_rule(world.multiworld.get_location("Mafia Town - Top of Lighthouse", world.player), lambda state: True) - set_rule(world.multiworld.get_location("Mafia Town - Hot Air Balloon", world.player), lambda state: True) + # There are not enough buckets/beach balls to bucket/ball hover in Heating Up Mafia Town, so any other Mafia Town + # act is required. + add_rule(world.multiworld.get_location("Mafia Town - Hot Air Balloon", world.player), + lambda state: state.can_reach_region("Mafia Town Area", world.player), "or") # Expert: Clear Dead Bird Studio with nothing for loc in world.multiworld.get_region("Dead Bird Studio - Post Elevator Area", world.player).locations: @@ -590,7 +590,7 @@ def set_expert_rules(world: "HatInTimeWorld"): if world.is_dlc2(): # Expert: clear Rush Hour with nothing - if not world.options.NoTicketSkips: + if world.options.NoTicketSkips != NoTicketSkips.option_true: set_rule(world.multiworld.get_location("Act Completion (Rush Hour)", world.player), lambda state: True) else: set_rule(world.multiworld.get_location("Act Completion (Rush Hour)", world.player), @@ -739,7 +739,7 @@ def set_dlc1_rules(world: "HatInTimeWorld"): # This particular item isn't present in Act 3 for some reason, yes in vanilla too add_rule(world.multiworld.get_location("The Arctic Cruise - Toilet", world.player), - lambda state: state.can_reach("Bon Voyage!", "Region", world.player) + lambda state: (state.can_reach("Bon Voyage!", "Region", world.player) and can_use_hookshot(state, world)) or state.can_reach("Ship Shape", "Region", world.player)) From 2e4f5a64b3b40cbfb75b5af34cc4db32004ade09 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Thu, 16 Jan 2025 21:13:37 -0500 Subject: [PATCH 0045/1218] TUNIC: Make the local_fill option load in a specific number of locations (#4488) * Make it load in a specific number of locations * TunicLocation -> Location * Actually shuffle the list --- worlds/tunic/__init__.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 09279dd1bd86..388a44113a82 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -95,7 +95,7 @@ class TunicWorld(World): # for the local_fill option fill_items: List[TunicItem] - fill_locations: List[TunicLocation] + fill_locations: List[Location] amount_to_local_fill: int # so we only loop the multiworld locations once @@ -394,8 +394,6 @@ def remove_filler(amount: int) -> None: self.multiworld.itempool += tunic_items def pre_fill(self) -> None: - self.fill_locations = [] - if self.options.local_fill > 0 and self.multiworld.players > 1: # we need to reserve a couple locations so that we don't fill up every sphere 1 location reserved_locations: Set[str] = set(self.random.sample(sphere_one, 2)) @@ -406,8 +404,8 @@ def pre_fill(self) -> None: if len(viable_locations) < self.amount_to_local_fill: raise OptionError(f"TUNIC: Not enough locations for local_fill option for {self.player_name}. " f"This is likely due to excess plando or priority locations.") - - self.fill_locations += viable_locations + self.random.shuffle(viable_locations) + self.fill_locations = viable_locations[:self.amount_to_local_fill] @classmethod def stage_pre_fill(cls, multiworld: MultiWorld) -> None: From 1485882642cad9a542561015d35c675dabee8c9a Mon Sep 17 00:00:00 2001 From: JaredWeakStrike <96694163+JaredWeakStrike@users.noreply.github.com> Date: Thu, 16 Jan 2025 21:57:41 -0500 Subject: [PATCH 0046/1218] KH2: Fixes abilities overflowing into items and crashing the game (#4384) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/kh2/Client.py | 51 +++++--------------------------------------- 1 file changed, 5 insertions(+), 46 deletions(-) diff --git a/worlds/kh2/Client.py b/worlds/kh2/Client.py index e2d2338b7651..d8bdf6a9e368 100644 --- a/worlds/kh2/Client.py +++ b/worlds/kh2/Client.py @@ -345,33 +345,12 @@ def on_package(self, cmd: str, args: dict): self.lookup_id_to_item = {v: k for k, v in self.kh2_item_name_to_id.items()} self.ability_code_list = [self.kh2_item_name_to_id[item] for item in exclusion_item_table["Ability"]] - if "keyblade_abilities" in self.kh2slotdata.keys(): - sora_ability_dict = self.kh2slotdata["KeybladeAbilities"] + if "KeybladeAbilities" in self.kh2slotdata.keys(): # sora ability to slot + self.AbilityQuantityDict.update(self.kh2slotdata["KeybladeAbilities"]) # itemid:[slots that are available for that item] - for k, v in sora_ability_dict.items(): - if v >= 1: - if k not in self.sora_ability_to_slot.keys(): - self.sora_ability_to_slot[k] = [] - for _ in range(sora_ability_dict[k]): - self.sora_ability_to_slot[k].append(self.kh2_seed_save_cache["SoraInvo"][0]) - self.kh2_seed_save_cache["SoraInvo"][0] -= 2 - donald_ability_dict = self.kh2slotdata["StaffAbilities"] - for k, v in donald_ability_dict.items(): - if v >= 1: - if k not in self.donald_ability_to_slot.keys(): - self.donald_ability_to_slot[k] = [] - for _ in range(donald_ability_dict[k]): - self.donald_ability_to_slot[k].append(self.kh2_seed_save_cache["DonaldInvo"][0]) - self.kh2_seed_save_cache["DonaldInvo"][0] -= 2 - goofy_ability_dict = self.kh2slotdata["ShieldAbilities"] - for k, v in goofy_ability_dict.items(): - if v >= 1: - if k not in self.goofy_ability_to_slot.keys(): - self.goofy_ability_to_slot[k] = [] - for _ in range(goofy_ability_dict[k]): - self.goofy_ability_to_slot[k].append(self.kh2_seed_save_cache["GoofyInvo"][0]) - self.kh2_seed_save_cache["GoofyInvo"][0] -= 2 + self.AbilityQuantityDict.update(self.kh2slotdata["StaffAbilities"]) + self.AbilityQuantityDict.update(self.kh2slotdata["ShieldAbilities"]) all_weapon_location_id = [] for weapon_location in all_weapon_slot: @@ -525,27 +504,7 @@ async def give_item(self, item, location): if itemname not in self.kh2_seed_save_cache["AmountInvo"]["Ability"]: self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname] = [] # appending the slot that the ability should be in - # for non beta. remove after 4.3 - if "PoptrackerVersion" in self.kh2slotdata: - if self.kh2slotdata["PoptrackerVersionCheck"] < 4.3: - if (itemname in self.sora_ability_set - and len(self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname]) < self.item_name_to_data[itemname].quantity) \ - and self.kh2_seed_save_cache["SoraInvo"][1] > 0x254C: - ability_slot = self.kh2_seed_save_cache["SoraInvo"][1] - self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname].append(ability_slot) - self.kh2_seed_save_cache["SoraInvo"][1] -= 2 - elif itemname in self.donald_ability_set: - ability_slot = self.kh2_seed_save_cache["DonaldInvo"][1] - self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname].append(ability_slot) - self.kh2_seed_save_cache["DonaldInvo"][1] -= 2 - else: - ability_slot = self.kh2_seed_save_cache["GoofyInvo"][1] - self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname].append(ability_slot) - self.kh2_seed_save_cache["GoofyInvo"][1] -= 2 - if ability_slot in self.front_ability_slots: - self.front_ability_slots.remove(ability_slot) - - elif len(self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname]) < \ + if len(self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname]) < \ self.AbilityQuantityDict[itemname]: if itemname in self.sora_ability_set: ability_slot = self.kh2_seed_save_cache["SoraInvo"][0] From 3a5a4b89ee860d4b9c762119c27df4abb74c3ba7 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Thu, 16 Jan 2025 21:58:49 -0500 Subject: [PATCH 0047/1218] LADX: improved warps across unexplored tiles (#4111) --- worlds/ladx/LADXR/generator.py | 1 + worlds/ladx/LADXR/patches/core.py | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/worlds/ladx/LADXR/generator.py b/worlds/ladx/LADXR/generator.py index ff6cc06c39a9..413bf89c063c 100644 --- a/worlds/ladx/LADXR/generator.py +++ b/worlds/ladx/LADXR/generator.py @@ -103,6 +103,7 @@ def generateRom(args, world: "LinksAwakeningWorld"): assembler.const("wGoldenLeaves", 0xDB42) # New memory location where to store the golden leaf counter assembler.const("wCollectedTunics", 0xDB6D) # Memory location where to store which tunic options are available (and boots) assembler.const("wCustomMessage", 0xC0A0) + assembler.const("wOverworldRoomStatus", 0xD800) # We store the link info in unused color dungeon flags, so it gets preserved in the savegame. assembler.const("wLinkSyncSequenceNumber", 0xDDF6) diff --git a/worlds/ladx/LADXR/patches/core.py b/worlds/ladx/LADXR/patches/core.py index f4752c82e3da..d9fcd62e3060 100644 --- a/worlds/ladx/LADXR/patches/core.py +++ b/worlds/ladx/LADXR/patches/core.py @@ -716,9 +716,7 @@ def addWarpImprovements(rom, extra_warps): # Allow cursor to move over black squares # This allows warping to undiscovered areas - a fine cheat, but needs a check for wOverworldRoomStatus in the warp code - CHEAT_WARP_ANYWHERE = False - if CHEAT_WARP_ANYWHERE: - rom.patch(0x01, 0x1AE8, None, ASM("jp $5AF5")) + rom.patch(0x01, 0x1AE8, None, ASM("jp $5AF5")) # This disables the arrows around the selection bubble #rom.patch(0x01, 0x1B6F, None, ASM("ret"), fill_nop=True) @@ -797,8 +795,14 @@ def addWarpImprovements(rom, extra_warps): TeleportHandler: ld a, [$DBB4] ; Load the current selected tile - ; TODO: check if actually revealed so we can have free movement - ; Check cursor against different tiles to see if we are selecting a warp + ld hl, wOverworldRoomStatus + ld e, a ; $5D38: $5F + ld d, $00 ; $5D39: $16 $00 + add hl, de ; $5D3B: $19 + ld a, [hl] + and $80 + jr z, exit + ld a, [$DBB4] ; Load the current selected tile {warp_jump} jr exit From 4b8f990960f405e9a1d42b25f0ea4699f029b8f1 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Thu, 16 Jan 2025 21:59:19 -0500 Subject: [PATCH 0048/1218] LADX: Swap out invalid characters in item names (#4495) --- worlds/ladx/LADXR/locations/itemInfo.py | 9 +++++++++ worlds/ladx/__init__.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/worlds/ladx/LADXR/locations/itemInfo.py b/worlds/ladx/LADXR/locations/itemInfo.py index dcd4205f4cd9..cd0f35514972 100644 --- a/worlds/ladx/LADXR/locations/itemInfo.py +++ b/worlds/ladx/LADXR/locations/itemInfo.py @@ -2,6 +2,10 @@ from ..checkMetadata import checkMetadataTable from .constants import * +custom_name_replacements = { + '"':"'", + '_':' ', +} class ItemInfo: MULTIWORLD = True @@ -23,6 +27,11 @@ def location(self): def setLocation(self, location): self._location = location + def setCustomItemName(self, name): + for key, val in custom_name_replacements.items(): + name = name.replace(key, val) + self.custom_item_name = name + def getOptions(self): return self.OPTIONS diff --git a/worlds/ladx/__init__.py b/worlds/ladx/__init__.py index f20b7f8018aa..7b1a35666ae7 100644 --- a/worlds/ladx/__init__.py +++ b/worlds/ladx/__init__.py @@ -439,7 +439,7 @@ def generate_output(self, output_directory: str): # Otherwise, use a cute letter as the icon elif self.options.foreign_item_icons == 'guess_by_name': loc.ladxr_item.item = self.guess_icon_for_other_world(loc.item) - loc.ladxr_item.custom_item_name = loc.item.name + loc.ladxr_item.setCustomItemName(loc.item.name) else: if loc.item.advancement: From 8f307c226bde17a0e1a1caf4ad98dfccc7bb0c34 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Fri, 17 Jan 2025 02:59:38 +0000 Subject: [PATCH 0049/1218] Core: Fix the distribution of Options.Range.triangular() (#4283) --- Options.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Options.py b/Options.py index 135a1dcb5398..d9122d444c97 100644 --- a/Options.py +++ b/Options.py @@ -689,9 +689,9 @@ def from_text(cls, text: str) -> Range: @classmethod def weighted_range(cls, text) -> Range: if text == "random-low": - return cls(cls.triangular(cls.range_start, cls.range_end, cls.range_start)) + return cls(cls.triangular(cls.range_start, cls.range_end, 0.0)) elif text == "random-high": - return cls(cls.triangular(cls.range_start, cls.range_end, cls.range_end)) + return cls(cls.triangular(cls.range_start, cls.range_end, 1.0)) elif text == "random-middle": return cls(cls.triangular(cls.range_start, cls.range_end)) elif text.startswith("random-range-"): @@ -717,11 +717,11 @@ def custom_range(cls, text) -> Range: f"{random_range[0]}-{random_range[1]} is outside allowed range " f"{cls.range_start}-{cls.range_end} for option {cls.__name__}") if text.startswith("random-range-low"): - return cls(cls.triangular(random_range[0], random_range[1], random_range[0])) + return cls(cls.triangular(random_range[0], random_range[1], 0.0)) elif text.startswith("random-range-middle"): return cls(cls.triangular(random_range[0], random_range[1])) elif text.startswith("random-range-high"): - return cls(cls.triangular(random_range[0], random_range[1], random_range[1])) + return cls(cls.triangular(random_range[0], random_range[1], 1.0)) else: return cls(random.randint(random_range[0], random_range[1])) @@ -739,8 +739,16 @@ def __str__(self) -> str: return str(self.value) @staticmethod - def triangular(lower: int, end: int, tri: typing.Optional[int] = None) -> int: - return int(round(random.triangular(lower, end, tri), 0)) + def triangular(lower: int, end: int, tri: float = 0.5) -> int: + """ + Integer triangular distribution for `lower` inclusive to `end` inclusive. + + Expects `lower <= end` and `0.0 <= tri <= 1.0`. The result of other inputs is undefined. + """ + # Use the continuous range [lower, end + 1) to produce an integer result in [lower, end]. + # random.triangular is actually [a, b] and not [a, b), so there is a very small chance of getting exactly b even + # when a != b, so ensure the result is never more than `end`. + return min(end, math.floor(random.triangular(0.0, 1.0, tri) * (end - lower + 1) + lower)) class NamedRange(Range): From a9435dc6bb7b237f97f5cd4cd6f0f65e7d9c17d7 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Fri, 17 Jan 2025 03:00:29 +0000 Subject: [PATCH 0050/1218] KH2: Reduce unnecessary packets sent/requested by the client (#4035) --- worlds/kh2/Client.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/worlds/kh2/Client.py b/worlds/kh2/Client.py index d8bdf6a9e368..3ea47e40ebba 100644 --- a/worlds/kh2/Client.py +++ b/worlds/kh2/Client.py @@ -110,6 +110,7 @@ def __init__(self, server_address, password): 18: TWTNW_Checks, # 255: {}, # starting screen } + self.last_world_int = -1 # 0x2A09C00+0x40 is the sve anchor. +1 is the last saved room # self.sveroom = 0x2A09C00 + 0x41 # 0 not in battle 1 in yellow battle 2 red battle #short @@ -387,13 +388,15 @@ def on_package(self, cmd: str, args: dict): async def checkWorldLocations(self): try: currentworldint = self.kh2_read_byte(self.Now) - await self.send_msgs([{ - "cmd": "Set", "key": "Slot: " + str(self.slot) + " :CurrentWorld", - "default": 0, "want_reply": True, "operations": [{ - "operation": "replace", - "value": currentworldint - }] - }]) + if self.last_world_int != currentworldint: + self.last_world_int = currentworldint + await self.send_msgs([{ + "cmd": "Set", "key": "Slot: " + str(self.slot) + " :CurrentWorld", + "default": 0, "want_reply": False, "operations": [{ + "operation": "replace", + "value": currentworldint + }] + }]) if currentworldint in self.worldid_to_locations: curworldid = self.worldid_to_locations[currentworldint] for location, data in curworldid.items(): @@ -804,7 +807,7 @@ async def verifyItems(self): logger.info("line 840") -def finishedGame(ctx: KH2Context, message): +def finishedGame(ctx: KH2Context): if ctx.kh2slotdata['FinalXemnas'] == 1: if not ctx.final_xemnas and ctx.kh2_read_byte(ctx.Save + all_world_locations[LocationName.FinalXemnas].addrObtained) \ & 0x1 << all_world_locations[LocationName.FinalXemnas].bitIndex > 0: @@ -836,8 +839,9 @@ def finishedGame(ctx: KH2Context, message): elif ctx.kh2slotdata['Goal'] == 2: # for backwards compat if "hitlist" in ctx.kh2slotdata: + locations = ctx.sending for boss in ctx.kh2slotdata["hitlist"]: - if boss in message[0]["locations"]: + if boss in locations: ctx.hitlist_bounties += 1 if ctx.hitlist_bounties >= ctx.kh2slotdata["BountyRequired"] or ctx.kh2_seed_save_cache["AmountInvo"]["Amount"]["Bounty"] >= ctx.kh2slotdata["BountyRequired"]: if ctx.kh2_read_byte(ctx.Save + 0x36B3) < 1: @@ -878,11 +882,12 @@ async def kh2_watcher(ctx: KH2Context): await asyncio.create_task(ctx.verifyChests()) await asyncio.create_task(ctx.verifyItems()) await asyncio.create_task(ctx.verifyLevel()) - message = [{"cmd": 'LocationChecks', "locations": ctx.sending}] - if finishedGame(ctx, message) and not ctx.kh2_finished_game: + if finishedGame(ctx) and not ctx.kh2_finished_game: await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) ctx.kh2_finished_game = True - await ctx.send_msgs(message) + if ctx.sending: + message = [{"cmd": 'LocationChecks', "locations": ctx.sending}] + await ctx.send_msgs(message) elif not ctx.kh2connected and ctx.serverconneced: logger.info("Game Connection lost. waiting 15 seconds until trying to reconnect.") ctx.kh2 = None From 3d5c277c310684969d8cebfd67a495fafb94e024 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Fri, 17 Jan 2025 07:39:41 -0600 Subject: [PATCH 0051/1218] Core: don't log warnings for plando_items and missing lttp options (#3606) * Core: don't log a warning for the "options" that are valid in a game section but not on the options system * don't rebuild a set every loop --- Generate.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Generate.py b/Generate.py index 8a2e72d1ce6a..d6611b0f8a31 100644 --- a/Generate.py +++ b/Generate.py @@ -438,7 +438,7 @@ def roll_settings(weights: dict, plando_options: PlandoOptions = PlandoOptions.b if "linked_options" in weights: weights = roll_linked_options(weights) - valid_keys = set() + valid_keys = {"triggers"} if "triggers" in weights: weights = roll_triggers(weights, weights["triggers"], valid_keys) @@ -497,16 +497,23 @@ def roll_settings(weights: dict, plando_options: PlandoOptions = PlandoOptions.b for option_key, option in world_type.options_dataclass.type_hints.items(): handle_option(ret, game_weights, option_key, option, plando_options) valid_keys.add(option_key) - for option_key in game_weights: - if option_key in {"triggers", *valid_keys}: - continue - logging.warning(f"{option_key} is not a valid option name for {ret.game} and is not present in triggers " - f"for player {ret.name}.") + + # TODO remove plando_items after moving it to the options system + valid_keys.add("plando_items") if PlandoOptions.items in plando_options: ret.plando_items = copy.deepcopy(game_weights.get("plando_items", [])) if ret.game == "A Link to the Past": + # TODO there are still more LTTP options not on the options system + valid_keys |= {"sprite_pool", "sprite", "random_sprite_on_event"} roll_alttp_settings(ret, game_weights) + # log a warning for options within a game section that aren't determined as valid + for option_key in game_weights: + if option_key in valid_keys: + continue + logging.warning(f"{option_key} is not a valid option name for {ret.game} and is not present in triggers " + f"for player {ret.name}.") + return ret From d218dec82699876cea22c41bdaa63b9bae849922 Mon Sep 17 00:00:00 2001 From: digiholic Date: Fri, 17 Jan 2025 06:41:12 -0700 Subject: [PATCH 0052/1218] MMBN3: Logic and Bug Fixes, New Checks (#3646) * PMDs now check to make sure you have enough unlockers for all of them before any are in logic, to avoid softlocks * Adds Humor and BlckMnd to the pool and sets logic for Villain and Comedian. Patch not yet updated to remove starting inventory * Adds Serenade as a check * Fixes hide and seek completion to use proper Yoka Zoo map. Updates bsdiff patch to 1.2 * Adds option for excluding Secret Area, and item/location groups for further customization * Update worlds/mmbn3/Locations.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mmbn3/Regions.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mmbn3/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mmbn3/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mmbn3/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Replaces can_reach generic with can_reach_region or can_reach_location, where applciable * Unlocker is now a progression item, Excluded Locations is now a Set * Missed a merge marker * Excluded locations is no longer a set since you can't append to a set with += * Excluded locations is now a set again since you apparent can append to a set with |= * Replaces more lists with sets. Fixes wording in option descriptions * Update worlds/mmbn3/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/mmbn3/Items.py | 29 ++++- worlds/mmbn3/Locations.py | 37 +++--- worlds/mmbn3/Names/ItemName.py | 2 + worlds/mmbn3/Names/LocationName.py | 2 + worlds/mmbn3/Options.py | 12 +- worlds/mmbn3/Regions.py | 4 +- worlds/mmbn3/__init__.py | 178 +++++++++++++++----------- worlds/mmbn3/data/bn3-ap-patch.bsdiff | Bin 59914 -> 61276 bytes 8 files changed, 165 insertions(+), 99 deletions(-) diff --git a/worlds/mmbn3/Items.py b/worlds/mmbn3/Items.py index 30ec311ecbe2..7e3458c913f4 100644 --- a/worlds/mmbn3/Items.py +++ b/worlds/mmbn3/Items.py @@ -85,7 +85,7 @@ class MMBN3Item(Item): ] subChipList: typing.List[ItemData] = [ - ItemData(0xB31018, ItemName.Unlocker, ItemClassification.useful, ItemType.SubChip, 117), + ItemData(0xB31018, ItemName.Unlocker, ItemClassification.progression, ItemType.SubChip, 117), ItemData(0xB31019, ItemName.Untrap, ItemClassification.filler, ItemType.SubChip, 115), ItemData(0xB3101A, ItemName.LockEnmy, ItemClassification.filler, ItemType.SubChip, 116), ItemData(0xB3101B, ItemName.MiniEnrg, ItemClassification.filler, ItemType.SubChip, 112), @@ -290,7 +290,9 @@ class MMBN3Item(Item): ItemData(0xB31099, ItemName.WpnLV_plus_Yellow, ItemClassification.filler, ItemType.Program, 35, ProgramColor.Yellow), ItemData(0xB3109A, ItemName.Press, ItemClassification.progression, ItemType.Program, 20, ProgramColor.White), - ItemData(0xB310B7, ItemName.UnderSht, ItemClassification.useful, ItemType.Program, 30, ProgramColor.White) + ItemData(0xB310B7, ItemName.UnderSht, ItemClassification.useful, ItemType.Program, 30, ProgramColor.White), + ItemData(0xB310E0, ItemName.Humor, ItemClassification.progression, ItemType.Program, 45, ProgramColor.Pink), + ItemData(0xB310E1, ItemName.BlckMnd, ItemClassification.progression, ItemType.Program, 46, ProgramColor.White) ] zennyList: typing.List[ItemData] = [ @@ -338,8 +340,29 @@ class MMBN3Item(Item): ItemName.zenny_800z: 2, ItemName.zenny_1000z: 2, ItemName.zenny_1200z: 2, - ItemName.bugfrag_01: 5, + ItemName.bugfrag_01: 10, + ItemName.bugfrag_10: 5 } + +item_groups: typing.Dict[str, typing.Set[str]] = { + "Key Items": {loc.itemName for loc in keyItemList}, + "Subchips": {loc.itemName for loc in subChipList}, + "Programs": {loc.itemName for loc in programList}, + "BattleChips": {loc.itemName for loc in chipList}, + "Zenny": {loc.itemName for loc in zennyList}, + "BugFrags": {loc.itemName for loc in bugFragList}, + "Navi Chips": { + ItemName.Roll_R, ItemName.RollV2_R, ItemName.RollV3_R, ItemName.GutsMan_G, ItemName.GutsManV2_G, + ItemName.GutsManV3_G, ItemName.ProtoMan_B, ItemName.ProtoManV2_B, ItemName.ProtoManV3_B, ItemName.FlashMan_F, + ItemName.FlashManV2_F, ItemName.FlashManV3_F, ItemName.BeastMan_B, ItemName.BeastManV2_B, ItemName.BeastManV3_B, + ItemName.BubblMan_B, ItemName.BubblManV2_B, ItemName.BubblManV3_B, ItemName.DesertMan_D, ItemName.DesertManV2_D, + ItemName.DesertManV3_D, ItemName.PlantMan_P, ItemName.PlantManV2_P, ItemName.PlantManV3_P, ItemName.FlamMan_F, + ItemName.FlamManV2_F, ItemName.FlamManV3_F, ItemName.DrillMan_D, ItemName.DrillManV2_D, ItemName.DrillManV3_D, + ItemName.MetalMan_M, ItemName.MetalManV2_M, ItemName.MetalManV3_M, ItemName.KingMan_K, ItemName.KingManV2_K, + ItemName.KingManV3_K, ItemName.BowlMan_B, ItemName.BowlManV2_B, ItemName.BowlManV3_B + } +} + all_items: typing.List[ItemData] = keyItemList + subChipList + chipList + programList + zennyList + bugFragList item_table: typing.Dict[str, ItemData] = {item.itemName: item for item in all_items} items_by_id: typing.Dict[int, ItemData] = {item.code: item for item in all_items} diff --git a/worlds/mmbn3/Locations.py b/worlds/mmbn3/Locations.py index 0e2a1c51d11b..bc16c99a5823 100644 --- a/worlds/mmbn3/Locations.py +++ b/worlds/mmbn3/Locations.py @@ -221,7 +221,8 @@ class MMBN3Location(Location): LocationData(LocationName.Hades_Boat_Dock, 0xb310ab, 0x200024c, 0x10, 0x7519B0, 223, [3]), LocationData(LocationName.WWW_Control_Room_1_Screen, 0xb310ac, 0x200024d, 0x40, 0x7596C4, 222, [3, 4]), LocationData(LocationName.WWW_Wilys_Desk, 0xb310ad, 0x200024d, 0x2, 0x759384, 229, [3]), - LocationData(LocationName.Undernet_4_Pillar_Prog, 0xb310ae, 0x2000161, 0x1, 0x7746C8, 191, [0, 1]) + LocationData(LocationName.Undernet_4_Pillar_Prog, 0xb310ae, 0x2000161, 0x1, 0x7746C8, 191, [0, 1]), + LocationData(LocationName.Serenade, 0xb3110f, 0x2000178, 0x40, 0x7B3C74, 1, [0]) ] jobs = [ @@ -240,7 +241,8 @@ class MMBN3Location(Location): # LocationData(LocationName.Gathering_Data, 0xb310bb, 0x2000300, 0x10, 0x739580, 193, [0]), LocationData(LocationName.Somebody_please_help, 0xb310bc, 0x2000301, 0x4, 0x73A14C, 193, [0]), LocationData(LocationName.Looking_for_condor, 0xb310bd, 0x2000301, 0x2, 0x749444, 203, [0]), - LocationData(LocationName.Help_with_rehab, 0xb310be, 0x2000301, 0x1, 0x762CF0, 192, [3]), + LocationData(LocationName.Help_with_rehab, 0xb310be, 0x2000301, 0x1, 0x762CF0, 192, [0]), + LocationData(LocationName.Help_with_rehab_bonus, 0xb3110e, 0x2000301, 0x1, 0x762CF0, 192, [3]), LocationData(LocationName.Old_Master, 0xb310bf, 0x2000302, 0x80, 0x760E80, 193, [0]), LocationData(LocationName.Catching_gang_members, 0xb310c0, 0x2000302, 0x40, 0x76EAE4, 193, [0]), LocationData(LocationName.Please_adopt_a_virus, 0xb310c1, 0x2000302, 0x20, 0x76A4F4, 193, [0]), @@ -250,7 +252,7 @@ class MMBN3Location(Location): LocationData(LocationName.Hide_and_seek_Second_Child, 0xb310c5, 0x2000188, 0x2, 0x75ADA8, 191, [0]), LocationData(LocationName.Hide_and_seek_Third_Child, 0xb310c6, 0x2000188, 0x1, 0x75B5EC, 191, [0]), LocationData(LocationName.Hide_and_seek_Fourth_Child, 0xb310c7, 0x2000189, 0x80, 0x75BEB0, 191, [0]), - LocationData(LocationName.Hide_and_seek_Completion, 0xb310c8, 0x2000302, 0x8, 0x7406A0, 193, [0]), + LocationData(LocationName.Hide_and_seek_Completion, 0xb310c8, 0x2000302, 0x8, 0x742D40, 193, [0]), LocationData(LocationName.Finding_the_blue_Navi, 0xb310c9, 0x2000302, 0x4, 0x773700, 192, [0]), LocationData(LocationName.Give_your_support, 0xb310ca, 0x2000302, 0x2, 0x752D80, 192, [0]), LocationData(LocationName.Stamp_collecting, 0xb310cb, 0x2000302, 0x1, 0x756074, 193, [0]), @@ -329,10 +331,7 @@ class MMBN3Location(Location): LocationData(LocationName.Chocolate_Shop_32, 0xb3110d, 0x20001c3, 0x01, 0x73F8FC, 181, [0]), ] -always_excluded_locations = [ - LocationName.Undernet_7_PMD, - LocationName.Undernet_7_Northeast_BMD, - LocationName.Undernet_7_Northwest_BMD, +secret_locations = { LocationName.Secret_1_Northwest_BMD, LocationName.Secret_1_Northeast_BMD, LocationName.Secret_1_South_BMD, @@ -341,19 +340,23 @@ class MMBN3Location(Location): LocationName.Secret_2_Island_BMD, LocationName.Secret_3_Island_BMD, LocationName.Secret_3_BugFrag_BMD, - LocationName.Secret_3_South_BMD -] + LocationName.Secret_3_South_BMD, + LocationName.Serenade +} +location_groups: typing.Dict[str, typing.Set[str]] = { + "BMDs": {loc.name for loc in bmds}, + "PMDs": {loc.name for loc in pmds}, + "Jobs": {loc.name for loc in jobs}, + "Number Trader": {loc.name for loc in number_traders}, + "Bugfrag Trader": {loc.name for loc in chocolate_shop}, + "Secret Area": {LocationName.Secret_1_Northwest_BMD, LocationName.Secret_1_Northeast_BMD, + LocationName.Secret_1_South_BMD, LocationName.Secret_2_Upper_BMD, LocationName.Secret_2_Lower_BMD, + LocationName.Secret_2_Island_BMD, LocationName.Secret_3_Island_BMD, + LocationName.Secret_3_BugFrag_BMD, LocationName.Secret_3_South_BMD, LocationName.Serenade}, +} all_locations: typing.List[LocationData] = bmds + pmds + overworlds + jobs + number_traders + chocolate_shop scoutable_locations: typing.List[LocationData] = [loc for loc in all_locations if loc.hint_flag is not None] location_table: typing.Dict[str, int] = {locData.name: locData.id for locData in all_locations} location_data_table: typing.Dict[str, LocationData] = {locData.name: locData for locData in all_locations} - - -""" -def setup_locations(world, player: int): - # If we later include options to change what gets added to the random pool, - # this is where they would be changed - return {locData.name: locData.id for locData in all_locations} -""" diff --git a/worlds/mmbn3/Names/ItemName.py b/worlds/mmbn3/Names/ItemName.py index 677eff22b353..af645db90c21 100644 --- a/worlds/mmbn3/Names/ItemName.py +++ b/worlds/mmbn3/Names/ItemName.py @@ -173,6 +173,8 @@ class ItemName(): WpnLV_plus_White = "WpnLV+1 (White)" Press = "Press" UnderSht = "UnderSht" + Humor = "Humor" + BlckMnd = "BlckMnd" ## Currency zenny_200z = "200z" diff --git a/worlds/mmbn3/Names/LocationName.py b/worlds/mmbn3/Names/LocationName.py index 36060b12ec39..61c64faa9dab 100644 --- a/worlds/mmbn3/Names/LocationName.py +++ b/worlds/mmbn3/Names/LocationName.py @@ -210,6 +210,7 @@ class LocationName(): WWW_Control_Room_1_Screen = "WWW Control Room 1 Screen" WWW_Wilys_Desk = "WWW Wily's Desk" Undernet_4_Pillar_Prog = "Undernet 4 Pillar Prog" + Serenade = "Serenade" ## Numberman Codes Numberman_Code_01 = "Numberman Code 01" @@ -261,6 +262,7 @@ class LocationName(): Somebody_please_help = "Job: Somebody, please help!" Looking_for_condor = "Job: Looking for condor" Help_with_rehab = "Job: Help with rehab" + Help_with_rehab_bonus = "Job: Help with rehab bonus" Old_Master = "Job: Old Master" Catching_gang_members = "Job: Catching gang members" Please_adopt_a_virus = "Job: Please adopt a virus!" diff --git a/worlds/mmbn3/Options.py b/worlds/mmbn3/Options.py index 4ed64e3d9dbf..a127d25dda3e 100644 --- a/worlds/mmbn3/Options.py +++ b/worlds/mmbn3/Options.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from Options import Choice, Range, DefaultOnToggle, PerGameCommonOptions +from Options import Choice, Range, DefaultOnToggle, Toggle, PerGameCommonOptions class ExtraRanks(Range): @@ -17,10 +17,17 @@ class ExtraRanks(Range): class IncludeJobs(DefaultOnToggle): """ - Whether Jobs can be included in logic. + Whether Jobs can contain progression or useful items. """ display_name = "Include Jobs" + +class IncludeSecretArea(Toggle): + """ + Whether the Secret Area (including Serenade) can contain progression or useful items. + """ + display_name = "Include Secret Area" + # Possible logic options: # - Include Number Trader # - Include Secret Area @@ -46,5 +53,6 @@ class TradeQuestHinting(Choice): class MMBN3Options(PerGameCommonOptions): extra_ranks: ExtraRanks include_jobs: IncludeJobs + include_secret: IncludeSecretArea trade_quest_hinting: TradeQuestHinting \ No newline at end of file diff --git a/worlds/mmbn3/Regions.py b/worlds/mmbn3/Regions.py index 1dc58600cbc4..286e95a1c263 100644 --- a/worlds/mmbn3/Regions.py +++ b/worlds/mmbn3/Regions.py @@ -135,6 +135,7 @@ def __init__(self, name, connections, locations): LocationName.Somebody_please_help, LocationName.Looking_for_condor, LocationName.Help_with_rehab, + LocationName.Help_with_rehab_bonus, LocationName.Old_Master, LocationName.Catching_gang_members, LocationName.Please_adopt_a_virus, @@ -349,6 +350,7 @@ def __init__(self, name, connections, locations): LocationName.Secret_2_Upper_BMD, LocationName.Secret_3_Island_BMD, LocationName.Secret_3_South_BMD, - LocationName.Secret_3_BugFrag_BMD + LocationName.Secret_3_BugFrag_BMD, + LocationName.Serenade ]) ] diff --git a/worlds/mmbn3/__init__.py b/worlds/mmbn3/__init__.py index 6d28b101c377..08165a7df6e2 100644 --- a/worlds/mmbn3/__init__.py +++ b/worlds/mmbn3/__init__.py @@ -9,14 +9,14 @@ from worlds.AutoWorld import WebWorld, World from .Rom import MMBN3DeltaPatch, LocalRom, get_base_rom_path -from .Items import MMBN3Item, ItemData, item_table, all_items, item_frequencies, items_by_id, ItemType +from .Items import MMBN3Item, ItemData, item_table, all_items, item_frequencies, items_by_id, ItemType, item_groups from .Locations import Location, MMBN3Location, all_locations, location_table, location_data_table, \ - always_excluded_locations, jobs + secret_locations, jobs, location_groups from .Options import MMBN3Options from .Regions import regions, RegionName from .Names.ItemName import ItemName from .Names.LocationName import LocationName -from worlds.generic.Rules import add_item_rule +from worlds.generic.Rules import add_item_rule, add_rule class MMBN3Settings(settings.Group): @@ -57,12 +57,16 @@ class MMBN3World(World): settings: typing.ClassVar[MMBN3Settings] topology_present = False + item_name_to_id = {name: data.code for name, data in item_table.items()} location_name_to_id = {loc_data.name: loc_data.id for loc_data in all_locations} - excluded_locations: typing.List[str] + excluded_locations: typing.Set[str] item_frequencies: typing.Dict[str, int] + location_name_groups = location_groups + item_name_groups = item_groups + web = MMBN3Web() def generate_early(self) -> None: @@ -74,10 +78,11 @@ def generate_early(self) -> None: if self.options.extra_ranks > 0: self.item_frequencies[ItemName.Progressive_Undernet_Rank] = 8 + self.options.extra_ranks + self.excluded_locations = set() + if not self.options.include_secret: + self.excluded_locations |= secret_locations if not self.options.include_jobs: - self.excluded_locations = always_excluded_locations + [job.name for job in jobs] - else: - self.excluded_locations = always_excluded_locations + self.excluded_locations |= {job.name for job in jobs} def create_regions(self) -> None: """ @@ -140,19 +145,19 @@ def register_explore_score_indirect_conditions(entrance): if connection == RegionName.SciLab_Cyberworld: entrance.access_rule = lambda state: \ state.has(ItemName.CSciPas, self.player) or \ - state.can_reach(RegionName.SciLab_Overworld, "Region", self.player) + state.can_reach_region(RegionName.SciLab_Overworld, self.player) self.multiworld.register_indirect_condition(self.get_region(RegionName.SciLab_Overworld), entrance) if connection == RegionName.Yoka_Cyberworld: entrance.access_rule = lambda state: \ state.has(ItemName.CYokaPas, self.player) or \ ( - state.can_reach(RegionName.SciLab_Overworld, "Region", self.player) and + state.can_reach_region(RegionName.SciLab_Overworld, self.player) and state.has(ItemName.Press, self.player) ) self.multiworld.register_indirect_condition(self.get_region(RegionName.SciLab_Overworld), entrance) if connection == RegionName.Beach_Cyberworld: entrance.access_rule = lambda state: state.has(ItemName.CBeacPas, self.player) and\ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) self.multiworld.register_indirect_condition(self.get_region(RegionName.Yoka_Overworld), entrance) if connection == RegionName.Undernet: entrance.access_rule = lambda state: self.explore_score(state) > 8 and\ @@ -198,122 +203,138 @@ def set_rules(self) -> None: # Set WWW ID requirements def has_www_id(state): return state.has(ItemName.WWW_ID, self.player) - self.multiworld.get_location(LocationName.ACDC_1_PMD, self.player).access_rule = has_www_id - self.multiworld.get_location(LocationName.SciLab_1_WWW_BMD, self.player).access_rule = has_www_id - self.multiworld.get_location(LocationName.Yoka_1_WWW_BMD, self.player).access_rule = has_www_id - self.multiworld.get_location(LocationName.Undernet_1_WWW_BMD, self.player).access_rule = has_www_id + add_rule(self.multiworld.get_location(LocationName.ACDC_1_PMD, self.player), has_www_id) + add_rule(self.multiworld.get_location(LocationName.SciLab_1_WWW_BMD, self.player), has_www_id) + add_rule(self.multiworld.get_location(LocationName.Yoka_1_WWW_BMD, self.player), has_www_id) + add_rule(self.multiworld.get_location(LocationName.Undernet_1_WWW_BMD, self.player), has_www_id) # Set Press Program requirements def has_press(state): return state.has(ItemName.Press, self.player) - self.multiworld.get_location(LocationName.Yoka_1_PMD, self.player).access_rule = has_press - self.multiworld.get_location(LocationName.Yoka_2_Upper_BMD, self.player).access_rule = has_press - self.multiworld.get_location(LocationName.Beach_2_East_BMD, self.player).access_rule = has_press - self.multiworld.get_location(LocationName.Hades_South_BMD, self.player).access_rule = has_press - self.multiworld.get_location(LocationName.Secret_3_BugFrag_BMD, self.player).access_rule = has_press - self.multiworld.get_location(LocationName.Secret_3_Island_BMD, self.player).access_rule = has_press + add_rule(self.multiworld.get_location(LocationName.Yoka_1_PMD, self.player), has_press) + add_rule(self.multiworld.get_location(LocationName.Yoka_2_Upper_BMD, self.player), has_press) + add_rule(self.multiworld.get_location(LocationName.Beach_2_East_BMD, self.player), has_press) + add_rule(self.multiworld.get_location(LocationName.Hades_South_BMD, self.player), has_press) + add_rule(self.multiworld.get_location(LocationName.Secret_3_BugFrag_BMD, self.player), has_press) + add_rule(self.multiworld.get_location(LocationName.Secret_3_Island_BMD, self.player), has_press) + + # Set Purple Mystery Data Unlocker access + def can_unlock(state): return state.can_reach_region(RegionName.SciLab_Overworld, self.player) or \ + state.can_reach_region(RegionName.SciLab_Cyberworld, self.player) or \ + state.can_reach_region(RegionName.Yoka_Cyberworld, self.player) or \ + state.has(ItemName.Unlocker, self.player, 8) # There are 8 PMDs that aren't in one of the above areas + add_rule(self.multiworld.get_location(LocationName.ACDC_1_PMD, self.player), can_unlock) + add_rule(self.multiworld.get_location(LocationName.Yoka_1_PMD, self.player), can_unlock) + add_rule(self.multiworld.get_location(LocationName.Beach_1_PMD, self.player), can_unlock) + add_rule(self.multiworld.get_location(LocationName.Undernet_7_PMD, self.player), can_unlock) + add_rule(self.multiworld.get_location(LocationName.Mayls_HP_PMD, self.player), can_unlock) + add_rule(self.multiworld.get_location(LocationName.SciLab_Dads_Computer_PMD, self.player), can_unlock) + add_rule(self.multiworld.get_location(LocationName.Zoo_Panda_PMD, self.player), can_unlock) + add_rule(self.multiworld.get_location(LocationName.Beach_DNN_Security_Panel_PMD, self.player), can_unlock) + add_rule(self.multiworld.get_location(LocationName.Beach_DNN_Main_Console_PMD, self.player), can_unlock) + add_rule(self.multiworld.get_location(LocationName.Tamakos_HP_PMD, self.player), can_unlock) # Set Job additional area access self.multiworld.get_location(LocationName.Please_deliver_this, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.ACDC_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.ACDC_Cyberworld, "Region", self.player) + state.can_reach_region(RegionName.ACDC_Overworld, self.player) and \ + state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) self.multiworld.get_location(LocationName.My_Navi_is_sick, self.player).access_rule =\ lambda state: \ state.has(ItemName.Recov30_star, self.player) self.multiworld.get_location(LocationName.Help_me_with_my_son, self.player).access_rule =\ lambda state:\ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.ACDC_Cyberworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) and \ + state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) self.multiworld.get_location(LocationName.Transmission_error, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) self.multiworld.get_location(LocationName.Chip_Prices, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.ACDC_Cyberworld, "Region", self.player) and \ - state.can_reach(RegionName.SciLab_Cyberworld, "Region", self.player) + state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) and \ + state.can_reach_region(RegionName.SciLab_Cyberworld, self.player) self.multiworld.get_location(LocationName.Im_broke, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.Yoka_Cyberworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) and \ + state.can_reach_region(RegionName.Yoka_Cyberworld, self.player) self.multiworld.get_location(LocationName.Rare_chips_for_cheap, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.ACDC_Overworld, "Region", self.player) + state.can_reach_region(RegionName.ACDC_Overworld, self.player) self.multiworld.get_location(LocationName.Be_my_boyfriend, self.player).access_rule =\ lambda state: \ - state.can_reach(RegionName.Beach_Cyberworld, "Region", self.player) + state.can_reach_region(RegionName.Beach_Cyberworld, self.player) self.multiworld.get_location(LocationName.Will_you_deliver, self.player).access_rule=\ lambda state: \ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.Beach_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.ACDC_Cyberworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) and \ + state.can_reach_region(RegionName.Beach_Overworld, self.player) and \ + state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) self.multiworld.get_location(LocationName.Somebody_please_help, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.ACDC_Overworld, "Region", self.player) + state.can_reach_region(RegionName.ACDC_Overworld, self.player) self.multiworld.get_location(LocationName.Looking_for_condor, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.Beach_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.ACDC_Overworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) and \ + state.can_reach_region(RegionName.Beach_Overworld, self.player) and \ + state.can_reach_region(RegionName.ACDC_Overworld, self.player) self.multiworld.get_location(LocationName.Help_with_rehab, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Beach_Overworld, "Region", self.player) + state.can_reach_region(RegionName.Beach_Overworld, self.player) self.multiworld.get_location(LocationName.Old_Master, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.ACDC_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.Beach_Overworld, "Region", self.player) + state.can_reach_region(RegionName.ACDC_Overworld, self.player) and \ + state.can_reach_region(RegionName.Beach_Overworld, self.player) self.multiworld.get_location(LocationName.Catching_gang_members, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Yoka_Cyberworld, "Region", self.player) and \ + state.can_reach_region(RegionName.Yoka_Cyberworld, self.player) and \ state.has(ItemName.Press, self.player) self.multiworld.get_location(LocationName.Please_adopt_a_virus, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.SciLab_Cyberworld, "Region", self.player) + state.can_reach_region(RegionName.SciLab_Cyberworld, self.player) self.multiworld.get_location(LocationName.Legendary_Tomes, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Beach_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.Undernet, "Region", self.player) and \ - state.can_reach(RegionName.Deep_Undernet, "Region", self.player) and \ + state.can_reach_region(RegionName.Beach_Overworld, self.player) and \ + state.can_reach_region(RegionName.Undernet, self.player) and \ + state.can_reach_region(RegionName.Deep_Undernet, self.player) and \ state.has_all({ItemName.Press, ItemName.Magnum1_A}, self.player) self.multiworld.get_location(LocationName.Legendary_Tomes_Treasure, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.ACDC_Overworld, "Region", self.player) and \ - state.can_reach(LocationName.Legendary_Tomes, "Location", self.player) + state.can_reach_region(RegionName.ACDC_Overworld, self.player) and \ + state.can_reach_location(LocationName.Legendary_Tomes, self.player) self.multiworld.get_location(LocationName.Hide_and_seek_First_Child, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) self.multiworld.get_location(LocationName.Hide_and_seek_Second_Child, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) self.multiworld.get_location(LocationName.Hide_and_seek_Third_Child, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) self.multiworld.get_location(LocationName.Hide_and_seek_Fourth_Child, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) self.multiworld.get_location(LocationName.Hide_and_seek_Completion, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) + state.can_reach_region(RegionName.Yoka_Overworld, self.player) self.multiworld.get_location(LocationName.Finding_the_blue_Navi, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Undernet, "Region", self.player) + state.can_reach_region(RegionName.Undernet, self.player) self.multiworld.get_location(LocationName.Give_your_support, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Beach_Overworld, "Region", self.player) + state.can_reach_region(RegionName.Beach_Overworld, self.player) self.multiworld.get_location(LocationName.Stamp_collecting, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.Beach_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.ACDC_Cyberworld, "Region", self.player) and \ - state.can_reach(RegionName.SciLab_Cyberworld, "Region", self.player) and \ - state.can_reach(RegionName.Yoka_Cyberworld, "Region", self.player) and \ - state.can_reach(RegionName.Beach_Cyberworld, "Region", self.player) + state.can_reach_region(RegionName.Beach_Overworld, self.player) and \ + state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) and \ + state.can_reach_region(RegionName.SciLab_Cyberworld, self.player) and \ + state.can_reach_region(RegionName.Yoka_Cyberworld, self.player) and \ + state.can_reach_region(RegionName.Beach_Cyberworld, self.player) self.multiworld.get_location(LocationName.Help_with_a_will, self.player).access_rule = \ lambda state: \ - state.can_reach(RegionName.ACDC_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.ACDC_Cyberworld, "Region", self.player) and \ - state.can_reach(RegionName.Yoka_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.Yoka_Cyberworld, "Region", self.player) and \ - state.can_reach(RegionName.Beach_Overworld, "Region", self.player) and \ - state.can_reach(RegionName.Undernet, "Region", self.player) + state.can_reach_region(RegionName.ACDC_Overworld, self.player) and \ + state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) and \ + state.can_reach_region(RegionName.Yoka_Overworld, self.player) and \ + state.can_reach_region(RegionName.Yoka_Cyberworld, self.player) and \ + state.can_reach_region(RegionName.Beach_Overworld, self.player) and \ + state.can_reach_region(RegionName.Undernet, self.player) # Set Trade quests self.multiworld.get_location(LocationName.ACDC_SonicWav_W_Trade, self.player).access_rule =\ @@ -390,6 +411,11 @@ def has_press(state): return state.has(ItemName.Press, self.player) self.multiworld.get_location(LocationName.Numberman_Code_31, self.player).access_rule =\ lambda state: self.explore_score(state) > 10 + #miscellaneous locations with extra requirements + add_rule(self.multiworld.get_location(LocationName.Comedian, self.player), + lambda state: state.has(ItemName.Humor, self.player)) + add_rule(self.multiworld.get_location(LocationName.Villain, self.player), + lambda state: state.has(ItemName.BlckMnd, self.player)) def not_undernet(item): return item.code != item_table[ItemName.Progressive_Undernet_Rank].code or item.player != self.player self.multiworld.get_location(LocationName.WWW_1_Central_BMD, self.player).item_rule = not_undernet self.multiworld.get_location(LocationName.WWW_1_East_BMD, self.player).item_rule = not_undernet @@ -500,24 +526,24 @@ def explore_score(self, state): Determine roughly how much of the game you can explore to make certain checks not restrict much movement """ score = 0 - if state.can_reach(RegionName.WWW_Island, "Region", self.player): + if state.can_reach_region(RegionName.WWW_Island, self.player): return 999 - if state.can_reach(RegionName.SciLab_Overworld, "Region", self.player): + if state.can_reach_region(RegionName.SciLab_Overworld, self.player): score += 3 - if state.can_reach(RegionName.SciLab_Cyberworld, "Region", self.player): + if state.can_reach_region(RegionName.SciLab_Cyberworld, self.player): score += 1 - if state.can_reach(RegionName.Yoka_Overworld, "Region", self.player): + if state.can_reach_region(RegionName.Yoka_Overworld, self.player): score += 2 - if state.can_reach(RegionName.Yoka_Cyberworld, "Region", self.player): + if state.can_reach_region(RegionName.Yoka_Cyberworld, self.player): score += 1 - if state.can_reach(RegionName.Beach_Overworld, "Region", self.player): + if state.can_reach_region(RegionName.Beach_Overworld, self.player): score += 3 - if state.can_reach(RegionName.Beach_Cyberworld, "Region", self.player): + if state.can_reach_region(RegionName.Beach_Cyberworld, self.player): score += 1 - if state.can_reach(RegionName.Undernet, "Region", self.player): + if state.can_reach_region(RegionName.Undernet, self.player): score += 2 - if state.can_reach(RegionName.Deep_Undernet, "Region", self.player): + if state.can_reach_region(RegionName.Deep_Undernet, self.player): score += 1 - if state.can_reach(RegionName.Secret_Area, "Region", self.player): + if state.can_reach_region(RegionName.Secret_Area, self.player): score += 1 return score diff --git a/worlds/mmbn3/data/bn3-ap-patch.bsdiff b/worlds/mmbn3/data/bn3-ap-patch.bsdiff index d3548b4c949a459da53701090d5f6fa5f565b7f8..d55fecad80641b372bc7752600f335d6961f9185 100644 GIT binary patch literal 61276 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�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 literal 59914 zcmaI7V{j$R6YzWDb(0+uYc8?(=`|t$M%R{?aquJyX+F zT|G5bzY$Rtla`QRXZ{NX_&>5l^8ae_e?k9eAfjW%!y>Frsj7_?&GHKX%MkeepL~9Q zKmSi(e|HC7Utdc;_Wp0S@wx36X!xxJiJOdtZ#9)=G)D{q4N&HngA&cmkZB47Dia^s z0X`9n5Q~Tq!iDU3_IO!{0H2__qCx;WLOj6A3PMpi5nx4_ov%b17q+-=<6|$iF5*L2 zd0O%KQwc93Kgt-99jpZrC!1L!iyhDEksVr2R3d0>)(Rn1XqFuhkA2MgzpW6#iqKKS z%*spGf2oR!E?NQXh2}uPr+8pzRX01!JF@D+nk}gU_ z1WN<}{yQcB03Gx{FCK)%|IuJ)|E*w$&IX4N`kxtK_1~)hVuYgr09*hb01PA%oQOaf z^k0nGfA(}@_ZS`dKInMrJh#lWZtEu+VgJr48dp^Z1H^=Fi+SY5FTt z&lR6n{Syg-O62$n?r88NNn!^ztRe`)ek8VzNP!dUFG8h`U zP*ho5R21e@FT>IbXC?KJWJAgyZ-e1fvn`2F8uu#9E{>nbdUu4l9>Y~aB#EY#v9a%5 z(R8ps(KuFzm;Al$YB<%fn_mL{NN*~9pFIRRV`UVi` zb?3xw7E8m4Q%{45B~AcAm=#k0)u|F1VDUzM_bf}@eRRKLU{=X_>gErnOo)yM4gNk( zfb;jU9xg??k6fcwq>0!cNuE<;x<+2Zg?MOfmv;)};84abA!mVqWHMB{)f6&WFIi2U zdEpRVRj=;Em8gxE7e^q3k#A+t6`ew zkW52?mo!*0@#3kvRKJqGGy=M;k1<5N23QHSu|79>oX#|_dtbx@i0cvtL~$@;E9Vf! zS!!mKf(RKP7_lDbudQ3{zg#!WiQOhRw_#PZ^=r?azoqZ!v>B)Kamb-iVTsXT0pMX6 zBw^t~r6@uaVALVcpUw}+p)Jb%*|wxJsnE?a`kjh5GGDG~26Y$!Q-NSm1r zmm-&66(G;SQfw0d0zC>S(r|()TFdjx%ay(4i{FLPDKJtnjtgQKSI9aUL{BrV=VK(-7W{P-OoS-6%G0JRkMG4AmE715J#=7-M zwvmn8;+-+aPqj}pdk*%e5Tg{cU-F9bh2`O#<>3NUAvQkw<*5Rqi^j-upxFpTpicx` z^WqfAKRh4NMIXu3M>c8!s>(An+I-3=GdwFqZ~>H|@I~ zlX<%s!r6Jw=xo%Gg3?F+%D3$N{BVIYv0KFn0f}F#a~wbB__L|EOCN^D7M6aBkxj{y zNuFRBL#llOf+WJmpp~FQF-9mut=9vvxxvuyyD{GlQM|r2*jZXw3o|VKrNvJ<*1HxmWR!y;`tc3}vs=womP{Zl zNS|4anOQxsM#M9dad4{QWwW!ISy>nU5M!T$D;zTOVa+5dkwBR{MP#3~Vzn-6K?uUL zG6Ar|rY3@5t@6X!zz}{(%?aSKW}4%IQszp>9y0N)*`yl*@|?khAUQ=cG@LOjGSp0Y zGI>ybg+-LvkdHMpgjhdk)B-zP;(8WVkHR5wV0a}rhhUC`oAK{{S?|@!H}P8OUy!F6 z4_jI4$uAn5L4lme>iU|UfeEHTz44ZrBX6FFNp3EId|yl_0h}Ue?YX;8Zun@+%^K%z z2s@jB-JE${Aj6 zN$e)`JC}@;cY}{@s;hV9_ewS6JhS(EO7%hC8MeEV(Mb~GV<@o@L}rfT0HI9T=vP2w z1(~7yPzyEFo1IRdL>4E#_@{ASO*AH5$;4>$n?}PMdP;k%wgbka-RsszFWksyZVumX z{bAJlx?29c*9P2~hrb>_ht;^M2Hh!Qdd*645jC>W+qCcYkRcA_J(H&thZ!|IDEB)& zp1Xop8Z~Avn+4-wFvPAq-B5XPRAY#q7d<8YYIUeSXqHdO>3+p3f~TI zw}fb>mzoARKc0FcB9QkPE)hK{F`=y5pFfFW&cpcxCMB*Id0MR}W!7*I7N!X5|2f!E zb!zbkdDi!wJodPy#Ah0}Uz)d0>tE7iTep4Y3i8+Oh7#hHkoAO6MXJ1}dHVTHbcL(F z)Z*bMSkM!{Co>`B*d*J(7PZv3DK#c%mHG2Fe=w2CzgatEkE5z0gr8v6#^%KISDz_e zx#=3)!Pb{;Ej=?@u*m(sYIb_fiRodWO`rH61V)Cv>v^6u zqj5`z3uXs9tfD*{kNrv)HC??27t)p|lY&RSZYZ~C_ZU&&%J6w1uC8{1Iy%ezMcIN_YUT1cOV->nZ;E^%AfX#?Pj_wos%{^0&JUs=?roB)?qM= zPu4jJG@7qSJ%FBErT#;U)IXsyu^{5HXfKQJ*gJe~!s$x*dnW=d={7is!~QHUfvsb; z#Cj~wJVI>K%E}7-VJBVi7Mfm)_@Vr^>h{j(Xg!Y zq&WYAV-~>X4B)XM85t&&fGP-A=%7l$UW)d8)1XCn&HF1431b#TpoguFeIYKI6|ylT z(j}Lx@hVu`Cah9(=iv;00k|WMa$-Ti5IZaObMlPBIbpoSWVvTRC2XXzM4>MZJ{EaL z3HU(a`2*b+^=O0AKdK5qZ1qb#Gi~gX@9L5*fi&}coX}}^ zC0-*$q%U8UpL>UkZzl2v$q)~k+D z!+5^3#n>mz!zDOh!jv%M3aArI4k9y-j9+)aZPrY>_+$K2C%Dgzc1=2wpLQG?T5P-ishoYe7!13L{7h4aqx6eI^BN6`N_x{b9O7qa@^XPp3aF0mQ z(8&oB%u;y`k%iu#^+n%``0(G>{LtRfwxEqcCeKE4 z#T{ifOfaaZX=r+Amx>K)dWgfBbCU(3}`ET2~g*x5Ipof@n z5kbxxLKtvLRf&8Fk@;#>=a2L&xO@r<{sBSm=VAjl{kBTk*rw9Z5HjO@c&frOP&4>q z)I7!;7if6YmQ@(hL$bb7lD%2kkN{ylV#>VqdA%V1^iK)Nlt|1s^HL`p`WoP@%!Goz z8D&)b!Yq5CutKM)ugzBh(_LI_^N#SUabh6T#^5mlQ(UxvDmuA%t_v>{yuf>B`4uPAKLCDHDsNQzP?=CKrw?Zv;~F))&W6d zc_}$JrojR&_+zhj`0vt>AMs}h6|cuOE_YTYvm*2$)`?yxAvLHwLxuSfORCO^mAN!Au3`|oZ4ltjM zj*8t-6u_a@;WB^q0t@RzIp!15mH|*vKzkO(!iXJgbwmX9B}KBFVh|QA$;BuK#)1%1 zt(TLiDhA@VdxNMh3ja$a6}B-3d}er;E6b#~{2A>Z>N+N`!jqyKA-B(Xu-0EUQ7RO< z1{zfUBXjtF`TpQaK~+O2^H}K^SqaD?(^9_T$2r`vHz0oDV@SpYJ0s^2wT#TF{z{Oc zHR^~F91>#Y?tp$KG=MXqgeHub5)Dg0gZc|o5cwG7jK_;3Mfse4QFTD<&GJmrp~yPBm<2r^l^NZP)J4 z7HDX=_4{V87o6B>w8EE*`$v+Zt_4Yqr$StBry=JXi#~W>BgGY!^JTPh0fA>S;H^0s zFYWd_+$tq#wBw@iHXuWKmyh35mXmRi_0$_n(*}%&%=pr(aDq~PbD+aXh=i4*pos)V z*Gdq_Y=0>Q#hsr@-0N?$To9l!ceH3JUO{tcTD=4sW+6CjL}`9L1V|}AL%nn-^YJFN8Ign*Zt;| zX96cWXQ#rLfo9<5CFuN7*F1P+`oOVhd;=lebr6b_v`cw7ft5}yM?6Z6ogp#g^DHq@ zgBT@v+L;mhs_lY(D}1uM6BjBv!+p}4h?}!oi`2`;=0sTUC^tzG@nZ3VQu?+ep4^j! zt~*&+@iw+EjQB&uOA`!&{1?yuiyW7J+ZtvYrnE_yrX=w-mM!GjQOO}YA-{T5Qq#~- zeY!iNfcwZ(1*zdUH;AK|FyM#g1V_~heqVKbtrvzzMXGHz`+wY*KeVhsp?nNan1D(!~@d@fUwW%T9c z9GUCj7n3duFFgz|^OEu@jFr5~|5vxWB zuHn`g3C~m!do*bi(D3mEsQ`MP7s#ffjNSCgIka+(n>gRVfW@)GSM@ zBTa60n!jF98kp|TitAJoO-v|w#en%1HzOD&i5s$Epm*R4KfATnw-ciiJ~O%?wz0sn z`6qx!RkC6E6tgydJ(U1YqwL5?YGUNqxR1Ye7Th!_%G|E|t**6p(5f>l*yY&pZ1je0 z8Al1i+hwyAt0wIl4RC4<{LJ6?BWOuH0S5M^qPqPXvJw$W zED4KbdEg2foH>+OIKJ(}@E6?QUWtpQQC>N18{-|_{R)#m$R>$(9)5ZzFX9`6$p5vbDx>wgT%|q#_BxP7 zB98CE$kd45(u(jAA;&sX#?g5j}{pi1_MdT12c$2d#j>Sgwa8pQ|0(Hb#xJ}GZ3 z#h);6h*=cbsGr+|PTzQ&N2SkRh9^=@PDXC4RIz6_5WY0J=XHu5yGQQ3!cHvVZ`1W( zjak`~V6B%H&>s}uUJ%;~w>xW?cU_T!?Yhs1U%E@Gd?A5V$ek{$w0)}rA+}49lZxUT z0#V8>>ZId-YuwqX=A%ChA>sYC03YyQik`%)6?LEXn9hq-Mx6FN@AWFGS+h zEeRLo80maEbDx0LvC9;NT+(Qi;668eb3V#xd3OW0^tr1E!zkVy?G?c;rxxiqfAk*= ziVnEgvUCQh>cW`F%nJf89Hcp4y@tg_VZ|Dx<(-^_E|Nk~ST`D3Dv;@$MLJW?ySbr2 zmDrIjO~2_|qyF&D1lodeCc*KHY+q$Tgh`X0%0M&xzy^p2(J6AT)p~F7!U^&AAHzi` z2U+<<$q-q??8Xa}n7h!@xVuF)m#>!OI58?_s0AG^g8;2h15ZpE6-mTQYMud`ub1{E zh`F4U6$Do~q=2DM;=eDq;z3oSFJC)M9!>(o@ZjkMraxZC3|;HHSy9#UL%fyxgDEoq zAO=dcxt{VA42P9Ybsz-U!$P6C9tmu9Y-YmR!Eo!_>U!4qMzX}!;*a#e_p-}%4z zYPPU%d~@pNi`9RxIfZ)bQj@F*l5b1r`#_aTgF= z@p(x~tTAbs#?9oUD^{9KW4_+=UCMyUYUjfW5zq#t-ySt+r(ta8+0QwqsCUqX{E(|( zt3&E|k68WXEU!*(D-36KvCh zM3$CISj~=X-p5}EA8AOKXvP0J&}4%@XATY2Mw;ljv-wfXZzRZMBs>^ri?2B&>C~C+ zX*ms)7&m*Ag)Uu&UW*>mg~E>z6bF#$I$F*CF){)y$vxTbc0LxY3Gx;aZ~bsPfTN+a zN8?Yir@^DO{PdtOMZHj{&ag$QlpHaf2mnJT{^BvwK-qke5=IO3Mu$QRTACi^)Z{RW zs)xJpES;?!5X)|~)TCT;iTGqrkRMv{kxup!o%RDaA*0}W4h@ferWWu_1t;hW9j(GC z<(Dr%vz~%`^P&8@K6_%M8S>?a9?S}z)GY4~r{WawH%qAzqwFUh&^O79BxtoMY_x6R zsTpt6t0SY{_#FwS^2jo!nPC#0;5gpj&2eM(rh~A;yCVQ}Q-zV!M(~qFU|}f;u*as6 zf5`HNz)a?*i0)^autTTNHsdKCPqRHD@X~jk$Yl0w!j^6~0y&1VpNmRL_Gpj|hbeU+ zl)?o5efyY9fS72~MMsMVUQEH8PcBKP13;80W#Ha zOeojXS%hZAjUS(`K}{FzCQyg1O!_b6B)^sESy;7F!I*aIyTRh1vKuQdfqR)svabbwciG1HEj!9z0GOuotbc&>c#eGuA(+IMFszRc6 z-P#l5yQeo2@>lrNGa!02%S780P4oI<*U+wCOf= zjjrvX*KagKO4^Q5&ee4k>=3B))Vch ziacA7ZmFciiB@aO+bzr0&Jm-+WM+cG@--IY5oxZ(F7h3r_r&;u(Qz8*Q`Wecym)cT zO|^eG=Uc;-D2Ia)Q$~Brx()H+scycS*~r*mwd`7Bgzhkm_}K}!I6nORFpWQ`E*oot zK|v$*?07_{KnY1k`yC7w+ilpgWb7F?kw`c6g9ki0nVLvTNJpD9oV+Y@vXLJyz|ui2r&A|A?9g?W7Q|o9k64cnV7u>48Ef zBEqB!8MS^Ym?v_c&>S3XQ=#8uLyj0xOtO#RDbmMov`h>Kk8m)5tW- ztRmDz1N=xT0b8SamSW)bk$D}J^F|bQY5}6s_n$8A*wkH>X+_4u9*R~Xh+H7$dj@WB zh>E}jHpf)1&1a3=&%GTNI@T^(bFry!)+`_xcfqlk1a;J&_lQt9xww>2>P6SZ*p-OAX%I zB;lY^-zFCeUr(Jnd+i>*-5)>CP>SI-?`08vnT*}(fZo$T|IYU!**@n}VR86%wOi3F z?ZQ_56@5&Sg!UAp+g7EK=#45K!pHZ`JHiO12DB_^fX{ZYEPwnqCA~~0Cuji2`>~vM z8%3|4!}q0yB&oYrV`>(440iex0vpIvPO#+c>3?T6uYm4s$_`sAXo~7A0LbG9VTQ0OWSub)uzkl5lHu*eR4$mLdV%8AgJ!K*`(?G!M|MbTOR|H zSB(q5_WXzbb9tWr*)l~eW58+Dw>30OKRXdnMYgD$#4>So>FP25M=hpy+D>>%q4Sq8 z({r|tMbg33E4`7{FZWULq_JULOW_0Q%(MyKoh&%c_1~+A)?^;>Z85oF3Qz2iGr^}36+-jIYE?B_uSwqEqjCBPrGOjK1~91 zY&S2Jlj%l*tF$#Y@booPk(ms=iF=m_uJP?vQkOqRzpJ4w>mL!li@los-B6OmB* za%`d_eTEo?W03#_mDneq0BiTX!o`M%#rp}72ERAo^6LXL(Oa!L_$q2*;6Iy4G?d$I zS*k0i9#Dsh1opPx^xHg_P*Q)Bijp^c9w+Lj6n?Q#32Zyy;z-7-Oss8v)OB7M``^a- z1oH`+3mzs=z1ZM@;Jo090y@2Fw~n)sPEE;f+Ch+*J9MDzye&bX<)o2;>c;4R7ZS~J{tm1k+pJ}=|uyqcf zqXCe~{P+BI!!@t9P0-S9aCyP98OZ{vlPg^(QE=(`1SR>HwfkOiYeZUzF-v9na)bMX z<$mVc4Qgf5;(N+`(fEdw++4CksxZk52q*=G6Y8_}QmvL|*SYoha4}VuP&%e|taW@~OVtARAx#|}6 zpnyo@Uvv}ba1xA9L&}Stvy6x#n^@=0w;84NY%55}!aBV&E*3sOTaqbxY~19ocEQ$i zz~)wq5*2p_ItOSb|MZhVwmKcD#}M~At{Rl!3I-v&{@B?s`a3W5X2`nWIHAy1mL_6~ zdSFizcj>`XD;Xt+27cQ5M`IY6=FdSV`NB%e*5e?t6f^fg_5$zVipM>&jMCX6yBBNo?bez&X9Jv(urPtNd=5ju&9nzKNzTa1SM32x+?<*uo5SVmMbTb zp+?EyF81nu$9QGpR#&4jHZi#mcYA3#_K?C*nk#Ck>HJ4DIIe|xNRw@Ygs+2;EZGn- z;bn`%c7e86{&J0P@y!xvYQ{l7St6~g-fZw1F;A%cKn{V)7Fm3PQ<;>r#6;Q<=+_Ev-FOLplHVjVW zaW?~BPx|vz#@mjz!=vxP`O_HRO3o|_}__?h&1dN2~AJ@ayz@M&!!FZ)t}uh!_w z-$UGY+PJ@jlJ}Mc+xg((;EJ&Wrc}fQzSBoa$<9aPfra%_{khBFyzMTb!+08BVhcUb zWrcMEoGnvVi!_$O5&2MMmORPmO+uS}U(({sPq#0rap~dwHooL)LyW_&MKR)pO;Dz7 zd5|K*`kf;L!(w4t7R{|c;*f=-&Wxwpa%KYm`l>rt&UO($lH}Q=aS~xQ6d{5+WN7q!L{>z>zEv7c1f7QEQUz< z{F=R@(*$*uda+D|G?lTj#PZLY*~!w~5|y^W6%4JdTA>ov+UaO}f`027c`H}9KiIX- zjL(j*AxzKPR?pRY(?sNkU}yK^v*&1QtNL>Skvh8<& znoEY}B}0#M9f;c8i>+e+v{bG(rPMlLi~H&^g>3cKc4yDtgSz+Q8Lhvxxs-4*)v2)!5k3|Hl=ALuV5ANx-F0#>vGA znf1wmn;F64fu)E-jsXLL=8aS25y3=h4grvTa;RZeV+-gg?EixfUXpVhhSd=yZ{6AU|f--0p z0EUS7A3K@FOeQA>2a2HJ$M{5)0L(GN4%m1}fX4r$cvy|1PtOn)$z*(qtt-!btmMel zzG<>iQ$%TT6#S0l|20|Y@DktDLi1v3N4VCM=EB!VFO z*yjq-0dkb=l<}+x=;#s=a^)e=mEDMV>l@vW1N7?A7QguNw z_+TnjkixfOM67+7v(4zCH|UvB218(xN#bBHrF593!m6QPWUCWy9$6u86yBOVC!@qE zJ~55oL{kDjpBcD_izvR+b~ibqhZ5WwqE@$&!KQ2hU{2K*=N6K z)JJDq@b+`82e9SUo!2jfgh?2|*M^5S0;>&LMotyKZRz2VB&pL}R(*8oa5Dl7G zopY;aS%vid3kbUKDHz^Q^tW?0W#32H?SmCXFAie{4r3g0hehxQ1IC*3Ykuk62D5S< z+kNfkgW)Na{j6kHgnf|nGaTKO+YXR# z_8a}-!1L?Ijhf+C?O!;y9Q5v>orNiRy1aE~fy{$!y3&4TD4%@<%e6;4+ZnGmo zIROP)qp?f63mQjq0Yt7b`-1pqDQJpl@J^sKo+zuC7e{Cy(-?n$t!#RA?iN&s&~h>d zXavOeK&in-KL1nNlx)lKBO*+QEgVe!7j3?axcxxutDMfy?2jXrGKanDr4pwR$`giX zIUVk^y-gj|hTPtS0Eyn`6z)73R|t_+(t^TFowpG!=XSrM5274_{UgL}efrNoT8+O&qRXUd#@w+dNHzODFFhdG4PGeMX4{wW6^$nECeZJQHIW+UICtR@2k4nz`U472^%qx zXr*rs)hd~l0i~~F`@a`D40=vn2Y_!V(=*>Al&y$uV=|~T+?ucvyzvS5SgdiTjf@kg z<-V>Do7WPF%p_5~mUlGYx)?Ih-~MFGKW^w1KmkBf{aJnW27|6Z-uDPlL;27KgXLJoR-2twehwbfJEEE z59h9Jn4V2!I7P-dn6_F=dE-9q5YL*VL;IO}DKf>>}O%21~ox5)^7VRJBNeR8LrnJs776kFldQ%6PkArhNJm0v3y zu*ZB|^!yCawZWGXIZv9Z8JV3!*V)S~d$zBb@RM2#FRiJ|NBw*`J}~1cpekIvhnN<_ zPyC7gVUnWFRxEEEz+QRztLe2z{|t zwbxS)G2|SSj9r!-Q@(eacP~>~%2=d`t%VE<2`Rso%zmec#?oM-Aob;)1C_yLLuvho z-y~&B$T9SIn@Ed2VgnP@kjKAN?7x~>A`E0QMG5sZ95C z)%Y?FKo?)uRoY)SM$=NJs&!lJ=U1?@uPP=tog4`BPyH;63N}Mrh$2q4gJULdQGV|G zHWKS76oq`)54B9p%zv5w-44XQtOwzMcL60l+;Jwf69P^r&MJ|AawSQ+7E!*fjAbuM z*buhAnsUac1cz|W>$MjVtJsw-7hiq+0&@`}Ex2K{{E=Q;v<;i%>>gPbnlaHrdYLwN zMR?p@P=w=J6KbDIGd`R*kv87wMhpSE!A_>Hlb2NRjrIBWrQZ0@&u4zXK<(KnGZpR? z9oo={0XNOdWEyPE4uvu3MH0BQ8!g+>ljD?)lN&Sq@gm2xX zGK7qOIe3;bz&%*tndHWrE$XjEtj!K9G-=syLqyGn*E4^{BNp=Bc{)FB2&@JOV)l96 zELb`)3986uqDP}R*>b#>fY-Mr`V88oRoc^s7On5R9jY3{SXV--wF2xm;YJG58gQ=Z zR@T~~*EO$VqK{0K3<1$^^}|Ua5#l(spBZgF>6HXJVNzaaR&j>k%Kz|p?K9>A)4@G0 z?ZpxS0jJvVgZoAJ3l-n|>23Pt;y&YtqXe1#=KCQGtZOP^_@wo3*P z?^}q+D}1jspUaErXPR8FP(1HD(^wJN-x}5t)}voG9@y(1%k2y)siE9VY%Yuskt2b( zNH)m0ZM9xk)wbT=3kQpA8kCWqT_%WT?AwU^^x*LCo~Qt5dd41by)gFv4^%SP-WfTPBuCV8YA318f#-!f68Bq7mHf)(AE#BEJXt%rxi1eF44z%g| zH^P;|p`?&jwxLLBobFw+m$eur}G!5=Ikiv>)#_Y^$ ziargis={49)Q1T*MQ)>#yglDMRp6{xDg6ZPe)81h`t<_eUz!!pmzk0sDtFC9k_M&h zQlMf#iz2>$bpHlhpo`d)XJ^}-xlT|t5OXK5#@=!=`FXTIzV+(cdfUBCkv73U>p-8! zvB7qKJ$^d!DrY%psXo5+FwC_Po*ZLqY12chJ_!Hvo z>bt(J<7d~Wk0yAdqCuV!x3m55i_`1?+^{5W3kchk|F8bgpZxP5jKJ3yApJHq!+s(XFvhnV1?Dt5?kB{>wX zq>lh&>Qs_$dk~D|C>SHlon<&*Nyt z#4FoGic3fMhkQ$h=NNb@DlbeN)WS3XjxBpR^FQeo&-p3X+rSXX469sK8ms!lXWT-b zg_FB7a~zTp%RgcZN~j7LE$$59#K8l+=rN~lYF(6QwN z?OXX8Z<3q1zkTU0~T2U=gHOOQwO4sOHnj^l5Yuf#Hlr6V1d|RIc_-umNlvx>2 zX-7`x7ZB2wKu7gA$>mG}hsyKi#xnEy(Z!^^v-UF-&;rzdwWgI-Cp$j}9>lGa@HTZV z=}J!A(nq`K*pu++aNH$znuAs%xv(K|U1_B)AzKuBjt}sB=})8*r;D9ggViBIRX{eURNn2Qqo>EHf#ndG(;#xNns6@blThz0?RoWdS_6v1U1>4}nQKv>=XCqNhc=uiM4->LDeBzOpP@ ztFkxgk2g=G(v~+yTN9QMI7?Mr88i5Ki+HrvD|q6g`ggBD(f6!q-@v&QxX~-HMCa*> zl|^^Q?|C$U_Ny&o0FpbtRgvsv!|abbzrawuj2aF`CaxCR6|<$hu)~VMq^=eYzE~IK z?Tt>dVJXp`6FrMsNr*k*YZ+$E)?h}UD>k4x1bi21@fReUbUcJl00={fyOS7|M|oWw%ePp4eEI8`|*{ zEdR;-ABtGZF2EF|@7__$aP1l5fTuyV@J0o`nuoOK{c}1eys<=RzTPNY!3OI(q!c-% z8(^|`{Xu8G*CP5xM+W=*eVV{U)nSLPBi+E4srM$9O`v7u*w*C@zc#wb(A7WId^PrT zb?oba6zuroVe|KPJ;#|!sO7{rUGYBzC;$&JRi$U9dIL5V7CI2&Q*}NP5=nApHDl>b zVz(3c9X3UPY+IGZ?a7W8NiSHI3-$2*&rxM!S>HaQkaRR`QJm8|W?sC(fNz4XLn*z;3x;f5cr$Ysqvxm1`V%kTJl=MD! zJr2CMtq^{F7Kt`R!WRPuc$Y+k1`b)f)MMrQ)ucn7K(^aiiB+65*g_jLp}cR`@o^YG zn^Fkcg15A^aY9$uadO<=;!+3ZNxT};U#jXEPSTFi65scq8D>a1g%l4SE2d{xg~Q`8 zZIKqf-7i8f|C#|LzUx|9|G+SvM7rq#GJ>4Q%YbX((6;C6?+qzi2U}2g->sBx={vcm zmhv17)QuUULz}UMBHYN(x8MntgA=un=uzXZungZ+s|INGTw`gYWXL+?X4ewx4i(>_ zjp9YDrP~fjL7vUu*xtX}M#%%L@-q=rNmOU`LvCe1d7uU@&*i(im117}GkEc!+X)2= z<2C-l5UXW+Dt?U{UM$ej_5@OSugu-GDz|Axcf96?d3Hp_++3;Z7=6@vp)|DESqa6r z4a#Is2K0?P)zMfStq(R`Z&7_$D>}>*xG1 zKG1BjH;vP!MTs|dJLO;e%)y_UWkMoZa_o!fsAw#h)W|)M7gApK^51iv`Oh4a^Kg$s zExT@(u}LwWv5UJE!BIO4!e{^-czCi>EqkVc14~+7JYlE(e7|la8~$))J|^U}dvKPI zv_+mg@BfYQEoqFW6c7c{3S?Uj@oYx%1x+zO)AVscL@f32ednYNeJx@W^^Zkve4>Kz#JacK%JWmj3lqhaUu9~aH z8GTa7a;L_G(F7e=%Zg zW{@!s8rCpo@)VzU3wKm?>*cj#A-z)Fsf1H;ySM?HGhEgWn@B73Ukr)BEa)*!6mT^_ zkF$4Ad*O+0Y9tbQRmL6xzYYt9{v*X0?%RbK(;L!LTEQWo_p*FC^Syf9V@4M0(5kmI zpx5e)MGb!Zvi8amPg0ocN;Qs^n67reQ?01k85uWzji4o#Wj^>l(z9X_8)O6o$V;cc zHNc`XAV9rNx;is=GU!Inz^h}Y{{mNyjujW)d_TQ`I322iW=I^Va^j5I23ZN8OMA}L zTrV>s@(7=jp$rK2)dkQuZP?0D58*DxcH>Qv(d>^k`Brdcl`tR)RUB>_TP>|Ab6d^wA(wReE8yUuC3W+e53u}5LNtf@9l0GwC}=# zO{N!l2F9ZCn)Zgc;}nU_9a&tbTRPH`_o96t+d>byz|_*h6t1|WzRQETlo#?OGZE0s ziR`U-P5z7K+9vkqYR@u>}E;WNPkPf$J5mte%iIop2$W^P4ic7wl4u_p$`MVmkXqXKW^)y z7MMs?{CGZwirR(xq)uA!eYZmY{1QNh`t{pzJdz$E?$5#UwORpu&JQxBmY*4xd`rzN zY4!DY*yi?!KpsbwUcPZI3DJ6JbMWr?B(1ZzcxOXrR5eX(|Eb%yYJ1%;jC~QZOpAQ%55?o zpK@6c#iAb_uG8H>_e5`<6J4sY21A}ef9LB)^@vqQd(KK$YW?axoY>N>fiAZjiAM-k zYUHz=2%-QF01o9Ft_yo+pTIo*N3KMDM|H6&n!jS;*Ao&HRh$Qigak-q0LXa!0je5n z9mlh7Jd>vN2MxpxVb~i2DwRZ$10zamCSZt=P804^prJ^)4Om%3;d7wjCw})E)d{C! z0?Tt$1GaCHSRh#iTy}YWaHB&K5`%6Kp|Tj>FO8VMztcr8(jd=#HCUAG*Fd*0I7KaE z01~|z&Y2}!jJ8mNJYz%8qsYuVz~&hQP#Vl#bZ}}oA*mee8GA9HYiUAst5>7otLkGB z)|q5VI=Q)ALiy!Z!suj@e~-^sJZppy-;F1E-=c}GE=ZT$tU2W~97mf)Va6n!j&DEB95xl>S z(1mtX5L#adY}o2gkBD@^ighF6bq>o(RINkMHc8q^YBpora4NsN$)*_};@Qr?a6EXee|2H^*uKg4}hb z8RiEjZ|kaJN_2ooG!g|dFR%FMDoh12G^t6ri^~l zHCZjyt%BJM76*BuqL|qdOO4D1i;oi`nk@>`ykZEQ#tKXBwwsZmjRVQaf77pR_W!Mw zLLAastM(JVn_Vr-T|{on!fCah%ldujt%*t#R>7Mk84_LYaSOjPJXVl!AJ8AIfc6t> z`4RyMF2I8rf83N2h0J%e%$huN-9AW&l%Cm=q~O*^eIs+|1WJ3&Xh+gX`I%D=U3(y{ zaw^QViS-lU=6t?=OjSlJyagN;w8Ii005j{QM9Y6}IoFMc`lV%GnJO-?L*W>oH_%Pt z@%WO&KW2s;;!MbfK8pAuvAg9m0+#E`&S`clgxmpzr|w1{|28xf1k(M3sn_skBbwLR z$1E7};mQZ)FqfE#+_pKwP6}X&UURQi4e+Aa`20{R8vDmC^JIm7N(|M|JP}L26 zbZvy2xF5`aj~bZU$pzY#G6GEuc|>D5t}3W0X|#BQfmm{7H0B6XvCDX>KaA1O+O?b! z{F`3P7~WO0` zD@5Wpqwv(5F+erV{K}S?GjP}C9=?T=haV+Gu5x3Czh{d}Fhqr#>LWf<4lw1;3=@VDp0 zdHG$XEM9CjobNGnrB9>qw*M~+o{fAK{`aKgC5roO%_++~m>DB!C*qQ4!5hnqWuIo^ z*k8L)cGaDoP{#KF0+%6Iwy<8^{Kgv#muTZgGhb;8hmg72?$BS!Ns7gRv8Ns?>;$R; z0SKJFVI!bwG)pW80bhU;%d9&x7W;f8$q=0Z`c5Idh&D#Qn;knM8Y{LkC7v$p5qTdq zAN`cf>%0Sg8^g-%vTQw3PmRlkRXgWx7B|<>)Qbx|wn2>e#<0%nCfnrw--Dy|ISngf zE&ggaErPK0t~#NVgL&XjR2~Q8=<4XzRQaVU+y5y#F2!|mCjP@QDeW4zgi>2af~V@|_qa-%q~_H=R?R>GLsBX?g@e zyTg^JdGXL3hT=_o``IX!`(Dll2imgqizH7`$^YK&PU2BEFsnf5gs1gU4C9Q8ZTCdb zd)o=a&Eozo7PY>R9UbtS7+UTB@~2Ow`jsJ4O7dt>AEj=4wggp3O`vV8GqC#%0LktY zo!>nycjE7C?m*jth{ih#*>#5@40mna#6Yt^anA?+Rl>6)@X-q&VPUn$a1oKWrKG`+ zkqR^xAQylT)QEy?l}x8{;a&6fx&y}z#0JbWo<>S&XE=Tn*;|XT3#1{DEVZ$FG+o}A zQ2L+42tY@D6$Cp$H&bodRkU7et+R-QEPxZzxwa9~D0_!vFU=O&Jqi8+KuctKnmWVa#=NI**H_Z*RE0(=$-JN;}kp~qz31mi_XuM z4YcMSbAfl=7~w|pXbNnBn`jBwqHh^@O0L~LTYt5>D6?#7=jU*i*E?o7E3^^G(|=S1 zeQvc6d=e~$ji9Y5h&Fk4#>j+rKbzQFJu=5t7Az<_G_T*#RG_-UIy2IelcoAHq|QrN zRYInx=>PKaX&>%tA^-bRyWosj01;7-Y-r{uHk!6xQY2$0tSO#UwCSlbmBp8E^Y30y z4z`^QJ+rj1myt)_8ufng>a>tY=Hml5cE$H#!K&IYEPg&uT9N?nt9kPS7fW7i6ynE! z+f%C_p4H_?N@2v_$2ISMUN6GKk@{PPGm!n-BeJ5|MVpFW(VM7pnZ_ipGE5>}1)74|=CWUgdFQaxR1G_?M!tUcQR8qZ;y zvKzZlY2j||!X5{#pRh8BJivI}&NXeNkO6g^qGa}qIz-Hg{&Xf&mBsI~cd3>)aAl(7 z`LIcV!v?8%UDi$KoQ*Ih7YybRJXvlG>ODGxGLilnOU^UK;-++z+6}dXr;YL5kHyBB zRI(ANkW$lqiz7IO5M1T{*pK0AL<`nybjg=%;e*KPk?TCU-SG0|+clW>InG226hIKY5SFtX*<&7B4zWPn~Ct zdtp)$bix>)!BB>#5yUS-D>_IZ6+gp)q_OV{v8Vn0mH9d9q1N`KFDGpz}_#yHjB zsyTn2UA}F>jlS+J^o|597MDbgW(T9;gU3pZx(8#}E4k^5bmn?9YblQ#?u9G0(r;ZO z=cni(G1V>>loRVdR~D5~fP3p(wJK#;x`1r7#%P6p!Qv4`7?-QBWx8+DFOkYKbi-UT zy|uftl26YH65V$f=aqmfg(@r#-T_83MqPx_(lXhgIN;kwKFO(yniF{U0|{rpYL z;uG9$4`XYyx{~^E5@5y51i+F!$!$dY0yqxtyOKT+`8J7BXwfZ5^?VamXL}e}(n|{B zEosvhy(h^3I>`35_54>HT4S{xyDk}EXp_*dGt z=`O$mv6H^1%Srz6$L{_dOO3_76k`AP&~);jAV^@6 zB9mNr58=K6UU!u$1p_S9GbMRW=Gac}#uM0_TDaBhC>_gSts4;=6NH##WIt))uOUt+ zUC7E+%6W>_^_4FmdExhT4D~!8+ORH;9yXBVKTl<{(Scl@8P~2;z>mf7oUrCfly+P@ zT)z?bi#hUdM*z4H_5A9eONd;TfYM2f^)WtI;?J_SY~3!tf>p=C@1E&2 zC8mChJS8^WK{xy5Ev?Zrrwx^~Jsr2kpxNw7Ys+gdR8Z1?H&-83%opAbuU6r%r73^z zd5zNxY_kBmrXlXD<;p~`*Lp#f0p$Dg^-%LWXwFOA`1Tl~9#m$(eh zX5?1k6kBT`5<<1Cv~d&|!EnXpBUg{})=T0?wCJw)G8Vj6AyCKY<#`z`hp4l?9mnS+ z?dxx9i{H%X2%*fy-b9>V1leQkt9IpsdlpxuHlV^-rF55!iux_M8}4yCv(CiB)Be}- zo?N+Us_`a-vqtA_U>XCsHxx?ZW^}RLbK6#ZRlI(+GdjLQBaR zRz6X7cH+(Y$G5Ky`+#&EPH7jz)!=7>Ed}VcWE$7lt!dyB{(fU~i0`><=;@j#q@+gy zPfoiNA&LIhQqb^DE6;S+|Jh$RU&irI^C6My^iSj4I$Y$jwLx|oZjMWIx?o*g?`xTJ zxtQ-}B4fE%`9`9w<5~OtEwgkDLu}l6Ho58)3iB5aG9TN1I}GMO6Q6AqwPntc`hVzS zk@8W=|0%_177d~d_Vv;8ojw~-ndavG+BS?19kyTob)x4DhsF=KjQ;^5lrf4T}%%*p%<&XKli#Pdb+4O!rAR@ZXwyhy8LF2+z zTOp2HwqYxQ*kfjGb{89C>}X@GUiL>L=v8%N>V1zWG4Hp0^qe(&6vmqFkfFfiwK5AvARC6DuKFA$USNQ_JIkQ- zqa{HwcrPgZn;r8%8`g7_mpm0hI)Sd7q=;4ST-f2cxF zCl`bGGfm2{`mTGH^J2!aQTPh{dO>+PAtS@wxhv_|qB|nxQg5%yNrLfILb!lBjvx{{b40V3eek57kD9WD5Jhofq0<;{bMHUmPhWshk7CD z2fk#;LObiY3^|oBbaSE|SxNeux{tD(j&~7KJQ8V&c)eK9rw;9Md;>S9O{p0Ipnlr_ zgV(yr*fU*e8Th7@_*!fc5$KR}IFpKm>tIW7 zD1R(@3q@6H4C&TeFhCWKIP%Tm9`jpCR)(ua#kL~-buExq{l$=U>yE{DaF$|c;?Z@$ zD$D&^HYUg1pIEh}$Igl;fDVaw(NPm8~?5}y4 zeZNf4QIz!v)vABb{v9DFOX%RK_vlVEuffy7{^V5nW{d6^k?e+huC3X)c4VPhpKDO~ z-ggt(PiCSx%^Erv+4KyXp~u}k8O(kEtG@S?n<;3;%J1YiWZq3FU;(<=EwA3m5kjNB z)!IB;^9JLr)H3gM(}bclz^B~z2mUruw$iqT93&)VJkuz^yVK99nQFY2slJGugA-d$ zjSo30HhEVQ-^O%AF0Kz%s9F4@7lgMHZ8cP{QX7J+s9b-iLwnFb{r`p1vUw-;jwlX% z<1pU;?_W+UwQ_+kX&Bsg{M~qcQomy#mrF|Khl_6k@16Dj+^Gv&3RnGhHU|I)xvVa% zce*ODvO|v$;fvI9?crfh;m2+M4$JOw-}zm%@53W>2HN0x0`UKta%rm#R!bQwJ0Lrm zihOM^@K6y6oSdqDjjhL(2(`##oxgE$iL-Wup~%(RtzPL$H5!`sZ*L*#GnN0O7}V-` zxBNOTt4Sti*5enFitc%EOb!7_n1xlp7J- zKkY2802d0{*c%iSN&5V{ifyrO)F(-~axs}b{t3g*hEXe$@^`@bakKh6)p)NoZ4|QC zSAozp24eL?7nKcXqqjv;yIe$u@<0ILmR~1?fbU#TXW$5Ph|Tgu=KGN6En|ESEg?`6 zd~-=RgPBHp+uq+x8xfrsFhfuwO3&ym?`5KZaD81w3E7n+e_htRTJ1;`f(ME&p14ac zhv-I?yjodIK}+bRWS}Uo`RLW!rJ3T4tTXj2K7V5S#~WRRzp$j>LadU{|9s%SV0AZ( zcFk$Xj`mi@-V;fyv(v9?L?Bau^=jb_onk~=~!dFBz?!?p19rO6+ z8?0bCjEt^oA4jttnlFkL(cX-q_sL^Yfe=k;N+TJ2ppa7BWf=X!iSRLQP_rC$7+{E1 z4z61uvrGlUXHkhDdr$H&;g*?!S2G_2?W)D zTwq|xpmmKT!*o7Epylq7`Yi(}h6Zo>c>%!ow8xx@(M8&r?gFpF+v0R!aR+QaMADeL z$V3IJ6temY_p#?0D3CV0LJTt}1nOhhBn*C6Z0fXg)pr;*W0^d3!+l~|nIND#(lc>S zEg&=31>IM7g*GGtzUcB4Q2eTW|IJsU(M7hd@^4BA{P6Q5{XPd4^+ufd0j43HvXmt( z*e;n=NZZofMRftg{v(>WaJzj(79Amp{oG^s!uhj4g(a~b5C5MWR&_lerq+|UArHM^ zMhnuqnpuOuP&KXbn`B^M-5GehD>|yJd^cqt44A?bMNbm_zMZw>=ZJu^pLS~72SaYv z80PZ_blOJP!w_8>V99s6!a&vuEn~A4GXx6;$Y!^Wn0H2WH1$1j%3G)cce?2@W*=l5 zk042IoJfY)f~>xYP@_Y|9TMATnkihQXTv+nAZln&VQxvoY~zs1?R9<0gf;S;36}sK z4viM&KslUvpudMHJG3)G(y(F2?{pj2_|fF{UD)-3!ZnvPOj|+}Ks~e^qGC8WFro=E z{jRVLOSrJnh{$qJ*zxCQhTY5>*GV>E>6@M_T^po07BAXEX^=#!L(Tb+LeK0IrSp}c zF(1@kB`h;j!hgdS&4{38rf6`6b%n}v8K1z)qn14guTD{zC%GGz!y-GS=}yPR&a!V8 zgAPa80V@1gh@6kN86->sR3D`OFJK=RNrzCG4Lh?{TMJlKA1ha9WNh86cU65AE~4nM zC0<~Tm5K5Q$Ld~0c#?V=>lDXuAHbyEb&O)^<{}hC}Gm@O_ zcXbq?jk}>~we@33&qS#Ie3c7|Dij%?@6-sHYeb@qS6v=E^)-Zndk4Elbl+ zXnQa%Y>Fp<*DI8h0fatOz5!xN_(AdSK}K}}uJY9dZod_g$`OFH=%2prXVcL49_w6d zf+5uDqs!;uHIHo||QcYNf8|VZm4@jxgQ$nQ7A}}(0&tE^7jWCO^d)--5;|QB;r?1 z#@e&fOfN;% z#i7%znZ`6ih6RlzS}!4Bns;>1OpuDExL}jZ*gY~HZ+zQ>X0V$<%3r7Jxw`o}8xHpi3U0-x%?SV)cJpL(BAEHmC8M<^S$qA=#@%_a zJjD+cNtULeKS>np;2Y<#`z8M`4T)cN~ne%PR`aO z8v|cD;d=gbqdCA}1OWMV#P_vZ(Oh%&jGnlf^GXSG3k*R>;HLNJz4fe9(opvg+)q;> zmChFt_p6nLtYzn%%l?=Cc6Ohg(y|U3ixk|FO&l&W1N|r1SGdMGpAlU(iW>{aj2$!p zd5lKk)sz$Tq#bJOFCnqC?{O8it^1}j-Cp)BUIO%P(Bx<${?rs=R z`y}};6Ub{0!)0v{Rs423jHpEKHffq(eE$RtxZga9r(btWQR9?r)U@FSaC|7{Ysv<; zz;LT_+koaCzfEQDJQ&$s7i=+8OGg|ke0Y({*$U~dpm8{1uXV_ILghI+L*>27*tBZS zhTb^*>l&{ZC{Fkkp-D4UpzjtU@_V4kX3STNjF#C{I?0B(euOFrhxMgxxst~mKkKX4 z9vs?oO&_mr4*l!7TA9hY@&OJo!C(0vRxIy7xv@WPWkV)zT|CA~QygR2go=58yCgHV za;QPPqc+=zzc5ztcNZqN0}cOc@$7!5rp&2mZ;}%V3S0Y*v)1l)GwMO$#42UvK2GC5 z5L$$}-PCikx_A36(&Y=_-5auZt9oc| zkoW`gdo?QG08!pO1z5ak)I?mJ8ve#$fUpZ2(;C1~!oGvLgjd-f}ME z#TN#Q7YHi=(Lls8&j0L1LI_YGp|*p*9xJLTIyD;%5fmWP8!`7g%5433di@7N@tlWv zl%0x2oe5u?EiaagW3Dgf%Fnxayv3LE@;QBkT!h=BiVaCeKVvgpLbv{#A3&$hU}{%E z@ zjH*FG%;|?+m#Cb;A2tl9y&moW#AyNdAYDga+n}-&%3LMd*quUAV{;v65Go(J!&ENg zSJW2w*c^+VJnu-pv*?}d3IDTic7=cdMFdY~febAu*%8e2LQmB~jb5^hNq;tu)avM& z2xrgnM=k`M6NeF=q^Jd%0s-rLc}^uX`(e=dtx(nJorjU?%y{k}yYBp~cNrpf4z_hr zS_$EIH+Os_*w-HYTVo#&2%OZ9TU}kD-MwD%p_{1d5>ZYyO%A?VqZqdPgEj)zKGCX- zK0Y%FJntI+TcWjQ%eV3UzC9?9JVg10uOzM0#P;|uTtOU(JKfZQ@dZFD{DQ`$8@0T)} z`A2P!LX7Wec4N6e&TH>>@;pwvOg0VqE}aa%UIaOB10u65&BZX26s}cpn>}7#-3qc8 zeW7>azOP(g?iaDw{X*&zr2;*12>Cru&@OGM9bH|5=1P)-)9Z52y?*R!;wywj7eJS8 z|8aF*NHb&^Ve(g_yf|g zzJ%R2h|72maCrw^K5tyjt106r8BlMH5|z~Rkob!CZ($fmbH4fr)ryaEr}Xv25n|ZE zZ+Naz#r@Aejl(;)Oe)#R>C>pRc^@Fj!BBq3p{h$AMrJ6F0}qBu2Q4~=;1}<~YK}}r zj@Nt}T+FCz30zE`6{Vj8He)!@>Wcik+_4OsxBSnki!a7(tVrOA=HG#x-i@3P&3C}# zLf)Qt8>$E*v-E22gd=oJLkSrEnTViKhlbo{#Sjf=EG%#`(liaW#5}097zLG+(lQW% zH_M5>`eS!KQWTwe;&Z|9RNo;QV;{x6H`Mu@2j<#LIs#H{4yWD1MQtSkU2vsNi&5T^ z2RD#|DC)dp2wK?#U7w>deXQd!45Z+Mk^}4y_8vAhlgeF~v8aU!GV%U;s^}O&*9{jw zOJN?X2P9{_oN$26)34{V&e=l%%qtXQ??DLH*})2n$00}Es3C6%?OE%=vRy?A@quMI$;EOMqp7GzJ8|>mybi+VwtG0ob~irLq5)3oVNNb% z0h57|HRM}LP9IyBV{_Sv>vX9#s`Y%OGd8~OF+5h2^Uy!$&MC}X7mKfl!R*~hk zv##Y}Wk`pV;2XOWotE}-yO(X4*c`Ci(SbH&KHC(KeF#!XZA+8W8#|wrj@wM}T9*AtQ6 z{#pK&-0I4_`^a~c)I6{3L^#5&(Tw3h*K`STJSUJB8BeC9GLqxNLeuNu<2zRU@-J*N zb)Q9#s7Ef>By7;hFeL7u18*{-&{Ml?ehp4j&K1gnUxDAqr>m8F_dZj&8#g5rr)ZMG z$Y#&TQdVc)J3?=nMNT@oyKwqL9+GFo#us<+<>t1m#-vxpV)E`h&%7LLiI36hs$ddX zeS8SBw&luYIZRY`@*gWF3VLoCd%t&TO;op>Hv$^#hy3g`hGW4|S^Vbl?zJ3qi0SI5 zJ9_n=XZi-l%w|bT$B_*dALo9QQz$zO@qlX|_7I80TJYnmt5g_;4NKj&{N5fcGWCwB zTG>tt$QS{eI^sNuIbX_3*dB?c$q6IRa_iY_#}kY-DTdbIza0YJanO=`O9wp9#_Xid z{Sc%n83i{6mHO}KO%$!P;d{s6QRt~QHPHE+Fr2?`^X(6>(|)>`d77~)Iez>x8Qo<) zCw~lZBYBejR{s7f@~vie`wX1Rg#fGQ{ie-V{M>z{*C>sD-xK+c>bTNfz&3Tt;3j{0 zN+L!(QbqIBx|SBNaiP4Q#NV}SIj`;KZ1Z@&9s3D5@Av5yJT~?JqD80GPSmuy-DmK>@EiuO%_@hzRkgb+a5ek|Z-?hI zan8fO*_Yf_tbs__MJ0D+MoAy2Dig+DVB?C3aeQgW;|Rj#lL9uXF=3l}GIo3pC~x1a z<0no$0(w>becB~=Zp9&)*PBOm$P~jT{jmU)_BaD z0{dgf(WY)DL!st|9r_;X1SI6}jCH})I6$T{heS@WkB{wtImNm)WB?84 zvOMZJ4Z97-?7_^Sif{odX)U(!)!k~YJD`BWiWYysEpULN?OoJyOB?Dv6YzbT z2%a!b(+^lk+*}0F1jE<_;oR8FHW*-{rxp(43)<8i={9kuV3g^#X~qFDOcRm%U|f%- z>k7fxBPNC&u)+T{6v+6y@LEHDz>E|gvQ(tm_tcxWmoIAa|=?Z$2*H#+pG#6%ywtlvz+8+w7&IvzX zk>dRlqVrZ2pAG?sz+<_NGqCplPRmf*&*<(_3Xvj1CUy?-8L$syaGxtf$?N?atgzj^ zG#MIxY{9)wQ#r`sSgk?*hidBIzToMbkaPvN#LBZK!Ttv-r=WW2Kx zdb>A{p0blCu(8y4AF-NpRh)Ktq)p?oIlJGD)(zQ>&wTtVPKjCRsvOBKB^?ZRUh>V8 zCOv*Tl&}?RlhsB)8>;J6zX8Wq;kg&%JsZ$KwQF3B#e9YcT|WrT|8Vq9{7<@h+m`z& z;wi%P!6f2cveCWZugpsCmH20`Lvw`5HU$v=>Q{deza?(>-%8h47``mZ?l(ua(1Drf zw{iOGk6tSq=<3M?K|_g0U1fGWyn^8cyv zC(W#(!YL3q2|ME>TAItzQvJj}N2)llX(x=YW*)sR_83AT6?4Sc6$ENTHp@<~>M4QET?+`G}=``oc1EwlmB7JR9rz>i?k<;4hd^Xn@>1H*Hg4bibSz z&3_9U5u~1S<+)T^>wEn#V9Ae+T0!P!{f;dozu|b$-eKR7lHL~6cRz(azm9WfA0e+P z841dR$6@?k`ujIko{wzj_Faf=PLFHJ7bGW#&1u%E=({{Bf9W3QytM4?mh5OaGar|d zH>NfH0jCA4L+M{Q0o3M-^`okYntC0D#?(8ImH$bT=e5@a>ZfRzO(k>`3`SB)+{$5k zPjkC*{hjnoZ;MVy$36! zUI_6#-GZhCAh5s0Lc};+9mBG7`_Ighm{MaaS%PlNKL2m@)Q9AANZ_Y>NlC$k`9NW+ zx4}EV^GZ)NbDrLR=*7|ayE$=+YAPN9nWQoN@>;TeU*M*y(T*1OLk5| zr_mg*SwQ$swefVL3;m8Bg36}*>*Q%H@t@J#e!87G?sSv2@@}lP4a{aqCN;p*54ct9 z&?L#95M0n`=d6FfdQ8P1Nf~v9U3bm;cHGkb)*2eq{@Dxc3eiwqFF`H(>uz5^V2l75 zC*SL3`N`aK4*MwBJ5djWb`|0J|JRGxc{NmD0C)sN|KK*1Eo<+iy%i@~z4g4bzSJb>Alm+vbTB46;$bdklWoxs;;pE(x!p(EwNe0&aXq6*#6x~LGlKD4Yx2+(u=Oi zu8jY&8Lz~LqwB)aco;X`a&+hgrCx9@6DPGEQuPZfCi%R$#T0D|XcJS#`E64odZ~RD z{ZmtO2g9xcv$a)K85&Py zF!w=8>6+NiSh+}hM4hg8ju(agHz~_UXVG=D;det=GOOQhrU##wY?} z_k(5|+(HI6l!xJ{vi2$D8-KR%Yu%sYAig$hT@COuvZ&-&OxqGVd~o#@z-jG)5UKBY@{{43!N~kJ68wkDqouwtBbmP zSxxi>m|2xCa~qY+nsFGc3N2-aCP7TSoKJ^Sk79&rDz=rIK3a7m7ZZrY<^>OJaO(*= zjx2hR4DkYPLu>js?!o|GO=-lP`cc_ zH$2x`nZAiz%BFwlH?cFBtVc?j$>kJ*nZe1hdt`-0!rXe;wDC1gF=^`bdYCN#4d>=; zv5}{X^*ftHdR^0+qk#Zi-e(HM56aE;TcDD&O|a)aCq9~4v^s1FZ)F2d70%I$>dy>Q z3*5W&3@RoLg}kxqw1z$5|CXYjDHD^)#dXNjr2oaqYa4}n)x;`SSb4^~{NF~0$G-pv zTBKXVJnBXSUe+L|K;I zi)^DmH=xFR3BRuOn^!fWLYl4?eOfFs@bvite+X&K)^IWZ!yoS*HaJKFreieJd#**K zEM0N%kXzf%zIU1b7>uEDW~LnQ^RBk^vvhv@9+ouv8tE=mg#dO?0}W#gmCknJ8Fe2Y zSR-!I;MP&Mh;dd|RVyuzQiY|0!T+gz6=@bDktb@;VrX4e?vh(g{HSKbK)eYGDT7*V zX)zqu5+@ZR%p^P=n>UHO6#$YJu+f?kj^+}$oo{jiy>G~PNlE$U?FIPMVRs{f+||Rp zsHnqQ-o(-=t`b=NRQ%x(XTbc1uylDJ&2is?!KC?rv#;rA)NPo>Q?@OV(l#N1b%!rg`E1rh_xLW6?3wUfi z7Yo*5s6=2kiE=W0o$PdKB0{$W6ci#On$!s4^D!G}76h3m2tb6S{*hB%B`4+N69|WV z%8hU+0qhXdAc0@b9(k0CS?@bkS{AZOChb(eKMOOAeGakWR#gT^UiL(P4oaJoFuxnP z<723mdC(W#2SNbs5-XG~99JwF0o=vg)W9}i#^8g8hqS`)vW_ceH-hdR%t%q5mWS~B zAN2|)8dOMc2|FbIxM7jSyCFToi|DL}e+N~3%iEv3xn4J`sy|Dv++BPPoJsxoCW`4# zu}C;JM5KB|2Bx<<#EK@6N~i3nK#&>$xYN422iaO?-2>$lXcOxoqADm=ZvqG{VEFrQ z4w(|DV}JtfX{&%I&^A(YRJDS+2Ub71eSG zQG`a85Fy7U?#6qT5Ha7=hYZ<1B37-r4?qcGg3ds~ z_-6$lpw4{=alnWw(x1e3#}@iTjU1s14J=S($Bg#1O_lk(Cc(INxY)yZb*!u4c-JV- zVYEmXi3FF6KU&|xJl(LWpcaayjn;`&^U&CvHb#&f`BKaIk7lZ3-w24-P$dIk@xXSP z*6U5M7ZEeDk}2OoA0%=G087vBE0-7N^s~-Fp$^<(XAL1B16@z{8zP!%^tlsIl#>N%30!z*#XEd-2)072UJ4uGCWNc@r@q7hc@$It1S1%H*%0L z9eEw16x$jcoi&GFMWa%YeA@apj7T#4QkU#QgrO5cCUin#irxSZ1KAW!zm5&^nA=0g z?`4R5LlL>Ufo0;l=Or~r2);%~eh8mMD`2qfyuC1$V0J|McqT-~Oqr?S!s}*4wvOnq zsbbX>GS`&{Af1NsTG!qX{=_S_i!->E2qiAzi6aSaU^C{u`D&&h1_5Yy`VJq(?S^}@ z+W)I~l2k*s`5xXDIWa%5B@!TF8!GO4-us4GFCBnTfjP0(T=3IE($P-{3eq!PfU;LY zQL&|;r^mn^S=LFm+Tp!K0QXgt3PBwAl_MeD#(df1fXtNR16gwq`a!sJ#ihOPy#r2X zkjf0t>}q~#BtnT<*bx=LxoJA#+GTRlU>`UD0j>*;?R(RGBRpm|6#uyYwhG{2z8!Dd zZ^7EupwFF$hv3!qqhBiJQH;Vm>cjAb(+$IA}u7{`+Fl00@GFAm5iORc8tDy31mh4@xciQf>Hp2_qI1* z!W&x8q8Kc9pSe+Z$gCC)?u3No@83aig&eSI<&IL0Rue)8(R+G?^IgnsXEDm}rWGf} ztv5bPU5L~`jsvaj+_3)OB)dX0=@8ra$HS=|?9c--2?HSskr)J%68*iRl_P+hLX$ks zA>IEJndA=~=^)$-c0-eWrtH05JLF4(;k|$UdG`Kv(TaUy3nCg95N#Sp#OrQ9q^eih zi-_MarrjSrFes_vDE{sGBx7aB9Sqz6E|bk7I@lB5k+g_P09HDt%lOoAfh8^s{`QyC z8nl_tF-T)=afA=~ZpljO7ySFgF4b2x+gs1yz|_t7DWfj%b^k^!SS>-b^L$L3*gdX1 zv4t#Ji!Zr#E$y@@JuP)7m08b;AFU5lfL);d7`ohqYPN2gB;tywyY>r0|L=@5aEK>LJEDQWM6Kq zr~B?hPIC;nElz+#za2ZB?W(2E4W;}(1B&VTWMxB~ljjVB^;QrrcbnC=`*=Ns{s5}Ivuw9B-e#~%g7QfO6v%Cciops+5P~8 z7&&bqnfdV2!XQ!oQgH;#jXFip$)Y8)nt(n(@)nPdNBQbfdo?YFc01%3U^2rd5hN+d zPb#B(PAu^(l*tR{bxaFJyxlk=K11LKv&7J)yKQ(a&C!>Tzf7kgj(aMyzr0;lWe3Tab$I0{h0I_4p_XLVG$G}VJWP=l zhop=#hcq_#d}s{e2#XLH8i~;zUzAF$2%reQiR>#N8ez+$_=H=Ni@r>4%ALnu%R|HO zG*o_n5Y6bKa*k|uoPAI3gOZV~UI28N+Lg{K9U+Y|ssad*PbxA291a1z0YU&5(z(y- z403&WE^R*EhWP@^M6U+s)*fq#$D30e5xDf3boSwo8t?<)5DW@wDxDb8)(e)q``J76R$86X~b0IpDpYGS@*{l5$SSwZAmVnY0FMt0qG?@k`I0B4(`AQ-J_m8pi=w90*%_r^88 z0ke2jf`nvWnYEUgM-{Wd#=i(~@KBdSOV($40F%Oy46}0mxMT#or%jx9C^Xx7|jFZ?Iz^S@oi&npP7-L-k-7p z3E)%BZQYvTuax`Q;iAtkY^#;T7NvunYKhmN=r~az+rL=#f`xLkOT76P?2k>{-3*bI z#0q6#Lec@MZrBIOHqWQ*$d)N<(u;87e_4OWsE0Rwv z=h7e&%rMM0b`oI(FmQn}45F8@YYI2CFJU(rENLemtZ%NqZ?3oXl*4wlmt^1U_1O{7 zlHTc+4+;r^at}|j-?J+~C~oN~11zCpU)q29v(aWLnvdmVAT}Rc*=invPXtgM0eFbsElD_smJK!-xS;E` z|EG@?$nuP47y%L7mj}A?vQa#K~^_ATD27 zH8Jw1s&!4W*EelupwHk{x3s02>mlL@GQx?|3?T1mzbX{c@&>#>xbB8$Fv2Qwvo9j> z!Khwi8>P5tmRYJ*enIBKwOHA_fP~E%S>M)s!?j-6l>1GH8-Ase*OaWL%*U5<6`So@ zCmna*A#G-`Q&$peQLb6=3U+!G!Y#Kj3+_KzGt!+B%V`6iSJ9gA;|E_8S8{`yF^RK# zLdC@AyoT{M|5+`mN9q1)oc6*4PC4-A!iG!R`*a%QGZVbWTxva4#<{X?0jU7#K8ZeT zC&M9i5dr6HBb+?Wp+DA{_52@Kk*@!`mQT3baCxBcfgt9Idr>s#ehEP?&#vKYMEpbL zIZy?%)YL3APU=|ASm4Btd;;@=H!8c6WG(UNez_U!+!-b=C;W~auUqUClsvUY*)B&; z7T2Z9vAd=5JO4sk(1gFI>+Dk1p|zB{v2cB6J8Fm-_TK|;V_@$7NsUmLd0v#!hmWN% zk1^2?iZ3c#Q`3W+6f2)JeO(AyS{}`Izc`6usW1Ww(2~S$B0mU z<4b#$Dt^r;d-I@w%E4j8@@Zq=y&vKht)6iIJRzfTG=gfAT+zqnkt>0_FHxA>otwvl zpLP5#P{>@O?<$`m``vy_h5v2KT!$cIhV`^AAWBi|aKP{XhU@0?*Mq7n$4h6ai7zGU zZWeA6duf*8=*S@FHV_k3-7o72&8HG@k19-mc*JFtQYj!B03d%c$OLyb+427X3?TR zYVd*YrjIPambUnFu5WV4rT{InFWH~_?^}E6!bBb3N&)fE62;OwU;V;(vEd0Eg#(-2 zd%#FS0D&aLAc$?6?O+2fqs+xWI*vLyl6_M}aUQ@TO%RyGX~ z!<&8*jWcxj0^_d$|IoBrzE>yFJ76?C$V}XN_4wu)oqK_pOAc6?ZXuNrFbMn?qlQh% zGoS9wt!O0spy1_#6s{s`TP%~kW=y+(Srgn(bWa&6a&u9g2!)ft^Q8@HINe%Lw%X78 z?2G<>my-pf3p!&$0Z@`yjy6!1xnXh>ES3V$Lkr#`?BC6&M@pt#E6?t*yo!0^i`b@< zKsLJ`sTX3$@4)M#M*8%)JAxgEV{o?usCRPJu=!HCaC3sa3{#XBMS-N;^lN5Yvf>0`ny2?tkIm zq|FD)5xd%Ds`Uw$P~0%9WQp*}w^E=_Fei|gV_EtVBFKksex7}A#M4y%pTF51$*77ds~6!!VQ0AF9}kXk&3ad`^bJUxUMAK}E%t#42b5h+Fjv>Is8ZJ@4~7 z+Qu9(%H(KjQ??&ne|w_O#)i?xMw!wVXJYEm!6DVc_T2SkO-K$=f1r3y;i}5&>iG5NKCBtZN{DiT(Lefy=2+%Nnc532-N5 zCIbQ72INO|a`*I2fq)MNz|a~K*q`7qWXokN3REx0+EcZCXwQ`|?IfXzV?ti@OwY?f zm(cqM;8u&)Qfb?Tn`czim;c^R6Meb78wTGH*xVk~0@BzSm`(~v2!J9|7aAwZ;zkG^ znT-y=s5eo*?k$Eu7>w?{bLX7>j_i{?3F0rZcHx877AgmP{QWj~km}Mh!^ob;`;x~b zvKKq1vcFxQhhxk5@xIl)Mbh$(n8S(NEMrk4GC9w3<}G?4cxaO%UueCJ9dZGkknp0} zMUijpXAz&9Jqp(jgOrvaqylENP5Uwv&KGZK$SxtH25BfZr_Z^#@wt@^)Vx1ZfP@mj z*u|PF_114*#VD^klKN_#`(pgR1adK(s@8WXdaJYy$>3_!@%fiNG+39_Pczb#>zYuu zVq75Ph`xYEF8ie`W57d{*O;)ClR))0m!q>heufk zs8`&Q#p6dy$9MHcTfdf90&*NS{}HKy-L|MRq?=c#>3p1974{urp1*kx%+Ge?U#$*$ z_xp=@yFo6+7$E+BxY-C-Nem2U^ z3;l-;#hh&g)W>0f+%B`Dg$=9~u&=Og7-y?XayGPVf3tGNv!nk`Qc%}ohYn$*Tp4Em zaONj@F70=FxygROP*Xg3nL@3GdKftqs8jylj>Hi30Q`3kd-Q?oVf9Ofdv)Jr|Idp8 zmz|~tfT+5uuhc7Ck|xr%-s}2g3=dbbM!tv8!yA zqX7Y<#$+G&;0LW#&pzcr4Oq+{$fiK>QjvSHn!2>REXxr$myZnr$9chhz@g2R_&vSf z^X(y*1**^t0N&srFH63Qc7bk6_Wwf~hVKXcK%Y6;2nbqyc72MVsD<4kD-x<#fW4|I zQb7~im4H=zN7Vvi6D2@NJVik`vU-!Ub|it}mZ+o}4{y%;$CqM#5(V+ExeC?#=}I*b z99zueF>c;-q0iT{v0#KF;K4Ki(CR$|biuD;-b5!GG)PTlV$-A!3xx1%o@Q$rHbr04h7{}aQ`(L`7rpxF~|M$x8gEa!{men z0dLXW7xBoOH5WuC29d&=5%0&a_bn+Y11QBkaV7n+QgDd${KN@=_flyX@r zzsudqrq*rMmv&>mi`}Rt(diBluFiJFs_Xgnp3_$n3UPIgM8sip8q0br#=H`D(F?%E zxne>q@&^(7BmfWxC35xBG_QHbjUUY4aU8&}R;celSrwEshzSxcY9ABM=p`7U+AW7@ z%`&9ZUY2JvyRd`7KeGl3D;^y2_Y3wnTY@fekhCRpEG9`p1^d&NG*TOX`8Zhm4MdDt zkJj$p7%9~^{dwg8piA+e^~Z`r&}e}!pI^cWvK@8B1yKp8`v9cc_HetoaVmLA?8{Rk zwcrV0TRPSQI~r=~gE6=8DF96CI_ky6q7U&D&F`$){S9#u`SVIy>RQF2eBeooNlVn* zi>$A-tQfy>jP-UqHZi-f4a4rwrt+NFpr9bop1s>pJV%OA*$Cq#>)#;m-ZxK4$c3Z( zHBpV&Cz{CTpU-CBrOn>sWIv8?(|N@0&R4g_i_%&;(UnzOA{NKLM_-TP;N=cD9Y!ad zy;Dm*|CaA6)^lg>xz0Lf%%wGAqz(~JPz^8n9$5Nc)mvl11nXzu8Z=Vu5;R+5BGCM^ zvAUOlPo_1e?UG>byp^`T-w42%e)yfgmLU0nGy#0xV(z2R%@r<;x2!O5Kry)iJyn#& zr%~E{*+I@zJtI=>n2plX?qgwgkAM!wzWhdrbf(BI?n(H(D!qRAA{usf3}y0X@bYBy z_k7UW{oxgl>Mip1`Yq-C1j)+6E5AWxGV$)Fjaz*|Dsj;2^IJKh32COE(#75HRbSrz zi8~qsaaX$EHV#a6T~8Lsx8EQ`QmG5?Ye0y|F&G>r=((oQAvi;7aha_BhMoQhBqZnWRD`q!}tlKc`qoDJtY*C z#@6}2Y4Sc|jRkY_tiU?FBUOo~+4jpEQ-}eZ7uKv#7eXEWn$qUeCZHxg!6s;gw$j!x zSXE$9+Z#_u^ts<27EBcn*mBPPEwq*!v zu~q`qw&gSia}j0F$j&Nc3M3HM6Gu1Cx@4XPPyc-RM+V$FC}CX{QUSyyaUKdBlhBNJ zYkEDVe$vBk;BrAwnj+loLMY&ugjMLffQ_jaAA9T)Hh1E@hAmasFh^gwdR$tLvsn|s( z%?WHxRIRBw0|^#UfRuosQ{9@G0%kA!n%9YW=2bcUqh!oV7XmasvgK|P(hin2=(#Ak z7evp<(@R$tvuF$q%fK6zLnP*Z)E7eemQF#arX?Z+%f}Hn=V!qW@qcKix;h3H-XuCC zkP!ylvWGeq%E9(899ZmmR72@wetOPnt3?Uqyqju(KWM){xI2SAGT=uRT@pFN^A8*V zXGV!*$d=<0Mo;0&B)O*=|D$Z{$}z#ad~c#qDGAEx6HZmI*$8Gzls8AC!$Uk^CRyg}Su+e~GoGJ$txGS#o<(apd_6MM@lLeN8G#uo*l^xV1p=Xhd z$j1?YWIFMUl0jfaTtLPi2qYv3@odOvhWqj3{`8wo4dxo`1+sF({llF>swxxbXz7qz zOz!|1Iw`=J!AF%0~b>PxM(+ z+0tl|2V*SuE}<}JEem>U6x2x>emA7Sx>zPgmAwf{BJ%%W}Wl$I-%& z+@i~~>0>d8CAtsz!uf*9$D&q20&3cJ>9GaK1NH)&JB&_~5d0mqCzI3;qB3Nh75!NH$WtiP%+a-mJF5S0r24^kcQVt4XG;@5FWEDmCAIKfr=jWaJj6( zt&{<{8ex*+(?L`L6+M!@9xQ?3Nd-E$WvPca!3gH*QxJ(stAWKXf@h*P#zaWOtxTM5 zf_KP)d$e!!J>r${`g{E^y>7ADs)X<`*H1EaUjf@RVwyR`zw&`NP^W_e2eawi%Xec_ zdjOH9!L3I{*IRRW`Bls?{UVct-~8HH6m zW#LB3blr_5Ok+qFsbkzpWqrua_r2h$+vmcCS>6Jed0G~JY|vS@m$Fb1xiCnDYTdGc zKyP%N4+=tglr1{*C3z0uU*g@p0VaQG5T%0$9j!sWHf~WZ#WHw_+X?)gC-2(Gktaer zTNsqTMC@Mr(mJ6()J?e=970rl#t>1y zR|=XcMi8Xlzx0zp?-%2TSNWr!jhKKz*bZxtlSxc# zfY&xYUHZHB^v01-uZK{`pP<&5$x#-a+Iz-Fw<1F@a6KVgp-+Ke$iRXtMg{m(vrlao z!#y~_qWlSen{I}$LJm`S_l@@k!}I z*|46p?cXMC4sm8P_E!gb44@Mj^Lw7c(|1ZC=j`6jvD;LjvjZQg}l=_ z5v8?hws$n+k8Mx!Cs$s@@7uv8;Z(Cru=o&^>vghbWrI|CTmBgEZzyN_;#4Hdg4@zi zs|h8#E(S|J(>#H`hi!wi=X@MaICmS`pYc5Xz@Ty0HLbr|4s~O$zK1%pe=cI*Lk&;aW zlMl4uMJ&BpM@?lzmmm4GyH5_fCgs`7rkil;w({Qp#ta+?5CH`kfd~Ox3T>hCn+?>@ z=z4)kGlOG7%Q(ounXATds#lY$lFqzLi!9rBjQL%lk=8MxLx;^X>)kDhRj)E(V)%G0 zFH{~N&gQ&oD@@3bWbjc%{N#_px8b1{K=IV-9Z%~pAcXz)$AL{*J5D|kFM1++{Kjk; z{=FUreN=^_pnGV3jNKuNovrd2-Krq zIP2R{>WX6Tth3%n!u>msp0qgym?U!3{}Y(hcn?*HjtEZvv3&s0Ic^_>2ghoZ!A#d^ zS-vjQqA+%Ssj~jGto7JhS`!TqiQblq861b{Eq9)kFqiINSpSUGshDhDToF z_#nVt?d4{6ELp}wtoG&S4?kliAPvt0%Y-JrWXPL#CBl&4%JNan^(6Ol$A|Fti3TT; z`8kfH8XY|)S-zQ+atO3$G^h|zVxOSX?Mic&!exeqnr!pj-)BJ#Ko0v}u#hJYib!sMEUmrOp#i|MQ9 z;%R(1W$3Pzgx9!2m9+5)@cd?310sitI85K>d}|UqDPgukgvGLc(HjIP?c$Gu3CcnWm0)O^aQk`!?RR15wTBvRVVcG~1F5#eV7$=#--a zt$v^%;nj|eLA%L#bc$@(zqIMt;?+T3jJND7*#r^5hcpW|rCKotf6-uEj4f+OEYxvT zoqn^PLlDfv+o8PhQhrmAnM)syW{jq>VeToYfXbq<89w`)ssD2I6!P3vM z06h&X^$zTMdwfpihVP-Qfcb-*M4>XN`}O`;oTII?Jjs29fs-L8_J7S5_NvXPabx<3 zB^oNnfLL`9rVu~SB(o7%g+Kefn3Z)g4nzjTBf|r`JAji;OKQ%3D;FS;4-qMB$QO)% zB2Wxu2B#wv4G;F0yjX)U#F?p7dJm7~GY=fI`Qik%j?vr0qL6l7?c|*n?Xa=(Q5M^Y zQ-kI0Jq-@c1VKU2QfrSTbDK}GKH>++el2J~4C*NyG>bqA^g(?IBuiaeGDKcIFK+`= zMq74?A+m;HK}$_6qzO^@PN@yO^${r-Kx_Px zYAiKD$y=Z7@$S(d#&6H2N^z{qp{aSt?#_p`S{*i5LLQ0Ap7s7MZGrtc=iURzjidDD zO)NeQ>X9wOeIvpI@bE)3gdOncjTlnGQ5ZHF!49Y2K_T4IE4=)WPh0d`^IA}#yjE+L zP^&ak!aLTGhNBXY0_qV_Oi@4xVnY&b(2r8*EYujZO>-CRBs2c(xsYe=J&NNg3a66Q zX6wmgE}3M~dJ}0p?g#viS%_wF%@VOd|I7iXP$yAi+AOC1)_5@ldbj3^A;3fWgeQ+{ z*yM;fIs`OfqGyG{`-3tt;ehFKp<;e902g-K&*>i{QCwhca<#2CPEjAzrHo5)d08J5 z9mU7o1rOM7*`~WEd(+Rx68NwmE+@z^aGpGu3MfE>f$#UQ2sKAu)4DrTE{J_i5dn}i z3Vc2ZJOS$A`{%`Hx5xlzmVWn^@tj^=cmQLAuv6VBxOkFZs_>L-Gvi7%2Gg+90z?Qn z{#KTB{9vKnf)BJ;;T0}(Oj}Z(YU}plSeKp=BnOP{8k(rCv}390$i}P zFkdYTs#QKRfGhwf0)Nffl0e?xo4a)CW~poMmZPpbD)^U8$R`DFh99NBzakz(KL&}c zkS_)w&$}ja|6!387tR_@Z7;m%($k<9xw*B}Zqj(g1OL`Mt;8FoL{YZZ8}mVCf+mMA zbWR}C2K(vW}`4Ux@qzMU^0WSexOSftUgcq7JGZ_hYMvX*LNRy zNF|!W0HZYd$j62k0G<_4&LEMX4ryBChQ#lYcnLMy))PKl*9Y$|Kgd(~(#NShabor< zT>p%)9ngErg49m`f_?G`6}OS}^kG}a70oCR5TN6W_h`)dW5lfSdkNW*07xWa&Lj?r zuH5)gLR=Y~hK=5Z0rgZdB`rYss?!yGd^k2|Urq@~Gl_ zK^UAAI_(L+Ky(6Q5YksTjR|6O({RT|d2r^Ei1o0wHJ3p9Oq>?5wq$bMpTEp_-AEs= z$?aqDwn=F0gTu6IE@(r^v2p~?2q7mZ6cztLR%Wa`yFQ#03VAUaitebH&D#W^2TTwg ztSVF?0(Ktm()Ota1BVAeo|9xtu%H4j*lh+~=nQh8+@Xb;T{;--??L&P#gJq|ZhRUl zRmlJvDXbyyDUhAK3Vz7{q4p2J)%HKThAfnB(PkbGBJ@xN?B^AUN-LZXu+tCbOe`j6 zD+~rS6U35Nt4GWOpEGSf!}+mF%l|Tz05CeOa15P@GxoiThad(Zi@;x^e`wgcVA;vi zm&U_YP%&)9l#cz~QWG`4luNU>e(J%nnh&7@)F2{Adttzyr0P&Ki)MfQM&|Pn zB68CWR$0jTXx#v;K|}LTH6)r4*6^Ehzt>cjdelHLQyy8JyMxb4nH>i8oykSy&US$^ zXeRyBx@=3g9lbiN(TvIzr8Q8FTLlU6$ka03mub;Wc|uWBpXy(>j4Kcy``PiZ`mlFV zCXA|%^(k>D^HSGkJ!Psq>z6uUoUE_ZNO@jxlG4T<6K zoUR<4NMExBioIyE%HWGcu9XHXyh;Tk!hgxd?PSh1HNQN7)=cw$#8 z`X279n2;5S?G(({2D}OdlqFP8OsMmnF+*P&3?NDtK%nmLx0ez&yN}&@O@s6gS%#;?#E_C!{np7Ts-JDgg?WY8TkccMPnN8AmIbh<#lHb~2Y|=d zr<^cTY+TG$jaEqkVFq`%N`%@s@Wgz5jZON z*~PuT2Mx>g8Y}qnb!G46G;J%<&E|X%lmrO zey^2Urb+VYVA{{dOFY#gLX?6s_!YD;h-+Y^(vEZ##pRGm z+AqgV_Vtx9e4gsSmKy2h-oO)dH`>{ThcZQJ&yLs-D0+o6JjH3?5*dHdn4+PyFMry*Da9fotZ= zH96_j`ixEkcf4But|suWgxqjlx)1UFs@O?!gd=p#Ovu!KeCSWT`(8kbLNknepC!I3 zadD{dgs`nu=q|VKLgu?k-{S;lm^pTlzblSrMBlY9=+pln4z*P`yi$$(48)o}#V1?G zH^!NVK0>sDLVFIwbJiT(nKyiBkeSm&gw_5Nh#wpzx1Z3n*w$;Fyt24vqynB<>^2T{ zzuMGy@UnJDT9+@RGbX<}%PA&DUESrhMX}hoE&u{3N%n~_M`wUGIx1e08I#1*Xke)& zLbssLJ}H&HS9!!WmNQ zb;wPsRWy$us_X9_dIl^f^v>gm5){3u?o!qi_!qQcFj7=bX?%6&ikBOBz&i)T@I+n5 z@=(yc!7E=81yW6Zbi_xDAp^v%}>_w216#7d47(&JZQraH) zq>oqA5;HuqsF*ngg{5Ot=(Bj=jNWSe{`#S!dUieQ@^J*Z7&2Ns<3lX2K3S3bO?jnsD@%&R)?g904WWj6Eo@ePrdZf@7GDw*(55t*tM1{rM+BkfvJqUPB>Uw+Jg>>a z+18L>I_1Ilt~dR#o);_ji^ch>gBtpDPu`N;j#!~2$&5uW0&LK3fEeJa3JnNO-!=$W8rM`0 zqD6BWMs?P~7Ky~^6(-RiTNe^!3gOlV6kCa=(;AnNC#pJ>ncApN@X}t*suEQQ{EG|c zz+uR-w#8&|Fjn82*AAQG=GTZGvCwm~^BJCQfDWLL%IokSvP=e(CY~mFrp^6AVGBm9 zUjLrs!)%>K0h7o1FJh*S9$vfATbwN6;$bOHMo%A@_0@A8JE4NI?>#&G!QA8%ykMrO z&;1x+-zWakyL=NA2JhO?Ya5eols6XIg9P{8VVuBl|$^;U`fv84H@C znD~Tax%-%YYeS$ia@BrQj{*QYs{%9**CQT)ySM~w5563SxM(?Pkn#dOU8ZQ)he7pM zG^6<>d*o_&dAE4A)SOew^>?1ljR$a0_H)oFsFoN5wV$XPY2y}hDve6!n8%($mZ@q| z=B0!&T9GT_0if4kxN@1Jfv6pf#*ymCjbBg3G$TkUnE~spChB6~RM)Hd7U`@!M;Ns{ zdmzk&T;`PjR{Vt&d85Fmu(K~Z!?;`k!|xJT@*drZR!I;89nm9lE##jS1pY9>*LYM) zd?p57x6+Hip8cQtXDUZlbOHP>ALV?7=wD9lqlGgj&G*tbP>4}}-a$eDJV5PItIb$% zB-&!tY`v}xm7ZavI6ZfF7A|%+xAYRIV&BnUQH}S94|((Qtyh}i(ld*UvDGGaGy}Vh zp%j*#fmP*CFv}|Kje+%yNA+=gS)Jl)aM!@0ShP#RNByv6-oTf|$QzXSnXckzxKKm9>Km$=HKudlry~LTz;AD0e792)qQ}LxNI^F*d^jpK?d{qLmOm5 zhuQyr;g^yx1iY3uL9X~BXXa;#+VE0to$daMw@(UrD(|L;yGCe6IYPps7@g9XlED+NTKj&LH__G_`g!o3ZtdK{}SD5WE|x zO;bQf@r;@@K51l56}B<(Vcn3x$r6$fzYT=tm1USx8=K-}d+6u-)jJB_!ejXrgB-iF zlj9=Tij$55ZBRHEZF<<|X=1Khvi@7Uzj7#jg?#>;Jh=L{BdAXg!N#H75Lr5$Wx$c` z)r@i8K6&I+t$VRDFRMK=B(Nk;JMag9K9*?~_0U5sbd!BIL#qj_6?EdKB7EFjVZ0&2 z;A5}QCF735B*L04TtIq;G(=lfa8s>CwDZXlgST;HOWercElc)LEz4+e*IzH@dyTXr z0VQ&YjhEwPm>zTNUWNiSzt#}!rlZ!6sYD#osf(j;6)kd#D?Wh#sDW}L@x^BDQBFz~WPiU*3Nb-l$8_fKBWQrH+2vHegJ+D~Q;^EO1 zZZz+*+;~nEJ&)M-*TvXZMc?rxHne za<4TL_PonPisrwS|4um?pNDq0T7GJ``eXcQOfk7`y$RUGEK!rk8K@YI!sNT)5R3Z< z{2ceJDza4%mI>04>f~&|FB?m~_-(-s1iw#OJ(ASE9O#F;#|I{yFkBP!Hr?D=TxG{p z5cG|FRA-D<>+|JSD)DM+udyyvV>c&+r|-S7Y0=j|*`=S+Dqt9OJT5H!oDuy{Zm84D zP^7QlYF=*>-PqgK{l5>|C7BFg4`}iYz{1{Hy2Xe0muXyK-Pu=b27yXdOWSip_%8Jf zY%;cMqyQ^HRRR93qw5^s6btrh#sv{`wKeg?ps-fG^8%0NkM|$9jUqIn8^krnk&1I+ zdtwUyLGEtA(L-w$dP54d)G27$-5mWqjwkN90DcDFr9Hm+v=2;&GE9W>+8w+$n1eY@zd0e@LHhg_0ZDHE`0h~1HuZ{`yZsyDVl z#-Mts`cEaa8oCP?>i-G`2c;zbH7rKbIxfYB35Wjk;U=K{?%rz?=k(a`t23;ukGsN< zy%T@}uH}}Y zv)7LGm>R z(Ad)d4IT*|DKIH0X$vJ@NrCu=cLJ@2GaSgbx#ND4=Y;yZE=2Li)!|v{58Gt!QhEXJ zW{3b>SC0O%K*21;jz#gSjXjDeKq>s2Oa~2MkUs4d4liQK9bQJqw?ZisL}kZavO8m} zKiRUd)lQ|G^Y5Iml3TI)($?R{{EvC~$=ZB*{BRmNyZ&UE#UDEkW72u3>M2X54vcg? zX=*ExIImReL!)^%(0@0$b2X*lXJ1xq<8Kr98a3mEjHxm%?^dR@7(9}2i4ar7Dz*Ba zYi|JQkwZq=%LM!fmWdHJ4?Z}=`7O6ub`>>{kdlCRecXxY%jP@*gaAi9!Ld9+zyvs1z6yu?9@Ox6!ISuCjc7 z<%v3ctkqG&v3vYOP*bL!x`SrcxC~yd*aZ#y%@ z(=X7ZS||xi>hMOx=v1ma?bboZzuMI*r6e`MOWT`%m{9h@=0gQ849JnLVXnm80NA*h zz+HId$#*Sd)hTi}&VcF2)+Y&J!6JDtSfRCNAMzbV=XtpVS^s->U0|Nph^x5U^4)KS zb9L*Q+Fs|Nk77?hLyEz%)W>T0=DlR^L|EVp$m^Yi8IxVMX?$i2&PlwaN%^9ws3=Ob zxC5DJiWyOj-6K%Z@7HnY^QFA?@alXdt0q?(N@w?a)S$gyqW9q=4R~3_EowQJx+1GH zDC_qZ+ujVF;E|fL{!MZep9BMNwgJZUQ>{}t1KR`QmP*6mJQ|Z~b8bi>rD$5v_(V@5v~AuquV722{o}|#c7;g3+-064JFy+z6wi7Xw~*z4*gP}wXJK$ zLCF**3GA`knDRlwqGs_SF&;dF*Q)j0m=WMuwC{1~$g#V4TNG}#sGHJd6_HML9)q;Wh0ER%#E}R)ImF<#8sH|RBtBr1< zp`7E`bWHBg7mGl6#SMM2_{hNh#syNwSQec+w&|n+9jQ-hbZPZu=aROlY)^5o`j+|> zwV1HnPR$BLf&A3w$)PwSYSLo?ZET@pso&=}q63dzl^oY8H)DxlZD#*t{5b{WufD2e zq^o?FWB{k@hP$ul&LF4(O%~d(EA4q-N2u50xE)1I*|}omH?8#djmv8hG5g9jVIkIL zx!KE+?RY!~wB+O3ZEo}$Y9%VxGk6;Qp#%{3IJ+I-SWUvKij3-8U9!Na)Njs)?g=Mj zEZo490%kx+$dfu@nZXtG$ZHL!T4$Q5ILj{%55~OOAcx4uF3AhH)Q0Ldue@!}k+{AnA8uctN%Z{g=C=u~DuQp7D>kfIPWRS)1Yt>h);^HI&}j1vjt{-W)i zu|h7m$S+^3JS|xFe<=wtZjbG)uo1K!Q@VmWN!3ky%_z>b{t5#QvjtsiU%Mc@3_j}5 z(e7-_{?6~xGK0{HQ7z_v?Fe@Pz0}SpNTV4XlIBwtoMz%BZcM-ezC{ok+EgpaAcbTD-=R&f4^RdJGY%D7y>i&{s6?dG`@Az!iA&pqTB3Wyf) zpPFUplRSVZQ4>&5LmAOW)H4MK1(@a0Q%}k&l)t(#yq-^Hitx`STgN+!+fPTy{~4Du z8CUPNp?^g_SU)|D*q=kRp#_IoH@FH8WjsclRYx*!kAA859{<>K7$9gtlw4AhZ*ZLL zI&i9hE(OOi6q6U*8*b7~*IB(=j9iWpryQEIyrgUP`?J6r4C!n**Qoq?8b8>(D$?hyD3;a60#Td2R;_7rZBy5I z`{u*UfRU*e>4~^802VD5EX;5BT_=nc@toj(d1gE;?eb!{%MOr#@=d{z5+SvkpivwO zW@$wAx?!hZOwMWDU?-mN_D_#K%y=TS29bl9s??FcjavuhO0Fg0mz^<-Ug2=&mqrk3 zZc6$g%;R^%i?gE+MRfSDG_Lvj_1huLzA_nU4jMRCq#9}K?J1#JnI_}&lhlM!rx&5- zY6~!er!xS1LXU$<9?j-pHjt|qtu<3t16n8^fjZl^n*lG%Zz&NcT?S4pvaBC9hhB+= z>iiSp(U9H-U;qJ(5kV?Ot}c0$31AYw_B2MQfrW-Nf|>+i4)BiuYQmb;KN5^6M%`_s zD}cT}&`qjRoM`QPWv|fdv+XG6DEd&$ zdg!a52{xy`kk>@3VY~UL<^9j^I1kL`1vjXSi|Z|6T>;fQ!EOPWdPxUBO$%toZDJY0 zB635f94%ZTL*!TId7B#rbQ6UxGR0XPlVy+S$4YA@o1-v=_{{zP1{#Jl=6X;wG9C?`G-an)WnCUa-q-Q0{m?Gx&UzC`4=q?J zt}?6J-Pg-pdfg*7hdV~h^r;G`67`8n9!oEpzi<|aIv}*hmxiIU(8y_I(6DN&eM)tc z7g)-2<}Ni2jPb2}wL8kB6&A(ppI-WsT`_SQgj;ahiad79#_p@zQJn>*y(50jk|z`l zP@~j|o9x;4yFJHJFI>{n4g|$wvP!po*4GeQIja^^S?9%H8pg(^okw|g z5sI_hR_l~t-_e_J`CKH{PQ2JWm3uAnuHo&FDwx`<%iy<>pdQz-VO%(`My7jZJ(roz zSiE4fGyx)r3E^zr9CUh>&1Y%9f!OJw}#cOHIK z>YiFssjIkX2SQ~(^I&#(0)`lz%p?f(V_C&(J*M+=tuuEDu&6+<03?B~Cm4qr7MV{< zPAUxEV%Db$sgT`Ur#_SfUD>jqpMQyq^}a@sF(F}~0tPiNJ*+%LB_eu{mBz6^>B%qs zc4QQPX63;w++XT`k}J`>{#)v;cf zJlG>-@-T{46IaltV!(ybaR086Gjfj7S$o3u4d=TS*guy3c<+k{7sfUUJO}3q)2zY? zO(I_XmM=u4R1;o+VdzC=)x@>l6-KM?Q_ilob>UAwqup*gT@i|80Q@R-*1?F)_f!-| zAJyvV?5!}h_3W%Ze_A?(b=*UdMFdq~DgAX>e@Aw?Hw%9fun09UsQo`@66?cL&<8CV z6*A*jhqe_QRxXzGd{}|7t3**H4P}?<>M0;=Cc+OC=I!BYF>+iQ**oRs`z9n>tWmbb ztgz<#ULi&OB}36g*cS@@nfyH9d*7(Y?7@5Ep*yQ&dI1@R5!cQ|L!`gp4 z=80YSFu^FYe8w;ZcCmmPXr?zMonp|65(C$M;O1Dsa^nUX+5UEk?PB#MUCm+3x|3p* z%dBB3H9e_@?z8&tIEXu)Jb>%H`CJ)`9JI6qC|Ob*!4dV#uL`^~|CH7jLu*!=;fgYRq3YkL(SE&6D!Mv; zljc661$O9c)`7H66%wr;DEA<*w=5=_zgBoqI}N9^@iDv2 z2n2w=X8J;?7&#(j480`CC;)6Rvh_*xgWuSPCcYPUO5N&oq_F7N=BAjC!#ox>U4%@P z8(o<2bEac&b<|!%?Gv-N4(T7923BnuGhnr21Z8xF(jr+0w)A(T=-vWC8meIiFcB=X z-5J{wTcgWAH2q<8%%2lh>S@ zAl}kaf$ADbb_U!a7|f#jP3|cy^O@Gsj6jIwqcasQ&%MnLd1Ra?NW$&227AMwD2WN8 zOl?Q$U_JDPHA!ZQl<1-HsnJ+Vr#}dY0t!x0z#(3ws{;ebjdyx`W z!#u>1yhk>NZ-uF4%_Qe!YXR~m>#{9xBWz^0GU|+fq);xbCRpnFc9mzF>S18~0g47( zEgP@7Mn0i0KuaW|+Mvh%1O=_oO`L4ek^%pkON)bCHnbXG9P8<(FEz~6K;#visLAIe z|B7((6E5n|$RvD==MV0{X=P-gHTn)oK{A(#9_)7=bm4&QZ3im2(@N@wHxCaqvS+AJ z3SB=!A%JU#O!M4H^3brAu%X9GK<=&(BsBaU0QuuA0(ekbwGdKPUzx^ZZVf<@3_3;p=^-ac>o)iH+>1?Vb9w1$}eUKG%xaoKQMIB3-rc-91X% z85G&;cXaW3$)lfeH44*64j7?|L+)yFxhuz_WMjwc)(GsG>1rgP7iT4JvSl#MyCPni z*WpgJhpbD6eVpMv8BTQeN4TTN%_~2)Tm}eWlDicM(jzHi|HWIZeg}UuJ&r-Sr9kql zm#Uz7B1%A6!l?Nzio8N=SSvn4#$=lYvM@6%kJPzl^4Pq}mNQ}3!Sw1d6*athDy9{I zBe+Q~!Li#+&-Z9#z$&yPdEt<5_{44y*S#-JS0FXE?&zQEm@jXYfBLvJvbiTnnt-Z! zM1&8`Y_J7XiWEIMg&OHbi!)l|V;j~!wOn$$isxBtKXl(6d1unH;{p!3V4JB53{217 ztSXEtU!2B(5_56|)vEWk$&J2Ykw~e1e!>8wymn9?%pXup{HH%#hC=^$ z{IX7Op+hM7TaukDWPgH54Pv(g?xREVNqwY+beg#*8gh~LP2or@eO%8G9g38al!e;T zx=UK)S!42Mi4QrRxm&xnK#L4kQET(37I{yhS#-N;V%pj2;58K^n32$~+uLQ)$fifx zgO}5b_;BY`DH{|J^RqR?o&B{#GZp%83i_u&7KZO2gjnZ-mGHZu+>-8Gxk@dj&|4Vc zonkhCS!&%}hJRE>>VJMHk$9@(sk%<CGVq^<`n0Kn;B3j-l)ri1L}ra1oTukh~~ zJ3QWt(x|#Ka0fp8c{nk?6pE&yRc7u}=sf9xeC-gs!qs87nA9$O_DC~zPf_<2TRm8> zRzaJ=>Ht#tHv{a4s@LwE`o7T3d2uhY=II6|PjLO3ZKJ-S5mHvq!k!7gZ<3*WS2!yd#@ z1Y@4mQAt{TZNB2cnKJRC&Q`#)dzx_&7c1e6ls1S*X?SNHZ7XI6iUOXA!~#A!pj5-U z6_&!oXJ0HzG7vAvsDNWBCX$JnucgF=Y_8noR7w=~MNE<>)#ImPx^j`3feiV;07rZ(#*nSw_a#OTfpm0%T?v^w<{ z^>?!5o>ad%zHH1bgaP6x9oHjARQ?%pz>=&SUodK-m_loddl(|bY&x*)xe!E3tL-7Hd+;k?kM?2bTmnM#=c( zHB97V$eX6v3;7g1F)O#M^U;dA`rO8LWw82uK8sT%yLnGW;45POtvrba9V(q}|0kU? z1Xxs~Y$TpXnLtrOO}y-;&v9LaJis72%W~_(~_K<^@$pnazBcWxN z+P%~cGMzZ$B}7d*m3KgS3#y7kQ_4GJ1H9Go(`v&RWQQZ1rzTF|wSm_pl(L7BsbnUK zhelH0&wrqtW4aqn0srX<)!DbDsI7YWP3De_Lna7zEf-%&GwclYPoQS5Kb779`3PF4 zPafG4@=ej~q=9uzvlzf0@P~&kl=0J55C~xOw80*-8TS^_qOX8?b{RtW59sO_@+*Y( z!hf%DQ!Qzvy}Ct2!Ig?-{=)kH^H3ngVs{SAO_Hq%X;tJ!$MGPvHQ9Sqr7Zo;ggrU)@VNZK8IL%*LtOIbrC3cNNki9@4|>lStay zExLwq=s1XF+ozH7d#Xy=Y&^Fj^s3;Ze(`OzxCyACDh!ZNwE14(5`)iH2V$=LHvOzQ z_X``KSRujgXT(}I+0??bgD?$J8!t{+q79y@gw3m}t8cjy;?QnotgjFcRHi1cCkuY@ zHx-Z_hSk+N4)3Vi{(kktU_MA2q-#wH$#u%>kAudXD(7|s{h`Q4{gy$tS#QexA@cBI z8mEA@{%|UJsV8Jvf1i-bhIrTc5?fHS^rtm9fmF^AITA(lfz`)wm`E zasu7=PUhH}BIrq|=Ak2<0nl5gMo}lnS27dm!8R+~X61Eqfsj6Qc^#ix>BKDJiq_9m z`i!;a78grVHhtEoOw=$X7=enYkqzy_gp8{U zabvey@*et8^U>&v4Vh(DCKmUBV4`+(%7e{J2|!`lm#Fy}=tq*ciu;H`p`E+=2?^4; zA2b>d+VsnR0MG4UV8fE$WrDF3%>`q7ScKj`uTy#g{Q#X8tfQilE<%xEG6j`iHF(y! zZSey`jkK!H90gCr-E_5sONHgVz&O5KD1L3}2YAJn4yA&%S*lVnIutQX zmkJguFq??bg68P;;PZxuqdmwkr$P?GmdjI3utqW$60i z1`gvHU)8V`<(f&liyC7NmNHjR>CGWpg1n0ZZUN}om`KsGEs9}{{gJKSxT2W4=EKjy z3T;3pzUQAAmI5C1>$kC}Dg$=7tB9r;&}gUtdfBEOSx2Vn=B9f^W^1qU8ii@-Tin)) z$lGY>PFLhZqfW2U8|Y~Id~P?&cNZmg($2RCO!YIy-nB37U^crk37%>cR-g@A!u)XKpgkvsSH4XMYR)uR;FdMUE_Rs*(4p_BRGX`&pfI(g4@;>O^~CV^YFOODs+)q@mFGu`Hr} ziV^CIZXGtMz?Oj@vG_c>pm+K!xFE~1Z-xW83(O(}XH6Bu2^m5f2K^g{-b7dJhTy$` z5m}36CvQO?6moz%))ZWmimf;*VYH9El7=ED%AIlaokP;b(DoizDCPcZ{F}7i#YOXF z3gLtM5}GwRX%$i>0>&RwE_I{C(kCY`7v;#jmBX}Q%^5WtRL4o!6ptFvvB|~&$k+RG zNn)hw`vfolV+5FJRI~ywpa!7!%>o8KOiA{<76^NlJIC6v@1|i+rtv;BD+rZCO*v{Gi&W~`?W9SP z)*x4ebA@fGhN4e9RWAgC|{$hZd=SzY@i)9Y+3hEW#@T47C9O(d2^p7*}RA>3^!9r zIFJ3$xvc|6`twh9*n;CemE00y#vDZyPPAUY-h2s#z>0lzWY!B`L`8_3v3?Zb9Jo>t z31xY}zPrg_KO45jj*cnC-W%h1!&Ec~5i|%AWr6KdiKk3~oV?*lCi= zR}fb2F%WQSmo^GKOXz|fO#lm1viMxp42U+0Xbk3>_WuL+di{^z2Oug zeVw;T;aeA2;?;JZFb|0n5G#7ob;u+s=2tA$?Dkgls|{Cd1T)kce!7;Z8LIJ|5f*Y~ znq(NP;>VbZcAh1^a^lV|@ME=&oB;SG&GY;vy~=1D6Q0|S(vGqyiAiUqpRMM(e;;i_ zY?0*$iF}$ojec&>#Y_C>i^`-9g750|sVaeLiG^PRdvt-1P$cN|=S1SnE-dC^q5lhO zK54mm@~01ZyKzgwC|ntYjV4LpPtAx{xL9RZ`Wd$RvL)&dMyg{0?6K$3l%!ei_!69r zG1^{Ha1mBm)8=(@?H5>?m&Zw10ac>F8Tb^?*&&D}*ft3IlGh-62BD?rOB8GTEH0O+ z_t)v0k5t2y9lw^2?d?0m4ON-b=AR)12MyE=qfIsS0NnN85qJqlymR6K$$*b=s9LW> zgzEW_5JzkD?e`*F9U!^8pY@wqt|K|v7*JX}tEmm)pd{?9yx zN2wXe=xOBqx;h@;gcXEx(@i*VSjERqJuEQR z8n8%_h>i_~4(`exsQX9-Xx7y$SNeR&6Q3`&^0I10)iPG8Xcz*xsi&oF$UzCqEu4O` z8j9mQ2IO*dKB=t~^yAMoT2?d4eylb_g#{jtEgQ2+?Un1tpi~&5!wy&Wl#jxZM#P1- z6r+_lVGN?8%M4Hf2~=JAea6bqqa+KK){;-MWF7Hh(gN3{0#<3+AHa46>z~1u!`%}2mQvbMH}3?Bp+A1)IdVfF zwbh2dS%1@DGi||lru+x7}1NC z1rmdxsXrz$VTb{b=Cvn2-UC%hHHJEBuH%Nj>VZST7*yO8V!_kq@)8ORP22ie2B6G0 z4FWyccTBzvW(ldL#`e~J(JXgmbe!?vk#vL3vt*U0uUwt3fG;t=j5PBH(QmK#cG8@; zUU4-N4;SBRWoGLicdC9n+_E$$yo$IFhK*NmuL6Zx7OrZI$G36g`W~HKU%t7}VX6dB z@+;FLl~T)%&Yrn!(8XjODO}~n95m$s26&5njoViZq~a*1AtqAv9&yH8{)xhx|uaBiNe6byAf*A4mtz+nQ zf#Ouui$}Ns;53?Bg9`177#iW33iwOT&TkGIeJm` z`iR1Nyq^Ejc4yxlHOD=x6rYddAv>CUf4nuFrSDwjt*c|4AT_Fqvu>bS!eSqSM_5HI z8rsJ+%1wL6q6S81WhC$;wrS=lT#QB`rjrCamVGl6g5mAG{e2B>_X+yh?UQEA0NfA{ zq;ciRlcJ*OT*$*j#yIm3D)zgHZhzBVPMH42?RmpyP4*o|jx-5~WN0C9-O+W}zDc15 zMsS{&Uet^fS6HIA#9da3hY`u<3BQUt1;fqhc67PPs9ovZ>F8>M)tN*jJQO0mEo$nu zv`Wsbv76RX-IPTtty{vZ^Dd?_XTdfK02@x?^|0w- z8}1F$74ry9XUwOqleM0og3Jm?ZtFNLTM3)+h>|Xwi2+ zQ2*{e=AxRdQL%_f^xF=5(VYl(L1e=~AI|Q8)G=s6it+)f4w%s(%*;z9*S2lJD;)dS z+Z`xsP0=kl`L#w&i0|4*{=@(lm|dWHNavWhEgJb^<%H(2Mg$4E6L(wIwCAzmQquh) zG_`vI#W{GGCR~D+Y@_6LIsu*-@sE<95LHM|Fdwn>@F7pEgJ@Dsz}}0;AU& z!xb|O*H%(gr7TKQG-?OlI7*4L&4ShVAkQf?TE8bOxdKYIZb{-*oOavDGP^9HO5)3-& z54$f7_6YPmya}J&89qwg!5;5SMx|dZ9Dl zGVkQ3qd7*=?G^oMDyirCbLkrf2MH->KyBuEW*9zT`@(Q+ga8UB9c&;6a#?0KJ-F~9 z{yP8%XE69n@9b;dzKqcn)fQXSEZN=K=6r=I7Nn(%+HeM0Gud`*$m2b{f>Jn( z#1oFMOI9EYVdjO-q{Ytl$j2B|oSn%uTf^eWozDT=L8&4*VgB**)h?H^Yn?cSYX;{}*9 zMMHBGB~%I$Z1!$rHrl#rU(3NCqLGt}%?1UEmBq_qmkBj-nm8$&_?cmetfw-9;Hp;Hqa|b1GI#BIcEN#EUp;dgQ$2 zbo*i;J2A*5I^_JP2M)D1ZD8DzUsB7oft1ZMTH~8Wl`L@~I}7*8u3n~riNJ8+%FjoI zpg$)a@+W1kpGdL~Ha_!lJC5Rhn`K)K3jJ#oQyau#Bw-JR>`m3tXqBIHNeh&X@oRJn z+@eUU{26St{d4cBIek)g@(t+ZH#KStUUI=^*&M0z3CXgdvh=Adkf!IXUGw)TwV8*+ zt*iKL^eu1W?WWY6ITbW6%!C_jZ4mlc3N2!CbmLAyS2Hc&v4dJ;#o>`ve!cy*RWjE} zycBqoXotiFv*a2Qmc>pO&0WLWp}>`~S^F zLB;^Dl9?if_0>VjXd#e+-;jN^dso=37MdO**u(C=zE)#e>srCXJmF463H%@aE&^f$ zEei(7v#74p5ou3HfVuDp_31uh#Ufm-wCrN`7zM|R%CvKmKZ^OdGl3Mb19OQdF+;sc zgy*bkT}?+oP+1YW-`cv}O?I_BPmj(%j?rX0aw{{Nio|jVomnsFkBZ>1;Ft?4C{kvO z54nHqjHjJmi_DF+1pO>lKJb8<%lsX3!2V~O7iL~N8UW2Mc|L7^^@|6NXgZ7)JgTYo zlpiV?kyO@V%#S8iX2LJoQ^6ufoeO}ZULy|UYGvX=^(MwkHYtE; zie)Lo#P$$Usa!^zUWrUtR%ifv`)#0-wo-}$HCwE@mv3SY>TlGKRo1Cu8_x9Uvy&h| zkZ}c6zTB7~PJfU>hSm!q{G2P!!(`>Wm%a=B1R7zMF)ha8(@EYsGb@M)h{1b28l>cT zB?b#(9T&TIM}O^zC_gwL(aWLg37TdS4K=rkge}HRqrkl$Gq<;4_i&XD5vCP*fB^Eo zuH9`nd0nBo+87iw&f@n!pXj*DV{tY^ z_yEo2m5Xf?n}dZ3Og(Z))R$-J&3vZcnNKv|5smrwcnz9tze(#WpLd?((4vdV)}w{Q z3yHUmq0>$yrIll32jZvvv&tgknalaw`G}xsn2P95nxH)=-J}j*T-f-4>Wc|m5B)lS zzLaq(vB@r<2NS!Zi-qJCY~o1Et-NtCuTyillv9lq8yo}k#knp8L-Zl`(Q8e&E9U-D z)tZin=b!tP6S|?k-n!mcGt)b&RJ^gepjK^}8}fDd=A@gJ-}abSwIp<5$REC=&u*07 zdtnp1rSXjO-eq|qKXoJ>uq-P$srDlYRv;T$0vVt96;z1io`yqbap_BByf=!>TM(${ zHos``9co6_51>k^$Iqf(2>}X`l~3XvYG4xtF#cU@$5n8*?D2LR%hK@DOymXQT58q1 z8kiIPkG8XzTMdm`cL~JXX(2WFc5Av~w}h6A!#l>ll>x$rB?{mGosDC>(IP!Xwq-eH6(p`~ znlFDTnWB(c53L|2K%3C4dTyKi3}@>XdiYQ#AnE@#?r9k6v$v|cDp1?p=Wh<=0~Ye{ zjpsuLyQd?OT-N)*>vy~Ii-nyit_@gBMaQ;sV2cAc z@OxBwiXY&~_krwFwlpW}-tw#l`Ek7e&E1^mi4Xi^1K?dXR3D|)G>_~M;geW=c>?TWqLR67ElK#cRQ#&c&>Ku)#i#F!#w)egu(!w5)oMl5r+t{h6B2^L&kMm`*D<#U?S zi%2g*zm&7T`!kq~0U7H%@d80-60Ch=&;7?Skt*t*yiou=l0h)7?a7kvkW}zBN2GgM zq&IRruJ%bvo@&Y8;T>cVFOm@C7(G8P7je{L;@&sN54pti-g?!l@duJIPM*U70#Ntc zB!R5L*FC?!%r?ouLvVpvF4*IMvZEJIh5rSVF!`4Sc110ZTdR2#eCj2~Op^;L zxw%?%3PGih*-qWQWgcJS71}~~XA)AvRjNkT#WAF$3|G~mzXEl01`hxX+>JQEG`3>r z9lOq)a&|jRO6^F+g+lL%GYW>uGAcUCe05gdZ-qD!*_Bp3!mcC)s-Z)s{vnw@inAjP z6szqnCNSsRPKz`JVxTWd=>An`vm&Vwua3MUE(3g|f{gOQdHiv{bpRC;qFdNe$)%!cQ_W3zNo9&@5igZvRa7sl#rv5e z_`-5?$vWw=?Tq6z{am_xD#c{h5)lA9`c^%-jB*sK zT67HcGl-JU;1|l~CKbT{jkj0IwRXT-T04OIN8?i!vd&N3SyEU6Q0?t5>D|A#0a4;vbh1*_1J=g$w z&X9F{8w!Ua9p7V>AO_IS+R;gza|gCq3H7R@ z_yXEj2`7TBf-iXe+ssy&Jmn7Y#18Gu;!vcNgoxl2$RXoea6;`8lQ=n-Qv?-0Rs|2^ zQ=)5=q!m4~&FEUg?^_-Ds^WQ6F>uScexDBshr(Lh-C3Odpcu>!vFKq7o>7(sI4s*N7Geh9iY zhTB*5wQH$zRlG~1D6X>y2xT|0X}Y`j>!~>J90)?}AfE36F*p040NcIy_75PHcS59m zmbxy2$7@A2;+`gA8L5N`^w{h81@yUqKKEGj3LbM<5Btl(!eoj+cGqdu)Ho(!P|rKk z+XZBRE^jvtbhx(AOGJ=KN)ZPTBleY}m>)3~iKs6(P-b!n(o zyPVB&V@v}FPqXoHh@eDV?5SqC0D}Cz05F2v;>He)N3Wg(;FOh>ydjT|@*m-P+&ZUHQ^Kpp`H!Z=vk z0a8jm>RNN9;(ZJYVYK*MXKm2{(!g3Cra{Ynar<-tT_XW$^au9#Q%4r^ z>4){wIvY8-Sb~}390}QYbqD}QrsU;=TnZ3C*oX!1GcoC_yhD}p@YTxA5#-9?9_2LB z&=CWKW&B^U>9EWQa9`NIoZjI*i)nM9knQN*k(`#WW8w}b{t-jO9k|fQ>s1lu}DuX@w5pZxDLeul+JAU^2JLh%4VWk}@hCIng$I4GU*O#PhSn<4h}4`$^yFBcMuii)CVFfi27 zw$Y!?rHoIGk6Xq}<}nJ-z4z^+!f1N0oFAtw1n&x-v<;7?}0$f%z*pdQj{4=rUo z1aF!_%+~p!^CAQGRe6ooi+!!(6uC%?n}2H8dfkkE5r(etU}(WMJEUN6o;0-&_GNrq z3QJIN{6A)jLqo;yF6lXLV9H<}HB6KK&8>WKL*^FFWZSolRd$$4P`T8yBLP6L!?U+1 zc^@^#gzt)_MOIPzlo2-$uS2`fL_B-U!J*S-f8=x|xxOj8ij_FsI5* zSB^sU-K}pW6y9ch1`mdJ0b8Ss@ESoa%9Ip90W<@5AiFppw}qvX^yb@2^y+7(eea5z z@2Hlin!q0>;mk!;lN#nbrmZV$l^~zZQrK37t!eMHaY9=8T)W_`&+dD@xDYSF5jQL;uplmC*L zzH=pp0s*vV9}le7u7;6C!sHR+>wT}Nsw9XWKR1Wq+(N?H!qV^|xHdR(lh+SznjtJR z$TD@G_v?BIIu~@*dLB!}J>k+1E0+`C=X<%i{uH$|0;?IBvlL$w(v5yC8tme9m)G6X zt_eVErPfNSw&~lhfxSk@d=nnqgcoE5sUMSr=Yp9TKPNqd+FWQ6I2+cDXMZb7g?LvC zEp$Eom1-)dS`p!aiVgo#O0@R z&Mep1_;c!lfgZi`z5XTqK>z>@|B%7R7z5xBz?0N3ypmOdb)=jVVMvHm5@1g?o-K<5 j2!^xij=fBMKhMRYPy#B8Q{}Zg|Ha&qP81{{t54Q|)AB3| From 0d6db291de4d2427b6fa0c8624a7001dfd449d93 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Fri, 17 Jan 2025 12:30:00 -0500 Subject: [PATCH 0053/1218] TUNIC: Reorder options (#4491) * Reorder options * Also make ability shuffling on by default --- worlds/tunic/options.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index 9a04a137b044..14bf5d8a18a4 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -29,7 +29,7 @@ class KeysBehindBosses(Toggle): display_name = "Keys Behind Bosses" -class AbilityShuffling(Toggle): +class AbilityShuffling(DefaultOnToggle): """ Locks the usage of Prayer, Holy Cross*, and the Icebolt combo until the relevant pages of the manual have been found. If playing Hexagon Quest, abilities are instead randomly unlocked after obtaining 25%, 50%, and 75% of the required Hexagon goal amount. @@ -290,30 +290,37 @@ class LogicRules(Choice): @dataclass class TunicOptions(PerGameCommonOptions): start_inventory_from_pool: StartInventoryPool + sword_progression: SwordProgression start_with_sword: StartWithSword keys_behind_bosses: KeysBehindBosses ability_shuffling: AbilityShuffling - shuffle_ladders: ShuffleLadders - entrance_rando: EntranceRando - fixed_shop: FixedShop fool_traps: FoolTraps + laurels_location: LaurelsLocation + hexagon_quest: HexagonQuest hexagon_goal: HexagonGoal extra_hexagon_percentage: ExtraHexagonPercentage - laurels_location: LaurelsLocation + + shuffle_ladders: ShuffleLadders + grass_randomizer: GrassRandomizer + local_fill: LocalFill + + entrance_rando: EntranceRando + fixed_shop: FixedShop + combat_logic: CombatLogic lanternless: Lanternless maskless: Maskless - grass_randomizer: GrassRandomizer - local_fill: LocalFill laurels_zips: LaurelsZips ice_grappling: IceGrappling ladder_storage: LadderStorage ladder_storage_without_items: LadderStorageWithoutItems + plando_connections: TunicPlandoConnections + logic_rules: LogicRules - + tunic_option_groups = [ OptionGroup("Logic Options", [ From 9507300939415f49f1463223c3c0812e16fadbf2 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 17 Jan 2025 18:53:29 +0100 Subject: [PATCH 0054/1218] SoE: update to v050 (#4497) * Cuts some cutscenes * Adds meta data for tracker to detect settings --- worlds/soe/options.py | 2 +- worlds/soe/requirements.txt | 74 ++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/worlds/soe/options.py b/worlds/soe/options.py index 5ecd0f9e6666..9e0798e1a6b6 100644 --- a/worlds/soe/options.py +++ b/worlds/soe/options.py @@ -309,7 +309,7 @@ def trap_chances(self) -> Iterator[TrapChance]: @property def flags(self) -> str: - flags = '' + flags = 'AGBo' # configures auto-tracker to AP's fill for field in fields(self): option = getattr(self, field.name) if isinstance(option, (EvermizerFlag, EvermizerFlags)): diff --git a/worlds/soe/requirements.txt b/worlds/soe/requirements.txt index 7d1bae0d6a7b..6a569e83a142 100644 --- a/worlds/soe/requirements.txt +++ b/worlds/soe/requirements.txt @@ -1,37 +1,37 @@ -pyevermizer==0.48.1 \ - --hash=sha256:db85cb4760abfde9d4b566d4613f2eddb8c2ff6f1c202ca0c2c5800bd62c9507 \ - --hash=sha256:1c67d0dff0a42b9a037cdb138c0c7b2c776d8d7425830e7fd32f7ebf8f35ac00 \ - --hash=sha256:d417f5b0407b063496aca43a65389e3308b6d0933c1d7907f7ecc8a00057903b \ - --hash=sha256:abf6560204128783239c8f0fb15059a7c2ff453812f85fb8567766706b7839cc \ - --hash=sha256:39e0cba1de1bc108c5b770ebe0fcbf3f6cb05575daf6bebe78c831c74848d101 \ - --hash=sha256:a16054ce0d904749ef27ede375c0ca8f420831e28c4e84c67361e8181207f00d \ - --hash=sha256:e6de509e4943bcde3e207a3640cad8efe3d8183740b63dc3cdbf5013db0f618b \ - --hash=sha256:e9269cf1290ab2967eaac0bc24e658336fb0e1f6612efce8d7ef0e76c1c26200 \ - --hash=sha256:f69e244229a110183d36b6a43ca557e716016d17e11265dca4070b8857afdb8d \ - --hash=sha256:118d059b8ccd246dafb0a51d0aa8e4543c172f9665378983b9f43c680487732e \ - --hash=sha256:185210c68b16351b3add4896ecfc26fe3867dadee9022f6a256e13093cca4a3b \ - --hash=sha256:10e281612c38bbec11d35f5c09f5a5174fb884cc60e6f16b6790d854e4346678 \ - --hash=sha256:9fc7d7e986243a96e96c1c05a386eb5d2ae4faef1ba810ab7e9e63dd83e86c2b \ - --hash=sha256:c26eafc2230dca9e91aaf925a346532586d0f448456437ea4ce5054e15653fd8 \ - --hash=sha256:8f96ffc5cfbe17b5c08818052be6f96906a1c9d3911e7bc4fbefee9b9ffa8f15 \ - --hash=sha256:e40948cbcaab27aa4febb58054752f83357e81f4a6f088da22a71c4ec9aa7ef2 \ - --hash=sha256:d59369cafa5df0fd2ce5cd5656c926e2fc0226a5a67a003d95497d56a0728dd3 \ - --hash=sha256:345a25675d92aada5d94bc3f3d3e2946efd940a7228628bf8c05d2853ddda86d \ - --hash=sha256:c0aa5054178c5e9900bfcf393c2bffdc69921d165521a3e9e5271528b01ef442 \ - --hash=sha256:719d417fc21778d5036c9d25b7ce55582ab6f49da63ab93ec17d75ea6042364c \ - --hash=sha256:28e220939850cfd8da16743365b28fa36d5bfc1dc58564789ae415e014ebc354 \ - --hash=sha256:770e582000abf64dc7f0c62672e4a1f64729bb20695664c59e29d238398cb865 \ - --hash=sha256:61d451b6f7d76fd435a5e9d2df111533e6e43da397a457f310151917318bd175 \ - --hash=sha256:1c8b596e246bb8437c7fc6c9bb8d9c2c70bd9942f09b06ada02d2fabe596fa0b \ - --hash=sha256:617f3eb0938e71a07b16477529f97fdf64487875462eb2edba6c9820b9686c0a \ - --hash=sha256:98d655a256040a3ae6305145a9692a5483ddcfb9b9bbdb78d43f5e93e002a3ae \ - --hash=sha256:d565bde7b1eb873badeedc2c9f327b4e226702b571aab2019778d46aa4509572 \ - --hash=sha256:e04b89d6edf6ffdbf5c725b0cbf7375c87003378da80e6666818a2b6d59d3fc9 \ - --hash=sha256:cc35e72f2a9e438786451f54532ce663ca63aedc3b4a43532f4ee97b45a71ed1 \ - --hash=sha256:2e4640a975bf324e75f15edd6450e63db8228e2046b893bbdc47d896d5aec890 \ - --hash=sha256:752716024255f13f96e40877b932694a517100a382a13f76c0bed3116b77f6d6 \ - --hash=sha256:d36518349132cf2f3f4e5a6b0294db0b40f395daa620b0938227c2c8f5b1213e \ - --hash=sha256:b5bca6e7fe5dcccd1e8757db4fb20d4bd998ed2b0f4b9ed26f7407c0a9b48d9f \ - --hash=sha256:4663b727d2637ce7713e3db7b68828ca7dc6f03482f4763a055156f3fd16e026 \ - --hash=sha256:7732bec7ffb29337418e62f15dc924e229faf09c55b079ad3f46f47eedc10c0d \ - --hash=sha256:b83a7a4df24800f82844f6acc6d43cd4673de0c24c9041ab56e57f518defa5a1 \ +pyevermizer==0.50.1 \ + --hash=sha256:4d1f43d5f8016e7bfcb5cd80b447a4f278b60b1b250a6153e66150230bf280e8 \ + --hash=sha256:06af4f66ae1f21932a936bf741a0547bbb8ff92eea8fb8efece6bc1760a8a999 \ + --hash=sha256:1ddbc36860704385a767d24364eac6504acc74f185c98b50cf52219c6e0148c6 \ + --hash=sha256:61f0adc4f615867e51bfcd7d7c90f19779a61391a995c721e7393005e8413950 \ + --hash=sha256:d84761ee03ebdaf011befe01638db1fff128b1c37405088868f0025e064977f3 \ + --hash=sha256:0433507dd8ad96375f3b64534faefdf9d325b69a19e108db1414fc75d6e72160 \ + --hash=sha256:e8857f719da9eaaa54f564886ff1b36cb89b8ccf08aa6ccca2d5d3c41da0b067 \ + --hash=sha256:40e76a30968b1fce3d727b47b2693d4151a9ad29b053a33bf06cde8fa63c3d15 \ + --hash=sha256:09ced5349a183656c1f8dcb85e41bdd496d1c5f2bb8f712d12a055d6efa7b917 \ + --hash=sha256:162806e7b0156e25612e60d25af68772cf553b3352a5cf31866d838295ccb591 \ + --hash=sha256:79750965bc63ffa351c167672b51c32f2a8d3242e07e769f925d1f306564a18d \ + --hash=sha256:b1875eb79c8800352f30180db296036d8b512082d6609e2368aa7032c1cf7e27 \ + --hash=sha256:7989e6f06c1ea38687a6b14416b179f459282ea81edbb86086d426fe0d63bf7a \ + --hash=sha256:8a4c5c62997e7378457624a88c12b27b52d345b365c3cfae7fee77ee46eb7cd0 \ + --hash=sha256:a22557f56ada1ace61b781e731e06466c22b6cc605c1aa9dec10e3697b10f5e6 \ + --hash=sha256:d1057e70be839e9c3a91f0f173bc795fc0014cf560767d699cc26eba5f5cfc6f \ + --hash=sha256:8540bd8e8ec49422b494beece1f6bf4cca61aa452a4c0f85c3a8b77283b24753 \ + --hash=sha256:569b98352fc6e1fae85a8c2ee3f2e61276762bc158ac5b7e07a476ee0f9e2617 \ + --hash=sha256:1b21eed21eb9338a6e7024b015d0107eaecf78c61f8ece8e6553d77f7f0ba726 \ + --hash=sha256:51ff863e92c7b608d464da10c775b5df5ad3651a05c2d316c1d60a46572fdef9 \ + --hash=sha256:0f920d745df15e3171412cbda05fc21c9354323d0e8dfc066ed6051fa7df9879 \ + --hash=sha256:d78970415fb03c1dd22aef8da7526e5b33eaf4c9848f5cbad843ad159254f526 \ + --hash=sha256:50536924bbf702d310b92d307d7c5060f6a4307bf99b61f79571ba2675ebb1ff \ + --hash=sha256:1123f8f87ce6415183126842eca1fff98362ff545204adfd4c7b6cf1c396b738 \ + --hash=sha256:1b248af5aa7321e46ae05675b15a5993e28311dfabc68cee2e398ce571f28eb2 \ + --hash=sha256:a76e9d17ec3af9317b3a9d5e9f9f04aea80a5902c33f6fe82d02381f2fd2cb69 \ + --hash=sha256:081ed52f8e1693ca48262cb5a9687ee62c4f9a50c667a487192c72be4c1b7fac \ + --hash=sha256:2978aa13826337d59799f41dda41fa4cecd9f59fae8843613230cf298b06fa6e \ + --hash=sha256:d377c2fd68c3d529d89ba40a762b6424c3b04c0d58593c02f06adbdf236f72ad \ + --hash=sha256:800d6c30eab6ca3ee39a6c297d08cb74cfa5a4bce498aa3f05a612596f8c513b \ + --hash=sha256:0cf40413f4b7ae5d561e47706f446b91440a1b74abe33b8fabc995d92c3325ca \ + --hash=sha256:97791b8695aa215ef407824d1e6c0582a2a2f89f3a0f254f5d791a5a84a0ad00 \ + --hash=sha256:2174db5e4550f94cb63e17584973c9f9afdc23e5230cb556de8bf87bd72145ff \ + --hash=sha256:f3a4cd6a9b292e7385722d8200e834a936886136ddaef2069035f7ec5eb50d34 \ + --hash=sha256:7646efdf7e091c75dac9aebb6c9faf215de4f6b8567c049944790e43cbe63d51 \ + --hash=sha256:cd56cca26ed9675790154dd70402ad28a381fc3c9031bd02eb9b1dad8c317398 \ From 3a46c9fd3e3ff153d956e267c10f1486cff8dcae Mon Sep 17 00:00:00 2001 From: Ishigh1 Date: Fri, 17 Jan 2025 20:05:02 +0100 Subject: [PATCH 0055/1218] LADX: Closing the client window closes the window (#4350) --- LinksAwakeningClient.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/LinksAwakeningClient.py b/LinksAwakeningClient.py index aede742b82a0..e2e16922fa95 100644 --- a/LinksAwakeningClient.py +++ b/LinksAwakeningClient.py @@ -560,6 +560,10 @@ async def server_auth(self, password_requested: bool = False): while self.client.auth == None: await asyncio.sleep(0.1) + + # Just return if we're closing + if self.exit_event.is_set(): + return self.auth = self.client.auth await self.send_connect() From 698d27aada253d11c8df0db1e7d5a7e9d99a6fe7 Mon Sep 17 00:00:00 2001 From: Pierre-Alain BESSERO Date: Fri, 17 Jan 2025 20:06:20 +0100 Subject: [PATCH 0056/1218] OoT: Allow Crowd Control support for Ocarina of Time (Bizhawk) #4501 Changed the name of the default "receive" function in order to work with Crowd Control --- data/lua/connector_oot.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/lua/connector_oot.lua b/data/lua/connector_oot.lua index 7bec37244b07..9df9bdc4c94f 100644 --- a/data/lua/connector_oot.lua +++ b/data/lua/connector_oot.lua @@ -1816,7 +1816,7 @@ end -- Main control handling: main loop and socket receive -function receive() +function APreceive() l, e = ootSocket:receive() -- Handle incoming message if e == 'closed' then @@ -1874,7 +1874,7 @@ function main() end if (curstate == STATE_OK) or (curstate == STATE_INITIAL_CONNECTION_MADE) or (curstate == STATE_TENTATIVELY_CONNECTED) then if (frame % 30 == 0) then - receive() + APreceive() end elseif (curstate == STATE_UNINITIALIZED) then if (frame % 60 == 0) then From 23ea3c0efc4cd5a9f78436a26e4225aaac527801 Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Fri, 17 Jan 2025 11:14:21 -0800 Subject: [PATCH 0057/1218] Core: some low-hanging fruit on the strict type check (#3416) * Core: some low-hanging fruit on the strict type check * bump pyright version * bump pyright version * bump pyright and remove file that's no longer easy --- .github/pyright-config.json | 16 ++++++++++++++-- .github/workflows/strict-type-check.yml | 2 +- test/general/test_helpers.py | 11 +++++++---- test/general/test_memory.py | 2 +- test/general/test_names.py | 4 ++-- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/.github/pyright-config.json b/.github/pyright-config.json index 7d981778905f..de7758a71566 100644 --- a/.github/pyright-config.json +++ b/.github/pyright-config.json @@ -1,8 +1,20 @@ { "include": [ - "type_check.py", + "../BizHawkClient.py", + "../Patch.py", + "../test/general/test_groups.py", + "../test/general/test_helpers.py", + "../test/general/test_memory.py", + "../test/general/test_names.py", + "../test/multiworld/__init__.py", + "../test/multiworld/test_multiworlds.py", + "../test/netutils/__init__.py", + "../test/programs/__init__.py", + "../test/programs/test_multi_server.py", + "../test/utils/__init__.py", + "../test/webhost/test_descriptions.py", "../worlds/AutoSNIClient.py", - "../Patch.py" + "type_check.py" ], "exclude": [ diff --git a/.github/workflows/strict-type-check.yml b/.github/workflows/strict-type-check.yml index bafd572a26ae..91f4aed92a2d 100644 --- a/.github/workflows/strict-type-check.yml +++ b/.github/workflows/strict-type-check.yml @@ -26,7 +26,7 @@ jobs: - name: "Install dependencies" run: | - python -m pip install --upgrade pip pyright==1.1.358 + python -m pip install --upgrade pip pyright==1.1.377 python ModuleUpdate.py --append "WebHostLib/requirements.txt" --force --yes - name: "pyright: strict check on specific files" diff --git a/test/general/test_helpers.py b/test/general/test_helpers.py index be8473975638..7e850f9744c5 100644 --- a/test/general/test_helpers.py +++ b/test/general/test_helpers.py @@ -1,6 +1,8 @@ import unittest from typing import Callable, Dict, Optional +from typing_extensions import override + from BaseClasses import CollectionState, MultiWorld, Region @@ -8,6 +10,7 @@ class TestHelpers(unittest.TestCase): multiworld: MultiWorld player: int = 1 + @override def setUp(self) -> None: self.multiworld = MultiWorld(self.player) self.multiworld.game[self.player] = "helper_test_game" @@ -38,15 +41,15 @@ def test_region_helpers(self) -> None: "TestRegion1": {"TestRegion2": "connection"}, "TestRegion2": {"TestRegion1": None}, } - + reg_exit_set: Dict[str, set[str]] = { "TestRegion1": {"TestRegion3"} } - + exit_rules: Dict[str, Callable[[CollectionState], bool]] = { "TestRegion1": lambda state: state.has("test_item", self.player) } - + self.multiworld.regions += [Region(region, self.player, self.multiworld, regions[region]) for region in regions] with self.subTest("Test Location Creation Helper"): @@ -73,7 +76,7 @@ def test_region_helpers(self) -> None: entrance_name = exit_name if exit_name else f"{parent} -> {exit_reg}" self.assertEqual(exit_rules[exit_reg], self.multiworld.get_entrance(entrance_name, self.player).access_rule) - + for region in reg_exit_set: current_region = self.multiworld.get_region(region, self.player) current_region.add_exits(reg_exit_set[region]) diff --git a/test/general/test_memory.py b/test/general/test_memory.py index e352b9e8751a..987d19acf35f 100644 --- a/test/general/test_memory.py +++ b/test/general/test_memory.py @@ -5,7 +5,7 @@ class TestWorldMemory(unittest.TestCase): - def test_leak(self): + def test_leak(self) -> None: """Tests that worlds don't leak references to MultiWorld or themselves with default options.""" import gc import weakref diff --git a/test/general/test_names.py b/test/general/test_names.py index 7be76eed4ba9..8ad74a33544d 100644 --- a/test/general/test_names.py +++ b/test/general/test_names.py @@ -3,7 +3,7 @@ class TestNames(unittest.TestCase): - def test_item_names_format(self): + def test_item_names_format(self) -> None: """Item names must not be all numeric in order to differentiate between ID and name in !hint""" for gamename, world_type in AutoWorldRegister.world_types.items(): with self.subTest(game=gamename): @@ -11,7 +11,7 @@ def test_item_names_format(self): self.assertFalse(item_name.isnumeric(), f"Item name \"{item_name}\" is invalid. It must not be numeric.") - def test_location_name_format(self): + def test_location_name_format(self) -> None: """Location names must not be all numeric in order to differentiate between ID and name in !hint_location""" for gamename, world_type in AutoWorldRegister.world_types.items(): with self.subTest(game=gamename): From 2b9fa890509df1d53a68be0758119a767faf8aa8 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 17 Jan 2025 15:22:36 -0500 Subject: [PATCH 0058/1218] Bizhawk: adds typing to bizhawk component launch (#4505) --- worlds/_bizhawk/context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/_bizhawk/context.py b/worlds/_bizhawk/context.py index 8d029f92ec71..e20b6551cb26 100644 --- a/worlds/_bizhawk/context.py +++ b/worlds/_bizhawk/context.py @@ -241,7 +241,7 @@ def _patch_and_run_game(patch_file: str): return {} -def launch(*launch_args) -> None: +def launch(*launch_args: str) -> None: async def main(): parser = get_base_parser() parser.add_argument("patch_file", default="", type=str, nargs="?", help="Path to an Archipelago patch file") From 1ac8349bd427e7ba2980c4083e28ceaeafa923e8 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 17 Jan 2025 21:30:18 +0100 Subject: [PATCH 0059/1218] CI: update pyright (#4506) --- .github/workflows/strict-type-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/strict-type-check.yml b/.github/workflows/strict-type-check.yml index 91f4aed92a2d..2ccdad8d11af 100644 --- a/.github/workflows/strict-type-check.yml +++ b/.github/workflows/strict-type-check.yml @@ -26,7 +26,7 @@ jobs: - name: "Install dependencies" run: | - python -m pip install --upgrade pip pyright==1.1.377 + python -m pip install --upgrade pip pyright==1.1.392.post0 python ModuleUpdate.py --append "WebHostLib/requirements.txt" --force --yes - name: "pyright: strict check on specific files" From 8732974857f620fb05d98f53aee6802a31eb77e5 Mon Sep 17 00:00:00 2001 From: CarlosBor <48533334+CarlosBor@users.noreply.github.com> Date: Sat, 18 Jan 2025 03:38:59 +0100 Subject: [PATCH 0060/1218] ALttP: update Spanish Setup Docs (#2670) Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> --- worlds/alttp/docs/multiworld_es.md | 251 +++++++++-------------------- 1 file changed, 75 insertions(+), 176 deletions(-) diff --git a/worlds/alttp/docs/multiworld_es.md b/worlds/alttp/docs/multiworld_es.md index a8ed11cd3202..eade0372ec6e 100644 --- a/worlds/alttp/docs/multiworld_es.md +++ b/worlds/alttp/docs/multiworld_es.md @@ -1,224 +1,123 @@ # Guía de instalación para A Link to the Past Randomizer Multiworld -
- -
- ## Software requerido -- [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) -- [QUsb2Snes](https://github.com/Skarsnik/QUsb2snes/releases) (Incluido en Multiworld Utilities) -- Hardware o software capaz de cargar y ejecutar archivos de ROM de SNES - - Un emulador capaz de ejecutar scripts Lua - ([snes9x rr](https://github.com/gocha/snes9x-rr/releases), +- [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases). +- [SNI](https://github.com/alttpo/sni/releases). Esto está incluido automáticamente en la instalación de Archipelago. +- SNI no es compatible con (Q)Usb2Snes. +- Hardware o software capaz de cargar y ejecutar archivos de ROM de SNES, por ejemplo: + - Un emulador capaz de conectarse a SNI + ([snes9x-nwa](https://github.com/Skarsnik/snes9x-emunwa/releases), [snes9x-rr](https://github.com/gocha/snes9x-rr/releases), + [BSNES-plus](https://github.com/black-sliver/bsnes-plus), [BizHawk](https://tasvideos.org/BizHawk), o - [RetroArch](https://retroarch.com?page=platforms) 1.10.1 o más nuevo). O, - - Un flashcart SD2SNES, [FXPak Pro](https://krikzz.com/store/home/54-fxpak-pro.html), o otro hardware compatible + [RetroArch](https://retroarch.com?page=platforms) 1.10.1 o más nuevo). + - Un SD2SNES, [FXPak Pro](https://krikzz.com/store/home/54-fxpak-pro.html), u otro hardware compatible. **nota: +Las SNES minis modificadas no tienen soporte de SNI. Algunos usuarios dicen haber tenido éxito con Qusb2Snes para esta consola, +pero no tiene soporte.** - Tu archivo ROM japones v1.0, probablemente se llame `Zelda no Densetsu - Kamigami no Triforce (Japan).sfc` ## Procedimiento de instalación -### Instalación en Windows - -1. Descarga e instala MultiWorld Utilities desde el enlace anterior, asegurando que instalamos la versión más reciente. - **El archivo esta localizado en la sección "assets" en la parte inferior de la información de versión**. Si tu - intención es jugar la versión normal de multiworld, necesitarás el archivo `Setup.Archipelago.exe` - - Si estas interesado en jugar la variante que aleatoriza las puertas internas de las mazmorras, necesitaras bajar ' - Setup.BerserkerMultiWorld.Doors.exe' - - Durante el proceso de instalación, se te pedirá donde esta situado tu archivo ROM japonés v1.0. Si ya habías - instalado este software con anterioridad y simplemente estas actualizando, no se te pedirá la localización del - archivo una segunda vez. - - Puede ser que el programa pida la instalación de Microsoft Visual C++. Si ya lo tienes en tu ordenador ( - posiblemente por que un juego de Steam ya lo haya instalado), el instalador no te pedirá su instalación. - -2. Si estas usando un emulador, deberías asignar la versión capaz de ejecutar scripts Lua como programa por defecto para - lanzar ficheros de ROM de SNES. - 1. Extrae tu emulador al escritorio, o cualquier sitio que después recuerdes. - 2. Haz click derecho en un fichero de ROM (ha de tener la extensión sfc) y selecciona **Abrir con...** - 3. Marca la opción **Usar siempre esta aplicación para abrir los archivos .sfc** - 4. Baja hasta el final de la lista y haz click en la opción **Buscar otra aplicación en el equipo** (Si usas Windows - 10 es posible que debas hacer click en **Más aplicaciones**) - 5. Busca el archivo .exe de tu emulador y haz click en **Abrir**. Este archivo debe estar en el directorio donde - extrajiste en el paso 1. - -### Instalación en Macintosh - -- ¡Necesitamos voluntarios para rellenar esta seccion! Contactad con **Farrak Kilhn** (en inglés) en Discord si queréis - ayudar. - -## Configurar tu archivo YAML - -### Que es un archivo YAML y por qué necesito uno? - -Tu archivo YAML contiene un conjunto de opciones de configuración que proveen al generador con información sobre como -debe generar tu juego. Cada jugador en una partida de multiworld proveerá su propio fichero YAML. Esta configuración -permite que cada jugador disfrute de una experiencia personalizada a su gusto, y cada jugador dentro de la misma partida -de multiworld puede tener diferentes opciones. - -### Donde puedo obtener un fichero YAML? - -La página "[Generate Game](/games/A%20Link%20to%20the%20Past/player-options)" en el sitio web te permite configurar tu -configuración personal y descargar un fichero "YAML". - -### Configuración YAML avanzada - -Una version mas avanzada del fichero Yaml puede ser creada usando la pagina -["Weighted settings"](/games/A Link to the Past/weighted-options), -la cual te permite tener almacenadas hasta 3 preajustes. La pagina "Weighted Settings" tiene muchas opciones -representadas con controles deslizantes. Esto permite elegir cuan probable los valores de una categoría pueden ser -elegidos sobre otros de la misma. - -Por ejemplo, imagina que el generador crea un cubo llamado "map_shuffle", y pone trozos de papel doblado en él por cada -sub-opción. Ademas imaginemos que tu valor elegido para "on" es 20 y el elegido para "off" es 40. - -Por tanto, en este ejemplo, habrán 60 trozos de papel. 20 para "on" y 40 para "off". Cuando el generador esta decidiendo -si activar o no "map shuffle" para tu partida, meterá la mano en el cubo y sacara un trozo de papel al azar. En este -ejemplo, es mucho mas probable (2 de cada 3 veces (40/60)) que "map shuffle" esté desactivado. - -Si quieres que una opción no pueda ser escogida, simplemente asigna el valor 0 a dicha opción. Recuerda que cada opción -debe tener al menos un valor mayor que cero, si no la generación fallará. - -### Verificando tu archivo YAML - -Si quieres validar que tu fichero YAML para asegurarte que funciona correctamente, puedes hacerlo en la pagina -[YAML Validator](/check). - -## Generar una partida para un jugador - -1. Navega a [la pagina Generate game](/games/A%20Link%20to%20the%20Past/player-options), configura tus opciones, haz - click en el boton "Generate game". -2. Se te redigirá a una pagina "Seed Info", donde puedes descargar tu archivo de parche. -3. Haz doble click en tu fichero de parche, y el emulador debería ejecutar tu juego automáticamente. Como el Cliente no - es necesario para partidas de un jugador, puedes cerrarlo junto a la pagina web (que tiene como titulo "Multiworld - WebUI") que se ha abierto automáticamente. - -## Unirse a una partida MultiWorld +1. Descarga e instala [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases/latest). + **El archivo del instalador se encuentra en la sección de assets al final de la información de version**. +2. La primera vez que realices una generación local o parchees tu juego, se te pedirá que ubiques tu archivo ROM base. + Este es tu archivo ROM de Link to the Past japonés. Esto sólo debe hacerse una vez. + +4. Si estás usando un emulador, deberías de asignar tu emulador con compatibilidad con Lua como el programa por defecto para abrir archivos + ROM. + 1. Extrae la carpeta de tu emulador al Escritorio, o algún otro sitio que vayas a recordar. + 2. Haz click derecho en un archivo ROM y selecciona **Abrir con...** + 3. Marca la casilla junto a **Usar siempre este programa para abrir archivos .sfc** + 4. Baja al final de la lista y haz click en el texto gris **Buscar otro programa en este PC** + 5. Busca el archivo `.exe` de tu emulador y haz click en **Abrir**. Este archivo debería de encontrarse dentro de la carpeta que + extrajiste en el paso uno. ### Obtener el fichero de parche y crea tu ROM -Cuando te unes a una partida multiworld, debes proveer tu fichero YAML a quien sea el creador de la partida. Una vez +Cuando te unas a una partida multiworld, se te pedirá enviarle tu archivo de configuración a quien quiera que esté creando. Una vez eso este hecho, el creador te devolverá un enlace para descargar el parche o un fichero zip conteniendo todos los ficheros -de parche de la partida Tu fichero de parche debe tener la extensión `.aplttp`. +de parche de la partida. Tu fichero de parche debe de tener la extensión `.aplttp`. -Pon tu fichero de parche en el escritorio o en algún sitio conveniente, y haz doble click. Esto debería ejecutar -automáticamente el cliente, y ademas creara la rom en el mismo directorio donde este el fichero de parche. +Pon tu fichero de parche en el escritorio o en algún sitio conveniente, y hazle doble click. Esto debería ejecutar +automáticamente el cliente, y además creará la rom en el mismo directorio donde este el fichero de parche. ### Conectar al cliente #### Con emulador -Cuando el cliente se lance automáticamente, QUsb2Snes debería haberse ejecutado también. Si es la primera vez que lo -ejecutas, puedes ser que el firewall de Windows te pregunte si le permites la comunicación. +Cuando el cliente se lance automáticamente, SNI debería de ejecutarse en segundo plano. Si es la +primera vez que se ejecuta, tal vez se te pida permitir que se comunique a través del firewall de Windows + +#### snes9x-nwa + +1. Haz click en el menu Network y marca 'Enable Emu Network Control +2. Carga tu archivo ROM si no lo habías hecho antes ##### snes9x-rr -1. Carga tu fichero de ROM, si no lo has hecho ya +1. Carga tu fichero ROM, si no lo has hecho ya 2. Abre el menu "File" y situa el raton en **Lua Scripting** 3. Haz click en **New Lua Script Window...** 4. En la nueva ventana, haz click en **Browse...** -5. Navega hacia el directorio donde este situado snes9x-rr, entra en el directorio `lua`, y - escoge `multibridge.lua` -6. Observa que se ha asignado un nombre al dispositivo, y el cliente muestra "SNES Device: Connected", con el mismo - nombre en la esquina superior izquierda. +5. Selecciona el archivo lua conector incluido con tu cliente + - Busca en la carpeta de Archipelago `/SNI/lua/`. +6. Si ves un error mientras carga el script que dice `socket.dll missing` o algo similar, ve a la carpeta de +el lua que estas usando en tu gestor de archivos y copia el `socket.dll` a la raíz de tu instalación de snes9x. + +##### BNES-Plus + +1. Cargue su archivo ROM si aún no se ha cargado. +2. El emulador debería conectarse automáticamente mientras SNI se está ejecutando. ##### BizHawk -1. Asegurate que se ha cargado el nucleo BSNES. Debes hacer esto en el menu Tools y siguiento estas opciones: - `Config --> Cores --> SNES --> BSNES` - Una vez cambiado el nucleo cargado, BizHawk ha de ser reiniciado. +1. Asegurate que se ha cargado el núcleo BSNES. Se hace en la barra de menú principal, bajo: + - (≤ 2.8) `Config` 〉 `Cores` 〉 `SNES` 〉 `BSNES` + - (≥ 2.9) `Config` 〉 `Preferred Cores` 〉 `SNES` 〉 `BSNESv115+` 2. Carga tu fichero de ROM, si no lo has hecho ya. -3. Haz click en el menu Tools y en la opción **Lua Console** -4. Haz click en el botón para abrir un nuevo script Lua. -5. Navega al directorio de instalación de MultiWorld Utilities, y en los siguiente directorios: - `QUsb2Snes/Qusb2Snes/LuaBridge` -6. Selecciona `luabridge.lua` y haz click en Abrir. -7. Observa que se ha asignado un nombre al dispositivo, y el cliente muestra "SNES Device: Connected", con el mismo - nombre en la esquina superior izquierda. + Si has cambiado tu preferencia de núcleo tras haber cargado la ROM, no te olvides de volverlo a cargar (atajo por defecto: Ctrl+R). +3. Arrastra el archivo `Connector.lua` que has descargado a la ventana principal de EmuHawk. + - Busca en la carpeta de Archipelago `/SNI/lua/`. + - También podrías abrir la consola de Lua manualmente, hacer click en `Script` 〉 `Open Script`, e ir a `Connector.lua` + con el selector de archivos. ##### RetroArch 1.10.1 o más nuevo -Sólo hay que segiur estos pasos una vez. +Sólo hay que seguir estos pasos una vez. 1. Comienza en la pantalla del menú principal de RetroArch. 2. Ve a Ajustes --> Interfaz de usario. Configura "Mostrar ajustes avanzados" en ON. -3. Ve a Ajustes --> Red. Configura "Comandos de red" en ON. (Se encuentra bajo Request Device 16.) Deja en 55355 (el - default) el Puerto de comandos de red. +3. Ve a Ajustes --> Red. Pon "Comandos de red" en ON. (Se encuentra bajo Request Device 16.) Deja en 55355 el valor por defecto, + el Puerto de comandos de red. ![Captura de pantalla del ajuste Comandos de red](/static/generated/docs/A%20Link%20to%20the%20Past/retroarch-network-commands-en.png) 4. Ve a Menú principal --> Actualizador en línea --> Descargador de núcleos. Desplázate y selecciona "Nintendo - SNES / SFC (bsnes-mercury Performance)". -Cuando cargas un ROM, asegúrate de seleccionar un núcleo **bsnes-mercury**. Estos son los sólos núcleos que permiten +Cuando cargas un ROM, asegúrate de seleccionar un núcleo **bsnes-mercury**. Estos son los únicos núcleos que permiten que herramientas externas lean datos del ROM. #### Con Hardware -Esta guía asume que ya has descargado el firmware correcto para tu dispositivo. Si no lo has hecho ya, hazlo ahora. Los +Esta guía asume que ya has descargado el firmware correcto para tu dispositivo. Si no lo has hecho ya, por favor hazlo ahora. Los usuarios de SD2SNES y FXPak Pro pueden descargar el firmware apropiado -[aqui](https://github.com/RedGuyyyy/sd2snes/releases). Los usuarios de otros dispositivos pueden encontrar información +[aqui](https://github.com/RedGuyyyy/sd2snes/releases). Puede que los usuarios de otros dispositivos encuentren informacion útil [en esta página](http://usb2snes.com/#supported-platforms). 1. Cierra tu emulador, el cual debe haberse autoejecutado. -2. Cierra QUsb2Snes, el cual fue ejecutado junto al cliente. -3. Ejecuta la version correcta de QUsb2Snes (v0.7.16). -4. Enciende tu dispositivo y carga la ROM. -5. Observa en el cliente que ahora muestra "SNES Device: Connected", y aparece el nombre del dispositivo. - -### Conecta al MultiServer - -El fichero de parche que ha lanzado el cliente debe haberte conectado automaticamente al MultiServer. Hay algunas -razonas por las que esto puede que no pase, incluyendo que el juego este hospedado en el sitio web pero se genero en -algún otro sitio. Si el cliente muestra "Server Status: Not Connected", preguntale al creador de la partida la dirección -del servidor, copiala en el campo "Server" y presiona Enter. - -El cliente intentara conectarse a esta nueva dirección, y debería mostrar "Server Status: Connected" en algún momento. -Si el cliente no se conecta al cabo de un rato, puede ser que necesites refrescar la pagina web. - -### Jugando - -Cuando ambos SNES Device and Server aparezcan como "connected", estas listo para empezar a jugar. Felicidades por unirte -satisfactoriamente a una partida de multiworld! - -## Hospedando una partida de multiworld - -La manera recomendad para hospedar una partida es usar el servicio proveído en -[el sitio web](/generate). El proceso es relativamente sencillo: - -1. Recolecta los ficheros YAML de todos los jugadores que participen. -2. Crea un fichero ZIP conteniendo esos ficheros. -3. Carga el fichero zip en el sitio web enlazado anteriormente. -4. Espera a que la seed sea generada. -5. Cuando esto acabe, se te redigirá a una pagina titulada "Seed Info". -6. Haz click en "Create New Room". Esto te llevara a la pagina del servidor. Pasa el enlace a esta pagina a los - jugadores para que puedan descargar los ficheros de parche de ahi. - **Nota:** Los ficheros de parche de esta pagina permiten a los jugadores conectarse al servidor automaticamente, - mientras que los de la pagina "Seed info" no. -7. Hay un enlace a un MultiWorld Tracker en la parte superior de la pagina de la sala. Deberías pasar también este - enlace a los jugadores para que puedan ver el progreso de la partida. A los observadores también se les puede pasar - este enlace. -8. Una vez todos los jugadores se han unido, podeis empezar a jugar. - -## Auto-Tracking - -Si deseas usar auto-tracking para tu partida, varios programas ofrecen esta funcionalidad. -El programa recomentdado actualmente es: -[OpenTracker](https://github.com/trippsc2/OpenTracker/releases). - -### Instalación - -1. Descarga el fichero de instalacion apropiado para tu ordenador (Usuarios de windows quieren el fichero ".msi"). -2. Durante el proceso de insatalación, puede que se te pida instalar Microsoft Visual Studio Build Tools. Un enlace este - programa se muestra durante la proceso, y debe ser ejecutado manualmente. - -### Activar auto-tracking - -1. Con OpenTracker ejecutado, haz click en el menu Tracking en la parte superior de la ventana, y elige ** - AutoTracker...** -2. Click the **Get Devices** button -3. Selecciona tu "SNES device" de la lista -4. Si quieres que las llaves y los objetos de mazmorra tambien sean marcados, activa la caja con nombre **Race Illegal - Tracking** -5. Haz click en el boton **Start Autotracking** -6. Cierra la ventana AutoTracker, ya que deja de ser necesaria +2. Enciende tu dispositivo y carga la ROM. + +### Conecta al Servidor Archipelago + +El fichero de parche que ha lanzado el cliente debería de haberte conectado automaticamente al MultiServer. Sin embargo hay algunas +razones por las que puede que esto no suceda, como que la partida este hospedada en la página web pero generada en otra parte. Si la +ventana del cliente muestra "Server Status: Not Connected", simplemente preguntale al creador de la partida la dirección +del servidor, cópiala en el campo "Server" y presiona Enter. + +El cliente intentará conectarse a esta nueva dirección, y debería mostrar "Server Status: Connected" momentáneamente. + +### Jugar al juego + +Cuando el cliente muestre tanto el dispositivo SNES como el servidor como conectados, estas listo para empezar a jugar. Felicidades por +haberte unido a una partida multiworld con exito! Puedes ejecutar varios comandos en tu cliente. Para mas informacion +acerca de estos comando puedes usar `/help` para comandos locales del cliente y `!help` para comandos de servidor. From 005a143e3e1add0e781cbb87c696bdb2413e8ee1 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 18 Jan 2025 19:59:26 +0100 Subject: [PATCH 0061/1218] MultiServer: Add slot to SetReply packets (#3747) * Add slot to datastorage set response * update docs as well --- MultiServer.py | 1 + docs/network protocol.md | 1 + 2 files changed, 2 insertions(+) diff --git a/MultiServer.py b/MultiServer.py index 81426cb132d8..653c2ecaabb1 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1992,6 +1992,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): args["cmd"] = "SetReply" value = ctx.stored_data.get(args["key"], args.get("default", 0)) args["original_value"] = copy.copy(value) + args["slot"] = client.slot for operation in args["operations"]: func = modify_functions[operation["operation"]] value = func(value, operation["value"]) diff --git a/docs/network protocol.md b/docs/network protocol.md index 160f83031c9b..e32c266ffb67 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -261,6 +261,7 @@ Sent to clients in response to a [Set](#Set) package if want_reply was set to tr | key | str | The key that was updated. | | value | any | The new value for the key. | | original_value | any | The value the key had before it was updated. Not present on "_read" prefixed special keys. | +| slot | int | The slot that originally sent the Set package causing this change. | Additional arguments added to the [Set](#Set) package that triggered this [SetReply](#SetReply) will also be passed along. From 1c9409cac9e4612b8287d9499124b9e71872e197 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 19 Jan 2025 00:26:42 +0100 Subject: [PATCH 0062/1218] CommonClient: implement check_locations to send missing locations only (#4484) Co-authored-by: Scipio Wright --- CommonClient.py | 7 +++++++ worlds/alttp/Client.py | 2 +- worlds/factorio/Client.py | 5 ++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index fc6ae6d9a5fa..b43bf57d1985 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -459,6 +459,13 @@ async def send_connect(self, **kwargs: typing.Any) -> None: await self.send_msgs([payload]) await self.send_msgs([{"cmd": "Get", "keys": ["_read_race_mode"]}]) + async def check_locations(self, locations: typing.Collection[int]) -> set[int]: + """Send new location checks to the server. Returns the set of actually new locations that were sent.""" + locations = set(locations) & self.missing_locations + if locations: + await self.send_msgs([{"cmd": 'LocationChecks', "locations": tuple(locations)}]) + return locations + async def console_input(self) -> str: if self.ui: self.ui.focus_textinput() diff --git a/worlds/alttp/Client.py b/worlds/alttp/Client.py index a0b28829f4bb..78745f438b73 100644 --- a/worlds/alttp/Client.py +++ b/worlds/alttp/Client.py @@ -464,7 +464,7 @@ def new_check(location_id): snes_logger.info(f"Discarding recent {len(new_locations)} checks as ROM Status has changed.") return False else: - await ctx.send_msgs([{"cmd": 'LocationChecks', "locations": new_locations}]) + await ctx.check_locations(new_locations) await snes_flush_writes(ctx) return True diff --git a/worlds/factorio/Client.py b/worlds/factorio/Client.py index 3c35c4cb0986..ac58339c5e14 100644 --- a/worlds/factorio/Client.py +++ b/worlds/factorio/Client.py @@ -234,8 +234,7 @@ async def game_watcher(ctx: FactorioContext): f"Connected Multiworld is not the expected one {data['seed_name']} != {ctx.seed_name}") else: data = data["info"] - research_data = data["research_done"] - research_data = {int(tech_name.split("-")[1]) for tech_name in research_data} + research_data: set[int] = {int(tech_name.split("-")[1]) for tech_name in data["research_done"]} victory = data["victory"] await ctx.update_death_link(data["death_link"]) ctx.multiplayer = data.get("multiplayer", False) @@ -249,7 +248,7 @@ async def game_watcher(ctx: FactorioContext): f"New researches done: " f"{[ctx.location_names.lookup_in_game(rid) for rid in research_data - ctx.locations_checked]}") ctx.locations_checked = research_data - await ctx.send_msgs([{"cmd": 'LocationChecks', "locations": tuple(research_data)}]) + await ctx.check_locations(research_data) death_link_tick = data.get("death_link_tick", 0) if death_link_tick != ctx.death_link_tick: ctx.death_link_tick = death_link_tick From 992f1925296f7fe2e60b4c5358e810b640dadc3d Mon Sep 17 00:00:00 2001 From: Jouramie <16137441+Jouramie@users.noreply.github.com> Date: Sat, 18 Jan 2025 20:36:01 -0500 Subject: [PATCH 0063/1218] Stardew Valley: Improve generation performance by around 11% by moving calculating from rule evaluation to collect (#4231) --- worlds/stardew_valley/__init__.py | 40 +++++++++++------ worlds/stardew_valley/stardew_rule/state.py | 45 +++---------------- .../strings/ap_names/event_names.py | 2 + .../stardew_valley/test/rules/TestShipping.py | 11 +++-- 4 files changed, 42 insertions(+), 56 deletions(-) diff --git a/worlds/stardew_valley/__init__.py b/worlds/stardew_valley/__init__.py index 9da650520f05..ef842263ad2c 100644 --- a/worlds/stardew_valley/__init__.py +++ b/worlds/stardew_valley/__init__.py @@ -1,6 +1,6 @@ import logging from random import Random -from typing import Dict, Any, Iterable, Optional, Union, List, TextIO +from typing import Dict, Any, Iterable, Optional, List, TextIO from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState from Options import PerGameCommonOptions @@ -88,7 +88,6 @@ class StardewValleyWorld(World): randomized_entrances: Dict[str, str] total_progression_items: int - excluded_from_total_progression_items: List[str] = [Event.received_walnuts] def __init__(self, multiworld: MultiWorld, player: int): super().__init__(multiworld, player) @@ -176,7 +175,7 @@ def precollect_starting_season(self): if self.options.season_randomization == SeasonRandomization.option_disabled: for season in season_pool: - self.multiworld.push_precollected(self.create_starting_item(season)) + self.multiworld.push_precollected(self.create_item(season)) return if [item for item in self.multiworld.precollected_items[self.player] @@ -186,12 +185,12 @@ def precollect_starting_season(self): if self.options.season_randomization == SeasonRandomization.option_randomized_not_winter: season_pool = [season for season in season_pool if season.name != "Winter"] - starting_season = self.create_starting_item(self.random.choice(season_pool)) + starting_season = self.create_item(self.random.choice(season_pool)) self.multiworld.push_precollected(starting_season) def precollect_farm_type_items(self): if self.options.farm_type == FarmType.option_meadowlands and self.options.building_progression & BuildingProgression.option_progressive: - self.multiworld.push_precollected(self.create_starting_item("Progressive Coop")) + self.multiworld.push_precollected(self.create_item("Progressive Coop")) def setup_logic_events(self): def register_event(name: str, region: str, rule: StardewRule): @@ -271,7 +270,7 @@ def setup_victory(self): def get_all_location_names(self) -> List[str]: return list(location.name for location in self.multiworld.get_locations(self.player)) - def create_item(self, item: Union[str, ItemData], override_classification: ItemClassification = None) -> StardewItem: + def create_item(self, item: str | ItemData, override_classification: ItemClassification = None) -> StardewItem: if isinstance(item, str): item = item_table[item] @@ -280,12 +279,6 @@ def create_item(self, item: Union[str, ItemData], override_classification: ItemC return StardewItem(item.name, override_classification, item.code, self.player) - def create_starting_item(self, item: Union[str, ItemData]) -> StardewItem: - if isinstance(item, str): - item = item_table[item] - - return StardewItem(item.name, item.classification, item.code, self.player) - def create_event_location(self, location_data: LocationData, rule: StardewRule = None, item: Optional[str] = None): if rule is None: rule = True_() @@ -393,9 +386,19 @@ def collect(self, state: CollectionState, item: StardewItem) -> bool: if not change: return False + player_state = state.prog_items[self.player] + + received_progression_count = player_state[Event.received_progression_item] + received_progression_count += 1 + if self.total_progression_items: + # Total progression items is not set until all items are created, but collect will be called during the item creation when an item is precollected. + # We can't update the percentage if we don't know the total progression items, can't divide by 0. + player_state[Event.received_progression_percent] = received_progression_count * 100 // self.total_progression_items + player_state[Event.received_progression_item] = received_progression_count + walnut_amount = self.get_walnut_amount(item.name) if walnut_amount: - state.prog_items[self.player][Event.received_walnuts] += walnut_amount + player_state[Event.received_walnuts] += walnut_amount return True @@ -404,9 +407,18 @@ def remove(self, state: CollectionState, item: StardewItem) -> bool: if not change: return False + player_state = state.prog_items[self.player] + + received_progression_count = player_state[Event.received_progression_item] + received_progression_count -= 1 + if self.total_progression_items: + # We can't update the percentage if we don't know the total progression items, can't divide by 0. + player_state[Event.received_progression_percent] = received_progression_count * 100 // self.total_progression_items + player_state[Event.received_progression_item] = received_progression_count + walnut_amount = self.get_walnut_amount(item.name) if walnut_amount: - state.prog_items[self.player][Event.received_walnuts] -= walnut_amount + player_state[Event.received_walnuts] -= walnut_amount return True diff --git a/worlds/stardew_valley/stardew_rule/state.py b/worlds/stardew_valley/stardew_rule/state.py index 6fc349a6274d..d60f08ac4c94 100644 --- a/worlds/stardew_valley/stardew_rule/state.py +++ b/worlds/stardew_valley/stardew_rule/state.py @@ -4,6 +4,7 @@ from BaseClasses import CollectionState from .base import BaseStardewRule, CombinableStardewRule from .protocol import StardewRule +from ..strings.ap_names.event_names import Event if TYPE_CHECKING: from .. import StardewValleyWorld @@ -87,45 +88,13 @@ def __repr__(self): return f"Reach {self.resolution_hint} {self.spot}" -@dataclass(frozen=True) -class HasProgressionPercent(CombinableStardewRule): - player: int - percent: int +class HasProgressionPercent(Received): + def __init__(self, player: int, percent: int): + super().__init__(Event.received_progression_percent, player, percent, event=True) def __post_init__(self): - assert self.percent > 0, "HasProgressionPercent rule must be above 0%" - assert self.percent <= 100, "HasProgressionPercent rule can't require more than 100% of items" - - @property - def combination_key(self) -> Hashable: - return HasProgressionPercent.__name__ - - @property - def value(self): - return self.percent - - def __call__(self, state: CollectionState) -> bool: - stardew_world: "StardewValleyWorld" = state.multiworld.worlds[self.player] - total_count = stardew_world.total_progression_items - needed_count = (total_count * self.percent) // 100 - player_state = state.prog_items[self.player] - - if needed_count <= len(player_state) - len(stardew_world.excluded_from_total_progression_items): - return True - - total_count = 0 - for item, item_count in player_state.items(): - if item in stardew_world.excluded_from_total_progression_items: - continue - - total_count += item_count - if total_count >= needed_count: - return True - - return False - - def evaluate_while_simplifying(self, state: CollectionState) -> Tuple[StardewRule, bool]: - return self, self(state) + assert self.count > 0, "HasProgressionPercent rule must be above 0%" + assert self.count <= 100, "HasProgressionPercent rule can't require more than 100% of items" def __repr__(self): - return f"Received {self.percent}% progression items" + return f"Received {self.count}% progression items" diff --git a/worlds/stardew_valley/strings/ap_names/event_names.py b/worlds/stardew_valley/strings/ap_names/event_names.py index b7881b3bfd79..68f000bdc316 100644 --- a/worlds/stardew_valley/strings/ap_names/event_names.py +++ b/worlds/stardew_valley/strings/ap_names/event_names.py @@ -10,3 +10,5 @@ class Event: victory = event("Victory") received_walnuts = event("Received Walnuts") + received_progression_item = event("Received Progression Item") + received_progression_percent = event("Received Progression Percent") diff --git a/worlds/stardew_valley/test/rules/TestShipping.py b/worlds/stardew_valley/test/rules/TestShipping.py index b26d1e94ee2c..125b7f31d0d9 100644 --- a/worlds/stardew_valley/test/rules/TestShipping.py +++ b/worlds/stardew_valley/test/rules/TestShipping.py @@ -69,14 +69,17 @@ class TestShipsanityEverything(SVTestBase): def test_all_shipsanity_locations_require_shipping_bin(self): bin_name = "Shipping Bin" self.collect_all_except(bin_name) - shipsanity_locations = [location for location in self.get_real_locations() if - LocationTags.SHIPSANITY in location_table[location.name].tags] + shipsanity_locations = [location + for location in self.get_real_locations() + if LocationTags.SHIPSANITY in location_table[location.name].tags] bin_item = self.create_item(bin_name) + for location in shipsanity_locations: with self.subTest(location.name): - self.remove(bin_item) self.assertFalse(self.world.logic.region.can_reach_location(location.name)(self.multiworld.state)) - self.multiworld.state.collect(bin_item) + + self.collect(bin_item) shipsanity_rule = self.world.logic.region.can_reach_location(location.name) self.assert_rule_true(shipsanity_rule, self.multiworld.state) + self.remove(bin_item) From 0bb657d2c867ae3edc6a3145843ffe235de2ae4a Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sun, 19 Jan 2025 01:21:54 -0800 Subject: [PATCH 0064/1218] Pokemon Emerald: Use new check_locations helper (#4518) --- worlds/pokemon_emerald/client.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/worlds/pokemon_emerald/client.py b/worlds/pokemon_emerald/client.py index 5add7b3fca40..411fdd1a33be 100644 --- a/worlds/pokemon_emerald/client.py +++ b/worlds/pokemon_emerald/client.py @@ -287,7 +287,7 @@ async def game_watcher(self, ctx: "BizHawkClientContext") -> None: pokedex_caught_bytes = read_result[0] game_clear = False - local_checked_locations = set() + local_checked_locations: set[int] = set() local_set_events = {flag_name: False for flag_name in TRACKER_EVENT_FLAGS} local_found_key_items = {location_name: False for location_name in KEY_LOCATION_FLAGS} defeated_legendaries = {legendary_name: False for legendary_name in LEGENDARY_NAMES.values()} @@ -350,10 +350,7 @@ async def game_watcher(self, ctx: "BizHawkClientContext") -> None: self.local_checked_locations = local_checked_locations if local_checked_locations is not None: - await ctx.send_msgs([{ - "cmd": "LocationChecks", - "locations": list(local_checked_locations), - }]) + await ctx.check_locations(local_checked_locations) # Send game clear if not ctx.finished_game and game_clear: From 9183e8f9c9fcc124cf5b8a4b1cc9fc58056dc3fa Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sun, 19 Jan 2025 01:23:06 -0800 Subject: [PATCH 0065/1218] BizHawkClient: Use built-ins for typing (#4508) --- worlds/_bizhawk/__init__.py | 26 +++++++++++++------------- worlds/_bizhawk/client.py | 12 ++++++------ worlds/_bizhawk/context.py | 10 +++++----- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/worlds/_bizhawk/__init__.py b/worlds/_bizhawk/__init__.py index e7b8edc0b6d7..b10e33d3965f 100644 --- a/worlds/_bizhawk/__init__.py +++ b/worlds/_bizhawk/__init__.py @@ -10,7 +10,7 @@ import enum import json import sys -import typing +from typing import Any, Sequence BIZHAWK_SOCKET_PORT_RANGE_START = 43055 @@ -44,10 +44,10 @@ class SyncError(Exception): class BizHawkContext: - streams: typing.Optional[typing.Tuple[asyncio.StreamReader, asyncio.StreamWriter]] + streams: tuple[asyncio.StreamReader, asyncio.StreamWriter] | None connection_status: ConnectionStatus _lock: asyncio.Lock - _port: typing.Optional[int] + _port: int | None def __init__(self) -> None: self.streams = None @@ -122,12 +122,12 @@ async def get_script_version(ctx: BizHawkContext) -> int: return int(await ctx._send_message("VERSION")) -async def send_requests(ctx: BizHawkContext, req_list: typing.List[typing.Dict[str, typing.Any]]) -> typing.List[typing.Dict[str, typing.Any]]: +async def send_requests(ctx: BizHawkContext, req_list: list[dict[str, Any]]) -> list[dict[str, Any]]: """Sends a list of requests to the BizHawk connector and returns their responses. It's likely you want to use the wrapper functions instead of this.""" responses = json.loads(await ctx._send_message(json.dumps(req_list))) - errors: typing.List[ConnectorError] = [] + errors: list[ConnectorError] = [] for response in responses: if response["type"] == "ERROR": @@ -180,7 +180,7 @@ async def get_system(ctx: BizHawkContext) -> str: return res["value"] -async def get_cores(ctx: BizHawkContext) -> typing.Dict[str, str]: +async def get_cores(ctx: BizHawkContext) -> dict[str, str]: """Gets the preferred cores for systems with multiple cores. Only systems with multiple available cores have entries.""" res = (await send_requests(ctx, [{"type": "PREFERRED_CORES"}]))[0] @@ -233,8 +233,8 @@ async def set_message_interval(ctx: BizHawkContext, value: float) -> None: raise SyncError(f"Expected response of type SET_MESSAGE_INTERVAL_RESPONSE but got {res['type']}") -async def guarded_read(ctx: BizHawkContext, read_list: typing.Sequence[typing.Tuple[int, int, str]], - guard_list: typing.Sequence[typing.Tuple[int, typing.Sequence[int], str]]) -> typing.Optional[typing.List[bytes]]: +async def guarded_read(ctx: BizHawkContext, read_list: Sequence[tuple[int, int, str]], + guard_list: Sequence[tuple[int, Sequence[int], str]]) -> list[bytes] | None: """Reads an array of bytes at 1 or more addresses if and only if every byte in guard_list matches its expected value. @@ -262,7 +262,7 @@ async def guarded_read(ctx: BizHawkContext, read_list: typing.Sequence[typing.Tu "domain": domain } for address, size, domain in read_list]) - ret: typing.List[bytes] = [] + ret: list[bytes] = [] for item in res: if item["type"] == "GUARD_RESPONSE": if not item["value"]: @@ -276,7 +276,7 @@ async def guarded_read(ctx: BizHawkContext, read_list: typing.Sequence[typing.Tu return ret -async def read(ctx: BizHawkContext, read_list: typing.Sequence[typing.Tuple[int, int, str]]) -> typing.List[bytes]: +async def read(ctx: BizHawkContext, read_list: Sequence[tuple[int, int, str]]) -> list[bytes]: """Reads data at 1 or more addresses. Items in `read_list` should be organized `(address, size, domain)` where @@ -288,8 +288,8 @@ async def read(ctx: BizHawkContext, read_list: typing.Sequence[typing.Tuple[int, return await guarded_read(ctx, read_list, []) -async def guarded_write(ctx: BizHawkContext, write_list: typing.Sequence[typing.Tuple[int, typing.Sequence[int], str]], - guard_list: typing.Sequence[typing.Tuple[int, typing.Sequence[int], str]]) -> bool: +async def guarded_write(ctx: BizHawkContext, write_list: Sequence[tuple[int, Sequence[int], str]], + guard_list: Sequence[tuple[int, Sequence[int], str]]) -> bool: """Writes data to 1 or more addresses if and only if every byte in guard_list matches its expected value. Items in `write_list` should be organized `(address, value, domain)` where @@ -326,7 +326,7 @@ async def guarded_write(ctx: BizHawkContext, write_list: typing.Sequence[typing. return True -async def write(ctx: BizHawkContext, write_list: typing.Sequence[typing.Tuple[int, typing.Sequence[int], str]]) -> None: +async def write(ctx: BizHawkContext, write_list: Sequence[tuple[int, Sequence[int], str]]) -> None: """Writes data to 1 or more addresses. Items in write_list should be organized `(address, value, domain)` where diff --git a/worlds/_bizhawk/client.py b/worlds/_bizhawk/client.py index 415b663e60af..ce75b864b88c 100644 --- a/worlds/_bizhawk/client.py +++ b/worlds/_bizhawk/client.py @@ -5,7 +5,7 @@ from __future__ import annotations import abc -from typing import TYPE_CHECKING, Any, ClassVar, Dict, Optional, Tuple, Union +from typing import TYPE_CHECKING, Any, ClassVar from worlds.LauncherComponents import Component, SuffixIdentifier, Type, components, launch_subprocess @@ -24,9 +24,9 @@ def launch_client(*args) -> None: class AutoBizHawkClientRegister(abc.ABCMeta): - game_handlers: ClassVar[Dict[Tuple[str, ...], Dict[str, BizHawkClient]]] = {} + game_handlers: ClassVar[dict[tuple[str, ...], dict[str, BizHawkClient]]] = {} - def __new__(cls, name: str, bases: Tuple[type, ...], namespace: Dict[str, Any]) -> AutoBizHawkClientRegister: + def __new__(cls, name: str, bases: tuple[type, ...], namespace: dict[str, Any]) -> AutoBizHawkClientRegister: new_class = super().__new__(cls, name, bases, namespace) # Register handler @@ -54,7 +54,7 @@ def __new__(cls, name: str, bases: Tuple[type, ...], namespace: Dict[str, Any]) return new_class @staticmethod - async def get_handler(ctx: "BizHawkClientContext", system: str) -> Optional[BizHawkClient]: + async def get_handler(ctx: "BizHawkClientContext", system: str) -> BizHawkClient | None: for systems, handlers in AutoBizHawkClientRegister.game_handlers.items(): if system in systems: for handler in handlers.values(): @@ -65,13 +65,13 @@ async def get_handler(ctx: "BizHawkClientContext", system: str) -> Optional[BizH class BizHawkClient(abc.ABC, metaclass=AutoBizHawkClientRegister): - system: ClassVar[Union[str, Tuple[str, ...]]] + system: ClassVar[str | tuple[str, ...]] """The system(s) that the game this client is for runs on""" game: ClassVar[str] """The game this client is for""" - patch_suffix: ClassVar[Optional[Union[str, Tuple[str, ...]]]] + patch_suffix: ClassVar[str | tuple[str, ...] | None] """The file extension(s) this client is meant to open and patch (e.g. ".apz3")""" @abc.abstractmethod diff --git a/worlds/_bizhawk/context.py b/worlds/_bizhawk/context.py index e20b6551cb26..cb59050b84f6 100644 --- a/worlds/_bizhawk/context.py +++ b/worlds/_bizhawk/context.py @@ -6,7 +6,7 @@ import asyncio import enum import subprocess -from typing import Any, Dict, Optional +from typing import Any from CommonClient import CommonContext, ClientCommandProcessor, get_base_parser, server_loop, logger, gui_enabled import Patch @@ -43,15 +43,15 @@ class BizHawkClientContext(CommonContext): command_processor = BizHawkClientCommandProcessor auth_status: AuthStatus password_requested: bool - client_handler: Optional[BizHawkClient] - slot_data: Optional[Dict[str, Any]] = None - rom_hash: Optional[str] = None + client_handler: BizHawkClient | None + slot_data: dict[str, Any] | None = None + rom_hash: str | None = None bizhawk_ctx: BizHawkContext watcher_timeout: float """The maximum amount of time the game watcher loop will wait for an update from the server before executing""" - def __init__(self, server_address: Optional[str], password: Optional[str]): + def __init__(self, server_address: str | None, password: str | None): super().__init__(server_address, password) self.auth_status = AuthStatus.NOT_AUTHENTICATED self.password_requested = False From 9e353ebb8e2661bcdc95b11ff6520bcb6379368f Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Sun, 19 Jan 2025 06:17:12 -0600 Subject: [PATCH 0066/1218] =?UTF-8?q?SMZ3:=20Fix=20Itemlinks=20with=20link?= =?UTF-8?q?=5Freplacement=C2=A0#4099?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worlds/smz3/__init__.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/worlds/smz3/__init__.py b/worlds/smz3/__init__.py index 5998db8e6579..7ebec7d4e4be 100644 --- a/worlds/smz3/__init__.py +++ b/worlds/smz3/__init__.py @@ -87,6 +87,21 @@ def __init__(self, world: MultiWorld, player: int): self.rom_name_available_event = threading.Event() self.locations: Dict[str, Location] = {} self.unreachable = [] + self.junkItemsNames = [item.name for item in [ + ItemType.Arrow, + ItemType.OneHundredRupees, + ItemType.TenArrows, + ItemType.ThreeBombs, + ItemType.OneRupee, + ItemType.FiveRupees, + ItemType.TwentyRupees, + ItemType.FiftyRupees, + ItemType.ThreeHundredRupees, + ItemType.ETank, + ItemType.Missile, + ItemType.Super, + ItemType.PowerBomb + ]] super().__init__(world, player) @classmethod From cbf4bbbca8633592c93e3352b0d3d5027f1002f4 Mon Sep 17 00:00:00 2001 From: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> Date: Sun, 19 Jan 2025 18:17:31 -0500 Subject: [PATCH 0067/1218] OoT Adjuster: Remove per_slot_randoms (#4264) --- OoTAdjuster.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/OoTAdjuster.py b/OoTAdjuster.py index 9519b191e704..1581d6539825 100644 --- a/OoTAdjuster.py +++ b/OoTAdjuster.py @@ -1,7 +1,6 @@ import tkinter as tk import argparse import logging -import random import os import zipfile from itertools import chain @@ -197,7 +196,6 @@ def set_icon(window): def adjust(args): # Create a fake multiworld and OOTWorld to use as a base multiworld = MultiWorld(1) - multiworld.per_slot_randoms = {1: random} ootworld = OOTWorld(multiworld, 1) # Set options in the fake OOTWorld for name, option in chain(cosmetic_options.items(), sfx_options.items()): From 94438618495c0f9b051caea21ddb5d69c8c38c56 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Sun, 19 Jan 2025 23:20:45 +0000 Subject: [PATCH 0068/1218] Zillion: Finalize item locations in either generate_output or fill_slot_data (#4121) Co-authored-by: Doug Hoskisson --- test/general/test_implemented.py | 2 +- worlds/zillion/__init__.py | 36 +++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/test/general/test_implemented.py b/test/general/test_implemented.py index 7abf9959936a..1082a02912a8 100644 --- a/test/general/test_implemented.py +++ b/test/general/test_implemented.py @@ -39,7 +39,7 @@ def test_slot_data(self): """Tests that if a world creates slot data, it's json serializable.""" for game_name, world_type in AutoWorldRegister.world_types.items(): # has an await for generate_output which isn't being called - if game_name in {"Ocarina of Time", "Zillion"}: + if game_name in {"Ocarina of Time"}: continue multiworld = setup_solo_multiworld(world_type) with self.subTest(game=game_name, seed=multiworld.seed): diff --git a/worlds/zillion/__init__.py b/worlds/zillion/__init__.py index 5a4e2bb48f18..6fa5f86d0795 100644 --- a/worlds/zillion/__init__.py +++ b/worlds/zillion/__init__.py @@ -119,8 +119,13 @@ def flush(self) -> None: """ my_locations: list[ZillionLocation] = [] """ This is kind of a cache to avoid iterating through all the multiworld locations in logic. """ - slot_data_ready: threading.Event - """ This event is set in `generate_output` when the data is ready for `fill_slot_data` """ + finalized_gen_data: GenData | None + """ Finalized generation data needed by `generate_output` and by `fill_slot_data`. """ + item_locations_finalization_lock: threading.Lock + """ + This lock is used in `generate_output` and `fill_slot_data` to ensure synchronized access to `finalized_gen_data`, + so that whichever is run first can finalize the item locations while the other waits. + """ logic_cache: ZillionLogicCache | None = None def __init__(self, world: MultiWorld, player: int) -> None: @@ -128,7 +133,8 @@ def __init__(self, world: MultiWorld, player: int) -> None: self.logger = logging.getLogger("Zillion") self.lsi = ZillionWorld.LogStreamInterface(self.logger) self.zz_system = System() - self.slot_data_ready = threading.Event() + self.finalized_gen_data = None + self.item_locations_finalization_lock = threading.Lock() def _make_item_maps(self, start_char: Chars) -> None: _id_to_name, _id_to_zz_id, id_to_zz_item = make_id_to_others(start_char) @@ -305,6 +311,19 @@ def post_fill(self) -> None: self.zz_system.post_fill() + def finalize_item_locations_thread_safe(self) -> GenData: + """ + Call self.finalize_item_locations() and cache the result in a thread-safe manner so that either + `generate_output` or `fill_slot_data` can finalize item locations without concern for which of the two functions + is called first. + """ + # The lock is acquired when entering the context manager and released when exiting the context manager. + with self.item_locations_finalization_lock: + # If generation data has yet to be finalized, finalize it. + if self.finalized_gen_data is None: + self.finalized_gen_data = self.finalize_item_locations() + return self.finalized_gen_data + def finalize_item_locations(self) -> GenData: """ sync zilliandomizer item locations with AP item locations @@ -363,12 +382,7 @@ def finalize_item_locations(self) -> GenData: def generate_output(self, output_directory: str) -> None: """This method gets called from a threadpool, do not use multiworld.random here. If you need any last-second randomization, use self.random instead.""" - try: - gen_data = self.finalize_item_locations() - except BaseException: - raise - finally: - self.slot_data_ready.set() + gen_data = self.finalize_item_locations_thread_safe() out_file_base = self.multiworld.get_out_file_name_base(self.player) @@ -392,9 +406,7 @@ def fill_slot_data(self) -> ZillionSlotInfo: # json of WebHostLib.models.Slot # TODO: tell client which canisters are keywords # so it can open and get those when restoring doors - self.slot_data_ready.wait() - assert self.zz_system.randomizer, "didn't get randomizer from generate_early" - game = self.zz_system.get_game() + game = self.finalize_item_locations_thread_safe().zz_game return get_slot_info(game.regions, game.char_order[0], game.loc_name_2_pretty) # end of ordered Main.py calls From 563794ab832b813c1ff7bc51bf1b8c5a7243b17c Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Sun, 19 Jan 2025 15:29:13 -0800 Subject: [PATCH 0069/1218] Zillion: Use Useful Item Classification (#4179) --- worlds/zillion/__init__.py | 11 +++-------- worlds/zillion/item.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/worlds/zillion/__init__.py b/worlds/zillion/__init__.py index 6fa5f86d0795..58f513ba6fb5 100644 --- a/worlds/zillion/__init__.py +++ b/worlds/zillion/__init__.py @@ -9,8 +9,7 @@ from typing_extensions import override -from BaseClasses import ItemClassification, LocationProgressType, \ - MultiWorld, Item, CollectionState, Entrance, Tutorial +from BaseClasses import LocationProgressType, MultiWorld, Item, CollectionState, Entrance, Tutorial from .gen_data import GenData from .logic import ZillionLogicCache @@ -19,7 +18,7 @@ from .id_maps import ZillionSlotInfo, get_slot_info, item_name_to_id as _item_name_to_id, \ loc_name_to_id as _loc_name_to_id, make_id_to_others, \ zz_reg_name_to_reg_name, base_id -from .item import ZillionItem +from .item import ZillionItem, get_classification from .patch import ZillionPatch from zilliandomizer.system import System @@ -422,12 +421,8 @@ def create_item(self, name: str) -> Item: self.logger.warning("warning: called `create_item` without calling `generate_early` first") assert self.id_to_zz_item, "failed to get item maps" - classification = ItemClassification.filler zz_item = self.id_to_zz_item[item_id] - if zz_item.required: - classification = ItemClassification.progression - if not zz_item.is_progression: - classification = ItemClassification.progression_skip_balancing + classification = get_classification(name, zz_item, self._item_counts) z_item = ZillionItem(name, classification, item_id, self.player, zz_item) return z_item diff --git a/worlds/zillion/item.py b/worlds/zillion/item.py index fdf0fa8ba247..5fa481ac36d2 100644 --- a/worlds/zillion/item.py +++ b/worlds/zillion/item.py @@ -1,6 +1,34 @@ +from typing import Counter from BaseClasses import Item, ItemClassification as IC from zilliandomizer.logic_components.items import Item as ZzItem +_useful_thresholds = { + "Apple": 9999, + "Champ": 9999, + "JJ": 9999, + "Win": 9999, + "Empty": 0, + "ID Card": 10, + "Red ID Card": 2, + "Floppy Disk": 7, + "Bread": 0, + "Opa-Opa": 20, + "Zillion": 8, + "Scope": 8, +} +""" make the item useful if the number in the item pool is below this number """ + + +def get_classification(name: str, zz_item: ZzItem, item_counts: Counter[str]) -> IC: + classification = IC.filler + if zz_item.required: + classification = IC.progression + if not zz_item.is_progression: + classification = IC.progression_skip_balancing + if item_counts[name] < _useful_thresholds.get(name, 0): + classification |= IC.useful + return classification + class ZillionItem(Item): game = "Zillion" From ca8ffe583d019c9a82928757263e5daee4cafbd3 Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Sun, 19 Jan 2025 15:31:09 -0800 Subject: [PATCH 0070/1218] Zillion: Priority Dead Ends Feature (#4220) --- worlds/zillion/__init__.py | 14 ++++++++++++++ worlds/zillion/options.py | 15 +++++++++++++++ worlds/zillion/requirements.txt | 2 +- worlds/zillion/test/TestOptions.py | 17 ++++++++++++++++- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/worlds/zillion/__init__.py b/worlds/zillion/__init__.py index 58f513ba6fb5..d0064b9cb1b4 100644 --- a/worlds/zillion/__init__.py +++ b/worlds/zillion/__init__.py @@ -24,6 +24,7 @@ from zilliandomizer.system import System from zilliandomizer.logic_components.items import RESCUE, items as zz_items, Item as ZzItem from zilliandomizer.logic_components.locations import Location as ZzLocation, Req +from zilliandomizer.map_gen.region_maker import DEAD_END_SUFFIX from zilliandomizer.options import Chars from worlds.AutoWorld import World, WebWorld @@ -172,6 +173,7 @@ def create_regions(self) -> None: self.logic_cache = logic_cache w = self.multiworld self.my_locations = [] + dead_end_locations: list[ZillionLocation] = [] self.zz_system.randomizer.place_canister_gun_reqs() # low probability that place_canister_gun_reqs() results in empty 1st sphere @@ -224,6 +226,16 @@ def access_rule_wrapped(zz_loc_local: ZzLocation, here.locations.append(loc) self.my_locations.append(loc) + if (( + zz_here.name.endswith(DEAD_END_SUFFIX) + ) or ( + (self.options.map_gen.value != self.options.map_gen.option_full) and + (loc.name in self.options.priority_dead_ends.vanilla_dead_ends) + ) or ( + loc.name in self.options.priority_dead_ends.always_dead_ends + )): + dead_end_locations.append(loc) + for zz_dest in zz_here.connections.keys(): dest_name = "Menu" if zz_dest.name == "start" else zz_reg_name_to_reg_name(zz_dest.name) dest = all_regions[dest_name] @@ -233,6 +245,8 @@ def access_rule_wrapped(zz_loc_local: ZzLocation, queue.append(zz_dest) done.add(here.name) + if self.options.priority_dead_ends.value: + self.options.priority_locations.value |= {loc.name for loc in dead_end_locations} @override def create_items(self) -> None: diff --git a/worlds/zillion/options.py b/worlds/zillion/options.py index 22a698472265..13f3d43ab07f 100644 --- a/worlds/zillion/options.py +++ b/worlds/zillion/options.py @@ -272,6 +272,20 @@ def zz_value(self) -> Literal["none", "rooms", "full"]: return "full" +class ZillionPriorityDeadEnds(DefaultOnToggle): + """ + Single locations that are in a dead end behind a door + (example: vanilla Apple location) + are prioritized for progression items. + """ + display_name = "priority dead ends" + + vanilla_dead_ends: ClassVar = frozenset(("E-5 top far right", "J-4 top left")) + """ dead ends when not generating these rooms """ + always_dead_ends: ClassVar = frozenset(("A-6 top right",)) + """ dead ends in rooms that never get generated """ + + @dataclass class ZillionOptions(PerGameCommonOptions): continues: ZillionContinues @@ -293,6 +307,7 @@ class ZillionOptions(PerGameCommonOptions): skill: ZillionSkill starting_cards: ZillionStartingCards map_gen: ZillionMapGen + priority_dead_ends: ZillionPriorityDeadEnds room_gen: Removed diff --git a/worlds/zillion/requirements.txt b/worlds/zillion/requirements.txt index d6b01ac107ae..4f79626c9a50 100644 --- a/worlds/zillion/requirements.txt +++ b/worlds/zillion/requirements.txt @@ -1,2 +1,2 @@ -zilliandomizer @ git+https://github.com/beauxq/zilliandomizer@33045067f626266850f91c8045b9d3a9f52d02b0#0.9.0 +zilliandomizer @ git+https://github.com/beauxq/zilliandomizer@96d9a20f8278cee64bb4db859fbd874e0f332d36#0.9.1 typing-extensions>=4.7, <5 diff --git a/worlds/zillion/test/TestOptions.py b/worlds/zillion/test/TestOptions.py index 3820c32dd016..904063fd3cd8 100644 --- a/worlds/zillion/test/TestOptions.py +++ b/worlds/zillion/test/TestOptions.py @@ -1,6 +1,7 @@ from . import ZillionTestBase -from ..options import ZillionJumpLevels, ZillionGunLevels, ZillionOptions, validate +from .. import ZillionWorld +from ..options import ZillionJumpLevels, ZillionGunLevels, ZillionOptions, ZillionPriorityDeadEnds, validate from zilliandomizer.options import VBLR_CHOICES @@ -28,3 +29,17 @@ def test_vblr_ap_to_zz(self) -> None: assert getattr(zz_options, option_name) in VBLR_CHOICES # TODO: test validate with invalid combinations of options + + +class DeadEndsTest(ZillionTestBase): + def test_vanilla_dead_end_names(self) -> None: + z_world = self.multiworld.worlds[1] + assert isinstance(z_world, ZillionWorld) + for loc_name in ZillionPriorityDeadEnds.vanilla_dead_ends: + assert any(loc.name == loc_name for loc in z_world.my_locations), f"{loc_name=} {z_world.my_locations=}" + + def test_always_dead_end_names(self) -> None: + z_world = self.multiworld.worlds[1] + assert isinstance(z_world, ZillionWorld) + for loc_name in ZillionPriorityDeadEnds.always_dead_ends: + assert any(loc.name == loc_name for loc in z_world.my_locations), f"{loc_name=} {z_world.my_locations=}" From 130232b45707be8d9b8d7570344a8c3700d0f87b Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Mon, 20 Jan 2025 01:56:37 +0100 Subject: [PATCH 0071/1218] Core: Make log time an optional arg & setting for Generate.py as well #4312 --- Generate.py | 6 ++++-- settings.py | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Generate.py b/Generate.py index d6611b0f8a31..b057db25a311 100644 --- a/Generate.py +++ b/Generate.py @@ -42,7 +42,9 @@ def mystery_argparse(): help="Path to output folder. Absolute or relative to cwd.") # absolute or relative to cwd parser.add_argument('--race', action='store_true', default=defaults.race) parser.add_argument('--meta_file_path', default=defaults.meta_file_path) - parser.add_argument('--log_level', default='info', help='Sets log level') + parser.add_argument('--log_level', default=defaults.loglevel, help='Sets log level') + parser.add_argument('--log_time', help="Add timestamps to STDOUT", + default=defaults.logtime, action='store_true') parser.add_argument("--csv_output", action="store_true", help="Output rolled player options to csv (made for async multiworld).") parser.add_argument("--plando", default=defaults.plando_options, @@ -75,7 +77,7 @@ def main(args=None) -> Tuple[argparse.Namespace, int]: seed = get_seed(args.seed) - Utils.init_logging(f"Generate_{seed}", loglevel=args.log_level) + Utils.init_logging(f"Generate_{seed}", loglevel=args.log_level, add_timestamp=args.log_time) random.seed(seed) seed_name = get_seed_name(random) diff --git a/settings.py b/settings.py index 04d8760c3cd3..12dace632c8a 100644 --- a/settings.py +++ b/settings.py @@ -678,6 +678,8 @@ class PanicMethod(str): race: Race = Race(0) plando_options: PlandoOptions = PlandoOptions("bosses, connections, texts") panic_method: PanicMethod = PanicMethod("swap") + loglevel: str = "info" + logtime: bool = False class SNIOptions(Group): From 39847c55027117e43d44bd034585e21b79d4ed20 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 20 Jan 2025 02:05:07 +0100 Subject: [PATCH 0072/1218] WebHost: sort slots by player_id in api blueprint (#4354) --- WebHostLib/api/__init__.py | 4 ++-- WebHostLib/api/user.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WebHostLib/api/__init__.py b/WebHostLib/api/__init__.py index cf05e87374ab..d0b9d05c16b8 100644 --- a/WebHostLib/api/__init__.py +++ b/WebHostLib/api/__init__.py @@ -3,13 +3,13 @@ from flask import Blueprint -from ..models import Seed +from ..models import Seed, Slot api_endpoints = Blueprint('api', __name__, url_prefix="/api") def get_players(seed: Seed) -> List[Tuple[str, str]]: - return [(slot.player_name, slot.game) for slot in seed.slots] + return [(slot.player_name, slot.game) for slot in seed.slots.order_by(Slot.player_id)] from . import datapackage, generate, room, user # trigger registration diff --git a/WebHostLib/api/user.py b/WebHostLib/api/user.py index 116d3afa2288..0ddb6fe83ed8 100644 --- a/WebHostLib/api/user.py +++ b/WebHostLib/api/user.py @@ -30,4 +30,4 @@ def get_seeds(): "creation_time": seed.creation_time, "players": get_players(seed.slots), }) - return jsonify(response) \ No newline at end of file + return jsonify(response) From eb3c3d6bf2fb9b161723c7e7ae2990ab0ab7b6bd Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sun, 19 Jan 2025 20:12:44 -0500 Subject: [PATCH 0073/1218] FFMQ: Adds Items Accessibility (#4322) --- worlds/ffmq/Options.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/ffmq/Options.py b/worlds/ffmq/Options.py index 41c397315f87..4dcf1467d6d7 100644 --- a/worlds/ffmq/Options.py +++ b/worlds/ffmq/Options.py @@ -1,4 +1,4 @@ -from Options import Choice, FreeText, Toggle, Range, PerGameCommonOptions +from Options import Choice, FreeText, ItemsAccessibility, Toggle, Range, PerGameCommonOptions from dataclasses import dataclass @@ -324,6 +324,7 @@ class KaelisMomFightsMinotaur(Toggle): @dataclass class FFMQOptions(PerGameCommonOptions): + accessibility: ItemsAccessibility logic: Logic brown_boxes: BrownBoxes sky_coin_mode: SkyCoinMode From 992841a951d71bbee05e28655e587567ab9555ca Mon Sep 17 00:00:00 2001 From: qwint Date: Sun, 19 Jan 2025 20:18:36 -0500 Subject: [PATCH 0074/1218] CommonClient: abstract url handling so it's importable (#4068) Co-authored-by: Doug Hoskisson Co-authored-by: Jouramie <16137441+Jouramie@users.noreply.github.com> --- CommonClient.py | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index b43bf57d1985..f6b2623f8c02 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -31,6 +31,7 @@ if typing.TYPE_CHECKING: import kvui + import argparse logger = logging.getLogger("Client") @@ -1048,6 +1049,32 @@ def get_base_parser(description: typing.Optional[str] = None): return parser +def handle_url_arg(args: "argparse.Namespace", + parser: "typing.Optional[argparse.ArgumentParser]" = None) -> "argparse.Namespace": + """ + Parse the url arg "archipelago://name:pass@host:port" from launcher into correct launch args for CommonClient + If alternate data is required the urlparse response is saved back to args.url if valid + """ + if not args.url: + return args + + url = urllib.parse.urlparse(args.url) + if url.scheme != "archipelago": + if not parser: + parser = get_base_parser() + parser.error(f"bad url, found {args.url}, expected url in form of archipelago://archipelago.gg:38281") + return args + + args.url = url + args.connect = url.netloc + if url.username: + args.name = urllib.parse.unquote(url.username) + if url.password: + args.password = urllib.parse.unquote(url.password) + + return args + + def run_as_textclient(*args): class TextContext(CommonContext): # Text Mode to use !hint and such with games that have no text entry @@ -1089,17 +1116,7 @@ async def main(args): parser.add_argument("url", nargs="?", help="Archipelago connection url") args = parser.parse_args(args) - # handle if text client is launched using the "archipelago://name:pass@host:port" url from webhost - if args.url: - url = urllib.parse.urlparse(args.url) - if url.scheme == "archipelago": - args.connect = url.netloc - if url.username: - args.name = urllib.parse.unquote(url.username) - if url.password: - args.password = urllib.parse.unquote(url.password) - else: - parser.error(f"bad url, found {args.url}, expected url in form of archipelago://archipelago.gg:38281") + args = handle_url_arg(args, parser=parser) # use colorama to display colored text highlighting on windows colorama.init() From 4fa8c432666039ec7cd82e88ba2fd29a62bacbd9 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sun, 19 Jan 2025 23:06:09 -0500 Subject: [PATCH 0075/1218] FFMQ: Fix collect_item (#4433) * Fix FFMQ collect_item --- worlds/ffmq/__init__.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/worlds/ffmq/__init__.py b/worlds/ffmq/__init__.py index 3c58487265a6..58dc4bf13ebd 100644 --- a/worlds/ffmq/__init__.py +++ b/worlds/ffmq/__init__.py @@ -152,14 +152,23 @@ def create_item(self, name: str): return FFMQItem(name, self.player) def collect_item(self, state, item, remove=False): + if not item.advancement: + return None if "Progressive" in item.name: i = item.code - 256 + if remove: + if state.has(self.item_id_to_name[i+1], self.player): + if state.has(self.item_id_to_name[i+2], self.player): + return self.item_id_to_name[i+2] + return self.item_id_to_name[i+1] + return self.item_id_to_name[i] + if state.has(self.item_id_to_name[i], self.player): if state.has(self.item_id_to_name[i+1], self.player): return self.item_id_to_name[i+2] return self.item_id_to_name[i+1] return self.item_id_to_name[i] - return item.name if item.advancement else None + return item.name def modify_multidata(self, multidata): # wait for self.rom_name to be available. From a2fbf856ff1f6d274468b879521c72f78762aa3a Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sun, 19 Jan 2025 23:07:01 -0500 Subject: [PATCH 0076/1218] SMZ3: Change locality options earlier (#4424) --- worlds/smz3/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/worlds/smz3/__init__.py b/worlds/smz3/__init__.py index 7ebec7d4e4be..dca105b16283 100644 --- a/worlds/smz3/__init__.py +++ b/worlds/smz3/__init__.py @@ -217,6 +217,10 @@ def generate_early(self): SMZ3World.location_names = frozenset(self.smz3World.locationLookup.keys()) self.multiworld.state.smz3state[self.player] = TotalSMZ3Item.Progression([]) + + if not self.smz3World.Config.Keysanity: + # Dungeons items here are not in the itempool and will be prefilled locally so they must stay local + self.options.non_local_items.value -= frozenset(item_name for item_name in self.item_names if TotalSMZ3Item.Item.IsNameDungeonItem(item_name)) def create_items(self): self.dungeon = TotalSMZ3Item.Item.CreateDungeonPool(self.smz3World) @@ -233,8 +237,6 @@ def create_items(self): progressionItems = self.progression + self.dungeon + self.keyCardsItems + self.SmMapsItems else: progressionItems = self.progression - # Dungeons items here are not in the itempool and will be prefilled locally so they must stay local - self.options.non_local_items.value -= frozenset(item_name for item_name in self.item_names if TotalSMZ3Item.Item.IsNameDungeonItem(item_name)) for item in self.keyCardsItems: self.multiworld.push_precollected(SMZ3Item(item.Type.name, ItemClassification.filler, item.Type, self.item_name_to_id[item.Type.name], self.player, item)) From d5cd95c7fba516480d303df3a842bffd98d70ff4 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Mon, 20 Jan 2025 03:01:45 -0500 Subject: [PATCH 0077/1218] Docs: Clarify usage of slot data for trackers in World API doc (#3986) * Clarify usage of slot data for trackers in world API. * Typo. * Update docs/world api.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update docs/world api.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update docs/world api.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update docs/world api.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Keep to 120 char lines. --------- Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- docs/world api.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/world api.md b/docs/world api.md index 487c5b4a360c..762189a90842 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -835,14 +835,16 @@ def generate_output(self, output_directory: str) -> None: ### Slot Data -If the game client needs to know information about the generated seed, a preferred method of transferring the data -is through the slot data. This is filled with the `fill_slot_data` method of your world by returning -a `dict` with `str` keys that can be serialized with json. -But, to not waste resources, it should be limited to data that is absolutely necessary. Slot data is sent to your client -once it has successfully [connected](network%20protocol.md#connected). +If a client or tracker needs to know information about the generated seed, a preferred method of transferring the data +is through the slot data. This is filled with the `fill_slot_data` method of your world by returning a `dict` with +`str` keys that can be serialized with json. However, to not waste resources, it should be limited to data that is +absolutely necessary. Slot data is sent to your client once it has successfully +[connected](network%20protocol.md#connected). + If you need to know information about locations in your world, instead of propagating the slot data, it is preferable -to use [LocationScouts](network%20protocol.md#locationscouts), since that data already exists on the server. The most -common usage of slot data is sending option results that the client needs to be aware of. +to use [LocationScouts](network%20protocol.md#locationscouts), since that data already exists on the server. Adding +item/location pairs is unnecessary since the AP server already retains and freely gives that information to clients +that request it. The most common usage of slot data is sending option results that the client needs to be aware of. ```python def fill_slot_data(self) -> Dict[str, Any]: From 4f77abac4f567048d909a049004d03aa303c043c Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 20 Jan 2025 09:53:30 -0500 Subject: [PATCH 0078/1218] TUNIC: Fix failure in 1-player grass (#4520) * Fix failure in 1-player grass * Update worlds/tunic/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/tunic/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 388a44113a82..1394c11c9036 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -411,7 +411,7 @@ def pre_fill(self) -> None: def stage_pre_fill(cls, multiworld: MultiWorld) -> None: tunic_fill_worlds: List[TunicWorld] = [world for world in multiworld.get_game_worlds("TUNIC") if world.options.local_fill.value > 0] - if tunic_fill_worlds: + if tunic_fill_worlds and multiworld.players > 1: grass_fill: List[TunicItem] = [] non_grass_fill: List[TunicItem] = [] grass_fill_locations: List[Location] = [] From 96f469c73792199f84fe3128244c0dfa73331df4 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 20 Jan 2025 10:04:39 -0500 Subject: [PATCH 0079/1218] TUNIC: Fix hero relics not being prog if hex quest is on in combat logic #4509 --- worlds/tunic/__init__.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 1394c11c9036..96d3c10b82d1 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -331,10 +331,11 @@ def remove_filler(amount: int) -> None: remove_filler(items_to_create[gold_hexagon]) - # Sort for deterministic order - for hero_relic in sorted(item_name_groups["Hero Relics"]): - tunic_items.append(self.create_item(hero_relic, ItemClassification.useful)) - items_to_create[hero_relic] = 0 + if not self.options.combat_logic: + # Sort for deterministic order + for hero_relic in sorted(item_name_groups["Hero Relics"]): + tunic_items.append(self.create_item(hero_relic, ItemClassification.useful)) + items_to_create[hero_relic] = 0 if not self.options.ability_shuffling: # Sort for deterministic order From 436c0a41048f6f10084387e61f73995381808eed Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Mon, 20 Jan 2025 16:07:15 +0100 Subject: [PATCH 0080/1218] Core: Add connect_entrances world step/stage (#4420) * Add connect_entrances * update ER docs * fix that test, but also ew * Add a test that asserts the new finalization * Rewrite test a bit * rewrite some more * blank line * rewrite rewrite rewrite * rewrite rewrite rewrite * RE. WRITE. * oops * Bruh * I guess, while we're at it * giga oops * It's been a long day * Switch KH1 over to this design with permission of GICU * Revert * Oops * Bc I like it * Update locations.py --- Main.py | 3 ++- docs/entrance randomization.md | 20 ++++++----------- docs/world api.md | 3 +++ test/benchmark/locations.py | 10 ++++++++- test/general/__init__.py | 10 ++++++++- test/general/test_entrances.py | 36 +++++++++++++++++++++++++++++++ test/general/test_items.py | 4 ++-- test/general/test_locations.py | 6 ++++++ test/general/test_reachability.py | 4 ++-- worlds/AutoWorld.py | 4 ++++ worlds/kh1/Regions.py | 3 +++ worlds/kh1/__init__.py | 5 ++++- 12 files changed, 87 insertions(+), 21 deletions(-) create mode 100644 test/general/test_entrances.py diff --git a/Main.py b/Main.py index d105bd4ad0e5..d0e7a7f8793d 100644 --- a/Main.py +++ b/Main.py @@ -148,7 +148,8 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No else: multiworld.worlds[1].options.non_local_items.value = set() multiworld.worlds[1].options.local_items.value = set() - + + AutoWorld.call_all(multiworld, "connect_entrances") AutoWorld.call_all(multiworld, "generate_basic") # remove starting inventory from pool items. diff --git a/docs/entrance randomization.md b/docs/entrance randomization.md index 9e3e281bcc31..0f9d76471635 100644 --- a/docs/entrance randomization.md +++ b/docs/entrance randomization.md @@ -370,19 +370,13 @@ target_group_lookup = bake_target_group_lookup(world, get_target_groups) #### When to call `randomize_entrances` -The short answer is that you will almost always want to do ER in `pre_fill`. For more information why, continue reading. - -ER begins by collecting the entire item pool and then uses your access rules to try and prevent some kinds of failures. -This means 2 things about when you can call ER: -1. You must supply your item pool before calling ER, or call ER before setting any rules which require items. -2. If you have rules dependent on anything other than items (e.g. `Entrance`s or events), you must set your rules - and create your events before you call ER if you want to guarantee a correct output. - -If the conditions above are met, you could theoretically do ER as early as `create_regions`. However, plando is also -a consideration. Since item plando happens between `set_rules` and `pre_fill` and modifies the item pool, doing ER -in `pre_fill` is the only way to account for placements made by item plando, otherwise you risk impossible seeds or -generation failures. Obviously, if your world implements entrance plando, you will likely want to do that before ER as -well. +The correct step for this is `World.connect_entrances`. + +Currently, you could theoretically do it as early as `World.create_regions` or as late as `pre_fill`. +However, there are upcoming changes to Item Plando and Generic Entrance Randomizer to make the two features work better +together. +These changes necessitate that entrance randomization is done exactly in `World.connect_entrances`. +It is fine for your Entrances to be connected differently or not at all before this step. #### Informing your client about randomized entrances diff --git a/docs/world api.md b/docs/world api.md index 762189a90842..90fe446d6176 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -490,6 +490,9 @@ In addition, the following methods can be implemented and are called in this ord after this step. Locations cannot be moved to different regions after this step. * `set_rules(self)` called to set access and item rules on locations and entrances. +* `connect_entrances(self)` + by the end of this step, all entrances must exist and be connected to their source and target regions. + Entrance randomization should be done here. * `generate_basic(self)` player-specific randomization that does not affect logic can be done here. * `pre_fill(self)`, `fill_hook(self)` and `post_fill(self)` diff --git a/test/benchmark/locations.py b/test/benchmark/locations.py index f2209eb689e1..857e1882368b 100644 --- a/test/benchmark/locations.py +++ b/test/benchmark/locations.py @@ -18,7 +18,15 @@ def run_locations_benchmark(): class BenchmarkRunner: gen_steps: typing.Tuple[str, ...] = ( - "generate_early", "create_regions", "create_items", "set_rules", "generate_basic", "pre_fill") + "generate_early", + "create_regions", + "create_items", + "set_rules", + "connect_entrances", + "generate_basic", + "pre_fill", + ) + rule_iterations: int = 100_000 if sys.version_info >= (3, 9): diff --git a/test/general/__init__.py b/test/general/__init__.py index 8afd84976540..6c4d5092cf13 100644 --- a/test/general/__init__.py +++ b/test/general/__init__.py @@ -5,7 +5,15 @@ from worlds import network_data_package from worlds.AutoWorld import World, call_all -gen_steps = ("generate_early", "create_regions", "create_items", "set_rules", "generate_basic", "pre_fill") +gen_steps = ( + "generate_early", + "create_regions", + "create_items", + "set_rules", + "connect_entrances", + "generate_basic", + "pre_fill", +) def setup_solo_multiworld( diff --git a/test/general/test_entrances.py b/test/general/test_entrances.py new file mode 100644 index 000000000000..72161dfbdebc --- /dev/null +++ b/test/general/test_entrances.py @@ -0,0 +1,36 @@ +import unittest +from worlds.AutoWorld import AutoWorldRegister, call_all, World +from . import setup_solo_multiworld + + +class TestBase(unittest.TestCase): + def test_entrance_connection_steps(self): + """Tests that Entrances are connected and not changed after connect_entrances.""" + def get_entrance_name_to_source_and_target_dict(world: World): + return [ + (entrance.name, entrance.parent_region, entrance.connected_region) + for entrance in world.get_entrances() + ] + + gen_steps = ("generate_early", "create_regions", "create_items", "set_rules", "connect_entrances") + additional_steps = ("generate_basic", "pre_fill") + + for game_name, world_type in AutoWorldRegister.world_types.items(): + with self.subTest("Game", game_name=game_name): + multiworld = setup_solo_multiworld(world_type, gen_steps) + + original_entrances = get_entrance_name_to_source_and_target_dict(multiworld.worlds[1]) + + self.assertTrue( + all(entrance[1] is not None and entrance[2] is not None for entrance in original_entrances), + f"{game_name} had unconnected entrances after connect_entrances" + ) + + for step in additional_steps: + with self.subTest("Step", step=step): + call_all(multiworld, step) + step_entrances = get_entrance_name_to_source_and_target_dict(multiworld.worlds[1]) + + self.assertEqual( + original_entrances, step_entrances, f"{game_name} modified entrances during {step}" + ) diff --git a/test/general/test_items.py b/test/general/test_items.py index 64ce1b6997b7..91d334e9687a 100644 --- a/test/general/test_items.py +++ b/test/general/test_items.py @@ -67,7 +67,7 @@ def test_items_in_datapackage(self): def test_itempool_not_modified(self): """Test that worlds don't modify the itempool after `create_items`""" gen_steps = ("generate_early", "create_regions", "create_items") - additional_steps = ("set_rules", "generate_basic", "pre_fill") + additional_steps = ("set_rules", "connect_entrances", "generate_basic", "pre_fill") excluded_games = ("Links Awakening DX", "Ocarina of Time", "SMZ3") worlds_to_test = {game: world for game, world in AutoWorldRegister.world_types.items() if game not in excluded_games} @@ -84,7 +84,7 @@ def test_itempool_not_modified(self): def test_locality_not_modified(self): """Test that worlds don't modify the locality of items after duplicates are resolved""" gen_steps = ("generate_early", "create_regions", "create_items") - additional_steps = ("set_rules", "generate_basic", "pre_fill") + additional_steps = ("set_rules", "connect_entrances", "generate_basic", "pre_fill") worlds_to_test = {game: world for game, world in AutoWorldRegister.world_types.items()} for game_name, world_type in worlds_to_test.items(): with self.subTest("Game", game=game_name): diff --git a/test/general/test_locations.py b/test/general/test_locations.py index 4b95ebd22c90..37ae94e00328 100644 --- a/test/general/test_locations.py +++ b/test/general/test_locations.py @@ -45,6 +45,12 @@ def test_location_creation_steps(self): self.assertEqual(location_count, len(multiworld.get_locations()), f"{game_name} modified locations count during rule creation") + call_all(multiworld, "connect_entrances") + self.assertEqual(region_count, len(multiworld.get_regions()), + f"{game_name} modified region count during rule creation") + self.assertEqual(location_count, len(multiworld.get_locations()), + f"{game_name} modified locations count during rule creation") + call_all(multiworld, "generate_basic") self.assertEqual(region_count, len(multiworld.get_regions()), f"{game_name} modified region count during generate_basic") diff --git a/test/general/test_reachability.py b/test/general/test_reachability.py index fafa7023893c..b45a2bdfc0ef 100644 --- a/test/general/test_reachability.py +++ b/test/general/test_reachability.py @@ -2,11 +2,11 @@ from BaseClasses import CollectionState from worlds.AutoWorld import AutoWorldRegister -from . import setup_solo_multiworld +from . import setup_solo_multiworld, gen_steps class TestBase(unittest.TestCase): - gen_steps = ["generate_early", "create_regions", "create_items", "set_rules", "generate_basic", "pre_fill"] + gen_steps = gen_steps default_settings_unreachable_regions = { "A Link to the Past": { diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index a51071792079..0fcacc8ab317 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -378,6 +378,10 @@ def set_rules(self) -> None: """Method for setting the rules on the World's regions and locations.""" pass + def connect_entrances(self) -> None: + """Method to finalize the source and target regions of the World's entrances""" + pass + def generate_basic(self) -> None: """ Useful for randomizing things that don't affect logic but are better to be determined before the output stage. diff --git a/worlds/kh1/Regions.py b/worlds/kh1/Regions.py index a6f85fe617cb..6189adf2072c 100644 --- a/worlds/kh1/Regions.py +++ b/worlds/kh1/Regions.py @@ -483,6 +483,8 @@ def create_regions(multiworld: MultiWorld, player: int, options): for name, data in regions.items(): multiworld.regions.append(create_region(multiworld, player, name, data)) + +def connect_entrances(multiworld: MultiWorld, player: int): multiworld.get_entrance("Awakening", player).connect(multiworld.get_region("Awakening", player)) multiworld.get_entrance("Destiny Islands", player).connect(multiworld.get_region("Destiny Islands", player)) multiworld.get_entrance("Traverse Town", player).connect(multiworld.get_region("Traverse Town", player)) @@ -500,6 +502,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): multiworld.get_entrance("World Map", player).connect(multiworld.get_region("World Map", player)) multiworld.get_entrance("Levels", player).connect(multiworld.get_region("Levels", player)) + def create_region(multiworld: MultiWorld, player: int, name: str, data: KH1RegionData): region = Region(name, player, multiworld) if data.locations: diff --git a/worlds/kh1/__init__.py b/worlds/kh1/__init__.py index 63b457556894..3b498acf4670 100644 --- a/worlds/kh1/__init__.py +++ b/worlds/kh1/__init__.py @@ -6,7 +6,7 @@ from .Items import KH1Item, KH1ItemData, event_item_table, get_items_by_category, item_table, item_name_groups from .Locations import KH1Location, location_table, get_locations_by_category, location_name_groups from .Options import KH1Options, kh1_option_groups -from .Regions import create_regions +from .Regions import connect_entrances, create_regions from .Rules import set_rules from .Presets import kh1_option_presets from worlds.LauncherComponents import Component, components, Type, launch_subprocess @@ -242,6 +242,9 @@ def set_rules(self): def create_regions(self): create_regions(self.multiworld, self.player, self.options) + + def connect_entrances(self): + connect_entrances(self.multiworld, self.player) def generate_early(self): value_names = ["Reports to Open End of the World", "Reports to Open Final Rest Door", "Reports in Pool"] From 05d1b2129a9bdef4709f5a5b892324faa5c6b3bd Mon Sep 17 00:00:00 2001 From: "Chris J." Date: Mon, 20 Jan 2025 11:18:09 -0500 Subject: [PATCH 0081/1218] Docs: Update ID Overlapping Docs (#4447) --- docs/world api.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/world api.md b/docs/world api.md index 90fe446d6176..da74be70fb91 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -222,8 +222,8 @@ could also be progress in a research tree, or even something more abstract like Each location has a `name` and an `address` (hereafter referred to as an `id`), is placed in a Region, has access rules, and has a classification. The name needs to be unique within each game and must not be numeric (must contain least 1 -letter or symbol). The ID needs to be unique across all games, and is best kept in the same range as the item IDs. -Locations and items can share IDs, so typically a game's locations and items start at the same ID. +letter or symbol). The ID needs to be unique across all locations within the game. +Locations and items can share IDs, and locations can share IDs with other games' locations. World-specific IDs must be in the range 1 to 253-1; IDs ≤ 0 are global and reserved. @@ -243,7 +243,9 @@ progression. Progression items will be assigned to locations with higher priorit and satisfy progression balancing. The name needs to be unique within each game, meaning if you need to create multiple items with the same name, they -will all have the same ID. Name must not be numeric (must contain at least 1 letter or symbol). +will all have the same ID. Name must not be numeric (must contain at least 1 letter or symbol). +The ID thus also needs to be unique across all items with different names within the game. +Items and locations can share IDs, and items can share IDs with other games' items. Other classifications include: From 823b17c386f1dce27e537e1c0263b0bc8670c377 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 20 Jan 2025 11:44:39 -0500 Subject: [PATCH 0082/1218] TUNIC: Make grass go in the regular location name group too (#4504) * Make grass go in the normal loc group too * Make it not overwrite old groups --- worlds/tunic/__init__.py | 3 ++- worlds/tunic/grass.py | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 96d3c10b82d1..087e17c3e473 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -78,7 +78,8 @@ class TunicWorld(World): settings: ClassVar[TunicSettings] item_name_groups = item_name_groups location_name_groups = location_name_groups - location_name_groups.update(grass_location_name_groups) + for group_name, members in grass_location_name_groups.items(): + location_name_groups.setdefault(group_name, set()).update(members) item_name_to_id = item_name_to_id location_name_to_id = standard_location_name_to_id.copy() diff --git a/worlds/tunic/grass.py b/worlds/tunic/grass.py index 592b2938b118..eb688199dcef 100644 --- a/worlds/tunic/grass.py +++ b/worlds/tunic/grass.py @@ -7767,8 +7767,10 @@ class TunicLocationData(NamedTuple): grass_location_name_groups: Dict[str, Set[str]] = {} for loc_name, loc_data in grass_location_table.items(): - loc_group_name = loc_name.split(" - ", 1)[0] + " Grass" - grass_location_name_groups.setdefault(loc_group_name, set()).add(loc_name) + area_name = loc_name.split(" - ", 1)[0] + # adding it to the normal location group and a grass-only one + grass_location_name_groups.setdefault(area_name, set()).add(loc_name) + grass_location_name_groups.setdefault(area_name + " Grass", set()).add(loc_name) def can_break_grass(state: CollectionState, world: "TunicWorld") -> bool: From e2b942139a5ed1908725812edd52aa479a5d835b Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 20 Jan 2025 13:10:29 -0500 Subject: [PATCH 0083/1218] HK: Save GrubHuntGoal by value (#4521) --- worlds/hk/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/hk/__init__.py b/worlds/hk/__init__.py index 7e9b7442a746..daf177fb8dc9 100644 --- a/worlds/hk/__init__.py +++ b/worlds/hk/__init__.py @@ -209,7 +209,7 @@ def generate_early(self): # defaulting so completion condition isn't incorrect before pre_fill self.grub_count = ( 46 if options.GrubHuntGoal == GrubHuntGoal.special_range_names["all"] - else options.GrubHuntGoal + else options.GrubHuntGoal.value ) self.grub_player_count = {self.player: self.grub_count} From a126dee06824d3fee890eecfbf8a5d4870261e67 Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 20 Jan 2025 17:42:12 -0500 Subject: [PATCH 0084/1218] HK: some stuff ruff and pycodestyle complained about (#4523) --- worlds/hk/Options.py | 2 +- worlds/hk/__init__.py | 52 ++++++++++++++++--------------- worlds/hk/test/__init__.py | 1 - worlds/hk/test/test_grub_count.py | 3 +- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/worlds/hk/Options.py b/worlds/hk/Options.py index 53dda96e2b53..e76e7eba9d16 100644 --- a/worlds/hk/Options.py +++ b/worlds/hk/Options.py @@ -333,7 +333,7 @@ def __init__(self, value): continue try: self.value[key] = CharmCost.from_any(data).value - except ValueError as ex: + except ValueError: # will fail schema afterwords self.value[key] = data diff --git a/worlds/hk/__init__.py b/worlds/hk/__init__.py index daf177fb8dc9..4a0da109fa18 100644 --- a/worlds/hk/__init__.py +++ b/worlds/hk/__init__.py @@ -7,22 +7,22 @@ import operator from collections import defaultdict, Counter -logger = logging.getLogger("Hollow Knight") - -from .Items import item_table, lookup_type_to_names, item_name_groups -from .Regions import create_regions +from .Items import item_table, item_name_groups from .Rules import set_rules, cost_terms, _hk_can_beat_thk, _hk_siblings_ending, _hk_can_beat_radiance from .Options import hollow_knight_options, hollow_knight_randomize_options, Goal, WhitePalace, CostSanity, \ shop_to_option, HKOptions, GrubHuntGoal -from .ExtractedData import locations, starts, multi_locations, location_to_region_lookup, \ - event_names, item_effects, connectors, one_ways, vanilla_shop_costs, vanilla_location_costs +from .ExtractedData import locations, starts, multi_locations, event_names, item_effects, connectors, \ + vanilla_shop_costs, vanilla_location_costs from .Charms import names as charm_names -from BaseClasses import Region, Location, MultiWorld, Item, LocationProgressType, Tutorial, ItemClassification, CollectionState +from BaseClasses import Region, Location, MultiWorld, Item, LocationProgressType, Tutorial, ItemClassification, \ + CollectionState from worlds.AutoWorld import World, LogicMixin, WebWorld from settings import Group, Bool +logger = logging.getLogger("Hollow Knight") + class HollowKnightSettings(Group): class DisableMapModSpoilers(Bool): @@ -160,7 +160,7 @@ class HKWeb(WebWorld): class HKWorld(World): - """Beneath the fading town of Dirtmouth sleeps a vast, ancient kingdom. Many are drawn beneath the surface, + """Beneath the fading town of Dirtmouth sleeps a vast, ancient kingdom. Many are drawn beneath the surface, searching for riches, or glory, or answers to old secrets. As the enigmatic Knight, you’ll traverse the depths, unravel its mysteries and conquer its evils. @@ -231,7 +231,6 @@ def white_palace_exclusions(self): def create_regions(self): menu_region: Region = create_region(self.multiworld, self.player, 'Menu') self.multiworld.regions.append(menu_region) - # wp_exclusions = self.white_palace_exclusions() # check for any goal that godhome events are relevant to all_event_names = event_names.copy() @@ -241,21 +240,17 @@ def create_regions(self): # Link regions for event_name in sorted(all_event_names): - #if event_name in wp_exclusions: - # continue loc = HKLocation(self.player, event_name, None, menu_region) loc.place_locked_item(HKItem(event_name, - True, #event_name not in wp_exclusions, + True, None, "Event", self.player)) menu_region.locations.append(loc) for entry_transition, exit_transition in connectors.items(): - #if entry_transition in wp_exclusions: - # continue if exit_transition: # if door logic fulfilled -> award vanilla target as event loc = HKLocation(self.player, entry_transition, None, menu_region) loc.place_locked_item(HKItem(exit_transition, - True, #exit_transition not in wp_exclusions, + True, None, "Event", self.player)) menu_region.locations.append(loc) @@ -292,7 +287,10 @@ def _add(item_name: str, location_name: str, randomized: bool): if item_name in junk_replace: item_name = self.get_filler_item_name() - item = self.create_item(item_name) if not vanilla or location_name == "Start" or self.options.AddUnshuffledLocations else self.create_event(item_name) + item = (self.create_item(item_name) + if not vanilla or location_name == "Start" or self.options.AddUnshuffledLocations + else self.create_event(item_name) + ) if location_name == "Start": if item_name in randomized_starting_items: @@ -347,8 +345,8 @@ def _add(item_name: str, location_name: str, randomized: bool): randomized = True _add("Elevator_Pass", "Elevator_Pass", randomized) - for shop, locations in self.created_multi_locations.items(): - for _ in range(len(locations), getattr(self.options, shop_to_option[shop]).value): + for shop, shop_locations in self.created_multi_locations.items(): + for _ in range(len(shop_locations), getattr(self.options, shop_to_option[shop]).value): self.create_location(shop) unfilled_locations += 1 @@ -358,7 +356,7 @@ def _add(item_name: str, location_name: str, randomized: bool): # Add additional shop items, as needed. if additional_shop_items > 0: - shops = list(shop for shop, locations in self.created_multi_locations.items() if len(locations) < 16) + shops = [shop for shop, shop_locations in self.created_multi_locations.items() if len(shop_locations) < 16] if not self.options.EggShopSlots: # No eggshop, so don't place items there shops.remove('Egg_Shop') @@ -380,8 +378,8 @@ def _add(item_name: str, location_name: str, randomized: bool): self.sort_shops_by_cost() def sort_shops_by_cost(self): - for shop, locations in self.created_multi_locations.items(): - randomized_locations = list(loc for loc in locations if not loc.vanilla) + for shop, shop_locations in self.created_multi_locations.items(): + randomized_locations = [loc for loc in shop_locations if not loc.vanilla] prices = sorted( (loc.costs for loc in randomized_locations), key=lambda costs: (len(costs),) + tuple(costs.values()) @@ -405,7 +403,7 @@ def _compute_weights(weights: dict, desc: str) -> typing.Dict[str, int]: return {k: v for k, v in weights.items() if v} random = self.random - hybrid_chance = getattr(self.options, f"CostSanityHybridChance").value + hybrid_chance = getattr(self.options, "CostSanityHybridChance").value weights = { data.term: getattr(self.options, f"CostSanity{data.option}Weight").value for data in cost_terms.values() @@ -493,7 +491,11 @@ def stage_pre_fill(cls, multiworld: "MultiWorld"): worlds = [world for world in multiworld.get_game_worlds(cls.game) if world.options.Goal in ["any", "grub_hunt"]] if worlds: grubs = [item for item in multiworld.get_items() if item.name == "Grub"] - all_grub_players = [world.player for world in worlds if world.options.GrubHuntGoal == GrubHuntGoal.special_range_names["all"]] + all_grub_players = [ + world.player + for world in worlds + if world.options.GrubHuntGoal == GrubHuntGoal.special_range_names["all"] + ] if all_grub_players: group_lookup = defaultdict(set) @@ -668,8 +670,8 @@ def stage_write_spoiler(cls, multiworld: MultiWorld, spoiler_handle): ): spoiler_handle.write(f"\n{loc}: {loc.item} costing {loc.cost_text()}") else: - for shop_name, locations in hk_world.created_multi_locations.items(): - for loc in locations: + for shop_name, shop_locations in hk_world.created_multi_locations.items(): + for loc in shop_locations: spoiler_handle.write(f"\n{loc}: {loc.item} costing {loc.cost_text()}") def get_multi_location_name(self, base: str, i: typing.Optional[int]) -> str: diff --git a/worlds/hk/test/__init__.py b/worlds/hk/test/__init__.py index c41d20127fcc..67591001a7e5 100644 --- a/worlds/hk/test/__init__.py +++ b/worlds/hk/test/__init__.py @@ -2,7 +2,6 @@ from argparse import Namespace from BaseClasses import CollectionState, MultiWorld from Options import ItemLinks -from test.bases import WorldTestBase from worlds.AutoWorld import AutoWorldRegister, call_all from .. import HKWorld diff --git a/worlds/hk/test/test_grub_count.py b/worlds/hk/test/test_grub_count.py index dba15b614dd9..a58293c078ed 100644 --- a/worlds/hk/test/test_grub_count.py +++ b/worlds/hk/test/test_grub_count.py @@ -1,5 +1,6 @@ -from . import linkedTestHK, WorldTestBase +from test.bases import WorldTestBase from Options import ItemLinks +from . import linkedTestHK class test_grubcount_limited(linkedTestHK, WorldTestBase): From 33fd9de281f0d4bbbda5f6134eaa7759a3978cb4 Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 20 Jan 2025 18:56:20 -0500 Subject: [PATCH 0085/1218] Core: Add Retry to Priority Fill (#4477) * adds a retry to priority fill in case the one item per player optimization would cause the priority fill to fail to find valid placements * Update Fill.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- Fill.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Fill.py b/Fill.py index 0da2d5def978..d1773c82139b 100644 --- a/Fill.py +++ b/Fill.py @@ -502,7 +502,13 @@ def mark_for_locking(location: Location): # "priority fill" fill_restrictive(multiworld, multiworld.state, prioritylocations, progitempool, single_player_placement=single_player, swap=False, on_place=mark_for_locking, - name="Priority", one_item_per_player=False) + name="Priority", one_item_per_player=True, allow_partial=True) + + if prioritylocations: + # retry with one_item_per_player off because some priority fills can fail to fill with that optimization + fill_restrictive(multiworld, multiworld.state, prioritylocations, progitempool, + single_player_placement=single_player, swap=False, on_place=mark_for_locking, + name="Priority Retry", one_item_per_player=False) accessibility_corrections(multiworld, multiworld.state, prioritylocations, progitempool) defaultlocations = prioritylocations + defaultlocations From edacb17171478be7b512b61deac520c394e34b3f Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 21 Jan 2025 16:12:53 +0100 Subject: [PATCH 0086/1218] Factorio: remove debug print (#4533) --- worlds/factorio/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/worlds/factorio/__init__.py b/worlds/factorio/__init__.py index 8f8abeb292f1..a2bc518ae3fd 100644 --- a/worlds/factorio/__init__.py +++ b/worlds/factorio/__init__.py @@ -280,9 +280,6 @@ def set_rules(self): self.get_location("Rocket Launch").access_rule = lambda state: all(state.has(technology, player) for technology in victory_tech_names) - for tech_name in victory_tech_names: - if not self.multiworld.get_all_state(True).has(tech_name, player): - print(tech_name) self.multiworld.completion_condition[player] = lambda state: state.has('Victory', player) def get_recipe(self, name: str) -> Recipe: From 1a1b7e9cf4c14729f6d3cc0a06f69260610e50e0 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Tue, 21 Jan 2025 12:39:08 -0500 Subject: [PATCH 0087/1218] TUNIC: Reduce range end for local_fill option #4534 --- worlds/tunic/options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index 14bf5d8a18a4..d2ea82803704 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -173,7 +173,7 @@ class LocalFill(NamedRange): internal_name = "local_fill" display_name = "Local Fill Percent" range_start = 0 - range_end = 100 + range_end = 98 special_range_names = { "default": -1 } From 949527f9cb45ac7248d6aa7a73ec2ff980a64fcd Mon Sep 17 00:00:00 2001 From: JaredWeakStrike <96694163+JaredWeakStrike@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:28:33 -0500 Subject: [PATCH 0088/1218] KH2: Bug fixes and game update future proofing (#4075) Co-authored-by: qwint --- worlds/kh2/Client.py | 136 ++++++++++++++++++++++-------------- worlds/kh2/Regions.py | 2 +- worlds/kh2/Rules.py | 6 +- worlds/kh2/docs/setup_en.md | 2 +- 4 files changed, 89 insertions(+), 57 deletions(-) diff --git a/worlds/kh2/Client.py b/worlds/kh2/Client.py index 3ea47e40ebba..0254d46e934e 100644 --- a/worlds/kh2/Client.py +++ b/worlds/kh2/Client.py @@ -5,8 +5,10 @@ import os import asyncio import json +import requests from pymem import pymem -from . import item_dictionary_table, exclusion_item_table, CheckDupingItems, all_locations, exclusion_table, SupportAbility_Table, ActionAbility_Table, all_weapon_slot +from . import item_dictionary_table, exclusion_item_table, CheckDupingItems, all_locations, exclusion_table, \ + SupportAbility_Table, ActionAbility_Table, all_weapon_slot from .Names import ItemName from .WorldLocations import * @@ -82,6 +84,7 @@ def __init__(self, server_address, password): } self.kh2seedname = None self.kh2slotdata = None + self.mem_json = None self.itemamount = {} if "localappdata" in os.environ: self.game_communication_path = os.path.expandvars(r"%localappdata%\KH2AP") @@ -178,7 +181,8 @@ def __init__(self, server_address, password): self.base_accessory_slots = 1 self.base_armor_slots = 1 self.base_item_slots = 3 - self.front_ability_slots = [0x2546, 0x2658, 0x276C, 0x2548, 0x254A, 0x254C, 0x265A, 0x265C, 0x265E, 0x276E, 0x2770, 0x2772] + self.front_ability_slots = [0x2546, 0x2658, 0x276C, 0x2548, 0x254A, 0x254C, 0x265A, 0x265C, 0x265E, 0x276E, + 0x2770, 0x2772] async def server_auth(self, password_requested: bool = False): if password_requested and not self.password: @@ -340,12 +344,8 @@ def on_package(self, cmd: str, args: dict): self.locations_checked |= new_locations if cmd in {"DataPackage"}: - self.kh2_loc_name_to_id = args["data"]["games"]["Kingdom Hearts 2"]["location_name_to_id"] - self.lookup_id_to_location = {v: k for k, v in self.kh2_loc_name_to_id.items()} - self.kh2_item_name_to_id = args["data"]["games"]["Kingdom Hearts 2"]["item_name_to_id"] - self.lookup_id_to_item = {v: k for k, v in self.kh2_item_name_to_id.items()} - self.ability_code_list = [self.kh2_item_name_to_id[item] for item in exclusion_item_table["Ability"]] - + if "Kingdom Hearts 2" in args["data"]["games"]: + self.data_package_kh2_cache(args) if "KeybladeAbilities" in self.kh2slotdata.keys(): # sora ability to slot self.AbilityQuantityDict.update(self.kh2slotdata["KeybladeAbilities"]) @@ -359,24 +359,9 @@ def on_package(self, cmd: str, args: dict): self.all_weapon_location_id = set(all_weapon_location_id) try: - self.kh2 = pymem.Pymem(process_name="KINGDOM HEARTS II FINAL MIX") - if self.kh2_game_version is None: - if self.kh2_read_string(0x09A9830, 4) == "KH2J": - self.kh2_game_version = "STEAM" - self.Now = 0x0717008 - self.Save = 0x09A9830 - self.Slot1 = 0x2A23518 - self.Journal = 0x7434E0 - self.Shop = 0x7435D0 - - elif self.kh2_read_string(0x09A92F0, 4) == "KH2J": - self.kh2_game_version = "EGS" - else: - self.kh2_game_version = None - logger.info("Your game version is out of date. Please update your game via The Epic Games Store or Steam.") - if self.kh2_game_version is not None: - logger.info(f"You are now auto-tracking. {self.kh2_game_version}") - self.kh2connected = True + if not self.kh2: + self.kh2 = pymem.Pymem(process_name="KINGDOM HEARTS II FINAL MIX") + self.get_addresses() except Exception as e: if self.kh2connected: @@ -385,6 +370,13 @@ def on_package(self, cmd: str, args: dict): self.serverconneced = True asyncio.create_task(self.send_msgs([{'cmd': 'Sync'}])) + def data_package_kh2_cache(self, args): + self.kh2_loc_name_to_id = args["data"]["games"]["Kingdom Hearts 2"]["location_name_to_id"] + self.lookup_id_to_location = {v: k for k, v in self.kh2_loc_name_to_id.items()} + self.kh2_item_name_to_id = args["data"]["games"]["Kingdom Hearts 2"]["item_name_to_id"] + self.lookup_id_to_item = {v: k for k, v in self.kh2_item_name_to_id.items()} + self.ability_code_list = [self.kh2_item_name_to_id[item] for item in exclusion_item_table["Ability"]] + async def checkWorldLocations(self): try: currentworldint = self.kh2_read_byte(self.Now) @@ -425,7 +417,6 @@ async def checkLevels(self): 0: ["ValorLevel", ValorLevels], 1: ["WisdomLevel", WisdomLevels], 2: ["LimitLevel", LimitLevels], 3: ["MasterLevel", MasterLevels], 4: ["FinalLevel", FinalLevels], 5: ["SummonLevel", SummonLevels] } - # TODO: remove formDict[i][0] in self.kh2_seed_save_cache["Levels"].keys() after 4.3 for i in range(6): for location, data in formDict[i][1].items(): formlevel = self.kh2_read_byte(self.Save + data.addrObtained) @@ -469,9 +460,11 @@ async def verifyChests(self): if locationName in self.chest_set: if locationName in self.location_name_to_worlddata.keys(): locationData = self.location_name_to_worlddata[locationName] - if self.kh2_read_byte(self.Save + locationData.addrObtained) & 0x1 << locationData.bitIndex == 0: + if self.kh2_read_byte( + self.Save + locationData.addrObtained) & 0x1 << locationData.bitIndex == 0: roomData = self.kh2_read_byte(self.Save + locationData.addrObtained) - self.kh2_write_byte(self.Save + locationData.addrObtained, roomData | 0x01 << locationData.bitIndex) + self.kh2_write_byte(self.Save + locationData.addrObtained, + roomData | 0x01 << locationData.bitIndex) except Exception as e: if self.kh2connected: @@ -494,6 +487,9 @@ async def verifyLevel(self): async def give_item(self, item, location): try: # todo: ripout all the itemtype stuff and just have one dictionary. the only thing that needs to be tracked from the server/local is abilites + #sleep so we can get the datapackage and not miss any items that were sent to us while we didnt have our item id dicts + while not self.lookup_id_to_item: + await asyncio.sleep(0.5) itemname = self.lookup_id_to_item[item] itemdata = self.item_name_to_data[itemname] # itemcode = self.kh2_item_name_to_id[itemname] @@ -637,7 +633,8 @@ async def verifyItems(self): item_data = self.item_name_to_data[item_name] # if the inventory slot for that keyblade is less than the amount they should have, # and they are not in stt - if self.kh2_read_byte(self.Save + item_data.memaddr) != 1 and self.kh2_read_byte(self.Save + 0x1CFF) != 13: + if self.kh2_read_byte(self.Save + item_data.memaddr) != 1 and self.kh2_read_byte( + self.Save + 0x1CFF) != 13: # Checking form anchors for the keyblade to remove extra keyblades if self.kh2_read_short(self.Save + 0x24F0) == item_data.kh2id \ or self.kh2_read_short(self.Save + 0x32F4) == item_data.kh2id \ @@ -738,7 +735,8 @@ async def verifyItems(self): item_data = self.item_name_to_data[item_name] amount_of_items = 0 amount_of_items += self.kh2_seed_save_cache["AmountInvo"]["Magic"][item_name] - if self.kh2_read_byte(self.Save + item_data.memaddr) != amount_of_items and self.kh2_read_byte(self.Shop) in {10, 8}: + if self.kh2_read_byte(self.Save + item_data.memaddr) != amount_of_items and self.kh2_read_byte( + self.Shop) in {10, 8}: self.kh2_write_byte(self.Save + item_data.memaddr, amount_of_items) for item_name in master_stat: @@ -797,7 +795,8 @@ async def verifyItems(self): # self.kh2_write_byte(self.Save + item_data.memaddr, amount_of_items) if "PoptrackerVersionCheck" in self.kh2slotdata: - if self.kh2slotdata["PoptrackerVersionCheck"] > 4.2 and self.kh2_read_byte(self.Save + 0x3607) != 1: # telling the goa they are on version 4.3 + if self.kh2slotdata["PoptrackerVersionCheck"] > 4.2 and self.kh2_read_byte( + self.Save + 0x3607) != 1: # telling the goa they are on version 4.3 self.kh2_write_byte(self.Save + 0x3607, 1) except Exception as e: @@ -806,10 +805,59 @@ async def verifyItems(self): logger.info(e) logger.info("line 840") + def get_addresses(self): + if not self.kh2connected and self.kh2 is not None: + if self.kh2_game_version is None: + + if self.kh2_read_string(0x09A9830, 4) == "KH2J": + self.kh2_game_version = "STEAM" + self.Now = 0x0717008 + self.Save = 0x09A9830 + self.Slot1 = 0x2A23518 + self.Journal = 0x7434E0 + self.Shop = 0x7435D0 + elif self.kh2_read_string(0x09A92F0, 4) == "KH2J": + self.kh2_game_version = "EGS" + else: + if self.game_communication_path: + logger.info("Checking with most up to date addresses of github. If file is not found will be downloading datafiles. This might take a moment") + #if mem addresses file is found then check version and if old get new one + kh2memaddresses_path = os.path.join(self.game_communication_path, f"kh2memaddresses.json") + if not os.path.exists(kh2memaddresses_path): + mem_resp = requests.get("https://raw.githubusercontent.com/JaredWeakStrike/KH2APMemoryValues/master/kh2memaddresses.json") + if mem_resp.status_code == 200: + self.mem_json = json.loads(mem_resp.content) + with open(kh2memaddresses_path, + 'w') as f: + f.write(json.dumps(self.mem_json, indent=4)) + else: + with open(kh2memaddresses_path, 'r') as f: + self.mem_json = json.load(f) + if self.mem_json: + for key in self.mem_json.keys(): + + if self.kh2_read_string(eval(self.mem_json[key]["GameVersionCheck"]), 4) == "KH2J": + self.Now = eval(self.mem_json[key]["Now"]) + self.Save=eval(self.mem_json[key]["Save"]) + self.Slot1 = eval(self.mem_json[key]["Slot1"]) + self.Journal = eval(self.mem_json[key]["Journal"]) + self.Shop = eval(self.mem_json[key]["Shop"]) + self.kh2_game_version = key + + if self.kh2_game_version is not None: + logger.info(f"You are now auto-tracking {self.kh2_game_version}") + self.kh2connected = True + else: + logger.info("Your game version does not match what the client requires. Check in the " + "kingdom-hearts-2-final-mix channel for more information on correcting the game " + "version.") + self.kh2connected = False + def finishedGame(ctx: KH2Context): if ctx.kh2slotdata['FinalXemnas'] == 1: - if not ctx.final_xemnas and ctx.kh2_read_byte(ctx.Save + all_world_locations[LocationName.FinalXemnas].addrObtained) \ + if not ctx.final_xemnas and ctx.kh2_read_byte( + ctx.Save + all_world_locations[LocationName.FinalXemnas].addrObtained) \ & 0x1 << all_world_locations[LocationName.FinalXemnas].bitIndex > 0: ctx.final_xemnas = True # three proofs @@ -843,7 +891,8 @@ def finishedGame(ctx: KH2Context): for boss in ctx.kh2slotdata["hitlist"]: if boss in locations: ctx.hitlist_bounties += 1 - if ctx.hitlist_bounties >= ctx.kh2slotdata["BountyRequired"] or ctx.kh2_seed_save_cache["AmountInvo"]["Amount"]["Bounty"] >= ctx.kh2slotdata["BountyRequired"]: + if ctx.hitlist_bounties >= ctx.kh2slotdata["BountyRequired"] or ctx.kh2_seed_save_cache["AmountInvo"]["Amount"][ + "Bounty"] >= ctx.kh2slotdata["BountyRequired"]: if ctx.kh2_read_byte(ctx.Save + 0x36B3) < 1: ctx.kh2_write_byte(ctx.Save + 0x36B2, 1) ctx.kh2_write_byte(ctx.Save + 0x36B3, 1) @@ -894,24 +943,7 @@ async def kh2_watcher(ctx: KH2Context): while not ctx.kh2connected and ctx.serverconneced: await asyncio.sleep(15) ctx.kh2 = pymem.Pymem(process_name="KINGDOM HEARTS II FINAL MIX") - if ctx.kh2 is not None: - if ctx.kh2_game_version is None: - if ctx.kh2_read_string(0x09A9830, 4) == "KH2J": - ctx.kh2_game_version = "STEAM" - ctx.Now = 0x0717008 - ctx.Save = 0x09A9830 - ctx.Slot1 = 0x2A23518 - ctx.Journal = 0x7434E0 - ctx.Shop = 0x7435D0 - - elif ctx.kh2_read_string(0x09A92F0, 4) == "KH2J": - ctx.kh2_game_version = "EGS" - else: - ctx.kh2_game_version = None - logger.info("Your game version is out of date. Please update your game via The Epic Games Store or Steam.") - if ctx.kh2_game_version is not None: - logger.info(f"You are now auto-tracking {ctx.kh2_game_version}") - ctx.kh2connected = True + ctx.get_addresses() except Exception as e: if ctx.kh2connected: ctx.kh2connected = False diff --git a/worlds/kh2/Regions.py b/worlds/kh2/Regions.py index 7fc2ad8a873f..e6e8a7b2f663 100644 --- a/worlds/kh2/Regions.py +++ b/worlds/kh2/Regions.py @@ -540,7 +540,7 @@ LocationName.SephirothFenrir, LocationName.SephiEventLocation ], - RegionName.CoR: [ + RegionName.CoR: [ #todo: make logic for getting these checks. LocationName.CoRDepthsAPBoost, LocationName.CoRDepthsPowerCrystal, LocationName.CoRDepthsFrostCrystal, diff --git a/worlds/kh2/Rules.py b/worlds/kh2/Rules.py index 0f26b56d0e54..767c5643417e 100644 --- a/worlds/kh2/Rules.py +++ b/worlds/kh2/Rules.py @@ -194,8 +194,8 @@ def __init__(self, kh2world: KH2World) -> None: RegionName.Oc: lambda state: self.oc_unlocked(state, 1), RegionName.Oc2: lambda state: self.oc_unlocked(state, 2), + #twtnw1 is actually the roxas fight region thus roxas requires 1 way to the dawn RegionName.Twtnw2: lambda state: self.twtnw_unlocked(state, 2), - # These will be swapped and First Visit lock for twtnw is in development. # RegionName.Twtnw1: lambda state: self.lod_unlocked(state, 2), RegionName.Ht: lambda state: self.ht_unlocked(state, 1), @@ -919,8 +919,8 @@ def get_sephiroth_rules(self, state: CollectionState) -> bool: # normal:both gap closers,limit 5,reflera,guard,both 2 ground finishers,3 dodge roll,finishing plus # hard:1 gap closers,reflect, guard,both 1 ground finisher,2 dodge roll,finishing plus sephiroth_rules = { - "easy": self.kh2_dict_count(easy_sephiroth_tools, state) and self.kh2_can_reach(LocationName.Limitlvl5, state) and self.kh2_list_any_sum([donald_limit], state) >= 1, - "normal": self.kh2_dict_count(normal_sephiroth_tools, state) and self.kh2_can_reach(LocationName.Limitlvl5, state) and self.kh2_list_any_sum([donald_limit, gap_closer], state) >= 2, + "easy": self.kh2_dict_count(easy_sephiroth_tools, state) and self.kh2_can_reach(LocationName.Limitlvl5, state), + "normal": self.kh2_dict_count(normal_sephiroth_tools, state) and self.kh2_can_reach(LocationName.Limitlvl5, state) and self.kh2_list_any_sum([gap_closer], state) >= 1, "hard": self.kh2_dict_count(hard_sephiroth_tools, state) and self.kh2_list_any_sum([gap_closer, ground_finisher], state) >= 2, } return sephiroth_rules[self.fight_logic] diff --git a/worlds/kh2/docs/setup_en.md b/worlds/kh2/docs/setup_en.md index cb80ec609887..bee60bd36b18 100644 --- a/worlds/kh2/docs/setup_en.md +++ b/worlds/kh2/docs/setup_en.md @@ -52,7 +52,7 @@ After Installing the seed click "Mod Loader -> Build/Build and Run". Every slot

What the Mod Manager Should Look Like.

-![image](https://i.imgur.com/Si4oZ8w.png) +![image](https://i.imgur.com/N0WJ8Qn.png)

Using the KH2 Client

From 5a42c7067553995f9f630125a1860242452df4c7 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:00:47 +0100 Subject: [PATCH 0089/1218] Core: Fix worlds that rely on other worlds having their Entrances connected before connect_entrances, add unit test (#4530) * unit test that get all state is called with partial entrances before connect_entrances * fix the two worlds doing it * lol * unused import * Update test/general/test_entrances.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update test_entrances.py --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- test/general/test_entrances.py | 27 +++++++++++++++++++++++++++ worlds/alttp/Rules.py | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/test/general/test_entrances.py b/test/general/test_entrances.py index 72161dfbdebc..88362c8fa6d4 100644 --- a/test/general/test_entrances.py +++ b/test/general/test_entrances.py @@ -34,3 +34,30 @@ def get_entrance_name_to_source_and_target_dict(world: World): self.assertEqual( original_entrances, step_entrances, f"{game_name} modified entrances during {step}" ) + + def test_all_state_before_connect_entrances(self): + """Before connect_entrances, Entrance objects may be unconnected. + Thus, we test that get_all_state is performed with allow_partial_entrances if used before or during + connect_entrances.""" + + gen_steps = ("generate_early", "create_regions", "create_items", "set_rules", "connect_entrances") + + for game_name, world_type in AutoWorldRegister.world_types.items(): + with self.subTest("Game", game_name=game_name): + multiworld = setup_solo_multiworld(world_type, ()) + + original_get_all_state = multiworld.get_all_state + + def patched_get_all_state(use_cache: bool, allow_partial_entrances: bool = False): + self.assertTrue(allow_partial_entrances, ( + "Before the connect_entrances step finishes, other worlds might still have partial entrances. " + "As such, any call to get_all_state must use allow_partial_entrances = True." + )) + + return original_get_all_state(use_cache, allow_partial_entrances) + + multiworld.get_all_state = patched_get_all_state + + for step in gen_steps: + with self.subTest("Step", step=step): + call_all(multiworld, step) diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index 386e0b0e9e11..f13178c6c519 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -1125,7 +1125,7 @@ def set_trock_key_rules(world, player): for entrance in ['Turtle Rock Dark Room Staircase', 'Turtle Rock (Chain Chomp Room) (North)', 'Turtle Rock (Chain Chomp Room) (South)', 'Turtle Rock Entrance to Pokey Room', 'Turtle Rock (Pokey Room) (South)', 'Turtle Rock (Pokey Room) (North)', 'Turtle Rock Big Key Door']: set_rule(world.get_entrance(entrance, player), lambda state: False) - all_state = world.get_all_state(use_cache=False) + all_state = world.get_all_state(use_cache=False, allow_partial_entrances=True) all_state.reachable_regions[player] = set() # wipe reachable regions so that the locked doors actually work all_state.stale[player] = True From fa2816822b46a770417b745e97d0f25c42b3a9ac Mon Sep 17 00:00:00 2001 From: CookieCat <81494827+CookieCat45@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:45:11 -0500 Subject: [PATCH 0090/1218] AHIT: Fix broken link in setup guide (#4524) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/ahit/docs/setup_en.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/ahit/docs/setup_en.md b/worlds/ahit/docs/setup_en.md index 23b34907071c..167c6c2faa24 100644 --- a/worlds/ahit/docs/setup_en.md +++ b/worlds/ahit/docs/setup_en.md @@ -21,7 +21,7 @@ 3. Click the **Betas** tab. In the **Beta Participation** dropdown, select `tcplink`. - While it downloads, you can subscribe to the [Archipelago workshop mod.]((https://steamcommunity.com/sharedfiles/filedetails/?id=3026842601)) + While it downloads, you can subscribe to the [Archipelago workshop mod](https://steamcommunity.com/sharedfiles/filedetails/?id=3026842601). 4. Once the game finishes downloading, start it up. @@ -62,4 +62,4 @@ The level that the relic set unlocked will stay unlocked. ### When I start a new save file, the intro cinematic doesn't get skipped, Hat Kid's body is missing and the mod doesn't work! There is a bug on older versions of A Hat in Time that causes save file creation to fail to work properly -if you have too many save files. Delete them and it should fix the problem. \ No newline at end of file +if you have too many save files. Delete them and it should fix the problem. From bb0948154da8e3436ebd1ac9bbbc29ee230cc695 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Fri, 24 Jan 2025 12:42:31 -0500 Subject: [PATCH 0091/1218] TUNIC: Make the standard entrances get made with tuples instead of sets (#4546) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/tunic/regions.py | 46 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/worlds/tunic/regions.py b/worlds/tunic/regions.py index 93ec5640e0c2..8f5df8896ac9 100644 --- a/worlds/tunic/regions.py +++ b/worlds/tunic/regions.py @@ -1,26 +1,24 @@ -from typing import Dict, Set - -tunic_regions: Dict[str, Set[str]] = { - "Menu": {"Overworld"}, - "Overworld": {"Overworld Holy Cross", "East Forest", "Dark Tomb", "Beneath the Well", "West Garden", +tunic_regions: dict[str, tuple[str]] = { + "Menu": ("Overworld",), + "Overworld": ("Overworld Holy Cross", "East Forest", "Dark Tomb", "Beneath the Well", "West Garden", "Ruined Atoll", "Eastern Vault Fortress", "Beneath the Vault", "Quarry Back", "Quarry", "Swamp", - "Spirit Arena"}, - "Overworld Holy Cross": set(), - "East Forest": set(), - "Dark Tomb": {"West Garden"}, - "Beneath the Well": set(), - "West Garden": set(), - "Ruined Atoll": {"Frog's Domain", "Library"}, - "Frog's Domain": set(), - "Library": set(), - "Eastern Vault Fortress": {"Beneath the Vault"}, - "Beneath the Vault": {"Eastern Vault Fortress"}, - "Quarry Back": {"Quarry"}, - "Quarry": {"Monastery", "Lower Quarry"}, - "Monastery": set(), - "Lower Quarry": {"Rooted Ziggurat"}, - "Rooted Ziggurat": set(), - "Swamp": {"Cathedral"}, - "Cathedral": set(), - "Spirit Arena": set() + "Spirit Arena"), + "Overworld Holy Cross": tuple(), + "East Forest": tuple(), + "Dark Tomb": ("West Garden",), + "Beneath the Well": tuple(), + "West Garden": tuple(), + "Ruined Atoll": ("Frog's Domain", "Library"), + "Frog's Domain": tuple(), + "Library": tuple(), + "Eastern Vault Fortress": ("Beneath the Vault",), + "Beneath the Vault": ("Eastern Vault Fortress",), + "Quarry Back": ("Quarry",), + "Quarry": ("Monastery", "Lower Quarry"), + "Monastery": tuple(), + "Lower Quarry": ("Rooted Ziggurat",), + "Rooted Ziggurat": tuple(), + "Swamp": ("Cathedral",), + "Cathedral": tuple(), + "Spirit Arena": tuple() } From 7474c273729f68bc9f791626999e180cacbc6b46 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 24 Jan 2025 13:52:12 -0500 Subject: [PATCH 0092/1218] Core: Add launch function to call launch_subprocess only if multiprocessing is actually necessary (#4237) * skips opening a subprocess if kivy (and thus the launcher gui) hasn't been loaded so stdin can function as expected on --nogui and similar * this exists lol * keep old function around and use new function for CC component * fix name=None typing --- worlds/LauncherComponents.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index d1b274c19ae7..41c83db41995 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -87,7 +87,7 @@ def __repr__(self): processes = weakref.WeakSet() -def launch_subprocess(func: Callable, name: str = None, args: Tuple[str, ...] = ()) -> None: +def launch_subprocess(func: Callable, name: str | None = None, args: Tuple[str, ...] = ()) -> None: global processes import multiprocessing process = multiprocessing.Process(target=func, name=name, args=args) @@ -95,6 +95,14 @@ def launch_subprocess(func: Callable, name: str = None, args: Tuple[str, ...] = processes.add(process) +def launch(func: Callable, name: str | None = None, args: Tuple[str, ...] = ()) -> None: + from Utils import is_kivy_running + if is_kivy_running(): + launch_subprocess(func, name, args) + else: + func(*args) + + class SuffixIdentifier: suffixes: Iterable[str] @@ -111,7 +119,7 @@ def __call__(self, path: str) -> bool: def launch_textclient(*args): import CommonClient - launch_subprocess(CommonClient.run_as_textclient, name="TextClient", args=args) + launch(CommonClient.run_as_textclient, name="TextClient", args=args) def _install_apworld(apworld_src: str = "") -> Optional[Tuple[pathlib.Path, pathlib.Path]]: From 3d1d6908c8081f325659377e7d0dae4487badd07 Mon Sep 17 00:00:00 2001 From: Jasper den Brok Date: Fri, 24 Jan 2025 22:30:21 +0100 Subject: [PATCH 0093/1218] Pokemon Emerald: Add Free Fly Blacklist (#4165) Co-authored-by: Jasper den Brok --- worlds/pokemon_emerald/locations.py | 28 ++++++++++++++++------------ worlds/pokemon_emerald/options.py | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/worlds/pokemon_emerald/locations.py b/worlds/pokemon_emerald/locations.py index 473c189166be..2bae8e00ed34 100644 --- a/worlds/pokemon_emerald/locations.py +++ b/worlds/pokemon_emerald/locations.py @@ -33,6 +33,18 @@ "EVENT_VISITED_SOUTHERN_ISLAND": 17, } +BLACKLIST_OPTION_TO_VISITED_EVENT = { + "Slateport City": "EVENT_VISITED_SLATEPORT_CITY", + "Mauville City": "EVENT_VISITED_MAUVILLE_CITY", + "Verdanturf Town": "EVENT_VISITED_VERDANTURF_TOWN", + "Fallarbor Town": "EVENT_VISITED_FALLARBOR_TOWN", + "Lavaridge Town": "EVENT_VISITED_LAVARIDGE_TOWN", + "Fortree City": "EVENT_VISITED_FORTREE_CITY", + "Lilycove City": "EVENT_VISITED_LILYCOVE_CITY", + "Mossdeep City": "EVENT_VISITED_MOSSDEEP_CITY", + "Sootopolis City": "EVENT_VISITED_SOOTOPOLIS_CITY", + "Ever Grande City": "EVENT_VISITED_EVER_GRANDE_CITY", +} class PokemonEmeraldLocation(Location): game: str = "Pokemon Emerald" @@ -129,18 +141,10 @@ def set_free_fly(world: "PokemonEmeraldWorld") -> None: # If not enabled, set it to Littleroot Town by default fly_location_name = "EVENT_VISITED_LITTLEROOT_TOWN" if world.options.free_fly_location: - fly_location_name = world.random.choice([ - "EVENT_VISITED_SLATEPORT_CITY", - "EVENT_VISITED_MAUVILLE_CITY", - "EVENT_VISITED_VERDANTURF_TOWN", - "EVENT_VISITED_FALLARBOR_TOWN", - "EVENT_VISITED_LAVARIDGE_TOWN", - "EVENT_VISITED_FORTREE_CITY", - "EVENT_VISITED_LILYCOVE_CITY", - "EVENT_VISITED_MOSSDEEP_CITY", - "EVENT_VISITED_SOOTOPOLIS_CITY", - "EVENT_VISITED_EVER_GRANDE_CITY", - ]) + blacklisted_locations = set(BLACKLIST_OPTION_TO_VISITED_EVENT[city] for city in world.options.free_fly_blacklist.value) + free_fly_locations = sorted(set(BLACKLIST_OPTION_TO_VISITED_EVENT.values()) - blacklisted_locations) + if free_fly_locations: + fly_location_name = world.random.choice(free_fly_locations) world.free_fly_location_id = VISITED_EVENT_NAME_TO_ID[fly_location_name] diff --git a/worlds/pokemon_emerald/options.py b/worlds/pokemon_emerald/options.py index 8fcc74d1c34a..cf0c692d06d8 100644 --- a/worlds/pokemon_emerald/options.py +++ b/worlds/pokemon_emerald/options.py @@ -725,6 +725,24 @@ class FreeFlyLocation(Toggle): """ display_name = "Free Fly Location" +class FreeFlyBlacklist(OptionSet): + """ + Disables specific locations as valid free fly locations. + Has no effect if Free Fly Location is disabled. + """ + display_name = "Free Fly Blacklist" + valid_keys = [ + "Slateport City", + "Mauville City", + "Verdanturf Town", + "Fallarbor Town", + "Lavaridge Town", + "Fortree City", + "Lilycove City", + "Mossdeep City", + "Sootopolis City", + "Ever Grande City", + ] class HmRequirements(Choice): """ @@ -876,6 +894,7 @@ class PokemonEmeraldOptions(PerGameCommonOptions): extra_bumpy_slope: ExtraBumpySlope modify_118: ModifyRoute118 free_fly_location: FreeFlyLocation + free_fly_blacklist: FreeFlyBlacklist hm_requirements: HmRequirements turbo_a: TurboA From 3df2dbe051024df890f322280ee4373d4690c258 Mon Sep 17 00:00:00 2001 From: Silent <110704408+silent-destroyer@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:55:49 -0500 Subject: [PATCH 0094/1218] TUNIC: Add ability shuffle information to spoiler log (#4498) --- worlds/tunic/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 087e17c3e473..ed2923037eee 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Any, Tuple, TypedDict, ClassVar, Union, Set +from typing import Dict, List, Any, Tuple, TypedDict, ClassVar, Union, Set, TextIO from logging import warning from BaseClasses import Region, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState from .items import (item_name_to_id, item_table, item_name_groups, fool_tiers, filler_items, slot_data_item_names, @@ -502,6 +502,13 @@ def remove(self, state: CollectionState, item: Item) -> bool: state.tunic_need_to_reset_combat_from_remove[self.player] = True return change + def write_spoiler_header(self, spoiler_handle: TextIO): + if self.options.hexagon_quest and self.options.ability_shuffling: + spoiler_handle.write("\nAbility Unlocks (Hexagon Quest):\n") + for ability in self.ability_unlocks: + # Remove parentheses for better readability + spoiler_handle.write(f'{ability[ability.find("(")+1:ability.find(")")]}: {self.ability_unlocks[ability]} Gold Questagons\n') + def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]) -> None: if self.options.entrance_rando: hint_data.update({self.player: {}}) From ddf7fdccc718380e8611ab946ca5c529f897075b Mon Sep 17 00:00:00 2001 From: Silent <110704408+silent-destroyer@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:57:23 -0500 Subject: [PATCH 0095/1218] TUNIC: Add Torch Item (#4538) Co-authored-by: Scipio Wright --- worlds/tunic/items.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/tunic/items.py b/worlds/tunic/items.py index 729bfd441172..846650c68fef 100644 --- a/worlds/tunic/items.py +++ b/worlds/tunic/items.py @@ -48,6 +48,7 @@ class TunicItemData(NamedTuple): "Gun": TunicItemData(IC.progression | IC.useful, 1, 30, "Weapons"), "Shield": TunicItemData(IC.useful, 1, 31, combat_ic=IC.progression | IC.useful), "Dath Stone": TunicItemData(IC.useful, 1, 32), + "Torch": TunicItemData(IC.useful, 0, 156), "Hourglass": TunicItemData(IC.useful, 1, 33), "Old House Key": TunicItemData(IC.progression, 1, 34, "Keys"), "Key": TunicItemData(IC.progression, 2, 35, "Keys"), From 513e361764aea8a04e56010c6c47ee4bb53f5303 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Fri, 24 Jan 2025 17:10:58 -0500 Subject: [PATCH 0096/1218] TUNIC: Fix UT create_item classification (#4514) Co-authored-by: Silent <110704408+silent-destroyer@users.noreply.github.com> --- worlds/tunic/__init__.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index ed2923037eee..e86f731381e5 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -242,10 +242,18 @@ def stage_generate_early(cls, multiworld: MultiWorld) -> None: def create_item(self, name: str, classification: ItemClassification = None) -> TunicItem: item_data = item_table[name] - # if item_data.combat_ic is None, it'll take item_data.classification instead - itemclass: ItemClassification = ((item_data.combat_ic if self.options.combat_logic else None) + # evaluate alternate classifications based on options + # it'll choose whichever classification isn't None first in this if else tree + itemclass: ItemClassification = (classification + or (item_data.combat_ic if self.options.combat_logic else None) + or (ItemClassification.progression | ItemClassification.useful + if name == "Glass Cannon" and self.options.grass_randomizer + and not self.options.start_with_sword else None) + or (ItemClassification.progression | ItemClassification.useful + if name == "Shield" and self.options.ladder_storage + and not self.options.ladder_storage_without_items else None) or item_data.classification) - return TunicItem(name, classification or itemclass, self.item_name_to_id[name], self.player) + return TunicItem(name, itemclass, self.item_name_to_id[name], self.player) def create_items(self) -> None: tunic_items: List[TunicItem] = [] @@ -278,8 +286,6 @@ def create_items(self) -> None: if self.options.grass_randomizer: items_to_create["Grass"] = len(grass_location_table) - tunic_items.append(self.create_item("Glass Cannon", ItemClassification.progression)) - items_to_create["Glass Cannon"] = 0 for grass_location in excluded_grass_locations: self.get_location(grass_location).place_locked_item(self.create_item("Grass")) items_to_create["Grass"] -= len(excluded_grass_locations) @@ -351,11 +357,6 @@ def remove_filler(amount: int) -> None: tunic_items.append(self.create_item(page, ItemClassification.progression | ItemClassification.useful)) items_to_create[page] = 0 - # logically relevant if you have ladder storage enabled - if self.options.ladder_storage and not self.options.ladder_storage_without_items: - tunic_items.append(self.create_item("Shield", ItemClassification.progression)) - items_to_create["Shield"] = 0 - if self.options.maskless: tunic_items.append(self.create_item("Scavenger Mask", ItemClassification.useful)) items_to_create["Scavenger Mask"] = 0 From cc770418f2d1d5c88ec08f30ac45c05ea704445c Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 24 Jan 2025 23:22:33 +0100 Subject: [PATCH 0097/1218] MultiServer: optimize PrintJSON for !release (#4545) * MultiServer: optimize PrintJSON for !release * MultiServer: safer comparison Co-authored-by: Doug Hoskisson --------- Co-authored-by: Doug Hoskisson --- MultiServer.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 653c2ecaabb1..9e0868b0f4a8 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1060,21 +1060,37 @@ def send_items_to(ctx: Context, team: int, target_slot: int, *items: NetworkItem def register_location_checks(ctx: Context, team: int, slot: int, locations: typing.Iterable[int], count_activity: bool = True): + slot_locations = ctx.locations[slot] new_locations = set(locations) - ctx.location_checks[team, slot] - new_locations.intersection_update(ctx.locations[slot]) # ignore location IDs unknown to this multidata + new_locations.intersection_update(slot_locations) # ignore location IDs unknown to this multidata if new_locations: if count_activity: ctx.client_activity_timers[team, slot] = datetime.datetime.now(datetime.timezone.utc) + + sortable: list[tuple[int, int, int, int]] = [] for location in new_locations: - item_id, target_player, flags = ctx.locations[slot][location] + # extract all fields to avoid runtime overhead in LocationStore + item_id, target_player, flags = slot_locations[location] + # sort/group by receiver and item + sortable.append((target_player, item_id, location, flags)) + + info_texts: list[dict[str, typing.Any]] = [] + for target_player, item_id, location, flags in sorted(sortable): new_item = NetworkItem(item_id, location, slot, flags) send_items_to(ctx, team, target_player, new_item) ctx.logger.info('(Team #%d) %s sent %s to %s (%s)' % ( team + 1, ctx.player_names[(team, slot)], ctx.item_names[ctx.slot_info[target_player].game][item_id], ctx.player_names[(team, target_player)], ctx.location_names[ctx.slot_info[slot].game][location])) - info_text = json_format_send_event(new_item, target_player) - ctx.broadcast_team(team, [info_text]) + if len(info_texts) >= 140: + # split into chunks that are close to compression window of 64K but not too big on the wire + # (roughly 1300-2600 bytes after compression depending on repetitiveness) + ctx.broadcast_team(team, info_texts) + info_texts.clear() + info_texts.append(json_format_send_event(new_item, target_player)) + ctx.broadcast_team(team, info_texts) + del info_texts + del sortable ctx.location_checks[team, slot] |= new_locations send_new_items(ctx) From 86641223c12852d998d45638ea664317d29f8e25 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 24 Jan 2025 18:35:54 -0500 Subject: [PATCH 0098/1218] Shivers: Stop using get_all_state cache to fix timing issue #4522 Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- worlds/shivers/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/shivers/__init__.py b/worlds/shivers/__init__.py index 5c6203fd5761..85f2cf1861a7 100644 --- a/worlds/shivers/__init__.py +++ b/worlds/shivers/__init__.py @@ -245,7 +245,7 @@ def pre_fill(self) -> None: storage_items += [self.create_item("Empty") for _ in range(3)] - state = self.multiworld.get_all_state(True) + state = self.multiworld.get_all_state(False) self.random.shuffle(storage_locs) self.random.shuffle(storage_items) From 1832bac1a3c0e9b046c67271ee09601b26b0fe94 Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sat, 25 Jan 2025 06:35:42 -0800 Subject: [PATCH 0099/1218] BizHawkClient: Update README for `get_memory_size` (#4511) --- worlds/_bizhawk/README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/worlds/_bizhawk/README.md b/worlds/_bizhawk/README.md index ddc70c3dd748..9058fc30619c 100644 --- a/worlds/_bizhawk/README.md +++ b/worlds/_bizhawk/README.md @@ -55,6 +55,7 @@ async def lock(ctx) -> None async def unlock(ctx) -> None async def get_hash(ctx) -> str +async def get_memory_size(ctx, domain: str) -> int async def get_system(ctx) -> str async def get_cores(ctx) -> dict[str, str] async def ping(ctx) -> None @@ -168,9 +169,10 @@ select dialog and they will be associated with BizHawkClient. This does not affe associate the file extension with Archipelago. `validate_rom` is called to figure out whether a given ROM belongs to your client. It will only be called when a ROM is -running on a system you specified in your `system` class variable. In most cases, that will be a single system and you -can be sure that you're not about to try to read from nonexistent domains or out of bounds. If you decide to claim this -ROM as yours, this is where you should do setup for things like `items_handling`. +running on a system you specified in your `system` class variable. Take extra care here, because your code will run +against ROMs that you have no control over. If you're reading an address deep in ROM, you might want to check the size +of ROM before you attempt to read it using `get_memory_size`. If you decide to claim this ROM as yours, this is where +you should do setup for things like `items_handling`. `game_watcher` is the "main loop" of your client where you should be checking memory and sending new items to the ROM. `BizHawkClient` will make sure that your `game_watcher` only runs when your client has validated the ROM, and will do @@ -268,6 +270,8 @@ server connection before trying to interact with it. - By default, the player will be asked to provide their slot name after connecting to the server and validating, and that input will be used to authenticate with the `Connect` command. You can override `set_auth` in your own client to set it automatically based on data in the ROM or on your client instance. +- Use `get_memory_size` inside `validate_rom` if you need to read at large addresses, in case some other game has a +smaller ROM size. - You can override `on_package` in your client to watch raw packages, but don't forget you also have access to a subclass of `CommonContext` and its API. - You can import `BizHawkClientContext` for type hints using `typing.TYPE_CHECKING`. Importing it without conditions at From 96b941ed35cb5d34a44e261be6e00a7efd38175d Mon Sep 17 00:00:00 2001 From: josephwhite Date: Sat, 25 Jan 2025 09:36:23 -0500 Subject: [PATCH 0100/1218] Super Mario 64: Add Star Costs to Spoiler (#4544) --- worlds/sm64ex/__init__.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/worlds/sm64ex/__init__.py b/worlds/sm64ex/__init__.py index afa67f233c69..d54e0fc64d46 100644 --- a/worlds/sm64ex/__init__.py +++ b/worlds/sm64ex/__init__.py @@ -48,6 +48,17 @@ class SM64World(World): filler_count: int star_costs: typing.Dict[str, int] + # Spoiler specific variable(s) + star_costs_spoiler_key_maxlen = len(max([ + 'First Floor Big Star Door', + 'Basement Big Star Door', + 'Second Floor Big Star Door', + 'MIPS 1', + 'MIPS 2', + 'Endless Stairs', + ], key=len)) + + def generate_early(self): max_stars = 120 if (not self.options.enable_coin_stars): @@ -238,3 +249,19 @@ def extend_hint_information(self, hint_data: typing.Dict[int, typing.Dict[int, s for location in region.locations: er_hint_data[location.address] = entrance_name hint_data[self.player] = er_hint_data + + def write_spoiler(self, spoiler_handle: typing.TextIO) -> None: + # Write calculated star costs to spoiler. + star_cost_spoiler_header = '\n\n' + self.player_name + ' Star Costs for Super Mario 64:\n\n' + spoiler_handle.write(star_cost_spoiler_header) + # - Reformat star costs dictionary in spoiler to be a bit more readable. + star_costs_spoiler = {} + star_costs_copy = self.star_costs.copy() + star_costs_spoiler['First Floor Big Star Door'] = star_costs_copy['FirstBowserDoorCost'] + star_costs_spoiler['Basement Big Star Door'] = star_costs_copy['BasementDoorCost'] + star_costs_spoiler['Second Floor Big Star Door'] = star_costs_copy['SecondFloorDoorCost'] + star_costs_spoiler['MIPS 1'] = star_costs_copy['MIPS1Cost'] + star_costs_spoiler['MIPS 2'] = star_costs_copy['MIPS2Cost'] + star_costs_spoiler['Endless Stairs'] = star_costs_copy['StarsToFinish'] + for star, cost in star_costs_spoiler.items(): + spoiler_handle.write(f"{star:{self.star_costs_spoiler_key_maxlen}s} = {cost}\n") From 90417e002292b3982f8dff68fae4270bdbd9db5c Mon Sep 17 00:00:00 2001 From: qwint Date: Sun, 26 Jan 2025 07:06:27 -0500 Subject: [PATCH 0101/1218] CommonClient: Expand on make_gui docstring (#4449) * adds docstring to make_gui describing what things you might want to change without dealing with kivy/kvui directly (there are better places to document those) * Update CommonClient.py Co-authored-by: Doug Hoskisson * Update CommonClient.py Co-authored-by: Doug Hoskisson --------- Co-authored-by: Doug Hoskisson --- CommonClient.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index f6b2623f8c02..996ba3300575 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -709,8 +709,16 @@ def handle_connection_loss(self, msg: str) -> None: logger.exception(msg, exc_info=exc_info, extra={'compact_gui': True}) self._messagebox_connection_loss = self.gui_error(msg, exc_info[1]) - def make_gui(self) -> typing.Type["kvui.GameManager"]: - """To return the Kivy App class needed for run_gui so it can be overridden before being built""" + def make_gui(self) -> "type[kvui.GameManager]": + """ + To return the Kivy `App` class needed for `run_gui` so it can be overridden before being built + + Common changes are changing `base_title` to update the window title of the client and + updating `logging_pairs` to automatically make new tabs that can be filled with their respective logger. + + ex. `logging_pairs.append(("Foo", "Bar"))` + will add a "Bar" tab which follows the logger returned from `logging.getLogger("Foo")` + """ from kvui import GameManager class TextManager(GameManager): From 8622cb62040e1da2d1d3c66cb1563f76bddb57f9 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 26 Jan 2025 22:14:39 +0100 Subject: [PATCH 0102/1218] Factorio: Inventory Spill Traps (#4457) --- worlds/factorio/Options.py | 7 ++++ worlds/factorio/__init__.py | 22 +++++------ worlds/factorio/data/mod/lib.lua | 37 +++++++++++++++++++ worlds/factorio/data/mod_template/control.lua | 5 +++ 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/worlds/factorio/Options.py b/worlds/factorio/Options.py index 0fa75e1b8bfa..4848cd992664 100644 --- a/worlds/factorio/Options.py +++ b/worlds/factorio/Options.py @@ -304,6 +304,11 @@ class EvolutionTrapIncrease(Range): range_end = 100 +class InventorySpillTrapCount(TrapCount): + """Trap items that when received trigger dropping your main inventory and trash inventory onto the ground.""" + display_name = "Inventory Spill Traps" + + class FactorioWorldGen(OptionDict): """World Generation settings. Overview of options at https://wiki.factorio.com/Map_generator, with in-depth documentation at https://lua-api.factorio.com/latest/Concepts.html#MapGenSettings""" @@ -484,6 +489,7 @@ class FactorioOptions(PerGameCommonOptions): artillery_traps: ArtilleryTrapCount atomic_rocket_traps: AtomicRocketTrapCount atomic_cliff_remover_traps: AtomicCliffRemoverTrapCount + inventory_spill_traps: InventorySpillTrapCount attack_traps: AttackTrapCount evolution_traps: EvolutionTrapCount evolution_trap_increase: EvolutionTrapIncrease @@ -518,6 +524,7 @@ class FactorioOptions(PerGameCommonOptions): ArtilleryTrapCount, AtomicRocketTrapCount, AtomicCliffRemoverTrapCount, + InventorySpillTrapCount, ], start_collapsed=True ), diff --git a/worlds/factorio/__init__.py b/worlds/factorio/__init__.py index a2bc518ae3fd..ca9f12f1b21a 100644 --- a/worlds/factorio/__init__.py +++ b/worlds/factorio/__init__.py @@ -78,6 +78,7 @@ class FactorioItem(Item): all_items["Artillery Trap"] = factorio_base_id - 6 all_items["Atomic Rocket Trap"] = factorio_base_id - 7 all_items["Atomic Cliff Remover Trap"] = factorio_base_id - 8 +all_items["Inventory Spill Trap"] = factorio_base_id - 9 class Factorio(World): @@ -112,6 +113,8 @@ class Factorio(World): science_locations: typing.List[FactorioScienceLocation] removed_technologies: typing.Set[str] settings: typing.ClassVar[FactorioSettings] + trap_names: tuple[str] = ("Evolution", "Attack", "Teleport", "Grenade", "Cluster Grenade", "Artillery", + "Atomic Rocket", "Atomic Cliff Remover", "Inventory Spill") def __init__(self, world, player: int): super(Factorio, self).__init__(world, player) @@ -136,15 +139,11 @@ def create_regions(self): random = self.random nauvis = Region("Nauvis", player, self.multiworld) - location_count = len(base_tech_table) - len(useless_technologies) - self.skip_silo + \ - self.options.evolution_traps + \ - self.options.attack_traps + \ - self.options.teleport_traps + \ - self.options.grenade_traps + \ - self.options.cluster_grenade_traps + \ - self.options.atomic_rocket_traps + \ - self.options.atomic_cliff_remover_traps + \ - self.options.artillery_traps + location_count = len(base_tech_table) - len(useless_technologies) - self.skip_silo + + for name in self.trap_names: + name = name.replace(" ", "_").lower()+"_traps" + location_count += getattr(self.options, name) location_pool = [] @@ -196,9 +195,8 @@ def sorter(loc: FactorioScienceLocation): def create_items(self) -> None: self.custom_technologies = self.set_custom_technologies() self.set_custom_recipes() - traps = ("Evolution", "Attack", "Teleport", "Grenade", "Cluster Grenade", "Artillery", "Atomic Rocket", - "Atomic Cliff Remover") - for trap_name in traps: + + for trap_name in self.trap_names: self.multiworld.itempool.extend(self.create_item(f"{trap_name} Trap") for _ in range(getattr(self.options, f"{trap_name.lower().replace(' ', '_')}_traps"))) diff --git a/worlds/factorio/data/mod/lib.lua b/worlds/factorio/data/mod/lib.lua index 517a54e3d642..edec5b7acdc0 100644 --- a/worlds/factorio/data/mod/lib.lua +++ b/worlds/factorio/data/mod/lib.lua @@ -48,3 +48,40 @@ function fire_entity_at_entities(entity_name, entities, speed) target=target, speed=speed} end end + +function spill_character_inventory(character) + if not (character and character.valid) then + return false + end + + -- grab attrs once pre-loop + local position = character.position + local surface = character.surface + + local inventories_to_spill = { + defines.inventory.character_main, -- Main inventory + defines.inventory.character_trash, -- Logistic trash slots + } + + for _, inventory_type in pairs(inventories_to_spill) do + local inventory = character.get_inventory(inventory_type) + if inventory and inventory.valid then + -- Spill each item stack onto the ground + for i = 1, #inventory do + local stack = inventory[i] + if stack and stack.valid_for_read then + local spilled_items = surface.spill_item_stack{ + position = position, + stack = stack, + enable_looted = false, -- do not mark for auto-pickup + force = nil, -- do not mark for auto-deconstruction + allow_belts = true, -- do mark for putting it onto belts + } + if #spilled_items > 0 then + stack.clear() -- only delete if spilled successfully + end + end + end + end + end +end diff --git a/worlds/factorio/data/mod_template/control.lua b/worlds/factorio/data/mod_template/control.lua index 87669beaf199..07fd4c04afae 100644 --- a/worlds/factorio/data/mod_template/control.lua +++ b/worlds/factorio/data/mod_template/control.lua @@ -750,6 +750,11 @@ end, fire_entity_at_entities("atomic-rocket", {cliffs[math.random(#cliffs)]}, 0.1) end end, +["Inventory Spill Trap"] = function () + for _, player in ipairs(game.forces["player"].players) do + spill_character_inventory(player.character) + end +end, } commands.add_command("ap-get-technology", "Grant a technology, used by the Archipelago Client.", function(call) From 57a571cc110a0df310f0debc2a6fbbb9ea9304ca Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Sun, 26 Jan 2025 18:52:02 -0600 Subject: [PATCH 0103/1218] KDL3: Fix world access on non-strict open world (#4543) * Update rules.py * lambda capture --- worlds/kdl3/rules.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/worlds/kdl3/rules.py b/worlds/kdl3/rules.py index a08e99257e17..828740859e9b 100644 --- a/worlds/kdl3/rules.py +++ b/worlds/kdl3/rules.py @@ -206,19 +206,19 @@ def set_rules(world: "KDL3World") -> None: lambda state: can_reach_needle(state, world.player)) set_rule(world.multiworld.get_location(location_name.sand_canyon_5_u2, world.player), lambda state: can_reach_ice(state, world.player) and - (can_reach_rick(state, world.player) or can_reach_coo(state, world.player) - or can_reach_chuchu(state, world.player) or can_reach_pitch(state, world.player) - or can_reach_nago(state, world.player))) + (can_reach_rick(state, world.player) or can_reach_coo(state, world.player) + or can_reach_chuchu(state, world.player) or can_reach_pitch(state, world.player) + or can_reach_nago(state, world.player))) set_rule(world.multiworld.get_location(location_name.sand_canyon_5_u3, world.player), lambda state: can_reach_ice(state, world.player) and - (can_reach_rick(state, world.player) or can_reach_coo(state, world.player) - or can_reach_chuchu(state, world.player) or can_reach_pitch(state, world.player) - or can_reach_nago(state, world.player))) + (can_reach_rick(state, world.player) or can_reach_coo(state, world.player) + or can_reach_chuchu(state, world.player) or can_reach_pitch(state, world.player) + or can_reach_nago(state, world.player))) set_rule(world.multiworld.get_location(location_name.sand_canyon_5_u4, world.player), lambda state: can_reach_ice(state, world.player) and - (can_reach_rick(state, world.player) or can_reach_coo(state, world.player) - or can_reach_chuchu(state, world.player) or can_reach_pitch(state, world.player) - or can_reach_nago(state, world.player))) + (can_reach_rick(state, world.player) or can_reach_coo(state, world.player) + or can_reach_chuchu(state, world.player) or can_reach_pitch(state, world.player) + or can_reach_nago(state, world.player))) set_rule(world.multiworld.get_location(location_name.cloudy_park_6_u1, world.player), lambda state: can_reach_cutter(state, world.player)) @@ -248,9 +248,9 @@ def set_rules(world: "KDL3World") -> None: for i in range(12, 18): set_rule(world.multiworld.get_location(f"Sand Canyon 5 - Star {i}", world.player), lambda state: can_reach_ice(state, world.player) and - (can_reach_rick(state, world.player) or can_reach_coo(state, world.player) - or can_reach_chuchu(state, world.player) or can_reach_pitch(state, world.player) - or can_reach_nago(state, world.player))) + (can_reach_rick(state, world.player) or can_reach_coo(state, world.player) + or can_reach_chuchu(state, world.player) or can_reach_pitch(state, world.player) + or can_reach_nago(state, world.player))) for i in range(21, 23): set_rule(world.multiworld.get_location(f"Sand Canyon 5 - Star {i}", world.player), lambda state: can_reach_chuchu(state, world.player)) @@ -307,7 +307,7 @@ def set_rules(world: "KDL3World") -> None: lambda state: can_reach_coo(state, world.player) and can_reach_burning(state, world.player)) set_rule(world.multiworld.get_location(animal_friend_spawns.iceberg_4_a3, world.player), lambda state: can_reach_chuchu(state, world.player) and can_reach_coo(state, world.player) - and can_reach_burning(state, world.player)) + and can_reach_burning(state, world.player)) for boss_flag, purification, i in zip(["Level 1 Boss - Purified", "Level 2 Boss - Purified", "Level 3 Boss - Purified", "Level 4 Boss - Purified", @@ -329,6 +329,14 @@ def set_rules(world: "KDL3World") -> None: world.options.ow_boss_requirement.value, world.player_levels))) + if world.options.open_world: + for boss_flag, level in zip(["Level 1 Boss - Defeated", "Level 2 Boss - Defeated", "Level 3 Boss - Defeated", + "Level 4 Boss - Defeated", "Level 5 Boss - Defeated"], + location_name.level_names.keys()): + set_rule(world.get_location(boss_flag), + lambda state, lvl=level: state.has(f"{lvl} - Stage Completion", world.player, + world.options.ow_boss_requirement.value)) + set_rule(world.multiworld.get_entrance("To Level 6", world.player), lambda state: state.has("Heart Star", world.player, world.required_heart_stars)) From c43233120a828b4c89ee6c8ce1352c396fbe7266 Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Mon, 27 Jan 2025 07:24:26 -0800 Subject: [PATCH 0104/1218] Pokemon Emerald: Clarify death link and start inventory descriptions (#4517) --- worlds/pokemon_emerald/__init__.py | 3 ++- worlds/pokemon_emerald/options.py | 27 +++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/worlds/pokemon_emerald/__init__.py b/worlds/pokemon_emerald/__init__.py index 7b62b9ef73b1..50d6279179d9 100644 --- a/worlds/pokemon_emerald/__init__.py +++ b/worlds/pokemon_emerald/__init__.py @@ -22,7 +22,7 @@ set_free_fly, set_legendary_cave_entrances) from .opponents import randomize_opponent_parties from .options import (Goal, DarkCavesRequireFlash, HmRequirements, ItemPoolType, PokemonEmeraldOptions, - RandomizeWildPokemon, RandomizeBadges, RandomizeHms, NormanRequirement) + RandomizeWildPokemon, RandomizeBadges, RandomizeHms, NormanRequirement, OPTION_GROUPS) from .pokemon import (get_random_move, get_species_id_by_label, randomize_abilities, randomize_learnsets, randomize_legendary_encounters, randomize_misc_pokemon, randomize_starters, randomize_tm_hm_compatibility,randomize_types, randomize_wild_encounters) @@ -63,6 +63,7 @@ class PokemonEmeraldWebWorld(WebWorld): ) tutorials = [setup_en, setup_es, setup_sv] + option_groups = OPTION_GROUPS class PokemonEmeraldSettings(settings.Group): diff --git a/worlds/pokemon_emerald/options.py b/worlds/pokemon_emerald/options.py index cf0c692d06d8..32644d52e0b6 100644 --- a/worlds/pokemon_emerald/options.py +++ b/worlds/pokemon_emerald/options.py @@ -4,7 +4,7 @@ from dataclasses import dataclass from Options import (Choice, DeathLink, DefaultOnToggle, OptionSet, NamedRange, Range, Toggle, FreeText, - PerGameCommonOptions) + PerGameCommonOptions, OptionGroup, StartInventory) from .data import data @@ -803,6 +803,10 @@ class RandomizeFanfares(Toggle): display_name = "Randomize Fanfares" +class PokemonEmeraldDeathLink(DeathLink): + __doc__ = DeathLink.__doc__ + "\n\n In Pokemon Emerald, whiting out sends a death and receiving a death causes you to white out." + + class WonderTrading(DefaultOnToggle): """ Allows participation in wonder trading with other players in your current multiworld. Speak with the center receptionist on the second floor of any pokecenter. @@ -828,6 +832,14 @@ class EasterEgg(FreeText): default = "EMERALD SECRET" +class PokemonEmeraldStartInventory(StartInventory): + """ + Start with these items. + + They will be in your PC, which you can access from your home or a pokemon center. + """ + + @dataclass class PokemonEmeraldOptions(PerGameCommonOptions): goal: Goal @@ -904,7 +916,18 @@ class PokemonEmeraldOptions(PerGameCommonOptions): music: RandomizeMusic fanfares: RandomizeFanfares - death_link: DeathLink + death_link: PokemonEmeraldDeathLink enable_wonder_trading: WonderTrading easter_egg: EasterEgg + + start_inventory: PokemonEmeraldStartInventory + + +OPTION_GROUPS = [ + OptionGroup( + "Item & Location Options", [ + PokemonEmeraldStartInventory, + ], True, + ), +] From b570aa2ec6c811db280a835827aa3983f145a1a6 Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Mon, 27 Jan 2025 07:25:31 -0800 Subject: [PATCH 0105/1218] Pokemon Emerald: Clean up free fly blacklist (#4552) --- worlds/pokemon_emerald/locations.py | 10 +++++++++- worlds/pokemon_emerald/options.py | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/worlds/pokemon_emerald/locations.py b/worlds/pokemon_emerald/locations.py index 2bae8e00ed34..49ce147041ee 100644 --- a/worlds/pokemon_emerald/locations.py +++ b/worlds/pokemon_emerald/locations.py @@ -34,6 +34,11 @@ } BLACKLIST_OPTION_TO_VISITED_EVENT = { + "Littleroot Town": "EVENT_VISITED_LITTLEROOT_TOWN", + "Oldale Town": "EVENT_VISITED_OLDALE_TOWN", + "Petalburg City": "EVENT_VISITED_PETALBURG_CITY", + "Rustboro City": "EVENT_VISITED_RUSTBORO_CITY", + "Dewford Town": "EVENT_VISITED_DEWFORD_TOWN", "Slateport City": "EVENT_VISITED_SLATEPORT_CITY", "Mauville City": "EVENT_VISITED_MAUVILLE_CITY", "Verdanturf Town": "EVENT_VISITED_VERDANTURF_TOWN", @@ -46,6 +51,9 @@ "Ever Grande City": "EVENT_VISITED_EVER_GRANDE_CITY", } +VISITED_EVENTS = frozenset(BLACKLIST_OPTION_TO_VISITED_EVENT.values()) + + class PokemonEmeraldLocation(Location): game: str = "Pokemon Emerald" item_address: Optional[int] @@ -142,7 +150,7 @@ def set_free_fly(world: "PokemonEmeraldWorld") -> None: fly_location_name = "EVENT_VISITED_LITTLEROOT_TOWN" if world.options.free_fly_location: blacklisted_locations = set(BLACKLIST_OPTION_TO_VISITED_EVENT[city] for city in world.options.free_fly_blacklist.value) - free_fly_locations = sorted(set(BLACKLIST_OPTION_TO_VISITED_EVENT.values()) - blacklisted_locations) + free_fly_locations = sorted(VISITED_EVENTS - blacklisted_locations) if free_fly_locations: fly_location_name = world.random.choice(free_fly_locations) diff --git a/worlds/pokemon_emerald/options.py b/worlds/pokemon_emerald/options.py index 32644d52e0b6..29929bd67237 100644 --- a/worlds/pokemon_emerald/options.py +++ b/worlds/pokemon_emerald/options.py @@ -725,13 +725,20 @@ class FreeFlyLocation(Toggle): """ display_name = "Free Fly Location" + class FreeFlyBlacklist(OptionSet): """ Disables specific locations as valid free fly locations. + Has no effect if Free Fly Location is disabled. """ display_name = "Free Fly Blacklist" valid_keys = [ + "Littleroot Town", + "Oldale Town", + "Petalburg City", + "Rustboro City", + "Dewford Town", "Slateport City", "Mauville City", "Verdanturf Town", @@ -743,6 +750,14 @@ class FreeFlyBlacklist(OptionSet): "Sootopolis City", "Ever Grande City", ] + default = [ + "Littleroot Town", + "Oldale Town", + "Petalburg City", + "Rustboro City", + "Dewford Town", + ] + class HmRequirements(Choice): """ From 43874b1d28fa8d5a5bdc96d4408e303f57763ddd Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 27 Jan 2025 10:27:43 -0500 Subject: [PATCH 0106/1218] Noita: Add clarification to check option descriptions (#4553) --- worlds/noita/options.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/worlds/noita/options.py b/worlds/noita/options.py index 0fdd62365a5a..8a973a0d7229 100644 --- a/worlds/noita/options.py +++ b/worlds/noita/options.py @@ -20,6 +20,8 @@ class PathOption(Choice): class HiddenChests(Range): """ Number of hidden chest checks added to the applicable biomes. + Note: The number of hidden chests that spawn per run in each biome varies. + You are expected do multiple runs to get all of your checks. """ display_name = "Hidden Chests per Biome" range_start = 0 @@ -30,6 +32,8 @@ class HiddenChests(Range): class PedestalChecks(Range): """ Number of checks that will spawn on pedestals in the applicable biomes. + Note: The number of pedestals that spawn per run in each biome varies. + You are expected do multiple runs to get all of your checks. """ display_name = "Pedestal Checks per Biome" range_start = 0 From 41055cd963c183244e262344e03d6ae6369fc52a Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Mon, 27 Jan 2025 08:01:18 -0800 Subject: [PATCH 0107/1218] Pokemon Emerald: Update changelog (#4551) --- worlds/pokemon_emerald/CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/worlds/pokemon_emerald/CHANGELOG.md b/worlds/pokemon_emerald/CHANGELOG.md index 0dd874b25029..8d33d7090044 100644 --- a/worlds/pokemon_emerald/CHANGELOG.md +++ b/worlds/pokemon_emerald/CHANGELOG.md @@ -1,3 +1,16 @@ +# 2.4.0 + +### Features + +- New option `free_fly_blacklist` limits which cities can show up as a free fly location. +- Spoiler log and hint text for maps where a species can be found now use human-friendly labels. +- Added many item and location groups based on item type, location type, and location geography. + +### Fixes + +- Now excludes the location "Navel Rock Top - Hidden Item Sacred Ash" if your goal is Champion and you didn't randomize +event tickets. + # 2.3.0 ### Features From 8c5592e40684af4b9ac855e1a3b4b6e69622bffb Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:06:10 -0500 Subject: [PATCH 0108/1218] KH2: Fix determinism by using tuples instead of sets (#4548) --- worlds/kh2/Regions.py | 176 +++++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/worlds/kh2/Regions.py b/worlds/kh2/Regions.py index e6e8a7b2f663..72b3c95b0947 100644 --- a/worlds/kh2/Regions.py +++ b/worlds/kh2/Regions.py @@ -1032,99 +1032,99 @@ def connect_regions(self): multiworld = self.multiworld player = self.player # connecting every first visit to the GoA - KH2RegionConnections: typing.Dict[str, typing.Set[str]] = { - "Menu": {RegionName.GoA}, - RegionName.GoA: {RegionName.Sp, RegionName.Pr, RegionName.Tt, RegionName.Oc, RegionName.Ht, + KH2RegionConnections: typing.Dict[str, typing.Tuple[str]] = { + "Menu": (RegionName.GoA,), + RegionName.GoA: (RegionName.Sp, RegionName.Pr, RegionName.Tt, RegionName.Oc, RegionName.Ht, RegionName.LoD, RegionName.Twtnw, RegionName.Bc, RegionName.Ag, RegionName.Pl, RegionName.Hb, RegionName.Dc, RegionName.Stt, RegionName.Ha1, RegionName.Keyblade, RegionName.LevelsVS1, RegionName.Valor, RegionName.Wisdom, RegionName.Limit, RegionName.Master, - RegionName.Final, RegionName.Summon, RegionName.AtlanticaSongOne}, - RegionName.LoD: {RegionName.ShanYu}, - RegionName.ShanYu: {RegionName.LoD2}, - RegionName.LoD2: {RegionName.AnsemRiku}, - RegionName.AnsemRiku: {RegionName.StormRider}, - RegionName.StormRider: {RegionName.DataXigbar}, - RegionName.Ag: {RegionName.TwinLords}, - RegionName.TwinLords: {RegionName.Ag2}, - RegionName.Ag2: {RegionName.GenieJafar}, - RegionName.GenieJafar: {RegionName.DataLexaeus}, - RegionName.Dc: {RegionName.Tr}, - RegionName.Tr: {RegionName.OldPete}, - RegionName.OldPete: {RegionName.FuturePete}, - RegionName.FuturePete: {RegionName.Terra, RegionName.DataMarluxia}, - RegionName.Ha1: {RegionName.Ha2}, - RegionName.Ha2: {RegionName.Ha3}, - RegionName.Ha3: {RegionName.Ha4}, - RegionName.Ha4: {RegionName.Ha5}, - RegionName.Ha5: {RegionName.Ha6}, - RegionName.Pr: {RegionName.Barbosa}, - RegionName.Barbosa: {RegionName.Pr2}, - RegionName.Pr2: {RegionName.GrimReaper1}, - RegionName.GrimReaper1: {RegionName.GrimReaper2}, - RegionName.GrimReaper2: {RegionName.DataLuxord}, - RegionName.Oc: {RegionName.Cerberus}, - RegionName.Cerberus: {RegionName.OlympusPete}, - RegionName.OlympusPete: {RegionName.Hydra}, - RegionName.Hydra: {RegionName.OcPainAndPanicCup, RegionName.OcCerberusCup, RegionName.Oc2}, - RegionName.Oc2: {RegionName.Hades}, - RegionName.Hades: {RegionName.Oc2TitanCup, RegionName.Oc2GofCup, RegionName.DataZexion}, - RegionName.Oc2GofCup: {RegionName.HadesCups}, - RegionName.Bc: {RegionName.Thresholder}, - RegionName.Thresholder: {RegionName.Beast}, - RegionName.Beast: {RegionName.DarkThorn}, - RegionName.DarkThorn: {RegionName.Bc2}, - RegionName.Bc2: {RegionName.Xaldin}, - RegionName.Xaldin: {RegionName.DataXaldin}, - RegionName.Sp: {RegionName.HostileProgram}, - RegionName.HostileProgram: {RegionName.Sp2}, - RegionName.Sp2: {RegionName.Mcp}, - RegionName.Mcp: {RegionName.DataLarxene}, - RegionName.Ht: {RegionName.PrisonKeeper}, - RegionName.PrisonKeeper: {RegionName.OogieBoogie}, - RegionName.OogieBoogie: {RegionName.Ht2}, - RegionName.Ht2: {RegionName.Experiment}, - RegionName.Experiment: {RegionName.DataVexen}, - RegionName.Hb: {RegionName.Hb2}, - RegionName.Hb2: {RegionName.CoR, RegionName.HBDemyx}, - RegionName.HBDemyx: {RegionName.ThousandHeartless}, - RegionName.ThousandHeartless: {RegionName.Mushroom13, RegionName.DataDemyx, RegionName.Sephi}, - RegionName.CoR: {RegionName.CorFirstFight}, - RegionName.CorFirstFight: {RegionName.CorSecondFight}, - RegionName.CorSecondFight: {RegionName.Transport}, - RegionName.Pl: {RegionName.Scar}, - RegionName.Scar: {RegionName.Pl2}, - RegionName.Pl2: {RegionName.GroundShaker}, - RegionName.GroundShaker: {RegionName.DataSaix}, - RegionName.Stt: {RegionName.TwilightThorn}, - RegionName.TwilightThorn: {RegionName.Axel1}, - RegionName.Axel1: {RegionName.Axel2}, - RegionName.Axel2: {RegionName.DataRoxas}, - RegionName.Tt: {RegionName.Tt2}, - RegionName.Tt2: {RegionName.Tt3}, - RegionName.Tt3: {RegionName.DataAxel}, - RegionName.Twtnw: {RegionName.Roxas}, - RegionName.Roxas: {RegionName.Xigbar}, - RegionName.Xigbar: {RegionName.Luxord}, - RegionName.Luxord: {RegionName.Saix}, - RegionName.Saix: {RegionName.Twtnw2}, - RegionName.Twtnw2: {RegionName.Xemnas}, - RegionName.Xemnas: {RegionName.ArmoredXemnas, RegionName.DataXemnas}, - RegionName.ArmoredXemnas: {RegionName.ArmoredXemnas2}, - RegionName.ArmoredXemnas2: {RegionName.FinalXemnas}, - RegionName.LevelsVS1: {RegionName.LevelsVS3}, - RegionName.LevelsVS3: {RegionName.LevelsVS6}, - RegionName.LevelsVS6: {RegionName.LevelsVS9}, - RegionName.LevelsVS9: {RegionName.LevelsVS12}, - RegionName.LevelsVS12: {RegionName.LevelsVS15}, - RegionName.LevelsVS15: {RegionName.LevelsVS18}, - RegionName.LevelsVS18: {RegionName.LevelsVS21}, - RegionName.LevelsVS21: {RegionName.LevelsVS24}, - RegionName.LevelsVS24: {RegionName.LevelsVS26}, - RegionName.AtlanticaSongOne: {RegionName.AtlanticaSongTwo}, - RegionName.AtlanticaSongTwo: {RegionName.AtlanticaSongThree}, - RegionName.AtlanticaSongThree: {RegionName.AtlanticaSongFour}, + RegionName.Final, RegionName.Summon, RegionName.AtlanticaSongOne), + RegionName.LoD: (RegionName.ShanYu,), + RegionName.ShanYu: (RegionName.LoD2,), + RegionName.LoD2: (RegionName.AnsemRiku,), + RegionName.AnsemRiku: (RegionName.StormRider,), + RegionName.StormRider: (RegionName.DataXigbar,), + RegionName.Ag: (RegionName.TwinLords,), + RegionName.TwinLords: (RegionName.Ag2,), + RegionName.Ag2: (RegionName.GenieJafar,), + RegionName.GenieJafar: (RegionName.DataLexaeus,), + RegionName.Dc: (RegionName.Tr,), + RegionName.Tr: (RegionName.OldPete,), + RegionName.OldPete: (RegionName.FuturePete,), + RegionName.FuturePete: (RegionName.Terra, RegionName.DataMarluxia), + RegionName.Ha1: (RegionName.Ha2,), + RegionName.Ha2: (RegionName.Ha3,), + RegionName.Ha3: (RegionName.Ha4,), + RegionName.Ha4: (RegionName.Ha5,), + RegionName.Ha5: (RegionName.Ha6,), + RegionName.Pr: (RegionName.Barbosa,), + RegionName.Barbosa: (RegionName.Pr2,), + RegionName.Pr2: (RegionName.GrimReaper1,), + RegionName.GrimReaper1: (RegionName.GrimReaper2,), + RegionName.GrimReaper2: (RegionName.DataLuxord,), + RegionName.Oc: (RegionName.Cerberus,), + RegionName.Cerberus: (RegionName.OlympusPete,), + RegionName.OlympusPete: (RegionName.Hydra,), + RegionName.Hydra: (RegionName.OcPainAndPanicCup, RegionName.OcCerberusCup, RegionName.Oc2), + RegionName.Oc2: (RegionName.Hades,), + RegionName.Hades: (RegionName.Oc2TitanCup, RegionName.Oc2GofCup, RegionName.DataZexion), + RegionName.Oc2GofCup: (RegionName.HadesCups,), + RegionName.Bc: (RegionName.Thresholder,), + RegionName.Thresholder: (RegionName.Beast,), + RegionName.Beast: (RegionName.DarkThorn,), + RegionName.DarkThorn: (RegionName.Bc2,), + RegionName.Bc2: (RegionName.Xaldin,), + RegionName.Xaldin: (RegionName.DataXaldin,), + RegionName.Sp: (RegionName.HostileProgram,), + RegionName.HostileProgram: (RegionName.Sp2,), + RegionName.Sp2: (RegionName.Mcp,), + RegionName.Mcp: (RegionName.DataLarxene,), + RegionName.Ht: (RegionName.PrisonKeeper,), + RegionName.PrisonKeeper: (RegionName.OogieBoogie,), + RegionName.OogieBoogie: (RegionName.Ht2,), + RegionName.Ht2: (RegionName.Experiment,), + RegionName.Experiment: (RegionName.DataVexen,), + RegionName.Hb: (RegionName.Hb2,), + RegionName.Hb2: (RegionName.CoR, RegionName.HBDemyx), + RegionName.HBDemyx: (RegionName.ThousandHeartless,), + RegionName.ThousandHeartless: (RegionName.Mushroom13, RegionName.DataDemyx, RegionName.Sephi), + RegionName.CoR: (RegionName.CorFirstFight,), + RegionName.CorFirstFight: (RegionName.CorSecondFight,), + RegionName.CorSecondFight: (RegionName.Transport,), + RegionName.Pl: (RegionName.Scar,), + RegionName.Scar: (RegionName.Pl2,), + RegionName.Pl2: (RegionName.GroundShaker,), + RegionName.GroundShaker: (RegionName.DataSaix,), + RegionName.Stt: (RegionName.TwilightThorn,), + RegionName.TwilightThorn: (RegionName.Axel1,), + RegionName.Axel1: (RegionName.Axel2,), + RegionName.Axel2: (RegionName.DataRoxas,), + RegionName.Tt: (RegionName.Tt2,), + RegionName.Tt2: (RegionName.Tt3,), + RegionName.Tt3: (RegionName.DataAxel,), + RegionName.Twtnw: (RegionName.Roxas,), + RegionName.Roxas: (RegionName.Xigbar,), + RegionName.Xigbar: (RegionName.Luxord,), + RegionName.Luxord: (RegionName.Saix,), + RegionName.Saix: (RegionName.Twtnw2,), + RegionName.Twtnw2: (RegionName.Xemnas,), + RegionName.Xemnas: (RegionName.ArmoredXemnas, RegionName.DataXemnas), + RegionName.ArmoredXemnas: (RegionName.ArmoredXemnas2,), + RegionName.ArmoredXemnas2: (RegionName.FinalXemnas,), + RegionName.LevelsVS1: (RegionName.LevelsVS3,), + RegionName.LevelsVS3: (RegionName.LevelsVS6,), + RegionName.LevelsVS6: (RegionName.LevelsVS9,), + RegionName.LevelsVS9: (RegionName.LevelsVS12,), + RegionName.LevelsVS12: (RegionName.LevelsVS15,), + RegionName.LevelsVS15: (RegionName.LevelsVS18,), + RegionName.LevelsVS18: (RegionName.LevelsVS21,), + RegionName.LevelsVS21: (RegionName.LevelsVS24,), + RegionName.LevelsVS24: (RegionName.LevelsVS26,), + RegionName.AtlanticaSongOne: (RegionName.AtlanticaSongTwo,), + RegionName.AtlanticaSongTwo: (RegionName.AtlanticaSongThree,), + RegionName.AtlanticaSongThree: (RegionName.AtlanticaSongFour,), } for source, target in KH2RegionConnections.items(): From a53bcb4697f1a077075cc603ad4588a693c3b23d Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Mon, 27 Jan 2025 23:13:10 +0100 Subject: [PATCH 0109/1218] KH2: Use int(..., 0) in Client #4562 --- worlds/kh2/Client.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/worlds/kh2/Client.py b/worlds/kh2/Client.py index 0254d46e934e..a21c8c7c5536 100644 --- a/worlds/kh2/Client.py +++ b/worlds/kh2/Client.py @@ -836,12 +836,12 @@ def get_addresses(self): if self.mem_json: for key in self.mem_json.keys(): - if self.kh2_read_string(eval(self.mem_json[key]["GameVersionCheck"]), 4) == "KH2J": - self.Now = eval(self.mem_json[key]["Now"]) - self.Save=eval(self.mem_json[key]["Save"]) - self.Slot1 = eval(self.mem_json[key]["Slot1"]) - self.Journal = eval(self.mem_json[key]["Journal"]) - self.Shop = eval(self.mem_json[key]["Shop"]) + if self.kh2_read_string(int(self.mem_json[key]["GameVersionCheck"], 0), 4) == "KH2J": + self.Now = int(self.mem_json[key]["Now"], 0) + self.Save = int(self.mem_json[key]["Save"], 0) + self.Slot1 = int(self.mem_json[key]["Slot1"], 0) + self.Journal = int(self.mem_json[key]["Journal"], 0) + self.Shop = int(self.mem_json[key]["Shop"], 0) self.kh2_game_version = key if self.kh2_game_version is not None: From 9466d5274e5759d0081f02e0aad9829dd1f1dbd3 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Tue, 28 Jan 2025 14:45:28 -0600 Subject: [PATCH 0110/1218] MM2: fix plando and weakness special cases (#4561) --- worlds/mm2/options.py | 2 +- worlds/mm2/rules.py | 61 ++++++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/worlds/mm2/options.py b/worlds/mm2/options.py index 2d90395cacda..f33334898223 100644 --- a/worlds/mm2/options.py +++ b/worlds/mm2/options.py @@ -175,7 +175,7 @@ class WeaknessPlando(OptionDict): display_name = "Plando Weaknesses" schema = Schema({ Optional(And(str, Use(str.title), lambda s: s in bosses)): { - And(str, Use(str.title), lambda s: s in weapons_to_id): And(int, lambda i: i in range(-1, 14)) + And(str, Use(str.title), lambda s: s in weapons_to_id): And(int, lambda i: i in range(-1, 15)) } }) default = {} diff --git a/worlds/mm2/rules.py b/worlds/mm2/rules.py index 7e2ce1f3c752..7e03edf3a23b 100644 --- a/worlds/mm2/rules.py +++ b/worlds/mm2/rules.py @@ -135,41 +135,47 @@ def set_rules(world: "MM2World") -> None: world.weapon_damage[weapon][i] = 0 for p_boss in world.options.plando_weakness: + boss = bosses[p_boss] for p_weapon in world.options.plando_weakness[p_boss]: - if world.options.plando_weakness[p_boss][p_weapon] < minimum_weakness_requirement[p_weapon] \ - and not any(w != p_weapon - and world.weapon_damage[w][bosses[p_boss]] > minimum_weakness_requirement[w] - for w in world.weapon_damage): + weapon = weapons_to_id[p_weapon] + if world.options.plando_weakness[p_boss][p_weapon] < minimum_weakness_requirement[weapon] \ + and not any(w != weapon + and world.weapon_damage[w][boss] >= minimum_weakness_requirement[w] + for w in world.weapon_damage): # we need to replace this weakness - weakness = world.random.choice([key for key in world.weapon_damage if key != p_weapon]) - world.weapon_damage[weakness][bosses[p_boss]] = minimum_weakness_requirement[weakness] - world.weapon_damage[weapons_to_id[p_weapon]][bosses[p_boss]] \ - = world.options.plando_weakness[p_boss][p_weapon] + weakness = world.random.choice([key for key in world.weapon_damage if key != weapon]) + world.weapon_damage[weakness][boss] = minimum_weakness_requirement[weakness] + world.weapon_damage[weapon][boss] = world.options.plando_weakness[p_boss][p_weapon] # handle special cases for boss in range(14): for weapon in (1, 2, 3, 6, 8): if (0 < world.weapon_damage[weapon][boss] < minimum_weakness_requirement[weapon] and - not any(world.weapon_damage[i][boss] >= minimum_weakness_requirement[weapon] + not any(world.weapon_damage[i][boss] >= minimum_weakness_requirement[i] for i in range(9) if i != weapon)): # Weapon does not have enough possible ammo to kill the boss, raise the damage - if boss == 9: - if weapon in (1, 6): - # Atomic Fire and Crash Bomber cannot be Picopico-kun's only weakness - world.weapon_damage[weapon][boss] = 0 - weakness = world.random.choice((2, 3, 4, 5, 7, 8)) - world.weapon_damage[weakness][boss] = minimum_weakness_requirement[weakness] - elif boss == 11: - if weapon == 1: - # Atomic Fire cannot be Boobeam Trap's only weakness - world.weapon_damage[weapon][boss] = 0 - weakness = world.random.choice((2, 3, 4, 5, 6, 7, 8)) - world.weapon_damage[weakness][boss] = minimum_weakness_requirement[weakness] - else: - world.weapon_damage[weapon][boss] = minimum_weakness_requirement[weapon] + world.weapon_damage[weapon][boss] = minimum_weakness_requirement[weapon] + + for weapon in (1, 6): + if (world.weapon_damage[weapon][9] >= minimum_weakness_requirement[weapon] and + not any(world.weapon_damage[i][9] >= minimum_weakness_requirement[i] + for i in range(9) if i not in (1, 6))): + # Atomic Fire and Crash Bomber cannot be Picopico-kun's only weakness + world.weapon_damage[weapon][9] = 0 + weakness = world.random.choice((2, 3, 4, 5, 7, 8)) + world.weapon_damage[weakness][9] = minimum_weakness_requirement[weakness] + + if (world.weapon_damage[1][11] >= minimum_weakness_requirement[1] and + not any(world.weapon_damage[i][11] >= minimum_weakness_requirement[i] + for i in range(9) if i != 1)): + # Atomic Fire cannot be Boobeam Trap's only weakness + world.weapon_damage[1][11] = 0 + weakness = world.random.choice((2, 3, 4, 5, 6, 7, 8)) + world.weapon_damage[weakness][11] = minimum_weakness_requirement[weakness] if world.weapon_damage[0][world.options.starting_robot_master.value] < 1: - world.weapon_damage[0][world.options.starting_robot_master.value] = weapon_damage[0][world.options.starting_robot_master.value] + world.weapon_damage[0][world.options.starting_robot_master.value] = \ + weapon_damage[0][world.options.starting_robot_master.value] # final special case # There's a vanilla crash if Time Stopper kills Wily phase 1 @@ -218,9 +224,10 @@ def set_rules(world: "MM2World") -> None: # we are out of weapons that can actually damage the boss # so find the weapon that has the most uses, and apply that as an additional weakness # it should be impossible to be out of energy, simply because even if every boss took 1 from - # Quick Boomerang and no other, it would only be 28 off from defeating all 9, which Metal Blade should - # be able to cover - wp, max_uses = max((weapon, weapon_energy[weapon] // weapon_costs[weapon]) for weapon in weapon_weight + # Quick Boomerang and no other, it would only be 28 off from defeating all 9, + # which Metal Blade should be able to cover + wp, max_uses = max((weapon, weapon_energy[weapon] // weapon_costs[weapon]) + for weapon in weapon_weight if weapon != 0 and (weapon != 8 or boss != 12)) # Wily Machine cannot under any circumstances take damage from Time Stopper, prevent this world.weapon_damage[wp][boss] = minimum_weakness_requirement[wp] From 1ebc9e2ec03de4dc3c18af6b0d9e82655614ff81 Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Tue, 28 Jan 2025 17:19:20 -0500 Subject: [PATCH 0111/1218] Stardew Valley: Tests: Restructure the tests that validate Mods + ER together, improved performance (#4557) * - Unrolled and improved the structure of the test for Mods + ER, to improve total performance and performance on individual tests for threading purposes * Use | instead of Union[] Co-authored-by: Jouramie <16137441+Jouramie@users.noreply.github.com> * - Remove unused using --------- Co-authored-by: Jouramie <16137441+Jouramie@users.noreply.github.com> --- worlds/stardew_valley/test/mods/TestMods.py | 65 +++++++++++++++++---- 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/worlds/stardew_valley/test/mods/TestMods.py b/worlds/stardew_valley/test/mods/TestMods.py index 89f82870e4a7..02592cc3834a 100644 --- a/worlds/stardew_valley/test/mods/TestMods.py +++ b/worlds/stardew_valley/test/mods/TestMods.py @@ -7,7 +7,9 @@ from ... import items, Group, ItemClassification, create_content from ... import options from ...items import items_by_group +from ...mods.mod_data import ModNames from ...options import SkillProgression, Walnutsanity +from ...options.options import all_mods from ...regions import RandomizationFlag, randomize_connections, create_final_connections_and_regions @@ -20,17 +22,58 @@ def test_given_single_mods_when_generate_then_basic_checks(self): self.assert_basic_checks(multi_world) self.assert_stray_mod_items(mod, multi_world) - def test_given_mod_names_when_generate_paired_with_entrance_randomizer_then_basic_checks(self): - for option in options.EntranceRandomization.options: - for mod in options.Mods.valid_keys: - world_options = { - options.EntranceRandomization: options.EntranceRandomization.options[option], - options.Mods: mod, - options.ExcludeGingerIsland: options.ExcludeGingerIsland.option_false - } - with self.solo_world_sub_test(f"entrance_randomization: {option}, Mod: {mod}", world_options) as (multi_world, _): - self.assert_basic_checks(multi_world) - self.assert_stray_mod_items(mod, multi_world) + # The following tests validate that ER still generates winnable and logically-sane games with given mods. + # Mods that do not interact with entrances are skipped + # Not all ER settings are tested, because 'buildings' is, essentially, a superset of all others + def test_deepwoods_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.deepwoods, options.EntranceRandomization.option_buildings) + + def test_juna_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.juna, options.EntranceRandomization.option_buildings) + + def test_jasper_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.jasper, options.EntranceRandomization.option_buildings) + + def test_alec_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.alec, options.EntranceRandomization.option_buildings) + + def test_yoba_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.yoba, options.EntranceRandomization.option_buildings) + + def test_eugene_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.eugene, options.EntranceRandomization.option_buildings) + + def test_ayeisha_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.ayeisha, options.EntranceRandomization.option_buildings) + + def test_riley_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.riley, options.EntranceRandomization.option_buildings) + + def test_sve_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.sve, options.EntranceRandomization.option_buildings) + + def test_alecto_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.alecto, options.EntranceRandomization.option_buildings) + + def test_lacey_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.lacey, options.EntranceRandomization.option_buildings) + + def test_boarding_house_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.boarding_house, options.EntranceRandomization.option_buildings) + + def test_all_mods_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(all_mods, options.EntranceRandomization.option_buildings) + + def perform_basic_checks_on_mod_with_er(self, mods: str | set[str], er_option: int) -> None: + if isinstance(mods, str): + mods = {mods} + world_options = { + options.EntranceRandomization: er_option, + options.Mods: frozenset(mods), + options.ExcludeGingerIsland: options.ExcludeGingerIsland.option_false + } + with self.solo_world_sub_test(f"entrance_randomization: {er_option}, Mods: {mods}", world_options) as (multi_world, _): + self.assert_basic_checks(multi_world) def test_allsanity_all_mods_when_generate_then_basic_checks(self): with self.solo_world_sub_test(world_options=allsanity_mods_6_x_x()) as (multi_world, _): From 41898ed6403fa62487c51880792a648d1f4d246b Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:42:46 +0100 Subject: [PATCH 0112/1218] MultiServer: implement NoText and deprecate uncompressed Websocket connections (#4540) * MultiServer: add NoText tag and handling * MultiServer: deprecate and warn for uncompressed connections * MultiServer: fix missing space in no compression warning --- MultiServer.py | 51 +++++++++++++++++++++++++++++----------- NetUtils.py | 5 ++-- docs/network protocol.md | 4 ++++ 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 9e0868b0f4a8..51b72c93ad3d 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -28,9 +28,11 @@ if typing.TYPE_CHECKING: import ssl + from NetUtils import ServerConnection -import websockets import colorama +import websockets +from websockets.extensions.permessage_deflate import PerMessageDeflate try: # ponyorm is a requirement for webhost, not default server, so may not be importable from pony.orm.dbapiprovider import OperationalError @@ -119,13 +121,14 @@ def get_saving_second(seed_name: str, interval: int = 60) -> int: class Client(Endpoint): version = Version(0, 0, 0) - tags: typing.List[str] = [] + tags: typing.List[str] remote_items: bool remote_start_inventory: bool no_items: bool no_locations: bool + no_text: bool - def __init__(self, socket: websockets.WebSocketServerProtocol, ctx: Context): + def __init__(self, socket: "ServerConnection", ctx: Context) -> None: super().__init__(socket) self.auth = False self.team = None @@ -175,6 +178,7 @@ class Context: "compatibility": int} # team -> slot id -> list of clients authenticated to slot. clients: typing.Dict[int, typing.Dict[int, typing.List[Client]]] + endpoints: list[Client] locations: LocationStore # typing.Dict[int, typing.Dict[int, typing.Tuple[int, int, int]]] location_checks: typing.Dict[typing.Tuple[int, int], typing.Set[int]] hints_used: typing.Dict[typing.Tuple[int, int], int] @@ -364,18 +368,28 @@ async def broadcast_send_encoded_msgs(self, endpoints: typing.Iterable[Endpoint] return True def broadcast_all(self, msgs: typing.List[dict]): - msgs = self.dumper(msgs) - endpoints = (endpoint for endpoint in self.endpoints if endpoint.auth) - async_start(self.broadcast_send_encoded_msgs(endpoints, msgs)) + msg_is_text = all(msg["cmd"] == "PrintJSON" for msg in msgs) + data = self.dumper(msgs) + endpoints = ( + endpoint + for endpoint in self.endpoints + if endpoint.auth and not (msg_is_text and endpoint.no_text) + ) + async_start(self.broadcast_send_encoded_msgs(endpoints, data)) def broadcast_text_all(self, text: str, additional_arguments: dict = {}): self.logger.info("Notice (all): %s" % text) self.broadcast_all([{**{"cmd": "PrintJSON", "data": [{ "text": text }]}, **additional_arguments}]) def broadcast_team(self, team: int, msgs: typing.List[dict]): - msgs = self.dumper(msgs) - endpoints = (endpoint for endpoint in itertools.chain.from_iterable(self.clients[team].values())) - async_start(self.broadcast_send_encoded_msgs(endpoints, msgs)) + msg_is_text = all(msg["cmd"] == "PrintJSON" for msg in msgs) + data = self.dumper(msgs) + endpoints = ( + endpoint + for endpoint in itertools.chain.from_iterable(self.clients[team].values()) + if not (msg_is_text and endpoint.no_text) + ) + async_start(self.broadcast_send_encoded_msgs(endpoints, data)) def broadcast(self, endpoints: typing.Iterable[Client], msgs: typing.List[dict]): msgs = self.dumper(msgs) @@ -389,13 +403,13 @@ async def disconnect(self, endpoint: Client): await on_client_disconnected(self, endpoint) def notify_client(self, client: Client, text: str, additional_arguments: dict = {}): - if not client.auth: + if not client.auth or client.no_text: return self.logger.info("Notice (Player %s in team %d): %s" % (client.name, client.team + 1, text)) async_start(self.send_msgs(client, [{"cmd": "PrintJSON", "data": [{ "text": text }], **additional_arguments}])) def notify_client_multiple(self, client: Client, texts: typing.List[str], additional_arguments: dict = {}): - if not client.auth: + if not client.auth or client.no_text: return async_start(self.send_msgs(client, [{"cmd": "PrintJSON", "data": [{ "text": text }], **additional_arguments} @@ -760,7 +774,7 @@ def notify_hints(self, team: int, hints: typing.List[Hint], only_new: bool = Fal self.on_new_hint(team, slot) for slot, hint_data in concerns.items(): if recipients is None or slot in recipients: - clients = self.clients[team].get(slot) + clients = filter(lambda c: not c.no_text, self.clients[team].get(slot, [])) if not clients: continue client_hints = [datum[1] for datum in sorted(hint_data, key=lambda x: x[0].finding_player != slot)] @@ -819,7 +833,7 @@ def update_aliases(ctx: Context, team: int): async_start(ctx.send_encoded_msgs(client, cmd)) -async def server(websocket, path: str = "/", ctx: Context = None): +async def server(websocket: "ServerConnection", path: str = "/", ctx: Context = None) -> None: client = Client(websocket, ctx) ctx.endpoints.append(client) @@ -910,6 +924,10 @@ async def on_client_joined(ctx: Context, client: Client): "If your client supports it, " "you may have additional local commands you can list with /help.", {"type": "Tutorial"}) + if not any(isinstance(extension, PerMessageDeflate) for extension in client.socket.extensions): + ctx.notify_client(client, "Warning: your client does not support compressed websocket connections! " + "It may stop working in the future. If you are a player, please report this to the " + "client's developer.") ctx.client_connection_timers[client.team, client.slot] = datetime.datetime.now(datetime.timezone.utc) @@ -1803,7 +1821,9 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): ctx.clients[team][slot].append(client) client.version = args['version'] client.tags = args['tags'] - client.no_locations = 'TextOnly' in client.tags or 'Tracker' in client.tags + client.no_locations = "TextOnly" in client.tags or "Tracker" in client.tags + # set NoText for old PopTracker clients that predate the tag to save traffic + client.no_text = "NoText" in client.tags or ("PopTracker" in client.tags and client.version < (0, 5, 1)) connected_packet = { "cmd": "Connected", "team": client.team, "slot": client.slot, @@ -1876,6 +1896,9 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): client.tags = args["tags"] if set(old_tags) != set(client.tags): client.no_locations = 'TextOnly' in client.tags or 'Tracker' in client.tags + client.no_text = "NoText" in client.tags or ( + "PopTracker" in client.tags and client.version < (0, 5, 1) + ) ctx.broadcast_text_all( f"{ctx.get_aliased_name(client.team, client.slot)} (Team #{client.team + 1}) has changed tags " f"from {old_tags} to {client.tags}.", diff --git a/NetUtils.py b/NetUtils.py index d58bbe81e304..5bcc583c53b6 100644 --- a/NetUtils.py +++ b/NetUtils.py @@ -5,7 +5,8 @@ import warnings from json import JSONEncoder, JSONDecoder -import websockets +if typing.TYPE_CHECKING: + from websockets import WebSocketServerProtocol as ServerConnection from Utils import ByValue, Version @@ -151,7 +152,7 @@ def _object_hook(o: typing.Any) -> typing.Any: class Endpoint: - socket: websockets.WebSocketServerProtocol + socket: "ServerConnection" def __init__(self, socket): self.socket = socket diff --git a/docs/network protocol.md b/docs/network protocol.md index e32c266ffb67..2eb3b0d6f3c2 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -47,6 +47,9 @@ Packets are simple JSON lists in which any number of ordered network commands ca An object can contain the "class" key, which will tell the content data type, such as "Version" in the following example. +Websocket connections should support per-message compression. Uncompressed connections are deprecated and may stop +working in the future. + Example: ```javascript [{"cmd": "RoomInfo", "version": {"major": 0, "minor": 1, "build": 3, "class": "Version"}, "tags": ["WebHost"], ... }] @@ -745,6 +748,7 @@ Tags are represented as a list of strings, the common client tags follow: | HintGame | Indicates the client is a hint game, made to send hints instead of locations. Special join/leave message,¹ `game` is optional.² | | Tracker | Indicates the client is a tracker, made to track instead of sending locations. Special join/leave message,¹ `game` is optional.² | | TextOnly | Indicates the client is a basic client, made to chat instead of sending locations. Special join/leave message,¹ `game` is optional.² | +| NoText | Indicates the client does not want to receive text messages, improving performance if not needed. | ¹: When connecting or disconnecting, the chat message shows e.g. "tracking".\ ²: Allows `game` to be empty or null in [Connect](#connect). Game and version validation will then be skipped. From 738c21c625f673caac2d10c173688a10f23c86a1 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:52:01 +0100 Subject: [PATCH 0113/1218] Tests: massively improve the memory leak test performance (#4568) * Tests: massively improve the memory leak test performance With the growing number of worlds, GC becomes the bottleneck and slows down the test. * Tests: fix typing in general/test_memory --- test/general/test_memory.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/general/test_memory.py b/test/general/test_memory.py index 987d19acf35f..a4b2f1bd25df 100644 --- a/test/general/test_memory.py +++ b/test/general/test_memory.py @@ -1,5 +1,6 @@ import unittest +from BaseClasses import MultiWorld from worlds.AutoWorld import AutoWorldRegister from . import setup_solo_multiworld @@ -9,8 +10,12 @@ def test_leak(self) -> None: """Tests that worlds don't leak references to MultiWorld or themselves with default options.""" import gc import weakref + refs: dict[str, weakref.ReferenceType[MultiWorld]] = {} for game_name, world_type in AutoWorldRegister.world_types.items(): - with self.subTest("Game", game_name=game_name): + with self.subTest("Game creation", game_name=game_name): weak = weakref.ref(setup_solo_multiworld(world_type)) - gc.collect() + refs[game_name] = weak + gc.collect() + for game_name, weak in refs.items(): + with self.subTest("Game cleanup", game_name=game_name): self.assertFalse(weak(), "World leaked a reference") From 57afdfda6f6535bc592581d70d97a3f12977b5a1 Mon Sep 17 00:00:00 2001 From: Felix R <50271878+FelicitusNeko@users.noreply.github.com> Date: Tue, 28 Jan 2025 21:03:37 -0400 Subject: [PATCH 0114/1218] meritous: move completion_condition to set_rules (#4567) --- worlds/meritous/__init__.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/worlds/meritous/__init__.py b/worlds/meritous/__init__.py index 7a21b19ef247..2263478ff5e2 100644 --- a/worlds/meritous/__init__.py +++ b/worlds/meritous/__init__.py @@ -136,6 +136,12 @@ def create_items(self): def set_rules(self): set_rules(self.multiworld, self.player) + if self.goal == 0: + self.multiworld.completion_condition[self.player] = lambda state: state.has_any( + ["Victory", "Full Victory"], self.player) + else: + self.multiworld.completion_condition[self.player] = lambda state: state.has( + "Full Victory", self.player) def generate_basic(self): self.multiworld.get_location("Place of Power", self.player).place_locked_item( @@ -166,13 +172,6 @@ def generate_basic(self): self.multiworld.get_location(boss, self.player).place_locked_item( self.create_item("Evolution Trap")) - if self.goal == 0: - self.multiworld.completion_condition[self.player] = lambda state: state.has_any( - ["Victory", "Full Victory"], self.player) - else: - self.multiworld.completion_condition[self.player] = lambda state: state.has( - "Full Victory", self.player) - def fill_slot_data(self) -> dict: return { "goal": self.goal, From b8666b25625b0cd2341b9747bc126127cd26022e Mon Sep 17 00:00:00 2001 From: Jouramie <16137441+Jouramie@users.noreply.github.com> Date: Wed, 29 Jan 2025 13:56:50 -0500 Subject: [PATCH 0115/1218] Stardew Valley: Remove weird magic trap test? (#4570) --- worlds/stardew_valley/test/mods/TestMods.py | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/worlds/stardew_valley/test/mods/TestMods.py b/worlds/stardew_valley/test/mods/TestMods.py index 02592cc3834a..1dd2ab4902f7 100644 --- a/worlds/stardew_valley/test/mods/TestMods.py +++ b/worlds/stardew_valley/test/mods/TestMods.py @@ -1,12 +1,10 @@ import random from BaseClasses import get_seed -from .. import SVTestBase, SVTestCase, allsanity_no_mods_6_x_x, allsanity_mods_6_x_x, solo_multiworld, \ - fill_dataclass_with_default +from .. import SVTestBase, SVTestCase, allsanity_mods_6_x_x, fill_dataclass_with_default from ..assertion import ModAssertMixin, WorldAssertMixin from ... import items, Group, ItemClassification, create_content from ... import options -from ...items import items_by_group from ...mods.mod_data import ModNames from ...options import SkillProgression, Walnutsanity from ...options.options import all_mods @@ -190,19 +188,3 @@ def test_mod_entrance_randomization(self): self.assertEqual(len(set(randomized_connections.values())), len(randomized_connections.values()), f"Connections are duplicated in randomization.") - - -class TestModTraps(SVTestCase): - def test_given_traps_when_generate_then_all_traps_in_pool(self): - for value in options.TrapItems.options: - if value == "no_traps": - continue - - world_options = allsanity_no_mods_6_x_x() - world_options.update({options.TrapItems.internal_name: options.TrapItems.options[value], options.Mods.internal_name: "Magic"}) - with solo_multiworld(world_options) as (multi_world, _): - trap_items = [item_data.name for item_data in items_by_group[Group.TRAP] if Group.DEPRECATED not in item_data.groups] - multiworld_items = [item.name for item in multi_world.get_items()] - for item in trap_items: - with self.subTest(f"Option: {value}, Item: {item}"): - self.assertIn(item, multiworld_items) From 8e14e463e41945378090da40ab620698baf6d8cc Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Thu, 30 Jan 2025 03:05:51 -0500 Subject: [PATCH 0116/1218] Stardew Valley: Radioactive slot machine should be a ginger island check (#4578) --- worlds/stardew_valley/data/locations.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/stardew_valley/data/locations.csv b/worlds/stardew_valley/data/locations.csv index 43883b86f8ac..66a9157b3437 100644 --- a/worlds/stardew_valley/data/locations.csv +++ b/worlds/stardew_valley/data/locations.csv @@ -2938,7 +2938,7 @@ id,region,name,tags,mod_name 7440,Farm,Craft Copper Slot Machine,"CRAFTSANITY",Luck Skill 7441,Farm,Craft Gold Slot Machine,"CRAFTSANITY",Luck Skill 7442,Farm,Craft Iridium Slot Machine,"CRAFTSANITY",Luck Skill -7443,Farm,Craft Radioactive Slot Machine,"CRAFTSANITY",Luck Skill +7443,Farm,Craft Radioactive Slot Machine,"CRAFTSANITY,GINGER_ISLAND",Luck Skill 7451,Adventurer's Guild,Magic Elixir Recipe,"CHEFSANITY,CHEFSANITY_PURCHASE",Magic 7452,Adventurer's Guild,Travel Core Recipe,CRAFTSANITY,Magic 7453,Alesia Shop,Haste Elixir Recipe,CRAFTSANITY,Stardew Valley Expanded From 1fe8024b438dd56bd20e6b26c8d14fe1e1fbd0b4 Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Thu, 30 Jan 2025 03:19:06 -0500 Subject: [PATCH 0117/1218] Stardew valley: Add Mod Recipes tests (#4580) * `- Add Craftsanity Mod tests * - Add the same test for cooking --------- Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- .../stardew_valley/test/mods/TestModsFill.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 worlds/stardew_valley/test/mods/TestModsFill.py diff --git a/worlds/stardew_valley/test/mods/TestModsFill.py b/worlds/stardew_valley/test/mods/TestModsFill.py new file mode 100644 index 000000000000..a140f5abae14 --- /dev/null +++ b/worlds/stardew_valley/test/mods/TestModsFill.py @@ -0,0 +1,28 @@ +from .. import SVTestBase +from ... import options + + +class TestNoGingerIslandCraftingRecipesAreRequired(SVTestBase): + options = { + options.Goal.internal_name: options.Goal.option_craft_master, + options.Craftsanity.internal_name: options.Craftsanity.option_all, + options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true, + options.Mods.internal_name: frozenset(options.Mods.valid_keys) + } + + @property + def run_default_tests(self) -> bool: + return True + + +class TestNoGingerIslandCookingRecipesAreRequired(SVTestBase): + options = { + options.Goal.internal_name: options.Goal.option_gourmet_chef, + options.Cooksanity.internal_name: options.Cooksanity.option_all, + options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true, + options.Mods.internal_name: frozenset(options.Mods.valid_keys) + } + + @property + def run_default_tests(self) -> bool: + return True From 67e8877143aecf3587f7b60bdb34659de1500e0d Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:38:17 +0100 Subject: [PATCH 0118/1218] Docs: fix lower limit of valid IDs in network protocol.md (#4579) --- docs/network protocol.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/network protocol.md b/docs/network protocol.md index 2eb3b0d6f3c2..e5d3b7e6c26a 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -533,9 +533,9 @@ In JSON this may look like: {"item": 3, "location": 3, "player": 3, "flags": 0} ] ``` -`item` is the item id of the item. Item ids are only supported in the range of [-253, 253 - 1], with anything ≤ 0 reserved for Archipelago use. +`item` is the item id of the item. Item ids are only supported in the range of [-253 + 1, 253 - 1], with anything ≤ 0 reserved for Archipelago use. -`location` is the location id of the item inside the world. Location ids are only supported in the range of [-253, 253 - 1], with anything ≤ 0 reserved for Archipelago use. +`location` is the location id of the item inside the world. Location ids are only supported in the range of [-253 + 1, 253 - 1], with anything ≤ 0 reserved for Archipelago use. `player` is the player slot of the world the item is located in, except when inside an [LocationInfo](#LocationInfo) Packet then it will be the slot of the player to receive the item From 445c9b22d6cfb9b8ff4e76b91995d08abf154ff5 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 31 Jan 2025 20:11:04 -0500 Subject: [PATCH 0119/1218] Settings: Handle empty Groups (#4576) * export empty groups as an empty dict instead of crashing * Update settings.py Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> * check instance values from self as well * Apply suggestions from code review Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --------- Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- settings.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/settings.py b/settings.py index 12dace632c8a..cc808c2732df 100644 --- a/settings.py +++ b/settings.py @@ -109,7 +109,7 @@ def changed(self) -> bool: def get_type_hints(cls) -> Dict[str, Any]: """Returns resolved type hints for the class""" if cls._type_cache is None: - if not isinstance(next(iter(cls.__annotations__.values())), str): + if not cls.__annotations__ or not isinstance(next(iter(cls.__annotations__.values())), str): # non-str: assume already resolved cls._type_cache = cls.__annotations__ else: @@ -270,11 +270,15 @@ def dump(self, f: TextIO, level: int = 0) -> None: # fetch class to avoid going through getattr cls = self.__class__ type_hints = cls.get_type_hints() + entries = [e for e in self] + if not entries: + # write empty dict for empty Group with no instance values + cls._dump_value({}, f, indent=" " * level) # validate group for name in cls.__annotations__.keys(): assert hasattr(cls, name), f"{cls}.{name} is missing a default value" # dump ordered members - for name in self: + for name in entries: attr = cast(object, getattr(self, name)) attr_cls = type_hints[name] if name in type_hints else attr.__class__ attr_cls_origin = typing.get_origin(attr_cls) From d1167027f4d723856e555a8c9ca7cfe7ce8dde4f Mon Sep 17 00:00:00 2001 From: Jarno Date: Sat, 1 Feb 2025 02:26:59 +0100 Subject: [PATCH 0120/1218] Core: Make csv options output ignore hidden options (#4539) * Core: Make csv options output ignore hidden options * Update Options.py Co-authored-by: Aaron Wagener --------- Co-authored-by: Aaron Wagener --- Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Options.py b/Options.py index d9122d444c97..49e82069ee8d 100644 --- a/Options.py +++ b/Options.py @@ -1582,7 +1582,7 @@ def dump_player_options(multiworld: MultiWorld) -> None: } output.append(player_output) for option_key, option in world.options_dataclass.type_hints.items(): - if issubclass(Removed, option): + if option.visibility == Visibility.none: continue display_name = getattr(option, "display_name", option_key) player_output[display_name] = getattr(world.options, option_key).current_option_name From b7b78dead3bf181545352df1b0e3229fc592b9f2 Mon Sep 17 00:00:00 2001 From: Spineraks Date: Sat, 1 Feb 2025 22:03:49 +0100 Subject: [PATCH 0121/1218] LADX: Fix generation error on minimal accessibility (#4281) * [LADX] Fix minimal accessibility * allow_partial for minimal accessibility * create the correct partial_all_state * skip our prefills rather than removing after * dont rebuild our prefill list --------- Co-authored-by: threeandthreee --- worlds/ladx/__init__.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/worlds/ladx/__init__.py b/worlds/ladx/__init__.py index 7b1a35666ae7..a887638e377a 100644 --- a/worlds/ladx/__init__.py +++ b/worlds/ladx/__init__.py @@ -9,7 +9,7 @@ import bsdiff4 import settings -from BaseClasses import Entrance, Item, ItemClassification, Location, Tutorial, MultiWorld +from BaseClasses import CollectionState, Entrance, Item, ItemClassification, Location, Tutorial, MultiWorld from Fill import fill_restrictive from worlds.AutoWorld import WebWorld, World from .Common import * @@ -315,8 +315,6 @@ def pre_fill(self) -> None: # Set up filter rules - # The list of items we will pass to fill_restrictive, contains at first the items that go to all dungeons - all_dungeon_items_to_fill = list(self.prefill_own_dungeons) # set containing the list of all possible dungeon locations for the player all_dungeon_locs = set() @@ -327,9 +325,6 @@ def pre_fill(self) -> None: for item in self.prefill_original_dungeon[dungeon_index]: allowed_locations_by_item[item] = locs - # put the items for this dungeon in the list to fill - all_dungeon_items_to_fill.extend(self.prefill_original_dungeon[dungeon_index]) - # ...and gather the list of all dungeon locations all_dungeon_locs |= locs # ...also set the rules for the dungeon @@ -369,16 +364,27 @@ def priority(item): if allowed_locations_by_item[item] is all_dungeon_locs: i += 3 return i + all_dungeon_items_to_fill = self.get_pre_fill_items() all_dungeon_items_to_fill.sort(key=priority) # Set up state - all_state = self.multiworld.get_all_state(use_cache=False) - # Remove dungeon items we are about to put in from the state so that we don't double count - for item in all_dungeon_items_to_fill: - all_state.remove(item) + partial_all_state = CollectionState(self.multiworld) + # Collect every item from the item pool and every pre-fill item like MultiWorld.get_all_state, except not our own pre-fill items. + for item in self.multiworld.itempool: + partial_all_state.collect(item, prevent_sweep=True) + for player in self.multiworld.player_ids: + if player == self.player: + # Don't collect the items we're about to place. + continue + subworld = self.multiworld.worlds[player] + for item in subworld.get_pre_fill_items(): + partial_all_state.collect(item, prevent_sweep=True) + + # Sweep to pick up already placed items that are reachable with everything but the dungeon items. + partial_all_state.sweep_for_advancements() - # Finally, fill! - fill_restrictive(self.multiworld, all_state, all_dungeon_locs_to_fill, all_dungeon_items_to_fill, lock=True, single_player_placement=True, allow_partial=False) + fill_restrictive(self.multiworld, partial_all_state, all_dungeon_locs_to_fill, all_dungeon_items_to_fill, lock=True, single_player_placement=True, allow_partial=False) + name_cache = {} # Tries to associate an icon from another game with an icon we have From 051518e72aaed0b49d43fe80c01129fd52aca729 Mon Sep 17 00:00:00 2001 From: Jouramie <16137441+Jouramie@users.noreply.github.com> Date: Sat, 1 Feb 2025 16:07:08 -0500 Subject: [PATCH 0122/1218] Stardew Valley: Fix unresolved reference warning and unused imports (#4360) * fix unresolved reference warning and unused imports * revert stuff * just a commit to rerun the tests cuz messenger fail --- worlds/stardew_valley/__init__.py | 6 +- worlds/stardew_valley/bundles/bundle_room.py | 2 +- worlds/stardew_valley/content/mods/sve.py | 19 +- .../content/vanilla/qi_board.py | 1 - worlds/stardew_valley/data/bundle_data.py | 4 +- worlds/stardew_valley/data/craftable_data.py | 11 +- worlds/stardew_valley/data/recipe_data.py | 42 +- worlds/stardew_valley/data/recipe_source.py | 2 +- worlds/stardew_valley/logic/ability_logic.py | 10 +- worlds/stardew_valley/logic/action_logic.py | 1 - worlds/stardew_valley/logic/skill_logic.py | 8 +- .../stardew_valley/mods/logic/item_logic.py | 7 +- .../stardew_valley/mods/logic/quests_logic.py | 5 +- worlds/stardew_valley/regions.py | 623 +++++++++--------- worlds/stardew_valley/scripts/update_data.py | 8 +- worlds/stardew_valley/stardew_rule/base.py | 4 +- .../test/TestMultiplePlayers.py | 2 - .../stardew_valley/test/TestWalnutsanity.py | 12 +- .../stardew_valley/test/rules/TestFishing.py | 3 +- 19 files changed, 396 insertions(+), 374 deletions(-) diff --git a/worlds/stardew_valley/__init__.py b/worlds/stardew_valley/__init__.py index ef842263ad2c..e2d49e64ae14 100644 --- a/worlds/stardew_valley/__init__.py +++ b/worlds/stardew_valley/__init__.py @@ -1,6 +1,6 @@ import logging from random import Random -from typing import Dict, Any, Iterable, Optional, List, TextIO +from typing import Dict, Any, Iterable, Optional, List, TextIO, cast from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState from Options import PerGameCommonOptions @@ -124,7 +124,7 @@ def create_region(name: str, exits: Iterable[str]) -> Region: self.options) def add_location(name: str, code: Optional[int], region: str): - region = world_regions[region] + region: Region = world_regions[region] location = StardewLocation(self.player, name, code, region) region.locations.append(location) @@ -314,9 +314,9 @@ def get_filler_item_rules(self): include_traps = True exclude_island = False for player in link_group["players"]: - player_options = self.multiworld.worlds[player].options if self.multiworld.game[player] != self.game: continue + player_options = cast(StardewValleyOptions, self.multiworld.worlds[player].options) if player_options.trap_items == TrapItems.option_no_traps: include_traps = False if player_options.exclude_ginger_island == ExcludeGingerIsland.option_true: diff --git a/worlds/stardew_valley/bundles/bundle_room.py b/worlds/stardew_valley/bundles/bundle_room.py index 8068ff17ac83..225fb4feab1b 100644 --- a/worlds/stardew_valley/bundles/bundle_room.py +++ b/worlds/stardew_valley/bundles/bundle_room.py @@ -4,7 +4,7 @@ from .bundle import Bundle, BundleTemplate from ..content import StardewContent -from ..options import BundlePrice, StardewValleyOptions +from ..options import StardewValleyOptions @dataclass diff --git a/worlds/stardew_valley/content/mods/sve.py b/worlds/stardew_valley/content/mods/sve.py index a68d4ae9c097..12b3e3558a67 100644 --- a/worlds/stardew_valley/content/mods/sve.py +++ b/worlds/stardew_valley/content/mods/sve.py @@ -10,15 +10,14 @@ from ...mods.mod_data import ModNames from ...strings.craftable_names import ModEdible from ...strings.crop_names import Fruit, SVEVegetable, SVEFruit -from ...strings.fish_names import WaterItem, SVEFish, SVEWaterItem +from ...strings.fish_names import WaterItem, SVEWaterItem from ...strings.flower_names import Flower from ...strings.food_names import SVEMeal, SVEBeverage from ...strings.forageable_names import Mushroom, Forageable, SVEForage from ...strings.gift_names import SVEGift -from ...strings.metal_names import Ore -from ...strings.monster_drop_names import ModLoot, Loot +from ...strings.monster_drop_names import ModLoot from ...strings.performance_names import Performance -from ...strings.region_names import Region, SVERegion, LogicRegion +from ...strings.region_names import Region, SVERegion from ...strings.season_names import Season from ...strings.seed_names import SVESeed from ...strings.skill_names import Skill @@ -81,7 +80,8 @@ def harvest_source_hook(self, content: StardewContent): ModEdible.lightning_elixir: (ShopSource(money_price=12000, shop_region=SVERegion.galmoran_outpost),), ModEdible.barbarian_elixir: (ShopSource(money_price=22000, shop_region=SVERegion.galmoran_outpost),), ModEdible.gravity_elixir: (ShopSource(money_price=4000, shop_region=SVERegion.galmoran_outpost),), - SVEMeal.grampleton_orange_chicken: (ShopSource(money_price=650, shop_region=Region.saloon, other_requirements=(RelationshipRequirement(ModNPC.sophia, 6),)),), + SVEMeal.grampleton_orange_chicken: ( + ShopSource(money_price=650, shop_region=Region.saloon, other_requirements=(RelationshipRequirement(ModNPC.sophia, 6),)),), ModEdible.hero_elixir: (ShopSource(money_price=8000, shop_region=SVERegion.isaac_shop),), ModEdible.aegis_elixir: (ShopSource(money_price=28000, shop_region=SVERegion.galmoran_outpost),), SVEBeverage.sports_drink: (ShopSource(money_price=750, shop_region=Region.hospital),), @@ -92,7 +92,8 @@ def harvest_source_hook(self, content: StardewContent): ForagingSource(regions=(SVERegion.forest_west,), seasons=(Season.summer, Season.fall)), ForagingSource(regions=(SVERegion.sprite_spring_cave,), ) ), Mushroom.purple: ( - ForagingSource(regions=(SVERegion.forest_west,), seasons=(Season.fall,)), ForagingSource(regions=(SVERegion.sprite_spring_cave, SVERegion.junimo_woods), ) + ForagingSource(regions=(SVERegion.forest_west,), seasons=(Season.fall,)), + ForagingSource(regions=(SVERegion.sprite_spring_cave, SVERegion.junimo_woods), ) ), Mushroom.morel: ( ForagingSource(regions=(SVERegion.forest_west,), seasons=(Season.fall,)), ForagingSource(regions=(SVERegion.sprite_spring_cave,), ) @@ -117,7 +118,8 @@ def harvest_source_hook(self, content: StardewContent): ModLoot.green_mushroom: (ForagingSource(regions=(SVERegion.highlands_pond,), seasons=Season.not_winter),), ModLoot.ornate_treasure_chest: (ForagingSource(regions=(SVERegion.highlands_outside,), - other_requirements=(CombatRequirement(Performance.galaxy), ToolRequirement(Tool.axe, ToolMaterial.iron))),), + other_requirements=( + CombatRequirement(Performance.galaxy), ToolRequirement(Tool.axe, ToolMaterial.iron))),), ModLoot.swirl_stone: (ForagingSource(regions=(SVERegion.crimson_badlands,), other_requirements=(CombatRequirement(Performance.galaxy),)),), ModLoot.void_soul: (ForagingSource(regions=(SVERegion.crimson_badlands,), other_requirements=(CombatRequirement(Performance.good),)),), SVEForage.winter_star_rose: (ForagingSource(regions=(SVERegion.summit,), seasons=(Season.winter,)),), @@ -137,7 +139,8 @@ def harvest_source_hook(self, content: StardewContent): SVEForage.thistle: (ForagingSource(regions=(SVERegion.summit,)),), ModLoot.void_pebble: (ForagingSource(regions=(SVERegion.crimson_badlands,), other_requirements=(CombatRequirement(Performance.great),)),), ModLoot.void_shard: (ForagingSource(regions=(SVERegion.crimson_badlands,), - other_requirements=(CombatRequirement(Performance.galaxy), SkillRequirement(Skill.combat, 10), YearRequirement(3),)),), + other_requirements=( + CombatRequirement(Performance.galaxy), SkillRequirement(Skill.combat, 10), YearRequirement(3),)),), SVEWaterItem.dulse_seaweed: (ForagingSource(regions=(Region.beach,), other_requirements=(FishingRequirement(Region.beach),)),), # Fable Reef diff --git a/worlds/stardew_valley/content/vanilla/qi_board.py b/worlds/stardew_valley/content/vanilla/qi_board.py index d859d3b16ff7..e5f67c431953 100644 --- a/worlds/stardew_valley/content/vanilla/qi_board.py +++ b/worlds/stardew_valley/content/vanilla/qi_board.py @@ -6,7 +6,6 @@ from ...data.harvest import HarvestCropSource from ...strings.crop_names import Fruit from ...strings.region_names import Region -from ...strings.season_names import Season from ...strings.seed_names import Seed diff --git a/worlds/stardew_valley/data/bundle_data.py b/worlds/stardew_valley/data/bundle_data.py index 8b2e189c796e..75f0f75a23d2 100644 --- a/worlds/stardew_valley/data/bundle_data.py +++ b/worlds/stardew_valley/data/bundle_data.py @@ -10,7 +10,7 @@ from ..strings.crop_names import Fruit, Vegetable from ..strings.currency_names import Currency from ..strings.fertilizer_names import Fertilizer, RetainingSoil, SpeedGro -from ..strings.fish_names import Fish, WaterItem, Trash, all_fish +from ..strings.fish_names import Fish, WaterItem, Trash from ..strings.flower_names import Flower from ..strings.food_names import Beverage, Meal from ..strings.forageable_names import Forageable, Mushroom @@ -832,7 +832,7 @@ magic_rock_candy, mega_bomb.as_amount(10), mystery_box.as_amount(10), mixed_seeds.as_amount(50), strawberry_seeds.as_amount(20), spicy_eel.as_amount(5), crab_cakes.as_amount(5), eggplant_parmesan.as_amount(5), - pumpkin_soup.as_amount(5), lucky_lunch.as_amount(5),] + pumpkin_soup.as_amount(5), lucky_lunch.as_amount(5)] calico_bundle = BundleTemplate(CCRoom.bulletin_board, BundleName.calico, calico_items, 2, 2) raccoon_bundle = BundleTemplate(CCRoom.bulletin_board, BundleName.raccoon, raccoon_foraging_items, 4, 4) diff --git a/worlds/stardew_valley/data/craftable_data.py b/worlds/stardew_valley/data/craftable_data.py index 1bb4b2bea73b..de371b7c3a9b 100644 --- a/worlds/stardew_valley/data/craftable_data.py +++ b/worlds/stardew_valley/data/craftable_data.py @@ -14,7 +14,7 @@ from ..strings.fish_names import Fish, WaterItem, ModTrash, Trash from ..strings.flower_names import Flower from ..strings.food_names import Meal -from ..strings.forageable_names import Forageable, SVEForage, DistantLandsForageable, Mushroom +from ..strings.forageable_names import Forageable, DistantLandsForageable, Mushroom from ..strings.gift_names import Gift from ..strings.ingredient_names import Ingredient from ..strings.machine_names import Machine @@ -318,7 +318,8 @@ def create_recipe(name: str, ingredients: Dict[str, int], source: RecipeSource, preservation_chamber = skill_recipe(ModMachine.preservation_chamber, ModSkill.archaeology, 1, {MetalBar.copper: 1, Material.wood: 15, ArtisanGood.oak_resin: 30}, ModNames.archaeology) -restoration_table = skill_recipe(ModMachine.restoration_table, ModSkill.archaeology, 1, {Material.wood: 15, MetalBar.copper: 1, MetalBar.iron: 1}, ModNames.archaeology) +restoration_table = skill_recipe(ModMachine.restoration_table, ModSkill.archaeology, 1, {Material.wood: 15, MetalBar.copper: 1, MetalBar.iron: 1}, + ModNames.archaeology) preservation_chamber_h = skill_recipe(ModMachine.hardwood_preservation_chamber, ModSkill.archaeology, 6, {MetalBar.copper: 1, Material.hardwood: 15, ArtisanGood.oak_resin: 30}, ModNames.archaeology) grinder = skill_recipe(ModMachine.grinder, ModSkill.archaeology, 2, {Artifact.rusty_cog: 10, MetalBar.iron: 5, ArtisanGood.battery_pack: 1}, @@ -330,12 +331,14 @@ def create_recipe(name: str, ingredients: Dict[str, int], source: RecipeSource, glass_fence = skill_recipe(ModCraftable.glass_fence, ModSkill.archaeology, 7, {Artifact.glass_shards: 5}, ModNames.archaeology) bone_path = skill_recipe(ModFloor.bone_path, ModSkill.archaeology, 4, {Fossil.bone_fragment: 1}, ModNames.archaeology) rust_path = skill_recipe(ModFloor.rusty_path, ModSkill.archaeology, 2, {ModTrash.rusty_scrap: 2}, ModNames.archaeology) -rusty_brazier = skill_recipe(ModCraftable.rusty_brazier, ModSkill.archaeology, 3, {ModTrash.rusty_scrap: 10, Material.coal: 1, Material.fiber: 1}, ModNames.archaeology) +rusty_brazier = skill_recipe(ModCraftable.rusty_brazier, ModSkill.archaeology, 3, {ModTrash.rusty_scrap: 10, Material.coal: 1, Material.fiber: 1}, + ModNames.archaeology) bone_fence = skill_recipe(ModCraftable.bone_fence, ModSkill.archaeology, 8, {Fossil.bone_fragment: 2}, ModNames.archaeology) water_shifter = skill_recipe(ModCraftable.water_shifter, ModSkill.archaeology, 4, {Material.wood: 40, MetalBar.copper: 4}, ModNames.archaeology) wooden_display = skill_recipe(ModCraftable.wooden_display, ModSkill.archaeology, 1, {Material.wood: 25}, ModNames.archaeology) hardwood_display = skill_recipe(ModCraftable.hardwood_display, ModSkill.archaeology, 7, {Material.hardwood: 10}, ModNames.archaeology) -lucky_ring = skill_recipe(Ring.lucky_ring, ModSkill.archaeology, 8, {Artifact.elvish_jewelry: 1, AnimalProduct.rabbit_foot: 5, Mineral.tigerseye: 1}, ModNames.archaeology) +lucky_ring = skill_recipe(Ring.lucky_ring, ModSkill.archaeology, 8, {Artifact.elvish_jewelry: 1, AnimalProduct.rabbit_foot: 5, Mineral.tigerseye: 1}, + ModNames.archaeology) volcano_totem = skill_recipe(ModConsumable.volcano_totem, ModSkill.archaeology, 9, {Material.cinder_shard: 5, Artifact.rare_disc: 1, Artifact.dwarf_gadget: 1}, ModNames.archaeology) haste_elixir = shop_recipe(ModEdible.haste_elixir, SVERegion.alesia_shop, 35000, {Loot.void_essence: 35, ModLoot.void_soul: 5, Ingredient.sugar: 1, diff --git a/worlds/stardew_valley/data/recipe_data.py b/worlds/stardew_valley/data/recipe_data.py index 3123bb924307..667227cb9e2b 100644 --- a/worlds/stardew_valley/data/recipe_data.py +++ b/worlds/stardew_valley/data/recipe_data.py @@ -1,15 +1,16 @@ from typing import Dict, List, Optional -from ..mods.mod_data import ModNames + from .recipe_source import RecipeSource, FriendshipSource, SkillSource, QueenOfSauceSource, ShopSource, StarterSource, ShopTradeSource, ShopFriendshipSource +from ..mods.mod_data import ModNames from ..strings.animal_product_names import AnimalProduct from ..strings.artisan_good_names import ArtisanGood from ..strings.craftable_names import ModEdible, Edible from ..strings.crop_names import Fruit, Vegetable, SVEFruit, DistantLandsCrop from ..strings.fish_names import Fish, SVEFish, WaterItem, DistantLandsFish, SVEWaterItem from ..strings.flower_names import Flower -from ..strings.forageable_names import Forageable, SVEForage, DistantLandsForageable, Mushroom -from ..strings.ingredient_names import Ingredient from ..strings.food_names import Meal, SVEMeal, Beverage, DistantLandsMeal, BoardingHouseMeal, ArchaeologyMeal, TrashyMeal +from ..strings.forageable_names import Forageable, SVEForage, Mushroom +from ..strings.ingredient_names import Ingredient from ..strings.material_names import Material from ..strings.metal_names import Fossil, Artifact from ..strings.monster_drop_names import Loot @@ -45,7 +46,8 @@ def friendship_recipe(name: str, friend: str, hearts: int, ingredients: Dict[str return create_recipe(name, ingredients, source, mod_name) -def friendship_and_shop_recipe(name: str, friend: str, hearts: int, region: str, price: int, ingredients: Dict[str, int], mod_name: Optional[str] = None) -> CookingRecipe: +def friendship_and_shop_recipe(name: str, friend: str, hearts: int, region: str, price: int, ingredients: Dict[str, int], + mod_name: Optional[str] = None) -> CookingRecipe: source = ShopFriendshipSource(friend, hearts, region, price) return create_recipe(name, ingredients, source, mod_name) @@ -85,7 +87,8 @@ def create_recipe(name: str, ingredients: Dict[str, int], source: RecipeSource, artichoke_dip = queen_of_sauce_recipe(Meal.artichoke_dip, 1, Season.fall, 28, {Vegetable.artichoke: 1, AnimalProduct.cow_milk: 1}) autumn_bounty = friendship_recipe(Meal.autumn_bounty, NPC.demetrius, 7, {Vegetable.yam: 1, Vegetable.pumpkin: 1}) baked_fish = queen_of_sauce_recipe(Meal.baked_fish, 1, Season.summer, 7, {Fish.sunfish: 1, Fish.bream: 1, Ingredient.wheat_flour: 1}) -banana_pudding = shop_trade_recipe(Meal.banana_pudding, Region.island_trader, Fossil.bone_fragment, 30, {Fruit.banana: 1, AnimalProduct.cow_milk: 1, Ingredient.sugar: 1}) +banana_pudding = shop_trade_recipe(Meal.banana_pudding, Region.island_trader, Fossil.bone_fragment, 30, + {Fruit.banana: 1, AnimalProduct.cow_milk: 1, Ingredient.sugar: 1}) bean_hotpot = friendship_recipe(Meal.bean_hotpot, NPC.clint, 7, {Vegetable.green_bean: 2}) blackberry_cobbler_ingredients = {Forageable.blackberry: 2, Ingredient.sugar: 1, Ingredient.wheat_flour: 1} blackberry_cobbler_qos = queen_of_sauce_recipe(Meal.blackberry_cobbler, 2, Season.fall, 14, blackberry_cobbler_ingredients) @@ -181,21 +184,23 @@ def create_recipe(name: str, ingredients: Dict[str, int], source: RecipeSource, magic_elixir = shop_recipe(ModEdible.magic_elixir, Region.adventurer_guild, 3000, {Edible.life_elixir: 1, Mushroom.purple: 1}, ModNames.magic) baked_berry_oatmeal = shop_recipe(SVEMeal.baked_berry_oatmeal, SVERegion.bear_shop, 0, {Forageable.salmonberry: 15, Forageable.blackberry: 15, - Ingredient.sugar: 1, Ingredient.wheat_flour: 2}, ModNames.sve) + Ingredient.sugar: 1, Ingredient.wheat_flour: 2}, ModNames.sve) big_bark_burger = friendship_and_shop_recipe(SVEMeal.big_bark_burger, NPC.gus, 5, Region.saloon, 5500, {SVEFish.puppyfish: 1, Meal.bread: 1, Ingredient.oil: 1}, ModNames.sve) flower_cookie = shop_recipe(SVEMeal.flower_cookie, SVERegion.bear_shop, 0, {SVEForage.ferngill_primrose: 1, SVEForage.goldenrod: 1, - SVEForage.winter_star_rose: 1, Ingredient.wheat_flour: 1, Ingredient.sugar: 1, - AnimalProduct.large_egg: 1}, ModNames.sve) + SVEForage.winter_star_rose: 1, Ingredient.wheat_flour: 1, Ingredient.sugar: 1, + AnimalProduct.large_egg: 1}, ModNames.sve) frog_legs = shop_recipe(SVEMeal.frog_legs, Region.adventurer_guild, 2000, {SVEFish.frog: 1, Ingredient.oil: 1, Ingredient.wheat_flour: 1}, ModNames.sve) glazed_butterfish = friendship_and_shop_recipe(SVEMeal.glazed_butterfish, NPC.gus, 10, Region.saloon, 4000, {SVEFish.butterfish: 1, Ingredient.wheat_flour: 1, Ingredient.oil: 1}, ModNames.sve) mixed_berry_pie = shop_recipe(SVEMeal.mixed_berry_pie, Region.saloon, 3500, {Fruit.strawberry: 6, SVEFruit.salal_berry: 6, Forageable.blackberry: 6, SVEForage.bearberry: 6, Ingredient.sugar: 1, Ingredient.wheat_flour: 1}, ModNames.sve) -mushroom_berry_rice = friendship_and_shop_recipe(SVEMeal.mushroom_berry_rice, ModNPC.marlon, 6, Region.adventurer_guild, 1500, {SVEForage.poison_mushroom: 3, SVEForage.red_baneberry: 10, - Ingredient.rice: 1, Ingredient.sugar: 2}, ModNames.sve) -seaweed_salad = shop_recipe(SVEMeal.seaweed_salad, Region.fish_shop, 1250, {SVEWaterItem.dulse_seaweed: 2, WaterItem.seaweed: 2, Ingredient.oil: 1}, ModNames.sve) +mushroom_berry_rice = friendship_and_shop_recipe(SVEMeal.mushroom_berry_rice, ModNPC.marlon, 6, Region.adventurer_guild, 1500, + {SVEForage.poison_mushroom: 3, SVEForage.red_baneberry: 10, Ingredient.rice: 1, Ingredient.sugar: 2}, + ModNames.sve) +seaweed_salad = shop_recipe(SVEMeal.seaweed_salad, Region.fish_shop, 1250, {SVEWaterItem.dulse_seaweed: 2, WaterItem.seaweed: 2, Ingredient.oil: 1}, + ModNames.sve) void_delight = friendship_and_shop_recipe(SVEMeal.void_delight, NPC.krobus, 10, Region.sewer, 5000, {SVEFish.void_eel: 1, Loot.void_essence: 50, Loot.solar_essence: 20}, ModNames.sve) void_salmon_sushi = friendship_and_shop_recipe(SVEMeal.void_salmon_sushi, NPC.krobus, 10, Region.sewer, 5000, @@ -205,17 +210,22 @@ def create_recipe(name: str, ingredients: Dict[str, int], source: RecipeSource, Mushroom.red: 1, Material.wood: 1}, ModNames.distant_lands) void_mint_tea = friendship_recipe(DistantLandsMeal.void_mint_tea, ModNPC.goblin, 4, {DistantLandsCrop.void_mint: 1}, ModNames.distant_lands) crayfish_soup = friendship_recipe(DistantLandsMeal.crayfish_soup, ModNPC.goblin, 6, {Forageable.cave_carrot: 1, Fish.crayfish: 1, - DistantLandsFish.purple_algae: 1, WaterItem.white_algae: 1}, ModNames.distant_lands) + DistantLandsFish.purple_algae: 1, WaterItem.white_algae: 1}, + ModNames.distant_lands) pemmican = friendship_recipe(DistantLandsMeal.pemmican, ModNPC.goblin, 8, {Loot.bug_meat: 1, Fish.any: 1, Forageable.salmonberry: 3, Material.stone: 2}, ModNames.distant_lands) special_pumpkin_soup = friendship_recipe(BoardingHouseMeal.special_pumpkin_soup, ModNPC.joel, 6, {Vegetable.pumpkin: 2, AnimalProduct.large_goat_milk: 1, Vegetable.garlic: 1}, ModNames.boarding_house) -diggers_delight = skill_recipe(ArchaeologyMeal.diggers_delight, ModSkill.archaeology, 3, {Forageable.cave_carrot: 2, Ingredient.sugar: 1, AnimalProduct.milk: 1}, ModNames.archaeology) -rocky_root = skill_recipe(ArchaeologyMeal.rocky_root, ModSkill.archaeology, 7, {Forageable.cave_carrot: 3, Seed.coffee: 1, Material.stone: 1}, ModNames.archaeology) -ancient_jello = skill_recipe(ArchaeologyMeal.ancient_jello, ModSkill.archaeology, 9, {WaterItem.cave_jelly: 6, Ingredient.sugar: 5, AnimalProduct.egg: 1, AnimalProduct.milk: 1, Artifact.chipped_amphora: 1}, ModNames.archaeology) +diggers_delight = skill_recipe(ArchaeologyMeal.diggers_delight, ModSkill.archaeology, 3, + {Forageable.cave_carrot: 2, Ingredient.sugar: 1, AnimalProduct.milk: 1}, ModNames.archaeology) +rocky_root = skill_recipe(ArchaeologyMeal.rocky_root, ModSkill.archaeology, 7, {Forageable.cave_carrot: 3, Seed.coffee: 1, Material.stone: 1}, + ModNames.archaeology) +ancient_jello = skill_recipe(ArchaeologyMeal.ancient_jello, ModSkill.archaeology, 9, + {WaterItem.cave_jelly: 6, Ingredient.sugar: 5, AnimalProduct.egg: 1, AnimalProduct.milk: 1, Artifact.chipped_amphora: 1}, + ModNames.archaeology) grilled_cheese = skill_recipe(TrashyMeal.grilled_cheese, ModSkill.binning, 1, {Meal.bread: 1, ArtisanGood.cheese: 1}, ModNames.binning_skill) fish_casserole = skill_recipe(TrashyMeal.fish_casserole, ModSkill.binning, 8, {Fish.any: 1, AnimalProduct.milk: 1, Vegetable.carrot: 1}, ModNames.binning_skill) -all_cooking_recipes_by_name = {recipe.meal: recipe for recipe in all_cooking_recipes} \ No newline at end of file +all_cooking_recipes_by_name = {recipe.meal: recipe for recipe in all_cooking_recipes} diff --git a/worlds/stardew_valley/data/recipe_source.py b/worlds/stardew_valley/data/recipe_source.py index ead4d62f1650..bc8c09ee9241 100644 --- a/worlds/stardew_valley/data/recipe_source.py +++ b/worlds/stardew_valley/data/recipe_source.py @@ -106,7 +106,7 @@ def __init__(self, skill: str): self.skill = skill def __repr__(self): - return f"MasterySource at level {self.level} {self.skill}" + return f"MasterySource {self.skill}" class ShopSource(RecipeSource): diff --git a/worlds/stardew_valley/logic/ability_logic.py b/worlds/stardew_valley/logic/ability_logic.py index add99a2c2e7e..2038d995a720 100644 --- a/worlds/stardew_valley/logic/ability_logic.py +++ b/worlds/stardew_valley/logic/ability_logic.py @@ -1,7 +1,7 @@ +import typing from typing import Union from .base_logic import BaseLogicMixin, BaseLogic -from .cooking_logic import CookingLogicMixin from .mine_logic import MineLogicMixin from .received_logic import ReceivedLogicMixin from .region_logic import RegionLogicMixin @@ -13,6 +13,11 @@ from ..strings.skill_names import Skill, ModSkill from ..strings.tool_names import ToolMaterial, Tool +if typing.TYPE_CHECKING: + from ..mods.logic.mod_logic import ModLogicMixin +else: + ModLogicMixin = object + class AbilityLogicMixin(BaseLogicMixin): def __init__(self, *args, **kwargs): @@ -20,7 +25,8 @@ def __init__(self, *args, **kwargs): self.ability = AbilityLogic(*args, **kwargs) -class AbilityLogic(BaseLogic[Union[AbilityLogicMixin, RegionLogicMixin, ReceivedLogicMixin, ToolLogicMixin, SkillLogicMixin, MineLogicMixin, MagicLogicMixin]]): +class AbilityLogic(BaseLogic[Union[AbilityLogicMixin, RegionLogicMixin, ReceivedLogicMixin, ToolLogicMixin, SkillLogicMixin, MineLogicMixin, MagicLogicMixin, +ModLogicMixin]]): def can_mine_perfectly(self) -> StardewRule: return self.logic.mine.can_progress_in_the_mines_from_floor(160) diff --git a/worlds/stardew_valley/logic/action_logic.py b/worlds/stardew_valley/logic/action_logic.py index dc5deda427f3..5b117de68cf2 100644 --- a/worlds/stardew_valley/logic/action_logic.py +++ b/worlds/stardew_valley/logic/action_logic.py @@ -6,7 +6,6 @@ from .received_logic import ReceivedLogicMixin from .region_logic import RegionLogicMixin from .tool_logic import ToolLogicMixin -from ..options import ToolProgression from ..stardew_rule import StardewRule, True_ from ..strings.generic_names import Generic from ..strings.geode_names import Geode diff --git a/worlds/stardew_valley/logic/skill_logic.py b/worlds/stardew_valley/logic/skill_logic.py index bc2f6cb1263d..6d0cd11baf71 100644 --- a/worlds/stardew_valley/logic/skill_logic.py +++ b/worlds/stardew_valley/logic/skill_logic.py @@ -1,3 +1,4 @@ +import typing from functools import cached_property from typing import Union, Tuple @@ -24,6 +25,11 @@ from ..strings.tool_names import ToolMaterial, Tool from ..strings.wallet_item_names import Wallet +if typing.TYPE_CHECKING: + from ..mods.logic.mod_logic import ModLogicMixin +else: + ModLogicMixin = object + fishing_regions = (Region.beach, Region.town, Region.forest, Region.mountain, Region.island_south, Region.island_west) vanilla_skill_items = ("Farming Level", "Mining Level", "Foraging Level", "Fishing Level", "Combat Level") @@ -35,7 +41,7 @@ def __init__(self, *args, **kwargs): class SkillLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, RegionLogicMixin, SeasonLogicMixin, TimeLogicMixin, ToolLogicMixin, SkillLogicMixin, -CombatLogicMixin, MagicLogicMixin, HarvestingLogicMixin]]): +CombatLogicMixin, MagicLogicMixin, HarvestingLogicMixin, ModLogicMixin]]): # Should be cached def can_earn_level(self, skill: str, level: int) -> StardewRule: diff --git a/worlds/stardew_valley/mods/logic/item_logic.py b/worlds/stardew_valley/mods/logic/item_logic.py index ef5eab0134d1..12e824d21295 100644 --- a/worlds/stardew_valley/mods/logic/item_logic.py +++ b/worlds/stardew_valley/mods/logic/item_logic.py @@ -2,7 +2,6 @@ from ..mod_data import ModNames from ... import options -from ...data.craftable_data import all_crafting_recipes_by_name from ...logic.base_logic import BaseLogicMixin, BaseLogic from ...logic.combat_logic import CombatLogicMixin from ...logic.cooking_logic import CookingLogicMixin @@ -20,11 +19,9 @@ from ...logic.skill_logic import SkillLogicMixin from ...logic.time_logic import TimeLogicMixin from ...logic.tool_logic import ToolLogicMixin -from ...options import Cropsanity -from ...stardew_rule import StardewRule, True_ +from ...stardew_rule import StardewRule from ...strings.artisan_good_names import ModArtisanGood -from ...strings.craftable_names import ModCraftable, ModMachine -from ...strings.fish_names import ModTrash +from ...strings.craftable_names import ModCraftable from ...strings.ingredient_names import Ingredient from ...strings.material_names import Material from ...strings.metal_names import all_fossils, all_artifacts, Ore, ModFossil diff --git a/worlds/stardew_valley/mods/logic/quests_logic.py b/worlds/stardew_valley/mods/logic/quests_logic.py index 1aa71404ae51..2ff74523940e 100644 --- a/worlds/stardew_valley/mods/logic/quests_logic.py +++ b/worlds/stardew_valley/mods/logic/quests_logic.py @@ -3,8 +3,8 @@ from ..mod_data import ModNames from ...logic.base_logic import BaseLogic, BaseLogicMixin from ...logic.has_logic import HasLogicMixin -from ...logic.quest_logic import QuestLogicMixin from ...logic.monster_logic import MonsterLogicMixin +from ...logic.quest_logic import QuestLogicMixin from ...logic.received_logic import ReceivedLogicMixin from ...logic.region_logic import RegionLogicMixin from ...logic.relationship_logic import RelationshipLogicMixin @@ -16,7 +16,6 @@ from ...strings.crop_names import Fruit, SVEFruit, SVEVegetable, Vegetable from ...strings.fertilizer_names import Fertilizer from ...strings.food_names import Meal, Beverage -from ...strings.forageable_names import SVEForage from ...strings.material_names import Material from ...strings.metal_names import Ore, MetalBar from ...strings.monster_drop_names import Loot, ModLoot @@ -35,7 +34,7 @@ def __init__(self, *args, **kwargs): class ModQuestLogic(BaseLogic[Union[HasLogicMixin, QuestLogicMixin, ReceivedLogicMixin, RegionLogicMixin, - TimeLogicMixin, SeasonLogicMixin, RelationshipLogicMixin, MonsterLogicMixin]]): +TimeLogicMixin, SeasonLogicMixin, RelationshipLogicMixin, MonsterLogicMixin]]): def get_modded_quest_rules(self) -> Dict[str, StardewRule]: quests = dict() quests.update(self._get_juna_quest_rules()) diff --git a/worlds/stardew_valley/regions.py b/worlds/stardew_valley/regions.py index d59439a4879d..7a680d5faad0 100644 --- a/worlds/stardew_valley/regions.py +++ b/worlds/stardew_valley/regions.py @@ -7,7 +7,7 @@ from .options import EntranceRandomization, ExcludeGingerIsland, StardewValleyOptions from .region_classes import RegionData, ConnectionData, RandomizationFlag, ModificationFlag from .strings.entrance_names import Entrance, LogicEntrance -from .strings.region_names import Region, LogicRegion +from .strings.region_names import Region as RegionName, LogicRegion class RegionFactory(Protocol): @@ -16,192 +16,192 @@ def __call__(self, name: str, regions: Iterable[str]) -> Region: vanilla_regions = [ - RegionData(Region.menu, [Entrance.to_stardew_valley]), - RegionData(Region.stardew_valley, [Entrance.to_farmhouse]), - RegionData(Region.farm_house, + RegionData(RegionName.menu, [Entrance.to_stardew_valley]), + RegionData(RegionName.stardew_valley, [Entrance.to_farmhouse]), + RegionData(RegionName.farm_house, [Entrance.farmhouse_to_farm, Entrance.downstairs_to_cellar, LogicEntrance.farmhouse_cooking, LogicEntrance.watch_queen_of_sauce]), - RegionData(Region.cellar), - RegionData(Region.farm, + RegionData(RegionName.cellar), + RegionData(RegionName.farm, [Entrance.farm_to_backwoods, Entrance.farm_to_bus_stop, Entrance.farm_to_forest, Entrance.farm_to_farmcave, Entrance.enter_greenhouse, Entrance.enter_coop, Entrance.enter_barn, Entrance.enter_shed, Entrance.enter_slime_hutch, LogicEntrance.grow_spring_crops, LogicEntrance.grow_summer_crops, LogicEntrance.grow_fall_crops, LogicEntrance.grow_winter_crops, LogicEntrance.shipping]), - RegionData(Region.backwoods, [Entrance.backwoods_to_mountain]), - RegionData(Region.bus_stop, + RegionData(RegionName.backwoods, [Entrance.backwoods_to_mountain]), + RegionData(RegionName.bus_stop, [Entrance.bus_stop_to_town, Entrance.take_bus_to_desert, Entrance.bus_stop_to_tunnel_entrance]), - RegionData(Region.forest, + RegionData(RegionName.forest, [Entrance.forest_to_town, Entrance.enter_secret_woods, Entrance.forest_to_wizard_tower, Entrance.forest_to_marnie_ranch, Entrance.forest_to_leah_cottage, Entrance.forest_to_sewer, Entrance.forest_to_mastery_cave, LogicEntrance.buy_from_traveling_merchant, LogicEntrance.complete_raccoon_requests, LogicEntrance.fish_in_waterfall, LogicEntrance.attend_flower_dance, LogicEntrance.attend_trout_derby, LogicEntrance.attend_festival_of_ice]), RegionData(LogicRegion.forest_waterfall), - RegionData(Region.farm_cave), - RegionData(Region.greenhouse, + RegionData(RegionName.farm_cave), + RegionData(RegionName.greenhouse, [LogicEntrance.grow_spring_crops_in_greenhouse, LogicEntrance.grow_summer_crops_in_greenhouse, LogicEntrance.grow_fall_crops_in_greenhouse, LogicEntrance.grow_winter_crops_in_greenhouse, LogicEntrance.grow_indoor_crops_in_greenhouse]), - RegionData(Region.mountain, + RegionData(RegionName.mountain, [Entrance.mountain_to_railroad, Entrance.mountain_to_tent, Entrance.mountain_to_carpenter_shop, Entrance.mountain_to_the_mines, Entrance.enter_quarry, Entrance.mountain_to_adventurer_guild, Entrance.mountain_to_town, Entrance.mountain_to_maru_room, Entrance.mountain_to_leo_treehouse]), - RegionData(Region.leo_treehouse, is_ginger_island=True), - RegionData(Region.maru_room), - RegionData(Region.tunnel_entrance, [Entrance.tunnel_entrance_to_bus_tunnel]), - RegionData(Region.bus_tunnel), - RegionData(Region.town, + RegionData(RegionName.leo_treehouse, is_ginger_island=True), + RegionData(RegionName.maru_room), + RegionData(RegionName.tunnel_entrance, [Entrance.tunnel_entrance_to_bus_tunnel]), + RegionData(RegionName.bus_tunnel), + RegionData(RegionName.town, [Entrance.town_to_community_center, Entrance.town_to_beach, Entrance.town_to_hospital, Entrance.town_to_pierre_general_store, Entrance.town_to_saloon, Entrance.town_to_alex_house, Entrance.town_to_trailer, Entrance.town_to_mayor_manor, Entrance.town_to_sam_house, Entrance.town_to_haley_house, Entrance.town_to_sewer, Entrance.town_to_clint_blacksmith, Entrance.town_to_museum, Entrance.town_to_jojamart, Entrance.purchase_movie_ticket, LogicEntrance.buy_experience_books, LogicEntrance.attend_egg_festival, LogicEntrance.attend_fair, LogicEntrance.attend_spirit_eve, LogicEntrance.attend_winter_star]), - RegionData(Region.beach, + RegionData(RegionName.beach, [Entrance.beach_to_willy_fish_shop, Entrance.enter_elliott_house, Entrance.enter_tide_pools, LogicEntrance.fishing, LogicEntrance.attend_luau, LogicEntrance.attend_moonlight_jellies, LogicEntrance.attend_night_market, LogicEntrance.attend_squidfest]), - RegionData(Region.railroad, [Entrance.enter_bathhouse_entrance, Entrance.enter_witch_warp_cave]), - RegionData(Region.ranch), - RegionData(Region.leah_house), - RegionData(Region.mastery_cave), - RegionData(Region.sewer, [Entrance.enter_mutant_bug_lair]), - RegionData(Region.mutant_bug_lair), - RegionData(Region.wizard_tower, [Entrance.enter_wizard_basement, Entrance.use_desert_obelisk, Entrance.use_island_obelisk]), - RegionData(Region.wizard_basement), - RegionData(Region.tent), - RegionData(Region.carpenter, [Entrance.enter_sebastian_room]), - RegionData(Region.sebastian_room), - RegionData(Region.adventurer_guild, [Entrance.adventurer_guild_to_bedroom]), - RegionData(Region.adventurer_guild_bedroom), - RegionData(Region.community_center, + RegionData(RegionName.railroad, [Entrance.enter_bathhouse_entrance, Entrance.enter_witch_warp_cave]), + RegionData(RegionName.ranch), + RegionData(RegionName.leah_house), + RegionData(RegionName.mastery_cave), + RegionData(RegionName.sewer, [Entrance.enter_mutant_bug_lair]), + RegionData(RegionName.mutant_bug_lair), + RegionData(RegionName.wizard_tower, [Entrance.enter_wizard_basement, Entrance.use_desert_obelisk, Entrance.use_island_obelisk]), + RegionData(RegionName.wizard_basement), + RegionData(RegionName.tent), + RegionData(RegionName.carpenter, [Entrance.enter_sebastian_room]), + RegionData(RegionName.sebastian_room), + RegionData(RegionName.adventurer_guild, [Entrance.adventurer_guild_to_bedroom]), + RegionData(RegionName.adventurer_guild_bedroom), + RegionData(RegionName.community_center, [Entrance.access_crafts_room, Entrance.access_pantry, Entrance.access_fish_tank, Entrance.access_boiler_room, Entrance.access_bulletin_board, Entrance.access_vault]), - RegionData(Region.crafts_room), - RegionData(Region.pantry), - RegionData(Region.fish_tank), - RegionData(Region.boiler_room), - RegionData(Region.bulletin_board), - RegionData(Region.vault), - RegionData(Region.hospital, [Entrance.enter_harvey_room]), - RegionData(Region.harvey_room), - RegionData(Region.pierre_store, [Entrance.enter_sunroom]), - RegionData(Region.sunroom), - RegionData(Region.saloon, [Entrance.play_journey_of_the_prairie_king, Entrance.play_junimo_kart]), - RegionData(Region.jotpk_world_1, [Entrance.reach_jotpk_world_2]), - RegionData(Region.jotpk_world_2, [Entrance.reach_jotpk_world_3]), - RegionData(Region.jotpk_world_3), - RegionData(Region.junimo_kart_1, [Entrance.reach_junimo_kart_2]), - RegionData(Region.junimo_kart_2, [Entrance.reach_junimo_kart_3]), - RegionData(Region.junimo_kart_3, [Entrance.reach_junimo_kart_4]), - RegionData(Region.junimo_kart_4), - RegionData(Region.alex_house), - RegionData(Region.trailer), - RegionData(Region.mayor_house), - RegionData(Region.sam_house), - RegionData(Region.haley_house), - RegionData(Region.blacksmith, [LogicEntrance.blacksmith_copper]), - RegionData(Region.museum), - RegionData(Region.jojamart, [Entrance.enter_abandoned_jojamart]), - RegionData(Region.abandoned_jojamart, [Entrance.enter_movie_theater]), - RegionData(Region.movie_ticket_stand), - RegionData(Region.movie_theater), - RegionData(Region.fish_shop, [Entrance.fish_shop_to_boat_tunnel]), - RegionData(Region.boat_tunnel, [Entrance.boat_to_ginger_island], is_ginger_island=True), - RegionData(Region.elliott_house), - RegionData(Region.tide_pools), - RegionData(Region.bathhouse_entrance, [Entrance.enter_locker_room]), - RegionData(Region.locker_room, [Entrance.enter_public_bath]), - RegionData(Region.public_bath), - RegionData(Region.witch_warp_cave, [Entrance.enter_witch_swamp]), - RegionData(Region.witch_swamp, [Entrance.enter_witch_hut]), - RegionData(Region.witch_hut, [Entrance.witch_warp_to_wizard_basement]), - RegionData(Region.quarry, [Entrance.enter_quarry_mine_entrance]), - RegionData(Region.quarry_mine_entrance, [Entrance.enter_quarry_mine]), - RegionData(Region.quarry_mine), - RegionData(Region.secret_woods), - RegionData(Region.desert, [Entrance.enter_skull_cavern_entrance, Entrance.enter_oasis, LogicEntrance.attend_desert_festival]), - RegionData(Region.oasis, [Entrance.enter_casino]), - RegionData(Region.casino), - RegionData(Region.skull_cavern_entrance, [Entrance.enter_skull_cavern]), - RegionData(Region.skull_cavern, [Entrance.mine_to_skull_cavern_floor_25]), - RegionData(Region.skull_cavern_25, [Entrance.mine_to_skull_cavern_floor_50]), - RegionData(Region.skull_cavern_50, [Entrance.mine_to_skull_cavern_floor_75]), - RegionData(Region.skull_cavern_75, [Entrance.mine_to_skull_cavern_floor_100]), - RegionData(Region.skull_cavern_100, [Entrance.mine_to_skull_cavern_floor_125]), - RegionData(Region.skull_cavern_125, [Entrance.mine_to_skull_cavern_floor_150]), - RegionData(Region.skull_cavern_150, [Entrance.mine_to_skull_cavern_floor_175]), - RegionData(Region.skull_cavern_175, [Entrance.mine_to_skull_cavern_floor_200]), - RegionData(Region.skull_cavern_200, [Entrance.enter_dangerous_skull_cavern]), - RegionData(Region.dangerous_skull_cavern, is_ginger_island=True), - RegionData(Region.island_south, + RegionData(RegionName.crafts_room), + RegionData(RegionName.pantry), + RegionData(RegionName.fish_tank), + RegionData(RegionName.boiler_room), + RegionData(RegionName.bulletin_board), + RegionData(RegionName.vault), + RegionData(RegionName.hospital, [Entrance.enter_harvey_room]), + RegionData(RegionName.harvey_room), + RegionData(RegionName.pierre_store, [Entrance.enter_sunroom]), + RegionData(RegionName.sunroom), + RegionData(RegionName.saloon, [Entrance.play_journey_of_the_prairie_king, Entrance.play_junimo_kart]), + RegionData(RegionName.jotpk_world_1, [Entrance.reach_jotpk_world_2]), + RegionData(RegionName.jotpk_world_2, [Entrance.reach_jotpk_world_3]), + RegionData(RegionName.jotpk_world_3), + RegionData(RegionName.junimo_kart_1, [Entrance.reach_junimo_kart_2]), + RegionData(RegionName.junimo_kart_2, [Entrance.reach_junimo_kart_3]), + RegionData(RegionName.junimo_kart_3, [Entrance.reach_junimo_kart_4]), + RegionData(RegionName.junimo_kart_4), + RegionData(RegionName.alex_house), + RegionData(RegionName.trailer), + RegionData(RegionName.mayor_house), + RegionData(RegionName.sam_house), + RegionData(RegionName.haley_house), + RegionData(RegionName.blacksmith, [LogicEntrance.blacksmith_copper]), + RegionData(RegionName.museum), + RegionData(RegionName.jojamart, [Entrance.enter_abandoned_jojamart]), + RegionData(RegionName.abandoned_jojamart, [Entrance.enter_movie_theater]), + RegionData(RegionName.movie_ticket_stand), + RegionData(RegionName.movie_theater), + RegionData(RegionName.fish_shop, [Entrance.fish_shop_to_boat_tunnel]), + RegionData(RegionName.boat_tunnel, [Entrance.boat_to_ginger_island], is_ginger_island=True), + RegionData(RegionName.elliott_house), + RegionData(RegionName.tide_pools), + RegionData(RegionName.bathhouse_entrance, [Entrance.enter_locker_room]), + RegionData(RegionName.locker_room, [Entrance.enter_public_bath]), + RegionData(RegionName.public_bath), + RegionData(RegionName.witch_warp_cave, [Entrance.enter_witch_swamp]), + RegionData(RegionName.witch_swamp, [Entrance.enter_witch_hut]), + RegionData(RegionName.witch_hut, [Entrance.witch_warp_to_wizard_basement]), + RegionData(RegionName.quarry, [Entrance.enter_quarry_mine_entrance]), + RegionData(RegionName.quarry_mine_entrance, [Entrance.enter_quarry_mine]), + RegionData(RegionName.quarry_mine), + RegionData(RegionName.secret_woods), + RegionData(RegionName.desert, [Entrance.enter_skull_cavern_entrance, Entrance.enter_oasis, LogicEntrance.attend_desert_festival]), + RegionData(RegionName.oasis, [Entrance.enter_casino]), + RegionData(RegionName.casino), + RegionData(RegionName.skull_cavern_entrance, [Entrance.enter_skull_cavern]), + RegionData(RegionName.skull_cavern, [Entrance.mine_to_skull_cavern_floor_25]), + RegionData(RegionName.skull_cavern_25, [Entrance.mine_to_skull_cavern_floor_50]), + RegionData(RegionName.skull_cavern_50, [Entrance.mine_to_skull_cavern_floor_75]), + RegionData(RegionName.skull_cavern_75, [Entrance.mine_to_skull_cavern_floor_100]), + RegionData(RegionName.skull_cavern_100, [Entrance.mine_to_skull_cavern_floor_125]), + RegionData(RegionName.skull_cavern_125, [Entrance.mine_to_skull_cavern_floor_150]), + RegionData(RegionName.skull_cavern_150, [Entrance.mine_to_skull_cavern_floor_175]), + RegionData(RegionName.skull_cavern_175, [Entrance.mine_to_skull_cavern_floor_200]), + RegionData(RegionName.skull_cavern_200, [Entrance.enter_dangerous_skull_cavern]), + RegionData(RegionName.dangerous_skull_cavern, is_ginger_island=True), + RegionData(RegionName.island_south, [Entrance.island_south_to_west, Entrance.island_south_to_north, Entrance.island_south_to_east, Entrance.island_south_to_southeast, Entrance.use_island_resort, Entrance.parrot_express_docks_to_volcano, Entrance.parrot_express_docks_to_dig_site, Entrance.parrot_express_docks_to_jungle], is_ginger_island=True), - RegionData(Region.island_resort, is_ginger_island=True), - RegionData(Region.island_west, + RegionData(RegionName.island_resort, is_ginger_island=True), + RegionData(RegionName.island_west, [Entrance.island_west_to_islandfarmhouse, Entrance.island_west_to_gourmand_cave, Entrance.island_west_to_crystals_cave, Entrance.island_west_to_shipwreck, Entrance.island_west_to_qi_walnut_room, Entrance.use_farm_obelisk, Entrance.parrot_express_jungle_to_docks, Entrance.parrot_express_jungle_to_dig_site, Entrance.parrot_express_jungle_to_volcano, LogicEntrance.grow_spring_crops_on_island, LogicEntrance.grow_summer_crops_on_island, LogicEntrance.grow_fall_crops_on_island, LogicEntrance.grow_winter_crops_on_island, LogicEntrance.grow_indoor_crops_on_island], is_ginger_island=True), - RegionData(Region.island_east, [Entrance.island_east_to_leo_hut, Entrance.island_east_to_island_shrine], is_ginger_island=True), - RegionData(Region.island_shrine, is_ginger_island=True), - RegionData(Region.island_south_east, [Entrance.island_southeast_to_pirate_cove], is_ginger_island=True), - RegionData(Region.island_north, + RegionData(RegionName.island_east, [Entrance.island_east_to_leo_hut, Entrance.island_east_to_island_shrine], is_ginger_island=True), + RegionData(RegionName.island_shrine, is_ginger_island=True), + RegionData(RegionName.island_south_east, [Entrance.island_southeast_to_pirate_cove], is_ginger_island=True), + RegionData(RegionName.island_north, [Entrance.talk_to_island_trader, Entrance.island_north_to_field_office, Entrance.island_north_to_dig_site, Entrance.island_north_to_volcano, Entrance.parrot_express_volcano_to_dig_site, Entrance.parrot_express_volcano_to_jungle, Entrance.parrot_express_volcano_to_docks], is_ginger_island=True), - RegionData(Region.volcano, [Entrance.climb_to_volcano_5, Entrance.volcano_to_secret_beach], is_ginger_island=True), - RegionData(Region.volcano_secret_beach, is_ginger_island=True), - RegionData(Region.volcano_floor_5, [Entrance.talk_to_volcano_dwarf, Entrance.climb_to_volcano_10], is_ginger_island=True), - RegionData(Region.volcano_dwarf_shop, is_ginger_island=True), - RegionData(Region.volcano_floor_10, is_ginger_island=True), - RegionData(Region.island_trader, is_ginger_island=True), - RegionData(Region.island_farmhouse, [LogicEntrance.island_cooking], is_ginger_island=True), - RegionData(Region.gourmand_frog_cave, is_ginger_island=True), - RegionData(Region.colored_crystals_cave, is_ginger_island=True), - RegionData(Region.shipwreck, is_ginger_island=True), - RegionData(Region.qi_walnut_room, is_ginger_island=True), - RegionData(Region.leo_hut, is_ginger_island=True), - RegionData(Region.pirate_cove, is_ginger_island=True), - RegionData(Region.field_office, is_ginger_island=True), - RegionData(Region.dig_site, + RegionData(RegionName.volcano, [Entrance.climb_to_volcano_5, Entrance.volcano_to_secret_beach], is_ginger_island=True), + RegionData(RegionName.volcano_secret_beach, is_ginger_island=True), + RegionData(RegionName.volcano_floor_5, [Entrance.talk_to_volcano_dwarf, Entrance.climb_to_volcano_10], is_ginger_island=True), + RegionData(RegionName.volcano_dwarf_shop, is_ginger_island=True), + RegionData(RegionName.volcano_floor_10, is_ginger_island=True), + RegionData(RegionName.island_trader, is_ginger_island=True), + RegionData(RegionName.island_farmhouse, [LogicEntrance.island_cooking], is_ginger_island=True), + RegionData(RegionName.gourmand_frog_cave, is_ginger_island=True), + RegionData(RegionName.colored_crystals_cave, is_ginger_island=True), + RegionData(RegionName.shipwreck, is_ginger_island=True), + RegionData(RegionName.qi_walnut_room, is_ginger_island=True), + RegionData(RegionName.leo_hut, is_ginger_island=True), + RegionData(RegionName.pirate_cove, is_ginger_island=True), + RegionData(RegionName.field_office, is_ginger_island=True), + RegionData(RegionName.dig_site, [Entrance.dig_site_to_professor_snail_cave, Entrance.parrot_express_dig_site_to_volcano, Entrance.parrot_express_dig_site_to_docks, Entrance.parrot_express_dig_site_to_jungle], is_ginger_island=True), - RegionData(Region.professor_snail_cave, is_ginger_island=True), - RegionData(Region.coop), - RegionData(Region.barn), - RegionData(Region.shed), - RegionData(Region.slime_hutch), - - RegionData(Region.mines, [LogicEntrance.talk_to_mines_dwarf, - Entrance.dig_to_mines_floor_5]), - RegionData(Region.mines_floor_5, [Entrance.dig_to_mines_floor_10]), - RegionData(Region.mines_floor_10, [Entrance.dig_to_mines_floor_15]), - RegionData(Region.mines_floor_15, [Entrance.dig_to_mines_floor_20]), - RegionData(Region.mines_floor_20, [Entrance.dig_to_mines_floor_25]), - RegionData(Region.mines_floor_25, [Entrance.dig_to_mines_floor_30]), - RegionData(Region.mines_floor_30, [Entrance.dig_to_mines_floor_35]), - RegionData(Region.mines_floor_35, [Entrance.dig_to_mines_floor_40]), - RegionData(Region.mines_floor_40, [Entrance.dig_to_mines_floor_45]), - RegionData(Region.mines_floor_45, [Entrance.dig_to_mines_floor_50]), - RegionData(Region.mines_floor_50, [Entrance.dig_to_mines_floor_55]), - RegionData(Region.mines_floor_55, [Entrance.dig_to_mines_floor_60]), - RegionData(Region.mines_floor_60, [Entrance.dig_to_mines_floor_65]), - RegionData(Region.mines_floor_65, [Entrance.dig_to_mines_floor_70]), - RegionData(Region.mines_floor_70, [Entrance.dig_to_mines_floor_75]), - RegionData(Region.mines_floor_75, [Entrance.dig_to_mines_floor_80]), - RegionData(Region.mines_floor_80, [Entrance.dig_to_mines_floor_85]), - RegionData(Region.mines_floor_85, [Entrance.dig_to_mines_floor_90]), - RegionData(Region.mines_floor_90, [Entrance.dig_to_mines_floor_95]), - RegionData(Region.mines_floor_95, [Entrance.dig_to_mines_floor_100]), - RegionData(Region.mines_floor_100, [Entrance.dig_to_mines_floor_105]), - RegionData(Region.mines_floor_105, [Entrance.dig_to_mines_floor_110]), - RegionData(Region.mines_floor_110, [Entrance.dig_to_mines_floor_115]), - RegionData(Region.mines_floor_115, [Entrance.dig_to_mines_floor_120]), - RegionData(Region.mines_floor_120, [Entrance.dig_to_dangerous_mines_20, Entrance.dig_to_dangerous_mines_60, Entrance.dig_to_dangerous_mines_100]), - RegionData(Region.dangerous_mines_20, is_ginger_island=True), - RegionData(Region.dangerous_mines_60, is_ginger_island=True), - RegionData(Region.dangerous_mines_100, is_ginger_island=True), + RegionData(RegionName.professor_snail_cave, is_ginger_island=True), + RegionData(RegionName.coop), + RegionData(RegionName.barn), + RegionData(RegionName.shed), + RegionData(RegionName.slime_hutch), + + RegionData(RegionName.mines, [LogicEntrance.talk_to_mines_dwarf, + Entrance.dig_to_mines_floor_5]), + RegionData(RegionName.mines_floor_5, [Entrance.dig_to_mines_floor_10]), + RegionData(RegionName.mines_floor_10, [Entrance.dig_to_mines_floor_15]), + RegionData(RegionName.mines_floor_15, [Entrance.dig_to_mines_floor_20]), + RegionData(RegionName.mines_floor_20, [Entrance.dig_to_mines_floor_25]), + RegionData(RegionName.mines_floor_25, [Entrance.dig_to_mines_floor_30]), + RegionData(RegionName.mines_floor_30, [Entrance.dig_to_mines_floor_35]), + RegionData(RegionName.mines_floor_35, [Entrance.dig_to_mines_floor_40]), + RegionData(RegionName.mines_floor_40, [Entrance.dig_to_mines_floor_45]), + RegionData(RegionName.mines_floor_45, [Entrance.dig_to_mines_floor_50]), + RegionData(RegionName.mines_floor_50, [Entrance.dig_to_mines_floor_55]), + RegionData(RegionName.mines_floor_55, [Entrance.dig_to_mines_floor_60]), + RegionData(RegionName.mines_floor_60, [Entrance.dig_to_mines_floor_65]), + RegionData(RegionName.mines_floor_65, [Entrance.dig_to_mines_floor_70]), + RegionData(RegionName.mines_floor_70, [Entrance.dig_to_mines_floor_75]), + RegionData(RegionName.mines_floor_75, [Entrance.dig_to_mines_floor_80]), + RegionData(RegionName.mines_floor_80, [Entrance.dig_to_mines_floor_85]), + RegionData(RegionName.mines_floor_85, [Entrance.dig_to_mines_floor_90]), + RegionData(RegionName.mines_floor_90, [Entrance.dig_to_mines_floor_95]), + RegionData(RegionName.mines_floor_95, [Entrance.dig_to_mines_floor_100]), + RegionData(RegionName.mines_floor_100, [Entrance.dig_to_mines_floor_105]), + RegionData(RegionName.mines_floor_105, [Entrance.dig_to_mines_floor_110]), + RegionData(RegionName.mines_floor_110, [Entrance.dig_to_mines_floor_115]), + RegionData(RegionName.mines_floor_115, [Entrance.dig_to_mines_floor_120]), + RegionData(RegionName.mines_floor_120, [Entrance.dig_to_dangerous_mines_20, Entrance.dig_to_dangerous_mines_60, Entrance.dig_to_dangerous_mines_100]), + RegionData(RegionName.dangerous_mines_20, is_ginger_island=True), + RegionData(RegionName.dangerous_mines_60, is_ginger_island=True), + RegionData(RegionName.dangerous_mines_100, is_ginger_island=True), RegionData(LogicRegion.mines_dwarf_shop), RegionData(LogicRegion.blacksmith_copper, [LogicEntrance.blacksmith_iron]), @@ -256,206 +256,207 @@ def __call__(self, name: str, regions: Iterable[str]) -> Region: # Exists and where they lead vanilla_connections = [ - ConnectionData(Entrance.to_stardew_valley, Region.stardew_valley), - ConnectionData(Entrance.to_farmhouse, Region.farm_house), - ConnectionData(Entrance.farmhouse_to_farm, Region.farm), - ConnectionData(Entrance.downstairs_to_cellar, Region.cellar), - ConnectionData(Entrance.farm_to_backwoods, Region.backwoods), - ConnectionData(Entrance.farm_to_bus_stop, Region.bus_stop), - ConnectionData(Entrance.farm_to_forest, Region.forest), - ConnectionData(Entrance.farm_to_farmcave, Region.farm_cave, flag=RandomizationFlag.NON_PROGRESSION), - ConnectionData(Entrance.enter_greenhouse, Region.greenhouse), - ConnectionData(Entrance.enter_coop, Region.coop), - ConnectionData(Entrance.enter_barn, Region.barn), - ConnectionData(Entrance.enter_shed, Region.shed), - ConnectionData(Entrance.enter_slime_hutch, Region.slime_hutch), - ConnectionData(Entrance.use_desert_obelisk, Region.desert), - ConnectionData(Entrance.use_island_obelisk, Region.island_south, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.use_farm_obelisk, Region.farm), - ConnectionData(Entrance.backwoods_to_mountain, Region.mountain), - ConnectionData(Entrance.bus_stop_to_town, Region.town), - ConnectionData(Entrance.bus_stop_to_tunnel_entrance, Region.tunnel_entrance), - ConnectionData(Entrance.tunnel_entrance_to_bus_tunnel, Region.bus_tunnel, flag=RandomizationFlag.NON_PROGRESSION), - ConnectionData(Entrance.take_bus_to_desert, Region.desert), - ConnectionData(Entrance.forest_to_town, Region.town), - ConnectionData(Entrance.forest_to_wizard_tower, Region.wizard_tower, + ConnectionData(Entrance.to_stardew_valley, RegionName.stardew_valley), + ConnectionData(Entrance.to_farmhouse, RegionName.farm_house), + ConnectionData(Entrance.farmhouse_to_farm, RegionName.farm), + ConnectionData(Entrance.downstairs_to_cellar, RegionName.cellar), + ConnectionData(Entrance.farm_to_backwoods, RegionName.backwoods), + ConnectionData(Entrance.farm_to_bus_stop, RegionName.bus_stop), + ConnectionData(Entrance.farm_to_forest, RegionName.forest), + ConnectionData(Entrance.farm_to_farmcave, RegionName.farm_cave, flag=RandomizationFlag.NON_PROGRESSION), + ConnectionData(Entrance.enter_greenhouse, RegionName.greenhouse), + ConnectionData(Entrance.enter_coop, RegionName.coop), + ConnectionData(Entrance.enter_barn, RegionName.barn), + ConnectionData(Entrance.enter_shed, RegionName.shed), + ConnectionData(Entrance.enter_slime_hutch, RegionName.slime_hutch), + ConnectionData(Entrance.use_desert_obelisk, RegionName.desert), + ConnectionData(Entrance.use_island_obelisk, RegionName.island_south, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.use_farm_obelisk, RegionName.farm), + ConnectionData(Entrance.backwoods_to_mountain, RegionName.mountain), + ConnectionData(Entrance.bus_stop_to_town, RegionName.town), + ConnectionData(Entrance.bus_stop_to_tunnel_entrance, RegionName.tunnel_entrance), + ConnectionData(Entrance.tunnel_entrance_to_bus_tunnel, RegionName.bus_tunnel, flag=RandomizationFlag.NON_PROGRESSION), + ConnectionData(Entrance.take_bus_to_desert, RegionName.desert), + ConnectionData(Entrance.forest_to_town, RegionName.town), + ConnectionData(Entrance.forest_to_wizard_tower, RegionName.wizard_tower, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_wizard_basement, Region.wizard_basement, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.forest_to_marnie_ranch, Region.ranch, + ConnectionData(Entrance.enter_wizard_basement, RegionName.wizard_basement, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.forest_to_marnie_ranch, RegionName.ranch, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.forest_to_leah_cottage, Region.leah_house, + ConnectionData(Entrance.forest_to_leah_cottage, RegionName.leah_house, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_secret_woods, Region.secret_woods), - ConnectionData(Entrance.forest_to_sewer, Region.sewer, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.forest_to_mastery_cave, Region.mastery_cave, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.MASTERIES), - ConnectionData(Entrance.town_to_sewer, Region.sewer, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_mutant_bug_lair, Region.mutant_bug_lair, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.mountain_to_railroad, Region.railroad), - ConnectionData(Entrance.mountain_to_tent, Region.tent, + ConnectionData(Entrance.enter_secret_woods, RegionName.secret_woods), + ConnectionData(Entrance.forest_to_sewer, RegionName.sewer, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.forest_to_mastery_cave, RegionName.mastery_cave, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.MASTERIES), + ConnectionData(Entrance.town_to_sewer, RegionName.sewer, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_mutant_bug_lair, RegionName.mutant_bug_lair, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.mountain_to_railroad, RegionName.railroad), + ConnectionData(Entrance.mountain_to_tent, RegionName.tent, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.mountain_to_leo_treehouse, Region.leo_treehouse, + ConnectionData(Entrance.mountain_to_leo_treehouse, RegionName.leo_treehouse, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.mountain_to_carpenter_shop, Region.carpenter, + ConnectionData(Entrance.mountain_to_carpenter_shop, RegionName.carpenter, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.mountain_to_maru_room, Region.maru_room, + ConnectionData(Entrance.mountain_to_maru_room, RegionName.maru_room, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_sebastian_room, Region.sebastian_room, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.mountain_to_adventurer_guild, Region.adventurer_guild, + ConnectionData(Entrance.enter_sebastian_room, RegionName.sebastian_room, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.mountain_to_adventurer_guild, RegionName.adventurer_guild, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.adventurer_guild_to_bedroom, Region.adventurer_guild_bedroom), - ConnectionData(Entrance.enter_quarry, Region.quarry), - ConnectionData(Entrance.enter_quarry_mine_entrance, Region.quarry_mine_entrance, + ConnectionData(Entrance.adventurer_guild_to_bedroom, RegionName.adventurer_guild_bedroom), + ConnectionData(Entrance.enter_quarry, RegionName.quarry), + ConnectionData(Entrance.enter_quarry_mine_entrance, RegionName.quarry_mine_entrance, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_quarry_mine, Region.quarry_mine), - ConnectionData(Entrance.mountain_to_town, Region.town), - ConnectionData(Entrance.town_to_community_center, Region.community_center, + ConnectionData(Entrance.enter_quarry_mine, RegionName.quarry_mine), + ConnectionData(Entrance.mountain_to_town, RegionName.town), + ConnectionData(Entrance.town_to_community_center, RegionName.community_center, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.access_crafts_room, Region.crafts_room), - ConnectionData(Entrance.access_pantry, Region.pantry), - ConnectionData(Entrance.access_fish_tank, Region.fish_tank), - ConnectionData(Entrance.access_boiler_room, Region.boiler_room), - ConnectionData(Entrance.access_bulletin_board, Region.bulletin_board), - ConnectionData(Entrance.access_vault, Region.vault), - ConnectionData(Entrance.town_to_hospital, Region.hospital, + ConnectionData(Entrance.access_crafts_room, RegionName.crafts_room), + ConnectionData(Entrance.access_pantry, RegionName.pantry), + ConnectionData(Entrance.access_fish_tank, RegionName.fish_tank), + ConnectionData(Entrance.access_boiler_room, RegionName.boiler_room), + ConnectionData(Entrance.access_bulletin_board, RegionName.bulletin_board), + ConnectionData(Entrance.access_vault, RegionName.vault), + ConnectionData(Entrance.town_to_hospital, RegionName.hospital, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_harvey_room, Region.harvey_room, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.town_to_pierre_general_store, Region.pierre_store, + ConnectionData(Entrance.enter_harvey_room, RegionName.harvey_room, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.town_to_pierre_general_store, RegionName.pierre_store, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_sunroom, Region.sunroom, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.town_to_clint_blacksmith, Region.blacksmith, + ConnectionData(Entrance.enter_sunroom, RegionName.sunroom, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.town_to_clint_blacksmith, RegionName.blacksmith, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_saloon, Region.saloon, + ConnectionData(Entrance.town_to_saloon, RegionName.saloon, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.play_journey_of_the_prairie_king, Region.jotpk_world_1), - ConnectionData(Entrance.reach_jotpk_world_2, Region.jotpk_world_2), - ConnectionData(Entrance.reach_jotpk_world_3, Region.jotpk_world_3), - ConnectionData(Entrance.play_junimo_kart, Region.junimo_kart_1), - ConnectionData(Entrance.reach_junimo_kart_2, Region.junimo_kart_2), - ConnectionData(Entrance.reach_junimo_kart_3, Region.junimo_kart_3), - ConnectionData(Entrance.reach_junimo_kart_4, Region.junimo_kart_4), - ConnectionData(Entrance.town_to_sam_house, Region.sam_house, + ConnectionData(Entrance.play_journey_of_the_prairie_king, RegionName.jotpk_world_1), + ConnectionData(Entrance.reach_jotpk_world_2, RegionName.jotpk_world_2), + ConnectionData(Entrance.reach_jotpk_world_3, RegionName.jotpk_world_3), + ConnectionData(Entrance.play_junimo_kart, RegionName.junimo_kart_1), + ConnectionData(Entrance.reach_junimo_kart_2, RegionName.junimo_kart_2), + ConnectionData(Entrance.reach_junimo_kart_3, RegionName.junimo_kart_3), + ConnectionData(Entrance.reach_junimo_kart_4, RegionName.junimo_kart_4), + ConnectionData(Entrance.town_to_sam_house, RegionName.sam_house, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_haley_house, Region.haley_house, + ConnectionData(Entrance.town_to_haley_house, RegionName.haley_house, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_mayor_manor, Region.mayor_house, + ConnectionData(Entrance.town_to_mayor_manor, RegionName.mayor_house, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_alex_house, Region.alex_house, + ConnectionData(Entrance.town_to_alex_house, RegionName.alex_house, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_trailer, Region.trailer, + ConnectionData(Entrance.town_to_trailer, RegionName.trailer, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_museum, Region.museum, + ConnectionData(Entrance.town_to_museum, RegionName.museum, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_jojamart, Region.jojamart, + ConnectionData(Entrance.town_to_jojamart, RegionName.jojamart, flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.purchase_movie_ticket, Region.movie_ticket_stand), - ConnectionData(Entrance.enter_abandoned_jojamart, Region.abandoned_jojamart), - ConnectionData(Entrance.enter_movie_theater, Region.movie_theater), - ConnectionData(Entrance.town_to_beach, Region.beach), - ConnectionData(Entrance.enter_elliott_house, Region.elliott_house, + ConnectionData(Entrance.purchase_movie_ticket, RegionName.movie_ticket_stand), + ConnectionData(Entrance.enter_abandoned_jojamart, RegionName.abandoned_jojamart), + ConnectionData(Entrance.enter_movie_theater, RegionName.movie_theater), + ConnectionData(Entrance.town_to_beach, RegionName.beach), + ConnectionData(Entrance.enter_elliott_house, RegionName.elliott_house, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.beach_to_willy_fish_shop, Region.fish_shop, + ConnectionData(Entrance.beach_to_willy_fish_shop, RegionName.fish_shop, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.fish_shop_to_boat_tunnel, Region.boat_tunnel, + ConnectionData(Entrance.fish_shop_to_boat_tunnel, RegionName.boat_tunnel, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.boat_to_ginger_island, Region.island_south, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.enter_tide_pools, Region.tide_pools), - ConnectionData(Entrance.mountain_to_the_mines, Region.mines, + ConnectionData(Entrance.boat_to_ginger_island, RegionName.island_south, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.enter_tide_pools, RegionName.tide_pools), + ConnectionData(Entrance.mountain_to_the_mines, RegionName.mines, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.dig_to_mines_floor_5, Region.mines_floor_5), - ConnectionData(Entrance.dig_to_mines_floor_10, Region.mines_floor_10), - ConnectionData(Entrance.dig_to_mines_floor_15, Region.mines_floor_15), - ConnectionData(Entrance.dig_to_mines_floor_20, Region.mines_floor_20), - ConnectionData(Entrance.dig_to_mines_floor_25, Region.mines_floor_25), - ConnectionData(Entrance.dig_to_mines_floor_30, Region.mines_floor_30), - ConnectionData(Entrance.dig_to_mines_floor_35, Region.mines_floor_35), - ConnectionData(Entrance.dig_to_mines_floor_40, Region.mines_floor_40), - ConnectionData(Entrance.dig_to_mines_floor_45, Region.mines_floor_45), - ConnectionData(Entrance.dig_to_mines_floor_50, Region.mines_floor_50), - ConnectionData(Entrance.dig_to_mines_floor_55, Region.mines_floor_55), - ConnectionData(Entrance.dig_to_mines_floor_60, Region.mines_floor_60), - ConnectionData(Entrance.dig_to_mines_floor_65, Region.mines_floor_65), - ConnectionData(Entrance.dig_to_mines_floor_70, Region.mines_floor_70), - ConnectionData(Entrance.dig_to_mines_floor_75, Region.mines_floor_75), - ConnectionData(Entrance.dig_to_mines_floor_80, Region.mines_floor_80), - ConnectionData(Entrance.dig_to_mines_floor_85, Region.mines_floor_85), - ConnectionData(Entrance.dig_to_mines_floor_90, Region.mines_floor_90), - ConnectionData(Entrance.dig_to_mines_floor_95, Region.mines_floor_95), - ConnectionData(Entrance.dig_to_mines_floor_100, Region.mines_floor_100), - ConnectionData(Entrance.dig_to_mines_floor_105, Region.mines_floor_105), - ConnectionData(Entrance.dig_to_mines_floor_110, Region.mines_floor_110), - ConnectionData(Entrance.dig_to_mines_floor_115, Region.mines_floor_115), - ConnectionData(Entrance.dig_to_mines_floor_120, Region.mines_floor_120), - ConnectionData(Entrance.dig_to_dangerous_mines_20, Region.dangerous_mines_20, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.dig_to_dangerous_mines_60, Region.dangerous_mines_60, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.dig_to_dangerous_mines_100, Region.dangerous_mines_100, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.enter_skull_cavern_entrance, Region.skull_cavern_entrance, + ConnectionData(Entrance.dig_to_mines_floor_5, RegionName.mines_floor_5), + ConnectionData(Entrance.dig_to_mines_floor_10, RegionName.mines_floor_10), + ConnectionData(Entrance.dig_to_mines_floor_15, RegionName.mines_floor_15), + ConnectionData(Entrance.dig_to_mines_floor_20, RegionName.mines_floor_20), + ConnectionData(Entrance.dig_to_mines_floor_25, RegionName.mines_floor_25), + ConnectionData(Entrance.dig_to_mines_floor_30, RegionName.mines_floor_30), + ConnectionData(Entrance.dig_to_mines_floor_35, RegionName.mines_floor_35), + ConnectionData(Entrance.dig_to_mines_floor_40, RegionName.mines_floor_40), + ConnectionData(Entrance.dig_to_mines_floor_45, RegionName.mines_floor_45), + ConnectionData(Entrance.dig_to_mines_floor_50, RegionName.mines_floor_50), + ConnectionData(Entrance.dig_to_mines_floor_55, RegionName.mines_floor_55), + ConnectionData(Entrance.dig_to_mines_floor_60, RegionName.mines_floor_60), + ConnectionData(Entrance.dig_to_mines_floor_65, RegionName.mines_floor_65), + ConnectionData(Entrance.dig_to_mines_floor_70, RegionName.mines_floor_70), + ConnectionData(Entrance.dig_to_mines_floor_75, RegionName.mines_floor_75), + ConnectionData(Entrance.dig_to_mines_floor_80, RegionName.mines_floor_80), + ConnectionData(Entrance.dig_to_mines_floor_85, RegionName.mines_floor_85), + ConnectionData(Entrance.dig_to_mines_floor_90, RegionName.mines_floor_90), + ConnectionData(Entrance.dig_to_mines_floor_95, RegionName.mines_floor_95), + ConnectionData(Entrance.dig_to_mines_floor_100, RegionName.mines_floor_100), + ConnectionData(Entrance.dig_to_mines_floor_105, RegionName.mines_floor_105), + ConnectionData(Entrance.dig_to_mines_floor_110, RegionName.mines_floor_110), + ConnectionData(Entrance.dig_to_mines_floor_115, RegionName.mines_floor_115), + ConnectionData(Entrance.dig_to_mines_floor_120, RegionName.mines_floor_120), + ConnectionData(Entrance.dig_to_dangerous_mines_20, RegionName.dangerous_mines_20, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.dig_to_dangerous_mines_60, RegionName.dangerous_mines_60, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.dig_to_dangerous_mines_100, RegionName.dangerous_mines_100, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.enter_skull_cavern_entrance, RegionName.skull_cavern_entrance, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_oasis, Region.oasis, + ConnectionData(Entrance.enter_oasis, RegionName.oasis, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_casino, Region.casino, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_skull_cavern, Region.skull_cavern), - ConnectionData(Entrance.mine_to_skull_cavern_floor_25, Region.skull_cavern_25), - ConnectionData(Entrance.mine_to_skull_cavern_floor_50, Region.skull_cavern_50), - ConnectionData(Entrance.mine_to_skull_cavern_floor_75, Region.skull_cavern_75), - ConnectionData(Entrance.mine_to_skull_cavern_floor_100, Region.skull_cavern_100), - ConnectionData(Entrance.mine_to_skull_cavern_floor_125, Region.skull_cavern_125), - ConnectionData(Entrance.mine_to_skull_cavern_floor_150, Region.skull_cavern_150), - ConnectionData(Entrance.mine_to_skull_cavern_floor_175, Region.skull_cavern_175), - ConnectionData(Entrance.mine_to_skull_cavern_floor_200, Region.skull_cavern_200), - ConnectionData(Entrance.enter_dangerous_skull_cavern, Region.dangerous_skull_cavern, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.enter_witch_warp_cave, Region.witch_warp_cave, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_witch_swamp, Region.witch_swamp, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_witch_hut, Region.witch_hut, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.witch_warp_to_wizard_basement, Region.wizard_basement, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_bathhouse_entrance, Region.bathhouse_entrance, + ConnectionData(Entrance.enter_casino, RegionName.casino, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_skull_cavern, RegionName.skull_cavern), + ConnectionData(Entrance.mine_to_skull_cavern_floor_25, RegionName.skull_cavern_25), + ConnectionData(Entrance.mine_to_skull_cavern_floor_50, RegionName.skull_cavern_50), + ConnectionData(Entrance.mine_to_skull_cavern_floor_75, RegionName.skull_cavern_75), + ConnectionData(Entrance.mine_to_skull_cavern_floor_100, RegionName.skull_cavern_100), + ConnectionData(Entrance.mine_to_skull_cavern_floor_125, RegionName.skull_cavern_125), + ConnectionData(Entrance.mine_to_skull_cavern_floor_150, RegionName.skull_cavern_150), + ConnectionData(Entrance.mine_to_skull_cavern_floor_175, RegionName.skull_cavern_175), + ConnectionData(Entrance.mine_to_skull_cavern_floor_200, RegionName.skull_cavern_200), + ConnectionData(Entrance.enter_dangerous_skull_cavern, RegionName.dangerous_skull_cavern, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.enter_witch_warp_cave, RegionName.witch_warp_cave, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_witch_swamp, RegionName.witch_swamp, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_witch_hut, RegionName.witch_hut, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.witch_warp_to_wizard_basement, RegionName.wizard_basement, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_bathhouse_entrance, RegionName.bathhouse_entrance, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_locker_room, Region.locker_room, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_public_bath, Region.public_bath, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.island_south_to_west, Region.island_west, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_south_to_north, Region.island_north, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_south_to_east, Region.island_east, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_south_to_southeast, Region.island_south_east, + ConnectionData(Entrance.enter_locker_room, RegionName.locker_room, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_public_bath, RegionName.public_bath, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_south_to_west, RegionName.island_west, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.island_south_to_north, RegionName.island_north, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.island_south_to_east, RegionName.island_east, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.island_south_to_southeast, RegionName.island_south_east, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.use_island_resort, Region.island_resort, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_west_to_islandfarmhouse, Region.island_farmhouse, + ConnectionData(Entrance.use_island_resort, RegionName.island_resort, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.island_west_to_islandfarmhouse, RegionName.island_farmhouse, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_west_to_gourmand_cave, Region.gourmand_frog_cave, + ConnectionData(Entrance.island_west_to_gourmand_cave, RegionName.gourmand_frog_cave, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_west_to_crystals_cave, Region.colored_crystals_cave, + ConnectionData(Entrance.island_west_to_crystals_cave, RegionName.colored_crystals_cave, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_west_to_shipwreck, Region.shipwreck, + ConnectionData(Entrance.island_west_to_shipwreck, RegionName.shipwreck, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_west_to_qi_walnut_room, Region.qi_walnut_room, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_east_to_leo_hut, Region.leo_hut, + ConnectionData(Entrance.island_west_to_qi_walnut_room, RegionName.qi_walnut_room, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.island_east_to_leo_hut, RegionName.leo_hut, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_east_to_island_shrine, Region.island_shrine, + ConnectionData(Entrance.island_east_to_island_shrine, RegionName.island_shrine, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_southeast_to_pirate_cove, Region.pirate_cove, + ConnectionData(Entrance.island_southeast_to_pirate_cove, RegionName.pirate_cove, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_north_to_field_office, Region.field_office, + ConnectionData(Entrance.island_north_to_field_office, RegionName.field_office, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_north_to_dig_site, Region.dig_site, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.dig_site_to_professor_snail_cave, Region.professor_snail_cave, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_north_to_volcano, Region.volcano, + ConnectionData(Entrance.island_north_to_dig_site, RegionName.dig_site, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.dig_site_to_professor_snail_cave, RegionName.professor_snail_cave, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.volcano_to_secret_beach, Region.volcano_secret_beach, + ConnectionData(Entrance.island_north_to_volcano, RegionName.volcano, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.talk_to_island_trader, Region.island_trader, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.climb_to_volcano_5, Region.volcano_floor_5, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.talk_to_volcano_dwarf, Region.volcano_dwarf_shop, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.climb_to_volcano_10, Region.volcano_floor_10, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_jungle_to_docks, Region.island_south, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_dig_site_to_docks, Region.island_south, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_volcano_to_docks, Region.island_south, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_volcano_to_jungle, Region.island_west, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_docks_to_jungle, Region.island_west, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_dig_site_to_jungle, Region.island_west, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_docks_to_dig_site, Region.dig_site, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_volcano_to_dig_site, Region.dig_site, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_jungle_to_dig_site, Region.dig_site, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_dig_site_to_volcano, Region.island_north, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_docks_to_volcano, Region.island_north, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_jungle_to_volcano, Region.island_north, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.volcano_to_secret_beach, RegionName.volcano_secret_beach, + flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.talk_to_island_trader, RegionName.island_trader, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.climb_to_volcano_5, RegionName.volcano_floor_5, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.talk_to_volcano_dwarf, RegionName.volcano_dwarf_shop, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.climb_to_volcano_10, RegionName.volcano_floor_10, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_jungle_to_docks, RegionName.island_south, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_dig_site_to_docks, RegionName.island_south, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_volcano_to_docks, RegionName.island_south, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_volcano_to_jungle, RegionName.island_west, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_docks_to_jungle, RegionName.island_west, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_dig_site_to_jungle, RegionName.island_west, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_docks_to_dig_site, RegionName.dig_site, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_volcano_to_dig_site, RegionName.dig_site, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_jungle_to_dig_site, RegionName.dig_site, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_dig_site_to_volcano, RegionName.island_north, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_docks_to_volcano, RegionName.island_north, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(Entrance.parrot_express_jungle_to_volcano, RegionName.island_north, flag=RandomizationFlag.GINGER_ISLAND), ConnectionData(LogicEntrance.talk_to_mines_dwarf, LogicRegion.mines_dwarf_shop), @@ -708,7 +709,7 @@ def swap_connections_until_valid(regions_by_name, connections_by_name: Dict[str, def region_should_be_reachable(region_name: str, connections_in_slot: Iterable[ConnectionData]) -> bool: - if region_name == Region.menu: + if region_name == RegionName.menu: return True for connection in connections_in_slot: if region_name == connection.destination: @@ -718,11 +719,11 @@ def region_should_be_reachable(region_name: str, connections_in_slot: Iterable[C def find_reachable_regions(regions_by_name, connections_by_name, randomized_connections: Dict[ConnectionData, ConnectionData]): - reachable_regions = {Region.menu} + reachable_regions = {RegionName.menu} unreachable_regions = {region for region in regions_by_name.keys()} # unreachable_regions = {region for region in regions_by_name.keys() if region_should_be_reachable(region, connections_by_name.values())} - unreachable_regions.remove(Region.menu) - exits_to_explore = list(regions_by_name[Region.menu].exits) + unreachable_regions.remove(RegionName.menu) + exits_to_explore = list(regions_by_name[RegionName.menu].exits) while exits_to_explore: exit_name = exits_to_explore.pop() # if exit_name not in connections_by_name: diff --git a/worlds/stardew_valley/scripts/update_data.py b/worlds/stardew_valley/scripts/update_data.py index ae8f7f8d5503..5c2e6a57a4db 100644 --- a/worlds/stardew_valley/scripts/update_data.py +++ b/worlds/stardew_valley/scripts/update_data.py @@ -12,7 +12,7 @@ from worlds.stardew_valley import LocationData from worlds.stardew_valley.items import load_item_csv, Group, ItemData -from worlds.stardew_valley.locations import load_location_csv, LocationTags +from worlds.stardew_valley.locations import load_location_csv RESOURCE_PACK_CODE_OFFSET = 5000 script_folder = Path(__file__) @@ -56,9 +56,9 @@ def write_location_csv(locations: List[LocationData]): and item.code_without_offset is not None) + 1) resource_pack_counter = itertools.count(max(item.code_without_offset - for item in loaded_items - if Group.RESOURCE_PACK in item.groups - and item.code_without_offset is not None) + 1) + for item in loaded_items + if Group.RESOURCE_PACK in item.groups + and item.code_without_offset is not None) + 1) items_to_write = [] for item in loaded_items: if item.code_without_offset is None: diff --git a/worlds/stardew_valley/stardew_rule/base.py b/worlds/stardew_valley/stardew_rule/base.py index af4c3c35330d..ff1fbba37648 100644 --- a/worlds/stardew_valley/stardew_rule/base.py +++ b/worlds/stardew_valley/stardew_rule/base.py @@ -6,7 +6,7 @@ from functools import cached_property from itertools import chain from threading import Lock -from typing import Iterable, Dict, List, Union, Sized, Hashable, Callable, Tuple, Set, Optional +from typing import Iterable, Dict, List, Union, Sized, Hashable, Callable, Tuple, Set, Optional, cast from BaseClasses import CollectionState from .literal import true_, false_, LiteralStardewRule @@ -318,6 +318,7 @@ def __or__(self, other): return Or(_combinable_rules=other.add_into(self.combinable_rules, self.combine), _simplification_state=self.simplification_state) if type(other) is Or: + other = cast(Or, other) return Or(_combinable_rules=self.merge(self.combinable_rules, other.combinable_rules), _simplification_state=self.simplification_state.merge(other.simplification_state)) @@ -344,6 +345,7 @@ def __and__(self, other): return And(_combinable_rules=other.add_into(self.combinable_rules, self.combine), _simplification_state=self.simplification_state) if type(other) is And: + other = cast(And, other) return And(_combinable_rules=self.merge(self.combinable_rules, other.combinable_rules), _simplification_state=self.simplification_state.merge(other.simplification_state)) diff --git a/worlds/stardew_valley/test/TestMultiplePlayers.py b/worlds/stardew_valley/test/TestMultiplePlayers.py index 2f2092fdf7b6..d8db616f66f4 100644 --- a/worlds/stardew_valley/test/TestMultiplePlayers.py +++ b/worlds/stardew_valley/test/TestMultiplePlayers.py @@ -53,8 +53,6 @@ def test_different_money_settings(self): def test_money_rule_caching(self): options_festivals_limited_money = {FestivalLocations.internal_name: FestivalLocations.option_easy, StartingMoney.internal_name: 5000} - options_festivals_limited_money = {FestivalLocations.internal_name: FestivalLocations.option_easy, - StartingMoney.internal_name: 5000} multiplayer_options = [options_festivals_limited_money, options_festivals_limited_money] multiworld = setup_multiworld(multiplayer_options) diff --git a/worlds/stardew_valley/test/TestWalnutsanity.py b/worlds/stardew_valley/test/TestWalnutsanity.py index c1e8c2c8f095..da17d749eaed 100644 --- a/worlds/stardew_valley/test/TestWalnutsanity.py +++ b/worlds/stardew_valley/test/TestWalnutsanity.py @@ -25,7 +25,7 @@ def test_logic_received_walnuts(self): self.collect("Island Obelisk") self.collect("Island West Turtle") self.collect("Progressive House") - items = self.collect("5 Golden Walnuts", 10) + self.collect("5 Golden Walnuts", 10) self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) self.collect("Island North Turtle") @@ -126,10 +126,10 @@ def test_logic_received_walnuts(self): # You need to receive 25, and collect 15 self.collect("Island Obelisk") self.collect("Island West Turtle") - items = self.collect("5 Golden Walnuts", 5) + self.collect("5 Golden Walnuts", 5) self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) - items = self.collect("Island North Turtle") + self.collect("Island North Turtle") self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) @@ -203,7 +203,7 @@ def test_logic_received_walnuts(self): self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) self.remove(items) self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) - items = self.collect("5 Golden Walnuts", 4) - items = self.collect("3 Golden Walnuts", 6) - items = self.collect("Golden Walnut", 2) + self.collect("5 Golden Walnuts", 4) + self.collect("3 Golden Walnuts", 6) + self.collect("Golden Walnut", 2) self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) diff --git a/worlds/stardew_valley/test/rules/TestFishing.py b/worlds/stardew_valley/test/rules/TestFishing.py index 04a1528dd8b1..513bb951e933 100644 --- a/worlds/stardew_valley/test/rules/TestFishing.py +++ b/worlds/stardew_valley/test/rules/TestFishing.py @@ -1,5 +1,4 @@ -from ...options import SeasonRandomization, Friendsanity, FriendsanityHeartSize, Fishsanity, ExcludeGingerIsland, SkillProgression, ToolProgression, \ - ElevatorProgression, SpecialOrderLocations +from ...options import SeasonRandomization, Fishsanity, ExcludeGingerIsland, SkillProgression, ToolProgression, ElevatorProgression, SpecialOrderLocations from ...strings.fish_names import Fish from ...test import SVTestBase From 894732be474a63f84783de6cfad2260a047e8ad8 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 2 Feb 2025 02:53:16 +0100 Subject: [PATCH 0123/1218] kvui: set home folder to non-default (#4590) Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- kvui.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kvui.py b/kvui.py index f47e45b93c07..6718e48bee33 100644 --- a/kvui.py +++ b/kvui.py @@ -26,6 +26,10 @@ if Utils.is_frozen(): os.environ["KIVY_DATA_DIR"] = Utils.local_path("data") +import platformdirs +os.environ["KIVY_HOME"] = os.path.join(platformdirs.user_config_dir("Archipelago", False), "kivy") +os.makedirs(os.environ["KIVY_HOME"], exist_ok=True) + from kivy.config import Config Config.set("input", "mouse", "mouse,disable_multitouch") From f28aff6f9a86b6adff6f67253d17ee12a5c49c92 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Sun, 2 Feb 2025 14:25:34 +0000 Subject: [PATCH 0124/1218] Core: Replace generator creation/iteration in CollectionState methods (#4587) * Core: Replace generator creation/iteration in CollectionState methods Using generators in these functions incurs overhead to create the new generator instance, call the `any`/`all`/`sum` function and have the `any`/`all`/`sum` function iterate the generator, which in turn iterates the iterable. Replacing the use of generators with for loops is faster. Getting `self.prog_items[player]` once in advance also improves performance of iterating longer iterables. * Add comment on the choice of for loops instead of any()/all()/sum() --- BaseClasses.py | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index e19ba5f7772e..3d0004806cc5 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -869,21 +869,40 @@ def sweep_for_advancements(self, locations: Optional[Iterable[Location]] = None) def has(self, item: str, player: int, count: int = 1) -> bool: return self.prog_items[player][item] >= count + # for loops are specifically used in all/any/count methods, instead of all()/any()/sum(), to avoid the overhead of + # creating and iterating generator instances. In `return all(player_prog_items[item] for item in items)`, the + # argument to all() would be a new generator instance, for example. def has_all(self, items: Iterable[str], player: int) -> bool: """Returns True if each item name of items is in state at least once.""" - return all(self.prog_items[player][item] for item in items) + player_prog_items = self.prog_items[player] + for item in items: + if not player_prog_items[item]: + return False + return True def has_any(self, items: Iterable[str], player: int) -> bool: """Returns True if at least one item name of items is in state at least once.""" - return any(self.prog_items[player][item] for item in items) + player_prog_items = self.prog_items[player] + for item in items: + if player_prog_items[item]: + return True + return False def has_all_counts(self, item_counts: Mapping[str, int], player: int) -> bool: """Returns True if each item name is in the state at least as many times as specified.""" - return all(self.prog_items[player][item] >= count for item, count in item_counts.items()) + player_prog_items = self.prog_items[player] + for item, count in item_counts.items(): + if player_prog_items[item] < count: + return False + return True def has_any_count(self, item_counts: Mapping[str, int], player: int) -> bool: """Returns True if at least one item name is in the state at least as many times as specified.""" - return any(self.prog_items[player][item] >= count for item, count in item_counts.items()) + player_prog_items = self.prog_items[player] + for item, count in item_counts.items(): + if player_prog_items[item] >= count: + return True + return False def count(self, item: str, player: int) -> int: return self.prog_items[player][item] @@ -911,11 +930,20 @@ def has_from_list_unique(self, items: Iterable[str], player: int, count: int) -> def count_from_list(self, items: Iterable[str], player: int) -> int: """Returns the cumulative count of items from a list present in state.""" - return sum(self.prog_items[player][item_name] for item_name in items) + player_prog_items = self.prog_items[player] + total = 0 + for item_name in items: + total += player_prog_items[item_name] + return total def count_from_list_unique(self, items: Iterable[str], player: int) -> int: """Returns the cumulative count of items from a list present in state. Ignores duplicates of the same item.""" - return sum(self.prog_items[player][item_name] > 0 for item_name in items) + player_prog_items = self.prog_items[player] + total = 0 + for item_name in items: + if player_prog_items[item_name] > 0: + total += 1 + return total # item name group related def has_group(self, item_name_group: str, player: int, count: int = 1) -> bool: From 628252896e41d5d3e10414149a7bf50eed1307e3 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 3 Feb 2025 09:53:56 -0500 Subject: [PATCH 0125/1218] TUNIC: Call Combat Logic experimental (#4594) * Update options.py * Update options.py --- worlds/tunic/options.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index d2ea82803704..8fe2ea5ce854 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -197,6 +197,7 @@ class TunicPlandoConnections(PlandoConnections): class CombatLogic(Choice): """ + EXPERIMENTAL - may cause gen failures, especially when playthrough generation for the spoiler log is enabled, and may have slight logic issues. If enabled, the player will logically require a combination of stat upgrade items and equipment to get some checks or navigate to some areas, with a goal of matching the vanilla combat difficulty. The player may still be expected to run past enemies, reset aggro (by using a checkpoint or doing a scene transition), or find sneaky paths to checks. This option marks many more items as progression and may force weapons much earlier than normal. From 19faaa4104a97cac4a7980454ba55dae42758ea7 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Mon, 3 Feb 2025 19:49:07 -0500 Subject: [PATCH 0126/1218] Core: Fix #4595 by using first type's docstring in a union type (#4600) * Fix #4595: use first type's docstring in a union type. * Reuse existing import. --- settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/settings.py b/settings.py index cc808c2732df..14d4ba30cefb 100644 --- a/settings.py +++ b/settings.py @@ -282,7 +282,8 @@ def dump(self, f: TextIO, level: int = 0) -> None: attr = cast(object, getattr(self, name)) attr_cls = type_hints[name] if name in type_hints else attr.__class__ attr_cls_origin = typing.get_origin(attr_cls) - while attr_cls_origin is Union: # resolve to first type for doc string + # resolve to first type for doc string + while attr_cls_origin is Union or attr_cls_origin is types.UnionType: attr_cls = typing.get_args(attr_cls)[0] attr_cls_origin = typing.get_origin(attr_cls) if attr_cls.__doc__ and attr_cls.__module__ != "builtins": From da48af60dc443526cf28a16568e6cdb9d5732f09 Mon Sep 17 00:00:00 2001 From: Jouramie <16137441+Jouramie@users.noreply.github.com> Date: Tue, 4 Feb 2025 02:27:23 -0500 Subject: [PATCH 0127/1218] Stardew Valley: add assert_can_reach_region_* for better tests (#4556) * add assert_reach_region_*; refactor existing assert_reach_location_* to allow string * rename asserts --- worlds/stardew_valley/test/TestBooksanity.py | 8 ++-- .../stardew_valley/test/TestWalnutsanity.py | 4 +- .../test/assertion/rule_assert.py | 41 +++++++++++++++---- .../test/assertion/world_assert.py | 2 +- worlds/stardew_valley/test/rules/TestBooks.py | 8 ++-- .../stardew_valley/test/rules/TestFishing.py | 6 +-- .../stardew_valley/test/rules/TestSkills.py | 10 ++--- 7 files changed, 50 insertions(+), 29 deletions(-) diff --git a/worlds/stardew_valley/test/TestBooksanity.py b/worlds/stardew_valley/test/TestBooksanity.py index 942f35d961a9..3c737e502c64 100644 --- a/worlds/stardew_valley/test/TestBooksanity.py +++ b/worlds/stardew_valley/test/TestBooksanity.py @@ -65,7 +65,7 @@ def test_can_ship_all_books(self): if item_to_ship not in power_books and item_to_ship not in skill_books: continue with self.subTest(location.name): - self.assert_reach_location_true(location, self.multiworld.state) + self.assert_can_reach_location(location, self.multiworld.state) class TestBooksanityPowers(SVTestBase): @@ -111,7 +111,7 @@ def test_can_ship_all_books(self): if item_to_ship not in power_books and item_to_ship not in skill_books: continue with self.subTest(location.name): - self.assert_reach_location_true(location, self.multiworld.state) + self.assert_can_reach_location(location, self.multiworld.state) class TestBooksanityPowersAndSkills(SVTestBase): @@ -157,7 +157,7 @@ def test_can_ship_all_books(self): if item_to_ship not in power_books and item_to_ship not in skill_books: continue with self.subTest(location.name): - self.assert_reach_location_true(location, self.multiworld.state) + self.assert_can_reach_location(location, self.multiworld.state) class TestBooksanityAll(SVTestBase): @@ -203,4 +203,4 @@ def test_can_ship_all_books(self): if item_to_ship not in power_books and item_to_ship not in skill_books: continue with self.subTest(location.name): - self.assert_reach_location_true(location, self.multiworld.state) + self.assert_can_reach_location(location, self.multiworld.state) diff --git a/worlds/stardew_valley/test/TestWalnutsanity.py b/worlds/stardew_valley/test/TestWalnutsanity.py index da17d749eaed..862553dee1cb 100644 --- a/worlds/stardew_valley/test/TestWalnutsanity.py +++ b/worlds/stardew_valley/test/TestWalnutsanity.py @@ -81,10 +81,10 @@ def test_field_office_locations_require_professor_snail(self): self.collect("Combat Level", 10) self.collect("Mining Level", 10) for location in locations: - self.assert_reach_location_false(location, self.multiworld.state) + self.assert_cannot_reach_location(location, self.multiworld.state) self.collect("Open Professor Snail Cave") for location in locations: - self.assert_reach_location_true(location, self.multiworld.state) + self.assert_can_reach_location(location, self.multiworld.state) class TestWalnutsanityBushes(SVTestBase): diff --git a/worlds/stardew_valley/test/assertion/rule_assert.py b/worlds/stardew_valley/test/assertion/rule_assert.py index 1031a18e115c..02362f2d150d 100644 --- a/worlds/stardew_valley/test/assertion/rule_assert.py +++ b/worlds/stardew_valley/test/assertion/rule_assert.py @@ -1,7 +1,7 @@ from typing import List from unittest import TestCase -from BaseClasses import CollectionState, Location +from BaseClasses import CollectionState, Location, Region from ...stardew_rule import StardewRule, false_, MISSING_ITEM, Reach from ...stardew_rule.rule_explain import explain @@ -40,19 +40,42 @@ def assert_rule_can_be_resolved(self, rule: StardewRule, complete_state: Collect raise AssertionError(f"Error while checking rule {rule}: {e}" f"\nExplanation: {expl}") - def assert_reach_location_true(self, location: Location, state: CollectionState): - expl = explain(Reach(location.name, "Location", 1), state) + def assert_can_reach_location(self, location: Location | str, state: CollectionState) -> None: + location_name = location.name if isinstance(location, Location) else location + expl = explain(Reach(location_name, "Location", 1), state) try: - can_reach = location.can_reach(state) + can_reach = state.can_reach_location(location_name, 1) self.assertTrue(can_reach, expl) except KeyError as e: - raise AssertionError(f"Error while checking location {location.name}: {e}" + raise AssertionError(f"Error while checking location {location_name}: {e}" f"\nExplanation: {expl}") - def assert_reach_location_false(self, location: Location, state: CollectionState): - expl = explain(Reach(location.name, "Location", 1), state, expected=False) + def assert_cannot_reach_location(self, location: Location | str, state: CollectionState) -> None: + location_name = location.name if isinstance(location, Location) else location + expl = explain(Reach(location_name, "Location", 1), state, expected=False) try: - self.assertFalse(location.can_reach(state), expl) + can_reach = state.can_reach_location(location_name, 1) + self.assertFalse(can_reach, expl) except KeyError as e: - raise AssertionError(f"Error while checking location {location.name}: {e}" + raise AssertionError(f"Error while checking location {location_name}: {e}" + f"\nExplanation: {expl}") + + def assert_can_reach_region(self, region: Region | str, state: CollectionState) -> None: + region_name = region.name if isinstance(region, Region) else region + expl = explain(Reach(region_name, "Region", 1), state) + try: + can_reach = state.can_reach_region(region_name, 1) + self.assertTrue(can_reach, expl) + except KeyError as e: + raise AssertionError(f"Error while checking region {region_name}: {e}" + f"\nExplanation: {expl}") + + def assert_cannot_reach_region(self, region: Region | str, state: CollectionState) -> None: + region_name = region.name if isinstance(region, Region) else region + expl = explain(Reach(region_name, "Region", 1), state, expected=False) + try: + can_reach = state.can_reach_region(region_name, 1) + self.assertFalse(can_reach, expl) + except KeyError as e: + raise AssertionError(f"Error while checking region {region_name}: {e}" f"\nExplanation: {expl}") diff --git a/worlds/stardew_valley/test/assertion/world_assert.py b/worlds/stardew_valley/test/assertion/world_assert.py index 97172834543c..97f5376058cb 100644 --- a/worlds/stardew_valley/test/assertion/world_assert.py +++ b/worlds/stardew_valley/test/assertion/world_assert.py @@ -53,7 +53,7 @@ def assert_same_number_items_locations(self, multiworld: MultiWorld): def assert_can_reach_everything(self, multiworld: MultiWorld): for location in multiworld.get_locations(): - self.assert_reach_location_true(location, multiworld.state) + self.assert_can_reach_location(location, multiworld.state) def assert_basic_checks(self, multiworld: MultiWorld): self.assert_same_number_items_locations(multiworld) diff --git a/worlds/stardew_valley/test/rules/TestBooks.py b/worlds/stardew_valley/test/rules/TestBooks.py index 6605e7e645e3..af0055d2282d 100644 --- a/worlds/stardew_valley/test/rules/TestBooks.py +++ b/worlds/stardew_valley/test/rules/TestBooks.py @@ -12,15 +12,13 @@ def test_need_weapon_for_mapping_cave_systems(self): location = self.multiworld.get_location("Read Mapping Cave Systems", self.player) - self.assert_reach_location_false(location, self.multiworld.state) + self.assert_cannot_reach_location(location, self.multiworld.state) self.collect("Progressive Mine Elevator") self.collect("Progressive Mine Elevator") self.collect("Progressive Mine Elevator") self.collect("Progressive Mine Elevator") - self.assert_reach_location_false(location, self.multiworld.state) + self.assert_cannot_reach_location(location, self.multiworld.state) self.collect("Progressive Weapon") - self.assert_reach_location_true(location, self.multiworld.state) - - + self.assert_can_reach_location(location, self.multiworld.state) diff --git a/worlds/stardew_valley/test/rules/TestFishing.py b/worlds/stardew_valley/test/rules/TestFishing.py index 513bb951e933..74a33f36686f 100644 --- a/worlds/stardew_valley/test/rules/TestFishing.py +++ b/worlds/stardew_valley/test/rules/TestFishing.py @@ -43,18 +43,18 @@ def test_catch_fish_requires_region_unlock(self): self.collect_all_the_money() item_names = fish_and_items[fish] location = self.multiworld.get_location(f"Fishsanity: {fish}", self.player) - self.assert_reach_location_false(location, self.multiworld.state) + self.assert_cannot_reach_location(location, self.multiworld.state) items = [] for item_name in item_names: items.append(self.collect(item_name)) with self.subTest(f"{fish} can be reached with {item_names}"): - self.assert_reach_location_true(location, self.multiworld.state) + self.assert_can_reach_location(location, self.multiworld.state) for item_required in items: self.multiworld.state = self.original_state.copy() with self.subTest(f"{fish} requires {item_required.name}"): for item_to_collect in items: if item_to_collect.name != item_required.name: self.collect(item_to_collect) - self.assert_reach_location_false(location, self.multiworld.state) + self.assert_cannot_reach_location(location, self.multiworld.state) self.multiworld.state = self.original_state.copy() diff --git a/worlds/stardew_valley/test/rules/TestSkills.py b/worlds/stardew_valley/test/rules/TestSkills.py index 77adade886dc..ee605bfaa161 100644 --- a/worlds/stardew_valley/test/rules/TestSkills.py +++ b/worlds/stardew_valley/test/rules/TestSkills.py @@ -39,10 +39,10 @@ def test_all_skill_levels_require_previous_level(self): with self.subTest(location_name): if level > 1: - self.assert_reach_location_false(location, self.multiworld.state) + self.assert_cannot_reach_location(location, self.multiworld.state) self.collect(f"{skill} Level") - self.assert_reach_location_true(location, self.multiworld.state) + self.assert_can_reach_location(location, self.multiworld.state) self.reset_collection_state() @@ -88,7 +88,7 @@ def test_given_all_levels_when_can_earn_mastery_then_can_earn_mastery(self): for skill in all_vanilla_skills: with self.subTest(skill): location = self.multiworld.get_location(f"{skill} Mastery", self.player) - self.assert_reach_location_true(location, self.multiworld.state) + self.assert_can_reach_location(location, self.multiworld.state) self.reset_collection_state() @@ -99,7 +99,7 @@ def test_given_one_level_missing_when_can_earn_mastery_then_cannot_earn_mastery( self.remove_one_by_name(f"{skill} Level") location = self.multiworld.get_location(f"{skill} Mastery", self.player) - self.assert_reach_location_false(location, self.multiworld.state) + self.assert_cannot_reach_location(location, self.multiworld.state) self.reset_collection_state() @@ -108,6 +108,6 @@ def test_given_one_tool_missing_when_can_earn_mastery_then_cannot_earn_mastery(s self.remove_one_by_name(f"Progressive Pickaxe") location = self.multiworld.get_location("Mining Mastery", self.player) - self.assert_reach_location_false(location, self.multiworld.state) + self.assert_cannot_reach_location(location, self.multiworld.state) self.reset_collection_state() From db11c620a746b23c46216cae1e2f05a013aeb341 Mon Sep 17 00:00:00 2001 From: shananas <47014056+shananas@users.noreply.github.com> Date: Tue, 4 Feb 2025 11:09:02 -0500 Subject: [PATCH 0128/1218] =?UTF-8?q?KH2=20Doc=20Update=C2=A0#4609?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mod Manager Version Number --- worlds/kh2/docs/setup_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/kh2/docs/setup_en.md b/worlds/kh2/docs/setup_en.md index bee60bd36b18..2e1022f3efa7 100644 --- a/worlds/kh2/docs/setup_en.md +++ b/worlds/kh2/docs/setup_en.md @@ -10,7 +10,7 @@ Kingdom Hearts II Final Mix from the [Epic Games Store](https://store.epicgames.com/en-US/discover/kingdom-hearts) or [Steam](https://store.steampowered.com/app/2552430/KINGDOM_HEARTS_HD_1525_ReMIX/) - Follow this Guide to set up these requirements [KH2Rando.com](https://tommadness.github.io/KH2Randomizer/setup/Panacea-ModLoader/) - 1. Version 3.4.0 or greater OpenKH Mod Manager with Panacea + 1. Version 25.01.26.0 or greater OpenKH Mod Manager with Panacea 2. Lua Backend from the OpenKH Mod Manager 3. Install the mod `KH2FM-Mods-Num/GoA-ROM-Edition` using OpenKH Mod Manager - Needed for Archipelago From f6668997e61a0e2ea53bf2e6f92a070686659f8c Mon Sep 17 00:00:00 2001 From: Martmists Date: Fri, 7 Feb 2025 21:02:37 +0100 Subject: [PATCH 0129/1218] [AHIT] Fix small options issue (#4615) --- worlds/ahit/Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/ahit/Options.py b/worlds/ahit/Options.py index 17c4b95efc7a..b331ca524244 100644 --- a/worlds/ahit/Options.py +++ b/worlds/ahit/Options.py @@ -338,7 +338,7 @@ class MinExtraYarn(Range): There must be at least this much more yarn over the total number of yarn needed to craft all hats. For example, if this option's value is 10, and the total yarn needed to craft all hats is 40, there must be at least 50 yarn in the pool.""" - display_name = "Max Extra Yarn" + display_name = "Min Extra Yarn" range_start = 5 range_end = 15 default = 10 From 768ccffe722551f6225c70003906f2b787bffdd0 Mon Sep 17 00:00:00 2001 From: Kory Dondzila Date: Fri, 7 Feb 2025 15:06:06 -0500 Subject: [PATCH 0130/1218] Shivers: Update shivers links and guides (#4592) --- worlds/shivers/docs/en_Shivers.md | 4 +++- worlds/shivers/docs/setup_en.md | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/worlds/shivers/docs/en_Shivers.md b/worlds/shivers/docs/en_Shivers.md index 9490b577bdd0..f36cbcce36e1 100644 --- a/worlds/shivers/docs/en_Shivers.md +++ b/worlds/shivers/docs/en_Shivers.md @@ -9,6 +9,7 @@ configuration file. All Ixupi pot pieces are randomized. Keys have been added to the game to lock off different rooms in the museum, these are randomized. Crawling has been added and is required to use any crawl space. +Randomization can also control if Ixupi pots are in pieces, mixed, or complete, and in which worlds they will show up in. ## What is considered a location check in Shivers? @@ -27,4 +28,5 @@ Victory is achieved when the player has captured the required number Ixupi set i ## Encountered a bug? -Please contact GodlFire or Cynbel_Terreus on Discord for bugs related to Shivers world generation or the Shivers Randomizer. +Please contact GodlFire or Cynbel_Terreus on Discord for bugs related to Shivers world generation or the Shivers Randomizer. +You may also open issues for the Shivers Randomizer Client [here](https://github.com/Shivers-Randomizer/Shivers-Randomizer/issues). diff --git a/worlds/shivers/docs/setup_en.md b/worlds/shivers/docs/setup_en.md index a495c87b226a..5d73a81b2967 100644 --- a/worlds/shivers/docs/setup_en.md +++ b/worlds/shivers/docs/setup_en.md @@ -5,12 +5,12 @@ - [Shivers (GOG version)](https://www.gog.com/en/game/shivers) or original disc - [ScummVM](https://www.scummvm.org/downloads/) version 2.7.0 or later -- [Shivers Randomizer](https://github.com/GodlFire/Shivers-Randomizer-CSharp/releases/latest) Latest release version +- [Shivers Randomizer Client](https://github.com/Shivers-Randomizer/Shivers-Randomizer/releases/latest) Latest release version ## Optional Software - [PopTracker](https://github.com/black-sliver/PopTracker/releases/) - - [Jax's Shivers PopTracker pack](https://github.com/blazik-barth/Shivers-Tracker/releases/) + - [Shivers PopTracker pack](https://github.com/Shivers-Randomizer/Shivers-AP-Tracker/releases/latest) ## Setup ScummVM for Shivers @@ -59,7 +59,9 @@ validator page: [YAML Validation page](/mysterycheck) ## What is a check -- Every puzzle -- Every puzzle hint/solution -- Every document that is considered a Flashback +- All puzzles +- All puzzle hints or solutions +- All documents that are considered Flashbacks +- All Ixupi captures (Lightning only if early) - Optionally information plaques +- Optionally elevators From f75a1ae1174fb467e5c5bd5568d7de3c806d5b1c Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 8 Feb 2025 00:06:04 +0100 Subject: [PATCH 0131/1218] KH2: Fix lambda capture issue with weapon slot logic (#4604) * KH2: Fix lambda capture issue with weapon slot logic * Update Rules.py * Improved by JaredWeakStrike (#4605) * Apparently this wasn't meant to be indented --------- Co-authored-by: JaredWeakStrike <96694163+JaredWeakStrike@users.noreply.github.com> --- worlds/kh2/Rules.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/worlds/kh2/Rules.py b/worlds/kh2/Rules.py index 767c5643417e..a59fbfd8ab97 100644 --- a/worlds/kh2/Rules.py +++ b/worlds/kh2/Rules.py @@ -263,7 +263,10 @@ def set_kh2_rules(self) -> None: weapon_region = self.multiworld.get_region(RegionName.Keyblade, self.player) for location in weapon_region.locations: - add_rule(location, lambda state: state.has(exclusion_table["WeaponSlots"][location.name], self.player)) + if location.name in exclusion_table["WeaponSlots"]: # shop items and starting items are not in this list + exclusion_item = exclusion_table["WeaponSlots"][location.name] + add_rule(location, lambda state, e_item=exclusion_item: state.has(e_item, self.player)) + if location.name in Goofy_Checks: add_item_rule(location, lambda item: item.player == self.player and item.name in GoofyAbility_Table.keys()) elif location.name in Donald_Checks: From f5c574c37ac6283cb360432e6c5b5cc35b2d1780 Mon Sep 17 00:00:00 2001 From: qwint Date: Sun, 9 Feb 2025 06:11:27 -0500 Subject: [PATCH 0132/1218] Settings: add format handling to yaml exception marks for readability (#4531) --- settings.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/settings.py b/settings.py index 14d4ba30cefb..255c537fe09a 100644 --- a/settings.py +++ b/settings.py @@ -792,7 +792,17 @@ def __init__(self, location: Optional[str]): # change to PathLike[str] once we if location: from Utils import parse_yaml with open(location, encoding="utf-8-sig") as f: - options = parse_yaml(f.read()) + from yaml.error import MarkedYAMLError + try: + options = parse_yaml(f.read()) + except MarkedYAMLError as ex: + if ex.problem_mark: + f.seek(0) + lines = f.readlines() + problem_line = lines[ex.problem_mark.line] + error_line = " " * ex.problem_mark.column + "^" + raise Exception(f"{ex.context} {ex.problem}\n{problem_line}{error_line}") + raise ex # TODO: detect if upgrade is required # TODO: once we have a cache for _world_settings_name_cache, detect if any game section is missing self.update(options or {}) From 359f45d50f3872fe097b6e605faf494398c8ff8a Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sun, 9 Feb 2025 13:12:17 -0500 Subject: [PATCH 0133/1218] TUNIC: Combat logic fix (#4589) * Potential fix for attack issue * also put the lazy version of the swamp fix in for good measure * fix extra line * now it is good * Add the test, roll the other PR into this one * Make the test exception more useful * Remove debug print * Combat logic fixed? * Move a few areas to before well instead of east forest * Put in qwint's suggestions in test * Implement qwint's suggestions in combat_logic.py * Implement qwint's suggestions for combat_logic.py * Fix typo * Remove experimental from combat logic description * Remove copy_mixin again * Add comment about copy_mixin * Use a more proper random * Some optimizations from Vi's comments --- worlds/tunic/combat_logic.py | 308 +++++++++++++++++-------------- worlds/tunic/er_rules.py | 20 +- worlds/tunic/options.py | 1 - worlds/tunic/test/test_combat.py | 83 +++++++++ 4 files changed, 261 insertions(+), 151 deletions(-) create mode 100644 worlds/tunic/test/test_combat.py diff --git a/worlds/tunic/combat_logic.py b/worlds/tunic/combat_logic.py index 9ff363942c9e..2e490d1dad6e 100644 --- a/worlds/tunic/combat_logic.py +++ b/worlds/tunic/combat_logic.py @@ -8,6 +8,7 @@ # the vanilla stats you are expected to have to get through an area, based on where they are in vanilla class AreaStats(NamedTuple): + """Attack, Defense, Potion, HP, SP, MP, Flasks, Equipment, is_boss""" att_level: int def_level: int potion_level: int # all 3 are before your first bonfire after getting the upgrade page, third costs 1k @@ -41,7 +42,7 @@ class AreaStats(NamedTuple): "Rooted Ziggurat": AreaStats(5, 5, 3, 5, 3, 3, 6, ["Sword", "Shield", "Magic"]), "Boss Scavenger": AreaStats(5, 5, 3, 5, 3, 3, 6, ["Sword", "Shield", "Magic"], is_boss=True), "Swamp": AreaStats(1, 1, 1, 1, 1, 1, 6, ["Sword", "Shield", "Magic"]), - "Cathedral": AreaStats(1, 1, 1, 1, 1, 1, 6, ["Sword", "Shield", "Magic"]), + # Cathedral has the same requirements as Swamp # marked as boss because the garden knights can't get hurt by stick "Gauntlet": AreaStats(1, 1, 1, 1, 1, 1, 6, ["Sword", "Shield", "Magic"], is_boss=True), "The Heir": AreaStats(5, 5, 3, 5, 3, 3, 6, ["Sword", "Shield", "Magic", "Laurels"], is_boss=True), @@ -49,8 +50,10 @@ class AreaStats(NamedTuple): # these are used for caching which areas can currently be reached in state +# Gauntlet does not have exclusively higher stat requirements, so it will be checked separately boss_areas: List[str] = [name for name, data in area_data.items() if data.is_boss and name != "Gauntlet"] -non_boss_areas: List[str] = [name for name, data in area_data.items() if not data.is_boss] +# Swamp does not have exclusively higher stat requirements, so it will be checked separately +non_boss_areas: List[str] = [name for name, data in area_data.items() if not data.is_boss and name != "Swamp"] class CombatState(IntEnum): @@ -89,6 +92,7 @@ def has_combat_reqs(area_name: str, state: CollectionState, player: int) -> bool elif area_name in non_boss_areas: area_list = non_boss_areas else: + # this is to check Swamp and Gauntlet on their own area_list = [area_name] if met_combat_reqs: @@ -114,88 +118,99 @@ def check_combat_reqs(area_name: str, state: CollectionState, player: int, alt_d extra_att_needed = 0 extra_def_needed = 0 extra_mp_needed = 0 - has_magic = state.has_any({"Magic Wand", "Gun"}, player) - stick_bool = False - sword_bool = False + has_magic = state.has_any(("Magic Wand", "Gun"), player) + sword_bool = has_sword(state, player) + stick_bool = sword_bool or has_melee(state, player) + equipment = data.equipment.copy() for item in data.equipment: if item == "Stick": - if not has_melee(state, player): + if not stick_bool: if has_magic: + equipment.remove("Stick") + if "Magic" not in equipment: + equipment.append("Magic") # magic can make up for the lack of stick extra_mp_needed += 2 - extra_att_needed -= 16 + extra_att_needed -= 32 else: return False - else: - stick_bool = True elif item == "Sword": - if not has_sword(state, player): + if not sword_bool: # need sword for bosses if data.is_boss: return False + equipment.remove("Sword") if has_magic: + if "Magic" not in equipment: + equipment.append("Magic") # +4 mp pretty much makes up for the lack of sword, at least in Quarry extra_mp_needed += 4 - # stick is a backup plan, and doesn't scale well, so let's require a little less - extra_att_needed -= 2 - elif has_melee(state, player): + if stick_bool: + # stick is a backup plan, and doesn't scale well, so let's require a little less + equipment.append("Stick") + extra_att_needed -= 2 + else: + extra_mp_needed += 2 + extra_att_needed -= 32 + elif stick_bool: + equipment.append("Stick") # may revise this later based on feedback extra_att_needed += 3 extra_def_needed += 2 else: return False - else: - sword_bool = True + # just increase the stat requirement, we'll check for shield when calculating defense elif item == "Shield": - if not state.has("Shield", player): - extra_def_needed += 2 + equipment.remove("Shield") + extra_def_needed += 2 + elif item == "Laurels": if not state.has("Hero's Laurels", player): - # these are entirely based on vibes - extra_att_needed += 2 - extra_def_needed += 3 + # require Laurels for the Heir + return False + elif item == "Magic": if not has_magic: + equipment.remove("Magic") extra_att_needed += 2 extra_def_needed += 2 - extra_mp_needed -= 16 + extra_mp_needed -= 32 + modified_stats = AreaStats(data.att_level + extra_att_needed, data.def_level + extra_def_needed, data.potion_level, - data.hp_level, data.sp_level, data.mp_level + extra_mp_needed, data.potion_count) - if not has_required_stats(modified_stats, state, player): + data.hp_level, data.sp_level, data.mp_level + extra_mp_needed, data.potion_count, + equipment, data.is_boss) + if has_required_stats(modified_stats, state, player): + return True + else: # we may need to check if you would have the required stats if you were missing a weapon - # it's kinda janky, but these only get hit in less than once per 100 generations, so whatever - if sword_bool and "Sword" in data.equipment and "Magic" in data.equipment: - # we need to check if you would have the required stats if you didn't have melee - equip_list = [item for item in data.equipment if item != "Sword"] - more_modified_stats = AreaStats(data.att_level - 16, data.def_level, data.potion_level, - data.hp_level, data.sp_level, data.mp_level + 4, data.potion_count, - equip_list) + if sword_bool and "Sword" in equipment and has_magic: + # we need to check if you would have the required stats if you didn't have the sword + equip_list = [item for item in equipment if item != "Sword"] + if "Magic" not in equip_list: + equip_list.append("Magic") + more_modified_stats = AreaStats(modified_stats.att_level - 32, modified_stats.def_level, + modified_stats.potion_level, modified_stats.hp_level, + modified_stats.sp_level, modified_stats.mp_level + 4, + modified_stats.potion_count, equip_list, data.is_boss) if check_combat_reqs("none", state, player, more_modified_stats): return True - # and we need to check if you would have the required stats if you didn't have magic - equip_list = [item for item in data.equipment if item != "Magic"] - more_modified_stats = AreaStats(data.att_level + 2, data.def_level + 2, data.potion_level, - data.hp_level, data.sp_level, data.mp_level - 16, data.potion_count, - equip_list) - if check_combat_reqs("none", state, player, more_modified_stats): - return True - return False - - elif stick_bool and "Stick" in data.equipment and "Magic" in data.equipment: + elif stick_bool and "Stick" in equipment and has_magic: # we need to check if you would have the required stats if you didn't have the stick - equip_list = [item for item in data.equipment if item != "Stick"] - more_modified_stats = AreaStats(data.att_level - 16, data.def_level, data.potion_level, - data.hp_level, data.sp_level, data.mp_level + 4, data.potion_count, - equip_list) + equip_list = [item for item in equipment if item != "Stick"] + if "Magic" not in equip_list: + equip_list.append("Magic") + more_modified_stats = AreaStats(modified_stats.att_level - 32, modified_stats.def_level, + modified_stats.potion_level, modified_stats.hp_level, + modified_stats.sp_level, modified_stats.mp_level + 4, + modified_stats.potion_count, equip_list, data.is_boss) if check_combat_reqs("none", state, player, more_modified_stats): return True - return False else: return False - return True + return False # check if you have the required stats, and the money to afford them @@ -203,72 +218,63 @@ def check_combat_reqs(area_name: str, state: CollectionState, player: int, alt_d # but that's fine -- it's already pretty generous to begin with def has_required_stats(data: AreaStats, state: CollectionState, player: int) -> bool: money_required = 0 - player_att = 0 + att_required = data.att_level + player_att, att_offerings = get_att_level(state, player) - # check if we actually need the stat before checking state - if data.att_level > 1: - player_att, att_offerings = get_att_level(state, player) - if player_att < data.att_level: - return False + # if you have 2 more attack than needed, we can forego needing mp + if data.mp_level > 1: + if player_att < data.att_level + 2: + player_mp, mp_offerings = get_mp_level(state, player) + if player_mp < data.mp_level: + return False + else: + extra_mp = player_mp - data.mp_level + paid_mp = max(0, mp_offerings - extra_mp) + # mp costs 300 for the first, +50 for each additional + money_per_mp = 300 + for _ in range(paid_mp): + money_required += money_per_mp + money_per_mp += 50 else: - extra_att = player_att - data.att_level - paid_att = max(0, att_offerings - extra_att) - # attack upgrades cost 100 for the first, +50 for each additional - money_per_att = 100 - for _ in range(paid_att): - money_required += money_per_att - money_per_att += 50 + att_required += 2 + + if player_att < att_required: + return False + else: + extra_att = player_att - att_required + paid_att = max(0, att_offerings - extra_att) + # attack upgrades cost 100 for the first, +50 for each additional + money_per_att = 100 + for _ in range(paid_att): + money_required += money_per_att + money_per_att += 50 # adding defense and sp together since they accomplish similar things: making you take less damage if data.def_level + data.sp_level > 2: player_def, def_offerings = get_def_level(state, player) player_sp, sp_offerings = get_sp_level(state, player) - if player_def + player_sp < data.def_level + data.sp_level: + req_stats = data.def_level + data.sp_level + if player_def + player_sp < req_stats: return False else: free_def = player_def - def_offerings free_sp = player_sp - sp_offerings - paid_stats = data.def_level + data.sp_level - free_def - free_sp - sp_to_buy = 0 - - if paid_stats <= 0: - # if you don't have to pay for any stats, you don't need money for these upgrades - def_to_buy = 0 - elif paid_stats <= def_offerings: - # get the amount needed to buy these def offerings - def_to_buy = paid_stats + if free_sp + free_def >= req_stats: + # you don't need to buy upgrades + pass else: - def_to_buy = def_offerings - sp_to_buy = max(0, paid_stats - def_offerings) - - # if you have to buy more than 3 def, it's cheaper to buy 1 extra sp - if def_to_buy > 3 and sp_offerings > 0: - def_to_buy -= 1 - sp_to_buy += 1 - # def costs 100 for the first, +50 for each additional - money_per_def = 100 - for _ in range(def_to_buy): - money_required += money_per_def - money_per_def += 50 - # sp costs 200 for the first, +200 for each additional - money_per_sp = 200 - for _ in range(sp_to_buy): - money_required += money_per_sp - money_per_sp += 200 - - # if you have 2 more attack than needed, we can forego needing mp - if data.mp_level > 1 and player_att < data.att_level + 2: - player_mp, mp_offerings = get_mp_level(state, player) - if player_mp < data.mp_level: - return False - else: - extra_mp = player_mp - data.mp_level - paid_mp = max(0, mp_offerings - extra_mp) - # mp costs 300 for the first, +50 for each additional - money_per_mp = 300 - for _ in range(paid_mp): - money_required += money_per_mp - money_per_mp += 50 + # we need to pick the cheapest option that gets us above the stats we need + # first number is def, second number is sp + upgrade_options: set[tuple[int, int]] = set() + stats_to_buy = req_stats - free_def - free_sp + for paid_def in range(0, min(def_offerings + 1, stats_to_buy + 1)): + sp_required = stats_to_buy - paid_def + if sp_offerings >= sp_required: + if sp_required < 0: + break + upgrade_options.add((paid_def, stats_to_buy - paid_def)) + costs = [calc_def_sp_cost(defense, sp) for defense, sp in upgrade_options] + money_required += min(costs) req_effective_hp = calc_effective_hp(data.hp_level, data.potion_level, data.potion_count) player_potion, potion_offerings = get_potion_level(state, player) @@ -279,53 +285,30 @@ def has_required_stats(data: AreaStats, state: CollectionState, player: int) -> return False else: # need a way to determine which of potion offerings or hp offerings you can reduce - # your level if you didn't pay for offerings free_potion = player_potion - potion_offerings free_hp = player_hp - hp_offerings - paid_hp_count = 0 - paid_potion_count = 0 if calc_effective_hp(free_hp, free_potion, player_potion_count) >= req_effective_hp: # you don't need to buy upgrades pass - # if you have no potions, or no potion upgrades, you only need to check your hp upgrades - elif player_potion_count == 0 or potion_offerings == 0: - # check if you have enough hp at each paid hp offering - for i in range(hp_offerings): - paid_hp_count = i + 1 - if calc_effective_hp(paid_hp_count, 0, player_potion_count) > req_effective_hp: - break else: - for i in range(potion_offerings): - paid_potion_count = i + 1 - if calc_effective_hp(free_hp, free_potion + paid_potion_count, player_potion_count) > req_effective_hp: - break - for j in range(hp_offerings): - paid_hp_count = j + 1 - if (calc_effective_hp(free_hp + paid_hp_count, free_potion + paid_potion_count, player_potion_count) - > req_effective_hp): + # we need to pick the cheapest option that gets us above the amount of effective HP we need + # first number is hp, second number is potion + upgrade_options: set[tuple[int, int]] = set() + # filter out exclusively worse options + lowest_hp_added = hp_offerings + 1 + for paid_potion in range(0, potion_offerings + 1): + # check quantities of hp offerings for each potion offering + for paid_hp in range(0, lowest_hp_added): + if (calc_effective_hp(free_hp + paid_hp, free_potion + paid_potion, player_potion_count) + >= req_effective_hp): + upgrade_options.add((paid_hp, paid_potion)) + lowest_hp_added = paid_hp break - # hp costs 200 for the first, +50 for each additional - money_per_hp = 200 - for _ in range(paid_hp_count): - money_required += money_per_hp - money_per_hp += 50 - - # potion costs 100 for the first, 300 for the second, 1,000 for the third, and +200 for each additional - # currently we assume you will not buy past the second potion upgrade, but we might change our minds later - money_per_potion = 100 - for _ in range(paid_potion_count): - money_required += money_per_potion - if money_per_potion == 100: - money_per_potion = 300 - elif money_per_potion == 300: - money_per_potion = 1000 - else: - money_per_potion += 200 - if money_required > get_money_count(state, player): - return False + costs = [calc_hp_potion_cost(hp, potion) for hp, potion in upgrade_options] + money_required += min(costs) - return True + return get_money_count(state, player) >= money_required # returns a tuple of your max attack level, the number of attack offerings @@ -336,7 +319,8 @@ def get_att_level(state: CollectionState, player: int) -> Tuple[int, int]: if sword_level >= 3: att_upgrades += min(2, sword_level - 2) # attack falls off, can just cap it at 8 for simplicity - return min(8, 1 + att_offerings + att_upgrades), att_offerings + return (min(8, 1 + att_offerings + att_upgrades) + + (1 if state.has("Hero's Laurels", player) else 0), att_offerings) # returns a tuple of your max defense level, the number of defense offerings @@ -344,7 +328,9 @@ def get_def_level(state: CollectionState, player: int) -> Tuple[int, int]: def_offerings = state.count("DEF Offering", player) # defense falls off, can just cap it at 8 for simplicity return (min(8, 1 + def_offerings - + state.count_from_list({"Hero Relic - DEF", "Secret Legend", "Phonomath"}, player)), + + state.count_from_list({"Hero Relic - DEF", "Secret Legend", "Phonomath"}, player)) + + (2 if state.has("Shield", player) else 0) + + (2 if state.has("Hero's Laurels", player) else 0), def_offerings) @@ -408,6 +394,46 @@ def get_money_count(state: CollectionState, player: int) -> int: return money +def calc_hp_potion_cost(hp_upgrades: int, potion_upgrades: int) -> int: + money = 0 + + # hp costs 200 for the first, +50 for each additional + money_per_hp = 200 + for _ in range(hp_upgrades): + money += money_per_hp + money_per_hp += 50 + + # potion costs 100 for the first, 300 for the second, 1,000 for the third, and +200 for each additional + # currently we assume you will not buy past the second potion upgrade, but we might change our minds later + money_per_potion = 100 + for _ in range(potion_upgrades): + money += money_per_potion + if money_per_potion == 100: + money_per_potion = 300 + elif money_per_potion == 300: + money_per_potion = 1000 + else: + money_per_potion += 200 + + return money + + +def calc_def_sp_cost(def_upgrades: int, sp_upgrades: int) -> int: + money = 0 + + money_per_def = 100 + for _ in range(def_upgrades): + money += money_per_def + money_per_def += 50 + + money_per_sp = 200 + for _ in range(sp_upgrades): + money += money_per_sp + money_per_sp += 200 + + return money + + class TunicState(LogicMixin): tunic_need_to_reset_combat_from_collect: Dict[int, bool] tunic_need_to_reset_combat_from_remove: Dict[int, bool] @@ -420,3 +446,5 @@ def init_mixin(self, _): self.tunic_need_to_reset_combat_from_remove = defaultdict(lambda: False) # the per-player, per-area state of combat checking -- unchecked, failed, or succeeded self.tunic_area_combat_state = defaultdict(lambda: defaultdict(lambda: CombatState.unchecked)) + # a copy_mixin was intentionally excluded because the empty state from init_mixin + # will always be appropriate for recalculating the logic cache diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index 08b088f7e4a7..4d0a462cbb8a 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -1386,9 +1386,9 @@ def ls_connect(origin_name: str, portal_sdt: str) -> None: # need to fight through the rudelings and turret, or just laurels from near the windmill set_rule(ow_to_well_entry, lambda state: state.has(laurels, player) - or has_combat_reqs("East Forest", state, player)) + or has_combat_reqs("Before Well", state, player)) set_rule(ow_tunnel_beach, - lambda state: has_combat_reqs("East Forest", state, player)) + lambda state: has_combat_reqs("Before Well", state, player)) add_rule(atoll_statue, lambda state: has_combat_reqs("Ruined Atoll", state, player)) @@ -1467,12 +1467,12 @@ def ls_connect(origin_name: str, portal_sdt: str) -> None: set_rule(cath_entry_to_elev, lambda state: options.entrance_rando or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world) - or (has_ability(prayer, state, world) and has_combat_reqs("Cathedral", state, player))) + or (has_ability(prayer, state, world) and has_combat_reqs("Swamp", state, player))) set_rule(cath_entry_to_main, - lambda state: has_combat_reqs("Cathedral", state, player)) + lambda state: has_combat_reqs("Swamp", state, player)) set_rule(cath_elev_to_main, - lambda state: has_combat_reqs("Cathedral", state, player)) + lambda state: has_combat_reqs("Swamp", state, player)) # for spots where you can go into and come out of an entrance to reset enemy aggro if world.options.entrance_rando: @@ -1835,10 +1835,10 @@ def combat_logic_to_loc(loc_name: str, combat_req_area: str, set_instead: bool = combat_logic_to_loc("Overworld - [Northeast] Chest Above Patrol Cave", "Garden Knight", dagger=True) combat_logic_to_loc("Overworld - [Southwest] West Beach Guarded By Turret", "Overworld", dagger=True) combat_logic_to_loc("Overworld - [Southwest] West Beach Guarded By Turret 2", "Overworld") - combat_logic_to_loc("Overworld - [Southwest] Bombable Wall Near Fountain", "East Forest", dagger=True) - combat_logic_to_loc("Overworld - [Southwest] Fountain Holy Cross", "East Forest", dagger=True) - combat_logic_to_loc("Overworld - [Southwest] South Chest Near Guard", "East Forest", dagger=True) - combat_logic_to_loc("Overworld - [Southwest] Tunnel Guarded By Turret", "East Forest", dagger=True) + combat_logic_to_loc("Overworld - [Southwest] Bombable Wall Near Fountain", "Before Well", dagger=True) + combat_logic_to_loc("Overworld - [Southwest] Fountain Holy Cross", "Before Well", dagger=True) + combat_logic_to_loc("Overworld - [Southwest] South Chest Near Guard", "Before Well", dagger=True) + combat_logic_to_loc("Overworld - [Southwest] Tunnel Guarded By Turret", "Before Well", dagger=True) combat_logic_to_loc("Overworld - [Northwest] Chest Near Turret", "Before Well") add_rule(world.get_location("Hourglass Cave - Hourglass Chest"), @@ -1927,4 +1927,4 @@ def combat_logic_to_loc(loc_name: str, combat_req_area: str, set_instead: bool = # zip through the rubble to sneakily grab this chest, or just fight to it add_rule(world.get_location("Cathedral - [1F] Near Spikes"), - lambda state: laurels_zip(state, world) or has_combat_reqs("Cathedral", state, player)) + lambda state: laurels_zip(state, world) or has_combat_reqs("Swamp", state, player)) diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index 8fe2ea5ce854..d2ea82803704 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -197,7 +197,6 @@ class TunicPlandoConnections(PlandoConnections): class CombatLogic(Choice): """ - EXPERIMENTAL - may cause gen failures, especially when playthrough generation for the spoiler log is enabled, and may have slight logic issues. If enabled, the player will logically require a combination of stat upgrade items and equipment to get some checks or navigate to some areas, with a goal of matching the vanilla combat difficulty. The player may still be expected to run past enemies, reset aggro (by using a checkpoint or doing a scene transition), or find sneaky paths to checks. This option marks many more items as progression and may force weapons much earlier than normal. diff --git a/worlds/tunic/test/test_combat.py b/worlds/tunic/test/test_combat.py new file mode 100644 index 000000000000..866dc5f81429 --- /dev/null +++ b/worlds/tunic/test/test_combat.py @@ -0,0 +1,83 @@ +from BaseClasses import ItemClassification +from collections import Counter + +from . import TunicTestBase +from .. import options +from ..combat_logic import (check_combat_reqs, area_data, get_money_count, calc_effective_hp, get_potion_level, + get_hp_level, get_def_level, get_sp_level) +from ..items import item_table +from .. import TunicWorld + + +class TestCombat(TunicTestBase): + options = {options.CombatLogic.internal_name: options.CombatLogic.option_on} + player = 1 + world: TunicWorld + combat_items = [] + # these are items that are progression that do not contribute to combat logic + # it's listed as using skipped items instead of a list of viable items so that if we add/remove some later, + # that this won't require updates most likely + # Stick and Sword are in here because sword progression is the clear determining case here + skipped_items = {"Fairy", "Stick", "Sword", "Magic Dagger", "Magic Orb", "Lantern", "Old House Key", "Key", + "Fortress Vault Key", "Golden Coin", "Red Questagon", "Green Questagon", "Blue Questagon", + "Scavenger Mask", "Pages 24-25 (Prayer)", "Pages 42-43 (Holy Cross)", "Pages 52-53 (Icebolt)"} + # converts golden trophies to their hero relic stat equivalent, for easier parsing + converter = { + "Secret Legend": "Hero Relic - DEF", + "Phonomath": "Hero Relic - DEF", + "Just Some Pals": "Hero Relic - POTION", + "Spring Falls": "Hero Relic - POTION", + "Back To Work": "Hero Relic - POTION", + "Mr Mayor": "Hero Relic - SP", + "Power Up": "Hero Relic - SP", + "Regal Weasel": "Hero Relic - SP", + "Forever Friend": "Hero Relic - SP", + "Sacred Geometry": "Hero Relic - MP", + "Vintage": "Hero Relic - MP", + "Dusty": "Hero Relic - MP", + } + skipped_items.update({item for item in item_table.keys() if item.startswith("Ladder")}) + for item, data in item_table.items(): + if item in skipped_items: + continue + ic = data.combat_ic or data.classification + if item in converter: + item = converter[item] + if ItemClassification.progression in ic: + combat_items += [item] * data.quantity_in_item_pool + + # we had an issue where collecting certain items brought certain areas out of logic + # due to the weirdness of swapping between "you have enough attack that you don't need magic" + # so this will make sure collecting an item doesn't bring something out of logic + def test_combat_doesnt_fail_backwards(self): + combat_items = self.combat_items.copy() + self.multiworld.worlds[1].random.shuffle(combat_items) + curr_statuses = {name: False for name in area_data.keys()} + prev_statuses = curr_statuses.copy() + area_names = list(area_data.keys()) + current_items = Counter() + for current_item_name in combat_items: + current_items[current_item_name] += 1 + current_item = TunicWorld.create_item(self.world, current_item_name) + self.collect(current_item) + self.multiworld.worlds[1].random.shuffle(area_names) + for area in area_names: + curr_statuses[area] = check_combat_reqs(area, self.multiworld.state, self.player) + if curr_statuses[area] < prev_statuses[area]: + data = area_data[area] + state = self.multiworld.state + player = self.player + req_effective_hp = calc_effective_hp(data.hp_level, data.potion_level, data.potion_count) + player_potion, potion_offerings = get_potion_level(state, player) + player_hp, hp_offerings = get_hp_level(state, player) + player_def, def_offerings = get_def_level(state, player) + player_sp, sp_offerings = get_sp_level(state, player) + raise Exception(f"Status for {area} decreased after collecting {current_item_name}.\n" + f"Current items: {current_items}.\n" + f"Total money: {get_money_count(self.multiworld.state, self.player)}.\n" + f"Required Effective HP: {req_effective_hp}.\n" + f"Free HP and Offerings: {player_hp - hp_offerings}, {hp_offerings}\n" + f"Free Potion and Offerings: {player_potion - potion_offerings}, {potion_offerings}\n" + f"Free Def and Offerings: {player_def - def_offerings}, {def_offerings}\n" + f"Free SP and Offerings: {player_sp - sp_offerings}, {sp_offerings}") + prev_statuses[area] = curr_statuses[area] From 18bcaa85a27890de47e623c630a65dddb3d644d4 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 10 Feb 2025 19:18:14 +0100 Subject: [PATCH 0134/1218] Test: ensure get_all_state() does not error in between steps (#4612) --- test/general/test_state.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 test/general/test_state.py diff --git a/test/general/test_state.py b/test/general/test_state.py new file mode 100644 index 000000000000..460fc3d60846 --- /dev/null +++ b/test/general/test_state.py @@ -0,0 +1,29 @@ +import unittest + +from worlds.AutoWorld import AutoWorldRegister, call_all +from . import setup_solo_multiworld + + +class TestBase(unittest.TestCase): + gen_steps = ( + "generate_early", + "create_regions", + ) + + test_steps = ( + "create_items", + "set_rules", + "connect_entrances", + "generate_basic", + "pre_fill", + ) + + def test_all_state_is_available(self): + """Ensure all_state can be created at certain steps.""" + for game_name, world_type in AutoWorldRegister.world_types.items(): + with self.subTest("Game", game=game_name): + multiworld = setup_solo_multiworld(world_type, self.gen_steps) + for step in self.test_steps: + with self.subTest("Step", step=step): + call_all(multiworld, step) + self.assertTrue(multiworld.get_all_state(False, True)) From a298be9c41a60da209bf1eb6da15ff16f33350f1 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 10 Feb 2025 19:19:00 +0100 Subject: [PATCH 0135/1218] Core: change HINT_FOUND to 40 and HINT_UNSPECIFIED to 0 (#4620) --- NetUtils.py | 4 ++-- docs/network protocol.md | 4 ++-- kvui.py | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/NetUtils.py b/NetUtils.py index 5bcc583c53b6..f2ae2a63a056 100644 --- a/NetUtils.py +++ b/NetUtils.py @@ -12,11 +12,11 @@ class HintStatus(ByValue, enum.IntEnum): - HINT_FOUND = 0 - HINT_UNSPECIFIED = 1 + HINT_UNSPECIFIED = 0 HINT_NO_PRIORITY = 10 HINT_AVOID = 20 HINT_PRIORITY = 30 + HINT_FOUND = 40 class JSONMessagePart(typing.TypedDict, total=False): diff --git a/docs/network protocol.md b/docs/network protocol.md index e5d3b7e6c26a..05a53344267e 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -363,11 +363,11 @@ An enumeration containing the possible hint states. ```python import enum class HintStatus(enum.IntEnum): - HINT_FOUND = 0 # The location has been collected. Status cannot be changed once found. - HINT_UNSPECIFIED = 1 # The receiving player has not specified any status + HINT_UNSPECIFIED = 0 # The receiving player has not specified any status HINT_NO_PRIORITY = 10 # The receiving player has specified that the item is unneeded HINT_AVOID = 20 # The receiving player has specified that the item is detrimental HINT_PRIORITY = 30 # The receiving player has specified that the item is needed + HINT_FOUND = 40 # The location has been collected. Status cannot be changed once found. ``` - Hints for items with `ItemClassification.trap` default to `HINT_AVOID`. - Hints created with `LocationScouts`, `!hint_location`, or similar (hinting a location) default to `HINT_UNSPECIFIED`. diff --git a/kvui.py b/kvui.py index 6718e48bee33..60042b00ec5c 100644 --- a/kvui.py +++ b/kvui.py @@ -444,8 +444,11 @@ def on_touch_down(self, touch): if child.collide_point(*touch.pos): key = child.sort_key if key == "status": - parent.hint_sorter = lambda element: element["status"]["hint"]["status"] - else: parent.hint_sorter = lambda element: remove_between_brackets.sub("", element[key]["text"]).lower() + parent.hint_sorter = lambda element: status_sort_weights[element["status"]["hint"]["status"]] + else: + parent.hint_sorter = lambda element: ( + remove_between_brackets.sub("", element[key]["text"]).lower() + ) if key == parent.sort_key: # second click reverses order parent.reversed = not parent.reversed @@ -829,7 +832,13 @@ def __init__(self, *args, **kwargs): HintStatus.HINT_AVOID: "salmon", HintStatus.HINT_PRIORITY: "plum", } - +status_sort_weights: dict[HintStatus, int] = { + HintStatus.HINT_FOUND: 0, + HintStatus.HINT_UNSPECIFIED: 1, + HintStatus.HINT_NO_PRIORITY: 2, + HintStatus.HINT_AVOID: 3, + HintStatus.HINT_PRIORITY: 4, +} class HintLog(RecycleView): From f4e43ca9e097f8301ce71bb0f53cbd9fca504a5d Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 10 Feb 2025 13:22:06 -0500 Subject: [PATCH 0136/1218] LttP: mock world.random in adjuster (#4623) --- LttPAdjuster.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/LttPAdjuster.py b/LttPAdjuster.py index 7e33a3d5efe8..963557e8da81 100644 --- a/LttPAdjuster.py +++ b/LttPAdjuster.py @@ -33,10 +33,15 @@ WINDOW_MIN_WIDTH = 425 class AdjusterWorld(object): + class AdjusterSubWorld(object): + def __init__(self, random): + self.random = random + def __init__(self, sprite_pool): import random self.sprite_pool = {1: sprite_pool} self.per_slot_randoms = {1: random} + self.worlds = {1: self.AdjusterSubWorld(random)} class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter): From e9c463c897449202c4e958fe5a13947eee3325f2 Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 10 Feb 2025 13:23:09 -0500 Subject: [PATCH 0137/1218] CC: Force Text Client to always connect with empty game (#4607) --- CommonClient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CommonClient.py b/CommonClient.py index 996ba3300575..eb38195216b6 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -1095,7 +1095,7 @@ async def server_auth(self, password_requested: bool = False): if password_requested and not self.password: await super(TextContext, self).server_auth(password_requested) await self.get_username() - await self.send_connect() + await self.send_connect(game="") def on_package(self, cmd: str, args: dict): if cmd == "Connected": From dbf6b6f935c7b049c015a8a6830e078c769326ec Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 10 Feb 2025 13:23:58 -0500 Subject: [PATCH 0138/1218] CC: don't try to reconnect on invalid version (#4606) --- CommonClient.py | 1 + 1 file changed, 1 insertion(+) diff --git a/CommonClient.py b/CommonClient.py index eb38195216b6..33792f0ed28b 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -907,6 +907,7 @@ async def process_server_cmd(ctx: CommonContext, args: dict): ctx.disconnected_intentionally = True ctx.event_invalid_game() elif 'IncompatibleVersion' in errors: + ctx.disconnected_intentionally = True raise Exception('Server reported your client version as incompatible. ' 'This probably means you have to update.') elif 'InvalidItemsHandling' in errors: From 910369a7f8d1e08744c616b59beedbeb5b2c3f90 Mon Sep 17 00:00:00 2001 From: PinkSwitch <52474902+PinkSwitch@users.noreply.github.com> Date: Mon, 10 Feb 2025 12:27:10 -0600 Subject: [PATCH 0139/1218] Bizhawk Client: Display Err (#4532) Co-authored-by: Bryce Wilson --- worlds/_bizhawk/context.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/_bizhawk/context.py b/worlds/_bizhawk/context.py index cb59050b84f6..accb5f94c482 100644 --- a/worlds/_bizhawk/context.py +++ b/worlds/_bizhawk/context.py @@ -238,6 +238,7 @@ def _patch_and_run_game(patch_file: str): return metadata except Exception as exc: logger.exception(exc) + Utils.messagebox("Error Patching Game", str(exc), True) return {} From f520c1d9f28d50850f7cb3b2cd58e5ad8984e43d Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 10 Feb 2025 13:34:27 -0500 Subject: [PATCH 0140/1218] Launcher: Allow for --nogui client launches (#4549) --- worlds/_bizhawk/client.py | 4 ++-- worlds/ahit/__init__.py | 4 ++-- worlds/factorio/__init__.py | 4 ++-- worlds/kh1/__init__.py | 4 ++-- worlds/kh2/__init__.py | 4 ++-- worlds/zork_grand_inquisitor/__init__.py | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/worlds/_bizhawk/client.py b/worlds/_bizhawk/client.py index ce75b864b88c..16a8325a10f7 100644 --- a/worlds/_bizhawk/client.py +++ b/worlds/_bizhawk/client.py @@ -7,7 +7,7 @@ import abc from typing import TYPE_CHECKING, Any, ClassVar -from worlds.LauncherComponents import Component, SuffixIdentifier, Type, components, launch_subprocess +from worlds.LauncherComponents import Component, SuffixIdentifier, Type, components, launch as launch_component if TYPE_CHECKING: from .context import BizHawkClientContext @@ -15,7 +15,7 @@ def launch_client(*args) -> None: from .context import launch - launch_subprocess(launch, name="BizHawkClient", args=args) + launch_component(launch, name="BizHawkClient", args=args) component = Component("BizHawk Client", "BizHawkClient", component_type=Type.CLIENT, func=launch_client, diff --git a/worlds/ahit/__init__.py b/worlds/ahit/__init__.py index 14cf13ec346d..c2fe39872f31 100644 --- a/worlds/ahit/__init__.py +++ b/worlds/ahit/__init__.py @@ -12,13 +12,13 @@ from worlds.AutoWorld import World, WebWorld, CollectionState from worlds.generic.Rules import add_rule from typing import List, Dict, TextIO -from worlds.LauncherComponents import Component, components, icon_paths, launch_subprocess, Type +from worlds.LauncherComponents import Component, components, icon_paths, launch as launch_component, Type from Utils import local_path def launch_client(): from .Client import launch - launch_subprocess(launch, name="AHITClient") + launch_component(launch, name="AHITClient") components.append(Component("A Hat in Time Client", "AHITClient", func=launch_client, diff --git a/worlds/factorio/__init__.py b/worlds/factorio/__init__.py index ca9f12f1b21a..3f480527f549 100644 --- a/worlds/factorio/__init__.py +++ b/worlds/factorio/__init__.py @@ -8,7 +8,7 @@ import settings from BaseClasses import Region, Location, Item, Tutorial, ItemClassification from worlds.AutoWorld import World, WebWorld -from worlds.LauncherComponents import Component, components, Type, launch_subprocess +from worlds.LauncherComponents import Component, components, Type, launch as launch_component from worlds.generic import Rules from .Locations import location_pools, location_table from .Mod import generate_mod @@ -24,7 +24,7 @@ def launch_client(): from .Client import launch - launch_subprocess(launch, name="FactorioClient") + launch_component(launch, name="FactorioClient") components.append(Component("Factorio Client", "FactorioClient", func=launch_client, component_type=Type.CLIENT)) diff --git a/worlds/kh1/__init__.py b/worlds/kh1/__init__.py index 3b498acf4670..ac0afca50142 100644 --- a/worlds/kh1/__init__.py +++ b/worlds/kh1/__init__.py @@ -9,12 +9,12 @@ from .Regions import connect_entrances, create_regions from .Rules import set_rules from .Presets import kh1_option_presets -from worlds.LauncherComponents import Component, components, Type, launch_subprocess +from worlds.LauncherComponents import Component, components, Type, launch as launch_component def launch_client(): from .Client import launch - launch_subprocess(launch, name="KH1 Client") + launch_component(launch, name="KH1 Client") components.append(Component("KH1 Client", "KH1Client", func=launch_client, component_type=Type.CLIENT)) diff --git a/worlds/kh2/__init__.py b/worlds/kh2/__init__.py index 59c77627eebe..edc4305accaf 100644 --- a/worlds/kh2/__init__.py +++ b/worlds/kh2/__init__.py @@ -3,7 +3,7 @@ from BaseClasses import Tutorial, ItemClassification from Fill import fast_fill -from worlds.LauncherComponents import Component, components, Type, launch_subprocess +from worlds.LauncherComponents import Component, components, Type, launch as launch_component from worlds.AutoWorld import World, WebWorld from .Items import * from .Locations import * @@ -17,7 +17,7 @@ def launch_client(): from .Client import launch - launch_subprocess(launch, name="KH2Client") + launch_component(launch, name="KH2Client") components.append(Component("KH2 Client", "KH2Client", func=launch_client, component_type=Type.CLIENT)) diff --git a/worlds/zork_grand_inquisitor/__init__.py b/worlds/zork_grand_inquisitor/__init__.py index 4da257e47bd0..791f41dd00a2 100644 --- a/worlds/zork_grand_inquisitor/__init__.py +++ b/worlds/zork_grand_inquisitor/__init__.py @@ -5,7 +5,7 @@ def launch_client() -> None: from .client import main - LauncherComponents.launch_subprocess(main, name="ZorkGrandInquisitorClient") + LauncherComponents.launch(main, name="ZorkGrandInquisitorClient") LauncherComponents.components.append( From f1769a8d0070dad489e35edb481e81ba0330c95f Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Wed, 12 Feb 2025 19:45:03 +0300 Subject: [PATCH 0141/1218] Stardew Valley: Fixed Powdermelon and option inconsistencies (#4632) * - Fixed powdermelon season * - Improve cohesion in presets * - Update several tooltips to be more consistent and accurate --- worlds/stardew_valley/content/vanilla/base.py | 2 +- worlds/stardew_valley/options/options.py | 35 ++++++++++--------- worlds/stardew_valley/options/presets.py | 2 +- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/worlds/stardew_valley/content/vanilla/base.py b/worlds/stardew_valley/content/vanilla/base.py index 2c910df5d00f..9e5f53eb866e 100644 --- a/worlds/stardew_valley/content/vanilla/base.py +++ b/worlds/stardew_valley/content/vanilla/base.py @@ -140,7 +140,7 @@ def finalize_hook(self, content: StardewContent): Vegetable.broccoli: (HarvestCropSource(seed=Seed.broccoli, seasons=(Season.fall,)),), Vegetable.carrot: (HarvestCropSource(seed=Seed.carrot, seasons=(Season.spring,)),), - Fruit.powdermelon: (HarvestCropSource(seed=Seed.powdermelon, seasons=(Season.summer,)),), + Fruit.powdermelon: (HarvestCropSource(seed=Seed.powdermelon, seasons=(Season.winter,)),), Vegetable.summer_squash: (HarvestCropSource(seed=Seed.summer_squash, seasons=(Season.summer,)),), Fruit.strawberry: (HarvestCropSource(seed=Seed.strawberry, seasons=(Season.spring,)),), diff --git a/worlds/stardew_valley/options/options.py b/worlds/stardew_valley/options/options.py index f66ec3bdad80..aaeeedd1b3d8 100644 --- a/worlds/stardew_valley/options/options.py +++ b/worlds/stardew_valley/options/options.py @@ -66,7 +66,8 @@ def get_option_name(cls, value) -> str: class FarmType(Choice): - """What farm to play on?""" + """What farm to play on? + Custom farms are not supported""" internal_name = "farm_type" display_name = "Farm Type" default = "random" @@ -203,7 +204,7 @@ class SeasonRandomization(Choice): class Cropsanity(Choice): - """Formerly named "Seed Shuffle" + """ Pierre now sells a random amount of seasonal seeds and Joja sells them without season requirements, but only in huge packs. Disabled: All the seeds are unlocked from the start, there are no location checks for growing and harvesting crops Enabled: Seeds are unlocked as archipelago items, for each seed there is a location check for growing and harvesting that crop @@ -233,9 +234,9 @@ class BackpackProgression(Choice): class ToolProgression(Choice): """Shuffle the tool upgrades? Vanilla: Clint will upgrade your tools with metal bars. - Progressive: You will randomly find Progressive Tool upgrades. - Cheap: Tool Upgrades will cost 2/5th as much - Very Cheap: Tool Upgrades will cost 1/5th as much""" + Progressive: Your tools upgrades are randomized. + Cheap: Tool Upgrades have a 60% discount + Very Cheap: Tool Upgrades have an 80% discount""" internal_name = "tool_progression" display_name = "Tool Progression" default = 1 @@ -279,8 +280,8 @@ class BuildingProgression(Choice): Vanilla: You can buy each building normally. Progressive: You will receive the buildings and will be able to build the first one of each type for free, once it is received. If you want more of the same building, it will cost the vanilla price. - Cheap: Buildings will cost half as much - Very Cheap: Buildings will cost 1/5th as much + Cheap: Buildings will have a 50% discount + Very Cheap: Buildings will an 80% discount """ internal_name = "building_progression" display_name = "Building Progression" @@ -327,7 +328,7 @@ class ArcadeMachineLocations(Choice): class SpecialOrderLocations(Choice): """Shuffle Special Orders? - Disabled: The special orders are not included in the Archipelago shuffling. + Vanilla: The special orders are not included in the Archipelago shuffling. You may need to complete some of them anyway for their vanilla rewards Board Only: The Special Orders on the board in town are location checks Board and Qi: The Special Orders from Mr Qi's walnut room are checks, in addition to the board in town Short: All Special Order requirements are reduced by 40% @@ -377,12 +378,12 @@ class QuestLocations(NamedRange): class Fishsanity(Choice): - """Locations for catching a fish the first time? + """Locations for catching each fish the first time? None: There are no locations for catching fish Legendaries: Each of the 5 legendary fish are checks, plus the extended family if qi board is turned on Special: A curated selection of strong fish are checks Randomized: A random selection of fish are checks - All: Every single fish in the game is a location that contains an item. Pairs well with the Master Angler Goal + All: Every single fish in the game is a location that contains an item. Exclude Legendaries: Every fish except legendaries Exclude Hard Fish: Every fish under difficulty 80 Only Easy Fish: Every fish under difficulty 50 @@ -517,7 +518,7 @@ class Chefsanity(NamedRange): class Craftsanity(Choice): """Checks for crafting items? If enabled, all recipes purchased in shops will be checks as well. - Recipes obtained from other sources will depend on related archipelago settings + Recipes obtained from other sources will depend on their respective archipelago settings """ internal_name = "craftsanity" display_name = "Craftsanity" @@ -530,9 +531,9 @@ class Friendsanity(Choice): """Shuffle Friendships? None: Friendship hearts are earned normally Bachelors: Hearts with bachelors are shuffled - Starting NPCs: Hearts for NPCs available immediately are checks - All: Hearts for all npcs are checks, including Leo, Kent, Sandy, etc - All With Marriage: Hearts for all npcs are checks, including romance hearts up to 14 when applicable + Starting NPCs: Hearts for NPCs available immediately are shuffled + All: Hearts for all npcs are shuffled, including Leo, Kent, Sandy, etc + All With Marriage: All hearts for all npcs are shuffled, including romance hearts up to 14 when applicable """ internal_name = "friendsanity" display_name = "Friendsanity" @@ -577,7 +578,7 @@ class Walnutsanity(OptionSet): """Shuffle walnuts? Puzzles: Walnuts obtained from solving a special puzzle or winning a minigame Bushes: Walnuts that are in a bush and can be collected by clicking it - Dig spots: Walnuts that are underground and must be digged up. Includes Journal scrap walnuts + Dig Spots: Walnuts that are underground and must be digged up. Includes Journal scrap walnuts Repeatables: Random chance walnuts from normal actions (fishing, farming, combat, etc) """ internal_name = "walnutsanity" @@ -612,7 +613,7 @@ class NumberOfMovementBuffs(Range): class EnabledFillerBuffs(OptionSet): """Enable various permanent player buffs to roll as filler items - Luck: Increase daily luck + Luck: Increased daily luck Damage: Increased Damage % Defense: Increased Defense Immunity: Increased Immunity @@ -637,7 +638,7 @@ class EnabledFillerBuffs(OptionSet): class ExcludeGingerIsland(Toggle): """Exclude Ginger Island? This option will forcefully exclude everything related to Ginger Island from the slot. - If you pick a goal that requires Ginger Island, you cannot exclude it and it will get included anyway""" + If you pick a goal that requires Ginger Island, this option will get forced to 'false'""" internal_name = "exclude_ginger_island" display_name = "Exclude Ginger Island" default = 0 diff --git a/worlds/stardew_valley/options/presets.py b/worlds/stardew_valley/options/presets.py index c2c210e5ca6e..3dbb5ab3f554 100644 --- a/worlds/stardew_valley/options/presets.py +++ b/worlds/stardew_valley/options/presets.py @@ -122,7 +122,7 @@ options.Friendsanity.internal_name: options.Friendsanity.option_starting_npcs, options.FriendsanityHeartSize.internal_name: 4, options.Booksanity.internal_name: options.Booksanity.option_power_skill, - options.Walnutsanity.internal_name: [WalnutsanityOptionName.puzzles], + options.Walnutsanity.internal_name: options.Walnutsanity.preset_none, options.NumberOfMovementBuffs.internal_name: 6, options.EnabledFillerBuffs.internal_name: options.EnabledFillerBuffs.preset_all, options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true, From b2162bb8e698fcc910377c3f76d5893c5f36ff3e Mon Sep 17 00:00:00 2001 From: qwint Date: Wed, 12 Feb 2025 11:46:07 -0500 Subject: [PATCH 0142/1218] Docs: clean up create_item/event example (#4596) * eyes * remove line wraps where unnecessary --- docs/world api.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/world api.md b/docs/world api.md index da74be70fb91..6a45ccbf99dc 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -562,17 +562,13 @@ from .items import is_progression # this is just a dummy def create_item(self, item: str) -> MyGameItem: # this is called when AP wants to create an item by name (for plando) or when you call it from your own code - classification = ItemClassification.progression if is_progression(item) else - ItemClassification.filler - - -return MyGameItem(item, classification, self.item_name_to_id[item], - self.player) + classification = ItemClassification.progression if is_progression(item) else ItemClassification.filler + return MyGameItem(item, classification, self.item_name_to_id[item], self.player) def create_event(self, event: str) -> MyGameItem: # while we are at it, we can also add a helper to create events - return MyGameItem(event, True, None, self.player) + return MyGameItem(event, ItemClassification.progression, None, self.player) ``` #### create_items From 5c1ded1fe97a8f9fc5c69ac24d2832605c34347b Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Wed, 12 Feb 2025 11:46:43 -0500 Subject: [PATCH 0143/1218] LADX: bomb as logical bush breaker #4636 --- worlds/ladx/LADXR/logic/requirements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/ladx/LADXR/logic/requirements.py b/worlds/ladx/LADXR/logic/requirements.py index fa01627a15c3..4e1fe03b096f 100644 --- a/worlds/ladx/LADXR/logic/requirements.py +++ b/worlds/ladx/LADXR/logic/requirements.py @@ -253,7 +253,7 @@ def isConsumable(item) -> bool: class RequirementsSettings: def __init__(self, options): - self.bush = OR(SWORD, MAGIC_POWDER, MAGIC_ROD, POWER_BRACELET, BOOMERANG) + self.bush = OR(SWORD, MAGIC_POWDER, MAGIC_ROD, POWER_BRACELET, BOOMERANG, BOMB) self.pit_bush = OR(SWORD, MAGIC_POWDER, MAGIC_ROD, BOOMERANG, BOMB) # unique self.attack = OR(SWORD, BOMB, BOW, MAGIC_ROD, BOOMERANG) self.attack_hookshot = OR(SWORD, BOMB, BOW, MAGIC_ROD, BOOMERANG, HOOKSHOT) # hinox, shrouded stalfos From c799531105808c45849aa282168a3efa1a58f2e7 Mon Sep 17 00:00:00 2001 From: Matthew Wells <91291346+richarm4@users.noreply.github.com> Date: Wed, 12 Feb 2025 08:47:17 -0800 Subject: [PATCH 0144/1218] Docs: Add missing plural in faq (#4622) --- WebHostLib/static/assets/faq/en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/static/assets/faq/en.md b/WebHostLib/static/assets/faq/en.md index e64535b42d03..96e526612be6 100644 --- a/WebHostLib/static/assets/faq/en.md +++ b/WebHostLib/static/assets/faq/en.md @@ -22,7 +22,7 @@ players to rely upon each other to complete their game. While a multiworld game traditionally requires all players to be playing the same game, a multi-game multiworld allows players to randomize any of the supported games, and send items between them. This allows players of different -games to interact with one another in a single multiplayer environment. Archipelago supports multi-game multiworld. +games to interact with one another in a single multiplayer environment. Archipelago supports multi-game multiworlds. Here is a list of our [Supported Games](https://archipelago.gg/games). ## Can I generate a single-player game with Archipelago? From efd5004330e2cb25bac094a2b78f370cacece635 Mon Sep 17 00:00:00 2001 From: JoshuaEagles Date: Wed, 12 Feb 2025 11:47:43 -0500 Subject: [PATCH 0145/1218] Docs: Update SA2B Linux and Steam Deck Setup Guide + Add Celeste 64 Linux Setup Guide (#4593) * Update Linux and Steam Deck setup guide for sa2b * Add Linux and Steam Deck setup guide for Celeste 64 --- worlds/celeste64/docs/guide_en.md | 8 +++++-- worlds/sa2b/docs/setup_en.md | 36 ++++++++++++++----------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/worlds/celeste64/docs/guide_en.md b/worlds/celeste64/docs/guide_en.md index 74ab94b913d1..87ebf09f755e 100644 --- a/worlds/celeste64/docs/guide_en.md +++ b/worlds/celeste64/docs/guide_en.md @@ -12,6 +12,12 @@ 1. Download the above release and extract it. +## Installation Procedures (Linux and Steam Deck) + +1. Download the above release and extract it. + +2. Add Celeste64.exe to Steam as a Non-Steam Game. In the properties for it on Steam, set it to use Proton as the compatibility tool. Launch the game through Steam in order to run it. + ## Joining a MultiWorld Game 1. Before launching the game, edit the `AP.json` file in the root of the Celeste 64 install. @@ -33,5 +39,3 @@ An Example `AP.json` file: "Password": "" } ``` - - diff --git a/worlds/sa2b/docs/setup_en.md b/worlds/sa2b/docs/setup_en.md index f32001a67827..c34e45ce9b51 100644 --- a/worlds/sa2b/docs/setup_en.md +++ b/worlds/sa2b/docs/setup_en.md @@ -5,7 +5,7 @@ - Sonic Adventure 2: Battle from: [Sonic Adventure 2: Battle Steam Store Page](https://store.steampowered.com/app/213610/Sonic_Adventure_2/) - The Battle DLC is required if you choose to add Chao Karate locations to the randomizer - SA Mod Manager from: [SA Mod Manager GitHub Releases Page](https://github.com/X-Hax/SA-Mod-Manager/releases) -- .NET Desktop Runtime 7.0 from: [.NET Desktop Runtime 7.0 Download Page](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-7.0.9-windows-x64-installer) +- .NET Desktop Runtime 8.0 from: [.NET Desktop Runtime 8.0 Download Page](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-8.0.12-windows-x64-installer) - Archipelago Mod for Sonic Adventure 2: Battle from: [Sonic Adventure 2: Battle Archipelago Randomizer Mod Releases Page](https://github.com/PoryGone/SA2B_Archipelago/releases/) @@ -36,27 +36,23 @@ 1. Install Sonic Adventure 2: Battle from Steam. -2. In the properties for Sonic Adventure 2 on Steam, force the use of Proton Experimental as the compatibility tool. - -3. Launch the game at least once without mods. - -4. Create both a `/mods` directory and a `/SAManager` directory in the folder into which you installed Sonic Adventure 2: Battle. +2. Launch the game at least once without mods. -5. Install SA Mod Manager as per [its instructions](https://github.com/X-Hax/SA-Mod-Manager/tree/master?tab=readme-ov-file). Specifically, extract SAModManager.exe file to the folder that Sonic Adventure 2: Battle is installed to. To launch it, add ``SAModManager.exe`` as a non-Steam game. In the properties on Steam for SA Mod Manager, set it to use Proton as the compatibility tool. +3. Create both a `/mods` directory and a `/SAManager` directory in the folder into which you installed Sonic Adventure 2: Battle. -6. Run SAModManager.exe from Steam once. It should produce an error popup for a missing dependency, close the error. +4. Unpack the Archipelago Mod into this folder, so that `/mods/SA2B_Archipelago` is a valid path. -7. Install protontricks, on the Steam Deck this can be done via the Discover store, on other distros instructions vary, [see its github page](https://github.com/Matoking/protontricks). +5. In the SA2B_Archipelago folder, copy the `APCpp.dll` file and paste it in the Sonic Adventure 2 install folder (where `sonic2app.exe` is). -8. Download the [.NET 7 Desktop Runtime for x64 Windows](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-7.0.17-windows-x64-installer). If this link does not work, the download can be found on [this page](https://dotnet.microsoft.com/en-us/download/dotnet/7.0). +6. Install SA Mod Manager as per [its instructions](https://github.com/X-Hax/SA-Mod-Manager/tree/master?tab=readme-ov-file). Specifically, extract SAModManager.exe file to the folder that Sonic Adventure 2: Battle is installed to. To launch it, add ``SAModManager.exe`` as a non-Steam game. In the properties on Steam for SA Mod Manager, set it to use Proton as the compatibility tool. -9. Right click the .NET 7 Desktop Runtime exe, and assuming protontricks was installed correctly, the option to "Open with Protontricks Launcher" should be available. Click that, and in the popup window that opens, select SAModManager.exe. Follow the prompts after this to install the .NET 7 Desktop Runtime for SAModManager. Once it is done, you should be able to successfully launch SAModManager to steam. +7. Run SAModManager.exe from Steam once. It should produce an error popup saying you need .NET Desktop Runtime and ask you if you'd like to download it. Say yes and it will download through your browser. -6. Unpack the Archipelago Mod into this folder, so that `/mods/SA2B_Archipelago` is a valid path. +8. Install protontricks, on the Steam Deck this can be done via the Discover store, on other distros instructions vary, [see its github page](https://github.com/Matoking/protontricks). -7. In the SA2B_Archipelago folder, copy the `APCpp.dll` file and paste it in the Sonic Adventure 2 install folder (where `sonic2app.exe` is). +9. Right click the .NET Desktop Runtime exe that was downloaded in step 6, and assuming protontricks was installed correctly, the option to "Open with Protontricks Launcher" should be available. Click that, and in the popup window that opens, select SAModManager.exe. Follow the prompts after this to install the .NET Desktop Runtime for SAModManager. Once it is done, you should be able to successfully launch SAModManager to steam. -8. Launch `SAModManager.exe` from Steam and make sure the SA2B_Archipelago mod is listed and enabled. +10. Launch `SAModManager.exe` from Steam and make sure the SA2B_Archipelago mod is listed and enabled. Note: Ensure that you launch Sonic Adventure 2 from Steam directly on Linux, rather than launching using the `Save & Play` button in SA Mod Manager. @@ -77,7 +73,7 @@ Note: Ensure that you launch Sonic Adventure 2 from Steam directly on Linux, rat ## Additional Options Some additional settings related to the Archipelago messages in game can be adjusted in the SAModManager if you select `Configure Mod` on the SA2B_Archipelago mod. This settings will be under a `General Settings` tab. - + - Message Display Count: This is the maximum number of Archipelago messages that can be displayed on screen at any given time. - Message Display Duration: This dictates how long Archipelago messages are displayed on screen (in seconds). - Message Font Size: The is the size of the font used to display the messages from Archipelago. @@ -94,7 +90,7 @@ If you wish to use the `SADX Music` option of the Randomizer, you must own a cop - "The following mods didn't load correctly: SA2B_Archipelago: DLL error - The specified module could not be found." - Make sure the `APCpp.dll` is in the same folder as the `sonic2app.exe`. (See Installation Procedures step 6) - + - "sonic2app.exe - Entry Point Not Found" - Make sure the `APCpp.dll` is up to date. Follow Installation Procedures step 6 to update the dll. @@ -116,7 +112,7 @@ If you wish to use the `SADX Music` option of the Randomizer, you must own a cop 1. Run the Launcher.exe which should be in the same folder as the your Sonic Adventure 2: Battle install. 2. Select the `Player` tab and reselect the controller for the player 1 input method. 3. Click the `Save settings and launch SONIC ADVENTURE 2` button. (Any mod manager settings will apply even if the game is launched this way rather than through the mod manager) - + - Game crashes after display logos. - This may be caused by a high monitor refresh rate. - Change the monitor refresh rate to 60 Hz [Change display refresh rate on Windows] (https://support.microsoft.com/en-us/windows/change-your-display-refresh-rate-in-windows-c8ea729e-0678-015c-c415-f806f04aae5a) @@ -125,13 +121,13 @@ If you wish to use the `SADX Music` option of the Randomizer, you must own a cop 2. Select the `Compatibility` tab. 3. Check the `Run this program in compatility mode for:` box and select Windows 7 in the drop down. 4. Click the `Apply` button. - + - No resolution options in the Launcher.exe. - In the `Graphics device` dropdown, select the device and display you plan to run the game on. The `Resolution` dropdown should populate once a graphics device is selected. - + - No music is playing in the game. - If you enabled an `SADX Music` option, then most likely the music data was not copied properly into the mod folder (See Additional Options for instructions). - + - Mission 1 is missing a texture in the stage select UI. - Most likely another mod is conflicting and overwriting the texture pack. It is recommeded to have the SA2B Archipelago mod load last in the mod manager. From 34795b598a7a94cca93a744c8e8a115183f9e028 Mon Sep 17 00:00:00 2001 From: qwint Date: Sun, 16 Feb 2025 14:21:09 -0500 Subject: [PATCH 0146/1218] GER: Use Itempool Count for Minimal handling (#4649) * uses itempool count vs unfilled location count instead of counting prog_items values which could have custom counters * move unfilled location check to before can_reach * add tests for successful minimal GER call with extra collect override prog_items in the pool to regression test issue fixed in this PR --- entrance_rando.py | 5 +++-- test/general/test_entrance_rando.py | 31 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/entrance_rando.py b/entrance_rando.py index 5aa16fa0bb06..b6e64002bd38 100644 --- a/entrance_rando.py +++ b/entrance_rando.py @@ -378,13 +378,14 @@ def find_pairing(dead_end: bool, require_new_exits: bool) -> bool: and world.multiworld.has_beaten_game(er_state.collection_state, world.player): # ensure that we have enough locations to place our progression accessible_location_count = 0 - prog_item_count = sum(er_state.collection_state.prog_items[world.player].values()) + prog_item_count = len([item for item in world.multiworld.itempool if item.advancement and item.player == world.player]) # short-circuit location checking in this case if prog_item_count == 0: return True for region in er_state.placed_regions: for loc in region.locations: - if loc.can_reach(er_state.collection_state): + if not loc.item and loc.can_reach(er_state.collection_state): + # don't count locations with preplaced items accessible_location_count += 1 if accessible_location_count >= prog_item_count: perform_validity_check = False diff --git a/test/general/test_entrance_rando.py b/test/general/test_entrance_rando.py index efbcf7df4636..7e904d33403d 100644 --- a/test/general/test_entrance_rando.py +++ b/test/general/test_entrance_rando.py @@ -311,6 +311,37 @@ def test_minimal_entrance_rando(self): self.assertEqual([], [exit_ for region in multiworld.get_regions() for exit_ in region.exits if not exit_.connected_region]) + def test_minimal_entrance_rando_with_collect_override(self): + """ + tests that entrance randomization can complete with minimal accessibility and unreachable exits + when the world defines a collect override that add extra values to prog_items + """ + multiworld = generate_test_multiworld() + multiworld.worlds[1].options.accessibility = Accessibility.from_any(Accessibility.option_minimal) + multiworld.completion_condition[1] = lambda state: state.can_reach("region24", player=1) + generate_disconnected_region_grid(multiworld, 5, 1) + prog_items = generate_items(10, 1, True) + multiworld.itempool += prog_items + filler_items = generate_items(15, 1, False) + multiworld.itempool += filler_items + e = multiworld.get_entrance("region1_right", 1) + set_rule(e, lambda state: False) + + old_collect = multiworld.worlds[1].collect + + def new_collect(state, item): + old_collect(state, item) + state.prog_items[item.player]["counter"] += 300 + + multiworld.worlds[1].collect = new_collect + + randomize_entrances(multiworld.worlds[1], False, directionally_matched_group_lookup) + + self.assertEqual([], [entrance for region in multiworld.get_regions() + for entrance in region.entrances if not entrance.parent_region]) + self.assertEqual([], [exit_ for region in multiworld.get_regions() + for exit_ in region.exits if not exit_.connected_region]) + def test_restrictive_region_requirement_does_not_fail(self): multiworld = generate_test_multiworld() generate_disconnected_region_grid(multiworld, 2, 1) From 8349774c5cfb18487124019c43d1c03dcb6e5698 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Sun, 16 Feb 2025 23:51:36 +0100 Subject: [PATCH 0147/1218] customserver: ignore static datapackage optimization for old games (#4650) --- WebHostLib/customserver.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WebHostLib/customserver.py b/WebHostLib/customserver.py index a2eef108b0a1..76a2b8a4dc15 100644 --- a/WebHostLib/customserver.py +++ b/WebHostLib/customserver.py @@ -117,6 +117,7 @@ def load(self, room_id: int): self.gamespackage = {"Archipelago": static_gamespackage.get("Archipelago", {})} # this may be modified by _load self.item_name_groups = {"Archipelago": static_item_name_groups.get("Archipelago", {})} self.location_name_groups = {"Archipelago": static_location_name_groups.get("Archipelago", {})} + missing_checksum = False for game in list(multidata.get("datapackage", {})): game_data = multidata["datapackage"][game] @@ -132,11 +133,13 @@ def load(self, room_id: int): continue else: self.logger.warning(f"Did not find game_data_package for {game}: {game_data['checksum']}") + else: + missing_checksum = True # Game rolled on old AP and will load data package from multidata self.gamespackage[game] = static_gamespackage.get(game, {}) self.item_name_groups[game] = static_item_name_groups.get(game, {}) self.location_name_groups[game] = static_location_name_groups.get(game, {}) - if not game_data_packages: + if not game_data_packages and not missing_checksum: # all static -> use the static dicts directly self.gamespackage = static_gamespackage self.item_name_groups = static_item_name_groups From 378fa5d5c4b5dfea8ebd51e67ae4fc8309cfedff Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sun, 16 Feb 2025 19:30:40 -0500 Subject: [PATCH 0148/1218] Fix gun missing from combat_items, add new for combat logic cache, very slight refactor of check_combat_reqs to let it do the changeover in a less complicated fashion, fix area being a boss area rather than non-boss area for a check (#4657) --- worlds/tunic/combat_logic.py | 22 +++++------------- worlds/tunic/er_rules.py | 2 +- worlds/tunic/items.py | 2 +- worlds/tunic/test/test_combat.py | 38 +++++++++++++++++++++++++++++++- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/worlds/tunic/combat_logic.py b/worlds/tunic/combat_logic.py index 2e490d1dad6e..2e9f19dbc296 100644 --- a/worlds/tunic/combat_logic.py +++ b/worlds/tunic/combat_logic.py @@ -140,24 +140,14 @@ def check_combat_reqs(area_name: str, state: CollectionState, player: int, alt_d # need sword for bosses if data.is_boss: return False - equipment.remove("Sword") - if has_magic: - if "Magic" not in equipment: - equipment.append("Magic") - # +4 mp pretty much makes up for the lack of sword, at least in Quarry - extra_mp_needed += 4 - if stick_bool: - # stick is a backup plan, and doesn't scale well, so let's require a little less - equipment.append("Stick") - extra_att_needed -= 2 - else: - extra_mp_needed += 2 - extra_att_needed -= 32 - elif stick_bool: + if stick_bool: + equipment.remove("Sword") equipment.append("Stick") # may revise this later based on feedback extra_att_needed += 3 extra_def_needed += 2 + # this is for when it changes over to the magic-only state if it needs to later + extra_mp_needed += 4 else: return False @@ -204,7 +194,7 @@ def check_combat_reqs(area_name: str, state: CollectionState, player: int, alt_d equip_list.append("Magic") more_modified_stats = AreaStats(modified_stats.att_level - 32, modified_stats.def_level, modified_stats.potion_level, modified_stats.hp_level, - modified_stats.sp_level, modified_stats.mp_level + 4, + modified_stats.sp_level, modified_stats.mp_level + 2, modified_stats.potion_count, equip_list, data.is_boss) if check_combat_reqs("none", state, player, more_modified_stats): return True @@ -222,7 +212,7 @@ def has_required_stats(data: AreaStats, state: CollectionState, player: int) -> player_att, att_offerings = get_att_level(state, player) # if you have 2 more attack than needed, we can forego needing mp - if data.mp_level > 1: + if data.mp_level > 1 and "Magic" in data.equipment: if player_att < data.att_level + 2: player_mp, mp_offerings = get_mp_level(state, player) if player_mp < data.mp_level: diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index 4d0a462cbb8a..f111fed8b13a 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -1832,7 +1832,7 @@ def combat_logic_to_loc(loc_name: str, combat_req_area: str, set_instead: bool = if world.options.combat_logic == CombatLogic.option_on: combat_logic_to_loc("Overworld - [Northeast] Flowers Holy Cross", "Garden Knight") combat_logic_to_loc("Overworld - [Northwest] Chest Near Quarry Gate", "Before Well", dagger=True) - combat_logic_to_loc("Overworld - [Northeast] Chest Above Patrol Cave", "Garden Knight", dagger=True) + combat_logic_to_loc("Overworld - [Northeast] Chest Above Patrol Cave", "West Garden", dagger=True) combat_logic_to_loc("Overworld - [Southwest] West Beach Guarded By Turret", "Overworld", dagger=True) combat_logic_to_loc("Overworld - [Southwest] West Beach Guarded By Turret 2", "Overworld") combat_logic_to_loc("Overworld - [Southwest] Bombable Wall Near Fountain", "Before Well", dagger=True) diff --git a/worlds/tunic/items.py b/worlds/tunic/items.py index 846650c68fef..20696eb51128 100644 --- a/worlds/tunic/items.py +++ b/worlds/tunic/items.py @@ -212,7 +212,7 @@ class TunicItemData(NamedTuple): combat_items: List[str] = [name for name, data in item_table.items() if data.combat_ic and IC.progression in data.combat_ic] -combat_items.extend(["Stick", "Sword", "Sword Upgrade", "Magic Wand", "Hero's Laurels"]) +combat_items.extend(["Stick", "Sword", "Sword Upgrade", "Magic Wand", "Hero's Laurels", "Gun"]) item_name_to_id: Dict[str, int] = {name: item_base_id + data.item_id_offset for name, data in item_table.items()} diff --git a/worlds/tunic/test/test_combat.py b/worlds/tunic/test/test_combat.py index 866dc5f81429..c0e76ef92bca 100644 --- a/worlds/tunic/test/test_combat.py +++ b/worlds/tunic/test/test_combat.py @@ -4,7 +4,7 @@ from . import TunicTestBase from .. import options from ..combat_logic import (check_combat_reqs, area_data, get_money_count, calc_effective_hp, get_potion_level, - get_hp_level, get_def_level, get_sp_level) + get_hp_level, get_def_level, get_sp_level, has_combat_reqs) from ..items import item_table from .. import TunicWorld @@ -81,3 +81,39 @@ def test_combat_doesnt_fail_backwards(self): f"Free Def and Offerings: {player_def - def_offerings}, {def_offerings}\n" f"Free SP and Offerings: {player_sp - sp_offerings}, {sp_offerings}") prev_statuses[area] = curr_statuses[area] + + # the issue was that a direct check of the logic and the cache had different results + # it was actually due to the combat_items in items.py not having the Gun in it + # but this test is still helpful for verifying the cache + def test_combat_magic_weapons(self): + combat_items = self.combat_items.copy() + combat_items.remove("Magic Wand") + combat_items.remove("Gun") + area_names = list(area_data.keys()) + self.multiworld.worlds[1].random.shuffle(combat_items) + self.multiworld.worlds[1].random.shuffle(area_names) + current_items = Counter() + state = self.multiworld.state.copy() + player = self.player + gun = TunicWorld.create_item(self.world, "Gun") + + for current_item_name in combat_items: + current_item = TunicWorld.create_item(self.world, current_item_name) + state.collect(current_item) + current_items[current_item_name] += 1 + for area in area_names: + if check_combat_reqs(area, state, player) != has_combat_reqs(area, state, player): + raise Exception(f"Cache for {area} does not match a direct check " + f"after collecting {current_item_name}.\n" + f"Current items: {current_items}.\n" + f"Cache {'succeeded' if has_combat_reqs(area, state, player) else 'failed'}\n" + f"Direct {'succeeded' if check_combat_reqs(area, state, player) else 'failed'}") + state.collect(gun) + for area in area_names: + if check_combat_reqs(area, state, player) != has_combat_reqs(area, state, player): + raise Exception(f"Cache for {area} does not match a direct check " + f"after collecting the Gun.\n" + f"Current items: {current_items}.\n" + f"Cache {'succeeded' if has_combat_reqs(area, state, player) else 'failed'}\n" + f"Direct {'succeeded' if check_combat_reqs(area, state, player) else 'failed'}") + state.remove(gun) From d744e086efb23673326d791a01a748c0f7213597 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Mon, 17 Feb 2025 15:16:18 +0100 Subject: [PATCH 0149/1218] MultiServer: Fix hinting an item that someone else already hinted in their slot not resolving correctly (#4655) * Fix get_hint not checking for finding_player * Fix using the wrong variable for slot lookup --- MultiServer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 51b72c93ad3d..a310808b3aec 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -783,7 +783,7 @@ def notify_hints(self, team: int, hints: typing.List[Hint], only_new: bool = Fal def get_hint(self, team: int, finding_player: int, seeked_location: int) -> typing.Optional[Hint]: for hint in self.hints[team, finding_player]: - if hint.location == seeked_location: + if hint.location == seeked_location and hint.finding_player == finding_player: return hint return None @@ -1135,7 +1135,7 @@ def collect_hints(ctx: Context, team: int, slot: int, item: typing.Union[int, st seeked_item_id = item if isinstance(item, int) else ctx.item_names_for_game(ctx.games[slot])[item] for finding_player, location_id, item_id, receiving_player, item_flags \ in ctx.locations.find_item(slots, seeked_item_id): - prev_hint = ctx.get_hint(team, slot, location_id) + prev_hint = ctx.get_hint(team, finding_player, location_id) if prev_hint: hints.append(prev_hint) else: From 15bde565511e4d1e4eb4522df6cc938cf9e33ba0 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 17 Feb 2025 18:58:38 +0100 Subject: [PATCH 0150/1218] Factorio: prevent invalid starting items count (#4658) --- worlds/factorio/Options.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/worlds/factorio/Options.py b/worlds/factorio/Options.py index 4848cd992664..fe72d386507c 100644 --- a/worlds/factorio/Options.py +++ b/worlds/factorio/Options.py @@ -235,6 +235,12 @@ class FactorioStartItems(OptionDict): """Mapping of Factorio internal item-name to amount granted on start.""" display_name = "Starting Items" default = {"burner-mining-drill": 4, "stone-furnace": 4, "raw-fish": 50} + schema = Schema( + { + str: And(int, lambda n: n > 0, + error="amount of starting items has to be a positive integer"), + } + ) class FactorioFreeSampleBlacklist(OptionSet): From 91a8fc91d6636e15a8967b764928bd37bae5e656 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Wed, 19 Feb 2025 13:50:25 +0100 Subject: [PATCH 0151/1218] CI: fix native tests toolchain on windows (#4668) * CI: ctest: fix trigger on CMakeLists change * CI: ctest: update cmake version this removes a warning and matches gtest * CI: ctest: remove explicit build mode for MSVC gtest switched to dynamic libc (/MD), which is default, so this just works now --- .github/workflows/ctest.yml | 4 ++-- test/cpp/CMakeLists.txt | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ctest.yml b/.github/workflows/ctest.yml index 9492c83c9e53..a0ae2cb25206 100644 --- a/.github/workflows/ctest.yml +++ b/.github/workflows/ctest.yml @@ -11,7 +11,7 @@ on: - '**.hh?' - '**.hpp' - '**.hxx' - - '**.CMakeLists' + - '**/CMakeLists.txt' - '.github/workflows/ctest.yml' pull_request: paths: @@ -21,7 +21,7 @@ on: - '**.hh?' - '**.hpp' - '**.hxx' - - '**.CMakeLists' + - '**/CMakeLists.txt' - '.github/workflows/ctest.yml' jobs: diff --git a/test/cpp/CMakeLists.txt b/test/cpp/CMakeLists.txt index 927b7494dac4..03deb8f98224 100644 --- a/test/cpp/CMakeLists.txt +++ b/test/cpp/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.16) project(ap-cpp-tests) enable_testing() @@ -7,8 +7,8 @@ find_package(GTest REQUIRED) if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") add_definitions("/source-charset:utf-8") - set(CMAKE_CXX_FLAGS_DEBUG "/MTd") - set(CMAKE_CXX_FLAGS_RELEASE "/MT") + # set(CMAKE_CXX_FLAGS_DEBUG "/MDd") # this is the default + # set(CMAKE_CXX_FLAGS_RELEASE "/MD") # this is the default elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # enable static analysis for gcc add_compile_options(-fanalyzer -Werror) From 11fa43f0a49abcab762bc15613e1d74ce4d5869b Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Thu, 20 Feb 2025 00:17:19 +0100 Subject: [PATCH 0152/1218] Factorio: prevent players from getting stuck from Teleport Traps (#4537) --- worlds/factorio/Options.py | 3 +- worlds/factorio/data/mod/lib.lua | 67 +++++++++++++++++++ worlds/factorio/data/mod_template/control.lua | 13 ++-- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/worlds/factorio/Options.py b/worlds/factorio/Options.py index fe72d386507c..481ed00987f2 100644 --- a/worlds/factorio/Options.py +++ b/worlds/factorio/Options.py @@ -263,7 +263,8 @@ class AttackTrapCount(TrapCount): class TeleportTrapCount(TrapCount): - """Trap items that when received trigger a random teleport.""" + """Trap items that when received trigger a random teleport. + It is ensured the player can walk back to where they got teleported from.""" display_name = "Teleport Traps" diff --git a/worlds/factorio/data/mod/lib.lua b/worlds/factorio/data/mod/lib.lua index edec5b7acdc0..aa50b926f04f 100644 --- a/worlds/factorio/data/mod/lib.lua +++ b/worlds/factorio/data/mod/lib.lua @@ -49,6 +49,73 @@ function fire_entity_at_entities(entity_name, entities, speed) end end +local teleport_requests = {} +local teleport_attempts = {} +local max_attempts = 100 + +function attempt_teleport_player(player, attempt) + -- global attempt storage as metadata can't be stored + if attempt == nil then + attempt = teleport_attempts[player.index] + else + teleport_attempts[player.index] = attempt + end + + if attempt > max_attempts then + player.print("Teleport failed: No valid position found after " .. max_attempts .. " attempts!") + teleport_attempts[player.index] = 0 + return + end + + local surface = player.character.surface + local prototype_name = player.character.prototype.name + local original_position = player.character.position + local candidate_position = random_offset_position(original_position, 1024) + + local non_colliding_position = surface.find_non_colliding_position( + prototype_name, candidate_position, 0, 1 + ) + + if non_colliding_position then + -- Request pathfinding asynchronously + local path_id = surface.request_path{ + bounding_box = player.character.prototype.collision_box, + collision_mask = { layers = { ["player"] = true } }, + start = original_position, + goal = non_colliding_position, + force = player.force.name, + radius = 1, + pathfind_flags = {cache = true, low_priority = true, allow_paths_through_own_entities = true}, + } + + -- Store the request with the player index as the key + teleport_requests[player.index] = path_id + else + attempt_teleport_player(player, attempt + 1) + end +end + +function handle_teleport_attempt(event) + for player_index, path_id in pairs(teleport_requests) do + -- Check if the event matches the stored path_id + if path_id == event.id then + local player = game.players[player_index] + + if event.path then + if player.character then + player.character.teleport(event.path[#event.path].position) -- Teleport to the last point in the path + -- Clear the attempts for this player + teleport_attempts[player_index] = 0 + return + end + return + end + + attempt_teleport_player(player, nil) + break + end + end +end function spill_character_inventory(character) if not (character and character.valid) then return false diff --git a/worlds/factorio/data/mod_template/control.lua b/worlds/factorio/data/mod_template/control.lua index 07fd4c04afae..cd0c00e9877f 100644 --- a/worlds/factorio/data/mod_template/control.lua +++ b/worlds/factorio/data/mod_template/control.lua @@ -134,6 +134,9 @@ end script.on_event(defines.events.on_player_changed_position, on_player_changed_position) {% endif %} +-- Handle the pathfinding result of teleport traps +script.on_event(defines.events.on_script_path_request_finished, handle_teleport_attempt) + function count_energy_bridges() local count = 0 for i, bridge in pairs(storage.energy_link_bridges) do @@ -143,9 +146,11 @@ function count_energy_bridges() end return count end + function get_energy_increment(bridge) return ENERGY_INCREMENT + (ENERGY_INCREMENT * 0.3 * bridge.quality.level) end + function on_check_energy_link(event) --- assuming 1 MJ increment and 5MJ battery: --- first 2 MJ request fill, last 2 MJ push energy, middle 1 MJ does nothing @@ -722,12 +727,10 @@ end, game.forces["enemy"].set_evolution_factor(new_factor, "nauvis") game.print({"", "New evolution factor:", new_factor}) end, -["Teleport Trap"] = function () +["Teleport Trap"] = function() for _, player in ipairs(game.forces["player"].players) do - current_character = player.character - if current_character ~= nil then - current_character.teleport(current_character.surface.find_non_colliding_position( - current_character.prototype.name, random_offset_position(current_character.position, 1024), 0, 1)) + if player.character then + attempt_teleport_player(player, 1) end end end, From 18de035b4deec96a237a8dd49a739db3ac659039 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 22 Feb 2025 05:33:58 -0800 Subject: [PATCH 0153/1218] DS3: Update setup documentation (#4437) --- worlds/dark_souls_3/docs/setup_en.md | 68 +++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/docs/setup_en.md b/worlds/dark_souls_3/docs/setup_en.md index 484afdce3fcb..4c3a6b2a7d60 100644 --- a/worlds/dark_souls_3/docs/setup_en.md +++ b/worlds/dark_souls_3/docs/setup_en.md @@ -3,11 +3,13 @@ ## Required Software - [Dark Souls III](https://store.steampowered.com/app/374320/DARK_SOULS_III/) -- [Dark Souls III AP Client](https://github.com/nex3/Dark-Souls-III-Archipelago-client/releases/latest) +- [Dark Souls III AP Client] + +[Dark Souls III AP Client]: https://github.com/nex3/Dark-Souls-III-Archipelago-client/releases/latest ## Optional Software -- Map tracker not yet updated for 3.0.0 +- [Map tracker](https://github.com/TVV1GK/DS3_AP_Maptracker) ## Setting Up @@ -73,3 +75,65 @@ things to keep in mind: [.NET Runtime]: https://dotnet.microsoft.com/en-us/download/dotnet/8.0 [WINE]: https://www.winehq.org/ + +## Troubleshooting + +### Enemy randomizer issues + +The DS3 Archipelago randomizer uses [thefifthmatt's DS3 enemy randomizer], +essentially unchanged. Unfortunately, this randomizer has a few known issues, +including enemy AI not working, enemies spawning in places they can't be killed, +and, in a few rare cases, enemies spawning in ways that crash the game when they +load. These bugs should be [reported upstream], but unfortunately the +Archipelago devs can't help much with them. + +[thefifthmatt's DS3 enemy randomizer]: https://www.nexusmods.com/darksouls3/mods/484 +[reported upstream]: https://github.com/thefifthmatt/SoulsRandomizers/issues + +Because in rare cases the enemy randomizer can cause seeds to be impossible to +complete, we recommend disabling it for large async multiworlds for safety +purposes. + +### `launchmod_darksouls3.bat` isn't working + +Sometimes `launchmod_darksouls3.bat` will briefly flash a terminal on your +screen and then terminate without actually starting the game. This is usually +caused by some issue communicating with Steam either to find `DarkSoulsIII.exe` +or to launch it properly. If this is happening to you, make sure: + +* You have DS3 1.15.2 installed. This is the latest patch as of January 2025. + (Note that older versions of Archipelago required an older patch, but that + _will not work_ with the current version.) + +* You own the DS3 DLC if your randomizer config has DLC enabled. (It's possible, + but unconfirmed, that you need the DLC even when it's disabled in your config). + +* Steam is not running in administrator mode. To fix this, right-click + `steam.exe` (by default this is in `C:\Program Files\Steam`), select + "Properties", open the "Compatiblity" tab, and uncheck "Run this program as an + administrator". + +* There is no `dinput8.dll` file in your DS3 game directory. This is the old way + of installing mods, and it can interfere with the new ModEngine2 workflow. + +If you've checked all of these, you can also try: + +* Running `launchmod_darksouls3.bat` as an administrator. + +* Reinstalling DS3 or even reinstalling Steam itself. + +* Making sure DS3 is installed on the same drive as Steam and as the randomizer. + (A number of users are able to run these on different drives, but this has + helped some users.) + +If none of this works, unfortunately there's not much we can do. We use +ModEngine2 to launch DS3 with the Archipelago mod enabled, but unfortunately +it's no longer maintained and its successor, ModEngine3, isn't usable yet. + +### `DS3Randomizer.exe` isn't working + +This is almost always caused by using a version of the randomizer client that's +not compatible with the version used to generate the multiworld. If you're +generating your multiworld on archipelago.gg, you *must* use the latest [Dark +Souls III AP Client]. If you want to use a different client version, you *must* +generate the multiworld locally using the apworld bundled with the client. From 0f7fd48cddac9dc5d6da8347aca7ee27afc7bb8a Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sun, 23 Feb 2025 11:02:30 -0500 Subject: [PATCH 0154/1218] TUNIC: Add some more rules for Monastery connections (#4564) * Move a couple locations to monastery * Connect Quarry Back to Monastery * Quarry Back -> Monastery with laurels, Monastery -> Monastery Back with wand/sword * Add Monastery Back region * Move a couple non-ER locations to monastery back * Monastery front -> back with sword, wand, or laurels zip * also laurels zip for non-ER --- worlds/tunic/er_rules.py | 4 +++- worlds/tunic/locations.py | 8 ++++---- worlds/tunic/regions.py | 5 +++-- worlds/tunic/rules.py | 5 +++++ 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index f111fed8b13a..1d3ede21a41a 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -990,7 +990,9 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: rule=lambda state: has_ice_grapple_logic(True, IceGrappling.option_hard, state, world)) monastery_front_to_back = regions["Monastery Front"].connect( - connecting_region=regions["Monastery Back"]) + connecting_region=regions["Monastery Back"], + rule=lambda state: has_sword(state, player) or state.has(fire_wand, player) + or laurels_zip(state, world)) # laurels through the gate, no setup needed regions["Monastery Back"].connect( connecting_region=regions["Monastery Front"], diff --git a/worlds/tunic/locations.py b/worlds/tunic/locations.py index d0c4f860e47f..d3c23406ed38 100644 --- a/worlds/tunic/locations.py +++ b/worlds/tunic/locations.py @@ -206,7 +206,7 @@ class TunicLocationData(NamedTuple): "Fountain Cross Door - Page Pickup": TunicLocationData("Overworld Holy Cross", "Fountain Cross Room", location_group="Holy Cross"), "Secret Gathering Place - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Secret Gathering Place", location_group="Holy Cross"), "Top of the Mountain - Page At The Peak": TunicLocationData("Overworld Holy Cross", "Top of the Mountain", location_group="Holy Cross"), - "Monastery - Monastery Chest": TunicLocationData("Monastery", "Monastery Back"), + "Monastery - Monastery Chest": TunicLocationData("Monastery Back", "Monastery Back"), "Quarry - [Back Entrance] Bushes Holy Cross": TunicLocationData("Quarry Back", "Quarry Back", location_group="Holy Cross"), "Quarry - [Back Entrance] Chest": TunicLocationData("Quarry Back", "Quarry Back"), "Quarry - [Central] Near Shortcut Ladder": TunicLocationData("Quarry Back", "Quarry Back"), @@ -220,12 +220,12 @@ class TunicLocationData(NamedTuple): "Quarry - [Central] Obscured Below Entry Walkway": TunicLocationData("Quarry Back", "Quarry Back"), "Quarry - [Central] Top Floor Overhang": TunicLocationData("Quarry", "Quarry"), "Quarry - [East] Near Bridge": TunicLocationData("Quarry", "Quarry"), - "Quarry - [Central] Above Ladder": TunicLocationData("Quarry", "Quarry Monastery Entry"), + "Quarry - [Central] Above Ladder": TunicLocationData("Monastery", "Quarry Monastery Entry"), "Quarry - [Central] Obscured Behind Staircase": TunicLocationData("Quarry", "Quarry"), - "Quarry - [Central] Above Ladder Dash Chest": TunicLocationData("Quarry", "Quarry Monastery Entry"), + "Quarry - [Central] Above Ladder Dash Chest": TunicLocationData("Monastery", "Quarry Monastery Entry"), "Quarry - [West] Upper Area Bombable Wall": TunicLocationData("Quarry Back", "Quarry Back"), "Quarry - [East] Bombable Wall": TunicLocationData("Quarry", "Quarry"), - "Hero's Grave - Ash Relic": TunicLocationData("Monastery", "Hero Relic - Quarry"), + "Hero's Grave - Ash Relic": TunicLocationData("Monastery Back", "Hero Relic - Quarry"), "Quarry - [West] Shooting Range Secret Path": TunicLocationData("Lower Quarry", "Lower Quarry"), "Quarry - [West] Near Shooting Range": TunicLocationData("Lower Quarry", "Lower Quarry"), "Quarry - [West] Below Shooting Range": TunicLocationData("Lower Quarry", "Lower Quarry"), diff --git a/worlds/tunic/regions.py b/worlds/tunic/regions.py index 8f5df8896ac9..f21af11ee49d 100644 --- a/worlds/tunic/regions.py +++ b/worlds/tunic/regions.py @@ -13,9 +13,10 @@ "Library": tuple(), "Eastern Vault Fortress": ("Beneath the Vault",), "Beneath the Vault": ("Eastern Vault Fortress",), - "Quarry Back": ("Quarry",), + "Quarry Back": ("Quarry", "Monastery"), "Quarry": ("Monastery", "Lower Quarry"), - "Monastery": tuple(), + "Monastery": ("Monastery Back",), + "Monastery Back": tuple(), "Lower Quarry": ("Rooted Ziggurat",), "Rooted Ziggurat": tuple(), "Swamp": ("Cathedral",), diff --git a/worlds/tunic/rules.py b/worlds/tunic/rules.py index 959376787d0e..63f76ac92984 100644 --- a/worlds/tunic/rules.py +++ b/worlds/tunic/rules.py @@ -124,6 +124,11 @@ def set_region_rules(world: "TunicWorld") -> None: and (state.has_any({grapple, laurels, gun}, player) or can_ladder_storage(state, world)) world.get_entrance("Quarry Back -> Quarry").access_rule = \ lambda state: has_sword(state, player) or state.has(fire_wand, player) + world.get_entrance("Quarry Back -> Monastery").access_rule = \ + lambda state: state.has(laurels, player) + world.get_entrance("Monastery -> Monastery Back").access_rule = \ + lambda state: (has_sword(state, player) or state.has(fire_wand, player) + or laurels_zip(state, world)) world.get_entrance("Quarry -> Lower Quarry").access_rule = \ lambda state: has_mask(state, world) world.get_entrance("Lower Quarry -> Rooted Ziggurat").access_rule = \ From 58d460678e5e0e22995e3ce0b0fd93fa86db0c99 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Sun, 23 Feb 2025 11:11:24 -0500 Subject: [PATCH 0155/1218] LADX: drop rupee farm condition (#4189) * drop rupee farm condition * cleanup * rupee farm backup for all spending checks * not power bracelet * oops --- worlds/ladx/LADXR/logic/overworld.py | 12 ++++++------ worlds/ladx/LADXR/logic/requirements.py | 1 + worlds/ladx/Locations.py | 13 +------------ 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/worlds/ladx/LADXR/logic/overworld.py b/worlds/ladx/LADXR/logic/overworld.py index a85a97ae6451..b63aad2b340d 100644 --- a/worlds/ladx/LADXR/logic/overworld.py +++ b/worlds/ladx/LADXR/logic/overworld.py @@ -11,7 +11,7 @@ def __init__(self, options, world_setup, r): mabe_village = Location("Mabe Village") Location().add(HeartPiece(0x2A4)).connect(mabe_village, r.bush) # well - Location().add(FishingMinigame()).connect(mabe_village, AND(r.bush, COUNT("RUPEES", 20))) # fishing game, heart piece is directly done by the minigame. + Location().add(FishingMinigame()).connect(mabe_village, AND(r.can_farm, COUNT("RUPEES", 20))) # fishing game, heart piece is directly done by the minigame. Location().add(Seashell(0x0A3)).connect(mabe_village, r.bush) # bushes below the shop Location().add(Seashell(0x0D2)).connect(mabe_village, PEGASUS_BOOTS) # smash into tree next to lv1 Location().add(Song(0x092)).connect(mabe_village, OCARINA) # Marins song @@ -23,7 +23,7 @@ def __init__(self, options, world_setup, r): papahl_house.connect(mamasha_trade, TRADING_ITEM_YOSHI_DOLL) trendy_shop = Location("Trendy Shop") - trendy_shop.connect(Location().add(TradeSequenceItem(0x2A0, TRADING_ITEM_YOSHI_DOLL)), FOUND("RUPEES", 50)) + trendy_shop.connect(Location().add(TradeSequenceItem(0x2A0, TRADING_ITEM_YOSHI_DOLL)), AND(r.can_farm, FOUND("RUPEES", 50))) outside_trendy = Location() outside_trendy.connect(mabe_village, r.bush) @@ -43,8 +43,8 @@ def __init__(self, options, world_setup, r): self._addEntrance("start_house", mabe_village, start_house, None) shop = Location("Shop") - Location().add(ShopItem(0)).connect(shop, OR(COUNT("RUPEES", 500), SWORD)) - Location().add(ShopItem(1)).connect(shop, OR(COUNT("RUPEES", 1480), SWORD)) + Location().add(ShopItem(0)).connect(shop, OR(AND(r.can_farm, COUNT("RUPEES", 500)), SWORD)) + Location().add(ShopItem(1)).connect(shop, OR(AND(r.can_farm, COUNT("RUPEES", 1480)), SWORD)) self._addEntrance("shop", mabe_village, shop, None) dream_hut = Location("Dream Hut") @@ -164,7 +164,7 @@ def __init__(self, options, world_setup, r): self._addEntrance("prairie_left_cave2", ukuku_prairie, prairie_left_cave2, BOMB) self._addEntranceRequirementExit("prairie_left_cave2", None) # if exiting, you do not need bombs - mamu = Location().connect(Location().add(Song(0x2FB)), AND(OCARINA, COUNT("RUPEES", 1480))) + mamu = Location().connect(Location().add(Song(0x2FB)), AND(OCARINA, r.can_farm, COUNT("RUPEES", 1480))) self._addEntrance("mamu", ukuku_prairie, mamu, AND(OR(AND(FEATHER, PEGASUS_BOOTS), ROOSTER), OR(HOOKSHOT, ROOSTER), POWER_BRACELET)) dungeon3_entrance = Location().connect(ukuku_prairie, OR(FEATHER, ROOSTER, FLIPPERS)) @@ -377,7 +377,7 @@ def __init__(self, options, world_setup, r): # Raft game. raft_house = Location("Raft House") - Location().add(KeyLocation("RAFT")).connect(raft_house, AND(r.bush, COUNT("RUPEES", 100))) # add bush requirement for farming in case player has to try again + Location().add(KeyLocation("RAFT")).connect(raft_house, AND(r.can_farm, COUNT("RUPEES", 100))) raft_return_upper = Location() raft_return_lower = Location().connect(raft_return_upper, None, one_way=True) outside_raft_house = Location().connect(below_right_taltal, HOOKSHOT).connect(below_right_taltal, FLIPPERS, one_way=True) diff --git a/worlds/ladx/LADXR/logic/requirements.py b/worlds/ladx/LADXR/logic/requirements.py index 4e1fe03b096f..8d637ecfe99b 100644 --- a/worlds/ladx/LADXR/logic/requirements.py +++ b/worlds/ladx/LADXR/logic/requirements.py @@ -253,6 +253,7 @@ def isConsumable(item) -> bool: class RequirementsSettings: def __init__(self, options): + self.can_farm = OR(SWORD, MAGIC_POWDER, MAGIC_ROD, BOOMERANG, BOMB, HOOKSHOT, BOW) self.bush = OR(SWORD, MAGIC_POWDER, MAGIC_ROD, POWER_BRACELET, BOOMERANG, BOMB) self.pit_bush = OR(SWORD, MAGIC_POWDER, MAGIC_ROD, BOOMERANG, BOMB) # unique self.attack = OR(SWORD, BOMB, BOW, MAGIC_ROD, BOOMERANG) diff --git a/worlds/ladx/Locations.py b/worlds/ladx/Locations.py index 8670738e0869..45fa99adc56a 100644 --- a/worlds/ladx/Locations.py +++ b/worlds/ladx/Locations.py @@ -110,15 +110,6 @@ def filter_item(item): add_item_rule(self, filter_item) -def has_free_weapon(state: CollectionState, player: int) -> bool: - return state.has("Progressive Sword", player) or state.has("Magic Rod", player) or state.has("Boomerang", player) or state.has("Hookshot", player) - - -# If the player has access to farm enough rupees to afford a game, we assume that they can keep beating the game -def can_farm_rupees(state: CollectionState, player: int) -> bool: - return has_free_weapon(state, player) and (state.has("Can Play Trendy Game", player=player) or state.has("RAFT", player=player)) - - class LinksAwakeningRegion(Region): dungeon_index = None ladxr_region = None @@ -154,9 +145,7 @@ def __contains__(self, item): def get(self, item, default): # Don't allow any money usage if you can't get back wasted rupees if item == "RUPEES": - if can_farm_rupees(self.state, self.player): - return self.state.prog_items[self.player]["RUPEES"] - return 0 + return self.state.prog_items[self.player]["RUPEES"] elif item.endswith("_USED"): return 0 else: From 6dc461609b1df651e327050f279f8cdce38fe95b Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sun, 23 Feb 2025 11:27:05 -0500 Subject: [PATCH 0156/1218] Noita: Fix bug with Traps disabled in 1-player games #4651 --- worlds/noita/items.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/noita/items.py b/worlds/noita/items.py index 394bcdb5757f..20d9ff1930de 100644 --- a/worlds/noita/items.py +++ b/worlds/noita/items.py @@ -52,8 +52,8 @@ def create_kantele(victory_condition: VictoryCondition) -> List[str]: def create_random_items(world: NoitaWorld, weights: Dict[str, int], count: int) -> List[str]: filler_pool = weights.copy() if not world.options.bad_effects: - del filler_pool["Trap"] - del filler_pool["Greed Die"] + filler_pool["Trap"] = 0 + filler_pool["Greed Die"] = 0 return world.random.choices(population=list(filler_pool.keys()), weights=list(filler_pool.values()), From 69940374e13d27faae30c13fe6e6e0396b21000c Mon Sep 17 00:00:00 2001 From: BadMagic100 Date: Thu, 27 Feb 2025 08:12:35 -0800 Subject: [PATCH 0157/1218] Core: Only consider requested exits during ER placement and speculative sweep #4684 --- entrance_rando.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/entrance_rando.py b/entrance_rando.py index b6e64002bd38..67ca65672041 100644 --- a/entrance_rando.py +++ b/entrance_rando.py @@ -157,17 +157,16 @@ def __init__(self, world: World, coupled: bool): def placed_regions(self) -> set[Region]: return self.collection_state.reachable_regions[self.world.player] - def find_placeable_exits(self, check_validity: bool) -> list[Entrance]: + def find_placeable_exits(self, check_validity: bool, usable_exits: list[Entrance]) -> list[Entrance]: if check_validity: blocked_connections = self.collection_state.blocked_connections[self.world.player] - blocked_connections = sorted(blocked_connections, key=lambda x: x.name) - placeable_randomized_exits = [connection for connection in blocked_connections - if not connection.connected_region - and connection.is_valid_source_transition(self)] + placeable_randomized_exits = [ex for ex in usable_exits + if not ex.connected_region + and ex in blocked_connections + and ex.is_valid_source_transition(self)] else: # this is on a beaten minimal attempt, so any exit anywhere is fair game - placeable_randomized_exits = [ex for region in self.world.multiworld.get_regions(self.world.player) - for ex in region.exits if not ex.connected_region] + placeable_randomized_exits = [ex for ex in usable_exits if not ex.connected_region] self.world.random.shuffle(placeable_randomized_exits) return placeable_randomized_exits @@ -181,7 +180,8 @@ def _connect_one_way(self, source_exit: Entrance, target_entrance: Entrance) -> self.placements.append(source_exit) self.pairings.append((source_exit.name, target_entrance.name)) - def test_speculative_connection(self, source_exit: Entrance, target_entrance: Entrance) -> bool: + def test_speculative_connection(self, source_exit: Entrance, target_entrance: Entrance, + usable_exits: list[Entrance]) -> bool: copied_state = self.collection_state.copy() # simulated connection. A real connection is unsafe because the region graph is shallow-copied and would # propagate back to the real multiworld. @@ -198,6 +198,9 @@ def test_speculative_connection(self, source_exit: Entrance, target_entrance: En # ignore the source exit, and, if coupled, the reverse exit. They're not actually new if _exit.name == source_exit.name or (self.coupled and _exit.name == target_entrance.name): continue + # make sure we are only paying attention to usable exits + if _exit not in usable_exits: + continue # technically this should be is_valid_source_transition, but that may rely on side effects from # on_connect, which have not happened here (because we didn't do a real connection, and if we did, we would # not want them to persist). can_reach is a close enough approximation most of the time. @@ -339,7 +342,7 @@ def do_placement(source_exit: Entrance, target_entrance: Entrance) -> None: def find_pairing(dead_end: bool, require_new_exits: bool) -> bool: nonlocal perform_validity_check - placeable_exits = er_state.find_placeable_exits(perform_validity_check) + placeable_exits = er_state.find_placeable_exits(perform_validity_check, exits) for source_exit in placeable_exits: target_groups = target_group_lookup[source_exit.randomization_group] for target_entrance in entrance_lookup.get_targets(target_groups, dead_end, preserve_group_order): @@ -355,7 +358,7 @@ def find_pairing(dead_end: bool, require_new_exits: bool) -> bool: and len(placeable_exits) == 1) if exit_requirement_satisfied and source_exit.can_connect_to(target_entrance, dead_end, er_state): if (needs_speculative_sweep - and not er_state.test_speculative_connection(source_exit, target_entrance)): + and not er_state.test_speculative_connection(source_exit, target_entrance, exits)): continue do_placement(source_exit, target_entrance) return True From adc5f3a07d40341f6e50da932286075a3882ca0c Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Thu, 27 Feb 2025 10:13:37 -0600 Subject: [PATCH 0158/1218] MM2: Fix Shuffled Weaknesses Seed Bleed (#4689) --- worlds/mm2/rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/mm2/rules.py b/worlds/mm2/rules.py index 7e03edf3a23b..d84c13c827b2 100644 --- a/worlds/mm2/rules.py +++ b/worlds/mm2/rules.py @@ -92,7 +92,7 @@ def set_rules(world: "MM2World") -> None: world.wily_5_weapons = slot_data["wily_5_weapons"] else: if world.options.random_weakness == RandomWeaknesses.option_shuffled: - weapon_tables = [table for weapon, table in weapon_damage.items() if weapon not in (0, 8)] + weapon_tables = [table.copy() for weapon, table in weapon_damage.items() if weapon not in (0, 8)] world.random.shuffle(weapon_tables) for i in range(1, 8): world.weapon_damage[i] = weapon_tables.pop() From 026011323eb2a35bbeeed68428f9dcc6abf86c06 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 27 Feb 2025 10:42:41 -0600 Subject: [PATCH 0159/1218] The Messenger: Fix 0 Required Power Seals (#4692) --- worlds/messenger/__init__.py | 2 +- worlds/messenger/rules.py | 7 +++++-- worlds/messenger/test/test_shop_chest.py | 26 +++++++++++++++++++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/worlds/messenger/__init__.py b/worlds/messenger/__init__.py index 043be455bc1f..a6effc31d56d 100644 --- a/worlds/messenger/__init__.py +++ b/worlds/messenger/__init__.py @@ -228,7 +228,7 @@ def create_items(self) -> None: f"({self.options.total_seals}). Adjusting to {total_seals}" ) self.total_seals = total_seals - self.required_seals = int(self.options.percent_seals_required.value / 100 * self.total_seals) + self.required_seals = max(1, int(self.options.percent_seals_required.value / 100 * self.total_seals)) seals = [self.create_item("Power Seal") for _ in range(self.total_seals)] itempool += seals diff --git a/worlds/messenger/rules.py b/worlds/messenger/rules.py index f09025c7edce..2a3434266fab 100644 --- a/worlds/messenger/rules.py +++ b/worlds/messenger/rules.py @@ -26,7 +26,7 @@ def __init__(self, world: "MessengerWorld") -> None: maximum_price = (world.multiworld.get_location("The Shop - Demon's Bane", self.player).cost + world.multiworld.get_location("The Shop - Focused Power Sense", self.player).cost) self.maximum_price = min(maximum_price, world.total_shards) - self.required_seals = max(1, world.required_seals) + self.required_seals = world.required_seals # dict of connection names and requirements to traverse the exit self.connection_rules = { @@ -34,7 +34,7 @@ def __init__(self, world: "MessengerWorld") -> None: "Artificer's Portal": lambda state: state.has_all({"Demon King Crown", "Magic Firefly"}, self.player), "Shrink Down": - lambda state: state.has_all(NOTES, self.player) or self.has_enough_seals(state), + lambda state: state.has_all(NOTES, self.player), # the shop "Money Sink": lambda state: state.has("Money Wrench", self.player) and self.can_shop(state), @@ -314,6 +314,9 @@ def __init__(self, world: "MessengerWorld") -> None: self.has_dart, } + if self.required_seals: + self.connection_rules["Shrink Down"] = self.has_enough_seals + def has_wingsuit(self, state: CollectionState) -> bool: return state.has("Wingsuit", self.player) diff --git a/worlds/messenger/test/test_shop_chest.py b/worlds/messenger/test/test_shop_chest.py index 2ac306972614..cd65424bc873 100644 --- a/worlds/messenger/test/test_shop_chest.py +++ b/worlds/messenger/test/test_shop_chest.py @@ -1,4 +1,4 @@ -from BaseClasses import ItemClassification, CollectionState +from BaseClasses import CollectionState, ItemClassification from . import MessengerTestBase @@ -10,8 +10,9 @@ class AllSealsRequired(MessengerTestBase): def test_chest_access(self) -> None: """Defaults to a total of 45 power seals in the pool and required.""" with self.subTest("Access Dependency"): - self.assertEqual(len([seal for seal in self.multiworld.itempool if seal.name == "Power Seal"]), - self.world.options.total_seals) + self.assertEqual( + len([seal for seal in self.multiworld.itempool if seal.name == "Power Seal"]), + self.world.options.total_seals) locations = ["Rescue Phantom"] items = [["Power Seal"]] self.assertAccessDependency(locations, items) @@ -93,3 +94,22 @@ def test_seals_amount(self) -> None: if seal.classification == ItemClassification.progression_skip_balancing] self.assertEqual(len(total_seals), 85) self.assertEqual(len(required_seals), 85) + + +class NoSealsRequired(MessengerTestBase): + options = { + "goal": "power_seal_hunt", + "total_seals": 1, + "percent_seals_required": 10, # percentage + } + + def test_seals_amount(self) -> None: + """Should be 1 seal and it should be progression.""" + self.assertEqual(self.world.options.total_seals, 1) + self.assertEqual(self.world.total_seals, 1) + self.assertEqual(self.world.required_seals, 1) + total_seals = [item for item in self.multiworld.itempool if item.name == "Power Seal"] + required_seals = [item for item in self.multiworld.itempool if + item.advancement and item.name == "Power Seal"] + self.assertEqual(len(total_seals), 1) + self.assertEqual(len(required_seals), 1) From cd761db17035254559306f835c80f91c11e3b7af Mon Sep 17 00:00:00 2001 From: BadMagic100 Date: Thu, 27 Feb 2025 10:21:48 -0800 Subject: [PATCH 0160/1218] Core: Do GER speculative sweep membership checks against a set #4698 --- entrance_rando.py | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/entrance_rando.py b/entrance_rando.py index 67ca65672041..2cfebe74ad36 100644 --- a/entrance_rando.py +++ b/entrance_rando.py @@ -181,7 +181,7 @@ def _connect_one_way(self, source_exit: Entrance, target_entrance: Entrance) -> self.pairings.append((source_exit.name, target_entrance.name)) def test_speculative_connection(self, source_exit: Entrance, target_entrance: Entrance, - usable_exits: list[Entrance]) -> bool: + usable_exits: set[Entrance]) -> bool: copied_state = self.collection_state.copy() # simulated connection. A real connection is unsafe because the region graph is shallow-copied and would # propagate back to the real multiworld. @@ -329,6 +329,24 @@ def randomize_entrances( # similar to fill, skip validity checks on entrances if the game is beatable on minimal accessibility perform_validity_check = True + if not er_targets: + er_targets = sorted([entrance for region in world.multiworld.get_regions(world.player) + for entrance in region.entrances if not entrance.parent_region], key=lambda x: x.name) + if not exits: + exits = sorted([ex for region in world.multiworld.get_regions(world.player) + for ex in region.exits if not ex.connected_region], key=lambda x: x.name) + if len(er_targets) != len(exits): + raise EntranceRandomizationError(f"Unable to randomize entrances due to a mismatched count of " + f"entrances ({len(er_targets)}) and exits ({len(exits)}.") + + # used when membership checks are needed on the exit list, e.g. speculative sweep + exits_set = set(exits) + for entrance in er_targets: + entrance_lookup.add(entrance) + + # place the menu region and connected start region(s) + er_state.collection_state.update_reachable_regions(world.player) + def do_placement(source_exit: Entrance, target_entrance: Entrance) -> None: placed_exits, removed_entrances = er_state.connect(source_exit, target_entrance) # remove the placed targets from consideration @@ -358,7 +376,7 @@ def find_pairing(dead_end: bool, require_new_exits: bool) -> bool: and len(placeable_exits) == 1) if exit_requirement_satisfied and source_exit.can_connect_to(target_entrance, dead_end, er_state): if (needs_speculative_sweep - and not er_state.test_speculative_connection(source_exit, target_entrance, exits)): + and not er_state.test_speculative_connection(source_exit, target_entrance, exits_set)): continue do_placement(source_exit, target_entrance) return True @@ -410,21 +428,6 @@ def find_pairing(dead_end: bool, require_new_exits: bool) -> bool: f"All unplaced entrances: {unplaced_entrances}\n" f"All unplaced exits: {unplaced_exits}") - if not er_targets: - er_targets = sorted([entrance for region in world.multiworld.get_regions(world.player) - for entrance in region.entrances if not entrance.parent_region], key=lambda x: x.name) - if not exits: - exits = sorted([ex for region in world.multiworld.get_regions(world.player) - for ex in region.exits if not ex.connected_region], key=lambda x: x.name) - if len(er_targets) != len(exits): - raise EntranceRandomizationError(f"Unable to randomize entrances due to a mismatched count of " - f"entrances ({len(er_targets)}) and exits ({len(exits)}.") - for entrance in er_targets: - entrance_lookup.add(entrance) - - # place the menu region and connected start region(s) - er_state.collection_state.update_reachable_regions(world.player) - # stage 1 - try to place all the non-dead-end entrances while entrance_lookup.others: if not find_pairing(dead_end=False, require_new_exits=True): From 91d977479d3bd736a4b79cb7608ac1066cf00e5c Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 5 Mar 2025 23:48:03 +0100 Subject: [PATCH 0161/1218] Tests: test that collect and remove have expected behaviour. (#2062) --------- Co-authored-by: qwint Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- test/general/test_items.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/general/test_items.py b/test/general/test_items.py index 91d334e9687a..f9488e1b250b 100644 --- a/test/general/test_items.py +++ b/test/general/test_items.py @@ -1,5 +1,6 @@ import unittest +from BaseClasses import CollectionState from worlds.AutoWorld import AutoWorldRegister, call_all from . import setup_solo_multiworld @@ -8,12 +9,31 @@ class TestBase(unittest.TestCase): def test_create_item(self): """Test that a world can successfully create all items in its datapackage""" for game_name, world_type in AutoWorldRegister.world_types.items(): - proxy_world = setup_solo_multiworld(world_type, ()).worlds[1] + multiworld = setup_solo_multiworld(world_type, steps=("generate_early", "create_regions", "create_items")) + proxy_world = multiworld.worlds[1] for item_name in world_type.item_name_to_id: + test_state = CollectionState(multiworld) with self.subTest("Create Item", item_name=item_name, game_name=game_name): item = proxy_world.create_item(item_name) + + with self.subTest("Item Name", item_name=item_name, game_name=game_name): self.assertEqual(item.name, item_name) + if item.advancement: + with self.subTest("Item State Collect", item_name=item_name, game_name=game_name): + test_state.collect(item, True) + + with self.subTest("Item State Remove", item_name=item_name, game_name=game_name): + test_state.remove(item) + + self.assertEqual(test_state.prog_items, multiworld.state.prog_items, + "Item Collect -> Remove should restore empty state.") + else: + with self.subTest("Item State Collect No Change", item_name=item_name, game_name=game_name): + # Non-Advancement should not modify state. + test_state.collect(item) + self.assertEqual(test_state.prog_items, multiworld.state.prog_items) + def test_item_name_group_has_valid_item(self): """Test that all item name groups contain valid items. """ # This cannot test for Event names that you may have declared for logic, only sendable Items. From 0eb6150e953189f60cc0fdd41de19a0e4748b139 Mon Sep 17 00:00:00 2001 From: Silent <110704408+silent-destroyer@users.noreply.github.com> Date: Wed, 5 Mar 2025 18:17:27 -0500 Subject: [PATCH 0162/1218] TUNIC: Fix rule for some grass in West Garden (#4682) --- worlds/tunic/grass.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/worlds/tunic/grass.py b/worlds/tunic/grass.py index eb688199dcef..971ac4c0fe98 100644 --- a/worlds/tunic/grass.py +++ b/worlds/tunic/grass.py @@ -7938,6 +7938,18 @@ def set_grass_location_rules(world: "TunicWorld") -> None: add_rule(world.get_location("West Garden - West Garden Grass (174) (-243.9, 0.5, 52.1)"), lambda state: state.has("Hero's Laurels", player)) add_rule(world.get_location("West Garden - West Garden Grass (262) (-244.8, 0.5, 51.3)"), lambda state: state.has("Hero's Laurels", player)) add_rule(world.get_location("West Garden - West Garden Grass (263) (-244.8, 0.5, 52.3)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (269) (-162.5, 2.0, 75.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (267) (-161.3, 2.0, 75.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (268) (-161.3, 2.0, 74.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (299) (-172.1, 2.0, 81.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (404) (-172.1, 2.0, 80.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (402) (-172.1, 2.0, 82.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (403) (-173.4, 2.0, 81.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (401) (-173.4, 2.0, 82.5)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (261) (-182.8, 2.0, 75.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (259) (-183.8, 2.0, 75.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (260) (-183.8, 2.0, 74.0)"), lambda state: state.has("Hero's Laurels", player)) + add_rule(world.get_location("West Garden - West Garden Laurels Exit Grass (258) (-184.8, 2.0, 75.0)"), lambda state: state.has("Hero's Laurels", player)) add_rule(world.get_location("Swamp - Back of Swamp Laurels Area Grass swamp (991) (34.5, 8.3, 31.8)"), lambda state: state.has("Hero's Laurels", player)) add_rule(world.get_location("Swamp - Back of Swamp Laurels Area Grass swamp (992) (34.5, 8.0, 30.8)"), lambda state: state.has("Hero's Laurels", player)) add_rule(world.get_location("Swamp - Back of Swamp Laurels Area Grass swamp (989) (35.5, 8.0, 30.8)"), lambda state: state.has("Hero's Laurels", player)) From e00467c2a299623f630d5a3e68f35bc56ccaa8aa Mon Sep 17 00:00:00 2001 From: Silent <110704408+silent-destroyer@users.noreply.github.com> Date: Wed, 5 Mar 2025 18:18:27 -0500 Subject: [PATCH 0163/1218] TUNIC: Update logic for chest in fortress dark area (#4691) * Update logic for beneath the vault chest * use helper method instead so that it checks the lanternless option --- worlds/tunic/er_rules.py | 8 ++------ worlds/tunic/rules.py | 3 ++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index 1d3ede21a41a..fe01337c643b 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -1697,7 +1697,8 @@ def set_er_location_rules(world: "TunicWorld") -> None: # Beneath the Vault set_rule(world.get_location("Beneath the Fortress - Bridge"), - lambda state: has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player)) + lambda state: has_lantern(state, world) and + (has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player))) # Quarry set_rule(world.get_location("Quarry - [Central] Above Ladder Dash Chest"), @@ -1877,11 +1878,6 @@ def combat_logic_to_loc(loc_name: str, combat_req_area: str, set_instead: bool = combat_logic_to_loc("West Garden - [Central Highlands] Holy Cross (Blue Lines)", "West Garden") combat_logic_to_loc("West Garden - [Central Highlands] Behind Guard Captain", "West Garden") - # with combat logic on, I presume the player will want to be able to see to avoid the spiders - set_rule(world.get_location("Beneath the Fortress - Bridge"), - lambda state: has_lantern(state, world) - and (state.has_any({laurels, fire_wand, "Gun"}, player) or has_melee(state, player))) - combat_logic_to_loc("Eastern Vault Fortress - [West Wing] Candles Holy Cross", "Eastern Vault Fortress", dagger=True) diff --git a/worlds/tunic/rules.py b/worlds/tunic/rules.py index 63f76ac92984..b58ad73072bc 100644 --- a/worlds/tunic/rules.py +++ b/worlds/tunic/rules.py @@ -328,7 +328,8 @@ def set_location_rules(world: "TunicWorld") -> None: # Beneath the Vault set_rule(world.get_location("Beneath the Fortress - Bridge"), - lambda state: has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player)) + lambda state: has_lantern(state, world) and + (has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player))) set_rule(world.get_location("Beneath the Fortress - Obscured Behind Waterfall"), lambda state: has_melee(state, player) and has_lantern(state, world)) From c8b7ef10160820a77326aa4fc03d6bf353d26eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Fri, 7 Mar 2025 18:14:10 -0500 Subject: [PATCH 0164/1218] Stardew Valley: Fix a logic bug where the Tea Sapling would be considered available without having the recipe (#4703) --- worlds/stardew_valley/content/vanilla/base.py | 3 ++- worlds/stardew_valley/logic/logic.py | 2 -- worlds/stardew_valley/strings/fruit_tree_names.py | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/worlds/stardew_valley/content/vanilla/base.py b/worlds/stardew_valley/content/vanilla/base.py index 9e5f53eb866e..2215215c395b 100644 --- a/worlds/stardew_valley/content/vanilla/base.py +++ b/worlds/stardew_valley/content/vanilla/base.py @@ -150,7 +150,8 @@ def finalize_hook(self, content: StardewContent): Seed.coffee_starter: (CustomRuleSource(lambda logic: logic.traveling_merchant.has_days(3) & logic.monster.can_kill_many(Monster.dust_sprite)),), Seed.coffee: (HarvestCropSource(seed=Seed.coffee_starter, seasons=(Season.spring, Season.summer,)),), - Vegetable.tea_leaves: (CustomRuleSource(lambda logic: logic.has(Sapling.tea) & logic.time.has_lived_months(2) & logic.season.has_any_not_winter()),), + Vegetable.tea_leaves: ( + CustomRuleSource(lambda logic: logic.has(WildSeeds.tea_sapling) & logic.time.has_lived_months(2) & logic.season.has_any_not_winter()),), }, artisan_good_sources={ Beverage.beer: (MachineSource(item=Vegetable.wheat, machine=Machine.keg),), diff --git a/worlds/stardew_valley/logic/logic.py b/worlds/stardew_valley/logic/logic.py index 6efc1ade4980..34f609c0e26c 100644 --- a/worlds/stardew_valley/logic/logic.py +++ b/worlds/stardew_valley/logic/logic.py @@ -67,7 +67,6 @@ from ..strings.flower_names import Flower from ..strings.food_names import Meal, Beverage from ..strings.forageable_names import Forageable -from ..strings.fruit_tree_names import Sapling from ..strings.generic_names import Generic from ..strings.geode_names import Geode from ..strings.gift_names import Gift @@ -300,7 +299,6 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC Ore.radioactive: self.ability.can_mine_perfectly() & self.region.can_reach(Region.qi_walnut_room), RetainingSoil.basic: self.money.can_spend_at(Region.pierre_store, 100), RetainingSoil.quality: self.time.has_year_two & self.money.can_spend_at(Region.pierre_store, 150), - Sapling.tea: self.relationship.has_hearts(NPC.caroline, 2) & self.has(Material.fiber) & self.has(Material.wood), SpeedGro.basic: self.money.can_spend_at(Region.pierre_store, 100), SpeedGro.deluxe: self.time.has_year_two & self.money.can_spend_at(Region.pierre_store, 150), Trash.broken_cd: self.skill.can_crab_pot, diff --git a/worlds/stardew_valley/strings/fruit_tree_names.py b/worlds/stardew_valley/strings/fruit_tree_names.py index bd49dc57302a..fce34205f793 100644 --- a/worlds/stardew_valley/strings/fruit_tree_names.py +++ b/worlds/stardew_valley/strings/fruit_tree_names.py @@ -7,4 +7,3 @@ class Sapling: pomegranate = "Pomegranate Sapling" banana = "Banana Sapling" mango = "Mango Sapling" - tea = "Tea Sapling" From bb9a6bcd2e82b8827659c63b6e2f1d49d4bffe4d Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Fri, 7 Mar 2025 19:19:51 -0500 Subject: [PATCH 0165/1218] LADX: more marin joke text (#3966) * marin text * Adds lots of Marin Flavour Text (#32) * Updates of Splash text 24-09-18 * Re-Adds ' * use pkgutil * Adds all community suggestions up until 20/09/2024 (#33) * Adds all community suggestions up until 20/09/2024 * cutting deathlink jokes --------- Co-authored-by: Alex Nordstrom * drop piracy-adjacent jokes * marin text was too long * more submissions * no longer looking for new maintainer --------- Co-authored-by: palex00 <32203971+palex00@users.noreply.github.com> --- worlds/ladx/LADXR/patches/aesthetics.py | 22 +- worlds/ladx/LADXR/patches/marin.txt | 465 ++++++++++++++++++++++++ 2 files changed, 469 insertions(+), 18 deletions(-) create mode 100644 worlds/ladx/LADXR/patches/marin.txt diff --git a/worlds/ladx/LADXR/patches/aesthetics.py b/worlds/ladx/LADXR/patches/aesthetics.py index 2975c804d472..6ca7d3d973fd 100644 --- a/worlds/ladx/LADXR/patches/aesthetics.py +++ b/worlds/ladx/LADXR/patches/aesthetics.py @@ -4,6 +4,7 @@ from .. import entityData import os import bsdiff4 +import pkgutil def imageTo2bpp(filename): import PIL.Image @@ -179,24 +180,9 @@ def noText(rom): def reduceMessageLengths(rom, rnd): # Into text from Marin. Got to go fast, so less text. (This intro text is very long) - rom.texts[0x01] = formatText(rnd.choice([ - "Let's a go!", - "Remember, sword goes on A!", - "Avoid the heart piece of shame!", - "Marin? No, this is Zelda. Welcome to Hyrule", - "Why are you in my bed?", - "This is not a Mario game!", - "MuffinJets was here...", - "Remember, there are no bugs in LADX", - "#####, #####, you got to wake up!\nDinner is ready.", - "Go find the stepladder", - "Pizza power!", - "Eastmost penninsula is the secret", - "There is no cow level", - "You cannot lift rocks with your bear hands", - "Thank you, daid!", - "There, there now. Just relax. You've been asleep for almost nine hours now." - ])) + lines = pkgutil.get_data(__name__, "marin.txt").decode("unicode_escape").splitlines() + lines = [l for l in lines if l.strip()] + rom.texts[0x01] = formatText(rnd.choice(lines).strip()) # Reduce length of a bunch of common texts rom.texts[0xEA] = formatText("You've got a Guardian Acorn!") diff --git a/worlds/ladx/LADXR/patches/marin.txt b/worlds/ladx/LADXR/patches/marin.txt new file mode 100644 index 000000000000..3634014afe23 --- /dev/null +++ b/worlds/ladx/LADXR/patches/marin.txt @@ -0,0 +1,465 @@ +Let's a go! +Remember, sword goes on A! +Remember, sword goes on B! +It's pronounced Hydrocity Zone. +Avoid the heart piece of shame! +Marin? No, this is Zelda. Welcome to Hyrule +Why are you in my bed? +This is not a Mario game! +Wait, I thought Daid was French! +Is it spicefather or spaceotter? +kbranch finally took a break! +Baby seed ahead. +Abandon all hope ye who enter here... +Link... Open your eyes...\nWait, you're #####? +Remember, there are no bugs in LADX. +#####, #####, you got to wake up!\nDinner is ready. +Go find the stepladder. +Pizza power! +Eastmost peninsula is the secret. +There is no cow level. +You cannot lift rocks with your bear hands. +Don't worry, the doghouse was patched. +The carpet whale isn't real, it can't hurt you. +Isn't this a demake of Phantom Hourglass? +Go try the LAS rando! +Go try the Oracles rando! +Go try Archipelago! +Go try touching grass! +Please leave my house. +Trust me, this will be a 2 hour seed, max. +This is still better than doing Dampe dungeons. +They say that Marin can be found here. +Stalfos are such boneheads. +90 percent bug-free! +404 Marin.personality not found. +Idk man, works on my machine. +Hey guys, did you know that Vaporeon +Trans rights! +Support gay rights!\nAnd their lefts! +Snake? Snake?! SNAAAAKE!!! +Oh, you chose THESE settings? +As seen on TV! +May contain nuts. +Limited edition! +May contain RNG. +Reticulating splines! +Keyboard compatible! +Teetsuuuuoooo! +Kaaneeeedaaaa! +Learn about allyship! +This Marin text left intentionally blank. +'Autological' is! +Technoblade never dies! +Thank you, CrystalSaver! +Wait, LADX has a rando? +Wait, how many Pokemon are there now? +GOOD EMU +Good luck finding the feather. +Good luck finding the bracelets. +Good luck finding the boots. +Good luck finding your swords. +Good luck finding the flippers. +Good luck finding the rooster. +Good luck finding the hookshot. +Good luck finding the magic rod. +It's not a fire rod.\nIt's a magic rod, it shoots magic. +You should check the Seashell Mansion. +Mt. Tamaranch +WIND FISH IN NAME ONLY, FOR IT IS NEITHER. +Stuck? Try Magpie! +Ribbit! Ribbit! I'm Marin, on vocals! +Try this rando at ladxr.daid.eu! +He turned himself into a carpet whale! +Which came first, the whale or the egg? +Glan - Known Death and Taxes appreciator. +Pokemon number 591. +Would you? +Sprinkle the desert skulls. +Please don't curse in my Christian LADXR seed. +... ... ... \n... ...smash. +How was bedwetting practice? +The Oracles decomp project is going well! +#####, how do I download RAM? +Is this a delayed April Fool's Joke? +Play as if your footage will go in a\nSummoning Salt video. +I hope you prepared for our date later. +Isn't this the game where you date a seagull? +You look pretty good for a guy who probably drowned. +Remember, we race on Sundays. +This randomizer was made possible by players like you. \n \n Thank you! +Now with real fake doors! +Now with real fake floors! +You could be doing something productive right now. +No eggs were harmed in the making of this game. +I'm helping the goat, \ncatfishing Mr. Write is kinda the goal. +There are actually two LADX randomizers. +You're not gonna cheat... \n ...right? +Mamu's singing is so bad it wakes the dead. +Don't forget the Richard picture. +Are you sure you wanna do this? I kinda like this island. +SJ, BT, WW, OoB, HIJKLMNOP. +5 dollars in the swear jar. Now. +#####, I promise this seed will be better than the last one. +Want your name here? Contribute to LADXR! +Kappa +HEY! \n \n LANGUAGE! +I sell seashells on the seashore. +Hey! Are you even listening to me? +Your stay will total 10,000 rupees. I hope you have good insurance. +I have like the biggest crush on you. Will you get the hints now? +Daid watches Matty for ideas. \nBlame her if things go wrong. +'All of you are to blame.' -Daid +Batman Contingency Plan: Link. Step 1: Disguise yourself as a maiden to attract the young hero. +I have flooded Koholint with a deadly neurotoxin. +Ahh, General #####. +Finally, Link's Awakening! +Is the Wind Fish dreaming that he's sleeping in an egg? Or is he dreaming that he's you? +Save Koholint. By destroying it. Huh? Don't ask me, I'm just a kid! +There aren't enough women in this village to sustain a civilization. +So does this game take place before or after Oracles? +Have you tried the critically acclaimed MMORPG FINAL FANTASY XIV that has a free trial up to level 60 including the Heavensward expansion? +The thumbs-up sign had been used by the Galactic Federation for ages. Me, I was known for giving the thumbs-down during briefing. I had my reasons, though... Commander Adam Malkovich was normally cool and not one to joke around, but he would end all of his mission briefings by saying, 'Any objections, Lady?' +Hot hippos are near your location! +#####, get up! It's my turn in the bed! Tarin's smells too much... +Have you ever had a dream\nthat\nyo wa-\nyo had\nyo\nthat\nthat you could do anything? +Next time, try a salad. +seagull noises +I'm telling you, YOU HAVE UNO, it came free with your Xbox! +I'm telling you, YOU HAVE TRENDY, it came free with your Mabe! +LADXR - Now with even more Marin quotes! +You guys are spending more time adding Marin quotes than actually playing the game. +NASA faked the moon. +Doh, I missed! +Beginning the seed in... 100\n99\n98\n97\n96\n...\nJust Kidding. +Consider libre software! +Consider a GNU/Linux installation! +Now you're gonna tell me about how you need to get some instruments or maybe shells to hatch a whale out of an egg, right? All you boys are the same... +Oh hey #####! I made pancakes! +Oh hey #####! I made breakfast! +Alright Tarin, test subject number 142857 was a failure, give him the item and the memory drug and we'll try next time. +Betcha 100 rupees that Tarin gives you a sword. +Betcha 100 rupees that Tarin gives you the feather. +Betcha 100 rupees that Tarin gives you a bracelet. +Betcha 100 rupees that Tarin gives you the boots. +Betcha 100 rupees that Tarin gives you the hookshot. +Betcha 100 rupees that Tarin gives you the rod. +You'd think that Madam MeowMeow would be a cat person. +Look at you, with them dry lips. +You are now manually breathing. Hope that doesn't throw you off for this race. +Lemme get a number nine, a number nine large, a number six, with extra dip... +Tarin, the red-nosed deadbeat \nHad a mushroom addiction! +I'm using tilt controls! +SPLASH! \n \n \n ...Wait, you meant something else by 'splash text'? +CRACKLE-FWOOSH! +'Logic' is a strong word. +They say that the go-to way for fixing things is just to add another one of me. +gl hf +Have you considered multi-classing as a THIEF? +Don't call me Shirley +WHY are you buying CLOTHES at the SOUP STORE? +Believe it or not, this won't be the last time Link gets stranded on an island. +Is this the real life? Or is this just fantasy? +To the owner of the white sedan, your lights are on. +Now remade, in beautiful SD 2D! +Animal Village in my seed \nMarin and rabbits, loop de loop. +You seem totally entranced in Marin's appearance. +House hippoes are very timid creatures and are rarely seen, but they will defend their territory if provoked. +New goal! Close this seed, open the LADXR source code, and find the typo. +All your base are belong to us +Really? Another seed? +This seed brought to you by: the corners in the D2 boss room. +Hey, THIEF! Oh wait, you haven't done anything wrong... yet. +Hello World +With these hands, I give you life! +I heard we're a subcommunity of FFR now. +Try the Final Fantasy Randomizer! +How soon should we start calling you THIEF? +... Why do you keep doing this to yourself? +YOUR AD HERE +Did Matty give you this seed? Yeesh, good luck. +Yoooo I looked ahead into the spoiler log for this one...\n...\n...\n...good luck. +Lemme check the spoiler log...\nOkay, cool, only the normal amount of stupid. +Oh, you're alive. Dang. Guess I won't be needing THIS anymore. +Now you're gonna go talk to my dad. Gosh, boys are so predictable. +Shoot, I WAS going to steal your kidneys while you were asleep. Guess I'll have to find a moment when you don't expect me. +You caught me, mid-suavamente! +You'll be the bedwetting champion in no time. +Link, stop doing that, this is the fifth time this week I've had to change the sheets! +You mind napping in Not My Bed next time? +Why do they call it oven when you of in the cold food of out hot eat the food? +Marin sayings will never be generated by AI. Our community really is just that unfunny. +skibidi toilet\n...\nYes, that joke WILL age well +WHO DARES AWAKEN ME FROM MY THOUSAND-YEAR SLUMBER +The wind... it is... blowing... +Have I ever told you how much I hate sand? +explosion.gif +It is pronounced LADXR, not LADXR. +Stop pronouncing it lah-decks. +Someone once suggested to add all the nag messages all at once for me. +Accidentally playing Song 2? In front of the egg? It's more likely than you think. +Ladies and gentlemen? We got him. +Ladies and gentlemen? We got her. +Ladies and gentlemen? We got 'em. +What a wake up! I thought you'd never Marin! You were feeling a bit woozy and Zelda... What? Koholint? No, my name's relief! You must still be tossing. You are on turning Island! +...Zelda? Oh Marin is it? My apologies, thank you for saving me. So I'm on Koholint Island? Wait, where's my sword and shield?! +Koholint? More like kOWOlint. +What? The Wind Fish will grant my wish literally? I forsee nothing wrong happening with this. +Hey Marin! You woke me up from a fine nap! ... Thanks a lot! But now, I'll get my revenge! Are you ready?! +Why bother coming up with a funny quote? You're just gonna mash through it anyway. +something something whale something something dream something something adventure. +Some people won't be able to see this message! +If you're playing Archipelago and see this message, say hi to zig for me! +I think it may be time to stop playing LADXR seeds. +Rings do nothing unless worn! +Thank you Link, but our Instruments are in another Dungeon. +Are you sure you loaded the right seed? +Is this even randomized? +This seed brought to you by... Corners! +To this day I still don't know if we inconvenienced the Mad Batter or not. +Oh, hi ##### +People forgot I was playable in Hyrule Warriors +Join our Discord. Or else. +Also try Minecraft! +I see you're finally awake... +OwO +This is Todd Howard, and today I'm pleased to announce... The Elder Scrolls V: Skyrim for the Nintendo Game Boy Color! +Hey dummy! Need a hint? The power bracelet is... !! Whoops! There I go, talking too much again. +Thank you for visiting Toronbo Shores featuring Mabe Village. Don't forget your complimentary gift on the way out. +They say that sand can be found in Yarna Desert. +I got to see a previously unreleased cut yesterday. It only cost me 200 rupees. What a deal! +Just let him sleep +LADXR is going to be renamed X now. +Did you hear this chart-topping song yet? It's called Manbo's Mambo, it's so catchy! OH! +YOU DARE BRING LIGHT INTO MY LAIR?!?! You must DIE! +But enough talk! Have at you! +Please input your age for optimal meme-text delivery. +So the bear is just calling the walrus fat beecause he's projecting, right? +Please help, #####! The Nightmare has shuffled all the items around! +One does not simply Wake the Wind Fish. +Nothing unusual here, just a completely normal LADX game, Mister Nintendo. +Remember:\n1) Play Vanilla\n2) Play Solo Rando\n3) Play Multi +Is :) a good item? +What version do we have anyway? 0.6.9? +So, what &newgames are coming in the next AP version? +Is !remaining fixed yet? +Remember the APocalypse. Never forget the rooms we lost that day. +Have you heard of Berserker's Multiworld? +MILF. Man I love Fangames. +How big can the Big Async be anyway? A hundred worlds? +Have you heard of the After Dark server? +Try Adventure! +Try Aquaria! +Try Blasphemous! +Try Bomb Rush Cyberfunk! +Try Bumper Stickers! +Try Castlevania 64! +Try Celeste 64! +Try ChecksFinder! +Try Clique! +Try Dark Souls III! +Try DLCQuest! +Try Donkey Kong Country 3! +Try DOOM 1993! +Try DOOM II! +Try Factorio! +Try Final Fantasy! +Try Final Fantasy Mystic Quest! +Try A Hat in Time! +Try Heretic! +Try Hollow Knight! +Try Hylics 2! +Try Kingdom Hearts 2! +Try Kirby's Dream Land 3! +Try Landstalker - The Treasures of King Nole! +Try The Legend of Zelda! +Try Lingo! +Try A Link to the Past! +Try Links Awakening DX! +Try Lufia II Ancient Cave! +Try Mario & Luigi Superstar Saga! +Try MegaMan Battle Network 3! +Try Meritous! +Try The Messenger! +Try Minecraft! +Try Muse Dash! +Try Noita! +Try Ocarina of Time! +Try Overcooked! 2! +Try Pokemon Emerald! +Try Pokemon Red and Blue! +Try Raft! +Try Risk of Rain 2! +Try Rogue Legacy! +Try Secret of Evermore! +Try Shivers! +Try A Short Hike! +Try Slay the Spire! +Try SMZ3! +Try Sonic Adventure 2 Battle! +Try Starcraft 2! +Try Stardew Valley! +Try Subnautica! +Try Sudoku! +Try Super Mario 64! +Try Super Mario World! +Try Super Metroid! +Try Terraria! +Try Timespinner! +Try TUNIC! +Try Undertale! +Try VVVVVV! +Try Wargroove! +Try The Witness! +Try Yoshi's Island! +Try Yu-Gi-Oh! 2006! +Try Zillion! +Try Zork Grand Inquisitor! +Try Old School Runescape! +Try Kingdom Hearts! +Try Mega Man 2! +Try Yacht Dice! +VVVVVVVVVVVVVV this should be enough V right? +If you see this message, please open a #bug-report about it\n\n\nDon't actually though. +This YAML is going in the bucket, isn't it? +Oh, this is a terrible seed for a Sync +Oh, this is a terrible seed for an Async +What does BK stand for anyway? +Check out the #future-game-design forum +This is actually a Free trial of the critically acclaimed MMORPG Final Fantasy XIV, including the entirety of A Realm Reborn and the award winning Heavensward and Stormblood expansions up to level 70 with no restrictions on playtime! +Is it April yet? Can I play ArchipIDLE again? +https://archipelago.gg/datapackage +Hello, Link! (Disregard message if your player sprite is not Link.) +Go back to sleep, Outer Wilds isn't supported yet. +:)\nWelcome back! +Don't forget about Aginah! +Remind your Undertale player not to warp before Mad Dummy. +You need\n9 instruments\nor maybe not. I wouldn't know. +Try !\n\nIt makes the game easier. +Have you tried The Witness? If you're a fan of games about waking up on an unfamiliar island, give it a shot! +Have you tried turning it off and on again? +Its about time. Now go and check +This dream is a lie. Or is it a cake? +Don't live your dream. Dream your live. +Only 5 more minutes. zzzZ +Tell me, for whom do you fight?\nHmmph. How very glib. And do you believe in Koholint? +I wonder when Undertale will be merged?\nOh wait it already has. +Hit me up if you get stuck -\nwe could go to Burger King together. +Post this message to delay Silksong. +Sorry #####, but your princess is in another castle! +You've been met with a terrible fate, haven't you? +Hey!\nListen!\nHey! Hey!\nListen! +I bet there's a progression item at the 980 Rupee shop check. +Lamp oil? Rope? Bombs? You want it? It's yours, my friend. As long as you have enough rubies. +One day I happened to be occupied with the subject of generation of waves by wind. +(nuzzles you) uwu +why do they call it links awakening when links awake and IN links asleep OUT the wind fish +For many years I have been looking, searching for, but never finding, the builder of this house... +What the heck is a Quatro? +Have you tried The Binding of Isaac yet? +Have you played Pong? \n I hear it's still popular nowadays. +Five Nights at Freddy's... \n That's where I wanna be +Setting Coinsanity to -1... +Your Feather can be found at Mask-Shard_Grey_Mourner +Your Sword can be found in Ganon's Tower +Your Rooster can be found in HylemXylem +Your Bracelet can be found at Giant Floor Puzzle +Your Flippers can be found in Valley of Bowser +Your Magic Rod can be found in Victory Road +Your Hookshot can be found in Bowser in the Sky +Have they added Among Us to AP yet? +Every copy of LADX is personalized, David. +Looks like you're going on A Short Hike. Bring back feathers please? +Functioning Brain is at...\nWait. This isn't Witness. Wrong game, sorry. +Don't forget to check your Clique!\nIf, y'know, you have one. No pressure... +:3 +Sorry ######, but your progression item is in another world. +&newgames\n&oldgames +Do arrows come with turners? I'm stuck in my Bumper Stickers world. +This seed has dexsanity enabled. Don't get stuck in Dewford! +Please purchase the Dialogue Pack for DLC Quest: Link's Adventure to read the rest of this text. +No hints here. Maybe ask BK Sudoku for some? +KILNS (Yellow Middle, 5) \n REVELATION (White Low, 9) +Push the button! When someone lets you... +You won't believe the WEIRD thing Tarin found at the beach! Go on, ask him about it! +When's door randomizer getting added to AP? +Can you get my Morph Ball? +Shoutouts to Simpleflips +Remember, Sword goes on C!\n...you have a C button, right? +Ask Berserker for your Progressive Power Bracelets! +I will be taking your Burger King order now to save you some time when you inevitably need it. +Welcome to KOHOLINT ISLAND.\nNo, we do not have a BURGER KING. +Welcome to Burger King, may I take your order? +Rise and shine, #####. Rise and shine. +Well, this is\nLITTLEROOT TOWN.\nHow do you like it? +My boy, this peace is what all true warriors strive for! +#####, you can do it!\nSave the Princess...\nZelda is your... ... ... +Dear Mario:\nPlease come to the castle, I've baked a cake for you. Yours truly--\nPrincess Toadstool\nPeach +Grass-sanity mode activated. Have fun! +Don't forget to bring rupees to the signpost maze this time. +UP UP DOWN DOWN LEFT RIGHT LEFT RIGHT B A START +Try LADX!\nWait a minute... +ERROR! Unable to verify player. Please drink a verification can. +We have been trying to reach you about your raft's extended warranty +Are you ready for the easiest BK of your life? +Hello, welcome to the world of Pokemon!\nMy name is Marin, and I'm-- +Alright, this is very important, I need you to listen to what I'm about to tell you--\nHey, wait, where are you going?! +Cheques?\nSorry we don't accept cheques here +Hi! \nMarin. \nWho...? \nHow...? \nWait... \nWhy??? \nSorry... \n...\nThanks. \nBye! +AHHH WHY IS THERE SO MUCH GRASS? \nHOLY SH*T GRASS SNAKE AHHHH +Could you buy some strawberries on your way home? \nHuh it's out of logic??? What?? +I heard you sleeptalking about skeletons and genocide... Your past must have been full of misery (mire) +It's time to let go... \nIt wasn't your fault... \nYou couldn't have known your first check was going to be hardmode... +They say that your progression is in another castle... +A minute of silence for the failed generations due to the Fitness Gram Pacer test. +Save an Ice Trap for me, please? +maren +ERROR DETECTED IN YAML\nOHKO MODE FORCED ON +she awaken my link (extremely loud incorrect buzzer) +Is deathlink on? If so, be careful! +Sorry, but you're about to be BK'd. +Did you set up cheesetracker yet? +I've got a hint I need you to get... +You aren't planning to destroy this island and kill everyone on it are you? +Have you ever had a dream, that, that you um you had you'd you would you could you'd do you wi you wants you you could do so you you'd do you could you you want you want him to do you so much you could do anything? +R R R U L L U L U R U R D R D R U U +I'm not sure how, but I am pretty sure this is Phar's fault. +Oh, look at that. Link's Awakened.\nYou did it, you beat the game. +Excellent armaments, #####. Please return - \nCOVERED IN BLOOD -\n...safe and sound. +Pray return to the Link's Awakening Sands. +This Marin dialogue was inspired by The Witness's audiologs. +You're awake!\n....\nYou were warned.\nI'm now going to say every word beginning with Z!\nZA\nZABAGLIONE\nZABAGLIONES\nZABAIONE\nZABAIONES\nZABAJONE\nZABAJONES\nZABETA\nZABETAS\nZABRA\nZABRAS\nZABTIEH\nZABTIEHS\nZACATON\nZACATONS\nZACK\nZACKS\nZADDICK\nZADDIK\nZADDIKIM\nZADDIKS\nZAFFAR\nzAFFARS\nZAFFER\nZAFFERS\nZAFFIR\n....\n....\n....\nI'll let you off easy.\nThis time. +Leave me alone, I'm Marinating. +praise be to the tungsten cube +If you play multiple seeds in a row, you can pretend that each run is the dream you awaken from in the next. +If this is a competitive race,\n\nyour time has already started. +If anything goes wrong, remember.\n Blame Phar. +Better hope your Hookshot didn't land on the Sick Kid. +One time, I accidentally said Konoliht instead of Koholint... +Sometimes, you must become best girl yourself... +You just woke up! My name's #####!\nYou must be Marin, right? +I just had the strangest dream, I was a seagull!\nI sung many songs for everybody to hear!\nHave you ever had a strange dream before? +If you think about it, Koholint sounds suspiciously similar to Coherent... +All I kin remember is biting into a juicy toadstool. Then I had the strangest dream... I was a Marin! Yeah, it sounds strange, but it sure was fun! +Prepare for a 100% run! +Prediction: 1 hour +Prediction: 4 hours +Prediction: 6 hours +Prediction: 12 hours +Prediction: Impossible seed +Oak's parcel has arrived. +Don't forget to like and subscribe! +Don't BK, eat healthy! +No omega symbols broke this seed gen? Good! +#####...\nYou're lucky.\nLooks like my summer vacation is...\nover. +Are you ready to send nukes to someone's Factorio game? +You're late... Is this a Cmario game? +At least you don't have to fight Ganon... What? +PRAISE THE SUN! +I'd recommend more sleep before heading out there. +You Must Construct Additional Pylons +#####, you lazy bum. I knew that I'd find you snoozing down here. +This is it, #####.\nJust breathe.\nWhy are you so nervous? +Hey, you. You're finally awake.\nYou were trying to cross the border, huh? +Hey, you. You're finally awake.\nYou were trying to leave the island, huh?\nSwam straight into that whirlpool, same as us, and that thief over there. +Is my Triforce locked behind your Wind Fish? From 2f0b81e12c67b5a5d8d2d0643a71dc7cf88d1e32 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Fri, 7 Mar 2025 19:24:58 -0500 Subject: [PATCH 0166/1218] LADX: tarins gift improvement (#3970) * add groups and a preset * formatting * pull zig's tarin's gift improvements * typing * alias groups for progressive items * change tarins gift option a bit * add bush breakers item group * fix typo * bush_breaker option, respect non_local_items * review suggestions * cleaner thx exempt * Update worlds/ladx/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * fix gen failures for dungeon shuffle * exclude shovel based on entrance mapping --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/ladx/LADXR/locations/startItem.py | 11 --- worlds/ladx/Options.py | 16 +++++ worlds/ladx/__init__.py | 88 ++++++++++++++++-------- 3 files changed, 77 insertions(+), 38 deletions(-) diff --git a/worlds/ladx/LADXR/locations/startItem.py b/worlds/ladx/LADXR/locations/startItem.py index 0421c1d6d865..6cd9651671ac 100644 --- a/worlds/ladx/LADXR/locations/startItem.py +++ b/worlds/ladx/LADXR/locations/startItem.py @@ -7,23 +7,12 @@ class StartItem(DroppedKey): - # We need to give something here that we can use to progress. - # FEATHER - OPTIONS = [SWORD, SHIELD, POWER_BRACELET, OCARINA, BOOMERANG, MAGIC_ROD, TAIL_KEY, SHOVEL, HOOKSHOT, PEGASUS_BOOTS, MAGIC_POWDER, BOMB] MULTIWORLD = False def __init__(self): super().__init__(0x2A3) self.give_bowwow = False - def configure(self, options): - if options.bowwow != 'normal': - # When we have bowwow mode, we pretend to be a sword for logic reasons - self.OPTIONS = [SWORD] - self.give_bowwow = True - if options.randomstartlocation and options.entranceshuffle != 'none': - self.OPTIONS.append(FLIPPERS) - def patch(self, rom, option, *, multiworld=None): assert multiworld is None diff --git a/worlds/ladx/Options.py b/worlds/ladx/Options.py index a35bb870fd91..7ea7df36597c 100644 --- a/worlds/ladx/Options.py +++ b/worlds/ladx/Options.py @@ -527,6 +527,20 @@ class InGameHints(DefaultOnToggle): display_name = "In-game Hints" +class TarinsGift(Choice): + """ + [Local Progression] Forces Tarin's gift to be an item that immediately opens up local checks. + Has little effect in single player games, and isn't always necessary with randomized entrances. + [Bush Breaker] Forces Tarin's gift to be an item that can destroy bushes. + [Any Item] Tarin's gift can be any item for any world + """ + display_name = "Tarin's Gift" + option_local_progression = 0 + option_bush_breaker = 1 + option_any_item = 2 + default = option_local_progression + + class StabilizeItemPool(DefaultOffToggle): """ By default, rupees in the item pool may be randomly swapped with bombs, arrows, powders, or capacity upgrades. This option disables that swapping, which is useful for plando. @@ -565,6 +579,7 @@ class ForeignItemIcons(Choice): OptionGroup("Miscellaneous", [ TradeQuest, Rooster, + TarinsGift, Overworld, TrendyGame, InGameHints, @@ -638,6 +653,7 @@ class LinksAwakeningOptions(PerGameCommonOptions): text_mode: TextMode no_flash: NoFlash in_game_hints: InGameHints + tarins_gift: TarinsGift overworld: Overworld stabilize_item_pool: StabilizeItemPool diff --git a/worlds/ladx/__init__.py b/worlds/ladx/__init__.py index a887638e377a..4c22693c8fe9 100644 --- a/worlds/ladx/__init__.py +++ b/worlds/ladx/__init__.py @@ -4,6 +4,7 @@ import pkgutil import tempfile import typing +import logging import re import bsdiff4 @@ -178,10 +179,10 @@ def create_regions(self) -> None: assert(start) - menu_region = LinksAwakeningRegion("Menu", None, "Menu", self.player, self.multiworld) + menu_region = LinksAwakeningRegion("Menu", None, "Menu", self.player, self.multiworld) menu_region.exits = [Entrance(self.player, "Start Game", menu_region)] menu_region.exits[0].connect(start) - + self.multiworld.regions.append(menu_region) # Place RAFT, other access events @@ -189,14 +190,14 @@ def create_regions(self) -> None: for loc in region.locations: if loc.address is None: loc.place_locked_item(self.create_event(loc.ladxr_item.event)) - + # Connect Windfish -> Victory windfish = self.multiworld.get_region("Windfish", self.player) l = Location(self.player, "Windfish", parent=windfish) windfish.locations = [l] - + l.place_locked_item(self.create_event("An Alarm Clock")) - + self.multiworld.completion_condition[self.player] = lambda state: state.has("An Alarm Clock", player=self.player) def create_item(self, item_name: str): @@ -206,6 +207,8 @@ def create_event(self, event: str): return Item(event, ItemClassification.progression, None, self.player) def create_items(self) -> None: + itempool = [] + exclude = [item.name for item in self.multiworld.precollected_items[self.player]] self.prefill_original_dungeon = [ [], [], [], [], [], [], [], [], [] ] @@ -265,9 +268,9 @@ def create_items(self) -> None: self.prefill_own_dungeons.append(item) self.pre_fill_items.append(item) else: - self.multiworld.itempool.append(item) + itempool.append(item) else: - self.multiworld.itempool.append(item) + itempool.append(item) self.multi_key = self.generate_multi_key() @@ -276,8 +279,8 @@ def create_items(self) -> None: event_location = Location(self.player, "Can Play Trendy Game", parent=trendy_region) trendy_region.locations.insert(0, event_location) event_location.place_locked_item(self.create_event("Can Play Trendy Game")) - - self.dungeon_locations_by_dungeon = [[], [], [], [], [], [], [], [], []] + + self.dungeon_locations_by_dungeon = [[], [], [], [], [], [], [], [], []] for r in self.multiworld.get_regions(self.player): # Set aside dungeon locations if r.dungeon_index: @@ -290,21 +293,52 @@ def create_items(self) -> None: # Properly fill locations within dungeon location.dungeon = r.dungeon_index - # For now, special case first item - FORCE_START_ITEM = True - if FORCE_START_ITEM: - self.force_start_item() + if self.options.tarins_gift != "any_item": + self.force_start_item(itempool) + + + self.multiworld.itempool += itempool - def force_start_item(self): + def force_start_item(self, itempool): start_loc = self.multiworld.get_location("Tarin's Gift (Mabe Village)", self.player) if not start_loc.item: - possible_start_items = [index for index, item in enumerate(self.multiworld.itempool) - if item.player == self.player - and item.item_data.ladxr_id in start_loc.ladxr_item.OPTIONS and not item.location] - if possible_start_items: - index = self.random.choice(possible_start_items) - start_item = self.multiworld.itempool.pop(index) + """ + Find an item that forces progression or a bush breaker for the player, depending on settings. + """ + def is_possible_start_item(item): + return item.advancement and item.name not in self.options.non_local_items + + def opens_new_regions(item): + collection_state = base_collection_state.copy() + collection_state.collect(item) + return len(collection_state.reachable_regions[self.player]) > reachable_count + + start_items = [item for item in itempool if is_possible_start_item(item)] + self.random.shuffle(start_items) + + if self.options.tarins_gift == "bush_breaker": + start_item = next((item for item in start_items if item.name in links_awakening_item_name_groups["Bush Breakers"]), None) + + else: # local_progression + entrance_mapping = self.ladxr_logic.world_setup.entrance_mapping + # Tail key opens a region but not a location if d1 entrance is not mapped to d1 or d4 + # exclude it in these cases to avoid fill errors + if entrance_mapping['d1'] not in ['d1', 'd4']: + start_items = [item for item in start_items if item.name != 'Tail Key'] + # Exclude shovel unless starting in Mabe Village + if entrance_mapping['start_house'] not in ['start_house', 'shop']: + start_items = [item for item in start_items if item.name != 'Shovel'] + base_collection_state = CollectionState(self.multiworld) + base_collection_state.update_reachable_regions(self.player) + reachable_count = len(base_collection_state.reachable_regions[self.player]) + start_item = next((item for item in start_items if opens_new_regions(item)), None) + + if start_item: + itempool.remove(start_item) start_loc.place_locked_item(start_item) + else: + logging.getLogger("Link's Awakening Logger").warning(f"No {self.options.tarins_gift.current_option_name} available for Tarin's Gift.") + def get_pre_fill_items(self): return self.pre_fill_items @@ -317,7 +351,7 @@ def pre_fill(self) -> None: # set containing the list of all possible dungeon locations for the player all_dungeon_locs = set() - + # Do dungeon specific things for dungeon_index in range(0, 9): # set up allow-list for dungeon specific items @@ -330,7 +364,7 @@ def pre_fill(self) -> None: # ...also set the rules for the dungeon for location in locs: orig_rule = location.item_rule - # If an item is about to be placed on a dungeon location, it can go there iff + # If an item is about to be placed on a dungeon location, it can go there iff # 1. it fits the general rules for that location (probably 'return True' for most places) # 2. Either # 2a. it's not a restricted dungeon item @@ -382,7 +416,7 @@ def priority(item): # Sweep to pick up already placed items that are reachable with everything but the dungeon items. partial_all_state.sweep_for_advancements() - + fill_restrictive(self.multiworld, partial_all_state, all_dungeon_locs_to_fill, all_dungeon_items_to_fill, lock=True, single_player_placement=True, allow_partial=False) @@ -421,7 +455,7 @@ def guess_icon_for_other_world(self, foreign_item): for name in possibles: if name in self.name_cache: return self.name_cache[name] - + return "TRADING_ITEM_LETTER" @classmethod @@ -436,7 +470,7 @@ def generate_output(self, output_directory: str): for loc in r.locations: if isinstance(loc, LinksAwakeningLocation): assert(loc.item) - + # If we're a links awakening item, just use the item if isinstance(loc.item, LinksAwakeningItem): loc.ladxr_item.item = loc.item.item_data.ladxr_id @@ -470,7 +504,7 @@ def generate_output(self, output_directory: str): args = parser.parse_args([rom_name, "-o", out_name, "--dump"]) rom = generator.generateRom(args, self) - + with open(out_path, "wb") as handle: rom.save(handle, name="LADXR") @@ -478,7 +512,7 @@ def generate_output(self, output_directory: str): if self.options.ap_title_screen: with tempfile.NamedTemporaryFile(delete=False) as title_patch: title_patch.write(pkgutil.get_data(__name__, "LADXR/patches/title_screen.bdiff4")) - + bsdiff4.file_patch_inplace(out_path, title_patch.name) os.unlink(title_patch.name) From bc61221ec60ab1b3b31ef5d3b412a70f9d4f3c85 Mon Sep 17 00:00:00 2001 From: Silent <110704408+silent-destroyer@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:43:02 -0500 Subject: [PATCH 0167/1218] TUNIC: Expanded hexagon quest options (#4076) * More hex quest updates - Implement page ability shuffle for hex quest - Fix keys behind bosses if hex goal is less than 3 - Added check to fix conflicting hex quest options - Add option to slot data * Change option comparison * Change option checking and fix some stuff - also keep prayer first on low hex counts * Update option defaulting * Update option checking * Fix option assignment again * Show player name in option warning * Add new option to universal tracker stuff * Update __init__.py * Make helper method for getting total hexagons in itempool * Update options.py * Update option value passthrough * Change ability shuffle to default on * Check for hexagons option when writing spoiler --- worlds/tunic/__init__.py | 44 +++++++++++++++++++--------- worlds/tunic/options.py | 63 ++++++++++++++++++++++++++++++++++++---- worlds/tunic/rules.py | 21 +++++++++----- 3 files changed, 103 insertions(+), 25 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index e86f731381e5..2ee58d42d1bc 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -11,7 +11,8 @@ from .grass import grass_location_table, grass_location_name_to_id, grass_location_name_groups, excluded_grass_locations from .er_data import portal_mapping, RegionInfo, tunic_er_regions from .options import (TunicOptions, EntranceRando, tunic_option_groups, tunic_option_presets, TunicPlandoConnections, - LaurelsLocation, LogicRules, LaurelsZips, IceGrappling, LadderStorage) + LaurelsLocation, LogicRules, LaurelsZips, IceGrappling, LadderStorage, check_options, + get_hexagons_in_pool, HexagonQuestAbilityUnlockType) from .combat_logic import area_data, CombatState from worlds.AutoWorld import WebWorld, World from Options import PlandoConnection, OptionError @@ -109,6 +110,8 @@ class TunicWorld(World): ut_can_gen_without_yaml = True # class var that tells it to ignore the player yaml def generate_early(self) -> None: + check_options(self) + if self.options.logic_rules >= LogicRules.option_no_major_glitches: self.options.laurels_zips.value = LaurelsZips.option_true self.options.ice_grappling.value = IceGrappling.option_medium @@ -144,6 +147,7 @@ def generate_early(self) -> None: self.options.lanternless.value = self.passthrough["lanternless"] self.options.maskless.value = self.passthrough["maskless"] self.options.hexagon_quest.value = self.passthrough["hexagon_quest"] + self.options.hexagon_quest_ability_type.value = self.passthrough.get("hexagon_quest_ability_type", 0) self.options.entrance_rando.value = self.passthrough["entrance_rando"] self.options.shuffle_ladders.value = self.passthrough["shuffle_ladders"] self.options.grass_randomizer.value = self.passthrough.get("grass_randomizer", 0) @@ -261,6 +265,10 @@ def create_items(self) -> None: items_to_create: Dict[str, int] = {item: data.quantity_in_item_pool for item, data in item_table.items()} + # Calculate number of hexagons in item pool + if self.options.hexagon_quest: + items_to_create[gold_hexagon] = get_hexagons_in_pool(self) + for money_fool in fool_tiers[self.options.fool_traps]: items_to_create["Fool Trap"] += items_to_create[money_fool] items_to_create[money_fool] = 0 @@ -291,11 +299,21 @@ def create_items(self) -> None: items_to_create["Grass"] -= len(excluded_grass_locations) if self.options.keys_behind_bosses: - for rgb_hexagon, location in hexagon_locations.items(): - hex_item = self.create_item(gold_hexagon if self.options.hexagon_quest else rgb_hexagon) - self.get_location(location).place_locked_item(hex_item) - items_to_create[rgb_hexagon] = 0 - items_to_create[gold_hexagon] -= 3 + rgb_hexagons = list(hexagon_locations.keys()) + # shuffle these in case not all are placed in hex quest + self.random.shuffle(rgb_hexagons) + for rgb_hexagon in rgb_hexagons: + location = hexagon_locations[rgb_hexagon] + if self.options.hexagon_quest: + if items_to_create[gold_hexagon] > 0: + hex_item = self.create_item(gold_hexagon) + items_to_create[gold_hexagon] -= 1 + items_to_create[rgb_hexagon] = 0 + self.get_location(location).place_locked_item(hex_item) + else: + hex_item = self.create_item(rgb_hexagon) + self.get_location(location).place_locked_item(hex_item) + items_to_create[rgb_hexagon] = 0 # Filler items in the item pool available_filler: List[str] = [filler for filler in items_to_create if items_to_create[filler] > 0 and @@ -323,13 +341,11 @@ def remove_filler(amount: int) -> None: remove_filler(ladder_count) if self.options.hexagon_quest: - # Calculate number of hexagons in item pool - hexagon_goal = self.options.hexagon_goal - extra_hexagons = self.options.extra_hexagon_percentage - items_to_create[gold_hexagon] += int((Decimal(100 + extra_hexagons) / 100 * hexagon_goal).to_integral_value(rounding=ROUND_HALF_UP)) - # Replace pages and normal hexagons with filler for replaced_item in list(filter(lambda item: "Pages" in item or item in hexagon_locations, items_to_create)): + if replaced_item in item_name_groups["Abilities"] and self.options.ability_shuffling \ + and self.options.hexagon_quest_ability_type == "pages": + continue filler_name = self.get_filler_item_name() items_to_create[filler_name] += items_to_create[replaced_item] if items_to_create[filler_name] >= 1 and filler_name not in available_filler: @@ -441,7 +457,7 @@ def stage_pre_fill(cls, multiworld: MultiWorld) -> None: def create_regions(self) -> None: self.tunic_portal_pairs = {} self.er_portal_hints = {} - self.ability_unlocks = randomize_ability_unlocks(self.random, self.options) + self.ability_unlocks = randomize_ability_unlocks(self) # stuff for universal tracker support, can be ignored for standard gen if self.using_ut: @@ -504,7 +520,8 @@ def remove(self, state: CollectionState, item: Item) -> bool: return change def write_spoiler_header(self, spoiler_handle: TextIO): - if self.options.hexagon_quest and self.options.ability_shuffling: + if self.options.hexagon_quest and self.options.ability_shuffling\ + and self.options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: spoiler_handle.write("\nAbility Unlocks (Hexagon Quest):\n") for ability in self.ability_unlocks: # Remove parentheses for better readability @@ -567,6 +584,7 @@ def fill_slot_data(self) -> Dict[str, Any]: "sword_progression": self.options.sword_progression.value, "ability_shuffling": self.options.ability_shuffling.value, "hexagon_quest": self.options.hexagon_quest.value, + "hexagon_quest_ability_type": self.options.hexagon_quest_ability_type.value, "fool_traps": self.options.fool_traps.value, "laurels_zips": self.options.laurels_zips.value, "ice_grappling": self.options.ice_grappling.value, diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index d2ea82803704..3ace28cffafa 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -1,8 +1,14 @@ +import logging from dataclasses import dataclass -from typing import Dict, Any +from typing import Dict, Any, TYPE_CHECKING + +from decimal import Decimal, ROUND_HALF_UP + from Options import (DefaultOnToggle, Toggle, StartInventoryPool, Choice, Range, TextChoice, PlandoConnections, PerGameCommonOptions, OptionGroup, Visibility, NamedRange) from .er_data import portal_mapping +if TYPE_CHECKING: + from . import TunicWorld class SwordProgression(DefaultOnToggle): @@ -24,6 +30,7 @@ class StartWithSword(Toggle): class KeysBehindBosses(Toggle): """ Places the three hexagon keys behind their respective boss fight in your world. + If playing Hexagon Quest, it will place three gold hexagons at the boss locations. """ internal_name = "keys_behind_bosses" display_name = "Keys Behind Bosses" @@ -32,7 +39,8 @@ class KeysBehindBosses(Toggle): class AbilityShuffling(DefaultOnToggle): """ Locks the usage of Prayer, Holy Cross*, and the Icebolt combo until the relevant pages of the manual have been found. - If playing Hexagon Quest, abilities are instead randomly unlocked after obtaining 25%, 50%, and 75% of the required Hexagon goal amount. + If playing Hexagon Quest, abilities are instead randomly unlocked after obtaining 25%, 50%, and 75% of the required + Hexagon goal amount, unless the option is set to have them unlock via pages instead. * Certain Holy Cross usages are still allowed, such as the free bomb codes, the seeking spell, and other player-facing codes. """ internal_name = "ability_shuffling" @@ -84,14 +92,16 @@ class HexagonGoal(Range): """ internal_name = "hexagon_goal" display_name = "Gold Hexagons Required" - range_start = 15 - range_end = 50 + range_start = 1 + range_end = 100 default = 20 class ExtraHexagonPercentage(Range): """ How many extra Gold Questagons are shuffled into the item pool, taken as a percentage of the goal amount. + The max number of Gold Questagons that can be in the item pool is 100, so this option may be overridden and/or + reduced if the Hexagon Goal amount is greater than 50. """ internal_name = "extra_hexagon_percentage" display_name = "Percentage of Extra Gold Hexagons" @@ -100,11 +110,27 @@ class ExtraHexagonPercentage(Range): default = 50 +class HexagonQuestAbilityUnlockType(Choice): + """ + Determines how abilities are unlocked when playing Hexagon Quest with Shuffled Abilities enabled. + + Hexagons: A new ability is randomly unlocked after obtaining 25%, 50%, and 75% of the required Hexagon goal amount. Requires at least 3 Gold Hexagons in the item pool, or 15 if Keys Behind Bosses is enabled. + Pages: Abilities are unlocked by finding specific pages in the manual. + + This option does nothing if Shuffled Abilities is not enabled. + """ + internal_name = "hexagon_quest_ability_type" + display_name = "Hexagon Quest Ability Unlocks" + option_hexagons = 0 + option_pages = 1 + default = 0 + + class EntranceRando(TextChoice): """ Randomize the connections between scenes. A small, very lost fox on a big adventure. - + If you set this option's value to a string, it will be used as a custom seed. Every player who uses the same custom seed will have the same entrances, choosing the most restrictive settings among these players for the purpose of pairing entrances. """ @@ -301,6 +327,7 @@ class TunicOptions(PerGameCommonOptions): hexagon_quest: HexagonQuest hexagon_goal: HexagonGoal extra_hexagon_percentage: ExtraHexagonPercentage + hexagon_quest_ability_type: HexagonQuestAbilityUnlockType shuffle_ladders: ShuffleLadders grass_randomizer: GrassRandomizer @@ -323,6 +350,12 @@ class TunicOptions(PerGameCommonOptions): tunic_option_groups = [ + OptionGroup("Hexagon Quest Options", [ + HexagonQuest, + HexagonGoal, + ExtraHexagonPercentage, + HexagonQuestAbilityUnlockType + ]), OptionGroup("Logic Options", [ CombatLogic, Lanternless, @@ -357,3 +390,23 @@ class TunicOptions(PerGameCommonOptions): "lanternless": True, }, } + + +def check_options(world: "TunicWorld"): + options = world.options + if options.hexagon_quest and options.ability_shuffling and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: + total_hexes = get_hexagons_in_pool(world) + min_hexes = 3 + + if options.keys_behind_bosses: + min_hexes = 15 + if total_hexes < min_hexes: + logging.warning(f"TUNIC: Not enough Gold Hexagons in {world.player_name}'s item pool for Hexagon Ability Shuffle with the selected options. Ability Shuffle mode will be switched to Pages.") + options.hexagon_quest_ability_type.value = HexagonQuestAbilityUnlockType.option_pages + + +def get_hexagons_in_pool(world: "TunicWorld"): + # Calculate number of hexagons in item pool + options = world.options + return min(int((Decimal(100 + options.extra_hexagon_percentage) / 100 * options.hexagon_goal) + .to_integral_value(rounding=ROUND_HALF_UP)), 100) diff --git a/worlds/tunic/rules.py b/worlds/tunic/rules.py index b58ad73072bc..c7b4ad0d405f 100644 --- a/worlds/tunic/rules.py +++ b/worlds/tunic/rules.py @@ -1,9 +1,9 @@ -from random import Random from typing import Dict, TYPE_CHECKING +from decimal import Decimal, ROUND_HALF_UP from worlds.generic.Rules import set_rule, forbid_item, add_rule from BaseClasses import CollectionState -from .options import TunicOptions, LadderStorage, IceGrappling +from .options import LadderStorage, IceGrappling, HexagonQuestAbilityUnlockType if TYPE_CHECKING: from . import TunicWorld @@ -34,14 +34,21 @@ "Quarry - [West] Upper Area Bombable Wall", "Ruined Atoll - [Northwest] Bombable Wall"] -def randomize_ability_unlocks(random: Random, options: TunicOptions) -> Dict[str, int]: +def randomize_ability_unlocks(world: "TunicWorld") -> Dict[str, int]: + random = world.random + options = world.options + + abilities = [prayer, holy_cross, icebolt] ability_requirement = [1, 1, 1] - if options.hexagon_quest.value: + random.shuffle(abilities) + + if options.hexagon_quest.value and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: hexagon_goal = options.hexagon_goal.value # Set ability unlocks to 25, 50, and 75% of goal amount ability_requirement = [hexagon_goal // 4, hexagon_goal // 2, hexagon_goal * 3 // 4] - abilities = [prayer, holy_cross, icebolt] - random.shuffle(abilities) + if any(req == 0 for req in ability_requirement): + ability_requirement = [1, 2, 3] + return dict(zip(abilities, ability_requirement)) @@ -50,7 +57,7 @@ def has_ability(ability: str, state: CollectionState, world: "TunicWorld") -> bo ability_unlocks = world.ability_unlocks if not options.ability_shuffling: return True - if options.hexagon_quest: + if options.hexagon_quest and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: return state.has(gold_hexagon, world.player, ability_unlocks[ability]) return state.has(ability, world.player) From 08b3b3ecf51b0a6fd3fa7c02ad10bf05e6892312 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 8 Mar 2025 01:44:06 +0100 Subject: [PATCH 0168/1218] The Witness: The Secret Feature (#4370) * Secret Feature * Fixes * Fixes and unit tests * renaming some variables * Fix the thing * unit test for elevator egg * Docstring * reword * Fix duplicate locations I think? * Remove debug thing * Add the tests back lol * Make it so that you can exclude an egg to disable it * Improve hint text for easter eggs * Update worlds/witness/options.py Co-authored-by: Scipio Wright * Update worlds/witness/player_logic.py Co-authored-by: Scipio Wright * Update worlds/witness/options.py Co-authored-by: Scipio Wright * Update worlds/witness/player_logic.py Co-authored-by: Scipio Wright * Update worlds/witness/rules.py Co-authored-by: Scipio Wright * Update test_easter_egg_shuffle.py * This was actually not necessary, since this is the Egg requirements, nothing to do with location names * Move one of them * Improve logic * Lol * Moar * Adjust unit tests * option docstring adjustment * Recommend door shuffle * Don't overlap IDs * Option description idk * Change the way the difficulties work to reward playing higher modes * Fix merge * add some stuff to generate_data_file (this file is not imported during gen, don't review it :D) * oop * space * This can be earlier than I thought, apparently. * buffer * Comment * Make sure the option is VERY visible * Some mypy stuff * apparently ruff wants this * . * durinig * Update options.py * Explain the additional effects of each difficulty * Fix logic of flood room secret * Add Southern Peninsula Area * oop --------- Co-authored-by: Scipio Wright --- worlds/witness/__init__.py | 35 ++-- worlds/witness/data/WitnessLogic.txt | 40 ++++- worlds/witness/data/WitnessLogicExpert.txt | 40 ++++- worlds/witness/data/WitnessLogicVanilla.txt | 40 ++++- worlds/witness/data/WitnessLogicVariety.txt | 40 ++++- worlds/witness/data/settings/easter_eggs.py | 75 +++++++++ worlds/witness/data/static_logic.py | 71 +++++++- worlds/witness/data/utils.py | 16 +- worlds/witness/generate_data_file.py | 9 + worlds/witness/hints.py | 12 +- worlds/witness/locations.py | 2 +- worlds/witness/options.py | 61 +++++++ worlds/witness/player_items.py | 7 + worlds/witness/player_logic.py | 89 ++++++++-- worlds/witness/regions.py | 15 +- worlds/witness/ruff.toml | 2 +- worlds/witness/rules.py | 15 +- .../witness/test/test_easter_egg_shuffle.py | 155 ++++++++++++++++++ 18 files changed, 651 insertions(+), 73 deletions(-) create mode 100644 worlds/witness/data/settings/easter_eggs.py create mode 100644 worlds/witness/test/test_easter_egg_shuffle.py diff --git a/worlds/witness/__init__.py b/worlds/witness/__init__.py index 471d030d4897..3bf3661bc12a 100644 --- a/worlds/witness/__init__.py +++ b/worlds/witness/__init__.py @@ -5,7 +5,7 @@ from logging import error, warning from typing import Any, Dict, List, Optional, cast -from BaseClasses import CollectionState, Entrance, Location, Region, Tutorial +from BaseClasses import CollectionState, Entrance, Location, LocationProgressType, Region, Tutorial from Options import OptionError, PerGameCommonOptions, Toggle from worlds.AutoWorld import WebWorld, World @@ -380,6 +380,10 @@ def create_item(self, item_name: str) -> WitnessItem: if isinstance(item_name, dict): item_name = next(iter(item_name)) + # Easter Egg events with arbitrary sizes + if item_name.startswith("+") and "Easter Egg" in item_name: + return WitnessItem.make_egg_event(item_name, self.player) + # this conditional is purely for unit tests, which need to be able to create an item before generate_early item_data: ItemData if hasattr(self, "player_items") and self.player_items and item_name in self.player_items.item_data: @@ -389,6 +393,18 @@ def create_item(self, item_name: str) -> WitnessItem: return WitnessItem(item_name, item_data.classification, item_data.ap_code, player=self.player) + def collect(self, state: "CollectionState", item: WitnessItem) -> bool: + changed = super().collect(state, item) + if changed and item.eggs: + state.prog_items[self.player]["Egg"] += item.eggs + return changed + + def remove(self, state: "CollectionState", item: WitnessItem) -> bool: + changed = super().remove(state, item) + if changed and item.eggs: + state.prog_items[self.player]["Egg"] -= item.eggs + return changed + def get_filler_item_name(self) -> str: return "Speed Boost" @@ -398,11 +414,9 @@ class WitnessLocation(Location): Archipelago Location for The Witness """ game: str = "The Witness" - entity_hex: int = -1 - def __init__(self, player: int, name: str, address: Optional[int], parent: Region, ch_hex: int = -1) -> None: + def __init__(self, player: int, name: str, address: Optional[int], parent: Region) -> None: super().__init__(player, name, address, parent) - self.entity_hex = ch_hex def create_region(world: WitnessWorld, name: str, player_locations: WitnessPlayerLocations, @@ -416,14 +430,13 @@ def create_region(world: WitnessWorld, name: str, player_locations: WitnessPlaye for location in region_locations: loc_id = player_locations.CHECK_LOCATION_TABLE[location] - entity_hex = -1 + location_obj = WitnessLocation(world.player, location, loc_id, ret) + if location in static_witness_logic.ENTITIES_BY_NAME: - entity_hex = int( - static_witness_logic.ENTITIES_BY_NAME[location]["entity_hex"], 0 - ) - location_obj = WitnessLocation( - world.player, location, loc_id, ret, entity_hex - ) + entity_hex = static_witness_logic.ENTITIES_BY_NAME[location]["entity_hex"] + + if entity_hex in world.player_logic.EXCLUDED_ENTITIES: + location_obj.progress_type = LocationProgressType.EXCLUDED ret.locations.append(location_obj) if exits: diff --git a/worlds/witness/data/WitnessLogic.txt b/worlds/witness/data/WitnessLogic.txt index 0dbb88a107b1..edc45222b51e 100644 --- a/worlds/witness/data/WitnessLogic.txt +++ b/worlds/witness/data/WitnessLogic.txt @@ -206,7 +206,7 @@ Door - 0x0A24B (Flood Room Entry) - 0x0A249 159043 - 0x0A14C (Pond Room Near Reflection EP) - True - True 159044 - 0x0A14D (Pond Room Far Reflection EP) - True - True -Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316: +Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316 - Desert Flood Room Underwater - 0x1C260: 158097 - 0x1C2DF (Reduce Water Level Far Left) - True - True 158098 - 0x1831E (Reduce Water Level Far Right) - True - True 158099 - 0x1C260 (Reduce Water Level Near Left) - True - True @@ -224,6 +224,8 @@ Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316: Door - 0x0C316 (Elevator Room Entry) - 0x18076 159034 - 0x337F8 (Flood Room EP) - 0x1C2DF - True +Desert Flood Room Underwater (Desert): + Desert Elevator Room (Desert) - Desert Behind Elevator - 0x01317: 158111 - 0x17C31 (Elevator Room Transparent) - True - True 158113 - 0x012D7 (Elevator Room Hexagonal) - 0x17C31 & 0x0A015 - True @@ -501,7 +503,7 @@ Laser - 0x17C65 (Laser) - 0x17CA4 159121 - 0x03BE3 (Garden Right EP) - True - True 159122 - 0x0A409 (Wall EP) - True - True -Inside Monastery (Monastery): +Inside Monastery (Monastery) - Monastery North Shutters - 0x09D9B: 158213 - 0x09D9B (Shutters Control) - True - Dots 158214 - 0x193A7 (Inside 1) - 0x00037 - True 158215 - 0x193AA (Inside 2) - 0x193A7 - True @@ -513,6 +515,8 @@ Inside Monastery (Monastery): Monastery Garden (Monastery): +Monastery North Shutters (Monastery): + ==Town== Town Obelisk (Town) - Entry - True: @@ -637,9 +641,13 @@ Door - 0x3CCDF (Exit Right) - 0x33AB2 159556 - 0x33A2A (Door EP) - 0x03553 - True 159558 - 0x33B06 (Church EP) - 0x0354E - True +==Southern Peninsula== + +Southern Peninsula (Southern Peninsula) - Main Island - True: + ==Jungle== -Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF: +Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF - Jungle Under Popup Wall - 0x1475B: 158251 - 0x17CDF (Shore Boat Spawn) - True - Boat 158609 - 0x17F9B (Discard) - True - Triangles 158252 - 0x002C4 (First Row 1) - True - True @@ -670,6 +678,8 @@ Door - 0x3873B (Laser Shortcut) - 0x337FA 159350 - 0x035CB (Bamboo CCW EP) - True - True 159351 - 0x035CF (Bamboo CW EP) - True - True +Jungle Under Popup Wall (Jungle): + Outside Jungle River (Jungle) - Main Island - True - Monastery Garden - 0x0CF2A - Jungle Vault - 0x15287: 158267 - 0x17CAA (Monastery Garden Shortcut Panel) - True - True Door - 0x0CF2A (Monastery Garden Shortcut) - 0x17CAA @@ -712,9 +722,11 @@ Bunker Ultraviolet Room (Bunker) - Bunker Elevator Section - 0x0A08D: 158285 - 0x17E67 (UV Room 2) - 0x17E63 & 0x34BC6 - Colored Squares & Black/White Squares Door - 0x0A08D (Elevator Room Entry) - 0x17E67 -Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay: +Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay - Bunker Under Elevator - 0x0A079 | Bunker Green Room | Bunker Cyan Room | Bunker Laser Platform: 159311 - 0x035F5 (Tinted Door EP) - 0x17C79 - True +Bunker Under Elevator (Bunker): + Bunker Elevator (Bunker) - Bunker Elevator Section - 0x0A079 - Bunker Cyan Room - 0x0A079 - Bunker Green Room - 0x0A079 - Bunker Laser Platform - 0x0A079 - Outside Bunker - 0x0A079: 158286 - 0x0A079 (Elevator Control) - True - Colored Squares & Black/White Squares @@ -1005,7 +1017,7 @@ Mountaintop (Mountaintop) - Mountain Floor 1 - 0x17C34: Mountain Floor 1 (Mountain Floor 1) - Mountain Floor 1 Bridge - 0x09E39: 158408 - 0x09E39 (Light Bridge Controller) - True - Black/White Squares & Colored Squares & Eraser -Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneWay: +Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneWay - Mountain Floor 1 Trash Pillar - TrueOneWay - Mountain Floor 1 Back Section - TrueOneWay: 158409 - 0x09E7A (Right Row 1) - True - Black/White Squares & Dots 158410 - 0x09E71 (Right Row 2) - 0x09E7A - Black/White Squares & Dots 158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers & Dots @@ -1018,11 +1030,15 @@ Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneW 158418 - 0x09E6C (Left Row 5) - 0x09E79 - Stars & Black/White Squares & Stars + Same Colored Symbol 158419 - 0x09E6F (Left Row 6) - 0x09E6C - Stars & Rotated Shapers & Shapers 158420 - 0x09E6B (Left Row 7) - 0x09E6F - Stars & Dots +158424 - 0x09EAD (Trash Pillar 1) - True - Black/White Squares & Shapers +158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Black/White Squares & Shaper + +Mountain Floor 1 Trash Pillar (Mountain Floor 1): + +Mountain Floor 1 Back Section (Mountain Floor 1): 158421 - 0x33AF5 (Back Row 1) - True - Black/White Squares & Symmetry 158422 - 0x33AF7 (Back Row 2) - 0x33AF5 - Black/White Squares & Stars 158423 - 0x09F6E (Back Row 3) - 0x33AF7 - Symmetry & Dots -158424 - 0x09EAD (Trash Pillar 1) - True - Black/White Squares & Shapers -158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Black/White Squares & Shapers Mountain Floor 1 At Door (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B @@ -1098,14 +1114,16 @@ Elevator (Mountain Bottom Floor): Mountain Pink Bridge EP (Mountain Floor 2): 159312 - 0x09D63 (Pink Bridge EP) - 0x09E39 - True -Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D: +Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D - Caves Entry Door - TrueOneWay: 158447 - 0x00FF8 (Caves Entry Panel) - True - Triangles & Black/White Squares Door - 0x2D77D (Caves Entry) - 0x00FF8 158448 - 0x334E1 (Rock Control) - True - True ==Caves== -Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x019A5: +Caves Entry Door (Caves): + +Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x019A5 - Caves Entry Door - TrueOneWay: 158451 - 0x335AB (Elevator Inside Control) - True - Dots & Black/White Squares 158452 - 0x335AC (Elevator Upper Outside Control) - 0x335AB - Black/White Squares 158453 - 0x3369D (Elevator Lower Outside Control) - 0x335AB - Black/White Squares & Dots @@ -1219,3 +1237,7 @@ The Ocean (Boat) - Main Island - TrueOneWay - Swamp Near Boat - TrueOneWay - Tre 159521 - 0x33879 (Tutorial Reflection EP) - True - True 159522 - 0x03C19 (Tutorial Moss EP) - True - True 159531 - 0x035C9 (Cargo Box EP) - 0x0A0C9 - True + +==Easter Eggs== + +Easter Eggs (Easter Eggs) - Entry - True: diff --git a/worlds/witness/data/WitnessLogicExpert.txt b/worlds/witness/data/WitnessLogicExpert.txt index 0f601724acbe..23521dddeb5b 100644 --- a/worlds/witness/data/WitnessLogicExpert.txt +++ b/worlds/witness/data/WitnessLogicExpert.txt @@ -206,7 +206,7 @@ Door - 0x0A24B (Flood Room Entry) - 0x0A249 159043 - 0x0A14C (Pond Room Near Reflection EP) - True - True 159044 - 0x0A14D (Pond Room Far Reflection EP) - True - True -Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316: +Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316 - Desert Flood Room Underwater - 0x1C260: 158097 - 0x1C2DF (Reduce Water Level Far Left) - True - True 158098 - 0x1831E (Reduce Water Level Far Right) - True - True 158099 - 0x1C260 (Reduce Water Level Near Left) - True - True @@ -224,6 +224,8 @@ Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316: Door - 0x0C316 (Elevator Room Entry) - 0x18076 159034 - 0x337F8 (Flood Room EP) - 0x1C2DF - True +Desert Flood Room Underwater (Desert): + Desert Elevator Room (Desert) - Desert Behind Elevator - 0x01317: 158111 - 0x17C31 (Elevator Room Transparent) - True - True 158113 - 0x012D7 (Elevator Room Hexagonal) - 0x17C31 & 0x0A015 - True @@ -501,7 +503,7 @@ Laser - 0x17C65 (Laser) - 0x17CA4 159121 - 0x03BE3 (Garden Right EP) - True - True 159122 - 0x0A409 (Wall EP) - True - True -Inside Monastery (Monastery): +Inside Monastery (Monastery) - Monastery North Shutters - 0x09D9B: 158213 - 0x09D9B (Shutters Control) - True - Dots 158214 - 0x193A7 (Inside 1) - 0x00037 - True 158215 - 0x193AA (Inside 2) - 0x193A7 - True @@ -513,6 +515,8 @@ Inside Monastery (Monastery): Monastery Garden (Monastery): +Monastery North Shutters (Monastery): + ==Town== Town Obelisk (Town) - Entry - True: @@ -637,9 +641,13 @@ Door - 0x3CCDF (Exit Right) - 0x33AB2 159556 - 0x33A2A (Door EP) - 0x03553 - True 159558 - 0x33B06 (Church EP) - 0x0354E - True +==Southern Peninsula== + +Southern Peninsula (Southern Peninsula) - Main Island - True: + ==Jungle== -Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF: +Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF - Jungle Under Popup Wall - 0x1475B: 158251 - 0x17CDF (Shore Boat Spawn) - True - Boat 158609 - 0x17F9B (Discard) - True - Arrows 158252 - 0x002C4 (First Row 1) - True - True @@ -670,6 +678,8 @@ Door - 0x3873B (Laser Shortcut) - 0x337FA 159350 - 0x035CB (Bamboo CCW EP) - True - True 159351 - 0x035CF (Bamboo CW EP) - True - True +Jungle Under Popup Wall (Jungle): + Outside Jungle River (Jungle) - Main Island - True - Monastery Garden - 0x0CF2A - Jungle Vault - 0x15287: 158267 - 0x17CAA (Monastery Garden Shortcut Panel) - True - True Door - 0x0CF2A (Monastery Garden Shortcut) - 0x17CAA @@ -712,9 +722,11 @@ Bunker Ultraviolet Room (Bunker) - Bunker Elevator Section - 0x0A08D: 158285 - 0x17E67 (UV Room 2) - 0x17E63 & 0x34BC6 - Squares & Colored Squares & Black/White Squares Door - 0x0A08D (Elevator Room Entry) - 0x17E67 -Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay: +Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay - Bunker Under Elevator - 0x0A079 | Bunker Green Room | Bunker Cyan Room | Bunker Laser Platform: 159311 - 0x035F5 (Tinted Door EP) - 0x17C79 - True +Bunker Under Elevator (Bunker): + Bunker Elevator (Bunker) - Bunker Elevator Section - 0x0A079 - Bunker Cyan Room - 0x0A079 - Bunker Green Room - 0x0A079 - Bunker Laser Platform - 0x0A079 - Outside Bunker - 0x0A079: 158286 - 0x0A079 (Elevator Control) - True - Colored Squares & Black/White Squares @@ -1005,7 +1017,7 @@ Mountaintop (Mountaintop) - Mountain Floor 1 - 0x17C34: Mountain Floor 1 (Mountain Floor 1) - Mountain Floor 1 Bridge - 0x09E39: 158408 - 0x09E39 (Light Bridge Controller) - True - Eraser & Triangles -Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneWay: +Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneWay - Mountain Floor 1 Trash Pillar - TrueOneWay - Mountain Floor 1 Back Section - TrueOneWay: 158409 - 0x09E7A (Right Row 1) - True - Black/White Squares & Dots & Stars & Stars + Same Colored Symbol 158410 - 0x09E71 (Right Row 2) - 0x09E7A - Black/White Squares & Triangles 158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers & Stars & Stars + Same Colored Symbol @@ -1018,11 +1030,15 @@ Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneW 158418 - 0x09E6C (Left Row 5) - 0x09E79 - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol 158419 - 0x09E6F (Left Row 6) - 0x09E6C - Symmetry & Stars & Colored Squares & Black/White Squares & Stars + Same Colored Symbol & Symmetry & Eraser 158420 - 0x09E6B (Left Row 7) - 0x09E6F - Symmetry & Dots & Full Dots & Triangles +158424 - 0x09EAD (Trash Pillar 1) - True - Rotated Shapers & Stars +158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Rotated Shapers & Triangles + +Mountain Floor 1 Trash Pillar (Mountain Floor 1): + +Mountain Floor 1 Back Section (Mountain Floor 1): 158421 - 0x33AF5 (Back Row 1) - True - Symmetry & Black/White Squares & Triangles 158422 - 0x33AF7 (Back Row 2) - 0x33AF5 - Symmetry & Stars & Triangles & Stars + Same Colored Symbol 158423 - 0x09F6E (Back Row 3) - 0x33AF7 - Symmetry & Stars & Shapers & Stars + Same Colored Symbol -158424 - 0x09EAD (Trash Pillar 1) - True - Rotated Shapers & Stars -158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Rotated Shapers & Triangles Mountain Floor 1 At Door (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B @@ -1098,14 +1114,16 @@ Elevator (Mountain Bottom Floor): Mountain Pink Bridge EP (Mountain Floor 2): 159312 - 0x09D63 (Pink Bridge EP) - 0x09E39 - True -Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D: +Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D - Caves Entry Door - TrueOneWay: 158447 - 0x00FF8 (Caves Entry Panel) - True - Arrows & Black/White Squares Door - 0x2D77D (Caves Entry) - 0x00FF8 158448 - 0x334E1 (Rock Control) - True - True ==Caves== -Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x019A5: +Caves Entry Door (Caves): + +Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x019A5 - Caves Entry Door - TrueOneWay: 158451 - 0x335AB (Elevator Inside Control) - True - Dots & Squares & Black/White Squares 158452 - 0x335AC (Elevator Upper Outside Control) - 0x335AB - Squares & Black/White Squares 158453 - 0x3369D (Elevator Lower Outside Control) - 0x335AB - Squares & Black/White Squares & Dots @@ -1219,3 +1237,7 @@ The Ocean (Boat) - Main Island - TrueOneWay - Swamp Near Boat - TrueOneWay - Tre 159521 - 0x33879 (Tutorial Reflection EP) - True - True 159522 - 0x03C19 (Tutorial Moss EP) - True - True 159531 - 0x035C9 (Cargo Box EP) - 0x0A0C9 - True + +==Easter Eggs== + +Easter Eggs (Easter Eggs) - Entry - True: diff --git a/worlds/witness/data/WitnessLogicVanilla.txt b/worlds/witness/data/WitnessLogicVanilla.txt index f0c6a8690ed3..a967a12e28c0 100644 --- a/worlds/witness/data/WitnessLogicVanilla.txt +++ b/worlds/witness/data/WitnessLogicVanilla.txt @@ -206,7 +206,7 @@ Door - 0x0A24B (Flood Room Entry) - 0x0A249 159043 - 0x0A14C (Pond Room Near Reflection EP) - True - True 159044 - 0x0A14D (Pond Room Far Reflection EP) - True - True -Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316: +Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316 - Desert Flood Room Underwater - 0x1C260: 158097 - 0x1C2DF (Reduce Water Level Far Left) - True - True 158098 - 0x1831E (Reduce Water Level Far Right) - True - True 158099 - 0x1C260 (Reduce Water Level Near Left) - True - True @@ -224,6 +224,8 @@ Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316: Door - 0x0C316 (Elevator Room Entry) - 0x18076 159034 - 0x337F8 (Flood Room EP) - 0x1C2DF - True +Desert Flood Room Underwater (Desert): + Desert Elevator Room (Desert) - Desert Behind Elevator - 0x01317: 158111 - 0x17C31 (Elevator Room Transparent) - True - True 158113 - 0x012D7 (Elevator Room Hexagonal) - 0x17C31 & 0x0A015 - True @@ -501,7 +503,7 @@ Laser - 0x17C65 (Laser) - 0x17CA4 159121 - 0x03BE3 (Garden Right EP) - True - True 159122 - 0x0A409 (Wall EP) - True - True -Inside Monastery (Monastery): +Inside Monastery (Monastery) - Monastery North Shutters - 0x09D9B: 158213 - 0x09D9B (Shutters Control) - True - Dots 158214 - 0x193A7 (Inside 1) - 0x00037 - True 158215 - 0x193AA (Inside 2) - 0x193A7 - True @@ -513,6 +515,8 @@ Inside Monastery (Monastery): Monastery Garden (Monastery): +Monastery North Shutters (Monastery): + ==Town== Town Obelisk (Town) - Entry - True: @@ -637,9 +641,13 @@ Door - 0x3CCDF (Exit Right) - 0x33AB2 159556 - 0x33A2A (Door EP) - 0x03553 - True 159558 - 0x33B06 (Church EP) - 0x0354E - True +==Southern Peninsula== + +Southern Peninsula (Southern Peninsula) - Main Island - True: + ==Jungle== -Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF: +Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF - Jungle Under Popup Wall - 0x1475B: 158251 - 0x17CDF (Shore Boat Spawn) - True - Boat 158609 - 0x17F9B (Discard) - True - Triangles 158252 - 0x002C4 (First Row 1) - True - True @@ -670,6 +678,8 @@ Door - 0x3873B (Laser Shortcut) - 0x337FA 159350 - 0x035CB (Bamboo CCW EP) - True - True 159351 - 0x035CF (Bamboo CW EP) - True - True +Jungle Under Popup Wall (Jungle): + Outside Jungle River (Jungle) - Main Island - True - Monastery Garden - 0x0CF2A - Jungle Vault - 0x15287: 158267 - 0x17CAA (Monastery Garden Shortcut Panel) - True - True Door - 0x0CF2A (Monastery Garden Shortcut) - 0x17CAA @@ -712,9 +722,11 @@ Bunker Ultraviolet Room (Bunker) - Bunker Elevator Section - 0x0A08D: 158285 - 0x17E67 (UV Room 2) - 0x17E63 & 0x34BC6 - Colored Squares & Black/White Squares Door - 0x0A08D (Elevator Room Entry) - 0x17E67 -Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay: +Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay - Bunker Under Elevator - 0x0A079 | Bunker Green Room | Bunker Cyan Room | Bunker Laser Platform: 159311 - 0x035F5 (Tinted Door EP) - 0x17C79 - True +Bunker Under Elevator (Bunker): + Bunker Elevator (Bunker) - Bunker Elevator Section - 0x0A079 - Bunker Cyan Room - 0x0A079 - Bunker Green Room - 0x0A079 - Bunker Laser Platform - 0x0A079 - Outside Bunker - 0x0A079: 158286 - 0x0A079 (Elevator Control) - True - Colored Squares & Black/White Squares @@ -1005,7 +1017,7 @@ Mountaintop (Mountaintop) - Mountain Floor 1 - 0x17C34: Mountain Floor 1 (Mountain Floor 1) - Mountain Floor 1 Bridge - 0x09E39: 158408 - 0x09E39 (Light Bridge Controller) - True - Black/White Squares & Rotated Shapers -Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneWay: +Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneWay - Mountain Floor 1 Trash Pillar - TrueOneWay - Mountain Floor 1 Back Section - TrueOneWay: 158409 - 0x09E7A (Right Row 1) - True - Black/White Squares & Dots 158410 - 0x09E71 (Right Row 2) - 0x09E7A - Black/White Squares & Dots 158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers @@ -1018,11 +1030,15 @@ Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneW 158418 - 0x09E6C (Left Row 5) - 0x09E79 - Stars & Black/White Squares 158419 - 0x09E6F (Left Row 6) - 0x09E6C - Shapers & Dots 158420 - 0x09E6B (Left Row 7) - 0x09E6F - Dots +158424 - 0x09EAD (Trash Pillar 1) - True - Black/White Squares & Shapers +158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Black/White Squares & Shapers + +Mountain Floor 1 Trash Pillar (Mountain Floor 1): + +Mountain Floor 1 Back Section (Mountain Floor 1): 158421 - 0x33AF5 (Back Row 1) - True - Black/White Squares & Symmetry 158422 - 0x33AF7 (Back Row 2) - 0x33AF5 - Black/White Squares 158423 - 0x09F6E (Back Row 3) - 0x33AF7 - Symmetry & Dots -158424 - 0x09EAD (Trash Pillar 1) - True - Black/White Squares & Shapers -158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Black/White Squares & Shapers Mountain Floor 1 At Door (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B @@ -1098,14 +1114,16 @@ Elevator (Mountain Bottom Floor): Mountain Pink Bridge EP (Mountain Floor 2): 159312 - 0x09D63 (Pink Bridge EP) - 0x09E39 - True -Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D: +Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D - Caves Entry Door - TrueOneWay: 158447 - 0x00FF8 (Caves Entry Panel) - True - Black/White Squares Door - 0x2D77D (Caves Entry) - 0x00FF8 158448 - 0x334E1 (Rock Control) - True - True ==Caves== -Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x019A5: +Caves Entry Door (Caves): + +Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x019A5 - Caves Entry Door - TrueOneWay: 158451 - 0x335AB (Elevator Inside Control) - True - Dots & Black/White Squares 158452 - 0x335AC (Elevator Upper Outside Control) - 0x335AB - Black/White Squares 158453 - 0x3369D (Elevator Lower Outside Control) - 0x335AB - Black/White Squares & Dots @@ -1219,3 +1237,7 @@ The Ocean (Boat) - Main Island - TrueOneWay - Swamp Near Boat - TrueOneWay - Tre 159521 - 0x33879 (Tutorial Reflection EP) - True - True 159522 - 0x03C19 (Tutorial Moss EP) - True - True 159531 - 0x035C9 (Cargo Box EP) - 0x0A0C9 - True + +==Easter Eggs== + +Easter Eggs (Easter Eggs) - Entry - True: diff --git a/worlds/witness/data/WitnessLogicVariety.txt b/worlds/witness/data/WitnessLogicVariety.txt index b7b705a6db9f..bc9a40f566f0 100644 --- a/worlds/witness/data/WitnessLogicVariety.txt +++ b/worlds/witness/data/WitnessLogicVariety.txt @@ -206,7 +206,7 @@ Door - 0x0A24B (Flood Room Entry) - 0x0A249 159043 - 0x0A14C (Pond Room Near Reflection EP) - True - True 159044 - 0x0A14D (Pond Room Far Reflection EP) - True - True -Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316: +Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316 - Desert Flood Room Underwater - 0x1C260: 158097 - 0x1C2DF (Reduce Water Level Far Left) - True - True 158098 - 0x1831E (Reduce Water Level Far Right) - True - True 158099 - 0x1C260 (Reduce Water Level Near Left) - True - True @@ -224,6 +224,8 @@ Desert Flood Room (Desert) - Desert Elevator Room - 0x0C316: Door - 0x0C316 (Elevator Room Entry) - 0x18076 159034 - 0x337F8 (Flood Room EP) - 0x1C2DF - True +Desert Flood Room Underwater (Desert): + Desert Elevator Room (Desert) - Desert Behind Elevator - 0x01317: 158111 - 0x17C31 (Elevator Room Transparent) - True - True 158113 - 0x012D7 (Elevator Room Hexagonal) - 0x17C31 & 0x0A015 - True @@ -501,7 +503,7 @@ Laser - 0x17C65 (Laser) - 0x17CA4 159121 - 0x03BE3 (Garden Right EP) - True - True 159122 - 0x0A409 (Wall EP) - True - True -Inside Monastery (Monastery): +Inside Monastery (Monastery) - Monastery North Shutters - 0x09D9B: 158213 - 0x09D9B (Shutters Control) - True - Dots 158214 - 0x193A7 (Inside 1) - 0x00037 - True 158215 - 0x193AA (Inside 2) - 0x193A7 - True @@ -513,6 +515,8 @@ Inside Monastery (Monastery): Monastery Garden (Monastery): +Monastery North Shutters (Monastery): + ==Town== Town Obelisk (Town) - Entry - True: @@ -637,9 +641,13 @@ Door - 0x3CCDF (Exit Right) - 0x33AB2 159556 - 0x33A2A (Door EP) - 0x03553 - True 159558 - 0x33B06 (Church EP) - 0x0354E - True +==Southern Peninsula== + +Southern Peninsula (Southern Peninsula) - Main Island - True: + ==Jungle== -Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF: +Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF - Jungle Under Popup Wall - 0x1475B: 158251 - 0x17CDF (Shore Boat Spawn) - True - Boat 158609 - 0x17F9B (Discard) - True - Arrows & Triangles 158252 - 0x002C4 (First Row 1) - True - True @@ -670,6 +678,8 @@ Door - 0x3873B (Laser Shortcut) - 0x337FA 159350 - 0x035CB (Bamboo CCW EP) - True - True 159351 - 0x035CF (Bamboo CW EP) - True - True +Jungle Under Popup Wall (Jungle): + Outside Jungle River (Jungle) - Main Island - True - Monastery Garden - 0x0CF2A - Jungle Vault - 0x15287: 158267 - 0x17CAA (Monastery Garden Shortcut Panel) - True - True Door - 0x0CF2A (Monastery Garden Shortcut) - 0x17CAA @@ -712,9 +722,11 @@ Bunker Ultraviolet Room (Bunker) - Bunker Elevator Section - 0x0A08D: 158285 - 0x17E67 (UV Room 2) - 0x17E63 & 0x34BC6 - Colored Squares & Black/White Squares Door - 0x0A08D (Elevator Room Entry) - 0x17E67 -Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay: +Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay - Bunker Under Elevator - 0x0A079 | Bunker Green Room | Bunker Cyan Room | Bunker Laser Platform: 159311 - 0x035F5 (Tinted Door EP) - 0x17C79 - True +Bunker Under Elevator (Bunker): + Bunker Elevator (Bunker) - Bunker Elevator Section - 0x0A079 - Bunker Cyan Room - 0x0A079 - Bunker Green Room - 0x0A079 - Bunker Laser Platform - 0x0A079 - Outside Bunker - 0x0A079: 158286 - 0x0A079 (Elevator Control) - True - Colored Squares & Black/White Squares @@ -1005,7 +1017,7 @@ Mountaintop (Mountaintop) - Mountain Floor 1 - 0x17C34: Mountain Floor 1 (Mountain Floor 1) - Mountain Floor 1 Bridge - 0x09E39: 158408 - 0x09E39 (Light Bridge Controller) - True - Black/White Squares & Colored Squares & Eraser -Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneWay: +Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneWay - Mountain Floor 1 Trash Pillar - TrueOneWay - Mountain Floor 1 Back Section - TrueOneWay: 158409 - 0x09E7A (Right Row 1) - True - Black/White Squares & Dots 158410 - 0x09E71 (Right Row 2) - 0x09E7A - Black/White Squares & Dots & Stars & Stars + Same Colored Symbol 158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers & Stars & Stars + Same Colored Symbol @@ -1018,11 +1030,15 @@ Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneW 158418 - 0x09E6C (Left Row 5) - 0x09E79 - Arrows & Black/White Squares & Stars & Stars + Same Colored Symbol 158419 - 0x09E6F (Left Row 6) - 0x09E6C - Arrows & Dots & Full Dots 158420 - 0x09E6B (Left Row 7) - 0x09E6F - Arrows & Dots & Full Dots +158424 - 0x09EAD (Trash Pillar 1) - True - Triangles & Arrows +158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Triangles & Arrows + +Mountain Floor 1 Trash Pillar (Mountain Floor 1): + +Mountain Floor 1 Back Section (Mountain Floor 1): 158421 - 0x33AF5 (Back Row 1) - True - Symmetry & Triangles 158422 - 0x33AF7 (Back Row 2) - 0x33AF5 - Triangles 158423 - 0x09F6E (Back Row 3) - 0x33AF7 - Symmetry & Triangles -158424 - 0x09EAD (Trash Pillar 1) - True - Triangles & Arrows -158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Triangles & Arrows Mountain Floor 1 At Door (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B @@ -1098,14 +1114,16 @@ Elevator (Mountain Bottom Floor): Mountain Pink Bridge EP (Mountain Floor 2): 159312 - 0x09D63 (Pink Bridge EP) - 0x09E39 - True -Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D: +Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D - Caves Entry Door - TrueOneWay: 158447 - 0x00FF8 (Caves Entry Panel) - True - Black/White Squares & Arrows & Triangles Door - 0x2D77D (Caves Entry) - 0x00FF8 158448 - 0x334E1 (Rock Control) - True - True ==Caves== -Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x019A5: +Caves Entry Door (Caves): + +Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x019A5 - Caves Entry Door - TrueOneWay: 158451 - 0x335AB (Elevator Inside Control) - True - Dots & Black/White Squares 158452 - 0x335AC (Elevator Upper Outside Control) - 0x335AB - Black/White Squares 158453 - 0x3369D (Elevator Lower Outside Control) - 0x335AB - Black/White Squares & Dots @@ -1219,3 +1237,7 @@ The Ocean (Boat) - Main Island - TrueOneWay - Swamp Near Boat - TrueOneWay - Tre 159521 - 0x33879 (Tutorial Reflection EP) - True - True 159522 - 0x03C19 (Tutorial Moss EP) - True - True 159531 - 0x035C9 (Cargo Box EP) - 0x0A0C9 - True + +==Easter Eggs== + +Easter Eggs (Easter Eggs) - Entry - True: diff --git a/worlds/witness/data/settings/easter_eggs.py b/worlds/witness/data/settings/easter_eggs.py new file mode 100644 index 000000000000..248e94273129 --- /dev/null +++ b/worlds/witness/data/settings/easter_eggs.py @@ -0,0 +1,75 @@ +MAXIMUM_EASTER_EGG_CHECKS = 50 + +EASTER_EGGS = { + "Tutorial": 1, + "Outside Tutorial": 4, + "Outside Tutorial Path To Outpost": 1, + "Outside Tutorial Outpost": 1, + "Orchard Beyond First Gate": 1, + "Orchard End": 1, + "Inside Glass Factory": 2, + "Symmetry Island Lower": 2, + "Symmetry Island Upper": 1, + "Desert Outside": 6, + "Desert Vault": 1, + "Desert Pond Room": 2, + "Desert Flood Room Underwater": 1, + "Desert Elevator Room": 1, + "Outside Quarry": 2, + "Quarry": 5, + "Quarry Stoneworks Upper Floor": 2, + "Quarry Boathouse": 2, + "Shadows": 2, + "Shadows Ledge": 1, + "Shadows Laser Room": 1, + "Keep": 1, + "Keep 3rd Maze": 3, + "Keep 2nd Pressure Plate": 2, + "Keep 3rd Pressure Plate": 1, + "Keep 4th Pressure Plate": 1, + "Keep Tower": 2, + "Shipwreck": 5, + "Inside Monastery": 1, + "Monastery North Shutters": 1, + "Monastery Garden": 1, + "Town": 5, + "Town Wooden Rooftop": 1, + "Town RGB House": 2, + "Town Tower Top": 1, + "Windmill Interior": 2, + "Theater": 1, + "Southern Peninsula": 5, + "Jungle": 2, + "Jungle Under Popup Wall": 1, + "Jungle Vault": 1, + "Outside Bunker": 3, + "Bunker Glass Room": 1, + "Bunker Under Elevator": 1, + "Bunker Green Room": 1, + "Outside Swamp": 2, + "Swamp Entry Area": 1, + "Swamp Platform": 1, + "Swamp Cyan Underwater": 1, + "Swamp Near Boat": 1, + "Swamp Laser Area": 1, + "Treehouse Beach": 1, + "Treehouse Yellow Bridge": 1, + "Treehouse Junction": 2, + "Treehouse Second Purple Bridge": 1, + "Treehouse Green Bridge Left House": 1, + "Treehouse Laser Room Back Platform": 1, + "Treehouse Burned House": 1, + "Treehouse Drawbridge Platform": 1, + "Mountainside": 4, + "Mountaintop": 1, + "Mountain Floor 1 Trash Pillar": 1, + "Mountain Floor 1 Back Section": 1, + "Mountain Floor 2": 1, + "Mountain Bottom Floor Pillars Room": 1, + "Caves Entry Door": 1, + "Caves": 2, + "Caves Path to Challenge": 1, + "Challenge": 2, + "Tunnels": 2, + "The Ocean": 2, +} diff --git a/worlds/witness/data/static_logic.py b/worlds/witness/data/static_logic.py index 6cc4e1431d07..4f4786a38b9a 100644 --- a/worlds/witness/data/static_logic.py +++ b/worlds/witness/data/static_logic.py @@ -1,4 +1,4 @@ -from collections import defaultdict +from collections import Counter, defaultdict from typing import Any, Dict, List, Optional, Set, Tuple from Utils import cache_argsless @@ -11,6 +11,7 @@ ProgressiveItemDefinition, WeightedItemDefinition, ) +from .settings.easter_eggs import EASTER_EGGS from .utils import ( WitnessRule, define_new_region, @@ -49,6 +50,70 @@ def __init__(self, lines: Optional[List[str]] = None) -> None: self.reverse_connections() self.combine_connections() + def add_easter_eggs(self) -> None: + egg_counter = 0 + area_counts: Dict[str, int] = Counter() + for region_name, entity_amount in EASTER_EGGS.items(): + region_object = self.ALL_REGIONS_BY_NAME[region_name] + correct_area = region_object["area"] + + for _ in range(entity_amount): + location_id = 160200 + egg_counter + entity_hex = hex(0xEE000 + egg_counter) + egg_counter += 1 + + area_counts[correct_area["name"]] += 1 + full_entity_name = f"{correct_area['name']} Easter Egg {area_counts[correct_area['name']]}" + + self.ENTITIES_BY_HEX[entity_hex] = { + "checkName": full_entity_name, + "entity_hex": entity_hex, + "region": region_object, + "id": int(location_id), + "entityType": "Easter Egg", + "locationType": "Easter Egg", + "area": correct_area, + "order": len(self.ENTITIES_BY_HEX), + } + + self.ENTITIES_BY_NAME[self.ENTITIES_BY_HEX[entity_hex]["checkName"]] = self.ENTITIES_BY_HEX[entity_hex] + + self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[entity_hex] = { + "entities": frozenset({frozenset({})}) + } + region_object["entities"].append(entity_hex) + region_object["physical_entities"].append(entity_hex) + + easter_egg_region = self.ALL_REGIONS_BY_NAME["Easter Eggs"] + easter_egg_area = easter_egg_region["area"] + for i in range(sum(EASTER_EGGS.values())): + location_id = 160000 + i + entity_hex = hex(0xEE200 + i) + + if i == 0: + continue + + full_entity_name = f"{i + 1} Easter Eggs Collected" + + self.ENTITIES_BY_HEX[entity_hex] = { + "checkName": full_entity_name, + "entity_hex": entity_hex, + "region": easter_egg_region, + "id": int(location_id), + "entityType": "Easter Egg Total", + "locationType": "Easter Egg Total", + "area": easter_egg_area, + "order": len(self.ENTITIES_BY_HEX), + } + + self.ENTITIES_BY_NAME[self.ENTITIES_BY_HEX[entity_hex]["checkName"]] = self.ENTITIES_BY_HEX[entity_hex] + + self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[entity_hex] = { + "entities": frozenset({frozenset({})}) + } + easter_egg_region["entities"].append(entity_hex) + easter_egg_region["physical_entities"].append(entity_hex) + def read_logic_file(self, lines: List[str]) -> None: """ Reads the logic file and does the initial population of data structures @@ -66,7 +131,7 @@ def read_logic_file(self, lines: List[str]) -> None: continue if line[-1] == ":": - new_region_and_connections = define_new_region(line) + new_region_and_connections = define_new_region(line, current_area) current_region = new_region_and_connections[0] region_name = current_region["name"] self.ALL_REGIONS_BY_NAME[region_name] = current_region @@ -198,6 +263,8 @@ def read_logic_file(self, lines: List[str]) -> None: current_region["entities"].append(entity_hex) current_region["physical_entities"].append(entity_hex) + self.add_easter_eggs() + def reverse_connection(self, source_region: str, connection: Tuple[str, Set[WitnessRule]]) -> None: target = connection[0] traversal_options = connection[1] diff --git a/worlds/witness/data/utils.py b/worlds/witness/data/utils.py index 190c00dc283b..aca457380664 100644 --- a/worlds/witness/data/utils.py +++ b/worlds/witness/data/utils.py @@ -1,3 +1,4 @@ +from datetime import date from math import floor from pkgutil import get_data from random import Random @@ -61,7 +62,7 @@ def build_weighted_int_list(inputs: Collection[float], total: int) -> List[int]: return rounded_output -def define_new_region(region_string: str) -> Tuple[Dict[str, Any], Set[Tuple[str, WitnessRule]]]: +def define_new_region(region_string: str, area: dict[str, Any]) -> Tuple[Dict[str, Any], Set[Tuple[str, WitnessRule]]]: """ Returns a region object by parsing a line in the logic file """ @@ -91,6 +92,7 @@ def define_new_region(region_string: str) -> Tuple[Dict[str, Any], Set[Tuple[str "shortName": region_name_simple, "entities": [], "physical_entities": [], + "area": area, } return region_obj, options @@ -264,3 +266,15 @@ def logical_and_witness_rules(witness_rules: Iterable[WitnessRule]) -> WitnessRu def logical_or_witness_rules(witness_rules: Iterable[WitnessRule]) -> WitnessRule: return optimize_witness_rule(frozenset.union(*witness_rules)) + + +def is_easter_time() -> bool: + # dateutils would have been nice here, because it has an easter() function. + # But adding it as a requirement seems heavier than necessary. + # Thus, we just take a range from the earliest to latest possible easter dates. + + today = date.today() + earliest_easter_day = date(today.year, 3, 20) # Earliest possible is 3/22 + 2 day buffer for Good Friday + last_easter_day = date(today.year, 4, 26) # Latest possible is 4/25 + 1 day buffer for Easter Monday + + return earliest_easter_day <= today <= last_easter_day diff --git a/worlds/witness/generate_data_file.py b/worlds/witness/generate_data_file.py index 50a63a374619..cc05015cd810 100644 --- a/worlds/witness/generate_data_file.py +++ b/worlds/witness/generate_data_file.py @@ -43,3 +43,12 @@ ) ) datafile.write("\n};\n\n") + + datafile.write("inline std::map entityToName = {") + datafile.write( + "\n".join( + "\t{ " + entity_hex + ', "' + entity_object["checkName"] + '" },' + for entity_hex, entity_object in static_witness_logic.ENTITIES_BY_HEX.items() + ) + ) + datafile.write("\n};\n\n") diff --git a/worlds/witness/hints.py b/worlds/witness/hints.py index 82837aed0686..6f274f5e2c6b 100644 --- a/worlds/witness/hints.py +++ b/worlds/witness/hints.py @@ -241,7 +241,10 @@ def word_direct_hint(world: "WitnessWorld", hint: WitnessLocationHint) -> Witnes area = chosen_group # local locations should only ever return a location group, as Witness defines groups for every location. - hint_text = f"{item_name} can be found in the {area} area." + if area == "Easter Eggs": + hint_text = f"{item_name} can be found by collecting Easter Eggs." + else: + hint_text = f"{item_name} can be found in the {area} area." else: player_name = world.multiworld.get_player_name(hint.location.player) @@ -505,10 +508,13 @@ def word_area_hint(world: "WitnessWorld", hinted_area: str, area_items: List[Ite area_progression_word = "Both" if total_progression == 2 else "All" - hint_string = f"In the {hinted_area} area, you will find " + if hinted_area == "Easter Eggs": + hint_string = "Through collecting Easter Eggs, you will find " + else: + hint_string = f"In the {hinted_area} area, you will find " hunt_panels = None - if world.options.victory_condition == "panel_hunt": + if world.options.victory_condition == "panel_hunt" and hinted_area != "Easter Eggs": hunt_panels = sum( static_witness_logic.ENTITIES_BY_HEX[hunt_entity]["area"]["name"] == hinted_area for hunt_entity in world.player_logic.HUNT_ENTITIES diff --git a/worlds/witness/locations.py b/worlds/witness/locations.py index 49a4437c5ab7..e7f6f94d659e 100644 --- a/worlds/witness/locations.py +++ b/worlds/witness/locations.py @@ -19,7 +19,7 @@ class WitnessPlayerLocations: def __init__(self, world: "WitnessWorld", player_logic: WitnessPlayerLogic) -> None: """Defines locations AFTER logic changes due to options""" - self.PANEL_TYPES_TO_SHUFFLE = {"General", "Good Boi"} + self.PANEL_TYPES_TO_SHUFFLE = {"General", "Good Boi", "Easter Egg Total"} self.CHECK_LOCATIONS = static_witness_locations.GENERAL_LOCATIONS.copy() if world.options.shuffle_discarded_panels: diff --git a/worlds/witness/options.py b/worlds/witness/options.py index d739517870a5..c56209b226a4 100644 --- a/worlds/witness/options.py +++ b/worlds/witness/options.py @@ -1,4 +1,6 @@ from dataclasses import dataclass +from datetime import datetime +from typing import Tuple from schema import And, Schema @@ -18,6 +20,7 @@ from .data import static_logic as static_witness_logic from .data.item_definition_classes import ItemCategory, WeightedItemDefinition +from .data.utils import is_easter_time from .entity_hunt import ALL_HUNTABLE_PANELS @@ -142,6 +145,53 @@ class ShuffleEnvironmentalPuzzles(Choice): option_obelisk_sides = 2 +class EasterEggHunt(Choice): + """ + Adds up to 120 Easter Eggs to the game, placed by NewSoupVi, Exempt-Medic, hatkirby, Scipio, and Rever. + These can be collected by simply clicking on them. + + The difficulty options differ by how many Eggs you need to collect for each check and how many are logically required for each check. + + - "Easy": 3 / 8 + - "Normal": 3 / 6 + - "Hard": 4 / 6 + - "Very Hard": 4 / 5 + - "Extreme": 4 / 4 (You are expected to collect every Easter Egg) + + Checks that require more Eggs than logically available still exist, but are excluded. + For example, on "Easy", the "63 Eggs Collected" check can physically be obtained, but would logically require 125 Easter Eggs, which is impossible. Thus, it is excluded. + + On "Easy", "Normal", and "Hard", you will start with an "Egg Radar" that you can activate using the Puzzle Skip key. + On every difficulty except "Extreme", there will be a message when you've collected all Easter Eggs in an area. + On "Easy", there will be an additional message after every Easter Egg telling you how many Easter Eggs are remaining in the area. + + It is recommended that you play this mode together with Door Shuffle. Without it, more than half of the Easter Eggs will be in sphere 1. + """ + + visibility = Visibility.all if is_easter_time() else Visibility.none + + display_name = "Easter Egg Hunt" + option_off = 0 + # Number represents the amount of eggs needed per check + option_easy = 1 + option_normal = 2 + option_hard = 3 + option_very_hard = 4 + option_extreme = 5 + default = 2 if is_easter_time() else 0 + + def get_step_and_logical_step(self) -> Tuple[int, int]: + if self == "easy": + return 3, 8 + if self == "normal": + return 3, 6 + if self == "hard": + return 4, 6 + if self == "very_hard": + return 4, 5 + return 4, 4 + + class ShuffleDog(Choice): """ Adds petting the dog statue in Town into the location pool. @@ -504,6 +554,7 @@ class TheWitnessOptions(PerGameCommonOptions): death_link_amnesty: DeathLinkAmnesty puzzle_randomization_seed: PuzzleRandomizationSeed shuffle_dog: ShuffleDog + easter_egg_hunt: EasterEggHunt witness_option_groups = [ @@ -561,3 +612,13 @@ class TheWitnessOptions(PerGameCommonOptions): ShuffleDog, ]) ] + +# Make sure that Easter Egg Hunt is VERY visible during easter time (when it's enabled by default) +if is_easter_time(): + easter_special_option_group = OptionGroup("EASTER SPECIAL", [ + EasterEggHunt, + ]) + witness_option_groups = [easter_special_option_group, *witness_option_groups] +else: + silly_options_group = next(group for group in witness_option_groups if group.name == "Silly Options") + silly_options_group.options.append(EasterEggHunt) diff --git a/worlds/witness/player_items.py b/worlds/witness/player_items.py index e40d261d8a97..b98c59e9a60a 100644 --- a/worlds/witness/player_items.py +++ b/worlds/witness/player_items.py @@ -31,6 +31,13 @@ class WitnessItem(Item): Item from the game The Witness """ game: str = "The Witness" + eggs: int = 0 + + @classmethod + def make_egg_event(cls, item_name: str, player: int): + ret = cls(item_name, ItemClassification.progression, None, player) + ret.eggs = int(item_name[1:].split(" ", 1)[0]) + return ret class WitnessPlayerItems: diff --git a/worlds/witness/player_logic.py b/worlds/witness/player_logic.py index aea2953abb50..1276d55dce76 100644 --- a/worlds/witness/player_logic.py +++ b/worlds/witness/player_logic.py @@ -24,7 +24,6 @@ from .data.static_logic import StaticWitnessLogicObj from .data.utils import ( WitnessRule, - define_new_region, get_boat, get_caves_except_path_to_challenge_exclusion_list, get_complex_additional_panels, @@ -119,6 +118,8 @@ def __init__(self, world: "WitnessWorld", disabled_locations: Set[str], start_in self.PRE_PICKED_HUNT_ENTITIES: Set[str] = set() self.HUNT_ENTITIES: Set[str] = set() + self.AVAILABLE_EASTER_EGGS: Set[str] = set() + self.AVAILABLE_EASTER_EGGS_PER_REGION: Dict[str, int] = {} self.ALWAYS_EVENT_NAMES_BY_HEX = { "0x00509": "+1 Laser", "0x012FB": "+1 Laser (Unredirected)", @@ -154,6 +155,9 @@ def __init__(self, world: "WitnessWorld", disabled_locations: Set[str], start_in picker = EntityHuntPicker(self, world, self.PRE_PICKED_HUNT_ENTITIES) self.HUNT_ENTITIES = picker.pick_panel_hunt_panels(world.options.panel_hunt_total.value) + if world.options.easter_egg_hunt: + self.finalize_easter_eggs(world) + # Finalize which items actually exist in the MultiWorld and which get grouped into progressive items. self.finalize_items() @@ -241,6 +245,8 @@ def reduce_req_within_region(self, entity_hex: str) -> WitnessRule: if option_entity in {"7 Lasers", "11 Lasers", "7 Lasers + Redirect", "11 Lasers + Redirect", "PP2 Weirdness", "Theater to Tunnels", "Entity Hunt"}: new_items = frozenset({frozenset([option_entity])}) + elif "Eggs" in option_entity: + new_items = frozenset({frozenset([option_entity])}) elif option_entity in self.DISABLE_EVERYTHING_BEHIND: new_items = frozenset() else: @@ -387,13 +393,6 @@ def make_single_adjustment(self, adj_type: str, line: str) -> None: return - if adj_type == "Region Changes": - new_region_and_options = define_new_region(line + ":") - - self.CONNECTIONS_BY_REGION_NAME_THEORETICAL[new_region_and_options[0]["name"]] = new_region_and_options[1] - - return - if adj_type == "New Connections": line_split = line.split(" - ") source_region = line_split[0] @@ -533,6 +532,55 @@ def handle_panelhunt_postgame(self, world: "WitnessWorld") -> List[List[str]]: return postgame_adjustments + def set_easter_egg_requirements(self, world: "WitnessWorld") -> None: + eggs_per_check, logically_required_eggs_per_check = world.options.easter_egg_hunt.get_step_and_logical_step() + + for entity_hex, entity_obj in static_witness_logic.ENTITIES_BY_HEX.items(): + if entity_obj["entityType"] != "Easter Egg Total": + continue + + direct_egg_count = int(entity_obj["checkName"].split(" ")[0]) + + if direct_egg_count % eggs_per_check: + self.COMPLETELY_DISABLED_ENTITIES.add(entity_hex) + + requirement = direct_egg_count // eggs_per_check * logically_required_eggs_per_check + self.DEPENDENT_REQUIREMENTS_BY_HEX[entity_hex] = { + "entities": frozenset({frozenset({f"{requirement} Eggs"})}) + } + + def finalize_easter_eggs(self, world: "WitnessWorld") -> None: + self.AVAILABLE_EASTER_EGGS = { + entity_hex for entity_hex, entity_obj in static_witness_logic.ENTITIES_BY_HEX.items() + if entity_obj["entityType"] == "Easter Egg" and self.solvability_guaranteed(entity_hex) + } + max_eggs = len(self.AVAILABLE_EASTER_EGGS) + + self.AVAILABLE_EASTER_EGGS_PER_REGION = defaultdict(int) + for entity_hex in self.AVAILABLE_EASTER_EGGS: + region_name = static_witness_logic.ENTITIES_BY_HEX[entity_hex]["region"]["name"] + self.AVAILABLE_EASTER_EGGS_PER_REGION[region_name] += 1 + + eggs_per_check, logically_required_eggs_per_check = world.options.easter_egg_hunt.get_step_and_logical_step() + + for entity_hex, entity_obj in static_witness_logic.ENTITIES_BY_HEX.items(): + if entity_obj["entityType"] != "Easter Egg Total": + continue + if entity_hex in self.COMPLETELY_DISABLED_ENTITIES: + continue + + direct_egg_count = int(entity_obj["checkName"].split(" ", 1)[0]) + logically_required_egg_count = direct_egg_count // eggs_per_check * logically_required_eggs_per_check + if direct_egg_count > max_eggs: + self.COMPLETELY_DISABLED_ENTITIES.add(entity_hex) + continue + + self.ADDED_CHECKS.add(entity_obj["checkName"]) + if logically_required_egg_count > max_eggs: + # Exclude and set logic to require every egg + self.EXCLUDED_ENTITIES.add(entity_hex) + self.REQUIREMENTS_BY_HEX[entity_hex] = frozenset({frozenset({f"{max_eggs} Eggs"})}) + def make_options_adjustments(self, world: "WitnessWorld") -> None: """Makes logic adjustments based on options""" adjustment_linesets_in_order = [] @@ -641,6 +689,8 @@ def make_options_adjustments(self, world: "WitnessWorld") -> None: adjustment_linesets_in_order.append([ "New Connections:", "Outside Bunker - Bunker Elevator - TrueOneWay", + "Bunker Elevator Section - Bunker Under Elevator - " + "0x0A079 | Bunker Green Room | Bunker Cyan Room | Bunker Laser Platform | Outside Bunker", ]) if "Swamp Long Bridge" in world.options.elevators_come_to_you: adjustment_linesets_in_order.append([ @@ -655,6 +705,14 @@ def make_options_adjustments(self, world: "WitnessWorld") -> None: # "New Connections:" # "Town Red Rooftop - Town Maze Rooftop - TrueOneWay" + if world.options.easter_egg_hunt: + self.set_easter_egg_requirements(world) + else: + self.COMPLETELY_DISABLED_ENTITIES.update({ + entity_hex for entity_hex, entity_obj in static_witness_logic.ENTITIES_BY_HEX.items() + if "Easter Egg" in entity_obj["entityType"] + }) + if world.options.victory_condition == "panel_hunt": adjustment_linesets_in_order.append(get_entity_hunt()) @@ -691,6 +749,9 @@ def make_options_adjustments(self, world: "WitnessWorld") -> None: if loc_obj["entityType"] == "EP": self.COMPLETELY_DISABLED_ENTITIES.add(loc_obj["entity_hex"]) + if loc_obj["entityType"] == "Easter Egg": + self.COMPLETELY_DISABLED_ENTITIES.add(loc_obj["entity_hex"]) + elif loc_obj["entityType"] == "Panel": self.EXCLUDED_ENTITIES.add(loc_obj["entity_hex"]) @@ -937,6 +998,7 @@ def determine_unrequired_entities(self, world: "WitnessWorld") -> None: doors = world.options.shuffle_doors shortbox_req = world.options.mountain_lasers longbox_req = world.options.challenge_lasers + eggs_exist = world.options.easter_egg_hunt swamp_bridge_comes_to_you = "Swamp Long Bridge" in world.options.elevators_come_to_you quarry_elevator_comes_to_you = "Quarry Elevator" in world.options.elevators_come_to_you @@ -953,17 +1015,17 @@ def determine_unrequired_entities(self, world: "WitnessWorld") -> None: # It is easier to think about when these items *are* required, so we make that dict first # If the entity is disabled anyway, we don't need to consider that case is_item_required_dict = { - "0x03750": eps_shuffled, # Monastery Garden Entry Door + "0x03750": eps_shuffled or eggs_exist, # Monastery Garden Entry Door "0x275FA": eps_shuffled, # Boathouse Hook Control "0x17D02": eps_shuffled, # Windmill Turn Control "0x0368A": symbols_shuffled or door_panels, # Quarry Stoneworks Stairs Door "0x3865F": symbols_shuffled or door_panels or eps_shuffled, # Quarry Boathouse 2nd Barrier "0x17CC4": quarry_elevator_comes_to_you or eps_shuffled, # Quarry Elevator Panel "0x17E2B": swamp_bridge_comes_to_you and boat_shuffled or eps_shuffled, # Swamp Long Bridge - "0x0CF2A": False, # Jungle Monastery Garden Shortcut + "0x0CF2A": eggs_exist, # Jungle Monastery Garden Shortcut "0x0364E": False, # Monastery Laser Shortcut Door "0x03713": remote_doors, # Monastery Laser Shortcut Panel - "0x03313": False, # Orchard Second Gate + "0x03313": eggs_exist, # Orchard Second Gate "0x337FA": remote_doors, # Jungle Bamboo Laser Shortcut Panel "0x3873B": False, # Jungle Bamboo Laser Shortcut Door "0x335AB": False, # Caves Elevator Controls @@ -1026,4 +1088,9 @@ def make_event_panel_lists(self) -> None: entity_name = entity_obj["checkName"] self.EVENT_ITEM_PAIRS[entity_name + " (Panel Hunt)"] = ("+1 Panel Hunt", entity_hex) + for region_name, easter_egg_count in self.AVAILABLE_EASTER_EGGS_PER_REGION.items(): + plural = "s" if easter_egg_count != 1 else "" + event_name = f"+{easter_egg_count} Easter Egg{plural}" + self.EVENT_ITEM_PAIRS[f"{region_name} Easter Egg{plural}"] = (event_name, region_name) + return diff --git a/worlds/witness/regions.py b/worlds/witness/regions.py index a1f7df8a310c..8cb3678ab65d 100644 --- a/worlds/witness/regions.py +++ b/worlds/witness/regions.py @@ -117,12 +117,17 @@ def create_regions(self, world: "WitnessWorld", player_logic: WitnessPlayerLogic event_locations_per_region = defaultdict(dict) for event_location, event_item_and_entity in player_logic.EVENT_ITEM_PAIRS.items(): - region = static_witness_logic.ENTITIES_BY_HEX[event_item_and_entity[1]]["region"] - if region is None: - region_name = "Entry" + entity_or_region = event_item_and_entity[1] + if entity_or_region in static_witness_logic.ALL_REGIONS_BY_NAME: + region_name = entity_or_region + order = -1 else: - region_name = region["name"] - order = self.reference_logic.ENTITIES_BY_HEX[event_item_and_entity[1]]["order"] + region = static_witness_logic.ENTITIES_BY_HEX[event_item_and_entity[1]]["region"] + if region is None: + region_name = "Entry" + else: + region_name = region["name"] + order = self.reference_logic.ENTITIES_BY_HEX[entity_or_region]["order"] event_locations_per_region[region_name][event_location] = order for region_name, region in regions_to_create.items(): diff --git a/worlds/witness/ruff.toml b/worlds/witness/ruff.toml index a35711cce66d..6deccd1343c7 100644 --- a/worlds/witness/ruff.toml +++ b/worlds/witness/ruff.toml @@ -2,7 +2,7 @@ line-length = 120 [lint] select = ["C", "E", "F", "R", "W", "I", "N", "Q", "UP", "RUF", "ISC", "T20"] -ignore = ["C9", "RUF012", "RUF100"] +ignore = ["C9", "RUF012", "RUF021", "RUF100", "UP006", "UP035"] [lint.per-file-ignores] # The way options definitions work right now, I am forced to break line length requirements. diff --git a/worlds/witness/rules.py b/worlds/witness/rules.py index dac1556e46d4..866f4690f5fd 100644 --- a/worlds/witness/rules.py +++ b/worlds/witness/rules.py @@ -196,6 +196,8 @@ def _has_item(item: str, world: "WitnessWorld", if item == "Entity Hunt": # Right now, panel hunt is the only type of entity hunt. This may need to be changed later return _can_do_panel_hunt(world) + if "Eggs" in item: + return SimpleItemRepresentation("Egg", int(item.split(" ")[0])) if item == "PP2 Weirdness": return lambda state: _can_do_expert_pp2(state, world) if item == "Theater to Tunnels": @@ -303,6 +305,11 @@ def make_lambda(entity_hex: str, world: "WitnessWorld") -> Optional[CollectionRu return _meets_item_requirements(entity_req, world) +def make_region_lambda(region_name: str, world: "WitnessWorld") -> CollectionRule: + region = world.get_region(region_name) + return lambda state: region.can_reach(state) + + def set_rules(world: "WitnessWorld") -> None: """ Sets all rules for all locations @@ -312,8 +319,12 @@ def set_rules(world: "WitnessWorld") -> None: real_location = location if location in world.player_locations.EVENT_LOCATION_TABLE: - entity_hex = world.player_logic.EVENT_ITEM_PAIRS[location][1] - real_location = static_witness_logic.ENTITIES_BY_HEX[entity_hex]["checkName"] + entity_hex_or_region_name = world.player_logic.EVENT_ITEM_PAIRS[location][1] + if entity_hex_or_region_name in static_witness_logic.ALL_REGIONS_BY_NAME: + set_rule(world.get_location(location), make_region_lambda(entity_hex_or_region_name, world)) + continue + + real_location = static_witness_logic.ENTITIES_BY_HEX[entity_hex_or_region_name]["checkName"] associated_entity = world.player_logic.REFERENCE_LOGIC.ENTITIES_BY_NAME[real_location] entity_hex = associated_entity["entity_hex"] diff --git a/worlds/witness/test/test_easter_egg_shuffle.py b/worlds/witness/test/test_easter_egg_shuffle.py new file mode 100644 index 000000000000..300d32f97fc6 --- /dev/null +++ b/worlds/witness/test/test_easter_egg_shuffle.py @@ -0,0 +1,155 @@ +from typing import cast + +from BaseClasses import LocationProgressType + +from .. import WitnessWorld +from ..test import WitnessMultiworldTestBase + + +class TestEasterEggShuffle(WitnessMultiworldTestBase): + options_per_world = [ + { + "easter_egg_hunt": "off", + }, + { + "easter_egg_hunt": "easy", + }, + { + "easter_egg_hunt": "normal", + }, + { + "easter_egg_hunt": "hard", + }, + { + "easter_egg_hunt": "very_hard", + }, + { + "easter_egg_hunt": "extreme", + }, + ] + + def test_easter_egg_hunt(self) -> None: + with self.subTest("Test that player without Easter Egg Hunt has no easter egg related locations"): + egg_locations = {location for location in self.multiworld.get_locations(1) if "Egg" in location.name} + self.assertFalse(egg_locations) + + for player, eggs_per_check, logical_eggs_per_check in zip([2, 3, 4, 5, 6], [3, 3, 4, 4, 4], [8, 6, 6, 5, 4]): + world = cast(WitnessWorld, self.multiworld.worlds[player]) + option_name = world.options.easter_egg_hunt + + with self.subTest(f"Test that {option_name} Egg Hunt player starts with 0 eggs"): + self.assertEqual(self.multiworld.state.count("Egg", player), 0) + + with self.subTest(f"Test that the correct Egg Collection locations exist for {option_name} player"): + first_egg_location = f"{eggs_per_check} Easter Eggs Collected" + one_less_location = f"{eggs_per_check - 1} Easter Eggs Collected" + one_more_location = f"{eggs_per_check + 1} Easter Eggs Collected" + self.assert_location_exists(first_egg_location, player) + self.assert_location_does_not_exist(one_less_location, player, strict_check=False) + self.assert_location_does_not_exist(one_more_location, player, strict_check=False) + + one_too_few = logical_eggs_per_check - 1 + with self.subTest(f'Test that "+{one_too_few} Easter Eggs" item adds 4 easter eggs'): + item = world.create_item(f"+{one_too_few} Easter Eggs") + self.multiworld.state.collect(item, prevent_sweep=True) + self.assertEqual(self.multiworld.state.count("Egg", player), one_too_few) + + with self.subTest( + f"Test that {one_too_few} Easter Eggs are not enough for {option_name} player's first location" + ): + self.assertFalse(self.multiworld.state.can_reach_location(first_egg_location, player)) + + with self.subTest( + f"Test that {logical_eggs_per_check} Easter Eggs are enough for {option_name} player's first location" + ): + item = world.create_item("+1 Easter Egg") + self.multiworld.state.collect(item, prevent_sweep=True) + self.assertTrue(self.multiworld.state.can_reach_location(first_egg_location, player)) + + +class TestEggRestrictions(WitnessMultiworldTestBase): + options_per_world = [ + { + "shuffle_postgame": False, + }, + { + "shuffle_postgame": True, + }, + { + "shuffle_postgame": True, + "exclude_locations": frozenset({"Bunker Easter Egg 3"}), + } + ] + + common_options = { + "victory_condition": "mountain_box_short", + "shuffle_doors": "off", + "easter_egg_hunt": "very_hard", + "shuffle_vault_boxes": True, + } + + def test_egg_restrictions(self) -> None: + with self.subTest("Test that locations beyond 108 Easter Eggs don't exist for a seed without Mountain"): + self.assert_location_exists("108 Easter Eggs Collected", 1) + self.assert_location_does_not_exist("112 Easter Eggs Collected", 1) + + with self.subTest( + "Test that locations beyond 86 Easter Eggs, which would logically require more than 108 Eggs, are excluded" + ): + egg_84_location = self.multiworld.get_location("84 Easter Eggs Collected", 1) + egg_88_location = self.multiworld.get_location("88 Easter Eggs Collected", 1) + + self.assertNotEqual(egg_84_location.progress_type, LocationProgressType.EXCLUDED) + self.assertEqual(egg_88_location.progress_type, LocationProgressType.EXCLUDED) + + with self.subTest("Test that in a seed with the whole game included, the 120 egg location exists"): + self.assert_location_exists("120 Easter Eggs Collected", 2) + + with self.subTest( + "Test that locations beyond 96 Easter Eggs, which would logically require more than 120 Eggs, are excluded" + ): + egg_96_location = self.multiworld.get_location("96 Easter Eggs Collected", 2) + egg_100_location = self.multiworld.get_location("100 Easter Eggs Collected", 2) + + self.assertNotEqual(egg_96_location.progress_type, LocationProgressType.EXCLUDED) + self.assertEqual(egg_100_location.progress_type, LocationProgressType.EXCLUDED) + + with self.subTest("Test that you can exclude and egg to disable it"): + self.assert_location_exists("116 Easter Eggs Collected", 3) + self.assert_location_does_not_exist("120 Easter Eggs Collected", 3) + + +class TestBunkerElevatorEgg(WitnessMultiworldTestBase): + options_per_world = [ + { + "elevators_come_to_you": frozenset() + }, + { + "elevators_come_to_you": frozenset({"Bunker Elevator"}) + }, + ] + + common_options = { + "easter_egg_hunt": "normal", + "shuffle_doors": "panels", + "shuffle_symbols": False, + } + + def test_bunker_elevator_egg(self) -> None: + items_to_reach_bunker_elevator = [ + "Bunker Entry (Panel)", + "Bunker Tinted Glass Door (Panel)", + "Bunker Drop-Down Door Controls (Panel)" + ] + + with self.subTest("Test that normally, the egg behind the elevator needs Elevator Control"): + self.assertFalse(self.multiworld.state.can_reach_location("Bunker Under Elevator Easter Egg", 1)) + self.collect_by_name(items_to_reach_bunker_elevator, 1) + self.assertFalse(self.multiworld.state.can_reach_location("Bunker Under Elevator Easter Egg", 1)) + self.collect_by_name(["Bunker Elevator Control (Panel)"], 1) + self.assertTrue(self.multiworld.state.can_reach_location("Bunker Under Elevator Easter Egg", 1)) + + with self.subTest("Test that with auto-elevators, the egg behind the elevator doesn't need Elevator Control"): + self.assertFalse(self.multiworld.state.can_reach_location("Bunker Under Elevator Easter Egg", 2)) + self.collect_by_name(items_to_reach_bunker_elevator, 2) + self.assertTrue(self.multiworld.state.can_reach_location("Bunker Under Elevator Easter Egg", 2)) From 61afe76eae7419cdab096dad642fd55ef80b0cd1 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 8 Mar 2025 00:45:52 +0000 Subject: [PATCH 0169/1218] DS3: Remove the outdated French translation of the setup docs (#4700) This was causing confusion and Discord support requests because the instructions there are no longer compatible with the latest version of Archipelago. This also lists me as the primary author of the new setup guide. --- worlds/dark_souls_3/__init__.py | 13 ++--------- worlds/dark_souls_3/docs/setup_fr.md | 33 ---------------------------- 2 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 worlds/dark_souls_3/docs/setup_fr.md diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index e1787a9a44aa..b9f32a8d4015 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -25,19 +25,10 @@ class DarkSouls3Web(WebWorld): "English", "setup_en.md", "setup/en", - ["Marech"] + ["Natalie", "Marech"] ) - setup_fr = Tutorial( - setup_en.tutorial_name, - setup_en.description, - "Français", - "setup_fr.md", - "setup/fr", - ["Marech"] - ) - - tutorials = [setup_en, setup_fr] + tutorials = [setup_en] option_groups = option_groups item_descriptions = item_descriptions rich_text_options_doc = True diff --git a/worlds/dark_souls_3/docs/setup_fr.md b/worlds/dark_souls_3/docs/setup_fr.md deleted file mode 100644 index ea4d8f818604..000000000000 --- a/worlds/dark_souls_3/docs/setup_fr.md +++ /dev/null @@ -1,33 +0,0 @@ -# Guide d'installation de Dark Souls III Randomizer - -## Logiciels requis - -- [Dark Souls III](https://store.steampowered.com/app/374320/DARK_SOULS_III/) -- [Client AP de Dark Souls III](https://github.com/Marechal-L/Dark-Souls-III-Archipelago-client/releases) - -## Concept général - -Le client Archipelago de Dark Souls III est un fichier dinput8.dll. Cette .dll va lancer une invite de commande Windows -permettant de lire des informations de la partie et écrire des commandes pour intéragir avec le serveur Archipelago. - -## Procédures d'installation - - -**Il y a des risques de bannissement permanent des serveurs FromSoftware si ce mod est utilisé en ligne.** - -Ce client a été testé sur la version Steam officielle du jeu (v1.15/1.35), peu importe les DLCs actuellement installés. - -Télécharger le fichier dinput8.dll disponible dans le [Client AP de Dark Souls III](https://github.com/Marechal-L/Dark-Souls-III-Archipelago-client/releases) et -placez-le à la racine du jeu (ex: "SteamLibrary\steamapps\common\DARK SOULS III\Game") - -## Rejoindre une partie Multiworld - -1. Lancer DarkSoulsIII.exe ou lancer le jeu depuis Steam -2. Ecrire "/connect {SERVER_IP}:{SERVER_PORT} {SLOT_NAME}" dans l'invite de commande Windows ouverte au lancement du jeu -3. Une fois connecté, créez une nouvelle partie, choisissez une classe et attendez que les autres soient prêts avant de lancer -4. Vous pouvez quitter et lancer le jeu n'importe quand pendant une partie - -## Où trouver le fichier de configuration ? - -La [Page de configuration](/games/Dark%20Souls%20III/player-options) sur le site vous permez de configurer vos -paramètres et de les exporter sous la forme d'un fichier. From 113259bc1546ec648b4d1780ec79e6c7b53f11f8 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:17:45 -0500 Subject: [PATCH 0170/1218] Update links (#4690) * Update links * Update two more --- docs/tests.md | 4 ++-- docs/world api.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tests.md b/docs/tests.md index c8655ccf3f4d..e7f400423621 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -73,11 +73,11 @@ When tests are run, this class will create a multiworld with a single player hav generic tests, as well as the new custom test. Each test method definition will create its own separate solo multiworld that will be cleaned up after. If you don't want to run the generic tests on a base, `run_default_tests` can be overridden. For more information on what methods are available to your class, check the -[WorldTestBase definition](/test/bases.py#L104). +[WorldTestBase definition](/test/bases.py#L106). #### Alternatives to WorldTestBase -Unit tests can also be created using [TestBase](/test/bases.py#L14) or +Unit tests can also be created using [TestBase](/test/bases.py#L16) or [unittest.TestCase](https://docs.python.org/3/library/unittest.html#unittest.TestCase) depending on your use case. These may be useful for generating a multiworld under very specific constraints without using the generic world setup, or for testing portions of your code that can be tested without relying on a multiworld to be created first. diff --git a/docs/world api.md b/docs/world api.md index 6a45ccbf99dc..9e3fe67b4fbb 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -291,7 +291,7 @@ like entrance randomization in logic. Regions have a list called `exits`, containing `Entrance` objects representing transitions to other regions. -There must be one special region (Called "Menu" by default, but configurable using [origin_region_name](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/AutoWorld.py#L295-L296)), +There must be one special region (Called "Menu" by default, but configurable using [origin_region_name](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/AutoWorld.py#L298-L299)), from which the logic unfolds. AP assumes that a player will always be able to return to this starting region by resetting the game ("Save and quit"). ### Entrances @@ -331,7 +331,7 @@ Even doing `state.can_reach_location` or `state.can_reach_entrance` is problemat You can use `multiworld.register_indirect_condition(region, entrance)` to explicitly tell the generator that, when a given region becomes accessible, it is necessary to re-check a specific entrance. You **must** use `multiworld.register_indirect_condition` if you perform this kind of `can_reach` from an entrance access rule, unless you have a **very** good technical understanding of the relevant code and can reason why it will never lead to problems in your case. -Alternatively, you can set [world.explicit_indirect_conditions = False](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/AutoWorld.py#L298-L301), +Alternatively, you can set [world.explicit_indirect_conditions = False](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/AutoWorld.py#L301-L304), avoiding the need for indirect conditions at the expense of performance. ### Item Rules From 3e08acf381f31c41e6cc45bca248758f272fd62e Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 8 Mar 2025 12:26:59 +0100 Subject: [PATCH 0171/1218] The Witness: Move local_items code earlier #4696 --- worlds/witness/__init__.py | 7 +++---- worlds/witness/player_items.py | 5 ++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/worlds/witness/__init__.py b/worlds/witness/__init__.py index 3bf3661bc12a..80ef996a0e4a 100644 --- a/worlds/witness/__init__.py +++ b/worlds/witness/__init__.py @@ -156,8 +156,9 @@ def generate_early(self) -> None: self.determine_sufficient_progression() - if self.options.shuffle_lasers == "local": - self.options.local_items.value |= self.item_name_groups["Lasers"] + for item_name, item_data in self.player_items.item_data.items(): + if item_data.local_only: + self.options.local_items.value.add(item_name) if self.options.victory_condition == "panel_hunt": total_panels = self.options.panel_hunt_total @@ -323,8 +324,6 @@ def create_items(self) -> None: self.own_itempool += new_items self.multiworld.itempool += new_items - if self.player_items.item_data[item_name].local_only: - self.options.local_items.value.add(item_name) def fill_slot_data(self) -> Dict[str, Any]: already_hinted_locations = set() diff --git a/worlds/witness/player_items.py b/worlds/witness/player_items.py index b98c59e9a60a..7b71e3c1f933 100644 --- a/worlds/witness/player_items.py +++ b/worlds/witness/player_items.py @@ -65,7 +65,7 @@ def __init__(self, world: "WitnessWorld", player_logic: WitnessPlayerLogic, or name in player_logic.PROGRESSION_ITEMS_ACTUALLY_IN_THE_GAME } - # Downgrade door items + # Downgrade door items and make lasers local if local lasers is on for item_name, item_data in self.item_data.items(): if not isinstance(item_data.definition, DoorItemDefinition): continue @@ -73,6 +73,9 @@ def __init__(self, world: "WitnessWorld", player_logic: WitnessPlayerLogic, if all(not self._logic.solvability_guaranteed(e_hex) for e_hex in item_data.definition.panel_id_hexes): item_data.classification = ItemClassification.useful + if item_data.definition.category == ItemCategory.LASER and self._world.options.shuffle_lasers == "local": + item_data.local_only = True + # Build the mandatory item list. self._mandatory_items: Dict[str, int] = {} From 9c579762524ac121cb089d80a3bf90ab99b84814 Mon Sep 17 00:00:00 2001 From: kbranch Date: Sat, 8 Mar 2025 07:32:45 -0500 Subject: [PATCH 0172/1218] LADX: Autotracker improvements (#4445) * Expand and validate the RAM cache * Part way through location improvement * Fixed location tracking * Preliminary entrance tracking support * Actually send entrance messages * Store found entrances on the server * Bit of cleanup * Added rupee count, items linked to checks * Send Magpie a handshAck * Got my own version wrong * Remove the Beta name * Only send slot_data if there's something in it * Ask the server for entrance updates * Small fix to stabilize Link's location when changing rooms * Oops, server storage is shared between worlds * Deal with null responses from the server * Added UNUSED_KEY item --- LinksAwakeningClient.py | 136 ++++++++++++--- worlds/ladx/GpsTracker.py | 310 +++++++++++++++++++++++++++-------- worlds/ladx/ItemTracker.py | 46 ++++-- worlds/ladx/Tracker.py | 81 +++++++-- worlds/ladx/TrackerConsts.py | 291 ++++++++++++++++++++++++++++++++ 5 files changed, 753 insertions(+), 111 deletions(-) create mode 100644 worlds/ladx/TrackerConsts.py diff --git a/LinksAwakeningClient.py b/LinksAwakeningClient.py index e2e16922fa95..ff932e7c76fa 100644 --- a/LinksAwakeningClient.py +++ b/LinksAwakeningClient.py @@ -28,6 +28,7 @@ from NetUtils import ClientStatus from worlds.ladx.Common import BASE_ID as LABaseID from worlds.ladx.GpsTracker import GpsTracker +from worlds.ladx.TrackerConsts import storage_key from worlds.ladx.ItemTracker import ItemTracker from worlds.ladx.LADXR.checkMetadata import checkMetadataTable from worlds.ladx.Locations import get_locations_to_id, meta_to_name @@ -100,19 +101,23 @@ class LAClientConstants: WRamCheckSize = 0x4 WRamSafetyValue = bytearray([0]*WRamCheckSize) + wRamStart = 0xC000 + hRamStart = 0xFF80 + hRamSize = 0x80 + MinGameplayValue = 0x06 MaxGameplayValue = 0x1A VictoryGameplayAndSub = 0x0102 - class RAGameboy(): cache = [] - cache_start = 0 - cache_size = 0 last_cache_read = None socket = None def __init__(self, address, port) -> None: + self.cache_start = LAClientConstants.wRamStart + self.cache_size = LAClientConstants.hRamStart + LAClientConstants.hRamSize - LAClientConstants.wRamStart + self.address = address self.port = port self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) @@ -131,9 +136,14 @@ async def get_retroarch_version(self): async def get_retroarch_status(self): return await self.send_command("GET_STATUS") - def set_cache_limits(self, cache_start, cache_size): - self.cache_start = cache_start - self.cache_size = cache_size + def set_checks_range(self, checks_start, checks_size): + self.checks_start = checks_start + self.checks_size = checks_size + + def set_location_range(self, location_start, location_size, critical_addresses): + self.location_start = location_start + self.location_size = location_size + self.critical_location_addresses = critical_addresses def send(self, b): if type(b) is str: @@ -188,21 +198,57 @@ async def update_cache(self): if not await self.check_safe_gameplay(): return - cache = [] - remaining_size = self.cache_size - while remaining_size: - block = await self.async_read_memory(self.cache_start + len(cache), remaining_size) - remaining_size -= len(block) - cache += block + attempts = 0 + while True: + # RA doesn't let us do an atomic read of a large enough block of RAM + # Some bytes can't change in between reading location_block and hram_block + location_block = await self.read_memory_block(self.location_start, self.location_size) + hram_block = await self.read_memory_block(LAClientConstants.hRamStart, LAClientConstants.hRamSize) + verification_block = await self.read_memory_block(self.location_start, self.location_size) + + valid = True + for address in self.critical_location_addresses: + if location_block[address - self.location_start] != verification_block[address - self.location_start]: + valid = False + + if valid: + break + + attempts += 1 + + # Shouldn't really happen, but keep it from choking + if attempts > 5: + return + + checks_block = await self.read_memory_block(self.checks_start, self.checks_size) if not await self.check_safe_gameplay(): return - self.cache = cache + self.cache = bytearray(self.cache_size) + + start = self.checks_start - self.cache_start + self.cache[start:start + len(checks_block)] = checks_block + + start = self.location_start - self.cache_start + self.cache[start:start + len(location_block)] = location_block + + start = LAClientConstants.hRamStart - self.cache_start + self.cache[start:start + len(hram_block)] = hram_block + self.last_cache_read = time.time() + + async def read_memory_block(self, address: int, size: int): + block = bytearray() + remaining_size = size + while remaining_size: + chunk = await self.async_read_memory(address + len(block), remaining_size) + remaining_size -= len(chunk) + block += chunk + + return block async def read_memory_cache(self, addresses): - # TODO: can we just update once per frame? if not self.last_cache_read or self.last_cache_read + 0.1 < time.time(): await self.update_cache() if not self.cache: @@ -359,11 +405,12 @@ async def reset_auth(self): auth = binascii.hexlify(await self.gameboy.async_read_memory(0x0134, 12)).decode() self.auth = auth - async def wait_and_init_tracker(self): + async def wait_and_init_tracker(self, magpie: MagpieBridge): await self.wait_for_game_ready() self.tracker = LocationTracker(self.gameboy) self.item_tracker = ItemTracker(self.gameboy) self.gps_tracker = GpsTracker(self.gameboy) + magpie.gps_tracker = self.gps_tracker async def recved_item_from_ap(self, item_id, from_player, next_index): # Don't allow getting an item until you've got your first check @@ -405,9 +452,11 @@ async def is_victory(self): return (await self.gameboy.read_memory_cache([LAClientConstants.wGameplayType]))[LAClientConstants.wGameplayType] == 1 async def main_tick(self, item_get_cb, win_cb, deathlink_cb): + await self.gameboy.update_cache() await self.tracker.readChecks(item_get_cb) await self.item_tracker.readItems() await self.gps_tracker.read_location() + await self.gps_tracker.read_entrances() current_health = (await self.gameboy.read_memory_cache([LAClientConstants.wLinkHealth]))[LAClientConstants.wLinkHealth] if self.deathlink_debounce and current_health != 0: @@ -465,6 +514,10 @@ class LinksAwakeningContext(CommonContext): magpie_task = None won = False + @property + def slot_storage_key(self): + return f"{self.slot_info[self.slot].name}_{storage_key}" + def __init__(self, server_address: typing.Optional[str], password: typing.Optional[str], magpie: typing.Optional[bool]) -> None: self.client = LinksAwakeningClient() self.slot_data = {} @@ -507,7 +560,19 @@ def set_center(_, center): self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI") async def send_checks(self): - message = [{"cmd": 'LocationChecks', "locations": self.found_checks}] + message = [{"cmd": "LocationChecks", "locations": self.found_checks}] + await self.send_msgs(message) + + async def send_new_entrances(self, entrances: typing.Dict[str, str]): + # Store the entrances we find on the server for future sessions + message = [{ + "cmd": "Set", + "key": self.slot_storage_key, + "default": {}, + "want_reply": False, + "operations": [{"operation": "update", "value": entrances}], + }] + await self.send_msgs(message) had_invalid_slot_data = None @@ -536,6 +601,12 @@ async def send_victory(self): logger.info("victory!") await self.send_msgs(message) self.won = True + + async def request_found_entrances(self): + await self.send_msgs([{"cmd": "Get", "keys": [self.slot_storage_key]}]) + + # Ask for updates so that players can co-op entrances in a seed + await self.send_msgs([{"cmd": "SetNotify", "keys": [self.slot_storage_key]}]) async def on_deathlink(self, data: typing.Dict[str, typing.Any]) -> None: if self.ENABLE_DEATHLINK: @@ -576,6 +647,12 @@ def on_package(self, cmd: str, args: dict): if cmd == "ReceivedItems": for index, item in enumerate(args["items"], start=args["index"]): self.client.recvd_checks[index] = item + + if cmd == "Retrieved" and self.magpie_enabled and self.slot_storage_key in args["keys"]: + self.client.gps_tracker.receive_found_entrances(args["keys"][self.slot_storage_key]) + + if cmd == "SetReply" and self.magpie_enabled and args["key"] == self.slot_storage_key: + self.client.gps_tracker.receive_found_entrances(args["value"]) async def sync(self): sync_msg = [{'cmd': 'Sync'}] @@ -589,6 +666,12 @@ def on_item_get(ladxr_checks): checkMetadataTable[check.id])] for check in ladxr_checks] self.new_checks(checks, [check.id for check in ladxr_checks]) + for check in ladxr_checks: + if check.value and check.linkedItem: + linkedItem = check.linkedItem + if 'condition' not in linkedItem or linkedItem['condition'](self.slot_data): + self.client.item_tracker.setExtraItem(check.linkedItem['item'], check.linkedItem['qty']) + async def victory(): await self.send_victory() @@ -622,12 +705,20 @@ async def deathlink(): if not self.client.recvd_checks: await self.sync() - await self.client.wait_and_init_tracker() + await self.client.wait_and_init_tracker(self.magpie) + min_tick_duration = 0.1 + last_tick = time.time() while True: await self.client.main_tick(on_item_get, victory, deathlink) - await asyncio.sleep(0.1) + now = time.time() + tick_duration = now - last_tick + sleep_duration = max(min_tick_duration - tick_duration, 0) + await asyncio.sleep(sleep_duration) + + last_tick = now + if self.last_resend + 5.0 < now: self.last_resend = now await self.send_checks() @@ -635,8 +726,15 @@ async def deathlink(): try: self.magpie.set_checks(self.client.tracker.all_checks) await self.magpie.set_item_tracker(self.client.item_tracker) - await self.magpie.send_gps(self.client.gps_tracker) self.magpie.slot_data = self.slot_data + + if self.client.gps_tracker.needs_found_entrances: + await self.request_found_entrances() + self.client.gps_tracker.needs_found_entrances = False + + new_entrances = await self.magpie.send_gps(self.client.gps_tracker) + if new_entrances: + await self.send_new_entrances(new_entrances) except Exception: # Don't let magpie errors take out the client pass diff --git a/worlds/ladx/GpsTracker.py b/worlds/ladx/GpsTracker.py index 1ea465eb162c..d98acf71b4a1 100644 --- a/worlds/ladx/GpsTracker.py +++ b/worlds/ladx/GpsTracker.py @@ -1,92 +1,266 @@ import json -roomAddress = 0xFFF6 -mapIdAddress = 0xFFF7 -indoorFlagAddress = 0xDBA5 -entranceRoomOffset = 0xD800 -screenCoordAddress = 0xFFFA - -mapMap = { - 0x00: 0x01, - 0x01: 0x01, - 0x02: 0x01, - 0x03: 0x01, - 0x04: 0x01, - 0x05: 0x01, - 0x06: 0x02, - 0x07: 0x02, - 0x08: 0x02, - 0x09: 0x02, - 0x0A: 0x02, - 0x0B: 0x02, - 0x0C: 0x02, - 0x0D: 0x02, - 0x0E: 0x02, - 0x0F: 0x02, - 0x10: 0x02, - 0x11: 0x02, - 0x12: 0x02, - 0x13: 0x02, - 0x14: 0x02, - 0x15: 0x02, - 0x16: 0x02, - 0x17: 0x02, - 0x18: 0x02, - 0x19: 0x02, - 0x1D: 0x01, - 0x1E: 0x01, - 0x1F: 0x01, - 0xFF: 0x03, -} +import typing +from websockets import WebSocketServerProtocol + +from . import TrackerConsts as Consts +from .TrackerConsts import EntranceCoord +from .LADXR.entranceInfo import ENTRANCE_INFO + +class Entrance: + outdoor_room: int + indoor_map: int + indoor_address: int + name: str + other_side_name: str = None + changed: bool = False + known_to_server: bool = False + + def __init__(self, outdoor: int, indoor: int, name: str, indoor_address: int=None): + self.outdoor_room = outdoor + self.indoor_map = indoor + self.indoor_address = indoor_address + self.name = name + + def map(self, other_side: str, known_to_server: bool = False): + if other_side != self.other_side_name: + self.changed = True + self.known_to_server = known_to_server + + self.other_side_name = other_side class GpsTracker: - room = None - location_changed = False - screenX = 0 - screenY = 0 - indoors = None + room: int = None + last_room: int = None + last_different_room: int = None + room_same_for: int = 0 + room_changed: bool = False + screen_x: int = 0 + screen_y: int = 0 + spawn_x: int = 0 + spawn_y: int = 0 + indoors: int = None + indoors_changed: bool = False + spawn_map: int = None + spawn_room: int = None + spawn_changed: bool = False + spawn_same_for: int = 0 + entrance_mapping: typing.Dict[str, str] = None + entrances_by_name: typing.Dict[str, Entrance] = {} + needs_found_entrances: bool = False + needs_slot_data: bool = True def __init__(self, gameboy) -> None: self.gameboy = gameboy - async def read_byte(self, b): - return (await self.gameboy.async_read_memory(b))[0] + self.gameboy.set_location_range( + Consts.link_motion_state, + Consts.transition_sequence - Consts.link_motion_state + 1, + [Consts.transition_state] + ) + + async def read_byte(self, b: int): + return (await self.gameboy.read_memory_cache([b]))[b] + + def load_slot_data(self, slot_data: typing.Dict[str, typing.Any]): + if 'entrance_mapping' not in slot_data: + return + + # We need to know how entrances were mapped at generation before we can autotrack them + self.entrance_mapping = {} + + # Convert to upstream's newer format + for outside, inside in slot_data['entrance_mapping'].items(): + new_inside = f"{inside}:inside" + self.entrance_mapping[outside] = new_inside + self.entrance_mapping[new_inside] = outside + + self.entrances_by_name = {} + + for name, info in ENTRANCE_INFO.items(): + alternate_address = ( + Consts.entrance_address_overrides[info.target] + if info.target in Consts.entrance_address_overrides + else None + ) + + entrance = Entrance(info.room, info.target, name, alternate_address) + self.entrances_by_name[name] = entrance + + inside_entrance = Entrance(info.target, info.room, f"{name}:inside", alternate_address) + self.entrances_by_name[f"{name}:inside"] = inside_entrance + + self.needs_slot_data = False + self.needs_found_entrances = True async def read_location(self): - indoors = await self.read_byte(indoorFlagAddress) + # We need to wait for screen transitions to finish + transition_state = await self.read_byte(Consts.transition_state) + transition_target_x = await self.read_byte(Consts.transition_target_x) + transition_target_y = await self.read_byte(Consts.transition_target_y) + transition_scroll_x = await self.read_byte(Consts.transition_scroll_x) + transition_scroll_y = await self.read_byte(Consts.transition_scroll_y) + transition_sequence = await self.read_byte(Consts.transition_sequence) + motion_state = await self.read_byte(Consts.link_motion_state) + if (transition_state != 0 + or transition_target_x != transition_scroll_x + or transition_target_y != transition_scroll_y + or transition_sequence != 0x04): + return + + indoors = await self.read_byte(Consts.indoor_flag) if indoors != self.indoors and self.indoors != None: - self.indoorsChanged = True - + self.indoors_changed = True + self.indoors = indoors - mapId = await self.read_byte(mapIdAddress) - if mapId not in mapMap: - print(f'Unknown map ID {hex(mapId)}') + # We use the spawn point to know which entrance was most recently entered + spawn_map = await self.read_byte(Consts.spawn_map) + map_digit = Consts.map_map[spawn_map] << 8 if self.spawn_map else 0 + spawn_room = await self.read_byte(Consts.spawn_room) + map_digit + spawn_x = await self.read_byte(Consts.spawn_x) + spawn_y = await self.read_byte(Consts.spawn_y) + + # The spawn point needs to be settled before we can trust location data + if ((spawn_room != self.spawn_room and self.spawn_room != None) + or (spawn_map != self.spawn_map and self.spawn_map != None) + or (spawn_x != self.spawn_x and self.spawn_x != None) + or (spawn_y != self.spawn_y and self.spawn_y != None)): + self.spawn_changed = True + self.spawn_same_for = 0 + else: + self.spawn_same_for += 1 + + self.spawn_map = spawn_map + self.spawn_room = spawn_room + self.spawn_x = spawn_x + self.spawn_y = spawn_y + + # Spawn point is preferred, but doesn't work for the sidescroller entrances + # Those can be addressed by keeping track of which room we're in + # Also used to validate that we came from the right room for what the spawn point is mapped to + map_id = await self.read_byte(Consts.map_id) + if map_id not in Consts.map_map: + print(f'Unknown map ID {hex(map_id)}') + return + + map_digit = Consts.map_map[map_id] << 8 if indoors else 0 + self.last_room = self.room + self.room = await self.read_byte(Consts.room) + map_digit + + # Again, the room needs to settle before we can trust location data + if self.last_room != self.room: + self.room_same_for = 0 + self.room_changed = True + self.last_different_room = self.last_room + else: + self.room_same_for += 1 + + # Only update Link's location when he's not in the air to avoid weirdness + if motion_state in [0, 1]: + coords = await self.read_byte(Consts.screen_coord) + self.screen_x = coords & 0x0F + self.screen_y = (coords & 0xF0) >> 4 + + async def read_entrances(self): + if not self.last_different_room or not self.entrance_mapping: return - mapDigit = mapMap[mapId] << 8 if indoors else 0 - last_room = self.room - self.room = await self.read_byte(roomAddress) + mapDigit + if self.spawn_changed and self.spawn_same_for > 0 and self.room_same_for > 0: + # Use the spawn location, last room, and entrance mapping at generation to map the right entrance + # A bit overkill for simple ER, but necessary for upstream's advanced ER + spawn_coord = EntranceCoord(None, self.spawn_room, self.spawn_x, self.spawn_y) + if str(spawn_coord) in Consts.entrance_lookup: + valid_sources = {x.name for x in Consts.entrance_coords if x.room == self.last_different_room} + dest_entrance = Consts.entrance_lookup[str(spawn_coord)].name + source_entrance = [ + x for x in self.entrance_mapping + if self.entrance_mapping[x] == dest_entrance and x in valid_sources + ] + + if source_entrance: + self.entrances_by_name[source_entrance[0]].map(dest_entrance) + + self.spawn_changed = False + elif self.room_changed and self.room_same_for > 0: + # Check for the stupid sidescroller rooms that don't set your spawn point + if self.last_different_room in Consts.sidescroller_rooms: + source_entrance = Consts.sidescroller_rooms[self.last_different_room] + if source_entrance in self.entrance_mapping: + dest_entrance = self.entrance_mapping[source_entrance] + + expected_room = self.entrances_by_name[dest_entrance].outdoor_room + if dest_entrance.endswith(":indoor"): + expected_room = self.entrances_by_name[dest_entrance].indoor_map + + if expected_room == self.room: + self.entrances_by_name[source_entrance].map(dest_entrance) + + if self.room in Consts.sidescroller_rooms: + valid_sources = {x.name for x in Consts.entrance_coords if x.room == self.last_different_room} + dest_entrance = Consts.sidescroller_rooms[self.room] + source_entrance = [ + x for x in self.entrance_mapping + if self.entrance_mapping[x] == dest_entrance and x in valid_sources + ] - coords = await self.read_byte(screenCoordAddress) - self.screenX = coords & 0x0F - self.screenY = (coords & 0xF0) >> 4 + if source_entrance: + self.entrances_by_name[source_entrance[0]].map(dest_entrance) - if (self.room != last_room): - self.location_changed = True - - last_message = {} - async def send_location(self, socket, diff=False): - if self.room is None: + self.room_changed = False + + last_location_message = {} + async def send_location(self, socket: WebSocketServerProtocol) -> None: + if self.room is None or self.room_same_for < 1: return + message = { "type":"location", "refresh": True, - "version":"1.0", "room": f'0x{self.room:02X}', - "x": self.screenX, - "y": self.screenY, + "x": self.screen_x, + "y": self.screen_y, + "drawFine": True, } - if message != self.last_message: - self.last_message = message + + if message != self.last_location_message: + self.last_location_message = message await socket.send(json.dumps(message)) + + async def send_entrances(self, socket: WebSocketServerProtocol, diff: bool=True) -> typing.Dict[str, str]: + if not self.entrance_mapping: + return + + new_entrances = [x for x in self.entrances_by_name.values() if x.changed or (not diff and x.other_side_name)] + + if not new_entrances: + return + + message = { + "type":"entrance", + "refresh": True, + "diff": True, + "entranceMap": {}, + } + + for entrance in new_entrances: + message['entranceMap'][entrance.name] = entrance.other_side_name + entrance.changed = False + + await socket.send(json.dumps(message)) + + new_to_server = { + entrance.name: entrance.other_side_name + for entrance in new_entrances + if not entrance.known_to_server + } + + return new_to_server + + def receive_found_entrances(self, found_entrances: typing.Dict[str, str]): + if not found_entrances: + return + + for entrance, destination in found_entrances.items(): + if entrance in self.entrances_by_name: + self.entrances_by_name[entrance].map(destination, known_to_server=True) diff --git a/worlds/ladx/ItemTracker.py b/worlds/ladx/ItemTracker.py index 92ef71633e0f..b288bba84339 100644 --- a/worlds/ladx/ItemTracker.py +++ b/worlds/ladx/ItemTracker.py @@ -1,12 +1,16 @@ import json -gameStateAddress = 0xDB95 -validGameStates = {0x0B, 0x0C} -gameStateResetThreshold = 0x06 inventorySlotCount = 16 inventoryStartAddress = 0xDB00 inventoryEndAddress = inventoryStartAddress + inventorySlotCount +rupeesHigh = 0xDB5D +rupeesLow = 0xDB5E +addRupeesHigh = 0xDB8F +addRupeesLow = 0xDB90 +removeRupeesHigh = 0xDB91 +removeRupeesLow = 0xDB92 + inventoryItemIds = { 0x02: 'BOMB', 0x05: 'BOW', @@ -98,10 +102,11 @@ 'STONE_BEAK{}': 2, 'NIGHTMARE_KEY{}': 3, 'KEY{}': 4, + 'UNUSED_KEY{}': 4, } class Item: - def __init__(self, id, address, threshold=0, mask=None, increaseOnly=False, count=False, max=None): + def __init__(self, id, address, threshold=0, mask=None, increaseOnly=False, count=False, max=None, encodedCount=True): self.id = id self.address = address self.threshold = threshold @@ -112,6 +117,7 @@ def __init__(self, id, address, threshold=0, mask=None, increaseOnly=False, coun self.rawValue = 0 self.diff = 0 self.max = max + self.encodedCount = encodedCount def set(self, byte, extra): oldValue = self.value @@ -121,7 +127,7 @@ def set(self, byte, extra): if not self.count: byte = int(byte > self.threshold) - else: + elif self.encodedCount: # LADX seems to store one decimal digit per nibble byte = byte - (byte // 16 * 6) @@ -165,6 +171,7 @@ def loadItems(self): Item('BOOMERANG', None), Item('TOADSTOOL', None), Item('ROOSTER', None), + Item('RUPEE_COUNT', None, count=True, encodedCount=False), Item('SWORD', 0xDB4E, count=True), Item('POWER_BRACELET', 0xDB43, count=True), Item('SHIELD', 0xDB44, count=True), @@ -219,9 +226,9 @@ def loadItems(self): self.itemDict = {item.id: item for item in self.items} - async def readItems(state): - extraItems = state.extraItems - missingItems = {x for x in state.items if x.address == None} + async def readItems(self): + extraItems = self.extraItems + missingItems = {x for x in self.items if x.address == None and x.id != 'RUPEE_COUNT'} # Add keys for opened key doors for i in range(len(dungeonKeyDoors)): @@ -230,16 +237,16 @@ async def readItems(state): for address, masks in dungeonKeyDoors[i].items(): for mask in masks: - value = await state.readRamByte(address) & mask + value = await self.readRamByte(address) & mask if value > 0: extraItems[item] += 1 # Main inventory items for i in range(inventoryStartAddress, inventoryEndAddress): - value = await state.readRamByte(i) + value = await self.readRamByte(i) if value in inventoryItemIds: - item = state.itemDict[inventoryItemIds[value]] + item = self.itemDict[inventoryItemIds[value]] extra = extraItems[item.id] if item.id in extraItems else 0 item.set(1, extra) missingItems.remove(item) @@ -249,9 +256,21 @@ async def readItems(state): item.set(0, extra) # All other items - for item in [x for x in state.items if x.address]: + for item in [x for x in self.items if x.address]: extra = extraItems[item.id] if item.id in extraItems else 0 - item.set(await state.readRamByte(item.address), extra) + item.set(await self.readRamByte(item.address), extra) + + # The current rupee count is BCD, but the add/remove values are not + currentRupees = self.calculateRupeeCount(await self.readRamByte(rupeesHigh), await self.readRamByte(rupeesLow)) + addingRupees = (await self.readRamByte(addRupeesHigh) << 8) + await self.readRamByte(addRupeesLow) + removingRupees = (await self.readRamByte(removeRupeesHigh) << 8) + await self.readRamByte(removeRupeesLow) + self.itemDict['RUPEE_COUNT'].set(currentRupees + addingRupees - removingRupees, 0) + + def calculateRupeeCount(self, high: int, low: int) -> int: + return (high - (high // 16 * 6)) * 100 + (low - (low // 16 * 6)) + + def setExtraItem(self, item: str, qty: int) -> None: + self.extraItems[item] = qty async def sendItems(self, socket, diff=False): if not self.items: @@ -259,7 +278,6 @@ async def sendItems(self, socket, diff=False): message = { "type":"item", "refresh": True, - "version":"1.0", "diff": diff, "items": [], } diff --git a/worlds/ladx/Tracker.py b/worlds/ladx/Tracker.py index 5f48b64c4f5e..1842ceaec820 100644 --- a/worlds/ladx/Tracker.py +++ b/worlds/ladx/Tracker.py @@ -1,3 +1,6 @@ +import typing + +from worlds.ladx.GpsTracker import GpsTracker from .LADXR.checkMetadata import checkMetadataTable import json import logging @@ -10,13 +13,14 @@ # kbranch you're a hero # https://github.com/kbranch/Magpie/blob/master/autotracking/checks.py class Check: - def __init__(self, id, address, mask, alternateAddress=None): + def __init__(self, id, address, mask, alternateAddress=None, linkedItem=None): self.id = id self.address = address self.alternateAddress = alternateAddress self.mask = mask self.value = None self.diff = 0 + self.linkedItem = linkedItem def set(self, bytes): oldValue = self.value @@ -86,6 +90,27 @@ def __init__(self, gameboy): blacklist = {'None', '0x2A1-2'} + def seashellCondition(slot_data): + return 'goal' not in slot_data or slot_data['goal'] != 'seashells' + + linkedCheckItems = { + '0x2E9': {'item': 'SEASHELL', 'qty': 20, 'condition': seashellCondition}, + '0x2A2': {'item': 'TOADSTOOL', 'qty': 1}, + '0x2A6-Trade': {'item': 'TRADING_ITEM_YOSHI_DOLL', 'qty': 1}, + '0x2B2-Trade': {'item': 'TRADING_ITEM_RIBBON', 'qty': 1}, + '0x2FE-Trade': {'item': 'TRADING_ITEM_DOG_FOOD', 'qty': 1}, + '0x07B-Trade': {'item': 'TRADING_ITEM_BANANAS', 'qty': 1}, + '0x087-Trade': {'item': 'TRADING_ITEM_STICK', 'qty': 1}, + '0x2D7-Trade': {'item': 'TRADING_ITEM_HONEYCOMB', 'qty': 1}, + '0x019-Trade': {'item': 'TRADING_ITEM_PINEAPPLE', 'qty': 1}, + '0x2D9-Trade': {'item': 'TRADING_ITEM_HIBISCUS', 'qty': 1}, + '0x2A8-Trade': {'item': 'TRADING_ITEM_LETTER', 'qty': 1}, + '0x0CD-Trade': {'item': 'TRADING_ITEM_BROOM', 'qty': 1}, + '0x2F5-Trade': {'item': 'TRADING_ITEM_FISHING_HOOK', 'qty': 1}, + '0x0C9-Trade': {'item': 'TRADING_ITEM_NECKLACE', 'qty': 1}, + '0x297-Trade': {'item': 'TRADING_ITEM_SCALE', 'qty': 1}, + } + # in no dungeons boss shuffle, the d3 boss in d7 set 0x20 in fascade's room (0x1BC) # after beating evil eagile in D6, 0x1BC is now 0xAC (other things may have happened in between) # entered d3, slime eye flag had already been set (0x15A 0x20). after killing angler fish, bits 0x0C were set @@ -98,6 +123,8 @@ def __init__(self, gameboy): address = addressOverrides[check_id] if check_id in addressOverrides else 0xD800 + int( room, 16) + linkedItem = linkedCheckItems[check_id] if check_id in linkedCheckItems else None + if 'Trade' in check_id or 'Owl' in check_id: mask = 0x20 @@ -111,13 +138,19 @@ def __init__(self, gameboy): highest_check = max( highest_check, alternateAddresses[check_id]) - check = Check(check_id, address, mask, - alternateAddresses[check_id] if check_id in alternateAddresses else None) + check = Check( + check_id, + address, + mask, + (alternateAddresses[check_id] if check_id in alternateAddresses else None), + linkedItem, + ) + if check_id == '0x2A3': self.start_check = check self.all_checks.append(check) self.remaining_checks = [check for check in self.all_checks] - self.gameboy.set_cache_limits( + self.gameboy.set_checks_range( lowest_check, highest_check - lowest_check + 1) def has_start_item(self): @@ -147,10 +180,17 @@ class MagpieBridge: server = None checks = None item_tracker = None + gps_tracker: GpsTracker = None ws = None features = [] slot_data = {} + def use_entrance_tracker(self): + return "entrances" in self.features \ + and self.slot_data \ + and "entrance_mapping" in self.slot_data \ + and any([k != v for k, v in self.slot_data["entrance_mapping"].items()]) + async def handler(self, websocket): self.ws = websocket while True: @@ -159,14 +199,18 @@ async def handler(self, websocket): logger.info( f"Connected, supported features: {message['features']}") self.features = message["features"] + + await self.send_handshAck() - if message["type"] in ("handshake", "sendFull"): + if message["type"] == "sendFull": if "items" in self.features: await self.send_all_inventory() if "checks" in self.features: await self.send_all_checks() - if "slot_data" in self.features: + if "slot_data" in self.features and self.slot_data: await self.send_slot_data(self.slot_data) + if self.use_entrance_tracker(): + await self.send_gps(diff=False) # Translate renamed IDs back to LADXR IDs @staticmethod @@ -176,6 +220,18 @@ def fixup_id(the_id): if the_id == "0x2A7": return "0x2A1-1" return the_id + + async def send_handshAck(self): + if not self.ws: + return + + message = { + "type": "handshAck", + "version": "1.32", + "name": "archipelago-ladx-client", + } + + await self.ws.send(json.dumps(message)) async def send_all_checks(self): while self.checks == None: @@ -185,7 +241,6 @@ async def send_all_checks(self): message = { "type": "check", "refresh": True, - "version": "1.0", "diff": False, "checks": [{"id": self.fixup_id(check.id), "checked": check.value} for check in self.checks] } @@ -200,7 +255,6 @@ async def send_new_checks(self, checks): message = { "type": "check", "refresh": True, - "version": "1.0", "diff": True, "checks": [{"id": self.fixup_id(check), "checked": True} for check in checks] } @@ -222,10 +276,17 @@ async def send_inventory_diffs(self): return await self.item_tracker.sendItems(self.ws, diff=True) - async def send_gps(self, gps): + async def send_gps(self, diff: bool=True) -> typing.Dict[str, str]: if not self.ws: return - await gps.send_location(self.ws) + + await self.gps_tracker.send_location(self.ws) + + if self.use_entrance_tracker(): + if self.slot_data and self.gps_tracker.needs_slot_data: + self.gps_tracker.load_slot_data(self.slot_data) + + return await self.gps_tracker.send_entrances(self.ws, diff) async def send_slot_data(self, slot_data): if not self.ws: diff --git a/worlds/ladx/TrackerConsts.py b/worlds/ladx/TrackerConsts.py new file mode 100644 index 000000000000..99452608ecbb --- /dev/null +++ b/worlds/ladx/TrackerConsts.py @@ -0,0 +1,291 @@ +class EntranceCoord: + name: str + room: int + x: int + y: int + + def __init__(self, name: str, room: int, x: int, y: int): + self.name = name + self.room = room + self.x = x + self.y = y + + def __repr__(self): + return EntranceCoord.coordString(self.room, self.x, self.y) + + def coordString(room: int, x: int, y: int): + return f"{room:#05x}, {x}, {y}" + +storage_key = "found_entrances" + +room = 0xFFF6 +map_id = 0xFFF7 +indoor_flag = 0xDBA5 +spawn_map = 0xDB60 +spawn_room = 0xDB61 +spawn_x = 0xDB62 +spawn_y = 0xDB63 +entrance_room_offset = 0xD800 +transition_state = 0xC124 +transition_target_x = 0xC12C +transition_target_y = 0xC12D +transition_scroll_x = 0xFF96 +transition_scroll_y = 0xFF97 +link_motion_state = 0xC11C +transition_sequence = 0xC16B +screen_coord = 0xFFFA + +entrance_address_overrides = { + 0x312: 0xDDF2, +} + +map_map = { + 0x00: 0x01, + 0x01: 0x01, + 0x02: 0x01, + 0x03: 0x01, + 0x04: 0x01, + 0x05: 0x01, + 0x06: 0x02, + 0x07: 0x02, + 0x08: 0x02, + 0x09: 0x02, + 0x0A: 0x02, + 0x0B: 0x02, + 0x0C: 0x02, + 0x0D: 0x02, + 0x0E: 0x02, + 0x0F: 0x02, + 0x10: 0x02, + 0x11: 0x02, + 0x12: 0x02, + 0x13: 0x02, + 0x14: 0x02, + 0x15: 0x02, + 0x16: 0x02, + 0x17: 0x02, + 0x18: 0x02, + 0x19: 0x02, + 0x1D: 0x01, + 0x1E: 0x01, + 0x1F: 0x01, + 0xFF: 0x03, +} + +sidescroller_rooms = { + 0x2e9: "seashell_mansion:inside", + 0x08a: "seashell_mansion", + 0x2fd: "mambo:inside", + 0x02a: "mambo", + 0x1eb: "castle_secret_exit:inside", + 0x049: "castle_secret_exit", + 0x1ec: "castle_secret_entrance:inside", + 0x04a: "castle_secret_entrance", + 0x117: "d1:inside", # not a sidescroller, but acts weird +} + +entrance_coords = [ + EntranceCoord("writes_house:inside", 0x2a8, 80, 124), + EntranceCoord("rooster_grave", 0x92, 88, 82), + EntranceCoord("start_house:inside", 0x2a3, 80, 124), + EntranceCoord("dream_hut", 0x83, 40, 66), + EntranceCoord("papahl_house_right:inside", 0x2a6, 80, 124), + EntranceCoord("papahl_house_right", 0x82, 120, 82), + EntranceCoord("papahl_house_left:inside", 0x2a5, 80, 124), + EntranceCoord("papahl_house_left", 0x82, 88, 82), + EntranceCoord("d2:inside", 0x136, 80, 124), + EntranceCoord("shop", 0x93, 72, 98), + EntranceCoord("armos_maze_cave:inside", 0x2fc, 104, 96), + EntranceCoord("start_house", 0xa2, 88, 82), + EntranceCoord("animal_house3:inside", 0x2d9, 80, 124), + EntranceCoord("trendy_shop", 0xb3, 88, 82), + EntranceCoord("mabe_phone:inside", 0x2cb, 80, 124), + EntranceCoord("mabe_phone", 0xb2, 88, 82), + EntranceCoord("ulrira:inside", 0x2a9, 80, 124), + EntranceCoord("ulrira", 0xb1, 72, 98), + EntranceCoord("moblin_cave:inside", 0x2f0, 80, 124), + EntranceCoord("kennel", 0xa1, 88, 66), + EntranceCoord("madambowwow:inside", 0x2a7, 80, 124), + EntranceCoord("madambowwow", 0xa1, 56, 66), + EntranceCoord("library:inside", 0x1fa, 80, 124), + EntranceCoord("library", 0xb0, 56, 50), + EntranceCoord("d5:inside", 0x1a1, 80, 124), + EntranceCoord("d1", 0xd3, 104, 34), + EntranceCoord("d1:inside", 0x117, 80, 124), + EntranceCoord("d3:inside", 0x152, 80, 124), + EntranceCoord("d3", 0xb5, 104, 32), + EntranceCoord("banana_seller", 0xe3, 72, 48), + EntranceCoord("armos_temple:inside", 0x28f, 80, 124), + EntranceCoord("boomerang_cave", 0xf4, 24, 32), + EntranceCoord("forest_madbatter:inside", 0x1e1, 136, 80), + EntranceCoord("ghost_house", 0xf6, 88, 66), + EntranceCoord("prairie_low_phone:inside", 0x29d, 80, 124), + EntranceCoord("prairie_low_phone", 0xe8, 56, 98), + EntranceCoord("prairie_madbatter_connector_entrance:inside", 0x1f6, 136, 112), + EntranceCoord("prairie_madbatter_connector_entrance", 0xf9, 120, 80), + EntranceCoord("prairie_madbatter_connector_exit", 0xe7, 104, 32), + EntranceCoord("prairie_madbatter_connector_exit:inside", 0x1e5, 40, 48), + EntranceCoord("ghost_house:inside", 0x1e3, 80, 124), + EntranceCoord("prairie_madbatter", 0xe6, 72, 64), + EntranceCoord("d4:inside", 0x17a, 80, 124), + EntranceCoord("d5", 0xd9, 88, 64), + EntranceCoord("prairie_right_cave_bottom:inside", 0x293, 48, 124), + EntranceCoord("prairie_right_cave_bottom", 0xc8, 40, 80), + EntranceCoord("prairie_right_cave_high", 0xb8, 88, 48), + EntranceCoord("prairie_right_cave_high:inside", 0x295, 112, 124), + EntranceCoord("prairie_right_cave_top", 0xb8, 120, 96), + EntranceCoord("prairie_right_cave_top:inside", 0x292, 48, 124), + EntranceCoord("prairie_to_animal_connector:inside", 0x2d0, 40, 64), + EntranceCoord("prairie_to_animal_connector", 0xaa, 136, 64), + EntranceCoord("animal_to_prairie_connector", 0xab, 120, 80), + EntranceCoord("animal_to_prairie_connector:inside", 0x2d1, 120, 64), + EntranceCoord("animal_phone:inside", 0x2e3, 80, 124), + EntranceCoord("animal_phone", 0xdb, 120, 82), + EntranceCoord("animal_house1:inside", 0x2db, 80, 124), + EntranceCoord("animal_house1", 0xcc, 40, 80), + EntranceCoord("animal_house2:inside", 0x2dd, 80, 124), + EntranceCoord("animal_house2", 0xcc, 120, 80), + EntranceCoord("hookshot_cave:inside", 0x2b3, 80, 124), + EntranceCoord("animal_house3", 0xcd, 40, 80), + EntranceCoord("animal_house4:inside", 0x2da, 80, 124), + EntranceCoord("animal_house4", 0xcd, 88, 80), + EntranceCoord("banana_seller:inside", 0x2fe, 80, 124), + EntranceCoord("animal_house5", 0xdd, 88, 66), + EntranceCoord("animal_cave:inside", 0x2f7, 96, 124), + EntranceCoord("animal_cave", 0xcd, 136, 32), + EntranceCoord("d6", 0x8c, 56, 64), + EntranceCoord("madbatter_taltal:inside", 0x1e2, 136, 80), + EntranceCoord("desert_cave", 0xcf, 88, 16), + EntranceCoord("dream_hut:inside", 0x2aa, 80, 124), + EntranceCoord("armos_maze_cave", 0xae, 72, 112), + EntranceCoord("shop:inside", 0x2a1, 80, 124), + EntranceCoord("armos_temple", 0xac, 88, 64), + EntranceCoord("d6_connector_exit:inside", 0x1f0, 56, 16), + EntranceCoord("d6_connector_exit", 0x9c, 88, 16), + EntranceCoord("desert_cave:inside", 0x1f9, 120, 96), + EntranceCoord("d6_connector_entrance:inside", 0x1f1, 136, 96), + EntranceCoord("d6_connector_entrance", 0x9d, 56, 48), + EntranceCoord("armos_fairy:inside", 0x1ac, 80, 124), + EntranceCoord("armos_fairy", 0x8d, 56, 32), + EntranceCoord("raft_return_enter:inside", 0x1f7, 136, 96), + EntranceCoord("raft_return_enter", 0x8f, 8, 32), + EntranceCoord("raft_return_exit", 0x2f, 24, 112), + EntranceCoord("raft_return_exit:inside", 0x1e7, 72, 16), + EntranceCoord("raft_house:inside", 0x2b0, 80, 124), + EntranceCoord("raft_house", 0x3f, 40, 34), + EntranceCoord("heartpiece_swim_cave:inside", 0x1f2, 72, 124), + EntranceCoord("heartpiece_swim_cave", 0x2e, 88, 32), + EntranceCoord("rooster_grave:inside", 0x1f4, 88, 112), + EntranceCoord("d4", 0x2b, 72, 34), + EntranceCoord("castle_phone:inside", 0x2cc, 80, 124), + EntranceCoord("castle_phone", 0x4b, 72, 34), + EntranceCoord("castle_main_entrance:inside", 0x2d3, 80, 124), + EntranceCoord("castle_main_entrance", 0x69, 88, 64), + EntranceCoord("castle_upper_left", 0x59, 24, 48), + EntranceCoord("castle_upper_left:inside", 0x2d5, 80, 124), + EntranceCoord("witch:inside", 0x2a2, 80, 124), + EntranceCoord("castle_upper_right", 0x59, 88, 64), + EntranceCoord("prairie_left_cave2:inside", 0x2f4, 64, 124), + EntranceCoord("castle_jump_cave", 0x78, 40, 112), + EntranceCoord("prairie_left_cave1:inside", 0x2cd, 80, 124), + EntranceCoord("seashell_mansion", 0x8a, 88, 64), + EntranceCoord("prairie_right_phone:inside", 0x29c, 80, 124), + EntranceCoord("prairie_right_phone", 0x88, 88, 82), + EntranceCoord("prairie_left_fairy:inside", 0x1f3, 80, 124), + EntranceCoord("prairie_left_fairy", 0x87, 40, 16), + EntranceCoord("bird_cave:inside", 0x27e, 96, 124), + EntranceCoord("prairie_left_cave2", 0x86, 24, 64), + EntranceCoord("prairie_left_cave1", 0x84, 152, 98), + EntranceCoord("prairie_left_phone:inside", 0x2b4, 80, 124), + EntranceCoord("prairie_left_phone", 0xa4, 56, 66), + EntranceCoord("mamu:inside", 0x2fb, 136, 112), + EntranceCoord("mamu", 0xd4, 136, 48), + EntranceCoord("richard_house:inside", 0x2c7, 80, 124), + EntranceCoord("richard_house", 0xd6, 72, 80), + EntranceCoord("richard_maze:inside", 0x2c9, 128, 124), + EntranceCoord("richard_maze", 0xc6, 56, 80), + EntranceCoord("graveyard_cave_left:inside", 0x2de, 56, 64), + EntranceCoord("graveyard_cave_left", 0x75, 56, 64), + EntranceCoord("graveyard_cave_right:inside", 0x2df, 56, 48), + EntranceCoord("graveyard_cave_right", 0x76, 104, 80), + EntranceCoord("trendy_shop:inside", 0x2a0, 80, 124), + EntranceCoord("d0", 0x77, 120, 46), + EntranceCoord("boomerang_cave:inside", 0x1f5, 72, 124), + EntranceCoord("witch", 0x65, 72, 50), + EntranceCoord("toadstool_entrance:inside", 0x2bd, 80, 124), + EntranceCoord("toadstool_entrance", 0x62, 120, 66), + EntranceCoord("toadstool_exit", 0x50, 136, 50), + EntranceCoord("toadstool_exit:inside", 0x2ab, 80, 124), + EntranceCoord("prairie_madbatter:inside", 0x1e0, 136, 112), + EntranceCoord("hookshot_cave", 0x42, 56, 66), + EntranceCoord("castle_upper_right:inside", 0x2d6, 80, 124), + EntranceCoord("forest_madbatter", 0x52, 104, 48), + EntranceCoord("writes_phone:inside", 0x29b, 80, 124), + EntranceCoord("writes_phone", 0x31, 104, 82), + EntranceCoord("d0:inside", 0x312, 80, 92), + EntranceCoord("writes_house", 0x30, 120, 50), + EntranceCoord("writes_cave_left:inside", 0x2ae, 80, 124), + EntranceCoord("writes_cave_left", 0x20, 136, 50), + EntranceCoord("writes_cave_right:inside", 0x2af, 80, 124), + EntranceCoord("writes_cave_right", 0x21, 24, 50), + EntranceCoord("d6:inside", 0x1d4, 80, 124), + EntranceCoord("d2", 0x24, 56, 34), + EntranceCoord("animal_house5:inside", 0x2d7, 80, 124), + EntranceCoord("moblin_cave", 0x35, 104, 80), + EntranceCoord("crazy_tracy:inside", 0x2ad, 80, 124), + EntranceCoord("crazy_tracy", 0x45, 136, 66), + EntranceCoord("photo_house:inside", 0x2b5, 80, 124), + EntranceCoord("photo_house", 0x37, 72, 66), + EntranceCoord("obstacle_cave_entrance:inside", 0x2b6, 80, 124), + EntranceCoord("obstacle_cave_entrance", 0x17, 56, 50), + EntranceCoord("left_to_right_taltalentrance:inside", 0x2ee, 120, 48), + EntranceCoord("left_to_right_taltalentrance", 0x7, 56, 80), + EntranceCoord("obstacle_cave_outside_chest:inside", 0x2bb, 80, 124), + EntranceCoord("obstacle_cave_outside_chest", 0x18, 104, 18), + EntranceCoord("obstacle_cave_exit:inside", 0x2bc, 48, 124), + EntranceCoord("obstacle_cave_exit", 0x18, 136, 18), + EntranceCoord("papahl_entrance:inside", 0x289, 64, 124), + EntranceCoord("papahl_entrance", 0x19, 136, 64), + EntranceCoord("papahl_exit:inside", 0x28b, 80, 124), + EntranceCoord("papahl_exit", 0xa, 24, 112), + EntranceCoord("rooster_house:inside", 0x29f, 80, 124), + EntranceCoord("rooster_house", 0xa, 72, 34), + EntranceCoord("d7:inside", 0x20e, 80, 124), + EntranceCoord("bird_cave", 0xa, 120, 112), + EntranceCoord("multichest_top:inside", 0x2f2, 80, 124), + EntranceCoord("multichest_top", 0xd, 24, 112), + EntranceCoord("multichest_left:inside", 0x2f9, 32, 124), + EntranceCoord("multichest_left", 0x1d, 24, 48), + EntranceCoord("multichest_right:inside", 0x2fa, 112, 124), + EntranceCoord("multichest_right", 0x1d, 120, 80), + EntranceCoord("right_taltal_connector1:inside", 0x280, 32, 124), + EntranceCoord("right_taltal_connector1", 0x1e, 56, 16), + EntranceCoord("right_taltal_connector3:inside", 0x283, 128, 124), + EntranceCoord("right_taltal_connector3", 0x1e, 120, 16), + EntranceCoord("right_taltal_connector2:inside", 0x282, 112, 124), + EntranceCoord("right_taltal_connector2", 0x1f, 40, 16), + EntranceCoord("right_fairy:inside", 0x1fb, 80, 124), + EntranceCoord("right_fairy", 0x1f, 56, 80), + EntranceCoord("right_taltal_connector4:inside", 0x287, 96, 124), + EntranceCoord("right_taltal_connector4", 0x1f, 88, 64), + EntranceCoord("right_taltal_connector5:inside", 0x28c, 96, 124), + EntranceCoord("right_taltal_connector5", 0x1f, 120, 16), + EntranceCoord("right_taltal_connector6:inside", 0x28e, 112, 124), + EntranceCoord("right_taltal_connector6", 0xf, 72, 80), + EntranceCoord("d7", 0x0e, 88, 48), + EntranceCoord("left_taltal_entrance:inside", 0x2ea, 80, 124), + EntranceCoord("left_taltal_entrance", 0x15, 136, 64), + EntranceCoord("castle_jump_cave:inside", 0x1fd, 88, 80), + EntranceCoord("madbatter_taltal", 0x4, 120, 112), + EntranceCoord("fire_cave_exit:inside", 0x1ee, 24, 64), + EntranceCoord("fire_cave_exit", 0x3, 72, 80), + EntranceCoord("fire_cave_entrance:inside", 0x1fe, 112, 124), + EntranceCoord("fire_cave_entrance", 0x13, 88, 16), + EntranceCoord("phone_d8:inside", 0x299, 80, 124), + EntranceCoord("phone_d8", 0x11, 104, 50), + EntranceCoord("kennel:inside", 0x2b2, 80, 124), + EntranceCoord("d8", 0x10, 88, 16), + EntranceCoord("d8:inside", 0x25d, 80, 124), +] + +entrance_lookup = {str(coord): coord for coord in entrance_coords} From 0f738935ee4cfce6d54a471e4a393ac69812aad8 Mon Sep 17 00:00:00 2001 From: Justus Lind Date: Sat, 8 Mar 2025 23:58:26 +1000 Subject: [PATCH 0173/1218] Muse Dash: Update song list to Cosmic Radio. (#4554) * MSR Anthology Vol.2 update * Missing new line. * Update to Cosmic Radio 2024 --- worlds/musedash/MuseDashCollection.py | 3 ++- worlds/musedash/MuseDashData.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/worlds/musedash/MuseDashCollection.py b/worlds/musedash/MuseDashCollection.py index 64aa6ca49ae3..8bad02f2dccb 100644 --- a/worlds/musedash/MuseDashCollection.py +++ b/worlds/musedash/MuseDashCollection.py @@ -24,9 +24,10 @@ class MuseDashCollections: MUSE_PLUS_DLC, "CHUNITHM COURSE MUSE", # Part of Muse Plus. Goes away 22nd May 2027. "maimai DX Limited-time Suite", # Part of Muse Plus. Goes away 31st Jan 2026. - "MSR Anthology", # Now no longer available. + "MSR Anthology", # Goes away January 26, 2026. "Miku in Museland", # Paid DLC not included in Muse Plus "Rin Len's Mirrorland", # Paid DLC not included in Muse Plus + "MSR Anthology_Vol.02", # Goes away January 26, 2026. ] REMOVED_SONGS = [ diff --git a/worlds/musedash/MuseDashData.py b/worlds/musedash/MuseDashData.py index 1700f956aa35..d8efadd136e8 100644 --- a/worlds/musedash/MuseDashData.py +++ b/worlds/musedash/MuseDashData.py @@ -612,4 +612,19 @@ "Usagi Flap": SongData(2900736, "81-1", "MD-level Tactical Training Blu-ray", False, 3, 6, 8), "RE Aoharu": SongData(2900737, "81-2", "MD-level Tactical Training Blu-ray", False, 3, 5, 8), "Operation*DOTABATA!": SongData(2900738, "81-3", "MD-level Tactical Training Blu-ray", False, 5, 7, 10), + "Break Through the Dome": SongData(2900739, "82-0", "MSR Anthology_Vol.02", False, 5, 7, 9), + "Here in Vernal Terrene": SongData(2900740, "82-1", "MSR Anthology_Vol.02", False, 3, 5, 7), + "Everything's Alright": SongData(2900741, "82-2", "MSR Anthology_Vol.02", False, 3, 5, 8), + "Operation Ashring": SongData(2900742, "82-3", "MSR Anthology_Vol.02", False, 3, 5, 7), + "Misty Memory Day Version": SongData(2900743, "82-4", "MSR Anthology_Vol.02", False, 3, 5, 7), + "Misty Memory Night Version": SongData(2900744, "82-5", "MSR Anthology_Vol.02", False, 2, 6, 9), + "Arsonist": SongData(2900745, "82-6", "MSR Anthology_Vol.02", False, 3, 6, 8), + "Operation Deepness": SongData(2900746, "82-7", "MSR Anthology_Vol.02", False, 2, 4, 6), + "ALL!!!": SongData(2900747, "82-8", "MSR Anthology_Vol.02", False, 6, 8, 10), + "LUNATiC CiRCUiT": SongData(2900748, "83-0", "Cosmic Radio 2024", False, 7, 9, 11), + "Synthesis.": SongData(2900749, "83-1", "Cosmic Radio 2024", True, 6, 8, 10), + "COSMiC FANFARE!!!!": SongData(2900750, "83-2", "Cosmic Radio 2024", False, 7, 9, 11), + "Sharp Bubbles": SongData(2900751, "83-3", "Cosmic Radio 2024", True, 7, 9, 11), + "Replay": SongData(2900752, "83-4", "Cosmic Radio 2024", True, 5, 7, 9), + "Cosmic Dusty Girl": SongData(2900753, "83-5", "Cosmic Radio 2024", True, 5, 7, 9), } From 3f8e3082c0e0eba30d409d3c3b1f748d7e8762d3 Mon Sep 17 00:00:00 2001 From: JaredWeakStrike <96694163+JaredWeakStrike@users.noreply.github.com> Date: Sat, 8 Mar 2025 08:58:59 -0500 Subject: [PATCH 0174/1218] KH2: Client Optimizations and some QoL (#4547) * adding qwints suggestions * add stat increase protection and ingame yml stuff * idk how I forgot these * reword things * Update worlds/kh2/Client.py Co-authored-by: qwint * 3.12 compat * too long of a line * why didnt I do this before lol * reading is hard * missed one * forgot the self * fix crash if you get datapackage that isnt kh2 * update to main? * update to use 0.10 as base and fix violet's base 0 on hex values * reverting this because I'm bad at my job --------- Co-authored-by: qwint --- worlds/kh2/Client.py | 151 ++++++++++++++++++++++--------------------- worlds/kh2/OpenKH.py | 62 +++++++++++++++++- 2 files changed, 140 insertions(+), 73 deletions(-) diff --git a/worlds/kh2/Client.py b/worlds/kh2/Client.py index a21c8c7c5536..15a103c2a1ae 100644 --- a/worlds/kh2/Client.py +++ b/worlds/kh2/Client.py @@ -1,4 +1,5 @@ import ModuleUpdate +import Utils ModuleUpdate.update() @@ -23,6 +24,7 @@ class KH2Context(CommonContext): def __init__(self, server_address, password): super(KH2Context, self).__init__(server_address, password) + self.goofy_ability_to_slot = dict() self.donald_ability_to_slot = dict() self.all_weapon_location_id = None @@ -35,6 +37,7 @@ def __init__(self, server_address, password): self.serverconneced = False self.item_name_to_data = {name: data for name, data, in item_dictionary_table.items()} self.location_name_to_data = {name: data for name, data, in all_locations.items()} + self.kh2_data_package = {} self.kh2_loc_name_to_id = None self.kh2_item_name_to_id = None self.lookup_id_to_item = None @@ -83,6 +86,8 @@ def __init__(self, server_address, password): }, } self.kh2seedname = None + self.kh2_seed_save_path_join = None + self.kh2slotdata = None self.mem_json = None self.itemamount = {} @@ -114,26 +119,18 @@ def __init__(self, server_address, password): # 255: {}, # starting screen } self.last_world_int = -1 - # 0x2A09C00+0x40 is the sve anchor. +1 is the last saved room - # self.sveroom = 0x2A09C00 + 0x41 - # 0 not in battle 1 in yellow battle 2 red battle #short - # self.inBattle = 0x2A0EAC4 + 0x40 - # self.onDeath = 0xAB9078 # PC Address anchors - # self.Now = 0x0714DB8 old address - # epic addresses + # epic .10 addresses self.Now = 0x0716DF8 - self.Save = 0x09A92F0 + self.Save = 0x9A9330 self.Journal = 0x743260 self.Shop = 0x743350 - self.Slot1 = 0x2A22FD8 - # self.Sys3 = 0x2A59DF0 - # self.Bt10 = 0x2A74880 - # self.BtlEnd = 0x2A0D3E0 - # self.Slot1 = 0x2A20C98 old address + self.Slot1 = 0x2A23018 self.kh2_game_version = None # can be egs or steam + self.kh2_seed_save_path = None + self.chest_set = set(exclusion_table["Chests"]) self.keyblade_set = set(CheckDupingItems["Weapons"]["Keyblades"]) self.staff_set = set(CheckDupingItems["Weapons"]["Staffs"]) @@ -194,8 +191,7 @@ async def connection_closed(self): self.kh2connected = False self.serverconneced = False if self.kh2seedname is not None and self.auth is not None: - with open(os.path.join(self.game_communication_path, f"kh2save2{self.kh2seedname}{self.auth}.json"), - 'w') as f: + with open(self.kh2_seed_save_path_join, 'w') as f: f.write(json.dumps(self.kh2_seed_save, indent=4)) await super(KH2Context, self).connection_closed() @@ -203,8 +199,7 @@ async def disconnect(self, allow_autoreconnect: bool = False): self.kh2connected = False self.serverconneced = False if self.kh2seedname not in {None} and self.auth not in {None}: - with open(os.path.join(self.game_communication_path, f"kh2save2{self.kh2seedname}{self.auth}.json"), - 'w') as f: + with open(self.kh2_seed_save_path_join, 'w') as f: f.write(json.dumps(self.kh2_seed_save, indent=4)) await super(KH2Context, self).disconnect() @@ -217,8 +212,7 @@ def endpoints(self): async def shutdown(self): if self.kh2seedname not in {None} and self.auth not in {None}: - with open(os.path.join(self.game_communication_path, f"kh2save2{self.kh2seedname}{self.auth}.json"), - 'w') as f: + with open(self.kh2_seed_save_path_join, 'w') as f: f.write(json.dumps(self.kh2_seed_save, indent=4)) await super(KH2Context, self).shutdown() @@ -232,7 +226,7 @@ def kh2_write_byte(self, address, value): return self.kh2.write_bytes(self.kh2.base_address + address, value.to_bytes(1, 'big'), 1) def kh2_read_byte(self, address): - return int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + address, 1), "big") + return int.from_bytes(self.kh2.read_bytes(self.kh2.base_address + address, 1)) def kh2_read_int(self, address): return self.kh2.read_int(self.kh2.base_address + address) @@ -244,11 +238,14 @@ def kh2_read_string(self, address, length): return self.kh2.read_string(self.kh2.base_address + address, length) def on_package(self, cmd: str, args: dict): - if cmd in {"RoomInfo"}: + if cmd == "RoomInfo": self.kh2seedname = args['seed_name'] + self.kh2_seed_save_path = f"kh2save2{self.kh2seedname}{self.auth}.json" + self.kh2_seed_save_path_join = os.path.join(self.game_communication_path, self.kh2_seed_save_path) + if not os.path.exists(self.game_communication_path): os.makedirs(self.game_communication_path) - if not os.path.exists(self.game_communication_path + f"\kh2save2{self.kh2seedname}{self.auth}.json"): + if not os.path.exists(self.kh2_seed_save_path_join): self.kh2_seed_save = { "Levels": { "SoraLevel": 0, @@ -261,12 +258,11 @@ def on_package(self, cmd: str, args: dict): }, "SoldEquipment": [], } - with open(os.path.join(self.game_communication_path, f"kh2save2{self.kh2seedname}{self.auth}.json"), - 'wt') as f: + with open(self.kh2_seed_save_path_join, 'wt') as f: pass # self.locations_checked = set() - elif os.path.exists(self.game_communication_path + f"\kh2save2{self.kh2seedname}{self.auth}.json"): - with open(self.game_communication_path + f"\kh2save2{self.kh2seedname}{self.auth}.json", 'r') as f: + elif os.path.exists(self.kh2_seed_save_path_join): + with open(self.kh2_seed_save_path_join) as f: self.kh2_seed_save = json.load(f) if self.kh2_seed_save is None: self.kh2_seed_save = { @@ -284,13 +280,22 @@ def on_package(self, cmd: str, args: dict): # self.locations_checked = set(self.kh2_seed_save_cache["LocationsChecked"]) # self.serverconneced = True - if cmd in {"Connected"}: - asyncio.create_task(self.send_msgs([{"cmd": "GetDataPackage", "games": ["Kingdom Hearts 2"]}])) + if cmd == "Connected": self.kh2slotdata = args['slot_data'] - # self.kh2_local_items = {int(location): item for location, item in self.kh2slotdata["LocalItems"].items()} + + self.kh2_data_package = Utils.load_data_package_for_checksum( + "Kingdom Hearts 2", self.checksums["Kingdom Hearts 2"]) + + if "location_name_to_id" in self.kh2_data_package: + self.data_package_kh2_cache( + self.kh2_data_package["location_name_to_id"], self.kh2_data_package["item_name_to_id"]) + self.connect_to_game() + else: + asyncio.create_task(self.send_msgs([{"cmd": "GetDataPackage", "games": ["Kingdom Hearts 2"]}])) + self.locations_checked = set(args["checked_locations"]) - if cmd in {"ReceivedItems"}: + if cmd == "ReceivedItems": # 0x2546 # 0x2658 # 0x276A @@ -338,42 +343,44 @@ def on_package(self, cmd: str, args: dict): for item in args['items']: asyncio.create_task(self.give_item(item.item, item.location)) - if cmd in {"RoomUpdate"}: + if cmd == "RoomUpdate": if "checked_locations" in args: new_locations = set(args["checked_locations"]) self.locations_checked |= new_locations - if cmd in {"DataPackage"}: + if cmd == "DataPackage": if "Kingdom Hearts 2" in args["data"]["games"]: - self.data_package_kh2_cache(args) - if "KeybladeAbilities" in self.kh2slotdata.keys(): - # sora ability to slot - self.AbilityQuantityDict.update(self.kh2slotdata["KeybladeAbilities"]) - # itemid:[slots that are available for that item] - self.AbilityQuantityDict.update(self.kh2slotdata["StaffAbilities"]) - self.AbilityQuantityDict.update(self.kh2slotdata["ShieldAbilities"]) - - all_weapon_location_id = [] - for weapon_location in all_weapon_slot: - all_weapon_location_id.append(self.kh2_loc_name_to_id[weapon_location]) - self.all_weapon_location_id = set(all_weapon_location_id) - - try: - if not self.kh2: - self.kh2 = pymem.Pymem(process_name="KINGDOM HEARTS II FINAL MIX") - self.get_addresses() - - except Exception as e: - if self.kh2connected: - self.kh2connected = False - logger.info("Game is not open.") - self.serverconneced = True - asyncio.create_task(self.send_msgs([{'cmd': 'Sync'}])) - - def data_package_kh2_cache(self, args): - self.kh2_loc_name_to_id = args["data"]["games"]["Kingdom Hearts 2"]["location_name_to_id"] + self.data_package_kh2_cache( + args["data"]["games"]["Kingdom Hearts 2"]["location_name_to_id"], + args["data"]["games"]["Kingdom Hearts 2"]["item_name_to_id"]) + self.connect_to_game() + asyncio.create_task(self.send_msgs([{'cmd': 'Sync'}])) + + def connect_to_game(self): + if "KeybladeAbilities" in self.kh2slotdata.keys(): + # sora ability to slot + self.AbilityQuantityDict.update(self.kh2slotdata["KeybladeAbilities"]) + # itemid:[slots that are available for that item] + self.AbilityQuantityDict.update(self.kh2slotdata["StaffAbilities"]) + self.AbilityQuantityDict.update(self.kh2slotdata["ShieldAbilities"]) + + self.all_weapon_location_id = {self.kh2_loc_name_to_id[loc] for loc in all_weapon_slot} + + try: + if not self.kh2: + self.kh2 = pymem.Pymem(process_name="KINGDOM HEARTS II FINAL MIX") + self.get_addresses() + + except Exception as e: + if self.kh2connected: + self.kh2connected = False + logger.info("Game is not open.") + self.serverconneced = True + + def data_package_kh2_cache(self, loc_to_id, item_to_id): + self.kh2_loc_name_to_id = loc_to_id self.lookup_id_to_location = {v: k for k, v in self.kh2_loc_name_to_id.items()} - self.kh2_item_name_to_id = args["data"]["games"]["Kingdom Hearts 2"]["item_name_to_id"] + self.kh2_item_name_to_id = item_to_id self.lookup_id_to_item = {v: k for k, v in self.kh2_item_name_to_id.items()} self.ability_code_list = [self.kh2_item_name_to_id[item] for item in exclusion_item_table["Ability"]] @@ -742,7 +749,8 @@ async def verifyItems(self): for item_name in master_stat: amount_of_items = 0 amount_of_items += self.kh2_seed_save_cache["AmountInvo"]["StatIncrease"][item_name] - if self.kh2_read_byte(self.Slot1 + 0x1B2) >= 5: + # checking if they talked to the computer to give them these + if self.kh2_read_byte(self.Slot1 + 0x1B2) >= 5 and (self.kh2_read_byte(self.Save + 0x1D27) & 0x1 << 3) > 0: if item_name == ItemName.MaxHPUp: if self.kh2_read_byte(self.Save + 0x2498) < 3: # Non-Critical Bonus = 5 @@ -808,34 +816,33 @@ async def verifyItems(self): def get_addresses(self): if not self.kh2connected and self.kh2 is not None: if self.kh2_game_version is None: - - if self.kh2_read_string(0x09A9830, 4) == "KH2J": + # current verions is .10 then runs the get from github stuff + if self.kh2_read_string(0x9A98B0, 4) == "KH2J": self.kh2_game_version = "STEAM" self.Now = 0x0717008 - self.Save = 0x09A9830 - self.Slot1 = 0x2A23518 + self.Save = 0x09A98B0 + self.Slot1 = 0x2A23598 self.Journal = 0x7434E0 self.Shop = 0x7435D0 - elif self.kh2_read_string(0x09A92F0, 4) == "KH2J": + elif self.kh2_read_string(0x9A9330, 4) == "KH2J": self.kh2_game_version = "EGS" else: if self.game_communication_path: - logger.info("Checking with most up to date addresses of github. If file is not found will be downloading datafiles. This might take a moment") + logger.info("Checking with most up to date addresses from the addresses json.") #if mem addresses file is found then check version and if old get new one - kh2memaddresses_path = os.path.join(self.game_communication_path, f"kh2memaddresses.json") + kh2memaddresses_path = os.path.join(self.game_communication_path, "kh2memaddresses.json") if not os.path.exists(kh2memaddresses_path): + logger.info("File is not found. Downloading json with memory addresses. This might take a moment") mem_resp = requests.get("https://raw.githubusercontent.com/JaredWeakStrike/KH2APMemoryValues/master/kh2memaddresses.json") if mem_resp.status_code == 200: self.mem_json = json.loads(mem_resp.content) - with open(kh2memaddresses_path, - 'w') as f: + with open(kh2memaddresses_path, 'w') as f: f.write(json.dumps(self.mem_json, indent=4)) else: - with open(kh2memaddresses_path, 'r') as f: + with open(kh2memaddresses_path) as f: self.mem_json = json.load(f) if self.mem_json: for key in self.mem_json.keys(): - if self.kh2_read_string(int(self.mem_json[key]["GameVersionCheck"], 0), 4) == "KH2J": self.Now = int(self.mem_json[key]["Now"], 0) self.Save = int(self.mem_json[key]["Save"], 0) diff --git a/worlds/kh2/OpenKH.py b/worlds/kh2/OpenKH.py index 17d7f84e8cfd..7226525d0c4b 100644 --- a/worlds/kh2/OpenKH.py +++ b/worlds/kh2/OpenKH.py @@ -368,6 +368,37 @@ def increaseStat(i): } ] }, + { + 'name': 'msg/us/he.bar', + 'multi': [ + { + 'name': 'msg/fr/he.bar' + }, + { + 'name': 'msg/gr/he.bar' + }, + { + 'name': 'msg/it/he.bar' + }, + { + 'name': 'msg/sp/he.bar' + } + ], + 'method': 'binarc', + 'source': [ + { + 'name': 'he', + 'type': 'list', + 'method': 'kh2msg', + 'source': [ + { + 'name': 'he.yml', + 'language': 'en' + } + ] + } + ] + }, ], 'title': 'Randomizer Seed' } @@ -411,6 +442,34 @@ def increaseStat(i): 'en': f"Your Level Depth is {self.options.LevelDepth.current_option_name}" } ] + self.fight_and_form_text = [ + { + 'id': 15121, # poster name + 'en': f"Game Options" + }, + { + 'id': 15122, + 'en': f"Fight Logic is {self.options.FightLogic.current_option_name}\n" + f"Auto Form Logic is {self.options.AutoFormLogic.current_option_name}\n" + f"Final Form Logic is {self.options.FinalFormLogic.current_option_name}" + } + + ] + self.cups_text = [ + { + 'id': 4043, + 'en': f"CupsToggle: {self.options.Cups.current_option_name}" + }, + { + 'id': 4044, + 'en': f"CupsToggle: {self.options.Cups.current_option_name}" + }, + { + 'id': 4045, + 'en': f"CupsToggle: {self.options.Cups.current_option_name}" + }, + ] + mod_dir = os.path.join(output_directory, mod_name + "_" + Utils.__version__) self.mod_yml["title"] = f"Randomizer Seed {mod_name}" @@ -423,7 +482,8 @@ def increaseStat(i): "FmlvList.yml": yaml.dump(self.formattedFmlv, line_break="\n"), "mod.yml": yaml.dump(self.mod_yml, line_break="\n"), "po.yml": yaml.dump(self.pooh_text, line_break="\n"), - "sys.yml": yaml.dump(self.level_depth_text, line_break="\n"), + "sys.yml": yaml.dump(self.level_depth_text + self.fight_and_form_text, line_break="\n"), + "he.yml": yaml.dump(self.cups_text, line_break="\n") } mod = KH2Container(openkhmod, mod_dir, output_directory, self.player, From d4e2698ae0d58ebb05fd041d9d21dbd2affaa978 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sat, 8 Mar 2025 09:56:29 -0500 Subject: [PATCH 0175/1218] TUNIC: Add exception handling to deal with duplicate apworlds (#4634) * Add exception handling to deal with duplicate apworlds * Update worlds/tunic/__init__.py --- worlds/tunic/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 2ee58d42d1bc..250f6706f122 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -110,6 +110,13 @@ class TunicWorld(World): ut_can_gen_without_yaml = True # class var that tells it to ignore the player yaml def generate_early(self) -> None: + try: + int(self.settings.disable_local_spoiler) + except AttributeError: + raise Exception("You have a TUNIC APWorld in your lib/worlds folder and custom_worlds folder.\n" + "This would cause an error at the end of generation.\n" + "Please remove one of them, most likely the one in lib/worlds.") + check_options(self) if self.options.logic_rules >= LogicRules.option_no_major_glitches: From 414ab8642251101f657cc389c42fd5a664b29ff5 Mon Sep 17 00:00:00 2001 From: CaitSith2 Date: Sat, 8 Mar 2025 07:13:32 -0800 Subject: [PATCH 0176/1218] LttP: Fix dungeon counter options. (#4704) --- worlds/alttp/Rom.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index 73a77b03f532..f658b930d013 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -1547,9 +1547,9 @@ def chunk(l, n): rom.write_byte(0x18003B, 0x01 if world.map_shuffle[player] else 0x00) # maps showing crystals on overworld # compasses showing dungeon count - if local_world.clock_mode or not world.dungeon_counters[player]: + if local_world.clock_mode or world.dungeon_counters[player] == 'off': rom.write_byte(0x18003C, 0x00) # Currently must be off if timer is on, because they use same HUD location - elif world.dungeon_counters[player] is True: + elif world.dungeon_counters[player] == 'on': rom.write_byte(0x18003C, 0x02) # always on elif world.compass_shuffle[player] or world.dungeon_counters[player] == 'pickup': rom.write_byte(0x18003C, 0x01) # show on pickup From ea8a14b00371a58196e0354453008cdb5238ffcd Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sat, 8 Mar 2025 07:13:58 -0800 Subject: [PATCH 0177/1218] Pokemon Emerald: Some dexsanity locations contribute evolution items (#3187) * Pokemon Emerald: Change some dexsanity vanilla items to evo items If a species evolves via item use (Fire Stone, Metal Coat, etc.), use that as it's vanilla item instead of a ball * Pokemon Emerald: Remove accidentally added print * Pokemon Emerald: Update changelog * Pokemon Emerald: Adjust changelog * Pokemon Emerald: Remove unnecessary else * Pokemon Emerald: Fix changelog --- worlds/pokemon_emerald/data.py | 51 ++++++++++++---------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/worlds/pokemon_emerald/data.py b/worlds/pokemon_emerald/data.py index cd1becf44b22..198572628346 100644 --- a/worlds/pokemon_emerald/data.py +++ b/worlds/pokemon_emerald/data.py @@ -215,34 +215,9 @@ class EvolutionMethodEnum(IntEnum): FRIENDSHIP_NIGHT = 11 -def _str_to_evolution_method(string: str) -> EvolutionMethodEnum: - if string == "LEVEL": - return EvolutionMethodEnum.LEVEL - if string == "LEVEL_ATK_LT_DEF": - return EvolutionMethodEnum.LEVEL_ATK_LT_DEF - if string == "LEVEL_ATK_EQ_DEF": - return EvolutionMethodEnum.LEVEL_ATK_EQ_DEF - if string == "LEVEL_ATK_GT_DEF": - return EvolutionMethodEnum.LEVEL_ATK_GT_DEF - if string == "LEVEL_SILCOON": - return EvolutionMethodEnum.LEVEL_SILCOON - if string == "LEVEL_CASCOON": - return EvolutionMethodEnum.LEVEL_CASCOON - if string == "LEVEL_NINJASK": - return EvolutionMethodEnum.LEVEL_NINJASK - if string == "LEVEL_SHEDINJA": - return EvolutionMethodEnum.LEVEL_SHEDINJA - if string == "FRIENDSHIP": - return EvolutionMethodEnum.FRIENDSHIP - if string == "FRIENDSHIP_DAY": - return EvolutionMethodEnum.FRIENDSHIP_DAY - if string == "FRIENDSHIP_NIGHT": - return EvolutionMethodEnum.FRIENDSHIP_NIGHT - - class EvolutionData(NamedTuple): method: EvolutionMethodEnum - param: int + param: int # Level/item id/friendship/etc.; depends on method species_id: int @@ -959,7 +934,7 @@ def _init() -> None: (species_data["types"][0], species_data["types"][1]), (species_data["abilities"][0], species_data["abilities"][1]), [EvolutionData( - _str_to_evolution_method(evolution_json["method"]), + EvolutionMethodEnum[evolution_json["method"]], evolution_json["param"], evolution_json["species"], ) for evolution_json in species_data["evolutions"]], @@ -977,24 +952,34 @@ def _init() -> None: data.species[evolution.species_id].pre_evolution = species.species_id # Replace default item for dex entry locations based on evo stage of species - evo_stage_to_ball_map = { + evo_stage_to_ball_map: Dict[int, int] = { 0: data.constants["ITEM_POKE_BALL"], 1: data.constants["ITEM_GREAT_BALL"], 2: data.constants["ITEM_ULTRA_BALL"], } + for species in data.species.values(): - evo_stage = 0 + default_item: Optional[int] = None pre_evolution = species.pre_evolution - while pre_evolution is not None: - evo_stage += 1 - pre_evolution = data.species[pre_evolution].pre_evolution + + if pre_evolution is not None: + evo_data = next(evo for evo in data.species[pre_evolution].evolutions if evo.species_id == species.species_id) + if evo_data.method == EvolutionMethodEnum.ITEM: + default_item = evo_data.param + + evo_stage = 0 + if default_item is None: + while pre_evolution is not None: + evo_stage += 1 + pre_evolution = data.species[pre_evolution].pre_evolution + default_item = evo_stage_to_ball_map[evo_stage] dex_location_name = f"POKEDEX_REWARD_{str(species.national_dex_number).zfill(3)}" data.locations[dex_location_name] = LocationData( data.locations[dex_location_name].name, data.locations[dex_location_name].label, data.locations[dex_location_name].parent_region, - evo_stage_to_ball_map[evo_stage], + default_item, data.locations[dex_location_name].address, data.locations[dex_location_name].flag, data.locations[dex_location_name].category, From 00a6ac3a52188238133aae336bec4b3a0876b254 Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sat, 8 Mar 2025 07:14:25 -0800 Subject: [PATCH 0178/1218] BizHawkClient: Store seed name sent by the server for clients to check (#4702) --- worlds/_bizhawk/context.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/worlds/_bizhawk/context.py b/worlds/_bizhawk/context.py index accb5f94c482..21c54d30c752 100644 --- a/worlds/_bizhawk/context.py +++ b/worlds/_bizhawk/context.py @@ -41,6 +41,7 @@ def _cmd_bh(self): class BizHawkClientContext(CommonContext): command_processor = BizHawkClientCommandProcessor + server_seed_name: str | None = None auth_status: AuthStatus password_requested: bool client_handler: BizHawkClient | None @@ -68,6 +69,8 @@ def on_package(self, cmd, args): if cmd == "Connected": self.slot_data = args.get("slot_data", None) self.auth_status = AuthStatus.AUTHENTICATED + elif cmd == "RoomInfo": + self.server_seed_name = args.get("seed_name", None) if self.client_handler is not None: self.client_handler.on_package(self, cmd, args) @@ -100,6 +103,7 @@ async def server_auth(self, password_requested: bool=False): async def disconnect(self, allow_autoreconnect: bool=False): self.auth_status = AuthStatus.NOT_AUTHENTICATED + self.server_seed_name = None await super().disconnect(allow_autoreconnect) From b5269e9aa4526b0e6b179f2ac62689f7b9a216bb Mon Sep 17 00:00:00 2001 From: Kaito Sinclaire Date: Sat, 8 Mar 2025 07:37:54 -0800 Subject: [PATCH 0179/1218] id Tech Games: Customizable ammo capacity (#3565) * Doom, Doom 2, Heretic: customizable ammo capacity * Do not progression balance capacity up items * Prog fill still doesn't agree, just go with our original idea * Clean up the new options a bit - Gave all options a consistent and easily readable naming scheme (`max_ammo_` and `added_ammo_`) - Don't show the new options in the spoiler log, as they do not affect logic - Fix the Doom games' Split Backpack option accidentally referring to Heretic's Bag of Holding The logging change across all three games is incidental, as at some point I did run into that condition by happenstance and it turns out that it throws an exception due to bad formatting if it's reached * Do the visibility change for Heretic as well * Update required client version * Remove spoiler log restriction on options * Remove Visibility import now made redundant --- worlds/doom_1993/Items.py | 28 +++++++- worlds/doom_1993/Options.py | 91 ++++++++++++++++++++++++- worlds/doom_1993/__init__.py | 23 ++++++- worlds/doom_ii/Items.py | 28 +++++++- worlds/doom_ii/Options.py | 91 ++++++++++++++++++++++++- worlds/doom_ii/__init__.py | 27 +++++++- worlds/heretic/Items.py | 40 ++++++++++- worlds/heretic/Options.py | 127 ++++++++++++++++++++++++++++++++++- worlds/heretic/Rules.py | 4 +- worlds/heretic/__init__.py | 29 +++++++- 10 files changed, 469 insertions(+), 19 deletions(-) diff --git a/worlds/doom_1993/Items.py b/worlds/doom_1993/Items.py index 3c5124d4d57b..3dce3e01e11f 100644 --- a/worlds/doom_1993/Items.py +++ b/worlds/doom_1993/Items.py @@ -650,8 +650,8 @@ class ItemDict(TypedDict, total=False): 'doom_type': 2006, 'episode': -1, 'map': -1}, - 350106: {'classification': ItemClassification.progression, - 'count': 1, + 350106: {'classification': ItemClassification.useful, + 'count': 0, 'name': 'Backpack', 'doom_type': 8, 'episode': -1, @@ -1160,6 +1160,30 @@ class ItemDict(TypedDict, total=False): 'doom_type': 2026, 'episode': 4, 'map': 9}, + 350191: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Bullet capacity', + 'doom_type': 65001, + 'episode': -1, + 'map': -1}, + 350192: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Shell capacity', + 'doom_type': 65002, + 'episode': -1, + 'map': -1}, + 350193: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Energy cell capacity', + 'doom_type': 65003, + 'episode': -1, + 'map': -1}, + 350194: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Rocket capacity', + 'doom_type': 65004, + 'episode': -1, + 'map': -1}, } diff --git a/worlds/doom_1993/Options.py b/worlds/doom_1993/Options.py index c9c61110328c..c741df382033 100644 --- a/worlds/doom_1993/Options.py +++ b/worlds/doom_1993/Options.py @@ -1,4 +1,4 @@ -from Options import PerGameCommonOptions, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool +from Options import PerGameCommonOptions, Range, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool from dataclasses import dataclass @@ -144,6 +144,84 @@ class Episode4(Toggle): display_name = "Episode 4" +class SplitBackpack(Toggle): + """Split the Backpack into four individual items, each one increasing ammo capacity for one type of weapon only.""" + display_name = "Split Backpack" + + +class BackpackCount(Range): + """How many Backpacks will be available. + If Split Backpack is set, this will be the number of each capacity upgrade available.""" + display_name = "Backpack Count" + range_start = 0 + range_end = 10 + default = 1 + + +class MaxAmmoBullets(Range): + """Set the starting ammo capacity for bullets.""" + display_name = "Max Ammo - Bullets" + range_start = 200 + range_end = 999 + default = 200 + + +class MaxAmmoShells(Range): + """Set the starting ammo capacity for shotgun shells.""" + display_name = "Max Ammo - Shells" + range_start = 50 + range_end = 999 + default = 50 + + +class MaxAmmoRockets(Range): + """Set the starting ammo capacity for rockets.""" + display_name = "Max Ammo - Rockets" + range_start = 50 + range_end = 999 + default = 50 + + +class MaxAmmoEnergyCells(Range): + """Set the starting ammo capacity for energy cells.""" + display_name = "Max Ammo - Energy Cells" + range_start = 300 + range_end = 999 + default = 300 + + +class AddedAmmoBullets(Range): + """Set the amount of bullet capacity added when collecting a backpack or capacity upgrade.""" + display_name = "Added Ammo - Bullets" + range_start = 20 + range_end = 999 + default = 200 + + +class AddedAmmoShells(Range): + """Set the amount of shotgun shell capacity added when collecting a backpack or capacity upgrade.""" + display_name = "Added Ammo - Shells" + range_start = 5 + range_end = 999 + default = 50 + + +class AddedAmmoRockets(Range): + """Set the amount of rocket capacity added when collecting a backpack or capacity upgrade.""" + display_name = "Added Ammo - Rockets" + range_start = 5 + range_end = 999 + default = 50 + + +class AddedAmmoEnergyCells(Range): + """Set the amount of energy cell capacity added when collecting a backpack or capacity upgrade.""" + display_name = "Added Ammo - Energy Cells" + range_start = 30 + range_end = 999 + default = 300 + + @dataclass class DOOM1993Options(PerGameCommonOptions): start_inventory_from_pool: StartInventoryPool @@ -163,3 +241,14 @@ class DOOM1993Options(PerGameCommonOptions): episode3: Episode3 episode4: Episode4 + split_backpack: SplitBackpack + backpack_count: BackpackCount + max_ammo_bullets: MaxAmmoBullets + max_ammo_shells: MaxAmmoShells + max_ammo_rockets: MaxAmmoRockets + max_ammo_energy_cells: MaxAmmoEnergyCells + added_ammo_bullets: AddedAmmoBullets + added_ammo_shells: AddedAmmoShells + added_ammo_rockets: AddedAmmoRockets + added_ammo_energy_cells: AddedAmmoEnergyCells + diff --git a/worlds/doom_1993/__init__.py b/worlds/doom_1993/__init__.py index b6138ae07103..d459290f9292 100644 --- a/worlds/doom_1993/__init__.py +++ b/worlds/doom_1993/__init__.py @@ -42,7 +42,7 @@ class DOOM1993World(World): options: DOOM1993Options game = "DOOM 1993" web = DOOM1993Web() - required_client_version = (0, 3, 9) + required_client_version = (0, 5, 0) # 1.2.0-prerelease or higher item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()} item_name_groups = Items.item_name_groups @@ -204,6 +204,15 @@ def create_items(self): count = item["count"] if item["name"] not in self.starting_level_for_episode else item["count"] - 1 itempool += [self.create_item(item["name"]) for _ in range(count)] + # Backpack(s) based on options + if self.options.split_backpack.value: + itempool += [self.create_item("Bullet capacity") for _ in range(self.options.backpack_count.value)] + itempool += [self.create_item("Shell capacity") for _ in range(self.options.backpack_count.value)] + itempool += [self.create_item("Energy cell capacity") for _ in range(self.options.backpack_count.value)] + itempool += [self.create_item("Rocket capacity") for _ in range(self.options.backpack_count.value)] + else: + itempool += [self.create_item("Backpack") for _ in range(self.options.backpack_count.value)] + # Place end level items in locked locations for map_name in Maps.map_names: loc_name = map_name + " - Exit" @@ -265,7 +274,7 @@ def create_ratioed_items(self, item_name: str, itempool: List[DOOM1993Item]): # Was balanced for 3 episodes (We added 4th episode, but keep same ratio) count = min(remaining_loc, max(1, int(round(self.items_ratio[item_name] * ep_count / 3)))) if count == 0: - logger.warning("Warning, no ", item_name, " will be placed.") + logger.warning(f"Warning, no {item_name} will be placed.") return for i in range(count): @@ -281,4 +290,14 @@ def fill_slot_data(self) -> Dict[str, Any]: # an older version, the player would end up stuck. slot_data["two_ways_keydoors"] = True + # Send slot data for ammo capacity values; this must be generic because Heretic uses it too + slot_data["ammo1start"] = self.options.max_ammo_bullets.value + slot_data["ammo2start"] = self.options.max_ammo_shells.value + slot_data["ammo3start"] = self.options.max_ammo_energy_cells.value + slot_data["ammo4start"] = self.options.max_ammo_rockets.value + slot_data["ammo1add"] = self.options.added_ammo_bullets.value + slot_data["ammo2add"] = self.options.added_ammo_shells.value + slot_data["ammo3add"] = self.options.added_ammo_energy_cells.value + slot_data["ammo4add"] = self.options.added_ammo_rockets.value + return slot_data diff --git a/worlds/doom_ii/Items.py b/worlds/doom_ii/Items.py index fc426cc883f2..009e6034cdf8 100644 --- a/worlds/doom_ii/Items.py +++ b/worlds/doom_ii/Items.py @@ -56,8 +56,8 @@ class ItemDict(TypedDict, total=False): 'doom_type': 82, 'episode': -1, 'map': -1}, - 360007: {'classification': ItemClassification.progression, - 'count': 1, + 360007: {'classification': ItemClassification.useful, + 'count': 0, 'name': 'Backpack', 'doom_type': 8, 'episode': -1, @@ -1058,6 +1058,30 @@ class ItemDict(TypedDict, total=False): 'doom_type': 2026, 'episode': 4, 'map': 2}, + 360600: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Bullet capacity', + 'doom_type': 65001, + 'episode': -1, + 'map': -1}, + 360601: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Shell capacity', + 'doom_type': 65002, + 'episode': -1, + 'map': -1}, + 360602: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Energy cell capacity', + 'doom_type': 65003, + 'episode': -1, + 'map': -1}, + 360603: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Rocket capacity', + 'doom_type': 65004, + 'episode': -1, + 'map': -1}, } diff --git a/worlds/doom_ii/Options.py b/worlds/doom_ii/Options.py index 98c8ebc56e16..c8b0c9fb08fd 100644 --- a/worlds/doom_ii/Options.py +++ b/worlds/doom_ii/Options.py @@ -1,6 +1,6 @@ import typing -from Options import PerGameCommonOptions, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool +from Options import PerGameCommonOptions, Range, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool from dataclasses import dataclass @@ -136,6 +136,84 @@ class SecretLevels(Toggle): display_name = "Secret Levels" +class SplitBackpack(Toggle): + """Split the Backpack into four individual items, each one increasing ammo capacity for one type of weapon only.""" + display_name = "Split Backpack" + + +class BackpackCount(Range): + """How many Backpacks will be available. + If Split Backpack is set, this will be the number of each capacity upgrade available.""" + display_name = "Backpack Count" + range_start = 0 + range_end = 10 + default = 1 + + +class MaxAmmoBullets(Range): + """Set the starting ammo capacity for bullets.""" + display_name = "Max Ammo - Bullets" + range_start = 200 + range_end = 999 + default = 200 + + +class MaxAmmoShells(Range): + """Set the starting ammo capacity for shotgun shells.""" + display_name = "Max Ammo - Shells" + range_start = 50 + range_end = 999 + default = 50 + + +class MaxAmmoRockets(Range): + """Set the starting ammo capacity for rockets.""" + display_name = "Max Ammo - Rockets" + range_start = 50 + range_end = 999 + default = 50 + + +class MaxAmmoEnergyCells(Range): + """Set the starting ammo capacity for energy cells.""" + display_name = "Max Ammo - Energy Cells" + range_start = 300 + range_end = 999 + default = 300 + + +class AddedAmmoBullets(Range): + """Set the amount of bullet capacity added when collecting a backpack or capacity upgrade.""" + display_name = "Added Ammo - Bullets" + range_start = 20 + range_end = 999 + default = 200 + + +class AddedAmmoShells(Range): + """Set the amount of shotgun shell capacity added when collecting a backpack or capacity upgrade.""" + display_name = "Added Ammo - Shells" + range_start = 5 + range_end = 999 + default = 50 + + +class AddedAmmoRockets(Range): + """Set the amount of rocket capacity added when collecting a backpack or capacity upgrade.""" + display_name = "Added Ammo - Rockets" + range_start = 5 + range_end = 999 + default = 50 + + +class AddedAmmoEnergyCells(Range): + """Set the amount of energy cell capacity added when collecting a backpack or capacity upgrade.""" + display_name = "Added Ammo - Energy Cells" + range_start = 30 + range_end = 999 + default = 300 + + @dataclass class DOOM2Options(PerGameCommonOptions): start_inventory_from_pool: StartInventoryPool @@ -153,3 +231,14 @@ class DOOM2Options(PerGameCommonOptions): episode2: Episode2 episode3: Episode3 episode4: SecretLevels + + split_backpack: SplitBackpack + backpack_count: BackpackCount + max_ammo_bullets: MaxAmmoBullets + max_ammo_shells: MaxAmmoShells + max_ammo_rockets: MaxAmmoRockets + max_ammo_energy_cells: MaxAmmoEnergyCells + added_ammo_bullets: AddedAmmoBullets + added_ammo_shells: AddedAmmoShells + added_ammo_rockets: AddedAmmoRockets + added_ammo_energy_cells: AddedAmmoEnergyCells diff --git a/worlds/doom_ii/__init__.py b/worlds/doom_ii/__init__.py index 32c3cbd5a2c1..815e21419aff 100644 --- a/worlds/doom_ii/__init__.py +++ b/worlds/doom_ii/__init__.py @@ -43,7 +43,7 @@ class DOOM2World(World): options: DOOM2Options game = "DOOM II" web = DOOM2Web() - required_client_version = (0, 3, 9) + required_client_version = (0, 5, 0) # 1.2.0-prerelease or higher item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()} item_name_groups = Items.item_name_groups @@ -196,6 +196,15 @@ def create_items(self): count = item["count"] if item["name"] not in self.starting_level_for_episode else item["count"] - 1 itempool += [self.create_item(item["name"]) for _ in range(count)] + # Backpack(s) based on options + if self.options.split_backpack.value: + itempool += [self.create_item("Bullet capacity") for _ in range(self.options.backpack_count.value)] + itempool += [self.create_item("Shell capacity") for _ in range(self.options.backpack_count.value)] + itempool += [self.create_item("Energy cell capacity") for _ in range(self.options.backpack_count.value)] + itempool += [self.create_item("Rocket capacity") for _ in range(self.options.backpack_count.value)] + else: + itempool += [self.create_item("Backpack") for _ in range(self.options.backpack_count.value)] + # Place end level items in locked locations for map_name in Maps.map_names: loc_name = map_name + " - Exit" @@ -258,11 +267,23 @@ def create_ratioed_items(self, item_name: str, itempool: List[DOOM2Item]): # Was balanced based on DOOM 1993's first 3 episodes count = min(remaining_loc, max(1, int(round(self.items_ratio[item_name] * ep_count / 3)))) if count == 0: - logger.warning("Warning, no ", item_name, " will be placed.") + logger.warning(f"Warning, no {item_name} will be placed.") return for i in range(count): itempool.append(self.create_item(item_name)) def fill_slot_data(self) -> Dict[str, Any]: - return self.options.as_dict("difficulty", "random_monsters", "random_pickups", "random_music", "flip_levels", "allow_death_logic", "pro", "death_link", "reset_level_on_death", "episode1", "episode2", "episode3", "episode4") + slot_data = self.options.as_dict("difficulty", "random_monsters", "random_pickups", "random_music", "flip_levels", "allow_death_logic", "pro", "death_link", "reset_level_on_death", "episode1", "episode2", "episode3", "episode4") + + # Send slot data for ammo capacity values; this must be generic because Heretic uses it too + slot_data["ammo1start"] = self.options.max_ammo_bullets.value + slot_data["ammo2start"] = self.options.max_ammo_shells.value + slot_data["ammo3start"] = self.options.max_ammo_energy_cells.value + slot_data["ammo4start"] = self.options.max_ammo_rockets.value + slot_data["ammo1add"] = self.options.added_ammo_bullets.value + slot_data["ammo2add"] = self.options.added_ammo_shells.value + slot_data["ammo3add"] = self.options.added_ammo_energy_cells.value + slot_data["ammo4add"] = self.options.added_ammo_rockets.value + + return slot_data diff --git a/worlds/heretic/Items.py b/worlds/heretic/Items.py index a0907a3a3040..777bf06cdae8 100644 --- a/worlds/heretic/Items.py +++ b/worlds/heretic/Items.py @@ -50,8 +50,8 @@ class ItemDict(TypedDict, total=False): 'doom_type': 2004, 'episode': -1, 'map': -1}, - 370006: {'classification': ItemClassification.progression, - 'count': 1, + 370006: {'classification': ItemClassification.useful, + 'count': 0, 'name': 'Bag of Holding', 'doom_type': 8, 'episode': -1, @@ -1592,6 +1592,42 @@ class ItemDict(TypedDict, total=False): 'doom_type': 35, 'episode': 5, 'map': 9}, + 370600: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Crystal Capacity', + 'doom_type': 65001, + 'episode': -1, + 'map': -1}, + 370601: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Ethereal Arrow Capacity', + 'doom_type': 65002, + 'episode': -1, + 'map': -1}, + 370602: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Claw Orb Capacity', + 'doom_type': 65003, + 'episode': -1, + 'map': -1}, + 370603: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Rune Capacity', + 'doom_type': 65004, + 'episode': -1, + 'map': -1}, + 370604: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Flame Orb Capacity', + 'doom_type': 65005, + 'episode': -1, + 'map': -1}, + 370605: {'classification': ItemClassification.useful, + 'count': 0, + 'name': 'Mace Sphere Capacity', + 'doom_type': 65006, + 'episode': -1, + 'map': -1}, } diff --git a/worlds/heretic/Options.py b/worlds/heretic/Options.py index 7d98207b0f8e..fe64f5878305 100644 --- a/worlds/heretic/Options.py +++ b/worlds/heretic/Options.py @@ -1,4 +1,4 @@ -from Options import PerGameCommonOptions, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool +from Options import PerGameCommonOptions, Range, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool from dataclasses import dataclass @@ -144,6 +144,116 @@ class Episode5(Toggle): display_name = "Episode 5" +class SplitBagOfHolding(Toggle): + """Split the Bag of Holding into six individual items, each one increasing ammo capacity for one type of weapon only.""" + display_name = "Split Bag of Holding" + + +class BagOfHoldingCount(Range): + """How many Bags of Holding will be available. + If Split Bag of Holding is set, this will be the number of each capacity upgrade available.""" + display_name = "Bag of Holding Count" + range_start = 0 + range_end = 10 + default = 1 + + +class MaxAmmoCrystals(Range): + """Set the starting ammo capacity for crystals (Elven Wand ammo).""" + display_name = "Max Ammo - Crystals" + range_start = 100 + range_end = 999 + default = 100 + + +class MaxAmmoArrows(Range): + """Set the starting ammo capacity for arrows (Ethereal Crossbow ammo).""" + display_name = "Max Ammo - Arrows" + range_start = 50 + range_end = 999 + default = 50 + + +class MaxAmmoClawOrbs(Range): + """Set the starting ammo capacity for claw orbs (Dragon Claw ammo).""" + display_name = "Max Ammo - Claw Orbs" + range_start = 200 + range_end = 999 + default = 200 + + +class MaxAmmoRunes(Range): + """Set the starting ammo capacity for runes (Hellstaff ammo).""" + display_name = "Max Ammo - Runes" + range_start = 200 + range_end = 999 + default = 200 + + +class MaxAmmoFlameOrbs(Range): + """Set the starting ammo capacity for flame orbs (Phoenix Rod ammo).""" + display_name = "Max Ammo - Flame Orbs" + range_start = 20 + range_end = 999 + default = 20 + + +class MaxAmmoSpheres(Range): + """Set the starting ammo capacity for spheres (Firemace ammo).""" + display_name = "Max Ammo - Spheres" + range_start = 150 + range_end = 999 + default = 150 + + +class AddedAmmoCrystals(Range): + """Set the amount of crystal capacity gained when collecting a bag of holding or a capacity upgrade.""" + display_name = "Added Ammo - Crystals" + range_start = 10 + range_end = 999 + default = 100 + + +class AddedAmmoArrows(Range): + """Set the amount of arrow capacity gained when collecting a bag of holding or a capacity upgrade.""" + display_name = "Added Ammo - Arrows" + range_start = 5 + range_end = 999 + default = 50 + + +class AddedAmmoClawOrbs(Range): + """Set the amount of claw orb capacity gained when collecting a bag of holding or a capacity upgrade.""" + display_name = "Added Ammo - Claw Orbs" + range_start = 20 + range_end = 999 + default = 200 + + +class AddedAmmoRunes(Range): + """Set the amount of rune capacity gained when collecting a bag of holding or a capacity upgrade.""" + display_name = "Added Ammo - Runes" + range_start = 20 + range_end = 999 + default = 200 + + +class AddedAmmoFlameOrbs(Range): + """Set the amount of flame orb capacity gained when collecting a bag of holding or a capacity upgrade.""" + display_name = "Added Ammo - Flame Orbs" + range_start = 2 + range_end = 999 + default = 20 + + +class AddedAmmoSpheres(Range): + """Set the amount of sphere capacity gained when collecting a bag of holding or a capacity upgrade.""" + display_name = "Added Ammo - Spheres" + range_start = 15 + range_end = 999 + default = 150 + + @dataclass class HereticOptions(PerGameCommonOptions): start_inventory_from_pool: StartInventoryPool @@ -163,3 +273,18 @@ class HereticOptions(PerGameCommonOptions): episode3: Episode3 episode4: Episode4 episode5: Episode5 + + split_bag_of_holding: SplitBagOfHolding + bag_of_holding_count: BagOfHoldingCount + max_ammo_crystals: MaxAmmoCrystals + max_ammo_arrows: MaxAmmoArrows + max_ammo_claw_orbs: MaxAmmoClawOrbs + max_ammo_runes: MaxAmmoRunes + max_ammo_flame_orbs: MaxAmmoFlameOrbs + max_ammo_spheres: MaxAmmoSpheres + added_ammo_crystals: AddedAmmoCrystals + added_ammo_arrows: AddedAmmoArrows + added_ammo_claw_orbs: AddedAmmoClawOrbs + added_ammo_runes: AddedAmmoRunes + added_ammo_flame_orbs: AddedAmmoFlameOrbs + added_ammo_spheres: AddedAmmoSpheres diff --git a/worlds/heretic/Rules.py b/worlds/heretic/Rules.py index 579fd8b77179..492b8f38c60d 100644 --- a/worlds/heretic/Rules.py +++ b/worlds/heretic/Rules.py @@ -695,13 +695,11 @@ def set_episode5_rules(player, multiworld, pro): state.has("Phoenix Rod", player, 1) and state.has("Firemace", player, 1) and state.has("Hellstaff", player, 1) and - state.has("Gauntlets of the Necromancer", player, 1) and - state.has("Bag of Holding", player, 1)) + state.has("Gauntlets of the Necromancer", player, 1)) # Skein of D'Sparil (E5M9) set_rule(multiworld.get_entrance("Hub -> Skein of D'Sparil (E5M9) Main", player), lambda state: state.has("Skein of D'Sparil (E5M9)", player, 1) and - state.has("Bag of Holding", player, 1) and state.has("Hellstaff", player, 1) and state.has("Phoenix Rod", player, 1) and state.has("Dragon Claw", player, 1) and diff --git a/worlds/heretic/__init__.py b/worlds/heretic/__init__.py index bc0a54698a59..14b7ca49feda 100644 --- a/worlds/heretic/__init__.py +++ b/worlds/heretic/__init__.py @@ -41,7 +41,7 @@ class HereticWorld(World): options: HereticOptions game = "Heretic" web = HereticWeb() - required_client_version = (0, 3, 9) + required_client_version = (0, 5, 0) # 1.2.0-prerelease or higher item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()} item_name_groups = Items.item_name_groups @@ -206,6 +206,17 @@ def create_items(self): count = item["count"] if item["name"] not in self.starting_level_for_episode else item["count"] - 1 itempool += [self.create_item(item["name"]) for _ in range(count)] + # Bag(s) of Holding based on options + if self.options.split_bag_of_holding.value: + itempool += [self.create_item("Crystal Capacity") for _ in range(self.options.bag_of_holding_count.value)] + itempool += [self.create_item("Ethereal Arrow Capacity") for _ in range(self.options.bag_of_holding_count.value)] + itempool += [self.create_item("Claw Orb Capacity") for _ in range(self.options.bag_of_holding_count.value)] + itempool += [self.create_item("Rune Capacity") for _ in range(self.options.bag_of_holding_count.value)] + itempool += [self.create_item("Flame Orb Capacity") for _ in range(self.options.bag_of_holding_count.value)] + itempool += [self.create_item("Mace Sphere Capacity") for _ in range(self.options.bag_of_holding_count.value)] + else: + itempool += [self.create_item("Bag of Holding") for _ in range(self.options.bag_of_holding_count.value)] + # Place end level items in locked locations for map_name in Maps.map_names: loc_name = map_name + " - Exit" @@ -274,7 +285,7 @@ def create_ratioed_items(self, item_name: str, itempool: List[HereticItem]): episode_count = self.get_episode_count() count = min(remaining_loc, max(1, self.items_ratio[item_name] * episode_count)) if count == 0: - logger.warning("Warning, no " + item_name + " will be placed.") + logger.warning(f"Warning, no {item_name} will be placed.") return for i in range(count): @@ -290,4 +301,18 @@ def fill_slot_data(self) -> Dict[str, Any]: slot_data["episode4"] = self.included_episodes[3] slot_data["episode5"] = self.included_episodes[4] + # Send slot data for ammo capacity values; this must be generic because Doom uses it too + slot_data["ammo1start"] = self.options.max_ammo_crystals.value + slot_data["ammo2start"] = self.options.max_ammo_arrows.value + slot_data["ammo3start"] = self.options.max_ammo_claw_orbs.value + slot_data["ammo4start"] = self.options.max_ammo_runes.value + slot_data["ammo5start"] = self.options.max_ammo_flame_orbs.value + slot_data["ammo6start"] = self.options.max_ammo_spheres.value + slot_data["ammo1add"] = self.options.added_ammo_crystals.value + slot_data["ammo2add"] = self.options.added_ammo_arrows.value + slot_data["ammo3add"] = self.options.added_ammo_claw_orbs.value + slot_data["ammo4add"] = self.options.added_ammo_runes.value + slot_data["ammo5add"] = self.options.added_ammo_flame_orbs.value + slot_data["ammo6add"] = self.options.added_ammo_spheres.value + return slot_data From ee9bcb84b7fd5e642b667f9b715cf2520bc18c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sat, 8 Mar 2025 11:19:29 -0500 Subject: [PATCH 0180/1218] Stardew Valley: Move progressive tool options handling in features (#4374) * create tool progression feature and unwrap option * replace option usage with calling feature * add comment explaining why some logic is a weird place * replace item creation logic with feature * self review and add unit tests * rename test cuz I named them too long * add a test for the trash can useful stuff cuz I thought there was a bug but turns out it works * self review again * remove price_multiplier, turns out it's unused during generation * damn it 3.11 why are you like this * use blacksmith region when checking vanilla tools * fix rule * move can mine using in tool logic * remove changes to performance test * properly set the option I guess * properly set options 2 * that's what happen when you code too late --- worlds/stardew_valley/content/__init__.py | 18 ++++- .../content/feature/__init__.py | 1 + .../content/feature/tool_progression.py | 68 +++++++++++++++++ worlds/stardew_valley/content/game_content.py | 3 +- worlds/stardew_valley/early_items.py | 2 +- worlds/stardew_valley/items.py | 34 +++------ worlds/stardew_valley/locations.py | 4 +- worlds/stardew_valley/logic/mine_logic.py | 13 ++-- worlds/stardew_valley/logic/tool_logic.py | 27 +++++-- .../stardew_valley/mods/logic/item_logic.py | 3 +- worlds/stardew_valley/options/options.py | 8 ++ worlds/stardew_valley/rules.py | 25 +++---- .../stardew_valley/strings/entrance_names.py | 13 +++- worlds/stardew_valley/strings/region_names.py | 13 +++- worlds/stardew_valley/test/TestGeneration.py | 6 +- worlds/stardew_valley/test/TestOptionFlags.py | 12 +-- worlds/stardew_valley/test/TestOptions.py | 74 +++++++------------ .../stardew_valley/test/TestWalnutsanity.py | 6 +- .../stardew_valley/test/content/__init__.py | 1 + .../content/feature/TestToolProgression.py | 52 +++++++++++++ 20 files changed, 262 insertions(+), 121 deletions(-) create mode 100644 worlds/stardew_valley/content/feature/tool_progression.py create mode 100644 worlds/stardew_valley/test/content/feature/TestToolProgression.py diff --git a/worlds/stardew_valley/content/__init__.py b/worlds/stardew_valley/content/__init__.py index 54b4d75d5e5c..530850643749 100644 --- a/worlds/stardew_valley/content/__init__.py +++ b/worlds/stardew_valley/content/__init__.py @@ -1,5 +1,5 @@ from . import content_packs -from .feature import cropsanity, friendsanity, fishsanity, booksanity, skill_progression +from .feature import cropsanity, friendsanity, fishsanity, booksanity, skill_progression, tool_progression from .game_content import ContentPack, StardewContent, StardewFeatures from .unpacking import unpack_content from .. import options @@ -33,6 +33,7 @@ def choose_features(player_options: options.StardewValleyOptions) -> StardewFeat choose_fishsanity(player_options.fishsanity), choose_friendsanity(player_options.friendsanity, player_options.friendsanity_heart_size), choose_skill_progression(player_options.skill_progression), + choose_tool_progression(player_options.tool_progression, player_options.skill_progression), ) @@ -122,3 +123,18 @@ def choose_skill_progression(skill_progression_option: options.SkillProgression) raise ValueError(f"No skill progression feature mapped to {str(skill_progression_option.value)}") return skill_progression_feature + + +def choose_tool_progression(tool_option: options.ToolProgression, skill_option: options.SkillProgression) -> tool_progression.ToolProgressionFeature: + if tool_option.is_vanilla: + return tool_progression.ToolProgressionVanilla() + + tools_distribution = tool_progression.get_tools_distribution( + progressive_tools_enabled=True, + skill_masteries_enabled=skill_option == options.SkillProgression.option_progressive_with_masteries, + ) + + if tool_option.is_progressive: + return tool_progression.ToolProgressionProgressive(tools_distribution) + + raise ValueError(f"No tool progression feature mapped to {str(tool_option.value)}") diff --git a/worlds/stardew_valley/content/feature/__init__.py b/worlds/stardew_valley/content/feature/__init__.py index f3e5c6732e32..eb23f8105bd3 100644 --- a/worlds/stardew_valley/content/feature/__init__.py +++ b/worlds/stardew_valley/content/feature/__init__.py @@ -3,3 +3,4 @@ from . import fishsanity from . import friendsanity from . import skill_progression +from . import tool_progression diff --git a/worlds/stardew_valley/content/feature/tool_progression.py b/worlds/stardew_valley/content/feature/tool_progression.py new file mode 100644 index 000000000000..d5fe5cef99de --- /dev/null +++ b/worlds/stardew_valley/content/feature/tool_progression.py @@ -0,0 +1,68 @@ +from abc import ABC +from collections import Counter +from collections.abc import Mapping +from dataclasses import dataclass, field +from functools import cache +from types import MappingProxyType +from typing import ClassVar + +from ...strings.tool_names import Tool + + +def to_progressive_item(tool: str) -> str: + """Return the name of the progressive item.""" + return f"Progressive {tool}" + + +# The golden scythe is always randomized +VANILLA_TOOL_DISTRIBUTION = MappingProxyType({ + Tool.scythe: 1, +}) + +PROGRESSIVE_TOOL_DISTRIBUTION = MappingProxyType({ + Tool.axe: 4, + Tool.hoe: 4, + Tool.pickaxe: 4, + Tool.pan: 4, + Tool.trash_can: 4, + Tool.watering_can: 4, + Tool.fishing_rod: 4, +}) + +# Masteries add another tier to the scythe and the fishing rod +SKILL_MASTERIES_TOOL_DISTRIBUTION = MappingProxyType({ + Tool.scythe: 1, + Tool.fishing_rod: 1, +}) + + +@cache +def get_tools_distribution(progressive_tools_enabled: bool, skill_masteries_enabled: bool) -> Mapping[str, int]: + distribution = Counter(VANILLA_TOOL_DISTRIBUTION) + + if progressive_tools_enabled: + distribution += PROGRESSIVE_TOOL_DISTRIBUTION + + if skill_masteries_enabled: + distribution += SKILL_MASTERIES_TOOL_DISTRIBUTION + + return MappingProxyType(distribution) + + +@dataclass(frozen=True) +class ToolProgressionFeature(ABC): + is_progressive: ClassVar[bool] + tool_distribution: Mapping[str, int] + + to_progressive_item = staticmethod(to_progressive_item) + + +@dataclass(frozen=True) +class ToolProgressionVanilla(ToolProgressionFeature): + is_progressive = False + # FIXME change the default_factory to a simple default when python 3.11 is no longer supported + tool_distribution: Mapping[str, int] = field(default_factory=lambda: VANILLA_TOOL_DISTRIBUTION) + + +class ToolProgressionProgressive(ToolProgressionFeature): + is_progressive = True diff --git a/worlds/stardew_valley/content/game_content.py b/worlds/stardew_valley/content/game_content.py index 7ff3217b04ed..3aa3350f4714 100644 --- a/worlds/stardew_valley/content/game_content.py +++ b/worlds/stardew_valley/content/game_content.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field from typing import Dict, Iterable, Set, Any, Mapping, Type, Tuple, Union -from .feature import booksanity, cropsanity, fishsanity, friendsanity, skill_progression +from .feature import booksanity, cropsanity, fishsanity, friendsanity, skill_progression, tool_progression from ..data.fish_data import FishItem from ..data.game_item import GameItem, ItemSource, ItemTag from ..data.skill import Skill @@ -54,6 +54,7 @@ class StardewFeatures: fishsanity: fishsanity.FishsanityFeature friendsanity: friendsanity.FriendsanityFeature skill_progression: skill_progression.SkillProgressionFeature + tool_progression: tool_progression.ToolProgressionFeature @dataclass(frozen=True) diff --git a/worlds/stardew_valley/early_items.py b/worlds/stardew_valley/early_items.py index 81e28956b3cf..5ad48912a28d 100644 --- a/worlds/stardew_valley/early_items.py +++ b/worlds/stardew_valley/early_items.py @@ -32,7 +32,7 @@ def setup_early_items(multiworld, options: stardew_options.StardewValleyOptions, if options.backpack_progression == stardew_options.BackpackProgression.option_early_progressive: early_forced.append("Progressive Backpack") - if options.tool_progression & stardew_options.ToolProgression.option_progressive: + if content.features.tool_progression.is_progressive: if content.features.fishsanity.is_enabled: early_candidates.append("Progressive Fishing Rod") early_forced.append("Progressive Pickaxe") diff --git a/worlds/stardew_valley/items.py b/worlds/stardew_valley/items.py index 6ac827f869cc..056a4f6e397d 100644 --- a/worlds/stardew_valley/items.py +++ b/worlds/stardew_valley/items.py @@ -15,7 +15,7 @@ from .logic.logic_event import all_events from .mods.mod_data import ModNames from .options import StardewValleyOptions, TrapItems, FestivalLocations, ExcludeGingerIsland, SpecialOrderLocations, SeasonRandomization, Museumsanity, \ - BuildingProgression, ToolProgression, ElevatorProgression, BackpackProgression, ArcadeMachineLocations, Monstersanity, Goal, \ + BuildingProgression, ElevatorProgression, BackpackProgression, ArcadeMachineLocations, Monstersanity, Goal, \ Chefsanity, Craftsanity, BundleRandomization, EntranceRandomization, Shipsanity, Walnutsanity, EnabledFillerBuffs from .strings.ap_names.ap_option_names import BuffOptionName, WalnutsanityOptionName from .strings.ap_names.ap_weapon_names import APWeapon @@ -23,6 +23,7 @@ from .strings.ap_names.community_upgrade_names import CommunityUpgrade from .strings.ap_names.mods.mod_items import SVEQuestItem from .strings.currency_names import Currency +from .strings.tool_names import Tool from .strings.wallet_item_names import Wallet ITEM_CODE_OFFSET = 717000 @@ -119,11 +120,6 @@ def __call__(self, name: Union[str, ItemData], override_classification: ItemClas raise NotImplementedError -class StardewItemDeleter(Protocol): - def __call__(self, item: Item): - raise NotImplementedError - - def load_item_csv(): from importlib.resources import files @@ -226,7 +222,7 @@ def create_unique_items(item_factory: StardewItemFactory, options: StardewValley create_weapons(item_factory, options, items) items.append(item_factory("Skull Key")) create_elevators(item_factory, options, items) - create_tools(item_factory, options, content, items) + create_tools(item_factory, content, items) create_skills(item_factory, content, items) create_wizard_buildings(item_factory, options, items) create_carpenter_buildings(item_factory, options, items) @@ -316,23 +312,17 @@ def create_elevators(item_factory: StardewItemFactory, options: StardewValleyOpt items.extend([item_factory(item) for item in ["Progressive Skull Cavern Elevator"] * 8]) -def create_tools(item_factory: StardewItemFactory, options: StardewValleyOptions, content: StardewContent, items: List[Item]): - if options.tool_progression & ToolProgression.option_progressive: - for item_data in items_by_group[Group.PROGRESSIVE_TOOLS]: - name = item_data.name - if "Trash Can" in name: - items.extend([item_factory(item) for item in [item_data] * 3]) - items.append(item_factory(item_data, ItemClassification.useful)) - else: - items.extend([item_factory(item) for item in [item_data] * 4]) +def create_tools(item_factory: StardewItemFactory, content: StardewContent, items: List[Item]): + tool_progression = content.features.tool_progression + for tool, count in tool_progression.tool_distribution.items(): + item = item_table[tool_progression.to_progressive_item(tool)] - if content.features.skill_progression.are_masteries_shuffled: - # Masteries add another tier to the scythe and the fishing rod - items.append(item_factory("Progressive Scythe")) - items.append(item_factory("Progressive Fishing Rod")) + # Trash can is only used in tool upgrade logic, so the last trash can is not progression because it basically does not unlock anything. + if tool == Tool.trash_can: + count -= 1 + items.append(item_factory(item, ItemClassification.useful)) - # The golden scythe is always randomized - items.append(item_factory("Progressive Scythe")) + items.extend([item_factory(item) for _ in range(count)]) def create_skills(item_factory: StardewItemFactory, content: StardewContent, items: List[Item]): diff --git a/worlds/stardew_valley/locations.py b/worlds/stardew_valley/locations.py index 02c8a5441c52..df86e0812505 100644 --- a/worlds/stardew_valley/locations.py +++ b/worlds/stardew_valley/locations.py @@ -11,7 +11,7 @@ from .data.museum_data import all_museum_items from .mods.mod_data import ModNames from .options import ExcludeGingerIsland, ArcadeMachineLocations, SpecialOrderLocations, Museumsanity, \ - FestivalLocations, BuildingProgression, ToolProgression, ElevatorProgression, BackpackProgression, FarmType + FestivalLocations, BuildingProgression, ElevatorProgression, BackpackProgression, FarmType from .options import StardewValleyOptions, Craftsanity, Chefsanity, Cooksanity, Shipsanity, Monstersanity from .strings.goal_names import Goal from .strings.quest_names import ModQuest, Quest @@ -473,7 +473,7 @@ def create_locations(location_collector: StardewLocationCollector, extend_bundle_locations(randomized_locations, bundle_rooms) extend_backpack_locations(randomized_locations, options) - if options.tool_progression & ToolProgression.option_progressive: + if content.features.tool_progression.is_progressive: randomized_locations.extend(locations_by_tag[LocationTags.TOOL_UPGRADE]) extend_elevator_locations(randomized_locations, options) diff --git a/worlds/stardew_valley/logic/mine_logic.py b/worlds/stardew_valley/logic/mine_logic.py index 350582ae0dbb..e332241c1016 100644 --- a/worlds/stardew_valley/logic/mine_logic.py +++ b/worlds/stardew_valley/logic/mine_logic.py @@ -10,12 +10,11 @@ from .skill_logic import SkillLogicMixin from .tool_logic import ToolLogicMixin from .. import options -from ..options import ToolProgression from ..stardew_rule import StardewRule, True_ from ..strings.performance_names import Performance from ..strings.region_names import Region from ..strings.skill_names import Skill -from ..strings.tool_names import Tool, ToolMaterial +from ..strings.tool_names import ToolMaterial class MineLogicMixin(BaseLogicMixin): @@ -56,11 +55,12 @@ def get_weapon_rule_for_floor_tier(self, tier: int): def can_progress_in_the_mines_from_floor(self, floor: int) -> StardewRule: tier = floor // 40 rules = [] + weapon_rule = self.logic.mine.get_weapon_rule_for_floor_tier(tier) rules.append(weapon_rule) - if self.options.tool_progression & ToolProgression.option_progressive: - rules.append(self.logic.tool.has_tool(Tool.pickaxe, ToolMaterial.tiers[tier])) + tool_rule = self.logic.tool.can_mine_using(ToolMaterial.tiers[tier]) + rules.append(tool_rule) # No alternative for vanilla because we assume that you will grind the levels in the mines. if self.content.features.skill_progression.is_progressive: @@ -85,11 +85,12 @@ def has_mine_elevator_to_floor(self, floor: int) -> StardewRule: def can_progress_in_the_skull_cavern_from_floor(self, floor: int) -> StardewRule: tier = floor // 50 rules = [] + weapon_rule = self.logic.combat.has_great_weapon rules.append(weapon_rule) - if self.options.tool_progression & ToolProgression.option_progressive: - rules.append(self.logic.received("Progressive Pickaxe", min(4, max(0, tier + 2)))) + tool_rule = self.logic.tool.can_mine_using(ToolMaterial.tiers[min(4, max(0, tier + 2))]) + rules.append(tool_rule) # No alternative for vanilla because we assume that you will grind the levels in the mines. if self.content.features.skill_progression.is_progressive: diff --git a/worlds/stardew_valley/logic/tool_logic.py b/worlds/stardew_valley/logic/tool_logic.py index ba593c085ae4..8292325af7d8 100644 --- a/worlds/stardew_valley/logic/tool_logic.py +++ b/worlds/stardew_valley/logic/tool_logic.py @@ -8,12 +8,11 @@ from .region_logic import RegionLogicMixin from .season_logic import SeasonLogicMixin from ..mods.logic.magic_logic import MagicLogicMixin -from ..options import ToolProgression from ..stardew_rule import StardewRule, True_, False_ from ..strings.ap_names.skill_level_names import ModSkillLevel -from ..strings.region_names import Region +from ..strings.region_names import Region, LogicRegion from ..strings.spells import MagicSpell -from ..strings.tool_names import ToolMaterial, Tool +from ..strings.tool_names import ToolMaterial, Tool, APTool fishing_rod_prices = { 3: 1800, @@ -57,10 +56,10 @@ def has_tool(self, tool: str, material: str = ToolMaterial.basic) -> StardewRule if material == ToolMaterial.basic or tool == Tool.scythe: return True_() - if self.options.tool_progression & ToolProgression.option_progressive: + if self.content.features.tool_progression.is_progressive: return self.logic.received(f"Progressive {tool}", tool_materials[material]) - can_upgrade_rule = self.logic.has(f"{material} Bar") & self.logic.money.can_spend_at(Region.blacksmith, tool_upgrade_prices[material]) + can_upgrade_rule = self.logic.tool._can_purchase_upgrade(material) if tool == Tool.pan: has_base_pan = self.logic.received("Glittering Boulder Removed") & self.logic.region.can_reach(Region.mountain) if material == ToolMaterial.copper: @@ -69,6 +68,20 @@ def has_tool(self, tool: str, material: str = ToolMaterial.basic) -> StardewRule return can_upgrade_rule + @cache_self1 + def can_mine_using(self, material: str) -> StardewRule: + if material == ToolMaterial.basic: + return self.logic.true_ + + if self.content.features.tool_progression.is_progressive: + return self.logic.received(APTool.pickaxe, tool_materials[material]) + else: + return self.logic.tool._can_purchase_upgrade(material) + + @cache_self1 + def _can_purchase_upgrade(self, material: str) -> StardewRule: + return self.logic.region.can_reach(LogicRegion.blacksmith_upgrade(material)) + def can_use_tool_at(self, tool: str, material: str, region: str) -> StardewRule: return self.has_tool(tool, material) & self.logic.region.can_reach(region) @@ -76,8 +89,8 @@ def can_use_tool_at(self, tool: str, material: str, region: str) -> StardewRule: def has_fishing_rod(self, level: int) -> StardewRule: assert 1 <= level <= 4, "Fishing rod 0 isn't real, it can't hurt you. Training is 1, Bamboo is 2, Fiberglass is 3 and Iridium is 4." - if self.options.tool_progression & ToolProgression.option_progressive: - return self.logic.received(f"Progressive {Tool.fishing_rod}", level) + if self.content.features.tool_progression.is_progressive: + return self.logic.received(APTool.fishing_rod, level) if level <= 2: # We assume you always have access to the Bamboo pole, because mod side there is a builtin way to get it back. diff --git a/worlds/stardew_valley/mods/logic/item_logic.py b/worlds/stardew_valley/mods/logic/item_logic.py index 12e824d21295..fd87a4a0aceb 100644 --- a/worlds/stardew_valley/mods/logic/item_logic.py +++ b/worlds/stardew_valley/mods/logic/item_logic.py @@ -1,7 +1,6 @@ from typing import Dict, Union from ..mod_data import ModNames -from ... import options from ...logic.base_logic import BaseLogicMixin, BaseLogic from ...logic.combat_logic import CombatLogicMixin from ...logic.cooking_logic import CookingLogicMixin @@ -80,7 +79,7 @@ def get_modified_item_rules_for_deep_woods(self, items: Dict[str, StardewRule]): # Gingerbread House } - if self.options.tool_progression & options.ToolProgression.option_progressive: + if self.content.features.tool_progression.is_progressive: options_to_update.update({ Ore.iridium: items[Ore.iridium] | self.logic.tool.can_use_tool_at(Tool.axe, ToolMaterial.iridium, DeepWoodsRegion.floor_50), # Iridium Tree }) diff --git a/worlds/stardew_valley/options/options.py b/worlds/stardew_valley/options/options.py index aaeeedd1b3d8..5cfdfcf9c741 100644 --- a/worlds/stardew_valley/options/options.py +++ b/worlds/stardew_valley/options/options.py @@ -247,6 +247,14 @@ class ToolProgression(Choice): option_progressive_cheap = 0b011 # 3 option_progressive_very_cheap = 0b101 # 5 + @property + def is_vanilla(self): + return not self.is_progressive + + @property + def is_progressive(self): + return bool(self.value & self.option_progressive) + class ElevatorProgression(Choice): """Shuffle the elevator? diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index 54afc31eb892..01acc7b82225 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -19,9 +19,8 @@ from .logic.time_logic import MAX_MONTHS from .logic.tool_logic import tool_upgrade_prices from .mods.mod_data import ModNames -from .options import StardewValleyOptions, Walnutsanity -from .options import ToolProgression, BuildingProgression, ExcludeGingerIsland, SpecialOrderLocations, Museumsanity, BackpackProgression, Shipsanity, \ - Monstersanity, Chefsanity, Craftsanity, ArcadeMachineLocations, Cooksanity +from .options import BuildingProgression, ExcludeGingerIsland, SpecialOrderLocations, Museumsanity, BackpackProgression, Shipsanity, \ + Monstersanity, Chefsanity, Craftsanity, ArcadeMachineLocations, Cooksanity, StardewValleyOptions, Walnutsanity from .stardew_rule import And, StardewRule, true_ from .stardew_rule.indirect_connection import look_for_indirect_connection from .stardew_rule.rule_explain import explain @@ -69,7 +68,7 @@ def set_rules(world): set_entrance_rules(logic, multiworld, player, world_options) set_ginger_island_rules(logic, multiworld, player, world_options) - set_tool_rules(logic, multiworld, player, world_options) + set_tool_rules(logic, multiworld, player, world_content) set_skills_rules(logic, multiworld, player, world_content) set_bundle_rules(bundle_rooms, logic, multiworld, player, world_options) set_building_rules(logic, multiworld, player, world_options) @@ -111,8 +110,8 @@ def set_isolated_locations_rules(logic: StardewLogic, multiworld, player): logic.season.has(Season.spring)) -def set_tool_rules(logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): - if not world_options.tool_progression & ToolProgression.option_progressive: +def set_tool_rules(logic: StardewLogic, multiworld, player, content: StardewContent): + if not content.features.tool_progression.is_progressive: return MultiWorldRules.add_rule(multiworld.get_location("Purchase Fiberglass Rod", player), @@ -281,13 +280,6 @@ def set_skull_cavern_floor_entrance_rules(logic, multiworld, player): set_entrance_rule(multiworld, player, dig_to_skull_floor(floor), rule) -def set_blacksmith_entrance_rules(logic, multiworld, player): - set_blacksmith_upgrade_rule(logic, multiworld, player, LogicEntrance.blacksmith_copper, MetalBar.copper, ToolMaterial.copper) - set_blacksmith_upgrade_rule(logic, multiworld, player, LogicEntrance.blacksmith_iron, MetalBar.iron, ToolMaterial.iron) - set_blacksmith_upgrade_rule(logic, multiworld, player, LogicEntrance.blacksmith_gold, MetalBar.gold, ToolMaterial.gold) - set_blacksmith_upgrade_rule(logic, multiworld, player, LogicEntrance.blacksmith_iridium, MetalBar.iridium, ToolMaterial.iridium) - - def set_skill_entrance_rules(logic, multiworld, player, world_options: StardewValleyOptions): set_entrance_rule(multiworld, player, LogicEntrance.grow_spring_crops, logic.farming.has_farming_tools & logic.season.has_spring) set_entrance_rule(multiworld, player, LogicEntrance.grow_summer_crops, logic.farming.has_farming_tools & logic.season.has_summer) @@ -306,6 +298,13 @@ def set_skill_entrance_rules(logic, multiworld, player, world_options: StardewVa set_entrance_rule(multiworld, player, LogicEntrance.fishing, logic.skill.can_get_fishing_xp) +def set_blacksmith_entrance_rules(logic, multiworld, player): + set_blacksmith_upgrade_rule(logic, multiworld, player, LogicEntrance.blacksmith_copper, MetalBar.copper, ToolMaterial.copper) + set_blacksmith_upgrade_rule(logic, multiworld, player, LogicEntrance.blacksmith_iron, MetalBar.iron, ToolMaterial.iron) + set_blacksmith_upgrade_rule(logic, multiworld, player, LogicEntrance.blacksmith_gold, MetalBar.gold, ToolMaterial.gold) + set_blacksmith_upgrade_rule(logic, multiworld, player, LogicEntrance.blacksmith_iridium, MetalBar.iridium, ToolMaterial.iridium) + + def set_blacksmith_upgrade_rule(logic, multiworld, player, entrance_name: str, item_name: str, tool_material: str): upgrade_rule = logic.has(item_name) & logic.money.can_spend(tool_upgrade_prices[tool_material]) set_entrance_rule(multiworld, player, entrance_name, upgrade_rule) diff --git a/worlds/stardew_valley/strings/entrance_names.py b/worlds/stardew_valley/strings/entrance_names.py index b1c84004eb7a..bad46c42947d 100644 --- a/worlds/stardew_valley/strings/entrance_names.py +++ b/worlds/stardew_valley/strings/entrance_names.py @@ -194,10 +194,15 @@ class LogicEntrance: island_cooking = "Island Cooking" shipping = "Use Shipping Bin" watch_queen_of_sauce = "Watch Queen of Sauce" - blacksmith_copper = "Upgrade Copper Tools" - blacksmith_iron = "Upgrade Iron Tools" - blacksmith_gold = "Upgrade Gold Tools" - blacksmith_iridium = "Upgrade Iridium Tools" + + @staticmethod + def blacksmith_upgrade(material: str) -> str: + return f"Upgrade {material} Tools" + + blacksmith_copper = blacksmith_upgrade("Copper") + blacksmith_iron = blacksmith_upgrade("Iron") + blacksmith_gold = blacksmith_upgrade("Gold") + blacksmith_iridium = blacksmith_upgrade("Iridium") grow_spring_crops = "Grow Spring Crops" grow_summer_crops = "Grow Summer Crops" diff --git a/worlds/stardew_valley/strings/region_names.py b/worlds/stardew_valley/strings/region_names.py index 2bbc6228ab19..567f13158185 100644 --- a/worlds/stardew_valley/strings/region_names.py +++ b/worlds/stardew_valley/strings/region_names.py @@ -159,10 +159,15 @@ class LogicRegion: kitchen = "Kitchen" shipping = "Shipping" queen_of_sauce = "The Queen of Sauce" - blacksmith_copper = "Blacksmith Copper Upgrades" - blacksmith_iron = "Blacksmith Iron Upgrades" - blacksmith_gold = "Blacksmith Gold Upgrades" - blacksmith_iridium = "Blacksmith Iridium Upgrades" + + @staticmethod + def blacksmith_upgrade(material: str) -> str: + return f"Blacksmith {material} Upgrades" + + blacksmith_copper = blacksmith_upgrade("Copper") + blacksmith_iron = blacksmith_upgrade("Iron") + blacksmith_gold = blacksmith_upgrade("Gold") + blacksmith_iridium = blacksmith_upgrade("Iridium") spring_farming = "Spring Farming" summer_farming = "Summer Farming" diff --git a/worlds/stardew_valley/test/TestGeneration.py b/worlds/stardew_valley/test/TestGeneration.py index 56f338fe8e11..38882136ce91 100644 --- a/worlds/stardew_valley/test/TestGeneration.py +++ b/worlds/stardew_valley/test/TestGeneration.py @@ -5,8 +5,8 @@ from .. import items, location_table, options from ..items import Group from ..locations import LocationTags -from ..options import Friendsanity, SpecialOrderLocations, Shipsanity, Chefsanity, SeasonRandomization, Craftsanity, ExcludeGingerIsland, ToolProgression, \ - SkillProgression, Booksanity, Walnutsanity +from ..options import Friendsanity, SpecialOrderLocations, Shipsanity, Chefsanity, SeasonRandomization, Craftsanity, ExcludeGingerIsland, SkillProgression, \ + Booksanity, Walnutsanity from ..strings.region_names import Region @@ -320,7 +320,7 @@ def generate_items_for_extra_mine_levels(self, weapon_name: str) -> List[Item]: class TestSkullCavernLogic(SVTestBase): options = { options.ElevatorProgression.internal_name: options.ElevatorProgression.option_vanilla, - ToolProgression.internal_name: ToolProgression.option_progressive, + options.ToolProgression.internal_name: options.ToolProgression.option_progressive, options.SkillProgression.internal_name: options.SkillProgression.option_progressive, } diff --git a/worlds/stardew_valley/test/TestOptionFlags.py b/worlds/stardew_valley/test/TestOptionFlags.py index 05e52b40c4bd..88f2257cabee 100644 --- a/worlds/stardew_valley/test/TestOptionFlags.py +++ b/worlds/stardew_valley/test/TestOptionFlags.py @@ -9,7 +9,7 @@ class TestBitFlagsVanilla(SVTestBase): def test_options_are_not_detected_as_progressive(self): world_options = self.world.options - tool_progressive = world_options.tool_progression & ToolProgression.option_progressive + tool_progressive = self.world.content.features.tool_progression.is_progressive building_progressive = world_options.building_progression & BuildingProgression.option_progressive self.assertFalse(tool_progressive) self.assertFalse(building_progressive) @@ -26,7 +26,7 @@ class TestBitFlagsVanillaCheap(SVTestBase): def test_options_are_not_detected_as_progressive(self): world_options = self.world.options - tool_progressive = world_options.tool_progression & ToolProgression.option_progressive + tool_progressive = self.world.content.features.tool_progression.is_progressive building_progressive = world_options.building_progression & BuildingProgression.option_progressive self.assertFalse(tool_progressive) self.assertFalse(building_progressive) @@ -43,7 +43,7 @@ class TestBitFlagsVanillaVeryCheap(SVTestBase): def test_options_are_not_detected_as_progressive(self): world_options = self.world.options - tool_progressive = world_options.tool_progression & ToolProgression.option_progressive + tool_progressive = self.world.content.features.tool_progression.is_progressive building_progressive = world_options.building_progression & BuildingProgression.option_progressive self.assertFalse(tool_progressive) self.assertFalse(building_progressive) @@ -60,7 +60,7 @@ class TestBitFlagsProgressive(SVTestBase): def test_options_are_detected_as_progressive(self): world_options = self.world.options - tool_progressive = world_options.tool_progression & ToolProgression.option_progressive + tool_progressive = self.world.content.features.tool_progression.is_progressive building_progressive = world_options.building_progression & BuildingProgression.option_progressive self.assertTrue(tool_progressive) self.assertTrue(building_progressive) @@ -77,7 +77,7 @@ class TestBitFlagsProgressiveCheap(SVTestBase): def test_options_are_detected_as_progressive(self): world_options = self.world.options - tool_progressive = world_options.tool_progression & ToolProgression.option_progressive + tool_progressive = self.world.content.features.tool_progression.is_progressive building_progressive = world_options.building_progression & BuildingProgression.option_progressive self.assertTrue(tool_progressive) self.assertTrue(building_progressive) @@ -94,7 +94,7 @@ class TestBitFlagsProgressiveVeryCheap(SVTestBase): def test_options_are_detected_as_progressive(self): world_options = self.world.options - tool_progressive = world_options.tool_progression & ToolProgression.option_progressive + tool_progressive = self.world.content.features.tool_progression.is_progressive building_progressive = world_options.building_progression & BuildingProgression.option_progressive self.assertTrue(tool_progressive) self.assertTrue(building_progressive) diff --git a/worlds/stardew_valley/test/TestOptions.py b/worlds/stardew_valley/test/TestOptions.py index 2cd83f013ae5..06bbfd457ac8 100644 --- a/worlds/stardew_valley/test/TestOptions.py +++ b/worlds/stardew_valley/test/TestOptions.py @@ -1,17 +1,17 @@ import itertools +from BaseClasses import ItemClassification from Options import NamedRange -from . import SVTestCase, allsanity_no_mods_6_x_x, allsanity_mods_6_x_x, solo_multiworld +from . import SVTestCase, allsanity_no_mods_6_x_x, allsanity_mods_6_x_x, solo_multiworld, SVTestBase from .assertion import WorldAssertMixin from .long.option_names import all_option_choices from .. import items_by_group, Group, StardewValleyWorld from ..locations import locations_by_tag, LocationTags, location_table -from ..options import ExcludeGingerIsland, ToolProgression, Goal, SeasonRandomization, TrapItems, SpecialOrderLocations, ArcadeMachineLocations, \ - SkillProgression +from ..options import ExcludeGingerIsland, ToolProgression, Goal, SeasonRandomization, TrapItems, SpecialOrderLocations, ArcadeMachineLocations from ..strings.goal_names import Goal as GoalName from ..strings.season_names import Season from ..strings.special_order_names import SpecialOrder -from ..strings.tool_names import ToolMaterial, Tool +from ..strings.tool_names import ToolMaterial, Tool, APTool SEASONS = {Season.spring, Season.summer, Season.fall, Season.winter} TOOLS = {"Hoe", "Pickaxe", "Axe", "Watering Can", "Trash Can", "Fishing Rod"} @@ -77,52 +77,30 @@ def test_given_progressive_when_generate_then_3_progressive_seasons_are_in_the_p self.assertEqual(items.count(Season.progressive), 3) -class TestToolProgression(SVTestCase): - def test_given_vanilla_when_generate_then_no_tool_in_pool(self): - world_options = {ToolProgression.internal_name: ToolProgression.option_vanilla} - with solo_multiworld(world_options) as (multi_world, _): - items = {item.name for item in multi_world.get_items()} - for tool in TOOLS: - self.assertNotIn(tool, items) - - def test_given_progressive_when_generate_then_each_tool_is_in_pool_4_times(self): - world_options = {ToolProgression.internal_name: ToolProgression.option_progressive, - SkillProgression.internal_name: SkillProgression.option_progressive} - with solo_multiworld(world_options) as (multi_world, _): - items = [item.name for item in multi_world.get_items()] - for tool in TOOLS: - count = items.count("Progressive " + tool) - self.assertEqual(count, 4, f"Progressive {tool} was there {count} times") - scythe_count = items.count("Progressive Scythe") - self.assertEqual(scythe_count, 1, f"Progressive Scythe was there {scythe_count} times") - self.assertEqual(items.count("Golden Scythe"), 0, f"Golden Scythe is deprecated") - - def test_given_progressive_with_masteries_when_generate_then_fishing_rod_is_in_the_pool_5_times(self): - world_options = {ToolProgression.internal_name: ToolProgression.option_progressive, - SkillProgression.internal_name: SkillProgression.option_progressive_with_masteries} - with solo_multiworld(world_options) as (multi_world, _): - items = [item.name for item in multi_world.get_items()] - for tool in TOOLS: - count = items.count("Progressive " + tool) - expected_count = 5 if tool == "Fishing Rod" else 4 - self.assertEqual(count, expected_count, f"Progressive {tool} was there {count} times") - scythe_count = items.count("Progressive Scythe") - self.assertEqual(scythe_count, 2, f"Progressive Scythe was there {scythe_count} times") - self.assertEqual(items.count("Golden Scythe"), 0, f"Golden Scythe is deprecated") +class TestToolProgression(SVTestBase): + options = { + ToolProgression.internal_name: ToolProgression.option_progressive, + } def test_given_progressive_when_generate_then_tool_upgrades_are_locations(self): - world_options = {ToolProgression.internal_name: ToolProgression.option_progressive} - with solo_multiworld(world_options) as (multi_world, _): - locations = {locations.name for locations in multi_world.get_locations(1)} - for material, tool in itertools.product(ToolMaterial.tiers.values(), - [Tool.hoe, Tool.pickaxe, Tool.axe, Tool.watering_can, Tool.trash_can]): - if material == ToolMaterial.basic: - continue - self.assertIn(f"{material} {tool} Upgrade", locations) - self.assertIn("Purchase Training Rod", locations) - self.assertIn("Bamboo Pole Cutscene", locations) - self.assertIn("Purchase Fiberglass Rod", locations) - self.assertIn("Purchase Iridium Rod", locations) + locations = set(self.get_real_location_names()) + for material, tool in itertools.product(ToolMaterial.tiers.values(), + [Tool.hoe, Tool.pickaxe, Tool.axe, Tool.watering_can, Tool.trash_can]): + if material == ToolMaterial.basic: + continue + self.assertIn(f"{material} {tool} Upgrade", locations) + self.assertIn("Purchase Training Rod", locations) + self.assertIn("Bamboo Pole Cutscene", locations) + self.assertIn("Purchase Fiberglass Rod", locations) + self.assertIn("Purchase Iridium Rod", locations) + + def test_given_progressive_when_generate_then_only_3_trash_can_are_progressive(self): + trash_cans = self.get_items_by_name(APTool.trash_can) + progressive_count = sum([1 for item in trash_cans if item.classification == ItemClassification.progression]) + useful_count = sum([1 for item in trash_cans if item.classification == ItemClassification.useful]) + + self.assertEqual(progressive_count, 3) + self.assertEqual(useful_count, 1) class TestGenerateAllOptionsWithExcludeGingerIsland(WorldAssertMixin, SVTestCase): diff --git a/worlds/stardew_valley/test/TestWalnutsanity.py b/worlds/stardew_valley/test/TestWalnutsanity.py index 862553dee1cb..e3f06bf1335c 100644 --- a/worlds/stardew_valley/test/TestWalnutsanity.py +++ b/worlds/stardew_valley/test/TestWalnutsanity.py @@ -1,5 +1,5 @@ from . import SVTestBase -from ..options import ExcludeGingerIsland, Walnutsanity +from ..options import ExcludeGingerIsland, Walnutsanity, ToolProgression, SkillProgression from ..strings.ap_names.ap_option_names import WalnutsanityOptionName @@ -7,6 +7,8 @@ class TestWalnutsanityNone(SVTestBase): options = { ExcludeGingerIsland: ExcludeGingerIsland.option_false, Walnutsanity: Walnutsanity.preset_none, + SkillProgression: ToolProgression.option_progressive, + ToolProgression: ToolProgression.option_progressive, } def test_no_walnut_locations(self): @@ -50,6 +52,8 @@ class TestWalnutsanityPuzzles(SVTestBase): options = { ExcludeGingerIsland: ExcludeGingerIsland.option_false, Walnutsanity: frozenset({WalnutsanityOptionName.puzzles}), + SkillProgression: ToolProgression.option_progressive, + ToolProgression: ToolProgression.option_progressive, } def test_only_puzzle_walnut_locations(self): diff --git a/worlds/stardew_valley/test/content/__init__.py b/worlds/stardew_valley/test/content/__init__.py index c666a3aae14d..0832c2e3c36d 100644 --- a/worlds/stardew_valley/test/content/__init__.py +++ b/worlds/stardew_valley/test/content/__init__.py @@ -9,6 +9,7 @@ feature.fishsanity.FishsanityNone(), feature.friendsanity.FriendsanityNone(), feature.skill_progression.SkillProgressionVanilla(), + feature.tool_progression.ToolProgressionVanilla() ) diff --git a/worlds/stardew_valley/test/content/feature/TestToolProgression.py b/worlds/stardew_valley/test/content/feature/TestToolProgression.py new file mode 100644 index 000000000000..618c78dd7a92 --- /dev/null +++ b/worlds/stardew_valley/test/content/feature/TestToolProgression.py @@ -0,0 +1,52 @@ +import unittest + +from ....content import choose_tool_progression +from ....options import ToolProgression, SkillProgression +from ....strings.tool_names import Tool + + +class TestToolDistribution(unittest.TestCase): + + def test_given_vanilla_tool_progression_when_create_feature_then_only_one_scythe_is_randomized(self): + tool_progression = ToolProgression(ToolProgression.option_vanilla) + skill_progression = SkillProgression.from_text("random") + + feature = choose_tool_progression(tool_progression, skill_progression) + + self.assertEqual(feature.tool_distribution, { + Tool.scythe: 1, + }) + + def test_given_progressive_tool_when_create_feature_then_all_tool_upgrades_are_randomized(self): + tool_progression = ToolProgression(ToolProgression.option_progressive) + skill_progression = SkillProgression(SkillProgression.option_progressive) + + feature = choose_tool_progression(tool_progression, skill_progression) + + self.assertEqual(feature.tool_distribution, { + Tool.scythe: 1, + Tool.pickaxe: 4, + Tool.axe: 4, + Tool.hoe: 4, + Tool.watering_can: 4, + Tool.trash_can: 4, + Tool.pan: 4, + Tool.fishing_rod: 4, + }) + + def test_given_progressive_tool_and_skill_masteries_when_create_feature_then_additional_scythe_and_fishing_rod_are_randomized(self): + tool_progression = ToolProgression(ToolProgression.option_progressive) + skill_progression = SkillProgression(SkillProgression.option_progressive_with_masteries) + + feature = choose_tool_progression(tool_progression, skill_progression) + + self.assertEqual(feature.tool_distribution, { + Tool.scythe: 2, + Tool.pickaxe: 4, + Tool.axe: 4, + Tool.hoe: 4, + Tool.watering_can: 4, + Tool.trash_can: 4, + Tool.pan: 4, + Tool.fishing_rod: 5, + }) From 33a75fb2cbb0d51f3d52a3c453e15ed90be4b91f Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sat, 8 Mar 2025 11:25:47 -0500 Subject: [PATCH 0181/1218] TUNIC: Breakable Shuffle (#4489) * Starting out * Rules for breakable regions * make the rest of it work, it's pr ready, boom * Make it work in not pot shuffle * Fix after merge * Fix item id overlap * Move breakable, grass, and local fill options in yaml * Fix groups getting overwritten * Rename, add new breakables * Rename more stuff * Time to rename them again * Make it actually default for breakable shuffle * Burn the signs down * Fix west courtyard pot regions * Fix fortress courtyard and beneath the fortress loc groups again * More missing loc group conversions * Replace instances of world.player with player, same for multiworld * Update worlds/tunic/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Remove unused import --- worlds/tunic/__init__.py | 39 +++- worlds/tunic/breakables.py | 466 +++++++++++++++++++++++++++++++++++++ worlds/tunic/er_data.py | 13 +- worlds/tunic/er_rules.py | 15 +- worlds/tunic/er_scripts.py | 40 ++-- worlds/tunic/items.py | 4 + worlds/tunic/locations.py | 2 + worlds/tunic/options.py | 9 + 8 files changed, 554 insertions(+), 34 deletions(-) create mode 100644 worlds/tunic/breakables.py diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 250f6706f122..ff1dc414c340 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -13,10 +13,10 @@ from .options import (TunicOptions, EntranceRando, tunic_option_groups, tunic_option_presets, TunicPlandoConnections, LaurelsLocation, LogicRules, LaurelsZips, IceGrappling, LadderStorage, check_options, get_hexagons_in_pool, HexagonQuestAbilityUnlockType) +from .breakables import breakable_location_name_to_id, breakable_location_groups, breakable_location_table from .combat_logic import area_data, CombatState from worlds.AutoWorld import WebWorld, World from Options import PlandoConnection, OptionError -from decimal import Decimal, ROUND_HALF_UP from settings import Group, Bool @@ -81,10 +81,13 @@ class TunicWorld(World): location_name_groups = location_name_groups for group_name, members in grass_location_name_groups.items(): location_name_groups.setdefault(group_name, set()).update(members) + for group_name, members in breakable_location_groups.items(): + location_name_groups.setdefault(group_name, set()).update(members) item_name_to_id = item_name_to_id location_name_to_id = standard_location_name_to_id.copy() location_name_to_id.update(grass_location_name_to_id) + location_name_to_id.update(breakable_location_name_to_id) player_location_table: Dict[str, int] ability_unlocks: Dict[str, int] @@ -158,6 +161,7 @@ def generate_early(self) -> None: self.options.entrance_rando.value = self.passthrough["entrance_rando"] self.options.shuffle_ladders.value = self.passthrough["shuffle_ladders"] self.options.grass_randomizer.value = self.passthrough.get("grass_randomizer", 0) + self.options.breakable_shuffle.value = self.passthrough.get("breakable_shuffle", 0) self.options.fixed_shop.value = self.options.fixed_shop.option_false self.options.laurels_location.value = self.options.laurels_location.option_anywhere self.options.combat_logic.value = self.passthrough["combat_logic"] @@ -170,7 +174,12 @@ def generate_early(self) -> None: if self.options.local_fill == -1: if self.options.grass_randomizer: - self.options.local_fill.value = 95 + if self.options.breakable_shuffle: + self.options.local_fill.value = 96 + else: + self.options.local_fill.value = 95 + elif self.options.breakable_shuffle: + self.options.local_fill.value = 40 else: self.options.local_fill.value = 0 @@ -182,6 +191,13 @@ def generate_early(self) -> None: self.player_location_table.update(grass_location_name_to_id) + if self.options.breakable_shuffle: + if self.options.entrance_rando: + self.player_location_table.update(breakable_location_name_to_id) + else: + self.player_location_table.update({name: num for name, num in breakable_location_name_to_id.items() + if not name.startswith("Purgatory")}) + @classmethod def stage_generate_early(cls, multiworld: MultiWorld) -> None: tunic_worlds: Tuple[TunicWorld] = multiworld.get_game_worlds("TUNIC") @@ -258,7 +274,8 @@ def create_item(self, name: str, classification: ItemClassification = None) -> T itemclass: ItemClassification = (classification or (item_data.combat_ic if self.options.combat_logic else None) or (ItemClassification.progression | ItemClassification.useful - if name == "Glass Cannon" and self.options.grass_randomizer + if name == "Glass Cannon" + and (self.options.grass_randomizer or self.options.breakable_shuffle) and not self.options.start_with_sword else None) or (ItemClassification.progression | ItemClassification.useful if name == "Shield" and self.options.ladder_storage @@ -280,6 +297,13 @@ def create_items(self) -> None: items_to_create["Fool Trap"] += items_to_create[money_fool] items_to_create[money_fool] = 0 + # creating these after the fool traps are made mostly so we don't have to mess with it + if self.options.breakable_shuffle: + for loc_data in breakable_location_table.values(): + if not self.options.entrance_rando and loc_data.er_region == "Purgatory": + continue + items_to_create[f"Money x{self.random.randint(1, 5)}"] += 1 + if self.options.start_with_sword: self.multiworld.push_precollected(self.create_item("Sword")) @@ -472,9 +496,9 @@ def create_regions(self) -> None: self.ability_unlocks["Pages 42-43 (Holy Cross)"] = self.passthrough["Hexagon Quest Holy Cross"] self.ability_unlocks["Pages 52-53 (Icebolt)"] = self.passthrough["Hexagon Quest Icebolt"] - # Ladders and Combat Logic uses ER rules with vanilla connections for easier maintenance + # Most non-standard options use ER regions if (self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic - or self.options.grass_randomizer): + or self.options.grass_randomizer or self.options.breakable_shuffle): portal_pairs = create_er_regions(self) if self.options.entrance_rando: # these get interpreted by the game to tell it which entrances to connect @@ -502,9 +526,9 @@ def create_regions(self) -> None: victory_region.locations.append(victory_location) def set_rules(self) -> None: - # same reason as in create_regions, could probably be put into create_regions + # same reason as in create_regions if (self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic - or self.options.grass_randomizer): + or self.options.grass_randomizer or self.options.breakable_shuffle): set_er_location_rules(self) else: set_region_rules(self) @@ -609,6 +633,7 @@ def fill_slot_data(self) -> Dict[str, Any]: "Hexagon Quest Goal": self.options.hexagon_goal.value, "Entrance Rando": self.tunic_portal_pairs, "disable_local_spoiler": int(self.settings.disable_local_spoiler or self.multiworld.is_race), + "breakable_shuffle": self.options.breakable_shuffle.value, } # this would be in a stage if there was an appropriate stage for it diff --git a/worlds/tunic/breakables.py b/worlds/tunic/breakables.py new file mode 100644 index 000000000000..156bece7ca0f --- /dev/null +++ b/worlds/tunic/breakables.py @@ -0,0 +1,466 @@ +from typing import TYPE_CHECKING, NamedTuple + +from enum import IntEnum +from BaseClasses import CollectionState, Region +from worlds.generic.Rules import set_rule +from .rules import has_sword, has_melee +from .er_rules import can_shop +if TYPE_CHECKING: + from . import TunicWorld + + +# just getting an id that is a decent chunk ahead of the grass ones +breakable_base_id = 509342400 + 8000 + + +class BreakableType(IntEnum): + pot = 1 + fire_pot = 2 + explosive_pot = 3 + sign = 4 + barrel = 5 + crate = 6 + table = 7 + glass = 8 + leaves = 9 + wall = 10 + + +class TunicLocationData(NamedTuple): + er_region: str + breakable: BreakableType + + +breakable_location_table: dict[str, TunicLocationData] = { + "Overworld - [Northwest] Sign by Quarry Gate": TunicLocationData("Overworld", BreakableType.sign), + "Overworld - [Central] Sign South of Checkpoint": TunicLocationData("Overworld", BreakableType.sign), + "Overworld - [Central] Sign by Ruined Passage": TunicLocationData("Overworld", BreakableType.sign), + "Overworld - [East] Pot near Slimes 1": TunicLocationData("East Overworld", BreakableType.pot), + "Overworld - [East] Pot near Slimes 2": TunicLocationData("East Overworld", BreakableType.pot), + "Overworld - [East] Pot near Slimes 3": TunicLocationData("East Overworld", BreakableType.pot), + "Overworld - [East] Pot near Slimes 4": TunicLocationData("East Overworld", BreakableType.pot), + "Overworld - [East] Pot near Slimes 5": TunicLocationData("East Overworld", BreakableType.pot), + "Overworld - [East] Forest Sign": TunicLocationData("East Overworld", BreakableType.sign), + "Overworld - [East] Fortress Sign": TunicLocationData("East Overworld", BreakableType.sign), + "Overworld - [North] Pot 1": TunicLocationData("Upper Overworld", BreakableType.pot), + "Overworld - [North] Pot 2": TunicLocationData("Upper Overworld", BreakableType.pot), + "Overworld - [North] Pot 3": TunicLocationData("Upper Overworld", BreakableType.pot), + "Overworld - [North] Pot 4": TunicLocationData("Upper Overworld", BreakableType.pot), + "Overworld - [West] Sign Near West Garden Entrance": TunicLocationData("Overworld to West Garden from Furnace", BreakableType.sign), + "Stick House - Pot 1": TunicLocationData("Stick House", BreakableType.pot), + "Stick House - Pot 2": TunicLocationData("Stick House", BreakableType.pot), + "Stick House - Pot 3": TunicLocationData("Stick House", BreakableType.pot), + "Stick House - Pot 4": TunicLocationData("Stick House", BreakableType.pot), + "Stick House - Pot 5": TunicLocationData("Stick House", BreakableType.pot), + "Stick House - Pot 6": TunicLocationData("Stick House", BreakableType.pot), + "Stick House - Pot 7": TunicLocationData("Stick House", BreakableType.pot), + "Ruined Shop - Pot 1": TunicLocationData("Ruined Shop", BreakableType.pot), + "Ruined Shop - Pot 2": TunicLocationData("Ruined Shop", BreakableType.pot), + "Ruined Shop - Pot 3": TunicLocationData("Ruined Shop", BreakableType.pot), + "Ruined Shop - Pot 4": TunicLocationData("Ruined Shop", BreakableType.pot), + "Ruined Shop - Pot 5": TunicLocationData("Ruined Shop", BreakableType.pot), + "Hourglass Cave - Sign": TunicLocationData("Hourglass Cave", BreakableType.sign), + "Forest Belltower - Pot by Slimes 1": TunicLocationData("Forest Belltower Main", BreakableType.pot), + "Forest Belltower - Pot by Slimes 2": TunicLocationData("Forest Belltower Main", BreakableType.pot), + "Forest Belltower - Pot by Slimes 3": TunicLocationData("Forest Belltower Main", BreakableType.pot), + "Forest Belltower - Pot by Slimes 4": TunicLocationData("Forest Belltower Main", BreakableType.pot), + "Forest Belltower - Pot by Slimes 5": TunicLocationData("Forest Belltower Main", BreakableType.pot), + "Forest Belltower - Pot by Slimes 6": TunicLocationData("Forest Belltower Main", BreakableType.pot), + "Forest Belltower - [Upper] Barrel 1": TunicLocationData("Forest Belltower Upper", BreakableType.barrel), + "Forest Belltower - [Upper] Barrel 2": TunicLocationData("Forest Belltower Upper", BreakableType.barrel), + "Forest Belltower - [Upper] Barrel 3": TunicLocationData("Forest Belltower Upper", BreakableType.barrel), + "Forest Belltower - Pot after Guard Captain 1": TunicLocationData("Forest Belltower Upper", BreakableType.pot), + "Forest Belltower - Pot after Guard Captain 2": TunicLocationData("Forest Belltower Upper", BreakableType.pot), + "Forest Belltower - Pot after Guard Captain 3": TunicLocationData("Forest Belltower Upper", BreakableType.pot), + "Forest Belltower - Pot after Guard Captain 4": TunicLocationData("Forest Belltower Upper", BreakableType.pot), + "Forest Belltower - Pot after Guard Captain 5": TunicLocationData("Forest Belltower Upper", BreakableType.pot), + "Forest Belltower - Pot after Guard Captain 6": TunicLocationData("Forest Belltower Upper", BreakableType.pot), + "Forest Belltower - Pot after Guard Captain 7": TunicLocationData("Forest Belltower Upper", BreakableType.pot), + "Forest Belltower - Pot after Guard Captain 8": TunicLocationData("Forest Belltower Upper", BreakableType.pot), + "Forest Belltower - Pot after Guard Captain 9": TunicLocationData("Forest Belltower Upper", BreakableType.pot), + "Guardhouse 1 - Pot 1": TunicLocationData("Guard House 1 East", BreakableType.pot), + "Guardhouse 1 - Pot 2": TunicLocationData("Guard House 1 East", BreakableType.pot), + "Guardhouse 1 - Pot 3": TunicLocationData("Guard House 1 East", BreakableType.pot), + "Guardhouse 1 - Pot 4": TunicLocationData("Guard House 1 East", BreakableType.pot), + "Guardhouse 1 - Pot 5": TunicLocationData("Guard House 1 East", BreakableType.pot), + "East Forest - Sign by Grave Path": TunicLocationData("East Forest", BreakableType.sign), + "East Forest - Sign by Guardhouse 1": TunicLocationData("East Forest", BreakableType.sign), + "East Forest - Pot by Grave Path 1": TunicLocationData("East Forest", BreakableType.pot), + "East Forest - Pot by Grave Path 2": TunicLocationData("East Forest", BreakableType.pot), + "East Forest - Pot by Grave Path 3": TunicLocationData("East Forest", BreakableType.pot), + "East Forest - Pot by Envoy 1": TunicLocationData("East Forest", BreakableType.pot), + "East Forest - Pot by Envoy 2": TunicLocationData("East Forest", BreakableType.pot), + "East Forest - Pot by Envoy 3": TunicLocationData("East Forest", BreakableType.pot), + "Guardhouse 2 - Bottom Floor Pot 1": TunicLocationData("Guard House 2 Lower", BreakableType.pot), + "Guardhouse 2 - Bottom Floor Pot 2": TunicLocationData("Guard House 2 Lower", BreakableType.pot), + "Guardhouse 2 - Bottom Floor Pot 3": TunicLocationData("Guard House 2 Lower", BreakableType.pot), + "Guardhouse 2 - Bottom Floor Pot 4": TunicLocationData("Guard House 2 Lower", BreakableType.pot), + "Guardhouse 2 - Bottom Floor Pot 5": TunicLocationData("Guard House 2 Lower", BreakableType.pot), + "Beneath the Well - [Side Room] Pot by Chest 1": TunicLocationData("Beneath the Well Back", BreakableType.pot), + "Beneath the Well - [Side Room] Pot by Chest 2": TunicLocationData("Beneath the Well Back", BreakableType.pot), + "Beneath the Well - [Side Room] Pot by Chest 3": TunicLocationData("Beneath the Well Back", BreakableType.pot), + "Beneath the Well - [Third Room] Barrel by Bridge 1": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Barrel by Bridge 2": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Barrel by Bridge 3": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Barrel after Back Corridor 1": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Barrel after Back Corridor 2": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Barrel after Back Corridor 3": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Barrel after Back Corridor 4": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Barrel after Back Corridor 5": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Barrel by West Turret 1": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Barrel by West Turret 2": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Barrel by West Turret 3": TunicLocationData("Beneath the Well Main", BreakableType.barrel), + "Beneath the Well - [Third Room] Pot by East Turret 1": TunicLocationData("Beneath the Well Main", BreakableType.pot), + "Beneath the Well - [Third Room] Pot by East Turret 2": TunicLocationData("Beneath the Well Main", BreakableType.pot), + "Beneath the Well - [Third Room] Pot by East Turret 3": TunicLocationData("Beneath the Well Main", BreakableType.pot), + "Beneath the Well - [Third Room] Pot by East Turret 4": TunicLocationData("Beneath the Well Main", BreakableType.pot), + "Beneath the Well - [Third Room] Pot by East Turret 5": TunicLocationData("Beneath the Well Main", BreakableType.pot), + "Beneath the Well - [Third Room] Pot by East Turret 6": TunicLocationData("Beneath the Well Main", BreakableType.pot), + "Beneath the Well - [Third Room] Pot by East Turret 7": TunicLocationData("Beneath the Well Main", BreakableType.pot), + "Well Boss - Barrel 1": TunicLocationData("Well Boss", BreakableType.barrel), + "Well Boss - Barrel 2": TunicLocationData("Well Boss", BreakableType.barrel), + "Dark Tomb - Pot Hallway Pot 1": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 2": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 3": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 4": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 5": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 6": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 7": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 8": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 9": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 10": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 11": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 12": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 13": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - Pot Hallway Pot 14": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - 2nd Laser Room Pot 1": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - 2nd Laser Room Pot 2": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - 2nd Laser Room Pot 3": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - 2nd Laser Room Pot 4": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "Dark Tomb - 2nd Laser Room Pot 5": TunicLocationData("Dark Tomb Main", BreakableType.pot), + "West Garden House - Pot 1": TunicLocationData("Magic Dagger House", BreakableType.pot), + "West Garden House - Pot 2": TunicLocationData("Magic Dagger House", BreakableType.pot), + "West Garden House - Pot 3": TunicLocationData("Magic Dagger House", BreakableType.pot), + "Fortress Courtyard - Fire Pot 1": TunicLocationData("Fortress Courtyard westmost pots", BreakableType.fire_pot), + "Fortress Courtyard - Fire Pot 2": TunicLocationData("Fortress Courtyard westmost pots", BreakableType.fire_pot), + "Fortress Courtyard - Fire Pot 3": TunicLocationData("Fortress Courtyard west pots", BreakableType.fire_pot), + "Fortress Courtyard - Fire Pot 4": TunicLocationData("Fortress Courtyard west pots", BreakableType.fire_pot), + "Fortress Courtyard - Fire Pot 5": TunicLocationData("Fortress Courtyard", BreakableType.fire_pot), + "Fortress Courtyard - Fire Pot 6": TunicLocationData("Fortress Courtyard", BreakableType.fire_pot), + "Fortress Courtyard - Fire Pot 7": TunicLocationData("Fortress Courtyard", BreakableType.fire_pot), + "Fortress Courtyard - Fire Pot 8": TunicLocationData("Fortress Courtyard", BreakableType.fire_pot), + "Fortress Courtyard - Upper Fire Pot": TunicLocationData("Fortress Courtyard Upper pot", BreakableType.fire_pot), + "Fortress Grave Path - [Entry] Pot 1": TunicLocationData("Fortress Grave Path Entry", BreakableType.pot), + "Fortress Grave Path - [Entry] Pot 2": TunicLocationData("Fortress Grave Path Entry", BreakableType.pot), + "Fortress Grave Path - [By Grave] Pot 1": TunicLocationData("Fortress Grave Path pots", BreakableType.pot), + "Fortress Grave Path - [By Grave] Pot 2": TunicLocationData("Fortress Grave Path pots", BreakableType.pot), + "Fortress Grave Path - [By Grave] Pot 3": TunicLocationData("Fortress Grave Path pots", BreakableType.pot), + "Fortress Grave Path - [By Grave] Pot 4": TunicLocationData("Fortress Grave Path pots", BreakableType.pot), + "Fortress Grave Path - [By Grave] Pot 5": TunicLocationData("Fortress Grave Path pots", BreakableType.pot), + "Fortress Grave Path - [By Grave] Pot 6": TunicLocationData("Fortress Grave Path pots", BreakableType.pot), + "Fortress Grave Path - [Central] Fire Pot 1": TunicLocationData("Fortress Grave Path westmost pot", BreakableType.fire_pot), + "Fortress Grave Path - [Central] Fire Pot 2": TunicLocationData("Fortress Grave Path Combat", BreakableType.fire_pot), + "Eastern Vault Fortress - [Central] Pot by Door 1": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [Central] Pot by Door 2": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [Central] Pot by Door 3": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [Central] Pot by Door 4": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [Central] Pot by Door 5": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [Central] Pot by Door 6": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [Central] Pot by Door 7": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [Central] Pot by Door 8": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [Central] Pot by Door 9": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [Central] Pot by Door 10": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [Central] Pot by Door 11": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [East Wing] Pot by Broken Checkpoint 1": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [East Wing] Pot by Broken Checkpoint 2": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [East Wing] Pot by Broken Checkpoint 3": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Pot by Checkpoint 1": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Pot by Checkpoint 2": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Pot by Checkpoint 3": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Pot by Overlook 1": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Pot by Overlook 2": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Slorm Room Pot 1": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Slorm Room Pot 2": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Slorm Room Pot 3": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Chest Room Pot 1": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Chest Room Pot 2": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Pot by Stairs to Basement 1": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Pot by Stairs to Basement 2": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Eastern Vault Fortress - [West Wing] Pot by Stairs to Basement 3": TunicLocationData("Eastern Vault Fortress", BreakableType.pot), + "Beneath the Fortress - Entry Spot Pot 1": TunicLocationData("Beneath the Vault Entry Spot", BreakableType.pot), + "Beneath the Fortress - Entry Spot Pot 2": TunicLocationData("Beneath the Vault Entry Spot", BreakableType.pot), + "Beneath the Fortress - Entry Spot Crate 1": TunicLocationData("Beneath the Vault Entry Spot", BreakableType.crate), + "Beneath the Fortress - Entry Spot Crate 2": TunicLocationData("Beneath the Vault Entry Spot", BreakableType.crate), + "Beneath the Fortress - Entry Spot Crate 3": TunicLocationData("Beneath the Vault Entry Spot", BreakableType.crate), + "Beneath the Fortress - Entry Spot Crate 4": TunicLocationData("Beneath the Vault Entry Spot", BreakableType.crate), + "Beneath the Fortress - Entry Spot Crate 5": TunicLocationData("Beneath the Vault Entry Spot", BreakableType.crate), + "Beneath the Fortress - Entry Spot Crate 6": TunicLocationData("Beneath the Vault Entry Spot", BreakableType.crate), + "Beneath the Fortress - Entry Spot Crate 7": TunicLocationData("Beneath the Vault Entry Spot", BreakableType.crate), + "Beneath the Fortress - Slorm Room Crate 1": TunicLocationData("Beneath the Vault Main", BreakableType.crate), + "Beneath the Fortress - Slorm Room Crate 2": TunicLocationData("Beneath the Vault Main", BreakableType.crate), + "Beneath the Fortress - Crate under Rope 1": TunicLocationData("Beneath the Vault Main", BreakableType.crate), + "Beneath the Fortress - Crate under Rope 2": TunicLocationData("Beneath the Vault Main", BreakableType.crate), + "Beneath the Fortress - Crate under Rope 3": TunicLocationData("Beneath the Vault Main", BreakableType.crate), + "Beneath the Fortress - Crate under Rope 4": TunicLocationData("Beneath the Vault Main", BreakableType.crate), + "Beneath the Fortress - Crate under Rope 5": TunicLocationData("Beneath the Vault Main", BreakableType.crate), + "Beneath the Fortress - Crate under Rope 6": TunicLocationData("Beneath the Vault Main", BreakableType.crate), + "Beneath the Fortress - Fuse Room Fire Pot 1": TunicLocationData("Beneath the Vault Back", BreakableType.fire_pot), + "Beneath the Fortress - Fuse Room Fire Pot 2": TunicLocationData("Beneath the Vault Back", BreakableType.fire_pot), + "Beneath the Fortress - Fuse Room Fire Pot 3": TunicLocationData("Beneath the Vault Back", BreakableType.fire_pot), + "Beneath the Fortress - Barrel by Back Room 1": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Barrel by Back Room 2": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Barrel by Back Room 3": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Barrel by Back Room 4": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Barrel by Back Room 5": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Barrel by Back Room 6": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Back Room Barrel 1": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Back Room Barrel 2": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Back Room Barrel 3": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Back Room Barrel 4": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Back Room Barrel 5": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Back Room Barrel 6": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Beneath the Fortress - Back Room Barrel 7": TunicLocationData("Beneath the Vault Back", BreakableType.barrel), + "Fortress Leaf Piles - Leaf Pile 1": TunicLocationData("Fortress Leaf Piles", BreakableType.leaves), + "Fortress Leaf Piles - Leaf Pile 2": TunicLocationData("Fortress Leaf Piles", BreakableType.leaves), + "Fortress Leaf Piles - Leaf Pile 3": TunicLocationData("Fortress Leaf Piles", BreakableType.leaves), + "Fortress Leaf Piles - Leaf Pile 4": TunicLocationData("Fortress Leaf Piles", BreakableType.leaves), + "Fortress Arena - Pot 1": TunicLocationData("Fortress Arena", BreakableType.pot), + "Fortress Arena - Pot 2": TunicLocationData("Fortress Arena", BreakableType.pot), + "Ruined Atoll - [West] Pot in Broken House 1": TunicLocationData("Ruined Atoll", BreakableType.pot), + "Ruined Atoll - [West] Pot in Broken House 2": TunicLocationData("Ruined Atoll", BreakableType.pot), + "Ruined Atoll - [West] Table in Broken House": TunicLocationData("Ruined Atoll", BreakableType.table), + "Ruined Atoll - [South] Explosive Pot near Birds": TunicLocationData("Ruined Atoll", BreakableType.explosive_pot), + "Frog Stairs - [Upper] Pot 1": TunicLocationData("Frog Stairs Upper", BreakableType.pot), + "Frog Stairs - [Upper] Pot 2": TunicLocationData("Frog Stairs Upper", BreakableType.pot), + "Frog Stairs - [Upper] Pot 3": TunicLocationData("Frog Stairs Upper", BreakableType.pot), + "Frog Stairs - [Upper] Pot 4": TunicLocationData("Frog Stairs Upper", BreakableType.pot), + "Frog Stairs - [Upper] Pot 5": TunicLocationData("Frog Stairs Upper", BreakableType.pot), + "Frog Stairs - [Upper] Pot 6": TunicLocationData("Frog Stairs Upper", BreakableType.pot), + "Frog's Domain - Pot above Orb Altar 1": TunicLocationData("Frog's Domain Front", BreakableType.pot), + "Frog's Domain - Pot above Orb Altar 2": TunicLocationData("Frog's Domain Front", BreakableType.pot), + "Frog's Domain - Side Room Pot 1": TunicLocationData("Frog's Domain Main", BreakableType.pot), + "Frog's Domain - Side Room Pot 2": TunicLocationData("Frog's Domain Main", BreakableType.pot), + "Frog's Domain - Side Room Pot 3": TunicLocationData("Frog's Domain Main", BreakableType.pot), + "Frog's Domain - Main Room Pot 1": TunicLocationData("Frog's Domain Main", BreakableType.pot), + "Frog's Domain - Main Room Pot 2": TunicLocationData("Frog's Domain Main", BreakableType.pot), + "Frog's Domain - Side Room Pot 4": TunicLocationData("Frog's Domain Main", BreakableType.pot), + "Frog's Domain - Pot after Gate 1": TunicLocationData("Frog's Domain Main", BreakableType.pot), + "Frog's Domain - Pot after Gate 2": TunicLocationData("Frog's Domain Main", BreakableType.pot), + "Frog's Domain - Orb Room Explosive Pot 1": TunicLocationData("Frog's Domain Main", BreakableType.explosive_pot), + "Frog's Domain - Orb Room Explosive Pot 2": TunicLocationData("Frog's Domain Main", BreakableType.explosive_pot), + "Library Lab - Display Case 1": TunicLocationData("Library Lab", BreakableType.glass), + "Library Lab - Display Case 2": TunicLocationData("Library Lab", BreakableType.glass), + "Library Lab - Display Case 3": TunicLocationData("Library Lab", BreakableType.glass), + "Quarry - [East] Explosive Pot 1": TunicLocationData("Quarry", BreakableType.explosive_pot), + "Quarry - [East] Explosive Pot 2": TunicLocationData("Quarry", BreakableType.explosive_pot), + "Quarry - [East] Explosive Pot 3": TunicLocationData("Quarry", BreakableType.explosive_pot), + "Quarry - [East] Explosive Pot beneath Scaffolding": TunicLocationData("Quarry", BreakableType.explosive_pot), + "Quarry - [Central] Explosive Pot near Monastery 1": TunicLocationData("Quarry Monastery Entry", BreakableType.explosive_pot), + "Quarry - [Central] Explosive Pot near Monastery 2": TunicLocationData("Quarry Monastery Entry", BreakableType.explosive_pot), + "Quarry - [Back Entrance] Pot 1": TunicLocationData("Quarry Back", BreakableType.pot), + "Quarry - [Back Entrance] Pot 2": TunicLocationData("Quarry Back", BreakableType.pot), + "Quarry - [Back Entrance] Pot 3": TunicLocationData("Quarry Back", BreakableType.pot), + "Quarry - [Back Entrance] Pot 4": TunicLocationData("Quarry Back", BreakableType.pot), + "Quarry - [Back Entrance] Pot 5": TunicLocationData("Quarry Back", BreakableType.pot), + "Quarry - [Central] Explosive Pot near Shortcut Ladder 1": TunicLocationData("Quarry Back", BreakableType.explosive_pot), + "Quarry - [Central] Explosive Pot near Shortcut Ladder 2": TunicLocationData("Quarry Back", BreakableType.explosive_pot), + "Quarry - [Central] Crate near Shortcut Ladder 1": TunicLocationData("Quarry Back", BreakableType.crate), + "Quarry - [Central] Crate near Shortcut Ladder 2": TunicLocationData("Quarry Back", BreakableType.crate), + "Quarry - [Central] Crate near Shortcut Ladder 3": TunicLocationData("Quarry Back", BreakableType.crate), + "Quarry - [Central] Crate near Shortcut Ladder 4": TunicLocationData("Quarry Back", BreakableType.crate), + "Quarry - [Central] Crate near Shortcut Ladder 5": TunicLocationData("Quarry Back", BreakableType.crate), + "Quarry - [West] Explosive Pot near Bombable Wall 1": TunicLocationData("Lower Quarry upper pots", BreakableType.explosive_pot), + "Quarry - [West] Explosive Pot near Bombable Wall 2": TunicLocationData("Lower Quarry upper pots", BreakableType.explosive_pot), + "Quarry - [West] Explosive Pot above Shooting Range": TunicLocationData("Lower Quarry", BreakableType.explosive_pot), + "Quarry - [West] Explosive Pot near Isolated Chest 1": TunicLocationData("Lower Quarry", BreakableType.explosive_pot), + "Quarry - [West] Explosive Pot near Isolated Chest 2": TunicLocationData("Lower Quarry", BreakableType.explosive_pot), + "Quarry - [West] Crate by Shooting Range 1": TunicLocationData("Lower Quarry", BreakableType.crate), + "Quarry - [West] Crate by Shooting Range 2": TunicLocationData("Lower Quarry", BreakableType.crate), + "Quarry - [West] Crate by Shooting Range 3": TunicLocationData("Lower Quarry", BreakableType.crate), + "Quarry - [West] Crate by Shooting Range 4": TunicLocationData("Lower Quarry", BreakableType.crate), + "Quarry - [West] Crate by Shooting Range 5": TunicLocationData("Lower Quarry", BreakableType.crate), + "Quarry - [West] Crate near Isolated Chest 1": TunicLocationData("Lower Quarry", BreakableType.crate), + "Quarry - [West] Crate near Isolated Chest 2": TunicLocationData("Lower Quarry", BreakableType.crate), + "Quarry - [West] Crate near Isolated Chest 3": TunicLocationData("Lower Quarry", BreakableType.crate), + "Quarry - [West] Crate near Isolated Chest 4": TunicLocationData("Lower Quarry", BreakableType.crate), + "Quarry - [West] Crate near Isolated Chest 5": TunicLocationData("Lower Quarry", BreakableType.crate), + "Quarry - [Lowlands] Crate 1": TunicLocationData("Even Lower Quarry", BreakableType.crate), + "Quarry - [Lowlands] Crate 2": TunicLocationData("Even Lower Quarry", BreakableType.crate), + "Monastery - Crate 1": TunicLocationData("Monastery Back", BreakableType.crate), + "Monastery - Crate 2": TunicLocationData("Monastery Back", BreakableType.crate), + "Monastery - Crate 3": TunicLocationData("Monastery Back", BreakableType.crate), + "Monastery - Crate 4": TunicLocationData("Monastery Back", BreakableType.crate), + "Monastery - Crate 5": TunicLocationData("Monastery Back", BreakableType.crate), + "Monastery - Crate 6": TunicLocationData("Monastery Back", BreakableType.crate), + "Monastery - Crate 7": TunicLocationData("Monastery Back", BreakableType.crate), + "Monastery - Crate 8": TunicLocationData("Monastery Back", BreakableType.crate), + "Monastery - Crate 9": TunicLocationData("Monastery Back", BreakableType.crate), + "Cathedral - [1F] Pot by Stairs 1": TunicLocationData("Cathedral Main", BreakableType.pot), + "Cathedral - [1F] Pot by Stairs 2": TunicLocationData("Cathedral Main", BreakableType.pot), + "Purgatory - Pot 1": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 2": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 3": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 4": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 5": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 6": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 7": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 8": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 9": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 10": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 11": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 12": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 13": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 14": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 15": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 16": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 17": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 18": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 19": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 20": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 21": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 22": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 23": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 24": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 25": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 26": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 27": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 28": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 29": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 30": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 31": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 32": TunicLocationData("Purgatory", BreakableType.pot), + "Purgatory - Pot 33": TunicLocationData("Purgatory", BreakableType.pot), + "Overworld - [Central] Break Bombable Wall": TunicLocationData("Overworld", BreakableType.wall), + "Overworld - [Southwest] Break Cube Cave Bombable Wall": TunicLocationData("Overworld", BreakableType.wall), + "Overworld - [Southwest] Break Bombable Wall near Fountain": TunicLocationData("Overworld", BreakableType.wall), + "Ruined Atoll - [Northwest] Break Bombable Wall": TunicLocationData("Ruined Atoll", BreakableType.wall), + "East Forest - Break Bombable Wall": TunicLocationData("East Forest", BreakableType.wall), + "Eastern Vault Fortress - [East Wing] Break Bombable Wall": TunicLocationData("Eastern Vault Fortress", BreakableType.wall), + "Quarry - [West] Break Upper Area Bombable Wall": TunicLocationData("Quarry Back", BreakableType.wall), + "Quarry - [East] Break Bombable Wall": TunicLocationData("Quarry", BreakableType.wall), +} + + +breakable_location_name_to_id: dict[str, int] = {name: breakable_base_id + index + for index, name in enumerate(breakable_location_table)} + + +# key is the name in the table above, value is the loc group name for the area +loc_group_convert: dict[str, str] = { + "East Overworld": "Overworld", + "Upper Overworld": "Overworld", + "Overworld to West Garden from Furnace": "Overworld", + "Forest Belltower Upper": "Forest Belltower", + "Forest Belltower Main": "Forest Belltower", + "Guard House 1 East": "Guardhouse 1", + "Guard House 2 Lower": "Guardhouse 2", + "Beneath the Well Back": "Beneath the Well", + "Beneath the Well Main": "Beneath the Well", + "Well Boss": "Dark Tomb Checkpoint", + "Dark Tomb Main": "Dark Tomb", + "Fortress Courtyard Upper": "Fortress Courtyard", + "Fortress Courtyard Upper pot": "Fortress Courtyard", + "Fortress Courtyard west pots": "Fortress Courtyard", + "Fortress Courtyard westmost pots": "Fortress Courtyard", + "Beneath the Vault Entry Spot": "Beneath the Fortress", + "Beneath the Vault Main": "Beneath the Fortress", + "Beneath the Vault Back": "Beneath the Fortress", + "Fortress Grave Path Entry": "Fortress Grave Path", + "Fortress Grave Path Combat": "Fortress Grave Path", + "Fortress Grave Path westmost pot": "Fortress Grave Path", + "Fortress Grave Path pots": "Fortress Grave Path", + "Dusty": "Fortress Leaf Piles", + "Frog Stairs Upper": "Frog Stairs", + "Quarry Monastery Entry": "Quarry", + "Quarry Back": "Quarry", + "Lower Quarry": "Quarry", + "Lower Quarry upper pots": "Quarry", + "Even Lower Quarry": "Quarry", + "Monastery Back": "Monastery", +} + + +breakable_location_groups: dict[str, set[str]] = {} +for location_name, location_data in breakable_location_table.items(): + group_name = loc_group_convert.get(location_data.er_region, location_data.er_region) + breakable_location_groups.setdefault(group_name, set()).add(location_name) + + +def can_break_breakables(state: CollectionState, world: "TunicWorld") -> bool: + return has_melee(state, world.player) or state.has_any(("Magic Wand", "Gun"), world.player) + + +# and also the table +def can_break_signs(state: CollectionState, world: "TunicWorld") -> bool: + return (has_sword(state, world.player) or state.has_any(("Magic Wand", "Gun"), world.player) + or (has_melee(state, world.player) and state.has("Glass Cannon", world.player))) + + +def can_break_leaf_piles(state: CollectionState, world: "TunicWorld") -> bool: + return has_melee(state, world.player) or state.has_any(("Magic Dagger", "Gun"), world.player) + + +def can_break_bomb_walls(state: CollectionState, world: "TunicWorld") -> bool: + return state.has("Gun", world.player) or can_shop(state, world) + + +def create_breakable_exclusive_regions(world: "TunicWorld") -> list[Region]: + player = world.player + multiworld = world.multiworld + new_regions: list[Region] = [] + + region = Region("Fortress Courtyard westmost pots", player, multiworld) + new_regions.append(region) + world.get_region("Fortress Courtyard").connect(region) + world.get_region("Fortress Exterior near cave").connect( + region, rule=lambda state: state.has_any(("Magic Wand", "Gun"), player)) + + region = Region("Fortress Courtyard west pots", player, multiworld) + new_regions.append(region) + world.get_region("Fortress Courtyard").connect(region) + world.get_region("Fortress Exterior near cave").connect( + region, rule=lambda state: state.has("Magic Wand", player)) + + region = Region("Fortress Courtyard Upper pot", player, multiworld) + new_regions.append(region) + world.get_region("Fortress Courtyard Upper").connect(region) + world.get_region("Fortress Courtyard").connect( + region, rule=lambda state: state.has("Magic Wand", player)) + + region = Region("Fortress Grave Path westmost pot", player, multiworld) + new_regions.append(region) + world.get_region("Fortress Grave Path Entry").connect(region) + world.get_region("Fortress Grave Path Upper").connect( + region, rule=lambda state: state.has_any(("Magic Wand", "Gun"), player)) + + region = Region("Fortress Grave Path pots", player, multiworld) + new_regions.append(region) + world.get_region("Fortress Grave Path by Grave").connect(region) + world.get_region("Fortress Grave Path Dusty Entrance Region").connect( + region, rule=lambda state: state.has("Magic Wand", player)) + + region = Region("Lower Quarry upper pots", player, multiworld) + new_regions.append(region) + world.get_region("Lower Quarry").connect(region) + world.get_region("Quarry Back").connect( + region, rule=lambda state: state.has_any(("Magic Wand", "Gun"), player)) + + for region in new_regions: + multiworld.regions.append(region) + + return new_regions + + +def set_breakable_location_rules(world: "TunicWorld") -> None: + for loc_name, loc_data in breakable_location_table.items(): + if not world.options.entrance_rando and loc_data.er_region == "Purgatory": + continue + location = world.get_location(loc_name) + if loc_data.breakable == BreakableType.leaves: + set_rule(location, lambda state: can_break_leaf_piles(state, world)) + elif loc_data.breakable in (BreakableType.sign, BreakableType.table): + set_rule(location, lambda state: can_break_signs(state, world)) + elif loc_data.breakable == BreakableType.wall: + set_rule(location, lambda state: can_break_bomb_walls(state, world)) + else: + set_rule(location, lambda state: can_break_breakables(state, world)) diff --git a/worlds/tunic/er_data.py b/worlds/tunic/er_data.py index f1a428cce1b5..0b3a16167a87 100644 --- a/worlds/tunic/er_data.py +++ b/worlds/tunic/er_data.py @@ -679,8 +679,9 @@ class DeadEnd(IntEnum): "Fortress Courtyard": RegionInfo("Fortress Courtyard"), "Fortress Courtyard Upper": RegionInfo("Fortress Courtyard"), "Beneath the Vault Ladder Exit": RegionInfo("Fortress Basement"), - "Beneath the Vault Main": RegionInfo("Fortress Basement"), # the vanilla entry point - "Beneath the Vault Back": RegionInfo("Fortress Basement"), # the vanilla exit point + "Beneath the Vault Entry Spot": RegionInfo("Fortress Basement"), # where the boxes are + "Beneath the Vault Main": RegionInfo("Fortress Basement"), + "Beneath the Vault Back": RegionInfo("Fortress Basement"), "Eastern Vault Fortress": RegionInfo("Fortress Main"), "Eastern Vault Fortress Gold Door": RegionInfo("Fortress Main"), "Fortress East Shortcut Upper": RegionInfo("Fortress East"), @@ -1421,11 +1422,17 @@ class DeadEnd(IntEnum): }, "Beneath the Vault Ladder Exit": { + "Beneath the Vault Entry Spot": + [], + }, + "Beneath the Vault Entry Spot": { "Beneath the Vault Main": [], + "Beneath the Vault Ladder Exit": + [], }, "Beneath the Vault Main": { - "Beneath the Vault Ladder Exit": + "Beneath the Vault Entry Spot": [], "Beneath the Vault Back": [], diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index fe01337c643b..7a3264b6c4fc 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -855,16 +855,21 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Fortress Courtyard Upper"].connect( connecting_region=regions["Fortress Exterior from Overworld"]) - btv_front_to_main = regions["Beneath the Vault Ladder Exit"].connect( + regions["Beneath the Vault Ladder Exit"].connect( + connecting_region=regions["Beneath the Vault Entry Spot"], + rule=lambda state: has_ladder("Ladder to Beneath the Vault", state, world)) + regions["Beneath the Vault Entry Spot"].connect( + connecting_region=regions["Beneath the Vault Ladder Exit"], + rule=lambda state: has_ladder("Ladder to Beneath the Vault", state, world)) + + btv_front_to_main = regions["Beneath the Vault Entry Spot"].connect( connecting_region=regions["Beneath the Vault Main"], - rule=lambda state: has_ladder("Ladder to Beneath the Vault", state, world) - and has_lantern(state, world) + rule=lambda state: has_lantern(state, world) # there's some boxes in the way and (has_melee(state, player) or state.has_any((gun, grapple, fire_wand, laurels), player))) # on the reverse trip, you can lure an enemy over to break the boxes if needed regions["Beneath the Vault Main"].connect( - connecting_region=regions["Beneath the Vault Ladder Exit"], - rule=lambda state: has_ladder("Ladder to Beneath the Vault", state, world)) + connecting_region=regions["Beneath the Vault Entry Spot"]) regions["Beneath the Vault Main"].connect( connecting_region=regions["Beneath the Vault Back"]) diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index 4cd0f49ddf9b..ddb4ec6c58a3 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -3,6 +3,7 @@ from .locations import all_locations from .er_data import Portal, portal_mapping, traversal_requirements, DeadEnd, RegionInfo from .er_rules import set_er_region_rules +from .breakables import create_breakable_exclusive_regions, set_breakable_location_rules from Options import PlandoConnection from .options import EntranceRando from random import Random @@ -22,19 +23,26 @@ class TunicERLocation(Location): def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]: regions: Dict[str, Region] = {} - - if world.options.entrance_rando: - for region_name, region_data in world.er_regions.items(): - # if fewer shops is off, zig skip is not made - if region_name == "Zig Skip Exit": - # need to check if there's a seed group for this first - if world.options.entrance_rando.value not in EntranceRando.options.values(): - if not world.seed_groups[world.options.entrance_rando.value]["fixed_shop"]: - continue - elif not world.options.fixed_shop: + for region_name, region_data in world.er_regions.items(): + if world.options.entrance_rando and region_name == "Zig Skip Exit": + # need to check if there's a seed group for this first + if world.options.entrance_rando.value not in EntranceRando.options.values(): + if not world.seed_groups[world.options.entrance_rando.value]["fixed_shop"]: continue - regions[region_name] = Region(region_name, world.player, world.multiworld) + elif not world.options.fixed_shop: + continue + if not world.options.entrance_rando and region_name in ("Zig Skip Exit", "Purgatory"): + continue + + region = Region(region_name, world.player, world.multiworld) + regions[region_name] = region + world.multiworld.regions.append(region) + + if world.options.breakable_shuffle: + breakable_regions = create_breakable_exclusive_regions(world) + regions.update({region.name: region for region in breakable_regions}) + if world.options.entrance_rando: portal_pairs = pair_portals(world, regions) # output the entrances to the spoiler log here for convenience @@ -42,11 +50,6 @@ def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]: for portal1, portal2 in sorted_portal_pairs.items(): world.multiworld.spoiler.set_entrance(portal1, portal2, "both", world.player) else: - for region_name, region_data in world.er_regions.items(): - # filter out regions that are inaccessible in non-er - if region_name not in ["Zig Skip Exit", "Purgatory"]: - regions[region_name] = Region(region_name, world.player, world.multiworld) - portal_pairs = vanilla_portals(world, regions) create_randomized_entrances(portal_pairs, regions) @@ -58,8 +61,8 @@ def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]: location = TunicERLocation(world.player, location_name, location_id, region) region.locations.append(location) - for region in regions.values(): - world.multiworld.regions.append(region) + if world.options.breakable_shuffle: + set_breakable_location_rules(world) place_event_items(world, regions) @@ -557,4 +560,3 @@ def sort_portals(portal_pairs: Dict[Portal, Portal]) -> Dict[str, str]: sorted_pairs[portal1.name] = portal2.name break return sorted_pairs - diff --git a/worlds/tunic/items.py b/worlds/tunic/items.py index 20696eb51128..1898534c1bba 100644 --- a/worlds/tunic/items.py +++ b/worlds/tunic/items.py @@ -103,6 +103,10 @@ class TunicItemData(NamedTuple): "Forever Friend": TunicItemData(IC.useful, 1, 84, "Golden Treasures", combat_ic=IC.progression), "Fool Trap": TunicItemData(IC.trap, 0, 85), "Money x1": TunicItemData(IC.filler, 3, 86, "Money"), + "Money x2": TunicItemData(IC.filler, 0, 152, "Money"), + "Money x3": TunicItemData(IC.filler, 0, 153, "Money"), + "Money x4": TunicItemData(IC.filler, 0, 154, "Money"), + "Money x5": TunicItemData(IC.filler, 0, 155, "Money"), "Money x10": TunicItemData(IC.filler, 1, 87, "Money"), "Money x15": TunicItemData(IC.filler, 10, 88, "Money"), "Money x16": TunicItemData(IC.filler, 1, 89, "Money"), diff --git a/worlds/tunic/locations.py b/worlds/tunic/locations.py index d3c23406ed38..18c0fb3c134b 100644 --- a/worlds/tunic/locations.py +++ b/worlds/tunic/locations.py @@ -1,5 +1,6 @@ from typing import Dict, NamedTuple, Set, Optional, List from .grass import grass_location_table +from .breakables import breakable_location_table class TunicLocationData(NamedTuple): @@ -342,6 +343,7 @@ class TunicLocationData(NamedTuple): all_locations = location_table.copy() all_locations.update(grass_location_table) +all_locations.update(breakable_location_table) location_name_groups: Dict[str, Set[str]] = {} for loc_name, loc_data in location_table.items(): diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index 3ace28cffafa..c17b085b1187 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -313,6 +313,14 @@ class LogicRules(Choice): default = 0 +class BreakableShuffle(Toggle): + """ + Turns approximately 250 breakable objects in the game into checks. + """ + internal_name = "breakable_shuffle" + display_name = "Breakable Shuffle" + + @dataclass class TunicOptions(PerGameCommonOptions): start_inventory_from_pool: StartInventoryPool @@ -331,6 +339,7 @@ class TunicOptions(PerGameCommonOptions): shuffle_ladders: ShuffleLadders grass_randomizer: GrassRandomizer + breakable_shuffle: BreakableShuffle local_fill: LocalFill entrance_rando: EntranceRando From 5662da6f7d2e9d498ea3fd536bc27981aae10774 Mon Sep 17 00:00:00 2001 From: sgrunt Date: Sat, 8 Mar 2025 09:54:23 -0700 Subject: [PATCH 0182/1218] Timespinner: Support new flags and settings from the randomizer (#4559) * Timespinner: Add "no hell spiders" enemy rando option that is present in upstream settings * Timespinner: Prism Break support tweaks (including tracker support) * Timespinner: Add support for upstream Lock Key Amadeus flag * Timespinner: Add support for upstream Risky Warps flag * Timespinner: Add support for upstream Pyramid Start flag * Timespinner: fix error in lab connectivity logic * Timespinner: use has_all to simplify one check Per PR suggestion. Co-authored-by: Scipio Wright * Timespinner: fix apparent logic error inherited from in-rando logic * Timespinner: adjust "Origins" location logic slightly further to account for a Risky Warps case * Timespinner: remove the backward compat options for the recent flag additions * Timespinner: add newly added Gate Keep option from rando * Timespinner: adjust the laser access colours in the tracker * Timespinner: fix an item description in the tracker * Timespinner: based on testing feedback, put Laser Access items in their own category * Timespinner: add support for new upstream flag Royal Roadblock * Timespinner: also ensure the new flag gets put in slot data * Timespinner: fix bug in universal tracker support indicating castle basement is accessible at the lower Rising Tides flooding level * Timespinner: exclude Talaria Attachment and Timespinner Wheel from pyramid start starter progression items * Timespinner: fix region logic for the left pyramid warp * Timespinner: fix main Gyre access logic when Risky Warps warps you behind the lasers * Timespinner: apply suggested spacing fix Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --------- Co-authored-by: sgrunt Co-authored-by: Scipio Wright --- .../static/styles/timespinnerTracker.css | 21 +++++++++ .../templates/tracker__Timespinner.html | 46 +++++++++++++++++++ WebHostLib/tracker.py | 8 ++++ worlds/timespinner/Items.py | 26 +++++++++-- worlds/timespinner/Locations.py | 28 +++++++---- worlds/timespinner/LogicExtensions.py | 1 + worlds/timespinner/Options.py | 26 +++++++++++ worlds/timespinner/PreCalculatedWeights.py | 16 +++++-- worlds/timespinner/Regions.py | 26 +++++++---- worlds/timespinner/__init__.py | 32 +++++++++++-- 10 files changed, 196 insertions(+), 34 deletions(-) diff --git a/WebHostLib/static/styles/timespinnerTracker.css b/WebHostLib/static/styles/timespinnerTracker.css index 007c6a19ba9a..640b5846840b 100644 --- a/WebHostLib/static/styles/timespinnerTracker.css +++ b/WebHostLib/static/styles/timespinnerTracker.css @@ -75,6 +75,27 @@ #inventory-table img.acquired.green{ /*32CD32*/ filter: hue-rotate(84deg) saturate(10) brightness(0.7); } +#inventory-table img.acquired.hotpink{ /*FF69B4*/ + filter: sepia(100%) hue-rotate(300deg) saturate(10); +} +#inventory-table img.acquired.lightsalmon{ /*FFA07A*/ + filter: sepia(100%) hue-rotate(347deg) saturate(10); +} +#inventory-table img.acquired.crimson{ /*DB143B*/ + filter: sepia(100%) hue-rotate(318deg) saturate(10) brightness(0.86); +} + +#inventory-table span{ + color: #B4B4A0; + font-size: 40px; + max-width: 40px; + max-height: 40px; + filter: grayscale(100%) contrast(75%) brightness(30%); +} + +#inventory-table span.acquired{ + filter: none; +} #inventory-table div.image-stack{ display: grid; diff --git a/WebHostLib/templates/tracker__Timespinner.html b/WebHostLib/templates/tracker__Timespinner.html index b118c3383344..aa8567659cc9 100644 --- a/WebHostLib/templates/tracker__Timespinner.html +++ b/WebHostLib/templates/tracker__Timespinner.html @@ -99,6 +99,52 @@ {% endif %} + {% if 'PrismBreak' in options or 'LockKeyAmadeus' in options or 'GateKeep' in options %} +
+ {% if 'PrismBreak' in options %} +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ {% endif %} + {% if 'LockKeyAmadeus' in options %} +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ {% endif %} + {% if 'GateKeep' in options %} +
+ +
+ {% endif %} +
+ {% endif %} diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py index 043764a53b08..3748de97a4bf 100644 --- a/WebHostLib/tracker.py +++ b/WebHostLib/tracker.py @@ -1071,6 +1071,11 @@ def render_Timespinner_tracker(tracker_data: TrackerData, team: int, player: int "Plasma Orb": "https://timespinnerwiki.com/mediawiki/images/4/44/Plasma_Orb.png", "Kobo": "https://timespinnerwiki.com/mediawiki/images/c/c6/Familiar_Kobo.png", "Merchant Crow": "https://timespinnerwiki.com/mediawiki/images/4/4e/Familiar_Crow.png", + "Laser Access": "https://timespinnerwiki.com/mediawiki/images/9/99/Historical_Documents.png", + "Lab Glasses": "https://timespinnerwiki.com/mediawiki/images/4/4a/Lab_Glasses.png", + "Eye Orb": "https://timespinnerwiki.com/mediawiki/images/a/a4/Eye_Orb.png", + "Lab Coat": "https://timespinnerwiki.com/mediawiki/images/5/51/Lab_Coat.png", + "Demon": "https://timespinnerwiki.com/mediawiki/images/f/f8/Familiar_Demon.png", } timespinner_location_ids = { @@ -1118,6 +1123,9 @@ def render_Timespinner_tracker(tracker_data: TrackerData, team: int, player: int timespinner_location_ids["Ancient Pyramid"] += [ 1337237, 1337238, 1337239, 1337240, 1337241, 1337242, 1337243, 1337244, 1337245] + if (slot_data["PyramidStart"]): + timespinner_location_ids["Ancient Pyramid"] += [ + 1337233, 1337234, 1337235] display_data = {} diff --git a/worlds/timespinner/Items.py b/worlds/timespinner/Items.py index 3beead95153b..a00fca7ee5f4 100644 --- a/worlds/timespinner/Items.py +++ b/worlds/timespinner/Items.py @@ -199,11 +199,16 @@ class ItemData(NamedTuple): 'Chaos Trap': ItemData('Trap', 1337186, 0, trap=True), 'Neurotoxin Trap': ItemData('Trap', 1337187, 0, trap=True), 'Bee Trap': ItemData('Trap', 1337188, 0, trap=True), - 'Laser Access A': ItemData('Relic', 1337189, progression=True), - 'Laser Access I': ItemData('Relic', 1337191, progression=True), - 'Laser Access M': ItemData('Relic', 1337192, progression=True), + 'Laser Access A': ItemData('Laser Access', 1337189, progression=True), + 'Laser Access I': ItemData('Laser Access', 1337191, progression=True), + 'Laser Access M': ItemData('Laser Access', 1337192, progression=True), 'Throw Stun Trap': ItemData('Trap', 1337193, 0, trap=True), - # 1337194 - 1337248 Reserved + 'Lab Access Genza': ItemData('Lab Access', 1337194, progression=True), + 'Lab Access Experiment': ItemData('Lab Access', 1337195, progression=True), + 'Lab Access Research': ItemData('Lab Access', 1337196, progression=True), + 'Lab Access Dynamo': ItemData('Lab Access', 1337197, progression=True), + 'Drawbridge Key': ItemData('Key', 1337198, progression=True), + # 1337199 - 1337248 Reserved 'Max Sand': ItemData('Stat', 1337249, 14) } @@ -259,6 +264,17 @@ class ItemData(NamedTuple): 'Mysterious Warp Beacon' ) +pyramid_start_starter_progression_items: Tuple[str, ...] = ( + 'Succubus Hairpin', + 'Succubus Hairpin', + 'Twin Pyramid Key', + 'Celestial Sash', + 'Lightwall', + 'Modern Warp Beacon', + 'Timeworn Warp Beacon', + 'Mysterious Warp Beacon' +) + filler_items: Tuple[str, ...] = ( 'Potion', 'Ether', @@ -280,4 +296,4 @@ def get_item_names_per_category() -> Dict[str, Set[str]]: for name, data in item_table.items(): categories.setdefault(data.category, set()).add(name) - return categories \ No newline at end of file + return categories diff --git a/worlds/timespinner/Locations.py b/worlds/timespinner/Locations.py index 93ac6ccb98c7..644304733a9e 100644 --- a/worlds/timespinner/Locations.py +++ b/worlds/timespinner/Locations.py @@ -92,15 +92,15 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio LocationData('Military Fortress (hangar)', 'Military Fortress: Pedestal', 1337065, lambda state: state.has('Water Mask', player) if flooded.flood_lab else (logic.has_doublejump_of_npc(state) or logic.has_forwarddash_doublejump(state))), LocationData('The lab', 'Lab: Coffee break', 1337066), LocationData('The lab', 'Lab: Lower trash right', 1337067, logic.has_doublejump), - LocationData('The lab', 'Lab: Lower trash left', 1337068, logic.has_upwarddash), + LocationData('The lab', 'Lab: Lower trash left', 1337068, lambda state: logic.has_doublejump_of_npc(state) if options.lock_key_amadeus else logic.has_upwarddash ), LocationData('The lab', 'Lab: Below lab entrance', 1337069, logic.has_doublejump), - LocationData('The lab (power off)', 'Lab: Trash jump room', 1337070), - LocationData('The lab (power off)', 'Lab: Dynamo Works', 1337071), + LocationData('The lab (power off)', 'Lab: Trash jump room', 1337070, lambda state: not options.lock_key_amadeus or logic.has_doublejump_of_npc(state) ), + LocationData('The lab (power off)', 'Lab: Dynamo Works', 1337071, lambda state: not options.lock_key_amadeus or (state.has_all(('Lab Access Research', 'Lab Access Dynamo'), player)) ), LocationData('The lab (upper)', 'Lab: Genza (Blob Mom)', 1337072), - LocationData('The lab (power off)', 'Lab: Experiment #13', 1337073), + LocationData('The lab (power off)', 'Lab: Experiment #13', 1337073, lambda state: not options.lock_key_amadeus or state.has('Lab Access Experiment', player) ), LocationData('The lab (upper)', 'Lab: Download and chest room chest', 1337074), LocationData('The lab (upper)', 'Lab: Lab secret', 1337075, logic.can_break_walls), - LocationData('The lab (power off)', 'Lab: Spider Hell', 1337076, logic.has_keycard_A), + LocationData('The lab (power off)', 'Lab: Spider Hell', 1337076, lambda state: logic.has_keycard_A and not options.lock_key_amadeus or state.has('Lab Access Research', player)), LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard bottom chest', 1337077), LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard floor secret', 1337078, lambda state: logic.has_upwarddash(state) and logic.can_break_walls(state)), LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard upper chest', 1337079, lambda state: logic.has_upwarddash(state)), @@ -214,11 +214,11 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio LocationData('Library top', 'Library: Backer room terminal (Vandagray Metropolis Map)', 1337163, lambda state: state.has('Tablet', player)), LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Medbay terminal (Bleakness Research)', 1337164, lambda state: state.has('Tablet', player) and logic.has_keycard_B(state)), LocationData('The lab (upper)', 'Lab: Download and chest room terminal (Experiment #13)', 1337165, lambda state: state.has('Tablet', player)), - LocationData('The lab (power off)', 'Lab: Middle terminal (Amadeus Laboratory Map)', 1337166, lambda state: state.has('Tablet', player)), - LocationData('The lab (power off)', 'Lab: Sentry platform terminal (Origins)', 1337167, lambda state: state.has('Tablet', player)), + LocationData('The lab (power off)', 'Lab: Middle terminal (Amadeus Laboratory Map)', 1337166, lambda state: state.has('Tablet', player) and (not options.lock_key_amadeus or state.has('Lab Access Research', player))), + LocationData('The lab (power off)', 'Lab: Sentry platform terminal (Origins)', 1337167, lambda state: state.has('Tablet', player) and (not options.lock_key_amadeus or state.has('Lab Access Genza', player) or logic.can_teleport_to(state, "Time", "GateDadsTower"))), LocationData('The lab', 'Lab: Experiment 13 terminal (W.R.E.C Farewell)', 1337168, lambda state: state.has('Tablet', player)), LocationData('The lab', 'Lab: Left terminal (Biotechnology)', 1337169, lambda state: state.has('Tablet', player)), - LocationData('The lab (power off)', 'Lab: Right terminal (Experiment #11)', 1337170, lambda state: state.has('Tablet', player)) + LocationData('The lab (power off)', 'Lab: Right terminal (Experiment #11)', 1337170, lambda state: state.has('Tablet', player) and (not options.lock_key_amadeus or state.has('Lab Access Research', player))) ) # 1337176 - 1337176 Cantoran @@ -254,7 +254,17 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Journal - Lower Left Caves (Naivety)', 1337198, lambda state: not flooded.flood_maw or state.has('Water Mask', player)) ) - # 1337199 - 1337236 Reserved for future use + # 1337199 - 1337232 Reserved for future use + + # 1337233 - 1337235 Pyramid Start checks + if not options or options.pyramid_start: + location_table += ( + LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Training Dummy', 1337233), + LocationData('Ancient Pyramid (entrance)', 'Temporal Gyre: Forest Entrance', 1337234, lambda state: logic.has_upwarddash(state) or logic.can_teleport_to(state, "Time", "GateGyre")), + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Rubble', 1337235), + ) + + # 1337236 Nightmare door # 1337237 - 1337245 GyreArchives if not options or options.gyre_archives: diff --git a/worlds/timespinner/LogicExtensions.py b/worlds/timespinner/LogicExtensions.py index 2a0a358737f7..878b69ae9c6e 100644 --- a/worlds/timespinner/LogicExtensions.py +++ b/worlds/timespinner/LogicExtensions.py @@ -10,6 +10,7 @@ class TimespinnerLogic: flag_unchained_keys: bool flag_eye_spy: bool flag_specific_keycards: bool + flag_prism_break: bool pyramid_keys_unlock: Optional[str] present_keys_unlock: Optional[str] past_keys_unlock: Optional[str] diff --git a/worlds/timespinner/Options.py b/worlds/timespinner/Options.py index 72f2d8b35abf..4cb7fbbce14b 100644 --- a/worlds/timespinner/Options.py +++ b/worlds/timespinner/Options.py @@ -60,6 +60,7 @@ class EnemyRando(Choice): option_scaled = 1 option_unscaled = 2 option_ryshia = 3 + option_no_hell_spiders = 4 alias_true = 1 class DamageRando(Choice): @@ -377,6 +378,26 @@ class PrismBreak(Toggle): """Adds 3 Laser Access items to the item pool to remove the lasers blocking the military hangar area instead of needing to beat the Golden Idol, Aelana, and The Maw.""" display_name = "Prism Break" + +class LockKeyAmadeus(Toggle): + """Lasers in Amadeus' Laboratory are disabled via items, rather than by de-powering the lab. Experiments will spawn in the lab.""" + display_name = "Lock Key Amadeus" + +class RiskyWarps(Toggle): + """Expanded free-warp eligible locations, including Azure Queen, Xarion, Amadeus' Laboratory, and Emperor's Tower.""" + display_name = "Risky Warps" + +class PyramidStart(Toggle): + """Start in ???. Takes priority over Inverted. Additional chests in Dark Forest and Pyramid. Sandman door behaves as it does in Enter Sandman.""" + display_name = "Pyramid Start" + +class GateKeep(Toggle): + """The castle drawbridge starts raised, and can be lowered via item.""" + display_name = "Gate Keep" + +class RoyalRoadblock(Toggle): + """The Royal Towers entrance door requires a royal orb (Plasma Orb, Plasma Geyser, or Royal Ring) to enter.""" + display_name = "Royal Roadblock" @dataclass class TimespinnerOptions(PerGameCommonOptions, DeathLinkMixin): @@ -415,6 +436,11 @@ class TimespinnerOptions(PerGameCommonOptions, DeathLinkMixin): unchained_keys: UnchainedKeys back_to_the_future: PresentAccessWithWheelAndSpindle prism_break: PrismBreak + lock_key_amadeus: LockKeyAmadeus + risky_warps: RiskyWarps + pyramid_start: PyramidStart + gate_keep: GateKeep + royal_roadblock: RoyalRoadblock trap_chance: TrapChance traps: Traps diff --git a/worlds/timespinner/PreCalculatedWeights.py b/worlds/timespinner/PreCalculatedWeights.py index c9d80d7a709d..3ad7c2c78af0 100644 --- a/worlds/timespinner/PreCalculatedWeights.py +++ b/worlds/timespinner/PreCalculatedWeights.py @@ -52,11 +52,12 @@ def __init__(self, options: TimespinnerOptions, random: Random): self.flood_lab = False self.pyramid_keys_unlock, self.present_key_unlock, self.past_key_unlock, self.time_key_unlock = \ - self.get_pyramid_keys_unlocks(options, random, self.flood_maw, self.flood_xarion) + self.get_pyramid_keys_unlocks(options, random, self.flood_maw, self.flood_xarion, self.flood_lab) @staticmethod def get_pyramid_keys_unlocks(options: TimespinnerOptions, random: Random, - is_maw_flooded: bool, is_xarion_flooded: bool) -> Tuple[str, str, str, str]: + is_maw_flooded: bool, is_xarion_flooded: bool, + is_lab_flooded: bool) -> Tuple[str, str, str, str]: present_teleportation_gates: List[str] = [ "GateKittyBoss", @@ -85,10 +86,15 @@ def get_pyramid_keys_unlocks(options: TimespinnerOptions, random: Random, if not is_maw_flooded: past_teleportation_gates.append("GateMaw") - if not is_xarion_flooded: - present_teleportation_gates.append("GateXarion") + if options.risky_warps: + past_teleportation_gates.append("GateLakeSereneLeft") + present_teleportation_gates.append("GateDadsTower") + if not is_xarion_flooded: + present_teleportation_gates.append("GateXarion") + if not is_lab_flooded: + present_teleportation_gates.append("GateLabEntrance") - if options.inverted: + if options.inverted or (options.pyramid_start and not options.back_to_the_future): all_gates: Tuple[str, ...] = present_teleportation_gates else: all_gates: Tuple[str, ...] = past_teleportation_gates + present_teleportation_gates diff --git a/worlds/timespinner/Regions.py b/worlds/timespinner/Regions.py index f737b461d0bc..51b1688f1a6d 100644 --- a/worlds/timespinner/Regions.py +++ b/worlds/timespinner/Regions.py @@ -106,15 +106,15 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'Sealed Caves (Sirens)', 'Varndagroth tower right (lower)', lambda state: state.has('Elevator Keycard', player)) connect(world, player, 'Sealed Caves (Sirens)', 'Space time continuum', logic.has_teleport) connect(world, player, 'Military Fortress', 'Varndagroth tower right (lower)', logic.can_kill_all_3_bosses) - connect(world, player, 'Military Fortress', 'Temporal Gyre', lambda state: state.has('Timespinner Wheel', player)) + connect(world, player, 'Military Fortress', 'Temporal Gyre', lambda state: state.has('Timespinner Wheel', player) and logic.can_kill_all_3_bosses(state)) connect(world, player, 'Military Fortress', 'Military Fortress (hangar)', logic.has_doublejump) connect(world, player, 'Military Fortress (hangar)', 'Military Fortress') connect(world, player, 'Military Fortress (hangar)', 'The lab', lambda state: logic.has_keycard_B(state) and (state.has('Water Mask', player) if flooded.flood_lab else logic.has_doublejump(state))) connect(world, player, 'Temporal Gyre', 'Military Fortress') connect(world, player, 'The lab', 'Military Fortress') - connect(world, player, 'The lab', 'The lab (power off)', logic.has_doublejump_of_npc) + connect(world, player, 'The lab', 'The lab (power off)', lambda state: options.lock_key_amadeus or logic.has_doublejump_of_npc(state)) connect(world, player, 'The lab (power off)', 'The lab', lambda state: not flooded.flood_lab or state.has('Water Mask', player)) - connect(world, player, 'The lab (power off)', 'The lab (upper)', logic.has_forwarddash_doublejump) + connect(world, player, 'The lab (power off)', 'The lab (upper)', lambda state: logic.has_forwarddash_doublejump(state) and ((not options.lock_key_amadeus) or state.has('Lab Access Genza', player))) connect(world, player, 'The lab (upper)', 'The lab (power off)') connect(world, player, 'The lab (upper)', 'Emperors tower', logic.has_forwarddash_doublejump) connect(world, player, 'The lab (upper)', 'Ancient Pyramid (entrance)', lambda state: state.has_all({'Timespinner Wheel', 'Timespinner Spindle', 'Timespinner Gear 1', 'Timespinner Gear 2', 'Timespinner Gear 3'}, player)) @@ -125,12 +125,12 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'Sealed Caves (Xarion)', 'Skeleton Shaft') connect(world, player, 'Sealed Caves (Xarion)', 'Space time continuum', logic.has_teleport) connect(world, player, 'Refugee Camp', 'Forest') - connect(world, player, 'Refugee Camp', 'Library', lambda state: options.inverted and options.back_to_the_future and state.has_all({'Timespinner Wheel', 'Timespinner Spindle'}, player)) + connect(world, player, 'Refugee Camp', 'Library', lambda state: (options.pyramid_start or options.inverted) and options.back_to_the_future and state.has_all({'Timespinner Wheel', 'Timespinner Spindle'}, player)) connect(world, player, 'Refugee Camp', 'Space time continuum', logic.has_teleport) connect(world, player, 'Forest', 'Refugee Camp') connect(world, player, 'Forest', 'Left Side forest Caves', lambda state: flooded.flood_lake_serene_bridge or state.has('Talaria Attachment', player) or logic.has_timestop(state)) connect(world, player, 'Forest', 'Caves of Banishment (Sirens)') - connect(world, player, 'Forest', 'Castle Ramparts') + connect(world, player, 'Forest', 'Castle Ramparts', lambda state: not options.gate_keep or state.has('Drawbridge Key', player) or logic.has_upwarddash(state)) connect(world, player, 'Left Side forest Caves', 'Forest') connect(world, player, 'Left Side forest Caves', 'Upper Lake Serene', logic.has_timestop) connect(world, player, 'Left Side forest Caves', 'Lower Lake Serene', lambda state: not flooded.flood_lake_serene or state.has('Water Mask', player)) @@ -152,7 +152,7 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'Castle Ramparts', 'Space time continuum', logic.has_teleport) connect(world, player, 'Castle Keep', 'Castle Ramparts') connect(world, player, 'Castle Keep', 'Castle Basement', lambda state: not flooded.flood_basement or state.has('Water Mask', player)) - connect(world, player, 'Castle Keep', 'Royal towers (lower)', logic.has_doublejump) + connect(world, player, 'Castle Keep', 'Royal towers (lower)', lambda state: logic.has_doublejump(state) and (not options.royal_roadblock or logic.has_pink(state))) connect(world, player, 'Castle Keep', 'Space time continuum', logic.has_teleport) connect(world, player, 'Royal towers (lower)', 'Castle Keep') connect(world, player, 'Royal towers (lower)', 'Royal towers', lambda state: state.has('Timespinner Wheel', player) or logic.has_forwarddash_doublejump(state)) @@ -162,9 +162,12 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'Royal towers (upper)', 'Royal towers') #connect(world, player, 'Ancient Pyramid (entrance)', 'The lab (upper)', lambda state: not is_option_enabled(world, player, "EnterSandman")) connect(world, player, 'Ancient Pyramid (entrance)', 'Ancient Pyramid (left)', logic.has_doublejump) + connect(world, player, 'Ancient Pyramid (entrance)', 'Space time continuum', logic.has_teleport) connect(world, player, 'Ancient Pyramid (left)', 'Ancient Pyramid (entrance)') connect(world, player, 'Ancient Pyramid (left)', 'Ancient Pyramid (right)', lambda state: flooded.flood_pyramid_shaft or logic.has_upwarddash(state)) + connect(world, player, 'Ancient Pyramid (left)', 'Space time continuum', logic.has_teleport) connect(world, player, 'Ancient Pyramid (right)', 'Ancient Pyramid (left)', lambda state: flooded.flood_pyramid_shaft or logic.has_upwarddash(state)) + connect(world, player, 'Ancient Pyramid (right)', 'Space time continuum', logic.has_teleport) connect(world, player, 'Space time continuum', 'Lake desolation', lambda state: logic.can_teleport_to(state, "Present", "GateLakeDesolation")) connect(world, player, 'Space time continuum', 'Lower lake desolation', lambda state: logic.can_teleport_to(state, "Present", "GateKittyBoss")) connect(world, player, 'Space time continuum', 'Library', lambda state: logic.can_teleport_to(state, "Present", "GateLeftLibrary")) @@ -180,8 +183,9 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'Space time continuum', 'Royal towers (lower)', lambda state: logic.can_teleport_to(state, "Past", "GateRoyalTowers")) connect(world, player, 'Space time continuum', 'Caves of Banishment (Maw)', lambda state: logic.can_teleport_to(state, "Past", "GateMaw")) connect(world, player, 'Space time continuum', 'Caves of Banishment (upper)', lambda state: logic.can_teleport_to(state, "Past", "GateCavesOfBanishment")) - connect(world, player, 'Space time continuum', 'Ancient Pyramid (entrance)', lambda state: logic.can_teleport_to(state, "Time", "GateGyre") or (not options.unchained_keys and options.enter_sandman)) - connect(world, player, 'Space time continuum', 'Ancient Pyramid (left)', lambda state: logic.can_teleport_to(state, "Time", "GateLeftPyramid")) + connect(world, player, 'Space time continuum', 'Military Fortress (hangar)', lambda state: logic.can_teleport_to(state, "Present", "GateLabEntrance")) + connect(world, player, 'Space time continuum', 'The lab (upper)', lambda state: logic.can_teleport_to(state, "Present", "GateDadsTower")) + connect(world, player, 'Space time continuum', 'Ancient Pyramid (entrance)', lambda state: logic.can_teleport_to(state, "Time", "GateGyre") or logic.can_teleport_to(state, "Time", "GateLeftPyramid") or (not options.unchained_keys and options.enter_sandman)) connect(world, player, 'Space time continuum', 'Ancient Pyramid (right)', lambda state: logic.can_teleport_to(state, "Time", "GateRightPyramid")) if options.gyre_archives: @@ -227,7 +231,9 @@ def connectStartingRegion(world: MultiWorld, player: int, options: TimespinnerOp tutorial = world.get_region('Tutorial', player) space_time_continuum = world.get_region('Space time continuum', player) - if options.inverted: + if options.pyramid_start: + starting_region = world.get_region('Ancient Pyramid (entrance)', player) + elif options.inverted: starting_region = world.get_region('Refugee Camp', player) else: starting_region = world.get_region('Lake desolation', player) @@ -264,4 +270,4 @@ def split_location_datas_per_region(locations: List[LocationData]) -> Dict[str, for location in locations: per_region.setdefault(location.region, []).append(location) - return per_region \ No newline at end of file + return per_region diff --git a/worlds/timespinner/__init__.py b/worlds/timespinner/__init__.py index ca31d08326b5..4d1efc41e53f 100644 --- a/worlds/timespinner/__init__.py +++ b/worlds/timespinner/__init__.py @@ -1,7 +1,7 @@ from typing import Dict, List, Set, Tuple, TextIO, Any, Optional from BaseClasses import Item, Tutorial, ItemClassification from .Items import get_item_names_per_category -from .Items import item_table, starter_melee_weapons, starter_spells, filler_items, starter_progression_items +from .Items import item_table, starter_melee_weapons, starter_spells, filler_items, starter_progression_items, pyramid_start_starter_progression_items from .Locations import get_location_datas, EventId from .Options import BackwardsCompatiableTimespinnerOptions, Toggle from .PreCalculatedWeights import PreCalculatedWeights @@ -126,6 +126,11 @@ def fill_slot_data(self) -> Dict[str, object]: "UnchainedKeys": self.options.unchained_keys.value, "PresentAccessWithWheelAndSpindle": self.options.back_to_the_future.value, "PrismBreak": self.options.prism_break.value, + "LockKeyAmadeus": self.options.lock_key_amadeus.value, + "RiskyWarps": self.options.risky_warps.value, + "PyramidStart": self.options.pyramid_start.value, + "GateKeep": self.options.gate_keep.value, + "RoyalRoadblock": self.options.royal_roadblock.value, "Traps": self.options.traps.value, "DeathLink": self.options.death_link.value, "StinkyMaw": True, @@ -203,7 +208,7 @@ def interpret_slot_data(self, slot_data: Optional[Dict[str, Any]]) -> Optional[D self.precalculated_weights.past_key_unlock = slot_data["PastGate"] self.precalculated_weights.time_key_unlock = slot_data["TimeGate"] # rising tides - if (slot_data["Basement"] > 1): + if (slot_data["Basement"] > 0): self.precalculated_weights.flood_basement = True if (slot_data["Basement"] == 2): self.precalculated_weights.flood_basement_high = True @@ -304,6 +309,11 @@ def create_item(self, name: str) -> Item: elif name in {"Laser Access A", "Laser Access I", "Laser Access M"} \ and not self.options.prism_break: item.classification = ItemClassification.filler + elif name in {"Lab Access Genza", "Lab Access Experiment", "Lab Access Research", "Lab Access Dynamo"} \ + and not self.options.lock_key_amadeus: + item.classification = ItemClassification.filler + elif name == "Drawbridge Key" and not self.options.gate_keep: + item.classification = ItemClassification.filler return item @@ -341,6 +351,15 @@ def get_excluded_items(self) -> Set[str]: excluded_items.add('Laser Access I') excluded_items.add('Laser Access M') + if not self.options.lock_key_amadeus: + excluded_items.add('Lab Access Genza') + excluded_items.add('Lab Access Experiment') + excluded_items.add('Lab Access Research') + excluded_items.add('Lab Access Dynamo') + + if not self.options.gate_keep: + excluded_items.add('Drawbridge Key') + for item in self.multiworld.precollected_items[self.player]: if item.name not in self.item_name_groups['UseItem']: excluded_items.add(item.name) @@ -376,15 +395,18 @@ def assign_starter_item(self, excluded_items: Set[str], location: str, item_list self.place_locked_item(excluded_items, location, item_name) def place_first_progression_item(self, excluded_items: Set[str]) -> None: - if self.options.quick_seed or self.options.inverted or self.precalculated_weights.flood_lake_desolation: + if (self.options.quick_seed or self.options.inverted or self.precalculated_weights.flood_lake_desolation) \ + and not self.options.pyramid_start: return + enabled_starter_progression_items = pyramid_start_starter_progression_items if self.options.pyramid_start else starter_progression_items + for item_name in self.options.start_inventory.value.keys(): - if item_name in starter_progression_items: + if item_name in enabled_starter_progression_items: return local_starter_progression_items = tuple( - item for item in starter_progression_items + item for item in enabled_starter_progression_items if item not in excluded_items and item not in self.options.non_local_items.value) if not local_starter_progression_items: From 3986f6f11ae82e312eb3d7605d831ffc35a7275b Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sat, 8 Mar 2025 08:57:16 -0800 Subject: [PATCH 0183/1218] Pokemon Emerald: Randomize rock smash encounters (#3912) * Pokemon Emerald: WIP add rock smash encounter randomization * Pokemon Emerald: Refactor encounter data on maps * Pokemon Emerald: Remove unused import * Pokemon Emerald: Swap StrEnum for regular Enum and use .value --- worlds/pokemon_emerald/__init__.py | 59 +---- worlds/pokemon_emerald/data.py | 34 ++- .../pokemon_emerald/data/extracted_data.json | 2 +- worlds/pokemon_emerald/pokemon.py | 241 +++++++++--------- worlds/pokemon_emerald/regions.py | 20 +- worlds/pokemon_emerald/rom.py | 10 +- worlds/pokemon_emerald/util.py | 24 +- 7 files changed, 194 insertions(+), 196 deletions(-) diff --git a/worlds/pokemon_emerald/__init__.py b/worlds/pokemon_emerald/__init__.py index 50d6279179d9..9996bfc6b7a2 100644 --- a/worlds/pokemon_emerald/__init__.py +++ b/worlds/pokemon_emerald/__init__.py @@ -27,6 +27,7 @@ randomize_legendary_encounters, randomize_misc_pokemon, randomize_starters, randomize_tm_hm_compatibility,randomize_types, randomize_wild_encounters) from .rom import PokemonEmeraldProcedurePatch, write_tokens +from .util import get_encounter_type_label class PokemonEmeraldWebWorld(WebWorld): @@ -636,32 +637,11 @@ def write_spoiler(self, spoiler_handle: TextIO): spoiler_handle.write(f"\n\nWild Pokemon ({self.player_name}):\n\n") - slot_to_rod_suffix = { - 0: " (Old Rod)", - 1: " (Old Rod)", - 2: " (Good Rod)", - 3: " (Good Rod)", - 4: " (Good Rod)", - 5: " (Super Rod)", - 6: " (Super Rod)", - 7: " (Super Rod)", - 8: " (Super Rod)", - 9: " (Super Rod)", - } - species_maps = defaultdict(set) - for map in self.modified_maps.values(): - if map.land_encounters is not None: - for encounter in map.land_encounters.slots: - species_maps[encounter].add(map.label + " (Land)") - - if map.water_encounters is not None: - for encounter in map.water_encounters.slots: - species_maps[encounter].add(map.label + " (Water)") - - if map.fishing_encounters is not None: - for slot, encounter in enumerate(map.fishing_encounters.slots): - species_maps[encounter].add(map.label + slot_to_rod_suffix[slot]) + for map_data in self.modified_maps.values(): + for encounter_type, encounter_data in map_data.encounters.items(): + for i, encounter in enumerate(encounter_data.slots): + species_maps[encounter].add(f"{map_data.label} ({get_encounter_type_label(encounter_type, i)})") lines = [f"{emerald_data.species[species].label}: {', '.join(sorted(maps))}\n" for species, maps in species_maps.items()] @@ -675,32 +655,11 @@ def extend_hint_information(self, hint_data): if self.options.dexsanity: from collections import defaultdict - slot_to_rod_suffix = { - 0: " (Old Rod)", - 1: " (Old Rod)", - 2: " (Good Rod)", - 3: " (Good Rod)", - 4: " (Good Rod)", - 5: " (Super Rod)", - 6: " (Super Rod)", - 7: " (Super Rod)", - 8: " (Super Rod)", - 9: " (Super Rod)", - } - species_maps = defaultdict(set) - for map in self.modified_maps.values(): - if map.land_encounters is not None: - for encounter in map.land_encounters.slots: - species_maps[encounter].add(map.label + " (Land)") - - if map.water_encounters is not None: - for encounter in map.water_encounters.slots: - species_maps[encounter].add(map.label + " (Water)") - - if map.fishing_encounters is not None: - for slot, encounter in enumerate(map.fishing_encounters.slots): - species_maps[encounter].add(map.label + slot_to_rod_suffix[slot]) + for map_data in self.modified_maps.values(): + for encounter_type, encounter_data in map_data.encounters.items(): + for i, encounter in enumerate(encounter_data.slots): + species_maps[encounter].add(f"{map_data.label} ({get_encounter_type_label(encounter_type, i)})") hint_data[self.player] = { self.location_name_to_id[f"Pokedex - {emerald_data.species[species].label}"]: ", ".join(sorted(maps)) diff --git a/worlds/pokemon_emerald/data.py b/worlds/pokemon_emerald/data.py index 198572628346..5b5d65369cc9 100644 --- a/worlds/pokemon_emerald/data.py +++ b/worlds/pokemon_emerald/data.py @@ -5,7 +5,7 @@ and sorting, and Warp methods. """ from dataclasses import dataclass -from enum import IntEnum +from enum import IntEnum, Enum import orjson from typing import Dict, List, NamedTuple, Optional, Set, FrozenSet, Tuple, Any, Union import pkgutil @@ -148,14 +148,20 @@ class EncounterTableData(NamedTuple): address: int +# class EncounterType(StrEnum): # StrEnum introduced in python 3.11 +class EncounterType(Enum): + LAND = "LAND" + WATER = "WATER" + FISHING = "FISHING" + ROCK_SMASH = "ROCK_SMASH" + + @dataclass class MapData: name: str label: str header_address: int - land_encounters: Optional[EncounterTableData] - water_encounters: Optional[EncounterTableData] - fishing_encounters: Optional[EncounterTableData] + encounters: Dict[EncounterType, EncounterTableData] class EventData(NamedTuple): @@ -348,25 +354,27 @@ def _init() -> None: if map_name in IGNORABLE_MAPS: continue - land_encounters = None - water_encounters = None - fishing_encounters = None - + encounter_tables: Dict[EncounterType, EncounterTableData] = {} if "land_encounters" in map_json: - land_encounters = EncounterTableData( + encounter_tables[EncounterType.LAND] = EncounterTableData( map_json["land_encounters"]["slots"], map_json["land_encounters"]["address"] ) if "water_encounters" in map_json: - water_encounters = EncounterTableData( + encounter_tables[EncounterType.WATER] = EncounterTableData( map_json["water_encounters"]["slots"], map_json["water_encounters"]["address"] ) if "fishing_encounters" in map_json: - fishing_encounters = EncounterTableData( + encounter_tables[EncounterType.FISHING] = EncounterTableData( map_json["fishing_encounters"]["slots"], map_json["fishing_encounters"]["address"] ) + if "rock_smash_encounters" in map_json: + encounter_tables[EncounterType.ROCK_SMASH] = EncounterTableData( + map_json["rock_smash_encounters"]["slots"], + map_json["rock_smash_encounters"]["address"] + ) # Derive a user-facing label label = [] @@ -398,9 +406,7 @@ def _init() -> None: map_name, " ".join(label), map_json["header_address"], - land_encounters, - water_encounters, - fishing_encounters + encounter_tables ) # Load/merge region json files diff --git a/worlds/pokemon_emerald/data/extracted_data.json b/worlds/pokemon_emerald/data/extracted_data.json index fcc2cf24e7b7..f270637481cb 100644 --- a/worlds/pokemon_emerald/data/extracted_data.json +++ b/worlds/pokemon_emerald/data/extracted_data.json @@ -1 +1 @@ -{"_comment":"DO NOT MODIFY. This file was auto-generated. Your changes will likely be overwritten.","_rom_name":"pokemon emerald version / AP 5","constants":{"ABILITIES_COUNT":78,"ABILITY_AIR_LOCK":77,"ABILITY_ARENA_TRAP":71,"ABILITY_BATTLE_ARMOR":4,"ABILITY_BLAZE":66,"ABILITY_CACOPHONY":76,"ABILITY_CHLOROPHYLL":34,"ABILITY_CLEAR_BODY":29,"ABILITY_CLOUD_NINE":13,"ABILITY_COLOR_CHANGE":16,"ABILITY_COMPOUND_EYES":14,"ABILITY_CUTE_CHARM":56,"ABILITY_DAMP":6,"ABILITY_DRIZZLE":2,"ABILITY_DROUGHT":70,"ABILITY_EARLY_BIRD":48,"ABILITY_EFFECT_SPORE":27,"ABILITY_FLAME_BODY":49,"ABILITY_FLASH_FIRE":18,"ABILITY_FORECAST":59,"ABILITY_GUTS":62,"ABILITY_HUGE_POWER":37,"ABILITY_HUSTLE":55,"ABILITY_HYPER_CUTTER":52,"ABILITY_ILLUMINATE":35,"ABILITY_IMMUNITY":17,"ABILITY_INNER_FOCUS":39,"ABILITY_INSOMNIA":15,"ABILITY_INTIMIDATE":22,"ABILITY_KEEN_EYE":51,"ABILITY_LEVITATE":26,"ABILITY_LIGHTNING_ROD":31,"ABILITY_LIMBER":7,"ABILITY_LIQUID_OOZE":64,"ABILITY_MAGMA_ARMOR":40,"ABILITY_MAGNET_PULL":42,"ABILITY_MARVEL_SCALE":63,"ABILITY_MINUS":58,"ABILITY_NATURAL_CURE":30,"ABILITY_NONE":0,"ABILITY_OBLIVIOUS":12,"ABILITY_OVERGROW":65,"ABILITY_OWN_TEMPO":20,"ABILITY_PICKUP":53,"ABILITY_PLUS":57,"ABILITY_POISON_POINT":38,"ABILITY_PRESSURE":46,"ABILITY_PURE_POWER":74,"ABILITY_RAIN_DISH":44,"ABILITY_ROCK_HEAD":69,"ABILITY_ROUGH_SKIN":24,"ABILITY_RUN_AWAY":50,"ABILITY_SAND_STREAM":45,"ABILITY_SAND_VEIL":8,"ABILITY_SERENE_GRACE":32,"ABILITY_SHADOW_TAG":23,"ABILITY_SHED_SKIN":61,"ABILITY_SHELL_ARMOR":75,"ABILITY_SHIELD_DUST":19,"ABILITY_SOUNDPROOF":43,"ABILITY_SPEED_BOOST":3,"ABILITY_STATIC":9,"ABILITY_STENCH":1,"ABILITY_STICKY_HOLD":60,"ABILITY_STURDY":5,"ABILITY_SUCTION_CUPS":21,"ABILITY_SWARM":68,"ABILITY_SWIFT_SWIM":33,"ABILITY_SYNCHRONIZE":28,"ABILITY_THICK_FAT":47,"ABILITY_TORRENT":67,"ABILITY_TRACE":36,"ABILITY_TRUANT":54,"ABILITY_VITAL_SPIRIT":72,"ABILITY_VOLT_ABSORB":10,"ABILITY_WATER_ABSORB":11,"ABILITY_WATER_VEIL":41,"ABILITY_WHITE_SMOKE":73,"ABILITY_WONDER_GUARD":25,"ACRO_BIKE":1,"BAG_ITEM_CAPACITY_DIGITS":2,"BERRY_CAPACITY_DIGITS":3,"BERRY_FIRMNESS_HARD":3,"BERRY_FIRMNESS_SOFT":2,"BERRY_FIRMNESS_SUPER_HARD":5,"BERRY_FIRMNESS_UNKNOWN":0,"BERRY_FIRMNESS_VERY_HARD":4,"BERRY_FIRMNESS_VERY_SOFT":1,"BERRY_NONE":0,"BERRY_STAGE_BERRIES":5,"BERRY_STAGE_FLOWERING":4,"BERRY_STAGE_NO_BERRY":0,"BERRY_STAGE_PLANTED":1,"BERRY_STAGE_SPARKLING":255,"BERRY_STAGE_SPROUTED":2,"BERRY_STAGE_TALLER":3,"BERRY_TREES_COUNT":128,"BERRY_TREE_ROUTE_102_ORAN":2,"BERRY_TREE_ROUTE_102_PECHA":1,"BERRY_TREE_ROUTE_103_CHERI_1":5,"BERRY_TREE_ROUTE_103_CHERI_2":7,"BERRY_TREE_ROUTE_103_LEPPA":6,"BERRY_TREE_ROUTE_104_CHERI_1":8,"BERRY_TREE_ROUTE_104_CHERI_2":76,"BERRY_TREE_ROUTE_104_LEPPA":10,"BERRY_TREE_ROUTE_104_ORAN_1":4,"BERRY_TREE_ROUTE_104_ORAN_2":11,"BERRY_TREE_ROUTE_104_PECHA":13,"BERRY_TREE_ROUTE_104_SOIL_1":3,"BERRY_TREE_ROUTE_104_SOIL_2":9,"BERRY_TREE_ROUTE_104_SOIL_3":12,"BERRY_TREE_ROUTE_104_SOIL_4":75,"BERRY_TREE_ROUTE_110_NANAB_1":16,"BERRY_TREE_ROUTE_110_NANAB_2":17,"BERRY_TREE_ROUTE_110_NANAB_3":18,"BERRY_TREE_ROUTE_111_ORAN_1":80,"BERRY_TREE_ROUTE_111_ORAN_2":81,"BERRY_TREE_ROUTE_111_RAZZ_1":19,"BERRY_TREE_ROUTE_111_RAZZ_2":20,"BERRY_TREE_ROUTE_112_PECHA_1":22,"BERRY_TREE_ROUTE_112_PECHA_2":23,"BERRY_TREE_ROUTE_112_RAWST_1":21,"BERRY_TREE_ROUTE_112_RAWST_2":24,"BERRY_TREE_ROUTE_114_PERSIM_1":68,"BERRY_TREE_ROUTE_114_PERSIM_2":77,"BERRY_TREE_ROUTE_114_PERSIM_3":78,"BERRY_TREE_ROUTE_115_BLUK_1":55,"BERRY_TREE_ROUTE_115_BLUK_2":56,"BERRY_TREE_ROUTE_115_KELPSY_1":69,"BERRY_TREE_ROUTE_115_KELPSY_2":70,"BERRY_TREE_ROUTE_115_KELPSY_3":71,"BERRY_TREE_ROUTE_116_CHESTO_1":26,"BERRY_TREE_ROUTE_116_CHESTO_2":66,"BERRY_TREE_ROUTE_116_PINAP_1":25,"BERRY_TREE_ROUTE_116_PINAP_2":67,"BERRY_TREE_ROUTE_117_WEPEAR_1":27,"BERRY_TREE_ROUTE_117_WEPEAR_2":28,"BERRY_TREE_ROUTE_117_WEPEAR_3":29,"BERRY_TREE_ROUTE_118_SITRUS_1":31,"BERRY_TREE_ROUTE_118_SITRUS_2":33,"BERRY_TREE_ROUTE_118_SOIL":32,"BERRY_TREE_ROUTE_119_HONDEW_1":83,"BERRY_TREE_ROUTE_119_HONDEW_2":84,"BERRY_TREE_ROUTE_119_LEPPA":86,"BERRY_TREE_ROUTE_119_POMEG_1":34,"BERRY_TREE_ROUTE_119_POMEG_2":35,"BERRY_TREE_ROUTE_119_POMEG_3":36,"BERRY_TREE_ROUTE_119_SITRUS":85,"BERRY_TREE_ROUTE_120_ASPEAR_1":37,"BERRY_TREE_ROUTE_120_ASPEAR_2":38,"BERRY_TREE_ROUTE_120_ASPEAR_3":39,"BERRY_TREE_ROUTE_120_NANAB":44,"BERRY_TREE_ROUTE_120_PECHA_1":40,"BERRY_TREE_ROUTE_120_PECHA_2":41,"BERRY_TREE_ROUTE_120_PECHA_3":42,"BERRY_TREE_ROUTE_120_PINAP":45,"BERRY_TREE_ROUTE_120_RAZZ":43,"BERRY_TREE_ROUTE_120_WEPEAR":46,"BERRY_TREE_ROUTE_121_ASPEAR":48,"BERRY_TREE_ROUTE_121_CHESTO":50,"BERRY_TREE_ROUTE_121_NANAB_1":52,"BERRY_TREE_ROUTE_121_NANAB_2":53,"BERRY_TREE_ROUTE_121_PERSIM":47,"BERRY_TREE_ROUTE_121_RAWST":49,"BERRY_TREE_ROUTE_121_SOIL_1":51,"BERRY_TREE_ROUTE_121_SOIL_2":54,"BERRY_TREE_ROUTE_123_GREPA_1":60,"BERRY_TREE_ROUTE_123_GREPA_2":61,"BERRY_TREE_ROUTE_123_GREPA_3":65,"BERRY_TREE_ROUTE_123_GREPA_4":72,"BERRY_TREE_ROUTE_123_LEPPA_1":62,"BERRY_TREE_ROUTE_123_LEPPA_2":64,"BERRY_TREE_ROUTE_123_PECHA":87,"BERRY_TREE_ROUTE_123_POMEG_1":15,"BERRY_TREE_ROUTE_123_POMEG_2":30,"BERRY_TREE_ROUTE_123_POMEG_3":58,"BERRY_TREE_ROUTE_123_POMEG_4":59,"BERRY_TREE_ROUTE_123_QUALOT_1":14,"BERRY_TREE_ROUTE_123_QUALOT_2":73,"BERRY_TREE_ROUTE_123_QUALOT_3":74,"BERRY_TREE_ROUTE_123_QUALOT_4":79,"BERRY_TREE_ROUTE_123_RAWST":57,"BERRY_TREE_ROUTE_123_SITRUS":88,"BERRY_TREE_ROUTE_123_SOIL":63,"BERRY_TREE_ROUTE_130_LIECHI":82,"DAILY_FLAGS_END":2399,"DAILY_FLAGS_START":2336,"FIRST_BALL":1,"FIRST_BERRY_INDEX":133,"FIRST_BERRY_MASTER_BERRY":153,"FIRST_BERRY_MASTER_WIFE_BERRY":133,"FIRST_KIRI_BERRY":153,"FIRST_MAIL_INDEX":121,"FIRST_ROUTE_114_MAN_BERRY":148,"FLAGS_COUNT":2400,"FLAG_ADDED_MATCH_CALL_TO_POKENAV":304,"FLAG_ADVENTURE_STARTED":116,"FLAG_ARRIVED_AT_MARINE_CAVE_EMERGE_SPOT":2265,"FLAG_ARRIVED_AT_NAVEL_ROCK":2273,"FLAG_ARRIVED_AT_TERRA_CAVE_ENTRANCE":2266,"FLAG_ARRIVED_ON_FARAWAY_ISLAND":2264,"FLAG_BADGE01_GET":2151,"FLAG_BADGE02_GET":2152,"FLAG_BADGE03_GET":2153,"FLAG_BADGE04_GET":2154,"FLAG_BADGE05_GET":2155,"FLAG_BADGE06_GET":2156,"FLAG_BADGE07_GET":2157,"FLAG_BADGE08_GET":2158,"FLAG_BATTLE_FRONTIER_TRADE_DONE":156,"FLAG_BEAT_MAGMA_GRUNT_JAGGED_PASS":313,"FLAG_BEAUTY_PAINTING_MADE":161,"FLAG_BERRY_MASTERS_WIFE":1197,"FLAG_BERRY_MASTER_RECEIVED_BERRY_1":1195,"FLAG_BERRY_MASTER_RECEIVED_BERRY_2":1196,"FLAG_BERRY_TREES_START":612,"FLAG_BERRY_TREE_01":612,"FLAG_BERRY_TREE_02":613,"FLAG_BERRY_TREE_03":614,"FLAG_BERRY_TREE_04":615,"FLAG_BERRY_TREE_05":616,"FLAG_BERRY_TREE_06":617,"FLAG_BERRY_TREE_07":618,"FLAG_BERRY_TREE_08":619,"FLAG_BERRY_TREE_09":620,"FLAG_BERRY_TREE_10":621,"FLAG_BERRY_TREE_11":622,"FLAG_BERRY_TREE_12":623,"FLAG_BERRY_TREE_13":624,"FLAG_BERRY_TREE_14":625,"FLAG_BERRY_TREE_15":626,"FLAG_BERRY_TREE_16":627,"FLAG_BERRY_TREE_17":628,"FLAG_BERRY_TREE_18":629,"FLAG_BERRY_TREE_19":630,"FLAG_BERRY_TREE_20":631,"FLAG_BERRY_TREE_21":632,"FLAG_BERRY_TREE_22":633,"FLAG_BERRY_TREE_23":634,"FLAG_BERRY_TREE_24":635,"FLAG_BERRY_TREE_25":636,"FLAG_BERRY_TREE_26":637,"FLAG_BERRY_TREE_27":638,"FLAG_BERRY_TREE_28":639,"FLAG_BERRY_TREE_29":640,"FLAG_BERRY_TREE_30":641,"FLAG_BERRY_TREE_31":642,"FLAG_BERRY_TREE_32":643,"FLAG_BERRY_TREE_33":644,"FLAG_BERRY_TREE_34":645,"FLAG_BERRY_TREE_35":646,"FLAG_BERRY_TREE_36":647,"FLAG_BERRY_TREE_37":648,"FLAG_BERRY_TREE_38":649,"FLAG_BERRY_TREE_39":650,"FLAG_BERRY_TREE_40":651,"FLAG_BERRY_TREE_41":652,"FLAG_BERRY_TREE_42":653,"FLAG_BERRY_TREE_43":654,"FLAG_BERRY_TREE_44":655,"FLAG_BERRY_TREE_45":656,"FLAG_BERRY_TREE_46":657,"FLAG_BERRY_TREE_47":658,"FLAG_BERRY_TREE_48":659,"FLAG_BERRY_TREE_49":660,"FLAG_BERRY_TREE_50":661,"FLAG_BERRY_TREE_51":662,"FLAG_BERRY_TREE_52":663,"FLAG_BERRY_TREE_53":664,"FLAG_BERRY_TREE_54":665,"FLAG_BERRY_TREE_55":666,"FLAG_BERRY_TREE_56":667,"FLAG_BERRY_TREE_57":668,"FLAG_BERRY_TREE_58":669,"FLAG_BERRY_TREE_59":670,"FLAG_BERRY_TREE_60":671,"FLAG_BERRY_TREE_61":672,"FLAG_BERRY_TREE_62":673,"FLAG_BERRY_TREE_63":674,"FLAG_BERRY_TREE_64":675,"FLAG_BERRY_TREE_65":676,"FLAG_BERRY_TREE_66":677,"FLAG_BERRY_TREE_67":678,"FLAG_BERRY_TREE_68":679,"FLAG_BERRY_TREE_69":680,"FLAG_BERRY_TREE_70":681,"FLAG_BERRY_TREE_71":682,"FLAG_BERRY_TREE_72":683,"FLAG_BERRY_TREE_73":684,"FLAG_BERRY_TREE_74":685,"FLAG_BERRY_TREE_75":686,"FLAG_BERRY_TREE_76":687,"FLAG_BERRY_TREE_77":688,"FLAG_BERRY_TREE_78":689,"FLAG_BERRY_TREE_79":690,"FLAG_BERRY_TREE_80":691,"FLAG_BERRY_TREE_81":692,"FLAG_BERRY_TREE_82":693,"FLAG_BERRY_TREE_83":694,"FLAG_BERRY_TREE_84":695,"FLAG_BERRY_TREE_85":696,"FLAG_BERRY_TREE_86":697,"FLAG_BERRY_TREE_87":698,"FLAG_BERRY_TREE_88":699,"FLAG_BETTER_SHOPS_ENABLED":206,"FLAG_BIRCH_AIDE_MET":88,"FLAG_CANCEL_BATTLE_ROOM_CHALLENGE":119,"FLAG_CAUGHT_DEOXYS":429,"FLAG_CAUGHT_GROUDON":480,"FLAG_CAUGHT_HO_OH":146,"FLAG_CAUGHT_KYOGRE":479,"FLAG_CAUGHT_LATIAS":457,"FLAG_CAUGHT_LATIOS":482,"FLAG_CAUGHT_LUGIA":145,"FLAG_CAUGHT_MEW":458,"FLAG_CAUGHT_RAYQUAZA":478,"FLAG_CAUGHT_REGICE":427,"FLAG_CAUGHT_REGIROCK":426,"FLAG_CAUGHT_REGISTEEL":483,"FLAG_CHOSEN_MULTI_BATTLE_NPC_PARTNER":338,"FLAG_CHOSE_CLAW_FOSSIL":336,"FLAG_CHOSE_ROOT_FOSSIL":335,"FLAG_COLLECTED_ALL_GOLD_SYMBOLS":466,"FLAG_COLLECTED_ALL_SILVER_SYMBOLS":92,"FLAG_CONTEST_SKETCH_CREATED":270,"FLAG_COOL_PAINTING_MADE":160,"FLAG_CUTE_PAINTING_MADE":162,"FLAG_DAILY_APPRENTICE_LEAVES":2356,"FLAG_DAILY_BERRY_MASTERS_WIFE":2353,"FLAG_DAILY_BERRY_MASTER_RECEIVED_BERRY":2349,"FLAG_DAILY_CONTEST_LOBBY_RECEIVED_BERRY":2337,"FLAG_DAILY_FLOWER_SHOP_RECEIVED_BERRY":2352,"FLAG_DAILY_LILYCOVE_RECEIVED_BERRY":2351,"FLAG_DAILY_PICKED_LOTO_TICKET":2346,"FLAG_DAILY_ROUTE_111_RECEIVED_BERRY":2348,"FLAG_DAILY_ROUTE_114_RECEIVED_BERRY":2347,"FLAG_DAILY_ROUTE_120_RECEIVED_BERRY":2350,"FLAG_DAILY_SECRET_BASE":2338,"FLAG_DAILY_SOOTOPOLIS_RECEIVED_BERRY":2354,"FLAG_DECLINED_BIKE":89,"FLAG_DECLINED_RIVAL_BATTLE_LILYCOVE":286,"FLAG_DECLINED_WALLY_BATTLE_MAUVILLE":284,"FLAG_DECORATION_1":174,"FLAG_DECORATION_10":183,"FLAG_DECORATION_11":184,"FLAG_DECORATION_12":185,"FLAG_DECORATION_13":186,"FLAG_DECORATION_14":187,"FLAG_DECORATION_2":175,"FLAG_DECORATION_3":176,"FLAG_DECORATION_4":177,"FLAG_DECORATION_5":178,"FLAG_DECORATION_6":179,"FLAG_DECORATION_7":180,"FLAG_DECORATION_8":181,"FLAG_DECORATION_9":182,"FLAG_DEFEATED_DEOXYS":428,"FLAG_DEFEATED_DEWFORD_GYM":1265,"FLAG_DEFEATED_ELECTRODE_1_AQUA_HIDEOUT":452,"FLAG_DEFEATED_ELECTRODE_2_AQUA_HIDEOUT":453,"FLAG_DEFEATED_ELITE_4_DRAKE":1278,"FLAG_DEFEATED_ELITE_4_GLACIA":1277,"FLAG_DEFEATED_ELITE_4_PHOEBE":1276,"FLAG_DEFEATED_ELITE_4_SIDNEY":1275,"FLAG_DEFEATED_EVIL_TEAM_MT_CHIMNEY":139,"FLAG_DEFEATED_FORTREE_GYM":1269,"FLAG_DEFEATED_GROUDON":447,"FLAG_DEFEATED_GRUNT_SPACE_CENTER_1F":191,"FLAG_DEFEATED_HO_OH":476,"FLAG_DEFEATED_KECLEON_1_ROUTE_119":989,"FLAG_DEFEATED_KECLEON_1_ROUTE_120":982,"FLAG_DEFEATED_KECLEON_2_ROUTE_119":990,"FLAG_DEFEATED_KECLEON_2_ROUTE_120":985,"FLAG_DEFEATED_KECLEON_3_ROUTE_120":986,"FLAG_DEFEATED_KECLEON_4_ROUTE_120":987,"FLAG_DEFEATED_KECLEON_5_ROUTE_120":988,"FLAG_DEFEATED_KEKLEON_ROUTE_120_BRIDGE":970,"FLAG_DEFEATED_KYOGRE":446,"FLAG_DEFEATED_LATIAS":456,"FLAG_DEFEATED_LATIOS":481,"FLAG_DEFEATED_LAVARIDGE_GYM":1267,"FLAG_DEFEATED_LUGIA":477,"FLAG_DEFEATED_MAGMA_SPACE_CENTER":117,"FLAG_DEFEATED_MAUVILLE_GYM":1266,"FLAG_DEFEATED_METEOR_FALLS_STEVEN":1272,"FLAG_DEFEATED_MEW":455,"FLAG_DEFEATED_MOSSDEEP_GYM":1270,"FLAG_DEFEATED_PETALBURG_GYM":1268,"FLAG_DEFEATED_RAYQUAZA":448,"FLAG_DEFEATED_REGICE":444,"FLAG_DEFEATED_REGIROCK":443,"FLAG_DEFEATED_REGISTEEL":445,"FLAG_DEFEATED_RIVAL_ROUTE103":130,"FLAG_DEFEATED_RIVAL_ROUTE_104":125,"FLAG_DEFEATED_RIVAL_RUSTBORO":211,"FLAG_DEFEATED_RUSTBORO_GYM":1264,"FLAG_DEFEATED_SEASHORE_HOUSE":141,"FLAG_DEFEATED_SOOTOPOLIS_GYM":1271,"FLAG_DEFEATED_SS_TIDAL_TRAINERS":247,"FLAG_DEFEATED_SUDOWOODO":454,"FLAG_DEFEATED_VOLTORB_1_NEW_MAUVILLE":449,"FLAG_DEFEATED_VOLTORB_2_NEW_MAUVILLE":450,"FLAG_DEFEATED_VOLTORB_3_NEW_MAUVILLE":451,"FLAG_DEFEATED_WALLY_MAUVILLE":190,"FLAG_DEFEATED_WALLY_VICTORY_ROAD":126,"FLAG_DELIVERED_DEVON_GOODS":149,"FLAG_DELIVERED_STEVEN_LETTER":189,"FLAG_DEOXYS_IS_RECOVERING":1258,"FLAG_DEOXYS_ROCK_COMPLETE":2260,"FLAG_DEVON_GOODS_STOLEN":142,"FLAG_DOCK_REJECTED_DEVON_GOODS":148,"FLAG_DONT_TRANSITION_MUSIC":16385,"FLAG_ENABLE_BRAWLY_MATCH_CALL":468,"FLAG_ENABLE_FIRST_WALLY_POKENAV_CALL":136,"FLAG_ENABLE_FLANNERY_MATCH_CALL":470,"FLAG_ENABLE_JUAN_MATCH_CALL":473,"FLAG_ENABLE_MOM_MATCH_CALL":216,"FLAG_ENABLE_MR_STONE_POKENAV":344,"FLAG_ENABLE_MULTI_CORRIDOR_DOOR":16386,"FLAG_ENABLE_NORMAN_MATCH_CALL":306,"FLAG_ENABLE_PROF_BIRCH_MATCH_CALL":281,"FLAG_ENABLE_RIVAL_MATCH_CALL":253,"FLAG_ENABLE_ROXANNE_FIRST_CALL":128,"FLAG_ENABLE_ROXANNE_MATCH_CALL":467,"FLAG_ENABLE_SCOTT_MATCH_CALL":215,"FLAG_ENABLE_SHIP_BIRTH_ISLAND":2261,"FLAG_ENABLE_SHIP_FARAWAY_ISLAND":2262,"FLAG_ENABLE_SHIP_NAVEL_ROCK":2272,"FLAG_ENABLE_SHIP_SOUTHERN_ISLAND":2227,"FLAG_ENABLE_TATE_AND_LIZA_MATCH_CALL":472,"FLAG_ENABLE_WALLY_MATCH_CALL":214,"FLAG_ENABLE_WATTSON_MATCH_CALL":469,"FLAG_ENABLE_WINONA_MATCH_CALL":471,"FLAG_ENTERED_CONTEST":341,"FLAG_ENTERED_ELITE_FOUR":263,"FLAG_ENTERED_MIRAGE_TOWER":2268,"FLAG_EVIL_LEADER_PLEASE_STOP":219,"FLAG_EVIL_TEAM_ESCAPED_STERN_SPOKE":271,"FLAG_EXCHANGED_SCANNER":294,"FLAG_FAN_CLUB_STRENGTH_SHARED":210,"FLAG_FLOWER_SHOP_RECEIVED_BERRY":1207,"FLAG_FORCE_MIRAGE_TOWER_VISIBLE":157,"FLAG_FORTREE_NPC_TRADE_COMPLETED":155,"FLAG_GOOD_LUCK_SAFARI_ZONE":93,"FLAG_GOT_BASEMENT_KEY_FROM_WATTSON":208,"FLAG_GOT_TM_THUNDERBOLT_FROM_WATTSON":209,"FLAG_GROUDON_AWAKENED_MAGMA_HIDEOUT":111,"FLAG_GROUDON_IS_RECOVERING":1274,"FLAG_HAS_MATCH_CALL":303,"FLAG_HIDDEN_ITEMS_START":500,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":531,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":532,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":533,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":534,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":601,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":604,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":603,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":602,"FLAG_HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":528,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":548,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":549,"FLAG_HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":577,"FLAG_HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":576,"FLAG_HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":500,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":527,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":575,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":543,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":578,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":529,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":580,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":579,"FLAG_HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":609,"FLAG_HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":595,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":561,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POTION":558,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":559,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":560,"FLAG_HIDDEN_ITEM_ROUTE_104_ANTIDOTE":585,"FLAG_HIDDEN_ITEM_ROUTE_104_HEART_SCALE":588,"FLAG_HIDDEN_ITEM_ROUTE_104_POKE_BALL":562,"FLAG_HIDDEN_ITEM_ROUTE_104_POTION":537,"FLAG_HIDDEN_ITEM_ROUTE_104_SUPER_POTION":544,"FLAG_HIDDEN_ITEM_ROUTE_105_BIG_PEARL":611,"FLAG_HIDDEN_ITEM_ROUTE_105_HEART_SCALE":589,"FLAG_HIDDEN_ITEM_ROUTE_106_HEART_SCALE":547,"FLAG_HIDDEN_ITEM_ROUTE_106_POKE_BALL":563,"FLAG_HIDDEN_ITEM_ROUTE_106_STARDUST":546,"FLAG_HIDDEN_ITEM_ROUTE_108_RARE_CANDY":586,"FLAG_HIDDEN_ITEM_ROUTE_109_ETHER":564,"FLAG_HIDDEN_ITEM_ROUTE_109_GREAT_BALL":551,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":552,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":590,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":591,"FLAG_HIDDEN_ITEM_ROUTE_109_REVIVE":550,"FLAG_HIDDEN_ITEM_ROUTE_110_FULL_HEAL":555,"FLAG_HIDDEN_ITEM_ROUTE_110_GREAT_BALL":553,"FLAG_HIDDEN_ITEM_ROUTE_110_POKE_BALL":565,"FLAG_HIDDEN_ITEM_ROUTE_110_REVIVE":554,"FLAG_HIDDEN_ITEM_ROUTE_111_PROTEIN":556,"FLAG_HIDDEN_ITEM_ROUTE_111_RARE_CANDY":557,"FLAG_HIDDEN_ITEM_ROUTE_111_STARDUST":502,"FLAG_HIDDEN_ITEM_ROUTE_113_ETHER":503,"FLAG_HIDDEN_ITEM_ROUTE_113_NUGGET":598,"FLAG_HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":530,"FLAG_HIDDEN_ITEM_ROUTE_114_CARBOS":504,"FLAG_HIDDEN_ITEM_ROUTE_114_REVIVE":542,"FLAG_HIDDEN_ITEM_ROUTE_115_HEART_SCALE":597,"FLAG_HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":596,"FLAG_HIDDEN_ITEM_ROUTE_116_SUPER_POTION":545,"FLAG_HIDDEN_ITEM_ROUTE_117_REPEL":572,"FLAG_HIDDEN_ITEM_ROUTE_118_HEART_SCALE":566,"FLAG_HIDDEN_ITEM_ROUTE_118_IRON":567,"FLAG_HIDDEN_ITEM_ROUTE_119_CALCIUM":505,"FLAG_HIDDEN_ITEM_ROUTE_119_FULL_HEAL":568,"FLAG_HIDDEN_ITEM_ROUTE_119_MAX_ETHER":587,"FLAG_HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":506,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":571,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":569,"FLAG_HIDDEN_ITEM_ROUTE_120_REVIVE":584,"FLAG_HIDDEN_ITEM_ROUTE_120_ZINC":570,"FLAG_HIDDEN_ITEM_ROUTE_121_FULL_HEAL":573,"FLAG_HIDDEN_ITEM_ROUTE_121_HP_UP":539,"FLAG_HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":600,"FLAG_HIDDEN_ITEM_ROUTE_121_NUGGET":540,"FLAG_HIDDEN_ITEM_ROUTE_123_HYPER_POTION":574,"FLAG_HIDDEN_ITEM_ROUTE_123_PP_UP":599,"FLAG_HIDDEN_ITEM_ROUTE_123_RARE_CANDY":610,"FLAG_HIDDEN_ITEM_ROUTE_123_REVIVE":541,"FLAG_HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":507,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":592,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":593,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":594,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":606,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":607,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":605,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":608,"FLAG_HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":535,"FLAG_HIDDEN_ITEM_TRICK_HOUSE_NUGGET":501,"FLAG_HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":511,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CALCIUM":536,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CARBOS":508,"FLAG_HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":509,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":513,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":538,"FLAG_HIDDEN_ITEM_UNDERWATER_124_PEARL":510,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":520,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":512,"FLAG_HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":514,"FLAG_HIDDEN_ITEM_UNDERWATER_126_IRON":519,"FLAG_HIDDEN_ITEM_UNDERWATER_126_PEARL":517,"FLAG_HIDDEN_ITEM_UNDERWATER_126_STARDUST":516,"FLAG_HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":515,"FLAG_HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":518,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":523,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HP_UP":522,"FLAG_HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":524,"FLAG_HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":521,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PEARL":526,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PROTEIN":525,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":581,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":582,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":583,"FLAG_HIDE_APPRENTICE":701,"FLAG_HIDE_AQUA_HIDEOUT_1F_GRUNTS_BLOCKING_ENTRANCE":821,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_1":977,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_2":978,"FLAG_HIDE_AQUA_HIDEOUT_B2F_SUBMARINE_SHADOW":943,"FLAG_HIDE_AQUA_HIDEOUT_GRUNTS":924,"FLAG_HIDE_BATTLE_FRONTIER_RECEPTION_GATE_SCOTT":836,"FLAG_HIDE_BATTLE_FRONTIER_SUDOWOODO":842,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_1":711,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_2":712,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_3":713,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_4":714,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_5":715,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_6":716,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_1":864,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_2":865,"FLAG_HIDE_BATTLE_TOWER_OPPONENT":888,"FLAG_HIDE_BATTLE_TOWER_REPORTER":918,"FLAG_HIDE_BIRTH_ISLAND_DEOXYS_TRIANGLE":764,"FLAG_HIDE_BRINEYS_HOUSE_MR_BRINEY":739,"FLAG_HIDE_BRINEYS_HOUSE_PEEKO":881,"FLAG_HIDE_CAVE_OF_ORIGIN_B1F_WALLACE":820,"FLAG_HIDE_CHAMPIONS_ROOM_BIRCH":921,"FLAG_HIDE_CHAMPIONS_ROOM_RIVAL":920,"FLAG_HIDE_CONTEST_POKE_BALL":86,"FLAG_HIDE_DEOXYS":763,"FLAG_HIDE_DESERT_UNDERPASS_FOSSIL":874,"FLAG_HIDE_DEWFORD_HALL_SLUDGE_BOMB_MAN":940,"FLAG_HIDE_EVER_GRANDE_POKEMON_CENTER_1F_SCOTT":793,"FLAG_HIDE_FALLARBOR_AZURILL":907,"FLAG_HIDE_FALLARBOR_HOUSE_PROF_COZMO":928,"FLAG_HIDE_FALLARBOR_TOWN_BATTLE_TENT_SCOTT":767,"FLAG_HIDE_FALLORBOR_POKEMON_CENTER_LANETTE":871,"FLAG_HIDE_FANCLUB_BOY":790,"FLAG_HIDE_FANCLUB_LADY":792,"FLAG_HIDE_FANCLUB_LITTLE_BOY":791,"FLAG_HIDE_FANCLUB_OLD_LADY":789,"FLAG_HIDE_FORTREE_CITY_HOUSE_4_WINGULL":933,"FLAG_HIDE_FORTREE_CITY_KECLEON":969,"FLAG_HIDE_GRANITE_CAVE_STEVEN":833,"FLAG_HIDE_HO_OH":801,"FLAG_HIDE_JAGGED_PASS_MAGMA_GUARD":847,"FLAG_HIDE_LANETTES_HOUSE_LANETTE":870,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL":929,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL_ON_BIKE":930,"FLAG_HIDE_LILYCOVE_CITY_AQUA_GRUNTS":852,"FLAG_HIDE_LILYCOVE_CITY_RIVAL":971,"FLAG_HIDE_LILYCOVE_CITY_WAILMER":729,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER":832,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER_REPLACEMENT":873,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_1":774,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_2":895,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_REPORTER":802,"FLAG_HIDE_LILYCOVE_DEPARTMENT_STORE_ROOFTOP_SALE_WOMAN":962,"FLAG_HIDE_LILYCOVE_FAN_CLUB_INTERVIEWER":730,"FLAG_HIDE_LILYCOVE_HARBOR_EVENT_TICKET_TAKER":748,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_ATTENDANT":908,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_SAILOR":909,"FLAG_HIDE_LILYCOVE_HARBOR_SSTIDAL":861,"FLAG_HIDE_LILYCOVE_MOTEL_GAME_DESIGNERS":925,"FLAG_HIDE_LILYCOVE_MOTEL_SCOTT":787,"FLAG_HIDE_LILYCOVE_MUSEUM_CURATOR":775,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_1":776,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_2":777,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_3":778,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_4":779,"FLAG_HIDE_LILYCOVE_MUSEUM_TOURISTS":780,"FLAG_HIDE_LILYCOVE_POKEMON_CENTER_CONTEST_LADY_MON":993,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCH":795,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_BIRCH":721,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CHIKORITA":838,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CYNDAQUIL":811,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_TOTODILE":812,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_RIVAL":889,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_UNKNOWN_0x380":896,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_POKE_BALL":817,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_SWABLU_DOLL":815,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_BRENDAN":745,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_MOM":758,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_BEDROOM":760,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_MOM":784,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_SIBLING":735,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_TRUCK":761,"FLAG_HIDE_LITTLEROOT_TOWN_FAT_MAN":868,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_PICHU_DOLL":849,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_POKE_BALL":818,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MAY":746,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MOM":759,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_BEDROOM":722,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_MOM":785,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_SIBLING":736,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_TRUCK":762,"FLAG_HIDE_LITTLEROOT_TOWN_MOM_OUTSIDE":752,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_BEDROOM_MOM":757,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_1":754,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_2":755,"FLAG_HIDE_LITTLEROOT_TOWN_RIVAL":794,"FLAG_HIDE_LUGIA":800,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON":853,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON_ASLEEP":850,"FLAG_HIDE_MAGMA_HIDEOUT_GRUNTS":857,"FLAG_HIDE_MAGMA_HIDEOUT_MAXIE":867,"FLAG_HIDE_MAP_NAME_POPUP":16384,"FLAG_HIDE_MARINE_CAVE_KYOGRE":782,"FLAG_HIDE_MAUVILLE_CITY_SCOTT":765,"FLAG_HIDE_MAUVILLE_CITY_WALLY":804,"FLAG_HIDE_MAUVILLE_CITY_WALLYS_UNCLE":805,"FLAG_HIDE_MAUVILLE_CITY_WATTSON":912,"FLAG_HIDE_MAUVILLE_GYM_WATTSON":913,"FLAG_HIDE_METEOR_FALLS_1F_1R_COZMO":942,"FLAG_HIDE_METEOR_FALLS_TEAM_AQUA":938,"FLAG_HIDE_METEOR_FALLS_TEAM_MAGMA":939,"FLAG_HIDE_MEW":718,"FLAG_HIDE_MIRAGE_TOWER_CLAW_FOSSIL":964,"FLAG_HIDE_MIRAGE_TOWER_ROOT_FOSSIL":963,"FLAG_HIDE_MOSSDEEP_CITY_HOUSE_2_WINGULL":934,"FLAG_HIDE_MOSSDEEP_CITY_SCOTT":788,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_STEVEN":753,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_TEAM_MAGMA":756,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_STEVEN":863,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_TEAM_MAGMA":862,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_MAGMA_NOTE":737,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_BELDUM_POKEBALL":968,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_INVISIBLE_NINJA_BOY":727,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_STEVEN":967,"FLAG_HIDE_MOSSDEEP_CITY_TEAM_MAGMA":823,"FLAG_HIDE_MR_BRINEY_BOAT_DEWFORD_TOWN":743,"FLAG_HIDE_MR_BRINEY_DEWFORD_TOWN":740,"FLAG_HIDE_MT_CHIMNEY_LAVA_COOKIE_LADY":994,"FLAG_HIDE_MT_CHIMNEY_TEAM_AQUA":926,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA":927,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA_BATTLEABLE":981,"FLAG_HIDE_MT_CHIMNEY_TRAINERS":877,"FLAG_HIDE_MT_PYRE_SUMMIT_ARCHIE":916,"FLAG_HIDE_MT_PYRE_SUMMIT_MAXIE":856,"FLAG_HIDE_MT_PYRE_SUMMIT_TEAM_AQUA":917,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_1":974,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_2":975,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_3":976,"FLAG_HIDE_OLDALE_TOWN_RIVAL":979,"FLAG_HIDE_PETALBURG_CITY_SCOTT":995,"FLAG_HIDE_PETALBURG_CITY_WALLY":726,"FLAG_HIDE_PETALBURG_CITY_WALLYS_DAD":830,"FLAG_HIDE_PETALBURG_CITY_WALLYS_MOM":728,"FLAG_HIDE_PETALBURG_GYM_GREETER":781,"FLAG_HIDE_PETALBURG_GYM_NORMAN":772,"FLAG_HIDE_PETALBURG_GYM_WALLY":866,"FLAG_HIDE_PETALBURG_GYM_WALLYS_DAD":824,"FLAG_HIDE_PETALBURG_WOODS_AQUA_GRUNT":725,"FLAG_HIDE_PETALBURG_WOODS_DEVON_EMPLOYEE":724,"FLAG_HIDE_PLAYERS_HOUSE_DAD":734,"FLAG_HIDE_POKEMON_CENTER_2F_MYSTERY_GIFT_MAN":702,"FLAG_HIDE_REGICE":936,"FLAG_HIDE_REGIROCK":935,"FLAG_HIDE_REGISTEEL":937,"FLAG_HIDE_ROUTE_101_BIRCH":897,"FLAG_HIDE_ROUTE_101_BIRCH_STARTERS_BAG":700,"FLAG_HIDE_ROUTE_101_BIRCH_ZIGZAGOON_BATTLE":720,"FLAG_HIDE_ROUTE_101_BOY":991,"FLAG_HIDE_ROUTE_101_ZIGZAGOON":750,"FLAG_HIDE_ROUTE_103_BIRCH":898,"FLAG_HIDE_ROUTE_103_RIVAL":723,"FLAG_HIDE_ROUTE_104_MR_BRINEY":738,"FLAG_HIDE_ROUTE_104_MR_BRINEY_BOAT":742,"FLAG_HIDE_ROUTE_104_RIVAL":719,"FLAG_HIDE_ROUTE_104_WHITE_HERB_FLORIST":906,"FLAG_HIDE_ROUTE_109_MR_BRINEY":741,"FLAG_HIDE_ROUTE_109_MR_BRINEY_BOAT":744,"FLAG_HIDE_ROUTE_110_BIRCH":837,"FLAG_HIDE_ROUTE_110_RIVAL":919,"FLAG_HIDE_ROUTE_110_RIVAL_ON_BIKE":922,"FLAG_HIDE_ROUTE_110_TEAM_AQUA":900,"FLAG_HIDE_ROUTE_111_DESERT_FOSSIL":876,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_1":796,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_2":903,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_3":799,"FLAG_HIDE_ROUTE_111_PLAYER_DESCENT":875,"FLAG_HIDE_ROUTE_111_ROCK_SMASH_TIP_GUY":843,"FLAG_HIDE_ROUTE_111_SECRET_POWER_MAN":960,"FLAG_HIDE_ROUTE_111_VICKY_WINSTRATE":771,"FLAG_HIDE_ROUTE_111_VICTORIA_WINSTRATE":769,"FLAG_HIDE_ROUTE_111_VICTOR_WINSTRATE":768,"FLAG_HIDE_ROUTE_111_VIVI_WINSTRATE":770,"FLAG_HIDE_ROUTE_112_TEAM_MAGMA":819,"FLAG_HIDE_ROUTE_115_BOULDERS":825,"FLAG_HIDE_ROUTE_116_DEVON_EMPLOYEE":947,"FLAG_HIDE_ROUTE_116_DROPPED_GLASSES_MAN":813,"FLAG_HIDE_ROUTE_116_MR_BRINEY":891,"FLAG_HIDE_ROUTE_116_WANDAS_BOYFRIEND":894,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_1":797,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_2":901,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_3":904,"FLAG_HIDE_ROUTE_118_STEVEN":966,"FLAG_HIDE_ROUTE_119_RIVAL":851,"FLAG_HIDE_ROUTE_119_RIVAL_ON_BIKE":923,"FLAG_HIDE_ROUTE_119_SCOTT":786,"FLAG_HIDE_ROUTE_119_TEAM_AQUA":890,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_BRIDGE":822,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_SHELLY":915,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_1":798,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_2":902,"FLAG_HIDE_ROUTE_120_STEVEN":972,"FLAG_HIDE_ROUTE_121_TEAM_AQUA_GRUNTS":914,"FLAG_HIDE_ROUTE_128_ARCHIE":944,"FLAG_HIDE_ROUTE_128_MAXIE":945,"FLAG_HIDE_ROUTE_128_STEVEN":834,"FLAG_HIDE_RUSTBORO_CITY_AQUA_GRUNT":731,"FLAG_HIDE_RUSTBORO_CITY_DEVON_CORP_3F_EMPLOYEE":949,"FLAG_HIDE_RUSTBORO_CITY_DEVON_EMPLOYEE_1":732,"FLAG_HIDE_RUSTBORO_CITY_POKEMON_SCHOOL_SCOTT":999,"FLAG_HIDE_RUSTBORO_CITY_RIVAL":814,"FLAG_HIDE_RUSTBORO_CITY_SCIENTIST":844,"FLAG_HIDE_RUSTURF_TUNNEL_AQUA_GRUNT":878,"FLAG_HIDE_RUSTURF_TUNNEL_BRINEY":879,"FLAG_HIDE_RUSTURF_TUNNEL_PEEKO":880,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_1":931,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_2":932,"FLAG_HIDE_RUSTURF_TUNNEL_WANDA":983,"FLAG_HIDE_RUSTURF_TUNNEL_WANDAS_BOYFRIEND":807,"FLAG_HIDE_SAFARI_ZONE_SOUTH_CONSTRUCTION_WORKERS":717,"FLAG_HIDE_SAFARI_ZONE_SOUTH_EAST_EXPANSION":747,"FLAG_HIDE_SEAFLOOR_CAVERN_AQUA_GRUNTS":946,"FLAG_HIDE_SEAFLOOR_CAVERN_ENTRANCE_AQUA_GRUNT":941,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_ARCHIE":828,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE":859,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE_ASLEEP":733,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAGMA_GRUNTS":831,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAXIE":829,"FLAG_HIDE_SECRET_BASE_TRAINER":173,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA":773,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA_STILL":80,"FLAG_HIDE_SKY_PILLAR_WALLACE":855,"FLAG_HIDE_SLATEPORT_CITY_CAPTAIN_STERN":840,"FLAG_HIDE_SLATEPORT_CITY_CONTEST_REPORTER":803,"FLAG_HIDE_SLATEPORT_CITY_GABBY_AND_TY":835,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_AQUA_GRUNT":845,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_ARCHIE":846,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_CAPTAIN_STERN":841,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_PATRONS":905,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SS_TIDAL":860,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SUBMARINE_SHADOW":848,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_1":884,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_2":885,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_ARCHIE":886,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_CAPTAIN_STERN":887,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_AQUA_GRUNTS":883,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_FAMILIAR_AQUA_GRUNT":965,"FLAG_HIDE_SLATEPORT_CITY_SCOTT":749,"FLAG_HIDE_SLATEPORT_CITY_STERNS_SHIPYARD_MR_BRINEY":869,"FLAG_HIDE_SLATEPORT_CITY_TEAM_AQUA":882,"FLAG_HIDE_SLATEPORT_CITY_TM_SALESMAN":948,"FLAG_HIDE_SLATEPORT_MUSEUM_POPULATION":961,"FLAG_HIDE_SOOTOPOLIS_CITY_ARCHIE":826,"FLAG_HIDE_SOOTOPOLIS_CITY_GROUDON":998,"FLAG_HIDE_SOOTOPOLIS_CITY_KYOGRE":997,"FLAG_HIDE_SOOTOPOLIS_CITY_MAN_1":839,"FLAG_HIDE_SOOTOPOLIS_CITY_MAXIE":827,"FLAG_HIDE_SOOTOPOLIS_CITY_RAYQUAZA":996,"FLAG_HIDE_SOOTOPOLIS_CITY_RESIDENTS":854,"FLAG_HIDE_SOOTOPOLIS_CITY_STEVEN":973,"FLAG_HIDE_SOOTOPOLIS_CITY_WALLACE":816,"FLAG_HIDE_SOUTHERN_ISLAND_EON_STONE":910,"FLAG_HIDE_SOUTHERN_ISLAND_UNCHOSEN_EON_DUO_MON":911,"FLAG_HIDE_SS_TIDAL_CORRIDOR_MR_BRINEY":950,"FLAG_HIDE_SS_TIDAL_CORRIDOR_SCOTT":810,"FLAG_HIDE_SS_TIDAL_ROOMS_SNATCH_GIVER":951,"FLAG_HIDE_TERRA_CAVE_GROUDON":783,"FLAG_HIDE_TRICK_HOUSE_END_MAN":899,"FLAG_HIDE_TRICK_HOUSE_ENTRANCE_MAN":872,"FLAG_HIDE_UNDERWATER_SEA_FLOOR_CAVERN_STOLEN_SUBMARINE":980,"FLAG_HIDE_UNION_ROOM_PLAYER_1":703,"FLAG_HIDE_UNION_ROOM_PLAYER_2":704,"FLAG_HIDE_UNION_ROOM_PLAYER_3":705,"FLAG_HIDE_UNION_ROOM_PLAYER_4":706,"FLAG_HIDE_UNION_ROOM_PLAYER_5":707,"FLAG_HIDE_UNION_ROOM_PLAYER_6":708,"FLAG_HIDE_UNION_ROOM_PLAYER_7":709,"FLAG_HIDE_UNION_ROOM_PLAYER_8":710,"FLAG_HIDE_VERDANTURF_TOWN_SCOTT":766,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLY":806,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLYS_UNCLE":809,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDA":984,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDAS_BOYFRIEND":808,"FLAG_HIDE_VICTORY_ROAD_ENTRANCE_WALLY":858,"FLAG_HIDE_VICTORY_ROAD_EXIT_WALLY":751,"FLAG_HIDE_WEATHER_INSTITUTE_1F_WORKERS":892,"FLAG_HIDE_WEATHER_INSTITUTE_2F_AQUA_GRUNT_M":992,"FLAG_HIDE_WEATHER_INSTITUTE_2F_WORKERS":893,"FLAG_HO_OH_IS_RECOVERING":1256,"FLAG_INTERACTED_WITH_DEVON_EMPLOYEE_GOODS_STOLEN":159,"FLAG_INTERACTED_WITH_STEVEN_SPACE_CENTER":205,"FLAG_IS_CHAMPION":2175,"FLAG_ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":1100,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":1102,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":1078,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":1101,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":1077,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":1095,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":1099,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":1097,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":1096,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":1098,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":1124,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":1071,"FLAG_ITEM_AQUA_HIDEOUT_B1F_NUGGET":1132,"FLAG_ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":1072,"FLAG_ITEM_ARTISAN_CAVE_1F_CARBOS":1163,"FLAG_ITEM_ARTISAN_CAVE_B1F_HP_UP":1162,"FLAG_ITEM_FIERY_PATH_FIRE_STONE":1111,"FLAG_ITEM_FIERY_PATH_TM_TOXIC":1091,"FLAG_ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":1050,"FLAG_ITEM_GRANITE_CAVE_B1F_POKE_BALL":1051,"FLAG_ITEM_GRANITE_CAVE_B2F_RARE_CANDY":1054,"FLAG_ITEM_GRANITE_CAVE_B2F_REPEL":1053,"FLAG_ITEM_JAGGED_PASS_BURN_HEAL":1070,"FLAG_ITEM_LILYCOVE_CITY_MAX_REPEL":1042,"FLAG_ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":1151,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":1165,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":1164,"FLAG_ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":1166,"FLAG_ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":1167,"FLAG_ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":1059,"FLAG_ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":1168,"FLAG_ITEM_MAUVILLE_CITY_X_SPEED":1116,"FLAG_ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":1045,"FLAG_ITEM_METEOR_FALLS_1F_1R_MOON_STONE":1046,"FLAG_ITEM_METEOR_FALLS_1F_1R_PP_UP":1047,"FLAG_ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":1044,"FLAG_ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":1080,"FLAG_ITEM_MOSSDEEP_CITY_NET_BALL":1043,"FLAG_ITEM_MOSSDEEP_STEVENS_HOUSE_HM08":1133,"FLAG_ITEM_MT_PYRE_2F_ULTRA_BALL":1129,"FLAG_ITEM_MT_PYRE_3F_SUPER_REPEL":1120,"FLAG_ITEM_MT_PYRE_4F_SEA_INCENSE":1130,"FLAG_ITEM_MT_PYRE_5F_LAX_INCENSE":1052,"FLAG_ITEM_MT_PYRE_6F_TM_SHADOW_BALL":1089,"FLAG_ITEM_MT_PYRE_EXTERIOR_MAX_POTION":1073,"FLAG_ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":1074,"FLAG_ITEM_NEW_MAUVILLE_ESCAPE_ROPE":1076,"FLAG_ITEM_NEW_MAUVILLE_FULL_HEAL":1122,"FLAG_ITEM_NEW_MAUVILLE_PARALYZE_HEAL":1123,"FLAG_ITEM_NEW_MAUVILLE_THUNDER_STONE":1110,"FLAG_ITEM_NEW_MAUVILLE_ULTRA_BALL":1075,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MASTER_BALL":1125,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MAX_ELIXIR":1126,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B2F_NEST_BALL":1127,"FLAG_ITEM_PETALBURG_CITY_ETHER":1040,"FLAG_ITEM_PETALBURG_CITY_MAX_REVIVE":1039,"FLAG_ITEM_PETALBURG_WOODS_ETHER":1058,"FLAG_ITEM_PETALBURG_WOODS_GREAT_BALL":1056,"FLAG_ITEM_PETALBURG_WOODS_PARALYZE_HEAL":1117,"FLAG_ITEM_PETALBURG_WOODS_X_ATTACK":1055,"FLAG_ITEM_ROUTE_102_POTION":1000,"FLAG_ITEM_ROUTE_103_GUARD_SPEC":1114,"FLAG_ITEM_ROUTE_103_PP_UP":1137,"FLAG_ITEM_ROUTE_104_POKE_BALL":1057,"FLAG_ITEM_ROUTE_104_POTION":1135,"FLAG_ITEM_ROUTE_104_PP_UP":1002,"FLAG_ITEM_ROUTE_104_X_ACCURACY":1115,"FLAG_ITEM_ROUTE_105_IRON":1003,"FLAG_ITEM_ROUTE_106_PROTEIN":1004,"FLAG_ITEM_ROUTE_108_STAR_PIECE":1139,"FLAG_ITEM_ROUTE_109_POTION":1140,"FLAG_ITEM_ROUTE_109_PP_UP":1005,"FLAG_ITEM_ROUTE_110_DIRE_HIT":1007,"FLAG_ITEM_ROUTE_110_ELIXIR":1141,"FLAG_ITEM_ROUTE_110_RARE_CANDY":1006,"FLAG_ITEM_ROUTE_111_ELIXIR":1142,"FLAG_ITEM_ROUTE_111_HP_UP":1010,"FLAG_ITEM_ROUTE_111_STARDUST":1009,"FLAG_ITEM_ROUTE_111_TM_SANDSTORM":1008,"FLAG_ITEM_ROUTE_112_NUGGET":1011,"FLAG_ITEM_ROUTE_113_HYPER_POTION":1143,"FLAG_ITEM_ROUTE_113_MAX_ETHER":1012,"FLAG_ITEM_ROUTE_113_SUPER_REPEL":1013,"FLAG_ITEM_ROUTE_114_ENERGY_POWDER":1160,"FLAG_ITEM_ROUTE_114_PROTEIN":1015,"FLAG_ITEM_ROUTE_114_RARE_CANDY":1014,"FLAG_ITEM_ROUTE_115_GREAT_BALL":1118,"FLAG_ITEM_ROUTE_115_HEAL_POWDER":1144,"FLAG_ITEM_ROUTE_115_IRON":1018,"FLAG_ITEM_ROUTE_115_PP_UP":1161,"FLAG_ITEM_ROUTE_115_SUPER_POTION":1016,"FLAG_ITEM_ROUTE_115_TM_FOCUS_PUNCH":1017,"FLAG_ITEM_ROUTE_116_ETHER":1019,"FLAG_ITEM_ROUTE_116_HP_UP":1021,"FLAG_ITEM_ROUTE_116_POTION":1146,"FLAG_ITEM_ROUTE_116_REPEL":1020,"FLAG_ITEM_ROUTE_116_X_SPECIAL":1001,"FLAG_ITEM_ROUTE_117_GREAT_BALL":1022,"FLAG_ITEM_ROUTE_117_REVIVE":1023,"FLAG_ITEM_ROUTE_118_HYPER_POTION":1121,"FLAG_ITEM_ROUTE_119_ELIXIR_1":1026,"FLAG_ITEM_ROUTE_119_ELIXIR_2":1147,"FLAG_ITEM_ROUTE_119_HYPER_POTION_1":1029,"FLAG_ITEM_ROUTE_119_HYPER_POTION_2":1106,"FLAG_ITEM_ROUTE_119_LEAF_STONE":1027,"FLAG_ITEM_ROUTE_119_NUGGET":1134,"FLAG_ITEM_ROUTE_119_RARE_CANDY":1028,"FLAG_ITEM_ROUTE_119_SUPER_REPEL":1024,"FLAG_ITEM_ROUTE_119_ZINC":1025,"FLAG_ITEM_ROUTE_120_FULL_HEAL":1031,"FLAG_ITEM_ROUTE_120_HYPER_POTION":1107,"FLAG_ITEM_ROUTE_120_NEST_BALL":1108,"FLAG_ITEM_ROUTE_120_NUGGET":1030,"FLAG_ITEM_ROUTE_120_REVIVE":1148,"FLAG_ITEM_ROUTE_121_CARBOS":1103,"FLAG_ITEM_ROUTE_121_REVIVE":1149,"FLAG_ITEM_ROUTE_121_ZINC":1150,"FLAG_ITEM_ROUTE_123_CALCIUM":1032,"FLAG_ITEM_ROUTE_123_ELIXIR":1109,"FLAG_ITEM_ROUTE_123_PP_UP":1152,"FLAG_ITEM_ROUTE_123_REVIVAL_HERB":1153,"FLAG_ITEM_ROUTE_123_ULTRA_BALL":1104,"FLAG_ITEM_ROUTE_124_BLUE_SHARD":1093,"FLAG_ITEM_ROUTE_124_RED_SHARD":1092,"FLAG_ITEM_ROUTE_124_YELLOW_SHARD":1066,"FLAG_ITEM_ROUTE_125_BIG_PEARL":1154,"FLAG_ITEM_ROUTE_126_GREEN_SHARD":1105,"FLAG_ITEM_ROUTE_127_CARBOS":1035,"FLAG_ITEM_ROUTE_127_RARE_CANDY":1155,"FLAG_ITEM_ROUTE_127_ZINC":1034,"FLAG_ITEM_ROUTE_132_PROTEIN":1156,"FLAG_ITEM_ROUTE_132_RARE_CANDY":1036,"FLAG_ITEM_ROUTE_133_BIG_PEARL":1037,"FLAG_ITEM_ROUTE_133_MAX_REVIVE":1157,"FLAG_ITEM_ROUTE_133_STAR_PIECE":1038,"FLAG_ITEM_ROUTE_134_CARBOS":1158,"FLAG_ITEM_ROUTE_134_STAR_PIECE":1159,"FLAG_ITEM_RUSTBORO_CITY_X_DEFEND":1041,"FLAG_ITEM_RUSTURF_TUNNEL_MAX_ETHER":1049,"FLAG_ITEM_RUSTURF_TUNNEL_POKE_BALL":1048,"FLAG_ITEM_SAFARI_ZONE_NORTH_CALCIUM":1119,"FLAG_ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":1169,"FLAG_ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":1094,"FLAG_ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":1170,"FLAG_ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":1131,"FLAG_ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":1079,"FLAG_ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":1090,"FLAG_ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":1081,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":1113,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":1112,"FLAG_ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":1082,"FLAG_ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":1083,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":1060,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":1061,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":1062,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":1063,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":1064,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":1065,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":1067,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":1068,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":1069,"FLAG_ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":1084,"FLAG_ITEM_VICTORY_ROAD_1F_PP_UP":1085,"FLAG_ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":1087,"FLAG_ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":1086,"FLAG_ITEM_VICTORY_ROAD_B2F_FULL_HEAL":1088,"FLAG_KECLEON_FLED_FORTREE":295,"FLAG_KYOGRE_ESCAPED_SEAFLOOR_CAVERN":129,"FLAG_KYOGRE_IS_RECOVERING":1273,"FLAG_LANDMARK_ABANDONED_SHIP":2206,"FLAG_LANDMARK_ALTERING_CAVE":2269,"FLAG_LANDMARK_ANCIENT_TOMB":2233,"FLAG_LANDMARK_ARTISAN_CAVE":2271,"FLAG_LANDMARK_BATTLE_FRONTIER":2216,"FLAG_LANDMARK_BERRY_MASTERS_HOUSE":2243,"FLAG_LANDMARK_DESERT_RUINS":2230,"FLAG_LANDMARK_DESERT_UNDERPASS":2270,"FLAG_LANDMARK_FIERY_PATH":2218,"FLAG_LANDMARK_FLOWER_SHOP":2204,"FLAG_LANDMARK_FOSSIL_MANIACS_HOUSE":2231,"FLAG_LANDMARK_GLASS_WORKSHOP":2212,"FLAG_LANDMARK_HUNTERS_HOUSE":2235,"FLAG_LANDMARK_ISLAND_CAVE":2229,"FLAG_LANDMARK_LANETTES_HOUSE":2213,"FLAG_LANDMARK_MIRAGE_TOWER":120,"FLAG_LANDMARK_MR_BRINEY_HOUSE":2205,"FLAG_LANDMARK_NEW_MAUVILLE":2208,"FLAG_LANDMARK_OLD_LADY_REST_SHOP":2209,"FLAG_LANDMARK_POKEMON_DAYCARE":2214,"FLAG_LANDMARK_POKEMON_LEAGUE":2228,"FLAG_LANDMARK_SCORCHED_SLAB":2232,"FLAG_LANDMARK_SEAFLOOR_CAVERN":2215,"FLAG_LANDMARK_SEALED_CHAMBER":2236,"FLAG_LANDMARK_SEASHORE_HOUSE":2207,"FLAG_LANDMARK_SKY_PILLAR":2238,"FLAG_LANDMARK_SOUTHERN_ISLAND":2217,"FLAG_LANDMARK_TRAINER_HILL":2274,"FLAG_LANDMARK_TRICK_HOUSE":2210,"FLAG_LANDMARK_TUNNELERS_REST_HOUSE":2234,"FLAG_LANDMARK_WINSTRATE_FAMILY":2211,"FLAG_LATIAS_IS_RECOVERING":1263,"FLAG_LATIOS_IS_RECOVERING":1255,"FLAG_LATIOS_OR_LATIAS_ROAMING":255,"FLAG_LEGENDARIES_IN_SOOTOPOLIS":83,"FLAG_LILYCOVE_RECEIVED_BERRY":1208,"FLAG_LUGIA_IS_RECOVERING":1257,"FLAG_MAP_SCRIPT_CHECKED_DEOXYS":2259,"FLAG_MATCH_CALL_REGISTERED":348,"FLAG_MAUVILLE_GYM_BARRIERS_STATE":99,"FLAG_MET_ARCHIE_METEOR_FALLS":207,"FLAG_MET_ARCHIE_SOOTOPOLIS":308,"FLAG_MET_BATTLE_FRONTIER_BREEDER":339,"FLAG_MET_BATTLE_FRONTIER_GAMBLER":343,"FLAG_MET_BATTLE_FRONTIER_MANIAC":340,"FLAG_MET_DEVON_EMPLOYEE":287,"FLAG_MET_DIVING_TREASURE_HUNTER":217,"FLAG_MET_FANCLUB_YOUNGER_BROTHER":300,"FLAG_MET_FRONTIER_BEAUTY_MOVE_TUTOR":346,"FLAG_MET_FRONTIER_SWIMMER_MOVE_TUTOR":347,"FLAG_MET_HIDDEN_POWER_GIVER":118,"FLAG_MET_MAXIE_SOOTOPOLIS":309,"FLAG_MET_PRETTY_PETAL_SHOP_OWNER":127,"FLAG_MET_PROF_COZMO":244,"FLAG_MET_RIVAL_IN_HOUSE_AFTER_LILYCOVE":293,"FLAG_MET_RIVAL_LILYCOVE":292,"FLAG_MET_RIVAL_MOM":87,"FLAG_MET_RIVAL_RUSTBORO":288,"FLAG_MET_SCOTT_AFTER_OBTAINING_STONE_BADGE":459,"FLAG_MET_SCOTT_IN_EVERGRANDE":463,"FLAG_MET_SCOTT_IN_FALLARBOR":461,"FLAG_MET_SCOTT_IN_LILYCOVE":462,"FLAG_MET_SCOTT_IN_VERDANTURF":460,"FLAG_MET_SCOTT_ON_SS_TIDAL":464,"FLAG_MET_SCOTT_RUSTBORO":310,"FLAG_MET_SLATEPORT_FANCLUB_CHAIRMAN":342,"FLAG_MET_TEAM_AQUA_HARBOR":97,"FLAG_MET_WAILMER_TRAINER":218,"FLAG_MEW_IS_RECOVERING":1259,"FLAG_MIRAGE_TOWER_VISIBLE":334,"FLAG_MOSSDEEP_GYM_SWITCH_1":100,"FLAG_MOSSDEEP_GYM_SWITCH_2":101,"FLAG_MOSSDEEP_GYM_SWITCH_3":102,"FLAG_MOSSDEEP_GYM_SWITCH_4":103,"FLAG_MOVE_TUTOR_TAUGHT_DOUBLE_EDGE":441,"FLAG_MOVE_TUTOR_TAUGHT_DYNAMICPUNCH":440,"FLAG_MOVE_TUTOR_TAUGHT_EXPLOSION":442,"FLAG_MOVE_TUTOR_TAUGHT_FURY_CUTTER":435,"FLAG_MOVE_TUTOR_TAUGHT_METRONOME":437,"FLAG_MOVE_TUTOR_TAUGHT_MIMIC":436,"FLAG_MOVE_TUTOR_TAUGHT_ROLLOUT":434,"FLAG_MOVE_TUTOR_TAUGHT_SLEEP_TALK":438,"FLAG_MOVE_TUTOR_TAUGHT_SUBSTITUTE":439,"FLAG_MOVE_TUTOR_TAUGHT_SWAGGER":433,"FLAG_MR_BRINEY_SAILING_INTRO":147,"FLAG_MYSTERY_GIFT_1":485,"FLAG_MYSTERY_GIFT_10":494,"FLAG_MYSTERY_GIFT_11":495,"FLAG_MYSTERY_GIFT_12":496,"FLAG_MYSTERY_GIFT_13":497,"FLAG_MYSTERY_GIFT_14":498,"FLAG_MYSTERY_GIFT_15":499,"FLAG_MYSTERY_GIFT_2":486,"FLAG_MYSTERY_GIFT_3":487,"FLAG_MYSTERY_GIFT_4":488,"FLAG_MYSTERY_GIFT_5":489,"FLAG_MYSTERY_GIFT_6":490,"FLAG_MYSTERY_GIFT_7":491,"FLAG_MYSTERY_GIFT_8":492,"FLAG_MYSTERY_GIFT_9":493,"FLAG_MYSTERY_GIFT_DONE":484,"FLAG_NEVER_SET_0x0DC":220,"FLAG_NOT_READY_FOR_BATTLE_ROUTE_120":290,"FLAG_NURSE_MENTIONS_GOLD_CARD":345,"FLAG_NURSE_UNION_ROOM_REMINDER":2176,"FLAG_OCEANIC_MUSEUM_MET_REPORTER":105,"FLAG_OMIT_DIVE_FROM_STEVEN_LETTER":302,"FLAG_PACIFIDLOG_NPC_TRADE_COMPLETED":154,"FLAG_PENDING_DAYCARE_EGG":134,"FLAG_PETALBURG_MART_EXPANDED_ITEMS":296,"FLAG_POKERUS_EXPLAINED":273,"FLAG_PURCHASED_HARBOR_MAIL":104,"FLAG_RAYQUAZA_IS_RECOVERING":1279,"FLAG_RECEIVED_20_COINS":225,"FLAG_RECEIVED_6_SODA_POP":140,"FLAG_RECEIVED_ACRO_BIKE":1181,"FLAG_RECEIVED_AMULET_COIN":133,"FLAG_RECEIVED_AURORA_TICKET":314,"FLAG_RECEIVED_BADGE_1":1182,"FLAG_RECEIVED_BADGE_2":1183,"FLAG_RECEIVED_BADGE_3":1184,"FLAG_RECEIVED_BADGE_4":1185,"FLAG_RECEIVED_BADGE_5":1186,"FLAG_RECEIVED_BADGE_6":1187,"FLAG_RECEIVED_BADGE_7":1188,"FLAG_RECEIVED_BADGE_8":1189,"FLAG_RECEIVED_BELDUM":298,"FLAG_RECEIVED_BELUE_BERRY":252,"FLAG_RECEIVED_BIKE":90,"FLAG_RECEIVED_BLUE_SCARF":201,"FLAG_RECEIVED_CASTFORM":151,"FLAG_RECEIVED_CHARCOAL":254,"FLAG_RECEIVED_CHESTO_BERRY_ROUTE_104":246,"FLAG_RECEIVED_CLEANSE_TAG":282,"FLAG_RECEIVED_COIN_CASE":258,"FLAG_RECEIVED_CONTEST_PASS":150,"FLAG_RECEIVED_DEEP_SEA_SCALE":1190,"FLAG_RECEIVED_DEEP_SEA_TOOTH":1191,"FLAG_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":1172,"FLAG_RECEIVED_DEVON_SCOPE":285,"FLAG_RECEIVED_DOLL_LANETTE":131,"FLAG_RECEIVED_DURIN_BERRY":251,"FLAG_RECEIVED_EON_TICKET":474,"FLAG_RECEIVED_EXP_SHARE":272,"FLAG_RECEIVED_FANCLUB_TM_THIS_WEEK":299,"FLAG_RECEIVED_FIRST_POKEBALLS":233,"FLAG_RECEIVED_FOCUS_BAND":283,"FLAG_RECEIVED_GLASS_ORNAMENT":236,"FLAG_RECEIVED_GOLD_SHIELD":238,"FLAG_RECEIVED_GOOD_ROD":227,"FLAG_RECEIVED_GO_GOGGLES":221,"FLAG_RECEIVED_GREAT_BALL_PETALBURG_WOODS":1171,"FLAG_RECEIVED_GREAT_BALL_RUSTBORO_CITY":1173,"FLAG_RECEIVED_GREEN_SCARF":203,"FLAG_RECEIVED_HM_CUT":137,"FLAG_RECEIVED_HM_DIVE":123,"FLAG_RECEIVED_HM_FLASH":109,"FLAG_RECEIVED_HM_FLY":110,"FLAG_RECEIVED_HM_ROCK_SMASH":107,"FLAG_RECEIVED_HM_STRENGTH":106,"FLAG_RECEIVED_HM_SURF":122,"FLAG_RECEIVED_HM_WATERFALL":312,"FLAG_RECEIVED_ITEMFINDER":1176,"FLAG_RECEIVED_KINGS_ROCK":276,"FLAG_RECEIVED_LAVARIDGE_EGG":266,"FLAG_RECEIVED_LETTER":1174,"FLAG_RECEIVED_MACHO_BRACE":277,"FLAG_RECEIVED_MACH_BIKE":1180,"FLAG_RECEIVED_MAGMA_EMBLEM":1177,"FLAG_RECEIVED_MENTAL_HERB":223,"FLAG_RECEIVED_METEORITE":115,"FLAG_RECEIVED_MIRACLE_SEED":297,"FLAG_RECEIVED_MYSTIC_TICKET":315,"FLAG_RECEIVED_OLD_ROD":257,"FLAG_RECEIVED_OLD_SEA_MAP":316,"FLAG_RECEIVED_PAMTRE_BERRY":249,"FLAG_RECEIVED_PINK_SCARF":202,"FLAG_RECEIVED_POKEBLOCK_CASE":95,"FLAG_RECEIVED_POKEDEX_FROM_BIRCH":2276,"FLAG_RECEIVED_POKENAV":188,"FLAG_RECEIVED_POTION_OLDALE":132,"FLAG_RECEIVED_POWDER_JAR":337,"FLAG_RECEIVED_PREMIER_BALL_RUSTBORO":213,"FLAG_RECEIVED_QUICK_CLAW":275,"FLAG_RECEIVED_RED_OR_BLUE_ORB":212,"FLAG_RECEIVED_RED_SCARF":200,"FLAG_RECEIVED_REPEAT_BALL":256,"FLAG_RECEIVED_REVIVED_FOSSIL_MON":267,"FLAG_RECEIVED_RUNNING_SHOES":274,"FLAG_RECEIVED_SECRET_POWER":96,"FLAG_RECEIVED_SHOAL_SALT_1":952,"FLAG_RECEIVED_SHOAL_SALT_2":953,"FLAG_RECEIVED_SHOAL_SALT_3":954,"FLAG_RECEIVED_SHOAL_SALT_4":955,"FLAG_RECEIVED_SHOAL_SHELL_1":956,"FLAG_RECEIVED_SHOAL_SHELL_2":957,"FLAG_RECEIVED_SHOAL_SHELL_3":958,"FLAG_RECEIVED_SHOAL_SHELL_4":959,"FLAG_RECEIVED_SILK_SCARF":289,"FLAG_RECEIVED_SILVER_SHIELD":237,"FLAG_RECEIVED_SOFT_SAND":280,"FLAG_RECEIVED_SOOTHE_BELL":278,"FLAG_RECEIVED_SOOT_SACK":1033,"FLAG_RECEIVED_SPECIAL_PHRASE_HINT":85,"FLAG_RECEIVED_SPELON_BERRY":248,"FLAG_RECEIVED_SS_TICKET":291,"FLAG_RECEIVED_STARTER_DOLL":226,"FLAG_RECEIVED_SUN_STONE_MOSSDEEP":192,"FLAG_RECEIVED_SUPER_ROD":152,"FLAG_RECEIVED_TM_AERIAL_ACE":170,"FLAG_RECEIVED_TM_ATTRACT":235,"FLAG_RECEIVED_TM_BRICK_BREAK":121,"FLAG_RECEIVED_TM_BULK_UP":166,"FLAG_RECEIVED_TM_BULLET_SEED":262,"FLAG_RECEIVED_TM_CALM_MIND":171,"FLAG_RECEIVED_TM_DIG":261,"FLAG_RECEIVED_TM_FACADE":169,"FLAG_RECEIVED_TM_FRUSTRATION":1179,"FLAG_RECEIVED_TM_GIGA_DRAIN":232,"FLAG_RECEIVED_TM_HIDDEN_POWER":264,"FLAG_RECEIVED_TM_OVERHEAT":168,"FLAG_RECEIVED_TM_REST":234,"FLAG_RECEIVED_TM_RETURN":229,"FLAG_RECEIVED_TM_RETURN_2":1178,"FLAG_RECEIVED_TM_ROAR":231,"FLAG_RECEIVED_TM_ROCK_TOMB":165,"FLAG_RECEIVED_TM_SHOCK_WAVE":167,"FLAG_RECEIVED_TM_SLUDGE_BOMB":230,"FLAG_RECEIVED_TM_SNATCH":260,"FLAG_RECEIVED_TM_STEEL_WING":1175,"FLAG_RECEIVED_TM_THIEF":269,"FLAG_RECEIVED_TM_TORMENT":265,"FLAG_RECEIVED_TM_WATER_PULSE":172,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_1":1200,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_2":1201,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_3":1202,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_4":1203,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_5":1204,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_6":1205,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_7":1206,"FLAG_RECEIVED_WAILMER_DOLL":245,"FLAG_RECEIVED_WAILMER_PAIL":94,"FLAG_RECEIVED_WATMEL_BERRY":250,"FLAG_RECEIVED_WHITE_HERB":279,"FLAG_RECEIVED_YELLOW_SCARF":204,"FLAG_RECOVERED_DEVON_GOODS":143,"FLAG_REGICE_IS_RECOVERING":1260,"FLAG_REGIROCK_IS_RECOVERING":1261,"FLAG_REGISTEEL_IS_RECOVERING":1262,"FLAG_REGISTERED_STEVEN_POKENAV":305,"FLAG_REGISTER_RIVAL_POKENAV":124,"FLAG_REGI_DOORS_OPENED":228,"FLAG_REMATCH_ABIGAIL":387,"FLAG_REMATCH_AMY_AND_LIV":399,"FLAG_REMATCH_ANDRES":350,"FLAG_REMATCH_ANNA_AND_MEG":378,"FLAG_REMATCH_BENJAMIN":390,"FLAG_REMATCH_BERNIE":369,"FLAG_REMATCH_BRAWLY":415,"FLAG_REMATCH_BROOKE":356,"FLAG_REMATCH_CALVIN":383,"FLAG_REMATCH_CAMERON":373,"FLAG_REMATCH_CATHERINE":406,"FLAG_REMATCH_CINDY":359,"FLAG_REMATCH_CORY":401,"FLAG_REMATCH_CRISTIN":355,"FLAG_REMATCH_CYNDY":395,"FLAG_REMATCH_DALTON":368,"FLAG_REMATCH_DIANA":398,"FLAG_REMATCH_DRAKE":424,"FLAG_REMATCH_DUSTY":351,"FLAG_REMATCH_DYLAN":388,"FLAG_REMATCH_EDWIN":402,"FLAG_REMATCH_ELLIOT":384,"FLAG_REMATCH_ERNEST":400,"FLAG_REMATCH_ETHAN":370,"FLAG_REMATCH_FERNANDO":367,"FLAG_REMATCH_FLANNERY":417,"FLAG_REMATCH_GABRIELLE":405,"FLAG_REMATCH_GLACIA":423,"FLAG_REMATCH_HALEY":408,"FLAG_REMATCH_ISAAC":404,"FLAG_REMATCH_ISABEL":379,"FLAG_REMATCH_ISAIAH":385,"FLAG_REMATCH_JACKI":374,"FLAG_REMATCH_JACKSON":407,"FLAG_REMATCH_JAMES":409,"FLAG_REMATCH_JEFFREY":372,"FLAG_REMATCH_JENNY":397,"FLAG_REMATCH_JERRY":377,"FLAG_REMATCH_JESSICA":361,"FLAG_REMATCH_JOHN_AND_JAY":371,"FLAG_REMATCH_KAREN":376,"FLAG_REMATCH_KATELYN":389,"FLAG_REMATCH_KIRA_AND_DAN":412,"FLAG_REMATCH_KOJI":366,"FLAG_REMATCH_LAO":394,"FLAG_REMATCH_LILA_AND_ROY":354,"FLAG_REMATCH_LOLA":352,"FLAG_REMATCH_LYDIA":403,"FLAG_REMATCH_MADELINE":396,"FLAG_REMATCH_MARIA":386,"FLAG_REMATCH_MIGUEL":380,"FLAG_REMATCH_NICOLAS":392,"FLAG_REMATCH_NOB":365,"FLAG_REMATCH_NORMAN":418,"FLAG_REMATCH_PABLO":391,"FLAG_REMATCH_PHOEBE":422,"FLAG_REMATCH_RICKY":353,"FLAG_REMATCH_ROBERT":393,"FLAG_REMATCH_ROSE":349,"FLAG_REMATCH_ROXANNE":414,"FLAG_REMATCH_SAWYER":411,"FLAG_REMATCH_SHELBY":382,"FLAG_REMATCH_SIDNEY":421,"FLAG_REMATCH_STEVE":363,"FLAG_REMATCH_TATE_AND_LIZA":420,"FLAG_REMATCH_THALIA":360,"FLAG_REMATCH_TIMOTHY":381,"FLAG_REMATCH_TONY":364,"FLAG_REMATCH_TRENT":410,"FLAG_REMATCH_VALERIE":358,"FLAG_REMATCH_WALLACE":425,"FLAG_REMATCH_WALLY":413,"FLAG_REMATCH_WALTER":375,"FLAG_REMATCH_WATTSON":416,"FLAG_REMATCH_WILTON":357,"FLAG_REMATCH_WINONA":419,"FLAG_REMATCH_WINSTON":362,"FLAG_RESCUED_BIRCH":82,"FLAG_RETURNED_DEVON_GOODS":144,"FLAG_RETURNED_RED_OR_BLUE_ORB":259,"FLAG_RIVAL_LEFT_FOR_ROUTE103":301,"FLAG_ROUTE_111_RECEIVED_BERRY":1192,"FLAG_ROUTE_114_RECEIVED_BERRY":1193,"FLAG_ROUTE_120_RECEIVED_BERRY":1194,"FLAG_RUSTBORO_NPC_TRADE_COMPLETED":153,"FLAG_RUSTURF_TUNNEL_OPENED":199,"FLAG_SCOTT_CALL_BATTLE_FRONTIER":114,"FLAG_SCOTT_CALL_FORTREE_GYM":138,"FLAG_SCOTT_GIVES_BATTLE_POINTS":465,"FLAG_SECRET_BASE_REGISTRY_ENABLED":268,"FLAG_SET_WALL_CLOCK":81,"FLAG_SHOWN_AURORA_TICKET":431,"FLAG_SHOWN_BOX_WAS_FULL_MESSAGE":2263,"FLAG_SHOWN_EON_TICKET":430,"FLAG_SHOWN_MYSTIC_TICKET":475,"FLAG_SHOWN_OLD_SEA_MAP":432,"FLAG_SMART_PAINTING_MADE":163,"FLAG_SOOTOPOLIS_ARCHIE_MAXIE_LEAVE":158,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_1":1198,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_2":1199,"FLAG_SPECIAL_FLAG_UNUSED_0x4003":16387,"FLAG_SS_TIDAL_DISABLED":84,"FLAG_STEVEN_GUIDES_TO_CAVE_OF_ORIGIN":307,"FLAG_STORING_ITEMS_IN_PYRAMID_BAG":16388,"FLAG_SYS_ARENA_GOLD":2251,"FLAG_SYS_ARENA_SILVER":2250,"FLAG_SYS_BRAILLE_DIG":2223,"FLAG_SYS_BRAILLE_REGICE_COMPLETED":2225,"FLAG_SYS_B_DASH":2240,"FLAG_SYS_CAVE_BATTLE":2201,"FLAG_SYS_CAVE_SHIP":2199,"FLAG_SYS_CAVE_WONDER":2200,"FLAG_SYS_CHANGED_DEWFORD_TREND":2195,"FLAG_SYS_CHAT_USED":2149,"FLAG_SYS_CLOCK_SET":2197,"FLAG_SYS_CRUISE_MODE":2189,"FLAG_SYS_CTRL_OBJ_DELETE":2241,"FLAG_SYS_CYCLING_ROAD":2187,"FLAG_SYS_DOME_GOLD":2247,"FLAG_SYS_DOME_SILVER":2246,"FLAG_SYS_ENC_DOWN_ITEM":2222,"FLAG_SYS_ENC_UP_ITEM":2221,"FLAG_SYS_FACTORY_GOLD":2253,"FLAG_SYS_FACTORY_SILVER":2252,"FLAG_SYS_FRONTIER_PASS":2258,"FLAG_SYS_GAME_CLEAR":2148,"FLAG_SYS_MIX_RECORD":2196,"FLAG_SYS_MYSTERY_EVENT_ENABLE":2220,"FLAG_SYS_MYSTERY_GIFT_ENABLE":2267,"FLAG_SYS_NATIONAL_DEX":2198,"FLAG_SYS_PALACE_GOLD":2249,"FLAG_SYS_PALACE_SILVER":2248,"FLAG_SYS_PC_LANETTE":2219,"FLAG_SYS_PIKE_GOLD":2255,"FLAG_SYS_PIKE_SILVER":2254,"FLAG_SYS_POKEDEX_GET":2145,"FLAG_SYS_POKEMON_GET":2144,"FLAG_SYS_POKENAV_GET":2146,"FLAG_SYS_PYRAMID_GOLD":2257,"FLAG_SYS_PYRAMID_SILVER":2256,"FLAG_SYS_REGIROCK_PUZZLE_COMPLETED":2224,"FLAG_SYS_REGISTEEL_PUZZLE_COMPLETED":2226,"FLAG_SYS_RESET_RTC_ENABLE":2242,"FLAG_SYS_RIBBON_GET":2203,"FLAG_SYS_SAFARI_MODE":2188,"FLAG_SYS_SHOAL_ITEM":2239,"FLAG_SYS_SHOAL_TIDE":2202,"FLAG_SYS_TOWER_GOLD":2245,"FLAG_SYS_TOWER_SILVER":2244,"FLAG_SYS_TV_HOME":2192,"FLAG_SYS_TV_LATIAS_LATIOS":2237,"FLAG_SYS_TV_START":2194,"FLAG_SYS_TV_WATCH":2193,"FLAG_SYS_USE_FLASH":2184,"FLAG_SYS_USE_STRENGTH":2185,"FLAG_SYS_WEATHER_CTRL":2186,"FLAG_TEAM_AQUA_ESCAPED_IN_SUBMARINE":112,"FLAG_TEMP_1":1,"FLAG_TEMP_10":16,"FLAG_TEMP_11":17,"FLAG_TEMP_12":18,"FLAG_TEMP_13":19,"FLAG_TEMP_14":20,"FLAG_TEMP_15":21,"FLAG_TEMP_16":22,"FLAG_TEMP_17":23,"FLAG_TEMP_18":24,"FLAG_TEMP_19":25,"FLAG_TEMP_1A":26,"FLAG_TEMP_1B":27,"FLAG_TEMP_1C":28,"FLAG_TEMP_1D":29,"FLAG_TEMP_1E":30,"FLAG_TEMP_1F":31,"FLAG_TEMP_2":2,"FLAG_TEMP_3":3,"FLAG_TEMP_4":4,"FLAG_TEMP_5":5,"FLAG_TEMP_6":6,"FLAG_TEMP_7":7,"FLAG_TEMP_8":8,"FLAG_TEMP_9":9,"FLAG_TEMP_A":10,"FLAG_TEMP_B":11,"FLAG_TEMP_C":12,"FLAG_TEMP_D":13,"FLAG_TEMP_E":14,"FLAG_TEMP_F":15,"FLAG_TEMP_HIDE_MIRAGE_ISLAND_BERRY_TREE":17,"FLAG_TEMP_REGICE_PUZZLE_FAILED":3,"FLAG_TEMP_REGICE_PUZZLE_STARTED":2,"FLAG_TEMP_SKIP_GABBY_INTERVIEW":1,"FLAG_THANKED_FOR_PLAYING_WITH_WALLY":135,"FLAG_TOUGH_PAINTING_MADE":164,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_1":194,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_2":195,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_3":196,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_4":197,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_5":198,"FLAG_TV_EXPLAINED":98,"FLAG_UNLOCKED_TRENDY_SAYINGS":2150,"FLAG_USED_ROOM_1_KEY":240,"FLAG_USED_ROOM_2_KEY":241,"FLAG_USED_ROOM_4_KEY":242,"FLAG_USED_ROOM_6_KEY":243,"FLAG_USED_STORAGE_KEY":239,"FLAG_VISITED_DEWFORD_TOWN":2161,"FLAG_VISITED_EVER_GRANDE_CITY":2174,"FLAG_VISITED_FALLARBOR_TOWN":2163,"FLAG_VISITED_FORTREE_CITY":2170,"FLAG_VISITED_LAVARIDGE_TOWN":2162,"FLAG_VISITED_LILYCOVE_CITY":2171,"FLAG_VISITED_LITTLEROOT_TOWN":2159,"FLAG_VISITED_MAUVILLE_CITY":2168,"FLAG_VISITED_MOSSDEEP_CITY":2172,"FLAG_VISITED_OLDALE_TOWN":2160,"FLAG_VISITED_PACIFIDLOG_TOWN":2165,"FLAG_VISITED_PETALBURG_CITY":2166,"FLAG_VISITED_RUSTBORO_CITY":2169,"FLAG_VISITED_SLATEPORT_CITY":2167,"FLAG_VISITED_SOOTOPOLIS_CITY":2173,"FLAG_VISITED_VERDANTURF_TOWN":2164,"FLAG_WALLACE_GOES_TO_SKY_PILLAR":311,"FLAG_WALLY_SPEECH":193,"FLAG_WATTSON_REMATCH_AVAILABLE":91,"FLAG_WHITEOUT_TO_LAVARIDGE":108,"FLAG_WINGULL_DELIVERED_MAIL":224,"FLAG_WINGULL_SENT_ON_ERRAND":222,"FLAG_WONDER_CARD_UNUSED_1":317,"FLAG_WONDER_CARD_UNUSED_10":326,"FLAG_WONDER_CARD_UNUSED_11":327,"FLAG_WONDER_CARD_UNUSED_12":328,"FLAG_WONDER_CARD_UNUSED_13":329,"FLAG_WONDER_CARD_UNUSED_14":330,"FLAG_WONDER_CARD_UNUSED_15":331,"FLAG_WONDER_CARD_UNUSED_16":332,"FLAG_WONDER_CARD_UNUSED_17":333,"FLAG_WONDER_CARD_UNUSED_2":318,"FLAG_WONDER_CARD_UNUSED_3":319,"FLAG_WONDER_CARD_UNUSED_4":320,"FLAG_WONDER_CARD_UNUSED_5":321,"FLAG_WONDER_CARD_UNUSED_6":322,"FLAG_WONDER_CARD_UNUSED_7":323,"FLAG_WONDER_CARD_UNUSED_8":324,"FLAG_WONDER_CARD_UNUSED_9":325,"FLAVOR_BITTER":3,"FLAVOR_COUNT":5,"FLAVOR_DRY":1,"FLAVOR_SOUR":4,"FLAVOR_SPICY":0,"FLAVOR_SWEET":2,"GOOD_ROD":1,"ITEMS_COUNT":377,"ITEM_034":52,"ITEM_035":53,"ITEM_036":54,"ITEM_037":55,"ITEM_038":56,"ITEM_039":57,"ITEM_03A":58,"ITEM_03B":59,"ITEM_03C":60,"ITEM_03D":61,"ITEM_03E":62,"ITEM_048":72,"ITEM_052":82,"ITEM_057":87,"ITEM_058":88,"ITEM_059":89,"ITEM_05A":90,"ITEM_05B":91,"ITEM_05C":92,"ITEM_063":99,"ITEM_064":100,"ITEM_065":101,"ITEM_066":102,"ITEM_069":105,"ITEM_071":113,"ITEM_072":114,"ITEM_073":115,"ITEM_074":116,"ITEM_075":117,"ITEM_076":118,"ITEM_077":119,"ITEM_078":120,"ITEM_0EA":234,"ITEM_0EB":235,"ITEM_0EC":236,"ITEM_0ED":237,"ITEM_0EE":238,"ITEM_0EF":239,"ITEM_0F0":240,"ITEM_0F1":241,"ITEM_0F2":242,"ITEM_0F3":243,"ITEM_0F4":244,"ITEM_0F5":245,"ITEM_0F6":246,"ITEM_0F7":247,"ITEM_0F8":248,"ITEM_0F9":249,"ITEM_0FA":250,"ITEM_0FB":251,"ITEM_0FC":252,"ITEM_0FD":253,"ITEM_10B":267,"ITEM_15B":347,"ITEM_15C":348,"ITEM_ACRO_BIKE":272,"ITEM_AGUAV_BERRY":146,"ITEM_AMULET_COIN":189,"ITEM_ANTIDOTE":14,"ITEM_APICOT_BERRY":172,"ITEM_ARCHIPELAGO_PROGRESSION":112,"ITEM_ASPEAR_BERRY":137,"ITEM_AURORA_TICKET":371,"ITEM_AWAKENING":17,"ITEM_BADGE_1":226,"ITEM_BADGE_2":227,"ITEM_BADGE_3":228,"ITEM_BADGE_4":229,"ITEM_BADGE_5":230,"ITEM_BADGE_6":231,"ITEM_BADGE_7":232,"ITEM_BADGE_8":233,"ITEM_BASEMENT_KEY":271,"ITEM_BEAD_MAIL":127,"ITEM_BELUE_BERRY":167,"ITEM_BERRY_JUICE":44,"ITEM_BERRY_POUCH":365,"ITEM_BICYCLE":360,"ITEM_BIG_MUSHROOM":104,"ITEM_BIG_PEARL":107,"ITEM_BIKE_VOUCHER":352,"ITEM_BLACK_BELT":207,"ITEM_BLACK_FLUTE":42,"ITEM_BLACK_GLASSES":206,"ITEM_BLUE_FLUTE":39,"ITEM_BLUE_ORB":277,"ITEM_BLUE_SCARF":255,"ITEM_BLUE_SHARD":49,"ITEM_BLUK_BERRY":149,"ITEM_BRIGHT_POWDER":179,"ITEM_BURN_HEAL":15,"ITEM_B_USE_MEDICINE":1,"ITEM_B_USE_OTHER":2,"ITEM_CALCIUM":67,"ITEM_CARBOS":66,"ITEM_CARD_KEY":355,"ITEM_CHARCOAL":215,"ITEM_CHERI_BERRY":133,"ITEM_CHESTO_BERRY":134,"ITEM_CHOICE_BAND":186,"ITEM_CLAW_FOSSIL":287,"ITEM_CLEANSE_TAG":190,"ITEM_COIN_CASE":260,"ITEM_CONTEST_PASS":266,"ITEM_CORNN_BERRY":159,"ITEM_DEEP_SEA_SCALE":193,"ITEM_DEEP_SEA_TOOTH":192,"ITEM_DEVON_GOODS":269,"ITEM_DEVON_SCOPE":288,"ITEM_DIRE_HIT":74,"ITEM_DIVE_BALL":7,"ITEM_DOME_FOSSIL":358,"ITEM_DRAGON_FANG":216,"ITEM_DRAGON_SCALE":201,"ITEM_DREAM_MAIL":130,"ITEM_DURIN_BERRY":166,"ITEM_ELIXIR":36,"ITEM_ENERGY_POWDER":30,"ITEM_ENERGY_ROOT":31,"ITEM_ENIGMA_BERRY":175,"ITEM_EON_TICKET":275,"ITEM_ESCAPE_ROPE":85,"ITEM_ETHER":34,"ITEM_EVERSTONE":195,"ITEM_EXP_SHARE":182,"ITEM_FAB_MAIL":131,"ITEM_FAME_CHECKER":363,"ITEM_FIGY_BERRY":143,"ITEM_FIRE_STONE":95,"ITEM_FLUFFY_TAIL":81,"ITEM_FOCUS_BAND":196,"ITEM_FRESH_WATER":26,"ITEM_FULL_HEAL":23,"ITEM_FULL_RESTORE":19,"ITEM_GANLON_BERRY":169,"ITEM_GLITTER_MAIL":123,"ITEM_GOLD_TEETH":353,"ITEM_GOOD_ROD":263,"ITEM_GO_GOGGLES":279,"ITEM_GREAT_BALL":3,"ITEM_GREEN_SCARF":257,"ITEM_GREEN_SHARD":51,"ITEM_GREPA_BERRY":157,"ITEM_GUARD_SPEC":73,"ITEM_HARBOR_MAIL":122,"ITEM_HARD_STONE":204,"ITEM_HEAL_POWDER":32,"ITEM_HEART_SCALE":111,"ITEM_HELIX_FOSSIL":357,"ITEM_HM01":339,"ITEM_HM02":340,"ITEM_HM03":341,"ITEM_HM04":342,"ITEM_HM05":343,"ITEM_HM06":344,"ITEM_HM07":345,"ITEM_HM08":346,"ITEM_HM_CUT":339,"ITEM_HM_DIVE":346,"ITEM_HM_FLASH":343,"ITEM_HM_FLY":340,"ITEM_HM_ROCK_SMASH":344,"ITEM_HM_STRENGTH":342,"ITEM_HM_SURF":341,"ITEM_HM_WATERFALL":345,"ITEM_HONDEW_BERRY":156,"ITEM_HP_UP":63,"ITEM_HYPER_POTION":21,"ITEM_IAPAPA_BERRY":147,"ITEM_ICE_HEAL":16,"ITEM_IRON":65,"ITEM_ITEMFINDER":261,"ITEM_KELPSY_BERRY":154,"ITEM_KINGS_ROCK":187,"ITEM_LANSAT_BERRY":173,"ITEM_LAVA_COOKIE":38,"ITEM_LAX_INCENSE":221,"ITEM_LEAF_STONE":98,"ITEM_LEFTOVERS":200,"ITEM_LEMONADE":28,"ITEM_LEPPA_BERRY":138,"ITEM_LETTER":274,"ITEM_LIECHI_BERRY":168,"ITEM_LIFT_KEY":356,"ITEM_LIGHT_BALL":202,"ITEM_LIST_END":65535,"ITEM_LUCKY_EGG":197,"ITEM_LUCKY_PUNCH":222,"ITEM_LUM_BERRY":141,"ITEM_LUXURY_BALL":11,"ITEM_MACHO_BRACE":181,"ITEM_MACH_BIKE":259,"ITEM_MAGMA_EMBLEM":375,"ITEM_MAGNET":208,"ITEM_MAGOST_BERRY":160,"ITEM_MAGO_BERRY":145,"ITEM_MASTER_BALL":1,"ITEM_MAX_ELIXIR":37,"ITEM_MAX_ETHER":35,"ITEM_MAX_POTION":20,"ITEM_MAX_REPEL":84,"ITEM_MAX_REVIVE":25,"ITEM_MECH_MAIL":124,"ITEM_MENTAL_HERB":185,"ITEM_METAL_COAT":199,"ITEM_METAL_POWDER":223,"ITEM_METEORITE":280,"ITEM_MIRACLE_SEED":205,"ITEM_MOOMOO_MILK":29,"ITEM_MOON_STONE":94,"ITEM_MYSTIC_TICKET":370,"ITEM_MYSTIC_WATER":209,"ITEM_NANAB_BERRY":150,"ITEM_NEST_BALL":8,"ITEM_NET_BALL":6,"ITEM_NEVER_MELT_ICE":212,"ITEM_NOMEL_BERRY":162,"ITEM_NONE":0,"ITEM_NUGGET":110,"ITEM_OAKS_PARCEL":349,"ITEM_OLD_AMBER":354,"ITEM_OLD_ROD":262,"ITEM_OLD_SEA_MAP":376,"ITEM_ORANGE_MAIL":121,"ITEM_ORAN_BERRY":139,"ITEM_PAMTRE_BERRY":164,"ITEM_PARALYZE_HEAL":18,"ITEM_PEARL":106,"ITEM_PECHA_BERRY":135,"ITEM_PERSIM_BERRY":140,"ITEM_PETAYA_BERRY":171,"ITEM_PINAP_BERRY":152,"ITEM_PINK_SCARF":256,"ITEM_POISON_BARB":211,"ITEM_POKEBLOCK_CASE":273,"ITEM_POKE_BALL":4,"ITEM_POKE_DOLL":80,"ITEM_POKE_FLUTE":350,"ITEM_POMEG_BERRY":153,"ITEM_POTION":13,"ITEM_POWDER_JAR":372,"ITEM_PP_MAX":71,"ITEM_PP_UP":69,"ITEM_PREMIER_BALL":12,"ITEM_PROTEIN":64,"ITEM_QUALOT_BERRY":155,"ITEM_QUICK_CLAW":183,"ITEM_RABUTA_BERRY":161,"ITEM_RAINBOW_PASS":368,"ITEM_RARE_CANDY":68,"ITEM_RAWST_BERRY":136,"ITEM_RAZZ_BERRY":148,"ITEM_RED_FLUTE":41,"ITEM_RED_ORB":276,"ITEM_RED_SCARF":254,"ITEM_RED_SHARD":48,"ITEM_REPEAT_BALL":9,"ITEM_REPEL":86,"ITEM_RETRO_MAIL":132,"ITEM_REVIVAL_HERB":33,"ITEM_REVIVE":24,"ITEM_ROOM_1_KEY":281,"ITEM_ROOM_2_KEY":282,"ITEM_ROOM_4_KEY":283,"ITEM_ROOM_6_KEY":284,"ITEM_ROOT_FOSSIL":286,"ITEM_RUBY":373,"ITEM_SACRED_ASH":45,"ITEM_SAFARI_BALL":5,"ITEM_SALAC_BERRY":170,"ITEM_SAPPHIRE":374,"ITEM_SCANNER":278,"ITEM_SCOPE_LENS":198,"ITEM_SEA_INCENSE":220,"ITEM_SECRET_KEY":351,"ITEM_SHADOW_MAIL":128,"ITEM_SHARP_BEAK":210,"ITEM_SHELL_BELL":219,"ITEM_SHOAL_SALT":46,"ITEM_SHOAL_SHELL":47,"ITEM_SILK_SCARF":217,"ITEM_SILPH_SCOPE":359,"ITEM_SILVER_POWDER":188,"ITEM_SITRUS_BERRY":142,"ITEM_SMOKE_BALL":194,"ITEM_SODA_POP":27,"ITEM_SOFT_SAND":203,"ITEM_SOOTHE_BELL":184,"ITEM_SOOT_SACK":270,"ITEM_SOUL_DEW":191,"ITEM_SPELL_TAG":213,"ITEM_SPELON_BERRY":163,"ITEM_SS_TICKET":265,"ITEM_STARDUST":108,"ITEM_STARF_BERRY":174,"ITEM_STAR_PIECE":109,"ITEM_STICK":225,"ITEM_STORAGE_KEY":285,"ITEM_SUN_STONE":93,"ITEM_SUPER_POTION":22,"ITEM_SUPER_REPEL":83,"ITEM_SUPER_ROD":264,"ITEM_TAMATO_BERRY":158,"ITEM_TEA":369,"ITEM_TEACHY_TV":366,"ITEM_THICK_CLUB":224,"ITEM_THUNDER_STONE":96,"ITEM_TIMER_BALL":10,"ITEM_TINY_MUSHROOM":103,"ITEM_TM01":289,"ITEM_TM02":290,"ITEM_TM03":291,"ITEM_TM04":292,"ITEM_TM05":293,"ITEM_TM06":294,"ITEM_TM07":295,"ITEM_TM08":296,"ITEM_TM09":297,"ITEM_TM10":298,"ITEM_TM11":299,"ITEM_TM12":300,"ITEM_TM13":301,"ITEM_TM14":302,"ITEM_TM15":303,"ITEM_TM16":304,"ITEM_TM17":305,"ITEM_TM18":306,"ITEM_TM19":307,"ITEM_TM20":308,"ITEM_TM21":309,"ITEM_TM22":310,"ITEM_TM23":311,"ITEM_TM24":312,"ITEM_TM25":313,"ITEM_TM26":314,"ITEM_TM27":315,"ITEM_TM28":316,"ITEM_TM29":317,"ITEM_TM30":318,"ITEM_TM31":319,"ITEM_TM32":320,"ITEM_TM33":321,"ITEM_TM34":322,"ITEM_TM35":323,"ITEM_TM36":324,"ITEM_TM37":325,"ITEM_TM38":326,"ITEM_TM39":327,"ITEM_TM40":328,"ITEM_TM41":329,"ITEM_TM42":330,"ITEM_TM43":331,"ITEM_TM44":332,"ITEM_TM45":333,"ITEM_TM46":334,"ITEM_TM47":335,"ITEM_TM48":336,"ITEM_TM49":337,"ITEM_TM50":338,"ITEM_TM_AERIAL_ACE":328,"ITEM_TM_ATTRACT":333,"ITEM_TM_BLIZZARD":302,"ITEM_TM_BRICK_BREAK":319,"ITEM_TM_BULK_UP":296,"ITEM_TM_BULLET_SEED":297,"ITEM_TM_CALM_MIND":292,"ITEM_TM_CASE":364,"ITEM_TM_DIG":316,"ITEM_TM_DOUBLE_TEAM":320,"ITEM_TM_DRAGON_CLAW":290,"ITEM_TM_EARTHQUAKE":314,"ITEM_TM_FACADE":330,"ITEM_TM_FIRE_BLAST":326,"ITEM_TM_FLAMETHROWER":323,"ITEM_TM_FOCUS_PUNCH":289,"ITEM_TM_FRUSTRATION":309,"ITEM_TM_GIGA_DRAIN":307,"ITEM_TM_HAIL":295,"ITEM_TM_HIDDEN_POWER":298,"ITEM_TM_HYPER_BEAM":303,"ITEM_TM_ICE_BEAM":301,"ITEM_TM_IRON_TAIL":311,"ITEM_TM_LIGHT_SCREEN":304,"ITEM_TM_OVERHEAT":338,"ITEM_TM_PROTECT":305,"ITEM_TM_PSYCHIC":317,"ITEM_TM_RAIN_DANCE":306,"ITEM_TM_REFLECT":321,"ITEM_TM_REST":332,"ITEM_TM_RETURN":315,"ITEM_TM_ROAR":293,"ITEM_TM_ROCK_TOMB":327,"ITEM_TM_SAFEGUARD":308,"ITEM_TM_SANDSTORM":325,"ITEM_TM_SECRET_POWER":331,"ITEM_TM_SHADOW_BALL":318,"ITEM_TM_SHOCK_WAVE":322,"ITEM_TM_SKILL_SWAP":336,"ITEM_TM_SLUDGE_BOMB":324,"ITEM_TM_SNATCH":337,"ITEM_TM_SOLAR_BEAM":310,"ITEM_TM_STEEL_WING":335,"ITEM_TM_SUNNY_DAY":299,"ITEM_TM_TAUNT":300,"ITEM_TM_THIEF":334,"ITEM_TM_THUNDER":313,"ITEM_TM_THUNDERBOLT":312,"ITEM_TM_TORMENT":329,"ITEM_TM_TOXIC":294,"ITEM_TM_WATER_PULSE":291,"ITEM_TOWN_MAP":361,"ITEM_TRI_PASS":367,"ITEM_TROPIC_MAIL":129,"ITEM_TWISTED_SPOON":214,"ITEM_ULTRA_BALL":2,"ITEM_UNUSED_BERRY_1":176,"ITEM_UNUSED_BERRY_2":177,"ITEM_UNUSED_BERRY_3":178,"ITEM_UP_GRADE":218,"ITEM_USE_BAG_MENU":4,"ITEM_USE_FIELD":2,"ITEM_USE_MAIL":0,"ITEM_USE_PARTY_MENU":1,"ITEM_USE_PBLOCK_CASE":3,"ITEM_VS_SEEKER":362,"ITEM_WAILMER_PAIL":268,"ITEM_WATER_STONE":97,"ITEM_WATMEL_BERRY":165,"ITEM_WAVE_MAIL":126,"ITEM_WEPEAR_BERRY":151,"ITEM_WHITE_FLUTE":43,"ITEM_WHITE_HERB":180,"ITEM_WIKI_BERRY":144,"ITEM_WOOD_MAIL":125,"ITEM_X_ACCURACY":78,"ITEM_X_ATTACK":75,"ITEM_X_DEFEND":76,"ITEM_X_SPECIAL":79,"ITEM_X_SPEED":77,"ITEM_YELLOW_FLUTE":40,"ITEM_YELLOW_SCARF":258,"ITEM_YELLOW_SHARD":50,"ITEM_ZINC":70,"LAST_BALL":12,"LAST_BERRY_INDEX":175,"LAST_BERRY_MASTER_BERRY":162,"LAST_BERRY_MASTER_WIFE_BERRY":142,"LAST_KIRI_BERRY":162,"LAST_ROUTE_114_MAN_BERRY":152,"MACH_BIKE":0,"MAIL_NONE":255,"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":6207,"MAP_ABANDONED_SHIP_CORRIDORS_1F":6199,"MAP_ABANDONED_SHIP_CORRIDORS_B1F":6201,"MAP_ABANDONED_SHIP_DECK":6198,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":6209,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":6210,"MAP_ABANDONED_SHIP_ROOMS2_1F":6206,"MAP_ABANDONED_SHIP_ROOMS2_B1F":6203,"MAP_ABANDONED_SHIP_ROOMS_1F":6200,"MAP_ABANDONED_SHIP_ROOMS_B1F":6202,"MAP_ABANDONED_SHIP_ROOM_B1F":6205,"MAP_ABANDONED_SHIP_UNDERWATER1":6204,"MAP_ABANDONED_SHIP_UNDERWATER2":6208,"MAP_ALTERING_CAVE":6250,"MAP_ANCIENT_TOMB":6212,"MAP_AQUA_HIDEOUT_1F":6167,"MAP_AQUA_HIDEOUT_B1F":6168,"MAP_AQUA_HIDEOUT_B2F":6169,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":6218,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":6219,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":6220,"MAP_ARTISAN_CAVE_1F":6244,"MAP_ARTISAN_CAVE_B1F":6243,"MAP_BATTLE_COLOSSEUM_2P":6424,"MAP_BATTLE_COLOSSEUM_4P":6427,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":6686,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":6685,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":6684,"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":6677,"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":6675,"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":6674,"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":6676,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":6689,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":6687,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":6688,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":6680,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":6679,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":6678,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":6691,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":6690,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":6694,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":6693,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":6695,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":6692,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":6682,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":6681,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":6683,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":6664,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":6663,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":6662,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":6661,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":6673,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":6672,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":6671,"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":6698,"MAP_BATTLE_FRONTIER_LOUNGE1":6697,"MAP_BATTLE_FRONTIER_LOUNGE2":6699,"MAP_BATTLE_FRONTIER_LOUNGE3":6700,"MAP_BATTLE_FRONTIER_LOUNGE4":6701,"MAP_BATTLE_FRONTIER_LOUNGE5":6703,"MAP_BATTLE_FRONTIER_LOUNGE6":6704,"MAP_BATTLE_FRONTIER_LOUNGE7":6705,"MAP_BATTLE_FRONTIER_LOUNGE8":6707,"MAP_BATTLE_FRONTIER_LOUNGE9":6708,"MAP_BATTLE_FRONTIER_MART":6711,"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":6670,"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":6660,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":6709,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":6710,"MAP_BATTLE_FRONTIER_RANKING_HALL":6696,"MAP_BATTLE_FRONTIER_RECEPTION_GATE":6706,"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":6702,"MAP_BATTLE_PYRAMID_SQUARE01":6444,"MAP_BATTLE_PYRAMID_SQUARE02":6445,"MAP_BATTLE_PYRAMID_SQUARE03":6446,"MAP_BATTLE_PYRAMID_SQUARE04":6447,"MAP_BATTLE_PYRAMID_SQUARE05":6448,"MAP_BATTLE_PYRAMID_SQUARE06":6449,"MAP_BATTLE_PYRAMID_SQUARE07":6450,"MAP_BATTLE_PYRAMID_SQUARE08":6451,"MAP_BATTLE_PYRAMID_SQUARE09":6452,"MAP_BATTLE_PYRAMID_SQUARE10":6453,"MAP_BATTLE_PYRAMID_SQUARE11":6454,"MAP_BATTLE_PYRAMID_SQUARE12":6455,"MAP_BATTLE_PYRAMID_SQUARE13":6456,"MAP_BATTLE_PYRAMID_SQUARE14":6457,"MAP_BATTLE_PYRAMID_SQUARE15":6458,"MAP_BATTLE_PYRAMID_SQUARE16":6459,"MAP_BIRTH_ISLAND_EXTERIOR":6714,"MAP_BIRTH_ISLAND_HARBOR":6715,"MAP_CAVE_OF_ORIGIN_1F":6182,"MAP_CAVE_OF_ORIGIN_B1F":6186,"MAP_CAVE_OF_ORIGIN_ENTRANCE":6181,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":6183,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":6184,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":6185,"MAP_CONTEST_HALL":6428,"MAP_CONTEST_HALL_BEAUTY":6435,"MAP_CONTEST_HALL_COOL":6437,"MAP_CONTEST_HALL_CUTE":6439,"MAP_CONTEST_HALL_SMART":6438,"MAP_CONTEST_HALL_TOUGH":6436,"MAP_DESERT_RUINS":6150,"MAP_DESERT_UNDERPASS":6242,"MAP_DEWFORD_TOWN":11,"MAP_DEWFORD_TOWN_GYM":771,"MAP_DEWFORD_TOWN_HALL":772,"MAP_DEWFORD_TOWN_HOUSE1":768,"MAP_DEWFORD_TOWN_HOUSE2":773,"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":769,"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":770,"MAP_EVER_GRANDE_CITY":8,"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":4100,"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":4099,"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":4098,"MAP_EVER_GRANDE_CITY_HALL1":4101,"MAP_EVER_GRANDE_CITY_HALL2":4102,"MAP_EVER_GRANDE_CITY_HALL3":4103,"MAP_EVER_GRANDE_CITY_HALL4":4104,"MAP_EVER_GRANDE_CITY_HALL5":4105,"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":4107,"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":4097,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":4108,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":4109,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":4106,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":4110,"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":4096,"MAP_FALLARBOR_TOWN":13,"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":1283,"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":1282,"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":1281,"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":1286,"MAP_FALLARBOR_TOWN_MART":1280,"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":1287,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":1284,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":1285,"MAP_FARAWAY_ISLAND_ENTRANCE":6712,"MAP_FARAWAY_ISLAND_INTERIOR":6713,"MAP_FIERY_PATH":6158,"MAP_FORTREE_CITY":4,"MAP_FORTREE_CITY_DECORATION_SHOP":3081,"MAP_FORTREE_CITY_GYM":3073,"MAP_FORTREE_CITY_HOUSE1":3072,"MAP_FORTREE_CITY_HOUSE2":3077,"MAP_FORTREE_CITY_HOUSE3":3078,"MAP_FORTREE_CITY_HOUSE4":3079,"MAP_FORTREE_CITY_HOUSE5":3080,"MAP_FORTREE_CITY_MART":3076,"MAP_FORTREE_CITY_POKEMON_CENTER_1F":3074,"MAP_FORTREE_CITY_POKEMON_CENTER_2F":3075,"MAP_GRANITE_CAVE_1F":6151,"MAP_GRANITE_CAVE_B1F":6152,"MAP_GRANITE_CAVE_B2F":6153,"MAP_GRANITE_CAVE_STEVENS_ROOM":6154,"MAP_GROUPS_COUNT":34,"MAP_INSIDE_OF_TRUCK":6440,"MAP_ISLAND_CAVE":6211,"MAP_JAGGED_PASS":6157,"MAP_LAVARIDGE_TOWN":12,"MAP_LAVARIDGE_TOWN_GYM_1F":1025,"MAP_LAVARIDGE_TOWN_GYM_B1F":1026,"MAP_LAVARIDGE_TOWN_HERB_SHOP":1024,"MAP_LAVARIDGE_TOWN_HOUSE":1027,"MAP_LAVARIDGE_TOWN_MART":1028,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":1029,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":1030,"MAP_LILYCOVE_CITY":5,"MAP_LILYCOVE_CITY_CONTEST_HALL":3333,"MAP_LILYCOVE_CITY_CONTEST_LOBBY":3332,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":3328,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":3329,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":3344,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":3345,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":3346,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":3347,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":3348,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":3350,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":3349,"MAP_LILYCOVE_CITY_HARBOR":3338,"MAP_LILYCOVE_CITY_HOUSE1":3340,"MAP_LILYCOVE_CITY_HOUSE2":3341,"MAP_LILYCOVE_CITY_HOUSE3":3342,"MAP_LILYCOVE_CITY_HOUSE4":3343,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":3330,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":3331,"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":3339,"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":3334,"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":3335,"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":3337,"MAP_LILYCOVE_CITY_UNUSED_MART":3336,"MAP_LITTLEROOT_TOWN":9,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":256,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":257,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":258,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":259,"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":260,"MAP_MAGMA_HIDEOUT_1F":6230,"MAP_MAGMA_HIDEOUT_2F_1R":6231,"MAP_MAGMA_HIDEOUT_2F_2R":6232,"MAP_MAGMA_HIDEOUT_2F_3R":6237,"MAP_MAGMA_HIDEOUT_3F_1R":6233,"MAP_MAGMA_HIDEOUT_3F_2R":6234,"MAP_MAGMA_HIDEOUT_3F_3R":6236,"MAP_MAGMA_HIDEOUT_4F":6235,"MAP_MARINE_CAVE_END":6247,"MAP_MARINE_CAVE_ENTRANCE":6246,"MAP_MAUVILLE_CITY":2,"MAP_MAUVILLE_CITY_BIKE_SHOP":2561,"MAP_MAUVILLE_CITY_GAME_CORNER":2563,"MAP_MAUVILLE_CITY_GYM":2560,"MAP_MAUVILLE_CITY_HOUSE1":2562,"MAP_MAUVILLE_CITY_HOUSE2":2564,"MAP_MAUVILLE_CITY_MART":2567,"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":2565,"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":2566,"MAP_METEOR_FALLS_1F_1R":6144,"MAP_METEOR_FALLS_1F_2R":6145,"MAP_METEOR_FALLS_B1F_1R":6146,"MAP_METEOR_FALLS_B1F_2R":6147,"MAP_METEOR_FALLS_STEVENS_CAVE":6251,"MAP_MIRAGE_TOWER_1F":6238,"MAP_MIRAGE_TOWER_2F":6239,"MAP_MIRAGE_TOWER_3F":6240,"MAP_MIRAGE_TOWER_4F":6241,"MAP_MOSSDEEP_CITY":6,"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":3595,"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":3596,"MAP_MOSSDEEP_CITY_GYM":3584,"MAP_MOSSDEEP_CITY_HOUSE1":3585,"MAP_MOSSDEEP_CITY_HOUSE2":3586,"MAP_MOSSDEEP_CITY_HOUSE3":3590,"MAP_MOSSDEEP_CITY_HOUSE4":3592,"MAP_MOSSDEEP_CITY_MART":3589,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":3587,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":3588,"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":3593,"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":3594,"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":3591,"MAP_MT_CHIMNEY":6156,"MAP_MT_CHIMNEY_CABLE_CAR_STATION":4865,"MAP_MT_PYRE_1F":6159,"MAP_MT_PYRE_2F":6160,"MAP_MT_PYRE_3F":6161,"MAP_MT_PYRE_4F":6162,"MAP_MT_PYRE_5F":6163,"MAP_MT_PYRE_6F":6164,"MAP_MT_PYRE_EXTERIOR":6165,"MAP_MT_PYRE_SUMMIT":6166,"MAP_NAVEL_ROCK_B1F":6725,"MAP_NAVEL_ROCK_BOTTOM":6743,"MAP_NAVEL_ROCK_DOWN01":6732,"MAP_NAVEL_ROCK_DOWN02":6733,"MAP_NAVEL_ROCK_DOWN03":6734,"MAP_NAVEL_ROCK_DOWN04":6735,"MAP_NAVEL_ROCK_DOWN05":6736,"MAP_NAVEL_ROCK_DOWN06":6737,"MAP_NAVEL_ROCK_DOWN07":6738,"MAP_NAVEL_ROCK_DOWN08":6739,"MAP_NAVEL_ROCK_DOWN09":6740,"MAP_NAVEL_ROCK_DOWN10":6741,"MAP_NAVEL_ROCK_DOWN11":6742,"MAP_NAVEL_ROCK_ENTRANCE":6724,"MAP_NAVEL_ROCK_EXTERIOR":6722,"MAP_NAVEL_ROCK_FORK":6726,"MAP_NAVEL_ROCK_HARBOR":6723,"MAP_NAVEL_ROCK_TOP":6731,"MAP_NAVEL_ROCK_UP1":6727,"MAP_NAVEL_ROCK_UP2":6728,"MAP_NAVEL_ROCK_UP3":6729,"MAP_NAVEL_ROCK_UP4":6730,"MAP_NEW_MAUVILLE_ENTRANCE":6196,"MAP_NEW_MAUVILLE_INSIDE":6197,"MAP_OLDALE_TOWN":10,"MAP_OLDALE_TOWN_HOUSE1":512,"MAP_OLDALE_TOWN_HOUSE2":513,"MAP_OLDALE_TOWN_MART":516,"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":514,"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":515,"MAP_PACIFIDLOG_TOWN":15,"MAP_PACIFIDLOG_TOWN_HOUSE1":1794,"MAP_PACIFIDLOG_TOWN_HOUSE2":1795,"MAP_PACIFIDLOG_TOWN_HOUSE3":1796,"MAP_PACIFIDLOG_TOWN_HOUSE4":1797,"MAP_PACIFIDLOG_TOWN_HOUSE5":1798,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":1792,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":1793,"MAP_PETALBURG_CITY":0,"MAP_PETALBURG_CITY_GYM":2049,"MAP_PETALBURG_CITY_HOUSE1":2050,"MAP_PETALBURG_CITY_HOUSE2":2051,"MAP_PETALBURG_CITY_MART":2054,"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":2052,"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":2053,"MAP_PETALBURG_CITY_WALLYS_HOUSE":2048,"MAP_PETALBURG_WOODS":6155,"MAP_RECORD_CORNER":6426,"MAP_ROUTE101":16,"MAP_ROUTE102":17,"MAP_ROUTE103":18,"MAP_ROUTE104":19,"MAP_ROUTE104_MR_BRINEYS_HOUSE":4352,"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":4353,"MAP_ROUTE104_PROTOTYPE":6912,"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":6913,"MAP_ROUTE105":20,"MAP_ROUTE106":21,"MAP_ROUTE107":22,"MAP_ROUTE108":23,"MAP_ROUTE109":24,"MAP_ROUTE109_SEASHORE_HOUSE":7168,"MAP_ROUTE110":25,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":7435,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":7436,"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":7426,"MAP_ROUTE110_TRICK_HOUSE_END":7425,"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":7424,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":7427,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":7428,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":7429,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":7430,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":7431,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":7432,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":7433,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":7434,"MAP_ROUTE111":26,"MAP_ROUTE111_OLD_LADYS_REST_STOP":4609,"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":4608,"MAP_ROUTE112":27,"MAP_ROUTE112_CABLE_CAR_STATION":4864,"MAP_ROUTE113":28,"MAP_ROUTE113_GLASS_WORKSHOP":7680,"MAP_ROUTE114":29,"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":5120,"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":5121,"MAP_ROUTE114_LANETTES_HOUSE":5122,"MAP_ROUTE115":30,"MAP_ROUTE116":31,"MAP_ROUTE116_TUNNELERS_REST_HOUSE":5376,"MAP_ROUTE117":32,"MAP_ROUTE117_POKEMON_DAY_CARE":5632,"MAP_ROUTE118":33,"MAP_ROUTE119":34,"MAP_ROUTE119_HOUSE":8194,"MAP_ROUTE119_WEATHER_INSTITUTE_1F":8192,"MAP_ROUTE119_WEATHER_INSTITUTE_2F":8193,"MAP_ROUTE120":35,"MAP_ROUTE121":36,"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":5888,"MAP_ROUTE122":37,"MAP_ROUTE123":38,"MAP_ROUTE123_BERRY_MASTERS_HOUSE":7936,"MAP_ROUTE124":39,"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":8448,"MAP_ROUTE125":40,"MAP_ROUTE126":41,"MAP_ROUTE127":42,"MAP_ROUTE128":43,"MAP_ROUTE129":44,"MAP_ROUTE130":45,"MAP_ROUTE131":46,"MAP_ROUTE132":47,"MAP_ROUTE133":48,"MAP_ROUTE134":49,"MAP_RUSTBORO_CITY":3,"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":2827,"MAP_RUSTBORO_CITY_DEVON_CORP_1F":2816,"MAP_RUSTBORO_CITY_DEVON_CORP_2F":2817,"MAP_RUSTBORO_CITY_DEVON_CORP_3F":2818,"MAP_RUSTBORO_CITY_FLAT1_1F":2824,"MAP_RUSTBORO_CITY_FLAT1_2F":2825,"MAP_RUSTBORO_CITY_FLAT2_1F":2829,"MAP_RUSTBORO_CITY_FLAT2_2F":2830,"MAP_RUSTBORO_CITY_FLAT2_3F":2831,"MAP_RUSTBORO_CITY_GYM":2819,"MAP_RUSTBORO_CITY_HOUSE1":2826,"MAP_RUSTBORO_CITY_HOUSE2":2828,"MAP_RUSTBORO_CITY_HOUSE3":2832,"MAP_RUSTBORO_CITY_MART":2823,"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":2821,"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":2822,"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":2820,"MAP_RUSTURF_TUNNEL":6148,"MAP_SAFARI_ZONE_NORTH":6657,"MAP_SAFARI_ZONE_NORTHEAST":6668,"MAP_SAFARI_ZONE_NORTHWEST":6656,"MAP_SAFARI_ZONE_REST_HOUSE":6667,"MAP_SAFARI_ZONE_SOUTH":6659,"MAP_SAFARI_ZONE_SOUTHEAST":6669,"MAP_SAFARI_ZONE_SOUTHWEST":6658,"MAP_SCORCHED_SLAB":6217,"MAP_SEAFLOOR_CAVERN_ENTRANCE":6171,"MAP_SEAFLOOR_CAVERN_ROOM1":6172,"MAP_SEAFLOOR_CAVERN_ROOM2":6173,"MAP_SEAFLOOR_CAVERN_ROOM3":6174,"MAP_SEAFLOOR_CAVERN_ROOM4":6175,"MAP_SEAFLOOR_CAVERN_ROOM5":6176,"MAP_SEAFLOOR_CAVERN_ROOM6":6177,"MAP_SEAFLOOR_CAVERN_ROOM7":6178,"MAP_SEAFLOOR_CAVERN_ROOM8":6179,"MAP_SEAFLOOR_CAVERN_ROOM9":6180,"MAP_SEALED_CHAMBER_INNER_ROOM":6216,"MAP_SEALED_CHAMBER_OUTER_ROOM":6215,"MAP_SECRET_BASE_BLUE_CAVE1":6402,"MAP_SECRET_BASE_BLUE_CAVE2":6408,"MAP_SECRET_BASE_BLUE_CAVE3":6414,"MAP_SECRET_BASE_BLUE_CAVE4":6420,"MAP_SECRET_BASE_BROWN_CAVE1":6401,"MAP_SECRET_BASE_BROWN_CAVE2":6407,"MAP_SECRET_BASE_BROWN_CAVE3":6413,"MAP_SECRET_BASE_BROWN_CAVE4":6419,"MAP_SECRET_BASE_RED_CAVE1":6400,"MAP_SECRET_BASE_RED_CAVE2":6406,"MAP_SECRET_BASE_RED_CAVE3":6412,"MAP_SECRET_BASE_RED_CAVE4":6418,"MAP_SECRET_BASE_SHRUB1":6405,"MAP_SECRET_BASE_SHRUB2":6411,"MAP_SECRET_BASE_SHRUB3":6417,"MAP_SECRET_BASE_SHRUB4":6423,"MAP_SECRET_BASE_TREE1":6404,"MAP_SECRET_BASE_TREE2":6410,"MAP_SECRET_BASE_TREE3":6416,"MAP_SECRET_BASE_TREE4":6422,"MAP_SECRET_BASE_YELLOW_CAVE1":6403,"MAP_SECRET_BASE_YELLOW_CAVE2":6409,"MAP_SECRET_BASE_YELLOW_CAVE3":6415,"MAP_SECRET_BASE_YELLOW_CAVE4":6421,"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":6194,"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":6195,"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":6190,"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":6227,"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":6191,"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":6193,"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":6192,"MAP_SKY_PILLAR_1F":6223,"MAP_SKY_PILLAR_2F":6224,"MAP_SKY_PILLAR_3F":6225,"MAP_SKY_PILLAR_4F":6226,"MAP_SKY_PILLAR_5F":6228,"MAP_SKY_PILLAR_ENTRANCE":6221,"MAP_SKY_PILLAR_OUTSIDE":6222,"MAP_SKY_PILLAR_TOP":6229,"MAP_SLATEPORT_CITY":1,"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":2308,"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":2307,"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":2306,"MAP_SLATEPORT_CITY_HARBOR":2313,"MAP_SLATEPORT_CITY_HOUSE":2314,"MAP_SLATEPORT_CITY_MART":2317,"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":2309,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":2311,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":2312,"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":2315,"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":2316,"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":2310,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":2304,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":2305,"MAP_SOOTOPOLIS_CITY":7,"MAP_SOOTOPOLIS_CITY_GYM_1F":3840,"MAP_SOOTOPOLIS_CITY_GYM_B1F":3841,"MAP_SOOTOPOLIS_CITY_HOUSE1":3845,"MAP_SOOTOPOLIS_CITY_HOUSE2":3846,"MAP_SOOTOPOLIS_CITY_HOUSE3":3847,"MAP_SOOTOPOLIS_CITY_HOUSE4":3848,"MAP_SOOTOPOLIS_CITY_HOUSE5":3849,"MAP_SOOTOPOLIS_CITY_HOUSE6":3850,"MAP_SOOTOPOLIS_CITY_HOUSE7":3851,"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":3852,"MAP_SOOTOPOLIS_CITY_MART":3844,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":3853,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":3854,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":3842,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":3843,"MAP_SOUTHERN_ISLAND_EXTERIOR":6665,"MAP_SOUTHERN_ISLAND_INTERIOR":6666,"MAP_SS_TIDAL_CORRIDOR":6441,"MAP_SS_TIDAL_LOWER_DECK":6442,"MAP_SS_TIDAL_ROOMS":6443,"MAP_TERRA_CAVE_END":6249,"MAP_TERRA_CAVE_ENTRANCE":6248,"MAP_TRADE_CENTER":6425,"MAP_TRAINER_HILL_1F":6717,"MAP_TRAINER_HILL_2F":6718,"MAP_TRAINER_HILL_3F":6719,"MAP_TRAINER_HILL_4F":6720,"MAP_TRAINER_HILL_ELEVATOR":6744,"MAP_TRAINER_HILL_ENTRANCE":6716,"MAP_TRAINER_HILL_ROOF":6721,"MAP_UNDERWATER_MARINE_CAVE":6245,"MAP_UNDERWATER_ROUTE105":55,"MAP_UNDERWATER_ROUTE124":50,"MAP_UNDERWATER_ROUTE125":56,"MAP_UNDERWATER_ROUTE126":51,"MAP_UNDERWATER_ROUTE127":52,"MAP_UNDERWATER_ROUTE128":53,"MAP_UNDERWATER_ROUTE129":54,"MAP_UNDERWATER_ROUTE134":6213,"MAP_UNDERWATER_SEAFLOOR_CAVERN":6170,"MAP_UNDERWATER_SEALED_CHAMBER":6214,"MAP_UNDERWATER_SOOTOPOLIS_CITY":6149,"MAP_UNION_ROOM":6460,"MAP_UNUSED_CONTEST_HALL1":6429,"MAP_UNUSED_CONTEST_HALL2":6430,"MAP_UNUSED_CONTEST_HALL3":6431,"MAP_UNUSED_CONTEST_HALL4":6432,"MAP_UNUSED_CONTEST_HALL5":6433,"MAP_UNUSED_CONTEST_HALL6":6434,"MAP_VERDANTURF_TOWN":14,"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":1538,"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":1537,"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":1536,"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":1543,"MAP_VERDANTURF_TOWN_HOUSE":1544,"MAP_VERDANTURF_TOWN_MART":1539,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":1540,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":1541,"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":1542,"MAP_VICTORY_ROAD_1F":6187,"MAP_VICTORY_ROAD_B1F":6188,"MAP_VICTORY_ROAD_B2F":6189,"MAX_BAG_ITEM_CAPACITY":99,"MAX_BERRY_CAPACITY":999,"MAX_BERRY_INDEX":178,"MAX_ITEM_DIGITS":3,"MAX_PC_ITEM_CAPACITY":999,"MAX_TRAINERS_COUNT":864,"MOVES_COUNT":355,"MOVE_ABSORB":71,"MOVE_ACID":51,"MOVE_ACID_ARMOR":151,"MOVE_AERIAL_ACE":332,"MOVE_AEROBLAST":177,"MOVE_AGILITY":97,"MOVE_AIR_CUTTER":314,"MOVE_AMNESIA":133,"MOVE_ANCIENT_POWER":246,"MOVE_ARM_THRUST":292,"MOVE_AROMATHERAPY":312,"MOVE_ASSIST":274,"MOVE_ASTONISH":310,"MOVE_ATTRACT":213,"MOVE_AURORA_BEAM":62,"MOVE_BARRAGE":140,"MOVE_BARRIER":112,"MOVE_BATON_PASS":226,"MOVE_BEAT_UP":251,"MOVE_BELLY_DRUM":187,"MOVE_BIDE":117,"MOVE_BIND":20,"MOVE_BITE":44,"MOVE_BLAST_BURN":307,"MOVE_BLAZE_KICK":299,"MOVE_BLIZZARD":59,"MOVE_BLOCK":335,"MOVE_BODY_SLAM":34,"MOVE_BONEMERANG":155,"MOVE_BONE_CLUB":125,"MOVE_BONE_RUSH":198,"MOVE_BOUNCE":340,"MOVE_BRICK_BREAK":280,"MOVE_BUBBLE":145,"MOVE_BUBBLE_BEAM":61,"MOVE_BULK_UP":339,"MOVE_BULLET_SEED":331,"MOVE_CALM_MIND":347,"MOVE_CAMOUFLAGE":293,"MOVE_CHARGE":268,"MOVE_CHARM":204,"MOVE_CLAMP":128,"MOVE_COMET_PUNCH":4,"MOVE_CONFUSE_RAY":109,"MOVE_CONFUSION":93,"MOVE_CONSTRICT":132,"MOVE_CONVERSION":160,"MOVE_CONVERSION_2":176,"MOVE_COSMIC_POWER":322,"MOVE_COTTON_SPORE":178,"MOVE_COUNTER":68,"MOVE_COVET":343,"MOVE_CRABHAMMER":152,"MOVE_CROSS_CHOP":238,"MOVE_CRUNCH":242,"MOVE_CRUSH_CLAW":306,"MOVE_CURSE":174,"MOVE_CUT":15,"MOVE_DEFENSE_CURL":111,"MOVE_DESTINY_BOND":194,"MOVE_DETECT":197,"MOVE_DIG":91,"MOVE_DISABLE":50,"MOVE_DIVE":291,"MOVE_DIZZY_PUNCH":146,"MOVE_DOOM_DESIRE":353,"MOVE_DOUBLE_EDGE":38,"MOVE_DOUBLE_KICK":24,"MOVE_DOUBLE_SLAP":3,"MOVE_DOUBLE_TEAM":104,"MOVE_DRAGON_BREATH":225,"MOVE_DRAGON_CLAW":337,"MOVE_DRAGON_DANCE":349,"MOVE_DRAGON_RAGE":82,"MOVE_DREAM_EATER":138,"MOVE_DRILL_PECK":65,"MOVE_DYNAMIC_PUNCH":223,"MOVE_EARTHQUAKE":89,"MOVE_EGG_BOMB":121,"MOVE_EMBER":52,"MOVE_ENCORE":227,"MOVE_ENDEAVOR":283,"MOVE_ENDURE":203,"MOVE_ERUPTION":284,"MOVE_EXPLOSION":153,"MOVE_EXTRASENSORY":326,"MOVE_EXTREME_SPEED":245,"MOVE_FACADE":263,"MOVE_FAINT_ATTACK":185,"MOVE_FAKE_OUT":252,"MOVE_FAKE_TEARS":313,"MOVE_FALSE_SWIPE":206,"MOVE_FEATHER_DANCE":297,"MOVE_FIRE_BLAST":126,"MOVE_FIRE_PUNCH":7,"MOVE_FIRE_SPIN":83,"MOVE_FISSURE":90,"MOVE_FLAIL":175,"MOVE_FLAMETHROWER":53,"MOVE_FLAME_WHEEL":172,"MOVE_FLASH":148,"MOVE_FLATTER":260,"MOVE_FLY":19,"MOVE_FOCUS_ENERGY":116,"MOVE_FOCUS_PUNCH":264,"MOVE_FOLLOW_ME":266,"MOVE_FORESIGHT":193,"MOVE_FRENZY_PLANT":338,"MOVE_FRUSTRATION":218,"MOVE_FURY_ATTACK":31,"MOVE_FURY_CUTTER":210,"MOVE_FURY_SWIPES":154,"MOVE_FUTURE_SIGHT":248,"MOVE_GIGA_DRAIN":202,"MOVE_GLARE":137,"MOVE_GRASS_WHISTLE":320,"MOVE_GROWL":45,"MOVE_GROWTH":74,"MOVE_GRUDGE":288,"MOVE_GUILLOTINE":12,"MOVE_GUST":16,"MOVE_HAIL":258,"MOVE_HARDEN":106,"MOVE_HAZE":114,"MOVE_HEADBUTT":29,"MOVE_HEAL_BELL":215,"MOVE_HEAT_WAVE":257,"MOVE_HELPING_HAND":270,"MOVE_HIDDEN_POWER":237,"MOVE_HI_JUMP_KICK":136,"MOVE_HORN_ATTACK":30,"MOVE_HORN_DRILL":32,"MOVE_HOWL":336,"MOVE_HYDRO_CANNON":308,"MOVE_HYDRO_PUMP":56,"MOVE_HYPER_BEAM":63,"MOVE_HYPER_FANG":158,"MOVE_HYPER_VOICE":304,"MOVE_HYPNOSIS":95,"MOVE_ICE_BALL":301,"MOVE_ICE_BEAM":58,"MOVE_ICE_PUNCH":8,"MOVE_ICICLE_SPEAR":333,"MOVE_ICY_WIND":196,"MOVE_IMPRISON":286,"MOVE_INGRAIN":275,"MOVE_IRON_DEFENSE":334,"MOVE_IRON_TAIL":231,"MOVE_JUMP_KICK":26,"MOVE_KARATE_CHOP":2,"MOVE_KINESIS":134,"MOVE_KNOCK_OFF":282,"MOVE_LEAF_BLADE":348,"MOVE_LEECH_LIFE":141,"MOVE_LEECH_SEED":73,"MOVE_LEER":43,"MOVE_LICK":122,"MOVE_LIGHT_SCREEN":113,"MOVE_LOCK_ON":199,"MOVE_LOVELY_KISS":142,"MOVE_LOW_KICK":67,"MOVE_LUSTER_PURGE":295,"MOVE_MACH_PUNCH":183,"MOVE_MAGICAL_LEAF":345,"MOVE_MAGIC_COAT":277,"MOVE_MAGNITUDE":222,"MOVE_MEAN_LOOK":212,"MOVE_MEDITATE":96,"MOVE_MEGAHORN":224,"MOVE_MEGA_DRAIN":72,"MOVE_MEGA_KICK":25,"MOVE_MEGA_PUNCH":5,"MOVE_MEMENTO":262,"MOVE_METAL_CLAW":232,"MOVE_METAL_SOUND":319,"MOVE_METEOR_MASH":309,"MOVE_METRONOME":118,"MOVE_MILK_DRINK":208,"MOVE_MIMIC":102,"MOVE_MIND_READER":170,"MOVE_MINIMIZE":107,"MOVE_MIRROR_COAT":243,"MOVE_MIRROR_MOVE":119,"MOVE_MIST":54,"MOVE_MIST_BALL":296,"MOVE_MOONLIGHT":236,"MOVE_MORNING_SUN":234,"MOVE_MUDDY_WATER":330,"MOVE_MUD_SHOT":341,"MOVE_MUD_SLAP":189,"MOVE_MUD_SPORT":300,"MOVE_NATURE_POWER":267,"MOVE_NEEDLE_ARM":302,"MOVE_NIGHTMARE":171,"MOVE_NIGHT_SHADE":101,"MOVE_NONE":0,"MOVE_OCTAZOOKA":190,"MOVE_ODOR_SLEUTH":316,"MOVE_OUTRAGE":200,"MOVE_OVERHEAT":315,"MOVE_PAIN_SPLIT":220,"MOVE_PAY_DAY":6,"MOVE_PECK":64,"MOVE_PERISH_SONG":195,"MOVE_PETAL_DANCE":80,"MOVE_PIN_MISSILE":42,"MOVE_POISON_FANG":305,"MOVE_POISON_GAS":139,"MOVE_POISON_POWDER":77,"MOVE_POISON_STING":40,"MOVE_POISON_TAIL":342,"MOVE_POUND":1,"MOVE_POWDER_SNOW":181,"MOVE_PRESENT":217,"MOVE_PROTECT":182,"MOVE_PSYBEAM":60,"MOVE_PSYCHIC":94,"MOVE_PSYCHO_BOOST":354,"MOVE_PSYCH_UP":244,"MOVE_PSYWAVE":149,"MOVE_PURSUIT":228,"MOVE_QUICK_ATTACK":98,"MOVE_RAGE":99,"MOVE_RAIN_DANCE":240,"MOVE_RAPID_SPIN":229,"MOVE_RAZOR_LEAF":75,"MOVE_RAZOR_WIND":13,"MOVE_RECOVER":105,"MOVE_RECYCLE":278,"MOVE_REFLECT":115,"MOVE_REFRESH":287,"MOVE_REST":156,"MOVE_RETURN":216,"MOVE_REVENGE":279,"MOVE_REVERSAL":179,"MOVE_ROAR":46,"MOVE_ROCK_BLAST":350,"MOVE_ROCK_SLIDE":157,"MOVE_ROCK_SMASH":249,"MOVE_ROCK_THROW":88,"MOVE_ROCK_TOMB":317,"MOVE_ROLE_PLAY":272,"MOVE_ROLLING_KICK":27,"MOVE_ROLLOUT":205,"MOVE_SACRED_FIRE":221,"MOVE_SAFEGUARD":219,"MOVE_SANDSTORM":201,"MOVE_SAND_ATTACK":28,"MOVE_SAND_TOMB":328,"MOVE_SCARY_FACE":184,"MOVE_SCRATCH":10,"MOVE_SCREECH":103,"MOVE_SECRET_POWER":290,"MOVE_SEISMIC_TOSS":69,"MOVE_SELF_DESTRUCT":120,"MOVE_SHADOW_BALL":247,"MOVE_SHADOW_PUNCH":325,"MOVE_SHARPEN":159,"MOVE_SHEER_COLD":329,"MOVE_SHOCK_WAVE":351,"MOVE_SIGNAL_BEAM":324,"MOVE_SILVER_WIND":318,"MOVE_SING":47,"MOVE_SKETCH":166,"MOVE_SKILL_SWAP":285,"MOVE_SKULL_BASH":130,"MOVE_SKY_ATTACK":143,"MOVE_SKY_UPPERCUT":327,"MOVE_SLACK_OFF":303,"MOVE_SLAM":21,"MOVE_SLASH":163,"MOVE_SLEEP_POWDER":79,"MOVE_SLEEP_TALK":214,"MOVE_SLUDGE":124,"MOVE_SLUDGE_BOMB":188,"MOVE_SMELLING_SALT":265,"MOVE_SMOG":123,"MOVE_SMOKESCREEN":108,"MOVE_SNATCH":289,"MOVE_SNORE":173,"MOVE_SOFT_BOILED":135,"MOVE_SOLAR_BEAM":76,"MOVE_SONIC_BOOM":49,"MOVE_SPARK":209,"MOVE_SPIDER_WEB":169,"MOVE_SPIKES":191,"MOVE_SPIKE_CANNON":131,"MOVE_SPITE":180,"MOVE_SPIT_UP":255,"MOVE_SPLASH":150,"MOVE_SPORE":147,"MOVE_STEEL_WING":211,"MOVE_STOCKPILE":254,"MOVE_STOMP":23,"MOVE_STRENGTH":70,"MOVE_STRING_SHOT":81,"MOVE_STRUGGLE":165,"MOVE_STUN_SPORE":78,"MOVE_SUBMISSION":66,"MOVE_SUBSTITUTE":164,"MOVE_SUNNY_DAY":241,"MOVE_SUPERPOWER":276,"MOVE_SUPERSONIC":48,"MOVE_SUPER_FANG":162,"MOVE_SURF":57,"MOVE_SWAGGER":207,"MOVE_SWALLOW":256,"MOVE_SWEET_KISS":186,"MOVE_SWEET_SCENT":230,"MOVE_SWIFT":129,"MOVE_SWORDS_DANCE":14,"MOVE_SYNTHESIS":235,"MOVE_TACKLE":33,"MOVE_TAIL_GLOW":294,"MOVE_TAIL_WHIP":39,"MOVE_TAKE_DOWN":36,"MOVE_TAUNT":269,"MOVE_TEETER_DANCE":298,"MOVE_TELEPORT":100,"MOVE_THIEF":168,"MOVE_THRASH":37,"MOVE_THUNDER":87,"MOVE_THUNDERBOLT":85,"MOVE_THUNDER_PUNCH":9,"MOVE_THUNDER_SHOCK":84,"MOVE_THUNDER_WAVE":86,"MOVE_TICKLE":321,"MOVE_TORMENT":259,"MOVE_TOXIC":92,"MOVE_TRANSFORM":144,"MOVE_TRICK":271,"MOVE_TRIPLE_KICK":167,"MOVE_TRI_ATTACK":161,"MOVE_TWINEEDLE":41,"MOVE_TWISTER":239,"MOVE_UNAVAILABLE":65535,"MOVE_UPROAR":253,"MOVE_VICE_GRIP":11,"MOVE_VINE_WHIP":22,"MOVE_VITAL_THROW":233,"MOVE_VOLT_TACKLE":344,"MOVE_WATERFALL":127,"MOVE_WATER_GUN":55,"MOVE_WATER_PULSE":352,"MOVE_WATER_SPORT":346,"MOVE_WATER_SPOUT":323,"MOVE_WEATHER_BALL":311,"MOVE_WHIRLPOOL":250,"MOVE_WHIRLWIND":18,"MOVE_WILL_O_WISP":261,"MOVE_WING_ATTACK":17,"MOVE_WISH":273,"MOVE_WITHDRAW":110,"MOVE_WRAP":35,"MOVE_YAWN":281,"MOVE_ZAP_CANNON":192,"MUS_ABANDONED_SHIP":381,"MUS_ABNORMAL_WEATHER":443,"MUS_AQUA_MAGMA_HIDEOUT":430,"MUS_AWAKEN_LEGEND":388,"MUS_BIRCH_LAB":383,"MUS_B_ARENA":458,"MUS_B_DOME":467,"MUS_B_DOME_LOBBY":473,"MUS_B_FACTORY":469,"MUS_B_FRONTIER":457,"MUS_B_PALACE":463,"MUS_B_PIKE":468,"MUS_B_PYRAMID":461,"MUS_B_PYRAMID_TOP":462,"MUS_B_TOWER":465,"MUS_B_TOWER_RS":384,"MUS_CABLE_CAR":425,"MUS_CAUGHT":352,"MUS_CAVE_OF_ORIGIN":386,"MUS_CONTEST":440,"MUS_CONTEST_LOBBY":452,"MUS_CONTEST_RESULTS":446,"MUS_CONTEST_WINNER":439,"MUS_CREDITS":455,"MUS_CYCLING":403,"MUS_C_COMM_CENTER":356,"MUS_C_VS_LEGEND_BEAST":358,"MUS_DESERT":409,"MUS_DEWFORD":427,"MUS_DUMMY":0,"MUS_ENCOUNTER_AQUA":419,"MUS_ENCOUNTER_BRENDAN":421,"MUS_ENCOUNTER_CHAMPION":454,"MUS_ENCOUNTER_COOL":417,"MUS_ENCOUNTER_ELITE_FOUR":450,"MUS_ENCOUNTER_FEMALE":407,"MUS_ENCOUNTER_GIRL":379,"MUS_ENCOUNTER_HIKER":451,"MUS_ENCOUNTER_INTENSE":416,"MUS_ENCOUNTER_INTERVIEWER":453,"MUS_ENCOUNTER_MAGMA":441,"MUS_ENCOUNTER_MALE":380,"MUS_ENCOUNTER_MAY":415,"MUS_ENCOUNTER_RICH":397,"MUS_ENCOUNTER_SUSPICIOUS":423,"MUS_ENCOUNTER_SWIMMER":385,"MUS_ENCOUNTER_TWINS":449,"MUS_END":456,"MUS_EVER_GRANDE":422,"MUS_EVOLUTION":377,"MUS_EVOLUTION_INTRO":376,"MUS_EVOLVED":371,"MUS_FALLARBOR":437,"MUS_FOLLOW_ME":420,"MUS_FORTREE":382,"MUS_GAME_CORNER":426,"MUS_GSC_PEWTER":357,"MUS_GSC_ROUTE38":351,"MUS_GYM":364,"MUS_HALL_OF_FAME":436,"MUS_HALL_OF_FAME_ROOM":447,"MUS_HEAL":368,"MUS_HELP":410,"MUS_INTRO":414,"MUS_INTRO_BATTLE":442,"MUS_LEVEL_UP":367,"MUS_LILYCOVE":408,"MUS_LILYCOVE_MUSEUM":373,"MUS_LINK_CONTEST_P1":393,"MUS_LINK_CONTEST_P2":394,"MUS_LINK_CONTEST_P3":395,"MUS_LINK_CONTEST_P4":396,"MUS_LITTLEROOT":405,"MUS_LITTLEROOT_TEST":350,"MUS_MOVE_DELETED":378,"MUS_MT_CHIMNEY":406,"MUS_MT_PYRE":432,"MUS_MT_PYRE_EXTERIOR":434,"MUS_NONE":65535,"MUS_OBTAIN_BADGE":369,"MUS_OBTAIN_BERRY":387,"MUS_OBTAIN_B_POINTS":459,"MUS_OBTAIN_ITEM":370,"MUS_OBTAIN_SYMBOL":466,"MUS_OBTAIN_TMHM":372,"MUS_OCEANIC_MUSEUM":375,"MUS_OLDALE":363,"MUS_PETALBURG":362,"MUS_PETALBURG_WOODS":366,"MUS_POKE_CENTER":400,"MUS_POKE_MART":404,"MUS_RAYQUAZA_APPEARS":464,"MUS_REGISTER_MATCH_CALL":460,"MUS_RG_BERRY_PICK":542,"MUS_RG_CAUGHT":534,"MUS_RG_CAUGHT_INTRO":531,"MUS_RG_CELADON":521,"MUS_RG_CINNABAR":491,"MUS_RG_CREDITS":502,"MUS_RG_CYCLING":494,"MUS_RG_DEX_RATING":529,"MUS_RG_ENCOUNTER_BOY":497,"MUS_RG_ENCOUNTER_DEOXYS":555,"MUS_RG_ENCOUNTER_GIRL":496,"MUS_RG_ENCOUNTER_GYM_LEADER":554,"MUS_RG_ENCOUNTER_RIVAL":527,"MUS_RG_ENCOUNTER_ROCKET":495,"MUS_RG_FOLLOW_ME":484,"MUS_RG_FUCHSIA":520,"MUS_RG_GAME_CORNER":485,"MUS_RG_GAME_FREAK":533,"MUS_RG_GYM":487,"MUS_RG_HALL_OF_FAME":498,"MUS_RG_HEAL":493,"MUS_RG_INTRO_FIGHT":489,"MUS_RG_JIGGLYPUFF":488,"MUS_RG_LAVENDER":492,"MUS_RG_MT_MOON":500,"MUS_RG_MYSTERY_GIFT":541,"MUS_RG_NET_CENTER":540,"MUS_RG_NEW_GAME_EXIT":537,"MUS_RG_NEW_GAME_INSTRUCT":535,"MUS_RG_NEW_GAME_INTRO":536,"MUS_RG_OAK":514,"MUS_RG_OAK_LAB":513,"MUS_RG_OBTAIN_KEY_ITEM":530,"MUS_RG_PALLET":512,"MUS_RG_PEWTER":526,"MUS_RG_PHOTO":532,"MUS_RG_POKE_CENTER":515,"MUS_RG_POKE_FLUTE":550,"MUS_RG_POKE_JUMP":538,"MUS_RG_POKE_MANSION":501,"MUS_RG_POKE_TOWER":518,"MUS_RG_RIVAL_EXIT":528,"MUS_RG_ROCKET_HIDEOUT":486,"MUS_RG_ROUTE1":503,"MUS_RG_ROUTE11":506,"MUS_RG_ROUTE24":504,"MUS_RG_ROUTE3":505,"MUS_RG_SEVII_123":547,"MUS_RG_SEVII_45":548,"MUS_RG_SEVII_67":549,"MUS_RG_SEVII_CAVE":543,"MUS_RG_SEVII_DUNGEON":546,"MUS_RG_SEVII_ROUTE":545,"MUS_RG_SILPH":519,"MUS_RG_SLOW_PALLET":557,"MUS_RG_SS_ANNE":516,"MUS_RG_SURF":517,"MUS_RG_TEACHY_TV_MENU":558,"MUS_RG_TEACHY_TV_SHOW":544,"MUS_RG_TITLE":490,"MUS_RG_TRAINER_TOWER":556,"MUS_RG_UNION_ROOM":539,"MUS_RG_VERMILLION":525,"MUS_RG_VICTORY_GYM_LEADER":524,"MUS_RG_VICTORY_ROAD":507,"MUS_RG_VICTORY_TRAINER":522,"MUS_RG_VICTORY_WILD":523,"MUS_RG_VIRIDIAN_FOREST":499,"MUS_RG_VS_CHAMPION":511,"MUS_RG_VS_DEOXYS":551,"MUS_RG_VS_GYM_LEADER":508,"MUS_RG_VS_LEGEND":553,"MUS_RG_VS_MEWTWO":552,"MUS_RG_VS_TRAINER":509,"MUS_RG_VS_WILD":510,"MUS_ROULETTE":392,"MUS_ROUTE101":359,"MUS_ROUTE104":401,"MUS_ROUTE110":360,"MUS_ROUTE113":418,"MUS_ROUTE118":32767,"MUS_ROUTE119":402,"MUS_ROUTE120":361,"MUS_ROUTE122":374,"MUS_RUSTBORO":399,"MUS_SAFARI_ZONE":428,"MUS_SAILING":431,"MUS_SCHOOL":435,"MUS_SEALED_CHAMBER":438,"MUS_SLATEPORT":433,"MUS_SLOTS_JACKPOT":389,"MUS_SLOTS_WIN":390,"MUS_SOOTOPOLIS":445,"MUS_SURF":365,"MUS_TITLE":413,"MUS_TOO_BAD":391,"MUS_TRICK_HOUSE":448,"MUS_UNDERWATER":411,"MUS_VERDANTURF":398,"MUS_VICTORY_AQUA_MAGMA":424,"MUS_VICTORY_GYM_LEADER":354,"MUS_VICTORY_LEAGUE":355,"MUS_VICTORY_ROAD":429,"MUS_VICTORY_TRAINER":412,"MUS_VICTORY_WILD":353,"MUS_VS_AQUA_MAGMA":475,"MUS_VS_AQUA_MAGMA_LEADER":483,"MUS_VS_CHAMPION":478,"MUS_VS_ELITE_FOUR":482,"MUS_VS_FRONTIER_BRAIN":471,"MUS_VS_GYM_LEADER":477,"MUS_VS_KYOGRE_GROUDON":480,"MUS_VS_MEW":472,"MUS_VS_RAYQUAZA":470,"MUS_VS_REGI":479,"MUS_VS_RIVAL":481,"MUS_VS_TRAINER":476,"MUS_VS_WILD":474,"MUS_WEATHER_GROUDON":444,"NUM_BADGES":8,"NUM_BERRY_MASTER_BERRIES":10,"NUM_BERRY_MASTER_BERRIES_SKIPPED":20,"NUM_BERRY_MASTER_WIFE_BERRIES":10,"NUM_DAILY_FLAGS":64,"NUM_HIDDEN_MACHINES":8,"NUM_KIRI_BERRIES":10,"NUM_KIRI_BERRIES_SKIPPED":20,"NUM_ROUTE_114_MAN_BERRIES":5,"NUM_ROUTE_114_MAN_BERRIES_SKIPPED":15,"NUM_SPECIAL_FLAGS":128,"NUM_SPECIES":412,"NUM_TECHNICAL_MACHINES":50,"NUM_TEMP_FLAGS":32,"NUM_WATER_STAGES":4,"NUM_WONDER_CARD_FLAGS":20,"OLD_ROD":0,"PH_CHOICE_BLEND":589,"PH_CHOICE_HELD":590,"PH_CHOICE_SOLO":591,"PH_CLOTH_BLEND":565,"PH_CLOTH_HELD":566,"PH_CLOTH_SOLO":567,"PH_CURE_BLEND":604,"PH_CURE_HELD":605,"PH_CURE_SOLO":606,"PH_DRESS_BLEND":568,"PH_DRESS_HELD":569,"PH_DRESS_SOLO":570,"PH_FACE_BLEND":562,"PH_FACE_HELD":563,"PH_FACE_SOLO":564,"PH_FLEECE_BLEND":571,"PH_FLEECE_HELD":572,"PH_FLEECE_SOLO":573,"PH_FOOT_BLEND":595,"PH_FOOT_HELD":596,"PH_FOOT_SOLO":597,"PH_GOAT_BLEND":583,"PH_GOAT_HELD":584,"PH_GOAT_SOLO":585,"PH_GOOSE_BLEND":598,"PH_GOOSE_HELD":599,"PH_GOOSE_SOLO":600,"PH_KIT_BLEND":574,"PH_KIT_HELD":575,"PH_KIT_SOLO":576,"PH_LOT_BLEND":580,"PH_LOT_HELD":581,"PH_LOT_SOLO":582,"PH_MOUTH_BLEND":592,"PH_MOUTH_HELD":593,"PH_MOUTH_SOLO":594,"PH_NURSE_BLEND":607,"PH_NURSE_HELD":608,"PH_NURSE_SOLO":609,"PH_PRICE_BLEND":577,"PH_PRICE_HELD":578,"PH_PRICE_SOLO":579,"PH_STRUT_BLEND":601,"PH_STRUT_HELD":602,"PH_STRUT_SOLO":603,"PH_THOUGHT_BLEND":586,"PH_THOUGHT_HELD":587,"PH_THOUGHT_SOLO":588,"PH_TRAP_BLEND":559,"PH_TRAP_HELD":560,"PH_TRAP_SOLO":561,"SE_A":25,"SE_APPLAUSE":105,"SE_ARENA_TIMEUP1":265,"SE_ARENA_TIMEUP2":266,"SE_BALL":23,"SE_BALLOON_BLUE":75,"SE_BALLOON_RED":74,"SE_BALLOON_YELLOW":76,"SE_BALL_BOUNCE_1":56,"SE_BALL_BOUNCE_2":57,"SE_BALL_BOUNCE_3":58,"SE_BALL_BOUNCE_4":59,"SE_BALL_OPEN":15,"SE_BALL_THROW":61,"SE_BALL_TRADE":60,"SE_BALL_TRAY_BALL":115,"SE_BALL_TRAY_ENTER":114,"SE_BALL_TRAY_EXIT":116,"SE_BANG":20,"SE_BERRY_BLENDER":53,"SE_BIKE_BELL":11,"SE_BIKE_HOP":34,"SE_BOO":22,"SE_BREAKABLE_DOOR":77,"SE_BRIDGE_WALK":71,"SE_CARD":54,"SE_CLICK":36,"SE_CONTEST_CONDITION_LOSE":38,"SE_CONTEST_CURTAIN_FALL":98,"SE_CONTEST_CURTAIN_RISE":97,"SE_CONTEST_HEART":96,"SE_CONTEST_ICON_CHANGE":99,"SE_CONTEST_ICON_CLEAR":100,"SE_CONTEST_MONS_TURN":101,"SE_CONTEST_PLACE":24,"SE_DEX_PAGE":109,"SE_DEX_SCROLL":108,"SE_DEX_SEARCH":112,"SE_DING_DONG":73,"SE_DOOR":8,"SE_DOWNPOUR":83,"SE_DOWNPOUR_STOP":84,"SE_E":28,"SE_EFFECTIVE":13,"SE_EGG_HATCH":113,"SE_ELEVATOR":89,"SE_ESCALATOR":80,"SE_EXIT":9,"SE_EXP":33,"SE_EXP_MAX":91,"SE_FAILURE":32,"SE_FAINT":16,"SE_FALL":43,"SE_FIELD_POISON":79,"SE_FLEE":17,"SE_FU_ZAKU":37,"SE_GLASS_FLUTE":117,"SE_I":26,"SE_ICE_BREAK":41,"SE_ICE_CRACK":42,"SE_ICE_STAIRS":40,"SE_INTRO_BLAST":103,"SE_ITEMFINDER":72,"SE_LAVARIDGE_FALL_WARP":39,"SE_LEDGE":10,"SE_LOW_HEALTH":90,"SE_MUD_BALL":78,"SE_MUGSHOT":104,"SE_M_ABSORB":180,"SE_M_ABSORB_2":179,"SE_M_ACID_ARMOR":218,"SE_M_ATTRACT":226,"SE_M_ATTRACT2":227,"SE_M_BARRIER":208,"SE_M_BATON_PASS":224,"SE_M_BELLY_DRUM":185,"SE_M_BIND":170,"SE_M_BITE":161,"SE_M_BLIZZARD":153,"SE_M_BLIZZARD2":154,"SE_M_BONEMERANG":187,"SE_M_BRICK_BREAK":198,"SE_M_BUBBLE":124,"SE_M_BUBBLE2":125,"SE_M_BUBBLE3":126,"SE_M_BUBBLE_BEAM":182,"SE_M_BUBBLE_BEAM2":183,"SE_M_CHARGE":213,"SE_M_CHARM":212,"SE_M_COMET_PUNCH":139,"SE_M_CONFUSE_RAY":196,"SE_M_COSMIC_POWER":243,"SE_M_CRABHAMMER":142,"SE_M_CUT":128,"SE_M_DETECT":209,"SE_M_DIG":175,"SE_M_DIVE":233,"SE_M_DIZZY_PUNCH":176,"SE_M_DOUBLE_SLAP":134,"SE_M_DOUBLE_TEAM":135,"SE_M_DRAGON_RAGE":171,"SE_M_EARTHQUAKE":234,"SE_M_EMBER":151,"SE_M_ENCORE":222,"SE_M_ENCORE2":223,"SE_M_EXPLOSION":178,"SE_M_FAINT_ATTACK":190,"SE_M_FIRE_PUNCH":147,"SE_M_FLAMETHROWER":146,"SE_M_FLAME_WHEEL":144,"SE_M_FLAME_WHEEL2":145,"SE_M_FLATTER":229,"SE_M_FLY":158,"SE_M_GIGA_DRAIN":199,"SE_M_GRASSWHISTLE":231,"SE_M_GUST":132,"SE_M_GUST2":133,"SE_M_HAIL":242,"SE_M_HARDEN":120,"SE_M_HAZE":246,"SE_M_HEADBUTT":162,"SE_M_HEAL_BELL":195,"SE_M_HEAT_WAVE":240,"SE_M_HORN_ATTACK":166,"SE_M_HYDRO_PUMP":164,"SE_M_HYPER_BEAM":215,"SE_M_HYPER_BEAM2":247,"SE_M_ICY_WIND":137,"SE_M_JUMP_KICK":143,"SE_M_LEER":192,"SE_M_LICK":188,"SE_M_LOCK_ON":210,"SE_M_MEGA_KICK":140,"SE_M_MEGA_KICK2":141,"SE_M_METRONOME":186,"SE_M_MILK_DRINK":225,"SE_M_MINIMIZE":204,"SE_M_MIST":168,"SE_M_MOONLIGHT":211,"SE_M_MORNING_SUN":228,"SE_M_NIGHTMARE":121,"SE_M_PAY_DAY":174,"SE_M_PERISH_SONG":173,"SE_M_PETAL_DANCE":202,"SE_M_POISON_POWDER":169,"SE_M_PSYBEAM":189,"SE_M_PSYBEAM2":200,"SE_M_RAIN_DANCE":127,"SE_M_RAZOR_WIND":136,"SE_M_RAZOR_WIND2":160,"SE_M_REFLECT":207,"SE_M_REVERSAL":217,"SE_M_ROCK_THROW":131,"SE_M_SACRED_FIRE":149,"SE_M_SACRED_FIRE2":150,"SE_M_SANDSTORM":219,"SE_M_SAND_ATTACK":159,"SE_M_SAND_TOMB":230,"SE_M_SCRATCH":155,"SE_M_SCREECH":181,"SE_M_SELF_DESTRUCT":177,"SE_M_SING":172,"SE_M_SKETCH":205,"SE_M_SKY_UPPERCUT":238,"SE_M_SNORE":197,"SE_M_SOLAR_BEAM":201,"SE_M_SPIT_UP":232,"SE_M_STAT_DECREASE":245,"SE_M_STAT_INCREASE":239,"SE_M_STRENGTH":214,"SE_M_STRING_SHOT":129,"SE_M_STRING_SHOT2":130,"SE_M_SUPERSONIC":184,"SE_M_SURF":163,"SE_M_SWAGGER":193,"SE_M_SWAGGER2":194,"SE_M_SWEET_SCENT":236,"SE_M_SWIFT":206,"SE_M_SWORDS_DANCE":191,"SE_M_TAIL_WHIP":167,"SE_M_TAKE_DOWN":152,"SE_M_TEETER_DANCE":244,"SE_M_TELEPORT":203,"SE_M_THUNDERBOLT":118,"SE_M_THUNDERBOLT2":119,"SE_M_THUNDER_WAVE":138,"SE_M_TOXIC":148,"SE_M_TRI_ATTACK":220,"SE_M_TRI_ATTACK2":221,"SE_M_TWISTER":235,"SE_M_UPROAR":241,"SE_M_VICEGRIP":156,"SE_M_VITAL_THROW":122,"SE_M_VITAL_THROW2":123,"SE_M_WATERFALL":216,"SE_M_WHIRLPOOL":165,"SE_M_WING_ATTACK":157,"SE_M_YAWN":237,"SE_N":30,"SE_NOTE_A":67,"SE_NOTE_B":68,"SE_NOTE_C":62,"SE_NOTE_C_HIGH":69,"SE_NOTE_D":63,"SE_NOTE_E":64,"SE_NOTE_F":65,"SE_NOTE_G":66,"SE_NOT_EFFECTIVE":12,"SE_O":29,"SE_ORB":107,"SE_PC_LOGIN":2,"SE_PC_OFF":3,"SE_PC_ON":4,"SE_PIKE_CURTAIN_CLOSE":267,"SE_PIKE_CURTAIN_OPEN":268,"SE_PIN":21,"SE_POKENAV_CALL":263,"SE_POKENAV_HANG_UP":264,"SE_POKENAV_OFF":111,"SE_POKENAV_ON":110,"SE_PUDDLE":70,"SE_RAIN":85,"SE_RAIN_STOP":86,"SE_REPEL":47,"SE_RG_BAG_CURSOR":252,"SE_RG_BAG_POCKET":253,"SE_RG_BALL_CLICK":254,"SE_RG_CARD_FLIP":249,"SE_RG_CARD_FLIPPING":250,"SE_RG_CARD_OPEN":251,"SE_RG_DEOXYS_MOVE":260,"SE_RG_DOOR":248,"SE_RG_HELP_CLOSE":258,"SE_RG_HELP_ERROR":259,"SE_RG_HELP_OPEN":257,"SE_RG_POKE_JUMP_FAILURE":262,"SE_RG_POKE_JUMP_SUCCESS":261,"SE_RG_SHOP":255,"SE_RG_SS_ANNE_HORN":256,"SE_ROTATING_GATE":48,"SE_ROULETTE_BALL":92,"SE_ROULETTE_BALL2":93,"SE_SAVE":55,"SE_SELECT":5,"SE_SHINY":102,"SE_SHIP":19,"SE_SHOP":95,"SE_SLIDING_DOOR":18,"SE_SUCCESS":31,"SE_SUDOWOODO_SHAKE":269,"SE_SUPER_EFFECTIVE":14,"SE_SWITCH":35,"SE_TAILLOW_WING_FLAP":94,"SE_THUNDER":87,"SE_THUNDER2":88,"SE_THUNDERSTORM":81,"SE_THUNDERSTORM_STOP":82,"SE_TRUCK_DOOR":52,"SE_TRUCK_MOVE":49,"SE_TRUCK_STOP":50,"SE_TRUCK_UNLOAD":51,"SE_U":27,"SE_UNLOCK":44,"SE_USE_ITEM":1,"SE_VEND":106,"SE_WALL_HIT":7,"SE_WARP_IN":45,"SE_WARP_OUT":46,"SE_WIN_OPEN":6,"SPECIAL_FLAGS_END":16511,"SPECIAL_FLAGS_START":16384,"SPECIES_ABRA":63,"SPECIES_ABSOL":376,"SPECIES_AERODACTYL":142,"SPECIES_AGGRON":384,"SPECIES_AIPOM":190,"SPECIES_ALAKAZAM":65,"SPECIES_ALTARIA":359,"SPECIES_AMPHAROS":181,"SPECIES_ANORITH":390,"SPECIES_ARBOK":24,"SPECIES_ARCANINE":59,"SPECIES_ARIADOS":168,"SPECIES_ARMALDO":391,"SPECIES_ARON":382,"SPECIES_ARTICUNO":144,"SPECIES_AZUMARILL":184,"SPECIES_AZURILL":350,"SPECIES_BAGON":395,"SPECIES_BALTOY":318,"SPECIES_BANETTE":378,"SPECIES_BARBOACH":323,"SPECIES_BAYLEEF":153,"SPECIES_BEAUTIFLY":292,"SPECIES_BEEDRILL":15,"SPECIES_BELDUM":398,"SPECIES_BELLOSSOM":182,"SPECIES_BELLSPROUT":69,"SPECIES_BLASTOISE":9,"SPECIES_BLAZIKEN":282,"SPECIES_BLISSEY":242,"SPECIES_BRELOOM":307,"SPECIES_BULBASAUR":1,"SPECIES_BUTTERFREE":12,"SPECIES_CACNEA":344,"SPECIES_CACTURNE":345,"SPECIES_CAMERUPT":340,"SPECIES_CARVANHA":330,"SPECIES_CASCOON":293,"SPECIES_CASTFORM":385,"SPECIES_CATERPIE":10,"SPECIES_CELEBI":251,"SPECIES_CHANSEY":113,"SPECIES_CHARIZARD":6,"SPECIES_CHARMANDER":4,"SPECIES_CHARMELEON":5,"SPECIES_CHIKORITA":152,"SPECIES_CHIMECHO":411,"SPECIES_CHINCHOU":170,"SPECIES_CLAMPERL":373,"SPECIES_CLAYDOL":319,"SPECIES_CLEFABLE":36,"SPECIES_CLEFAIRY":35,"SPECIES_CLEFFA":173,"SPECIES_CLOYSTER":91,"SPECIES_COMBUSKEN":281,"SPECIES_CORPHISH":326,"SPECIES_CORSOLA":222,"SPECIES_CRADILY":389,"SPECIES_CRAWDAUNT":327,"SPECIES_CROBAT":169,"SPECIES_CROCONAW":159,"SPECIES_CUBONE":104,"SPECIES_CYNDAQUIL":155,"SPECIES_DELCATTY":316,"SPECIES_DELIBIRD":225,"SPECIES_DEOXYS":410,"SPECIES_DEWGONG":87,"SPECIES_DIGLETT":50,"SPECIES_DITTO":132,"SPECIES_DODRIO":85,"SPECIES_DODUO":84,"SPECIES_DONPHAN":232,"SPECIES_DRAGONAIR":148,"SPECIES_DRAGONITE":149,"SPECIES_DRATINI":147,"SPECIES_DROWZEE":96,"SPECIES_DUGTRIO":51,"SPECIES_DUNSPARCE":206,"SPECIES_DUSCLOPS":362,"SPECIES_DUSKULL":361,"SPECIES_DUSTOX":294,"SPECIES_EEVEE":133,"SPECIES_EGG":412,"SPECIES_EKANS":23,"SPECIES_ELECTABUZZ":125,"SPECIES_ELECTRIKE":337,"SPECIES_ELECTRODE":101,"SPECIES_ELEKID":239,"SPECIES_ENTEI":244,"SPECIES_ESPEON":196,"SPECIES_EXEGGCUTE":102,"SPECIES_EXEGGUTOR":103,"SPECIES_EXPLOUD":372,"SPECIES_FARFETCHD":83,"SPECIES_FEAROW":22,"SPECIES_FEEBAS":328,"SPECIES_FERALIGATR":160,"SPECIES_FLAAFFY":180,"SPECIES_FLAREON":136,"SPECIES_FLYGON":334,"SPECIES_FORRETRESS":205,"SPECIES_FURRET":162,"SPECIES_GARDEVOIR":394,"SPECIES_GASTLY":92,"SPECIES_GENGAR":94,"SPECIES_GEODUDE":74,"SPECIES_GIRAFARIG":203,"SPECIES_GLALIE":347,"SPECIES_GLIGAR":207,"SPECIES_GLOOM":44,"SPECIES_GOLBAT":42,"SPECIES_GOLDEEN":118,"SPECIES_GOLDUCK":55,"SPECIES_GOLEM":76,"SPECIES_GOREBYSS":375,"SPECIES_GRANBULL":210,"SPECIES_GRAVELER":75,"SPECIES_GRIMER":88,"SPECIES_GROUDON":405,"SPECIES_GROVYLE":278,"SPECIES_GROWLITHE":58,"SPECIES_GRUMPIG":352,"SPECIES_GULPIN":367,"SPECIES_GYARADOS":130,"SPECIES_HARIYAMA":336,"SPECIES_HAUNTER":93,"SPECIES_HERACROSS":214,"SPECIES_HITMONCHAN":107,"SPECIES_HITMONLEE":106,"SPECIES_HITMONTOP":237,"SPECIES_HOOTHOOT":163,"SPECIES_HOPPIP":187,"SPECIES_HORSEA":116,"SPECIES_HOUNDOOM":229,"SPECIES_HOUNDOUR":228,"SPECIES_HO_OH":250,"SPECIES_HUNTAIL":374,"SPECIES_HYPNO":97,"SPECIES_IGGLYBUFF":174,"SPECIES_ILLUMISE":387,"SPECIES_IVYSAUR":2,"SPECIES_JIGGLYPUFF":39,"SPECIES_JIRACHI":409,"SPECIES_JOLTEON":135,"SPECIES_JUMPLUFF":189,"SPECIES_JYNX":124,"SPECIES_KABUTO":140,"SPECIES_KABUTOPS":141,"SPECIES_KADABRA":64,"SPECIES_KAKUNA":14,"SPECIES_KANGASKHAN":115,"SPECIES_KECLEON":317,"SPECIES_KINGDRA":230,"SPECIES_KINGLER":99,"SPECIES_KIRLIA":393,"SPECIES_KOFFING":109,"SPECIES_KRABBY":98,"SPECIES_KYOGRE":404,"SPECIES_LAIRON":383,"SPECIES_LANTURN":171,"SPECIES_LAPRAS":131,"SPECIES_LARVITAR":246,"SPECIES_LATIAS":407,"SPECIES_LATIOS":408,"SPECIES_LEDIAN":166,"SPECIES_LEDYBA":165,"SPECIES_LICKITUNG":108,"SPECIES_LILEEP":388,"SPECIES_LINOONE":289,"SPECIES_LOMBRE":296,"SPECIES_LOTAD":295,"SPECIES_LOUDRED":371,"SPECIES_LUDICOLO":297,"SPECIES_LUGIA":249,"SPECIES_LUNATONE":348,"SPECIES_LUVDISC":325,"SPECIES_MACHAMP":68,"SPECIES_MACHOKE":67,"SPECIES_MACHOP":66,"SPECIES_MAGBY":240,"SPECIES_MAGCARGO":219,"SPECIES_MAGIKARP":129,"SPECIES_MAGMAR":126,"SPECIES_MAGNEMITE":81,"SPECIES_MAGNETON":82,"SPECIES_MAKUHITA":335,"SPECIES_MANECTRIC":338,"SPECIES_MANKEY":56,"SPECIES_MANTINE":226,"SPECIES_MAREEP":179,"SPECIES_MARILL":183,"SPECIES_MAROWAK":105,"SPECIES_MARSHTOMP":284,"SPECIES_MASQUERAIN":312,"SPECIES_MAWILE":355,"SPECIES_MEDICHAM":357,"SPECIES_MEDITITE":356,"SPECIES_MEGANIUM":154,"SPECIES_MEOWTH":52,"SPECIES_METAGROSS":400,"SPECIES_METANG":399,"SPECIES_METAPOD":11,"SPECIES_MEW":151,"SPECIES_MEWTWO":150,"SPECIES_MIGHTYENA":287,"SPECIES_MILOTIC":329,"SPECIES_MILTANK":241,"SPECIES_MINUN":354,"SPECIES_MISDREAVUS":200,"SPECIES_MOLTRES":146,"SPECIES_MR_MIME":122,"SPECIES_MUDKIP":283,"SPECIES_MUK":89,"SPECIES_MURKROW":198,"SPECIES_NATU":177,"SPECIES_NIDOKING":34,"SPECIES_NIDOQUEEN":31,"SPECIES_NIDORAN_F":29,"SPECIES_NIDORAN_M":32,"SPECIES_NIDORINA":30,"SPECIES_NIDORINO":33,"SPECIES_NINCADA":301,"SPECIES_NINETALES":38,"SPECIES_NINJASK":302,"SPECIES_NOCTOWL":164,"SPECIES_NONE":0,"SPECIES_NOSEPASS":320,"SPECIES_NUMEL":339,"SPECIES_NUZLEAF":299,"SPECIES_OCTILLERY":224,"SPECIES_ODDISH":43,"SPECIES_OLD_UNOWN_B":252,"SPECIES_OLD_UNOWN_C":253,"SPECIES_OLD_UNOWN_D":254,"SPECIES_OLD_UNOWN_E":255,"SPECIES_OLD_UNOWN_F":256,"SPECIES_OLD_UNOWN_G":257,"SPECIES_OLD_UNOWN_H":258,"SPECIES_OLD_UNOWN_I":259,"SPECIES_OLD_UNOWN_J":260,"SPECIES_OLD_UNOWN_K":261,"SPECIES_OLD_UNOWN_L":262,"SPECIES_OLD_UNOWN_M":263,"SPECIES_OLD_UNOWN_N":264,"SPECIES_OLD_UNOWN_O":265,"SPECIES_OLD_UNOWN_P":266,"SPECIES_OLD_UNOWN_Q":267,"SPECIES_OLD_UNOWN_R":268,"SPECIES_OLD_UNOWN_S":269,"SPECIES_OLD_UNOWN_T":270,"SPECIES_OLD_UNOWN_U":271,"SPECIES_OLD_UNOWN_V":272,"SPECIES_OLD_UNOWN_W":273,"SPECIES_OLD_UNOWN_X":274,"SPECIES_OLD_UNOWN_Y":275,"SPECIES_OLD_UNOWN_Z":276,"SPECIES_OMANYTE":138,"SPECIES_OMASTAR":139,"SPECIES_ONIX":95,"SPECIES_PARAS":46,"SPECIES_PARASECT":47,"SPECIES_PELIPPER":310,"SPECIES_PERSIAN":53,"SPECIES_PHANPY":231,"SPECIES_PICHU":172,"SPECIES_PIDGEOT":18,"SPECIES_PIDGEOTTO":17,"SPECIES_PIDGEY":16,"SPECIES_PIKACHU":25,"SPECIES_PILOSWINE":221,"SPECIES_PINECO":204,"SPECIES_PINSIR":127,"SPECIES_PLUSLE":353,"SPECIES_POLITOED":186,"SPECIES_POLIWAG":60,"SPECIES_POLIWHIRL":61,"SPECIES_POLIWRATH":62,"SPECIES_PONYTA":77,"SPECIES_POOCHYENA":286,"SPECIES_PORYGON":137,"SPECIES_PORYGON2":233,"SPECIES_PRIMEAPE":57,"SPECIES_PSYDUCK":54,"SPECIES_PUPITAR":247,"SPECIES_QUAGSIRE":195,"SPECIES_QUILAVA":156,"SPECIES_QWILFISH":211,"SPECIES_RAICHU":26,"SPECIES_RAIKOU":243,"SPECIES_RALTS":392,"SPECIES_RAPIDASH":78,"SPECIES_RATICATE":20,"SPECIES_RATTATA":19,"SPECIES_RAYQUAZA":406,"SPECIES_REGICE":402,"SPECIES_REGIROCK":401,"SPECIES_REGISTEEL":403,"SPECIES_RELICANTH":381,"SPECIES_REMORAID":223,"SPECIES_RHYDON":112,"SPECIES_RHYHORN":111,"SPECIES_ROSELIA":363,"SPECIES_SABLEYE":322,"SPECIES_SALAMENCE":397,"SPECIES_SANDSHREW":27,"SPECIES_SANDSLASH":28,"SPECIES_SCEPTILE":279,"SPECIES_SCIZOR":212,"SPECIES_SCYTHER":123,"SPECIES_SEADRA":117,"SPECIES_SEAKING":119,"SPECIES_SEALEO":342,"SPECIES_SEEDOT":298,"SPECIES_SEEL":86,"SPECIES_SENTRET":161,"SPECIES_SEVIPER":379,"SPECIES_SHARPEDO":331,"SPECIES_SHEDINJA":303,"SPECIES_SHELGON":396,"SPECIES_SHELLDER":90,"SPECIES_SHIFTRY":300,"SPECIES_SHROOMISH":306,"SPECIES_SHUCKLE":213,"SPECIES_SHUPPET":377,"SPECIES_SILCOON":291,"SPECIES_SKARMORY":227,"SPECIES_SKIPLOOM":188,"SPECIES_SKITTY":315,"SPECIES_SLAKING":366,"SPECIES_SLAKOTH":364,"SPECIES_SLOWBRO":80,"SPECIES_SLOWKING":199,"SPECIES_SLOWPOKE":79,"SPECIES_SLUGMA":218,"SPECIES_SMEARGLE":235,"SPECIES_SMOOCHUM":238,"SPECIES_SNEASEL":215,"SPECIES_SNORLAX":143,"SPECIES_SNORUNT":346,"SPECIES_SNUBBULL":209,"SPECIES_SOLROCK":349,"SPECIES_SPEAROW":21,"SPECIES_SPHEAL":341,"SPECIES_SPINARAK":167,"SPECIES_SPINDA":308,"SPECIES_SPOINK":351,"SPECIES_SQUIRTLE":7,"SPECIES_STANTLER":234,"SPECIES_STARMIE":121,"SPECIES_STARYU":120,"SPECIES_STEELIX":208,"SPECIES_SUDOWOODO":185,"SPECIES_SUICUNE":245,"SPECIES_SUNFLORA":192,"SPECIES_SUNKERN":191,"SPECIES_SURSKIT":311,"SPECIES_SWABLU":358,"SPECIES_SWALOT":368,"SPECIES_SWAMPERT":285,"SPECIES_SWELLOW":305,"SPECIES_SWINUB":220,"SPECIES_TAILLOW":304,"SPECIES_TANGELA":114,"SPECIES_TAUROS":128,"SPECIES_TEDDIURSA":216,"SPECIES_TENTACOOL":72,"SPECIES_TENTACRUEL":73,"SPECIES_TOGEPI":175,"SPECIES_TOGETIC":176,"SPECIES_TORCHIC":280,"SPECIES_TORKOAL":321,"SPECIES_TOTODILE":158,"SPECIES_TRAPINCH":332,"SPECIES_TREECKO":277,"SPECIES_TROPIUS":369,"SPECIES_TYPHLOSION":157,"SPECIES_TYRANITAR":248,"SPECIES_TYROGUE":236,"SPECIES_UMBREON":197,"SPECIES_UNOWN":201,"SPECIES_UNOWN_B":413,"SPECIES_UNOWN_C":414,"SPECIES_UNOWN_D":415,"SPECIES_UNOWN_E":416,"SPECIES_UNOWN_EMARK":438,"SPECIES_UNOWN_F":417,"SPECIES_UNOWN_G":418,"SPECIES_UNOWN_H":419,"SPECIES_UNOWN_I":420,"SPECIES_UNOWN_J":421,"SPECIES_UNOWN_K":422,"SPECIES_UNOWN_L":423,"SPECIES_UNOWN_M":424,"SPECIES_UNOWN_N":425,"SPECIES_UNOWN_O":426,"SPECIES_UNOWN_P":427,"SPECIES_UNOWN_Q":428,"SPECIES_UNOWN_QMARK":439,"SPECIES_UNOWN_R":429,"SPECIES_UNOWN_S":430,"SPECIES_UNOWN_T":431,"SPECIES_UNOWN_U":432,"SPECIES_UNOWN_V":433,"SPECIES_UNOWN_W":434,"SPECIES_UNOWN_X":435,"SPECIES_UNOWN_Y":436,"SPECIES_UNOWN_Z":437,"SPECIES_URSARING":217,"SPECIES_VAPOREON":134,"SPECIES_VENOMOTH":49,"SPECIES_VENONAT":48,"SPECIES_VENUSAUR":3,"SPECIES_VIBRAVA":333,"SPECIES_VICTREEBEL":71,"SPECIES_VIGOROTH":365,"SPECIES_VILEPLUME":45,"SPECIES_VOLBEAT":386,"SPECIES_VOLTORB":100,"SPECIES_VULPIX":37,"SPECIES_WAILMER":313,"SPECIES_WAILORD":314,"SPECIES_WALREIN":343,"SPECIES_WARTORTLE":8,"SPECIES_WEEDLE":13,"SPECIES_WEEPINBELL":70,"SPECIES_WEEZING":110,"SPECIES_WHISCASH":324,"SPECIES_WHISMUR":370,"SPECIES_WIGGLYTUFF":40,"SPECIES_WINGULL":309,"SPECIES_WOBBUFFET":202,"SPECIES_WOOPER":194,"SPECIES_WURMPLE":290,"SPECIES_WYNAUT":360,"SPECIES_XATU":178,"SPECIES_YANMA":193,"SPECIES_ZANGOOSE":380,"SPECIES_ZAPDOS":145,"SPECIES_ZIGZAGOON":288,"SPECIES_ZUBAT":41,"SUPER_ROD":2,"SYSTEM_FLAGS":2144,"TEMP_FLAGS_END":31,"TEMP_FLAGS_START":0,"TRAINERS_COUNT":855,"TRAINER_AARON":397,"TRAINER_ABIGAIL_1":358,"TRAINER_ABIGAIL_2":360,"TRAINER_ABIGAIL_3":361,"TRAINER_ABIGAIL_4":362,"TRAINER_ABIGAIL_5":363,"TRAINER_AIDAN":674,"TRAINER_AISHA":757,"TRAINER_ALAN":630,"TRAINER_ALBERT":80,"TRAINER_ALBERTO":12,"TRAINER_ALEX":413,"TRAINER_ALEXA":670,"TRAINER_ALEXIA":90,"TRAINER_ALEXIS":248,"TRAINER_ALICE":448,"TRAINER_ALIX":750,"TRAINER_ALLEN":333,"TRAINER_ALLISON":387,"TRAINER_ALVARO":849,"TRAINER_ALYSSA":701,"TRAINER_AMY_AND_LIV_1":481,"TRAINER_AMY_AND_LIV_2":482,"TRAINER_AMY_AND_LIV_3":485,"TRAINER_AMY_AND_LIV_4":487,"TRAINER_AMY_AND_LIV_5":488,"TRAINER_AMY_AND_LIV_6":489,"TRAINER_ANABEL":805,"TRAINER_ANDREA":613,"TRAINER_ANDRES_1":737,"TRAINER_ANDRES_2":812,"TRAINER_ANDRES_3":813,"TRAINER_ANDRES_4":814,"TRAINER_ANDRES_5":815,"TRAINER_ANDREW":336,"TRAINER_ANGELICA":436,"TRAINER_ANGELINA":712,"TRAINER_ANGELO":802,"TRAINER_ANNA_AND_MEG_1":287,"TRAINER_ANNA_AND_MEG_2":288,"TRAINER_ANNA_AND_MEG_3":289,"TRAINER_ANNA_AND_MEG_4":290,"TRAINER_ANNA_AND_MEG_5":291,"TRAINER_ANNIKA":502,"TRAINER_ANTHONY":352,"TRAINER_ARCHIE":34,"TRAINER_ASHLEY":655,"TRAINER_ATHENA":577,"TRAINER_ATSUSHI":190,"TRAINER_AURON":506,"TRAINER_AUSTINA":58,"TRAINER_AUTUMN":217,"TRAINER_AXLE":203,"TRAINER_BARNY":343,"TRAINER_BARRY":163,"TRAINER_BEAU":212,"TRAINER_BECK":414,"TRAINER_BECKY":470,"TRAINER_BEN":323,"TRAINER_BENJAMIN_1":353,"TRAINER_BENJAMIN_2":354,"TRAINER_BENJAMIN_3":355,"TRAINER_BENJAMIN_4":356,"TRAINER_BENJAMIN_5":357,"TRAINER_BENNY":407,"TRAINER_BERKE":74,"TRAINER_BERNIE_1":206,"TRAINER_BERNIE_2":207,"TRAINER_BERNIE_3":208,"TRAINER_BERNIE_4":209,"TRAINER_BERNIE_5":210,"TRAINER_BETH":445,"TRAINER_BETHANY":301,"TRAINER_BEVERLY":441,"TRAINER_BIANCA":706,"TRAINER_BILLY":319,"TRAINER_BLAKE":235,"TRAINER_BRANDEN":745,"TRAINER_BRANDI":756,"TRAINER_BRANDON":811,"TRAINER_BRAWLY_1":266,"TRAINER_BRAWLY_2":774,"TRAINER_BRAWLY_3":775,"TRAINER_BRAWLY_4":776,"TRAINER_BRAWLY_5":777,"TRAINER_BRAXTON":75,"TRAINER_BRENDA":454,"TRAINER_BRENDAN_LILYCOVE_MUDKIP":661,"TRAINER_BRENDAN_LILYCOVE_TORCHIC":663,"TRAINER_BRENDAN_LILYCOVE_TREECKO":662,"TRAINER_BRENDAN_PLACEHOLDER":853,"TRAINER_BRENDAN_ROUTE_103_MUDKIP":520,"TRAINER_BRENDAN_ROUTE_103_TORCHIC":526,"TRAINER_BRENDAN_ROUTE_103_TREECKO":523,"TRAINER_BRENDAN_ROUTE_110_MUDKIP":521,"TRAINER_BRENDAN_ROUTE_110_TORCHIC":527,"TRAINER_BRENDAN_ROUTE_110_TREECKO":524,"TRAINER_BRENDAN_ROUTE_119_MUDKIP":522,"TRAINER_BRENDAN_ROUTE_119_TORCHIC":528,"TRAINER_BRENDAN_ROUTE_119_TREECKO":525,"TRAINER_BRENDAN_RUSTBORO_MUDKIP":593,"TRAINER_BRENDAN_RUSTBORO_TORCHIC":599,"TRAINER_BRENDAN_RUSTBORO_TREECKO":592,"TRAINER_BRENDEN":572,"TRAINER_BRENT":223,"TRAINER_BRIANNA":118,"TRAINER_BRICE":626,"TRAINER_BRIDGET":129,"TRAINER_BROOKE_1":94,"TRAINER_BROOKE_2":101,"TRAINER_BROOKE_3":102,"TRAINER_BROOKE_4":103,"TRAINER_BROOKE_5":104,"TRAINER_BRYAN":744,"TRAINER_BRYANT":746,"TRAINER_CALE":764,"TRAINER_CALLIE":763,"TRAINER_CALVIN_1":318,"TRAINER_CALVIN_2":328,"TRAINER_CALVIN_3":329,"TRAINER_CALVIN_4":330,"TRAINER_CALVIN_5":331,"TRAINER_CAMDEN":374,"TRAINER_CAMERON_1":238,"TRAINER_CAMERON_2":239,"TRAINER_CAMERON_3":240,"TRAINER_CAMERON_4":241,"TRAINER_CAMERON_5":242,"TRAINER_CAMRON":739,"TRAINER_CARLEE":464,"TRAINER_CAROL":471,"TRAINER_CAROLINA":741,"TRAINER_CAROLINE":99,"TRAINER_CARTER":345,"TRAINER_CATHERINE_1":559,"TRAINER_CATHERINE_2":562,"TRAINER_CATHERINE_3":563,"TRAINER_CATHERINE_4":564,"TRAINER_CATHERINE_5":565,"TRAINER_CEDRIC":475,"TRAINER_CELIA":743,"TRAINER_CELINA":705,"TRAINER_CHAD":174,"TRAINER_CHANDLER":698,"TRAINER_CHARLIE":66,"TRAINER_CHARLOTTE":714,"TRAINER_CHASE":378,"TRAINER_CHESTER":408,"TRAINER_CHIP":45,"TRAINER_CHRIS":693,"TRAINER_CINDY_1":114,"TRAINER_CINDY_2":117,"TRAINER_CINDY_3":120,"TRAINER_CINDY_4":121,"TRAINER_CINDY_5":122,"TRAINER_CINDY_6":123,"TRAINER_CLARENCE":580,"TRAINER_CLARISSA":435,"TRAINER_CLARK":631,"TRAINER_CLAUDE":338,"TRAINER_CLIFFORD":584,"TRAINER_COBY":709,"TRAINER_COLE":201,"TRAINER_COLIN":405,"TRAINER_COLTON":294,"TRAINER_CONNIE":128,"TRAINER_CONOR":511,"TRAINER_CORA":428,"TRAINER_CORY_1":740,"TRAINER_CORY_2":816,"TRAINER_CORY_3":817,"TRAINER_CORY_4":818,"TRAINER_CORY_5":819,"TRAINER_CRISSY":614,"TRAINER_CRISTIAN":574,"TRAINER_CRISTIN_1":767,"TRAINER_CRISTIN_2":828,"TRAINER_CRISTIN_3":829,"TRAINER_CRISTIN_4":830,"TRAINER_CRISTIN_5":831,"TRAINER_CYNDY_1":427,"TRAINER_CYNDY_2":430,"TRAINER_CYNDY_3":431,"TRAINER_CYNDY_4":432,"TRAINER_CYNDY_5":433,"TRAINER_DAISUKE":189,"TRAINER_DAISY":36,"TRAINER_DALE":341,"TRAINER_DALTON_1":196,"TRAINER_DALTON_2":197,"TRAINER_DALTON_3":198,"TRAINER_DALTON_4":199,"TRAINER_DALTON_5":200,"TRAINER_DANA":458,"TRAINER_DANIELLE":650,"TRAINER_DAPHNE":115,"TRAINER_DARCY":733,"TRAINER_DARIAN":696,"TRAINER_DARIUS":803,"TRAINER_DARRIN":154,"TRAINER_DAVID":158,"TRAINER_DAVIS":539,"TRAINER_DAWSON":694,"TRAINER_DAYTON":760,"TRAINER_DEAN":164,"TRAINER_DEANDRE":715,"TRAINER_DEBRA":460,"TRAINER_DECLAN":15,"TRAINER_DEMETRIUS":375,"TRAINER_DENISE":444,"TRAINER_DEREK":227,"TRAINER_DEVAN":753,"TRAINER_DEZ_AND_LUKE":640,"TRAINER_DIANA_1":474,"TRAINER_DIANA_2":477,"TRAINER_DIANA_3":478,"TRAINER_DIANA_4":479,"TRAINER_DIANA_5":480,"TRAINER_DIANNE":417,"TRAINER_DILLON":327,"TRAINER_DOMINIK":152,"TRAINER_DONALD":224,"TRAINER_DONNY":384,"TRAINER_DOUG":618,"TRAINER_DOUGLAS":153,"TRAINER_DRAKE":264,"TRAINER_DREW":211,"TRAINER_DUDLEY":173,"TRAINER_DUNCAN":496,"TRAINER_DUSTY_1":44,"TRAINER_DUSTY_2":47,"TRAINER_DUSTY_3":48,"TRAINER_DUSTY_4":49,"TRAINER_DUSTY_5":50,"TRAINER_DWAYNE":493,"TRAINER_DYLAN_1":364,"TRAINER_DYLAN_2":365,"TRAINER_DYLAN_3":366,"TRAINER_DYLAN_4":367,"TRAINER_DYLAN_5":368,"TRAINER_ED":13,"TRAINER_EDDIE":332,"TRAINER_EDGAR":79,"TRAINER_EDMOND":491,"TRAINER_EDWARD":232,"TRAINER_EDWARDO":404,"TRAINER_EDWIN_1":512,"TRAINER_EDWIN_2":515,"TRAINER_EDWIN_3":516,"TRAINER_EDWIN_4":517,"TRAINER_EDWIN_5":518,"TRAINER_ELI":501,"TRAINER_ELIJAH":742,"TRAINER_ELLIOT_1":339,"TRAINER_ELLIOT_2":346,"TRAINER_ELLIOT_3":347,"TRAINER_ELLIOT_4":348,"TRAINER_ELLIOT_5":349,"TRAINER_ERIC":632,"TRAINER_ERNEST_1":492,"TRAINER_ERNEST_2":497,"TRAINER_ERNEST_3":498,"TRAINER_ERNEST_4":499,"TRAINER_ERNEST_5":500,"TRAINER_ETHAN_1":216,"TRAINER_ETHAN_2":219,"TRAINER_ETHAN_3":220,"TRAINER_ETHAN_4":221,"TRAINER_ETHAN_5":222,"TRAINER_EVERETT":850,"TRAINER_FABIAN":759,"TRAINER_FELIX":38,"TRAINER_FERNANDO_1":195,"TRAINER_FERNANDO_2":832,"TRAINER_FERNANDO_3":833,"TRAINER_FERNANDO_4":834,"TRAINER_FERNANDO_5":835,"TRAINER_FLAGS_END":2143,"TRAINER_FLAGS_START":1280,"TRAINER_FLANNERY_1":268,"TRAINER_FLANNERY_2":782,"TRAINER_FLANNERY_3":783,"TRAINER_FLANNERY_4":784,"TRAINER_FLANNERY_5":785,"TRAINER_FLINT":654,"TRAINER_FOSTER":46,"TRAINER_FRANKLIN":170,"TRAINER_FREDRICK":29,"TRAINER_GABBY_AND_TY_1":51,"TRAINER_GABBY_AND_TY_2":52,"TRAINER_GABBY_AND_TY_3":53,"TRAINER_GABBY_AND_TY_4":54,"TRAINER_GABBY_AND_TY_5":55,"TRAINER_GABBY_AND_TY_6":56,"TRAINER_GABRIELLE_1":9,"TRAINER_GABRIELLE_2":840,"TRAINER_GABRIELLE_3":841,"TRAINER_GABRIELLE_4":842,"TRAINER_GABRIELLE_5":843,"TRAINER_GARRET":138,"TRAINER_GARRISON":547,"TRAINER_GEORGE":73,"TRAINER_GEORGIA":281,"TRAINER_GERALD":648,"TRAINER_GILBERT":169,"TRAINER_GINA_AND_MIA_1":483,"TRAINER_GINA_AND_MIA_2":486,"TRAINER_GLACIA":263,"TRAINER_GRACE":450,"TRAINER_GREG":619,"TRAINER_GRETA":808,"TRAINER_GRUNT_AQUA_HIDEOUT_1":2,"TRAINER_GRUNT_AQUA_HIDEOUT_2":3,"TRAINER_GRUNT_AQUA_HIDEOUT_3":4,"TRAINER_GRUNT_AQUA_HIDEOUT_4":5,"TRAINER_GRUNT_AQUA_HIDEOUT_5":27,"TRAINER_GRUNT_AQUA_HIDEOUT_6":28,"TRAINER_GRUNT_AQUA_HIDEOUT_7":192,"TRAINER_GRUNT_AQUA_HIDEOUT_8":193,"TRAINER_GRUNT_JAGGED_PASS":570,"TRAINER_GRUNT_MAGMA_HIDEOUT_1":716,"TRAINER_GRUNT_MAGMA_HIDEOUT_10":725,"TRAINER_GRUNT_MAGMA_HIDEOUT_11":726,"TRAINER_GRUNT_MAGMA_HIDEOUT_12":727,"TRAINER_GRUNT_MAGMA_HIDEOUT_13":728,"TRAINER_GRUNT_MAGMA_HIDEOUT_14":729,"TRAINER_GRUNT_MAGMA_HIDEOUT_15":730,"TRAINER_GRUNT_MAGMA_HIDEOUT_16":731,"TRAINER_GRUNT_MAGMA_HIDEOUT_2":717,"TRAINER_GRUNT_MAGMA_HIDEOUT_3":718,"TRAINER_GRUNT_MAGMA_HIDEOUT_4":719,"TRAINER_GRUNT_MAGMA_HIDEOUT_5":720,"TRAINER_GRUNT_MAGMA_HIDEOUT_6":721,"TRAINER_GRUNT_MAGMA_HIDEOUT_7":722,"TRAINER_GRUNT_MAGMA_HIDEOUT_8":723,"TRAINER_GRUNT_MAGMA_HIDEOUT_9":724,"TRAINER_GRUNT_MT_CHIMNEY_1":146,"TRAINER_GRUNT_MT_CHIMNEY_2":579,"TRAINER_GRUNT_MT_PYRE_1":23,"TRAINER_GRUNT_MT_PYRE_2":24,"TRAINER_GRUNT_MT_PYRE_3":25,"TRAINER_GRUNT_MT_PYRE_4":569,"TRAINER_GRUNT_MUSEUM_1":20,"TRAINER_GRUNT_MUSEUM_2":21,"TRAINER_GRUNT_PETALBURG_WOODS":10,"TRAINER_GRUNT_RUSTURF_TUNNEL":16,"TRAINER_GRUNT_SEAFLOOR_CAVERN_1":6,"TRAINER_GRUNT_SEAFLOOR_CAVERN_2":7,"TRAINER_GRUNT_SEAFLOOR_CAVERN_3":8,"TRAINER_GRUNT_SEAFLOOR_CAVERN_4":14,"TRAINER_GRUNT_SEAFLOOR_CAVERN_5":567,"TRAINER_GRUNT_SPACE_CENTER_1":22,"TRAINER_GRUNT_SPACE_CENTER_2":116,"TRAINER_GRUNT_SPACE_CENTER_3":586,"TRAINER_GRUNT_SPACE_CENTER_4":587,"TRAINER_GRUNT_SPACE_CENTER_5":588,"TRAINER_GRUNT_SPACE_CENTER_6":589,"TRAINER_GRUNT_SPACE_CENTER_7":590,"TRAINER_GRUNT_UNUSED":568,"TRAINER_GRUNT_WEATHER_INST_1":17,"TRAINER_GRUNT_WEATHER_INST_2":18,"TRAINER_GRUNT_WEATHER_INST_3":19,"TRAINER_GRUNT_WEATHER_INST_4":26,"TRAINER_GRUNT_WEATHER_INST_5":596,"TRAINER_GWEN":59,"TRAINER_HAILEY":697,"TRAINER_HALEY_1":604,"TRAINER_HALEY_2":607,"TRAINER_HALEY_3":608,"TRAINER_HALEY_4":609,"TRAINER_HALEY_5":610,"TRAINER_HALLE":546,"TRAINER_HANNAH":244,"TRAINER_HARRISON":578,"TRAINER_HAYDEN":707,"TRAINER_HECTOR":513,"TRAINER_HEIDI":469,"TRAINER_HELENE":751,"TRAINER_HENRY":668,"TRAINER_HERMAN":167,"TRAINER_HIDEO":651,"TRAINER_HITOSHI":180,"TRAINER_HOPE":96,"TRAINER_HUDSON":510,"TRAINER_HUEY":490,"TRAINER_HUGH":399,"TRAINER_HUMBERTO":402,"TRAINER_IMANI":442,"TRAINER_IRENE":476,"TRAINER_ISAAC_1":538,"TRAINER_ISAAC_2":541,"TRAINER_ISAAC_3":542,"TRAINER_ISAAC_4":543,"TRAINER_ISAAC_5":544,"TRAINER_ISABELLA":595,"TRAINER_ISABELLE":736,"TRAINER_ISABEL_1":302,"TRAINER_ISABEL_2":303,"TRAINER_ISABEL_3":304,"TRAINER_ISABEL_4":305,"TRAINER_ISABEL_5":306,"TRAINER_ISAIAH_1":376,"TRAINER_ISAIAH_2":379,"TRAINER_ISAIAH_3":380,"TRAINER_ISAIAH_4":381,"TRAINER_ISAIAH_5":382,"TRAINER_ISOBEL":383,"TRAINER_IVAN":337,"TRAINER_JACE":204,"TRAINER_JACK":172,"TRAINER_JACKI_1":249,"TRAINER_JACKI_2":250,"TRAINER_JACKI_3":251,"TRAINER_JACKI_4":252,"TRAINER_JACKI_5":253,"TRAINER_JACKSON_1":552,"TRAINER_JACKSON_2":555,"TRAINER_JACKSON_3":556,"TRAINER_JACKSON_4":557,"TRAINER_JACKSON_5":558,"TRAINER_JACLYN":243,"TRAINER_JACOB":351,"TRAINER_JAIDEN":749,"TRAINER_JAMES_1":621,"TRAINER_JAMES_2":622,"TRAINER_JAMES_3":623,"TRAINER_JAMES_4":624,"TRAINER_JAMES_5":625,"TRAINER_JANI":418,"TRAINER_JANICE":605,"TRAINER_JARED":401,"TRAINER_JASMINE":359,"TRAINER_JAYLEN":326,"TRAINER_JAZMYN":503,"TRAINER_JEFF":202,"TRAINER_JEFFREY_1":226,"TRAINER_JEFFREY_2":228,"TRAINER_JEFFREY_3":229,"TRAINER_JEFFREY_4":230,"TRAINER_JEFFREY_5":231,"TRAINER_JENNA":560,"TRAINER_JENNIFER":95,"TRAINER_JENNY_1":449,"TRAINER_JENNY_2":465,"TRAINER_JENNY_3":466,"TRAINER_JENNY_4":467,"TRAINER_JENNY_5":468,"TRAINER_JEROME":156,"TRAINER_JERRY_1":273,"TRAINER_JERRY_2":276,"TRAINER_JERRY_3":277,"TRAINER_JERRY_4":278,"TRAINER_JERRY_5":279,"TRAINER_JESSICA_1":127,"TRAINER_JESSICA_2":132,"TRAINER_JESSICA_3":133,"TRAINER_JESSICA_4":134,"TRAINER_JESSICA_5":135,"TRAINER_JOCELYN":425,"TRAINER_JODY":91,"TRAINER_JOEY":322,"TRAINER_JOHANNA":647,"TRAINER_JOHNSON":754,"TRAINER_JOHN_AND_JAY_1":681,"TRAINER_JOHN_AND_JAY_2":682,"TRAINER_JOHN_AND_JAY_3":683,"TRAINER_JOHN_AND_JAY_4":684,"TRAINER_JOHN_AND_JAY_5":685,"TRAINER_JONAH":667,"TRAINER_JONAS":504,"TRAINER_JONATHAN":598,"TRAINER_JOSE":617,"TRAINER_JOSEPH":700,"TRAINER_JOSH":320,"TRAINER_JOSHUA":237,"TRAINER_JOSUE":738,"TRAINER_JUAN_1":272,"TRAINER_JUAN_2":798,"TRAINER_JUAN_3":799,"TRAINER_JUAN_4":800,"TRAINER_JUAN_5":801,"TRAINER_JULIE":100,"TRAINER_JULIO":566,"TRAINER_JUSTIN":215,"TRAINER_KAI":713,"TRAINER_KALEB":699,"TRAINER_KARA":457,"TRAINER_KAREN_1":280,"TRAINER_KAREN_2":282,"TRAINER_KAREN_3":283,"TRAINER_KAREN_4":284,"TRAINER_KAREN_5":285,"TRAINER_KATELYNN":325,"TRAINER_KATELYN_1":386,"TRAINER_KATELYN_2":388,"TRAINER_KATELYN_3":389,"TRAINER_KATELYN_4":390,"TRAINER_KATELYN_5":391,"TRAINER_KATE_AND_JOY":286,"TRAINER_KATHLEEN":583,"TRAINER_KATIE":455,"TRAINER_KAYLA":247,"TRAINER_KAYLEE":462,"TRAINER_KAYLEY":505,"TRAINER_KEEGAN":205,"TRAINER_KEIGO":652,"TRAINER_KEIRA":93,"TRAINER_KELVIN":507,"TRAINER_KENT":620,"TRAINER_KEVIN":171,"TRAINER_KIM_AND_IRIS":678,"TRAINER_KINDRA":106,"TRAINER_KIRA_AND_DAN_1":642,"TRAINER_KIRA_AND_DAN_2":643,"TRAINER_KIRA_AND_DAN_3":644,"TRAINER_KIRA_AND_DAN_4":645,"TRAINER_KIRA_AND_DAN_5":646,"TRAINER_KIRK":191,"TRAINER_KIYO":181,"TRAINER_KOICHI":182,"TRAINER_KOJI_1":672,"TRAINER_KOJI_2":824,"TRAINER_KOJI_3":825,"TRAINER_KOJI_4":826,"TRAINER_KOJI_5":827,"TRAINER_KYLA":443,"TRAINER_KYRA":748,"TRAINER_LAO_1":419,"TRAINER_LAO_2":421,"TRAINER_LAO_3":422,"TRAINER_LAO_4":423,"TRAINER_LAO_5":424,"TRAINER_LARRY":213,"TRAINER_LAURA":426,"TRAINER_LAUREL":463,"TRAINER_LAWRENCE":710,"TRAINER_LEAF":852,"TRAINER_LEAH":35,"TRAINER_LEA_AND_JED":641,"TRAINER_LENNY":628,"TRAINER_LEONARD":495,"TRAINER_LEONARDO":576,"TRAINER_LEONEL":762,"TRAINER_LEROY":77,"TRAINER_LILA_AND_ROY_1":687,"TRAINER_LILA_AND_ROY_2":688,"TRAINER_LILA_AND_ROY_3":689,"TRAINER_LILA_AND_ROY_4":690,"TRAINER_LILA_AND_ROY_5":691,"TRAINER_LILITH":573,"TRAINER_LINDA":461,"TRAINER_LISA_AND_RAY":692,"TRAINER_LOLA_1":57,"TRAINER_LOLA_2":60,"TRAINER_LOLA_3":61,"TRAINER_LOLA_4":62,"TRAINER_LOLA_5":63,"TRAINER_LORENZO":553,"TRAINER_LUCAS_1":629,"TRAINER_LUCAS_2":633,"TRAINER_LUCY":810,"TRAINER_LUIS":151,"TRAINER_LUNG":420,"TRAINER_LYDIA_1":545,"TRAINER_LYDIA_2":548,"TRAINER_LYDIA_3":549,"TRAINER_LYDIA_4":550,"TRAINER_LYDIA_5":551,"TRAINER_LYLE":616,"TRAINER_MACEY":591,"TRAINER_MADELINE_1":434,"TRAINER_MADELINE_2":437,"TRAINER_MADELINE_3":438,"TRAINER_MADELINE_4":439,"TRAINER_MADELINE_5":440,"TRAINER_MAKAYLA":758,"TRAINER_MARC":571,"TRAINER_MARCEL":11,"TRAINER_MARCOS":702,"TRAINER_MARIA_1":369,"TRAINER_MARIA_2":370,"TRAINER_MARIA_3":371,"TRAINER_MARIA_4":372,"TRAINER_MARIA_5":373,"TRAINER_MARIELA":848,"TRAINER_MARK":145,"TRAINER_MARLENE":752,"TRAINER_MARLEY":508,"TRAINER_MARTHA":473,"TRAINER_MARY":89,"TRAINER_MATT":30,"TRAINER_MATTHEW":157,"TRAINER_MAURA":246,"TRAINER_MAXIE_MAGMA_HIDEOUT":601,"TRAINER_MAXIE_MOSSDEEP":734,"TRAINER_MAXIE_MT_CHIMNEY":602,"TRAINER_MAY_LILYCOVE_MUDKIP":664,"TRAINER_MAY_LILYCOVE_TORCHIC":666,"TRAINER_MAY_LILYCOVE_TREECKO":665,"TRAINER_MAY_PLACEHOLDER":854,"TRAINER_MAY_ROUTE_103_MUDKIP":529,"TRAINER_MAY_ROUTE_103_TORCHIC":535,"TRAINER_MAY_ROUTE_103_TREECKO":532,"TRAINER_MAY_ROUTE_110_MUDKIP":530,"TRAINER_MAY_ROUTE_110_TORCHIC":536,"TRAINER_MAY_ROUTE_110_TREECKO":533,"TRAINER_MAY_ROUTE_119_MUDKIP":531,"TRAINER_MAY_ROUTE_119_TORCHIC":537,"TRAINER_MAY_ROUTE_119_TREECKO":534,"TRAINER_MAY_RUSTBORO_MUDKIP":600,"TRAINER_MAY_RUSTBORO_TORCHIC":769,"TRAINER_MAY_RUSTBORO_TREECKO":768,"TRAINER_MELINA":755,"TRAINER_MELISSA":124,"TRAINER_MEL_AND_PAUL":680,"TRAINER_MICAH":255,"TRAINER_MICHELLE":98,"TRAINER_MIGUEL_1":293,"TRAINER_MIGUEL_2":295,"TRAINER_MIGUEL_3":296,"TRAINER_MIGUEL_4":297,"TRAINER_MIGUEL_5":298,"TRAINER_MIKE_1":634,"TRAINER_MIKE_2":635,"TRAINER_MISSY":447,"TRAINER_MITCHELL":540,"TRAINER_MIU_AND_YUKI":484,"TRAINER_MOLLIE":137,"TRAINER_MYLES":765,"TRAINER_NANCY":472,"TRAINER_NAOMI":119,"TRAINER_NATE":582,"TRAINER_NED":340,"TRAINER_NICHOLAS":585,"TRAINER_NICOLAS_1":392,"TRAINER_NICOLAS_2":393,"TRAINER_NICOLAS_3":394,"TRAINER_NICOLAS_4":395,"TRAINER_NICOLAS_5":396,"TRAINER_NIKKI":453,"TRAINER_NOB_1":183,"TRAINER_NOB_2":184,"TRAINER_NOB_3":185,"TRAINER_NOB_4":186,"TRAINER_NOB_5":187,"TRAINER_NOLAN":342,"TRAINER_NOLAND":809,"TRAINER_NOLEN":161,"TRAINER_NONE":0,"TRAINER_NORMAN_1":269,"TRAINER_NORMAN_2":786,"TRAINER_NORMAN_3":787,"TRAINER_NORMAN_4":788,"TRAINER_NORMAN_5":789,"TRAINER_OLIVIA":130,"TRAINER_OWEN":83,"TRAINER_PABLO_1":377,"TRAINER_PABLO_2":820,"TRAINER_PABLO_3":821,"TRAINER_PABLO_4":822,"TRAINER_PABLO_5":823,"TRAINER_PARKER":72,"TRAINER_PAT":766,"TRAINER_PATRICIA":105,"TRAINER_PAUL":275,"TRAINER_PAULA":429,"TRAINER_PAXTON":594,"TRAINER_PERRY":398,"TRAINER_PETE":735,"TRAINER_PHIL":400,"TRAINER_PHILLIP":494,"TRAINER_PHOEBE":262,"TRAINER_PRESLEY":403,"TRAINER_PRESTON":233,"TRAINER_QUINCY":324,"TRAINER_RACHEL":761,"TRAINER_RANDALL":71,"TRAINER_RED":851,"TRAINER_REED":675,"TRAINER_RELI_AND_IAN":686,"TRAINER_REYNA":509,"TRAINER_RHETT":703,"TRAINER_RICHARD":166,"TRAINER_RICK":615,"TRAINER_RICKY_1":64,"TRAINER_RICKY_2":67,"TRAINER_RICKY_3":68,"TRAINER_RICKY_4":69,"TRAINER_RICKY_5":70,"TRAINER_RILEY":653,"TRAINER_ROBERT_1":406,"TRAINER_ROBERT_2":409,"TRAINER_ROBERT_3":410,"TRAINER_ROBERT_4":411,"TRAINER_ROBERT_5":412,"TRAINER_ROBIN":612,"TRAINER_RODNEY":165,"TRAINER_ROGER":669,"TRAINER_ROLAND":160,"TRAINER_RONALD":350,"TRAINER_ROSE_1":37,"TRAINER_ROSE_2":40,"TRAINER_ROSE_3":41,"TRAINER_ROSE_4":42,"TRAINER_ROSE_5":43,"TRAINER_ROXANNE_1":265,"TRAINER_ROXANNE_2":770,"TRAINER_ROXANNE_3":771,"TRAINER_ROXANNE_4":772,"TRAINER_ROXANNE_5":773,"TRAINER_RUBEN":671,"TRAINER_SALLY":611,"TRAINER_SAMANTHA":245,"TRAINER_SAMUEL":81,"TRAINER_SANTIAGO":168,"TRAINER_SARAH":695,"TRAINER_SAWYER_1":1,"TRAINER_SAWYER_2":836,"TRAINER_SAWYER_3":837,"TRAINER_SAWYER_4":838,"TRAINER_SAWYER_5":839,"TRAINER_SEBASTIAN":554,"TRAINER_SHANE":214,"TRAINER_SHANNON":97,"TRAINER_SHARON":452,"TRAINER_SHAWN":194,"TRAINER_SHAYLA":747,"TRAINER_SHEILA":125,"TRAINER_SHELBY_1":313,"TRAINER_SHELBY_2":314,"TRAINER_SHELBY_3":315,"TRAINER_SHELBY_4":316,"TRAINER_SHELBY_5":317,"TRAINER_SHELLY_SEAFLOOR_CAVERN":33,"TRAINER_SHELLY_WEATHER_INSTITUTE":32,"TRAINER_SHIRLEY":126,"TRAINER_SIDNEY":261,"TRAINER_SIENNA":459,"TRAINER_SIMON":65,"TRAINER_SOPHIA":561,"TRAINER_SOPHIE":708,"TRAINER_SPENCER":159,"TRAINER_SPENSER":807,"TRAINER_STAN":162,"TRAINER_STEVEN":804,"TRAINER_STEVE_1":143,"TRAINER_STEVE_2":147,"TRAINER_STEVE_3":148,"TRAINER_STEVE_4":149,"TRAINER_STEVE_5":150,"TRAINER_SUSIE":456,"TRAINER_SYLVIA":575,"TRAINER_TABITHA_MAGMA_HIDEOUT":732,"TRAINER_TABITHA_MOSSDEEP":514,"TRAINER_TABITHA_MT_CHIMNEY":597,"TRAINER_TAKAO":179,"TRAINER_TAKASHI":416,"TRAINER_TALIA":385,"TRAINER_TAMMY":107,"TRAINER_TANYA":451,"TRAINER_TARA":446,"TRAINER_TASHA":109,"TRAINER_TATE_AND_LIZA_1":271,"TRAINER_TATE_AND_LIZA_2":794,"TRAINER_TATE_AND_LIZA_3":795,"TRAINER_TATE_AND_LIZA_4":796,"TRAINER_TATE_AND_LIZA_5":797,"TRAINER_TAYLOR":225,"TRAINER_TED":274,"TRAINER_TERRY":581,"TRAINER_THALIA_1":144,"TRAINER_THALIA_2":844,"TRAINER_THALIA_3":845,"TRAINER_THALIA_4":846,"TRAINER_THALIA_5":847,"TRAINER_THOMAS":256,"TRAINER_TIANA":603,"TRAINER_TIFFANY":131,"TRAINER_TIMMY":334,"TRAINER_TIMOTHY_1":307,"TRAINER_TIMOTHY_2":308,"TRAINER_TIMOTHY_3":309,"TRAINER_TIMOTHY_4":310,"TRAINER_TIMOTHY_5":311,"TRAINER_TISHA":676,"TRAINER_TOMMY":321,"TRAINER_TONY_1":155,"TRAINER_TONY_2":175,"TRAINER_TONY_3":176,"TRAINER_TONY_4":177,"TRAINER_TONY_5":178,"TRAINER_TORI_AND_TIA":677,"TRAINER_TRAVIS":218,"TRAINER_TRENT_1":627,"TRAINER_TRENT_2":636,"TRAINER_TRENT_3":637,"TRAINER_TRENT_4":638,"TRAINER_TRENT_5":639,"TRAINER_TUCKER":806,"TRAINER_TYRA_AND_IVY":679,"TRAINER_TYRON":704,"TRAINER_VALERIE_1":108,"TRAINER_VALERIE_2":110,"TRAINER_VALERIE_3":111,"TRAINER_VALERIE_4":112,"TRAINER_VALERIE_5":113,"TRAINER_VANESSA":300,"TRAINER_VICKY":312,"TRAINER_VICTOR":292,"TRAINER_VICTORIA":299,"TRAINER_VINCENT":76,"TRAINER_VIOLET":39,"TRAINER_VIRGIL":234,"TRAINER_VITO":82,"TRAINER_VIVI":606,"TRAINER_VIVIAN":649,"TRAINER_WADE":344,"TRAINER_WALLACE":335,"TRAINER_WALLY_MAUVILLE":656,"TRAINER_WALLY_VR_1":519,"TRAINER_WALLY_VR_2":657,"TRAINER_WALLY_VR_3":658,"TRAINER_WALLY_VR_4":659,"TRAINER_WALLY_VR_5":660,"TRAINER_WALTER_1":254,"TRAINER_WALTER_2":257,"TRAINER_WALTER_3":258,"TRAINER_WALTER_4":259,"TRAINER_WALTER_5":260,"TRAINER_WARREN":88,"TRAINER_WATTSON_1":267,"TRAINER_WATTSON_2":778,"TRAINER_WATTSON_3":779,"TRAINER_WATTSON_4":780,"TRAINER_WATTSON_5":781,"TRAINER_WAYNE":673,"TRAINER_WENDY":92,"TRAINER_WILLIAM":236,"TRAINER_WILTON_1":78,"TRAINER_WILTON_2":84,"TRAINER_WILTON_3":85,"TRAINER_WILTON_4":86,"TRAINER_WILTON_5":87,"TRAINER_WINONA_1":270,"TRAINER_WINONA_2":790,"TRAINER_WINONA_3":791,"TRAINER_WINONA_4":792,"TRAINER_WINONA_5":793,"TRAINER_WINSTON_1":136,"TRAINER_WINSTON_2":139,"TRAINER_WINSTON_3":140,"TRAINER_WINSTON_4":141,"TRAINER_WINSTON_5":142,"TRAINER_WYATT":711,"TRAINER_YASU":415,"TRAINER_YUJI":188,"TRAINER_ZANDER":31},"legendary_encounters":[{"address":2538600,"catch_flag":429,"defeat_flag":428,"level":30,"species":410},{"address":2354334,"catch_flag":480,"defeat_flag":447,"level":70,"species":405},{"address":2543160,"catch_flag":146,"defeat_flag":476,"level":70,"species":250},{"address":2354112,"catch_flag":479,"defeat_flag":446,"level":70,"species":404},{"address":2385623,"catch_flag":457,"defeat_flag":456,"level":50,"species":407},{"address":2385687,"catch_flag":482,"defeat_flag":481,"level":50,"species":408},{"address":2543443,"catch_flag":145,"defeat_flag":477,"level":70,"species":249},{"address":2538177,"catch_flag":458,"defeat_flag":455,"level":30,"species":151},{"address":2347488,"catch_flag":478,"defeat_flag":448,"level":70,"species":406},{"address":2345460,"catch_flag":427,"defeat_flag":444,"level":40,"species":402},{"address":2298183,"catch_flag":426,"defeat_flag":443,"level":40,"species":401},{"address":2345731,"catch_flag":483,"defeat_flag":445,"level":40,"species":403}],"locations":{"BADGE_1":{"address":2188036,"default_item":226,"flag":1182},"BADGE_2":{"address":2095131,"default_item":227,"flag":1183},"BADGE_3":{"address":2167252,"default_item":228,"flag":1184},"BADGE_4":{"address":2103246,"default_item":229,"flag":1185},"BADGE_5":{"address":2129781,"default_item":230,"flag":1186},"BADGE_6":{"address":2202122,"default_item":231,"flag":1187},"BADGE_7":{"address":2243964,"default_item":232,"flag":1188},"BADGE_8":{"address":2262314,"default_item":233,"flag":1189},"BERRY_TREE_01":{"address":5843562,"default_item":135,"flag":612},"BERRY_TREE_02":{"address":5843564,"default_item":139,"flag":613},"BERRY_TREE_03":{"address":5843566,"default_item":142,"flag":614},"BERRY_TREE_04":{"address":5843568,"default_item":139,"flag":615},"BERRY_TREE_05":{"address":5843570,"default_item":133,"flag":616},"BERRY_TREE_06":{"address":5843572,"default_item":138,"flag":617},"BERRY_TREE_07":{"address":5843574,"default_item":133,"flag":618},"BERRY_TREE_08":{"address":5843576,"default_item":133,"flag":619},"BERRY_TREE_09":{"address":5843578,"default_item":142,"flag":620},"BERRY_TREE_10":{"address":5843580,"default_item":138,"flag":621},"BERRY_TREE_11":{"address":5843582,"default_item":139,"flag":622},"BERRY_TREE_12":{"address":5843584,"default_item":142,"flag":623},"BERRY_TREE_13":{"address":5843586,"default_item":135,"flag":624},"BERRY_TREE_14":{"address":5843588,"default_item":155,"flag":625},"BERRY_TREE_15":{"address":5843590,"default_item":153,"flag":626},"BERRY_TREE_16":{"address":5843592,"default_item":150,"flag":627},"BERRY_TREE_17":{"address":5843594,"default_item":150,"flag":628},"BERRY_TREE_18":{"address":5843596,"default_item":150,"flag":629},"BERRY_TREE_19":{"address":5843598,"default_item":148,"flag":630},"BERRY_TREE_20":{"address":5843600,"default_item":148,"flag":631},"BERRY_TREE_21":{"address":5843602,"default_item":136,"flag":632},"BERRY_TREE_22":{"address":5843604,"default_item":135,"flag":633},"BERRY_TREE_23":{"address":5843606,"default_item":135,"flag":634},"BERRY_TREE_24":{"address":5843608,"default_item":136,"flag":635},"BERRY_TREE_25":{"address":5843610,"default_item":152,"flag":636},"BERRY_TREE_26":{"address":5843612,"default_item":134,"flag":637},"BERRY_TREE_27":{"address":5843614,"default_item":151,"flag":638},"BERRY_TREE_28":{"address":5843616,"default_item":151,"flag":639},"BERRY_TREE_29":{"address":5843618,"default_item":151,"flag":640},"BERRY_TREE_30":{"address":5843620,"default_item":153,"flag":641},"BERRY_TREE_31":{"address":5843622,"default_item":142,"flag":642},"BERRY_TREE_32":{"address":5843624,"default_item":142,"flag":643},"BERRY_TREE_33":{"address":5843626,"default_item":142,"flag":644},"BERRY_TREE_34":{"address":5843628,"default_item":153,"flag":645},"BERRY_TREE_35":{"address":5843630,"default_item":153,"flag":646},"BERRY_TREE_36":{"address":5843632,"default_item":153,"flag":647},"BERRY_TREE_37":{"address":5843634,"default_item":137,"flag":648},"BERRY_TREE_38":{"address":5843636,"default_item":137,"flag":649},"BERRY_TREE_39":{"address":5843638,"default_item":137,"flag":650},"BERRY_TREE_40":{"address":5843640,"default_item":135,"flag":651},"BERRY_TREE_41":{"address":5843642,"default_item":135,"flag":652},"BERRY_TREE_42":{"address":5843644,"default_item":135,"flag":653},"BERRY_TREE_43":{"address":5843646,"default_item":148,"flag":654},"BERRY_TREE_44":{"address":5843648,"default_item":150,"flag":655},"BERRY_TREE_45":{"address":5843650,"default_item":152,"flag":656},"BERRY_TREE_46":{"address":5843652,"default_item":151,"flag":657},"BERRY_TREE_47":{"address":5843654,"default_item":140,"flag":658},"BERRY_TREE_48":{"address":5843656,"default_item":137,"flag":659},"BERRY_TREE_49":{"address":5843658,"default_item":136,"flag":660},"BERRY_TREE_50":{"address":5843660,"default_item":134,"flag":661},"BERRY_TREE_51":{"address":5843662,"default_item":142,"flag":662},"BERRY_TREE_52":{"address":5843664,"default_item":150,"flag":663},"BERRY_TREE_53":{"address":5843666,"default_item":150,"flag":664},"BERRY_TREE_54":{"address":5843668,"default_item":142,"flag":665},"BERRY_TREE_55":{"address":5843670,"default_item":149,"flag":666},"BERRY_TREE_56":{"address":5843672,"default_item":149,"flag":667},"BERRY_TREE_57":{"address":5843674,"default_item":136,"flag":668},"BERRY_TREE_58":{"address":5843676,"default_item":153,"flag":669},"BERRY_TREE_59":{"address":5843678,"default_item":153,"flag":670},"BERRY_TREE_60":{"address":5843680,"default_item":157,"flag":671},"BERRY_TREE_61":{"address":5843682,"default_item":157,"flag":672},"BERRY_TREE_62":{"address":5843684,"default_item":138,"flag":673},"BERRY_TREE_63":{"address":5843686,"default_item":142,"flag":674},"BERRY_TREE_64":{"address":5843688,"default_item":138,"flag":675},"BERRY_TREE_65":{"address":5843690,"default_item":157,"flag":676},"BERRY_TREE_66":{"address":5843692,"default_item":134,"flag":677},"BERRY_TREE_67":{"address":5843694,"default_item":152,"flag":678},"BERRY_TREE_68":{"address":5843696,"default_item":140,"flag":679},"BERRY_TREE_69":{"address":5843698,"default_item":154,"flag":680},"BERRY_TREE_70":{"address":5843700,"default_item":154,"flag":681},"BERRY_TREE_71":{"address":5843702,"default_item":154,"flag":682},"BERRY_TREE_72":{"address":5843704,"default_item":157,"flag":683},"BERRY_TREE_73":{"address":5843706,"default_item":155,"flag":684},"BERRY_TREE_74":{"address":5843708,"default_item":155,"flag":685},"BERRY_TREE_75":{"address":5843710,"default_item":142,"flag":686},"BERRY_TREE_76":{"address":5843712,"default_item":133,"flag":687},"BERRY_TREE_77":{"address":5843714,"default_item":140,"flag":688},"BERRY_TREE_78":{"address":5843716,"default_item":140,"flag":689},"BERRY_TREE_79":{"address":5843718,"default_item":155,"flag":690},"BERRY_TREE_80":{"address":5843720,"default_item":139,"flag":691},"BERRY_TREE_81":{"address":5843722,"default_item":139,"flag":692},"BERRY_TREE_82":{"address":5843724,"default_item":168,"flag":693},"BERRY_TREE_83":{"address":5843726,"default_item":156,"flag":694},"BERRY_TREE_84":{"address":5843728,"default_item":156,"flag":695},"BERRY_TREE_85":{"address":5843730,"default_item":142,"flag":696},"BERRY_TREE_86":{"address":5843732,"default_item":138,"flag":697},"BERRY_TREE_87":{"address":5843734,"default_item":135,"flag":698},"BERRY_TREE_88":{"address":5843736,"default_item":142,"flag":699},"HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":{"address":5497200,"default_item":281,"flag":531},"HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":{"address":5497212,"default_item":282,"flag":532},"HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":{"address":5497224,"default_item":283,"flag":533},"HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":{"address":5497236,"default_item":284,"flag":534},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":{"address":5500100,"default_item":67,"flag":601},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":{"address":5500124,"default_item":65,"flag":604},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":{"address":5500112,"default_item":64,"flag":603},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":{"address":5500088,"default_item":70,"flag":602},"HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":{"address":5435924,"default_item":110,"flag":528},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":{"address":5487372,"default_item":195,"flag":548},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":{"address":5487384,"default_item":195,"flag":549},"HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":{"address":5489116,"default_item":23,"flag":577},"HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":{"address":5489128,"default_item":3,"flag":576},"HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":{"address":5435672,"default_item":16,"flag":500},"HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":{"address":5432608,"default_item":111,"flag":527},"HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":{"address":5432632,"default_item":4,"flag":575},"HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":{"address":5432620,"default_item":69,"flag":543},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":{"address":5490440,"default_item":35,"flag":578},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":{"address":5490428,"default_item":2,"flag":529},"HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":{"address":5490796,"default_item":68,"flag":580},"HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":{"address":5490784,"default_item":70,"flag":579},"HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":{"address":5525804,"default_item":45,"flag":609},"HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":{"address":5428972,"default_item":68,"flag":595},"HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":{"address":5487908,"default_item":4,"flag":561},"HIDDEN_ITEM_PETALBURG_WOODS_POTION":{"address":5487872,"default_item":13,"flag":558},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":{"address":5487884,"default_item":103,"flag":559},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":{"address":5487896,"default_item":103,"flag":560},"HIDDEN_ITEM_ROUTE_104_ANTIDOTE":{"address":5438492,"default_item":14,"flag":585},"HIDDEN_ITEM_ROUTE_104_HEART_SCALE":{"address":5438504,"default_item":111,"flag":588},"HIDDEN_ITEM_ROUTE_104_POKE_BALL":{"address":5438468,"default_item":4,"flag":562},"HIDDEN_ITEM_ROUTE_104_POTION":{"address":5438480,"default_item":13,"flag":537},"HIDDEN_ITEM_ROUTE_104_SUPER_POTION":{"address":5438456,"default_item":22,"flag":544},"HIDDEN_ITEM_ROUTE_105_BIG_PEARL":{"address":5438748,"default_item":107,"flag":611},"HIDDEN_ITEM_ROUTE_105_HEART_SCALE":{"address":5438736,"default_item":111,"flag":589},"HIDDEN_ITEM_ROUTE_106_HEART_SCALE":{"address":5438932,"default_item":111,"flag":547},"HIDDEN_ITEM_ROUTE_106_POKE_BALL":{"address":5438908,"default_item":4,"flag":563},"HIDDEN_ITEM_ROUTE_106_STARDUST":{"address":5438920,"default_item":108,"flag":546},"HIDDEN_ITEM_ROUTE_108_RARE_CANDY":{"address":5439340,"default_item":68,"flag":586},"HIDDEN_ITEM_ROUTE_109_ETHER":{"address":5440016,"default_item":34,"flag":564},"HIDDEN_ITEM_ROUTE_109_GREAT_BALL":{"address":5440004,"default_item":3,"flag":551},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":{"address":5439992,"default_item":111,"flag":552},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":{"address":5440028,"default_item":111,"flag":590},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":{"address":5440040,"default_item":111,"flag":591},"HIDDEN_ITEM_ROUTE_109_REVIVE":{"address":5439980,"default_item":24,"flag":550},"HIDDEN_ITEM_ROUTE_110_FULL_HEAL":{"address":5441308,"default_item":23,"flag":555},"HIDDEN_ITEM_ROUTE_110_GREAT_BALL":{"address":5441284,"default_item":3,"flag":553},"HIDDEN_ITEM_ROUTE_110_POKE_BALL":{"address":5441296,"default_item":4,"flag":565},"HIDDEN_ITEM_ROUTE_110_REVIVE":{"address":5441272,"default_item":24,"flag":554},"HIDDEN_ITEM_ROUTE_111_PROTEIN":{"address":5443220,"default_item":64,"flag":556},"HIDDEN_ITEM_ROUTE_111_RARE_CANDY":{"address":5443232,"default_item":68,"flag":557},"HIDDEN_ITEM_ROUTE_111_STARDUST":{"address":5443160,"default_item":108,"flag":502},"HIDDEN_ITEM_ROUTE_113_ETHER":{"address":5444488,"default_item":34,"flag":503},"HIDDEN_ITEM_ROUTE_113_NUGGET":{"address":5444512,"default_item":110,"flag":598},"HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":{"address":5444500,"default_item":320,"flag":530},"HIDDEN_ITEM_ROUTE_114_CARBOS":{"address":5445340,"default_item":66,"flag":504},"HIDDEN_ITEM_ROUTE_114_REVIVE":{"address":5445364,"default_item":24,"flag":542},"HIDDEN_ITEM_ROUTE_115_HEART_SCALE":{"address":5446176,"default_item":111,"flag":597},"HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":{"address":5447056,"default_item":206,"flag":596},"HIDDEN_ITEM_ROUTE_116_SUPER_POTION":{"address":5447044,"default_item":22,"flag":545},"HIDDEN_ITEM_ROUTE_117_REPEL":{"address":5447708,"default_item":86,"flag":572},"HIDDEN_ITEM_ROUTE_118_HEART_SCALE":{"address":5448404,"default_item":111,"flag":566},"HIDDEN_ITEM_ROUTE_118_IRON":{"address":5448392,"default_item":65,"flag":567},"HIDDEN_ITEM_ROUTE_119_CALCIUM":{"address":5449972,"default_item":67,"flag":505},"HIDDEN_ITEM_ROUTE_119_FULL_HEAL":{"address":5450056,"default_item":23,"flag":568},"HIDDEN_ITEM_ROUTE_119_MAX_ETHER":{"address":5450068,"default_item":35,"flag":587},"HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":{"address":5449984,"default_item":2,"flag":506},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":{"address":5451596,"default_item":68,"flag":571},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":{"address":5451620,"default_item":68,"flag":569},"HIDDEN_ITEM_ROUTE_120_REVIVE":{"address":5451608,"default_item":24,"flag":584},"HIDDEN_ITEM_ROUTE_120_ZINC":{"address":5451632,"default_item":70,"flag":570},"HIDDEN_ITEM_ROUTE_121_FULL_HEAL":{"address":5452540,"default_item":23,"flag":573},"HIDDEN_ITEM_ROUTE_121_HP_UP":{"address":5452516,"default_item":63,"flag":539},"HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":{"address":5452552,"default_item":25,"flag":600},"HIDDEN_ITEM_ROUTE_121_NUGGET":{"address":5452528,"default_item":110,"flag":540},"HIDDEN_ITEM_ROUTE_123_HYPER_POTION":{"address":5454100,"default_item":21,"flag":574},"HIDDEN_ITEM_ROUTE_123_PP_UP":{"address":5454112,"default_item":69,"flag":599},"HIDDEN_ITEM_ROUTE_123_RARE_CANDY":{"address":5454124,"default_item":68,"flag":610},"HIDDEN_ITEM_ROUTE_123_REVIVE":{"address":5454088,"default_item":24,"flag":541},"HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":{"address":5454052,"default_item":83,"flag":507},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":{"address":5455620,"default_item":111,"flag":592},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":{"address":5455632,"default_item":111,"flag":593},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":{"address":5455644,"default_item":111,"flag":594},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":{"address":5517256,"default_item":68,"flag":606},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":{"address":5517268,"default_item":70,"flag":607},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":{"address":5517432,"default_item":19,"flag":605},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":{"address":5517420,"default_item":69,"flag":608},"HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":{"address":5511292,"default_item":200,"flag":535},"HIDDEN_ITEM_TRICK_HOUSE_NUGGET":{"address":5526716,"default_item":110,"flag":501},"HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":{"address":5456992,"default_item":107,"flag":511},"HIDDEN_ITEM_UNDERWATER_124_CALCIUM":{"address":5457016,"default_item":67,"flag":536},"HIDDEN_ITEM_UNDERWATER_124_CARBOS":{"address":5456956,"default_item":66,"flag":508},"HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":{"address":5456968,"default_item":51,"flag":509},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":{"address":5457004,"default_item":111,"flag":513},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":{"address":5457028,"default_item":111,"flag":538},"HIDDEN_ITEM_UNDERWATER_124_PEARL":{"address":5456980,"default_item":106,"flag":510},"HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":{"address":5457140,"default_item":107,"flag":520},"HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":{"address":5457152,"default_item":49,"flag":512},"HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":{"address":5457068,"default_item":111,"flag":514},"HIDDEN_ITEM_UNDERWATER_126_IRON":{"address":5457116,"default_item":65,"flag":519},"HIDDEN_ITEM_UNDERWATER_126_PEARL":{"address":5457104,"default_item":106,"flag":517},"HIDDEN_ITEM_UNDERWATER_126_STARDUST":{"address":5457092,"default_item":108,"flag":516},"HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":{"address":5457080,"default_item":2,"flag":515},"HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":{"address":5457128,"default_item":50,"flag":518},"HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":{"address":5457224,"default_item":111,"flag":523},"HIDDEN_ITEM_UNDERWATER_127_HP_UP":{"address":5457212,"default_item":63,"flag":522},"HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":{"address":5457236,"default_item":48,"flag":524},"HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":{"address":5457200,"default_item":109,"flag":521},"HIDDEN_ITEM_UNDERWATER_128_PEARL":{"address":5457288,"default_item":106,"flag":526},"HIDDEN_ITEM_UNDERWATER_128_PROTEIN":{"address":5457276,"default_item":64,"flag":525},"HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":{"address":5493932,"default_item":2,"flag":581},"HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":{"address":5494744,"default_item":36,"flag":582},"HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":{"address":5494756,"default_item":84,"flag":583},"ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":{"address":2709805,"default_item":285,"flag":1100},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":{"address":2709857,"default_item":306,"flag":1102},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":{"address":2709831,"default_item":278,"flag":1078},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":{"address":2709844,"default_item":97,"flag":1101},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":{"address":2709818,"default_item":11,"flag":1077},"ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":{"address":2709740,"default_item":122,"flag":1095},"ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":{"address":2709792,"default_item":24,"flag":1099},"ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":{"address":2709766,"default_item":7,"flag":1097},"ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":{"address":2709753,"default_item":85,"flag":1096},"ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":{"address":2709779,"default_item":301,"flag":1098},"ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":{"address":2710039,"default_item":1,"flag":1124},"ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":{"address":2710065,"default_item":37,"flag":1071},"ITEM_AQUA_HIDEOUT_B1F_NUGGET":{"address":2710052,"default_item":110,"flag":1132},"ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":{"address":2710078,"default_item":8,"flag":1072},"ITEM_ARTISAN_CAVE_1F_CARBOS":{"address":2710416,"default_item":66,"flag":1163},"ITEM_ARTISAN_CAVE_B1F_HP_UP":{"address":2710403,"default_item":63,"flag":1162},"ITEM_FIERY_PATH_FIRE_STONE":{"address":2709584,"default_item":95,"flag":1111},"ITEM_FIERY_PATH_TM_TOXIC":{"address":2709597,"default_item":294,"flag":1091},"ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":{"address":2709519,"default_item":85,"flag":1050},"ITEM_GRANITE_CAVE_B1F_POKE_BALL":{"address":2709532,"default_item":4,"flag":1051},"ITEM_GRANITE_CAVE_B2F_RARE_CANDY":{"address":2709558,"default_item":68,"flag":1054},"ITEM_GRANITE_CAVE_B2F_REPEL":{"address":2709545,"default_item":86,"flag":1053},"ITEM_JAGGED_PASS_BURN_HEAL":{"address":2709571,"default_item":15,"flag":1070},"ITEM_LILYCOVE_CITY_MAX_REPEL":{"address":2709415,"default_item":84,"flag":1042},"ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":{"address":2710429,"default_item":68,"flag":1151},"ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":{"address":2710455,"default_item":19,"flag":1165},"ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":{"address":2710442,"default_item":37,"flag":1164},"ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":{"address":2710468,"default_item":110,"flag":1166},"ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":{"address":2710481,"default_item":71,"flag":1167},"ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":{"address":2710507,"default_item":85,"flag":1059},"ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":{"address":2710494,"default_item":25,"flag":1168},"ITEM_MAUVILLE_CITY_X_SPEED":{"address":2709389,"default_item":77,"flag":1116},"ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":{"address":2709623,"default_item":23,"flag":1045},"ITEM_METEOR_FALLS_1F_1R_MOON_STONE":{"address":2709636,"default_item":94,"flag":1046},"ITEM_METEOR_FALLS_1F_1R_PP_UP":{"address":2709649,"default_item":69,"flag":1047},"ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":{"address":2709610,"default_item":311,"flag":1044},"ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":{"address":2709662,"default_item":290,"flag":1080},"ITEM_MOSSDEEP_CITY_NET_BALL":{"address":2709428,"default_item":6,"flag":1043},"ITEM_MT_PYRE_2F_ULTRA_BALL":{"address":2709948,"default_item":2,"flag":1129},"ITEM_MT_PYRE_3F_SUPER_REPEL":{"address":2709961,"default_item":83,"flag":1120},"ITEM_MT_PYRE_4F_SEA_INCENSE":{"address":2709974,"default_item":220,"flag":1130},"ITEM_MT_PYRE_5F_LAX_INCENSE":{"address":2709987,"default_item":221,"flag":1052},"ITEM_MT_PYRE_6F_TM_SHADOW_BALL":{"address":2710000,"default_item":318,"flag":1089},"ITEM_MT_PYRE_EXTERIOR_MAX_POTION":{"address":2710013,"default_item":20,"flag":1073},"ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":{"address":2710026,"default_item":336,"flag":1074},"ITEM_NEW_MAUVILLE_ESCAPE_ROPE":{"address":2709688,"default_item":85,"flag":1076},"ITEM_NEW_MAUVILLE_FULL_HEAL":{"address":2709714,"default_item":23,"flag":1122},"ITEM_NEW_MAUVILLE_PARALYZE_HEAL":{"address":2709727,"default_item":18,"flag":1123},"ITEM_NEW_MAUVILLE_THUNDER_STONE":{"address":2709701,"default_item":96,"flag":1110},"ITEM_NEW_MAUVILLE_ULTRA_BALL":{"address":2709675,"default_item":2,"flag":1075},"ITEM_PETALBURG_CITY_ETHER":{"address":2709376,"default_item":34,"flag":1040},"ITEM_PETALBURG_CITY_MAX_REVIVE":{"address":2709363,"default_item":25,"flag":1039},"ITEM_PETALBURG_WOODS_ETHER":{"address":2709467,"default_item":34,"flag":1058},"ITEM_PETALBURG_WOODS_GREAT_BALL":{"address":2709454,"default_item":3,"flag":1056},"ITEM_PETALBURG_WOODS_PARALYZE_HEAL":{"address":2709480,"default_item":18,"flag":1117},"ITEM_PETALBURG_WOODS_X_ATTACK":{"address":2709441,"default_item":75,"flag":1055},"ITEM_ROUTE_102_POTION":{"address":2708375,"default_item":13,"flag":1000},"ITEM_ROUTE_103_GUARD_SPEC":{"address":2708388,"default_item":73,"flag":1114},"ITEM_ROUTE_103_PP_UP":{"address":2708401,"default_item":69,"flag":1137},"ITEM_ROUTE_104_POKE_BALL":{"address":2708427,"default_item":4,"flag":1057},"ITEM_ROUTE_104_POTION":{"address":2708453,"default_item":13,"flag":1135},"ITEM_ROUTE_104_PP_UP":{"address":2708414,"default_item":69,"flag":1002},"ITEM_ROUTE_104_X_ACCURACY":{"address":2708440,"default_item":78,"flag":1115},"ITEM_ROUTE_105_IRON":{"address":2708466,"default_item":65,"flag":1003},"ITEM_ROUTE_106_PROTEIN":{"address":2708479,"default_item":64,"flag":1004},"ITEM_ROUTE_108_STAR_PIECE":{"address":2708492,"default_item":109,"flag":1139},"ITEM_ROUTE_109_POTION":{"address":2708518,"default_item":13,"flag":1140},"ITEM_ROUTE_109_PP_UP":{"address":2708505,"default_item":69,"flag":1005},"ITEM_ROUTE_110_DIRE_HIT":{"address":2708544,"default_item":74,"flag":1007},"ITEM_ROUTE_110_ELIXIR":{"address":2708557,"default_item":36,"flag":1141},"ITEM_ROUTE_110_RARE_CANDY":{"address":2708531,"default_item":68,"flag":1006},"ITEM_ROUTE_111_ELIXIR":{"address":2708609,"default_item":36,"flag":1142},"ITEM_ROUTE_111_HP_UP":{"address":2708596,"default_item":63,"flag":1010},"ITEM_ROUTE_111_STARDUST":{"address":2708583,"default_item":108,"flag":1009},"ITEM_ROUTE_111_TM_SANDSTORM":{"address":2708570,"default_item":325,"flag":1008},"ITEM_ROUTE_112_NUGGET":{"address":2708622,"default_item":110,"flag":1011},"ITEM_ROUTE_113_HYPER_POTION":{"address":2708661,"default_item":21,"flag":1143},"ITEM_ROUTE_113_MAX_ETHER":{"address":2708635,"default_item":35,"flag":1012},"ITEM_ROUTE_113_SUPER_REPEL":{"address":2708648,"default_item":83,"flag":1013},"ITEM_ROUTE_114_ENERGY_POWDER":{"address":2708700,"default_item":30,"flag":1160},"ITEM_ROUTE_114_PROTEIN":{"address":2708687,"default_item":64,"flag":1015},"ITEM_ROUTE_114_RARE_CANDY":{"address":2708674,"default_item":68,"flag":1014},"ITEM_ROUTE_115_GREAT_BALL":{"address":2708752,"default_item":3,"flag":1118},"ITEM_ROUTE_115_HEAL_POWDER":{"address":2708765,"default_item":32,"flag":1144},"ITEM_ROUTE_115_IRON":{"address":2708739,"default_item":65,"flag":1018},"ITEM_ROUTE_115_PP_UP":{"address":2708778,"default_item":69,"flag":1161},"ITEM_ROUTE_115_SUPER_POTION":{"address":2708713,"default_item":22,"flag":1016},"ITEM_ROUTE_115_TM_FOCUS_PUNCH":{"address":2708726,"default_item":289,"flag":1017},"ITEM_ROUTE_116_ETHER":{"address":2708804,"default_item":34,"flag":1019},"ITEM_ROUTE_116_HP_UP":{"address":2708830,"default_item":63,"flag":1021},"ITEM_ROUTE_116_POTION":{"address":2708843,"default_item":13,"flag":1146},"ITEM_ROUTE_116_REPEL":{"address":2708817,"default_item":86,"flag":1020},"ITEM_ROUTE_116_X_SPECIAL":{"address":2708791,"default_item":79,"flag":1001},"ITEM_ROUTE_117_GREAT_BALL":{"address":2708856,"default_item":3,"flag":1022},"ITEM_ROUTE_117_REVIVE":{"address":2708869,"default_item":24,"flag":1023},"ITEM_ROUTE_118_HYPER_POTION":{"address":2708882,"default_item":21,"flag":1121},"ITEM_ROUTE_119_ELIXIR_1":{"address":2708921,"default_item":36,"flag":1026},"ITEM_ROUTE_119_ELIXIR_2":{"address":2708986,"default_item":36,"flag":1147},"ITEM_ROUTE_119_HYPER_POTION_1":{"address":2708960,"default_item":21,"flag":1029},"ITEM_ROUTE_119_HYPER_POTION_2":{"address":2708973,"default_item":21,"flag":1106},"ITEM_ROUTE_119_LEAF_STONE":{"address":2708934,"default_item":98,"flag":1027},"ITEM_ROUTE_119_NUGGET":{"address":2710104,"default_item":110,"flag":1134},"ITEM_ROUTE_119_RARE_CANDY":{"address":2708947,"default_item":68,"flag":1028},"ITEM_ROUTE_119_SUPER_REPEL":{"address":2708895,"default_item":83,"flag":1024},"ITEM_ROUTE_119_ZINC":{"address":2708908,"default_item":70,"flag":1025},"ITEM_ROUTE_120_FULL_HEAL":{"address":2709012,"default_item":23,"flag":1031},"ITEM_ROUTE_120_HYPER_POTION":{"address":2709025,"default_item":21,"flag":1107},"ITEM_ROUTE_120_NEST_BALL":{"address":2709038,"default_item":8,"flag":1108},"ITEM_ROUTE_120_NUGGET":{"address":2708999,"default_item":110,"flag":1030},"ITEM_ROUTE_120_REVIVE":{"address":2709051,"default_item":24,"flag":1148},"ITEM_ROUTE_121_CARBOS":{"address":2709064,"default_item":66,"flag":1103},"ITEM_ROUTE_121_REVIVE":{"address":2709077,"default_item":24,"flag":1149},"ITEM_ROUTE_121_ZINC":{"address":2709090,"default_item":70,"flag":1150},"ITEM_ROUTE_123_CALCIUM":{"address":2709103,"default_item":67,"flag":1032},"ITEM_ROUTE_123_ELIXIR":{"address":2709129,"default_item":36,"flag":1109},"ITEM_ROUTE_123_PP_UP":{"address":2709142,"default_item":69,"flag":1152},"ITEM_ROUTE_123_REVIVAL_HERB":{"address":2709155,"default_item":33,"flag":1153},"ITEM_ROUTE_123_ULTRA_BALL":{"address":2709116,"default_item":2,"flag":1104},"ITEM_ROUTE_124_BLUE_SHARD":{"address":2709181,"default_item":49,"flag":1093},"ITEM_ROUTE_124_RED_SHARD":{"address":2709168,"default_item":48,"flag":1092},"ITEM_ROUTE_124_YELLOW_SHARD":{"address":2709194,"default_item":50,"flag":1066},"ITEM_ROUTE_125_BIG_PEARL":{"address":2709207,"default_item":107,"flag":1154},"ITEM_ROUTE_126_GREEN_SHARD":{"address":2709220,"default_item":51,"flag":1105},"ITEM_ROUTE_127_CARBOS":{"address":2709246,"default_item":66,"flag":1035},"ITEM_ROUTE_127_RARE_CANDY":{"address":2709259,"default_item":68,"flag":1155},"ITEM_ROUTE_127_ZINC":{"address":2709233,"default_item":70,"flag":1034},"ITEM_ROUTE_132_PROTEIN":{"address":2709285,"default_item":64,"flag":1156},"ITEM_ROUTE_132_RARE_CANDY":{"address":2709272,"default_item":68,"flag":1036},"ITEM_ROUTE_133_BIG_PEARL":{"address":2709298,"default_item":107,"flag":1037},"ITEM_ROUTE_133_MAX_REVIVE":{"address":2709324,"default_item":25,"flag":1157},"ITEM_ROUTE_133_STAR_PIECE":{"address":2709311,"default_item":109,"flag":1038},"ITEM_ROUTE_134_CARBOS":{"address":2709337,"default_item":66,"flag":1158},"ITEM_ROUTE_134_STAR_PIECE":{"address":2709350,"default_item":109,"flag":1159},"ITEM_RUSTBORO_CITY_X_DEFEND":{"address":2709402,"default_item":76,"flag":1041},"ITEM_RUSTURF_TUNNEL_MAX_ETHER":{"address":2709506,"default_item":35,"flag":1049},"ITEM_RUSTURF_TUNNEL_POKE_BALL":{"address":2709493,"default_item":4,"flag":1048},"ITEM_SAFARI_ZONE_NORTH_CALCIUM":{"address":2709896,"default_item":67,"flag":1119},"ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":{"address":2709922,"default_item":110,"flag":1169},"ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":{"address":2709883,"default_item":310,"flag":1094},"ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":{"address":2709935,"default_item":107,"flag":1170},"ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":{"address":2709909,"default_item":25,"flag":1131},"ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":{"address":2709870,"default_item":299,"flag":1079},"ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":{"address":2710208,"default_item":314,"flag":1090},"ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":{"address":2710143,"default_item":107,"flag":1081},"ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":{"address":2710195,"default_item":212,"flag":1113},"ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":{"address":2710182,"default_item":295,"flag":1112},"ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":{"address":2710156,"default_item":68,"flag":1082},"ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":{"address":2710169,"default_item":16,"flag":1083},"ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":{"address":[2710221,2551006],"default_item":121,"flag":1060},"ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":{"address":[2710234,2551032],"default_item":122,"flag":1061},"ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":{"address":[2710247,2551058],"default_item":126,"flag":1062},"ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":{"address":[2710260,2551084],"default_item":128,"flag":1063},"ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":{"address":[2710273,2551110],"default_item":125,"flag":1064},"ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":{"address":[2710286,2551136],"default_item":124,"flag":1065},"ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":{"address":[2710299,2551162],"default_item":123,"flag":1067},"ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":{"address":[2710312,2551188],"default_item":129,"flag":1068},"ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":{"address":[2710325,2551214],"default_item":127,"flag":1069},"ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":{"address":2710338,"default_item":37,"flag":1084},"ITEM_VICTORY_ROAD_1F_PP_UP":{"address":2710351,"default_item":69,"flag":1085},"ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":{"address":2710377,"default_item":19,"flag":1087},"ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":{"address":2710364,"default_item":317,"flag":1086},"ITEM_VICTORY_ROAD_B2F_FULL_HEAL":{"address":2710390,"default_item":23,"flag":1088},"NPC_GIFT_BERRY_MASTERS_WIFE":{"address":2570453,"default_item":133,"flag":1197},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_1":{"address":2570263,"default_item":153,"flag":1195},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_2":{"address":2570315,"default_item":154,"flag":1196},"NPC_GIFT_FLOWER_SHOP_RECEIVED_BERRY":{"address":2284375,"default_item":133,"flag":1207},"NPC_GIFT_GOT_BASEMENT_KEY_FROM_WATTSON":{"address":1971718,"default_item":271,"flag":208},"NPC_GIFT_GOT_TM_THUNDERBOLT_FROM_WATTSON":{"address":1971754,"default_item":312,"flag":209},"NPC_GIFT_LILYCOVE_RECEIVED_BERRY":{"address":1985277,"default_item":141,"flag":1208},"NPC_GIFT_RECEIVED_6_SODA_POP":{"address":2543767,"default_item":27,"flag":140},"NPC_GIFT_RECEIVED_ACRO_BIKE":{"address":2170570,"default_item":272,"flag":1181},"NPC_GIFT_RECEIVED_AMULET_COIN":{"address":2716248,"default_item":189,"flag":133},"NPC_GIFT_RECEIVED_AURORA_TICKET":{"address":2716523,"default_item":371,"flag":314},"NPC_GIFT_RECEIVED_CHARCOAL":{"address":2102559,"default_item":215,"flag":254},"NPC_GIFT_RECEIVED_CHESTO_BERRY_ROUTE_104":{"address":2028703,"default_item":134,"flag":246},"NPC_GIFT_RECEIVED_CLEANSE_TAG":{"address":2312109,"default_item":190,"flag":282},"NPC_GIFT_RECEIVED_COIN_CASE":{"address":2179054,"default_item":260,"flag":258},"NPC_GIFT_RECEIVED_DEEP_SEA_SCALE":{"address":2162572,"default_item":193,"flag":1190},"NPC_GIFT_RECEIVED_DEEP_SEA_TOOTH":{"address":2162555,"default_item":192,"flag":1191},"NPC_GIFT_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":{"address":2295814,"default_item":269,"flag":1172},"NPC_GIFT_RECEIVED_DEVON_SCOPE":{"address":2065146,"default_item":288,"flag":285},"NPC_GIFT_RECEIVED_EON_TICKET":{"address":2716574,"default_item":275,"flag":474},"NPC_GIFT_RECEIVED_EXP_SHARE":{"address":2185525,"default_item":182,"flag":272},"NPC_GIFT_RECEIVED_FIRST_POKEBALLS":{"address":2085751,"default_item":4,"flag":233},"NPC_GIFT_RECEIVED_FOCUS_BAND":{"address":2337807,"default_item":196,"flag":283},"NPC_GIFT_RECEIVED_GOOD_ROD":{"address":2058408,"default_item":263,"flag":227},"NPC_GIFT_RECEIVED_GO_GOGGLES":{"address":2017746,"default_item":279,"flag":221},"NPC_GIFT_RECEIVED_GREAT_BALL_PETALBURG_WOODS":{"address":2300119,"default_item":3,"flag":1171},"NPC_GIFT_RECEIVED_GREAT_BALL_RUSTBORO_CITY":{"address":1977146,"default_item":3,"flag":1173},"NPC_GIFT_RECEIVED_HM_CUT":{"address":2199532,"default_item":339,"flag":137},"NPC_GIFT_RECEIVED_HM_DIVE":{"address":2252095,"default_item":346,"flag":123},"NPC_GIFT_RECEIVED_HM_FLASH":{"address":2298287,"default_item":343,"flag":109},"NPC_GIFT_RECEIVED_HM_FLY":{"address":2060636,"default_item":340,"flag":110},"NPC_GIFT_RECEIVED_HM_ROCK_SMASH":{"address":2174128,"default_item":344,"flag":107},"NPC_GIFT_RECEIVED_HM_STRENGTH":{"address":2295305,"default_item":342,"flag":106},"NPC_GIFT_RECEIVED_HM_SURF":{"address":2126671,"default_item":341,"flag":122},"NPC_GIFT_RECEIVED_HM_WATERFALL":{"address":1999854,"default_item":345,"flag":312},"NPC_GIFT_RECEIVED_ITEMFINDER":{"address":2039874,"default_item":261,"flag":1176},"NPC_GIFT_RECEIVED_KINGS_ROCK":{"address":1993670,"default_item":187,"flag":276},"NPC_GIFT_RECEIVED_LETTER":{"address":2185301,"default_item":274,"flag":1174},"NPC_GIFT_RECEIVED_MACHO_BRACE":{"address":2284472,"default_item":181,"flag":277},"NPC_GIFT_RECEIVED_MACH_BIKE":{"address":2170553,"default_item":259,"flag":1180},"NPC_GIFT_RECEIVED_MAGMA_EMBLEM":{"address":2316671,"default_item":375,"flag":1177},"NPC_GIFT_RECEIVED_MENTAL_HERB":{"address":2208103,"default_item":185,"flag":223},"NPC_GIFT_RECEIVED_METEORITE":{"address":2304222,"default_item":280,"flag":115},"NPC_GIFT_RECEIVED_MIRACLE_SEED":{"address":2300337,"default_item":205,"flag":297},"NPC_GIFT_RECEIVED_MYSTIC_TICKET":{"address":2716540,"default_item":370,"flag":315},"NPC_GIFT_RECEIVED_OLD_ROD":{"address":2012541,"default_item":262,"flag":257},"NPC_GIFT_RECEIVED_OLD_SEA_MAP":{"address":2716557,"default_item":376,"flag":316},"NPC_GIFT_RECEIVED_POKEBLOCK_CASE":{"address":2614193,"default_item":273,"flag":95},"NPC_GIFT_RECEIVED_POTION_OLDALE":{"address":2010888,"default_item":13,"flag":132},"NPC_GIFT_RECEIVED_POWDER_JAR":{"address":1962504,"default_item":372,"flag":337},"NPC_GIFT_RECEIVED_PREMIER_BALL_RUSTBORO":{"address":2200571,"default_item":12,"flag":213},"NPC_GIFT_RECEIVED_QUICK_CLAW":{"address":2192227,"default_item":183,"flag":275},"NPC_GIFT_RECEIVED_REPEAT_BALL":{"address":2053722,"default_item":9,"flag":256},"NPC_GIFT_RECEIVED_SECRET_POWER":{"address":2598914,"default_item":331,"flag":96},"NPC_GIFT_RECEIVED_SILK_SCARF":{"address":2101830,"default_item":217,"flag":289},"NPC_GIFT_RECEIVED_SOFT_SAND":{"address":2035664,"default_item":203,"flag":280},"NPC_GIFT_RECEIVED_SOOTHE_BELL":{"address":2151278,"default_item":184,"flag":278},"NPC_GIFT_RECEIVED_SOOT_SACK":{"address":2567245,"default_item":270,"flag":1033},"NPC_GIFT_RECEIVED_SS_TICKET":{"address":2716506,"default_item":265,"flag":291},"NPC_GIFT_RECEIVED_SUN_STONE_MOSSDEEP":{"address":2254406,"default_item":93,"flag":192},"NPC_GIFT_RECEIVED_SUPER_ROD":{"address":2251560,"default_item":264,"flag":152},"NPC_GIFT_RECEIVED_TM_AERIAL_ACE":{"address":2202201,"default_item":328,"flag":170},"NPC_GIFT_RECEIVED_TM_ATTRACT":{"address":2116413,"default_item":333,"flag":235},"NPC_GIFT_RECEIVED_TM_BRICK_BREAK":{"address":2269085,"default_item":319,"flag":121},"NPC_GIFT_RECEIVED_TM_BULK_UP":{"address":2095210,"default_item":296,"flag":166},"NPC_GIFT_RECEIVED_TM_BULLET_SEED":{"address":2028910,"default_item":297,"flag":262},"NPC_GIFT_RECEIVED_TM_CALM_MIND":{"address":2244066,"default_item":292,"flag":171},"NPC_GIFT_RECEIVED_TM_DIG":{"address":2286669,"default_item":316,"flag":261},"NPC_GIFT_RECEIVED_TM_FACADE":{"address":2129909,"default_item":330,"flag":169},"NPC_GIFT_RECEIVED_TM_FRUSTRATION":{"address":2124110,"default_item":309,"flag":1179},"NPC_GIFT_RECEIVED_TM_GIGA_DRAIN":{"address":2068012,"default_item":307,"flag":232},"NPC_GIFT_RECEIVED_TM_HIDDEN_POWER":{"address":2206905,"default_item":298,"flag":264},"NPC_GIFT_RECEIVED_TM_OVERHEAT":{"address":2103328,"default_item":338,"flag":168},"NPC_GIFT_RECEIVED_TM_REST":{"address":2236966,"default_item":332,"flag":234},"NPC_GIFT_RECEIVED_TM_RETURN":{"address":2113546,"default_item":315,"flag":229},"NPC_GIFT_RECEIVED_TM_RETURN_2":{"address":2124055,"default_item":315,"flag":1178},"NPC_GIFT_RECEIVED_TM_ROAR":{"address":2051750,"default_item":293,"flag":231},"NPC_GIFT_RECEIVED_TM_ROCK_TOMB":{"address":2188088,"default_item":327,"flag":165},"NPC_GIFT_RECEIVED_TM_SHOCK_WAVE":{"address":2167340,"default_item":322,"flag":167},"NPC_GIFT_RECEIVED_TM_SLUDGE_BOMB":{"address":2099189,"default_item":324,"flag":230},"NPC_GIFT_RECEIVED_TM_SNATCH":{"address":2360766,"default_item":337,"flag":260},"NPC_GIFT_RECEIVED_TM_STEEL_WING":{"address":2298866,"default_item":335,"flag":1175},"NPC_GIFT_RECEIVED_TM_THIEF":{"address":2154698,"default_item":334,"flag":269},"NPC_GIFT_RECEIVED_TM_TORMENT":{"address":2145260,"default_item":329,"flag":265},"NPC_GIFT_RECEIVED_TM_WATER_PULSE":{"address":2262402,"default_item":291,"flag":172},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_1":{"address":2550316,"default_item":68,"flag":1200},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_2":{"address":2550390,"default_item":10,"flag":1201},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_3":{"address":2550473,"default_item":204,"flag":1202},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_4":{"address":2550556,"default_item":194,"flag":1203},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_5":{"address":2550630,"default_item":300,"flag":1204},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_6":{"address":2550695,"default_item":208,"flag":1205},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_7":{"address":2550769,"default_item":71,"flag":1206},"NPC_GIFT_RECEIVED_WAILMER_PAIL":{"address":2284320,"default_item":268,"flag":94},"NPC_GIFT_RECEIVED_WHITE_HERB":{"address":2028770,"default_item":180,"flag":279},"NPC_GIFT_ROUTE_111_RECEIVED_BERRY":{"address":2045493,"default_item":148,"flag":1192},"NPC_GIFT_ROUTE_114_RECEIVED_BERRY":{"address":2051680,"default_item":149,"flag":1193},"NPC_GIFT_ROUTE_120_RECEIVED_BERRY":{"address":2064727,"default_item":143,"flag":1194},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_1":{"address":1998521,"default_item":153,"flag":1198},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_2":{"address":1998566,"default_item":143,"flag":1199},"POKEDEX_REWARD_001":{"address":5729368,"default_item":3,"flag":0},"POKEDEX_REWARD_002":{"address":5729370,"default_item":3,"flag":0},"POKEDEX_REWARD_003":{"address":5729372,"default_item":3,"flag":0},"POKEDEX_REWARD_004":{"address":5729374,"default_item":3,"flag":0},"POKEDEX_REWARD_005":{"address":5729376,"default_item":3,"flag":0},"POKEDEX_REWARD_006":{"address":5729378,"default_item":3,"flag":0},"POKEDEX_REWARD_007":{"address":5729380,"default_item":3,"flag":0},"POKEDEX_REWARD_008":{"address":5729382,"default_item":3,"flag":0},"POKEDEX_REWARD_009":{"address":5729384,"default_item":3,"flag":0},"POKEDEX_REWARD_010":{"address":5729386,"default_item":3,"flag":0},"POKEDEX_REWARD_011":{"address":5729388,"default_item":3,"flag":0},"POKEDEX_REWARD_012":{"address":5729390,"default_item":3,"flag":0},"POKEDEX_REWARD_013":{"address":5729392,"default_item":3,"flag":0},"POKEDEX_REWARD_014":{"address":5729394,"default_item":3,"flag":0},"POKEDEX_REWARD_015":{"address":5729396,"default_item":3,"flag":0},"POKEDEX_REWARD_016":{"address":5729398,"default_item":3,"flag":0},"POKEDEX_REWARD_017":{"address":5729400,"default_item":3,"flag":0},"POKEDEX_REWARD_018":{"address":5729402,"default_item":3,"flag":0},"POKEDEX_REWARD_019":{"address":5729404,"default_item":3,"flag":0},"POKEDEX_REWARD_020":{"address":5729406,"default_item":3,"flag":0},"POKEDEX_REWARD_021":{"address":5729408,"default_item":3,"flag":0},"POKEDEX_REWARD_022":{"address":5729410,"default_item":3,"flag":0},"POKEDEX_REWARD_023":{"address":5729412,"default_item":3,"flag":0},"POKEDEX_REWARD_024":{"address":5729414,"default_item":3,"flag":0},"POKEDEX_REWARD_025":{"address":5729416,"default_item":3,"flag":0},"POKEDEX_REWARD_026":{"address":5729418,"default_item":3,"flag":0},"POKEDEX_REWARD_027":{"address":5729420,"default_item":3,"flag":0},"POKEDEX_REWARD_028":{"address":5729422,"default_item":3,"flag":0},"POKEDEX_REWARD_029":{"address":5729424,"default_item":3,"flag":0},"POKEDEX_REWARD_030":{"address":5729426,"default_item":3,"flag":0},"POKEDEX_REWARD_031":{"address":5729428,"default_item":3,"flag":0},"POKEDEX_REWARD_032":{"address":5729430,"default_item":3,"flag":0},"POKEDEX_REWARD_033":{"address":5729432,"default_item":3,"flag":0},"POKEDEX_REWARD_034":{"address":5729434,"default_item":3,"flag":0},"POKEDEX_REWARD_035":{"address":5729436,"default_item":3,"flag":0},"POKEDEX_REWARD_036":{"address":5729438,"default_item":3,"flag":0},"POKEDEX_REWARD_037":{"address":5729440,"default_item":3,"flag":0},"POKEDEX_REWARD_038":{"address":5729442,"default_item":3,"flag":0},"POKEDEX_REWARD_039":{"address":5729444,"default_item":3,"flag":0},"POKEDEX_REWARD_040":{"address":5729446,"default_item":3,"flag":0},"POKEDEX_REWARD_041":{"address":5729448,"default_item":3,"flag":0},"POKEDEX_REWARD_042":{"address":5729450,"default_item":3,"flag":0},"POKEDEX_REWARD_043":{"address":5729452,"default_item":3,"flag":0},"POKEDEX_REWARD_044":{"address":5729454,"default_item":3,"flag":0},"POKEDEX_REWARD_045":{"address":5729456,"default_item":3,"flag":0},"POKEDEX_REWARD_046":{"address":5729458,"default_item":3,"flag":0},"POKEDEX_REWARD_047":{"address":5729460,"default_item":3,"flag":0},"POKEDEX_REWARD_048":{"address":5729462,"default_item":3,"flag":0},"POKEDEX_REWARD_049":{"address":5729464,"default_item":3,"flag":0},"POKEDEX_REWARD_050":{"address":5729466,"default_item":3,"flag":0},"POKEDEX_REWARD_051":{"address":5729468,"default_item":3,"flag":0},"POKEDEX_REWARD_052":{"address":5729470,"default_item":3,"flag":0},"POKEDEX_REWARD_053":{"address":5729472,"default_item":3,"flag":0},"POKEDEX_REWARD_054":{"address":5729474,"default_item":3,"flag":0},"POKEDEX_REWARD_055":{"address":5729476,"default_item":3,"flag":0},"POKEDEX_REWARD_056":{"address":5729478,"default_item":3,"flag":0},"POKEDEX_REWARD_057":{"address":5729480,"default_item":3,"flag":0},"POKEDEX_REWARD_058":{"address":5729482,"default_item":3,"flag":0},"POKEDEX_REWARD_059":{"address":5729484,"default_item":3,"flag":0},"POKEDEX_REWARD_060":{"address":5729486,"default_item":3,"flag":0},"POKEDEX_REWARD_061":{"address":5729488,"default_item":3,"flag":0},"POKEDEX_REWARD_062":{"address":5729490,"default_item":3,"flag":0},"POKEDEX_REWARD_063":{"address":5729492,"default_item":3,"flag":0},"POKEDEX_REWARD_064":{"address":5729494,"default_item":3,"flag":0},"POKEDEX_REWARD_065":{"address":5729496,"default_item":3,"flag":0},"POKEDEX_REWARD_066":{"address":5729498,"default_item":3,"flag":0},"POKEDEX_REWARD_067":{"address":5729500,"default_item":3,"flag":0},"POKEDEX_REWARD_068":{"address":5729502,"default_item":3,"flag":0},"POKEDEX_REWARD_069":{"address":5729504,"default_item":3,"flag":0},"POKEDEX_REWARD_070":{"address":5729506,"default_item":3,"flag":0},"POKEDEX_REWARD_071":{"address":5729508,"default_item":3,"flag":0},"POKEDEX_REWARD_072":{"address":5729510,"default_item":3,"flag":0},"POKEDEX_REWARD_073":{"address":5729512,"default_item":3,"flag":0},"POKEDEX_REWARD_074":{"address":5729514,"default_item":3,"flag":0},"POKEDEX_REWARD_075":{"address":5729516,"default_item":3,"flag":0},"POKEDEX_REWARD_076":{"address":5729518,"default_item":3,"flag":0},"POKEDEX_REWARD_077":{"address":5729520,"default_item":3,"flag":0},"POKEDEX_REWARD_078":{"address":5729522,"default_item":3,"flag":0},"POKEDEX_REWARD_079":{"address":5729524,"default_item":3,"flag":0},"POKEDEX_REWARD_080":{"address":5729526,"default_item":3,"flag":0},"POKEDEX_REWARD_081":{"address":5729528,"default_item":3,"flag":0},"POKEDEX_REWARD_082":{"address":5729530,"default_item":3,"flag":0},"POKEDEX_REWARD_083":{"address":5729532,"default_item":3,"flag":0},"POKEDEX_REWARD_084":{"address":5729534,"default_item":3,"flag":0},"POKEDEX_REWARD_085":{"address":5729536,"default_item":3,"flag":0},"POKEDEX_REWARD_086":{"address":5729538,"default_item":3,"flag":0},"POKEDEX_REWARD_087":{"address":5729540,"default_item":3,"flag":0},"POKEDEX_REWARD_088":{"address":5729542,"default_item":3,"flag":0},"POKEDEX_REWARD_089":{"address":5729544,"default_item":3,"flag":0},"POKEDEX_REWARD_090":{"address":5729546,"default_item":3,"flag":0},"POKEDEX_REWARD_091":{"address":5729548,"default_item":3,"flag":0},"POKEDEX_REWARD_092":{"address":5729550,"default_item":3,"flag":0},"POKEDEX_REWARD_093":{"address":5729552,"default_item":3,"flag":0},"POKEDEX_REWARD_094":{"address":5729554,"default_item":3,"flag":0},"POKEDEX_REWARD_095":{"address":5729556,"default_item":3,"flag":0},"POKEDEX_REWARD_096":{"address":5729558,"default_item":3,"flag":0},"POKEDEX_REWARD_097":{"address":5729560,"default_item":3,"flag":0},"POKEDEX_REWARD_098":{"address":5729562,"default_item":3,"flag":0},"POKEDEX_REWARD_099":{"address":5729564,"default_item":3,"flag":0},"POKEDEX_REWARD_100":{"address":5729566,"default_item":3,"flag":0},"POKEDEX_REWARD_101":{"address":5729568,"default_item":3,"flag":0},"POKEDEX_REWARD_102":{"address":5729570,"default_item":3,"flag":0},"POKEDEX_REWARD_103":{"address":5729572,"default_item":3,"flag":0},"POKEDEX_REWARD_104":{"address":5729574,"default_item":3,"flag":0},"POKEDEX_REWARD_105":{"address":5729576,"default_item":3,"flag":0},"POKEDEX_REWARD_106":{"address":5729578,"default_item":3,"flag":0},"POKEDEX_REWARD_107":{"address":5729580,"default_item":3,"flag":0},"POKEDEX_REWARD_108":{"address":5729582,"default_item":3,"flag":0},"POKEDEX_REWARD_109":{"address":5729584,"default_item":3,"flag":0},"POKEDEX_REWARD_110":{"address":5729586,"default_item":3,"flag":0},"POKEDEX_REWARD_111":{"address":5729588,"default_item":3,"flag":0},"POKEDEX_REWARD_112":{"address":5729590,"default_item":3,"flag":0},"POKEDEX_REWARD_113":{"address":5729592,"default_item":3,"flag":0},"POKEDEX_REWARD_114":{"address":5729594,"default_item":3,"flag":0},"POKEDEX_REWARD_115":{"address":5729596,"default_item":3,"flag":0},"POKEDEX_REWARD_116":{"address":5729598,"default_item":3,"flag":0},"POKEDEX_REWARD_117":{"address":5729600,"default_item":3,"flag":0},"POKEDEX_REWARD_118":{"address":5729602,"default_item":3,"flag":0},"POKEDEX_REWARD_119":{"address":5729604,"default_item":3,"flag":0},"POKEDEX_REWARD_120":{"address":5729606,"default_item":3,"flag":0},"POKEDEX_REWARD_121":{"address":5729608,"default_item":3,"flag":0},"POKEDEX_REWARD_122":{"address":5729610,"default_item":3,"flag":0},"POKEDEX_REWARD_123":{"address":5729612,"default_item":3,"flag":0},"POKEDEX_REWARD_124":{"address":5729614,"default_item":3,"flag":0},"POKEDEX_REWARD_125":{"address":5729616,"default_item":3,"flag":0},"POKEDEX_REWARD_126":{"address":5729618,"default_item":3,"flag":0},"POKEDEX_REWARD_127":{"address":5729620,"default_item":3,"flag":0},"POKEDEX_REWARD_128":{"address":5729622,"default_item":3,"flag":0},"POKEDEX_REWARD_129":{"address":5729624,"default_item":3,"flag":0},"POKEDEX_REWARD_130":{"address":5729626,"default_item":3,"flag":0},"POKEDEX_REWARD_131":{"address":5729628,"default_item":3,"flag":0},"POKEDEX_REWARD_132":{"address":5729630,"default_item":3,"flag":0},"POKEDEX_REWARD_133":{"address":5729632,"default_item":3,"flag":0},"POKEDEX_REWARD_134":{"address":5729634,"default_item":3,"flag":0},"POKEDEX_REWARD_135":{"address":5729636,"default_item":3,"flag":0},"POKEDEX_REWARD_136":{"address":5729638,"default_item":3,"flag":0},"POKEDEX_REWARD_137":{"address":5729640,"default_item":3,"flag":0},"POKEDEX_REWARD_138":{"address":5729642,"default_item":3,"flag":0},"POKEDEX_REWARD_139":{"address":5729644,"default_item":3,"flag":0},"POKEDEX_REWARD_140":{"address":5729646,"default_item":3,"flag":0},"POKEDEX_REWARD_141":{"address":5729648,"default_item":3,"flag":0},"POKEDEX_REWARD_142":{"address":5729650,"default_item":3,"flag":0},"POKEDEX_REWARD_143":{"address":5729652,"default_item":3,"flag":0},"POKEDEX_REWARD_144":{"address":5729654,"default_item":3,"flag":0},"POKEDEX_REWARD_145":{"address":5729656,"default_item":3,"flag":0},"POKEDEX_REWARD_146":{"address":5729658,"default_item":3,"flag":0},"POKEDEX_REWARD_147":{"address":5729660,"default_item":3,"flag":0},"POKEDEX_REWARD_148":{"address":5729662,"default_item":3,"flag":0},"POKEDEX_REWARD_149":{"address":5729664,"default_item":3,"flag":0},"POKEDEX_REWARD_150":{"address":5729666,"default_item":3,"flag":0},"POKEDEX_REWARD_151":{"address":5729668,"default_item":3,"flag":0},"POKEDEX_REWARD_152":{"address":5729670,"default_item":3,"flag":0},"POKEDEX_REWARD_153":{"address":5729672,"default_item":3,"flag":0},"POKEDEX_REWARD_154":{"address":5729674,"default_item":3,"flag":0},"POKEDEX_REWARD_155":{"address":5729676,"default_item":3,"flag":0},"POKEDEX_REWARD_156":{"address":5729678,"default_item":3,"flag":0},"POKEDEX_REWARD_157":{"address":5729680,"default_item":3,"flag":0},"POKEDEX_REWARD_158":{"address":5729682,"default_item":3,"flag":0},"POKEDEX_REWARD_159":{"address":5729684,"default_item":3,"flag":0},"POKEDEX_REWARD_160":{"address":5729686,"default_item":3,"flag":0},"POKEDEX_REWARD_161":{"address":5729688,"default_item":3,"flag":0},"POKEDEX_REWARD_162":{"address":5729690,"default_item":3,"flag":0},"POKEDEX_REWARD_163":{"address":5729692,"default_item":3,"flag":0},"POKEDEX_REWARD_164":{"address":5729694,"default_item":3,"flag":0},"POKEDEX_REWARD_165":{"address":5729696,"default_item":3,"flag":0},"POKEDEX_REWARD_166":{"address":5729698,"default_item":3,"flag":0},"POKEDEX_REWARD_167":{"address":5729700,"default_item":3,"flag":0},"POKEDEX_REWARD_168":{"address":5729702,"default_item":3,"flag":0},"POKEDEX_REWARD_169":{"address":5729704,"default_item":3,"flag":0},"POKEDEX_REWARD_170":{"address":5729706,"default_item":3,"flag":0},"POKEDEX_REWARD_171":{"address":5729708,"default_item":3,"flag":0},"POKEDEX_REWARD_172":{"address":5729710,"default_item":3,"flag":0},"POKEDEX_REWARD_173":{"address":5729712,"default_item":3,"flag":0},"POKEDEX_REWARD_174":{"address":5729714,"default_item":3,"flag":0},"POKEDEX_REWARD_175":{"address":5729716,"default_item":3,"flag":0},"POKEDEX_REWARD_176":{"address":5729718,"default_item":3,"flag":0},"POKEDEX_REWARD_177":{"address":5729720,"default_item":3,"flag":0},"POKEDEX_REWARD_178":{"address":5729722,"default_item":3,"flag":0},"POKEDEX_REWARD_179":{"address":5729724,"default_item":3,"flag":0},"POKEDEX_REWARD_180":{"address":5729726,"default_item":3,"flag":0},"POKEDEX_REWARD_181":{"address":5729728,"default_item":3,"flag":0},"POKEDEX_REWARD_182":{"address":5729730,"default_item":3,"flag":0},"POKEDEX_REWARD_183":{"address":5729732,"default_item":3,"flag":0},"POKEDEX_REWARD_184":{"address":5729734,"default_item":3,"flag":0},"POKEDEX_REWARD_185":{"address":5729736,"default_item":3,"flag":0},"POKEDEX_REWARD_186":{"address":5729738,"default_item":3,"flag":0},"POKEDEX_REWARD_187":{"address":5729740,"default_item":3,"flag":0},"POKEDEX_REWARD_188":{"address":5729742,"default_item":3,"flag":0},"POKEDEX_REWARD_189":{"address":5729744,"default_item":3,"flag":0},"POKEDEX_REWARD_190":{"address":5729746,"default_item":3,"flag":0},"POKEDEX_REWARD_191":{"address":5729748,"default_item":3,"flag":0},"POKEDEX_REWARD_192":{"address":5729750,"default_item":3,"flag":0},"POKEDEX_REWARD_193":{"address":5729752,"default_item":3,"flag":0},"POKEDEX_REWARD_194":{"address":5729754,"default_item":3,"flag":0},"POKEDEX_REWARD_195":{"address":5729756,"default_item":3,"flag":0},"POKEDEX_REWARD_196":{"address":5729758,"default_item":3,"flag":0},"POKEDEX_REWARD_197":{"address":5729760,"default_item":3,"flag":0},"POKEDEX_REWARD_198":{"address":5729762,"default_item":3,"flag":0},"POKEDEX_REWARD_199":{"address":5729764,"default_item":3,"flag":0},"POKEDEX_REWARD_200":{"address":5729766,"default_item":3,"flag":0},"POKEDEX_REWARD_201":{"address":5729768,"default_item":3,"flag":0},"POKEDEX_REWARD_202":{"address":5729770,"default_item":3,"flag":0},"POKEDEX_REWARD_203":{"address":5729772,"default_item":3,"flag":0},"POKEDEX_REWARD_204":{"address":5729774,"default_item":3,"flag":0},"POKEDEX_REWARD_205":{"address":5729776,"default_item":3,"flag":0},"POKEDEX_REWARD_206":{"address":5729778,"default_item":3,"flag":0},"POKEDEX_REWARD_207":{"address":5729780,"default_item":3,"flag":0},"POKEDEX_REWARD_208":{"address":5729782,"default_item":3,"flag":0},"POKEDEX_REWARD_209":{"address":5729784,"default_item":3,"flag":0},"POKEDEX_REWARD_210":{"address":5729786,"default_item":3,"flag":0},"POKEDEX_REWARD_211":{"address":5729788,"default_item":3,"flag":0},"POKEDEX_REWARD_212":{"address":5729790,"default_item":3,"flag":0},"POKEDEX_REWARD_213":{"address":5729792,"default_item":3,"flag":0},"POKEDEX_REWARD_214":{"address":5729794,"default_item":3,"flag":0},"POKEDEX_REWARD_215":{"address":5729796,"default_item":3,"flag":0},"POKEDEX_REWARD_216":{"address":5729798,"default_item":3,"flag":0},"POKEDEX_REWARD_217":{"address":5729800,"default_item":3,"flag":0},"POKEDEX_REWARD_218":{"address":5729802,"default_item":3,"flag":0},"POKEDEX_REWARD_219":{"address":5729804,"default_item":3,"flag":0},"POKEDEX_REWARD_220":{"address":5729806,"default_item":3,"flag":0},"POKEDEX_REWARD_221":{"address":5729808,"default_item":3,"flag":0},"POKEDEX_REWARD_222":{"address":5729810,"default_item":3,"flag":0},"POKEDEX_REWARD_223":{"address":5729812,"default_item":3,"flag":0},"POKEDEX_REWARD_224":{"address":5729814,"default_item":3,"flag":0},"POKEDEX_REWARD_225":{"address":5729816,"default_item":3,"flag":0},"POKEDEX_REWARD_226":{"address":5729818,"default_item":3,"flag":0},"POKEDEX_REWARD_227":{"address":5729820,"default_item":3,"flag":0},"POKEDEX_REWARD_228":{"address":5729822,"default_item":3,"flag":0},"POKEDEX_REWARD_229":{"address":5729824,"default_item":3,"flag":0},"POKEDEX_REWARD_230":{"address":5729826,"default_item":3,"flag":0},"POKEDEX_REWARD_231":{"address":5729828,"default_item":3,"flag":0},"POKEDEX_REWARD_232":{"address":5729830,"default_item":3,"flag":0},"POKEDEX_REWARD_233":{"address":5729832,"default_item":3,"flag":0},"POKEDEX_REWARD_234":{"address":5729834,"default_item":3,"flag":0},"POKEDEX_REWARD_235":{"address":5729836,"default_item":3,"flag":0},"POKEDEX_REWARD_236":{"address":5729838,"default_item":3,"flag":0},"POKEDEX_REWARD_237":{"address":5729840,"default_item":3,"flag":0},"POKEDEX_REWARD_238":{"address":5729842,"default_item":3,"flag":0},"POKEDEX_REWARD_239":{"address":5729844,"default_item":3,"flag":0},"POKEDEX_REWARD_240":{"address":5729846,"default_item":3,"flag":0},"POKEDEX_REWARD_241":{"address":5729848,"default_item":3,"flag":0},"POKEDEX_REWARD_242":{"address":5729850,"default_item":3,"flag":0},"POKEDEX_REWARD_243":{"address":5729852,"default_item":3,"flag":0},"POKEDEX_REWARD_244":{"address":5729854,"default_item":3,"flag":0},"POKEDEX_REWARD_245":{"address":5729856,"default_item":3,"flag":0},"POKEDEX_REWARD_246":{"address":5729858,"default_item":3,"flag":0},"POKEDEX_REWARD_247":{"address":5729860,"default_item":3,"flag":0},"POKEDEX_REWARD_248":{"address":5729862,"default_item":3,"flag":0},"POKEDEX_REWARD_249":{"address":5729864,"default_item":3,"flag":0},"POKEDEX_REWARD_250":{"address":5729866,"default_item":3,"flag":0},"POKEDEX_REWARD_251":{"address":5729868,"default_item":3,"flag":0},"POKEDEX_REWARD_252":{"address":5729870,"default_item":3,"flag":0},"POKEDEX_REWARD_253":{"address":5729872,"default_item":3,"flag":0},"POKEDEX_REWARD_254":{"address":5729874,"default_item":3,"flag":0},"POKEDEX_REWARD_255":{"address":5729876,"default_item":3,"flag":0},"POKEDEX_REWARD_256":{"address":5729878,"default_item":3,"flag":0},"POKEDEX_REWARD_257":{"address":5729880,"default_item":3,"flag":0},"POKEDEX_REWARD_258":{"address":5729882,"default_item":3,"flag":0},"POKEDEX_REWARD_259":{"address":5729884,"default_item":3,"flag":0},"POKEDEX_REWARD_260":{"address":5729886,"default_item":3,"flag":0},"POKEDEX_REWARD_261":{"address":5729888,"default_item":3,"flag":0},"POKEDEX_REWARD_262":{"address":5729890,"default_item":3,"flag":0},"POKEDEX_REWARD_263":{"address":5729892,"default_item":3,"flag":0},"POKEDEX_REWARD_264":{"address":5729894,"default_item":3,"flag":0},"POKEDEX_REWARD_265":{"address":5729896,"default_item":3,"flag":0},"POKEDEX_REWARD_266":{"address":5729898,"default_item":3,"flag":0},"POKEDEX_REWARD_267":{"address":5729900,"default_item":3,"flag":0},"POKEDEX_REWARD_268":{"address":5729902,"default_item":3,"flag":0},"POKEDEX_REWARD_269":{"address":5729904,"default_item":3,"flag":0},"POKEDEX_REWARD_270":{"address":5729906,"default_item":3,"flag":0},"POKEDEX_REWARD_271":{"address":5729908,"default_item":3,"flag":0},"POKEDEX_REWARD_272":{"address":5729910,"default_item":3,"flag":0},"POKEDEX_REWARD_273":{"address":5729912,"default_item":3,"flag":0},"POKEDEX_REWARD_274":{"address":5729914,"default_item":3,"flag":0},"POKEDEX_REWARD_275":{"address":5729916,"default_item":3,"flag":0},"POKEDEX_REWARD_276":{"address":5729918,"default_item":3,"flag":0},"POKEDEX_REWARD_277":{"address":5729920,"default_item":3,"flag":0},"POKEDEX_REWARD_278":{"address":5729922,"default_item":3,"flag":0},"POKEDEX_REWARD_279":{"address":5729924,"default_item":3,"flag":0},"POKEDEX_REWARD_280":{"address":5729926,"default_item":3,"flag":0},"POKEDEX_REWARD_281":{"address":5729928,"default_item":3,"flag":0},"POKEDEX_REWARD_282":{"address":5729930,"default_item":3,"flag":0},"POKEDEX_REWARD_283":{"address":5729932,"default_item":3,"flag":0},"POKEDEX_REWARD_284":{"address":5729934,"default_item":3,"flag":0},"POKEDEX_REWARD_285":{"address":5729936,"default_item":3,"flag":0},"POKEDEX_REWARD_286":{"address":5729938,"default_item":3,"flag":0},"POKEDEX_REWARD_287":{"address":5729940,"default_item":3,"flag":0},"POKEDEX_REWARD_288":{"address":5729942,"default_item":3,"flag":0},"POKEDEX_REWARD_289":{"address":5729944,"default_item":3,"flag":0},"POKEDEX_REWARD_290":{"address":5729946,"default_item":3,"flag":0},"POKEDEX_REWARD_291":{"address":5729948,"default_item":3,"flag":0},"POKEDEX_REWARD_292":{"address":5729950,"default_item":3,"flag":0},"POKEDEX_REWARD_293":{"address":5729952,"default_item":3,"flag":0},"POKEDEX_REWARD_294":{"address":5729954,"default_item":3,"flag":0},"POKEDEX_REWARD_295":{"address":5729956,"default_item":3,"flag":0},"POKEDEX_REWARD_296":{"address":5729958,"default_item":3,"flag":0},"POKEDEX_REWARD_297":{"address":5729960,"default_item":3,"flag":0},"POKEDEX_REWARD_298":{"address":5729962,"default_item":3,"flag":0},"POKEDEX_REWARD_299":{"address":5729964,"default_item":3,"flag":0},"POKEDEX_REWARD_300":{"address":5729966,"default_item":3,"flag":0},"POKEDEX_REWARD_301":{"address":5729968,"default_item":3,"flag":0},"POKEDEX_REWARD_302":{"address":5729970,"default_item":3,"flag":0},"POKEDEX_REWARD_303":{"address":5729972,"default_item":3,"flag":0},"POKEDEX_REWARD_304":{"address":5729974,"default_item":3,"flag":0},"POKEDEX_REWARD_305":{"address":5729976,"default_item":3,"flag":0},"POKEDEX_REWARD_306":{"address":5729978,"default_item":3,"flag":0},"POKEDEX_REWARD_307":{"address":5729980,"default_item":3,"flag":0},"POKEDEX_REWARD_308":{"address":5729982,"default_item":3,"flag":0},"POKEDEX_REWARD_309":{"address":5729984,"default_item":3,"flag":0},"POKEDEX_REWARD_310":{"address":5729986,"default_item":3,"flag":0},"POKEDEX_REWARD_311":{"address":5729988,"default_item":3,"flag":0},"POKEDEX_REWARD_312":{"address":5729990,"default_item":3,"flag":0},"POKEDEX_REWARD_313":{"address":5729992,"default_item":3,"flag":0},"POKEDEX_REWARD_314":{"address":5729994,"default_item":3,"flag":0},"POKEDEX_REWARD_315":{"address":5729996,"default_item":3,"flag":0},"POKEDEX_REWARD_316":{"address":5729998,"default_item":3,"flag":0},"POKEDEX_REWARD_317":{"address":5730000,"default_item":3,"flag":0},"POKEDEX_REWARD_318":{"address":5730002,"default_item":3,"flag":0},"POKEDEX_REWARD_319":{"address":5730004,"default_item":3,"flag":0},"POKEDEX_REWARD_320":{"address":5730006,"default_item":3,"flag":0},"POKEDEX_REWARD_321":{"address":5730008,"default_item":3,"flag":0},"POKEDEX_REWARD_322":{"address":5730010,"default_item":3,"flag":0},"POKEDEX_REWARD_323":{"address":5730012,"default_item":3,"flag":0},"POKEDEX_REWARD_324":{"address":5730014,"default_item":3,"flag":0},"POKEDEX_REWARD_325":{"address":5730016,"default_item":3,"flag":0},"POKEDEX_REWARD_326":{"address":5730018,"default_item":3,"flag":0},"POKEDEX_REWARD_327":{"address":5730020,"default_item":3,"flag":0},"POKEDEX_REWARD_328":{"address":5730022,"default_item":3,"flag":0},"POKEDEX_REWARD_329":{"address":5730024,"default_item":3,"flag":0},"POKEDEX_REWARD_330":{"address":5730026,"default_item":3,"flag":0},"POKEDEX_REWARD_331":{"address":5730028,"default_item":3,"flag":0},"POKEDEX_REWARD_332":{"address":5730030,"default_item":3,"flag":0},"POKEDEX_REWARD_333":{"address":5730032,"default_item":3,"flag":0},"POKEDEX_REWARD_334":{"address":5730034,"default_item":3,"flag":0},"POKEDEX_REWARD_335":{"address":5730036,"default_item":3,"flag":0},"POKEDEX_REWARD_336":{"address":5730038,"default_item":3,"flag":0},"POKEDEX_REWARD_337":{"address":5730040,"default_item":3,"flag":0},"POKEDEX_REWARD_338":{"address":5730042,"default_item":3,"flag":0},"POKEDEX_REWARD_339":{"address":5730044,"default_item":3,"flag":0},"POKEDEX_REWARD_340":{"address":5730046,"default_item":3,"flag":0},"POKEDEX_REWARD_341":{"address":5730048,"default_item":3,"flag":0},"POKEDEX_REWARD_342":{"address":5730050,"default_item":3,"flag":0},"POKEDEX_REWARD_343":{"address":5730052,"default_item":3,"flag":0},"POKEDEX_REWARD_344":{"address":5730054,"default_item":3,"flag":0},"POKEDEX_REWARD_345":{"address":5730056,"default_item":3,"flag":0},"POKEDEX_REWARD_346":{"address":5730058,"default_item":3,"flag":0},"POKEDEX_REWARD_347":{"address":5730060,"default_item":3,"flag":0},"POKEDEX_REWARD_348":{"address":5730062,"default_item":3,"flag":0},"POKEDEX_REWARD_349":{"address":5730064,"default_item":3,"flag":0},"POKEDEX_REWARD_350":{"address":5730066,"default_item":3,"flag":0},"POKEDEX_REWARD_351":{"address":5730068,"default_item":3,"flag":0},"POKEDEX_REWARD_352":{"address":5730070,"default_item":3,"flag":0},"POKEDEX_REWARD_353":{"address":5730072,"default_item":3,"flag":0},"POKEDEX_REWARD_354":{"address":5730074,"default_item":3,"flag":0},"POKEDEX_REWARD_355":{"address":5730076,"default_item":3,"flag":0},"POKEDEX_REWARD_356":{"address":5730078,"default_item":3,"flag":0},"POKEDEX_REWARD_357":{"address":5730080,"default_item":3,"flag":0},"POKEDEX_REWARD_358":{"address":5730082,"default_item":3,"flag":0},"POKEDEX_REWARD_359":{"address":5730084,"default_item":3,"flag":0},"POKEDEX_REWARD_360":{"address":5730086,"default_item":3,"flag":0},"POKEDEX_REWARD_361":{"address":5730088,"default_item":3,"flag":0},"POKEDEX_REWARD_362":{"address":5730090,"default_item":3,"flag":0},"POKEDEX_REWARD_363":{"address":5730092,"default_item":3,"flag":0},"POKEDEX_REWARD_364":{"address":5730094,"default_item":3,"flag":0},"POKEDEX_REWARD_365":{"address":5730096,"default_item":3,"flag":0},"POKEDEX_REWARD_366":{"address":5730098,"default_item":3,"flag":0},"POKEDEX_REWARD_367":{"address":5730100,"default_item":3,"flag":0},"POKEDEX_REWARD_368":{"address":5730102,"default_item":3,"flag":0},"POKEDEX_REWARD_369":{"address":5730104,"default_item":3,"flag":0},"POKEDEX_REWARD_370":{"address":5730106,"default_item":3,"flag":0},"POKEDEX_REWARD_371":{"address":5730108,"default_item":3,"flag":0},"POKEDEX_REWARD_372":{"address":5730110,"default_item":3,"flag":0},"POKEDEX_REWARD_373":{"address":5730112,"default_item":3,"flag":0},"POKEDEX_REWARD_374":{"address":5730114,"default_item":3,"flag":0},"POKEDEX_REWARD_375":{"address":5730116,"default_item":3,"flag":0},"POKEDEX_REWARD_376":{"address":5730118,"default_item":3,"flag":0},"POKEDEX_REWARD_377":{"address":5730120,"default_item":3,"flag":0},"POKEDEX_REWARD_378":{"address":5730122,"default_item":3,"flag":0},"POKEDEX_REWARD_379":{"address":5730124,"default_item":3,"flag":0},"POKEDEX_REWARD_380":{"address":5730126,"default_item":3,"flag":0},"POKEDEX_REWARD_381":{"address":5730128,"default_item":3,"flag":0},"POKEDEX_REWARD_382":{"address":5730130,"default_item":3,"flag":0},"POKEDEX_REWARD_383":{"address":5730132,"default_item":3,"flag":0},"POKEDEX_REWARD_384":{"address":5730134,"default_item":3,"flag":0},"POKEDEX_REWARD_385":{"address":5730136,"default_item":3,"flag":0},"POKEDEX_REWARD_386":{"address":5730138,"default_item":3,"flag":0},"TRAINER_AARON_REWARD":{"address":5602878,"default_item":104,"flag":1677},"TRAINER_ABIGAIL_1_REWARD":{"address":5602800,"default_item":106,"flag":1638},"TRAINER_AIDAN_REWARD":{"address":5603432,"default_item":104,"flag":1954},"TRAINER_AISHA_REWARD":{"address":5603598,"default_item":106,"flag":2037},"TRAINER_ALBERTO_REWARD":{"address":5602108,"default_item":108,"flag":1292},"TRAINER_ALBERT_REWARD":{"address":5602244,"default_item":104,"flag":1360},"TRAINER_ALEXA_REWARD":{"address":5603424,"default_item":104,"flag":1950},"TRAINER_ALEXIA_REWARD":{"address":5602264,"default_item":104,"flag":1370},"TRAINER_ALEX_REWARD":{"address":5602910,"default_item":104,"flag":1693},"TRAINER_ALICE_REWARD":{"address":5602980,"default_item":103,"flag":1728},"TRAINER_ALIX_REWARD":{"address":5603584,"default_item":106,"flag":2030},"TRAINER_ALLEN_REWARD":{"address":5602750,"default_item":103,"flag":1613},"TRAINER_ALLISON_REWARD":{"address":5602858,"default_item":104,"flag":1667},"TRAINER_ALYSSA_REWARD":{"address":5603486,"default_item":106,"flag":1981},"TRAINER_AMY_AND_LIV_1_REWARD":{"address":5603046,"default_item":103,"flag":1761},"TRAINER_ANDREA_REWARD":{"address":5603310,"default_item":106,"flag":1893},"TRAINER_ANDRES_1_REWARD":{"address":5603558,"default_item":104,"flag":2017},"TRAINER_ANDREW_REWARD":{"address":5602756,"default_item":106,"flag":1616},"TRAINER_ANGELICA_REWARD":{"address":5602956,"default_item":104,"flag":1716},"TRAINER_ANGELINA_REWARD":{"address":5603508,"default_item":106,"flag":1992},"TRAINER_ANGELO_REWARD":{"address":5603688,"default_item":104,"flag":2082},"TRAINER_ANNA_AND_MEG_1_REWARD":{"address":5602658,"default_item":106,"flag":1567},"TRAINER_ANNIKA_REWARD":{"address":5603088,"default_item":107,"flag":1782},"TRAINER_ANTHONY_REWARD":{"address":5602788,"default_item":106,"flag":1632},"TRAINER_ARCHIE_REWARD":{"address":5602152,"default_item":107,"flag":1314},"TRAINER_ASHLEY_REWARD":{"address":5603394,"default_item":106,"flag":1935},"TRAINER_ATHENA_REWARD":{"address":5603238,"default_item":104,"flag":1857},"TRAINER_ATSUSHI_REWARD":{"address":5602464,"default_item":104,"flag":1470},"TRAINER_AURON_REWARD":{"address":5603096,"default_item":104,"flag":1786},"TRAINER_AUSTINA_REWARD":{"address":5602200,"default_item":103,"flag":1338},"TRAINER_AUTUMN_REWARD":{"address":5602518,"default_item":106,"flag":1497},"TRAINER_AXLE_REWARD":{"address":5602490,"default_item":108,"flag":1483},"TRAINER_BARNY_REWARD":{"address":5602770,"default_item":104,"flag":1623},"TRAINER_BARRY_REWARD":{"address":5602410,"default_item":106,"flag":1443},"TRAINER_BEAU_REWARD":{"address":5602508,"default_item":106,"flag":1492},"TRAINER_BECKY_REWARD":{"address":5603024,"default_item":106,"flag":1750},"TRAINER_BECK_REWARD":{"address":5602912,"default_item":104,"flag":1694},"TRAINER_BENJAMIN_1_REWARD":{"address":5602790,"default_item":106,"flag":1633},"TRAINER_BEN_REWARD":{"address":5602730,"default_item":106,"flag":1603},"TRAINER_BERKE_REWARD":{"address":5602232,"default_item":104,"flag":1354},"TRAINER_BERNIE_1_REWARD":{"address":5602496,"default_item":106,"flag":1486},"TRAINER_BETHANY_REWARD":{"address":5602686,"default_item":107,"flag":1581},"TRAINER_BETH_REWARD":{"address":5602974,"default_item":103,"flag":1725},"TRAINER_BEVERLY_REWARD":{"address":5602966,"default_item":103,"flag":1721},"TRAINER_BIANCA_REWARD":{"address":5603496,"default_item":106,"flag":1986},"TRAINER_BILLY_REWARD":{"address":5602722,"default_item":103,"flag":1599},"TRAINER_BLAKE_REWARD":{"address":5602554,"default_item":108,"flag":1515},"TRAINER_BRANDEN_REWARD":{"address":5603574,"default_item":106,"flag":2025},"TRAINER_BRANDI_REWARD":{"address":5603596,"default_item":106,"flag":2036},"TRAINER_BRAWLY_1_REWARD":{"address":5602616,"default_item":104,"flag":1546},"TRAINER_BRAXTON_REWARD":{"address":5602234,"default_item":104,"flag":1355},"TRAINER_BRENDAN_LILYCOVE_MUDKIP_REWARD":{"address":5603406,"default_item":104,"flag":1941},"TRAINER_BRENDAN_LILYCOVE_TORCHIC_REWARD":{"address":5603410,"default_item":104,"flag":1943},"TRAINER_BRENDAN_LILYCOVE_TREECKO_REWARD":{"address":5603408,"default_item":104,"flag":1942},"TRAINER_BRENDAN_ROUTE_103_MUDKIP_REWARD":{"address":5603124,"default_item":106,"flag":1800},"TRAINER_BRENDAN_ROUTE_103_TORCHIC_REWARD":{"address":5603136,"default_item":106,"flag":1806},"TRAINER_BRENDAN_ROUTE_103_TREECKO_REWARD":{"address":5603130,"default_item":106,"flag":1803},"TRAINER_BRENDAN_ROUTE_110_MUDKIP_REWARD":{"address":5603126,"default_item":104,"flag":1801},"TRAINER_BRENDAN_ROUTE_110_TORCHIC_REWARD":{"address":5603138,"default_item":104,"flag":1807},"TRAINER_BRENDAN_ROUTE_110_TREECKO_REWARD":{"address":5603132,"default_item":104,"flag":1804},"TRAINER_BRENDAN_ROUTE_119_MUDKIP_REWARD":{"address":5603128,"default_item":104,"flag":1802},"TRAINER_BRENDAN_ROUTE_119_TORCHIC_REWARD":{"address":5603140,"default_item":104,"flag":1808},"TRAINER_BRENDAN_ROUTE_119_TREECKO_REWARD":{"address":5603134,"default_item":104,"flag":1805},"TRAINER_BRENDAN_RUSTBORO_MUDKIP_REWARD":{"address":5603270,"default_item":108,"flag":1873},"TRAINER_BRENDAN_RUSTBORO_TORCHIC_REWARD":{"address":5603282,"default_item":108,"flag":1879},"TRAINER_BRENDAN_RUSTBORO_TREECKO_REWARD":{"address":5603268,"default_item":108,"flag":1872},"TRAINER_BRENDA_REWARD":{"address":5602992,"default_item":106,"flag":1734},"TRAINER_BRENDEN_REWARD":{"address":5603228,"default_item":106,"flag":1852},"TRAINER_BRENT_REWARD":{"address":5602530,"default_item":104,"flag":1503},"TRAINER_BRIANNA_REWARD":{"address":5602320,"default_item":110,"flag":1398},"TRAINER_BRICE_REWARD":{"address":5603336,"default_item":106,"flag":1906},"TRAINER_BRIDGET_REWARD":{"address":5602342,"default_item":107,"flag":1409},"TRAINER_BROOKE_1_REWARD":{"address":5602272,"default_item":108,"flag":1374},"TRAINER_BRYANT_REWARD":{"address":5603576,"default_item":106,"flag":2026},"TRAINER_BRYAN_REWARD":{"address":5603572,"default_item":104,"flag":2024},"TRAINER_CALE_REWARD":{"address":5603612,"default_item":104,"flag":2044},"TRAINER_CALLIE_REWARD":{"address":5603610,"default_item":106,"flag":2043},"TRAINER_CALVIN_1_REWARD":{"address":5602720,"default_item":103,"flag":1598},"TRAINER_CAMDEN_REWARD":{"address":5602832,"default_item":104,"flag":1654},"TRAINER_CAMERON_1_REWARD":{"address":5602560,"default_item":108,"flag":1518},"TRAINER_CAMRON_REWARD":{"address":5603562,"default_item":104,"flag":2019},"TRAINER_CARLEE_REWARD":{"address":5603012,"default_item":106,"flag":1744},"TRAINER_CAROLINA_REWARD":{"address":5603566,"default_item":104,"flag":2021},"TRAINER_CAROLINE_REWARD":{"address":5602282,"default_item":104,"flag":1379},"TRAINER_CAROL_REWARD":{"address":5603026,"default_item":106,"flag":1751},"TRAINER_CARTER_REWARD":{"address":5602774,"default_item":104,"flag":1625},"TRAINER_CATHERINE_1_REWARD":{"address":5603202,"default_item":104,"flag":1839},"TRAINER_CEDRIC_REWARD":{"address":5603034,"default_item":108,"flag":1755},"TRAINER_CELIA_REWARD":{"address":5603570,"default_item":106,"flag":2023},"TRAINER_CELINA_REWARD":{"address":5603494,"default_item":108,"flag":1985},"TRAINER_CHAD_REWARD":{"address":5602432,"default_item":106,"flag":1454},"TRAINER_CHANDLER_REWARD":{"address":5603480,"default_item":103,"flag":1978},"TRAINER_CHARLIE_REWARD":{"address":5602216,"default_item":103,"flag":1346},"TRAINER_CHARLOTTE_REWARD":{"address":5603512,"default_item":106,"flag":1994},"TRAINER_CHASE_REWARD":{"address":5602840,"default_item":104,"flag":1658},"TRAINER_CHESTER_REWARD":{"address":5602900,"default_item":108,"flag":1688},"TRAINER_CHIP_REWARD":{"address":5602174,"default_item":104,"flag":1325},"TRAINER_CHRIS_REWARD":{"address":5603470,"default_item":108,"flag":1973},"TRAINER_CINDY_1_REWARD":{"address":5602312,"default_item":104,"flag":1394},"TRAINER_CLARENCE_REWARD":{"address":5603244,"default_item":106,"flag":1860},"TRAINER_CLARISSA_REWARD":{"address":5602954,"default_item":104,"flag":1715},"TRAINER_CLARK_REWARD":{"address":5603346,"default_item":106,"flag":1911},"TRAINER_CLAUDE_REWARD":{"address":5602760,"default_item":108,"flag":1618},"TRAINER_CLIFFORD_REWARD":{"address":5603252,"default_item":107,"flag":1864},"TRAINER_COBY_REWARD":{"address":5603502,"default_item":106,"flag":1989},"TRAINER_COLE_REWARD":{"address":5602486,"default_item":108,"flag":1481},"TRAINER_COLIN_REWARD":{"address":5602894,"default_item":108,"flag":1685},"TRAINER_COLTON_REWARD":{"address":5602672,"default_item":107,"flag":1574},"TRAINER_CONNIE_REWARD":{"address":5602340,"default_item":107,"flag":1408},"TRAINER_CONOR_REWARD":{"address":5603106,"default_item":104,"flag":1791},"TRAINER_CORY_1_REWARD":{"address":5603564,"default_item":108,"flag":2020},"TRAINER_CRISSY_REWARD":{"address":5603312,"default_item":106,"flag":1894},"TRAINER_CRISTIAN_REWARD":{"address":5603232,"default_item":106,"flag":1854},"TRAINER_CRISTIN_1_REWARD":{"address":5603618,"default_item":104,"flag":2047},"TRAINER_CYNDY_1_REWARD":{"address":5602938,"default_item":106,"flag":1707},"TRAINER_DAISUKE_REWARD":{"address":5602462,"default_item":106,"flag":1469},"TRAINER_DAISY_REWARD":{"address":5602156,"default_item":106,"flag":1316},"TRAINER_DALE_REWARD":{"address":5602766,"default_item":106,"flag":1621},"TRAINER_DALTON_1_REWARD":{"address":5602476,"default_item":106,"flag":1476},"TRAINER_DANA_REWARD":{"address":5603000,"default_item":106,"flag":1738},"TRAINER_DANIELLE_REWARD":{"address":5603384,"default_item":106,"flag":1930},"TRAINER_DAPHNE_REWARD":{"address":5602314,"default_item":110,"flag":1395},"TRAINER_DARCY_REWARD":{"address":5603550,"default_item":104,"flag":2013},"TRAINER_DARIAN_REWARD":{"address":5603476,"default_item":106,"flag":1976},"TRAINER_DARIUS_REWARD":{"address":5603690,"default_item":108,"flag":2083},"TRAINER_DARRIN_REWARD":{"address":5602392,"default_item":103,"flag":1434},"TRAINER_DAVID_REWARD":{"address":5602400,"default_item":103,"flag":1438},"TRAINER_DAVIS_REWARD":{"address":5603162,"default_item":106,"flag":1819},"TRAINER_DAWSON_REWARD":{"address":5603472,"default_item":104,"flag":1974},"TRAINER_DAYTON_REWARD":{"address":5603604,"default_item":108,"flag":2040},"TRAINER_DEANDRE_REWARD":{"address":5603514,"default_item":103,"flag":1995},"TRAINER_DEAN_REWARD":{"address":5602412,"default_item":103,"flag":1444},"TRAINER_DEBRA_REWARD":{"address":5603004,"default_item":106,"flag":1740},"TRAINER_DECLAN_REWARD":{"address":5602114,"default_item":106,"flag":1295},"TRAINER_DEMETRIUS_REWARD":{"address":5602834,"default_item":106,"flag":1655},"TRAINER_DENISE_REWARD":{"address":5602972,"default_item":103,"flag":1724},"TRAINER_DEREK_REWARD":{"address":5602538,"default_item":108,"flag":1507},"TRAINER_DEVAN_REWARD":{"address":5603590,"default_item":106,"flag":2033},"TRAINER_DEZ_AND_LUKE_REWARD":{"address":5603364,"default_item":108,"flag":1920},"TRAINER_DIANA_1_REWARD":{"address":5603032,"default_item":106,"flag":1754},"TRAINER_DIANNE_REWARD":{"address":5602918,"default_item":104,"flag":1697},"TRAINER_DILLON_REWARD":{"address":5602738,"default_item":106,"flag":1607},"TRAINER_DOMINIK_REWARD":{"address":5602388,"default_item":103,"flag":1432},"TRAINER_DONALD_REWARD":{"address":5602532,"default_item":104,"flag":1504},"TRAINER_DONNY_REWARD":{"address":5602852,"default_item":104,"flag":1664},"TRAINER_DOUGLAS_REWARD":{"address":5602390,"default_item":103,"flag":1433},"TRAINER_DOUG_REWARD":{"address":5603320,"default_item":106,"flag":1898},"TRAINER_DRAKE_REWARD":{"address":5602612,"default_item":110,"flag":1544},"TRAINER_DREW_REWARD":{"address":5602506,"default_item":106,"flag":1491},"TRAINER_DUNCAN_REWARD":{"address":5603076,"default_item":108,"flag":1776},"TRAINER_DUSTY_1_REWARD":{"address":5602172,"default_item":104,"flag":1324},"TRAINER_DWAYNE_REWARD":{"address":5603070,"default_item":106,"flag":1773},"TRAINER_DYLAN_1_REWARD":{"address":5602812,"default_item":106,"flag":1644},"TRAINER_EDGAR_REWARD":{"address":5602242,"default_item":104,"flag":1359},"TRAINER_EDMOND_REWARD":{"address":5603066,"default_item":106,"flag":1771},"TRAINER_EDWARDO_REWARD":{"address":5602892,"default_item":108,"flag":1684},"TRAINER_EDWARD_REWARD":{"address":5602548,"default_item":106,"flag":1512},"TRAINER_EDWIN_1_REWARD":{"address":5603108,"default_item":108,"flag":1792},"TRAINER_ED_REWARD":{"address":5602110,"default_item":104,"flag":1293},"TRAINER_ELIJAH_REWARD":{"address":5603568,"default_item":108,"flag":2022},"TRAINER_ELI_REWARD":{"address":5603086,"default_item":108,"flag":1781},"TRAINER_ELLIOT_1_REWARD":{"address":5602762,"default_item":106,"flag":1619},"TRAINER_ERIC_REWARD":{"address":5603348,"default_item":108,"flag":1912},"TRAINER_ERNEST_1_REWARD":{"address":5603068,"default_item":104,"flag":1772},"TRAINER_ETHAN_1_REWARD":{"address":5602516,"default_item":106,"flag":1496},"TRAINER_FABIAN_REWARD":{"address":5603602,"default_item":108,"flag":2039},"TRAINER_FELIX_REWARD":{"address":5602160,"default_item":104,"flag":1318},"TRAINER_FERNANDO_1_REWARD":{"address":5602474,"default_item":108,"flag":1475},"TRAINER_FLANNERY_1_REWARD":{"address":5602620,"default_item":107,"flag":1548},"TRAINER_FLINT_REWARD":{"address":5603392,"default_item":106,"flag":1934},"TRAINER_FOSTER_REWARD":{"address":5602176,"default_item":104,"flag":1326},"TRAINER_FRANKLIN_REWARD":{"address":5602424,"default_item":106,"flag":1450},"TRAINER_FREDRICK_REWARD":{"address":5602142,"default_item":104,"flag":1309},"TRAINER_GABRIELLE_1_REWARD":{"address":5602102,"default_item":104,"flag":1289},"TRAINER_GARRET_REWARD":{"address":5602360,"default_item":110,"flag":1418},"TRAINER_GARRISON_REWARD":{"address":5603178,"default_item":104,"flag":1827},"TRAINER_GEORGE_REWARD":{"address":5602230,"default_item":104,"flag":1353},"TRAINER_GERALD_REWARD":{"address":5603380,"default_item":104,"flag":1928},"TRAINER_GILBERT_REWARD":{"address":5602422,"default_item":106,"flag":1449},"TRAINER_GINA_AND_MIA_1_REWARD":{"address":5603050,"default_item":103,"flag":1763},"TRAINER_GLACIA_REWARD":{"address":5602610,"default_item":110,"flag":1543},"TRAINER_GRACE_REWARD":{"address":5602984,"default_item":106,"flag":1730},"TRAINER_GREG_REWARD":{"address":5603322,"default_item":106,"flag":1899},"TRAINER_GRUNT_AQUA_HIDEOUT_1_REWARD":{"address":5602088,"default_item":106,"flag":1282},"TRAINER_GRUNT_AQUA_HIDEOUT_2_REWARD":{"address":5602090,"default_item":106,"flag":1283},"TRAINER_GRUNT_AQUA_HIDEOUT_3_REWARD":{"address":5602092,"default_item":106,"flag":1284},"TRAINER_GRUNT_AQUA_HIDEOUT_4_REWARD":{"address":5602094,"default_item":106,"flag":1285},"TRAINER_GRUNT_AQUA_HIDEOUT_5_REWARD":{"address":5602138,"default_item":106,"flag":1307},"TRAINER_GRUNT_AQUA_HIDEOUT_6_REWARD":{"address":5602140,"default_item":106,"flag":1308},"TRAINER_GRUNT_AQUA_HIDEOUT_7_REWARD":{"address":5602468,"default_item":106,"flag":1472},"TRAINER_GRUNT_AQUA_HIDEOUT_8_REWARD":{"address":5602470,"default_item":106,"flag":1473},"TRAINER_GRUNT_MAGMA_HIDEOUT_10_REWARD":{"address":5603534,"default_item":106,"flag":2005},"TRAINER_GRUNT_MAGMA_HIDEOUT_11_REWARD":{"address":5603536,"default_item":106,"flag":2006},"TRAINER_GRUNT_MAGMA_HIDEOUT_12_REWARD":{"address":5603538,"default_item":106,"flag":2007},"TRAINER_GRUNT_MAGMA_HIDEOUT_13_REWARD":{"address":5603540,"default_item":106,"flag":2008},"TRAINER_GRUNT_MAGMA_HIDEOUT_14_REWARD":{"address":5603542,"default_item":106,"flag":2009},"TRAINER_GRUNT_MAGMA_HIDEOUT_15_REWARD":{"address":5603544,"default_item":106,"flag":2010},"TRAINER_GRUNT_MAGMA_HIDEOUT_16_REWARD":{"address":5603546,"default_item":106,"flag":2011},"TRAINER_GRUNT_MAGMA_HIDEOUT_1_REWARD":{"address":5603516,"default_item":106,"flag":1996},"TRAINER_GRUNT_MAGMA_HIDEOUT_2_REWARD":{"address":5603518,"default_item":106,"flag":1997},"TRAINER_GRUNT_MAGMA_HIDEOUT_3_REWARD":{"address":5603520,"default_item":106,"flag":1998},"TRAINER_GRUNT_MAGMA_HIDEOUT_4_REWARD":{"address":5603522,"default_item":106,"flag":1999},"TRAINER_GRUNT_MAGMA_HIDEOUT_5_REWARD":{"address":5603524,"default_item":106,"flag":2000},"TRAINER_GRUNT_MAGMA_HIDEOUT_6_REWARD":{"address":5603526,"default_item":106,"flag":2001},"TRAINER_GRUNT_MAGMA_HIDEOUT_7_REWARD":{"address":5603528,"default_item":106,"flag":2002},"TRAINER_GRUNT_MAGMA_HIDEOUT_8_REWARD":{"address":5603530,"default_item":106,"flag":2003},"TRAINER_GRUNT_MAGMA_HIDEOUT_9_REWARD":{"address":5603532,"default_item":106,"flag":2004},"TRAINER_GRUNT_MT_CHIMNEY_1_REWARD":{"address":5602376,"default_item":106,"flag":1426},"TRAINER_GRUNT_MT_CHIMNEY_2_REWARD":{"address":5603242,"default_item":106,"flag":1859},"TRAINER_GRUNT_MT_PYRE_1_REWARD":{"address":5602130,"default_item":106,"flag":1303},"TRAINER_GRUNT_MT_PYRE_2_REWARD":{"address":5602132,"default_item":106,"flag":1304},"TRAINER_GRUNT_MT_PYRE_3_REWARD":{"address":5602134,"default_item":106,"flag":1305},"TRAINER_GRUNT_MT_PYRE_4_REWARD":{"address":5603222,"default_item":106,"flag":1849},"TRAINER_GRUNT_MUSEUM_1_REWARD":{"address":5602124,"default_item":106,"flag":1300},"TRAINER_GRUNT_MUSEUM_2_REWARD":{"address":5602126,"default_item":106,"flag":1301},"TRAINER_GRUNT_PETALBURG_WOODS_REWARD":{"address":5602104,"default_item":103,"flag":1290},"TRAINER_GRUNT_RUSTURF_TUNNEL_REWARD":{"address":5602116,"default_item":103,"flag":1296},"TRAINER_GRUNT_SEAFLOOR_CAVERN_1_REWARD":{"address":5602096,"default_item":108,"flag":1286},"TRAINER_GRUNT_SEAFLOOR_CAVERN_2_REWARD":{"address":5602098,"default_item":108,"flag":1287},"TRAINER_GRUNT_SEAFLOOR_CAVERN_3_REWARD":{"address":5602100,"default_item":108,"flag":1288},"TRAINER_GRUNT_SEAFLOOR_CAVERN_4_REWARD":{"address":5602112,"default_item":108,"flag":1294},"TRAINER_GRUNT_SEAFLOOR_CAVERN_5_REWARD":{"address":5603218,"default_item":108,"flag":1847},"TRAINER_GRUNT_SPACE_CENTER_1_REWARD":{"address":5602128,"default_item":106,"flag":1302},"TRAINER_GRUNT_SPACE_CENTER_2_REWARD":{"address":5602316,"default_item":106,"flag":1396},"TRAINER_GRUNT_SPACE_CENTER_3_REWARD":{"address":5603256,"default_item":106,"flag":1866},"TRAINER_GRUNT_SPACE_CENTER_4_REWARD":{"address":5603258,"default_item":106,"flag":1867},"TRAINER_GRUNT_SPACE_CENTER_5_REWARD":{"address":5603260,"default_item":106,"flag":1868},"TRAINER_GRUNT_SPACE_CENTER_6_REWARD":{"address":5603262,"default_item":106,"flag":1869},"TRAINER_GRUNT_SPACE_CENTER_7_REWARD":{"address":5603264,"default_item":106,"flag":1870},"TRAINER_GRUNT_WEATHER_INST_1_REWARD":{"address":5602118,"default_item":106,"flag":1297},"TRAINER_GRUNT_WEATHER_INST_2_REWARD":{"address":5602120,"default_item":106,"flag":1298},"TRAINER_GRUNT_WEATHER_INST_3_REWARD":{"address":5602122,"default_item":106,"flag":1299},"TRAINER_GRUNT_WEATHER_INST_4_REWARD":{"address":5602136,"default_item":106,"flag":1306},"TRAINER_GRUNT_WEATHER_INST_5_REWARD":{"address":5603276,"default_item":106,"flag":1876},"TRAINER_GWEN_REWARD":{"address":5602202,"default_item":103,"flag":1339},"TRAINER_HAILEY_REWARD":{"address":5603478,"default_item":103,"flag":1977},"TRAINER_HALEY_1_REWARD":{"address":5603292,"default_item":103,"flag":1884},"TRAINER_HALLE_REWARD":{"address":5603176,"default_item":104,"flag":1826},"TRAINER_HANNAH_REWARD":{"address":5602572,"default_item":108,"flag":1524},"TRAINER_HARRISON_REWARD":{"address":5603240,"default_item":106,"flag":1858},"TRAINER_HAYDEN_REWARD":{"address":5603498,"default_item":106,"flag":1987},"TRAINER_HECTOR_REWARD":{"address":5603110,"default_item":104,"flag":1793},"TRAINER_HEIDI_REWARD":{"address":5603022,"default_item":106,"flag":1749},"TRAINER_HELENE_REWARD":{"address":5603586,"default_item":106,"flag":2031},"TRAINER_HENRY_REWARD":{"address":5603420,"default_item":104,"flag":1948},"TRAINER_HERMAN_REWARD":{"address":5602418,"default_item":106,"flag":1447},"TRAINER_HIDEO_REWARD":{"address":5603386,"default_item":106,"flag":1931},"TRAINER_HITOSHI_REWARD":{"address":5602444,"default_item":104,"flag":1460},"TRAINER_HOPE_REWARD":{"address":5602276,"default_item":104,"flag":1376},"TRAINER_HUDSON_REWARD":{"address":5603104,"default_item":104,"flag":1790},"TRAINER_HUEY_REWARD":{"address":5603064,"default_item":106,"flag":1770},"TRAINER_HUGH_REWARD":{"address":5602882,"default_item":108,"flag":1679},"TRAINER_HUMBERTO_REWARD":{"address":5602888,"default_item":108,"flag":1682},"TRAINER_IMANI_REWARD":{"address":5602968,"default_item":103,"flag":1722},"TRAINER_IRENE_REWARD":{"address":5603036,"default_item":106,"flag":1756},"TRAINER_ISAAC_1_REWARD":{"address":5603160,"default_item":106,"flag":1818},"TRAINER_ISABELLA_REWARD":{"address":5603274,"default_item":104,"flag":1875},"TRAINER_ISABELLE_REWARD":{"address":5603556,"default_item":103,"flag":2016},"TRAINER_ISABEL_1_REWARD":{"address":5602688,"default_item":104,"flag":1582},"TRAINER_ISAIAH_1_REWARD":{"address":5602836,"default_item":104,"flag":1656},"TRAINER_ISOBEL_REWARD":{"address":5602850,"default_item":104,"flag":1663},"TRAINER_IVAN_REWARD":{"address":5602758,"default_item":106,"flag":1617},"TRAINER_JACE_REWARD":{"address":5602492,"default_item":108,"flag":1484},"TRAINER_JACKI_1_REWARD":{"address":5602582,"default_item":108,"flag":1529},"TRAINER_JACKSON_1_REWARD":{"address":5603188,"default_item":104,"flag":1832},"TRAINER_JACK_REWARD":{"address":5602428,"default_item":106,"flag":1452},"TRAINER_JACLYN_REWARD":{"address":5602570,"default_item":106,"flag":1523},"TRAINER_JACOB_REWARD":{"address":5602786,"default_item":106,"flag":1631},"TRAINER_JAIDEN_REWARD":{"address":5603582,"default_item":106,"flag":2029},"TRAINER_JAMES_1_REWARD":{"address":5603326,"default_item":103,"flag":1901},"TRAINER_JANICE_REWARD":{"address":5603294,"default_item":103,"flag":1885},"TRAINER_JANI_REWARD":{"address":5602920,"default_item":103,"flag":1698},"TRAINER_JARED_REWARD":{"address":5602886,"default_item":108,"flag":1681},"TRAINER_JASMINE_REWARD":{"address":5602802,"default_item":103,"flag":1639},"TRAINER_JAYLEN_REWARD":{"address":5602736,"default_item":106,"flag":1606},"TRAINER_JAZMYN_REWARD":{"address":5603090,"default_item":106,"flag":1783},"TRAINER_JEFFREY_1_REWARD":{"address":5602536,"default_item":104,"flag":1506},"TRAINER_JEFF_REWARD":{"address":5602488,"default_item":108,"flag":1482},"TRAINER_JENNA_REWARD":{"address":5603204,"default_item":104,"flag":1840},"TRAINER_JENNIFER_REWARD":{"address":5602274,"default_item":104,"flag":1375},"TRAINER_JENNY_1_REWARD":{"address":5602982,"default_item":106,"flag":1729},"TRAINER_JEROME_REWARD":{"address":5602396,"default_item":103,"flag":1436},"TRAINER_JERRY_1_REWARD":{"address":5602630,"default_item":103,"flag":1553},"TRAINER_JESSICA_1_REWARD":{"address":5602338,"default_item":104,"flag":1407},"TRAINER_JOCELYN_REWARD":{"address":5602934,"default_item":106,"flag":1705},"TRAINER_JODY_REWARD":{"address":5602266,"default_item":104,"flag":1371},"TRAINER_JOEY_REWARD":{"address":5602728,"default_item":103,"flag":1602},"TRAINER_JOHANNA_REWARD":{"address":5603378,"default_item":104,"flag":1927},"TRAINER_JOHNSON_REWARD":{"address":5603592,"default_item":103,"flag":2034},"TRAINER_JOHN_AND_JAY_1_REWARD":{"address":5603446,"default_item":104,"flag":1961},"TRAINER_JONAH_REWARD":{"address":5603418,"default_item":104,"flag":1947},"TRAINER_JONAS_REWARD":{"address":5603092,"default_item":106,"flag":1784},"TRAINER_JONATHAN_REWARD":{"address":5603280,"default_item":104,"flag":1878},"TRAINER_JOSEPH_REWARD":{"address":5603484,"default_item":106,"flag":1980},"TRAINER_JOSE_REWARD":{"address":5603318,"default_item":103,"flag":1897},"TRAINER_JOSH_REWARD":{"address":5602724,"default_item":103,"flag":1600},"TRAINER_JOSUE_REWARD":{"address":5603560,"default_item":108,"flag":2018},"TRAINER_JUAN_1_REWARD":{"address":5602628,"default_item":109,"flag":1552},"TRAINER_JULIE_REWARD":{"address":5602284,"default_item":104,"flag":1380},"TRAINER_JULIO_REWARD":{"address":5603216,"default_item":108,"flag":1846},"TRAINER_KAI_REWARD":{"address":5603510,"default_item":108,"flag":1993},"TRAINER_KALEB_REWARD":{"address":5603482,"default_item":104,"flag":1979},"TRAINER_KARA_REWARD":{"address":5602998,"default_item":106,"flag":1737},"TRAINER_KAREN_1_REWARD":{"address":5602644,"default_item":103,"flag":1560},"TRAINER_KATELYNN_REWARD":{"address":5602734,"default_item":104,"flag":1605},"TRAINER_KATELYN_1_REWARD":{"address":5602856,"default_item":104,"flag":1666},"TRAINER_KATE_AND_JOY_REWARD":{"address":5602656,"default_item":106,"flag":1566},"TRAINER_KATHLEEN_REWARD":{"address":5603250,"default_item":108,"flag":1863},"TRAINER_KATIE_REWARD":{"address":5602994,"default_item":106,"flag":1735},"TRAINER_KAYLA_REWARD":{"address":5602578,"default_item":106,"flag":1527},"TRAINER_KAYLEY_REWARD":{"address":5603094,"default_item":104,"flag":1785},"TRAINER_KEEGAN_REWARD":{"address":5602494,"default_item":108,"flag":1485},"TRAINER_KEIGO_REWARD":{"address":5603388,"default_item":106,"flag":1932},"TRAINER_KELVIN_REWARD":{"address":5603098,"default_item":104,"flag":1787},"TRAINER_KENT_REWARD":{"address":5603324,"default_item":106,"flag":1900},"TRAINER_KEVIN_REWARD":{"address":5602426,"default_item":106,"flag":1451},"TRAINER_KIM_AND_IRIS_REWARD":{"address":5603440,"default_item":106,"flag":1958},"TRAINER_KINDRA_REWARD":{"address":5602296,"default_item":108,"flag":1386},"TRAINER_KIRA_AND_DAN_1_REWARD":{"address":5603368,"default_item":108,"flag":1922},"TRAINER_KIRK_REWARD":{"address":5602466,"default_item":106,"flag":1471},"TRAINER_KIYO_REWARD":{"address":5602446,"default_item":104,"flag":1461},"TRAINER_KOICHI_REWARD":{"address":5602448,"default_item":108,"flag":1462},"TRAINER_KOJI_1_REWARD":{"address":5603428,"default_item":104,"flag":1952},"TRAINER_KYLA_REWARD":{"address":5602970,"default_item":103,"flag":1723},"TRAINER_KYRA_REWARD":{"address":5603580,"default_item":104,"flag":2028},"TRAINER_LAO_1_REWARD":{"address":5602922,"default_item":103,"flag":1699},"TRAINER_LARRY_REWARD":{"address":5602510,"default_item":106,"flag":1493},"TRAINER_LAURA_REWARD":{"address":5602936,"default_item":106,"flag":1706},"TRAINER_LAUREL_REWARD":{"address":5603010,"default_item":106,"flag":1743},"TRAINER_LAWRENCE_REWARD":{"address":5603504,"default_item":106,"flag":1990},"TRAINER_LEAH_REWARD":{"address":5602154,"default_item":108,"flag":1315},"TRAINER_LEA_AND_JED_REWARD":{"address":5603366,"default_item":104,"flag":1921},"TRAINER_LENNY_REWARD":{"address":5603340,"default_item":108,"flag":1908},"TRAINER_LEONARDO_REWARD":{"address":5603236,"default_item":106,"flag":1856},"TRAINER_LEONARD_REWARD":{"address":5603074,"default_item":104,"flag":1775},"TRAINER_LEONEL_REWARD":{"address":5603608,"default_item":104,"flag":2042},"TRAINER_LILA_AND_ROY_1_REWARD":{"address":5603458,"default_item":106,"flag":1967},"TRAINER_LILITH_REWARD":{"address":5603230,"default_item":106,"flag":1853},"TRAINER_LINDA_REWARD":{"address":5603006,"default_item":106,"flag":1741},"TRAINER_LISA_AND_RAY_REWARD":{"address":5603468,"default_item":106,"flag":1972},"TRAINER_LOLA_1_REWARD":{"address":5602198,"default_item":103,"flag":1337},"TRAINER_LORENZO_REWARD":{"address":5603190,"default_item":104,"flag":1833},"TRAINER_LUCAS_1_REWARD":{"address":5603342,"default_item":108,"flag":1909},"TRAINER_LUIS_REWARD":{"address":5602386,"default_item":103,"flag":1431},"TRAINER_LUNG_REWARD":{"address":5602924,"default_item":103,"flag":1700},"TRAINER_LYDIA_1_REWARD":{"address":5603174,"default_item":106,"flag":1825},"TRAINER_LYLE_REWARD":{"address":5603316,"default_item":103,"flag":1896},"TRAINER_MACEY_REWARD":{"address":5603266,"default_item":108,"flag":1871},"TRAINER_MADELINE_1_REWARD":{"address":5602952,"default_item":108,"flag":1714},"TRAINER_MAKAYLA_REWARD":{"address":5603600,"default_item":104,"flag":2038},"TRAINER_MARCEL_REWARD":{"address":5602106,"default_item":104,"flag":1291},"TRAINER_MARCOS_REWARD":{"address":5603488,"default_item":106,"flag":1982},"TRAINER_MARC_REWARD":{"address":5603226,"default_item":106,"flag":1851},"TRAINER_MARIA_1_REWARD":{"address":5602822,"default_item":106,"flag":1649},"TRAINER_MARK_REWARD":{"address":5602374,"default_item":104,"flag":1425},"TRAINER_MARLENE_REWARD":{"address":5603588,"default_item":106,"flag":2032},"TRAINER_MARLEY_REWARD":{"address":5603100,"default_item":104,"flag":1788},"TRAINER_MARY_REWARD":{"address":5602262,"default_item":104,"flag":1369},"TRAINER_MATTHEW_REWARD":{"address":5602398,"default_item":103,"flag":1437},"TRAINER_MATT_REWARD":{"address":5602144,"default_item":104,"flag":1310},"TRAINER_MAURA_REWARD":{"address":5602576,"default_item":108,"flag":1526},"TRAINER_MAXIE_MAGMA_HIDEOUT_REWARD":{"address":5603286,"default_item":107,"flag":1881},"TRAINER_MAXIE_MT_CHIMNEY_REWARD":{"address":5603288,"default_item":104,"flag":1882},"TRAINER_MAY_LILYCOVE_MUDKIP_REWARD":{"address":5603412,"default_item":104,"flag":1944},"TRAINER_MAY_LILYCOVE_TORCHIC_REWARD":{"address":5603416,"default_item":104,"flag":1946},"TRAINER_MAY_LILYCOVE_TREECKO_REWARD":{"address":5603414,"default_item":104,"flag":1945},"TRAINER_MAY_ROUTE_103_MUDKIP_REWARD":{"address":5603142,"default_item":106,"flag":1809},"TRAINER_MAY_ROUTE_103_TORCHIC_REWARD":{"address":5603154,"default_item":106,"flag":1815},"TRAINER_MAY_ROUTE_103_TREECKO_REWARD":{"address":5603148,"default_item":106,"flag":1812},"TRAINER_MAY_ROUTE_110_MUDKIP_REWARD":{"address":5603144,"default_item":104,"flag":1810},"TRAINER_MAY_ROUTE_110_TORCHIC_REWARD":{"address":5603156,"default_item":104,"flag":1816},"TRAINER_MAY_ROUTE_110_TREECKO_REWARD":{"address":5603150,"default_item":104,"flag":1813},"TRAINER_MAY_ROUTE_119_MUDKIP_REWARD":{"address":5603146,"default_item":104,"flag":1811},"TRAINER_MAY_ROUTE_119_TORCHIC_REWARD":{"address":5603158,"default_item":104,"flag":1817},"TRAINER_MAY_ROUTE_119_TREECKO_REWARD":{"address":5603152,"default_item":104,"flag":1814},"TRAINER_MAY_RUSTBORO_MUDKIP_REWARD":{"address":5603284,"default_item":108,"flag":1880},"TRAINER_MAY_RUSTBORO_TORCHIC_REWARD":{"address":5603622,"default_item":108,"flag":2049},"TRAINER_MAY_RUSTBORO_TREECKO_REWARD":{"address":5603620,"default_item":108,"flag":2048},"TRAINER_MELINA_REWARD":{"address":5603594,"default_item":106,"flag":2035},"TRAINER_MELISSA_REWARD":{"address":5602332,"default_item":104,"flag":1404},"TRAINER_MEL_AND_PAUL_REWARD":{"address":5603444,"default_item":108,"flag":1960},"TRAINER_MICAH_REWARD":{"address":5602594,"default_item":107,"flag":1535},"TRAINER_MICHELLE_REWARD":{"address":5602280,"default_item":104,"flag":1378},"TRAINER_MIGUEL_1_REWARD":{"address":5602670,"default_item":104,"flag":1573},"TRAINER_MIKE_2_REWARD":{"address":5603354,"default_item":106,"flag":1915},"TRAINER_MISSY_REWARD":{"address":5602978,"default_item":103,"flag":1727},"TRAINER_MITCHELL_REWARD":{"address":5603164,"default_item":104,"flag":1820},"TRAINER_MIU_AND_YUKI_REWARD":{"address":5603052,"default_item":106,"flag":1764},"TRAINER_MOLLIE_REWARD":{"address":5602358,"default_item":104,"flag":1417},"TRAINER_MYLES_REWARD":{"address":5603614,"default_item":104,"flag":2045},"TRAINER_NANCY_REWARD":{"address":5603028,"default_item":106,"flag":1752},"TRAINER_NAOMI_REWARD":{"address":5602322,"default_item":110,"flag":1399},"TRAINER_NATE_REWARD":{"address":5603248,"default_item":107,"flag":1862},"TRAINER_NED_REWARD":{"address":5602764,"default_item":106,"flag":1620},"TRAINER_NICHOLAS_REWARD":{"address":5603254,"default_item":108,"flag":1865},"TRAINER_NICOLAS_1_REWARD":{"address":5602868,"default_item":104,"flag":1672},"TRAINER_NIKKI_REWARD":{"address":5602990,"default_item":106,"flag":1733},"TRAINER_NOB_1_REWARD":{"address":5602450,"default_item":106,"flag":1463},"TRAINER_NOLAN_REWARD":{"address":5602768,"default_item":108,"flag":1622},"TRAINER_NOLEN_REWARD":{"address":5602406,"default_item":106,"flag":1441},"TRAINER_NORMAN_1_REWARD":{"address":5602622,"default_item":107,"flag":1549},"TRAINER_OLIVIA_REWARD":{"address":5602344,"default_item":107,"flag":1410},"TRAINER_OWEN_REWARD":{"address":5602250,"default_item":104,"flag":1363},"TRAINER_PABLO_1_REWARD":{"address":5602838,"default_item":104,"flag":1657},"TRAINER_PARKER_REWARD":{"address":5602228,"default_item":104,"flag":1352},"TRAINER_PAT_REWARD":{"address":5603616,"default_item":104,"flag":2046},"TRAINER_PAXTON_REWARD":{"address":5603272,"default_item":104,"flag":1874},"TRAINER_PERRY_REWARD":{"address":5602880,"default_item":108,"flag":1678},"TRAINER_PETE_REWARD":{"address":5603554,"default_item":103,"flag":2015},"TRAINER_PHILLIP_REWARD":{"address":5603072,"default_item":104,"flag":1774},"TRAINER_PHIL_REWARD":{"address":5602884,"default_item":108,"flag":1680},"TRAINER_PHOEBE_REWARD":{"address":5602608,"default_item":110,"flag":1542},"TRAINER_PRESLEY_REWARD":{"address":5602890,"default_item":104,"flag":1683},"TRAINER_PRESTON_REWARD":{"address":5602550,"default_item":108,"flag":1513},"TRAINER_QUINCY_REWARD":{"address":5602732,"default_item":104,"flag":1604},"TRAINER_RACHEL_REWARD":{"address":5603606,"default_item":104,"flag":2041},"TRAINER_RANDALL_REWARD":{"address":5602226,"default_item":104,"flag":1351},"TRAINER_REED_REWARD":{"address":5603434,"default_item":106,"flag":1955},"TRAINER_RELI_AND_IAN_REWARD":{"address":5603456,"default_item":106,"flag":1966},"TRAINER_REYNA_REWARD":{"address":5603102,"default_item":108,"flag":1789},"TRAINER_RHETT_REWARD":{"address":5603490,"default_item":106,"flag":1983},"TRAINER_RICHARD_REWARD":{"address":5602416,"default_item":106,"flag":1446},"TRAINER_RICKY_1_REWARD":{"address":5602212,"default_item":103,"flag":1344},"TRAINER_RICK_REWARD":{"address":5603314,"default_item":103,"flag":1895},"TRAINER_RILEY_REWARD":{"address":5603390,"default_item":106,"flag":1933},"TRAINER_ROBERT_1_REWARD":{"address":5602896,"default_item":108,"flag":1686},"TRAINER_RODNEY_REWARD":{"address":5602414,"default_item":106,"flag":1445},"TRAINER_ROGER_REWARD":{"address":5603422,"default_item":104,"flag":1949},"TRAINER_ROLAND_REWARD":{"address":5602404,"default_item":106,"flag":1440},"TRAINER_RONALD_REWARD":{"address":5602784,"default_item":104,"flag":1630},"TRAINER_ROSE_1_REWARD":{"address":5602158,"default_item":106,"flag":1317},"TRAINER_ROXANNE_1_REWARD":{"address":5602614,"default_item":104,"flag":1545},"TRAINER_RUBEN_REWARD":{"address":5603426,"default_item":104,"flag":1951},"TRAINER_SAMANTHA_REWARD":{"address":5602574,"default_item":108,"flag":1525},"TRAINER_SAMUEL_REWARD":{"address":5602246,"default_item":104,"flag":1361},"TRAINER_SANTIAGO_REWARD":{"address":5602420,"default_item":106,"flag":1448},"TRAINER_SARAH_REWARD":{"address":5603474,"default_item":104,"flag":1975},"TRAINER_SAWYER_1_REWARD":{"address":5602086,"default_item":108,"flag":1281},"TRAINER_SHANE_REWARD":{"address":5602512,"default_item":106,"flag":1494},"TRAINER_SHANNON_REWARD":{"address":5602278,"default_item":104,"flag":1377},"TRAINER_SHARON_REWARD":{"address":5602988,"default_item":106,"flag":1732},"TRAINER_SHAWN_REWARD":{"address":5602472,"default_item":106,"flag":1474},"TRAINER_SHAYLA_REWARD":{"address":5603578,"default_item":108,"flag":2027},"TRAINER_SHEILA_REWARD":{"address":5602334,"default_item":104,"flag":1405},"TRAINER_SHELBY_1_REWARD":{"address":5602710,"default_item":108,"flag":1593},"TRAINER_SHELLY_SEAFLOOR_CAVERN_REWARD":{"address":5602150,"default_item":104,"flag":1313},"TRAINER_SHELLY_WEATHER_INSTITUTE_REWARD":{"address":5602148,"default_item":104,"flag":1312},"TRAINER_SHIRLEY_REWARD":{"address":5602336,"default_item":104,"flag":1406},"TRAINER_SIDNEY_REWARD":{"address":5602606,"default_item":110,"flag":1541},"TRAINER_SIENNA_REWARD":{"address":5603002,"default_item":106,"flag":1739},"TRAINER_SIMON_REWARD":{"address":5602214,"default_item":103,"flag":1345},"TRAINER_SOPHIE_REWARD":{"address":5603500,"default_item":106,"flag":1988},"TRAINER_SPENCER_REWARD":{"address":5602402,"default_item":106,"flag":1439},"TRAINER_STAN_REWARD":{"address":5602408,"default_item":106,"flag":1442},"TRAINER_STEVEN_REWARD":{"address":5603692,"default_item":109,"flag":2084},"TRAINER_STEVE_1_REWARD":{"address":5602370,"default_item":104,"flag":1423},"TRAINER_SUSIE_REWARD":{"address":5602996,"default_item":106,"flag":1736},"TRAINER_SYLVIA_REWARD":{"address":5603234,"default_item":108,"flag":1855},"TRAINER_TABITHA_MAGMA_HIDEOUT_REWARD":{"address":5603548,"default_item":104,"flag":2012},"TRAINER_TABITHA_MT_CHIMNEY_REWARD":{"address":5603278,"default_item":108,"flag":1877},"TRAINER_TAKAO_REWARD":{"address":5602442,"default_item":106,"flag":1459},"TRAINER_TAKASHI_REWARD":{"address":5602916,"default_item":106,"flag":1696},"TRAINER_TALIA_REWARD":{"address":5602854,"default_item":104,"flag":1665},"TRAINER_TAMMY_REWARD":{"address":5602298,"default_item":106,"flag":1387},"TRAINER_TANYA_REWARD":{"address":5602986,"default_item":106,"flag":1731},"TRAINER_TARA_REWARD":{"address":5602976,"default_item":103,"flag":1726},"TRAINER_TASHA_REWARD":{"address":5602302,"default_item":108,"flag":1389},"TRAINER_TATE_AND_LIZA_1_REWARD":{"address":5602626,"default_item":109,"flag":1551},"TRAINER_TAYLOR_REWARD":{"address":5602534,"default_item":104,"flag":1505},"TRAINER_THALIA_1_REWARD":{"address":5602372,"default_item":104,"flag":1424},"TRAINER_THOMAS_REWARD":{"address":5602596,"default_item":107,"flag":1536},"TRAINER_TIANA_REWARD":{"address":5603290,"default_item":103,"flag":1883},"TRAINER_TIFFANY_REWARD":{"address":5602346,"default_item":107,"flag":1411},"TRAINER_TIMMY_REWARD":{"address":5602752,"default_item":103,"flag":1614},"TRAINER_TIMOTHY_1_REWARD":{"address":5602698,"default_item":104,"flag":1587},"TRAINER_TISHA_REWARD":{"address":5603436,"default_item":106,"flag":1956},"TRAINER_TOMMY_REWARD":{"address":5602726,"default_item":103,"flag":1601},"TRAINER_TONY_1_REWARD":{"address":5602394,"default_item":103,"flag":1435},"TRAINER_TORI_AND_TIA_REWARD":{"address":5603438,"default_item":103,"flag":1957},"TRAINER_TRAVIS_REWARD":{"address":5602520,"default_item":106,"flag":1498},"TRAINER_TRENT_1_REWARD":{"address":5603338,"default_item":106,"flag":1907},"TRAINER_TYRA_AND_IVY_REWARD":{"address":5603442,"default_item":106,"flag":1959},"TRAINER_TYRON_REWARD":{"address":5603492,"default_item":106,"flag":1984},"TRAINER_VALERIE_1_REWARD":{"address":5602300,"default_item":108,"flag":1388},"TRAINER_VANESSA_REWARD":{"address":5602684,"default_item":104,"flag":1580},"TRAINER_VICKY_REWARD":{"address":5602708,"default_item":108,"flag":1592},"TRAINER_VICTORIA_REWARD":{"address":5602682,"default_item":106,"flag":1579},"TRAINER_VICTOR_REWARD":{"address":5602668,"default_item":106,"flag":1572},"TRAINER_VIOLET_REWARD":{"address":5602162,"default_item":104,"flag":1319},"TRAINER_VIRGIL_REWARD":{"address":5602552,"default_item":108,"flag":1514},"TRAINER_VITO_REWARD":{"address":5602248,"default_item":104,"flag":1362},"TRAINER_VIVIAN_REWARD":{"address":5603382,"default_item":106,"flag":1929},"TRAINER_VIVI_REWARD":{"address":5603296,"default_item":106,"flag":1886},"TRAINER_WADE_REWARD":{"address":5602772,"default_item":106,"flag":1624},"TRAINER_WALLACE_REWARD":{"address":5602754,"default_item":110,"flag":1615},"TRAINER_WALLY_MAUVILLE_REWARD":{"address":5603396,"default_item":108,"flag":1936},"TRAINER_WALLY_VR_1_REWARD":{"address":5603122,"default_item":107,"flag":1799},"TRAINER_WALTER_1_REWARD":{"address":5602592,"default_item":104,"flag":1534},"TRAINER_WARREN_REWARD":{"address":5602260,"default_item":104,"flag":1368},"TRAINER_WATTSON_1_REWARD":{"address":5602618,"default_item":104,"flag":1547},"TRAINER_WAYNE_REWARD":{"address":5603430,"default_item":104,"flag":1953},"TRAINER_WENDY_REWARD":{"address":5602268,"default_item":104,"flag":1372},"TRAINER_WILLIAM_REWARD":{"address":5602556,"default_item":106,"flag":1516},"TRAINER_WILTON_1_REWARD":{"address":5602240,"default_item":108,"flag":1358},"TRAINER_WINONA_1_REWARD":{"address":5602624,"default_item":107,"flag":1550},"TRAINER_WINSTON_1_REWARD":{"address":5602356,"default_item":104,"flag":1416},"TRAINER_WYATT_REWARD":{"address":5603506,"default_item":104,"flag":1991},"TRAINER_YASU_REWARD":{"address":5602914,"default_item":106,"flag":1695},"TRAINER_ZANDER_REWARD":{"address":5602146,"default_item":108,"flag":1311}},"maps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":{"header_address":4766420,"warp_table_address":5496844},"MAP_ABANDONED_SHIP_CORRIDORS_1F":{"header_address":4766196,"warp_table_address":5495920},"MAP_ABANDONED_SHIP_CORRIDORS_B1F":{"header_address":4766252,"warp_table_address":5496248},"MAP_ABANDONED_SHIP_DECK":{"header_address":4766168,"warp_table_address":5495812},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":{"fishing_encounters":{"address":5609088,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766476,"warp_table_address":5496908,"water_encounters":{"address":5609060,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":{"header_address":4766504,"warp_table_address":5497120},"MAP_ABANDONED_SHIP_ROOMS2_1F":{"header_address":4766392,"warp_table_address":5496752},"MAP_ABANDONED_SHIP_ROOMS2_B1F":{"header_address":4766308,"warp_table_address":5496484},"MAP_ABANDONED_SHIP_ROOMS_1F":{"header_address":4766224,"warp_table_address":5496132},"MAP_ABANDONED_SHIP_ROOMS_B1F":{"fishing_encounters":{"address":5606324,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766280,"warp_table_address":5496392,"water_encounters":{"address":5606296,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_ROOM_B1F":{"header_address":4766364,"warp_table_address":5496596},"MAP_ABANDONED_SHIP_UNDERWATER1":{"header_address":4766336,"warp_table_address":5496536},"MAP_ABANDONED_SHIP_UNDERWATER2":{"header_address":4766448,"warp_table_address":5496880},"MAP_ALTERING_CAVE":{"header_address":4767624,"land_encounters":{"address":5613400,"slots":[41,41,41,41,41,41,41,41,41,41,41,41]},"warp_table_address":5500436},"MAP_ANCIENT_TOMB":{"header_address":4766560,"warp_table_address":5497460},"MAP_AQUA_HIDEOUT_1F":{"header_address":4765300,"warp_table_address":5490892},"MAP_AQUA_HIDEOUT_B1F":{"header_address":4765328,"warp_table_address":5491152},"MAP_AQUA_HIDEOUT_B2F":{"header_address":4765356,"warp_table_address":5491516},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":{"header_address":4766728,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":{"header_address":4766756,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":{"header_address":4766784,"warp_table_address":4160749568},"MAP_ARTISAN_CAVE_1F":{"header_address":4767456,"land_encounters":{"address":5613344,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500172},"MAP_ARTISAN_CAVE_B1F":{"header_address":4767428,"land_encounters":{"address":5613288,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500064},"MAP_BATTLE_COLOSSEUM_2P":{"header_address":4768352,"warp_table_address":5509852},"MAP_BATTLE_COLOSSEUM_4P":{"header_address":4768436,"warp_table_address":5510152},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":{"header_address":4770228,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":{"header_address":4770200,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":{"header_address":4770172,"warp_table_address":5520908},"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":{"header_address":4769976,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":{"header_address":4769920,"warp_table_address":5519076},"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":{"header_address":4769892,"warp_table_address":5518968},"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":{"header_address":4769948,"warp_table_address":5519136},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":{"header_address":4770312,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":{"header_address":4770256,"warp_table_address":5521384},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":{"header_address":4770284,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":{"header_address":4770060,"warp_table_address":5520116},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":{"header_address":4770032,"warp_table_address":5519944},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":{"header_address":4770004,"warp_table_address":5519696},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":{"header_address":4770368,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":{"header_address":4770340,"warp_table_address":5521808},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":{"header_address":4770452,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":{"header_address":4770424,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":{"header_address":4770480,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":{"header_address":4770396,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":{"header_address":4770116,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":{"header_address":4770088,"warp_table_address":5520248},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":{"header_address":4770144,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":{"header_address":4769612,"warp_table_address":5516696},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":{"header_address":4769584,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":{"header_address":4769556,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":{"header_address":4769528,"warp_table_address":5516432},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":{"header_address":4769864,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":{"header_address":4769836,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":{"header_address":4769808,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":{"header_address":4770564,"warp_table_address":5523056},"MAP_BATTLE_FRONTIER_LOUNGE1":{"header_address":4770536,"warp_table_address":5522812},"MAP_BATTLE_FRONTIER_LOUNGE2":{"header_address":4770592,"warp_table_address":5523220},"MAP_BATTLE_FRONTIER_LOUNGE3":{"header_address":4770620,"warp_table_address":5523376},"MAP_BATTLE_FRONTIER_LOUNGE4":{"header_address":4770648,"warp_table_address":5523476},"MAP_BATTLE_FRONTIER_LOUNGE5":{"header_address":4770704,"warp_table_address":5523660},"MAP_BATTLE_FRONTIER_LOUNGE6":{"header_address":4770732,"warp_table_address":5523720},"MAP_BATTLE_FRONTIER_LOUNGE7":{"header_address":4770760,"warp_table_address":5523844},"MAP_BATTLE_FRONTIER_LOUNGE8":{"header_address":4770816,"warp_table_address":5524100},"MAP_BATTLE_FRONTIER_LOUNGE9":{"header_address":4770844,"warp_table_address":5524152},"MAP_BATTLE_FRONTIER_MART":{"header_address":4770928,"warp_table_address":5524588},"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":{"header_address":4769780,"warp_table_address":5518080},"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":{"header_address":4769500,"warp_table_address":5516048},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":{"header_address":4770872,"warp_table_address":5524308},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":{"header_address":4770900,"warp_table_address":5524448},"MAP_BATTLE_FRONTIER_RANKING_HALL":{"header_address":4770508,"warp_table_address":5522560},"MAP_BATTLE_FRONTIER_RECEPTION_GATE":{"header_address":4770788,"warp_table_address":5523992},"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":{"header_address":4770676,"warp_table_address":5523528},"MAP_BATTLE_PYRAMID_SQUARE01":{"header_address":4768912,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE02":{"header_address":4768940,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE03":{"header_address":4768968,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE04":{"header_address":4768996,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE05":{"header_address":4769024,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE06":{"header_address":4769052,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE07":{"header_address":4769080,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE08":{"header_address":4769108,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE09":{"header_address":4769136,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE10":{"header_address":4769164,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE11":{"header_address":4769192,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE12":{"header_address":4769220,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE13":{"header_address":4769248,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE14":{"header_address":4769276,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE15":{"header_address":4769304,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE16":{"header_address":4769332,"warp_table_address":4160749568},"MAP_BIRTH_ISLAND_EXTERIOR":{"header_address":4771012,"warp_table_address":5524876},"MAP_BIRTH_ISLAND_HARBOR":{"header_address":4771040,"warp_table_address":5524952},"MAP_CAVE_OF_ORIGIN_1F":{"header_address":4765720,"land_encounters":{"address":5609868,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493440},"MAP_CAVE_OF_ORIGIN_B1F":{"header_address":4765832,"warp_table_address":5493608},"MAP_CAVE_OF_ORIGIN_ENTRANCE":{"header_address":4765692,"land_encounters":{"address":5609812,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493404},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":{"header_address":4765748,"land_encounters":{"address":5609924,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493476},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":{"header_address":4765776,"land_encounters":{"address":5609980,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493512},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":{"header_address":4765804,"land_encounters":{"address":5610036,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493548},"MAP_CONTEST_HALL":{"header_address":4768464,"warp_table_address":4160749568},"MAP_CONTEST_HALL_BEAUTY":{"header_address":4768660,"warp_table_address":4160749568},"MAP_CONTEST_HALL_COOL":{"header_address":4768716,"warp_table_address":4160749568},"MAP_CONTEST_HALL_CUTE":{"header_address":4768772,"warp_table_address":4160749568},"MAP_CONTEST_HALL_SMART":{"header_address":4768744,"warp_table_address":4160749568},"MAP_CONTEST_HALL_TOUGH":{"header_address":4768688,"warp_table_address":4160749568},"MAP_DESERT_RUINS":{"header_address":4764824,"warp_table_address":5486828},"MAP_DESERT_UNDERPASS":{"header_address":4767400,"land_encounters":{"address":5613232,"slots":[132,370,132,371,132,370,371,132,370,132,371,132]},"warp_table_address":5500012},"MAP_DEWFORD_TOWN":{"fishing_encounters":{"address":5611588,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758300,"warp_table_address":5435180,"water_encounters":{"address":5611560,"slots":[72,309,309,310,310]}},"MAP_DEWFORD_TOWN_GYM":{"header_address":4759952,"warp_table_address":5460340},"MAP_DEWFORD_TOWN_HALL":{"header_address":4759980,"warp_table_address":5460640},"MAP_DEWFORD_TOWN_HOUSE1":{"header_address":4759868,"warp_table_address":5459856},"MAP_DEWFORD_TOWN_HOUSE2":{"header_address":4760008,"warp_table_address":5460748},"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":{"header_address":4759896,"warp_table_address":5459964},"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":{"header_address":4759924,"warp_table_address":5460104},"MAP_EVER_GRANDE_CITY":{"fishing_encounters":{"address":5611892,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4758216,"warp_table_address":5434048,"water_encounters":{"address":5611864,"slots":[72,309,309,310,310]}},"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":{"header_address":4764012,"warp_table_address":5483720},"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":{"header_address":4763984,"warp_table_address":5483612},"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":{"header_address":4763956,"warp_table_address":5483552},"MAP_EVER_GRANDE_CITY_HALL1":{"header_address":4764040,"warp_table_address":5483756},"MAP_EVER_GRANDE_CITY_HALL2":{"header_address":4764068,"warp_table_address":5483808},"MAP_EVER_GRANDE_CITY_HALL3":{"header_address":4764096,"warp_table_address":5483860},"MAP_EVER_GRANDE_CITY_HALL4":{"header_address":4764124,"warp_table_address":5483912},"MAP_EVER_GRANDE_CITY_HALL5":{"header_address":4764152,"warp_table_address":5483948},"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":{"header_address":4764208,"warp_table_address":5484180},"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":{"header_address":4763928,"warp_table_address":5483492},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":{"header_address":4764236,"warp_table_address":5484304},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":{"header_address":4764264,"warp_table_address":5484444},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":{"header_address":4764180,"warp_table_address":5484096},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":{"header_address":4764292,"warp_table_address":5484584},"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":{"header_address":4763900,"warp_table_address":5483432},"MAP_FALLARBOR_TOWN":{"header_address":4758356,"warp_table_address":5435792},"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760316,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760288,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760260,"warp_table_address":5462376},"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":{"header_address":4760400,"warp_table_address":5462888},"MAP_FALLARBOR_TOWN_MART":{"header_address":4760232,"warp_table_address":5462220},"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":{"header_address":4760428,"warp_table_address":5462948},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":{"header_address":4760344,"warp_table_address":5462656},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":{"header_address":4760372,"warp_table_address":5462796},"MAP_FARAWAY_ISLAND_ENTRANCE":{"header_address":4770956,"warp_table_address":5524672},"MAP_FARAWAY_ISLAND_INTERIOR":{"header_address":4770984,"warp_table_address":5524792},"MAP_FIERY_PATH":{"header_address":4765048,"land_encounters":{"address":5606456,"slots":[339,109,339,66,321,218,109,66,321,321,88,88]},"warp_table_address":5489344},"MAP_FORTREE_CITY":{"header_address":4758104,"warp_table_address":5431676},"MAP_FORTREE_CITY_DECORATION_SHOP":{"header_address":4762444,"warp_table_address":5473936},"MAP_FORTREE_CITY_GYM":{"header_address":4762220,"warp_table_address":5472984},"MAP_FORTREE_CITY_HOUSE1":{"header_address":4762192,"warp_table_address":5472756},"MAP_FORTREE_CITY_HOUSE2":{"header_address":4762332,"warp_table_address":5473504},"MAP_FORTREE_CITY_HOUSE3":{"header_address":4762360,"warp_table_address":5473588},"MAP_FORTREE_CITY_HOUSE4":{"header_address":4762388,"warp_table_address":5473696},"MAP_FORTREE_CITY_HOUSE5":{"header_address":4762416,"warp_table_address":5473804},"MAP_FORTREE_CITY_MART":{"header_address":4762304,"warp_table_address":5473420},"MAP_FORTREE_CITY_POKEMON_CENTER_1F":{"header_address":4762248,"warp_table_address":5473140},"MAP_FORTREE_CITY_POKEMON_CENTER_2F":{"header_address":4762276,"warp_table_address":5473280},"MAP_GRANITE_CAVE_1F":{"header_address":4764852,"land_encounters":{"address":5605988,"slots":[41,335,335,41,335,63,335,335,74,74,74,74]},"warp_table_address":5486956},"MAP_GRANITE_CAVE_B1F":{"header_address":4764880,"land_encounters":{"address":5606044,"slots":[41,382,382,382,41,63,335,335,322,322,322,322]},"warp_table_address":5487032},"MAP_GRANITE_CAVE_B2F":{"header_address":4764908,"land_encounters":{"address":5606372,"slots":[41,382,382,41,382,63,322,322,322,322,322,322]},"warp_table_address":5487324},"MAP_GRANITE_CAVE_STEVENS_ROOM":{"header_address":4764936,"land_encounters":{"address":5608188,"slots":[41,335,335,41,335,63,335,335,382,382,382,382]},"warp_table_address":5487432},"MAP_INSIDE_OF_TRUCK":{"header_address":4768800,"warp_table_address":5510720},"MAP_ISLAND_CAVE":{"header_address":4766532,"warp_table_address":5497356},"MAP_JAGGED_PASS":{"header_address":4765020,"land_encounters":{"address":5606644,"slots":[339,339,66,339,351,66,351,66,339,351,339,351]},"warp_table_address":5488908},"MAP_LAVARIDGE_TOWN":{"header_address":4758328,"warp_table_address":5435516},"MAP_LAVARIDGE_TOWN_GYM_1F":{"header_address":4760064,"warp_table_address":5461036},"MAP_LAVARIDGE_TOWN_GYM_B1F":{"header_address":4760092,"warp_table_address":5461384},"MAP_LAVARIDGE_TOWN_HERB_SHOP":{"header_address":4760036,"warp_table_address":5460856},"MAP_LAVARIDGE_TOWN_HOUSE":{"header_address":4760120,"warp_table_address":5461668},"MAP_LAVARIDGE_TOWN_MART":{"header_address":4760148,"warp_table_address":5461776},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":{"header_address":4760176,"warp_table_address":5461908},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":{"header_address":4760204,"warp_table_address":5462056},"MAP_LILYCOVE_CITY":{"fishing_encounters":{"address":5611512,"slots":[129,72,129,72,313,313,313,120,313,313]},"header_address":4758132,"warp_table_address":5432368,"water_encounters":{"address":5611484,"slots":[72,309,309,310,310]}},"MAP_LILYCOVE_CITY_CONTEST_HALL":{"header_address":4762612,"warp_table_address":5476560},"MAP_LILYCOVE_CITY_CONTEST_LOBBY":{"header_address":4762584,"warp_table_address":5475596},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":{"header_address":4762472,"warp_table_address":5473996},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":{"header_address":4762500,"warp_table_address":5474224},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":{"header_address":4762920,"warp_table_address":5478044},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":{"header_address":4762948,"warp_table_address":5478228},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":{"header_address":4762976,"warp_table_address":5478392},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":{"header_address":4763004,"warp_table_address":5478556},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":{"header_address":4763032,"warp_table_address":5478768},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":{"header_address":4763088,"warp_table_address":5478984},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":{"header_address":4763060,"warp_table_address":5478908},"MAP_LILYCOVE_CITY_HARBOR":{"header_address":4762752,"warp_table_address":5477396},"MAP_LILYCOVE_CITY_HOUSE1":{"header_address":4762808,"warp_table_address":5477540},"MAP_LILYCOVE_CITY_HOUSE2":{"header_address":4762836,"warp_table_address":5477600},"MAP_LILYCOVE_CITY_HOUSE3":{"header_address":4762864,"warp_table_address":5477780},"MAP_LILYCOVE_CITY_HOUSE4":{"header_address":4762892,"warp_table_address":5477864},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":{"header_address":4762528,"warp_table_address":5474492},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":{"header_address":4762556,"warp_table_address":5474824},"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":{"header_address":4762780,"warp_table_address":5477456},"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":{"header_address":4762640,"warp_table_address":5476804},"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":{"header_address":4762668,"warp_table_address":5476944},"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":{"header_address":4762724,"warp_table_address":5477240},"MAP_LILYCOVE_CITY_UNUSED_MART":{"header_address":4762696,"warp_table_address":5476988},"MAP_LITTLEROOT_TOWN":{"header_address":4758244,"warp_table_address":5434528},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":{"header_address":4759588,"warp_table_address":5457588},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":{"header_address":4759616,"warp_table_address":5458080},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":{"header_address":4759644,"warp_table_address":5458324},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":{"header_address":4759672,"warp_table_address":5458816},"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":{"header_address":4759700,"warp_table_address":5459036},"MAP_MAGMA_HIDEOUT_1F":{"header_address":4767064,"land_encounters":{"address":5612560,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498844},"MAP_MAGMA_HIDEOUT_2F_1R":{"header_address":4767092,"land_encounters":{"address":5612616,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498992},"MAP_MAGMA_HIDEOUT_2F_2R":{"header_address":4767120,"land_encounters":{"address":5612672,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499180},"MAP_MAGMA_HIDEOUT_2F_3R":{"header_address":4767260,"land_encounters":{"address":5612952,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499696},"MAP_MAGMA_HIDEOUT_3F_1R":{"header_address":4767148,"land_encounters":{"address":5612728,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499288},"MAP_MAGMA_HIDEOUT_3F_2R":{"header_address":4767176,"land_encounters":{"address":5612784,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499380},"MAP_MAGMA_HIDEOUT_3F_3R":{"header_address":4767232,"land_encounters":{"address":5612896,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499660},"MAP_MAGMA_HIDEOUT_4F":{"header_address":4767204,"land_encounters":{"address":5612840,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499600},"MAP_MARINE_CAVE_END":{"header_address":4767540,"warp_table_address":5500288},"MAP_MARINE_CAVE_ENTRANCE":{"header_address":4767512,"warp_table_address":5500236},"MAP_MAUVILLE_CITY":{"header_address":4758048,"warp_table_address":5430380},"MAP_MAUVILLE_CITY_BIKE_SHOP":{"header_address":4761520,"warp_table_address":5469232},"MAP_MAUVILLE_CITY_GAME_CORNER":{"header_address":4761576,"warp_table_address":5469640},"MAP_MAUVILLE_CITY_GYM":{"header_address":4761492,"warp_table_address":5469060},"MAP_MAUVILLE_CITY_HOUSE1":{"header_address":4761548,"warp_table_address":5469316},"MAP_MAUVILLE_CITY_HOUSE2":{"header_address":4761604,"warp_table_address":5469988},"MAP_MAUVILLE_CITY_MART":{"header_address":4761688,"warp_table_address":5470424},"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":{"header_address":4761632,"warp_table_address":5470144},"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":{"header_address":4761660,"warp_table_address":5470308},"MAP_METEOR_FALLS_1F_1R":{"fishing_encounters":{"address":5610796,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4764656,"land_encounters":{"address":5610712,"slots":[41,41,41,41,41,349,349,349,41,41,41,41]},"warp_table_address":5486052,"water_encounters":{"address":5610768,"slots":[41,41,349,349,349]}},"MAP_METEOR_FALLS_1F_2R":{"fishing_encounters":{"address":5610928,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764684,"land_encounters":{"address":5610844,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486220,"water_encounters":{"address":5610900,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_1R":{"fishing_encounters":{"address":5611060,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764712,"land_encounters":{"address":5610976,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486284,"water_encounters":{"address":5611032,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_2R":{"fishing_encounters":{"address":5606596,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764740,"land_encounters":{"address":5606512,"slots":[42,42,395,349,395,349,395,349,42,42,42,42]},"warp_table_address":5486376,"water_encounters":{"address":5606568,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_STEVENS_CAVE":{"header_address":4767652,"land_encounters":{"address":5613904,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5500488},"MAP_MIRAGE_TOWER_1F":{"header_address":4767288,"land_encounters":{"address":5613008,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499732},"MAP_MIRAGE_TOWER_2F":{"header_address":4767316,"land_encounters":{"address":5613064,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499768},"MAP_MIRAGE_TOWER_3F":{"header_address":4767344,"land_encounters":{"address":5613120,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499852},"MAP_MIRAGE_TOWER_4F":{"header_address":4767372,"land_encounters":{"address":5613176,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499960},"MAP_MOSSDEEP_CITY":{"fishing_encounters":{"address":5611740,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758160,"warp_table_address":5433064,"water_encounters":{"address":5611712,"slots":[72,309,309,310,310]}},"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":{"header_address":4763424,"warp_table_address":5481712},"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":{"header_address":4763452,"warp_table_address":5481816},"MAP_MOSSDEEP_CITY_GYM":{"header_address":4763116,"warp_table_address":5479884},"MAP_MOSSDEEP_CITY_HOUSE1":{"header_address":4763144,"warp_table_address":5480232},"MAP_MOSSDEEP_CITY_HOUSE2":{"header_address":4763172,"warp_table_address":5480340},"MAP_MOSSDEEP_CITY_HOUSE3":{"header_address":4763284,"warp_table_address":5480812},"MAP_MOSSDEEP_CITY_HOUSE4":{"header_address":4763340,"warp_table_address":5481076},"MAP_MOSSDEEP_CITY_MART":{"header_address":4763256,"warp_table_address":5480752},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":{"header_address":4763200,"warp_table_address":5480448},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":{"header_address":4763228,"warp_table_address":5480612},"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":{"header_address":4763368,"warp_table_address":5481376},"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":{"header_address":4763396,"warp_table_address":5481636},"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":{"header_address":4763312,"warp_table_address":5480920},"MAP_MT_CHIMNEY":{"header_address":4764992,"warp_table_address":5488664},"MAP_MT_CHIMNEY_CABLE_CAR_STATION":{"header_address":4764460,"warp_table_address":5485144},"MAP_MT_PYRE_1F":{"header_address":4765076,"land_encounters":{"address":5606100,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489452},"MAP_MT_PYRE_2F":{"header_address":4765104,"land_encounters":{"address":5607796,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489712},"MAP_MT_PYRE_3F":{"header_address":4765132,"land_encounters":{"address":5607852,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489868},"MAP_MT_PYRE_4F":{"header_address":4765160,"land_encounters":{"address":5607908,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5489984},"MAP_MT_PYRE_5F":{"header_address":4765188,"land_encounters":{"address":5607964,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490100},"MAP_MT_PYRE_6F":{"header_address":4765216,"land_encounters":{"address":5608020,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490232},"MAP_MT_PYRE_EXTERIOR":{"header_address":4765244,"land_encounters":{"address":5608076,"slots":[377,377,377,377,37,37,37,37,309,309,309,309]},"warp_table_address":5490316},"MAP_MT_PYRE_SUMMIT":{"header_address":4765272,"land_encounters":{"address":5608132,"slots":[377,377,377,377,377,377,377,361,361,361,411,411]},"warp_table_address":5490656},"MAP_NAVEL_ROCK_B1F":{"header_address":4771320,"warp_table_address":5525524},"MAP_NAVEL_ROCK_BOTTOM":{"header_address":4771824,"warp_table_address":5526248},"MAP_NAVEL_ROCK_DOWN01":{"header_address":4771516,"warp_table_address":5525828},"MAP_NAVEL_ROCK_DOWN02":{"header_address":4771544,"warp_table_address":5525864},"MAP_NAVEL_ROCK_DOWN03":{"header_address":4771572,"warp_table_address":5525900},"MAP_NAVEL_ROCK_DOWN04":{"header_address":4771600,"warp_table_address":5525936},"MAP_NAVEL_ROCK_DOWN05":{"header_address":4771628,"warp_table_address":5525972},"MAP_NAVEL_ROCK_DOWN06":{"header_address":4771656,"warp_table_address":5526008},"MAP_NAVEL_ROCK_DOWN07":{"header_address":4771684,"warp_table_address":5526044},"MAP_NAVEL_ROCK_DOWN08":{"header_address":4771712,"warp_table_address":5526080},"MAP_NAVEL_ROCK_DOWN09":{"header_address":4771740,"warp_table_address":5526116},"MAP_NAVEL_ROCK_DOWN10":{"header_address":4771768,"warp_table_address":5526152},"MAP_NAVEL_ROCK_DOWN11":{"header_address":4771796,"warp_table_address":5526188},"MAP_NAVEL_ROCK_ENTRANCE":{"header_address":4771292,"warp_table_address":5525488},"MAP_NAVEL_ROCK_EXTERIOR":{"header_address":4771236,"warp_table_address":5525376},"MAP_NAVEL_ROCK_FORK":{"header_address":4771348,"warp_table_address":5525560},"MAP_NAVEL_ROCK_HARBOR":{"header_address":4771264,"warp_table_address":5525460},"MAP_NAVEL_ROCK_TOP":{"header_address":4771488,"warp_table_address":5525772},"MAP_NAVEL_ROCK_UP1":{"header_address":4771376,"warp_table_address":5525604},"MAP_NAVEL_ROCK_UP2":{"header_address":4771404,"warp_table_address":5525640},"MAP_NAVEL_ROCK_UP3":{"header_address":4771432,"warp_table_address":5525676},"MAP_NAVEL_ROCK_UP4":{"header_address":4771460,"warp_table_address":5525712},"MAP_NEW_MAUVILLE_ENTRANCE":{"header_address":4766112,"land_encounters":{"address":5610092,"slots":[100,81,100,81,100,81,100,81,100,81,100,81]},"warp_table_address":5495284},"MAP_NEW_MAUVILLE_INSIDE":{"header_address":4766140,"land_encounters":{"address":5607136,"slots":[100,81,100,81,100,81,100,81,100,81,101,82]},"warp_table_address":5495528},"MAP_OLDALE_TOWN":{"header_address":4758272,"warp_table_address":5434860},"MAP_OLDALE_TOWN_HOUSE1":{"header_address":4759728,"warp_table_address":5459276},"MAP_OLDALE_TOWN_HOUSE2":{"header_address":4759756,"warp_table_address":5459360},"MAP_OLDALE_TOWN_MART":{"header_address":4759840,"warp_table_address":5459748},"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":{"header_address":4759784,"warp_table_address":5459492},"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":{"header_address":4759812,"warp_table_address":5459632},"MAP_PACIFIDLOG_TOWN":{"fishing_encounters":{"address":5611816,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758412,"warp_table_address":5436288,"water_encounters":{"address":5611788,"slots":[72,309,309,310,310]}},"MAP_PACIFIDLOG_TOWN_HOUSE1":{"header_address":4760764,"warp_table_address":5464400},"MAP_PACIFIDLOG_TOWN_HOUSE2":{"header_address":4760792,"warp_table_address":5464508},"MAP_PACIFIDLOG_TOWN_HOUSE3":{"header_address":4760820,"warp_table_address":5464592},"MAP_PACIFIDLOG_TOWN_HOUSE4":{"header_address":4760848,"warp_table_address":5464700},"MAP_PACIFIDLOG_TOWN_HOUSE5":{"header_address":4760876,"warp_table_address":5464784},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":{"header_address":4760708,"warp_table_address":5464168},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":{"header_address":4760736,"warp_table_address":5464308},"MAP_PETALBURG_CITY":{"fishing_encounters":{"address":5611968,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4757992,"warp_table_address":5428704,"water_encounters":{"address":5611940,"slots":[183,183,183,183,183]}},"MAP_PETALBURG_CITY_GYM":{"header_address":4760932,"warp_table_address":5465168},"MAP_PETALBURG_CITY_HOUSE1":{"header_address":4760960,"warp_table_address":5465708},"MAP_PETALBURG_CITY_HOUSE2":{"header_address":4760988,"warp_table_address":5465792},"MAP_PETALBURG_CITY_MART":{"header_address":4761072,"warp_table_address":5466228},"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":{"header_address":4761016,"warp_table_address":5465948},"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":{"header_address":4761044,"warp_table_address":5466088},"MAP_PETALBURG_CITY_WALLYS_HOUSE":{"header_address":4760904,"warp_table_address":5464868},"MAP_PETALBURG_WOODS":{"header_address":4764964,"land_encounters":{"address":5605876,"slots":[286,290,306,286,291,293,290,306,304,364,304,364]},"warp_table_address":5487772},"MAP_RECORD_CORNER":{"header_address":4768408,"warp_table_address":5510036},"MAP_ROUTE101":{"header_address":4758440,"land_encounters":{"address":5604388,"slots":[290,286,290,290,286,286,290,286,288,288,288,288]},"warp_table_address":4160749568},"MAP_ROUTE102":{"fishing_encounters":{"address":5604528,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758468,"land_encounters":{"address":5604444,"slots":[286,290,286,290,295,295,288,288,288,392,288,298]},"warp_table_address":4160749568,"water_encounters":{"address":5604500,"slots":[183,183,183,183,118]}},"MAP_ROUTE103":{"fishing_encounters":{"address":5604660,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758496,"land_encounters":{"address":5604576,"slots":[286,286,286,286,309,288,288,288,309,309,309,309]},"warp_table_address":5437452,"water_encounters":{"address":5604632,"slots":[72,309,309,310,310]}},"MAP_ROUTE104":{"fishing_encounters":{"address":5604792,"slots":[129,129,129,129,129,129,129,129,129,129]},"header_address":4758524,"land_encounters":{"address":5604708,"slots":[286,290,286,183,183,286,304,304,309,309,309,309]},"warp_table_address":5438308,"water_encounters":{"address":5604764,"slots":[309,309,309,310,310]}},"MAP_ROUTE104_MR_BRINEYS_HOUSE":{"header_address":4764320,"warp_table_address":5484676},"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4764348,"warp_table_address":5484784},"MAP_ROUTE104_PROTOTYPE":{"header_address":4771880,"warp_table_address":4160749568},"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4771908,"warp_table_address":4160749568},"MAP_ROUTE105":{"fishing_encounters":{"address":5604868,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758552,"warp_table_address":5438720,"water_encounters":{"address":5604840,"slots":[72,309,309,310,310]}},"MAP_ROUTE106":{"fishing_encounters":{"address":5606728,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758580,"warp_table_address":5438892,"water_encounters":{"address":5606700,"slots":[72,309,309,310,310]}},"MAP_ROUTE107":{"fishing_encounters":{"address":5606804,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758608,"warp_table_address":4160749568,"water_encounters":{"address":5606776,"slots":[72,309,309,310,310]}},"MAP_ROUTE108":{"fishing_encounters":{"address":5606880,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758636,"warp_table_address":5439324,"water_encounters":{"address":5606852,"slots":[72,309,309,310,310]}},"MAP_ROUTE109":{"fishing_encounters":{"address":5606956,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758664,"warp_table_address":5439940,"water_encounters":{"address":5606928,"slots":[72,309,309,310,310]}},"MAP_ROUTE109_SEASHORE_HOUSE":{"header_address":4771936,"warp_table_address":5526472},"MAP_ROUTE110":{"fishing_encounters":{"address":5605000,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758692,"land_encounters":{"address":5604916,"slots":[286,337,367,337,354,43,354,367,309,309,353,353]},"warp_table_address":5440928,"water_encounters":{"address":5604972,"slots":[72,309,309,310,310]}},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":{"header_address":4772272,"warp_table_address":5529400},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":{"header_address":4772300,"warp_table_address":5529508},"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":{"header_address":4772020,"warp_table_address":5526740},"MAP_ROUTE110_TRICK_HOUSE_END":{"header_address":4771992,"warp_table_address":5526676},"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":{"header_address":4771964,"warp_table_address":5526532},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":{"header_address":4772048,"warp_table_address":5527152},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":{"header_address":4772076,"warp_table_address":5527328},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":{"header_address":4772104,"warp_table_address":5527616},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":{"header_address":4772132,"warp_table_address":5528072},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":{"header_address":4772160,"warp_table_address":5528248},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":{"header_address":4772188,"warp_table_address":5528752},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":{"header_address":4772216,"warp_table_address":5529024},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":{"header_address":4772244,"warp_table_address":5529320},"MAP_ROUTE111":{"fishing_encounters":{"address":5605160,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758720,"land_encounters":{"address":5605048,"slots":[27,332,27,332,318,318,27,332,318,344,344,344]},"warp_table_address":5442448,"water_encounters":{"address":5605104,"slots":[183,183,183,183,118]}},"MAP_ROUTE111_OLD_LADYS_REST_STOP":{"header_address":4764404,"warp_table_address":5484976},"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":{"header_address":4764376,"warp_table_address":5484916},"MAP_ROUTE112":{"header_address":4758748,"land_encounters":{"address":5605208,"slots":[339,339,183,339,339,183,339,183,339,339,339,339]},"warp_table_address":5443604},"MAP_ROUTE112_CABLE_CAR_STATION":{"header_address":4764432,"warp_table_address":5485060},"MAP_ROUTE113":{"header_address":4758776,"land_encounters":{"address":5605264,"slots":[308,308,218,308,308,218,308,218,308,227,308,227]},"warp_table_address":5444092},"MAP_ROUTE113_GLASS_WORKSHOP":{"header_address":4772328,"warp_table_address":5529640},"MAP_ROUTE114":{"fishing_encounters":{"address":5605432,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758804,"land_encounters":{"address":5605320,"slots":[358,295,358,358,295,296,296,296,379,379,379,299]},"warp_table_address":5445184,"water_encounters":{"address":5605376,"slots":[183,183,183,183,118]}},"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":{"header_address":4764488,"warp_table_address":5485204},"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":{"header_address":4764516,"warp_table_address":5485320},"MAP_ROUTE114_LANETTES_HOUSE":{"header_address":4764544,"warp_table_address":5485420},"MAP_ROUTE115":{"fishing_encounters":{"address":5607088,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758832,"land_encounters":{"address":5607004,"slots":[358,304,358,304,304,305,39,39,309,309,309,309]},"warp_table_address":5445988,"water_encounters":{"address":5607060,"slots":[72,309,309,310,310]}},"MAP_ROUTE116":{"header_address":4758860,"land_encounters":{"address":5605480,"slots":[286,370,301,63,301,304,304,304,286,286,315,315]},"warp_table_address":5446872},"MAP_ROUTE116_TUNNELERS_REST_HOUSE":{"header_address":4764572,"warp_table_address":5485564},"MAP_ROUTE117":{"fishing_encounters":{"address":5605620,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758888,"land_encounters":{"address":5605536,"slots":[286,43,286,43,183,43,387,387,387,387,386,298]},"warp_table_address":5447656,"water_encounters":{"address":5605592,"slots":[183,183,183,183,118]}},"MAP_ROUTE117_POKEMON_DAY_CARE":{"header_address":4764600,"warp_table_address":5485624},"MAP_ROUTE118":{"fishing_encounters":{"address":5605752,"slots":[129,72,129,72,330,331,330,330,330,330]},"header_address":4758916,"land_encounters":{"address":5605668,"slots":[288,337,288,337,289,338,309,309,309,309,309,317]},"warp_table_address":5448236,"water_encounters":{"address":5605724,"slots":[72,309,309,310,310]}},"MAP_ROUTE119":{"fishing_encounters":{"address":5607276,"slots":[129,72,129,72,330,330,330,330,330,330]},"header_address":4758944,"land_encounters":{"address":5607192,"slots":[288,289,288,43,289,43,43,43,369,369,369,317]},"warp_table_address":5449460,"water_encounters":{"address":5607248,"slots":[72,309,309,310,310]}},"MAP_ROUTE119_HOUSE":{"header_address":4772440,"warp_table_address":5530360},"MAP_ROUTE119_WEATHER_INSTITUTE_1F":{"header_address":4772384,"warp_table_address":5529880},"MAP_ROUTE119_WEATHER_INSTITUTE_2F":{"header_address":4772412,"warp_table_address":5530164},"MAP_ROUTE120":{"fishing_encounters":{"address":5607408,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758972,"land_encounters":{"address":5607324,"slots":[286,287,287,43,183,43,43,183,376,376,317,298]},"warp_table_address":5451160,"water_encounters":{"address":5607380,"slots":[183,183,183,183,118]}},"MAP_ROUTE121":{"fishing_encounters":{"address":5607540,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759000,"land_encounters":{"address":5607456,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5452364,"water_encounters":{"address":5607512,"slots":[72,309,309,310,310]}},"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":{"header_address":4764628,"warp_table_address":5485732},"MAP_ROUTE122":{"fishing_encounters":{"address":5607616,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759028,"warp_table_address":5452576,"water_encounters":{"address":5607588,"slots":[72,309,309,310,310]}},"MAP_ROUTE123":{"fishing_encounters":{"address":5607748,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759056,"land_encounters":{"address":5607664,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5453636,"water_encounters":{"address":5607720,"slots":[72,309,309,310,310]}},"MAP_ROUTE123_BERRY_MASTERS_HOUSE":{"header_address":4772356,"warp_table_address":5529724},"MAP_ROUTE124":{"fishing_encounters":{"address":5605828,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759084,"warp_table_address":5454436,"water_encounters":{"address":5605800,"slots":[72,309,309,310,310]}},"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":{"header_address":4772468,"warp_table_address":5530420},"MAP_ROUTE125":{"fishing_encounters":{"address":5608272,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759112,"warp_table_address":5454716,"water_encounters":{"address":5608244,"slots":[72,309,309,310,310]}},"MAP_ROUTE126":{"fishing_encounters":{"address":5608348,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759140,"warp_table_address":4160749568,"water_encounters":{"address":5608320,"slots":[72,309,309,310,310]}},"MAP_ROUTE127":{"fishing_encounters":{"address":5608424,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759168,"warp_table_address":4160749568,"water_encounters":{"address":5608396,"slots":[72,309,309,310,310]}},"MAP_ROUTE128":{"fishing_encounters":{"address":5608500,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4759196,"warp_table_address":4160749568,"water_encounters":{"address":5608472,"slots":[72,309,309,310,310]}},"MAP_ROUTE129":{"fishing_encounters":{"address":5608576,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759224,"warp_table_address":4160749568,"water_encounters":{"address":5608548,"slots":[72,309,309,310,314]}},"MAP_ROUTE130":{"fishing_encounters":{"address":5608708,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759252,"land_encounters":{"address":5608624,"slots":[360,360,360,360,360,360,360,360,360,360,360,360]},"warp_table_address":4160749568,"water_encounters":{"address":5608680,"slots":[72,309,309,310,310]}},"MAP_ROUTE131":{"fishing_encounters":{"address":5608784,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759280,"warp_table_address":5456116,"water_encounters":{"address":5608756,"slots":[72,309,309,310,310]}},"MAP_ROUTE132":{"fishing_encounters":{"address":5608860,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759308,"warp_table_address":4160749568,"water_encounters":{"address":5608832,"slots":[72,309,309,310,310]}},"MAP_ROUTE133":{"fishing_encounters":{"address":5608936,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759336,"warp_table_address":4160749568,"water_encounters":{"address":5608908,"slots":[72,309,309,310,310]}},"MAP_ROUTE134":{"fishing_encounters":{"address":5609012,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759364,"warp_table_address":4160749568,"water_encounters":{"address":5608984,"slots":[72,309,309,310,310]}},"MAP_RUSTBORO_CITY":{"header_address":4758076,"warp_table_address":5430936},"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":{"header_address":4762024,"warp_table_address":5472204},"MAP_RUSTBORO_CITY_DEVON_CORP_1F":{"header_address":4761716,"warp_table_address":5470532},"MAP_RUSTBORO_CITY_DEVON_CORP_2F":{"header_address":4761744,"warp_table_address":5470744},"MAP_RUSTBORO_CITY_DEVON_CORP_3F":{"header_address":4761772,"warp_table_address":5470852},"MAP_RUSTBORO_CITY_FLAT1_1F":{"header_address":4761940,"warp_table_address":5471808},"MAP_RUSTBORO_CITY_FLAT1_2F":{"header_address":4761968,"warp_table_address":5472044},"MAP_RUSTBORO_CITY_FLAT2_1F":{"header_address":4762080,"warp_table_address":5472372},"MAP_RUSTBORO_CITY_FLAT2_2F":{"header_address":4762108,"warp_table_address":5472464},"MAP_RUSTBORO_CITY_FLAT2_3F":{"header_address":4762136,"warp_table_address":5472548},"MAP_RUSTBORO_CITY_GYM":{"header_address":4761800,"warp_table_address":5471024},"MAP_RUSTBORO_CITY_HOUSE1":{"header_address":4761996,"warp_table_address":5472120},"MAP_RUSTBORO_CITY_HOUSE2":{"header_address":4762052,"warp_table_address":5472288},"MAP_RUSTBORO_CITY_HOUSE3":{"header_address":4762164,"warp_table_address":5472648},"MAP_RUSTBORO_CITY_MART":{"header_address":4761912,"warp_table_address":5471724},"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":{"header_address":4761856,"warp_table_address":5471444},"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":{"header_address":4761884,"warp_table_address":5471584},"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":{"header_address":4761828,"warp_table_address":5471252},"MAP_RUSTURF_TUNNEL":{"header_address":4764768,"land_encounters":{"address":5605932,"slots":[370,370,370,370,370,370,370,370,370,370,370,370]},"warp_table_address":5486644},"MAP_SAFARI_ZONE_NORTH":{"header_address":4769416,"land_encounters":{"address":5610280,"slots":[231,43,231,43,177,44,44,177,178,214,178,214]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHEAST":{"header_address":4769724,"land_encounters":{"address":5612476,"slots":[190,216,190,216,191,165,163,204,228,241,228,241]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHWEST":{"fishing_encounters":{"address":5610448,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769388,"land_encounters":{"address":5610364,"slots":[111,43,111,43,84,44,44,84,85,127,85,127]},"warp_table_address":4160749568,"water_encounters":{"address":5610420,"slots":[54,54,54,55,55]}},"MAP_SAFARI_ZONE_REST_HOUSE":{"header_address":4769696,"warp_table_address":5516996},"MAP_SAFARI_ZONE_SOUTH":{"header_address":4769472,"land_encounters":{"address":5606212,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515444},"MAP_SAFARI_ZONE_SOUTHEAST":{"fishing_encounters":{"address":5612428,"slots":[129,118,129,118,223,118,223,223,223,224]},"header_address":4769752,"land_encounters":{"address":5612344,"slots":[191,179,191,179,190,167,163,209,234,207,234,207]},"warp_table_address":4160749568,"water_encounters":{"address":5612400,"slots":[194,183,183,183,195]}},"MAP_SAFARI_ZONE_SOUTHWEST":{"fishing_encounters":{"address":5610232,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769444,"land_encounters":{"address":5610148,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515260,"water_encounters":{"address":5610204,"slots":[54,54,54,54,54]}},"MAP_SCORCHED_SLAB":{"header_address":4766700,"warp_table_address":5498144},"MAP_SEAFLOOR_CAVERN_ENTRANCE":{"fishing_encounters":{"address":5609764,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765412,"warp_table_address":5491796,"water_encounters":{"address":5609736,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM1":{"header_address":4765440,"land_encounters":{"address":5609136,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5491952},"MAP_SEAFLOOR_CAVERN_ROOM2":{"header_address":4765468,"land_encounters":{"address":5609192,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492188},"MAP_SEAFLOOR_CAVERN_ROOM3":{"header_address":4765496,"land_encounters":{"address":5609248,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492456},"MAP_SEAFLOOR_CAVERN_ROOM4":{"header_address":4765524,"land_encounters":{"address":5609304,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492548},"MAP_SEAFLOOR_CAVERN_ROOM5":{"header_address":4765552,"land_encounters":{"address":5609360,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492744},"MAP_SEAFLOOR_CAVERN_ROOM6":{"fishing_encounters":{"address":5609500,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765580,"land_encounters":{"address":5609416,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492788,"water_encounters":{"address":5609472,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM7":{"fishing_encounters":{"address":5609632,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765608,"land_encounters":{"address":5609548,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492832,"water_encounters":{"address":5609604,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM8":{"header_address":4765636,"land_encounters":{"address":5609680,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493156},"MAP_SEAFLOOR_CAVERN_ROOM9":{"header_address":4765664,"warp_table_address":5493360},"MAP_SEALED_CHAMBER_INNER_ROOM":{"header_address":4766672,"warp_table_address":5497984},"MAP_SEALED_CHAMBER_OUTER_ROOM":{"header_address":4766644,"warp_table_address":5497608},"MAP_SECRET_BASE_BLUE_CAVE1":{"header_address":4767736,"warp_table_address":5501652},"MAP_SECRET_BASE_BLUE_CAVE2":{"header_address":4767904,"warp_table_address":5503980},"MAP_SECRET_BASE_BLUE_CAVE3":{"header_address":4768072,"warp_table_address":5506308},"MAP_SECRET_BASE_BLUE_CAVE4":{"header_address":4768240,"warp_table_address":5508636},"MAP_SECRET_BASE_BROWN_CAVE1":{"header_address":4767708,"warp_table_address":5501264},"MAP_SECRET_BASE_BROWN_CAVE2":{"header_address":4767876,"warp_table_address":5503592},"MAP_SECRET_BASE_BROWN_CAVE3":{"header_address":4768044,"warp_table_address":5505920},"MAP_SECRET_BASE_BROWN_CAVE4":{"header_address":4768212,"warp_table_address":5508248},"MAP_SECRET_BASE_RED_CAVE1":{"header_address":4767680,"warp_table_address":5500876},"MAP_SECRET_BASE_RED_CAVE2":{"header_address":4767848,"warp_table_address":5503204},"MAP_SECRET_BASE_RED_CAVE3":{"header_address":4768016,"warp_table_address":5505532},"MAP_SECRET_BASE_RED_CAVE4":{"header_address":4768184,"warp_table_address":5507860},"MAP_SECRET_BASE_SHRUB1":{"header_address":4767820,"warp_table_address":5502816},"MAP_SECRET_BASE_SHRUB2":{"header_address":4767988,"warp_table_address":5505144},"MAP_SECRET_BASE_SHRUB3":{"header_address":4768156,"warp_table_address":5507472},"MAP_SECRET_BASE_SHRUB4":{"header_address":4768324,"warp_table_address":5509800},"MAP_SECRET_BASE_TREE1":{"header_address":4767792,"warp_table_address":5502428},"MAP_SECRET_BASE_TREE2":{"header_address":4767960,"warp_table_address":5504756},"MAP_SECRET_BASE_TREE3":{"header_address":4768128,"warp_table_address":5507084},"MAP_SECRET_BASE_TREE4":{"header_address":4768296,"warp_table_address":5509412},"MAP_SECRET_BASE_YELLOW_CAVE1":{"header_address":4767764,"warp_table_address":5502040},"MAP_SECRET_BASE_YELLOW_CAVE2":{"header_address":4767932,"warp_table_address":5504368},"MAP_SECRET_BASE_YELLOW_CAVE3":{"header_address":4768100,"warp_table_address":5506696},"MAP_SECRET_BASE_YELLOW_CAVE4":{"header_address":4768268,"warp_table_address":5509024},"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":{"header_address":4766056,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":{"header_address":4766084,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":{"fishing_encounters":{"address":5611436,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765944,"land_encounters":{"address":5611352,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494828,"water_encounters":{"address":5611408,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":{"header_address":4766980,"land_encounters":{"address":5612044,"slots":[41,341,41,341,41,341,346,341,42,346,42,346]},"warp_table_address":5498544},"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":{"fishing_encounters":{"address":5611304,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765972,"land_encounters":{"address":5611220,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494904,"water_encounters":{"address":5611276,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":{"header_address":4766028,"land_encounters":{"address":5611164,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495180},"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":{"header_address":4766000,"land_encounters":{"address":5611108,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495084},"MAP_SKY_PILLAR_1F":{"header_address":4766868,"land_encounters":{"address":5612100,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498328},"MAP_SKY_PILLAR_2F":{"header_address":4766896,"warp_table_address":5498372},"MAP_SKY_PILLAR_3F":{"header_address":4766924,"land_encounters":{"address":5612232,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498408},"MAP_SKY_PILLAR_4F":{"header_address":4766952,"warp_table_address":5498452},"MAP_SKY_PILLAR_5F":{"header_address":4767008,"land_encounters":{"address":5612288,"slots":[322,42,42,322,319,378,378,319,319,359,359,359]},"warp_table_address":5498572},"MAP_SKY_PILLAR_ENTRANCE":{"header_address":4766812,"warp_table_address":5498232},"MAP_SKY_PILLAR_OUTSIDE":{"header_address":4766840,"warp_table_address":5498292},"MAP_SKY_PILLAR_TOP":{"header_address":4767036,"warp_table_address":5498656},"MAP_SLATEPORT_CITY":{"fishing_encounters":{"address":5611664,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758020,"warp_table_address":5429836,"water_encounters":{"address":5611636,"slots":[72,309,309,310,310]}},"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":{"header_address":4761212,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":{"header_address":4761184,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":{"header_address":4761156,"warp_table_address":5466624},"MAP_SLATEPORT_CITY_HARBOR":{"header_address":4761352,"warp_table_address":5468328},"MAP_SLATEPORT_CITY_HOUSE":{"header_address":4761380,"warp_table_address":5468492},"MAP_SLATEPORT_CITY_MART":{"header_address":4761464,"warp_table_address":5468856},"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":{"header_address":4761240,"warp_table_address":5466832},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":{"header_address":4761296,"warp_table_address":5467456},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":{"header_address":4761324,"warp_table_address":5467856},"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":{"header_address":4761408,"warp_table_address":5468600},"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":{"header_address":4761436,"warp_table_address":5468740},"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":{"header_address":4761268,"warp_table_address":5467084},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":{"header_address":4761100,"warp_table_address":5466360},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":{"header_address":4761128,"warp_table_address":5466476},"MAP_SOOTOPOLIS_CITY":{"fishing_encounters":{"address":5612184,"slots":[129,72,129,129,129,129,129,130,130,130]},"header_address":4758188,"warp_table_address":5433852,"water_encounters":{"address":5612156,"slots":[129,129,129,129,129]}},"MAP_SOOTOPOLIS_CITY_GYM_1F":{"header_address":4763480,"warp_table_address":5481892},"MAP_SOOTOPOLIS_CITY_GYM_B1F":{"header_address":4763508,"warp_table_address":5482200},"MAP_SOOTOPOLIS_CITY_HOUSE1":{"header_address":4763620,"warp_table_address":5482664},"MAP_SOOTOPOLIS_CITY_HOUSE2":{"header_address":4763648,"warp_table_address":5482724},"MAP_SOOTOPOLIS_CITY_HOUSE3":{"header_address":4763676,"warp_table_address":5482808},"MAP_SOOTOPOLIS_CITY_HOUSE4":{"header_address":4763704,"warp_table_address":5482916},"MAP_SOOTOPOLIS_CITY_HOUSE5":{"header_address":4763732,"warp_table_address":5483000},"MAP_SOOTOPOLIS_CITY_HOUSE6":{"header_address":4763760,"warp_table_address":5483060},"MAP_SOOTOPOLIS_CITY_HOUSE7":{"header_address":4763788,"warp_table_address":5483144},"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":{"header_address":4763816,"warp_table_address":5483228},"MAP_SOOTOPOLIS_CITY_MART":{"header_address":4763592,"warp_table_address":5482580},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":{"header_address":4763844,"warp_table_address":5483312},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":{"header_address":4763872,"warp_table_address":5483380},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":{"header_address":4763536,"warp_table_address":5482324},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":{"header_address":4763564,"warp_table_address":5482464},"MAP_SOUTHERN_ISLAND_EXTERIOR":{"header_address":4769640,"warp_table_address":5516780},"MAP_SOUTHERN_ISLAND_INTERIOR":{"header_address":4769668,"warp_table_address":5516876},"MAP_SS_TIDAL_CORRIDOR":{"header_address":4768828,"warp_table_address":5510992},"MAP_SS_TIDAL_LOWER_DECK":{"header_address":4768856,"warp_table_address":5511276},"MAP_SS_TIDAL_ROOMS":{"header_address":4768884,"warp_table_address":5511508},"MAP_TERRA_CAVE_END":{"header_address":4767596,"warp_table_address":5500392},"MAP_TERRA_CAVE_ENTRANCE":{"header_address":4767568,"warp_table_address":5500332},"MAP_TRADE_CENTER":{"header_address":4768380,"warp_table_address":5509944},"MAP_TRAINER_HILL_1F":{"header_address":4771096,"warp_table_address":5525172},"MAP_TRAINER_HILL_2F":{"header_address":4771124,"warp_table_address":5525208},"MAP_TRAINER_HILL_3F":{"header_address":4771152,"warp_table_address":5525244},"MAP_TRAINER_HILL_4F":{"header_address":4771180,"warp_table_address":5525280},"MAP_TRAINER_HILL_ELEVATOR":{"header_address":4771852,"warp_table_address":5526300},"MAP_TRAINER_HILL_ENTRANCE":{"header_address":4771068,"warp_table_address":5525100},"MAP_TRAINER_HILL_ROOF":{"header_address":4771208,"warp_table_address":5525340},"MAP_UNDERWATER_MARINE_CAVE":{"header_address":4767484,"warp_table_address":5500208},"MAP_UNDERWATER_ROUTE105":{"header_address":4759532,"warp_table_address":5457348},"MAP_UNDERWATER_ROUTE124":{"header_address":4759392,"warp_table_address":4160749568,"water_encounters":{"address":5612016,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE125":{"header_address":4759560,"warp_table_address":5457384},"MAP_UNDERWATER_ROUTE126":{"header_address":4759420,"warp_table_address":5457052,"water_encounters":{"address":5606268,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE127":{"header_address":4759448,"warp_table_address":5457176},"MAP_UNDERWATER_ROUTE128":{"header_address":4759476,"warp_table_address":5457260},"MAP_UNDERWATER_ROUTE129":{"header_address":4759504,"warp_table_address":5457312},"MAP_UNDERWATER_ROUTE134":{"header_address":4766588,"warp_table_address":5497540},"MAP_UNDERWATER_SEAFLOOR_CAVERN":{"header_address":4765384,"warp_table_address":5491744},"MAP_UNDERWATER_SEALED_CHAMBER":{"header_address":4766616,"warp_table_address":5497568},"MAP_UNDERWATER_SOOTOPOLIS_CITY":{"header_address":4764796,"warp_table_address":5486768},"MAP_UNION_ROOM":{"header_address":4769360,"warp_table_address":5514872},"MAP_UNUSED_CONTEST_HALL1":{"header_address":4768492,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL2":{"header_address":4768520,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL3":{"header_address":4768548,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL4":{"header_address":4768576,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL5":{"header_address":4768604,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL6":{"header_address":4768632,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN":{"header_address":4758384,"warp_table_address":5436044},"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760512,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760484,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760456,"warp_table_address":5463128},"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":{"header_address":4760652,"warp_table_address":5463928},"MAP_VERDANTURF_TOWN_HOUSE":{"header_address":4760680,"warp_table_address":5464012},"MAP_VERDANTURF_TOWN_MART":{"header_address":4760540,"warp_table_address":5463408},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":{"header_address":4760568,"warp_table_address":5463540},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":{"header_address":4760596,"warp_table_address":5463680},"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":{"header_address":4760624,"warp_table_address":5463844},"MAP_VICTORY_ROAD_1F":{"header_address":4765860,"land_encounters":{"address":5606156,"slots":[42,336,383,371,41,335,42,336,382,370,382,370]},"warp_table_address":5493852},"MAP_VICTORY_ROAD_B1F":{"header_address":4765888,"land_encounters":{"address":5610496,"slots":[42,336,383,383,42,336,42,336,383,355,383,355]},"warp_table_address":5494460},"MAP_VICTORY_ROAD_B2F":{"fishing_encounters":{"address":5610664,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4765916,"land_encounters":{"address":5610580,"slots":[42,322,383,383,42,322,42,322,383,355,383,355]},"warp_table_address":5494704,"water_encounters":{"address":5610636,"slots":[42,42,42,42,42]}}},"misc_pokemon":[{"address":2572358,"species":385},{"address":2018148,"species":360},{"address":2323175,"species":101},{"address":2323252,"species":101},{"address":2581669,"species":317},{"address":2581574,"species":317},{"address":2581688,"species":317},{"address":2581593,"species":317},{"address":2581612,"species":317},{"address":2581631,"species":317},{"address":2581650,"species":317},{"address":2065036,"species":317},{"address":2386223,"species":185},{"address":2339323,"species":100},{"address":2339400,"species":100},{"address":2339477,"species":100}],"misc_ram_addresses":{"CB2_Overworld":134768624,"gArchipelagoDeathLinkQueued":33804824,"gArchipelagoReceivedItem":33804776,"gMain":50340544,"gPlayerParty":33703196,"gSaveBlock1Ptr":50355596,"gSaveBlock2Ptr":50355600},"misc_rom_addresses":{"gArchipelagoInfo":5912960,"gArchipelagoItemNames":5896457,"gArchipelagoNameTable":5905457,"gArchipelagoOptions":5895556,"gArchipelagoPlayerNames":5895607,"gBattleMoves":3281380,"gEvolutionTable":3318404,"gLevelUpLearnsets":3334884,"gRandomizedBerryTreeItems":5843560,"gRandomizedSoundTable":10155508,"gSpeciesInfo":3296744,"gTMHMLearnsets":3289780,"gTrainers":3230072,"gTutorMoves":6428060,"sFanfares":5422580,"sNewGamePCItems":6210444,"sStarterMon":6021752,"sTMHMMoves":6432208,"sTutorLearnsets":6428120},"species":[{"abilities":[0,0],"address":3296744,"base_stats":[0,0,0,0,0,0],"catch_rate":0,"evolutions":[],"friendship":0,"id":0,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3296772,"base_stats":[45,49,49,45,65,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":2}],"friendship":70,"id":1,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296800,"base_stats":[60,62,63,60,80,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":3}],"friendship":70,"id":2,"learnset":{"address":3308308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":38,"move_id":74},{"level":47,"move_id":235},{"level":56,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296828,"base_stats":[80,82,83,80,100,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":3,"learnset":{"address":3308338,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":1,"move_id":22},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":41,"move_id":74},{"level":53,"move_id":235},{"level":65,"move_id":76}]},"tmhm_learnset":"00E41E0886354730","types":[12,3]},{"abilities":[66,0],"address":3296856,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":5}],"friendship":70,"id":4,"learnset":{"address":3308368,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":19,"move_id":99},{"level":25,"move_id":184},{"level":31,"move_id":53},{"level":37,"move_id":163},{"level":43,"move_id":82},{"level":49,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296884,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":6}],"friendship":70,"id":5,"learnset":{"address":3308394,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":41,"move_id":163},{"level":48,"move_id":82},{"level":55,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296912,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":6,"learnset":{"address":3308420,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":1,"move_id":108},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":36,"move_id":17},{"level":44,"move_id":163},{"level":54,"move_id":82},{"level":64,"move_id":83}]},"tmhm_learnset":"00AE5EA4CE514633","types":[10,2]},{"abilities":[67,0],"address":3296940,"base_stats":[44,48,65,43,50,64],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":8}],"friendship":70,"id":7,"learnset":{"address":3308448,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":18,"move_id":44},{"level":23,"move_id":229},{"level":28,"move_id":182},{"level":33,"move_id":240},{"level":40,"move_id":130},{"level":47,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296968,"base_stats":[59,63,80,58,65,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":9}],"friendship":70,"id":8,"learnset":{"address":3308478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":37,"move_id":240},{"level":45,"move_id":130},{"level":53,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296996,"base_stats":[79,83,100,78,85,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":9,"learnset":{"address":3308508,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":1,"move_id":110},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":42,"move_id":240},{"level":55,"move_id":130},{"level":68,"move_id":56}]},"tmhm_learnset":"03B01E00CE537275","types":[11,11]},{"abilities":[19,0],"address":3297024,"base_stats":[45,30,35,45,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":11}],"friendship":70,"id":10,"learnset":{"address":3308538,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3297052,"base_stats":[50,20,55,30,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":12}],"friendship":70,"id":11,"learnset":{"address":3308548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[14,0],"address":3297080,"base_stats":[60,45,50,70,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":12,"learnset":{"address":3308560,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":77},{"level":14,"move_id":78},{"level":15,"move_id":79},{"level":18,"move_id":48},{"level":23,"move_id":18},{"level":28,"move_id":16},{"level":34,"move_id":60},{"level":40,"move_id":219},{"level":47,"move_id":318}]},"tmhm_learnset":"0040BE80B43F4620","types":[6,2]},{"abilities":[19,0],"address":3297108,"base_stats":[40,35,30,50,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":14}],"friendship":70,"id":13,"learnset":{"address":3308590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[61,0],"address":3297136,"base_stats":[45,25,50,35,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":15}],"friendship":70,"id":14,"learnset":{"address":3308600,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[68,0],"address":3297164,"base_stats":[65,80,40,75,45,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":15,"learnset":{"address":3308612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":31},{"level":10,"move_id":31},{"level":15,"move_id":116},{"level":20,"move_id":41},{"level":25,"move_id":99},{"level":30,"move_id":228},{"level":35,"move_id":42},{"level":40,"move_id":97},{"level":45,"move_id":283}]},"tmhm_learnset":"00843E88C4354620","types":[6,3]},{"abilities":[51,0],"address":3297192,"base_stats":[40,45,40,56,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":17}],"friendship":70,"id":16,"learnset":{"address":3308638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":19,"move_id":18},{"level":25,"move_id":17},{"level":31,"move_id":297},{"level":39,"move_id":97},{"level":47,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297220,"base_stats":[63,60,55,71,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":18}],"friendship":70,"id":17,"learnset":{"address":3308664,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":43,"move_id":97},{"level":52,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297248,"base_stats":[83,80,75,91,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":18,"learnset":{"address":3308690,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":1,"move_id":98},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":48,"move_id":97},{"level":62,"move_id":119}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[50,62],"address":3297276,"base_stats":[30,56,35,72,25,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":20}],"friendship":70,"id":19,"learnset":{"address":3308716,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":116},{"level":27,"move_id":228},{"level":34,"move_id":162},{"level":41,"move_id":283}]},"tmhm_learnset":"00843E02ADD33E20","types":[0,0]},{"abilities":[50,62],"address":3297304,"base_stats":[55,81,60,97,50,70],"catch_rate":127,"evolutions":[],"friendship":70,"id":20,"learnset":{"address":3308738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":184},{"level":30,"move_id":228},{"level":40,"move_id":162},{"level":50,"move_id":283}]},"tmhm_learnset":"00A43E02ADD37E30","types":[0,0]},{"abilities":[51,0],"address":3297332,"base_stats":[40,60,30,70,31,31],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":22}],"friendship":70,"id":21,"learnset":{"address":3308760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":19,"move_id":228},{"level":25,"move_id":332},{"level":31,"move_id":119},{"level":37,"move_id":65},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297360,"base_stats":[65,90,65,100,61,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":22,"learnset":{"address":3308784,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":43},{"level":1,"move_id":31},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":26,"move_id":228},{"level":32,"move_id":119},{"level":40,"move_id":65},{"level":47,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[22,61],"address":3297388,"base_stats":[35,60,44,55,40,54],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":24}],"friendship":70,"id":23,"learnset":{"address":3308806,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":25,"move_id":103},{"level":32,"move_id":51},{"level":37,"move_id":254},{"level":37,"move_id":256},{"level":37,"move_id":255},{"level":44,"move_id":114}]},"tmhm_learnset":"00213F088E570620","types":[3,3]},{"abilities":[22,61],"address":3297416,"base_stats":[60,85,69,80,65,79],"catch_rate":90,"evolutions":[],"friendship":70,"id":24,"learnset":{"address":3308834,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":40},{"level":1,"move_id":44},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":28,"move_id":103},{"level":38,"move_id":51},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255},{"level":56,"move_id":114}]},"tmhm_learnset":"00213F088E574620","types":[3,3]},{"abilities":[9,0],"address":3297444,"base_stats":[35,55,30,90,50,40],"catch_rate":190,"evolutions":[{"method":"ITEM","param":96,"species":26}],"friendship":70,"id":25,"learnset":{"address":3308862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":45},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":98},{"level":15,"move_id":104},{"level":20,"move_id":21},{"level":26,"move_id":85},{"level":33,"move_id":97},{"level":41,"move_id":87},{"level":50,"move_id":113}]},"tmhm_learnset":"00E01E02CDD38221","types":[13,13]},{"abilities":[9,0],"address":3297472,"base_stats":[60,90,55,100,90,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":26,"learnset":{"address":3308890,"moves":[{"level":1,"move_id":84},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":1,"move_id":85}]},"tmhm_learnset":"00E03E02CDD3C221","types":[13,13]},{"abilities":[8,0],"address":3297500,"base_stats":[50,75,85,40,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":28}],"friendship":70,"id":27,"learnset":{"address":3308900,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":23,"move_id":163},{"level":30,"move_id":129},{"level":37,"move_id":154},{"level":45,"move_id":328},{"level":53,"move_id":201}]},"tmhm_learnset":"00A43ED0CE510621","types":[4,4]},{"abilities":[8,0],"address":3297528,"base_stats":[75,100,110,65,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":28,"learnset":{"address":3308926,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":28},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":24,"move_id":163},{"level":33,"move_id":129},{"level":42,"move_id":154},{"level":52,"move_id":328},{"level":62,"move_id":201}]},"tmhm_learnset":"00A43ED0CE514621","types":[4,4]},{"abilities":[38,0],"address":3297556,"base_stats":[55,47,52,41,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":30}],"friendship":70,"id":29,"learnset":{"address":3308952,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":44},{"level":23,"move_id":270},{"level":30,"move_id":154},{"level":38,"move_id":260},{"level":47,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297584,"base_stats":[70,62,67,56,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":31}],"friendship":70,"id":30,"learnset":{"address":3308978,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":44},{"level":26,"move_id":270},{"level":34,"move_id":154},{"level":43,"move_id":260},{"level":53,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297612,"base_stats":[90,82,87,76,75,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":31,"learnset":{"address":3309004,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":34}]},"tmhm_learnset":"00B43FFEEFD37E35","types":[3,4]},{"abilities":[38,0],"address":3297640,"base_stats":[46,57,40,50,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":33}],"friendship":70,"id":32,"learnset":{"address":3309016,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":30},{"level":23,"move_id":270},{"level":30,"move_id":31},{"level":38,"move_id":260},{"level":47,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297668,"base_stats":[61,72,57,65,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":34}],"friendship":70,"id":33,"learnset":{"address":3309042,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":30},{"level":26,"move_id":270},{"level":34,"move_id":31},{"level":43,"move_id":260},{"level":53,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297696,"base_stats":[81,92,77,85,85,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":34,"learnset":{"address":3309068,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":116},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":37}]},"tmhm_learnset":"00B43F7EEFD37E35","types":[3,4]},{"abilities":[56,0],"address":3297724,"base_stats":[70,45,48,35,60,65],"catch_rate":150,"evolutions":[{"method":"ITEM","param":94,"species":36}],"friendship":140,"id":35,"learnset":{"address":3309080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":227},{"level":9,"move_id":47},{"level":13,"move_id":3},{"level":17,"move_id":266},{"level":21,"move_id":107},{"level":25,"move_id":111},{"level":29,"move_id":118},{"level":33,"move_id":322},{"level":37,"move_id":236},{"level":41,"move_id":113},{"level":45,"move_id":309}]},"tmhm_learnset":"00611E27FDFBB62D","types":[0,0]},{"abilities":[56,0],"address":3297752,"base_stats":[95,70,73,60,85,90],"catch_rate":25,"evolutions":[],"friendship":140,"id":36,"learnset":{"address":3309112,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":3},{"level":1,"move_id":107},{"level":1,"move_id":118}]},"tmhm_learnset":"00611E27FDFBF62D","types":[0,0]},{"abilities":[18,0],"address":3297780,"base_stats":[38,41,40,65,50,65],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":38}],"friendship":70,"id":37,"learnset":{"address":3309122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":5,"move_id":39},{"level":9,"move_id":46},{"level":13,"move_id":98},{"level":17,"move_id":261},{"level":21,"move_id":109},{"level":25,"move_id":286},{"level":29,"move_id":53},{"level":33,"move_id":219},{"level":37,"move_id":288},{"level":41,"move_id":83}]},"tmhm_learnset":"00021E248C590630","types":[10,10]},{"abilities":[18,0],"address":3297808,"base_stats":[73,76,75,100,81,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":38,"learnset":{"address":3309152,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":98},{"level":1,"move_id":109},{"level":1,"move_id":219},{"level":45,"move_id":83}]},"tmhm_learnset":"00021E248C594630","types":[10,10]},{"abilities":[56,0],"address":3297836,"base_stats":[115,45,20,20,45,25],"catch_rate":170,"evolutions":[{"method":"ITEM","param":94,"species":40}],"friendship":70,"id":39,"learnset":{"address":3309164,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":50},{"level":19,"move_id":205},{"level":24,"move_id":3},{"level":29,"move_id":156},{"level":34,"move_id":34},{"level":39,"move_id":102},{"level":44,"move_id":304},{"level":49,"move_id":38}]},"tmhm_learnset":"00611E27FDBBB625","types":[0,0]},{"abilities":[56,0],"address":3297864,"base_stats":[140,70,45,45,75,50],"catch_rate":50,"evolutions":[],"friendship":70,"id":40,"learnset":{"address":3309194,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":50},{"level":1,"move_id":111},{"level":1,"move_id":3}]},"tmhm_learnset":"00611E27FDBBF625","types":[0,0]},{"abilities":[39,0],"address":3297892,"base_stats":[40,45,35,55,30,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":42}],"friendship":70,"id":41,"learnset":{"address":3309204,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":141},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":26,"move_id":109},{"level":31,"move_id":314},{"level":36,"move_id":212},{"level":41,"move_id":305},{"level":46,"move_id":114}]},"tmhm_learnset":"00017F88A4170E20","types":[3,2]},{"abilities":[39,0],"address":3297920,"base_stats":[75,80,70,90,65,75],"catch_rate":90,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":169}],"friendship":70,"id":42,"learnset":{"address":3309232,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00017F88A4174E20","types":[3,2]},{"abilities":[34,0],"address":3297948,"base_stats":[45,50,55,30,75,65],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":44}],"friendship":70,"id":43,"learnset":{"address":3309260,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":23,"move_id":51},{"level":32,"move_id":236},{"level":39,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3297976,"base_stats":[60,65,70,40,85,75],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":45},{"method":"ITEM","param":93,"species":182}],"friendship":70,"id":44,"learnset":{"address":3309284,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":77},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":24,"move_id":51},{"level":35,"move_id":236},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298004,"base_stats":[75,80,85,50,100,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":45,"learnset":{"address":3309308,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":312},{"level":1,"move_id":78},{"level":1,"move_id":72},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884354720","types":[12,3]},{"abilities":[27,0],"address":3298032,"base_stats":[35,70,55,25,45,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":24,"species":47}],"friendship":70,"id":46,"learnset":{"address":3309320,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":25,"move_id":147},{"level":31,"move_id":163},{"level":37,"move_id":74},{"level":43,"move_id":202},{"level":49,"move_id":312}]},"tmhm_learnset":"00C43E888C350720","types":[6,12]},{"abilities":[27,0],"address":3298060,"base_stats":[60,95,80,30,60,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":47,"learnset":{"address":3309346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":78},{"level":1,"move_id":77},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":27,"move_id":147},{"level":35,"move_id":163},{"level":43,"move_id":74},{"level":51,"move_id":202},{"level":59,"move_id":312}]},"tmhm_learnset":"00C43E888C354720","types":[6,12]},{"abilities":[14,0],"address":3298088,"base_stats":[60,55,50,45,40,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":49}],"friendship":70,"id":48,"learnset":{"address":3309372,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":33,"move_id":60},{"level":36,"move_id":79},{"level":41,"move_id":94}]},"tmhm_learnset":"0040BE0894350620","types":[6,3]},{"abilities":[19,0],"address":3298116,"base_stats":[70,65,60,90,90,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":49,"learnset":{"address":3309398,"moves":[{"level":1,"move_id":318},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":1,"move_id":48},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":31,"move_id":16},{"level":36,"move_id":60},{"level":42,"move_id":79},{"level":52,"move_id":94}]},"tmhm_learnset":"0040BE8894354620","types":[6,3]},{"abilities":[8,71],"address":3298144,"base_stats":[10,55,25,95,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":26,"species":51}],"friendship":70,"id":50,"learnset":{"address":3309428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":33,"move_id":163},{"level":41,"move_id":89},{"level":49,"move_id":90}]},"tmhm_learnset":"00843EC88E110620","types":[4,4]},{"abilities":[8,71],"address":3298172,"base_stats":[35,80,50,120,50,70],"catch_rate":50,"evolutions":[],"friendship":70,"id":51,"learnset":{"address":3309452,"moves":[{"level":1,"move_id":161},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":1,"move_id":45},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":26,"move_id":328},{"level":38,"move_id":163},{"level":51,"move_id":89},{"level":64,"move_id":90}]},"tmhm_learnset":"00843EC88E114620","types":[4,4]},{"abilities":[53,0],"address":3298200,"base_stats":[40,45,35,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":28,"species":53}],"friendship":70,"id":52,"learnset":{"address":3309478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":28,"move_id":185},{"level":35,"move_id":103},{"level":41,"move_id":154},{"level":46,"move_id":163},{"level":50,"move_id":252}]},"tmhm_learnset":"00453F82ADD30E24","types":[0,0]},{"abilities":[7,0],"address":3298228,"base_stats":[65,70,60,115,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":53,"learnset":{"address":3309502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":44},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":29,"move_id":185},{"level":38,"move_id":103},{"level":46,"move_id":154},{"level":53,"move_id":163},{"level":59,"move_id":252}]},"tmhm_learnset":"00453F82ADD34E34","types":[0,0]},{"abilities":[6,13],"address":3298256,"base_stats":[50,52,48,55,65,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":33,"species":55}],"friendship":70,"id":54,"learnset":{"address":3309526,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":40,"move_id":154},{"level":50,"move_id":56}]},"tmhm_learnset":"03F01E80CC53326D","types":[11,11]},{"abilities":[6,13],"address":3298284,"base_stats":[80,82,78,85,95,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":55,"learnset":{"address":3309550,"moves":[{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":50},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":44,"move_id":154},{"level":58,"move_id":56}]},"tmhm_learnset":"03F01E80CC53726D","types":[11,11]},{"abilities":[72,0],"address":3298312,"base_stats":[40,80,35,70,35,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":57}],"friendship":70,"id":56,"learnset":{"address":3309574,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":33,"move_id":69},{"level":39,"move_id":238},{"level":45,"move_id":103},{"level":51,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD30EA1","types":[1,1]},{"abilities":[72,0],"address":3298340,"base_stats":[65,105,60,95,60,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":57,"learnset":{"address":3309600,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":67},{"level":1,"move_id":99},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":28,"move_id":99},{"level":36,"move_id":69},{"level":45,"move_id":238},{"level":54,"move_id":103},{"level":63,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD34EA1","types":[1,1]},{"abilities":[22,18],"address":3298368,"base_stats":[55,70,45,60,70,50],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":59}],"friendship":70,"id":58,"learnset":{"address":3309628,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":7,"move_id":52},{"level":13,"move_id":43},{"level":19,"move_id":316},{"level":25,"move_id":36},{"level":31,"move_id":172},{"level":37,"move_id":270},{"level":43,"move_id":97},{"level":49,"move_id":53}]},"tmhm_learnset":"00A23EA48C510630","types":[10,10]},{"abilities":[22,18],"address":3298396,"base_stats":[90,110,80,95,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":59,"learnset":{"address":3309654,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":1,"move_id":52},{"level":1,"move_id":316},{"level":49,"move_id":245}]},"tmhm_learnset":"00A23EA48C514630","types":[10,10]},{"abilities":[11,6],"address":3298424,"base_stats":[40,50,40,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":61}],"friendship":70,"id":60,"learnset":{"address":3309666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":25,"move_id":240},{"level":31,"move_id":34},{"level":37,"move_id":187},{"level":43,"move_id":56}]},"tmhm_learnset":"03103E009C133264","types":[11,11]},{"abilities":[11,6],"address":3298452,"base_stats":[65,65,65,90,50,50],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":62},{"method":"ITEM","param":187,"species":186}],"friendship":70,"id":61,"learnset":{"address":3309690,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":95},{"level":1,"move_id":55},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":27,"move_id":240},{"level":35,"move_id":34},{"level":43,"move_id":187},{"level":51,"move_id":56}]},"tmhm_learnset":"03B03E00DE133265","types":[11,11]},{"abilities":[11,6],"address":3298480,"base_stats":[90,85,95,70,70,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":62,"learnset":{"address":3309714,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":66},{"level":35,"move_id":66},{"level":51,"move_id":170}]},"tmhm_learnset":"03B03E40DE1372E5","types":[11,1]},{"abilities":[28,39],"address":3298508,"base_stats":[25,20,15,90,105,55],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":16,"species":64}],"friendship":70,"id":63,"learnset":{"address":3309728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":100}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298536,"base_stats":[40,35,30,105,120,70],"catch_rate":100,"evolutions":[{"method":"LEVEL","param":37,"species":65}],"friendship":70,"id":64,"learnset":{"address":3309738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":272},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298564,"base_stats":[55,50,45,120,135,85],"catch_rate":50,"evolutions":[],"friendship":70,"id":65,"learnset":{"address":3309766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":347},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45BCE29","types":[14,14]},{"abilities":[62,0],"address":3298592,"base_stats":[70,80,50,35,35,35],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":28,"species":67}],"friendship":70,"id":66,"learnset":{"address":3309794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":31,"move_id":233},{"level":37,"move_id":66},{"level":40,"move_id":238},{"level":43,"move_id":184},{"level":49,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298620,"base_stats":[80,100,70,45,50,60],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":68}],"friendship":70,"id":67,"learnset":{"address":3309824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298648,"base_stats":[90,130,80,55,65,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":68,"learnset":{"address":3309854,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1346A1","types":[1,1]},{"abilities":[34,0],"address":3298676,"base_stats":[50,75,35,40,70,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":70}],"friendship":70,"id":69,"learnset":{"address":3309884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":23,"move_id":51},{"level":30,"move_id":230},{"level":37,"move_id":75},{"level":45,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298704,"base_stats":[65,90,50,55,85,45],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":71}],"friendship":70,"id":70,"learnset":{"address":3309912,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":1,"move_id":74},{"level":1,"move_id":35},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":24,"move_id":51},{"level":33,"move_id":230},{"level":42,"move_id":75},{"level":54,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298732,"base_stats":[80,105,65,70,100,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":71,"learnset":{"address":3309940,"moves":[{"level":1,"move_id":22},{"level":1,"move_id":79},{"level":1,"move_id":230},{"level":1,"move_id":75}]},"tmhm_learnset":"00443E0884354720","types":[12,3]},{"abilities":[29,64],"address":3298760,"base_stats":[40,40,35,70,50,100],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":73}],"friendship":70,"id":72,"learnset":{"address":3309950,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":36,"move_id":112},{"level":43,"move_id":103},{"level":49,"move_id":56}]},"tmhm_learnset":"03143E0884173264","types":[11,3]},{"abilities":[29,64],"address":3298788,"base_stats":[80,70,65,100,80,120],"catch_rate":60,"evolutions":[],"friendship":70,"id":73,"learnset":{"address":3309976,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":48},{"level":1,"move_id":132},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":38,"move_id":112},{"level":47,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03143E0884177264","types":[11,3]},{"abilities":[69,5],"address":3298816,"base_stats":[40,80,100,20,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":75}],"friendship":70,"id":74,"learnset":{"address":3310002,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":26,"move_id":205},{"level":31,"move_id":350},{"level":36,"move_id":89},{"level":41,"move_id":153},{"level":46,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298844,"base_stats":[55,95,115,35,45,45],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":37,"species":76}],"friendship":70,"id":75,"learnset":{"address":3310030,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298872,"base_stats":[80,110,130,45,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":76,"learnset":{"address":3310058,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE114631","types":[5,4]},{"abilities":[50,18],"address":3298900,"base_stats":[50,85,55,90,65,65],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":40,"species":78}],"friendship":70,"id":77,"learnset":{"address":3310086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":45,"move_id":340},{"level":53,"move_id":126}]},"tmhm_learnset":"00221E2484710620","types":[10,10]},{"abilities":[50,18],"address":3298928,"base_stats":[65,100,70,105,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":78,"learnset":{"address":3310114,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":52},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":40,"move_id":31},{"level":50,"move_id":340},{"level":63,"move_id":126}]},"tmhm_learnset":"00221E2484714620","types":[10,10]},{"abilities":[12,20],"address":3298956,"base_stats":[90,65,65,15,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":80},{"method":"ITEM","param":187,"species":199}],"friendship":70,"id":79,"learnset":{"address":3310144,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":133},{"level":48,"move_id":94}]},"tmhm_learnset":"02709E24BE5B366C","types":[11,14]},{"abilities":[12,20],"address":3298984,"base_stats":[95,75,110,30,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":80,"learnset":{"address":3310168,"moves":[{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":37,"move_id":110},{"level":46,"move_id":133},{"level":54,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[42,5],"address":3299012,"base_stats":[25,35,70,45,95,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":82}],"friendship":70,"id":81,"learnset":{"address":3310194,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":32,"move_id":199},{"level":38,"move_id":129},{"level":44,"move_id":103},{"level":50,"move_id":192}]},"tmhm_learnset":"00400E0385930620","types":[13,8]},{"abilities":[42,5],"address":3299040,"base_stats":[50,60,95,70,120,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":82,"learnset":{"address":3310222,"moves":[{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":1,"move_id":84},{"level":1,"move_id":48},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":35,"move_id":199},{"level":44,"move_id":161},{"level":53,"move_id":103},{"level":62,"move_id":192}]},"tmhm_learnset":"00400E0385934620","types":[13,8]},{"abilities":[51,39],"address":3299068,"base_stats":[52,65,55,60,58,62],"catch_rate":45,"evolutions":[],"friendship":70,"id":83,"learnset":{"address":3310250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":6,"move_id":28},{"level":11,"move_id":43},{"level":16,"move_id":31},{"level":21,"move_id":282},{"level":26,"move_id":210},{"level":31,"move_id":14},{"level":36,"move_id":97},{"level":41,"move_id":163},{"level":46,"move_id":206}]},"tmhm_learnset":"000C7E8084510620","types":[0,2]},{"abilities":[50,48],"address":3299096,"base_stats":[35,85,45,75,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":85}],"friendship":70,"id":84,"learnset":{"address":3310278,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":33,"move_id":253},{"level":37,"move_id":65},{"level":45,"move_id":97}]},"tmhm_learnset":"00087E8084110620","types":[0,2]},{"abilities":[50,48],"address":3299124,"base_stats":[60,110,70,100,60,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":85,"learnset":{"address":3310302,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":228},{"level":1,"move_id":31},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":38,"move_id":253},{"level":47,"move_id":65},{"level":60,"move_id":97}]},"tmhm_learnset":"00087F8084114E20","types":[0,2]},{"abilities":[47,0],"address":3299152,"base_stats":[65,45,55,45,45,70],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":34,"species":87}],"friendship":70,"id":86,"learnset":{"address":3310326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":29},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":37,"move_id":36},{"level":41,"move_id":58},{"level":49,"move_id":219}]},"tmhm_learnset":"03103E00841B3264","types":[11,11]},{"abilities":[47,0],"address":3299180,"base_stats":[90,70,80,70,70,95],"catch_rate":75,"evolutions":[],"friendship":70,"id":87,"learnset":{"address":3310350,"moves":[{"level":1,"move_id":29},{"level":1,"move_id":45},{"level":1,"move_id":196},{"level":1,"move_id":62},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":34,"move_id":329},{"level":42,"move_id":36},{"level":51,"move_id":58},{"level":64,"move_id":219}]},"tmhm_learnset":"03103E00841B7264","types":[11,15]},{"abilities":[1,60],"address":3299208,"base_stats":[80,80,50,25,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":89}],"friendship":70,"id":88,"learnset":{"address":3310376,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":43,"move_id":188},{"level":53,"move_id":262}]},"tmhm_learnset":"00003F6E8D970E20","types":[3,3]},{"abilities":[1,60],"address":3299236,"base_stats":[105,105,75,50,65,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":89,"learnset":{"address":3310402,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":47,"move_id":188},{"level":61,"move_id":262}]},"tmhm_learnset":"00A03F6ECD974E21","types":[3,3]},{"abilities":[75,0],"address":3299264,"base_stats":[30,65,100,40,45,25],"catch_rate":190,"evolutions":[{"method":"ITEM","param":97,"species":91}],"friendship":70,"id":90,"learnset":{"address":3310428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":110},{"level":9,"move_id":48},{"level":17,"move_id":62},{"level":25,"move_id":182},{"level":33,"move_id":43},{"level":41,"move_id":128},{"level":49,"move_id":58}]},"tmhm_learnset":"02101E0084133264","types":[11,11]},{"abilities":[75,0],"address":3299292,"base_stats":[50,95,180,70,85,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":91,"learnset":{"address":3310450,"moves":[{"level":1,"move_id":110},{"level":1,"move_id":48},{"level":1,"move_id":62},{"level":1,"move_id":182},{"level":33,"move_id":191},{"level":41,"move_id":131}]},"tmhm_learnset":"02101F0084137264","types":[11,15]},{"abilities":[26,0],"address":3299320,"base_stats":[30,35,30,80,100,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":93}],"friendship":70,"id":92,"learnset":{"address":3310464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":28,"move_id":109},{"level":33,"move_id":138},{"level":36,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299348,"base_stats":[45,50,45,95,115,55],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":94}],"friendship":70,"id":93,"learnset":{"address":3310488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299376,"base_stats":[60,65,60,110,130,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":94,"learnset":{"address":3310514,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"00A1BF08F5974E21","types":[7,3]},{"abilities":[69,5],"address":3299404,"base_stats":[35,45,160,70,30,45],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":208}],"friendship":70,"id":95,"learnset":{"address":3310540,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":328},{"level":57,"move_id":38}]},"tmhm_learnset":"00A01F508E510E30","types":[5,4]},{"abilities":[15,0],"address":3299432,"base_stats":[60,48,45,42,43,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":26,"species":97}],"friendship":70,"id":96,"learnset":{"address":3310568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":31,"move_id":139},{"level":36,"move_id":96},{"level":40,"move_id":94},{"level":43,"move_id":244},{"level":45,"move_id":248}]},"tmhm_learnset":"0041BF01F41B8E29","types":[14,14]},{"abilities":[15,0],"address":3299460,"base_stats":[85,73,70,67,73,115],"catch_rate":75,"evolutions":[],"friendship":70,"id":97,"learnset":{"address":3310594,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":1,"move_id":50},{"level":1,"move_id":93},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":33,"move_id":139},{"level":40,"move_id":96},{"level":49,"move_id":94},{"level":55,"move_id":244},{"level":60,"move_id":248}]},"tmhm_learnset":"0041BF01F41BCE29","types":[14,14]},{"abilities":[52,75],"address":3299488,"base_stats":[30,105,90,50,25,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":28,"species":99}],"friendship":70,"id":98,"learnset":{"address":3310620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":34,"move_id":12},{"level":41,"move_id":182},{"level":45,"move_id":152}]},"tmhm_learnset":"02B43E408C133264","types":[11,11]},{"abilities":[52,75],"address":3299516,"base_stats":[55,130,115,75,50,50],"catch_rate":60,"evolutions":[],"friendship":70,"id":99,"learnset":{"address":3310646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":43},{"level":1,"move_id":11},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":38,"move_id":12},{"level":49,"move_id":182},{"level":57,"move_id":152}]},"tmhm_learnset":"02B43E408C137264","types":[11,11]},{"abilities":[43,9],"address":3299544,"base_stats":[40,30,50,100,55,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":101}],"friendship":70,"id":100,"learnset":{"address":3310672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":32,"move_id":205},{"level":37,"move_id":113},{"level":42,"move_id":129},{"level":46,"move_id":153},{"level":49,"move_id":243}]},"tmhm_learnset":"00402F0285938A20","types":[13,13]},{"abilities":[43,9],"address":3299572,"base_stats":[60,50,70,140,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":101,"learnset":{"address":3310700,"moves":[{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":1,"move_id":49},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":34,"move_id":205},{"level":41,"move_id":113},{"level":48,"move_id":129},{"level":54,"move_id":153},{"level":59,"move_id":243}]},"tmhm_learnset":"00402F028593CA20","types":[13,13]},{"abilities":[34,0],"address":3299600,"base_stats":[60,40,80,40,60,45],"catch_rate":90,"evolutions":[{"method":"ITEM","param":98,"species":103}],"friendship":70,"id":102,"learnset":{"address":3310728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":253},{"level":1,"move_id":95},{"level":7,"move_id":115},{"level":13,"move_id":73},{"level":19,"move_id":93},{"level":25,"move_id":78},{"level":31,"move_id":77},{"level":37,"move_id":79},{"level":43,"move_id":76}]},"tmhm_learnset":"0060BE0994358720","types":[12,14]},{"abilities":[34,0],"address":3299628,"base_stats":[95,95,85,55,125,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":103,"learnset":{"address":3310752,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":95},{"level":1,"move_id":93},{"level":19,"move_id":23},{"level":31,"move_id":121}]},"tmhm_learnset":"0060BE099435C720","types":[12,14]},{"abilities":[69,31],"address":3299656,"base_stats":[50,50,95,35,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":105}],"friendship":70,"id":104,"learnset":{"address":3310766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":125},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":29,"move_id":99},{"level":33,"move_id":206},{"level":37,"move_id":37},{"level":41,"move_id":198},{"level":45,"move_id":38}]},"tmhm_learnset":"00A03EF4CE513621","types":[4,4]},{"abilities":[69,31],"address":3299684,"base_stats":[60,80,110,45,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":105,"learnset":{"address":3310798,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":125},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":32,"move_id":99},{"level":39,"move_id":206},{"level":46,"move_id":37},{"level":53,"move_id":198},{"level":61,"move_id":38}]},"tmhm_learnset":"00A03EF4CE517621","types":[4,4]},{"abilities":[7,0],"address":3299712,"base_stats":[50,120,53,87,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":106,"learnset":{"address":3310830,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":24},{"level":6,"move_id":96},{"level":11,"move_id":27},{"level":16,"move_id":26},{"level":20,"move_id":280},{"level":21,"move_id":116},{"level":26,"move_id":136},{"level":31,"move_id":170},{"level":36,"move_id":193},{"level":41,"move_id":203},{"level":46,"move_id":25},{"level":51,"move_id":179}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[51,0],"address":3299740,"base_stats":[50,105,79,76,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":107,"learnset":{"address":3310862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":4},{"level":7,"move_id":97},{"level":13,"move_id":228},{"level":20,"move_id":183},{"level":26,"move_id":9},{"level":26,"move_id":8},{"level":26,"move_id":7},{"level":32,"move_id":327},{"level":38,"move_id":5},{"level":44,"move_id":197},{"level":50,"move_id":68}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[20,12],"address":3299768,"base_stats":[90,55,75,30,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":108,"learnset":{"address":3310892,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":122},{"level":7,"move_id":48},{"level":12,"move_id":111},{"level":18,"move_id":282},{"level":23,"move_id":23},{"level":29,"move_id":35},{"level":34,"move_id":50},{"level":40,"move_id":21},{"level":45,"move_id":103},{"level":51,"move_id":287}]},"tmhm_learnset":"00B43E76EFF37625","types":[0,0]},{"abilities":[26,0],"address":3299796,"base_stats":[40,65,95,35,60,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":35,"species":110}],"friendship":70,"id":109,"learnset":{"address":3310920,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":41,"move_id":153},{"level":45,"move_id":194},{"level":49,"move_id":262}]},"tmhm_learnset":"00403F2EA5930E20","types":[3,3]},{"abilities":[26,0],"address":3299824,"base_stats":[65,90,120,60,85,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":110,"learnset":{"address":3310946,"moves":[{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":1,"move_id":123},{"level":1,"move_id":120},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":44,"move_id":153},{"level":51,"move_id":194},{"level":58,"move_id":262}]},"tmhm_learnset":"00403F2EA5934E20","types":[3,3]},{"abilities":[31,69],"address":3299852,"base_stats":[80,85,95,25,30,30],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":42,"species":112}],"friendship":70,"id":111,"learnset":{"address":3310972,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":43,"move_id":36},{"level":52,"move_id":89},{"level":57,"move_id":224}]},"tmhm_learnset":"00A03E768FD33630","types":[4,5]},{"abilities":[31,69],"address":3299880,"base_stats":[105,130,120,40,45,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":112,"learnset":{"address":3310998,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":1,"move_id":23},{"level":1,"move_id":31},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":46,"move_id":36},{"level":58,"move_id":89},{"level":66,"move_id":224}]},"tmhm_learnset":"00B43E76CFD37631","types":[4,5]},{"abilities":[30,32],"address":3299908,"base_stats":[250,5,5,50,35,105],"catch_rate":30,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":242}],"friendship":140,"id":113,"learnset":{"address":3311024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":287},{"level":13,"move_id":135},{"level":17,"move_id":3},{"level":23,"move_id":107},{"level":29,"move_id":47},{"level":35,"move_id":121},{"level":41,"move_id":111},{"level":49,"move_id":113},{"level":57,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[34,0],"address":3299936,"base_stats":[65,55,115,60,100,40],"catch_rate":45,"evolutions":[],"friendship":70,"id":114,"learnset":{"address":3311054,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":275},{"level":1,"move_id":132},{"level":4,"move_id":79},{"level":10,"move_id":71},{"level":13,"move_id":74},{"level":19,"move_id":77},{"level":22,"move_id":22},{"level":28,"move_id":20},{"level":31,"move_id":72},{"level":37,"move_id":78},{"level":40,"move_id":21},{"level":46,"move_id":321}]},"tmhm_learnset":"00C43E0884354720","types":[12,12]},{"abilities":[48,0],"address":3299964,"base_stats":[105,95,80,90,40,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":115,"learnset":{"address":3311084,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":4},{"level":1,"move_id":43},{"level":7,"move_id":44},{"level":13,"move_id":39},{"level":19,"move_id":252},{"level":25,"move_id":5},{"level":31,"move_id":99},{"level":37,"move_id":203},{"level":43,"move_id":146},{"level":49,"move_id":179}]},"tmhm_learnset":"00B43EF6EFF37675","types":[0,0]},{"abilities":[33,0],"address":3299992,"base_stats":[30,40,70,60,70,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":32,"species":117}],"friendship":70,"id":116,"learnset":{"address":3311110,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":36,"move_id":97},{"level":43,"move_id":56},{"level":50,"move_id":349}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[38,0],"address":3300020,"base_stats":[55,65,95,85,95,45],"catch_rate":75,"evolutions":[{"method":"ITEM","param":201,"species":230}],"friendship":70,"id":117,"learnset":{"address":3311134,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[33,41],"address":3300048,"base_stats":[45,67,60,63,35,50],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":119}],"friendship":70,"id":118,"learnset":{"address":3311158,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":38,"move_id":127},{"level":43,"move_id":32},{"level":52,"move_id":97}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,41],"address":3300076,"base_stats":[80,92,65,68,65,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":119,"learnset":{"address":3311182,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":1,"move_id":48},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":41,"move_id":127},{"level":49,"move_id":32},{"level":61,"move_id":97}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[35,30],"address":3300104,"base_stats":[30,45,55,85,70,55],"catch_rate":225,"evolutions":[{"method":"ITEM","param":97,"species":121}],"friendship":70,"id":120,"learnset":{"address":3311206,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":6,"move_id":55},{"level":10,"move_id":229},{"level":15,"move_id":105},{"level":19,"move_id":293},{"level":24,"move_id":129},{"level":28,"move_id":61},{"level":33,"move_id":107},{"level":37,"move_id":113},{"level":42,"move_id":322},{"level":46,"move_id":56}]},"tmhm_learnset":"03500E019593B264","types":[11,11]},{"abilities":[35,30],"address":3300132,"base_stats":[60,75,85,115,100,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":121,"learnset":{"address":3311236,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":229},{"level":1,"move_id":105},{"level":1,"move_id":129},{"level":33,"move_id":109}]},"tmhm_learnset":"03508E019593F264","types":[11,14]},{"abilities":[43,0],"address":3300160,"base_stats":[40,45,65,90,100,120],"catch_rate":45,"evolutions":[],"friendship":70,"id":122,"learnset":{"address":3311248,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":112},{"level":5,"move_id":93},{"level":9,"move_id":164},{"level":13,"move_id":96},{"level":17,"move_id":3},{"level":21,"move_id":113},{"level":21,"move_id":115},{"level":25,"move_id":227},{"level":29,"move_id":60},{"level":33,"move_id":278},{"level":37,"move_id":271},{"level":41,"move_id":272},{"level":45,"move_id":94},{"level":49,"move_id":226},{"level":53,"move_id":219}]},"tmhm_learnset":"0041BF03F5BBCE29","types":[14,14]},{"abilities":[68,0],"address":3300188,"base_stats":[70,110,80,105,55,80],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":212}],"friendship":70,"id":123,"learnset":{"address":3311286,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":17},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00847E8084134620","types":[6,2]},{"abilities":[12,0],"address":3300216,"base_stats":[65,50,35,95,115,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":124,"learnset":{"address":3311314,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":1,"move_id":142},{"level":1,"move_id":181},{"level":9,"move_id":142},{"level":13,"move_id":181},{"level":21,"move_id":3},{"level":25,"move_id":8},{"level":35,"move_id":212},{"level":41,"move_id":313},{"level":51,"move_id":34},{"level":57,"move_id":195},{"level":67,"move_id":59}]},"tmhm_learnset":"0040BF01F413FA6D","types":[15,14]},{"abilities":[9,0],"address":3300244,"base_stats":[65,83,57,105,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":125,"learnset":{"address":3311342,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":1,"move_id":9},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":36,"move_id":103},{"level":47,"move_id":85},{"level":58,"move_id":87}]},"tmhm_learnset":"00E03E02D5D3C221","types":[13,13]},{"abilities":[49,0],"address":3300272,"base_stats":[65,95,57,93,100,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":126,"learnset":{"address":3311364,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":43},{"level":1,"move_id":123},{"level":1,"move_id":7},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":33,"move_id":241},{"level":41,"move_id":53},{"level":49,"move_id":109},{"level":57,"move_id":126}]},"tmhm_learnset":"00A03E24D4514621","types":[10,10]},{"abilities":[52,0],"address":3300300,"base_stats":[65,125,100,85,55,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":127,"learnset":{"address":3311390,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":11},{"level":1,"move_id":116},{"level":7,"move_id":20},{"level":13,"move_id":69},{"level":19,"move_id":106},{"level":25,"move_id":279},{"level":31,"move_id":280},{"level":37,"move_id":12},{"level":43,"move_id":66},{"level":49,"move_id":14}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,6]},{"abilities":[22,0],"address":3300328,"base_stats":[75,100,95,110,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":128,"learnset":{"address":3311416,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":8,"move_id":99},{"level":13,"move_id":30},{"level":19,"move_id":184},{"level":26,"move_id":228},{"level":34,"move_id":156},{"level":43,"move_id":37},{"level":53,"move_id":36}]},"tmhm_learnset":"00B01E7687F37624","types":[0,0]},{"abilities":[33,0],"address":3300356,"base_stats":[20,10,55,80,15,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":130}],"friendship":70,"id":129,"learnset":{"address":3311442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"0000000000000000","types":[11,11]},{"abilities":[22,0],"address":3300384,"base_stats":[95,125,79,81,60,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":130,"learnset":{"address":3311456,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":37},{"level":20,"move_id":44},{"level":25,"move_id":82},{"level":30,"move_id":43},{"level":35,"move_id":239},{"level":40,"move_id":56},{"level":45,"move_id":240},{"level":50,"move_id":349},{"level":55,"move_id":63}]},"tmhm_learnset":"03B01F3487937A74","types":[11,2]},{"abilities":[11,75],"address":3300412,"base_stats":[130,85,80,60,85,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":131,"learnset":{"address":3311482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":45},{"level":1,"move_id":47},{"level":7,"move_id":54},{"level":13,"move_id":34},{"level":19,"move_id":109},{"level":25,"move_id":195},{"level":31,"move_id":58},{"level":37,"move_id":240},{"level":43,"move_id":219},{"level":49,"move_id":56},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E0295DB7274","types":[11,15]},{"abilities":[7,0],"address":3300440,"base_stats":[48,48,48,48,48,48],"catch_rate":35,"evolutions":[],"friendship":70,"id":132,"learnset":{"address":3311510,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":144}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[50,0],"address":3300468,"base_stats":[55,55,50,55,45,65],"catch_rate":45,"evolutions":[{"method":"ITEM","param":96,"species":135},{"method":"ITEM","param":97,"species":134},{"method":"ITEM","param":95,"species":136},{"method":"FRIENDSHIP_DAY","param":0,"species":196},{"method":"FRIENDSHIP_NIGHT","param":0,"species":197}],"friendship":70,"id":133,"learnset":{"address":3311520,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":45},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":226},{"level":42,"move_id":36}]},"tmhm_learnset":"00001E00AC530620","types":[0,0]},{"abilities":[11,0],"address":3300496,"base_stats":[130,65,60,65,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":134,"learnset":{"address":3311542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":55},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":62},{"level":42,"move_id":114},{"level":47,"move_id":151},{"level":52,"move_id":56}]},"tmhm_learnset":"03101E00AC537674","types":[11,11]},{"abilities":[10,0],"address":3300524,"base_stats":[65,65,60,130,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":135,"learnset":{"address":3311568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":84},{"level":23,"move_id":98},{"level":30,"move_id":24},{"level":36,"move_id":42},{"level":42,"move_id":86},{"level":47,"move_id":97},{"level":52,"move_id":87}]},"tmhm_learnset":"00401E02ADD34630","types":[13,13]},{"abilities":[18,0],"address":3300552,"base_stats":[65,130,60,65,95,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":136,"learnset":{"address":3311594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":52},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":83},{"level":42,"move_id":123},{"level":47,"move_id":43},{"level":52,"move_id":53}]},"tmhm_learnset":"00021E24AC534630","types":[10,10]},{"abilities":[36,0],"address":3300580,"base_stats":[65,60,70,40,85,75],"catch_rate":45,"evolutions":[{"method":"ITEM","param":218,"species":233}],"friendship":70,"id":137,"learnset":{"address":3311620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":159},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[33,75],"address":3300608,"base_stats":[35,40,100,35,90,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":139}],"friendship":70,"id":138,"learnset":{"address":3311646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":43,"move_id":321},{"level":49,"move_id":246},{"level":55,"move_id":56}]},"tmhm_learnset":"03903E5084133264","types":[5,11]},{"abilities":[33,75],"address":3300636,"base_stats":[70,60,125,55,115,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":139,"learnset":{"address":3311672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":1,"move_id":44},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":40,"move_id":131},{"level":46,"move_id":321},{"level":55,"move_id":246},{"level":65,"move_id":56}]},"tmhm_learnset":"03903E5084137264","types":[5,11]},{"abilities":[33,4],"address":3300664,"base_stats":[30,80,90,55,55,45],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":141}],"friendship":70,"id":140,"learnset":{"address":3311700,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":43,"move_id":319},{"level":49,"move_id":72},{"level":55,"move_id":246}]},"tmhm_learnset":"01903ED08C173264","types":[5,11]},{"abilities":[33,4],"address":3300692,"base_stats":[60,115,105,80,65,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":141,"learnset":{"address":3311726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":71},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":40,"move_id":163},{"level":46,"move_id":319},{"level":55,"move_id":72},{"level":65,"move_id":246}]},"tmhm_learnset":"03943ED0CC177264","types":[5,11]},{"abilities":[69,46],"address":3300720,"base_stats":[80,105,65,130,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":142,"learnset":{"address":3311754,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":8,"move_id":97},{"level":15,"move_id":44},{"level":22,"move_id":48},{"level":29,"move_id":246},{"level":36,"move_id":184},{"level":43,"move_id":36},{"level":50,"move_id":63}]},"tmhm_learnset":"00A87FF486534E32","types":[5,2]},{"abilities":[17,47],"address":3300748,"base_stats":[160,110,65,30,65,110],"catch_rate":25,"evolutions":[],"friendship":70,"id":143,"learnset":{"address":3311778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":133},{"level":10,"move_id":111},{"level":15,"move_id":187},{"level":19,"move_id":29},{"level":24,"move_id":281},{"level":28,"move_id":156},{"level":28,"move_id":173},{"level":33,"move_id":34},{"level":37,"move_id":335},{"level":42,"move_id":343},{"level":46,"move_id":205},{"level":51,"move_id":63}]},"tmhm_learnset":"00301E76F7B37625","types":[0,0]},{"abilities":[46,0],"address":3300776,"base_stats":[90,85,100,85,95,125],"catch_rate":3,"evolutions":[],"friendship":35,"id":144,"learnset":{"address":3311812,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":181},{"level":13,"move_id":54},{"level":25,"move_id":97},{"level":37,"move_id":170},{"level":49,"move_id":58},{"level":61,"move_id":115},{"level":73,"move_id":59},{"level":85,"move_id":329}]},"tmhm_learnset":"00884E9184137674","types":[15,2]},{"abilities":[46,0],"address":3300804,"base_stats":[90,90,85,100,125,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":145,"learnset":{"address":3311836,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":84},{"level":13,"move_id":86},{"level":25,"move_id":97},{"level":37,"move_id":197},{"level":49,"move_id":65},{"level":61,"move_id":268},{"level":73,"move_id":113},{"level":85,"move_id":87}]},"tmhm_learnset":"00C84E928593C630","types":[13,2]},{"abilities":[46,0],"address":3300832,"base_stats":[90,100,90,90,125,85],"catch_rate":3,"evolutions":[],"friendship":35,"id":146,"learnset":{"address":3311860,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":1,"move_id":52},{"level":13,"move_id":83},{"level":25,"move_id":97},{"level":37,"move_id":203},{"level":49,"move_id":53},{"level":61,"move_id":219},{"level":73,"move_id":257},{"level":85,"move_id":143}]},"tmhm_learnset":"008A4EB4841B4630","types":[10,2]},{"abilities":[61,0],"address":3300860,"base_stats":[41,64,45,50,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":148}],"friendship":35,"id":147,"learnset":{"address":3311884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":36,"move_id":97},{"level":43,"move_id":219},{"level":50,"move_id":200},{"level":57,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[61,0],"address":3300888,"base_stats":[61,84,65,70,70,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":149}],"friendship":35,"id":148,"learnset":{"address":3311910,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":56,"move_id":200},{"level":65,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[39,0],"address":3300916,"base_stats":[91,134,95,80,100,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":149,"learnset":{"address":3311936,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":55,"move_id":17},{"level":61,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BC5EF6C7DB7677","types":[16,2]},{"abilities":[46,0],"address":3300944,"base_stats":[106,110,90,130,154,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":150,"learnset":{"address":3311964,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":50},{"level":11,"move_id":112},{"level":22,"move_id":129},{"level":33,"move_id":244},{"level":44,"move_id":248},{"level":55,"move_id":54},{"level":66,"move_id":94},{"level":77,"move_id":133},{"level":88,"move_id":105},{"level":99,"move_id":219}]},"tmhm_learnset":"00E18FF7F7FBFEED","types":[14,14]},{"abilities":[28,0],"address":3300972,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":151,"learnset":{"address":3311992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":10,"move_id":144},{"level":20,"move_id":5},{"level":30,"move_id":118},{"level":40,"move_id":94},{"level":50,"move_id":246}]},"tmhm_learnset":"03FFFFFFFFFFFFFF","types":[14,14]},{"abilities":[65,0],"address":3301000,"base_stats":[45,49,65,45,49,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":153}],"friendship":70,"id":152,"learnset":{"address":3312012,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":22,"move_id":235},{"level":29,"move_id":34},{"level":36,"move_id":113},{"level":43,"move_id":219},{"level":50,"move_id":76}]},"tmhm_learnset":"00441E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301028,"base_stats":[60,62,80,60,63,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":154}],"friendship":70,"id":153,"learnset":{"address":3312038,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":39,"move_id":113},{"level":47,"move_id":219},{"level":55,"move_id":76}]},"tmhm_learnset":"00E41E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301056,"base_stats":[80,82,100,80,83,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":154,"learnset":{"address":3312064,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":41,"move_id":113},{"level":51,"move_id":219},{"level":61,"move_id":76}]},"tmhm_learnset":"00E41E01867DC720","types":[12,12]},{"abilities":[66,0],"address":3301084,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":14,"species":156}],"friendship":70,"id":155,"learnset":{"address":3312090,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":19,"move_id":98},{"level":27,"move_id":172},{"level":36,"move_id":129},{"level":46,"move_id":53}]},"tmhm_learnset":"00061EA48C110620","types":[10,10]},{"abilities":[66,0],"address":3301112,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":157}],"friendship":70,"id":156,"learnset":{"address":3312112,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":42,"move_id":129},{"level":54,"move_id":53}]},"tmhm_learnset":"00A61EA4CC110631","types":[10,10]},{"abilities":[66,0],"address":3301140,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":157,"learnset":{"address":3312134,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":1,"move_id":52},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":45,"move_id":129},{"level":60,"move_id":53}]},"tmhm_learnset":"00A61EA4CE114631","types":[10,10]},{"abilities":[67,0],"address":3301168,"base_stats":[50,65,64,43,44,48],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":18,"species":159}],"friendship":70,"id":158,"learnset":{"address":3312156,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":20,"move_id":44},{"level":27,"move_id":184},{"level":35,"move_id":163},{"level":43,"move_id":103},{"level":52,"move_id":56}]},"tmhm_learnset":"03141E80CC533265","types":[11,11]},{"abilities":[67,0],"address":3301196,"base_stats":[65,80,80,58,59,63],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":160}],"friendship":70,"id":159,"learnset":{"address":3312180,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":37,"move_id":163},{"level":45,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03B41E80CC533275","types":[11,11]},{"abilities":[67,0],"address":3301224,"base_stats":[85,105,100,78,79,83],"catch_rate":45,"evolutions":[],"friendship":70,"id":160,"learnset":{"address":3312204,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":1,"move_id":55},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":38,"move_id":163},{"level":47,"move_id":103},{"level":58,"move_id":56}]},"tmhm_learnset":"03B41E80CE537277","types":[11,11]},{"abilities":[50,51],"address":3301252,"base_stats":[35,46,34,20,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":15,"species":162}],"friendship":70,"id":161,"learnset":{"address":3312228,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":17,"move_id":270},{"level":24,"move_id":21},{"level":31,"move_id":266},{"level":40,"move_id":156},{"level":49,"move_id":133}]},"tmhm_learnset":"00143E06ECF31625","types":[0,0]},{"abilities":[50,51],"address":3301280,"base_stats":[85,76,64,90,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":162,"learnset":{"address":3312254,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":98},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":19,"move_id":270},{"level":28,"move_id":21},{"level":37,"move_id":266},{"level":48,"move_id":156},{"level":59,"move_id":133}]},"tmhm_learnset":"00B43E06EDF37625","types":[0,0]},{"abilities":[15,51],"address":3301308,"base_stats":[60,30,30,50,36,56],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":164}],"friendship":70,"id":163,"learnset":{"address":3312280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":22,"move_id":115},{"level":28,"move_id":36},{"level":34,"move_id":93},{"level":48,"move_id":138}]},"tmhm_learnset":"00487E81B4130620","types":[0,2]},{"abilities":[15,51],"address":3301336,"base_stats":[100,50,50,70,76,96],"catch_rate":90,"evolutions":[],"friendship":70,"id":164,"learnset":{"address":3312304,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":193},{"level":1,"move_id":64},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":25,"move_id":115},{"level":33,"move_id":36},{"level":41,"move_id":93},{"level":57,"move_id":138}]},"tmhm_learnset":"00487E81B4134620","types":[0,2]},{"abilities":[68,48],"address":3301364,"base_stats":[40,20,30,55,40,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":166}],"friendship":70,"id":165,"learnset":{"address":3312328,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":22,"move_id":113},{"level":22,"move_id":115},{"level":22,"move_id":219},{"level":29,"move_id":226},{"level":36,"move_id":129},{"level":43,"move_id":97},{"level":50,"move_id":38}]},"tmhm_learnset":"00403E81CC3D8621","types":[6,2]},{"abilities":[68,48],"address":3301392,"base_stats":[55,35,50,85,55,110],"catch_rate":90,"evolutions":[],"friendship":70,"id":166,"learnset":{"address":3312356,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":48},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":24,"move_id":113},{"level":24,"move_id":115},{"level":24,"move_id":219},{"level":33,"move_id":226},{"level":42,"move_id":129},{"level":51,"move_id":97},{"level":60,"move_id":38}]},"tmhm_learnset":"00403E81CC3DC621","types":[6,2]},{"abilities":[68,15],"address":3301420,"base_stats":[40,60,40,30,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":168}],"friendship":70,"id":167,"learnset":{"address":3312384,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":23,"move_id":141},{"level":30,"move_id":154},{"level":37,"move_id":169},{"level":45,"move_id":97},{"level":53,"move_id":94}]},"tmhm_learnset":"00403E089C350620","types":[6,3]},{"abilities":[68,15],"address":3301448,"base_stats":[70,90,70,40,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":168,"learnset":{"address":3312410,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":1,"move_id":184},{"level":1,"move_id":132},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":25,"move_id":141},{"level":34,"move_id":154},{"level":43,"move_id":169},{"level":53,"move_id":97},{"level":63,"move_id":94}]},"tmhm_learnset":"00403E089C354620","types":[6,3]},{"abilities":[39,0],"address":3301476,"base_stats":[85,90,80,130,70,80],"catch_rate":90,"evolutions":[],"friendship":70,"id":169,"learnset":{"address":3312436,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00097F88A4174E20","types":[3,2]},{"abilities":[10,35],"address":3301504,"base_stats":[75,38,38,67,56,56],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":27,"species":171}],"friendship":70,"id":170,"learnset":{"address":3312464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":29,"move_id":109},{"level":37,"move_id":36},{"level":41,"move_id":56},{"level":49,"move_id":268}]},"tmhm_learnset":"03501E0285933264","types":[11,13]},{"abilities":[10,35],"address":3301532,"base_stats":[125,58,58,67,76,76],"catch_rate":75,"evolutions":[],"friendship":70,"id":171,"learnset":{"address":3312490,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":1,"move_id":48},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":32,"move_id":109},{"level":43,"move_id":36},{"level":50,"move_id":56},{"level":61,"move_id":268}]},"tmhm_learnset":"03501E0285937264","types":[11,13]},{"abilities":[9,0],"address":3301560,"base_stats":[20,40,15,60,35,35],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":25}],"friendship":70,"id":172,"learnset":{"address":3312516,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":204},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":186}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[56,0],"address":3301588,"base_stats":[50,25,28,15,45,55],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":35}],"friendship":140,"id":173,"learnset":{"address":3312532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":204},{"level":4,"move_id":227},{"level":8,"move_id":47},{"level":13,"move_id":186}]},"tmhm_learnset":"00401E27BC7B8624","types":[0,0]},{"abilities":[56,0],"address":3301616,"base_stats":[90,30,15,15,40,20],"catch_rate":170,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":39}],"friendship":70,"id":174,"learnset":{"address":3312548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":1,"move_id":204},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":186}]},"tmhm_learnset":"00401E27BC3B8624","types":[0,0]},{"abilities":[55,32],"address":3301644,"base_stats":[35,20,65,20,40,65],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":176}],"friendship":70,"id":175,"learnset":{"address":3312564,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C01E27B43B8624","types":[0,0]},{"abilities":[55,32],"address":3301672,"base_stats":[55,40,85,40,80,105],"catch_rate":75,"evolutions":[],"friendship":70,"id":176,"learnset":{"address":3312590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C85EA7F43BC625","types":[0,2]},{"abilities":[28,48],"address":3301700,"base_stats":[40,50,45,70,70,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":178}],"friendship":70,"id":177,"learnset":{"address":3312616,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":30,"move_id":273},{"level":30,"move_id":248},{"level":40,"move_id":109},{"level":50,"move_id":94}]},"tmhm_learnset":"0040FE81B4378628","types":[14,2]},{"abilities":[28,48],"address":3301728,"base_stats":[65,75,70,95,95,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":178,"learnset":{"address":3312638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":35,"move_id":273},{"level":35,"move_id":248},{"level":50,"move_id":109},{"level":65,"move_id":94}]},"tmhm_learnset":"0048FE81B437C628","types":[14,2]},{"abilities":[9,0],"address":3301756,"base_stats":[55,40,40,35,65,45],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":15,"species":180}],"friendship":70,"id":179,"learnset":{"address":3312660,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":84},{"level":16,"move_id":86},{"level":23,"move_id":178},{"level":30,"move_id":113},{"level":37,"move_id":87}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[9,0],"address":3301784,"base_stats":[70,55,55,45,80,60],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":181}],"friendship":70,"id":180,"learnset":{"address":3312680,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":36,"move_id":113},{"level":45,"move_id":87}]},"tmhm_learnset":"00E01E02C5D38221","types":[13,13]},{"abilities":[9,0],"address":3301812,"base_stats":[90,75,75,55,115,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":181,"learnset":{"address":3312700,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":1,"move_id":86},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":30,"move_id":9},{"level":42,"move_id":113},{"level":57,"move_id":87}]},"tmhm_learnset":"00E01E02C5D3C221","types":[13,13]},{"abilities":[34,0],"address":3301840,"base_stats":[75,80,85,50,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":182,"learnset":{"address":3312722,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":78},{"level":1,"move_id":345},{"level":44,"move_id":80},{"level":55,"move_id":76}]},"tmhm_learnset":"00441E08843D4720","types":[12,12]},{"abilities":[47,37],"address":3301868,"base_stats":[70,20,50,40,20,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":18,"species":184}],"friendship":70,"id":183,"learnset":{"address":3312736,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":21,"move_id":61},{"level":28,"move_id":38},{"level":36,"move_id":240},{"level":45,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[47,37],"address":3301896,"base_stats":[100,50,80,50,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":184,"learnset":{"address":3312762,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":39},{"level":1,"move_id":55},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":24,"move_id":61},{"level":34,"move_id":38},{"level":45,"move_id":240},{"level":57,"move_id":56}]},"tmhm_learnset":"03B01E00CC537265","types":[11,11]},{"abilities":[5,69],"address":3301924,"base_stats":[70,100,115,30,30,65],"catch_rate":65,"evolutions":[],"friendship":70,"id":185,"learnset":{"address":3312788,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":102},{"level":9,"move_id":175},{"level":17,"move_id":67},{"level":25,"move_id":157},{"level":33,"move_id":335},{"level":41,"move_id":185},{"level":49,"move_id":21},{"level":57,"move_id":38}]},"tmhm_learnset":"00A03E50CE110E29","types":[5,5]},{"abilities":[11,6],"address":3301952,"base_stats":[90,75,75,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":186,"learnset":{"address":3312812,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":195},{"level":35,"move_id":195},{"level":51,"move_id":207}]},"tmhm_learnset":"03B03E00DE137265","types":[11,11]},{"abilities":[34,0],"address":3301980,"base_stats":[35,35,40,50,35,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":188}],"friendship":70,"id":187,"learnset":{"address":3312826,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":20,"move_id":73},{"level":25,"move_id":178},{"level":30,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302008,"base_stats":[55,45,50,80,45,65],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":27,"species":189}],"friendship":70,"id":188,"learnset":{"address":3312854,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":29,"move_id":178},{"level":36,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302036,"base_stats":[75,55,70,110,55,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":189,"learnset":{"address":3312882,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":33,"move_id":178},{"level":44,"move_id":72}]},"tmhm_learnset":"00401E8084354720","types":[12,2]},{"abilities":[50,53],"address":3302064,"base_stats":[55,70,55,85,40,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":190,"learnset":{"address":3312910,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":6,"move_id":28},{"level":13,"move_id":310},{"level":18,"move_id":226},{"level":25,"move_id":321},{"level":31,"move_id":154},{"level":38,"move_id":129},{"level":43,"move_id":103},{"level":50,"move_id":97}]},"tmhm_learnset":"00A53E82EDF30E25","types":[0,0]},{"abilities":[34,0],"address":3302092,"base_stats":[30,30,30,30,30,30],"catch_rate":235,"evolutions":[{"method":"ITEM","param":93,"species":192}],"friendship":70,"id":191,"learnset":{"address":3312936,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":6,"move_id":74},{"level":13,"move_id":72},{"level":18,"move_id":275},{"level":25,"move_id":283},{"level":30,"move_id":241},{"level":37,"move_id":235},{"level":42,"move_id":202}]},"tmhm_learnset":"00441E08843D8720","types":[12,12]},{"abilities":[34,0],"address":3302120,"base_stats":[75,75,55,30,105,85],"catch_rate":120,"evolutions":[],"friendship":70,"id":192,"learnset":{"address":3312960,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":1},{"level":6,"move_id":74},{"level":13,"move_id":75},{"level":18,"move_id":275},{"level":25,"move_id":331},{"level":30,"move_id":241},{"level":37,"move_id":80},{"level":42,"move_id":76}]},"tmhm_learnset":"00441E08843DC720","types":[12,12]},{"abilities":[3,14],"address":3302148,"base_stats":[65,65,45,95,75,45],"catch_rate":75,"evolutions":[],"friendship":70,"id":193,"learnset":{"address":3312984,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":193},{"level":7,"move_id":98},{"level":13,"move_id":104},{"level":19,"move_id":49},{"level":25,"move_id":197},{"level":31,"move_id":48},{"level":37,"move_id":253},{"level":43,"move_id":17},{"level":49,"move_id":103}]},"tmhm_learnset":"00407E80B4350620","types":[6,2]},{"abilities":[6,11],"address":3302176,"base_stats":[55,45,45,15,25,25],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":195}],"friendship":70,"id":194,"learnset":{"address":3313010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":21,"move_id":133},{"level":31,"move_id":281},{"level":36,"move_id":89},{"level":41,"move_id":240},{"level":51,"move_id":54},{"level":51,"move_id":114}]},"tmhm_learnset":"03D01E188E533264","types":[11,4]},{"abilities":[6,11],"address":3302204,"base_stats":[95,85,85,35,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":195,"learnset":{"address":3313036,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":23,"move_id":133},{"level":35,"move_id":281},{"level":42,"move_id":89},{"level":49,"move_id":240},{"level":61,"move_id":54},{"level":61,"move_id":114}]},"tmhm_learnset":"03F01E58CE537265","types":[11,4]},{"abilities":[28,0],"address":3302232,"base_stats":[65,65,60,110,130,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":196,"learnset":{"address":3313062,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":93},{"level":23,"move_id":98},{"level":30,"move_id":129},{"level":36,"move_id":60},{"level":42,"move_id":244},{"level":47,"move_id":94},{"level":52,"move_id":234}]},"tmhm_learnset":"00449E01BC53C628","types":[14,14]},{"abilities":[28,0],"address":3302260,"base_stats":[95,65,110,65,60,130],"catch_rate":45,"evolutions":[],"friendship":35,"id":197,"learnset":{"address":3313088,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":228},{"level":23,"move_id":98},{"level":30,"move_id":109},{"level":36,"move_id":185},{"level":42,"move_id":212},{"level":47,"move_id":103},{"level":52,"move_id":236}]},"tmhm_learnset":"00451F00BC534E20","types":[17,17]},{"abilities":[15,0],"address":3302288,"base_stats":[60,85,42,91,85,42],"catch_rate":30,"evolutions":[],"friendship":35,"id":198,"learnset":{"address":3313114,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":9,"move_id":310},{"level":14,"move_id":228},{"level":22,"move_id":114},{"level":27,"move_id":101},{"level":35,"move_id":185},{"level":40,"move_id":269},{"level":48,"move_id":212}]},"tmhm_learnset":"00097F80A4130E28","types":[17,2]},{"abilities":[12,20],"address":3302316,"base_stats":[95,75,80,30,100,110],"catch_rate":70,"evolutions":[],"friendship":70,"id":199,"learnset":{"address":3313138,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":207},{"level":48,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[26,0],"address":3302344,"base_stats":[60,60,60,85,85,85],"catch_rate":45,"evolutions":[],"friendship":35,"id":200,"learnset":{"address":3313162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":149},{"level":6,"move_id":180},{"level":11,"move_id":310},{"level":17,"move_id":109},{"level":23,"move_id":212},{"level":30,"move_id":60},{"level":37,"move_id":220},{"level":45,"move_id":195},{"level":53,"move_id":288}]},"tmhm_learnset":"0041BF82B5930E28","types":[7,7]},{"abilities":[26,0],"address":3302372,"base_stats":[48,72,48,48,72,48],"catch_rate":225,"evolutions":[],"friendship":70,"id":201,"learnset":{"address":3313188,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":237}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[23,0],"address":3302400,"base_stats":[190,33,58,33,33,58],"catch_rate":45,"evolutions":[],"friendship":70,"id":202,"learnset":{"address":3313198,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":243},{"level":1,"move_id":219},{"level":1,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[39,48],"address":3302428,"base_stats":[70,80,65,85,90,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":203,"learnset":{"address":3313208,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":7,"move_id":310},{"level":13,"move_id":93},{"level":19,"move_id":23},{"level":25,"move_id":316},{"level":31,"move_id":97},{"level":37,"move_id":226},{"level":43,"move_id":60},{"level":49,"move_id":242}]},"tmhm_learnset":"00E0BE03B7D38628","types":[0,14]},{"abilities":[5,0],"address":3302456,"base_stats":[50,65,90,15,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":205}],"friendship":70,"id":204,"learnset":{"address":3313234,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":36,"move_id":153},{"level":43,"move_id":191},{"level":50,"move_id":38}]},"tmhm_learnset":"00A01E118E358620","types":[6,6]},{"abilities":[5,0],"address":3302484,"base_stats":[75,90,140,40,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":205,"learnset":{"address":3313258,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":1,"move_id":120},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":39,"move_id":153},{"level":49,"move_id":191},{"level":59,"move_id":38}]},"tmhm_learnset":"00A01E118E35C620","types":[6,8]},{"abilities":[32,50],"address":3302512,"base_stats":[100,70,70,45,65,65],"catch_rate":190,"evolutions":[],"friendship":70,"id":206,"learnset":{"address":3313282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":4,"move_id":111},{"level":11,"move_id":281},{"level":14,"move_id":137},{"level":21,"move_id":180},{"level":24,"move_id":228},{"level":31,"move_id":103},{"level":34,"move_id":36},{"level":41,"move_id":283}]},"tmhm_learnset":"00A03E66AFF3362C","types":[0,0]},{"abilities":[52,8],"address":3302540,"base_stats":[65,75,105,85,35,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":207,"learnset":{"address":3313308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":28},{"level":13,"move_id":106},{"level":20,"move_id":98},{"level":28,"move_id":185},{"level":36,"move_id":163},{"level":44,"move_id":103},{"level":52,"move_id":12}]},"tmhm_learnset":"00A47ED88E530620","types":[4,2]},{"abilities":[69,5],"address":3302568,"base_stats":[75,85,200,30,55,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":208,"learnset":{"address":3313332,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":242},{"level":57,"move_id":38}]},"tmhm_learnset":"00A41F508E514E30","types":[8,4]},{"abilities":[22,50],"address":3302596,"base_stats":[60,80,50,30,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":23,"species":210}],"friendship":70,"id":209,"learnset":{"address":3313360,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":26,"move_id":46},{"level":34,"move_id":99},{"level":43,"move_id":36},{"level":53,"move_id":242}]},"tmhm_learnset":"00A23F2EEFB30EB5","types":[0,0]},{"abilities":[22,22],"address":3302624,"base_stats":[90,120,75,45,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":210,"learnset":{"address":3313386,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":28,"move_id":46},{"level":38,"move_id":99},{"level":49,"move_id":36},{"level":61,"move_id":242}]},"tmhm_learnset":"00A23F6EEFF34EB5","types":[0,0]},{"abilities":[38,33],"address":3302652,"base_stats":[65,95,75,85,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":211,"learnset":{"address":3313412,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":191},{"level":1,"move_id":33},{"level":1,"move_id":40},{"level":10,"move_id":106},{"level":10,"move_id":107},{"level":19,"move_id":55},{"level":28,"move_id":42},{"level":37,"move_id":36},{"level":46,"move_id":56}]},"tmhm_learnset":"03101E0AA4133264","types":[11,3]},{"abilities":[68,0],"address":3302680,"base_stats":[70,130,100,65,55,80],"catch_rate":25,"evolutions":[],"friendship":70,"id":212,"learnset":{"address":3313434,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":232},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00A47E9084134620","types":[6,8]},{"abilities":[5,0],"address":3302708,"base_stats":[20,10,230,5,10,230],"catch_rate":190,"evolutions":[],"friendship":70,"id":213,"learnset":{"address":3313462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":9,"move_id":35},{"level":14,"move_id":227},{"level":23,"move_id":219},{"level":28,"move_id":117},{"level":37,"move_id":156}]},"tmhm_learnset":"00E01E588E190620","types":[6,5]},{"abilities":[68,62],"address":3302736,"base_stats":[80,125,75,85,40,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":214,"learnset":{"address":3313482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":30},{"level":11,"move_id":203},{"level":17,"move_id":31},{"level":23,"move_id":280},{"level":30,"move_id":68},{"level":37,"move_id":36},{"level":45,"move_id":179},{"level":53,"move_id":224}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,1]},{"abilities":[39,51],"address":3302764,"base_stats":[55,95,55,115,35,75],"catch_rate":60,"evolutions":[],"friendship":35,"id":215,"learnset":{"address":3313508,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":269},{"level":8,"move_id":98},{"level":15,"move_id":103},{"level":22,"move_id":185},{"level":29,"move_id":154},{"level":36,"move_id":97},{"level":43,"move_id":196},{"level":50,"move_id":163},{"level":57,"move_id":251},{"level":64,"move_id":232}]},"tmhm_learnset":"00B53F80EC533E69","types":[17,15]},{"abilities":[53,0],"address":3302792,"base_stats":[60,80,50,40,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":217}],"friendship":70,"id":216,"learnset":{"address":3313536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43F80CE130EB1","types":[0,0]},{"abilities":[62,0],"address":3302820,"base_stats":[90,130,75,55,75,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":217,"learnset":{"address":3313562,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":122},{"level":1,"move_id":154},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43FC0CE134EB1","types":[0,0]},{"abilities":[40,49],"address":3302848,"base_stats":[40,40,40,20,70,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":219}],"friendship":70,"id":218,"learnset":{"address":3313588,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":43,"move_id":157},{"level":50,"move_id":34}]},"tmhm_learnset":"00821E2584118620","types":[10,10]},{"abilities":[40,49],"address":3302876,"base_stats":[50,50,120,30,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":219,"learnset":{"address":3313612,"moves":[{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":1,"move_id":52},{"level":1,"move_id":88},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":48,"move_id":157},{"level":60,"move_id":34}]},"tmhm_learnset":"00A21E758611C620","types":[10,5]},{"abilities":[12,0],"address":3302904,"base_stats":[50,50,40,50,30,30],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":221}],"friendship":70,"id":220,"learnset":{"address":3313636,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":316},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":37,"move_id":54},{"level":46,"move_id":59},{"level":55,"move_id":133}]},"tmhm_learnset":"00A01E518E13B270","types":[15,4]},{"abilities":[12,0],"address":3302932,"base_stats":[100,100,80,50,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":221,"learnset":{"address":3313658,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":316},{"level":1,"move_id":181},{"level":1,"move_id":203},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":33,"move_id":31},{"level":42,"move_id":54},{"level":56,"move_id":59},{"level":70,"move_id":133}]},"tmhm_learnset":"00A01E518E13F270","types":[15,4]},{"abilities":[55,30],"address":3302960,"base_stats":[55,55,85,35,65,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":222,"learnset":{"address":3313682,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":106},{"level":12,"move_id":145},{"level":17,"move_id":105},{"level":17,"move_id":287},{"level":23,"move_id":61},{"level":28,"move_id":131},{"level":34,"move_id":350},{"level":39,"move_id":243},{"level":45,"move_id":246}]},"tmhm_learnset":"00B01E51BE1BB66C","types":[11,5]},{"abilities":[55,0],"address":3302988,"base_stats":[35,65,35,65,65,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":224}],"friendship":70,"id":223,"learnset":{"address":3313710,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":199},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":33,"move_id":116},{"level":44,"move_id":58},{"level":55,"move_id":63}]},"tmhm_learnset":"03103E2494137624","types":[11,11]},{"abilities":[21,0],"address":3303016,"base_stats":[75,105,75,45,105,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":224,"learnset":{"address":3313734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":132},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":25,"move_id":190},{"level":38,"move_id":116},{"level":54,"move_id":58},{"level":70,"move_id":63}]},"tmhm_learnset":"03103E2C94137724","types":[11,11]},{"abilities":[72,55],"address":3303044,"base_stats":[45,55,45,75,65,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":225,"learnset":{"address":3313760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":217}]},"tmhm_learnset":"00083E8084133265","types":[15,2]},{"abilities":[33,11],"address":3303072,"base_stats":[65,40,70,70,80,140],"catch_rate":25,"evolutions":[],"friendship":70,"id":226,"learnset":{"address":3313770,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":145},{"level":8,"move_id":48},{"level":15,"move_id":61},{"level":22,"move_id":36},{"level":29,"move_id":97},{"level":36,"move_id":17},{"level":43,"move_id":352},{"level":50,"move_id":109}]},"tmhm_learnset":"03101E8086133264","types":[11,2]},{"abilities":[51,5],"address":3303100,"base_stats":[65,80,140,70,40,70],"catch_rate":25,"evolutions":[],"friendship":70,"id":227,"learnset":{"address":3313794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":10,"move_id":28},{"level":13,"move_id":129},{"level":16,"move_id":97},{"level":26,"move_id":31},{"level":29,"move_id":314},{"level":32,"move_id":211},{"level":42,"move_id":191},{"level":45,"move_id":319}]},"tmhm_learnset":"008C7F9084110E30","types":[8,2]},{"abilities":[48,18],"address":3303128,"base_stats":[45,60,30,65,80,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":24,"species":229}],"friendship":35,"id":228,"learnset":{"address":3313820,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":25,"move_id":44},{"level":31,"move_id":316},{"level":37,"move_id":185},{"level":43,"move_id":53},{"level":49,"move_id":242}]},"tmhm_learnset":"00833F2CA4710E30","types":[17,10]},{"abilities":[48,18],"address":3303156,"base_stats":[75,90,50,95,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":229,"learnset":{"address":3313846,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":1,"move_id":336},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":27,"move_id":44},{"level":35,"move_id":316},{"level":43,"move_id":185},{"level":51,"move_id":53},{"level":59,"move_id":242}]},"tmhm_learnset":"00A33F2CA4714E30","types":[17,10]},{"abilities":[33,0],"address":3303184,"base_stats":[75,95,95,85,95,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":230,"learnset":{"address":3313872,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,16]},{"abilities":[53,0],"address":3303212,"base_stats":[90,60,60,40,40,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":25,"species":232}],"friendship":70,"id":231,"learnset":{"address":3313896,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":36},{"level":33,"move_id":205},{"level":41,"move_id":203},{"level":49,"move_id":38}]},"tmhm_learnset":"00A01E5086510630","types":[4,4]},{"abilities":[5,0],"address":3303240,"base_stats":[90,120,120,50,60,60],"catch_rate":60,"evolutions":[],"friendship":70,"id":232,"learnset":{"address":3313918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":30},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":31},{"level":33,"move_id":205},{"level":41,"move_id":229},{"level":49,"move_id":89}]},"tmhm_learnset":"00A01E5086514630","types":[4,4]},{"abilities":[36,0],"address":3303268,"base_stats":[85,80,90,60,105,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":233,"learnset":{"address":3313940,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":111},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[22,0],"address":3303296,"base_stats":[73,95,62,85,85,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":234,"learnset":{"address":3313966,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":43},{"level":13,"move_id":310},{"level":19,"move_id":95},{"level":25,"move_id":23},{"level":31,"move_id":28},{"level":37,"move_id":36},{"level":43,"move_id":109},{"level":49,"move_id":347}]},"tmhm_learnset":"0040BE03B7F38638","types":[0,0]},{"abilities":[20,0],"address":3303324,"base_stats":[55,20,35,75,20,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":235,"learnset":{"address":3313992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":166},{"level":11,"move_id":166},{"level":21,"move_id":166},{"level":31,"move_id":166},{"level":41,"move_id":166},{"level":51,"move_id":166},{"level":61,"move_id":166},{"level":71,"move_id":166},{"level":81,"move_id":166},{"level":91,"move_id":166}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[62,0],"address":3303352,"base_stats":[35,35,35,35,35,35],"catch_rate":75,"evolutions":[{"method":"LEVEL_ATK_LT_DEF","param":20,"species":107},{"method":"LEVEL_ATK_GT_DEF","param":20,"species":106},{"method":"LEVEL_ATK_EQ_DEF","param":20,"species":237}],"friendship":70,"id":236,"learnset":{"address":3314020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"00A03E00C61306A0","types":[1,1]},{"abilities":[22,0],"address":3303380,"base_stats":[50,95,95,70,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":237,"learnset":{"address":3314030,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":27},{"level":7,"move_id":116},{"level":13,"move_id":228},{"level":19,"move_id":98},{"level":20,"move_id":167},{"level":25,"move_id":229},{"level":31,"move_id":68},{"level":37,"move_id":97},{"level":43,"move_id":197},{"level":49,"move_id":283}]},"tmhm_learnset":"00A03E10CE1306A0","types":[1,1]},{"abilities":[12,0],"address":3303408,"base_stats":[45,30,15,65,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":124}],"friendship":70,"id":238,"learnset":{"address":3314058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":9,"move_id":186},{"level":13,"move_id":181},{"level":21,"move_id":93},{"level":25,"move_id":47},{"level":33,"move_id":212},{"level":37,"move_id":313},{"level":45,"move_id":94},{"level":49,"move_id":195},{"level":57,"move_id":59}]},"tmhm_learnset":"0040BE01B413B26C","types":[15,14]},{"abilities":[9,0],"address":3303436,"base_stats":[45,63,37,95,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":125}],"friendship":70,"id":239,"learnset":{"address":3314086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":33,"move_id":103},{"level":41,"move_id":85},{"level":49,"move_id":87}]},"tmhm_learnset":"00C03E02D5938221","types":[13,13]},{"abilities":[49,0],"address":3303464,"base_stats":[45,75,37,83,70,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":126}],"friendship":70,"id":240,"learnset":{"address":3314108,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":31,"move_id":241},{"level":37,"move_id":53},{"level":43,"move_id":109},{"level":49,"move_id":126}]},"tmhm_learnset":"00803E24D4510621","types":[10,10]},{"abilities":[47,0],"address":3303492,"base_stats":[95,80,105,100,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":241,"learnset":{"address":3314134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":8,"move_id":111},{"level":13,"move_id":23},{"level":19,"move_id":208},{"level":26,"move_id":117},{"level":34,"move_id":205},{"level":43,"move_id":34},{"level":53,"move_id":215}]},"tmhm_learnset":"00B01E52E7F37625","types":[0,0]},{"abilities":[30,32],"address":3303520,"base_stats":[255,10,10,55,75,135],"catch_rate":30,"evolutions":[],"friendship":140,"id":242,"learnset":{"address":3314160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":4,"move_id":39},{"level":7,"move_id":287},{"level":10,"move_id":135},{"level":13,"move_id":3},{"level":18,"move_id":107},{"level":23,"move_id":47},{"level":28,"move_id":121},{"level":33,"move_id":111},{"level":40,"move_id":113},{"level":47,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[46,0],"address":3303548,"base_stats":[90,85,75,115,115,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":243,"learnset":{"address":3314190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":84},{"level":21,"move_id":46},{"level":31,"move_id":98},{"level":41,"move_id":209},{"level":51,"move_id":115},{"level":61,"move_id":242},{"level":71,"move_id":87},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E138DD34638","types":[13,13]},{"abilities":[46,0],"address":3303576,"base_stats":[115,115,85,100,90,75],"catch_rate":3,"evolutions":[],"friendship":35,"id":244,"learnset":{"address":3314216,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":52},{"level":21,"move_id":46},{"level":31,"move_id":83},{"level":41,"move_id":23},{"level":51,"move_id":53},{"level":61,"move_id":207},{"level":71,"move_id":126},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E358C734638","types":[10,10]},{"abilities":[46,0],"address":3303604,"base_stats":[100,75,115,85,90,115],"catch_rate":3,"evolutions":[],"friendship":35,"id":245,"learnset":{"address":3314242,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":61},{"level":21,"move_id":240},{"level":31,"move_id":16},{"level":41,"move_id":62},{"level":51,"move_id":54},{"level":61,"move_id":243},{"level":71,"move_id":56},{"level":81,"move_id":347}]},"tmhm_learnset":"03940E118C53767C","types":[11,11]},{"abilities":[62,0],"address":3303632,"base_stats":[50,64,50,41,45,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":247}],"friendship":35,"id":246,"learnset":{"address":3314268,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":36,"move_id":184},{"level":43,"move_id":242},{"level":50,"move_id":89},{"level":57,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[61,0],"address":3303660,"base_stats":[70,84,70,51,65,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":248}],"friendship":35,"id":247,"learnset":{"address":3314294,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":56,"move_id":89},{"level":65,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[45,0],"address":3303688,"base_stats":[100,134,110,61,95,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":248,"learnset":{"address":3314320,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":61,"move_id":89},{"level":75,"move_id":63}]},"tmhm_learnset":"00B41FF6CFD37E37","types":[5,17]},{"abilities":[46,0],"address":3303716,"base_stats":[106,90,130,110,90,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":249,"learnset":{"address":3314346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":56},{"level":55,"move_id":240},{"level":66,"move_id":129},{"level":77,"move_id":177},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"03B8CE93B7DFF67C","types":[14,2]},{"abilities":[46,0],"address":3303744,"base_stats":[106,130,90,90,110,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":250,"learnset":{"address":3314374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":126},{"level":55,"move_id":241},{"level":66,"move_id":129},{"level":77,"move_id":221},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"00EA4EB7B7BFC638","types":[10,2]},{"abilities":[30,0],"address":3303772,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":251,"learnset":{"address":3314402,"moves":[{"level":1,"move_id":73},{"level":1,"move_id":93},{"level":1,"move_id":105},{"level":1,"move_id":215},{"level":10,"move_id":219},{"level":20,"move_id":246},{"level":30,"move_id":248},{"level":40,"move_id":226},{"level":50,"move_id":195}]},"tmhm_learnset":"00448E93B43FC62C","types":[14,12]},{"abilities":[0,0],"address":3303800,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":252,"learnset":{"address":3314422,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303828,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":253,"learnset":{"address":3314432,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303856,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":254,"learnset":{"address":3314442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303884,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":255,"learnset":{"address":3314452,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303912,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":256,"learnset":{"address":3314462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303940,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":257,"learnset":{"address":3314472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303968,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":258,"learnset":{"address":3314482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303996,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":259,"learnset":{"address":3314492,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304024,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":260,"learnset":{"address":3314502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304052,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":261,"learnset":{"address":3314512,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304080,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":262,"learnset":{"address":3314522,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304108,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":263,"learnset":{"address":3314532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304136,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":264,"learnset":{"address":3314542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304164,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":265,"learnset":{"address":3314552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304192,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":266,"learnset":{"address":3314562,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304220,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":267,"learnset":{"address":3314572,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304248,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":268,"learnset":{"address":3314582,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304276,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":269,"learnset":{"address":3314592,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304304,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":270,"learnset":{"address":3314602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304332,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":271,"learnset":{"address":3314612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304360,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":272,"learnset":{"address":3314622,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304388,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":273,"learnset":{"address":3314632,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304416,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":274,"learnset":{"address":3314642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304444,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":275,"learnset":{"address":3314652,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304472,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":276,"learnset":{"address":3314662,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3304500,"base_stats":[40,45,35,70,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":278}],"friendship":70,"id":277,"learnset":{"address":3314672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":228},{"level":21,"move_id":103},{"level":26,"move_id":72},{"level":31,"move_id":97},{"level":36,"move_id":21},{"level":41,"move_id":197},{"level":46,"move_id":202}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304528,"base_stats":[50,65,45,95,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":279}],"friendship":70,"id":278,"learnset":{"address":3314700,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":41,"move_id":21},{"level":47,"move_id":197},{"level":53,"move_id":206}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304556,"base_stats":[70,85,65,120,105,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":279,"learnset":{"address":3314730,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":43,"move_id":21},{"level":51,"move_id":197},{"level":59,"move_id":206}]},"tmhm_learnset":"00E41EC0CE7D4733","types":[12,12]},{"abilities":[66,0],"address":3304584,"base_stats":[45,60,40,45,70,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":281}],"friendship":70,"id":280,"learnset":{"address":3314760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":116},{"level":10,"move_id":52},{"level":16,"move_id":64},{"level":19,"move_id":28},{"level":25,"move_id":83},{"level":28,"move_id":98},{"level":34,"move_id":163},{"level":37,"move_id":119},{"level":43,"move_id":53}]},"tmhm_learnset":"00A61EE48C110620","types":[10,10]},{"abilities":[66,0],"address":3304612,"base_stats":[60,85,60,55,85,60],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":282}],"friendship":70,"id":281,"learnset":{"address":3314788,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":39,"move_id":163},{"level":43,"move_id":119},{"level":50,"move_id":327}]},"tmhm_learnset":"00A61EE4CC1106A1","types":[10,1]},{"abilities":[66,0],"address":3304640,"base_stats":[80,120,70,80,110,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":282,"learnset":{"address":3314818,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":36,"move_id":299},{"level":42,"move_id":163},{"level":49,"move_id":119},{"level":59,"move_id":327}]},"tmhm_learnset":"00A61EE4CE1146B1","types":[10,1]},{"abilities":[67,0],"address":3304668,"base_stats":[50,70,50,40,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":284}],"friendship":70,"id":283,"learnset":{"address":3314852,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":19,"move_id":193},{"level":24,"move_id":300},{"level":28,"move_id":36},{"level":33,"move_id":250},{"level":37,"move_id":182},{"level":42,"move_id":56},{"level":46,"move_id":283}]},"tmhm_learnset":"03B01E408C533264","types":[11,11]},{"abilities":[67,0],"address":3304696,"base_stats":[70,85,70,50,60,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":285}],"friendship":70,"id":284,"learnset":{"address":3314882,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":37,"move_id":330},{"level":42,"move_id":182},{"level":46,"move_id":89},{"level":53,"move_id":283}]},"tmhm_learnset":"03B01E408E533264","types":[11,4]},{"abilities":[67,0],"address":3304724,"base_stats":[100,110,90,60,85,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":285,"learnset":{"address":3314914,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":39,"move_id":330},{"level":46,"move_id":182},{"level":52,"move_id":89},{"level":61,"move_id":283}]},"tmhm_learnset":"03B01E40CE537275","types":[11,4]},{"abilities":[50,0],"address":3304752,"base_stats":[35,55,35,35,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":287}],"friendship":70,"id":286,"learnset":{"address":3314946,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":21,"move_id":46},{"level":25,"move_id":207},{"level":29,"move_id":184},{"level":33,"move_id":36},{"level":37,"move_id":269},{"level":41,"move_id":242},{"level":45,"move_id":168}]},"tmhm_learnset":"00813F00AC530E30","types":[17,17]},{"abilities":[22,0],"address":3304780,"base_stats":[70,90,70,70,60,60],"catch_rate":127,"evolutions":[],"friendship":70,"id":287,"learnset":{"address":3314978,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":336},{"level":1,"move_id":28},{"level":1,"move_id":44},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":22,"move_id":46},{"level":27,"move_id":207},{"level":32,"move_id":184},{"level":37,"move_id":36},{"level":42,"move_id":269},{"level":47,"move_id":242},{"level":52,"move_id":168}]},"tmhm_learnset":"00A13F00AC534E30","types":[17,17]},{"abilities":[53,0],"address":3304808,"base_stats":[38,30,41,60,30,41],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":289}],"friendship":70,"id":288,"learnset":{"address":3315010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":21,"move_id":300},{"level":25,"move_id":42},{"level":29,"move_id":343},{"level":33,"move_id":175},{"level":37,"move_id":156},{"level":41,"move_id":187}]},"tmhm_learnset":"00943E02ADD33624","types":[0,0]},{"abilities":[53,0],"address":3304836,"base_stats":[78,70,61,100,50,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":289,"learnset":{"address":3315040,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":23,"move_id":300},{"level":29,"move_id":154},{"level":35,"move_id":343},{"level":41,"move_id":163},{"level":47,"move_id":156},{"level":53,"move_id":187}]},"tmhm_learnset":"00B43E02ADD37634","types":[0,0]},{"abilities":[19,0],"address":3304864,"base_stats":[45,45,35,20,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_SILCOON","param":7,"species":291},{"method":"LEVEL_CASCOON","param":7,"species":293}],"friendship":70,"id":290,"learnset":{"address":3315070,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81},{"level":5,"move_id":40}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3304892,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":292}],"friendship":70,"id":291,"learnset":{"address":3315082,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[68,0],"address":3304920,"base_stats":[60,70,50,65,90,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":292,"learnset":{"address":3315094,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":10,"move_id":71},{"level":13,"move_id":16},{"level":17,"move_id":78},{"level":20,"move_id":234},{"level":24,"move_id":72},{"level":27,"move_id":18},{"level":31,"move_id":213},{"level":34,"move_id":318},{"level":38,"move_id":202}]},"tmhm_learnset":"00403E80B43D4620","types":[6,2]},{"abilities":[61,0],"address":3304948,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":294}],"friendship":70,"id":293,"learnset":{"address":3315122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[19,0],"address":3304976,"base_stats":[60,50,70,65,50,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":294,"learnset":{"address":3315134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":16},{"level":17,"move_id":182},{"level":20,"move_id":236},{"level":24,"move_id":60},{"level":27,"move_id":18},{"level":31,"move_id":113},{"level":34,"move_id":318},{"level":38,"move_id":92}]},"tmhm_learnset":"00403E88B435C620","types":[6,3]},{"abilities":[33,44],"address":3305004,"base_stats":[40,30,30,30,40,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":296}],"friendship":70,"id":295,"learnset":{"address":3315162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":21,"move_id":54},{"level":31,"move_id":240},{"level":43,"move_id":72}]},"tmhm_learnset":"00503E0084373764","types":[11,12]},{"abilities":[33,44],"address":3305032,"base_stats":[60,50,50,50,60,70],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":297}],"friendship":70,"id":296,"learnset":{"address":3315184,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":154},{"level":31,"move_id":346},{"level":37,"move_id":168},{"level":43,"move_id":253},{"level":49,"move_id":56}]},"tmhm_learnset":"03F03E00C4373764","types":[11,12]},{"abilities":[33,44],"address":3305060,"base_stats":[80,70,70,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":297,"learnset":{"address":3315212,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":45},{"level":1,"move_id":71},{"level":1,"move_id":267}]},"tmhm_learnset":"03F03E00C4377765","types":[11,12]},{"abilities":[34,48],"address":3305088,"base_stats":[40,40,50,30,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":299}],"friendship":70,"id":298,"learnset":{"address":3315222,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":21,"move_id":235},{"level":31,"move_id":241},{"level":43,"move_id":153}]},"tmhm_learnset":"00C01E00AC350720","types":[12,12]},{"abilities":[34,48],"address":3305116,"base_stats":[70,70,40,60,60,40],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":300}],"friendship":70,"id":299,"learnset":{"address":3315244,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":259},{"level":31,"move_id":185},{"level":37,"move_id":13},{"level":43,"move_id":207},{"level":49,"move_id":326}]},"tmhm_learnset":"00E43F40EC354720","types":[12,17]},{"abilities":[34,48],"address":3305144,"base_stats":[90,100,60,80,90,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":300,"learnset":{"address":3315272,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":1,"move_id":74},{"level":1,"move_id":267}]},"tmhm_learnset":"00E43FC0EC354720","types":[12,17]},{"abilities":[14,0],"address":3305172,"base_stats":[31,45,90,40,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_NINJASK","param":20,"species":302},{"method":"LEVEL_SHEDINJA","param":20,"species":303}],"friendship":70,"id":301,"learnset":{"address":3315282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":206},{"level":31,"move_id":189},{"level":38,"move_id":232},{"level":45,"move_id":91}]},"tmhm_learnset":"00440E90AC350620","types":[6,4]},{"abilities":[3,0],"address":3305200,"base_stats":[61,90,45,160,50,50],"catch_rate":120,"evolutions":[],"friendship":70,"id":302,"learnset":{"address":3315308,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":141},{"level":1,"move_id":28},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":20,"move_id":104},{"level":20,"move_id":210},{"level":20,"move_id":103},{"level":25,"move_id":14},{"level":31,"move_id":163},{"level":38,"move_id":97},{"level":45,"move_id":226}]},"tmhm_learnset":"00443E90AC354620","types":[6,2]},{"abilities":[25,0],"address":3305228,"base_stats":[1,90,45,40,30,30],"catch_rate":45,"evolutions":[],"friendship":70,"id":303,"learnset":{"address":3315340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":180},{"level":31,"move_id":109},{"level":38,"move_id":247},{"level":45,"move_id":288}]},"tmhm_learnset":"00442E90AC354620","types":[6,7]},{"abilities":[62,0],"address":3305256,"base_stats":[40,55,30,85,30,30],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":305}],"friendship":70,"id":304,"learnset":{"address":3315366,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":26,"move_id":283},{"level":34,"move_id":332},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[62,0],"address":3305284,"base_stats":[60,85,60,125,50,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":305,"learnset":{"address":3315390,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":98},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":28,"move_id":283},{"level":38,"move_id":332},{"level":49,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[27,0],"address":3305312,"base_stats":[60,40,60,35,40,60],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":23,"species":307}],"friendship":70,"id":306,"learnset":{"address":3315414,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":28,"move_id":77},{"level":36,"move_id":74},{"level":45,"move_id":202},{"level":54,"move_id":147}]},"tmhm_learnset":"00411E08843D0720","types":[12,12]},{"abilities":[27,0],"address":3305340,"base_stats":[60,130,80,70,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":307,"learnset":{"address":3315442,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":33},{"level":1,"move_id":78},{"level":1,"move_id":73},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":23,"move_id":183},{"level":28,"move_id":68},{"level":36,"move_id":327},{"level":45,"move_id":170},{"level":54,"move_id":223}]},"tmhm_learnset":"00E51E08C47D47A1","types":[12,1]},{"abilities":[20,0],"address":3305368,"base_stats":[60,60,60,60,60,60],"catch_rate":255,"evolutions":[],"friendship":70,"id":308,"learnset":{"address":3315472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":253},{"level":12,"move_id":185},{"level":16,"move_id":60},{"level":23,"move_id":95},{"level":27,"move_id":146},{"level":34,"move_id":298},{"level":38,"move_id":244},{"level":45,"move_id":38},{"level":49,"move_id":175},{"level":56,"move_id":37}]},"tmhm_learnset":"00E1BE42FC1B062D","types":[0,0]},{"abilities":[51,0],"address":3305396,"base_stats":[40,30,30,85,55,30],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":310}],"friendship":70,"id":309,"learnset":{"address":3315502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":31,"move_id":98},{"level":43,"move_id":228},{"level":55,"move_id":97}]},"tmhm_learnset":"00087E8284133264","types":[11,2]},{"abilities":[51,0],"address":3305424,"base_stats":[60,50,100,65,85,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":310,"learnset":{"address":3315524,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":346},{"level":1,"move_id":17},{"level":3,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":25,"move_id":182},{"level":33,"move_id":254},{"level":33,"move_id":256},{"level":47,"move_id":255},{"level":61,"move_id":56}]},"tmhm_learnset":"00187E8284137264","types":[11,2]},{"abilities":[33,0],"address":3305452,"base_stats":[40,30,32,65,50,52],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":312}],"friendship":70,"id":311,"learnset":{"address":3315552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":25,"move_id":61},{"level":31,"move_id":97},{"level":37,"move_id":54},{"level":37,"move_id":114}]},"tmhm_learnset":"00403E00A4373624","types":[6,11]},{"abilities":[22,0],"address":3305480,"base_stats":[70,60,62,60,80,82],"catch_rate":75,"evolutions":[],"friendship":70,"id":312,"learnset":{"address":3315576,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":98},{"level":1,"move_id":230},{"level":1,"move_id":346},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":26,"move_id":16},{"level":33,"move_id":184},{"level":40,"move_id":78},{"level":47,"move_id":318},{"level":53,"move_id":18}]},"tmhm_learnset":"00403E80A4377624","types":[6,2]},{"abilities":[41,12],"address":3305508,"base_stats":[130,70,35,60,70,35],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":40,"species":314}],"friendship":70,"id":313,"learnset":{"address":3315602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":150},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":41,"move_id":323},{"level":46,"move_id":133},{"level":50,"move_id":56}]},"tmhm_learnset":"03B01E4086133274","types":[11,11]},{"abilities":[41,12],"address":3305536,"base_stats":[170,90,45,60,90,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":314,"learnset":{"address":3315634,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":205},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":44,"move_id":323},{"level":52,"move_id":133},{"level":59,"move_id":56}]},"tmhm_learnset":"03B01E4086137274","types":[11,11]},{"abilities":[56,0],"address":3305564,"base_stats":[50,45,45,50,35,35],"catch_rate":255,"evolutions":[{"method":"ITEM","param":94,"species":316}],"friendship":70,"id":315,"learnset":{"address":3315666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":3,"move_id":39},{"level":7,"move_id":213},{"level":13,"move_id":47},{"level":15,"move_id":3},{"level":19,"move_id":274},{"level":25,"move_id":204},{"level":27,"move_id":185},{"level":31,"move_id":343},{"level":37,"move_id":215},{"level":39,"move_id":38}]},"tmhm_learnset":"00401E02ADFB362C","types":[0,0]},{"abilities":[56,0],"address":3305592,"base_stats":[70,65,65,70,55,55],"catch_rate":60,"evolutions":[],"friendship":70,"id":316,"learnset":{"address":3315696,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":213},{"level":1,"move_id":47},{"level":1,"move_id":3}]},"tmhm_learnset":"00E01E02ADFB762C","types":[0,0]},{"abilities":[16,0],"address":3305620,"base_stats":[60,90,70,40,60,120],"catch_rate":200,"evolutions":[],"friendship":70,"id":317,"learnset":{"address":3315706,"moves":[{"level":1,"move_id":168},{"level":1,"move_id":39},{"level":1,"move_id":310},{"level":1,"move_id":122},{"level":1,"move_id":10},{"level":4,"move_id":20},{"level":7,"move_id":185},{"level":12,"move_id":154},{"level":17,"move_id":60},{"level":24,"move_id":103},{"level":31,"move_id":163},{"level":40,"move_id":164},{"level":49,"move_id":246}]},"tmhm_learnset":"00E5BEE6EDF33625","types":[0,0]},{"abilities":[26,0],"address":3305648,"base_stats":[40,40,55,55,40,70],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":36,"species":319}],"friendship":70,"id":318,"learnset":{"address":3315734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":37,"move_id":322},{"level":45,"move_id":153}]},"tmhm_learnset":"00408E51BE339620","types":[4,14]},{"abilities":[26,0],"address":3305676,"base_stats":[60,70,105,75,70,120],"catch_rate":90,"evolutions":[],"friendship":70,"id":319,"learnset":{"address":3315764,"moves":[{"level":1,"move_id":100},{"level":1,"move_id":93},{"level":1,"move_id":106},{"level":1,"move_id":229},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":36,"move_id":63},{"level":42,"move_id":322},{"level":55,"move_id":153}]},"tmhm_learnset":"00E08E51BE33D620","types":[4,14]},{"abilities":[5,42],"address":3305704,"base_stats":[30,45,135,30,45,90],"catch_rate":255,"evolutions":[],"friendship":70,"id":320,"learnset":{"address":3315796,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":106},{"level":13,"move_id":88},{"level":16,"move_id":335},{"level":22,"move_id":86},{"level":28,"move_id":157},{"level":31,"move_id":201},{"level":37,"move_id":156},{"level":43,"move_id":192},{"level":46,"move_id":199}]},"tmhm_learnset":"00A01F5287910E20","types":[5,5]},{"abilities":[73,0],"address":3305732,"base_stats":[70,85,140,20,85,70],"catch_rate":90,"evolutions":[],"friendship":70,"id":321,"learnset":{"address":3315824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":4,"move_id":123},{"level":7,"move_id":174},{"level":14,"move_id":108},{"level":17,"move_id":83},{"level":20,"move_id":34},{"level":27,"move_id":182},{"level":30,"move_id":53},{"level":33,"move_id":334},{"level":40,"move_id":133},{"level":43,"move_id":175},{"level":46,"move_id":257}]},"tmhm_learnset":"00A21E2C84510620","types":[10,10]},{"abilities":[51,0],"address":3305760,"base_stats":[50,75,75,50,65,65],"catch_rate":45,"evolutions":[],"friendship":35,"id":322,"learnset":{"address":3315856,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":10},{"level":5,"move_id":193},{"level":9,"move_id":101},{"level":13,"move_id":310},{"level":17,"move_id":154},{"level":21,"move_id":252},{"level":25,"move_id":197},{"level":29,"move_id":185},{"level":33,"move_id":282},{"level":37,"move_id":109},{"level":41,"move_id":247},{"level":45,"move_id":212}]},"tmhm_learnset":"00C53FC2FC130E2D","types":[17,7]},{"abilities":[12,0],"address":3305788,"base_stats":[50,48,43,60,46,41],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":324}],"friendship":70,"id":323,"learnset":{"address":3315888,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":189},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":31,"move_id":89},{"level":36,"move_id":248},{"level":41,"move_id":90}]},"tmhm_learnset":"03101E5086133264","types":[11,4]},{"abilities":[12,0],"address":3305816,"base_stats":[110,78,73,60,76,71],"catch_rate":75,"evolutions":[],"friendship":70,"id":324,"learnset":{"address":3315918,"moves":[{"level":1,"move_id":321},{"level":1,"move_id":189},{"level":1,"move_id":300},{"level":1,"move_id":346},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":36,"move_id":89},{"level":46,"move_id":248},{"level":56,"move_id":90}]},"tmhm_learnset":"03B01E5086137264","types":[11,4]},{"abilities":[33,0],"address":3305844,"base_stats":[43,30,55,97,40,65],"catch_rate":225,"evolutions":[],"friendship":70,"id":325,"learnset":{"address":3315948,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":204},{"level":12,"move_id":55},{"level":16,"move_id":97},{"level":24,"move_id":36},{"level":28,"move_id":213},{"level":36,"move_id":186},{"level":40,"move_id":175},{"level":48,"move_id":219}]},"tmhm_learnset":"03101E00841B3264","types":[11,11]},{"abilities":[52,75],"address":3305872,"base_stats":[43,80,65,35,50,35],"catch_rate":205,"evolutions":[{"method":"LEVEL","param":30,"species":327}],"friendship":70,"id":326,"learnset":{"address":3315974,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":32,"move_id":269},{"level":35,"move_id":152},{"level":38,"move_id":14},{"level":44,"move_id":12}]},"tmhm_learnset":"01B41EC8CC133A64","types":[11,11]},{"abilities":[52,75],"address":3305900,"base_stats":[63,120,85,55,90,55],"catch_rate":155,"evolutions":[],"friendship":70,"id":327,"learnset":{"address":3316004,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":106},{"level":1,"move_id":11},{"level":1,"move_id":43},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":34,"move_id":269},{"level":39,"move_id":152},{"level":44,"move_id":14},{"level":52,"move_id":12}]},"tmhm_learnset":"03B41EC8CC137A64","types":[11,17]},{"abilities":[33,0],"address":3305928,"base_stats":[20,15,20,80,10,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":30,"species":329}],"friendship":70,"id":328,"learnset":{"address":3316034,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[63,0],"address":3305956,"base_stats":[95,60,79,81,100,125],"catch_rate":60,"evolutions":[],"friendship":70,"id":329,"learnset":{"address":3316048,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":5,"move_id":35},{"level":10,"move_id":346},{"level":15,"move_id":287},{"level":20,"move_id":352},{"level":25,"move_id":239},{"level":30,"move_id":105},{"level":35,"move_id":240},{"level":40,"move_id":56},{"level":45,"move_id":213},{"level":50,"move_id":219}]},"tmhm_learnset":"03101E00845B7264","types":[11,11]},{"abilities":[24,0],"address":3305984,"base_stats":[45,90,20,65,65,20],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":30,"species":331}],"friendship":35,"id":330,"learnset":{"address":3316078,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":31,"move_id":36},{"level":37,"move_id":207},{"level":43,"move_id":97}]},"tmhm_learnset":"03103F0084133A64","types":[11,17]},{"abilities":[24,0],"address":3306012,"base_stats":[70,120,40,95,95,40],"catch_rate":60,"evolutions":[],"friendship":35,"id":331,"learnset":{"address":3316104,"moves":[{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":1,"move_id":99},{"level":1,"move_id":116},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":33,"move_id":163},{"level":38,"move_id":269},{"level":43,"move_id":207},{"level":48,"move_id":130},{"level":53,"move_id":97}]},"tmhm_learnset":"03B03F4086137A74","types":[11,17]},{"abilities":[52,71],"address":3306040,"base_stats":[45,100,45,10,45,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":333}],"friendship":70,"id":332,"learnset":{"address":3316134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":41,"move_id":91},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A01E508E354620","types":[4,4]},{"abilities":[26,26],"address":3306068,"base_stats":[50,70,50,70,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":45,"species":334}],"friendship":70,"id":333,"learnset":{"address":3316158,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A85E508E354620","types":[4,16]},{"abilities":[26,26],"address":3306096,"base_stats":[80,100,80,100,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":334,"learnset":{"address":3316184,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":53,"move_id":201},{"level":65,"move_id":63}]},"tmhm_learnset":"00A85E748E754622","types":[4,16]},{"abilities":[47,62],"address":3306124,"base_stats":[72,60,30,25,20,30],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":24,"species":336}],"friendship":70,"id":335,"learnset":{"address":3316210,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":28,"move_id":282},{"level":31,"move_id":265},{"level":37,"move_id":187},{"level":40,"move_id":203},{"level":46,"move_id":69},{"level":49,"move_id":179}]},"tmhm_learnset":"00B01E40CE1306A1","types":[1,1]},{"abilities":[47,62],"address":3306152,"base_stats":[144,120,60,50,40,60],"catch_rate":200,"evolutions":[],"friendship":70,"id":336,"learnset":{"address":3316242,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":1,"move_id":28},{"level":1,"move_id":292},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":29,"move_id":282},{"level":33,"move_id":265},{"level":40,"move_id":187},{"level":44,"move_id":203},{"level":51,"move_id":69},{"level":55,"move_id":179}]},"tmhm_learnset":"00B01E40CE1346A1","types":[1,1]},{"abilities":[9,31],"address":3306180,"base_stats":[40,45,40,65,65,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":26,"species":338}],"friendship":70,"id":337,"learnset":{"address":3316274,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":28,"move_id":46},{"level":33,"move_id":44},{"level":36,"move_id":87},{"level":41,"move_id":268}]},"tmhm_learnset":"00603E0285D30230","types":[13,13]},{"abilities":[9,31],"address":3306208,"base_stats":[70,75,60,105,105,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":338,"learnset":{"address":3316304,"moves":[{"level":1,"move_id":86},{"level":1,"move_id":43},{"level":1,"move_id":336},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":31,"move_id":46},{"level":39,"move_id":44},{"level":45,"move_id":87},{"level":53,"move_id":268}]},"tmhm_learnset":"00603E0285D34230","types":[13,13]},{"abilities":[12,0],"address":3306236,"base_stats":[60,60,40,35,65,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":33,"species":340}],"friendship":70,"id":339,"learnset":{"address":3316334,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":35,"move_id":89},{"level":41,"move_id":53},{"level":49,"move_id":38}]},"tmhm_learnset":"00A21E748E110620","types":[10,4]},{"abilities":[40,0],"address":3306264,"base_stats":[70,100,70,40,105,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":340,"learnset":{"address":3316360,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":1,"move_id":52},{"level":1,"move_id":222},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":33,"move_id":157},{"level":37,"move_id":89},{"level":45,"move_id":284},{"level":55,"move_id":90}]},"tmhm_learnset":"00A21E748E114630","types":[10,4]},{"abilities":[47,0],"address":3306292,"base_stats":[70,40,50,25,55,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":342}],"friendship":70,"id":341,"learnset":{"address":3316388,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":59},{"level":49,"move_id":329}]},"tmhm_learnset":"03B01E4086533264","types":[15,11]},{"abilities":[47,0],"address":3306320,"base_stats":[90,60,70,45,75,70],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":44,"species":343}],"friendship":70,"id":342,"learnset":{"address":3316416,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":47,"move_id":59},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E4086533274","types":[15,11]},{"abilities":[47,0],"address":3306348,"base_stats":[110,80,90,65,95,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":343,"learnset":{"address":3316444,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":50,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"03B01E4086537274","types":[15,11]},{"abilities":[8,0],"address":3306376,"base_stats":[50,85,40,35,85,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":32,"species":345}],"friendship":35,"id":344,"learnset":{"address":3316472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":33,"move_id":191},{"level":37,"move_id":302},{"level":41,"move_id":178},{"level":45,"move_id":201}]},"tmhm_learnset":"00441E1084350721","types":[12,12]},{"abilities":[8,0],"address":3306404,"base_stats":[70,115,60,55,115,60],"catch_rate":60,"evolutions":[],"friendship":35,"id":345,"learnset":{"address":3316504,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":74},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":35,"move_id":191},{"level":41,"move_id":302},{"level":47,"move_id":178},{"level":53,"move_id":201}]},"tmhm_learnset":"00641E1084354721","types":[12,17]},{"abilities":[39,0],"address":3306432,"base_stats":[50,50,50,50,50,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":42,"species":347}],"friendship":70,"id":346,"learnset":{"address":3316536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":37,"move_id":258},{"level":43,"move_id":59}]},"tmhm_learnset":"00401E00A41BB264","types":[15,15]},{"abilities":[39,0],"address":3306460,"base_stats":[80,80,80,80,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":347,"learnset":{"address":3316564,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":1,"move_id":104},{"level":1,"move_id":44},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":42,"move_id":258},{"level":53,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"00401F00A61BFA64","types":[15,15]},{"abilities":[26,0],"address":3306488,"base_stats":[70,55,65,70,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":348,"learnset":{"address":3316594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":95},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":94},{"level":43,"move_id":248},{"level":49,"move_id":153}]},"tmhm_learnset":"00408E51B61BD228","types":[5,14]},{"abilities":[26,0],"address":3306516,"base_stats":[70,95,85,70,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":349,"learnset":{"address":3316620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":83},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":157},{"level":43,"move_id":76},{"level":49,"move_id":153}]},"tmhm_learnset":"00428E75B639C628","types":[5,14]},{"abilities":[47,37],"address":3306544,"base_stats":[50,20,40,20,20,40],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":183}],"friendship":70,"id":350,"learnset":{"address":3316646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":150},{"level":3,"move_id":204},{"level":6,"move_id":39},{"level":10,"move_id":145},{"level":15,"move_id":21},{"level":21,"move_id":55}]},"tmhm_learnset":"01101E0084533264","types":[0,0]},{"abilities":[47,20],"address":3306572,"base_stats":[60,25,35,60,70,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":352}],"friendship":70,"id":351,"learnset":{"address":3316666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":1,"move_id":150},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":34,"move_id":94},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":340}]},"tmhm_learnset":"0041BF03B4538E28","types":[14,14]},{"abilities":[47,20],"address":3306600,"base_stats":[80,45,65,80,90,110],"catch_rate":60,"evolutions":[],"friendship":70,"id":352,"learnset":{"address":3316696,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":149},{"level":1,"move_id":316},{"level":1,"move_id":60},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":37,"move_id":94},{"level":43,"move_id":156},{"level":43,"move_id":173},{"level":55,"move_id":340}]},"tmhm_learnset":"0041BF03B453CE29","types":[14,14]},{"abilities":[57,0],"address":3306628,"base_stats":[60,50,40,95,85,75],"catch_rate":200,"evolutions":[],"friendship":70,"id":353,"learnset":{"address":3316726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":313},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[58,0],"address":3306656,"base_stats":[60,40,50,95,75,85],"catch_rate":200,"evolutions":[],"friendship":70,"id":354,"learnset":{"address":3316756,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":204},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[52,22],"address":3306684,"base_stats":[50,85,85,50,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":355,"learnset":{"address":3316786,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":6,"move_id":313},{"level":11,"move_id":44},{"level":16,"move_id":230},{"level":21,"move_id":11},{"level":26,"move_id":185},{"level":31,"move_id":226},{"level":36,"move_id":242},{"level":41,"move_id":334},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255}]},"tmhm_learnset":"00A01F7CC4335E21","types":[8,8]},{"abilities":[74,0],"address":3306712,"base_stats":[30,40,55,60,40,55],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":37,"species":357}],"friendship":70,"id":356,"learnset":{"address":3316818,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":38,"move_id":244},{"level":42,"move_id":179},{"level":48,"move_id":105}]},"tmhm_learnset":"00E01E41F41386A9","types":[1,14]},{"abilities":[74,0],"address":3306740,"base_stats":[60,60,75,80,60,75],"catch_rate":90,"evolutions":[],"friendship":70,"id":357,"learnset":{"address":3316848,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":9},{"level":1,"move_id":8},{"level":1,"move_id":117},{"level":1,"move_id":96},{"level":1,"move_id":93},{"level":1,"move_id":197},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":40,"move_id":244},{"level":46,"move_id":179},{"level":54,"move_id":105}]},"tmhm_learnset":"00E01E41F413C6A9","types":[1,14]},{"abilities":[30,0],"address":3306768,"base_stats":[45,40,60,50,40,75],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":359}],"friendship":70,"id":358,"learnset":{"address":3316884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":38,"move_id":119},{"level":41,"move_id":287},{"level":48,"move_id":195}]},"tmhm_learnset":"00087E80843B1620","types":[0,2]},{"abilities":[30,0],"address":3306796,"base_stats":[75,70,90,80,70,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":359,"learnset":{"address":3316912,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":310},{"level":1,"move_id":47},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":35,"move_id":225},{"level":40,"move_id":349},{"level":45,"move_id":287},{"level":54,"move_id":195},{"level":59,"move_id":143}]},"tmhm_learnset":"00887EA4867B5632","types":[16,2]},{"abilities":[23,0],"address":3306824,"base_stats":[95,23,48,23,23,48],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":15,"species":202}],"friendship":70,"id":360,"learnset":{"address":3316944,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":150},{"level":1,"move_id":204},{"level":1,"move_id":227},{"level":15,"move_id":68},{"level":15,"move_id":243},{"level":15,"move_id":219},{"level":15,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[26,0],"address":3306852,"base_stats":[20,40,90,25,30,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":362}],"friendship":35,"id":361,"learnset":{"address":3316962,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":38,"move_id":261},{"level":45,"move_id":212},{"level":49,"move_id":248}]},"tmhm_learnset":"0041BF00B4133E28","types":[7,7]},{"abilities":[46,0],"address":3306880,"base_stats":[40,70,130,25,60,130],"catch_rate":90,"evolutions":[],"friendship":35,"id":362,"learnset":{"address":3316990,"moves":[{"level":1,"move_id":20},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":1,"move_id":50},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":37,"move_id":325},{"level":41,"move_id":261},{"level":51,"move_id":212},{"level":58,"move_id":248}]},"tmhm_learnset":"00E1BF40B6137E29","types":[7,7]},{"abilities":[30,38],"address":3306908,"base_stats":[50,60,45,65,100,80],"catch_rate":150,"evolutions":[],"friendship":70,"id":363,"learnset":{"address":3317020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":5,"move_id":74},{"level":9,"move_id":40},{"level":13,"move_id":78},{"level":17,"move_id":72},{"level":21,"move_id":73},{"level":25,"move_id":345},{"level":29,"move_id":320},{"level":33,"move_id":202},{"level":37,"move_id":230},{"level":41,"move_id":275},{"level":45,"move_id":92},{"level":49,"move_id":80},{"level":53,"move_id":312},{"level":57,"move_id":235}]},"tmhm_learnset":"00441E08A4350720","types":[12,3]},{"abilities":[54,0],"address":3306936,"base_stats":[60,60,60,30,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":365}],"friendship":70,"id":364,"learnset":{"address":3317058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E5B336A5","types":[0,0]},{"abilities":[72,0],"address":3306964,"base_stats":[80,80,80,90,55,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":366}],"friendship":70,"id":365,"learnset":{"address":3317082,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":116},{"level":1,"move_id":227},{"level":1,"move_id":253},{"level":7,"move_id":227},{"level":13,"move_id":253},{"level":19,"move_id":154},{"level":25,"move_id":203},{"level":31,"move_id":163},{"level":37,"move_id":68},{"level":43,"move_id":264},{"level":49,"move_id":179}]},"tmhm_learnset":"00A41EA6E7B33EB5","types":[0,0]},{"abilities":[54,0],"address":3306992,"base_stats":[150,160,100,100,95,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":366,"learnset":{"address":3317108,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":1,"move_id":227},{"level":1,"move_id":303},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":36,"move_id":207},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E7B37EB5","types":[0,0]},{"abilities":[64,60],"address":3307020,"base_stats":[70,43,53,40,43,53],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":26,"species":368}],"friendship":70,"id":367,"learnset":{"address":3317134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":28,"move_id":92},{"level":34,"move_id":254},{"level":34,"move_id":255},{"level":34,"move_id":256},{"level":39,"move_id":188}]},"tmhm_learnset":"00A11E0AA4371724","types":[3,3]},{"abilities":[64,60],"address":3307048,"base_stats":[100,73,83,55,73,83],"catch_rate":75,"evolutions":[],"friendship":70,"id":368,"learnset":{"address":3317164,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":281},{"level":1,"move_id":139},{"level":1,"move_id":124},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":26,"move_id":34},{"level":31,"move_id":92},{"level":40,"move_id":254},{"level":40,"move_id":255},{"level":40,"move_id":256},{"level":48,"move_id":188}]},"tmhm_learnset":"00A11E0AA4375724","types":[3,3]},{"abilities":[34,0],"address":3307076,"base_stats":[99,68,83,51,72,87],"catch_rate":200,"evolutions":[],"friendship":70,"id":369,"learnset":{"address":3317196,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":16},{"level":7,"move_id":74},{"level":11,"move_id":75},{"level":17,"move_id":23},{"level":21,"move_id":230},{"level":27,"move_id":18},{"level":31,"move_id":345},{"level":37,"move_id":34},{"level":41,"move_id":76},{"level":47,"move_id":235}]},"tmhm_learnset":"00EC5E80863D4730","types":[12,2]},{"abilities":[43,0],"address":3307104,"base_stats":[64,51,23,28,51,23],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":20,"species":371}],"friendship":70,"id":370,"learnset":{"address":3317224,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":21,"move_id":48},{"level":25,"move_id":23},{"level":31,"move_id":103},{"level":35,"move_id":46},{"level":41,"move_id":156},{"level":41,"move_id":214},{"level":45,"move_id":304}]},"tmhm_learnset":"00001E26A4333634","types":[0,0]},{"abilities":[43,0],"address":3307132,"base_stats":[84,71,43,48,71,43],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":40,"species":372}],"friendship":70,"id":371,"learnset":{"address":3317254,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":43,"move_id":46},{"level":51,"move_id":156},{"level":51,"move_id":214},{"level":57,"move_id":304}]},"tmhm_learnset":"00A21F26E6333E34","types":[0,0]},{"abilities":[43,0],"address":3307160,"base_stats":[104,91,63,68,91,63],"catch_rate":45,"evolutions":[],"friendship":70,"id":372,"learnset":{"address":3317284,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":40,"move_id":63},{"level":45,"move_id":46},{"level":55,"move_id":156},{"level":55,"move_id":214},{"level":63,"move_id":304}]},"tmhm_learnset":"00A21F26E6337E34","types":[0,0]},{"abilities":[75,0],"address":3307188,"base_stats":[35,64,85,32,74,55],"catch_rate":255,"evolutions":[{"method":"ITEM","param":192,"species":374},{"method":"ITEM","param":193,"species":375}],"friendship":70,"id":373,"learnset":{"address":3317316,"moves":[{"level":1,"move_id":128},{"level":1,"move_id":55},{"level":1,"move_id":250},{"level":1,"move_id":334}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,0],"address":3307216,"base_stats":[55,104,105,52,94,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":374,"learnset":{"address":3317326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":44},{"level":15,"move_id":103},{"level":22,"move_id":352},{"level":29,"move_id":184},{"level":36,"move_id":242},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03111E4084137264","types":[11,11]},{"abilities":[33,0],"address":3307244,"base_stats":[55,84,105,52,114,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":375,"learnset":{"address":3317350,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":93},{"level":15,"move_id":97},{"level":22,"move_id":352},{"level":29,"move_id":133},{"level":36,"move_id":94},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03101E00B41B7264","types":[11,11]},{"abilities":[46,0],"address":3307272,"base_stats":[65,130,60,75,75,60],"catch_rate":30,"evolutions":[],"friendship":35,"id":376,"learnset":{"address":3317374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":5,"move_id":43},{"level":9,"move_id":269},{"level":13,"move_id":98},{"level":17,"move_id":13},{"level":21,"move_id":44},{"level":26,"move_id":14},{"level":31,"move_id":104},{"level":36,"move_id":163},{"level":41,"move_id":248},{"level":46,"move_id":195}]},"tmhm_learnset":"00E53FB6A5D37E6C","types":[17,17]},{"abilities":[15,0],"address":3307300,"base_stats":[44,75,35,45,63,33],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":37,"species":378}],"friendship":35,"id":377,"learnset":{"address":3317404,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":282},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":37,"move_id":185},{"level":44,"move_id":247},{"level":49,"move_id":289},{"level":56,"move_id":288}]},"tmhm_learnset":"0041BF02B5930E28","types":[7,7]},{"abilities":[15,0],"address":3307328,"base_stats":[64,115,65,65,83,63],"catch_rate":45,"evolutions":[],"friendship":35,"id":378,"learnset":{"address":3317432,"moves":[{"level":1,"move_id":282},{"level":1,"move_id":103},{"level":1,"move_id":101},{"level":1,"move_id":174},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":39,"move_id":185},{"level":48,"move_id":247},{"level":55,"move_id":289},{"level":64,"move_id":288}]},"tmhm_learnset":"0041BF02B5934E28","types":[7,7]},{"abilities":[61,0],"address":3307356,"base_stats":[73,100,60,65,100,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":379,"learnset":{"address":3317460,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":7,"move_id":122},{"level":10,"move_id":44},{"level":16,"move_id":342},{"level":19,"move_id":103},{"level":25,"move_id":137},{"level":28,"move_id":242},{"level":34,"move_id":305},{"level":37,"move_id":207},{"level":43,"move_id":114}]},"tmhm_learnset":"00A13E0C8E570E20","types":[3,3]},{"abilities":[17,0],"address":3307384,"base_stats":[73,115,60,90,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":380,"learnset":{"address":3317488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":43},{"level":7,"move_id":98},{"level":10,"move_id":14},{"level":13,"move_id":210},{"level":19,"move_id":163},{"level":25,"move_id":228},{"level":31,"move_id":306},{"level":37,"move_id":269},{"level":46,"move_id":197},{"level":55,"move_id":206}]},"tmhm_learnset":"00A03EA6EDF73E35","types":[0,0]},{"abilities":[33,69],"address":3307412,"base_stats":[100,90,130,55,45,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":381,"learnset":{"address":3317518,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":8,"move_id":55},{"level":15,"move_id":317},{"level":22,"move_id":281},{"level":29,"move_id":36},{"level":36,"move_id":300},{"level":43,"move_id":246},{"level":50,"move_id":156},{"level":57,"move_id":38},{"level":64,"move_id":56}]},"tmhm_learnset":"03901E50861B726C","types":[11,5]},{"abilities":[5,69],"address":3307440,"base_stats":[50,70,100,30,40,40],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":32,"species":383}],"friendship":35,"id":382,"learnset":{"address":3317546,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":34,"move_id":182},{"level":39,"move_id":319},{"level":44,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307468,"base_stats":[60,90,140,40,50,50],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":42,"species":384}],"friendship":35,"id":383,"learnset":{"address":3317578,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":45,"move_id":319},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307496,"base_stats":[70,110,180,50,60,60],"catch_rate":45,"evolutions":[],"friendship":35,"id":384,"learnset":{"address":3317610,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":50,"move_id":319},{"level":63,"move_id":38}]},"tmhm_learnset":"00B41EF6CFF37E37","types":[8,5]},{"abilities":[59,0],"address":3307524,"base_stats":[70,70,70,70,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":385,"learnset":{"address":3317642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":10,"move_id":55},{"level":10,"move_id":52},{"level":10,"move_id":181},{"level":20,"move_id":240},{"level":20,"move_id":241},{"level":20,"move_id":258},{"level":30,"move_id":311}]},"tmhm_learnset":"00403E36A5B33664","types":[0,0]},{"abilities":[35,68],"address":3307552,"base_stats":[65,73,55,85,47,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":386,"learnset":{"address":3317666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":109},{"level":9,"move_id":104},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":294},{"level":25,"move_id":324},{"level":29,"move_id":182},{"level":33,"move_id":270},{"level":37,"move_id":38}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[12,0],"address":3307580,"base_stats":[65,47,55,85,73,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":387,"learnset":{"address":3317694,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":230},{"level":9,"move_id":204},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":273},{"level":25,"move_id":227},{"level":29,"move_id":260},{"level":33,"move_id":270},{"level":37,"move_id":343}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[21,0],"address":3307608,"base_stats":[66,41,77,23,61,87],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":389}],"friendship":70,"id":388,"learnset":{"address":3317722,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":43,"move_id":246},{"level":50,"move_id":254},{"level":50,"move_id":255},{"level":50,"move_id":256}]},"tmhm_learnset":"00001E1884350720","types":[5,12]},{"abilities":[21,0],"address":3307636,"base_stats":[86,81,97,43,81,107],"catch_rate":45,"evolutions":[],"friendship":70,"id":389,"learnset":{"address":3317750,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":132},{"level":1,"move_id":51},{"level":1,"move_id":275},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":48,"move_id":246},{"level":60,"move_id":254},{"level":60,"move_id":255},{"level":60,"move_id":256}]},"tmhm_learnset":"00A01E5886354720","types":[5,12]},{"abilities":[4,0],"address":3307664,"base_stats":[45,95,50,75,40,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":391}],"friendship":70,"id":390,"learnset":{"address":3317778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":43,"move_id":210},{"level":49,"move_id":163},{"level":55,"move_id":350}]},"tmhm_learnset":"00841ED0CC110624","types":[5,6]},{"abilities":[4,0],"address":3307692,"base_stats":[75,125,100,45,70,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":391,"learnset":{"address":3317806,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":300},{"level":1,"move_id":55},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":46,"move_id":210},{"level":55,"move_id":163},{"level":64,"move_id":350}]},"tmhm_learnset":"00A41ED0CE514624","types":[5,6]},{"abilities":[28,36],"address":3307720,"base_stats":[28,25,25,40,45,35],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":20,"species":393}],"friendship":35,"id":392,"learnset":{"address":3317834,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":45},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":31,"move_id":286},{"level":36,"move_id":248},{"level":41,"move_id":95},{"level":46,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307748,"base_stats":[38,35,35,50,65,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":394}],"friendship":35,"id":393,"learnset":{"address":3317862,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":40,"move_id":248},{"level":47,"move_id":95},{"level":54,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307776,"base_stats":[68,65,65,80,125,115],"catch_rate":45,"evolutions":[],"friendship":35,"id":394,"learnset":{"address":3317890,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":42,"move_id":248},{"level":51,"move_id":95},{"level":60,"move_id":138}]},"tmhm_learnset":"0041BF03B49BCE28","types":[14,14]},{"abilities":[69,0],"address":3307804,"base_stats":[45,75,60,50,40,30],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":396}],"friendship":35,"id":395,"learnset":{"address":3317918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":33,"move_id":225},{"level":37,"move_id":184},{"level":41,"move_id":242},{"level":49,"move_id":337},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[69,0],"address":3307832,"base_stats":[65,95,100,50,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":50,"species":397}],"friendship":35,"id":396,"learnset":{"address":3317948,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":56,"move_id":242},{"level":69,"move_id":337},{"level":78,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[22,0],"address":3307860,"base_stats":[95,135,80,100,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":397,"learnset":{"address":3317980,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":50,"move_id":19},{"level":61,"move_id":242},{"level":79,"move_id":337},{"level":93,"move_id":38}]},"tmhm_learnset":"00AC5EE4C6534632","types":[16,2]},{"abilities":[29,0],"address":3307888,"base_stats":[40,55,80,30,35,60],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":20,"species":399}],"friendship":35,"id":398,"learnset":{"address":3318014,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36}]},"tmhm_learnset":"0000000000000000","types":[8,14]},{"abilities":[29,0],"address":3307916,"base_stats":[60,75,100,50,55,80],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":45,"species":400}],"friendship":35,"id":399,"learnset":{"address":3318024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":50,"move_id":309},{"level":56,"move_id":97},{"level":62,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307944,"base_stats":[80,135,130,70,95,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":400,"learnset":{"address":3318052,"moves":[{"level":1,"move_id":36},{"level":1,"move_id":93},{"level":1,"move_id":232},{"level":1,"move_id":184},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":55,"move_id":309},{"level":66,"move_id":97},{"level":77,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307972,"base_stats":[80,100,200,50,50,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":401,"learnset":{"address":3318080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":153},{"level":9,"move_id":88},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E52CF994621","types":[5,5]},{"abilities":[29,0],"address":3308000,"base_stats":[80,50,100,50,100,200],"catch_rate":3,"evolutions":[],"friendship":35,"id":402,"learnset":{"address":3318106,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":196},{"level":1,"move_id":153},{"level":9,"move_id":196},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E02C79B7261","types":[15,15]},{"abilities":[29,0],"address":3308028,"base_stats":[80,75,150,50,75,150],"catch_rate":3,"evolutions":[],"friendship":35,"id":403,"learnset":{"address":3318132,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":232},{"level":1,"move_id":153},{"level":9,"move_id":232},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00ED2C79B4621","types":[8,8]},{"abilities":[2,0],"address":3308056,"base_stats":[100,100,90,90,150,140],"catch_rate":5,"evolutions":[],"friendship":0,"id":404,"learnset":{"address":3318160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":352},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":34},{"level":30,"move_id":347},{"level":35,"move_id":58},{"level":45,"move_id":56},{"level":50,"move_id":156},{"level":60,"move_id":329},{"level":65,"move_id":38},{"level":75,"move_id":323}]},"tmhm_learnset":"03B00E42C79B727C","types":[11,11]},{"abilities":[70,0],"address":3308084,"base_stats":[100,150,140,90,100,90],"catch_rate":5,"evolutions":[],"friendship":0,"id":405,"learnset":{"address":3318190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":341},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":163},{"level":30,"move_id":339},{"level":35,"move_id":89},{"level":45,"move_id":126},{"level":50,"move_id":156},{"level":60,"move_id":90},{"level":65,"move_id":76},{"level":75,"move_id":284}]},"tmhm_learnset":"00A60EF6CFF946B2","types":[4,4]},{"abilities":[77,0],"address":3308112,"base_stats":[105,150,90,95,150,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":406,"learnset":{"address":3318220,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":239},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":337},{"level":30,"move_id":349},{"level":35,"move_id":242},{"level":45,"move_id":19},{"level":50,"move_id":156},{"level":60,"move_id":245},{"level":65,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BA0EB6C7F376B6","types":[16,2]},{"abilities":[26,0],"address":3308140,"base_stats":[80,80,90,110,110,130],"catch_rate":3,"evolutions":[],"friendship":90,"id":407,"learnset":{"address":3318250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":273},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":346},{"level":30,"move_id":287},{"level":35,"move_id":296},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":204}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[26,0],"address":3308168,"base_stats":[80,90,80,110,130,110],"catch_rate":3,"evolutions":[],"friendship":90,"id":408,"learnset":{"address":3318280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":262},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":182},{"level":30,"move_id":287},{"level":35,"move_id":295},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":349}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[32,0],"address":3308196,"base_stats":[100,100,100,100,100,100],"catch_rate":3,"evolutions":[],"friendship":100,"id":409,"learnset":{"address":3318310,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":273},{"level":1,"move_id":93},{"level":5,"move_id":156},{"level":10,"move_id":129},{"level":15,"move_id":270},{"level":20,"move_id":94},{"level":25,"move_id":287},{"level":30,"move_id":156},{"level":35,"move_id":38},{"level":40,"move_id":248},{"level":45,"move_id":322},{"level":50,"move_id":353}]},"tmhm_learnset":"00408E93B59BC62C","types":[8,14]},{"abilities":[46,0],"address":3308224,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":410,"learnset":{"address":3318340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":35},{"level":5,"move_id":101},{"level":10,"move_id":104},{"level":15,"move_id":282},{"level":20,"move_id":228},{"level":25,"move_id":94},{"level":30,"move_id":129},{"level":35,"move_id":97},{"level":40,"move_id":105},{"level":45,"move_id":354},{"level":50,"move_id":245}]},"tmhm_learnset":"00E58FC3F5BBDE2D","types":[14,14]},{"abilities":[26,0],"address":3308252,"base_stats":[65,50,70,65,95,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":411,"learnset":{"address":3318370,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":6,"move_id":45},{"level":9,"move_id":310},{"level":14,"move_id":93},{"level":17,"move_id":36},{"level":22,"move_id":253},{"level":25,"move_id":281},{"level":30,"move_id":149},{"level":33,"move_id":38},{"level":38,"move_id":215},{"level":41,"move_id":219},{"level":46,"move_id":94}]},"tmhm_learnset":"00419F03B41B8E28","types":[14,14]}],"tmhm_moves":[264,337,352,347,46,92,258,339,331,237,241,269,58,59,63,113,182,240,202,219,218,76,231,85,87,89,216,91,94,247,280,104,115,351,53,188,201,126,317,332,259,263,290,156,213,168,211,285,289,315,15,19,57,70,148,249,127,291],"trainers":[{"address":3230072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[],"party_address":4160749568,"script_address":0},{"address":3230112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":74}],"party_address":3211124,"script_address":2304511},{"address":3230152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":286}],"party_address":3211132,"script_address":2321901},{"address":3230192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":330}],"party_address":3211140,"script_address":2323326},{"address":3230232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211156,"script_address":2323373},{"address":3230272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211164,"script_address":2324386},{"address":3230312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":286}],"party_address":3211172,"script_address":2326808},{"address":3230352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211180,"script_address":2326839},{"address":3230392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":41}],"party_address":3211188,"script_address":2328040},{"address":3230432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":315},{"level":26,"species":286},{"level":26,"species":288},{"level":26,"species":295},{"level":26,"species":298},{"level":26,"species":304}],"party_address":3211196,"script_address":2314251},{"address":3230472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":286}],"party_address":3211244,"script_address":0},{"address":3230512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":300}],"party_address":3211252,"script_address":2067580},{"address":3230552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":310},{"level":30,"species":178}],"party_address":3211268,"script_address":2068523},{"address":3230592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":380},{"level":30,"species":379}],"party_address":3211284,"script_address":2068554},{"address":3230632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211300,"script_address":2328071},{"address":3230672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3211308,"script_address":2069620},{"address":3230712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":286}],"party_address":3211316,"script_address":0},{"address":3230752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3211324,"script_address":2570959},{"address":3230792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":286},{"level":27,"species":330}],"party_address":3211340,"script_address":2572093},{"address":3230832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":286},{"level":26,"species":41},{"level":26,"species":330}],"party_address":3211356,"script_address":2572124},{"address":3230872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":330}],"party_address":3211380,"script_address":2157889},{"address":3230912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":41},{"level":14,"species":330}],"party_address":3211388,"script_address":2157948},{"address":3230952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":339}],"party_address":3211404,"script_address":2254636},{"address":3230992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211412,"script_address":2317522},{"address":3231032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211420,"script_address":2317553},{"address":3231072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":286},{"level":30,"species":330}],"party_address":3211428,"script_address":2317584},{"address":3231112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330}],"party_address":3211444,"script_address":2570990},{"address":3231152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211452,"script_address":2323414},{"address":3231192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211460,"script_address":2324427},{"address":3231232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":335},{"level":30,"species":67}],"party_address":3211468,"script_address":2068492},{"address":3231272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":287},{"level":34,"species":42}],"party_address":3211484,"script_address":2324250},{"address":3231312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":336}],"party_address":3211500,"script_address":2312702},{"address":3231352,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330},{"level":28,"species":287}],"party_address":3211508,"script_address":2572155},{"address":3231392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":331},{"level":37,"species":287}],"party_address":3211524,"script_address":2327156},{"address":3231432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":287},{"level":41,"species":169},{"level":43,"species":331}],"party_address":3211540,"script_address":2328478},{"address":3231472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":351}],"party_address":3211564,"script_address":2312671},{"address":3231512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211572,"script_address":2026085},{"address":3231552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":363},{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211588,"script_address":2058784},{"address":3231592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,0,0,0],"species":357},{"level":43,"moves":[29,89,0,0],"species":319}],"party_address":3211612,"script_address":2335547},{"address":3231632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":363},{"level":26,"species":44}],"party_address":3211644,"script_address":2068148},{"address":3231672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":363}],"party_address":3211660,"script_address":0},{"address":3231712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":306},{"level":28,"species":44},{"level":28,"species":363}],"party_address":3211676,"script_address":0},{"address":3231752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":306},{"level":31,"species":44},{"level":31,"species":363}],"party_address":3211700,"script_address":0},{"address":3231792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307},{"level":34,"species":44},{"level":34,"species":363}],"party_address":3211724,"script_address":0},{"address":3231832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,163,28,40],"species":28}],"party_address":3211748,"script_address":2046490},{"address":3231872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[60,120,201,246],"species":318},{"level":27,"moves":[91,163,28,40],"species":27},{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211764,"script_address":2065682},{"address":3231912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[91,163,28,40],"species":27},{"level":25,"moves":[91,163,28,40],"species":28}],"party_address":3211812,"script_address":2033540},{"address":3231952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211844,"script_address":0},{"address":3231992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[91,163,28,40],"species":28}],"party_address":3211860,"script_address":0},{"address":3232032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[91,163,28,40],"species":28}],"party_address":3211876,"script_address":0},{"address":3232072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[91,163,28,40],"species":28}],"party_address":3211892,"script_address":0},{"address":3232112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":81},{"level":17,"species":370}],"party_address":3211908,"script_address":0},{"address":3232152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":81},{"level":27,"species":371}],"party_address":3211924,"script_address":0},{"address":3232192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":82},{"level":30,"species":371}],"party_address":3211940,"script_address":0},{"address":3232232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":82},{"level":33,"species":371}],"party_address":3211956,"script_address":0},{"address":3232272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82},{"level":36,"species":371}],"party_address":3211972,"script_address":0},{"address":3232312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[49,86,63,85],"species":82},{"level":39,"moves":[54,23,48,48],"species":372}],"party_address":3211988,"script_address":0},{"address":3232352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":350}],"party_address":3212020,"script_address":2036011},{"address":3232392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212036,"script_address":2036121},{"address":3232432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212044,"script_address":2036152},{"address":3232472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183},{"level":26,"species":183}],"party_address":3212052,"script_address":0},{"address":3232512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":183},{"level":29,"species":183}],"party_address":3212068,"script_address":0},{"address":3232552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":183},{"level":32,"species":183}],"party_address":3212084,"script_address":0},{"address":3232592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":35,"species":184}],"party_address":3212100,"script_address":0},{"address":3232632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":13,"moves":[28,29,39,57],"species":288}],"party_address":3212116,"script_address":2035901},{"address":3232672,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":183}],"party_address":3212132,"script_address":2544001},{"address":3232712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212148,"script_address":2339831},{"address":3232752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[28,42,39,57],"species":289}],"party_address":3212156,"script_address":0},{"address":3232792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[28,42,39,57],"species":289}],"party_address":3212172,"script_address":0},{"address":3232832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[28,42,39,57],"species":289}],"party_address":3212188,"script_address":0},{"address":3232872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[28,42,39,57],"species":289}],"party_address":3212204,"script_address":0},{"address":3232912,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[98,97,17,0],"species":305}],"party_address":3212220,"script_address":2131164},{"address":3232952,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[42,146,8,0],"species":308}],"party_address":3212236,"script_address":2131228},{"address":3232992,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[47,68,247,0],"species":364}],"party_address":3212252,"script_address":2131292},{"address":3233032,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[116,163,0,0],"species":365}],"party_address":3212268,"script_address":2131356},{"address":3233072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[116,98,17,27],"species":305},{"level":28,"moves":[44,91,185,72],"species":332},{"level":28,"moves":[205,250,54,96],"species":313},{"level":28,"moves":[85,48,86,49],"species":82},{"level":28,"moves":[202,185,104,207],"species":300}],"party_address":3212284,"script_address":2068117},{"address":3233112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":322},{"level":44,"species":357},{"level":44,"species":331}],"party_address":3212364,"script_address":2565920},{"address":3233152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":355},{"level":46,"species":121}],"party_address":3212388,"script_address":2565982},{"address":3233192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":337},{"level":17,"species":313},{"level":17,"species":335}],"party_address":3212404,"script_address":2046693},{"address":3233232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":345},{"level":43,"species":310}],"party_address":3212428,"script_address":2332685},{"address":3233272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":82},{"level":43,"species":89}],"party_address":3212444,"script_address":2332716},{"address":3233312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":305},{"level":42,"species":355},{"level":42,"species":64}],"party_address":3212460,"script_address":2334375},{"address":3233352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":85},{"level":42,"species":64},{"level":42,"species":101},{"level":42,"species":300}],"party_address":3212484,"script_address":2335423},{"address":3233392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":317},{"level":42,"species":75},{"level":42,"species":314}],"party_address":3212516,"script_address":2335454},{"address":3233432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":337},{"level":26,"species":313},{"level":26,"species":335}],"party_address":3212540,"script_address":0},{"address":3233472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":313},{"level":29,"species":335}],"party_address":3212564,"script_address":0},{"address":3233512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":338},{"level":32,"species":313},{"level":32,"species":335}],"party_address":3212588,"script_address":0},{"address":3233552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":338},{"level":35,"species":313},{"level":35,"species":336}],"party_address":3212612,"script_address":0},{"address":3233592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":297}],"party_address":3212636,"script_address":2073950},{"address":3233632,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[185,95,0,0],"species":316}],"party_address":3212652,"script_address":2131420},{"address":3233672,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[111,38,247,0],"species":40}],"party_address":3212668,"script_address":2131484},{"address":3233712,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[14,163,0,0],"species":380}],"party_address":3212684,"script_address":2131548},{"address":3233752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[226,185,57,44],"species":355},{"level":29,"moves":[72,89,64,73],"species":363},{"level":29,"moves":[19,55,54,182],"species":310}],"party_address":3212700,"script_address":2068086},{"address":3233792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":383},{"level":45,"species":338}],"party_address":3212748,"script_address":2565951},{"address":3233832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":309},{"level":17,"species":339},{"level":17,"species":363}],"party_address":3212764,"script_address":2046803},{"address":3233872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":322}],"party_address":3212788,"script_address":2065651},{"address":3233912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3212796,"script_address":2332747},{"address":3233952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":319}],"party_address":3212804,"script_address":2334406},{"address":3233992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":321},{"level":42,"species":357},{"level":42,"species":297}],"party_address":3212812,"script_address":2334437},{"address":3234032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":227},{"level":43,"species":322}],"party_address":3212836,"script_address":2335485},{"address":3234072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":28},{"level":42,"species":38},{"level":42,"species":369}],"party_address":3212852,"script_address":2335516},{"address":3234112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":26,"species":339},{"level":26,"species":363}],"party_address":3212876,"script_address":0},{"address":3234152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":339},{"level":29,"species":363}],"party_address":3212900,"script_address":0},{"address":3234192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":339},{"level":32,"species":363}],"party_address":3212924,"script_address":0},{"address":3234232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":340},{"level":34,"species":363}],"party_address":3212948,"script_address":0},{"address":3234272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":348}],"party_address":3212972,"script_address":2564729},{"address":3234312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":361},{"level":30,"species":377}],"party_address":3212988,"script_address":2068461},{"address":3234352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":361},{"level":29,"species":377}],"party_address":3213004,"script_address":2067284},{"address":3234392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":322}],"party_address":3213020,"script_address":2315745},{"address":3234432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":377}],"party_address":3213028,"script_address":2315532},{"address":3234472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":322},{"level":31,"species":351}],"party_address":3213036,"script_address":0},{"address":3234512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":351},{"level":35,"species":322}],"party_address":3213052,"script_address":0},{"address":3234552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":351},{"level":40,"species":322}],"party_address":3213068,"script_address":0},{"address":3234592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":361},{"level":42,"species":322},{"level":42,"species":352}],"party_address":3213084,"script_address":0},{"address":3234632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213108,"script_address":2030087},{"address":3234672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[213,186,175,96],"species":325},{"level":39,"moves":[213,219,36,96],"species":325}],"party_address":3213116,"script_address":2265894},{"address":3234712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":287},{"level":28,"species":287},{"level":30,"species":339}],"party_address":3213148,"script_address":2254717},{"address":3234752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":11,"moves":[33,39,0,0],"species":288}],"party_address":3213172,"script_address":0},{"address":3234792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":40,"species":119}],"party_address":3213188,"script_address":2265677},{"address":3234832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3213196,"script_address":2361019},{"address":3234872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213204,"script_address":0},{"address":3234912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213212,"script_address":0},{"address":3234952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213220,"script_address":0},{"address":3234992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213228,"script_address":0},{"address":3235032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":183}],"party_address":3213244,"script_address":2304387},{"address":3235072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3213252,"script_address":2304418},{"address":3235112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":339}],"party_address":3213260,"script_address":2304449},{"address":3235152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[20,122,154,185],"species":317},{"level":29,"moves":[86,103,137,242],"species":379}],"party_address":3213268,"script_address":2067377},{"address":3235192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":118}],"party_address":3213300,"script_address":2265708},{"address":3235232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":184}],"party_address":3213308,"script_address":2265739},{"address":3235272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[78,250,240,96],"species":373},{"level":37,"moves":[13,152,96,0],"species":326},{"level":39,"moves":[253,154,252,96],"species":296}],"party_address":3213316,"script_address":2265770},{"address":3235312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":330},{"level":39,"species":331}],"party_address":3213364,"script_address":2265801},{"address":3235352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[20,122,154,185],"species":317},{"level":35,"moves":[86,103,137,242],"species":379}],"party_address":3213380,"script_address":0},{"address":3235392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[20,122,154,185],"species":317},{"level":38,"moves":[86,103,137,242],"species":379}],"party_address":3213412,"script_address":0},{"address":3235432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[20,122,154,185],"species":317},{"level":41,"moves":[86,103,137,242],"species":379}],"party_address":3213444,"script_address":0},{"address":3235472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[20,122,154,185],"species":317},{"level":44,"moves":[86,103,137,242],"species":379}],"party_address":3213476,"script_address":0},{"address":3235512,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213508,"script_address":2029901},{"address":3235552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":324},{"level":33,"species":356}],"party_address":3213516,"script_address":2074012},{"address":3235592,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":184}],"party_address":3213532,"script_address":2360988},{"address":3235632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213540,"script_address":0},{"address":3235672,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213548,"script_address":0},{"address":3235712,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213556,"script_address":0},{"address":3235752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213564,"script_address":0},{"address":3235792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3213580,"script_address":2051965},{"address":3235832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":116}],"party_address":3213588,"script_address":2340108},{"address":3235872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":111}],"party_address":3213604,"script_address":2312578},{"address":3235912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":339}],"party_address":3213612,"script_address":2304480},{"address":3235952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":383}],"party_address":3213620,"script_address":0},{"address":3235992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":383},{"level":29,"species":111}],"party_address":3213628,"script_address":0},{"address":3236032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":383},{"level":32,"species":111}],"party_address":3213644,"script_address":0},{"address":3236072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":384},{"level":35,"species":112}],"party_address":3213660,"script_address":0},{"address":3236112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213676,"script_address":2033571},{"address":3236152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":72}],"party_address":3213684,"script_address":2033602},{"address":3236192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":72}],"party_address":3213692,"script_address":2034185},{"address":3236232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":309},{"level":24,"species":72}],"party_address":3213708,"script_address":2034479},{"address":3236272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213732,"script_address":2034510},{"address":3236312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":73}],"party_address":3213740,"script_address":2034776},{"address":3236352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213748,"script_address":2034807},{"address":3236392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3213756,"script_address":2035777},{"address":3236432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309}],"party_address":3213772,"script_address":2069178},{"address":3236472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3213788,"script_address":2069209},{"address":3236512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":73}],"party_address":3213796,"script_address":2069789},{"address":3236552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":116}],"party_address":3213804,"script_address":2069820},{"address":3236592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213812,"script_address":2070163},{"address":3236632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":31,"species":309},{"level":31,"species":330}],"party_address":3213820,"script_address":2070194},{"address":3236672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213844,"script_address":2073229},{"address":3236712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310}],"party_address":3213852,"script_address":2073359},{"address":3236752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213860,"script_address":2073390},{"address":3236792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":73},{"level":33,"species":313}],"party_address":3213876,"script_address":2073291},{"address":3236832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3213892,"script_address":2073608},{"address":3236872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":342}],"party_address":3213900,"script_address":2073857},{"address":3236912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":341}],"party_address":3213908,"script_address":2073576},{"address":3236952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213916,"script_address":2074089},{"address":3236992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213924,"script_address":0},{"address":3237032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":313}],"party_address":3213948,"script_address":2069381},{"address":3237072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":331}],"party_address":3213964,"script_address":0},{"address":3237112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":331}],"party_address":3213972,"script_address":0},{"address":3237152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120},{"level":36,"species":331}],"party_address":3213980,"script_address":0},{"address":3237192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":121},{"level":39,"species":331}],"party_address":3213996,"script_address":0},{"address":3237232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3214012,"script_address":2095275},{"address":3237272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":66},{"level":32,"species":67}],"party_address":3214020,"script_address":2074213},{"address":3237312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":336}],"party_address":3214036,"script_address":2073701},{"address":3237352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":66},{"level":28,"species":67}],"party_address":3214044,"script_address":2052921},{"address":3237392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214060,"script_address":2052952},{"address":3237432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":67}],"party_address":3214068,"script_address":0},{"address":3237472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":66},{"level":29,"species":67}],"party_address":3214076,"script_address":0},{"address":3237512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":66},{"level":31,"species":67},{"level":31,"species":67}],"party_address":3214092,"script_address":0},{"address":3237552,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":66},{"level":33,"species":67},{"level":33,"species":67},{"level":33,"species":68}],"party_address":3214116,"script_address":0},{"address":3237592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":335},{"level":26,"species":67}],"party_address":3214148,"script_address":2557758},{"address":3237632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214164,"script_address":2046662},{"address":3237672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":336}],"party_address":3214172,"script_address":2315359},{"address":3237712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[98,86,209,43],"species":337},{"level":17,"moves":[12,95,103,0],"species":100}],"party_address":3214180,"script_address":2167608},{"address":3237752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":286},{"level":31,"species":41}],"party_address":3214212,"script_address":2323445},{"address":3237792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3214228,"script_address":2324458},{"address":3237832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":100},{"level":17,"species":81}],"party_address":3214236,"script_address":2167639},{"address":3237872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":337},{"level":30,"species":371}],"party_address":3214252,"script_address":2068709},{"address":3237912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81},{"level":15,"species":370}],"party_address":3214268,"script_address":2058956},{"address":3237952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":81},{"level":25,"species":370},{"level":25,"species":81}],"party_address":3214284,"script_address":0},{"address":3237992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81},{"level":28,"species":371},{"level":28,"species":81}],"party_address":3214308,"script_address":0},{"address":3238032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":82},{"level":31,"species":371},{"level":31,"species":82}],"party_address":3214332,"script_address":0},{"address":3238072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82},{"level":34,"species":372},{"level":34,"species":82}],"party_address":3214356,"script_address":0},{"address":3238112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214380,"script_address":2103394},{"address":3238152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":218},{"level":22,"species":218}],"party_address":3214388,"script_address":2103601},{"address":3238192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214404,"script_address":2103446},{"address":3238232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214412,"script_address":2103570},{"address":3238272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214420,"script_address":2103477},{"address":3238312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309}],"party_address":3214428,"script_address":2052075},{"address":3238352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":218},{"level":26,"species":309}],"party_address":3214444,"script_address":0},{"address":3238392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310}],"party_address":3214460,"script_address":0},{"address":3238432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":218},{"level":32,"species":310}],"party_address":3214476,"script_address":0},{"address":3238472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":219},{"level":35,"species":310}],"party_address":3214492,"script_address":0},{"address":3238512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,28,40,163],"species":27}],"party_address":3214508,"script_address":2046366},{"address":3238552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":21,"moves":[229,189,60,61],"species":318},{"level":21,"moves":[40,28,10,91],"species":27},{"level":21,"moves":[229,189,60,61],"species":318}],"party_address":3214524,"script_address":2046428},{"address":3238592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":299}],"party_address":3214572,"script_address":2049829},{"address":3238632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27},{"level":18,"species":299}],"party_address":3214580,"script_address":2051903},{"address":3238672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":317}],"party_address":3214596,"script_address":2557005},{"address":3238712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":288},{"level":20,"species":304}],"party_address":3214604,"script_address":2310199},{"address":3238752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3214620,"script_address":2310337},{"address":3238792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27}],"party_address":3214628,"script_address":2046600},{"address":3238832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":288},{"level":26,"species":304}],"party_address":3214636,"script_address":0},{"address":3238872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":289},{"level":29,"species":305}],"party_address":3214652,"script_address":0},{"address":3238912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":305},{"level":31,"species":289}],"party_address":3214668,"script_address":0},{"address":3238952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":28},{"level":34,"species":289}],"party_address":3214692,"script_address":0},{"address":3238992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":311}],"party_address":3214716,"script_address":2061044},{"address":3239032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":290},{"level":24,"species":291},{"level":24,"species":292}],"party_address":3214724,"script_address":2061075},{"address":3239072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":290},{"level":27,"species":293},{"level":27,"species":294}],"party_address":3214748,"script_address":2061106},{"address":3239112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":311},{"level":27,"species":311},{"level":27,"species":311}],"party_address":3214772,"script_address":2065541},{"address":3239152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":294},{"level":16,"species":292}],"party_address":3214796,"script_address":2057595},{"address":3239192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":311},{"level":31,"species":311}],"party_address":3214812,"script_address":0},{"address":3239232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":311},{"level":34,"species":311},{"level":34,"species":312}],"party_address":3214836,"script_address":0},{"address":3239272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":311},{"level":36,"species":290},{"level":36,"species":311},{"level":36,"species":312}],"party_address":3214860,"script_address":0},{"address":3239312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":311},{"level":38,"species":294},{"level":38,"species":311},{"level":38,"species":312},{"level":38,"species":292}],"party_address":3214892,"script_address":0},{"address":3239352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[237,0,0,0],"species":63}],"party_address":3214932,"script_address":2038374},{"address":3239392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3214948,"script_address":2244488},{"address":3239432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":392}],"party_address":3214956,"script_address":2244519},{"address":3239472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3214964,"script_address":2244550},{"address":3239512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":392},{"level":26,"species":393}],"party_address":3214972,"script_address":2314189},{"address":3239552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3214996,"script_address":2564698},{"address":3239592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":349}],"party_address":3215012,"script_address":2068179},{"address":3239632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":64},{"level":33,"species":349}],"party_address":3215020,"script_address":0},{"address":3239672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":64},{"level":38,"species":349}],"party_address":3215036,"script_address":0},{"address":3239712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3215052,"script_address":0},{"address":3239752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":349},{"level":45,"species":65}],"party_address":3215068,"script_address":0},{"address":3239792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[237,0,0,0],"species":63}],"party_address":3215084,"script_address":2038405},{"address":3239832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3215100,"script_address":2244581},{"address":3239872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":178}],"party_address":3215108,"script_address":2244612},{"address":3239912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3215116,"script_address":2244643},{"address":3239952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":202},{"level":26,"species":177},{"level":26,"species":64}],"party_address":3215124,"script_address":2314220},{"address":3239992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":393},{"level":41,"species":178}],"party_address":3215148,"script_address":2564760},{"address":3240032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":64},{"level":30,"species":348}],"party_address":3215164,"script_address":2068289},{"address":3240072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":64},{"level":34,"species":348}],"party_address":3215180,"script_address":0},{"address":3240112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":64},{"level":37,"species":348}],"party_address":3215196,"script_address":0},{"address":3240152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":64},{"level":40,"species":348}],"party_address":3215212,"script_address":0},{"address":3240192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":348},{"level":43,"species":65}],"party_address":3215228,"script_address":0},{"address":3240232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338}],"party_address":3215244,"script_address":2067174},{"address":3240272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":338},{"level":44,"species":338}],"party_address":3215252,"script_address":2360864},{"address":3240312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":380}],"party_address":3215268,"script_address":2360895},{"address":3240352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":338}],"party_address":3215276,"script_address":0},{"address":3240392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[29,28,60,154],"species":289},{"level":36,"moves":[98,209,60,46],"species":338}],"party_address":3215284,"script_address":0},{"address":3240432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[29,28,60,154],"species":289},{"level":39,"moves":[98,209,60,0],"species":338}],"party_address":3215316,"script_address":0},{"address":3240472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[29,28,60,154],"species":289},{"level":41,"moves":[154,50,93,244],"species":55},{"level":41,"moves":[98,209,60,46],"species":338}],"party_address":3215348,"script_address":0},{"address":3240512,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,38,28,242],"species":287},{"level":48,"moves":[3,104,207,70],"species":300},{"level":46,"moves":[73,185,46,178],"species":345},{"level":48,"moves":[57,14,70,7],"species":327},{"level":49,"moves":[76,157,14,163],"species":376}],"party_address":3215396,"script_address":2274753},{"address":3240552,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[69,109,174,182],"species":362},{"level":49,"moves":[247,32,5,185],"species":378},{"level":50,"moves":[247,104,101,185],"species":322},{"level":49,"moves":[247,94,85,7],"species":378},{"level":51,"moves":[247,58,157,89],"species":362}],"party_address":3215476,"script_address":2275380},{"address":3240592,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[227,34,2,45],"species":342},{"level":50,"moves":[113,242,196,58],"species":347},{"level":52,"moves":[213,38,2,59],"species":342},{"level":52,"moves":[247,153,2,58],"species":347},{"level":53,"moves":[57,34,58,73],"species":343}],"party_address":3215556,"script_address":2276062},{"address":3240632,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[61,81,182,38],"species":396},{"level":54,"moves":[38,225,93,76],"species":359},{"level":53,"moves":[108,93,57,34],"species":230},{"level":53,"moves":[53,242,225,89],"species":334},{"level":55,"moves":[53,81,157,242],"species":397}],"party_address":3215636,"script_address":2276724},{"address":3240672,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":12,"moves":[33,111,88,61],"species":74},{"level":12,"moves":[33,111,88,61],"species":74},{"level":15,"moves":[79,106,33,61],"species":320}],"party_address":3215716,"script_address":2187976},{"address":3240712,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[2,67,69,83],"species":66},{"level":16,"moves":[8,113,115,83],"species":356},{"level":19,"moves":[36,233,179,83],"species":335}],"party_address":3215764,"script_address":2095066},{"address":3240752,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":20,"moves":[205,209,120,95],"species":100},{"level":20,"moves":[95,43,98,80],"species":337},{"level":22,"moves":[48,95,86,49],"species":82},{"level":24,"moves":[98,86,95,80],"species":338}],"party_address":3215812,"script_address":2167181},{"address":3240792,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[59,36,222,241],"species":339},{"level":24,"moves":[59,123,113,241],"species":218},{"level":26,"moves":[59,33,241,213],"species":340},{"level":29,"moves":[59,241,34,213],"species":321}],"party_address":3215876,"script_address":2103186},{"address":3240832,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[42,60,7,227],"species":308},{"level":27,"moves":[163,7,227,185],"species":365},{"level":29,"moves":[163,187,7,29],"species":289},{"level":31,"moves":[68,25,7,185],"species":366}],"party_address":3215940,"script_address":2129756},{"address":3240872,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[195,119,219,76],"species":358},{"level":29,"moves":[241,76,76,235],"species":369},{"level":30,"moves":[55,48,182,76],"species":310},{"level":31,"moves":[28,31,211,76],"species":227},{"level":33,"moves":[89,225,93,76],"species":359}],"party_address":3216004,"script_address":2202062},{"address":3240912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[89,246,94,113],"species":319},{"level":41,"moves":[94,241,109,91],"species":178},{"level":42,"moves":[113,94,95,91],"species":348},{"level":42,"moves":[241,76,94,53],"species":349}],"party_address":3216084,"script_address":0},{"address":3240952,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[96,213,186,175],"species":325},{"level":41,"moves":[240,96,133,89],"species":324},{"level":43,"moves":[227,34,62,96],"species":342},{"level":43,"moves":[96,152,13,43],"species":327},{"level":46,"moves":[96,104,58,156],"species":230}],"party_address":3216148,"script_address":2262245},{"address":3240992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":392}],"party_address":3216228,"script_address":2054242},{"address":3241032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3216236,"script_address":2554598},{"address":3241072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":339},{"level":15,"species":43},{"level":15,"species":309}],"party_address":3216244,"script_address":2554629},{"address":3241112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":356}],"party_address":3216268,"script_address":0},{"address":3241152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":393},{"level":29,"species":356}],"party_address":3216284,"script_address":0},{"address":3241192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":393},{"level":32,"species":357}],"party_address":3216300,"script_address":0},{"address":3241232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":393},{"level":34,"species":378},{"level":34,"species":357}],"party_address":3216316,"script_address":0},{"address":3241272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":306}],"party_address":3216340,"script_address":2054490},{"address":3241312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":306},{"level":16,"species":292}],"party_address":3216348,"script_address":2554660},{"address":3241352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":370}],"party_address":3216364,"script_address":0},{"address":3241392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":306},{"level":29,"species":371}],"party_address":3216380,"script_address":0},{"address":3241432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":307},{"level":32,"species":371}],"party_address":3216396,"script_address":0},{"address":3241472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":307},{"level":35,"species":372}],"party_address":3216412,"script_address":0},{"address":3241512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[95,60,146,42],"species":308},{"level":32,"moves":[8,25,47,185],"species":366}],"party_address":3216428,"script_address":0},{"address":3241552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[45,39,29,60],"species":288},{"level":17,"moves":[33,116,36,0],"species":335}],"party_address":3216460,"script_address":0},{"address":3241592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[45,39,29,60],"species":288},{"level":30,"moves":[33,116,36,0],"species":335}],"party_address":3216492,"script_address":0},{"address":3241632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[45,39,29,60],"species":288},{"level":33,"moves":[33,116,36,0],"species":335}],"party_address":3216524,"script_address":0},{"address":3241672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[45,39,29,60],"species":289},{"level":36,"moves":[33,116,36,0],"species":335}],"party_address":3216556,"script_address":0},{"address":3241712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[45,39,29,60],"species":289},{"level":38,"moves":[33,116,36,0],"species":336}],"party_address":3216588,"script_address":0},{"address":3241752,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":16,"species":304},{"level":16,"species":288}],"party_address":3216620,"script_address":2045785},{"address":3241792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":15,"species":315}],"party_address":3216636,"script_address":2026353},{"address":3241832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[18,204,185,215],"species":315},{"level":36,"moves":[18,204,185,215],"species":315},{"level":40,"moves":[18,204,185,215],"species":315},{"level":12,"moves":[18,204,185,215],"species":315},{"level":30,"moves":[18,204,185,215],"species":315},{"level":42,"moves":[18,204,185,215],"species":316}],"party_address":3216644,"script_address":2360833},{"address":3241872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":315}],"party_address":3216740,"script_address":0},{"address":3241912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":315}],"party_address":3216748,"script_address":0},{"address":3241952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316}],"party_address":3216756,"script_address":0},{"address":3241992,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":316}],"party_address":3216764,"script_address":0},{"address":3242032,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":17,"species":363}],"party_address":3216772,"script_address":2045890},{"address":3242072,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":25}],"party_address":3216780,"script_address":2067143},{"address":3242112,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":350},{"level":37,"species":183},{"level":39,"species":184}],"party_address":3216788,"script_address":2265832},{"address":3242152,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":353},{"level":14,"species":354}],"party_address":3216812,"script_address":2038890},{"address":3242192,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":26,"species":353},{"level":26,"species":354}],"party_address":3216828,"script_address":0},{"address":3242232,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":353},{"level":29,"species":354}],"party_address":3216844,"script_address":0},{"address":3242272,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":353},{"level":32,"species":354}],"party_address":3216860,"script_address":0},{"address":3242312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":353},{"level":35,"species":354}],"party_address":3216876,"script_address":0},{"address":3242352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":336}],"party_address":3216892,"script_address":2052811},{"address":3242392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[36,26,28,91],"species":336}],"party_address":3216900,"script_address":0},{"address":3242432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[36,26,28,91],"species":336}],"party_address":3216916,"script_address":0},{"address":3242472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[36,187,28,91],"species":336}],"party_address":3216932,"script_address":0},{"address":3242512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[36,187,28,91],"species":336}],"party_address":3216948,"script_address":0},{"address":3242552,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[136,96,93,197],"species":356}],"party_address":3216964,"script_address":2046100},{"address":3242592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":356},{"level":21,"species":335}],"party_address":3216980,"script_address":2304277},{"address":3242632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":356},{"level":30,"species":335}],"party_address":3216996,"script_address":0},{"address":3242672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":357},{"level":33,"species":336}],"party_address":3217012,"script_address":0},{"address":3242712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":357},{"level":36,"species":336}],"party_address":3217028,"script_address":0},{"address":3242752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":357},{"level":39,"species":336}],"party_address":3217044,"script_address":0},{"address":3242792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":286}],"party_address":3217060,"script_address":2024678},{"address":3242832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":288},{"level":7,"species":298}],"party_address":3217068,"script_address":2029684},{"address":3242872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[33,0,0,0],"species":74}],"party_address":3217084,"script_address":2188154},{"address":3242912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3217100,"script_address":2188185},{"address":3242952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":66}],"party_address":3217116,"script_address":2054180},{"address":3242992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[29,28,45,85],"species":288},{"level":17,"moves":[133,124,25,1],"species":367}],"party_address":3217124,"script_address":2167670},{"address":3243032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[213,58,85,53],"species":366},{"level":43,"moves":[29,182,5,92],"species":362}],"party_address":3217156,"script_address":2332778},{"address":3243072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,94,85,91],"species":394},{"level":43,"moves":[89,247,76,24],"species":366}],"party_address":3217188,"script_address":2332809},{"address":3243112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":332}],"party_address":3217220,"script_address":2050594},{"address":3243152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3217228,"script_address":2050625},{"address":3243192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":287}],"party_address":3217236,"script_address":0},{"address":3243232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":305},{"level":30,"species":287}],"party_address":3217244,"script_address":0},{"address":3243272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":305},{"level":29,"species":289},{"level":33,"species":287}],"party_address":3217260,"script_address":0},{"address":3243312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":32,"species":289},{"level":36,"species":287}],"party_address":3217284,"script_address":0},{"address":3243352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":16,"species":288}],"party_address":3217308,"script_address":2553792},{"address":3243392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":3,"species":304}],"party_address":3217324,"script_address":2024926},{"address":3243432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":382},{"level":13,"species":337}],"party_address":3217340,"script_address":2039000},{"address":3243472,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[240,67,38,59],"species":314},{"level":55,"moves":[92,56,188,58],"species":73},{"level":56,"moves":[202,57,73,104],"species":297},{"level":56,"moves":[89,57,133,63],"species":324},{"level":56,"moves":[93,89,63,57],"species":130},{"level":58,"moves":[105,57,58,92],"species":329}],"party_address":3217356,"script_address":2277575},{"address":3243512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":10,"species":72},{"level":15,"species":129}],"party_address":3217452,"script_address":2026322},{"address":3243552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":6,"species":129},{"level":7,"species":129}],"party_address":3217476,"script_address":2029653},{"address":3243592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":129},{"level":17,"species":118},{"level":18,"species":323}],"party_address":3217500,"script_address":2052185},{"address":3243632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":10,"species":129},{"level":7,"species":72},{"level":10,"species":129}],"party_address":3217524,"script_address":2034247},{"address":3243672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72}],"party_address":3217548,"script_address":2034357},{"address":3243712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72},{"level":14,"species":313},{"level":11,"species":72},{"level":14,"species":313}],"party_address":3217556,"script_address":2038546},{"address":3243752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3217588,"script_address":2052216},{"address":3243792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3217596,"script_address":2058894},{"address":3243832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":72}],"party_address":3217612,"script_address":2058925},{"address":3243872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":73}],"party_address":3217620,"script_address":2036183},{"address":3243912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":27,"species":130},{"level":27,"species":130}],"party_address":3217636,"script_address":0},{"address":3243952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":130},{"level":26,"species":330},{"level":26,"species":72},{"level":29,"species":130}],"party_address":3217660,"script_address":0},{"address":3243992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":130},{"level":30,"species":330},{"level":30,"species":73},{"level":31,"species":130}],"party_address":3217692,"script_address":0},{"address":3244032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":130},{"level":33,"species":331},{"level":33,"species":130},{"level":35,"species":73}],"party_address":3217724,"script_address":0},{"address":3244072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":129},{"level":21,"species":130},{"level":23,"species":130},{"level":26,"species":130},{"level":30,"species":130},{"level":35,"species":130}],"party_address":3217756,"script_address":2073670},{"address":3244112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":100},{"level":6,"species":100},{"level":14,"species":81}],"party_address":3217804,"script_address":2038577},{"address":3244152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81}],"party_address":3217828,"script_address":2038608},{"address":3244192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217844,"script_address":2038639},{"address":3244232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":81}],"party_address":3217852,"script_address":0},{"address":3244272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":81}],"party_address":3217860,"script_address":0},{"address":3244312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82}],"party_address":3217868,"script_address":0},{"address":3244352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":82}],"party_address":3217876,"script_address":0},{"address":3244392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217884,"script_address":2038780},{"address":3244432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81},{"level":6,"species":100}],"party_address":3217892,"script_address":2038749},{"address":3244472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81}],"party_address":3217916,"script_address":0},{"address":3244512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":81}],"party_address":3217924,"script_address":0},{"address":3244552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82}],"party_address":3217932,"script_address":0},{"address":3244592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":82}],"party_address":3217940,"script_address":0},{"address":3244632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217948,"script_address":2057375},{"address":3244672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217956,"script_address":0},{"address":3244712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3217964,"script_address":0},{"address":3244752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3217972,"script_address":0},{"address":3244792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3217980,"script_address":0},{"address":3244832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217988,"script_address":2057485},{"address":3244872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217996,"script_address":0},{"address":3244912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3218004,"script_address":0},{"address":3244952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3218012,"script_address":0},{"address":3244992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3218020,"script_address":0},{"address":3245032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218028,"script_address":2070582},{"address":3245072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":288},{"level":25,"species":337}],"party_address":3218044,"script_address":2340077},{"address":3245112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218060,"script_address":2071332},{"address":3245152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218068,"script_address":2070380},{"address":3245192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218084,"script_address":2072978},{"address":3245232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218100,"script_address":0},{"address":3245272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218108,"script_address":0},{"address":3245312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218116,"script_address":0},{"address":3245352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218124,"script_address":0},{"address":3245392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218132,"script_address":2070318},{"address":3245432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218140,"script_address":2070613},{"address":3245472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218156,"script_address":2073545},{"address":3245512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218164,"script_address":2071442},{"address":3245552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":309},{"level":33,"species":120}],"party_address":3218172,"script_address":2073009},{"address":3245592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218188,"script_address":0},{"address":3245632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218196,"script_address":0},{"address":3245672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218204,"script_address":0},{"address":3245712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218212,"script_address":0},{"address":3245752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":359},{"level":37,"species":359}],"party_address":3218220,"script_address":2292701},{"address":3245792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":359}],"party_address":3218236,"script_address":0},{"address":3245832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":359},{"level":44,"species":359}],"party_address":3218252,"script_address":0},{"address":3245872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":395},{"level":46,"species":359},{"level":46,"species":359}],"party_address":3218268,"script_address":0},{"address":3245912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":49,"species":359},{"level":49,"species":359},{"level":49,"species":396}],"party_address":3218292,"script_address":0},{"address":3245952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[225,29,116,52],"species":395}],"party_address":3218316,"script_address":2074182},{"address":3245992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309}],"party_address":3218332,"script_address":2059066},{"address":3246032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":369}],"party_address":3218340,"script_address":2061450},{"address":3246072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":305}],"party_address":3218356,"script_address":2061481},{"address":3246112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":84},{"level":27,"species":227},{"level":27,"species":369}],"party_address":3218364,"script_address":2202267},{"address":3246152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":227}],"party_address":3218388,"script_address":2202391},{"address":3246192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":369},{"level":33,"species":178}],"party_address":3218396,"script_address":2070085},{"address":3246232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":84},{"level":29,"species":310}],"party_address":3218412,"script_address":2202298},{"address":3246272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":309},{"level":28,"species":177}],"party_address":3218428,"script_address":2065338},{"address":3246312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":358}],"party_address":3218444,"script_address":2065369},{"address":3246352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":305},{"level":36,"species":310},{"level":36,"species":178}],"party_address":3218452,"script_address":2563257},{"address":3246392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":305}],"party_address":3218476,"script_address":2059097},{"address":3246432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":177},{"level":32,"species":358}],"party_address":3218492,"script_address":0},{"address":3246472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":177},{"level":35,"species":359}],"party_address":3218508,"script_address":0},{"address":3246512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":177},{"level":38,"species":359}],"party_address":3218524,"script_address":0},{"address":3246552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":178}],"party_address":3218540,"script_address":0},{"address":3246592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":177},{"level":33,"species":305}],"party_address":3218556,"script_address":2074151},{"address":3246632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":369}],"party_address":3218572,"script_address":2073981},{"address":3246672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302}],"party_address":3218580,"script_address":2061512},{"address":3246712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302},{"level":25,"species":109}],"party_address":3218588,"script_address":2061543},{"address":3246752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,89,0,0],"species":319},{"level":43,"moves":[85,89,0,0],"species":171}],"party_address":3218604,"script_address":2335578},{"address":3246792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3218636,"script_address":2341860},{"address":3246832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,124,120],"species":109}],"party_address":3218644,"script_address":2050766},{"address":3246872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":109},{"level":18,"species":302}],"party_address":3218692,"script_address":2050876},{"address":3246912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[139,33,124,120],"species":109},{"level":24,"moves":[139,33,124,0],"species":109},{"level":24,"moves":[139,33,124,120],"species":109},{"level":26,"moves":[33,124,0,0],"species":109}],"party_address":3218708,"script_address":0},{"address":3246952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,0],"species":109},{"level":29,"moves":[33,124,0,0],"species":109}],"party_address":3218772,"script_address":0},{"address":3246992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":32,"moves":[33,124,0,0],"species":109}],"party_address":3218836,"script_address":0},{"address":3247032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[139,33,124,0],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":35,"moves":[33,124,0,0],"species":110}],"party_address":3218900,"script_address":0},{"address":3247072,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218964,"script_address":2095313},{"address":3247112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218972,"script_address":2095351},{"address":3247152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":335}],"party_address":3218980,"script_address":2053062},{"address":3247192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":356}],"party_address":3218996,"script_address":2557727},{"address":3247232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3219004,"script_address":2557789},{"address":3247272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3219012,"script_address":0},{"address":3247312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":356},{"level":29,"species":335}],"party_address":3219028,"script_address":0},{"address":3247352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":357},{"level":32,"species":336}],"party_address":3219044,"script_address":0},{"address":3247392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":357},{"level":35,"species":336}],"party_address":3219060,"script_address":0},{"address":3247432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":19,"moves":[52,33,222,241],"species":339}],"party_address":3219076,"script_address":2050656},{"address":3247472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":363},{"level":28,"species":313}],"party_address":3219092,"script_address":2065713},{"address":3247512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[240,55,87,96],"species":385}],"party_address":3219108,"script_address":2065744},{"address":3247552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[52,33,222,241],"species":339}],"party_address":3219124,"script_address":0},{"address":3247592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[52,36,222,241],"species":339}],"party_address":3219140,"script_address":0},{"address":3247632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[73,72,64,241],"species":363},{"level":34,"moves":[53,36,222,241],"species":339}],"party_address":3219156,"script_address":0},{"address":3247672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[73,202,76,241],"species":363},{"level":37,"moves":[53,36,89,241],"species":340}],"party_address":3219188,"script_address":0},{"address":3247712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":313}],"party_address":3219220,"script_address":2033633},{"address":3247752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3219236,"script_address":2033664},{"address":3247792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":313}],"party_address":3219244,"script_address":2034216},{"address":3247832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":118}],"party_address":3219252,"script_address":2034620},{"address":3247872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219268,"script_address":2034651},{"address":3247912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":116},{"level":25,"species":183}],"party_address":3219276,"script_address":2034838},{"address":3247952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219292,"script_address":2034869},{"address":3247992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":118},{"level":24,"species":309},{"level":24,"species":118}],"party_address":3219300,"script_address":2035808},{"address":3248032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3219324,"script_address":2069240},{"address":3248072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":183}],"party_address":3219332,"script_address":2069350},{"address":3248112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219340,"script_address":2069851},{"address":3248152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219348,"script_address":2069882},{"address":3248192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":183},{"level":33,"species":341}],"party_address":3219356,"script_address":2070225},{"address":3248232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":118}],"party_address":3219372,"script_address":2070256},{"address":3248272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":118},{"level":33,"species":341}],"party_address":3219380,"script_address":2073260},{"address":3248312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219396,"script_address":2073421},{"address":3248352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219404,"script_address":2073452},{"address":3248392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":184}],"party_address":3219412,"script_address":2073639},{"address":3248432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219420,"script_address":2070349},{"address":3248472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219436,"script_address":2073888},{"address":3248512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":116},{"level":33,"species":117}],"party_address":3219444,"script_address":2073919},{"address":3248552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":171},{"level":34,"species":310}],"party_address":3219460,"script_address":0},{"address":3248592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219476,"script_address":2074120},{"address":3248632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":119}],"party_address":3219492,"script_address":2071676},{"address":3248672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":313}],"party_address":3219500,"script_address":0},{"address":3248712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":313}],"party_address":3219508,"script_address":0},{"address":3248752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":120},{"level":43,"species":313}],"party_address":3219516,"script_address":0},{"address":3248792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":313},{"level":45,"species":121}],"party_address":3219532,"script_address":0},{"address":3248832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[91,28,40,163],"species":27},{"level":22,"moves":[229,189,60,61],"species":318}],"party_address":3219556,"script_address":2046397},{"address":3248872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[28,40,163,91],"species":27},{"level":22,"moves":[205,61,39,111],"species":183}],"party_address":3219588,"script_address":2046459},{"address":3248912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":304},{"level":17,"species":296}],"party_address":3219620,"script_address":2049860},{"address":3248952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":183},{"level":18,"species":296}],"party_address":3219636,"script_address":2051934},{"address":3248992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":315},{"level":23,"species":358}],"party_address":3219652,"script_address":2557036},{"address":3249032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":306},{"level":19,"species":43},{"level":19,"species":358}],"party_address":3219668,"script_address":2310092},{"address":3249072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[194,219,68,243],"species":202}],"party_address":3219692,"script_address":2315855},{"address":3249112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":306},{"level":17,"species":183}],"party_address":3219708,"script_address":2046631},{"address":3249152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":306},{"level":25,"species":44},{"level":25,"species":358}],"party_address":3219724,"script_address":0},{"address":3249192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":307},{"level":28,"species":44},{"level":28,"species":358}],"party_address":3219748,"script_address":0},{"address":3249232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307},{"level":31,"species":44},{"level":31,"species":358}],"party_address":3219772,"script_address":0},{"address":3249272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":307},{"level":40,"species":45},{"level":40,"species":359}],"party_address":3219796,"script_address":0},{"address":3249312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":353},{"level":15,"species":354}],"party_address":3219820,"script_address":0},{"address":3249352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":353},{"level":27,"species":354}],"party_address":3219836,"script_address":0},{"address":3249392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":298},{"level":6,"species":295}],"party_address":3219852,"script_address":0},{"address":3249432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":292},{"level":26,"species":294}],"party_address":3219868,"script_address":0},{"address":3249472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":353},{"level":9,"species":354}],"party_address":3219884,"script_address":0},{"address":3249512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[101,50,0,0],"species":361},{"level":10,"moves":[71,73,0,0],"species":306}],"party_address":3219900,"script_address":0},{"address":3249552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":353},{"level":30,"species":354}],"party_address":3219932,"script_address":0},{"address":3249592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[209,12,57,14],"species":353},{"level":33,"moves":[209,12,204,14],"species":354}],"party_address":3219948,"script_address":0},{"address":3249632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,12,57,14],"species":353},{"level":36,"moves":[87,12,204,14],"species":354}],"party_address":3219980,"script_address":0},{"address":3249672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":309},{"level":12,"species":66}],"party_address":3220012,"script_address":2035839},{"address":3249712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309}],"party_address":3220028,"script_address":2035870},{"address":3249752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":67}],"party_address":3220036,"script_address":2069913},{"address":3249792,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":66},{"level":11,"species":72}],"party_address":3220052,"script_address":2543939},{"address":3249832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":73},{"level":44,"species":67}],"party_address":3220076,"script_address":2360255},{"address":3249872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":66},{"level":43,"species":310},{"level":43,"species":67}],"party_address":3220092,"script_address":2360286},{"address":3249912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":341},{"level":25,"species":67}],"party_address":3220116,"script_address":2340984},{"address":3249952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":309},{"level":36,"species":72},{"level":36,"species":67}],"party_address":3220132,"script_address":0},{"address":3249992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":310},{"level":39,"species":72},{"level":39,"species":67}],"party_address":3220156,"script_address":0},{"address":3250032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":310},{"level":42,"species":72},{"level":42,"species":67}],"party_address":3220180,"script_address":0},{"address":3250072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":310},{"level":45,"species":67},{"level":45,"species":73}],"party_address":3220204,"script_address":0},{"address":3250112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3220228,"script_address":2103632},{"address":3250152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[175,96,216,213],"species":328},{"level":39,"moves":[175,96,216,213],"species":328}],"party_address":3220236,"script_address":2265863},{"address":3250192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":376}],"party_address":3220268,"script_address":2068647},{"address":3250232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[92,87,120,188],"species":109}],"party_address":3220276,"script_address":2068616},{"address":3250272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[241,55,53,76],"species":385}],"party_address":3220292,"script_address":2068585},{"address":3250312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":338},{"level":33,"species":68}],"party_address":3220308,"script_address":2070116},{"address":3250352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":341}],"party_address":3220324,"script_address":2074337},{"address":3250392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[44,46,86,85],"species":338}],"party_address":3220340,"script_address":2074306},{"address":3250432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":356},{"level":33,"species":336}],"party_address":3220356,"script_address":2074275},{"address":3250472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3220372,"script_address":2074244},{"address":3250512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":170},{"level":33,"species":336}],"party_address":3220380,"script_address":2074043},{"address":3250552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":296},{"level":14,"species":299}],"party_address":3220396,"script_address":2038436},{"address":3250592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":380},{"level":18,"species":379}],"party_address":3220412,"script_address":2053172},{"address":3250632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":340},{"level":38,"species":287},{"level":40,"species":42}],"party_address":3220428,"script_address":0},{"address":3250672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":299}],"party_address":3220452,"script_address":0},{"address":3250712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":299}],"party_address":3220468,"script_address":0},{"address":3250752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":299}],"party_address":3220484,"script_address":0},{"address":3250792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":297},{"level":35,"species":300}],"party_address":3220500,"script_address":0},{"address":3250832,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[76,219,225,93],"species":359},{"level":43,"moves":[47,18,204,185],"species":316},{"level":44,"moves":[89,73,202,92],"species":363},{"level":41,"moves":[48,85,161,103],"species":82},{"level":45,"moves":[104,91,94,248],"species":394}],"party_address":3220516,"script_address":2332529},{"address":3250872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220596,"script_address":2025759},{"address":3250912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309},{"level":20,"species":278}],"party_address":3220604,"script_address":2039798},{"address":3250952,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310},{"level":31,"species":278}],"party_address":3220628,"script_address":2060578},{"address":3250992,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220652,"script_address":2025703},{"address":3251032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220660,"script_address":2039742},{"address":3251072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220684,"script_address":2060522},{"address":3251112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220708,"script_address":2025731},{"address":3251152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220716,"script_address":2039770},{"address":3251192,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220740,"script_address":2060550},{"address":3251232,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220764,"script_address":2025675},{"address":3251272,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":218},{"level":20,"species":278}],"party_address":3220772,"script_address":2039622},{"address":3251312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":296},{"level":31,"species":278}],"party_address":3220796,"script_address":2060420},{"address":3251352,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220820,"script_address":2025619},{"address":3251392,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220828,"script_address":2039566},{"address":3251432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220852,"script_address":2060364},{"address":3251472,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220876,"script_address":2025647},{"address":3251512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220884,"script_address":2039594},{"address":3251552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220908,"script_address":2060392},{"address":3251592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":370},{"level":11,"species":288},{"level":11,"species":382},{"level":11,"species":286},{"level":11,"species":304},{"level":11,"species":335}],"party_address":3220932,"script_address":2057155},{"address":3251632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":127}],"party_address":3220980,"script_address":2068678},{"address":3251672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[153,115,113,94],"species":348},{"level":43,"moves":[153,115,113,247],"species":349}],"party_address":3220988,"script_address":2334468},{"address":3251712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":371},{"level":22,"species":289},{"level":22,"species":382},{"level":22,"species":287},{"level":22,"species":305},{"level":22,"species":335}],"party_address":3221020,"script_address":0},{"address":3251752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":371},{"level":25,"species":289},{"level":25,"species":382},{"level":25,"species":287},{"level":25,"species":305},{"level":25,"species":336}],"party_address":3221068,"script_address":0},{"address":3251792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":371},{"level":28,"species":289},{"level":28,"species":382},{"level":28,"species":287},{"level":28,"species":305},{"level":28,"species":336}],"party_address":3221116,"script_address":0},{"address":3251832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":371},{"level":31,"species":289},{"level":31,"species":383},{"level":31,"species":287},{"level":31,"species":305},{"level":31,"species":336}],"party_address":3221164,"script_address":0},{"address":3251872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":306},{"level":11,"species":183},{"level":11,"species":363},{"level":11,"species":315},{"level":11,"species":118}],"party_address":3221212,"script_address":2057265},{"address":3251912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":322},{"level":43,"species":376}],"party_address":3221260,"script_address":2334499},{"address":3251952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":28}],"party_address":3221276,"script_address":2341891},{"address":3251992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":309},{"level":22,"species":306},{"level":22,"species":183},{"level":22,"species":363},{"level":22,"species":315},{"level":22,"species":118}],"party_address":3221284,"script_address":0},{"address":3252032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":310},{"level":25,"species":307},{"level":25,"species":183},{"level":25,"species":363},{"level":25,"species":316},{"level":25,"species":118}],"party_address":3221332,"script_address":0},{"address":3252072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":310},{"level":28,"species":307},{"level":28,"species":183},{"level":28,"species":363},{"level":28,"species":316},{"level":28,"species":118}],"party_address":3221380,"script_address":0},{"address":3252112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":310},{"level":31,"species":307},{"level":31,"species":184},{"level":31,"species":363},{"level":31,"species":316},{"level":31,"species":119}],"party_address":3221428,"script_address":0},{"address":3252152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3221476,"script_address":2061230},{"address":3252192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":298},{"level":28,"species":299},{"level":28,"species":296}],"party_address":3221484,"script_address":2065479},{"address":3252232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":345}],"party_address":3221508,"script_address":2563288},{"address":3252272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307}],"party_address":3221516,"script_address":0},{"address":3252312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307}],"party_address":3221524,"script_address":0},{"address":3252352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":307}],"party_address":3221532,"script_address":0},{"address":3252392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":317},{"level":39,"species":307}],"party_address":3221540,"script_address":0},{"address":3252432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":44},{"level":26,"species":363}],"party_address":3221556,"script_address":2061340},{"address":3252472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":295},{"level":28,"species":296},{"level":28,"species":299}],"party_address":3221572,"script_address":2065510},{"address":3252512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":358},{"level":38,"species":363}],"party_address":3221596,"script_address":2563226},{"address":3252552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":44},{"level":30,"species":363}],"party_address":3221612,"script_address":0},{"address":3252592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":44},{"level":33,"species":363}],"party_address":3221628,"script_address":0},{"address":3252632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":44},{"level":36,"species":363}],"party_address":3221644,"script_address":0},{"address":3252672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":182},{"level":39,"species":363}],"party_address":3221660,"script_address":0},{"address":3252712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":81}],"party_address":3221676,"script_address":2310306},{"address":3252752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":287},{"level":35,"species":42}],"party_address":3221684,"script_address":2327187},{"address":3252792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":313},{"level":31,"species":41}],"party_address":3221700,"script_address":0},{"address":3252832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":30,"species":41}],"party_address":3221716,"script_address":2317615},{"address":3252872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":286},{"level":22,"species":339}],"party_address":3221732,"script_address":2309993},{"address":3252912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3221748,"script_address":2188216},{"address":3252952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3221764,"script_address":2095389},{"address":3252992,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3221772,"script_address":2095465},{"address":3253032,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":335}],"party_address":3221780,"script_address":2095427},{"address":3253072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":356}],"party_address":3221788,"script_address":2244674},{"address":3253112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3221796,"script_address":2070287},{"address":3253152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[87,86,98,0],"species":338},{"level":32,"moves":[57,168,0,0],"species":289}],"party_address":3221804,"script_address":2070768},{"address":3253192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":73}],"party_address":3221836,"script_address":2071645},{"address":3253232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":41}],"party_address":3221844,"script_address":2304070},{"address":3253272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3221852,"script_address":2073102},{"address":3253312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":203}],"party_address":3221860,"script_address":0},{"address":3253352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":351}],"party_address":3221868,"script_address":2244705},{"address":3253392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3221876,"script_address":2244829},{"address":3253432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3221884,"script_address":2244767},{"address":3253472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":202}],"party_address":3221892,"script_address":2244798},{"address":3253512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":286}],"party_address":3221900,"script_address":2254605},{"address":3253552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221916,"script_address":2254667},{"address":3253592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3221924,"script_address":2257768},{"address":3253632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":287}],"party_address":3221932,"script_address":2257818},{"address":3253672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221940,"script_address":2257868},{"address":3253712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":177}],"party_address":3221948,"script_address":2244736},{"address":3253752,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3221956,"script_address":1978559},{"address":3253792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3221972,"script_address":1978621},{"address":3253832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":305},{"level":33,"species":307}],"party_address":3221988,"script_address":2073732},{"address":3253872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3222004,"script_address":2069651},{"address":3253912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3222012,"script_address":2572062},{"address":3253952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":20,"species":286},{"level":22,"species":339},{"level":22,"species":41}],"party_address":3222028,"script_address":2304039},{"address":3253992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":317},{"level":33,"species":371}],"party_address":3222060,"script_address":2073794},{"address":3254032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":218},{"level":15,"species":283}],"party_address":3222076,"script_address":1978590},{"address":3254072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3222092,"script_address":1978317},{"address":3254112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":287},{"level":38,"species":169},{"level":39,"species":340}],"party_address":3222108,"script_address":2351441},{"address":3254152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":287},{"level":24,"species":41},{"level":25,"species":340}],"party_address":3222132,"script_address":2303440},{"address":3254192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":4,"species":306}],"party_address":3222156,"script_address":2024895},{"address":3254232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":295},{"level":6,"species":306}],"party_address":3222172,"script_address":2029715},{"address":3254272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":183}],"party_address":3222188,"script_address":2054459},{"address":3254312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183},{"level":15,"species":306},{"level":15,"species":339}],"party_address":3222196,"script_address":2045995},{"address":3254352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":306}],"party_address":3222220,"script_address":0},{"address":3254392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":307}],"party_address":3222236,"script_address":0},{"address":3254432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":307}],"party_address":3222252,"script_address":0},{"address":3254472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":296},{"level":34,"species":307}],"party_address":3222268,"script_address":0},{"address":3254512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":43}],"party_address":3222292,"script_address":2553761},{"address":3254552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":315},{"level":14,"species":306},{"level":14,"species":183}],"party_address":3222300,"script_address":2553823},{"address":3254592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325}],"party_address":3222324,"script_address":2265615},{"address":3254632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":118},{"level":39,"species":313}],"party_address":3222332,"script_address":2265646},{"address":3254672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":290},{"level":4,"species":290}],"party_address":3222348,"script_address":2024864},{"address":3254712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290}],"party_address":3222364,"script_address":2300392},{"address":3254752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":290},{"level":8,"species":301}],"party_address":3222396,"script_address":2054211},{"address":3254792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":301},{"level":28,"species":302}],"party_address":3222412,"script_address":2061137},{"address":3254832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222428,"script_address":2061168},{"address":3254872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302}],"party_address":3222444,"script_address":2061199},{"address":3254912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":301},{"level":6,"species":301}],"party_address":3222452,"script_address":2300423},{"address":3254952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":302}],"party_address":3222468,"script_address":0},{"address":3254992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":302}],"party_address":3222476,"script_address":0},{"address":3255032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":294},{"level":31,"species":302}],"party_address":3222492,"script_address":0},{"address":3255072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":311},{"level":33,"species":302},{"level":33,"species":294},{"level":33,"species":302}],"party_address":3222516,"script_address":0},{"address":3255112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":339},{"level":17,"species":66}],"party_address":3222548,"script_address":2049688},{"address":3255152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":17,"species":74},{"level":16,"species":74}],"party_address":3222564,"script_address":2049719},{"address":3255192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":66}],"party_address":3222588,"script_address":2051841},{"address":3255232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":339}],"party_address":3222604,"script_address":2051872},{"address":3255272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":74},{"level":22,"species":320},{"level":22,"species":75}],"party_address":3222620,"script_address":2557067},{"address":3255312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74}],"party_address":3222644,"script_address":2054428},{"address":3255352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":74},{"level":20,"species":318}],"party_address":3222652,"script_address":2310061},{"address":3255392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":9,"moves":[150,55,0,0],"species":313}],"party_address":3222668,"script_address":0},{"address":3255432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[16,45,0,0],"species":310},{"level":10,"moves":[44,184,0,0],"species":286}],"party_address":3222684,"script_address":0},{"address":3255472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":16,"species":74},{"level":16,"species":66}],"party_address":3222716,"script_address":2296023},{"address":3255512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":75}],"party_address":3222740,"script_address":0},{"address":3255552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":74},{"level":27,"species":74},{"level":27,"species":75},{"level":27,"species":75}],"party_address":3222772,"script_address":0},{"address":3255592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":74},{"level":30,"species":75},{"level":30,"species":75},{"level":30,"species":75}],"party_address":3222804,"script_address":0},{"address":3255632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":76}],"party_address":3222836,"script_address":0},{"address":3255672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":316},{"level":31,"species":338}],"party_address":3222868,"script_address":0},{"address":3255712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":325}],"party_address":3222884,"script_address":0},{"address":3255752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222900,"script_address":0},{"address":3255792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":386},{"level":30,"species":387}],"party_address":3222916,"script_address":0},{"address":3255832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":386},{"level":33,"species":387}],"party_address":3222932,"script_address":0},{"address":3255872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":386},{"level":36,"species":387}],"party_address":3222948,"script_address":0},{"address":3255912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":386},{"level":39,"species":387}],"party_address":3222964,"script_address":0},{"address":3255952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":118}],"party_address":3222980,"script_address":2543970},{"address":3255992,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[53,154,185,20],"species":317}],"party_address":3222988,"script_address":2103539},{"address":3256032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[117,197,93,9],"species":356},{"level":17,"moves":[9,197,93,96],"species":356}],"party_address":3223004,"script_address":2167701},{"address":3256072,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[117,197,93,7],"species":356}],"party_address":3223036,"script_address":2103508},{"address":3256112,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[33,120,124,108],"species":109},{"level":25,"moves":[33,139,124,108],"species":109}],"party_address":3223052,"script_address":2061574},{"address":3256152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[139,120,124,108],"species":109},{"level":28,"moves":[28,104,210,14],"species":302}],"party_address":3223084,"script_address":2065775},{"address":3256192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[141,154,170,91],"species":301},{"level":28,"moves":[33,120,124,108],"species":109}],"party_address":3223116,"script_address":2065806},{"address":3256232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":305},{"level":29,"species":178}],"party_address":3223148,"script_address":2202329},{"address":3256272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":358},{"level":27,"species":358},{"level":27,"species":358}],"party_address":3223164,"script_address":2202360},{"address":3256312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":392}],"party_address":3223188,"script_address":1971405},{"address":3256352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[76,219,225,93],"species":359},{"level":46,"moves":[47,18,204,185],"species":316},{"level":47,"moves":[89,73,202,92],"species":363},{"level":44,"moves":[48,85,161,103],"species":82},{"level":48,"moves":[104,91,94,248],"species":394}],"party_address":3223196,"script_address":2332607},{"address":3256392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[76,219,225,93],"species":359},{"level":49,"moves":[47,18,204,185],"species":316},{"level":50,"moves":[89,73,202,92],"species":363},{"level":47,"moves":[48,85,161,103],"species":82},{"level":51,"moves":[104,91,94,248],"species":394}],"party_address":3223276,"script_address":0},{"address":3256432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[76,219,225,93],"species":359},{"level":52,"moves":[47,18,204,185],"species":316},{"level":53,"moves":[89,73,202,92],"species":363},{"level":50,"moves":[48,85,161,103],"species":82},{"level":54,"moves":[104,91,94,248],"species":394}],"party_address":3223356,"script_address":0},{"address":3256472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[76,219,225,93],"species":359},{"level":55,"moves":[47,18,204,185],"species":316},{"level":56,"moves":[89,73,202,92],"species":363},{"level":53,"moves":[48,85,161,103],"species":82},{"level":57,"moves":[104,91,94,248],"species":394}],"party_address":3223436,"script_address":0},{"address":3256512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223516,"script_address":1986165},{"address":3256552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223548,"script_address":1986109},{"address":3256592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223580,"script_address":1986137},{"address":3256632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223612,"script_address":1986081},{"address":3256672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223644,"script_address":1986025},{"address":3256712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223676,"script_address":1986053},{"address":3256752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":31,"species":72},{"level":32,"species":331}],"party_address":3223708,"script_address":2070644},{"address":3256792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":34,"species":73}],"party_address":3223732,"script_address":2070675},{"address":3256832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":129},{"level":25,"species":129},{"level":35,"species":130}],"party_address":3223748,"script_address":2070706},{"address":3256872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":44},{"level":34,"species":184}],"party_address":3223772,"script_address":2071552},{"address":3256912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":300},{"level":34,"species":320}],"party_address":3223788,"script_address":2071583},{"address":3256952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":67}],"party_address":3223804,"script_address":2070799},{"address":3256992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":72},{"level":31,"species":72},{"level":36,"species":313}],"party_address":3223812,"script_address":2071614},{"address":3257032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":305},{"level":32,"species":227}],"party_address":3223836,"script_address":2070737},{"address":3257072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":341},{"level":33,"species":331}],"party_address":3223852,"script_address":2073040},{"address":3257112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170}],"party_address":3223868,"script_address":2073071},{"address":3257152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":308},{"level":19,"species":308}],"party_address":3223876,"script_address":0},{"address":3257192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[47,31,219,76],"species":358},{"level":35,"moves":[53,36,156,89],"species":339}],"party_address":3223892,"script_address":0},{"address":3257232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[74,78,72,73],"species":363},{"level":20,"moves":[111,205,44,88],"species":75}],"party_address":3223924,"script_address":0},{"address":3257272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[16,60,92,182],"species":294},{"level":27,"moves":[16,72,213,78],"species":292}],"party_address":3223956,"script_address":0},{"address":3257312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[94,7,244,182],"species":357},{"level":39,"moves":[8,61,156,187],"species":336}],"party_address":3223988,"script_address":0},{"address":3257352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,7,244,182],"species":357},{"level":43,"moves":[8,61,156,187],"species":336}],"party_address":3224020,"script_address":0},{"address":3257392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[94,7,244,182],"species":357},{"level":46,"moves":[8,61,156,187],"species":336}],"party_address":3224052,"script_address":0},{"address":3257432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":49,"moves":[94,7,244,182],"species":357},{"level":49,"moves":[8,61,156,187],"species":336}],"party_address":3224084,"script_address":0},{"address":3257472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[94,7,244,182],"species":357},{"level":52,"moves":[8,61,156,187],"species":336}],"party_address":3224116,"script_address":0},{"address":3257512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":33,"species":309}],"party_address":3224148,"script_address":0},{"address":3257552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170},{"level":33,"species":330}],"party_address":3224164,"script_address":0},{"address":3257592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":170},{"level":40,"species":330}],"party_address":3224180,"script_address":0},{"address":3257632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":171},{"level":43,"species":330}],"party_address":3224196,"script_address":0},{"address":3257672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":171},{"level":46,"species":331}],"party_address":3224212,"script_address":0},{"address":3257712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":51,"species":171},{"level":49,"species":331}],"party_address":3224228,"script_address":0},{"address":3257752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":118},{"level":25,"species":72}],"party_address":3224244,"script_address":0},{"address":3257792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":129},{"level":20,"species":72},{"level":26,"species":328},{"level":23,"species":330}],"party_address":3224260,"script_address":2061605},{"address":3257832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":288},{"level":8,"species":286}],"party_address":3224292,"script_address":2054707},{"address":3257872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":295},{"level":8,"species":288}],"party_address":3224308,"script_address":2054676},{"address":3257912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":129}],"party_address":3224324,"script_address":2030343},{"address":3257952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":183}],"party_address":3224332,"script_address":2036307},{"address":3257992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":72},{"level":12,"species":72}],"party_address":3224340,"script_address":2036276},{"address":3258032,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":354},{"level":14,"species":353}],"party_address":3224356,"script_address":2039032},{"address":3258072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":337},{"level":14,"species":100}],"party_address":3224372,"script_address":2039063},{"address":3258112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81}],"party_address":3224388,"script_address":2039094},{"address":3258152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":100}],"party_address":3224396,"script_address":2026463},{"address":3258192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":335}],"party_address":3224404,"script_address":2026494},{"address":3258232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":27}],"party_address":3224412,"script_address":2046975},{"address":3258272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":363}],"party_address":3224420,"script_address":2047006},{"address":3258312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306}],"party_address":3224428,"script_address":2046944},{"address":3258352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339}],"party_address":3224436,"script_address":2046913},{"address":3258392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":183},{"level":19,"species":296}],"party_address":3224444,"script_address":2050969},{"address":3258432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":227},{"level":19,"species":305}],"party_address":3224460,"script_address":2051000},{"address":3258472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":318},{"level":18,"species":27}],"party_address":3224476,"script_address":2051031},{"address":3258512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":382},{"level":18,"species":382}],"party_address":3224492,"script_address":2051062},{"address":3258552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":183}],"party_address":3224508,"script_address":2052309},{"address":3258592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3224524,"script_address":2052371},{"address":3258632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":299}],"party_address":3224532,"script_address":2052340},{"address":3258672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":14,"species":382},{"level":14,"species":337}],"party_address":3224540,"script_address":2059128},{"address":3258712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224564,"script_address":2347841},{"address":3258752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224572,"script_address":2347872},{"address":3258792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224580,"script_address":2348597},{"address":3258832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":41}],"party_address":3224588,"script_address":2348628},{"address":3258872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":339}],"party_address":3224604,"script_address":2348659},{"address":3258912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224620,"script_address":2349324},{"address":3258952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224628,"script_address":2349355},{"address":3258992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224636,"script_address":2349386},{"address":3259032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224644,"script_address":2350264},{"address":3259072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224652,"script_address":2350826},{"address":3259112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224660,"script_address":2351566},{"address":3259152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224668,"script_address":2351597},{"address":3259192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224676,"script_address":2351628},{"address":3259232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224684,"script_address":2348566},{"address":3259272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224692,"script_address":2349293},{"address":3259312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224700,"script_address":2350295},{"address":3259352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":339},{"level":28,"species":287},{"level":30,"species":41},{"level":33,"species":340}],"party_address":3224708,"script_address":2351659},{"address":3259392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":310},{"level":33,"species":340}],"party_address":3224740,"script_address":2073763},{"address":3259432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":287},{"level":43,"species":169},{"level":44,"species":340}],"party_address":3224756,"script_address":0},{"address":3259472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":72}],"party_address":3224780,"script_address":2026525},{"address":3259512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183}],"party_address":3224788,"script_address":2026556},{"address":3259552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":27},{"level":25,"species":27}],"party_address":3224796,"script_address":2033726},{"address":3259592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":309}],"party_address":3224812,"script_address":2033695},{"address":3259632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":120}],"party_address":3224828,"script_address":2034744},{"address":3259672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":309},{"level":24,"species":66},{"level":24,"species":72}],"party_address":3224836,"script_address":2034931},{"address":3259712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":338},{"level":24,"species":305},{"level":24,"species":338}],"party_address":3224860,"script_address":2034900},{"address":3259752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":227},{"level":25,"species":227}],"party_address":3224884,"script_address":2036338},{"address":3259792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":183},{"level":22,"species":296}],"party_address":3224900,"script_address":2047037},{"address":3259832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":27},{"level":22,"species":28}],"party_address":3224916,"script_address":2047068},{"address":3259872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":304},{"level":22,"species":299}],"party_address":3224932,"script_address":2047099},{"address":3259912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":18,"species":218}],"party_address":3224948,"script_address":2049891},{"address":3259952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306},{"level":18,"species":363}],"party_address":3224964,"script_address":2049922},{"address":3259992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":84},{"level":26,"species":85}],"party_address":3224980,"script_address":2053203},{"address":3260032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302},{"level":26,"species":367}],"party_address":3224996,"script_address":2053234},{"address":3260072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":64},{"level":26,"species":393}],"party_address":3225012,"script_address":2053265},{"address":3260112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3225028,"script_address":2053296},{"address":3260152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":351}],"party_address":3225044,"script_address":2053327},{"address":3260192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3225060,"script_address":2054738},{"address":3260232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":306},{"level":8,"species":295}],"party_address":3225076,"script_address":2054769},{"address":3260272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3225092,"script_address":2057834},{"address":3260312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3225100,"script_address":2057865},{"address":3260352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":356}],"party_address":3225108,"script_address":2057896},{"address":3260392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":363},{"level":33,"species":357}],"party_address":3225116,"script_address":2073825},{"address":3260432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":338}],"party_address":3225132,"script_address":2061636},{"address":3260472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":218},{"level":25,"species":339}],"party_address":3225140,"script_address":2061667},{"address":3260512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3225156,"script_address":2061698},{"address":3260552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[87,98,86,0],"species":338}],"party_address":3225164,"script_address":2065837},{"address":3260592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":356},{"level":28,"species":335}],"party_address":3225180,"script_address":2065868},{"address":3260632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":292}],"party_address":3225196,"script_address":2067487},{"address":3260672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":335},{"level":25,"species":309},{"level":25,"species":369},{"level":25,"species":288},{"level":25,"species":337},{"level":25,"species":339}],"party_address":3225212,"script_address":2067518},{"address":3260712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":286},{"level":25,"species":306},{"level":25,"species":337},{"level":25,"species":183},{"level":25,"species":27},{"level":25,"species":367}],"party_address":3225260,"script_address":2067549},{"address":3260752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":371},{"level":29,"species":365}],"party_address":3225308,"script_address":2067611},{"address":3260792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3225324,"script_address":1978255},{"address":3260832,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":321},{"level":15,"species":283}],"party_address":3225340,"script_address":1978286},{"address":3260872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[182,205,222,153],"species":76},{"level":35,"moves":[14,58,57,157],"species":140},{"level":35,"moves":[231,153,46,157],"species":95},{"level":37,"moves":[104,153,182,157],"species":320}],"party_address":3225356,"script_address":0},{"address":3260912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[182,58,157,57],"species":138},{"level":37,"moves":[182,205,222,153],"species":76},{"level":40,"moves":[14,58,57,157],"species":141},{"level":40,"moves":[231,153,46,157],"species":95},{"level":42,"moves":[104,153,182,157],"species":320}],"party_address":3225420,"script_address":0},{"address":3260952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[182,58,157,57],"species":139},{"level":42,"moves":[182,205,89,153],"species":76},{"level":45,"moves":[14,58,57,157],"species":141},{"level":45,"moves":[231,153,46,157],"species":95},{"level":47,"moves":[104,153,182,157],"species":320}],"party_address":3225500,"script_address":0},{"address":3260992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[157,63,48,182],"species":142},{"level":47,"moves":[8,205,89,153],"species":76},{"level":47,"moves":[182,58,157,57],"species":139},{"level":50,"moves":[14,58,57,157],"species":141},{"level":50,"moves":[231,153,46,157],"species":208},{"level":52,"moves":[104,153,182,157],"species":320}],"party_address":3225580,"script_address":0},{"address":3261032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[2,157,8,83],"species":68},{"level":33,"moves":[94,113,115,8],"species":356},{"level":35,"moves":[228,68,182,167],"species":237},{"level":37,"moves":[252,8,187,89],"species":336}],"party_address":3225676,"script_address":0},{"address":3261072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[2,157,8,83],"species":68},{"level":38,"moves":[94,113,115,8],"species":357},{"level":40,"moves":[228,68,182,167],"species":237},{"level":42,"moves":[252,8,187,89],"species":336}],"party_address":3225740,"script_address":0},{"address":3261112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[71,182,7,8],"species":107},{"level":43,"moves":[2,157,8,83],"species":68},{"level":43,"moves":[8,113,115,94],"species":357},{"level":45,"moves":[228,68,182,167],"species":237},{"level":47,"moves":[252,8,187,89],"species":336}],"party_address":3225804,"script_address":0},{"address":3261152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[25,8,89,83],"species":106},{"level":46,"moves":[71,182,7,8],"species":107},{"level":48,"moves":[238,157,8,83],"species":68},{"level":48,"moves":[8,113,115,94],"species":357},{"level":50,"moves":[228,68,182,167],"species":237},{"level":52,"moves":[252,8,187,89],"species":336}],"party_address":3225884,"script_address":0},{"address":3261192,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,182,86,113],"species":179},{"level":36,"moves":[205,87,153,240],"species":101},{"level":38,"moves":[48,182,87,240],"species":82},{"level":40,"moves":[44,86,87,182],"species":338}],"party_address":3225980,"script_address":0},{"address":3261232,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[87,21,240,95],"species":25},{"level":41,"moves":[87,182,86,113],"species":180},{"level":41,"moves":[205,87,153,240],"species":101},{"level":43,"moves":[48,182,87,240],"species":82},{"level":45,"moves":[44,86,87,182],"species":338}],"party_address":3226044,"script_address":0},{"address":3261272,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[87,21,240,182],"species":26},{"level":46,"moves":[87,182,86,113],"species":181},{"level":46,"moves":[205,87,153,240],"species":101},{"level":48,"moves":[48,182,87,240],"species":82},{"level":50,"moves":[44,86,87,182],"species":338}],"party_address":3226124,"script_address":0},{"address":3261312,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[129,8,9,113],"species":125},{"level":51,"moves":[87,21,240,182],"species":26},{"level":51,"moves":[87,182,86,113],"species":181},{"level":53,"moves":[205,87,153,240],"species":101},{"level":53,"moves":[48,182,87,240],"species":82},{"level":55,"moves":[44,86,87,182],"species":338}],"party_address":3226204,"script_address":0},{"address":3261352,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[59,213,113,157],"species":219},{"level":36,"moves":[53,213,76,84],"species":77},{"level":38,"moves":[59,241,89,213],"species":340},{"level":40,"moves":[59,241,153,213],"species":321}],"party_address":3226300,"script_address":0},{"address":3261392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[14,53,46,241],"species":58},{"level":43,"moves":[59,213,113,157],"species":219},{"level":41,"moves":[53,213,76,84],"species":77},{"level":43,"moves":[59,241,89,213],"species":340},{"level":45,"moves":[59,241,153,213],"species":321}],"party_address":3226364,"script_address":0},{"address":3261432,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,76,13,241],"species":228},{"level":46,"moves":[14,53,241,46],"species":58},{"level":48,"moves":[59,213,113,157],"species":219},{"level":46,"moves":[53,213,76,84],"species":78},{"level":48,"moves":[59,241,89,213],"species":340},{"level":50,"moves":[59,241,153,213],"species":321}],"party_address":3226444,"script_address":0},{"address":3261472,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":51,"moves":[14,53,241,46],"species":59},{"level":53,"moves":[59,213,113,157],"species":219},{"level":51,"moves":[46,76,13,241],"species":229},{"level":51,"moves":[53,213,76,84],"species":78},{"level":53,"moves":[59,241,89,213],"species":340},{"level":55,"moves":[59,241,153,213],"species":321}],"party_address":3226540,"script_address":0},{"address":3261512,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[113,47,29,8],"species":113},{"level":42,"moves":[59,247,38,126],"species":366},{"level":43,"moves":[42,29,7,95],"species":308},{"level":45,"moves":[63,53,85,247],"species":366}],"party_address":3226636,"script_address":0},{"address":3261552,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[59,247,38,126],"species":366},{"level":47,"moves":[113,47,29,8],"species":113},{"level":45,"moves":[252,146,203,179],"species":115},{"level":48,"moves":[42,29,7,95],"species":308},{"level":50,"moves":[63,53,85,247],"species":366}],"party_address":3226700,"script_address":0},{"address":3261592,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[59,247,38,126],"species":366},{"level":52,"moves":[113,47,29,8],"species":242},{"level":50,"moves":[252,146,203,179],"species":115},{"level":53,"moves":[42,29,7,95],"species":308},{"level":55,"moves":[63,53,85,247],"species":366}],"party_address":3226780,"script_address":0},{"address":3261632,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[59,247,38,126],"species":366},{"level":57,"moves":[182,47,29,8],"species":242},{"level":55,"moves":[252,146,203,179],"species":115},{"level":57,"moves":[36,182,126,89],"species":128},{"level":58,"moves":[42,29,7,95],"species":308},{"level":60,"moves":[63,53,85,247],"species":366}],"party_address":3226860,"script_address":0},{"address":3261672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[86,85,182,58],"species":147},{"level":38,"moves":[241,76,76,89],"species":369},{"level":41,"moves":[57,48,182,76],"species":310},{"level":43,"moves":[18,191,211,76],"species":227},{"level":45,"moves":[76,156,93,89],"species":359}],"party_address":3226956,"script_address":0},{"address":3261712,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[95,94,115,138],"species":163},{"level":43,"moves":[241,76,76,89],"species":369},{"level":45,"moves":[86,85,182,58],"species":148},{"level":46,"moves":[57,48,182,76],"species":310},{"level":48,"moves":[18,191,211,76],"species":227},{"level":50,"moves":[76,156,93,89],"species":359}],"party_address":3227036,"script_address":0},{"address":3261752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[95,94,115,138],"species":164},{"level":49,"moves":[241,76,76,89],"species":369},{"level":50,"moves":[86,85,182,58],"species":148},{"level":51,"moves":[57,48,182,76],"species":310},{"level":53,"moves":[18,191,211,76],"species":227},{"level":55,"moves":[76,156,93,89],"species":359}],"party_address":3227132,"script_address":0},{"address":3261792,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,94,115,138],"species":164},{"level":54,"moves":[241,76,76,89],"species":369},{"level":55,"moves":[57,48,182,76],"species":310},{"level":55,"moves":[63,85,89,58],"species":149},{"level":58,"moves":[18,191,211,76],"species":227},{"level":60,"moves":[143,156,93,89],"species":359}],"party_address":3227228,"script_address":0},{"address":3261832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[25,94,91,182],"species":79},{"level":49,"moves":[89,246,94,113],"species":319},{"level":49,"moves":[94,156,109,91],"species":178},{"level":50,"moves":[89,94,156,91],"species":348},{"level":50,"moves":[241,76,94,53],"species":349}],"party_address":3227324,"script_address":0},{"address":3261872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,138,29,182],"species":96},{"level":53,"moves":[25,94,91,182],"species":79},{"level":54,"moves":[89,153,94,113],"species":319},{"level":54,"moves":[94,156,109,91],"species":178},{"level":55,"moves":[89,94,156,91],"species":348},{"level":55,"moves":[241,76,94,53],"species":349}],"party_address":3227404,"script_address":0},{"address":3261912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":58,"moves":[95,138,29,182],"species":97},{"level":59,"moves":[89,153,94,113],"species":319},{"level":58,"moves":[25,94,91,182],"species":79},{"level":59,"moves":[94,156,109,91],"species":178},{"level":60,"moves":[89,94,156,91],"species":348},{"level":60,"moves":[241,76,94,53],"species":349}],"party_address":3227500,"script_address":0},{"address":3261952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":63,"moves":[95,138,29,182],"species":97},{"level":64,"moves":[89,153,94,113],"species":319},{"level":63,"moves":[25,94,91,182],"species":199},{"level":64,"moves":[94,156,109,91],"species":178},{"level":65,"moves":[89,94,156,91],"species":348},{"level":65,"moves":[241,76,94,53],"species":349}],"party_address":3227596,"script_address":0},{"address":3261992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[95,240,182,56],"species":60},{"level":46,"moves":[240,96,104,90],"species":324},{"level":48,"moves":[96,34,182,58],"species":343},{"level":48,"moves":[156,152,13,104],"species":327},{"level":51,"moves":[96,104,58,156],"species":230}],"party_address":3227692,"script_address":0},{"address":3262032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[95,240,182,56],"species":61},{"level":51,"moves":[240,96,104,90],"species":324},{"level":53,"moves":[96,34,182,58],"species":343},{"level":53,"moves":[156,12,13,104],"species":327},{"level":56,"moves":[96,104,58,156],"species":230}],"party_address":3227772,"script_address":0},{"address":3262072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[56,195,58,109],"species":131},{"level":58,"moves":[240,96,104,90],"species":324},{"level":56,"moves":[95,240,182,56],"species":61},{"level":58,"moves":[96,34,182,58],"species":343},{"level":58,"moves":[156,12,13,104],"species":327},{"level":61,"moves":[96,104,58,156],"species":230}],"party_address":3227852,"script_address":0},{"address":3262112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":61,"moves":[56,195,58,109],"species":131},{"level":63,"moves":[240,96,104,90],"species":324},{"level":61,"moves":[95,240,56,195],"species":186},{"level":63,"moves":[96,34,182,73],"species":343},{"level":63,"moves":[156,12,13,104],"species":327},{"level":66,"moves":[96,104,58,156],"species":230}],"party_address":3227948,"script_address":0},{"address":3262152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[95,98,204,0],"species":387},{"level":17,"moves":[95,98,109,0],"species":386}],"party_address":3228044,"script_address":2167732},{"address":3262192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":369}],"party_address":3228076,"script_address":2202422},{"address":3262232,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":77,"moves":[92,76,191,211],"species":227},{"level":75,"moves":[115,113,246,89],"species":319},{"level":76,"moves":[87,89,76,81],"species":384},{"level":76,"moves":[202,246,19,109],"species":389},{"level":76,"moves":[96,246,76,163],"species":391},{"level":78,"moves":[89,94,53,247],"species":400}],"party_address":3228084,"script_address":2354502},{"address":3262272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228180,"script_address":0},{"address":3262312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228188,"script_address":0},{"address":3262352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228196,"script_address":0},{"address":3262392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228204,"script_address":0},{"address":3262432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228212,"script_address":0},{"address":3262472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228220,"script_address":0},{"address":3262512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228228,"script_address":0},{"address":3262552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":27}],"party_address":3228236,"script_address":0},{"address":3262592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":320},{"level":33,"species":27},{"level":33,"species":27}],"party_address":3228252,"script_address":0},{"address":3262632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":320},{"level":35,"species":27},{"level":35,"species":27}],"party_address":3228276,"script_address":0},{"address":3262672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":320},{"level":37,"species":28},{"level":37,"species":28}],"party_address":3228300,"script_address":0},{"address":3262712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":309},{"level":30,"species":66},{"level":30,"species":72}],"party_address":3228324,"script_address":0},{"address":3262752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":66},{"level":32,"species":72}],"party_address":3228348,"script_address":0},{"address":3262792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":66},{"level":34,"species":73}],"party_address":3228372,"script_address":0},{"address":3262832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":310},{"level":36,"species":67},{"level":36,"species":73}],"party_address":3228396,"script_address":0},{"address":3262872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":120},{"level":37,"species":120}],"party_address":3228420,"script_address":0},{"address":3262912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":309},{"level":39,"species":120},{"level":39,"species":120}],"party_address":3228436,"script_address":0},{"address":3262952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":310},{"level":41,"species":120},{"level":41,"species":120}],"party_address":3228460,"script_address":0},{"address":3262992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":310},{"level":43,"species":121},{"level":43,"species":121}],"party_address":3228484,"script_address":0},{"address":3263032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":67},{"level":37,"species":67}],"party_address":3228508,"script_address":0},{"address":3263072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":335},{"level":39,"species":67},{"level":39,"species":67}],"party_address":3228524,"script_address":0},{"address":3263112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":336},{"level":41,"species":67},{"level":41,"species":67}],"party_address":3228548,"script_address":0},{"address":3263152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":336},{"level":43,"species":68},{"level":43,"species":68}],"party_address":3228572,"script_address":0},{"address":3263192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":371},{"level":35,"species":365}],"party_address":3228596,"script_address":0},{"address":3263232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":308},{"level":37,"species":371},{"level":37,"species":365}],"party_address":3228612,"script_address":0},{"address":3263272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":308},{"level":39,"species":371},{"level":39,"species":365}],"party_address":3228636,"script_address":0},{"address":3263312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":308},{"level":41,"species":372},{"level":41,"species":366}],"party_address":3228660,"script_address":0},{"address":3263352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":337},{"level":35,"species":337},{"level":35,"species":371}],"party_address":3228684,"script_address":0},{"address":3263392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":337},{"level":37,"species":338},{"level":37,"species":371}],"party_address":3228708,"script_address":0},{"address":3263432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":338},{"level":39,"species":338},{"level":39,"species":371}],"party_address":3228732,"script_address":0},{"address":3263472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":338},{"level":41,"species":338},{"level":41,"species":372}],"party_address":3228756,"script_address":0},{"address":3263512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":74},{"level":26,"species":339}],"party_address":3228780,"script_address":0},{"address":3263552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":66},{"level":28,"species":339},{"level":28,"species":75}],"party_address":3228796,"script_address":0},{"address":3263592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":66},{"level":30,"species":339},{"level":30,"species":75}],"party_address":3228820,"script_address":0},{"address":3263632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":340},{"level":33,"species":76}],"party_address":3228844,"script_address":0},{"address":3263672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":315},{"level":31,"species":287},{"level":31,"species":288},{"level":31,"species":295},{"level":31,"species":298},{"level":31,"species":304}],"party_address":3228868,"script_address":0},{"address":3263712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":315},{"level":33,"species":287},{"level":33,"species":289},{"level":33,"species":296},{"level":33,"species":299},{"level":33,"species":304}],"party_address":3228916,"script_address":0},{"address":3263752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316},{"level":35,"species":287},{"level":35,"species":289},{"level":35,"species":296},{"level":35,"species":299},{"level":35,"species":305}],"party_address":3228964,"script_address":0},{"address":3263792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":316},{"level":37,"species":287},{"level":37,"species":289},{"level":37,"species":297},{"level":37,"species":300},{"level":37,"species":305}],"party_address":3229012,"script_address":0},{"address":3263832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313},{"level":34,"species":116}],"party_address":3229060,"script_address":0},{"address":3263872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":325},{"level":36,"species":313},{"level":36,"species":117}],"party_address":3229076,"script_address":0},{"address":3263912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":325},{"level":38,"species":313},{"level":38,"species":117}],"party_address":3229100,"script_address":0},{"address":3263952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325},{"level":40,"species":314},{"level":40,"species":230}],"party_address":3229124,"script_address":0},{"address":3263992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":411}],"party_address":3229148,"script_address":2564791},{"address":3264032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":64}],"party_address":3229156,"script_address":2564822},{"address":3264072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":202}],"party_address":3229172,"script_address":0},{"address":3264112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":4}],"party_address":3229180,"script_address":0},{"address":3264152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":1}],"party_address":3229188,"script_address":0},{"address":3264192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":405}],"party_address":3229196,"script_address":0},{"address":3264232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":404}],"party_address":3229204,"script_address":0}],"warps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4":"MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0","MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2":"MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1","MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10","MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2":"MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11","MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3":"MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2","MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0":"MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4","MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3":"MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5","MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2":"MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6","MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4":"MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7","MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0":"MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8","MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9","MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2":"MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0","MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0":"MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1","MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0":"MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2","MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1":"MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3","MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2":"MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4","MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0":"MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5","MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10":"MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6","MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9":"MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7","MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0":"MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0","MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2","MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3","MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0":"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8","MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8":"MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0","MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11":"MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2","MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0","MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0","MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3","MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4","MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0","MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1","MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2","MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0","MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0":"MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0","MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0":"MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0","MAP_ALTERING_CAVE:0/MAP_ROUTE103:0":"MAP_ROUTE103:0/MAP_ALTERING_CAVE:0","MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0":"MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0","MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2":"MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1","MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1":"MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2","MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6":"MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0","MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0":"MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2","MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2":"MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0","MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0":"MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1","MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6":"MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10","MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22":"MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11","MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9":"MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12","MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18":"MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13","MAP_AQUA_HIDEOUT_B1F:14/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16":"MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15","MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15":"MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16","MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20":"MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17","MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13":"MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18","MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24":"MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19","MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1":"MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2","MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:21/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11":"MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22","MAP_AQUA_HIDEOUT_B1F:23/MAP_AQUA_HIDEOUT_B1F:17!":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19":"MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24","MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2":"MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3","MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7":"MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4","MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8":"MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5","MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10":"MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6","MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5":"MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8","MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1":"MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0","MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2":"MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1","MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3":"MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2","MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5":"MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3","MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8":"MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4","MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3":"MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5","MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7":"MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6","MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6":"MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7","MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4":"MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8","MAP_AQUA_HIDEOUT_B2F:9/MAP_AQUA_HIDEOUT_B1F:4!":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0","MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1":"MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1","MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0","MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1":"MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1","MAP_BATTLE_COLOSSEUM_2P:0,1/MAP_DYNAMIC:-1!":"","MAP_BATTLE_COLOSSEUM_4P:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:3/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0!":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2","MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2","MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0","MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0","MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0","MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0","MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0","MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0","MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0","MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0","MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0","MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0","MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0":"MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0":"MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0":"MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0":"MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0":"MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0":"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0":"MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0":"MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0":"MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0":"MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0":"MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0":"MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0":"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0":"MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0":"MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1","MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0","MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0":"MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0","MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0":"MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0","MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1":"MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0","MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3":"MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0":"MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:0/MAP_CAVE_OF_ORIGIN_1F:1!":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:1/MAP_CAVE_OF_ORIGIN_B1F:0!":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_DESERT_RUINS:0/MAP_ROUTE111:1":"MAP_ROUTE111:1/MAP_DESERT_RUINS:0","MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2":"MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1","MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1":"MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2","MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0","MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0":"MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0","MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1","MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0":"MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2","MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0":"MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3","MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0":"MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4","MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2":"MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0","MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0":"MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0","MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3":"MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0","MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4":"MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1":"MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0","MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1","MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0":"MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2","MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1":"MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1":"MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0":"MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1":"MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0":"MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1":"MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0":"MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1","MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0","MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1","MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0","MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1","MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0","MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1","MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0","MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1","MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0","MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1","MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1":"MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0":"MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1":"MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0":"MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0":"MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1":"MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0":"MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1","MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0":"MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0","MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0":"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1","MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2","MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0":"MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3","MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0":"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4","MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1":"MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0","MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3":"MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0","MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0":"MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0","MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4":"MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2":"MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1":"MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1","MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1":"MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1","MAP_FIERY_PATH:0/MAP_ROUTE112:4":"MAP_ROUTE112:4/MAP_FIERY_PATH:0","MAP_FIERY_PATH:1/MAP_ROUTE112:5":"MAP_ROUTE112:5/MAP_FIERY_PATH:1","MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0","MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0":"MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1","MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0":"MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2","MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0":"MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3","MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0":"MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4","MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0":"MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5","MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0":"MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6","MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0":"MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7","MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0":"MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8","MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8":"MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0","MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2":"MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0","MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1":"MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0","MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4":"MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0","MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5":"MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0","MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6":"MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0","MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7":"MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0","MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3":"MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0":"MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2","MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0","MAP_FORTREE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FORTREE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0":"MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0","MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0":"MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1","MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1":"MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2","MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0":"MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3","MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1":"MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0","MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2":"MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1","MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0":"MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2","MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1":"MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3","MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2":"MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4","MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3":"MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5","MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4":"MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6","MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2":"MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0","MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3":"MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1","MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4":"MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2","MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5":"MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3","MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6":"MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4","MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3":"MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0","MAP_INSIDE_OF_TRUCK:0,1,2/MAP_DYNAMIC:-1!":"","MAP_ISLAND_CAVE:0/MAP_ROUTE105:0":"MAP_ROUTE105:0/MAP_ISLAND_CAVE:0","MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2":"MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1","MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1":"MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2","MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3":"MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1","MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3":"MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3","MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0":"MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4","MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0":"MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0","MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0":"MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1","MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0":"MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2","MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3","MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0":"MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4","MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5","MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1":"MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0","MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8":"MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10","MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9":"MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11","MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10":"MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12","MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11":"MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13","MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12":"MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14","MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13":"MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15","MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14":"MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16","MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15":"MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17","MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16":"MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18","MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17":"MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19","MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0":"MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2","MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18":"MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20","MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20":"MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21","MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19":"MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22","MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21":"MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23","MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22":"MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24","MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23":"MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25","MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2":"MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3","MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4":"MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4","MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3":"MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5","MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1":"MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6","MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5":"MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7","MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6":"MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8","MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7":"MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9","MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2":"MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0","MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6":"MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1","MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12":"MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10","MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13":"MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11","MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14":"MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12","MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15":"MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13","MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16":"MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14","MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17":"MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15","MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18":"MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16","MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19":"MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17","MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20":"MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18","MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22":"MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19","MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3":"MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2","MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21":"MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20","MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23":"MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21","MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24":"MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22","MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25":"MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23","MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5":"MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3","MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4":"MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4","MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7":"MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5","MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8":"MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6","MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9":"MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7","MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10":"MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8","MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11":"MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9","MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0":"MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0","MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4":"MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0","MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2":"MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3":"MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5":"MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0","MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1","MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0":"MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10","MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0":"MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11","MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0":"MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12","MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2","MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13","MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4","MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1":"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5","MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0":"MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6","MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0":"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7","MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0":"MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8","MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0":"MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9","MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0","MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1","MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4":"MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0","MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0":"MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2","MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1":"MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1":"MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:3/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!":"","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0","MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12":"MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0","MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8":"MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0","MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9":"MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0","MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10":"MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0","MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11":"MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13":"MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0","MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7":"MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2":"MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5":"MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1","MAP_LILYCOVE_CITY_UNUSED_MART:0,1/MAP_LILYCOVE_CITY:0!":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0","MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1","MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0":"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1":"MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0":"MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2":"MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0","MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4":"MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0","MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1":"MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1","MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1":"MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2","MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0":"MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3","MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0":"MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0","MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1":"MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1","MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2":"MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2","MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0":"MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0","MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2":"MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1","MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3":"MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0","MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0":"MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1","MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0":"MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0","MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0":"MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1","MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2":"MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2","MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1":"MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0","MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1":"MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0","MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1":"MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1","MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0":"MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0","MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1":"MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1","MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0":"MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0","MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0":"MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0","MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0":"MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0","MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1","MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0":"MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2","MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0":"MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3","MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0":"MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4","MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0":"MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5","MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0":"MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6","MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2":"MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0","MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5":"MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0","MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0":"MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0","MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4":"MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0","MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6":"MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0","MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3":"MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1":"MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0":"MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0","MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0":"MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1","MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0":"MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2","MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4":"MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3","MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5":"MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4","MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0":"MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5","MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2":"MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0","MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0":"MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1","MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1":"MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2","MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2":"MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3","MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1":"MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0","MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2":"MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1","MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3":"MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2","MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0":"MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3","MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3":"MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4","MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4":"MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5","MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3":"MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0","MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5":"MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0","MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3":"MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0","MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1":"MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1","MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0":"MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0","MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1":"MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1","MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0":"MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0","MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0":"MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1","MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1":"MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0","MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0":"MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0","MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0":"MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1","MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2","MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0":"MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3","MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0":"MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4","MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0":"MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5","MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0":"MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6","MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1":"MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7","MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8","MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9":"MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2","MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0","MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1":"MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0","MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11":"MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10","MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10":"MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11","MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13":"MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12","MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12":"MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13","MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3":"MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2","MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2":"MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3","MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5":"MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4","MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4":"MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5","MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7":"MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6","MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6":"MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7","MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9":"MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8","MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8":"MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9","MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0":"MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0","MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3":"MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0","MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5":"MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0","MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7":"MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1","MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4":"MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2":"MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8":"MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2","MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0","MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6":"MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0","MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1":"MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1","MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3":"MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3","MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1":"MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1","MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0":"MAP_ROUTE122:0/MAP_MT_PYRE_1F:0","MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0":"MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1","MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0":"MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4","MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4":"MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5","MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4":"MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0","MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0":"MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1","MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4":"MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2","MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5":"MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3","MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5":"MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4","MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1":"MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0","MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1":"MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1","MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4":"MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2","MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5":"MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3","MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2":"MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4","MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3":"MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5","MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1":"MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0","MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1":"MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1","MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3":"MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2","MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4":"MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3","MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2":"MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4","MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3":"MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5","MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0":"MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0","MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0":"MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1","MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1":"MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2","MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2":"MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3","MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3":"MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4","MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0":"MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0","MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2":"MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1","MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1":"MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0","MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1":"MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1","MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1":"MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1","MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0":"MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0","MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1":"MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1","MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0":"MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0","MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2":"MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0","MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0":"MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1","MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1":"MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0","MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0":"MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1","MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1":"MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0","MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0":"MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1","MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1":"MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0","MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0":"MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1","MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1":"MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0","MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0":"MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1","MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1":"MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0","MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0":"MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1","MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1":"MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0","MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0":"MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1","MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1":"MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0","MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0":"MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1","MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1":"MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0","MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0":"MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1","MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1":"MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0","MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1":"MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1","MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0":"MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0","MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1":"MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1","MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0":"MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0","MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1":"MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1","MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0":"MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0","MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1":"MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1","MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0":"MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0","MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1":"MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1","MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0":"MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2","MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0":"MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0","MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1":"MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0","MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0":"MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0","MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0":"MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1","MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1":"MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0","MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0":"MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1","MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1":"MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0","MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0":"MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1","MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1":"MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0","MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0":"MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1","MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0":"MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0","MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0":"MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1","MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1":"MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0","MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0":"MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0","MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0":"MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1","MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2","MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0":"MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3","MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0":"MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0","MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1":"MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0","MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3":"MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2":"MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0","MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0":"MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1","MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0":"MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2","MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0":"MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3","MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0":"MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4","MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0":"MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5","MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1":"MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0","MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2":"MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0","MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3":"MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0","MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4":"MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0","MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5":"MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0":"MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0":"MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0","MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0":"MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1","MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0":"MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2","MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3","MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0":"MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4","MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0":"MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5","MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2":"MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0","MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8":"MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10","MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9":"MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12","MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16":"MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14","MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18":"MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15","MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14":"MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16","MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15":"MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18","MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3":"MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2","MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24":"MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20","MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26":"MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21","MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28":"MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22","MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30":"MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23","MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20":"MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24","MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21":"MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26","MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22":"MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28","MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2":"MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3","MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23":"MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30","MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34":"MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32","MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36":"MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33","MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32":"MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34","MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33":"MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36","MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6":"MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5","MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5":"MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6","MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10":"MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8","MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12":"MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9","MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0":"MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0","MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4":"MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0","MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5":"MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3":"MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1":"MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0","MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3":"MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1","MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5":"MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3","MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7":"MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5","MAP_RECORD_CORNER:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_ROUTE103:0/MAP_ALTERING_CAVE:0":"MAP_ALTERING_CAVE:0/MAP_ROUTE103:0","MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0":"MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0","MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0":"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1","MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1":"MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3","MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3":"MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5","MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5":"MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7","MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0":"MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0","MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1":"MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0","MAP_ROUTE105:0/MAP_ISLAND_CAVE:0":"MAP_ISLAND_CAVE:0/MAP_ROUTE105:0","MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0":"MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0","MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0":"MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0","MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0":"MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0","MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0":"MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0","MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0":"MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0","MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1","MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2","MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3","MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4","MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4":"MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5":"MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2":"MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3":"MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1":"MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:2,3/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0","MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0":"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1":"MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0":"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0","MAP_ROUTE111:1/MAP_DESERT_RUINS:0":"MAP_DESERT_RUINS:0/MAP_ROUTE111:1","MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0":"MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2","MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0":"MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3","MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0":"MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4","MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2":"MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0","MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0":"MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0","MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1":"MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1","MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1":"MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3","MAP_ROUTE112:4/MAP_FIERY_PATH:0":"MAP_FIERY_PATH:0/MAP_ROUTE112:4","MAP_ROUTE112:5/MAP_FIERY_PATH:1":"MAP_FIERY_PATH:1/MAP_ROUTE112:5","MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1":"MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1","MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0":"MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0","MAP_ROUTE113:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0":"MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0","MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0":"MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0","MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1","MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0":"MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2","MAP_ROUTE114:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1":"MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0":"MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2","MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2":"MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0","MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1":"MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0","MAP_ROUTE115:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE115:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0":"MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0","MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0":"MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1","MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2":"MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2","MAP_ROUTE116:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1":"MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0","MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0":"MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0","MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0":"MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0","MAP_ROUTE118:0/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE118:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0","MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0":"MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1","MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1":"MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0":"MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2","MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0","MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0":"MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0","MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0":"MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1","MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0":"MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0":"MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2","MAP_ROUTE122:0/MAP_MT_PYRE_1F:0":"MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0","MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0":"MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0","MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0":"MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0","MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0":"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0","MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0":"MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0","MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0","MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0":"MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0","MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0":"MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0","MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0":"MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1","MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0":"MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10","MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0":"MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11","MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0":"MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2","MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3","MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0":"MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4","MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6","MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0":"MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7","MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0":"MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8","MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0":"MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9","MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8":"MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0","MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6":"MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1","MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2","MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0","MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1","MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0","MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1":"MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0","MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0":"MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2","MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2":"MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0","MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10":"MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0","MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0":"MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2","MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2":"MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0","MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0":"MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1","MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1":"MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0","MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0":"MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0","MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7":"MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0","MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9":"MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0","MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11":"MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0","MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2":"MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3":"MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4":"MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0","MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0":"MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0","MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4":"MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1","MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2":"MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2","MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0":"MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0","MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0","MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0":"MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0","MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1":"MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:0/MAP_UNDERWATER_ROUTE128:0!":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0":"MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1","MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0":"MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1","MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0":"MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2","MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2":"MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0","MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0":"MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1","MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0":"MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2","MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0":"MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3","MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1":"MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0","MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1":"MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1","MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1":"MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2","MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1":"MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0","MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1":"MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1","MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2":"MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2","MAP_SEAFLOOR_CAVERN_ROOM4:3/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1":"MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0","MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1":"MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1","MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2":"MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2","MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2":"MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0","MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2":"MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1","MAP_SEAFLOOR_CAVERN_ROOM6:2/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3":"MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0","MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1":"MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1","MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0":"MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0","MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0":"MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1","MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0":"MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0","MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0":"MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0","MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0":"MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0","MAP_SECRET_BASE_BLUE_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0":"MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1","MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1":"MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0","MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0":"MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2","MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2":"MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0","MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0":"MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1","MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1":"MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0","MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0":"MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1","MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1":"MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2","MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1":"MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0","MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2":"MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1","MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0":"MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2","MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2":"MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0","MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0":"MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1","MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0":"MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0","MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0":"MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1","MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1":"MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0","MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0":"MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1","MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1":"MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0","MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0","MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0":"MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1","MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0":"MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10","MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2","MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0":"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3","MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0":"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4","MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7","MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0":"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6","MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0":"MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8","MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2":"MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9","MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3":"MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0","MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8":"MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0","MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9":"MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2","MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10":"MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0","MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1":"MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0","MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6":"MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7":"MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0":"MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4":"MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2":"MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0","MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0","MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0":"MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1","MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0":"MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10","MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0":"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11","MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12","MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0":"MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2","MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0":"MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3","MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0":"MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4","MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0":"MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5","MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0":"MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6","MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0":"MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7","MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0":"MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8","MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0":"MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9","MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2":"MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0","MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0":"MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2","MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2":"MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0","MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4":"MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0","MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5":"MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0","MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6":"MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0","MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7":"MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0","MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8":"MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0","MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9":"MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0","MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10":"MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0","MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11":"MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0","MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1":"MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12":"MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0":"MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1":"MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1","MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1":"MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1","MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0":"MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0","MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2":"MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1","MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4":"MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2","MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6":"MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3","MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8":"MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4","MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9":"MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5","MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10":"MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6","MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11":"MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7","MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0":"MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8","MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8":"MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0","MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0":"MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0","MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6":"MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10","MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7":"MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11","MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1":"MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2","MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2":"MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4","MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3":"MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6","MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4":"MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8","MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5":"MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9","MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1":"MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0","MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!":"","MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0":"MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1","MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!":"","MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2":"MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0","MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0":"MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1","MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1":"MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0","MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0":"MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1","MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1":"MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0","MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0":"MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1","MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1":"MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0","MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0":"MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1","MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1":"MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1","MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4":"MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0","MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0":"MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2","MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1":"MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0","MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1":"MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1","MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!":"","MAP_UNDERWATER_ROUTE105:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE105:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0":"MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0","MAP_UNDERWATER_ROUTE127:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE127:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0":"MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0","MAP_UNDERWATER_ROUTE129:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE129:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0":"MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0","MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0":"MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0","MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0":"MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0","MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!":"","MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0":"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0","MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0":"MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1","MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2","MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0":"MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3","MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1":"MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4","MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0":"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5","MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0":"MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6","MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0":"MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0","MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5":"MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0","MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6":"MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0","MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1":"MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2":"MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3":"MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0","MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2":"MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0","MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3":"MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1","MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5":"MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2","MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2":"MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3","MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4":"MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4","MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0":"MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0","MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2":"MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1","MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3":"MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2","MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1":"MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3","MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4":"MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4","MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2":"MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5","MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3":"MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6","MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0":"MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0","MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3":"MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1","MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1":"MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2","MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6":"MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3"}} +{"_comment":"DO NOT MODIFY. This file was auto-generated. Your changes will likely be overwritten.","_rom_name":"pokemon emerald version / AP 5","constants":{"ABILITIES_COUNT":78,"ABILITY_AIR_LOCK":77,"ABILITY_ARENA_TRAP":71,"ABILITY_BATTLE_ARMOR":4,"ABILITY_BLAZE":66,"ABILITY_CACOPHONY":76,"ABILITY_CHLOROPHYLL":34,"ABILITY_CLEAR_BODY":29,"ABILITY_CLOUD_NINE":13,"ABILITY_COLOR_CHANGE":16,"ABILITY_COMPOUND_EYES":14,"ABILITY_CUTE_CHARM":56,"ABILITY_DAMP":6,"ABILITY_DRIZZLE":2,"ABILITY_DROUGHT":70,"ABILITY_EARLY_BIRD":48,"ABILITY_EFFECT_SPORE":27,"ABILITY_FLAME_BODY":49,"ABILITY_FLASH_FIRE":18,"ABILITY_FORECAST":59,"ABILITY_GUTS":62,"ABILITY_HUGE_POWER":37,"ABILITY_HUSTLE":55,"ABILITY_HYPER_CUTTER":52,"ABILITY_ILLUMINATE":35,"ABILITY_IMMUNITY":17,"ABILITY_INNER_FOCUS":39,"ABILITY_INSOMNIA":15,"ABILITY_INTIMIDATE":22,"ABILITY_KEEN_EYE":51,"ABILITY_LEVITATE":26,"ABILITY_LIGHTNING_ROD":31,"ABILITY_LIMBER":7,"ABILITY_LIQUID_OOZE":64,"ABILITY_MAGMA_ARMOR":40,"ABILITY_MAGNET_PULL":42,"ABILITY_MARVEL_SCALE":63,"ABILITY_MINUS":58,"ABILITY_NATURAL_CURE":30,"ABILITY_NONE":0,"ABILITY_OBLIVIOUS":12,"ABILITY_OVERGROW":65,"ABILITY_OWN_TEMPO":20,"ABILITY_PICKUP":53,"ABILITY_PLUS":57,"ABILITY_POISON_POINT":38,"ABILITY_PRESSURE":46,"ABILITY_PURE_POWER":74,"ABILITY_RAIN_DISH":44,"ABILITY_ROCK_HEAD":69,"ABILITY_ROUGH_SKIN":24,"ABILITY_RUN_AWAY":50,"ABILITY_SAND_STREAM":45,"ABILITY_SAND_VEIL":8,"ABILITY_SERENE_GRACE":32,"ABILITY_SHADOW_TAG":23,"ABILITY_SHED_SKIN":61,"ABILITY_SHELL_ARMOR":75,"ABILITY_SHIELD_DUST":19,"ABILITY_SOUNDPROOF":43,"ABILITY_SPEED_BOOST":3,"ABILITY_STATIC":9,"ABILITY_STENCH":1,"ABILITY_STICKY_HOLD":60,"ABILITY_STURDY":5,"ABILITY_SUCTION_CUPS":21,"ABILITY_SWARM":68,"ABILITY_SWIFT_SWIM":33,"ABILITY_SYNCHRONIZE":28,"ABILITY_THICK_FAT":47,"ABILITY_TORRENT":67,"ABILITY_TRACE":36,"ABILITY_TRUANT":54,"ABILITY_VITAL_SPIRIT":72,"ABILITY_VOLT_ABSORB":10,"ABILITY_WATER_ABSORB":11,"ABILITY_WATER_VEIL":41,"ABILITY_WHITE_SMOKE":73,"ABILITY_WONDER_GUARD":25,"ACRO_BIKE":1,"BAG_ITEM_CAPACITY_DIGITS":2,"BERRY_CAPACITY_DIGITS":3,"BERRY_FIRMNESS_HARD":3,"BERRY_FIRMNESS_SOFT":2,"BERRY_FIRMNESS_SUPER_HARD":5,"BERRY_FIRMNESS_UNKNOWN":0,"BERRY_FIRMNESS_VERY_HARD":4,"BERRY_FIRMNESS_VERY_SOFT":1,"BERRY_NONE":0,"BERRY_STAGE_BERRIES":5,"BERRY_STAGE_FLOWERING":4,"BERRY_STAGE_NO_BERRY":0,"BERRY_STAGE_PLANTED":1,"BERRY_STAGE_SPARKLING":255,"BERRY_STAGE_SPROUTED":2,"BERRY_STAGE_TALLER":3,"BERRY_TREES_COUNT":128,"BERRY_TREE_ROUTE_102_ORAN":2,"BERRY_TREE_ROUTE_102_PECHA":1,"BERRY_TREE_ROUTE_103_CHERI_1":5,"BERRY_TREE_ROUTE_103_CHERI_2":7,"BERRY_TREE_ROUTE_103_LEPPA":6,"BERRY_TREE_ROUTE_104_CHERI_1":8,"BERRY_TREE_ROUTE_104_CHERI_2":76,"BERRY_TREE_ROUTE_104_LEPPA":10,"BERRY_TREE_ROUTE_104_ORAN_1":4,"BERRY_TREE_ROUTE_104_ORAN_2":11,"BERRY_TREE_ROUTE_104_PECHA":13,"BERRY_TREE_ROUTE_104_SOIL_1":3,"BERRY_TREE_ROUTE_104_SOIL_2":9,"BERRY_TREE_ROUTE_104_SOIL_3":12,"BERRY_TREE_ROUTE_104_SOIL_4":75,"BERRY_TREE_ROUTE_110_NANAB_1":16,"BERRY_TREE_ROUTE_110_NANAB_2":17,"BERRY_TREE_ROUTE_110_NANAB_3":18,"BERRY_TREE_ROUTE_111_ORAN_1":80,"BERRY_TREE_ROUTE_111_ORAN_2":81,"BERRY_TREE_ROUTE_111_RAZZ_1":19,"BERRY_TREE_ROUTE_111_RAZZ_2":20,"BERRY_TREE_ROUTE_112_PECHA_1":22,"BERRY_TREE_ROUTE_112_PECHA_2":23,"BERRY_TREE_ROUTE_112_RAWST_1":21,"BERRY_TREE_ROUTE_112_RAWST_2":24,"BERRY_TREE_ROUTE_114_PERSIM_1":68,"BERRY_TREE_ROUTE_114_PERSIM_2":77,"BERRY_TREE_ROUTE_114_PERSIM_3":78,"BERRY_TREE_ROUTE_115_BLUK_1":55,"BERRY_TREE_ROUTE_115_BLUK_2":56,"BERRY_TREE_ROUTE_115_KELPSY_1":69,"BERRY_TREE_ROUTE_115_KELPSY_2":70,"BERRY_TREE_ROUTE_115_KELPSY_3":71,"BERRY_TREE_ROUTE_116_CHESTO_1":26,"BERRY_TREE_ROUTE_116_CHESTO_2":66,"BERRY_TREE_ROUTE_116_PINAP_1":25,"BERRY_TREE_ROUTE_116_PINAP_2":67,"BERRY_TREE_ROUTE_117_WEPEAR_1":27,"BERRY_TREE_ROUTE_117_WEPEAR_2":28,"BERRY_TREE_ROUTE_117_WEPEAR_3":29,"BERRY_TREE_ROUTE_118_SITRUS_1":31,"BERRY_TREE_ROUTE_118_SITRUS_2":33,"BERRY_TREE_ROUTE_118_SOIL":32,"BERRY_TREE_ROUTE_119_HONDEW_1":83,"BERRY_TREE_ROUTE_119_HONDEW_2":84,"BERRY_TREE_ROUTE_119_LEPPA":86,"BERRY_TREE_ROUTE_119_POMEG_1":34,"BERRY_TREE_ROUTE_119_POMEG_2":35,"BERRY_TREE_ROUTE_119_POMEG_3":36,"BERRY_TREE_ROUTE_119_SITRUS":85,"BERRY_TREE_ROUTE_120_ASPEAR_1":37,"BERRY_TREE_ROUTE_120_ASPEAR_2":38,"BERRY_TREE_ROUTE_120_ASPEAR_3":39,"BERRY_TREE_ROUTE_120_NANAB":44,"BERRY_TREE_ROUTE_120_PECHA_1":40,"BERRY_TREE_ROUTE_120_PECHA_2":41,"BERRY_TREE_ROUTE_120_PECHA_3":42,"BERRY_TREE_ROUTE_120_PINAP":45,"BERRY_TREE_ROUTE_120_RAZZ":43,"BERRY_TREE_ROUTE_120_WEPEAR":46,"BERRY_TREE_ROUTE_121_ASPEAR":48,"BERRY_TREE_ROUTE_121_CHESTO":50,"BERRY_TREE_ROUTE_121_NANAB_1":52,"BERRY_TREE_ROUTE_121_NANAB_2":53,"BERRY_TREE_ROUTE_121_PERSIM":47,"BERRY_TREE_ROUTE_121_RAWST":49,"BERRY_TREE_ROUTE_121_SOIL_1":51,"BERRY_TREE_ROUTE_121_SOIL_2":54,"BERRY_TREE_ROUTE_123_GREPA_1":60,"BERRY_TREE_ROUTE_123_GREPA_2":61,"BERRY_TREE_ROUTE_123_GREPA_3":65,"BERRY_TREE_ROUTE_123_GREPA_4":72,"BERRY_TREE_ROUTE_123_LEPPA_1":62,"BERRY_TREE_ROUTE_123_LEPPA_2":64,"BERRY_TREE_ROUTE_123_PECHA":87,"BERRY_TREE_ROUTE_123_POMEG_1":15,"BERRY_TREE_ROUTE_123_POMEG_2":30,"BERRY_TREE_ROUTE_123_POMEG_3":58,"BERRY_TREE_ROUTE_123_POMEG_4":59,"BERRY_TREE_ROUTE_123_QUALOT_1":14,"BERRY_TREE_ROUTE_123_QUALOT_2":73,"BERRY_TREE_ROUTE_123_QUALOT_3":74,"BERRY_TREE_ROUTE_123_QUALOT_4":79,"BERRY_TREE_ROUTE_123_RAWST":57,"BERRY_TREE_ROUTE_123_SITRUS":88,"BERRY_TREE_ROUTE_123_SOIL":63,"BERRY_TREE_ROUTE_130_LIECHI":82,"DAILY_FLAGS_END":2399,"DAILY_FLAGS_START":2336,"FIRST_BALL":1,"FIRST_BERRY_INDEX":133,"FIRST_BERRY_MASTER_BERRY":153,"FIRST_BERRY_MASTER_WIFE_BERRY":133,"FIRST_KIRI_BERRY":153,"FIRST_MAIL_INDEX":121,"FIRST_ROUTE_114_MAN_BERRY":148,"FLAGS_COUNT":2400,"FLAG_ADDED_MATCH_CALL_TO_POKENAV":304,"FLAG_ADVENTURE_STARTED":116,"FLAG_ARRIVED_AT_MARINE_CAVE_EMERGE_SPOT":2265,"FLAG_ARRIVED_AT_NAVEL_ROCK":2273,"FLAG_ARRIVED_AT_TERRA_CAVE_ENTRANCE":2266,"FLAG_ARRIVED_ON_FARAWAY_ISLAND":2264,"FLAG_BADGE01_GET":2151,"FLAG_BADGE02_GET":2152,"FLAG_BADGE03_GET":2153,"FLAG_BADGE04_GET":2154,"FLAG_BADGE05_GET":2155,"FLAG_BADGE06_GET":2156,"FLAG_BADGE07_GET":2157,"FLAG_BADGE08_GET":2158,"FLAG_BATTLE_FRONTIER_TRADE_DONE":156,"FLAG_BEAT_MAGMA_GRUNT_JAGGED_PASS":313,"FLAG_BEAUTY_PAINTING_MADE":161,"FLAG_BERRY_MASTERS_WIFE":1197,"FLAG_BERRY_MASTER_RECEIVED_BERRY_1":1195,"FLAG_BERRY_MASTER_RECEIVED_BERRY_2":1196,"FLAG_BERRY_TREES_START":612,"FLAG_BERRY_TREE_01":612,"FLAG_BERRY_TREE_02":613,"FLAG_BERRY_TREE_03":614,"FLAG_BERRY_TREE_04":615,"FLAG_BERRY_TREE_05":616,"FLAG_BERRY_TREE_06":617,"FLAG_BERRY_TREE_07":618,"FLAG_BERRY_TREE_08":619,"FLAG_BERRY_TREE_09":620,"FLAG_BERRY_TREE_10":621,"FLAG_BERRY_TREE_11":622,"FLAG_BERRY_TREE_12":623,"FLAG_BERRY_TREE_13":624,"FLAG_BERRY_TREE_14":625,"FLAG_BERRY_TREE_15":626,"FLAG_BERRY_TREE_16":627,"FLAG_BERRY_TREE_17":628,"FLAG_BERRY_TREE_18":629,"FLAG_BERRY_TREE_19":630,"FLAG_BERRY_TREE_20":631,"FLAG_BERRY_TREE_21":632,"FLAG_BERRY_TREE_22":633,"FLAG_BERRY_TREE_23":634,"FLAG_BERRY_TREE_24":635,"FLAG_BERRY_TREE_25":636,"FLAG_BERRY_TREE_26":637,"FLAG_BERRY_TREE_27":638,"FLAG_BERRY_TREE_28":639,"FLAG_BERRY_TREE_29":640,"FLAG_BERRY_TREE_30":641,"FLAG_BERRY_TREE_31":642,"FLAG_BERRY_TREE_32":643,"FLAG_BERRY_TREE_33":644,"FLAG_BERRY_TREE_34":645,"FLAG_BERRY_TREE_35":646,"FLAG_BERRY_TREE_36":647,"FLAG_BERRY_TREE_37":648,"FLAG_BERRY_TREE_38":649,"FLAG_BERRY_TREE_39":650,"FLAG_BERRY_TREE_40":651,"FLAG_BERRY_TREE_41":652,"FLAG_BERRY_TREE_42":653,"FLAG_BERRY_TREE_43":654,"FLAG_BERRY_TREE_44":655,"FLAG_BERRY_TREE_45":656,"FLAG_BERRY_TREE_46":657,"FLAG_BERRY_TREE_47":658,"FLAG_BERRY_TREE_48":659,"FLAG_BERRY_TREE_49":660,"FLAG_BERRY_TREE_50":661,"FLAG_BERRY_TREE_51":662,"FLAG_BERRY_TREE_52":663,"FLAG_BERRY_TREE_53":664,"FLAG_BERRY_TREE_54":665,"FLAG_BERRY_TREE_55":666,"FLAG_BERRY_TREE_56":667,"FLAG_BERRY_TREE_57":668,"FLAG_BERRY_TREE_58":669,"FLAG_BERRY_TREE_59":670,"FLAG_BERRY_TREE_60":671,"FLAG_BERRY_TREE_61":672,"FLAG_BERRY_TREE_62":673,"FLAG_BERRY_TREE_63":674,"FLAG_BERRY_TREE_64":675,"FLAG_BERRY_TREE_65":676,"FLAG_BERRY_TREE_66":677,"FLAG_BERRY_TREE_67":678,"FLAG_BERRY_TREE_68":679,"FLAG_BERRY_TREE_69":680,"FLAG_BERRY_TREE_70":681,"FLAG_BERRY_TREE_71":682,"FLAG_BERRY_TREE_72":683,"FLAG_BERRY_TREE_73":684,"FLAG_BERRY_TREE_74":685,"FLAG_BERRY_TREE_75":686,"FLAG_BERRY_TREE_76":687,"FLAG_BERRY_TREE_77":688,"FLAG_BERRY_TREE_78":689,"FLAG_BERRY_TREE_79":690,"FLAG_BERRY_TREE_80":691,"FLAG_BERRY_TREE_81":692,"FLAG_BERRY_TREE_82":693,"FLAG_BERRY_TREE_83":694,"FLAG_BERRY_TREE_84":695,"FLAG_BERRY_TREE_85":696,"FLAG_BERRY_TREE_86":697,"FLAG_BERRY_TREE_87":698,"FLAG_BERRY_TREE_88":699,"FLAG_BETTER_SHOPS_ENABLED":206,"FLAG_BIRCH_AIDE_MET":88,"FLAG_CANCEL_BATTLE_ROOM_CHALLENGE":119,"FLAG_CAUGHT_DEOXYS":429,"FLAG_CAUGHT_GROUDON":480,"FLAG_CAUGHT_HO_OH":146,"FLAG_CAUGHT_KYOGRE":479,"FLAG_CAUGHT_LATIAS":457,"FLAG_CAUGHT_LATIOS":482,"FLAG_CAUGHT_LUGIA":145,"FLAG_CAUGHT_MEW":458,"FLAG_CAUGHT_RAYQUAZA":478,"FLAG_CAUGHT_REGICE":427,"FLAG_CAUGHT_REGIROCK":426,"FLAG_CAUGHT_REGISTEEL":483,"FLAG_CHOSEN_MULTI_BATTLE_NPC_PARTNER":338,"FLAG_CHOSE_CLAW_FOSSIL":336,"FLAG_CHOSE_ROOT_FOSSIL":335,"FLAG_COLLECTED_ALL_GOLD_SYMBOLS":466,"FLAG_COLLECTED_ALL_SILVER_SYMBOLS":92,"FLAG_CONTEST_SKETCH_CREATED":270,"FLAG_COOL_PAINTING_MADE":160,"FLAG_CUTE_PAINTING_MADE":162,"FLAG_DAILY_APPRENTICE_LEAVES":2356,"FLAG_DAILY_BERRY_MASTERS_WIFE":2353,"FLAG_DAILY_BERRY_MASTER_RECEIVED_BERRY":2349,"FLAG_DAILY_CONTEST_LOBBY_RECEIVED_BERRY":2337,"FLAG_DAILY_FLOWER_SHOP_RECEIVED_BERRY":2352,"FLAG_DAILY_LILYCOVE_RECEIVED_BERRY":2351,"FLAG_DAILY_PICKED_LOTO_TICKET":2346,"FLAG_DAILY_ROUTE_111_RECEIVED_BERRY":2348,"FLAG_DAILY_ROUTE_114_RECEIVED_BERRY":2347,"FLAG_DAILY_ROUTE_120_RECEIVED_BERRY":2350,"FLAG_DAILY_SECRET_BASE":2338,"FLAG_DAILY_SOOTOPOLIS_RECEIVED_BERRY":2354,"FLAG_DECLINED_BIKE":89,"FLAG_DECLINED_RIVAL_BATTLE_LILYCOVE":286,"FLAG_DECLINED_WALLY_BATTLE_MAUVILLE":284,"FLAG_DECORATION_1":174,"FLAG_DECORATION_10":183,"FLAG_DECORATION_11":184,"FLAG_DECORATION_12":185,"FLAG_DECORATION_13":186,"FLAG_DECORATION_14":187,"FLAG_DECORATION_2":175,"FLAG_DECORATION_3":176,"FLAG_DECORATION_4":177,"FLAG_DECORATION_5":178,"FLAG_DECORATION_6":179,"FLAG_DECORATION_7":180,"FLAG_DECORATION_8":181,"FLAG_DECORATION_9":182,"FLAG_DEFEATED_DEOXYS":428,"FLAG_DEFEATED_DEWFORD_GYM":1265,"FLAG_DEFEATED_ELECTRODE_1_AQUA_HIDEOUT":452,"FLAG_DEFEATED_ELECTRODE_2_AQUA_HIDEOUT":453,"FLAG_DEFEATED_ELITE_4_DRAKE":1278,"FLAG_DEFEATED_ELITE_4_GLACIA":1277,"FLAG_DEFEATED_ELITE_4_PHOEBE":1276,"FLAG_DEFEATED_ELITE_4_SIDNEY":1275,"FLAG_DEFEATED_EVIL_TEAM_MT_CHIMNEY":139,"FLAG_DEFEATED_FORTREE_GYM":1269,"FLAG_DEFEATED_GROUDON":447,"FLAG_DEFEATED_GRUNT_SPACE_CENTER_1F":191,"FLAG_DEFEATED_HO_OH":476,"FLAG_DEFEATED_KECLEON_1_ROUTE_119":989,"FLAG_DEFEATED_KECLEON_1_ROUTE_120":982,"FLAG_DEFEATED_KECLEON_2_ROUTE_119":990,"FLAG_DEFEATED_KECLEON_2_ROUTE_120":985,"FLAG_DEFEATED_KECLEON_3_ROUTE_120":986,"FLAG_DEFEATED_KECLEON_4_ROUTE_120":987,"FLAG_DEFEATED_KECLEON_5_ROUTE_120":988,"FLAG_DEFEATED_KEKLEON_ROUTE_120_BRIDGE":970,"FLAG_DEFEATED_KYOGRE":446,"FLAG_DEFEATED_LATIAS":456,"FLAG_DEFEATED_LATIOS":481,"FLAG_DEFEATED_LAVARIDGE_GYM":1267,"FLAG_DEFEATED_LUGIA":477,"FLAG_DEFEATED_MAGMA_SPACE_CENTER":117,"FLAG_DEFEATED_MAUVILLE_GYM":1266,"FLAG_DEFEATED_METEOR_FALLS_STEVEN":1272,"FLAG_DEFEATED_MEW":455,"FLAG_DEFEATED_MOSSDEEP_GYM":1270,"FLAG_DEFEATED_PETALBURG_GYM":1268,"FLAG_DEFEATED_RAYQUAZA":448,"FLAG_DEFEATED_REGICE":444,"FLAG_DEFEATED_REGIROCK":443,"FLAG_DEFEATED_REGISTEEL":445,"FLAG_DEFEATED_RIVAL_ROUTE103":130,"FLAG_DEFEATED_RIVAL_ROUTE_104":125,"FLAG_DEFEATED_RIVAL_RUSTBORO":211,"FLAG_DEFEATED_RUSTBORO_GYM":1264,"FLAG_DEFEATED_SEASHORE_HOUSE":141,"FLAG_DEFEATED_SOOTOPOLIS_GYM":1271,"FLAG_DEFEATED_SS_TIDAL_TRAINERS":247,"FLAG_DEFEATED_SUDOWOODO":454,"FLAG_DEFEATED_VOLTORB_1_NEW_MAUVILLE":449,"FLAG_DEFEATED_VOLTORB_2_NEW_MAUVILLE":450,"FLAG_DEFEATED_VOLTORB_3_NEW_MAUVILLE":451,"FLAG_DEFEATED_WALLY_MAUVILLE":190,"FLAG_DEFEATED_WALLY_VICTORY_ROAD":126,"FLAG_DELIVERED_DEVON_GOODS":149,"FLAG_DELIVERED_STEVEN_LETTER":189,"FLAG_DEOXYS_IS_RECOVERING":1258,"FLAG_DEOXYS_ROCK_COMPLETE":2260,"FLAG_DEVON_GOODS_STOLEN":142,"FLAG_DOCK_REJECTED_DEVON_GOODS":148,"FLAG_DONT_TRANSITION_MUSIC":16385,"FLAG_ENABLE_BRAWLY_MATCH_CALL":468,"FLAG_ENABLE_FIRST_WALLY_POKENAV_CALL":136,"FLAG_ENABLE_FLANNERY_MATCH_CALL":470,"FLAG_ENABLE_JUAN_MATCH_CALL":473,"FLAG_ENABLE_MOM_MATCH_CALL":216,"FLAG_ENABLE_MR_STONE_POKENAV":344,"FLAG_ENABLE_MULTI_CORRIDOR_DOOR":16386,"FLAG_ENABLE_NORMAN_MATCH_CALL":306,"FLAG_ENABLE_PROF_BIRCH_MATCH_CALL":281,"FLAG_ENABLE_RIVAL_MATCH_CALL":253,"FLAG_ENABLE_ROXANNE_FIRST_CALL":128,"FLAG_ENABLE_ROXANNE_MATCH_CALL":467,"FLAG_ENABLE_SCOTT_MATCH_CALL":215,"FLAG_ENABLE_SHIP_BIRTH_ISLAND":2261,"FLAG_ENABLE_SHIP_FARAWAY_ISLAND":2262,"FLAG_ENABLE_SHIP_NAVEL_ROCK":2272,"FLAG_ENABLE_SHIP_SOUTHERN_ISLAND":2227,"FLAG_ENABLE_TATE_AND_LIZA_MATCH_CALL":472,"FLAG_ENABLE_WALLY_MATCH_CALL":214,"FLAG_ENABLE_WATTSON_MATCH_CALL":469,"FLAG_ENABLE_WINONA_MATCH_CALL":471,"FLAG_ENTERED_CONTEST":341,"FLAG_ENTERED_ELITE_FOUR":263,"FLAG_ENTERED_MIRAGE_TOWER":2268,"FLAG_EVIL_LEADER_PLEASE_STOP":219,"FLAG_EVIL_TEAM_ESCAPED_STERN_SPOKE":271,"FLAG_EXCHANGED_SCANNER":294,"FLAG_FAN_CLUB_STRENGTH_SHARED":210,"FLAG_FLOWER_SHOP_RECEIVED_BERRY":1207,"FLAG_FORCE_MIRAGE_TOWER_VISIBLE":157,"FLAG_FORTREE_NPC_TRADE_COMPLETED":155,"FLAG_GOOD_LUCK_SAFARI_ZONE":93,"FLAG_GOT_BASEMENT_KEY_FROM_WATTSON":208,"FLAG_GOT_TM_THUNDERBOLT_FROM_WATTSON":209,"FLAG_GROUDON_AWAKENED_MAGMA_HIDEOUT":111,"FLAG_GROUDON_IS_RECOVERING":1274,"FLAG_HAS_MATCH_CALL":303,"FLAG_HIDDEN_ITEMS_START":500,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":531,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":532,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":533,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":534,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":601,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":604,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":603,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":602,"FLAG_HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":528,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":548,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":549,"FLAG_HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":577,"FLAG_HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":576,"FLAG_HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":500,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":527,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":575,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":543,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":578,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":529,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":580,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":579,"FLAG_HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":609,"FLAG_HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":595,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":561,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POTION":558,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":559,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":560,"FLAG_HIDDEN_ITEM_ROUTE_104_ANTIDOTE":585,"FLAG_HIDDEN_ITEM_ROUTE_104_HEART_SCALE":588,"FLAG_HIDDEN_ITEM_ROUTE_104_POKE_BALL":562,"FLAG_HIDDEN_ITEM_ROUTE_104_POTION":537,"FLAG_HIDDEN_ITEM_ROUTE_104_SUPER_POTION":544,"FLAG_HIDDEN_ITEM_ROUTE_105_BIG_PEARL":611,"FLAG_HIDDEN_ITEM_ROUTE_105_HEART_SCALE":589,"FLAG_HIDDEN_ITEM_ROUTE_106_HEART_SCALE":547,"FLAG_HIDDEN_ITEM_ROUTE_106_POKE_BALL":563,"FLAG_HIDDEN_ITEM_ROUTE_106_STARDUST":546,"FLAG_HIDDEN_ITEM_ROUTE_108_RARE_CANDY":586,"FLAG_HIDDEN_ITEM_ROUTE_109_ETHER":564,"FLAG_HIDDEN_ITEM_ROUTE_109_GREAT_BALL":551,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":552,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":590,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":591,"FLAG_HIDDEN_ITEM_ROUTE_109_REVIVE":550,"FLAG_HIDDEN_ITEM_ROUTE_110_FULL_HEAL":555,"FLAG_HIDDEN_ITEM_ROUTE_110_GREAT_BALL":553,"FLAG_HIDDEN_ITEM_ROUTE_110_POKE_BALL":565,"FLAG_HIDDEN_ITEM_ROUTE_110_REVIVE":554,"FLAG_HIDDEN_ITEM_ROUTE_111_PROTEIN":556,"FLAG_HIDDEN_ITEM_ROUTE_111_RARE_CANDY":557,"FLAG_HIDDEN_ITEM_ROUTE_111_STARDUST":502,"FLAG_HIDDEN_ITEM_ROUTE_113_ETHER":503,"FLAG_HIDDEN_ITEM_ROUTE_113_NUGGET":598,"FLAG_HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":530,"FLAG_HIDDEN_ITEM_ROUTE_114_CARBOS":504,"FLAG_HIDDEN_ITEM_ROUTE_114_REVIVE":542,"FLAG_HIDDEN_ITEM_ROUTE_115_HEART_SCALE":597,"FLAG_HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":596,"FLAG_HIDDEN_ITEM_ROUTE_116_SUPER_POTION":545,"FLAG_HIDDEN_ITEM_ROUTE_117_REPEL":572,"FLAG_HIDDEN_ITEM_ROUTE_118_HEART_SCALE":566,"FLAG_HIDDEN_ITEM_ROUTE_118_IRON":567,"FLAG_HIDDEN_ITEM_ROUTE_119_CALCIUM":505,"FLAG_HIDDEN_ITEM_ROUTE_119_FULL_HEAL":568,"FLAG_HIDDEN_ITEM_ROUTE_119_MAX_ETHER":587,"FLAG_HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":506,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":571,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":569,"FLAG_HIDDEN_ITEM_ROUTE_120_REVIVE":584,"FLAG_HIDDEN_ITEM_ROUTE_120_ZINC":570,"FLAG_HIDDEN_ITEM_ROUTE_121_FULL_HEAL":573,"FLAG_HIDDEN_ITEM_ROUTE_121_HP_UP":539,"FLAG_HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":600,"FLAG_HIDDEN_ITEM_ROUTE_121_NUGGET":540,"FLAG_HIDDEN_ITEM_ROUTE_123_HYPER_POTION":574,"FLAG_HIDDEN_ITEM_ROUTE_123_PP_UP":599,"FLAG_HIDDEN_ITEM_ROUTE_123_RARE_CANDY":610,"FLAG_HIDDEN_ITEM_ROUTE_123_REVIVE":541,"FLAG_HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":507,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":592,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":593,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":594,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":606,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":607,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":605,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":608,"FLAG_HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":535,"FLAG_HIDDEN_ITEM_TRICK_HOUSE_NUGGET":501,"FLAG_HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":511,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CALCIUM":536,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CARBOS":508,"FLAG_HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":509,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":513,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":538,"FLAG_HIDDEN_ITEM_UNDERWATER_124_PEARL":510,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":520,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":512,"FLAG_HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":514,"FLAG_HIDDEN_ITEM_UNDERWATER_126_IRON":519,"FLAG_HIDDEN_ITEM_UNDERWATER_126_PEARL":517,"FLAG_HIDDEN_ITEM_UNDERWATER_126_STARDUST":516,"FLAG_HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":515,"FLAG_HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":518,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":523,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HP_UP":522,"FLAG_HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":524,"FLAG_HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":521,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PEARL":526,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PROTEIN":525,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":581,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":582,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":583,"FLAG_HIDE_APPRENTICE":701,"FLAG_HIDE_AQUA_HIDEOUT_1F_GRUNTS_BLOCKING_ENTRANCE":821,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_1":977,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_2":978,"FLAG_HIDE_AQUA_HIDEOUT_B2F_SUBMARINE_SHADOW":943,"FLAG_HIDE_AQUA_HIDEOUT_GRUNTS":924,"FLAG_HIDE_BATTLE_FRONTIER_RECEPTION_GATE_SCOTT":836,"FLAG_HIDE_BATTLE_FRONTIER_SUDOWOODO":842,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_1":711,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_2":712,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_3":713,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_4":714,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_5":715,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_6":716,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_1":864,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_2":865,"FLAG_HIDE_BATTLE_TOWER_OPPONENT":888,"FLAG_HIDE_BATTLE_TOWER_REPORTER":918,"FLAG_HIDE_BIRTH_ISLAND_DEOXYS_TRIANGLE":764,"FLAG_HIDE_BRINEYS_HOUSE_MR_BRINEY":739,"FLAG_HIDE_BRINEYS_HOUSE_PEEKO":881,"FLAG_HIDE_CAVE_OF_ORIGIN_B1F_WALLACE":820,"FLAG_HIDE_CHAMPIONS_ROOM_BIRCH":921,"FLAG_HIDE_CHAMPIONS_ROOM_RIVAL":920,"FLAG_HIDE_CONTEST_POKE_BALL":86,"FLAG_HIDE_DEOXYS":763,"FLAG_HIDE_DESERT_UNDERPASS_FOSSIL":874,"FLAG_HIDE_DEWFORD_HALL_SLUDGE_BOMB_MAN":940,"FLAG_HIDE_EVER_GRANDE_POKEMON_CENTER_1F_SCOTT":793,"FLAG_HIDE_FALLARBOR_AZURILL":907,"FLAG_HIDE_FALLARBOR_HOUSE_PROF_COZMO":928,"FLAG_HIDE_FALLARBOR_TOWN_BATTLE_TENT_SCOTT":767,"FLAG_HIDE_FALLORBOR_POKEMON_CENTER_LANETTE":871,"FLAG_HIDE_FANCLUB_BOY":790,"FLAG_HIDE_FANCLUB_LADY":792,"FLAG_HIDE_FANCLUB_LITTLE_BOY":791,"FLAG_HIDE_FANCLUB_OLD_LADY":789,"FLAG_HIDE_FORTREE_CITY_HOUSE_4_WINGULL":933,"FLAG_HIDE_FORTREE_CITY_KECLEON":969,"FLAG_HIDE_GRANITE_CAVE_STEVEN":833,"FLAG_HIDE_HO_OH":801,"FLAG_HIDE_JAGGED_PASS_MAGMA_GUARD":847,"FLAG_HIDE_LANETTES_HOUSE_LANETTE":870,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL":929,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL_ON_BIKE":930,"FLAG_HIDE_LILYCOVE_CITY_AQUA_GRUNTS":852,"FLAG_HIDE_LILYCOVE_CITY_RIVAL":971,"FLAG_HIDE_LILYCOVE_CITY_WAILMER":729,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER":832,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER_REPLACEMENT":873,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_1":774,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_2":895,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_REPORTER":802,"FLAG_HIDE_LILYCOVE_DEPARTMENT_STORE_ROOFTOP_SALE_WOMAN":962,"FLAG_HIDE_LILYCOVE_FAN_CLUB_INTERVIEWER":730,"FLAG_HIDE_LILYCOVE_HARBOR_EVENT_TICKET_TAKER":748,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_ATTENDANT":908,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_SAILOR":909,"FLAG_HIDE_LILYCOVE_HARBOR_SSTIDAL":861,"FLAG_HIDE_LILYCOVE_MOTEL_GAME_DESIGNERS":925,"FLAG_HIDE_LILYCOVE_MOTEL_SCOTT":787,"FLAG_HIDE_LILYCOVE_MUSEUM_CURATOR":775,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_1":776,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_2":777,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_3":778,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_4":779,"FLAG_HIDE_LILYCOVE_MUSEUM_TOURISTS":780,"FLAG_HIDE_LILYCOVE_POKEMON_CENTER_CONTEST_LADY_MON":993,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCH":795,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_BIRCH":721,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CHIKORITA":838,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CYNDAQUIL":811,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_TOTODILE":812,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_RIVAL":889,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_UNKNOWN_0x380":896,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_POKE_BALL":817,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_SWABLU_DOLL":815,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_BRENDAN":745,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_MOM":758,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_BEDROOM":760,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_MOM":784,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_SIBLING":735,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_TRUCK":761,"FLAG_HIDE_LITTLEROOT_TOWN_FAT_MAN":868,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_PICHU_DOLL":849,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_POKE_BALL":818,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MAY":746,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MOM":759,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_BEDROOM":722,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_MOM":785,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_SIBLING":736,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_TRUCK":762,"FLAG_HIDE_LITTLEROOT_TOWN_MOM_OUTSIDE":752,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_BEDROOM_MOM":757,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_1":754,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_2":755,"FLAG_HIDE_LITTLEROOT_TOWN_RIVAL":794,"FLAG_HIDE_LUGIA":800,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON":853,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON_ASLEEP":850,"FLAG_HIDE_MAGMA_HIDEOUT_GRUNTS":857,"FLAG_HIDE_MAGMA_HIDEOUT_MAXIE":867,"FLAG_HIDE_MAP_NAME_POPUP":16384,"FLAG_HIDE_MARINE_CAVE_KYOGRE":782,"FLAG_HIDE_MAUVILLE_CITY_SCOTT":765,"FLAG_HIDE_MAUVILLE_CITY_WALLY":804,"FLAG_HIDE_MAUVILLE_CITY_WALLYS_UNCLE":805,"FLAG_HIDE_MAUVILLE_CITY_WATTSON":912,"FLAG_HIDE_MAUVILLE_GYM_WATTSON":913,"FLAG_HIDE_METEOR_FALLS_1F_1R_COZMO":942,"FLAG_HIDE_METEOR_FALLS_TEAM_AQUA":938,"FLAG_HIDE_METEOR_FALLS_TEAM_MAGMA":939,"FLAG_HIDE_MEW":718,"FLAG_HIDE_MIRAGE_TOWER_CLAW_FOSSIL":964,"FLAG_HIDE_MIRAGE_TOWER_ROOT_FOSSIL":963,"FLAG_HIDE_MOSSDEEP_CITY_HOUSE_2_WINGULL":934,"FLAG_HIDE_MOSSDEEP_CITY_SCOTT":788,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_STEVEN":753,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_TEAM_MAGMA":756,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_STEVEN":863,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_TEAM_MAGMA":862,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_MAGMA_NOTE":737,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_BELDUM_POKEBALL":968,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_INVISIBLE_NINJA_BOY":727,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_STEVEN":967,"FLAG_HIDE_MOSSDEEP_CITY_TEAM_MAGMA":823,"FLAG_HIDE_MR_BRINEY_BOAT_DEWFORD_TOWN":743,"FLAG_HIDE_MR_BRINEY_DEWFORD_TOWN":740,"FLAG_HIDE_MT_CHIMNEY_LAVA_COOKIE_LADY":994,"FLAG_HIDE_MT_CHIMNEY_TEAM_AQUA":926,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA":927,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA_BATTLEABLE":981,"FLAG_HIDE_MT_CHIMNEY_TRAINERS":877,"FLAG_HIDE_MT_PYRE_SUMMIT_ARCHIE":916,"FLAG_HIDE_MT_PYRE_SUMMIT_MAXIE":856,"FLAG_HIDE_MT_PYRE_SUMMIT_TEAM_AQUA":917,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_1":974,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_2":975,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_3":976,"FLAG_HIDE_OLDALE_TOWN_RIVAL":979,"FLAG_HIDE_PETALBURG_CITY_SCOTT":995,"FLAG_HIDE_PETALBURG_CITY_WALLY":726,"FLAG_HIDE_PETALBURG_CITY_WALLYS_DAD":830,"FLAG_HIDE_PETALBURG_CITY_WALLYS_MOM":728,"FLAG_HIDE_PETALBURG_GYM_GREETER":781,"FLAG_HIDE_PETALBURG_GYM_NORMAN":772,"FLAG_HIDE_PETALBURG_GYM_WALLY":866,"FLAG_HIDE_PETALBURG_GYM_WALLYS_DAD":824,"FLAG_HIDE_PETALBURG_WOODS_AQUA_GRUNT":725,"FLAG_HIDE_PETALBURG_WOODS_DEVON_EMPLOYEE":724,"FLAG_HIDE_PLAYERS_HOUSE_DAD":734,"FLAG_HIDE_POKEMON_CENTER_2F_MYSTERY_GIFT_MAN":702,"FLAG_HIDE_REGICE":936,"FLAG_HIDE_REGIROCK":935,"FLAG_HIDE_REGISTEEL":937,"FLAG_HIDE_ROUTE_101_BIRCH":897,"FLAG_HIDE_ROUTE_101_BIRCH_STARTERS_BAG":700,"FLAG_HIDE_ROUTE_101_BIRCH_ZIGZAGOON_BATTLE":720,"FLAG_HIDE_ROUTE_101_BOY":991,"FLAG_HIDE_ROUTE_101_ZIGZAGOON":750,"FLAG_HIDE_ROUTE_103_BIRCH":898,"FLAG_HIDE_ROUTE_103_RIVAL":723,"FLAG_HIDE_ROUTE_104_MR_BRINEY":738,"FLAG_HIDE_ROUTE_104_MR_BRINEY_BOAT":742,"FLAG_HIDE_ROUTE_104_RIVAL":719,"FLAG_HIDE_ROUTE_104_WHITE_HERB_FLORIST":906,"FLAG_HIDE_ROUTE_109_MR_BRINEY":741,"FLAG_HIDE_ROUTE_109_MR_BRINEY_BOAT":744,"FLAG_HIDE_ROUTE_110_BIRCH":837,"FLAG_HIDE_ROUTE_110_RIVAL":919,"FLAG_HIDE_ROUTE_110_RIVAL_ON_BIKE":922,"FLAG_HIDE_ROUTE_110_TEAM_AQUA":900,"FLAG_HIDE_ROUTE_111_DESERT_FOSSIL":876,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_1":796,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_2":903,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_3":799,"FLAG_HIDE_ROUTE_111_PLAYER_DESCENT":875,"FLAG_HIDE_ROUTE_111_ROCK_SMASH_TIP_GUY":843,"FLAG_HIDE_ROUTE_111_SECRET_POWER_MAN":960,"FLAG_HIDE_ROUTE_111_VICKY_WINSTRATE":771,"FLAG_HIDE_ROUTE_111_VICTORIA_WINSTRATE":769,"FLAG_HIDE_ROUTE_111_VICTOR_WINSTRATE":768,"FLAG_HIDE_ROUTE_111_VIVI_WINSTRATE":770,"FLAG_HIDE_ROUTE_112_TEAM_MAGMA":819,"FLAG_HIDE_ROUTE_115_BOULDERS":825,"FLAG_HIDE_ROUTE_116_DEVON_EMPLOYEE":947,"FLAG_HIDE_ROUTE_116_DROPPED_GLASSES_MAN":813,"FLAG_HIDE_ROUTE_116_MR_BRINEY":891,"FLAG_HIDE_ROUTE_116_WANDAS_BOYFRIEND":894,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_1":797,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_2":901,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_3":904,"FLAG_HIDE_ROUTE_118_STEVEN":966,"FLAG_HIDE_ROUTE_119_RIVAL":851,"FLAG_HIDE_ROUTE_119_RIVAL_ON_BIKE":923,"FLAG_HIDE_ROUTE_119_SCOTT":786,"FLAG_HIDE_ROUTE_119_TEAM_AQUA":890,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_BRIDGE":822,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_SHELLY":915,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_1":798,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_2":902,"FLAG_HIDE_ROUTE_120_STEVEN":972,"FLAG_HIDE_ROUTE_121_TEAM_AQUA_GRUNTS":914,"FLAG_HIDE_ROUTE_128_ARCHIE":944,"FLAG_HIDE_ROUTE_128_MAXIE":945,"FLAG_HIDE_ROUTE_128_STEVEN":834,"FLAG_HIDE_RUSTBORO_CITY_AQUA_GRUNT":731,"FLAG_HIDE_RUSTBORO_CITY_DEVON_CORP_3F_EMPLOYEE":949,"FLAG_HIDE_RUSTBORO_CITY_DEVON_EMPLOYEE_1":732,"FLAG_HIDE_RUSTBORO_CITY_POKEMON_SCHOOL_SCOTT":999,"FLAG_HIDE_RUSTBORO_CITY_RIVAL":814,"FLAG_HIDE_RUSTBORO_CITY_SCIENTIST":844,"FLAG_HIDE_RUSTURF_TUNNEL_AQUA_GRUNT":878,"FLAG_HIDE_RUSTURF_TUNNEL_BRINEY":879,"FLAG_HIDE_RUSTURF_TUNNEL_PEEKO":880,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_1":931,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_2":932,"FLAG_HIDE_RUSTURF_TUNNEL_WANDA":983,"FLAG_HIDE_RUSTURF_TUNNEL_WANDAS_BOYFRIEND":807,"FLAG_HIDE_SAFARI_ZONE_SOUTH_CONSTRUCTION_WORKERS":717,"FLAG_HIDE_SAFARI_ZONE_SOUTH_EAST_EXPANSION":747,"FLAG_HIDE_SEAFLOOR_CAVERN_AQUA_GRUNTS":946,"FLAG_HIDE_SEAFLOOR_CAVERN_ENTRANCE_AQUA_GRUNT":941,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_ARCHIE":828,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE":859,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE_ASLEEP":733,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAGMA_GRUNTS":831,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAXIE":829,"FLAG_HIDE_SECRET_BASE_TRAINER":173,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA":773,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA_STILL":80,"FLAG_HIDE_SKY_PILLAR_WALLACE":855,"FLAG_HIDE_SLATEPORT_CITY_CAPTAIN_STERN":840,"FLAG_HIDE_SLATEPORT_CITY_CONTEST_REPORTER":803,"FLAG_HIDE_SLATEPORT_CITY_GABBY_AND_TY":835,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_AQUA_GRUNT":845,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_ARCHIE":846,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_CAPTAIN_STERN":841,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_PATRONS":905,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SS_TIDAL":860,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SUBMARINE_SHADOW":848,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_1":884,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_2":885,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_ARCHIE":886,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_CAPTAIN_STERN":887,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_AQUA_GRUNTS":883,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_FAMILIAR_AQUA_GRUNT":965,"FLAG_HIDE_SLATEPORT_CITY_SCOTT":749,"FLAG_HIDE_SLATEPORT_CITY_STERNS_SHIPYARD_MR_BRINEY":869,"FLAG_HIDE_SLATEPORT_CITY_TEAM_AQUA":882,"FLAG_HIDE_SLATEPORT_CITY_TM_SALESMAN":948,"FLAG_HIDE_SLATEPORT_MUSEUM_POPULATION":961,"FLAG_HIDE_SOOTOPOLIS_CITY_ARCHIE":826,"FLAG_HIDE_SOOTOPOLIS_CITY_GROUDON":998,"FLAG_HIDE_SOOTOPOLIS_CITY_KYOGRE":997,"FLAG_HIDE_SOOTOPOLIS_CITY_MAN_1":839,"FLAG_HIDE_SOOTOPOLIS_CITY_MAXIE":827,"FLAG_HIDE_SOOTOPOLIS_CITY_RAYQUAZA":996,"FLAG_HIDE_SOOTOPOLIS_CITY_RESIDENTS":854,"FLAG_HIDE_SOOTOPOLIS_CITY_STEVEN":973,"FLAG_HIDE_SOOTOPOLIS_CITY_WALLACE":816,"FLAG_HIDE_SOUTHERN_ISLAND_EON_STONE":910,"FLAG_HIDE_SOUTHERN_ISLAND_UNCHOSEN_EON_DUO_MON":911,"FLAG_HIDE_SS_TIDAL_CORRIDOR_MR_BRINEY":950,"FLAG_HIDE_SS_TIDAL_CORRIDOR_SCOTT":810,"FLAG_HIDE_SS_TIDAL_ROOMS_SNATCH_GIVER":951,"FLAG_HIDE_TERRA_CAVE_GROUDON":783,"FLAG_HIDE_TRICK_HOUSE_END_MAN":899,"FLAG_HIDE_TRICK_HOUSE_ENTRANCE_MAN":872,"FLAG_HIDE_UNDERWATER_SEA_FLOOR_CAVERN_STOLEN_SUBMARINE":980,"FLAG_HIDE_UNION_ROOM_PLAYER_1":703,"FLAG_HIDE_UNION_ROOM_PLAYER_2":704,"FLAG_HIDE_UNION_ROOM_PLAYER_3":705,"FLAG_HIDE_UNION_ROOM_PLAYER_4":706,"FLAG_HIDE_UNION_ROOM_PLAYER_5":707,"FLAG_HIDE_UNION_ROOM_PLAYER_6":708,"FLAG_HIDE_UNION_ROOM_PLAYER_7":709,"FLAG_HIDE_UNION_ROOM_PLAYER_8":710,"FLAG_HIDE_VERDANTURF_TOWN_SCOTT":766,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLY":806,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLYS_UNCLE":809,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDA":984,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDAS_BOYFRIEND":808,"FLAG_HIDE_VICTORY_ROAD_ENTRANCE_WALLY":858,"FLAG_HIDE_VICTORY_ROAD_EXIT_WALLY":751,"FLAG_HIDE_WEATHER_INSTITUTE_1F_WORKERS":892,"FLAG_HIDE_WEATHER_INSTITUTE_2F_AQUA_GRUNT_M":992,"FLAG_HIDE_WEATHER_INSTITUTE_2F_WORKERS":893,"FLAG_HO_OH_IS_RECOVERING":1256,"FLAG_INTERACTED_WITH_DEVON_EMPLOYEE_GOODS_STOLEN":159,"FLAG_INTERACTED_WITH_STEVEN_SPACE_CENTER":205,"FLAG_IS_CHAMPION":2175,"FLAG_ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":1100,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":1102,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":1078,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":1101,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":1077,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":1095,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":1099,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":1097,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":1096,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":1098,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":1124,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":1071,"FLAG_ITEM_AQUA_HIDEOUT_B1F_NUGGET":1132,"FLAG_ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":1072,"FLAG_ITEM_ARTISAN_CAVE_1F_CARBOS":1163,"FLAG_ITEM_ARTISAN_CAVE_B1F_HP_UP":1162,"FLAG_ITEM_FIERY_PATH_FIRE_STONE":1111,"FLAG_ITEM_FIERY_PATH_TM_TOXIC":1091,"FLAG_ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":1050,"FLAG_ITEM_GRANITE_CAVE_B1F_POKE_BALL":1051,"FLAG_ITEM_GRANITE_CAVE_B2F_RARE_CANDY":1054,"FLAG_ITEM_GRANITE_CAVE_B2F_REPEL":1053,"FLAG_ITEM_JAGGED_PASS_BURN_HEAL":1070,"FLAG_ITEM_LILYCOVE_CITY_MAX_REPEL":1042,"FLAG_ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":1151,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":1165,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":1164,"FLAG_ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":1166,"FLAG_ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":1167,"FLAG_ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":1059,"FLAG_ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":1168,"FLAG_ITEM_MAUVILLE_CITY_X_SPEED":1116,"FLAG_ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":1045,"FLAG_ITEM_METEOR_FALLS_1F_1R_MOON_STONE":1046,"FLAG_ITEM_METEOR_FALLS_1F_1R_PP_UP":1047,"FLAG_ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":1044,"FLAG_ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":1080,"FLAG_ITEM_MOSSDEEP_CITY_NET_BALL":1043,"FLAG_ITEM_MOSSDEEP_STEVENS_HOUSE_HM08":1133,"FLAG_ITEM_MT_PYRE_2F_ULTRA_BALL":1129,"FLAG_ITEM_MT_PYRE_3F_SUPER_REPEL":1120,"FLAG_ITEM_MT_PYRE_4F_SEA_INCENSE":1130,"FLAG_ITEM_MT_PYRE_5F_LAX_INCENSE":1052,"FLAG_ITEM_MT_PYRE_6F_TM_SHADOW_BALL":1089,"FLAG_ITEM_MT_PYRE_EXTERIOR_MAX_POTION":1073,"FLAG_ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":1074,"FLAG_ITEM_NEW_MAUVILLE_ESCAPE_ROPE":1076,"FLAG_ITEM_NEW_MAUVILLE_FULL_HEAL":1122,"FLAG_ITEM_NEW_MAUVILLE_PARALYZE_HEAL":1123,"FLAG_ITEM_NEW_MAUVILLE_THUNDER_STONE":1110,"FLAG_ITEM_NEW_MAUVILLE_ULTRA_BALL":1075,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MASTER_BALL":1125,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MAX_ELIXIR":1126,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B2F_NEST_BALL":1127,"FLAG_ITEM_PETALBURG_CITY_ETHER":1040,"FLAG_ITEM_PETALBURG_CITY_MAX_REVIVE":1039,"FLAG_ITEM_PETALBURG_WOODS_ETHER":1058,"FLAG_ITEM_PETALBURG_WOODS_GREAT_BALL":1056,"FLAG_ITEM_PETALBURG_WOODS_PARALYZE_HEAL":1117,"FLAG_ITEM_PETALBURG_WOODS_X_ATTACK":1055,"FLAG_ITEM_ROUTE_102_POTION":1000,"FLAG_ITEM_ROUTE_103_GUARD_SPEC":1114,"FLAG_ITEM_ROUTE_103_PP_UP":1137,"FLAG_ITEM_ROUTE_104_POKE_BALL":1057,"FLAG_ITEM_ROUTE_104_POTION":1135,"FLAG_ITEM_ROUTE_104_PP_UP":1002,"FLAG_ITEM_ROUTE_104_X_ACCURACY":1115,"FLAG_ITEM_ROUTE_105_IRON":1003,"FLAG_ITEM_ROUTE_106_PROTEIN":1004,"FLAG_ITEM_ROUTE_108_STAR_PIECE":1139,"FLAG_ITEM_ROUTE_109_POTION":1140,"FLAG_ITEM_ROUTE_109_PP_UP":1005,"FLAG_ITEM_ROUTE_110_DIRE_HIT":1007,"FLAG_ITEM_ROUTE_110_ELIXIR":1141,"FLAG_ITEM_ROUTE_110_RARE_CANDY":1006,"FLAG_ITEM_ROUTE_111_ELIXIR":1142,"FLAG_ITEM_ROUTE_111_HP_UP":1010,"FLAG_ITEM_ROUTE_111_STARDUST":1009,"FLAG_ITEM_ROUTE_111_TM_SANDSTORM":1008,"FLAG_ITEM_ROUTE_112_NUGGET":1011,"FLAG_ITEM_ROUTE_113_HYPER_POTION":1143,"FLAG_ITEM_ROUTE_113_MAX_ETHER":1012,"FLAG_ITEM_ROUTE_113_SUPER_REPEL":1013,"FLAG_ITEM_ROUTE_114_ENERGY_POWDER":1160,"FLAG_ITEM_ROUTE_114_PROTEIN":1015,"FLAG_ITEM_ROUTE_114_RARE_CANDY":1014,"FLAG_ITEM_ROUTE_115_GREAT_BALL":1118,"FLAG_ITEM_ROUTE_115_HEAL_POWDER":1144,"FLAG_ITEM_ROUTE_115_IRON":1018,"FLAG_ITEM_ROUTE_115_PP_UP":1161,"FLAG_ITEM_ROUTE_115_SUPER_POTION":1016,"FLAG_ITEM_ROUTE_115_TM_FOCUS_PUNCH":1017,"FLAG_ITEM_ROUTE_116_ETHER":1019,"FLAG_ITEM_ROUTE_116_HP_UP":1021,"FLAG_ITEM_ROUTE_116_POTION":1146,"FLAG_ITEM_ROUTE_116_REPEL":1020,"FLAG_ITEM_ROUTE_116_X_SPECIAL":1001,"FLAG_ITEM_ROUTE_117_GREAT_BALL":1022,"FLAG_ITEM_ROUTE_117_REVIVE":1023,"FLAG_ITEM_ROUTE_118_HYPER_POTION":1121,"FLAG_ITEM_ROUTE_119_ELIXIR_1":1026,"FLAG_ITEM_ROUTE_119_ELIXIR_2":1147,"FLAG_ITEM_ROUTE_119_HYPER_POTION_1":1029,"FLAG_ITEM_ROUTE_119_HYPER_POTION_2":1106,"FLAG_ITEM_ROUTE_119_LEAF_STONE":1027,"FLAG_ITEM_ROUTE_119_NUGGET":1134,"FLAG_ITEM_ROUTE_119_RARE_CANDY":1028,"FLAG_ITEM_ROUTE_119_SUPER_REPEL":1024,"FLAG_ITEM_ROUTE_119_ZINC":1025,"FLAG_ITEM_ROUTE_120_FULL_HEAL":1031,"FLAG_ITEM_ROUTE_120_HYPER_POTION":1107,"FLAG_ITEM_ROUTE_120_NEST_BALL":1108,"FLAG_ITEM_ROUTE_120_NUGGET":1030,"FLAG_ITEM_ROUTE_120_REVIVE":1148,"FLAG_ITEM_ROUTE_121_CARBOS":1103,"FLAG_ITEM_ROUTE_121_REVIVE":1149,"FLAG_ITEM_ROUTE_121_ZINC":1150,"FLAG_ITEM_ROUTE_123_CALCIUM":1032,"FLAG_ITEM_ROUTE_123_ELIXIR":1109,"FLAG_ITEM_ROUTE_123_PP_UP":1152,"FLAG_ITEM_ROUTE_123_REVIVAL_HERB":1153,"FLAG_ITEM_ROUTE_123_ULTRA_BALL":1104,"FLAG_ITEM_ROUTE_124_BLUE_SHARD":1093,"FLAG_ITEM_ROUTE_124_RED_SHARD":1092,"FLAG_ITEM_ROUTE_124_YELLOW_SHARD":1066,"FLAG_ITEM_ROUTE_125_BIG_PEARL":1154,"FLAG_ITEM_ROUTE_126_GREEN_SHARD":1105,"FLAG_ITEM_ROUTE_127_CARBOS":1035,"FLAG_ITEM_ROUTE_127_RARE_CANDY":1155,"FLAG_ITEM_ROUTE_127_ZINC":1034,"FLAG_ITEM_ROUTE_132_PROTEIN":1156,"FLAG_ITEM_ROUTE_132_RARE_CANDY":1036,"FLAG_ITEM_ROUTE_133_BIG_PEARL":1037,"FLAG_ITEM_ROUTE_133_MAX_REVIVE":1157,"FLAG_ITEM_ROUTE_133_STAR_PIECE":1038,"FLAG_ITEM_ROUTE_134_CARBOS":1158,"FLAG_ITEM_ROUTE_134_STAR_PIECE":1159,"FLAG_ITEM_RUSTBORO_CITY_X_DEFEND":1041,"FLAG_ITEM_RUSTURF_TUNNEL_MAX_ETHER":1049,"FLAG_ITEM_RUSTURF_TUNNEL_POKE_BALL":1048,"FLAG_ITEM_SAFARI_ZONE_NORTH_CALCIUM":1119,"FLAG_ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":1169,"FLAG_ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":1094,"FLAG_ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":1170,"FLAG_ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":1131,"FLAG_ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":1079,"FLAG_ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":1090,"FLAG_ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":1081,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":1113,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":1112,"FLAG_ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":1082,"FLAG_ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":1083,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":1060,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":1061,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":1062,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":1063,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":1064,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":1065,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":1067,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":1068,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":1069,"FLAG_ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":1084,"FLAG_ITEM_VICTORY_ROAD_1F_PP_UP":1085,"FLAG_ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":1087,"FLAG_ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":1086,"FLAG_ITEM_VICTORY_ROAD_B2F_FULL_HEAL":1088,"FLAG_KECLEON_FLED_FORTREE":295,"FLAG_KYOGRE_ESCAPED_SEAFLOOR_CAVERN":129,"FLAG_KYOGRE_IS_RECOVERING":1273,"FLAG_LANDMARK_ABANDONED_SHIP":2206,"FLAG_LANDMARK_ALTERING_CAVE":2269,"FLAG_LANDMARK_ANCIENT_TOMB":2233,"FLAG_LANDMARK_ARTISAN_CAVE":2271,"FLAG_LANDMARK_BATTLE_FRONTIER":2216,"FLAG_LANDMARK_BERRY_MASTERS_HOUSE":2243,"FLAG_LANDMARK_DESERT_RUINS":2230,"FLAG_LANDMARK_DESERT_UNDERPASS":2270,"FLAG_LANDMARK_FIERY_PATH":2218,"FLAG_LANDMARK_FLOWER_SHOP":2204,"FLAG_LANDMARK_FOSSIL_MANIACS_HOUSE":2231,"FLAG_LANDMARK_GLASS_WORKSHOP":2212,"FLAG_LANDMARK_HUNTERS_HOUSE":2235,"FLAG_LANDMARK_ISLAND_CAVE":2229,"FLAG_LANDMARK_LANETTES_HOUSE":2213,"FLAG_LANDMARK_MIRAGE_TOWER":120,"FLAG_LANDMARK_MR_BRINEY_HOUSE":2205,"FLAG_LANDMARK_NEW_MAUVILLE":2208,"FLAG_LANDMARK_OLD_LADY_REST_SHOP":2209,"FLAG_LANDMARK_POKEMON_DAYCARE":2214,"FLAG_LANDMARK_POKEMON_LEAGUE":2228,"FLAG_LANDMARK_SCORCHED_SLAB":2232,"FLAG_LANDMARK_SEAFLOOR_CAVERN":2215,"FLAG_LANDMARK_SEALED_CHAMBER":2236,"FLAG_LANDMARK_SEASHORE_HOUSE":2207,"FLAG_LANDMARK_SKY_PILLAR":2238,"FLAG_LANDMARK_SOUTHERN_ISLAND":2217,"FLAG_LANDMARK_TRAINER_HILL":2274,"FLAG_LANDMARK_TRICK_HOUSE":2210,"FLAG_LANDMARK_TUNNELERS_REST_HOUSE":2234,"FLAG_LANDMARK_WINSTRATE_FAMILY":2211,"FLAG_LATIAS_IS_RECOVERING":1263,"FLAG_LATIOS_IS_RECOVERING":1255,"FLAG_LATIOS_OR_LATIAS_ROAMING":255,"FLAG_LEGENDARIES_IN_SOOTOPOLIS":83,"FLAG_LILYCOVE_RECEIVED_BERRY":1208,"FLAG_LUGIA_IS_RECOVERING":1257,"FLAG_MAP_SCRIPT_CHECKED_DEOXYS":2259,"FLAG_MATCH_CALL_REGISTERED":348,"FLAG_MAUVILLE_GYM_BARRIERS_STATE":99,"FLAG_MET_ARCHIE_METEOR_FALLS":207,"FLAG_MET_ARCHIE_SOOTOPOLIS":308,"FLAG_MET_BATTLE_FRONTIER_BREEDER":339,"FLAG_MET_BATTLE_FRONTIER_GAMBLER":343,"FLAG_MET_BATTLE_FRONTIER_MANIAC":340,"FLAG_MET_DEVON_EMPLOYEE":287,"FLAG_MET_DIVING_TREASURE_HUNTER":217,"FLAG_MET_FANCLUB_YOUNGER_BROTHER":300,"FLAG_MET_FRONTIER_BEAUTY_MOVE_TUTOR":346,"FLAG_MET_FRONTIER_SWIMMER_MOVE_TUTOR":347,"FLAG_MET_HIDDEN_POWER_GIVER":118,"FLAG_MET_MAXIE_SOOTOPOLIS":309,"FLAG_MET_PRETTY_PETAL_SHOP_OWNER":127,"FLAG_MET_PROF_COZMO":244,"FLAG_MET_RIVAL_IN_HOUSE_AFTER_LILYCOVE":293,"FLAG_MET_RIVAL_LILYCOVE":292,"FLAG_MET_RIVAL_MOM":87,"FLAG_MET_RIVAL_RUSTBORO":288,"FLAG_MET_SCOTT_AFTER_OBTAINING_STONE_BADGE":459,"FLAG_MET_SCOTT_IN_EVERGRANDE":463,"FLAG_MET_SCOTT_IN_FALLARBOR":461,"FLAG_MET_SCOTT_IN_LILYCOVE":462,"FLAG_MET_SCOTT_IN_VERDANTURF":460,"FLAG_MET_SCOTT_ON_SS_TIDAL":464,"FLAG_MET_SCOTT_RUSTBORO":310,"FLAG_MET_SLATEPORT_FANCLUB_CHAIRMAN":342,"FLAG_MET_TEAM_AQUA_HARBOR":97,"FLAG_MET_WAILMER_TRAINER":218,"FLAG_MEW_IS_RECOVERING":1259,"FLAG_MIRAGE_TOWER_VISIBLE":334,"FLAG_MOSSDEEP_GYM_SWITCH_1":100,"FLAG_MOSSDEEP_GYM_SWITCH_2":101,"FLAG_MOSSDEEP_GYM_SWITCH_3":102,"FLAG_MOSSDEEP_GYM_SWITCH_4":103,"FLAG_MOVE_TUTOR_TAUGHT_DOUBLE_EDGE":441,"FLAG_MOVE_TUTOR_TAUGHT_DYNAMICPUNCH":440,"FLAG_MOVE_TUTOR_TAUGHT_EXPLOSION":442,"FLAG_MOVE_TUTOR_TAUGHT_FURY_CUTTER":435,"FLAG_MOVE_TUTOR_TAUGHT_METRONOME":437,"FLAG_MOVE_TUTOR_TAUGHT_MIMIC":436,"FLAG_MOVE_TUTOR_TAUGHT_ROLLOUT":434,"FLAG_MOVE_TUTOR_TAUGHT_SLEEP_TALK":438,"FLAG_MOVE_TUTOR_TAUGHT_SUBSTITUTE":439,"FLAG_MOVE_TUTOR_TAUGHT_SWAGGER":433,"FLAG_MR_BRINEY_SAILING_INTRO":147,"FLAG_MYSTERY_GIFT_1":485,"FLAG_MYSTERY_GIFT_10":494,"FLAG_MYSTERY_GIFT_11":495,"FLAG_MYSTERY_GIFT_12":496,"FLAG_MYSTERY_GIFT_13":497,"FLAG_MYSTERY_GIFT_14":498,"FLAG_MYSTERY_GIFT_15":499,"FLAG_MYSTERY_GIFT_2":486,"FLAG_MYSTERY_GIFT_3":487,"FLAG_MYSTERY_GIFT_4":488,"FLAG_MYSTERY_GIFT_5":489,"FLAG_MYSTERY_GIFT_6":490,"FLAG_MYSTERY_GIFT_7":491,"FLAG_MYSTERY_GIFT_8":492,"FLAG_MYSTERY_GIFT_9":493,"FLAG_MYSTERY_GIFT_DONE":484,"FLAG_NEVER_SET_0x0DC":220,"FLAG_NOT_READY_FOR_BATTLE_ROUTE_120":290,"FLAG_NURSE_MENTIONS_GOLD_CARD":345,"FLAG_NURSE_UNION_ROOM_REMINDER":2176,"FLAG_OCEANIC_MUSEUM_MET_REPORTER":105,"FLAG_OMIT_DIVE_FROM_STEVEN_LETTER":302,"FLAG_PACIFIDLOG_NPC_TRADE_COMPLETED":154,"FLAG_PENDING_DAYCARE_EGG":134,"FLAG_PETALBURG_MART_EXPANDED_ITEMS":296,"FLAG_POKERUS_EXPLAINED":273,"FLAG_PURCHASED_HARBOR_MAIL":104,"FLAG_RAYQUAZA_IS_RECOVERING":1279,"FLAG_RECEIVED_20_COINS":225,"FLAG_RECEIVED_6_SODA_POP":140,"FLAG_RECEIVED_ACRO_BIKE":1181,"FLAG_RECEIVED_AMULET_COIN":133,"FLAG_RECEIVED_AURORA_TICKET":314,"FLAG_RECEIVED_BADGE_1":1182,"FLAG_RECEIVED_BADGE_2":1183,"FLAG_RECEIVED_BADGE_3":1184,"FLAG_RECEIVED_BADGE_4":1185,"FLAG_RECEIVED_BADGE_5":1186,"FLAG_RECEIVED_BADGE_6":1187,"FLAG_RECEIVED_BADGE_7":1188,"FLAG_RECEIVED_BADGE_8":1189,"FLAG_RECEIVED_BELDUM":298,"FLAG_RECEIVED_BELUE_BERRY":252,"FLAG_RECEIVED_BIKE":90,"FLAG_RECEIVED_BLUE_SCARF":201,"FLAG_RECEIVED_CASTFORM":151,"FLAG_RECEIVED_CHARCOAL":254,"FLAG_RECEIVED_CHESTO_BERRY_ROUTE_104":246,"FLAG_RECEIVED_CLEANSE_TAG":282,"FLAG_RECEIVED_COIN_CASE":258,"FLAG_RECEIVED_CONTEST_PASS":150,"FLAG_RECEIVED_DEEP_SEA_SCALE":1190,"FLAG_RECEIVED_DEEP_SEA_TOOTH":1191,"FLAG_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":1172,"FLAG_RECEIVED_DEVON_SCOPE":285,"FLAG_RECEIVED_DOLL_LANETTE":131,"FLAG_RECEIVED_DURIN_BERRY":251,"FLAG_RECEIVED_EON_TICKET":474,"FLAG_RECEIVED_EXP_SHARE":272,"FLAG_RECEIVED_FANCLUB_TM_THIS_WEEK":299,"FLAG_RECEIVED_FIRST_POKEBALLS":233,"FLAG_RECEIVED_FOCUS_BAND":283,"FLAG_RECEIVED_GLASS_ORNAMENT":236,"FLAG_RECEIVED_GOLD_SHIELD":238,"FLAG_RECEIVED_GOOD_ROD":227,"FLAG_RECEIVED_GO_GOGGLES":221,"FLAG_RECEIVED_GREAT_BALL_PETALBURG_WOODS":1171,"FLAG_RECEIVED_GREAT_BALL_RUSTBORO_CITY":1173,"FLAG_RECEIVED_GREEN_SCARF":203,"FLAG_RECEIVED_HM_CUT":137,"FLAG_RECEIVED_HM_DIVE":123,"FLAG_RECEIVED_HM_FLASH":109,"FLAG_RECEIVED_HM_FLY":110,"FLAG_RECEIVED_HM_ROCK_SMASH":107,"FLAG_RECEIVED_HM_STRENGTH":106,"FLAG_RECEIVED_HM_SURF":122,"FLAG_RECEIVED_HM_WATERFALL":312,"FLAG_RECEIVED_ITEMFINDER":1176,"FLAG_RECEIVED_KINGS_ROCK":276,"FLAG_RECEIVED_LAVARIDGE_EGG":266,"FLAG_RECEIVED_LETTER":1174,"FLAG_RECEIVED_MACHO_BRACE":277,"FLAG_RECEIVED_MACH_BIKE":1180,"FLAG_RECEIVED_MAGMA_EMBLEM":1177,"FLAG_RECEIVED_MENTAL_HERB":223,"FLAG_RECEIVED_METEORITE":115,"FLAG_RECEIVED_MIRACLE_SEED":297,"FLAG_RECEIVED_MYSTIC_TICKET":315,"FLAG_RECEIVED_OLD_ROD":257,"FLAG_RECEIVED_OLD_SEA_MAP":316,"FLAG_RECEIVED_PAMTRE_BERRY":249,"FLAG_RECEIVED_PINK_SCARF":202,"FLAG_RECEIVED_POKEBLOCK_CASE":95,"FLAG_RECEIVED_POKEDEX_FROM_BIRCH":2276,"FLAG_RECEIVED_POKENAV":188,"FLAG_RECEIVED_POTION_OLDALE":132,"FLAG_RECEIVED_POWDER_JAR":337,"FLAG_RECEIVED_PREMIER_BALL_RUSTBORO":213,"FLAG_RECEIVED_QUICK_CLAW":275,"FLAG_RECEIVED_RED_OR_BLUE_ORB":212,"FLAG_RECEIVED_RED_SCARF":200,"FLAG_RECEIVED_REPEAT_BALL":256,"FLAG_RECEIVED_REVIVED_FOSSIL_MON":267,"FLAG_RECEIVED_RUNNING_SHOES":274,"FLAG_RECEIVED_SECRET_POWER":96,"FLAG_RECEIVED_SHOAL_SALT_1":952,"FLAG_RECEIVED_SHOAL_SALT_2":953,"FLAG_RECEIVED_SHOAL_SALT_3":954,"FLAG_RECEIVED_SHOAL_SALT_4":955,"FLAG_RECEIVED_SHOAL_SHELL_1":956,"FLAG_RECEIVED_SHOAL_SHELL_2":957,"FLAG_RECEIVED_SHOAL_SHELL_3":958,"FLAG_RECEIVED_SHOAL_SHELL_4":959,"FLAG_RECEIVED_SILK_SCARF":289,"FLAG_RECEIVED_SILVER_SHIELD":237,"FLAG_RECEIVED_SOFT_SAND":280,"FLAG_RECEIVED_SOOTHE_BELL":278,"FLAG_RECEIVED_SOOT_SACK":1033,"FLAG_RECEIVED_SPECIAL_PHRASE_HINT":85,"FLAG_RECEIVED_SPELON_BERRY":248,"FLAG_RECEIVED_SS_TICKET":291,"FLAG_RECEIVED_STARTER_DOLL":226,"FLAG_RECEIVED_SUN_STONE_MOSSDEEP":192,"FLAG_RECEIVED_SUPER_ROD":152,"FLAG_RECEIVED_TM_AERIAL_ACE":170,"FLAG_RECEIVED_TM_ATTRACT":235,"FLAG_RECEIVED_TM_BRICK_BREAK":121,"FLAG_RECEIVED_TM_BULK_UP":166,"FLAG_RECEIVED_TM_BULLET_SEED":262,"FLAG_RECEIVED_TM_CALM_MIND":171,"FLAG_RECEIVED_TM_DIG":261,"FLAG_RECEIVED_TM_FACADE":169,"FLAG_RECEIVED_TM_FRUSTRATION":1179,"FLAG_RECEIVED_TM_GIGA_DRAIN":232,"FLAG_RECEIVED_TM_HIDDEN_POWER":264,"FLAG_RECEIVED_TM_OVERHEAT":168,"FLAG_RECEIVED_TM_REST":234,"FLAG_RECEIVED_TM_RETURN":229,"FLAG_RECEIVED_TM_RETURN_2":1178,"FLAG_RECEIVED_TM_ROAR":231,"FLAG_RECEIVED_TM_ROCK_TOMB":165,"FLAG_RECEIVED_TM_SHOCK_WAVE":167,"FLAG_RECEIVED_TM_SLUDGE_BOMB":230,"FLAG_RECEIVED_TM_SNATCH":260,"FLAG_RECEIVED_TM_STEEL_WING":1175,"FLAG_RECEIVED_TM_THIEF":269,"FLAG_RECEIVED_TM_TORMENT":265,"FLAG_RECEIVED_TM_WATER_PULSE":172,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_1":1200,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_2":1201,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_3":1202,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_4":1203,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_5":1204,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_6":1205,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_7":1206,"FLAG_RECEIVED_WAILMER_DOLL":245,"FLAG_RECEIVED_WAILMER_PAIL":94,"FLAG_RECEIVED_WATMEL_BERRY":250,"FLAG_RECEIVED_WHITE_HERB":279,"FLAG_RECEIVED_YELLOW_SCARF":204,"FLAG_RECOVERED_DEVON_GOODS":143,"FLAG_REGICE_IS_RECOVERING":1260,"FLAG_REGIROCK_IS_RECOVERING":1261,"FLAG_REGISTEEL_IS_RECOVERING":1262,"FLAG_REGISTERED_STEVEN_POKENAV":305,"FLAG_REGISTER_RIVAL_POKENAV":124,"FLAG_REGI_DOORS_OPENED":228,"FLAG_REMATCH_ABIGAIL":387,"FLAG_REMATCH_AMY_AND_LIV":399,"FLAG_REMATCH_ANDRES":350,"FLAG_REMATCH_ANNA_AND_MEG":378,"FLAG_REMATCH_BENJAMIN":390,"FLAG_REMATCH_BERNIE":369,"FLAG_REMATCH_BRAWLY":415,"FLAG_REMATCH_BROOKE":356,"FLAG_REMATCH_CALVIN":383,"FLAG_REMATCH_CAMERON":373,"FLAG_REMATCH_CATHERINE":406,"FLAG_REMATCH_CINDY":359,"FLAG_REMATCH_CORY":401,"FLAG_REMATCH_CRISTIN":355,"FLAG_REMATCH_CYNDY":395,"FLAG_REMATCH_DALTON":368,"FLAG_REMATCH_DIANA":398,"FLAG_REMATCH_DRAKE":424,"FLAG_REMATCH_DUSTY":351,"FLAG_REMATCH_DYLAN":388,"FLAG_REMATCH_EDWIN":402,"FLAG_REMATCH_ELLIOT":384,"FLAG_REMATCH_ERNEST":400,"FLAG_REMATCH_ETHAN":370,"FLAG_REMATCH_FERNANDO":367,"FLAG_REMATCH_FLANNERY":417,"FLAG_REMATCH_GABRIELLE":405,"FLAG_REMATCH_GLACIA":423,"FLAG_REMATCH_HALEY":408,"FLAG_REMATCH_ISAAC":404,"FLAG_REMATCH_ISABEL":379,"FLAG_REMATCH_ISAIAH":385,"FLAG_REMATCH_JACKI":374,"FLAG_REMATCH_JACKSON":407,"FLAG_REMATCH_JAMES":409,"FLAG_REMATCH_JEFFREY":372,"FLAG_REMATCH_JENNY":397,"FLAG_REMATCH_JERRY":377,"FLAG_REMATCH_JESSICA":361,"FLAG_REMATCH_JOHN_AND_JAY":371,"FLAG_REMATCH_KAREN":376,"FLAG_REMATCH_KATELYN":389,"FLAG_REMATCH_KIRA_AND_DAN":412,"FLAG_REMATCH_KOJI":366,"FLAG_REMATCH_LAO":394,"FLAG_REMATCH_LILA_AND_ROY":354,"FLAG_REMATCH_LOLA":352,"FLAG_REMATCH_LYDIA":403,"FLAG_REMATCH_MADELINE":396,"FLAG_REMATCH_MARIA":386,"FLAG_REMATCH_MIGUEL":380,"FLAG_REMATCH_NICOLAS":392,"FLAG_REMATCH_NOB":365,"FLAG_REMATCH_NORMAN":418,"FLAG_REMATCH_PABLO":391,"FLAG_REMATCH_PHOEBE":422,"FLAG_REMATCH_RICKY":353,"FLAG_REMATCH_ROBERT":393,"FLAG_REMATCH_ROSE":349,"FLAG_REMATCH_ROXANNE":414,"FLAG_REMATCH_SAWYER":411,"FLAG_REMATCH_SHELBY":382,"FLAG_REMATCH_SIDNEY":421,"FLAG_REMATCH_STEVE":363,"FLAG_REMATCH_TATE_AND_LIZA":420,"FLAG_REMATCH_THALIA":360,"FLAG_REMATCH_TIMOTHY":381,"FLAG_REMATCH_TONY":364,"FLAG_REMATCH_TRENT":410,"FLAG_REMATCH_VALERIE":358,"FLAG_REMATCH_WALLACE":425,"FLAG_REMATCH_WALLY":413,"FLAG_REMATCH_WALTER":375,"FLAG_REMATCH_WATTSON":416,"FLAG_REMATCH_WILTON":357,"FLAG_REMATCH_WINONA":419,"FLAG_REMATCH_WINSTON":362,"FLAG_RESCUED_BIRCH":82,"FLAG_RETURNED_DEVON_GOODS":144,"FLAG_RETURNED_RED_OR_BLUE_ORB":259,"FLAG_RIVAL_LEFT_FOR_ROUTE103":301,"FLAG_ROUTE_111_RECEIVED_BERRY":1192,"FLAG_ROUTE_114_RECEIVED_BERRY":1193,"FLAG_ROUTE_120_RECEIVED_BERRY":1194,"FLAG_RUSTBORO_NPC_TRADE_COMPLETED":153,"FLAG_RUSTURF_TUNNEL_OPENED":199,"FLAG_SCOTT_CALL_BATTLE_FRONTIER":114,"FLAG_SCOTT_CALL_FORTREE_GYM":138,"FLAG_SCOTT_GIVES_BATTLE_POINTS":465,"FLAG_SECRET_BASE_REGISTRY_ENABLED":268,"FLAG_SET_WALL_CLOCK":81,"FLAG_SHOWN_AURORA_TICKET":431,"FLAG_SHOWN_BOX_WAS_FULL_MESSAGE":2263,"FLAG_SHOWN_EON_TICKET":430,"FLAG_SHOWN_MYSTIC_TICKET":475,"FLAG_SHOWN_OLD_SEA_MAP":432,"FLAG_SMART_PAINTING_MADE":163,"FLAG_SOOTOPOLIS_ARCHIE_MAXIE_LEAVE":158,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_1":1198,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_2":1199,"FLAG_SPECIAL_FLAG_UNUSED_0x4003":16387,"FLAG_SS_TIDAL_DISABLED":84,"FLAG_STEVEN_GUIDES_TO_CAVE_OF_ORIGIN":307,"FLAG_STORING_ITEMS_IN_PYRAMID_BAG":16388,"FLAG_SYS_ARENA_GOLD":2251,"FLAG_SYS_ARENA_SILVER":2250,"FLAG_SYS_BRAILLE_DIG":2223,"FLAG_SYS_BRAILLE_REGICE_COMPLETED":2225,"FLAG_SYS_B_DASH":2240,"FLAG_SYS_CAVE_BATTLE":2201,"FLAG_SYS_CAVE_SHIP":2199,"FLAG_SYS_CAVE_WONDER":2200,"FLAG_SYS_CHANGED_DEWFORD_TREND":2195,"FLAG_SYS_CHAT_USED":2149,"FLAG_SYS_CLOCK_SET":2197,"FLAG_SYS_CRUISE_MODE":2189,"FLAG_SYS_CTRL_OBJ_DELETE":2241,"FLAG_SYS_CYCLING_ROAD":2187,"FLAG_SYS_DOME_GOLD":2247,"FLAG_SYS_DOME_SILVER":2246,"FLAG_SYS_ENC_DOWN_ITEM":2222,"FLAG_SYS_ENC_UP_ITEM":2221,"FLAG_SYS_FACTORY_GOLD":2253,"FLAG_SYS_FACTORY_SILVER":2252,"FLAG_SYS_FRONTIER_PASS":2258,"FLAG_SYS_GAME_CLEAR":2148,"FLAG_SYS_MIX_RECORD":2196,"FLAG_SYS_MYSTERY_EVENT_ENABLE":2220,"FLAG_SYS_MYSTERY_GIFT_ENABLE":2267,"FLAG_SYS_NATIONAL_DEX":2198,"FLAG_SYS_PALACE_GOLD":2249,"FLAG_SYS_PALACE_SILVER":2248,"FLAG_SYS_PC_LANETTE":2219,"FLAG_SYS_PIKE_GOLD":2255,"FLAG_SYS_PIKE_SILVER":2254,"FLAG_SYS_POKEDEX_GET":2145,"FLAG_SYS_POKEMON_GET":2144,"FLAG_SYS_POKENAV_GET":2146,"FLAG_SYS_PYRAMID_GOLD":2257,"FLAG_SYS_PYRAMID_SILVER":2256,"FLAG_SYS_REGIROCK_PUZZLE_COMPLETED":2224,"FLAG_SYS_REGISTEEL_PUZZLE_COMPLETED":2226,"FLAG_SYS_RESET_RTC_ENABLE":2242,"FLAG_SYS_RIBBON_GET":2203,"FLAG_SYS_SAFARI_MODE":2188,"FLAG_SYS_SHOAL_ITEM":2239,"FLAG_SYS_SHOAL_TIDE":2202,"FLAG_SYS_TOWER_GOLD":2245,"FLAG_SYS_TOWER_SILVER":2244,"FLAG_SYS_TV_HOME":2192,"FLAG_SYS_TV_LATIAS_LATIOS":2237,"FLAG_SYS_TV_START":2194,"FLAG_SYS_TV_WATCH":2193,"FLAG_SYS_USE_FLASH":2184,"FLAG_SYS_USE_STRENGTH":2185,"FLAG_SYS_WEATHER_CTRL":2186,"FLAG_TEAM_AQUA_ESCAPED_IN_SUBMARINE":112,"FLAG_TEMP_1":1,"FLAG_TEMP_10":16,"FLAG_TEMP_11":17,"FLAG_TEMP_12":18,"FLAG_TEMP_13":19,"FLAG_TEMP_14":20,"FLAG_TEMP_15":21,"FLAG_TEMP_16":22,"FLAG_TEMP_17":23,"FLAG_TEMP_18":24,"FLAG_TEMP_19":25,"FLAG_TEMP_1A":26,"FLAG_TEMP_1B":27,"FLAG_TEMP_1C":28,"FLAG_TEMP_1D":29,"FLAG_TEMP_1E":30,"FLAG_TEMP_1F":31,"FLAG_TEMP_2":2,"FLAG_TEMP_3":3,"FLAG_TEMP_4":4,"FLAG_TEMP_5":5,"FLAG_TEMP_6":6,"FLAG_TEMP_7":7,"FLAG_TEMP_8":8,"FLAG_TEMP_9":9,"FLAG_TEMP_A":10,"FLAG_TEMP_B":11,"FLAG_TEMP_C":12,"FLAG_TEMP_D":13,"FLAG_TEMP_E":14,"FLAG_TEMP_F":15,"FLAG_TEMP_HIDE_MIRAGE_ISLAND_BERRY_TREE":17,"FLAG_TEMP_REGICE_PUZZLE_FAILED":3,"FLAG_TEMP_REGICE_PUZZLE_STARTED":2,"FLAG_TEMP_SKIP_GABBY_INTERVIEW":1,"FLAG_THANKED_FOR_PLAYING_WITH_WALLY":135,"FLAG_TOUGH_PAINTING_MADE":164,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_1":194,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_2":195,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_3":196,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_4":197,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_5":198,"FLAG_TV_EXPLAINED":98,"FLAG_UNLOCKED_TRENDY_SAYINGS":2150,"FLAG_USED_ROOM_1_KEY":240,"FLAG_USED_ROOM_2_KEY":241,"FLAG_USED_ROOM_4_KEY":242,"FLAG_USED_ROOM_6_KEY":243,"FLAG_USED_STORAGE_KEY":239,"FLAG_VISITED_DEWFORD_TOWN":2161,"FLAG_VISITED_EVER_GRANDE_CITY":2174,"FLAG_VISITED_FALLARBOR_TOWN":2163,"FLAG_VISITED_FORTREE_CITY":2170,"FLAG_VISITED_LAVARIDGE_TOWN":2162,"FLAG_VISITED_LILYCOVE_CITY":2171,"FLAG_VISITED_LITTLEROOT_TOWN":2159,"FLAG_VISITED_MAUVILLE_CITY":2168,"FLAG_VISITED_MOSSDEEP_CITY":2172,"FLAG_VISITED_OLDALE_TOWN":2160,"FLAG_VISITED_PACIFIDLOG_TOWN":2165,"FLAG_VISITED_PETALBURG_CITY":2166,"FLAG_VISITED_RUSTBORO_CITY":2169,"FLAG_VISITED_SLATEPORT_CITY":2167,"FLAG_VISITED_SOOTOPOLIS_CITY":2173,"FLAG_VISITED_VERDANTURF_TOWN":2164,"FLAG_WALLACE_GOES_TO_SKY_PILLAR":311,"FLAG_WALLY_SPEECH":193,"FLAG_WATTSON_REMATCH_AVAILABLE":91,"FLAG_WHITEOUT_TO_LAVARIDGE":108,"FLAG_WINGULL_DELIVERED_MAIL":224,"FLAG_WINGULL_SENT_ON_ERRAND":222,"FLAG_WONDER_CARD_UNUSED_1":317,"FLAG_WONDER_CARD_UNUSED_10":326,"FLAG_WONDER_CARD_UNUSED_11":327,"FLAG_WONDER_CARD_UNUSED_12":328,"FLAG_WONDER_CARD_UNUSED_13":329,"FLAG_WONDER_CARD_UNUSED_14":330,"FLAG_WONDER_CARD_UNUSED_15":331,"FLAG_WONDER_CARD_UNUSED_16":332,"FLAG_WONDER_CARD_UNUSED_17":333,"FLAG_WONDER_CARD_UNUSED_2":318,"FLAG_WONDER_CARD_UNUSED_3":319,"FLAG_WONDER_CARD_UNUSED_4":320,"FLAG_WONDER_CARD_UNUSED_5":321,"FLAG_WONDER_CARD_UNUSED_6":322,"FLAG_WONDER_CARD_UNUSED_7":323,"FLAG_WONDER_CARD_UNUSED_8":324,"FLAG_WONDER_CARD_UNUSED_9":325,"FLAVOR_BITTER":3,"FLAVOR_COUNT":5,"FLAVOR_DRY":1,"FLAVOR_SOUR":4,"FLAVOR_SPICY":0,"FLAVOR_SWEET":2,"GOOD_ROD":1,"ITEMS_COUNT":377,"ITEM_034":52,"ITEM_035":53,"ITEM_036":54,"ITEM_037":55,"ITEM_038":56,"ITEM_039":57,"ITEM_03A":58,"ITEM_03B":59,"ITEM_03C":60,"ITEM_03D":61,"ITEM_03E":62,"ITEM_048":72,"ITEM_052":82,"ITEM_057":87,"ITEM_058":88,"ITEM_059":89,"ITEM_05A":90,"ITEM_05B":91,"ITEM_05C":92,"ITEM_063":99,"ITEM_064":100,"ITEM_065":101,"ITEM_066":102,"ITEM_069":105,"ITEM_071":113,"ITEM_072":114,"ITEM_073":115,"ITEM_074":116,"ITEM_075":117,"ITEM_076":118,"ITEM_077":119,"ITEM_078":120,"ITEM_0EA":234,"ITEM_0EB":235,"ITEM_0EC":236,"ITEM_0ED":237,"ITEM_0EE":238,"ITEM_0EF":239,"ITEM_0F0":240,"ITEM_0F1":241,"ITEM_0F2":242,"ITEM_0F3":243,"ITEM_0F4":244,"ITEM_0F5":245,"ITEM_0F6":246,"ITEM_0F7":247,"ITEM_0F8":248,"ITEM_0F9":249,"ITEM_0FA":250,"ITEM_0FB":251,"ITEM_0FC":252,"ITEM_0FD":253,"ITEM_10B":267,"ITEM_15B":347,"ITEM_15C":348,"ITEM_ACRO_BIKE":272,"ITEM_AGUAV_BERRY":146,"ITEM_AMULET_COIN":189,"ITEM_ANTIDOTE":14,"ITEM_APICOT_BERRY":172,"ITEM_ARCHIPELAGO_PROGRESSION":112,"ITEM_ASPEAR_BERRY":137,"ITEM_AURORA_TICKET":371,"ITEM_AWAKENING":17,"ITEM_BADGE_1":226,"ITEM_BADGE_2":227,"ITEM_BADGE_3":228,"ITEM_BADGE_4":229,"ITEM_BADGE_5":230,"ITEM_BADGE_6":231,"ITEM_BADGE_7":232,"ITEM_BADGE_8":233,"ITEM_BASEMENT_KEY":271,"ITEM_BEAD_MAIL":127,"ITEM_BELUE_BERRY":167,"ITEM_BERRY_JUICE":44,"ITEM_BERRY_POUCH":365,"ITEM_BICYCLE":360,"ITEM_BIG_MUSHROOM":104,"ITEM_BIG_PEARL":107,"ITEM_BIKE_VOUCHER":352,"ITEM_BLACK_BELT":207,"ITEM_BLACK_FLUTE":42,"ITEM_BLACK_GLASSES":206,"ITEM_BLUE_FLUTE":39,"ITEM_BLUE_ORB":277,"ITEM_BLUE_SCARF":255,"ITEM_BLUE_SHARD":49,"ITEM_BLUK_BERRY":149,"ITEM_BRIGHT_POWDER":179,"ITEM_BURN_HEAL":15,"ITEM_B_USE_MEDICINE":1,"ITEM_B_USE_OTHER":2,"ITEM_CALCIUM":67,"ITEM_CARBOS":66,"ITEM_CARD_KEY":355,"ITEM_CHARCOAL":215,"ITEM_CHERI_BERRY":133,"ITEM_CHESTO_BERRY":134,"ITEM_CHOICE_BAND":186,"ITEM_CLAW_FOSSIL":287,"ITEM_CLEANSE_TAG":190,"ITEM_COIN_CASE":260,"ITEM_CONTEST_PASS":266,"ITEM_CORNN_BERRY":159,"ITEM_DEEP_SEA_SCALE":193,"ITEM_DEEP_SEA_TOOTH":192,"ITEM_DEVON_GOODS":269,"ITEM_DEVON_SCOPE":288,"ITEM_DIRE_HIT":74,"ITEM_DIVE_BALL":7,"ITEM_DOME_FOSSIL":358,"ITEM_DRAGON_FANG":216,"ITEM_DRAGON_SCALE":201,"ITEM_DREAM_MAIL":130,"ITEM_DURIN_BERRY":166,"ITEM_ELIXIR":36,"ITEM_ENERGY_POWDER":30,"ITEM_ENERGY_ROOT":31,"ITEM_ENIGMA_BERRY":175,"ITEM_EON_TICKET":275,"ITEM_ESCAPE_ROPE":85,"ITEM_ETHER":34,"ITEM_EVERSTONE":195,"ITEM_EXP_SHARE":182,"ITEM_FAB_MAIL":131,"ITEM_FAME_CHECKER":363,"ITEM_FIGY_BERRY":143,"ITEM_FIRE_STONE":95,"ITEM_FLUFFY_TAIL":81,"ITEM_FOCUS_BAND":196,"ITEM_FRESH_WATER":26,"ITEM_FULL_HEAL":23,"ITEM_FULL_RESTORE":19,"ITEM_GANLON_BERRY":169,"ITEM_GLITTER_MAIL":123,"ITEM_GOLD_TEETH":353,"ITEM_GOOD_ROD":263,"ITEM_GO_GOGGLES":279,"ITEM_GREAT_BALL":3,"ITEM_GREEN_SCARF":257,"ITEM_GREEN_SHARD":51,"ITEM_GREPA_BERRY":157,"ITEM_GUARD_SPEC":73,"ITEM_HARBOR_MAIL":122,"ITEM_HARD_STONE":204,"ITEM_HEAL_POWDER":32,"ITEM_HEART_SCALE":111,"ITEM_HELIX_FOSSIL":357,"ITEM_HM01":339,"ITEM_HM02":340,"ITEM_HM03":341,"ITEM_HM04":342,"ITEM_HM05":343,"ITEM_HM06":344,"ITEM_HM07":345,"ITEM_HM08":346,"ITEM_HM_CUT":339,"ITEM_HM_DIVE":346,"ITEM_HM_FLASH":343,"ITEM_HM_FLY":340,"ITEM_HM_ROCK_SMASH":344,"ITEM_HM_STRENGTH":342,"ITEM_HM_SURF":341,"ITEM_HM_WATERFALL":345,"ITEM_HONDEW_BERRY":156,"ITEM_HP_UP":63,"ITEM_HYPER_POTION":21,"ITEM_IAPAPA_BERRY":147,"ITEM_ICE_HEAL":16,"ITEM_IRON":65,"ITEM_ITEMFINDER":261,"ITEM_KELPSY_BERRY":154,"ITEM_KINGS_ROCK":187,"ITEM_LANSAT_BERRY":173,"ITEM_LAVA_COOKIE":38,"ITEM_LAX_INCENSE":221,"ITEM_LEAF_STONE":98,"ITEM_LEFTOVERS":200,"ITEM_LEMONADE":28,"ITEM_LEPPA_BERRY":138,"ITEM_LETTER":274,"ITEM_LIECHI_BERRY":168,"ITEM_LIFT_KEY":356,"ITEM_LIGHT_BALL":202,"ITEM_LIST_END":65535,"ITEM_LUCKY_EGG":197,"ITEM_LUCKY_PUNCH":222,"ITEM_LUM_BERRY":141,"ITEM_LUXURY_BALL":11,"ITEM_MACHO_BRACE":181,"ITEM_MACH_BIKE":259,"ITEM_MAGMA_EMBLEM":375,"ITEM_MAGNET":208,"ITEM_MAGOST_BERRY":160,"ITEM_MAGO_BERRY":145,"ITEM_MASTER_BALL":1,"ITEM_MAX_ELIXIR":37,"ITEM_MAX_ETHER":35,"ITEM_MAX_POTION":20,"ITEM_MAX_REPEL":84,"ITEM_MAX_REVIVE":25,"ITEM_MECH_MAIL":124,"ITEM_MENTAL_HERB":185,"ITEM_METAL_COAT":199,"ITEM_METAL_POWDER":223,"ITEM_METEORITE":280,"ITEM_MIRACLE_SEED":205,"ITEM_MOOMOO_MILK":29,"ITEM_MOON_STONE":94,"ITEM_MYSTIC_TICKET":370,"ITEM_MYSTIC_WATER":209,"ITEM_NANAB_BERRY":150,"ITEM_NEST_BALL":8,"ITEM_NET_BALL":6,"ITEM_NEVER_MELT_ICE":212,"ITEM_NOMEL_BERRY":162,"ITEM_NONE":0,"ITEM_NUGGET":110,"ITEM_OAKS_PARCEL":349,"ITEM_OLD_AMBER":354,"ITEM_OLD_ROD":262,"ITEM_OLD_SEA_MAP":376,"ITEM_ORANGE_MAIL":121,"ITEM_ORAN_BERRY":139,"ITEM_PAMTRE_BERRY":164,"ITEM_PARALYZE_HEAL":18,"ITEM_PEARL":106,"ITEM_PECHA_BERRY":135,"ITEM_PERSIM_BERRY":140,"ITEM_PETAYA_BERRY":171,"ITEM_PINAP_BERRY":152,"ITEM_PINK_SCARF":256,"ITEM_POISON_BARB":211,"ITEM_POKEBLOCK_CASE":273,"ITEM_POKE_BALL":4,"ITEM_POKE_DOLL":80,"ITEM_POKE_FLUTE":350,"ITEM_POMEG_BERRY":153,"ITEM_POTION":13,"ITEM_POWDER_JAR":372,"ITEM_PP_MAX":71,"ITEM_PP_UP":69,"ITEM_PREMIER_BALL":12,"ITEM_PROTEIN":64,"ITEM_QUALOT_BERRY":155,"ITEM_QUICK_CLAW":183,"ITEM_RABUTA_BERRY":161,"ITEM_RAINBOW_PASS":368,"ITEM_RARE_CANDY":68,"ITEM_RAWST_BERRY":136,"ITEM_RAZZ_BERRY":148,"ITEM_RED_FLUTE":41,"ITEM_RED_ORB":276,"ITEM_RED_SCARF":254,"ITEM_RED_SHARD":48,"ITEM_REPEAT_BALL":9,"ITEM_REPEL":86,"ITEM_RETRO_MAIL":132,"ITEM_REVIVAL_HERB":33,"ITEM_REVIVE":24,"ITEM_ROOM_1_KEY":281,"ITEM_ROOM_2_KEY":282,"ITEM_ROOM_4_KEY":283,"ITEM_ROOM_6_KEY":284,"ITEM_ROOT_FOSSIL":286,"ITEM_RUBY":373,"ITEM_SACRED_ASH":45,"ITEM_SAFARI_BALL":5,"ITEM_SALAC_BERRY":170,"ITEM_SAPPHIRE":374,"ITEM_SCANNER":278,"ITEM_SCOPE_LENS":198,"ITEM_SEA_INCENSE":220,"ITEM_SECRET_KEY":351,"ITEM_SHADOW_MAIL":128,"ITEM_SHARP_BEAK":210,"ITEM_SHELL_BELL":219,"ITEM_SHOAL_SALT":46,"ITEM_SHOAL_SHELL":47,"ITEM_SILK_SCARF":217,"ITEM_SILPH_SCOPE":359,"ITEM_SILVER_POWDER":188,"ITEM_SITRUS_BERRY":142,"ITEM_SMOKE_BALL":194,"ITEM_SODA_POP":27,"ITEM_SOFT_SAND":203,"ITEM_SOOTHE_BELL":184,"ITEM_SOOT_SACK":270,"ITEM_SOUL_DEW":191,"ITEM_SPELL_TAG":213,"ITEM_SPELON_BERRY":163,"ITEM_SS_TICKET":265,"ITEM_STARDUST":108,"ITEM_STARF_BERRY":174,"ITEM_STAR_PIECE":109,"ITEM_STICK":225,"ITEM_STORAGE_KEY":285,"ITEM_SUN_STONE":93,"ITEM_SUPER_POTION":22,"ITEM_SUPER_REPEL":83,"ITEM_SUPER_ROD":264,"ITEM_TAMATO_BERRY":158,"ITEM_TEA":369,"ITEM_TEACHY_TV":366,"ITEM_THICK_CLUB":224,"ITEM_THUNDER_STONE":96,"ITEM_TIMER_BALL":10,"ITEM_TINY_MUSHROOM":103,"ITEM_TM01":289,"ITEM_TM02":290,"ITEM_TM03":291,"ITEM_TM04":292,"ITEM_TM05":293,"ITEM_TM06":294,"ITEM_TM07":295,"ITEM_TM08":296,"ITEM_TM09":297,"ITEM_TM10":298,"ITEM_TM11":299,"ITEM_TM12":300,"ITEM_TM13":301,"ITEM_TM14":302,"ITEM_TM15":303,"ITEM_TM16":304,"ITEM_TM17":305,"ITEM_TM18":306,"ITEM_TM19":307,"ITEM_TM20":308,"ITEM_TM21":309,"ITEM_TM22":310,"ITEM_TM23":311,"ITEM_TM24":312,"ITEM_TM25":313,"ITEM_TM26":314,"ITEM_TM27":315,"ITEM_TM28":316,"ITEM_TM29":317,"ITEM_TM30":318,"ITEM_TM31":319,"ITEM_TM32":320,"ITEM_TM33":321,"ITEM_TM34":322,"ITEM_TM35":323,"ITEM_TM36":324,"ITEM_TM37":325,"ITEM_TM38":326,"ITEM_TM39":327,"ITEM_TM40":328,"ITEM_TM41":329,"ITEM_TM42":330,"ITEM_TM43":331,"ITEM_TM44":332,"ITEM_TM45":333,"ITEM_TM46":334,"ITEM_TM47":335,"ITEM_TM48":336,"ITEM_TM49":337,"ITEM_TM50":338,"ITEM_TM_AERIAL_ACE":328,"ITEM_TM_ATTRACT":333,"ITEM_TM_BLIZZARD":302,"ITEM_TM_BRICK_BREAK":319,"ITEM_TM_BULK_UP":296,"ITEM_TM_BULLET_SEED":297,"ITEM_TM_CALM_MIND":292,"ITEM_TM_CASE":364,"ITEM_TM_DIG":316,"ITEM_TM_DOUBLE_TEAM":320,"ITEM_TM_DRAGON_CLAW":290,"ITEM_TM_EARTHQUAKE":314,"ITEM_TM_FACADE":330,"ITEM_TM_FIRE_BLAST":326,"ITEM_TM_FLAMETHROWER":323,"ITEM_TM_FOCUS_PUNCH":289,"ITEM_TM_FRUSTRATION":309,"ITEM_TM_GIGA_DRAIN":307,"ITEM_TM_HAIL":295,"ITEM_TM_HIDDEN_POWER":298,"ITEM_TM_HYPER_BEAM":303,"ITEM_TM_ICE_BEAM":301,"ITEM_TM_IRON_TAIL":311,"ITEM_TM_LIGHT_SCREEN":304,"ITEM_TM_OVERHEAT":338,"ITEM_TM_PROTECT":305,"ITEM_TM_PSYCHIC":317,"ITEM_TM_RAIN_DANCE":306,"ITEM_TM_REFLECT":321,"ITEM_TM_REST":332,"ITEM_TM_RETURN":315,"ITEM_TM_ROAR":293,"ITEM_TM_ROCK_TOMB":327,"ITEM_TM_SAFEGUARD":308,"ITEM_TM_SANDSTORM":325,"ITEM_TM_SECRET_POWER":331,"ITEM_TM_SHADOW_BALL":318,"ITEM_TM_SHOCK_WAVE":322,"ITEM_TM_SKILL_SWAP":336,"ITEM_TM_SLUDGE_BOMB":324,"ITEM_TM_SNATCH":337,"ITEM_TM_SOLAR_BEAM":310,"ITEM_TM_STEEL_WING":335,"ITEM_TM_SUNNY_DAY":299,"ITEM_TM_TAUNT":300,"ITEM_TM_THIEF":334,"ITEM_TM_THUNDER":313,"ITEM_TM_THUNDERBOLT":312,"ITEM_TM_TORMENT":329,"ITEM_TM_TOXIC":294,"ITEM_TM_WATER_PULSE":291,"ITEM_TOWN_MAP":361,"ITEM_TRI_PASS":367,"ITEM_TROPIC_MAIL":129,"ITEM_TWISTED_SPOON":214,"ITEM_ULTRA_BALL":2,"ITEM_UNUSED_BERRY_1":176,"ITEM_UNUSED_BERRY_2":177,"ITEM_UNUSED_BERRY_3":178,"ITEM_UP_GRADE":218,"ITEM_USE_BAG_MENU":4,"ITEM_USE_FIELD":2,"ITEM_USE_MAIL":0,"ITEM_USE_PARTY_MENU":1,"ITEM_USE_PBLOCK_CASE":3,"ITEM_VS_SEEKER":362,"ITEM_WAILMER_PAIL":268,"ITEM_WATER_STONE":97,"ITEM_WATMEL_BERRY":165,"ITEM_WAVE_MAIL":126,"ITEM_WEPEAR_BERRY":151,"ITEM_WHITE_FLUTE":43,"ITEM_WHITE_HERB":180,"ITEM_WIKI_BERRY":144,"ITEM_WOOD_MAIL":125,"ITEM_X_ACCURACY":78,"ITEM_X_ATTACK":75,"ITEM_X_DEFEND":76,"ITEM_X_SPECIAL":79,"ITEM_X_SPEED":77,"ITEM_YELLOW_FLUTE":40,"ITEM_YELLOW_SCARF":258,"ITEM_YELLOW_SHARD":50,"ITEM_ZINC":70,"LAST_BALL":12,"LAST_BERRY_INDEX":175,"LAST_BERRY_MASTER_BERRY":162,"LAST_BERRY_MASTER_WIFE_BERRY":142,"LAST_KIRI_BERRY":162,"LAST_ROUTE_114_MAN_BERRY":152,"MACH_BIKE":0,"MAIL_NONE":255,"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":6207,"MAP_ABANDONED_SHIP_CORRIDORS_1F":6199,"MAP_ABANDONED_SHIP_CORRIDORS_B1F":6201,"MAP_ABANDONED_SHIP_DECK":6198,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":6209,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":6210,"MAP_ABANDONED_SHIP_ROOMS2_1F":6206,"MAP_ABANDONED_SHIP_ROOMS2_B1F":6203,"MAP_ABANDONED_SHIP_ROOMS_1F":6200,"MAP_ABANDONED_SHIP_ROOMS_B1F":6202,"MAP_ABANDONED_SHIP_ROOM_B1F":6205,"MAP_ABANDONED_SHIP_UNDERWATER1":6204,"MAP_ABANDONED_SHIP_UNDERWATER2":6208,"MAP_ALTERING_CAVE":6250,"MAP_ANCIENT_TOMB":6212,"MAP_AQUA_HIDEOUT_1F":6167,"MAP_AQUA_HIDEOUT_B1F":6168,"MAP_AQUA_HIDEOUT_B2F":6169,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":6218,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":6219,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":6220,"MAP_ARTISAN_CAVE_1F":6244,"MAP_ARTISAN_CAVE_B1F":6243,"MAP_BATTLE_COLOSSEUM_2P":6424,"MAP_BATTLE_COLOSSEUM_4P":6427,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":6686,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":6685,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":6684,"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":6677,"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":6675,"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":6674,"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":6676,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":6689,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":6687,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":6688,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":6680,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":6679,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":6678,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":6691,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":6690,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":6694,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":6693,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":6695,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":6692,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":6682,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":6681,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":6683,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":6664,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":6663,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":6662,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":6661,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":6673,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":6672,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":6671,"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":6698,"MAP_BATTLE_FRONTIER_LOUNGE1":6697,"MAP_BATTLE_FRONTIER_LOUNGE2":6699,"MAP_BATTLE_FRONTIER_LOUNGE3":6700,"MAP_BATTLE_FRONTIER_LOUNGE4":6701,"MAP_BATTLE_FRONTIER_LOUNGE5":6703,"MAP_BATTLE_FRONTIER_LOUNGE6":6704,"MAP_BATTLE_FRONTIER_LOUNGE7":6705,"MAP_BATTLE_FRONTIER_LOUNGE8":6707,"MAP_BATTLE_FRONTIER_LOUNGE9":6708,"MAP_BATTLE_FRONTIER_MART":6711,"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":6670,"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":6660,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":6709,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":6710,"MAP_BATTLE_FRONTIER_RANKING_HALL":6696,"MAP_BATTLE_FRONTIER_RECEPTION_GATE":6706,"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":6702,"MAP_BATTLE_PYRAMID_SQUARE01":6444,"MAP_BATTLE_PYRAMID_SQUARE02":6445,"MAP_BATTLE_PYRAMID_SQUARE03":6446,"MAP_BATTLE_PYRAMID_SQUARE04":6447,"MAP_BATTLE_PYRAMID_SQUARE05":6448,"MAP_BATTLE_PYRAMID_SQUARE06":6449,"MAP_BATTLE_PYRAMID_SQUARE07":6450,"MAP_BATTLE_PYRAMID_SQUARE08":6451,"MAP_BATTLE_PYRAMID_SQUARE09":6452,"MAP_BATTLE_PYRAMID_SQUARE10":6453,"MAP_BATTLE_PYRAMID_SQUARE11":6454,"MAP_BATTLE_PYRAMID_SQUARE12":6455,"MAP_BATTLE_PYRAMID_SQUARE13":6456,"MAP_BATTLE_PYRAMID_SQUARE14":6457,"MAP_BATTLE_PYRAMID_SQUARE15":6458,"MAP_BATTLE_PYRAMID_SQUARE16":6459,"MAP_BIRTH_ISLAND_EXTERIOR":6714,"MAP_BIRTH_ISLAND_HARBOR":6715,"MAP_CAVE_OF_ORIGIN_1F":6182,"MAP_CAVE_OF_ORIGIN_B1F":6186,"MAP_CAVE_OF_ORIGIN_ENTRANCE":6181,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":6183,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":6184,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":6185,"MAP_CONTEST_HALL":6428,"MAP_CONTEST_HALL_BEAUTY":6435,"MAP_CONTEST_HALL_COOL":6437,"MAP_CONTEST_HALL_CUTE":6439,"MAP_CONTEST_HALL_SMART":6438,"MAP_CONTEST_HALL_TOUGH":6436,"MAP_DESERT_RUINS":6150,"MAP_DESERT_UNDERPASS":6242,"MAP_DEWFORD_TOWN":11,"MAP_DEWFORD_TOWN_GYM":771,"MAP_DEWFORD_TOWN_HALL":772,"MAP_DEWFORD_TOWN_HOUSE1":768,"MAP_DEWFORD_TOWN_HOUSE2":773,"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":769,"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":770,"MAP_EVER_GRANDE_CITY":8,"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":4100,"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":4099,"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":4098,"MAP_EVER_GRANDE_CITY_HALL1":4101,"MAP_EVER_GRANDE_CITY_HALL2":4102,"MAP_EVER_GRANDE_CITY_HALL3":4103,"MAP_EVER_GRANDE_CITY_HALL4":4104,"MAP_EVER_GRANDE_CITY_HALL5":4105,"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":4107,"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":4097,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":4108,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":4109,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":4106,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":4110,"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":4096,"MAP_FALLARBOR_TOWN":13,"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":1283,"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":1282,"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":1281,"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":1286,"MAP_FALLARBOR_TOWN_MART":1280,"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":1287,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":1284,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":1285,"MAP_FARAWAY_ISLAND_ENTRANCE":6712,"MAP_FARAWAY_ISLAND_INTERIOR":6713,"MAP_FIERY_PATH":6158,"MAP_FORTREE_CITY":4,"MAP_FORTREE_CITY_DECORATION_SHOP":3081,"MAP_FORTREE_CITY_GYM":3073,"MAP_FORTREE_CITY_HOUSE1":3072,"MAP_FORTREE_CITY_HOUSE2":3077,"MAP_FORTREE_CITY_HOUSE3":3078,"MAP_FORTREE_CITY_HOUSE4":3079,"MAP_FORTREE_CITY_HOUSE5":3080,"MAP_FORTREE_CITY_MART":3076,"MAP_FORTREE_CITY_POKEMON_CENTER_1F":3074,"MAP_FORTREE_CITY_POKEMON_CENTER_2F":3075,"MAP_GRANITE_CAVE_1F":6151,"MAP_GRANITE_CAVE_B1F":6152,"MAP_GRANITE_CAVE_B2F":6153,"MAP_GRANITE_CAVE_STEVENS_ROOM":6154,"MAP_GROUPS_COUNT":34,"MAP_INSIDE_OF_TRUCK":6440,"MAP_ISLAND_CAVE":6211,"MAP_JAGGED_PASS":6157,"MAP_LAVARIDGE_TOWN":12,"MAP_LAVARIDGE_TOWN_GYM_1F":1025,"MAP_LAVARIDGE_TOWN_GYM_B1F":1026,"MAP_LAVARIDGE_TOWN_HERB_SHOP":1024,"MAP_LAVARIDGE_TOWN_HOUSE":1027,"MAP_LAVARIDGE_TOWN_MART":1028,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":1029,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":1030,"MAP_LILYCOVE_CITY":5,"MAP_LILYCOVE_CITY_CONTEST_HALL":3333,"MAP_LILYCOVE_CITY_CONTEST_LOBBY":3332,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":3328,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":3329,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":3344,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":3345,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":3346,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":3347,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":3348,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":3350,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":3349,"MAP_LILYCOVE_CITY_HARBOR":3338,"MAP_LILYCOVE_CITY_HOUSE1":3340,"MAP_LILYCOVE_CITY_HOUSE2":3341,"MAP_LILYCOVE_CITY_HOUSE3":3342,"MAP_LILYCOVE_CITY_HOUSE4":3343,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":3330,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":3331,"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":3339,"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":3334,"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":3335,"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":3337,"MAP_LILYCOVE_CITY_UNUSED_MART":3336,"MAP_LITTLEROOT_TOWN":9,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":256,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":257,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":258,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":259,"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":260,"MAP_MAGMA_HIDEOUT_1F":6230,"MAP_MAGMA_HIDEOUT_2F_1R":6231,"MAP_MAGMA_HIDEOUT_2F_2R":6232,"MAP_MAGMA_HIDEOUT_2F_3R":6237,"MAP_MAGMA_HIDEOUT_3F_1R":6233,"MAP_MAGMA_HIDEOUT_3F_2R":6234,"MAP_MAGMA_HIDEOUT_3F_3R":6236,"MAP_MAGMA_HIDEOUT_4F":6235,"MAP_MARINE_CAVE_END":6247,"MAP_MARINE_CAVE_ENTRANCE":6246,"MAP_MAUVILLE_CITY":2,"MAP_MAUVILLE_CITY_BIKE_SHOP":2561,"MAP_MAUVILLE_CITY_GAME_CORNER":2563,"MAP_MAUVILLE_CITY_GYM":2560,"MAP_MAUVILLE_CITY_HOUSE1":2562,"MAP_MAUVILLE_CITY_HOUSE2":2564,"MAP_MAUVILLE_CITY_MART":2567,"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":2565,"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":2566,"MAP_METEOR_FALLS_1F_1R":6144,"MAP_METEOR_FALLS_1F_2R":6145,"MAP_METEOR_FALLS_B1F_1R":6146,"MAP_METEOR_FALLS_B1F_2R":6147,"MAP_METEOR_FALLS_STEVENS_CAVE":6251,"MAP_MIRAGE_TOWER_1F":6238,"MAP_MIRAGE_TOWER_2F":6239,"MAP_MIRAGE_TOWER_3F":6240,"MAP_MIRAGE_TOWER_4F":6241,"MAP_MOSSDEEP_CITY":6,"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":3595,"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":3596,"MAP_MOSSDEEP_CITY_GYM":3584,"MAP_MOSSDEEP_CITY_HOUSE1":3585,"MAP_MOSSDEEP_CITY_HOUSE2":3586,"MAP_MOSSDEEP_CITY_HOUSE3":3590,"MAP_MOSSDEEP_CITY_HOUSE4":3592,"MAP_MOSSDEEP_CITY_MART":3589,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":3587,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":3588,"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":3593,"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":3594,"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":3591,"MAP_MT_CHIMNEY":6156,"MAP_MT_CHIMNEY_CABLE_CAR_STATION":4865,"MAP_MT_PYRE_1F":6159,"MAP_MT_PYRE_2F":6160,"MAP_MT_PYRE_3F":6161,"MAP_MT_PYRE_4F":6162,"MAP_MT_PYRE_5F":6163,"MAP_MT_PYRE_6F":6164,"MAP_MT_PYRE_EXTERIOR":6165,"MAP_MT_PYRE_SUMMIT":6166,"MAP_NAVEL_ROCK_B1F":6725,"MAP_NAVEL_ROCK_BOTTOM":6743,"MAP_NAVEL_ROCK_DOWN01":6732,"MAP_NAVEL_ROCK_DOWN02":6733,"MAP_NAVEL_ROCK_DOWN03":6734,"MAP_NAVEL_ROCK_DOWN04":6735,"MAP_NAVEL_ROCK_DOWN05":6736,"MAP_NAVEL_ROCK_DOWN06":6737,"MAP_NAVEL_ROCK_DOWN07":6738,"MAP_NAVEL_ROCK_DOWN08":6739,"MAP_NAVEL_ROCK_DOWN09":6740,"MAP_NAVEL_ROCK_DOWN10":6741,"MAP_NAVEL_ROCK_DOWN11":6742,"MAP_NAVEL_ROCK_ENTRANCE":6724,"MAP_NAVEL_ROCK_EXTERIOR":6722,"MAP_NAVEL_ROCK_FORK":6726,"MAP_NAVEL_ROCK_HARBOR":6723,"MAP_NAVEL_ROCK_TOP":6731,"MAP_NAVEL_ROCK_UP1":6727,"MAP_NAVEL_ROCK_UP2":6728,"MAP_NAVEL_ROCK_UP3":6729,"MAP_NAVEL_ROCK_UP4":6730,"MAP_NEW_MAUVILLE_ENTRANCE":6196,"MAP_NEW_MAUVILLE_INSIDE":6197,"MAP_OLDALE_TOWN":10,"MAP_OLDALE_TOWN_HOUSE1":512,"MAP_OLDALE_TOWN_HOUSE2":513,"MAP_OLDALE_TOWN_MART":516,"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":514,"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":515,"MAP_PACIFIDLOG_TOWN":15,"MAP_PACIFIDLOG_TOWN_HOUSE1":1794,"MAP_PACIFIDLOG_TOWN_HOUSE2":1795,"MAP_PACIFIDLOG_TOWN_HOUSE3":1796,"MAP_PACIFIDLOG_TOWN_HOUSE4":1797,"MAP_PACIFIDLOG_TOWN_HOUSE5":1798,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":1792,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":1793,"MAP_PETALBURG_CITY":0,"MAP_PETALBURG_CITY_GYM":2049,"MAP_PETALBURG_CITY_HOUSE1":2050,"MAP_PETALBURG_CITY_HOUSE2":2051,"MAP_PETALBURG_CITY_MART":2054,"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":2052,"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":2053,"MAP_PETALBURG_CITY_WALLYS_HOUSE":2048,"MAP_PETALBURG_WOODS":6155,"MAP_RECORD_CORNER":6426,"MAP_ROUTE101":16,"MAP_ROUTE102":17,"MAP_ROUTE103":18,"MAP_ROUTE104":19,"MAP_ROUTE104_MR_BRINEYS_HOUSE":4352,"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":4353,"MAP_ROUTE104_PROTOTYPE":6912,"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":6913,"MAP_ROUTE105":20,"MAP_ROUTE106":21,"MAP_ROUTE107":22,"MAP_ROUTE108":23,"MAP_ROUTE109":24,"MAP_ROUTE109_SEASHORE_HOUSE":7168,"MAP_ROUTE110":25,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":7435,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":7436,"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":7426,"MAP_ROUTE110_TRICK_HOUSE_END":7425,"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":7424,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":7427,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":7428,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":7429,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":7430,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":7431,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":7432,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":7433,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":7434,"MAP_ROUTE111":26,"MAP_ROUTE111_OLD_LADYS_REST_STOP":4609,"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":4608,"MAP_ROUTE112":27,"MAP_ROUTE112_CABLE_CAR_STATION":4864,"MAP_ROUTE113":28,"MAP_ROUTE113_GLASS_WORKSHOP":7680,"MAP_ROUTE114":29,"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":5120,"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":5121,"MAP_ROUTE114_LANETTES_HOUSE":5122,"MAP_ROUTE115":30,"MAP_ROUTE116":31,"MAP_ROUTE116_TUNNELERS_REST_HOUSE":5376,"MAP_ROUTE117":32,"MAP_ROUTE117_POKEMON_DAY_CARE":5632,"MAP_ROUTE118":33,"MAP_ROUTE119":34,"MAP_ROUTE119_HOUSE":8194,"MAP_ROUTE119_WEATHER_INSTITUTE_1F":8192,"MAP_ROUTE119_WEATHER_INSTITUTE_2F":8193,"MAP_ROUTE120":35,"MAP_ROUTE121":36,"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":5888,"MAP_ROUTE122":37,"MAP_ROUTE123":38,"MAP_ROUTE123_BERRY_MASTERS_HOUSE":7936,"MAP_ROUTE124":39,"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":8448,"MAP_ROUTE125":40,"MAP_ROUTE126":41,"MAP_ROUTE127":42,"MAP_ROUTE128":43,"MAP_ROUTE129":44,"MAP_ROUTE130":45,"MAP_ROUTE131":46,"MAP_ROUTE132":47,"MAP_ROUTE133":48,"MAP_ROUTE134":49,"MAP_RUSTBORO_CITY":3,"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":2827,"MAP_RUSTBORO_CITY_DEVON_CORP_1F":2816,"MAP_RUSTBORO_CITY_DEVON_CORP_2F":2817,"MAP_RUSTBORO_CITY_DEVON_CORP_3F":2818,"MAP_RUSTBORO_CITY_FLAT1_1F":2824,"MAP_RUSTBORO_CITY_FLAT1_2F":2825,"MAP_RUSTBORO_CITY_FLAT2_1F":2829,"MAP_RUSTBORO_CITY_FLAT2_2F":2830,"MAP_RUSTBORO_CITY_FLAT2_3F":2831,"MAP_RUSTBORO_CITY_GYM":2819,"MAP_RUSTBORO_CITY_HOUSE1":2826,"MAP_RUSTBORO_CITY_HOUSE2":2828,"MAP_RUSTBORO_CITY_HOUSE3":2832,"MAP_RUSTBORO_CITY_MART":2823,"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":2821,"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":2822,"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":2820,"MAP_RUSTURF_TUNNEL":6148,"MAP_SAFARI_ZONE_NORTH":6657,"MAP_SAFARI_ZONE_NORTHEAST":6668,"MAP_SAFARI_ZONE_NORTHWEST":6656,"MAP_SAFARI_ZONE_REST_HOUSE":6667,"MAP_SAFARI_ZONE_SOUTH":6659,"MAP_SAFARI_ZONE_SOUTHEAST":6669,"MAP_SAFARI_ZONE_SOUTHWEST":6658,"MAP_SCORCHED_SLAB":6217,"MAP_SEAFLOOR_CAVERN_ENTRANCE":6171,"MAP_SEAFLOOR_CAVERN_ROOM1":6172,"MAP_SEAFLOOR_CAVERN_ROOM2":6173,"MAP_SEAFLOOR_CAVERN_ROOM3":6174,"MAP_SEAFLOOR_CAVERN_ROOM4":6175,"MAP_SEAFLOOR_CAVERN_ROOM5":6176,"MAP_SEAFLOOR_CAVERN_ROOM6":6177,"MAP_SEAFLOOR_CAVERN_ROOM7":6178,"MAP_SEAFLOOR_CAVERN_ROOM8":6179,"MAP_SEAFLOOR_CAVERN_ROOM9":6180,"MAP_SEALED_CHAMBER_INNER_ROOM":6216,"MAP_SEALED_CHAMBER_OUTER_ROOM":6215,"MAP_SECRET_BASE_BLUE_CAVE1":6402,"MAP_SECRET_BASE_BLUE_CAVE2":6408,"MAP_SECRET_BASE_BLUE_CAVE3":6414,"MAP_SECRET_BASE_BLUE_CAVE4":6420,"MAP_SECRET_BASE_BROWN_CAVE1":6401,"MAP_SECRET_BASE_BROWN_CAVE2":6407,"MAP_SECRET_BASE_BROWN_CAVE3":6413,"MAP_SECRET_BASE_BROWN_CAVE4":6419,"MAP_SECRET_BASE_RED_CAVE1":6400,"MAP_SECRET_BASE_RED_CAVE2":6406,"MAP_SECRET_BASE_RED_CAVE3":6412,"MAP_SECRET_BASE_RED_CAVE4":6418,"MAP_SECRET_BASE_SHRUB1":6405,"MAP_SECRET_BASE_SHRUB2":6411,"MAP_SECRET_BASE_SHRUB3":6417,"MAP_SECRET_BASE_SHRUB4":6423,"MAP_SECRET_BASE_TREE1":6404,"MAP_SECRET_BASE_TREE2":6410,"MAP_SECRET_BASE_TREE3":6416,"MAP_SECRET_BASE_TREE4":6422,"MAP_SECRET_BASE_YELLOW_CAVE1":6403,"MAP_SECRET_BASE_YELLOW_CAVE2":6409,"MAP_SECRET_BASE_YELLOW_CAVE3":6415,"MAP_SECRET_BASE_YELLOW_CAVE4":6421,"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":6194,"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":6195,"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":6190,"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":6227,"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":6191,"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":6193,"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":6192,"MAP_SKY_PILLAR_1F":6223,"MAP_SKY_PILLAR_2F":6224,"MAP_SKY_PILLAR_3F":6225,"MAP_SKY_PILLAR_4F":6226,"MAP_SKY_PILLAR_5F":6228,"MAP_SKY_PILLAR_ENTRANCE":6221,"MAP_SKY_PILLAR_OUTSIDE":6222,"MAP_SKY_PILLAR_TOP":6229,"MAP_SLATEPORT_CITY":1,"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":2308,"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":2307,"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":2306,"MAP_SLATEPORT_CITY_HARBOR":2313,"MAP_SLATEPORT_CITY_HOUSE":2314,"MAP_SLATEPORT_CITY_MART":2317,"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":2309,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":2311,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":2312,"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":2315,"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":2316,"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":2310,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":2304,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":2305,"MAP_SOOTOPOLIS_CITY":7,"MAP_SOOTOPOLIS_CITY_GYM_1F":3840,"MAP_SOOTOPOLIS_CITY_GYM_B1F":3841,"MAP_SOOTOPOLIS_CITY_HOUSE1":3845,"MAP_SOOTOPOLIS_CITY_HOUSE2":3846,"MAP_SOOTOPOLIS_CITY_HOUSE3":3847,"MAP_SOOTOPOLIS_CITY_HOUSE4":3848,"MAP_SOOTOPOLIS_CITY_HOUSE5":3849,"MAP_SOOTOPOLIS_CITY_HOUSE6":3850,"MAP_SOOTOPOLIS_CITY_HOUSE7":3851,"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":3852,"MAP_SOOTOPOLIS_CITY_MART":3844,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":3853,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":3854,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":3842,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":3843,"MAP_SOUTHERN_ISLAND_EXTERIOR":6665,"MAP_SOUTHERN_ISLAND_INTERIOR":6666,"MAP_SS_TIDAL_CORRIDOR":6441,"MAP_SS_TIDAL_LOWER_DECK":6442,"MAP_SS_TIDAL_ROOMS":6443,"MAP_TERRA_CAVE_END":6249,"MAP_TERRA_CAVE_ENTRANCE":6248,"MAP_TRADE_CENTER":6425,"MAP_TRAINER_HILL_1F":6717,"MAP_TRAINER_HILL_2F":6718,"MAP_TRAINER_HILL_3F":6719,"MAP_TRAINER_HILL_4F":6720,"MAP_TRAINER_HILL_ELEVATOR":6744,"MAP_TRAINER_HILL_ENTRANCE":6716,"MAP_TRAINER_HILL_ROOF":6721,"MAP_UNDERWATER_MARINE_CAVE":6245,"MAP_UNDERWATER_ROUTE105":55,"MAP_UNDERWATER_ROUTE124":50,"MAP_UNDERWATER_ROUTE125":56,"MAP_UNDERWATER_ROUTE126":51,"MAP_UNDERWATER_ROUTE127":52,"MAP_UNDERWATER_ROUTE128":53,"MAP_UNDERWATER_ROUTE129":54,"MAP_UNDERWATER_ROUTE134":6213,"MAP_UNDERWATER_SEAFLOOR_CAVERN":6170,"MAP_UNDERWATER_SEALED_CHAMBER":6214,"MAP_UNDERWATER_SOOTOPOLIS_CITY":6149,"MAP_UNION_ROOM":6460,"MAP_UNUSED_CONTEST_HALL1":6429,"MAP_UNUSED_CONTEST_HALL2":6430,"MAP_UNUSED_CONTEST_HALL3":6431,"MAP_UNUSED_CONTEST_HALL4":6432,"MAP_UNUSED_CONTEST_HALL5":6433,"MAP_UNUSED_CONTEST_HALL6":6434,"MAP_VERDANTURF_TOWN":14,"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":1538,"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":1537,"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":1536,"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":1543,"MAP_VERDANTURF_TOWN_HOUSE":1544,"MAP_VERDANTURF_TOWN_MART":1539,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":1540,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":1541,"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":1542,"MAP_VICTORY_ROAD_1F":6187,"MAP_VICTORY_ROAD_B1F":6188,"MAP_VICTORY_ROAD_B2F":6189,"MAX_BAG_ITEM_CAPACITY":99,"MAX_BERRY_CAPACITY":999,"MAX_BERRY_INDEX":178,"MAX_ITEM_DIGITS":3,"MAX_PC_ITEM_CAPACITY":999,"MAX_TRAINERS_COUNT":864,"MOVES_COUNT":355,"MOVE_ABSORB":71,"MOVE_ACID":51,"MOVE_ACID_ARMOR":151,"MOVE_AERIAL_ACE":332,"MOVE_AEROBLAST":177,"MOVE_AGILITY":97,"MOVE_AIR_CUTTER":314,"MOVE_AMNESIA":133,"MOVE_ANCIENT_POWER":246,"MOVE_ARM_THRUST":292,"MOVE_AROMATHERAPY":312,"MOVE_ASSIST":274,"MOVE_ASTONISH":310,"MOVE_ATTRACT":213,"MOVE_AURORA_BEAM":62,"MOVE_BARRAGE":140,"MOVE_BARRIER":112,"MOVE_BATON_PASS":226,"MOVE_BEAT_UP":251,"MOVE_BELLY_DRUM":187,"MOVE_BIDE":117,"MOVE_BIND":20,"MOVE_BITE":44,"MOVE_BLAST_BURN":307,"MOVE_BLAZE_KICK":299,"MOVE_BLIZZARD":59,"MOVE_BLOCK":335,"MOVE_BODY_SLAM":34,"MOVE_BONEMERANG":155,"MOVE_BONE_CLUB":125,"MOVE_BONE_RUSH":198,"MOVE_BOUNCE":340,"MOVE_BRICK_BREAK":280,"MOVE_BUBBLE":145,"MOVE_BUBBLE_BEAM":61,"MOVE_BULK_UP":339,"MOVE_BULLET_SEED":331,"MOVE_CALM_MIND":347,"MOVE_CAMOUFLAGE":293,"MOVE_CHARGE":268,"MOVE_CHARM":204,"MOVE_CLAMP":128,"MOVE_COMET_PUNCH":4,"MOVE_CONFUSE_RAY":109,"MOVE_CONFUSION":93,"MOVE_CONSTRICT":132,"MOVE_CONVERSION":160,"MOVE_CONVERSION_2":176,"MOVE_COSMIC_POWER":322,"MOVE_COTTON_SPORE":178,"MOVE_COUNTER":68,"MOVE_COVET":343,"MOVE_CRABHAMMER":152,"MOVE_CROSS_CHOP":238,"MOVE_CRUNCH":242,"MOVE_CRUSH_CLAW":306,"MOVE_CURSE":174,"MOVE_CUT":15,"MOVE_DEFENSE_CURL":111,"MOVE_DESTINY_BOND":194,"MOVE_DETECT":197,"MOVE_DIG":91,"MOVE_DISABLE":50,"MOVE_DIVE":291,"MOVE_DIZZY_PUNCH":146,"MOVE_DOOM_DESIRE":353,"MOVE_DOUBLE_EDGE":38,"MOVE_DOUBLE_KICK":24,"MOVE_DOUBLE_SLAP":3,"MOVE_DOUBLE_TEAM":104,"MOVE_DRAGON_BREATH":225,"MOVE_DRAGON_CLAW":337,"MOVE_DRAGON_DANCE":349,"MOVE_DRAGON_RAGE":82,"MOVE_DREAM_EATER":138,"MOVE_DRILL_PECK":65,"MOVE_DYNAMIC_PUNCH":223,"MOVE_EARTHQUAKE":89,"MOVE_EGG_BOMB":121,"MOVE_EMBER":52,"MOVE_ENCORE":227,"MOVE_ENDEAVOR":283,"MOVE_ENDURE":203,"MOVE_ERUPTION":284,"MOVE_EXPLOSION":153,"MOVE_EXTRASENSORY":326,"MOVE_EXTREME_SPEED":245,"MOVE_FACADE":263,"MOVE_FAINT_ATTACK":185,"MOVE_FAKE_OUT":252,"MOVE_FAKE_TEARS":313,"MOVE_FALSE_SWIPE":206,"MOVE_FEATHER_DANCE":297,"MOVE_FIRE_BLAST":126,"MOVE_FIRE_PUNCH":7,"MOVE_FIRE_SPIN":83,"MOVE_FISSURE":90,"MOVE_FLAIL":175,"MOVE_FLAMETHROWER":53,"MOVE_FLAME_WHEEL":172,"MOVE_FLASH":148,"MOVE_FLATTER":260,"MOVE_FLY":19,"MOVE_FOCUS_ENERGY":116,"MOVE_FOCUS_PUNCH":264,"MOVE_FOLLOW_ME":266,"MOVE_FORESIGHT":193,"MOVE_FRENZY_PLANT":338,"MOVE_FRUSTRATION":218,"MOVE_FURY_ATTACK":31,"MOVE_FURY_CUTTER":210,"MOVE_FURY_SWIPES":154,"MOVE_FUTURE_SIGHT":248,"MOVE_GIGA_DRAIN":202,"MOVE_GLARE":137,"MOVE_GRASS_WHISTLE":320,"MOVE_GROWL":45,"MOVE_GROWTH":74,"MOVE_GRUDGE":288,"MOVE_GUILLOTINE":12,"MOVE_GUST":16,"MOVE_HAIL":258,"MOVE_HARDEN":106,"MOVE_HAZE":114,"MOVE_HEADBUTT":29,"MOVE_HEAL_BELL":215,"MOVE_HEAT_WAVE":257,"MOVE_HELPING_HAND":270,"MOVE_HIDDEN_POWER":237,"MOVE_HI_JUMP_KICK":136,"MOVE_HORN_ATTACK":30,"MOVE_HORN_DRILL":32,"MOVE_HOWL":336,"MOVE_HYDRO_CANNON":308,"MOVE_HYDRO_PUMP":56,"MOVE_HYPER_BEAM":63,"MOVE_HYPER_FANG":158,"MOVE_HYPER_VOICE":304,"MOVE_HYPNOSIS":95,"MOVE_ICE_BALL":301,"MOVE_ICE_BEAM":58,"MOVE_ICE_PUNCH":8,"MOVE_ICICLE_SPEAR":333,"MOVE_ICY_WIND":196,"MOVE_IMPRISON":286,"MOVE_INGRAIN":275,"MOVE_IRON_DEFENSE":334,"MOVE_IRON_TAIL":231,"MOVE_JUMP_KICK":26,"MOVE_KARATE_CHOP":2,"MOVE_KINESIS":134,"MOVE_KNOCK_OFF":282,"MOVE_LEAF_BLADE":348,"MOVE_LEECH_LIFE":141,"MOVE_LEECH_SEED":73,"MOVE_LEER":43,"MOVE_LICK":122,"MOVE_LIGHT_SCREEN":113,"MOVE_LOCK_ON":199,"MOVE_LOVELY_KISS":142,"MOVE_LOW_KICK":67,"MOVE_LUSTER_PURGE":295,"MOVE_MACH_PUNCH":183,"MOVE_MAGICAL_LEAF":345,"MOVE_MAGIC_COAT":277,"MOVE_MAGNITUDE":222,"MOVE_MEAN_LOOK":212,"MOVE_MEDITATE":96,"MOVE_MEGAHORN":224,"MOVE_MEGA_DRAIN":72,"MOVE_MEGA_KICK":25,"MOVE_MEGA_PUNCH":5,"MOVE_MEMENTO":262,"MOVE_METAL_CLAW":232,"MOVE_METAL_SOUND":319,"MOVE_METEOR_MASH":309,"MOVE_METRONOME":118,"MOVE_MILK_DRINK":208,"MOVE_MIMIC":102,"MOVE_MIND_READER":170,"MOVE_MINIMIZE":107,"MOVE_MIRROR_COAT":243,"MOVE_MIRROR_MOVE":119,"MOVE_MIST":54,"MOVE_MIST_BALL":296,"MOVE_MOONLIGHT":236,"MOVE_MORNING_SUN":234,"MOVE_MUDDY_WATER":330,"MOVE_MUD_SHOT":341,"MOVE_MUD_SLAP":189,"MOVE_MUD_SPORT":300,"MOVE_NATURE_POWER":267,"MOVE_NEEDLE_ARM":302,"MOVE_NIGHTMARE":171,"MOVE_NIGHT_SHADE":101,"MOVE_NONE":0,"MOVE_OCTAZOOKA":190,"MOVE_ODOR_SLEUTH":316,"MOVE_OUTRAGE":200,"MOVE_OVERHEAT":315,"MOVE_PAIN_SPLIT":220,"MOVE_PAY_DAY":6,"MOVE_PECK":64,"MOVE_PERISH_SONG":195,"MOVE_PETAL_DANCE":80,"MOVE_PIN_MISSILE":42,"MOVE_POISON_FANG":305,"MOVE_POISON_GAS":139,"MOVE_POISON_POWDER":77,"MOVE_POISON_STING":40,"MOVE_POISON_TAIL":342,"MOVE_POUND":1,"MOVE_POWDER_SNOW":181,"MOVE_PRESENT":217,"MOVE_PROTECT":182,"MOVE_PSYBEAM":60,"MOVE_PSYCHIC":94,"MOVE_PSYCHO_BOOST":354,"MOVE_PSYCH_UP":244,"MOVE_PSYWAVE":149,"MOVE_PURSUIT":228,"MOVE_QUICK_ATTACK":98,"MOVE_RAGE":99,"MOVE_RAIN_DANCE":240,"MOVE_RAPID_SPIN":229,"MOVE_RAZOR_LEAF":75,"MOVE_RAZOR_WIND":13,"MOVE_RECOVER":105,"MOVE_RECYCLE":278,"MOVE_REFLECT":115,"MOVE_REFRESH":287,"MOVE_REST":156,"MOVE_RETURN":216,"MOVE_REVENGE":279,"MOVE_REVERSAL":179,"MOVE_ROAR":46,"MOVE_ROCK_BLAST":350,"MOVE_ROCK_SLIDE":157,"MOVE_ROCK_SMASH":249,"MOVE_ROCK_THROW":88,"MOVE_ROCK_TOMB":317,"MOVE_ROLE_PLAY":272,"MOVE_ROLLING_KICK":27,"MOVE_ROLLOUT":205,"MOVE_SACRED_FIRE":221,"MOVE_SAFEGUARD":219,"MOVE_SANDSTORM":201,"MOVE_SAND_ATTACK":28,"MOVE_SAND_TOMB":328,"MOVE_SCARY_FACE":184,"MOVE_SCRATCH":10,"MOVE_SCREECH":103,"MOVE_SECRET_POWER":290,"MOVE_SEISMIC_TOSS":69,"MOVE_SELF_DESTRUCT":120,"MOVE_SHADOW_BALL":247,"MOVE_SHADOW_PUNCH":325,"MOVE_SHARPEN":159,"MOVE_SHEER_COLD":329,"MOVE_SHOCK_WAVE":351,"MOVE_SIGNAL_BEAM":324,"MOVE_SILVER_WIND":318,"MOVE_SING":47,"MOVE_SKETCH":166,"MOVE_SKILL_SWAP":285,"MOVE_SKULL_BASH":130,"MOVE_SKY_ATTACK":143,"MOVE_SKY_UPPERCUT":327,"MOVE_SLACK_OFF":303,"MOVE_SLAM":21,"MOVE_SLASH":163,"MOVE_SLEEP_POWDER":79,"MOVE_SLEEP_TALK":214,"MOVE_SLUDGE":124,"MOVE_SLUDGE_BOMB":188,"MOVE_SMELLING_SALT":265,"MOVE_SMOG":123,"MOVE_SMOKESCREEN":108,"MOVE_SNATCH":289,"MOVE_SNORE":173,"MOVE_SOFT_BOILED":135,"MOVE_SOLAR_BEAM":76,"MOVE_SONIC_BOOM":49,"MOVE_SPARK":209,"MOVE_SPIDER_WEB":169,"MOVE_SPIKES":191,"MOVE_SPIKE_CANNON":131,"MOVE_SPITE":180,"MOVE_SPIT_UP":255,"MOVE_SPLASH":150,"MOVE_SPORE":147,"MOVE_STEEL_WING":211,"MOVE_STOCKPILE":254,"MOVE_STOMP":23,"MOVE_STRENGTH":70,"MOVE_STRING_SHOT":81,"MOVE_STRUGGLE":165,"MOVE_STUN_SPORE":78,"MOVE_SUBMISSION":66,"MOVE_SUBSTITUTE":164,"MOVE_SUNNY_DAY":241,"MOVE_SUPERPOWER":276,"MOVE_SUPERSONIC":48,"MOVE_SUPER_FANG":162,"MOVE_SURF":57,"MOVE_SWAGGER":207,"MOVE_SWALLOW":256,"MOVE_SWEET_KISS":186,"MOVE_SWEET_SCENT":230,"MOVE_SWIFT":129,"MOVE_SWORDS_DANCE":14,"MOVE_SYNTHESIS":235,"MOVE_TACKLE":33,"MOVE_TAIL_GLOW":294,"MOVE_TAIL_WHIP":39,"MOVE_TAKE_DOWN":36,"MOVE_TAUNT":269,"MOVE_TEETER_DANCE":298,"MOVE_TELEPORT":100,"MOVE_THIEF":168,"MOVE_THRASH":37,"MOVE_THUNDER":87,"MOVE_THUNDERBOLT":85,"MOVE_THUNDER_PUNCH":9,"MOVE_THUNDER_SHOCK":84,"MOVE_THUNDER_WAVE":86,"MOVE_TICKLE":321,"MOVE_TORMENT":259,"MOVE_TOXIC":92,"MOVE_TRANSFORM":144,"MOVE_TRICK":271,"MOVE_TRIPLE_KICK":167,"MOVE_TRI_ATTACK":161,"MOVE_TWINEEDLE":41,"MOVE_TWISTER":239,"MOVE_UNAVAILABLE":65535,"MOVE_UPROAR":253,"MOVE_VICE_GRIP":11,"MOVE_VINE_WHIP":22,"MOVE_VITAL_THROW":233,"MOVE_VOLT_TACKLE":344,"MOVE_WATERFALL":127,"MOVE_WATER_GUN":55,"MOVE_WATER_PULSE":352,"MOVE_WATER_SPORT":346,"MOVE_WATER_SPOUT":323,"MOVE_WEATHER_BALL":311,"MOVE_WHIRLPOOL":250,"MOVE_WHIRLWIND":18,"MOVE_WILL_O_WISP":261,"MOVE_WING_ATTACK":17,"MOVE_WISH":273,"MOVE_WITHDRAW":110,"MOVE_WRAP":35,"MOVE_YAWN":281,"MOVE_ZAP_CANNON":192,"MUS_ABANDONED_SHIP":381,"MUS_ABNORMAL_WEATHER":443,"MUS_AQUA_MAGMA_HIDEOUT":430,"MUS_AWAKEN_LEGEND":388,"MUS_BIRCH_LAB":383,"MUS_B_ARENA":458,"MUS_B_DOME":467,"MUS_B_DOME_LOBBY":473,"MUS_B_FACTORY":469,"MUS_B_FRONTIER":457,"MUS_B_PALACE":463,"MUS_B_PIKE":468,"MUS_B_PYRAMID":461,"MUS_B_PYRAMID_TOP":462,"MUS_B_TOWER":465,"MUS_B_TOWER_RS":384,"MUS_CABLE_CAR":425,"MUS_CAUGHT":352,"MUS_CAVE_OF_ORIGIN":386,"MUS_CONTEST":440,"MUS_CONTEST_LOBBY":452,"MUS_CONTEST_RESULTS":446,"MUS_CONTEST_WINNER":439,"MUS_CREDITS":455,"MUS_CYCLING":403,"MUS_C_COMM_CENTER":356,"MUS_C_VS_LEGEND_BEAST":358,"MUS_DESERT":409,"MUS_DEWFORD":427,"MUS_DUMMY":0,"MUS_ENCOUNTER_AQUA":419,"MUS_ENCOUNTER_BRENDAN":421,"MUS_ENCOUNTER_CHAMPION":454,"MUS_ENCOUNTER_COOL":417,"MUS_ENCOUNTER_ELITE_FOUR":450,"MUS_ENCOUNTER_FEMALE":407,"MUS_ENCOUNTER_GIRL":379,"MUS_ENCOUNTER_HIKER":451,"MUS_ENCOUNTER_INTENSE":416,"MUS_ENCOUNTER_INTERVIEWER":453,"MUS_ENCOUNTER_MAGMA":441,"MUS_ENCOUNTER_MALE":380,"MUS_ENCOUNTER_MAY":415,"MUS_ENCOUNTER_RICH":397,"MUS_ENCOUNTER_SUSPICIOUS":423,"MUS_ENCOUNTER_SWIMMER":385,"MUS_ENCOUNTER_TWINS":449,"MUS_END":456,"MUS_EVER_GRANDE":422,"MUS_EVOLUTION":377,"MUS_EVOLUTION_INTRO":376,"MUS_EVOLVED":371,"MUS_FALLARBOR":437,"MUS_FOLLOW_ME":420,"MUS_FORTREE":382,"MUS_GAME_CORNER":426,"MUS_GSC_PEWTER":357,"MUS_GSC_ROUTE38":351,"MUS_GYM":364,"MUS_HALL_OF_FAME":436,"MUS_HALL_OF_FAME_ROOM":447,"MUS_HEAL":368,"MUS_HELP":410,"MUS_INTRO":414,"MUS_INTRO_BATTLE":442,"MUS_LEVEL_UP":367,"MUS_LILYCOVE":408,"MUS_LILYCOVE_MUSEUM":373,"MUS_LINK_CONTEST_P1":393,"MUS_LINK_CONTEST_P2":394,"MUS_LINK_CONTEST_P3":395,"MUS_LINK_CONTEST_P4":396,"MUS_LITTLEROOT":405,"MUS_LITTLEROOT_TEST":350,"MUS_MOVE_DELETED":378,"MUS_MT_CHIMNEY":406,"MUS_MT_PYRE":432,"MUS_MT_PYRE_EXTERIOR":434,"MUS_NONE":65535,"MUS_OBTAIN_BADGE":369,"MUS_OBTAIN_BERRY":387,"MUS_OBTAIN_B_POINTS":459,"MUS_OBTAIN_ITEM":370,"MUS_OBTAIN_SYMBOL":466,"MUS_OBTAIN_TMHM":372,"MUS_OCEANIC_MUSEUM":375,"MUS_OLDALE":363,"MUS_PETALBURG":362,"MUS_PETALBURG_WOODS":366,"MUS_POKE_CENTER":400,"MUS_POKE_MART":404,"MUS_RAYQUAZA_APPEARS":464,"MUS_REGISTER_MATCH_CALL":460,"MUS_RG_BERRY_PICK":542,"MUS_RG_CAUGHT":534,"MUS_RG_CAUGHT_INTRO":531,"MUS_RG_CELADON":521,"MUS_RG_CINNABAR":491,"MUS_RG_CREDITS":502,"MUS_RG_CYCLING":494,"MUS_RG_DEX_RATING":529,"MUS_RG_ENCOUNTER_BOY":497,"MUS_RG_ENCOUNTER_DEOXYS":555,"MUS_RG_ENCOUNTER_GIRL":496,"MUS_RG_ENCOUNTER_GYM_LEADER":554,"MUS_RG_ENCOUNTER_RIVAL":527,"MUS_RG_ENCOUNTER_ROCKET":495,"MUS_RG_FOLLOW_ME":484,"MUS_RG_FUCHSIA":520,"MUS_RG_GAME_CORNER":485,"MUS_RG_GAME_FREAK":533,"MUS_RG_GYM":487,"MUS_RG_HALL_OF_FAME":498,"MUS_RG_HEAL":493,"MUS_RG_INTRO_FIGHT":489,"MUS_RG_JIGGLYPUFF":488,"MUS_RG_LAVENDER":492,"MUS_RG_MT_MOON":500,"MUS_RG_MYSTERY_GIFT":541,"MUS_RG_NET_CENTER":540,"MUS_RG_NEW_GAME_EXIT":537,"MUS_RG_NEW_GAME_INSTRUCT":535,"MUS_RG_NEW_GAME_INTRO":536,"MUS_RG_OAK":514,"MUS_RG_OAK_LAB":513,"MUS_RG_OBTAIN_KEY_ITEM":530,"MUS_RG_PALLET":512,"MUS_RG_PEWTER":526,"MUS_RG_PHOTO":532,"MUS_RG_POKE_CENTER":515,"MUS_RG_POKE_FLUTE":550,"MUS_RG_POKE_JUMP":538,"MUS_RG_POKE_MANSION":501,"MUS_RG_POKE_TOWER":518,"MUS_RG_RIVAL_EXIT":528,"MUS_RG_ROCKET_HIDEOUT":486,"MUS_RG_ROUTE1":503,"MUS_RG_ROUTE11":506,"MUS_RG_ROUTE24":504,"MUS_RG_ROUTE3":505,"MUS_RG_SEVII_123":547,"MUS_RG_SEVII_45":548,"MUS_RG_SEVII_67":549,"MUS_RG_SEVII_CAVE":543,"MUS_RG_SEVII_DUNGEON":546,"MUS_RG_SEVII_ROUTE":545,"MUS_RG_SILPH":519,"MUS_RG_SLOW_PALLET":557,"MUS_RG_SS_ANNE":516,"MUS_RG_SURF":517,"MUS_RG_TEACHY_TV_MENU":558,"MUS_RG_TEACHY_TV_SHOW":544,"MUS_RG_TITLE":490,"MUS_RG_TRAINER_TOWER":556,"MUS_RG_UNION_ROOM":539,"MUS_RG_VERMILLION":525,"MUS_RG_VICTORY_GYM_LEADER":524,"MUS_RG_VICTORY_ROAD":507,"MUS_RG_VICTORY_TRAINER":522,"MUS_RG_VICTORY_WILD":523,"MUS_RG_VIRIDIAN_FOREST":499,"MUS_RG_VS_CHAMPION":511,"MUS_RG_VS_DEOXYS":551,"MUS_RG_VS_GYM_LEADER":508,"MUS_RG_VS_LEGEND":553,"MUS_RG_VS_MEWTWO":552,"MUS_RG_VS_TRAINER":509,"MUS_RG_VS_WILD":510,"MUS_ROULETTE":392,"MUS_ROUTE101":359,"MUS_ROUTE104":401,"MUS_ROUTE110":360,"MUS_ROUTE113":418,"MUS_ROUTE118":32767,"MUS_ROUTE119":402,"MUS_ROUTE120":361,"MUS_ROUTE122":374,"MUS_RUSTBORO":399,"MUS_SAFARI_ZONE":428,"MUS_SAILING":431,"MUS_SCHOOL":435,"MUS_SEALED_CHAMBER":438,"MUS_SLATEPORT":433,"MUS_SLOTS_JACKPOT":389,"MUS_SLOTS_WIN":390,"MUS_SOOTOPOLIS":445,"MUS_SURF":365,"MUS_TITLE":413,"MUS_TOO_BAD":391,"MUS_TRICK_HOUSE":448,"MUS_UNDERWATER":411,"MUS_VERDANTURF":398,"MUS_VICTORY_AQUA_MAGMA":424,"MUS_VICTORY_GYM_LEADER":354,"MUS_VICTORY_LEAGUE":355,"MUS_VICTORY_ROAD":429,"MUS_VICTORY_TRAINER":412,"MUS_VICTORY_WILD":353,"MUS_VS_AQUA_MAGMA":475,"MUS_VS_AQUA_MAGMA_LEADER":483,"MUS_VS_CHAMPION":478,"MUS_VS_ELITE_FOUR":482,"MUS_VS_FRONTIER_BRAIN":471,"MUS_VS_GYM_LEADER":477,"MUS_VS_KYOGRE_GROUDON":480,"MUS_VS_MEW":472,"MUS_VS_RAYQUAZA":470,"MUS_VS_REGI":479,"MUS_VS_RIVAL":481,"MUS_VS_TRAINER":476,"MUS_VS_WILD":474,"MUS_WEATHER_GROUDON":444,"NUM_BADGES":8,"NUM_BERRY_MASTER_BERRIES":10,"NUM_BERRY_MASTER_BERRIES_SKIPPED":20,"NUM_BERRY_MASTER_WIFE_BERRIES":10,"NUM_DAILY_FLAGS":64,"NUM_HIDDEN_MACHINES":8,"NUM_KIRI_BERRIES":10,"NUM_KIRI_BERRIES_SKIPPED":20,"NUM_ROUTE_114_MAN_BERRIES":5,"NUM_ROUTE_114_MAN_BERRIES_SKIPPED":15,"NUM_SPECIAL_FLAGS":128,"NUM_SPECIES":412,"NUM_TECHNICAL_MACHINES":50,"NUM_TEMP_FLAGS":32,"NUM_WATER_STAGES":4,"NUM_WONDER_CARD_FLAGS":20,"OLD_ROD":0,"PH_CHOICE_BLEND":589,"PH_CHOICE_HELD":590,"PH_CHOICE_SOLO":591,"PH_CLOTH_BLEND":565,"PH_CLOTH_HELD":566,"PH_CLOTH_SOLO":567,"PH_CURE_BLEND":604,"PH_CURE_HELD":605,"PH_CURE_SOLO":606,"PH_DRESS_BLEND":568,"PH_DRESS_HELD":569,"PH_DRESS_SOLO":570,"PH_FACE_BLEND":562,"PH_FACE_HELD":563,"PH_FACE_SOLO":564,"PH_FLEECE_BLEND":571,"PH_FLEECE_HELD":572,"PH_FLEECE_SOLO":573,"PH_FOOT_BLEND":595,"PH_FOOT_HELD":596,"PH_FOOT_SOLO":597,"PH_GOAT_BLEND":583,"PH_GOAT_HELD":584,"PH_GOAT_SOLO":585,"PH_GOOSE_BLEND":598,"PH_GOOSE_HELD":599,"PH_GOOSE_SOLO":600,"PH_KIT_BLEND":574,"PH_KIT_HELD":575,"PH_KIT_SOLO":576,"PH_LOT_BLEND":580,"PH_LOT_HELD":581,"PH_LOT_SOLO":582,"PH_MOUTH_BLEND":592,"PH_MOUTH_HELD":593,"PH_MOUTH_SOLO":594,"PH_NURSE_BLEND":607,"PH_NURSE_HELD":608,"PH_NURSE_SOLO":609,"PH_PRICE_BLEND":577,"PH_PRICE_HELD":578,"PH_PRICE_SOLO":579,"PH_STRUT_BLEND":601,"PH_STRUT_HELD":602,"PH_STRUT_SOLO":603,"PH_THOUGHT_BLEND":586,"PH_THOUGHT_HELD":587,"PH_THOUGHT_SOLO":588,"PH_TRAP_BLEND":559,"PH_TRAP_HELD":560,"PH_TRAP_SOLO":561,"SE_A":25,"SE_APPLAUSE":105,"SE_ARENA_TIMEUP1":265,"SE_ARENA_TIMEUP2":266,"SE_BALL":23,"SE_BALLOON_BLUE":75,"SE_BALLOON_RED":74,"SE_BALLOON_YELLOW":76,"SE_BALL_BOUNCE_1":56,"SE_BALL_BOUNCE_2":57,"SE_BALL_BOUNCE_3":58,"SE_BALL_BOUNCE_4":59,"SE_BALL_OPEN":15,"SE_BALL_THROW":61,"SE_BALL_TRADE":60,"SE_BALL_TRAY_BALL":115,"SE_BALL_TRAY_ENTER":114,"SE_BALL_TRAY_EXIT":116,"SE_BANG":20,"SE_BERRY_BLENDER":53,"SE_BIKE_BELL":11,"SE_BIKE_HOP":34,"SE_BOO":22,"SE_BREAKABLE_DOOR":77,"SE_BRIDGE_WALK":71,"SE_CARD":54,"SE_CLICK":36,"SE_CONTEST_CONDITION_LOSE":38,"SE_CONTEST_CURTAIN_FALL":98,"SE_CONTEST_CURTAIN_RISE":97,"SE_CONTEST_HEART":96,"SE_CONTEST_ICON_CHANGE":99,"SE_CONTEST_ICON_CLEAR":100,"SE_CONTEST_MONS_TURN":101,"SE_CONTEST_PLACE":24,"SE_DEX_PAGE":109,"SE_DEX_SCROLL":108,"SE_DEX_SEARCH":112,"SE_DING_DONG":73,"SE_DOOR":8,"SE_DOWNPOUR":83,"SE_DOWNPOUR_STOP":84,"SE_E":28,"SE_EFFECTIVE":13,"SE_EGG_HATCH":113,"SE_ELEVATOR":89,"SE_ESCALATOR":80,"SE_EXIT":9,"SE_EXP":33,"SE_EXP_MAX":91,"SE_FAILURE":32,"SE_FAINT":16,"SE_FALL":43,"SE_FIELD_POISON":79,"SE_FLEE":17,"SE_FU_ZAKU":37,"SE_GLASS_FLUTE":117,"SE_I":26,"SE_ICE_BREAK":41,"SE_ICE_CRACK":42,"SE_ICE_STAIRS":40,"SE_INTRO_BLAST":103,"SE_ITEMFINDER":72,"SE_LAVARIDGE_FALL_WARP":39,"SE_LEDGE":10,"SE_LOW_HEALTH":90,"SE_MUD_BALL":78,"SE_MUGSHOT":104,"SE_M_ABSORB":180,"SE_M_ABSORB_2":179,"SE_M_ACID_ARMOR":218,"SE_M_ATTRACT":226,"SE_M_ATTRACT2":227,"SE_M_BARRIER":208,"SE_M_BATON_PASS":224,"SE_M_BELLY_DRUM":185,"SE_M_BIND":170,"SE_M_BITE":161,"SE_M_BLIZZARD":153,"SE_M_BLIZZARD2":154,"SE_M_BONEMERANG":187,"SE_M_BRICK_BREAK":198,"SE_M_BUBBLE":124,"SE_M_BUBBLE2":125,"SE_M_BUBBLE3":126,"SE_M_BUBBLE_BEAM":182,"SE_M_BUBBLE_BEAM2":183,"SE_M_CHARGE":213,"SE_M_CHARM":212,"SE_M_COMET_PUNCH":139,"SE_M_CONFUSE_RAY":196,"SE_M_COSMIC_POWER":243,"SE_M_CRABHAMMER":142,"SE_M_CUT":128,"SE_M_DETECT":209,"SE_M_DIG":175,"SE_M_DIVE":233,"SE_M_DIZZY_PUNCH":176,"SE_M_DOUBLE_SLAP":134,"SE_M_DOUBLE_TEAM":135,"SE_M_DRAGON_RAGE":171,"SE_M_EARTHQUAKE":234,"SE_M_EMBER":151,"SE_M_ENCORE":222,"SE_M_ENCORE2":223,"SE_M_EXPLOSION":178,"SE_M_FAINT_ATTACK":190,"SE_M_FIRE_PUNCH":147,"SE_M_FLAMETHROWER":146,"SE_M_FLAME_WHEEL":144,"SE_M_FLAME_WHEEL2":145,"SE_M_FLATTER":229,"SE_M_FLY":158,"SE_M_GIGA_DRAIN":199,"SE_M_GRASSWHISTLE":231,"SE_M_GUST":132,"SE_M_GUST2":133,"SE_M_HAIL":242,"SE_M_HARDEN":120,"SE_M_HAZE":246,"SE_M_HEADBUTT":162,"SE_M_HEAL_BELL":195,"SE_M_HEAT_WAVE":240,"SE_M_HORN_ATTACK":166,"SE_M_HYDRO_PUMP":164,"SE_M_HYPER_BEAM":215,"SE_M_HYPER_BEAM2":247,"SE_M_ICY_WIND":137,"SE_M_JUMP_KICK":143,"SE_M_LEER":192,"SE_M_LICK":188,"SE_M_LOCK_ON":210,"SE_M_MEGA_KICK":140,"SE_M_MEGA_KICK2":141,"SE_M_METRONOME":186,"SE_M_MILK_DRINK":225,"SE_M_MINIMIZE":204,"SE_M_MIST":168,"SE_M_MOONLIGHT":211,"SE_M_MORNING_SUN":228,"SE_M_NIGHTMARE":121,"SE_M_PAY_DAY":174,"SE_M_PERISH_SONG":173,"SE_M_PETAL_DANCE":202,"SE_M_POISON_POWDER":169,"SE_M_PSYBEAM":189,"SE_M_PSYBEAM2":200,"SE_M_RAIN_DANCE":127,"SE_M_RAZOR_WIND":136,"SE_M_RAZOR_WIND2":160,"SE_M_REFLECT":207,"SE_M_REVERSAL":217,"SE_M_ROCK_THROW":131,"SE_M_SACRED_FIRE":149,"SE_M_SACRED_FIRE2":150,"SE_M_SANDSTORM":219,"SE_M_SAND_ATTACK":159,"SE_M_SAND_TOMB":230,"SE_M_SCRATCH":155,"SE_M_SCREECH":181,"SE_M_SELF_DESTRUCT":177,"SE_M_SING":172,"SE_M_SKETCH":205,"SE_M_SKY_UPPERCUT":238,"SE_M_SNORE":197,"SE_M_SOLAR_BEAM":201,"SE_M_SPIT_UP":232,"SE_M_STAT_DECREASE":245,"SE_M_STAT_INCREASE":239,"SE_M_STRENGTH":214,"SE_M_STRING_SHOT":129,"SE_M_STRING_SHOT2":130,"SE_M_SUPERSONIC":184,"SE_M_SURF":163,"SE_M_SWAGGER":193,"SE_M_SWAGGER2":194,"SE_M_SWEET_SCENT":236,"SE_M_SWIFT":206,"SE_M_SWORDS_DANCE":191,"SE_M_TAIL_WHIP":167,"SE_M_TAKE_DOWN":152,"SE_M_TEETER_DANCE":244,"SE_M_TELEPORT":203,"SE_M_THUNDERBOLT":118,"SE_M_THUNDERBOLT2":119,"SE_M_THUNDER_WAVE":138,"SE_M_TOXIC":148,"SE_M_TRI_ATTACK":220,"SE_M_TRI_ATTACK2":221,"SE_M_TWISTER":235,"SE_M_UPROAR":241,"SE_M_VICEGRIP":156,"SE_M_VITAL_THROW":122,"SE_M_VITAL_THROW2":123,"SE_M_WATERFALL":216,"SE_M_WHIRLPOOL":165,"SE_M_WING_ATTACK":157,"SE_M_YAWN":237,"SE_N":30,"SE_NOTE_A":67,"SE_NOTE_B":68,"SE_NOTE_C":62,"SE_NOTE_C_HIGH":69,"SE_NOTE_D":63,"SE_NOTE_E":64,"SE_NOTE_F":65,"SE_NOTE_G":66,"SE_NOT_EFFECTIVE":12,"SE_O":29,"SE_ORB":107,"SE_PC_LOGIN":2,"SE_PC_OFF":3,"SE_PC_ON":4,"SE_PIKE_CURTAIN_CLOSE":267,"SE_PIKE_CURTAIN_OPEN":268,"SE_PIN":21,"SE_POKENAV_CALL":263,"SE_POKENAV_HANG_UP":264,"SE_POKENAV_OFF":111,"SE_POKENAV_ON":110,"SE_PUDDLE":70,"SE_RAIN":85,"SE_RAIN_STOP":86,"SE_REPEL":47,"SE_RG_BAG_CURSOR":252,"SE_RG_BAG_POCKET":253,"SE_RG_BALL_CLICK":254,"SE_RG_CARD_FLIP":249,"SE_RG_CARD_FLIPPING":250,"SE_RG_CARD_OPEN":251,"SE_RG_DEOXYS_MOVE":260,"SE_RG_DOOR":248,"SE_RG_HELP_CLOSE":258,"SE_RG_HELP_ERROR":259,"SE_RG_HELP_OPEN":257,"SE_RG_POKE_JUMP_FAILURE":262,"SE_RG_POKE_JUMP_SUCCESS":261,"SE_RG_SHOP":255,"SE_RG_SS_ANNE_HORN":256,"SE_ROTATING_GATE":48,"SE_ROULETTE_BALL":92,"SE_ROULETTE_BALL2":93,"SE_SAVE":55,"SE_SELECT":5,"SE_SHINY":102,"SE_SHIP":19,"SE_SHOP":95,"SE_SLIDING_DOOR":18,"SE_SUCCESS":31,"SE_SUDOWOODO_SHAKE":269,"SE_SUPER_EFFECTIVE":14,"SE_SWITCH":35,"SE_TAILLOW_WING_FLAP":94,"SE_THUNDER":87,"SE_THUNDER2":88,"SE_THUNDERSTORM":81,"SE_THUNDERSTORM_STOP":82,"SE_TRUCK_DOOR":52,"SE_TRUCK_MOVE":49,"SE_TRUCK_STOP":50,"SE_TRUCK_UNLOAD":51,"SE_U":27,"SE_UNLOCK":44,"SE_USE_ITEM":1,"SE_VEND":106,"SE_WALL_HIT":7,"SE_WARP_IN":45,"SE_WARP_OUT":46,"SE_WIN_OPEN":6,"SPECIAL_FLAGS_END":16511,"SPECIAL_FLAGS_START":16384,"SPECIES_ABRA":63,"SPECIES_ABSOL":376,"SPECIES_AERODACTYL":142,"SPECIES_AGGRON":384,"SPECIES_AIPOM":190,"SPECIES_ALAKAZAM":65,"SPECIES_ALTARIA":359,"SPECIES_AMPHAROS":181,"SPECIES_ANORITH":390,"SPECIES_ARBOK":24,"SPECIES_ARCANINE":59,"SPECIES_ARIADOS":168,"SPECIES_ARMALDO":391,"SPECIES_ARON":382,"SPECIES_ARTICUNO":144,"SPECIES_AZUMARILL":184,"SPECIES_AZURILL":350,"SPECIES_BAGON":395,"SPECIES_BALTOY":318,"SPECIES_BANETTE":378,"SPECIES_BARBOACH":323,"SPECIES_BAYLEEF":153,"SPECIES_BEAUTIFLY":292,"SPECIES_BEEDRILL":15,"SPECIES_BELDUM":398,"SPECIES_BELLOSSOM":182,"SPECIES_BELLSPROUT":69,"SPECIES_BLASTOISE":9,"SPECIES_BLAZIKEN":282,"SPECIES_BLISSEY":242,"SPECIES_BRELOOM":307,"SPECIES_BULBASAUR":1,"SPECIES_BUTTERFREE":12,"SPECIES_CACNEA":344,"SPECIES_CACTURNE":345,"SPECIES_CAMERUPT":340,"SPECIES_CARVANHA":330,"SPECIES_CASCOON":293,"SPECIES_CASTFORM":385,"SPECIES_CATERPIE":10,"SPECIES_CELEBI":251,"SPECIES_CHANSEY":113,"SPECIES_CHARIZARD":6,"SPECIES_CHARMANDER":4,"SPECIES_CHARMELEON":5,"SPECIES_CHIKORITA":152,"SPECIES_CHIMECHO":411,"SPECIES_CHINCHOU":170,"SPECIES_CLAMPERL":373,"SPECIES_CLAYDOL":319,"SPECIES_CLEFABLE":36,"SPECIES_CLEFAIRY":35,"SPECIES_CLEFFA":173,"SPECIES_CLOYSTER":91,"SPECIES_COMBUSKEN":281,"SPECIES_CORPHISH":326,"SPECIES_CORSOLA":222,"SPECIES_CRADILY":389,"SPECIES_CRAWDAUNT":327,"SPECIES_CROBAT":169,"SPECIES_CROCONAW":159,"SPECIES_CUBONE":104,"SPECIES_CYNDAQUIL":155,"SPECIES_DELCATTY":316,"SPECIES_DELIBIRD":225,"SPECIES_DEOXYS":410,"SPECIES_DEWGONG":87,"SPECIES_DIGLETT":50,"SPECIES_DITTO":132,"SPECIES_DODRIO":85,"SPECIES_DODUO":84,"SPECIES_DONPHAN":232,"SPECIES_DRAGONAIR":148,"SPECIES_DRAGONITE":149,"SPECIES_DRATINI":147,"SPECIES_DROWZEE":96,"SPECIES_DUGTRIO":51,"SPECIES_DUNSPARCE":206,"SPECIES_DUSCLOPS":362,"SPECIES_DUSKULL":361,"SPECIES_DUSTOX":294,"SPECIES_EEVEE":133,"SPECIES_EGG":412,"SPECIES_EKANS":23,"SPECIES_ELECTABUZZ":125,"SPECIES_ELECTRIKE":337,"SPECIES_ELECTRODE":101,"SPECIES_ELEKID":239,"SPECIES_ENTEI":244,"SPECIES_ESPEON":196,"SPECIES_EXEGGCUTE":102,"SPECIES_EXEGGUTOR":103,"SPECIES_EXPLOUD":372,"SPECIES_FARFETCHD":83,"SPECIES_FEAROW":22,"SPECIES_FEEBAS":328,"SPECIES_FERALIGATR":160,"SPECIES_FLAAFFY":180,"SPECIES_FLAREON":136,"SPECIES_FLYGON":334,"SPECIES_FORRETRESS":205,"SPECIES_FURRET":162,"SPECIES_GARDEVOIR":394,"SPECIES_GASTLY":92,"SPECIES_GENGAR":94,"SPECIES_GEODUDE":74,"SPECIES_GIRAFARIG":203,"SPECIES_GLALIE":347,"SPECIES_GLIGAR":207,"SPECIES_GLOOM":44,"SPECIES_GOLBAT":42,"SPECIES_GOLDEEN":118,"SPECIES_GOLDUCK":55,"SPECIES_GOLEM":76,"SPECIES_GOREBYSS":375,"SPECIES_GRANBULL":210,"SPECIES_GRAVELER":75,"SPECIES_GRIMER":88,"SPECIES_GROUDON":405,"SPECIES_GROVYLE":278,"SPECIES_GROWLITHE":58,"SPECIES_GRUMPIG":352,"SPECIES_GULPIN":367,"SPECIES_GYARADOS":130,"SPECIES_HARIYAMA":336,"SPECIES_HAUNTER":93,"SPECIES_HERACROSS":214,"SPECIES_HITMONCHAN":107,"SPECIES_HITMONLEE":106,"SPECIES_HITMONTOP":237,"SPECIES_HOOTHOOT":163,"SPECIES_HOPPIP":187,"SPECIES_HORSEA":116,"SPECIES_HOUNDOOM":229,"SPECIES_HOUNDOUR":228,"SPECIES_HO_OH":250,"SPECIES_HUNTAIL":374,"SPECIES_HYPNO":97,"SPECIES_IGGLYBUFF":174,"SPECIES_ILLUMISE":387,"SPECIES_IVYSAUR":2,"SPECIES_JIGGLYPUFF":39,"SPECIES_JIRACHI":409,"SPECIES_JOLTEON":135,"SPECIES_JUMPLUFF":189,"SPECIES_JYNX":124,"SPECIES_KABUTO":140,"SPECIES_KABUTOPS":141,"SPECIES_KADABRA":64,"SPECIES_KAKUNA":14,"SPECIES_KANGASKHAN":115,"SPECIES_KECLEON":317,"SPECIES_KINGDRA":230,"SPECIES_KINGLER":99,"SPECIES_KIRLIA":393,"SPECIES_KOFFING":109,"SPECIES_KRABBY":98,"SPECIES_KYOGRE":404,"SPECIES_LAIRON":383,"SPECIES_LANTURN":171,"SPECIES_LAPRAS":131,"SPECIES_LARVITAR":246,"SPECIES_LATIAS":407,"SPECIES_LATIOS":408,"SPECIES_LEDIAN":166,"SPECIES_LEDYBA":165,"SPECIES_LICKITUNG":108,"SPECIES_LILEEP":388,"SPECIES_LINOONE":289,"SPECIES_LOMBRE":296,"SPECIES_LOTAD":295,"SPECIES_LOUDRED":371,"SPECIES_LUDICOLO":297,"SPECIES_LUGIA":249,"SPECIES_LUNATONE":348,"SPECIES_LUVDISC":325,"SPECIES_MACHAMP":68,"SPECIES_MACHOKE":67,"SPECIES_MACHOP":66,"SPECIES_MAGBY":240,"SPECIES_MAGCARGO":219,"SPECIES_MAGIKARP":129,"SPECIES_MAGMAR":126,"SPECIES_MAGNEMITE":81,"SPECIES_MAGNETON":82,"SPECIES_MAKUHITA":335,"SPECIES_MANECTRIC":338,"SPECIES_MANKEY":56,"SPECIES_MANTINE":226,"SPECIES_MAREEP":179,"SPECIES_MARILL":183,"SPECIES_MAROWAK":105,"SPECIES_MARSHTOMP":284,"SPECIES_MASQUERAIN":312,"SPECIES_MAWILE":355,"SPECIES_MEDICHAM":357,"SPECIES_MEDITITE":356,"SPECIES_MEGANIUM":154,"SPECIES_MEOWTH":52,"SPECIES_METAGROSS":400,"SPECIES_METANG":399,"SPECIES_METAPOD":11,"SPECIES_MEW":151,"SPECIES_MEWTWO":150,"SPECIES_MIGHTYENA":287,"SPECIES_MILOTIC":329,"SPECIES_MILTANK":241,"SPECIES_MINUN":354,"SPECIES_MISDREAVUS":200,"SPECIES_MOLTRES":146,"SPECIES_MR_MIME":122,"SPECIES_MUDKIP":283,"SPECIES_MUK":89,"SPECIES_MURKROW":198,"SPECIES_NATU":177,"SPECIES_NIDOKING":34,"SPECIES_NIDOQUEEN":31,"SPECIES_NIDORAN_F":29,"SPECIES_NIDORAN_M":32,"SPECIES_NIDORINA":30,"SPECIES_NIDORINO":33,"SPECIES_NINCADA":301,"SPECIES_NINETALES":38,"SPECIES_NINJASK":302,"SPECIES_NOCTOWL":164,"SPECIES_NONE":0,"SPECIES_NOSEPASS":320,"SPECIES_NUMEL":339,"SPECIES_NUZLEAF":299,"SPECIES_OCTILLERY":224,"SPECIES_ODDISH":43,"SPECIES_OLD_UNOWN_B":252,"SPECIES_OLD_UNOWN_C":253,"SPECIES_OLD_UNOWN_D":254,"SPECIES_OLD_UNOWN_E":255,"SPECIES_OLD_UNOWN_F":256,"SPECIES_OLD_UNOWN_G":257,"SPECIES_OLD_UNOWN_H":258,"SPECIES_OLD_UNOWN_I":259,"SPECIES_OLD_UNOWN_J":260,"SPECIES_OLD_UNOWN_K":261,"SPECIES_OLD_UNOWN_L":262,"SPECIES_OLD_UNOWN_M":263,"SPECIES_OLD_UNOWN_N":264,"SPECIES_OLD_UNOWN_O":265,"SPECIES_OLD_UNOWN_P":266,"SPECIES_OLD_UNOWN_Q":267,"SPECIES_OLD_UNOWN_R":268,"SPECIES_OLD_UNOWN_S":269,"SPECIES_OLD_UNOWN_T":270,"SPECIES_OLD_UNOWN_U":271,"SPECIES_OLD_UNOWN_V":272,"SPECIES_OLD_UNOWN_W":273,"SPECIES_OLD_UNOWN_X":274,"SPECIES_OLD_UNOWN_Y":275,"SPECIES_OLD_UNOWN_Z":276,"SPECIES_OMANYTE":138,"SPECIES_OMASTAR":139,"SPECIES_ONIX":95,"SPECIES_PARAS":46,"SPECIES_PARASECT":47,"SPECIES_PELIPPER":310,"SPECIES_PERSIAN":53,"SPECIES_PHANPY":231,"SPECIES_PICHU":172,"SPECIES_PIDGEOT":18,"SPECIES_PIDGEOTTO":17,"SPECIES_PIDGEY":16,"SPECIES_PIKACHU":25,"SPECIES_PILOSWINE":221,"SPECIES_PINECO":204,"SPECIES_PINSIR":127,"SPECIES_PLUSLE":353,"SPECIES_POLITOED":186,"SPECIES_POLIWAG":60,"SPECIES_POLIWHIRL":61,"SPECIES_POLIWRATH":62,"SPECIES_PONYTA":77,"SPECIES_POOCHYENA":286,"SPECIES_PORYGON":137,"SPECIES_PORYGON2":233,"SPECIES_PRIMEAPE":57,"SPECIES_PSYDUCK":54,"SPECIES_PUPITAR":247,"SPECIES_QUAGSIRE":195,"SPECIES_QUILAVA":156,"SPECIES_QWILFISH":211,"SPECIES_RAICHU":26,"SPECIES_RAIKOU":243,"SPECIES_RALTS":392,"SPECIES_RAPIDASH":78,"SPECIES_RATICATE":20,"SPECIES_RATTATA":19,"SPECIES_RAYQUAZA":406,"SPECIES_REGICE":402,"SPECIES_REGIROCK":401,"SPECIES_REGISTEEL":403,"SPECIES_RELICANTH":381,"SPECIES_REMORAID":223,"SPECIES_RHYDON":112,"SPECIES_RHYHORN":111,"SPECIES_ROSELIA":363,"SPECIES_SABLEYE":322,"SPECIES_SALAMENCE":397,"SPECIES_SANDSHREW":27,"SPECIES_SANDSLASH":28,"SPECIES_SCEPTILE":279,"SPECIES_SCIZOR":212,"SPECIES_SCYTHER":123,"SPECIES_SEADRA":117,"SPECIES_SEAKING":119,"SPECIES_SEALEO":342,"SPECIES_SEEDOT":298,"SPECIES_SEEL":86,"SPECIES_SENTRET":161,"SPECIES_SEVIPER":379,"SPECIES_SHARPEDO":331,"SPECIES_SHEDINJA":303,"SPECIES_SHELGON":396,"SPECIES_SHELLDER":90,"SPECIES_SHIFTRY":300,"SPECIES_SHROOMISH":306,"SPECIES_SHUCKLE":213,"SPECIES_SHUPPET":377,"SPECIES_SILCOON":291,"SPECIES_SKARMORY":227,"SPECIES_SKIPLOOM":188,"SPECIES_SKITTY":315,"SPECIES_SLAKING":366,"SPECIES_SLAKOTH":364,"SPECIES_SLOWBRO":80,"SPECIES_SLOWKING":199,"SPECIES_SLOWPOKE":79,"SPECIES_SLUGMA":218,"SPECIES_SMEARGLE":235,"SPECIES_SMOOCHUM":238,"SPECIES_SNEASEL":215,"SPECIES_SNORLAX":143,"SPECIES_SNORUNT":346,"SPECIES_SNUBBULL":209,"SPECIES_SOLROCK":349,"SPECIES_SPEAROW":21,"SPECIES_SPHEAL":341,"SPECIES_SPINARAK":167,"SPECIES_SPINDA":308,"SPECIES_SPOINK":351,"SPECIES_SQUIRTLE":7,"SPECIES_STANTLER":234,"SPECIES_STARMIE":121,"SPECIES_STARYU":120,"SPECIES_STEELIX":208,"SPECIES_SUDOWOODO":185,"SPECIES_SUICUNE":245,"SPECIES_SUNFLORA":192,"SPECIES_SUNKERN":191,"SPECIES_SURSKIT":311,"SPECIES_SWABLU":358,"SPECIES_SWALOT":368,"SPECIES_SWAMPERT":285,"SPECIES_SWELLOW":305,"SPECIES_SWINUB":220,"SPECIES_TAILLOW":304,"SPECIES_TANGELA":114,"SPECIES_TAUROS":128,"SPECIES_TEDDIURSA":216,"SPECIES_TENTACOOL":72,"SPECIES_TENTACRUEL":73,"SPECIES_TOGEPI":175,"SPECIES_TOGETIC":176,"SPECIES_TORCHIC":280,"SPECIES_TORKOAL":321,"SPECIES_TOTODILE":158,"SPECIES_TRAPINCH":332,"SPECIES_TREECKO":277,"SPECIES_TROPIUS":369,"SPECIES_TYPHLOSION":157,"SPECIES_TYRANITAR":248,"SPECIES_TYROGUE":236,"SPECIES_UMBREON":197,"SPECIES_UNOWN":201,"SPECIES_UNOWN_B":413,"SPECIES_UNOWN_C":414,"SPECIES_UNOWN_D":415,"SPECIES_UNOWN_E":416,"SPECIES_UNOWN_EMARK":438,"SPECIES_UNOWN_F":417,"SPECIES_UNOWN_G":418,"SPECIES_UNOWN_H":419,"SPECIES_UNOWN_I":420,"SPECIES_UNOWN_J":421,"SPECIES_UNOWN_K":422,"SPECIES_UNOWN_L":423,"SPECIES_UNOWN_M":424,"SPECIES_UNOWN_N":425,"SPECIES_UNOWN_O":426,"SPECIES_UNOWN_P":427,"SPECIES_UNOWN_Q":428,"SPECIES_UNOWN_QMARK":439,"SPECIES_UNOWN_R":429,"SPECIES_UNOWN_S":430,"SPECIES_UNOWN_T":431,"SPECIES_UNOWN_U":432,"SPECIES_UNOWN_V":433,"SPECIES_UNOWN_W":434,"SPECIES_UNOWN_X":435,"SPECIES_UNOWN_Y":436,"SPECIES_UNOWN_Z":437,"SPECIES_URSARING":217,"SPECIES_VAPOREON":134,"SPECIES_VENOMOTH":49,"SPECIES_VENONAT":48,"SPECIES_VENUSAUR":3,"SPECIES_VIBRAVA":333,"SPECIES_VICTREEBEL":71,"SPECIES_VIGOROTH":365,"SPECIES_VILEPLUME":45,"SPECIES_VOLBEAT":386,"SPECIES_VOLTORB":100,"SPECIES_VULPIX":37,"SPECIES_WAILMER":313,"SPECIES_WAILORD":314,"SPECIES_WALREIN":343,"SPECIES_WARTORTLE":8,"SPECIES_WEEDLE":13,"SPECIES_WEEPINBELL":70,"SPECIES_WEEZING":110,"SPECIES_WHISCASH":324,"SPECIES_WHISMUR":370,"SPECIES_WIGGLYTUFF":40,"SPECIES_WINGULL":309,"SPECIES_WOBBUFFET":202,"SPECIES_WOOPER":194,"SPECIES_WURMPLE":290,"SPECIES_WYNAUT":360,"SPECIES_XATU":178,"SPECIES_YANMA":193,"SPECIES_ZANGOOSE":380,"SPECIES_ZAPDOS":145,"SPECIES_ZIGZAGOON":288,"SPECIES_ZUBAT":41,"SUPER_ROD":2,"SYSTEM_FLAGS":2144,"TEMP_FLAGS_END":31,"TEMP_FLAGS_START":0,"TRAINERS_COUNT":855,"TRAINER_AARON":397,"TRAINER_ABIGAIL_1":358,"TRAINER_ABIGAIL_2":360,"TRAINER_ABIGAIL_3":361,"TRAINER_ABIGAIL_4":362,"TRAINER_ABIGAIL_5":363,"TRAINER_AIDAN":674,"TRAINER_AISHA":757,"TRAINER_ALAN":630,"TRAINER_ALBERT":80,"TRAINER_ALBERTO":12,"TRAINER_ALEX":413,"TRAINER_ALEXA":670,"TRAINER_ALEXIA":90,"TRAINER_ALEXIS":248,"TRAINER_ALICE":448,"TRAINER_ALIX":750,"TRAINER_ALLEN":333,"TRAINER_ALLISON":387,"TRAINER_ALVARO":849,"TRAINER_ALYSSA":701,"TRAINER_AMY_AND_LIV_1":481,"TRAINER_AMY_AND_LIV_2":482,"TRAINER_AMY_AND_LIV_3":485,"TRAINER_AMY_AND_LIV_4":487,"TRAINER_AMY_AND_LIV_5":488,"TRAINER_AMY_AND_LIV_6":489,"TRAINER_ANABEL":805,"TRAINER_ANDREA":613,"TRAINER_ANDRES_1":737,"TRAINER_ANDRES_2":812,"TRAINER_ANDRES_3":813,"TRAINER_ANDRES_4":814,"TRAINER_ANDRES_5":815,"TRAINER_ANDREW":336,"TRAINER_ANGELICA":436,"TRAINER_ANGELINA":712,"TRAINER_ANGELO":802,"TRAINER_ANNA_AND_MEG_1":287,"TRAINER_ANNA_AND_MEG_2":288,"TRAINER_ANNA_AND_MEG_3":289,"TRAINER_ANNA_AND_MEG_4":290,"TRAINER_ANNA_AND_MEG_5":291,"TRAINER_ANNIKA":502,"TRAINER_ANTHONY":352,"TRAINER_ARCHIE":34,"TRAINER_ASHLEY":655,"TRAINER_ATHENA":577,"TRAINER_ATSUSHI":190,"TRAINER_AURON":506,"TRAINER_AUSTINA":58,"TRAINER_AUTUMN":217,"TRAINER_AXLE":203,"TRAINER_BARNY":343,"TRAINER_BARRY":163,"TRAINER_BEAU":212,"TRAINER_BECK":414,"TRAINER_BECKY":470,"TRAINER_BEN":323,"TRAINER_BENJAMIN_1":353,"TRAINER_BENJAMIN_2":354,"TRAINER_BENJAMIN_3":355,"TRAINER_BENJAMIN_4":356,"TRAINER_BENJAMIN_5":357,"TRAINER_BENNY":407,"TRAINER_BERKE":74,"TRAINER_BERNIE_1":206,"TRAINER_BERNIE_2":207,"TRAINER_BERNIE_3":208,"TRAINER_BERNIE_4":209,"TRAINER_BERNIE_5":210,"TRAINER_BETH":445,"TRAINER_BETHANY":301,"TRAINER_BEVERLY":441,"TRAINER_BIANCA":706,"TRAINER_BILLY":319,"TRAINER_BLAKE":235,"TRAINER_BRANDEN":745,"TRAINER_BRANDI":756,"TRAINER_BRANDON":811,"TRAINER_BRAWLY_1":266,"TRAINER_BRAWLY_2":774,"TRAINER_BRAWLY_3":775,"TRAINER_BRAWLY_4":776,"TRAINER_BRAWLY_5":777,"TRAINER_BRAXTON":75,"TRAINER_BRENDA":454,"TRAINER_BRENDAN_LILYCOVE_MUDKIP":661,"TRAINER_BRENDAN_LILYCOVE_TORCHIC":663,"TRAINER_BRENDAN_LILYCOVE_TREECKO":662,"TRAINER_BRENDAN_PLACEHOLDER":853,"TRAINER_BRENDAN_ROUTE_103_MUDKIP":520,"TRAINER_BRENDAN_ROUTE_103_TORCHIC":526,"TRAINER_BRENDAN_ROUTE_103_TREECKO":523,"TRAINER_BRENDAN_ROUTE_110_MUDKIP":521,"TRAINER_BRENDAN_ROUTE_110_TORCHIC":527,"TRAINER_BRENDAN_ROUTE_110_TREECKO":524,"TRAINER_BRENDAN_ROUTE_119_MUDKIP":522,"TRAINER_BRENDAN_ROUTE_119_TORCHIC":528,"TRAINER_BRENDAN_ROUTE_119_TREECKO":525,"TRAINER_BRENDAN_RUSTBORO_MUDKIP":593,"TRAINER_BRENDAN_RUSTBORO_TORCHIC":599,"TRAINER_BRENDAN_RUSTBORO_TREECKO":592,"TRAINER_BRENDEN":572,"TRAINER_BRENT":223,"TRAINER_BRIANNA":118,"TRAINER_BRICE":626,"TRAINER_BRIDGET":129,"TRAINER_BROOKE_1":94,"TRAINER_BROOKE_2":101,"TRAINER_BROOKE_3":102,"TRAINER_BROOKE_4":103,"TRAINER_BROOKE_5":104,"TRAINER_BRYAN":744,"TRAINER_BRYANT":746,"TRAINER_CALE":764,"TRAINER_CALLIE":763,"TRAINER_CALVIN_1":318,"TRAINER_CALVIN_2":328,"TRAINER_CALVIN_3":329,"TRAINER_CALVIN_4":330,"TRAINER_CALVIN_5":331,"TRAINER_CAMDEN":374,"TRAINER_CAMERON_1":238,"TRAINER_CAMERON_2":239,"TRAINER_CAMERON_3":240,"TRAINER_CAMERON_4":241,"TRAINER_CAMERON_5":242,"TRAINER_CAMRON":739,"TRAINER_CARLEE":464,"TRAINER_CAROL":471,"TRAINER_CAROLINA":741,"TRAINER_CAROLINE":99,"TRAINER_CARTER":345,"TRAINER_CATHERINE_1":559,"TRAINER_CATHERINE_2":562,"TRAINER_CATHERINE_3":563,"TRAINER_CATHERINE_4":564,"TRAINER_CATHERINE_5":565,"TRAINER_CEDRIC":475,"TRAINER_CELIA":743,"TRAINER_CELINA":705,"TRAINER_CHAD":174,"TRAINER_CHANDLER":698,"TRAINER_CHARLIE":66,"TRAINER_CHARLOTTE":714,"TRAINER_CHASE":378,"TRAINER_CHESTER":408,"TRAINER_CHIP":45,"TRAINER_CHRIS":693,"TRAINER_CINDY_1":114,"TRAINER_CINDY_2":117,"TRAINER_CINDY_3":120,"TRAINER_CINDY_4":121,"TRAINER_CINDY_5":122,"TRAINER_CINDY_6":123,"TRAINER_CLARENCE":580,"TRAINER_CLARISSA":435,"TRAINER_CLARK":631,"TRAINER_CLAUDE":338,"TRAINER_CLIFFORD":584,"TRAINER_COBY":709,"TRAINER_COLE":201,"TRAINER_COLIN":405,"TRAINER_COLTON":294,"TRAINER_CONNIE":128,"TRAINER_CONOR":511,"TRAINER_CORA":428,"TRAINER_CORY_1":740,"TRAINER_CORY_2":816,"TRAINER_CORY_3":817,"TRAINER_CORY_4":818,"TRAINER_CORY_5":819,"TRAINER_CRISSY":614,"TRAINER_CRISTIAN":574,"TRAINER_CRISTIN_1":767,"TRAINER_CRISTIN_2":828,"TRAINER_CRISTIN_3":829,"TRAINER_CRISTIN_4":830,"TRAINER_CRISTIN_5":831,"TRAINER_CYNDY_1":427,"TRAINER_CYNDY_2":430,"TRAINER_CYNDY_3":431,"TRAINER_CYNDY_4":432,"TRAINER_CYNDY_5":433,"TRAINER_DAISUKE":189,"TRAINER_DAISY":36,"TRAINER_DALE":341,"TRAINER_DALTON_1":196,"TRAINER_DALTON_2":197,"TRAINER_DALTON_3":198,"TRAINER_DALTON_4":199,"TRAINER_DALTON_5":200,"TRAINER_DANA":458,"TRAINER_DANIELLE":650,"TRAINER_DAPHNE":115,"TRAINER_DARCY":733,"TRAINER_DARIAN":696,"TRAINER_DARIUS":803,"TRAINER_DARRIN":154,"TRAINER_DAVID":158,"TRAINER_DAVIS":539,"TRAINER_DAWSON":694,"TRAINER_DAYTON":760,"TRAINER_DEAN":164,"TRAINER_DEANDRE":715,"TRAINER_DEBRA":460,"TRAINER_DECLAN":15,"TRAINER_DEMETRIUS":375,"TRAINER_DENISE":444,"TRAINER_DEREK":227,"TRAINER_DEVAN":753,"TRAINER_DEZ_AND_LUKE":640,"TRAINER_DIANA_1":474,"TRAINER_DIANA_2":477,"TRAINER_DIANA_3":478,"TRAINER_DIANA_4":479,"TRAINER_DIANA_5":480,"TRAINER_DIANNE":417,"TRAINER_DILLON":327,"TRAINER_DOMINIK":152,"TRAINER_DONALD":224,"TRAINER_DONNY":384,"TRAINER_DOUG":618,"TRAINER_DOUGLAS":153,"TRAINER_DRAKE":264,"TRAINER_DREW":211,"TRAINER_DUDLEY":173,"TRAINER_DUNCAN":496,"TRAINER_DUSTY_1":44,"TRAINER_DUSTY_2":47,"TRAINER_DUSTY_3":48,"TRAINER_DUSTY_4":49,"TRAINER_DUSTY_5":50,"TRAINER_DWAYNE":493,"TRAINER_DYLAN_1":364,"TRAINER_DYLAN_2":365,"TRAINER_DYLAN_3":366,"TRAINER_DYLAN_4":367,"TRAINER_DYLAN_5":368,"TRAINER_ED":13,"TRAINER_EDDIE":332,"TRAINER_EDGAR":79,"TRAINER_EDMOND":491,"TRAINER_EDWARD":232,"TRAINER_EDWARDO":404,"TRAINER_EDWIN_1":512,"TRAINER_EDWIN_2":515,"TRAINER_EDWIN_3":516,"TRAINER_EDWIN_4":517,"TRAINER_EDWIN_5":518,"TRAINER_ELI":501,"TRAINER_ELIJAH":742,"TRAINER_ELLIOT_1":339,"TRAINER_ELLIOT_2":346,"TRAINER_ELLIOT_3":347,"TRAINER_ELLIOT_4":348,"TRAINER_ELLIOT_5":349,"TRAINER_ERIC":632,"TRAINER_ERNEST_1":492,"TRAINER_ERNEST_2":497,"TRAINER_ERNEST_3":498,"TRAINER_ERNEST_4":499,"TRAINER_ERNEST_5":500,"TRAINER_ETHAN_1":216,"TRAINER_ETHAN_2":219,"TRAINER_ETHAN_3":220,"TRAINER_ETHAN_4":221,"TRAINER_ETHAN_5":222,"TRAINER_EVERETT":850,"TRAINER_FABIAN":759,"TRAINER_FELIX":38,"TRAINER_FERNANDO_1":195,"TRAINER_FERNANDO_2":832,"TRAINER_FERNANDO_3":833,"TRAINER_FERNANDO_4":834,"TRAINER_FERNANDO_5":835,"TRAINER_FLAGS_END":2143,"TRAINER_FLAGS_START":1280,"TRAINER_FLANNERY_1":268,"TRAINER_FLANNERY_2":782,"TRAINER_FLANNERY_3":783,"TRAINER_FLANNERY_4":784,"TRAINER_FLANNERY_5":785,"TRAINER_FLINT":654,"TRAINER_FOSTER":46,"TRAINER_FRANKLIN":170,"TRAINER_FREDRICK":29,"TRAINER_GABBY_AND_TY_1":51,"TRAINER_GABBY_AND_TY_2":52,"TRAINER_GABBY_AND_TY_3":53,"TRAINER_GABBY_AND_TY_4":54,"TRAINER_GABBY_AND_TY_5":55,"TRAINER_GABBY_AND_TY_6":56,"TRAINER_GABRIELLE_1":9,"TRAINER_GABRIELLE_2":840,"TRAINER_GABRIELLE_3":841,"TRAINER_GABRIELLE_4":842,"TRAINER_GABRIELLE_5":843,"TRAINER_GARRET":138,"TRAINER_GARRISON":547,"TRAINER_GEORGE":73,"TRAINER_GEORGIA":281,"TRAINER_GERALD":648,"TRAINER_GILBERT":169,"TRAINER_GINA_AND_MIA_1":483,"TRAINER_GINA_AND_MIA_2":486,"TRAINER_GLACIA":263,"TRAINER_GRACE":450,"TRAINER_GREG":619,"TRAINER_GRETA":808,"TRAINER_GRUNT_AQUA_HIDEOUT_1":2,"TRAINER_GRUNT_AQUA_HIDEOUT_2":3,"TRAINER_GRUNT_AQUA_HIDEOUT_3":4,"TRAINER_GRUNT_AQUA_HIDEOUT_4":5,"TRAINER_GRUNT_AQUA_HIDEOUT_5":27,"TRAINER_GRUNT_AQUA_HIDEOUT_6":28,"TRAINER_GRUNT_AQUA_HIDEOUT_7":192,"TRAINER_GRUNT_AQUA_HIDEOUT_8":193,"TRAINER_GRUNT_JAGGED_PASS":570,"TRAINER_GRUNT_MAGMA_HIDEOUT_1":716,"TRAINER_GRUNT_MAGMA_HIDEOUT_10":725,"TRAINER_GRUNT_MAGMA_HIDEOUT_11":726,"TRAINER_GRUNT_MAGMA_HIDEOUT_12":727,"TRAINER_GRUNT_MAGMA_HIDEOUT_13":728,"TRAINER_GRUNT_MAGMA_HIDEOUT_14":729,"TRAINER_GRUNT_MAGMA_HIDEOUT_15":730,"TRAINER_GRUNT_MAGMA_HIDEOUT_16":731,"TRAINER_GRUNT_MAGMA_HIDEOUT_2":717,"TRAINER_GRUNT_MAGMA_HIDEOUT_3":718,"TRAINER_GRUNT_MAGMA_HIDEOUT_4":719,"TRAINER_GRUNT_MAGMA_HIDEOUT_5":720,"TRAINER_GRUNT_MAGMA_HIDEOUT_6":721,"TRAINER_GRUNT_MAGMA_HIDEOUT_7":722,"TRAINER_GRUNT_MAGMA_HIDEOUT_8":723,"TRAINER_GRUNT_MAGMA_HIDEOUT_9":724,"TRAINER_GRUNT_MT_CHIMNEY_1":146,"TRAINER_GRUNT_MT_CHIMNEY_2":579,"TRAINER_GRUNT_MT_PYRE_1":23,"TRAINER_GRUNT_MT_PYRE_2":24,"TRAINER_GRUNT_MT_PYRE_3":25,"TRAINER_GRUNT_MT_PYRE_4":569,"TRAINER_GRUNT_MUSEUM_1":20,"TRAINER_GRUNT_MUSEUM_2":21,"TRAINER_GRUNT_PETALBURG_WOODS":10,"TRAINER_GRUNT_RUSTURF_TUNNEL":16,"TRAINER_GRUNT_SEAFLOOR_CAVERN_1":6,"TRAINER_GRUNT_SEAFLOOR_CAVERN_2":7,"TRAINER_GRUNT_SEAFLOOR_CAVERN_3":8,"TRAINER_GRUNT_SEAFLOOR_CAVERN_4":14,"TRAINER_GRUNT_SEAFLOOR_CAVERN_5":567,"TRAINER_GRUNT_SPACE_CENTER_1":22,"TRAINER_GRUNT_SPACE_CENTER_2":116,"TRAINER_GRUNT_SPACE_CENTER_3":586,"TRAINER_GRUNT_SPACE_CENTER_4":587,"TRAINER_GRUNT_SPACE_CENTER_5":588,"TRAINER_GRUNT_SPACE_CENTER_6":589,"TRAINER_GRUNT_SPACE_CENTER_7":590,"TRAINER_GRUNT_UNUSED":568,"TRAINER_GRUNT_WEATHER_INST_1":17,"TRAINER_GRUNT_WEATHER_INST_2":18,"TRAINER_GRUNT_WEATHER_INST_3":19,"TRAINER_GRUNT_WEATHER_INST_4":26,"TRAINER_GRUNT_WEATHER_INST_5":596,"TRAINER_GWEN":59,"TRAINER_HAILEY":697,"TRAINER_HALEY_1":604,"TRAINER_HALEY_2":607,"TRAINER_HALEY_3":608,"TRAINER_HALEY_4":609,"TRAINER_HALEY_5":610,"TRAINER_HALLE":546,"TRAINER_HANNAH":244,"TRAINER_HARRISON":578,"TRAINER_HAYDEN":707,"TRAINER_HECTOR":513,"TRAINER_HEIDI":469,"TRAINER_HELENE":751,"TRAINER_HENRY":668,"TRAINER_HERMAN":167,"TRAINER_HIDEO":651,"TRAINER_HITOSHI":180,"TRAINER_HOPE":96,"TRAINER_HUDSON":510,"TRAINER_HUEY":490,"TRAINER_HUGH":399,"TRAINER_HUMBERTO":402,"TRAINER_IMANI":442,"TRAINER_IRENE":476,"TRAINER_ISAAC_1":538,"TRAINER_ISAAC_2":541,"TRAINER_ISAAC_3":542,"TRAINER_ISAAC_4":543,"TRAINER_ISAAC_5":544,"TRAINER_ISABELLA":595,"TRAINER_ISABELLE":736,"TRAINER_ISABEL_1":302,"TRAINER_ISABEL_2":303,"TRAINER_ISABEL_3":304,"TRAINER_ISABEL_4":305,"TRAINER_ISABEL_5":306,"TRAINER_ISAIAH_1":376,"TRAINER_ISAIAH_2":379,"TRAINER_ISAIAH_3":380,"TRAINER_ISAIAH_4":381,"TRAINER_ISAIAH_5":382,"TRAINER_ISOBEL":383,"TRAINER_IVAN":337,"TRAINER_JACE":204,"TRAINER_JACK":172,"TRAINER_JACKI_1":249,"TRAINER_JACKI_2":250,"TRAINER_JACKI_3":251,"TRAINER_JACKI_4":252,"TRAINER_JACKI_5":253,"TRAINER_JACKSON_1":552,"TRAINER_JACKSON_2":555,"TRAINER_JACKSON_3":556,"TRAINER_JACKSON_4":557,"TRAINER_JACKSON_5":558,"TRAINER_JACLYN":243,"TRAINER_JACOB":351,"TRAINER_JAIDEN":749,"TRAINER_JAMES_1":621,"TRAINER_JAMES_2":622,"TRAINER_JAMES_3":623,"TRAINER_JAMES_4":624,"TRAINER_JAMES_5":625,"TRAINER_JANI":418,"TRAINER_JANICE":605,"TRAINER_JARED":401,"TRAINER_JASMINE":359,"TRAINER_JAYLEN":326,"TRAINER_JAZMYN":503,"TRAINER_JEFF":202,"TRAINER_JEFFREY_1":226,"TRAINER_JEFFREY_2":228,"TRAINER_JEFFREY_3":229,"TRAINER_JEFFREY_4":230,"TRAINER_JEFFREY_5":231,"TRAINER_JENNA":560,"TRAINER_JENNIFER":95,"TRAINER_JENNY_1":449,"TRAINER_JENNY_2":465,"TRAINER_JENNY_3":466,"TRAINER_JENNY_4":467,"TRAINER_JENNY_5":468,"TRAINER_JEROME":156,"TRAINER_JERRY_1":273,"TRAINER_JERRY_2":276,"TRAINER_JERRY_3":277,"TRAINER_JERRY_4":278,"TRAINER_JERRY_5":279,"TRAINER_JESSICA_1":127,"TRAINER_JESSICA_2":132,"TRAINER_JESSICA_3":133,"TRAINER_JESSICA_4":134,"TRAINER_JESSICA_5":135,"TRAINER_JOCELYN":425,"TRAINER_JODY":91,"TRAINER_JOEY":322,"TRAINER_JOHANNA":647,"TRAINER_JOHNSON":754,"TRAINER_JOHN_AND_JAY_1":681,"TRAINER_JOHN_AND_JAY_2":682,"TRAINER_JOHN_AND_JAY_3":683,"TRAINER_JOHN_AND_JAY_4":684,"TRAINER_JOHN_AND_JAY_5":685,"TRAINER_JONAH":667,"TRAINER_JONAS":504,"TRAINER_JONATHAN":598,"TRAINER_JOSE":617,"TRAINER_JOSEPH":700,"TRAINER_JOSH":320,"TRAINER_JOSHUA":237,"TRAINER_JOSUE":738,"TRAINER_JUAN_1":272,"TRAINER_JUAN_2":798,"TRAINER_JUAN_3":799,"TRAINER_JUAN_4":800,"TRAINER_JUAN_5":801,"TRAINER_JULIE":100,"TRAINER_JULIO":566,"TRAINER_JUSTIN":215,"TRAINER_KAI":713,"TRAINER_KALEB":699,"TRAINER_KARA":457,"TRAINER_KAREN_1":280,"TRAINER_KAREN_2":282,"TRAINER_KAREN_3":283,"TRAINER_KAREN_4":284,"TRAINER_KAREN_5":285,"TRAINER_KATELYNN":325,"TRAINER_KATELYN_1":386,"TRAINER_KATELYN_2":388,"TRAINER_KATELYN_3":389,"TRAINER_KATELYN_4":390,"TRAINER_KATELYN_5":391,"TRAINER_KATE_AND_JOY":286,"TRAINER_KATHLEEN":583,"TRAINER_KATIE":455,"TRAINER_KAYLA":247,"TRAINER_KAYLEE":462,"TRAINER_KAYLEY":505,"TRAINER_KEEGAN":205,"TRAINER_KEIGO":652,"TRAINER_KEIRA":93,"TRAINER_KELVIN":507,"TRAINER_KENT":620,"TRAINER_KEVIN":171,"TRAINER_KIM_AND_IRIS":678,"TRAINER_KINDRA":106,"TRAINER_KIRA_AND_DAN_1":642,"TRAINER_KIRA_AND_DAN_2":643,"TRAINER_KIRA_AND_DAN_3":644,"TRAINER_KIRA_AND_DAN_4":645,"TRAINER_KIRA_AND_DAN_5":646,"TRAINER_KIRK":191,"TRAINER_KIYO":181,"TRAINER_KOICHI":182,"TRAINER_KOJI_1":672,"TRAINER_KOJI_2":824,"TRAINER_KOJI_3":825,"TRAINER_KOJI_4":826,"TRAINER_KOJI_5":827,"TRAINER_KYLA":443,"TRAINER_KYRA":748,"TRAINER_LAO_1":419,"TRAINER_LAO_2":421,"TRAINER_LAO_3":422,"TRAINER_LAO_4":423,"TRAINER_LAO_5":424,"TRAINER_LARRY":213,"TRAINER_LAURA":426,"TRAINER_LAUREL":463,"TRAINER_LAWRENCE":710,"TRAINER_LEAF":852,"TRAINER_LEAH":35,"TRAINER_LEA_AND_JED":641,"TRAINER_LENNY":628,"TRAINER_LEONARD":495,"TRAINER_LEONARDO":576,"TRAINER_LEONEL":762,"TRAINER_LEROY":77,"TRAINER_LILA_AND_ROY_1":687,"TRAINER_LILA_AND_ROY_2":688,"TRAINER_LILA_AND_ROY_3":689,"TRAINER_LILA_AND_ROY_4":690,"TRAINER_LILA_AND_ROY_5":691,"TRAINER_LILITH":573,"TRAINER_LINDA":461,"TRAINER_LISA_AND_RAY":692,"TRAINER_LOLA_1":57,"TRAINER_LOLA_2":60,"TRAINER_LOLA_3":61,"TRAINER_LOLA_4":62,"TRAINER_LOLA_5":63,"TRAINER_LORENZO":553,"TRAINER_LUCAS_1":629,"TRAINER_LUCAS_2":633,"TRAINER_LUCY":810,"TRAINER_LUIS":151,"TRAINER_LUNG":420,"TRAINER_LYDIA_1":545,"TRAINER_LYDIA_2":548,"TRAINER_LYDIA_3":549,"TRAINER_LYDIA_4":550,"TRAINER_LYDIA_5":551,"TRAINER_LYLE":616,"TRAINER_MACEY":591,"TRAINER_MADELINE_1":434,"TRAINER_MADELINE_2":437,"TRAINER_MADELINE_3":438,"TRAINER_MADELINE_4":439,"TRAINER_MADELINE_5":440,"TRAINER_MAKAYLA":758,"TRAINER_MARC":571,"TRAINER_MARCEL":11,"TRAINER_MARCOS":702,"TRAINER_MARIA_1":369,"TRAINER_MARIA_2":370,"TRAINER_MARIA_3":371,"TRAINER_MARIA_4":372,"TRAINER_MARIA_5":373,"TRAINER_MARIELA":848,"TRAINER_MARK":145,"TRAINER_MARLENE":752,"TRAINER_MARLEY":508,"TRAINER_MARTHA":473,"TRAINER_MARY":89,"TRAINER_MATT":30,"TRAINER_MATTHEW":157,"TRAINER_MAURA":246,"TRAINER_MAXIE_MAGMA_HIDEOUT":601,"TRAINER_MAXIE_MOSSDEEP":734,"TRAINER_MAXIE_MT_CHIMNEY":602,"TRAINER_MAY_LILYCOVE_MUDKIP":664,"TRAINER_MAY_LILYCOVE_TORCHIC":666,"TRAINER_MAY_LILYCOVE_TREECKO":665,"TRAINER_MAY_PLACEHOLDER":854,"TRAINER_MAY_ROUTE_103_MUDKIP":529,"TRAINER_MAY_ROUTE_103_TORCHIC":535,"TRAINER_MAY_ROUTE_103_TREECKO":532,"TRAINER_MAY_ROUTE_110_MUDKIP":530,"TRAINER_MAY_ROUTE_110_TORCHIC":536,"TRAINER_MAY_ROUTE_110_TREECKO":533,"TRAINER_MAY_ROUTE_119_MUDKIP":531,"TRAINER_MAY_ROUTE_119_TORCHIC":537,"TRAINER_MAY_ROUTE_119_TREECKO":534,"TRAINER_MAY_RUSTBORO_MUDKIP":600,"TRAINER_MAY_RUSTBORO_TORCHIC":769,"TRAINER_MAY_RUSTBORO_TREECKO":768,"TRAINER_MELINA":755,"TRAINER_MELISSA":124,"TRAINER_MEL_AND_PAUL":680,"TRAINER_MICAH":255,"TRAINER_MICHELLE":98,"TRAINER_MIGUEL_1":293,"TRAINER_MIGUEL_2":295,"TRAINER_MIGUEL_3":296,"TRAINER_MIGUEL_4":297,"TRAINER_MIGUEL_5":298,"TRAINER_MIKE_1":634,"TRAINER_MIKE_2":635,"TRAINER_MISSY":447,"TRAINER_MITCHELL":540,"TRAINER_MIU_AND_YUKI":484,"TRAINER_MOLLIE":137,"TRAINER_MYLES":765,"TRAINER_NANCY":472,"TRAINER_NAOMI":119,"TRAINER_NATE":582,"TRAINER_NED":340,"TRAINER_NICHOLAS":585,"TRAINER_NICOLAS_1":392,"TRAINER_NICOLAS_2":393,"TRAINER_NICOLAS_3":394,"TRAINER_NICOLAS_4":395,"TRAINER_NICOLAS_5":396,"TRAINER_NIKKI":453,"TRAINER_NOB_1":183,"TRAINER_NOB_2":184,"TRAINER_NOB_3":185,"TRAINER_NOB_4":186,"TRAINER_NOB_5":187,"TRAINER_NOLAN":342,"TRAINER_NOLAND":809,"TRAINER_NOLEN":161,"TRAINER_NONE":0,"TRAINER_NORMAN_1":269,"TRAINER_NORMAN_2":786,"TRAINER_NORMAN_3":787,"TRAINER_NORMAN_4":788,"TRAINER_NORMAN_5":789,"TRAINER_OLIVIA":130,"TRAINER_OWEN":83,"TRAINER_PABLO_1":377,"TRAINER_PABLO_2":820,"TRAINER_PABLO_3":821,"TRAINER_PABLO_4":822,"TRAINER_PABLO_5":823,"TRAINER_PARKER":72,"TRAINER_PAT":766,"TRAINER_PATRICIA":105,"TRAINER_PAUL":275,"TRAINER_PAULA":429,"TRAINER_PAXTON":594,"TRAINER_PERRY":398,"TRAINER_PETE":735,"TRAINER_PHIL":400,"TRAINER_PHILLIP":494,"TRAINER_PHOEBE":262,"TRAINER_PRESLEY":403,"TRAINER_PRESTON":233,"TRAINER_QUINCY":324,"TRAINER_RACHEL":761,"TRAINER_RANDALL":71,"TRAINER_RED":851,"TRAINER_REED":675,"TRAINER_RELI_AND_IAN":686,"TRAINER_REYNA":509,"TRAINER_RHETT":703,"TRAINER_RICHARD":166,"TRAINER_RICK":615,"TRAINER_RICKY_1":64,"TRAINER_RICKY_2":67,"TRAINER_RICKY_3":68,"TRAINER_RICKY_4":69,"TRAINER_RICKY_5":70,"TRAINER_RILEY":653,"TRAINER_ROBERT_1":406,"TRAINER_ROBERT_2":409,"TRAINER_ROBERT_3":410,"TRAINER_ROBERT_4":411,"TRAINER_ROBERT_5":412,"TRAINER_ROBIN":612,"TRAINER_RODNEY":165,"TRAINER_ROGER":669,"TRAINER_ROLAND":160,"TRAINER_RONALD":350,"TRAINER_ROSE_1":37,"TRAINER_ROSE_2":40,"TRAINER_ROSE_3":41,"TRAINER_ROSE_4":42,"TRAINER_ROSE_5":43,"TRAINER_ROXANNE_1":265,"TRAINER_ROXANNE_2":770,"TRAINER_ROXANNE_3":771,"TRAINER_ROXANNE_4":772,"TRAINER_ROXANNE_5":773,"TRAINER_RUBEN":671,"TRAINER_SALLY":611,"TRAINER_SAMANTHA":245,"TRAINER_SAMUEL":81,"TRAINER_SANTIAGO":168,"TRAINER_SARAH":695,"TRAINER_SAWYER_1":1,"TRAINER_SAWYER_2":836,"TRAINER_SAWYER_3":837,"TRAINER_SAWYER_4":838,"TRAINER_SAWYER_5":839,"TRAINER_SEBASTIAN":554,"TRAINER_SHANE":214,"TRAINER_SHANNON":97,"TRAINER_SHARON":452,"TRAINER_SHAWN":194,"TRAINER_SHAYLA":747,"TRAINER_SHEILA":125,"TRAINER_SHELBY_1":313,"TRAINER_SHELBY_2":314,"TRAINER_SHELBY_3":315,"TRAINER_SHELBY_4":316,"TRAINER_SHELBY_5":317,"TRAINER_SHELLY_SEAFLOOR_CAVERN":33,"TRAINER_SHELLY_WEATHER_INSTITUTE":32,"TRAINER_SHIRLEY":126,"TRAINER_SIDNEY":261,"TRAINER_SIENNA":459,"TRAINER_SIMON":65,"TRAINER_SOPHIA":561,"TRAINER_SOPHIE":708,"TRAINER_SPENCER":159,"TRAINER_SPENSER":807,"TRAINER_STAN":162,"TRAINER_STEVEN":804,"TRAINER_STEVE_1":143,"TRAINER_STEVE_2":147,"TRAINER_STEVE_3":148,"TRAINER_STEVE_4":149,"TRAINER_STEVE_5":150,"TRAINER_SUSIE":456,"TRAINER_SYLVIA":575,"TRAINER_TABITHA_MAGMA_HIDEOUT":732,"TRAINER_TABITHA_MOSSDEEP":514,"TRAINER_TABITHA_MT_CHIMNEY":597,"TRAINER_TAKAO":179,"TRAINER_TAKASHI":416,"TRAINER_TALIA":385,"TRAINER_TAMMY":107,"TRAINER_TANYA":451,"TRAINER_TARA":446,"TRAINER_TASHA":109,"TRAINER_TATE_AND_LIZA_1":271,"TRAINER_TATE_AND_LIZA_2":794,"TRAINER_TATE_AND_LIZA_3":795,"TRAINER_TATE_AND_LIZA_4":796,"TRAINER_TATE_AND_LIZA_5":797,"TRAINER_TAYLOR":225,"TRAINER_TED":274,"TRAINER_TERRY":581,"TRAINER_THALIA_1":144,"TRAINER_THALIA_2":844,"TRAINER_THALIA_3":845,"TRAINER_THALIA_4":846,"TRAINER_THALIA_5":847,"TRAINER_THOMAS":256,"TRAINER_TIANA":603,"TRAINER_TIFFANY":131,"TRAINER_TIMMY":334,"TRAINER_TIMOTHY_1":307,"TRAINER_TIMOTHY_2":308,"TRAINER_TIMOTHY_3":309,"TRAINER_TIMOTHY_4":310,"TRAINER_TIMOTHY_5":311,"TRAINER_TISHA":676,"TRAINER_TOMMY":321,"TRAINER_TONY_1":155,"TRAINER_TONY_2":175,"TRAINER_TONY_3":176,"TRAINER_TONY_4":177,"TRAINER_TONY_5":178,"TRAINER_TORI_AND_TIA":677,"TRAINER_TRAVIS":218,"TRAINER_TRENT_1":627,"TRAINER_TRENT_2":636,"TRAINER_TRENT_3":637,"TRAINER_TRENT_4":638,"TRAINER_TRENT_5":639,"TRAINER_TUCKER":806,"TRAINER_TYRA_AND_IVY":679,"TRAINER_TYRON":704,"TRAINER_VALERIE_1":108,"TRAINER_VALERIE_2":110,"TRAINER_VALERIE_3":111,"TRAINER_VALERIE_4":112,"TRAINER_VALERIE_5":113,"TRAINER_VANESSA":300,"TRAINER_VICKY":312,"TRAINER_VICTOR":292,"TRAINER_VICTORIA":299,"TRAINER_VINCENT":76,"TRAINER_VIOLET":39,"TRAINER_VIRGIL":234,"TRAINER_VITO":82,"TRAINER_VIVI":606,"TRAINER_VIVIAN":649,"TRAINER_WADE":344,"TRAINER_WALLACE":335,"TRAINER_WALLY_MAUVILLE":656,"TRAINER_WALLY_VR_1":519,"TRAINER_WALLY_VR_2":657,"TRAINER_WALLY_VR_3":658,"TRAINER_WALLY_VR_4":659,"TRAINER_WALLY_VR_5":660,"TRAINER_WALTER_1":254,"TRAINER_WALTER_2":257,"TRAINER_WALTER_3":258,"TRAINER_WALTER_4":259,"TRAINER_WALTER_5":260,"TRAINER_WARREN":88,"TRAINER_WATTSON_1":267,"TRAINER_WATTSON_2":778,"TRAINER_WATTSON_3":779,"TRAINER_WATTSON_4":780,"TRAINER_WATTSON_5":781,"TRAINER_WAYNE":673,"TRAINER_WENDY":92,"TRAINER_WILLIAM":236,"TRAINER_WILTON_1":78,"TRAINER_WILTON_2":84,"TRAINER_WILTON_3":85,"TRAINER_WILTON_4":86,"TRAINER_WILTON_5":87,"TRAINER_WINONA_1":270,"TRAINER_WINONA_2":790,"TRAINER_WINONA_3":791,"TRAINER_WINONA_4":792,"TRAINER_WINONA_5":793,"TRAINER_WINSTON_1":136,"TRAINER_WINSTON_2":139,"TRAINER_WINSTON_3":140,"TRAINER_WINSTON_4":141,"TRAINER_WINSTON_5":142,"TRAINER_WYATT":711,"TRAINER_YASU":415,"TRAINER_YUJI":188,"TRAINER_ZANDER":31},"legendary_encounters":[{"address":2538600,"catch_flag":429,"defeat_flag":428,"level":30,"species":410},{"address":2354334,"catch_flag":480,"defeat_flag":447,"level":70,"species":405},{"address":2543160,"catch_flag":146,"defeat_flag":476,"level":70,"species":250},{"address":2354112,"catch_flag":479,"defeat_flag":446,"level":70,"species":404},{"address":2385623,"catch_flag":457,"defeat_flag":456,"level":50,"species":407},{"address":2385687,"catch_flag":482,"defeat_flag":481,"level":50,"species":408},{"address":2543443,"catch_flag":145,"defeat_flag":477,"level":70,"species":249},{"address":2538177,"catch_flag":458,"defeat_flag":455,"level":30,"species":151},{"address":2347488,"catch_flag":478,"defeat_flag":448,"level":70,"species":406},{"address":2345460,"catch_flag":427,"defeat_flag":444,"level":40,"species":402},{"address":2298183,"catch_flag":426,"defeat_flag":443,"level":40,"species":401},{"address":2345731,"catch_flag":483,"defeat_flag":445,"level":40,"species":403}],"locations":{"BADGE_1":{"address":2188036,"default_item":226,"flag":1182},"BADGE_2":{"address":2095131,"default_item":227,"flag":1183},"BADGE_3":{"address":2167252,"default_item":228,"flag":1184},"BADGE_4":{"address":2103246,"default_item":229,"flag":1185},"BADGE_5":{"address":2129781,"default_item":230,"flag":1186},"BADGE_6":{"address":2202122,"default_item":231,"flag":1187},"BADGE_7":{"address":2243964,"default_item":232,"flag":1188},"BADGE_8":{"address":2262314,"default_item":233,"flag":1189},"BERRY_TREE_01":{"address":5843562,"default_item":135,"flag":612},"BERRY_TREE_02":{"address":5843564,"default_item":139,"flag":613},"BERRY_TREE_03":{"address":5843566,"default_item":142,"flag":614},"BERRY_TREE_04":{"address":5843568,"default_item":139,"flag":615},"BERRY_TREE_05":{"address":5843570,"default_item":133,"flag":616},"BERRY_TREE_06":{"address":5843572,"default_item":138,"flag":617},"BERRY_TREE_07":{"address":5843574,"default_item":133,"flag":618},"BERRY_TREE_08":{"address":5843576,"default_item":133,"flag":619},"BERRY_TREE_09":{"address":5843578,"default_item":142,"flag":620},"BERRY_TREE_10":{"address":5843580,"default_item":138,"flag":621},"BERRY_TREE_11":{"address":5843582,"default_item":139,"flag":622},"BERRY_TREE_12":{"address":5843584,"default_item":142,"flag":623},"BERRY_TREE_13":{"address":5843586,"default_item":135,"flag":624},"BERRY_TREE_14":{"address":5843588,"default_item":155,"flag":625},"BERRY_TREE_15":{"address":5843590,"default_item":153,"flag":626},"BERRY_TREE_16":{"address":5843592,"default_item":150,"flag":627},"BERRY_TREE_17":{"address":5843594,"default_item":150,"flag":628},"BERRY_TREE_18":{"address":5843596,"default_item":150,"flag":629},"BERRY_TREE_19":{"address":5843598,"default_item":148,"flag":630},"BERRY_TREE_20":{"address":5843600,"default_item":148,"flag":631},"BERRY_TREE_21":{"address":5843602,"default_item":136,"flag":632},"BERRY_TREE_22":{"address":5843604,"default_item":135,"flag":633},"BERRY_TREE_23":{"address":5843606,"default_item":135,"flag":634},"BERRY_TREE_24":{"address":5843608,"default_item":136,"flag":635},"BERRY_TREE_25":{"address":5843610,"default_item":152,"flag":636},"BERRY_TREE_26":{"address":5843612,"default_item":134,"flag":637},"BERRY_TREE_27":{"address":5843614,"default_item":151,"flag":638},"BERRY_TREE_28":{"address":5843616,"default_item":151,"flag":639},"BERRY_TREE_29":{"address":5843618,"default_item":151,"flag":640},"BERRY_TREE_30":{"address":5843620,"default_item":153,"flag":641},"BERRY_TREE_31":{"address":5843622,"default_item":142,"flag":642},"BERRY_TREE_32":{"address":5843624,"default_item":142,"flag":643},"BERRY_TREE_33":{"address":5843626,"default_item":142,"flag":644},"BERRY_TREE_34":{"address":5843628,"default_item":153,"flag":645},"BERRY_TREE_35":{"address":5843630,"default_item":153,"flag":646},"BERRY_TREE_36":{"address":5843632,"default_item":153,"flag":647},"BERRY_TREE_37":{"address":5843634,"default_item":137,"flag":648},"BERRY_TREE_38":{"address":5843636,"default_item":137,"flag":649},"BERRY_TREE_39":{"address":5843638,"default_item":137,"flag":650},"BERRY_TREE_40":{"address":5843640,"default_item":135,"flag":651},"BERRY_TREE_41":{"address":5843642,"default_item":135,"flag":652},"BERRY_TREE_42":{"address":5843644,"default_item":135,"flag":653},"BERRY_TREE_43":{"address":5843646,"default_item":148,"flag":654},"BERRY_TREE_44":{"address":5843648,"default_item":150,"flag":655},"BERRY_TREE_45":{"address":5843650,"default_item":152,"flag":656},"BERRY_TREE_46":{"address":5843652,"default_item":151,"flag":657},"BERRY_TREE_47":{"address":5843654,"default_item":140,"flag":658},"BERRY_TREE_48":{"address":5843656,"default_item":137,"flag":659},"BERRY_TREE_49":{"address":5843658,"default_item":136,"flag":660},"BERRY_TREE_50":{"address":5843660,"default_item":134,"flag":661},"BERRY_TREE_51":{"address":5843662,"default_item":142,"flag":662},"BERRY_TREE_52":{"address":5843664,"default_item":150,"flag":663},"BERRY_TREE_53":{"address":5843666,"default_item":150,"flag":664},"BERRY_TREE_54":{"address":5843668,"default_item":142,"flag":665},"BERRY_TREE_55":{"address":5843670,"default_item":149,"flag":666},"BERRY_TREE_56":{"address":5843672,"default_item":149,"flag":667},"BERRY_TREE_57":{"address":5843674,"default_item":136,"flag":668},"BERRY_TREE_58":{"address":5843676,"default_item":153,"flag":669},"BERRY_TREE_59":{"address":5843678,"default_item":153,"flag":670},"BERRY_TREE_60":{"address":5843680,"default_item":157,"flag":671},"BERRY_TREE_61":{"address":5843682,"default_item":157,"flag":672},"BERRY_TREE_62":{"address":5843684,"default_item":138,"flag":673},"BERRY_TREE_63":{"address":5843686,"default_item":142,"flag":674},"BERRY_TREE_64":{"address":5843688,"default_item":138,"flag":675},"BERRY_TREE_65":{"address":5843690,"default_item":157,"flag":676},"BERRY_TREE_66":{"address":5843692,"default_item":134,"flag":677},"BERRY_TREE_67":{"address":5843694,"default_item":152,"flag":678},"BERRY_TREE_68":{"address":5843696,"default_item":140,"flag":679},"BERRY_TREE_69":{"address":5843698,"default_item":154,"flag":680},"BERRY_TREE_70":{"address":5843700,"default_item":154,"flag":681},"BERRY_TREE_71":{"address":5843702,"default_item":154,"flag":682},"BERRY_TREE_72":{"address":5843704,"default_item":157,"flag":683},"BERRY_TREE_73":{"address":5843706,"default_item":155,"flag":684},"BERRY_TREE_74":{"address":5843708,"default_item":155,"flag":685},"BERRY_TREE_75":{"address":5843710,"default_item":142,"flag":686},"BERRY_TREE_76":{"address":5843712,"default_item":133,"flag":687},"BERRY_TREE_77":{"address":5843714,"default_item":140,"flag":688},"BERRY_TREE_78":{"address":5843716,"default_item":140,"flag":689},"BERRY_TREE_79":{"address":5843718,"default_item":155,"flag":690},"BERRY_TREE_80":{"address":5843720,"default_item":139,"flag":691},"BERRY_TREE_81":{"address":5843722,"default_item":139,"flag":692},"BERRY_TREE_82":{"address":5843724,"default_item":168,"flag":693},"BERRY_TREE_83":{"address":5843726,"default_item":156,"flag":694},"BERRY_TREE_84":{"address":5843728,"default_item":156,"flag":695},"BERRY_TREE_85":{"address":5843730,"default_item":142,"flag":696},"BERRY_TREE_86":{"address":5843732,"default_item":138,"flag":697},"BERRY_TREE_87":{"address":5843734,"default_item":135,"flag":698},"BERRY_TREE_88":{"address":5843736,"default_item":142,"flag":699},"HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":{"address":5497200,"default_item":281,"flag":531},"HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":{"address":5497212,"default_item":282,"flag":532},"HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":{"address":5497224,"default_item":283,"flag":533},"HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":{"address":5497236,"default_item":284,"flag":534},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":{"address":5500100,"default_item":67,"flag":601},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":{"address":5500124,"default_item":65,"flag":604},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":{"address":5500112,"default_item":64,"flag":603},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":{"address":5500088,"default_item":70,"flag":602},"HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":{"address":5435924,"default_item":110,"flag":528},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":{"address":5487372,"default_item":195,"flag":548},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":{"address":5487384,"default_item":195,"flag":549},"HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":{"address":5489116,"default_item":23,"flag":577},"HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":{"address":5489128,"default_item":3,"flag":576},"HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":{"address":5435672,"default_item":16,"flag":500},"HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":{"address":5432608,"default_item":111,"flag":527},"HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":{"address":5432632,"default_item":4,"flag":575},"HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":{"address":5432620,"default_item":69,"flag":543},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":{"address":5490440,"default_item":35,"flag":578},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":{"address":5490428,"default_item":2,"flag":529},"HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":{"address":5490796,"default_item":68,"flag":580},"HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":{"address":5490784,"default_item":70,"flag":579},"HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":{"address":5525804,"default_item":45,"flag":609},"HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":{"address":5428972,"default_item":68,"flag":595},"HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":{"address":5487908,"default_item":4,"flag":561},"HIDDEN_ITEM_PETALBURG_WOODS_POTION":{"address":5487872,"default_item":13,"flag":558},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":{"address":5487884,"default_item":103,"flag":559},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":{"address":5487896,"default_item":103,"flag":560},"HIDDEN_ITEM_ROUTE_104_ANTIDOTE":{"address":5438492,"default_item":14,"flag":585},"HIDDEN_ITEM_ROUTE_104_HEART_SCALE":{"address":5438504,"default_item":111,"flag":588},"HIDDEN_ITEM_ROUTE_104_POKE_BALL":{"address":5438468,"default_item":4,"flag":562},"HIDDEN_ITEM_ROUTE_104_POTION":{"address":5438480,"default_item":13,"flag":537},"HIDDEN_ITEM_ROUTE_104_SUPER_POTION":{"address":5438456,"default_item":22,"flag":544},"HIDDEN_ITEM_ROUTE_105_BIG_PEARL":{"address":5438748,"default_item":107,"flag":611},"HIDDEN_ITEM_ROUTE_105_HEART_SCALE":{"address":5438736,"default_item":111,"flag":589},"HIDDEN_ITEM_ROUTE_106_HEART_SCALE":{"address":5438932,"default_item":111,"flag":547},"HIDDEN_ITEM_ROUTE_106_POKE_BALL":{"address":5438908,"default_item":4,"flag":563},"HIDDEN_ITEM_ROUTE_106_STARDUST":{"address":5438920,"default_item":108,"flag":546},"HIDDEN_ITEM_ROUTE_108_RARE_CANDY":{"address":5439340,"default_item":68,"flag":586},"HIDDEN_ITEM_ROUTE_109_ETHER":{"address":5440016,"default_item":34,"flag":564},"HIDDEN_ITEM_ROUTE_109_GREAT_BALL":{"address":5440004,"default_item":3,"flag":551},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":{"address":5439992,"default_item":111,"flag":552},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":{"address":5440028,"default_item":111,"flag":590},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":{"address":5440040,"default_item":111,"flag":591},"HIDDEN_ITEM_ROUTE_109_REVIVE":{"address":5439980,"default_item":24,"flag":550},"HIDDEN_ITEM_ROUTE_110_FULL_HEAL":{"address":5441308,"default_item":23,"flag":555},"HIDDEN_ITEM_ROUTE_110_GREAT_BALL":{"address":5441284,"default_item":3,"flag":553},"HIDDEN_ITEM_ROUTE_110_POKE_BALL":{"address":5441296,"default_item":4,"flag":565},"HIDDEN_ITEM_ROUTE_110_REVIVE":{"address":5441272,"default_item":24,"flag":554},"HIDDEN_ITEM_ROUTE_111_PROTEIN":{"address":5443220,"default_item":64,"flag":556},"HIDDEN_ITEM_ROUTE_111_RARE_CANDY":{"address":5443232,"default_item":68,"flag":557},"HIDDEN_ITEM_ROUTE_111_STARDUST":{"address":5443160,"default_item":108,"flag":502},"HIDDEN_ITEM_ROUTE_113_ETHER":{"address":5444488,"default_item":34,"flag":503},"HIDDEN_ITEM_ROUTE_113_NUGGET":{"address":5444512,"default_item":110,"flag":598},"HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":{"address":5444500,"default_item":320,"flag":530},"HIDDEN_ITEM_ROUTE_114_CARBOS":{"address":5445340,"default_item":66,"flag":504},"HIDDEN_ITEM_ROUTE_114_REVIVE":{"address":5445364,"default_item":24,"flag":542},"HIDDEN_ITEM_ROUTE_115_HEART_SCALE":{"address":5446176,"default_item":111,"flag":597},"HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":{"address":5447056,"default_item":206,"flag":596},"HIDDEN_ITEM_ROUTE_116_SUPER_POTION":{"address":5447044,"default_item":22,"flag":545},"HIDDEN_ITEM_ROUTE_117_REPEL":{"address":5447708,"default_item":86,"flag":572},"HIDDEN_ITEM_ROUTE_118_HEART_SCALE":{"address":5448404,"default_item":111,"flag":566},"HIDDEN_ITEM_ROUTE_118_IRON":{"address":5448392,"default_item":65,"flag":567},"HIDDEN_ITEM_ROUTE_119_CALCIUM":{"address":5449972,"default_item":67,"flag":505},"HIDDEN_ITEM_ROUTE_119_FULL_HEAL":{"address":5450056,"default_item":23,"flag":568},"HIDDEN_ITEM_ROUTE_119_MAX_ETHER":{"address":5450068,"default_item":35,"flag":587},"HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":{"address":5449984,"default_item":2,"flag":506},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":{"address":5451596,"default_item":68,"flag":571},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":{"address":5451620,"default_item":68,"flag":569},"HIDDEN_ITEM_ROUTE_120_REVIVE":{"address":5451608,"default_item":24,"flag":584},"HIDDEN_ITEM_ROUTE_120_ZINC":{"address":5451632,"default_item":70,"flag":570},"HIDDEN_ITEM_ROUTE_121_FULL_HEAL":{"address":5452540,"default_item":23,"flag":573},"HIDDEN_ITEM_ROUTE_121_HP_UP":{"address":5452516,"default_item":63,"flag":539},"HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":{"address":5452552,"default_item":25,"flag":600},"HIDDEN_ITEM_ROUTE_121_NUGGET":{"address":5452528,"default_item":110,"flag":540},"HIDDEN_ITEM_ROUTE_123_HYPER_POTION":{"address":5454100,"default_item":21,"flag":574},"HIDDEN_ITEM_ROUTE_123_PP_UP":{"address":5454112,"default_item":69,"flag":599},"HIDDEN_ITEM_ROUTE_123_RARE_CANDY":{"address":5454124,"default_item":68,"flag":610},"HIDDEN_ITEM_ROUTE_123_REVIVE":{"address":5454088,"default_item":24,"flag":541},"HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":{"address":5454052,"default_item":83,"flag":507},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":{"address":5455620,"default_item":111,"flag":592},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":{"address":5455632,"default_item":111,"flag":593},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":{"address":5455644,"default_item":111,"flag":594},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":{"address":5517256,"default_item":68,"flag":606},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":{"address":5517268,"default_item":70,"flag":607},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":{"address":5517432,"default_item":19,"flag":605},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":{"address":5517420,"default_item":69,"flag":608},"HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":{"address":5511292,"default_item":200,"flag":535},"HIDDEN_ITEM_TRICK_HOUSE_NUGGET":{"address":5526716,"default_item":110,"flag":501},"HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":{"address":5456992,"default_item":107,"flag":511},"HIDDEN_ITEM_UNDERWATER_124_CALCIUM":{"address":5457016,"default_item":67,"flag":536},"HIDDEN_ITEM_UNDERWATER_124_CARBOS":{"address":5456956,"default_item":66,"flag":508},"HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":{"address":5456968,"default_item":51,"flag":509},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":{"address":5457004,"default_item":111,"flag":513},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":{"address":5457028,"default_item":111,"flag":538},"HIDDEN_ITEM_UNDERWATER_124_PEARL":{"address":5456980,"default_item":106,"flag":510},"HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":{"address":5457140,"default_item":107,"flag":520},"HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":{"address":5457152,"default_item":49,"flag":512},"HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":{"address":5457068,"default_item":111,"flag":514},"HIDDEN_ITEM_UNDERWATER_126_IRON":{"address":5457116,"default_item":65,"flag":519},"HIDDEN_ITEM_UNDERWATER_126_PEARL":{"address":5457104,"default_item":106,"flag":517},"HIDDEN_ITEM_UNDERWATER_126_STARDUST":{"address":5457092,"default_item":108,"flag":516},"HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":{"address":5457080,"default_item":2,"flag":515},"HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":{"address":5457128,"default_item":50,"flag":518},"HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":{"address":5457224,"default_item":111,"flag":523},"HIDDEN_ITEM_UNDERWATER_127_HP_UP":{"address":5457212,"default_item":63,"flag":522},"HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":{"address":5457236,"default_item":48,"flag":524},"HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":{"address":5457200,"default_item":109,"flag":521},"HIDDEN_ITEM_UNDERWATER_128_PEARL":{"address":5457288,"default_item":106,"flag":526},"HIDDEN_ITEM_UNDERWATER_128_PROTEIN":{"address":5457276,"default_item":64,"flag":525},"HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":{"address":5493932,"default_item":2,"flag":581},"HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":{"address":5494744,"default_item":36,"flag":582},"HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":{"address":5494756,"default_item":84,"flag":583},"ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":{"address":2709805,"default_item":285,"flag":1100},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":{"address":2709857,"default_item":306,"flag":1102},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":{"address":2709831,"default_item":278,"flag":1078},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":{"address":2709844,"default_item":97,"flag":1101},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":{"address":2709818,"default_item":11,"flag":1077},"ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":{"address":2709740,"default_item":122,"flag":1095},"ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":{"address":2709792,"default_item":24,"flag":1099},"ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":{"address":2709766,"default_item":7,"flag":1097},"ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":{"address":2709753,"default_item":85,"flag":1096},"ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":{"address":2709779,"default_item":301,"flag":1098},"ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":{"address":2710039,"default_item":1,"flag":1124},"ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":{"address":2710065,"default_item":37,"flag":1071},"ITEM_AQUA_HIDEOUT_B1F_NUGGET":{"address":2710052,"default_item":110,"flag":1132},"ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":{"address":2710078,"default_item":8,"flag":1072},"ITEM_ARTISAN_CAVE_1F_CARBOS":{"address":2710416,"default_item":66,"flag":1163},"ITEM_ARTISAN_CAVE_B1F_HP_UP":{"address":2710403,"default_item":63,"flag":1162},"ITEM_FIERY_PATH_FIRE_STONE":{"address":2709584,"default_item":95,"flag":1111},"ITEM_FIERY_PATH_TM_TOXIC":{"address":2709597,"default_item":294,"flag":1091},"ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":{"address":2709519,"default_item":85,"flag":1050},"ITEM_GRANITE_CAVE_B1F_POKE_BALL":{"address":2709532,"default_item":4,"flag":1051},"ITEM_GRANITE_CAVE_B2F_RARE_CANDY":{"address":2709558,"default_item":68,"flag":1054},"ITEM_GRANITE_CAVE_B2F_REPEL":{"address":2709545,"default_item":86,"flag":1053},"ITEM_JAGGED_PASS_BURN_HEAL":{"address":2709571,"default_item":15,"flag":1070},"ITEM_LILYCOVE_CITY_MAX_REPEL":{"address":2709415,"default_item":84,"flag":1042},"ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":{"address":2710429,"default_item":68,"flag":1151},"ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":{"address":2710455,"default_item":19,"flag":1165},"ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":{"address":2710442,"default_item":37,"flag":1164},"ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":{"address":2710468,"default_item":110,"flag":1166},"ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":{"address":2710481,"default_item":71,"flag":1167},"ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":{"address":2710507,"default_item":85,"flag":1059},"ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":{"address":2710494,"default_item":25,"flag":1168},"ITEM_MAUVILLE_CITY_X_SPEED":{"address":2709389,"default_item":77,"flag":1116},"ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":{"address":2709623,"default_item":23,"flag":1045},"ITEM_METEOR_FALLS_1F_1R_MOON_STONE":{"address":2709636,"default_item":94,"flag":1046},"ITEM_METEOR_FALLS_1F_1R_PP_UP":{"address":2709649,"default_item":69,"flag":1047},"ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":{"address":2709610,"default_item":311,"flag":1044},"ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":{"address":2709662,"default_item":290,"flag":1080},"ITEM_MOSSDEEP_CITY_NET_BALL":{"address":2709428,"default_item":6,"flag":1043},"ITEM_MT_PYRE_2F_ULTRA_BALL":{"address":2709948,"default_item":2,"flag":1129},"ITEM_MT_PYRE_3F_SUPER_REPEL":{"address":2709961,"default_item":83,"flag":1120},"ITEM_MT_PYRE_4F_SEA_INCENSE":{"address":2709974,"default_item":220,"flag":1130},"ITEM_MT_PYRE_5F_LAX_INCENSE":{"address":2709987,"default_item":221,"flag":1052},"ITEM_MT_PYRE_6F_TM_SHADOW_BALL":{"address":2710000,"default_item":318,"flag":1089},"ITEM_MT_PYRE_EXTERIOR_MAX_POTION":{"address":2710013,"default_item":20,"flag":1073},"ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":{"address":2710026,"default_item":336,"flag":1074},"ITEM_NEW_MAUVILLE_ESCAPE_ROPE":{"address":2709688,"default_item":85,"flag":1076},"ITEM_NEW_MAUVILLE_FULL_HEAL":{"address":2709714,"default_item":23,"flag":1122},"ITEM_NEW_MAUVILLE_PARALYZE_HEAL":{"address":2709727,"default_item":18,"flag":1123},"ITEM_NEW_MAUVILLE_THUNDER_STONE":{"address":2709701,"default_item":96,"flag":1110},"ITEM_NEW_MAUVILLE_ULTRA_BALL":{"address":2709675,"default_item":2,"flag":1075},"ITEM_PETALBURG_CITY_ETHER":{"address":2709376,"default_item":34,"flag":1040},"ITEM_PETALBURG_CITY_MAX_REVIVE":{"address":2709363,"default_item":25,"flag":1039},"ITEM_PETALBURG_WOODS_ETHER":{"address":2709467,"default_item":34,"flag":1058},"ITEM_PETALBURG_WOODS_GREAT_BALL":{"address":2709454,"default_item":3,"flag":1056},"ITEM_PETALBURG_WOODS_PARALYZE_HEAL":{"address":2709480,"default_item":18,"flag":1117},"ITEM_PETALBURG_WOODS_X_ATTACK":{"address":2709441,"default_item":75,"flag":1055},"ITEM_ROUTE_102_POTION":{"address":2708375,"default_item":13,"flag":1000},"ITEM_ROUTE_103_GUARD_SPEC":{"address":2708388,"default_item":73,"flag":1114},"ITEM_ROUTE_103_PP_UP":{"address":2708401,"default_item":69,"flag":1137},"ITEM_ROUTE_104_POKE_BALL":{"address":2708427,"default_item":4,"flag":1057},"ITEM_ROUTE_104_POTION":{"address":2708453,"default_item":13,"flag":1135},"ITEM_ROUTE_104_PP_UP":{"address":2708414,"default_item":69,"flag":1002},"ITEM_ROUTE_104_X_ACCURACY":{"address":2708440,"default_item":78,"flag":1115},"ITEM_ROUTE_105_IRON":{"address":2708466,"default_item":65,"flag":1003},"ITEM_ROUTE_106_PROTEIN":{"address":2708479,"default_item":64,"flag":1004},"ITEM_ROUTE_108_STAR_PIECE":{"address":2708492,"default_item":109,"flag":1139},"ITEM_ROUTE_109_POTION":{"address":2708518,"default_item":13,"flag":1140},"ITEM_ROUTE_109_PP_UP":{"address":2708505,"default_item":69,"flag":1005},"ITEM_ROUTE_110_DIRE_HIT":{"address":2708544,"default_item":74,"flag":1007},"ITEM_ROUTE_110_ELIXIR":{"address":2708557,"default_item":36,"flag":1141},"ITEM_ROUTE_110_RARE_CANDY":{"address":2708531,"default_item":68,"flag":1006},"ITEM_ROUTE_111_ELIXIR":{"address":2708609,"default_item":36,"flag":1142},"ITEM_ROUTE_111_HP_UP":{"address":2708596,"default_item":63,"flag":1010},"ITEM_ROUTE_111_STARDUST":{"address":2708583,"default_item":108,"flag":1009},"ITEM_ROUTE_111_TM_SANDSTORM":{"address":2708570,"default_item":325,"flag":1008},"ITEM_ROUTE_112_NUGGET":{"address":2708622,"default_item":110,"flag":1011},"ITEM_ROUTE_113_HYPER_POTION":{"address":2708661,"default_item":21,"flag":1143},"ITEM_ROUTE_113_MAX_ETHER":{"address":2708635,"default_item":35,"flag":1012},"ITEM_ROUTE_113_SUPER_REPEL":{"address":2708648,"default_item":83,"flag":1013},"ITEM_ROUTE_114_ENERGY_POWDER":{"address":2708700,"default_item":30,"flag":1160},"ITEM_ROUTE_114_PROTEIN":{"address":2708687,"default_item":64,"flag":1015},"ITEM_ROUTE_114_RARE_CANDY":{"address":2708674,"default_item":68,"flag":1014},"ITEM_ROUTE_115_GREAT_BALL":{"address":2708752,"default_item":3,"flag":1118},"ITEM_ROUTE_115_HEAL_POWDER":{"address":2708765,"default_item":32,"flag":1144},"ITEM_ROUTE_115_IRON":{"address":2708739,"default_item":65,"flag":1018},"ITEM_ROUTE_115_PP_UP":{"address":2708778,"default_item":69,"flag":1161},"ITEM_ROUTE_115_SUPER_POTION":{"address":2708713,"default_item":22,"flag":1016},"ITEM_ROUTE_115_TM_FOCUS_PUNCH":{"address":2708726,"default_item":289,"flag":1017},"ITEM_ROUTE_116_ETHER":{"address":2708804,"default_item":34,"flag":1019},"ITEM_ROUTE_116_HP_UP":{"address":2708830,"default_item":63,"flag":1021},"ITEM_ROUTE_116_POTION":{"address":2708843,"default_item":13,"flag":1146},"ITEM_ROUTE_116_REPEL":{"address":2708817,"default_item":86,"flag":1020},"ITEM_ROUTE_116_X_SPECIAL":{"address":2708791,"default_item":79,"flag":1001},"ITEM_ROUTE_117_GREAT_BALL":{"address":2708856,"default_item":3,"flag":1022},"ITEM_ROUTE_117_REVIVE":{"address":2708869,"default_item":24,"flag":1023},"ITEM_ROUTE_118_HYPER_POTION":{"address":2708882,"default_item":21,"flag":1121},"ITEM_ROUTE_119_ELIXIR_1":{"address":2708921,"default_item":36,"flag":1026},"ITEM_ROUTE_119_ELIXIR_2":{"address":2708986,"default_item":36,"flag":1147},"ITEM_ROUTE_119_HYPER_POTION_1":{"address":2708960,"default_item":21,"flag":1029},"ITEM_ROUTE_119_HYPER_POTION_2":{"address":2708973,"default_item":21,"flag":1106},"ITEM_ROUTE_119_LEAF_STONE":{"address":2708934,"default_item":98,"flag":1027},"ITEM_ROUTE_119_NUGGET":{"address":2710104,"default_item":110,"flag":1134},"ITEM_ROUTE_119_RARE_CANDY":{"address":2708947,"default_item":68,"flag":1028},"ITEM_ROUTE_119_SUPER_REPEL":{"address":2708895,"default_item":83,"flag":1024},"ITEM_ROUTE_119_ZINC":{"address":2708908,"default_item":70,"flag":1025},"ITEM_ROUTE_120_FULL_HEAL":{"address":2709012,"default_item":23,"flag":1031},"ITEM_ROUTE_120_HYPER_POTION":{"address":2709025,"default_item":21,"flag":1107},"ITEM_ROUTE_120_NEST_BALL":{"address":2709038,"default_item":8,"flag":1108},"ITEM_ROUTE_120_NUGGET":{"address":2708999,"default_item":110,"flag":1030},"ITEM_ROUTE_120_REVIVE":{"address":2709051,"default_item":24,"flag":1148},"ITEM_ROUTE_121_CARBOS":{"address":2709064,"default_item":66,"flag":1103},"ITEM_ROUTE_121_REVIVE":{"address":2709077,"default_item":24,"flag":1149},"ITEM_ROUTE_121_ZINC":{"address":2709090,"default_item":70,"flag":1150},"ITEM_ROUTE_123_CALCIUM":{"address":2709103,"default_item":67,"flag":1032},"ITEM_ROUTE_123_ELIXIR":{"address":2709129,"default_item":36,"flag":1109},"ITEM_ROUTE_123_PP_UP":{"address":2709142,"default_item":69,"flag":1152},"ITEM_ROUTE_123_REVIVAL_HERB":{"address":2709155,"default_item":33,"flag":1153},"ITEM_ROUTE_123_ULTRA_BALL":{"address":2709116,"default_item":2,"flag":1104},"ITEM_ROUTE_124_BLUE_SHARD":{"address":2709181,"default_item":49,"flag":1093},"ITEM_ROUTE_124_RED_SHARD":{"address":2709168,"default_item":48,"flag":1092},"ITEM_ROUTE_124_YELLOW_SHARD":{"address":2709194,"default_item":50,"flag":1066},"ITEM_ROUTE_125_BIG_PEARL":{"address":2709207,"default_item":107,"flag":1154},"ITEM_ROUTE_126_GREEN_SHARD":{"address":2709220,"default_item":51,"flag":1105},"ITEM_ROUTE_127_CARBOS":{"address":2709246,"default_item":66,"flag":1035},"ITEM_ROUTE_127_RARE_CANDY":{"address":2709259,"default_item":68,"flag":1155},"ITEM_ROUTE_127_ZINC":{"address":2709233,"default_item":70,"flag":1034},"ITEM_ROUTE_132_PROTEIN":{"address":2709285,"default_item":64,"flag":1156},"ITEM_ROUTE_132_RARE_CANDY":{"address":2709272,"default_item":68,"flag":1036},"ITEM_ROUTE_133_BIG_PEARL":{"address":2709298,"default_item":107,"flag":1037},"ITEM_ROUTE_133_MAX_REVIVE":{"address":2709324,"default_item":25,"flag":1157},"ITEM_ROUTE_133_STAR_PIECE":{"address":2709311,"default_item":109,"flag":1038},"ITEM_ROUTE_134_CARBOS":{"address":2709337,"default_item":66,"flag":1158},"ITEM_ROUTE_134_STAR_PIECE":{"address":2709350,"default_item":109,"flag":1159},"ITEM_RUSTBORO_CITY_X_DEFEND":{"address":2709402,"default_item":76,"flag":1041},"ITEM_RUSTURF_TUNNEL_MAX_ETHER":{"address":2709506,"default_item":35,"flag":1049},"ITEM_RUSTURF_TUNNEL_POKE_BALL":{"address":2709493,"default_item":4,"flag":1048},"ITEM_SAFARI_ZONE_NORTH_CALCIUM":{"address":2709896,"default_item":67,"flag":1119},"ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":{"address":2709922,"default_item":110,"flag":1169},"ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":{"address":2709883,"default_item":310,"flag":1094},"ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":{"address":2709935,"default_item":107,"flag":1170},"ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":{"address":2709909,"default_item":25,"flag":1131},"ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":{"address":2709870,"default_item":299,"flag":1079},"ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":{"address":2710208,"default_item":314,"flag":1090},"ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":{"address":2710143,"default_item":107,"flag":1081},"ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":{"address":2710195,"default_item":212,"flag":1113},"ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":{"address":2710182,"default_item":295,"flag":1112},"ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":{"address":2710156,"default_item":68,"flag":1082},"ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":{"address":2710169,"default_item":16,"flag":1083},"ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":{"address":[2710221,2551006],"default_item":121,"flag":1060},"ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":{"address":[2710234,2551032],"default_item":122,"flag":1061},"ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":{"address":[2710247,2551058],"default_item":126,"flag":1062},"ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":{"address":[2710260,2551084],"default_item":128,"flag":1063},"ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":{"address":[2710273,2551110],"default_item":125,"flag":1064},"ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":{"address":[2710286,2551136],"default_item":124,"flag":1065},"ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":{"address":[2710299,2551162],"default_item":123,"flag":1067},"ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":{"address":[2710312,2551188],"default_item":129,"flag":1068},"ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":{"address":[2710325,2551214],"default_item":127,"flag":1069},"ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":{"address":2710338,"default_item":37,"flag":1084},"ITEM_VICTORY_ROAD_1F_PP_UP":{"address":2710351,"default_item":69,"flag":1085},"ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":{"address":2710377,"default_item":19,"flag":1087},"ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":{"address":2710364,"default_item":317,"flag":1086},"ITEM_VICTORY_ROAD_B2F_FULL_HEAL":{"address":2710390,"default_item":23,"flag":1088},"NPC_GIFT_BERRY_MASTERS_WIFE":{"address":2570453,"default_item":133,"flag":1197},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_1":{"address":2570263,"default_item":153,"flag":1195},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_2":{"address":2570315,"default_item":154,"flag":1196},"NPC_GIFT_FLOWER_SHOP_RECEIVED_BERRY":{"address":2284375,"default_item":133,"flag":1207},"NPC_GIFT_GOT_BASEMENT_KEY_FROM_WATTSON":{"address":1971718,"default_item":271,"flag":208},"NPC_GIFT_GOT_TM_THUNDERBOLT_FROM_WATTSON":{"address":1971754,"default_item":312,"flag":209},"NPC_GIFT_LILYCOVE_RECEIVED_BERRY":{"address":1985277,"default_item":141,"flag":1208},"NPC_GIFT_RECEIVED_6_SODA_POP":{"address":2543767,"default_item":27,"flag":140},"NPC_GIFT_RECEIVED_ACRO_BIKE":{"address":2170570,"default_item":272,"flag":1181},"NPC_GIFT_RECEIVED_AMULET_COIN":{"address":2716248,"default_item":189,"flag":133},"NPC_GIFT_RECEIVED_AURORA_TICKET":{"address":2716523,"default_item":371,"flag":314},"NPC_GIFT_RECEIVED_CHARCOAL":{"address":2102559,"default_item":215,"flag":254},"NPC_GIFT_RECEIVED_CHESTO_BERRY_ROUTE_104":{"address":2028703,"default_item":134,"flag":246},"NPC_GIFT_RECEIVED_CLEANSE_TAG":{"address":2312109,"default_item":190,"flag":282},"NPC_GIFT_RECEIVED_COIN_CASE":{"address":2179054,"default_item":260,"flag":258},"NPC_GIFT_RECEIVED_DEEP_SEA_SCALE":{"address":2162572,"default_item":193,"flag":1190},"NPC_GIFT_RECEIVED_DEEP_SEA_TOOTH":{"address":2162555,"default_item":192,"flag":1191},"NPC_GIFT_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":{"address":2295814,"default_item":269,"flag":1172},"NPC_GIFT_RECEIVED_DEVON_SCOPE":{"address":2065146,"default_item":288,"flag":285},"NPC_GIFT_RECEIVED_EON_TICKET":{"address":2716574,"default_item":275,"flag":474},"NPC_GIFT_RECEIVED_EXP_SHARE":{"address":2185525,"default_item":182,"flag":272},"NPC_GIFT_RECEIVED_FIRST_POKEBALLS":{"address":2085751,"default_item":4,"flag":233},"NPC_GIFT_RECEIVED_FOCUS_BAND":{"address":2337807,"default_item":196,"flag":283},"NPC_GIFT_RECEIVED_GOOD_ROD":{"address":2058408,"default_item":263,"flag":227},"NPC_GIFT_RECEIVED_GO_GOGGLES":{"address":2017746,"default_item":279,"flag":221},"NPC_GIFT_RECEIVED_GREAT_BALL_PETALBURG_WOODS":{"address":2300119,"default_item":3,"flag":1171},"NPC_GIFT_RECEIVED_GREAT_BALL_RUSTBORO_CITY":{"address":1977146,"default_item":3,"flag":1173},"NPC_GIFT_RECEIVED_HM_CUT":{"address":2199532,"default_item":339,"flag":137},"NPC_GIFT_RECEIVED_HM_DIVE":{"address":2252095,"default_item":346,"flag":123},"NPC_GIFT_RECEIVED_HM_FLASH":{"address":2298287,"default_item":343,"flag":109},"NPC_GIFT_RECEIVED_HM_FLY":{"address":2060636,"default_item":340,"flag":110},"NPC_GIFT_RECEIVED_HM_ROCK_SMASH":{"address":2174128,"default_item":344,"flag":107},"NPC_GIFT_RECEIVED_HM_STRENGTH":{"address":2295305,"default_item":342,"flag":106},"NPC_GIFT_RECEIVED_HM_SURF":{"address":2126671,"default_item":341,"flag":122},"NPC_GIFT_RECEIVED_HM_WATERFALL":{"address":1999854,"default_item":345,"flag":312},"NPC_GIFT_RECEIVED_ITEMFINDER":{"address":2039874,"default_item":261,"flag":1176},"NPC_GIFT_RECEIVED_KINGS_ROCK":{"address":1993670,"default_item":187,"flag":276},"NPC_GIFT_RECEIVED_LETTER":{"address":2185301,"default_item":274,"flag":1174},"NPC_GIFT_RECEIVED_MACHO_BRACE":{"address":2284472,"default_item":181,"flag":277},"NPC_GIFT_RECEIVED_MACH_BIKE":{"address":2170553,"default_item":259,"flag":1180},"NPC_GIFT_RECEIVED_MAGMA_EMBLEM":{"address":2316671,"default_item":375,"flag":1177},"NPC_GIFT_RECEIVED_MENTAL_HERB":{"address":2208103,"default_item":185,"flag":223},"NPC_GIFT_RECEIVED_METEORITE":{"address":2304222,"default_item":280,"flag":115},"NPC_GIFT_RECEIVED_MIRACLE_SEED":{"address":2300337,"default_item":205,"flag":297},"NPC_GIFT_RECEIVED_MYSTIC_TICKET":{"address":2716540,"default_item":370,"flag":315},"NPC_GIFT_RECEIVED_OLD_ROD":{"address":2012541,"default_item":262,"flag":257},"NPC_GIFT_RECEIVED_OLD_SEA_MAP":{"address":2716557,"default_item":376,"flag":316},"NPC_GIFT_RECEIVED_POKEBLOCK_CASE":{"address":2614193,"default_item":273,"flag":95},"NPC_GIFT_RECEIVED_POTION_OLDALE":{"address":2010888,"default_item":13,"flag":132},"NPC_GIFT_RECEIVED_POWDER_JAR":{"address":1962504,"default_item":372,"flag":337},"NPC_GIFT_RECEIVED_PREMIER_BALL_RUSTBORO":{"address":2200571,"default_item":12,"flag":213},"NPC_GIFT_RECEIVED_QUICK_CLAW":{"address":2192227,"default_item":183,"flag":275},"NPC_GIFT_RECEIVED_REPEAT_BALL":{"address":2053722,"default_item":9,"flag":256},"NPC_GIFT_RECEIVED_SECRET_POWER":{"address":2598914,"default_item":331,"flag":96},"NPC_GIFT_RECEIVED_SILK_SCARF":{"address":2101830,"default_item":217,"flag":289},"NPC_GIFT_RECEIVED_SOFT_SAND":{"address":2035664,"default_item":203,"flag":280},"NPC_GIFT_RECEIVED_SOOTHE_BELL":{"address":2151278,"default_item":184,"flag":278},"NPC_GIFT_RECEIVED_SOOT_SACK":{"address":2567245,"default_item":270,"flag":1033},"NPC_GIFT_RECEIVED_SS_TICKET":{"address":2716506,"default_item":265,"flag":291},"NPC_GIFT_RECEIVED_SUN_STONE_MOSSDEEP":{"address":2254406,"default_item":93,"flag":192},"NPC_GIFT_RECEIVED_SUPER_ROD":{"address":2251560,"default_item":264,"flag":152},"NPC_GIFT_RECEIVED_TM_AERIAL_ACE":{"address":2202201,"default_item":328,"flag":170},"NPC_GIFT_RECEIVED_TM_ATTRACT":{"address":2116413,"default_item":333,"flag":235},"NPC_GIFT_RECEIVED_TM_BRICK_BREAK":{"address":2269085,"default_item":319,"flag":121},"NPC_GIFT_RECEIVED_TM_BULK_UP":{"address":2095210,"default_item":296,"flag":166},"NPC_GIFT_RECEIVED_TM_BULLET_SEED":{"address":2028910,"default_item":297,"flag":262},"NPC_GIFT_RECEIVED_TM_CALM_MIND":{"address":2244066,"default_item":292,"flag":171},"NPC_GIFT_RECEIVED_TM_DIG":{"address":2286669,"default_item":316,"flag":261},"NPC_GIFT_RECEIVED_TM_FACADE":{"address":2129909,"default_item":330,"flag":169},"NPC_GIFT_RECEIVED_TM_FRUSTRATION":{"address":2124110,"default_item":309,"flag":1179},"NPC_GIFT_RECEIVED_TM_GIGA_DRAIN":{"address":2068012,"default_item":307,"flag":232},"NPC_GIFT_RECEIVED_TM_HIDDEN_POWER":{"address":2206905,"default_item":298,"flag":264},"NPC_GIFT_RECEIVED_TM_OVERHEAT":{"address":2103328,"default_item":338,"flag":168},"NPC_GIFT_RECEIVED_TM_REST":{"address":2236966,"default_item":332,"flag":234},"NPC_GIFT_RECEIVED_TM_RETURN":{"address":2113546,"default_item":315,"flag":229},"NPC_GIFT_RECEIVED_TM_RETURN_2":{"address":2124055,"default_item":315,"flag":1178},"NPC_GIFT_RECEIVED_TM_ROAR":{"address":2051750,"default_item":293,"flag":231},"NPC_GIFT_RECEIVED_TM_ROCK_TOMB":{"address":2188088,"default_item":327,"flag":165},"NPC_GIFT_RECEIVED_TM_SHOCK_WAVE":{"address":2167340,"default_item":322,"flag":167},"NPC_GIFT_RECEIVED_TM_SLUDGE_BOMB":{"address":2099189,"default_item":324,"flag":230},"NPC_GIFT_RECEIVED_TM_SNATCH":{"address":2360766,"default_item":337,"flag":260},"NPC_GIFT_RECEIVED_TM_STEEL_WING":{"address":2298866,"default_item":335,"flag":1175},"NPC_GIFT_RECEIVED_TM_THIEF":{"address":2154698,"default_item":334,"flag":269},"NPC_GIFT_RECEIVED_TM_TORMENT":{"address":2145260,"default_item":329,"flag":265},"NPC_GIFT_RECEIVED_TM_WATER_PULSE":{"address":2262402,"default_item":291,"flag":172},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_1":{"address":2550316,"default_item":68,"flag":1200},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_2":{"address":2550390,"default_item":10,"flag":1201},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_3":{"address":2550473,"default_item":204,"flag":1202},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_4":{"address":2550556,"default_item":194,"flag":1203},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_5":{"address":2550630,"default_item":300,"flag":1204},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_6":{"address":2550695,"default_item":208,"flag":1205},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_7":{"address":2550769,"default_item":71,"flag":1206},"NPC_GIFT_RECEIVED_WAILMER_PAIL":{"address":2284320,"default_item":268,"flag":94},"NPC_GIFT_RECEIVED_WHITE_HERB":{"address":2028770,"default_item":180,"flag":279},"NPC_GIFT_ROUTE_111_RECEIVED_BERRY":{"address":2045493,"default_item":148,"flag":1192},"NPC_GIFT_ROUTE_114_RECEIVED_BERRY":{"address":2051680,"default_item":149,"flag":1193},"NPC_GIFT_ROUTE_120_RECEIVED_BERRY":{"address":2064727,"default_item":143,"flag":1194},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_1":{"address":1998521,"default_item":153,"flag":1198},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_2":{"address":1998566,"default_item":143,"flag":1199},"POKEDEX_REWARD_001":{"address":5729368,"default_item":3,"flag":0},"POKEDEX_REWARD_002":{"address":5729370,"default_item":3,"flag":0},"POKEDEX_REWARD_003":{"address":5729372,"default_item":3,"flag":0},"POKEDEX_REWARD_004":{"address":5729374,"default_item":3,"flag":0},"POKEDEX_REWARD_005":{"address":5729376,"default_item":3,"flag":0},"POKEDEX_REWARD_006":{"address":5729378,"default_item":3,"flag":0},"POKEDEX_REWARD_007":{"address":5729380,"default_item":3,"flag":0},"POKEDEX_REWARD_008":{"address":5729382,"default_item":3,"flag":0},"POKEDEX_REWARD_009":{"address":5729384,"default_item":3,"flag":0},"POKEDEX_REWARD_010":{"address":5729386,"default_item":3,"flag":0},"POKEDEX_REWARD_011":{"address":5729388,"default_item":3,"flag":0},"POKEDEX_REWARD_012":{"address":5729390,"default_item":3,"flag":0},"POKEDEX_REWARD_013":{"address":5729392,"default_item":3,"flag":0},"POKEDEX_REWARD_014":{"address":5729394,"default_item":3,"flag":0},"POKEDEX_REWARD_015":{"address":5729396,"default_item":3,"flag":0},"POKEDEX_REWARD_016":{"address":5729398,"default_item":3,"flag":0},"POKEDEX_REWARD_017":{"address":5729400,"default_item":3,"flag":0},"POKEDEX_REWARD_018":{"address":5729402,"default_item":3,"flag":0},"POKEDEX_REWARD_019":{"address":5729404,"default_item":3,"flag":0},"POKEDEX_REWARD_020":{"address":5729406,"default_item":3,"flag":0},"POKEDEX_REWARD_021":{"address":5729408,"default_item":3,"flag":0},"POKEDEX_REWARD_022":{"address":5729410,"default_item":3,"flag":0},"POKEDEX_REWARD_023":{"address":5729412,"default_item":3,"flag":0},"POKEDEX_REWARD_024":{"address":5729414,"default_item":3,"flag":0},"POKEDEX_REWARD_025":{"address":5729416,"default_item":3,"flag":0},"POKEDEX_REWARD_026":{"address":5729418,"default_item":3,"flag":0},"POKEDEX_REWARD_027":{"address":5729420,"default_item":3,"flag":0},"POKEDEX_REWARD_028":{"address":5729422,"default_item":3,"flag":0},"POKEDEX_REWARD_029":{"address":5729424,"default_item":3,"flag":0},"POKEDEX_REWARD_030":{"address":5729426,"default_item":3,"flag":0},"POKEDEX_REWARD_031":{"address":5729428,"default_item":3,"flag":0},"POKEDEX_REWARD_032":{"address":5729430,"default_item":3,"flag":0},"POKEDEX_REWARD_033":{"address":5729432,"default_item":3,"flag":0},"POKEDEX_REWARD_034":{"address":5729434,"default_item":3,"flag":0},"POKEDEX_REWARD_035":{"address":5729436,"default_item":3,"flag":0},"POKEDEX_REWARD_036":{"address":5729438,"default_item":3,"flag":0},"POKEDEX_REWARD_037":{"address":5729440,"default_item":3,"flag":0},"POKEDEX_REWARD_038":{"address":5729442,"default_item":3,"flag":0},"POKEDEX_REWARD_039":{"address":5729444,"default_item":3,"flag":0},"POKEDEX_REWARD_040":{"address":5729446,"default_item":3,"flag":0},"POKEDEX_REWARD_041":{"address":5729448,"default_item":3,"flag":0},"POKEDEX_REWARD_042":{"address":5729450,"default_item":3,"flag":0},"POKEDEX_REWARD_043":{"address":5729452,"default_item":3,"flag":0},"POKEDEX_REWARD_044":{"address":5729454,"default_item":3,"flag":0},"POKEDEX_REWARD_045":{"address":5729456,"default_item":3,"flag":0},"POKEDEX_REWARD_046":{"address":5729458,"default_item":3,"flag":0},"POKEDEX_REWARD_047":{"address":5729460,"default_item":3,"flag":0},"POKEDEX_REWARD_048":{"address":5729462,"default_item":3,"flag":0},"POKEDEX_REWARD_049":{"address":5729464,"default_item":3,"flag":0},"POKEDEX_REWARD_050":{"address":5729466,"default_item":3,"flag":0},"POKEDEX_REWARD_051":{"address":5729468,"default_item":3,"flag":0},"POKEDEX_REWARD_052":{"address":5729470,"default_item":3,"flag":0},"POKEDEX_REWARD_053":{"address":5729472,"default_item":3,"flag":0},"POKEDEX_REWARD_054":{"address":5729474,"default_item":3,"flag":0},"POKEDEX_REWARD_055":{"address":5729476,"default_item":3,"flag":0},"POKEDEX_REWARD_056":{"address":5729478,"default_item":3,"flag":0},"POKEDEX_REWARD_057":{"address":5729480,"default_item":3,"flag":0},"POKEDEX_REWARD_058":{"address":5729482,"default_item":3,"flag":0},"POKEDEX_REWARD_059":{"address":5729484,"default_item":3,"flag":0},"POKEDEX_REWARD_060":{"address":5729486,"default_item":3,"flag":0},"POKEDEX_REWARD_061":{"address":5729488,"default_item":3,"flag":0},"POKEDEX_REWARD_062":{"address":5729490,"default_item":3,"flag":0},"POKEDEX_REWARD_063":{"address":5729492,"default_item":3,"flag":0},"POKEDEX_REWARD_064":{"address":5729494,"default_item":3,"flag":0},"POKEDEX_REWARD_065":{"address":5729496,"default_item":3,"flag":0},"POKEDEX_REWARD_066":{"address":5729498,"default_item":3,"flag":0},"POKEDEX_REWARD_067":{"address":5729500,"default_item":3,"flag":0},"POKEDEX_REWARD_068":{"address":5729502,"default_item":3,"flag":0},"POKEDEX_REWARD_069":{"address":5729504,"default_item":3,"flag":0},"POKEDEX_REWARD_070":{"address":5729506,"default_item":3,"flag":0},"POKEDEX_REWARD_071":{"address":5729508,"default_item":3,"flag":0},"POKEDEX_REWARD_072":{"address":5729510,"default_item":3,"flag":0},"POKEDEX_REWARD_073":{"address":5729512,"default_item":3,"flag":0},"POKEDEX_REWARD_074":{"address":5729514,"default_item":3,"flag":0},"POKEDEX_REWARD_075":{"address":5729516,"default_item":3,"flag":0},"POKEDEX_REWARD_076":{"address":5729518,"default_item":3,"flag":0},"POKEDEX_REWARD_077":{"address":5729520,"default_item":3,"flag":0},"POKEDEX_REWARD_078":{"address":5729522,"default_item":3,"flag":0},"POKEDEX_REWARD_079":{"address":5729524,"default_item":3,"flag":0},"POKEDEX_REWARD_080":{"address":5729526,"default_item":3,"flag":0},"POKEDEX_REWARD_081":{"address":5729528,"default_item":3,"flag":0},"POKEDEX_REWARD_082":{"address":5729530,"default_item":3,"flag":0},"POKEDEX_REWARD_083":{"address":5729532,"default_item":3,"flag":0},"POKEDEX_REWARD_084":{"address":5729534,"default_item":3,"flag":0},"POKEDEX_REWARD_085":{"address":5729536,"default_item":3,"flag":0},"POKEDEX_REWARD_086":{"address":5729538,"default_item":3,"flag":0},"POKEDEX_REWARD_087":{"address":5729540,"default_item":3,"flag":0},"POKEDEX_REWARD_088":{"address":5729542,"default_item":3,"flag":0},"POKEDEX_REWARD_089":{"address":5729544,"default_item":3,"flag":0},"POKEDEX_REWARD_090":{"address":5729546,"default_item":3,"flag":0},"POKEDEX_REWARD_091":{"address":5729548,"default_item":3,"flag":0},"POKEDEX_REWARD_092":{"address":5729550,"default_item":3,"flag":0},"POKEDEX_REWARD_093":{"address":5729552,"default_item":3,"flag":0},"POKEDEX_REWARD_094":{"address":5729554,"default_item":3,"flag":0},"POKEDEX_REWARD_095":{"address":5729556,"default_item":3,"flag":0},"POKEDEX_REWARD_096":{"address":5729558,"default_item":3,"flag":0},"POKEDEX_REWARD_097":{"address":5729560,"default_item":3,"flag":0},"POKEDEX_REWARD_098":{"address":5729562,"default_item":3,"flag":0},"POKEDEX_REWARD_099":{"address":5729564,"default_item":3,"flag":0},"POKEDEX_REWARD_100":{"address":5729566,"default_item":3,"flag":0},"POKEDEX_REWARD_101":{"address":5729568,"default_item":3,"flag":0},"POKEDEX_REWARD_102":{"address":5729570,"default_item":3,"flag":0},"POKEDEX_REWARD_103":{"address":5729572,"default_item":3,"flag":0},"POKEDEX_REWARD_104":{"address":5729574,"default_item":3,"flag":0},"POKEDEX_REWARD_105":{"address":5729576,"default_item":3,"flag":0},"POKEDEX_REWARD_106":{"address":5729578,"default_item":3,"flag":0},"POKEDEX_REWARD_107":{"address":5729580,"default_item":3,"flag":0},"POKEDEX_REWARD_108":{"address":5729582,"default_item":3,"flag":0},"POKEDEX_REWARD_109":{"address":5729584,"default_item":3,"flag":0},"POKEDEX_REWARD_110":{"address":5729586,"default_item":3,"flag":0},"POKEDEX_REWARD_111":{"address":5729588,"default_item":3,"flag":0},"POKEDEX_REWARD_112":{"address":5729590,"default_item":3,"flag":0},"POKEDEX_REWARD_113":{"address":5729592,"default_item":3,"flag":0},"POKEDEX_REWARD_114":{"address":5729594,"default_item":3,"flag":0},"POKEDEX_REWARD_115":{"address":5729596,"default_item":3,"flag":0},"POKEDEX_REWARD_116":{"address":5729598,"default_item":3,"flag":0},"POKEDEX_REWARD_117":{"address":5729600,"default_item":3,"flag":0},"POKEDEX_REWARD_118":{"address":5729602,"default_item":3,"flag":0},"POKEDEX_REWARD_119":{"address":5729604,"default_item":3,"flag":0},"POKEDEX_REWARD_120":{"address":5729606,"default_item":3,"flag":0},"POKEDEX_REWARD_121":{"address":5729608,"default_item":3,"flag":0},"POKEDEX_REWARD_122":{"address":5729610,"default_item":3,"flag":0},"POKEDEX_REWARD_123":{"address":5729612,"default_item":3,"flag":0},"POKEDEX_REWARD_124":{"address":5729614,"default_item":3,"flag":0},"POKEDEX_REWARD_125":{"address":5729616,"default_item":3,"flag":0},"POKEDEX_REWARD_126":{"address":5729618,"default_item":3,"flag":0},"POKEDEX_REWARD_127":{"address":5729620,"default_item":3,"flag":0},"POKEDEX_REWARD_128":{"address":5729622,"default_item":3,"flag":0},"POKEDEX_REWARD_129":{"address":5729624,"default_item":3,"flag":0},"POKEDEX_REWARD_130":{"address":5729626,"default_item":3,"flag":0},"POKEDEX_REWARD_131":{"address":5729628,"default_item":3,"flag":0},"POKEDEX_REWARD_132":{"address":5729630,"default_item":3,"flag":0},"POKEDEX_REWARD_133":{"address":5729632,"default_item":3,"flag":0},"POKEDEX_REWARD_134":{"address":5729634,"default_item":3,"flag":0},"POKEDEX_REWARD_135":{"address":5729636,"default_item":3,"flag":0},"POKEDEX_REWARD_136":{"address":5729638,"default_item":3,"flag":0},"POKEDEX_REWARD_137":{"address":5729640,"default_item":3,"flag":0},"POKEDEX_REWARD_138":{"address":5729642,"default_item":3,"flag":0},"POKEDEX_REWARD_139":{"address":5729644,"default_item":3,"flag":0},"POKEDEX_REWARD_140":{"address":5729646,"default_item":3,"flag":0},"POKEDEX_REWARD_141":{"address":5729648,"default_item":3,"flag":0},"POKEDEX_REWARD_142":{"address":5729650,"default_item":3,"flag":0},"POKEDEX_REWARD_143":{"address":5729652,"default_item":3,"flag":0},"POKEDEX_REWARD_144":{"address":5729654,"default_item":3,"flag":0},"POKEDEX_REWARD_145":{"address":5729656,"default_item":3,"flag":0},"POKEDEX_REWARD_146":{"address":5729658,"default_item":3,"flag":0},"POKEDEX_REWARD_147":{"address":5729660,"default_item":3,"flag":0},"POKEDEX_REWARD_148":{"address":5729662,"default_item":3,"flag":0},"POKEDEX_REWARD_149":{"address":5729664,"default_item":3,"flag":0},"POKEDEX_REWARD_150":{"address":5729666,"default_item":3,"flag":0},"POKEDEX_REWARD_151":{"address":5729668,"default_item":3,"flag":0},"POKEDEX_REWARD_152":{"address":5729670,"default_item":3,"flag":0},"POKEDEX_REWARD_153":{"address":5729672,"default_item":3,"flag":0},"POKEDEX_REWARD_154":{"address":5729674,"default_item":3,"flag":0},"POKEDEX_REWARD_155":{"address":5729676,"default_item":3,"flag":0},"POKEDEX_REWARD_156":{"address":5729678,"default_item":3,"flag":0},"POKEDEX_REWARD_157":{"address":5729680,"default_item":3,"flag":0},"POKEDEX_REWARD_158":{"address":5729682,"default_item":3,"flag":0},"POKEDEX_REWARD_159":{"address":5729684,"default_item":3,"flag":0},"POKEDEX_REWARD_160":{"address":5729686,"default_item":3,"flag":0},"POKEDEX_REWARD_161":{"address":5729688,"default_item":3,"flag":0},"POKEDEX_REWARD_162":{"address":5729690,"default_item":3,"flag":0},"POKEDEX_REWARD_163":{"address":5729692,"default_item":3,"flag":0},"POKEDEX_REWARD_164":{"address":5729694,"default_item":3,"flag":0},"POKEDEX_REWARD_165":{"address":5729696,"default_item":3,"flag":0},"POKEDEX_REWARD_166":{"address":5729698,"default_item":3,"flag":0},"POKEDEX_REWARD_167":{"address":5729700,"default_item":3,"flag":0},"POKEDEX_REWARD_168":{"address":5729702,"default_item":3,"flag":0},"POKEDEX_REWARD_169":{"address":5729704,"default_item":3,"flag":0},"POKEDEX_REWARD_170":{"address":5729706,"default_item":3,"flag":0},"POKEDEX_REWARD_171":{"address":5729708,"default_item":3,"flag":0},"POKEDEX_REWARD_172":{"address":5729710,"default_item":3,"flag":0},"POKEDEX_REWARD_173":{"address":5729712,"default_item":3,"flag":0},"POKEDEX_REWARD_174":{"address":5729714,"default_item":3,"flag":0},"POKEDEX_REWARD_175":{"address":5729716,"default_item":3,"flag":0},"POKEDEX_REWARD_176":{"address":5729718,"default_item":3,"flag":0},"POKEDEX_REWARD_177":{"address":5729720,"default_item":3,"flag":0},"POKEDEX_REWARD_178":{"address":5729722,"default_item":3,"flag":0},"POKEDEX_REWARD_179":{"address":5729724,"default_item":3,"flag":0},"POKEDEX_REWARD_180":{"address":5729726,"default_item":3,"flag":0},"POKEDEX_REWARD_181":{"address":5729728,"default_item":3,"flag":0},"POKEDEX_REWARD_182":{"address":5729730,"default_item":3,"flag":0},"POKEDEX_REWARD_183":{"address":5729732,"default_item":3,"flag":0},"POKEDEX_REWARD_184":{"address":5729734,"default_item":3,"flag":0},"POKEDEX_REWARD_185":{"address":5729736,"default_item":3,"flag":0},"POKEDEX_REWARD_186":{"address":5729738,"default_item":3,"flag":0},"POKEDEX_REWARD_187":{"address":5729740,"default_item":3,"flag":0},"POKEDEX_REWARD_188":{"address":5729742,"default_item":3,"flag":0},"POKEDEX_REWARD_189":{"address":5729744,"default_item":3,"flag":0},"POKEDEX_REWARD_190":{"address":5729746,"default_item":3,"flag":0},"POKEDEX_REWARD_191":{"address":5729748,"default_item":3,"flag":0},"POKEDEX_REWARD_192":{"address":5729750,"default_item":3,"flag":0},"POKEDEX_REWARD_193":{"address":5729752,"default_item":3,"flag":0},"POKEDEX_REWARD_194":{"address":5729754,"default_item":3,"flag":0},"POKEDEX_REWARD_195":{"address":5729756,"default_item":3,"flag":0},"POKEDEX_REWARD_196":{"address":5729758,"default_item":3,"flag":0},"POKEDEX_REWARD_197":{"address":5729760,"default_item":3,"flag":0},"POKEDEX_REWARD_198":{"address":5729762,"default_item":3,"flag":0},"POKEDEX_REWARD_199":{"address":5729764,"default_item":3,"flag":0},"POKEDEX_REWARD_200":{"address":5729766,"default_item":3,"flag":0},"POKEDEX_REWARD_201":{"address":5729768,"default_item":3,"flag":0},"POKEDEX_REWARD_202":{"address":5729770,"default_item":3,"flag":0},"POKEDEX_REWARD_203":{"address":5729772,"default_item":3,"flag":0},"POKEDEX_REWARD_204":{"address":5729774,"default_item":3,"flag":0},"POKEDEX_REWARD_205":{"address":5729776,"default_item":3,"flag":0},"POKEDEX_REWARD_206":{"address":5729778,"default_item":3,"flag":0},"POKEDEX_REWARD_207":{"address":5729780,"default_item":3,"flag":0},"POKEDEX_REWARD_208":{"address":5729782,"default_item":3,"flag":0},"POKEDEX_REWARD_209":{"address":5729784,"default_item":3,"flag":0},"POKEDEX_REWARD_210":{"address":5729786,"default_item":3,"flag":0},"POKEDEX_REWARD_211":{"address":5729788,"default_item":3,"flag":0},"POKEDEX_REWARD_212":{"address":5729790,"default_item":3,"flag":0},"POKEDEX_REWARD_213":{"address":5729792,"default_item":3,"flag":0},"POKEDEX_REWARD_214":{"address":5729794,"default_item":3,"flag":0},"POKEDEX_REWARD_215":{"address":5729796,"default_item":3,"flag":0},"POKEDEX_REWARD_216":{"address":5729798,"default_item":3,"flag":0},"POKEDEX_REWARD_217":{"address":5729800,"default_item":3,"flag":0},"POKEDEX_REWARD_218":{"address":5729802,"default_item":3,"flag":0},"POKEDEX_REWARD_219":{"address":5729804,"default_item":3,"flag":0},"POKEDEX_REWARD_220":{"address":5729806,"default_item":3,"flag":0},"POKEDEX_REWARD_221":{"address":5729808,"default_item":3,"flag":0},"POKEDEX_REWARD_222":{"address":5729810,"default_item":3,"flag":0},"POKEDEX_REWARD_223":{"address":5729812,"default_item":3,"flag":0},"POKEDEX_REWARD_224":{"address":5729814,"default_item":3,"flag":0},"POKEDEX_REWARD_225":{"address":5729816,"default_item":3,"flag":0},"POKEDEX_REWARD_226":{"address":5729818,"default_item":3,"flag":0},"POKEDEX_REWARD_227":{"address":5729820,"default_item":3,"flag":0},"POKEDEX_REWARD_228":{"address":5729822,"default_item":3,"flag":0},"POKEDEX_REWARD_229":{"address":5729824,"default_item":3,"flag":0},"POKEDEX_REWARD_230":{"address":5729826,"default_item":3,"flag":0},"POKEDEX_REWARD_231":{"address":5729828,"default_item":3,"flag":0},"POKEDEX_REWARD_232":{"address":5729830,"default_item":3,"flag":0},"POKEDEX_REWARD_233":{"address":5729832,"default_item":3,"flag":0},"POKEDEX_REWARD_234":{"address":5729834,"default_item":3,"flag":0},"POKEDEX_REWARD_235":{"address":5729836,"default_item":3,"flag":0},"POKEDEX_REWARD_236":{"address":5729838,"default_item":3,"flag":0},"POKEDEX_REWARD_237":{"address":5729840,"default_item":3,"flag":0},"POKEDEX_REWARD_238":{"address":5729842,"default_item":3,"flag":0},"POKEDEX_REWARD_239":{"address":5729844,"default_item":3,"flag":0},"POKEDEX_REWARD_240":{"address":5729846,"default_item":3,"flag":0},"POKEDEX_REWARD_241":{"address":5729848,"default_item":3,"flag":0},"POKEDEX_REWARD_242":{"address":5729850,"default_item":3,"flag":0},"POKEDEX_REWARD_243":{"address":5729852,"default_item":3,"flag":0},"POKEDEX_REWARD_244":{"address":5729854,"default_item":3,"flag":0},"POKEDEX_REWARD_245":{"address":5729856,"default_item":3,"flag":0},"POKEDEX_REWARD_246":{"address":5729858,"default_item":3,"flag":0},"POKEDEX_REWARD_247":{"address":5729860,"default_item":3,"flag":0},"POKEDEX_REWARD_248":{"address":5729862,"default_item":3,"flag":0},"POKEDEX_REWARD_249":{"address":5729864,"default_item":3,"flag":0},"POKEDEX_REWARD_250":{"address":5729866,"default_item":3,"flag":0},"POKEDEX_REWARD_251":{"address":5729868,"default_item":3,"flag":0},"POKEDEX_REWARD_252":{"address":5729870,"default_item":3,"flag":0},"POKEDEX_REWARD_253":{"address":5729872,"default_item":3,"flag":0},"POKEDEX_REWARD_254":{"address":5729874,"default_item":3,"flag":0},"POKEDEX_REWARD_255":{"address":5729876,"default_item":3,"flag":0},"POKEDEX_REWARD_256":{"address":5729878,"default_item":3,"flag":0},"POKEDEX_REWARD_257":{"address":5729880,"default_item":3,"flag":0},"POKEDEX_REWARD_258":{"address":5729882,"default_item":3,"flag":0},"POKEDEX_REWARD_259":{"address":5729884,"default_item":3,"flag":0},"POKEDEX_REWARD_260":{"address":5729886,"default_item":3,"flag":0},"POKEDEX_REWARD_261":{"address":5729888,"default_item":3,"flag":0},"POKEDEX_REWARD_262":{"address":5729890,"default_item":3,"flag":0},"POKEDEX_REWARD_263":{"address":5729892,"default_item":3,"flag":0},"POKEDEX_REWARD_264":{"address":5729894,"default_item":3,"flag":0},"POKEDEX_REWARD_265":{"address":5729896,"default_item":3,"flag":0},"POKEDEX_REWARD_266":{"address":5729898,"default_item":3,"flag":0},"POKEDEX_REWARD_267":{"address":5729900,"default_item":3,"flag":0},"POKEDEX_REWARD_268":{"address":5729902,"default_item":3,"flag":0},"POKEDEX_REWARD_269":{"address":5729904,"default_item":3,"flag":0},"POKEDEX_REWARD_270":{"address":5729906,"default_item":3,"flag":0},"POKEDEX_REWARD_271":{"address":5729908,"default_item":3,"flag":0},"POKEDEX_REWARD_272":{"address":5729910,"default_item":3,"flag":0},"POKEDEX_REWARD_273":{"address":5729912,"default_item":3,"flag":0},"POKEDEX_REWARD_274":{"address":5729914,"default_item":3,"flag":0},"POKEDEX_REWARD_275":{"address":5729916,"default_item":3,"flag":0},"POKEDEX_REWARD_276":{"address":5729918,"default_item":3,"flag":0},"POKEDEX_REWARD_277":{"address":5729920,"default_item":3,"flag":0},"POKEDEX_REWARD_278":{"address":5729922,"default_item":3,"flag":0},"POKEDEX_REWARD_279":{"address":5729924,"default_item":3,"flag":0},"POKEDEX_REWARD_280":{"address":5729926,"default_item":3,"flag":0},"POKEDEX_REWARD_281":{"address":5729928,"default_item":3,"flag":0},"POKEDEX_REWARD_282":{"address":5729930,"default_item":3,"flag":0},"POKEDEX_REWARD_283":{"address":5729932,"default_item":3,"flag":0},"POKEDEX_REWARD_284":{"address":5729934,"default_item":3,"flag":0},"POKEDEX_REWARD_285":{"address":5729936,"default_item":3,"flag":0},"POKEDEX_REWARD_286":{"address":5729938,"default_item":3,"flag":0},"POKEDEX_REWARD_287":{"address":5729940,"default_item":3,"flag":0},"POKEDEX_REWARD_288":{"address":5729942,"default_item":3,"flag":0},"POKEDEX_REWARD_289":{"address":5729944,"default_item":3,"flag":0},"POKEDEX_REWARD_290":{"address":5729946,"default_item":3,"flag":0},"POKEDEX_REWARD_291":{"address":5729948,"default_item":3,"flag":0},"POKEDEX_REWARD_292":{"address":5729950,"default_item":3,"flag":0},"POKEDEX_REWARD_293":{"address":5729952,"default_item":3,"flag":0},"POKEDEX_REWARD_294":{"address":5729954,"default_item":3,"flag":0},"POKEDEX_REWARD_295":{"address":5729956,"default_item":3,"flag":0},"POKEDEX_REWARD_296":{"address":5729958,"default_item":3,"flag":0},"POKEDEX_REWARD_297":{"address":5729960,"default_item":3,"flag":0},"POKEDEX_REWARD_298":{"address":5729962,"default_item":3,"flag":0},"POKEDEX_REWARD_299":{"address":5729964,"default_item":3,"flag":0},"POKEDEX_REWARD_300":{"address":5729966,"default_item":3,"flag":0},"POKEDEX_REWARD_301":{"address":5729968,"default_item":3,"flag":0},"POKEDEX_REWARD_302":{"address":5729970,"default_item":3,"flag":0},"POKEDEX_REWARD_303":{"address":5729972,"default_item":3,"flag":0},"POKEDEX_REWARD_304":{"address":5729974,"default_item":3,"flag":0},"POKEDEX_REWARD_305":{"address":5729976,"default_item":3,"flag":0},"POKEDEX_REWARD_306":{"address":5729978,"default_item":3,"flag":0},"POKEDEX_REWARD_307":{"address":5729980,"default_item":3,"flag":0},"POKEDEX_REWARD_308":{"address":5729982,"default_item":3,"flag":0},"POKEDEX_REWARD_309":{"address":5729984,"default_item":3,"flag":0},"POKEDEX_REWARD_310":{"address":5729986,"default_item":3,"flag":0},"POKEDEX_REWARD_311":{"address":5729988,"default_item":3,"flag":0},"POKEDEX_REWARD_312":{"address":5729990,"default_item":3,"flag":0},"POKEDEX_REWARD_313":{"address":5729992,"default_item":3,"flag":0},"POKEDEX_REWARD_314":{"address":5729994,"default_item":3,"flag":0},"POKEDEX_REWARD_315":{"address":5729996,"default_item":3,"flag":0},"POKEDEX_REWARD_316":{"address":5729998,"default_item":3,"flag":0},"POKEDEX_REWARD_317":{"address":5730000,"default_item":3,"flag":0},"POKEDEX_REWARD_318":{"address":5730002,"default_item":3,"flag":0},"POKEDEX_REWARD_319":{"address":5730004,"default_item":3,"flag":0},"POKEDEX_REWARD_320":{"address":5730006,"default_item":3,"flag":0},"POKEDEX_REWARD_321":{"address":5730008,"default_item":3,"flag":0},"POKEDEX_REWARD_322":{"address":5730010,"default_item":3,"flag":0},"POKEDEX_REWARD_323":{"address":5730012,"default_item":3,"flag":0},"POKEDEX_REWARD_324":{"address":5730014,"default_item":3,"flag":0},"POKEDEX_REWARD_325":{"address":5730016,"default_item":3,"flag":0},"POKEDEX_REWARD_326":{"address":5730018,"default_item":3,"flag":0},"POKEDEX_REWARD_327":{"address":5730020,"default_item":3,"flag":0},"POKEDEX_REWARD_328":{"address":5730022,"default_item":3,"flag":0},"POKEDEX_REWARD_329":{"address":5730024,"default_item":3,"flag":0},"POKEDEX_REWARD_330":{"address":5730026,"default_item":3,"flag":0},"POKEDEX_REWARD_331":{"address":5730028,"default_item":3,"flag":0},"POKEDEX_REWARD_332":{"address":5730030,"default_item":3,"flag":0},"POKEDEX_REWARD_333":{"address":5730032,"default_item":3,"flag":0},"POKEDEX_REWARD_334":{"address":5730034,"default_item":3,"flag":0},"POKEDEX_REWARD_335":{"address":5730036,"default_item":3,"flag":0},"POKEDEX_REWARD_336":{"address":5730038,"default_item":3,"flag":0},"POKEDEX_REWARD_337":{"address":5730040,"default_item":3,"flag":0},"POKEDEX_REWARD_338":{"address":5730042,"default_item":3,"flag":0},"POKEDEX_REWARD_339":{"address":5730044,"default_item":3,"flag":0},"POKEDEX_REWARD_340":{"address":5730046,"default_item":3,"flag":0},"POKEDEX_REWARD_341":{"address":5730048,"default_item":3,"flag":0},"POKEDEX_REWARD_342":{"address":5730050,"default_item":3,"flag":0},"POKEDEX_REWARD_343":{"address":5730052,"default_item":3,"flag":0},"POKEDEX_REWARD_344":{"address":5730054,"default_item":3,"flag":0},"POKEDEX_REWARD_345":{"address":5730056,"default_item":3,"flag":0},"POKEDEX_REWARD_346":{"address":5730058,"default_item":3,"flag":0},"POKEDEX_REWARD_347":{"address":5730060,"default_item":3,"flag":0},"POKEDEX_REWARD_348":{"address":5730062,"default_item":3,"flag":0},"POKEDEX_REWARD_349":{"address":5730064,"default_item":3,"flag":0},"POKEDEX_REWARD_350":{"address":5730066,"default_item":3,"flag":0},"POKEDEX_REWARD_351":{"address":5730068,"default_item":3,"flag":0},"POKEDEX_REWARD_352":{"address":5730070,"default_item":3,"flag":0},"POKEDEX_REWARD_353":{"address":5730072,"default_item":3,"flag":0},"POKEDEX_REWARD_354":{"address":5730074,"default_item":3,"flag":0},"POKEDEX_REWARD_355":{"address":5730076,"default_item":3,"flag":0},"POKEDEX_REWARD_356":{"address":5730078,"default_item":3,"flag":0},"POKEDEX_REWARD_357":{"address":5730080,"default_item":3,"flag":0},"POKEDEX_REWARD_358":{"address":5730082,"default_item":3,"flag":0},"POKEDEX_REWARD_359":{"address":5730084,"default_item":3,"flag":0},"POKEDEX_REWARD_360":{"address":5730086,"default_item":3,"flag":0},"POKEDEX_REWARD_361":{"address":5730088,"default_item":3,"flag":0},"POKEDEX_REWARD_362":{"address":5730090,"default_item":3,"flag":0},"POKEDEX_REWARD_363":{"address":5730092,"default_item":3,"flag":0},"POKEDEX_REWARD_364":{"address":5730094,"default_item":3,"flag":0},"POKEDEX_REWARD_365":{"address":5730096,"default_item":3,"flag":0},"POKEDEX_REWARD_366":{"address":5730098,"default_item":3,"flag":0},"POKEDEX_REWARD_367":{"address":5730100,"default_item":3,"flag":0},"POKEDEX_REWARD_368":{"address":5730102,"default_item":3,"flag":0},"POKEDEX_REWARD_369":{"address":5730104,"default_item":3,"flag":0},"POKEDEX_REWARD_370":{"address":5730106,"default_item":3,"flag":0},"POKEDEX_REWARD_371":{"address":5730108,"default_item":3,"flag":0},"POKEDEX_REWARD_372":{"address":5730110,"default_item":3,"flag":0},"POKEDEX_REWARD_373":{"address":5730112,"default_item":3,"flag":0},"POKEDEX_REWARD_374":{"address":5730114,"default_item":3,"flag":0},"POKEDEX_REWARD_375":{"address":5730116,"default_item":3,"flag":0},"POKEDEX_REWARD_376":{"address":5730118,"default_item":3,"flag":0},"POKEDEX_REWARD_377":{"address":5730120,"default_item":3,"flag":0},"POKEDEX_REWARD_378":{"address":5730122,"default_item":3,"flag":0},"POKEDEX_REWARD_379":{"address":5730124,"default_item":3,"flag":0},"POKEDEX_REWARD_380":{"address":5730126,"default_item":3,"flag":0},"POKEDEX_REWARD_381":{"address":5730128,"default_item":3,"flag":0},"POKEDEX_REWARD_382":{"address":5730130,"default_item":3,"flag":0},"POKEDEX_REWARD_383":{"address":5730132,"default_item":3,"flag":0},"POKEDEX_REWARD_384":{"address":5730134,"default_item":3,"flag":0},"POKEDEX_REWARD_385":{"address":5730136,"default_item":3,"flag":0},"POKEDEX_REWARD_386":{"address":5730138,"default_item":3,"flag":0},"TRAINER_AARON_REWARD":{"address":5602878,"default_item":104,"flag":1677},"TRAINER_ABIGAIL_1_REWARD":{"address":5602800,"default_item":106,"flag":1638},"TRAINER_AIDAN_REWARD":{"address":5603432,"default_item":104,"flag":1954},"TRAINER_AISHA_REWARD":{"address":5603598,"default_item":106,"flag":2037},"TRAINER_ALBERTO_REWARD":{"address":5602108,"default_item":108,"flag":1292},"TRAINER_ALBERT_REWARD":{"address":5602244,"default_item":104,"flag":1360},"TRAINER_ALEXA_REWARD":{"address":5603424,"default_item":104,"flag":1950},"TRAINER_ALEXIA_REWARD":{"address":5602264,"default_item":104,"flag":1370},"TRAINER_ALEX_REWARD":{"address":5602910,"default_item":104,"flag":1693},"TRAINER_ALICE_REWARD":{"address":5602980,"default_item":103,"flag":1728},"TRAINER_ALIX_REWARD":{"address":5603584,"default_item":106,"flag":2030},"TRAINER_ALLEN_REWARD":{"address":5602750,"default_item":103,"flag":1613},"TRAINER_ALLISON_REWARD":{"address":5602858,"default_item":104,"flag":1667},"TRAINER_ALYSSA_REWARD":{"address":5603486,"default_item":106,"flag":1981},"TRAINER_AMY_AND_LIV_1_REWARD":{"address":5603046,"default_item":103,"flag":1761},"TRAINER_ANDREA_REWARD":{"address":5603310,"default_item":106,"flag":1893},"TRAINER_ANDRES_1_REWARD":{"address":5603558,"default_item":104,"flag":2017},"TRAINER_ANDREW_REWARD":{"address":5602756,"default_item":106,"flag":1616},"TRAINER_ANGELICA_REWARD":{"address":5602956,"default_item":104,"flag":1716},"TRAINER_ANGELINA_REWARD":{"address":5603508,"default_item":106,"flag":1992},"TRAINER_ANGELO_REWARD":{"address":5603688,"default_item":104,"flag":2082},"TRAINER_ANNA_AND_MEG_1_REWARD":{"address":5602658,"default_item":106,"flag":1567},"TRAINER_ANNIKA_REWARD":{"address":5603088,"default_item":107,"flag":1782},"TRAINER_ANTHONY_REWARD":{"address":5602788,"default_item":106,"flag":1632},"TRAINER_ARCHIE_REWARD":{"address":5602152,"default_item":107,"flag":1314},"TRAINER_ASHLEY_REWARD":{"address":5603394,"default_item":106,"flag":1935},"TRAINER_ATHENA_REWARD":{"address":5603238,"default_item":104,"flag":1857},"TRAINER_ATSUSHI_REWARD":{"address":5602464,"default_item":104,"flag":1470},"TRAINER_AURON_REWARD":{"address":5603096,"default_item":104,"flag":1786},"TRAINER_AUSTINA_REWARD":{"address":5602200,"default_item":103,"flag":1338},"TRAINER_AUTUMN_REWARD":{"address":5602518,"default_item":106,"flag":1497},"TRAINER_AXLE_REWARD":{"address":5602490,"default_item":108,"flag":1483},"TRAINER_BARNY_REWARD":{"address":5602770,"default_item":104,"flag":1623},"TRAINER_BARRY_REWARD":{"address":5602410,"default_item":106,"flag":1443},"TRAINER_BEAU_REWARD":{"address":5602508,"default_item":106,"flag":1492},"TRAINER_BECKY_REWARD":{"address":5603024,"default_item":106,"flag":1750},"TRAINER_BECK_REWARD":{"address":5602912,"default_item":104,"flag":1694},"TRAINER_BENJAMIN_1_REWARD":{"address":5602790,"default_item":106,"flag":1633},"TRAINER_BEN_REWARD":{"address":5602730,"default_item":106,"flag":1603},"TRAINER_BERKE_REWARD":{"address":5602232,"default_item":104,"flag":1354},"TRAINER_BERNIE_1_REWARD":{"address":5602496,"default_item":106,"flag":1486},"TRAINER_BETHANY_REWARD":{"address":5602686,"default_item":107,"flag":1581},"TRAINER_BETH_REWARD":{"address":5602974,"default_item":103,"flag":1725},"TRAINER_BEVERLY_REWARD":{"address":5602966,"default_item":103,"flag":1721},"TRAINER_BIANCA_REWARD":{"address":5603496,"default_item":106,"flag":1986},"TRAINER_BILLY_REWARD":{"address":5602722,"default_item":103,"flag":1599},"TRAINER_BLAKE_REWARD":{"address":5602554,"default_item":108,"flag":1515},"TRAINER_BRANDEN_REWARD":{"address":5603574,"default_item":106,"flag":2025},"TRAINER_BRANDI_REWARD":{"address":5603596,"default_item":106,"flag":2036},"TRAINER_BRAWLY_1_REWARD":{"address":5602616,"default_item":104,"flag":1546},"TRAINER_BRAXTON_REWARD":{"address":5602234,"default_item":104,"flag":1355},"TRAINER_BRENDAN_LILYCOVE_MUDKIP_REWARD":{"address":5603406,"default_item":104,"flag":1941},"TRAINER_BRENDAN_LILYCOVE_TORCHIC_REWARD":{"address":5603410,"default_item":104,"flag":1943},"TRAINER_BRENDAN_LILYCOVE_TREECKO_REWARD":{"address":5603408,"default_item":104,"flag":1942},"TRAINER_BRENDAN_ROUTE_103_MUDKIP_REWARD":{"address":5603124,"default_item":106,"flag":1800},"TRAINER_BRENDAN_ROUTE_103_TORCHIC_REWARD":{"address":5603136,"default_item":106,"flag":1806},"TRAINER_BRENDAN_ROUTE_103_TREECKO_REWARD":{"address":5603130,"default_item":106,"flag":1803},"TRAINER_BRENDAN_ROUTE_110_MUDKIP_REWARD":{"address":5603126,"default_item":104,"flag":1801},"TRAINER_BRENDAN_ROUTE_110_TORCHIC_REWARD":{"address":5603138,"default_item":104,"flag":1807},"TRAINER_BRENDAN_ROUTE_110_TREECKO_REWARD":{"address":5603132,"default_item":104,"flag":1804},"TRAINER_BRENDAN_ROUTE_119_MUDKIP_REWARD":{"address":5603128,"default_item":104,"flag":1802},"TRAINER_BRENDAN_ROUTE_119_TORCHIC_REWARD":{"address":5603140,"default_item":104,"flag":1808},"TRAINER_BRENDAN_ROUTE_119_TREECKO_REWARD":{"address":5603134,"default_item":104,"flag":1805},"TRAINER_BRENDAN_RUSTBORO_MUDKIP_REWARD":{"address":5603270,"default_item":108,"flag":1873},"TRAINER_BRENDAN_RUSTBORO_TORCHIC_REWARD":{"address":5603282,"default_item":108,"flag":1879},"TRAINER_BRENDAN_RUSTBORO_TREECKO_REWARD":{"address":5603268,"default_item":108,"flag":1872},"TRAINER_BRENDA_REWARD":{"address":5602992,"default_item":106,"flag":1734},"TRAINER_BRENDEN_REWARD":{"address":5603228,"default_item":106,"flag":1852},"TRAINER_BRENT_REWARD":{"address":5602530,"default_item":104,"flag":1503},"TRAINER_BRIANNA_REWARD":{"address":5602320,"default_item":110,"flag":1398},"TRAINER_BRICE_REWARD":{"address":5603336,"default_item":106,"flag":1906},"TRAINER_BRIDGET_REWARD":{"address":5602342,"default_item":107,"flag":1409},"TRAINER_BROOKE_1_REWARD":{"address":5602272,"default_item":108,"flag":1374},"TRAINER_BRYANT_REWARD":{"address":5603576,"default_item":106,"flag":2026},"TRAINER_BRYAN_REWARD":{"address":5603572,"default_item":104,"flag":2024},"TRAINER_CALE_REWARD":{"address":5603612,"default_item":104,"flag":2044},"TRAINER_CALLIE_REWARD":{"address":5603610,"default_item":106,"flag":2043},"TRAINER_CALVIN_1_REWARD":{"address":5602720,"default_item":103,"flag":1598},"TRAINER_CAMDEN_REWARD":{"address":5602832,"default_item":104,"flag":1654},"TRAINER_CAMERON_1_REWARD":{"address":5602560,"default_item":108,"flag":1518},"TRAINER_CAMRON_REWARD":{"address":5603562,"default_item":104,"flag":2019},"TRAINER_CARLEE_REWARD":{"address":5603012,"default_item":106,"flag":1744},"TRAINER_CAROLINA_REWARD":{"address":5603566,"default_item":104,"flag":2021},"TRAINER_CAROLINE_REWARD":{"address":5602282,"default_item":104,"flag":1379},"TRAINER_CAROL_REWARD":{"address":5603026,"default_item":106,"flag":1751},"TRAINER_CARTER_REWARD":{"address":5602774,"default_item":104,"flag":1625},"TRAINER_CATHERINE_1_REWARD":{"address":5603202,"default_item":104,"flag":1839},"TRAINER_CEDRIC_REWARD":{"address":5603034,"default_item":108,"flag":1755},"TRAINER_CELIA_REWARD":{"address":5603570,"default_item":106,"flag":2023},"TRAINER_CELINA_REWARD":{"address":5603494,"default_item":108,"flag":1985},"TRAINER_CHAD_REWARD":{"address":5602432,"default_item":106,"flag":1454},"TRAINER_CHANDLER_REWARD":{"address":5603480,"default_item":103,"flag":1978},"TRAINER_CHARLIE_REWARD":{"address":5602216,"default_item":103,"flag":1346},"TRAINER_CHARLOTTE_REWARD":{"address":5603512,"default_item":106,"flag":1994},"TRAINER_CHASE_REWARD":{"address":5602840,"default_item":104,"flag":1658},"TRAINER_CHESTER_REWARD":{"address":5602900,"default_item":108,"flag":1688},"TRAINER_CHIP_REWARD":{"address":5602174,"default_item":104,"flag":1325},"TRAINER_CHRIS_REWARD":{"address":5603470,"default_item":108,"flag":1973},"TRAINER_CINDY_1_REWARD":{"address":5602312,"default_item":104,"flag":1394},"TRAINER_CLARENCE_REWARD":{"address":5603244,"default_item":106,"flag":1860},"TRAINER_CLARISSA_REWARD":{"address":5602954,"default_item":104,"flag":1715},"TRAINER_CLARK_REWARD":{"address":5603346,"default_item":106,"flag":1911},"TRAINER_CLAUDE_REWARD":{"address":5602760,"default_item":108,"flag":1618},"TRAINER_CLIFFORD_REWARD":{"address":5603252,"default_item":107,"flag":1864},"TRAINER_COBY_REWARD":{"address":5603502,"default_item":106,"flag":1989},"TRAINER_COLE_REWARD":{"address":5602486,"default_item":108,"flag":1481},"TRAINER_COLIN_REWARD":{"address":5602894,"default_item":108,"flag":1685},"TRAINER_COLTON_REWARD":{"address":5602672,"default_item":107,"flag":1574},"TRAINER_CONNIE_REWARD":{"address":5602340,"default_item":107,"flag":1408},"TRAINER_CONOR_REWARD":{"address":5603106,"default_item":104,"flag":1791},"TRAINER_CORY_1_REWARD":{"address":5603564,"default_item":108,"flag":2020},"TRAINER_CRISSY_REWARD":{"address":5603312,"default_item":106,"flag":1894},"TRAINER_CRISTIAN_REWARD":{"address":5603232,"default_item":106,"flag":1854},"TRAINER_CRISTIN_1_REWARD":{"address":5603618,"default_item":104,"flag":2047},"TRAINER_CYNDY_1_REWARD":{"address":5602938,"default_item":106,"flag":1707},"TRAINER_DAISUKE_REWARD":{"address":5602462,"default_item":106,"flag":1469},"TRAINER_DAISY_REWARD":{"address":5602156,"default_item":106,"flag":1316},"TRAINER_DALE_REWARD":{"address":5602766,"default_item":106,"flag":1621},"TRAINER_DALTON_1_REWARD":{"address":5602476,"default_item":106,"flag":1476},"TRAINER_DANA_REWARD":{"address":5603000,"default_item":106,"flag":1738},"TRAINER_DANIELLE_REWARD":{"address":5603384,"default_item":106,"flag":1930},"TRAINER_DAPHNE_REWARD":{"address":5602314,"default_item":110,"flag":1395},"TRAINER_DARCY_REWARD":{"address":5603550,"default_item":104,"flag":2013},"TRAINER_DARIAN_REWARD":{"address":5603476,"default_item":106,"flag":1976},"TRAINER_DARIUS_REWARD":{"address":5603690,"default_item":108,"flag":2083},"TRAINER_DARRIN_REWARD":{"address":5602392,"default_item":103,"flag":1434},"TRAINER_DAVID_REWARD":{"address":5602400,"default_item":103,"flag":1438},"TRAINER_DAVIS_REWARD":{"address":5603162,"default_item":106,"flag":1819},"TRAINER_DAWSON_REWARD":{"address":5603472,"default_item":104,"flag":1974},"TRAINER_DAYTON_REWARD":{"address":5603604,"default_item":108,"flag":2040},"TRAINER_DEANDRE_REWARD":{"address":5603514,"default_item":103,"flag":1995},"TRAINER_DEAN_REWARD":{"address":5602412,"default_item":103,"flag":1444},"TRAINER_DEBRA_REWARD":{"address":5603004,"default_item":106,"flag":1740},"TRAINER_DECLAN_REWARD":{"address":5602114,"default_item":106,"flag":1295},"TRAINER_DEMETRIUS_REWARD":{"address":5602834,"default_item":106,"flag":1655},"TRAINER_DENISE_REWARD":{"address":5602972,"default_item":103,"flag":1724},"TRAINER_DEREK_REWARD":{"address":5602538,"default_item":108,"flag":1507},"TRAINER_DEVAN_REWARD":{"address":5603590,"default_item":106,"flag":2033},"TRAINER_DEZ_AND_LUKE_REWARD":{"address":5603364,"default_item":108,"flag":1920},"TRAINER_DIANA_1_REWARD":{"address":5603032,"default_item":106,"flag":1754},"TRAINER_DIANNE_REWARD":{"address":5602918,"default_item":104,"flag":1697},"TRAINER_DILLON_REWARD":{"address":5602738,"default_item":106,"flag":1607},"TRAINER_DOMINIK_REWARD":{"address":5602388,"default_item":103,"flag":1432},"TRAINER_DONALD_REWARD":{"address":5602532,"default_item":104,"flag":1504},"TRAINER_DONNY_REWARD":{"address":5602852,"default_item":104,"flag":1664},"TRAINER_DOUGLAS_REWARD":{"address":5602390,"default_item":103,"flag":1433},"TRAINER_DOUG_REWARD":{"address":5603320,"default_item":106,"flag":1898},"TRAINER_DRAKE_REWARD":{"address":5602612,"default_item":110,"flag":1544},"TRAINER_DREW_REWARD":{"address":5602506,"default_item":106,"flag":1491},"TRAINER_DUNCAN_REWARD":{"address":5603076,"default_item":108,"flag":1776},"TRAINER_DUSTY_1_REWARD":{"address":5602172,"default_item":104,"flag":1324},"TRAINER_DWAYNE_REWARD":{"address":5603070,"default_item":106,"flag":1773},"TRAINER_DYLAN_1_REWARD":{"address":5602812,"default_item":106,"flag":1644},"TRAINER_EDGAR_REWARD":{"address":5602242,"default_item":104,"flag":1359},"TRAINER_EDMOND_REWARD":{"address":5603066,"default_item":106,"flag":1771},"TRAINER_EDWARDO_REWARD":{"address":5602892,"default_item":108,"flag":1684},"TRAINER_EDWARD_REWARD":{"address":5602548,"default_item":106,"flag":1512},"TRAINER_EDWIN_1_REWARD":{"address":5603108,"default_item":108,"flag":1792},"TRAINER_ED_REWARD":{"address":5602110,"default_item":104,"flag":1293},"TRAINER_ELIJAH_REWARD":{"address":5603568,"default_item":108,"flag":2022},"TRAINER_ELI_REWARD":{"address":5603086,"default_item":108,"flag":1781},"TRAINER_ELLIOT_1_REWARD":{"address":5602762,"default_item":106,"flag":1619},"TRAINER_ERIC_REWARD":{"address":5603348,"default_item":108,"flag":1912},"TRAINER_ERNEST_1_REWARD":{"address":5603068,"default_item":104,"flag":1772},"TRAINER_ETHAN_1_REWARD":{"address":5602516,"default_item":106,"flag":1496},"TRAINER_FABIAN_REWARD":{"address":5603602,"default_item":108,"flag":2039},"TRAINER_FELIX_REWARD":{"address":5602160,"default_item":104,"flag":1318},"TRAINER_FERNANDO_1_REWARD":{"address":5602474,"default_item":108,"flag":1475},"TRAINER_FLANNERY_1_REWARD":{"address":5602620,"default_item":107,"flag":1548},"TRAINER_FLINT_REWARD":{"address":5603392,"default_item":106,"flag":1934},"TRAINER_FOSTER_REWARD":{"address":5602176,"default_item":104,"flag":1326},"TRAINER_FRANKLIN_REWARD":{"address":5602424,"default_item":106,"flag":1450},"TRAINER_FREDRICK_REWARD":{"address":5602142,"default_item":104,"flag":1309},"TRAINER_GABRIELLE_1_REWARD":{"address":5602102,"default_item":104,"flag":1289},"TRAINER_GARRET_REWARD":{"address":5602360,"default_item":110,"flag":1418},"TRAINER_GARRISON_REWARD":{"address":5603178,"default_item":104,"flag":1827},"TRAINER_GEORGE_REWARD":{"address":5602230,"default_item":104,"flag":1353},"TRAINER_GERALD_REWARD":{"address":5603380,"default_item":104,"flag":1928},"TRAINER_GILBERT_REWARD":{"address":5602422,"default_item":106,"flag":1449},"TRAINER_GINA_AND_MIA_1_REWARD":{"address":5603050,"default_item":103,"flag":1763},"TRAINER_GLACIA_REWARD":{"address":5602610,"default_item":110,"flag":1543},"TRAINER_GRACE_REWARD":{"address":5602984,"default_item":106,"flag":1730},"TRAINER_GREG_REWARD":{"address":5603322,"default_item":106,"flag":1899},"TRAINER_GRUNT_AQUA_HIDEOUT_1_REWARD":{"address":5602088,"default_item":106,"flag":1282},"TRAINER_GRUNT_AQUA_HIDEOUT_2_REWARD":{"address":5602090,"default_item":106,"flag":1283},"TRAINER_GRUNT_AQUA_HIDEOUT_3_REWARD":{"address":5602092,"default_item":106,"flag":1284},"TRAINER_GRUNT_AQUA_HIDEOUT_4_REWARD":{"address":5602094,"default_item":106,"flag":1285},"TRAINER_GRUNT_AQUA_HIDEOUT_5_REWARD":{"address":5602138,"default_item":106,"flag":1307},"TRAINER_GRUNT_AQUA_HIDEOUT_6_REWARD":{"address":5602140,"default_item":106,"flag":1308},"TRAINER_GRUNT_AQUA_HIDEOUT_7_REWARD":{"address":5602468,"default_item":106,"flag":1472},"TRAINER_GRUNT_AQUA_HIDEOUT_8_REWARD":{"address":5602470,"default_item":106,"flag":1473},"TRAINER_GRUNT_MAGMA_HIDEOUT_10_REWARD":{"address":5603534,"default_item":106,"flag":2005},"TRAINER_GRUNT_MAGMA_HIDEOUT_11_REWARD":{"address":5603536,"default_item":106,"flag":2006},"TRAINER_GRUNT_MAGMA_HIDEOUT_12_REWARD":{"address":5603538,"default_item":106,"flag":2007},"TRAINER_GRUNT_MAGMA_HIDEOUT_13_REWARD":{"address":5603540,"default_item":106,"flag":2008},"TRAINER_GRUNT_MAGMA_HIDEOUT_14_REWARD":{"address":5603542,"default_item":106,"flag":2009},"TRAINER_GRUNT_MAGMA_HIDEOUT_15_REWARD":{"address":5603544,"default_item":106,"flag":2010},"TRAINER_GRUNT_MAGMA_HIDEOUT_16_REWARD":{"address":5603546,"default_item":106,"flag":2011},"TRAINER_GRUNT_MAGMA_HIDEOUT_1_REWARD":{"address":5603516,"default_item":106,"flag":1996},"TRAINER_GRUNT_MAGMA_HIDEOUT_2_REWARD":{"address":5603518,"default_item":106,"flag":1997},"TRAINER_GRUNT_MAGMA_HIDEOUT_3_REWARD":{"address":5603520,"default_item":106,"flag":1998},"TRAINER_GRUNT_MAGMA_HIDEOUT_4_REWARD":{"address":5603522,"default_item":106,"flag":1999},"TRAINER_GRUNT_MAGMA_HIDEOUT_5_REWARD":{"address":5603524,"default_item":106,"flag":2000},"TRAINER_GRUNT_MAGMA_HIDEOUT_6_REWARD":{"address":5603526,"default_item":106,"flag":2001},"TRAINER_GRUNT_MAGMA_HIDEOUT_7_REWARD":{"address":5603528,"default_item":106,"flag":2002},"TRAINER_GRUNT_MAGMA_HIDEOUT_8_REWARD":{"address":5603530,"default_item":106,"flag":2003},"TRAINER_GRUNT_MAGMA_HIDEOUT_9_REWARD":{"address":5603532,"default_item":106,"flag":2004},"TRAINER_GRUNT_MT_CHIMNEY_1_REWARD":{"address":5602376,"default_item":106,"flag":1426},"TRAINER_GRUNT_MT_CHIMNEY_2_REWARD":{"address":5603242,"default_item":106,"flag":1859},"TRAINER_GRUNT_MT_PYRE_1_REWARD":{"address":5602130,"default_item":106,"flag":1303},"TRAINER_GRUNT_MT_PYRE_2_REWARD":{"address":5602132,"default_item":106,"flag":1304},"TRAINER_GRUNT_MT_PYRE_3_REWARD":{"address":5602134,"default_item":106,"flag":1305},"TRAINER_GRUNT_MT_PYRE_4_REWARD":{"address":5603222,"default_item":106,"flag":1849},"TRAINER_GRUNT_MUSEUM_1_REWARD":{"address":5602124,"default_item":106,"flag":1300},"TRAINER_GRUNT_MUSEUM_2_REWARD":{"address":5602126,"default_item":106,"flag":1301},"TRAINER_GRUNT_PETALBURG_WOODS_REWARD":{"address":5602104,"default_item":103,"flag":1290},"TRAINER_GRUNT_RUSTURF_TUNNEL_REWARD":{"address":5602116,"default_item":103,"flag":1296},"TRAINER_GRUNT_SEAFLOOR_CAVERN_1_REWARD":{"address":5602096,"default_item":108,"flag":1286},"TRAINER_GRUNT_SEAFLOOR_CAVERN_2_REWARD":{"address":5602098,"default_item":108,"flag":1287},"TRAINER_GRUNT_SEAFLOOR_CAVERN_3_REWARD":{"address":5602100,"default_item":108,"flag":1288},"TRAINER_GRUNT_SEAFLOOR_CAVERN_4_REWARD":{"address":5602112,"default_item":108,"flag":1294},"TRAINER_GRUNT_SEAFLOOR_CAVERN_5_REWARD":{"address":5603218,"default_item":108,"flag":1847},"TRAINER_GRUNT_SPACE_CENTER_1_REWARD":{"address":5602128,"default_item":106,"flag":1302},"TRAINER_GRUNT_SPACE_CENTER_2_REWARD":{"address":5602316,"default_item":106,"flag":1396},"TRAINER_GRUNT_SPACE_CENTER_3_REWARD":{"address":5603256,"default_item":106,"flag":1866},"TRAINER_GRUNT_SPACE_CENTER_4_REWARD":{"address":5603258,"default_item":106,"flag":1867},"TRAINER_GRUNT_SPACE_CENTER_5_REWARD":{"address":5603260,"default_item":106,"flag":1868},"TRAINER_GRUNT_SPACE_CENTER_6_REWARD":{"address":5603262,"default_item":106,"flag":1869},"TRAINER_GRUNT_SPACE_CENTER_7_REWARD":{"address":5603264,"default_item":106,"flag":1870},"TRAINER_GRUNT_WEATHER_INST_1_REWARD":{"address":5602118,"default_item":106,"flag":1297},"TRAINER_GRUNT_WEATHER_INST_2_REWARD":{"address":5602120,"default_item":106,"flag":1298},"TRAINER_GRUNT_WEATHER_INST_3_REWARD":{"address":5602122,"default_item":106,"flag":1299},"TRAINER_GRUNT_WEATHER_INST_4_REWARD":{"address":5602136,"default_item":106,"flag":1306},"TRAINER_GRUNT_WEATHER_INST_5_REWARD":{"address":5603276,"default_item":106,"flag":1876},"TRAINER_GWEN_REWARD":{"address":5602202,"default_item":103,"flag":1339},"TRAINER_HAILEY_REWARD":{"address":5603478,"default_item":103,"flag":1977},"TRAINER_HALEY_1_REWARD":{"address":5603292,"default_item":103,"flag":1884},"TRAINER_HALLE_REWARD":{"address":5603176,"default_item":104,"flag":1826},"TRAINER_HANNAH_REWARD":{"address":5602572,"default_item":108,"flag":1524},"TRAINER_HARRISON_REWARD":{"address":5603240,"default_item":106,"flag":1858},"TRAINER_HAYDEN_REWARD":{"address":5603498,"default_item":106,"flag":1987},"TRAINER_HECTOR_REWARD":{"address":5603110,"default_item":104,"flag":1793},"TRAINER_HEIDI_REWARD":{"address":5603022,"default_item":106,"flag":1749},"TRAINER_HELENE_REWARD":{"address":5603586,"default_item":106,"flag":2031},"TRAINER_HENRY_REWARD":{"address":5603420,"default_item":104,"flag":1948},"TRAINER_HERMAN_REWARD":{"address":5602418,"default_item":106,"flag":1447},"TRAINER_HIDEO_REWARD":{"address":5603386,"default_item":106,"flag":1931},"TRAINER_HITOSHI_REWARD":{"address":5602444,"default_item":104,"flag":1460},"TRAINER_HOPE_REWARD":{"address":5602276,"default_item":104,"flag":1376},"TRAINER_HUDSON_REWARD":{"address":5603104,"default_item":104,"flag":1790},"TRAINER_HUEY_REWARD":{"address":5603064,"default_item":106,"flag":1770},"TRAINER_HUGH_REWARD":{"address":5602882,"default_item":108,"flag":1679},"TRAINER_HUMBERTO_REWARD":{"address":5602888,"default_item":108,"flag":1682},"TRAINER_IMANI_REWARD":{"address":5602968,"default_item":103,"flag":1722},"TRAINER_IRENE_REWARD":{"address":5603036,"default_item":106,"flag":1756},"TRAINER_ISAAC_1_REWARD":{"address":5603160,"default_item":106,"flag":1818},"TRAINER_ISABELLA_REWARD":{"address":5603274,"default_item":104,"flag":1875},"TRAINER_ISABELLE_REWARD":{"address":5603556,"default_item":103,"flag":2016},"TRAINER_ISABEL_1_REWARD":{"address":5602688,"default_item":104,"flag":1582},"TRAINER_ISAIAH_1_REWARD":{"address":5602836,"default_item":104,"flag":1656},"TRAINER_ISOBEL_REWARD":{"address":5602850,"default_item":104,"flag":1663},"TRAINER_IVAN_REWARD":{"address":5602758,"default_item":106,"flag":1617},"TRAINER_JACE_REWARD":{"address":5602492,"default_item":108,"flag":1484},"TRAINER_JACKI_1_REWARD":{"address":5602582,"default_item":108,"flag":1529},"TRAINER_JACKSON_1_REWARD":{"address":5603188,"default_item":104,"flag":1832},"TRAINER_JACK_REWARD":{"address":5602428,"default_item":106,"flag":1452},"TRAINER_JACLYN_REWARD":{"address":5602570,"default_item":106,"flag":1523},"TRAINER_JACOB_REWARD":{"address":5602786,"default_item":106,"flag":1631},"TRAINER_JAIDEN_REWARD":{"address":5603582,"default_item":106,"flag":2029},"TRAINER_JAMES_1_REWARD":{"address":5603326,"default_item":103,"flag":1901},"TRAINER_JANICE_REWARD":{"address":5603294,"default_item":103,"flag":1885},"TRAINER_JANI_REWARD":{"address":5602920,"default_item":103,"flag":1698},"TRAINER_JARED_REWARD":{"address":5602886,"default_item":108,"flag":1681},"TRAINER_JASMINE_REWARD":{"address":5602802,"default_item":103,"flag":1639},"TRAINER_JAYLEN_REWARD":{"address":5602736,"default_item":106,"flag":1606},"TRAINER_JAZMYN_REWARD":{"address":5603090,"default_item":106,"flag":1783},"TRAINER_JEFFREY_1_REWARD":{"address":5602536,"default_item":104,"flag":1506},"TRAINER_JEFF_REWARD":{"address":5602488,"default_item":108,"flag":1482},"TRAINER_JENNA_REWARD":{"address":5603204,"default_item":104,"flag":1840},"TRAINER_JENNIFER_REWARD":{"address":5602274,"default_item":104,"flag":1375},"TRAINER_JENNY_1_REWARD":{"address":5602982,"default_item":106,"flag":1729},"TRAINER_JEROME_REWARD":{"address":5602396,"default_item":103,"flag":1436},"TRAINER_JERRY_1_REWARD":{"address":5602630,"default_item":103,"flag":1553},"TRAINER_JESSICA_1_REWARD":{"address":5602338,"default_item":104,"flag":1407},"TRAINER_JOCELYN_REWARD":{"address":5602934,"default_item":106,"flag":1705},"TRAINER_JODY_REWARD":{"address":5602266,"default_item":104,"flag":1371},"TRAINER_JOEY_REWARD":{"address":5602728,"default_item":103,"flag":1602},"TRAINER_JOHANNA_REWARD":{"address":5603378,"default_item":104,"flag":1927},"TRAINER_JOHNSON_REWARD":{"address":5603592,"default_item":103,"flag":2034},"TRAINER_JOHN_AND_JAY_1_REWARD":{"address":5603446,"default_item":104,"flag":1961},"TRAINER_JONAH_REWARD":{"address":5603418,"default_item":104,"flag":1947},"TRAINER_JONAS_REWARD":{"address":5603092,"default_item":106,"flag":1784},"TRAINER_JONATHAN_REWARD":{"address":5603280,"default_item":104,"flag":1878},"TRAINER_JOSEPH_REWARD":{"address":5603484,"default_item":106,"flag":1980},"TRAINER_JOSE_REWARD":{"address":5603318,"default_item":103,"flag":1897},"TRAINER_JOSH_REWARD":{"address":5602724,"default_item":103,"flag":1600},"TRAINER_JOSUE_REWARD":{"address":5603560,"default_item":108,"flag":2018},"TRAINER_JUAN_1_REWARD":{"address":5602628,"default_item":109,"flag":1552},"TRAINER_JULIE_REWARD":{"address":5602284,"default_item":104,"flag":1380},"TRAINER_JULIO_REWARD":{"address":5603216,"default_item":108,"flag":1846},"TRAINER_KAI_REWARD":{"address":5603510,"default_item":108,"flag":1993},"TRAINER_KALEB_REWARD":{"address":5603482,"default_item":104,"flag":1979},"TRAINER_KARA_REWARD":{"address":5602998,"default_item":106,"flag":1737},"TRAINER_KAREN_1_REWARD":{"address":5602644,"default_item":103,"flag":1560},"TRAINER_KATELYNN_REWARD":{"address":5602734,"default_item":104,"flag":1605},"TRAINER_KATELYN_1_REWARD":{"address":5602856,"default_item":104,"flag":1666},"TRAINER_KATE_AND_JOY_REWARD":{"address":5602656,"default_item":106,"flag":1566},"TRAINER_KATHLEEN_REWARD":{"address":5603250,"default_item":108,"flag":1863},"TRAINER_KATIE_REWARD":{"address":5602994,"default_item":106,"flag":1735},"TRAINER_KAYLA_REWARD":{"address":5602578,"default_item":106,"flag":1527},"TRAINER_KAYLEY_REWARD":{"address":5603094,"default_item":104,"flag":1785},"TRAINER_KEEGAN_REWARD":{"address":5602494,"default_item":108,"flag":1485},"TRAINER_KEIGO_REWARD":{"address":5603388,"default_item":106,"flag":1932},"TRAINER_KELVIN_REWARD":{"address":5603098,"default_item":104,"flag":1787},"TRAINER_KENT_REWARD":{"address":5603324,"default_item":106,"flag":1900},"TRAINER_KEVIN_REWARD":{"address":5602426,"default_item":106,"flag":1451},"TRAINER_KIM_AND_IRIS_REWARD":{"address":5603440,"default_item":106,"flag":1958},"TRAINER_KINDRA_REWARD":{"address":5602296,"default_item":108,"flag":1386},"TRAINER_KIRA_AND_DAN_1_REWARD":{"address":5603368,"default_item":108,"flag":1922},"TRAINER_KIRK_REWARD":{"address":5602466,"default_item":106,"flag":1471},"TRAINER_KIYO_REWARD":{"address":5602446,"default_item":104,"flag":1461},"TRAINER_KOICHI_REWARD":{"address":5602448,"default_item":108,"flag":1462},"TRAINER_KOJI_1_REWARD":{"address":5603428,"default_item":104,"flag":1952},"TRAINER_KYLA_REWARD":{"address":5602970,"default_item":103,"flag":1723},"TRAINER_KYRA_REWARD":{"address":5603580,"default_item":104,"flag":2028},"TRAINER_LAO_1_REWARD":{"address":5602922,"default_item":103,"flag":1699},"TRAINER_LARRY_REWARD":{"address":5602510,"default_item":106,"flag":1493},"TRAINER_LAURA_REWARD":{"address":5602936,"default_item":106,"flag":1706},"TRAINER_LAUREL_REWARD":{"address":5603010,"default_item":106,"flag":1743},"TRAINER_LAWRENCE_REWARD":{"address":5603504,"default_item":106,"flag":1990},"TRAINER_LEAH_REWARD":{"address":5602154,"default_item":108,"flag":1315},"TRAINER_LEA_AND_JED_REWARD":{"address":5603366,"default_item":104,"flag":1921},"TRAINER_LENNY_REWARD":{"address":5603340,"default_item":108,"flag":1908},"TRAINER_LEONARDO_REWARD":{"address":5603236,"default_item":106,"flag":1856},"TRAINER_LEONARD_REWARD":{"address":5603074,"default_item":104,"flag":1775},"TRAINER_LEONEL_REWARD":{"address":5603608,"default_item":104,"flag":2042},"TRAINER_LILA_AND_ROY_1_REWARD":{"address":5603458,"default_item":106,"flag":1967},"TRAINER_LILITH_REWARD":{"address":5603230,"default_item":106,"flag":1853},"TRAINER_LINDA_REWARD":{"address":5603006,"default_item":106,"flag":1741},"TRAINER_LISA_AND_RAY_REWARD":{"address":5603468,"default_item":106,"flag":1972},"TRAINER_LOLA_1_REWARD":{"address":5602198,"default_item":103,"flag":1337},"TRAINER_LORENZO_REWARD":{"address":5603190,"default_item":104,"flag":1833},"TRAINER_LUCAS_1_REWARD":{"address":5603342,"default_item":108,"flag":1909},"TRAINER_LUIS_REWARD":{"address":5602386,"default_item":103,"flag":1431},"TRAINER_LUNG_REWARD":{"address":5602924,"default_item":103,"flag":1700},"TRAINER_LYDIA_1_REWARD":{"address":5603174,"default_item":106,"flag":1825},"TRAINER_LYLE_REWARD":{"address":5603316,"default_item":103,"flag":1896},"TRAINER_MACEY_REWARD":{"address":5603266,"default_item":108,"flag":1871},"TRAINER_MADELINE_1_REWARD":{"address":5602952,"default_item":108,"flag":1714},"TRAINER_MAKAYLA_REWARD":{"address":5603600,"default_item":104,"flag":2038},"TRAINER_MARCEL_REWARD":{"address":5602106,"default_item":104,"flag":1291},"TRAINER_MARCOS_REWARD":{"address":5603488,"default_item":106,"flag":1982},"TRAINER_MARC_REWARD":{"address":5603226,"default_item":106,"flag":1851},"TRAINER_MARIA_1_REWARD":{"address":5602822,"default_item":106,"flag":1649},"TRAINER_MARK_REWARD":{"address":5602374,"default_item":104,"flag":1425},"TRAINER_MARLENE_REWARD":{"address":5603588,"default_item":106,"flag":2032},"TRAINER_MARLEY_REWARD":{"address":5603100,"default_item":104,"flag":1788},"TRAINER_MARY_REWARD":{"address":5602262,"default_item":104,"flag":1369},"TRAINER_MATTHEW_REWARD":{"address":5602398,"default_item":103,"flag":1437},"TRAINER_MATT_REWARD":{"address":5602144,"default_item":104,"flag":1310},"TRAINER_MAURA_REWARD":{"address":5602576,"default_item":108,"flag":1526},"TRAINER_MAXIE_MAGMA_HIDEOUT_REWARD":{"address":5603286,"default_item":107,"flag":1881},"TRAINER_MAXIE_MT_CHIMNEY_REWARD":{"address":5603288,"default_item":104,"flag":1882},"TRAINER_MAY_LILYCOVE_MUDKIP_REWARD":{"address":5603412,"default_item":104,"flag":1944},"TRAINER_MAY_LILYCOVE_TORCHIC_REWARD":{"address":5603416,"default_item":104,"flag":1946},"TRAINER_MAY_LILYCOVE_TREECKO_REWARD":{"address":5603414,"default_item":104,"flag":1945},"TRAINER_MAY_ROUTE_103_MUDKIP_REWARD":{"address":5603142,"default_item":106,"flag":1809},"TRAINER_MAY_ROUTE_103_TORCHIC_REWARD":{"address":5603154,"default_item":106,"flag":1815},"TRAINER_MAY_ROUTE_103_TREECKO_REWARD":{"address":5603148,"default_item":106,"flag":1812},"TRAINER_MAY_ROUTE_110_MUDKIP_REWARD":{"address":5603144,"default_item":104,"flag":1810},"TRAINER_MAY_ROUTE_110_TORCHIC_REWARD":{"address":5603156,"default_item":104,"flag":1816},"TRAINER_MAY_ROUTE_110_TREECKO_REWARD":{"address":5603150,"default_item":104,"flag":1813},"TRAINER_MAY_ROUTE_119_MUDKIP_REWARD":{"address":5603146,"default_item":104,"flag":1811},"TRAINER_MAY_ROUTE_119_TORCHIC_REWARD":{"address":5603158,"default_item":104,"flag":1817},"TRAINER_MAY_ROUTE_119_TREECKO_REWARD":{"address":5603152,"default_item":104,"flag":1814},"TRAINER_MAY_RUSTBORO_MUDKIP_REWARD":{"address":5603284,"default_item":108,"flag":1880},"TRAINER_MAY_RUSTBORO_TORCHIC_REWARD":{"address":5603622,"default_item":108,"flag":2049},"TRAINER_MAY_RUSTBORO_TREECKO_REWARD":{"address":5603620,"default_item":108,"flag":2048},"TRAINER_MELINA_REWARD":{"address":5603594,"default_item":106,"flag":2035},"TRAINER_MELISSA_REWARD":{"address":5602332,"default_item":104,"flag":1404},"TRAINER_MEL_AND_PAUL_REWARD":{"address":5603444,"default_item":108,"flag":1960},"TRAINER_MICAH_REWARD":{"address":5602594,"default_item":107,"flag":1535},"TRAINER_MICHELLE_REWARD":{"address":5602280,"default_item":104,"flag":1378},"TRAINER_MIGUEL_1_REWARD":{"address":5602670,"default_item":104,"flag":1573},"TRAINER_MIKE_2_REWARD":{"address":5603354,"default_item":106,"flag":1915},"TRAINER_MISSY_REWARD":{"address":5602978,"default_item":103,"flag":1727},"TRAINER_MITCHELL_REWARD":{"address":5603164,"default_item":104,"flag":1820},"TRAINER_MIU_AND_YUKI_REWARD":{"address":5603052,"default_item":106,"flag":1764},"TRAINER_MOLLIE_REWARD":{"address":5602358,"default_item":104,"flag":1417},"TRAINER_MYLES_REWARD":{"address":5603614,"default_item":104,"flag":2045},"TRAINER_NANCY_REWARD":{"address":5603028,"default_item":106,"flag":1752},"TRAINER_NAOMI_REWARD":{"address":5602322,"default_item":110,"flag":1399},"TRAINER_NATE_REWARD":{"address":5603248,"default_item":107,"flag":1862},"TRAINER_NED_REWARD":{"address":5602764,"default_item":106,"flag":1620},"TRAINER_NICHOLAS_REWARD":{"address":5603254,"default_item":108,"flag":1865},"TRAINER_NICOLAS_1_REWARD":{"address":5602868,"default_item":104,"flag":1672},"TRAINER_NIKKI_REWARD":{"address":5602990,"default_item":106,"flag":1733},"TRAINER_NOB_1_REWARD":{"address":5602450,"default_item":106,"flag":1463},"TRAINER_NOLAN_REWARD":{"address":5602768,"default_item":108,"flag":1622},"TRAINER_NOLEN_REWARD":{"address":5602406,"default_item":106,"flag":1441},"TRAINER_NORMAN_1_REWARD":{"address":5602622,"default_item":107,"flag":1549},"TRAINER_OLIVIA_REWARD":{"address":5602344,"default_item":107,"flag":1410},"TRAINER_OWEN_REWARD":{"address":5602250,"default_item":104,"flag":1363},"TRAINER_PABLO_1_REWARD":{"address":5602838,"default_item":104,"flag":1657},"TRAINER_PARKER_REWARD":{"address":5602228,"default_item":104,"flag":1352},"TRAINER_PAT_REWARD":{"address":5603616,"default_item":104,"flag":2046},"TRAINER_PAXTON_REWARD":{"address":5603272,"default_item":104,"flag":1874},"TRAINER_PERRY_REWARD":{"address":5602880,"default_item":108,"flag":1678},"TRAINER_PETE_REWARD":{"address":5603554,"default_item":103,"flag":2015},"TRAINER_PHILLIP_REWARD":{"address":5603072,"default_item":104,"flag":1774},"TRAINER_PHIL_REWARD":{"address":5602884,"default_item":108,"flag":1680},"TRAINER_PHOEBE_REWARD":{"address":5602608,"default_item":110,"flag":1542},"TRAINER_PRESLEY_REWARD":{"address":5602890,"default_item":104,"flag":1683},"TRAINER_PRESTON_REWARD":{"address":5602550,"default_item":108,"flag":1513},"TRAINER_QUINCY_REWARD":{"address":5602732,"default_item":104,"flag":1604},"TRAINER_RACHEL_REWARD":{"address":5603606,"default_item":104,"flag":2041},"TRAINER_RANDALL_REWARD":{"address":5602226,"default_item":104,"flag":1351},"TRAINER_REED_REWARD":{"address":5603434,"default_item":106,"flag":1955},"TRAINER_RELI_AND_IAN_REWARD":{"address":5603456,"default_item":106,"flag":1966},"TRAINER_REYNA_REWARD":{"address":5603102,"default_item":108,"flag":1789},"TRAINER_RHETT_REWARD":{"address":5603490,"default_item":106,"flag":1983},"TRAINER_RICHARD_REWARD":{"address":5602416,"default_item":106,"flag":1446},"TRAINER_RICKY_1_REWARD":{"address":5602212,"default_item":103,"flag":1344},"TRAINER_RICK_REWARD":{"address":5603314,"default_item":103,"flag":1895},"TRAINER_RILEY_REWARD":{"address":5603390,"default_item":106,"flag":1933},"TRAINER_ROBERT_1_REWARD":{"address":5602896,"default_item":108,"flag":1686},"TRAINER_RODNEY_REWARD":{"address":5602414,"default_item":106,"flag":1445},"TRAINER_ROGER_REWARD":{"address":5603422,"default_item":104,"flag":1949},"TRAINER_ROLAND_REWARD":{"address":5602404,"default_item":106,"flag":1440},"TRAINER_RONALD_REWARD":{"address":5602784,"default_item":104,"flag":1630},"TRAINER_ROSE_1_REWARD":{"address":5602158,"default_item":106,"flag":1317},"TRAINER_ROXANNE_1_REWARD":{"address":5602614,"default_item":104,"flag":1545},"TRAINER_RUBEN_REWARD":{"address":5603426,"default_item":104,"flag":1951},"TRAINER_SAMANTHA_REWARD":{"address":5602574,"default_item":108,"flag":1525},"TRAINER_SAMUEL_REWARD":{"address":5602246,"default_item":104,"flag":1361},"TRAINER_SANTIAGO_REWARD":{"address":5602420,"default_item":106,"flag":1448},"TRAINER_SARAH_REWARD":{"address":5603474,"default_item":104,"flag":1975},"TRAINER_SAWYER_1_REWARD":{"address":5602086,"default_item":108,"flag":1281},"TRAINER_SHANE_REWARD":{"address":5602512,"default_item":106,"flag":1494},"TRAINER_SHANNON_REWARD":{"address":5602278,"default_item":104,"flag":1377},"TRAINER_SHARON_REWARD":{"address":5602988,"default_item":106,"flag":1732},"TRAINER_SHAWN_REWARD":{"address":5602472,"default_item":106,"flag":1474},"TRAINER_SHAYLA_REWARD":{"address":5603578,"default_item":108,"flag":2027},"TRAINER_SHEILA_REWARD":{"address":5602334,"default_item":104,"flag":1405},"TRAINER_SHELBY_1_REWARD":{"address":5602710,"default_item":108,"flag":1593},"TRAINER_SHELLY_SEAFLOOR_CAVERN_REWARD":{"address":5602150,"default_item":104,"flag":1313},"TRAINER_SHELLY_WEATHER_INSTITUTE_REWARD":{"address":5602148,"default_item":104,"flag":1312},"TRAINER_SHIRLEY_REWARD":{"address":5602336,"default_item":104,"flag":1406},"TRAINER_SIDNEY_REWARD":{"address":5602606,"default_item":110,"flag":1541},"TRAINER_SIENNA_REWARD":{"address":5603002,"default_item":106,"flag":1739},"TRAINER_SIMON_REWARD":{"address":5602214,"default_item":103,"flag":1345},"TRAINER_SOPHIE_REWARD":{"address":5603500,"default_item":106,"flag":1988},"TRAINER_SPENCER_REWARD":{"address":5602402,"default_item":106,"flag":1439},"TRAINER_STAN_REWARD":{"address":5602408,"default_item":106,"flag":1442},"TRAINER_STEVEN_REWARD":{"address":5603692,"default_item":109,"flag":2084},"TRAINER_STEVE_1_REWARD":{"address":5602370,"default_item":104,"flag":1423},"TRAINER_SUSIE_REWARD":{"address":5602996,"default_item":106,"flag":1736},"TRAINER_SYLVIA_REWARD":{"address":5603234,"default_item":108,"flag":1855},"TRAINER_TABITHA_MAGMA_HIDEOUT_REWARD":{"address":5603548,"default_item":104,"flag":2012},"TRAINER_TABITHA_MT_CHIMNEY_REWARD":{"address":5603278,"default_item":108,"flag":1877},"TRAINER_TAKAO_REWARD":{"address":5602442,"default_item":106,"flag":1459},"TRAINER_TAKASHI_REWARD":{"address":5602916,"default_item":106,"flag":1696},"TRAINER_TALIA_REWARD":{"address":5602854,"default_item":104,"flag":1665},"TRAINER_TAMMY_REWARD":{"address":5602298,"default_item":106,"flag":1387},"TRAINER_TANYA_REWARD":{"address":5602986,"default_item":106,"flag":1731},"TRAINER_TARA_REWARD":{"address":5602976,"default_item":103,"flag":1726},"TRAINER_TASHA_REWARD":{"address":5602302,"default_item":108,"flag":1389},"TRAINER_TATE_AND_LIZA_1_REWARD":{"address":5602626,"default_item":109,"flag":1551},"TRAINER_TAYLOR_REWARD":{"address":5602534,"default_item":104,"flag":1505},"TRAINER_THALIA_1_REWARD":{"address":5602372,"default_item":104,"flag":1424},"TRAINER_THOMAS_REWARD":{"address":5602596,"default_item":107,"flag":1536},"TRAINER_TIANA_REWARD":{"address":5603290,"default_item":103,"flag":1883},"TRAINER_TIFFANY_REWARD":{"address":5602346,"default_item":107,"flag":1411},"TRAINER_TIMMY_REWARD":{"address":5602752,"default_item":103,"flag":1614},"TRAINER_TIMOTHY_1_REWARD":{"address":5602698,"default_item":104,"flag":1587},"TRAINER_TISHA_REWARD":{"address":5603436,"default_item":106,"flag":1956},"TRAINER_TOMMY_REWARD":{"address":5602726,"default_item":103,"flag":1601},"TRAINER_TONY_1_REWARD":{"address":5602394,"default_item":103,"flag":1435},"TRAINER_TORI_AND_TIA_REWARD":{"address":5603438,"default_item":103,"flag":1957},"TRAINER_TRAVIS_REWARD":{"address":5602520,"default_item":106,"flag":1498},"TRAINER_TRENT_1_REWARD":{"address":5603338,"default_item":106,"flag":1907},"TRAINER_TYRA_AND_IVY_REWARD":{"address":5603442,"default_item":106,"flag":1959},"TRAINER_TYRON_REWARD":{"address":5603492,"default_item":106,"flag":1984},"TRAINER_VALERIE_1_REWARD":{"address":5602300,"default_item":108,"flag":1388},"TRAINER_VANESSA_REWARD":{"address":5602684,"default_item":104,"flag":1580},"TRAINER_VICKY_REWARD":{"address":5602708,"default_item":108,"flag":1592},"TRAINER_VICTORIA_REWARD":{"address":5602682,"default_item":106,"flag":1579},"TRAINER_VICTOR_REWARD":{"address":5602668,"default_item":106,"flag":1572},"TRAINER_VIOLET_REWARD":{"address":5602162,"default_item":104,"flag":1319},"TRAINER_VIRGIL_REWARD":{"address":5602552,"default_item":108,"flag":1514},"TRAINER_VITO_REWARD":{"address":5602248,"default_item":104,"flag":1362},"TRAINER_VIVIAN_REWARD":{"address":5603382,"default_item":106,"flag":1929},"TRAINER_VIVI_REWARD":{"address":5603296,"default_item":106,"flag":1886},"TRAINER_WADE_REWARD":{"address":5602772,"default_item":106,"flag":1624},"TRAINER_WALLACE_REWARD":{"address":5602754,"default_item":110,"flag":1615},"TRAINER_WALLY_MAUVILLE_REWARD":{"address":5603396,"default_item":108,"flag":1936},"TRAINER_WALLY_VR_1_REWARD":{"address":5603122,"default_item":107,"flag":1799},"TRAINER_WALTER_1_REWARD":{"address":5602592,"default_item":104,"flag":1534},"TRAINER_WARREN_REWARD":{"address":5602260,"default_item":104,"flag":1368},"TRAINER_WATTSON_1_REWARD":{"address":5602618,"default_item":104,"flag":1547},"TRAINER_WAYNE_REWARD":{"address":5603430,"default_item":104,"flag":1953},"TRAINER_WENDY_REWARD":{"address":5602268,"default_item":104,"flag":1372},"TRAINER_WILLIAM_REWARD":{"address":5602556,"default_item":106,"flag":1516},"TRAINER_WILTON_1_REWARD":{"address":5602240,"default_item":108,"flag":1358},"TRAINER_WINONA_1_REWARD":{"address":5602624,"default_item":107,"flag":1550},"TRAINER_WINSTON_1_REWARD":{"address":5602356,"default_item":104,"flag":1416},"TRAINER_WYATT_REWARD":{"address":5603506,"default_item":104,"flag":1991},"TRAINER_YASU_REWARD":{"address":5602914,"default_item":106,"flag":1695},"TRAINER_ZANDER_REWARD":{"address":5602146,"default_item":108,"flag":1311}},"maps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":{"header_address":4766420,"warp_table_address":5496844},"MAP_ABANDONED_SHIP_CORRIDORS_1F":{"header_address":4766196,"warp_table_address":5495920},"MAP_ABANDONED_SHIP_CORRIDORS_B1F":{"header_address":4766252,"warp_table_address":5496248},"MAP_ABANDONED_SHIP_DECK":{"header_address":4766168,"warp_table_address":5495812},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":{"fishing_encounters":{"address":5609088,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766476,"warp_table_address":5496908,"water_encounters":{"address":5609060,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":{"header_address":4766504,"warp_table_address":5497120},"MAP_ABANDONED_SHIP_ROOMS2_1F":{"header_address":4766392,"warp_table_address":5496752},"MAP_ABANDONED_SHIP_ROOMS2_B1F":{"header_address":4766308,"warp_table_address":5496484},"MAP_ABANDONED_SHIP_ROOMS_1F":{"header_address":4766224,"warp_table_address":5496132},"MAP_ABANDONED_SHIP_ROOMS_B1F":{"fishing_encounters":{"address":5606324,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766280,"warp_table_address":5496392,"water_encounters":{"address":5606296,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_ROOM_B1F":{"header_address":4766364,"warp_table_address":5496596},"MAP_ABANDONED_SHIP_UNDERWATER1":{"header_address":4766336,"warp_table_address":5496536},"MAP_ABANDONED_SHIP_UNDERWATER2":{"header_address":4766448,"warp_table_address":5496880},"MAP_ALTERING_CAVE":{"header_address":4767624,"land_encounters":{"address":5613400,"slots":[41,41,41,41,41,41,41,41,41,41,41,41]},"warp_table_address":5500436},"MAP_ANCIENT_TOMB":{"header_address":4766560,"warp_table_address":5497460},"MAP_AQUA_HIDEOUT_1F":{"header_address":4765300,"warp_table_address":5490892},"MAP_AQUA_HIDEOUT_B1F":{"header_address":4765328,"warp_table_address":5491152},"MAP_AQUA_HIDEOUT_B2F":{"header_address":4765356,"warp_table_address":5491516},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":{"header_address":4766728,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":{"header_address":4766756,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":{"header_address":4766784,"warp_table_address":4160749568},"MAP_ARTISAN_CAVE_1F":{"header_address":4767456,"land_encounters":{"address":5613344,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500172},"MAP_ARTISAN_CAVE_B1F":{"header_address":4767428,"land_encounters":{"address":5613288,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500064},"MAP_BATTLE_COLOSSEUM_2P":{"header_address":4768352,"warp_table_address":5509852},"MAP_BATTLE_COLOSSEUM_4P":{"header_address":4768436,"warp_table_address":5510152},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":{"header_address":4770228,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":{"header_address":4770200,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":{"header_address":4770172,"warp_table_address":5520908},"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":{"header_address":4769976,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":{"header_address":4769920,"warp_table_address":5519076},"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":{"header_address":4769892,"warp_table_address":5518968},"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":{"header_address":4769948,"warp_table_address":5519136},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":{"header_address":4770312,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":{"header_address":4770256,"warp_table_address":5521384},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":{"header_address":4770284,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":{"header_address":4770060,"warp_table_address":5520116},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":{"header_address":4770032,"warp_table_address":5519944},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":{"header_address":4770004,"warp_table_address":5519696},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":{"header_address":4770368,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":{"header_address":4770340,"warp_table_address":5521808},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":{"header_address":4770452,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":{"header_address":4770424,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":{"header_address":4770480,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":{"header_address":4770396,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":{"header_address":4770116,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":{"header_address":4770088,"warp_table_address":5520248},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":{"header_address":4770144,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":{"header_address":4769612,"warp_table_address":5516696},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":{"header_address":4769584,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":{"header_address":4769556,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":{"header_address":4769528,"warp_table_address":5516432},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":{"header_address":4769864,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":{"header_address":4769836,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":{"header_address":4769808,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":{"header_address":4770564,"warp_table_address":5523056},"MAP_BATTLE_FRONTIER_LOUNGE1":{"header_address":4770536,"warp_table_address":5522812},"MAP_BATTLE_FRONTIER_LOUNGE2":{"header_address":4770592,"warp_table_address":5523220},"MAP_BATTLE_FRONTIER_LOUNGE3":{"header_address":4770620,"warp_table_address":5523376},"MAP_BATTLE_FRONTIER_LOUNGE4":{"header_address":4770648,"warp_table_address":5523476},"MAP_BATTLE_FRONTIER_LOUNGE5":{"header_address":4770704,"warp_table_address":5523660},"MAP_BATTLE_FRONTIER_LOUNGE6":{"header_address":4770732,"warp_table_address":5523720},"MAP_BATTLE_FRONTIER_LOUNGE7":{"header_address":4770760,"warp_table_address":5523844},"MAP_BATTLE_FRONTIER_LOUNGE8":{"header_address":4770816,"warp_table_address":5524100},"MAP_BATTLE_FRONTIER_LOUNGE9":{"header_address":4770844,"warp_table_address":5524152},"MAP_BATTLE_FRONTIER_MART":{"header_address":4770928,"warp_table_address":5524588},"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":{"header_address":4769780,"warp_table_address":5518080},"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":{"header_address":4769500,"warp_table_address":5516048},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":{"header_address":4770872,"warp_table_address":5524308},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":{"header_address":4770900,"warp_table_address":5524448},"MAP_BATTLE_FRONTIER_RANKING_HALL":{"header_address":4770508,"warp_table_address":5522560},"MAP_BATTLE_FRONTIER_RECEPTION_GATE":{"header_address":4770788,"warp_table_address":5523992},"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":{"header_address":4770676,"warp_table_address":5523528},"MAP_BATTLE_PYRAMID_SQUARE01":{"header_address":4768912,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE02":{"header_address":4768940,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE03":{"header_address":4768968,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE04":{"header_address":4768996,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE05":{"header_address":4769024,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE06":{"header_address":4769052,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE07":{"header_address":4769080,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE08":{"header_address":4769108,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE09":{"header_address":4769136,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE10":{"header_address":4769164,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE11":{"header_address":4769192,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE12":{"header_address":4769220,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE13":{"header_address":4769248,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE14":{"header_address":4769276,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE15":{"header_address":4769304,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE16":{"header_address":4769332,"warp_table_address":4160749568},"MAP_BIRTH_ISLAND_EXTERIOR":{"header_address":4771012,"warp_table_address":5524876},"MAP_BIRTH_ISLAND_HARBOR":{"header_address":4771040,"warp_table_address":5524952},"MAP_CAVE_OF_ORIGIN_1F":{"header_address":4765720,"land_encounters":{"address":5609868,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493440},"MAP_CAVE_OF_ORIGIN_B1F":{"header_address":4765832,"warp_table_address":5493608},"MAP_CAVE_OF_ORIGIN_ENTRANCE":{"header_address":4765692,"land_encounters":{"address":5609812,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493404},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":{"header_address":4765748,"land_encounters":{"address":5609924,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493476},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":{"header_address":4765776,"land_encounters":{"address":5609980,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493512},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":{"header_address":4765804,"land_encounters":{"address":5610036,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493548},"MAP_CONTEST_HALL":{"header_address":4768464,"warp_table_address":4160749568},"MAP_CONTEST_HALL_BEAUTY":{"header_address":4768660,"warp_table_address":4160749568},"MAP_CONTEST_HALL_COOL":{"header_address":4768716,"warp_table_address":4160749568},"MAP_CONTEST_HALL_CUTE":{"header_address":4768772,"warp_table_address":4160749568},"MAP_CONTEST_HALL_SMART":{"header_address":4768744,"warp_table_address":4160749568},"MAP_CONTEST_HALL_TOUGH":{"header_address":4768688,"warp_table_address":4160749568},"MAP_DESERT_RUINS":{"header_address":4764824,"warp_table_address":5486828},"MAP_DESERT_UNDERPASS":{"header_address":4767400,"land_encounters":{"address":5613232,"slots":[132,370,132,371,132,370,371,132,370,132,371,132]},"warp_table_address":5500012},"MAP_DEWFORD_TOWN":{"fishing_encounters":{"address":5611588,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758300,"warp_table_address":5435180,"water_encounters":{"address":5611560,"slots":[72,309,309,310,310]}},"MAP_DEWFORD_TOWN_GYM":{"header_address":4759952,"warp_table_address":5460340},"MAP_DEWFORD_TOWN_HALL":{"header_address":4759980,"warp_table_address":5460640},"MAP_DEWFORD_TOWN_HOUSE1":{"header_address":4759868,"warp_table_address":5459856},"MAP_DEWFORD_TOWN_HOUSE2":{"header_address":4760008,"warp_table_address":5460748},"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":{"header_address":4759896,"warp_table_address":5459964},"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":{"header_address":4759924,"warp_table_address":5460104},"MAP_EVER_GRANDE_CITY":{"fishing_encounters":{"address":5611892,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4758216,"warp_table_address":5434048,"water_encounters":{"address":5611864,"slots":[72,309,309,310,310]}},"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":{"header_address":4764012,"warp_table_address":5483720},"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":{"header_address":4763984,"warp_table_address":5483612},"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":{"header_address":4763956,"warp_table_address":5483552},"MAP_EVER_GRANDE_CITY_HALL1":{"header_address":4764040,"warp_table_address":5483756},"MAP_EVER_GRANDE_CITY_HALL2":{"header_address":4764068,"warp_table_address":5483808},"MAP_EVER_GRANDE_CITY_HALL3":{"header_address":4764096,"warp_table_address":5483860},"MAP_EVER_GRANDE_CITY_HALL4":{"header_address":4764124,"warp_table_address":5483912},"MAP_EVER_GRANDE_CITY_HALL5":{"header_address":4764152,"warp_table_address":5483948},"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":{"header_address":4764208,"warp_table_address":5484180},"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":{"header_address":4763928,"warp_table_address":5483492},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":{"header_address":4764236,"warp_table_address":5484304},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":{"header_address":4764264,"warp_table_address":5484444},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":{"header_address":4764180,"warp_table_address":5484096},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":{"header_address":4764292,"warp_table_address":5484584},"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":{"header_address":4763900,"warp_table_address":5483432},"MAP_FALLARBOR_TOWN":{"header_address":4758356,"warp_table_address":5435792},"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760316,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760288,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760260,"warp_table_address":5462376},"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":{"header_address":4760400,"warp_table_address":5462888},"MAP_FALLARBOR_TOWN_MART":{"header_address":4760232,"warp_table_address":5462220},"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":{"header_address":4760428,"warp_table_address":5462948},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":{"header_address":4760344,"warp_table_address":5462656},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":{"header_address":4760372,"warp_table_address":5462796},"MAP_FARAWAY_ISLAND_ENTRANCE":{"header_address":4770956,"warp_table_address":5524672},"MAP_FARAWAY_ISLAND_INTERIOR":{"header_address":4770984,"warp_table_address":5524792},"MAP_FIERY_PATH":{"header_address":4765048,"land_encounters":{"address":5606456,"slots":[339,109,339,66,321,218,109,66,321,321,88,88]},"warp_table_address":5489344},"MAP_FORTREE_CITY":{"header_address":4758104,"warp_table_address":5431676},"MAP_FORTREE_CITY_DECORATION_SHOP":{"header_address":4762444,"warp_table_address":5473936},"MAP_FORTREE_CITY_GYM":{"header_address":4762220,"warp_table_address":5472984},"MAP_FORTREE_CITY_HOUSE1":{"header_address":4762192,"warp_table_address":5472756},"MAP_FORTREE_CITY_HOUSE2":{"header_address":4762332,"warp_table_address":5473504},"MAP_FORTREE_CITY_HOUSE3":{"header_address":4762360,"warp_table_address":5473588},"MAP_FORTREE_CITY_HOUSE4":{"header_address":4762388,"warp_table_address":5473696},"MAP_FORTREE_CITY_HOUSE5":{"header_address":4762416,"warp_table_address":5473804},"MAP_FORTREE_CITY_MART":{"header_address":4762304,"warp_table_address":5473420},"MAP_FORTREE_CITY_POKEMON_CENTER_1F":{"header_address":4762248,"warp_table_address":5473140},"MAP_FORTREE_CITY_POKEMON_CENTER_2F":{"header_address":4762276,"warp_table_address":5473280},"MAP_GRANITE_CAVE_1F":{"header_address":4764852,"land_encounters":{"address":5605988,"slots":[41,335,335,41,335,63,335,335,74,74,74,74]},"warp_table_address":5486956},"MAP_GRANITE_CAVE_B1F":{"header_address":4764880,"land_encounters":{"address":5606044,"slots":[41,382,382,382,41,63,335,335,322,322,322,322]},"warp_table_address":5487032},"MAP_GRANITE_CAVE_B2F":{"header_address":4764908,"land_encounters":{"address":5606372,"slots":[41,382,382,41,382,63,322,322,322,322,322,322]},"rock_smash_encounters":{"address":5606428,"slots":[74,320,74,74,74]},"warp_table_address":5487324},"MAP_GRANITE_CAVE_STEVENS_ROOM":{"header_address":4764936,"land_encounters":{"address":5608188,"slots":[41,335,335,41,335,63,335,335,382,382,382,382]},"warp_table_address":5487432},"MAP_INSIDE_OF_TRUCK":{"header_address":4768800,"warp_table_address":5510720},"MAP_ISLAND_CAVE":{"header_address":4766532,"warp_table_address":5497356},"MAP_JAGGED_PASS":{"header_address":4765020,"land_encounters":{"address":5606644,"slots":[339,339,66,339,351,66,351,66,339,351,339,351]},"warp_table_address":5488908},"MAP_LAVARIDGE_TOWN":{"header_address":4758328,"warp_table_address":5435516},"MAP_LAVARIDGE_TOWN_GYM_1F":{"header_address":4760064,"warp_table_address":5461036},"MAP_LAVARIDGE_TOWN_GYM_B1F":{"header_address":4760092,"warp_table_address":5461384},"MAP_LAVARIDGE_TOWN_HERB_SHOP":{"header_address":4760036,"warp_table_address":5460856},"MAP_LAVARIDGE_TOWN_HOUSE":{"header_address":4760120,"warp_table_address":5461668},"MAP_LAVARIDGE_TOWN_MART":{"header_address":4760148,"warp_table_address":5461776},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":{"header_address":4760176,"warp_table_address":5461908},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":{"header_address":4760204,"warp_table_address":5462056},"MAP_LILYCOVE_CITY":{"fishing_encounters":{"address":5611512,"slots":[129,72,129,72,313,313,313,120,313,313]},"header_address":4758132,"warp_table_address":5432368,"water_encounters":{"address":5611484,"slots":[72,309,309,310,310]}},"MAP_LILYCOVE_CITY_CONTEST_HALL":{"header_address":4762612,"warp_table_address":5476560},"MAP_LILYCOVE_CITY_CONTEST_LOBBY":{"header_address":4762584,"warp_table_address":5475596},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":{"header_address":4762472,"warp_table_address":5473996},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":{"header_address":4762500,"warp_table_address":5474224},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":{"header_address":4762920,"warp_table_address":5478044},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":{"header_address":4762948,"warp_table_address":5478228},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":{"header_address":4762976,"warp_table_address":5478392},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":{"header_address":4763004,"warp_table_address":5478556},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":{"header_address":4763032,"warp_table_address":5478768},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":{"header_address":4763088,"warp_table_address":5478984},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":{"header_address":4763060,"warp_table_address":5478908},"MAP_LILYCOVE_CITY_HARBOR":{"header_address":4762752,"warp_table_address":5477396},"MAP_LILYCOVE_CITY_HOUSE1":{"header_address":4762808,"warp_table_address":5477540},"MAP_LILYCOVE_CITY_HOUSE2":{"header_address":4762836,"warp_table_address":5477600},"MAP_LILYCOVE_CITY_HOUSE3":{"header_address":4762864,"warp_table_address":5477780},"MAP_LILYCOVE_CITY_HOUSE4":{"header_address":4762892,"warp_table_address":5477864},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":{"header_address":4762528,"warp_table_address":5474492},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":{"header_address":4762556,"warp_table_address":5474824},"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":{"header_address":4762780,"warp_table_address":5477456},"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":{"header_address":4762640,"warp_table_address":5476804},"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":{"header_address":4762668,"warp_table_address":5476944},"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":{"header_address":4762724,"warp_table_address":5477240},"MAP_LILYCOVE_CITY_UNUSED_MART":{"header_address":4762696,"warp_table_address":5476988},"MAP_LITTLEROOT_TOWN":{"header_address":4758244,"warp_table_address":5434528},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":{"header_address":4759588,"warp_table_address":5457588},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":{"header_address":4759616,"warp_table_address":5458080},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":{"header_address":4759644,"warp_table_address":5458324},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":{"header_address":4759672,"warp_table_address":5458816},"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":{"header_address":4759700,"warp_table_address":5459036},"MAP_MAGMA_HIDEOUT_1F":{"header_address":4767064,"land_encounters":{"address":5612560,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498844},"MAP_MAGMA_HIDEOUT_2F_1R":{"header_address":4767092,"land_encounters":{"address":5612616,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498992},"MAP_MAGMA_HIDEOUT_2F_2R":{"header_address":4767120,"land_encounters":{"address":5612672,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499180},"MAP_MAGMA_HIDEOUT_2F_3R":{"header_address":4767260,"land_encounters":{"address":5612952,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499696},"MAP_MAGMA_HIDEOUT_3F_1R":{"header_address":4767148,"land_encounters":{"address":5612728,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499288},"MAP_MAGMA_HIDEOUT_3F_2R":{"header_address":4767176,"land_encounters":{"address":5612784,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499380},"MAP_MAGMA_HIDEOUT_3F_3R":{"header_address":4767232,"land_encounters":{"address":5612896,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499660},"MAP_MAGMA_HIDEOUT_4F":{"header_address":4767204,"land_encounters":{"address":5612840,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499600},"MAP_MARINE_CAVE_END":{"header_address":4767540,"warp_table_address":5500288},"MAP_MARINE_CAVE_ENTRANCE":{"header_address":4767512,"warp_table_address":5500236},"MAP_MAUVILLE_CITY":{"header_address":4758048,"warp_table_address":5430380},"MAP_MAUVILLE_CITY_BIKE_SHOP":{"header_address":4761520,"warp_table_address":5469232},"MAP_MAUVILLE_CITY_GAME_CORNER":{"header_address":4761576,"warp_table_address":5469640},"MAP_MAUVILLE_CITY_GYM":{"header_address":4761492,"warp_table_address":5469060},"MAP_MAUVILLE_CITY_HOUSE1":{"header_address":4761548,"warp_table_address":5469316},"MAP_MAUVILLE_CITY_HOUSE2":{"header_address":4761604,"warp_table_address":5469988},"MAP_MAUVILLE_CITY_MART":{"header_address":4761688,"warp_table_address":5470424},"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":{"header_address":4761632,"warp_table_address":5470144},"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":{"header_address":4761660,"warp_table_address":5470308},"MAP_METEOR_FALLS_1F_1R":{"fishing_encounters":{"address":5610796,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4764656,"land_encounters":{"address":5610712,"slots":[41,41,41,41,41,349,349,349,41,41,41,41]},"warp_table_address":5486052,"water_encounters":{"address":5610768,"slots":[41,41,349,349,349]}},"MAP_METEOR_FALLS_1F_2R":{"fishing_encounters":{"address":5610928,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764684,"land_encounters":{"address":5610844,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486220,"water_encounters":{"address":5610900,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_1R":{"fishing_encounters":{"address":5611060,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764712,"land_encounters":{"address":5610976,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486284,"water_encounters":{"address":5611032,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_2R":{"fishing_encounters":{"address":5606596,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764740,"land_encounters":{"address":5606512,"slots":[42,42,395,349,395,349,395,349,42,42,42,42]},"warp_table_address":5486376,"water_encounters":{"address":5606568,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_STEVENS_CAVE":{"header_address":4767652,"land_encounters":{"address":5613904,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5500488},"MAP_MIRAGE_TOWER_1F":{"header_address":4767288,"land_encounters":{"address":5613008,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499732},"MAP_MIRAGE_TOWER_2F":{"header_address":4767316,"land_encounters":{"address":5613064,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499768},"MAP_MIRAGE_TOWER_3F":{"header_address":4767344,"land_encounters":{"address":5613120,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499852},"MAP_MIRAGE_TOWER_4F":{"header_address":4767372,"land_encounters":{"address":5613176,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499960},"MAP_MOSSDEEP_CITY":{"fishing_encounters":{"address":5611740,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758160,"warp_table_address":5433064,"water_encounters":{"address":5611712,"slots":[72,309,309,310,310]}},"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":{"header_address":4763424,"warp_table_address":5481712},"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":{"header_address":4763452,"warp_table_address":5481816},"MAP_MOSSDEEP_CITY_GYM":{"header_address":4763116,"warp_table_address":5479884},"MAP_MOSSDEEP_CITY_HOUSE1":{"header_address":4763144,"warp_table_address":5480232},"MAP_MOSSDEEP_CITY_HOUSE2":{"header_address":4763172,"warp_table_address":5480340},"MAP_MOSSDEEP_CITY_HOUSE3":{"header_address":4763284,"warp_table_address":5480812},"MAP_MOSSDEEP_CITY_HOUSE4":{"header_address":4763340,"warp_table_address":5481076},"MAP_MOSSDEEP_CITY_MART":{"header_address":4763256,"warp_table_address":5480752},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":{"header_address":4763200,"warp_table_address":5480448},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":{"header_address":4763228,"warp_table_address":5480612},"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":{"header_address":4763368,"warp_table_address":5481376},"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":{"header_address":4763396,"warp_table_address":5481636},"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":{"header_address":4763312,"warp_table_address":5480920},"MAP_MT_CHIMNEY":{"header_address":4764992,"warp_table_address":5488664},"MAP_MT_CHIMNEY_CABLE_CAR_STATION":{"header_address":4764460,"warp_table_address":5485144},"MAP_MT_PYRE_1F":{"header_address":4765076,"land_encounters":{"address":5606100,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489452},"MAP_MT_PYRE_2F":{"header_address":4765104,"land_encounters":{"address":5607796,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489712},"MAP_MT_PYRE_3F":{"header_address":4765132,"land_encounters":{"address":5607852,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489868},"MAP_MT_PYRE_4F":{"header_address":4765160,"land_encounters":{"address":5607908,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5489984},"MAP_MT_PYRE_5F":{"header_address":4765188,"land_encounters":{"address":5607964,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490100},"MAP_MT_PYRE_6F":{"header_address":4765216,"land_encounters":{"address":5608020,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490232},"MAP_MT_PYRE_EXTERIOR":{"header_address":4765244,"land_encounters":{"address":5608076,"slots":[377,377,377,377,37,37,37,37,309,309,309,309]},"warp_table_address":5490316},"MAP_MT_PYRE_SUMMIT":{"header_address":4765272,"land_encounters":{"address":5608132,"slots":[377,377,377,377,377,377,377,361,361,361,411,411]},"warp_table_address":5490656},"MAP_NAVEL_ROCK_B1F":{"header_address":4771320,"warp_table_address":5525524},"MAP_NAVEL_ROCK_BOTTOM":{"header_address":4771824,"warp_table_address":5526248},"MAP_NAVEL_ROCK_DOWN01":{"header_address":4771516,"warp_table_address":5525828},"MAP_NAVEL_ROCK_DOWN02":{"header_address":4771544,"warp_table_address":5525864},"MAP_NAVEL_ROCK_DOWN03":{"header_address":4771572,"warp_table_address":5525900},"MAP_NAVEL_ROCK_DOWN04":{"header_address":4771600,"warp_table_address":5525936},"MAP_NAVEL_ROCK_DOWN05":{"header_address":4771628,"warp_table_address":5525972},"MAP_NAVEL_ROCK_DOWN06":{"header_address":4771656,"warp_table_address":5526008},"MAP_NAVEL_ROCK_DOWN07":{"header_address":4771684,"warp_table_address":5526044},"MAP_NAVEL_ROCK_DOWN08":{"header_address":4771712,"warp_table_address":5526080},"MAP_NAVEL_ROCK_DOWN09":{"header_address":4771740,"warp_table_address":5526116},"MAP_NAVEL_ROCK_DOWN10":{"header_address":4771768,"warp_table_address":5526152},"MAP_NAVEL_ROCK_DOWN11":{"header_address":4771796,"warp_table_address":5526188},"MAP_NAVEL_ROCK_ENTRANCE":{"header_address":4771292,"warp_table_address":5525488},"MAP_NAVEL_ROCK_EXTERIOR":{"header_address":4771236,"warp_table_address":5525376},"MAP_NAVEL_ROCK_FORK":{"header_address":4771348,"warp_table_address":5525560},"MAP_NAVEL_ROCK_HARBOR":{"header_address":4771264,"warp_table_address":5525460},"MAP_NAVEL_ROCK_TOP":{"header_address":4771488,"warp_table_address":5525772},"MAP_NAVEL_ROCK_UP1":{"header_address":4771376,"warp_table_address":5525604},"MAP_NAVEL_ROCK_UP2":{"header_address":4771404,"warp_table_address":5525640},"MAP_NAVEL_ROCK_UP3":{"header_address":4771432,"warp_table_address":5525676},"MAP_NAVEL_ROCK_UP4":{"header_address":4771460,"warp_table_address":5525712},"MAP_NEW_MAUVILLE_ENTRANCE":{"header_address":4766112,"land_encounters":{"address":5610092,"slots":[100,81,100,81,100,81,100,81,100,81,100,81]},"warp_table_address":5495284},"MAP_NEW_MAUVILLE_INSIDE":{"header_address":4766140,"land_encounters":{"address":5607136,"slots":[100,81,100,81,100,81,100,81,100,81,101,82]},"warp_table_address":5495528},"MAP_OLDALE_TOWN":{"header_address":4758272,"warp_table_address":5434860},"MAP_OLDALE_TOWN_HOUSE1":{"header_address":4759728,"warp_table_address":5459276},"MAP_OLDALE_TOWN_HOUSE2":{"header_address":4759756,"warp_table_address":5459360},"MAP_OLDALE_TOWN_MART":{"header_address":4759840,"warp_table_address":5459748},"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":{"header_address":4759784,"warp_table_address":5459492},"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":{"header_address":4759812,"warp_table_address":5459632},"MAP_PACIFIDLOG_TOWN":{"fishing_encounters":{"address":5611816,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758412,"warp_table_address":5436288,"water_encounters":{"address":5611788,"slots":[72,309,309,310,310]}},"MAP_PACIFIDLOG_TOWN_HOUSE1":{"header_address":4760764,"warp_table_address":5464400},"MAP_PACIFIDLOG_TOWN_HOUSE2":{"header_address":4760792,"warp_table_address":5464508},"MAP_PACIFIDLOG_TOWN_HOUSE3":{"header_address":4760820,"warp_table_address":5464592},"MAP_PACIFIDLOG_TOWN_HOUSE4":{"header_address":4760848,"warp_table_address":5464700},"MAP_PACIFIDLOG_TOWN_HOUSE5":{"header_address":4760876,"warp_table_address":5464784},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":{"header_address":4760708,"warp_table_address":5464168},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":{"header_address":4760736,"warp_table_address":5464308},"MAP_PETALBURG_CITY":{"fishing_encounters":{"address":5611968,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4757992,"warp_table_address":5428704,"water_encounters":{"address":5611940,"slots":[183,183,183,183,183]}},"MAP_PETALBURG_CITY_GYM":{"header_address":4760932,"warp_table_address":5465168},"MAP_PETALBURG_CITY_HOUSE1":{"header_address":4760960,"warp_table_address":5465708},"MAP_PETALBURG_CITY_HOUSE2":{"header_address":4760988,"warp_table_address":5465792},"MAP_PETALBURG_CITY_MART":{"header_address":4761072,"warp_table_address":5466228},"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":{"header_address":4761016,"warp_table_address":5465948},"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":{"header_address":4761044,"warp_table_address":5466088},"MAP_PETALBURG_CITY_WALLYS_HOUSE":{"header_address":4760904,"warp_table_address":5464868},"MAP_PETALBURG_WOODS":{"header_address":4764964,"land_encounters":{"address":5605876,"slots":[286,290,306,286,291,293,290,306,304,364,304,364]},"warp_table_address":5487772},"MAP_RECORD_CORNER":{"header_address":4768408,"warp_table_address":5510036},"MAP_ROUTE101":{"header_address":4758440,"land_encounters":{"address":5604388,"slots":[290,286,290,290,286,286,290,286,288,288,288,288]},"warp_table_address":4160749568},"MAP_ROUTE102":{"fishing_encounters":{"address":5604528,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758468,"land_encounters":{"address":5604444,"slots":[286,290,286,290,295,295,288,288,288,392,288,298]},"warp_table_address":4160749568,"water_encounters":{"address":5604500,"slots":[183,183,183,183,118]}},"MAP_ROUTE103":{"fishing_encounters":{"address":5604660,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758496,"land_encounters":{"address":5604576,"slots":[286,286,286,286,309,288,288,288,309,309,309,309]},"warp_table_address":5437452,"water_encounters":{"address":5604632,"slots":[72,309,309,310,310]}},"MAP_ROUTE104":{"fishing_encounters":{"address":5604792,"slots":[129,129,129,129,129,129,129,129,129,129]},"header_address":4758524,"land_encounters":{"address":5604708,"slots":[286,290,286,183,183,286,304,304,309,309,309,309]},"warp_table_address":5438308,"water_encounters":{"address":5604764,"slots":[309,309,309,310,310]}},"MAP_ROUTE104_MR_BRINEYS_HOUSE":{"header_address":4764320,"warp_table_address":5484676},"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4764348,"warp_table_address":5484784},"MAP_ROUTE104_PROTOTYPE":{"header_address":4771880,"warp_table_address":4160749568},"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4771908,"warp_table_address":4160749568},"MAP_ROUTE105":{"fishing_encounters":{"address":5604868,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758552,"warp_table_address":5438720,"water_encounters":{"address":5604840,"slots":[72,309,309,310,310]}},"MAP_ROUTE106":{"fishing_encounters":{"address":5606728,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758580,"warp_table_address":5438892,"water_encounters":{"address":5606700,"slots":[72,309,309,310,310]}},"MAP_ROUTE107":{"fishing_encounters":{"address":5606804,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758608,"warp_table_address":4160749568,"water_encounters":{"address":5606776,"slots":[72,309,309,310,310]}},"MAP_ROUTE108":{"fishing_encounters":{"address":5606880,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758636,"warp_table_address":5439324,"water_encounters":{"address":5606852,"slots":[72,309,309,310,310]}},"MAP_ROUTE109":{"fishing_encounters":{"address":5606956,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758664,"warp_table_address":5439940,"water_encounters":{"address":5606928,"slots":[72,309,309,310,310]}},"MAP_ROUTE109_SEASHORE_HOUSE":{"header_address":4771936,"warp_table_address":5526472},"MAP_ROUTE110":{"fishing_encounters":{"address":5605000,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758692,"land_encounters":{"address":5604916,"slots":[286,337,367,337,354,43,354,367,309,309,353,353]},"warp_table_address":5440928,"water_encounters":{"address":5604972,"slots":[72,309,309,310,310]}},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":{"header_address":4772272,"warp_table_address":5529400},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":{"header_address":4772300,"warp_table_address":5529508},"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":{"header_address":4772020,"warp_table_address":5526740},"MAP_ROUTE110_TRICK_HOUSE_END":{"header_address":4771992,"warp_table_address":5526676},"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":{"header_address":4771964,"warp_table_address":5526532},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":{"header_address":4772048,"warp_table_address":5527152},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":{"header_address":4772076,"warp_table_address":5527328},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":{"header_address":4772104,"warp_table_address":5527616},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":{"header_address":4772132,"warp_table_address":5528072},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":{"header_address":4772160,"warp_table_address":5528248},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":{"header_address":4772188,"warp_table_address":5528752},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":{"header_address":4772216,"warp_table_address":5529024},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":{"header_address":4772244,"warp_table_address":5529320},"MAP_ROUTE111":{"fishing_encounters":{"address":5605160,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758720,"land_encounters":{"address":5605048,"slots":[27,332,27,332,318,318,27,332,318,344,344,344]},"rock_smash_encounters":{"address":5605132,"slots":[74,74,74,74,74]},"warp_table_address":5442448,"water_encounters":{"address":5605104,"slots":[183,183,183,183,118]}},"MAP_ROUTE111_OLD_LADYS_REST_STOP":{"header_address":4764404,"warp_table_address":5484976},"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":{"header_address":4764376,"warp_table_address":5484916},"MAP_ROUTE112":{"header_address":4758748,"land_encounters":{"address":5605208,"slots":[339,339,183,339,339,183,339,183,339,339,339,339]},"warp_table_address":5443604},"MAP_ROUTE112_CABLE_CAR_STATION":{"header_address":4764432,"warp_table_address":5485060},"MAP_ROUTE113":{"header_address":4758776,"land_encounters":{"address":5605264,"slots":[308,308,218,308,308,218,308,218,308,227,308,227]},"warp_table_address":5444092},"MAP_ROUTE113_GLASS_WORKSHOP":{"header_address":4772328,"warp_table_address":5529640},"MAP_ROUTE114":{"fishing_encounters":{"address":5605432,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758804,"land_encounters":{"address":5605320,"slots":[358,295,358,358,295,296,296,296,379,379,379,299]},"rock_smash_encounters":{"address":5605404,"slots":[74,74,74,74,74]},"warp_table_address":5445184,"water_encounters":{"address":5605376,"slots":[183,183,183,183,118]}},"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":{"header_address":4764488,"warp_table_address":5485204},"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":{"header_address":4764516,"warp_table_address":5485320},"MAP_ROUTE114_LANETTES_HOUSE":{"header_address":4764544,"warp_table_address":5485420},"MAP_ROUTE115":{"fishing_encounters":{"address":5607088,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758832,"land_encounters":{"address":5607004,"slots":[358,304,358,304,304,305,39,39,309,309,309,309]},"warp_table_address":5445988,"water_encounters":{"address":5607060,"slots":[72,309,309,310,310]}},"MAP_ROUTE116":{"header_address":4758860,"land_encounters":{"address":5605480,"slots":[286,370,301,63,301,304,304,304,286,286,315,315]},"warp_table_address":5446872},"MAP_ROUTE116_TUNNELERS_REST_HOUSE":{"header_address":4764572,"warp_table_address":5485564},"MAP_ROUTE117":{"fishing_encounters":{"address":5605620,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758888,"land_encounters":{"address":5605536,"slots":[286,43,286,43,183,43,387,387,387,387,386,298]},"warp_table_address":5447656,"water_encounters":{"address":5605592,"slots":[183,183,183,183,118]}},"MAP_ROUTE117_POKEMON_DAY_CARE":{"header_address":4764600,"warp_table_address":5485624},"MAP_ROUTE118":{"fishing_encounters":{"address":5605752,"slots":[129,72,129,72,330,331,330,330,330,330]},"header_address":4758916,"land_encounters":{"address":5605668,"slots":[288,337,288,337,289,338,309,309,309,309,309,317]},"warp_table_address":5448236,"water_encounters":{"address":5605724,"slots":[72,309,309,310,310]}},"MAP_ROUTE119":{"fishing_encounters":{"address":5607276,"slots":[129,72,129,72,330,330,330,330,330,330]},"header_address":4758944,"land_encounters":{"address":5607192,"slots":[288,289,288,43,289,43,43,43,369,369,369,317]},"warp_table_address":5449460,"water_encounters":{"address":5607248,"slots":[72,309,309,310,310]}},"MAP_ROUTE119_HOUSE":{"header_address":4772440,"warp_table_address":5530360},"MAP_ROUTE119_WEATHER_INSTITUTE_1F":{"header_address":4772384,"warp_table_address":5529880},"MAP_ROUTE119_WEATHER_INSTITUTE_2F":{"header_address":4772412,"warp_table_address":5530164},"MAP_ROUTE120":{"fishing_encounters":{"address":5607408,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758972,"land_encounters":{"address":5607324,"slots":[286,287,287,43,183,43,43,183,376,376,317,298]},"warp_table_address":5451160,"water_encounters":{"address":5607380,"slots":[183,183,183,183,118]}},"MAP_ROUTE121":{"fishing_encounters":{"address":5607540,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759000,"land_encounters":{"address":5607456,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5452364,"water_encounters":{"address":5607512,"slots":[72,309,309,310,310]}},"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":{"header_address":4764628,"warp_table_address":5485732},"MAP_ROUTE122":{"fishing_encounters":{"address":5607616,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759028,"warp_table_address":5452576,"water_encounters":{"address":5607588,"slots":[72,309,309,310,310]}},"MAP_ROUTE123":{"fishing_encounters":{"address":5607748,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759056,"land_encounters":{"address":5607664,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5453636,"water_encounters":{"address":5607720,"slots":[72,309,309,310,310]}},"MAP_ROUTE123_BERRY_MASTERS_HOUSE":{"header_address":4772356,"warp_table_address":5529724},"MAP_ROUTE124":{"fishing_encounters":{"address":5605828,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759084,"warp_table_address":5454436,"water_encounters":{"address":5605800,"slots":[72,309,309,310,310]}},"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":{"header_address":4772468,"warp_table_address":5530420},"MAP_ROUTE125":{"fishing_encounters":{"address":5608272,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759112,"warp_table_address":5454716,"water_encounters":{"address":5608244,"slots":[72,309,309,310,310]}},"MAP_ROUTE126":{"fishing_encounters":{"address":5608348,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759140,"warp_table_address":4160749568,"water_encounters":{"address":5608320,"slots":[72,309,309,310,310]}},"MAP_ROUTE127":{"fishing_encounters":{"address":5608424,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759168,"warp_table_address":4160749568,"water_encounters":{"address":5608396,"slots":[72,309,309,310,310]}},"MAP_ROUTE128":{"fishing_encounters":{"address":5608500,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4759196,"warp_table_address":4160749568,"water_encounters":{"address":5608472,"slots":[72,309,309,310,310]}},"MAP_ROUTE129":{"fishing_encounters":{"address":5608576,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759224,"warp_table_address":4160749568,"water_encounters":{"address":5608548,"slots":[72,309,309,310,314]}},"MAP_ROUTE130":{"fishing_encounters":{"address":5608708,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759252,"land_encounters":{"address":5608624,"slots":[360,360,360,360,360,360,360,360,360,360,360,360]},"warp_table_address":4160749568,"water_encounters":{"address":5608680,"slots":[72,309,309,310,310]}},"MAP_ROUTE131":{"fishing_encounters":{"address":5608784,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759280,"warp_table_address":5456116,"water_encounters":{"address":5608756,"slots":[72,309,309,310,310]}},"MAP_ROUTE132":{"fishing_encounters":{"address":5608860,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759308,"warp_table_address":4160749568,"water_encounters":{"address":5608832,"slots":[72,309,309,310,310]}},"MAP_ROUTE133":{"fishing_encounters":{"address":5608936,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759336,"warp_table_address":4160749568,"water_encounters":{"address":5608908,"slots":[72,309,309,310,310]}},"MAP_ROUTE134":{"fishing_encounters":{"address":5609012,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759364,"warp_table_address":4160749568,"water_encounters":{"address":5608984,"slots":[72,309,309,310,310]}},"MAP_RUSTBORO_CITY":{"header_address":4758076,"warp_table_address":5430936},"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":{"header_address":4762024,"warp_table_address":5472204},"MAP_RUSTBORO_CITY_DEVON_CORP_1F":{"header_address":4761716,"warp_table_address":5470532},"MAP_RUSTBORO_CITY_DEVON_CORP_2F":{"header_address":4761744,"warp_table_address":5470744},"MAP_RUSTBORO_CITY_DEVON_CORP_3F":{"header_address":4761772,"warp_table_address":5470852},"MAP_RUSTBORO_CITY_FLAT1_1F":{"header_address":4761940,"warp_table_address":5471808},"MAP_RUSTBORO_CITY_FLAT1_2F":{"header_address":4761968,"warp_table_address":5472044},"MAP_RUSTBORO_CITY_FLAT2_1F":{"header_address":4762080,"warp_table_address":5472372},"MAP_RUSTBORO_CITY_FLAT2_2F":{"header_address":4762108,"warp_table_address":5472464},"MAP_RUSTBORO_CITY_FLAT2_3F":{"header_address":4762136,"warp_table_address":5472548},"MAP_RUSTBORO_CITY_GYM":{"header_address":4761800,"warp_table_address":5471024},"MAP_RUSTBORO_CITY_HOUSE1":{"header_address":4761996,"warp_table_address":5472120},"MAP_RUSTBORO_CITY_HOUSE2":{"header_address":4762052,"warp_table_address":5472288},"MAP_RUSTBORO_CITY_HOUSE3":{"header_address":4762164,"warp_table_address":5472648},"MAP_RUSTBORO_CITY_MART":{"header_address":4761912,"warp_table_address":5471724},"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":{"header_address":4761856,"warp_table_address":5471444},"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":{"header_address":4761884,"warp_table_address":5471584},"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":{"header_address":4761828,"warp_table_address":5471252},"MAP_RUSTURF_TUNNEL":{"header_address":4764768,"land_encounters":{"address":5605932,"slots":[370,370,370,370,370,370,370,370,370,370,370,370]},"warp_table_address":5486644},"MAP_SAFARI_ZONE_NORTH":{"header_address":4769416,"land_encounters":{"address":5610280,"slots":[231,43,231,43,177,44,44,177,178,214,178,214]},"rock_smash_encounters":{"address":5610336,"slots":[74,74,74,74,74]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHEAST":{"header_address":4769724,"land_encounters":{"address":5612476,"slots":[190,216,190,216,191,165,163,204,228,241,228,241]},"rock_smash_encounters":{"address":5612532,"slots":[213,213,213,213,213]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHWEST":{"fishing_encounters":{"address":5610448,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769388,"land_encounters":{"address":5610364,"slots":[111,43,111,43,84,44,44,84,85,127,85,127]},"warp_table_address":4160749568,"water_encounters":{"address":5610420,"slots":[54,54,54,55,55]}},"MAP_SAFARI_ZONE_REST_HOUSE":{"header_address":4769696,"warp_table_address":5516996},"MAP_SAFARI_ZONE_SOUTH":{"header_address":4769472,"land_encounters":{"address":5606212,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515444},"MAP_SAFARI_ZONE_SOUTHEAST":{"fishing_encounters":{"address":5612428,"slots":[129,118,129,118,223,118,223,223,223,224]},"header_address":4769752,"land_encounters":{"address":5612344,"slots":[191,179,191,179,190,167,163,209,234,207,234,207]},"warp_table_address":4160749568,"water_encounters":{"address":5612400,"slots":[194,183,183,183,195]}},"MAP_SAFARI_ZONE_SOUTHWEST":{"fishing_encounters":{"address":5610232,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769444,"land_encounters":{"address":5610148,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515260,"water_encounters":{"address":5610204,"slots":[54,54,54,54,54]}},"MAP_SCORCHED_SLAB":{"header_address":4766700,"warp_table_address":5498144},"MAP_SEAFLOOR_CAVERN_ENTRANCE":{"fishing_encounters":{"address":5609764,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765412,"warp_table_address":5491796,"water_encounters":{"address":5609736,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM1":{"header_address":4765440,"land_encounters":{"address":5609136,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5491952},"MAP_SEAFLOOR_CAVERN_ROOM2":{"header_address":4765468,"land_encounters":{"address":5609192,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492188},"MAP_SEAFLOOR_CAVERN_ROOM3":{"header_address":4765496,"land_encounters":{"address":5609248,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492456},"MAP_SEAFLOOR_CAVERN_ROOM4":{"header_address":4765524,"land_encounters":{"address":5609304,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492548},"MAP_SEAFLOOR_CAVERN_ROOM5":{"header_address":4765552,"land_encounters":{"address":5609360,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492744},"MAP_SEAFLOOR_CAVERN_ROOM6":{"fishing_encounters":{"address":5609500,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765580,"land_encounters":{"address":5609416,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492788,"water_encounters":{"address":5609472,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM7":{"fishing_encounters":{"address":5609632,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765608,"land_encounters":{"address":5609548,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492832,"water_encounters":{"address":5609604,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM8":{"header_address":4765636,"land_encounters":{"address":5609680,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493156},"MAP_SEAFLOOR_CAVERN_ROOM9":{"header_address":4765664,"warp_table_address":5493360},"MAP_SEALED_CHAMBER_INNER_ROOM":{"header_address":4766672,"warp_table_address":5497984},"MAP_SEALED_CHAMBER_OUTER_ROOM":{"header_address":4766644,"warp_table_address":5497608},"MAP_SECRET_BASE_BLUE_CAVE1":{"header_address":4767736,"warp_table_address":5501652},"MAP_SECRET_BASE_BLUE_CAVE2":{"header_address":4767904,"warp_table_address":5503980},"MAP_SECRET_BASE_BLUE_CAVE3":{"header_address":4768072,"warp_table_address":5506308},"MAP_SECRET_BASE_BLUE_CAVE4":{"header_address":4768240,"warp_table_address":5508636},"MAP_SECRET_BASE_BROWN_CAVE1":{"header_address":4767708,"warp_table_address":5501264},"MAP_SECRET_BASE_BROWN_CAVE2":{"header_address":4767876,"warp_table_address":5503592},"MAP_SECRET_BASE_BROWN_CAVE3":{"header_address":4768044,"warp_table_address":5505920},"MAP_SECRET_BASE_BROWN_CAVE4":{"header_address":4768212,"warp_table_address":5508248},"MAP_SECRET_BASE_RED_CAVE1":{"header_address":4767680,"warp_table_address":5500876},"MAP_SECRET_BASE_RED_CAVE2":{"header_address":4767848,"warp_table_address":5503204},"MAP_SECRET_BASE_RED_CAVE3":{"header_address":4768016,"warp_table_address":5505532},"MAP_SECRET_BASE_RED_CAVE4":{"header_address":4768184,"warp_table_address":5507860},"MAP_SECRET_BASE_SHRUB1":{"header_address":4767820,"warp_table_address":5502816},"MAP_SECRET_BASE_SHRUB2":{"header_address":4767988,"warp_table_address":5505144},"MAP_SECRET_BASE_SHRUB3":{"header_address":4768156,"warp_table_address":5507472},"MAP_SECRET_BASE_SHRUB4":{"header_address":4768324,"warp_table_address":5509800},"MAP_SECRET_BASE_TREE1":{"header_address":4767792,"warp_table_address":5502428},"MAP_SECRET_BASE_TREE2":{"header_address":4767960,"warp_table_address":5504756},"MAP_SECRET_BASE_TREE3":{"header_address":4768128,"warp_table_address":5507084},"MAP_SECRET_BASE_TREE4":{"header_address":4768296,"warp_table_address":5509412},"MAP_SECRET_BASE_YELLOW_CAVE1":{"header_address":4767764,"warp_table_address":5502040},"MAP_SECRET_BASE_YELLOW_CAVE2":{"header_address":4767932,"warp_table_address":5504368},"MAP_SECRET_BASE_YELLOW_CAVE3":{"header_address":4768100,"warp_table_address":5506696},"MAP_SECRET_BASE_YELLOW_CAVE4":{"header_address":4768268,"warp_table_address":5509024},"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":{"header_address":4766056,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":{"header_address":4766084,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":{"fishing_encounters":{"address":5611436,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765944,"land_encounters":{"address":5611352,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494828,"water_encounters":{"address":5611408,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":{"header_address":4766980,"land_encounters":{"address":5612044,"slots":[41,341,41,341,41,341,346,341,42,346,42,346]},"warp_table_address":5498544},"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":{"fishing_encounters":{"address":5611304,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765972,"land_encounters":{"address":5611220,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494904,"water_encounters":{"address":5611276,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":{"header_address":4766028,"land_encounters":{"address":5611164,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495180},"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":{"header_address":4766000,"land_encounters":{"address":5611108,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495084},"MAP_SKY_PILLAR_1F":{"header_address":4766868,"land_encounters":{"address":5612100,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498328},"MAP_SKY_PILLAR_2F":{"header_address":4766896,"warp_table_address":5498372},"MAP_SKY_PILLAR_3F":{"header_address":4766924,"land_encounters":{"address":5612232,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498408},"MAP_SKY_PILLAR_4F":{"header_address":4766952,"warp_table_address":5498452},"MAP_SKY_PILLAR_5F":{"header_address":4767008,"land_encounters":{"address":5612288,"slots":[322,42,42,322,319,378,378,319,319,359,359,359]},"warp_table_address":5498572},"MAP_SKY_PILLAR_ENTRANCE":{"header_address":4766812,"warp_table_address":5498232},"MAP_SKY_PILLAR_OUTSIDE":{"header_address":4766840,"warp_table_address":5498292},"MAP_SKY_PILLAR_TOP":{"header_address":4767036,"warp_table_address":5498656},"MAP_SLATEPORT_CITY":{"fishing_encounters":{"address":5611664,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758020,"warp_table_address":5429836,"water_encounters":{"address":5611636,"slots":[72,309,309,310,310]}},"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":{"header_address":4761212,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":{"header_address":4761184,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":{"header_address":4761156,"warp_table_address":5466624},"MAP_SLATEPORT_CITY_HARBOR":{"header_address":4761352,"warp_table_address":5468328},"MAP_SLATEPORT_CITY_HOUSE":{"header_address":4761380,"warp_table_address":5468492},"MAP_SLATEPORT_CITY_MART":{"header_address":4761464,"warp_table_address":5468856},"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":{"header_address":4761240,"warp_table_address":5466832},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":{"header_address":4761296,"warp_table_address":5467456},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":{"header_address":4761324,"warp_table_address":5467856},"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":{"header_address":4761408,"warp_table_address":5468600},"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":{"header_address":4761436,"warp_table_address":5468740},"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":{"header_address":4761268,"warp_table_address":5467084},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":{"header_address":4761100,"warp_table_address":5466360},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":{"header_address":4761128,"warp_table_address":5466476},"MAP_SOOTOPOLIS_CITY":{"fishing_encounters":{"address":5612184,"slots":[129,72,129,129,129,129,129,130,130,130]},"header_address":4758188,"warp_table_address":5433852,"water_encounters":{"address":5612156,"slots":[129,129,129,129,129]}},"MAP_SOOTOPOLIS_CITY_GYM_1F":{"header_address":4763480,"warp_table_address":5481892},"MAP_SOOTOPOLIS_CITY_GYM_B1F":{"header_address":4763508,"warp_table_address":5482200},"MAP_SOOTOPOLIS_CITY_HOUSE1":{"header_address":4763620,"warp_table_address":5482664},"MAP_SOOTOPOLIS_CITY_HOUSE2":{"header_address":4763648,"warp_table_address":5482724},"MAP_SOOTOPOLIS_CITY_HOUSE3":{"header_address":4763676,"warp_table_address":5482808},"MAP_SOOTOPOLIS_CITY_HOUSE4":{"header_address":4763704,"warp_table_address":5482916},"MAP_SOOTOPOLIS_CITY_HOUSE5":{"header_address":4763732,"warp_table_address":5483000},"MAP_SOOTOPOLIS_CITY_HOUSE6":{"header_address":4763760,"warp_table_address":5483060},"MAP_SOOTOPOLIS_CITY_HOUSE7":{"header_address":4763788,"warp_table_address":5483144},"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":{"header_address":4763816,"warp_table_address":5483228},"MAP_SOOTOPOLIS_CITY_MART":{"header_address":4763592,"warp_table_address":5482580},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":{"header_address":4763844,"warp_table_address":5483312},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":{"header_address":4763872,"warp_table_address":5483380},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":{"header_address":4763536,"warp_table_address":5482324},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":{"header_address":4763564,"warp_table_address":5482464},"MAP_SOUTHERN_ISLAND_EXTERIOR":{"header_address":4769640,"warp_table_address":5516780},"MAP_SOUTHERN_ISLAND_INTERIOR":{"header_address":4769668,"warp_table_address":5516876},"MAP_SS_TIDAL_CORRIDOR":{"header_address":4768828,"warp_table_address":5510992},"MAP_SS_TIDAL_LOWER_DECK":{"header_address":4768856,"warp_table_address":5511276},"MAP_SS_TIDAL_ROOMS":{"header_address":4768884,"warp_table_address":5511508},"MAP_TERRA_CAVE_END":{"header_address":4767596,"warp_table_address":5500392},"MAP_TERRA_CAVE_ENTRANCE":{"header_address":4767568,"warp_table_address":5500332},"MAP_TRADE_CENTER":{"header_address":4768380,"warp_table_address":5509944},"MAP_TRAINER_HILL_1F":{"header_address":4771096,"warp_table_address":5525172},"MAP_TRAINER_HILL_2F":{"header_address":4771124,"warp_table_address":5525208},"MAP_TRAINER_HILL_3F":{"header_address":4771152,"warp_table_address":5525244},"MAP_TRAINER_HILL_4F":{"header_address":4771180,"warp_table_address":5525280},"MAP_TRAINER_HILL_ELEVATOR":{"header_address":4771852,"warp_table_address":5526300},"MAP_TRAINER_HILL_ENTRANCE":{"header_address":4771068,"warp_table_address":5525100},"MAP_TRAINER_HILL_ROOF":{"header_address":4771208,"warp_table_address":5525340},"MAP_UNDERWATER_MARINE_CAVE":{"header_address":4767484,"warp_table_address":5500208},"MAP_UNDERWATER_ROUTE105":{"header_address":4759532,"warp_table_address":5457348},"MAP_UNDERWATER_ROUTE124":{"header_address":4759392,"warp_table_address":4160749568,"water_encounters":{"address":5612016,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE125":{"header_address":4759560,"warp_table_address":5457384},"MAP_UNDERWATER_ROUTE126":{"header_address":4759420,"warp_table_address":5457052,"water_encounters":{"address":5606268,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE127":{"header_address":4759448,"warp_table_address":5457176},"MAP_UNDERWATER_ROUTE128":{"header_address":4759476,"warp_table_address":5457260},"MAP_UNDERWATER_ROUTE129":{"header_address":4759504,"warp_table_address":5457312},"MAP_UNDERWATER_ROUTE134":{"header_address":4766588,"warp_table_address":5497540},"MAP_UNDERWATER_SEAFLOOR_CAVERN":{"header_address":4765384,"warp_table_address":5491744},"MAP_UNDERWATER_SEALED_CHAMBER":{"header_address":4766616,"warp_table_address":5497568},"MAP_UNDERWATER_SOOTOPOLIS_CITY":{"header_address":4764796,"warp_table_address":5486768},"MAP_UNION_ROOM":{"header_address":4769360,"warp_table_address":5514872},"MAP_UNUSED_CONTEST_HALL1":{"header_address":4768492,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL2":{"header_address":4768520,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL3":{"header_address":4768548,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL4":{"header_address":4768576,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL5":{"header_address":4768604,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL6":{"header_address":4768632,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN":{"header_address":4758384,"warp_table_address":5436044},"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760512,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760484,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760456,"warp_table_address":5463128},"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":{"header_address":4760652,"warp_table_address":5463928},"MAP_VERDANTURF_TOWN_HOUSE":{"header_address":4760680,"warp_table_address":5464012},"MAP_VERDANTURF_TOWN_MART":{"header_address":4760540,"warp_table_address":5463408},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":{"header_address":4760568,"warp_table_address":5463540},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":{"header_address":4760596,"warp_table_address":5463680},"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":{"header_address":4760624,"warp_table_address":5463844},"MAP_VICTORY_ROAD_1F":{"header_address":4765860,"land_encounters":{"address":5606156,"slots":[42,336,383,371,41,335,42,336,382,370,382,370]},"warp_table_address":5493852},"MAP_VICTORY_ROAD_B1F":{"header_address":4765888,"land_encounters":{"address":5610496,"slots":[42,336,383,383,42,336,42,336,383,355,383,355]},"rock_smash_encounters":{"address":5610552,"slots":[75,74,75,75,75]},"warp_table_address":5494460},"MAP_VICTORY_ROAD_B2F":{"fishing_encounters":{"address":5610664,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4765916,"land_encounters":{"address":5610580,"slots":[42,322,383,383,42,322,42,322,383,355,383,355]},"warp_table_address":5494704,"water_encounters":{"address":5610636,"slots":[42,42,42,42,42]}}},"misc_pokemon":[{"address":2572358,"species":385},{"address":2018148,"species":360},{"address":2323175,"species":101},{"address":2323252,"species":101},{"address":2581669,"species":317},{"address":2581574,"species":317},{"address":2581688,"species":317},{"address":2581593,"species":317},{"address":2581612,"species":317},{"address":2581631,"species":317},{"address":2581650,"species":317},{"address":2065036,"species":317},{"address":2386223,"species":185},{"address":2339323,"species":100},{"address":2339400,"species":100},{"address":2339477,"species":100}],"misc_ram_addresses":{"CB2_Overworld":134768624,"gArchipelagoDeathLinkQueued":33804824,"gArchipelagoReceivedItem":33804776,"gMain":50340544,"gPlayerParty":33703196,"gSaveBlock1Ptr":50355596,"gSaveBlock2Ptr":50355600},"misc_rom_addresses":{"gArchipelagoInfo":5912960,"gArchipelagoItemNames":5896457,"gArchipelagoNameTable":5905457,"gArchipelagoOptions":5895556,"gArchipelagoPlayerNames":5895607,"gBattleMoves":3281380,"gEvolutionTable":3318404,"gLevelUpLearnsets":3334884,"gRandomizedBerryTreeItems":5843560,"gRandomizedSoundTable":10155508,"gSpeciesInfo":3296744,"gTMHMLearnsets":3289780,"gTrainers":3230072,"gTutorMoves":6428060,"sFanfares":5422580,"sNewGamePCItems":6210444,"sStarterMon":6021752,"sTMHMMoves":6432208,"sTutorLearnsets":6428120},"species":[{"abilities":[0,0],"address":3296744,"base_stats":[0,0,0,0,0,0],"catch_rate":0,"evolutions":[],"friendship":0,"id":0,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3296772,"base_stats":[45,49,49,45,65,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":2}],"friendship":70,"id":1,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296800,"base_stats":[60,62,63,60,80,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":3}],"friendship":70,"id":2,"learnset":{"address":3308308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":38,"move_id":74},{"level":47,"move_id":235},{"level":56,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296828,"base_stats":[80,82,83,80,100,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":3,"learnset":{"address":3308338,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":1,"move_id":22},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":41,"move_id":74},{"level":53,"move_id":235},{"level":65,"move_id":76}]},"tmhm_learnset":"00E41E0886354730","types":[12,3]},{"abilities":[66,0],"address":3296856,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":5}],"friendship":70,"id":4,"learnset":{"address":3308368,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":19,"move_id":99},{"level":25,"move_id":184},{"level":31,"move_id":53},{"level":37,"move_id":163},{"level":43,"move_id":82},{"level":49,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296884,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":6}],"friendship":70,"id":5,"learnset":{"address":3308394,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":41,"move_id":163},{"level":48,"move_id":82},{"level":55,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296912,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":6,"learnset":{"address":3308420,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":1,"move_id":108},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":36,"move_id":17},{"level":44,"move_id":163},{"level":54,"move_id":82},{"level":64,"move_id":83}]},"tmhm_learnset":"00AE5EA4CE514633","types":[10,2]},{"abilities":[67,0],"address":3296940,"base_stats":[44,48,65,43,50,64],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":8}],"friendship":70,"id":7,"learnset":{"address":3308448,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":18,"move_id":44},{"level":23,"move_id":229},{"level":28,"move_id":182},{"level":33,"move_id":240},{"level":40,"move_id":130},{"level":47,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296968,"base_stats":[59,63,80,58,65,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":9}],"friendship":70,"id":8,"learnset":{"address":3308478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":37,"move_id":240},{"level":45,"move_id":130},{"level":53,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296996,"base_stats":[79,83,100,78,85,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":9,"learnset":{"address":3308508,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":1,"move_id":110},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":42,"move_id":240},{"level":55,"move_id":130},{"level":68,"move_id":56}]},"tmhm_learnset":"03B01E00CE537275","types":[11,11]},{"abilities":[19,0],"address":3297024,"base_stats":[45,30,35,45,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":11}],"friendship":70,"id":10,"learnset":{"address":3308538,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3297052,"base_stats":[50,20,55,30,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":12}],"friendship":70,"id":11,"learnset":{"address":3308548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[14,0],"address":3297080,"base_stats":[60,45,50,70,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":12,"learnset":{"address":3308560,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":77},{"level":14,"move_id":78},{"level":15,"move_id":79},{"level":18,"move_id":48},{"level":23,"move_id":18},{"level":28,"move_id":16},{"level":34,"move_id":60},{"level":40,"move_id":219},{"level":47,"move_id":318}]},"tmhm_learnset":"0040BE80B43F4620","types":[6,2]},{"abilities":[19,0],"address":3297108,"base_stats":[40,35,30,50,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":14}],"friendship":70,"id":13,"learnset":{"address":3308590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[61,0],"address":3297136,"base_stats":[45,25,50,35,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":15}],"friendship":70,"id":14,"learnset":{"address":3308600,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[68,0],"address":3297164,"base_stats":[65,80,40,75,45,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":15,"learnset":{"address":3308612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":31},{"level":10,"move_id":31},{"level":15,"move_id":116},{"level":20,"move_id":41},{"level":25,"move_id":99},{"level":30,"move_id":228},{"level":35,"move_id":42},{"level":40,"move_id":97},{"level":45,"move_id":283}]},"tmhm_learnset":"00843E88C4354620","types":[6,3]},{"abilities":[51,0],"address":3297192,"base_stats":[40,45,40,56,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":17}],"friendship":70,"id":16,"learnset":{"address":3308638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":19,"move_id":18},{"level":25,"move_id":17},{"level":31,"move_id":297},{"level":39,"move_id":97},{"level":47,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297220,"base_stats":[63,60,55,71,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":18}],"friendship":70,"id":17,"learnset":{"address":3308664,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":43,"move_id":97},{"level":52,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297248,"base_stats":[83,80,75,91,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":18,"learnset":{"address":3308690,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":1,"move_id":98},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":48,"move_id":97},{"level":62,"move_id":119}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[50,62],"address":3297276,"base_stats":[30,56,35,72,25,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":20}],"friendship":70,"id":19,"learnset":{"address":3308716,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":116},{"level":27,"move_id":228},{"level":34,"move_id":162},{"level":41,"move_id":283}]},"tmhm_learnset":"00843E02ADD33E20","types":[0,0]},{"abilities":[50,62],"address":3297304,"base_stats":[55,81,60,97,50,70],"catch_rate":127,"evolutions":[],"friendship":70,"id":20,"learnset":{"address":3308738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":184},{"level":30,"move_id":228},{"level":40,"move_id":162},{"level":50,"move_id":283}]},"tmhm_learnset":"00A43E02ADD37E30","types":[0,0]},{"abilities":[51,0],"address":3297332,"base_stats":[40,60,30,70,31,31],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":22}],"friendship":70,"id":21,"learnset":{"address":3308760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":19,"move_id":228},{"level":25,"move_id":332},{"level":31,"move_id":119},{"level":37,"move_id":65},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297360,"base_stats":[65,90,65,100,61,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":22,"learnset":{"address":3308784,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":43},{"level":1,"move_id":31},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":26,"move_id":228},{"level":32,"move_id":119},{"level":40,"move_id":65},{"level":47,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[22,61],"address":3297388,"base_stats":[35,60,44,55,40,54],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":24}],"friendship":70,"id":23,"learnset":{"address":3308806,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":25,"move_id":103},{"level":32,"move_id":51},{"level":37,"move_id":254},{"level":37,"move_id":256},{"level":37,"move_id":255},{"level":44,"move_id":114}]},"tmhm_learnset":"00213F088E570620","types":[3,3]},{"abilities":[22,61],"address":3297416,"base_stats":[60,85,69,80,65,79],"catch_rate":90,"evolutions":[],"friendship":70,"id":24,"learnset":{"address":3308834,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":40},{"level":1,"move_id":44},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":28,"move_id":103},{"level":38,"move_id":51},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255},{"level":56,"move_id":114}]},"tmhm_learnset":"00213F088E574620","types":[3,3]},{"abilities":[9,0],"address":3297444,"base_stats":[35,55,30,90,50,40],"catch_rate":190,"evolutions":[{"method":"ITEM","param":96,"species":26}],"friendship":70,"id":25,"learnset":{"address":3308862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":45},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":98},{"level":15,"move_id":104},{"level":20,"move_id":21},{"level":26,"move_id":85},{"level":33,"move_id":97},{"level":41,"move_id":87},{"level":50,"move_id":113}]},"tmhm_learnset":"00E01E02CDD38221","types":[13,13]},{"abilities":[9,0],"address":3297472,"base_stats":[60,90,55,100,90,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":26,"learnset":{"address":3308890,"moves":[{"level":1,"move_id":84},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":1,"move_id":85}]},"tmhm_learnset":"00E03E02CDD3C221","types":[13,13]},{"abilities":[8,0],"address":3297500,"base_stats":[50,75,85,40,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":28}],"friendship":70,"id":27,"learnset":{"address":3308900,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":23,"move_id":163},{"level":30,"move_id":129},{"level":37,"move_id":154},{"level":45,"move_id":328},{"level":53,"move_id":201}]},"tmhm_learnset":"00A43ED0CE510621","types":[4,4]},{"abilities":[8,0],"address":3297528,"base_stats":[75,100,110,65,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":28,"learnset":{"address":3308926,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":28},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":24,"move_id":163},{"level":33,"move_id":129},{"level":42,"move_id":154},{"level":52,"move_id":328},{"level":62,"move_id":201}]},"tmhm_learnset":"00A43ED0CE514621","types":[4,4]},{"abilities":[38,0],"address":3297556,"base_stats":[55,47,52,41,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":30}],"friendship":70,"id":29,"learnset":{"address":3308952,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":44},{"level":23,"move_id":270},{"level":30,"move_id":154},{"level":38,"move_id":260},{"level":47,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297584,"base_stats":[70,62,67,56,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":31}],"friendship":70,"id":30,"learnset":{"address":3308978,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":44},{"level":26,"move_id":270},{"level":34,"move_id":154},{"level":43,"move_id":260},{"level":53,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297612,"base_stats":[90,82,87,76,75,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":31,"learnset":{"address":3309004,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":34}]},"tmhm_learnset":"00B43FFEEFD37E35","types":[3,4]},{"abilities":[38,0],"address":3297640,"base_stats":[46,57,40,50,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":33}],"friendship":70,"id":32,"learnset":{"address":3309016,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":30},{"level":23,"move_id":270},{"level":30,"move_id":31},{"level":38,"move_id":260},{"level":47,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297668,"base_stats":[61,72,57,65,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":34}],"friendship":70,"id":33,"learnset":{"address":3309042,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":30},{"level":26,"move_id":270},{"level":34,"move_id":31},{"level":43,"move_id":260},{"level":53,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297696,"base_stats":[81,92,77,85,85,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":34,"learnset":{"address":3309068,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":116},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":37}]},"tmhm_learnset":"00B43F7EEFD37E35","types":[3,4]},{"abilities":[56,0],"address":3297724,"base_stats":[70,45,48,35,60,65],"catch_rate":150,"evolutions":[{"method":"ITEM","param":94,"species":36}],"friendship":140,"id":35,"learnset":{"address":3309080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":227},{"level":9,"move_id":47},{"level":13,"move_id":3},{"level":17,"move_id":266},{"level":21,"move_id":107},{"level":25,"move_id":111},{"level":29,"move_id":118},{"level":33,"move_id":322},{"level":37,"move_id":236},{"level":41,"move_id":113},{"level":45,"move_id":309}]},"tmhm_learnset":"00611E27FDFBB62D","types":[0,0]},{"abilities":[56,0],"address":3297752,"base_stats":[95,70,73,60,85,90],"catch_rate":25,"evolutions":[],"friendship":140,"id":36,"learnset":{"address":3309112,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":3},{"level":1,"move_id":107},{"level":1,"move_id":118}]},"tmhm_learnset":"00611E27FDFBF62D","types":[0,0]},{"abilities":[18,0],"address":3297780,"base_stats":[38,41,40,65,50,65],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":38}],"friendship":70,"id":37,"learnset":{"address":3309122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":5,"move_id":39},{"level":9,"move_id":46},{"level":13,"move_id":98},{"level":17,"move_id":261},{"level":21,"move_id":109},{"level":25,"move_id":286},{"level":29,"move_id":53},{"level":33,"move_id":219},{"level":37,"move_id":288},{"level":41,"move_id":83}]},"tmhm_learnset":"00021E248C590630","types":[10,10]},{"abilities":[18,0],"address":3297808,"base_stats":[73,76,75,100,81,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":38,"learnset":{"address":3309152,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":98},{"level":1,"move_id":109},{"level":1,"move_id":219},{"level":45,"move_id":83}]},"tmhm_learnset":"00021E248C594630","types":[10,10]},{"abilities":[56,0],"address":3297836,"base_stats":[115,45,20,20,45,25],"catch_rate":170,"evolutions":[{"method":"ITEM","param":94,"species":40}],"friendship":70,"id":39,"learnset":{"address":3309164,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":50},{"level":19,"move_id":205},{"level":24,"move_id":3},{"level":29,"move_id":156},{"level":34,"move_id":34},{"level":39,"move_id":102},{"level":44,"move_id":304},{"level":49,"move_id":38}]},"tmhm_learnset":"00611E27FDBBB625","types":[0,0]},{"abilities":[56,0],"address":3297864,"base_stats":[140,70,45,45,75,50],"catch_rate":50,"evolutions":[],"friendship":70,"id":40,"learnset":{"address":3309194,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":50},{"level":1,"move_id":111},{"level":1,"move_id":3}]},"tmhm_learnset":"00611E27FDBBF625","types":[0,0]},{"abilities":[39,0],"address":3297892,"base_stats":[40,45,35,55,30,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":42}],"friendship":70,"id":41,"learnset":{"address":3309204,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":141},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":26,"move_id":109},{"level":31,"move_id":314},{"level":36,"move_id":212},{"level":41,"move_id":305},{"level":46,"move_id":114}]},"tmhm_learnset":"00017F88A4170E20","types":[3,2]},{"abilities":[39,0],"address":3297920,"base_stats":[75,80,70,90,65,75],"catch_rate":90,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":169}],"friendship":70,"id":42,"learnset":{"address":3309232,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00017F88A4174E20","types":[3,2]},{"abilities":[34,0],"address":3297948,"base_stats":[45,50,55,30,75,65],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":44}],"friendship":70,"id":43,"learnset":{"address":3309260,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":23,"move_id":51},{"level":32,"move_id":236},{"level":39,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3297976,"base_stats":[60,65,70,40,85,75],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":45},{"method":"ITEM","param":93,"species":182}],"friendship":70,"id":44,"learnset":{"address":3309284,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":77},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":24,"move_id":51},{"level":35,"move_id":236},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298004,"base_stats":[75,80,85,50,100,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":45,"learnset":{"address":3309308,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":312},{"level":1,"move_id":78},{"level":1,"move_id":72},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884354720","types":[12,3]},{"abilities":[27,0],"address":3298032,"base_stats":[35,70,55,25,45,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":24,"species":47}],"friendship":70,"id":46,"learnset":{"address":3309320,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":25,"move_id":147},{"level":31,"move_id":163},{"level":37,"move_id":74},{"level":43,"move_id":202},{"level":49,"move_id":312}]},"tmhm_learnset":"00C43E888C350720","types":[6,12]},{"abilities":[27,0],"address":3298060,"base_stats":[60,95,80,30,60,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":47,"learnset":{"address":3309346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":78},{"level":1,"move_id":77},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":27,"move_id":147},{"level":35,"move_id":163},{"level":43,"move_id":74},{"level":51,"move_id":202},{"level":59,"move_id":312}]},"tmhm_learnset":"00C43E888C354720","types":[6,12]},{"abilities":[14,0],"address":3298088,"base_stats":[60,55,50,45,40,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":49}],"friendship":70,"id":48,"learnset":{"address":3309372,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":33,"move_id":60},{"level":36,"move_id":79},{"level":41,"move_id":94}]},"tmhm_learnset":"0040BE0894350620","types":[6,3]},{"abilities":[19,0],"address":3298116,"base_stats":[70,65,60,90,90,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":49,"learnset":{"address":3309398,"moves":[{"level":1,"move_id":318},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":1,"move_id":48},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":31,"move_id":16},{"level":36,"move_id":60},{"level":42,"move_id":79},{"level":52,"move_id":94}]},"tmhm_learnset":"0040BE8894354620","types":[6,3]},{"abilities":[8,71],"address":3298144,"base_stats":[10,55,25,95,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":26,"species":51}],"friendship":70,"id":50,"learnset":{"address":3309428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":33,"move_id":163},{"level":41,"move_id":89},{"level":49,"move_id":90}]},"tmhm_learnset":"00843EC88E110620","types":[4,4]},{"abilities":[8,71],"address":3298172,"base_stats":[35,80,50,120,50,70],"catch_rate":50,"evolutions":[],"friendship":70,"id":51,"learnset":{"address":3309452,"moves":[{"level":1,"move_id":161},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":1,"move_id":45},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":26,"move_id":328},{"level":38,"move_id":163},{"level":51,"move_id":89},{"level":64,"move_id":90}]},"tmhm_learnset":"00843EC88E114620","types":[4,4]},{"abilities":[53,0],"address":3298200,"base_stats":[40,45,35,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":28,"species":53}],"friendship":70,"id":52,"learnset":{"address":3309478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":28,"move_id":185},{"level":35,"move_id":103},{"level":41,"move_id":154},{"level":46,"move_id":163},{"level":50,"move_id":252}]},"tmhm_learnset":"00453F82ADD30E24","types":[0,0]},{"abilities":[7,0],"address":3298228,"base_stats":[65,70,60,115,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":53,"learnset":{"address":3309502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":44},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":29,"move_id":185},{"level":38,"move_id":103},{"level":46,"move_id":154},{"level":53,"move_id":163},{"level":59,"move_id":252}]},"tmhm_learnset":"00453F82ADD34E34","types":[0,0]},{"abilities":[6,13],"address":3298256,"base_stats":[50,52,48,55,65,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":33,"species":55}],"friendship":70,"id":54,"learnset":{"address":3309526,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":40,"move_id":154},{"level":50,"move_id":56}]},"tmhm_learnset":"03F01E80CC53326D","types":[11,11]},{"abilities":[6,13],"address":3298284,"base_stats":[80,82,78,85,95,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":55,"learnset":{"address":3309550,"moves":[{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":50},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":44,"move_id":154},{"level":58,"move_id":56}]},"tmhm_learnset":"03F01E80CC53726D","types":[11,11]},{"abilities":[72,0],"address":3298312,"base_stats":[40,80,35,70,35,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":57}],"friendship":70,"id":56,"learnset":{"address":3309574,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":33,"move_id":69},{"level":39,"move_id":238},{"level":45,"move_id":103},{"level":51,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD30EA1","types":[1,1]},{"abilities":[72,0],"address":3298340,"base_stats":[65,105,60,95,60,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":57,"learnset":{"address":3309600,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":67},{"level":1,"move_id":99},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":28,"move_id":99},{"level":36,"move_id":69},{"level":45,"move_id":238},{"level":54,"move_id":103},{"level":63,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD34EA1","types":[1,1]},{"abilities":[22,18],"address":3298368,"base_stats":[55,70,45,60,70,50],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":59}],"friendship":70,"id":58,"learnset":{"address":3309628,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":7,"move_id":52},{"level":13,"move_id":43},{"level":19,"move_id":316},{"level":25,"move_id":36},{"level":31,"move_id":172},{"level":37,"move_id":270},{"level":43,"move_id":97},{"level":49,"move_id":53}]},"tmhm_learnset":"00A23EA48C510630","types":[10,10]},{"abilities":[22,18],"address":3298396,"base_stats":[90,110,80,95,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":59,"learnset":{"address":3309654,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":1,"move_id":52},{"level":1,"move_id":316},{"level":49,"move_id":245}]},"tmhm_learnset":"00A23EA48C514630","types":[10,10]},{"abilities":[11,6],"address":3298424,"base_stats":[40,50,40,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":61}],"friendship":70,"id":60,"learnset":{"address":3309666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":25,"move_id":240},{"level":31,"move_id":34},{"level":37,"move_id":187},{"level":43,"move_id":56}]},"tmhm_learnset":"03103E009C133264","types":[11,11]},{"abilities":[11,6],"address":3298452,"base_stats":[65,65,65,90,50,50],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":62},{"method":"ITEM","param":187,"species":186}],"friendship":70,"id":61,"learnset":{"address":3309690,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":95},{"level":1,"move_id":55},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":27,"move_id":240},{"level":35,"move_id":34},{"level":43,"move_id":187},{"level":51,"move_id":56}]},"tmhm_learnset":"03B03E00DE133265","types":[11,11]},{"abilities":[11,6],"address":3298480,"base_stats":[90,85,95,70,70,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":62,"learnset":{"address":3309714,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":66},{"level":35,"move_id":66},{"level":51,"move_id":170}]},"tmhm_learnset":"03B03E40DE1372E5","types":[11,1]},{"abilities":[28,39],"address":3298508,"base_stats":[25,20,15,90,105,55],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":16,"species":64}],"friendship":70,"id":63,"learnset":{"address":3309728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":100}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298536,"base_stats":[40,35,30,105,120,70],"catch_rate":100,"evolutions":[{"method":"LEVEL","param":37,"species":65}],"friendship":70,"id":64,"learnset":{"address":3309738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":272},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298564,"base_stats":[55,50,45,120,135,85],"catch_rate":50,"evolutions":[],"friendship":70,"id":65,"learnset":{"address":3309766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":347},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45BCE29","types":[14,14]},{"abilities":[62,0],"address":3298592,"base_stats":[70,80,50,35,35,35],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":28,"species":67}],"friendship":70,"id":66,"learnset":{"address":3309794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":31,"move_id":233},{"level":37,"move_id":66},{"level":40,"move_id":238},{"level":43,"move_id":184},{"level":49,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298620,"base_stats":[80,100,70,45,50,60],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":68}],"friendship":70,"id":67,"learnset":{"address":3309824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298648,"base_stats":[90,130,80,55,65,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":68,"learnset":{"address":3309854,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1346A1","types":[1,1]},{"abilities":[34,0],"address":3298676,"base_stats":[50,75,35,40,70,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":70}],"friendship":70,"id":69,"learnset":{"address":3309884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":23,"move_id":51},{"level":30,"move_id":230},{"level":37,"move_id":75},{"level":45,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298704,"base_stats":[65,90,50,55,85,45],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":71}],"friendship":70,"id":70,"learnset":{"address":3309912,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":1,"move_id":74},{"level":1,"move_id":35},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":24,"move_id":51},{"level":33,"move_id":230},{"level":42,"move_id":75},{"level":54,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298732,"base_stats":[80,105,65,70,100,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":71,"learnset":{"address":3309940,"moves":[{"level":1,"move_id":22},{"level":1,"move_id":79},{"level":1,"move_id":230},{"level":1,"move_id":75}]},"tmhm_learnset":"00443E0884354720","types":[12,3]},{"abilities":[29,64],"address":3298760,"base_stats":[40,40,35,70,50,100],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":73}],"friendship":70,"id":72,"learnset":{"address":3309950,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":36,"move_id":112},{"level":43,"move_id":103},{"level":49,"move_id":56}]},"tmhm_learnset":"03143E0884173264","types":[11,3]},{"abilities":[29,64],"address":3298788,"base_stats":[80,70,65,100,80,120],"catch_rate":60,"evolutions":[],"friendship":70,"id":73,"learnset":{"address":3309976,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":48},{"level":1,"move_id":132},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":38,"move_id":112},{"level":47,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03143E0884177264","types":[11,3]},{"abilities":[69,5],"address":3298816,"base_stats":[40,80,100,20,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":75}],"friendship":70,"id":74,"learnset":{"address":3310002,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":26,"move_id":205},{"level":31,"move_id":350},{"level":36,"move_id":89},{"level":41,"move_id":153},{"level":46,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298844,"base_stats":[55,95,115,35,45,45],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":37,"species":76}],"friendship":70,"id":75,"learnset":{"address":3310030,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298872,"base_stats":[80,110,130,45,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":76,"learnset":{"address":3310058,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE114631","types":[5,4]},{"abilities":[50,18],"address":3298900,"base_stats":[50,85,55,90,65,65],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":40,"species":78}],"friendship":70,"id":77,"learnset":{"address":3310086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":45,"move_id":340},{"level":53,"move_id":126}]},"tmhm_learnset":"00221E2484710620","types":[10,10]},{"abilities":[50,18],"address":3298928,"base_stats":[65,100,70,105,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":78,"learnset":{"address":3310114,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":52},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":40,"move_id":31},{"level":50,"move_id":340},{"level":63,"move_id":126}]},"tmhm_learnset":"00221E2484714620","types":[10,10]},{"abilities":[12,20],"address":3298956,"base_stats":[90,65,65,15,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":80},{"method":"ITEM","param":187,"species":199}],"friendship":70,"id":79,"learnset":{"address":3310144,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":133},{"level":48,"move_id":94}]},"tmhm_learnset":"02709E24BE5B366C","types":[11,14]},{"abilities":[12,20],"address":3298984,"base_stats":[95,75,110,30,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":80,"learnset":{"address":3310168,"moves":[{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":37,"move_id":110},{"level":46,"move_id":133},{"level":54,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[42,5],"address":3299012,"base_stats":[25,35,70,45,95,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":82}],"friendship":70,"id":81,"learnset":{"address":3310194,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":32,"move_id":199},{"level":38,"move_id":129},{"level":44,"move_id":103},{"level":50,"move_id":192}]},"tmhm_learnset":"00400E0385930620","types":[13,8]},{"abilities":[42,5],"address":3299040,"base_stats":[50,60,95,70,120,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":82,"learnset":{"address":3310222,"moves":[{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":1,"move_id":84},{"level":1,"move_id":48},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":35,"move_id":199},{"level":44,"move_id":161},{"level":53,"move_id":103},{"level":62,"move_id":192}]},"tmhm_learnset":"00400E0385934620","types":[13,8]},{"abilities":[51,39],"address":3299068,"base_stats":[52,65,55,60,58,62],"catch_rate":45,"evolutions":[],"friendship":70,"id":83,"learnset":{"address":3310250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":6,"move_id":28},{"level":11,"move_id":43},{"level":16,"move_id":31},{"level":21,"move_id":282},{"level":26,"move_id":210},{"level":31,"move_id":14},{"level":36,"move_id":97},{"level":41,"move_id":163},{"level":46,"move_id":206}]},"tmhm_learnset":"000C7E8084510620","types":[0,2]},{"abilities":[50,48],"address":3299096,"base_stats":[35,85,45,75,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":85}],"friendship":70,"id":84,"learnset":{"address":3310278,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":33,"move_id":253},{"level":37,"move_id":65},{"level":45,"move_id":97}]},"tmhm_learnset":"00087E8084110620","types":[0,2]},{"abilities":[50,48],"address":3299124,"base_stats":[60,110,70,100,60,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":85,"learnset":{"address":3310302,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":228},{"level":1,"move_id":31},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":38,"move_id":253},{"level":47,"move_id":65},{"level":60,"move_id":97}]},"tmhm_learnset":"00087F8084114E20","types":[0,2]},{"abilities":[47,0],"address":3299152,"base_stats":[65,45,55,45,45,70],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":34,"species":87}],"friendship":70,"id":86,"learnset":{"address":3310326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":29},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":37,"move_id":36},{"level":41,"move_id":58},{"level":49,"move_id":219}]},"tmhm_learnset":"03103E00841B3264","types":[11,11]},{"abilities":[47,0],"address":3299180,"base_stats":[90,70,80,70,70,95],"catch_rate":75,"evolutions":[],"friendship":70,"id":87,"learnset":{"address":3310350,"moves":[{"level":1,"move_id":29},{"level":1,"move_id":45},{"level":1,"move_id":196},{"level":1,"move_id":62},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":34,"move_id":329},{"level":42,"move_id":36},{"level":51,"move_id":58},{"level":64,"move_id":219}]},"tmhm_learnset":"03103E00841B7264","types":[11,15]},{"abilities":[1,60],"address":3299208,"base_stats":[80,80,50,25,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":89}],"friendship":70,"id":88,"learnset":{"address":3310376,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":43,"move_id":188},{"level":53,"move_id":262}]},"tmhm_learnset":"00003F6E8D970E20","types":[3,3]},{"abilities":[1,60],"address":3299236,"base_stats":[105,105,75,50,65,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":89,"learnset":{"address":3310402,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":47,"move_id":188},{"level":61,"move_id":262}]},"tmhm_learnset":"00A03F6ECD974E21","types":[3,3]},{"abilities":[75,0],"address":3299264,"base_stats":[30,65,100,40,45,25],"catch_rate":190,"evolutions":[{"method":"ITEM","param":97,"species":91}],"friendship":70,"id":90,"learnset":{"address":3310428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":110},{"level":9,"move_id":48},{"level":17,"move_id":62},{"level":25,"move_id":182},{"level":33,"move_id":43},{"level":41,"move_id":128},{"level":49,"move_id":58}]},"tmhm_learnset":"02101E0084133264","types":[11,11]},{"abilities":[75,0],"address":3299292,"base_stats":[50,95,180,70,85,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":91,"learnset":{"address":3310450,"moves":[{"level":1,"move_id":110},{"level":1,"move_id":48},{"level":1,"move_id":62},{"level":1,"move_id":182},{"level":33,"move_id":191},{"level":41,"move_id":131}]},"tmhm_learnset":"02101F0084137264","types":[11,15]},{"abilities":[26,0],"address":3299320,"base_stats":[30,35,30,80,100,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":93}],"friendship":70,"id":92,"learnset":{"address":3310464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":28,"move_id":109},{"level":33,"move_id":138},{"level":36,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299348,"base_stats":[45,50,45,95,115,55],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":94}],"friendship":70,"id":93,"learnset":{"address":3310488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299376,"base_stats":[60,65,60,110,130,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":94,"learnset":{"address":3310514,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"00A1BF08F5974E21","types":[7,3]},{"abilities":[69,5],"address":3299404,"base_stats":[35,45,160,70,30,45],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":208}],"friendship":70,"id":95,"learnset":{"address":3310540,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":328},{"level":57,"move_id":38}]},"tmhm_learnset":"00A01F508E510E30","types":[5,4]},{"abilities":[15,0],"address":3299432,"base_stats":[60,48,45,42,43,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":26,"species":97}],"friendship":70,"id":96,"learnset":{"address":3310568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":31,"move_id":139},{"level":36,"move_id":96},{"level":40,"move_id":94},{"level":43,"move_id":244},{"level":45,"move_id":248}]},"tmhm_learnset":"0041BF01F41B8E29","types":[14,14]},{"abilities":[15,0],"address":3299460,"base_stats":[85,73,70,67,73,115],"catch_rate":75,"evolutions":[],"friendship":70,"id":97,"learnset":{"address":3310594,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":1,"move_id":50},{"level":1,"move_id":93},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":33,"move_id":139},{"level":40,"move_id":96},{"level":49,"move_id":94},{"level":55,"move_id":244},{"level":60,"move_id":248}]},"tmhm_learnset":"0041BF01F41BCE29","types":[14,14]},{"abilities":[52,75],"address":3299488,"base_stats":[30,105,90,50,25,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":28,"species":99}],"friendship":70,"id":98,"learnset":{"address":3310620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":34,"move_id":12},{"level":41,"move_id":182},{"level":45,"move_id":152}]},"tmhm_learnset":"02B43E408C133264","types":[11,11]},{"abilities":[52,75],"address":3299516,"base_stats":[55,130,115,75,50,50],"catch_rate":60,"evolutions":[],"friendship":70,"id":99,"learnset":{"address":3310646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":43},{"level":1,"move_id":11},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":38,"move_id":12},{"level":49,"move_id":182},{"level":57,"move_id":152}]},"tmhm_learnset":"02B43E408C137264","types":[11,11]},{"abilities":[43,9],"address":3299544,"base_stats":[40,30,50,100,55,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":101}],"friendship":70,"id":100,"learnset":{"address":3310672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":32,"move_id":205},{"level":37,"move_id":113},{"level":42,"move_id":129},{"level":46,"move_id":153},{"level":49,"move_id":243}]},"tmhm_learnset":"00402F0285938A20","types":[13,13]},{"abilities":[43,9],"address":3299572,"base_stats":[60,50,70,140,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":101,"learnset":{"address":3310700,"moves":[{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":1,"move_id":49},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":34,"move_id":205},{"level":41,"move_id":113},{"level":48,"move_id":129},{"level":54,"move_id":153},{"level":59,"move_id":243}]},"tmhm_learnset":"00402F028593CA20","types":[13,13]},{"abilities":[34,0],"address":3299600,"base_stats":[60,40,80,40,60,45],"catch_rate":90,"evolutions":[{"method":"ITEM","param":98,"species":103}],"friendship":70,"id":102,"learnset":{"address":3310728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":253},{"level":1,"move_id":95},{"level":7,"move_id":115},{"level":13,"move_id":73},{"level":19,"move_id":93},{"level":25,"move_id":78},{"level":31,"move_id":77},{"level":37,"move_id":79},{"level":43,"move_id":76}]},"tmhm_learnset":"0060BE0994358720","types":[12,14]},{"abilities":[34,0],"address":3299628,"base_stats":[95,95,85,55,125,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":103,"learnset":{"address":3310752,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":95},{"level":1,"move_id":93},{"level":19,"move_id":23},{"level":31,"move_id":121}]},"tmhm_learnset":"0060BE099435C720","types":[12,14]},{"abilities":[69,31],"address":3299656,"base_stats":[50,50,95,35,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":105}],"friendship":70,"id":104,"learnset":{"address":3310766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":125},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":29,"move_id":99},{"level":33,"move_id":206},{"level":37,"move_id":37},{"level":41,"move_id":198},{"level":45,"move_id":38}]},"tmhm_learnset":"00A03EF4CE513621","types":[4,4]},{"abilities":[69,31],"address":3299684,"base_stats":[60,80,110,45,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":105,"learnset":{"address":3310798,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":125},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":32,"move_id":99},{"level":39,"move_id":206},{"level":46,"move_id":37},{"level":53,"move_id":198},{"level":61,"move_id":38}]},"tmhm_learnset":"00A03EF4CE517621","types":[4,4]},{"abilities":[7,0],"address":3299712,"base_stats":[50,120,53,87,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":106,"learnset":{"address":3310830,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":24},{"level":6,"move_id":96},{"level":11,"move_id":27},{"level":16,"move_id":26},{"level":20,"move_id":280},{"level":21,"move_id":116},{"level":26,"move_id":136},{"level":31,"move_id":170},{"level":36,"move_id":193},{"level":41,"move_id":203},{"level":46,"move_id":25},{"level":51,"move_id":179}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[51,0],"address":3299740,"base_stats":[50,105,79,76,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":107,"learnset":{"address":3310862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":4},{"level":7,"move_id":97},{"level":13,"move_id":228},{"level":20,"move_id":183},{"level":26,"move_id":9},{"level":26,"move_id":8},{"level":26,"move_id":7},{"level":32,"move_id":327},{"level":38,"move_id":5},{"level":44,"move_id":197},{"level":50,"move_id":68}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[20,12],"address":3299768,"base_stats":[90,55,75,30,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":108,"learnset":{"address":3310892,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":122},{"level":7,"move_id":48},{"level":12,"move_id":111},{"level":18,"move_id":282},{"level":23,"move_id":23},{"level":29,"move_id":35},{"level":34,"move_id":50},{"level":40,"move_id":21},{"level":45,"move_id":103},{"level":51,"move_id":287}]},"tmhm_learnset":"00B43E76EFF37625","types":[0,0]},{"abilities":[26,0],"address":3299796,"base_stats":[40,65,95,35,60,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":35,"species":110}],"friendship":70,"id":109,"learnset":{"address":3310920,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":41,"move_id":153},{"level":45,"move_id":194},{"level":49,"move_id":262}]},"tmhm_learnset":"00403F2EA5930E20","types":[3,3]},{"abilities":[26,0],"address":3299824,"base_stats":[65,90,120,60,85,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":110,"learnset":{"address":3310946,"moves":[{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":1,"move_id":123},{"level":1,"move_id":120},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":44,"move_id":153},{"level":51,"move_id":194},{"level":58,"move_id":262}]},"tmhm_learnset":"00403F2EA5934E20","types":[3,3]},{"abilities":[31,69],"address":3299852,"base_stats":[80,85,95,25,30,30],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":42,"species":112}],"friendship":70,"id":111,"learnset":{"address":3310972,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":43,"move_id":36},{"level":52,"move_id":89},{"level":57,"move_id":224}]},"tmhm_learnset":"00A03E768FD33630","types":[4,5]},{"abilities":[31,69],"address":3299880,"base_stats":[105,130,120,40,45,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":112,"learnset":{"address":3310998,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":1,"move_id":23},{"level":1,"move_id":31},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":46,"move_id":36},{"level":58,"move_id":89},{"level":66,"move_id":224}]},"tmhm_learnset":"00B43E76CFD37631","types":[4,5]},{"abilities":[30,32],"address":3299908,"base_stats":[250,5,5,50,35,105],"catch_rate":30,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":242}],"friendship":140,"id":113,"learnset":{"address":3311024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":287},{"level":13,"move_id":135},{"level":17,"move_id":3},{"level":23,"move_id":107},{"level":29,"move_id":47},{"level":35,"move_id":121},{"level":41,"move_id":111},{"level":49,"move_id":113},{"level":57,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[34,0],"address":3299936,"base_stats":[65,55,115,60,100,40],"catch_rate":45,"evolutions":[],"friendship":70,"id":114,"learnset":{"address":3311054,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":275},{"level":1,"move_id":132},{"level":4,"move_id":79},{"level":10,"move_id":71},{"level":13,"move_id":74},{"level":19,"move_id":77},{"level":22,"move_id":22},{"level":28,"move_id":20},{"level":31,"move_id":72},{"level":37,"move_id":78},{"level":40,"move_id":21},{"level":46,"move_id":321}]},"tmhm_learnset":"00C43E0884354720","types":[12,12]},{"abilities":[48,0],"address":3299964,"base_stats":[105,95,80,90,40,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":115,"learnset":{"address":3311084,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":4},{"level":1,"move_id":43},{"level":7,"move_id":44},{"level":13,"move_id":39},{"level":19,"move_id":252},{"level":25,"move_id":5},{"level":31,"move_id":99},{"level":37,"move_id":203},{"level":43,"move_id":146},{"level":49,"move_id":179}]},"tmhm_learnset":"00B43EF6EFF37675","types":[0,0]},{"abilities":[33,0],"address":3299992,"base_stats":[30,40,70,60,70,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":32,"species":117}],"friendship":70,"id":116,"learnset":{"address":3311110,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":36,"move_id":97},{"level":43,"move_id":56},{"level":50,"move_id":349}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[38,0],"address":3300020,"base_stats":[55,65,95,85,95,45],"catch_rate":75,"evolutions":[{"method":"ITEM","param":201,"species":230}],"friendship":70,"id":117,"learnset":{"address":3311134,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[33,41],"address":3300048,"base_stats":[45,67,60,63,35,50],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":119}],"friendship":70,"id":118,"learnset":{"address":3311158,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":38,"move_id":127},{"level":43,"move_id":32},{"level":52,"move_id":97}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,41],"address":3300076,"base_stats":[80,92,65,68,65,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":119,"learnset":{"address":3311182,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":1,"move_id":48},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":41,"move_id":127},{"level":49,"move_id":32},{"level":61,"move_id":97}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[35,30],"address":3300104,"base_stats":[30,45,55,85,70,55],"catch_rate":225,"evolutions":[{"method":"ITEM","param":97,"species":121}],"friendship":70,"id":120,"learnset":{"address":3311206,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":6,"move_id":55},{"level":10,"move_id":229},{"level":15,"move_id":105},{"level":19,"move_id":293},{"level":24,"move_id":129},{"level":28,"move_id":61},{"level":33,"move_id":107},{"level":37,"move_id":113},{"level":42,"move_id":322},{"level":46,"move_id":56}]},"tmhm_learnset":"03500E019593B264","types":[11,11]},{"abilities":[35,30],"address":3300132,"base_stats":[60,75,85,115,100,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":121,"learnset":{"address":3311236,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":229},{"level":1,"move_id":105},{"level":1,"move_id":129},{"level":33,"move_id":109}]},"tmhm_learnset":"03508E019593F264","types":[11,14]},{"abilities":[43,0],"address":3300160,"base_stats":[40,45,65,90,100,120],"catch_rate":45,"evolutions":[],"friendship":70,"id":122,"learnset":{"address":3311248,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":112},{"level":5,"move_id":93},{"level":9,"move_id":164},{"level":13,"move_id":96},{"level":17,"move_id":3},{"level":21,"move_id":113},{"level":21,"move_id":115},{"level":25,"move_id":227},{"level":29,"move_id":60},{"level":33,"move_id":278},{"level":37,"move_id":271},{"level":41,"move_id":272},{"level":45,"move_id":94},{"level":49,"move_id":226},{"level":53,"move_id":219}]},"tmhm_learnset":"0041BF03F5BBCE29","types":[14,14]},{"abilities":[68,0],"address":3300188,"base_stats":[70,110,80,105,55,80],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":212}],"friendship":70,"id":123,"learnset":{"address":3311286,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":17},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00847E8084134620","types":[6,2]},{"abilities":[12,0],"address":3300216,"base_stats":[65,50,35,95,115,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":124,"learnset":{"address":3311314,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":1,"move_id":142},{"level":1,"move_id":181},{"level":9,"move_id":142},{"level":13,"move_id":181},{"level":21,"move_id":3},{"level":25,"move_id":8},{"level":35,"move_id":212},{"level":41,"move_id":313},{"level":51,"move_id":34},{"level":57,"move_id":195},{"level":67,"move_id":59}]},"tmhm_learnset":"0040BF01F413FA6D","types":[15,14]},{"abilities":[9,0],"address":3300244,"base_stats":[65,83,57,105,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":125,"learnset":{"address":3311342,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":1,"move_id":9},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":36,"move_id":103},{"level":47,"move_id":85},{"level":58,"move_id":87}]},"tmhm_learnset":"00E03E02D5D3C221","types":[13,13]},{"abilities":[49,0],"address":3300272,"base_stats":[65,95,57,93,100,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":126,"learnset":{"address":3311364,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":43},{"level":1,"move_id":123},{"level":1,"move_id":7},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":33,"move_id":241},{"level":41,"move_id":53},{"level":49,"move_id":109},{"level":57,"move_id":126}]},"tmhm_learnset":"00A03E24D4514621","types":[10,10]},{"abilities":[52,0],"address":3300300,"base_stats":[65,125,100,85,55,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":127,"learnset":{"address":3311390,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":11},{"level":1,"move_id":116},{"level":7,"move_id":20},{"level":13,"move_id":69},{"level":19,"move_id":106},{"level":25,"move_id":279},{"level":31,"move_id":280},{"level":37,"move_id":12},{"level":43,"move_id":66},{"level":49,"move_id":14}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,6]},{"abilities":[22,0],"address":3300328,"base_stats":[75,100,95,110,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":128,"learnset":{"address":3311416,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":8,"move_id":99},{"level":13,"move_id":30},{"level":19,"move_id":184},{"level":26,"move_id":228},{"level":34,"move_id":156},{"level":43,"move_id":37},{"level":53,"move_id":36}]},"tmhm_learnset":"00B01E7687F37624","types":[0,0]},{"abilities":[33,0],"address":3300356,"base_stats":[20,10,55,80,15,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":130}],"friendship":70,"id":129,"learnset":{"address":3311442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"0000000000000000","types":[11,11]},{"abilities":[22,0],"address":3300384,"base_stats":[95,125,79,81,60,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":130,"learnset":{"address":3311456,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":37},{"level":20,"move_id":44},{"level":25,"move_id":82},{"level":30,"move_id":43},{"level":35,"move_id":239},{"level":40,"move_id":56},{"level":45,"move_id":240},{"level":50,"move_id":349},{"level":55,"move_id":63}]},"tmhm_learnset":"03B01F3487937A74","types":[11,2]},{"abilities":[11,75],"address":3300412,"base_stats":[130,85,80,60,85,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":131,"learnset":{"address":3311482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":45},{"level":1,"move_id":47},{"level":7,"move_id":54},{"level":13,"move_id":34},{"level":19,"move_id":109},{"level":25,"move_id":195},{"level":31,"move_id":58},{"level":37,"move_id":240},{"level":43,"move_id":219},{"level":49,"move_id":56},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E0295DB7274","types":[11,15]},{"abilities":[7,0],"address":3300440,"base_stats":[48,48,48,48,48,48],"catch_rate":35,"evolutions":[],"friendship":70,"id":132,"learnset":{"address":3311510,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":144}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[50,0],"address":3300468,"base_stats":[55,55,50,55,45,65],"catch_rate":45,"evolutions":[{"method":"ITEM","param":96,"species":135},{"method":"ITEM","param":97,"species":134},{"method":"ITEM","param":95,"species":136},{"method":"FRIENDSHIP_DAY","param":0,"species":196},{"method":"FRIENDSHIP_NIGHT","param":0,"species":197}],"friendship":70,"id":133,"learnset":{"address":3311520,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":45},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":226},{"level":42,"move_id":36}]},"tmhm_learnset":"00001E00AC530620","types":[0,0]},{"abilities":[11,0],"address":3300496,"base_stats":[130,65,60,65,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":134,"learnset":{"address":3311542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":55},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":62},{"level":42,"move_id":114},{"level":47,"move_id":151},{"level":52,"move_id":56}]},"tmhm_learnset":"03101E00AC537674","types":[11,11]},{"abilities":[10,0],"address":3300524,"base_stats":[65,65,60,130,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":135,"learnset":{"address":3311568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":84},{"level":23,"move_id":98},{"level":30,"move_id":24},{"level":36,"move_id":42},{"level":42,"move_id":86},{"level":47,"move_id":97},{"level":52,"move_id":87}]},"tmhm_learnset":"00401E02ADD34630","types":[13,13]},{"abilities":[18,0],"address":3300552,"base_stats":[65,130,60,65,95,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":136,"learnset":{"address":3311594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":52},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":83},{"level":42,"move_id":123},{"level":47,"move_id":43},{"level":52,"move_id":53}]},"tmhm_learnset":"00021E24AC534630","types":[10,10]},{"abilities":[36,0],"address":3300580,"base_stats":[65,60,70,40,85,75],"catch_rate":45,"evolutions":[{"method":"ITEM","param":218,"species":233}],"friendship":70,"id":137,"learnset":{"address":3311620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":159},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[33,75],"address":3300608,"base_stats":[35,40,100,35,90,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":139}],"friendship":70,"id":138,"learnset":{"address":3311646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":43,"move_id":321},{"level":49,"move_id":246},{"level":55,"move_id":56}]},"tmhm_learnset":"03903E5084133264","types":[5,11]},{"abilities":[33,75],"address":3300636,"base_stats":[70,60,125,55,115,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":139,"learnset":{"address":3311672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":1,"move_id":44},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":40,"move_id":131},{"level":46,"move_id":321},{"level":55,"move_id":246},{"level":65,"move_id":56}]},"tmhm_learnset":"03903E5084137264","types":[5,11]},{"abilities":[33,4],"address":3300664,"base_stats":[30,80,90,55,55,45],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":141}],"friendship":70,"id":140,"learnset":{"address":3311700,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":43,"move_id":319},{"level":49,"move_id":72},{"level":55,"move_id":246}]},"tmhm_learnset":"01903ED08C173264","types":[5,11]},{"abilities":[33,4],"address":3300692,"base_stats":[60,115,105,80,65,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":141,"learnset":{"address":3311726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":71},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":40,"move_id":163},{"level":46,"move_id":319},{"level":55,"move_id":72},{"level":65,"move_id":246}]},"tmhm_learnset":"03943ED0CC177264","types":[5,11]},{"abilities":[69,46],"address":3300720,"base_stats":[80,105,65,130,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":142,"learnset":{"address":3311754,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":8,"move_id":97},{"level":15,"move_id":44},{"level":22,"move_id":48},{"level":29,"move_id":246},{"level":36,"move_id":184},{"level":43,"move_id":36},{"level":50,"move_id":63}]},"tmhm_learnset":"00A87FF486534E32","types":[5,2]},{"abilities":[17,47],"address":3300748,"base_stats":[160,110,65,30,65,110],"catch_rate":25,"evolutions":[],"friendship":70,"id":143,"learnset":{"address":3311778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":133},{"level":10,"move_id":111},{"level":15,"move_id":187},{"level":19,"move_id":29},{"level":24,"move_id":281},{"level":28,"move_id":156},{"level":28,"move_id":173},{"level":33,"move_id":34},{"level":37,"move_id":335},{"level":42,"move_id":343},{"level":46,"move_id":205},{"level":51,"move_id":63}]},"tmhm_learnset":"00301E76F7B37625","types":[0,0]},{"abilities":[46,0],"address":3300776,"base_stats":[90,85,100,85,95,125],"catch_rate":3,"evolutions":[],"friendship":35,"id":144,"learnset":{"address":3311812,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":181},{"level":13,"move_id":54},{"level":25,"move_id":97},{"level":37,"move_id":170},{"level":49,"move_id":58},{"level":61,"move_id":115},{"level":73,"move_id":59},{"level":85,"move_id":329}]},"tmhm_learnset":"00884E9184137674","types":[15,2]},{"abilities":[46,0],"address":3300804,"base_stats":[90,90,85,100,125,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":145,"learnset":{"address":3311836,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":84},{"level":13,"move_id":86},{"level":25,"move_id":97},{"level":37,"move_id":197},{"level":49,"move_id":65},{"level":61,"move_id":268},{"level":73,"move_id":113},{"level":85,"move_id":87}]},"tmhm_learnset":"00C84E928593C630","types":[13,2]},{"abilities":[46,0],"address":3300832,"base_stats":[90,100,90,90,125,85],"catch_rate":3,"evolutions":[],"friendship":35,"id":146,"learnset":{"address":3311860,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":1,"move_id":52},{"level":13,"move_id":83},{"level":25,"move_id":97},{"level":37,"move_id":203},{"level":49,"move_id":53},{"level":61,"move_id":219},{"level":73,"move_id":257},{"level":85,"move_id":143}]},"tmhm_learnset":"008A4EB4841B4630","types":[10,2]},{"abilities":[61,0],"address":3300860,"base_stats":[41,64,45,50,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":148}],"friendship":35,"id":147,"learnset":{"address":3311884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":36,"move_id":97},{"level":43,"move_id":219},{"level":50,"move_id":200},{"level":57,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[61,0],"address":3300888,"base_stats":[61,84,65,70,70,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":149}],"friendship":35,"id":148,"learnset":{"address":3311910,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":56,"move_id":200},{"level":65,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[39,0],"address":3300916,"base_stats":[91,134,95,80,100,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":149,"learnset":{"address":3311936,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":55,"move_id":17},{"level":61,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BC5EF6C7DB7677","types":[16,2]},{"abilities":[46,0],"address":3300944,"base_stats":[106,110,90,130,154,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":150,"learnset":{"address":3311964,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":50},{"level":11,"move_id":112},{"level":22,"move_id":129},{"level":33,"move_id":244},{"level":44,"move_id":248},{"level":55,"move_id":54},{"level":66,"move_id":94},{"level":77,"move_id":133},{"level":88,"move_id":105},{"level":99,"move_id":219}]},"tmhm_learnset":"00E18FF7F7FBFEED","types":[14,14]},{"abilities":[28,0],"address":3300972,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":151,"learnset":{"address":3311992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":10,"move_id":144},{"level":20,"move_id":5},{"level":30,"move_id":118},{"level":40,"move_id":94},{"level":50,"move_id":246}]},"tmhm_learnset":"03FFFFFFFFFFFFFF","types":[14,14]},{"abilities":[65,0],"address":3301000,"base_stats":[45,49,65,45,49,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":153}],"friendship":70,"id":152,"learnset":{"address":3312012,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":22,"move_id":235},{"level":29,"move_id":34},{"level":36,"move_id":113},{"level":43,"move_id":219},{"level":50,"move_id":76}]},"tmhm_learnset":"00441E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301028,"base_stats":[60,62,80,60,63,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":154}],"friendship":70,"id":153,"learnset":{"address":3312038,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":39,"move_id":113},{"level":47,"move_id":219},{"level":55,"move_id":76}]},"tmhm_learnset":"00E41E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301056,"base_stats":[80,82,100,80,83,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":154,"learnset":{"address":3312064,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":41,"move_id":113},{"level":51,"move_id":219},{"level":61,"move_id":76}]},"tmhm_learnset":"00E41E01867DC720","types":[12,12]},{"abilities":[66,0],"address":3301084,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":14,"species":156}],"friendship":70,"id":155,"learnset":{"address":3312090,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":19,"move_id":98},{"level":27,"move_id":172},{"level":36,"move_id":129},{"level":46,"move_id":53}]},"tmhm_learnset":"00061EA48C110620","types":[10,10]},{"abilities":[66,0],"address":3301112,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":157}],"friendship":70,"id":156,"learnset":{"address":3312112,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":42,"move_id":129},{"level":54,"move_id":53}]},"tmhm_learnset":"00A61EA4CC110631","types":[10,10]},{"abilities":[66,0],"address":3301140,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":157,"learnset":{"address":3312134,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":1,"move_id":52},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":45,"move_id":129},{"level":60,"move_id":53}]},"tmhm_learnset":"00A61EA4CE114631","types":[10,10]},{"abilities":[67,0],"address":3301168,"base_stats":[50,65,64,43,44,48],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":18,"species":159}],"friendship":70,"id":158,"learnset":{"address":3312156,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":20,"move_id":44},{"level":27,"move_id":184},{"level":35,"move_id":163},{"level":43,"move_id":103},{"level":52,"move_id":56}]},"tmhm_learnset":"03141E80CC533265","types":[11,11]},{"abilities":[67,0],"address":3301196,"base_stats":[65,80,80,58,59,63],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":160}],"friendship":70,"id":159,"learnset":{"address":3312180,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":37,"move_id":163},{"level":45,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03B41E80CC533275","types":[11,11]},{"abilities":[67,0],"address":3301224,"base_stats":[85,105,100,78,79,83],"catch_rate":45,"evolutions":[],"friendship":70,"id":160,"learnset":{"address":3312204,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":1,"move_id":55},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":38,"move_id":163},{"level":47,"move_id":103},{"level":58,"move_id":56}]},"tmhm_learnset":"03B41E80CE537277","types":[11,11]},{"abilities":[50,51],"address":3301252,"base_stats":[35,46,34,20,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":15,"species":162}],"friendship":70,"id":161,"learnset":{"address":3312228,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":17,"move_id":270},{"level":24,"move_id":21},{"level":31,"move_id":266},{"level":40,"move_id":156},{"level":49,"move_id":133}]},"tmhm_learnset":"00143E06ECF31625","types":[0,0]},{"abilities":[50,51],"address":3301280,"base_stats":[85,76,64,90,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":162,"learnset":{"address":3312254,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":98},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":19,"move_id":270},{"level":28,"move_id":21},{"level":37,"move_id":266},{"level":48,"move_id":156},{"level":59,"move_id":133}]},"tmhm_learnset":"00B43E06EDF37625","types":[0,0]},{"abilities":[15,51],"address":3301308,"base_stats":[60,30,30,50,36,56],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":164}],"friendship":70,"id":163,"learnset":{"address":3312280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":22,"move_id":115},{"level":28,"move_id":36},{"level":34,"move_id":93},{"level":48,"move_id":138}]},"tmhm_learnset":"00487E81B4130620","types":[0,2]},{"abilities":[15,51],"address":3301336,"base_stats":[100,50,50,70,76,96],"catch_rate":90,"evolutions":[],"friendship":70,"id":164,"learnset":{"address":3312304,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":193},{"level":1,"move_id":64},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":25,"move_id":115},{"level":33,"move_id":36},{"level":41,"move_id":93},{"level":57,"move_id":138}]},"tmhm_learnset":"00487E81B4134620","types":[0,2]},{"abilities":[68,48],"address":3301364,"base_stats":[40,20,30,55,40,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":166}],"friendship":70,"id":165,"learnset":{"address":3312328,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":22,"move_id":113},{"level":22,"move_id":115},{"level":22,"move_id":219},{"level":29,"move_id":226},{"level":36,"move_id":129},{"level":43,"move_id":97},{"level":50,"move_id":38}]},"tmhm_learnset":"00403E81CC3D8621","types":[6,2]},{"abilities":[68,48],"address":3301392,"base_stats":[55,35,50,85,55,110],"catch_rate":90,"evolutions":[],"friendship":70,"id":166,"learnset":{"address":3312356,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":48},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":24,"move_id":113},{"level":24,"move_id":115},{"level":24,"move_id":219},{"level":33,"move_id":226},{"level":42,"move_id":129},{"level":51,"move_id":97},{"level":60,"move_id":38}]},"tmhm_learnset":"00403E81CC3DC621","types":[6,2]},{"abilities":[68,15],"address":3301420,"base_stats":[40,60,40,30,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":168}],"friendship":70,"id":167,"learnset":{"address":3312384,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":23,"move_id":141},{"level":30,"move_id":154},{"level":37,"move_id":169},{"level":45,"move_id":97},{"level":53,"move_id":94}]},"tmhm_learnset":"00403E089C350620","types":[6,3]},{"abilities":[68,15],"address":3301448,"base_stats":[70,90,70,40,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":168,"learnset":{"address":3312410,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":1,"move_id":184},{"level":1,"move_id":132},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":25,"move_id":141},{"level":34,"move_id":154},{"level":43,"move_id":169},{"level":53,"move_id":97},{"level":63,"move_id":94}]},"tmhm_learnset":"00403E089C354620","types":[6,3]},{"abilities":[39,0],"address":3301476,"base_stats":[85,90,80,130,70,80],"catch_rate":90,"evolutions":[],"friendship":70,"id":169,"learnset":{"address":3312436,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00097F88A4174E20","types":[3,2]},{"abilities":[10,35],"address":3301504,"base_stats":[75,38,38,67,56,56],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":27,"species":171}],"friendship":70,"id":170,"learnset":{"address":3312464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":29,"move_id":109},{"level":37,"move_id":36},{"level":41,"move_id":56},{"level":49,"move_id":268}]},"tmhm_learnset":"03501E0285933264","types":[11,13]},{"abilities":[10,35],"address":3301532,"base_stats":[125,58,58,67,76,76],"catch_rate":75,"evolutions":[],"friendship":70,"id":171,"learnset":{"address":3312490,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":1,"move_id":48},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":32,"move_id":109},{"level":43,"move_id":36},{"level":50,"move_id":56},{"level":61,"move_id":268}]},"tmhm_learnset":"03501E0285937264","types":[11,13]},{"abilities":[9,0],"address":3301560,"base_stats":[20,40,15,60,35,35],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":25}],"friendship":70,"id":172,"learnset":{"address":3312516,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":204},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":186}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[56,0],"address":3301588,"base_stats":[50,25,28,15,45,55],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":35}],"friendship":140,"id":173,"learnset":{"address":3312532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":204},{"level":4,"move_id":227},{"level":8,"move_id":47},{"level":13,"move_id":186}]},"tmhm_learnset":"00401E27BC7B8624","types":[0,0]},{"abilities":[56,0],"address":3301616,"base_stats":[90,30,15,15,40,20],"catch_rate":170,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":39}],"friendship":70,"id":174,"learnset":{"address":3312548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":1,"move_id":204},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":186}]},"tmhm_learnset":"00401E27BC3B8624","types":[0,0]},{"abilities":[55,32],"address":3301644,"base_stats":[35,20,65,20,40,65],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":176}],"friendship":70,"id":175,"learnset":{"address":3312564,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C01E27B43B8624","types":[0,0]},{"abilities":[55,32],"address":3301672,"base_stats":[55,40,85,40,80,105],"catch_rate":75,"evolutions":[],"friendship":70,"id":176,"learnset":{"address":3312590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C85EA7F43BC625","types":[0,2]},{"abilities":[28,48],"address":3301700,"base_stats":[40,50,45,70,70,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":178}],"friendship":70,"id":177,"learnset":{"address":3312616,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":30,"move_id":273},{"level":30,"move_id":248},{"level":40,"move_id":109},{"level":50,"move_id":94}]},"tmhm_learnset":"0040FE81B4378628","types":[14,2]},{"abilities":[28,48],"address":3301728,"base_stats":[65,75,70,95,95,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":178,"learnset":{"address":3312638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":35,"move_id":273},{"level":35,"move_id":248},{"level":50,"move_id":109},{"level":65,"move_id":94}]},"tmhm_learnset":"0048FE81B437C628","types":[14,2]},{"abilities":[9,0],"address":3301756,"base_stats":[55,40,40,35,65,45],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":15,"species":180}],"friendship":70,"id":179,"learnset":{"address":3312660,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":84},{"level":16,"move_id":86},{"level":23,"move_id":178},{"level":30,"move_id":113},{"level":37,"move_id":87}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[9,0],"address":3301784,"base_stats":[70,55,55,45,80,60],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":181}],"friendship":70,"id":180,"learnset":{"address":3312680,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":36,"move_id":113},{"level":45,"move_id":87}]},"tmhm_learnset":"00E01E02C5D38221","types":[13,13]},{"abilities":[9,0],"address":3301812,"base_stats":[90,75,75,55,115,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":181,"learnset":{"address":3312700,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":1,"move_id":86},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":30,"move_id":9},{"level":42,"move_id":113},{"level":57,"move_id":87}]},"tmhm_learnset":"00E01E02C5D3C221","types":[13,13]},{"abilities":[34,0],"address":3301840,"base_stats":[75,80,85,50,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":182,"learnset":{"address":3312722,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":78},{"level":1,"move_id":345},{"level":44,"move_id":80},{"level":55,"move_id":76}]},"tmhm_learnset":"00441E08843D4720","types":[12,12]},{"abilities":[47,37],"address":3301868,"base_stats":[70,20,50,40,20,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":18,"species":184}],"friendship":70,"id":183,"learnset":{"address":3312736,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":21,"move_id":61},{"level":28,"move_id":38},{"level":36,"move_id":240},{"level":45,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[47,37],"address":3301896,"base_stats":[100,50,80,50,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":184,"learnset":{"address":3312762,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":39},{"level":1,"move_id":55},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":24,"move_id":61},{"level":34,"move_id":38},{"level":45,"move_id":240},{"level":57,"move_id":56}]},"tmhm_learnset":"03B01E00CC537265","types":[11,11]},{"abilities":[5,69],"address":3301924,"base_stats":[70,100,115,30,30,65],"catch_rate":65,"evolutions":[],"friendship":70,"id":185,"learnset":{"address":3312788,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":102},{"level":9,"move_id":175},{"level":17,"move_id":67},{"level":25,"move_id":157},{"level":33,"move_id":335},{"level":41,"move_id":185},{"level":49,"move_id":21},{"level":57,"move_id":38}]},"tmhm_learnset":"00A03E50CE110E29","types":[5,5]},{"abilities":[11,6],"address":3301952,"base_stats":[90,75,75,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":186,"learnset":{"address":3312812,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":195},{"level":35,"move_id":195},{"level":51,"move_id":207}]},"tmhm_learnset":"03B03E00DE137265","types":[11,11]},{"abilities":[34,0],"address":3301980,"base_stats":[35,35,40,50,35,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":188}],"friendship":70,"id":187,"learnset":{"address":3312826,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":20,"move_id":73},{"level":25,"move_id":178},{"level":30,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302008,"base_stats":[55,45,50,80,45,65],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":27,"species":189}],"friendship":70,"id":188,"learnset":{"address":3312854,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":29,"move_id":178},{"level":36,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302036,"base_stats":[75,55,70,110,55,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":189,"learnset":{"address":3312882,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":33,"move_id":178},{"level":44,"move_id":72}]},"tmhm_learnset":"00401E8084354720","types":[12,2]},{"abilities":[50,53],"address":3302064,"base_stats":[55,70,55,85,40,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":190,"learnset":{"address":3312910,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":6,"move_id":28},{"level":13,"move_id":310},{"level":18,"move_id":226},{"level":25,"move_id":321},{"level":31,"move_id":154},{"level":38,"move_id":129},{"level":43,"move_id":103},{"level":50,"move_id":97}]},"tmhm_learnset":"00A53E82EDF30E25","types":[0,0]},{"abilities":[34,0],"address":3302092,"base_stats":[30,30,30,30,30,30],"catch_rate":235,"evolutions":[{"method":"ITEM","param":93,"species":192}],"friendship":70,"id":191,"learnset":{"address":3312936,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":6,"move_id":74},{"level":13,"move_id":72},{"level":18,"move_id":275},{"level":25,"move_id":283},{"level":30,"move_id":241},{"level":37,"move_id":235},{"level":42,"move_id":202}]},"tmhm_learnset":"00441E08843D8720","types":[12,12]},{"abilities":[34,0],"address":3302120,"base_stats":[75,75,55,30,105,85],"catch_rate":120,"evolutions":[],"friendship":70,"id":192,"learnset":{"address":3312960,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":1},{"level":6,"move_id":74},{"level":13,"move_id":75},{"level":18,"move_id":275},{"level":25,"move_id":331},{"level":30,"move_id":241},{"level":37,"move_id":80},{"level":42,"move_id":76}]},"tmhm_learnset":"00441E08843DC720","types":[12,12]},{"abilities":[3,14],"address":3302148,"base_stats":[65,65,45,95,75,45],"catch_rate":75,"evolutions":[],"friendship":70,"id":193,"learnset":{"address":3312984,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":193},{"level":7,"move_id":98},{"level":13,"move_id":104},{"level":19,"move_id":49},{"level":25,"move_id":197},{"level":31,"move_id":48},{"level":37,"move_id":253},{"level":43,"move_id":17},{"level":49,"move_id":103}]},"tmhm_learnset":"00407E80B4350620","types":[6,2]},{"abilities":[6,11],"address":3302176,"base_stats":[55,45,45,15,25,25],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":195}],"friendship":70,"id":194,"learnset":{"address":3313010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":21,"move_id":133},{"level":31,"move_id":281},{"level":36,"move_id":89},{"level":41,"move_id":240},{"level":51,"move_id":54},{"level":51,"move_id":114}]},"tmhm_learnset":"03D01E188E533264","types":[11,4]},{"abilities":[6,11],"address":3302204,"base_stats":[95,85,85,35,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":195,"learnset":{"address":3313036,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":23,"move_id":133},{"level":35,"move_id":281},{"level":42,"move_id":89},{"level":49,"move_id":240},{"level":61,"move_id":54},{"level":61,"move_id":114}]},"tmhm_learnset":"03F01E58CE537265","types":[11,4]},{"abilities":[28,0],"address":3302232,"base_stats":[65,65,60,110,130,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":196,"learnset":{"address":3313062,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":93},{"level":23,"move_id":98},{"level":30,"move_id":129},{"level":36,"move_id":60},{"level":42,"move_id":244},{"level":47,"move_id":94},{"level":52,"move_id":234}]},"tmhm_learnset":"00449E01BC53C628","types":[14,14]},{"abilities":[28,0],"address":3302260,"base_stats":[95,65,110,65,60,130],"catch_rate":45,"evolutions":[],"friendship":35,"id":197,"learnset":{"address":3313088,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":228},{"level":23,"move_id":98},{"level":30,"move_id":109},{"level":36,"move_id":185},{"level":42,"move_id":212},{"level":47,"move_id":103},{"level":52,"move_id":236}]},"tmhm_learnset":"00451F00BC534E20","types":[17,17]},{"abilities":[15,0],"address":3302288,"base_stats":[60,85,42,91,85,42],"catch_rate":30,"evolutions":[],"friendship":35,"id":198,"learnset":{"address":3313114,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":9,"move_id":310},{"level":14,"move_id":228},{"level":22,"move_id":114},{"level":27,"move_id":101},{"level":35,"move_id":185},{"level":40,"move_id":269},{"level":48,"move_id":212}]},"tmhm_learnset":"00097F80A4130E28","types":[17,2]},{"abilities":[12,20],"address":3302316,"base_stats":[95,75,80,30,100,110],"catch_rate":70,"evolutions":[],"friendship":70,"id":199,"learnset":{"address":3313138,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":207},{"level":48,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[26,0],"address":3302344,"base_stats":[60,60,60,85,85,85],"catch_rate":45,"evolutions":[],"friendship":35,"id":200,"learnset":{"address":3313162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":149},{"level":6,"move_id":180},{"level":11,"move_id":310},{"level":17,"move_id":109},{"level":23,"move_id":212},{"level":30,"move_id":60},{"level":37,"move_id":220},{"level":45,"move_id":195},{"level":53,"move_id":288}]},"tmhm_learnset":"0041BF82B5930E28","types":[7,7]},{"abilities":[26,0],"address":3302372,"base_stats":[48,72,48,48,72,48],"catch_rate":225,"evolutions":[],"friendship":70,"id":201,"learnset":{"address":3313188,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":237}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[23,0],"address":3302400,"base_stats":[190,33,58,33,33,58],"catch_rate":45,"evolutions":[],"friendship":70,"id":202,"learnset":{"address":3313198,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":243},{"level":1,"move_id":219},{"level":1,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[39,48],"address":3302428,"base_stats":[70,80,65,85,90,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":203,"learnset":{"address":3313208,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":7,"move_id":310},{"level":13,"move_id":93},{"level":19,"move_id":23},{"level":25,"move_id":316},{"level":31,"move_id":97},{"level":37,"move_id":226},{"level":43,"move_id":60},{"level":49,"move_id":242}]},"tmhm_learnset":"00E0BE03B7D38628","types":[0,14]},{"abilities":[5,0],"address":3302456,"base_stats":[50,65,90,15,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":205}],"friendship":70,"id":204,"learnset":{"address":3313234,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":36,"move_id":153},{"level":43,"move_id":191},{"level":50,"move_id":38}]},"tmhm_learnset":"00A01E118E358620","types":[6,6]},{"abilities":[5,0],"address":3302484,"base_stats":[75,90,140,40,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":205,"learnset":{"address":3313258,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":1,"move_id":120},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":39,"move_id":153},{"level":49,"move_id":191},{"level":59,"move_id":38}]},"tmhm_learnset":"00A01E118E35C620","types":[6,8]},{"abilities":[32,50],"address":3302512,"base_stats":[100,70,70,45,65,65],"catch_rate":190,"evolutions":[],"friendship":70,"id":206,"learnset":{"address":3313282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":4,"move_id":111},{"level":11,"move_id":281},{"level":14,"move_id":137},{"level":21,"move_id":180},{"level":24,"move_id":228},{"level":31,"move_id":103},{"level":34,"move_id":36},{"level":41,"move_id":283}]},"tmhm_learnset":"00A03E66AFF3362C","types":[0,0]},{"abilities":[52,8],"address":3302540,"base_stats":[65,75,105,85,35,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":207,"learnset":{"address":3313308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":28},{"level":13,"move_id":106},{"level":20,"move_id":98},{"level":28,"move_id":185},{"level":36,"move_id":163},{"level":44,"move_id":103},{"level":52,"move_id":12}]},"tmhm_learnset":"00A47ED88E530620","types":[4,2]},{"abilities":[69,5],"address":3302568,"base_stats":[75,85,200,30,55,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":208,"learnset":{"address":3313332,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":242},{"level":57,"move_id":38}]},"tmhm_learnset":"00A41F508E514E30","types":[8,4]},{"abilities":[22,50],"address":3302596,"base_stats":[60,80,50,30,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":23,"species":210}],"friendship":70,"id":209,"learnset":{"address":3313360,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":26,"move_id":46},{"level":34,"move_id":99},{"level":43,"move_id":36},{"level":53,"move_id":242}]},"tmhm_learnset":"00A23F2EEFB30EB5","types":[0,0]},{"abilities":[22,22],"address":3302624,"base_stats":[90,120,75,45,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":210,"learnset":{"address":3313386,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":28,"move_id":46},{"level":38,"move_id":99},{"level":49,"move_id":36},{"level":61,"move_id":242}]},"tmhm_learnset":"00A23F6EEFF34EB5","types":[0,0]},{"abilities":[38,33],"address":3302652,"base_stats":[65,95,75,85,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":211,"learnset":{"address":3313412,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":191},{"level":1,"move_id":33},{"level":1,"move_id":40},{"level":10,"move_id":106},{"level":10,"move_id":107},{"level":19,"move_id":55},{"level":28,"move_id":42},{"level":37,"move_id":36},{"level":46,"move_id":56}]},"tmhm_learnset":"03101E0AA4133264","types":[11,3]},{"abilities":[68,0],"address":3302680,"base_stats":[70,130,100,65,55,80],"catch_rate":25,"evolutions":[],"friendship":70,"id":212,"learnset":{"address":3313434,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":232},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00A47E9084134620","types":[6,8]},{"abilities":[5,0],"address":3302708,"base_stats":[20,10,230,5,10,230],"catch_rate":190,"evolutions":[],"friendship":70,"id":213,"learnset":{"address":3313462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":9,"move_id":35},{"level":14,"move_id":227},{"level":23,"move_id":219},{"level":28,"move_id":117},{"level":37,"move_id":156}]},"tmhm_learnset":"00E01E588E190620","types":[6,5]},{"abilities":[68,62],"address":3302736,"base_stats":[80,125,75,85,40,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":214,"learnset":{"address":3313482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":30},{"level":11,"move_id":203},{"level":17,"move_id":31},{"level":23,"move_id":280},{"level":30,"move_id":68},{"level":37,"move_id":36},{"level":45,"move_id":179},{"level":53,"move_id":224}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,1]},{"abilities":[39,51],"address":3302764,"base_stats":[55,95,55,115,35,75],"catch_rate":60,"evolutions":[],"friendship":35,"id":215,"learnset":{"address":3313508,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":269},{"level":8,"move_id":98},{"level":15,"move_id":103},{"level":22,"move_id":185},{"level":29,"move_id":154},{"level":36,"move_id":97},{"level":43,"move_id":196},{"level":50,"move_id":163},{"level":57,"move_id":251},{"level":64,"move_id":232}]},"tmhm_learnset":"00B53F80EC533E69","types":[17,15]},{"abilities":[53,0],"address":3302792,"base_stats":[60,80,50,40,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":217}],"friendship":70,"id":216,"learnset":{"address":3313536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43F80CE130EB1","types":[0,0]},{"abilities":[62,0],"address":3302820,"base_stats":[90,130,75,55,75,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":217,"learnset":{"address":3313562,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":122},{"level":1,"move_id":154},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43FC0CE134EB1","types":[0,0]},{"abilities":[40,49],"address":3302848,"base_stats":[40,40,40,20,70,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":219}],"friendship":70,"id":218,"learnset":{"address":3313588,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":43,"move_id":157},{"level":50,"move_id":34}]},"tmhm_learnset":"00821E2584118620","types":[10,10]},{"abilities":[40,49],"address":3302876,"base_stats":[50,50,120,30,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":219,"learnset":{"address":3313612,"moves":[{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":1,"move_id":52},{"level":1,"move_id":88},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":48,"move_id":157},{"level":60,"move_id":34}]},"tmhm_learnset":"00A21E758611C620","types":[10,5]},{"abilities":[12,0],"address":3302904,"base_stats":[50,50,40,50,30,30],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":221}],"friendship":70,"id":220,"learnset":{"address":3313636,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":316},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":37,"move_id":54},{"level":46,"move_id":59},{"level":55,"move_id":133}]},"tmhm_learnset":"00A01E518E13B270","types":[15,4]},{"abilities":[12,0],"address":3302932,"base_stats":[100,100,80,50,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":221,"learnset":{"address":3313658,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":316},{"level":1,"move_id":181},{"level":1,"move_id":203},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":33,"move_id":31},{"level":42,"move_id":54},{"level":56,"move_id":59},{"level":70,"move_id":133}]},"tmhm_learnset":"00A01E518E13F270","types":[15,4]},{"abilities":[55,30],"address":3302960,"base_stats":[55,55,85,35,65,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":222,"learnset":{"address":3313682,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":106},{"level":12,"move_id":145},{"level":17,"move_id":105},{"level":17,"move_id":287},{"level":23,"move_id":61},{"level":28,"move_id":131},{"level":34,"move_id":350},{"level":39,"move_id":243},{"level":45,"move_id":246}]},"tmhm_learnset":"00B01E51BE1BB66C","types":[11,5]},{"abilities":[55,0],"address":3302988,"base_stats":[35,65,35,65,65,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":224}],"friendship":70,"id":223,"learnset":{"address":3313710,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":199},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":33,"move_id":116},{"level":44,"move_id":58},{"level":55,"move_id":63}]},"tmhm_learnset":"03103E2494137624","types":[11,11]},{"abilities":[21,0],"address":3303016,"base_stats":[75,105,75,45,105,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":224,"learnset":{"address":3313734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":132},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":25,"move_id":190},{"level":38,"move_id":116},{"level":54,"move_id":58},{"level":70,"move_id":63}]},"tmhm_learnset":"03103E2C94137724","types":[11,11]},{"abilities":[72,55],"address":3303044,"base_stats":[45,55,45,75,65,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":225,"learnset":{"address":3313760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":217}]},"tmhm_learnset":"00083E8084133265","types":[15,2]},{"abilities":[33,11],"address":3303072,"base_stats":[65,40,70,70,80,140],"catch_rate":25,"evolutions":[],"friendship":70,"id":226,"learnset":{"address":3313770,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":145},{"level":8,"move_id":48},{"level":15,"move_id":61},{"level":22,"move_id":36},{"level":29,"move_id":97},{"level":36,"move_id":17},{"level":43,"move_id":352},{"level":50,"move_id":109}]},"tmhm_learnset":"03101E8086133264","types":[11,2]},{"abilities":[51,5],"address":3303100,"base_stats":[65,80,140,70,40,70],"catch_rate":25,"evolutions":[],"friendship":70,"id":227,"learnset":{"address":3313794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":10,"move_id":28},{"level":13,"move_id":129},{"level":16,"move_id":97},{"level":26,"move_id":31},{"level":29,"move_id":314},{"level":32,"move_id":211},{"level":42,"move_id":191},{"level":45,"move_id":319}]},"tmhm_learnset":"008C7F9084110E30","types":[8,2]},{"abilities":[48,18],"address":3303128,"base_stats":[45,60,30,65,80,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":24,"species":229}],"friendship":35,"id":228,"learnset":{"address":3313820,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":25,"move_id":44},{"level":31,"move_id":316},{"level":37,"move_id":185},{"level":43,"move_id":53},{"level":49,"move_id":242}]},"tmhm_learnset":"00833F2CA4710E30","types":[17,10]},{"abilities":[48,18],"address":3303156,"base_stats":[75,90,50,95,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":229,"learnset":{"address":3313846,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":1,"move_id":336},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":27,"move_id":44},{"level":35,"move_id":316},{"level":43,"move_id":185},{"level":51,"move_id":53},{"level":59,"move_id":242}]},"tmhm_learnset":"00A33F2CA4714E30","types":[17,10]},{"abilities":[33,0],"address":3303184,"base_stats":[75,95,95,85,95,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":230,"learnset":{"address":3313872,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,16]},{"abilities":[53,0],"address":3303212,"base_stats":[90,60,60,40,40,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":25,"species":232}],"friendship":70,"id":231,"learnset":{"address":3313896,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":36},{"level":33,"move_id":205},{"level":41,"move_id":203},{"level":49,"move_id":38}]},"tmhm_learnset":"00A01E5086510630","types":[4,4]},{"abilities":[5,0],"address":3303240,"base_stats":[90,120,120,50,60,60],"catch_rate":60,"evolutions":[],"friendship":70,"id":232,"learnset":{"address":3313918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":30},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":31},{"level":33,"move_id":205},{"level":41,"move_id":229},{"level":49,"move_id":89}]},"tmhm_learnset":"00A01E5086514630","types":[4,4]},{"abilities":[36,0],"address":3303268,"base_stats":[85,80,90,60,105,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":233,"learnset":{"address":3313940,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":111},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[22,0],"address":3303296,"base_stats":[73,95,62,85,85,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":234,"learnset":{"address":3313966,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":43},{"level":13,"move_id":310},{"level":19,"move_id":95},{"level":25,"move_id":23},{"level":31,"move_id":28},{"level":37,"move_id":36},{"level":43,"move_id":109},{"level":49,"move_id":347}]},"tmhm_learnset":"0040BE03B7F38638","types":[0,0]},{"abilities":[20,0],"address":3303324,"base_stats":[55,20,35,75,20,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":235,"learnset":{"address":3313992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":166},{"level":11,"move_id":166},{"level":21,"move_id":166},{"level":31,"move_id":166},{"level":41,"move_id":166},{"level":51,"move_id":166},{"level":61,"move_id":166},{"level":71,"move_id":166},{"level":81,"move_id":166},{"level":91,"move_id":166}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[62,0],"address":3303352,"base_stats":[35,35,35,35,35,35],"catch_rate":75,"evolutions":[{"method":"LEVEL_ATK_LT_DEF","param":20,"species":107},{"method":"LEVEL_ATK_GT_DEF","param":20,"species":106},{"method":"LEVEL_ATK_EQ_DEF","param":20,"species":237}],"friendship":70,"id":236,"learnset":{"address":3314020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"00A03E00C61306A0","types":[1,1]},{"abilities":[22,0],"address":3303380,"base_stats":[50,95,95,70,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":237,"learnset":{"address":3314030,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":27},{"level":7,"move_id":116},{"level":13,"move_id":228},{"level":19,"move_id":98},{"level":20,"move_id":167},{"level":25,"move_id":229},{"level":31,"move_id":68},{"level":37,"move_id":97},{"level":43,"move_id":197},{"level":49,"move_id":283}]},"tmhm_learnset":"00A03E10CE1306A0","types":[1,1]},{"abilities":[12,0],"address":3303408,"base_stats":[45,30,15,65,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":124}],"friendship":70,"id":238,"learnset":{"address":3314058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":9,"move_id":186},{"level":13,"move_id":181},{"level":21,"move_id":93},{"level":25,"move_id":47},{"level":33,"move_id":212},{"level":37,"move_id":313},{"level":45,"move_id":94},{"level":49,"move_id":195},{"level":57,"move_id":59}]},"tmhm_learnset":"0040BE01B413B26C","types":[15,14]},{"abilities":[9,0],"address":3303436,"base_stats":[45,63,37,95,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":125}],"friendship":70,"id":239,"learnset":{"address":3314086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":33,"move_id":103},{"level":41,"move_id":85},{"level":49,"move_id":87}]},"tmhm_learnset":"00C03E02D5938221","types":[13,13]},{"abilities":[49,0],"address":3303464,"base_stats":[45,75,37,83,70,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":126}],"friendship":70,"id":240,"learnset":{"address":3314108,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":31,"move_id":241},{"level":37,"move_id":53},{"level":43,"move_id":109},{"level":49,"move_id":126}]},"tmhm_learnset":"00803E24D4510621","types":[10,10]},{"abilities":[47,0],"address":3303492,"base_stats":[95,80,105,100,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":241,"learnset":{"address":3314134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":8,"move_id":111},{"level":13,"move_id":23},{"level":19,"move_id":208},{"level":26,"move_id":117},{"level":34,"move_id":205},{"level":43,"move_id":34},{"level":53,"move_id":215}]},"tmhm_learnset":"00B01E52E7F37625","types":[0,0]},{"abilities":[30,32],"address":3303520,"base_stats":[255,10,10,55,75,135],"catch_rate":30,"evolutions":[],"friendship":140,"id":242,"learnset":{"address":3314160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":4,"move_id":39},{"level":7,"move_id":287},{"level":10,"move_id":135},{"level":13,"move_id":3},{"level":18,"move_id":107},{"level":23,"move_id":47},{"level":28,"move_id":121},{"level":33,"move_id":111},{"level":40,"move_id":113},{"level":47,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[46,0],"address":3303548,"base_stats":[90,85,75,115,115,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":243,"learnset":{"address":3314190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":84},{"level":21,"move_id":46},{"level":31,"move_id":98},{"level":41,"move_id":209},{"level":51,"move_id":115},{"level":61,"move_id":242},{"level":71,"move_id":87},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E138DD34638","types":[13,13]},{"abilities":[46,0],"address":3303576,"base_stats":[115,115,85,100,90,75],"catch_rate":3,"evolutions":[],"friendship":35,"id":244,"learnset":{"address":3314216,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":52},{"level":21,"move_id":46},{"level":31,"move_id":83},{"level":41,"move_id":23},{"level":51,"move_id":53},{"level":61,"move_id":207},{"level":71,"move_id":126},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E358C734638","types":[10,10]},{"abilities":[46,0],"address":3303604,"base_stats":[100,75,115,85,90,115],"catch_rate":3,"evolutions":[],"friendship":35,"id":245,"learnset":{"address":3314242,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":61},{"level":21,"move_id":240},{"level":31,"move_id":16},{"level":41,"move_id":62},{"level":51,"move_id":54},{"level":61,"move_id":243},{"level":71,"move_id":56},{"level":81,"move_id":347}]},"tmhm_learnset":"03940E118C53767C","types":[11,11]},{"abilities":[62,0],"address":3303632,"base_stats":[50,64,50,41,45,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":247}],"friendship":35,"id":246,"learnset":{"address":3314268,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":36,"move_id":184},{"level":43,"move_id":242},{"level":50,"move_id":89},{"level":57,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[61,0],"address":3303660,"base_stats":[70,84,70,51,65,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":248}],"friendship":35,"id":247,"learnset":{"address":3314294,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":56,"move_id":89},{"level":65,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[45,0],"address":3303688,"base_stats":[100,134,110,61,95,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":248,"learnset":{"address":3314320,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":61,"move_id":89},{"level":75,"move_id":63}]},"tmhm_learnset":"00B41FF6CFD37E37","types":[5,17]},{"abilities":[46,0],"address":3303716,"base_stats":[106,90,130,110,90,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":249,"learnset":{"address":3314346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":56},{"level":55,"move_id":240},{"level":66,"move_id":129},{"level":77,"move_id":177},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"03B8CE93B7DFF67C","types":[14,2]},{"abilities":[46,0],"address":3303744,"base_stats":[106,130,90,90,110,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":250,"learnset":{"address":3314374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":126},{"level":55,"move_id":241},{"level":66,"move_id":129},{"level":77,"move_id":221},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"00EA4EB7B7BFC638","types":[10,2]},{"abilities":[30,0],"address":3303772,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":251,"learnset":{"address":3314402,"moves":[{"level":1,"move_id":73},{"level":1,"move_id":93},{"level":1,"move_id":105},{"level":1,"move_id":215},{"level":10,"move_id":219},{"level":20,"move_id":246},{"level":30,"move_id":248},{"level":40,"move_id":226},{"level":50,"move_id":195}]},"tmhm_learnset":"00448E93B43FC62C","types":[14,12]},{"abilities":[0,0],"address":3303800,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":252,"learnset":{"address":3314422,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303828,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":253,"learnset":{"address":3314432,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303856,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":254,"learnset":{"address":3314442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303884,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":255,"learnset":{"address":3314452,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303912,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":256,"learnset":{"address":3314462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303940,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":257,"learnset":{"address":3314472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303968,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":258,"learnset":{"address":3314482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303996,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":259,"learnset":{"address":3314492,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304024,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":260,"learnset":{"address":3314502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304052,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":261,"learnset":{"address":3314512,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304080,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":262,"learnset":{"address":3314522,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304108,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":263,"learnset":{"address":3314532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304136,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":264,"learnset":{"address":3314542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304164,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":265,"learnset":{"address":3314552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304192,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":266,"learnset":{"address":3314562,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304220,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":267,"learnset":{"address":3314572,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304248,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":268,"learnset":{"address":3314582,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304276,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":269,"learnset":{"address":3314592,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304304,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":270,"learnset":{"address":3314602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304332,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":271,"learnset":{"address":3314612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304360,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":272,"learnset":{"address":3314622,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304388,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":273,"learnset":{"address":3314632,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304416,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":274,"learnset":{"address":3314642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304444,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":275,"learnset":{"address":3314652,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304472,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":276,"learnset":{"address":3314662,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3304500,"base_stats":[40,45,35,70,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":278}],"friendship":70,"id":277,"learnset":{"address":3314672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":228},{"level":21,"move_id":103},{"level":26,"move_id":72},{"level":31,"move_id":97},{"level":36,"move_id":21},{"level":41,"move_id":197},{"level":46,"move_id":202}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304528,"base_stats":[50,65,45,95,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":279}],"friendship":70,"id":278,"learnset":{"address":3314700,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":41,"move_id":21},{"level":47,"move_id":197},{"level":53,"move_id":206}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304556,"base_stats":[70,85,65,120,105,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":279,"learnset":{"address":3314730,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":43,"move_id":21},{"level":51,"move_id":197},{"level":59,"move_id":206}]},"tmhm_learnset":"00E41EC0CE7D4733","types":[12,12]},{"abilities":[66,0],"address":3304584,"base_stats":[45,60,40,45,70,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":281}],"friendship":70,"id":280,"learnset":{"address":3314760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":116},{"level":10,"move_id":52},{"level":16,"move_id":64},{"level":19,"move_id":28},{"level":25,"move_id":83},{"level":28,"move_id":98},{"level":34,"move_id":163},{"level":37,"move_id":119},{"level":43,"move_id":53}]},"tmhm_learnset":"00A61EE48C110620","types":[10,10]},{"abilities":[66,0],"address":3304612,"base_stats":[60,85,60,55,85,60],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":282}],"friendship":70,"id":281,"learnset":{"address":3314788,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":39,"move_id":163},{"level":43,"move_id":119},{"level":50,"move_id":327}]},"tmhm_learnset":"00A61EE4CC1106A1","types":[10,1]},{"abilities":[66,0],"address":3304640,"base_stats":[80,120,70,80,110,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":282,"learnset":{"address":3314818,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":36,"move_id":299},{"level":42,"move_id":163},{"level":49,"move_id":119},{"level":59,"move_id":327}]},"tmhm_learnset":"00A61EE4CE1146B1","types":[10,1]},{"abilities":[67,0],"address":3304668,"base_stats":[50,70,50,40,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":284}],"friendship":70,"id":283,"learnset":{"address":3314852,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":19,"move_id":193},{"level":24,"move_id":300},{"level":28,"move_id":36},{"level":33,"move_id":250},{"level":37,"move_id":182},{"level":42,"move_id":56},{"level":46,"move_id":283}]},"tmhm_learnset":"03B01E408C533264","types":[11,11]},{"abilities":[67,0],"address":3304696,"base_stats":[70,85,70,50,60,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":285}],"friendship":70,"id":284,"learnset":{"address":3314882,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":37,"move_id":330},{"level":42,"move_id":182},{"level":46,"move_id":89},{"level":53,"move_id":283}]},"tmhm_learnset":"03B01E408E533264","types":[11,4]},{"abilities":[67,0],"address":3304724,"base_stats":[100,110,90,60,85,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":285,"learnset":{"address":3314914,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":39,"move_id":330},{"level":46,"move_id":182},{"level":52,"move_id":89},{"level":61,"move_id":283}]},"tmhm_learnset":"03B01E40CE537275","types":[11,4]},{"abilities":[50,0],"address":3304752,"base_stats":[35,55,35,35,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":287}],"friendship":70,"id":286,"learnset":{"address":3314946,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":21,"move_id":46},{"level":25,"move_id":207},{"level":29,"move_id":184},{"level":33,"move_id":36},{"level":37,"move_id":269},{"level":41,"move_id":242},{"level":45,"move_id":168}]},"tmhm_learnset":"00813F00AC530E30","types":[17,17]},{"abilities":[22,0],"address":3304780,"base_stats":[70,90,70,70,60,60],"catch_rate":127,"evolutions":[],"friendship":70,"id":287,"learnset":{"address":3314978,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":336},{"level":1,"move_id":28},{"level":1,"move_id":44},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":22,"move_id":46},{"level":27,"move_id":207},{"level":32,"move_id":184},{"level":37,"move_id":36},{"level":42,"move_id":269},{"level":47,"move_id":242},{"level":52,"move_id":168}]},"tmhm_learnset":"00A13F00AC534E30","types":[17,17]},{"abilities":[53,0],"address":3304808,"base_stats":[38,30,41,60,30,41],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":289}],"friendship":70,"id":288,"learnset":{"address":3315010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":21,"move_id":300},{"level":25,"move_id":42},{"level":29,"move_id":343},{"level":33,"move_id":175},{"level":37,"move_id":156},{"level":41,"move_id":187}]},"tmhm_learnset":"00943E02ADD33624","types":[0,0]},{"abilities":[53,0],"address":3304836,"base_stats":[78,70,61,100,50,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":289,"learnset":{"address":3315040,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":23,"move_id":300},{"level":29,"move_id":154},{"level":35,"move_id":343},{"level":41,"move_id":163},{"level":47,"move_id":156},{"level":53,"move_id":187}]},"tmhm_learnset":"00B43E02ADD37634","types":[0,0]},{"abilities":[19,0],"address":3304864,"base_stats":[45,45,35,20,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_SILCOON","param":7,"species":291},{"method":"LEVEL_CASCOON","param":7,"species":293}],"friendship":70,"id":290,"learnset":{"address":3315070,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81},{"level":5,"move_id":40}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3304892,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":292}],"friendship":70,"id":291,"learnset":{"address":3315082,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[68,0],"address":3304920,"base_stats":[60,70,50,65,90,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":292,"learnset":{"address":3315094,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":10,"move_id":71},{"level":13,"move_id":16},{"level":17,"move_id":78},{"level":20,"move_id":234},{"level":24,"move_id":72},{"level":27,"move_id":18},{"level":31,"move_id":213},{"level":34,"move_id":318},{"level":38,"move_id":202}]},"tmhm_learnset":"00403E80B43D4620","types":[6,2]},{"abilities":[61,0],"address":3304948,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":294}],"friendship":70,"id":293,"learnset":{"address":3315122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[19,0],"address":3304976,"base_stats":[60,50,70,65,50,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":294,"learnset":{"address":3315134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":16},{"level":17,"move_id":182},{"level":20,"move_id":236},{"level":24,"move_id":60},{"level":27,"move_id":18},{"level":31,"move_id":113},{"level":34,"move_id":318},{"level":38,"move_id":92}]},"tmhm_learnset":"00403E88B435C620","types":[6,3]},{"abilities":[33,44],"address":3305004,"base_stats":[40,30,30,30,40,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":296}],"friendship":70,"id":295,"learnset":{"address":3315162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":21,"move_id":54},{"level":31,"move_id":240},{"level":43,"move_id":72}]},"tmhm_learnset":"00503E0084373764","types":[11,12]},{"abilities":[33,44],"address":3305032,"base_stats":[60,50,50,50,60,70],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":297}],"friendship":70,"id":296,"learnset":{"address":3315184,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":154},{"level":31,"move_id":346},{"level":37,"move_id":168},{"level":43,"move_id":253},{"level":49,"move_id":56}]},"tmhm_learnset":"03F03E00C4373764","types":[11,12]},{"abilities":[33,44],"address":3305060,"base_stats":[80,70,70,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":297,"learnset":{"address":3315212,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":45},{"level":1,"move_id":71},{"level":1,"move_id":267}]},"tmhm_learnset":"03F03E00C4377765","types":[11,12]},{"abilities":[34,48],"address":3305088,"base_stats":[40,40,50,30,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":299}],"friendship":70,"id":298,"learnset":{"address":3315222,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":21,"move_id":235},{"level":31,"move_id":241},{"level":43,"move_id":153}]},"tmhm_learnset":"00C01E00AC350720","types":[12,12]},{"abilities":[34,48],"address":3305116,"base_stats":[70,70,40,60,60,40],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":300}],"friendship":70,"id":299,"learnset":{"address":3315244,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":259},{"level":31,"move_id":185},{"level":37,"move_id":13},{"level":43,"move_id":207},{"level":49,"move_id":326}]},"tmhm_learnset":"00E43F40EC354720","types":[12,17]},{"abilities":[34,48],"address":3305144,"base_stats":[90,100,60,80,90,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":300,"learnset":{"address":3315272,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":1,"move_id":74},{"level":1,"move_id":267}]},"tmhm_learnset":"00E43FC0EC354720","types":[12,17]},{"abilities":[14,0],"address":3305172,"base_stats":[31,45,90,40,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_NINJASK","param":20,"species":302},{"method":"LEVEL_SHEDINJA","param":20,"species":303}],"friendship":70,"id":301,"learnset":{"address":3315282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":206},{"level":31,"move_id":189},{"level":38,"move_id":232},{"level":45,"move_id":91}]},"tmhm_learnset":"00440E90AC350620","types":[6,4]},{"abilities":[3,0],"address":3305200,"base_stats":[61,90,45,160,50,50],"catch_rate":120,"evolutions":[],"friendship":70,"id":302,"learnset":{"address":3315308,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":141},{"level":1,"move_id":28},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":20,"move_id":104},{"level":20,"move_id":210},{"level":20,"move_id":103},{"level":25,"move_id":14},{"level":31,"move_id":163},{"level":38,"move_id":97},{"level":45,"move_id":226}]},"tmhm_learnset":"00443E90AC354620","types":[6,2]},{"abilities":[25,0],"address":3305228,"base_stats":[1,90,45,40,30,30],"catch_rate":45,"evolutions":[],"friendship":70,"id":303,"learnset":{"address":3315340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":180},{"level":31,"move_id":109},{"level":38,"move_id":247},{"level":45,"move_id":288}]},"tmhm_learnset":"00442E90AC354620","types":[6,7]},{"abilities":[62,0],"address":3305256,"base_stats":[40,55,30,85,30,30],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":305}],"friendship":70,"id":304,"learnset":{"address":3315366,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":26,"move_id":283},{"level":34,"move_id":332},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[62,0],"address":3305284,"base_stats":[60,85,60,125,50,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":305,"learnset":{"address":3315390,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":98},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":28,"move_id":283},{"level":38,"move_id":332},{"level":49,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[27,0],"address":3305312,"base_stats":[60,40,60,35,40,60],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":23,"species":307}],"friendship":70,"id":306,"learnset":{"address":3315414,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":28,"move_id":77},{"level":36,"move_id":74},{"level":45,"move_id":202},{"level":54,"move_id":147}]},"tmhm_learnset":"00411E08843D0720","types":[12,12]},{"abilities":[27,0],"address":3305340,"base_stats":[60,130,80,70,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":307,"learnset":{"address":3315442,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":33},{"level":1,"move_id":78},{"level":1,"move_id":73},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":23,"move_id":183},{"level":28,"move_id":68},{"level":36,"move_id":327},{"level":45,"move_id":170},{"level":54,"move_id":223}]},"tmhm_learnset":"00E51E08C47D47A1","types":[12,1]},{"abilities":[20,0],"address":3305368,"base_stats":[60,60,60,60,60,60],"catch_rate":255,"evolutions":[],"friendship":70,"id":308,"learnset":{"address":3315472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":253},{"level":12,"move_id":185},{"level":16,"move_id":60},{"level":23,"move_id":95},{"level":27,"move_id":146},{"level":34,"move_id":298},{"level":38,"move_id":244},{"level":45,"move_id":38},{"level":49,"move_id":175},{"level":56,"move_id":37}]},"tmhm_learnset":"00E1BE42FC1B062D","types":[0,0]},{"abilities":[51,0],"address":3305396,"base_stats":[40,30,30,85,55,30],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":310}],"friendship":70,"id":309,"learnset":{"address":3315502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":31,"move_id":98},{"level":43,"move_id":228},{"level":55,"move_id":97}]},"tmhm_learnset":"00087E8284133264","types":[11,2]},{"abilities":[51,0],"address":3305424,"base_stats":[60,50,100,65,85,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":310,"learnset":{"address":3315524,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":346},{"level":1,"move_id":17},{"level":3,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":25,"move_id":182},{"level":33,"move_id":254},{"level":33,"move_id":256},{"level":47,"move_id":255},{"level":61,"move_id":56}]},"tmhm_learnset":"00187E8284137264","types":[11,2]},{"abilities":[33,0],"address":3305452,"base_stats":[40,30,32,65,50,52],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":312}],"friendship":70,"id":311,"learnset":{"address":3315552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":25,"move_id":61},{"level":31,"move_id":97},{"level":37,"move_id":54},{"level":37,"move_id":114}]},"tmhm_learnset":"00403E00A4373624","types":[6,11]},{"abilities":[22,0],"address":3305480,"base_stats":[70,60,62,60,80,82],"catch_rate":75,"evolutions":[],"friendship":70,"id":312,"learnset":{"address":3315576,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":98},{"level":1,"move_id":230},{"level":1,"move_id":346},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":26,"move_id":16},{"level":33,"move_id":184},{"level":40,"move_id":78},{"level":47,"move_id":318},{"level":53,"move_id":18}]},"tmhm_learnset":"00403E80A4377624","types":[6,2]},{"abilities":[41,12],"address":3305508,"base_stats":[130,70,35,60,70,35],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":40,"species":314}],"friendship":70,"id":313,"learnset":{"address":3315602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":150},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":41,"move_id":323},{"level":46,"move_id":133},{"level":50,"move_id":56}]},"tmhm_learnset":"03B01E4086133274","types":[11,11]},{"abilities":[41,12],"address":3305536,"base_stats":[170,90,45,60,90,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":314,"learnset":{"address":3315634,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":205},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":44,"move_id":323},{"level":52,"move_id":133},{"level":59,"move_id":56}]},"tmhm_learnset":"03B01E4086137274","types":[11,11]},{"abilities":[56,0],"address":3305564,"base_stats":[50,45,45,50,35,35],"catch_rate":255,"evolutions":[{"method":"ITEM","param":94,"species":316}],"friendship":70,"id":315,"learnset":{"address":3315666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":3,"move_id":39},{"level":7,"move_id":213},{"level":13,"move_id":47},{"level":15,"move_id":3},{"level":19,"move_id":274},{"level":25,"move_id":204},{"level":27,"move_id":185},{"level":31,"move_id":343},{"level":37,"move_id":215},{"level":39,"move_id":38}]},"tmhm_learnset":"00401E02ADFB362C","types":[0,0]},{"abilities":[56,0],"address":3305592,"base_stats":[70,65,65,70,55,55],"catch_rate":60,"evolutions":[],"friendship":70,"id":316,"learnset":{"address":3315696,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":213},{"level":1,"move_id":47},{"level":1,"move_id":3}]},"tmhm_learnset":"00E01E02ADFB762C","types":[0,0]},{"abilities":[16,0],"address":3305620,"base_stats":[60,90,70,40,60,120],"catch_rate":200,"evolutions":[],"friendship":70,"id":317,"learnset":{"address":3315706,"moves":[{"level":1,"move_id":168},{"level":1,"move_id":39},{"level":1,"move_id":310},{"level":1,"move_id":122},{"level":1,"move_id":10},{"level":4,"move_id":20},{"level":7,"move_id":185},{"level":12,"move_id":154},{"level":17,"move_id":60},{"level":24,"move_id":103},{"level":31,"move_id":163},{"level":40,"move_id":164},{"level":49,"move_id":246}]},"tmhm_learnset":"00E5BEE6EDF33625","types":[0,0]},{"abilities":[26,0],"address":3305648,"base_stats":[40,40,55,55,40,70],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":36,"species":319}],"friendship":70,"id":318,"learnset":{"address":3315734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":37,"move_id":322},{"level":45,"move_id":153}]},"tmhm_learnset":"00408E51BE339620","types":[4,14]},{"abilities":[26,0],"address":3305676,"base_stats":[60,70,105,75,70,120],"catch_rate":90,"evolutions":[],"friendship":70,"id":319,"learnset":{"address":3315764,"moves":[{"level":1,"move_id":100},{"level":1,"move_id":93},{"level":1,"move_id":106},{"level":1,"move_id":229},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":36,"move_id":63},{"level":42,"move_id":322},{"level":55,"move_id":153}]},"tmhm_learnset":"00E08E51BE33D620","types":[4,14]},{"abilities":[5,42],"address":3305704,"base_stats":[30,45,135,30,45,90],"catch_rate":255,"evolutions":[],"friendship":70,"id":320,"learnset":{"address":3315796,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":106},{"level":13,"move_id":88},{"level":16,"move_id":335},{"level":22,"move_id":86},{"level":28,"move_id":157},{"level":31,"move_id":201},{"level":37,"move_id":156},{"level":43,"move_id":192},{"level":46,"move_id":199}]},"tmhm_learnset":"00A01F5287910E20","types":[5,5]},{"abilities":[73,0],"address":3305732,"base_stats":[70,85,140,20,85,70],"catch_rate":90,"evolutions":[],"friendship":70,"id":321,"learnset":{"address":3315824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":4,"move_id":123},{"level":7,"move_id":174},{"level":14,"move_id":108},{"level":17,"move_id":83},{"level":20,"move_id":34},{"level":27,"move_id":182},{"level":30,"move_id":53},{"level":33,"move_id":334},{"level":40,"move_id":133},{"level":43,"move_id":175},{"level":46,"move_id":257}]},"tmhm_learnset":"00A21E2C84510620","types":[10,10]},{"abilities":[51,0],"address":3305760,"base_stats":[50,75,75,50,65,65],"catch_rate":45,"evolutions":[],"friendship":35,"id":322,"learnset":{"address":3315856,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":10},{"level":5,"move_id":193},{"level":9,"move_id":101},{"level":13,"move_id":310},{"level":17,"move_id":154},{"level":21,"move_id":252},{"level":25,"move_id":197},{"level":29,"move_id":185},{"level":33,"move_id":282},{"level":37,"move_id":109},{"level":41,"move_id":247},{"level":45,"move_id":212}]},"tmhm_learnset":"00C53FC2FC130E2D","types":[17,7]},{"abilities":[12,0],"address":3305788,"base_stats":[50,48,43,60,46,41],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":324}],"friendship":70,"id":323,"learnset":{"address":3315888,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":189},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":31,"move_id":89},{"level":36,"move_id":248},{"level":41,"move_id":90}]},"tmhm_learnset":"03101E5086133264","types":[11,4]},{"abilities":[12,0],"address":3305816,"base_stats":[110,78,73,60,76,71],"catch_rate":75,"evolutions":[],"friendship":70,"id":324,"learnset":{"address":3315918,"moves":[{"level":1,"move_id":321},{"level":1,"move_id":189},{"level":1,"move_id":300},{"level":1,"move_id":346},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":36,"move_id":89},{"level":46,"move_id":248},{"level":56,"move_id":90}]},"tmhm_learnset":"03B01E5086137264","types":[11,4]},{"abilities":[33,0],"address":3305844,"base_stats":[43,30,55,97,40,65],"catch_rate":225,"evolutions":[],"friendship":70,"id":325,"learnset":{"address":3315948,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":204},{"level":12,"move_id":55},{"level":16,"move_id":97},{"level":24,"move_id":36},{"level":28,"move_id":213},{"level":36,"move_id":186},{"level":40,"move_id":175},{"level":48,"move_id":219}]},"tmhm_learnset":"03101E00841B3264","types":[11,11]},{"abilities":[52,75],"address":3305872,"base_stats":[43,80,65,35,50,35],"catch_rate":205,"evolutions":[{"method":"LEVEL","param":30,"species":327}],"friendship":70,"id":326,"learnset":{"address":3315974,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":32,"move_id":269},{"level":35,"move_id":152},{"level":38,"move_id":14},{"level":44,"move_id":12}]},"tmhm_learnset":"01B41EC8CC133A64","types":[11,11]},{"abilities":[52,75],"address":3305900,"base_stats":[63,120,85,55,90,55],"catch_rate":155,"evolutions":[],"friendship":70,"id":327,"learnset":{"address":3316004,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":106},{"level":1,"move_id":11},{"level":1,"move_id":43},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":34,"move_id":269},{"level":39,"move_id":152},{"level":44,"move_id":14},{"level":52,"move_id":12}]},"tmhm_learnset":"03B41EC8CC137A64","types":[11,17]},{"abilities":[33,0],"address":3305928,"base_stats":[20,15,20,80,10,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":30,"species":329}],"friendship":70,"id":328,"learnset":{"address":3316034,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[63,0],"address":3305956,"base_stats":[95,60,79,81,100,125],"catch_rate":60,"evolutions":[],"friendship":70,"id":329,"learnset":{"address":3316048,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":5,"move_id":35},{"level":10,"move_id":346},{"level":15,"move_id":287},{"level":20,"move_id":352},{"level":25,"move_id":239},{"level":30,"move_id":105},{"level":35,"move_id":240},{"level":40,"move_id":56},{"level":45,"move_id":213},{"level":50,"move_id":219}]},"tmhm_learnset":"03101E00845B7264","types":[11,11]},{"abilities":[24,0],"address":3305984,"base_stats":[45,90,20,65,65,20],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":30,"species":331}],"friendship":35,"id":330,"learnset":{"address":3316078,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":31,"move_id":36},{"level":37,"move_id":207},{"level":43,"move_id":97}]},"tmhm_learnset":"03103F0084133A64","types":[11,17]},{"abilities":[24,0],"address":3306012,"base_stats":[70,120,40,95,95,40],"catch_rate":60,"evolutions":[],"friendship":35,"id":331,"learnset":{"address":3316104,"moves":[{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":1,"move_id":99},{"level":1,"move_id":116},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":33,"move_id":163},{"level":38,"move_id":269},{"level":43,"move_id":207},{"level":48,"move_id":130},{"level":53,"move_id":97}]},"tmhm_learnset":"03B03F4086137A74","types":[11,17]},{"abilities":[52,71],"address":3306040,"base_stats":[45,100,45,10,45,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":333}],"friendship":70,"id":332,"learnset":{"address":3316134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":41,"move_id":91},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A01E508E354620","types":[4,4]},{"abilities":[26,26],"address":3306068,"base_stats":[50,70,50,70,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":45,"species":334}],"friendship":70,"id":333,"learnset":{"address":3316158,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A85E508E354620","types":[4,16]},{"abilities":[26,26],"address":3306096,"base_stats":[80,100,80,100,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":334,"learnset":{"address":3316184,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":53,"move_id":201},{"level":65,"move_id":63}]},"tmhm_learnset":"00A85E748E754622","types":[4,16]},{"abilities":[47,62],"address":3306124,"base_stats":[72,60,30,25,20,30],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":24,"species":336}],"friendship":70,"id":335,"learnset":{"address":3316210,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":28,"move_id":282},{"level":31,"move_id":265},{"level":37,"move_id":187},{"level":40,"move_id":203},{"level":46,"move_id":69},{"level":49,"move_id":179}]},"tmhm_learnset":"00B01E40CE1306A1","types":[1,1]},{"abilities":[47,62],"address":3306152,"base_stats":[144,120,60,50,40,60],"catch_rate":200,"evolutions":[],"friendship":70,"id":336,"learnset":{"address":3316242,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":1,"move_id":28},{"level":1,"move_id":292},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":29,"move_id":282},{"level":33,"move_id":265},{"level":40,"move_id":187},{"level":44,"move_id":203},{"level":51,"move_id":69},{"level":55,"move_id":179}]},"tmhm_learnset":"00B01E40CE1346A1","types":[1,1]},{"abilities":[9,31],"address":3306180,"base_stats":[40,45,40,65,65,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":26,"species":338}],"friendship":70,"id":337,"learnset":{"address":3316274,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":28,"move_id":46},{"level":33,"move_id":44},{"level":36,"move_id":87},{"level":41,"move_id":268}]},"tmhm_learnset":"00603E0285D30230","types":[13,13]},{"abilities":[9,31],"address":3306208,"base_stats":[70,75,60,105,105,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":338,"learnset":{"address":3316304,"moves":[{"level":1,"move_id":86},{"level":1,"move_id":43},{"level":1,"move_id":336},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":31,"move_id":46},{"level":39,"move_id":44},{"level":45,"move_id":87},{"level":53,"move_id":268}]},"tmhm_learnset":"00603E0285D34230","types":[13,13]},{"abilities":[12,0],"address":3306236,"base_stats":[60,60,40,35,65,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":33,"species":340}],"friendship":70,"id":339,"learnset":{"address":3316334,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":35,"move_id":89},{"level":41,"move_id":53},{"level":49,"move_id":38}]},"tmhm_learnset":"00A21E748E110620","types":[10,4]},{"abilities":[40,0],"address":3306264,"base_stats":[70,100,70,40,105,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":340,"learnset":{"address":3316360,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":1,"move_id":52},{"level":1,"move_id":222},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":33,"move_id":157},{"level":37,"move_id":89},{"level":45,"move_id":284},{"level":55,"move_id":90}]},"tmhm_learnset":"00A21E748E114630","types":[10,4]},{"abilities":[47,0],"address":3306292,"base_stats":[70,40,50,25,55,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":342}],"friendship":70,"id":341,"learnset":{"address":3316388,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":59},{"level":49,"move_id":329}]},"tmhm_learnset":"03B01E4086533264","types":[15,11]},{"abilities":[47,0],"address":3306320,"base_stats":[90,60,70,45,75,70],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":44,"species":343}],"friendship":70,"id":342,"learnset":{"address":3316416,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":47,"move_id":59},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E4086533274","types":[15,11]},{"abilities":[47,0],"address":3306348,"base_stats":[110,80,90,65,95,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":343,"learnset":{"address":3316444,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":50,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"03B01E4086537274","types":[15,11]},{"abilities":[8,0],"address":3306376,"base_stats":[50,85,40,35,85,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":32,"species":345}],"friendship":35,"id":344,"learnset":{"address":3316472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":33,"move_id":191},{"level":37,"move_id":302},{"level":41,"move_id":178},{"level":45,"move_id":201}]},"tmhm_learnset":"00441E1084350721","types":[12,12]},{"abilities":[8,0],"address":3306404,"base_stats":[70,115,60,55,115,60],"catch_rate":60,"evolutions":[],"friendship":35,"id":345,"learnset":{"address":3316504,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":74},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":35,"move_id":191},{"level":41,"move_id":302},{"level":47,"move_id":178},{"level":53,"move_id":201}]},"tmhm_learnset":"00641E1084354721","types":[12,17]},{"abilities":[39,0],"address":3306432,"base_stats":[50,50,50,50,50,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":42,"species":347}],"friendship":70,"id":346,"learnset":{"address":3316536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":37,"move_id":258},{"level":43,"move_id":59}]},"tmhm_learnset":"00401E00A41BB264","types":[15,15]},{"abilities":[39,0],"address":3306460,"base_stats":[80,80,80,80,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":347,"learnset":{"address":3316564,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":1,"move_id":104},{"level":1,"move_id":44},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":42,"move_id":258},{"level":53,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"00401F00A61BFA64","types":[15,15]},{"abilities":[26,0],"address":3306488,"base_stats":[70,55,65,70,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":348,"learnset":{"address":3316594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":95},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":94},{"level":43,"move_id":248},{"level":49,"move_id":153}]},"tmhm_learnset":"00408E51B61BD228","types":[5,14]},{"abilities":[26,0],"address":3306516,"base_stats":[70,95,85,70,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":349,"learnset":{"address":3316620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":83},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":157},{"level":43,"move_id":76},{"level":49,"move_id":153}]},"tmhm_learnset":"00428E75B639C628","types":[5,14]},{"abilities":[47,37],"address":3306544,"base_stats":[50,20,40,20,20,40],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":183}],"friendship":70,"id":350,"learnset":{"address":3316646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":150},{"level":3,"move_id":204},{"level":6,"move_id":39},{"level":10,"move_id":145},{"level":15,"move_id":21},{"level":21,"move_id":55}]},"tmhm_learnset":"01101E0084533264","types":[0,0]},{"abilities":[47,20],"address":3306572,"base_stats":[60,25,35,60,70,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":352}],"friendship":70,"id":351,"learnset":{"address":3316666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":1,"move_id":150},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":34,"move_id":94},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":340}]},"tmhm_learnset":"0041BF03B4538E28","types":[14,14]},{"abilities":[47,20],"address":3306600,"base_stats":[80,45,65,80,90,110],"catch_rate":60,"evolutions":[],"friendship":70,"id":352,"learnset":{"address":3316696,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":149},{"level":1,"move_id":316},{"level":1,"move_id":60},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":37,"move_id":94},{"level":43,"move_id":156},{"level":43,"move_id":173},{"level":55,"move_id":340}]},"tmhm_learnset":"0041BF03B453CE29","types":[14,14]},{"abilities":[57,0],"address":3306628,"base_stats":[60,50,40,95,85,75],"catch_rate":200,"evolutions":[],"friendship":70,"id":353,"learnset":{"address":3316726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":313},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[58,0],"address":3306656,"base_stats":[60,40,50,95,75,85],"catch_rate":200,"evolutions":[],"friendship":70,"id":354,"learnset":{"address":3316756,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":204},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[52,22],"address":3306684,"base_stats":[50,85,85,50,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":355,"learnset":{"address":3316786,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":6,"move_id":313},{"level":11,"move_id":44},{"level":16,"move_id":230},{"level":21,"move_id":11},{"level":26,"move_id":185},{"level":31,"move_id":226},{"level":36,"move_id":242},{"level":41,"move_id":334},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255}]},"tmhm_learnset":"00A01F7CC4335E21","types":[8,8]},{"abilities":[74,0],"address":3306712,"base_stats":[30,40,55,60,40,55],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":37,"species":357}],"friendship":70,"id":356,"learnset":{"address":3316818,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":38,"move_id":244},{"level":42,"move_id":179},{"level":48,"move_id":105}]},"tmhm_learnset":"00E01E41F41386A9","types":[1,14]},{"abilities":[74,0],"address":3306740,"base_stats":[60,60,75,80,60,75],"catch_rate":90,"evolutions":[],"friendship":70,"id":357,"learnset":{"address":3316848,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":9},{"level":1,"move_id":8},{"level":1,"move_id":117},{"level":1,"move_id":96},{"level":1,"move_id":93},{"level":1,"move_id":197},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":40,"move_id":244},{"level":46,"move_id":179},{"level":54,"move_id":105}]},"tmhm_learnset":"00E01E41F413C6A9","types":[1,14]},{"abilities":[30,0],"address":3306768,"base_stats":[45,40,60,50,40,75],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":359}],"friendship":70,"id":358,"learnset":{"address":3316884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":38,"move_id":119},{"level":41,"move_id":287},{"level":48,"move_id":195}]},"tmhm_learnset":"00087E80843B1620","types":[0,2]},{"abilities":[30,0],"address":3306796,"base_stats":[75,70,90,80,70,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":359,"learnset":{"address":3316912,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":310},{"level":1,"move_id":47},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":35,"move_id":225},{"level":40,"move_id":349},{"level":45,"move_id":287},{"level":54,"move_id":195},{"level":59,"move_id":143}]},"tmhm_learnset":"00887EA4867B5632","types":[16,2]},{"abilities":[23,0],"address":3306824,"base_stats":[95,23,48,23,23,48],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":15,"species":202}],"friendship":70,"id":360,"learnset":{"address":3316944,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":150},{"level":1,"move_id":204},{"level":1,"move_id":227},{"level":15,"move_id":68},{"level":15,"move_id":243},{"level":15,"move_id":219},{"level":15,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[26,0],"address":3306852,"base_stats":[20,40,90,25,30,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":362}],"friendship":35,"id":361,"learnset":{"address":3316962,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":38,"move_id":261},{"level":45,"move_id":212},{"level":49,"move_id":248}]},"tmhm_learnset":"0041BF00B4133E28","types":[7,7]},{"abilities":[46,0],"address":3306880,"base_stats":[40,70,130,25,60,130],"catch_rate":90,"evolutions":[],"friendship":35,"id":362,"learnset":{"address":3316990,"moves":[{"level":1,"move_id":20},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":1,"move_id":50},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":37,"move_id":325},{"level":41,"move_id":261},{"level":51,"move_id":212},{"level":58,"move_id":248}]},"tmhm_learnset":"00E1BF40B6137E29","types":[7,7]},{"abilities":[30,38],"address":3306908,"base_stats":[50,60,45,65,100,80],"catch_rate":150,"evolutions":[],"friendship":70,"id":363,"learnset":{"address":3317020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":5,"move_id":74},{"level":9,"move_id":40},{"level":13,"move_id":78},{"level":17,"move_id":72},{"level":21,"move_id":73},{"level":25,"move_id":345},{"level":29,"move_id":320},{"level":33,"move_id":202},{"level":37,"move_id":230},{"level":41,"move_id":275},{"level":45,"move_id":92},{"level":49,"move_id":80},{"level":53,"move_id":312},{"level":57,"move_id":235}]},"tmhm_learnset":"00441E08A4350720","types":[12,3]},{"abilities":[54,0],"address":3306936,"base_stats":[60,60,60,30,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":365}],"friendship":70,"id":364,"learnset":{"address":3317058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E5B336A5","types":[0,0]},{"abilities":[72,0],"address":3306964,"base_stats":[80,80,80,90,55,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":366}],"friendship":70,"id":365,"learnset":{"address":3317082,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":116},{"level":1,"move_id":227},{"level":1,"move_id":253},{"level":7,"move_id":227},{"level":13,"move_id":253},{"level":19,"move_id":154},{"level":25,"move_id":203},{"level":31,"move_id":163},{"level":37,"move_id":68},{"level":43,"move_id":264},{"level":49,"move_id":179}]},"tmhm_learnset":"00A41EA6E7B33EB5","types":[0,0]},{"abilities":[54,0],"address":3306992,"base_stats":[150,160,100,100,95,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":366,"learnset":{"address":3317108,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":1,"move_id":227},{"level":1,"move_id":303},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":36,"move_id":207},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E7B37EB5","types":[0,0]},{"abilities":[64,60],"address":3307020,"base_stats":[70,43,53,40,43,53],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":26,"species":368}],"friendship":70,"id":367,"learnset":{"address":3317134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":28,"move_id":92},{"level":34,"move_id":254},{"level":34,"move_id":255},{"level":34,"move_id":256},{"level":39,"move_id":188}]},"tmhm_learnset":"00A11E0AA4371724","types":[3,3]},{"abilities":[64,60],"address":3307048,"base_stats":[100,73,83,55,73,83],"catch_rate":75,"evolutions":[],"friendship":70,"id":368,"learnset":{"address":3317164,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":281},{"level":1,"move_id":139},{"level":1,"move_id":124},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":26,"move_id":34},{"level":31,"move_id":92},{"level":40,"move_id":254},{"level":40,"move_id":255},{"level":40,"move_id":256},{"level":48,"move_id":188}]},"tmhm_learnset":"00A11E0AA4375724","types":[3,3]},{"abilities":[34,0],"address":3307076,"base_stats":[99,68,83,51,72,87],"catch_rate":200,"evolutions":[],"friendship":70,"id":369,"learnset":{"address":3317196,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":16},{"level":7,"move_id":74},{"level":11,"move_id":75},{"level":17,"move_id":23},{"level":21,"move_id":230},{"level":27,"move_id":18},{"level":31,"move_id":345},{"level":37,"move_id":34},{"level":41,"move_id":76},{"level":47,"move_id":235}]},"tmhm_learnset":"00EC5E80863D4730","types":[12,2]},{"abilities":[43,0],"address":3307104,"base_stats":[64,51,23,28,51,23],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":20,"species":371}],"friendship":70,"id":370,"learnset":{"address":3317224,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":21,"move_id":48},{"level":25,"move_id":23},{"level":31,"move_id":103},{"level":35,"move_id":46},{"level":41,"move_id":156},{"level":41,"move_id":214},{"level":45,"move_id":304}]},"tmhm_learnset":"00001E26A4333634","types":[0,0]},{"abilities":[43,0],"address":3307132,"base_stats":[84,71,43,48,71,43],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":40,"species":372}],"friendship":70,"id":371,"learnset":{"address":3317254,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":43,"move_id":46},{"level":51,"move_id":156},{"level":51,"move_id":214},{"level":57,"move_id":304}]},"tmhm_learnset":"00A21F26E6333E34","types":[0,0]},{"abilities":[43,0],"address":3307160,"base_stats":[104,91,63,68,91,63],"catch_rate":45,"evolutions":[],"friendship":70,"id":372,"learnset":{"address":3317284,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":40,"move_id":63},{"level":45,"move_id":46},{"level":55,"move_id":156},{"level":55,"move_id":214},{"level":63,"move_id":304}]},"tmhm_learnset":"00A21F26E6337E34","types":[0,0]},{"abilities":[75,0],"address":3307188,"base_stats":[35,64,85,32,74,55],"catch_rate":255,"evolutions":[{"method":"ITEM","param":192,"species":374},{"method":"ITEM","param":193,"species":375}],"friendship":70,"id":373,"learnset":{"address":3317316,"moves":[{"level":1,"move_id":128},{"level":1,"move_id":55},{"level":1,"move_id":250},{"level":1,"move_id":334}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,0],"address":3307216,"base_stats":[55,104,105,52,94,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":374,"learnset":{"address":3317326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":44},{"level":15,"move_id":103},{"level":22,"move_id":352},{"level":29,"move_id":184},{"level":36,"move_id":242},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03111E4084137264","types":[11,11]},{"abilities":[33,0],"address":3307244,"base_stats":[55,84,105,52,114,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":375,"learnset":{"address":3317350,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":93},{"level":15,"move_id":97},{"level":22,"move_id":352},{"level":29,"move_id":133},{"level":36,"move_id":94},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03101E00B41B7264","types":[11,11]},{"abilities":[46,0],"address":3307272,"base_stats":[65,130,60,75,75,60],"catch_rate":30,"evolutions":[],"friendship":35,"id":376,"learnset":{"address":3317374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":5,"move_id":43},{"level":9,"move_id":269},{"level":13,"move_id":98},{"level":17,"move_id":13},{"level":21,"move_id":44},{"level":26,"move_id":14},{"level":31,"move_id":104},{"level":36,"move_id":163},{"level":41,"move_id":248},{"level":46,"move_id":195}]},"tmhm_learnset":"00E53FB6A5D37E6C","types":[17,17]},{"abilities":[15,0],"address":3307300,"base_stats":[44,75,35,45,63,33],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":37,"species":378}],"friendship":35,"id":377,"learnset":{"address":3317404,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":282},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":37,"move_id":185},{"level":44,"move_id":247},{"level":49,"move_id":289},{"level":56,"move_id":288}]},"tmhm_learnset":"0041BF02B5930E28","types":[7,7]},{"abilities":[15,0],"address":3307328,"base_stats":[64,115,65,65,83,63],"catch_rate":45,"evolutions":[],"friendship":35,"id":378,"learnset":{"address":3317432,"moves":[{"level":1,"move_id":282},{"level":1,"move_id":103},{"level":1,"move_id":101},{"level":1,"move_id":174},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":39,"move_id":185},{"level":48,"move_id":247},{"level":55,"move_id":289},{"level":64,"move_id":288}]},"tmhm_learnset":"0041BF02B5934E28","types":[7,7]},{"abilities":[61,0],"address":3307356,"base_stats":[73,100,60,65,100,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":379,"learnset":{"address":3317460,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":7,"move_id":122},{"level":10,"move_id":44},{"level":16,"move_id":342},{"level":19,"move_id":103},{"level":25,"move_id":137},{"level":28,"move_id":242},{"level":34,"move_id":305},{"level":37,"move_id":207},{"level":43,"move_id":114}]},"tmhm_learnset":"00A13E0C8E570E20","types":[3,3]},{"abilities":[17,0],"address":3307384,"base_stats":[73,115,60,90,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":380,"learnset":{"address":3317488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":43},{"level":7,"move_id":98},{"level":10,"move_id":14},{"level":13,"move_id":210},{"level":19,"move_id":163},{"level":25,"move_id":228},{"level":31,"move_id":306},{"level":37,"move_id":269},{"level":46,"move_id":197},{"level":55,"move_id":206}]},"tmhm_learnset":"00A03EA6EDF73E35","types":[0,0]},{"abilities":[33,69],"address":3307412,"base_stats":[100,90,130,55,45,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":381,"learnset":{"address":3317518,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":8,"move_id":55},{"level":15,"move_id":317},{"level":22,"move_id":281},{"level":29,"move_id":36},{"level":36,"move_id":300},{"level":43,"move_id":246},{"level":50,"move_id":156},{"level":57,"move_id":38},{"level":64,"move_id":56}]},"tmhm_learnset":"03901E50861B726C","types":[11,5]},{"abilities":[5,69],"address":3307440,"base_stats":[50,70,100,30,40,40],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":32,"species":383}],"friendship":35,"id":382,"learnset":{"address":3317546,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":34,"move_id":182},{"level":39,"move_id":319},{"level":44,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307468,"base_stats":[60,90,140,40,50,50],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":42,"species":384}],"friendship":35,"id":383,"learnset":{"address":3317578,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":45,"move_id":319},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307496,"base_stats":[70,110,180,50,60,60],"catch_rate":45,"evolutions":[],"friendship":35,"id":384,"learnset":{"address":3317610,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":50,"move_id":319},{"level":63,"move_id":38}]},"tmhm_learnset":"00B41EF6CFF37E37","types":[8,5]},{"abilities":[59,0],"address":3307524,"base_stats":[70,70,70,70,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":385,"learnset":{"address":3317642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":10,"move_id":55},{"level":10,"move_id":52},{"level":10,"move_id":181},{"level":20,"move_id":240},{"level":20,"move_id":241},{"level":20,"move_id":258},{"level":30,"move_id":311}]},"tmhm_learnset":"00403E36A5B33664","types":[0,0]},{"abilities":[35,68],"address":3307552,"base_stats":[65,73,55,85,47,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":386,"learnset":{"address":3317666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":109},{"level":9,"move_id":104},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":294},{"level":25,"move_id":324},{"level":29,"move_id":182},{"level":33,"move_id":270},{"level":37,"move_id":38}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[12,0],"address":3307580,"base_stats":[65,47,55,85,73,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":387,"learnset":{"address":3317694,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":230},{"level":9,"move_id":204},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":273},{"level":25,"move_id":227},{"level":29,"move_id":260},{"level":33,"move_id":270},{"level":37,"move_id":343}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[21,0],"address":3307608,"base_stats":[66,41,77,23,61,87],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":389}],"friendship":70,"id":388,"learnset":{"address":3317722,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":43,"move_id":246},{"level":50,"move_id":254},{"level":50,"move_id":255},{"level":50,"move_id":256}]},"tmhm_learnset":"00001E1884350720","types":[5,12]},{"abilities":[21,0],"address":3307636,"base_stats":[86,81,97,43,81,107],"catch_rate":45,"evolutions":[],"friendship":70,"id":389,"learnset":{"address":3317750,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":132},{"level":1,"move_id":51},{"level":1,"move_id":275},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":48,"move_id":246},{"level":60,"move_id":254},{"level":60,"move_id":255},{"level":60,"move_id":256}]},"tmhm_learnset":"00A01E5886354720","types":[5,12]},{"abilities":[4,0],"address":3307664,"base_stats":[45,95,50,75,40,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":391}],"friendship":70,"id":390,"learnset":{"address":3317778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":43,"move_id":210},{"level":49,"move_id":163},{"level":55,"move_id":350}]},"tmhm_learnset":"00841ED0CC110624","types":[5,6]},{"abilities":[4,0],"address":3307692,"base_stats":[75,125,100,45,70,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":391,"learnset":{"address":3317806,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":300},{"level":1,"move_id":55},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":46,"move_id":210},{"level":55,"move_id":163},{"level":64,"move_id":350}]},"tmhm_learnset":"00A41ED0CE514624","types":[5,6]},{"abilities":[28,36],"address":3307720,"base_stats":[28,25,25,40,45,35],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":20,"species":393}],"friendship":35,"id":392,"learnset":{"address":3317834,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":45},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":31,"move_id":286},{"level":36,"move_id":248},{"level":41,"move_id":95},{"level":46,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307748,"base_stats":[38,35,35,50,65,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":394}],"friendship":35,"id":393,"learnset":{"address":3317862,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":40,"move_id":248},{"level":47,"move_id":95},{"level":54,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307776,"base_stats":[68,65,65,80,125,115],"catch_rate":45,"evolutions":[],"friendship":35,"id":394,"learnset":{"address":3317890,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":42,"move_id":248},{"level":51,"move_id":95},{"level":60,"move_id":138}]},"tmhm_learnset":"0041BF03B49BCE28","types":[14,14]},{"abilities":[69,0],"address":3307804,"base_stats":[45,75,60,50,40,30],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":396}],"friendship":35,"id":395,"learnset":{"address":3317918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":33,"move_id":225},{"level":37,"move_id":184},{"level":41,"move_id":242},{"level":49,"move_id":337},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[69,0],"address":3307832,"base_stats":[65,95,100,50,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":50,"species":397}],"friendship":35,"id":396,"learnset":{"address":3317948,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":56,"move_id":242},{"level":69,"move_id":337},{"level":78,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[22,0],"address":3307860,"base_stats":[95,135,80,100,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":397,"learnset":{"address":3317980,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":50,"move_id":19},{"level":61,"move_id":242},{"level":79,"move_id":337},{"level":93,"move_id":38}]},"tmhm_learnset":"00AC5EE4C6534632","types":[16,2]},{"abilities":[29,0],"address":3307888,"base_stats":[40,55,80,30,35,60],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":20,"species":399}],"friendship":35,"id":398,"learnset":{"address":3318014,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36}]},"tmhm_learnset":"0000000000000000","types":[8,14]},{"abilities":[29,0],"address":3307916,"base_stats":[60,75,100,50,55,80],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":45,"species":400}],"friendship":35,"id":399,"learnset":{"address":3318024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":50,"move_id":309},{"level":56,"move_id":97},{"level":62,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307944,"base_stats":[80,135,130,70,95,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":400,"learnset":{"address":3318052,"moves":[{"level":1,"move_id":36},{"level":1,"move_id":93},{"level":1,"move_id":232},{"level":1,"move_id":184},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":55,"move_id":309},{"level":66,"move_id":97},{"level":77,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307972,"base_stats":[80,100,200,50,50,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":401,"learnset":{"address":3318080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":153},{"level":9,"move_id":88},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E52CF994621","types":[5,5]},{"abilities":[29,0],"address":3308000,"base_stats":[80,50,100,50,100,200],"catch_rate":3,"evolutions":[],"friendship":35,"id":402,"learnset":{"address":3318106,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":196},{"level":1,"move_id":153},{"level":9,"move_id":196},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E02C79B7261","types":[15,15]},{"abilities":[29,0],"address":3308028,"base_stats":[80,75,150,50,75,150],"catch_rate":3,"evolutions":[],"friendship":35,"id":403,"learnset":{"address":3318132,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":232},{"level":1,"move_id":153},{"level":9,"move_id":232},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00ED2C79B4621","types":[8,8]},{"abilities":[2,0],"address":3308056,"base_stats":[100,100,90,90,150,140],"catch_rate":5,"evolutions":[],"friendship":0,"id":404,"learnset":{"address":3318160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":352},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":34},{"level":30,"move_id":347},{"level":35,"move_id":58},{"level":45,"move_id":56},{"level":50,"move_id":156},{"level":60,"move_id":329},{"level":65,"move_id":38},{"level":75,"move_id":323}]},"tmhm_learnset":"03B00E42C79B727C","types":[11,11]},{"abilities":[70,0],"address":3308084,"base_stats":[100,150,140,90,100,90],"catch_rate":5,"evolutions":[],"friendship":0,"id":405,"learnset":{"address":3318190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":341},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":163},{"level":30,"move_id":339},{"level":35,"move_id":89},{"level":45,"move_id":126},{"level":50,"move_id":156},{"level":60,"move_id":90},{"level":65,"move_id":76},{"level":75,"move_id":284}]},"tmhm_learnset":"00A60EF6CFF946B2","types":[4,4]},{"abilities":[77,0],"address":3308112,"base_stats":[105,150,90,95,150,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":406,"learnset":{"address":3318220,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":239},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":337},{"level":30,"move_id":349},{"level":35,"move_id":242},{"level":45,"move_id":19},{"level":50,"move_id":156},{"level":60,"move_id":245},{"level":65,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BA0EB6C7F376B6","types":[16,2]},{"abilities":[26,0],"address":3308140,"base_stats":[80,80,90,110,110,130],"catch_rate":3,"evolutions":[],"friendship":90,"id":407,"learnset":{"address":3318250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":273},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":346},{"level":30,"move_id":287},{"level":35,"move_id":296},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":204}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[26,0],"address":3308168,"base_stats":[80,90,80,110,130,110],"catch_rate":3,"evolutions":[],"friendship":90,"id":408,"learnset":{"address":3318280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":262},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":182},{"level":30,"move_id":287},{"level":35,"move_id":295},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":349}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[32,0],"address":3308196,"base_stats":[100,100,100,100,100,100],"catch_rate":3,"evolutions":[],"friendship":100,"id":409,"learnset":{"address":3318310,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":273},{"level":1,"move_id":93},{"level":5,"move_id":156},{"level":10,"move_id":129},{"level":15,"move_id":270},{"level":20,"move_id":94},{"level":25,"move_id":287},{"level":30,"move_id":156},{"level":35,"move_id":38},{"level":40,"move_id":248},{"level":45,"move_id":322},{"level":50,"move_id":353}]},"tmhm_learnset":"00408E93B59BC62C","types":[8,14]},{"abilities":[46,0],"address":3308224,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":410,"learnset":{"address":3318340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":35},{"level":5,"move_id":101},{"level":10,"move_id":104},{"level":15,"move_id":282},{"level":20,"move_id":228},{"level":25,"move_id":94},{"level":30,"move_id":129},{"level":35,"move_id":97},{"level":40,"move_id":105},{"level":45,"move_id":354},{"level":50,"move_id":245}]},"tmhm_learnset":"00E58FC3F5BBDE2D","types":[14,14]},{"abilities":[26,0],"address":3308252,"base_stats":[65,50,70,65,95,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":411,"learnset":{"address":3318370,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":6,"move_id":45},{"level":9,"move_id":310},{"level":14,"move_id":93},{"level":17,"move_id":36},{"level":22,"move_id":253},{"level":25,"move_id":281},{"level":30,"move_id":149},{"level":33,"move_id":38},{"level":38,"move_id":215},{"level":41,"move_id":219},{"level":46,"move_id":94}]},"tmhm_learnset":"00419F03B41B8E28","types":[14,14]}],"tmhm_moves":[264,337,352,347,46,92,258,339,331,237,241,269,58,59,63,113,182,240,202,219,218,76,231,85,87,89,216,91,94,247,280,104,115,351,53,188,201,126,317,332,259,263,290,156,213,168,211,285,289,315,15,19,57,70,148,249,127,291],"trainers":[{"address":3230072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[],"party_address":4160749568,"script_address":0},{"address":3230112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":74}],"party_address":3211124,"script_address":2304511},{"address":3230152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":286}],"party_address":3211132,"script_address":2321901},{"address":3230192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":330}],"party_address":3211140,"script_address":2323326},{"address":3230232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211156,"script_address":2323373},{"address":3230272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211164,"script_address":2324386},{"address":3230312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":286}],"party_address":3211172,"script_address":2326808},{"address":3230352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211180,"script_address":2326839},{"address":3230392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":41}],"party_address":3211188,"script_address":2328040},{"address":3230432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":315},{"level":26,"species":286},{"level":26,"species":288},{"level":26,"species":295},{"level":26,"species":298},{"level":26,"species":304}],"party_address":3211196,"script_address":2314251},{"address":3230472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":286}],"party_address":3211244,"script_address":0},{"address":3230512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":300}],"party_address":3211252,"script_address":2067580},{"address":3230552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":310},{"level":30,"species":178}],"party_address":3211268,"script_address":2068523},{"address":3230592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":380},{"level":30,"species":379}],"party_address":3211284,"script_address":2068554},{"address":3230632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211300,"script_address":2328071},{"address":3230672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3211308,"script_address":2069620},{"address":3230712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":286}],"party_address":3211316,"script_address":0},{"address":3230752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3211324,"script_address":2570959},{"address":3230792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":286},{"level":27,"species":330}],"party_address":3211340,"script_address":2572093},{"address":3230832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":286},{"level":26,"species":41},{"level":26,"species":330}],"party_address":3211356,"script_address":2572124},{"address":3230872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":330}],"party_address":3211380,"script_address":2157889},{"address":3230912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":41},{"level":14,"species":330}],"party_address":3211388,"script_address":2157948},{"address":3230952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":339}],"party_address":3211404,"script_address":2254636},{"address":3230992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211412,"script_address":2317522},{"address":3231032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211420,"script_address":2317553},{"address":3231072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":286},{"level":30,"species":330}],"party_address":3211428,"script_address":2317584},{"address":3231112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330}],"party_address":3211444,"script_address":2570990},{"address":3231152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211452,"script_address":2323414},{"address":3231192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211460,"script_address":2324427},{"address":3231232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":335},{"level":30,"species":67}],"party_address":3211468,"script_address":2068492},{"address":3231272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":287},{"level":34,"species":42}],"party_address":3211484,"script_address":2324250},{"address":3231312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":336}],"party_address":3211500,"script_address":2312702},{"address":3231352,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330},{"level":28,"species":287}],"party_address":3211508,"script_address":2572155},{"address":3231392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":331},{"level":37,"species":287}],"party_address":3211524,"script_address":2327156},{"address":3231432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":287},{"level":41,"species":169},{"level":43,"species":331}],"party_address":3211540,"script_address":2328478},{"address":3231472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":351}],"party_address":3211564,"script_address":2312671},{"address":3231512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211572,"script_address":2026085},{"address":3231552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":363},{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211588,"script_address":2058784},{"address":3231592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,0,0,0],"species":357},{"level":43,"moves":[29,89,0,0],"species":319}],"party_address":3211612,"script_address":2335547},{"address":3231632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":363},{"level":26,"species":44}],"party_address":3211644,"script_address":2068148},{"address":3231672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":363}],"party_address":3211660,"script_address":0},{"address":3231712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":306},{"level":28,"species":44},{"level":28,"species":363}],"party_address":3211676,"script_address":0},{"address":3231752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":306},{"level":31,"species":44},{"level":31,"species":363}],"party_address":3211700,"script_address":0},{"address":3231792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307},{"level":34,"species":44},{"level":34,"species":363}],"party_address":3211724,"script_address":0},{"address":3231832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,163,28,40],"species":28}],"party_address":3211748,"script_address":2046490},{"address":3231872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[60,120,201,246],"species":318},{"level":27,"moves":[91,163,28,40],"species":27},{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211764,"script_address":2065682},{"address":3231912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[91,163,28,40],"species":27},{"level":25,"moves":[91,163,28,40],"species":28}],"party_address":3211812,"script_address":2033540},{"address":3231952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211844,"script_address":0},{"address":3231992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[91,163,28,40],"species":28}],"party_address":3211860,"script_address":0},{"address":3232032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[91,163,28,40],"species":28}],"party_address":3211876,"script_address":0},{"address":3232072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[91,163,28,40],"species":28}],"party_address":3211892,"script_address":0},{"address":3232112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":81},{"level":17,"species":370}],"party_address":3211908,"script_address":0},{"address":3232152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":81},{"level":27,"species":371}],"party_address":3211924,"script_address":0},{"address":3232192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":82},{"level":30,"species":371}],"party_address":3211940,"script_address":0},{"address":3232232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":82},{"level":33,"species":371}],"party_address":3211956,"script_address":0},{"address":3232272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82},{"level":36,"species":371}],"party_address":3211972,"script_address":0},{"address":3232312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[49,86,63,85],"species":82},{"level":39,"moves":[54,23,48,48],"species":372}],"party_address":3211988,"script_address":0},{"address":3232352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":350}],"party_address":3212020,"script_address":2036011},{"address":3232392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212036,"script_address":2036121},{"address":3232432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212044,"script_address":2036152},{"address":3232472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183},{"level":26,"species":183}],"party_address":3212052,"script_address":0},{"address":3232512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":183},{"level":29,"species":183}],"party_address":3212068,"script_address":0},{"address":3232552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":183},{"level":32,"species":183}],"party_address":3212084,"script_address":0},{"address":3232592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":35,"species":184}],"party_address":3212100,"script_address":0},{"address":3232632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":13,"moves":[28,29,39,57],"species":288}],"party_address":3212116,"script_address":2035901},{"address":3232672,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":183}],"party_address":3212132,"script_address":2544001},{"address":3232712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212148,"script_address":2339831},{"address":3232752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[28,42,39,57],"species":289}],"party_address":3212156,"script_address":0},{"address":3232792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[28,42,39,57],"species":289}],"party_address":3212172,"script_address":0},{"address":3232832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[28,42,39,57],"species":289}],"party_address":3212188,"script_address":0},{"address":3232872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[28,42,39,57],"species":289}],"party_address":3212204,"script_address":0},{"address":3232912,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[98,97,17,0],"species":305}],"party_address":3212220,"script_address":2131164},{"address":3232952,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[42,146,8,0],"species":308}],"party_address":3212236,"script_address":2131228},{"address":3232992,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[47,68,247,0],"species":364}],"party_address":3212252,"script_address":2131292},{"address":3233032,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[116,163,0,0],"species":365}],"party_address":3212268,"script_address":2131356},{"address":3233072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[116,98,17,27],"species":305},{"level":28,"moves":[44,91,185,72],"species":332},{"level":28,"moves":[205,250,54,96],"species":313},{"level":28,"moves":[85,48,86,49],"species":82},{"level":28,"moves":[202,185,104,207],"species":300}],"party_address":3212284,"script_address":2068117},{"address":3233112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":322},{"level":44,"species":357},{"level":44,"species":331}],"party_address":3212364,"script_address":2565920},{"address":3233152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":355},{"level":46,"species":121}],"party_address":3212388,"script_address":2565982},{"address":3233192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":337},{"level":17,"species":313},{"level":17,"species":335}],"party_address":3212404,"script_address":2046693},{"address":3233232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":345},{"level":43,"species":310}],"party_address":3212428,"script_address":2332685},{"address":3233272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":82},{"level":43,"species":89}],"party_address":3212444,"script_address":2332716},{"address":3233312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":305},{"level":42,"species":355},{"level":42,"species":64}],"party_address":3212460,"script_address":2334375},{"address":3233352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":85},{"level":42,"species":64},{"level":42,"species":101},{"level":42,"species":300}],"party_address":3212484,"script_address":2335423},{"address":3233392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":317},{"level":42,"species":75},{"level":42,"species":314}],"party_address":3212516,"script_address":2335454},{"address":3233432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":337},{"level":26,"species":313},{"level":26,"species":335}],"party_address":3212540,"script_address":0},{"address":3233472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":313},{"level":29,"species":335}],"party_address":3212564,"script_address":0},{"address":3233512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":338},{"level":32,"species":313},{"level":32,"species":335}],"party_address":3212588,"script_address":0},{"address":3233552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":338},{"level":35,"species":313},{"level":35,"species":336}],"party_address":3212612,"script_address":0},{"address":3233592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":297}],"party_address":3212636,"script_address":2073950},{"address":3233632,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[185,95,0,0],"species":316}],"party_address":3212652,"script_address":2131420},{"address":3233672,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[111,38,247,0],"species":40}],"party_address":3212668,"script_address":2131484},{"address":3233712,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[14,163,0,0],"species":380}],"party_address":3212684,"script_address":2131548},{"address":3233752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[226,185,57,44],"species":355},{"level":29,"moves":[72,89,64,73],"species":363},{"level":29,"moves":[19,55,54,182],"species":310}],"party_address":3212700,"script_address":2068086},{"address":3233792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":383},{"level":45,"species":338}],"party_address":3212748,"script_address":2565951},{"address":3233832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":309},{"level":17,"species":339},{"level":17,"species":363}],"party_address":3212764,"script_address":2046803},{"address":3233872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":322}],"party_address":3212788,"script_address":2065651},{"address":3233912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3212796,"script_address":2332747},{"address":3233952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":319}],"party_address":3212804,"script_address":2334406},{"address":3233992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":321},{"level":42,"species":357},{"level":42,"species":297}],"party_address":3212812,"script_address":2334437},{"address":3234032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":227},{"level":43,"species":322}],"party_address":3212836,"script_address":2335485},{"address":3234072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":28},{"level":42,"species":38},{"level":42,"species":369}],"party_address":3212852,"script_address":2335516},{"address":3234112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":26,"species":339},{"level":26,"species":363}],"party_address":3212876,"script_address":0},{"address":3234152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":339},{"level":29,"species":363}],"party_address":3212900,"script_address":0},{"address":3234192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":339},{"level":32,"species":363}],"party_address":3212924,"script_address":0},{"address":3234232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":340},{"level":34,"species":363}],"party_address":3212948,"script_address":0},{"address":3234272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":348}],"party_address":3212972,"script_address":2564729},{"address":3234312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":361},{"level":30,"species":377}],"party_address":3212988,"script_address":2068461},{"address":3234352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":361},{"level":29,"species":377}],"party_address":3213004,"script_address":2067284},{"address":3234392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":322}],"party_address":3213020,"script_address":2315745},{"address":3234432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":377}],"party_address":3213028,"script_address":2315532},{"address":3234472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":322},{"level":31,"species":351}],"party_address":3213036,"script_address":0},{"address":3234512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":351},{"level":35,"species":322}],"party_address":3213052,"script_address":0},{"address":3234552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":351},{"level":40,"species":322}],"party_address":3213068,"script_address":0},{"address":3234592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":361},{"level":42,"species":322},{"level":42,"species":352}],"party_address":3213084,"script_address":0},{"address":3234632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213108,"script_address":2030087},{"address":3234672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[213,186,175,96],"species":325},{"level":39,"moves":[213,219,36,96],"species":325}],"party_address":3213116,"script_address":2265894},{"address":3234712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":287},{"level":28,"species":287},{"level":30,"species":339}],"party_address":3213148,"script_address":2254717},{"address":3234752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":11,"moves":[33,39,0,0],"species":288}],"party_address":3213172,"script_address":0},{"address":3234792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":40,"species":119}],"party_address":3213188,"script_address":2265677},{"address":3234832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3213196,"script_address":2361019},{"address":3234872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213204,"script_address":0},{"address":3234912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213212,"script_address":0},{"address":3234952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213220,"script_address":0},{"address":3234992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213228,"script_address":0},{"address":3235032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":183}],"party_address":3213244,"script_address":2304387},{"address":3235072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3213252,"script_address":2304418},{"address":3235112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":339}],"party_address":3213260,"script_address":2304449},{"address":3235152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[20,122,154,185],"species":317},{"level":29,"moves":[86,103,137,242],"species":379}],"party_address":3213268,"script_address":2067377},{"address":3235192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":118}],"party_address":3213300,"script_address":2265708},{"address":3235232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":184}],"party_address":3213308,"script_address":2265739},{"address":3235272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[78,250,240,96],"species":373},{"level":37,"moves":[13,152,96,0],"species":326},{"level":39,"moves":[253,154,252,96],"species":296}],"party_address":3213316,"script_address":2265770},{"address":3235312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":330},{"level":39,"species":331}],"party_address":3213364,"script_address":2265801},{"address":3235352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[20,122,154,185],"species":317},{"level":35,"moves":[86,103,137,242],"species":379}],"party_address":3213380,"script_address":0},{"address":3235392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[20,122,154,185],"species":317},{"level":38,"moves":[86,103,137,242],"species":379}],"party_address":3213412,"script_address":0},{"address":3235432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[20,122,154,185],"species":317},{"level":41,"moves":[86,103,137,242],"species":379}],"party_address":3213444,"script_address":0},{"address":3235472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[20,122,154,185],"species":317},{"level":44,"moves":[86,103,137,242],"species":379}],"party_address":3213476,"script_address":0},{"address":3235512,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213508,"script_address":2029901},{"address":3235552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":324},{"level":33,"species":356}],"party_address":3213516,"script_address":2074012},{"address":3235592,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":184}],"party_address":3213532,"script_address":2360988},{"address":3235632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213540,"script_address":0},{"address":3235672,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213548,"script_address":0},{"address":3235712,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213556,"script_address":0},{"address":3235752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213564,"script_address":0},{"address":3235792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3213580,"script_address":2051965},{"address":3235832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":116}],"party_address":3213588,"script_address":2340108},{"address":3235872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":111}],"party_address":3213604,"script_address":2312578},{"address":3235912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":339}],"party_address":3213612,"script_address":2304480},{"address":3235952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":383}],"party_address":3213620,"script_address":0},{"address":3235992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":383},{"level":29,"species":111}],"party_address":3213628,"script_address":0},{"address":3236032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":383},{"level":32,"species":111}],"party_address":3213644,"script_address":0},{"address":3236072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":384},{"level":35,"species":112}],"party_address":3213660,"script_address":0},{"address":3236112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213676,"script_address":2033571},{"address":3236152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":72}],"party_address":3213684,"script_address":2033602},{"address":3236192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":72}],"party_address":3213692,"script_address":2034185},{"address":3236232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":309},{"level":24,"species":72}],"party_address":3213708,"script_address":2034479},{"address":3236272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213732,"script_address":2034510},{"address":3236312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":73}],"party_address":3213740,"script_address":2034776},{"address":3236352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213748,"script_address":2034807},{"address":3236392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3213756,"script_address":2035777},{"address":3236432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309}],"party_address":3213772,"script_address":2069178},{"address":3236472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3213788,"script_address":2069209},{"address":3236512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":73}],"party_address":3213796,"script_address":2069789},{"address":3236552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":116}],"party_address":3213804,"script_address":2069820},{"address":3236592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213812,"script_address":2070163},{"address":3236632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":31,"species":309},{"level":31,"species":330}],"party_address":3213820,"script_address":2070194},{"address":3236672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213844,"script_address":2073229},{"address":3236712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310}],"party_address":3213852,"script_address":2073359},{"address":3236752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213860,"script_address":2073390},{"address":3236792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":73},{"level":33,"species":313}],"party_address":3213876,"script_address":2073291},{"address":3236832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3213892,"script_address":2073608},{"address":3236872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":342}],"party_address":3213900,"script_address":2073857},{"address":3236912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":341}],"party_address":3213908,"script_address":2073576},{"address":3236952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213916,"script_address":2074089},{"address":3236992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213924,"script_address":0},{"address":3237032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":313}],"party_address":3213948,"script_address":2069381},{"address":3237072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":331}],"party_address":3213964,"script_address":0},{"address":3237112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":331}],"party_address":3213972,"script_address":0},{"address":3237152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120},{"level":36,"species":331}],"party_address":3213980,"script_address":0},{"address":3237192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":121},{"level":39,"species":331}],"party_address":3213996,"script_address":0},{"address":3237232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3214012,"script_address":2095275},{"address":3237272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":66},{"level":32,"species":67}],"party_address":3214020,"script_address":2074213},{"address":3237312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":336}],"party_address":3214036,"script_address":2073701},{"address":3237352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":66},{"level":28,"species":67}],"party_address":3214044,"script_address":2052921},{"address":3237392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214060,"script_address":2052952},{"address":3237432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":67}],"party_address":3214068,"script_address":0},{"address":3237472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":66},{"level":29,"species":67}],"party_address":3214076,"script_address":0},{"address":3237512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":66},{"level":31,"species":67},{"level":31,"species":67}],"party_address":3214092,"script_address":0},{"address":3237552,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":66},{"level":33,"species":67},{"level":33,"species":67},{"level":33,"species":68}],"party_address":3214116,"script_address":0},{"address":3237592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":335},{"level":26,"species":67}],"party_address":3214148,"script_address":2557758},{"address":3237632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214164,"script_address":2046662},{"address":3237672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":336}],"party_address":3214172,"script_address":2315359},{"address":3237712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[98,86,209,43],"species":337},{"level":17,"moves":[12,95,103,0],"species":100}],"party_address":3214180,"script_address":2167608},{"address":3237752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":286},{"level":31,"species":41}],"party_address":3214212,"script_address":2323445},{"address":3237792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3214228,"script_address":2324458},{"address":3237832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":100},{"level":17,"species":81}],"party_address":3214236,"script_address":2167639},{"address":3237872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":337},{"level":30,"species":371}],"party_address":3214252,"script_address":2068709},{"address":3237912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81},{"level":15,"species":370}],"party_address":3214268,"script_address":2058956},{"address":3237952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":81},{"level":25,"species":370},{"level":25,"species":81}],"party_address":3214284,"script_address":0},{"address":3237992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81},{"level":28,"species":371},{"level":28,"species":81}],"party_address":3214308,"script_address":0},{"address":3238032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":82},{"level":31,"species":371},{"level":31,"species":82}],"party_address":3214332,"script_address":0},{"address":3238072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82},{"level":34,"species":372},{"level":34,"species":82}],"party_address":3214356,"script_address":0},{"address":3238112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214380,"script_address":2103394},{"address":3238152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":218},{"level":22,"species":218}],"party_address":3214388,"script_address":2103601},{"address":3238192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214404,"script_address":2103446},{"address":3238232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214412,"script_address":2103570},{"address":3238272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214420,"script_address":2103477},{"address":3238312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309}],"party_address":3214428,"script_address":2052075},{"address":3238352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":218},{"level":26,"species":309}],"party_address":3214444,"script_address":0},{"address":3238392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310}],"party_address":3214460,"script_address":0},{"address":3238432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":218},{"level":32,"species":310}],"party_address":3214476,"script_address":0},{"address":3238472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":219},{"level":35,"species":310}],"party_address":3214492,"script_address":0},{"address":3238512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,28,40,163],"species":27}],"party_address":3214508,"script_address":2046366},{"address":3238552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":21,"moves":[229,189,60,61],"species":318},{"level":21,"moves":[40,28,10,91],"species":27},{"level":21,"moves":[229,189,60,61],"species":318}],"party_address":3214524,"script_address":2046428},{"address":3238592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":299}],"party_address":3214572,"script_address":2049829},{"address":3238632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27},{"level":18,"species":299}],"party_address":3214580,"script_address":2051903},{"address":3238672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":317}],"party_address":3214596,"script_address":2557005},{"address":3238712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":288},{"level":20,"species":304}],"party_address":3214604,"script_address":2310199},{"address":3238752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3214620,"script_address":2310337},{"address":3238792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27}],"party_address":3214628,"script_address":2046600},{"address":3238832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":288},{"level":26,"species":304}],"party_address":3214636,"script_address":0},{"address":3238872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":289},{"level":29,"species":305}],"party_address":3214652,"script_address":0},{"address":3238912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":305},{"level":31,"species":289}],"party_address":3214668,"script_address":0},{"address":3238952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":28},{"level":34,"species":289}],"party_address":3214692,"script_address":0},{"address":3238992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":311}],"party_address":3214716,"script_address":2061044},{"address":3239032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":290},{"level":24,"species":291},{"level":24,"species":292}],"party_address":3214724,"script_address":2061075},{"address":3239072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":290},{"level":27,"species":293},{"level":27,"species":294}],"party_address":3214748,"script_address":2061106},{"address":3239112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":311},{"level":27,"species":311},{"level":27,"species":311}],"party_address":3214772,"script_address":2065541},{"address":3239152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":294},{"level":16,"species":292}],"party_address":3214796,"script_address":2057595},{"address":3239192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":311},{"level":31,"species":311}],"party_address":3214812,"script_address":0},{"address":3239232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":311},{"level":34,"species":311},{"level":34,"species":312}],"party_address":3214836,"script_address":0},{"address":3239272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":311},{"level":36,"species":290},{"level":36,"species":311},{"level":36,"species":312}],"party_address":3214860,"script_address":0},{"address":3239312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":311},{"level":38,"species":294},{"level":38,"species":311},{"level":38,"species":312},{"level":38,"species":292}],"party_address":3214892,"script_address":0},{"address":3239352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[237,0,0,0],"species":63}],"party_address":3214932,"script_address":2038374},{"address":3239392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3214948,"script_address":2244488},{"address":3239432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":392}],"party_address":3214956,"script_address":2244519},{"address":3239472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3214964,"script_address":2244550},{"address":3239512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":392},{"level":26,"species":393}],"party_address":3214972,"script_address":2314189},{"address":3239552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3214996,"script_address":2564698},{"address":3239592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":349}],"party_address":3215012,"script_address":2068179},{"address":3239632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":64},{"level":33,"species":349}],"party_address":3215020,"script_address":0},{"address":3239672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":64},{"level":38,"species":349}],"party_address":3215036,"script_address":0},{"address":3239712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3215052,"script_address":0},{"address":3239752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":349},{"level":45,"species":65}],"party_address":3215068,"script_address":0},{"address":3239792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[237,0,0,0],"species":63}],"party_address":3215084,"script_address":2038405},{"address":3239832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3215100,"script_address":2244581},{"address":3239872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":178}],"party_address":3215108,"script_address":2244612},{"address":3239912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3215116,"script_address":2244643},{"address":3239952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":202},{"level":26,"species":177},{"level":26,"species":64}],"party_address":3215124,"script_address":2314220},{"address":3239992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":393},{"level":41,"species":178}],"party_address":3215148,"script_address":2564760},{"address":3240032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":64},{"level":30,"species":348}],"party_address":3215164,"script_address":2068289},{"address":3240072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":64},{"level":34,"species":348}],"party_address":3215180,"script_address":0},{"address":3240112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":64},{"level":37,"species":348}],"party_address":3215196,"script_address":0},{"address":3240152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":64},{"level":40,"species":348}],"party_address":3215212,"script_address":0},{"address":3240192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":348},{"level":43,"species":65}],"party_address":3215228,"script_address":0},{"address":3240232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338}],"party_address":3215244,"script_address":2067174},{"address":3240272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":338},{"level":44,"species":338}],"party_address":3215252,"script_address":2360864},{"address":3240312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":380}],"party_address":3215268,"script_address":2360895},{"address":3240352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":338}],"party_address":3215276,"script_address":0},{"address":3240392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[29,28,60,154],"species":289},{"level":36,"moves":[98,209,60,46],"species":338}],"party_address":3215284,"script_address":0},{"address":3240432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[29,28,60,154],"species":289},{"level":39,"moves":[98,209,60,0],"species":338}],"party_address":3215316,"script_address":0},{"address":3240472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[29,28,60,154],"species":289},{"level":41,"moves":[154,50,93,244],"species":55},{"level":41,"moves":[98,209,60,46],"species":338}],"party_address":3215348,"script_address":0},{"address":3240512,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,38,28,242],"species":287},{"level":48,"moves":[3,104,207,70],"species":300},{"level":46,"moves":[73,185,46,178],"species":345},{"level":48,"moves":[57,14,70,7],"species":327},{"level":49,"moves":[76,157,14,163],"species":376}],"party_address":3215396,"script_address":2274753},{"address":3240552,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[69,109,174,182],"species":362},{"level":49,"moves":[247,32,5,185],"species":378},{"level":50,"moves":[247,104,101,185],"species":322},{"level":49,"moves":[247,94,85,7],"species":378},{"level":51,"moves":[247,58,157,89],"species":362}],"party_address":3215476,"script_address":2275380},{"address":3240592,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[227,34,2,45],"species":342},{"level":50,"moves":[113,242,196,58],"species":347},{"level":52,"moves":[213,38,2,59],"species":342},{"level":52,"moves":[247,153,2,58],"species":347},{"level":53,"moves":[57,34,58,73],"species":343}],"party_address":3215556,"script_address":2276062},{"address":3240632,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[61,81,182,38],"species":396},{"level":54,"moves":[38,225,93,76],"species":359},{"level":53,"moves":[108,93,57,34],"species":230},{"level":53,"moves":[53,242,225,89],"species":334},{"level":55,"moves":[53,81,157,242],"species":397}],"party_address":3215636,"script_address":2276724},{"address":3240672,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":12,"moves":[33,111,88,61],"species":74},{"level":12,"moves":[33,111,88,61],"species":74},{"level":15,"moves":[79,106,33,61],"species":320}],"party_address":3215716,"script_address":2187976},{"address":3240712,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[2,67,69,83],"species":66},{"level":16,"moves":[8,113,115,83],"species":356},{"level":19,"moves":[36,233,179,83],"species":335}],"party_address":3215764,"script_address":2095066},{"address":3240752,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":20,"moves":[205,209,120,95],"species":100},{"level":20,"moves":[95,43,98,80],"species":337},{"level":22,"moves":[48,95,86,49],"species":82},{"level":24,"moves":[98,86,95,80],"species":338}],"party_address":3215812,"script_address":2167181},{"address":3240792,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[59,36,222,241],"species":339},{"level":24,"moves":[59,123,113,241],"species":218},{"level":26,"moves":[59,33,241,213],"species":340},{"level":29,"moves":[59,241,34,213],"species":321}],"party_address":3215876,"script_address":2103186},{"address":3240832,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[42,60,7,227],"species":308},{"level":27,"moves":[163,7,227,185],"species":365},{"level":29,"moves":[163,187,7,29],"species":289},{"level":31,"moves":[68,25,7,185],"species":366}],"party_address":3215940,"script_address":2129756},{"address":3240872,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[195,119,219,76],"species":358},{"level":29,"moves":[241,76,76,235],"species":369},{"level":30,"moves":[55,48,182,76],"species":310},{"level":31,"moves":[28,31,211,76],"species":227},{"level":33,"moves":[89,225,93,76],"species":359}],"party_address":3216004,"script_address":2202062},{"address":3240912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[89,246,94,113],"species":319},{"level":41,"moves":[94,241,109,91],"species":178},{"level":42,"moves":[113,94,95,91],"species":348},{"level":42,"moves":[241,76,94,53],"species":349}],"party_address":3216084,"script_address":0},{"address":3240952,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[96,213,186,175],"species":325},{"level":41,"moves":[240,96,133,89],"species":324},{"level":43,"moves":[227,34,62,96],"species":342},{"level":43,"moves":[96,152,13,43],"species":327},{"level":46,"moves":[96,104,58,156],"species":230}],"party_address":3216148,"script_address":2262245},{"address":3240992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":392}],"party_address":3216228,"script_address":2054242},{"address":3241032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3216236,"script_address":2554598},{"address":3241072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":339},{"level":15,"species":43},{"level":15,"species":309}],"party_address":3216244,"script_address":2554629},{"address":3241112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":356}],"party_address":3216268,"script_address":0},{"address":3241152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":393},{"level":29,"species":356}],"party_address":3216284,"script_address":0},{"address":3241192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":393},{"level":32,"species":357}],"party_address":3216300,"script_address":0},{"address":3241232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":393},{"level":34,"species":378},{"level":34,"species":357}],"party_address":3216316,"script_address":0},{"address":3241272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":306}],"party_address":3216340,"script_address":2054490},{"address":3241312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":306},{"level":16,"species":292}],"party_address":3216348,"script_address":2554660},{"address":3241352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":370}],"party_address":3216364,"script_address":0},{"address":3241392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":306},{"level":29,"species":371}],"party_address":3216380,"script_address":0},{"address":3241432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":307},{"level":32,"species":371}],"party_address":3216396,"script_address":0},{"address":3241472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":307},{"level":35,"species":372}],"party_address":3216412,"script_address":0},{"address":3241512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[95,60,146,42],"species":308},{"level":32,"moves":[8,25,47,185],"species":366}],"party_address":3216428,"script_address":0},{"address":3241552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[45,39,29,60],"species":288},{"level":17,"moves":[33,116,36,0],"species":335}],"party_address":3216460,"script_address":0},{"address":3241592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[45,39,29,60],"species":288},{"level":30,"moves":[33,116,36,0],"species":335}],"party_address":3216492,"script_address":0},{"address":3241632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[45,39,29,60],"species":288},{"level":33,"moves":[33,116,36,0],"species":335}],"party_address":3216524,"script_address":0},{"address":3241672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[45,39,29,60],"species":289},{"level":36,"moves":[33,116,36,0],"species":335}],"party_address":3216556,"script_address":0},{"address":3241712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[45,39,29,60],"species":289},{"level":38,"moves":[33,116,36,0],"species":336}],"party_address":3216588,"script_address":0},{"address":3241752,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":16,"species":304},{"level":16,"species":288}],"party_address":3216620,"script_address":2045785},{"address":3241792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":15,"species":315}],"party_address":3216636,"script_address":2026353},{"address":3241832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[18,204,185,215],"species":315},{"level":36,"moves":[18,204,185,215],"species":315},{"level":40,"moves":[18,204,185,215],"species":315},{"level":12,"moves":[18,204,185,215],"species":315},{"level":30,"moves":[18,204,185,215],"species":315},{"level":42,"moves":[18,204,185,215],"species":316}],"party_address":3216644,"script_address":2360833},{"address":3241872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":315}],"party_address":3216740,"script_address":0},{"address":3241912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":315}],"party_address":3216748,"script_address":0},{"address":3241952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316}],"party_address":3216756,"script_address":0},{"address":3241992,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":316}],"party_address":3216764,"script_address":0},{"address":3242032,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":17,"species":363}],"party_address":3216772,"script_address":2045890},{"address":3242072,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":25}],"party_address":3216780,"script_address":2067143},{"address":3242112,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":350},{"level":37,"species":183},{"level":39,"species":184}],"party_address":3216788,"script_address":2265832},{"address":3242152,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":353},{"level":14,"species":354}],"party_address":3216812,"script_address":2038890},{"address":3242192,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":26,"species":353},{"level":26,"species":354}],"party_address":3216828,"script_address":0},{"address":3242232,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":353},{"level":29,"species":354}],"party_address":3216844,"script_address":0},{"address":3242272,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":353},{"level":32,"species":354}],"party_address":3216860,"script_address":0},{"address":3242312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":353},{"level":35,"species":354}],"party_address":3216876,"script_address":0},{"address":3242352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":336}],"party_address":3216892,"script_address":2052811},{"address":3242392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[36,26,28,91],"species":336}],"party_address":3216900,"script_address":0},{"address":3242432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[36,26,28,91],"species":336}],"party_address":3216916,"script_address":0},{"address":3242472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[36,187,28,91],"species":336}],"party_address":3216932,"script_address":0},{"address":3242512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[36,187,28,91],"species":336}],"party_address":3216948,"script_address":0},{"address":3242552,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[136,96,93,197],"species":356}],"party_address":3216964,"script_address":2046100},{"address":3242592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":356},{"level":21,"species":335}],"party_address":3216980,"script_address":2304277},{"address":3242632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":356},{"level":30,"species":335}],"party_address":3216996,"script_address":0},{"address":3242672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":357},{"level":33,"species":336}],"party_address":3217012,"script_address":0},{"address":3242712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":357},{"level":36,"species":336}],"party_address":3217028,"script_address":0},{"address":3242752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":357},{"level":39,"species":336}],"party_address":3217044,"script_address":0},{"address":3242792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":286}],"party_address":3217060,"script_address":2024678},{"address":3242832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":288},{"level":7,"species":298}],"party_address":3217068,"script_address":2029684},{"address":3242872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[33,0,0,0],"species":74}],"party_address":3217084,"script_address":2188154},{"address":3242912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3217100,"script_address":2188185},{"address":3242952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":66}],"party_address":3217116,"script_address":2054180},{"address":3242992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[29,28,45,85],"species":288},{"level":17,"moves":[133,124,25,1],"species":367}],"party_address":3217124,"script_address":2167670},{"address":3243032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[213,58,85,53],"species":366},{"level":43,"moves":[29,182,5,92],"species":362}],"party_address":3217156,"script_address":2332778},{"address":3243072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,94,85,91],"species":394},{"level":43,"moves":[89,247,76,24],"species":366}],"party_address":3217188,"script_address":2332809},{"address":3243112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":332}],"party_address":3217220,"script_address":2050594},{"address":3243152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3217228,"script_address":2050625},{"address":3243192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":287}],"party_address":3217236,"script_address":0},{"address":3243232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":305},{"level":30,"species":287}],"party_address":3217244,"script_address":0},{"address":3243272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":305},{"level":29,"species":289},{"level":33,"species":287}],"party_address":3217260,"script_address":0},{"address":3243312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":32,"species":289},{"level":36,"species":287}],"party_address":3217284,"script_address":0},{"address":3243352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":16,"species":288}],"party_address":3217308,"script_address":2553792},{"address":3243392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":3,"species":304}],"party_address":3217324,"script_address":2024926},{"address":3243432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":382},{"level":13,"species":337}],"party_address":3217340,"script_address":2039000},{"address":3243472,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[240,67,38,59],"species":314},{"level":55,"moves":[92,56,188,58],"species":73},{"level":56,"moves":[202,57,73,104],"species":297},{"level":56,"moves":[89,57,133,63],"species":324},{"level":56,"moves":[93,89,63,57],"species":130},{"level":58,"moves":[105,57,58,92],"species":329}],"party_address":3217356,"script_address":2277575},{"address":3243512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":10,"species":72},{"level":15,"species":129}],"party_address":3217452,"script_address":2026322},{"address":3243552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":6,"species":129},{"level":7,"species":129}],"party_address":3217476,"script_address":2029653},{"address":3243592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":129},{"level":17,"species":118},{"level":18,"species":323}],"party_address":3217500,"script_address":2052185},{"address":3243632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":10,"species":129},{"level":7,"species":72},{"level":10,"species":129}],"party_address":3217524,"script_address":2034247},{"address":3243672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72}],"party_address":3217548,"script_address":2034357},{"address":3243712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72},{"level":14,"species":313},{"level":11,"species":72},{"level":14,"species":313}],"party_address":3217556,"script_address":2038546},{"address":3243752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3217588,"script_address":2052216},{"address":3243792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3217596,"script_address":2058894},{"address":3243832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":72}],"party_address":3217612,"script_address":2058925},{"address":3243872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":73}],"party_address":3217620,"script_address":2036183},{"address":3243912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":27,"species":130},{"level":27,"species":130}],"party_address":3217636,"script_address":0},{"address":3243952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":130},{"level":26,"species":330},{"level":26,"species":72},{"level":29,"species":130}],"party_address":3217660,"script_address":0},{"address":3243992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":130},{"level":30,"species":330},{"level":30,"species":73},{"level":31,"species":130}],"party_address":3217692,"script_address":0},{"address":3244032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":130},{"level":33,"species":331},{"level":33,"species":130},{"level":35,"species":73}],"party_address":3217724,"script_address":0},{"address":3244072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":129},{"level":21,"species":130},{"level":23,"species":130},{"level":26,"species":130},{"level":30,"species":130},{"level":35,"species":130}],"party_address":3217756,"script_address":2073670},{"address":3244112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":100},{"level":6,"species":100},{"level":14,"species":81}],"party_address":3217804,"script_address":2038577},{"address":3244152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81}],"party_address":3217828,"script_address":2038608},{"address":3244192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217844,"script_address":2038639},{"address":3244232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":81}],"party_address":3217852,"script_address":0},{"address":3244272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":81}],"party_address":3217860,"script_address":0},{"address":3244312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82}],"party_address":3217868,"script_address":0},{"address":3244352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":82}],"party_address":3217876,"script_address":0},{"address":3244392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217884,"script_address":2038780},{"address":3244432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81},{"level":6,"species":100}],"party_address":3217892,"script_address":2038749},{"address":3244472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81}],"party_address":3217916,"script_address":0},{"address":3244512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":81}],"party_address":3217924,"script_address":0},{"address":3244552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82}],"party_address":3217932,"script_address":0},{"address":3244592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":82}],"party_address":3217940,"script_address":0},{"address":3244632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217948,"script_address":2057375},{"address":3244672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217956,"script_address":0},{"address":3244712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3217964,"script_address":0},{"address":3244752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3217972,"script_address":0},{"address":3244792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3217980,"script_address":0},{"address":3244832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217988,"script_address":2057485},{"address":3244872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217996,"script_address":0},{"address":3244912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3218004,"script_address":0},{"address":3244952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3218012,"script_address":0},{"address":3244992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3218020,"script_address":0},{"address":3245032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218028,"script_address":2070582},{"address":3245072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":288},{"level":25,"species":337}],"party_address":3218044,"script_address":2340077},{"address":3245112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218060,"script_address":2071332},{"address":3245152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218068,"script_address":2070380},{"address":3245192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218084,"script_address":2072978},{"address":3245232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218100,"script_address":0},{"address":3245272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218108,"script_address":0},{"address":3245312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218116,"script_address":0},{"address":3245352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218124,"script_address":0},{"address":3245392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218132,"script_address":2070318},{"address":3245432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218140,"script_address":2070613},{"address":3245472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218156,"script_address":2073545},{"address":3245512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218164,"script_address":2071442},{"address":3245552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":309},{"level":33,"species":120}],"party_address":3218172,"script_address":2073009},{"address":3245592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218188,"script_address":0},{"address":3245632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218196,"script_address":0},{"address":3245672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218204,"script_address":0},{"address":3245712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218212,"script_address":0},{"address":3245752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":359},{"level":37,"species":359}],"party_address":3218220,"script_address":2292701},{"address":3245792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":359}],"party_address":3218236,"script_address":0},{"address":3245832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":359},{"level":44,"species":359}],"party_address":3218252,"script_address":0},{"address":3245872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":395},{"level":46,"species":359},{"level":46,"species":359}],"party_address":3218268,"script_address":0},{"address":3245912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":49,"species":359},{"level":49,"species":359},{"level":49,"species":396}],"party_address":3218292,"script_address":0},{"address":3245952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[225,29,116,52],"species":395}],"party_address":3218316,"script_address":2074182},{"address":3245992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309}],"party_address":3218332,"script_address":2059066},{"address":3246032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":369}],"party_address":3218340,"script_address":2061450},{"address":3246072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":305}],"party_address":3218356,"script_address":2061481},{"address":3246112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":84},{"level":27,"species":227},{"level":27,"species":369}],"party_address":3218364,"script_address":2202267},{"address":3246152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":227}],"party_address":3218388,"script_address":2202391},{"address":3246192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":369},{"level":33,"species":178}],"party_address":3218396,"script_address":2070085},{"address":3246232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":84},{"level":29,"species":310}],"party_address":3218412,"script_address":2202298},{"address":3246272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":309},{"level":28,"species":177}],"party_address":3218428,"script_address":2065338},{"address":3246312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":358}],"party_address":3218444,"script_address":2065369},{"address":3246352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":305},{"level":36,"species":310},{"level":36,"species":178}],"party_address":3218452,"script_address":2563257},{"address":3246392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":305}],"party_address":3218476,"script_address":2059097},{"address":3246432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":177},{"level":32,"species":358}],"party_address":3218492,"script_address":0},{"address":3246472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":177},{"level":35,"species":359}],"party_address":3218508,"script_address":0},{"address":3246512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":177},{"level":38,"species":359}],"party_address":3218524,"script_address":0},{"address":3246552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":178}],"party_address":3218540,"script_address":0},{"address":3246592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":177},{"level":33,"species":305}],"party_address":3218556,"script_address":2074151},{"address":3246632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":369}],"party_address":3218572,"script_address":2073981},{"address":3246672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302}],"party_address":3218580,"script_address":2061512},{"address":3246712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302},{"level":25,"species":109}],"party_address":3218588,"script_address":2061543},{"address":3246752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,89,0,0],"species":319},{"level":43,"moves":[85,89,0,0],"species":171}],"party_address":3218604,"script_address":2335578},{"address":3246792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3218636,"script_address":2341860},{"address":3246832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,124,120],"species":109}],"party_address":3218644,"script_address":2050766},{"address":3246872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":109},{"level":18,"species":302}],"party_address":3218692,"script_address":2050876},{"address":3246912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[139,33,124,120],"species":109},{"level":24,"moves":[139,33,124,0],"species":109},{"level":24,"moves":[139,33,124,120],"species":109},{"level":26,"moves":[33,124,0,0],"species":109}],"party_address":3218708,"script_address":0},{"address":3246952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,0],"species":109},{"level":29,"moves":[33,124,0,0],"species":109}],"party_address":3218772,"script_address":0},{"address":3246992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":32,"moves":[33,124,0,0],"species":109}],"party_address":3218836,"script_address":0},{"address":3247032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[139,33,124,0],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":35,"moves":[33,124,0,0],"species":110}],"party_address":3218900,"script_address":0},{"address":3247072,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218964,"script_address":2095313},{"address":3247112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218972,"script_address":2095351},{"address":3247152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":335}],"party_address":3218980,"script_address":2053062},{"address":3247192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":356}],"party_address":3218996,"script_address":2557727},{"address":3247232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3219004,"script_address":2557789},{"address":3247272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3219012,"script_address":0},{"address":3247312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":356},{"level":29,"species":335}],"party_address":3219028,"script_address":0},{"address":3247352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":357},{"level":32,"species":336}],"party_address":3219044,"script_address":0},{"address":3247392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":357},{"level":35,"species":336}],"party_address":3219060,"script_address":0},{"address":3247432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":19,"moves":[52,33,222,241],"species":339}],"party_address":3219076,"script_address":2050656},{"address":3247472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":363},{"level":28,"species":313}],"party_address":3219092,"script_address":2065713},{"address":3247512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[240,55,87,96],"species":385}],"party_address":3219108,"script_address":2065744},{"address":3247552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[52,33,222,241],"species":339}],"party_address":3219124,"script_address":0},{"address":3247592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[52,36,222,241],"species":339}],"party_address":3219140,"script_address":0},{"address":3247632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[73,72,64,241],"species":363},{"level":34,"moves":[53,36,222,241],"species":339}],"party_address":3219156,"script_address":0},{"address":3247672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[73,202,76,241],"species":363},{"level":37,"moves":[53,36,89,241],"species":340}],"party_address":3219188,"script_address":0},{"address":3247712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":313}],"party_address":3219220,"script_address":2033633},{"address":3247752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3219236,"script_address":2033664},{"address":3247792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":313}],"party_address":3219244,"script_address":2034216},{"address":3247832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":118}],"party_address":3219252,"script_address":2034620},{"address":3247872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219268,"script_address":2034651},{"address":3247912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":116},{"level":25,"species":183}],"party_address":3219276,"script_address":2034838},{"address":3247952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219292,"script_address":2034869},{"address":3247992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":118},{"level":24,"species":309},{"level":24,"species":118}],"party_address":3219300,"script_address":2035808},{"address":3248032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3219324,"script_address":2069240},{"address":3248072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":183}],"party_address":3219332,"script_address":2069350},{"address":3248112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219340,"script_address":2069851},{"address":3248152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219348,"script_address":2069882},{"address":3248192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":183},{"level":33,"species":341}],"party_address":3219356,"script_address":2070225},{"address":3248232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":118}],"party_address":3219372,"script_address":2070256},{"address":3248272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":118},{"level":33,"species":341}],"party_address":3219380,"script_address":2073260},{"address":3248312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219396,"script_address":2073421},{"address":3248352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219404,"script_address":2073452},{"address":3248392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":184}],"party_address":3219412,"script_address":2073639},{"address":3248432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219420,"script_address":2070349},{"address":3248472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219436,"script_address":2073888},{"address":3248512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":116},{"level":33,"species":117}],"party_address":3219444,"script_address":2073919},{"address":3248552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":171},{"level":34,"species":310}],"party_address":3219460,"script_address":0},{"address":3248592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219476,"script_address":2074120},{"address":3248632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":119}],"party_address":3219492,"script_address":2071676},{"address":3248672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":313}],"party_address":3219500,"script_address":0},{"address":3248712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":313}],"party_address":3219508,"script_address":0},{"address":3248752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":120},{"level":43,"species":313}],"party_address":3219516,"script_address":0},{"address":3248792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":313},{"level":45,"species":121}],"party_address":3219532,"script_address":0},{"address":3248832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[91,28,40,163],"species":27},{"level":22,"moves":[229,189,60,61],"species":318}],"party_address":3219556,"script_address":2046397},{"address":3248872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[28,40,163,91],"species":27},{"level":22,"moves":[205,61,39,111],"species":183}],"party_address":3219588,"script_address":2046459},{"address":3248912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":304},{"level":17,"species":296}],"party_address":3219620,"script_address":2049860},{"address":3248952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":183},{"level":18,"species":296}],"party_address":3219636,"script_address":2051934},{"address":3248992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":315},{"level":23,"species":358}],"party_address":3219652,"script_address":2557036},{"address":3249032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":306},{"level":19,"species":43},{"level":19,"species":358}],"party_address":3219668,"script_address":2310092},{"address":3249072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[194,219,68,243],"species":202}],"party_address":3219692,"script_address":2315855},{"address":3249112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":306},{"level":17,"species":183}],"party_address":3219708,"script_address":2046631},{"address":3249152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":306},{"level":25,"species":44},{"level":25,"species":358}],"party_address":3219724,"script_address":0},{"address":3249192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":307},{"level":28,"species":44},{"level":28,"species":358}],"party_address":3219748,"script_address":0},{"address":3249232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307},{"level":31,"species":44},{"level":31,"species":358}],"party_address":3219772,"script_address":0},{"address":3249272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":307},{"level":40,"species":45},{"level":40,"species":359}],"party_address":3219796,"script_address":0},{"address":3249312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":353},{"level":15,"species":354}],"party_address":3219820,"script_address":0},{"address":3249352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":353},{"level":27,"species":354}],"party_address":3219836,"script_address":0},{"address":3249392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":298},{"level":6,"species":295}],"party_address":3219852,"script_address":0},{"address":3249432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":292},{"level":26,"species":294}],"party_address":3219868,"script_address":0},{"address":3249472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":353},{"level":9,"species":354}],"party_address":3219884,"script_address":0},{"address":3249512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[101,50,0,0],"species":361},{"level":10,"moves":[71,73,0,0],"species":306}],"party_address":3219900,"script_address":0},{"address":3249552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":353},{"level":30,"species":354}],"party_address":3219932,"script_address":0},{"address":3249592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[209,12,57,14],"species":353},{"level":33,"moves":[209,12,204,14],"species":354}],"party_address":3219948,"script_address":0},{"address":3249632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,12,57,14],"species":353},{"level":36,"moves":[87,12,204,14],"species":354}],"party_address":3219980,"script_address":0},{"address":3249672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":309},{"level":12,"species":66}],"party_address":3220012,"script_address":2035839},{"address":3249712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309}],"party_address":3220028,"script_address":2035870},{"address":3249752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":67}],"party_address":3220036,"script_address":2069913},{"address":3249792,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":66},{"level":11,"species":72}],"party_address":3220052,"script_address":2543939},{"address":3249832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":73},{"level":44,"species":67}],"party_address":3220076,"script_address":2360255},{"address":3249872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":66},{"level":43,"species":310},{"level":43,"species":67}],"party_address":3220092,"script_address":2360286},{"address":3249912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":341},{"level":25,"species":67}],"party_address":3220116,"script_address":2340984},{"address":3249952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":309},{"level":36,"species":72},{"level":36,"species":67}],"party_address":3220132,"script_address":0},{"address":3249992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":310},{"level":39,"species":72},{"level":39,"species":67}],"party_address":3220156,"script_address":0},{"address":3250032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":310},{"level":42,"species":72},{"level":42,"species":67}],"party_address":3220180,"script_address":0},{"address":3250072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":310},{"level":45,"species":67},{"level":45,"species":73}],"party_address":3220204,"script_address":0},{"address":3250112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3220228,"script_address":2103632},{"address":3250152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[175,96,216,213],"species":328},{"level":39,"moves":[175,96,216,213],"species":328}],"party_address":3220236,"script_address":2265863},{"address":3250192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":376}],"party_address":3220268,"script_address":2068647},{"address":3250232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[92,87,120,188],"species":109}],"party_address":3220276,"script_address":2068616},{"address":3250272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[241,55,53,76],"species":385}],"party_address":3220292,"script_address":2068585},{"address":3250312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":338},{"level":33,"species":68}],"party_address":3220308,"script_address":2070116},{"address":3250352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":341}],"party_address":3220324,"script_address":2074337},{"address":3250392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[44,46,86,85],"species":338}],"party_address":3220340,"script_address":2074306},{"address":3250432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":356},{"level":33,"species":336}],"party_address":3220356,"script_address":2074275},{"address":3250472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3220372,"script_address":2074244},{"address":3250512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":170},{"level":33,"species":336}],"party_address":3220380,"script_address":2074043},{"address":3250552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":296},{"level":14,"species":299}],"party_address":3220396,"script_address":2038436},{"address":3250592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":380},{"level":18,"species":379}],"party_address":3220412,"script_address":2053172},{"address":3250632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":340},{"level":38,"species":287},{"level":40,"species":42}],"party_address":3220428,"script_address":0},{"address":3250672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":299}],"party_address":3220452,"script_address":0},{"address":3250712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":299}],"party_address":3220468,"script_address":0},{"address":3250752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":299}],"party_address":3220484,"script_address":0},{"address":3250792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":297},{"level":35,"species":300}],"party_address":3220500,"script_address":0},{"address":3250832,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[76,219,225,93],"species":359},{"level":43,"moves":[47,18,204,185],"species":316},{"level":44,"moves":[89,73,202,92],"species":363},{"level":41,"moves":[48,85,161,103],"species":82},{"level":45,"moves":[104,91,94,248],"species":394}],"party_address":3220516,"script_address":2332529},{"address":3250872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220596,"script_address":2025759},{"address":3250912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309},{"level":20,"species":278}],"party_address":3220604,"script_address":2039798},{"address":3250952,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310},{"level":31,"species":278}],"party_address":3220628,"script_address":2060578},{"address":3250992,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220652,"script_address":2025703},{"address":3251032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220660,"script_address":2039742},{"address":3251072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220684,"script_address":2060522},{"address":3251112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220708,"script_address":2025731},{"address":3251152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220716,"script_address":2039770},{"address":3251192,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220740,"script_address":2060550},{"address":3251232,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220764,"script_address":2025675},{"address":3251272,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":218},{"level":20,"species":278}],"party_address":3220772,"script_address":2039622},{"address":3251312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":296},{"level":31,"species":278}],"party_address":3220796,"script_address":2060420},{"address":3251352,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220820,"script_address":2025619},{"address":3251392,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220828,"script_address":2039566},{"address":3251432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220852,"script_address":2060364},{"address":3251472,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220876,"script_address":2025647},{"address":3251512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220884,"script_address":2039594},{"address":3251552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220908,"script_address":2060392},{"address":3251592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":370},{"level":11,"species":288},{"level":11,"species":382},{"level":11,"species":286},{"level":11,"species":304},{"level":11,"species":335}],"party_address":3220932,"script_address":2057155},{"address":3251632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":127}],"party_address":3220980,"script_address":2068678},{"address":3251672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[153,115,113,94],"species":348},{"level":43,"moves":[153,115,113,247],"species":349}],"party_address":3220988,"script_address":2334468},{"address":3251712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":371},{"level":22,"species":289},{"level":22,"species":382},{"level":22,"species":287},{"level":22,"species":305},{"level":22,"species":335}],"party_address":3221020,"script_address":0},{"address":3251752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":371},{"level":25,"species":289},{"level":25,"species":382},{"level":25,"species":287},{"level":25,"species":305},{"level":25,"species":336}],"party_address":3221068,"script_address":0},{"address":3251792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":371},{"level":28,"species":289},{"level":28,"species":382},{"level":28,"species":287},{"level":28,"species":305},{"level":28,"species":336}],"party_address":3221116,"script_address":0},{"address":3251832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":371},{"level":31,"species":289},{"level":31,"species":383},{"level":31,"species":287},{"level":31,"species":305},{"level":31,"species":336}],"party_address":3221164,"script_address":0},{"address":3251872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":306},{"level":11,"species":183},{"level":11,"species":363},{"level":11,"species":315},{"level":11,"species":118}],"party_address":3221212,"script_address":2057265},{"address":3251912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":322},{"level":43,"species":376}],"party_address":3221260,"script_address":2334499},{"address":3251952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":28}],"party_address":3221276,"script_address":2341891},{"address":3251992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":309},{"level":22,"species":306},{"level":22,"species":183},{"level":22,"species":363},{"level":22,"species":315},{"level":22,"species":118}],"party_address":3221284,"script_address":0},{"address":3252032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":310},{"level":25,"species":307},{"level":25,"species":183},{"level":25,"species":363},{"level":25,"species":316},{"level":25,"species":118}],"party_address":3221332,"script_address":0},{"address":3252072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":310},{"level":28,"species":307},{"level":28,"species":183},{"level":28,"species":363},{"level":28,"species":316},{"level":28,"species":118}],"party_address":3221380,"script_address":0},{"address":3252112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":310},{"level":31,"species":307},{"level":31,"species":184},{"level":31,"species":363},{"level":31,"species":316},{"level":31,"species":119}],"party_address":3221428,"script_address":0},{"address":3252152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3221476,"script_address":2061230},{"address":3252192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":298},{"level":28,"species":299},{"level":28,"species":296}],"party_address":3221484,"script_address":2065479},{"address":3252232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":345}],"party_address":3221508,"script_address":2563288},{"address":3252272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307}],"party_address":3221516,"script_address":0},{"address":3252312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307}],"party_address":3221524,"script_address":0},{"address":3252352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":307}],"party_address":3221532,"script_address":0},{"address":3252392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":317},{"level":39,"species":307}],"party_address":3221540,"script_address":0},{"address":3252432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":44},{"level":26,"species":363}],"party_address":3221556,"script_address":2061340},{"address":3252472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":295},{"level":28,"species":296},{"level":28,"species":299}],"party_address":3221572,"script_address":2065510},{"address":3252512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":358},{"level":38,"species":363}],"party_address":3221596,"script_address":2563226},{"address":3252552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":44},{"level":30,"species":363}],"party_address":3221612,"script_address":0},{"address":3252592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":44},{"level":33,"species":363}],"party_address":3221628,"script_address":0},{"address":3252632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":44},{"level":36,"species":363}],"party_address":3221644,"script_address":0},{"address":3252672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":182},{"level":39,"species":363}],"party_address":3221660,"script_address":0},{"address":3252712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":81}],"party_address":3221676,"script_address":2310306},{"address":3252752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":287},{"level":35,"species":42}],"party_address":3221684,"script_address":2327187},{"address":3252792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":313},{"level":31,"species":41}],"party_address":3221700,"script_address":0},{"address":3252832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":30,"species":41}],"party_address":3221716,"script_address":2317615},{"address":3252872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":286},{"level":22,"species":339}],"party_address":3221732,"script_address":2309993},{"address":3252912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3221748,"script_address":2188216},{"address":3252952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3221764,"script_address":2095389},{"address":3252992,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3221772,"script_address":2095465},{"address":3253032,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":335}],"party_address":3221780,"script_address":2095427},{"address":3253072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":356}],"party_address":3221788,"script_address":2244674},{"address":3253112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3221796,"script_address":2070287},{"address":3253152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[87,86,98,0],"species":338},{"level":32,"moves":[57,168,0,0],"species":289}],"party_address":3221804,"script_address":2070768},{"address":3253192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":73}],"party_address":3221836,"script_address":2071645},{"address":3253232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":41}],"party_address":3221844,"script_address":2304070},{"address":3253272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3221852,"script_address":2073102},{"address":3253312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":203}],"party_address":3221860,"script_address":0},{"address":3253352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":351}],"party_address":3221868,"script_address":2244705},{"address":3253392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3221876,"script_address":2244829},{"address":3253432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3221884,"script_address":2244767},{"address":3253472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":202}],"party_address":3221892,"script_address":2244798},{"address":3253512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":286}],"party_address":3221900,"script_address":2254605},{"address":3253552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221916,"script_address":2254667},{"address":3253592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3221924,"script_address":2257768},{"address":3253632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":287}],"party_address":3221932,"script_address":2257818},{"address":3253672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221940,"script_address":2257868},{"address":3253712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":177}],"party_address":3221948,"script_address":2244736},{"address":3253752,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3221956,"script_address":1978559},{"address":3253792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3221972,"script_address":1978621},{"address":3253832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":305},{"level":33,"species":307}],"party_address":3221988,"script_address":2073732},{"address":3253872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3222004,"script_address":2069651},{"address":3253912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3222012,"script_address":2572062},{"address":3253952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":20,"species":286},{"level":22,"species":339},{"level":22,"species":41}],"party_address":3222028,"script_address":2304039},{"address":3253992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":317},{"level":33,"species":371}],"party_address":3222060,"script_address":2073794},{"address":3254032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":218},{"level":15,"species":283}],"party_address":3222076,"script_address":1978590},{"address":3254072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3222092,"script_address":1978317},{"address":3254112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":287},{"level":38,"species":169},{"level":39,"species":340}],"party_address":3222108,"script_address":2351441},{"address":3254152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":287},{"level":24,"species":41},{"level":25,"species":340}],"party_address":3222132,"script_address":2303440},{"address":3254192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":4,"species":306}],"party_address":3222156,"script_address":2024895},{"address":3254232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":295},{"level":6,"species":306}],"party_address":3222172,"script_address":2029715},{"address":3254272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":183}],"party_address":3222188,"script_address":2054459},{"address":3254312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183},{"level":15,"species":306},{"level":15,"species":339}],"party_address":3222196,"script_address":2045995},{"address":3254352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":306}],"party_address":3222220,"script_address":0},{"address":3254392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":307}],"party_address":3222236,"script_address":0},{"address":3254432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":307}],"party_address":3222252,"script_address":0},{"address":3254472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":296},{"level":34,"species":307}],"party_address":3222268,"script_address":0},{"address":3254512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":43}],"party_address":3222292,"script_address":2553761},{"address":3254552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":315},{"level":14,"species":306},{"level":14,"species":183}],"party_address":3222300,"script_address":2553823},{"address":3254592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325}],"party_address":3222324,"script_address":2265615},{"address":3254632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":118},{"level":39,"species":313}],"party_address":3222332,"script_address":2265646},{"address":3254672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":290},{"level":4,"species":290}],"party_address":3222348,"script_address":2024864},{"address":3254712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290}],"party_address":3222364,"script_address":2300392},{"address":3254752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":290},{"level":8,"species":301}],"party_address":3222396,"script_address":2054211},{"address":3254792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":301},{"level":28,"species":302}],"party_address":3222412,"script_address":2061137},{"address":3254832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222428,"script_address":2061168},{"address":3254872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302}],"party_address":3222444,"script_address":2061199},{"address":3254912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":301},{"level":6,"species":301}],"party_address":3222452,"script_address":2300423},{"address":3254952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":302}],"party_address":3222468,"script_address":0},{"address":3254992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":302}],"party_address":3222476,"script_address":0},{"address":3255032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":294},{"level":31,"species":302}],"party_address":3222492,"script_address":0},{"address":3255072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":311},{"level":33,"species":302},{"level":33,"species":294},{"level":33,"species":302}],"party_address":3222516,"script_address":0},{"address":3255112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":339},{"level":17,"species":66}],"party_address":3222548,"script_address":2049688},{"address":3255152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":17,"species":74},{"level":16,"species":74}],"party_address":3222564,"script_address":2049719},{"address":3255192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":66}],"party_address":3222588,"script_address":2051841},{"address":3255232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":339}],"party_address":3222604,"script_address":2051872},{"address":3255272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":74},{"level":22,"species":320},{"level":22,"species":75}],"party_address":3222620,"script_address":2557067},{"address":3255312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74}],"party_address":3222644,"script_address":2054428},{"address":3255352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":74},{"level":20,"species":318}],"party_address":3222652,"script_address":2310061},{"address":3255392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":9,"moves":[150,55,0,0],"species":313}],"party_address":3222668,"script_address":0},{"address":3255432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[16,45,0,0],"species":310},{"level":10,"moves":[44,184,0,0],"species":286}],"party_address":3222684,"script_address":0},{"address":3255472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":16,"species":74},{"level":16,"species":66}],"party_address":3222716,"script_address":2296023},{"address":3255512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":75}],"party_address":3222740,"script_address":0},{"address":3255552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":74},{"level":27,"species":74},{"level":27,"species":75},{"level":27,"species":75}],"party_address":3222772,"script_address":0},{"address":3255592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":74},{"level":30,"species":75},{"level":30,"species":75},{"level":30,"species":75}],"party_address":3222804,"script_address":0},{"address":3255632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":76}],"party_address":3222836,"script_address":0},{"address":3255672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":316},{"level":31,"species":338}],"party_address":3222868,"script_address":0},{"address":3255712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":325}],"party_address":3222884,"script_address":0},{"address":3255752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222900,"script_address":0},{"address":3255792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":386},{"level":30,"species":387}],"party_address":3222916,"script_address":0},{"address":3255832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":386},{"level":33,"species":387}],"party_address":3222932,"script_address":0},{"address":3255872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":386},{"level":36,"species":387}],"party_address":3222948,"script_address":0},{"address":3255912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":386},{"level":39,"species":387}],"party_address":3222964,"script_address":0},{"address":3255952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":118}],"party_address":3222980,"script_address":2543970},{"address":3255992,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[53,154,185,20],"species":317}],"party_address":3222988,"script_address":2103539},{"address":3256032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[117,197,93,9],"species":356},{"level":17,"moves":[9,197,93,96],"species":356}],"party_address":3223004,"script_address":2167701},{"address":3256072,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[117,197,93,7],"species":356}],"party_address":3223036,"script_address":2103508},{"address":3256112,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[33,120,124,108],"species":109},{"level":25,"moves":[33,139,124,108],"species":109}],"party_address":3223052,"script_address":2061574},{"address":3256152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[139,120,124,108],"species":109},{"level":28,"moves":[28,104,210,14],"species":302}],"party_address":3223084,"script_address":2065775},{"address":3256192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[141,154,170,91],"species":301},{"level":28,"moves":[33,120,124,108],"species":109}],"party_address":3223116,"script_address":2065806},{"address":3256232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":305},{"level":29,"species":178}],"party_address":3223148,"script_address":2202329},{"address":3256272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":358},{"level":27,"species":358},{"level":27,"species":358}],"party_address":3223164,"script_address":2202360},{"address":3256312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":392}],"party_address":3223188,"script_address":1971405},{"address":3256352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[76,219,225,93],"species":359},{"level":46,"moves":[47,18,204,185],"species":316},{"level":47,"moves":[89,73,202,92],"species":363},{"level":44,"moves":[48,85,161,103],"species":82},{"level":48,"moves":[104,91,94,248],"species":394}],"party_address":3223196,"script_address":2332607},{"address":3256392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[76,219,225,93],"species":359},{"level":49,"moves":[47,18,204,185],"species":316},{"level":50,"moves":[89,73,202,92],"species":363},{"level":47,"moves":[48,85,161,103],"species":82},{"level":51,"moves":[104,91,94,248],"species":394}],"party_address":3223276,"script_address":0},{"address":3256432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[76,219,225,93],"species":359},{"level":52,"moves":[47,18,204,185],"species":316},{"level":53,"moves":[89,73,202,92],"species":363},{"level":50,"moves":[48,85,161,103],"species":82},{"level":54,"moves":[104,91,94,248],"species":394}],"party_address":3223356,"script_address":0},{"address":3256472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[76,219,225,93],"species":359},{"level":55,"moves":[47,18,204,185],"species":316},{"level":56,"moves":[89,73,202,92],"species":363},{"level":53,"moves":[48,85,161,103],"species":82},{"level":57,"moves":[104,91,94,248],"species":394}],"party_address":3223436,"script_address":0},{"address":3256512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223516,"script_address":1986165},{"address":3256552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223548,"script_address":1986109},{"address":3256592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223580,"script_address":1986137},{"address":3256632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223612,"script_address":1986081},{"address":3256672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223644,"script_address":1986025},{"address":3256712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223676,"script_address":1986053},{"address":3256752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":31,"species":72},{"level":32,"species":331}],"party_address":3223708,"script_address":2070644},{"address":3256792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":34,"species":73}],"party_address":3223732,"script_address":2070675},{"address":3256832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":129},{"level":25,"species":129},{"level":35,"species":130}],"party_address":3223748,"script_address":2070706},{"address":3256872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":44},{"level":34,"species":184}],"party_address":3223772,"script_address":2071552},{"address":3256912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":300},{"level":34,"species":320}],"party_address":3223788,"script_address":2071583},{"address":3256952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":67}],"party_address":3223804,"script_address":2070799},{"address":3256992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":72},{"level":31,"species":72},{"level":36,"species":313}],"party_address":3223812,"script_address":2071614},{"address":3257032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":305},{"level":32,"species":227}],"party_address":3223836,"script_address":2070737},{"address":3257072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":341},{"level":33,"species":331}],"party_address":3223852,"script_address":2073040},{"address":3257112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170}],"party_address":3223868,"script_address":2073071},{"address":3257152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":308},{"level":19,"species":308}],"party_address":3223876,"script_address":0},{"address":3257192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[47,31,219,76],"species":358},{"level":35,"moves":[53,36,156,89],"species":339}],"party_address":3223892,"script_address":0},{"address":3257232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[74,78,72,73],"species":363},{"level":20,"moves":[111,205,44,88],"species":75}],"party_address":3223924,"script_address":0},{"address":3257272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[16,60,92,182],"species":294},{"level":27,"moves":[16,72,213,78],"species":292}],"party_address":3223956,"script_address":0},{"address":3257312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[94,7,244,182],"species":357},{"level":39,"moves":[8,61,156,187],"species":336}],"party_address":3223988,"script_address":0},{"address":3257352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,7,244,182],"species":357},{"level":43,"moves":[8,61,156,187],"species":336}],"party_address":3224020,"script_address":0},{"address":3257392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[94,7,244,182],"species":357},{"level":46,"moves":[8,61,156,187],"species":336}],"party_address":3224052,"script_address":0},{"address":3257432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":49,"moves":[94,7,244,182],"species":357},{"level":49,"moves":[8,61,156,187],"species":336}],"party_address":3224084,"script_address":0},{"address":3257472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[94,7,244,182],"species":357},{"level":52,"moves":[8,61,156,187],"species":336}],"party_address":3224116,"script_address":0},{"address":3257512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":33,"species":309}],"party_address":3224148,"script_address":0},{"address":3257552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170},{"level":33,"species":330}],"party_address":3224164,"script_address":0},{"address":3257592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":170},{"level":40,"species":330}],"party_address":3224180,"script_address":0},{"address":3257632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":171},{"level":43,"species":330}],"party_address":3224196,"script_address":0},{"address":3257672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":171},{"level":46,"species":331}],"party_address":3224212,"script_address":0},{"address":3257712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":51,"species":171},{"level":49,"species":331}],"party_address":3224228,"script_address":0},{"address":3257752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":118},{"level":25,"species":72}],"party_address":3224244,"script_address":0},{"address":3257792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":129},{"level":20,"species":72},{"level":26,"species":328},{"level":23,"species":330}],"party_address":3224260,"script_address":2061605},{"address":3257832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":288},{"level":8,"species":286}],"party_address":3224292,"script_address":2054707},{"address":3257872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":295},{"level":8,"species":288}],"party_address":3224308,"script_address":2054676},{"address":3257912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":129}],"party_address":3224324,"script_address":2030343},{"address":3257952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":183}],"party_address":3224332,"script_address":2036307},{"address":3257992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":72},{"level":12,"species":72}],"party_address":3224340,"script_address":2036276},{"address":3258032,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":354},{"level":14,"species":353}],"party_address":3224356,"script_address":2039032},{"address":3258072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":337},{"level":14,"species":100}],"party_address":3224372,"script_address":2039063},{"address":3258112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81}],"party_address":3224388,"script_address":2039094},{"address":3258152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":100}],"party_address":3224396,"script_address":2026463},{"address":3258192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":335}],"party_address":3224404,"script_address":2026494},{"address":3258232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":27}],"party_address":3224412,"script_address":2046975},{"address":3258272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":363}],"party_address":3224420,"script_address":2047006},{"address":3258312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306}],"party_address":3224428,"script_address":2046944},{"address":3258352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339}],"party_address":3224436,"script_address":2046913},{"address":3258392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":183},{"level":19,"species":296}],"party_address":3224444,"script_address":2050969},{"address":3258432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":227},{"level":19,"species":305}],"party_address":3224460,"script_address":2051000},{"address":3258472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":318},{"level":18,"species":27}],"party_address":3224476,"script_address":2051031},{"address":3258512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":382},{"level":18,"species":382}],"party_address":3224492,"script_address":2051062},{"address":3258552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":183}],"party_address":3224508,"script_address":2052309},{"address":3258592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3224524,"script_address":2052371},{"address":3258632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":299}],"party_address":3224532,"script_address":2052340},{"address":3258672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":14,"species":382},{"level":14,"species":337}],"party_address":3224540,"script_address":2059128},{"address":3258712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224564,"script_address":2347841},{"address":3258752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224572,"script_address":2347872},{"address":3258792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224580,"script_address":2348597},{"address":3258832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":41}],"party_address":3224588,"script_address":2348628},{"address":3258872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":339}],"party_address":3224604,"script_address":2348659},{"address":3258912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224620,"script_address":2349324},{"address":3258952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224628,"script_address":2349355},{"address":3258992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224636,"script_address":2349386},{"address":3259032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224644,"script_address":2350264},{"address":3259072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224652,"script_address":2350826},{"address":3259112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224660,"script_address":2351566},{"address":3259152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224668,"script_address":2351597},{"address":3259192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224676,"script_address":2351628},{"address":3259232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224684,"script_address":2348566},{"address":3259272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224692,"script_address":2349293},{"address":3259312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224700,"script_address":2350295},{"address":3259352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":339},{"level":28,"species":287},{"level":30,"species":41},{"level":33,"species":340}],"party_address":3224708,"script_address":2351659},{"address":3259392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":310},{"level":33,"species":340}],"party_address":3224740,"script_address":2073763},{"address":3259432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":287},{"level":43,"species":169},{"level":44,"species":340}],"party_address":3224756,"script_address":0},{"address":3259472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":72}],"party_address":3224780,"script_address":2026525},{"address":3259512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183}],"party_address":3224788,"script_address":2026556},{"address":3259552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":27},{"level":25,"species":27}],"party_address":3224796,"script_address":2033726},{"address":3259592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":309}],"party_address":3224812,"script_address":2033695},{"address":3259632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":120}],"party_address":3224828,"script_address":2034744},{"address":3259672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":309},{"level":24,"species":66},{"level":24,"species":72}],"party_address":3224836,"script_address":2034931},{"address":3259712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":338},{"level":24,"species":305},{"level":24,"species":338}],"party_address":3224860,"script_address":2034900},{"address":3259752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":227},{"level":25,"species":227}],"party_address":3224884,"script_address":2036338},{"address":3259792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":183},{"level":22,"species":296}],"party_address":3224900,"script_address":2047037},{"address":3259832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":27},{"level":22,"species":28}],"party_address":3224916,"script_address":2047068},{"address":3259872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":304},{"level":22,"species":299}],"party_address":3224932,"script_address":2047099},{"address":3259912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":18,"species":218}],"party_address":3224948,"script_address":2049891},{"address":3259952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306},{"level":18,"species":363}],"party_address":3224964,"script_address":2049922},{"address":3259992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":84},{"level":26,"species":85}],"party_address":3224980,"script_address":2053203},{"address":3260032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302},{"level":26,"species":367}],"party_address":3224996,"script_address":2053234},{"address":3260072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":64},{"level":26,"species":393}],"party_address":3225012,"script_address":2053265},{"address":3260112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3225028,"script_address":2053296},{"address":3260152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":351}],"party_address":3225044,"script_address":2053327},{"address":3260192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3225060,"script_address":2054738},{"address":3260232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":306},{"level":8,"species":295}],"party_address":3225076,"script_address":2054769},{"address":3260272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3225092,"script_address":2057834},{"address":3260312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3225100,"script_address":2057865},{"address":3260352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":356}],"party_address":3225108,"script_address":2057896},{"address":3260392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":363},{"level":33,"species":357}],"party_address":3225116,"script_address":2073825},{"address":3260432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":338}],"party_address":3225132,"script_address":2061636},{"address":3260472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":218},{"level":25,"species":339}],"party_address":3225140,"script_address":2061667},{"address":3260512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3225156,"script_address":2061698},{"address":3260552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[87,98,86,0],"species":338}],"party_address":3225164,"script_address":2065837},{"address":3260592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":356},{"level":28,"species":335}],"party_address":3225180,"script_address":2065868},{"address":3260632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":292}],"party_address":3225196,"script_address":2067487},{"address":3260672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":335},{"level":25,"species":309},{"level":25,"species":369},{"level":25,"species":288},{"level":25,"species":337},{"level":25,"species":339}],"party_address":3225212,"script_address":2067518},{"address":3260712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":286},{"level":25,"species":306},{"level":25,"species":337},{"level":25,"species":183},{"level":25,"species":27},{"level":25,"species":367}],"party_address":3225260,"script_address":2067549},{"address":3260752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":371},{"level":29,"species":365}],"party_address":3225308,"script_address":2067611},{"address":3260792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3225324,"script_address":1978255},{"address":3260832,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":321},{"level":15,"species":283}],"party_address":3225340,"script_address":1978286},{"address":3260872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[182,205,222,153],"species":76},{"level":35,"moves":[14,58,57,157],"species":140},{"level":35,"moves":[231,153,46,157],"species":95},{"level":37,"moves":[104,153,182,157],"species":320}],"party_address":3225356,"script_address":0},{"address":3260912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[182,58,157,57],"species":138},{"level":37,"moves":[182,205,222,153],"species":76},{"level":40,"moves":[14,58,57,157],"species":141},{"level":40,"moves":[231,153,46,157],"species":95},{"level":42,"moves":[104,153,182,157],"species":320}],"party_address":3225420,"script_address":0},{"address":3260952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[182,58,157,57],"species":139},{"level":42,"moves":[182,205,89,153],"species":76},{"level":45,"moves":[14,58,57,157],"species":141},{"level":45,"moves":[231,153,46,157],"species":95},{"level":47,"moves":[104,153,182,157],"species":320}],"party_address":3225500,"script_address":0},{"address":3260992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[157,63,48,182],"species":142},{"level":47,"moves":[8,205,89,153],"species":76},{"level":47,"moves":[182,58,157,57],"species":139},{"level":50,"moves":[14,58,57,157],"species":141},{"level":50,"moves":[231,153,46,157],"species":208},{"level":52,"moves":[104,153,182,157],"species":320}],"party_address":3225580,"script_address":0},{"address":3261032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[2,157,8,83],"species":68},{"level":33,"moves":[94,113,115,8],"species":356},{"level":35,"moves":[228,68,182,167],"species":237},{"level":37,"moves":[252,8,187,89],"species":336}],"party_address":3225676,"script_address":0},{"address":3261072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[2,157,8,83],"species":68},{"level":38,"moves":[94,113,115,8],"species":357},{"level":40,"moves":[228,68,182,167],"species":237},{"level":42,"moves":[252,8,187,89],"species":336}],"party_address":3225740,"script_address":0},{"address":3261112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[71,182,7,8],"species":107},{"level":43,"moves":[2,157,8,83],"species":68},{"level":43,"moves":[8,113,115,94],"species":357},{"level":45,"moves":[228,68,182,167],"species":237},{"level":47,"moves":[252,8,187,89],"species":336}],"party_address":3225804,"script_address":0},{"address":3261152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[25,8,89,83],"species":106},{"level":46,"moves":[71,182,7,8],"species":107},{"level":48,"moves":[238,157,8,83],"species":68},{"level":48,"moves":[8,113,115,94],"species":357},{"level":50,"moves":[228,68,182,167],"species":237},{"level":52,"moves":[252,8,187,89],"species":336}],"party_address":3225884,"script_address":0},{"address":3261192,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,182,86,113],"species":179},{"level":36,"moves":[205,87,153,240],"species":101},{"level":38,"moves":[48,182,87,240],"species":82},{"level":40,"moves":[44,86,87,182],"species":338}],"party_address":3225980,"script_address":0},{"address":3261232,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[87,21,240,95],"species":25},{"level":41,"moves":[87,182,86,113],"species":180},{"level":41,"moves":[205,87,153,240],"species":101},{"level":43,"moves":[48,182,87,240],"species":82},{"level":45,"moves":[44,86,87,182],"species":338}],"party_address":3226044,"script_address":0},{"address":3261272,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[87,21,240,182],"species":26},{"level":46,"moves":[87,182,86,113],"species":181},{"level":46,"moves":[205,87,153,240],"species":101},{"level":48,"moves":[48,182,87,240],"species":82},{"level":50,"moves":[44,86,87,182],"species":338}],"party_address":3226124,"script_address":0},{"address":3261312,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[129,8,9,113],"species":125},{"level":51,"moves":[87,21,240,182],"species":26},{"level":51,"moves":[87,182,86,113],"species":181},{"level":53,"moves":[205,87,153,240],"species":101},{"level":53,"moves":[48,182,87,240],"species":82},{"level":55,"moves":[44,86,87,182],"species":338}],"party_address":3226204,"script_address":0},{"address":3261352,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[59,213,113,157],"species":219},{"level":36,"moves":[53,213,76,84],"species":77},{"level":38,"moves":[59,241,89,213],"species":340},{"level":40,"moves":[59,241,153,213],"species":321}],"party_address":3226300,"script_address":0},{"address":3261392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[14,53,46,241],"species":58},{"level":43,"moves":[59,213,113,157],"species":219},{"level":41,"moves":[53,213,76,84],"species":77},{"level":43,"moves":[59,241,89,213],"species":340},{"level":45,"moves":[59,241,153,213],"species":321}],"party_address":3226364,"script_address":0},{"address":3261432,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,76,13,241],"species":228},{"level":46,"moves":[14,53,241,46],"species":58},{"level":48,"moves":[59,213,113,157],"species":219},{"level":46,"moves":[53,213,76,84],"species":78},{"level":48,"moves":[59,241,89,213],"species":340},{"level":50,"moves":[59,241,153,213],"species":321}],"party_address":3226444,"script_address":0},{"address":3261472,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":51,"moves":[14,53,241,46],"species":59},{"level":53,"moves":[59,213,113,157],"species":219},{"level":51,"moves":[46,76,13,241],"species":229},{"level":51,"moves":[53,213,76,84],"species":78},{"level":53,"moves":[59,241,89,213],"species":340},{"level":55,"moves":[59,241,153,213],"species":321}],"party_address":3226540,"script_address":0},{"address":3261512,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[113,47,29,8],"species":113},{"level":42,"moves":[59,247,38,126],"species":366},{"level":43,"moves":[42,29,7,95],"species":308},{"level":45,"moves":[63,53,85,247],"species":366}],"party_address":3226636,"script_address":0},{"address":3261552,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[59,247,38,126],"species":366},{"level":47,"moves":[113,47,29,8],"species":113},{"level":45,"moves":[252,146,203,179],"species":115},{"level":48,"moves":[42,29,7,95],"species":308},{"level":50,"moves":[63,53,85,247],"species":366}],"party_address":3226700,"script_address":0},{"address":3261592,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[59,247,38,126],"species":366},{"level":52,"moves":[113,47,29,8],"species":242},{"level":50,"moves":[252,146,203,179],"species":115},{"level":53,"moves":[42,29,7,95],"species":308},{"level":55,"moves":[63,53,85,247],"species":366}],"party_address":3226780,"script_address":0},{"address":3261632,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[59,247,38,126],"species":366},{"level":57,"moves":[182,47,29,8],"species":242},{"level":55,"moves":[252,146,203,179],"species":115},{"level":57,"moves":[36,182,126,89],"species":128},{"level":58,"moves":[42,29,7,95],"species":308},{"level":60,"moves":[63,53,85,247],"species":366}],"party_address":3226860,"script_address":0},{"address":3261672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[86,85,182,58],"species":147},{"level":38,"moves":[241,76,76,89],"species":369},{"level":41,"moves":[57,48,182,76],"species":310},{"level":43,"moves":[18,191,211,76],"species":227},{"level":45,"moves":[76,156,93,89],"species":359}],"party_address":3226956,"script_address":0},{"address":3261712,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[95,94,115,138],"species":163},{"level":43,"moves":[241,76,76,89],"species":369},{"level":45,"moves":[86,85,182,58],"species":148},{"level":46,"moves":[57,48,182,76],"species":310},{"level":48,"moves":[18,191,211,76],"species":227},{"level":50,"moves":[76,156,93,89],"species":359}],"party_address":3227036,"script_address":0},{"address":3261752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[95,94,115,138],"species":164},{"level":49,"moves":[241,76,76,89],"species":369},{"level":50,"moves":[86,85,182,58],"species":148},{"level":51,"moves":[57,48,182,76],"species":310},{"level":53,"moves":[18,191,211,76],"species":227},{"level":55,"moves":[76,156,93,89],"species":359}],"party_address":3227132,"script_address":0},{"address":3261792,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,94,115,138],"species":164},{"level":54,"moves":[241,76,76,89],"species":369},{"level":55,"moves":[57,48,182,76],"species":310},{"level":55,"moves":[63,85,89,58],"species":149},{"level":58,"moves":[18,191,211,76],"species":227},{"level":60,"moves":[143,156,93,89],"species":359}],"party_address":3227228,"script_address":0},{"address":3261832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[25,94,91,182],"species":79},{"level":49,"moves":[89,246,94,113],"species":319},{"level":49,"moves":[94,156,109,91],"species":178},{"level":50,"moves":[89,94,156,91],"species":348},{"level":50,"moves":[241,76,94,53],"species":349}],"party_address":3227324,"script_address":0},{"address":3261872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,138,29,182],"species":96},{"level":53,"moves":[25,94,91,182],"species":79},{"level":54,"moves":[89,153,94,113],"species":319},{"level":54,"moves":[94,156,109,91],"species":178},{"level":55,"moves":[89,94,156,91],"species":348},{"level":55,"moves":[241,76,94,53],"species":349}],"party_address":3227404,"script_address":0},{"address":3261912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":58,"moves":[95,138,29,182],"species":97},{"level":59,"moves":[89,153,94,113],"species":319},{"level":58,"moves":[25,94,91,182],"species":79},{"level":59,"moves":[94,156,109,91],"species":178},{"level":60,"moves":[89,94,156,91],"species":348},{"level":60,"moves":[241,76,94,53],"species":349}],"party_address":3227500,"script_address":0},{"address":3261952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":63,"moves":[95,138,29,182],"species":97},{"level":64,"moves":[89,153,94,113],"species":319},{"level":63,"moves":[25,94,91,182],"species":199},{"level":64,"moves":[94,156,109,91],"species":178},{"level":65,"moves":[89,94,156,91],"species":348},{"level":65,"moves":[241,76,94,53],"species":349}],"party_address":3227596,"script_address":0},{"address":3261992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[95,240,182,56],"species":60},{"level":46,"moves":[240,96,104,90],"species":324},{"level":48,"moves":[96,34,182,58],"species":343},{"level":48,"moves":[156,152,13,104],"species":327},{"level":51,"moves":[96,104,58,156],"species":230}],"party_address":3227692,"script_address":0},{"address":3262032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[95,240,182,56],"species":61},{"level":51,"moves":[240,96,104,90],"species":324},{"level":53,"moves":[96,34,182,58],"species":343},{"level":53,"moves":[156,12,13,104],"species":327},{"level":56,"moves":[96,104,58,156],"species":230}],"party_address":3227772,"script_address":0},{"address":3262072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[56,195,58,109],"species":131},{"level":58,"moves":[240,96,104,90],"species":324},{"level":56,"moves":[95,240,182,56],"species":61},{"level":58,"moves":[96,34,182,58],"species":343},{"level":58,"moves":[156,12,13,104],"species":327},{"level":61,"moves":[96,104,58,156],"species":230}],"party_address":3227852,"script_address":0},{"address":3262112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":61,"moves":[56,195,58,109],"species":131},{"level":63,"moves":[240,96,104,90],"species":324},{"level":61,"moves":[95,240,56,195],"species":186},{"level":63,"moves":[96,34,182,73],"species":343},{"level":63,"moves":[156,12,13,104],"species":327},{"level":66,"moves":[96,104,58,156],"species":230}],"party_address":3227948,"script_address":0},{"address":3262152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[95,98,204,0],"species":387},{"level":17,"moves":[95,98,109,0],"species":386}],"party_address":3228044,"script_address":2167732},{"address":3262192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":369}],"party_address":3228076,"script_address":2202422},{"address":3262232,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":77,"moves":[92,76,191,211],"species":227},{"level":75,"moves":[115,113,246,89],"species":319},{"level":76,"moves":[87,89,76,81],"species":384},{"level":76,"moves":[202,246,19,109],"species":389},{"level":76,"moves":[96,246,76,163],"species":391},{"level":78,"moves":[89,94,53,247],"species":400}],"party_address":3228084,"script_address":2354502},{"address":3262272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228180,"script_address":0},{"address":3262312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228188,"script_address":0},{"address":3262352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228196,"script_address":0},{"address":3262392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228204,"script_address":0},{"address":3262432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228212,"script_address":0},{"address":3262472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228220,"script_address":0},{"address":3262512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228228,"script_address":0},{"address":3262552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":27}],"party_address":3228236,"script_address":0},{"address":3262592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":320},{"level":33,"species":27},{"level":33,"species":27}],"party_address":3228252,"script_address":0},{"address":3262632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":320},{"level":35,"species":27},{"level":35,"species":27}],"party_address":3228276,"script_address":0},{"address":3262672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":320},{"level":37,"species":28},{"level":37,"species":28}],"party_address":3228300,"script_address":0},{"address":3262712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":309},{"level":30,"species":66},{"level":30,"species":72}],"party_address":3228324,"script_address":0},{"address":3262752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":66},{"level":32,"species":72}],"party_address":3228348,"script_address":0},{"address":3262792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":66},{"level":34,"species":73}],"party_address":3228372,"script_address":0},{"address":3262832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":310},{"level":36,"species":67},{"level":36,"species":73}],"party_address":3228396,"script_address":0},{"address":3262872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":120},{"level":37,"species":120}],"party_address":3228420,"script_address":0},{"address":3262912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":309},{"level":39,"species":120},{"level":39,"species":120}],"party_address":3228436,"script_address":0},{"address":3262952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":310},{"level":41,"species":120},{"level":41,"species":120}],"party_address":3228460,"script_address":0},{"address":3262992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":310},{"level":43,"species":121},{"level":43,"species":121}],"party_address":3228484,"script_address":0},{"address":3263032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":67},{"level":37,"species":67}],"party_address":3228508,"script_address":0},{"address":3263072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":335},{"level":39,"species":67},{"level":39,"species":67}],"party_address":3228524,"script_address":0},{"address":3263112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":336},{"level":41,"species":67},{"level":41,"species":67}],"party_address":3228548,"script_address":0},{"address":3263152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":336},{"level":43,"species":68},{"level":43,"species":68}],"party_address":3228572,"script_address":0},{"address":3263192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":371},{"level":35,"species":365}],"party_address":3228596,"script_address":0},{"address":3263232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":308},{"level":37,"species":371},{"level":37,"species":365}],"party_address":3228612,"script_address":0},{"address":3263272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":308},{"level":39,"species":371},{"level":39,"species":365}],"party_address":3228636,"script_address":0},{"address":3263312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":308},{"level":41,"species":372},{"level":41,"species":366}],"party_address":3228660,"script_address":0},{"address":3263352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":337},{"level":35,"species":337},{"level":35,"species":371}],"party_address":3228684,"script_address":0},{"address":3263392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":337},{"level":37,"species":338},{"level":37,"species":371}],"party_address":3228708,"script_address":0},{"address":3263432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":338},{"level":39,"species":338},{"level":39,"species":371}],"party_address":3228732,"script_address":0},{"address":3263472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":338},{"level":41,"species":338},{"level":41,"species":372}],"party_address":3228756,"script_address":0},{"address":3263512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":74},{"level":26,"species":339}],"party_address":3228780,"script_address":0},{"address":3263552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":66},{"level":28,"species":339},{"level":28,"species":75}],"party_address":3228796,"script_address":0},{"address":3263592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":66},{"level":30,"species":339},{"level":30,"species":75}],"party_address":3228820,"script_address":0},{"address":3263632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":340},{"level":33,"species":76}],"party_address":3228844,"script_address":0},{"address":3263672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":315},{"level":31,"species":287},{"level":31,"species":288},{"level":31,"species":295},{"level":31,"species":298},{"level":31,"species":304}],"party_address":3228868,"script_address":0},{"address":3263712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":315},{"level":33,"species":287},{"level":33,"species":289},{"level":33,"species":296},{"level":33,"species":299},{"level":33,"species":304}],"party_address":3228916,"script_address":0},{"address":3263752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316},{"level":35,"species":287},{"level":35,"species":289},{"level":35,"species":296},{"level":35,"species":299},{"level":35,"species":305}],"party_address":3228964,"script_address":0},{"address":3263792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":316},{"level":37,"species":287},{"level":37,"species":289},{"level":37,"species":297},{"level":37,"species":300},{"level":37,"species":305}],"party_address":3229012,"script_address":0},{"address":3263832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313},{"level":34,"species":116}],"party_address":3229060,"script_address":0},{"address":3263872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":325},{"level":36,"species":313},{"level":36,"species":117}],"party_address":3229076,"script_address":0},{"address":3263912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":325},{"level":38,"species":313},{"level":38,"species":117}],"party_address":3229100,"script_address":0},{"address":3263952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325},{"level":40,"species":314},{"level":40,"species":230}],"party_address":3229124,"script_address":0},{"address":3263992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":411}],"party_address":3229148,"script_address":2564791},{"address":3264032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":64}],"party_address":3229156,"script_address":2564822},{"address":3264072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":202}],"party_address":3229172,"script_address":0},{"address":3264112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":4}],"party_address":3229180,"script_address":0},{"address":3264152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":1}],"party_address":3229188,"script_address":0},{"address":3264192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":405}],"party_address":3229196,"script_address":0},{"address":3264232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":404}],"party_address":3229204,"script_address":0}],"warps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4":"MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0","MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2":"MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1","MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10","MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2":"MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11","MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3":"MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2","MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0":"MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4","MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3":"MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5","MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2":"MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6","MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4":"MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7","MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0":"MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8","MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9","MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2":"MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0","MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0":"MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1","MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0":"MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2","MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1":"MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3","MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2":"MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4","MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0":"MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5","MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10":"MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6","MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9":"MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7","MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0":"MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0","MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2","MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3","MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0":"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8","MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8":"MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0","MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11":"MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2","MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0","MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0","MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3","MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4","MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0","MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1","MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2","MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0","MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0":"MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0","MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0":"MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0","MAP_ALTERING_CAVE:0/MAP_ROUTE103:0":"MAP_ROUTE103:0/MAP_ALTERING_CAVE:0","MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0":"MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0","MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2":"MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1","MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1":"MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2","MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6":"MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0","MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0":"MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2","MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2":"MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0","MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0":"MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1","MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6":"MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10","MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22":"MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11","MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9":"MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12","MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18":"MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13","MAP_AQUA_HIDEOUT_B1F:14/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16":"MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15","MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15":"MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16","MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20":"MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17","MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13":"MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18","MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24":"MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19","MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1":"MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2","MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:21/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11":"MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22","MAP_AQUA_HIDEOUT_B1F:23/MAP_AQUA_HIDEOUT_B1F:17!":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19":"MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24","MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2":"MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3","MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7":"MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4","MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8":"MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5","MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10":"MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6","MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5":"MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8","MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1":"MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0","MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2":"MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1","MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3":"MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2","MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5":"MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3","MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8":"MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4","MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3":"MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5","MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7":"MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6","MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6":"MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7","MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4":"MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8","MAP_AQUA_HIDEOUT_B2F:9/MAP_AQUA_HIDEOUT_B1F:4!":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0","MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1":"MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1","MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0","MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1":"MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1","MAP_BATTLE_COLOSSEUM_2P:0,1/MAP_DYNAMIC:-1!":"","MAP_BATTLE_COLOSSEUM_4P:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:3/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0!":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2","MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2","MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0","MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0","MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0","MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0","MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0","MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0","MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0","MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0","MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0","MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0","MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0":"MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0":"MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0":"MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0":"MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0":"MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0":"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0":"MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0":"MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0":"MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0":"MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0":"MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0":"MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0":"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0":"MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0":"MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1","MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0","MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0":"MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0","MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0":"MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0","MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1":"MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0","MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3":"MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0":"MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:0/MAP_CAVE_OF_ORIGIN_1F:1!":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:1/MAP_CAVE_OF_ORIGIN_B1F:0!":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_DESERT_RUINS:0/MAP_ROUTE111:1":"MAP_ROUTE111:1/MAP_DESERT_RUINS:0","MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2":"MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1","MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1":"MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2","MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0","MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0":"MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0","MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1","MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0":"MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2","MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0":"MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3","MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0":"MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4","MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2":"MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0","MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0":"MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0","MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3":"MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0","MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4":"MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1":"MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0","MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1","MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0":"MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2","MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1":"MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1":"MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0":"MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1":"MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0":"MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1":"MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0":"MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1","MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0","MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1","MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0","MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1","MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0","MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1","MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0","MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1","MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0","MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1","MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1":"MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0":"MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1":"MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0":"MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0":"MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1":"MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0":"MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1","MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0":"MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0","MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0":"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1","MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2","MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0":"MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3","MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0":"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4","MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1":"MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0","MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3":"MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0","MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0":"MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0","MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4":"MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2":"MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1":"MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1","MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1":"MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1","MAP_FIERY_PATH:0/MAP_ROUTE112:4":"MAP_ROUTE112:4/MAP_FIERY_PATH:0","MAP_FIERY_PATH:1/MAP_ROUTE112:5":"MAP_ROUTE112:5/MAP_FIERY_PATH:1","MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0","MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0":"MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1","MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0":"MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2","MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0":"MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3","MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0":"MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4","MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0":"MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5","MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0":"MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6","MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0":"MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7","MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0":"MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8","MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8":"MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0","MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2":"MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0","MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1":"MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0","MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4":"MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0","MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5":"MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0","MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6":"MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0","MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7":"MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0","MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3":"MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0":"MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2","MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0","MAP_FORTREE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FORTREE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0":"MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0","MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0":"MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1","MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1":"MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2","MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0":"MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3","MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1":"MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0","MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2":"MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1","MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0":"MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2","MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1":"MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3","MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2":"MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4","MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3":"MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5","MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4":"MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6","MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2":"MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0","MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3":"MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1","MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4":"MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2","MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5":"MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3","MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6":"MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4","MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3":"MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0","MAP_INSIDE_OF_TRUCK:0,1,2/MAP_DYNAMIC:-1!":"","MAP_ISLAND_CAVE:0/MAP_ROUTE105:0":"MAP_ROUTE105:0/MAP_ISLAND_CAVE:0","MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2":"MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1","MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1":"MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2","MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3":"MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1","MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3":"MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3","MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0":"MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4","MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0":"MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0","MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0":"MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1","MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0":"MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2","MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3","MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0":"MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4","MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5","MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1":"MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0","MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8":"MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10","MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9":"MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11","MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10":"MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12","MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11":"MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13","MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12":"MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14","MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13":"MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15","MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14":"MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16","MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15":"MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17","MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16":"MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18","MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17":"MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19","MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0":"MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2","MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18":"MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20","MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20":"MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21","MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19":"MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22","MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21":"MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23","MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22":"MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24","MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23":"MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25","MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2":"MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3","MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4":"MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4","MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3":"MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5","MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1":"MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6","MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5":"MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7","MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6":"MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8","MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7":"MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9","MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2":"MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0","MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6":"MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1","MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12":"MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10","MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13":"MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11","MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14":"MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12","MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15":"MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13","MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16":"MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14","MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17":"MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15","MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18":"MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16","MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19":"MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17","MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20":"MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18","MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22":"MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19","MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3":"MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2","MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21":"MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20","MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23":"MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21","MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24":"MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22","MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25":"MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23","MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5":"MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3","MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4":"MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4","MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7":"MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5","MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8":"MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6","MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9":"MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7","MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10":"MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8","MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11":"MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9","MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0":"MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0","MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4":"MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0","MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2":"MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3":"MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5":"MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0","MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1","MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0":"MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10","MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0":"MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11","MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0":"MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12","MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2","MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13","MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4","MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1":"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5","MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0":"MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6","MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0":"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7","MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0":"MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8","MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0":"MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9","MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0","MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1","MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4":"MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0","MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0":"MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2","MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1":"MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1":"MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:3/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!":"","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0","MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12":"MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0","MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8":"MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0","MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9":"MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0","MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10":"MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0","MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11":"MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13":"MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0","MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7":"MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2":"MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5":"MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1","MAP_LILYCOVE_CITY_UNUSED_MART:0,1/MAP_LILYCOVE_CITY:0!":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0","MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1","MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0":"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1":"MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0":"MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2":"MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0","MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4":"MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0","MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1":"MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1","MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1":"MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2","MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0":"MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3","MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0":"MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0","MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1":"MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1","MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2":"MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2","MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0":"MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0","MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2":"MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1","MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3":"MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0","MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0":"MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1","MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0":"MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0","MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0":"MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1","MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2":"MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2","MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1":"MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0","MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1":"MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0","MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1":"MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1","MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0":"MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0","MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1":"MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1","MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0":"MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0","MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0":"MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0","MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0":"MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0","MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1","MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0":"MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2","MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0":"MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3","MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0":"MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4","MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0":"MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5","MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0":"MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6","MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2":"MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0","MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5":"MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0","MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0":"MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0","MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4":"MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0","MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6":"MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0","MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3":"MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1":"MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0":"MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0","MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0":"MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1","MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0":"MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2","MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4":"MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3","MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5":"MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4","MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0":"MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5","MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2":"MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0","MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0":"MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1","MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1":"MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2","MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2":"MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3","MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1":"MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0","MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2":"MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1","MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3":"MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2","MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0":"MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3","MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3":"MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4","MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4":"MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5","MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3":"MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0","MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5":"MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0","MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3":"MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0","MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1":"MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1","MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0":"MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0","MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1":"MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1","MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0":"MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0","MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0":"MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1","MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1":"MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0","MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0":"MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0","MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0":"MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1","MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2","MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0":"MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3","MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0":"MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4","MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0":"MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5","MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0":"MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6","MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1":"MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7","MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8","MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9":"MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2","MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0","MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1":"MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0","MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11":"MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10","MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10":"MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11","MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13":"MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12","MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12":"MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13","MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3":"MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2","MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2":"MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3","MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5":"MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4","MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4":"MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5","MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7":"MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6","MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6":"MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7","MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9":"MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8","MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8":"MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9","MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0":"MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0","MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3":"MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0","MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5":"MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0","MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7":"MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1","MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4":"MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2":"MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8":"MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2","MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0","MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6":"MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0","MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1":"MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1","MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3":"MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3","MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1":"MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1","MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0":"MAP_ROUTE122:0/MAP_MT_PYRE_1F:0","MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0":"MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1","MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0":"MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4","MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4":"MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5","MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4":"MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0","MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0":"MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1","MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4":"MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2","MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5":"MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3","MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5":"MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4","MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1":"MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0","MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1":"MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1","MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4":"MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2","MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5":"MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3","MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2":"MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4","MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3":"MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5","MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1":"MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0","MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1":"MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1","MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3":"MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2","MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4":"MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3","MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2":"MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4","MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3":"MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5","MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0":"MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0","MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0":"MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1","MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1":"MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2","MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2":"MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3","MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3":"MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4","MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0":"MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0","MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2":"MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1","MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1":"MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0","MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1":"MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1","MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1":"MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1","MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0":"MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0","MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1":"MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1","MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0":"MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0","MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2":"MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0","MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0":"MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1","MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1":"MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0","MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0":"MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1","MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1":"MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0","MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0":"MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1","MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1":"MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0","MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0":"MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1","MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1":"MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0","MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0":"MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1","MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1":"MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0","MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0":"MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1","MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1":"MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0","MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0":"MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1","MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1":"MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0","MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0":"MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1","MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1":"MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0","MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0":"MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1","MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1":"MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0","MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1":"MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1","MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0":"MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0","MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1":"MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1","MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0":"MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0","MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1":"MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1","MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0":"MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0","MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1":"MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1","MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0":"MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0","MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1":"MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1","MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0":"MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2","MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0":"MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0","MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1":"MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0","MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0":"MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0","MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0":"MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1","MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1":"MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0","MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0":"MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1","MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1":"MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0","MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0":"MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1","MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1":"MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0","MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0":"MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1","MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0":"MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0","MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0":"MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1","MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1":"MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0","MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0":"MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0","MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0":"MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1","MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2","MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0":"MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3","MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0":"MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0","MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1":"MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0","MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3":"MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2":"MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0","MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0":"MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1","MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0":"MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2","MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0":"MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3","MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0":"MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4","MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0":"MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5","MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1":"MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0","MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2":"MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0","MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3":"MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0","MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4":"MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0","MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5":"MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0":"MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0":"MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0","MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0":"MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1","MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0":"MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2","MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3","MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0":"MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4","MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0":"MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5","MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2":"MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0","MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8":"MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10","MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9":"MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12","MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16":"MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14","MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18":"MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15","MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14":"MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16","MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15":"MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18","MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3":"MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2","MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24":"MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20","MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26":"MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21","MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28":"MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22","MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30":"MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23","MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20":"MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24","MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21":"MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26","MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22":"MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28","MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2":"MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3","MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23":"MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30","MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34":"MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32","MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36":"MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33","MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32":"MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34","MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33":"MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36","MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6":"MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5","MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5":"MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6","MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10":"MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8","MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12":"MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9","MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0":"MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0","MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4":"MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0","MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5":"MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3":"MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1":"MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0","MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3":"MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1","MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5":"MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3","MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7":"MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5","MAP_RECORD_CORNER:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_ROUTE103:0/MAP_ALTERING_CAVE:0":"MAP_ALTERING_CAVE:0/MAP_ROUTE103:0","MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0":"MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0","MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0":"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1","MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1":"MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3","MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3":"MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5","MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5":"MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7","MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0":"MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0","MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1":"MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0","MAP_ROUTE105:0/MAP_ISLAND_CAVE:0":"MAP_ISLAND_CAVE:0/MAP_ROUTE105:0","MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0":"MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0","MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0":"MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0","MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0":"MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0","MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0":"MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0","MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0":"MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0","MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1","MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2","MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3","MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4","MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4":"MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5":"MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2":"MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3":"MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1":"MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:2,3/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0","MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0":"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1":"MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0":"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0","MAP_ROUTE111:1/MAP_DESERT_RUINS:0":"MAP_DESERT_RUINS:0/MAP_ROUTE111:1","MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0":"MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2","MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0":"MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3","MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0":"MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4","MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2":"MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0","MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0":"MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0","MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1":"MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1","MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1":"MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3","MAP_ROUTE112:4/MAP_FIERY_PATH:0":"MAP_FIERY_PATH:0/MAP_ROUTE112:4","MAP_ROUTE112:5/MAP_FIERY_PATH:1":"MAP_FIERY_PATH:1/MAP_ROUTE112:5","MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1":"MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1","MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0":"MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0","MAP_ROUTE113:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0":"MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0","MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0":"MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0","MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1","MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0":"MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2","MAP_ROUTE114:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1":"MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0":"MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2","MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2":"MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0","MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1":"MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0","MAP_ROUTE115:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE115:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0":"MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0","MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0":"MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1","MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2":"MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2","MAP_ROUTE116:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1":"MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0","MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0":"MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0","MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0":"MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0","MAP_ROUTE118:0/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE118:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0","MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0":"MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1","MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1":"MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0":"MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2","MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0","MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0":"MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0","MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0":"MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1","MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0":"MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0":"MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2","MAP_ROUTE122:0/MAP_MT_PYRE_1F:0":"MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0","MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0":"MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0","MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0":"MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0","MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0":"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0","MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0":"MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0","MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0","MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0":"MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0","MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0":"MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0","MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0":"MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1","MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0":"MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10","MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0":"MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11","MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0":"MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2","MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3","MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0":"MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4","MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6","MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0":"MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7","MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0":"MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8","MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0":"MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9","MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8":"MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0","MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6":"MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1","MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2","MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0","MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1","MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0","MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1":"MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0","MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0":"MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2","MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2":"MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0","MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10":"MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0","MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0":"MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2","MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2":"MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0","MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0":"MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1","MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1":"MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0","MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0":"MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0","MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7":"MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0","MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9":"MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0","MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11":"MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0","MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2":"MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3":"MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4":"MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0","MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0":"MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0","MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4":"MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1","MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2":"MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2","MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0":"MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0","MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0","MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0":"MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0","MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1":"MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:0/MAP_UNDERWATER_ROUTE128:0!":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0":"MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1","MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0":"MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1","MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0":"MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2","MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2":"MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0","MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0":"MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1","MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0":"MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2","MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0":"MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3","MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1":"MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0","MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1":"MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1","MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1":"MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2","MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1":"MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0","MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1":"MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1","MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2":"MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2","MAP_SEAFLOOR_CAVERN_ROOM4:3/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1":"MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0","MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1":"MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1","MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2":"MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2","MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2":"MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0","MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2":"MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1","MAP_SEAFLOOR_CAVERN_ROOM6:2/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3":"MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0","MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1":"MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1","MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0":"MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0","MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0":"MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1","MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0":"MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0","MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0":"MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0","MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0":"MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0","MAP_SECRET_BASE_BLUE_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0":"MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1","MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1":"MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0","MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0":"MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2","MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2":"MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0","MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0":"MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1","MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1":"MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0","MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0":"MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1","MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1":"MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2","MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1":"MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0","MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2":"MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1","MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0":"MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2","MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2":"MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0","MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0":"MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1","MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0":"MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0","MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0":"MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1","MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1":"MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0","MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0":"MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1","MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1":"MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0","MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0","MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0":"MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1","MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0":"MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10","MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2","MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0":"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3","MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0":"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4","MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7","MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0":"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6","MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0":"MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8","MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2":"MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9","MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3":"MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0","MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8":"MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0","MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9":"MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2","MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10":"MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0","MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1":"MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0","MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6":"MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7":"MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0":"MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4":"MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2":"MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0","MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0","MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0":"MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1","MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0":"MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10","MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0":"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11","MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12","MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0":"MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2","MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0":"MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3","MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0":"MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4","MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0":"MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5","MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0":"MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6","MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0":"MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7","MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0":"MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8","MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0":"MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9","MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2":"MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0","MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0":"MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2","MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2":"MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0","MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4":"MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0","MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5":"MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0","MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6":"MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0","MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7":"MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0","MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8":"MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0","MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9":"MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0","MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10":"MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0","MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11":"MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0","MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1":"MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12":"MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0":"MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1":"MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1","MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1":"MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1","MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0":"MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0","MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2":"MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1","MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4":"MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2","MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6":"MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3","MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8":"MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4","MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9":"MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5","MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10":"MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6","MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11":"MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7","MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0":"MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8","MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8":"MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0","MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0":"MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0","MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6":"MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10","MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7":"MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11","MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1":"MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2","MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2":"MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4","MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3":"MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6","MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4":"MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8","MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5":"MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9","MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1":"MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0","MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!":"","MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0":"MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1","MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!":"","MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2":"MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0","MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0":"MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1","MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1":"MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0","MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0":"MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1","MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1":"MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0","MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0":"MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1","MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1":"MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0","MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0":"MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1","MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1":"MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1","MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4":"MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0","MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0":"MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2","MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1":"MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0","MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1":"MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1","MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!":"","MAP_UNDERWATER_ROUTE105:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE105:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0":"MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0","MAP_UNDERWATER_ROUTE127:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE127:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0":"MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0","MAP_UNDERWATER_ROUTE129:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE129:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0":"MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0","MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0":"MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0","MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0":"MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0","MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!":"","MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0":"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0","MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0":"MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1","MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2","MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0":"MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3","MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1":"MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4","MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0":"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5","MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0":"MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6","MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0":"MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0","MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5":"MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0","MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6":"MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0","MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1":"MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2":"MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3":"MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0","MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2":"MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0","MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3":"MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1","MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5":"MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2","MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2":"MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3","MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4":"MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4","MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0":"MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0","MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2":"MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1","MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3":"MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2","MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1":"MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3","MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4":"MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4","MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2":"MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5","MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3":"MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6","MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0":"MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0","MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3":"MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1","MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1":"MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2","MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6":"MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3"}} diff --git a/worlds/pokemon_emerald/pokemon.py b/worlds/pokemon_emerald/pokemon.py index fec1101dab0d..6f2676500d66 100644 --- a/worlds/pokemon_emerald/pokemon.py +++ b/worlds/pokemon_emerald/pokemon.py @@ -4,7 +4,8 @@ import functools from typing import TYPE_CHECKING, Dict, List, Set, Optional, Tuple -from .data import (NUM_REAL_SPECIES, OUT_OF_LOGIC_MAPS, EncounterTableData, LearnsetMove, SpeciesData, data) +from .data import (NUM_REAL_SPECIES, OUT_OF_LOGIC_MAPS, EncounterType, EncounterTableData, LearnsetMove, SpeciesData, + MapData, data) from .options import (Goal, HmCompatibility, LevelUpMoves, RandomizeAbilities, RandomizeLegendaryEncounters, RandomizeMiscPokemon, RandomizeStarters, RandomizeTypes, RandomizeWildPokemon, TmTutorCompatibility) @@ -226,6 +227,42 @@ def randomize_types(world: "PokemonEmeraldWorld") -> None: evolutions += [world.modified_species[evo.species_id] for evo in evolution.evolutions] +_encounter_subcategory_ranges: Dict[EncounterType, Dict[range, Optional[str]]] = { + EncounterType.LAND: {range(0, 12): None}, + EncounterType.WATER: {range(0, 5): None}, + EncounterType.FISHING: {range(0, 2): "OLD_ROD", range(2, 5): "GOOD_ROD", range(5, 10): "SUPER_ROD"}, +} + + +def _rename_wild_events(world: "PokemonEmeraldWorld", map_data: MapData, new_slots: List[int], encounter_type: EncounterType): + """ + Renames the events that correspond to wild encounters to reflect the new species there after randomization + """ + for i, new_species_id in enumerate(new_slots): + # Get the subcategory for rods + subcategory_range, subcategory_name = next( + (r, sc) + for r, sc in _encounter_subcategory_ranges[encounter_type].items() + if i in r + ) + subcategory_species = [] + for k in subcategory_range: + if new_slots[k] not in subcategory_species: + subcategory_species.append(new_slots[k]) + + # Create the name of the location that corresponds to this encounter slot + # Fishing locations include the rod name + subcategory_str = "" if subcategory_name is None else "_" + subcategory_name + encounter_location_index = subcategory_species.index(new_species_id) + 1 + encounter_location_name = f"{map_data.name}_{encounter_type.value}_ENCOUNTERS{subcategory_str}_{encounter_location_index}" + try: + # Get the corresponding location and change the event name to reflect the new species + slot_location = world.multiworld.get_location(encounter_location_name, world.player) + slot_location.item.name = f"CATCH_{data.species[new_species_id].name}" + except KeyError: + pass # Map probably isn't included; should be careful here about bad encounter location names + + def randomize_wild_encounters(world: "PokemonEmeraldWorld") -> None: if world.options.wild_pokemon == RandomizeWildPokemon.option_vanilla: return @@ -253,120 +290,96 @@ def randomize_wild_encounters(world: "PokemonEmeraldWorld") -> None: placed_priority_species = False map_data = world.modified_maps[map_name] - new_encounters: List[Optional[EncounterTableData]] = [None, None, None] - old_encounters = [map_data.land_encounters, map_data.water_encounters, map_data.fishing_encounters] - - for i, table in enumerate(old_encounters): - if table is not None: - # Create a map from the original species to new species - # instead of just randomizing every slot. - # Force area 1-to-1 mapping, in other words. - species_old_to_new_map: Dict[int, int] = {} - for species_id in table.slots: - if species_id not in species_old_to_new_map: - if not placed_priority_species and len(priority_species) > 0 \ - and map_name not in OUT_OF_LOGIC_MAPS: - new_species_id = priority_species.pop() - placed_priority_species = True - else: - original_species = data.species[species_id] - - # Construct progressive tiers of blacklists that can be peeled back if they - # collectively cover too much of the pokedex. A lower index in `blacklists` - # indicates a more important set of species to avoid. Entries at `0` will - # always be blacklisted. - blacklists: Dict[int, List[Set[int]]] = defaultdict(list) - - # Blacklist pokemon already on this table - blacklists[0].append(set(species_old_to_new_map.values())) - - # If doing legendary hunt, blacklist Latios from wild encounters so - # it can be tracked as the roamer. Otherwise it may be impossible - # to tell whether a highlighted route is the roamer or a wild - # encounter. - if world.options.goal == Goal.option_legendary_hunt: - blacklists[0].append({data.constants["SPECIES_LATIOS"]}) - - # If dexsanity/catch 'em all mode, blacklist already placed species - # until every species has been placed once - if world.options.dexsanity and len(already_placed) < num_placeable_species: - blacklists[1].append(already_placed) - - # Blacklist from player options - blacklists[2].append(world.blacklisted_wilds) - - # Type matching blacklist - if should_match_type: - blacklists[3].append({ - species.species_id - for species in world.modified_species.values() - if not bool(set(species.types) & set(original_species.types)) - }) - - merged_blacklist: Set[int] = set() - for max_priority in reversed(sorted(blacklists.keys())): - merged_blacklist = set() - for priority in blacklists.keys(): - if priority <= max_priority: - for blacklist in blacklists[priority]: - merged_blacklist |= blacklist - - if len(merged_blacklist) < NUM_REAL_SPECIES: - break - else: - raise RuntimeError("This should never happen") - - candidates = [ - species + new_encounters: Dict[EncounterType, EncounterTableData] = {} + + for encounter_type, table in map_data.encounters.items(): + # Create a map from the original species to new species + # instead of just randomizing every slot. + # Force area 1-to-1 mapping, in other words. + species_old_to_new_map: Dict[int, int] = {} + for species_id in table.slots: + if species_id not in species_old_to_new_map: + if not placed_priority_species and len(priority_species) > 0 \ + and encounter_type != EncounterType.ROCK_SMASH and map_name not in OUT_OF_LOGIC_MAPS: + new_species_id = priority_species.pop() + placed_priority_species = True + else: + original_species = data.species[species_id] + + # Construct progressive tiers of blacklists that can be peeled back if they + # collectively cover too much of the pokedex. A lower index in `blacklists` + # indicates a more important set of species to avoid. Entries at `0` will + # always be blacklisted. + blacklists: Dict[int, List[Set[int]]] = defaultdict(list) + + # Blacklist pokemon already on this table + blacklists[0].append(set(species_old_to_new_map.values())) + + # If doing legendary hunt, blacklist Latios from wild encounters so + # it can be tracked as the roamer. Otherwise it may be impossible + # to tell whether a highlighted route is the roamer or a wild + # encounter. + if world.options.goal == Goal.option_legendary_hunt: + blacklists[0].append({data.constants["SPECIES_LATIOS"]}) + + # If dexsanity/catch 'em all mode, blacklist already placed species + # until every species has been placed once + if world.options.dexsanity and len(already_placed) < num_placeable_species: + blacklists[1].append(already_placed) + + # Blacklist from player options + blacklists[2].append(world.blacklisted_wilds) + + # Type matching blacklist + if should_match_type: + blacklists[3].append({ + species.species_id for species in world.modified_species.values() - if species.species_id not in merged_blacklist - ] - - if should_match_bst: - candidates = filter_species_by_nearby_bst(candidates, sum(original_species.base_stats)) - - new_species_id = world.random.choice(candidates).species_id - species_old_to_new_map[species_id] = new_species_id - - if world.options.dexsanity and map_name not in OUT_OF_LOGIC_MAPS: - already_placed.add(new_species_id) - - # Actually create the new list of slots and encounter table - new_slots: List[int] = [] - for species_id in table.slots: - new_slots.append(species_old_to_new_map[species_id]) - - new_encounters[i] = EncounterTableData(new_slots, table.address) - - # Rename event items for the new wild pokemon species - slot_category: Tuple[str, List[Tuple[Optional[str], range]]] = [ - ("LAND", [(None, range(0, 12))]), - ("WATER", [(None, range(0, 5))]), - ("FISHING", [("OLD_ROD", range(0, 2)), ("GOOD_ROD", range(2, 5)), ("SUPER_ROD", range(5, 10))]), - ][i] - for j, new_species_id in enumerate(new_slots): - # Get the subcategory for rods - subcategory = next(sc for sc in slot_category[1] if j in sc[1]) - subcategory_species = [] - for k in subcategory[1]: - if new_slots[k] not in subcategory_species: - subcategory_species.append(new_slots[k]) - - # Create the name of the location that corresponds to this encounter slot - # Fishing locations include the rod name - subcategory_str = "" if subcategory[0] is None else "_" + subcategory[0] - encounter_location_index = subcategory_species.index(new_species_id) + 1 - encounter_location_name = f"{map_data.name}_{slot_category[0]}_ENCOUNTERS{subcategory_str}_{encounter_location_index}" - try: - # Get the corresponding location and change the event name to reflect the new species - slot_location = world.multiworld.get_location(encounter_location_name, world.player) - slot_location.item.name = f"CATCH_{data.species[new_species_id].name}" - except KeyError: - pass # Map probably isn't included; should be careful here about bad encounter location names - - map_data.land_encounters = new_encounters[0] - map_data.water_encounters = new_encounters[1] - map_data.fishing_encounters = new_encounters[2] + if not bool(set(species.types) & set(original_species.types)) + }) + + merged_blacklist: Set[int] = set() + for max_priority in reversed(sorted(blacklists.keys())): + merged_blacklist = set() + for priority in blacklists.keys(): + if priority <= max_priority: + for blacklist in blacklists[priority]: + merged_blacklist |= blacklist + + if len(merged_blacklist) < NUM_REAL_SPECIES: + break + else: + raise RuntimeError("This should never happen") + + candidates = [ + species + for species in world.modified_species.values() + if species.species_id not in merged_blacklist + ] + + if should_match_bst: + candidates = filter_species_by_nearby_bst(candidates, sum(original_species.base_stats)) + + new_species_id = world.random.choice(candidates).species_id + + species_old_to_new_map[species_id] = new_species_id + + if world.options.dexsanity and encounter_type != EncounterType.ROCK_SMASH \ + and map_name not in OUT_OF_LOGIC_MAPS: + already_placed.add(new_species_id) + + # Actually create the new list of slots and encounter table + new_slots: List[int] = [] + for species_id in table.slots: + new_slots.append(species_old_to_new_map[species_id]) + + new_encounters[encounter_type] = EncounterTableData(new_slots, table.address) + + # Rock smash encounters not used in logic, so they have no events + if encounter_type != EncounterType.ROCK_SMASH: + _rename_wild_events(world, map_data, new_slots, encounter_type) + + map_data.encounters = new_encounters def randomize_abilities(world: "PokemonEmeraldWorld") -> None: diff --git a/worlds/pokemon_emerald/regions.py b/worlds/pokemon_emerald/regions.py index b74f5f5ebf76..36f3cb7e19a6 100644 --- a/worlds/pokemon_emerald/regions.py +++ b/worlds/pokemon_emerald/regions.py @@ -5,7 +5,7 @@ from BaseClasses import CollectionState, ItemClassification, Region -from .data import data +from .data import EncounterType, data from .items import PokemonEmeraldItem from .locations import PokemonEmeraldLocation @@ -19,11 +19,11 @@ def create_regions(world: "PokemonEmeraldWorld") -> Dict[str, Region]: Also creates and places events and connects regions via warps and the exits defined in the JSON. """ # Used in connect_to_map_encounters. Splits encounter categories into "subcategories" and gives them names - # and rules so the rods can only access their specific slots. - encounter_categories: Dict[str, List[Tuple[Optional[str], range, Optional[Callable[[CollectionState], bool]]]]] = { - "LAND": [(None, range(0, 12), None)], - "WATER": [(None, range(0, 5), None)], - "FISHING": [ + # and rules so the rods can only access their specific slots. Rock smash encounters are not considered in logic. + encounter_categories: Dict[EncounterType, List[Tuple[Optional[str], range, Optional[Callable[[CollectionState], bool]]]]] = { + EncounterType.LAND: [(None, range(0, 12), None)], + EncounterType.WATER: [(None, range(0, 5), None)], + EncounterType.FISHING: [ ("OLD_ROD", range(0, 2), lambda state: state.has("Old Rod", world.player)), ("GOOD_ROD", range(2, 5), lambda state: state.has("Good Rod", world.player)), ("SUPER_ROD", range(5, 10), lambda state: state.has("Super Rod", world.player)), @@ -41,19 +41,19 @@ def connect_to_map_encounters(region: Region, map_name: str, include_slots: Tupl These regions are created lazily and dynamically so as not to bother with unused maps. """ # For each of land, water, and fishing, connect the region if indicated by include_slots - for i, encounter_category in enumerate(encounter_categories.items()): + for i, (encounter_type, subcategories) in enumerate(encounter_categories.items()): if include_slots[i]: - region_name = f"{map_name}_{encounter_category[0]}_ENCOUNTERS" + region_name = f"{map_name}_{encounter_type.value}_ENCOUNTERS" # If the region hasn't been created yet, create it now try: encounter_region = world.multiworld.get_region(region_name, world.player) except KeyError: encounter_region = Region(region_name, world.player, world.multiworld) - encounter_slots = getattr(data.maps[map_name], f"{encounter_category[0].lower()}_encounters").slots + encounter_slots = data.maps[map_name].encounters[encounter_type].slots # Subcategory is for splitting fishing rods; land and water only have one subcategory - for subcategory in encounter_category[1]: + for subcategory in subcategories: # Want to create locations per species, not per slot # encounter_categories includes info on which slots belong to which subcategory unique_species = [] diff --git a/worlds/pokemon_emerald/rom.py b/worlds/pokemon_emerald/rom.py index e2a7a4800bfb..ef87985a27bc 100644 --- a/worlds/pokemon_emerald/rom.py +++ b/worlds/pokemon_emerald/rom.py @@ -696,12 +696,10 @@ def _set_encounter_tables(world: "PokemonEmeraldWorld", patch: PokemonEmeraldPro } """ for map_data in world.modified_maps.values(): - tables = [map_data.land_encounters, map_data.water_encounters, map_data.fishing_encounters] - for table in tables: - if table is not None: - for i, species_id in enumerate(table.slots): - address = table.address + 2 + (4 * i) - patch.write_token(APTokenTypes.WRITE, address, struct.pack(" None: diff --git a/worlds/pokemon_emerald/util.py b/worlds/pokemon_emerald/util.py index f7f02edd95d6..3215113075e9 100644 --- a/worlds/pokemon_emerald/util.py +++ b/worlds/pokemon_emerald/util.py @@ -1,7 +1,7 @@ import orjson from typing import Any, Dict, List, Optional, Tuple, Iterable -from .data import NATIONAL_ID_TO_SPECIES_ID, data +from .data import NATIONAL_ID_TO_SPECIES_ID, EncounterType, data CHARACTER_DECODING_MAP = { @@ -86,6 +86,28 @@ def decode_string(string_data: Iterable[int]) -> str: return string +def get_encounter_type_label(encounter_type: EncounterType, slot: int) -> str: + if encounter_type == EncounterType.FISHING: + return { + 0: "Old Rod", + 1: "Old Rod", + 2: "Good Rod", + 3: "Good Rod", + 4: "Good Rod", + 5: "Super Rod", + 6: "Super Rod", + 7: "Super Rod", + 8: "Super Rod", + 9: "Super Rod", + }[slot] + + return { + EncounterType.LAND: 'Land', + EncounterType.WATER: 'Water', + EncounterType.ROCK_SMASH: 'Rock Smash', + }[encounter_type] + + def get_easter_egg(easter_egg: str) -> Tuple[int, int]: easter_egg = easter_egg.upper() result1 = 0 From 54094c633140daa90547e45985e7257fa5a7fb45 Mon Sep 17 00:00:00 2001 From: Trevor L <80716066+TRPG0@users.noreply.github.com> Date: Sat, 8 Mar 2025 09:59:35 -0700 Subject: [PATCH 0184/1218] Blasphemous: Restrict right half of map start locations to hard difficulty only (#4002) * Start locations, location name * Fix tests --- worlds/blasphemous/Locations.py | 2 +- worlds/blasphemous/__init__.py | 5 +++- .../test/test_starting_locations.py | 30 +------------------ 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/worlds/blasphemous/Locations.py b/worlds/blasphemous/Locations.py index 6c2f71cd3799..fac84313b186 100644 --- a/worlds/blasphemous/Locations.py +++ b/worlds/blasphemous/Locations.py @@ -89,7 +89,7 @@ "RESCUED_CHERUB_15": "DC: Top of elevator Child of Moonlight", "Lady[D01Z05S22]": "DC: Lady of the Six Sorrows, from MD", "QI75": "DC: Chalice room", - "Sword[D01Z05S24]": "DC: Mea culpa altar", + "Sword[D01Z05S24]": "DC: Mea Culpa altar", "CO44": "DC: Elevator shaft ledge", "RESCUED_CHERUB_22": "DC: Elevator shaft Child of Moonlight", "Lady[D01Z05S26]": "DC: Lady of the Six Sorrows, elevator shaft", diff --git a/worlds/blasphemous/__init__.py b/worlds/blasphemous/__init__.py index 4b151f41f860..a643e91c9b89 100644 --- a/worlds/blasphemous/__init__.py +++ b/worlds/blasphemous/__init__.py @@ -67,7 +67,8 @@ def get_filler_item_name(self) -> str: def generate_early(self): if not self.options.starting_location.randomized: - if self.options.starting_location == "mourning_havoc" and self.options.difficulty < 2: + if (self.options.starting_location == "knot_of_words" or self.options.starting_location == "rooftops" \ + or self.options.starting_location == "mourning_havoc") and self.options.difficulty < 2: raise OptionError(f"[Blasphemous - '{self.player_name}'] " f"{self.options.starting_location} cannot be chosen if Difficulty is lower than Hard.") @@ -83,6 +84,8 @@ def generate_early(self): locations: List[int] = [ 0, 1, 2, 3, 4, 5, 6 ] if self.options.difficulty < 2: + locations.remove(4) + locations.remove(5) locations.remove(6) if self.options.dash_shuffle: diff --git a/worlds/blasphemous/test/test_starting_locations.py b/worlds/blasphemous/test/test_starting_locations.py index 9e04d52ef369..1d541bc9696d 100644 --- a/worlds/blasphemous/test/test_starting_locations.py +++ b/worlds/blasphemous/test/test_starting_locations.py @@ -85,20 +85,7 @@ class TestGrievanceHard(BlasphemousTestBase): } -class TestKnotOfWordsEasy(BlasphemousTestBase): - options = { - "starting_location": "knot_of_words", - "difficulty": "easy" - } - - -class TestKnotOfWordsNormal(BlasphemousTestBase): - options = { - "starting_location": "knot_of_words", - "difficulty": "normal" - } - - +# knot of the three words, rooftops, and mourning and havoc can't be selected on easy or normal. hard only class TestKnotOfWordsHard(BlasphemousTestBase): options = { "starting_location": "knot_of_words", @@ -106,20 +93,6 @@ class TestKnotOfWordsHard(BlasphemousTestBase): } -class TestRooftopsEasy(BlasphemousTestBase): - options = { - "starting_location": "rooftops", - "difficulty": "easy" - } - - -class TestRooftopsNormal(BlasphemousTestBase): - options = { - "starting_location": "rooftops", - "difficulty": "normal" - } - - class TestRooftopsHard(BlasphemousTestBase): options = { "starting_location": "rooftops", @@ -127,7 +100,6 @@ class TestRooftopsHard(BlasphemousTestBase): } -# mourning and havoc can't be selected on easy or normal. hard only class TestMourningHavocHard(BlasphemousTestBase): options = { "starting_location": "mourning_havoc", From ce34b607124749ff2564eee79036f69224cc26ef Mon Sep 17 00:00:00 2001 From: josephwhite Date: Sat, 8 Mar 2025 12:07:50 -0500 Subject: [PATCH 0185/1218] Super Mario 64: ItemData class and tables (#4321) * sm64ex: use item data class * rearrange imports * Dict to dict * remove optional typing * bonus item descriptions since we can also add stuff for webworld easily * remove item descriptions (rip) and decrease verbosity for classifications * formatting --- worlds/sm64ex/Items.py | 81 ++++++++++++++++++++++----------------- worlds/sm64ex/Options.py | 4 +- worlds/sm64ex/Rules.py | 7 ++-- worlds/sm64ex/__init__.py | 22 +++++------ 4 files changed, 61 insertions(+), 53 deletions(-) diff --git a/worlds/sm64ex/Items.py b/worlds/sm64ex/Items.py index 546f1abd316b..28fcd744846b 100644 --- a/worlds/sm64ex/Items.py +++ b/worlds/sm64ex/Items.py @@ -1,47 +1,58 @@ -from BaseClasses import Item +from typing import NamedTuple +from BaseClasses import Item, ItemClassification + +sm64ex_base_id: int = 3626000 class SM64Item(Item): game: str = "Super Mario 64" - -generic_item_table = { - "Power Star": 3626000, - "Basement Key": 3626178, - "Second Floor Key": 3626179, - "Progressive Key": 3626180, - "Wing Cap": 3626181, - "Metal Cap": 3626182, - "Vanish Cap": 3626183, - "1Up Mushroom": 3626184 +class SM64ItemData(NamedTuple): + code: int | None = None + classification: ItemClassification = ItemClassification.progression + +generic_item_data_table: dict[str, SM64ItemData] = { + "Power Star": SM64ItemData(sm64ex_base_id + 0, ItemClassification.progression_skip_balancing), + "Basement Key": SM64ItemData(sm64ex_base_id + 178), + "Second Floor Key": SM64ItemData(sm64ex_base_id + 179), + "Progressive Key": SM64ItemData(sm64ex_base_id + 180), + "Wing Cap": SM64ItemData(sm64ex_base_id + 181), + "Metal Cap": SM64ItemData(sm64ex_base_id + 182), + "Vanish Cap": SM64ItemData(sm64ex_base_id + 183), + "1Up Mushroom": SM64ItemData(sm64ex_base_id + 184, ItemClassification.filler), } -action_item_table = { - "Double Jump": 3626185, - "Triple Jump": 3626186, - "Long Jump": 3626187, - "Backflip": 3626188, - "Side Flip": 3626189, - "Wall Kick": 3626190, - "Dive": 3626191, - "Ground Pound": 3626192, - "Kick": 3626193, - "Climb": 3626194, - "Ledge Grab": 3626195 +action_item_data_table: dict[str, SM64ItemData] = { + "Double Jump": SM64ItemData(sm64ex_base_id + 185), + "Triple Jump": SM64ItemData(sm64ex_base_id + 186), + "Long Jump": SM64ItemData(sm64ex_base_id + 187), + "Backflip": SM64ItemData(sm64ex_base_id + 188), + "Side Flip": SM64ItemData(sm64ex_base_id + 189), + "Wall Kick": SM64ItemData(sm64ex_base_id + 190), + "Dive": SM64ItemData(sm64ex_base_id + 191), + "Ground Pound": SM64ItemData(sm64ex_base_id + 192), + "Kick": SM64ItemData(sm64ex_base_id + 193), + "Climb": SM64ItemData(sm64ex_base_id + 194), + "Ledge Grab": SM64ItemData(sm64ex_base_id + 195), } +cannon_item_data_table: dict[str, SM64ItemData] = { + "Cannon Unlock BoB": SM64ItemData(sm64ex_base_id + 200), + "Cannon Unlock WF": SM64ItemData(sm64ex_base_id + 201), + "Cannon Unlock JRB": SM64ItemData(sm64ex_base_id + 202), + "Cannon Unlock CCM": SM64ItemData(sm64ex_base_id + 203), + "Cannon Unlock SSL": SM64ItemData(sm64ex_base_id + 207), + "Cannon Unlock SL": SM64ItemData(sm64ex_base_id + 209), + "Cannon Unlock WDW": SM64ItemData(sm64ex_base_id + 210), + "Cannon Unlock TTM": SM64ItemData(sm64ex_base_id + 211), + "Cannon Unlock THI": SM64ItemData(sm64ex_base_id + 212), + "Cannon Unlock RR": SM64ItemData(sm64ex_base_id + 214), +} -cannon_item_table = { - "Cannon Unlock BoB": 3626200, - "Cannon Unlock WF": 3626201, - "Cannon Unlock JRB": 3626202, - "Cannon Unlock CCM": 3626203, - "Cannon Unlock SSL": 3626207, - "Cannon Unlock SL": 3626209, - "Cannon Unlock WDW": 3626210, - "Cannon Unlock TTM": 3626211, - "Cannon Unlock THI": 3626212, - "Cannon Unlock RR": 3626214 +item_data_table = { + **generic_item_data_table, + **action_item_data_table, + **cannon_item_data_table } -item_table = {**generic_item_table, **action_item_table, **cannon_item_table} \ No newline at end of file +item_table = {name: data.code for name, data in item_data_table.items() if data.code is not None} diff --git a/worlds/sm64ex/Options.py b/worlds/sm64ex/Options.py index 9c428c99590e..47cda7507d23 100644 --- a/worlds/sm64ex/Options.py +++ b/worlds/sm64ex/Options.py @@ -1,7 +1,7 @@ import typing from dataclasses import dataclass from Options import DefaultOnToggle, Range, Toggle, DeathLink, Choice, PerGameCommonOptions, OptionSet, OptionGroup -from .Items import action_item_table +from .Items import action_item_data_table class EnableCoinStars(Choice): """ @@ -135,7 +135,7 @@ class MoveRandomizerActions(OptionSet): """Which actions to randomize when Move Randomizer is enabled""" display_name = "Randomized Moves" # HACK: Disable randomization for double jump - valid_keys = [action for action in action_item_table if action != 'Double Jump'] + valid_keys = [action for action in action_item_data_table if action != 'Double Jump'] default = valid_keys sm64_options_groups = [ diff --git a/worlds/sm64ex/Rules.py b/worlds/sm64ex/Rules.py index 1535f9ca1fde..f5305dab6c71 100644 --- a/worlds/sm64ex/Rules.py +++ b/worlds/sm64ex/Rules.py @@ -6,7 +6,7 @@ from .Options import SM64Options from .Regions import connect_regions, SM64Levels, sm64_level_to_paintings, sm64_paintings_to_level,\ sm64_level_to_secrets, sm64_secrets_to_level, sm64_entrances_to_level, sm64_level_to_entrances -from .Items import action_item_table +from .Items import action_item_data_table def shuffle_dict_keys(world, dictionary: dict) -> dict: keys = list(dictionary.keys()) @@ -372,8 +372,9 @@ def parse_token(self, token: str, cannon_name: str) -> Union[str, bool]: item = self.token_table.get(token, None) if not item: raise Exception(f"Invalid token: '{item}'") - if item in action_item_table: - if self.move_rando_bitvec & (1 << (action_item_table[item] - action_item_table['Double Jump'])) == 0: + if item in action_item_data_table: + double_jump_bitvec_offset = action_item_data_table['Double Jump'].code + if self.move_rando_bitvec & (1 << (action_item_data_table[item].code - double_jump_bitvec_offset)) == 0: # This action item is not randomized. return True return item diff --git a/worlds/sm64ex/__init__.py b/worlds/sm64ex/__init__.py index d54e0fc64d46..33aaa003ad8f 100644 --- a/worlds/sm64ex/__init__.py +++ b/worlds/sm64ex/__init__.py @@ -1,7 +1,7 @@ import typing import os import json -from .Items import item_table, action_item_table, cannon_item_table, SM64Item +from .Items import item_data_table, action_item_data_table, cannon_item_data_table, item_table, SM64Item from .Locations import location_table, SM64Location from .Options import sm64_options_groups, SM64Options from .Rules import set_rules @@ -65,9 +65,10 @@ def generate_early(self): max_stars -= 15 self.move_rando_bitvec = 0 if self.options.enable_move_rando: + double_jump_bitvec_offset = action_item_data_table['Double Jump'].code for action in self.options.move_rando_actions.value: max_stars -= 1 - self.move_rando_bitvec |= (1 << (action_item_table[action] - action_item_table['Double Jump'])) + self.move_rando_bitvec |= (1 << (action_item_data_table[action].code - double_jump_bitvec_offset)) if self.options.exclamation_boxes: max_stars += 29 self.number_of_stars = min(self.options.amount_of_stars, max_stars) @@ -100,14 +101,8 @@ def set_rules(self): 'entrance', self.player) def create_item(self, name: str) -> Item: - item_id = item_table[name] - if name == "1Up Mushroom": - classification = ItemClassification.filler - elif name == "Power Star": - classification = ItemClassification.progression_skip_balancing - else: - classification = ItemClassification.progression - item = SM64Item(name, classification, item_id, self.player) + data = item_data_table[name] + item = SM64Item(name, data.classification, data.code, self.player) return item @@ -131,11 +126,12 @@ def create_items(self): self.multiworld.itempool += [self.create_item(cap_name) for cap_name in ["Wing Cap", "Metal Cap", "Vanish Cap"]] # Cannons if (self.options.buddy_checks): - self.multiworld.itempool += [self.create_item(name) for name, id in cannon_item_table.items()] + self.multiworld.itempool += [self.create_item(cannon_name) for cannon_name in cannon_item_data_table.keys()] # Moves + double_jump_bitvec_offset = action_item_data_table['Double Jump'].code self.multiworld.itempool += [self.create_item(action) - for action, itemid in action_item_table.items() - if self.move_rando_bitvec & (1 << itemid - action_item_table['Double Jump'])] + for action, itemdata in action_item_data_table.items() + if self.move_rando_bitvec & (1 << itemdata.code - double_jump_bitvec_offset)] def generate_basic(self): if not (self.options.buddy_checks): From 4ebabc120802b43734791615a7ee82a7bddfb1f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sat, 8 Mar 2025 12:13:33 -0500 Subject: [PATCH 0186/1218] Stardew Valley: Move filler pool generation out of the world class (#4372) * merge group options so specific handling is not needed when generating filler pool * fix * remove unneeded imports * self review * remove unneeded imports * looks like typing was missing woopsi --- worlds/stardew_valley/__init__.py | 41 +++++++------------ worlds/stardew_valley/items.py | 10 +++++ worlds/stardew_valley/options/worlds_group.py | 14 +++++++ .../test/assertion/goal_assert.py | 4 +- .../test/assertion/option_assert.py | 4 +- 5 files changed, 43 insertions(+), 30 deletions(-) create mode 100644 worlds/stardew_valley/options/worlds_group.py diff --git a/worlds/stardew_valley/__init__.py b/worlds/stardew_valley/__init__.py index e2d49e64ae14..fe690308820b 100644 --- a/worlds/stardew_valley/__init__.py +++ b/worlds/stardew_valley/__init__.py @@ -1,4 +1,5 @@ import logging +import typing from random import Random from typing import Dict, Any, Iterable, Optional, List, TextIO, cast @@ -9,14 +10,15 @@ from .bundles.bundles import get_all_bundles from .content import StardewContent, create_content from .early_items import setup_early_items -from .items import item_table, create_items, ItemData, Group, items_by_group, get_all_filler_items, remove_limited_amount_packs +from .items import item_table, create_items, ItemData, Group, items_by_group, generate_filler_choice_pool from .locations import location_table, create_locations, LocationData, locations_by_tag from .logic.logic import StardewLogic from .options import StardewValleyOptions, SeasonRandomization, Goal, BundleRandomization, EnabledFillerBuffs, NumberOfMovementBuffs, \ - BuildingProgression, ExcludeGingerIsland, TrapItems, EntranceRandomization, FarmType + BuildingProgression, EntranceRandomization, FarmType from .options.forced_options import force_change_options_if_incompatible from .options.option_groups import sv_option_groups from .options.presets import sv_options_presets +from .options.worlds_group import apply_most_restrictive_options from .regions import create_regions from .rules import set_rules from .stardew_rule import True_, StardewRule, HasProgressionPercent @@ -89,6 +91,16 @@ class StardewValleyWorld(World): total_progression_items: int + @classmethod + def create_group(cls, multiworld: MultiWorld, new_player_id: int, players: set[int]) -> World: + world_group = super().create_group(multiworld, new_player_id, players) + + group_options = typing.cast(StardewValleyOptions, world_group.options) + worlds_options = [typing.cast(StardewValleyOptions, multiworld.worlds[player].options) for player in players] + apply_most_restrictive_options(group_options, worlds_options) + + return world_group + def __init__(self, multiworld: MultiWorld, player: int): super().__init__(multiworld, player) self.filler_item_pool_names = [] @@ -299,32 +311,9 @@ def generate_basic(self): def get_filler_item_name(self) -> str: if not self.filler_item_pool_names: - self.generate_filler_item_pool_names() + self.filler_item_pool_names = generate_filler_choice_pool(self.options) return self.random.choice(self.filler_item_pool_names) - def generate_filler_item_pool_names(self): - include_traps, exclude_island = self.get_filler_item_rules() - available_filler = get_all_filler_items(include_traps, exclude_island) - available_filler = remove_limited_amount_packs(available_filler) - self.filler_item_pool_names = [item.name for item in available_filler] - - def get_filler_item_rules(self): - if self.player in self.multiworld.groups: - link_group = self.multiworld.groups[self.player] - include_traps = True - exclude_island = False - for player in link_group["players"]: - if self.multiworld.game[player] != self.game: - continue - player_options = cast(StardewValleyOptions, self.multiworld.worlds[player].options) - if player_options.trap_items == TrapItems.option_no_traps: - include_traps = False - if player_options.exclude_ginger_island == ExcludeGingerIsland.option_true: - exclude_island = True - return include_traps, exclude_island - else: - return self.options.trap_items != TrapItems.option_no_traps, self.options.exclude_ginger_island == ExcludeGingerIsland.option_true - def write_spoiler_header(self, spoiler_handle: TextIO) -> None: """Write to the spoiler header. If individual it's right at the end of that player's options, if as stage it's right under the common header before per-player options.""" diff --git a/worlds/stardew_valley/items.py b/worlds/stardew_valley/items.py index 056a4f6e397d..1fbe012e279c 100644 --- a/worlds/stardew_valley/items.py +++ b/worlds/stardew_valley/items.py @@ -808,6 +808,16 @@ def remove_excluded_items_island_mods(items, exclude_ginger_island: bool, mods: return mod_filter +def generate_filler_choice_pool(options: StardewValleyOptions) -> list[str]: + include_traps = options.trap_items != TrapItems.option_no_traps + exclude_island = options.exclude_ginger_island == ExcludeGingerIsland.option_true + + available_filler = get_all_filler_items(include_traps, exclude_island) + available_filler = remove_limited_amount_packs(available_filler) + + return [item.name for item in available_filler] + + def remove_limited_amount_packs(packs): return [pack for pack in packs if Group.MAXIMUM_ONE not in pack.groups and Group.EXACTLY_TWO not in pack.groups] diff --git a/worlds/stardew_valley/options/worlds_group.py b/worlds/stardew_valley/options/worlds_group.py new file mode 100644 index 000000000000..bbf508c61c04 --- /dev/null +++ b/worlds/stardew_valley/options/worlds_group.py @@ -0,0 +1,14 @@ +from typing import Iterable + +from .options import StardewValleyOptions + + +def apply_most_restrictive_options(group_option: StardewValleyOptions, world_options: Iterable[StardewValleyOptions]) -> None: + """Merge the options of the worlds member of the group that can impact fillers generation into the option class of the group. + """ + + # If at least one world disabled ginger island, disabling it for the whole group + group_option.exclude_ginger_island.value = max(o.exclude_ginger_island.value for o in world_options) + + # If at least one world disabled traps, disabling them for the whole group + group_option.trap_items.value = min(o.trap_items.value for o in world_options) diff --git a/worlds/stardew_valley/test/assertion/goal_assert.py b/worlds/stardew_valley/test/assertion/goal_assert.py index 2b2efbf2ec03..3ba40d5a84b8 100644 --- a/worlds/stardew_valley/test/assertion/goal_assert.py +++ b/worlds/stardew_valley/test/assertion/goal_assert.py @@ -2,7 +2,7 @@ from BaseClasses import MultiWorld from .option_assert import get_stardew_options -from ... import options, ExcludeGingerIsland +from ... import options def is_goal(multiworld: MultiWorld, goal: int) -> bool: @@ -36,7 +36,7 @@ def is_not_perfection(multiworld: MultiWorld) -> bool: class GoalAssertMixin(TestCase): def assert_ginger_island_is_included(self, multiworld: MultiWorld): - self.assertEqual(get_stardew_options(multiworld).exclude_ginger_island, ExcludeGingerIsland.option_false) + self.assertEqual(get_stardew_options(multiworld).exclude_ginger_island, options.ExcludeGingerIsland.option_false) def assert_walnut_hunter_world_is_valid(self, multiworld: MultiWorld): if is_not_walnut_hunter(multiworld): diff --git a/worlds/stardew_valley/test/assertion/option_assert.py b/worlds/stardew_valley/test/assertion/option_assert.py index a07831f73e3f..ed7842bf8d98 100644 --- a/worlds/stardew_valley/test/assertion/option_assert.py +++ b/worlds/stardew_valley/test/assertion/option_assert.py @@ -2,7 +2,7 @@ from BaseClasses import MultiWorld from .world_assert import get_all_item_names, get_all_location_names -from ... import StardewValleyWorld, options, item_table, Group, location_table, ExcludeGingerIsland +from ... import StardewValleyWorld, options, item_table, Group, location_table from ...locations import LocationTags from ...strings.ap_names.transport_names import Transportation @@ -49,7 +49,7 @@ def assert_cannot_reach_island(self, multiworld: MultiWorld): def assert_can_reach_island_if_should(self, multiworld: MultiWorld): stardew_options = get_stardew_options(multiworld) - include_island = stardew_options.exclude_ginger_island.value == ExcludeGingerIsland.option_false + include_island = stardew_options.exclude_ginger_island.value == options.ExcludeGingerIsland.option_false if include_island: self.assert_can_reach_island(multiworld) else: From 2639796255d820d720e086e905e19226af2cbd4d Mon Sep 17 00:00:00 2001 From: jamesbrq Date: Sun, 9 Mar 2025 11:37:15 -0400 Subject: [PATCH 0187/1218] MLSS: Add new goal + Update basepatch to standalone equivalent (#4409) * Item groups + small changes * Add alternate goal * New Locations and Logic Updates + Basepatch * Update basepatch.bsdiff * Update Basepatch * Update basepatch.bsdiff * Update bowsers castle logic with emblem hunt * Update Archipelago Unittests.run.xml * Update Archipelago Unittests.run.xml * Fix for overlapping ROM addresses * Update Rom.py * Update __init__.py * Update basepatch.bsdiff * Update Rom.py * Update client with new helper function * Update basepatch.bsdiff * Update worlds/mlss/__init__.py Co-authored-by: qwint * Update worlds/mlss/__init__.py Co-authored-by: qwint * Review Refactor * Review Refactor --------- Co-authored-by: qwint --- worlds/mlss/Client.py | 2 +- worlds/mlss/Data.py | 2 +- worlds/mlss/Items.py | 8 +++ worlds/mlss/Locations.py | 16 +++-- worlds/mlss/Names/LocationName.py | 8 +-- worlds/mlss/Options.py | 45 ++++++++++-- worlds/mlss/Regions.py | 24 +++++-- worlds/mlss/Rom.py | 16 +++-- worlds/mlss/Rules.py | 116 ++++++++++++++++++++++++++++-- worlds/mlss/StateLogic.py | 23 +++++- worlds/mlss/__init__.py | 13 +++- worlds/mlss/data/basepatch.bsdiff | Bin 18482 -> 21812 bytes 12 files changed, 234 insertions(+), 39 deletions(-) diff --git a/worlds/mlss/Client.py b/worlds/mlss/Client.py index 75f6ac653003..17d87197ca84 100644 --- a/worlds/mlss/Client.py +++ b/worlds/mlss/Client.py @@ -269,7 +269,7 @@ async def game_watcher(self, ctx: "BizHawkClientContext") -> None: self.local_checked_locations = locs_to_send if locs_to_send is not None: - await ctx.send_msgs([{"cmd": "LocationChecks", "locations": list(locs_to_send)}]) + await ctx.check_locations(locs_to_send) except bizhawk.RequestFailedError: # Exit handler and return to main loop to reconnect. diff --git a/worlds/mlss/Data.py b/worlds/mlss/Data.py index add14aa008f1..7e3605f13879 100644 --- a/worlds/mlss/Data.py +++ b/worlds/mlss/Data.py @@ -153,7 +153,6 @@ 0x50458C, 0x5045AC, 0x50468C, - # 0x5046CC, 6 enemy formation 0x5046EC, 0x50470C ] @@ -166,6 +165,7 @@ 0x50360C, 0x5037AC, 0x5037CC, + 0x50396C, 0x503A8C, 0x503D6C, 0x503F0C, diff --git a/worlds/mlss/Items.py b/worlds/mlss/Items.py index 717443ddfc06..5fca829b22dd 100644 --- a/worlds/mlss/Items.py +++ b/worlds/mlss/Items.py @@ -160,6 +160,7 @@ class MLSSItem(Item): ItemData(77771142, "Game Boy Horror SP", ItemClassification.useful, 0xFE), ItemData(77771143, "Woo Bean", ItemClassification.skip_balancing, 0x1C), ItemData(77771144, "Hee Bean", ItemClassification.skip_balancing, 0x1F), + ItemData(77771145, "Beanstar Emblem", ItemClassification.progression, 0x3E), ] item_frequencies: typing.Dict[str, int] = { @@ -186,5 +187,12 @@ class MLSSItem(Item): "Hammers": 3, } +mlss_item_name_groups = { + "Beanstar Piece": { "Beanstar Piece 1", "Beanstar Piece 2", "Beanstar Piece 3", "Beanstar Piece 4"}, + "Beanfruit": { "Bean Fruit 1", "Bean Fruit 2", "Bean Fruit 3", "Bean Fruit 4", "Bean Fruit 5", "Bean Fruit 6", "Bean Fruit 7"}, + "Neon Egg": { "Blue Neon Egg", "Red Neon Egg", "Green Neon Egg", "Yellow Neon Egg", "Purple Neon Egg", "Orange Neon Egg", "Azure Neon Egg"}, + "Chuckola Fruit": { "Red Chuckola Fruit", "Purple Chuckola Fruit", "White Chuckola Fruit"} +} + item_table: typing.Dict[str, ItemData] = {item.itemName: item for item in itemList} items_by_id: typing.Dict[int, ItemData] = {item.code: item for item in itemList} diff --git a/worlds/mlss/Locations.py b/worlds/mlss/Locations.py index a2787ef9b1b1..9a114bc470a5 100644 --- a/worlds/mlss/Locations.py +++ b/worlds/mlss/Locations.py @@ -251,9 +251,9 @@ class MLSSLocation(Location): LocationData("Hoohoo Village North Cave Room 1 Coin Block", 0x39DAA0, 0), LocationData("Hoohoo Village South Cave Coin Block 1", 0x39DAC5, 0), LocationData("Hoohoo Village South Cave Coin Block 2", 0x39DAD5, 0), - LocationData("Hoohoo Mountain Base Boo Statue Cave Coin Block 1", 0x39DAE2, 0), - LocationData("Hoohoo Mountain Base Boo Statue Cave Coin Block 2", 0x39DAF2, 0), - LocationData("Hoohoo Mountain Base Boo Statue Cave Coin Block 3", 0x39DAFA, 0), + LocationData("Hoohoo Mountain Base Boostatue Cave Coin Block 1", 0x39DAE2, 0), + LocationData("Hoohoo Mountain Base Boostatue Cave Coin Block 2", 0x39DAF2, 0), + LocationData("Hoohoo Mountain Base Boostatue Cave Coin Block 3", 0x39DAFA, 0), LocationData("Beanbean Outskirts NW Coin Block", 0x39DB8F, 0), LocationData("Beanbean Outskirts S Room 1 Coin Block", 0x39DC18, 0), LocationData("Beanbean Outskirts S Room 2 Coin Block", 0x39DC3D, 0), @@ -262,6 +262,8 @@ class MLSSLocation(Location): LocationData("Chucklehuck Woods Cave Room 1 Coin Block", 0x39DD7A, 0), LocationData("Chucklehuck Woods Cave Room 2 Coin Block", 0x39DD97, 0), LocationData("Chucklehuck Woods Cave Room 3 Coin Block", 0x39DDB4, 0), + LocationData("Chucklehuck Woods Solo Luigi Cave Room 1 Coin Block 1", 0x39DB48, 0), + LocationData("Chucklehuck Woods Solo Luigi Cave Room 1 Coin Block 2", 0x39DB50, 0), LocationData("Chucklehuck Woods Pipe 5 Room Coin Block", 0x39DDE6, 0), LocationData("Chucklehuck Woods Room 7 Coin Block", 0x39DE31, 0), LocationData("Chucklehuck Woods Past Chuckleroot Coin Block", 0x39DF14, 0), @@ -289,6 +291,7 @@ class MLSSLocation(Location): LocationData("Teehee Valley Upper Maze Room 1 Block", 0x39E5E0, 0), LocationData("Teehee Valley Upper Maze Room 2 Digspot 1", 0x39E5C8, 0), LocationData("Teehee Valley Upper Maze Room 2 Digspot 2", 0x39E5D0, 0), + LocationData("Guffawha Ruins Block", 0x39E6A3, 0), LocationData("Hoohoo Mountain Base Guffawha Ruins Entrance Digspot", 0x39DA0B, 0), LocationData("Hoohoo Mountain Base Teehee Valley Entrance Digspot", 0x39DA20, 0), LocationData("Hoohoo Mountain Base Teehee Valley Entrance Block", 0x39DA18, 0), @@ -298,7 +301,7 @@ class MLSSLocation(Location): LocationData("Beanbean Outskirts Before Harhall Digspot 1", 0x39E951, 0), LocationData("Beanbean Outskirts Before Harhall Digspot 2", 0x39E959, 0), LocationData("Beanstar Piece Harhall", 0x1E9441, 2), - LocationData("Beanbean Outskirts Boo Statue Mole", 0x1E9434, 2), + LocationData("Beanbean Outskirts Boostatue Mole", 0x1E9434, 2), LocationData("Harhall's Pants", 0x1E9444, 2), LocationData("Beanbean Outskirts S Room 2 Digspot 1", 0x39DC65, 0), LocationData("Beanbean Outskirts S Room 2 Digspot 2", 0x39DC5D, 0), @@ -317,6 +320,9 @@ class MLSSLocation(Location): LocationData("Chucklehuck Woods Cave Room 1 Block 2", 0x39DD8A, 0), LocationData("Chucklehuck Woods Cave Room 2 Block", 0x39DD9F, 0), LocationData("Chucklehuck Woods Cave Room 3 Block", 0x39DDAC, 0), + LocationData("Chucklehuck Woods Solo Luigi Cave Room 2 Block", 0x39DB72, 0), + LocationData("Chucklehuck Woods Solo Luigi Cave Room 3 Block 1", 0x39DB5D, 0), + LocationData("Chucklehuck Woods Solo Luigi Cave Room 3 Block 2", 0x39DB65, 0), LocationData("Chucklehuck Woods Room 2 Block", 0x39DDC1, 0), LocationData("Chucklehuck Woods Room 2 Digspot", 0x39DDC9, 0), LocationData("Chucklehuck Woods Pipe Room Block 1", 0x39DDD6, 0), @@ -786,7 +792,7 @@ class MLSSLocation(Location): (0x4373, 0x10, 0x277A45), # Teehee Valley Mole (0x434D, 0x8, 0x1E9444), # Harhall's Pants (0x432E, 0x10, 0x1E9441), # Harhall Beanstar Piece - (0x434B, 0x8, 0x1E9434), # Outskirts Boo Statue Mole + (0x434B, 0x8, 0x1E9434), # Outskirts Boostatue Mole (0x42FE, 0x2, 0x1E943E), # Red Goblet (0x42FE, 0x4, 0x24E628), # Green Goblet (0x4301, 0x10, 0x250621), # Red Chuckola Fruit diff --git a/worlds/mlss/Names/LocationName.py b/worlds/mlss/Names/LocationName.py index 5b38b2a10f6e..43b75bf5d71c 100644 --- a/worlds/mlss/Names/LocationName.py +++ b/worlds/mlss/Names/LocationName.py @@ -59,7 +59,7 @@ class LocationName: HoohooMountainBaseBoostatueRoomDigspot1 = "Hoohoo Mountain Base Boostatue Room Digspot 1" HoohooMountainBaseBoostatueRoomDigspot2 = "Hoohoo Mountain Base Boostatue Room Digspot 2" HoohooMountainBaseBoostatueRoomDigspot3 = "Hoohoo Mountain Base Boostatue Room Digspot 3" - BeanbeanOutskirtsBooStatueMole = "Beanbean Outskirts Boo Statue Mole" + BeanbeanOutskirtsBooStatueMole = "Beanbean Outskirts Boostatue Mole" HoohooMountainBaseGrassyAreaBlock1 = "Hoohoo Mountain Base Grassy Area Block 1" HoohooMountainBaseGrassyAreaBlock2 = "Hoohoo Mountain Base Grassy Area Block 2" HoohooMountainBaseGuffawhaRuinsEntranceDigspot = "Hoohoo Mountain Base Guffawha Ruins Entrance Digspot" @@ -533,9 +533,9 @@ class LocationName: BadgeShopMomPiranhaFlag2 = "Badge Shop Mom Piranha Flag 2" BadgeShopMomPiranhaFlag3 = "Badge Shop Mom Piranha Flag 3" HarhallsPants = "Harhall's Pants" - HoohooMountainBaseBooStatueCaveCoinBlock1 = "Hoohoo Mountain Base Boo Statue Cave Coin Block 1" - HoohooMountainBaseBooStatueCaveCoinBlock2 = "Hoohoo Mountain Base Boo Statue Cave Coin Block 2" - HoohooMountainBaseBooStatueCaveCoinBlock3 = "Hoohoo Mountain Base Boo Statue Cave Coin Block 3" + HoohooMountainBaseBooStatueCaveCoinBlock1 = "Hoohoo Mountain Base Boostatue Cave Coin Block 1" + HoohooMountainBaseBooStatueCaveCoinBlock2 = "Hoohoo Mountain Base Boostatue Cave Coin Block 2" + HoohooMountainBaseBooStatueCaveCoinBlock3 = "Hoohoo Mountain Base Boostatue Cave Coin Block 3" BeanbeanOutskirtsNWCoinBlock = "Beanbean Outskirts NW Coin Block" BeanbeanOutskirtsSRoom1CoinBlock = "Beanbean Outskirts S Room 1 Coin Block" BeanbeanOutskirtsSRoom2CoinBlock = "Beanbean Outskirts S Room 2 Coin Block" diff --git a/worlds/mlss/Options.py b/worlds/mlss/Options.py index 73e8ebd4015f..dbf581b232b1 100644 --- a/worlds/mlss/Options.py +++ b/worlds/mlss/Options.py @@ -2,13 +2,13 @@ from dataclasses import dataclass -class BowsersCastleSkip(Toggle): +class SkipBowsersCastle(Toggle): """ - Skip straight from the entrance hall to Bowletta in Bowser's Castle. + Skip straight from the Entrance Hall to Bowletta in Bowser's Castle. All Bowser's Castle locations will be removed from the location pool. """ - display_name = "Bowser's Castle Skip" + display_name = "Skip Bowser's Castle" class ExtraPipes(Toggle): @@ -272,13 +272,47 @@ class ChuckleBeans(Choice): option_all = 2 default = 2 +class Goal(Choice): + """ + Vanilla: Complete jokes end with the required items and defeat Birdo to unlock Bowser's Castle. + + Emblem Hunt: Find the required number of Beanstar Emblems to gain access to Bowser's Castle. + """ + display_name = "Goal" + option_vanilla = 0 + option_emblem_hunt = 1 + default = 0 + +class EmblemsRequired(Range): + """ + Number of Beanstar Emblems to collect to unlock Bowser's Castle. + + If Goal is not Emblem Hunt, this does nothing. + """ + display_name = "Emblems Required" + range_start = 1 + range_end = 100 + default = 50 + + +class EmblemsAmount(Range): + """ + Number of Beanstar Emblems that are in the pool. + + If Goal is not Emblem Hunt, this does nothing. + """ + display_name = "Emblems Available" + range_start = 1 + range_end = 150 + default = 75 + @dataclass class MLSSOptions(PerGameCommonOptions): start_inventory_from_pool: StartInventoryPool coins: Coins difficult_logic: DifficultLogic - castle_skip: BowsersCastleSkip + castle_skip: SkipBowsersCastle extra_pipes: ExtraPipes skip_minecart: SkipMinecart disable_surf: DisableSurf @@ -286,6 +320,9 @@ class MLSSOptions(PerGameCommonOptions): harhalls_pants: Removed block_visibility: HiddenVisible chuckle_beans: ChuckleBeans + goal: Goal + emblems_required: EmblemsRequired + emblems_amount: EmblemsAmount music_options: MusicOptions randomize_sounds: RandomSounds randomize_enemies: RandomizeEnemies diff --git a/worlds/mlss/Regions.py b/worlds/mlss/Regions.py index 7dd5e9451141..e9008b86f16c 100644 --- a/worlds/mlss/Regions.py +++ b/worlds/mlss/Regions.py @@ -91,6 +91,16 @@ def connect_regions(world: "MLSSWorld"): connect(world, names, "Main Area", "BaseUltraRocks", lambda state: StateLogic.ultra(state, world.player)) connect(world, names, "Main Area", "Chucklehuck Woods", lambda state: StateLogic.brooch(state, world.player)) connect(world, names, "Main Area", "BooStatue", lambda state: StateLogic.canCrash(state, world.player)) + if world.options.goal == "emblem_hunt": + if world.options.castle_skip: + connect(world, names, "Main Area", "Cackletta's Soul", + lambda state: state.has("Beanstar Emblem", world.player, world.options.emblems_required.value)) + else: + connect(world, names, "Main Area", "Bowser's Castle", lambda state: state.has("Beanstar Emblem", world.player, world.options.emblems_required.value)) + connect(world, names, "Bowser's Castle", "Bowser's Castle Mini", lambda state: + StateLogic.canMini(state, world.player) + and StateLogic.thunder(state,world.player)) + connect(world, names, "Bowser's Castle Mini", "Cackletta's Soul", lambda state: StateLogic.soul(state, world.player)) connect( world, names, @@ -213,8 +223,8 @@ def connect_regions(world: "MLSSWorld"): connect(world, names, "Surfable", "GwarharEntrance") connect(world, names, "Surfable", "Oasis") connect(world, names, "Surfable", "JokesEntrance", lambda state: StateLogic.fire(state, world.player)) - connect(world, names, "JokesMain", "PostJokes", lambda state: StateLogic.postJokes(state, world.player)) - if not world.options.castle_skip: + connect(world, names, "JokesMain", "PostJokes", lambda state: StateLogic.postJokes(state, world.player, world.options.goal.value)) + if not world.options.castle_skip and world.options.goal != "emblem_hunt": connect(world, names, "PostJokes", "Bowser's Castle") connect( world, @@ -224,7 +234,7 @@ def connect_regions(world: "MLSSWorld"): lambda state: StateLogic.canMini(state, world.player) and StateLogic.thunder(state, world.player), ) connect(world, names, "Bowser's Castle Mini", "Cackletta's Soul") - else: + elif world.options.goal != "emblem_hunt": connect(world, names, "PostJokes", "Cackletta's Soul") connect(world, names, "Chucklehuck Woods", "Winkle", lambda state: StateLogic.canDash(state, world.player)) connect( @@ -247,14 +257,14 @@ def connect_regions(world: "MLSSWorld"): names, "Shop Starting Flag", "Shop Birdo Flag", - lambda state: StateLogic.postJokes(state, world.player), + lambda state: StateLogic.postJokes(state, world.player, world.options.goal.value), ) connect( world, names, "Fungitown", "Fungitown Shop Birdo Flag", - lambda state: StateLogic.postJokes(state, world.player), + lambda state: StateLogic.postJokes(state, world.player, world.options.goal.value), ) else: connect( @@ -276,14 +286,14 @@ def connect_regions(world: "MLSSWorld"): names, "Shop Starting Flag", "Shop Birdo Flag", - lambda state: StateLogic.canCrash(state, world.player) and StateLogic.postJokes(state, world.player), + lambda state: StateLogic.canCrash(state, world.player) and StateLogic.postJokes(state, world.player, world.options.goal.value), ) connect( world, names, "Fungitown", "Fungitown Shop Birdo Flag", - lambda state: StateLogic.canCrash(state, world.player) and StateLogic.postJokes(state, world.player), + lambda state: StateLogic.canCrash(state, world.player) and StateLogic.postJokes(state, world.player, world.options.goal.value), ) diff --git a/worlds/mlss/Rom.py b/worlds/mlss/Rom.py index 03eac040efb2..c83c01218275 100644 --- a/worlds/mlss/Rom.py +++ b/worlds/mlss/Rom.py @@ -177,10 +177,10 @@ def enemy_randomize(caller: APProcedurePatch, rom: bytes): for pos in enemies: stream.seek(pos + 8) for _ in range(6): - enemy = int.from_bytes(stream.read(1)) + enemy = int.from_bytes(stream.read(1), "little") if enemy > 0: stream.seek(1, 1) - flag = int.from_bytes(stream.read(1)) + flag = int.from_bytes(stream.read(1), "little") if flag == 0x7: break if flag in [0x0, 0x2, 0x4]: @@ -196,12 +196,12 @@ def enemy_randomize(caller: APProcedurePatch, rom: bytes): stream.seek(pos + 8) for _ in range(6): - enemy = int.from_bytes(stream.read(1)) + enemy = int.from_bytes(stream.read(1), "little") if enemy > 0 and enemy not in Data.flying and enemy not in Data.pestnut: if enemy == 0x52: chomp = True stream.seek(1, 1) - flag = int.from_bytes(stream.read(1)) + flag = int.from_bytes(stream.read(1), "little") if flag not in [0x0, 0x2, 0x4]: stream.seek(1, 1) continue @@ -234,7 +234,7 @@ def enemy_randomize(caller: APProcedurePatch, rom: bytes): stream.seek(pos) temp = stream.read(1) stream.seek(pos) - stream.write(bytes([temp[0] | 0x8])) + stream.write(bytes([temp[0] | 0x80])) stream.seek(pos + 1) stream.write(groups.pop()) @@ -316,6 +316,10 @@ def write_tokens(world: "MLSSWorld", patch: MLSSProcedurePatch) -> None: patch.write_token(APTokenTypes.WRITE, 0xD00003, bytes([world.options.xp_multiplier.value])) + if world.options.goal == 1: + patch.write_token(APTokenTypes.WRITE, 0xD00008, bytes([world.options.goal.value])) + patch.write_token(APTokenTypes.WRITE, 0xD00009, bytes([world.options.emblems_required.value])) + if world.options.tattle_hp: patch.write_token(APTokenTypes.WRITE, 0xD00000, bytes([0x1])) @@ -427,4 +431,4 @@ def desc_inject(world: "MLSSWorld", patch: MLSSProcedurePatch, location: Locatio index = value.index(location.address) + 66 dstring = f"{world.multiworld.player_name[item.player]}: {item.name}" - patch.write_token(APTokenTypes.WRITE, 0xD11000 + (index * 0x40), dstring.encode("UTF8")) + patch.write_token(APTokenTypes.WRITE, 0xD12000 + (index * 0x40), dstring.encode("UTF8")) diff --git a/worlds/mlss/Rules.py b/worlds/mlss/Rules.py index b0b5a36465e2..6592a805d56a 100644 --- a/worlds/mlss/Rules.py +++ b/worlds/mlss/Rules.py @@ -28,11 +28,14 @@ def set_rules(world: "MLSSWorld", excluded): lambda state: StateLogic.canDig(state, world.player), ) if "Shop" in location.name and "Coffee" not in location.name and location.name not in excluded: - forbid_item(world.get_location(location.name), "Hammers", world.player) if "Badge" in location.name or "Pants" in location.name: add_rule( world.get_location(location.name), - lambda state: StateLogic.brooch(state, world.player) or StateLogic.rose(state, world.player), + lambda state: (StateLogic.brooch(state, world.player) and StateLogic.fruits(state, world.player) + and (StateLogic.hammers(state, world.player) + or StateLogic.fire(state, world.player) + or StateLogic.thunder(state, world.player))) + or StateLogic.rose(state, world.player), ) if location.itemType != 0 and location.name not in excluded: if "Bowser" in location.name and world.options.castle_skip: @@ -99,9 +102,86 @@ def set_rules(world: "MLSSWorld", excluded): lambda state: StateLogic.ultra(state, world.player) and StateLogic.thunder(state, world.player), ) - forbid_item( - world.get_location(LocationName.SSChuckolaMembershipCard), "Nuts", world.player - ) # Bandaid Fix + if world.options.goal == 1 and not world.options.castle_skip: + add_rule( + world.get_location(LocationName.BowsersCastleRoyCorridorBlock1), + lambda state: StateLogic.canDig(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleRoyCorridorBlock2), + lambda state: StateLogic.canDig(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleMiniMarioSidescrollerBlock1), + lambda state: StateLogic.canDig(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleMiniMarioSidescrollerBlock2), + lambda state: StateLogic.canDig(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleMiniMarioMazeBlock1), + lambda state: StateLogic.canDig(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleMiniMarioMazeBlock2), + lambda state: StateLogic.canDig(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleBeforeWendyFightBlock1), + lambda state: StateLogic.canDig(state, world.player) + and StateLogic.ultra(state, world.player) + and StateLogic.fire(state, world.player) + and StateLogic.canCrash(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleBeforeWendyFightBlock2), + lambda state: StateLogic.canDig(state, world.player) + and StateLogic.ultra(state, world.player) + and StateLogic.fire(state, world.player) + and StateLogic.canCrash(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleLarryRoomBlock), + lambda state: StateLogic.canDig(state, world.player) + and StateLogic.ultra(state, world.player) + and StateLogic.canDash(state, world.player) + and StateLogic.canCrash(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleWendyLarryHallwayDigspot), + lambda state: StateLogic.ultra(state, world.player) + and StateLogic.fire(state, world.player) + and StateLogic.canCrash(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleBeforeFawfulFightBlock1), + lambda state: StateLogic.canDig(state, world.player) + and StateLogic.ultra(state, world.player) + and StateLogic.canDash(state, world.player) + and StateLogic.canCrash(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleBeforeFawfulFightBlock2), + lambda state: StateLogic.canDig(state, world.player) + and StateLogic.ultra(state, world.player) + and StateLogic.canDash(state, world.player) + and StateLogic.canCrash(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleGreatDoorBlock1), + lambda state: StateLogic.canDig(state, world.player) + and StateLogic.ultra(state, world.player) + and StateLogic.canDash(state, world.player) + and StateLogic.canCrash(state, world.player) + ) + add_rule( + world.get_location(LocationName.BowsersCastleGreatDoorBlock2), + lambda state: StateLogic.canDig(state, world.player) + and StateLogic.ultra(state, world.player) + and StateLogic.canDash(state, world.player) + and StateLogic.canCrash(state, world.player) + ) add_rule( world.get_location(LocationName.HoohooVillageHammerHouseBlock), @@ -398,6 +478,10 @@ def set_rules(world: "MLSSWorld", excluded): world.get_location(LocationName.BeanstarPieceWinkleArea), lambda state: StateLogic.winkle(state, world.player), ) + add_rule( + world.get_location("Guffawha Ruins Block"), + lambda state: StateLogic.thunder(state, world.player), + ) add_rule( world.get_location(LocationName.GwarharLagoonSpangleReward), lambda state: StateLogic.spangle(state, world.player), @@ -406,6 +490,18 @@ def set_rules(world: "MLSSWorld", excluded): world.get_location(LocationName.PantsShopMomPiranhaFlag1), lambda state: StateLogic.brooch(state, world.player) or StateLogic.rose(state, world.player), ) + add_rule( + world.get_location("Chucklehuck Woods Solo Luigi Cave Room 2 Block"), + lambda state: StateLogic.brooch(state, world.player) and StateLogic.canDig(state, world.player), + ) + add_rule( + world.get_location("Chucklehuck Woods Solo Luigi Cave Room 3 Block 1"), + lambda state: StateLogic.brooch(state, world.player) and StateLogic.canDig(state, world.player), + ) + add_rule( + world.get_location("Chucklehuck Woods Solo Luigi Cave Room 3 Block 2"), + lambda state: StateLogic.brooch(state, world.player) and StateLogic.canDig(state, world.player), + ) add_rule( world.get_location(LocationName.PantsShopMomPiranhaFlag2), lambda state: StateLogic.brooch(state, world.player) or StateLogic.rose(state, world.player), @@ -600,6 +696,14 @@ def set_rules(world: "MLSSWorld", excluded): world.get_location(LocationName.HoohooMountainBaseBooStatueCaveCoinBlock1), lambda state: StateLogic.canCrash(state, world.player) or StateLogic.super(state, world.player), ) + add_rule( + world.get_location("Chucklehuck Woods Solo Luigi Cave Room 1 Coin Block 1"), + lambda state: StateLogic.canDig(state, world.player) and StateLogic.brooch(state, world.player), + ) + add_rule( + world.get_location("Chucklehuck Woods Solo Luigi Cave Room 1 Coin Block 2"), + lambda state: StateLogic.canDig(state, world.player) and StateLogic.brooch(state, world.player), + ) add_rule( world.get_location(LocationName.HoohooMountainBaseBooStatueCaveCoinBlock2), lambda state: StateLogic.canCrash(state, world.player) or StateLogic.super(state, world.player), @@ -679,7 +783,7 @@ def set_rules(world: "MLSSWorld", excluded): add_rule( world.get_location(LocationName.GwarharLagoonFirstUnderwaterAreaRoom2CoinBlock), lambda state: StateLogic.canDash(state, world.player) - and (StateLogic.membership(state, world.player) or StateLogic.surfable(state, world.player)), + and (StateLogic.membership(state, world.player) or StateLogic.surfable(state, world.player)), ) add_rule( world.get_location(LocationName.JokesEndSecondFloorWestRoomCoinBlock), diff --git a/worlds/mlss/StateLogic.py b/worlds/mlss/StateLogic.py index 39f08e169ef5..74ad5aa3d7eb 100644 --- a/worlds/mlss/StateLogic.py +++ b/worlds/mlss/StateLogic.py @@ -1,3 +1,6 @@ +from .Options import Goal + + def canDig(state, player): return state.has("Green Goblet", player) and state.has("Hammers", player) @@ -105,8 +108,9 @@ def surfable(state, player): ) -def postJokes(state, player): - return ( +def postJokes(state, player, goal): + if goal == Goal.option_vanilla: # Logic for beating jokes end without beanstar emblems + return ( surfable(state, player) and canDig(state, player) and dressBeanstar(state, player) @@ -115,7 +119,13 @@ def postJokes(state, player): and brooch(state, player) and rose(state, player) and canDash(state, player) - ) + ) + else: # Logic for beating jokes end with beanstar emblems + return ( + surfable(state, player) + and canDig(state, player) + and canDash(state, player) + ) def teehee(state, player): @@ -153,3 +163,10 @@ def birdo_shop(state, player): def fungitown_birdo_shop(state, player): return state.can_reach("Fungitown Shop Birdo Flag", "Region", player) + +def soul(state, player): + return (ultra(state, player) + and canMini(state, player) + and canDig(state, player) + and canDash(state, player) + and canCrash(state, player)) diff --git a/worlds/mlss/__init__.py b/worlds/mlss/__init__.py index bb7ed0515419..103597958509 100644 --- a/worlds/mlss/__init__.py +++ b/worlds/mlss/__init__.py @@ -1,3 +1,4 @@ +import logging import os import pkgutil import typing @@ -7,7 +8,7 @@ from typing import Set, Dict, Any from .Locations import all_locations, location_table, bowsers, bowsersMini, hidden, coins from .Options import MLSSOptions -from .Items import MLSSItem, itemList, item_frequencies, item_table +from .Items import MLSSItem, itemList, item_frequencies, item_table, mlss_item_name_groups from .Names.LocationName import LocationName from .Client import MLSSClient from .Regions import create_regions, connect_regions @@ -53,6 +54,7 @@ class MLSSWorld(World): options_dataclass = MLSSOptions options: MLSSOptions settings: typing.ClassVar[MLSSSettings] + item_name_groups = mlss_item_name_groups item_name_to_id = {name: data.code for name, data in item_table.items()} location_name_to_id = {loc_data.name: loc_data.id for loc_data in all_locations} required_client_version = (0, 5, 0) @@ -61,6 +63,12 @@ class MLSSWorld(World): def generate_early(self) -> None: self.disabled_locations = set() + if self.options.goal == "emblem_hunt": + if self.options.emblems_amount < self.options.emblems_required: + self.options.emblems_amount.value = self.options.emblems_required.value + logging.warning( + f"{self.player_name}'s number of emblems required is greater than the number of emblems available. " + f"Changing to {self.options.emblems_required.value}.") if self.options.skip_minecart: self.disabled_locations.update([LocationName.HoohooMountainBaseMinecartCaveDigspot]) if self.options.disable_surf: @@ -111,6 +119,8 @@ def create_items(self) -> None: for item in itemList: if item.classification != ItemClassification.filler and item.classification != ItemClassification.skip_balancing: freq = item_frequencies.get(item.itemName, 1) + if item.itemName == "Beanstar Emblem": + freq = (0 if self.options.goal != "emblem_hunt" else self.options.emblems_amount.value) if item in precollected: freq = max(freq - precollected.count(item), 0) if self.options.disable_harhalls_pants and "Harhall's" in item.itemName: @@ -138,7 +148,6 @@ def create_items(self) -> None: # And finally take as many fillers as we need to have the same amount of items and locations. remaining = len(all_locations) - len(required_items) - len(self.disabled_locations) - 5 - self.multiworld.itempool += [ self.create_item(filler_item_name) for filler_item_name in self.random.sample(filler_items, remaining) ] diff --git a/worlds/mlss/data/basepatch.bsdiff b/worlds/mlss/data/basepatch.bsdiff index 7ed6c38ea9f432dfcf506156c77e4f56bdf3026a..18d6b56e59b746ecb6c7f3db8d297e2accc305c4 100644 GIT binary patch literal 21812 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 SIR9V&i@744C`e^&QgDD`h6H#3 literal 18482 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 From 04771fa4f03c5569d9f4100633ce79a0acbee6ad Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Sun, 9 Mar 2025 14:00:00 -0500 Subject: [PATCH 0188/1218] Core: fix pickling plando texts (#4711) --- Utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Utils.py b/Utils.py index 0aa81af1502e..c7f13f144d23 100644 --- a/Utils.py +++ b/Utils.py @@ -443,7 +443,8 @@ def find_class(self, module: str, name: str) -> type: else: mod = importlib.import_module(module) obj = getattr(mod, name) - if issubclass(obj, (self.options_module.Option, self.options_module.PlandoConnection)): + if issubclass(obj, (self.options_module.Option, self.options_module.PlandoConnection, + self.options_module.PlandoText)): return obj # Forbid everything else. raise pickle.UnpicklingError(f"global '{module}.{name}' is forbidden") From e95a41cf933946ff29d440a6e81bae314abfff96 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 10 Mar 2025 09:24:37 -0400 Subject: [PATCH 0189/1218] TUNIC: Add another alias for ladders #4714 --- worlds/tunic/items.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/tunic/items.py b/worlds/tunic/items.py index 1898534c1bba..a2b4140a6804 100644 --- a/worlds/tunic/items.py +++ b/worlds/tunic/items.py @@ -253,6 +253,7 @@ def get_item_group(item_name: str) -> str: "Ladders in Atoll": {"Ladders in South Atoll"}, "Ladders in Ruined Atoll": {"Ladders in South Atoll"}, "Ladders in Town": {"Ladders in Overworld Town"}, # fuzzy matching decided this was Ladders in South Atoll + "Ladder in Quarry": {"Ladders in Lower Quarry"}, # fuzzy matching decided this was Ladder to Quarry } item_name_groups.update(extra_groups) From 21ffc0fc548fc4fbddb6978282df1922f77f6e9d Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:43:52 +0100 Subject: [PATCH 0190/1218] Band-aid Linux Build breaking with the release of PyGObject 3.52.1 (#4716) * Band-aid Linux Build breaking with the release of PyGObject 3.52.1 * Update build.yml * Release workflow as well --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27ca76e41f8f..2b450fe46e37 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -132,7 +132,7 @@ jobs: # charset-normalizer was somehow incomplete in the github runner "${{ env.PYTHON }}" -m venv venv source venv/bin/activate - "${{ env.PYTHON }}" -m pip install --upgrade pip PyGObject charset-normalizer + "${{ env.PYTHON }}" -m pip install --upgrade pip "PyGObject<3.51.0" charset-normalizer python setup.py build_exe --yes bdist_appimage --yes echo -e "setup.py build output:\n `ls build`" echo -e "setup.py dist output:\n `ls dist`" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aec4f90998cf..f12e8fb80c5f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -64,7 +64,7 @@ jobs: # charset-normalizer was somehow incomplete in the github runner "${{ env.PYTHON }}" -m venv venv source venv/bin/activate - "${{ env.PYTHON }}" -m pip install --upgrade pip PyGObject charset-normalizer + "${{ env.PYTHON }}" -m pip install --upgrade pip "PyGObject<3.51.0" charset-normalizer python setup.py build_exe --yes bdist_appimage --yes echo -e "setup.py build output:\n `ls build`" echo -e "setup.py dist output:\n `ls dist`" From 5f73c245fc88f91bafedfa5f897839ec9fd8288a Mon Sep 17 00:00:00 2001 From: Carter Hesterman Date: Mon, 10 Mar 2025 07:53:26 -0600 Subject: [PATCH 0191/1218] New Game Implementation: Civilization VI (#3736) * Init * remove submodule * Init * Update docs * Fix tests * Update to use apcivvi * Update Readme and codeowners * Minor changes * Remove .value from options (except starting hint) * Minor updates * remove unnecessary property * Cleanup Rules and Region * Fix output file generation * Implement feedback * Remove 'AP' tag and fix issue with format strings and using same quotes * Update worlds/civ_6/__init__.py Co-authored-by: Scipio Wright * Minor docs changes * minor updates * Small rework of create items * Minor updates * Remove unused variable * Move client to Launcher Components with rest of similar clients * Revert "Move client to Launcher Components with rest of similar clients" This reverts commit f9fd5df9fdf19eaf4f1de54e21e3c33a74f02364. * modify component * Fix generation issues * Fix tests * Minor change * Add improvement and test case * Minor options changes * . * Preliminary Review * Fix failing test due to slot data serialization * Format json * Remove exclude missable boosts * Update options (update goody hut text, make research multiplier a range) * Update docs punctuation and slot data init * Move priority/excluded locations into options * Implement docs PR feedback * PR Feedback for options * PR feedback misc * Update location classification and fix client type * Fix typings * Update research cost multiplier * Remove unnecessary location priority code * Remove extrenous use of items() * WIP PR Feedback * WIP PR Feedback * Add victory event * Add option set for death link effect * PR improvements * Update post fill hint to support items with multiple classifications * remove unnecessary len * Move location exclusion logic * Update test to use set instead of accidental dict * Update docs around progressive eras and boost locations * Update docs for options to be more readable * Fix issue with filler items and prehints * Update filler_data to be static * Update links in docs * Minor updates and PR feedback * Update boosts data * Update era required items * Update existing techs * Update existing techs * move boost data class * Update reward data * Update prereq data * Update new items and progressive districts * Remove unused code * Make filler item name func more efficient * Update death link text * Move Civ6 to the end of readme * Fix bug with hidden locations and location.name * Partial PR Feedback Implementation * Format changes * Minor review feedback * Modify access rules to use list created in generate_early * Modify boost rules to precalculate requirements * Remove option checks from access rules * Fix issue with pre initialized dicts * Add inno setup for civ6 client * Update inno_setup.iss --------- Co-authored-by: Scipio Wright Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: Exempt-Medic Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- .gitignore | 1 + README.md | 1 + docs/CODEOWNERS | 3 + inno_setup.iss | 5 + worlds/civ_6/Civ6Client.py | 342 ++++++++ worlds/civ_6/CivVIInterface.py | 119 +++ worlds/civ_6/Container.py | 219 +++++ worlds/civ_6/Data.py | 70 ++ worlds/civ_6/DeathLink.py | 74 ++ worlds/civ_6/Enum.py | 39 + worlds/civ_6/ItemData.py | 38 + worlds/civ_6/Items.py | 353 ++++++++ worlds/civ_6/LICENSE.md | 21 + worlds/civ_6/Locations.py | 156 ++++ worlds/civ_6/Options.py | 130 +++ worlds/civ_6/ProgressiveDistricts.py | 35 + worlds/civ_6/Regions.py | 128 +++ worlds/civ_6/Rules.py | 109 +++ worlds/civ_6/TunerClient.py | 105 +++ worlds/civ_6/__init__.py | 326 +++++++ worlds/civ_6/data/boosts.py | 919 ++++++++++++++++++++ worlds/civ_6/data/era_required_items.py | 75 ++ worlds/civ_6/data/existing_civics.py | 435 +++++++++ worlds/civ_6/data/existing_tech.py | 546 ++++++++++++ worlds/civ_6/data/goody_hut_rewards.py | 81 ++ worlds/civ_6/data/new_civic_prereqs.py | 92 ++ worlds/civ_6/data/new_civics.py | 372 ++++++++ worlds/civ_6/data/new_tech.py | 468 ++++++++++ worlds/civ_6/data/new_tech_prereqs.py | 110 +++ worlds/civ_6/data/progressive_districts.py | 41 + worlds/civ_6/docs/en_Civilization VI.md | 59 ++ worlds/civ_6/docs/setup_en.md | 51 ++ worlds/civ_6/test/TestBoostsanity.py | 107 +++ worlds/civ_6/test/TestGoodyHuts.py | 114 +++ worlds/civ_6/test/TestRegionRequirements.py | 234 +++++ worlds/civ_6/test/TestStartingHints.py | 125 +++ worlds/civ_6/test/__init__.py | 8 + 37 files changed, 6111 insertions(+) create mode 100644 worlds/civ_6/Civ6Client.py create mode 100644 worlds/civ_6/CivVIInterface.py create mode 100644 worlds/civ_6/Container.py create mode 100644 worlds/civ_6/Data.py create mode 100644 worlds/civ_6/DeathLink.py create mode 100644 worlds/civ_6/Enum.py create mode 100644 worlds/civ_6/ItemData.py create mode 100644 worlds/civ_6/Items.py create mode 100644 worlds/civ_6/LICENSE.md create mode 100644 worlds/civ_6/Locations.py create mode 100644 worlds/civ_6/Options.py create mode 100644 worlds/civ_6/ProgressiveDistricts.py create mode 100644 worlds/civ_6/Regions.py create mode 100644 worlds/civ_6/Rules.py create mode 100644 worlds/civ_6/TunerClient.py create mode 100644 worlds/civ_6/__init__.py create mode 100644 worlds/civ_6/data/boosts.py create mode 100644 worlds/civ_6/data/era_required_items.py create mode 100644 worlds/civ_6/data/existing_civics.py create mode 100644 worlds/civ_6/data/existing_tech.py create mode 100644 worlds/civ_6/data/goody_hut_rewards.py create mode 100644 worlds/civ_6/data/new_civic_prereqs.py create mode 100644 worlds/civ_6/data/new_civics.py create mode 100644 worlds/civ_6/data/new_tech.py create mode 100644 worlds/civ_6/data/new_tech_prereqs.py create mode 100644 worlds/civ_6/data/progressive_districts.py create mode 100644 worlds/civ_6/docs/en_Civilization VI.md create mode 100644 worlds/civ_6/docs/setup_en.md create mode 100644 worlds/civ_6/test/TestBoostsanity.py create mode 100644 worlds/civ_6/test/TestGoodyHuts.py create mode 100644 worlds/civ_6/test/TestRegionRequirements.py create mode 100644 worlds/civ_6/test/TestStartingHints.py create mode 100644 worlds/civ_6/test/__init__.py diff --git a/.gitignore b/.gitignore index 791f7b1bb7fe..5da42dc1e0b9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *_Spoiler.txt *.bmbp *.apbp +*.apcivvi *.apl2ac *.apm3 *.apmc diff --git a/README.md b/README.md index d60f1b96651f..d119d560a7c0 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ Currently, the following games are supported: * Saving Princess * Castlevania: Circle of the Moon * Inscryption +* Civilization VI For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index c4cb83e42f38..ac88921356ca 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -45,6 +45,9 @@ # ChecksFinder /worlds/checksfinder/ @SunCatMC +# Civilization VI +/worlds/civ6/ @hesto2 + # Clique /worlds/clique/ @ThePhar diff --git a/inno_setup.iss b/inno_setup.iss index eb794650f3a6..9d03ca7baf5e 100644 --- a/inno_setup.iss +++ b/inno_setup.iss @@ -221,6 +221,11 @@ Root: HKCR; Subkey: "{#MyAppName}ygo06patch"; ValueData: "Ar Root: HKCR; Subkey: "{#MyAppName}ygo06patch\DefaultIcon"; ValueData: "{app}\ArchipelagoBizHawkClient.exe,0"; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}ygo06patch\shell\open\command"; ValueData: """{app}\ArchipelagoBizHawkClient.exe"" ""%1"""; ValueType: string; ValueName: ""; +Root: HKCR; Subkey: ".apcivvi"; ValueData: "{#MyAppName}apcivvipatch"; Flags: uninsdeletevalue; ValueType: string; ValueName: ""; +Root: HKCR; Subkey: "{#MyAppName}apcivvipatch"; ValueData: "Archipelago Civilization 6 Patch"; Flags: uninsdeletekey; ValueType: string; ValueName: ""; +Root: HKCR; Subkey: "{#MyAppName}apcivvipatch\DefaultIcon"; ValueData: "{app}\ArchipelagoLauncher.exe,0"; ValueType: string; ValueName: ""; +Root: HKCR; Subkey: "{#MyAppName}apcivvipatch\shell\open\command"; ValueData: """{app}\ArchipelagoLauncher.exe"" ""%1"""; ValueType: string; ValueName: ""; + Root: HKCR; Subkey: ".archipelago"; ValueData: "{#MyAppName}multidata"; Flags: uninsdeletevalue; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}multidata"; ValueData: "Archipelago Server Data"; Flags: uninsdeletekey; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}multidata\DefaultIcon"; ValueData: "{app}\ArchipelagoServer.exe,0"; ValueType: string; ValueName: ""; diff --git a/worlds/civ_6/Civ6Client.py b/worlds/civ_6/Civ6Client.py new file mode 100644 index 000000000000..7ef0a9e364c4 --- /dev/null +++ b/worlds/civ_6/Civ6Client.py @@ -0,0 +1,342 @@ +import asyncio +import logging +import os +import traceback +from typing import Any, Dict, List, Optional +import zipfile + +from CommonClient import ClientCommandProcessor, CommonContext, get_base_parser, logger, server_loop, gui_enabled +from .Data import get_progressive_districts_data +from .DeathLink import handle_check_deathlink +from NetUtils import ClientStatus +import Utils +from .CivVIInterface import CivVIInterface, ConnectionState +from .Enum import CivVICheckType +from .Items import CivVIItemData, generate_item_table, get_item_by_civ_name +from .Locations import CivVILocationData, generate_era_location_table +from .TunerClient import TunerErrorException, TunerTimeoutException + + +class CivVICommandProcessor(ClientCommandProcessor): + def __init__(self, ctx: CommonContext): + super().__init__(ctx) + + def _cmd_deathlink(self): + """Toggle deathlink from client. Overrides default setting.""" + if isinstance(self.ctx, CivVIContext): + self.ctx.death_link_enabled = not self.ctx.death_link_enabled + self.ctx.death_link_just_changed = True + Utils.async_start(self.ctx.update_death_link( + self.ctx.death_link_enabled), name="Update Deathlink") + self.ctx.logger.info(f"Deathlink is now {'enabled' if self.ctx.death_link_enabled else 'disabled'}") + + def _cmd_resync(self): + """Resends all items to client, and has client resend all locations to server. This can take up to a minute if the player has received a lot of items""" + if isinstance(self.ctx, CivVIContext): + logger.info("Resyncing...") + asyncio.create_task(self.ctx.resync()) + + def _cmd_toggle_progressive_eras(self): + """If you get stuck for some reason and unable to continue your game, you can run this command to disable the defeat that comes from pushing past the max unlocked era """ + if isinstance(self.ctx, CivVIContext): + print("Toggling progressive eras, stand by...") + self.ctx.is_pending_toggle_progressive_eras = True + + +class CivVIContext(CommonContext): + is_pending_death_link_reset = False + is_pending_toggle_progressive_eras = False + command_processor = CivVICommandProcessor + game = "Civilization VI" + items_handling = 0b111 + tuner_sync_task: Optional[asyncio.Task[None]] = None + game_interface: CivVIInterface + location_name_to_civ_location: Dict[str, CivVILocationData] = {} + location_name_to_id: Dict[str, int] = {} + item_id_to_civ_item: Dict[int, CivVIItemData] = {} + item_table: Dict[str, CivVIItemData] = {} + processing_multiple_items = False + received_death_link = False + death_link_message = "" + death_link_enabled = False + slot_data: Dict[str, Any] + + death_link_just_changed = False + # Used to prevent the deathlink from triggering when someone re enables it + + logger = logger + progressive_items_by_type = get_progressive_districts_data() + item_name_to_id = { + item.name: item.code for item in generate_item_table().values()} + connection_state = ConnectionState.DISCONNECTED + + def __init__(self, server_address: Optional[str], password: Optional[str], apcivvi_file: Optional[str] = None): + super().__init__(server_address, password) + self.slot_data: Dict[str, Any] = {} + self.game_interface = CivVIInterface(logger) + location_by_era = generate_era_location_table() + self.item_table = generate_item_table() + self.apcivvi_file = apcivvi_file + + # Get tables formatted in a way that is easier to use here + for locations in location_by_era.values(): + for location in locations.values(): + self.location_name_to_id[location.name] = location.code + self.location_name_to_civ_location[location.name] = location + + for item in self.item_table.values(): + self.item_id_to_civ_item[item.code] = item + + async def resync(self): + if self.processing_multiple_items: + logger.info( + "Waiting for items to finish processing, try again later") + return + await self.game_interface.resync() + await handle_receive_items(self, -1) + logger.info("Resynced") + + def on_deathlink(self, data: Utils.Dict[str, Utils.Any]) -> None: + super().on_deathlink(data) + text = data.get("cause", "") + if text: + message = text + else: + message = f"Received from {data['source']}" + self.death_link_message = message + self.received_death_link = True + + async def server_auth(self, password_requested: bool = False): + if password_requested and not self.password: + await super(CivVIContext, self).server_auth(password_requested) + await self.get_username() + self.tags = set() + await self.send_connect() + + def run_gui(self): + from kvui import GameManager + + class CivVIManager(GameManager): + logging_pairs = [ + ("Client", "Archipelago") + ] + base_title = "Archipelago Civilization VI Client" + + self.ui = CivVIManager(self) + self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI") + + def on_package(self, cmd: str, args: Dict[str, Any]): + if cmd == "Connected": + self.slot_data = args["slot_data"] + if "death_link" in args["slot_data"]: + self.death_link_enabled = bool(args["slot_data"]["death_link"]) + Utils.async_start(self.update_death_link( + bool(args["slot_data"]["death_link"]))) + + +def update_connection_status(ctx: CivVIContext, status: ConnectionState): + if ctx.connection_state == status: + return + elif status == ConnectionState.IN_GAME: + ctx.logger.info("Connected to Civ VI") + elif status == ConnectionState.IN_MENU: + ctx.logger.info("Connected to Civ VI, waiting for game to start") + elif status == ConnectionState.DISCONNECTED: + ctx.logger.info("Disconnected from Civ VI, attempting to reconnect...") + + ctx.connection_state = status + + +async def tuner_sync_task(ctx: CivVIContext): + logger.info("Starting CivVI connector") + while not ctx.exit_event.is_set(): + if not ctx.slot: + await asyncio.sleep(3) + continue + else: + try: + if ctx.processing_multiple_items: + await asyncio.sleep(3) + else: + state = await ctx.game_interface.is_in_game() + update_connection_status(ctx, state) + if state == ConnectionState.IN_GAME: + await _handle_game_ready(ctx) + else: + await asyncio.sleep(3) + except TunerTimeoutException: + logger.error( + "Timeout occurred while receiving data from Civ VI, this usually isn't a problem unless you see it repeatedly") + await asyncio.sleep(3) + except Exception as e: + if isinstance(e, TunerErrorException): + logger.debug(str(e)) + else: + logger.debug(traceback.format_exc()) + + await asyncio.sleep(3) + continue + + +async def handle_toggle_progressive_eras(ctx: CivVIContext): + if ctx.is_pending_toggle_progressive_eras: + ctx.is_pending_toggle_progressive_eras = False + current = await ctx.game_interface.get_max_allowed_era() + if current > -1: + await ctx.game_interface.set_max_allowed_era(-1) + logger.info("Disabled progressive eras") + else: + count = 0 + for _, network_item in enumerate(ctx.items_received): + item: CivVIItemData = ctx.item_id_to_civ_item[network_item.item] + if item.item_type == CivVICheckType.ERA: + count += 1 + await ctx.game_interface.set_max_allowed_era(count) + logger.info(f"Enabled progressive eras, set to {count}") + + +async def handle_checked_location(ctx: CivVIContext): + checked_locations = await ctx.game_interface.get_checked_locations() + checked_location_ids = [location.code for location_name, location in ctx.location_name_to_civ_location.items( + ) if location_name in checked_locations] + + await ctx.send_msgs([{"cmd": "LocationChecks", "locations": checked_location_ids}]) + + +async def handle_receive_items(ctx: CivVIContext, last_received_index_override: Optional[int] = None): + try: + last_received_index = last_received_index_override or await ctx.game_interface.get_last_received_index() + if len(ctx.items_received) - last_received_index > 1: + ctx.processing_multiple_items = True + + progressive_districts: List[CivVIItemData] = [] + progressive_eras: List[CivVIItemData] = [] + for index, network_item in enumerate(ctx.items_received): + + # Track these separately so if we replace "PROGRESSIVE_DISTRICT" with a specific tech, we can still check if need to add it to the list of districts + item: CivVIItemData = ctx.item_id_to_civ_item[network_item.item] + item_to_send: CivVIItemData = ctx.item_id_to_civ_item[network_item.item] + if index > last_received_index: + if item.item_type == CivVICheckType.PROGRESSIVE_DISTRICT and item.civ_name: + # if the item is progressive, then check how far in that progression type we are and send the appropriate item + count = sum( + 1 for count_item in progressive_districts if count_item.civ_name == item.civ_name) + + if count >= len(ctx.progressive_items_by_type[item.civ_name]): + logger.error( + f"Received more progressive items than expected for {item.civ_name}") + continue + + item_civ_name = ctx.progressive_items_by_type[item.civ_name][count] + actual_item_name = get_item_by_civ_name(item_civ_name, ctx.item_table).name + item_to_send = ctx.item_table[actual_item_name] + + sender = ctx.player_names[network_item.player] + if item.item_type == CivVICheckType.ERA: + count = len(progressive_eras) + 1 + await ctx.game_interface.give_item_to_player(item_to_send, sender, count) + elif item.item_type == CivVICheckType.GOODY and item_to_send.civ_name: + await ctx.game_interface.give_item_to_player(item_to_send, sender, game_id_override=item_to_send.civ_name) + else: + await ctx.game_interface.give_item_to_player(item_to_send, sender) + await asyncio.sleep(0.02) + + if item.item_type == CivVICheckType.PROGRESSIVE_DISTRICT: + progressive_districts.append(item) + elif item.item_type == CivVICheckType.ERA: + progressive_eras.append(item) + + ctx.processing_multiple_items = False + finally: + # If something errors out, then unblock item processing + ctx.processing_multiple_items = False + + +async def handle_check_goal_complete(ctx: CivVIContext): + if ctx.finished_game: + return + result = await ctx.game_interface.check_victory() + if result: + logger.info("Sending Victory to server!") + await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) + ctx.finished_game = True + + +async def _handle_game_ready(ctx: CivVIContext): + if ctx.server: + if not ctx.slot: + await asyncio.sleep(3) + return + + await handle_receive_items(ctx) + await handle_checked_location(ctx) + await handle_check_goal_complete(ctx) + + if ctx.death_link_enabled: + await handle_check_deathlink(ctx) + + # process pending commands + await handle_toggle_progressive_eras(ctx) + await asyncio.sleep(3) + else: + logger.info("Waiting for player to connect to server") + await asyncio.sleep(3) + + +def main(connect: Optional[str] = None, password: Optional[str] = None, name: Optional[str] = None): + Utils.init_logging("Civilization VI Client") + + async def _main(connect: Optional[str], password: Optional[str], name: Optional[str]): + parser = get_base_parser() + parser.add_argument("apcivvi_file", default="", type=str, nargs="?", help="Path to apcivvi file") + args = parser.parse_args() + ctx = CivVIContext(connect, password, args.apcivvi_file) + + if args.apcivvi_file: + parent_dir: str = os.path.dirname(args.apcivvi_file) + target_name: str = os.path.basename(args.apcivvi_file).replace(".apcivvi", "-MOD-FILES") + target_path: str = os.path.join(parent_dir, target_name) + if not os.path.exists(target_path): + os.makedirs(target_path, exist_ok=True) + logger.info("Extracting mod files to %s", target_path) + with zipfile.ZipFile(args.apcivvi_file, "r") as zip_ref: + for member in zip_ref.namelist(): + zip_ref.extract(member, target_path) + + ctx.auth = name + ctx.server_task = asyncio.create_task( + server_loop(ctx), name="ServerLoop") + if gui_enabled: + ctx.run_gui() + await asyncio.sleep(1) + + ctx.tuner_sync_task = asyncio.create_task( + tuner_sync_task(ctx), name="TunerSync") + + await ctx.exit_event.wait() + ctx.server_address = None + + await ctx.shutdown() + + if ctx.tuner_sync_task: + await asyncio.sleep(3) + await ctx.tuner_sync_task + + import colorama + + colorama.init() + asyncio.run(_main(connect, password, name)) + colorama.deinit() + + +def debug_main(): + parser = get_base_parser() + parser.add_argument("apcivvi_file", default="", type=str, nargs="?", help="Path to apcivvi file") + parser.add_argument("--name", default=None, + help="Slot Name to connect as.") + parser.add_argument("--debug", default=None, + help="debug mode, additional logging") + args = parser.parse_args() + if args.debug: + logger.setLevel(logging.DEBUG) + main(args.connect, args.password, args.name) diff --git a/worlds/civ_6/CivVIInterface.py b/worlds/civ_6/CivVIInterface.py new file mode 100644 index 000000000000..c74d45675a0e --- /dev/null +++ b/worlds/civ_6/CivVIInterface.py @@ -0,0 +1,119 @@ +from enum import Enum +from logging import Logger +from typing import List, Optional + +from .Items import CivVIItemData +from .TunerClient import TunerClient, TunerConnectionException, TunerTimeoutException + + +class ConnectionState(Enum): + DISCONNECTED = 0 + IN_GAME = 1 + IN_MENU = 2 + + +class CivVIInterface: + logger: Logger + tuner: TunerClient + last_error: Optional[str] = None + + def __init__(self, logger: Logger): + self.logger = logger + self.tuner = TunerClient(logger) + + async def is_in_game(self) -> ConnectionState: + command = "IsInGame()" + try: + result = await self.tuner.send_game_command(command) + if result == "false": + return ConnectionState.IN_MENU + self.last_error = None + return ConnectionState.IN_GAME + except TunerTimeoutException: + self.print_connection_error( + "Not connected to game, waiting for connection to be available") + return ConnectionState.DISCONNECTED + except TunerConnectionException as e: + if "The remote computer refused the network connection" in str(e): + self.print_connection_error( + "Unable to connect to game. Verify that the tuner is enabled. Attempting to reconnect") + else: + self.print_connection_error( + "Not connected to game, waiting for connection to be available") + return ConnectionState.DISCONNECTED + except Exception as e: + if "attempt to index a nil valuestack traceback" in str(e) \ + or ".. is not supported for string .. nilstack traceback" in str(e): + return ConnectionState.IN_MENU + return ConnectionState.DISCONNECTED + + def print_connection_error(self, error: str) -> None: + if error != self.last_error: + self.last_error = error + self.logger.info(error) + + async def give_item_to_player(self, item: CivVIItemData, sender: str = "", amount: int = 1, game_id_override: Optional[str] = None) -> None: + if game_id_override: + item_id = f'"{game_id_override}"' + else: + item_id = item.civ_vi_id + + command = f"HandleReceiveItem({item_id}, \"{item.name}\", \"{item.item_type.value}\", \"{sender}\", {amount})" + await self.tuner.send_game_command(command) + + async def resync(self) -> None: + """Has the client resend all the checked locations""" + command = "Resync()" + await self.tuner.send_game_command(command) + + async def check_victory(self) -> bool: + command = "ClientGetVictory()" + result = await self.tuner.send_game_command(command) + return result == "true" + + async def get_checked_locations(self) -> List[str]: + command = "GetUnsentCheckedLocations()" + result = await self.tuner.send_game_command(command, 2048 * 4) + return result.split(",") + + async def get_deathlink(self) -> str: + """returns either "false" or the name of the unit that killed the player's unit""" + command = "ClientGetDeathLink()" + result = await self.tuner.send_game_command(command) + return result + + async def kill_unit(self, message: str) -> None: + command = f"KillUnit(\"{message}\")" + await self.tuner.send_game_command(command) + + async def get_last_received_index(self) -> int: + command = "ClientGetLastReceivedIndex()" + result = await self.tuner.send_game_command(command) + return int(result) + + async def send_notification(self, item: CivVIItemData, sender: str = "someone") -> None: + command = f"GameCore.NotificationManager:SendNotification(GameCore.NotificationTypes.USER_DEFINED_2, \"{item.name} Received\", \"You have received {item.name} from \" .. \"{sender}\", 0, {item.civ_vi_id})" + await self.tuner.send_command(command) + + async def decrease_gold_by_percent(self, percent: int, message: str) -> None: + command = f"DecreaseGoldByPercent({percent}, \"{message}\")" + await self.tuner.send_game_command(command) + + async def decrease_faith_by_percent(self, percent: int, message: str) -> None: + command = f"DecreaseFaithByPercent({percent}, \"{message}\")" + await self.tuner.send_game_command(command) + + async def decrease_era_score_by_amount(self, amount: int, message: str) -> None: + command = f"DecreaseEraScoreByAmount({amount}, \"{message}\")" + await self.tuner.send_game_command(command) + + async def set_max_allowed_era(self, count: int) -> None: + command = f"SetMaxAllowedEra(\"{count}\")" + await self.tuner.send_game_command(command) + + async def get_max_allowed_era(self) -> int: + command = "ClientGetMaxAllowedEra()" + result = await self.tuner.send_game_command(command) + if result == "": + return -1 + return int(result) diff --git a/worlds/civ_6/Container.py b/worlds/civ_6/Container.py new file mode 100644 index 000000000000..26bb08c03b45 --- /dev/null +++ b/worlds/civ_6/Container.py @@ -0,0 +1,219 @@ +from dataclasses import dataclass +import os +from typing import TYPE_CHECKING, Dict, List, Optional, cast +import zipfile +from BaseClasses import Location +from worlds.Files import APContainer + +from .Enum import CivVICheckType +from .Locations import CivVILocation, CivVILocationData + +if TYPE_CHECKING: + from . import CivVIWorld + + +# Python fstrings don't allow backslashes, so we use this workaround +nl = "\n" +tab = "\t" +apo = "\'" + + +@dataclass +class CivTreeItem: + name: str + cost: int + ui_tree_row: int + + +class CivVIContainer(APContainer): + """ + Responsible for generating the dynamic mod files for the Civ VI multiworld + """ + game: Optional[str] = "Civilization VI" + + def __init__(self, patch_data: Dict[str, str], base_path: str, output_directory: str, + player: Optional[int] = None, player_name: str = "", server: str = ""): + self.patch_data = patch_data + self.file_path = base_path + container_path = os.path.join(output_directory, base_path + ".apcivvi") + super().__init__(container_path, player, player_name, server) + + def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None: + for filename, yml in self.patch_data.items(): + opened_zipfile.writestr(filename, yml) + super().write_contents(opened_zipfile) + + +def get_cost(world: 'CivVIWorld', location: CivVILocationData) -> int: + """ + Returns the cost of the item based on the game options + """ + # Research cost is between 50 and 150 where 100 equals the default cost + multiplier = world.options.research_cost_multiplier / 100 + return int(world.location_table[location.name].cost * multiplier) + + +def get_formatted_player_name(world: 'CivVIWorld', player: int) -> str: + """ + Returns the name of the player in the world + """ + if player != world.player: + return f"{world.multiworld.player_name[player]}{apo}s" + return "Your" + + +def get_advisor_type(world: 'CivVIWorld', location: Location) -> str: + if world.options.advisor_show_progression_items and location.item and location.item.advancement: + return "ADVISOR_PROGRESSIVE" + return "ADVISOR_GENERIC" + + +def generate_new_items(world: 'CivVIWorld') -> str: + """ + Generates the XML for the new techs/civics as well as the blockers used to prevent players from researching their own items + """ + locations: List[CivVILocation] = cast(List[CivVILocation], world.multiworld.get_filled_locations(world.player)) + techs = [location for location in locations if location.location_type == + CivVICheckType.TECH] + civics = [location for location in locations if location.location_type == + CivVICheckType.CIVIC] + + boost_techs = [] + boost_civics = [] + + if world.options.boostsanity: + boost_techs = [location for location in locations if location.location_type == CivVICheckType.BOOST and location.name.split("_")[1] == "TECH"] + boost_civics = [location for location in locations if location.location_type == CivVICheckType.BOOST and location.name.split("_")[1] == "CIVIC"] + techs += boost_techs + civics += boost_civics + + return f""" + + + + + {"".join([f'{tab}{nl}' for + tech in techs])} + {"".join([f'{tab}{nl}' for + civic in civics])} + + + +{"".join([f'{tab}{nl}' + for location in techs if location.item])} + + + {"".join([f'{tab}{nl}' for location in boost_techs])} + + + +{"".join([f'{tab}{nl}' + for location in civics if location.item])} + + + {"".join([f'{tab}{nl}' for location in boost_civics])} + + + + {"".join([f'{tab}{nl}' for location in civics if world.options.hide_item_names])} + + + + {"".join([f'{tab}{nl}' for location in techs if world.options.hide_item_names])} + + + + """ + + +def generate_setup_file(world: 'CivVIWorld') -> str: + """ + Generates the Lua for the setup file. This sets initial variables and state that affect gameplay around Progressive Eras + """ + setup = "-- Setup" + if world.options.progression_style == "eras_and_districts": + setup += f""" + -- Init Progressive Era Value if it hasn't been set already + if Game.GetProperty("MaxAllowedEra") == nil then + print("Setting MaxAllowedEra to 0") + Game.SetProperty("MaxAllowedEra", 0) + end + """ + + if world.options.boostsanity: + setup += f""" + -- Init Boosts + if Game.GetProperty("BoostsAsChecks") == nil then + print("Setting Boosts As Checks to True") + Game.SetProperty("BoostsAsChecks", true) + end + """ + return setup + + +def generate_goody_hut_sql(world: 'CivVIWorld') -> str: + """ + Generates the SQL for the goody huts or an empty string if they are disabled since the mod expects the file to be there + """ + + if world.options.shuffle_goody_hut_rewards: + return f""" + UPDATE GoodyHutSubTypes SET Description = NULL WHERE GoodyHut NOT IN ('METEOR_GOODIES', 'GOODYHUT_SAILOR_WONDROUS', 'DUMMY_GOODY_BUILDIER') AND Weight > 0; + +INSERT INTO Modifiers + (ModifierId, ModifierType, RunOnce, Permanent, SubjectRequirementSetId) +SELECT ModifierID||'_AI', ModifierType, RunOnce, Permanent, 'PLAYER_IS_AI' +FROM Modifiers +WHERE EXISTS ( + SELECT ModifierId + FROM GoodyHutSubTypes + WHERE Modifiers.ModifierId = GoodyHutSubTypes.ModifierId AND GoodyHutSubTypes.GoodyHut NOT IN ('METEOR_GOODIES', 'GOODYHUT_SAILOR_WONDROUS', 'DUMMY_GOODY_BUILDIER') AND GoodyHutSubTypes.Weight > 0); + +INSERT INTO ModifierArguments + (ModifierId, Name, Type, Value) +SELECT ModifierID||'_AI', Name, Type, Value +FROM ModifierArguments +WHERE EXISTS ( + SELECT ModifierId + FROM GoodyHutSubTypes + WHERE ModifierArguments.ModifierId = GoodyHutSubTypes.ModifierId AND GoodyHutSubTypes.GoodyHut NOT IN ('METEOR_GOODIES', 'GOODYHUT_SAILOR_WONDROUS', 'DUMMY_GOODY_BUILDIER') AND GoodyHutSubTypes.Weight > 0); + +UPDATE GoodyHutSubTypes +SET ModifierID = ModifierID||'_AI' +WHERE GoodyHut NOT IN ('METEOR_GOODIES', 'GOODYHUT_SAILOR_WONDROUS', 'DUMMY_GOODY_BUILDIER') AND Weight > 0; + + """ + return "-- Goody Huts are disabled, no changes needed" + + +def generate_update_boosts_sql(world: 'CivVIWorld') -> str: + """ + Generates the SQL for existing boosts in boostsanity or an empty string if they are disabled since the mod expects the file to be there + """ + + if world.options.boostsanity: + return f""" +UPDATE Boosts +SET TechnologyType = 'BOOST_' || TechnologyType +WHERE TechnologyType IS NOT NULL; +UPDATE Boosts +SET CivicType = 'BOOST_' || CivicType +WHERE CivicType IS NOT NULL AND CivicType NOT IN ('CIVIC_CORPORATE_LIBERTARIANISM', 'CIVIC_DIGITAL_DEMOCRACY', 'CIVIC_SYNTHETIC_TECHNOCRACY', 'CIVIC_NEAR_FUTURE_GOVERNANCE'); + """ + return "-- Boostsanity is disabled, no changes needed" diff --git a/worlds/civ_6/Data.py b/worlds/civ_6/Data.py new file mode 100644 index 000000000000..7c802688341e --- /dev/null +++ b/worlds/civ_6/Data.py @@ -0,0 +1,70 @@ +from typing import Dict, List + +from .ItemData import ( + CivVIBoostData, + CivicPrereqData, + ExistingItemData, + GoodyHutRewardData, + NewItemData, + TechPrereqData, +) + + +def get_boosts_data() -> List[CivVIBoostData]: + from .data.boosts import boosts + + return boosts + + +def get_era_required_items_data() -> Dict[str, List[str]]: + from .data.era_required_items import era_required_items + + return era_required_items + + +def get_existing_civics_data() -> List[ExistingItemData]: + from .data.existing_civics import existing_civics + + return existing_civics + + +def get_existing_techs_data() -> List[ExistingItemData]: + from .data.existing_tech import existing_tech + + return existing_tech + + +def get_goody_hut_rewards_data() -> List[GoodyHutRewardData]: + from .data.goody_hut_rewards import reward_data + + return reward_data + + +def get_new_civic_prereqs_data() -> List[CivicPrereqData]: + from .data.new_civic_prereqs import new_civic_prereqs + + return new_civic_prereqs + + +def get_new_civics_data() -> List[NewItemData]: + from .data.new_civics import new_civics + + return new_civics + + +def get_new_tech_prereqs_data() -> List[TechPrereqData]: + from .data.new_tech_prereqs import new_tech_prereqs + + return new_tech_prereqs + + +def get_new_techs_data() -> List[NewItemData]: + from .data.new_tech import new_tech + + return new_tech + + +def get_progressive_districts_data() -> Dict[str, List[str]]: + from .data.progressive_districts import progressive_districts + + return progressive_districts diff --git a/worlds/civ_6/DeathLink.py b/worlds/civ_6/DeathLink.py new file mode 100644 index 000000000000..2af98fea07bb --- /dev/null +++ b/worlds/civ_6/DeathLink.py @@ -0,0 +1,74 @@ +import random + +from typing import TYPE_CHECKING, List +if TYPE_CHECKING: + from .Civ6Client import CivVIContext + +# any is also an option but should not be considered an effect +DEATH_LINK_EFFECTS = ["Gold", "Faith", "Era Score", "Unit Killed"] + + +async def handle_receive_deathlink(ctx: 'CivVIContext', message: str): + """Resolves the effects of a deathlink received from the multiworld based on the options selected by the player""" + chosen_effects: List[str] = ctx.slot_data["death_link_effect"] + effect = random.choice(chosen_effects) + + percent = ctx.slot_data["death_link_effect_percent"] + if effect == "Gold": + ctx.logger.info(f"Decreasing gold by {percent}%") + await ctx.game_interface.decrease_gold_by_percent(percent, message) + elif effect == "Faith": + ctx.logger.info(f"Decreasing faith by {percent}%") + await ctx.game_interface.decrease_faith_by_percent(percent, message) + elif effect == "Era Score": + ctx.logger.info("Decreasing era score by 1") + await ctx.game_interface.decrease_era_score_by_amount(1, message) + elif effect == "Unit Killed": + ctx.logger.info("Destroying a random unit") + await ctx.game_interface.kill_unit(message) + + +async def handle_check_deathlink(ctx: 'CivVIContext'): + """Checks if the local player should send out a deathlink to the multiworld as well as if we should respond to any pending deathlinks sent to us """ + # check if we received a death link + if ctx.received_death_link: + ctx.received_death_link = False + await handle_receive_deathlink(ctx, ctx.death_link_message) + + # Check if we should send out a death link + result = await ctx.game_interface.get_deathlink() + if ctx.death_link_just_changed: + ctx.death_link_just_changed = False + return + if result != "false": + messages = [f"lost a unit to a {result}", + f"offered a sacrifice to the great {result}", + f"was killed by a {result}", + f"made a donation to the {result} fund", + f"made a tactical error", + f"picked a fight with a {result} and lost", + f"tried to befriend an enemy {result}", + f"used a {result} to reduce their military spend", + f"was defeated by a {result} in combat", + f"bravely struck a {result} and paid the price", + f"had a lapse in judgement against a {result}", + f"learned at the hands of a {result}", + f"attempted to non peacefully negotiate with a {result}", + f"was outsmarted by a {result}", + f"received a lesson from a {result}", + f"now understands the importance of not fighting a {result}", + f"let a {result} get the better of them", + f"allowed a {result} to show them the error of their ways", + f"heard the tragedy of Darth Plagueis the Wise from a {result}", + f"refused to join a {result} in their quest for power", + f"was tired of sitting in BK and decided to fight a {result} instead", + f"purposely lost to a {result} as a cry for help", + f"is wanting to remind everyone that they are here to have fun and not to win", + f"is reconsidering their pursuit of a domination victory", + f"had their plans toppled by a {result}", + ] + + if ctx.slot is not None: + player = ctx.player_names[ctx.slot] + message = random.choice(messages) + await ctx.send_death(f"{player} {message}") diff --git a/worlds/civ_6/Enum.py b/worlds/civ_6/Enum.py new file mode 100644 index 000000000000..d7c735d4332b --- /dev/null +++ b/worlds/civ_6/Enum.py @@ -0,0 +1,39 @@ +from enum import Enum + +from BaseClasses import ItemClassification + + +class EraType(Enum): + ERA_ANCIENT = "ERA_ANCIENT" + ERA_CLASSICAL = "ERA_CLASSICAL" + ERA_MEDIEVAL = "ERA_MEDIEVAL" + ERA_RENAISSANCE = "ERA_RENAISSANCE" + ERA_INDUSTRIAL = "ERA_INDUSTRIAL" + ERA_MODERN = "ERA_MODERN" + ERA_ATOMIC = "ERA_ATOMIC" + ERA_INFORMATION = "ERA_INFORMATION" + ERA_FUTURE = "ERA_FUTURE" + + +class CivVICheckType(Enum): + TECH = "TECH" + CIVIC = "CIVIC" + PROGRESSIVE_DISTRICT = "PROGRESSIVE_DISTRICT" + ERA = "ERA" + GOODY = "GOODY" + BOOST = "BOOST" + EVENT = "EVENT" + +class CivVIHintClassification(Enum): + PROGRESSION = "Progression" + USEFUL = "Useful" + FILLER = "Filler" + + def to_item_classification(self) -> ItemClassification: + if self == CivVIHintClassification.PROGRESSION: + return ItemClassification.progression + if self == CivVIHintClassification.USEFUL: + return ItemClassification.useful + if self == CivVIHintClassification.FILLER: + return ItemClassification.filler + assert False diff --git a/worlds/civ_6/ItemData.py b/worlds/civ_6/ItemData.py new file mode 100644 index 000000000000..5f3c16a9b1ba --- /dev/null +++ b/worlds/civ_6/ItemData.py @@ -0,0 +1,38 @@ +from dataclasses import dataclass +from typing import List, TypedDict + + +class NewItemData(TypedDict): + Type: str + Cost: int + UITreeRow: int + EraType: str + + +class ExistingItemData(NewItemData): + Name: str + + +@dataclass +class CivVIBoostData: + Type: str + EraType: str + Prereq: List[str] + PrereqRequiredCount: int + Classification: str + + +class GoodyHutRewardData(TypedDict): + Type: str + Name: str + Rarity: str + + +class CivicPrereqData(TypedDict): + Civic: str + PrereqTech: str + + +class TechPrereqData(TypedDict): + Technology: str + PrereqTech: str diff --git a/worlds/civ_6/Items.py b/worlds/civ_6/Items.py new file mode 100644 index 000000000000..64a6cbb03a1a --- /dev/null +++ b/worlds/civ_6/Items.py @@ -0,0 +1,353 @@ +from enum import Enum +from typing import Dict, Optional, TYPE_CHECKING, List +from BaseClasses import Item, ItemClassification +from .Data import ( + GoodyHutRewardData, + get_era_required_items_data, + get_existing_civics_data, + get_existing_techs_data, + get_goody_hut_rewards_data, + get_progressive_districts_data, +) +from .Enum import CivVICheckType, EraType +from .ProgressiveDistricts import get_flat_progressive_districts + +if TYPE_CHECKING: + from . import CivVIWorld + + +CIV_VI_AP_ITEM_ID_BASE = 5041000 + +NON_PROGRESSION_DISTRICTS = ["PROGRESSIVE_PRESERVE", "PROGRESSIVE_NEIGHBORHOOD"] + + +# Items required as progression for boostsanity mode +BOOSTSANITY_PROGRESSION_ITEMS = [ + "TECH_THE_WHEEL", + "TECH_MASONRY", + "TECH_ARCHERY", + "TECH_ENGINEERING", + "TECH_CONSTRUCTION", + "TECH_GUNPOWDER", + "TECH_MACHINERY", + "TECH_SIEGE_TACTICS", + "TECH_STIRRUPS", + "TECH_ASTRONOMY", + "TECH_BALLISTICS", + "TECH_STEAM_POWER", + "TECH_SANITATION", + "TECH_COMPUTERS", + "TECH_COMBUSTION", + "TECH_TELECOMMUNICATIONS", + "TECH_ROBOTICS", + "CIVIC_FEUDALISM", + "CIVIC_GUILDS", + "CIVIC_THE_ENLIGHTENMENT", + "CIVIC_MERCANTILISM", + "CIVIC_CONSERVATION", + "CIVIC_CIVIL_SERVICE", + "CIVIC_GLOBALIZATION", + "CIVIC_COLD_WAR", + "CIVIC_URBANIZATION", + "CIVIC_NATIONALISM", + "CIVIC_MOBILIZATION", + "PROGRESSIVE_NEIGHBORHOOD", + "PROGRESSIVE_PRESERVE", +] + + +class FillerItemRarity(Enum): + COMMON = "COMMON" + UNCOMMON = "UNCOMMON" + RARE = "RARE" + + +FILLER_DISTRIBUTION: Dict[FillerItemRarity, float] = { + FillerItemRarity.RARE: 0.025, + FillerItemRarity.UNCOMMON: 0.2, + FillerItemRarity.COMMON: 0.775, +} + + +class FillerItemData: + name: str + type: str + rarity: FillerItemRarity + civ_name: str + + def __init__(self, data: GoodyHutRewardData): + self.name = data["Name"] + self.rarity = FillerItemRarity(data["Rarity"]) + self.civ_name = data["Type"] + + +filler_data: Dict[str, FillerItemData] = { + item["Name"]: FillerItemData(item) for item in get_goody_hut_rewards_data() +} + + +class CivVIItemData: + civ_vi_id: int + classification: ItemClassification + name: str + code: int + cost: int + item_type: CivVICheckType + progressive_name: Optional[str] + civ_name: Optional[str] + era: Optional[EraType] + + def __init__( + self, + name: str, + civ_vi_id: int, + cost: int, + item_type: CivVICheckType, + id_offset: int, + classification: ItemClassification, + progressive_name: Optional[str], + civ_name: Optional[str] = None, + era: Optional[EraType] = None, + ): + self.classification = classification + self.civ_vi_id = civ_vi_id + self.name = name + self.code = civ_vi_id + CIV_VI_AP_ITEM_ID_BASE + id_offset + self.cost = cost + self.item_type = item_type + self.progressive_name = progressive_name + self.civ_name = civ_name + self.era = era + + +class CivVIEvent(Item): + game: str = "Civilization VI" + + +class CivVIItem(Item): + game: str = "Civilization VI" + civ_vi_id: int + item_type: CivVICheckType + + def __init__( + self, + item: CivVIItemData, + player: int, + classification: Optional[ItemClassification] = None, + ): + super().__init__( + item.name, classification or item.classification, item.code, player + ) + self.civ_vi_id = item.civ_vi_id + self.item_type = item.item_type + + +def format_item_name(name: str) -> str: + name_parts = name.split("_") + return " ".join([part.capitalize() for part in name_parts]) + + +_items_by_civ_name: Dict[str, CivVIItemData] = {} + + +def get_item_by_civ_name( + item_name: str, item_table: Dict[str, "CivVIItemData"] +) -> "CivVIItemData": + """Gets the names of the items in the item_table""" + if not _items_by_civ_name: + for item in item_table.values(): + if item.civ_name: + _items_by_civ_name[item.civ_name] = item + + try: + return _items_by_civ_name[item_name] + except KeyError as e: + raise KeyError(f"Item {item_name} not found in item_table") from e + + +def _generate_tech_items( + id_base: int, required_items: List[str], progressive_items: Dict[str, str] +) -> Dict[str, CivVIItemData]: + # Generate Techs + existing_techs = get_existing_techs_data() + tech_table: Dict[str, CivVIItemData] = {} + + tech_id = 0 + for tech in existing_techs: + classification = ItemClassification.useful + name = tech["Name"] + civ_name = tech["Type"] + if civ_name in required_items: + classification = ItemClassification.progression + progressive_name = None + check_type = CivVICheckType.TECH + if civ_name in progressive_items.keys(): + progressive_name = format_item_name(progressive_items[civ_name]) + + tech_table[name] = CivVIItemData( + name=name, + civ_vi_id=tech_id, + cost=tech["Cost"], + item_type=check_type, + id_offset=id_base, + classification=classification, + progressive_name=progressive_name, + civ_name=civ_name, + era=EraType(tech["EraType"]), + ) + + tech_id += 1 + + return tech_table + + +def _generate_civics_items( + id_base: int, required_items: List[str], progressive_items: Dict[str, str] +) -> Dict[str, CivVIItemData]: + civic_id = 0 + civic_table: Dict[str, CivVIItemData] = {} + existing_civics = get_existing_civics_data() + + for civic in existing_civics: + name = civic["Name"] + civ_name = civic["Type"] + progressive_name = None + check_type = CivVICheckType.CIVIC + + if civ_name in progressive_items.keys(): + progressive_name = format_item_name(progressive_items[civ_name]) + + classification = ItemClassification.useful + if civ_name in required_items: + classification = ItemClassification.progression + + civic_table[name] = CivVIItemData( + name=name, + civ_vi_id=civic_id, + cost=civic["Cost"], + item_type=check_type, + id_offset=id_base, + classification=classification, + progressive_name=progressive_name, + civ_name=civ_name, + era=EraType(civic["EraType"]), + ) + + civic_id += 1 + + return civic_table + + +def _generate_progressive_district_items(id_base: int) -> Dict[str, CivVIItemData]: + progressive_table: Dict[str, CivVIItemData] = {} + progressive_id_base = 0 + progressive_items = get_progressive_districts_data() + for item_name in progressive_items.keys(): + classification = ( + ItemClassification.useful + if item_name in NON_PROGRESSION_DISTRICTS + else ItemClassification.progression + ) + name = format_item_name(item_name) + progressive_table[name] = CivVIItemData( + name=name, + civ_vi_id=progressive_id_base, + cost=0, + item_type=CivVICheckType.PROGRESSIVE_DISTRICT, + id_offset=id_base, + classification=classification, + progressive_name=None, + civ_name=item_name, + ) + progressive_id_base += 1 + return progressive_table + + +def _generate_progressive_era_items(id_base: int) -> Dict[str, CivVIItemData]: + """Generates the single progressive district item""" + era_table: Dict[str, CivVIItemData] = {} + # Generate progressive eras + progressive_era_name = format_item_name("PROGRESSIVE_ERA") + era_table[progressive_era_name] = CivVIItemData( + name=progressive_era_name, + civ_vi_id=0, + cost=0, + item_type=CivVICheckType.ERA, + id_offset=id_base, + classification=ItemClassification.progression, + progressive_name=None, + civ_name="PROGRESSIVE_ERA", + ) + return era_table + + +def _generate_goody_hut_items(id_base: int) -> Dict[str, CivVIItemData]: + # Generate goody hut items + goody_huts = { + item["Name"]: FillerItemData(item) for item in get_goody_hut_rewards_data() + } + goody_table: Dict[str, CivVIItemData] = {} + goody_base = 0 + for value in goody_huts.values(): + goody_table[value.name] = CivVIItemData( + name=value.name, + civ_vi_id=goody_base, + cost=0, + item_type=CivVICheckType.GOODY, + id_offset=id_base, + classification=ItemClassification.filler, + progressive_name=None, + civ_name=value.civ_name, + ) + goody_base += 1 + return goody_table + + +def generate_item_table() -> Dict[str, CivVIItemData]: + era_required_items = get_era_required_items_data() + required_items: List[str] = [] + for value in era_required_items.values(): + required_items += value + + progressive_items = get_flat_progressive_districts() + + item_table: Dict[str, CivVIItemData] = {} + + def get_id_base(): + return len(item_table.keys()) + + item_table.update( + **_generate_tech_items(get_id_base(), required_items, progressive_items) + ) + item_table.update( + **_generate_civics_items(get_id_base(), required_items, progressive_items) + ) + item_table.update(**_generate_progressive_district_items(get_id_base())) + item_table.update(**_generate_progressive_era_items(get_id_base())) + item_table.update(**_generate_goody_hut_items(get_id_base())) + + return item_table + + +def get_items_by_type( + item_type: CivVICheckType, item_table: Dict[str, CivVIItemData] +) -> List[CivVIItemData]: + """ + Returns a list of items that match the given item type + """ + return [item for item in item_table.values() if item.item_type == item_type] + + +fillers_by_rarity: Dict[FillerItemRarity, List[FillerItemData]] = { + rarity: [item for item in filler_data.values() if item.rarity == rarity] + for rarity in FillerItemRarity +} + + +def get_random_filler_by_rarity( + world: "CivVIWorld", rarity: FillerItemRarity +) -> FillerItemData: + """ + Returns a random filler item by rarity + """ + return world.random.choice(fillers_by_rarity[rarity]) diff --git a/worlds/civ_6/LICENSE.md b/worlds/civ_6/LICENSE.md new file mode 100644 index 000000000000..7671a45b3046 --- /dev/null +++ b/worlds/civ_6/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright © 2024 tanjo3 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/worlds/civ_6/Locations.py b/worlds/civ_6/Locations.py new file mode 100644 index 000000000000..71f29f1cfc89 --- /dev/null +++ b/worlds/civ_6/Locations.py @@ -0,0 +1,156 @@ +from collections import defaultdict +from dataclasses import dataclass +from typing import Optional, Dict +from BaseClasses import Location, Region + +from .Data import get_boosts_data, get_new_civics_data, get_new_techs_data + +from .Enum import CivVICheckType, EraType + +CIV_VI_AP_LOCATION_ID_BASE = 5041000 + +# Locs that should not have progression items +GOODY_HUT_LOCATION_NAMES = [ + "GOODY_HUT_1", + "GOODY_HUT_2", + "GOODY_HUT_3", + "GOODY_HUT_4", + "GOODY_HUT_5", + "GOODY_HUT_6", + "GOODY_HUT_7", + "GOODY_HUT_8", + "GOODY_HUT_9", + "GOODY_HUT_10", +] + + +@dataclass +class CivVILocationData: + name: str + cost: int + uiTreeRow: int + civ_id: int + era_type: str + location_type: CivVICheckType + + game: str = "Civilization VI" + + @property + def code(self): + return self.civ_id + CIV_VI_AP_LOCATION_ID_BASE + + +class CivVILocation(Location): + game: str = "Civilization VI" + location_type: CivVICheckType + + def __init__( + self, + player: int, + name: str = "", + address: Optional[int] = None, + parent: Optional[Region] = None, + ): + super().__init__(player, name, address, parent) + category = name.split("_")[0] + if "victory" in category: + self.location_type = CivVICheckType.EVENT + else: + self.location_type = CivVICheckType(category) + + +def generate_flat_location_table() -> Dict[str, CivVILocationData]: + """ + Generates a flat location table in the following format: + { + "TECH_AP_ANCIENT_00": CivVILocationData, + "TECH_AP_ANCIENT_01": CivVILocationData, + "CIVIC_AP_ANCIENT_00": CivVILocationData, + ... + } + """ + era_locations = generate_era_location_table() + flat_locations: Dict[str, CivVILocationData] = {} + for locations in era_locations.values(): + for location_id, location_data in locations.items(): + flat_locations[location_id] = location_data + return flat_locations + + +def generate_era_location_table() -> Dict[str, Dict[str, CivVILocationData]]: + """ + Uses the data from existing_tech.json to generate a location table in the following format: + { + "ERA_ANCIENT": { + "TECH_AP_ANCIENT_00": CivVILocationData, + "TECH_AP_ANCIENT_01": CivVILocationData, + "CIVIC_AP_ANCIENT_00": CivVILocationData, + }, + ... + } + """ + + new_techs = get_new_techs_data() + era_locations: Dict[str, Dict[str, CivVILocationData]] = defaultdict(dict) + id_base = 0 + # Techs + for data in new_techs: + era_type = data["EraType"] + era_locations[era_type][data["Type"]] = CivVILocationData( + data["Type"], + data["Cost"], + data["UITreeRow"], + id_base, + era_type, + CivVICheckType.TECH, + ) + id_base += 1 + # Civics + new_civics = get_new_civics_data() + + for data in new_civics: + era_type = data["EraType"] + era_locations[era_type][data["Type"]] = CivVILocationData( + data["Type"], + data["Cost"], + data["UITreeRow"], + id_base, + era_type, + CivVICheckType.CIVIC, + ) + id_base += 1 + + # Eras + for era in EraType: + + if era == EraType.ERA_ANCIENT: + continue + + era_locations[era.name][era.name] = CivVILocationData( + era.name, 0, 0, id_base, era.name, CivVICheckType.ERA + ) + id_base += 1 + + # Goody Huts, defaults to 10 goody huts as location checks (rarely will a player get more than this) + for i in range(10): + era_locations[EraType.ERA_ANCIENT.value]["GOODY_HUT_" + str(i + 1)] = ( + CivVILocationData( + "GOODY_HUT_" + str(i + 1), + 0, + 0, + id_base, + EraType.ERA_ANCIENT.value, + CivVICheckType.GOODY, + ) + ) + id_base += 1 + # Boosts + boosts = get_boosts_data() + for boost in boosts: + location = CivVILocationData( + boost.Type, 0, 0, id_base, boost.EraType, CivVICheckType.BOOST + ) + era_locations["ERA_ANCIENT"][boost.Type] = location + id_base += 1 + + return era_locations diff --git a/worlds/civ_6/Options.py b/worlds/civ_6/Options.py new file mode 100644 index 000000000000..72297b1ca1ba --- /dev/null +++ b/worlds/civ_6/Options.py @@ -0,0 +1,130 @@ +from dataclasses import dataclass +from Options import ( + Choice, + DefaultOnToggle, + OptionSet, + PerGameCommonOptions, + Range, + StartInventoryPool, + Toggle, +) +from .Enum import CivVIHintClassification + + +class ProgressionStyle(Choice): + """ + **Districts Only**: Each tech/civic that would normally unlock a district or building now has a logical progression. + Example: TECH_BRONZE_WORKING is now PROGRESSIVE_ENCAMPMENT + + **Eras and Districts**: Players will be defeated if they play until the world era advances beyond the currently unlocked maximum era. + Unlocked eras can be seen in both the tech and civic trees. Includes all progressive districts. + + **None**: No progressive items will be included. This means you can get district upgrades that won't be usable until the relevant district is unlocked. + """ + + rich_text_doc = True + display_name = "Progression Style" + option_districts_only = 0 + option_eras_and_districts = 1 + option_none = 2 + default = option_districts_only + + +class ShuffleGoodyHuts(DefaultOnToggle): + """Shuffles the goody hut rewards. + Goody huts will only contain junk items and locations are checked sequentially (First goody hut gives GOODY_HUT_1, second gives GOODY_HUT_2, etc.). + """ + + display_name = "Shuffle Goody Hut Rewards" + + +class BoostSanity(Toggle): + """Boosts for Civics/Techs are location checks. Boosts can now be triggered even if the item has already been + researched. + + **Note**: If a boost is dependent upon a unit that is now obsolete, you can click to toggle on/off the relevant tech in + the tech tree.""" + + rich_text_doc = True + display_name = "Boostsanity" + + +class ResearchCostMultiplier(Range): + """Multiplier for research cost of techs and civics, higher values make research more expensive.""" + + display_name = "Tech/Civic Cost Multiplier" + range_start = 50 + range_end = 150 + default = 100 + + +class PreHintItems(OptionSet): + """Controls what items from the tech/civics trees are pre-hinted for the multiworld. + **Progression**: Include Progression items in hints + **Useful**: Include Useful items in hints + **Filler**: Include Filler items in hints + """ + + display_name = "Tech/Civic Tree pre-hinted Items" + valid_keys = {classification.value for classification in CivVIHintClassification} # type: ignore + + +class HideItemNames(Toggle): + """Each Tech and Civic Location will have a title of 'Unrevealed' until its prereqs have been researched. Note that + hints will still be precollected if that option is enabled.""" + + display_name = "Hide Item Names" + + +class InGameFlagProgressionItems(DefaultOnToggle): + """If enabled, an advisor icon will be added to any location that contains a progression item.""" + + display_name = "Advisor Indicates Progression Items" + + +class CivDeathLink(Toggle): + """If enabled, losing a unit will trigger a death link effect on other players in the multiworld. When a death link is received, the player will receive the effect specified in 'Death Link Effect'.""" + + display_name = "Death Link" + + +class DeathLinkEffect(OptionSet): + """What happens when a unit dies. + + **Unit Killed**: A random unit will be killed when a death link is received. + + **Faith**: Faith will be decreased by the amount specified in 'Death Link Effect Percent'. + + **Gold**: Gold will be decreased by the amount specified in 'Death Link Effect Percent'. + + **Era Score**: Era score is decreased by 1. + """ + + rich_text_doc = True + display_name = "Death Link Effect" + valid_keys = ["Unit Killed", "Faith", "Gold", "Era Score"] # type: ignore + default = frozenset({"Unit Killed"}) + + +class DeathLinkEffectPercent(Range): + """The percentage of the effect that will be applied. Only applicable for Gold and Faith effects.""" + + display_name = "Death Link Effect Percent" + default = 20 + range_start = 1 + range_end = 100 + + +@dataclass +class CivVIOptions(PerGameCommonOptions): + start_inventory_from_pool: StartInventoryPool + progression_style: ProgressionStyle + shuffle_goody_hut_rewards: ShuffleGoodyHuts + boostsanity: BoostSanity + research_cost_multiplier: ResearchCostMultiplier + pre_hint_items: PreHintItems + hide_item_names: HideItemNames + advisor_show_progression_items: InGameFlagProgressionItems + death_link: CivDeathLink + death_link_effect: DeathLinkEffect + death_link_effect_percent: DeathLinkEffectPercent diff --git a/worlds/civ_6/ProgressiveDistricts.py b/worlds/civ_6/ProgressiveDistricts.py new file mode 100644 index 000000000000..b71d2f3395f9 --- /dev/null +++ b/worlds/civ_6/ProgressiveDistricts.py @@ -0,0 +1,35 @@ +from typing import Dict, List, Optional + +from .Data import get_progressive_districts_data + +_flat_progressive_districts: Optional[Dict[str, str]] = {} + + +def get_flat_progressive_districts() -> Dict[str, str]: + """Returns a dictionary of all items that are associated with a progressive item. + Key is the item name ("TECH_WRITING") and the value is the associated progressive + item ("PROGRESSIVE_CAMPUS")""" + if _flat_progressive_districts: + return _flat_progressive_districts + + progressive_districts = get_progressive_districts_data() + flat_progressive_districts: Dict[str, str] = {} + for key, value in progressive_districts.items(): + for item in value: + flat_progressive_districts[item] = key + return flat_progressive_districts + + +def convert_items_to_progressive_items(items: List[str]): + """converts a list of items to instead be their associated progressive item if + they have one. ["TECH_MINING", "TECH_WRITING"] -> ["TECH_MINING", "PROGRESSIVE_CAMPUS] + """ + flat_progressive_districts = get_flat_progressive_districts() + return [flat_progressive_districts.get(item, item) for item in items] + + +def convert_item_to_progressive_item(item: str): + """converts an items to instead be its associated progressive item if + it has one. "TECH_WRITING" -> "PROGRESSIVE_CAMPUS""" + flat_progressive_districts = get_flat_progressive_districts() + return flat_progressive_districts.get(item, item) diff --git a/worlds/civ_6/Regions.py b/worlds/civ_6/Regions.py new file mode 100644 index 000000000000..9c5cca15b8ed --- /dev/null +++ b/worlds/civ_6/Regions.py @@ -0,0 +1,128 @@ +from typing import TYPE_CHECKING, Dict, List, Optional, Set, Union +from BaseClasses import CollectionState, LocationProgressType, Region +from worlds.generic.Rules import add_rule, set_rule +from .Data import ( + get_boosts_data, +) +from .Enum import EraType +from .Locations import GOODY_HUT_LOCATION_NAMES, CivVILocation + +if TYPE_CHECKING: + from . import CivVIWorld + + +def has_progressive_eras( + state: CollectionState, era: EraType, world: "CivVIWorld" +) -> bool: + return state.has( + "Progressive Era", world.player, world.era_required_progressive_era_counts[era] + ) + + +def has_non_progressive_items( + state: CollectionState, era: EraType, world: "CivVIWorld" +) -> bool: + return state.has_all(world.era_required_non_progressive_items[era], world.player) + + +def has_progressive_items( + state: CollectionState, era: EraType, world: "CivVIWorld" +) -> bool: + return state.has_all_counts( + world.era_required_progressive_items_counts[era], world.player + ) + + +def create_regions(world: "CivVIWorld"): + menu = Region("Menu", world.player, world.multiworld) + world.multiworld.regions.append(menu) + + optional_location_inclusions: Dict[str, Union[bool, int]] = { + "ERA": world.options.progression_style + == world.options.progression_style.option_eras_and_districts, + "GOODY": world.options.shuffle_goody_hut_rewards.value, + "BOOST": world.options.boostsanity.value, + } + + regions: List[Region] = [] + previous_era: EraType = EraType.ERA_ANCIENT + for era in EraType: + era_region = Region(era.value, world.player, world.multiworld) + era_locations: Dict[str, Optional[int]] = {} + + for key, location in world.location_by_era[era.value].items(): + category = key.split("_")[0] + if optional_location_inclusions.get(category, True): + era_locations[location.name] = location.code + + era_region.add_locations(era_locations, CivVILocation) + + regions.append(era_region) + world.multiworld.regions.append(era_region) + + # Connect era to previous era if not ancient era + if era == EraType.ERA_ANCIENT: + menu.connect(world.get_region(EraType.ERA_ANCIENT.value)) + continue + + connection = world.get_region(previous_era.value).connect( + world.get_region(era.value) + ) + + # Access rules for eras + add_rule( + connection, + lambda state, previous_era=previous_era, world=world: has_non_progressive_items( + state, previous_era, world + ), + ) + if world.options.progression_style == "eras_and_districts": + add_rule( + connection, + lambda state, previous_era=previous_era, world=world: has_progressive_eras( + state, previous_era, world + ), + ) + if world.options.progression_style != "none": + add_rule( + connection, + lambda state, previous_era=previous_era, world=world: has_progressive_items( + state, previous_era, world + ), + ) + previous_era = era + + future_era = world.get_region(EraType.ERA_FUTURE.value) + victory = CivVILocation(world.player, "Complete a victory type", None, future_era) + victory.place_locked_item(world.create_event("Victory")) + future_era.locations.append(victory) + + set_rule( + victory, + lambda state: state.can_reach_region(EraType.ERA_FUTURE.value, world.player), + ) + + world.multiworld.completion_condition[world.player] = lambda state: state.has( + "Victory", world.player + ) + exclude_necessary_locations(world) + + +def exclude_necessary_locations(world: "CivVIWorld"): + forced_excluded_location_names: Set[str] = set() + + if world.options.shuffle_goody_hut_rewards: + forced_excluded_location_names.update(GOODY_HUT_LOCATION_NAMES) + + if world.options.boostsanity: + boost_data_list = get_boosts_data() + excluded_boosts = { + boost_data.Type + for boost_data in boost_data_list + if boost_data.Classification == "EXCLUDED" + } + forced_excluded_location_names.update(excluded_boosts) + + for location_name in forced_excluded_location_names: + location = world.get_location(location_name) + location.progress_type = LocationProgressType.EXCLUDED diff --git a/worlds/civ_6/Rules.py b/worlds/civ_6/Rules.py new file mode 100644 index 000000000000..3f4c477a83da --- /dev/null +++ b/worlds/civ_6/Rules.py @@ -0,0 +1,109 @@ +from typing import TYPE_CHECKING, List, Tuple +from BaseClasses import CollectionState +from .ItemData import CivVIBoostData +from .Items import format_item_name +from .Data import get_boosts_data, get_progressive_districts_data +from .Enum import CivVICheckType +from .ProgressiveDistricts import convert_item_to_progressive_item + +from worlds.generic.Rules import forbid_item, set_rule + + +if TYPE_CHECKING: + from . import CivVIWorld + + +def generate_requirements_for_boosts( + world: "CivVIWorld", boost_data: CivVIBoostData +) -> Tuple[List[str], List[Tuple[str, int]]]: + required_non_progressive_items: List[str] = [] + required_progressive_item_counts: List[Tuple[str, int]] = [] + + for item in boost_data.Prereq: + progressive_item_name = convert_item_to_progressive_item(item) + if ( + world.options.progression_style != "none" + and "PROGRESSIVE" in progressive_item_name + ): + required_progressive_item_counts.append( + ( + format_item_name(progressive_item_name), + get_progressive_districts_data()[progressive_item_name].index(item) + + 1, + ) + ) + else: + ap_item_name = world.item_by_civ_name[item] + required_non_progressive_items.append(ap_item_name) + return required_non_progressive_items, required_progressive_item_counts + + +def create_boost_rules(world: "CivVIWorld"): + boost_data_list = get_boosts_data() + boost_locations = [ + location + for location in world.location_table.values() + if location.location_type == CivVICheckType.BOOST + ] + for location in boost_locations: + boost_data = next( + (boost for boost in boost_data_list if boost.Type == location.name), None + ) + world_location = world.get_location(location.name) + forbid_item(world_location, "Progressive Era", world.player) + + if boost_data and boost_data.PrereqRequiredCount > 0: + required_non_progressive_items, required_progressive_item_counts = ( + generate_requirements_for_boosts(world, boost_data) + ) + if world.options.progression_style != "none": + set_rule( + world_location, + lambda state, non_progressive_prereqs=required_non_progressive_items, progressive_prereq_counts=required_progressive_item_counts, required_count=boost_data.PrereqRequiredCount: has_required_items_progressive( + state, + non_progressive_prereqs, + progressive_prereq_counts, + required_count, + world, + ), + ) + else: + set_rule( + world_location, + lambda state, prereqs=required_non_progressive_items, required_count=boost_data.PrereqRequiredCount: has_required_items_non_progressive( + state, prereqs, required_count, world + ), + ) + + +def has_required_items_progressive( + state: CollectionState, + non_progressive_prereqs: List[str], + progressive_prereq_counts: List[Tuple[str, int]], + required_count: int, + world: "CivVIWorld", +) -> bool: + collected_count = 0 + for item, count in progressive_prereq_counts: + if state.has(item, world.player, count): + collected_count += 1 + # early out if we've already gotten enough + if collected_count >= required_count: + return True + for item in non_progressive_prereqs: + if state.has(item, world.player): + collected_count += 1 + # early out if we've already gotten enough + if collected_count >= required_count: + return True + return False + + +def has_required_items_non_progressive( + state: CollectionState, prereqs: List[str], required_count: int, world: "CivVIWorld" +) -> bool: + return state.has_from_list_unique( + prereqs, + world.player, + required_count, + ) diff --git a/worlds/civ_6/TunerClient.py b/worlds/civ_6/TunerClient.py new file mode 100644 index 000000000000..c4ff461eb948 --- /dev/null +++ b/worlds/civ_6/TunerClient.py @@ -0,0 +1,105 @@ +import asyncio +from logging import Logger +import socket +from typing import Any + +ADDRESS = "127.0.0.1" +PORT = 4318 + +CLIENT_PREFIX = "APSTART:" +CLIENT_POSTFIX = ":APEND" + + +def decode_mixed_string(data: bytes) -> str: + return "".join(chr(b) if 32 <= b < 127 else "?" for b in data) + + +class TunerException(Exception): + pass + + +class TunerTimeoutException(TunerException): + pass + + +class TunerErrorException(TunerException): + pass + + +class TunerConnectionException(TunerException): + pass + + +class TunerClient: + """Interfaces with Civilization via the tuner socket""" + logger: Logger + + def __init__(self, logger: Logger): + self.logger = logger + + def __parse_response(self, response: str) -> str: + """Parses the response from the tuner socket""" + split = response.split(CLIENT_PREFIX) + if len(split) > 1: + start = split[1] + end = start.split(CLIENT_POSTFIX)[0] + return end + elif "ERR:" in response: + raise TunerErrorException(response.replace("?", "")) + else: + return "" + + async def send_game_command(self, command_string: str, size: int = 64): + """Small helper that prefixes a command with GameCore.Game.""" + return await self.send_command("GameCore.Game." + command_string, size) + + async def send_command(self, command_string: str, size: int = 64): + """Send a raw commannd""" + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setblocking(False) + + b_command_string = command_string.encode("utf-8") + + # Send data to the server + command_prefix = b"CMD:0:" + delimiter = b"\x00" + full_command = b_command_string + message = command_prefix + full_command + delimiter + message_length = len(message).to_bytes(1, byteorder="little") + + # game expects this to be added before any command that is sent, indicates payload size + message_header = message_length + b"\x00\x00\x00\x03\x00\x00\x00" + data = message_header + command_prefix + full_command + delimiter + + server_address = (ADDRESS, PORT) + loop = asyncio.get_event_loop() + try: + await loop.sock_connect(sock, server_address) + await loop.sock_sendall(sock, data) + + # Add a delay before receiving data + await asyncio.sleep(.02) + + received_data = await self.async_recv(sock) + response = decode_mixed_string(received_data) + return self.__parse_response(response) + + except socket.timeout: + self.logger.debug("Timeout occurred while receiving data") + raise TunerTimeoutException() + except Exception as e: + self.logger.debug(f"Error occurred while receiving data: {str(e)}") + # check if No connection could be made is present in the error message + connection_errors = [ + "The remote computer refused the network connection", + ] + if any(error in str(e) for error in connection_errors): + raise TunerConnectionException(e) + else: + raise TunerErrorException(e) + finally: + sock.close() + + async def async_recv(self, sock: Any, timeout: float = 2.0, size: int = 4096): + response = await asyncio.wait_for(asyncio.get_event_loop().sock_recv(sock, size), timeout) + return response diff --git a/worlds/civ_6/__init__.py b/worlds/civ_6/__init__.py new file mode 100644 index 000000000000..0d8fb29d6c96 --- /dev/null +++ b/worlds/civ_6/__init__.py @@ -0,0 +1,326 @@ +from collections import defaultdict +import math +import os +from typing import Any, Dict, List, Set + +from .ProgressiveDistricts import get_flat_progressive_districts +from worlds.generic.Rules import forbid_item + + +from .Data import ( + get_boosts_data, + get_era_required_items_data, +) + +from .Rules import create_boost_rules +from .Container import ( + CivVIContainer, + generate_goody_hut_sql, + generate_new_items, + generate_setup_file, + generate_update_boosts_sql, +) +from .Enum import CivVICheckType, CivVIHintClassification +from .Items import ( + BOOSTSANITY_PROGRESSION_ITEMS, + FILLER_DISTRIBUTION, + CivVIEvent, + CivVIItemData, + FillerItemRarity, + format_item_name, + generate_item_table, + CivVIItem, + get_item_by_civ_name, + get_random_filler_by_rarity, +) +from .Locations import ( + CivVILocation, + CivVILocationData, + EraType, + generate_era_location_table, + generate_flat_location_table, +) +from .Options import CivVIOptions +from .Regions import create_regions +from BaseClasses import Item, ItemClassification, MultiWorld, Tutorial +from worlds.AutoWorld import World, WebWorld +from worlds.LauncherComponents import Component, SuffixIdentifier, Type, components, launch_subprocess # type: ignore + + +def run_client(*args: Any): + print("Running Civ6 Client") + from .Civ6Client import main # lazy import + + launch_subprocess(main, name="Civ6Client") + + +components.append( + Component( + "Civ6 Client", + func=run_client, + component_type=Type.CLIENT, + file_identifier=SuffixIdentifier(".apcivvi"), + ) +) + + +class CivVIWeb(WebWorld): + tutorials = [ + Tutorial( + "Multiworld Setup Guide", + "A guide to setting up Civilization VI for MultiWorld.", + "English", + "setup_en.md", + "setup/en", + ["hesto2"], + ) + ] + theme = "ocean" + + +class CivVIWorld(World): + """ + Civilization VI is a turn-based strategy video game in which one or more players compete alongside computer-controlled opponents to grow their individual civilization from a small tribe to control the entire planet across several periods of development. + """ + + game = "Civilization VI" + topology_present = False + options_dataclass = CivVIOptions + options: CivVIOptions # type: ignore + + web = CivVIWeb() + + item_name_to_id = {item.name: item.code for item in generate_item_table().values()} + location_name_to_id = { + location.name: location.code + for location in generate_flat_location_table().values() + } + + item_table: Dict[str, CivVIItemData] = {} + location_by_era: Dict[str, Dict[str, CivVILocationData]] + required_client_version = (0, 4, 5) + location_table: Dict[str, CivVILocationData] + era_required_non_progressive_items: Dict[EraType, List[str]] + era_required_progressive_items_counts: Dict[EraType, Dict[str, int]] + era_required_progressive_era_counts: Dict[EraType, int] + item_by_civ_name: Dict[str, str] + + def __init__(self, multiworld: MultiWorld, player: int): + super().__init__(multiworld, player) + self.location_by_era = generate_era_location_table() + + self.location_table: Dict[str, CivVILocationData] = {} + self.item_table = generate_item_table() + + self.era_required_non_progressive_items = {} + self.era_required_progressive_items_counts = {} + self.era_required_progressive_era_counts = {} + + for locations in self.location_by_era.values(): + for location in locations.values(): + self.location_table[location.name] = location + + def generate_early(self) -> None: + flat_progressive_items = get_flat_progressive_districts() + + self.item_by_civ_name = { + item.civ_name: get_item_by_civ_name(item.civ_name, self.item_table).name + for item in self.item_table.values() + if item.civ_name + } + + previous_era_counts = None + eras_list = [e.value for e in EraType] + for era in EraType: + # Initialize era_required_progressive_era_counts + era_index = eras_list.index(era.value) + self.era_required_progressive_era_counts[era] = ( + 0 + if era in {EraType.ERA_FUTURE, EraType.ERA_INFORMATION} + else era_index + 1 + ) + + # Initialize era_required_progressive_items_counts + self.era_required_progressive_items_counts[era] = defaultdict(int) + + if previous_era_counts: + self.era_required_progressive_items_counts[era].update( + previous_era_counts + ) + + # Initialize era_required_non_progressive_items and add to item counts + self.era_required_non_progressive_items[era] = [] + + for item in get_era_required_items_data()[era.value]: + if ( + item in flat_progressive_items + and self.options.progression_style != "none" + ): + progressive_name = format_item_name(flat_progressive_items[item]) + self.era_required_progressive_items_counts[era][ + progressive_name + ] += 1 + else: + self.era_required_non_progressive_items[era].append( + self.item_by_civ_name[item] + ) + + previous_era_counts = self.era_required_progressive_items_counts[era].copy() + + def get_filler_item_name(self) -> str: + return get_random_filler_by_rarity(self, FillerItemRarity.COMMON).name + + def create_regions(self) -> None: + create_regions(self) + + def set_rules(self) -> None: + if self.options.boostsanity: + create_boost_rules(self) + + def create_event(self, event: str): + return CivVIEvent(event, ItemClassification.progression, None, self.player) + + def create_item(self, name: str) -> Item: + item: CivVIItemData = self.item_table[name] + classification = item.classification + if self.options.boostsanity: + if item.civ_name in BOOSTSANITY_PROGRESSION_ITEMS: + classification = ItemClassification.progression + + return CivVIItem(item, self.player, classification) + + def create_items(self) -> None: + data = get_era_required_items_data() + early_items = data[EraType.ERA_ANCIENT.value] + early_locations = [ + location + for location in self.location_table.values() + if location.era_type == EraType.ERA_ANCIENT.value + ] + for item_name, item_data in self.item_table.items(): + # These item types are handled individually + if item_data.item_type in [ + CivVICheckType.PROGRESSIVE_DISTRICT, + CivVICheckType.ERA, + CivVICheckType.GOODY, + ]: + continue + + # If we're using progressive districts, we need to check if we need to create a different item instead + item_to_create = item_name + item: CivVIItemData = self.item_table[item_name] + if self.options.progression_style != "none": + if item.progressive_name: + item_to_create = self.item_table[item.progressive_name].name + + self.multiworld.itempool += [self.create_item(item_to_create)] + if item.civ_name in early_items: + self.multiworld.early_items[self.player][item_to_create] = 1 + elif self.item_table[item_name].era in [ + EraType.ERA_ATOMIC, + EraType.ERA_INFORMATION, + EraType.ERA_FUTURE, + ]: + for location in early_locations: + found_location = None + try: + found_location = self.get_location(location.name) + forbid_item(found_location, item_to_create, self.player) + except KeyError: + pass + + # Era items + if self.options.progression_style == "eras_and_districts": + # Add one less than the total number of eras (start in ancient, don't need to find it) + for era in EraType: + if era.value == "ERA_ANCIENT": + continue + progressive_era_item = self.item_table.get("Progressive Era") + assert progressive_era_item is not None + self.multiworld.itempool += [ + self.create_item(progressive_era_item.name) + ] + + self.multiworld.early_items[self.player]["Progressive Era"] = 2 + + num_filler_items = 0 + # Goody items, create 10 by default if options are enabled + if self.options.shuffle_goody_hut_rewards: + num_filler_items += 10 + + if self.options.boostsanity: + num_filler_items += len(get_boosts_data()) + + filler_count = { + rarity: math.ceil(FILLER_DISTRIBUTION[rarity] * num_filler_items) + for rarity in FillerItemRarity.__reversed__() + } + filler_count[FillerItemRarity.COMMON] -= ( + sum(filler_count.values()) - num_filler_items + ) + self.multiworld.itempool += [ + self.create_item(get_random_filler_by_rarity(self, rarity).name) + for rarity, count in filler_count.items() + for _ in range(count) + ] + + def post_fill(self) -> None: + if not self.options.pre_hint_items.value: + return + + def is_hintable_filler_item(item: Item) -> bool: + return ( + item.classification == 0 + and CivVIHintClassification.FILLER.value + in self.options.pre_hint_items.value + ) + + start_location_hints: Set[str] = self.options.start_location_hints.value + non_filler_flags = [ + CivVIHintClassification(flag).to_item_classification() + for flag in self.options.pre_hint_items.value + if flag != CivVIHintClassification.FILLER.value + ] + for location_name, location_data in self.location_table.items(): + if ( + location_data.location_type != CivVICheckType.CIVIC + and location_data.location_type != CivVICheckType.TECH + ): + continue + + location: CivVILocation = self.get_location(location_name) # type: ignore + + if location.item and ( + is_hintable_filler_item(location.item) + or any( + flag in location.item.classification for flag in non_filler_flags + ) + ): + start_location_hints.add(location_name) + + def fill_slot_data(self) -> Dict[str, Any]: + return self.options.as_dict( + "progression_style", + "death_link", + "research_cost_multiplier", + "death_link_effect", + "death_link_effect_percent", + ) + + def generate_output(self, output_directory: str): + mod_name = self.multiworld.get_out_file_name_base(self.player) + mod_dir = os.path.join(output_directory, mod_name) + mod_files = { + f"NewItems.xml": generate_new_items(self), + f"InitOptions.lua": generate_setup_file(self), + f"GoodyHutOverride.sql": generate_goody_hut_sql(self), + f"UpdateExistingBoosts.sql": generate_update_boosts_sql(self), + } + mod = CivVIContainer( + mod_files, + mod_dir, + output_directory, + self.player, + self.multiworld.get_file_safe_player_name(self.player), + ) + mod.write() diff --git a/worlds/civ_6/data/boosts.py b/worlds/civ_6/data/boosts.py new file mode 100644 index 000000000000..a3977208154e --- /dev/null +++ b/worlds/civ_6/data/boosts.py @@ -0,0 +1,919 @@ +from typing import List + +from ..ItemData import CivVIBoostData + + +boosts: List[CivVIBoostData] = [ + CivVIBoostData("BOOST_TECH_SAILING", "ERA_ANCIENT", [], 0, "DEFAULT"), + CivVIBoostData( + "BOOST_TECH_ASTROLOGY", + "ERA_ANCIENT", + [], + 0, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_IRRIGATION", + "ERA_ANCIENT", + [], + 0, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_ARCHERY", + "ERA_ANCIENT", + [], + 0, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_WRITING", + "ERA_ANCIENT", + [], + 0, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_MASONRY", + "ERA_ANCIENT", + ["TECH_MINING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_BRONZE_WORKING", + "ERA_ANCIENT", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_THE_WHEEL", + "ERA_ANCIENT", + ["TECH_MINING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_CELESTIAL_NAVIGATION", + "ERA_CLASSICAL", + ["TECH_SAILING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_CURRENCY", + "ERA_CLASSICAL", + ["CIVIC_FOREIGN_TRADE"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_HORSEBACK_RIDING", + "ERA_CLASSICAL", + ["TECH_ANIMAL_HUSBANDRY"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_IRON_WORKING", + "ERA_CLASSICAL", + ["TECH_MINING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_SHIPBUILDING", + "ERA_CLASSICAL", + ["TECH_SAILING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_MATHEMATICS", + "ERA_CLASSICAL", + [ + "TECH_CURRENCY", + "TECH_BRONZE_WORKING", + "TECH_CELESTIAL_NAVIGATION", + "TECH_WRITING", + "TECH_APPRENTICESHIP", + "TECH_FLIGHT", + "CIVIC_GAMES_RECREATION", + "CIVIC_DRAMA_POETRY", + ], + 3, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_CONSTRUCTION", + "ERA_CLASSICAL", + ["TECH_THE_WHEEL"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_ENGINEERING", + "ERA_CLASSICAL", + ["TECH_MASONRY"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_MILITARY_TACTICS", + "ERA_MEDIEVAL", + ["TECH_BRONZE_WORKING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_APPRENTICESHIP", + "ERA_MEDIEVAL", + ["TECH_MINING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_MACHINERY", + "ERA_MEDIEVAL", + ["TECH_ARCHERY"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_EDUCATION", + "ERA_MEDIEVAL", + ["TECH_WRITING"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_STIRRUPS", + "ERA_MEDIEVAL", + ["CIVIC_FEUDALISM"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_MILITARY_ENGINEERING", + "ERA_MEDIEVAL", + ["TECH_ENGINEERING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_CASTLES", + "ERA_MEDIEVAL", + [ + "CIVIC_DIVINE_RIGHT", + "CIVIC_EXPLORATION", + "CIVIC_REFORMED_CHURCH", + "CIVIC_SUFFRAGE", + "CIVIC_TOTALITARIANISM", + "CIVIC_CLASS_STRUGGLE", + "CIVIC_DIGITAL_DEMOCRACY", + "CIVIC_CORPORATE_LIBERTARIANISM", + "CIVIC_SYNTHETIC_TECHNOCRACY", + ], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_CARTOGRAPHY", + "ERA_RENAISSANCE", + ["TECH_CELESTIAL_NAVIGATION"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_MASS_PRODUCTION", + "ERA_RENAISSANCE", + ["TECH_CONSTRUCTION"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_BANKING", + "ERA_RENAISSANCE", + ["CIVIC_GUILDS"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_GUNPOWDER", + "ERA_RENAISSANCE", + ["TECH_BRONZE_WORKING", "TECH_MILITARY_ENGINEERING"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_PRINTING", + "ERA_RENAISSANCE", + ["TECH_WRITING", "TECH_EDUCATION"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_SQUARE_RIGGING", + "ERA_RENAISSANCE", + ["TECH_GUNPOWDER"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_ASTRONOMY", + "ERA_RENAISSANCE", + ["TECH_EDUCATION"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_METAL_CASTING", + "ERA_RENAISSANCE", + ["TECH_MACHINERY"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_SIEGE_TACTICS", + "ERA_RENAISSANCE", + ["TECH_MILITARY_ENGINEERING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_INDUSTRIALIZATION", + "ERA_INDUSTRIAL", + ["TECH_APPRENTICESHIP"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_SCIENTIFIC_THEORY", + "ERA_INDUSTRIAL", + ["CIVIC_THE_ENLIGHTENMENT"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_BALLISTICS", + "ERA_INDUSTRIAL", + ["TECH_SIEGE_TACTICS", "TECH_MILITARY_ENGINEERING"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_MILITARY_SCIENCE", + "ERA_INDUSTRIAL", + ["TECH_STIRRUPS"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_STEAM_POWER", + "ERA_INDUSTRIAL", + ["TECH_MASS_PRODUCTION"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_SANITATION", + "ERA_INDUSTRIAL", + ["CIVIC_URBANIZATION"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_ECONOMICS", + "ERA_INDUSTRIAL", + ["TECH_CURRENCY", "TECH_BANKING"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_RIFLING", + "ERA_INDUSTRIAL", + ["TECH_MINING", "TECH_MILITARY_ENGINEERING"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_FLIGHT", + "ERA_MODERN", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_REPLACEABLE_PARTS", + "ERA_MODERN", + ["TECH_MILITARY_SCIENCE"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_STEEL", + "ERA_MODERN", + ["TECH_MINING", "TECH_STEAM_POWER", "TECH_INDUSTRIALIZATION"], + 3, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_ELECTRICITY", + "ERA_MODERN", + ["CIVIC_MERCANTILISM", "TECH_CELESTIAL_NAVIGATION"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_RADIO", + "ERA_MODERN", + ["CIVIC_CONSERVATION"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_CHEMISTRY", + "ERA_MODERN", + ["CIVIC_CIVIL_SERVICE"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_COMBUSTION", + "ERA_MODERN", + ["CIVIC_NATURAL_HISTORY", "CIVIC_HUMANISM"], + 2, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_ADVANCED_FLIGHT", + "ERA_ATOMIC", + ["TECH_FLIGHT"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_ROCKETRY", + "ERA_ATOMIC", + ["CIVIC_DIPLOMATIC_SERVICE"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_ADVANCED_BALLISTICS", + "ERA_ATOMIC", + [ + "TECH_ELECTRICITY", + "TECH_REFINING", + "TECH_APPRENTICESHIP", + "TECH_INDUSTRIALIZATION", + ], + 4, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_COMBINED_ARMS", + "ERA_ATOMIC", + ["CIVIC_MOBILIZATION", "CIVIC_NATIONALISM"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_PLASTICS", + "ERA_ATOMIC", + ["TECH_REFINING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_COMPUTERS", + "ERA_ATOMIC", + [ + "CIVIC_SUFFRAGE", + "CIVIC_TOTALITARIANISM", + "CIVIC_CLASS_STRUGGLE", + "CIVIC_DIGITAL_DEMOCRACY", + "CIVIC_CORPORATE_LIBERTARIANISM", + "CIVIC_SYNTHETIC_TECHNOCRACY", + ], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_NUCLEAR_FISSION", + "ERA_ATOMIC", + ["CIVIC_DIPLOMATIC_SERVICE"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_SYNTHETIC_MATERIALS", + "ERA_ATOMIC", + ["TECH_FLIGHT"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_TELECOMMUNICATIONS", + "ERA_INFORMATION", + ["CIVIC_DIPLOMATIC_SERVICE"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_SATELLITES", + "ERA_INFORMATION", + ["CIVIC_DRAMA_POETRY", "CIVIC_HUMANISM", "TECH_RADIO"], + 3, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_GUIDANCE_SYSTEMS", + "ERA_INFORMATION", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_LASERS", + "ERA_INFORMATION", + ["TECH_COMPUTERS"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_COMPOSITES", + "ERA_INFORMATION", + ["TECH_COMBUSTION"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_STEALTH_TECHNOLOGY", + "ERA_INFORMATION", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_ROBOTICS", + "ERA_INFORMATION", + ["CIVIC_GLOBALIZATION"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_NANOTECHNOLOGY", + "ERA_INFORMATION", + ["TECH_MINING", "TECH_RADIO"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_NUCLEAR_FUSION", + "ERA_INFORMATION", + [ + "TECH_APPRENTICESHIP", + "TECH_INDUSTRIALIZATION", + "TECH_ELECTRICITY", + "TECH_NUCLEAR_FISSION", + ], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_BUTTRESS", + "ERA_MEDIEVAL", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_REFINING", + "ERA_MODERN", + ["TECH_INDUSTRIALIZATION", "TECH_MINING", "TECH_APPRENTICESHIP"], + 3, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_TECH_SEASTEADS", + "ERA_FUTURE", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_ADVANCED_AI", + "ERA_FUTURE", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_ADVANCED_POWER_CELLS", + "ERA_FUTURE", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_CYBERNETICS", + "ERA_FUTURE", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_SMART_MATERIALS", + "ERA_FUTURE", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_PREDICTIVE_SYSTEMS", + "ERA_FUTURE", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_TECH_OFFWORLD_MISSION", + "ERA_FUTURE", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_CRAFTSMANSHIP", + "ERA_ANCIENT", + [ + "TECH_IRRIGATION", + "TECH_MINING", + "TECH_CONSTRUCTION", + "TECH_ANIMAL_HUSBANDRY", + "TECH_SAILING", + ], + 3, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_FOREIGN_TRADE", + "ERA_ANCIENT", + ["TECH_CARTOGRAPHY"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_MILITARY_TRADITION", + "ERA_ANCIENT", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_STATE_WORKFORCE", + "ERA_ANCIENT", + [ + "TECH_CURRENCY", + "TECH_BRONZE_WORKING", + "TECH_CELESTIAL_NAVIGATION", + "TECH_WRITING", + "TECH_APPRENTICESHIP", + "TECH_FLIGHT", + "CIVIC_GAMES_RECREATION", + "CIVIC_DRAMA_POETRY", + ], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_EARLY_EMPIRE", + "ERA_ANCIENT", + [], + 0, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_MYSTICISM", + "ERA_ANCIENT", + [], + 0, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_GAMES_RECREATION", + "ERA_CLASSICAL", + ["TECH_CONSTRUCTION"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_POLITICAL_PHILOSOPHY", + "ERA_CLASSICAL", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_DRAMA_POETRY", + "ERA_CLASSICAL", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_MILITARY_TRAINING", + "ERA_CLASSICAL", + ["TECH_BRONZE_WORKING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_DEFENSIVE_TACTICS", + "ERA_CLASSICAL", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_RECORDED_HISTORY", + "ERA_CLASSICAL", + ["TECH_WRITING"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_THEOLOGY", + "ERA_CLASSICAL", + ["TECH_ASTROLOGY"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_NAVAL_TRADITION", + "ERA_MEDIEVAL", + ["TECH_SHIPBUILDING"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_FEUDALISM", + "ERA_MEDIEVAL", + [], + 0, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_CIVIL_SERVICE", + "ERA_MEDIEVAL", + [], + 0, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_MERCENARIES", + "ERA_MEDIEVAL", + [], + 0, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_MEDIEVAL_FAIRES", + "ERA_MEDIEVAL", + ["CIVIC_FOREIGN_TRADE", "TECH_CURRENCY"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_GUILDS", + "ERA_MEDIEVAL", + ["TECH_CURRENCY"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_DIVINE_RIGHT", + "ERA_MEDIEVAL", + ["CIVIC_THEOLOGY", "TECH_ASTROLOGY"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_EXPLORATION", + "ERA_RENAISSANCE", + ["TECH_CARTOGRAPHY", "TECH_CELESTIAL_NAVIGATION"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_HUMANISM", + "ERA_RENAISSANCE", + ["CIVIC_DRAMA_POETRY"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_DIPLOMATIC_SERVICE", + "ERA_RENAISSANCE", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_REFORMED_CHURCH", + "ERA_RENAISSANCE", + ["TECH_ASTROLOGY"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_MERCANTILISM", + "ERA_RENAISSANCE", + ["TECH_CURRENCY"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_THE_ENLIGHTENMENT", + "ERA_RENAISSANCE", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_COLONIALISM", + "ERA_INDUSTRIAL", + ["TECH_ASTRONOMY"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_CIVIL_ENGINEERING", + "ERA_INDUSTRIAL", + [ + "TECH_CURRENCY", + "TECH_BRONZE_WORKING", + "TECH_CELESTIAL_NAVIGATION", + "TECH_WRITING", + "TECH_APPRENTICESHIP", + "TECH_FLIGHT", + "CIVIC_GAMES_RECREATION", + "CIVIC_DRAMA_POETRY", + ], + 8, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_NATIONALISM", + "ERA_INDUSTRIAL", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_OPERA_BALLET", + "ERA_INDUSTRIAL", + ["CIVIC_HUMANISM", "CIVIC_DRAMA_POETRY"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_NATURAL_HISTORY", + "ERA_INDUSTRIAL", + ["CIVIC_HUMANISM", "CIVIC_DRAMA_POETRY"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_SCORCHED_EARTH", + "ERA_INDUSTRIAL", + ["TECH_BALLISTICS"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_URBANIZATION", + "ERA_INDUSTRIAL", + [], + 0, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_CONSERVATION", + "ERA_MODERN", + ["CIVIC_URBANIZATION"], + 1, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_CAPITALISM", + "ERA_MODERN", + ["TECH_CURRENCY", "TECH_BANKING", "TECH_ECONOMICS"], + 3, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_NUCLEAR_PROGRAM", + "ERA_MODERN", + ["TECH_WRITING", "TECH_EDUCATION", "TECH_CHEMISTRY"], + 3, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_MASS_MEDIA", + "ERA_MODERN", + ["TECH_RADIO"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_MOBILIZATION", + "ERA_MODERN", + ["CIVIC_NATIONALISM"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_SUFFRAGE", + "ERA_MODERN", + ["TECH_SANITATION"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_TOTALITARIANISM", + "ERA_MODERN", + [ + "TECH_BRONZE_WORKING", + "TECH_MILITARY_ENGINEERING", + "TECH_MILITARY_SCIENCE", + ], + 3, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_CLASS_STRUGGLE", + "ERA_MODERN", + ["TECH_APPRENTICESHIP", "TECH_INDUSTRIALIZATION"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_COLD_WAR", + "ERA_ATOMIC", + ["TECH_NUCLEAR_FISSION"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_PROFESSIONAL_SPORTS", + "ERA_ATOMIC", + ["CIVIC_GAMES_RECREATION"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_CULTURAL_HERITAGE", + "ERA_ATOMIC", + [], + 0, + "EXCLUDED", + ), + CivVIBoostData( + "BOOST_CIVIC_RAPID_DEPLOYMENT", + "ERA_ATOMIC", + ["TECH_FLIGHT", "TECH_CARTOGRAPHY", "TECH_SHIPBUILDING"], + 3, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_SPACE_RACE", + "ERA_ATOMIC", + ["TECH_ROCKETRY"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_GLOBALIZATION", + "ERA_INFORMATION", + ["TECH_FLIGHT", "TECH_ADVANCED_FLIGHT"], + 2, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_SOCIAL_MEDIA", + "ERA_INFORMATION", + ["TECH_TELECOMMUNICATIONS"], + 1, + "DEFAULT", + ), + CivVIBoostData( + "BOOST_CIVIC_ENVIRONMENTALISM", + "ERA_INFORMATION", + ["TECH_SATELLITES"], + 1, + "DEFAULT", + ), +] diff --git a/worlds/civ_6/data/era_required_items.py b/worlds/civ_6/data/era_required_items.py new file mode 100644 index 000000000000..fd3bca6954dc --- /dev/null +++ b/worlds/civ_6/data/era_required_items.py @@ -0,0 +1,75 @@ +from typing import Dict, List + + +era_required_items: Dict[str, List[str]] = { + "ERA_ANCIENT": [ + "TECH_MINING", + "TECH_BRONZE_WORKING", + "TECH_ASTROLOGY", + "TECH_WRITING", + "TECH_IRRIGATION", + "TECH_SAILING", + "TECH_ANIMAL_HUSBANDRY", + "CIVIC_STATE_WORKFORCE", + "CIVIC_FOREIGN_TRADE", + ], + "ERA_CLASSICAL": [ + "TECH_CELESTIAL_NAVIGATION", + "TECH_CURRENCY", + "TECH_MATHEMATICS", + "TECH_SHIPBUILDING", + "CIVIC_GAMES_RECREATION", + "CIVIC_POLITICAL_PHILOSOPHY", + "CIVIC_DRAMA_POETRY", + "CIVIC_THEOLOGY", + ], + "ERA_MEDIEVAL": [ + "TECH_APPRENTICESHIP", + "TECH_EDUCATION", + "TECH_MILITARY_ENGINEERING", + "CIVIC_DIVINE_RIGHT", + ], + "ERA_RENAISSANCE": [ + "TECH_MASS_PRODUCTION", + "TECH_BANKING", + "CIVIC_EXPLORATION", + "CIVIC_HUMANISM", + "CIVIC_REFORMED_CHURCH", + "CIVIC_DIPLOMATIC_SERVICE", + "TECH_CARTOGRAPHY", + ], + "ERA_INDUSTRIAL": [ + "TECH_INDUSTRIALIZATION", + "TECH_MILITARY_SCIENCE", + "TECH_ECONOMICS", + "CIVIC_NATIONALISM", + "CIVIC_NATURAL_HISTORY", + ], + "ERA_MODERN": [ + "TECH_FLIGHT", + "TECH_REFINING", + "TECH_ELECTRICITY", + "TECH_RADIO", + "TECH_CHEMISTRY", + "CIVIC_SUFFRAGE", + "CIVIC_TOTALITARIANISM", + "CIVIC_CLASS_STRUGGLE", + ], + "ERA_ATOMIC": [ + "TECH_ADVANCED_FLIGHT", + "TECH_ROCKETRY", + "TECH_COMBINED_ARMS", + "TECH_PLASTICS", + "TECH_NUCLEAR_FISSION", + "CIVIC_PROFESSIONAL_SPORTS", + ], + "ERA_INFORMATION": [ + "TECH_SATELLITES", + "TECH_NANOTECHNOLOGY", + "TECH_SMART_MATERIALS", + "CIVIC_CORPORATE_LIBERTARIANISM", + "CIVIC_DIGITAL_DEMOCRACY", + "CIVIC_SYNTHETIC_TECHNOCRACY", + ], + "ERA_FUTURE": [], +} diff --git a/worlds/civ_6/data/existing_civics.py b/worlds/civ_6/data/existing_civics.py new file mode 100644 index 000000000000..662110ab6778 --- /dev/null +++ b/worlds/civ_6/data/existing_civics.py @@ -0,0 +1,435 @@ +from typing import TYPE_CHECKING, List + +if TYPE_CHECKING: + from ..Data import ExistingItemData + + +existing_civics: List["ExistingItemData"] = [ + { + "Type": "CIVIC_CODE_OF_LAWS", + "Name": "Code of Laws", + "Cost": 20, + "EraType": "ERA_ANCIENT", + "UITreeRow": 0, + }, + { + "Type": "CIVIC_CRAFTSMANSHIP", + "Name": "Craftsmanship", + "Cost": 40, + "EraType": "ERA_ANCIENT", + "UITreeRow": -2, + }, + { + "Type": "CIVIC_FOREIGN_TRADE", + "Name": "Foreign Trade", + "Cost": 40, + "EraType": "ERA_ANCIENT", + "UITreeRow": 2, + }, + { + "Type": "CIVIC_MILITARY_TRADITION", + "Name": "Military Tradition", + "Cost": 50, + "EraType": "ERA_ANCIENT", + "UITreeRow": -3, + }, + { + "Type": "CIVIC_STATE_WORKFORCE", + "Name": "State Workforce", + "Cost": 70, + "EraType": "ERA_ANCIENT", + "UITreeRow": 0, + }, + { + "Type": "CIVIC_EARLY_EMPIRE", + "Name": "Early Empire", + "Cost": 70, + "EraType": "ERA_ANCIENT", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_MYSTICISM", + "Name": "Mysticism", + "Cost": 50, + "EraType": "ERA_ANCIENT", + "UITreeRow": 3, + }, + { + "Type": "CIVIC_GAMES_RECREATION", + "Name": "Games Recreation", + "Cost": 110, + "EraType": "ERA_CLASSICAL", + "UITreeRow": -2, + }, + { + "Type": "CIVIC_POLITICAL_PHILOSOPHY", + "Name": "Political Philosophy", + "Cost": 110, + "EraType": "ERA_CLASSICAL", + "UITreeRow": 0, + }, + { + "Type": "CIVIC_DRAMA_POETRY", + "Name": "Drama and Poetry", + "Cost": 110, + "EraType": "ERA_CLASSICAL", + "UITreeRow": 2, + }, + { + "Type": "CIVIC_MILITARY_TRAINING", + "Name": "Military Training", + "Cost": 120, + "EraType": "ERA_CLASSICAL", + "UITreeRow": -3, + }, + { + "Type": "CIVIC_DEFENSIVE_TACTICS", + "Name": "Defensive Tactics", + "Cost": 175, + "EraType": "ERA_CLASSICAL", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_RECORDED_HISTORY", + "Name": "Recorded History", + "Cost": 175, + "EraType": "ERA_CLASSICAL", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_THEOLOGY", + "Name": "Theology", + "Cost": 120, + "EraType": "ERA_CLASSICAL", + "UITreeRow": 3, + }, + { + "Type": "CIVIC_NAVAL_TRADITION", + "Name": "Naval Tradition", + "Cost": 220, + "EraType": "ERA_MEDIEVAL", + "UITreeRow": -2, + }, + { + "Type": "CIVIC_FEUDALISM", + "Name": "Feudalism", + "Cost": 300, + "EraType": "ERA_MEDIEVAL", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_CIVIL_SERVICE", + "Name": "Civil Service", + "Cost": 300, + "EraType": "ERA_MEDIEVAL", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_MERCENARIES", + "Name": "Mercenaries", + "Cost": 340, + "EraType": "ERA_MEDIEVAL", + "UITreeRow": -3, + }, + { + "Type": "CIVIC_MEDIEVAL_FAIRES", + "Name": "Medieval Faires", + "Cost": 420, + "EraType": "ERA_MEDIEVAL", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_GUILDS", + "Name": "Guilds", + "Cost": 420, + "EraType": "ERA_MEDIEVAL", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_DIVINE_RIGHT", + "Name": "Divine Right", + "Cost": 340, + "EraType": "ERA_MEDIEVAL", + "UITreeRow": 3, + }, + { + "Type": "CIVIC_EXPLORATION", + "Name": "Exploration", + "Cost": 440, + "EraType": "ERA_RENAISSANCE", + "UITreeRow": -3, + }, + { + "Type": "CIVIC_HUMANISM", + "Name": "Humanism", + "Cost": 600, + "EraType": "ERA_RENAISSANCE", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_DIPLOMATIC_SERVICE", + "Name": "Diplomatic Service", + "Cost": 600, + "EraType": "ERA_RENAISSANCE", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_REFORMED_CHURCH", + "Name": "Reformed Church", + "Cost": 440, + "EraType": "ERA_RENAISSANCE", + "UITreeRow": 3, + }, + { + "Type": "CIVIC_MERCANTILISM", + "Name": "Mercantilism", + "Cost": 720, + "EraType": "ERA_RENAISSANCE", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_THE_ENLIGHTENMENT", + "Name": "The Enlightenment", + "Cost": 720, + "EraType": "ERA_RENAISSANCE", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_COLONIALISM", + "Name": "Colonialism", + "Cost": 800, + "EraType": "ERA_INDUSTRIAL", + "UITreeRow": -3, + }, + { + "Type": "CIVIC_CIVIL_ENGINEERING", + "Name": "Civil Engineering", + "Cost": 1010, + "EraType": "ERA_INDUSTRIAL", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_NATIONALISM", + "Name": "Nationalism", + "Cost": 1010, + "EraType": "ERA_INDUSTRIAL", + "UITreeRow": 0, + }, + { + "Type": "CIVIC_OPERA_BALLET", + "Name": "Opera and Ballet", + "Cost": 800, + "EraType": "ERA_INDUSTRIAL", + "UITreeRow": 2, + }, + { + "Type": "CIVIC_NATURAL_HISTORY", + "Name": "Natural History", + "Cost": 1050, + "EraType": "ERA_INDUSTRIAL", + "UITreeRow": -3, + }, + { + "Type": "CIVIC_SCORCHED_EARTH", + "Name": "Scorched Earth", + "Cost": 1210, + "EraType": "ERA_INDUSTRIAL", + "UITreeRow": 2, + }, + { + "Type": "CIVIC_URBANIZATION", + "Name": "Urbanization", + "Cost": 1210, + "EraType": "ERA_INDUSTRIAL", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_CONSERVATION", + "Name": "Conservation", + "Cost": 1540, + "EraType": "ERA_MODERN", + "UITreeRow": -3, + }, + { + "Type": "CIVIC_CAPITALISM", + "Name": "Capitalism", + "Cost": 1580, + "EraType": "ERA_MODERN", + "UITreeRow": -2, + }, + { + "Type": "CIVIC_NUCLEAR_PROGRAM", + "Name": "Nuclear Program", + "Cost": 1715, + "EraType": "ERA_MODERN", + "UITreeRow": -2, + }, + { + "Type": "CIVIC_MASS_MEDIA", + "Name": "Mass Media", + "Cost": 1540, + "EraType": "ERA_MODERN", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_MOBILIZATION", + "Name": "Mobilization", + "Cost": 1540, + "EraType": "ERA_MODERN", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_IDEOLOGY", + "Name": "Ideology", + "Cost": 1640, + "EraType": "ERA_MODERN", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_SUFFRAGE", + "Name": "Suffrage", + "Cost": 1640, + "EraType": "ERA_MODERN", + "UITreeRow": 0, + }, + { + "Type": "CIVIC_TOTALITARIANISM", + "Name": "Totalitarianism", + "Cost": 1640, + "EraType": "ERA_MODERN", + "UITreeRow": 2, + }, + { + "Type": "CIVIC_CLASS_STRUGGLE", + "Name": "Class Struggle", + "Cost": 1640, + "EraType": "ERA_MODERN", + "UITreeRow": 3, + }, + { + "Type": "CIVIC_COLD_WAR", + "Name": "Cold War", + "Cost": 2185, + "EraType": "ERA_ATOMIC", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_PROFESSIONAL_SPORTS", + "Name": "Professional Sports", + "Cost": 2185, + "EraType": "ERA_ATOMIC", + "UITreeRow": 2, + }, + { + "Type": "CIVIC_CULTURAL_HERITAGE", + "Name": "Cultural Heritage", + "Cost": 1955, + "EraType": "ERA_ATOMIC", + "UITreeRow": -3, + }, + { + "Type": "CIVIC_RAPID_DEPLOYMENT", + "Name": "Rapid Deployment", + "Cost": 2415, + "EraType": "ERA_ATOMIC", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_SPACE_RACE", + "Name": "Space Race", + "Cost": 2415, + "EraType": "ERA_ATOMIC", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_GLOBALIZATION", + "Name": "Globalization", + "Cost": 2880, + "EraType": "ERA_INFORMATION", + "UITreeRow": 0, + }, + { + "Type": "CIVIC_SOCIAL_MEDIA", + "Name": "Social Media", + "Cost": 2880, + "EraType": "ERA_INFORMATION", + "UITreeRow": 2, + }, + { + "Type": "CIVIC_FUTURE_CIVIC", + "Name": "Future Civic", + "Cost": 3500, + "EraType": "ERA_FUTURE", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_ENVIRONMENTALISM", + "Name": "Environmentalism", + "Cost": 2880, + "EraType": "ERA_INFORMATION", + "UITreeRow": -2, + }, + { + "Type": "CIVIC_CORPORATE_LIBERTARIANISM", + "Name": "Corporate Libertarianism", + "Cost": 3000, + "EraType": "ERA_INFORMATION", + "UITreeRow": 0, + }, + { + "Type": "CIVIC_DIGITAL_DEMOCRACY", + "Name": "Digital Democracy", + "Cost": 3000, + "EraType": "ERA_INFORMATION", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_SYNTHETIC_TECHNOCRACY", + "Name": "Synthetic Technocracy", + "Cost": 3000, + "EraType": "ERA_INFORMATION", + "UITreeRow": 2, + }, + { + "Type": "CIVIC_NEAR_FUTURE_GOVERNANCE", + "Name": "Near Future Governance", + "Cost": 3100, + "EraType": "ERA_INFORMATION", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_GLOBAL_WARMING_MITIGATION", + "Name": "Global Warming Mitigation", + "Cost": 3200, + "EraType": "ERA_FUTURE", + "UITreeRow": -2, + }, + { + "Type": "CIVIC_SMART_POWER_DOCTRINE", + "Name": "Smart Power Doctrine", + "Cost": 3200, + "EraType": "ERA_FUTURE", + "UITreeRow": -1, + }, + { + "Type": "CIVIC_INFORMATION_WARFARE", + "Name": "Information Warfare", + "Cost": 3200, + "EraType": "ERA_FUTURE", + "UITreeRow": 0, + }, + { + "Type": "CIVIC_EXODUS_IMPERATIVE", + "Name": "Exodus Imperative", + "Cost": 3200, + "EraType": "ERA_FUTURE", + "UITreeRow": 1, + }, + { + "Type": "CIVIC_CULTURAL_HEGEMONY", + "Name": "Cultural Hegemony", + "Cost": 3200, + "EraType": "ERA_FUTURE", + "UITreeRow": 2, + }, +] diff --git a/worlds/civ_6/data/existing_tech.py b/worlds/civ_6/data/existing_tech.py new file mode 100644 index 000000000000..3ff39f7a59fc --- /dev/null +++ b/worlds/civ_6/data/existing_tech.py @@ -0,0 +1,546 @@ +from typing import List + +from ..ItemData import ExistingItemData + + +existing_tech: List[ExistingItemData] = [ + { + "Type": "TECH_POTTERY", + "Cost": 25, + "UITreeRow": 0, + "EraType": "ERA_ANCIENT", + "Name": "Pottery", + }, + { + "Type": "TECH_ANIMAL_HUSBANDRY", + "Cost": 25, + "UITreeRow": 1, + "EraType": "ERA_ANCIENT", + "Name": "Animal Husbandry", + }, + { + "Type": "TECH_MINING", + "Cost": 25, + "UITreeRow": 3, + "EraType": "ERA_ANCIENT", + "Name": "Mining", + }, + { + "Type": "TECH_SAILING", + "Cost": 50, + "UITreeRow": -3, + "EraType": "ERA_ANCIENT", + "Name": "Sailing", + }, + { + "Type": "TECH_ASTROLOGY", + "Cost": 50, + "UITreeRow": -2, + "EraType": "ERA_ANCIENT", + "Name": "Astrology", + }, + { + "Type": "TECH_IRRIGATION", + "Cost": 50, + "UITreeRow": -1, + "EraType": "ERA_ANCIENT", + "Name": "Irrigation", + }, + { + "Type": "TECH_ARCHERY", + "Cost": 50, + "UITreeRow": 1, + "EraType": "ERA_ANCIENT", + "Name": "Archery", + }, + { + "Type": "TECH_WRITING", + "Cost": 50, + "UITreeRow": 0, + "EraType": "ERA_ANCIENT", + "Name": "Writing", + }, + { + "Type": "TECH_MASONRY", + "Cost": 80, + "UITreeRow": 2, + "EraType": "ERA_ANCIENT", + "Name": "Masonry", + }, + { + "Type": "TECH_BRONZE_WORKING", + "Cost": 80, + "UITreeRow": 3, + "EraType": "ERA_ANCIENT", + "Name": "Bronze Working", + }, + { + "Type": "TECH_THE_WHEEL", + "Cost": 80, + "UITreeRow": 4, + "EraType": "ERA_ANCIENT", + "Name": "The Wheel", + }, + { + "Type": "TECH_CELESTIAL_NAVIGATION", + "Cost": 120, + "UITreeRow": -2, + "EraType": "ERA_CLASSICAL", + "Name": "Celestial Navigation", + }, + { + "Type": "TECH_CURRENCY", + "Cost": 120, + "UITreeRow": 0, + "EraType": "ERA_CLASSICAL", + "Name": "Currency", + }, + { + "Type": "TECH_HORSEBACK_RIDING", + "Cost": 120, + "UITreeRow": 1, + "EraType": "ERA_CLASSICAL", + "Name": "Horseback Riding", + }, + { + "Type": "TECH_IRON_WORKING", + "Cost": 120, + "UITreeRow": 3, + "EraType": "ERA_CLASSICAL", + "Name": "Iron Working", + }, + { + "Type": "TECH_SHIPBUILDING", + "Cost": 200, + "UITreeRow": -3, + "EraType": "ERA_CLASSICAL", + "Name": "Shipbuilding", + }, + { + "Type": "TECH_MATHEMATICS", + "Cost": 200, + "UITreeRow": -1, + "EraType": "ERA_CLASSICAL", + "Name": "Mathematics", + }, + { + "Type": "TECH_CONSTRUCTION", + "Cost": 200, + "UITreeRow": 2, + "EraType": "ERA_CLASSICAL", + "Name": "Construction", + }, + { + "Type": "TECH_ENGINEERING", + "Cost": 200, + "UITreeRow": 4, + "EraType": "ERA_CLASSICAL", + "Name": "Engineering", + }, + { + "Type": "TECH_MILITARY_TACTICS", + "Cost": 300, + "UITreeRow": -2, + "EraType": "ERA_MEDIEVAL", + "Name": "Military Tactics", + }, + { + "Type": "TECH_APPRENTICESHIP", + "Cost": 300, + "UITreeRow": 0, + "EraType": "ERA_MEDIEVAL", + "Name": "Apprenticeship", + }, + { + "Type": "TECH_MACHINERY", + "Cost": 300, + "UITreeRow": 4, + "EraType": "ERA_MEDIEVAL", + "Name": "Machinery", + }, + { + "Type": "TECH_EDUCATION", + "Cost": 390, + "UITreeRow": -1, + "EraType": "ERA_MEDIEVAL", + "Name": "Education", + }, + { + "Type": "TECH_STIRRUPS", + "Cost": 390, + "UITreeRow": 1, + "EraType": "ERA_MEDIEVAL", + "Name": "Stirrups", + }, + { + "Type": "TECH_MILITARY_ENGINEERING", + "Cost": 390, + "UITreeRow": 2, + "EraType": "ERA_MEDIEVAL", + "Name": "Military Engineering", + }, + { + "Type": "TECH_CASTLES", + "Cost": 390, + "UITreeRow": 3, + "EraType": "ERA_MEDIEVAL", + "Name": "Castles", + }, + { + "Type": "TECH_CARTOGRAPHY", + "Cost": 600, + "UITreeRow": -3, + "EraType": "ERA_RENAISSANCE", + "Name": "Cartography", + }, + { + "Type": "TECH_MASS_PRODUCTION", + "Cost": 600, + "UITreeRow": -2, + "EraType": "ERA_RENAISSANCE", + "Name": "Mass Production", + }, + { + "Type": "TECH_BANKING", + "Cost": 600, + "UITreeRow": 0, + "EraType": "ERA_RENAISSANCE", + "Name": "Banking", + }, + { + "Type": "TECH_GUNPOWDER", + "Cost": 600, + "UITreeRow": 1, + "EraType": "ERA_RENAISSANCE", + "Name": "Gunpowder", + }, + { + "Type": "TECH_PRINTING", + "Cost": 600, + "UITreeRow": 4, + "EraType": "ERA_RENAISSANCE", + "Name": "Printing", + }, + { + "Type": "TECH_SQUARE_RIGGING", + "Cost": 730, + "UITreeRow": -3, + "EraType": "ERA_RENAISSANCE", + "Name": "Square Rigging", + }, + { + "Type": "TECH_ASTRONOMY", + "Cost": 730, + "UITreeRow": -1, + "EraType": "ERA_RENAISSANCE", + "Name": "Astronomy", + }, + { + "Type": "TECH_METAL_CASTING", + "Cost": 730, + "UITreeRow": 1, + "EraType": "ERA_RENAISSANCE", + "Name": "Metal Casting", + }, + { + "Type": "TECH_SIEGE_TACTICS", + "Cost": 730, + "UITreeRow": 3, + "EraType": "ERA_RENAISSANCE", + "Name": "Siege Tactics", + }, + { + "Type": "TECH_INDUSTRIALIZATION", + "Cost": 930, + "UITreeRow": -2, + "EraType": "ERA_INDUSTRIAL", + "Name": "Industrialization", + }, + { + "Type": "TECH_SCIENTIFIC_THEORY", + "Cost": 930, + "UITreeRow": -1, + "EraType": "ERA_INDUSTRIAL", + "Name": "Scientific Theory", + }, + { + "Type": "TECH_BALLISTICS", + "Cost": 930, + "UITreeRow": 1, + "EraType": "ERA_INDUSTRIAL", + "Name": "Ballistics", + }, + { + "Type": "TECH_MILITARY_SCIENCE", + "Cost": 930, + "UITreeRow": 3, + "EraType": "ERA_INDUSTRIAL", + "Name": "Military Science", + }, + { + "Type": "TECH_STEAM_POWER", + "Cost": 1070, + "UITreeRow": -3, + "EraType": "ERA_INDUSTRIAL", + "Name": "Steam Power", + }, + { + "Type": "TECH_SANITATION", + "Cost": 1070, + "UITreeRow": -1, + "EraType": "ERA_INDUSTRIAL", + "Name": "Sanitation", + }, + { + "Type": "TECH_ECONOMICS", + "Cost": 1070, + "UITreeRow": 0, + "EraType": "ERA_INDUSTRIAL", + "Name": "Economics", + }, + { + "Type": "TECH_RIFLING", + "Cost": 1070, + "UITreeRow": 2, + "EraType": "ERA_INDUSTRIAL", + "Name": "Rifling", + }, + { + "Type": "TECH_FLIGHT", + "Cost": 1250, + "UITreeRow": -2, + "EraType": "ERA_MODERN", + "Name": "Flight", + }, + { + "Type": "TECH_REPLACEABLE_PARTS", + "Cost": 1250, + "UITreeRow": 0, + "EraType": "ERA_MODERN", + "Name": "Replaceable Parts", + }, + { + "Type": "TECH_STEEL", + "Cost": 1250, + "UITreeRow": 1, + "EraType": "ERA_MODERN", + "Name": "Steel", + }, + { + "Type": "TECH_ELECTRICITY", + "Cost": 1370, + "UITreeRow": -3, + "EraType": "ERA_MODERN", + "Name": "Electricity", + }, + { + "Type": "TECH_RADIO", + "Cost": 1370, + "UITreeRow": -2, + "EraType": "ERA_MODERN", + "Name": "Radio", + }, + { + "Type": "TECH_CHEMISTRY", + "Cost": 1370, + "UITreeRow": -1, + "EraType": "ERA_MODERN", + "Name": "Chemistry", + }, + { + "Type": "TECH_COMBUSTION", + "Cost": 1370, + "UITreeRow": 2, + "EraType": "ERA_MODERN", + "Name": "Combustion", + }, + { + "Type": "TECH_ADVANCED_FLIGHT", + "Cost": 1480, + "UITreeRow": -2, + "EraType": "ERA_ATOMIC", + "Name": "Advanced Flight", + }, + { + "Type": "TECH_ROCKETRY", + "Cost": 1480, + "UITreeRow": -1, + "EraType": "ERA_ATOMIC", + "Name": "Rocketry", + }, + { + "Type": "TECH_ADVANCED_BALLISTICS", + "Cost": 1480, + "UITreeRow": 0, + "EraType": "ERA_ATOMIC", + "Name": "Advanced Ballistics", + }, + { + "Type": "TECH_COMBINED_ARMS", + "Cost": 1480, + "UITreeRow": 1, + "EraType": "ERA_ATOMIC", + "Name": "Combined Arms", + }, + { + "Type": "TECH_PLASTICS", + "Cost": 1480, + "UITreeRow": 2, + "EraType": "ERA_ATOMIC", + "Name": "Plastics", + }, + { + "Type": "TECH_COMPUTERS", + "Cost": 1660, + "UITreeRow": -3, + "EraType": "ERA_ATOMIC", + "Name": "Computers", + }, + { + "Type": "TECH_NUCLEAR_FISSION", + "Cost": 1660, + "UITreeRow": 1, + "EraType": "ERA_ATOMIC", + "Name": "Nuclear Fission", + }, + { + "Type": "TECH_SYNTHETIC_MATERIALS", + "Cost": 1660, + "UITreeRow": 2, + "EraType": "ERA_ATOMIC", + "Name": "Synthetic Materials", + }, + { + "Type": "TECH_TELECOMMUNICATIONS", + "Cost": 1850, + "UITreeRow": -3, + "EraType": "ERA_INFORMATION", + "Name": "Telecommunications", + }, + { + "Type": "TECH_SATELLITES", + "Cost": 1850, + "UITreeRow": -1, + "EraType": "ERA_INFORMATION", + "Name": "Satellites", + }, + { + "Type": "TECH_GUIDANCE_SYSTEMS", + "Cost": 1850, + "UITreeRow": 0, + "EraType": "ERA_INFORMATION", + "Name": "Guidance Systems", + }, + { + "Type": "TECH_LASERS", + "Cost": 1850, + "UITreeRow": 1, + "EraType": "ERA_INFORMATION", + "Name": "Lasers", + }, + { + "Type": "TECH_COMPOSITES", + "Cost": 1850, + "UITreeRow": 2, + "EraType": "ERA_INFORMATION", + "Name": "Composites", + }, + { + "Type": "TECH_STEALTH_TECHNOLOGY", + "Cost": 1850, + "UITreeRow": 3, + "EraType": "ERA_INFORMATION", + "Name": "Stealth Technology", + }, + { + "Type": "TECH_ROBOTICS", + "Cost": 2155, + "UITreeRow": -2, + "EraType": "ERA_INFORMATION", + "Name": "Robotics", + }, + { + "Type": "TECH_NANOTECHNOLOGY", + "Cost": 2155, + "UITreeRow": 2, + "EraType": "ERA_INFORMATION", + "Name": "Nanotechnology", + }, + { + "Type": "TECH_NUCLEAR_FUSION", + "Cost": 2155, + "UITreeRow": 1, + "EraType": "ERA_INFORMATION", + "Name": "Nuclear Fusion", + }, + { + "Type": "TECH_BUTTRESS", + "Cost": 300, + "UITreeRow": -3, + "EraType": "ERA_MEDIEVAL", + "Name": "Buttress", + }, + { + "Type": "TECH_REFINING", + "Cost": 1250, + "UITreeRow": 3, + "EraType": "ERA_MODERN", + "Name": "Refining", + }, + { + "Type": "TECH_SEASTEADS", + "Cost": 2200, + "UITreeRow": -3, + "EraType": "ERA_FUTURE", + "Name": "Seasteads", + }, + { + "Type": "TECH_ADVANCED_AI", + "Cost": 2200, + "UITreeRow": -2, + "EraType": "ERA_FUTURE", + "Name": "Advanced AI", + }, + { + "Type": "TECH_ADVANCED_POWER_CELLS", + "Cost": 2200, + "UITreeRow": -1, + "EraType": "ERA_FUTURE", + "Name": "Advanced Power Cells", + }, + { + "Type": "TECH_CYBERNETICS", + "Cost": 2200, + "UITreeRow": 0, + "EraType": "ERA_FUTURE", + "Name": "Cybernetics", + }, + { + "Type": "TECH_SMART_MATERIALS", + "Cost": 2200, + "UITreeRow": 1, + "EraType": "ERA_FUTURE", + "Name": "Smart Materials", + }, + { + "Type": "TECH_PREDICTIVE_SYSTEMS", + "Cost": 2200, + "UITreeRow": 2, + "EraType": "ERA_FUTURE", + "Name": "Predictive Systems", + }, + { + "Type": "TECH_OFFWORLD_MISSION", + "Cost": 2500, + "UITreeRow": 0, + "EraType": "ERA_FUTURE", + "Name": "Offworld Mission", + }, + { + "Type": "TECH_FUTURE_TECH", + "Cost": 2600, + "UITreeRow": 0, + "EraType": "ERA_FUTURE", + "Name": "Future Tech", + }, +] diff --git a/worlds/civ_6/data/goody_hut_rewards.py b/worlds/civ_6/data/goody_hut_rewards.py new file mode 100644 index 000000000000..8bef7d8159f3 --- /dev/null +++ b/worlds/civ_6/data/goody_hut_rewards.py @@ -0,0 +1,81 @@ +from typing import List +from ..ItemData import GoodyHutRewardData + + +reward_data: List[GoodyHutRewardData] = [ + { + "Type": "GOODY_GOLD_SMALL_MODIFIER", + "Rarity": "COMMON", + "Name": "Gold: Small" + }, + { + "Type": "GOODY_GOLD_MEDIUM_MODIFIER", + "Rarity": "COMMON", + "Name": "Gold: Medium" + }, + { + "Type": "GOODY_GOLD_LARGE_MODIFIER", + "Rarity": "UNCOMMON", + "Name": "Gold: Large" + }, + { + "Type": "GOODY_FAITH_SMALL_MODIFIER", + "Rarity": "COMMON", + "Name": "Faith: Small" + }, + { + "Type": "GOODY_FAITH_MEDIUM_MODIFIER", + "Rarity": "COMMON", + "Name": "Faith: Medium" + }, + { + "Type": "GOODY_FAITH_LARGE_MODIFIER", + "Rarity": "UNCOMMON", + "Name": "Faith: Large" + }, + { + "Type": "GOODY_DIPLOMACY_GRANT_FAVOR", + "Rarity": "COMMON", + "Name": "Diplomatic Favor" + }, + { + "Type": "GOODY_DIPLOMACY_GRANT_GOVERNOR_TITLE", + "Rarity": "RARE", + "Name": "Governor Title" + }, + { + "Type": "GOODY_DIPLOMACY_GRANT_ENVOY", + "Rarity": "UNCOMMON", + "Name": "Envoy" + }, + { + "Type": "GOODY_CULTURE_GRANT_ONE_RELIC", + "Rarity": "RARE", + "Name": "Relic" + }, + { + "Type": "GOODY_MILITARY_GRANT_SCOUT", + "Rarity": "UNCOMMON", + "Name": "Scout" + }, + { + "Type": "GOODY_SURVIVORS_ADD_POPULATION", + "Rarity": "UNCOMMON", + "Name": "Additional Population" + }, + { + "Type": "GOODY_SURVIVORS_GRANT_BUILDER", + "Rarity": "UNCOMMON", + "Name": "Builder" + }, + { + "Type": "GOODY_SURVIVORS_GRANT_TRADER", + "Rarity": "UNCOMMON", + "Name": "Trader" + }, + { + "Type": "GOODY_SURVIVORS_GRANT_SETTLER", + "Rarity": "UNCOMMON", + "Name": "Settler" + } +] diff --git a/worlds/civ_6/data/new_civic_prereqs.py b/worlds/civ_6/data/new_civic_prereqs.py new file mode 100644 index 000000000000..0390c2d08ca6 --- /dev/null +++ b/worlds/civ_6/data/new_civic_prereqs.py @@ -0,0 +1,92 @@ +from typing import List + +from ..ItemData import CivicPrereqData + + +new_civic_prereqs: List[CivicPrereqData] = [ + {"Civic": "CIVIC_AP_ANCIENT_01", "PrereqCivic": "CIVIC_AP_ANCIENT_00"}, + {"Civic": "CIVIC_AP_ANCIENT_02", "PrereqCivic": "CIVIC_AP_ANCIENT_00"}, + {"Civic": "CIVIC_AP_ANCIENT_03", "PrereqCivic": "CIVIC_AP_ANCIENT_01"}, + {"Civic": "CIVIC_AP_ANCIENT_04", "PrereqCivic": "CIVIC_AP_ANCIENT_01"}, + {"Civic": "CIVIC_AP_ANCIENT_05", "PrereqCivic": "CIVIC_AP_ANCIENT_02"}, + {"Civic": "CIVIC_AP_ANCIENT_06", "PrereqCivic": "CIVIC_AP_ANCIENT_02"}, + {"Civic": "CIVIC_AP_CLASSICAL_07", "PrereqCivic": "CIVIC_AP_ANCIENT_04"}, + {"Civic": "CIVIC_AP_CLASSICAL_08", "PrereqCivic": "CIVIC_AP_ANCIENT_04"}, + {"Civic": "CIVIC_AP_CLASSICAL_08", "PrereqCivic": "CIVIC_AP_ANCIENT_05"}, + {"Civic": "CIVIC_AP_CLASSICAL_09", "PrereqCivic": "CIVIC_AP_ANCIENT_05"}, + {"Civic": "CIVIC_AP_CLASSICAL_10", "PrereqCivic": "CIVIC_AP_ANCIENT_03"}, + {"Civic": "CIVIC_AP_CLASSICAL_10", "PrereqCivic": "CIVIC_AP_CLASSICAL_07"}, + {"Civic": "CIVIC_AP_CLASSICAL_11", "PrereqCivic": "CIVIC_AP_CLASSICAL_07"}, + {"Civic": "CIVIC_AP_CLASSICAL_11", "PrereqCivic": "CIVIC_AP_CLASSICAL_08"}, + {"Civic": "CIVIC_AP_CLASSICAL_12", "PrereqCivic": "CIVIC_AP_CLASSICAL_08"}, + {"Civic": "CIVIC_AP_CLASSICAL_12", "PrereqCivic": "CIVIC_AP_CLASSICAL_09"}, + {"Civic": "CIVIC_AP_CLASSICAL_13", "PrereqCivic": "CIVIC_AP_CLASSICAL_09"}, + {"Civic": "CIVIC_AP_CLASSICAL_13", "PrereqCivic": "CIVIC_AP_ANCIENT_06"}, + {"Civic": "CIVIC_AP_MEDIEVAL_14", "PrereqCivic": "CIVIC_AP_CLASSICAL_11"}, + {"Civic": "CIVIC_AP_MEDIEVAL_15", "PrereqCivic": "CIVIC_AP_CLASSICAL_11"}, + {"Civic": "CIVIC_AP_MEDIEVAL_16", "PrereqCivic": "CIVIC_AP_CLASSICAL_11"}, + {"Civic": "CIVIC_AP_MEDIEVAL_16", "PrereqCivic": "CIVIC_AP_CLASSICAL_12"}, + {"Civic": "CIVIC_AP_MEDIEVAL_17", "PrereqCivic": "CIVIC_AP_CLASSICAL_10"}, + {"Civic": "CIVIC_AP_MEDIEVAL_17", "PrereqCivic": "CIVIC_AP_MEDIEVAL_15"}, + {"Civic": "CIVIC_AP_MEDIEVAL_18", "PrereqCivic": "CIVIC_AP_MEDIEVAL_15"}, + {"Civic": "CIVIC_AP_MEDIEVAL_19", "PrereqCivic": "CIVIC_AP_MEDIEVAL_15"}, + {"Civic": "CIVIC_AP_MEDIEVAL_19", "PrereqCivic": "CIVIC_AP_MEDIEVAL_16"}, + {"Civic": "CIVIC_AP_MEDIEVAL_20", "PrereqCivic": "CIVIC_AP_MEDIEVAL_16"}, + {"Civic": "CIVIC_AP_MEDIEVAL_20", "PrereqCivic": "CIVIC_AP_CLASSICAL_13"}, + {"Civic": "CIVIC_AP_RENAISSANCE_21", "PrereqCivic": "CIVIC_AP_MEDIEVAL_17"}, + {"Civic": "CIVIC_AP_RENAISSANCE_21", "PrereqCivic": "CIVIC_AP_MEDIEVAL_18"}, + {"Civic": "CIVIC_AP_RENAISSANCE_22", "PrereqCivic": "CIVIC_AP_MEDIEVAL_18"}, + {"Civic": "CIVIC_AP_RENAISSANCE_22", "PrereqCivic": "CIVIC_AP_MEDIEVAL_19"}, + {"Civic": "CIVIC_AP_RENAISSANCE_23", "PrereqCivic": "CIVIC_AP_MEDIEVAL_19"}, + {"Civic": "CIVIC_AP_RENAISSANCE_24", "PrereqCivic": "CIVIC_AP_MEDIEVAL_19"}, + {"Civic": "CIVIC_AP_RENAISSANCE_24", "PrereqCivic": "CIVIC_AP_MEDIEVAL_20"}, + {"Civic": "CIVIC_AP_RENAISSANCE_25", "PrereqCivic": "CIVIC_AP_RENAISSANCE_22"}, + {"Civic": "CIVIC_AP_RENAISSANCE_26", "PrereqCivic": "CIVIC_AP_RENAISSANCE_22"}, + {"Civic": "CIVIC_AP_RENAISSANCE_26", "PrereqCivic": "CIVIC_AP_RENAISSANCE_23"}, + {"Civic": "CIVIC_AP_INDUSTRIAL_27", "PrereqCivic": "CIVIC_AP_RENAISSANCE_25"}, + {"Civic": "CIVIC_AP_INDUSTRIAL_28", "PrereqCivic": "CIVIC_AP_RENAISSANCE_25"}, + {"Civic": "CIVIC_AP_INDUSTRIAL_29", "PrereqCivic": "CIVIC_AP_RENAISSANCE_26"}, + {"Civic": "CIVIC_AP_INDUSTRIAL_30", "PrereqCivic": "CIVIC_AP_RENAISSANCE_26"}, + {"Civic": "CIVIC_AP_INDUSTRIAL_31", "PrereqCivic": "CIVIC_AP_INDUSTRIAL_27"}, + {"Civic": "CIVIC_AP_INDUSTRIAL_32", "PrereqCivic": "CIVIC_AP_INDUSTRIAL_29"}, + {"Civic": "CIVIC_AP_INDUSTRIAL_33", "PrereqCivic": "CIVIC_AP_INDUSTRIAL_28"}, + {"Civic": "CIVIC_AP_INDUSTRIAL_33", "PrereqCivic": "CIVIC_AP_INDUSTRIAL_29"}, + {"Civic": "CIVIC_AP_MODERN_34", "PrereqCivic": "CIVIC_AP_INDUSTRIAL_31"}, + {"Civic": "CIVIC_AP_MODERN_37", "PrereqCivic": "CIVIC_AP_INDUSTRIAL_31"}, + {"Civic": "CIVIC_AP_MODERN_37", "PrereqCivic": "CIVIC_AP_INDUSTRIAL_33"}, + {"Civic": "CIVIC_AP_MODERN_35", "PrereqCivic": "CIVIC_AP_MODERN_37"}, + {"Civic": "CIVIC_AP_MODERN_38", "PrereqCivic": "CIVIC_AP_INDUSTRIAL_33"}, + {"Civic": "CIVIC_AP_MODERN_39", "PrereqCivic": "CIVIC_AP_MODERN_37"}, + {"Civic": "CIVIC_AP_MODERN_39", "PrereqCivic": "CIVIC_AP_MODERN_38"}, + {"Civic": "CIVIC_AP_MODERN_36", "PrereqCivic": "CIVIC_AP_MODERN_39"}, + {"Civic": "CIVIC_AP_MODERN_40", "PrereqCivic": "CIVIC_AP_MODERN_39"}, + {"Civic": "CIVIC_AP_MODERN_41", "PrereqCivic": "CIVIC_AP_MODERN_39"}, + {"Civic": "CIVIC_AP_MODERN_42", "PrereqCivic": "CIVIC_AP_MODERN_39"}, + {"Civic": "CIVIC_AP_ATOMIC_43", "PrereqCivic": "CIVIC_AP_MODERN_39"}, + {"Civic": "CIVIC_AP_ATOMIC_44", "PrereqCivic": "CIVIC_AP_MODERN_39"}, + {"Civic": "CIVIC_AP_ATOMIC_45", "PrereqCivic": "CIVIC_AP_MODERN_34"}, + {"Civic": "CIVIC_AP_ATOMIC_46", "PrereqCivic": "CIVIC_AP_ATOMIC_43"}, + {"Civic": "CIVIC_AP_ATOMIC_47", "PrereqCivic": "CIVIC_AP_ATOMIC_43"}, + {"Civic": "CIVIC_AP_INFORMATION_48", "PrereqCivic": "CIVIC_AP_ATOMIC_46"}, + {"Civic": "CIVIC_AP_INFORMATION_48", "PrereqCivic": "CIVIC_AP_ATOMIC_47"}, + {"Civic": "CIVIC_AP_INFORMATION_49", "PrereqCivic": "CIVIC_AP_ATOMIC_47"}, + {"Civic": "CIVIC_AP_INFORMATION_49", "PrereqCivic": "CIVIC_AP_ATOMIC_44"}, + {"Civic": "CIVIC_AP_FUTURE_50", "PrereqCivic": "CIVIC_AP_INFORMATION_48"}, + {"Civic": "CIVIC_AP_FUTURE_50", "PrereqCivic": "CIVIC_AP_INFORMATION_49"}, + {"Civic": "CIVIC_AP_MODERN_38", "PrereqCivic": "CIVIC_AP_INDUSTRIAL_32"}, + {"Civic": "CIVIC_AP_INFORMATION_51", "PrereqCivic": "CIVIC_AP_ATOMIC_45"}, + {"Civic": "CIVIC_AP_INFORMATION_51", "PrereqCivic": "CIVIC_AP_ATOMIC_46"}, + {"Civic": "CIVIC_AP_INFORMATION_52", "PrereqCivic": "CIVIC_AP_INFORMATION_48"}, + {"Civic": "CIVIC_AP_INFORMATION_52", "PrereqCivic": "CIVIC_AP_INFORMATION_49"}, + {"Civic": "CIVIC_AP_INFORMATION_53", "PrereqCivic": "CIVIC_AP_INFORMATION_48"}, + {"Civic": "CIVIC_AP_INFORMATION_53", "PrereqCivic": "CIVIC_AP_INFORMATION_49"}, + {"Civic": "CIVIC_AP_INFORMATION_54", "PrereqCivic": "CIVIC_AP_INFORMATION_48"}, + {"Civic": "CIVIC_AP_INFORMATION_54", "PrereqCivic": "CIVIC_AP_INFORMATION_49"}, + {"Civic": "CIVIC_AP_INFORMATION_55", "PrereqCivic": "CIVIC_AP_INFORMATION_51"}, + {"Civic": "CIVIC_AP_INFORMATION_55", "PrereqCivic": "CIVIC_AP_INFORMATION_48"}, + {"Civic": "CIVIC_AP_FUTURE_56", "PrereqCivic": "CIVIC_AP_FUTURE_50"}, + {"Civic": "CIVIC_AP_FUTURE_57", "PrereqCivic": "CIVIC_AP_FUTURE_50"}, + {"Civic": "CIVIC_AP_FUTURE_58", "PrereqCivic": "CIVIC_AP_FUTURE_50"}, + {"Civic": "CIVIC_AP_FUTURE_59", "PrereqCivic": "CIVIC_AP_FUTURE_50"}, + {"Civic": "CIVIC_AP_FUTURE_60", "PrereqCivic": "CIVIC_AP_FUTURE_50"}, +] diff --git a/worlds/civ_6/data/new_civics.py b/worlds/civ_6/data/new_civics.py new file mode 100644 index 000000000000..e232b67f5c74 --- /dev/null +++ b/worlds/civ_6/data/new_civics.py @@ -0,0 +1,372 @@ +from typing import List +from ..ItemData import NewItemData + + +new_civics: List[NewItemData] = [ + { + "Type": "CIVIC_AP_ANCIENT_00", + "Cost": 20, + "UITreeRow": 0, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "CIVIC_AP_ANCIENT_01", + "Cost": 40, + "UITreeRow": -2, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "CIVIC_AP_ANCIENT_02", + "Cost": 40, + "UITreeRow": 2, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "CIVIC_AP_ANCIENT_03", + "Cost": 50, + "UITreeRow": -3, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "CIVIC_AP_ANCIENT_04", + "Cost": 70, + "UITreeRow": 0, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "CIVIC_AP_ANCIENT_05", + "Cost": 70, + "UITreeRow": 1, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "CIVIC_AP_ANCIENT_06", + "Cost": 50, + "UITreeRow": 3, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "CIVIC_AP_CLASSICAL_07", + "Cost": 110, + "UITreeRow": -2, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "CIVIC_AP_CLASSICAL_08", + "Cost": 110, + "UITreeRow": 0, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "CIVIC_AP_CLASSICAL_09", + "Cost": 110, + "UITreeRow": 2, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "CIVIC_AP_CLASSICAL_10", + "Cost": 120, + "UITreeRow": -3, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "CIVIC_AP_CLASSICAL_11", + "Cost": 175, + "UITreeRow": -1, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "CIVIC_AP_CLASSICAL_12", + "Cost": 175, + "UITreeRow": 1, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "CIVIC_AP_CLASSICAL_13", + "Cost": 120, + "UITreeRow": 3, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "CIVIC_AP_MEDIEVAL_14", + "Cost": 220, + "UITreeRow": -2, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "CIVIC_AP_MEDIEVAL_15", + "Cost": 300, + "UITreeRow": -1, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "CIVIC_AP_MEDIEVAL_16", + "Cost": 300, + "UITreeRow": 1, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "CIVIC_AP_MEDIEVAL_17", + "Cost": 340, + "UITreeRow": -3, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "CIVIC_AP_MEDIEVAL_18", + "Cost": 420, + "UITreeRow": -1, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "CIVIC_AP_MEDIEVAL_19", + "Cost": 420, + "UITreeRow": 1, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "CIVIC_AP_MEDIEVAL_20", + "Cost": 340, + "UITreeRow": 3, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "CIVIC_AP_RENAISSANCE_21", + "Cost": 440, + "UITreeRow": -3, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "CIVIC_AP_RENAISSANCE_22", + "Cost": 600, + "UITreeRow": -1, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "CIVIC_AP_RENAISSANCE_23", + "Cost": 600, + "UITreeRow": 1, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "CIVIC_AP_RENAISSANCE_24", + "Cost": 440, + "UITreeRow": 3, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "CIVIC_AP_RENAISSANCE_25", + "Cost": 720, + "UITreeRow": -1, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "CIVIC_AP_RENAISSANCE_26", + "Cost": 720, + "UITreeRow": 1, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "CIVIC_AP_INDUSTRIAL_27", + "Cost": 800, + "UITreeRow": -3, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "CIVIC_AP_INDUSTRIAL_28", + "Cost": 1010, + "UITreeRow": -1, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "CIVIC_AP_INDUSTRIAL_29", + "Cost": 1010, + "UITreeRow": 0, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "CIVIC_AP_INDUSTRIAL_30", + "Cost": 800, + "UITreeRow": 2, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "CIVIC_AP_INDUSTRIAL_31", + "Cost": 1050, + "UITreeRow": -3, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "CIVIC_AP_INDUSTRIAL_32", + "Cost": 1210, + "UITreeRow": 2, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "CIVIC_AP_INDUSTRIAL_33", + "Cost": 1210, + "UITreeRow": -1, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "CIVIC_AP_MODERN_34", + "Cost": 1540, + "UITreeRow": -3, + "EraType": "ERA_MODERN", + }, + { + "Type": "CIVIC_AP_MODERN_35", + "Cost": 1580, + "UITreeRow": -2, + "EraType": "ERA_MODERN", + }, + { + "Type": "CIVIC_AP_MODERN_36", + "Cost": 1715, + "UITreeRow": -2, + "EraType": "ERA_MODERN", + }, + { + "Type": "CIVIC_AP_MODERN_37", + "Cost": 1540, + "UITreeRow": -1, + "EraType": "ERA_MODERN", + }, + { + "Type": "CIVIC_AP_MODERN_38", + "Cost": 1540, + "UITreeRow": 1, + "EraType": "ERA_MODERN", + }, + { + "Type": "CIVIC_AP_MODERN_39", + "Cost": 1640, + "UITreeRow": -1, + "EraType": "ERA_MODERN", + }, + { + "Type": "CIVIC_AP_MODERN_40", + "Cost": 1640, + "UITreeRow": 0, + "EraType": "ERA_MODERN", + }, + { + "Type": "CIVIC_AP_MODERN_41", + "Cost": 1640, + "UITreeRow": 2, + "EraType": "ERA_MODERN", + }, + { + "Type": "CIVIC_AP_MODERN_42", + "Cost": 1640, + "UITreeRow": 3, + "EraType": "ERA_MODERN", + }, + { + "Type": "CIVIC_AP_ATOMIC_43", + "Cost": 2185, + "UITreeRow": -1, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "CIVIC_AP_ATOMIC_44", + "Cost": 2185, + "UITreeRow": 2, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "CIVIC_AP_ATOMIC_45", + "Cost": 1955, + "UITreeRow": -3, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "CIVIC_AP_ATOMIC_46", + "Cost": 2415, + "UITreeRow": -1, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "CIVIC_AP_ATOMIC_47", + "Cost": 2415, + "UITreeRow": 1, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "CIVIC_AP_INFORMATION_48", + "Cost": 2880, + "UITreeRow": 0, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "CIVIC_AP_INFORMATION_49", + "Cost": 2880, + "UITreeRow": 2, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "CIVIC_AP_FUTURE_50", + "Cost": 3200, + "UITreeRow": 3, + "EraType": "ERA_FUTURE", + }, + { + "Type": "CIVIC_AP_INFORMATION_51", + "Cost": 2880, + "UITreeRow": -2, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "CIVIC_AP_INFORMATION_52", + "Cost": 3000, + "UITreeRow": 0, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "CIVIC_AP_INFORMATION_53", + "Cost": 3000, + "UITreeRow": 1, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "CIVIC_AP_INFORMATION_54", + "Cost": 3000, + "UITreeRow": 2, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "CIVIC_AP_INFORMATION_55", + "Cost": 3100, + "UITreeRow": -1, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "CIVIC_AP_FUTURE_56", + "Cost": 3200, + "UITreeRow": -2, + "EraType": "ERA_FUTURE", + }, + { + "Type": "CIVIC_AP_FUTURE_57", + "Cost": 3200, + "UITreeRow": -1, + "EraType": "ERA_FUTURE", + }, + { + "Type": "CIVIC_AP_FUTURE_58", + "Cost": 3200, + "UITreeRow": 0, + "EraType": "ERA_FUTURE", + }, + { + "Type": "CIVIC_AP_FUTURE_59", + "Cost": 3200, + "UITreeRow": 1, + "EraType": "ERA_FUTURE", + }, + { + "Type": "CIVIC_AP_FUTURE_60", + "Cost": 3200, + "UITreeRow": 2, + "EraType": "ERA_FUTURE", + }, +] diff --git a/worlds/civ_6/data/new_tech.py b/worlds/civ_6/data/new_tech.py new file mode 100644 index 000000000000..2810bd231de6 --- /dev/null +++ b/worlds/civ_6/data/new_tech.py @@ -0,0 +1,468 @@ +from typing import List +from ..ItemData import NewItemData + + +new_tech: List[NewItemData] = [ + { + "Type": "TECH_AP_ANCIENT_00", + "Cost": 25, + "UITreeRow": 0, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_ANCIENT_01", + "Cost": 25, + "UITreeRow": 1, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_ANCIENT_02", + "Cost": 25, + "UITreeRow": 3, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_ANCIENT_03", + "Cost": 50, + "UITreeRow": -3, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_ANCIENT_04", + "Cost": 50, + "UITreeRow": -2, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_ANCIENT_05", + "Cost": 50, + "UITreeRow": -1, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_ANCIENT_06", + "Cost": 50, + "UITreeRow": 1, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_ANCIENT_07", + "Cost": 50, + "UITreeRow": 0, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_ANCIENT_08", + "Cost": 80, + "UITreeRow": 2, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_ANCIENT_09", + "Cost": 80, + "UITreeRow": 3, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_ANCIENT_10", + "Cost": 80, + "UITreeRow": 4, + "EraType": "ERA_ANCIENT", + }, + { + "Type": "TECH_AP_CLASSICAL_11", + "Cost": 120, + "UITreeRow": -2, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "TECH_AP_CLASSICAL_12", + "Cost": 120, + "UITreeRow": 0, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "TECH_AP_CLASSICAL_13", + "Cost": 120, + "UITreeRow": 1, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "TECH_AP_CLASSICAL_14", + "Cost": 120, + "UITreeRow": 3, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "TECH_AP_CLASSICAL_15", + "Cost": 200, + "UITreeRow": -3, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "TECH_AP_CLASSICAL_16", + "Cost": 200, + "UITreeRow": -1, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "TECH_AP_CLASSICAL_17", + "Cost": 200, + "UITreeRow": 2, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "TECH_AP_CLASSICAL_18", + "Cost": 200, + "UITreeRow": 4, + "EraType": "ERA_CLASSICAL", + }, + { + "Type": "TECH_AP_MEDIEVAL_19", + "Cost": 300, + "UITreeRow": -2, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "TECH_AP_MEDIEVAL_20", + "Cost": 300, + "UITreeRow": 0, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "TECH_AP_MEDIEVAL_21", + "Cost": 300, + "UITreeRow": 4, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "TECH_AP_MEDIEVAL_22", + "Cost": 390, + "UITreeRow": -1, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "TECH_AP_MEDIEVAL_23", + "Cost": 390, + "UITreeRow": 1, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "TECH_AP_MEDIEVAL_24", + "Cost": 390, + "UITreeRow": 2, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "TECH_AP_MEDIEVAL_25", + "Cost": 390, + "UITreeRow": 3, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "TECH_AP_RENAISSANCE_26", + "Cost": 600, + "UITreeRow": -3, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "TECH_AP_RENAISSANCE_27", + "Cost": 600, + "UITreeRow": -2, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "TECH_AP_RENAISSANCE_28", + "Cost": 600, + "UITreeRow": 0, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "TECH_AP_RENAISSANCE_29", + "Cost": 600, + "UITreeRow": 1, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "TECH_AP_RENAISSANCE_30", + "Cost": 600, + "UITreeRow": 4, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "TECH_AP_RENAISSANCE_31", + "Cost": 730, + "UITreeRow": -3, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "TECH_AP_RENAISSANCE_32", + "Cost": 730, + "UITreeRow": -1, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "TECH_AP_RENAISSANCE_33", + "Cost": 730, + "UITreeRow": 1, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "TECH_AP_RENAISSANCE_34", + "Cost": 730, + "UITreeRow": 3, + "EraType": "ERA_RENAISSANCE", + }, + { + "Type": "TECH_AP_INDUSTRIAL_35", + "Cost": 930, + "UITreeRow": -2, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "TECH_AP_INDUSTRIAL_36", + "Cost": 930, + "UITreeRow": -1, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "TECH_AP_INDUSTRIAL_37", + "Cost": 930, + "UITreeRow": 1, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "TECH_AP_INDUSTRIAL_38", + "Cost": 930, + "UITreeRow": 3, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "TECH_AP_INDUSTRIAL_39", + "Cost": 1070, + "UITreeRow": -3, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "TECH_AP_INDUSTRIAL_40", + "Cost": 1070, + "UITreeRow": -1, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "TECH_AP_INDUSTRIAL_41", + "Cost": 1070, + "UITreeRow": 0, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "TECH_AP_INDUSTRIAL_42", + "Cost": 1070, + "UITreeRow": 2, + "EraType": "ERA_INDUSTRIAL", + }, + { + "Type": "TECH_AP_MODERN_43", + "Cost": 1250, + "UITreeRow": -2, + "EraType": "ERA_MODERN", + }, + { + "Type": "TECH_AP_MODERN_44", + "Cost": 1250, + "UITreeRow": 0, + "EraType": "ERA_MODERN", + }, + { + "Type": "TECH_AP_MODERN_45", + "Cost": 1250, + "UITreeRow": 1, + "EraType": "ERA_MODERN", + }, + { + "Type": "TECH_AP_MODERN_46", + "Cost": 1370, + "UITreeRow": -3, + "EraType": "ERA_MODERN", + }, + { + "Type": "TECH_AP_MODERN_47", + "Cost": 1370, + "UITreeRow": -2, + "EraType": "ERA_MODERN", + }, + { + "Type": "TECH_AP_MODERN_48", + "Cost": 1370, + "UITreeRow": -1, + "EraType": "ERA_MODERN", + }, + { + "Type": "TECH_AP_MODERN_49", + "Cost": 1370, + "UITreeRow": 2, + "EraType": "ERA_MODERN", + }, + { + "Type": "TECH_AP_ATOMIC_50", + "Cost": 1480, + "UITreeRow": -2, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "TECH_AP_ATOMIC_51", + "Cost": 1480, + "UITreeRow": -1, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "TECH_AP_ATOMIC_52", + "Cost": 1480, + "UITreeRow": 0, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "TECH_AP_ATOMIC_53", + "Cost": 1480, + "UITreeRow": 1, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "TECH_AP_ATOMIC_54", + "Cost": 1480, + "UITreeRow": 2, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "TECH_AP_ATOMIC_55", + "Cost": 1660, + "UITreeRow": -3, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "TECH_AP_ATOMIC_56", + "Cost": 1660, + "UITreeRow": 1, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "TECH_AP_ATOMIC_57", + "Cost": 1660, + "UITreeRow": 2, + "EraType": "ERA_ATOMIC", + }, + { + "Type": "TECH_AP_INFORMATION_58", + "Cost": 1850, + "UITreeRow": -3, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "TECH_AP_INFORMATION_59", + "Cost": 1850, + "UITreeRow": -1, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "TECH_AP_INFORMATION_60", + "Cost": 1850, + "UITreeRow": 0, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "TECH_AP_INFORMATION_61", + "Cost": 1850, + "UITreeRow": 1, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "TECH_AP_INFORMATION_62", + "Cost": 1850, + "UITreeRow": 2, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "TECH_AP_INFORMATION_63", + "Cost": 1850, + "UITreeRow": 3, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "TECH_AP_INFORMATION_64", + "Cost": 2155, + "UITreeRow": -2, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "TECH_AP_INFORMATION_65", + "Cost": 2155, + "UITreeRow": 2, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "TECH_AP_INFORMATION_66", + "Cost": 2155, + "UITreeRow": 1, + "EraType": "ERA_INFORMATION", + }, + { + "Type": "TECH_AP_MEDIEVAL_67", + "Cost": 300, + "UITreeRow": -3, + "EraType": "ERA_MEDIEVAL", + }, + { + "Type": "TECH_AP_MODERN_68", + "Cost": 1250, + "UITreeRow": 3, + "EraType": "ERA_MODERN", + }, + { + "Type": "TECH_AP_FUTURE_69", + "Cost": 2200, + "UITreeRow": -3, + "EraType": "ERA_FUTURE", + }, + { + "Type": "TECH_AP_FUTURE_70", + "Cost": 2200, + "UITreeRow": -2, + "EraType": "ERA_FUTURE", + }, + { + "Type": "TECH_AP_FUTURE_71", + "Cost": 2200, + "UITreeRow": -1, + "EraType": "ERA_FUTURE", + }, + { + "Type": "TECH_AP_FUTURE_72", + "Cost": 2200, + "UITreeRow": 0, + "EraType": "ERA_FUTURE", + }, + { + "Type": "TECH_AP_FUTURE_73", + "Cost": 2200, + "UITreeRow": 1, + "EraType": "ERA_FUTURE", + }, + { + "Type": "TECH_AP_FUTURE_74", + "Cost": 2200, + "UITreeRow": 2, + "EraType": "ERA_FUTURE", + }, + { + "Type": "TECH_AP_FUTURE_75", + "Cost": 2500, + "UITreeRow": 0, + "EraType": "ERA_FUTURE", + }, + { + "Type": "TECH_AP_FUTURE_76", + "Cost": 2600, + "UITreeRow": 0, + "EraType": "ERA_FUTURE", + }, +] diff --git a/worlds/civ_6/data/new_tech_prereqs.py b/worlds/civ_6/data/new_tech_prereqs.py new file mode 100644 index 000000000000..222100c2296f --- /dev/null +++ b/worlds/civ_6/data/new_tech_prereqs.py @@ -0,0 +1,110 @@ +from typing import List + +from ..ItemData import TechPrereqData + + +new_tech_prereqs: List[TechPrereqData] = [ + {"Technology": "TECH_AP_ANCIENT_06", "PrereqTech": "TECH_AP_ANCIENT_01"}, + {"Technology": "TECH_AP_ANCIENT_07", "PrereqTech": "TECH_AP_ANCIENT_00"}, + {"Technology": "TECH_AP_ANCIENT_05", "PrereqTech": "TECH_AP_ANCIENT_00"}, + {"Technology": "TECH_AP_ANCIENT_08", "PrereqTech": "TECH_AP_ANCIENT_02"}, + {"Technology": "TECH_AP_ANCIENT_09", "PrereqTech": "TECH_AP_ANCIENT_02"}, + {"Technology": "TECH_AP_ANCIENT_10", "PrereqTech": "TECH_AP_ANCIENT_02"}, + {"Technology": "TECH_AP_CLASSICAL_15", "PrereqTech": "TECH_AP_ANCIENT_03"}, + {"Technology": "TECH_AP_CLASSICAL_11", "PrereqTech": "TECH_AP_ANCIENT_03"}, + {"Technology": "TECH_AP_CLASSICAL_11", "PrereqTech": "TECH_AP_ANCIENT_04"}, + {"Technology": "TECH_AP_CLASSICAL_12", "PrereqTech": "TECH_AP_ANCIENT_07"}, + {"Technology": "TECH_AP_CLASSICAL_13", "PrereqTech": "TECH_AP_ANCIENT_06"}, + {"Technology": "TECH_AP_CLASSICAL_14", "PrereqTech": "TECH_AP_ANCIENT_09"}, + {"Technology": "TECH_AP_CLASSICAL_16", "PrereqTech": "TECH_AP_CLASSICAL_12"}, + {"Technology": "TECH_AP_CLASSICAL_17", "PrereqTech": "TECH_AP_ANCIENT_08"}, + {"Technology": "TECH_AP_CLASSICAL_17", "PrereqTech": "TECH_AP_CLASSICAL_13"}, + {"Technology": "TECH_AP_CLASSICAL_18", "PrereqTech": "TECH_AP_ANCIENT_10"}, + {"Technology": "TECH_AP_MEDIEVAL_19", "PrereqTech": "TECH_AP_CLASSICAL_16"}, + {"Technology": "TECH_AP_MEDIEVAL_20", "PrereqTech": "TECH_AP_CLASSICAL_12"}, + {"Technology": "TECH_AP_MEDIEVAL_20", "PrereqTech": "TECH_AP_CLASSICAL_13"}, + {"Technology": "TECH_AP_MEDIEVAL_23", "PrereqTech": "TECH_AP_CLASSICAL_13"}, + {"Technology": "TECH_AP_MEDIEVAL_21", "PrereqTech": "TECH_AP_CLASSICAL_14"}, + {"Technology": "TECH_AP_MEDIEVAL_21", "PrereqTech": "TECH_AP_CLASSICAL_18"}, + {"Technology": "TECH_AP_MEDIEVAL_22", "PrereqTech": "TECH_AP_CLASSICAL_16"}, + {"Technology": "TECH_AP_MEDIEVAL_22", "PrereqTech": "TECH_AP_MEDIEVAL_20"}, + {"Technology": "TECH_AP_MEDIEVAL_25", "PrereqTech": "TECH_AP_CLASSICAL_17"}, + {"Technology": "TECH_AP_MEDIEVAL_24", "PrereqTech": "TECH_AP_CLASSICAL_17"}, + {"Technology": "TECH_AP_RENAISSANCE_27", "PrereqTech": "TECH_AP_MEDIEVAL_22"}, + {"Technology": "TECH_AP_RENAISSANCE_28", "PrereqTech": "TECH_AP_MEDIEVAL_22"}, + {"Technology": "TECH_AP_RENAISSANCE_28", "PrereqTech": "TECH_AP_MEDIEVAL_23"}, + {"Technology": "TECH_AP_RENAISSANCE_29", "PrereqTech": "TECH_AP_MEDIEVAL_20"}, + {"Technology": "TECH_AP_RENAISSANCE_29", "PrereqTech": "TECH_AP_MEDIEVAL_23"}, + {"Technology": "TECH_AP_RENAISSANCE_29", "PrereqTech": "TECH_AP_MEDIEVAL_24"}, + {"Technology": "TECH_AP_RENAISSANCE_30", "PrereqTech": "TECH_AP_MEDIEVAL_21"}, + {"Technology": "TECH_AP_RENAISSANCE_31", "PrereqTech": "TECH_AP_RENAISSANCE_26"}, + {"Technology": "TECH_AP_RENAISSANCE_32", "PrereqTech": "TECH_AP_MEDIEVAL_22"}, + {"Technology": "TECH_AP_RENAISSANCE_33", "PrereqTech": "TECH_AP_RENAISSANCE_29"}, + {"Technology": "TECH_AP_RENAISSANCE_34", "PrereqTech": "TECH_AP_MEDIEVAL_25"}, + {"Technology": "TECH_AP_INDUSTRIAL_35", "PrereqTech": "TECH_AP_RENAISSANCE_31"}, + {"Technology": "TECH_AP_INDUSTRIAL_35", "PrereqTech": "TECH_AP_RENAISSANCE_27"}, + {"Technology": "TECH_AP_INDUSTRIAL_36", "PrereqTech": "TECH_AP_RENAISSANCE_32"}, + {"Technology": "TECH_AP_INDUSTRIAL_36", "PrereqTech": "TECH_AP_RENAISSANCE_28"}, + {"Technology": "TECH_AP_INDUSTRIAL_41", "PrereqTech": "TECH_AP_INDUSTRIAL_36"}, + {"Technology": "TECH_AP_INDUSTRIAL_41", "PrereqTech": "TECH_AP_RENAISSANCE_33"}, + {"Technology": "TECH_AP_INDUSTRIAL_38", "PrereqTech": "TECH_AP_RENAISSANCE_34"}, + {"Technology": "TECH_AP_INDUSTRIAL_38", "PrereqTech": "TECH_AP_RENAISSANCE_30"}, + {"Technology": "TECH_AP_INDUSTRIAL_39", "PrereqTech": "TECH_AP_INDUSTRIAL_35"}, + {"Technology": "TECH_AP_INDUSTRIAL_40", "PrereqTech": "TECH_AP_INDUSTRIAL_36"}, + {"Technology": "TECH_AP_INDUSTRIAL_37", "PrereqTech": "TECH_AP_RENAISSANCE_33"}, + {"Technology": "TECH_AP_INDUSTRIAL_42", "PrereqTech": "TECH_AP_INDUSTRIAL_37"}, + {"Technology": "TECH_AP_INDUSTRIAL_42", "PrereqTech": "TECH_AP_INDUSTRIAL_38"}, + {"Technology": "TECH_AP_MODERN_43", "PrereqTech": "TECH_AP_INDUSTRIAL_35"}, + {"Technology": "TECH_AP_MODERN_43", "PrereqTech": "TECH_AP_INDUSTRIAL_36"}, + {"Technology": "TECH_AP_MODERN_44", "PrereqTech": "TECH_AP_INDUSTRIAL_41"}, + {"Technology": "TECH_AP_MODERN_45", "PrereqTech": "TECH_AP_INDUSTRIAL_42"}, + {"Technology": "TECH_AP_MODERN_46", "PrereqTech": "TECH_AP_INDUSTRIAL_39"}, + {"Technology": "TECH_AP_MODERN_47", "PrereqTech": "TECH_AP_INDUSTRIAL_39"}, + {"Technology": "TECH_AP_MODERN_47", "PrereqTech": "TECH_AP_MODERN_43"}, + {"Technology": "TECH_AP_MODERN_48", "PrereqTech": "TECH_AP_INDUSTRIAL_40"}, + {"Technology": "TECH_AP_MODERN_49", "PrereqTech": "TECH_AP_MODERN_45"}, + {"Technology": "TECH_AP_ATOMIC_55", "PrereqTech": "TECH_AP_MODERN_46"}, + {"Technology": "TECH_AP_ATOMIC_55", "PrereqTech": "TECH_AP_MODERN_47"}, + {"Technology": "TECH_AP_ATOMIC_50", "PrereqTech": "TECH_AP_MODERN_47"}, + {"Technology": "TECH_AP_ATOMIC_51", "PrereqTech": "TECH_AP_MODERN_47"}, + {"Technology": "TECH_AP_ATOMIC_51", "PrereqTech": "TECH_AP_MODERN_48"}, + {"Technology": "TECH_AP_ATOMIC_52", "PrereqTech": "TECH_AP_MODERN_44"}, + {"Technology": "TECH_AP_ATOMIC_52", "PrereqTech": "TECH_AP_MODERN_45"}, + {"Technology": "TECH_AP_ATOMIC_53", "PrereqTech": "TECH_AP_MODERN_45"}, + {"Technology": "TECH_AP_ATOMIC_53", "PrereqTech": "TECH_AP_MODERN_49"}, + {"Technology": "TECH_AP_ATOMIC_56", "PrereqTech": "TECH_AP_ATOMIC_52"}, + {"Technology": "TECH_AP_ATOMIC_56", "PrereqTech": "TECH_AP_ATOMIC_53"}, + {"Technology": "TECH_AP_ATOMIC_54", "PrereqTech": "TECH_AP_MODERN_49"}, + {"Technology": "TECH_AP_ATOMIC_57", "PrereqTech": "TECH_AP_ATOMIC_54"}, + {"Technology": "TECH_AP_INFORMATION_58", "PrereqTech": "TECH_AP_ATOMIC_55"}, + {"Technology": "TECH_AP_INFORMATION_64", "PrereqTech": "TECH_AP_ATOMIC_55"}, + {"Technology": "TECH_AP_INFORMATION_59", "PrereqTech": "TECH_AP_ATOMIC_50"}, + {"Technology": "TECH_AP_INFORMATION_59", "PrereqTech": "TECH_AP_ATOMIC_51"}, + {"Technology": "TECH_AP_INFORMATION_60", "PrereqTech": "TECH_AP_ATOMIC_51"}, + {"Technology": "TECH_AP_INFORMATION_60", "PrereqTech": "TECH_AP_ATOMIC_52"}, + {"Technology": "TECH_AP_INFORMATION_61", "PrereqTech": "TECH_AP_ATOMIC_56"}, + {"Technology": "TECH_AP_INFORMATION_62", "PrereqTech": "TECH_AP_ATOMIC_57"}, + {"Technology": "TECH_AP_INFORMATION_63", "PrereqTech": "TECH_AP_ATOMIC_57"}, + {"Technology": "TECH_AP_INFORMATION_65", "PrereqTech": "TECH_AP_INFORMATION_62"}, + {"Technology": "TECH_AP_INFORMATION_66", "PrereqTech": "TECH_AP_INFORMATION_61"}, + {"Technology": "TECH_AP_MEDIEVAL_67", "PrereqTech": "TECH_AP_CLASSICAL_15"}, + {"Technology": "TECH_AP_MEDIEVAL_67", "PrereqTech": "TECH_AP_CLASSICAL_16"}, + {"Technology": "TECH_AP_MEDIEVAL_23", "PrereqTech": "TECH_AP_MEDIEVAL_20"}, + {"Technology": "TECH_AP_MODERN_68", "PrereqTech": "TECH_AP_INDUSTRIAL_42"}, + {"Technology": "TECH_AP_MODERN_49", "PrereqTech": "TECH_AP_MODERN_68"}, + {"Technology": "TECH_AP_RENAISSANCE_26", "PrereqTech": "TECH_AP_MEDIEVAL_67"}, + {"Technology": "TECH_AP_RENAISSANCE_27", "PrereqTech": "TECH_AP_MEDIEVAL_67"}, + {"Technology": "TECH_AP_RENAISSANCE_27", "PrereqTech": "TECH_AP_MEDIEVAL_19"}, + {"Technology": "TECH_AP_MODERN_48", "PrereqTech": "TECH_AP_MODERN_44"}, + {"Technology": "TECH_AP_INFORMATION_64", "PrereqTech": "TECH_AP_INFORMATION_59"}, + {"Technology": "TECH_AP_INFORMATION_64", "PrereqTech": "TECH_AP_INFORMATION_60"}, + {"Technology": "TECH_AP_INFORMATION_64", "PrereqTech": "TECH_AP_INFORMATION_61"}, + {"Technology": "TECH_AP_FUTURE_69", "PrereqTech": "TECH_AP_AP60"}, + {"Technology": "TECH_AP_FUTURE_70", "PrereqTech": "TECH_AP_AP60"}, + {"Technology": "TECH_AP_FUTURE_71", "PrereqTech": "TECH_AP_AP60"}, + {"Technology": "TECH_AP_FUTURE_72", "PrereqTech": "TECH_AP_AP60"}, + {"Technology": "TECH_AP_FUTURE_73", "PrereqTech": "TECH_AP_AP60"}, + {"Technology": "TECH_AP_FUTURE_74", "PrereqTech": "TECH_AP_AP60"}, + {"Technology": "TECH_AP_FUTURE_75", "PrereqTech": "TECH_AP_AP60"}, + {"Technology": "TECH_AP_FUTURE_76", "PrereqTech": "TECH_AP_AP60"}, +] diff --git a/worlds/civ_6/data/progressive_districts.py b/worlds/civ_6/data/progressive_districts.py new file mode 100644 index 000000000000..e75fbc616841 --- /dev/null +++ b/worlds/civ_6/data/progressive_districts.py @@ -0,0 +1,41 @@ +from typing import Dict, List + + +progressive_districts: Dict[str, List[str]] = { + "PROGRESSIVE_CAMPUS": ["TECH_WRITING", "TECH_EDUCATION", "TECH_CHEMISTRY"], + "PROGRESSIVE_THEATER": ["CIVIC_DRAMA_POETRY", "CIVIC_HUMANISM", "TECH_RADIO"], + "PROGRESSIVE_HOLY_SITE": ["TECH_ASTROLOGY", "CIVIC_THEOLOGY"], + "PROGRESSIVE_ENCAMPMENT": [ + "TECH_BRONZE_WORKING", + "TECH_MILITARY_ENGINEERING", + "TECH_MILITARY_SCIENCE", + ], + "PROGRESSIVE_COMMERCIAL_HUB": ["TECH_CURRENCY", "TECH_BANKING", "TECH_ECONOMICS"], + "PROGRESSIVE_HARBOR": ["TECH_CELESTIAL_NAVIGATION", "TECH_MASS_PRODUCTION"], + "PROGRESSIVE_INDUSTRIAL_ZONE": [ + "TECH_APPRENTICESHIP", + "TECH_INDUSTRIALIZATION", + "TECH_ELECTRICITY", + "TECH_NUCLEAR_FISSION", + ], + "PROGRESSIVE_PRESERVE": ["CIVIC_MYSTICISM", "CIVIC_CONSERVATION"], + "PROGRESSIVE_ENTERTAINMENT_COMPLEX": [ + "CIVIC_GAMES_RECREATION", + "CIVIC_NATURAL_HISTORY", + "CIVIC_PROFESSIONAL_SPORTS", + ], + "PROGRESSIVE_NEIGHBORHOOD": [ + "CIVIC_URBANIZATION", + "TECH_REPLACEABLE_PARTS", + "CIVIC_CAPITALISM", + ], + "PROGRESSIVE_AERODROME": ["TECH_FLIGHT", "TECH_ADVANCED_FLIGHT"], + "PROGRESSIVE_DIPLOMATIC_QUARTER": ["TECH_MATHEMATICS", "CIVIC_DIPLOMATIC_SERVICE"], + "PROGRESSIVE_SPACE_PORT": [ + "TECH_ROCKETRY", + "TECH_SATELLITES", + "TECH_NANOTECHNOLOGY", + "TECH_SMART_MATERIALS", + "TECH_OFFWORLD_MISSION", + ], +} diff --git a/worlds/civ_6/docs/en_Civilization VI.md b/worlds/civ_6/docs/en_Civilization VI.md new file mode 100644 index 000000000000..3b1fbbdb055a --- /dev/null +++ b/worlds/civ_6/docs/en_Civilization VI.md @@ -0,0 +1,59 @@ +# Civilization 6 Archipelago + +## What does randomization do to this game? + +In Civilization VI, the tech and civic trees are both shuffled. This presents some interesting ways to play the game in a non-standard way. If you are feeling adventurous, you can enable the "boostsanity" option in order to really change up the way you normally would play a Civ game. Details on the option can be found in the [Boostsanity](#boostsanity) section below. + +There are a few changes that the Archipelago mod introduces in order to make this playable/fun. These are detailed in the [__FAQ__](#faqs) section below. + +## What is the goal of Civilization VI when randomized? +The goal of randomized Civilization VI remains the same. Pursue any victory type you have enabled in your game settings, the one you normally go for may or may not be feasible based on how things have been changed up! + +## Which items can be in another player's world? +All technologies and civics can be found in another player's world. + +## What does another world's item look like in Civilization VI? +Each item from another world is represented as a researchable tech/civic in your normal tech/civic trees. + +## When the player receives an item, what happens? +A short period after receiving an item, you will get a notification indicating you have discovered the relevant tech/civic. You will also get the regular popup that details what the given item has unlocked for you. + +## FAQs +- Do I need the DLC to play this? + - Yes, you need both Rise & Fall and Gathering Storm. +- Does this work with Multiplayer? + - It does not and, despite my best efforts, probably won't until there's a new way for external programs to be able to interact with the game. +- Does my mod that reskins Barbarians as various Pro Wrestlers work with this? + - Only one way to find out! Any mods that modify techs/civics will most likely cause issues, though. +- "Help! I can't see any of the items that have been sent to me!" + - Both trees by default will show you the researchable Archipelago locations. To view the normal tree, you can click "Toggle Archipelago Tree" in the top-left corner of the tree view. +- "Oh no! I received the Machinery tech and now instead of getting an Archer next turn, I have to wait an additional 10 turns to get a Crossbowman!" + - Vanilla prevents you from building units of the same class from an earlier tech level after you have researched a later variant. For example, this could be problematic if someone unlocks Crossbowmen for you right out the gate since you won't be able to make Archers (which have a much lower production cost). +Solution: You can now go in to the tech tree, click "Toggle Archipelago Tree" to view your unlocked techs, and then can click any tech you have unlocked to toggle whether it is currently active or not. +- "How does DeathLink work? Am I going to have to start a new game every time one of my friends dies?" + - Heavens no, my fellow Archipelago appreciator. When configuring your Archipelago options for Civilization on the options page, there are several choices available for you to fine tune the way you'd like to be punished for the follies of your friends. These include: Having a random unit destroyed, losing a percentage of gold or faith, or even losing a point on your era score. If you can't make up your mind, you can elect to have any of them be selected every time a death link is sent your way. + In the event you lose one of your units in combat (this means captured units don't count), then you will send a death link event to the rest of your friends. + +- I enabled `progressive districts` but I have no idea what tech or civic a progressive district unlocks for me! + - Any technology or civic that grants you a new building in a district (or grants you the district itself) is now locked behind a progressive item. For example, `PROGRESSIVE_CAMPUS` would give you these items in the following order: + 1. `TECH_WRITING` + 2. `TECH_EDUCATION` + 3. `TECH_CHEMISTRY` + - If you want to see the details around each item, you can review [this file](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/civ_6/data/progressive_districts.json). + +## Boostsanity +Boostsanity takes all of the Eureka & Inspiration events and makes them location checks. This feature is the one to change up the way Civilization is played in an AP multiworld/randomizer. What normally are mundane tasks that are passively collected now become a novel and interesting bucket list that you need to pay attention to in order to unlock items for yourself and others! +Boosts have logic associated with them in order to verify you can always reach the ones you need to, when you need to. One side effect of this is that when boostsanity is enabled, some previously "Useful" items are now flagged as "Progression" (Urbanization, Pottery, The Wheel, to name a few). + +### Boostsanity FAQs +- Someone sent me a tech/civic, and I'm worried I won't be able to boost it anymore! + - Fear not! Through a lot of wizardry 🧙‍♂️ you can boost civics/techs that have already been received. Additionally, the UI has been updated to show you whether they have been boosted or not after receiving them. +- I need to kill a unit with a slinger/archer/musketman or some other obsolete unit I can't build anymore, how can I do this? + - Don't forget you can go into the Tech Tree and click on a Vanilla tech you've received in order to toggle it on/off. This is necessary in order to pursue some of the boosts if you receive techs in certain orders. +- Something happened, and I'm not able to unlock the boost due to game rules! + - A few scenarios you may worry about: "Found a religion", "Make an alliance with another player", "Develop an alliance to level 2", "Build a wonder from X Era", to name a few. Any boost that is "miss-able" has been flagged as an "Excluded" location and will not ever receive a progression item. For a list of how each boost is flagged, take a look [here](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/civ_6/data/boosts.json). +- I'm worried that my `PROGRESSIVE_ERA` item is going to be stuck in a boost I won't have time to complete before my maximum unlocked era ends! + - The unpredictable timing of boosts and unlocking them can occasionally lead to scenarios where you'll have to first encounter a locked era defeat and then load a previous save. To help reduce the frequency of this, local `PROGRESSIVE_ERA` items will never be located at a boost check. +- There's too many boosts, how will I know which one's I should focus on?! + - In order to give a little more focus to all the boosts rather than just arbitrarily picking them at random, items in both of the vanilla trees will now have an advisor icon on them if its associated boost contains a progression item. + diff --git a/worlds/civ_6/docs/setup_en.md b/worlds/civ_6/docs/setup_en.md new file mode 100644 index 000000000000..09f6ff55c5e0 --- /dev/null +++ b/worlds/civ_6/docs/setup_en.md @@ -0,0 +1,51 @@ +# Setup Guide for Civilization VI Archipelago + +This guide is meant to help you get up and running with Civilization VI in Archipelago. Note that this requires you to have both Rise & Fall and Gathering Storm installed. This will not work unless both of those DLCs are enabled. + +## Requirements + +The following are required in order to play Civ VI in Archipelago: + +- Windows OS (Firaxis does not support the necessary tooling for Mac, or Linux) + +- Installed [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) v0.4.5 or higher. + +- The latest version of the [Civ VI AP Mod](https://github.com/hesto2/civilization_archipelago_mod/releases/latest). + +## Enabling the tuner + +Depending on how you installed Civ 6 you will have to navigate to one of the following: + +- `YOUR_USER/Documents/My Games/Sid Meier's Civilization VI/AppOptions.txt` +- `YOUR_USER/AppData/Local/Firaxis Games/Sid Meier's Civilization VI/AppOptions.txt` + +Once you have located your `AppOptions.txt`, do a search for `Enable FireTuner`. Set `EnableTuner` to `1` instead of `0`. **NOTE**: While this is active, achievements will be disabled. + +## Mod Installation + +1. Download and unzip the latest release of the mod from [GitHub](https://github.com/hesto2/civilization_archipelago_mod/releases/latest). + +2. Copy the folder containing the mod files to your Civ VI mods folder. On Windows, this is usually located at `C:\Users\YOUR_USER\Documents\My Games\Sid Meier's Civilization VI\Mods`. + +3. After the Archipelago host generates a game, you should be given a `.apcivvi` file. Associate the file with the Archipelago Launcher and double click it. + +4. Copy the contents of the new folder it generates (it will have the same name as the `.apcivvi` file) into your Civilization VI Archipelago Mod folder. + +5. Your finished mod folder should look something like this: + +- Civ VI Mods Directory + - civilization_archipelago_mod + - NewItems.xml + - InitOptions.lua + - Archipelago.modinfo + - All the other mod files, etc. + +## Configuring your game + +When configuring your game, make sure to start the game in the Ancient Era and leave all settings related to starting technologies and civics as the defaults. Other than that, configure difficulty, AI, etc. as you normally would. + +## Troubleshooting + +- If you are getting an error: "The remote computer refused the network connection", or something else related to the client (or tuner) not being able to connect, it likely indicates the tuner is not actually enabled. One simple way to verify that it is enabled is, after completing the setup steps, go to Main Menu → Options → Look for an option named "Tuner" and verify it is set to "Enabled" + +- If your game gets in a state where someone has sent you items or you have sent locations but these are not correctly sent to the multiworld, you can run `/resync` from the Civ 6 client. This may take up to a minute depending on how many items there are. diff --git a/worlds/civ_6/test/TestBoostsanity.py b/worlds/civ_6/test/TestBoostsanity.py new file mode 100644 index 000000000000..6efed6c66e25 --- /dev/null +++ b/worlds/civ_6/test/TestBoostsanity.py @@ -0,0 +1,107 @@ +from Fill import distribute_items_restrictive +from ..Data import get_boosts_data +from . import CivVITestBase + + +class TestBoostsanityIncluded(CivVITestBase): + auto_construct = False + options = { + "progressive_eras": "true", + "boostsanity": "true", + "progression_style": "none", + "shuffle_goody_hut_rewards": "false", + } + + def test_boosts_get_included(self) -> None: + self.world_setup() + distribute_items_restrictive(self.multiworld) + locations = self.multiworld.get_locations(self.player) + found_locations = 0 + for location in locations: + if "BOOST" in location.name: + found_locations += 1 + num_boost_locations = len(get_boosts_data()) + self.assertEqual(found_locations, num_boost_locations) + + def test_boosts_require_prereqs_no_progressives(self) -> None: + self.world_setup() + location = "BOOST_TECH_ADVANCED_BALLISTICS" + items_to_give = ["Refining", "Electricity", "Apprenticeship", "Industrialization"] + self.assertFalse(self.can_reach_location(location)) + + for prereq in items_to_give: + self.collect_by_name(prereq) + is_last_prereq = prereq == items_to_give[-1] + self.assertEqual(self.can_reach_location(location), is_last_prereq) + + +class TestBoostsanityIncludedNoProgressiveDistricts(CivVITestBase): + auto_construct = False + options = { + "progressive_eras": "true", + "boostsanity": "true", + "progression_style": "districts_only", + "shuffle_goody_hut_rewards": "false", + } + + def test_boosts_get_included(self) -> None: + self.world_setup() + distribute_items_restrictive(self.multiworld) + locations = self.multiworld.get_locations(self.player) + found_locations = 0 + for location in locations: + if "BOOST" in location.name: + found_locations += 1 + num_boost_locations = len(get_boosts_data()) + self.assertEqual(found_locations, num_boost_locations) + + +class TestBoostsanityPrereqsWithProgressiveDistricts(CivVITestBase): + options = { + "progressive_eras": "true", + "boostsanity": "true", + "progression_style": "districts_only", + "shuffle_goody_hut_rewards": "false", + } + + def test_boosts_require_progressive_prereqs_optional(self) -> None: + location = "BOOST_TECH_NUCLEAR_FUSION" + items_to_give = ["Progressive Industrial Zone", "Progressive Industrial Zone"] + + self.assertFalse(self.can_reach_location(location)) + for prereq in items_to_give: + self.collect_by_name(prereq) + is_last_prereq = prereq == items_to_give[-1] + self.assertEqual(self.can_reach_location(location), is_last_prereq) + + def tests_boosts_require_correct_progressive_district_count(self) -> None: + location = "BOOST_TECH_RIFLING" + items_to_give = ["Mining", "Progressive Encampment", "Progressive Encampment"] + + self.assertFalse(self.can_reach_location(location)) + for prereq in items_to_give: + self.collect_by_name(prereq) + is_last_prereq = prereq == items_to_give[-1] + self.assertEqual(self.can_reach_location(location), is_last_prereq) + + +class TestBoostsanityExcluded(CivVITestBase): + auto_construct = False + options = { + "progressive_eras": "true", + "death_link": "true", + "boostsanity": "false", + "death_link_effect": "unit_killed", + "progressive_districts": "true", + "shuffle_goody_hut_rewards": "false", + } + + def test_boosts_are_not_included(self) -> None: + self.world_setup() + distribute_items_restrictive(self.multiworld) + locations = self.multiworld.get_locations(self.player) + found_locations = 0 + for location in locations: + if "BOOST" in location.name: + found_locations += 1 + self.assertEqual(found_locations, 0) diff --git a/worlds/civ_6/test/TestGoodyHuts.py b/worlds/civ_6/test/TestGoodyHuts.py new file mode 100644 index 000000000000..a55c74f38ed4 --- /dev/null +++ b/worlds/civ_6/test/TestGoodyHuts.py @@ -0,0 +1,114 @@ +from typing import Dict +from BaseClasses import ItemClassification +from Fill import distribute_items_restrictive +from ..Items import FillerItemRarity, filler_data +from . import CivVITestBase + + +class TestGoodyHutsIncluded(CivVITestBase): + auto_construct = False + options = { + "progressive_eras": "true", + "progressive_districts": "true", + "shuffle_goody_hut_rewards": "true", + } + + def test_goody_huts_get_included(self) -> None: + self.world_setup() + self.world.generate_early() + distribute_items_restrictive(self.multiworld) + expected_goody_huts = 10 + found = 0 + for location in self.multiworld.get_locations(self.player): + if location.name.startswith("GOODY_HUT_"): + found += 1 + self.assertEqual(found, expected_goody_huts) + + +class TestGoodyHutsExcluded(CivVITestBase): + auto_construct = False + options = { + "progressive_eras": "true", + "progressive_districts": "true", + "shuffle_goody_hut_rewards": "false", + } + + def test_goody_huts_are_not_included(self) -> None: + self.world_setup() + self.world.generate_early() + distribute_items_restrictive(self.multiworld) + found_goody_huts = 0 + for location in self.multiworld.get_locations(self.player): + if location.name.startswith("GOODY_HUT_"): + found_goody_huts += 1 + self.assertEqual(found_goody_huts, 0) + + +class TestFillerItemsIncludedByRarity(CivVITestBase): + auto_construct = False + options = { + "progressive_eras": "true", + "progressive_districts": "true", + "shuffle_goody_hut_rewards": "true", + "boostsanity": "true" + } + + def test_filler_items_are_included_by_rarity(self) -> None: + self.world_setup() + self.world.generate_early() + distribute_items_restrictive(self.multiworld) + rarity_counts: Dict[FillerItemRarity, int] = { + FillerItemRarity.COMMON: 0, + FillerItemRarity.UNCOMMON: 0, + FillerItemRarity.RARE: 0, + } + total_filler_items = 0 + for item in self.multiworld.itempool: + if item.classification == ItemClassification.filler: + rarity = filler_data[item.name].rarity + rarity_counts[rarity] += 1 + total_filler_items += 1 + + expected_counts = { + FillerItemRarity.COMMON: 101, + FillerItemRarity.UNCOMMON: 27, + FillerItemRarity.RARE: 4, + } + + for rarity, expected in expected_counts.items(): + self.assertEqual(rarity_counts[rarity], expected, f"Expected {expected} {rarity} items, found {rarity_counts[rarity]}") + + +class TestFillerItemsIncludedByRarityWithoutBoostsanity(CivVITestBase): + auto_construct = False + options = { + "progressive_eras": "true", + "progressive_districts": "true", + "shuffle_goody_hut_rewards": "true", + "boostsanity": "false" + } + + def test_filler_items_are_included_by_rarity_without_boostsanity(self) -> None: + self.world_setup() + self.world.generate_early() + distribute_items_restrictive(self.multiworld) + rarity_counts: Dict[FillerItemRarity, int] = { + FillerItemRarity.COMMON: 0, + FillerItemRarity.UNCOMMON: 0, + FillerItemRarity.RARE: 0, + } + total_filler_items = 0 + for item in self.multiworld.itempool: + if item.classification == ItemClassification.filler: + rarity = filler_data[item.name].rarity + rarity_counts[rarity] += 1 + total_filler_items += 1 + + expected_counts = { + FillerItemRarity.COMMON: 7, + FillerItemRarity.UNCOMMON: 2, + FillerItemRarity.RARE: 1, + } + + for rarity, expected in expected_counts.items(): + self.assertEqual(rarity_counts[rarity], expected, f"Expected {expected} {rarity} items, found {rarity_counts[rarity]}") diff --git a/worlds/civ_6/test/TestRegionRequirements.py b/worlds/civ_6/test/TestRegionRequirements.py new file mode 100644 index 000000000000..6ab945798fa2 --- /dev/null +++ b/worlds/civ_6/test/TestRegionRequirements.py @@ -0,0 +1,234 @@ +from typing import Callable, List + +from BaseClasses import CollectionState +from ..Data import get_era_required_items_data +from ..Enum import EraType +from ..ProgressiveDistricts import convert_items_to_progressive_items +from ..Items import get_item_by_civ_name +from . import CivVITestBase + + +def collect_items_for_era(test: CivVITestBase, era: EraType) -> None: + era_required_items = get_era_required_items_data() + items = [ + get_item_by_civ_name(item, test.world.item_table).name + for item in era_required_items[era.value] + ] + test.collect_by_name(items) + + +def collect_items_for_era_progressive(test: CivVITestBase, era: EraType) -> None: + era_progression_items = get_era_required_items_data() + progressive_items = convert_items_to_progressive_items( + era_progression_items[era.value] + ) + items = [ + get_item_by_civ_name(item, test.world.item_table).name + for item in progressive_items + ] + for item in items: + test.collect(test.get_item_by_name(item)) + + +def verify_eras_accessible( + test: CivVITestBase, + state: CollectionState, + collect_func: Callable[[CivVITestBase, EraType], None], +) -> None: + """Collect for an era, then check if the next era is accessible and the one after that is not""" + for era in EraType: + if era == EraType.ERA_ANCIENT: + test.assertTrue(state.can_reach(era.value, "Region", test.player)) + else: + test.assertFalse(state.can_reach(era.value, "Region", test.player)) + + eras = [ + EraType.ERA_ANCIENT, + EraType.ERA_CLASSICAL, + EraType.ERA_MEDIEVAL, + EraType.ERA_RENAISSANCE, + EraType.ERA_INDUSTRIAL, + EraType.ERA_MODERN, + EraType.ERA_ATOMIC, + EraType.ERA_INFORMATION, + EraType.ERA_FUTURE, + ] + + for i in range(len(eras) - 1): + collect_func(test, eras[i]) + test.assertTrue(state.can_reach(eras[i + 1].value, "Region", test.player)) + if i + 2 < len(eras): + test.assertFalse(state.can_reach(eras[i + 2].value, "Region", test.player)) + + +class TestNonProgressiveRegionRequirements(CivVITestBase): + options = { + "progression_style": "none", + "boostsanity": "false", + } + + def test_eras_are_accessible_without_progressive_districts(self) -> None: + state = self.multiworld.state + verify_eras_accessible(self, state, collect_items_for_era) + + +class TestNonProgressiveRegionRequirementsWithBoostsanity(CivVITestBase): + options = { + "progression_style": "none", + "boostsanity": "true", + } + + def test_eras_are_accessible_without_progressive_districts(self) -> None: + state = self.multiworld.state + verify_eras_accessible(self, state, collect_items_for_era) + + +class TestProgressiveDistrictRequirementsWithBoostsanity(CivVITestBase): + options = { + "progression_style": "districts_only", + "boostsanity": "true", + } + + def test_eras_are_accessible_with_progressive_districts(self) -> None: + state = self.multiworld.state + verify_eras_accessible(self, state, collect_items_for_era_progressive) + + +class TestProgressiveDistrictRequirements(CivVITestBase): + options = { + "progression_style": "districts_only", + "boostsanity": "false", + } + + def test_eras_are_accessible_with_progressive_districts(self) -> None: + state = self.multiworld.state + verify_eras_accessible(self, state, collect_items_for_era_progressive) + + def test_progressive_districts_are_required(self) -> None: + state = self.multiworld.state + self.collect_all_but(["Progressive Encampment"]) + self.assertFalse(state.can_reach("ERA_CLASSICAL", "Region", self.player)) + self.assertFalse(state.can_reach("ERA_RENAISSANCE", "Region", self.player)) + self.assertFalse(state.can_reach("ERA_MODERN", "Region", self.player)) + + self.collect(self.get_item_by_name("Progressive Encampment")) + self.assertTrue(state.can_reach("ERA_CLASSICAL", "Region", self.player)) + self.assertFalse(state.can_reach("ERA_RENAISSANCE", "Region", self.player)) + self.assertFalse(state.can_reach("ERA_MODERN", "Region", self.player)) + + self.collect(self.get_item_by_name("Progressive Encampment")) + self.assertTrue(state.can_reach("ERA_RENAISSANCE", "Region", self.player)) + self.assertFalse(state.can_reach("ERA_MODERN", "Region", self.player)) + + self.collect(self.get_item_by_name("Progressive Encampment")) + self.assertTrue(state.can_reach("ERA_MODERN", "Region", self.player)) + + +class TestProgressiveEraRequirements(CivVITestBase): + options = { + "progression_style": "eras_and_districts", + } + + def test_eras_are_accessible_with_progressive_eras(self) -> None: + state = self.multiworld.state + self.collect_all_but(["Progressive Era"]) + + def check_eras_accessible(eras: List[EraType]): + for era in EraType: + if era in eras: + self.assertTrue(state.can_reach(era.value, "Region", self.player)) + else: + self.assertFalse(state.can_reach(era.value, "Region", self.player)) + + progresive_era_item = self.get_item_by_name("Progressive Era") + accessible_eras = [EraType.ERA_ANCIENT] + check_eras_accessible(accessible_eras) + + # Classical era requires 2 progressive era items + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_CLASSICAL] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_MEDIEVAL] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_RENAISSANCE] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_INDUSTRIAL] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_MODERN] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_ATOMIC] + check_eras_accessible(accessible_eras) + + # Since we collect 2 in the ancient era, information and future era have same logic requirement + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_INFORMATION] + accessible_eras += [EraType.ERA_FUTURE] + check_eras_accessible(accessible_eras) + + +class TestProgressiveEraRequirementsWithBoostsanity(CivVITestBase): + options = { + "progression_style": "eras_and_districts", + "boostsanity": "true", + } + + def test_eras_are_accessible_with_progressive_eras(self) -> None: + state = self.multiworld.state + self.collect_all_but(["Progressive Era"]) + + def check_eras_accessible(eras: List[EraType]): + for era in EraType: + if era in eras: + self.assertTrue( + state.can_reach(era.value, "Region", self.player), + "Failed for era: " + era.value, + ) + else: + self.assertFalse( + state.can_reach(era.value, "Region", self.player), + "Failed for era: " + era.value, + ) + + progresive_era_item = self.get_item_by_name("Progressive Era") + accessible_eras = [EraType.ERA_ANCIENT] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_CLASSICAL] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_MEDIEVAL] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_RENAISSANCE] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_INDUSTRIAL] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_MODERN] + check_eras_accessible(accessible_eras) + + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_ATOMIC] + check_eras_accessible(accessible_eras) + + # Since we collect 2 in the ancient era, information and future era have same logic requirement + self.collect(progresive_era_item) + accessible_eras += [EraType.ERA_INFORMATION] + accessible_eras += [EraType.ERA_FUTURE] + check_eras_accessible(accessible_eras) diff --git a/worlds/civ_6/test/TestStartingHints.py b/worlds/civ_6/test/TestStartingHints.py new file mode 100644 index 000000000000..da198c6a45e8 --- /dev/null +++ b/worlds/civ_6/test/TestStartingHints.py @@ -0,0 +1,125 @@ +from BaseClasses import ItemClassification +from Fill import distribute_items_restrictive +from ..Enum import CivVICheckType +from . import CivVITestBase + + +class TestStartingHints(CivVITestBase): + run_default_tests = False # type: ignore + auto_construct = False + options = { + "progressive_eras": "true", + "death_link": "true", + "death_link_effect": "unit_killed", + "progressive_districts": "true", + "pre_hint_items": set({"Progression", "Useful", "Filler"}), + } + + def test_all_tech_civic_items_are_hinted_default(self) -> None: + self.world_setup() + distribute_items_restrictive(self.multiworld) + self.world.post_fill() + start_location_hints = self.world.options.start_location_hints.value + for location_name, location_data in self.world.location_table.items(): + if location_data.location_type == CivVICheckType.CIVIC or location_data.location_type == CivVICheckType.TECH: + self.assertIn(location_name, start_location_hints) + else: + self.assertNotIn(location_name, start_location_hints) + + +class TestOnlyProgressionItemsHinted(CivVITestBase): + run_default_tests = False # type: ignore + auto_construct = False + options = { + "progressive_eras": "true", + "death_link": "true", + "death_link_effect": "unit_killed", + "progressive_districts": "true", + "pre_hint_items": set({"Progression"}), + } + + def test_only_progression_items_are_hinted(self) -> None: + self.world_setup() + distribute_items_restrictive(self.multiworld) + self.world.post_fill() + start_location_hints = self.world.options.start_location_hints.value + self.assertTrue(len(start_location_hints) > 0) + for hint in start_location_hints: + location_data = self.world.get_location(hint) + if location_data.item: + self.assertTrue(location_data.item.classification == ItemClassification.progression) + else: + self.assertTrue(False, "Location has no item") + + +class TestNoJunkItemsHinted(CivVITestBase): + run_default_tests = False # type: ignore + auto_construct = False + options = { + "progressive_eras": "true", + "death_link": "true", + "death_link_effect": "unit_killed", + "progressive_districts": "true", + "pre_hint_items": set({"Progression", "Useful"}), + "boostsanity": "true", + "shuffle_goody_hut_rewards": "true", + } + + def test_no_junk_items_are_hinted(self) -> None: + self.world_setup() + distribute_items_restrictive(self.multiworld) + item = self.multiworld.get_location("TECH_AP_ANCIENT_01", self.player).item + self.assertIsNotNone(item) + + if item: + item.classification = ItemClassification.filler + + self.world.post_fill() + start_location_hints = self.world.options.start_location_hints.value + self.assertTrue(len(start_location_hints) > 0) + self.assertNotIn("TECH_AP_ANCIENT_01", start_location_hints) + + +class TestOnlyJunkItemsHinted(CivVITestBase): + run_default_tests = False # type: ignore + auto_construct = False + options = { + "progressive_eras": "true", + "death_link": "true", + "death_link_effect": "unit_killed", + "progressive_districts": "true", + "pre_hint_items": set({"Filler"}), + } + + def test_only_junk_items_are_hinted(self) -> None: + self.world_setup() + distribute_items_restrictive(self.multiworld) + item = self.multiworld.get_location("TECH_AP_ANCIENT_01", self.player).item + self.assertIsNotNone(item) + + if item: + item.classification = ItemClassification.filler + + self.world.post_fill() + start_location_hints = self.world.options.start_location_hints.value + self.assertEqual(len(start_location_hints), 1) + self.assertIn("TECH_AP_ANCIENT_01", start_location_hints) + + +class TestNoItemsHinted(CivVITestBase): + run_default_tests = False # type: ignore + auto_construct = False + options = { + "progressive_eras": "true", + "death_link": "true", + "death_link_effect": "unit_killed", + "progressive_districts": "true", + "pre_hint_items": set({}), + } + + def test_no_items_are_hinted(self) -> None: + self.world_setup() + distribute_items_restrictive(self.multiworld) + self.world.post_fill() + start_location_hints = self.world.options.start_location_hints.value + self.assertEqual(len(start_location_hints), 0) diff --git a/worlds/civ_6/test/__init__.py b/worlds/civ_6/test/__init__.py new file mode 100644 index 000000000000..597b52711ae9 --- /dev/null +++ b/worlds/civ_6/test/__init__.py @@ -0,0 +1,8 @@ +from typing import ClassVar + +from test.bases import WorldTestBase + + +class CivVITestBase(WorldTestBase): + game = "Civilization VI" + player: ClassVar[int] = 1 From 4882366ffcff6ed4186fc1f22ea0df2806054f5f Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Mon, 10 Mar 2025 10:56:05 -0400 Subject: [PATCH 0192/1218] LTTP: Fix TR Big Key Door Entrance Logic (#4712) --- worlds/alttp/Rules.py | 73 ++++++++++--------- .../test/inverted/TestInvertedTurtleRock.py | 30 ++++---- .../TestInvertedTurtleRock.py | 30 ++++---- .../alttp/test/inverted_owg/TestDungeons.py | 2 +- worlds/alttp/test/owg/TestDungeons.py | 4 +- 5 files changed, 70 insertions(+), 69 deletions(-) diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index f13178c6c519..47992947ac03 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -1120,28 +1120,28 @@ def toss_junk_item(world, player): raise Exception("Unable to find a junk item to toss to make room for a TR small key") -def set_trock_key_rules(world, player): +def set_trock_key_rules(multiworld, player): # First set all relevant locked doors to impassible. for entrance in ['Turtle Rock Dark Room Staircase', 'Turtle Rock (Chain Chomp Room) (North)', 'Turtle Rock (Chain Chomp Room) (South)', 'Turtle Rock Entrance to Pokey Room', 'Turtle Rock (Pokey Room) (South)', 'Turtle Rock (Pokey Room) (North)', 'Turtle Rock Big Key Door']: - set_rule(world.get_entrance(entrance, player), lambda state: False) + set_rule(multiworld.get_entrance(entrance, player), lambda state: False) - all_state = world.get_all_state(use_cache=False, allow_partial_entrances=True) + all_state = multiworld.get_all_state(use_cache=False, allow_partial_entrances=True) all_state.reachable_regions[player] = set() # wipe reachable regions so that the locked doors actually work all_state.stale[player] = True # Check if each of the four main regions of the dungoen can be reached. The previous code section prevents key-costing moves within the dungeon. - can_reach_back = all_state.can_reach(world.get_region('Turtle Rock (Eye Bridge)', player)) - can_reach_front = all_state.can_reach(world.get_region('Turtle Rock (Entrance)', player)) - can_reach_big_chest = all_state.can_reach(world.get_region('Turtle Rock (Big Chest)', player)) - can_reach_middle = all_state.can_reach(world.get_region('Turtle Rock (Second Section)', player)) + can_reach_back = all_state.can_reach(multiworld.get_region('Turtle Rock (Eye Bridge)', player)) + can_reach_front = all_state.can_reach(multiworld.get_region('Turtle Rock (Entrance)', player)) + can_reach_big_chest = all_state.can_reach(multiworld.get_region('Turtle Rock (Big Chest)', player)) + can_reach_middle = all_state.can_reach(multiworld.get_region('Turtle Rock (Second Section)', player)) # If you can't enter from the back, the door to the front of TR requires only 2 small keys if the big key is in one of these chests since 2 key doors are locked behind the big key door. # If you can only enter from the middle, this includes all locations that can only be reached by exiting the front. This can include Laser Bridge and Crystaroller if the front and back connect via Dark DM Ledge! front_locked_locations = {('Turtle Rock - Compass Chest', player), ('Turtle Rock - Roller Room - Left', player), ('Turtle Rock - Roller Room - Right', player)} if can_reach_middle and not can_reach_back and not can_reach_front: normal_regions = all_state.reachable_regions[player].copy() - set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (South)', player), lambda state: True) - set_rule(world.get_entrance('Turtle Rock (Pokey Room) (South)', player), lambda state: True) + set_rule(multiworld.get_entrance('Turtle Rock (Chain Chomp Room) (South)', player), lambda state: True) + set_rule(multiworld.get_entrance('Turtle Rock (Pokey Room) (South)', player), lambda state: True) all_state.update_reachable_regions(player) front_locked_regions = all_state.reachable_regions[player].difference(normal_regions) front_locked_locations = set((location.name, player) for region in front_locked_regions for location in region.locations) @@ -1151,37 +1151,38 @@ def set_trock_key_rules(world, player): # Big key door requires the big key, obviously. We removed this rule in the previous section to flag front_locked_locations correctly, # otherwise crystaroller room might not be properly marked as reachable through the back. - set_rule(world.get_entrance('Turtle Rock Big Key Door', player), lambda state: state.has('Big Key (Turtle Rock)', player)) + set_rule(multiworld.get_entrance('Turtle Rock Big Key Door', player), lambda state: state.has('Big Key (Turtle Rock)', player) and can_kill_most_things(state, player, 10) and can_bomb_or_bonk(state, player)) + # No matter what, the key requirement for going from the middle to the bottom should be five keys. - set_rule(world.get_entrance('Turtle Rock Dark Room Staircase', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 5)) + set_rule(multiworld.get_entrance('Turtle Rock Dark Room Staircase', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 5)) # Now we need to set rules based on which entrances we have access to. The most important point is whether we have back access. If we have back access, we # might open all the locked doors in any order, so we need maximally restrictive rules. if can_reach_back: - set_rule(world.get_location('Turtle Rock - Big Key Chest', player), lambda state: (state._lttp_has_key('Small Key (Turtle Rock)', player, 6) or location_item_name(state, 'Turtle Rock - Big Key Chest', player) == ('Small Key (Turtle Rock)', player))) - set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (South)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 5)) - set_rule(world.get_entrance('Turtle Rock (Pokey Room) (South)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 6)) + set_rule(multiworld.get_location('Turtle Rock - Big Key Chest', player), lambda state: (state._lttp_has_key('Small Key (Turtle Rock)', player, 6) or location_item_name(state, 'Turtle Rock - Big Key Chest', player) == ('Small Key (Turtle Rock)', player))) + set_rule(multiworld.get_entrance('Turtle Rock (Chain Chomp Room) (South)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 5)) + set_rule(multiworld.get_entrance('Turtle Rock (Pokey Room) (South)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 6)) - set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (North)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 6)) - set_rule(world.get_entrance('Turtle Rock (Pokey Room) (North)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 6)) - set_rule(world.get_entrance('Turtle Rock Entrance to Pokey Room', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 5)) + set_rule(multiworld.get_entrance('Turtle Rock (Chain Chomp Room) (North)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 6)) + set_rule(multiworld.get_entrance('Turtle Rock (Pokey Room) (North)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 6)) + set_rule(multiworld.get_entrance('Turtle Rock Entrance to Pokey Room', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 5)) else: # Middle to front requires 3 keys if the back is locked by this door, otherwise 5 - set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (South)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 3) + set_rule(multiworld.get_entrance('Turtle Rock (Chain Chomp Room) (South)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 3) if item_name_in_location_names(state, 'Big Key (Turtle Rock)', player, front_locked_locations.union({('Turtle Rock - Pokey 1 Key Drop', player)})) else state._lttp_has_key('Small Key (Turtle Rock)', player, 5)) # Middle to front requires 4 keys if the back is locked by this door, otherwise 6 - set_rule(world.get_entrance('Turtle Rock (Pokey Room) (South)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 4) + set_rule(multiworld.get_entrance('Turtle Rock (Pokey Room) (South)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 4) if item_name_in_location_names(state, 'Big Key (Turtle Rock)', player, front_locked_locations) else state._lttp_has_key('Small Key (Turtle Rock)', player, 6)) # Front to middle requires 3 keys (if the middle is accessible then these doors can be avoided, otherwise no keys can be wasted) - set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (North)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 3)) - set_rule(world.get_entrance('Turtle Rock (Pokey Room) (North)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 2)) - set_rule(world.get_entrance('Turtle Rock Entrance to Pokey Room', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 1)) + set_rule(multiworld.get_entrance('Turtle Rock (Chain Chomp Room) (North)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 3)) + set_rule(multiworld.get_entrance('Turtle Rock (Pokey Room) (North)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 2)) + set_rule(multiworld.get_entrance('Turtle Rock Entrance to Pokey Room', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 1)) - set_rule(world.get_location('Turtle Rock - Big Key Chest', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, tr_big_key_chest_keys_needed(state))) + set_rule(multiworld.get_location('Turtle Rock - Big Key Chest', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, tr_big_key_chest_keys_needed(state))) def tr_big_key_chest_keys_needed(state): # This function handles the key requirements for the TR Big Chest in the situations it having the Big Key should logically require 2 keys, small key @@ -1194,30 +1195,30 @@ def tr_big_key_chest_keys_needed(state): return 6 # If TR is only accessible from the middle, the big key must be further restricted to prevent softlock potential - if not can_reach_front and not world.small_key_shuffle[player]: + if not can_reach_front and not multiworld.small_key_shuffle[player]: # Must not go in the Big Key Chest - only 1 other chest available and 2+ keys required for all other chests - forbid_item(world.get_location('Turtle Rock - Big Key Chest', player), 'Big Key (Turtle Rock)', player) + forbid_item(multiworld.get_location('Turtle Rock - Big Key Chest', player), 'Big Key (Turtle Rock)', player) if not can_reach_big_chest: # Must not go in the Chain Chomps chest - only 2 other chests available and 3+ keys required for all other chests - forbid_item(world.get_location('Turtle Rock - Chain Chomps', player), 'Big Key (Turtle Rock)', player) - forbid_item(world.get_location('Turtle Rock - Pokey 2 Key Drop', player), 'Big Key (Turtle Rock)', player) - if world.accessibility[player] == 'full': - if world.big_key_shuffle[player] and can_reach_big_chest: + forbid_item(multiworld.get_location('Turtle Rock - Chain Chomps', player), 'Big Key (Turtle Rock)', player) + forbid_item(multiworld.get_location('Turtle Rock - Pokey 2 Key Drop', player), 'Big Key (Turtle Rock)', player) + if multiworld.accessibility[player] == 'full': + if multiworld.big_key_shuffle[player] and can_reach_big_chest: # Must not go in the dungeon - all 3 available chests (Chomps, Big Chest, Crystaroller) must be keys to access laser bridge, and the big key is required first for location in ['Turtle Rock - Chain Chomps', 'Turtle Rock - Compass Chest', 'Turtle Rock - Pokey 1 Key Drop', 'Turtle Rock - Pokey 2 Key Drop', 'Turtle Rock - Roller Room - Left', 'Turtle Rock - Roller Room - Right']: - forbid_item(world.get_location(location, player), 'Big Key (Turtle Rock)', player) + forbid_item(multiworld.get_location(location, player), 'Big Key (Turtle Rock)', player) else: # A key is required in the Big Key Chest to prevent a possible softlock. Place an extra key to ensure 100% locations still works - item = item_factory('Small Key (Turtle Rock)', world.worlds[player]) - location = world.get_location('Turtle Rock - Big Key Chest', player) + item = item_factory('Small Key (Turtle Rock)', multiworld.worlds[player]) + location = multiworld.get_location('Turtle Rock - Big Key Chest', player) location.place_locked_item(item) - toss_junk_item(world, player) + toss_junk_item(multiworld, player) - if world.accessibility[player] != 'full': - set_always_allow(world.get_location('Turtle Rock - Big Key Chest', player), lambda state, item: item.name == 'Small Key (Turtle Rock)' and item.player == player - and state.can_reach(state.multiworld.get_region('Turtle Rock (Second Section)', player))) + if multiworld.accessibility[player] != 'full': + set_always_allow(multiworld.get_location('Turtle Rock - Big Key Chest', player), lambda state, item: item.name == 'Small Key (Turtle Rock)' and item.player == player + and state.can_reach(state.multiworld.get_region('Turtle Rock (Second Section)', player))) def set_big_bomb_rules(world, player): diff --git a/worlds/alttp/test/inverted/TestInvertedTurtleRock.py b/worlds/alttp/test/inverted/TestInvertedTurtleRock.py index db3084b02a5b..21bcf709649b 100644 --- a/worlds/alttp/test/inverted/TestInvertedTurtleRock.py +++ b/worlds/alttp/test/inverted/TestInvertedTurtleRock.py @@ -79,12 +79,12 @@ def testTurtleRock(self): ["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Lamp']], ["Turtle Rock - Crystaroller Room", False, [], ['Magic Mirror', 'Cane of Somaria']], ["Turtle Rock - Crystaroller Room", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']], ["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria']], ["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria']], ["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Somaria']], @@ -97,9 +97,9 @@ def testTurtleRock(self): ["Turtle Rock - Boss", False, [], ['Big Key (Turtle Rock)']], ["Turtle Rock - Boss", False, [], ['Magic Mirror', 'Lamp']], ["Turtle Rock - Boss", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']], - ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Flute', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], - ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], - ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Magic Upgrade (1/2)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)','Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], + ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Flute', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Big Key (Turtle Rock)']], + ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Big Key (Turtle Rock)']], + ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Magic Upgrade (1/2)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)','Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Big Key (Turtle Rock)']], ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Flute', 'Magic Mirror', 'Moon Pearl', 'Hookshot', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']] @@ -117,12 +117,12 @@ def testEyeBridge(self): [location, False, [], ['Magic Mirror', 'Cane of Somaria']], [location, False, [], ['Magic Mirror', 'Lamp']], [location, False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']], - [location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']], - [location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']], - [location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']], - [location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']], - [location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']], - [location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']], # Mirroring into Eye Bridge does not require Cane of Somaria [location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']], diff --git a/worlds/alttp/test/inverted_minor_glitches/TestInvertedTurtleRock.py b/worlds/alttp/test/inverted_minor_glitches/TestInvertedTurtleRock.py index a416e1b35d33..343cf3f8b126 100644 --- a/worlds/alttp/test/inverted_minor_glitches/TestInvertedTurtleRock.py +++ b/worlds/alttp/test/inverted_minor_glitches/TestInvertedTurtleRock.py @@ -80,12 +80,12 @@ def testTurtleRock(self): ["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Lamp']], ["Turtle Rock - Crystaroller Room", False, [], ['Magic Mirror', 'Cane of Somaria']], ["Turtle Rock - Crystaroller Room", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot']], - ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot']], + ["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']], ["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria']], ["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria']], ["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Somaria']], @@ -98,9 +98,9 @@ def testTurtleRock(self): ["Turtle Rock - Boss", False, [], ['Big Key (Turtle Rock)']], ["Turtle Rock - Boss", False, [], ['Magic Mirror', 'Lamp']], ["Turtle Rock - Boss", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']], - ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Flute', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], - ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], - ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Magic Upgrade (1/2)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)','Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], + ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Flute', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Big Key (Turtle Rock)']], + ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Big Key (Turtle Rock)']], + ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Magic Upgrade (1/2)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)','Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Big Key (Turtle Rock)']], ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']], ["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Flute', 'Magic Mirror', 'Moon Pearl', 'Hookshot', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']] ]) @@ -116,12 +116,12 @@ def testEyeBridge(self): [location, False, [], ['Magic Mirror', 'Cane of Somaria']], [location, False, [], ['Magic Mirror', 'Lamp']], [location, False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']], - [location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']], - [location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']], - [location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']], - [location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']], - [location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']], - [location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']], + [location, True, ['Big Key (Turtle Rock)', 'Bomb Upgrade (50)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']], # Mirroring into Eye Bridge does not require Cane of Somaria [location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']], diff --git a/worlds/alttp/test/inverted_owg/TestDungeons.py b/worlds/alttp/test/inverted_owg/TestDungeons.py index ada1b92fca49..595587f0067b 100644 --- a/worlds/alttp/test/inverted_owg/TestDungeons.py +++ b/worlds/alttp/test/inverted_owg/TestDungeons.py @@ -102,7 +102,7 @@ def testFirstDungeonChests(self): ["Turtle Rock - Chain Chomps", True, ['Progressive Sword', 'Progressive Sword', 'Pegasus Boots']], ["Turtle Rock - Crystaroller Room", False, []], - ["Turtle Rock - Crystaroller Room", True, ['Pegasus Boots', 'Magic Mirror', 'Moon Pearl', 'Big Key (Turtle Rock)']], + ["Turtle Rock - Crystaroller Room", True, ['Pegasus Boots', 'Magic Mirror', 'Moon Pearl', 'Big Key (Turtle Rock)', 'Bomb Upgrade (50)']], ["Turtle Rock - Crystaroller Room", True, ['Pegasus Boots', 'Magic Mirror', 'Moon Pearl', 'Lamp', 'Cane of Somaria']], ["Ganons Tower - Hope Room - Left", False, []], diff --git a/worlds/alttp/test/owg/TestDungeons.py b/worlds/alttp/test/owg/TestDungeons.py index 2e55b308d327..e9b1fde2855a 100644 --- a/worlds/alttp/test/owg/TestDungeons.py +++ b/worlds/alttp/test/owg/TestDungeons.py @@ -120,8 +120,8 @@ def testFirstDungeonChests(self): #todo: does clip require sword? #["Turtle Rock - Crystaroller Room", True, ['Moon Pearl', 'Pegasus Boots', 'Big Key (Turtle Rock)']], ["Turtle Rock - Crystaroller Room", True, ['Moon Pearl', 'Pegasus Boots', 'Big Key (Turtle Rock)', 'Progressive Sword']], - ["Turtle Rock - Crystaroller Room", True, ['Moon Pearl', 'Pegasus Boots', 'Big Key (Turtle Rock)', 'Hookshot']], - ["Turtle Rock - Crystaroller Room", True, ['Pegasus Boots', 'Magic Mirror', 'Big Key (Turtle Rock)']], + ["Turtle Rock - Crystaroller Room", True, ['Moon Pearl', 'Pegasus Boots', 'Big Key (Turtle Rock)', 'Hookshot', 'Bomb Upgrade (50)']], + ["Turtle Rock - Crystaroller Room", True, ['Pegasus Boots', 'Magic Mirror', 'Big Key (Turtle Rock)', 'Bomb Upgrade (50)']], ["Ganons Tower - Hope Room - Left", False, []], ["Ganons Tower - Hope Room - Left", False, ['Moon Pearl', 'Crystal 1']], From 7c30c4a16952a3a6b325bdc6cb497b9fa0591714 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Mon, 10 Mar 2025 10:16:09 -0500 Subject: [PATCH 0193/1218] The Messenger: Transition Shuffle (#4402) * The Messenger: transition rando * remove unused import * always link both directions for plando when using coupled transitions * er_type was renamed to randomization_type * use frozenset for things that shouldn't change * review suggestions * do portal and transition shuffle in `connect_entrances` * remove some unnecessary connections that were causing entrance caching collisions * add test for strictest possible ER settings * use unittest.skip on the skipped test, so we don't waste time doing setUp and tearDown * use the world helpers * make the plando connection description more verbose * always add searing crags portal if portal shuffle is disabled * guarantee an arbitrary number of locations with first connection * make the constraints more lenient for a bit more variety --- worlds/messenger/__init__.py | 82 ++++++++++++++--- worlds/messenger/connections.py | 74 ++++++++------- worlds/messenger/options.py | 33 ++++--- worlds/messenger/portals.py | 10 +- worlds/messenger/subclasses.py | 23 ++++- .../test/test_entrance_randomization.py | 19 ++++ worlds/messenger/transitions.py | 92 +++++++++++++++++++ 7 files changed, 258 insertions(+), 75 deletions(-) create mode 100644 worlds/messenger/test/test_entrance_randomization.py create mode 100644 worlds/messenger/transitions.py diff --git a/worlds/messenger/__init__.py b/worlds/messenger/__init__.py index a6effc31d56d..8bde3bbc7ae5 100644 --- a/worlds/messenger/__init__.py +++ b/worlds/messenger/__init__.py @@ -1,7 +1,7 @@ import logging from typing import Any, ClassVar, TextIO -from BaseClasses import CollectionState, Entrance, Item, ItemClassification, MultiWorld, Tutorial +from BaseClasses import CollectionState, Entrance, EntranceType, Item, ItemClassification, MultiWorld, Tutorial from Options import Accessibility from Utils import output_path from settings import FilePath, Group @@ -17,6 +17,7 @@ from .rules import MessengerHardRules, MessengerOOBRules, MessengerRules from .shop import FIGURINES, PROG_SHOP_ITEMS, SHOP_ITEMS, USEFUL_SHOP_ITEMS, shuffle_shop_prices from .subclasses import MessengerEntrance, MessengerItem, MessengerRegion, MessengerShopLocation +from .transitions import shuffle_transitions components.append( Component("The Messenger", component_type=Type.CLIENT, func=launch_game, game_name="The Messenger", supports_uri=True) @@ -128,7 +129,7 @@ class MessengerWorld(World): spoiler_portal_mapping: dict[str, str] portal_mapping: list[int] transitions: list[Entrance] - reachable_locs: int = 0 + reachable_locs: bool = False filler: dict[str, int] def generate_early(self) -> None: @@ -145,13 +146,13 @@ def generate_early(self) -> None: self.shop_prices, self.figurine_prices = shuffle_shop_prices(self) - starting_portals = ["Autumn Hills", "Howling Grotto", "Glacial Peak", "Riviere Turquoise", "Sunken Shrine", "Searing Crags"] + starting_portals = ["Autumn Hills", "Howling Grotto", "Glacial Peak", "Riviere Turquoise", "Sunken Shrine", + "Searing Crags"] self.starting_portals = [f"{portal} Portal" for portal in starting_portals[:3] + self.random.sample(starting_portals[3:], k=self.options.available_portals - 3)] # super complicated method for adding searing crags to starting portals if it wasn't chosen - # TODO add a check for transition shuffle when that gets added back in if not self.options.shuffle_portals and "Searing Crags Portal" not in self.starting_portals: self.starting_portals.append("Searing Crags Portal") portals_to_strip = [portal for portal in ["Riviere Turquoise Portal", "Sunken Shrine Portal"] @@ -181,7 +182,7 @@ def create_regions(self) -> None: region_name = region.name.removeprefix(f"{region.parent} - ") connection_data = CONNECTIONS[region.parent][region_name] for exit_region in connection_data: - region.connect(self.multiworld.get_region(exit_region, self.player)) + region.connect(self.get_region(exit_region)) # all regions need to be created before i can do these connections so we create and connect the complex first for region in [level for level in simple_regions if level.name in REGION_CONNECTIONS]: @@ -256,6 +257,7 @@ def set_rules(self) -> None: f" {logic} for {self.multiworld.get_player_name(self.player)}") # MessengerOOBRules(self).set_messenger_rules() + def connect_entrances(self) -> None: add_closed_portal_reqs(self) # i need portal shuffle to happen after rules exist so i can validate it attempts = 5 @@ -271,6 +273,9 @@ def set_rules(self) -> None: else: raise RuntimeError("Unable to generate valid portal output.") + if self.options.shuffle_transitions: + shuffle_transitions(self) + def write_spoiler_header(self, spoiler_handle: TextIO) -> None: if self.options.available_portals < 6: spoiler_handle.write(f"\nStarting Portals:\n\n") @@ -286,9 +291,54 @@ def write_spoiler_header(self, spoiler_handle: TextIO) -> None: key=lambda portal: ["Autumn Hills", "Riviere Turquoise", "Howling Grotto", "Sunken Shrine", - "Searing Crags", "Glacial Peak"].index(portal[0])) + "Searing Crags", "Glacial Peak"].index(portal[0]) + ) for portal, output in portal_info: - spoiler.set_entrance(f"{portal} Portal", output, "I can write anything I want here lmao", self.player) + spoiler.set_entrance(f"{portal} Portal", output, "", self.player) + + if self.options.shuffle_transitions: + for transition in self.transitions: + if (transition.randomization_type == EntranceType.TWO_WAY + and (transition.connected_region.name, "both", self.player) in spoiler.entrances): + continue + spoiler.set_entrance( + transition.name if "->" not in transition.name else transition.parent_region.name, + transition.connected_region.name, + "both" if transition.randomization_type == EntranceType.TWO_WAY + and self.options.shuffle_transitions == ShuffleTransitions.option_coupled else "", + self.player + ) + + def extend_hint_information(self, hint_data: dict[int, dict[int, str]]) -> None: + if not self.options.shuffle_transitions: + return + + hint_data.update({self.player: {}}) + + all_state = self.multiworld.get_all_state(True) + # sometimes some of my regions aren't in path for some reason? + all_state.update_reachable_regions(self.player) + paths = all_state.path + start = self.get_region("Tower HQ") + start_connections = [entrance.name for entrance in start.exits if entrance not in {"Home", "Shrink Down"}] + transition_names = [transition.name for transition in self.transitions] + start_connections + for loc in self.get_locations(): + if (loc.parent_region.name in {"Tower HQ", "The Shop", "Music Box", "The Craftsman's Corner"} + or loc.address is None): + continue + path_to_loc: list[str] = [] + name, connection = paths.get(loc.parent_region, (None, None)) + while connection != ("Menu", None) and name is not None: + name, connection = connection + if name in transition_names: + if name in start_connections: + name = f"{name} -> {self.get_entrance(name).connected_region.name}" + path_to_loc.append(name) + + text = " => ".join(reversed(path_to_loc)) + if not text: + continue + hint_data[self.player][loc.address] = text def fill_slot_data(self) -> dict[str, Any]: slot_data = { @@ -308,11 +358,13 @@ def fill_slot_data(self) -> dict[str, Any]: def get_filler_item_name(self) -> str: if not getattr(self, "_filler_items", None): - self._filler_items = [name for name in self.random.choices( - list(self.filler), - weights=list(self.filler.values()), - k=20 - )] + self._filler_items = [ + name for name in self.random.choices( + list(self.filler), + weights=list(self.filler.values()), + k=20 + ) + ] return self._filler_items.pop(0) def create_item(self, name: str) -> MessengerItem: @@ -331,7 +383,7 @@ def get_item_classification(self, name: str) -> ItemClassification: self.total_shards += count return ItemClassification.progression_skip_balancing if count else ItemClassification.filler - if name == "Windmill Shuriken" and getattr(self, "multiworld", None) is not None: + if name == "Windmill Shuriken": return ItemClassification.progression if self.options.logic_level else ItemClassification.filler if name == "Power Seal": @@ -344,7 +396,7 @@ def get_item_classification(self, name: str) -> ItemClassification: if name in {*USEFUL_ITEMS, *USEFUL_SHOP_ITEMS}: return ItemClassification.useful - + if name in TRAPS: return ItemClassification.trap @@ -354,7 +406,7 @@ def get_item_classification(self, name: str) -> ItemClassification: def create_group(cls, multiworld: "MultiWorld", new_player_id: int, players: set[int]) -> World: group = super().create_group(multiworld, new_player_id, players) assert isinstance(group, MessengerWorld) - + group.filler = FILLER.copy() group.options.traps.value = all(multiworld.worlds[player].options.traps for player in players) if group.options.traps: diff --git a/worlds/messenger/connections.py b/worlds/messenger/connections.py index 79912a5688c2..84f7f9b24281 100644 --- a/worlds/messenger/connections.py +++ b/worlds/messenger/connections.py @@ -244,14 +244,12 @@ "Bottom Left": [ "Howling Grotto - Top", "Quillshroom Marsh - Sand Trap Shop", - "Quillshroom Marsh - Bottom Right", ], "Top Right": [ "Quillshroom Marsh - Queen of Quills Shop", "Searing Crags - Left", ], "Bottom Right": [ - "Quillshroom Marsh - Bottom Left", "Quillshroom Marsh - Sand Trap Shop", "Searing Crags - Bottom", ], @@ -639,43 +637,43 @@ } RANDOMIZED_CONNECTIONS: dict[str, str] = { - "Ninja Village - Right": "Autumn Hills - Left", - "Autumn Hills - Left": "Ninja Village - Right", - "Autumn Hills - Right": "Forlorn Temple - Left", - "Autumn Hills - Bottom": "Catacombs - Bottom Left", - "Forlorn Temple - Left": "Autumn Hills - Right", - "Forlorn Temple - Right": "Bamboo Creek - Top Left", - "Forlorn Temple - Bottom": "Catacombs - Top Left", - "Catacombs - Top Left": "Forlorn Temple - Bottom", - "Catacombs - Bottom Left": "Autumn Hills - Bottom", - "Catacombs - Bottom": "Dark Cave - Right", - "Catacombs - Right": "Bamboo Creek - Bottom Left", - "Bamboo Creek - Bottom Left": "Catacombs - Right", - "Bamboo Creek - Right": "Howling Grotto - Left", - "Bamboo Creek - Top Left": "Forlorn Temple - Right", - "Howling Grotto - Left": "Bamboo Creek - Right", - "Howling Grotto - Top": "Quillshroom Marsh - Bottom Left", - "Howling Grotto - Right": "Quillshroom Marsh - Top Left", - "Howling Grotto - Bottom": "Sunken Shrine - Left", - "Quillshroom Marsh - Top Left": "Howling Grotto - Right", - "Quillshroom Marsh - Bottom Left": "Howling Grotto - Top", - "Quillshroom Marsh - Top Right": "Searing Crags - Left", + "Ninja Village - Right": "Autumn Hills - Left", + "Autumn Hills - Left": "Ninja Village - Right", + "Autumn Hills - Right": "Forlorn Temple - Left", + "Autumn Hills - Bottom": "Catacombs - Bottom Left", + "Forlorn Temple - Left": "Autumn Hills - Right", + "Forlorn Temple - Right": "Bamboo Creek - Top Left", + "Forlorn Temple - Bottom": "Catacombs - Top Left", + "Catacombs - Top Left": "Forlorn Temple - Bottom", + "Catacombs - Bottom Left": "Autumn Hills - Bottom", + "Catacombs - Bottom": "Dark Cave - Right", + "Catacombs - Right": "Bamboo Creek - Bottom Left", + "Bamboo Creek - Bottom Left": "Catacombs - Right", + "Bamboo Creek - Right": "Howling Grotto - Left", + "Bamboo Creek - Top Left": "Forlorn Temple - Right", + "Howling Grotto - Left": "Bamboo Creek - Right", + "Howling Grotto - Top": "Quillshroom Marsh - Bottom Left", + "Howling Grotto - Right": "Quillshroom Marsh - Top Left", + "Howling Grotto - Bottom": "Sunken Shrine - Left", + "Quillshroom Marsh - Top Left": "Howling Grotto - Right", + "Quillshroom Marsh - Bottom Left": "Howling Grotto - Top", + "Quillshroom Marsh - Top Right": "Searing Crags - Left", "Quillshroom Marsh - Bottom Right": "Searing Crags - Bottom", - "Searing Crags - Left": "Quillshroom Marsh - Top Right", - "Searing Crags - Top": "Glacial Peak - Bottom", - "Searing Crags - Bottom": "Quillshroom Marsh - Bottom Right", - "Searing Crags - Right": "Underworld - Left", - "Glacial Peak - Bottom": "Searing Crags - Top", - "Glacial Peak - Top": "Cloud Ruins - Left", - "Glacial Peak - Left": "Elemental Skylands - Air Shmup", - "Cloud Ruins - Left": "Glacial Peak - Top", - "Elemental Skylands - Right": "Glacial Peak - Left", - "Tower HQ": "Tower of Time - Left", - "Artificer": "Corrupted Future", - "Underworld - Left": "Searing Crags - Right", - "Dark Cave - Right": "Catacombs - Bottom", - "Dark Cave - Left": "Riviere Turquoise - Right", - "Sunken Shrine - Left": "Howling Grotto - Bottom", + "Searing Crags - Left": "Quillshroom Marsh - Top Right", + "Searing Crags - Top": "Glacial Peak - Bottom", + "Searing Crags - Bottom": "Quillshroom Marsh - Bottom Right", + "Searing Crags - Right": "Underworld - Left", + "Glacial Peak - Bottom": "Searing Crags - Top", + "Glacial Peak - Top": "Cloud Ruins - Left", + "Glacial Peak - Left": "Elemental Skylands - Air Shmup", + "Cloud Ruins - Left": "Glacial Peak - Top", + "Elemental Skylands - Right": "Glacial Peak - Left", + "Tower HQ": "Tower of Time - Left", + "Artificer": "Corrupted Future", + "Underworld - Left": "Searing Crags - Right", + "Dark Cave - Right": "Catacombs - Bottom", + "Dark Cave - Left": "Riviere Turquoise - Right", + "Sunken Shrine - Left": "Howling Grotto - Bottom", } TRANSITIONS: list[str] = [ diff --git a/worlds/messenger/options.py b/worlds/messenger/options.py index 8b61a9435422..9ee04d26a6d8 100644 --- a/worlds/messenger/options.py +++ b/worlds/messenger/options.py @@ -3,7 +3,8 @@ from schema import And, Optional, Or, Schema from Options import Choice, DeathLinkMixin, DefaultOnToggle, ItemsAccessibility, OptionDict, PerGameCommonOptions, \ - PlandoConnections, Range, StartInventoryPool, Toggle, Visibility + PlandoConnections, Range, StartInventoryPool, Toggle +from . import RANDOMIZED_CONNECTIONS from .portals import CHECKPOINTS, PORTALS, SHOP_POINTS @@ -30,17 +31,25 @@ class PortalPlando(PlandoConnections): portals = [f"{portal} Portal" for portal in PORTALS] shop_points = [point for points in SHOP_POINTS.values() for point in points] checkpoints = [point for points in CHECKPOINTS.values() for point in points] - portal_entrances = PORTALS - portal_exits = portals + shop_points + checkpoints - entrances = portal_entrances - exits = portal_exits + entrances = frozenset(PORTALS) + exits = frozenset(portals + shop_points + checkpoints) -# for back compatibility. To later be replaced with transition plando -class HiddenPortalPlando(PortalPlando): - visibility = Visibility.none - entrances = PortalPlando.entrances - exits = PortalPlando.exits + +class TransitionPlando(PlandoConnections): + """ + Plando connections to be used with transition shuffle. + List of valid connections can be found at https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/messenger/connections.py#L641. + Dictionary keys (left) are entrances and values (right) are exits. If transition shuffle is on coupled all plando + connections will be coupled. If on decoupled, "entrance" and "exit" will be treated the same, simply making the + plando connection one-way from entrance to exit. + Example: + - entrance: Searing Crags - Top + exit: Dark Cave - Right + direction: both + """ + entrances = frozenset(RANDOMIZED_CONNECTIONS.keys()) + exits = frozenset(RANDOMIZED_CONNECTIONS.values()) class Logic(Choice): @@ -226,7 +235,7 @@ class MessengerOptions(DeathLinkMixin, PerGameCommonOptions): early_meditation: EarlyMed available_portals: AvailablePortals shuffle_portals: ShufflePortals - # shuffle_transitions: ShuffleTransitions + shuffle_transitions: ShuffleTransitions goal: Goal music_box: MusicBox notes_needed: NotesNeeded @@ -236,4 +245,4 @@ class MessengerOptions(DeathLinkMixin, PerGameCommonOptions): shop_price: ShopPrices shop_price_plan: PlannedShopPrices portal_plando: PortalPlando - plando_connections: HiddenPortalPlando + plando_connections: TransitionPlando diff --git a/worlds/messenger/portals.py b/worlds/messenger/portals.py index 896fefa686f1..704285896ccf 100644 --- a/worlds/messenger/portals.py +++ b/worlds/messenger/portals.py @@ -1,7 +1,7 @@ from copy import deepcopy from typing import TYPE_CHECKING -from BaseClasses import CollectionState, PlandoOptions +from BaseClasses import CollectionState from Options import PlandoConnection if TYPE_CHECKING: @@ -252,9 +252,7 @@ def handle_planned_portals(plando_connections: list[PlandoConnection]) -> None: world.random.shuffle(available_portals) plando = world.options.portal_plando.value - if not plando: - plando = world.options.plando_connections.value - if plando and world.multiworld.plando_options & PlandoOptions.connections and not world.plando_portals: + if plando and not world.plando_portals: try: handle_planned_portals(plando) # any failure i expect will trigger on available_portals.remove @@ -294,8 +292,8 @@ def disconnect_portals(world: "MessengerWorld") -> None: def validate_portals(world: "MessengerWorld") -> bool: - # if world.options.shuffle_transitions: - # return True + if world.options.shuffle_transitions: + return True new_state = CollectionState(world.multiworld) new_state.update_reachable_regions(world.player) reachable_locs = 0 diff --git a/worlds/messenger/subclasses.py b/worlds/messenger/subclasses.py index 29e3ea8953ec..0138a3f07428 100644 --- a/worlds/messenger/subclasses.py +++ b/worlds/messenger/subclasses.py @@ -1,7 +1,8 @@ from functools import cached_property from typing import TYPE_CHECKING -from BaseClasses import CollectionState, Entrance, Item, ItemClassification, Location, Region +from BaseClasses import CollectionState, Entrance, EntranceType, Item, ItemClassification, Location, Region +from entrance_rando import ERPlacementState from .regions import LOCATIONS, MEGA_SHARDS from .shop import FIGURINES, SHOP_ITEMS @@ -12,9 +13,21 @@ class MessengerEntrance(Entrance): world: "MessengerWorld | None" = None + def can_connect_to(self, other: Entrance, dead_end: bool, state: "ERPlacementState") -> bool: + can_connect = super().can_connect_to(other, dead_end, state) + world: MessengerWorld = getattr(self, "world", None) + if not world or world.reachable_locs or not can_connect: + return can_connect + empty_state = CollectionState(world.multiworld, True) + self.connected_region = other.connected_region + empty_state.update_reachable_regions(world.player) + world.reachable_locs = any(loc.can_reach(empty_state) and not loc.is_event for loc in world.get_locations()) + self.connected_region = None + return world.reachable_locs and (not state.coupled or self.name != other.name) + class MessengerRegion(Region): - parent: str + parent: str | None entrance_type = MessengerEntrance def __init__(self, name: str, world: "MessengerWorld", parent: str | None = None) -> None: @@ -32,8 +45,9 @@ def __init__(self, name: str, world: "MessengerWorld", parent: str | None = None for shop_loc in SHOP_ITEMS} self.add_locations(shop_locations, MessengerShopLocation) elif name == "The Craftsman's Corner": - self.add_locations({figurine: world.location_name_to_id[figurine] for figurine in FIGURINES}, - MessengerLocation) + self.add_locations( + {figurine: world.location_name_to_id[figurine] for figurine in FIGURINES}, + MessengerLocation) elif name == "Tower HQ": locations.append("Money Wrench") @@ -57,6 +71,7 @@ def __init__(self, player: int, name: str, loc_id: int | None, parent: Messenger class MessengerShopLocation(MessengerLocation): + @cached_property def cost(self) -> int: name = self.name.removeprefix("The Shop - ") diff --git a/worlds/messenger/test/test_entrance_randomization.py b/worlds/messenger/test/test_entrance_randomization.py new file mode 100644 index 000000000000..2a06a2e0348c --- /dev/null +++ b/worlds/messenger/test/test_entrance_randomization.py @@ -0,0 +1,19 @@ +import unittest + +from . import MessengerTestBase + + +class StrictEntranceRandoTest(MessengerTestBase): + """Bare-bones world that tests the strictest possible settings to ensure it doesn't crash""" + auto_construct = True + options = { + "limited_movement": 1, + "available_portals": 3, + "shuffle_portals": 1, + "shuffle_transitions": 1, + } + + @unittest.skip + def test_all_state_can_reach_everything(self) -> None: + """It's not possible to reach everything with these options so skip this test.""" + pass diff --git a/worlds/messenger/transitions.py b/worlds/messenger/transitions.py new file mode 100644 index 000000000000..1db975b3cd3f --- /dev/null +++ b/worlds/messenger/transitions.py @@ -0,0 +1,92 @@ +from typing import TYPE_CHECKING + +from BaseClasses import Region +from entrance_rando import EntranceType, randomize_entrances +from .connections import RANDOMIZED_CONNECTIONS, TRANSITIONS +from .options import ShuffleTransitions, TransitionPlando + +if TYPE_CHECKING: + from . import MessengerWorld + + +def connect_plando(world: "MessengerWorld", plando_connections: TransitionPlando) -> None: + def remove_dangling_exit(region: Region) -> None: + # find the disconnected exit and remove references to it + for _exit in region.exits: + if not _exit.connected_region: + break + else: + raise ValueError(f"Unable to find randomized transition for {plando_connection}") + region.exits.remove(_exit) + + def remove_dangling_entrance(region: Region) -> None: + # find the disconnected entrance and remove references to it + for _entrance in region.entrances: + if not _entrance.parent_region: + break + else: + raise ValueError(f"Invalid target region for {plando_connection}") + region.entrances.remove(_entrance) + + for plando_connection in plando_connections: + # get the connecting regions + reg1 = world.get_region(plando_connection.entrance) + reg2 = world.get_region(plando_connection.exit) + + remove_dangling_exit(reg1) + remove_dangling_entrance(reg2) + # connect the regions + reg1.connect(reg2) + + # pretend the user set the plando direction as "both" regardless of what they actually put on coupled + if ((world.options.shuffle_transitions == ShuffleTransitions.option_coupled + or plando_connection.direction == "both") + and plando_connection.exit in RANDOMIZED_CONNECTIONS): + remove_dangling_exit(reg2) + remove_dangling_entrance(reg1) + reg2.connect(reg1) + + +def shuffle_transitions(world: "MessengerWorld") -> None: + coupled = world.options.shuffle_transitions == ShuffleTransitions.option_coupled + + def disconnect_entrance() -> None: + child_region.entrances.remove(entrance) + entrance.connected_region = None + + er_type = EntranceType.ONE_WAY if child == "Glacial Peak - Left" else \ + EntranceType.TWO_WAY if child in RANDOMIZED_CONNECTIONS else EntranceType.ONE_WAY + if er_type == EntranceType.TWO_WAY: + mock_entrance = parent_region.create_er_target(entrance.name) + else: + mock_entrance = child_region.create_er_target(child) + + entrance.randomization_type = er_type + mock_entrance.randomization_type = er_type + + for parent, child in RANDOMIZED_CONNECTIONS.items(): + if child == "Corrupted Future": + entrance = world.get_entrance("Artificer's Portal") + elif child == "Tower of Time - Left": + entrance = world.get_entrance("Artificer's Challenge") + else: + entrance = world.get_entrance(f"{parent} -> {child}") + parent_region = entrance.parent_region + child_region = entrance.connected_region + entrance.world = world + disconnect_entrance() + + plando = world.options.plando_connections + if plando: + connect_plando(world, plando) + + result = randomize_entrances(world, coupled, {0: [0]}) + + world.transitions = sorted(result.placements, key=lambda entrance: TRANSITIONS.index(entrance.parent_region.name)) + + for transition in world.transitions: + if "->" not in transition.name: + continue + transition.parent_region.exits.remove(transition) + transition.name = f"{transition.parent_region.name} -> {transition.connected_region.name}" + transition.parent_region.exits.append(transition) From e267714d441c56e6a8bd1496138dc17ff0861035 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Mon, 10 Mar 2025 15:34:10 +0000 Subject: [PATCH 0194/1218] AHiT: Rework Subcon Forest Boss Arena, Boss Firewall and YCHE logic (#4494) A new `Subcon Forest - Behind Boss Firewall` region is added for `Subcon Village - Snatcher Statue Chest`. `Subcon Forest Area` connects to this new region, requiring either the first `Progressive Painting Unlock`, or Expert logic + `NoPaintingSkips: false`. A new `Subcon Forest Boss Arena` region is added for `Subcon Forest - Boss Arena Chest` because this is immediately accessible from YCHE. There are connections to this region from `Your Contract has Expired` (no requirements) and from `Subcon Forest - Behind Boss Firewall` (requiring either Hard logic or `Hookshot Badge` + `TOD Access`). A reverse connection is also added to Expert logic, for `Subcon Forest Boss Arena` -> `Subcon Forest - Behind Boss Firewall`. This could be extended to include Hard logic if there is a reasonable Cherry Bridge setup. A reverse connection is also added to Expert logic, for `Subcon Forest - Behind Boss Firewall` -> `Subcon Forest Area`, so long as `NoPaintingSkips: false` because it is impossible to burn the paintings to remove the firewall, from behind the firewall. A new `Your Contract has Expired - Post Fight` region is added for the Snatcher post fight cutscene to prevent the Snatcher Hover trick giving access to YCHE, which would otherwise also give access to the new `Subcon Forest Boss Arena` Region. The paintings and boss arena gap logic for `Snatcher Statue Chest` and `Boss Arena Chest` are now handled using the connections to/from these new regions rather than being on the locations themselves. The logic for `Act Completion (Toilet of Doom)` remains unchanged because it has to be in the `Toilet of Doom` region. In Expert logic, with `NoPaintingSkips: false`, YCHE is added as a rift access region to Subcon Forest Time Rift entrances. The `YCHE Access` event is no longer used and has been removed. - Fixes painting skips logic for Subcon Village - Snatcher Statue Chest - Fixes Subcon Forest - Boss Arena Chest being inaccessible from YCHE - Adds Expert logic to reach `Snatcher Statue Chest` from YCHE - Adds Expert logic to skip the boss firewall in reverse from YCHE so long as painting skips are not removed from logic - Adds Expert logic to access Subcon Forest Time Rift entrances from YCHE so long as painting skips are not removed from logic --- worlds/ahit/Locations.py | 7 ++-- worlds/ahit/Regions.py | 25 +++++++++++++- worlds/ahit/Rules.py | 75 ++++++++++++++++++++++++++++++---------- 3 files changed, 84 insertions(+), 23 deletions(-) diff --git a/worlds/ahit/Locations.py b/worlds/ahit/Locations.py index b34e6bb4a759..713113e6919b 100644 --- a/worlds/ahit/Locations.py +++ b/worlds/ahit/Locations.py @@ -206,7 +206,7 @@ def get_location_names() -> Dict[str, int]: "Subcon Village - Graveyard Ice Cube": LocData(2000325077, "Subcon Forest Area"), "Subcon Village - House Top": LocData(2000325471, "Subcon Forest Area"), "Subcon Village - Ice Cube House": LocData(2000325469, "Subcon Forest Area"), - "Subcon Village - Snatcher Statue Chest": LocData(2000323730, "Subcon Forest Area", paintings=1), + "Subcon Village - Snatcher Statue Chest": LocData(2000323730, "Subcon Forest Behind Boss Firewall"), "Subcon Village - Stump Platform Chest": LocData(2000323729, "Subcon Forest Area"), "Subcon Forest - Giant Tree Climb": LocData(2000325470, "Subcon Forest Area"), @@ -233,7 +233,7 @@ def get_location_names() -> Dict[str, int]: "Subcon Forest - Long Tree Climb Chest": LocData(2000323734, "Subcon Forest Area", required_hats=[HatType.DWELLER], paintings=2), - "Subcon Forest - Boss Arena Chest": LocData(2000323735, "Subcon Forest Area"), + "Subcon Forest - Boss Arena Chest": LocData(2000323735, "Subcon Forest Boss Arena"), "Subcon Forest - Manor Rooftop": LocData(2000325466, "Subcon Forest Area", hit_type=HitType.dweller_bell, paintings=1), @@ -411,7 +411,7 @@ def get_location_names() -> Dict[str, int]: "Act Completion (Mail Delivery Service)": LocData(2000312032, "Mail Delivery Service", required_hats=[HatType.SPRINT]), - "Act Completion (Your Contract has Expired)": LocData(2000311390, "Your Contract has Expired", + "Act Completion (Your Contract has Expired)": LocData(2000311390, "Your Contract has Expired - Post Fight", hit_type=HitType.umbrella), "Act Completion (Time Rift - Pipe)": LocData(2000313069, "Time Rift - Pipe", hookshot=True), @@ -976,7 +976,6 @@ def get_location_names() -> Dict[str, int]: **snatcher_coins, "HUMT Access": LocData(0, "Heating Up Mafia Town"), "TOD Access": LocData(0, "Toilet of Doom"), - "YCHE Access": LocData(0, "Your Contract has Expired"), "AFR Access": LocData(0, "Alpine Free Roam"), "TIHS Access": LocData(0, "The Illness has Spread"), diff --git a/worlds/ahit/Regions.py b/worlds/ahit/Regions.py index 31edf1d0b057..857c04f1d7fc 100644 --- a/worlds/ahit/Regions.py +++ b/worlds/ahit/Regions.py @@ -347,7 +347,7 @@ def create_regions(world: "HatInTimeWorld"): sf_act3 = create_region_and_connect(world, "Toilet of Doom", "Subcon Forest - Act 3", subcon_forest) sf_act4 = create_region_and_connect(world, "Queen Vanessa's Manor", "Subcon Forest - Act 4", subcon_forest) sf_act5 = create_region_and_connect(world, "Mail Delivery Service", "Subcon Forest - Act 5", subcon_forest) - create_region_and_connect(world, "Your Contract has Expired", "Subcon Forest - Finale", subcon_forest) + sf_finale = create_region_and_connect(world, "Your Contract has Expired", "Subcon Forest - Finale", subcon_forest) # ------------------------------------------- ALPINE SKYLINE ------------------------------------------ # alpine_skyline = create_region_and_connect(world, "Alpine Skyline", "Telescope -> Alpine Skyline", spaceship) @@ -386,11 +386,24 @@ def create_regions(world: "HatInTimeWorld"): create_rift_connections(world, create_region(world, "Time Rift - Bazaar")) sf_area: Region = create_region(world, "Subcon Forest Area") + sf_behind_boss_firewall: Region = create_region(world, "Subcon Forest Behind Boss Firewall") + sf_boss_arena: Region = create_region(world, "Subcon Forest Boss Arena") + sf_area.connect(sf_behind_boss_firewall, "SF Area -> SF Behind Boss Firewall") + sf_behind_boss_firewall.connect(sf_boss_arena, "SF Behind Boss Firewall -> SF Boss Arena") sf_act1.connect(sf_area, "Subcon Forest Entrance CO") sf_act2.connect(sf_area, "Subcon Forest Entrance SW") sf_act3.connect(sf_area, "Subcon Forest Entrance TOD") sf_act4.connect(sf_area, "Subcon Forest Entrance QVM") sf_act5.connect(sf_area, "Subcon Forest Entrance MDS") + # YCHE puts the player directly in the boss arena, with no access to the rest of Subcon Forest by default. + sf_finale.connect(sf_boss_arena, "Subcon Forest Entrance YCHE") + # To support the Snatcher Hover expert logic for Act Completion (Your Contract has Expired), the act completion has + # to go in a separate region because the Snatcher Hover gives direct access to the Act Completion, but does not + # give access to the act itself. + sf_finale_post_fight: Region = create_region(world, "Your Contract has Expired - Post Fight") + # This connection must never have any rules placed on it because they will not be inherited when setting up act + # connections, only the rules for the entrances to the act and the rules for the Act Completion are inherited. + sf_finale.connect(sf_finale_post_fight, "YCHE -> YCHE - Post Fight") create_rift_connections(world, create_region(world, "Time Rift - Sleepy Subcon")) create_rift_connections(world, create_region(world, "Time Rift - Pipe")) @@ -947,6 +960,16 @@ def get_shuffled_region(world: "HatInTimeWorld", region: str) -> str: return name +def get_region_shuffled_to(world: "HatInTimeWorld", region: str) -> str: + if world.options.ActRandomizer: + original_ci: str = chapter_act_info[region] + shuffled_ci = world.act_connections[original_ci] + return next(act_name for act_name, ci in chapter_act_info.items() + if ci == shuffled_ci) + else: + return region + + def get_region_location_count(world: "HatInTimeWorld", region_name: str, included_only: bool = True) -> int: count = 0 region = world.multiworld.get_region(region_name, world.player) diff --git a/worlds/ahit/Rules.py b/worlds/ahit/Rules.py index 6753b8eb8147..2ca0628a6875 100644 --- a/worlds/ahit/Rules.py +++ b/worlds/ahit/Rules.py @@ -481,9 +481,8 @@ def set_hard_rules(world: "HatInTimeWorld"): set_rule(world.multiworld.get_location("Subcon Forest - Dweller Platforming Tree B", world.player), lambda state: has_paintings(state, world, 3)) - # Cherry bridge over boss arena gap (painting still expected) - set_rule(world.multiworld.get_location("Subcon Forest - Boss Arena Chest", world.player), - lambda state: has_paintings(state, world, 1, False) or state.has("YCHE Access", world.player)) + # Cherry bridge over boss arena gap + set_rule(world.get_entrance("SF Behind Boss Firewall -> SF Boss Arena"), lambda state: True) set_rule(world.multiworld.get_location("Subcon Forest - Noose Treehouse", world.player), lambda state: has_paintings(state, world, 2, True)) @@ -566,27 +565,61 @@ def set_expert_rules(world: "HatInTimeWorld"): lambda state: True) # Expert: Cherry Hovering - subcon_area = world.multiworld.get_region("Subcon Forest Area", world.player) - yche = world.multiworld.get_region("Your Contract has Expired", world.player) - entrance = yche.connect(subcon_area, "Subcon Forest Entrance YCHE") + # Skipping the boss firewall is possible with a Cherry Hover. + set_rule(world.get_entrance("SF Area -> SF Behind Boss Firewall"), + lambda state: has_paintings(state, world, 1, True)) + # The boss arena gap can be crossed in reverse with a Cherry Hover. + subcon_boss_arena = world.get_region("Subcon Forest Boss Arena") + subcon_behind_boss_firewall = world.get_region("Subcon Forest Behind Boss Firewall") + subcon_boss_arena.connect(subcon_behind_boss_firewall, "SF Boss Arena -> SF Behind Boss Firewall") + + subcon_area = world.get_region("Subcon Forest Area") + + # The boss firewall can be skipped in reverse with a Cherry Hover, but it is not possible to remove the boss + # firewall from reverse because the paintings to burn to remove the firewall are on the other side of the firewall. + # Therefore, a painting skip is required. The paintings could be burned by already having access to + # "Subcon Forest Area" through another entrance, but making a new connection to "Subcon Forest Area" in that case + # would be pointless. + if not world.options.NoPaintingSkips: + # The import cannot be done at the module-level because it would cause a circular import. + from .Regions import get_region_shuffled_to + + subcon_behind_boss_firewall.connect(subcon_area, "SF Behind Boss Firewall -> SF Area") + + # Because the Your Contract has Expired entrance can now reach "Subcon Forest Area", it needs to be connected to + # each of the Subcon Forest Time Rift entrances, like the other Subcon Forest Acts. + yche = world.get_region("Your Contract has Expired") + + def connect_to_shuffled_act_at(original_act_name): + region_name = get_region_shuffled_to(world, original_act_name) + return yche.connect(world.get_region(region_name), f"{original_act_name} Portal - Entrance YCHE") + + # Rules copied from `Rules.set_rift_rules()` with painting logic removed because painting skips must be + # available. + entrance = connect_to_shuffled_act_at("Time Rift - Pipe") + add_rule(entrance, lambda state: can_clear_required_act(state, world, "Subcon Forest - Act 2")) + reg_act_connection(world, world.get_entrance("Subcon Forest - Act 2").connected_region, entrance) + + entrance = connect_to_shuffled_act_at("Time Rift - Village") + add_rule(entrance, lambda state: can_clear_required_act(state, world, "Subcon Forest - Act 4")) + reg_act_connection(world, world.get_entrance("Subcon Forest - Act 4").connected_region, entrance) - if world.options.NoPaintingSkips: - add_rule(entrance, lambda state: has_paintings(state, world, 1)) + entrance = connect_to_shuffled_act_at("Time Rift - Sleepy Subcon") + add_rule(entrance, lambda state: has_relic_combo(state, world, "UFO")) set_rule(world.multiworld.get_location("Act Completion (Toilet of Doom)", world.player), lambda state: can_use_hookshot(state, world) and can_hit(state, world) and has_paintings(state, world, 1, True)) # Set painting rules only. Skipping paintings is determined in has_paintings - set_rule(world.multiworld.get_location("Subcon Forest - Boss Arena Chest", world.player), - lambda state: has_paintings(state, world, 1, True)) set_rule(world.multiworld.get_location("Subcon Forest - Magnet Badge Bush", world.player), lambda state: has_paintings(state, world, 3, True)) # You can cherry hover to Snatcher's post-fight cutscene, which completes the level without having to fight him - subcon_area.connect(yche, "Snatcher Hover") - set_rule(world.multiworld.get_location("Act Completion (Your Contract has Expired)", world.player), - lambda state: True) + yche_post_fight = world.get_region("Your Contract has Expired - Post Fight") + subcon_area.connect(yche_post_fight, "Snatcher Hover") + # Cherry Hover from YCHE also works, so there are no requirements for the Act Completion. + set_rule(world.get_location("Act Completion (Your Contract has Expired)"), lambda state: True) if world.is_dlc2(): # Expert: clear Rush Hour with nothing @@ -681,12 +714,18 @@ def set_subcon_rules(world: "HatInTimeWorld"): lambda state: can_use_hat(state, world, HatType.BREWING) or state.has("Umbrella", world.player) or can_use_hat(state, world, HatType.DWELLER)) - # You can't skip over the boss arena wall without cherry hover, so these two need to be set this way - set_rule(world.multiworld.get_location("Subcon Forest - Boss Arena Chest", world.player), - lambda state: state.has("TOD Access", world.player) and can_use_hookshot(state, world) - and has_paintings(state, world, 1, False) or state.has("YCHE Access", world.player)) + # You can't skip over the boss arena wall without cherry hover. + set_rule(world.get_entrance("SF Area -> SF Behind Boss Firewall"), + lambda state: has_paintings(state, world, 1, False)) + + # The hookpoints to cross the boss arena gap are only present in Toilet of Doom. + set_rule(world.get_entrance("SF Behind Boss Firewall -> SF Boss Arena"), + lambda state: state.has("TOD Access", world.player) + and can_use_hookshot(state, world)) - # The painting wall can't be skipped without cherry hover, which is Expert + # The Act Completion is in the Toilet of Doom region, so the same rules as passing the boss firewall and crossing + # the boss arena gap are required. "TOD Access" is implied from the region so does not need to be included in the + # rule. set_rule(world.multiworld.get_location("Act Completion (Toilet of Doom)", world.player), lambda state: can_use_hookshot(state, world) and can_hit(state, world) and has_paintings(state, world, 1, False)) From dd554092095e51104205bb70c9d4aebf78c2efdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BCbcke?= <49335240+PaddiLu@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:35:40 +0100 Subject: [PATCH 0195/1218] =?UTF-8?q?Pok=C3=A9mon=20R/B:=20Fix=20Rock=20Tu?= =?UTF-8?q?nnel=20B1F=20randomization=20(#4670)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bottom to central path sealed off * Bottom-to-left-path to right path sealed off * Central opening (r4444): Left unsealed, paths seperated * Top right half rocks fixed * Middle to top opening sealed * Right hallway seal correctly positioned * Top right ladder: Fixed overlapping walls --- worlds/pokemon_rb/rock_tunnel.py | 42 +++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/worlds/pokemon_rb/rock_tunnel.py b/worlds/pokemon_rb/rock_tunnel.py index 3a70709eb0f2..46b2be3040dc 100644 --- a/worlds/pokemon_rb/rock_tunnel.py +++ b/worlds/pokemon_rb/rock_tunnel.py @@ -177,7 +177,11 @@ def single(x, y): if random.randint(0, 1): floor(10, 7) floor(11, 7) - tall(random.randint(12, 17), 8) + if current_map[10][13]==1: + # (13,10) is floor + tall(random.randint(14, 16), 8) + else: + tall(random.randint(12, 16), 8) else: floor(12, 5) floor(12, 6) @@ -185,8 +189,10 @@ def single(x, y): wide(17, random.randint(3, 5)) r = random.choice([1, 3]) floor(12, r) - floor(12, + 1) - + floor(12, r + 1) + if current_map[4][12] + current_map[5][12] == 2: + # (12,4) and (12,5) are floor + wide(11,4) elif c == 2: r = random.randint(0, 6) if r == 0: @@ -221,6 +227,9 @@ def single(x, y): #early block wide(13, random.randint(2, 5)) tall(random.randint(14, 15), 1) + if not 1 in (current_map[1][14],current_map[2][13]): + # wide(13,2) and tall(14,1) overlap + single(13,2) elif r == 1: if random.randint(0, 1): tall(16, 5) @@ -243,19 +252,34 @@ def single(x, y): r = random.randint(r, 6) if r == 6: #late open - r2 = random.randint(0, 2) - floor(1 + (r2 * 2), 14) - floor(2 + (r2 * 2), 14) + if random.randint(0, 1): + floor(1, 14) + floor(2, 14) + else: + floor(3, 14) + floor(4, 14) elif r == 5: - floor(6, 12) - floor(6, 13) + if random.randint(0,1): + floor(6, 12) + floor(6, 13) + else: + floor(5, 14) + floor(6, 14) elif r == 4: if random.randint(0, 1): floor(6, 11) floor(7, 11) else: floor(8, 11) - floor(9, 11) + if current_map[12][10]==32: + # (10,12) is wide + single(9, 11) + else: + floor(9, 11) + if 31 in (current_map[8][6],current_map[8][7]): + # (6,7) or (7,7) are tall + floor(6, 10) + wide(7, 9) elif r == 3: floor(9, 9) floor(9, 10) From be550ff6fb6d8ca4832e0ba7401d069f6c88b3d4 Mon Sep 17 00:00:00 2001 From: Dinopony Date: Mon, 10 Mar 2025 16:35:58 +0100 Subject: [PATCH 0196/1218] Landstalker: Several small fixes (#4675) * Landstalker: Fixed duplicate entrance names when using the "No teleport tree requirements" option * Landstalker: Fixed more cases of duplicate entrance names when using "Shuffle Trees" with open trees * Landstalker: Fixed endgame locations being present in "Reach Kazalt" goal * Landstalker: Fixed Lithograph hint pointing at the wrong player * Landstalker: Updated docs to remove the link to Steam since game got delisted * Landstalker: Fixed high value hint_count rarely failing at generation * Landstalker: Fixed dynamic shop prices being potentially invalid in case of a progression balancing (changes by ExemptMedic) --- worlds/landstalker/Hints.py | 2 +- worlds/landstalker/__init__.py | 19 ++++++------------- .../landstalker/docs/landstalker_setup_en.md | 2 +- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/worlds/landstalker/Hints.py b/worlds/landstalker/Hints.py index 4211e0ef3bb1..366925c64de1 100644 --- a/worlds/landstalker/Hints.py +++ b/worlds/landstalker/Hints.py @@ -131,7 +131,7 @@ def generate_random_hints(world: "LandstalkerWorld"): hint_texts = list(set(hint_texts)) random.shuffle(hint_texts) - hint_count = world.options.hint_count.value + hint_count = min(world.options.hint_count.value, len(hint_texts)) del hint_texts[hint_count:] hint_source_names = [source["description"] for source in HINT_SOURCES_JSON if diff --git a/worlds/landstalker/__init__.py b/worlds/landstalker/__init__.py index cfdc335c484e..98172eb6a7bb 100644 --- a/worlds/landstalker/__init__.py +++ b/worlds/landstalker/__init__.py @@ -39,7 +39,7 @@ class LandstalkerWorld(World): item_name_to_id = build_item_name_to_id_table() location_name_to_id = build_location_name_to_id_table() - cached_spheres: List[Set[Location]] + cached_spheres: List[Set[Location]] = [] def __init__(self, multiworld, player): super().__init__(multiworld, player) @@ -48,9 +48,11 @@ def __init__(self, multiworld, player): self.dark_region_ids = [] self.teleport_tree_pairs = [] self.jewel_items = [] - self.cached_spheres = [] def fill_slot_data(self) -> dict: + if not LandstalkerWorld.cached_spheres: + LandstalkerWorld.cached_spheres = list(self.multiworld.get_spheres()) + # Generate hints. self.adjust_shop_prices() hints = Hints.generate_random_hints(self) @@ -232,18 +234,9 @@ def get_starting_health(self): else: return 4 - @classmethod - def stage_post_fill(cls, multiworld: MultiWorld): - # Cache spheres for hint calculation after fill completes. - cached_spheres = list(multiworld.get_spheres()) - for world in multiworld.get_game_worlds(cls.game): - world.cached_spheres = cached_spheres - @classmethod def stage_modify_multidata(cls, multiworld: MultiWorld, *_): - # Clean up all references in cached spheres after generation completes. - for world in multiworld.get_game_worlds(cls.game): - world.cached_spheres = [] + LandstalkerWorld.cached_spheres = [] def adjust_shop_prices(self): # Calculate prices for items in shops once all items have their final position @@ -254,7 +247,7 @@ def adjust_shop_prices(self): global_price_factor = self.options.shop_prices_factor / 100.0 - spheres = self.cached_spheres + spheres = LandstalkerWorld.cached_spheres sphere_count = len(spheres) for sphere_id, sphere in enumerate(spheres): location: LandstalkerLocation # after conditional, we guarantee it's this kind of location. diff --git a/worlds/landstalker/docs/landstalker_setup_en.md b/worlds/landstalker/docs/landstalker_setup_en.md index 30f85dd8f19b..05cf35f8b071 100644 --- a/worlds/landstalker/docs/landstalker_setup_en.md +++ b/worlds/landstalker/docs/landstalker_setup_en.md @@ -6,7 +6,7 @@ - A compatible emulator to run the game - [RetroArch](https://retroarch.com?page=platforms) with the Genesis Plus GX core - [Bizhawk 2.9.1 (x64)](https://tasvideos.org/BizHawk/ReleaseHistory) with the Genesis Plus GX core -- Your legally obtained Landstalker US ROM file (which can be acquired on [Steam](https://store.steampowered.com/app/71118/Landstalker_The_Treasures_of_King_Nole/)) +- A Landstalker US ROM file dumped from the original cartridge ## Installation Instructions From d83294efa7a52170f4a7f71f1e6e2a53056cf368 Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Mon, 10 Mar 2025 18:39:35 +0300 Subject: [PATCH 0197/1218] Stardew valley: Fix Aurora Vineyard Tablet logic (#4512) * - Add requirement on Aurora Vineyard tablet to start the quest * - Add rule for using the aurora vineyard staircase * - Added a test for the tablet * - Add a few missing items to the test * - Introduce a new item to split the quest from the door and avoir ER issues * - Optimize imports * - Forgot to generate the item * fix Aurora mess # Conflicts: # worlds/stardew_valley/rules.py # worlds/stardew_valley/test/mods/TestMods.py * fix a couple errors in the cherry picked commit, added a method to improve readability and reduce chance of human error on story quest conditions * - remove blank line * - Code review comments * - fixed weird assert name * - fixed accidentally surviving line * - Fixed imports --------- Co-authored-by: Jouramie <16137441+Jouramie@users.noreply.github.com> --- worlds/stardew_valley/data/items.csv | 1 + worlds/stardew_valley/early_items.py | 2 +- worlds/stardew_valley/items.py | 6 ++-- worlds/stardew_valley/locations.py | 4 +-- worlds/stardew_valley/logic/bundle_logic.py | 2 +- worlds/stardew_valley/logic/crafting_logic.py | 2 +- worlds/stardew_valley/logic/quest_logic.py | 31 +++++++++---------- .../logic/relationship_logic.py | 12 +++++-- .../stardew_valley/mods/logic/quests_logic.py | 10 +++++- worlds/stardew_valley/mods/logic/sve_logic.py | 24 +++++++------- worlds/stardew_valley/options/options.py | 6 ++++ worlds/stardew_valley/rules.py | 9 +++--- .../strings/ap_names/mods/mod_items.py | 15 ++++++--- worlds/stardew_valley/test/mods/TestMods.py | 19 ++++++++++-- worlds/stardew_valley/test/mods/TestSVE.py | 29 +++++++++++++++++ 15 files changed, 120 insertions(+), 52 deletions(-) create mode 100644 worlds/stardew_valley/test/mods/TestSVE.py diff --git a/worlds/stardew_valley/data/items.csv b/worlds/stardew_valley/data/items.csv index 05af275ba472..36e048100c0e 100644 --- a/worlds/stardew_valley/data/items.csv +++ b/worlds/stardew_valley/data/items.csv @@ -928,6 +928,7 @@ id,name,classification,groups,mod_name 10518,Aurora Vineyard Tablet,progression,,Stardew Valley Expanded 10519,Scarlett's Job Offer,progression,,Stardew Valley Expanded 10520,Morgan's Schooling,progression,,Stardew Valley Expanded +10521,Aurora Vineyard Reclamation,progression,,Stardew Valley Expanded 10601,Magic Elixir Recipe,progression,"CHEFSANITY,CHEFSANITY_PURCHASE",Magic 10602,Travel Core Recipe,progression,CRAFTSANITY,Magic 10603,Haste Elixir Recipe,progression,CRAFTSANITY,Stardew Valley Expanded diff --git a/worlds/stardew_valley/early_items.py b/worlds/stardew_valley/early_items.py index 5ad48912a28d..1457c5c7c5ef 100644 --- a/worlds/stardew_valley/early_items.py +++ b/worlds/stardew_valley/early_items.py @@ -41,7 +41,7 @@ def setup_early_items(multiworld, options: stardew_options.StardewValleyOptions, if fishing is not None and content.features.skill_progression.is_progressive: early_forced.append(fishing.level_name) - if options.quest_locations >= 0: + if options.quest_locations.has_story_quests(): early_candidates.append(Wallet.magnifying_glass) if options.special_order_locations & stardew_options.SpecialOrderLocations.option_board: diff --git a/worlds/stardew_valley/items.py b/worlds/stardew_valley/items.py index 1fbe012e279c..dcb37a8f412c 100644 --- a/worlds/stardew_valley/items.py +++ b/worlds/stardew_valley/items.py @@ -264,7 +264,7 @@ def create_unique_items(item_factory: StardewItemFactory, options: StardewValley def create_raccoons(item_factory: StardewItemFactory, options: StardewValleyOptions, items: List[Item]): number_progressive_raccoons = 9 - if options.quest_locations < 0: + if options.quest_locations.has_no_story_quests(): number_progressive_raccoons = number_progressive_raccoons - 1 items.extend(item_factory(item) for item in [CommunityUpgrade.raccoon] * number_progressive_raccoons) @@ -387,7 +387,7 @@ def create_quest_rewards(item_factory: StardewItemFactory, options: StardewValle def create_special_quest_rewards(item_factory: StardewItemFactory, options: StardewValleyOptions, items: List[Item]): - if options.quest_locations < 0: + if options.quest_locations.has_no_story_quests(): return # items.append(item_factory("Adventurer's Guild")) # Now unlocked always! items.append(item_factory(Wallet.club_card)) @@ -698,7 +698,7 @@ def create_quest_rewards_sve(item_factory: StardewItemFactory, options: StardewV if not exclude_ginger_island: items.extend([item_factory(item) for item in SVEQuestItem.sve_always_quest_items_ginger_island]) - if options.quest_locations < 0: + if options.quest_locations.has_no_story_quests(): return items.extend([item_factory(item) for item in SVEQuestItem.sve_quest_items]) diff --git a/worlds/stardew_valley/locations.py b/worlds/stardew_valley/locations.py index df86e0812505..c7d787e55dc2 100644 --- a/worlds/stardew_valley/locations.py +++ b/worlds/stardew_valley/locations.py @@ -191,7 +191,7 @@ def extend_cropsanity_locations(randomized_locations: List[LocationData], conten def extend_quests_locations(randomized_locations: List[LocationData], options: StardewValleyOptions, content: StardewContent): - if options.quest_locations < 0: + if options.quest_locations.has_no_story_quests(): return story_quest_locations = locations_by_tag[LocationTags.STORY_QUEST] @@ -317,7 +317,7 @@ def extend_mandatory_locations(randomized_locations: List[LocationData], options def extend_situational_quest_locations(randomized_locations: List[LocationData], options: StardewValleyOptions): - if options.quest_locations < 0: + if options.quest_locations.has_no_story_quests(): return if ModNames.distant_lands in options.mods: if ModNames.alecto in options.mods: diff --git a/worlds/stardew_valley/logic/bundle_logic.py b/worlds/stardew_valley/logic/bundle_logic.py index 98fda1c73c7d..8ede4de5e7c4 100644 --- a/worlds/stardew_valley/logic/bundle_logic.py +++ b/worlds/stardew_valley/logic/bundle_logic.py @@ -76,7 +76,7 @@ def can_complete_community_center(self) -> StardewRule: self.logic.region.can_reach_location("Complete Boiler Room")) def can_access_raccoon_bundles(self) -> StardewRule: - if self.options.quest_locations < 0: + if self.options.quest_locations.has_no_story_quests(): return self.logic.received(CommunityUpgrade.raccoon, 1) & self.logic.quest.can_complete_quest(Quest.giant_stump) # 1 - Break the tree diff --git a/worlds/stardew_valley/logic/crafting_logic.py b/worlds/stardew_valley/logic/crafting_logic.py index 28bf0d2af22c..bd839707ef6b 100644 --- a/worlds/stardew_valley/logic/crafting_logic.py +++ b/worlds/stardew_valley/logic/crafting_logic.py @@ -48,7 +48,7 @@ def knows_recipe(self, recipe: CraftingRecipe) -> StardewRule: else: return self.logic.crafting.received_recipe(recipe.item) if isinstance(recipe.source, QuestSource): - if self.options.quest_locations < 0: + if self.options.quest_locations.has_no_story_quests(): return self.logic.crafting.can_learn_recipe(recipe) else: return self.logic.crafting.received_recipe(recipe.item) diff --git a/worlds/stardew_valley/logic/quest_logic.py b/worlds/stardew_valley/logic/quest_logic.py index 42f401b96025..8779848fed45 100644 --- a/worlds/stardew_valley/logic/quest_logic.py +++ b/worlds/stardew_valley/logic/quest_logic.py @@ -118,25 +118,24 @@ def can_complete_quest(self, quest: str) -> StardewRule: return Has(quest, self.registry.quest_rules, "quest") def has_club_card(self) -> StardewRule: - if self.options.quest_locations < 0: - return self.logic.quest.can_complete_quest(Quest.the_mysterious_qi) - return self.logic.received(Wallet.club_card) + if self.options.quest_locations.has_story_quests(): + return self.logic.received(Wallet.club_card) + return self.logic.quest.can_complete_quest(Quest.the_mysterious_qi) def has_magnifying_glass(self) -> StardewRule: - if self.options.quest_locations < 0: - return self.logic.quest.can_complete_quest(Quest.a_winter_mystery) - return self.logic.received(Wallet.magnifying_glass) + if self.options.quest_locations.has_story_quests(): + return self.logic.received(Wallet.magnifying_glass) + return self.logic.quest.can_complete_quest(Quest.a_winter_mystery) def has_dark_talisman(self) -> StardewRule: - if self.options.quest_locations < 0: - return self.logic.quest.can_complete_quest(Quest.dark_talisman) - return self.logic.received(Wallet.dark_talisman) + if self.options.quest_locations.has_story_quests(): + return self.logic.received(Wallet.dark_talisman) + return self.logic.quest.can_complete_quest(Quest.dark_talisman) def has_raccoon_shop(self) -> StardewRule: - if self.options.quest_locations < 0: - return self.logic.received(CommunityUpgrade.raccoon, 2) & self.logic.quest.can_complete_quest(Quest.giant_stump) - - # 1 - Break the tree - # 2 - Build the house, which summons the bundle racoon. This one is done manually if quests are turned off - # 3 - Raccoon's wife opens the shop - return self.logic.received(CommunityUpgrade.raccoon, 3) + if self.options.quest_locations.has_story_quests(): + # 1 - Break the tree + # 2 - Build the house, which summons the bundle racoon. This one is done manually if quests are turned off + # 3 - Raccoon's wife opens the shop + return self.logic.received(CommunityUpgrade.raccoon, 3) + return self.logic.received(CommunityUpgrade.raccoon, 2) & self.logic.quest.can_complete_quest(Quest.giant_stump) diff --git a/worlds/stardew_valley/logic/relationship_logic.py b/worlds/stardew_valley/logic/relationship_logic.py index 61e63a90c83a..b74bdc564581 100644 --- a/worlds/stardew_valley/logic/relationship_logic.py +++ b/worlds/stardew_valley/logic/relationship_logic.py @@ -1,4 +1,5 @@ import math +import typing from typing import Union from Utils import cache_self1 @@ -14,13 +15,18 @@ from ..data.villagers_data import Villager from ..stardew_rule import StardewRule, True_, false_, true_ from ..strings.ap_names.mods.mod_items import SVEQuestItem -from ..strings.crop_names import Fruit from ..strings.generic_names import Generic from ..strings.gift_names import Gift +from ..strings.quest_names import ModQuest from ..strings.region_names import Region from ..strings.season_names import Season from ..strings.villager_names import NPC, ModNPC +if typing.TYPE_CHECKING: + from ..mods.logic.mod_logic import ModLogicMixin +else: + ModLogicMixin = object + possible_kids = ("Cute Baby", "Ugly Baby") @@ -38,7 +44,7 @@ def __init__(self, *args, **kwargs): class RelationshipLogic(BaseLogic[Union[RelationshipLogicMixin, BuildingLogicMixin, SeasonLogicMixin, TimeLogicMixin, GiftLogicMixin, RegionLogicMixin, -ReceivedLogicMixin, HasLogicMixin]]): +ReceivedLogicMixin, HasLogicMixin, ModLogicMixin]]): def can_date(self, npc: str) -> StardewRule: return self.logic.relationship.has_hearts(npc, 8) & self.logic.has(Gift.bouquet) @@ -141,7 +147,7 @@ def can_meet(self, npc: str) -> StardewRule: rules.append(self.logic.region.can_reach(Region.volcano_floor_10)) elif npc == ModNPC.apples: - rules.append(self.logic.has(Fruit.starfruit)) + rules.append(self.logic.mod.quest.has_completed_aurora_vineyard_bundle()) elif npc == ModNPC.scarlett: scarlett_job = self.logic.received(SVEQuestItem.scarlett_job_offer) diff --git a/worlds/stardew_valley/mods/logic/quests_logic.py b/worlds/stardew_valley/mods/logic/quests_logic.py index 2ff74523940e..ef9698266147 100644 --- a/worlds/stardew_valley/mods/logic/quests_logic.py +++ b/worlds/stardew_valley/mods/logic/quests_logic.py @@ -12,6 +12,7 @@ from ...logic.time_logic import TimeLogicMixin from ...stardew_rule import StardewRule from ...strings.animal_product_names import AnimalProduct +from ...strings.ap_names.mods.mod_items import SVEQuestItem from ...strings.artisan_good_names import ArtisanGood from ...strings.crop_names import Fruit, SVEFruit, SVEVegetable, Vegetable from ...strings.fertilizer_names import Fertilizer @@ -83,7 +84,8 @@ def _get_sve_quest_rules(self): self.logic.region.can_reach(SVERegion.grandpas_shed), ModQuest.MarlonsBoat: self.logic.has_all(*(Loot.void_essence, Loot.solar_essence, Loot.slime, Loot.bat_wing, Loot.bug_meat)) & self.logic.relationship.can_meet(ModNPC.lance) & self.logic.region.can_reach(SVERegion.guild_summit), - ModQuest.AuroraVineyard: self.logic.has(Fruit.starfruit) & self.logic.region.can_reach(SVERegion.aurora_vineyard), + ModQuest.AuroraVineyard: self.logic.region.can_reach(SVERegion.aurora_vineyard) & self.logic.received(SVEQuestItem.aurora_vineyard_tablet) & + self.logic.has(Fruit.starfruit) & self.logic.region.can_reach(Region.forest), ModQuest.MonsterCrops: self.logic.has_all(*(SVEVegetable.monster_mushroom, SVEFruit.slime_berry, SVEFruit.monster_fruit, SVEVegetable.void_root)), ModQuest.VoidSoul: self.logic.has(ModLoot.void_soul) & self.logic.region.can_reach(Region.farm) & self.logic.season.has_any_not_winter() & self.logic.region.can_reach(SVERegion.badlands_entrance) & @@ -91,6 +93,12 @@ def _get_sve_quest_rules(self): self.logic.monster.can_kill_any((Monster.shadow_brute, Monster.shadow_shaman, Monster.shadow_sniper)), } + def has_completed_aurora_vineyard_bundle(self): + if self.options.quest_locations.has_story_quests(): + return self.logic.received(SVEQuestItem.aurora_vineyard_reclamation) + return self.logic.quest.can_complete_quest(ModQuest.AuroraVineyard) + + def _get_distant_lands_quest_rules(self): if ModNames.distant_lands not in self.options.mods: return {} diff --git a/worlds/stardew_valley/mods/logic/sve_logic.py b/worlds/stardew_valley/mods/logic/sve_logic.py index fc093554d8e6..faca8d332d22 100644 --- a/worlds/stardew_valley/mods/logic/sve_logic.py +++ b/worlds/stardew_valley/mods/logic/sve_logic.py @@ -41,24 +41,24 @@ def has_any_rune(self): return self.logic.or_(*(self.logic.received(rune) for rune in rune_list)) def has_iridium_bomb(self): - if self.options.quest_locations < 0: - return self.logic.quest.can_complete_quest(ModQuest.RailroadBoulder) - return self.logic.received(SVEQuestItem.iridium_bomb) + if self.options.quest_locations.has_story_quests(): + return self.logic.received(SVEQuestItem.iridium_bomb) + return self.logic.quest.can_complete_quest(ModQuest.RailroadBoulder) def has_marlon_boat(self): - if self.options.quest_locations < 0: - return self.logic.quest.can_complete_quest(ModQuest.MarlonsBoat) - return self.logic.received(SVEQuestItem.marlon_boat_paddle) + if self.options.quest_locations.has_story_quests(): + return self.logic.received(SVEQuestItem.marlon_boat_paddle) + return self.logic.quest.can_complete_quest(ModQuest.MarlonsBoat) def has_grandpa_shed_repaired(self): - if self.options.quest_locations < 0: - return self.logic.quest.can_complete_quest(ModQuest.GrandpasShed) - return self.logic.received(SVEQuestItem.grandpa_shed) + if self.options.quest_locations.has_story_quests(): + return self.logic.received(SVEQuestItem.grandpa_shed) + return self.logic.quest.can_complete_quest(ModQuest.GrandpasShed) def has_bear_knowledge(self): - if self.options.quest_locations < 0: - return self.logic.quest.can_complete_quest(Quest.strange_note) - return self.logic.received(Wallet.bears_knowledge) + if self.options.quest_locations.has_story_quests(): + return self.logic.received(Wallet.bears_knowledge) + return self.logic.quest.can_complete_quest(Quest.strange_note) def can_buy_bear_recipe(self): access_rule = (self.logic.quest.can_complete_quest(Quest.strange_note) & self.logic.tool.has_tool(Tool.axe, ToolMaterial.basic) & diff --git a/worlds/stardew_valley/options/options.py b/worlds/stardew_valley/options/options.py index 5cfdfcf9c741..bc76c617b31f 100644 --- a/worlds/stardew_valley/options/options.py +++ b/worlds/stardew_valley/options/options.py @@ -384,6 +384,12 @@ class QuestLocations(NamedRange): "maximum": 56, } + def has_story_quests(self) -> bool: + return self.value >= 0 + + def has_no_story_quests(self) -> bool: + return not self.has_story_quests() + class Fishsanity(Choice): """Locations for catching each fish the first time? diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index 01acc7b82225..dc63018697e0 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -149,7 +149,7 @@ def set_bundle_rules(bundle_rooms: List[BundleRoom], logic: StardewLogic, multiw bundle_rules = logic.bundle.can_complete_bundle(bundle) if bundle_room.name == CCRoom.raccoon_requests: num = int(bundle.name[-1]) - extra_raccoons = 1 if world_options.quest_locations >= 0 else 0 + extra_raccoons = 1 if world_options.quest_locations.has_story_quests() else 0 extra_raccoons = extra_raccoons + num bundle_rules = logic.received(CommunityUpgrade.raccoon, extra_raccoons) & bundle_rules if num > 1: @@ -505,7 +505,7 @@ def set_cropsanity_rules(logic: StardewLogic, multiworld, player, world_content: def set_story_quests_rules(all_location_names: Set[str], logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): - if world_options.quest_locations < 0: + if world_options.quest_locations.has_no_story_quests(): return for quest in locations.locations_by_tag[LocationTags.STORY_QUEST]: if quest.name in all_location_names and (quest.mod_name is None or quest.mod_name in world_options.mods): @@ -540,9 +540,9 @@ def set_special_order_rules(all_location_names: Set[str], logic: StardewLogic, m def set_help_wanted_quests_rules(logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): - help_wanted_number = world_options.quest_locations.value - if help_wanted_number < 0: + if world_options.quest_locations.has_no_story_quests(): return + help_wanted_number = world_options.quest_locations.value for i in range(0, help_wanted_number): set_number = i // 7 month_rule = logic.time.has_lived_months(set_number) @@ -973,6 +973,7 @@ def set_sve_rules(logic: StardewLogic, multiworld: MultiWorld, player: int, worl set_entrance_rule(multiworld, player, SVEEntrance.use_bear_shop, (logic.mod.sve.can_buy_bear_recipe())) set_entrance_rule(multiworld, player, SVEEntrance.railroad_to_grampleton_station, logic.received(SVEQuestItem.scarlett_job_offer)) set_entrance_rule(multiworld, player, SVEEntrance.museum_to_gunther_bedroom, logic.relationship.has_hearts(ModNPC.gunther, 2)) + set_entrance_rule(multiworld, player, SVEEntrance.to_aurora_basement, logic.mod.quest.has_completed_aurora_vineyard_bundle()) logic.mod.sve.initialize_rules() for location in logic.registry.sve_location_rules: MultiWorldRules.set_rule(multiworld.get_location(location, player), diff --git a/worlds/stardew_valley/strings/ap_names/mods/mod_items.py b/worlds/stardew_valley/strings/ap_names/mods/mod_items.py index 58371aebe7ed..d87a81f5e51d 100644 --- a/worlds/stardew_valley/strings/ap_names/mods/mod_items.py +++ b/worlds/stardew_valley/strings/ap_names/mods/mod_items.py @@ -19,6 +19,12 @@ class SkillLevel: class SVEQuestItem: aurora_vineyard_tablet = "Aurora Vineyard Tablet" + """Triggers the apparition of the bundle tablet in the Aurora Vineyard, so you can do the Aurora Vineyard quest. + This aim to break dependencies on completing the Community Center. + """ + aurora_vineyard_reclamation = "Aurora Vineyard Reclamation" + """Triggers the unlock of the Aurora Vineyard basement, so you can meet Apples. + """ iridium_bomb = "Iridium Bomb" void_soul = "Void Spirit Peace Agreement" kittyfish_spell = "Kittyfish Spell" @@ -29,10 +35,10 @@ class SVEQuestItem: fable_reef_portal = "Fable Reef Portal" grandpa_shed = "Grandpa's Shed" - sve_always_quest_items: List[str] = [kittyfish_spell, scarlett_job_offer, morgan_schooling] - sve_always_quest_items_ginger_island: List[str] = [fable_reef_portal] - sve_quest_items: List[str] = [aurora_vineyard_tablet, iridium_bomb, void_soul, grandpa_shed] - sve_quest_items_ginger_island: List[str] = [marlon_boat_paddle] + sve_always_quest_items: list[str] = [kittyfish_spell, scarlett_job_offer, morgan_schooling, aurora_vineyard_tablet, ] + sve_always_quest_items_ginger_island: list[str] = [fable_reef_portal, ] + sve_quest_items: list[str] = [iridium_bomb, void_soul, grandpa_shed, aurora_vineyard_reclamation, ] + sve_quest_items_ginger_island: list[str] = [marlon_boat_paddle, ] class SVELocation: @@ -53,4 +59,3 @@ class SVERunes: nexus_wizard = "Nexus: Wizard Runes" nexus_items: List[str] = [nexus_farm, nexus_wizard, nexus_spring, nexus_aurora, nexus_guild, nexus_junimo, nexus_outpost] - diff --git a/worlds/stardew_valley/test/mods/TestMods.py b/worlds/stardew_valley/test/mods/TestMods.py index 1dd2ab4902f7..dc958652e1ec 100644 --- a/worlds/stardew_valley/test/mods/TestMods.py +++ b/worlds/stardew_valley/test/mods/TestMods.py @@ -1,10 +1,9 @@ import random -from BaseClasses import get_seed +from BaseClasses import get_seed, ItemClassification from .. import SVTestBase, SVTestCase, allsanity_mods_6_x_x, fill_dataclass_with_default from ..assertion import ModAssertMixin, WorldAssertMixin -from ... import items, Group, ItemClassification, create_content -from ... import options +from ... import options, items, Group, create_content from ...mods.mod_data import ModNames from ...options import SkillProgression, Walnutsanity from ...options.options import all_mods @@ -188,3 +187,17 @@ def test_mod_entrance_randomization(self): self.assertEqual(len(set(randomized_connections.values())), len(randomized_connections.values()), f"Connections are duplicated in randomization.") + + +class TestVanillaLogicAlternativeWhenQuestsAreNotRandomized(WorldAssertMixin, SVTestBase): + """We often forget to add an alternative rule that works when quests are not randomized. When this happens, some + Location are not reachable because they depend on items that are only added to the pool when quests are randomized. + """ + options = allsanity_mods_6_x_x() | { + options.QuestLocations.internal_name: options.QuestLocations.special_range_names["none"], + options.Goal.internal_name: options.Goal.option_perfection, + } + + def test_given_no_quest_all_mods_when_generate_then_can_reach_everything(self): + self.collect_everything() + self.assert_can_reach_everything(self.multiworld) diff --git a/worlds/stardew_valley/test/mods/TestSVE.py b/worlds/stardew_valley/test/mods/TestSVE.py new file mode 100644 index 000000000000..ca63dcb351aa --- /dev/null +++ b/worlds/stardew_valley/test/mods/TestSVE.py @@ -0,0 +1,29 @@ +from .. import SVTestBase +from ... import options +from ...mods.mod_data import ModNames +from ...strings.ap_names.mods.mod_items import SVEQuestItem +from ...strings.quest_names import ModQuest +from ...strings.region_names import SVERegion + + +class TestAuroraVineyard(SVTestBase): + options = { + options.Cropsanity.internal_name: options.Cropsanity.option_enabled, + options.Mods.internal_name: frozenset({ModNames.sve}) + } + + def test_need_tablet_to_do_quest(self): + self.collect("Starfruit Seeds") + self.collect("Bus Repair") + self.collect("Shipping Bin") + self.collect("Summer") + location_name = ModQuest.AuroraVineyard + self.assert_cannot_reach_location(location_name, self.multiworld.state) + self.collect(SVEQuestItem.aurora_vineyard_tablet) + self.assert_can_reach_location(location_name, self.multiworld.state) + + def test_need_reclamation_to_go_downstairs(self): + region_name = SVERegion.aurora_vineyard_basement + self.assert_cannot_reach_region(region_name, self.multiworld.state) + self.collect(SVEQuestItem.aurora_vineyard_reclamation, 1) + self.assert_can_reach_region(region_name, self.multiworld.state) From 06111ac6cf30de7d8cfdf52f1f96baea9da7e9ea Mon Sep 17 00:00:00 2001 From: justinspatz <164453633+justinspatz@users.noreply.github.com> Date: Mon, 10 Mar 2025 12:39:45 -0400 Subject: [PATCH 0198/1218] OOT: Have beehives that only appear as a child not be in logic if only adult can break beehives (#4646) * Change the logic for the 3 Zora's Domain Beehives to support new rule Implement new logic changes to these 3 locations * Update LogicHelpers.json with new rule for beehives that only appear for child link Added below the "can_break_upper_beehive" a new helper called "can_break_upper_beehive_child" which removes the requirement for hookshot to avoid a logic error in the Zora Domain Beehives where it checks whether child or adult can break beehives, even though these beehives do not appear as an adult. * Update LogicHelpers.json moving the call for is_child As is_child is already called for can_use (Boomerang), it's a bit redundant to include the check for using the Boomerang, so it's being moved to be with the Bombchu check to ensure that it's not expected if the Bombchu Logic Rule is turned on that Adult can use bombchus to break the beehives. This effectively does the same thing, but should be better on performance. --- worlds/oot/data/LogicHelpers.json | 1 + worlds/oot/data/World/Overworld.json | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/worlds/oot/data/LogicHelpers.json b/worlds/oot/data/LogicHelpers.json index 7f3641062a8f..a05fe660664a 100644 --- a/worlds/oot/data/LogicHelpers.json +++ b/worlds/oot/data/LogicHelpers.json @@ -66,6 +66,7 @@ "can_break_heated_crate": "deadly_bonks != 'ohko' or (Fairy and (can_use(Goron_Tunic) or damage_multiplier != 'ohko')) or can_use(Nayrus_Love) or can_blast_or_smash", "can_break_lower_beehive": "can_use(Boomerang) or can_use(Hookshot) or Bombs or (logic_beehives_bombchus and has_bombchus)", "can_break_upper_beehive": "can_use(Boomerang) or can_use(Hookshot) or (logic_beehives_bombchus and has_bombchus)", + "can_break_upper_beehive_child": "can_use(Boomerang) or (logic_beehives_bombchus and has_bombchus and is_child)", # can_use and helpers # The parser reduces this to smallest form based on item category. # Note that can_use(item) is False for any item not covered here. diff --git a/worlds/oot/data/World/Overworld.json b/worlds/oot/data/World/Overworld.json index de2b4a61dc6a..87b24a6e578f 100644 --- a/worlds/oot/data/World/Overworld.json +++ b/worlds/oot/data/World/Overworld.json @@ -2233,8 +2233,8 @@ "ZD Pot 3": "True", "ZD Pot 4": "True", "ZD Pot 5": "True", - "ZD In Front of King Zora Beehive 1": "is_child and can_break_upper_beehive", - "ZD In Front of King Zora Beehive 2": "is_child and can_break_upper_beehive", + "ZD In Front of King Zora Beehive 1": "can_break_upper_beehive_child", + "ZD In Front of King Zora Beehive 2": "can_break_upper_beehive_child", "ZD GS Frozen Waterfall": " is_adult and at_night and (Hookshot or Bow or Magic_Meter or logic_domain_gs)", @@ -2259,7 +2259,7 @@ "scene": "Zoras Domain", "hint": "ZORAS_DOMAIN", "locations": { - "ZD Behind King Zora Beehive": "is_child and can_break_upper_beehive" + "ZD Behind King Zora Beehive": "can_break_upper_beehive_child" }, "exits": { "Zoras Domain": " From 2c8dded52f31485f6d9e9876a07dd667ddc38577 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Mon, 10 Mar 2025 21:13:49 -0500 Subject: [PATCH 0199/1218] The Messenger: Fix some transition plando issues (#4720) * don't allow one-way and two-way entrances to be connected to each other * add special handling for the tower hq nodes since they share the same parent region --- worlds/messenger/options.py | 6 ++++++ worlds/messenger/transitions.py | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/worlds/messenger/options.py b/worlds/messenger/options.py index 9ee04d26a6d8..85c746aae7fb 100644 --- a/worlds/messenger/options.py +++ b/worlds/messenger/options.py @@ -51,6 +51,12 @@ class TransitionPlando(PlandoConnections): entrances = frozenset(RANDOMIZED_CONNECTIONS.keys()) exits = frozenset(RANDOMIZED_CONNECTIONS.values()) + @classmethod + def can_connect(cls, entrance: str, exit: str) -> bool: + if entrance != "Glacial Peak - Left" and entrance.lower() in cls.exits: + return exit.lower() in cls.entrances + return exit.lower() not in cls.entrances + class Logic(Choice): """ diff --git a/worlds/messenger/transitions.py b/worlds/messenger/transitions.py index 1db975b3cd3f..53cfd836d5ce 100644 --- a/worlds/messenger/transitions.py +++ b/worlds/messenger/transitions.py @@ -30,10 +30,19 @@ def remove_dangling_entrance(region: Region) -> None: for plando_connection in plando_connections: # get the connecting regions - reg1 = world.get_region(plando_connection.entrance) + # need to handle these special because the names are unique but have the same parent region + if plando_connection.entrance in ("Artificer", "Tower HQ"): + reg1 = world.get_region("Tower HQ") + if plando_connection.entrance == "Artificer": + dangling_exit = world.get_entrance("Artificer's Portal") + else: + dangling_exit = world.get_entrance("Artificer's Challenge") + reg1.exits.remove(dangling_exit) + else: + reg1 = world.get_region(plando_connection.entrance) + remove_dangling_exit(reg1) + reg2 = world.get_region(plando_connection.exit) - - remove_dangling_exit(reg1) remove_dangling_entrance(reg2) # connect the regions reg1.connect(reg2) From 3192799bbf65259d8cdca73112081d13f1c491f3 Mon Sep 17 00:00:00 2001 From: LiquidCat64 <74896918+LiquidCat64@users.noreply.github.com> Date: Wed, 12 Mar 2025 17:21:09 -0600 Subject: [PATCH 0200/1218] CVCotM: Clarify the Wii U VC version is unsupported (#4734) * Comment out VC ROM hash usages and clarify that it's unsupported. * Update worlds/cvcotm/docs/en_Castlevania - Circle of the Moon.md Co-authored-by: Scipio Wright * Update worlds/cvcotm/docs/setup_en.md Co-authored-by: Scipio Wright --------- Co-authored-by: Scipio Wright --- worlds/cvcotm/__init__.py | 7 ++++--- .../docs/en_Castlevania - Circle of the Moon.md | 7 +++---- worlds/cvcotm/docs/setup_en.md | 2 +- worlds/cvcotm/rom.py | 12 ++++++------ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/worlds/cvcotm/__init__.py b/worlds/cvcotm/__init__.py index 4466ed79bdd2..0f5077e7098a 100644 --- a/worlds/cvcotm/__init__.py +++ b/worlds/cvcotm/__init__.py @@ -19,8 +19,8 @@ from .aesthetics import shuffle_sub_weapons, get_location_data, get_countdown_flags, populate_enemy_drops, \ get_start_inventory_data -from .rom import RomData, patch_rom, get_base_rom_path, CVCotMProcedurePatch, CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH, \ - CVCOTM_VC_US_HASH +from .rom import RomData, patch_rom, get_base_rom_path, CVCotMProcedurePatch, CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH + # CVCOTM_VC_US_HASH from .client import CastlevaniaCotMClient @@ -29,7 +29,8 @@ class RomFile(settings.UserFilePath): """File name of the Castlevania CotM US rom""" copy_to = "Castlevania - Circle of the Moon (USA).gba" description = "Castlevania CotM (US) ROM File" - md5s = [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH, CVCOTM_VC_US_HASH] + # md5s = [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH, CVCOTM_VC_US_HASH] + md5s = [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH] rom_file: RomFile = RomFile(RomFile.copy_to) diff --git a/worlds/cvcotm/docs/en_Castlevania - Circle of the Moon.md b/worlds/cvcotm/docs/en_Castlevania - Circle of the Moon.md index e81b79bf2048..695c5f0ff9c8 100644 --- a/worlds/cvcotm/docs/en_Castlevania - Circle of the Moon.md +++ b/worlds/cvcotm/docs/en_Castlevania - Circle of the Moon.md @@ -153,11 +153,10 @@ Advance Collection ROM; most notably the fact that the audio does not function w which is currently a requirement to connect to a multiworld. This happens because all audio code was stripped from the ROM, and all sound is instead played by the collection through external means. -For this reason, it is most recommended to obtain the ROM by dumping it from an original cartridge of the game that you legally own. -Though, the Advance Collection *can* still technically be an option if you cannot do that and don't mind the lack of sound. +The Wii U Virtual Console version does not work due to changes in the code in that version. -The Wii U Virtual Console version is currently untested. If you happen to have purchased it before the Wii U eShop shut down, you can try -dumping and playing with it. However, at the moment, we cannot guarantee that it will work well due to it being untested. +Due to the reasons mentioned above, it is most recommended to obtain the ROM by dumping it from an original cartridge of the +game that you legally own. However, the Advance Collection *is* an option if you cannot do that and don't mind the lack of sound. Regardless of which released ROM you intend to try playing with, the US version of the game is required. diff --git a/worlds/cvcotm/docs/setup_en.md b/worlds/cvcotm/docs/setup_en.md index 7899ac997366..459e0d6afb97 100644 --- a/worlds/cvcotm/docs/setup_en.md +++ b/worlds/cvcotm/docs/setup_en.md @@ -4,7 +4,7 @@ - [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases/latest). - A Castlevania: Circle of the Moon ROM of the US version specifically. The Archipelago community cannot provide this. -The Castlevania Advance Collection ROM can technically be used, but it has no audio. The Wii U Virtual Console ROM is untested. +The Castlevania Advance Collection ROM can be used, but it has no audio. The Wii U Virtual Console ROM does not work. - [BizHawk](https://tasvideos.org/BizHawk/ReleaseHistory) 2.7 or later. ### Configuring BizHawk diff --git a/worlds/cvcotm/rom.py b/worlds/cvcotm/rom.py index e7b0710d134e..6ae0b6e43863 100644 --- a/worlds/cvcotm/rom.py +++ b/worlds/cvcotm/rom.py @@ -22,11 +22,9 @@ CVCOTM_CT_US_HASH = "50a1089600603a94e15ecf287f8d5a1f" # Original GBA cartridge ROM CVCOTM_AC_US_HASH = "87a1bd6577b6702f97a60fc55772ad74" # Castlevania Advance Collection ROM -CVCOTM_VC_US_HASH = "2cc38305f62b337281663bad8c901cf9" # Wii U Virtual Console ROM +# CVCOTM_VC_US_HASH = "2cc38305f62b337281663bad8c901cf9" # Wii U Virtual Console ROM -# NOTE: The Wii U VC version is untested as of when this comment was written. I am only including its hash in case it -# does work. If someone who has it can confirm it does indeed work, this comment should be removed. If it doesn't, the -# hash should be removed in addition. See the Game Page for more information about supported versions. +# The Wii U VC version is not currently supported. See the Game Page for more info. ARCHIPELAGO_IDENTIFIER_START = 0x7FFF00 ARCHIPELAGO_IDENTIFIER = "ARCHIPELAG03" @@ -518,7 +516,8 @@ def fix_item_positions(caller: APProcedurePatch, rom: bytes) -> bytes: class CVCotMProcedurePatch(APProcedurePatch, APTokenMixin): - hash = [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH, CVCOTM_VC_US_HASH] + # hash = [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH, CVCOTM_VC_US_HASH] + hash = [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH] patch_file_ending: str = ".apcvcotm" result_file_ending: str = ".gba" @@ -585,7 +584,8 @@ def get_base_rom_bytes(file_name: str = "") -> bytes: basemd5 = hashlib.md5() basemd5.update(base_rom_bytes) - if basemd5.hexdigest() not in [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH, CVCOTM_VC_US_HASH]: + # if basemd5.hexdigest() not in [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH, CVCOTM_VC_US_HASH]: + if basemd5.hexdigest() not in [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH]: raise Exception("Supplied Base ROM does not match known MD5s for Castlevania: Circle of the Moon USA." "Get the correct game and version, then dump it.") setattr(get_base_rom_bytes, "base_rom_bytes", base_rom_bytes) From 1de411ec894e5667ea4d850e1949f9f79822e909 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Thu, 13 Mar 2025 23:59:09 +0100 Subject: [PATCH 0201/1218] The Witness: Change Regions, Areas and Connections from Dict[str, Any] to dataclasses&NamedTuples (#4415) * Change Regions, Areas and Connections to dataclasses/NamedTuples * Move to new file * we do a little renaming * Purge the 'lambda' naming in favor of 'rule' or 'WitnessRule' * missed one * unnecessary change * omega oops * NOOOOOOOO * Merge error * mypy thing --- worlds/witness/data/definition_classes.py | 33 +++++++ worlds/witness/data/static_locations.py | 2 +- worlds/witness/data/static_logic.py | 109 +++++++++++----------- worlds/witness/data/utils.py | 46 ++++----- worlds/witness/entity_hunt.py | 2 +- worlds/witness/generate_data_file.py | 2 +- worlds/witness/hints.py | 12 +-- worlds/witness/options.py | 1 - worlds/witness/player_logic.py | 59 ++++++------ worlds/witness/regions.py | 9 +- worlds/witness/rules.py | 2 +- 11 files changed, 150 insertions(+), 127 deletions(-) create mode 100644 worlds/witness/data/definition_classes.py diff --git a/worlds/witness/data/definition_classes.py b/worlds/witness/data/definition_classes.py new file mode 100644 index 000000000000..281fbfcdffd0 --- /dev/null +++ b/worlds/witness/data/definition_classes.py @@ -0,0 +1,33 @@ +from dataclasses import dataclass, field +from typing import FrozenSet, List, NamedTuple + +# A WitnessRule is just an or-chain of and-conditions. +# It represents the set of all options that could fulfill this requirement. +# E.g. if something requires "Dots or (Shapers and Stars)", it'd be represented as: {{"Dots"}, {"Shapers, "Stars"}} +# {} is an unusable requirement. +# {{}} is an always usable requirement. +WitnessRule = FrozenSet[FrozenSet[str]] + + +@dataclass +class AreaDefinition: + name: str + regions: List[str] = field(default_factory=list) + + +@dataclass +class RegionDefinition: + name: str + short_name: str + area: AreaDefinition + logical_entities: List[str] = field(default_factory=list) + physical_entities: List[str] = field(default_factory=list) + + +class ConnectionDefinition(NamedTuple): + target_region: str + traversal_rule: WitnessRule + + @property + def can_be_traversed(self) -> bool: + return bool(self.traversal_rule) diff --git a/worlds/witness/data/static_locations.py b/worlds/witness/data/static_locations.py index 5c5ad554ddab..a5cfc3b49f59 100644 --- a/worlds/witness/data/static_locations.py +++ b/worlds/witness/data/static_locations.py @@ -486,5 +486,5 @@ def get_event_name(entity_hex: str) -> str: ALL_LOCATIONS_TO_ID[key] = item for loc in ALL_LOCATIONS_TO_IDS: - area = static_witness_logic.ENTITIES_BY_NAME[loc]["area"]["name"] + area = static_witness_logic.ENTITIES_BY_NAME[loc]["area"].name AREA_LOCATION_GROUPS.setdefault(area, set()).add(loc) diff --git a/worlds/witness/data/static_logic.py b/worlds/witness/data/static_logic.py index 4f4786a38b9a..bfe92467fb61 100644 --- a/worlds/witness/data/static_logic.py +++ b/worlds/witness/data/static_logic.py @@ -1,8 +1,9 @@ from collections import Counter, defaultdict -from typing import Any, Dict, List, Optional, Set, Tuple +from typing import Any, Dict, FrozenSet, List, Optional, Set from Utils import cache_argsless +from .definition_classes import AreaDefinition, ConnectionDefinition, RegionDefinition, WitnessRule from .item_definition_classes import ( CATEGORY_NAME_MAPPINGS, DoorItemDefinition, @@ -13,7 +14,6 @@ ) from .settings.easter_eggs import EASTER_EGGS from .utils import ( - WitnessRule, define_new_region, get_items, get_sigma_expert_logic, @@ -21,7 +21,7 @@ get_umbra_variety_logic, get_vanilla_logic, logical_or_witness_rules, - parse_lambda, + parse_witness_rule, ) @@ -31,10 +31,10 @@ def __init__(self, lines: Optional[List[str]] = None) -> None: lines = get_sigma_normal_logic() # All regions with a list of panels in them and the connections to other regions, before logic adjustments - self.ALL_REGIONS_BY_NAME: Dict[str, Dict[str, Any]] = {} - self.ALL_AREAS_BY_NAME: Dict[str, Dict[str, Any]] = {} - self.CONNECTIONS_WITH_DUPLICATES: Dict[str, Dict[str, Set[WitnessRule]]] = defaultdict(lambda: defaultdict(set)) - self.STATIC_CONNECTIONS_BY_REGION_NAME: Dict[str, Set[Tuple[str, WitnessRule]]] = {} + self.ALL_REGIONS_BY_NAME: Dict[str, RegionDefinition] = {} + self.ALL_AREAS_BY_NAME: Dict[str, AreaDefinition] = {} + self.CONNECTIONS_WITH_DUPLICATES: Dict[str, List[ConnectionDefinition]] = defaultdict(list) + self.STATIC_CONNECTIONS_BY_REGION_NAME: Dict[str, List[ConnectionDefinition]] = {} self.ENTITIES_BY_HEX: Dict[str, Dict[str, Any]] = {} self.ENTITIES_BY_NAME: Dict[str, Dict[str, Any]] = {} @@ -55,15 +55,15 @@ def add_easter_eggs(self) -> None: area_counts: Dict[str, int] = Counter() for region_name, entity_amount in EASTER_EGGS.items(): region_object = self.ALL_REGIONS_BY_NAME[region_name] - correct_area = region_object["area"] + correct_area = region_object.area for _ in range(entity_amount): location_id = 160200 + egg_counter entity_hex = hex(0xEE000 + egg_counter) egg_counter += 1 - area_counts[correct_area["name"]] += 1 - full_entity_name = f"{correct_area['name']} Easter Egg {area_counts[correct_area['name']]}" + area_counts[correct_area.name] += 1 + full_entity_name = f"{correct_area.name} Easter Egg {area_counts[correct_area.name]}" self.ENTITIES_BY_HEX[entity_hex] = { "checkName": full_entity_name, @@ -81,11 +81,11 @@ def add_easter_eggs(self) -> None: self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[entity_hex] = { "entities": frozenset({frozenset({})}) } - region_object["entities"].append(entity_hex) - region_object["physical_entities"].append(entity_hex) + region_object.logical_entities.append(entity_hex) + region_object.physical_entities.append(entity_hex) easter_egg_region = self.ALL_REGIONS_BY_NAME["Easter Eggs"] - easter_egg_area = easter_egg_region["area"] + easter_egg_area = easter_egg_region.area for i in range(sum(EASTER_EGGS.values())): location_id = 160000 + i entity_hex = hex(0xEE200 + i) @@ -111,19 +111,15 @@ def add_easter_eggs(self) -> None: self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[entity_hex] = { "entities": frozenset({frozenset({})}) } - easter_egg_region["entities"].append(entity_hex) - easter_egg_region["physical_entities"].append(entity_hex) + easter_egg_region.logical_entities.append(entity_hex) + easter_egg_region.physical_entities.append(entity_hex) def read_logic_file(self, lines: List[str]) -> None: """ Reads the logic file and does the initial population of data structures """ - - current_region = {} - current_area: Dict[str, Any] = { - "name": "Misc", - "regions": [], - } + current_area = AreaDefinition("Misc") + current_region = RegionDefinition("Fake", "Fake", current_area) # Unused, but makes PyCharm & mypy shut up self.ALL_AREAS_BY_NAME["Misc"] = current_area for line in lines: @@ -133,19 +129,16 @@ def read_logic_file(self, lines: List[str]) -> None: if line[-1] == ":": new_region_and_connections = define_new_region(line, current_area) current_region = new_region_and_connections[0] - region_name = current_region["name"] + region_name = current_region.name self.ALL_REGIONS_BY_NAME[region_name] = current_region for connection in new_region_and_connections[1]: - self.CONNECTIONS_WITH_DUPLICATES[region_name][connection[0]].add(connection[1]) - current_area["regions"].append(region_name) + self.CONNECTIONS_WITH_DUPLICATES[region_name].append(connection) + current_area.regions.append(region_name) continue if line[0] == "=": area_name = line[2:-2] - current_area = { - "name": area_name, - "regions": [], - } + current_area = AreaDefinition(area_name, []) self.ALL_AREAS_BY_NAME[area_name] = current_area continue @@ -158,9 +151,9 @@ def read_logic_file(self, lines: List[str]) -> None: entity_hex = entity_name_full[0:7] entity_name = entity_name_full[9:-1] - required_panel_lambda = line_split.pop(0) + entity_requirement_string = line_split.pop(0) - full_entity_name = current_region["shortName"] + " " + entity_name + full_entity_name = current_region.short_name + " " + entity_name if location_id == "Door" or location_id == "Laser": self.ENTITIES_BY_HEX[entity_hex] = { @@ -177,18 +170,18 @@ def read_logic_file(self, lines: List[str]) -> None: self.ENTITIES_BY_NAME[self.ENTITIES_BY_HEX[entity_hex]["checkName"]] = self.ENTITIES_BY_HEX[entity_hex] self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[entity_hex] = { - "entities": parse_lambda(required_panel_lambda) + "entities": parse_witness_rule(entity_requirement_string) } # Lasers and Doors exist in a region, but don't have a regional *requirement* # If a laser is activated, you don't need to physically walk up to it for it to count # As such, logically, they behave more as if they were part of the "Entry" region - self.ALL_REGIONS_BY_NAME["Entry"]["entities"].append(entity_hex) + self.ALL_REGIONS_BY_NAME["Entry"].logical_entities.append(entity_hex) # However, it will also be important to keep track of their physical location for postgame purposes. - current_region["physical_entities"].append(entity_hex) + current_region.physical_entities.append(entity_hex) continue - required_item_lambda = line_split.pop(0) + item_requirement_string = line_split.pop(0) laser_names = { "Laser", @@ -224,18 +217,18 @@ def read_logic_file(self, lines: List[str]) -> None: entity_type = "Panel" location_type = "General" - required_items = parse_lambda(required_item_lambda) - required_panels = parse_lambda(required_panel_lambda) + required_items = parse_witness_rule(item_requirement_string) + required_entities = parse_witness_rule(entity_requirement_string) required_items = frozenset(required_items) requirement = { - "entities": required_panels, + "entities": required_entities, "items": required_items } if entity_type == "Obelisk Side": - eps = set(next(iter(required_panels))) + eps = set(next(iter(required_entities))) eps -= {"Theater to Tunnels"} eps_ints = {int(h, 16) for h in eps} @@ -260,39 +253,43 @@ def read_logic_file(self, lines: List[str]) -> None: self.ENTITIES_BY_NAME[self.ENTITIES_BY_HEX[entity_hex]["checkName"]] = self.ENTITIES_BY_HEX[entity_hex] self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[entity_hex] = requirement - current_region["entities"].append(entity_hex) - current_region["physical_entities"].append(entity_hex) + current_region.logical_entities.append(entity_hex) + current_region.physical_entities.append(entity_hex) self.add_easter_eggs() - def reverse_connection(self, source_region: str, connection: Tuple[str, Set[WitnessRule]]) -> None: - target = connection[0] - traversal_options = connection[1] - + def reverse_connection(self, source_region: str, connection: ConnectionDefinition) -> None: # Reverse this connection with all its possibilities, except the ones marked as "OneWay". - for requirement in traversal_options: - remaining_options = set() - for option in requirement: - if not any(req == "TrueOneWay" for req in option): - remaining_options.add(option) + remaining_options: Set[FrozenSet[str]] = set() + for sub_option in connection.traversal_rule: + if not any(req == "TrueOneWay" for req in sub_option): + remaining_options.add(sub_option) - if remaining_options: - self.CONNECTIONS_WITH_DUPLICATES[target][source_region].add(frozenset(remaining_options)) + reversed_connection = ConnectionDefinition(source_region, frozenset(remaining_options)) + if reversed_connection.can_be_traversed: + self.CONNECTIONS_WITH_DUPLICATES[connection.target_region].append(reversed_connection) def reverse_connections(self) -> None: # Iterate all connections for region_name, connections in list(self.CONNECTIONS_WITH_DUPLICATES.items()): - for connection in connections.items(): + for connection in connections: self.reverse_connection(region_name, connection) def combine_connections(self) -> None: # All regions need to be present, and this dict is copied later - Thus, defaultdict is not the correct choice. - self.STATIC_CONNECTIONS_BY_REGION_NAME = {region_name: set() for region_name in self.ALL_REGIONS_BY_NAME} + self.STATIC_CONNECTIONS_BY_REGION_NAME = {region_name: [] for region_name in self.ALL_REGIONS_BY_NAME} for source, connections in self.CONNECTIONS_WITH_DUPLICATES.items(): - for target, requirement in connections.items(): - combined_req = logical_or_witness_rules(requirement) - self.STATIC_CONNECTIONS_BY_REGION_NAME[source].add((target, combined_req)) + # Organize rules by target region + traversal_options_by_target_region = defaultdict(list) + for target_region, traversal_option in connections: + traversal_options_by_target_region[target_region].append(traversal_option) + + # Combine connections to the same target region into one connection + for target, traversal_rules in traversal_options_by_target_region.items(): + combined_rule = logical_or_witness_rules(traversal_rules) + combined_connection = ConnectionDefinition(target, combined_rule) + self.STATIC_CONNECTIONS_BY_REGION_NAME[source].append(combined_connection) # Item data parsed from WitnessItems.txt diff --git a/worlds/witness/data/utils.py b/worlds/witness/data/utils.py index aca457380664..5f5622819db5 100644 --- a/worlds/witness/data/utils.py +++ b/worlds/witness/data/utils.py @@ -2,16 +2,11 @@ from math import floor from pkgutil import get_data from random import Random -from typing import Any, Collection, Dict, FrozenSet, Iterable, List, Optional, Set, Tuple, TypeVar +from typing import Collection, FrozenSet, Iterable, List, Optional, Set, Tuple, TypeVar -T = TypeVar("T") +from .definition_classes import AreaDefinition, ConnectionDefinition, RegionDefinition, WitnessRule -# A WitnessRule is just an or-chain of and-conditions. -# It represents the set of all options that could fulfill this requirement. -# E.g. if something requires "Dots or (Shapers and Stars)", it'd be represented as: {{"Dots"}, {"Shapers, "Stars"}} -# {} is an unusable requirement. -# {{}} is an always usable requirement. -WitnessRule = FrozenSet[FrozenSet[str]] +T = TypeVar("T") def cast_not_none(value: Optional[T]) -> T: @@ -62,7 +57,7 @@ def build_weighted_int_list(inputs: Collection[float], total: int) -> List[int]: return rounded_output -def define_new_region(region_string: str, area: dict[str, Any]) -> Tuple[Dict[str, Any], Set[Tuple[str, WitnessRule]]]: +def define_new_region(region_string: str, area: AreaDefinition) -> Tuple[RegionDefinition, List[ConnectionDefinition]]: """ Returns a region object by parsing a line in the logic file """ @@ -77,35 +72,28 @@ def define_new_region(region_string: str, area: dict[str, Any]) -> Tuple[Dict[st region_name = region_name_split[0] region_name_simple = region_name_split[1][:-1] - options = set() + options = [] for _ in range(len(line_split) // 2): connected_region = line_split.pop(0) - corresponding_lambda = line_split.pop(0) - - options.add( - (connected_region, parse_lambda(corresponding_lambda)) - ) - - region_obj = { - "name": region_name, - "shortName": region_name_simple, - "entities": [], - "physical_entities": [], - "area": area, - } + traversal_rule_string = line_split.pop(0) + + options.append(ConnectionDefinition(connected_region, parse_witness_rule(traversal_rule_string))) + + region_obj = RegionDefinition(region_name, region_name_simple, area) + return region_obj, options -def parse_lambda(lambda_string: str) -> WitnessRule: +def parse_witness_rule(rule_string: str) -> WitnessRule: """ - Turns a lambda String literal like this: a | b & c - into a set of sets like this: {{a}, {b, c}} - The lambda has to be in DNF. + Turns a rule string literal like this: a | b & c + into a set of sets (called "WitnessRule") like this: {{a}, {b, c}} + The rule string has to be in DNF. """ - if lambda_string == "True": + if rule_string == "True": return frozenset([frozenset()]) - split_ands = set(lambda_string.split(" | ")) + split_ands = set(rule_string.split(" | ")) return frozenset({frozenset(a.split(" & ")) for a in split_ands}) diff --git a/worlds/witness/entity_hunt.py b/worlds/witness/entity_hunt.py index 9549246ce479..de2f7dd68d62 100644 --- a/worlds/witness/entity_hunt.py +++ b/worlds/witness/entity_hunt.py @@ -129,7 +129,7 @@ def _get_eligible_panels(self) -> Tuple[List[str], Dict[str, Set[str]]]: eligible_panels_by_area = defaultdict(set) for eligible_panel in all_eligible_panels: - associated_area = static_witness_logic.ENTITIES_BY_HEX[eligible_panel]["area"]["name"] + associated_area = static_witness_logic.ENTITIES_BY_HEX[eligible_panel]["area"].name eligible_panels_by_area[associated_area].add(eligible_panel) return all_eligible_panels, eligible_panels_by_area diff --git a/worlds/witness/generate_data_file.py b/worlds/witness/generate_data_file.py index cc05015cd810..679aa80b289c 100644 --- a/worlds/witness/generate_data_file.py +++ b/worlds/witness/generate_data_file.py @@ -18,7 +18,7 @@ for entity_id, entity_object in static_witness_logic.ENTITIES_BY_HEX.items(): location_id = entity_object["id"] - area = entity_object["area"]["name"] + area = entity_object["area"].name area_to_entity_ids[area].append(entity_id) if location_id is None: diff --git a/worlds/witness/hints.py b/worlds/witness/hints.py index 6f274f5e2c6b..c82024cc1217 100644 --- a/worlds/witness/hints.py +++ b/worlds/witness/hints.py @@ -464,7 +464,7 @@ def choose_areas(world: "WitnessWorld", amount: int, locations_per_area: Dict[st def get_hintable_areas(world: "WitnessWorld") -> Tuple[Dict[str, List[Location]], Dict[str, List[Item]]]: - potential_areas = list(static_witness_logic.ALL_AREAS_BY_NAME.keys()) + potential_areas = list(static_witness_logic.ALL_AREAS_BY_NAME.values()) locations_per_area = {} items_per_area = {} @@ -472,14 +472,14 @@ def get_hintable_areas(world: "WitnessWorld") -> Tuple[Dict[str, List[Location]] for area in potential_areas: regions = [ world.get_region(region) - for region in static_witness_logic.ALL_AREAS_BY_NAME[area]["regions"] + for region in area.regions if region in world.player_regions.created_region_names ] locations = [location for region in regions for location in region.get_locations() if not location.is_event] if locations: - locations_per_area[area] = locations - items_per_area[area] = [location.item for location in locations] + locations_per_area[area.name] = locations + items_per_area[area.name] = [location.item for location in locations] return locations_per_area, items_per_area @@ -516,7 +516,7 @@ def word_area_hint(world: "WitnessWorld", hinted_area: str, area_items: List[Ite hunt_panels = None if world.options.victory_condition == "panel_hunt" and hinted_area != "Easter Eggs": hunt_panels = sum( - static_witness_logic.ENTITIES_BY_HEX[hunt_entity]["area"]["name"] == hinted_area + static_witness_logic.ENTITIES_BY_HEX[hunt_entity]["area"].name == hinted_area for hunt_entity in world.player_logic.HUNT_ENTITIES ) @@ -620,7 +620,7 @@ def create_all_hints(world: "WitnessWorld", hint_amount: int, area_hints: int, already_hinted_locations |= { loc for loc in world.multiworld.get_reachable_locations(state, world.player) - if loc.address and static_witness_logic.ENTITIES_BY_NAME[loc.name]["area"]["name"] == "Tutorial (Inside)" + if loc.address and static_witness_logic.ENTITIES_BY_NAME[loc.name]["area"].name == "Tutorial (Inside)" } intended_location_hints = hint_amount - area_hints diff --git a/worlds/witness/options.py b/worlds/witness/options.py index c56209b226a4..1c2bc9324fa0 100644 --- a/worlds/witness/options.py +++ b/worlds/witness/options.py @@ -1,5 +1,4 @@ from dataclasses import dataclass -from datetime import datetime from typing import Tuple from schema import And, Schema diff --git a/worlds/witness/player_logic.py b/worlds/witness/player_logic.py index 1276d55dce76..52bddde17ee4 100644 --- a/worlds/witness/player_logic.py +++ b/worlds/witness/player_logic.py @@ -20,10 +20,10 @@ from typing import TYPE_CHECKING, Dict, List, Set, Tuple, cast from .data import static_logic as static_witness_logic +from .data.definition_classes import ConnectionDefinition, WitnessRule from .data.item_definition_classes import DoorItemDefinition, ItemCategory, ProgressiveItemDefinition from .data.static_logic import StaticWitnessLogicObj from .data.utils import ( - WitnessRule, get_boat, get_caves_except_path_to_challenge_exclusion_list, get_complex_additional_panels, @@ -47,7 +47,7 @@ get_vault_exclusion_list, logical_and_witness_rules, logical_or_witness_rules, - parse_lambda, + parse_witness_rule, ) from .entity_hunt import EntityHuntPicker @@ -97,10 +97,10 @@ def __init__(self, world: "WitnessWorld", disabled_locations: Set[str], start_in elif self.DIFFICULTY == "none": self.REFERENCE_LOGIC = static_witness_logic.vanilla - self.CONNECTIONS_BY_REGION_NAME_THEORETICAL: Dict[str, Set[Tuple[str, WitnessRule]]] = copy.deepcopy( + self.CONNECTIONS_BY_REGION_NAME_THEORETICAL: Dict[str, List[ConnectionDefinition]] = copy.deepcopy( self.REFERENCE_LOGIC.STATIC_CONNECTIONS_BY_REGION_NAME ) - self.CONNECTIONS_BY_REGION_NAME: Dict[str, Set[Tuple[str, WitnessRule]]] = copy.deepcopy( + self.CONNECTIONS_BY_REGION_NAME: Dict[str, List[ConnectionDefinition]] = copy.deepcopy( self.REFERENCE_LOGIC.STATIC_CONNECTIONS_BY_REGION_NAME ) self.DEPENDENT_REQUIREMENTS_BY_HEX: Dict[str, Dict[str, WitnessRule]] = copy.deepcopy( @@ -178,7 +178,7 @@ def reduce_req_within_region(self, entity_hex: str) -> WitnessRule: entity_obj = self.REFERENCE_LOGIC.ENTITIES_BY_HEX[entity_hex] - if entity_obj["region"] is not None and entity_obj["region"]["name"] in self.UNREACHABLE_REGIONS: + if entity_obj["region"] is not None and entity_obj["region"].name in self.UNREACHABLE_REGIONS: return frozenset() # For the requirement of an entity, we consider two things: @@ -270,7 +270,7 @@ def reduce_req_within_region(self, entity_hex: str) -> WitnessRule: new_items = theoretical_new_items if dep_obj["region"] and entity_obj["region"] != dep_obj["region"]: new_items = frozenset( - frozenset(possibility | {dep_obj["region"]["name"]}) + frozenset(possibility | {dep_obj["region"].name}) for possibility in new_items ) @@ -359,11 +359,11 @@ def make_single_adjustment(self, adj_type: str, line: str) -> None: line_split = line.split(" - ") requirement = { - "entities": parse_lambda(line_split[1]), + "entities": parse_witness_rule(line_split[1]), } if len(line_split) > 2: - required_items = parse_lambda(line_split[2]) + required_items = parse_witness_rule(line_split[2]) items_actually_in_the_game = [ item_name for item_name, item_definition in static_witness_logic.ALL_ITEMS.items() if item_definition.category is ItemCategory.SYMBOL @@ -394,26 +394,31 @@ def make_single_adjustment(self, adj_type: str, line: str) -> None: return if adj_type == "New Connections": + # This adjustment type does not actually reverse the connection if it could be reversed. + # If needed, this might be added later line_split = line.split(" - ") source_region = line_split[0] target_region = line_split[1] panel_set_string = line_split[2] for connection in self.CONNECTIONS_BY_REGION_NAME_THEORETICAL[source_region]: - if connection[0] == target_region: + if connection.target_region == target_region: self.CONNECTIONS_BY_REGION_NAME_THEORETICAL[source_region].remove(connection) if panel_set_string == "TrueOneWay": - self.CONNECTIONS_BY_REGION_NAME_THEORETICAL[source_region].add( - (target_region, frozenset({frozenset(["TrueOneWay"])})) - ) + # This means the connection can be completely replaced + only_connection = ConnectionDefinition(target_region, frozenset({frozenset(["TrueOneWay"])})) + self.CONNECTIONS_BY_REGION_NAME_THEORETICAL[source_region].append(only_connection) else: - new_lambda = logical_or_witness_rules([connection[1], parse_lambda(panel_set_string)]) - self.CONNECTIONS_BY_REGION_NAME_THEORETICAL[source_region].add((target_region, new_lambda)) + combined_rule = logical_or_witness_rules( + [connection.traversal_rule, parse_witness_rule(panel_set_string)] + ) + combined_connection = ConnectionDefinition(target_region, combined_rule) + self.CONNECTIONS_BY_REGION_NAME_THEORETICAL[source_region].append(combined_connection) break else: - new_conn = (target_region, parse_lambda(panel_set_string)) - self.CONNECTIONS_BY_REGION_NAME_THEORETICAL[source_region].add(new_conn) + new_connection = ConnectionDefinition(target_region, parse_witness_rule(panel_set_string)) + self.CONNECTIONS_BY_REGION_NAME_THEORETICAL[source_region].append(new_connection) if adj_type == "Added Locations": if "0x" in line: @@ -558,7 +563,7 @@ def finalize_easter_eggs(self, world: "WitnessWorld") -> None: self.AVAILABLE_EASTER_EGGS_PER_REGION = defaultdict(int) for entity_hex in self.AVAILABLE_EASTER_EGGS: - region_name = static_witness_logic.ENTITIES_BY_HEX[entity_hex]["region"]["name"] + region_name = static_witness_logic.ENTITIES_BY_HEX[entity_hex]["region"].name self.AVAILABLE_EASTER_EGGS_PER_REGION[region_name] += 1 eggs_per_check, logically_required_eggs_per_check = world.options.easter_egg_hunt.get_step_and_logical_step() @@ -796,7 +801,7 @@ def discover_reachable_regions(self) -> Set[str]: next_region = regions_to_check.pop() for region_exit in self.CONNECTIONS_BY_REGION_NAME[next_region]: - target = region_exit[0] + target = region_exit.target_region if target in reachable_regions: continue @@ -844,7 +849,7 @@ def find_unsolvable_entities(self, world: "WitnessWorld") -> None: # First, entities in unreachable regions are obviously themselves unreachable. for region in new_unreachable_regions: - for entity in static_witness_logic.ALL_REGIONS_BY_NAME[region]["physical_entities"]: + for entity in static_witness_logic.ALL_REGIONS_BY_NAME[region].physical_entities: # Never disable the Victory Location. if entity == self.VICTORY_LOCATION: continue @@ -879,11 +884,11 @@ def find_unsolvable_entities(self, world: "WitnessWorld") -> None: if not new_unreachable_regions and not newly_discovered_disabled_entities: return - def reduce_connection_requirement(self, connection: Tuple[str, WitnessRule]) -> WitnessRule: + def reduce_connection_requirement(self, connection: ConnectionDefinition) -> ConnectionDefinition: all_possibilities = [] # Check each traversal option individually - for option in connection[1]: + for option in connection.traversal_rule: individual_entity_requirements: List[WitnessRule] = [] for entity in option: # If a connection requires solving a disabled entity, it is not valid. @@ -901,7 +906,7 @@ def reduce_connection_requirement(self, connection: Tuple[str, WitnessRule]) -> entity_req = self.get_entity_requirement(entity) if self.REFERENCE_LOGIC.ENTITIES_BY_HEX[entity]["region"]: - region_name = self.REFERENCE_LOGIC.ENTITIES_BY_HEX[entity]["region"]["name"] + region_name = self.REFERENCE_LOGIC.ENTITIES_BY_HEX[entity]["region"].name entity_req = logical_and_witness_rules([entity_req, frozenset({frozenset({region_name})})]) individual_entity_requirements.append(entity_req) @@ -909,7 +914,7 @@ def reduce_connection_requirement(self, connection: Tuple[str, WitnessRule]) -> # Merge all possible requirements into one DNF condition. all_possibilities.append(logical_and_witness_rules(individual_entity_requirements)) - return logical_or_witness_rules(all_possibilities) + return ConnectionDefinition(connection.target_region, logical_or_witness_rules(all_possibilities)) def make_dependency_reduced_checklist(self) -> None: """ @@ -942,14 +947,14 @@ def make_dependency_reduced_checklist(self) -> None: # Make independent region connection requirements based on the entities they require for region, connections in self.CONNECTIONS_BY_REGION_NAME_THEORETICAL.items(): - new_connections = set() + new_connections = [] for connection in connections: - overall_requirement = self.reduce_connection_requirement(connection) + reduced_connection = self.reduce_connection_requirement(connection) # If there is a way to use this connection, add it. - if overall_requirement: - new_connections.add((connection[0], overall_requirement)) + if reduced_connection.can_be_traversed: + new_connections.append(reduced_connection) self.CONNECTIONS_BY_REGION_NAME[region] = new_connections diff --git a/worlds/witness/regions.py b/worlds/witness/regions.py index 8cb3678ab65d..c057134adba3 100644 --- a/worlds/witness/regions.py +++ b/worlds/witness/regions.py @@ -10,8 +10,9 @@ from worlds.generic.Rules import CollectionRule from .data import static_logic as static_witness_logic +from .data.definition_classes import WitnessRule from .data.static_logic import StaticWitnessLogicObj -from .data.utils import WitnessRule, optimize_witness_rule +from .data.utils import optimize_witness_rule from .locations import WitnessPlayerLocations from .player_logic import WitnessPlayerLogic @@ -114,7 +115,7 @@ def create_regions(self, world: "WitnessWorld", player_logic: WitnessPlayerLogic if k not in player_logic.UNREACHABLE_REGIONS } - event_locations_per_region = defaultdict(dict) + event_locations_per_region: Dict[str, Dict[str, int]] = defaultdict(dict) for event_location, event_item_and_entity in player_logic.EVENT_ITEM_PAIRS.items(): entity_or_region = event_item_and_entity[1] @@ -126,13 +127,13 @@ def create_regions(self, world: "WitnessWorld", player_logic: WitnessPlayerLogic if region is None: region_name = "Entry" else: - region_name = region["name"] + region_name = region.name order = self.reference_logic.ENTITIES_BY_HEX[entity_or_region]["order"] event_locations_per_region[region_name][event_location] = order for region_name, region in regions_to_create.items(): location_entities_for_this_region = [ - self.reference_logic.ENTITIES_BY_HEX[entity] for entity in region["entities"] + self.reference_logic.ENTITIES_BY_HEX[entity] for entity in region.logical_entities ] locations_for_this_region = { entity["checkName"]: entity["order"] for entity in location_entities_for_this_region diff --git a/worlds/witness/rules.py b/worlds/witness/rules.py index 866f4690f5fd..545c3e7dd042 100644 --- a/worlds/witness/rules.py +++ b/worlds/witness/rules.py @@ -10,7 +10,7 @@ from worlds.generic.Rules import CollectionRule, set_rule from .data import static_logic as static_witness_logic -from .data.utils import WitnessRule +from .data.definition_classes import WitnessRule from .player_logic import WitnessPlayerLogic if TYPE_CHECKING: From 9b3ee018e9866dd2a35649b130da6b9e6a9041f9 Mon Sep 17 00:00:00 2001 From: Benny D <78334662+benny-dreamly@users.noreply.github.com> Date: Fri, 14 Mar 2025 01:24:37 -0600 Subject: [PATCH 0202/1218] Core/Various Worlds: Fix crash/freeze with unicode characters (#4671) replace colorama.init with just_fix_windows_console --- AdventureClient.py | 2 +- CommonClient.py | 2 +- FF1Client.py | 2 +- LinksAwakeningClient.py | 2 +- MMBN3Client.py | 2 +- MultiServer.py | 2 +- OoTClient.py | 2 +- SNIClient.py | 2 +- UndertaleClient.py | 2 +- WargrooveClient.py | 2 +- Zelda1Client.py | 2 +- worlds/_bizhawk/context.py | 2 +- worlds/ahit/Client.py | 2 +- worlds/factorio/Client.py | 2 +- worlds/kh1/Client.py | 2 +- worlds/kh2/Client.py | 2 +- worlds/sc2/Client.py | 2 +- worlds/zillion/client.py | 2 +- worlds/zork_grand_inquisitor/client.py | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/AdventureClient.py b/AdventureClient.py index 24c6a4c4fc58..91567fc0a0e9 100644 --- a/AdventureClient.py +++ b/AdventureClient.py @@ -511,7 +511,7 @@ async def main(): import colorama - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main()) colorama.deinit() diff --git a/CommonClient.py b/CommonClient.py index 33792f0ed28b..ae411838d8de 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -1128,7 +1128,7 @@ async def main(args): args = handle_url_arg(args, parser=parser) # use colorama to display colored text highlighting on windows - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main(args)) colorama.deinit() diff --git a/FF1Client.py b/FF1Client.py index b7c58e206123..748a95b72cf4 100644 --- a/FF1Client.py +++ b/FF1Client.py @@ -261,7 +261,7 @@ async def main(args): parser = get_base_parser() args = parser.parse_args() - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main(args)) colorama.deinit() diff --git a/LinksAwakeningClient.py b/LinksAwakeningClient.py index ff932e7c76fa..aac6c2f214ec 100644 --- a/LinksAwakeningClient.py +++ b/LinksAwakeningClient.py @@ -803,6 +803,6 @@ async def main(): await ctx.shutdown() if __name__ == '__main__': - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main()) colorama.deinit() diff --git a/MMBN3Client.py b/MMBN3Client.py index 140a98745c26..4945d49221c4 100644 --- a/MMBN3Client.py +++ b/MMBN3Client.py @@ -370,7 +370,7 @@ async def main(): import colorama - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main()) colorama.deinit() diff --git a/MultiServer.py b/MultiServer.py index a310808b3aec..f9ed34e2f767 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -47,7 +47,7 @@ from BaseClasses import ItemClassification min_client_version = Version(0, 1, 6) -colorama.init() +colorama.just_fix_windows_console() def remove_from_list(container, value): diff --git a/OoTClient.py b/OoTClient.py index 115490417334..6a87b9e72201 100644 --- a/OoTClient.py +++ b/OoTClient.py @@ -346,7 +346,7 @@ async def main(): import colorama - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main()) colorama.deinit() diff --git a/SNIClient.py b/SNIClient.py index 9140c73c14e2..1156bf6040fb 100644 --- a/SNIClient.py +++ b/SNIClient.py @@ -735,6 +735,6 @@ async def main() -> None: if __name__ == '__main__': - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main()) colorama.deinit() diff --git a/UndertaleClient.py b/UndertaleClient.py index dfacee148abc..1c522fac924d 100644 --- a/UndertaleClient.py +++ b/UndertaleClient.py @@ -500,7 +500,7 @@ async def _main(): import colorama - colorama.init() + colorama.just_fix_windows_console() asyncio.run(_main()) colorama.deinit() diff --git a/WargrooveClient.py b/WargrooveClient.py index f9971f7a6c05..f900e05e3fef 100644 --- a/WargrooveClient.py +++ b/WargrooveClient.py @@ -446,6 +446,6 @@ async def main(args): parser = get_base_parser(description="Wargroove Client, for text interfacing.") args, rest = parser.parse_known_args() - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main(args)) colorama.deinit() diff --git a/Zelda1Client.py b/Zelda1Client.py index 1154804fbf56..4473b3f3c7a3 100644 --- a/Zelda1Client.py +++ b/Zelda1Client.py @@ -386,7 +386,7 @@ async def main(args): parser.add_argument('diff_file', default="", type=str, nargs="?", help='Path to a Archipelago Binary Patch file') args = parser.parse_args() - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main(args)) colorama.deinit() diff --git a/worlds/_bizhawk/context.py b/worlds/_bizhawk/context.py index 21c54d30c752..c9b107664463 100644 --- a/worlds/_bizhawk/context.py +++ b/worlds/_bizhawk/context.py @@ -276,6 +276,6 @@ async def main(): Utils.init_logging("BizHawkClient", exception_logger="Client") import colorama - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main()) colorama.deinit() diff --git a/worlds/ahit/Client.py b/worlds/ahit/Client.py index cbb5f2a13d1f..0a9d8d6042a3 100644 --- a/worlds/ahit/Client.py +++ b/worlds/ahit/Client.py @@ -261,6 +261,6 @@ async def main(): # options = Utils.get_options() import colorama - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main()) colorama.deinit() diff --git a/worlds/factorio/Client.py b/worlds/factorio/Client.py index ac58339c5e14..ff1de17f0b0d 100644 --- a/worlds/factorio/Client.py +++ b/worlds/factorio/Client.py @@ -530,7 +530,7 @@ def _handle_color(self, node: JSONMessagePart): def launch(): import colorama global executable, server_settings, server_args - colorama.init() + colorama.just_fix_windows_console() if server_settings: server_settings = os.path.abspath(server_settings) diff --git a/worlds/kh1/Client.py b/worlds/kh1/Client.py index 33fba85f6c54..b98f21531207 100644 --- a/worlds/kh1/Client.py +++ b/worlds/kh1/Client.py @@ -295,6 +295,6 @@ async def main(args): parser = get_base_parser(description="KH1 Client, for text interfacing.") args, rest = parser.parse_known_args() - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main(args)) colorama.deinit() diff --git a/worlds/kh2/Client.py b/worlds/kh2/Client.py index 15a103c2a1ae..96b406c72f2f 100644 --- a/worlds/kh2/Client.py +++ b/worlds/kh2/Client.py @@ -981,6 +981,6 @@ async def main(args): parser = get_base_parser(description="KH2 Client, for text interfacing.") args, rest = parser.parse_known_args() - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main(args)) colorama.deinit() diff --git a/worlds/sc2/Client.py b/worlds/sc2/Client.py index 813cf2884517..77b13a5acbdd 100644 --- a/worlds/sc2/Client.py +++ b/worlds/sc2/Client.py @@ -1625,6 +1625,6 @@ def get_location_offset(mission_id): def launch(): - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main()) colorama.deinit() diff --git a/worlds/zillion/client.py b/worlds/zillion/client.py index d629df583a81..71f0615d32bc 100644 --- a/worlds/zillion/client.py +++ b/worlds/zillion/client.py @@ -516,6 +516,6 @@ async def main() -> None: def launch() -> None: - colorama.init() + colorama.just_fix_windows_console() asyncio.run(main()) colorama.deinit() diff --git a/worlds/zork_grand_inquisitor/client.py b/worlds/zork_grand_inquisitor/client.py index 11d6b7f8f183..8b8d7d3ebf58 100644 --- a/worlds/zork_grand_inquisitor/client.py +++ b/worlds/zork_grand_inquisitor/client.py @@ -177,7 +177,7 @@ async def _main(): import colorama - colorama.init() + colorama.just_fix_windows_console() asyncio.run(_main()) From 0d1935e7572b7fdaef624086bffc87a987ea88bc Mon Sep 17 00:00:00 2001 From: neocerber <140952826+neocerber@users.noreply.github.com> Date: Fri, 14 Mar 2025 11:35:58 -0400 Subject: [PATCH 0203/1218] SC2: Add a description of mission order and the impact of collect on a SC2 world (#4398) * Added mission order to randomized stuff, added a mention to the default option collect on goal, added an issue about mission order progress vs AP collect * Remove false menion of collect being note modifyable after the mworld was gen * Simplification of some sentences * American spelling, header newline, and other * Revert gray to grey, corrected some colors * Forgot a gray -> grey * Replace how the faction color option is described to side-step difference within yaml and client. Both fr/en. --- worlds/sc2/docs/en_Starcraft 2.md | 40 ++++++++++++++++++++++----- worlds/sc2/docs/fr_Starcraft 2.md | 45 +++++++++++++++++++++++++------ worlds/sc2/docs/setup_en.md | 1 + worlds/sc2/docs/setup_fr.md | 1 + 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/worlds/sc2/docs/en_Starcraft 2.md b/worlds/sc2/docs/en_Starcraft 2.md index 813fdb5f4a2b..e860e8a6b6bb 100644 --- a/worlds/sc2/docs/en_Starcraft 2.md +++ b/worlds/sc2/docs/en_Starcraft 2.md @@ -1,10 +1,13 @@ # StarCraft 2 ## Game page in other languages: + * [Français](/games/Starcraft%202/info/fr) ## What does randomization do to this game? +### Items and locations + The following unlocks are randomized as items: 1. Your ability to build any non-worker unit. 2. Unit specific upgrades including some combinations not available in the vanilla campaigns, such as both strain @@ -34,18 +37,28 @@ When you receive items, they will immediately become available, even during a mi notified via a text box in the top-right corner of the game screen. Item unlocks are also logged in the Archipelago client. +### Mission order + +The missions and the order in which they need to be completed, referred to as the mission order, can also be randomized. +The four StarCraft 2 campaigns can be used to populate the mission order. +Note that the evolution missions from Heart of the Swarm are not included in the randomizer. +The default mission order follows the structure of the selected campaigns but several other options are available, +e.g., blitz, grid, etc. + Missions are launched through the StarCraft 2 Archipelago client, through the StarCraft 2 Launcher tab. The between mission segments on the Hyperion, the Leviathan, and the Spear of Adun are not included. Additionally, metaprogression currencies such as credits and Solarite are not used. +Available missions are in blue; missions where all locations were collected are in white. +If you move your mouse over a mission, the uncollected locations will be displayed, categorized by type. +Unavailable missions are in grey; their requirements will also be shown there. ## What is the goal of this game when randomized? The goal is to beat the final mission in the mission order. -The yaml configuration file controls the mission order (e.g. blitz, grid, etc.), which combination of the four -StarCraft 2 campaigns can be used to populate the mission order and how missions are shuffled. +The yaml configuration file controls the mission order, which combination of the four StarCraft 2 campaigns can be +used, and how missions are shuffled. Since the first two options determine the number of missions in a StarCraft 2 world, they can be used to customize the expected time to complete the world. -Note that the evolution missions from Heart of the Swarm are not included in the randomizer. ## What non-randomized changes are there from vanilla StarCraft 2? @@ -78,9 +91,7 @@ Will overwrite existing files * `/game_speed [game_speed]` Overrides the game speed for the world * Options: default, slower, slow, normal, fast, faster * `/color [faction] [color]` Changes your color for one of your playable factions. - * Faction options: raynor, kerrigan, primal, protoss, nova - * Color options: white, red, blue, teal, purple, yellow, orange, green, lightpink, violet, lightgrey, darkgreen, - brown, lightgreen, darkgrey, pink, rainbow, random, default + * Run without arguments to list all factions and colors that are available. * `/option [option_name] [option_value]` Sets an option normally controlled by your yaml after generation. * Run without arguments to list all options. * Options pertain to automatic cutscene skipping, Kerrigan presence, Spear of Adun presence, starting resource @@ -100,6 +111,19 @@ Additionally, upgrades are grouped beneath their corresponding units or building A filter parameter can be provided, e.g., `/received Thor`, to limit the number of items shown. Every item whose name, race, or group name contains the provided parameter will be shown. +## Particularities in a multiworld + +### Collect on goal completion + +One of the default options of multiworlds is that once a world has achieved its goal, it collects its items from all +other worlds. +If you do not want this to happen, you should ask the person generating the multiworld to set the `Collect Permission` +option to something else, e.g., manual. +If the generation is not done via the website, the person that does the generation should modify the `collect_mode` +option in their `host.yaml` file prior to generation. +If the multiworld has already been generated, the host can use the command `/option collect_mode [value]` to change +this option. + ## Known issues - StarCraft 2 Archipelago does not support loading a saved game. @@ -108,3 +132,7 @@ For this reason, it is recommended to play on a difficulty level lower than what To restart a mission, use the StarCraft 2 Client. - A crash report is often generated when a mission is closed. This does not affect the game and can be ignored. +- Currently, the StarCraft 2 client uses the Victory locations to determine which missions have been completed. +As a result, the Archipelago collect feature can sometime grant access to missions that are connected to a mission that +you did not complete. + diff --git a/worlds/sc2/docs/fr_Starcraft 2.md b/worlds/sc2/docs/fr_Starcraft 2.md index 092835c8e323..190802e91bff 100644 --- a/worlds/sc2/docs/fr_Starcraft 2.md +++ b/worlds/sc2/docs/fr_Starcraft 2.md @@ -2,6 +2,8 @@ ## Quel est l'effet de la *randomization* sur ce jeu ? +### *Items* et *locations* + Les éléments qui suivent sont les *items* qui sont *randomized* et qui doivent être débloqués pour être utilisés dans le jeu: 1. La capacité de produire des unités, excepté les drones/probes/scv. @@ -37,21 +39,33 @@ Quand vous recevez un *item*, il devient immédiatement disponible, même pendan la boîte de texte situé dans le coin en haut à droite de *StarCraft 2*. L'acquisition d'un *item* est aussi indiquée dans le client d'Archipelago. +### *Mission order* + +Les missions et l'ordre dans lequel elles doivent être complétées, dénoté *mission order*, peuvent également être +*randomized*. +Les quatre campagnes de *StarCraft 2* peuvent être utilisées pour remplir le *mission order*. +Notez que les missions d'évolution de *Heart of the Swarm* ne sont pas incluses dans le *randomizer*. +Par défaut, le *mission order* suit la structure des campagnes sélectionnées, mais plusieurs autres options sont +disponibles, comme *blitz*, *grid*, etc. + Les missions peuvent être lancées par le client *StarCraft 2 Archipelago*, via l'interface graphique de l'onglet *StarCraft 2 Launcher*. Les segments qui se passent sur l'*Hyperion*, un Léviathan et la *Spear of Adun* ne sont pas inclus. -De plus, les points de progression tels que les crédits ou la Solarite ne sont pas utilisés dans *StarCraft 2 +De plus, les points de progression, tels que les crédits ou la Solarite, ne sont pas utilisés dans *StarCraft 2 Archipelago*. +Les missions accessibles ont leur nom en bleu, tandis que celles où toutes les *locations* ont été collectées +apparaissent en blanc. +En plaçant votre souris sur une mission, les *locations* non collectées s’affichent, classées par catégorie. +Les missions qui ne sont pas accessibles ont leur nom en gris et leurs prérequis seront également affichés à cet endroit. + ## Quel est le but de ce jeu quand il est *randomized*? Le but est de réussir la mission finale du *mission order* (e.g. *blitz*, *grid*, etc.). -Le fichier de configuration yaml permet de spécifier le *mission order*, lesquelles des quatre campagnes de -*StarCraft 2* peuvent être utilisées pour remplir le *mission order* et comment les missions sont distribuées dans le -*mission order*. +Le fichier de configuration yaml permet de spécifier le *mission order*, quelle combinaison des quatre campagnes de +*StarCraft 2* peuvent être utilisée et comment les missions sont distribuées dans le *mission order*. Étant donné que les deux premières options déterminent le nombre de missions dans un monde de *StarCraft 2*, elles peuvent être utilisées pour moduler le temps nécessaire pour terminer le monde. -Notez que les missions d'évolution de Heart of the Swarm ne sont pas incluses dans le *randomizer*. ## Quelles sont les modifications non aléatoires comparativement à la version de base de *StarCraft 2* @@ -89,9 +103,7 @@ Les fichiers existants vont être écrasés. * `/game_speed [game_speed]` Remplace la vitesse du jeu pour le monde. * Les options sont *default*, *slower*, *slow*, *normal*, *fast*, and *faster*. * `/color [faction] [color]` Remplace la couleur d'une des *factions* qui est jouable. - * Les options de *faction*: raynor, kerrigan, primal, protoss, nova. - * Les options de couleur: *white*, *red*, *blue*, *teal*, *purple*, *yellow*, *orange*, *green*, *lightpink*, -*violet*, *lightgrey*, *darkgreen*, *brown*, *lightgreen*, *darkgrey*, *pink*, *rainbow*, *random*, *default*. + * Si la commande est lancée sans option, la liste des *factions* et des couleurs disponibles sera affichée. * `/option [option_name] [option_value]` Permet de changer un option normalement définit dans le *yaml*. * Si la commande est lancée sans option, la liste des options qui sont modifiables va être affichée. * Les options qui peuvent être changées avec cette commande incluent sauter les cinématiques automatiquement, la @@ -114,6 +126,19 @@ De plus, les améliorations sont regroupées sous leurs unités/bâtiments corre Un paramètre de filtrage peut aussi être fourni, e.g., `/received Thor`, pour limiter le nombre d'*items* affichés. Tous les *items* dont le nom, la race ou le nom de groupe contient le paramètre fourni seront affichés. +## Particularités dans un multiworld + +### *Collect on goal completion* + +L'une des options par défaut des *multiworlds* est qu'une fois qu'un monde a atteint son objectif final, il collecte +tous ses *items*, incluant ceux dans les autres mondes. +Si vous ne souhaitez pas que cela se produise, vous devez demander à la personne générant le *multiworld* de changer +l'option *Collect Permission*. +Si la génération n'est pas effectuée via le site web, la personne qui effectue la génération doit modifier l'option +`collect_mode` dans son fichier *host.yaml* avant la génération. +Si le *multiworld* a déjà été généré, l'hôte peut utiliser la commande `/option collect_mode [valeur]` pour modifier +cette option. + ## Problèmes connus - *StarCraft 2 Archipelago* ne supporte pas le chargement d'une sauvegarde. @@ -123,3 +148,7 @@ normalement à l'aise. Pour redémarrer une mission, utilisez le client de *StarCraft 2 Archipelago*. - Un rapport d'erreur est souvent généré lorsqu'une mission est fermée. Cela n'affecte pas le jeu et peut être ignoré. +- Actuellement, le client de *StarCraft 2* utilise la *location* associée à la victoire d'une mission pour déterminer +si celle-ci a été complétée. +En conséquence, la fonctionnalité *collect* d'*Archipelago* peut rendre accessible des missions connectées à une +mission que vous n'avez pas terminée. \ No newline at end of file diff --git a/worlds/sc2/docs/setup_en.md b/worlds/sc2/docs/setup_en.md index 5b378873f4a3..4364008b58a7 100644 --- a/worlds/sc2/docs/setup_en.md +++ b/worlds/sc2/docs/setup_en.md @@ -41,6 +41,7 @@ Remember the name you enter in the options page or in the yaml file, you'll need Check out [Creating a YAML](/tutorial/Archipelago/setup/en#creating-a-yaml) for more game-agnostic information. ### Common yaml questions + #### How do I know I set my yaml up correctly? The simplest way to check is to use the website [validator](/check). diff --git a/worlds/sc2/docs/setup_fr.md b/worlds/sc2/docs/setup_fr.md index d9b754572a66..7cdb7225b431 100644 --- a/worlds/sc2/docs/setup_fr.md +++ b/worlds/sc2/docs/setup_fr.md @@ -49,6 +49,7 @@ Si vous désirez des informations et/ou instructions générales sur l'utilisati veuillez consulter [*Creating a YAML*](/tutorial/Archipelago/setup/en#creating-a-yaml). ### Questions récurrentes à propos du fichier *yaml* + #### Comment est-ce que je sais que mon *yaml* est bien défini? La manière la plus simple de valider votre *yaml* est d'utiliser le From 7e32feeea373daca8a4a1045c2afadabe61c7429 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sat, 15 Mar 2025 07:09:04 -0400 Subject: [PATCH 0204/1218] Webhost: Update random option wording on webhost (#4555) * Update random option wording on webhost * Update WebHostLib/templates/playerOptions/macros.html Co-authored-by: Jouramie <16137441+Jouramie@users.noreply.github.com> --- WebHostLib/templates/playerOptions/macros.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/templates/playerOptions/macros.html b/WebHostLib/templates/playerOptions/macros.html index 64f0f140de95..972f03175d51 100644 --- a/WebHostLib/templates/playerOptions/macros.html +++ b/WebHostLib/templates/playerOptions/macros.html @@ -213,7 +213,7 @@ {% endmacro %} {% macro RandomizeButton(option_name, option) %} -
+
- {% include 'islandFooter.html' %} {% endblock %} diff --git a/WebHostLib/templates/hostGame.html b/WebHostLib/templates/hostGame.html index 2bcb993af572..d7d0a9633129 100644 --- a/WebHostLib/templates/hostGame.html +++ b/WebHostLib/templates/hostGame.html @@ -1,4 +1,5 @@ {% extends 'pageWrapper.html' %} +{% set show_footer = True %} {% block head %} Upload Multidata @@ -27,6 +28,4 @@

Host Game

- - {% include 'islandFooter.html' %} {% endblock %} diff --git a/WebHostLib/templates/landing.html b/WebHostLib/templates/landing.html index b489ef18ac91..e7d0569e6ca5 100644 --- a/WebHostLib/templates/landing.html +++ b/WebHostLib/templates/landing.html @@ -1,4 +1,5 @@ {% extends 'pageWrapper.html' %} +{% set show_footer = True %} {% block head %} Archipelago @@ -57,5 +58,4 @@

multiworld multi-game randomizer

- {% include 'islandFooter.html' %} {% endblock %} diff --git a/WebHostLib/templates/pageWrapper.html b/WebHostLib/templates/pageWrapper.html index c7dda523ef4e..4347b4add340 100644 --- a/WebHostLib/templates/pageWrapper.html +++ b/WebHostLib/templates/pageWrapper.html @@ -5,26 +5,29 @@ - {% block head %} Archipelago {% endblock %} +
+ {% with messages = get_flashed_messages() %} + {% if messages %} +
+ {% for message in messages | unique %} +
{{ message }}
+ {% endfor %} +
+ {% endif %} + {% endwith %} -{% with messages = get_flashed_messages() %} - {% if messages %} -
- {% for message in messages | unique %} -
{{ message }}
- {% endfor %} -
- {% endif %} -{% endwith %} - -{% block body %} -{% endblock %} + {% block body %} + {% endblock %} +
+ {% if show_footer %} + {% include "islandFooter.html" %} + {% endif %} diff --git a/WebHostLib/templates/seedError.html b/WebHostLib/templates/seedError.html index 0f5850da1b7d..a5eec1a4cc53 100644 --- a/WebHostLib/templates/seedError.html +++ b/WebHostLib/templates/seedError.html @@ -1,5 +1,6 @@ {% extends 'pageWrapper.html' %} {% import "macros.html" as macros %} +{% set show_footer = True %} {% block head %} Generation failed, please retry. @@ -15,5 +16,4 @@

please retry

{{ seed_error }} - {% include 'islandFooter.html' %} {% endblock %} diff --git a/WebHostLib/templates/startPlaying.html b/WebHostLib/templates/startPlaying.html index ab2f021d61d2..9e09474bd0f4 100644 --- a/WebHostLib/templates/startPlaying.html +++ b/WebHostLib/templates/startPlaying.html @@ -1,4 +1,5 @@ {% extends 'pageWrapper.html' %} +{% set show_footer = True %} {% block head %} Start Playing @@ -26,6 +27,4 @@

Start Playing

- - {% include 'islandFooter.html' %} {% endblock %} diff --git a/WebHostLib/templates/viewSeed.html b/WebHostLib/templates/viewSeed.html index a8478c95c30d..70ffe23b7be3 100644 --- a/WebHostLib/templates/viewSeed.html +++ b/WebHostLib/templates/viewSeed.html @@ -1,5 +1,6 @@ {% extends 'pageWrapper.html' %} {% import "macros.html" as macros %} +{% set show_footer = True %} {% block head %} View Seed {{ seed.id|suuid }} @@ -50,5 +51,4 @@

Seed Info

- {% include 'islandFooter.html' %} {% endblock %} diff --git a/WebHostLib/templates/waitSeed.html b/WebHostLib/templates/waitSeed.html index 9041b901b5c6..235c2f16651f 100644 --- a/WebHostLib/templates/waitSeed.html +++ b/WebHostLib/templates/waitSeed.html @@ -1,5 +1,6 @@ {% extends 'pageWrapper.html' %} {% import "macros.html" as macros %} +{% set show_footer = True %} {% block head %} Generation in Progress @@ -15,5 +16,4 @@

Generation in Progress

Waiting for game to generate, this page auto-refreshes to check. - {% include 'islandFooter.html' %} {% endblock %} From e211dfa1c2f6da28c17353749e319ec8a4ec7a4f Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 9 Apr 2025 07:43:28 +0200 Subject: [PATCH 0299/1218] WebHost: use JS to refresh waitSeed if scripting is enabled (#4843) --- WebHostLib/templates/waitSeed.html | 34 +++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/WebHostLib/templates/waitSeed.html b/WebHostLib/templates/waitSeed.html index 235c2f16651f..f2729353a617 100644 --- a/WebHostLib/templates/waitSeed.html +++ b/WebHostLib/templates/waitSeed.html @@ -4,7 +4,9 @@ {% block head %} Generation in Progress - + {% endblock %} @@ -16,4 +18,34 @@

Generation in Progress

Waiting for game to generate, this page auto-refreshes to check. + {% endblock %} From f93734f9e3b7b805bff4edacc204fbf31559e345 Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Wed, 9 Apr 2025 13:20:56 -0400 Subject: [PATCH 0300/1218] Pokemon Red and Blue: PC Item Fix (#4835) * Pokemon Red and Blue PC Item fix * Respect non_local_items for PC Item * prefer exclude if also in priority locations --------- Co-authored-by: alchav --- worlds/pokemon_rb/regions.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/worlds/pokemon_rb/regions.py b/worlds/pokemon_rb/regions.py index a7c0b6d5337c..84c9b2573547 100644 --- a/worlds/pokemon_rb/regions.py +++ b/worlds/pokemon_rb/regions.py @@ -1580,16 +1580,22 @@ def create_regions(world): world.random.shuffle(world.item_pool) if not world.options.key_items_only: - if "Player's House 2F - Player's PC" in world.options.exclude_locations: - acceptable_item = lambda item: item.excludable - elif "Player's House 2F - Player's PC" in world.options.priority_locations: - acceptable_item = lambda item: item.advancement - else: - acceptable_item = lambda item: True + def acceptable_item(item): + return ("Badge" not in item.name and "Trap" not in item.name and item.name != "Pokedex" + and "Coins" not in item.name and "Progressive" not in item.name + and ("Player's House 2F - Player's PC" not in world.options.exclude_locations or item.excludable) + and ("Player's House 2F - Player's PC" in world.options.exclude_locations or + "Player's House 2F - Player's PC" not in world.options.priority_locations or item.advancement)) for i, item in enumerate(world.item_pool): - if acceptable_item(item): + if acceptable_item(item) and (item.name not in world.options.non_local_items.value): world.pc_item = world.item_pool.pop(i) break + else: + for i, item in enumerate(world.item_pool): + if acceptable_item(item): + world.pc_item = world.item_pool.pop(i) + break + advancement_items = [item.name for item in world.item_pool if item.advancement] \ + [item.name for item in world.multiworld.precollected_items[world.player] if From 1ee749b3522735bdd7f250a69d7b3a2a1b19d4a4 Mon Sep 17 00:00:00 2001 From: Ziktofel Date: Wed, 9 Apr 2025 22:21:16 +0200 Subject: [PATCH 0301/1218] SC2 Client: Fix missing mission tooltip after KivyMD switch (#4827) --- worlds/sc2/ClientGui.py | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/worlds/sc2/ClientGui.py b/worlds/sc2/ClientGui.py index 27857715a851..d16acad83d9d 100644 --- a/worlds/sc2/ClientGui.py +++ b/worlds/sc2/ClientGui.py @@ -5,12 +5,11 @@ from kvui import GameManager, HoverBehavior, ServerToolTip, KivyJSONtoTextParser from kivy.app import App from kivy.clock import Clock -from kivymd.uix.tab import MDTabsItem, MDTabsItemText from kivy.uix.gridlayout import GridLayout from kivy.lang import Builder from kivy.uix.label import Label from kivy.uix.button import Button -from kivy.uix.floatlayout import FloatLayout +from kivymd.uix.tooltip import MDTooltip from kivy.uix.scrollview import ScrollView from kivy.properties import StringProperty @@ -26,30 +25,22 @@ class HoverableButton(HoverBehavior, Button): pass -class MissionButton(HoverableButton): +class MissionButton(HoverableButton, MDTooltip): tooltip_text = StringProperty("Test") def __init__(self, *args, **kwargs): - super(HoverableButton, self).__init__(*args, **kwargs) - self.layout = FloatLayout() - self.popuplabel = ServerToolTip(text=self.text, markup=True) - self.popuplabel.padding = [5, 2, 5, 2] - self.layout.add_widget(self.popuplabel) + super(HoverableButton, self).__init__(**kwargs) + self._tooltip = ServerToolTip(text=self.text, markup=True) + self._tooltip.padding = [5, 2, 5, 2] def on_enter(self): - self.popuplabel.text = self.tooltip_text + self._tooltip.text = self.tooltip_text - if self.ctx.current_tooltip: - App.get_running_app().root.remove_widget(self.ctx.current_tooltip) - - if self.tooltip_text == "": - self.ctx.current_tooltip = None - else: - App.get_running_app().root.add_widget(self.layout) - self.ctx.current_tooltip = self.layout + if self.tooltip_text != "": + self.display_tooltip() def on_leave(self): - self.ctx.ui.clear_tooltip() + self.remove_tooltip() @property def ctx(self) -> SC2Context: From b7263edfd0512949c0dbfef86e1e48bd43c13890 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Wed, 9 Apr 2025 19:41:07 -0400 Subject: [PATCH 0302/1218] Lingo: Removed unnecessary "global" keywords (#4854) --- worlds/lingo/items.py | 2 -- worlds/lingo/locations.py | 2 -- worlds/lingo/utils/pickle_static_data.py | 21 ++------------------- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/worlds/lingo/items.py b/worlds/lingo/items.py index b773caeb4e8f..338ddffa5d72 100644 --- a/worlds/lingo/items.py +++ b/worlds/lingo/items.py @@ -58,8 +58,6 @@ def get_prog_item_classification(item_name: str): def load_item_data(): - global ALL_ITEM_TABLE, ITEMS_BY_GROUP - for color in ["Black", "Red", "Blue", "Yellow", "Green", "Orange", "Gray", "Brown", "Purple"]: ALL_ITEM_TABLE[color] = ItemData(get_special_item_id(color), get_prog_item_classification(color), ItemType.COLOR, False, []) diff --git a/worlds/lingo/locations.py b/worlds/lingo/locations.py index c527e522fb06..bcd14fc5a7e3 100644 --- a/worlds/lingo/locations.py +++ b/worlds/lingo/locations.py @@ -35,8 +35,6 @@ class LingoLocation(Location): def load_location_data(): - global ALL_LOCATION_TABLE, LOCATIONS_BY_GROUP - for room_name, panels in PANELS_BY_ROOM.items(): for panel_name, panel in panels.items(): location_name = f"{room_name} - {panel_name}" if panel.location_name is None else panel.location_name diff --git a/worlds/lingo/utils/pickle_static_data.py b/worlds/lingo/utils/pickle_static_data.py index df82a12861a4..740e129bcb6c 100644 --- a/worlds/lingo/utils/pickle_static_data.py +++ b/worlds/lingo/utils/pickle_static_data.py @@ -58,8 +58,7 @@ def hash_file(path): def load_static_data(ll1_path, ids_path): - global PAINTING_EXITS, SPECIAL_ITEM_IDS, PANEL_LOCATION_IDS, DOOR_LOCATION_IDS, DOOR_ITEM_IDS, \ - DOOR_GROUP_ITEM_IDS, PROGRESSIVE_ITEM_IDS, PANEL_DOOR_ITEM_IDS, PANEL_GROUP_ITEM_IDS + global PAINTING_EXITS # Load in all item and location IDs. These are broken up into groups based on the type of item/location. with open(ids_path, "r") as file: @@ -128,7 +127,7 @@ def load_static_data(ll1_path, ids_path): def process_single_entrance(source_room: str, room_name: str, door_obj) -> RoomEntrance: - global PAINTING_ENTRANCES, PAINTING_EXIT_ROOMS + global PAINTING_ENTRANCES entrance_type = EntranceType.NORMAL if "painting" in door_obj and door_obj["painting"]: @@ -175,8 +174,6 @@ def process_entrance(source_room, doors, room_obj): def process_panel_door(room_name, panel_door_name, panel_door_data): - global PANEL_DOORS_BY_ROOM, PANEL_DOOR_BY_PANEL_BY_ROOM - panels: List[RoomAndPanel] = list() for panel in panel_door_data["panels"]: if isinstance(panel, dict): @@ -215,8 +212,6 @@ def process_panel_door(room_name, panel_door_name, panel_door_data): def process_panel(room_name, panel_name, panel_data): - global PANELS_BY_ROOM - # required_room can either be a single room or a list of rooms. if "required_room" in panel_data: if isinstance(panel_data["required_room"], list): @@ -310,8 +305,6 @@ def process_panel(room_name, panel_name, panel_data): def process_door(room_name, door_name, door_data): - global DOORS_BY_ROOM - # The item name associated with a door can be explicitly specified in the configuration. If it is not, it is # generated from the room and door name. if "item_name" in door_data: @@ -409,8 +402,6 @@ def process_door(room_name, door_name, door_data): def process_painting(room_name, painting_data): - global PAINTINGS, REQUIRED_PAINTING_ROOMS, REQUIRED_PAINTING_WHEN_NO_DOORS_ROOMS - # Read in information about this painting and store it in an object. painting_id = painting_data["id"] @@ -468,8 +459,6 @@ def process_painting(room_name, painting_data): def process_sunwarp(room_name, sunwarp_data): - global SUNWARP_ENTRANCES, SUNWARP_EXITS - if sunwarp_data["direction"] == "enter": SUNWARP_ENTRANCES[sunwarp_data["dots"] - 1] = room_name else: @@ -477,8 +466,6 @@ def process_sunwarp(room_name, sunwarp_data): def process_progressive_door(room_name, progression_name, progression_doors): - global PROGRESSIVE_ITEMS, PROGRESSIVE_DOORS_BY_ROOM - # Progressive items are configured as a list of doors. PROGRESSIVE_ITEMS.add(progression_name) @@ -497,8 +484,6 @@ def process_progressive_door(room_name, progression_name, progression_doors): def process_progressive_panel(room_name, progression_name, progression_panel_doors): - global PROGRESSIVE_ITEMS, PROGRESSIVE_PANELS_BY_ROOM - # Progressive items are configured as a list of panel doors. PROGRESSIVE_ITEMS.add(progression_name) @@ -517,8 +502,6 @@ def process_progressive_panel(room_name, progression_name, progression_panel_doo def process_room(room_name, room_data): - global ALL_ROOMS - room_obj = Room(room_name, []) if "entrances" in room_data: From e3b8a60584524e5dbb24cfc1542a3acb92da9360 Mon Sep 17 00:00:00 2001 From: qwint Date: Wed, 9 Apr 2025 20:29:11 -0500 Subject: [PATCH 0303/1218] Webhost: Fix Sphere Tracker crashing on item links (#4855) --- BaseClasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index 4db39179857e..4074108b4b05 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -616,7 +616,7 @@ def get_sendable_spheres(self) -> Iterator[Set[Location]]: locations: Set[Location] = set() events: Set[Location] = set() for location in self.get_filled_locations(): - if type(location.item.code) is int: + if type(location.item.code) is int and type(location.address) is int: locations.add(location) else: events.add(location) From 78c93d7e3905d932d284c72c525911fe1f731fe8 Mon Sep 17 00:00:00 2001 From: qwint Date: Thu, 10 Apr 2025 12:00:48 -0500 Subject: [PATCH 0304/1218] Docs: Add FAQ section for corrupted metadata debugging (#4705) Co-authored-by: Scipio Wright --- docs/apworld_dev_faq.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/apworld_dev_faq.md b/docs/apworld_dev_faq.md index 769a2fb3a0a7..6d7d23b488d1 100644 --- a/docs/apworld_dev_faq.md +++ b/docs/apworld_dev_faq.md @@ -66,3 +66,22 @@ The reason entrance access rules using `location.can_reach` and `entrance.can_re We recognize it can feel like a trap since it will not alert you when you are missing an indirect condition, and that some games have very complex access rules. As of [PR #3682 (Core: Region handling customization)](https://github.com/ArchipelagoMW/Archipelago/pull/3682) being merged, it is possible for a world to opt out of indirect conditions entirely, instead using the system of checking each entrance whenever a region has been reached, although this does come with a performance cost. Opting out of using indirect conditions should only be used by games that *really* need it. For most games, it should be reasonable to know all entrance → region dependencies, making indirect conditions preferred because they are much faster. + +--- + +### I uploaded the generated output of my world to the webhost and webhost is erroring on corrupted multidata + +The error `Could not load multidata. File may be corrupted or incompatible.` occurs when uploading a locally generated +file where there is an issue with the multidata contained within it. It may come with a description like +`(No module named 'worlds.myworld')` or `(global 'worlds.myworld.names.ItemNames' is forbidden)` + +Pickling is a way to compress python objects such that they can be decompressed and be used to rebuild the +python objects. This means that if one of your custom class instances ends up in the multidata, the server would not +be able to load that custom class to decompress the data, which can fail either because the custom class is unknown +(because it cannot load your world module) or the class it's attempting to import to decompress is deemed unsafe. + +Common situations where this can happen include: +* Using Option instances directly in slot_data. Ex: using `options.option_name` instead of `options.option_name.value`. + Also, consider using the `options.as_dict("option_name", "option_two")` helper. +* Using enums as Location/Item names in the datapackage. When building out `location_name_to_id` and `item_name_to_id`, + make sure that you are not using your enum class for either the names or ids in these mappings. From 399958c8814112ed266eef5734999544a9337da3 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 10 Apr 2025 12:03:05 -0500 Subject: [PATCH 0305/1218] The Messenger: Add an FAQ (#4718) --- worlds/messenger/docs/en_The Messenger.md | 20 ++++++++++++++++++-- worlds/messenger/options.py | 4 +++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/worlds/messenger/docs/en_The Messenger.md b/worlds/messenger/docs/en_The Messenger.md index a68ee5ba4c7a..1886162fc925 100644 --- a/worlds/messenger/docs/en_The Messenger.md +++ b/worlds/messenger/docs/en_The Messenger.md @@ -1,6 +1,7 @@ # The Messenger ## Quick Links + - [Setup](/tutorial/The%20Messenger/setup/en) - [Options Page](/games/The%20Messenger/player-options) - [Courier Github](https://github.com/Brokemia/Courier) @@ -26,6 +27,7 @@ obtained. You'll be forced to do sections of the game in different ways with you ## Where can I find items? You can find items wherever items can be picked up in the original game. This includes: + * Shopkeeper dialog where the player originally gains movement items * Quest Item pickups * Music Box notes @@ -42,6 +44,7 @@ group of items. Hinting for a group will choose a random item from the group tha for it. The groups you can use for The Messenger are: + * Notes - This covers the music notes * Keys - An alternative name for the music notes * Crest - The Sun and Moon Crests @@ -64,16 +67,29 @@ The groups you can use for The Messenger are: be entered in game. ## Known issues + * Ruxxtin Coffin cutscene will sometimes not play correctly, but will still reward the item * If you receive the Magic Firefly while in Quillshroom Marsh, The De-curse Queen cutscene will not play. You can exit to Searing Crags and re-enter to get it to play correctly. * Teleporting back to HQ, then returning to the same level you just left through a Portal can cause Ninja to run left and enter a different portal than the one entered by the player or lead to other incorrect inputs, causing a soft lock * Text entry menus don't accept controller input -* In power seal hunt mode, the chest must be opened by entering the shop from a level. Teleporting to HQ and opening the - chest will not work. ## What do I do if I have a problem? If you believe something happened that isn't intended, please get the `log.txt` from the folder of your game installation and send a bug report either on GitHub or the [Archipelago Discord Server](http://archipelago.gg/discord) + +## FAQ + +* The tracker says I can get some checks in Howling Grotto, but I can't defeat the Emerald Golem. How do I get there? + * Due to the way the vanilla game handles bosses and level transitions, if you die to him, the room will be unlocked, + and you can leave. +* I have the money wrench. Why won't the shopkeeper let me enter the sink? + * The money wrench is both an item you must find or receive from another player and a location check, which you must + purchase from the Artificer, as in vanilla. +* How do I unfreeze Manfred? Where is the monk? + * The monk will only appear near Manfred after you cleanse the Queen of Quills with the fairy (magic firefly). +* I have all the power seals I need to win, but nothing is happening when I open the chest. + * Due to how the level loading code works, I am currently unable to teleport you out of HQ at will; you must enter the + shop from within a level. diff --git a/worlds/messenger/options.py b/worlds/messenger/options.py index c7a0f543ba5c..aaf152fbf8c3 100644 --- a/worlds/messenger/options.py +++ b/worlds/messenger/options.py @@ -147,7 +147,9 @@ class MusicBox(DefaultOnToggle): class NotesNeeded(Range): - """How many notes are needed to access the Music Box.""" + """ + How many notes need to be found in order to access the Music Box. 6 are always needed to enter, so this places the others in your start inventory. + """ display_name = "Notes Needed" range_start = 1 range_end = 6 From 50fd42d0c2ade7fdd071c158cc172c42a416176e Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 10 Apr 2025 12:13:38 -0500 Subject: [PATCH 0306/1218] The Messenger: Add a plando guide (#4719) --- worlds/messenger/__init__.py | 10 ++- worlds/messenger/docs/plando_en.md | 101 +++++++++++++++++++++++++++++ worlds/messenger/options.py | 22 +------ 3 files changed, 113 insertions(+), 20 deletions(-) create mode 100644 worlds/messenger/docs/plando_en.md diff --git a/worlds/messenger/__init__.py b/worlds/messenger/__init__.py index 8bde3bbc7ae5..2382a46c314f 100644 --- a/worlds/messenger/__init__.py +++ b/worlds/messenger/__init__.py @@ -46,8 +46,16 @@ class MessengerWeb(WebWorld): "setup/en", ["alwaysintreble"], ) + plando_en = Tutorial( + "The Messenger Plando Guide", + "A guide detailing The Messenger's various supported plando options.", + "English", + "plando_en.md", + "plando/en", + ["alwaysintreble"], + ) - tutorials = [tut_en] + tutorials = [tut_en, plando_en] class MessengerWorld(World): diff --git a/worlds/messenger/docs/plando_en.md b/worlds/messenger/docs/plando_en.md new file mode 100644 index 000000000000..920cf029d833 --- /dev/null +++ b/worlds/messenger/docs/plando_en.md @@ -0,0 +1,101 @@ +# The Messenger Plando Guide + +This guide details the usage of the game-specific plando options that The Messenger has. The Messenger also supports the +generic item plando. For more information on what plando is and for information covering item plando, refer to the +[generic Archipelago plando guide](/tutorial/Archipelago/plando/en). The Messenger also uses the generic connection +plando system, but with specific behaviors that will be covered in this guide along with the other options. + +## Shop Price Plando + +This option allows you to specify prices for items in both shops. This also supports weighting, allowing you to choose +from multiple different prices for any given item. + +### Example + +```yaml +The Messenger: + shop_price_plan: + Karuta Plates: 50 + Devil's Due: 1 + Barmath'azel Figurine: + # left side is price, right side is weight + 500: 10 + 700: 5 + 1000: 20 +``` + +This block will make the item at the `Karuta Plates` node cost 50 shards, `Devil's Due` will cost 1 shard, and +`Barmath'azel Figurine` will cost either 500, 700, or 1000, with 1000 being the most likely with a 20/35 chance. + +## Portal Plando + +This option allows you to specify certain outputs for the portals. This option will only be checked if portal shuffle +and the `connections` plando host setting are enabled. + +A portal connection is plandoed by specifying an `entrance` and an `exit`. This option also supports `percentage`, which +is the percent chance that that connection occurs. The `entrance` is which portal is going to be entered, whereas the +`exit` is where the portal will lead and can include a shop location, a checkpoint, or any portal. However, the +portal exit must also be in the available pool for the selected portal shuffle option. For example, if portal shuffle is +set to `shops`, then the valid exits will only be portals and shops; any exit that is a checkpoint will not be valid. If +portal shuffle is set to `checkpoints`, you may not have multiple portals lead to the same area, e.g. `Seashell` and +`Spike Wave` may not both be used since they are both in Quillshroom Marsh. If the option is set to `anywhere`, then all +exits are valid. + +All valid connections for portal shuffle can be found by scrolling through the [portals module](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/messenger/portals.py#L12). +The entrance and exit should be written exactly as they appear within that file, except for when the **exit** point is a +portal. In that case, it should have "Portal" included. + +### Example + +```yaml +The Messenger: + portal_plando: + - entrance: Riviere Turquoise + exit: Wingsuit + - entrance: Sunken Shrine + exit: Sunny Day + - entrance: Searing Crags + exit: Glacial Peak Portal +``` + +This block will make it so that the Riviere Turquoise Portal will exit to the Wingsuit Shop, the Sunken Shrine Portal +will exit to the Sunny Day checkpoint, and the Searing Crags Portal will exit to the Glacial Peak Portal. + +## Transition Plando + +This option allows you to specify certain connections when using transition shuffle. This will only work if +transition shuffle and the `connections` plando host setting are enabled. + +Each transition connection is plandoed by specifying its attributes: + +* `entrance` is where you will enter this transition from. +* `exit` is where the transition will lead. +* `percentage` is the chance this connection will happen at all. +* `direction` is used to specify whether this connection will also go in reverse. This entry will be ignored if the + transition shuffle is set to `coupled` or if the specified connection can only occur in one direction, such as exiting + to Riviere Turquoise. The default direction is "both", which will make it so that returning through the exit + transition will return you to where you entered it from. "entrance" and "exit" are treated the same, with them both + making this transition only one-way. + +Valid connections can be found in the [`RANDOMIZED_CONNECTIONS` dictionary](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/messenger/connections.py#L640). +The keys (left) are entrances, and values (right) are exits. Whether you want the connection to go both ways or not, +both sides must either be two-way or one-way; E.g. connecting Artificer (Corrupted Future Portal) to one of the +Quillshroom Marsh entrances is not a valid pairing. A pairing can be determined to be two-way if both the entrance and +exit of that pair are an exit and entrance of another pairing, respectively. + +### Example + +```yaml +The Messenger: + plando_connections: + - entrance: Searing Crags - Top + exit: Dark Cave - Right + - entrance: Glacial Peak - Left + exit: Corrupted Future +``` + +This block will create the following connections: +1. Leaving Searing Crags towards Glacial Peak will take you to the beginning of Dark Cave, and leaving the Dark Cave + door will return you to the top of Searing Crags. +2. Taking Manfred to leave Glacial Peak, will take you to Corrupted Future. There is no reverse connection here so it + will always be one-way. diff --git a/worlds/messenger/options.py b/worlds/messenger/options.py index aaf152fbf8c3..6b04118893b1 100644 --- a/worlds/messenger/options.py +++ b/worlds/messenger/options.py @@ -16,17 +16,8 @@ class MessengerAccessibility(ItemsAccessibility): class PortalPlando(PlandoConnections): """ - Plando connections to be used with portal shuffle. Direction is ignored. - List of valid connections can be found here: https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/messenger/portals.py#L12. - The entering Portal should *not* have "Portal" appended. - For the exits, those in checkpoints and shops should just be the name of the spot, while portals should have " Portal" at the end. - Example: - - entrance: Riviere Turquoise - exit: Wingsuit - - entrance: Sunken Shrine - exit: Sunny Day - - entrance: Searing Crags - exit: Glacial Peak Portal + Plando connections to be used with portal shuffle. + Documentation on using this can be found in The Messenger plando guide. """ display_name = "Portal Plando Connections" portals = [f"{portal} Portal" for portal in PORTALS] @@ -40,14 +31,7 @@ class PortalPlando(PlandoConnections): class TransitionPlando(PlandoConnections): """ Plando connections to be used with transition shuffle. - List of valid connections can be found at https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/messenger/connections.py#L641. - Dictionary keys (left) are entrances and values (right) are exits. If transition shuffle is on coupled all plando - connections will be coupled. If on decoupled, "entrance" and "exit" will be treated the same, simply making the - plando connection one-way from entrance to exit. - Example: - - entrance: Searing Crags - Top - exit: Dark Cave - Right - direction: both + Documentation on using this can be found in The Messenger plando guide. """ display_name = "Transition Plando Connections" entrances = frozenset(RANDOMIZED_CONNECTIONS.keys()) From 1fd8e4435ec46c8c03140804ba5a7a323e1850e4 Mon Sep 17 00:00:00 2001 From: Carter Hesterman Date: Thu, 10 Apr 2025 11:19:03 -0600 Subject: [PATCH 0307/1218] Civ 6: Update setup documentation to account for common pitfalls (#4797) --- worlds/civ_6/docs/en_Civilization VI.md | 2 +- worlds/civ_6/docs/setup_en.md | 11 +++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/worlds/civ_6/docs/en_Civilization VI.md b/worlds/civ_6/docs/en_Civilization VI.md index 3b1fbbdb055a..215da00aa4fb 100644 --- a/worlds/civ_6/docs/en_Civilization VI.md +++ b/worlds/civ_6/docs/en_Civilization VI.md @@ -51,7 +51,7 @@ Boosts have logic associated with them in order to verify you can always reach t - I need to kill a unit with a slinger/archer/musketman or some other obsolete unit I can't build anymore, how can I do this? - Don't forget you can go into the Tech Tree and click on a Vanilla tech you've received in order to toggle it on/off. This is necessary in order to pursue some of the boosts if you receive techs in certain orders. - Something happened, and I'm not able to unlock the boost due to game rules! - - A few scenarios you may worry about: "Found a religion", "Make an alliance with another player", "Develop an alliance to level 2", "Build a wonder from X Era", to name a few. Any boost that is "miss-able" has been flagged as an "Excluded" location and will not ever receive a progression item. For a list of how each boost is flagged, take a look [here](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/civ_6/data/boosts.json). + - A few scenarios you may worry about: "Found a religion", "Make an alliance with another player", "Develop an alliance to level 2", "Build a wonder from X Era", to name a few. Any boost that is "miss-able" has been flagged as an "Excluded" location and will not ever receive a progression item. For a list of how each boost is flagged, take a look [here](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/civ_6/data/boosts.py). - I'm worried that my `PROGRESSIVE_ERA` item is going to be stuck in a boost I won't have time to complete before my maximum unlocked era ends! - The unpredictable timing of boosts and unlocking them can occasionally lead to scenarios where you'll have to first encounter a locked era defeat and then load a previous save. To help reduce the frequency of this, local `PROGRESSIVE_ERA` items will never be located at a boost check. - There's too many boosts, how will I know which one's I should focus on?! diff --git a/worlds/civ_6/docs/setup_en.md b/worlds/civ_6/docs/setup_en.md index 09f6ff55c5e0..9cf4744b6596 100644 --- a/worlds/civ_6/docs/setup_en.md +++ b/worlds/civ_6/docs/setup_en.md @@ -14,22 +14,17 @@ The following are required in order to play Civ VI in Archipelago: ## Enabling the tuner -Depending on how you installed Civ 6 you will have to navigate to one of the following: - -- `YOUR_USER/Documents/My Games/Sid Meier's Civilization VI/AppOptions.txt` -- `YOUR_USER/AppData/Local/Firaxis Games/Sid Meier's Civilization VI/AppOptions.txt` - -Once you have located your `AppOptions.txt`, do a search for `Enable FireTuner`. Set `EnableTuner` to `1` instead of `0`. **NOTE**: While this is active, achievements will be disabled. +In the main menu, navigate to the "Game Options" page. On the "Game" menu, make sure that "Tuner (disables achievements)" is enabled. ## Mod Installation 1. Download and unzip the latest release of the mod from [GitHub](https://github.com/hesto2/civilization_archipelago_mod/releases/latest). -2. Copy the folder containing the mod files to your Civ VI mods folder. On Windows, this is usually located at `C:\Users\YOUR_USER\Documents\My Games\Sid Meier's Civilization VI\Mods`. +2. Copy the folder containing the mod files to your Civ VI mods folder. On Windows, this is usually located at `C:\Users\YOUR_USER\Documents\My Games\Sid Meier's Civilization VI\Mods`. If you use OneDrive, check if the folder is instead located in your OneDrive file structure. 3. After the Archipelago host generates a game, you should be given a `.apcivvi` file. Associate the file with the Archipelago Launcher and double click it. -4. Copy the contents of the new folder it generates (it will have the same name as the `.apcivvi` file) into your Civilization VI Archipelago Mod folder. +4. Copy the contents of the new folder it generates (it will have the same name as the `.apcivvi` file) into your Civilization VI Archipelago Mod folder. If double clicking the `.apcivvi` file doesn't generate a folder, you can just rename it to a file ending with `.zip` and extract its contents to a new folder. To do this, right click the `.apcivvi` file and click "Rename", make sure it ends in `.zip`, then right click it again and select "Extract All". 5. Your finished mod folder should look something like this: From 934b09238ea5f0ce7b699c902cd95123e5a9a152 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Thu, 10 Apr 2025 13:21:33 -0400 Subject: [PATCH 0308/1218] Docs: Update to adding games.md (#4816) --- docs/adding games.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/adding games.md b/docs/adding games.md index fbbd7988595d..2decb667b76d 100644 --- a/docs/adding games.md +++ b/docs/adding games.md @@ -60,7 +60,7 @@ These are "nice to have" features for a client, but they are not strictly requir if possible. * If your client appears in the Archipelago Launcher, you may define an icon for it that differentiates it from - other clients. The icon size is 38x38 pixels, but it will accept larger images with downscaling. + other clients. The icon size is 48x48 pixels, but smaller or larger images will scale to that size. ## World @@ -109,6 +109,10 @@ subclass for webhost documentation and behaviors * A non-zero number of locations, added to your regions * A non-zero number of items **equal** to the number of locations, added to the multiworld itempool * In rare cases, there may be 0-location-0-item games, but this is extremely atypical. +* A set + [completion condition](https://github.com/ArchipelagoMW/Archipelago/blob/main/BaseClasses.py#L77) (aka "goal") for + the player. + * Use your player as the index (`multiworld.completion_condition[player]`) for your world's completion goal. ### Encouraged Features @@ -145,8 +149,8 @@ workarounds or preferred methods which should be used instead: * It is discouraged to use `yaml.load` directly due to security concerns. * When possible, use `Utils.yaml_load` instead, as this defaults to the safe loader. * When submitting regions or items to the multiworld (`multiworld.regions` and `multiworld.itempool` respectively), - Do **not** use `=` as this will overwrite all elements for all games in the seed. - * Instead, use `append`, `extend`, or `+=`. + do **not** use `=` as this will overwrite all elements for all games in the seed. + * Instead, use `append`, `extend`, or `+=`. ### Notable Caveats From 879d7c23b796ce281354add5be4211bd27852796 Mon Sep 17 00:00:00 2001 From: qwint Date: Thu, 10 Apr 2025 13:18:43 -0500 Subject: [PATCH 0309/1218] HK: Workaround for NamedRange webhost bug (#4819) --- worlds/hk/Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/hk/Options.py b/worlds/hk/Options.py index e76e7eba9d16..fbfdbfa871e0 100644 --- a/worlds/hk/Options.py +++ b/worlds/hk/Options.py @@ -450,7 +450,7 @@ class GrubHuntGoal(NamedRange): display_name = "Grub Hunt Goal" range_start = 1 range_end = 46 - special_range_names = {"all": -1} + special_range_names = {"all": -1, "forty_six": 46} default = 46 From ee471a48bd443b3663100efa6044dce88bfc3679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Thu, 10 Apr 2025 14:34:21 -0400 Subject: [PATCH 0310/1218] Stardew Valley: Fix some determinism issues with entrance rando when playing with mods (#4812) --- worlds/stardew_valley/content/__init__.py | 2 +- worlds/stardew_valley/region_classes.py | 2 +- worlds/stardew_valley/regions.py | 5 ++--- .../stardew_valley/test/stability/StabilityOutputScript.py | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/worlds/stardew_valley/content/__init__.py b/worlds/stardew_valley/content/__init__.py index 33608531d952..5f7d4a5fc567 100644 --- a/worlds/stardew_valley/content/__init__.py +++ b/worlds/stardew_valley/content/__init__.py @@ -21,7 +21,7 @@ def choose_content_packs(player_options: options.StardewValleyOptions): if player_options.special_order_locations & options.SpecialOrderLocations.value_qi: active_packs.append(content_packs.qi_board_content_pack) - for mod in player_options.mods.value: + for mod in sorted(player_options.mods.value): active_packs.append(content_packs.by_mod[mod]) return active_packs diff --git a/worlds/stardew_valley/region_classes.py b/worlds/stardew_valley/region_classes.py index bd64518ea153..d3d16e3878bb 100644 --- a/worlds/stardew_valley/region_classes.py +++ b/worlds/stardew_valley/region_classes.py @@ -34,7 +34,7 @@ def get_merged_with(self, exits: List[str]): merged_exits.extend(self.exits) if exits is not None: merged_exits.extend(exits) - merged_exits = list(set(merged_exits)) + merged_exits = sorted(set(merged_exits)) return RegionData(self.name, merged_exits, is_ginger_island=self.is_ginger_island) def get_without_exits(self, exits_to_remove: Set[str]): diff --git a/worlds/stardew_valley/regions.py b/worlds/stardew_valley/regions.py index 7a680d5faad0..d5be53ba866c 100644 --- a/worlds/stardew_valley/regions.py +++ b/worlds/stardew_valley/regions.py @@ -521,7 +521,7 @@ def create_final_regions(world_options) -> List[RegionData]: final_regions.extend(vanilla_regions) if world_options.mods is None: return final_regions - for mod in world_options.mods.value: + for mod in sorted(world_options.mods.value): if mod not in ModDataList: continue for mod_region in ModDataList[mod].regions: @@ -747,8 +747,7 @@ def swap_one_random_connection(regions_by_name, connections_by_name, randomized_ randomized_connections_already_shuffled = {connection: randomized_connections[connection] for connection in randomized_connections if connection != randomized_connections[connection]} - unreachable_regions_names_leading_somewhere = tuple([region for region in unreachable_regions - if len(regions_by_name[region].exits) > 0]) + unreachable_regions_names_leading_somewhere = [region for region in sorted(unreachable_regions) if len(regions_by_name[region].exits) > 0] unreachable_regions_leading_somewhere = [regions_by_name[region_name] for region_name in unreachable_regions_names_leading_somewhere] unreachable_regions_exits_names = [exit_name for region in unreachable_regions_leading_somewhere for exit_name in region.exits] unreachable_connections = [connections_by_name[exit_name] for exit_name in unreachable_regions_exits_names] diff --git a/worlds/stardew_valley/test/stability/StabilityOutputScript.py b/worlds/stardew_valley/test/stability/StabilityOutputScript.py index a5385362b7bc..9b4b608d4e0d 100644 --- a/worlds/stardew_valley/test/stability/StabilityOutputScript.py +++ b/worlds/stardew_valley/test/stability/StabilityOutputScript.py @@ -2,7 +2,7 @@ import json from .. import setup_solo_multiworld -from ..options.presets import allsanity_mods_6_x_x +from ..options.presets import allsanity_mods_6_x_x_exclude_disabled from ...options import FarmType, EntranceRandomization if __name__ == "__main__": @@ -12,7 +12,7 @@ args = parser.parse_args() seed = args.seed - options = allsanity_mods_6_x_x() + options = allsanity_mods_6_x_x_exclude_disabled() options[FarmType.internal_name] = FarmType.option_standard options[EntranceRandomization.internal_name] = EntranceRandomization.option_buildings multi_world = setup_solo_multiworld(options, seed=seed) From 6a9299018c7829f5ac922ed0805ccc9e1bb521e2 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Fri, 11 Apr 2025 02:17:28 +0100 Subject: [PATCH 0311/1218] MLSS: Fix generation error with emblem hunt and no digspots (#4859) --- worlds/mlss/Rules.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/worlds/mlss/Rules.py b/worlds/mlss/Rules.py index 6592a805d56a..848f00cb63b7 100644 --- a/worlds/mlss/Rules.py +++ b/worlds/mlss/Rules.py @@ -148,12 +148,13 @@ def set_rules(world: "MLSSWorld", excluded): and StateLogic.canDash(state, world.player) and StateLogic.canCrash(state, world.player) ) - add_rule( - world.get_location(LocationName.BowsersCastleWendyLarryHallwayDigspot), - lambda state: StateLogic.ultra(state, world.player) - and StateLogic.fire(state, world.player) - and StateLogic.canCrash(state, world.player) - ) + if world.options.chuckle_beans != 0: + add_rule( + world.get_location(LocationName.BowsersCastleWendyLarryHallwayDigspot), + lambda state: StateLogic.ultra(state, world.player) + and StateLogic.fire(state, world.player) + and StateLogic.canCrash(state, world.player) + ) add_rule( world.get_location(LocationName.BowsersCastleBeforeFawfulFightBlock1), lambda state: StateLogic.canDig(state, world.player) From f263a0bc912755b40024a45bd971a290afe6cbc4 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 10 Apr 2025 18:18:49 -0700 Subject: [PATCH 0312/1218] DS3: Mark a lizard location that was previously not annotated (#4860) --- worlds/dark_souls_3/Locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index cc202c76e8be..c5cdbba85d82 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -930,7 +930,7 @@ def __init__( "Great Swamp Ring", miniboss=True), # Giant Crab drop DS3LocationData("RS: Blue Sentinels - Horace", "Blue Sentinels", missable=True, npc=True), # Horace quest - DS3LocationData("RS: Crystal Gem - stronghold, lizard", "Crystal Gem"), + DS3LocationData("RS: Crystal Gem - stronghold, lizard", "Crystal Gem", lizard=True), DS3LocationData("RS: Fading Soul - woods by Crucifixion Woods bonfire", "Fading Soul", static='03,0:53300210::'), From a324c9781541563bde9885c4d7715b89b5e96f63 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 11 Apr 2025 20:52:20 +0200 Subject: [PATCH 0313/1218] Factorio: fix FloatRanges writing effectively nil into the mod (#4846) --- worlds/factorio/Options.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/worlds/factorio/Options.py b/worlds/factorio/Options.py index 481ed00987f2..12fc90c1fd15 100644 --- a/worlds/factorio/Options.py +++ b/worlds/factorio/Options.py @@ -8,17 +8,20 @@ from Options import Choice, OptionDict, OptionSet, DefaultOnToggle, Range, DeathLink, Toggle, \ StartInventoryPool, PerGameCommonOptions, OptionGroup + # schema helpers class FloatRange: def __init__(self, low, high): self._low = low self._high = high - def validate(self, value): + def validate(self, value) -> float: if not isinstance(value, (float, int)): raise SchemaError(f"should be instance of float or int, but was {value!r}") if not self._low <= value <= self._high: raise SchemaError(f"{value} is not between {self._low} and {self._high}") + return float(value) + LuaBool = Or(bool, And(int, lambda n: n in (0, 1))) From b7b5bf58aa16cae9926f66613db4c7f3d0aa2d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Fri, 11 Apr 2025 20:19:17 -0400 Subject: [PATCH 0314/1218] Stardew Valley: Use classvar_matrix to split tests (#4762) * Unroll tests for better parallelization * fix ut test * self review * bro it's the second time today I have to commit some garbage to have a github action rerun because messenger fails what is this * my god can the tests plz pass * code reviews * code reviews * move TestRandomWorlds out of long module --- worlds/stardew_valley/test/TestOptions.py | 95 ++++++++-------- .../stardew_valley/test/TestRandomWorlds.py | 29 +++++ worlds/stardew_valley/test/__init__.py | 59 +++++----- .../stardew_valley/test/long/TestModsLong.py | 103 ++++++++++-------- .../test/long/TestOptionsLong.py | 48 ++++---- .../test/long/TestPreRolledRandomness.py | 37 ++++--- .../test/long/TestRandomWorlds.py | 86 --------------- .../stardew_valley/test/long/option_names.py | 30 ----- worlds/stardew_valley/test/mods/TestMods.py | 102 +++++++---------- .../test/options/option_names.py | 51 +++++++++ .../test/stability/TestUniversalTracker.py | 7 +- 11 files changed, 300 insertions(+), 347 deletions(-) create mode 100644 worlds/stardew_valley/test/TestRandomWorlds.py delete mode 100644 worlds/stardew_valley/test/long/TestRandomWorlds.py delete mode 100644 worlds/stardew_valley/test/long/option_names.py create mode 100644 worlds/stardew_valley/test/options/option_names.py diff --git a/worlds/stardew_valley/test/TestOptions.py b/worlds/stardew_valley/test/TestOptions.py index 9d9af04a4ee8..4894ea55f241 100644 --- a/worlds/stardew_valley/test/TestOptions.py +++ b/worlds/stardew_valley/test/TestOptions.py @@ -1,12 +1,13 @@ import itertools +from typing import ClassVar from BaseClasses import ItemClassification -from Options import NamedRange +from test.param import classvar_matrix from . import SVTestCase, solo_multiworld, SVTestBase from .assertion import WorldAssertMixin -from .long.option_names import all_option_choices +from .options.option_names import all_option_choices from .options.presets import allsanity_no_mods_6_x_x, allsanity_mods_6_x_x -from .. import items_by_group, Group, StardewValleyWorld +from .. import items_by_group, Group from ..locations import locations_by_tag, LocationTags, location_table from ..options import ExcludeGingerIsland, ToolProgression, Goal, SeasonRandomization, TrapItems, SpecialOrderLocations, ArcadeMachineLocations from ..strings.goal_names import Goal as GoalName @@ -18,42 +19,36 @@ TOOLS = {"Hoe", "Pickaxe", "Axe", "Watering Can", "Trash Can", "Fishing Rod"} +@classvar_matrix(option_and_choice=all_option_choices) class TestGenerateDynamicOptions(WorldAssertMixin, SVTestCase): - def test_given_special_range_when_generate_then_basic_checks(self): - options = StardewValleyWorld.options_dataclass.type_hints - for option_name, option in options.items(): - if not issubclass(option, NamedRange): - continue - for value in option.special_range_names: - world_options = {option_name: option.special_range_names[value]} - with self.solo_world_sub_test(f"{option_name}: {value}", world_options) as (multiworld, _): - self.assert_basic_checks(multiworld) - - def test_given_choice_when_generate_then_basic_checks(self): - options = StardewValleyWorld.options_dataclass.type_hints - for option_name, option in options.items(): - if not option.options: - continue - for value in option.options: - world_options = {option_name: option.options[value]} - with self.solo_world_sub_test(f"{option_name}: {value}", world_options) as (multiworld, _): - self.assert_basic_checks(multiworld) - - + option_and_choice: ClassVar[tuple[str, str]] + + def test_given_option_and_choice_when_generate_then_basic_checks(self): + option, choice = self.option_and_choice + world_options = {option: choice} + with solo_multiworld(world_options) as (multiworld, stardew_world): + self.assert_basic_checks(multiworld) + + +@classvar_matrix(goal_and_location=[ + ("community_center", GoalName.community_center), + ("grandpa_evaluation", GoalName.grandpa_evaluation), + ("bottom_of_the_mines", GoalName.bottom_of_the_mines), + ("cryptic_note", GoalName.cryptic_note), + ("master_angler", GoalName.master_angler), + ("complete_collection", GoalName.complete_museum), + ("full_house", GoalName.full_house), + ("perfection", GoalName.perfection), +]) class TestGoal(SVTestCase): + goal_and_location: ClassVar[tuple[str, str]] + def test_given_goal_when_generate_then_victory_is_in_correct_location(self): - for goal, location in [("community_center", GoalName.community_center), - ("grandpa_evaluation", GoalName.grandpa_evaluation), - ("bottom_of_the_mines", GoalName.bottom_of_the_mines), - ("cryptic_note", GoalName.cryptic_note), - ("master_angler", GoalName.master_angler), - ("complete_collection", GoalName.complete_museum), - ("full_house", GoalName.full_house), - ("perfection", GoalName.perfection)]: - world_options = {Goal.internal_name: Goal.options[goal]} - with self.solo_world_sub_test(f"Goal: {goal}, Location: {location}", world_options) as (multi_world, _): - victory = multi_world.find_item("Victory", 1) - self.assertEqual(victory.name, location) + goal, location = self.goal_and_location + world_options = {Goal.internal_name: goal} + with solo_multiworld(world_options) as (multi_world, _): + victory = multi_world.find_item("Victory", 1) + self.assertEqual(victory.name, location) class TestSeasonRandomization(SVTestCase): @@ -104,26 +99,28 @@ def test_given_progressive_when_generate_then_only_3_trash_can_are_progressive(s self.assertEqual(useful_count, 1) +@classvar_matrix(option_and_choice=all_option_choices) class TestGenerateAllOptionsWithExcludeGingerIsland(WorldAssertMixin, SVTestCase): + option_and_choice: ClassVar[tuple[str, str]] def test_given_choice_when_generate_exclude_ginger_island_then_ginger_island_is_properly_excluded(self): - for option, option_choice in all_option_choices: - if option is ExcludeGingerIsland: - continue + option, option_choice = self.option_and_choice - world_options = { - ExcludeGingerIsland: ExcludeGingerIsland.option_true, - option: option_choice - } + if option == ExcludeGingerIsland.internal_name: + self.skipTest("ExcludeGingerIsland is forced to true") - with self.solo_world_sub_test(f"{option.internal_name}: {option_choice}", world_options) as (multiworld, stardew_world): + world_options = { + ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_true, + option: option_choice + } - # Some options, like goals, will force Ginger island back in the game. We want to skip testing those. - if stardew_world.options.exclude_ginger_island != ExcludeGingerIsland.option_true: - continue + with solo_multiworld(world_options) as (multiworld, stardew_world): + + if stardew_world.options.exclude_ginger_island != ExcludeGingerIsland.option_true: + self.skipTest("Some options, like goals, will force Ginger island back in the game. We want to skip testing those.") - self.assert_basic_checks(multiworld) - self.assert_no_ginger_island_content(multiworld) + self.assert_basic_checks(multiworld) + self.assert_no_ginger_island_content(multiworld) class TestTraps(SVTestCase): diff --git a/worlds/stardew_valley/test/TestRandomWorlds.py b/worlds/stardew_valley/test/TestRandomWorlds.py new file mode 100644 index 000000000000..550ae14b5520 --- /dev/null +++ b/worlds/stardew_valley/test/TestRandomWorlds.py @@ -0,0 +1,29 @@ +from typing import ClassVar + +from BaseClasses import MultiWorld, get_seed +from test.param import classvar_matrix +from . import SVTestCase, skip_long_tests, solo_multiworld +from .assertion import GoalAssertMixin, OptionAssertMixin, WorldAssertMixin +from .options.option_names import generate_random_world_options + + +@classvar_matrix(n=range(10 if skip_long_tests() else 1000)) +class TestGenerateManyWorlds(GoalAssertMixin, OptionAssertMixin, WorldAssertMixin, SVTestCase): + n: ClassVar[int] + + def test_generate_many_worlds_then_check_results(self): + seed = get_seed() + world_options = generate_random_world_options(seed + self.n) + + print(f"Generating solo multiworld with seed {seed} for Stardew Valley...") + with solo_multiworld(world_options, seed=seed, world_caching=False) as (multiworld, _): + self.assert_multiworld_is_valid(multiworld) + + def assert_multiworld_is_valid(self, multiworld: MultiWorld): + self.assert_victory_exists(multiworld) + self.assert_same_number_items_locations(multiworld) + self.assert_goal_world_is_valid(multiworld) + self.assert_can_reach_island_if_should(multiworld) + self.assert_cropsanity_same_number_items_and_locations(multiworld) + self.assert_festivals_give_access_to_deluxe_scarecrow(multiworld) + self.assert_has_festival_recipes(multiworld) diff --git a/worlds/stardew_valley/test/__init__.py b/worlds/stardew_valley/test/__init__.py index 800b21057626..702f590221f5 100644 --- a/worlds/stardew_valley/test/__init__.py +++ b/worlds/stardew_valley/test/__init__.py @@ -22,21 +22,19 @@ logger.info(f"Default Test Seed: {DEFAULT_TEST_SEED}") -class SVTestCase(unittest.TestCase): - # Set False to not skip some 'extra' tests - skip_base_tests: bool = True - # Set False to run tests that take long - skip_long_tests: bool = True +def skip_default_tests() -> bool: + return not bool(os.environ.get("base", False)) - @classmethod - def setUpClass(cls) -> None: - super().setUpClass() - base_tests_key = "base" - if base_tests_key in os.environ: - cls.skip_base_tests = not bool(os.environ[base_tests_key]) - long_tests_key = "long" - if long_tests_key in os.environ: - cls.skip_long_tests = not bool(os.environ[long_tests_key]) + +def skip_long_tests() -> bool: + return not bool(os.environ.get("long", False)) + + +class SVTestCase(unittest.TestCase): + skip_default_tests: bool = skip_default_tests() + """Set False to not skip the base fill tests""" + skip_long_tests: bool = skip_long_tests() + """Set False to run tests that take long""" @contextmanager def solo_world_sub_test(self, msg: Optional[str] = None, @@ -94,7 +92,7 @@ def tearDown(self) -> None: @property def run_default_tests(self) -> bool: - if self.skip_base_tests: + if self.skip_default_tests: return False return super().run_default_tests @@ -196,21 +194,22 @@ def solo_multiworld(world_options: Optional[Dict[Union[str, StardewValleyOption] yield multiworld, multiworld.worlds[1] else: multiworld = setup_solo_multiworld(world_options, seed) - multiworld.lock.acquire() - world = multiworld.worlds[1] - - original_state = multiworld.state.copy() - original_itempool = multiworld.itempool.copy() - unfilled_locations = multiworld.get_unfilled_locations(1) - - yield multiworld, world - - multiworld.state = original_state - multiworld.itempool = original_itempool - for location in unfilled_locations: - location.item = None - - multiworld.lock.release() + try: + multiworld.lock.acquire() + world = multiworld.worlds[1] + + original_state = multiworld.state.copy() + original_itempool = multiworld.itempool.copy() + unfilled_locations = multiworld.get_unfilled_locations(1) + + yield multiworld, world + + multiworld.state = original_state + multiworld.itempool = original_itempool + for location in unfilled_locations: + location.item = None + finally: + multiworld.lock.release() # Mostly a copy of test.general.setup_solo_multiworld, I just don't want to change the core. diff --git a/worlds/stardew_valley/test/long/TestModsLong.py b/worlds/stardew_valley/test/long/TestModsLong.py index 395c48ee698a..bc5e8bfff8ac 100644 --- a/worlds/stardew_valley/test/long/TestModsLong.py +++ b/worlds/stardew_valley/test/long/TestModsLong.py @@ -1,69 +1,84 @@ import unittest -from itertools import combinations, product +from itertools import combinations +from typing import ClassVar from BaseClasses import get_seed -from .option_names import all_option_choices, get_option_choices -from .. import SVTestCase +from test.param import classvar_matrix +from .. import SVTestCase, solo_multiworld, skip_long_tests from ..assertion import WorldAssertMixin, ModAssertMixin +from ..options.option_names import all_option_choices from ... import options from ...mods.mod_data import ModNames +from ...options.options import all_mods -assert unittest +@unittest.skip +class TestTroubleshootMods(WorldAssertMixin, ModAssertMixin, SVTestCase): + def test_troubleshoot_option(self): + seed = get_seed(78709133382876990000) -class TestGenerateModsOptions(WorldAssertMixin, ModAssertMixin, SVTestCase): + world_options = { + options.EntranceRandomization: options.EntranceRandomization.option_buildings, + options.Mods: ModNames.sve + } + + with self.solo_world_sub_test(world_options=world_options, seed=seed, world_caching=False) as (multiworld, _): + self.assert_basic_checks(multiworld) + self.assert_stray_mod_items(world_options[options.Mods], multiworld) + + +if skip_long_tests(): + raise unittest.SkipTest("Long tests disabled") - @classmethod - def setUpClass(cls) -> None: - super().setUpClass() - if cls.skip_long_tests: - raise unittest.SkipTest("Long tests disabled") + +@classvar_matrix(mod_pair=combinations(sorted(all_mods), 2)) +class TestGenerateModsPairs(WorldAssertMixin, ModAssertMixin, SVTestCase): + mod_pair: ClassVar[tuple[str, str]] def test_given_mod_pairs_when_generate_then_basic_checks(self): - for mod_pair in combinations(options.Mods.valid_keys, 2): - world_options = { - options.Mods: frozenset(mod_pair) - } + world_options = { + options.Mods.internal_name: frozenset(self.mod_pair) + } + + with solo_multiworld(world_options, world_caching=False) as (multiworld, _): + self.assert_basic_checks(multiworld) + self.assert_stray_mod_items(list(self.mod_pair), multiworld) - with self.solo_world_sub_test(f"Mods: {mod_pair}", world_options, world_caching=False) as (multiworld, _): - self.assert_basic_checks(multiworld) - self.assert_stray_mod_items(list(mod_pair), multiworld) + +@classvar_matrix(mod=all_mods, option_and_choice=all_option_choices) +class TestGenerateModAndOptionChoice(WorldAssertMixin, ModAssertMixin, SVTestCase): + mod: ClassVar[str] + option_and_choice: ClassVar[tuple[str, str]] def test_given_mod_names_when_generate_paired_with_other_options_then_basic_checks(self): - for mod, (option, value) in product(options.Mods.valid_keys, all_option_choices): - world_options = { - option: value, - options.Mods: mod - } + option, choice = self.option_and_choice - with self.solo_world_sub_test(f"{option.internal_name}: {value}, Mod: {mod}", world_options, world_caching=False) as (multiworld, _): - self.assert_basic_checks(multiworld) - self.assert_stray_mod_items(mod, multiworld) + world_options = { + option: choice, + options.Mods.internal_name: self.mod + } - def test_given_no_quest_all_mods_when_generate_with_all_goals_then_basic_checks(self): - for goal, (option, value) in product(get_option_choices(options.Goal), all_option_choices): - if option is options.QuestLocations: - continue + with solo_multiworld(world_options, world_caching=False) as (multiworld, _): + self.assert_basic_checks(multiworld) + self.assert_stray_mod_items(self.mod, multiworld) - world_options = { - options.Goal: goal, - option: value, - options.QuestLocations: -1, - options.Mods: frozenset(options.Mods.valid_keys), - } - with self.solo_world_sub_test(f"Goal: {goal}, {option.internal_name}: {value}", world_options, world_caching=False) as (multiworld, _): - self.assert_basic_checks(multiworld) +@classvar_matrix(goal=options.Goal.options.keys(), option_and_choice=all_option_choices) +class TestGenerateAllGoalAndAllOptionWithAllModsWithoutQuest(WorldAssertMixin, ModAssertMixin, SVTestCase): + goal = ClassVar[str] + option_and_choice = ClassVar[tuple[str, str]] - @unittest.skip - def test_troubleshoot_option(self): - seed = get_seed(78709133382876990000) + def test_given_no_quest_all_mods_when_generate_with_all_goals_then_basic_checks(self): + option, choice = self.option_and_choice + if option == options.QuestLocations.internal_name: + self.skipTest("QuestLocations are disabled") world_options = { - options.EntranceRandomization: options.EntranceRandomization.option_buildings, - options.Mods: ModNames.sve + options.Goal.internal_name: self.goal, + option: choice, + options.QuestLocations.internal_name: -1, + options.Mods.internal_name: frozenset(options.Mods.valid_keys), } - with self.solo_world_sub_test(world_options=world_options, seed=seed, world_caching=False) as (multiworld, _): + with solo_multiworld(world_options, world_caching=False) as (multiworld, _): self.assert_basic_checks(multiworld) - self.assert_stray_mod_items(world_options[options.Mods], multiworld) diff --git a/worlds/stardew_valley/test/long/TestOptionsLong.py b/worlds/stardew_valley/test/long/TestOptionsLong.py index 81bb4d1f30ee..db467964e7c4 100644 --- a/worlds/stardew_valley/test/long/TestOptionsLong.py +++ b/worlds/stardew_valley/test/long/TestOptionsLong.py @@ -1,34 +1,16 @@ import unittest from itertools import combinations +from typing import ClassVar from BaseClasses import get_seed -from .option_names import all_option_choices -from .. import SVTestCase, solo_multiworld +from test.param import classvar_matrix +from .. import SVTestCase, solo_multiworld, skip_long_tests from ..assertion.world_assert import WorldAssertMixin +from ..options.option_names import all_option_choices from ... import options -class TestGenerateDynamicOptions(WorldAssertMixin, SVTestCase): - def test_given_option_pair_when_generate_then_basic_checks(self): - if self.skip_long_tests: - raise unittest.SkipTest("Long tests disabled") - - for (option1, option1_choice), (option2, option2_choice) in combinations(all_option_choices, 2): - if option1 is option2: - continue - - world_options = { - option1: option1_choice, - option2: option2_choice - } - - with self.solo_world_sub_test(f"{option1.internal_name}: {option1_choice}, {option2.internal_name}: {option2_choice}", - world_options, - world_caching=False) \ - as (multiworld, _): - self.assert_basic_checks(multiworld) - - +@unittest.skip class TestDynamicOptionDebug(WorldAssertMixin, SVTestCase): def test_option_pair_debug(self): @@ -42,3 +24,23 @@ def test_option_pair_debug(self): print(f"Seed: {seed}") with solo_multiworld(option_dict, seed=seed) as (multiworld, _): self.assert_basic_checks(multiworld) + + +if skip_long_tests(): + raise unittest.SkipTest("Long tests disabled") + + +@classvar_matrix(options_and_choices=combinations(all_option_choices, 2)) +class TestGenerateDynamicOptions(WorldAssertMixin, SVTestCase): + options_and_choices: ClassVar[tuple[tuple[str, str], tuple[str, str]]] + + def test_given_option_pair_when_generate_then_basic_checks(self): + (option1, option1_choice), (option2, option2_choice) = self.options_and_choices + + world_options = { + option1: option1_choice, + option2: option2_choice + } + + with solo_multiworld(world_options, world_caching=False) as (multiworld, _): + self.assert_basic_checks(multiworld) diff --git a/worlds/stardew_valley/test/long/TestPreRolledRandomness.py b/worlds/stardew_valley/test/long/TestPreRolledRandomness.py index f233fc36dc84..3b6f818ec43c 100644 --- a/worlds/stardew_valley/test/long/TestPreRolledRandomness.py +++ b/worlds/stardew_valley/test/long/TestPreRolledRandomness.py @@ -1,28 +1,29 @@ import unittest +from typing import ClassVar from BaseClasses import get_seed -from .. import SVTestCase +from test.param import classvar_matrix +from .. import SVTestCase, solo_multiworld, skip_long_tests from ..assertion import WorldAssertMixin from ... import options +if skip_long_tests(): + raise unittest.SkipTest("Long tests disabled") +player_options = { + options.EntranceRandomization.internal_name: options.EntranceRandomization.option_buildings, + options.BundleRandomization.internal_name: options.BundleRandomization.option_remixed, + options.BundlePrice.internal_name: options.BundlePrice.option_maximum +} + + +@classvar_matrix(n=range(1000)) class TestGeneratePreRolledRandomness(WorldAssertMixin, SVTestCase): - def test_given_pre_rolled_difficult_randomness_when_generate_then_basic_checks(self): - if self.skip_long_tests: - raise unittest.SkipTest("Long tests disabled") + n: ClassVar[int] - choices = { - options.EntranceRandomization.internal_name: options.EntranceRandomization.option_buildings, - options.BundleRandomization.internal_name: options.BundleRandomization.option_remixed, - options.BundlePrice.internal_name: options.BundlePrice.option_maximum - } + def test_given_pre_rolled_difficult_randomness_when_generate_then_basic_checks(self): + seed = get_seed() - num_tests = 1000 - for i in range(num_tests): - seed = get_seed() # Put seed in parameter to test - with self.solo_world_sub_test(f"Entrance Randomizer and Remixed Bundles", - choices, - seed=seed, - world_caching=False) \ - as (multiworld, _): - self.assert_basic_checks(multiworld) + print(f"Generating solo multiworld with seed {seed} for Stardew Valley...") + with solo_multiworld(player_options, seed=seed, world_caching=False) as (multiworld, _): + self.assert_basic_checks(multiworld) diff --git a/worlds/stardew_valley/test/long/TestRandomWorlds.py b/worlds/stardew_valley/test/long/TestRandomWorlds.py deleted file mode 100644 index 6d4931280a79..000000000000 --- a/worlds/stardew_valley/test/long/TestRandomWorlds.py +++ /dev/null @@ -1,86 +0,0 @@ -import random -import unittest -from typing import Dict - -from BaseClasses import MultiWorld, get_seed -from Options import NamedRange, Range -from .option_names import options_to_include -from .. import SVTestCase -from ..assertion import GoalAssertMixin, OptionAssertMixin, WorldAssertMixin - - -def get_option_choices(option) -> Dict[str, int]: - if issubclass(option, NamedRange): - return option.special_range_names - if issubclass(option, Range): - return {f"{val}": val for val in range(option.range_start, option.range_end + 1)} - elif option.options: - return option.options - return {} - - -def generate_random_world_options(seed: int) -> Dict[str, int]: - num_options = len(options_to_include) - world_options = dict() - rng = random.Random(seed) - for option_index in range(0, num_options): - option = options_to_include[option_index] - option_choices = get_option_choices(option) - if not option_choices: - continue - chosen_option_value = rng.choice(list(option_choices.values())) - world_options[option.internal_name] = chosen_option_value - return world_options - - -def get_number_log_steps(number_worlds: int) -> int: - if number_worlds <= 10: - return 2 - if number_worlds <= 100: - return 5 - if number_worlds <= 500: - return 10 - if number_worlds <= 1000: - return 20 - if number_worlds <= 5000: - return 25 - if number_worlds <= 10000: - return 50 - return 100 - - -class TestGenerateManyWorlds(GoalAssertMixin, OptionAssertMixin, WorldAssertMixin, SVTestCase): - def test_generate_many_worlds_then_check_results(self): - if self.skip_long_tests: - raise unittest.SkipTest("Long tests disabled") - - number_worlds = 10 if self.skip_long_tests else 1000 - seed = get_seed() - self.generate_and_check_many_worlds(number_worlds, seed) - - def generate_and_check_many_worlds(self, number_worlds: int, seed: int): - num_steps = get_number_log_steps(number_worlds) - log_step = number_worlds / num_steps - - print(f"Generating {number_worlds} Solo Multiworlds [Start Seed: {seed}] for Stardew Valley...") - for world_number in range(0, number_worlds + 1): - - world_seed = world_number + seed - world_options = generate_random_world_options(world_seed) - - with self.solo_world_sub_test(f"Multiworld: {world_seed}", world_options, seed=world_seed, world_caching=False) as (multiworld, _): - self.assert_multiworld_is_valid(multiworld) - - if world_number > 0 and world_number % log_step == 0: - print(f"Generated and Verified {world_number}/{number_worlds} worlds [{(world_number * 100) // number_worlds}%]") - - print(f"Finished generating and verifying {number_worlds} Solo Multiworlds for Stardew Valley") - - def assert_multiworld_is_valid(self, multiworld: MultiWorld): - self.assert_victory_exists(multiworld) - self.assert_same_number_items_locations(multiworld) - self.assert_goal_world_is_valid(multiworld) - self.assert_can_reach_island_if_should(multiworld) - self.assert_cropsanity_same_number_items_and_locations(multiworld) - self.assert_festivals_give_access_to_deluxe_scarecrow(multiworld) - self.assert_has_festival_recipes(multiworld) diff --git a/worlds/stardew_valley/test/long/option_names.py b/worlds/stardew_valley/test/long/option_names.py deleted file mode 100644 index 9f3cf98b872c..000000000000 --- a/worlds/stardew_valley/test/long/option_names.py +++ /dev/null @@ -1,30 +0,0 @@ -from typing import Dict - -from Options import NamedRange -from ... import StardewValleyWorld - -options_to_exclude = {"profit_margin", "starting_money", "multiple_day_sleep_enabled", "multiple_day_sleep_cost", - "experience_multiplier", "friendship_multiplier", "debris_multiplier", - "quick_start", "gifting", "gift_tax", - "progression_balancing", "accessibility", "start_inventory", "start_hints", "death_link"} - -options_to_include = [option - for option_name, option in StardewValleyWorld.options_dataclass.type_hints.items() - if option_name not in options_to_exclude] - - -def get_option_choices(option) -> Dict[str, int]: - if issubclass(option, NamedRange): - return option.special_range_names - elif option.options: - return option.options - return {} - - -all_option_choices = [(option, value) - for option in options_to_include - if option.options - for value in get_option_choices(option) - if option.default != get_option_choices(option)[value]] - -assert all_option_choices diff --git a/worlds/stardew_valley/test/mods/TestMods.py b/worlds/stardew_valley/test/mods/TestMods.py index 932c76c68019..bd5d7d626dfc 100644 --- a/worlds/stardew_valley/test/mods/TestMods.py +++ b/worlds/stardew_valley/test/mods/TestMods.py @@ -1,88 +1,64 @@ import random +from typing import ClassVar from BaseClasses import get_seed -from .. import SVTestBase, SVTestCase +from test.param import classvar_matrix +from .. import SVTestBase, SVTestCase, solo_multiworld from ..TestGeneration import get_all_permanent_progression_items from ..assertion import ModAssertMixin, WorldAssertMixin from ..options.presets import allsanity_mods_6_x_x from ..options.utils import fill_dataclass_with_default from ... import options, Group, create_content from ...mods.mod_data import ModNames -from ...options import SkillProgression, Walnutsanity from ...options.options import all_mods from ...regions import RandomizationFlag, randomize_connections, create_final_connections_and_regions -class TestGenerateModsOptions(WorldAssertMixin, ModAssertMixin, SVTestCase): +class TestCanGenerateAllsanityWithMods(WorldAssertMixin, ModAssertMixin, SVTestCase): - def test_given_single_mods_when_generate_then_basic_checks(self): - for mod in options.Mods.valid_keys: - world_options = {options.Mods: mod, options.ExcludeGingerIsland: options.ExcludeGingerIsland.option_false} - with self.solo_world_sub_test(f"Mod: {mod}", world_options) as (multi_world, _): - self.assert_basic_checks(multi_world) - self.assert_stray_mod_items(mod, multi_world) - - # The following tests validate that ER still generates winnable and logically-sane games with given mods. - # Mods that do not interact with entrances are skipped - # Not all ER settings are tested, because 'buildings' is, essentially, a superset of all others - def test_deepwoods_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.deepwoods, options.EntranceRandomization.option_buildings) - - def test_juna_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.juna, options.EntranceRandomization.option_buildings) - - def test_jasper_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.jasper, options.EntranceRandomization.option_buildings) - - def test_alec_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.alec, options.EntranceRandomization.option_buildings) - - def test_yoba_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.yoba, options.EntranceRandomization.option_buildings) - - def test_eugene_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.eugene, options.EntranceRandomization.option_buildings) - - def test_ayeisha_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.ayeisha, options.EntranceRandomization.option_buildings) - - def test_riley_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.riley, options.EntranceRandomization.option_buildings) - - def test_sve_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.sve, options.EntranceRandomization.option_buildings) - - def test_alecto_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.alecto, options.EntranceRandomization.option_buildings) + def test_allsanity_all_mods_when_generate_then_basic_checks(self): + with solo_multiworld(allsanity_mods_6_x_x()) as (multi_world, _): + self.assert_basic_checks(multi_world) - def test_lacey_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.lacey, options.EntranceRandomization.option_buildings) + def test_allsanity_all_mods_exclude_island_when_generate_then_basic_checks(self): + world_options = allsanity_mods_6_x_x() + world_options.update({options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true}) + with solo_multiworld(world_options) as (multi_world, _): + self.assert_basic_checks(multi_world) - def test_boarding_house_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(ModNames.boarding_house, options.EntranceRandomization.option_buildings) - def test_all_mods_entrance_randomization_buildings(self): - self.perform_basic_checks_on_mod_with_er(all_mods, options.EntranceRandomization.option_buildings) +@classvar_matrix(mod=all_mods) +class TestCanGenerateWithEachMod(WorldAssertMixin, ModAssertMixin, SVTestCase): + mod: ClassVar[str] - def perform_basic_checks_on_mod_with_er(self, mods: str | set[str], er_option: int) -> None: - if isinstance(mods, str): - mods = {mods} + def test_given_single_mods_when_generate_then_basic_checks(self): world_options = { - options.EntranceRandomization: er_option, - options.Mods: frozenset(mods), + options.Mods: self.mod, options.ExcludeGingerIsland: options.ExcludeGingerIsland.option_false } - with self.solo_world_sub_test(f"entrance_randomization: {er_option}, Mods: {mods}", world_options) as (multi_world, _): + with solo_multiworld(world_options) as (multi_world, _): self.assert_basic_checks(multi_world) + self.assert_stray_mod_items(self.mod, multi_world) - def test_allsanity_all_mods_when_generate_then_basic_checks(self): - with self.solo_world_sub_test(world_options=allsanity_mods_6_x_x()) as (multi_world, _): - self.assert_basic_checks(multi_world) - def test_allsanity_all_mods_exclude_island_when_generate_then_basic_checks(self): - world_options = allsanity_mods_6_x_x() - world_options.update({options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true}) - with self.solo_world_sub_test(world_options=world_options) as (multi_world, _): +@classvar_matrix(mod=all_mods.difference([ + ModNames.ginger, ModNames.distant_lands, ModNames.skull_cavern_elevator, ModNames.wellwick, ModNames.magic, ModNames.binning_skill, ModNames.big_backpack, + ModNames.luck_skill, ModNames.tractor, ModNames.shiko, ModNames.archaeology, ModNames.delores, ModNames.socializing_skill, ModNames.cooking_skill +])) +class TestCanGenerateEachModWithEntranceRandomizationBuildings(WorldAssertMixin, SVTestCase): + """The following tests validate that ER still generates winnable and logically-sane games with given mods. + Mods that do not interact with entrances are skipped + Not all ER settings are tested, because 'buildings' is, essentially, a superset of all others + """ + mod: ClassVar[str] + + def test_given_mod_when_generate_then_basic_checks(self) -> None: + world_options = { + options.EntranceRandomization: options.EntranceRandomization.option_buildings, + options.Mods: self.mod, + options.ExcludeGingerIsland: options.ExcludeGingerIsland.option_false + } + with solo_multiworld(world_options, world_caching=False) as (multi_world, _): self.assert_basic_checks(multi_world) @@ -105,7 +81,7 @@ class TestBaseItemGeneration(SVTestBase): options.Chefsanity.internal_name: options.Chefsanity.option_all, options.Craftsanity.internal_name: options.Craftsanity.option_all, options.Booksanity.internal_name: options.Booksanity.option_all, - Walnutsanity.internal_name: Walnutsanity.preset_all, + options.Walnutsanity.internal_name: options.Walnutsanity.preset_all, options.Mods.internal_name: frozenset(options.Mods.valid_keys) } @@ -151,7 +127,7 @@ def test_mod_entrance_randomization(self): sv_options = fill_dataclass_with_default({ options.EntranceRandomization.internal_name: option, options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_false, - SkillProgression.internal_name: SkillProgression.option_progressive_with_masteries, + options.SkillProgression.internal_name: options.SkillProgression.option_progressive_with_masteries, options.Mods.internal_name: frozenset(options.Mods.valid_keys) }) content = create_content(sv_options) diff --git a/worlds/stardew_valley/test/options/option_names.py b/worlds/stardew_valley/test/options/option_names.py new file mode 100644 index 000000000000..07fa42b50862 --- /dev/null +++ b/worlds/stardew_valley/test/options/option_names.py @@ -0,0 +1,51 @@ +import random + +from Options import NamedRange, Option, Range +from ... import StardewValleyWorld +from ...options import StardewValleyOption + +options_to_exclude = {"profit_margin", "starting_money", "multiple_day_sleep_enabled", "multiple_day_sleep_cost", + "experience_multiplier", "friendship_multiplier", "debris_multiplier", + "quick_start", "gifting", "gift_tax", + "progression_balancing", "accessibility", "start_inventory", "start_hints", "death_link"} + +options_to_include: list[type[StardewValleyOption | Option]] = [ + option + for option_name, option in StardewValleyWorld.options_dataclass.type_hints.items() + if option_name not in options_to_exclude +] + + +def get_option_choices(option: type[Option]) -> dict[str, int]: + if issubclass(option, NamedRange): + return option.special_range_names + if issubclass(option, Range): + return {f"{val}": val for val in range(option.range_start, option.range_end + 1)} + elif option.options: + return option.options + return {} + + +def generate_random_world_options(seed: int) -> dict[str, int]: + num_options = len(options_to_include) + world_options = dict() + rng = random.Random(seed) + for option_index in range(0, num_options): + option = options_to_include[option_index] + option_choices = get_option_choices(option) + if not option_choices: + continue + chosen_option_value = rng.choice(list(option_choices.values())) + world_options[option.internal_name] = chosen_option_value + return world_options + + +all_option_choices = [ + (option.internal_name, value) + for option in options_to_include + if option.options + for value in get_option_choices(option) + if option.default != get_option_choices(option)[value] +] + +assert all_option_choices diff --git a/worlds/stardew_valley/test/stability/TestUniversalTracker.py b/worlds/stardew_valley/test/stability/TestUniversalTracker.py index 5e8075e4a1fd..0268d9e515ec 100644 --- a/worlds/stardew_valley/test/stability/TestUniversalTracker.py +++ b/worlds/stardew_valley/test/stability/TestUniversalTracker.py @@ -1,11 +1,12 @@ import unittest from unittest.mock import Mock -from .. import SVTestBase, fill_namespace_with_default +from .. import SVTestBase, fill_namespace_with_default, skip_long_tests from ..options.presets import allsanity_mods_6_x_x from ... import STARDEW_VALLEY, FarmType, BundleRandomization, EntranceRandomization +@unittest.skipIf(skip_long_tests(), "Long tests disabled") class TestUniversalTrackerGenerationIsStable(SVTestBase): options = allsanity_mods_6_x_x() options.update({ @@ -16,8 +17,6 @@ class TestUniversalTrackerGenerationIsStable(SVTestBase): def test_all_locations_and_items_are_the_same_between_two_generations(self): # This might open a kivy window temporarily, but it's the only way to test this... - if self.skip_long_tests: - raise unittest.SkipTest("Long tests disabled") try: # This test only run if UT is present, so no risk of running in the CI. @@ -30,7 +29,7 @@ def test_all_locations_and_items_are_the_same_between_two_generations(self): fake_context = Mock() fake_context.re_gen_passthrough = {STARDEW_VALLEY: ut_data} - args = fill_namespace_with_default({0: self.options}) + args = fill_namespace_with_default([self.options]) args.outputpath = None args.outputname = None args.multi = 1 From 347efac0cd787ded2eb79299e5eee6e60789733e Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Fri, 11 Apr 2025 20:41:08 -0400 Subject: [PATCH 0315/1218] DLC Quest - Skip two long tests in the main pipeline (#4862) * - Set up the two long tests to only run when the specific config is active * Apply Black Sliver's suggestion --- worlds/dlcquest/test/TestOptionsLong.py | 9 +++++++-- worlds/dlcquest/test/__init__.py | 13 ++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/worlds/dlcquest/test/TestOptionsLong.py b/worlds/dlcquest/test/TestOptionsLong.py index c6c594b6a004..d31e82c00fde 100644 --- a/worlds/dlcquest/test/TestOptionsLong.py +++ b/worlds/dlcquest/test/TestOptionsLong.py @@ -1,10 +1,11 @@ +import unittest from typing import Dict from BaseClasses import MultiWorld from Options import NamedRange -from .option_names import options_to_include -from .checks.world_checks import assert_can_win, assert_same_number_items_locations from . import DLCQuestTestBase, setup_dlc_quest_solo_multiworld +from .checks.world_checks import assert_can_win, assert_same_number_items_locations +from .option_names import options_to_include def basic_checks(tester: DLCQuestTestBase, multiworld: MultiWorld): @@ -38,6 +39,8 @@ def test_given_option_pair_when_generate_then_basic_checks(self): basic_checks(self, multiworld) def test_given_option_truple_when_generate_then_basic_checks(self): + if self.skip_long_tests: + raise unittest.SkipTest("Long tests disabled") num_options = len(options_to_include) for option1_index in range(0, num_options): for option2_index in range(option1_index + 1, num_options): @@ -59,6 +62,8 @@ def test_given_option_truple_when_generate_then_basic_checks(self): basic_checks(self, multiworld) def test_given_option_quartet_when_generate_then_basic_checks(self): + if self.skip_long_tests: + raise unittest.SkipTest("Long tests disabled") num_options = len(options_to_include) for option1_index in range(0, num_options): for option2_index in range(option1_index + 1, num_options): diff --git a/worlds/dlcquest/test/__init__.py b/worlds/dlcquest/test/__init__.py index 0432ae8b60ba..bcc4c14659d2 100644 --- a/worlds/dlcquest/test/__init__.py +++ b/worlds/dlcquest/test/__init__.py @@ -1,19 +1,26 @@ +import os +from argparse import Namespace from typing import ClassVar - from typing import Dict, FrozenSet, Tuple, Any -from argparse import Namespace from BaseClasses import MultiWorld from test.bases import WorldTestBase -from .. import DLCqworld from test.general import gen_steps, setup_solo_multiworld as setup_base_solo_multiworld from worlds.AutoWorld import call_all +from .. import DLCqworld class DLCQuestTestBase(WorldTestBase): game = "DLCQuest" world: DLCqworld player: ClassVar[int] = 1 + # Set False to run tests that take long + skip_long_tests: bool = True + + @classmethod + def setUpClass(cls) -> None: + super().setUpClass() + cls.skip_long_tests = not bool(os.environ.get("long")) def world_setup(self, *args, **kwargs): super().world_setup(*args, **kwargs) From ec1e113b4c6dbaa977a46325fb6cb7d958ea531e Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Sun, 13 Apr 2025 13:10:36 +0200 Subject: [PATCH 0316/1218] Doc: fix parse_yaml in adding games.md (#4872) --- docs/adding games.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/adding games.md b/docs/adding games.md index 2decb667b76d..c3eb0d023eb3 100644 --- a/docs/adding games.md +++ b/docs/adding games.md @@ -146,8 +146,8 @@ workarounds or preferred methods which should be used instead: * If you need to place specific items, there are multiple ways to do so, but they should not be added to the multiworld itempool. * It is not allowed to use `eval` for most reasons, chiefly due to security concerns. -* It is discouraged to use `yaml.load` directly due to security concerns. - * When possible, use `Utils.yaml_load` instead, as this defaults to the safe loader. +* It is discouraged to use PyYAML (i.e. `yaml.load`) directly due to security concerns. + * When possible, use `Utils.parse_yaml` instead, as this defaults to the safe loader and the faster C parser. * When submitting regions or items to the multiworld (`multiworld.regions` and `multiworld.itempool` respectively), do **not** use `=` as this will overwrite all elements for all games in the seed. * Instead, use `append`, `extend`, or `+=`. From 1873c52aa6f66fb79657555098d6c8e2efc9dada Mon Sep 17 00:00:00 2001 From: Seldom <38388947+Seldom-SE@users.noreply.github.com> Date: Tue, 15 Apr 2025 06:51:05 -0700 Subject: [PATCH 0317/1218] Terraria: 1.4.4 and Calamity support (#3847) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Terraria integration * Precollected items for debugging * Fix item classification * Golem requires Plantera's Bulb * Pumpkin Moon requires Dungeon * Progressive Dungeon * Reorg, Options.py work * Items are boss flags * Removed unused option * Removed nothing * Wall, Plantera, and Zenith goals * Achievements and items * Fixed The Cavalry and Completely Awesome achievements * Made "Dead Men Tell No Tales" a grindy achievement * Some docs, Python 3.8 compat * docs * Fix extra item and "Head in the Clouds" being included when achievements are disabled * Requested changes * Fix potential thread unsafety, replace Nothing with 50 Silver * Remove a log * Corrected heading * Added incompatible mods list * In-progress calamity integration * Terraria events progress * Rules use events * Removed an intentional crash I accidentally left in * Fixed infinite loop * Moved rules to data file * Moved item rewards to data file * Generating from data file * Fixed broken Mech Boss goal * Changes Calamity makes to vanilla rules, Calamity final bosses goal * Added Deerclops, fixed Zenith goal * Final detailed vanilla pass * Disable calamity goals * Typo * Fixed some reward items not adding to item pool * In-progress unit test fixes * Unit test fixes * `.apworld` compat * Organized rewards file, made Frog Leg and Fllpper available in vanilla * Water Walking Boots and Titan Glove rewards * Add goals to slot data * Fixed Hammush logic in Post-Mech goal * Fixed coin rewards * Updated Terraria docs * Formatted * Deathlink in-progress * Boots of the Hero is grindy * Fixed zenith goal not placing an item * Address review * Gelatin World Tour is grindy * Difficulty notice * Switched some achievements' grindiness * Added "Hey! Listen!" achievement * Terarria Python 3.8 compat * Fixed Terraria You and What Army logic * Calamity minion accessories * Typo * Calamity integration * `deathlink` -> `death_link` Co-authored-by: Zach Parks * Missing `.` Co-authored-by: Zach Parks * Incorrect type annotation Co-authored-by: Zach Parks * `deathlink` -> `death_link` 2 Co-authored-by: Zach Parks * Style Co-authored-by: Zach Parks * Markdown style Co-authored-by: Zach Parks * Markdown style 2 Co-authored-by: Zach Parks * Address review * Fix bad merge * Terraria utility mod recommendations * Calamity minion armor logic * ArmorMinions -> Armor Minions, boss rush goal, fixed unplaced item * Fixed unplaced item * Started on Terraria 1.4.4 * Crate logic * getfixedboi, 1.4.4 achievements, shimmer, town slimes, `Rule`, `Condition`, etc * More clam getfixedboi logic, bar decraft logic, `NotGetfixedboi` -> `Not Getfixedboi` * Calamity fixes * Calamity crate ore logic * Fixed item accessibility not generating in getfixedboi, fixed not generating with incompatible options, fixed grindy function * Early achievements, separate achievement category options * Infinity +1 Sword achievement can be location in later goals * The Frequent Flyer is impossible in Calamity getfixedboi * Add Enchanted Sword and Starfury for starting inventories * Don't Dread on Me is redundant in Calamity * In Calamity getfixedboi, Queen Bee summons enemies who drop Plague Cell Canisters * Can't use Gelatin Crystal outside Hallow * You can't get the Terminus without flags * Typo * Options difficult warnings * Robbing the Grave is Hardmode * Don't reserve an ID for unused Victory item * Plantera is accessible early in Calamity via Giant Plantera's Bulbs * Unshuffled Life Crystal and Defender Medal items * Comment about Midas' Blessing * Update worlds/terraria/Options.py Co-authored-by: Scipio Wright * Remove stray expression Co-authored-by: Scipio Wright * Review suggestions * Option naming caps consistency, add Laser Drill, Lunatic Cultist alt reqs, fix Eldritch Soul Artifact, Ceaseless Void reqs Dungeon * Cal Clone doesn't drop Broken Hero Sword anymore, Laser Drill is weaker in Calamity Co-authored-by: Seatori <92278897+Seatori@users.noreply.github.com> * Fix Acid Rain logic * Fix XB-∞ Hekate failing accessibility checks (by commenting it out bc it doesn't affect logic) * Hardmode ores being fishable early in Calamity is not a bug anymore * Mecha Mayhem is inaccessible in getfixedboi * Update worlds/terraria/Rules.dsv Co-authored-by: Seafo <92278897+Seatori@users.noreply.github.com> --------- Co-authored-by: Fabian Dill Co-authored-by: Zach Parks Co-authored-by: Scipio Wright Co-authored-by: Seatori <92278897+Seatori@users.noreply.github.com> --- worlds/terraria/Checks.py | 245 +++++++++++-------- worlds/terraria/Options.py | 73 ++++-- worlds/terraria/Rewards.dsv | 12 +- worlds/terraria/Rules.dsv | 461 ++++++++++++++++++++++++------------ worlds/terraria/__init__.py | 235 ++++++++++-------- 5 files changed, 653 insertions(+), 373 deletions(-) diff --git a/worlds/terraria/Checks.py b/worlds/terraria/Checks.py index 0630d6290be0..53e6626204a8 100644 --- a/worlds/terraria/Checks.py +++ b/worlds/terraria/Checks.py @@ -157,24 +157,57 @@ def unexpected(line: int, char: int, id: int, token, pos, pos_fmt, file): COND_GROUP = 3 +class Condition: + def __init__( + self, + # True = positive, False = negative + sign: bool, + # See the `COND_*` constants + type: int, + # Condition name or list + condition: Union[str, Tuple[Union[bool, None], List["Condition"]]], + argument: Union[str, int, None], + ): + self.sign = sign + self.type = type + self.condition = condition + self.argument = argument + + +class Rule: + def __init__( + self, + name: str, + # Name to arg + flags: Dict[str, Union[str, int, None]], + # True = or, False = and, None = N/A + operator: Union[bool, None], + conditions: List[Condition], + ): + self.name = name + self.flags = flags + self.operator = operator + self.conditions = conditions + + def validate_conditions( rule: str, rule_indices: dict, - conditions: List[ - Tuple[ - bool, int, Union[str, Tuple[Union[bool, None], list]], Union[str, int, None] - ] - ], + conditions: List[Condition], ): - for _, type, condition, _ in conditions: - if type == COND_ITEM: - if condition not in rule_indices: - raise Exception(f"item `{condition}` in `{rule}` is not defined") - elif type == COND_LOC: - if condition not in rule_indices: - raise Exception(f"location `{condition}` in `{rule}` is not defined") - elif type == COND_FN: - if condition not in { + for condition in conditions: + if condition.type == COND_ITEM: + if condition.condition not in rule_indices: + raise Exception( + f"item `{condition.condition}` in `{rule}` is not defined" + ) + elif condition.type == COND_LOC: + if condition.condition not in rule_indices: + raise Exception( + f"location `{condition.condition}` in `{rule}` is not defined" + ) + elif condition.type == COND_FN: + if condition.condition not in { "npc", "calamity", "grindy", @@ -182,43 +215,48 @@ def validate_conditions( "hammer", "mech_boss", "minions", + "getfixedboi", }: - raise Exception(f"function `{condition}` in `{rule}` is not defined") - elif type == COND_GROUP: - _, conditions = condition + raise Exception( + f"function `{condition.condition}` in `{rule}` is not defined" + ) + elif condition.type == COND_GROUP: + _, conditions = condition.condition validate_conditions(rule, rule_indices, conditions) def mark_progression( - conditions: List[ - Tuple[ - bool, int, Union[str, Tuple[Union[bool, None], list]], Union[str, int, None] - ] - ], + conditions: List[Condition], progression: Set[str], rules: list, rule_indices: dict, loc_to_item: dict, ): - for _, type, condition, _ in conditions: - if type == COND_ITEM: - prog = condition in progression - progression.add(loc_to_item[condition]) - _, flags, _, conditions = rules[rule_indices[condition]] + for condition in conditions: + if condition.type == COND_ITEM: + prog = condition.condition in progression + progression.add(loc_to_item[condition.condition]) + rule = rules[rule_indices[condition.condition]] if ( not prog - and "Achievement" not in flags - and "Location" not in flags - and "Item" not in flags + and "Achievement" not in rule.flags + and "Location" not in rule.flags + and "Item" not in rule.flags ): mark_progression( - conditions, progression, rules, rule_indices, loc_to_item + rule.conditions, progression, rules, rule_indices, loc_to_item ) - elif type == COND_LOC: - _, _, _, conditions = rules[rule_indices[condition]] - mark_progression(conditions, progression, rules, rule_indices, loc_to_item) - elif type == COND_GROUP: - _, conditions = condition + elif condition.type == COND_LOC: + + mark_progression( + rules[rule_indices[condition.condition]].conditions, + progression, + rules, + rule_indices, + loc_to_item, + ) + elif condition.type == COND_GROUP: + _, conditions = condition.condition mark_progression(conditions, progression, rules, rule_indices, loc_to_item) @@ -226,29 +264,7 @@ def read_data() -> Tuple[ # Goal to rule index that ends that goal's range and the locations required List[Tuple[int, Set[str]]], # Rules - List[ - Tuple[ - # Rule - str, - # Flag to flag arg - Dict[str, Union[str, int, None]], - # True = or, False = and, None = N/A - Union[bool, None], - # Conditions - List[ - Tuple[ - # True = positive, False = negative - bool, - # Condition type - int, - # Condition name or list (True = or, False = and, None = N/A) (list shares type with outer) - Union[str, Tuple[Union[bool, None], List]], - # Condition arg - Union[str, int, None], - ] - ], - ] - ], + List[Rule], # Rule to rule index Dict[str, int], # Label to rewards @@ -379,7 +395,7 @@ def read_data() -> Tuple[ unexpected(line, char, id, token, pos, POS_FMT, "Rules.dsv") elif pos == COND_OR_SEMI: if id == IDENT: - conditions.append((sign, COND_ITEM, token, None)) + conditions.append(Condition(sign, COND_ITEM, token, None)) sign = True pos = POST_COND elif id == HASH: @@ -424,14 +440,14 @@ def read_data() -> Tuple[ ) condition = operator, conditions sign, operator, conditions = outer.pop() - conditions.append((sign, COND_GROUP, condition, None)) + conditions.append(Condition(sign, COND_GROUP, condition, None)) sign = True pos = POST_COND else: unexpected(line, char, id, token, pos, POS_FMT, "Rules.dsv") elif pos == COND: if id == IDENT: - conditions.append((sign, COND_ITEM, token, None)) + conditions.append(Condition(sign, COND_ITEM, token, None)) sign = True pos = POST_COND elif id == HASH: @@ -449,7 +465,7 @@ def read_data() -> Tuple[ unexpected(line, char, id, token, pos, POS_FMT, "Rules.dsv") elif pos == LOC: if id == IDENT: - conditions.append((sign, COND_LOC, token, None)) + conditions.append(Condition(sign, COND_LOC, token, None)) sign = True pos = POST_COND else: @@ -464,10 +480,10 @@ def read_data() -> Tuple[ if id == LPAREN: pos = FN_ARG elif id == SEMI: - conditions.append((sign, COND_FN, function, None)) + conditions.append(Condition(sign, COND_FN, function, None)) pos = END elif id == AND: - conditions.append((sign, COND_FN, function, None)) + conditions.append(Condition(sign, COND_FN, function, None)) sign = True if operator is True: raise Exception( @@ -476,7 +492,7 @@ def read_data() -> Tuple[ operator = False pos = COND elif id == OR: - conditions.append((sign, COND_FN, function, None)) + conditions.append(Condition(sign, COND_FN, function, None)) sign = True if operator is False: raise Exception( @@ -485,21 +501,21 @@ def read_data() -> Tuple[ operator = True pos = COND elif id == RPAREN: - conditions.append((sign, COND_FN, function, None)) + conditions.append(Condition(sign, COND_FN, function, None)) if not outer: raise Exception( f"found `)` at {line + 1}:{char + 1} without matching `(`" ) condition = operator, conditions sign, operator, conditions = outer.pop() - conditions.append((sign, COND_GROUP, condition, None)) + conditions.append(Condition(sign, COND_GROUP, condition, None)) sign = True pos = POST_COND else: unexpected(line, char, id, token, pos, POS_FMT, "Rules.dsv") elif pos == FN_ARG: if id == IDENT or id == NUM: - conditions.append((sign, COND_FN, function, token)) + conditions.append(Condition(sign, COND_FN, function, token)) sign = True pos = FN_ARG_END else: @@ -527,7 +543,33 @@ def read_data() -> Tuple[ f"rule `{name}` on line `{line + 1}` shadows a previous rule" ) rule_indices[name] = len(rules) - rules.append((name, flags, operator, conditions)) + rules.append(Rule(name, flags, operator, conditions)) + + for flag in flags: + if flag not in { + "Location", + "Item", + "Goal", + "Early", + "Achievement", + "Grindy", + "Fishing", + "Npc", + "Pickaxe", + "Hammer", + "Minions", + "Armor Minions", + "Mech Boss", + "Final Boss", + "Getfixedboi", + "Not Getfixedboi", + "Calamity", + "Not Calamity", + "Not Calamity Getfixedboi", + }: + raise Exception( + f"rule `{name}` on line `{line + 1}` has unrecognized flag `{flag}`" + ) if "Item" in flags: item_name = flags["Item"] or f"Post-{name}" @@ -558,7 +600,7 @@ def read_data() -> Tuple[ final_bosses.append(flags["Item"] or f"Post-{name}") final_boss_loc.append(name) - if (minions := flags.get("ArmorMinions")) is not None: + if (minions := flags.get("Armor Minions")) is not None: armor_minions[name] = minions if (minions := flags.get("Minions")) is not None: @@ -572,16 +614,19 @@ def read_data() -> Tuple[ goal_indices[goal] = len(goals) goals.append((len(rules), set())) - for name, flags, _, _ in rules: - if "Goal" in flags: - _, items = goals[ - goal_indices[ - name.translate(str.maketrans("", "", string.punctuation)) + for rule in rules: + if "Goal" in rule.flags: + if (name := rule.flags.get("Goal")) is not None: + goal_name = name + else: + goal_name = ( + rule.name.translate(str.maketrans("", "", string.punctuation)) .replace(" ", "_") .lower() - ] - ] - items.add(name) + ) + + _, items = goals[goal_indices[goal_name]] + items.add(rule.name) _, mech_boss_items = goals[goal_indices["mechanical_bosses"]] mech_boss_items.update(mech_boss_loc) @@ -589,24 +634,27 @@ def read_data() -> Tuple[ _, final_boss_items = goals[goal_indices["calamity_final_bosses"]] final_boss_items.update(final_boss_loc) - for name, _, _, conditions in rules: - validate_conditions(name, rule_indices, conditions) + for rule in rules: + validate_conditions(rule.name, rule_indices, rule.conditions) - for name, flags, _, conditions in rules: + for rule in rules: prog = False if ( - "Npc" in flags - or "Goal" in flags - or "Pickaxe" in flags - or "Hammer" in flags - or "Mech Boss" in flags - or "Minions" in flags - or "ArmorMinions" in flags + "Npc" in rule.flags + or "Goal" in rule.flags + or "Pickaxe" in rule.flags + or "Hammer" in rule.flags + or "Mech Boss" in rule.flags + or "Final Boss" in rule.flags + or "Minions" in rule.flags + or "Armor Minions" in rule.flags ): - progression.add(loc_to_item[name]) + progression.add(loc_to_item[rule.name]) prog = True - if prog or "Location" in flags or "Achievement" in flags: - mark_progression(conditions, progression, rules, rule_indices, loc_to_item) + if prog or "Location" in rule.flags or "Achievement" in rule.flags: + mark_progression( + rule.conditions, progression, rules, rule_indices, loc_to_item + ) # Will be randomized via `slot_randoms` / `self.multiworld.random` label = None @@ -685,16 +733,15 @@ def read_data() -> Tuple[ next_id += 1 item_name_to_id["Reward: Coins"] = next_id - item_name_to_id["Victory"] = next_id + 1 - next_id += 2 + next_id += 1 location_name_to_id = {} - for name, flags, _, _ in rules: - if "Location" in flags or "Achievement" in flags: - if name in location_name_to_id: - raise Exception(f"location `{name}` shadows a previous location") - location_name_to_id[name] = next_id + for rule in rules: + if "Location" in rule.flags or "Achievement" in rule.flags: + if rule.name in location_name_to_id: + raise Exception(f"location `{rule.name}` shadows a previous location") + location_name_to_id[rule.name] = next_id next_id += 1 return ( diff --git a/worlds/terraria/Options.py b/worlds/terraria/Options.py index 4c4b96056c5f..f5056e4a0689 100644 --- a/worlds/terraria/Options.py +++ b/worlds/terraria/Options.py @@ -1,40 +1,70 @@ from dataclasses import dataclass -from Options import Choice, DeathLink, PerGameCommonOptions +from Options import Choice, DeathLink, PerGameCommonOptions, Toggle, DefaultOnToggle + + +class Calamity(Toggle): + """Calamity mod bosses and events are shuffled""" + + display_name = "Calamity Mod Integration" + + +class Getfixedboi(Toggle): + """Generation accomodates the secret, very difficult "getfixedboi" seed""" + + display_name = """"getfixedboi" Seed""" class Goal(Choice): - """The victory condition for your run. Stuff after the goal will not be shuffled.""" + """ + The victory condition for your run. Stuff after the goal will not be shuffled. + Primordial Wyrm and Boss Rush are accessible relatively early, so consider "Items" or + "Locations" accessibility to avoid getting stuck on the goal. + """ display_name = "Goal" option_mechanical_bosses = 0 - # option_calamitas_clone = 1 + option_calamitas_clone = 1 option_plantera = 2 option_golem = 3 option_empress_of_light = 4 option_lunatic_cultist = 5 - # option_astrum_deus = 6 + option_astrum_deus = 6 option_moon_lord = 7 - # option_providence_the_profaned_goddess = 8 - # option_devourer_of_gods = 9 - # option_yharon_dragon_of_rebirth = 10 + option_providence_the_profaned_goddess = 8 + option_devourer_of_gods = 9 + option_yharon_dragon_of_rebirth = 10 option_zenith = 11 - # option_calamity_final_bosses = 12 - # option_adult_eidolon_wyrm = 13 + option_calamity_final_bosses = 12 + option_primordial_wyrm = 13 + option_boss_rush = 14 default = 0 -class Achievements(Choice): +class EarlyAchievements(DefaultOnToggle): + """Adds checks upon collecting early Pre-Hardmode achievements. Adds many sphere 1 checks.""" + + display_name = "Early Pre-Hardmode Achievements" + + +class NormalAchievements(DefaultOnToggle): """ - Adds checks upon collecting achievements. Achievements for clearing bosses and events are excluded. - "Exclude Grindy" also excludes fishing achievements. + Adds checks upon collecting achivements not covered by the other options. Achievements for + clearing bosses and events are excluded. """ - display_name = "Achievements" - option_none = 0 - option_exclude_grindy = 1 - option_exclude_fishing = 2 - option_all = 3 - default = 1 + display_name = "Normal Achievements" + + +class GrindyAchievements(Toggle): + """Adds checks upon collecting grindy achievements""" + + display_name = "Grindy Achievements" + + +class FishingAchievements(Toggle): + """Adds checks upon collecting fishing quest achievements""" + + display_name = "Fishing Quest Achievements" class FillExtraChecksWith(Choice): @@ -51,7 +81,12 @@ class FillExtraChecksWith(Choice): @dataclass class TerrariaOptions(PerGameCommonOptions): + calamity: Calamity + getfixedboi: Getfixedboi goal: Goal - achievements: Achievements + early_achievements: EarlyAchievements + normal_achievements: NormalAchievements + grindy_achievements: GrindyAchievements + fishing_achievements: FishingAchievements fill_extra_checks_with: FillExtraChecksWith death_link: DeathLink diff --git a/worlds/terraria/Rewards.dsv b/worlds/terraria/Rewards.dsv index dbae37b449c9..c8fb96968973 100644 --- a/worlds/terraria/Rewards.dsv +++ b/worlds/terraria/Rewards.dsv @@ -121,10 +121,9 @@ Corrupt Flask; Calamity; Crimson Flask; Calamity; Craw Carapace; Calamity; Giant Shell; Calamity; -Fungal Carapace; Calamity; Life Jelly; Calamity; Vital Jelly; Calamity; -Mana Jelly; Calamity; +Cleansing Jelly; Calamity; Giant Tortoise Shell; Calamity; Coin of Deceit; Calamity; Ink Bomb; Calamity; @@ -151,4 +150,11 @@ Depths Charm; Calamity; Anechoic Plating; Calamity; Iron Boots; Calamity; Sprit Glyph; Calamity; -Abyssal Amulet; Calamity; \ No newline at end of file +Abyssal Amulet; Calamity; + +# unshuffled + +Life Crystal; +Enchanted Sword; +Starfury; +Defender Medal; \ No newline at end of file diff --git a/worlds/terraria/Rules.dsv b/worlds/terraria/Rules.dsv index 322bf9c5d3a3..9ae82d747243 100644 --- a/worlds/terraria/Rules.dsv +++ b/worlds/terraria/Rules.dsv @@ -1,43 +1,57 @@ -// TODO Calamity minion armor +// For the logic to account for all skips, these rules would need to be made much more comprehensive // Starting gear Copper Shortsword; Guide; Npc; // Immediately accessible -Timber!!; Achievement; -Benched; Achievement; -Stop! Hammer Time!; Achievement; -Matching Attire; Achievement; -Fashion Statement; Achievement; -Ooo! Shiny!; Achievement; -No Hobo; Achievement; +Squire Slime; Npc; +Traveling Merchant; ; @npc(2); +Lifeform Analyzer; ; Traveling Merchant; +DPS Meter; ; Traveling Merchant | (@calamity & Wire); +Stopwatch; ; Traveling Merchant; +Timber!!; Achievement | Early; +Benched; Achievement | Early; +Stop! Hammer Time!; Achievement | Early; +Matching Attire; Achievement | Early; +Fashion Statement; Achievement | Early; +Ooo! Shiny!; Achievement | Early; +No Hobo; Achievement | Early; // When NPC shuffling is added, this shouldn't be considered early Merchant; Npc; Bug Net; ; @calamity | Merchant; -Heavy Metal; Achievement; -Nurse; Npc; Merchant; -The Frequent Flyer; Achievement; Nurse; -Demolitionist; Npc; Merchant; +Heavy Metal; Achievement | Early; Dye Trader; Npc; @npc(4); Dye Hard; Achievement; Dye Trader; -Lucky Break; Achievement; -Star Power; Achievement; -You Can Do It!; Achievement; +Demolitionist; Npc; Merchant; +Lucky Break; Achievement | Early; +Star Power; Achievement | Early; +You Can Do It!; Achievement | Early; +Wulfrum Battery; Calamity; +Wulfrum Armor; Calamity | Armor Minions(1); // Surface exploration +Cactus; +Unusual Survival Strategies; Achievement | Early; Aglet; +Radar; +Wand of Sparking; Heliophobia; Achievement; Blighted Gel; Calamity; +Evil Powder; Archaeologist; Achievement | Grindy; Zoologist; Npc; Cat; Npc; Zoologist; Feeling Petty; Achievement; Cat | Dog; Dog; Npc; Zoologist; +Painter; Npc; @npc(8); A Rather Blustery Day; Achievement | Grindy; Enchanted Sword; Pretty in Pink; Achievement | Grindy; Marathon Medalist; Achievement | Grindy; Angler; Npc; +Fisherman's Pocket Guide; ; Angler | Weather Radio; +Weather Radio; ; Angler | Sextant; +Sextant; ; Angler | Fisherman's Pocket Guide; Servant-in-Training; Achievement | Fishing; Angler; \10 Fishing Quests; Achievement | Fishing; Angler; Trout Monkey; Achievement | Fishing; Angler; @@ -45,52 +59,69 @@ Glorious Golden Pole; Achievement | Fishing; Fast and Fishious; Achievement | Fishing; Angler; Supreme Helper Minion!; Achievement | Fishing; Angler; Water Walking Boots; -Painter; Npc; @npc(8); +Aquatic Heart; Calamity; // Sky exploration -Into Orbit; Achievement; +Into Orbit; Achievement | Early; Mysterious Circuitry; Calamity; Dubious Plating; Calamity; Charging Station; Calamity; Codebreaker Base; Calamity; Starfury; +Celestial Magnet; +Clumsy Slime; Npc; // Underground -Watch Your Step!; Achievement; -Throwing Lines; Achievement; +Watch Your Step!; Achievement | Early; +Throwing Lines; Achievement | Early; Torch God; Location | Item(Reward: Torch God's Favor); -Vehicular Manslaughter; Achievement; -Hey! Listen!; Achievement; +Vehicular Manslaughter; Achievement | Early; +Ancient Bone Dust; Calamity; +Depth Meter; +Compass; +Hey! Listen!; Achievement | Early; I Am Loot!; Achievement; +Magic Mirror; Heart Breaker; Achievement; -Hold on Tight!; Achievement; +Nurse; Npc; Merchant; +The Frequent Flyer; Not Calamity Getfixedboi | Achievement; Nurse; +Feast of Midas; Achievement; Bug Net; +Hold on Tight!; Achievement | Early; Feller of Evergreens; Calamity; Gold Hammer; Hammer(55); Gold Pickaxe; Pickaxe(55); +Gold Watch; Like a Boss; Achievement; Hermes Boots; Jeepers Creepers; Achievement; Stylist; Npc; Funkytown; Achievement; Deceiver of Fools; Achievement | Grindy; +Metal Detector; Dead Men Tell No Tales; Achievement; Bulldozer; Achievement | Grindy; // Cavern Obsidian; Obsidian Skull; ; Obsidian; +Raider's Talisman; Calamity; Obsidian; There are Some Who Call Him...; Achievement | Grindy; Lava Charm; Demonite Ore; -Demonite Bar; ; Demonite Ore | (@calamity & #Calamity Evil Boss); +Demonite Bar; ; Demonite Ore; Evil Sword; ; Demonite Bar; +Coin of Deceit; Calamity; Demonite Bar | Ruin Medallion; // Underground Ice Ice Skates; -Flinx Fur Coat; ArmorMinions(1); +Flinx Fur Coat; Armor Minions(1); // Underground Desert +Stormlion Mandible; Calamity; Golfer; Npc; +Party Girl; Npc; @npc(14); +Jolly Jamboree; Achievement | Grindy; Party Girl; +Cool Slime; Npc; Party Girl; // Sunken Sea Sea Prism; Calamity; @@ -98,37 +129,50 @@ Navyplate; Calamity; // Underground Jungle Anklet of the Wind; +Feral Claws; Stinger; Jungle Spores; Vine; Blade of Grass; ; Stinger & Jungle Spores & Vine; +Nature's Gift; +Bezoar; Summoning Potion; Minions(1); +// The Aether +A Shimmer In The Dark; Achievement; + // Underworld It's Getting Hot in Here; Achievement; Rock Bottom; Achievement; Obsidian Rose; Havocplate; Calamity; +Magma Stone; // Evil Smashing, Poppet!; Achievement; Arms Dealer; Npc; Leading Landlord; Achievement; Nurse & Arms Dealer; // The logic is way more complex, but that doesn't affect anything Completely Awesome; Achievement; Arms Dealer; +Illegal Gun Parts; ; Arms Dealer | Flamethrower; + +// Abyss +Ink Bomb; Calamity; // King Slime King Slime; Location | Item; -Sticky Situation; Achievement | Grindy; +Sticky Situation; Not Getfixedboi | Achievement | Grindy; The Cavalry; Achievement; Solidifier; ; #King Slime; +Nerdy Slime; Npc; #King Slime; // Desert Scourge Desert Scourge; Calamity | Location | Item; Pearl Shard; Calamity; #Desert Scourge; Sea Remains; Calamity; Pearl Shard; Reefclaw Hamaxe; Calamity | Hammer(60); Sea Remains; +Victide Armor; Calamity | Armor Minions(1); Sea Remains; Sandstorm; ; ~@calamity | Desert Scourge; -Voltaic Jelly; Calamity | Minions(1); Desert Scourge; // Jelly-Charged Battery doesn't stack. This is the case for all Calamity minion accessory upgrades. +Voltaic Jelly; Calamity | Minions(1); Desert Scourge | Jelly-Charged Battery; // Jelly-Charged Battery doesn't stack. This is the case for all Calamity minion accessory upgrades. // Giant Clam Giant Clam; Calamity | Location | Item; Desert Scourge; @@ -136,18 +180,21 @@ Amidias; Calamity; // Blood Moon Bloodbath; Achievement | Grindy; +Blood Orb; Calamity; +Shark Tooth Necklace; Til Death...; Achievement | Grindy; -Quiet Neighborhood; Achievement; +Quiet Neighborhood; Achievement | Early; +Surly Slime; Npc; // Eye of Cthulhu Eye of Cthulhu; Location | Item; Dryad; Npc; Eye of Cthulhu | Evil Boss | Skeletron; Pumpkin Seeds; ; Dryad; -Pumpkin; ; Pumpkin Seeds; -Purification Powder; ; Dryad; // Shimmered from Evil Powder in 1.4.4. Not bought from Dryad in get fixed boi. -Party Girl; Npc; @npc(14); -Jolly Jamboree; Achievement | Grindy; Party Girl; -Acid Rain Tier 1; Calamity | Location | Item; Eye of Cthulhu; +Pumpkin; ; Pumpkin Seeds | Cactus; +Purification Powder; ; (~@getfixedboi & Dryad) | Evil Powder; +Mystic Slime; Npc; Purification Powder; +And Good Riddance!; Achievement | Grindy; Dryad; +Acid Rain Tier 1; Calamity | Location | Item; Eye of Cthulhu | Wall of Flesh | Aquatic Scourge; // Crabulon Crabulon; Calamity | Location | Item; @@ -156,112 +203,160 @@ Crabulon; Calamity | Location | Item; Evil Boss; Location | Item; Evil Boss Part; ; #Evil Boss; Evil Pickaxe; Pickaxe(65); Evil Boss Part; -Obsidian Armor; ArmorMinions(1); Obsidian & Evil Boss Part; +Obsidian Armor; Armor Minions(1); Obsidian & Evil Boss Part; Tavernkeep; Npc; Evil Boss; Old One's Army Tier 1; Location | Item; Tavernkeep; -Meteorite; ; Evil Boss; -Meteorite Bar; ; Meteorite; +Meteorite; ; #Evil Boss | Evil Boss | Meteorite Bar | (@calamity & Astral Infection); +Meteorite Bar; ; Meteorite | (@calamity & Astral Infection) | Meteor Staff; Meteor Hamaxe; Hammer(60); Meteorite Bar; Hellforge; ; @pickaxe(60); -Hellstone; ; @pickaxe(65) | Wall of Flesh; +Hellstone; ; @pickaxe(65) | Wall of Flesh | Hellstone Bar; Hellstone Bar; ; Hellstone; Fiery Greatsword; ; Hellstone Bar; Molten Hamaxe; Hammer(70); Hellstone Bar; Molten Pickaxe; Pickaxe(100); Hellstone Bar; Miner for Fire; Achievement; Molten Pickaxe; -Hot Reels!; Achievement; Hellstone Bar & Bug Net; // TODO Calamity +Hot Reels!; Achievement; Hellstone Bar & (@calamity | Bug Net); Brimstone Slag; Calamity; @pickaxe(100); // Goblin Army Goblin Army; Location | Item; Goblin Tinkerer; Npc; Goblin Army; Tinkerer's Workshop; ; Goblin Tinkerer; +Mana Flower; ; (Tinkerer's Workshop & Nature's Gift) | (@calamity & Ethereal Talisman); +Silencing Sheath; Calamity; (Tinkerer's Workshop & Demonite Bar & Evil Boss Part) | Dark Matter Sheath; Rocket Boots; ; Goblin Tinkerer; Spectre Boots; ; Tinkerer's Workshop & Hermes Boots & Rocket Boots; Lightning Boots; ; Tinkerer's Workshop & Spectre Boots & Anklet of the Wind & Aglet; Frostspark Boots; ; Tinkerer's Workshop & Lightning Boots & Ice Skates; Lava Waders; ; Tinkerer's Workshop & Obsidian Skull & Lava Charm & Obsidian Rose & Water Walking Boots; Terraspark Boots; ; Tinkerer's Workshop & Frostspark Boots & Lava Waders; +GPS; ; Tinkerer's Workshop & Depth Meter & Gold Watch & Compass; +Goblin Tech; ; Tinkerer's Workshop & DPS Meter & Stopwatch & Metal Detector; +Fish Finder; ; Tinkerer's Workshop & Fisherman's Pocket Guide & Weather Radio & Sextant; Boots of the Hero; Achievement | Grindy; Terraspark Boots; +Diving Gear; ; Tinkerer's Workshop; // Queen Bee Where's My Honey?; Achievement; Queen Bee; Location | Item; Bee Keeper; ; #Queen Bee; Bee Wax; ; #Queen Bee; -Bee Armor; ArmorMinions(2); Bee Wax; +Bee Armor; Armor Minions(2); Bee Wax; Not the Bees!; Achievement; #Queen Bee & Bee Armor; Witch Doctor; Npc; Queen Bee; -Pygmy Necklace; Minions(1); Witch Doctor; +Pygmy Necklace; Minions(1); Witch Doctor | (@calamity & Statis' Blessing); // Calamity Evil Boss -Calamity Evil Boss; Calamity | Location | Item; -Aerialite Ore; Calamity; Calamity Evil Boss & @pickaxe(65); -Aerialite Bar; Calamity; Aerialite Ore; +The Hive Mind; Calamity | Location | Item; +The Perforators; Calamity | Location | Item; +Blood Sample; Calamity; #The Perforators; +Aerialite Ore; Calamity; The Hive Mind | The Perforators | Cobalt Ore | Aerialite Bar; // No pick needed; can be fished +Aerialite Bar; Calamity; Aerialite Ore | Feather Crown; Aerial Hamaxe; Calamity | Hammer(70); Aerialite Bar; Skyfringe Pickaxe; Calamity | Pickaxe(75); Aerialite Bar; +Aerospec Armor; Calamity | Armor Minions(1); Aerialite Bar; +Feather Crown; Calamity; Aerialite Bar | Moonstone Crown; // Skeletron Skeletron; Location | Item; Clothier; Npc; Skeletron; Dungeon; ; Skeletron; Dungeon Heist; Achievement; Dungeon; -Bone; ; Dungeon | (@calamity & #Skeletron); -Bewitching Table; Minions(1); Dungeon | (Witch Doctor & Wizard); +Bone; ; Dungeon | (@calamity & (#Skeletron | (@getfixedboi & #Ravager) | Mirage Mirror)); +Mirage Mirror; Calamity; (Tinkerer's Workshop & Bone) | Abyssal Mirror; +Tally Counter; ; Dungeon; +R.E.K. 3000; ; Tinkerer's Workshop & Radar & Tally Counter & Lifeform Analyzer; +PDA; ; Tinkerer's Workshop & GPS & R.E.K. 3000 & Goblin Tech & Fish Finder; +Cell Phone; ; (Tinkerer's Workshop & Magic Mirror & PDA) | (@getfixedboi & @calamity & #Polterghast); +Black Mirror; Achievement | Grindy; Cell Phone; +Bewitching Table; Minions(1); Dungeon | (Witch Doctor & Wizard) | Alchemy Table; +Alchemy Table; ; Dungeon | Bewitching Table; Mechanic; ; Dungeon; -Wire; ; Mechanic; +Wire; ; Mechanic | (@calamity & Electrician's Glove); Decryption Computer; Calamity; Mysterious Circuitry & Dubious Plating & Wire; Actuator; ; Mechanic; Muramasa; ; Dungeon; +Cobalt Shield; ; Dungeon | (@calamity & Cobalt Bar); +Obsidian Shield; ; Tinkerer's Workshop & Cobalt Shield & Obsidian Skull; +Elder Slime; Npc; Skeletron & Dungeon; // Deerclops Deerclops; Location | Item; // The Slime God The Slime God; Calamity | Location | Item; Blighted Gel; -Purified Gel; Calamity; #The Slime God; +Purified Gel; Calamity; #The Slime God | Jelly-Charged Battery; +Jelly-Charged Battery; Calamity; (Wulfrum Battery & Voltaic Jelly & Purified Gel & Stormlion Mandible) | Star-Tainted Generator; Static Refiner; Calamity; Purified Gel & Solidifier; Gelpick; Calamity | Pickaxe(100); Static Refiner & Purified Gel & Blighted Gel; +Statigel Armor; Calamity | Armor Minions(1); Static Refiner & Purified Gel & Blighted Gel; Night's Edge; ; Evil Sword & Muramasa & Blade of Grass & Fiery Greatsword & (~@calamity | Purified Gel); // Wall of Flesh Wall of Flesh; Location | Item(Hardmode); Guide; Pwnhammer; Hammer(80); #Wall of Flesh; +Emblem; ; #Wall of Flesh | Avenger Emblem | (@calamity & (Mechanical Glove | Celestial Emblem | Statis' Blessing)); +Fast Clock; ; Wall of Flesh | Trifold Map | (@calamity & Wire & Pixie Dust & Soul of Light); Wizard; Npc; Wall of Flesh; -Tax Collector; Npc; Purification Powder & Wall of Flesh; +Titan Glove; ; Wall of Flesh | Power Glove; +Power Glove; ; Tinkerer's Workshop & Titan Glove & Feral Claws; +Magic Quiver; ; Wall of Flesh | (@calamity & Elemental Quiver); +Hallowed Seeds; ; (Wall of Flesh & Dryad) | Holy Water; +Armor Polish; ; Wall of Flesh | Vitamins | (@calamity & Bone & Ancient Bone Dust); +Adhesive Bandage; ; @calamity | Wall of Flesh; +Medicated Bandage; ; Tinkerer's Workshop & Bezoar & Adhesive Bandage; +Megaphone; ; Wall of Flesh | Nazar | (@calamity & Wire & Cobalt Bar); +Pocket Mirror; ; Wall of Flesh | Blindfold | (@calamity & Crystal Shard & Soul of Night); +Trifold Map; ; Wall of Flesh | Fast Clock | (@calamity & Soul of Light & Soul of Night); +The Plan; ; Tinkerer's Workshop & Trifold Map & Fast Clock; +Tax Collector; Npc; (Purification Powder & Wall of Flesh) | @getfixedboi; Spider Fangs; ; Wall of Flesh; -Spider Armor; ArmorMinions(3); Spider Fangs; +Spider Armor; Armor Minions(3); Spider Fangs; Cross Necklace; ; Wall of Flesh; Altar; ; Wall of Flesh & @hammer(80); Begone, Evil!; Achievement; Altar; -Cobalt Ore; ; (((~@calamity & Altar) | (@calamity & Wall of Flesh)) & @pickaxe(100)) | Wall of Flesh; +Cobalt Ore; ; (((~@calamity & Altar) | (@calamity & Wall of Flesh)) & @pickaxe(100)) | Wall of Flesh | Mythril Ore | Cobalt Bar; Extra Shiny!; Achievement; Cobalt Ore | Mythril Ore | Adamantite Ore | Chlorophyte Ore; -Cobalt Bar; ; Cobalt Ore | Wall of Flesh; +Cobalt Bar; ; Cobalt Ore | (@calamity & Lunic Eye) | Wall of Flesh; Cobalt Pickaxe; Pickaxe(110); Cobalt Bar; -Soul of Night; ; Wall of Flesh | (@calamity & Altar); +Blindfold; ; @calamity | Wall of Flesh | Pocket Mirror; +Reflective Shades; ; Tinkerer's Workshop & Blindfold & Pocket Mirror; +Vitamins; ; Wall of Flesh | Armor Polish | (@calamity & Alchemy Table & Blood Orb); +Armor Bracing; ; Tinkerer's Workshop & Vitamins & Armor Polish; +Nazar; ; Wall of Flesh | Megaphone | (@calamity & Soul of Night); +Countercurse Mantra; ; Tinkerer's Workshop & Nazar & Megaphone; +Ankh Charm; ; Tinkerer's Workshop & Reflective Shades & Armor Bracing & Medicated Bandage & Countercurse Mantra & The Plan; +Ankh Shield; ; Tinkerer's Workshop & Obsidian Shield & Ankh Charm; +Ankhumulation Complete; Achievement | Grindy; Ankh Shield; +Soul of Night; ; Wall of Flesh | (@calamity & (Altar | (@getfixedboi & #Duke Fishron))); Hallow; ; Wall of Flesh; -Pixie Dust; ; Hallow; +Pixie Dust; ; Hallow | Meteor Staff | Holy Water; +Holy Water; ; (Pixie Dust & Hallowed Seeds) | (@calamity & Statis' Blessing); Unicorn Horn; ; Hallow; Crystal Shard; ; Hallow; Axe of Purity; Calamity; Feller of Evergreens & Purification Powder & Pixie Dust & Crystal Shard; -Soul of Light; ; Hallow | (@calamity & #Queen Slime); +Fabsol's Vodka; Calamity; (Pixie Dust & Crystal Shard & Unicorn Horn) | (@getfixedboi & #Empress of Light); +Soul of Light; ; Hallow | (@calamity & (#Queen Slime | (@getfixedboi & #Duke Fishron))) | Light Disc | Meteor Staff; +Meteor Staff; ; (Hardmode Anvil & Meteorite Bar & Pixie Dust & Soul of Light) | Asteroid Staff; Blessed Apple; ; Hallow; Rod of Discord; ; Hallow; Gelatin World Tour; Achievement | Grindy; Dungeon & Wall of Flesh & Hallow & #King Slime; Soul of Flight; ; Wall of Flesh; -Head in the Clouds; Achievement; @grindy | (Soul of Flight & ((Hardmode Anvil & (Soul of Light | Soul of Night | Pixie Dust | Wall of Flesh | Solar Eclipse | @mech_boss(1) | Plantera | Spectre Bar | #Golem)) | (Shroomite Bar & Autohammer) | #Mourning Wood | #Pumpking)) | Steampunker | (Wall of Flesh & Witch Doctor) | (Solar Eclipse & Plantera) | #Everscream | #Old One's Army Tier 3 | #Empress of Light | #Duke Fishron | (Fragment & Luminite Bar & Ancient Manipulator); // Leaf Wings are Post-Plantera in 1.4.4 +Head in the Clouds; Achievement; @grindy | (Soul of Flight & ((Hardmode Anvil & (Soul of Light | Soul of Night | Pixie Dust | Wall of Flesh | Solar Eclipse | @mech_boss(1) | Plantera | Spectre Bar | #Golem)) | (Shroomite Bar & Autohammer) | #Mourning Wood | #Pumpking)) | Steampunker | (Wall of Flesh & Plantera & Witch Doctor) | (Solar Eclipse & Plantera) | #Everscream | #Old One's Army Tier 3 | #Empress of Light | #Duke Fishron | (Fragment & Luminite Bar & Ancient Manipulator); Bunny; Npc; Zoologist & Wall of Flesh; // Extremely simplified Forbidden Fragment; ; Sandstorm & Wall of Flesh; -Astral Infection; Calamity; Wall of Flesh; -Stardust; Calamity; Astral Infection | #Astrum Aureus | #Astrum Deus; +Astral Infection; Calamity; Wall of Flesh | Astrum Aureus; +Stardust; Calamity; Astral Infection | #Astrum Aureus | #Astrum Deus | Eye of Magnus | Meld Construct; +Lunic Eye; Calamity; (Cobalt Bar & Stardust) | Eye of Magnus; Trapper Bulb; Calamity; Wall of Flesh; Titan Heart; Calamity; Astral Infection; Essence of Sunlight; Calamity; Wall of Flesh | Golem; -Essence of Eleum; Calamity; Wall of Flesh | Cryogen | #Cryogen; // TODO Check -Essence of Havoc; Calamity; Wall of Flesh | #Calamitas Clone | #Brimstone Elemental; -Don't Dread on Me; Achievement; Wall of Flesh; -Earth Elemental; Calamity | Location | Item; Wall of Flesh; -Cloud Elemental; Calamity | Location | Item; Wall of Flesh; +Essence of Eleum; Calamity; Wall of Flesh | Cryogen | #Cryogen | (@getfixedboi & #Duke Fishron); +Essence of Havoc; Calamity; Wall of Flesh | #Calamitas Clone | #Brimstone Elemental | Ruin Medallion; +Dreadnautilus; Calamity | Location | Item; Wall of Flesh; +Don't Dread on Me; Not Calamity | Achievement; Wall of Flesh; +Hardmode Giant Clam; Calamity | Location | Item; #Giant Clam & Wall of Flesh; Truffle; Npc; Wall of Flesh; It Can Talk?!; Achievement; Truffle; The First Shadowflame; Calamity | Minions(1); Goblin Army | Wall of Flesh; @@ -271,103 +366,125 @@ Pirate Invasion; Location | Item; Pirate; Npc; Pirate Invasion; // Queen Slime -Queen Slime; Location | Item; Hallow; +Queen Slime; Location | Item; Hallow | (@getfixedboi & @calamity & #Supreme Alchemist, Cirrus); +Sparkle Slime Balloon; ; #Queen Slime; +Diva Slime; Npc; Sparkle Slime Balloon; +The Great Slime Mitosis; Achievement; Nerdy Slime & Cool Slime & Elder Slime & Clumsy Slime & Diva Slime & Surly Slime & Mystic Slime & Squire Slime; // Aquatic Scourge -Mythril Ore; ; (((~@calamity & Altar) | (@calamity & @mech_boss(1))) & @pickaxe(110)) | (Wall of Flesh & (~@calamity | @mech_boss(1))); -Mythril Bar; ; Mythril Ore | (Wall of Flesh & (~@calamity | @mech_boss(1))); +Mythril Ore; ; (((~@calamity & Altar) | (@calamity & @mech_boss(1))) & @pickaxe(110)) | Wall of Flesh | Adamantite Ore | Mythril Bar; +Mythril Bar; ; Mythril Ore | Wall of Flesh | (@calamity & Electrician's Glove); Hardmode Anvil; ; Mythril Bar; Mythril Pickaxe; Pickaxe(150); Hardmode Anvil & Mythril Bar; -Adamantite Ore; ; (((~@calamity & Altar) | (@calamity & @mech_boss(2))) & @pickaxe(150)) | (Wall of Flesh & (~@calamity | @mech_boss(2))); +Electrician's Glove; Calamity; (Hardmode Anvil & Wire & Mythril Bar) | Nanotech; +Adamantite Ore; ; (((~@calamity & Altar) | (@calamity & @mech_boss(2))) & @pickaxe(150)) | Wall of Flesh | (~@calamity & Chlorophyte Ore) | Adamantite Bar | (@calamity & Hallowed Ore); Hardmode Forge; ; Hardmode Anvil & Adamantite Ore & Hellforge; -Adamantite Bar; ; (Hardmode Forge & Adamantite Ore) | (Wall of Flesh & (~@calamity | @mech_boss(2))); +Adamantite Bar; ; (Hardmode Forge & Adamantite Ore) | Wall of Flesh; Adamantite Pickaxe; Pickaxe(180); Hardmode Anvil & Adamantite Bar; -Forbidden Armor; ArmorMinions(2); Hardmode Anvil & Adamantite Bar & Forbidden Fragment; +Forbidden Armor; Armor Minions(2); Hardmode Anvil & Adamantite Bar & Forbidden Fragment; Aquatic Scourge; Calamity | Location | Item; -The Twins; Location | Item | Mech Boss; (@calamity | Hardmode Anvil) & Soul of Light; +Cragmaw Mire; Calamity | Location | Item; #Acid Rain Tier 2; +Nuclear Fuel Rod; Calamity | Minions(1); #Cragmaw Mire | Star-Tainted Generator; +Acid Rain Tier 2; Calamity | Location | Item; #Acid Rain Tier 1 & (Aquatic Scourge | Acid Rain Tier 3); +Mechanical Eye; ; (@calamity | Hardmode Anvil) & Soul of Light; +Mechanical Worm; ; (@calamity | Hardmode Anvil) & Soul of Night; +Mechanical Skull; ; (@calamity | Hardmode Anvil) & Soul of Night & Soul of Light & Bone; +Ocram's Razor; Getfixedboi; (@calamity | Hardmode Anvil) & Mechanical Eye & Mechanical Worm & Mechanical Skull; +The Twins; Location | Item | Mech Boss; (~@getfixedboi & Mechanical Eye) | (@getfixedboi & Ocram's Razor); Brimstone Elemental; Calamity | Location | Item; Soul of Night & Essence of Havoc & Unholy Core; -The Destroyer; Location | Item | Mech Boss; (@calamity | Hardmode Anvil) & Soul of Night; +The Destroyer; Location | Item | Mech Boss; (~@getfixedboi & Mechanical Worm) | (@getfixedboi & Ocram's Razor); Cryogen; Calamity | Location | Item; Soul of Night & Soul of Light & Essence of Eleum; -Skeletron Prime; Location | Item | Mech Boss; (@calamity | Hardmode Anvil) & Soul of Night & Soul of Light & Bone; +Skeletron Prime; Location | Item | Mech Boss; (~@getfixedboi & Mechanical Skull) | (@getfixedboi & Ocram's Razor); # mechanical_bosses -Cragmaw Mire; Calamity | Location | Item; #Acid Rain Tier 2; -Nuclear Rod; Calamity | Minions(1); #Cragmaw Mire; -Acid Rain Tier 2; Calamity | Location | Item; #Acid Rain Tier 1 & Aquatic Scourge; // The Twins -Soul of Sight; ; #The Twins; +Soul of Sight; ; #The Twins | Avenger Emblem | (@calamity & (Mechanical Glove | Celestial Emblem)); Steampunker; Npc; @mech_boss(1); Hammush; ; Truffle & @mech_boss(1); Rainbow Rod; ; Hardmode Anvil & Crystal Shard & Unicorn Horn & Pixie Dust & Soul of Light & Soul of Sight; Prismancer; Achievement; Rainbow Rod; Long Ranged Sensor Array; Calamity; Hardmode Anvil & Mysterious Circuitry & Dubious Plating & Mythril Bar & Wire & Decryption Computer & Codebreaker Base; Hydraulic Volt Crusher; Calamity; Hardmode Anvil & Mysterious Circuitry & Dubious Plating & Mythril Bar & Soul of Sight; -Life Fruit; ; (@mech_boss(1) & Wall of Flesh) | (@calamity & (Living Shard | Wall of Flesh)); +Life Fruit; ; (@mech_boss(1) & Wall of Flesh) | (@calamity & (Living Shard | Wall of Flesh | (@getfixedboi & #Plantera))); Get a Life; Achievement; Life Fruit; Topped Off; Achievement; Life Fruit; Old One's Army Tier 2; Location | Item; #Old One's Army Tier 1 & ((Wall of Flesh & @mech_boss(1)) | #Old One's Army Tier 3); // Brimstone Elemental Infernal Suevite; Calamity; @pickaxe(150) | Brimstone Elemental; -Unholy Core; Calamity; Infernal Suevite & Hellstone; +Unholy Core; Calamity; (Infernal Suevite & Hellstone) | Brimstone Elemental; +Ruin Medallion; Calamity; (Hardmode Anvil & Coin of Deceit & Unholy Core & Essence of Havoc) | Dark Matter Sheath; // The Destroyer -Soul of Might; ; #The Destroyer; +Soul of Might; ; #The Destroyer | Avenger Emblem | Light Disc | (@calamity & (Mechanical Glove | Celestial Emblem)); // Cryogen -Cryonic Ore; Calamity; Cryogen & (@pickaxe(180) | @mech_boss(2)); -Cryonic Bar; Calamity; (Hardmode Forge & Cryonic Ore) | Fleshy Geode | Necromantic Geode; +Cryonic Ore; Calamity; (Cryogen & (@pickaxe(180) | @mech_boss(2))) | Cryonic Bar; +Cryonic Bar; Calamity; (Hardmode Forge & Cryonic Ore) | Fleshy Geode | Necromantic Geode | (Cryogen & @mech_boss(2)) | Life Alloy; Abyssal Warhammer; Calamity | Hammer(88); Hardmode Anvil & Cryonic Bar; Shardlight Pickaxe; Calamity | Pickaxe(180); Hardmode Anvil & Cryonic Bar; +Daedalus Armor; Calamity | Armor Minions(2); Hardmode Anvil & Cryonic Bar & Essence of Eleum; // Skeletron Prime -Soul of Fright; ; #Skeletron Prime; +Soul of Fright; ; #Skeletron Prime | Avenger Emblem | Flamethrower | (@calamity & (Mechanical Glove | Celestial Emblem)); Inferna Cutter; Calamity; Hardmode Anvil & Axe of Purity & Soul of Fright & Essence of Havoc; +Flamethrower; ; (Hardmode Anvil & Illegal Gun Parts & Soul of Fright) | (@getfixedboi & @calamity & #Skeletron); Buckets of Bolts; Achievement; #The Twins & #The Destroyer & #Skeletron Prime; -Mecha Mayhem; Achievement; #The Twins & #The Destroyer & #Skeletron Prime; -Hallowed Bar; ; (#The Twins | #The Destroyer | #Skeletron Prime) & (~@calamity | @mech_boss(3)); // Can't count on Hallowed Ore, since the player may be in prehardmode (TODO Check this) -Hallowed Armor; ArmorMinions(3); Hardmode Anvil & Hallowed Bar; +Mecha Mayhem; Achievement | Not Getfixedboi; #The Twins & #The Destroyer & #Skeletron Prime; +Hallowed Ore; Calamity; (@mech_boss(3) & @pickaxe(180)) | Chlorophyte Ore | Hallowed Bar; +Hallowed Bar; ; ((#The Twins | #The Destroyer | #Skeletron Prime) & (~@calamity | @mech_boss(3))) | (@calamity & Hardmode Forge & Hallowed Ore) | Light Disc; +Hallowed Armor; Armor Minions(3); Hardmode Anvil & Hallowed Bar; Excalibur; ; Hardmode Anvil & Hallowed Bar; Pickaxe Axe; Pickaxe(200); Hardmode Anvil & Hallowed Bar & Soul of Fright & Soul of Might & Soul of Sight; Drax Attax; Achievement; Pickaxe Axe; True Night's Edge; ; Hardmode Anvil & Night's Edge & Soul of Fright & Soul of Might & Soul of Sight; -Chlorophyte Ore; ; Wall of Flesh & @pickaxe(200); +Avenger Emblem; ; (Tinkerer's Workshop & Emblem & Soul of Might & Soul of Sight & Soul of Fright) | (@calamity & (Sand Shark Tooth Necklace | Sigil of Calamitas)) | (~@calamity & (Mechanical Glove | Celestial Emblem)); +Mechanical Glove; ; (Power Glove & ((~@calamity & Tinkerer's Workshop & Avenger Emblem) | (@calamity & Emblem & Soul of Fright & Soul of Might & Soul of Sight))) | Fire Gauntlet; +Celestial Emblem; ; (Celestial Magnet & ((~@calamity & Tinkerer's Workshop & Avenger Emblem) | (@calamity & Emblem & Soul of Fright & Soul of Might & Soul of Sight))) | Sigil of Calamitas; +Light Disc; ; (Hallowed Bar & Soul of Light & Soul of Might) | (@getfixedboi & @calamity & #Evil Boss); +Chlorophyte Ore; ; (Wall of Flesh & @pickaxe(200)) | (~@calamity & Luminite) | Chlorophyte Bar | (@calamity & Perennial Ore); Photosynthesis; Achievement; Chlorophyte Ore; -Chlorophyte Bar; ; Hardmode Forge & Chlorophyte Ore; +Chlorophyte Bar; ; (Hardmode Forge & Chlorophyte Ore) | Spectre Bar | Shroomite Bar; True Excalibur; ; Hardmode Anvil & Excalibur & Chlorophyte Bar; Chlorophyte Pickaxe; Pickaxe(200); Hardmode Anvil & Chlorophyte Bar; Chlorophyte Warhammer; Hammer(90); Hardmode Anvil & Chlorophyte Bar; // Calamitas Clone Calamitas Clone; Calamity | Location | Item | Goal; Hardmode Anvil & Hellstone Bar & Essence of Havoc; -Plantera; Location | Item | Goal; Wall of Flesh & (@mech_boss(3) | (@calamity & Hardmode Anvil & Trapper Bulb)); +Plantera; Location | Item | Goal; Wall of Flesh & (@mech_boss(3) | @calamity); # calamitas_clone # plantera -Ashes of Calamity; Calamity; #Calamitas Clone; +Ashes of Calamity; Calamity; #Calamitas Clone | Sigil of Calamitas; +Depth Cells; Calamity; Calamitas Clone | Abyssal Mirror; +Lumenyl; Calamity; Calamitas Clone | Abyssal Mirror; +Abyssal Mirror; Calamity; (Hardmode Anvil & Mirage Mirror & Ink Bomb & Depth Cells & Lumenyl) | Eclipse Mirror; +Fathom Swarmer Armor; Calamity | Armor Minions(2); Hardmode Anvil & Sea Remains & Depth Cells; // Plantera The Axe; Hammer(100); #Plantera; Seedler; ; #Plantera; Living Shard; Calamity; #Plantera; -Tiki Armor; ArmorMinions(4); Witch Doctor & Wall of Flesh & Plantera; +Tiki Armor; Armor Minions(4); Witch Doctor & Wall of Flesh & Plantera; Hercules Beetle; ; Witch Doctor & Wall of Flesh & Plantera; You and What Army?; Achievement; @minions(8); Cyborg; Npc; Plantera; +To Infinity... and Beyond!; Achievement; Cyborg & Wall of Flesh; Autohammer; ; Truffle & Plantera; Shroomite Bar; ; Autohammer & Chlorophyte Bar; Shroomite Digging Claw; Pickaxe(200); Hardmode Anvil & Shroomite Bar; Princess; Npc; Guide & Merchant & Nurse & Demolitionist & Dye Trader & Zoologist & Angler & Painter & Stylist & Golfer & Arms Dealer & Dryad & Party Girl & Tavernkeep & Goblin Tinkerer & Witch Doctor & Clothier & Wizard & Truffle & Tax Collector & Pirate & Steampunker & Cyborg; Real Estate Agent; Achievement; Princess; -Ectoplasm; ; ((Dungeon & Wall of Flesh) | @calamity) & Plantera; +Ectoplasm; ; (((Dungeon & Wall of Flesh) | @calamity) & Plantera) | Spectre Bar; Paladin's Shield; ; Dungeon & Wall of Flesh & Plantera; -Core of Sunlight; Calamity; (Hardmode Anvil & Essence of Sunlight & Ectoplasm) | Fleshy Geode | Necromantic Geode; -Core of Eleum; Calamity; (Hardmode Anvil & Essence of Eleum & Ectoplasm) | Fleshy Geode | Necromantic Geode; -Core of Havoc; Calamity; (Hardmode Anvil & Essence of Havoc & Ectoplasm) | Fleshy Geode | Necromantic Geode; -Core of Calamity; Calamity; (Hardmode Anvil & Core of Sunlight & Core of Eleum & Core of Havoc & Ashes of Calamity) | Necromantic Geode; +Core of Sunlight; Calamity; (Hardmode Anvil & Essence of Sunlight & Ectoplasm) | Fleshy Geode | Necromantic Geode | Core of Calamity | Statis' Blessing; +Core of Eleum; Calamity; (Hardmode Anvil & Essence of Eleum & Ectoplasm) | Fleshy Geode | Necromantic Geode | Core of Calamity; +Core of Havoc; Calamity; (Hardmode Anvil & Essence of Havoc & Ectoplasm) | Fleshy Geode | Necromantic Geode | Core of Calamity; +Core of Calamity; Calamity; (Hardmode Anvil & Core of Sunlight & Core of Eleum & Core of Havoc & Ashes of Calamity) | Necromantic Geode | Deadshot Brooch; +Deadshot Brooch; Calamity; (Hardmode Anvil & Emblem & Core of Calamity) | Elemental Quiver; Spectre Bar; ; Hardmode Forge & Chlorophyte Bar & Ectoplasm; Spectre Pickaxe; Pickaxe(200); Hardmode Anvil & Spectre Bar; Spectre Hamaxe; Hammer(90); Hardmode Anvil & Spectre Bar; -Robbing the Grave; Achievement; Dungeon & Plantera; +Robbing the Grave; Achievement; Dungeon & Wall of Flesh & Plantera; Evil Key; ; Plantera | (@calamity & #Wall of Flesh); Frozen Key; ; Plantera | (@calamity & #Cryogen); Jungle Key; ; Plantera | (@calamity & #Plantera); @@ -376,22 +493,25 @@ Desert Key; ; Big Booty; Achievement; Dungeon & Wall of Flesh & Plantera & (Evil Key | Frozen Key | Jungle Key | Hallowed Key | Desert Key); Rainbow Gun; ; Dungeon & Wall of Flesh & Plantera & Hallowed Key; Rainbows and Unicorns; Achievement; Blessed Apple & Rainbow Gun; -Perennial Ore; Calamity; Plantera; -Perennial Bar; Calamity; Hardmode Forge & Perennial Ore; +Perennial Ore; Calamity; Plantera | Perennial Bar; +Perennial Bar; Calamity; (Hardmode Forge & Perennial Ore) | Plantera | Life Alloy; Beastial Pickaxe; Calamity | Pickaxe(200); Hardmode Anvil & Perennial Bar; -Armored Digger; Calamity | Location | Item; Plantera; // TODO Check // Solar Eclipse Temple Raider; Achievement; #Plantera; Lihzahrd Temple; ; #Plantera | (Plantera & Actuator) | @pickaxe(210) | (@calamity & Hardmode Anvil & Soul of Light & Soul of Night); +Lihzahrd Furniture; ; Lihzahrd Temple; Solar Eclipse; ; Lihzahrd Temple & Wall of Flesh; -Broken Hero Sword; ; (Solar Eclipse & Plantera & @mech_boss(3)) | (@calamity & #Calamitas Clone); +Broken Hero Sword; ; Solar Eclipse & Plantera & @mech_boss(3); Terra Blade; ; Hardmode Anvil & True Night's Edge & True Excalibur & Broken Hero Sword & (~@calamity | Living Shard); Sword of the Hero; Achievement; Terra Blade; +Neptune's Shell; ; Solar Eclipse; Kill the Sun; Achievement; Solar Eclipse; // Great Sand Shark Great Sand Shark; Calamity | Location | Item; Hardmode Anvil & Forbidden Fragment & Core of Sunlight; +Grand Scale; Calamity; #Great Sand Shark | Sand Shark Tooth Necklace; +Sand Shark Tooth Necklace; Calamity; (Tinkerer's Workshop & Shark Tooth Necklace & Avenger Emblem & Grand Scale) | (@getfixedboi & #Desert Scourge); // Leviathan and Anahita Leviathan and Anahita; Calamity | Location | Item; @@ -404,32 +524,40 @@ Starbuster Core; Calamity | Minions(1); Golem; Location | Item | Goal; (Wall of Flesh & Plantera & Lihzahrd Temple) | (@calamity & Hardmode Anvil & Lihzahrd Temple & Essence of Sunlight); # golem Picksaw; Pickaxe(210); #Golem; -Lihzahrd Brick; ; @pickaxe(210); -Scoria Ore; Calamity; Golem | @pickaxe(210); -Scoria Bar; Calamity; Hardmode Forge & Scoria Ore; +Lihzahrd Brick; ; @pickaxe(210) | (Lihzahrd Furniture & Golem) | (@calamity & Lihzahrd Temple); +Scoria Ore; Calamity; Golem | @pickaxe(210) | Astral Ore | Luminite | Scoria Bar; +Scoria Bar; Calamity; (Hardmode Forge & Scoria Ore) | Golem | Life Alloy | Sigil of Calamitas | Fire Gauntlet; Seismic Hampick; Calamity | Pickaxe(210) | Hammer(95); Hardmode Anvil & Scoria Bar; -Life Alloy; Calamity; (Hardmode Anvil & Cryonic Bar & Perennial Bar & Scoria Bar) | Necromantic Geode; +Hydrothermic Armor; Calamity | Armor Minions(2); Hardmode Anvil & Scoria Bar & Core of Havoc; +Fire Gauntlet; ; (Tinkerer's Workshop & Magma Stone & Mechanical Glove & (~@calamity | Scoria Bar)) | (@calamity & Elemental Gauntlet); +Sigil of Calamitas; Calamity; (Hardmode Anvil & Celestial Emblem & Scoria Bar & Ashes of Calamity) | Ethereal Talisman; +Life Alloy; Calamity; (Hardmode Anvil & Cryonic Bar & Perennial Bar & Scoria Bar) | Necromantic Geode | Star-Tainted Generator | (@getfixedboi & #Yharon, Dragon of Rebirth); Advanced Display; Calamity; Hardmode Anvil & Mysterious Circuitry & Dubious Plating & Life Alloy & Long Ranged Sensor Array; +Star-Tainted Generator; Calamity; (Hardmode Anvil & Jelly-Charged Battery & Nuclear Fuel Rod & Starbuster Core & Life Alloy) | Nucleogenesis; Old One's Army Tier 3; Location | Item; #Old One's Army Tier 1 & Wall of Flesh & Golem; // Martian Madness Martian Madness; Location | Item; Wall of Flesh & Golem; +Laser Drill; Pickaxe(220); #Martian Madness; Influx Waver; ; #Martian Madness; // The Plaguebringer Goliath -Plague Cell Canister; Calamity; Golem; -Plaguebringer; Calamity | Location | Item; Golem; +Plague Cell Canister; Calamity; Golem | Alchemical Flask | (@getfixedboi & #Queen Bee); +Alchemical Flask; Calamity; (Hardmode Anvil & Bee Wax & Plague Cell Canister) | (@getfixedboi & #Queen Bee); The Plaguebringer Goliath; Calamity | Location | Item; Hardmode Anvil & Plague Cell Canister; +Infected Armor Plating; Calamity; #The Plaguebringer Goliath; +Plaguebringer Armor; Calamity | Armor Minions(3); Hardmode Anvil & Bee Armor & Alchemical Flask & Plague Cell Canister & Infected Armor Plating; // Duke Fishron -Duke Fishron; Location | Item; Bug Net & Wall of Flesh; +Duke Fishron; Location | Item; (Bug Net & Wall of Flesh) | (@getfixedboi & @calamity & #Astrum Deus); // Pumpkin Moon Pumpkin Moon; ; Hardmode Anvil & Pumpkin & Ectoplasm & (@calamity | Hallowed Bar); -Spooky Armor; ArmorMinions(4); Pumpkin Moon; +Spooky Armor; Armor Minions(4); Pumpkin Moon; Mourning Wood; Location | Item; Pumpkin Moon; Necromantic Scroll; Minions(1); #Mourning Wood; -Papyrus Scarab; Minions(1); Tinkerer's Workshop & Hercules Beetle & Necromantic Scroll; +Papyrus Scarab; Minions(1); (Tinkerer's Workshop & Hercules Beetle & Necromantic Scroll) | (@calamity & Statis' Blessing); +Statis' Blessing; Calamity; (Hardmode Anvil & Papyrus Scarab & Pygmy Necklace & Emblem & Holy Water & Core of Sunlight) | Statis' Curse; Pumpking; Location | Item; Pumpkin Moon; The Horseman's Blade; ; #Pumpking; Baleful Harvest; Achievement; Pumpkin Moon; @@ -451,11 +579,11 @@ Ravager; Calamity | Location | Item; Fleshy Geode; Calamity; #Ravager; // Empress of Light -Empress of Light; Location | Item | Goal; Wall of Flesh & Hallow & (@calamity | Plantera); +Empress of Light; Location | Item | Goal; (Wall of Flesh & Hallow & (@calamity | Plantera)) | (@getfixedboi & @calamity & #Supreme Alchemist, Cirrus); # empress_of_light // Lunatic Cultist -Lunatic Cultist; Location | Item | Goal; (@calamity | (Dungeon & Golem)) & Wall of Flesh; +Lunatic Cultist; Location | Item | Goal; ((@calamity | (Dungeon & Golem)) & Wall of Flesh) | (@calamity & Calamitas Clone); Astrum Deus; Calamity | Location | Item | Goal; Titan Heart; # lunatic_cultist # astrum_deus @@ -463,111 +591,142 @@ Ancient Manipulator; ; // Lunar Events Lunar Events; Location | Item; #Lunatic Cultist; -Fragment; ; #Lunar Events | #Astrum Deus; -Galactica Singularity; Calamity; Ancient Manipulator & Fragment; -Meld Blob; Calamity; #Lunar Events | #Astrum Deus; -Meld Construct; Calamity; Ancient Manipulator & Meld Blob & Stardust; +Fragment; ; #Lunar Events | #Astrum Deus | (Ancient Manipulator & (Nebula Fragment | Stardust Fragment)) | (@calamity & Galactica Singularity); +Nebula Fragment; ; Fragment | (@calamity & Eye of Magnus); +Eye of Magnus; Calamity; (Ancient Manipulator & Lunic Eye & Nebula Fragment) | (@getfixedboi & #Wall of Flesh); +Stardust Fragment; ; Fragment | (@calamity & Statis' Curse); +Statis' Curse; Calamity; (Ancient Manipulator & Statis' Blessing & The First Shadowflame & Stardust Fragment) | Nucleogenesis; +Galactica Singularity; Calamity; (Ancient Manipulator & Fragment) | Elemental Gauntlet | Elemental Quiver | Nucleogenesis | Moonstone Crown | Ethereal Talisman; +Meld Blob; Calamity; #Lunar Events | #Astrum Deus | (Astral Infection & Astrum Deus) | Meld Construct; +Meld Construct; Calamity; (Ancient Manipulator & Meld Blob & Stardust) | Dark Matter Sheath; +Dark Matter Sheath; Calamity; (Ancient Manipulator & Silencing Sheath & Ruin Medallion & Meld Construct) | Eclipse Mirror; // Astrum Deus -Astral Ore; Calamity; Wall of Flesh & Astrum Deus; -Astral Bar; Calamity; Ancient Manipulator & Stardust & Astral Ore; +Astral Ore; Calamity; (Astral Infection & Astrum Deus) | Astral Bar; // No pick needed; you can fish it +Astral Bar; Calamity; (Ancient Manipulator & Stardust & Astral Ore) | (Astral Infection & Astrum Deus); Astral Hamaxe; Calamity | Hammer(100); Ancient Manipulator & Astral Bar; Astral Pickaxe; Calamity | Pickaxe(220); Ancient Manipulator & Astral Bar; +Astral Armor; Calamity | Armor Minions(3); Ancient Manipulator & Astral Bar & Meteorite Bar; // Moon Lord Moon Lord; Location | Item | Goal; #Lunar Events; # moon_lord Slayer of Worlds; Achievement; #Evil Boss & #The Destroyer & #Duke Fishron & #Eye of Cthulhu & #Golem & #King Slime & #Lunatic Cultist & #Moon Lord & #Plantera & #Queen Bee & #Skeletron & #Skeletron Prime & #The Twins & #Wall of Flesh; -Luminite; ; #Moon Lord; -Luminite Bar; ; Ancient Manipulator & Luminite; +Luminite; ; #Moon Lord | (@calamity & (Exodium Cluster | Asteroid Staff)) | Luminite Bar; +Luminite Bar; ; (Ancient Manipulator & Luminite) | (@calamity & (Elemental Gauntlet | Elemental Quiver | Nucleogenesis | Moonstone Crown | Ethereal Talisman)); Luminite Hamaxe; Hammer(100); Ancient Manipulator & Fragment & Luminite Bar; Luminite Pickaxe; Pickaxe(225); Ancient Manipulator & Fragment & Luminite Bar; Genesis Pickaxe; Calamity | Pickaxe(225); Ancient Manipulator & Meld Construct & Luminite Bar; -Stardust Armor; ArmorMinions(5); Ancient Manipulator & Fragment & Luminite Bar; +Stardust Armor; Armor Minions(5); Ancient Manipulator & Fragment & Luminite Bar; +Asteroid Staff; Calamity; (Ancient Manipulator & Meteor Staff & Luminite Bar) | (@getfixedboi & #Astrum Aureus); +Moonstone Crown; Calamity; (Ancient Manipulator & Feather Crown & Luminite Bar & Galactica Singularity) | Nanotech; Terrarian; ; #Moon Lord; Sick Throw; Achievement; Terrarian; Meowmere; ; #Moon Lord; Star Wrath; ; #Moon Lord; -Exodium Cluster; Calamity; Moon Lord & @pickaxe(225); +Exodium Cluster; Calamity; Moon Lord | Uelibloom Ore; // No pick needed; can be fished Normality Relocator; Calamity; Ancient Manipulator & Rod of Discord & Exodium Cluster & Fragment; -Unholy Essence; Calamity; Moon Lord | #Providence, the Profaned Goddess; -Phantoplasm; Calamity; Moon Lord & (Wall of Flesh | Dungeon); // TODO Check -Eldritch Soul Artifact; Calamity; Exodium Cluster & Navyplate & Phantoplasm; +Unholy Essence; Calamity; Moon Lord | #Providence, the Profaned Goddess | (Hallow & Providence, the Profaned Goddess) | (@getfixedboi & Plantera); +Polterplasm; Calamity; (Moon Lord & Wall of Flesh) | (Dungeon & (Polterghast | Moon Lord)) | #Polterghast; +Eldritch Soul Artifact; Calamity | Minions(1); Exodium Cluster & Navyplate & Polterplasm; // Profaned Guardians Profaned Guardians; Calamity | Location | Item; Ancient Manipulator & Unholy Essence & Luminite Bar; // Dragonfolly -The Dragonfolly; Calamity | Location | Item; Ancient Manipulator & Unholy Essence & Luminite Bar; -Effulgent Feather; Calamity; Moon Lord | #The Dragonfolly; +The Dragonfolly; Calamity | Location | Item; (Ancient Manipulator & Unholy Essence & Luminite Bar) | (@getfixedboi & #Supreme Alchemist, Cirrus); +Effulgent Feather; Calamity; Moon Lord | #The Dragonfolly | (@getfixedboi & #Yharon, Dragon of Rebirth); // Providence, the Profaned Goddess -Providence, the Profaned Goddess; Calamity | Location | Item | Goal; #Profaned Guardians; +Providence, the Profaned Goddess; Calamity | Location | Item | Goal; #Profaned Guardians | (@getfixedboi & #Supreme Alchemist, Cirrus); # providence_the_profaned_goddess -Divine Geode; Calamity; #Providence, the Profaned Goddess; +Divine Geode; Calamity; #Providence, the Profaned Goddess | (@getfixedboi & #Profaned Guardians); Profaned Soul Artifact; Calamity | Minions(1); Exodium Cluster & Havocplate & Divine Geode; Rune of Kos; Calamity; #Providence, the Profaned Goddess; -Uelibloom Ore; Calamity; Providence, the Profaned Goddess; -Uelibloom Bar; Calamity; Hardmode Forge & Uelibloom Ore; +Uelibloom Ore; Calamity; Providence, the Profaned Goddess | Auric Ore | Uelibloom Bar; +Uelibloom Bar; Calamity; (Hardmode Forge & Uelibloom Ore) | Providence, the Profaned Goddess; Grax; Calamity | Hammer(110); Ancient Manipulator & Inferna Cutter & Luminite Hamaxe & Uelibloom Bar; Blossom Pickaxe; Calamity | Pickaxe(250); Ancient Manipulator & Uelibloom Bar; Voltage Regulation System; Calamity; Ancient Manipulator & Mysterious Circuitry & Dubious Plating & Uelibloom Bar & Luminite Bar & Advanced Display; +Tarragon Armor; Calamity | Armor Minions(3); Ancient Manipulator & Uelibloom Bar & Divine Geode; Necromantic Geode; Calamity; #Ravager & Providence, the Profaned Goddess; +Bloodstone; Calamity; Providence, the Profaned Goddess; +Bloodstone Core; Calamity; Hardmode Forge & Bloodstone & Polterplasm; // Sentinels of the Devourer Storm Weaver; Calamity | Location | Item; Rune of Kos; Armored Shell; Calamity; #Storm Weaver; -Ceaseless Void; Calamity | Location | Item; Rune of Kos; +Ceaseless Void; Calamity | Location | Item; Dungeon & Rune of Kos; Dark Plasma; Calamity; #Ceaseless Void; Signus, Envoy of the Devourer; Calamity | Location | Item; Rune of Kos; Twisting Nether; Calamity; #Signus, Envoy of the Devourer; // Polterghast -Polterghast; Calamity | Location | Item; Dungeon & ((Ancient Manipulator & Phantoplasm) | Moon Lord); -Colossal Squid; Calamity | Location | Item; -Reaper Shark; Calamity | Location | Item; -Eidolon Wyrm; Calamity | Location | Item; +Polterghast; Calamity | Location | Item; Dungeon & ((Ancient Manipulator & Polterplasm) | Moon Lord); +Ruinous Soul; Calamity; #Polterghast; +Bloodflare Armor; Calamity | Armor Minions(3); Ancient Manipulator & Bloodstone Core & Ruinous Soul; +Reaper Tooth; Calamity; Polterghast; +Omega Blue Armor; Calamity | Armor Minions(2); Ancient Manipulator & Reaper Tooth & Depth Cells & Ruinous Soul; // The Old Duke -Mauler; Calamity | Location | Item; #Acid Rain Tier 3; -Nuclear Terror; Calamity | Location | Item; #Acid Rain Tier 3; -Acid Rain Tier 3; Calamity | Location | Item; #Acid Rain Tier 1 & Polterghast; // TODO Check -The Old Duke; Calamity | Location | Item; #Acid Rain Tier 3 | (Bug Net & Moon Lord) | (Amidias & The Old Duke); +Mauler; Calamity | Location | Item; Acid Rain Tier 3; +Nuclear Terror; Calamity | Location | Item; Acid Rain Tier 3; +Acid Rain Tier 3; Calamity; #Acid Rain Tier 1 & Polterghast; +The Old Duke; Calamity | Location | Item; Acid Rain Tier 3 | (Bug Net & Moon Lord) | (Amidias & The Old Duke) | (@getfixedboi & #The Destroyer); // The Devourer of Gods -The Devourer of Gods; Calamity | Location | Item | Goal; Ancient Manipulator & ((Armored Shell & Twisting Nether & Dark Plasma) | (Luminite Bar & Galactica Singularity & Phantoplasm)); +The Devourer of Gods; Calamity | Location | Item | Goal; (Ancient Manipulator & ((Armored Shell & Twisting Nether & Dark Plasma) | (Luminite Bar & Galactica Singularity & Polterplasm))) | (@getfixedboi & #Supreme Alchemist, Cirrus); # the_devourer_of_gods Cosmilite Bar; Calamity; #The Devourer of Gods; Cosmic Anvil; Calamity; Ancient Manipulator & Hardmode Anvil & Cosmilite Bar & Luminite Bar & Galactica Singularity & Exodium Cluster; -Nightmare Fuel; Calamity; Pumpkin Moon & The Devourer of Gods; +Nightmare Fuel; Calamity; (Pumpkin Moon & The Devourer of Gods) | Occult Skull Crown; +Occult Skull Crown; Calamity | Getfixedboi; @getfixedboi & #Evil Boss; // Revengeance or getfixedboi Endothermic Energy; Calamity; Frost Moon & The Devourer of Gods; -Darksun Fragment; Calamity; Solar Eclipse & The Devourer of Gods; +Darksun Fragment; Calamity; (Solar Eclipse & The Devourer of Gods) | Eclipse Mirror; Dark Sun Ring; Calamity; Cosmic Anvil & Uelibloom Bar & Darksun Fragment; -Ascendant Spirit Essence; Calamity; Ancient Manipulator & Phantoplasm & Nightmare Fuel & Endothermic Energy & Darksun Fragment; +Eclipse Mirror; Calamity; (Cosmic Anvil & Abyssal Mirror & Dark Matter Sheath & Darksun Fragment) | (@getfixedboi & #Ceaseless Void); +Ascendant Spirit Essence; Calamity; (Ancient Manipulator & Polterplasm & Nightmare Fuel & Endothermic Energy & Darksun Fragment) | (@getfixedboi & #Providence, the Profaned Goddess) | Elemental Gauntlet | Elemental Quiver | Nucleogenesis | Nanotech | Ethereal Talisman; +Fearmonger Armor; Calamity | Armor Minions(2); Cosmic Anvil & Spooky Armor & Cosmilite Bar & Soul of Fright & Ascendant Spirit Essence; +Silva Armor; Calamity | Armor Minions(5); Cosmic Anvil & Effulgent Feather & Ascendant Spirit Essence; +Elemental Gauntlet; Calamity; (Cosmic Anvil & Fire Gauntlet & Luminite Bar & Galactica Singularity & Ascendant Spirit Essence) | (@getfixedboi & #Storm Weaver); +Elemental Quiver; Calamity; (Cosmic Anvil & Magic Quiver & Deadshot Brooch & Luminite Bar & Galactica Singularity & Ascendant Spirit Essence) | (@getfixedboi & #Storm Weaver); +Nucleogenesis; Calamity; (Cosmic Anvil & Star-Tainted Generator & Statis' Curse & Luminite Bar & Galactica Singularity & Ascendant Spirit Essence) | (@getfixedboi & #Ceaseless Void); +Nanotech; Calamity; (Emblem & Raider's Talisman & Moonstone Crown & Electrician's Glove & Luminite Bar & Galactica Singularity & Ascendant Spirit Essence) | (@getfixedboi & #Signus, Envoy of the Devourer); +Ethereal Talisman; Calamity; (Cosmic Anvil & Sigil of Calamitas & Mana Flower & Luminite Bar & Galactica Singularity & Ascendant Spirit Essence) | (@getfixedboi & #Signus, Envoy of the Devourer); // Yharon, Dragon of Rebirth Yharon, Dragon of Rebirth; Calamity | Location | Item | Goal; Ancient Manipulator & Effulgent Feather & Life Alloy; # yharon_dragon_of_rebirth -Yharon Soul Fragment; Calamity; #Yharon, Dragon of Rebirth; -Auric Ore; Calamity; Yharon, Dragon of Rebirth & @pickaxe(250); -Auric Bar; Calamity; Cosmic Anvil & Auric Ore & Yharon Soul Fragment; -Zenith; Location | Item(Has Zenith) | Goal; Hardmode Anvil & Terra Blade & Meowmere & Star Wrath & Influx Waver & The Horseman's Blade & Seedler & Starfury & Bee Keeper & Enchanted Sword & Copper Shortsword & (~@calamity | Auric Bar); +Yharon Soul Fragment; Calamity; #Yharon, Dragon of Rebirth | The Wand | Auric Bar; +The Wand; Calamity; (Cosmic Anvil & Wand of Sparking & Yharon Soul Fragment) | (@getfixedboi & #The Devourer of Gods); +Auric Ore; Calamity; (Yharon, Dragon of Rebirth & (@pickaxe(250) | Wall of Flesh)) | Auric Bar; +Auric Bar; Calamity; (Cosmic Anvil & Auric Ore & Yharon Soul Fragment) | Shadowspec Bar; +Auric Tesla Armor; Calamity | Armor Minions(6); Cosmic Anvil & Silva Armor & Bloodflare Armor & Tarragon Armor & Auric Bar; +Infinity +1 Sword; Achievement | Grindy | Item(Has Zenith) | Goal(zenith); Hardmode Anvil & Terra Blade & Meowmere & Star Wrath & Influx Waver & The Horseman's Blade & Seedler & Starfury & Bee Keeper & Enchanted Sword & Copper Shortsword & (~@calamity | Auric Bar); # zenith // Exo Mechs Auric Quantum Cooling Cell; Calamity; Cosmic Anvil & Auric Bar & Mysterious Circuitry & Dubious Plating & Endothermic Energy & Core of Eleum & Voltage Regulation System; Exo Mechs; Calamity | Location | Item | Final Boss; Codebreaker Base & Decryption Computer & Auric Quantum Cooling Cell; -Supreme Witch, Calamitas; Calamity | Location | Item | Final Boss; Cosmic Anvil & Brimstone Slag & Auric Bar & Core of Calamity & Ashes of Calamity; +// XB-Infinity Hekate; Getfixedboi | Calamity; Codebreaker Base & Decryption Computer & Auric Quantum Cooling Cell & Blood Sample; // Currently, this boss doesn't affect logic at all +Supreme Witch, Calamitas; Calamity | Location | Item | Final Boss; (Cosmic Anvil & Brimstone Slag & Auric Bar & Core of Calamity & Ashes of Calamity) | (@getfixedboi & #Supreme Alchemist, Cirrus); +Supreme Alchemist, Cirrus; Getfixedboi | Calamity; Cosmic Anvil & Brimstone Slag & Auric Bar & Core of Calamity & Fabsol's Vodka; +THE LORDE; Getfixedboi | Calamity; Lihzahrd Temple; # calamity_final_bosses -Exo Prism; Calamity; #Exo Mechs; +Exo Prism; Calamity; #Exo Mechs | Shadowspec Bar; Draedon's Forge; Calamity; Cosmic Anvil & Hardmode Forge & Tinkerer's Workshop & Ancient Manipulator & Auric Bar & Exo Prism & Ascendant Spirit Essence; // Supreme Witch, Calamitas -Ashes of Annihilation; Calamity; #Supreme Witch, Calamitas; +Ashes of Annihilation; Calamity; #Supreme Witch, Calamitas | (@getfixedboi & #Calamitas Clone) | Shadowspec Bar; Shadowspec Bar; Calamity; Draedon's Forge & Auric Bar & Exo Prism & Ashes of Annihilation; Crystyl Crusher; Calamity | Pickaxe(1000); Draedon's Forge & Luminite Pickaxe & Blossom Pickaxe & Shadowspec Bar; Angelic Alliance; Calamity | Minions(2); Draedon's Forge & Hallowed Armor & Paladin's Shield & True Excalibur & Cross Necklace & Shadowspec Bar; +Demonshade Armor; Calamity | Armor Minions(10); Draedon's Forge & Shadowspec Bar; + +// Primordial Wyrm +Primordial Wyrm; Calamity | Location | Item | Goal; Rod of Discord | Normality Relocator; +# primordial_wyrm -// Adult Eidolon Wyrm; -Adult Eidolon Wyrm; Calamity | Location | Item | Goal; Rod of Discord | Normality Relocator; -# adult_eidolon_wyrm +// Boss Rush +Boss Rush; Calamity | Location | Item | Goal; Diving Gear | Neptune's Shell | (Aquatic Heart & Skeletron); // Might be obtainable earlier with Midas' Blessing +# boss_rush diff --git a/worlds/terraria/__init__.py b/worlds/terraria/__init__.py index abc10a7bb37c..20f56c8f63b3 100644 --- a/worlds/terraria/__init__.py +++ b/worlds/terraria/__init__.py @@ -1,11 +1,13 @@ # Look at `Rules.dsv` first to get an idea for how this works +import logging from typing import Union, Tuple, List, Dict, Set from worlds.AutoWorld import WebWorld, World from BaseClasses import Region, ItemClassification, Tutorial, CollectionState from .Checks import ( TerrariaItem, TerrariaLocation, + Condition, goals, rules, rule_indices, @@ -25,7 +27,7 @@ armor_minions, accessory_minions, ) -from .Options import TerrariaOptions +from .Options import TerrariaOptions, Goal class TerrariaWeb(WebWorld): @@ -55,8 +57,8 @@ class TerrariaWorld(World): item_name_to_id = item_name_to_id location_name_to_id = location_name_to_id - # Turn into an option when calamity is supported in the mod calamity = False + getfixedboi = False ter_items: List[str] ter_locations: List[str] @@ -70,72 +72,100 @@ def generate_early(self) -> None: ter_goals = {} goal_items = set() for location in goal_locations: - _, flags, _, _ = rules[rule_indices[location]] + flags = rules[rule_indices[location]].flags + if not self.options.calamity.value and "Calamity" in flags: + logging.warning( + f"Terraria goal `{Goal.name_lookup[self.options.goal.value]}`, which requires Calamity, was selected with Calamity disabled; enabling Calamity" + ) + self.options.calamity.value = True + item = flags.get("Item") or f"Post-{location}" ter_goals[item] = location goal_items.add(item) - achievements = self.options.achievements.value location_count = 0 locations = [] - for rule, flags, _, _ in rules[:goal]: + item_count = 0 + items = [] + for rule in rules[:goal]: + early = "Early" in rule.flags + grindy = "Grindy" in rule.flags + fishing = "Fishing" in rule.flags + if ( - (not self.calamity and "Calamity" in flags) - or (achievements < 1 and "Achievement" in flags) - or (achievements < 2 and "Grindy" in flags) - or (achievements < 3 and "Fishing" in flags) + (not self.options.getfixedboi.value and "Getfixedboi" in rule.flags) + or (self.options.getfixedboi.value and "Not Getfixedboi" in rule.flags) + or (not self.options.calamity.value and "Calamity" in rule.flags) + or (self.options.calamity.value and "Not Calamity" in rule.flags) or ( - rule == "Zenith" and self.options.goal.value != 11 - ) # Bad hardcoding - ): + self.options.getfixedboi.value + and self.options.calamity.value + and "Not Calamity Getfixedboi" in rule.flags + ) + or (not self.options.early_achievements.value and early) + or ( + not self.options.normal_achievements.value + and "Achievement" in rule.flags + and not early + and not grindy + and not fishing + ) + or (not self.options.grindy_achievements.value and grindy) + or (not self.options.fishing_achievements.value and fishing) + ) and rule.name not in goal_locations: continue - if "Location" in flags or ("Achievement" in flags and achievements >= 1): + + if "Location" in rule.flags or "Achievement" in rule.flags: # Location location_count += 1 - locations.append(rule) + locations.append(rule.name) elif ( - "Achievement" not in flags - and "Location" not in flags - and "Item" not in flags + "Achievement" not in rule.flags + and "Location" not in rule.flags + and "Item" not in rule.flags ): # Event - locations.append(rule) + locations.append(rule.name) - item_count = 0 - items = [] - for rule, flags, _, _ in rules[:goal]: - if not self.calamity and "Calamity" in flags: - continue - if "Item" in flags: + if "Item" in rule.flags and not ( + "Achievement" in rule.flags and rule.name not in goal_locations + ): # Item item_count += 1 - if rule not in goal_locations: - items.append(rule) + if rule.name not in goal_locations: + items.append(rule.name) elif ( - "Achievement" not in flags - and "Location" not in flags - and "Item" not in flags + "Achievement" not in rule.flags + and "Location" not in rule.flags + and "Item" not in rule.flags ): # Event - items.append(rule) + items.append(rule.name) - extra_checks = self.options.fill_extra_checks_with.value ordered_rewards = [ reward for reward in labels["ordered"] - if self.calamity or "Calamity" not in rewards[reward] + if self.options.calamity.value or "Calamity" not in rewards[reward] ] - while extra_checks == 1 and item_count < location_count and ordered_rewards: + while ( + self.options.fill_extra_checks_with.value == 1 + and item_count < location_count + and ordered_rewards + ): items.append(ordered_rewards.pop(0)) item_count += 1 random_rewards = [ reward for reward in labels["random"] - if self.calamity or "Calamity" not in rewards[reward] + if self.options.calamity.value or "Calamity" not in rewards[reward] ] self.multiworld.random.shuffle(random_rewards) - while extra_checks == 1 and item_count < location_count and random_rewards: + while ( + self.options.fill_extra_checks_with.value == 1 + and item_count < location_count + and random_rewards + ): items.append(random_rewards.pop(0)) item_count += 1 @@ -173,9 +203,9 @@ def create_item(self, item: str) -> TerrariaItem: def create_items(self) -> None: for item in self.ter_items: if (rule_index := rule_indices.get(item)) is not None: - _, flags, _, _ = rules[rule_index] - if "Item" in flags: - name = flags.get("Item") or f"Post-{item}" + rule = rules[rule_index] + if "Item" in rule.flags: + name = rule.flags.get("Item") or f"Post-{item}" else: continue else: @@ -186,8 +216,8 @@ def create_items(self) -> None: locked_items = {} for location in self.ter_locations: - _, flags, _, _ = rules[rule_indices[location]] - if "Location" not in flags and "Achievement" not in flags: + rule = rules[rule_indices[location]] + if "Location" not in rule.flags and "Achievement" not in rule.flags: if location in progression: classification = ItemClassification.progression else: @@ -202,95 +232,92 @@ def create_items(self) -> None: for location, item in locked_items.items(): self.multiworld.get_location(location, self.player).place_locked_item(item) - def check_condition( - self, - state, - sign: bool, - ty: int, - condition: Union[str, Tuple[Union[bool, None], list]], - arg: Union[str, int, None], - ) -> bool: - if ty == COND_ITEM: - _, flags, _, _ = rules[rule_indices[condition]] - if "Item" in flags: - name = flags.get("Item") or f"Post-{condition}" + def check_condition(self, state, condition: Condition) -> bool: + if condition.type == COND_ITEM: + rule = rules[rule_indices[condition.condition]] + if "Item" in rule.flags: + name = rule.flags.get("Item") or f"Post-{condition.condition}" else: - name = condition - - return sign == state.has(name, self.player) - elif ty == COND_LOC: - _, _, operator, conditions = rules[rule_indices[condition]] - return sign == self.check_conditions(state, operator, conditions) - elif ty == COND_FN: - if condition == "npc": - if type(arg) is not int: + name = condition.condition + + return condition.sign == state.has(name, self.player) + elif condition.type == COND_LOC: + rule = rules[rule_indices[condition.condition]] + return condition.sign == self.check_conditions( + state, rule.operator, rule.conditions + ) + elif condition.type == COND_FN: + if condition.condition == "npc": + if type(condition.argument) is not int: raise Exception("@npc requires an integer argument") npc_count = 0 for npc in npcs: if state.has(npc, self.player): npc_count += 1 - if npc_count >= arg: - return sign - - return not sign - elif condition == "calamity": - return sign == self.calamity - elif condition == "grindy": - return sign == (self.options.achievements.value >= 2) - elif condition == "pickaxe": - if type(arg) is not int: + if npc_count >= condition.argument: + return condition.sign + + return not condition.sign + elif condition.condition == "calamity": + return condition.sign == self.options.calamity.value + elif condition.condition == "grindy": + return condition.sign == self.options.grindy_achievements.value + elif condition.condition == "pickaxe": + if type(condition.argument) is not int: raise Exception("@pickaxe requires an integer argument") for pickaxe, power in pickaxes.items(): - if power >= arg and state.has(pickaxe, self.player): - return sign + if power >= condition.argument and state.has(pickaxe, self.player): + return condition.sign - return not sign - elif condition == "hammer": - if type(arg) is not int: + return not condition.sign + elif condition.condition == "hammer": + if type(condition.argument) is not int: raise Exception("@hammer requires an integer argument") for hammer, power in hammers.items(): - if power >= arg and state.has(hammer, self.player): - return sign + if power >= condition.argument and state.has(hammer, self.player): + return condition.sign - return not sign - elif condition == "mech_boss": - if type(arg) is not int: + return not condition.sign + elif condition.condition == "mech_boss": + if type(condition.argument) is not int: raise Exception("@mech_boss requires an integer argument") boss_count = 0 for boss in mech_bosses: if state.has(boss, self.player): boss_count += 1 - if boss_count >= arg: - return sign + if boss_count >= condition.argument: + return condition.sign - return not sign - elif condition == "minions": - if type(arg) is not int: + return not condition.sign + elif condition.condition == "minions": + if type(condition.argument) is not int: raise Exception("@minions requires an integer argument") minion_count = 1 for armor, minions in armor_minions.items(): if state.has(armor, self.player) and minions + 1 > minion_count: minion_count = minions + 1 - if minion_count >= arg: - return sign + if minion_count >= condition.argument: + return condition.sign for accessory, minions in accessory_minions.items(): if state.has(accessory, self.player): minion_count += minions - if minion_count >= arg: - return sign + if minion_count >= condition.argument: + return condition.sign - return not sign + return not condition.sign + elif condition.condition == "getfixedboi": + return condition.sign == self.options.getfixedboi.value else: - raise Exception(f"Unknown function {condition}") - elif ty == COND_GROUP: - operator, conditions = condition - return sign == self.check_conditions(state, operator, conditions) + raise Exception(f"Unknown function {condition.condition}") + elif condition.type == COND_GROUP: + operator, conditions = condition.condition + return condition.sign == self.check_conditions(state, operator, conditions) def check_conditions( self, @@ -310,22 +337,22 @@ def check_conditions( return True if len(conditions) > 1: raise Exception("Found multiple conditions without an operator") - return self.check_condition(state, *conditions[0]) + return self.check_condition(state, conditions[0]) elif operator: return any( - self.check_condition(state, *condition) for condition in conditions + self.check_condition(state, condition) for condition in conditions ) else: return all( - self.check_condition(state, *condition) for condition in conditions + self.check_condition(state, condition) for condition in conditions ) def set_rules(self) -> None: for location in self.ter_locations: def check(state: CollectionState, location=location): - _, _, operator, conditions = rules[rule_indices[location]] - return self.check_conditions(state, operator, conditions) + rule = rules[rule_indices[location]] + return self.check_conditions(state, rule.operator, rule.conditions) self.multiworld.get_location(location, self.player).access_rule = check @@ -336,6 +363,12 @@ def check(state: CollectionState, location=location): def fill_slot_data(self) -> Dict[str, object]: return { "goal": list(self.goal_locations), - "achievements": self.options.achievements.value, "deathlink": bool(self.options.death_link), + # The rest of these are included for trackers + "calamity": self.options.calamity.value, + "getfixedboi": self.options.getfixedboi.value, + "early_achievements": self.options.early_achievements.value, + "normal_achievements": self.options.normal_achievements.value, + "grindy_achievements": self.options.grindy_achievements.value, + "fishing_achievements": self.options.fishing_achievements.value, } From 125bf6f2702d9e7e8348c58dea639125a7778213 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Tue, 15 Apr 2025 17:09:27 -0500 Subject: [PATCH 0318/1218] Core: Post-KivyMD cleanup 2 and enhancements (#4876) * Adds a new class allowing TextFields to be resized * Resizes most CommonClient components to be more in-line with pre-KivyMD * Change the color of SelectableLabels and TooltipLabels to white * Fixed ClientTabs not correctly showing the current tab indicator * The server label now features a (i) icon to indicate that it can be hovered over. * Changed the default `primary_palette` to `Lightsteelblue` and the default `dynamic_scheme_name` to `VIBRANT` * Properly set attributes on `KivyJSONToTextParser.TextColors` so that proper typing can be utilized if an individual value is needed * Fixed some buttons being discolored permanently once pressed * Sped up the animations of button ripples and tab switching * Added the ability to insert a new tab to `GameManager.add_client_tab` * Hovering over the "Command" button in CommonClient will now display the contents of `/help` as a popup (note: this popup can be too large on default height for adequately large /help (SC2 Client), but should always fit fine on fullscreen). * Fixed invalid sizing of MessageBox errors, and changed their text color to white --- Launcher.py | 5 ++ data/client.kv | 41 ++++++++-- data/launcher.kv | 7 +- kvui.py | 197 ++++++++++++++++++++++++++++++++++++----------- 4 files changed, 198 insertions(+), 52 deletions(-) diff --git a/Launcher.py b/Launcher.py index d636ceab7426..29bd71764e4c 100644 --- a/Launcher.py +++ b/Launcher.py @@ -359,6 +359,11 @@ def build(self): self._refresh_components(self.current_filter) + # Uncomment to re-enable the Kivy console/live editor + # Ctrl-E to enable it, make sure numlock/capslock is disabled + # from kivy.modules.console import create_console + # create_console(Window, self.top_screen) + return self.top_screen def on_start(self): diff --git a/data/client.kv b/data/client.kv index ac0a45023c13..562986cd17a4 100644 --- a/data/client.kv +++ b/data/client.kv @@ -16,21 +16,30 @@ orange: "FF7700" # Used for command echo # KivyMD theming parameters theme_style: "Dark" # Light/Dark - primary_palette: "Green" # Many options - dynamic_scheme_name: "TONAL_SPOT" + primary_palette: "Lightsteelblue" # Many options + dynamic_scheme_name: "VIBRANT" dynamic_scheme_contrast: 0.0 : color: self.theme_cls.primaryColor +: + ripple_color: app.theme_cls.primaryColor + ripple_duration_in_fast: 0.2 +: + ripple_color: app.theme_cls.primaryColor + ripple_duration_in_fast: 0.2 : adaptive_height: True - font_size: dp(20) + theme_font_size: "Custom" + font_size: "20dp" markup: True halign: "left" : size_hint: 1, None + theme_text_color: "Custom" + text_color: 1, 1, 1, 1 canvas.before: Color: - rgba: (.0, 0.9, .1, .3) if self.selected else self.theme_cls.surfaceContainerLowColor + rgba: (self.theme_cls.primaryColor[0], self.theme_cls.primaryColor[1], self.theme_cls.primaryColor[2], .3) if self.selected else self.theme_cls.surfaceContainerLowestColor Rectangle: size: self.size pos: self.pos @@ -154,9 +163,12 @@ : size: self.texture_size size_hint: None, None + theme_font_size: "Custom" font_size: dp(18) pos_hint: {'center_y': 0.5, 'center_x': 0.5} halign: "left" + theme_text_color: "Custom" + text_color: (1, 1, 1, 1) canvas.before: Color: rgba: 0.2, 0.2, 0.2, 1 @@ -175,11 +187,28 @@ rectangle: self.x-2, self.y-2, self.width+4, self.height+4 : pos_hint: {'center_y': 0.5, 'center_x': 0.5} - +: size_hint_y: None - height: dp(30) + height: "30dp" multiline: False write_tab: False + pos_hint: {"center_x": 0.5, "center_y": 0.5} +: + height: "30dp" + multiline: False + write_tab: False + role: "medium" + size_hint_y: None + pos_hint: {"center_x": 0.5, "center_y": 0.5} +: + size_hint_y: None + height: "30dp" + multiline: False + write_tab: False + pos_hint: {"center_x": 0.5, "center_y": 0.5} +: + theme_text_color: "Custom" + text_color: 1, 1, 1, 1 : layout: layout bar_width: "12dp" diff --git a/data/launcher.kv b/data/launcher.kv index 03e1c3e07836..8c6a8288e485 100644 --- a/data/launcher.kv +++ b/data/launcher.kv @@ -5,12 +5,13 @@ size_hint: 1, None height: "75dp" context_button: context + focus_behavior: False MDRelativeLayout: ApAsyncImage: source: main.image size: (48, 48) - size_hint_y: None + size_hint: None, None pos_hint: {"center_x": 0.1, "center_y": 0.5} MDLabel: @@ -37,6 +38,7 @@ pos_hint:{"center_x": 0.85, "center_y": 0.8} theme_text_color: "Custom" text_color: app.theme_cls.primaryColor + detect_visible: False on_release: app.set_favorite(self) MDIconButton: @@ -46,6 +48,7 @@ pos_hint:{"center_x": 0.95, "center_y": 0.8} theme_text_color: "Custom" text_color: app.theme_cls.primaryColor + detect_visible: False MDButton: pos_hint:{"center_x": 0.9, "center_y": 0.25} @@ -53,7 +56,7 @@ height: "25dp" component: main.component on_release: app.component_action(self) - + detect_visible: False MDButtonText: text: "Open" diff --git a/kvui.py b/kvui.py index 81e3876fe5a5..9a8b7109fa66 100644 --- a/kvui.py +++ b/kvui.py @@ -43,8 +43,8 @@ from kivy.base import ExceptionHandler, ExceptionManager from kivy.clock import Clock from kivy.factory import Factory -from kivy.properties import BooleanProperty, ObjectProperty, NumericProperty -from kivy.metrics import dp +from kivy.properties import BooleanProperty, ObjectProperty, NumericProperty, StringProperty +from kivy.metrics import dp, sp from kivy.uix.widget import Widget from kivy.uix.layout import Layout from kivy.utils import escape_markup @@ -60,7 +60,7 @@ from kivymd.uix.gridlayout import MDGridLayout from kivymd.uix.floatlayout import MDFloatLayout from kivymd.uix.boxlayout import MDBoxLayout -from kivymd.uix.tab.tab import MDTabsPrimary, MDTabsItem, MDTabsItemText, MDTabsCarousel +from kivymd.uix.tab.tab import MDTabsSecondary, MDTabsItem, MDTabsItemText, MDTabsCarousel from kivymd.uix.menu import MDDropdownMenu from kivymd.uix.menu.menu import MDDropdownTextItem from kivymd.uix.dropdownitem import MDDropDownItem, MDDropDownItemText @@ -90,10 +90,10 @@ class ThemedApp(MDApp): def set_colors(self): text_colors = KivyJSONtoTextParser.TextColors() - self.theme_cls.theme_style = getattr(text_colors, "theme_style", "Dark") - self.theme_cls.primary_palette = getattr(text_colors, "primary_palette", "Green") - self.theme_cls.dynamic_scheme_name = getattr(text_colors, "dynamic_scheme_name", "TONAL_SPOT") - self.theme_cls.dynamic_scheme_contrast = getattr(text_colors, "dynamic_scheme_contrast", 0.0) + self.theme_cls.theme_style = text_colors.theme_style + self.theme_cls.primary_palette = text_colors.primary_palette + self.theme_cls.dynamic_scheme_name = text_colors.dynamic_scheme_name + self.theme_cls.dynamic_scheme_contrast = text_colors.dynamic_scheme_contrast class ImageIcon(MDButtonIcon, AsyncImage): @@ -166,6 +166,32 @@ def _update_bg(self, _, state: str): child.icon_color = self.theme_cls.primaryColor +# thanks kivymd +class ResizableTextField(MDTextField): + """ + Resizable MDTextField that manually overrides the builtin sizing. + + Note that in order to use this, the sizing must be specified from within a .kv rule. + """ + def __init__(self, *args, **kwargs): + # cursed rules override + rules = Builder.match(self) + textfield = next((rule for rule in rules if rule.name == f""), None) + if textfield: + subclasses = rules[rules.index(textfield) + 1:] + for subclass in subclasses: + height_rule = subclass.properties.get("height", None) + if height_rule: + height_rule.ignore_prev = True + super().__init__(args, kwargs) + + +def on_release(self: MDButton, *args): + super(MDButton, self).on_release(args) + self.on_leave() + +MDButton.on_release = on_release + # I was surprised to find this didn't already exist in kivy :( class HoverBehavior(object): """originally from https://stackoverflow.com/a/605348110""" @@ -266,11 +292,15 @@ def on_leave(self): self._tooltip = None -class ServerLabel(HovererableLabel, MDTooltip): +class ServerLabel(HoverBehavior, MDTooltip, MDBoxLayout): tooltip_display_delay = 0.1 + text: str = StringProperty("Server:") def __init__(self, *args, **kwargs): - super(HovererableLabel, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) + self.add_widget(MDIcon(icon="information", font_size=sp(15))) + self.add_widget(TooltipLabel(text=self.text, pos_hint={"center_x": 0.5, "center_y": 0.5}, + font_size=sp(15))) self._tooltip = ServerToolTip(text="Test") def on_enter(self): @@ -383,7 +413,6 @@ def __init__(self): for child in self.children: if child.__class__ == MDLabel: child.markup = True - print(self.text) # Currently, this only lets us do markup on text that does not have any icons # Create new TextItems as needed @@ -461,14 +490,13 @@ def on_items(self, instance, value: list) -> None: self.menu.data = self._items -class AutocompleteHintInput(MDTextField): +class AutocompleteHintInput(ResizableTextField): min_chars = NumericProperty(3) def __init__(self, **kwargs): super().__init__(**kwargs) - self.dropdown = MarkupDropdown(caller=self, position="bottom", border_margin=dp(24), width=self.width) - self.dropdown.bind(on_select=lambda instance, x: setattr(self, 'text', x)) + self.dropdown = MarkupDropdown(caller=self, position="bottom", border_margin=dp(2), width=self.width) self.bind(on_text_validate=self.on_message) self.bind(width=lambda instance, x: setattr(self.dropdown, "width", x)) @@ -485,8 +513,11 @@ def on_text(self, instance, value): def on_press(text): split_text = MarkupLabel(text=text).markup - return self.dropdown.select("".join(text_frag for text_frag in split_text - if not text_frag.startswith("["))) + self.set_text(self, "".join(text_frag for text_frag in split_text + if not text_frag.startswith("["))) + self.dropdown.dismiss() + self.focus = True + lowered = value.lower() for item_name in item_names: try: @@ -498,7 +529,7 @@ def on_press(text): text = text[:index] + "[b]" + text[index:index+len(value)]+"[/b]"+text[index+len(value):] self.dropdown.items.append({ "text": text, - "on_release": lambda: on_press(text), + "on_release": lambda txt=text: on_press(txt), "markup": True }) if not self.dropdown.parent: @@ -620,7 +651,7 @@ def apply_selection(self, rv, index, is_selected): self.selected = is_selected -class ConnectBarTextInput(MDTextField): +class ConnectBarTextInput(ResizableTextField): def insert_text(self, substring, from_undo=False): s = substring.replace("\n", "").replace("\r", "") return super(ConnectBarTextInput, self).insert_text(s, from_undo=from_undo) @@ -630,14 +661,14 @@ def is_command_input(string: str) -> bool: return len(string) > 0 and string[0] in "/!" -class CommandPromptTextInput(MDTextField): +class CommandPromptTextInput(ResizableTextField): MAXIMUM_HISTORY_MESSAGES = 50 def __init__(self, **kwargs) -> None: super().__init__(**kwargs) self._command_history_index = -1 self._command_history: typing.Deque[str] = deque(maxlen=CommandPromptTextInput.MAXIMUM_HISTORY_MESSAGES) - + def update_history(self, new_entry: str) -> None: self._command_history_index = -1 if is_command_input(new_entry): @@ -664,7 +695,7 @@ def keyboard_on_key_down( self._change_to_history_text_if_available(self._command_history_index - 1) return True return super().keyboard_on_key_down(window, keycode, text, modifiers) - + def _change_to_history_text_if_available(self, new_index: int) -> None: if new_index < -1: return @@ -682,29 +713,61 @@ class MessageBoxLabel(MDLabel): def __init__(self, **kwargs): super().__init__(**kwargs) self._label.refresh() - self.size = self._label.texture.size - if self.width + 50 > Window.width: - self.text_size[0] = Window.width - 50 - self._label.refresh() - self.size = self._label.texture.size def __init__(self, title, text, error=False, **kwargs): label = MessageBox.MessageBoxLabel(text=text) separator_color = [217 / 255, 129 / 255, 122 / 255, 1.] if error else [47 / 255., 167 / 255., 212 / 255, 1.] - super().__init__(title=title, content=label, size_hint=(None, None), width=max(100, int(label.width) + 40), + super().__init__(title=title, content=label, size_hint=(0.5, None), width=max(100, int(label.width) + 40), separator_color=separator_color, **kwargs) self.height += max(0, label.height - 18) -class ClientTabs(MDTabsPrimary): +class ClientTabs(MDTabsSecondary): carousel: MDTabsCarousel lock_swiping = True def __init__(self, *args, **kwargs): - self.carousel = MDTabsCarousel(lock_swiping=True) - super().__init__(*args, MDDivider(size_hint_y=None, height=dp(4)), self.carousel, **kwargs) + self.carousel = MDTabsCarousel(lock_swiping=True, anim_move_duration=0.2) + super().__init__(*args, MDDivider(size_hint_y=None, height=dp(1)), self.carousel, **kwargs) self.size_hint_y = 1 + def _check_panel_height(self, *args): + self.ids.tab_scroll.height = dp(38) + + def update_indicator( + self, x: float = 0.0, w: float = 0.0, instance: MDTabsItem = None + ) -> None: + def update_indicator(*args): + indicator_pos = (0, 0) + indicator_size = (0, 0) + + item_text_object = self._get_tab_item_text_icon_object() + + if item_text_object: + indicator_pos = ( + instance.x + dp(12), + self.indicator.pos[1] + if not self._tabs_carousel + else self._tabs_carousel.height, + ) + indicator_size = ( + instance.width - dp(24), + self.indicator_height, + ) + + Animation( + pos=indicator_pos, + size=indicator_size, + d=0 if not self.indicator_anim else self.indicator_duration, + t=self.indicator_transition, + ).start(self.indicator) + + if not instance: + self.indicator.pos = (x, self.indicator.pos[1]) + self.indicator.size = (w, self.indicator_height) + else: + Clock.schedule_once(update_indicator) + def remove_tab(self, tab, content=None): if content is None: content = tab.content @@ -713,6 +776,21 @@ def remove_tab(self, tab, content=None): self.on_size(self, self.size) +class CommandButton(MDButton, MDTooltip): + def __init__(self, *args, manager: "GameManager", **kwargs): + super().__init__(*args, **kwargs) + self.manager = manager + self._tooltip = ToolTip(text="Test") + + def on_enter(self): + self._tooltip.text = self.manager.commandprocessor.get_help_text() + self._tooltip.font_size = dp(20 - (len(self._tooltip.text) // 400)) # mostly guessing on the numbers here + self.display_tooltip() + + def on_leave(self): + self.animation_tooltip_dismiss() + + class GameManager(ThemedApp): logging_pairs = [ ("Client", "Archipelago"), @@ -767,19 +845,19 @@ def build(self) -> Layout: self.grid = MainLayout() self.grid.cols = 1 - self.connect_layout = MDBoxLayout(orientation="horizontal", size_hint_y=None, height=dp(70), + self.connect_layout = MDBoxLayout(orientation="horizontal", size_hint_y=None, height=dp(40), spacing=5, padding=(5, 10)) # top part - server_label = ServerLabel(halign="center") + server_label = ServerLabel(width=dp(75)) self.connect_layout.add_widget(server_label) self.server_connect_bar = ConnectBarTextInput(text=self.ctx.suggested_address or "archipelago.gg:", - size_hint_y=None, role="medium", - height=dp(70), multiline=False, write_tab=False) + pos_hint={"center_x": 0.5, "center_y": 0.5}) def connect_bar_validate(sender): if not self.ctx.server: self.connect_button_action(sender) + self.server_connect_bar.height = dp(30) self.server_connect_bar.bind(on_text_validate=connect_bar_validate) self.connect_layout.add_widget(self.server_connect_bar) self.server_connect_button = MDButton(MDButtonText(text="Connect"), style="filled", size=(dp(100), dp(70)), @@ -792,7 +870,7 @@ def connect_bar_validate(sender): self.grid.add_widget(self.progressbar) # middle part - self.tabs = ClientTabs() + self.tabs = ClientTabs(pos_hint={"center_x": 0.5, "center_y": 0.5}) self.tabs.add_widget(MDTabsItem(MDTabsItemText(text="All" if len(self.logging_pairs) > 1 else "Archipelago"))) self.log_panels["All"] = self.tabs.default_tab_content = UILog(*(logging.getLogger(logger_name) for logger_name, name in @@ -820,9 +898,10 @@ def connect_bar_validate(sender): self.grid.add_widget(self.main_area_container) # bottom part - bottom_layout = MDBoxLayout(orientation="horizontal", size_hint_y=None, height=dp(70), spacing=5, padding=(5, 10)) - info_button = MDButton(MDButtonText(text="Command:"), radius=5, style="filled", size=(dp(100), dp(70)), - size_hint_x=None, size_hint_y=None, pos_hint={"center_y": 0.575}) + bottom_layout = MDBoxLayout(orientation="horizontal", size_hint_y=None, height=dp(40), spacing=5, padding=(5, 10)) + info_button = CommandButton(MDButtonText(text="Command:", halign="left"), manager=self, radius=5, + style="filled", size=(dp(100), dp(70)), size_hint_x=None, size_hint_y=None, + pos_hint={"center_y": 0.575}) info_button.bind(on_release=self.command_button_action) bottom_layout.add_widget(info_button) self.textinput = CommandPromptTextInput(size_hint_y=None, height=dp(30), multiline=False, write_tab=False) @@ -843,15 +922,27 @@ def connect_bar_validate(sender): self.server_connect_bar.focus = True self.server_connect_bar.select_text(port_start if port_start > 0 else host_start, len(s)) + # Uncomment to enable the kivy live editor console + # Press Ctrl-E (with numlock/capslock) disabled to open + # from kivy.core.window import Window + # from kivy.modules import console + # console.create_console(Window, self.container) + return self.container - def add_client_tab(self, title: str, content: Widget) -> Widget: + def add_client_tab(self, title: str, content: Widget, index: int = -1) -> Widget: """Adds a new tab to the client window with a given title, and provides a given Widget as its content. Returns the new tab widget, with the provided content being placed on the tab as content.""" new_tab = MDTabsItem(MDTabsItemText(text=title)) new_tab.content = content - self.tabs.add_widget(new_tab) - self.tabs.carousel.add_widget(new_tab.content) + if -1 < index <= len(self.tabs.carousel.slides): + new_tab.bind(on_release=self.tabs.set_active_item) + new_tab._tabs = self.tabs + self.tabs.ids.container.add_widget(new_tab, index=index) + self.tabs.carousel.add_widget(new_tab.content, index=len(self.tabs.carousel.slides) - index) + else: + self.tabs.add_widget(new_tab) + self.tabs.carousel.add_widget(new_tab.content) return new_tab def update_texts(self, dt): @@ -1001,8 +1092,9 @@ class HintLayout(MDBoxLayout): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - boxlayout = MDBoxLayout(orientation="horizontal", size_hint_y=None, height=dp(55)) - boxlayout.add_widget(MDLabel(text="New Hint:", size_hint_x=None, size_hint_y=None, height=dp(55))) + boxlayout = MDBoxLayout(orientation="horizontal", size_hint_y=None, height=dp(40)) + boxlayout.add_widget(MDLabel(text="New Hint:", size_hint_x=None, size_hint_y=None, + height=dp(40), width=dp(75), halign="center", valign="center")) boxlayout.add_widget(AutocompleteHintInput()) self.add_widget(boxlayout) @@ -1012,7 +1104,7 @@ def fix_heights(self): if fix_func: fix_func() - + status_names: typing.Dict[HintStatus, str] = { HintStatus.HINT_FOUND: "Found", HintStatus.HINT_UNSPECIFIED: "Unspecified", @@ -1109,6 +1201,7 @@ def fix_heights(self): class ApAsyncImage(AsyncImage): + def is_uri(self, filename: str) -> bool: if filename.startswith("ap:"): return True @@ -1154,7 +1247,23 @@ def handle_exception(self, inst): class KivyJSONtoTextParser(JSONtoTextParser): # dummy class to absorb kvlang definitions class TextColors(Widget): - pass + white: str = StringProperty("FFFFFF") + black: str = StringProperty("000000") + red: str = StringProperty("EE0000") + green: str = StringProperty("00FF7F") + yellow: str = StringProperty("FAFAD2") + blue: str = StringProperty("6495ED") + magenta: str = StringProperty("EE00EE") + cyan: str = StringProperty("00EEEE") + slateblue: str = StringProperty("6D8BE8") + plum: str = StringProperty("AF99EF") + salmon: str = StringProperty("FA8072") + orange: str = StringProperty("FF7700") + # KivyMD parameters + theme_style: str = StringProperty("Dark") + primary_palette: str = StringProperty("Lightsteelblue") + dynamic_scheme_name: str = StringProperty("VIBRANT") + dynamic_scheme_contrast: int = NumericProperty(0) def __init__(self, *args, **kwargs): # we grab the color definitions from the .kv file, then overwrite the JSONtoTextParser default entries From 4b1898bfaf6522478ff738a3e99c5257903061f2 Mon Sep 17 00:00:00 2001 From: qwint Date: Thu, 17 Apr 2025 17:57:17 -0500 Subject: [PATCH 0319/1218] HK: fix docs whitespace (#4885) --- worlds/hk/docs/setup_en.md | 46 +++++++++++++++++------------------ worlds/hk/docs/setup_pt_br.md | 34 +++++++++++++------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/worlds/hk/docs/setup_en.md b/worlds/hk/docs/setup_en.md index 25f7c780758a..0375867d4059 100644 --- a/worlds/hk/docs/setup_en.md +++ b/worlds/hk/docs/setup_en.md @@ -3,34 +3,34 @@ ## Required Software * Download and unzip the Lumafly Mod Manager from the [Lumafly website](https://themulhima.github.io/Lumafly/). * A legal copy of Hollow Knight. - * Steam, Gog, and Xbox Game Pass versions of the game are supported. - * Windows, Mac, and Linux (including Steam Deck) are supported. + * Steam, Gog, and Xbox Game Pass versions of the game are supported. + * Windows, Mac, and Linux (including Steam Deck) are supported. ## Installing the Archipelago Mod using Lumafly 1. Launch Lumafly and ensure it locates your Hollow Knight installation directory. 2. Install the Archipelago mods by doing either of the following: - * Click one of the links below to allow Lumafly to install the mods. Lumafly will prompt for confirmation. - * [Archipelago and dependencies only](https://themulhima.github.io/Lumafly/commands/download/?mods=Archipelago) - * [Archipelago with rando essentials](https://themulhima.github.io/Lumafly/commands/download/?mods=Archipelago/Archipelago%20Map%20Mod/RecentItemsDisplay/DebugMod/RandoStats/Additional%20Timelines/CompassAlwaysOn/AdditionalMaps/) - (includes Archipelago Map Mod, RecentItemsDisplay, DebugMod, RandoStats, AdditionalTimelines, CompassAlwaysOn, - and AdditionalMaps). - * Click the "Install" button near the "Archipelago" mod entry. If desired, also install "Archipelago Map Mod" - to use as an in-game tracker. + * Click one of the links below to allow Lumafly to install the mods. Lumafly will prompt for confirmation. + * [Archipelago and dependencies only](https://themulhima.github.io/Lumafly/commands/download/?mods=Archipelago) + * [Archipelago with rando essentials](https://themulhima.github.io/Lumafly/commands/download/?mods=Archipelago/Archipelago%20Map%20Mod/RecentItemsDisplay/DebugMod/RandoStats/Additional%20Timelines/CompassAlwaysOn/AdditionalMaps/) + (includes Archipelago Map Mod, RecentItemsDisplay, DebugMod, RandoStats, AdditionalTimelines, CompassAlwaysOn, + and AdditionalMaps). + * Click the "Install" button near the "Archipelago" mod entry. If desired, also install "Archipelago Map Mod" + to use as an in-game tracker. 3. Launch the game, you're all set! ### What to do if Lumafly fails to find your installation directory 1. Find the directory manually. - * Xbox Game Pass: - 1. Enter the Xbox app and move your mouse over "Hollow Knight" on the left sidebar. - 2. Click the three points then click "Manage". - 3. Go to the "Files" tab and select "Browse...". - 4. Click "Hollow Knight", then "Content", then click the path bar and copy it. - * Steam: - 1. You likely put your Steam library in a non-standard place. If this is the case, you probably know where - it is. Find your steam library and then find the Hollow Knight folder and copy the path. - * Windows - `C:\Program Files (x86)\Steam\steamapps\common\Hollow Knight` - * Linux/Steam Deck - ~/.local/share/Steam/steamapps/common/Hollow Knight - * Mac - ~/Library/Application Support/Steam/steamapps/common/Hollow Knight/hollow_knight.app + * Xbox Game Pass: + 1. Enter the Xbox app and move your mouse over "Hollow Knight" on the left sidebar. + 2. Click the three points then click "Manage". + 3. Go to the "Files" tab and select "Browse...". + 4. Click "Hollow Knight", then "Content", then click the path bar and copy it. + * Steam: + 1. You likely put your Steam library in a non-standard place. If this is the case, you probably know where + it is. Find your steam library and then find the Hollow Knight folder and copy the path. + * Windows - `C:\Program Files (x86)\Steam\steamapps\common\Hollow Knight` + * Linux/Steam Deck - ~/.local/share/Steam/steamapps/common/Hollow Knight + * Mac - ~/Library/Application Support/Steam/steamapps/common/Hollow Knight/hollow_knight.app 2. Run Lumafly as an administrator and, when it asks you for the path, paste the path you copied. ## Configuring your YAML File @@ -49,9 +49,9 @@ website to generate a YAML using a graphical interface. 4. Enter the correct settings for your Archipelago server. 5. Hit **Start** to begin the game. The game will stall for a few seconds while it does all item placements. 6. The game will immediately drop you into the randomized game. - * If you are waiting for a countdown then wait for it to lapse before hitting Start. - * Or hit Start then pause the game once you're in it. - + * If you are waiting for a countdown then wait for it to lapse before hitting Start. + * Or hit Start then pause the game once you're in it. + ## Hints and other commands While playing in a multiworld, you can interact with the server using various commands listed in the [commands guide](/tutorial/Archipelago/commands/en). You can use the Archipelago Text Client to do this, diff --git a/worlds/hk/docs/setup_pt_br.md b/worlds/hk/docs/setup_pt_br.md index 9ae1ea89d566..511ee0d55293 100644 --- a/worlds/hk/docs/setup_pt_br.md +++ b/worlds/hk/docs/setup_pt_br.md @@ -3,28 +3,28 @@ ## Programas obrigatórios * Baixe e extraia o Lumafly Mod Manager (gerenciador de mods Lumafly) do [Site Lumafly](https://themulhima.github.io/Lumafly/). * Uma cópia legal de Hollow Knight. - * Versões Steam, Gog, e Xbox Game Pass do jogo são suportadas. - * Windows, Mac, e Linux (incluindo Steam Deck) são suportados. + * Versões Steam, Gog, e Xbox Game Pass do jogo são suportadas. + * Windows, Mac, e Linux (incluindo Steam Deck) são suportados. ## Instalando o mod Archipelago Mod usando Lumafly 1. Abra o Lumafly e confirme que ele localizou sua pasta de instalação do Hollow Knight. 2. Clique em "Install (instalar)" perto da opção "Archipelago" mod. - * Se quiser, instale também o "Archipelago Map Mod (mod do mapa do archipelago)" para usá-lo como rastreador dentro do jogo. + * Se quiser, instale também o "Archipelago Map Mod (mod do mapa do archipelago)" para usá-lo como rastreador dentro do jogo. 3. Abra o jogo, tudo preparado! ### O que fazer se o Lumafly falha em encontrar a sua pasta de instalação 1. Encontre a pasta manualmente. - * Xbox Game Pass: - 1. Entre no seu aplicativo Xbox e mova seu mouse em cima de "Hollow Knight" na sua barra da esquerda. - 2. Clique nos 3 pontos depois clique gerenciar. - 3. Vá nos arquivos e selecione procurar. - 4. Clique em "Hollow Knight", depois em "Content (Conteúdo)", depois clique na barra com o endereço e a copie. - * Steam: - 1. Você provavelmente colocou sua biblioteca Steam num local não padrão. Se esse for o caso você provavelmente sabe onde está. - . Encontre sua biblioteca Steam, depois encontre a pasta do Hollow Knight e copie seu endereço. - * Windows - `C:\Program Files (x86)\Steam\steamapps\common\Hollow Knight` - * Linux/Steam Deck - `~/.local/share/Steam/steamapps/common/Hollow Knight` - * Mac - `~/Library/Application Support/Steam/steamapps/common/Hollow Knight/hollow_knight.app` + * Xbox Game Pass: + 1. Entre no seu aplicativo Xbox e mova seu mouse em cima de "Hollow Knight" na sua barra da esquerda. + 2. Clique nos 3 pontos depois clique gerenciar. + 3. Vá nos arquivos e selecione procurar. + 4. Clique em "Hollow Knight", depois em "Content (Conteúdo)", depois clique na barra com o endereço e a copie. + * Steam: + 1. Você provavelmente colocou sua biblioteca Steam num local não padrão. Se esse for o caso você provavelmente sabe onde está. + Encontre sua biblioteca Steam, depois encontre a pasta do Hollow Knight e copie seu endereço. + * Windows - `C:\Program Files (x86)\Steam\steamapps\common\Hollow Knight` + * Linux/Steam Deck - `~/.local/share/Steam/steamapps/common/Hollow Knight` + * Mac - `~/Library/Application Support/Steam/steamapps/common/Hollow Knight/hollow_knight.app` 2. Rode o Lumafly como administrador e, quando ele perguntar pelo endereço do arquivo, cole o endereço do arquivo que você copiou. ## Configurando seu arquivo YAML @@ -43,9 +43,9 @@ para gerar o YAML usando a interface gráfica. 4. Coloque as configurações corretas do seu servidor Archipelago. 5. Aperte em **Começar**. O jogo vai travar por uns segundos enquanto ele coloca todos itens. 6. O jogo vai te colocar imediatamente numa partida randomizada. - * Se você está esperando uma contagem então espere ele cair antes de apertar começar. - * Ou clique em começar e pause o jogo enquanto estiver nele. - + * Se você está esperando uma contagem então espere ele cair antes de apertar começar. + * Ou clique em começar e pause o jogo enquanto estiver nele. + ## Dicas e outros comandos Enquanto jogar um multiworld, você pode interagir com o servidor usando vários comandos listados no [Guia de comandos](/tutorial/Archipelago/commands/en). Você pode usar o cliente de texto do Archipelago para isso, From 2dc55873f015f96ac0db361bd9495b66592715bc Mon Sep 17 00:00:00 2001 From: qwint Date: Thu, 17 Apr 2025 21:57:41 -0500 Subject: [PATCH 0320/1218] Webhost: add link to new session page (#4857) Co-authored-by: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> --- WebHostLib/templates/userContent.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WebHostLib/templates/userContent.html b/WebHostLib/templates/userContent.html index 4e3747f4f952..fa60deacd8c8 100644 --- a/WebHostLib/templates/userContent.html +++ b/WebHostLib/templates/userContent.html @@ -29,7 +29,8 @@

User Content

- Below is a list of all the content you have generated on this site. Rooms and seeds are listed separately. + Below is a list of all the content you have generated on this site. Rooms and seeds are listed separately.
+ Sessions can be saved or synced across devices using the Sessions Page.

Your Rooms

{% if rooms %} From 38bfb1087b6cda27cfe36d303012cde6d9dbd27a Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 18 Apr 2025 11:15:59 -0500 Subject: [PATCH 0321/1218] Webhost: fix get_seeds api endpoint (#4889) --- WebHostLib/api/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/api/user.py b/WebHostLib/api/user.py index 0ddb6fe83ed8..2524cc40a628 100644 --- a/WebHostLib/api/user.py +++ b/WebHostLib/api/user.py @@ -28,6 +28,6 @@ def get_seeds(): response.append({ "seed_id": seed.id, "creation_time": seed.creation_time, - "players": get_players(seed.slots), + "players": get_players(seed), }) return jsonify(response) From 552a6e7f1c6cac89f7d6766122eaf20717764351 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Fri, 18 Apr 2025 17:41:46 +0100 Subject: [PATCH 0322/1218] Stardew Valley: Precollect building items in deterministic order (#4883) #4239 refactored buildings, but introduced iteration of a set when precollecting the building items into start inventory. The iteration order of sets varies between separate Python processes due to set order being partially based on the hashes of the objects in the set and because Python processes each have a random hash seed by default. --- worlds/stardew_valley/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/stardew_valley/__init__.py b/worlds/stardew_valley/__init__.py index bf900742b97a..bad0ab9e683d 100644 --- a/worlds/stardew_valley/__init__.py +++ b/worlds/stardew_valley/__init__.py @@ -206,7 +206,8 @@ def precollect_building_items(self): if not building_progression.is_progressive: return - for building in building_progression.starting_buildings: + # starting_buildings is a set, so sort for deterministic order. + for building in sorted(building_progression.starting_buildings): item, quantity = building_progression.to_progressive_item(building) for _ in range(quantity): self.multiworld.push_precollected(self.create_item(item)) From 1b3ee0e94fdcc604c246bacedab4d60b9f0eb6cb Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 18 Apr 2025 20:41:09 +0200 Subject: [PATCH 0323/1218] Core: require clients to support overlapping IDs (#4451) --- MultiServer.py | 3 ++- test/hosting/client.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 05e93e678df2..c9e0ad8bfab0 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -46,7 +46,8 @@ SlotType, LocationStore, Hint, HintStatus from BaseClasses import ItemClassification -min_client_version = Version(0, 1, 6) + +min_client_version = Version(0, 5, 0) colorama.just_fix_windows_console() diff --git a/test/hosting/client.py b/test/hosting/client.py index b805bb6a2638..01572c442cc3 100644 --- a/test/hosting/client.py +++ b/test/hosting/client.py @@ -80,8 +80,8 @@ def connect(self) -> None: "version": { "class": "Version", "major": 0, - "minor": 4, - "build": 6, + "minor": 6, + "build": 0, }, "items_handling": 0, "tags": [], From a0c83b48547d0e170de2324ce0a2a851adb2dee6 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 18 Apr 2025 20:49:08 +0200 Subject: [PATCH 0324/1218] Core: no longer log ID ranges on generate (#4013) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- Main.py | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/Main.py b/Main.py index 528db10c64af..6f6a09619d17 100644 --- a/Main.py +++ b/Main.py @@ -56,29 +56,15 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No logger.info(f"Found {len(AutoWorld.AutoWorldRegister.world_types)} World Types:") longest_name = max(len(text) for text in AutoWorld.AutoWorldRegister.world_types) - max_item = 0 - max_location = 0 - for cls in AutoWorld.AutoWorldRegister.world_types.values(): - if cls.item_id_to_name: - max_item = max(max_item, max(cls.item_id_to_name)) - max_location = max(max_location, max(cls.location_id_to_name)) - - item_digits = len(str(max_item)) - location_digits = len(str(max_location)) item_count = len(str(max(len(cls.item_names) for cls in AutoWorld.AutoWorldRegister.world_types.values()))) location_count = len(str(max(len(cls.location_names) for cls in AutoWorld.AutoWorldRegister.world_types.values()))) - del max_item, max_location for name, cls in AutoWorld.AutoWorldRegister.world_types.items(): if not cls.hidden and len(cls.item_names) > 0: - logger.info(f" {name:{longest_name}}: {len(cls.item_names):{item_count}} " - f"Items (IDs: {min(cls.item_id_to_name):{item_digits}} - " - f"{max(cls.item_id_to_name):{item_digits}}) | " - f"{len(cls.location_names):{location_count}} " - f"Locations (IDs: {min(cls.location_id_to_name):{location_digits}} - " - f"{max(cls.location_id_to_name):{location_digits}})") - - del item_digits, location_digits, item_count, location_count + logger.info(f" {name:{longest_name}}: Items: {len(cls.item_names):{item_count}} | " + f"Locations: {len(cls.location_names):{location_count}}") + + del item_count, location_count # This assertion method should not be necessary to run if we are not outputting any multidata. if not args.skip_output and not args.spoiler_only: From cb3d35faf9c08b1900b310343c5c406eae501bcc Mon Sep 17 00:00:00 2001 From: ScootyPuffJr1 <77215594+ScootyPuffJr1@users.noreply.github.com> Date: Fri, 18 Apr 2025 14:50:51 -0400 Subject: [PATCH 0325/1218] LttP: Add keydrop locations to location groups (#4465) --- worlds/alttp/__init__.py | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index e4a04fe67e55..4a026f109b61 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -141,7 +141,7 @@ class ALTTPWorld(World): item_name_groups = item_name_groups location_name_groups = { "Blind's Hideout": {"Blind's Hideout - Top", "Blind's Hideout - Left", "Blind's Hideout - Right", - "Blind's Hideout - Far Left", "Blind's Hideout - Far Right"}, + "Blind's Hideout - Far Left", "Blind's Hideout - Far Right"}, "Kakariko Well": {"Kakariko Well - Top", "Kakariko Well - Left", "Kakariko Well - Middle", "Kakariko Well - Right", "Kakariko Well - Bottom"}, "Mini Moldorm Cave": {"Mini Moldorm Cave - Far Left", "Mini Moldorm Cave - Left", "Mini Moldorm Cave - Right", @@ -154,15 +154,23 @@ class ALTTPWorld(World): "Hookshot Cave": {"Hookshot Cave - Top Right", "Hookshot Cave - Top Left", "Hookshot Cave - Bottom Right", "Hookshot Cave - Bottom Left"}, "Hyrule Castle": {"Hyrule Castle - Boomerang Chest", "Hyrule Castle - Map Chest", - "Hyrule Castle - Zelda's Chest", "Sewers - Dark Cross", "Sewers - Secret Room - Left", - "Sewers - Secret Room - Middle", "Sewers - Secret Room - Right"}, + "Hyrule Castle - Zelda's Chest", "Hyrule Castle - Big Key Drop", + "Hyrule Castle - Boomerang Guard Key Drop", "Hyrule Castle - Map Guard Key Drop", + "Sewers - Dark Cross", "Sewers - Secret Room - Left", + "Sewers - Secret Room - Middle", "Sewers - Secret Room - Right", + "Sewers - Key Rat Key Drop"}, "Eastern Palace": {"Eastern Palace - Compass Chest", "Eastern Palace - Big Chest", "Eastern Palace - Cannonball Chest", "Eastern Palace - Big Key Chest", + "Eastern Palace - Dark Eyegore Key Drop", "Eastern Palace - Dark Square Pot Key", "Eastern Palace - Map Chest", "Eastern Palace - Boss"}, "Desert Palace": {"Desert Palace - Big Chest", "Desert Palace - Torch", "Desert Palace - Map Chest", - "Desert Palace - Compass Chest", "Desert Palace - Big Key Chest", "Desert Palace - Boss"}, + "Desert Palace - Beamos Hall Pot Key", "Desert Palace - Desert Tiles 1 Pot Key", + "Desert Palace - Desert Tiles 2 Pot Key", "Desert Palace - Compass Chest", + "Desert Palace - Big Key Chest", "Desert Palace - Boss"}, "Tower of Hera": {"Tower of Hera - Basement Cage", "Tower of Hera - Map Chest", "Tower of Hera - Big Key Chest", "Tower of Hera - Compass Chest", "Tower of Hera - Big Chest", "Tower of Hera - Boss"}, + "Castle Tower": {"Castle Tower - Room 03", "Castle Tower - Dark Maze", + "Castle Tower - Dark Archer Key Drop", "Castle Tower - Circle of Pots Key Drop"}, "Palace of Darkness": {"Palace of Darkness - Shooter Room", "Palace of Darkness - The Arena - Bridge", "Palace of Darkness - Stalfos Basement", "Palace of Darkness - Big Key Chest", "Palace of Darkness - The Arena - Ledge", "Palace of Darkness - Map Chest", @@ -173,25 +181,33 @@ class ALTTPWorld(World): "Swamp Palace": {"Swamp Palace - Entrance", "Swamp Palace - Map Chest", "Swamp Palace - Big Chest", "Swamp Palace - Compass Chest", "Swamp Palace - Big Key Chest", "Swamp Palace - West Chest", "Swamp Palace - Flooded Room - Left", "Swamp Palace - Flooded Room - Right", - "Swamp Palace - Waterfall Room", "Swamp Palace - Boss"}, + "Swamp Palace - Hookshot Pot Key", "Swamp Palace - Pot Row Pot Key", + "Swamp Palace - Trench 1 Pot Key", "Swamp Palace - Trench 2 Pot Key", + "Swamp Palace - Waterway Pot Key", "Swamp Palace - Waterfall Room", "Swamp Palace - Boss"}, "Thieves' Town": {"Thieves' Town - Big Key Chest", "Thieves' Town - Map Chest", "Thieves' Town - Compass Chest", "Thieves' Town - Ambush Chest", "Thieves' Town - Attic", "Thieves' Town - Big Chest", + "Thieves' Town - Hallway Pot Key", "Thieves' Town - Spike Switch Pot Key", "Thieves' Town - Blind's Cell", "Thieves' Town - Boss"}, "Skull Woods": {"Skull Woods - Map Chest", "Skull Woods - Pinball Room", "Skull Woods - Compass Chest", "Skull Woods - Pot Prison", "Skull Woods - Big Chest", "Skull Woods - Big Key Chest", + "Skull Woods - Spike Corner Key Drop", "Skull Woods - West Lobby Pot Key", "Skull Woods - Bridge Room", "Skull Woods - Boss"}, "Ice Palace": {"Ice Palace - Compass Chest", "Ice Palace - Freezor Chest", "Ice Palace - Big Chest", "Ice Palace - Freezor Chest", "Ice Palace - Big Chest", "Ice Palace - Iced T Room", "Ice Palace - Spike Room", "Ice Palace - Big Key Chest", "Ice Palace - Map Chest", + "Ice Palace - Conveyor Key Drop", "Ice Palace - Hammer Block Key Drop", + "Ice Palace - Jelly Key Drop", "Ice Palace - Many Pots Pot Key", "Ice Palace - Boss"}, "Misery Mire": {"Misery Mire - Big Chest", "Misery Mire - Map Chest", "Misery Mire - Main Lobby", "Misery Mire - Bridge Chest", "Misery Mire - Spike Chest", "Misery Mire - Compass Chest", - "Misery Mire - Big Key Chest", "Misery Mire - Boss"}, + "Misery Mire - Conveyor Crystal Key Drop", "Misery Mire - Fishbone Pot Key", + "Misery Mire - Spikes Pot Key", "Misery Mire - Big Key Chest", "Misery Mire - Boss"}, "Turtle Rock": {"Turtle Rock - Compass Chest", "Turtle Rock - Roller Room - Left", "Turtle Rock - Roller Room - Right", "Turtle Rock - Chain Chomps", "Turtle Rock - Big Key Chest", "Turtle Rock - Big Chest", "Turtle Rock - Crystaroller Room", "Turtle Rock - Eye Bridge - Bottom Left", "Turtle Rock - Eye Bridge - Bottom Right", "Turtle Rock - Eye Bridge - Top Left", "Turtle Rock - Eye Bridge - Top Right", + "Turtle Rock - Pokey 1 Key Drop", "Turtle Rock - Pokey 2 Key Drop", "Turtle Rock - Boss"}, "Ganons Tower": {"Ganons Tower - Bob's Torch", "Ganons Tower - Hope Room - Left", "Ganons Tower - Hope Room - Right", "Ganons Tower - Tile Room", @@ -204,10 +220,13 @@ class ALTTPWorld(World): "Ganons Tower - Randomizer Room - Bottom Left", "Ganons Tower - Randomizer Room - Bottom Right", "Ganons Tower - Bob's Chest", "Ganons Tower - Big Chest", "Ganons Tower - Big Key Room - Left", "Ganons Tower - Big Key Room - Right", "Ganons Tower - Big Key Chest", - "Ganons Tower - Mini Helmasaur Room - Left", "Ganons Tower - Mini Helmasaur Room - Right", - "Ganons Tower - Pre-Moldorm Chest", "Ganons Tower - Validation Chest"}, + "Ganons Tower - Conveyor Cross Pot Key", "Ganons Tower - Conveyor Star Pits Pot Key", + "Ganons Tower - Double Switch Pot Key", "Ganons Tower - Mini Helmasaur Room - Left", + "Ganons Tower - Mini Helmasaur Room - Right", "Ganons Tower - Pre-Moldorm Chest", + "Ganons Tower - Mini Helmasaur Key Drop", "Ganons Tower - Validation Chest"}, "Ganons Tower Climb": {"Ganons Tower - Mini Helmasaur Room - Left", "Ganons Tower - Mini Helmasaur Room - Right", - "Ganons Tower - Pre-Moldorm Chest", "Ganons Tower - Validation Chest"}, + "Ganons Tower - Mini Helmasaur Key Drop", "Ganons Tower - Pre-Moldorm Chest", + "Ganons Tower - Validation Chest"}, } hint_blacklist = {"Triforce"} From 1b51714f3b734d0c43e6fdffa006c692b12f8c50 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Fri, 18 Apr 2025 16:34:34 -0500 Subject: [PATCH 0326/1218] LTTP: Rip Lttp specific entrance code out of core and use Region helpers (#1960) --- BaseClasses.py | 7 +------ worlds/alttp/OverworldGlitchRules.py | 10 ++-------- worlds/alttp/Regions.py | 8 ++++---- worlds/alttp/Rules.py | 8 ++++---- worlds/alttp/SubClasses.py | 17 +++++++++++++++-- worlds/alttp/UnderworldGlitchRules.py | 14 ++++++-------- worlds/pokemon_rb/regions.py | 6 +++++- 7 files changed, 37 insertions(+), 33 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 4074108b4b05..ec3fa9cef17a 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1022,9 +1022,6 @@ class Entrance: connected_region: Optional[Region] = None randomization_group: int randomization_type: EntranceType - # LttP specific, TODO: should make a LttPEntrance - addresses = None - target = None def __init__(self, player: int, name: str = "", parent: Optional[Region] = None, randomization_group: int = 0, randomization_type: EntranceType = EntranceType.ONE_WAY) -> None: @@ -1043,10 +1040,8 @@ def can_reach(self, state: CollectionState) -> bool: return False - def connect(self, region: Region, addresses: Any = None, target: Any = None) -> None: + def connect(self, region: Region) -> None: self.connected_region = region - self.target = target - self.addresses = addresses region.entrances.append(self) def is_valid_source_transition(self, er_state: "ERPlacementState") -> bool: diff --git a/worlds/alttp/OverworldGlitchRules.py b/worlds/alttp/OverworldGlitchRules.py index 2da76234bd40..1a1c01525db7 100644 --- a/worlds/alttp/OverworldGlitchRules.py +++ b/worlds/alttp/OverworldGlitchRules.py @@ -2,8 +2,6 @@ Helper functions to deliver entrance/exit/region sets to OWG rules. """ -from BaseClasses import Entrance - from .StateHelpers import can_lift_heavy_rocks, can_boots_clip_lw, can_boots_clip_dw, can_get_glitched_speed_dw @@ -279,18 +277,14 @@ def create_no_logic_connections(player, world, connections): for entrance, parent_region, target_region, *rule_override in connections: parent = world.get_region(parent_region, player) target = world.get_region(target_region, player) - connection = Entrance(player, entrance, parent) - parent.exits.append(connection) - connection.connect(target) + parent.connect(target, entrance) def create_owg_connections(player, world, connections): for entrance, parent_region, target_region, *rule_override in connections: parent = world.get_region(parent_region, player) target = world.get_region(target_region, player) - connection = Entrance(player, entrance, parent) - parent.exits.append(connection) - connection.connect(target) + parent.connect(target, entrance) def set_owg_connection_rules(player, world, connections, default_rule): diff --git a/worlds/alttp/Regions.py b/worlds/alttp/Regions.py index f3dbbdc059f1..c2af7956373e 100644 --- a/worlds/alttp/Regions.py +++ b/worlds/alttp/Regions.py @@ -1,11 +1,11 @@ import collections import typing -from BaseClasses import Entrance, MultiWorld -from .SubClasses import LTTPRegion, LTTPRegionType +from BaseClasses import MultiWorld +from .SubClasses import LTTPEntrance, LTTPRegion, LTTPRegionType -def is_main_entrance(entrance: Entrance) -> bool: +def is_main_entrance(entrance: LTTPEntrance) -> bool: return entrance.parent_region.type in {LTTPRegionType.DarkWorld, LTTPRegionType.LightWorld} if entrance.parent_region.type else True @@ -410,7 +410,7 @@ def _create_region(world: MultiWorld, player: int, name: str, type: LTTPRegionTy ret = LTTPRegion(name, type, hint, player, world) if exits: for exit in exits: - ret.exits.append(Entrance(player, exit, ret)) + ret.create_exit(exit) if locations: for location in locations: if location in key_drop_data: diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index 47992947ac03..3f5081129aa9 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -3,7 +3,7 @@ from typing import Iterator, Set from Options import ItemsAccessibility -from BaseClasses import Entrance, MultiWorld +from BaseClasses import MultiWorld from worlds.generic.Rules import (add_item_rule, add_rule, forbid_item, item_name_in_location_names, location_item_name, set_rule, allow_self_locking_items) @@ -1071,9 +1071,8 @@ def swordless_rules(world, player): def add_connection(parent_name, target_name, entrance_name, world, player): parent = world.get_region(parent_name, player) target = world.get_region(target_name, player) - connection = Entrance(player, entrance_name, parent) - parent.exits.append(connection) - connection.connect(target) + parent.connect(target, entrance_name) + def standard_rules(world, player): @@ -1108,6 +1107,7 @@ def standard_rules(world, player): set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), lambda state: state.has('Big Key (Hyrule Castle)', player)) + def toss_junk_item(world, player): items = ['Rupees (20)', 'Bombs (3)', 'Arrows (10)', 'Rupees (5)', 'Rupee (1)', 'Bombs (10)', 'Single Arrow', 'Rupees (50)', 'Rupees (100)', 'Single Bomb', 'Bee', 'Bee Trap', diff --git a/worlds/alttp/SubClasses.py b/worlds/alttp/SubClasses.py index 328e28da9346..a3b1d778d670 100644 --- a/worlds/alttp/SubClasses.py +++ b/worlds/alttp/SubClasses.py @@ -2,11 +2,10 @@ from typing import Optional, TYPE_CHECKING from enum import IntEnum -from BaseClasses import Location, Item, ItemClassification, Region, MultiWorld +from BaseClasses import Entrance, Location, Item, ItemClassification, Region, MultiWorld if TYPE_CHECKING: from .Dungeons import Dungeon - from .Regions import LTTPRegion class ALttPLocation(Location): @@ -77,6 +76,19 @@ def dungeon_item(self) -> Optional[str]: return self.type +Addresses = int | list[int] | tuple[int, int, int, int, int, int, int, int, int, int, int, int, int] + + +class LTTPEntrance(Entrance): + addresses: Addresses | None = None + target: int | None = None + + def connect(self, region: Region, addresses: Addresses | None = None, target: int | None = None) -> None: + super().connect(region) + self.addresses = addresses + self.target = target + + class LTTPRegionType(IntEnum): LightWorld = 1 DarkWorld = 2 @@ -90,6 +102,7 @@ def is_indoors(self) -> bool: class LTTPRegion(Region): + entrance_type = LTTPEntrance type: LTTPRegionType # will be set after making connections. diff --git a/worlds/alttp/UnderworldGlitchRules.py b/worlds/alttp/UnderworldGlitchRules.py index 50397dea166c..2b18f67ed9b7 100644 --- a/worlds/alttp/UnderworldGlitchRules.py +++ b/worlds/alttp/UnderworldGlitchRules.py @@ -1,6 +1,6 @@ -from BaseClasses import Entrance from worlds.generic.Rules import set_rule, add_rule from .StateHelpers import can_bomb_clip, has_sword, has_beam_sword, has_fire_source, can_melt_things, has_misery_mire_medallion +from .SubClasses import LTTPEntrance # We actually need the logic to properly "mark" these regions as Light or Dark world. @@ -9,17 +9,15 @@ def underworld_glitch_connections(world, player): specrock = world.get_region('Spectacle Rock Cave (Bottom)', player) mire = world.get_region('Misery Mire (West)', player) - kikiskip = Entrance(player, 'Kiki Skip', specrock) - mire_to_hera = Entrance(player, 'Mire to Hera Clip', mire) - mire_to_swamp = Entrance(player, 'Hera to Swamp Clip', mire) - specrock.exits.append(kikiskip) - mire.exits.extend([mire_to_hera, mire_to_swamp]) + kikiskip = specrock.create_exit('Kiki Skip') + mire_to_hera = mire.create_exit('Mire to Hera Clip') + mire_to_swamp = mire.create_exit('Hera to Swamp Clip') if world.worlds[player].fix_fake_world: kikiskip.connect(world.get_entrance('Palace of Darkness Exit', player).connected_region) mire_to_hera.connect(world.get_entrance('Tower of Hera Exit', player).connected_region) mire_to_swamp.connect(world.get_entrance('Swamp Palace Exit', player).connected_region) - else: + else: kikiskip.connect(world.get_region('Palace of Darkness (Entrance)', player)) mire_to_hera.connect(world.get_region('Tower of Hera (Bottom)', player)) mire_to_swamp.connect(world.get_region('Swamp Palace (Entrance)', player)) @@ -37,7 +35,7 @@ def fake_pearl_state(state, player): # Sets the rules on where we can actually go using this clip. # Behavior differs based on what type of ER shuffle we're playing. -def dungeon_reentry_rules(world, player, clip: Entrance, dungeon_region: str, dungeon_exit: str): +def dungeon_reentry_rules(world, player, clip: LTTPEntrance, dungeon_region: str, dungeon_exit: str): fix_dungeon_exits = world.worlds[player].fix_palaceofdarkness_exit fix_fake_worlds = world.worlds[player].fix_fake_world diff --git a/worlds/pokemon_rb/regions.py b/worlds/pokemon_rb/regions.py index 84c9b2573547..5aa6243514b3 100644 --- a/worlds/pokemon_rb/regions.py +++ b/worlds/pokemon_rb/regions.py @@ -2640,9 +2640,13 @@ def __init__(self, player, name, parent, warp_id, address, flags): self.warp_id = warp_id self.address = address self.flags = flags + self.addresses = None + self.target = None def connect(self, entrance): - super().connect(entrance.parent_region, None, target=entrance.warp_id) + super().connect(entrance.parent_region) + self.addresses = None + self.target = entrance.warp_id def access_rule(self, state): if self.connected_region is None: From 57a716b57a7df9a6ca3ad2c4d2d7e5169bde7021 Mon Sep 17 00:00:00 2001 From: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> Date: Fri, 18 Apr 2025 17:41:38 -0400 Subject: [PATCH 0327/1218] LTTP: Update to options API (#4134) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/alttp/Bosses.py | 13 +- worlds/alttp/Dungeons.py | 4 +- worlds/alttp/EntranceShuffle.py | 100 ++--- worlds/alttp/ItemPool.py | 170 ++++----- worlds/alttp/Items.py | 4 +- worlds/alttp/Options.py | 6 +- worlds/alttp/OverworldGlitchRules.py | 20 +- worlds/alttp/Rom.py | 341 +++++++++--------- worlds/alttp/Rules.py | 155 ++++---- worlds/alttp/Shops.py | 56 +-- worlds/alttp/StateHelpers.py | 26 +- worlds/alttp/UnderworldGlitchRules.py | 6 +- worlds/alttp/__init__.py | 141 ++++---- worlds/alttp/test/dungeons/TestDungeon.py | 4 +- worlds/alttp/test/inverted/TestInverted.py | 6 +- .../test/inverted/TestInvertedBombRules.py | 2 +- .../TestInvertedMinor.py | 8 +- .../test/inverted_owg/TestInvertedOWG.py | 8 +- worlds/alttp/test/minor_glitches/TestMinor.py | 6 +- worlds/alttp/test/options/TestOpenPyramid.py | 2 +- worlds/alttp/test/owg/TestVanillaOWG.py | 6 +- worlds/alttp/test/vanilla/TestVanilla.py | 6 +- 22 files changed, 534 insertions(+), 556 deletions(-) diff --git a/worlds/alttp/Bosses.py b/worlds/alttp/Bosses.py index 02970edb9f55..54686f45ad29 100644 --- a/worlds/alttp/Bosses.py +++ b/worlds/alttp/Bosses.py @@ -102,7 +102,7 @@ def KholdstareDefeatRule(state, player: int) -> bool: state.has('Fire Rod', player) or ( state.has('Bombos', player) and - (has_sword(state, player) or state.multiworld.swordless[player]) + (has_sword(state, player) or state.multiworld.worlds[player].options.swordless) ) ) and ( @@ -111,7 +111,7 @@ def KholdstareDefeatRule(state, player: int) -> bool: ( state.has('Fire Rod', player) and state.has('Bombos', player) and - state.multiworld.swordless[player] and + state.multiworld.worlds[player].options.swordless and can_extend_magic(state, player, 16) ) ) @@ -137,7 +137,7 @@ def AgahnimDefeatRule(state, player: int) -> bool: def GanonDefeatRule(state, player: int) -> bool: - if state.multiworld.swordless[player]: + if state.multiworld.worlds[player].options.swordless: return state.has('Hammer', player) and \ has_fire_source(state, player) and \ state.has('Silver Bow', player) and \ @@ -146,7 +146,7 @@ def GanonDefeatRule(state, player: int) -> bool: can_hurt = has_beam_sword(state, player) common = can_hurt and has_fire_source(state, player) # silverless ganon may be needed in anything higher than no glitches - if state.multiworld.glitches_required[player] != 'no_glitches': + if state.multiworld.worlds[player].options.glitches_required != 'no_glitches': # need to light torch a sufficient amount of times return common and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) or ( state.has('Silver Bow', player) and can_shoot_arrows(state, player)) or @@ -248,7 +248,7 @@ def can_place_boss(boss: str, dungeon_name: str, level: Optional[str] = None) -> def place_boss(world: "ALTTPWorld", boss: str, location: str, level: Optional[str]) -> None: player = world.player - if location == 'Ganons Tower' and world.multiworld.mode[player] == 'inverted': + if location == 'Ganons Tower' and world.options.mode == 'inverted': location = 'Inverted Ganons Tower' logging.debug('Placing boss %s at %s', boss, location + (' (' + level + ')' if level else '')) world.dungeons[location].bosses[level] = BossFactory(boss, player) @@ -260,9 +260,8 @@ def format_boss_location(location_name: str, level: str) -> str: def place_bosses(world: "ALTTPWorld") -> None: multiworld = world.multiworld - player = world.player # will either be an int or a lower case string with ';' between options - boss_shuffle: Union[str, int] = multiworld.boss_shuffle[player].value + boss_shuffle: Union[str, int] = world.options.boss_shuffle.value already_placed_bosses: List[str] = [] remaining_locations: List[Tuple[str, str]] = [] # handle plando diff --git a/worlds/alttp/Dungeons.py b/worlds/alttp/Dungeons.py index 8405fc4480a1..39e8d7072bb5 100644 --- a/worlds/alttp/Dungeons.py +++ b/worlds/alttp/Dungeons.py @@ -66,7 +66,7 @@ def create_dungeons(world: "ALTTPWorld"): def make_dungeon(name, default_boss, dungeon_regions, big_key, small_keys, dungeon_items): dungeon = Dungeon(name, dungeon_regions, big_key, - [] if multiworld.small_key_shuffle[player] == small_key_shuffle.option_universal else small_keys, + [] if multiworld.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal else small_keys, dungeon_items, player) for item in dungeon.all_items: item.dungeon = dungeon @@ -143,7 +143,7 @@ def make_dungeon(name, default_boss, dungeon_regions, big_key, small_keys, dunge item_factory(['Small Key (Turtle Rock)'] * 6, world), item_factory(['Map (Turtle Rock)', 'Compass (Turtle Rock)'], world)) - if multiworld.mode[player] != 'inverted': + if multiworld.worlds[player].options.mode != 'inverted': AT = make_dungeon('Agahnims Tower', 'Agahnim', ['Agahnims Tower', 'Agahnim 1'], None, item_factory(['Small Key (Agahnims Tower)'] * 4, world), []) GT = make_dungeon('Ganons Tower', 'Agahnim2', diff --git a/worlds/alttp/EntranceShuffle.py b/worlds/alttp/EntranceShuffle.py index d0487494aa64..c062a17ea695 100644 --- a/worlds/alttp/EntranceShuffle.py +++ b/worlds/alttp/EntranceShuffle.py @@ -23,17 +23,17 @@ def link_entrances(world, player): connect_simple(world, exitname, regionname, player) # if we do not shuffle, set default connections - if world.entrance_shuffle[player] == 'vanilla': + if world.worlds[player].options.entrance_shuffle == 'vanilla': for exitname, regionname in default_connections: connect_simple(world, exitname, regionname, player) for exitname, regionname in default_dungeon_connections: connect_simple(world, exitname, regionname, player) - elif world.entrance_shuffle[player] == 'dungeons_simple': + elif world.worlds[player].options.entrance_shuffle == 'dungeons_simple': for exitname, regionname in default_connections: connect_simple(world, exitname, regionname, player) simple_shuffle_dungeons(world, player) - elif world.entrance_shuffle[player] == 'dungeons_full': + elif world.worlds[player].options.entrance_shuffle == 'dungeons_full': for exitname, regionname in default_connections: connect_simple(world, exitname, regionname, player) @@ -43,7 +43,7 @@ def link_entrances(world, player): lw_entrances = list(LW_Dungeon_Entrances) dw_entrances = list(DW_Dungeon_Entrances) - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': # must connect front of hyrule castle to do escape connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) else: @@ -56,7 +56,7 @@ def link_entrances(world, player): dw_entrances.append('Ganons Tower') dungeon_exits.append('Ganons Tower Exit') - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': # rest of hyrule castle must be in light world, so it has to be the one connected to east exit of desert hyrule_castle_exits = [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')] connect_mandatory_exits(world, lw_entrances, hyrule_castle_exits, list(LW_Dungeon_Entrances_Must_Exit), player) @@ -65,9 +65,9 @@ def link_entrances(world, player): connect_mandatory_exits(world, lw_entrances, dungeon_exits, list(LW_Dungeon_Entrances_Must_Exit), player) connect_mandatory_exits(world, dw_entrances, dungeon_exits, list(DW_Dungeon_Entrances_Must_Exit), player) connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player) - elif world.entrance_shuffle[player] == 'dungeons_crossed': + elif world.worlds[player].options.entrance_shuffle == 'dungeons_crossed': crossed_shuffle_dungeons(world, player) - elif world.entrance_shuffle[player] == 'simple': + elif world.worlds[player].options.entrance_shuffle == 'simple': simple_shuffle_dungeons(world, player) old_man_entrances = list(Old_Man_Entrances) @@ -138,7 +138,7 @@ def link_entrances(world, player): # place remaining doors connect_doors(world, single_doors, door_targets, player) - elif world.entrance_shuffle[player] == 'restricted': + elif world.worlds[player].options.entrance_shuffle == 'restricted': simple_shuffle_dungeons(world, player) lw_entrances = list(LW_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances) @@ -210,7 +210,7 @@ def link_entrances(world, player): # place remaining doors connect_doors(world, doors, door_targets, player) - elif world.entrance_shuffle[player] == 'full': + elif world.worlds[player].options.entrance_shuffle == 'full': skull_woods_shuffle(world, player) lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances) @@ -227,7 +227,7 @@ def link_entrances(world, player): # tavern back door cannot be shuffled yet connect_doors(world, ['Tavern North'], ['Tavern'], player) - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': # must connect front of hyrule castle to do escape connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) else: @@ -264,7 +264,7 @@ def link_entrances(world, player): pass else: #if the cave wasn't placed we get here connect_caves(world, lw_entrances, [], old_man_house, player) - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': # rest of hyrule castle must be in light world connect_caves(world, lw_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player) @@ -316,7 +316,7 @@ def link_entrances(world, player): # place remaining doors connect_doors(world, doors, door_targets, player) - elif world.entrance_shuffle[player] == 'crossed': + elif world.worlds[player].options.entrance_shuffle == 'crossed': skull_woods_shuffle(world, player) entrances = list(LW_Entrances + LW_Dungeon_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances + DW_Entrances + DW_Dungeon_Entrances + DW_Single_Cave_Doors) @@ -331,7 +331,7 @@ def link_entrances(world, player): # tavern back door cannot be shuffled yet connect_doors(world, ['Tavern North'], ['Tavern'], player) - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': # must connect front of hyrule castle to do escape connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) else: @@ -348,7 +348,7 @@ def link_entrances(world, player): #place must-exit caves connect_mandatory_exits(world, entrances, caves, must_exits, player) - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': # rest of hyrule castle must be dealt with connect_caves(world, entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player) @@ -394,7 +394,7 @@ def link_entrances(world, player): # place remaining doors connect_doors(world, entrances, door_targets, player) - elif world.entrance_shuffle[player] == 'insanity': + elif world.worlds[player].options.entrance_shuffle == 'insanity': # beware ye who enter here entrances = LW_Entrances + LW_Dungeon_Entrances + DW_Entrances + DW_Dungeon_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave'] @@ -431,7 +431,7 @@ def link_entrances(world, player): # tavern back door cannot be shuffled yet connect_doors(world, ['Tavern North'], ['Tavern'], player) - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': # cannot move uncle cave connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player) connect_exit(world, 'Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance Stairs', player) @@ -464,7 +464,7 @@ def link_entrances(world, player): connect_entrance(world, hole, hole_targets.pop(), player) # hyrule castle handling - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': # must connect front of hyrule castle to do escape connect_entrance(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) connect_exit(world, 'Hyrule Castle Exit (South)', 'Hyrule Castle Entrance (South)', player) @@ -544,12 +544,12 @@ def connect_reachable_exit(entrance, caves, doors): else: raise NotImplementedError( - f'{world.entrance_shuffle[player]} Shuffling not supported yet. Player {world.get_player_name(player)}') + f'{world.worlds[player].options.entrance_shuffle} Shuffling not supported yet. Player {world.get_player_name(player)}') - if world.glitches_required[player] in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: + if world.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: overworld_glitch_connections(world, player) # mandatory hybrid major glitches connections - if world.glitches_required[player] in ['hybrid_major_glitches', 'no_logic']: + if world.worlds[player].options.glitches_required in ['hybrid_major_glitches', 'no_logic']: underworld_glitch_connections(world, player) # check for swamp palace fix @@ -584,17 +584,17 @@ def link_inverted_entrances(world, player): connect_simple(world, exitname, regionname, player) # if we do not shuffle, set default connections - if world.entrance_shuffle[player] == 'vanilla': + if world.worlds[player].options.entrance_shuffle == 'vanilla': for exitname, regionname in inverted_default_connections: connect_simple(world, exitname, regionname, player) for exitname, regionname in inverted_default_dungeon_connections: connect_simple(world, exitname, regionname, player) - elif world.entrance_shuffle[player] == 'dungeons_simple': + elif world.worlds[player].options.entrance_shuffle == 'dungeons_simple': for exitname, regionname in inverted_default_connections: connect_simple(world, exitname, regionname, player) simple_shuffle_dungeons(world, player) - elif world.entrance_shuffle[player] == 'dungeons_full': + elif world.worlds[player].options.entrance_shuffle == 'dungeons_full': for exitname, regionname in inverted_default_connections: connect_simple(world, exitname, regionname, player) @@ -649,9 +649,9 @@ def link_inverted_entrances(world, player): connect_mandatory_exits(world, lw_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player) connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player) - elif world.entrance_shuffle[player] == 'dungeons_crossed': + elif world.worlds[player].options.entrance_shuffle == 'dungeons_crossed': inverted_crossed_shuffle_dungeons(world, player) - elif world.entrance_shuffle[player] == 'simple': + elif world.worlds[player].options.entrance_shuffle == 'simple': simple_shuffle_dungeons(world, player) old_man_entrances = list(Inverted_Old_Man_Entrances) @@ -748,7 +748,7 @@ def link_inverted_entrances(world, player): # place remaining doors connect_doors(world, single_doors, door_targets, player) - elif world.entrance_shuffle[player] == 'restricted': + elif world.worlds[player].options.entrance_shuffle == 'restricted': simple_shuffle_dungeons(world, player) lw_entrances = list(Inverted_LW_Entrances + Inverted_LW_Single_Cave_Doors) @@ -833,7 +833,7 @@ def link_inverted_entrances(world, player): doors = lw_entrances + dw_entrances # place remaining doors connect_doors(world, doors, door_targets, player) - elif world.entrance_shuffle[player] == 'full': + elif world.worlds[player].options.entrance_shuffle == 'full': skull_woods_shuffle(world, player) lw_entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors) @@ -984,7 +984,7 @@ def link_inverted_entrances(world, player): # place remaining doors connect_doors(world, doors, door_targets, player) - elif world.entrance_shuffle[player] == 'crossed': + elif world.worlds[player].options.entrance_shuffle == 'crossed': skull_woods_shuffle(world, player) entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors + Inverted_Old_Man_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_DW_Single_Cave_Doors) @@ -1095,7 +1095,7 @@ def link_inverted_entrances(world, player): # place remaining doors connect_doors(world, entrances, door_targets, player) - elif world.entrance_shuffle[player] == 'insanity': + elif world.worlds[player].options.entrance_shuffle == 'insanity': # beware ye who enter here entrances = Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Entrance (South)'] @@ -1254,10 +1254,10 @@ def connect_reachable_exit(entrance, caves, doors): else: raise NotImplementedError('Shuffling not supported yet') - if world.glitches_required[player] in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: + if world.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: overworld_glitch_connections(world, player) # mandatory hybrid major glitches connections - if world.glitches_required[player] in ['hybrid_major_glitches', 'no_logic']: + if world.worlds[player].options.glitches_required in ['hybrid_major_glitches', 'no_logic']: underworld_glitch_connections(world, player) # patch swamp drain @@ -1349,7 +1349,7 @@ def scramble_holes(world, player): else: hole_targets.append(('Pyramid Exit', 'Pyramid')) - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': # cannot move uncle cave connect_two_way(world, 'Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', player) connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player) @@ -1358,14 +1358,14 @@ def scramble_holes(world, player): hole_targets.append(('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance')) # do not shuffle sanctuary into pyramid hole unless shuffle is crossed - if world.entrance_shuffle[player] == 'crossed': + if world.worlds[player].options.entrance_shuffle == 'crossed': hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) if world.shuffle_ganon: world.random.shuffle(hole_targets) exit, target = hole_targets.pop() connect_two_way(world, 'Pyramid Entrance', exit, player) connect_entrance(world, 'Pyramid Hole', target, player) - if world.entrance_shuffle[player] != 'crossed': + if world.worlds[player].options.entrance_shuffle != 'crossed': hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) world.random.shuffle(hole_targets) @@ -1400,14 +1400,14 @@ def scramble_inverted_holes(world, player): hole_targets.append(('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance')) # do not shuffle sanctuary into pyramid hole unless shuffle is crossed - if world.entrance_shuffle[player] == 'crossed': + if world.worlds[player].options.entrance_shuffle == 'crossed': hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) if world.shuffle_ganon: world.random.shuffle(hole_targets) exit, target = hole_targets.pop() connect_two_way(world, 'Inverted Pyramid Entrance', exit, player) connect_entrance(world, 'Inverted Pyramid Hole', target, player) - if world.entrance_shuffle[player] != 'crossed': + if world.worlds[player].options.entrance_shuffle != 'crossed': hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) world.random.shuffle(hole_targets) @@ -1430,15 +1430,15 @@ def connect_random(world, exitlist, targetlist, player, two_way=False): def connect_mandatory_exits(world, entrances, caves, must_be_exits, player): # Keeps track of entrances that cannot be used to access each exit / cave - if world.mode[player] == 'inverted': + if world.worlds[player].options.mode == 'inverted': invalid_connections = Inverted_Must_Exit_Invalid_Connections.copy() else: invalid_connections = Must_Exit_Invalid_Connections.copy() invalid_cave_connections = defaultdict(set) - if world.glitches_required[player] in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: + if world.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: from . import OverworldGlitchRules - for entrance in OverworldGlitchRules.get_non_mandatory_exits(world.mode[player] == 'inverted'): + for entrance in OverworldGlitchRules.get_non_mandatory_exits(world.worlds[player].options.mode == 'inverted'): invalid_connections[entrance] = set() if entrance in must_be_exits: must_be_exits.remove(entrance) @@ -1449,7 +1449,7 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player): world.random.shuffle(caves) # Handle inverted Aga Tower - if it depends on connections, then so does Hyrule Castle Ledge - if world.mode[player] == 'inverted': + if world.worlds[player].options.mode == 'inverted': for entrance in invalid_connections: if world.get_entrance(entrance, player).connected_region == world.get_region('Inverted Agahnims Tower', player): @@ -1490,7 +1490,7 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player): entrance = next(e for e in entrances[::-1] if e not in invalid_connections[exit]) cave_entrances.append(entrance) entrances.remove(entrance) - connect_two_way(world,entrance,cave_exit, player) + connect_two_way(world, entrance, cave_exit, player) if entrance not in invalid_connections: invalid_connections[exit] = set() if all(entrance in invalid_connections for entrance in cave_entrances): @@ -1564,7 +1564,7 @@ def simple_shuffle_dungeons(world, player): dungeon_entrances = ['Eastern Palace', 'Tower of Hera', 'Thieves Town', 'Skull Woods Final Section', 'Palace of Darkness', 'Ice Palace', 'Misery Mire', 'Swamp Palace'] dungeon_exits = ['Eastern Palace Exit', 'Tower of Hera Exit', 'Thieves Town Exit', 'Skull Woods Final Section Exit', 'Palace of Darkness Exit', 'Ice Palace Exit', 'Misery Mire Exit', 'Swamp Palace Exit'] - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': if not world.shuffle_ganon: connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) else: @@ -1579,13 +1579,13 @@ def simple_shuffle_dungeons(world, player): # mix up 4 door dungeons multi_dungeons = ['Desert', 'Turtle Rock'] - if world.mode[player] == 'open' or (world.mode[player] == 'inverted' and world.shuffle_ganon): + if world.worlds[player].options.mode == 'open' or (world.worlds[player].options.mode == 'inverted' and world.shuffle_ganon): multi_dungeons.append('Hyrule Castle') world.random.shuffle(multi_dungeons) dp_target = multi_dungeons[0] tr_target = multi_dungeons[1] - if world.mode[player] not in ['open', 'inverted'] or (world.mode[player] == 'inverted' and world.shuffle_ganon is False): + if world.worlds[player].options.mode not in ['open', 'inverted'] or (world.worlds[player].options.mode == 'inverted' and world.shuffle_ganon is False): # place hyrule castle as intended hc_target = 'Hyrule Castle' else: @@ -1593,7 +1593,7 @@ def simple_shuffle_dungeons(world, player): # ToDo improve this? - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': if hc_target == 'Hyrule Castle': connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) connect_two_way(world, 'Hyrule Castle Entrance (East)', 'Hyrule Castle Exit (East)', player) @@ -1708,7 +1708,7 @@ def crossed_shuffle_dungeons(world, player: int): dungeon_entrances.append('Ganons Tower') dungeon_exits.append('Ganons Tower Exit') - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': # must connect front of hyrule castle to do escape connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) else: @@ -1718,7 +1718,7 @@ def crossed_shuffle_dungeons(world, player: int): connect_mandatory_exits(world, dungeon_entrances, dungeon_exits, LW_Dungeon_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit, player) - if world.mode[player] == 'standard': + if world.worlds[player].options.mode == 'standard': connect_caves(world, dungeon_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player) connect_caves(world, dungeon_entrances, [], dungeon_exits, player) @@ -1823,14 +1823,14 @@ def tuplize_lists_in_list(ls): def plando_connect(world, player: int): - if world.plando_connections[player]: - for connection in world.plando_connections[player]: + if world.worlds[player].options.plando_connections: + for connection in world.worlds[player].options.plando_connections: func = lookup[connection.direction] try: func(world, connection.entrance, connection.exit, player) except Exception as e: raise Exception(f"Could not connect using {connection}") from e - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': mark_light_world_regions(world, player) else: mark_dark_world_regions(world, player) diff --git a/worlds/alttp/ItemPool.py b/worlds/alttp/ItemPool.py index 77d02f9770cc..2b99ef8a739c 100644 --- a/worlds/alttp/ItemPool.py +++ b/worlds/alttp/ItemPool.py @@ -226,25 +226,25 @@ def generate_itempool(world): player = world.player multiworld = world.multiworld - if multiworld.item_pool[player].current_key not in difficulties: - raise NotImplementedError(f"Diffulty {multiworld.item_pool[player]}") - if multiworld.goal[player] not in ('ganon', 'pedestal', 'bosses', 'triforce_hunt', 'local_triforce_hunt', - 'ganon_triforce_hunt', 'local_ganon_triforce_hunt', 'crystals', - 'ganon_pedestal'): - raise NotImplementedError(f"Goal {multiworld.goal[player]} for player {player}") - if multiworld.mode[player] not in ('open', 'standard', 'inverted'): - raise NotImplementedError(f"Mode {multiworld.mode[player]} for player {player}") - if multiworld.timer[player] not in (False, 'display', 'timed', 'timed_ohko', 'ohko', 'timed_countdown'): - raise NotImplementedError(f"Timer {multiworld.timer[player]} for player {player}") - - if multiworld.timer[player] in ['ohko', 'timed_ohko']: + if world.options.item_pool.current_key not in difficulties: + raise NotImplementedError(f"Diffulty {world.options.item_pool}") + if world.options.goal not in ('ganon', 'pedestal', 'bosses', 'triforce_hunt', 'local_triforce_hunt', + 'ganon_triforce_hunt', 'local_ganon_triforce_hunt', 'crystals', + 'ganon_pedestal'): + raise NotImplementedError(f"Goal {world.options.goal} for player {player}") + if world.options.mode not in ('open', 'standard', 'inverted'): + raise NotImplementedError(f"Mode {world.options.mode} for player {player}") + if world.options.timer not in (False, 'display', 'timed', 'timed_ohko', 'ohko', 'timed_countdown'): + raise NotImplementedError(f"Timer {world.options.timer} for player {player}") + + if world.options.timer in ['ohko', 'timed_ohko']: world.can_take_damage = False - if multiworld.goal[player] in ['pedestal', 'triforce_hunt', 'local_triforce_hunt']: + if world.options.goal in ['pedestal', 'triforce_hunt', 'local_triforce_hunt']: multiworld.push_item(multiworld.get_location('Ganon', player), item_factory('Nothing', world), False) else: multiworld.push_item(multiworld.get_location('Ganon', player), item_factory('Triforce', world), False) - if multiworld.goal[player] in ['triforce_hunt', 'local_triforce_hunt']: + if world.options.goal in ['triforce_hunt', 'local_triforce_hunt']: region = multiworld.get_region('Light World', player) loc = ALttPLocation(player, "Murahdahla", parent=region) @@ -288,7 +288,7 @@ def generate_itempool(world): for item in precollected_items: multiworld.push_precollected(item_factory(item, world)) - if multiworld.mode[player] == 'standard' and not has_melee_weapon(multiworld.state, player): + if world.options.mode == 'standard' and not has_melee_weapon(multiworld.state, player): if "Link's Uncle" not in placed_items: found_sword = False found_bow = False @@ -304,10 +304,10 @@ def generate_itempool(world): elif item in ['Hammer', 'Fire Rod', 'Cane of Somaria', 'Cane of Byrna']: if item not in possible_weapons: possible_weapons.append(item) - elif (item == 'Bombs (10)' and (not multiworld.bombless_start[player]) and item not in + elif (item == 'Bombs (10)' and (not world.options.bombless_start) and item not in possible_weapons): possible_weapons.append(item) - elif (item in ['Bomb Upgrade (+10)', 'Bomb Upgrade (50)'] and multiworld.bombless_start[player] and item + elif (item in ['Bomb Upgrade (+10)', 'Bomb Upgrade (50)'] and world.options.bombless_start and item not in possible_weapons): possible_weapons.append(item) @@ -315,21 +315,21 @@ def generate_itempool(world): placed_items["Link's Uncle"] = starting_weapon pool.remove(starting_weapon) if (placed_items["Link's Uncle"] in ['Bow', 'Progressive Bow', 'Bombs (10)', 'Bomb Upgrade (+10)', - 'Bomb Upgrade (50)', 'Cane of Somaria', 'Cane of Byrna'] and multiworld.enemy_health[player] not in ['default', 'easy']): - if multiworld.bombless_start[player] and "Bomb Upgrade" not in placed_items["Link's Uncle"]: + 'Bomb Upgrade (50)', 'Cane of Somaria', 'Cane of Byrna'] and world.options.enemy_health not in ['default', 'easy']): + if world.options.bombless_start and "Bomb Upgrade" not in placed_items["Link's Uncle"]: if 'Bow' in placed_items["Link's Uncle"]: - multiworld.worlds[player].escape_assist.append('arrows') + world.escape_assist.append('arrows') elif 'Cane' in placed_items["Link's Uncle"]: - multiworld.worlds[player].escape_assist.append('magic') + world.escape_assist.append('magic') else: - multiworld.worlds[player].escape_assist.append('bombs') + world.escape_assist.append('bombs') for (location, item) in placed_items.items(): multiworld.get_location(location, player).place_locked_item(item_factory(item, world)) items = item_factory(pool, world) # convert one Progressive Bow into Progressive Bow (Alt), in ID only, for ganon silvers hint text - if multiworld.worlds[player].has_progressive_bows: + if world.has_progressive_bows: for item in items: if item.code == 0x64: # Progressive Bow item.code = 0x65 # Progressive Bow (Alt) @@ -338,21 +338,21 @@ def generate_itempool(world): if clock_mode: world.clock_mode = clock_mode - multiworld.worlds[player].treasure_hunt_required = treasure_hunt_required % 999 - multiworld.worlds[player].treasure_hunt_total = treasure_hunt_total + world.treasure_hunt_required = treasure_hunt_required % 999 + world.treasure_hunt_total = treasure_hunt_total dungeon_items = [item for item in get_dungeon_item_pool_player(world) - if item.name not in multiworld.worlds[player].dungeon_local_item_names] + if item.name not in world.dungeon_local_item_names] for key_loc in key_drop_data: key_data = key_drop_data[key_loc] drop_item = item_factory(key_data[3], world) - if not multiworld.key_drop_shuffle[player]: + if not world.options.key_drop_shuffle: if drop_item in dungeon_items: dungeon_items.remove(drop_item) else: dungeon = drop_item.name.split("(")[1].split(")")[0] - if multiworld.mode[player] == 'inverted': + if world.options.mode == 'inverted': if dungeon == "Agahnims Tower": dungeon = "Inverted Agahnims Tower" if dungeon == "Ganons Tower": @@ -365,7 +365,7 @@ def generate_itempool(world): loc = multiworld.get_location(key_loc, player) loc.place_locked_item(drop_item) loc.address = None - elif "Small" in key_data[3] and multiworld.small_key_shuffle[player] == small_key_shuffle.option_universal: + elif "Small" in key_data[3] and world.options.small_key_shuffle == small_key_shuffle.option_universal: # key drop shuffle and universal keys are on. Add universal keys in place of key drop keys. multiworld.itempool.append(item_factory(GetBeemizerItem(multiworld, player, 'Small Key (Universal)'), world)) dungeon_item_replacements = sum(difficulties[world.options.item_pool.current_key].extras, []) * 2 @@ -373,10 +373,10 @@ def generate_itempool(world): for x in range(len(dungeon_items)-1, -1, -1): item = dungeon_items[x] - if ((multiworld.small_key_shuffle[player] == small_key_shuffle.option_start_with and item.type == 'SmallKey') - or (multiworld.big_key_shuffle[player] == big_key_shuffle.option_start_with and item.type == 'BigKey') - or (multiworld.compass_shuffle[player] == compass_shuffle.option_start_with and item.type == 'Compass') - or (multiworld.map_shuffle[player] == map_shuffle.option_start_with and item.type == 'Map')): + if ((world.options.small_key_shuffle == small_key_shuffle.option_start_with and item.type == 'SmallKey') + or (world.options.big_key_shuffle == big_key_shuffle.option_start_with and item.type == 'BigKey') + or (world.options.compass_shuffle == compass_shuffle.option_start_with and item.type == 'Compass') + or (world.options.map_shuffle == map_shuffle.option_start_with and item.type == 'Map')): dungeon_items.pop(x) multiworld.push_precollected(item) multiworld.itempool.append(item_factory(dungeon_item_replacements.pop(), world)) @@ -384,7 +384,7 @@ def generate_itempool(world): set_up_shops(multiworld, player) - if multiworld.retro_bow[player]: + if world.options.retro_bow: shop_items = 0 shop_locations = [location for shop_locations in (shop.region.locations for shop in multiworld.shops if shop.type == ShopType.Shop and shop.region.player == player) for location in shop_locations if @@ -395,12 +395,12 @@ def generate_itempool(world): else: shop_items += 1 else: - shop_items = min(multiworld.shop_item_slots[player], 30 if multiworld.include_witch_hut[player] else 27) + shop_items = min(world.options.shop_item_slots, 30 if world.options.include_witch_hut else 27) - if multiworld.shuffle_capacity_upgrades[player]: + if world.options.shuffle_capacity_upgrades: shop_items += 2 - chance_100 = int(multiworld.retro_bow[player]) * 0.25 + int( - multiworld.small_key_shuffle[player] == small_key_shuffle.option_universal) * 0.5 + chance_100 = int(world.options.retro_bow) * 0.25 + int( + world.options.small_key_shuffle == small_key_shuffle.option_universal) * 0.5 for _ in range(shop_items): if multiworld.random.random() < chance_100: items.append(item_factory(GetBeemizerItem(multiworld, player, "Rupees (100)"), world)) @@ -410,19 +410,19 @@ def generate_itempool(world): multiworld.random.shuffle(items) pool_count = len(items) new_items = ["Triforce Piece" for _ in range(additional_triforce_pieces)] - if multiworld.shuffle_capacity_upgrades[player] or multiworld.bombless_start[player]: - progressive = multiworld.progressive[player] + if world.options.shuffle_capacity_upgrades or world.options.bombless_start: + progressive = world.options.progressive progressive = multiworld.random.choice([True, False]) if progressive == 'grouped_random' else progressive == 'on' - if multiworld.shuffle_capacity_upgrades[player] == "on_combined": + if world.options.shuffle_capacity_upgrades == "on_combined": new_items.append("Bomb Upgrade (50)") - elif multiworld.shuffle_capacity_upgrades[player] == "on": + elif world.options.shuffle_capacity_upgrades == "on": new_items += ["Bomb Upgrade (+5)"] * 6 new_items.append("Bomb Upgrade (+5)" if progressive else "Bomb Upgrade (+10)") - if multiworld.shuffle_capacity_upgrades[player] != "on_combined" and multiworld.bombless_start[player]: + if world.options.shuffle_capacity_upgrades != "on_combined" and world.options.bombless_start: new_items.append("Bomb Upgrade (+5)" if progressive else "Bomb Upgrade (+10)") - if multiworld.shuffle_capacity_upgrades[player] and not multiworld.retro_bow[player]: - if multiworld.shuffle_capacity_upgrades[player] == "on_combined": + if world.options.shuffle_capacity_upgrades and not world.options.retro_bow: + if world.options.shuffle_capacity_upgrades == "on_combined": new_items += ["Arrow Upgrade (70)"] else: new_items += ["Arrow Upgrade (+5)"] * 6 @@ -481,7 +481,7 @@ def cut_item(items, item_to_cut, minimum_items): if len(items) < pool_count: items += removed_filler[len(items) - pool_count:] - if multiworld.randomize_cost_types[player]: + if world.options.randomize_cost_types: # Heart and Arrow costs require all Heart Container/Pieces and Arrow Upgrades to be advancement items for logic for item in items: if item.name in ("Boss Heart Container", "Sanctuary Heart Container", "Piece of Heart"): @@ -490,21 +490,21 @@ def cut_item(items, item_to_cut, minimum_items): # Otherwise, logic has some branches where having 4 hearts is one possible requirement (of several alternatives) # rather than making all hearts/heart pieces progression items (which slows down generation considerably) # We mark one random heart container as an advancement item (or 4 heart pieces in expert mode) - if multiworld.item_pool[player] in ['easy', 'normal', 'hard'] and not (multiworld.custom and multiworld.customitemarray[30] == 0): + if world.options.item_pool in ['easy', 'normal', 'hard'] and not (multiworld.custom and multiworld.customitemarray[30] == 0): next(item for item in items if item.name == 'Boss Heart Container').classification = ItemClassification.progression - elif multiworld.item_pool[player] in ['expert'] and not (multiworld.custom and multiworld.customitemarray[29] < 4): + elif world.options.item_pool in ['expert'] and not (multiworld.custom and multiworld.customitemarray[29] < 4): adv_heart_pieces = (item for item in items if item.name == 'Piece of Heart') for i in range(4): next(adv_heart_pieces).classification = ItemClassification.progression - world.required_medallions = (multiworld.misery_mire_medallion[player].current_key.title(), - multiworld.turtle_rock_medallion[player].current_key.title()) + world.required_medallions = (world.options.misery_mire_medallion.current_key.title(), + world.options.turtle_rock_medallion.current_key.title()) place_bosses(world) multiworld.itempool += items - if multiworld.retro_caves[player]: + if world.options.retro_caves: set_up_take_anys(multiworld, world, player) # depends on world.itempool to be set @@ -527,7 +527,7 @@ def cut_item(items, item_to_cut, minimum_items): def set_up_take_anys(multiworld, world, player): # these are references, do not modify these lists in-place - if multiworld.mode[player] == 'inverted': + if world.options.mode == 'inverted': take_any_locs = take_any_locations_inverted else: take_any_locs = take_any_locations @@ -578,14 +578,14 @@ def set_up_take_anys(multiworld, world, player): def get_pool_core(world, player: int): - shuffle = world.entrance_shuffle[player].current_key - difficulty = world.item_pool[player].current_key - timer = world.timer[player].current_key - goal = world.goal[player].current_key - mode = world.mode[player].current_key - swordless = world.swordless[player] - retro_bow = world.retro_bow[player] - logic = world.glitches_required[player] + shuffle = world.worlds[player].options.entrance_shuffle.current_key + difficulty = world.worlds[player].options.item_pool.current_key + timer = world.worlds[player].options.timer.current_key + goal = world.worlds[player].options.goal.current_key + mode = world.worlds[player].options.mode.current_key + swordless = world.worlds[player].options.swordless + retro_bow = world.worlds[player].options.retro_bow + logic = world.worlds[player].options.glitches_required pool = [] placed_items = {} @@ -602,11 +602,11 @@ def place_item(loc, item): placed_items[loc] = item # provide boots to major glitch dependent seeds - if logic.current_key in {'overworld_glitches', 'hybrid_major_glitches', 'no_logic'} and world.glitch_boots[player]: + if logic.current_key in {'overworld_glitches', 'hybrid_major_glitches', 'no_logic'} and world.worlds[player].options.glitch_boots: precollected_items.append('Pegasus Boots') pool.remove('Pegasus Boots') pool.append('Rupees (20)') - want_progressives = world.progressive[player].want_progressives + want_progressives = world.worlds[player].options.progressive.want_progressives if want_progressives(world.random): pool.extend(diff.progressiveglove) @@ -680,22 +680,22 @@ def place_item(loc, item): additional_pieces_to_place = 0 if 'triforce_hunt' in goal: - if world.triforce_pieces_mode[player].value == TriforcePiecesMode.option_extra: - treasure_hunt_total = (world.triforce_pieces_required[player].value - + world.triforce_pieces_extra[player].value) - elif world.triforce_pieces_mode[player].value == TriforcePiecesMode.option_percentage: - percentage = float(world.triforce_pieces_percentage[player].value) / 100 - treasure_hunt_total = int(round(world.triforce_pieces_required[player].value * percentage, 0)) + if world.worlds[player].options.triforce_pieces_mode.value == TriforcePiecesMode.option_extra: + treasure_hunt_total = (world.worlds[player].options.triforce_pieces_required.value + + world.worlds[player].options.triforce_pieces_extra.value) + elif world.worlds[player].options.triforce_pieces_mode.value == TriforcePiecesMode.option_percentage: + percentage = float(world.worlds[player].options.triforce_pieces_percentage.value) / 100 + treasure_hunt_total = int(round(world.worlds[player].options.triforce_pieces_required.value * percentage, 0)) else: # available - treasure_hunt_total = world.triforce_pieces_available[player].value + treasure_hunt_total = world.worlds[player].options.triforce_pieces_available.value - triforce_pieces = min(90, max(treasure_hunt_total, world.triforce_pieces_required[player].value)) + triforce_pieces = min(90, max(treasure_hunt_total, world.worlds[player].options.triforce_pieces_required.value)) pieces_in_core = min(extraitems, triforce_pieces) additional_pieces_to_place = triforce_pieces - pieces_in_core pool.extend(["Triforce Piece"] * pieces_in_core) extraitems -= pieces_in_core - treasure_hunt_required = world.triforce_pieces_required[player].value + treasure_hunt_required = world.worlds[player].options.triforce_pieces_required.value for extra in diff.extras: if extraitems >= len(extra): @@ -714,10 +714,10 @@ def place_item(loc, item): if retro_bow: replace = {'Single Arrow', 'Arrows (10)', 'Arrow Upgrade (+5)', 'Arrow Upgrade (+10)', 'Arrow Upgrade (70)'} pool = ['Rupees (5)' if item in replace else item for item in pool] - if world.small_key_shuffle[player] == small_key_shuffle.option_universal: + if world.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: pool.extend(diff.universal_keys) if mode == 'standard': - if world.key_drop_shuffle[player]: + if world.worlds[player].options.key_drop_shuffle: key_locations = ['Secret Passage', 'Hyrule Castle - Map Guard Key Drop'] key_location = world.random.choice(key_locations) key_locations.remove(key_location) @@ -741,11 +741,11 @@ def place_item(loc, item): def make_custom_item_pool(world, player): - shuffle = world.entrance_shuffle[player] - difficulty = world.item_pool[player] - timer = world.timer[player] - goal = world.goal[player] - mode = world.mode[player] + shuffle = world.worlds[player].options.entrance_shuffle + difficulty = world.worlds[player].options.item_pool + timer = world.worlds[player].options.timer + goal = world.worlds[player].options.goal + mode = world.worlds[player].options.mode customitemarray = world.customitemarray pool = [] @@ -845,10 +845,10 @@ def place_item(loc, item): thisbottle = world.random.choice(diff.bottles) pool.append(thisbottle) - if "triforce" in world.goal[player]: - pool.extend(["Triforce Piece"] * world.triforce_pieces_available[player]) - itemtotal += world.triforce_pieces_available[player] - treasure_hunt_required = world.triforce_pieces_required[player] + if "triforce" in world.worlds[player].options.goal: + pool.extend(["Triforce Piece"] * world.worlds[player].options.triforce_pieces_available) + itemtotal += world.worlds[player].options.triforce_pieces_available + treasure_hunt_required = world.worlds[player].options.triforce_pieces_required if timer in ['display', 'timed', 'timed_countdown']: clock_mode = 'countdown' if timer == 'timed_countdown' else 'stopwatch' @@ -862,7 +862,7 @@ def place_item(loc, item): itemtotal = itemtotal + 1 if mode == 'standard': - if world.small_key_shuffle[player] == small_key_shuffle.option_universal: + if world.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: key_location = world.random.choice( ['Secret Passage', 'Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest', 'Sewers - Dark Cross']) @@ -885,9 +885,9 @@ def place_item(loc, item): pool.extend(['Magic Mirror'] * customitemarray[22]) pool.extend(['Moon Pearl'] * customitemarray[28]) - if world.small_key_shuffle[player] == small_key_shuffle.option_universal: + if world.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: itemtotal = itemtotal - 28 # Corrects for small keys not being in item pool in universal Mode - if world.key_drop_shuffle[player]: + if world.worlds[player].options.key_drop_shuffle: itemtotal = itemtotal - (len(key_drop_data) - 1) if itemtotal < total_items_to_place: pool.extend(['Nothing'] * (total_items_to_place - itemtotal)) diff --git a/worlds/alttp/Items.py b/worlds/alttp/Items.py index 5f081e65fc8b..cbe6e9964232 100644 --- a/worlds/alttp/Items.py +++ b/worlds/alttp/Items.py @@ -11,11 +11,11 @@ def GetBeemizerItem(world, player: int, item): return item # first roll - replaceable item should be replaced, within beemizer_total_chance - if not world.beemizer_total_chance[player] or world.random.random() > (world.beemizer_total_chance[player] / 100): + if not world.worlds[player].options.beemizer_total_chance or world.random.random() > (world.worlds[player].options.beemizer_total_chance / 100): return item # second roll - bee replacement should be trap, within beemizer_trap_chance - if not world.beemizer_trap_chance[player] or world.random.random() > (world.beemizer_trap_chance[player] / 100): + if not world.worlds[player].options.beemizer_trap_chance or world.random.random() > (world.worlds[player].options.beemizer_trap_chance / 100): return "Bee" if isinstance(item, str) else world.create_item("Bee", player) else: return "Bee Trap" if isinstance(item, str) else world.create_item("Bee Trap", player) diff --git a/worlds/alttp/Options.py b/worlds/alttp/Options.py index 097458611734..519241d7f4a9 100644 --- a/worlds/alttp/Options.py +++ b/worlds/alttp/Options.py @@ -156,10 +156,10 @@ class OpenPyramid(Choice): def to_bool(self, world: MultiWorld, player: int) -> bool: if self.value == self.option_goal: - return world.goal[player].current_key in {'crystals', 'ganon_triforce_hunt', 'local_ganon_triforce_hunt', 'ganon_pedestal'} + return world.worlds[player].options.goal.current_key in {'crystals', 'ganon_triforce_hunt', 'local_ganon_triforce_hunt', 'ganon_pedestal'} elif self.value == self.option_auto: - return world.goal[player].current_key in {'crystals', 'ganon_triforce_hunt', 'local_ganon_triforce_hunt', 'ganon_pedestal'} \ - and (world.entrance_shuffle[player].current_key in {'vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed'} or not + return world.worlds[player].options.goal.current_key in {'crystals', 'ganon_triforce_hunt', 'local_ganon_triforce_hunt', 'ganon_pedestal'} \ + and (world.worlds[player].options.entrance_shuffle.current_key in {'vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed'} or not world.shuffle_ganon) elif self.value == self.option_open: return True diff --git a/worlds/alttp/OverworldGlitchRules.py b/worlds/alttp/OverworldGlitchRules.py index 1a1c01525db7..aeff9cb88e9a 100644 --- a/worlds/alttp/OverworldGlitchRules.py +++ b/worlds/alttp/OverworldGlitchRules.py @@ -220,14 +220,14 @@ def get_invalid_bunny_revival_dungeons(): def overworld_glitch_connections(world, player): # Boots-accessible locations. - create_owg_connections(player, world, get_boots_clip_exits_lw(world.mode[player] == 'inverted')) - create_owg_connections(player, world, get_boots_clip_exits_dw(world.mode[player] == 'inverted', player)) + create_owg_connections(player, world, get_boots_clip_exits_lw(world.worlds[player].options.mode == 'inverted')) + create_owg_connections(player, world, get_boots_clip_exits_dw(world.worlds[player].options.mode == 'inverted', player)) # Glitched speed drops. - create_owg_connections(player, world, get_glitched_speed_drops_dw(world.mode[player] == 'inverted')) + create_owg_connections(player, world, get_glitched_speed_drops_dw(world.worlds[player].options.mode == 'inverted')) # Mirror clip spots. - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': create_owg_connections(player, world, get_mirror_clip_spots_dw()) create_owg_connections(player, world, get_mirror_offset_spots_dw()) else: @@ -237,24 +237,24 @@ def overworld_glitch_connections(world, player): def overworld_glitches_rules(world, player): # Boots-accessible locations. - set_owg_connection_rules(player, world, get_boots_clip_exits_lw(world.mode[player] == 'inverted'), lambda state: can_boots_clip_lw(state, player)) - set_owg_connection_rules(player, world, get_boots_clip_exits_dw(world.mode[player] == 'inverted', player), lambda state: can_boots_clip_dw(state, player)) + set_owg_connection_rules(player, world, get_boots_clip_exits_lw(world.worlds[player].options.mode == 'inverted'), lambda state: can_boots_clip_lw(state, player)) + set_owg_connection_rules(player, world, get_boots_clip_exits_dw(world.worlds[player].options.mode == 'inverted', player), lambda state: can_boots_clip_dw(state, player)) # Glitched speed drops. - set_owg_connection_rules(player, world, get_glitched_speed_drops_dw(world.mode[player] == 'inverted'), lambda state: can_get_glitched_speed_dw(state, player)) + set_owg_connection_rules(player, world, get_glitched_speed_drops_dw(world.worlds[player].options.mode == 'inverted'), lambda state: can_get_glitched_speed_dw(state, player)) # Dark Death Mountain Ledge Clip Spot also accessible with mirror. - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': add_alternate_rule(world.get_entrance('Dark Death Mountain Ledge Clip Spot', player), lambda state: state.has('Magic Mirror', player)) # Mirror clip spots. - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': set_owg_connection_rules(player, world, get_mirror_clip_spots_dw(), lambda state: state.has('Magic Mirror', player)) set_owg_connection_rules(player, world, get_mirror_offset_spots_dw(), lambda state: state.has('Magic Mirror', player) and can_boots_clip_lw(state, player)) else: set_owg_connection_rules(player, world, get_mirror_offset_spots_lw(player), lambda state: state.has('Magic Mirror', player) and can_boots_clip_dw(state, player)) # Regions that require the boots and some other stuff. - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': world.get_entrance('Turtle Rock Teleporter', player).access_rule = lambda state: (can_boots_clip_lw(state, player) or can_lift_heavy_rocks(state, player)) and state.has('Hammer', player) add_alternate_rule(world.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Moon Pearl', player) or state.has('Pegasus Boots', player)) else: diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index 5ed048e88123..f69e6bb955fc 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -92,7 +92,7 @@ def encrypt(self, world, player): # cause crash to provide traceback import xxtea - local_random = world.per_slot_randoms[player] + local_random = world.worlds[player].random key = bytes(local_random.getrandbits(8 * 16).to_bytes(16, 'big')) self.write_bytes(0x1800B0, bytearray(key)) self.write_int16(0x180087, 1) @@ -281,7 +281,6 @@ def apply_random_sprite_on_event(rom: LocalRom, sprite, local_random, allow_rand def patch_enemizer(world, rom: LocalRom, enemizercli, output_directory): player = world.player - multiworld = world.multiworld check_enemizer(enemizercli) randopatch_path = os.path.abspath(os.path.join(output_directory, f'enemizer_randopatch_{player}.sfc')) options_path = os.path.abspath(os.path.join(output_directory, f'enemizer_options_{player}.json')) @@ -289,18 +288,18 @@ def patch_enemizer(world, rom: LocalRom, enemizercli, output_directory): # write options file for enemizer options = { - 'RandomizeEnemies': multiworld.enemy_shuffle[player].value, + 'RandomizeEnemies': world.options.enemy_shuffle.value, 'RandomizeEnemiesType': 3, - 'RandomizeBushEnemyChance': multiworld.bush_shuffle[player].value, - 'RandomizeEnemyHealthRange': multiworld.enemy_health[player] != 'default', + 'RandomizeBushEnemyChance': world.options.bush_shuffle.value, + 'RandomizeEnemyHealthRange': world.options.enemy_health != 'default', 'RandomizeEnemyHealthType': {'default': 0, 'easy': 0, 'normal': 1, 'hard': 2, 'expert': 3}[ - multiworld.enemy_health[player].current_key], + world.options.enemy_health.current_key], 'OHKO': False, - 'RandomizeEnemyDamage': multiworld.enemy_damage[player] != 'default', + 'RandomizeEnemyDamage': world.options.enemy_damage != 'default', 'AllowEnemyZeroDamage': True, - 'ShuffleEnemyDamageGroups': multiworld.enemy_damage[player] != 'default', - 'EnemyDamageChaosMode': multiworld.enemy_damage[player] == 'chaos', - 'EasyModeEscape': multiworld.mode[player] == "standard", + 'ShuffleEnemyDamageGroups': world.options.enemy_damage != 'default', + 'EnemyDamageChaosMode': world.options.enemy_damage == 'chaos', + 'EasyModeEscape': world.options.mode == "standard", 'EnemiesAbsorbable': False, 'AbsorbableSpawnRate': 10, 'AbsorbableTypes': { @@ -329,7 +328,7 @@ def patch_enemizer(world, rom: LocalRom, enemizercli, output_directory): 'GrayscaleMode': False, 'GenerateSpoilers': False, 'RandomizeLinkSpritePalette': False, - 'RandomizePots': multiworld.pot_shuffle[player].value, + 'RandomizePots': world.options.pot_shuffle.value, 'ShuffleMusic': False, 'BootlegMagic': True, 'CustomBosses': False, @@ -342,7 +341,7 @@ def patch_enemizer(world, rom: LocalRom, enemizercli, output_directory): 'BeesLevel': 0, 'RandomizeTileTrapPattern': False, 'RandomizeTileTrapFloorTile': False, - 'AllowKillableThief': multiworld.killable_thieves[player].value, + 'AllowKillableThief': world.options.killable_thieves.value, 'RandomizeSpriteOnHit': False, 'DebugMode': False, 'DebugForceEnemy': False, @@ -366,13 +365,13 @@ def patch_enemizer(world, rom: LocalRom, enemizercli, output_directory): 'MiseryMire': world.dungeons["Misery Mire"].boss.enemizer_name, 'TurtleRock': world.dungeons["Turtle Rock"].boss.enemizer_name, 'GanonsTower1': - world.dungeons["Ganons Tower" if multiworld.mode[player] != 'inverted' else + world.dungeons["Ganons Tower" if world.options.mode != 'inverted' else "Inverted Ganons Tower"].bosses['bottom'].enemizer_name, 'GanonsTower2': - world.dungeons["Ganons Tower" if multiworld.mode[player] != 'inverted' else + world.dungeons["Ganons Tower" if world.options.mode != 'inverted' else "Inverted Ganons Tower"].bosses['middle'].enemizer_name, 'GanonsTower3': - world.dungeons["Ganons Tower" if multiworld.mode[player] != 'inverted' else + world.dungeons["Ganons Tower" if world.options.mode != 'inverted' else "Inverted Ganons Tower"].bosses['top'].enemizer_name, 'GanonsTower4': 'Agahnim2', 'Ganon': 'Ganon', @@ -386,7 +385,7 @@ def patch_enemizer(world, rom: LocalRom, enemizercli, output_directory): max_enemizer_tries = 5 for i in range(max_enemizer_tries): - enemizer_seed = str(multiworld.per_slot_randoms[player].randint(0, 999999999)) + enemizer_seed = str(world.random.randint(0, 999999999)) enemizer_command = [os.path.abspath(enemizercli), '--rom', randopatch_path, '--seed', enemizer_seed, @@ -416,7 +415,7 @@ def patch_enemizer(world, rom: LocalRom, enemizercli, output_directory): continue for j in range(i + 1, max_enemizer_tries): - multiworld.per_slot_randoms[player].randint(0, 999999999) + world.random.randint(0, 999999999) # Sacrifice all remaining random numbers that would have been used for unused enemizer tries. # This allows for future enemizer bug fixes to NOT affect the rest of the seed's randomness break @@ -430,7 +429,7 @@ def patch_enemizer(world, rom: LocalRom, enemizercli, output_directory): # Moblins attached to "key drop" locations crash the game when dropping their item when Key Drop Shuffle is on. # Replace them with a Slime enemy if they are placed. - if multiworld.key_drop_shuffle[player]: + if world.options.key_drop_shuffle: key_drop_enemies = { 0x4DA20, 0x4DA5C, 0x4DB7F, 0x4DD73, 0x4DDC3, 0x4DE07, 0x4E201, 0x4E20A, 0x4E326, 0x4E4F7, 0x4E687, 0x4E70C, 0x4E7C8, 0x4E7FA @@ -792,8 +791,8 @@ def get_nonnative_item_sprite(code: int) -> int: def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): + local_random = world.worlds[player].random local_world = world.worlds[player] - local_random = local_world.random # patch items @@ -840,14 +839,14 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): # patch music music_addresses = dungeon_music_addresses[location.name] - if world.map_shuffle[player]: + if local_world.options.map_shuffle: music = local_random.choice([0x11, 0x16]) else: music = 0x11 if 'Pendant' in location.item.name else 0x16 for music_address in music_addresses: rom.write_byte(music_address, music) - if world.map_shuffle[player]: + if local_world.options.map_shuffle: rom.write_byte(0x155C9, local_random.choice([0x11, 0x16])) # Randomize GT music too with map shuffle # patch entrance/exits/holes @@ -868,15 +867,15 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): # Thanks to Zarby89 for originally finding these values # todo fix screen scrolling - if world.entrance_shuffle[player] != 'insanity' and \ + if local_world.options.entrance_shuffle != 'insanity' and \ exit.name in {'Eastern Palace Exit', 'Tower of Hera Exit', 'Thieves Town Exit', 'Skull Woods Final Section Exit', 'Ice Palace Exit', 'Misery Mire Exit', 'Palace of Darkness Exit', 'Swamp Palace Exit', 'Ganons Tower Exit', 'Desert Palace Exit (North)', 'Agahnims Tower Exit', 'Spiral Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)', 'Turtle Rock Ledge Exit (East)'} and \ - (world.glitches_required[player] not in ['hybrid_major_glitches', 'no_logic'] or - exit.name not in {'Palace of Darkness Exit', 'Tower of Hera Exit', 'Swamp Palace Exit'}): - # For exits that connot be reached from another, no need to apply offset fixes. + (local_world.options.glitches_required not in ['hybrid_major_glitches', 'no_logic'] or + exit.name not in {'Palace of Darkness Exit', 'Tower of Hera Exit', 'Swamp Palace Exit'}): + # For exits that cannot be reached from another, no need to apply offset fixes. rom.write_int16(0x15DB5 + 2 * offset, link_y) # same as final else elif room_id == 0x0059 and local_world.fix_skullwoods_exit: rom.write_int16(0x15DB5 + 2 * offset, 0x00F8) @@ -903,7 +902,7 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): else: # patch door table rom.write_byte(0xDBB73 + exit.addresses, exit.target) - if world.mode[player] == 'inverted': + if local_world.options.mode == 'inverted': patch_shuffled_dark_sanc(world, rom, player) write_custom_shops(rom, world, player) @@ -914,16 +913,16 @@ def credits_digit(num): return 0x53 + int(num), 0x79 + int(num) credits_total = 216 - if world.retro_caves[player]: # Old man cave and Take any caves will count towards collection rate. + if local_world.options.retro_caves: # Old man cave and Take any caves will count towards collection rate. credits_total += 5 - if world.shop_item_slots[player]: # Potion shop only counts towards collection rate if included in the shuffle. - credits_total += 30 if world.include_witch_hut[player] else 27 - if world.shuffle_capacity_upgrades[player]: + if local_world.options.shop_item_slots: # Potion shop only counts towards collection rate if included in the shuffle. + credits_total += 30 if local_world.options.include_witch_hut else 27 + if local_world.options.shuffle_capacity_upgrades: credits_total += 2 rom.write_byte(0x187010, credits_total) # dynamic credits - if world.key_drop_shuffle[player]: + if local_world.options.key_drop_shuffle: rom.write_byte(0x140000, 1) # enable key drop shuffle credits_total += len(key_drop_data) # update dungeon counters @@ -977,11 +976,11 @@ def credits_digit(num): rom.write_byte(0x51DE, 0x00) # set open mode: - if world.mode[player] in ['open', 'inverted']: + if local_world.options.mode in ['open', 'inverted']: rom.write_byte(0x180032, 0x01) # open mode - if world.mode[player] == 'inverted': + if local_world.options.mode == 'inverted': set_inverted_mode(world, player, rom) - elif world.mode[player] == 'standard': + elif local_world.options.mode == 'standard': rom.write_byte(0x180032, 0x00) # standard mode uncle_location = world.get_location('Link\'s Uncle', player) @@ -1001,7 +1000,7 @@ def credits_digit(num): rom.write_bytes(0x6D323, [0x00, 0x00, 0xe4, 0xff, 0x08, 0x0E]) # set light cones - rom.write_byte(0x180038, 0x01 if world.mode[player] == "standard" else 0x00) + rom.write_byte(0x180038, 0x01 if local_world.options.mode == "standard" else 0x00) rom.write_byte(0x180039, 0x01 if world.light_world_light_cone else 0x00) rom.write_byte(0x18003A, 0x01 if world.dark_world_light_cone else 0x00) @@ -1011,7 +1010,7 @@ def credits_digit(num): rom.write_byte(0x18004F, 0x01) # Byrna Invulnerability: on # handle item_functionality - if world.item_functionality[player] == 'hard': + if local_world.options.item_functionality == 'hard': rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon rom.write_byte(0x180182, 0x00) # Don't auto equip silvers on pickup # Powdered Fairies Prize @@ -1031,7 +1030,7 @@ def credits_digit(num): rom.write_int16(0x180036, world.rupoor_cost) # Set stun items rom.write_byte(0x180180, 0x02) # Hookshot only - elif world.item_functionality[player] == 'expert': + elif local_world.options.item_functionality == 'expert': rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon rom.write_byte(0x180182, 0x00) # Don't auto equip silvers on pickup # Powdered Fairies Prize @@ -1071,7 +1070,7 @@ def credits_digit(num): # Set stun items rom.write_byte(0x180180, 0x03) # All standard items # Set overflow items for progressive equipment - if world.timer[player] in ['timed', 'timed_countdown', 'timed_ohko']: + if local_world.options.timer in ['timed', 'timed_countdown', 'timed_ohko']: overflow_replacement = GREEN_CLOCK else: overflow_replacement = GREEN_TWENTY_RUPEES @@ -1083,7 +1082,7 @@ def credits_digit(num): # Set overflow items for progressive equipment rom.write_bytes(0x180090, - [difficulty.progressive_sword_limit if not world.swordless[player] else 0, + [difficulty.progressive_sword_limit if not local_world.options.swordless else 0, item_table[difficulty.basicsword[-1]].item_code, difficulty.progressive_shield_limit, item_table[difficulty.basicshield[-1]].item_code, difficulty.progressive_armor_limit, item_table[difficulty.basicarmor[-1]].item_code, @@ -1091,7 +1090,7 @@ def credits_digit(num): difficulty.progressive_bow_limit, item_table[difficulty.basicbow[-1]].item_code]) if difficulty.progressive_bow_limit < 2 and ( - world.swordless[player] or world.glitches_required[player] == 'no_glitches'): + local_world.options.swordless or local_world.options.glitches_required == 'no_glitches'): rom.write_bytes(0x180098, [2, item_table["Silver Bow"].item_code]) rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon rom.write_byte(0x180182, 0x00) # Don't auto equip silvers on pickup @@ -1099,15 +1098,15 @@ def credits_digit(num): # set up game internal RNG seed rom.write_bytes(0x178000, local_random.getrandbits(8 * 1024).to_bytes(1024, 'big')) prize_replacements = {} - if world.item_functionality[player] in ['hard', 'expert']: + if local_world.options.item_functionality in ['hard', 'expert']: prize_replacements[0xE0] = 0xDF # Fairy -> heart prize_replacements[0xE3] = 0xD8 # Big magic -> small magic - if world.retro_bow[player]: + if local_world.options.retro_bow: prize_replacements[0xE1] = 0xDA # 5 Arrows -> Blue Rupee prize_replacements[0xE2] = 0xDB # 10 Arrows -> Red Rupee - if world.shuffle_prizes[player] in ("general", "both"): + if local_world.options.shuffle_prizes in ("general", "both"): # shuffle prize packs prizes = [0xD8, 0xD8, 0xD8, 0xD8, 0xD9, 0xD8, 0xD8, 0xD9, 0xDA, 0xD9, 0xDA, 0xDB, 0xDA, 0xD9, 0xDA, 0xDA, 0xE0, 0xDF, 0xDF, 0xDA, 0xE0, 0xDF, 0xD8, 0xDF, @@ -1169,7 +1168,7 @@ def chunk(l, n): byte = int(rom.read_byte(address)) rom.write_byte(address, prize_replacements.get(byte, byte)) - if world.shuffle_prizes[player] in ("bonk", "both"): + if local_world.options.shuffle_prizes in ("bonk", "both"): # set bonk prizes bonk_prizes = [0x79, 0xE3, 0x79, 0xAC, 0xAC, 0xE0, 0xDC, 0xAC, 0xE3, 0xE3, 0xDA, 0xE3, 0xDA, 0xD8, 0xAC, 0xAC, 0xE3, 0xD8, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xDC, 0xDB, 0xE3, 0xDA, 0x79, 0x79, @@ -1196,7 +1195,7 @@ def chunk(l, n): 0x12, 0x01, 0x35, 0xFF, # lamp -> 5 rupees 0x51, 0x06, 0x52, 0xFF, # 6 +5 bomb upgrades -> +10 bomb upgrade 0x53, 0x06, 0x54, 0xFF, # 6 +5 arrow upgrades -> +10 arrow upgrade - 0x58, 0x01, 0x36 if world.retro_bow[player] else 0x43, 0xFF, # silver arrows -> single arrow (red 20 in retro mode) + 0x58, 0x01, 0x36 if local_world.options.retro_bow else 0x43, 0xFF, # silver arrows -> single arrow (red 20 in retro mode) 0x3E, difficulty.boss_heart_container_limit, 0x47, 0xff, # boss heart -> green 20 0x17, difficulty.heart_piece_limit, 0x47, 0xff, # piece of heart -> green 20 0xFF, 0xFF, 0xFF, 0xFF, # end of table sentinel @@ -1238,13 +1237,13 @@ def chunk(l, n): rom.write_byte(0x180029, 0x01) # Smithy quick item give # set swordless mode settings - rom.write_byte(0x18003F, 0x01 if world.swordless[player] else 0x00) # hammer can harm ganon - rom.write_byte(0x180040, 0x01 if world.swordless[player] else 0x00) # open curtains - rom.write_byte(0x180041, 0x01 if world.swordless[player] else 0x00) # swordless medallions - rom.write_byte(0x180043, 0xFF if world.swordless[player] else 0x00) # starting sword for link - rom.write_byte(0x180044, 0x01 if world.swordless[player] else 0x00) # hammer activates tablets + rom.write_byte(0x18003F, 0x01 if local_world.options.swordless else 0x00) # hammer can harm ganon + rom.write_byte(0x180040, 0x01 if local_world.options.swordless else 0x00) # open curtains + rom.write_byte(0x180041, 0x01 if local_world.options.swordless else 0x00) # swordless medallions + rom.write_byte(0x180043, 0xFF if local_world.options.swordless else 0x00) # starting sword for link + rom.write_byte(0x180044, 0x01 if local_world.options.swordless else 0x00) # hammer activates tablets - if world.item_functionality[player] == 'easy': + if local_world.options.item_functionality == 'easy': rom.write_byte(0x18003F, 0x01) # hammer can harm ganon rom.write_byte(0x180041, 0x02) # Allow swordless medallion use EVERYWHERE. rom.write_byte(0x180044, 0x01) # hammer activates tablets @@ -1262,11 +1261,11 @@ def chunk(l, n): # Set up requested clock settings if local_world.clock_mode in ['countdown-ohko', 'stopwatch', 'countdown']: rom.write_int32(0x180200, - world.red_clock_time[player] * 60 * 60) # red clock adjustment time (in frames, sint32) + local_world.options.red_clock_time * 60 * 60) # red clock adjustment time (in frames, sint32) rom.write_int32(0x180204, - world.blue_clock_time[player] * 60 * 60) # blue clock adjustment time (in frames, sint32) + local_world.options.blue_clock_time * 60 * 60) # blue clock adjustment time (in frames, sint32) rom.write_int32(0x180208, - world.green_clock_time[player] * 60 * 60) # green clock adjustment time (in frames, sint32) + local_world.options.green_clock_time * 60 * 60) # green clock adjustment time (in frames, sint32) else: rom.write_int32(0x180200, 0) # red clock adjustment time (in frames, sint32) rom.write_int32(0x180204, 0) # blue clock adjustment time (in frames, sint32) @@ -1274,20 +1273,20 @@ def chunk(l, n): # Set up requested start time for countdown modes if local_world.clock_mode in ['countdown-ohko', 'countdown']: - rom.write_int32(0x18020C, world.countdown_start_time[player] * 60 * 60) # starting time (in frames, sint32) + rom.write_int32(0x18020C, local_world.options.countdown_start_time * 60 * 60) # starting time (in frames, sint32) else: rom.write_int32(0x18020C, 0) # starting time (in frames, sint32) # set up goals for treasure hunt rom.write_int16(0x180163, max(0, local_world.treasure_hunt_required - - sum(1 for item in world.precollected_items[player] if item.name == "Triforce Piece"))) + sum(1 for item in world.precollected_items[player] if item.name == "Triforce Piece"))) rom.write_bytes(0x180165, [0x0E, 0x28]) # Triforce Piece Sprite rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled) rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed gametype = 0x04 # item - if world.entrance_shuffle[player] != 'vanilla': + if local_world.options.entrance_shuffle != 'vanilla': gametype |= 0x02 # entrance if enemized: gametype |= 0x01 # enemizer @@ -1298,7 +1297,7 @@ def chunk(l, n): rom.write_byte(0x1800A2, 0x01 if local_world.fix_fake_world else 0x00) # Lock or unlock aga tower door during escape sequence. rom.write_byte(0x180169, 0x00) - if world.mode[player] == 'inverted': + if local_world.options.mode == 'inverted': rom.write_byte(0x180169, 0x02) # lock aga/ganon tower door with crystals in inverted rom.write_byte(0x180171, 0x01 if local_world.ganon_at_pyramid else 0x00) # Enable respawning on pyramid after ganon death @@ -1309,9 +1308,8 @@ def chunk(l, n): rom.write_bytes(0x50563, [0x3F, 0x14]) # disable below ganon chest rom.write_byte(0x50599, 0x00) # disable below ganon chest rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest - rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player].to_bool(world, player) else 0x00) # pre-open Pyramid Hole - rom.write_byte(0x18008C, 0x01 if world.crystals_needed_for_gt[ - player] == 0 else 0x00) # GT pre-opened if crystal requirement is 0 + rom.write_byte(0x18008B, 0x01 if local_world.options.open_pyramid.to_bool(world, player) else 0x00) # pre-open Pyramid Hole + rom.write_byte(0x18008C, 0x01 if local_world.options.crystals_needed_for_gt == 0 else 0x00) # GT pre-opened if crystal requirement is 0 rom.write_byte(0xF5D73, 0xF0) # bees are catchable rom.write_byte(0xF5F10, 0xF0) # bees are catchable rom.write_byte(0x180086, 0x00 if world.aga_randomness else 0x01) # set blue ball and ganon warp randomness @@ -1325,7 +1323,7 @@ def chunk(l, n): equip[0x36C] = 0x18 equip[0x36D] = 0x18 equip[0x379] = 0x68 - starting_max_bombs = 0 if world.bombless_start[player] else 10 + starting_max_bombs = 0 if local_world.options.bombless_start else 10 starting_max_arrows = 30 startingstate = CollectionState(world) @@ -1333,12 +1331,12 @@ def chunk(l, n): if startingstate.has('Silver Bow', player): equip[0x340] = 1 equip[0x38E] |= 0x60 - if not world.retro_bow[player]: + if not local_world.options.retro_bow: equip[0x38E] |= 0x80 elif startingstate.has('Bow', player): equip[0x340] = 1 equip[0x38E] |= 0x20 # progressive flag to get the correct hint in all cases - if not world.retro_bow[player]: + if not local_world.options.retro_bow: equip[0x38E] |= 0x80 if startingstate.has('Silver Arrows', player): equip[0x38E] |= 0x40 @@ -1476,7 +1474,7 @@ def chunk(l, n): elif item.name in bombs: equip[0x343] += bombs[item.name] elif item.name in arrows: - if world.retro_bow[player]: + if local_world.options.retro_bow: equip[0x38E] |= 0x80 equip[0x377] = 1 else: @@ -1502,16 +1500,13 @@ def chunk(l, n): rom.write_bytes(0x183000, equip[0x340:]) rom.write_bytes(0x271A6, equip[0x340:0x340 + 60]) - rom.write_byte(0x18004A, 0x00 if world.mode[player] != 'inverted' else 0x01) # Inverted mode + rom.write_byte(0x18004A, 0x00 if local_world.options.mode != 'inverted' else 0x01) # Inverted mode rom.write_byte(0x18005D, 0x00) # Hammer always breaks barrier - rom.write_byte(0x2AF79, 0xD0 if world.mode[ - player] != 'inverted' else 0xF0) # vortexes: Normal (D0=light to dark, F0=dark to light, 42 = both) - rom.write_byte(0x3A943, 0xD0 if world.mode[ - player] != 'inverted' else 0xF0) # Mirror: Normal (D0=Dark to Light, F0=light to dark, 42 = both) - rom.write_byte(0x3A96D, 0xF0 if world.mode[ - player] != 'inverted' else 0xD0) # Residual Portal: Normal (F0= Light Side, D0=Dark Side, 42 = both (Darth Vader)) + rom.write_byte(0x2AF79, 0xD0 if local_world.options.mode != 'inverted' else 0xF0) # vortexes: Normal (D0=light to dark, F0=dark to light, 42 = both) + rom.write_byte(0x3A943, 0xD0 if local_world.options.mode != 'inverted' else 0xF0) # Mirror: Normal (D0=Dark to Light, F0=light to dark, 42 = both) + rom.write_byte(0x3A96D, 0xF0 if local_world.options.mode != 'inverted' else 0xD0) # Residual Portal: Normal (F0= Light Side, D0=Dark Side, 42 = both (Darth Vader)) rom.write_byte(0x3A9A7, 0xD0) # Residual Portal: Normal (D0= Light Side, F0=Dark Side, 42 = both (Darth Vader)) - if world.shuffle_capacity_upgrades[player]: + if local_world.options.shuffle_capacity_upgrades: rom.write_bytes(0x180080, [5, 10, 5, 10]) # values to fill for Capacity Upgrades (Bomb5, Bomb10, Arrow5, Arrow10) else: @@ -1522,21 +1517,21 @@ def chunk(l, n): (0x02 if 'bombs' in local_world.escape_assist else 0x00) | (0x04 if 'magic' in local_world.escape_assist else 0x00))) # Escape assist - if world.goal[player] in ['pedestal', 'triforce_hunt', 'local_triforce_hunt']: + if local_world.options.goal in ['pedestal', 'triforce_hunt', 'local_triforce_hunt']: rom.write_byte(0x18003E, 0x01) # make ganon invincible - elif world.goal[player] in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: + elif local_world.options.goal in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: rom.write_byte(0x18003E, 0x05) # make ganon invincible until enough triforce pieces are collected - elif world.goal[player] in ['ganon_pedestal']: + elif local_world.options.goal in ['ganon_pedestal']: rom.write_byte(0x18003E, 0x06) - elif world.goal[player] in ['bosses']: + elif local_world.options.goal in ['bosses']: rom.write_byte(0x18003E, 0x02) # make ganon invincible until all bosses are beat - elif world.goal[player] in ['crystals']: + elif local_world.options.goal in ['crystals']: rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals else: rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected - rom.write_byte(0x18005E, world.crystals_needed_for_gt[player]) - rom.write_byte(0x18005F, world.crystals_needed_for_ganon[player]) + rom.write_byte(0x18005E, local_world.options.crystals_needed_for_gt) + rom.write_byte(0x18005F, local_world.options.crystals_needed_for_ganon) # Bitfield - enable text box to show with free roaming items # @@ -1547,21 +1542,20 @@ def chunk(l, n): # c - enabled for inside compasses # s - enabled for inside small keys # block HC upstairs doors in rain state in standard mode - rom.write_byte(0x18008A, 0x01 if world.mode[player] == "standard" and world.entrance_shuffle[player] != 'vanilla' else 0x00) + rom.write_byte(0x18008A, 0x01 if local_world.options.mode == "standard" and local_world.options.entrance_shuffle != 'vanilla' else 0x00) - rom.write_byte(0x18016A, 0x10 | ((0x01 if world.small_key_shuffle[player] else 0x00) - | (0x02 if world.compass_shuffle[player] else 0x00) - | (0x04 if world.map_shuffle[player] else 0x00) - | (0x08 if world.big_key_shuffle[ - player] else 0x00))) # free roaming item text boxes - rom.write_byte(0x18003B, 0x01 if world.map_shuffle[player] else 0x00) # maps showing crystals on overworld + rom.write_byte(0x18016A, 0x10 | ((0x01 if local_world.options.small_key_shuffle else 0x00) + | (0x02 if local_world.options.compass_shuffle else 0x00) + | (0x04 if local_world.options.map_shuffle else 0x00) + | (0x08 if local_world.options.big_key_shuffle else 0x00))) # free roaming item text boxes + rom.write_byte(0x18003B, 0x01 if local_world.options.map_shuffle else 0x00) # maps showing crystals on overworld # compasses showing dungeon count - if local_world.clock_mode or world.dungeon_counters[player] == 'off': + if local_world.clock_mode or local_world.options.dungeon_counters == 'off': rom.write_byte(0x18003C, 0x00) # Currently must be off if timer is on, because they use same HUD location - elif world.dungeon_counters[player] == 'on': + elif local_world.options.dungeon_counters == 'on': rom.write_byte(0x18003C, 0x02) # always on - elif world.compass_shuffle[player] or world.dungeon_counters[player] == 'pickup': + elif local_world.options.compass_shuffle or local_world.options.dungeon_counters == 'pickup': rom.write_byte(0x18003C, 0x01) # show on pickup else: rom.write_byte(0x18003C, 0x00) @@ -1574,11 +1568,11 @@ def chunk(l, n): # b - Big Key # a - Small Key # - rom.write_byte(0x180045, ((0x00 if (world.small_key_shuffle[player] == small_key_shuffle.option_original_dungeon or - world.small_key_shuffle[player] == small_key_shuffle.option_universal) else 0x01) - | (0x02 if world.big_key_shuffle[player] else 0x00) - | (0x04 if world.map_shuffle[player] else 0x00) - | (0x08 if world.compass_shuffle[player] else 0x00))) # free roaming items in menu + rom.write_byte(0x180045, ((0x00 if (local_world.options.small_key_shuffle == small_key_shuffle.option_original_dungeon or + local_world.options.small_key_shuffle == small_key_shuffle.option_universal) else 0x01) + | (0x02 if local_world.options.big_key_shuffle else 0x00) + | (0x04 if local_world.options.map_shuffle else 0x00) + | (0x08 if local_world.options.compass_shuffle else 0x00))) # free roaming items in menu # Map reveals reveal_bytes = { @@ -1604,31 +1598,25 @@ def get_reveal_bytes(itemName): return 0x0000 rom.write_int16(0x18017A, - get_reveal_bytes('Green Pendant') if world.map_shuffle[player] else 0x0000) # Sahasrahla reveal - rom.write_int16(0x18017C, get_reveal_bytes('Crystal 5') | get_reveal_bytes('Crystal 6') if world.map_shuffle[ - player] else 0x0000) # Bomb Shop Reveal - - rom.write_byte(0x180172, 0x01 if world.small_key_shuffle[ - player] == small_key_shuffle.option_universal else 0x00) # universal keys - rom.write_byte(0x18637E, 0x01 if world.retro_bow[player] else 0x00) # Skip quiver in item shops once bought - rom.write_byte(0x180175, 0x01 if world.retro_bow[player] else 0x00) # rupee bow - rom.write_byte(0x180176, 0x0A if world.retro_bow[player] else 0x00) # wood arrow cost - rom.write_byte(0x180178, 0x32 if world.retro_bow[player] else 0x00) # silver arrow cost - rom.write_byte(0x301FC, 0xDA if world.retro_bow[player] else 0xE1) # rupees replace arrows under pots - rom.write_byte(0x30052, 0xDB if world.retro_bow[player] else 0xE2) # replace arrows in fish prize from bottle merchant - rom.write_bytes(0xECB4E, [0xA9, 0x00, 0xEA, 0xEA] if world.retro_bow[player] else [0xAF, 0x77, 0xF3, - 0x7E]) # Thief steals rupees instead of arrows - rom.write_bytes(0xF0D96, [0xA9, 0x00, 0xEA, 0xEA] if world.retro_bow[player] else [0xAF, 0x77, 0xF3, - 0x7E]) # Pikit steals rupees instead of arrows - rom.write_bytes(0xEDA5, - [0x35, 0x41] if world.retro_bow[player] else [0x43, 0x44]) # Chest game gives rupees instead of arrows + get_reveal_bytes('Green Pendant') if local_world.options.map_shuffle else 0x0000) # Sahasrahla reveal + rom.write_int16(0x18017C, get_reveal_bytes('Crystal 5') | get_reveal_bytes('Crystal 6') if local_world.options.map_shuffle else 0x0000) # Bomb Shop Reveal + + rom.write_byte(0x180172, 0x01 if local_world.options.small_key_shuffle == small_key_shuffle.option_universal else 0x00) # universal keys + rom.write_byte(0x18637E, 0x01 if local_world.options.retro_bow else 0x00) # Skip quiver in item shops once bought + rom.write_byte(0x180175, 0x01 if local_world.options.retro_bow else 0x00) # rupee bow + rom.write_byte(0x180176, 0x0A if local_world.options.retro_bow else 0x00) # wood arrow cost + rom.write_byte(0x180178, 0x32 if local_world.options.retro_bow else 0x00) # silver arrow cost + rom.write_byte(0x301FC, 0xDA if local_world.options.retro_bow else 0xE1) # rupees replace arrows under pots + rom.write_byte(0x30052, 0xDB if local_world.options.retro_bow else 0xE2) # replace arrows in fish prize from bottle merchant + rom.write_bytes(0xECB4E, [0xA9, 0x00, 0xEA, 0xEA] if local_world.options.retro_bow else [0xAF, 0x77, 0xF3, 0x7E]) # Thief steals rupees instead of arrows + rom.write_bytes(0xF0D96, [0xA9, 0x00, 0xEA, 0xEA] if local_world.options.retro_bow else [0xAF, 0x77, 0xF3, 0x7E]) # Pikit steals rupees instead of arrows + rom.write_bytes(0xEDA5, [0x35, 0x41] if local_world.options.retro_bow else [0x43, 0x44]) # Chest game gives rupees instead of arrows digging_game_rng = local_random.randint(1, 30) # set rng for digging game rom.write_byte(0x180020, digging_game_rng) rom.write_byte(0xEFD95, digging_game_rng) rom.write_byte(0x1800A3, 0x01) # enable correct world setting behaviour after agahnim kills - rom.write_byte(0x1800A4, 0x01 if world.glitches_required[player] != 'no_logic' else 0x00) # enable POD EG fix - rom.write_byte(0x186383, 0x01 if world.glitches_required[ - player] == 'no_logic' else 0x00) # disable glitching to Triforce from Ganons Room + rom.write_byte(0x1800A4, 0x01 if local_world.options.glitches_required != 'no_logic' else 0x00) # enable POD EG fix + rom.write_byte(0x186383, 0x01 if local_world.options.glitches_required == 'no_logic' else 0x00) # disable glitching to Triforce from Ganons Room rom.write_byte(0x180042, 0x01 if world.save_and_quit_from_boss else 0x00) # Allow Save and Quit after boss kill # remove shield from uncle @@ -1645,7 +1633,7 @@ def get_reveal_bytes(itemName): rom.write_bytes(0x180185, [0, 0, 0]) # Uncle respawn refills (magic, bombs, arrows) rom.write_bytes(0x180188, [0, 0, 0]) # Zelda respawn refills (magic, bombs, arrows) rom.write_bytes(0x18018B, [0, 0, 0]) # Mantle respawn refills (magic, bombs, arrows) - if world.mode[player] == 'standard' and uncle_location.item and uncle_location.item.player == player: + if local_world.options.mode == 'standard' and uncle_location.item and uncle_location.item.player == player: if uncle_location.item.name in {'Bow', 'Progressive Bow'}: rom.write_byte(0x18004E, 1) # Escape Fill (arrows) rom.write_int16(0x180183, 300) # Escape fill rupee bow @@ -1673,8 +1661,8 @@ def get_reveal_bytes(itemName): 0xAD, 0xBF, 0x0A, 0xF0, 0x4F]) # allow smith into multi-entrance caves in appropriate shuffles - if world.entrance_shuffle[player] in ['restricted', 'full', 'crossed', 'insanity'] or ( - world.entrance_shuffle[player] == 'simple' and world.mode[player] == 'inverted'): + if local_world.options.entrance_shuffle in ['restricted', 'full', 'crossed', 'insanity'] or ( + local_world.options.entrance_shuffle == 'simple' and local_world.options.mode == 'inverted'): rom.write_byte(0x18004C, 0x01) # set correct flag for hera basement item @@ -1694,8 +1682,8 @@ def get_reveal_bytes(itemName): rom.write_byte(0xFED31, 0x2A) # bombable exit rom.write_byte(0xFEE41, 0x2A) # bombable exit - if world.tile_shuffle[player]: - tile_set = TileSet.get_random_tile_set(world.per_slot_randoms[player]) + if local_world.options.tile_shuffle: + tile_set = TileSet.get_random_tile_set(world.worlds[player].random) rom.write_byte(0x4BA21, tile_set.get_speed()) rom.write_byte(0x4BA1D, tile_set.get_len()) rom.write_bytes(0x4BA2A, tile_set.get_bytes()) @@ -1770,9 +1758,9 @@ def write_custom_shops(rom, world, player): slot = 0 if shop.type == ShopType.TakeAny else index if item is None: break - if world.shop_item_slots[player] or shop.type == ShopType.TakeAny: - count_shop = (shop.region.name != 'Potion Shop' or world.include_witch_hut[player]) and \ - (shop.region.name != 'Capacity Upgrade' or world.shuffle_capacity_upgrades[player]) + if world.worlds[player].options.shop_item_slots or shop.type == ShopType.TakeAny: + count_shop = (shop.region.name != 'Potion Shop' or world.worlds[player].options.include_witch_hut) and \ + (shop.region.name != 'Capacity Upgrade' or world.worlds[player].options.shuffle_capacity_upgrades) rom.write_byte(0x186560 + shop.sram_offset + slot, 1 if count_shop else 0) if item['item'] == 'Single Arrow' and item['player'] == 0: arrow_mask |= 1 << index @@ -1789,7 +1777,7 @@ def write_custom_shops(rom, world, player): item_code = get_nonnative_item_sprite(world.worlds[item['player']].item_name_to_id[item['item']]) else: item_code = item_table[item["item"]].item_code - if item['item'] == 'Single Arrow' and item['player'] == 0 and world.retro_bow[player]: + if item['item'] == 'Single Arrow' and item['player'] == 0 and world.worlds[player].options.retro_bow: rom.write_byte(0x186500 + shop.sram_offset + slot, arrow_mask) item_data = [shop_id, item_code] + price_data + \ @@ -1802,7 +1790,7 @@ def write_custom_shops(rom, world, player): items_data.extend([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) rom.write_bytes(0x184900, items_data) - if world.retro_bow[player]: + if world.worlds[player].options.retro_bow: retro_shop_slots.append(0xFF) rom.write_bytes(0x186540, retro_shop_slots) @@ -2207,19 +2195,18 @@ def write_string_to_rom(rom, target, string): def write_strings(rom, world, player): from . import ALTTPWorld - + local_random = world.worlds[player].random w: ALTTPWorld = world.worlds[player] - local_random = w.random tt = TextTable() tt.removeUnwantedText() # Let's keep this guy's text accurate to the shuffle setting. - if world.entrance_shuffle[player] in ['vanilla', 'dungeons_full', 'dungeons_simple', 'dungeons_crossed']: + if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_full', 'dungeons_simple', 'dungeons_crossed']: tt['kakariko_flophouse_man_no_flippers'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.' tt['kakariko_flophouse_man'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.' - if world.mode[player] == 'inverted': + if world.worlds[player].options.mode == 'inverted': tt['sign_village_of_outcasts'] = 'attention\nferal ducks sighted\nhiding in statues\n\nflute players beware\n' def hint_text(dest, ped_hint=False): @@ -2238,21 +2225,21 @@ def hint_text(dest, ped_hint=False): hint += f" for {world.player_name[dest.player]}" return hint - if world.scams[player].gives_king_zora_hint: + if world.worlds[player].options.scams.gives_king_zora_hint: # Zora hint zora_location = world.get_location("King Zora", player) tt['zora_tells_cost'] = f"You got 500 rupees to buy {hint_text(zora_location.item)}" \ f"\n ≥ Duh\n Oh carp\n{{CHOICE}}" - if world.scams[player].gives_bottle_merchant_hint: + if world.worlds[player].options.scams.gives_bottle_merchant_hint: # Bottle Vendor hint vendor_location = world.get_location("Bottle Merchant", player) tt['bottle_vendor_choice'] = f"I gots {hint_text(vendor_location.item)}\nYous gots 100 rupees?" \ f"\n ≥ I want\n no way!\n{{CHOICE}}" # First we write hints about entrances, some from the inconvenient list others from all reasonable entrances. - if world.hints[player]: - if world.hints[player].value >= 2: - if world.hints[player] == "full": + if world.worlds[player].options.hints: + if world.worlds[player].options.hints.value >= 2: + if world.worlds[player].options.hints == "full": tt['sign_north_of_links_house'] = '> Randomizer The telepathic tiles have hints!' else: tt['sign_north_of_links_house'] = '> Randomizer The telepathic tiles can have hints!' @@ -2265,11 +2252,11 @@ def hint_text(dest, ped_hint=False): entrances_to_hint = {} entrances_to_hint.update(InconvenientDungeonEntrances) if world.shuffle_ganon: - if world.mode[player] == 'inverted': + if world.worlds[player].options.mode == 'inverted': entrances_to_hint.update({'Inverted Ganons Tower': 'The sealed castle door'}) else: entrances_to_hint.update({'Ganons Tower': 'Ganon\'s Tower'}) - if world.entrance_shuffle[player] in ['simple', 'restricted']: + if world.worlds[player].options.entrance_shuffle in ['simple', 'restricted']: for entrance in all_entrances: if entrance.name in entrances_to_hint: this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text( @@ -2279,9 +2266,9 @@ def hint_text(dest, ped_hint=False): break # Now we write inconvenient locations for most shuffles and finish taking care of the less chaotic ones. entrances_to_hint.update(InconvenientOtherEntrances) - if world.entrance_shuffle[player] in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: hint_count = 0 - elif world.entrance_shuffle[player] in ['simple', 'restricted']: + elif world.worlds[player].options.entrance_shuffle in ['simple', 'restricted']: hint_count = 2 else: hint_count = 4 @@ -2298,31 +2285,31 @@ def hint_text(dest, ped_hint=False): # Next we handle hints for randomly selected other entrances, # curating the selection intelligently based on shuffle. - if world.entrance_shuffle[player] not in ['simple', 'restricted']: + if world.worlds[player].options.entrance_shuffle not in ['simple', 'restricted']: entrances_to_hint.update(ConnectorEntrances) entrances_to_hint.update(DungeonEntrances) - if world.mode[player] == 'inverted': + if world.worlds[player].options.mode == 'inverted': entrances_to_hint.update({'Inverted Agahnims Tower': 'The dark mountain tower'}) else: entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) - elif world.entrance_shuffle[player] == 'restricted': + elif world.worlds[player].options.entrance_shuffle == 'restricted': entrances_to_hint.update(ConnectorEntrances) entrances_to_hint.update(OtherEntrances) - if world.mode[player] == 'inverted': + if world.worlds[player].options.mode == 'inverted': entrances_to_hint.update({'Inverted Dark Sanctuary': 'The dark sanctuary cave'}) entrances_to_hint.update({'Inverted Big Bomb Shop': 'The old hero\'s dark home'}) entrances_to_hint.update({'Inverted Links House': 'The old hero\'s light home'}) else: entrances_to_hint.update({'Dark Sanctuary Hint': 'The dark sanctuary cave'}) entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'}) - if world.entrance_shuffle[player] != 'insanity': + if world.worlds[player].options.entrance_shuffle != 'insanity': entrances_to_hint.update(InsanityEntrances) if world.shuffle_ganon: - if world.mode[player] == 'inverted': + if world.worlds[player].options.mode == 'inverted': entrances_to_hint.update({'Inverted Pyramid Entrance': 'The extra castle passage'}) else: entrances_to_hint.update({'Pyramid Ledge': 'The pyramid ledge'}) - hint_count = 4 if world.entrance_shuffle[player] not in ['vanilla', 'dungeons_simple', 'dungeons_full', + hint_count = 4 if world.worlds[player].options.entrance_shuffle not in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed'] else 0 for entrance in all_entrances: if entrance.name in entrances_to_hint: @@ -2337,10 +2324,10 @@ def hint_text(dest, ped_hint=False): # Next we write a few hints for specific inconvenient locations. We don't make many because in entrance this is highly unpredictable. locations_to_hint = InconvenientLocations.copy() - if world.entrance_shuffle[player] in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: locations_to_hint.extend(InconvenientVanillaLocations) local_random.shuffle(locations_to_hint) - hint_count = 3 if world.entrance_shuffle[player] not in ['vanilla', 'dungeons_simple', 'dungeons_full', + hint_count = 3 if world.worlds[player].options.entrance_shuffle not in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed'] else 5 for location in locations_to_hint[:hint_count]: if location == 'Swamp Left': @@ -2395,15 +2382,15 @@ def hint_text(dest, ped_hint=False): # Lastly we write hints to show where certain interesting items are. items_to_hint = RelevantItems.copy() - if world.small_key_shuffle[player].hints_useful: + if world.worlds[player].options.small_key_shuffle.hints_useful: items_to_hint |= item_name_groups["Small Keys"] - if world.big_key_shuffle[player].hints_useful: + if world.worlds[player].options.big_key_shuffle.hints_useful: items_to_hint |= item_name_groups["Big Keys"] - if world.hints[player] == "full": + if world.worlds[player].options.hints == "full": hint_count = len(hint_locations) # fill all remaining hint locations with Item hints. else: - hint_count = 5 if world.entrance_shuffle[player] not in ['vanilla', 'dungeons_simple', 'dungeons_full', + hint_count = 5 if world.worlds[player].options.entrance_shuffle not in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed'] else 8 hint_count = min(hint_count, len(items_to_hint), len(hint_locations)) if hint_count: @@ -2434,7 +2421,7 @@ def hint_text(dest, ped_hint=False): tt['ganon_phase_3_no_silvers'] = 'Did you find the silver arrows%s' % silverarrow_hint tt['ganon_phase_3_no_silvers_alt'] = 'Did you find the silver arrows%s' % silverarrow_hint if world.worlds[player].has_progressive_bows and (w.difficulty_requirements.progressive_bow_limit >= 2 or ( - world.swordless[player] or world.glitches_required[player] == 'no_glitches')): + world.worlds[player].options.swordless or world.worlds[player].options.glitches_required == 'no_glitches')): prog_bow_locs = world.find_item_locations('Progressive Bow', player, True) local_random.shuffle(prog_bow_locs) found_bow = False @@ -2458,26 +2445,26 @@ def hint_text(dest, ped_hint=False): greenpendant = world.find_item('Green Pendant', player) tt['sahasrahla_bring_courage'] = 'I lost my family heirloom in %s' % greenpendant.hint_text - if world.crystals_needed_for_gt[player] == 1: + if world.worlds[player].options.crystals_needed_for_gt == 1: tt['sign_ganons_tower'] = 'You need a crystal to enter.' else: - tt['sign_ganons_tower'] = f'You need {world.crystals_needed_for_gt[player]} crystals to enter.' + tt['sign_ganons_tower'] = f'You need {world.worlds[player].options.crystals_needed_for_gt} crystals to enter.' - if world.goal[player] == 'bosses': + if world.worlds[player].options.goal == 'bosses': tt['sign_ganon'] = 'You need to kill all bosses, Ganon last.' - elif world.goal[player] == 'ganon_pedestal': + elif world.worlds[player].options.goal == 'ganon_pedestal': tt['sign_ganon'] = 'You need to pull the pedestal to defeat Ganon.' - elif world.goal[player] == "ganon": - if world.crystals_needed_for_ganon[player] == 1: + elif world.worlds[player].options.goal == "ganon": + if world.worlds[player].options.crystals_needed_for_ganon == 1: tt['sign_ganon'] = 'You need a crystal to beat Ganon and have beaten Agahnim atop Ganons Tower.' else: - tt['sign_ganon'] = f'You need {world.crystals_needed_for_ganon[player]} crystals to beat Ganon and ' \ + tt['sign_ganon'] = f'You need {world.worlds[player].options.crystals_needed_for_ganon} crystals to beat Ganon and ' \ f'have beaten Agahnim atop Ganons Tower' else: - if world.crystals_needed_for_ganon[player] == 1: + if world.worlds[player].options.crystals_needed_for_ganon == 1: tt['sign_ganon'] = 'You need a crystal to beat Ganon.' else: - tt['sign_ganon'] = f'You need {world.crystals_needed_for_ganon[player]} crystals to beat Ganon.' + tt['sign_ganon'] = f'You need {world.worlds[player].options.crystals_needed_for_ganon} crystals to beat Ganon.' tt['uncle_leaving_text'] = Uncle_texts[local_random.randint(0, len(Uncle_texts) - 1)] tt['end_triforce'] = "{NOBORDER}\n" + Triforce_texts[local_random.randint(0, len(Triforce_texts) - 1)] @@ -2490,10 +2477,10 @@ def hint_text(dest, ped_hint=False): triforce_pieces_required = max(0, w.treasure_hunt_required - sum(1 for item in world.precollected_items[player] if item.name == "Triforce Piece")) - if world.goal[player] in ['triforce_hunt', 'local_triforce_hunt']: + if world.worlds[player].options.goal in ['triforce_hunt', 'local_triforce_hunt']: tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Get the Triforce Pieces.' tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.' - if world.goal[player] == 'triforce_hunt' and world.players > 1: + if world.worlds[player].options.goal == 'triforce_hunt' and world.players > 1: tt['sign_ganon'] = 'Go find the Triforce pieces with your friends... Ganon is invincible!' else: tt['sign_ganon'] = 'Go find the Triforce pieces... Ganon is invincible!' @@ -2507,7 +2494,7 @@ def hint_text(dest, ped_hint=False): "invisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\n" \ "hidden in a hollow tree. If you bring\n%d Triforce piece out of %d, I can reassemble it." % \ (triforce_pieces_required, w.treasure_hunt_total) - elif world.goal[player] in ['pedestal']: + elif world.worlds[player].options.goal in ['pedestal']: tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Your goal is at the pedestal.' tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.' tt['sign_ganon'] = 'You need to get to the pedestal... Ganon is invincible!' @@ -2516,17 +2503,17 @@ def hint_text(dest, ped_hint=False): tt['ganon_fall_in_alt'] = 'You cannot defeat me until you finish your goal!' tt['ganon_phase_3_alt'] = 'Got wax in\nyour ears?\nI can not die!' if triforce_pieces_required > 1: - if world.goal[player] == 'ganon_triforce_hunt' and world.players > 1: + if world.worlds[player].options.goal == 'ganon_triforce_hunt' and world.players > 1: tt['sign_ganon'] = 'You need to find %d Triforce pieces out of %d with your friends to defeat Ganon.' % \ (triforce_pieces_required, w.treasure_hunt_total) - elif world.goal[player] in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: + elif world.worlds[player].options.goal in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: tt['sign_ganon'] = 'You need to find %d Triforce pieces out of %d to defeat Ganon.' % \ (triforce_pieces_required, w.treasure_hunt_total) else: - if world.goal[player] == 'ganon_triforce_hunt' and world.players > 1: + if world.worlds[player].options.goal == 'ganon_triforce_hunt' and world.players > 1: tt['sign_ganon'] = 'You need to find %d Triforce piece out of %d with your friends to defeat Ganon.' % \ (triforce_pieces_required, w.treasure_hunt_total) - elif world.goal[player] in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: + elif world.worlds[player].options.goal in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: tt['sign_ganon'] = 'You need to find %d Triforce piece out of %d to defeat Ganon.' % \ (triforce_pieces_required, w.treasure_hunt_total) @@ -2549,11 +2536,11 @@ def hint_text(dest, ped_hint=False): tt['tablet_bombos_book'] = bombos_text # inverted spawn menu changes - if world.mode[player] == 'inverted': + if world.worlds[player].options.mode == 'inverted': tt['menu_start_2'] = "{MENU}\n{SPEED0}\n≥@'s house\n Dark Chapel\n{CHOICE3}" tt['menu_start_3'] = "{MENU}\n{SPEED0}\n≥@'s house\n Dark Chapel\n Mountain Cave\n{CHOICE2}" - for at, text, _ in world.plando_texts[player]: + for at, text, _ in world.worlds[player].options.plando_texts: if at not in tt: raise Exception(f"No text target \"{at}\" found.") @@ -2626,12 +2613,12 @@ def set_inverted_mode(world, player, rom): rom.write_byte(snes_to_pc(0x08D40C), 0xD0) # morph proof # the following bytes should only be written in vanilla # or they'll overwrite the randomizer's shuffles - if world.entrance_shuffle[player] == 'vanilla': + if world.worlds[player].options.entrance_shuffle == 'vanilla': rom.write_byte(0xDBB73 + 0x23, 0x37) # switch AT and GT rom.write_byte(0xDBB73 + 0x36, 0x24) rom.write_int16(0x15AEE + 2 * 0x38, 0x00E0) rom.write_int16(0x15AEE + 2 * 0x25, 0x000C) - if world.entrance_shuffle[player] in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: rom.write_byte(0x15B8C, 0x6C) rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house rom.write_byte(0xDBB73 + 0x52, 0x01) @@ -2689,7 +2676,7 @@ def set_inverted_mode(world, player, rom): rom.write_int16(snes_to_pc(0x02D9A6), 0x005A) rom.write_byte(snes_to_pc(0x02D9B3), 0x12) # keep the old man spawn point at old man house unless shuffle is vanilla - if world.entrance_shuffle[player] in ['vanilla', 'dungeons_full', 'dungeons_simple', 'dungeons_crossed']: + if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_full', 'dungeons_simple', 'dungeons_crossed']: rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) rom.write_int16(snes_to_pc(0x02D8DE), 0x00F1) rom.write_bytes(snes_to_pc(0x02D910), [0x1F, 0x1E, 0x1F, 0x1F, 0x03, 0x02, 0x03, 0x03]) @@ -2752,7 +2739,7 @@ def set_inverted_mode(world, player, rom): rom.write_int16s(snes_to_pc(0x1bb836), [0x001B, 0x001B, 0x001B]) rom.write_int16(snes_to_pc(0x308300), 0x0140) # new pyramid hole entrance rom.write_int16(snes_to_pc(0x308320), 0x001B) - if world.entrance_shuffle[player] in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: rom.write_byte(snes_to_pc(0x308340), 0x7B) rom.write_int16(snes_to_pc(0x1af504), 0x148B) rom.write_int16(snes_to_pc(0x1af50c), 0x149B) @@ -2789,10 +2776,10 @@ def set_inverted_mode(world, player, rom): rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) rom.write_int16(0xDB96F + 2 * 0x35, 0x001B) # move pyramid exit door rom.write_int16(0xDBA71 + 2 * 0x35, 0x06A4) - if world.entrance_shuffle[player] in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: rom.write_byte(0xDBB73 + 0x35, 0x36) rom.write_byte(snes_to_pc(0x09D436), 0xF3) # remove castle gate warp - if world.entrance_shuffle[player] in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: rom.write_int16(0x15AEE + 2 * 0x37, 0x0010) # pyramid exit to new hc area rom.write_byte(0x15B8C + 0x37, 0x1B) rom.write_int16(0x15BDB + 2 * 0x37, 0x0418) diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index 3f5081129aa9..452c15223ca7 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -27,9 +27,9 @@ def set_rules(world): player = world.player world = world.multiworld - if world.glitches_required[player] == 'no_logic': + if world.worlds[player].options.glitches_required == 'no_logic': if player == next(player_id for player_id in world.get_game_players("A Link to the Past") - if world.glitches_required[player_id] == 'no_logic'): # only warn one time + if world.worlds[player_id].options.glitches_required == 'no_logic'): # only warn one time logging.info( 'WARNING! Seeds generated under this logic often require major glitches and may be impossible!') @@ -40,8 +40,8 @@ def set_rules(world): else: # Set access rules according to max glitches for multiworld progression. # Set accessibility to none, and shuffle assuming the no logic players can always win - world.accessibility[player].value = ItemsAccessibility.option_minimal - world.progression_balancing[player].value = 0 + world.worlds[player].options.accessibility.value = ItemsAccessibility.option_minimal + world.worlds[player].options.progression_balancing.value = 0 else: world.completion_condition[player] = lambda state: state.has('Triforce', player) @@ -49,52 +49,52 @@ def set_rules(world): dungeon_boss_rules(world, player) global_rules(world, player) - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': default_rules(world, player) - if world.mode[player] == 'open': + if world.worlds[player].options.mode == 'open': open_rules(world, player) - elif world.mode[player] == 'standard': + elif world.worlds[player].options.mode == 'standard': standard_rules(world, player) - elif world.mode[player] == 'inverted': + elif world.worlds[player].options.mode == 'inverted': open_rules(world, player) inverted_rules(world, player) else: - raise NotImplementedError(f'World state {world.mode[player]} is not implemented yet') + raise NotImplementedError(f'World state {world.worlds[player].options.mode} is not implemented yet') - if world.glitches_required[player] == 'no_glitches': + if world.worlds[player].options.glitches_required == 'no_glitches': no_glitches_rules(world, player) forbid_bomb_jump_requirements(world, player) - elif world.glitches_required[player] == 'overworld_glitches': + elif world.worlds[player].options.glitches_required == 'overworld_glitches': # Initially setting no_glitches_rules to set the baseline rules for some # entrances. The overworld_glitches_rules set is primarily additive. no_glitches_rules(world, player) fake_flipper_rules(world, player) overworld_glitches_rules(world, player) forbid_bomb_jump_requirements(world, player) - elif world.glitches_required[player] in ['hybrid_major_glitches', 'no_logic']: + elif world.worlds[player].options.glitches_required in ['hybrid_major_glitches', 'no_logic']: no_glitches_rules(world, player) fake_flipper_rules(world, player) overworld_glitches_rules(world, player) underworld_glitches_rules(world, player) bomb_jump_requirements(world, player) - elif world.glitches_required[player] == 'minor_glitches': + elif world.worlds[player].options.glitches_required == 'minor_glitches': no_glitches_rules(world, player) fake_flipper_rules(world, player) forbid_bomb_jump_requirements(world, player) else: - raise NotImplementedError(f'Not implemented yet: Logic - {world.glitches_required[player]}') + raise NotImplementedError(f'Not implemented yet: Logic - {world.worlds[player].options.glitches_required}') - if world.goal[player] == 'bosses': + if world.worlds[player].options.goal == 'bosses': # require all bosses to beat ganon add_rule(world.get_location('Ganon', player), lambda state: state.can_reach('Master Sword Pedestal', 'Location', player) and state.has('Beat Agahnim 1', player) and state.has('Beat Agahnim 2', player) and has_crystals(state, 7, player)) - elif world.goal[player] == 'ganon': + elif world.worlds[player].options.goal == 'ganon': # require aga2 to beat ganon add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player)) - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': set_big_bomb_rules(world, player) - if world.glitches_required[player].current_key in {'overworld_glitches', 'hybrid_major_glitches', 'no_logic'} and world.entrance_shuffle[player].current_key not in {'insanity', 'insanity_legacy', 'madness'}: + if world.worlds[player].options.glitches_required.current_key in {'overworld_glitches', 'hybrid_major_glitches', 'no_logic'} and world.worlds[player].options.entrance_shuffle.current_key not in {'insanity', 'insanity_legacy', 'madness'}: path_to_courtyard = mirrorless_path_to_castle_courtyard(world, player) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.multiworld.get_entrance('Dark Death Mountain Offset Mirror', player).can_reach(state) and all(rule(state) for rule in path_to_courtyard), 'or') else: @@ -102,21 +102,24 @@ def set_rules(world): # if swamp and dam have not been moved we require mirror for swamp palace # however there is mirrorless swamp in hybrid MG, so we don't necessarily want this. HMG handles this requirement itself. - if not world.worlds[player].swamp_patch_required and world.glitches_required[player] not in ['hybrid_major_glitches', 'no_logic']: + if not world.worlds[player].swamp_patch_required and world.worlds[player].options.glitches_required not in ['hybrid_major_glitches', 'no_logic']: add_rule(world.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Magic Mirror', player)) # GT Entrance may be required for Turtle Rock for OWG and < 7 required - ganons_tower = world.get_entrance('Inverted Ganons Tower' if world.mode[player] == 'inverted' else 'Ganons Tower', player) - if world.crystals_needed_for_gt[player] == 7 and not (world.glitches_required[player] in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic'] and world.mode[player] != 'inverted'): + ganons_tower = world.get_entrance('Inverted Ganons Tower' if world.worlds[player].options.mode == 'inverted' else 'Ganons Tower', player) + if (world.worlds[player].options.crystals_needed_for_gt == 7 + and not (world.worlds[player].options.glitches_required + in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic'] + and world.worlds[player].options.mode != 'inverted')): set_rule(ganons_tower, lambda state: False) set_trock_key_rules(world, player) - set_rule(ganons_tower, lambda state: has_crystals(state, state.multiworld.crystals_needed_for_gt[player], player)) - if world.mode[player] != 'inverted' and world.glitches_required[player] in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: + set_rule(ganons_tower, lambda state: has_crystals(state, state.multiworld.worlds[player].options.crystals_needed_for_gt, player)) + if world.worlds[player].options.mode != 'inverted' and world.worlds[player].options.glitches_required in ['overworld_glitches', 'hybrid_major_glitches', 'no_logic']: add_rule(world.get_entrance('Ganons Tower', player), lambda state: state.multiworld.get_entrance('Ganons Tower Ascent', player).can_reach(state), 'or') - set_bunny_rules(world, player, world.mode[player] == 'inverted') + set_bunny_rules(world, player, world.worlds[player].options.mode == 'inverted') def mirrorless_path_to_castle_courtyard(world, player): @@ -150,17 +153,17 @@ def set_always_allow(spot, rule): def add_lamp_requirement(world: MultiWorld, spot, player: int, has_accessible_torch: bool = False): - if world.dark_room_logic[player] == "lamp": + if world.worlds[player].options.dark_room_logic == "lamp": add_rule(spot, lambda state: state.has('Lamp', player)) - elif world.dark_room_logic[player] == "torches": # implicitly lamp as well + elif world.worlds[player].options.dark_room_logic == "torches": # implicitly lamp as well if has_accessible_torch: add_rule(spot, lambda state: state.has('Lamp', player) or state.has('Fire Rod', player)) else: add_rule(spot, lambda state: state.has('Lamp', player)) - elif world.dark_room_logic[player] == "none": + elif world.worlds[player].options.dark_room_logic == "none": pass else: - raise ValueError(f"Unknown Dark Room Logic: {world.dark_room_logic[player]}") + raise ValueError(f"Unknown Dark Room Logic: {world.worlds[player].options.dark_room_logic}") non_crossover_items = (item_name_groups["Small Keys"] | item_name_groups["Big Keys"] | progression_items) - { @@ -227,12 +230,13 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_location('Sick Kid', player), lambda state: state.has_group("Bottles", player)) set_rule(multiworld.get_location('Library', player), lambda state: state.has('Pegasus Boots', player)) - if multiworld.enemy_shuffle[player]: + if world.options.enemy_shuffle: set_rule(multiworld.get_location('Mimic Cave', player), lambda state: state.has('Hammer', player) and can_kill_most_things(state, player, 4)) else: set_rule(multiworld.get_location('Mimic Cave', player), lambda state: state.has('Hammer', player) - and ((state.multiworld.enemy_health[player] in ("easy", "default") and can_use_bombs(state, player, 4)) + and ((state.multiworld.worlds[player].options.enemy_health in ("easy", "default") + and can_use_bombs(state, player, 4)) or can_shoot_arrows(state, player) or state.has("Cane of Somaria", player) or has_beam_sword(state, player))) @@ -299,8 +303,7 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_entrance('Sewers Door', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 4) or ( - multiworld.small_key_shuffle[player] == small_key_shuffle.option_universal and multiworld.mode[ - player] == 'standard')) # standard universal small keys cannot access the shop + world.options.small_key_shuffle == small_key_shuffle.option_universal and world.options.mode == 'standard')) # standard universal small keys cannot access the shop set_rule(multiworld.get_entrance('Sewers Back Door', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 4)) set_rule(multiworld.get_entrance('Sewers Secret Room', player), lambda state: can_bomb_or_bonk(state, player)) @@ -339,12 +342,12 @@ def global_rules(multiworld: MultiWorld, player: int): add_rule(ep_prize, lambda state: state.has('Big Key (Eastern Palace)', player) and state._lttp_has_key('Small Key (Eastern Palace)', player, 2) and ep_prize.parent_region.dungeon.boss.can_defeat(state)) - if not multiworld.enemy_shuffle[player]: + if not world.options.enemy_shuffle: add_rule(ep_boss, lambda state: can_shoot_arrows(state, player)) add_rule(ep_prize, lambda state: can_shoot_arrows(state, player)) # You can always kill the Stalfos' with the pots on easy/normal - if multiworld.enemy_health[player] in ("hard", "expert") or multiworld.enemy_shuffle[player]: + if world.options.enemy_health in ("hard", "expert") or world.options.enemy_shuffle: stalfos_rule = lambda state: can_kill_most_things(state, player, 4) for location in ['Eastern Palace - Compass Chest', 'Eastern Palace - Big Chest', 'Eastern Palace - Dark Square Pot Key', 'Eastern Palace - Dark Eyegore Key Drop', @@ -362,14 +365,14 @@ def global_rules(multiworld: MultiWorld, player: int): add_rule(multiworld.get_location('Desert Palace - Boss', player), lambda state: state._lttp_has_key('Small Key (Desert Palace)', player, 4) and state.has('Big Key (Desert Palace)', player) and has_fire_source(state, player) and state.multiworld.get_location('Desert Palace - Boss', player).parent_region.dungeon.boss.can_defeat(state)) # logic patch to prevent placing a crystal in Desert that's required to reach the required keys - if not (multiworld.small_key_shuffle[player] and multiworld.big_key_shuffle[player]): + if not (world.options.small_key_shuffle and world.options.big_key_shuffle): add_rule(multiworld.get_location('Desert Palace - Prize', player), lambda state: state.multiworld.get_region('Desert Palace Main (Outer)', player).can_reach(state)) set_rule(multiworld.get_location('Tower of Hera - Basement Cage', player), lambda state: can_activate_crystal_switch(state, player)) set_rule(multiworld.get_location('Tower of Hera - Map Chest', player), lambda state: can_activate_crystal_switch(state, player)) set_rule(multiworld.get_entrance('Tower of Hera Small Key Door', player), lambda state: can_activate_crystal_switch(state, player) and (state._lttp_has_key('Small Key (Tower of Hera)', player) or location_item_name(state, 'Tower of Hera - Big Key Chest', player) == ('Small Key (Tower of Hera)', player))) set_rule(multiworld.get_entrance('Tower of Hera Big Key Door', player), lambda state: can_activate_crystal_switch(state, player) and state.has('Big Key (Tower of Hera)', player)) - if multiworld.enemy_shuffle[player]: + if world.options.enemy_shuffle: add_rule(multiworld.get_entrance('Tower of Hera Big Key Door', player), lambda state: can_kill_most_things(state, player, 3)) else: add_rule(multiworld.get_entrance('Tower of Hera Big Key Door', player), @@ -378,7 +381,7 @@ def global_rules(multiworld: MultiWorld, player: int): or state.has("Cane of Somaria", player))) set_rule(multiworld.get_location('Tower of Hera - Big Chest', player), lambda state: state.has('Big Key (Tower of Hera)', player)) set_rule(multiworld.get_location('Tower of Hera - Big Key Chest', player), lambda state: has_fire_source(state, player)) - if multiworld.accessibility[player] != 'full': + if world.options.accessibility != 'full': set_always_allow(multiworld.get_location('Tower of Hera - Big Key Chest', player), lambda state, item: item.name == 'Small Key (Tower of Hera)' and item.player == player) set_rule(multiworld.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Flippers', player) and state.has('Open Floodgate', player)) @@ -387,32 +390,32 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_location('Swamp Palace - Trench 1 Pot Key', player), lambda state: state._lttp_has_key('Small Key (Swamp Palace)', player, 2)) set_rule(multiworld.get_entrance('Swamp Palace (Center)', player), lambda state: state.has('Hammer', player) and state._lttp_has_key('Small Key (Swamp Palace)', player, 3)) set_rule(multiworld.get_location('Swamp Palace - Hookshot Pot Key', player), lambda state: state.has('Hookshot', player)) - if multiworld.pot_shuffle[player]: + if world.options.pot_shuffle: # it could move the key to the top right platform which can only be reached with bombs add_rule(multiworld.get_location('Swamp Palace - Hookshot Pot Key', player), lambda state: can_use_bombs(state, player)) set_rule(multiworld.get_entrance('Swamp Palace (West)', player), lambda state: state._lttp_has_key('Small Key (Swamp Palace)', player, 6) if state.has('Hookshot', player) else state._lttp_has_key('Small Key (Swamp Palace)', player, 4)) set_rule(multiworld.get_location('Swamp Palace - Big Chest', player), lambda state: state.has('Big Key (Swamp Palace)', player)) - if multiworld.accessibility[player] != 'full': + if world.options.accessibility != 'full': allow_self_locking_items(multiworld.get_location('Swamp Palace - Big Chest', player), 'Big Key (Swamp Palace)') set_rule(multiworld.get_entrance('Swamp Palace (North)', player), lambda state: state.has('Hookshot', player) and state._lttp_has_key('Small Key (Swamp Palace)', player, 5)) - if not multiworld.small_key_shuffle[player] and multiworld.glitches_required[player] not in ['hybrid_major_glitches', 'no_logic']: + if not world.options.small_key_shuffle and world.options.glitches_required not in ['hybrid_major_glitches', 'no_logic']: forbid_item(multiworld.get_location('Swamp Palace - Entrance', player), 'Big Key (Swamp Palace)', player) add_rule(multiworld.get_location('Swamp Palace - Prize', player), lambda state: state._lttp_has_key('Small Key (Swamp Palace)', player, 6)) add_rule(multiworld.get_location('Swamp Palace - Boss', player), lambda state: state._lttp_has_key('Small Key (Swamp Palace)', player, 6)) - if multiworld.pot_shuffle[player]: + if world.options.pot_shuffle: # key can (and probably will) be moved behind bombable wall set_rule(multiworld.get_location('Swamp Palace - Waterway Pot Key', player), lambda state: can_use_bombs(state, player)) set_rule(multiworld.get_entrance('Thieves Town Big Key Door', player), lambda state: state.has('Big Key (Thieves Town)', player)) - if multiworld.worlds[player].dungeons["Thieves Town"].boss.enemizer_name == "Blind": + if world.dungeons["Thieves Town"].boss.enemizer_name == "Blind": set_rule(multiworld.get_entrance('Blind Fight', player), lambda state: state._lttp_has_key('Small Key (Thieves Town)', player, 3) and can_use_bombs(state, player)) set_rule(multiworld.get_location('Thieves\' Town - Big Chest', player), lambda state: ((state._lttp_has_key('Small Key (Thieves Town)', player, 3)) or (location_item_name(state, 'Thieves\' Town - Big Chest', player) == ("Small Key (Thieves Town)", player)) and state._lttp_has_key('Small Key (Thieves Town)', player, 2)) and state.has('Hammer', player)) set_rule(multiworld.get_location('Thieves\' Town - Blind\'s Cell', player), lambda state: state._lttp_has_key('Small Key (Thieves Town)', player)) - if multiworld.accessibility[player] != 'full' and not multiworld.key_drop_shuffle[player]: + if world.options.accessibility != 'full' and not world.options.key_drop_shuffle: set_always_allow(multiworld.get_location('Thieves\' Town - Big Chest', player), lambda state, item: item.name == 'Small Key (Thieves Town)' and item.player == player) set_rule(multiworld.get_location('Thieves\' Town - Attic', player), lambda state: state._lttp_has_key('Small Key (Thieves Town)', player, 3)) set_rule(multiworld.get_location('Thieves\' Town - Spike Switch Pot Key', player), @@ -424,7 +427,7 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_entrance('Skull Woods First Section West Door', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 5)) set_rule(multiworld.get_entrance('Skull Woods First Section (Left) Door to Exit', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 5)) set_rule(multiworld.get_location('Skull Woods - Big Chest', player), lambda state: state.has('Big Key (Skull Woods)', player) and can_use_bombs(state, player)) - if multiworld.accessibility[player] != 'full': + if world.options.accessibility != 'full': allow_self_locking_items(multiworld.get_location('Skull Woods - Big Chest', player), 'Big Key (Skull Woods)') set_rule(multiworld.get_entrance('Skull Woods Torch Room', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 4) and state.has('Fire Rod', player) and has_sword(state, player)) # sword required for curtain add_rule(multiworld.get_location('Skull Woods - Prize', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 5)) @@ -501,13 +504,13 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_entrance('Turtle Rock (Trinexx)', player), lambda state: state._lttp_has_key('Small Key (Turtle Rock)', player, 6) and state.has('Big Key (Turtle Rock)', player) and state.has('Cane of Somaria', player)) set_rule(multiworld.get_entrance('Turtle Rock Second Section Bomb Wall', player), lambda state: can_kill_most_things(state, player, 10)) - if not multiworld.worlds[player].fix_trock_doors: + if not world.fix_trock_doors: add_rule(multiworld.get_entrance('Turtle Rock Second Section Bomb Wall', player), lambda state: can_use_bombs(state, player)) set_rule(multiworld.get_entrance('Turtle Rock Second Section from Bomb Wall', player), lambda state: can_use_bombs(state, player)) set_rule(multiworld.get_entrance('Turtle Rock Eye Bridge from Bomb Wall', player), lambda state: can_use_bombs(state, player)) set_rule(multiworld.get_entrance('Turtle Rock Eye Bridge Bomb Wall', player), lambda state: can_use_bombs(state, player)) - if multiworld.enemy_shuffle[player]: + if world.options.enemy_shuffle: set_rule(multiworld.get_entrance('Palace of Darkness Bonk Wall', player), lambda state: can_bomb_or_bonk(state, player) and can_kill_most_things(state, player, 3)) else: set_rule(multiworld.get_entrance('Palace of Darkness Bonk Wall', player), lambda state: can_bomb_or_bonk(state, player) and can_shoot_arrows(state, player)) @@ -517,18 +520,18 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_entrance('Palace of Darkness (North)', player), lambda state: state._lttp_has_key('Small Key (Palace of Darkness)', player, 4)) set_rule(multiworld.get_location('Palace of Darkness - Big Chest', player), lambda state: can_use_bombs(state, player) and state.has('Big Key (Palace of Darkness)', player)) set_rule(multiworld.get_location('Palace of Darkness - The Arena - Ledge', player), lambda state: can_use_bombs(state, player)) - if multiworld.pot_shuffle[player]: + if world.options.pot_shuffle: # chest switch may be up on ledge where bombs are required set_rule(multiworld.get_location('Palace of Darkness - Stalfos Basement', player), lambda state: can_use_bombs(state, player)) set_rule(multiworld.get_entrance('Palace of Darkness Big Key Chest Staircase', player), lambda state: can_use_bombs(state, player) and (state._lttp_has_key('Small Key (Palace of Darkness)', player, 6) or ( location_item_name(state, 'Palace of Darkness - Big Key Chest', player) in [('Small Key (Palace of Darkness)', player)] and state._lttp_has_key('Small Key (Palace of Darkness)', player, 3)))) - if multiworld.accessibility[player] != 'full': + if world.options.accessibility != 'full': set_always_allow(multiworld.get_location('Palace of Darkness - Big Key Chest', player), lambda state, item: item.name == 'Small Key (Palace of Darkness)' and item.player == player and state._lttp_has_key('Small Key (Palace of Darkness)', player, 5)) set_rule(multiworld.get_entrance('Palace of Darkness Spike Statue Room Door', player), lambda state: state._lttp_has_key('Small Key (Palace of Darkness)', player, 6) or ( location_item_name(state, 'Palace of Darkness - Harmless Hellway', player) in [('Small Key (Palace of Darkness)', player)] and state._lttp_has_key('Small Key (Palace of Darkness)', player, 4))) - if multiworld.accessibility[player] != 'full': + if world.options.accessibility != 'full': set_always_allow(multiworld.get_location('Palace of Darkness - Harmless Hellway', player), lambda state, item: item.name == 'Small Key (Palace of Darkness)' and item.player == player and state._lttp_has_key('Small Key (Palace of Darkness)', player, 5)) set_rule(multiworld.get_entrance('Palace of Darkness Maze Door', player), lambda state: state._lttp_has_key('Small Key (Palace of Darkness)', player, 6)) @@ -541,13 +544,13 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_location('Ganons Tower - Bob\'s Torch', player), lambda state: state.has('Pegasus Boots', player)) set_rule(multiworld.get_entrance('Ganons Tower (Tile Room)', player), lambda state: state.has('Cane of Somaria', player)) set_rule(multiworld.get_entrance('Ganons Tower (Hookshot Room)', player), lambda state: state.has('Hammer', player) and (state.has('Hookshot', player) or state.has('Pegasus Boots', player))) - if multiworld.pot_shuffle[player]: + if world.options.pot_shuffle: set_rule(multiworld.get_location('Ganons Tower - Conveyor Cross Pot Key', player), lambda state: state.has('Hammer', player) and (state.has('Hookshot', player) or state.has('Pegasus Boots', player))) set_rule(multiworld.get_entrance('Ganons Tower (Map Room)', player), lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 8) or ( location_item_name(state, 'Ganons Tower - Map Chest', player) in [('Big Key (Ganons Tower)', player)] and state._lttp_has_key('Small Key (Ganons Tower)', player, 6))) # this seemed to be causing generation failure, disable for now - # if world.accessibility[player] != 'full': + # if world.worlds[player].options.accessibility != 'full': # set_always_allow(world.get_location('Ganons Tower - Map Chest', player), lambda state, item: item.name == 'Small Key (Ganons Tower)' and item.player == player and state._lttp_has_key('Small Key (Ganons Tower)', player, 7) and state.can_reach('Ganons Tower (Hookshot Room)', 'region', player)) # It is possible to need more than 6 keys to get through this entrance if you spend keys elsewhere. We reflect this in the chest requirements. @@ -582,7 +585,7 @@ def global_rules(multiworld: MultiWorld, player: int): lambda state: can_use_bombs(state, player) and state.multiworld.get_location('Ganons Tower - Big Key Chest', player).parent_region.dungeon.bosses['bottom'].can_defeat(state)) set_rule(multiworld.get_location('Ganons Tower - Big Key Room - Right', player), lambda state: can_use_bombs(state, player) and state.multiworld.get_location('Ganons Tower - Big Key Room - Right', player).parent_region.dungeon.bosses['bottom'].can_defeat(state)) - if multiworld.enemy_shuffle[player]: + if world.options.enemy_shuffle: set_rule(multiworld.get_entrance('Ganons Tower Big Key Door', player), lambda state: state.has('Big Key (Ganons Tower)', player)) else: @@ -600,12 +603,12 @@ def global_rules(multiworld: MultiWorld, player: int): set_defeat_dungeon_boss_rule(multiworld.get_location('Agahnim 2', player)) ganon = multiworld.get_location('Ganon', player) set_rule(ganon, lambda state: GanonDefeatRule(state, player)) - if multiworld.goal[player] in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: + if world.options.goal in ['ganon_triforce_hunt', 'local_ganon_triforce_hunt']: add_rule(ganon, lambda state: has_triforce_pieces(state, player)) - elif multiworld.goal[player] == 'ganon_pedestal': + elif world.options.goal == 'ganon_pedestal': add_rule(multiworld.get_location('Ganon', player), lambda state: state.can_reach('Master Sword Pedestal', 'Location', player)) else: - add_rule(ganon, lambda state: has_crystals(state, state.multiworld.crystals_needed_for_ganon[player], player)) + add_rule(ganon, lambda state: has_crystals(state, state.multiworld.worlds[player].options.crystals_needed_for_ganon, player)) set_rule(multiworld.get_entrance('Ganon Drop', player), lambda state: has_beam_sword(state, player)) # need to damage ganon to get tiles to drop set_rule(multiworld.get_location('Flute Activation Spot', player), lambda state: state.has('Flute', player)) @@ -722,9 +725,9 @@ def default_rules(world, player): set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has('Magic Mirror', player)) set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has('Moon Pearl', player) and has_sword(state, player) and has_turtle_rock_medallion(state, player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword required to cast magic (!) - set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player].to_bool(world, player)) + set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.worlds[player].options.open_pyramid.to_bool(world, player)) - if world.swordless[player]: + if world.worlds[player].options.swordless: swordless_rules(world, player) @@ -879,14 +882,14 @@ def inverted_rules(world, player): set_rule(world.get_entrance('Dark Grassy Lawn Flute', player), lambda state: state.has('Activated Flute', player)) set_rule(world.get_entrance('Hammer Peg Area Flute', player), lambda state: state.has('Activated Flute', player)) - set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) + set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.worlds[player].options.open_pyramid) - if world.swordless[player]: + if world.worlds[player].options.swordless: swordless_rules(world, player) def no_glitches_rules(world, player): """""" - if world.mode[player] == 'inverted': + if world.worlds[player].options.mode == 'inverted': set_rule(world.get_entrance('Zoras River', player), lambda state: state.has('Moon Pearl', player) and (state.has('Flippers', player) or can_lift_rocks(state, player))) set_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # can be fake flippered to set_rule(world.get_entrance('Lake Hylia Island Pier', player), lambda state: state.has('Moon Pearl', player) and state.has('Flippers', player)) # can be fake flippered to @@ -910,7 +913,7 @@ def no_glitches_rules(world, player): add_conditional_lamps(world, player) def fake_flipper_rules(world, player): - if world.mode[player] == 'inverted': + if world.worlds[player].options.mode == 'inverted': set_rule(world.get_entrance('Zoras River', player), lambda state: state.has('Moon Pearl', player)) set_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has('Moon Pearl', player)) set_rule(world.get_entrance('Lake Hylia Island Pier', player), lambda state: state.has('Moon Pearl', player)) @@ -996,7 +999,7 @@ def add_conditional_lamp(spot, region, spottype='Location', accessible_torch=Fal 'Location', True) add_conditional_lamp('Palace of Darkness - Dark Basement - Right', 'Palace of Darkness (Entrance)', 'Location', True) - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': add_conditional_lamp('Agahnim 1', 'Agahnims Tower', 'Entrance') add_conditional_lamp('Castle Tower - Dark Maze', 'Agahnims Tower') add_conditional_lamp('Castle Tower - Dark Archer Key Drop', 'Agahnims Tower') @@ -1018,7 +1021,7 @@ def add_conditional_lamp(spot, region, spottype='Location', accessible_torch=Fal add_conditional_lamp('Eastern Palace - Boss', 'Eastern Palace', 'Location', True) add_conditional_lamp('Eastern Palace - Prize', 'Eastern Palace', 'Location', True) - if not world.mode[player] == "standard": + if not world.worlds[player].options.mode == "standard": add_lamp_requirement(world, world.get_location('Sewers - Dark Cross', player), player) add_lamp_requirement(world, world.get_entrance('Sewers Back Door', player), player) add_lamp_requirement(world, world.get_entrance('Throne Room', player), player) @@ -1044,7 +1047,7 @@ def basement_key_rule(state): set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 4) and state.has('Big Key (Hyrule Castle)', player) - and (world.enemy_health[player] in ("easy", "default") + and (world.worlds[player].options.enemy_health in ("easy", "default") or can_kill_most_things(state, player, 1))) @@ -1058,7 +1061,7 @@ def swordless_rules(world, player): set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has('Hammer', player)) # need to damage ganon to get tiles to drop - if world.mode[player] != 'inverted': + if world.worlds[player].options.mode != 'inverted': set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has('Moon Pearl', player) and has_turtle_rock_medallion(state, player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword not required to use medallion for opening in swordless (!) set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has('Moon Pearl', player) and has_misery_mire_medallion(state, player)) # sword not required to use medallion for opening in swordless (!) @@ -1084,7 +1087,7 @@ def standard_rules(world, player): set_rule(world.get_entrance('Links House S&Q', player), lambda state: state.can_reach('Sanctuary', 'Region', player)) set_rule(world.get_entrance('Sanctuary S&Q', player), lambda state: state.can_reach('Sanctuary', 'Region', player)) - if world.small_key_shuffle[player] != small_key_shuffle.option_universal: + if world.worlds[player].options.small_key_shuffle != small_key_shuffle.option_universal: set_rule(world.get_location('Hyrule Castle - Boomerang Guard Key Drop', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 1) and can_kill_most_things(state, player, 2)) @@ -1097,7 +1100,7 @@ def standard_rules(world, player): set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), lambda state: state._lttp_has_key('Small Key (Hyrule Castle)', player, 2) and state.has('Big Key (Hyrule Castle)', player) - and (world.enemy_health[player] in ("easy", "default") + and (world.worlds[player].options.enemy_health in ("easy", "default") or can_kill_most_things(state, player, 1))) set_rule(world.get_location('Sewers - Key Rat Key Drop', player), @@ -1195,15 +1198,15 @@ def tr_big_key_chest_keys_needed(state): return 6 # If TR is only accessible from the middle, the big key must be further restricted to prevent softlock potential - if not can_reach_front and not multiworld.small_key_shuffle[player]: + if not can_reach_front and not multiworld.worlds[player].options.small_key_shuffle: # Must not go in the Big Key Chest - only 1 other chest available and 2+ keys required for all other chests forbid_item(multiworld.get_location('Turtle Rock - Big Key Chest', player), 'Big Key (Turtle Rock)', player) if not can_reach_big_chest: # Must not go in the Chain Chomps chest - only 2 other chests available and 3+ keys required for all other chests forbid_item(multiworld.get_location('Turtle Rock - Chain Chomps', player), 'Big Key (Turtle Rock)', player) forbid_item(multiworld.get_location('Turtle Rock - Pokey 2 Key Drop', player), 'Big Key (Turtle Rock)', player) - if multiworld.accessibility[player] == 'full': - if multiworld.big_key_shuffle[player] and can_reach_big_chest: + if multiworld.worlds[player].options.accessibility == 'full': + if multiworld.worlds[player].options.big_key_shuffle and can_reach_big_chest: # Must not go in the dungeon - all 3 available chests (Chomps, Big Chest, Crystaroller) must be keys to access laser bridge, and the big key is required first for location in ['Turtle Rock - Chain Chomps', 'Turtle Rock - Compass Chest', 'Turtle Rock - Pokey 1 Key Drop', 'Turtle Rock - Pokey 2 Key Drop', @@ -1216,9 +1219,9 @@ def tr_big_key_chest_keys_needed(state): location.place_locked_item(item) toss_junk_item(multiworld, player) - if multiworld.accessibility[player] != 'full': + if multiworld.worlds[player].options.accessibility != 'full': set_always_allow(multiworld.get_location('Turtle Rock - Big Key Chest', player), lambda state, item: item.name == 'Small Key (Turtle Rock)' and item.player == player - and state.can_reach(state.multiworld.get_region('Turtle Rock (Second Section)', player))) + and state.can_reach(state.multiworld.get_region('Turtle Rock (Second Section)', player))) def set_big_bomb_rules(world, player): @@ -1683,7 +1686,7 @@ def is_link(region): def get_rule_to_add(region, location = None, connecting_entrance = None): # In OWG, a location can potentially be superbunny-mirror accessible or # bunny revival accessible. - if world.glitches_required[player] in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic']: + if world.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic']: if region.name == 'Swamp Palace (Entrance)': # Need to 0hp revive - not in logic return lambda state: state.has('Moon Pearl', player) if region.name == 'Tower of Hera (Bottom)': # Need to hit the crystal switch @@ -1723,7 +1726,7 @@ def get_rule_to_add(region, location = None, connecting_entrance = None): seen.add(new_region) if not is_link(new_region): # For glitch rulesets, establish superbunny and revival rules. - if world.glitches_required[player] in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] and entrance.name not in OverworldGlitchRules.get_invalid_bunny_revival_dungeons(): + if world.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] and entrance.name not in OverworldGlitchRules.get_invalid_bunny_revival_dungeons(): if region.name in OverworldGlitchRules.get_sword_required_superbunny_mirror_regions(): possible_options.append(lambda state: path_to_access_rule(new_path, entrance) and state.has('Magic Mirror', player) and has_sword(state, player)) elif (region.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_regions() @@ -1760,7 +1763,7 @@ def get_rule_to_add(region, location = None, connecting_entrance = None): # Add requirements for all locations that are actually in the dark world, except those available to the bunny, including dungeon revival for entrance in world.get_entrances(player): if is_bunny(entrance.connected_region): - if world.glitches_required[player] in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] : + if world.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] : if entrance.connected_region.type == LTTPRegionType.Dungeon: if entrance.parent_region.type != LTTPRegionType.Dungeon and entrance.connected_region.name in OverworldGlitchRules.get_invalid_bunny_revival_dungeons(): add_rule(entrance, get_rule_to_add(entrance.connected_region, None, entrance)) @@ -1768,7 +1771,7 @@ def get_rule_to_add(region, location = None, connecting_entrance = None): if entrance.connected_region.name == 'Turtle Rock (Entrance)': add_rule(world.get_entrance('Turtle Rock Entrance Gap', player), get_rule_to_add(entrance.connected_region, None, entrance)) for location in entrance.connected_region.locations: - if world.glitches_required[player] in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] and entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances(): + if world.worlds[player].options.glitches_required in ['minor_glitches', 'overworld_glitches', 'hybrid_major_glitches', 'no_logic'] and entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances(): continue if location.name in bunny_accessible_locations: continue diff --git a/worlds/alttp/Shops.py b/worlds/alttp/Shops.py index 055eb2da934b..bb3945f5b05a 100644 --- a/worlds/alttp/Shops.py +++ b/worlds/alttp/Shops.py @@ -168,7 +168,7 @@ def push_shop_inventories(multiworld): for location in shop_slots: item_name = location.item.name # Retro Bow arrows will already have been pushed - if (not multiworld.retro_bow[location.player]) or ((item_name, location.item.player) + if (not multiworld.worlds[location.player].options.retro_bow) or ((item_name, location.item.player) != ("Single Arrow", location.player)): location.shop.push_inventory(location.shop_slot, item_name, round(location.shop_price * get_price_modifier(location.item)), @@ -185,36 +185,36 @@ def push_shop_inventories(multiworld): def create_shops(multiworld, player: int): from .Options import RandomizeShopInventories player_shop_table = shop_table.copy() - if multiworld.include_witch_hut[player]: + if multiworld.worlds[player].options.include_witch_hut: player_shop_table["Potion Shop"] = player_shop_table["Potion Shop"]._replace(locked=False) dynamic_shop_slots = total_dynamic_shop_slots + 3 else: dynamic_shop_slots = total_dynamic_shop_slots - if multiworld.shuffle_capacity_upgrades[player]: + if multiworld.worlds[player].options.shuffle_capacity_upgrades: player_shop_table["Capacity Upgrade"] = player_shop_table["Capacity Upgrade"]._replace(locked=False) - num_slots = min(dynamic_shop_slots, multiworld.shop_item_slots[player]) + num_slots = min(dynamic_shop_slots, multiworld.worlds[player].options.shop_item_slots) single_purchase_slots: List[bool] = [True] * num_slots + [False] * (dynamic_shop_slots - num_slots) multiworld.random.shuffle(single_purchase_slots) - if multiworld.randomize_shop_inventories[player]: + if multiworld.worlds[player].options.randomize_shop_inventories: default_shop_table = [i for l in [shop_generation_types[x] for x in ['arrows', 'bombs', 'potions', 'shields', 'bottle'] if - not multiworld.retro_bow[player] or x != 'arrows'] for i in l] + not multiworld.worlds[player].options.retro_bow or x != 'arrows'] for i in l] new_basic_shop = multiworld.random.sample(default_shop_table, k=3) new_dark_shop = multiworld.random.sample(default_shop_table, k=3) for name, shop in player_shop_table.items(): typ, shop_id, keeper, custom, locked, items, sram_offset = shop if not locked: new_items = multiworld.random.sample(default_shop_table, k=len(items)) - if multiworld.randomize_shop_inventories[player] == RandomizeShopInventories.option_randomize_by_shop_type: + if multiworld.worlds[player].options.randomize_shop_inventories == RandomizeShopInventories.option_randomize_by_shop_type: if items == _basic_shop_defaults: new_items = new_basic_shop elif items == _dark_world_shop_defaults: new_items = new_dark_shop keeper = multiworld.random.choice([0xA0, 0xC1, 0xFF]) player_shop_table[name] = ShopData(typ, shop_id, keeper, custom, locked, new_items, sram_offset) - if multiworld.mode[player] == "inverted": + if multiworld.worlds[player].options.mode == "inverted": # make sure that blue potion is available in inverted, special case locked = None; lock when done. player_shop_table["Dark Lake Hylia Shop"] = \ player_shop_table["Dark Lake Hylia Shop"]._replace(items=_inverted_hylia_shop_defaults, locked=None) @@ -237,7 +237,7 @@ def create_shops(multiworld, player: int): add_rule(loc, lambda state, spot=loc: shop_price_rules(state, player, spot)) loc.shop = shop loc.shop_slot = index - if ((not (multiworld.shuffle_capacity_upgrades[player] and type == ShopType.UpgradeShop)) + if ((not (multiworld.worlds[player].options.shuffle_capacity_upgrades and type == ShopType.UpgradeShop)) and not single_purchase_slots.pop()): loc.shop_slot_disabled = True loc.locked = True @@ -309,18 +309,18 @@ def set_up_shops(multiworld, player: int): from .Options import small_key_shuffle # TODO: move hard+ mode changes for shields here, utilizing the new shops - if multiworld.retro_bow[player]: + if multiworld.worlds[player].options.retro_bow: rss = multiworld.get_region('Red Shield Shop', player).shop replacement_items = [['Red Potion', 150], ['Green Potion', 75], ['Blue Potion', 200], ['Bombs (10)', 50], ['Blue Shield', 50], ['Small Heart', 10]] # Can't just replace the single arrow with 10 arrows as retro doesn't need them. - if multiworld.small_key_shuffle[player] == small_key_shuffle.option_universal: + if multiworld.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: replacement_items.append(['Small Key (Universal)', 100]) replacement_item = multiworld.random.choice(replacement_items) rss.add_inventory(2, 'Single Arrow', 80, 1, replacement_item[0], replacement_item[1]) rss.locked = True - if multiworld.small_key_shuffle[player] == small_key_shuffle.option_universal or multiworld.retro_bow[player]: + if multiworld.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal or multiworld.worlds[player].options.retro_bow: for shop in multiworld.random.sample([s for s in multiworld.shops if s.custom and not s.locked and s.type == ShopType.Shop and s.region.player == player], 5): @@ -328,19 +328,19 @@ def set_up_shops(multiworld, player: int): slots = [0, 1, 2] multiworld.random.shuffle(slots) slots = iter(slots) - if multiworld.small_key_shuffle[player] == small_key_shuffle.option_universal: + if multiworld.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: shop.add_inventory(next(slots), 'Small Key (Universal)', 100) - if multiworld.retro_bow[player]: + if multiworld.worlds[player].options.retro_bow: shop.push_inventory(next(slots), 'Single Arrow', 80) - if multiworld.shuffle_capacity_upgrades[player]: + if multiworld.worlds[player].options.shuffle_capacity_upgrades: for shop in multiworld.shops: if shop.type == ShopType.UpgradeShop and shop.region.player == player and \ shop.region.name == "Capacity Upgrade": shop.clear_inventory() - if (multiworld.shuffle_shop_inventories[player] or multiworld.randomize_shop_prices[player] - or multiworld.randomize_cost_types[player]): + if (multiworld.worlds[player].options.shuffle_shop_inventories or multiworld.worlds[player].options.randomize_shop_prices + or multiworld.worlds[player].options.randomize_cost_types): shops = [] total_inventory = [] for shop in multiworld.shops: @@ -352,7 +352,7 @@ def set_up_shops(multiworld, player: int): for item in total_inventory: item["price_type"], item["price"] = get_price(multiworld, item, player) - if multiworld.shuffle_shop_inventories[player]: + if multiworld.worlds[player].options.shuffle_shop_inventories: multiworld.random.shuffle(total_inventory) i = 0 @@ -434,39 +434,39 @@ def get_price(multiworld, item, player: int, price_type=None): price_types = [price_type] else: price_types = [ShopPriceType.Rupees] # included as a chance to not change price - if multiworld.randomize_cost_types[player]: + if multiworld.worlds[player].options.randomize_cost_types: price_types += [ ShopPriceType.Hearts, ShopPriceType.Bombs, ShopPriceType.Magic, ] - if multiworld.small_key_shuffle[player] == small_key_shuffle.option_universal: + if multiworld.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: if item and item["item"] == "Small Key (Universal)": price_types = [ShopPriceType.Rupees, ShopPriceType.Magic] # no logical requirements for repeatable keys else: price_types.append(ShopPriceType.Keys) - if multiworld.retro_bow[player]: + if multiworld.worlds[player].options.retro_bow: if item and item["item"] == "Single Arrow": price_types = [ShopPriceType.Rupees, ShopPriceType.Magic] # no logical requirements for arrows else: price_types.append(ShopPriceType.Arrows) - diff = multiworld.item_pool[player].value + diff = multiworld.worlds[player].options.item_pool.value if item: # This is for a shop's regular inventory, the item is already determined, and we will decide the price here price = item["price"] - if multiworld.randomize_shop_prices[player]: + if multiworld.worlds[player].options.randomize_shop_prices: adjust = 2 if price < 100 else 5 - price = int((price / adjust) * (0.5 + multiworld.per_slot_randoms[player].random() * 1.5)) * adjust - multiworld.per_slot_randoms[player].shuffle(price_types) + price = int((price / adjust) * (0.5 + multiworld.worlds[player].random.random() * 1.5)) * adjust + multiworld.worlds[player].random.shuffle(price_types) for p_type in price_types: if any(x in item['item'] for x in price_blacklist[p_type]): continue return p_type, price_chart[p_type](price, diff) else: # This is an AP location and the price will be adjusted after an item is shuffled into it - p_type = multiworld.per_slot_randoms[player].choice(price_types) - return p_type, price_chart[p_type](min(int(multiworld.per_slot_randoms[player].randint(8, 56) - * multiworld.shop_price_modifier[player] / 100) * 5, 9999), diff) + p_type = multiworld.worlds[player].random.choice(price_types) + return p_type, price_chart[p_type](min(int(multiworld.worlds[player].random.randint(8, 56) + * multiworld.worlds[player].options.shop_price_modifier / 100) * 5, 9999), diff) def shop_price_rules(state: CollectionState, player: int, location: ALttPLocation): diff --git a/worlds/alttp/StateHelpers.py b/worlds/alttp/StateHelpers.py index 8661632b836e..6ac3c4b8f8a1 100644 --- a/worlds/alttp/StateHelpers.py +++ b/worlds/alttp/StateHelpers.py @@ -6,7 +6,7 @@ def is_not_bunny(state: CollectionState, region: LTTPRegion, player: int) -> boo if state.has('Moon Pearl', player): return True - return region.is_light_world if state.multiworld.mode[player] != 'inverted' else region.is_dark_world + return region.is_light_world if state.multiworld.worlds[player].options.mode != 'inverted' else region.is_dark_world def can_bomb_clip(state: CollectionState, region: LTTPRegion, player: int) -> bool: @@ -24,7 +24,7 @@ def can_buy(state: CollectionState, item: str, player: int) -> bool: def can_shoot_arrows(state: CollectionState, player: int, count: int = 0) -> bool: - if state.multiworld.retro_bow[player]: + if state.multiworld.worlds[player].options.retro_bow: return (state.has('Bow', player) or state.has('Silver Bow', player)) and can_buy(state, 'Single Arrow', player) return (state.has('Bow', player) or state.has('Silver Bow', player)) and can_hold_arrows(state, player, count) @@ -74,9 +74,9 @@ def can_extend_magic(state: CollectionState, player: int, smallmagic: int = 16, elif state.has('Magic Upgrade (1/2)', player): basemagic = 16 if can_buy_unlimited(state, 'Green Potion', player) or can_buy_unlimited(state, 'Blue Potion', player): - if state.multiworld.item_functionality[player] == 'hard' and not fullrefill: + if state.multiworld.worlds[player].options.item_functionality == 'hard' and not fullrefill: basemagic = basemagic + int(basemagic * 0.5 * bottle_count(state, player)) - elif state.multiworld.item_functionality[player] == 'expert' and not fullrefill: + elif state.multiworld.worlds[player].options.item_functionality == 'expert' and not fullrefill: basemagic = basemagic + int(basemagic * 0.25 * bottle_count(state, player)) else: basemagic = basemagic + basemagic * bottle_count(state, player) @@ -99,12 +99,12 @@ def can_hold_arrows(state: CollectionState, player: int, quantity: int): def can_use_bombs(state: CollectionState, player: int, quantity: int = 1) -> bool: - bombs = 0 if state.multiworld.bombless_start[player] else 10 + bombs = 0 if state.multiworld.worlds[player].options.bombless_start else 10 bombs += ((state.count("Bomb Upgrade (+5)", player) * 5) + (state.count("Bomb Upgrade (+10)", player) * 10) + (state.count("Bomb Upgrade (50)", player) * 50)) # Bomb Upgrade (+5) beyond the 6th gives +10 bombs += max(0, ((state.count("Bomb Upgrade (+5)", player) - 6) * 10)) - if (not state.multiworld.shuffle_capacity_upgrades[player]) and state.has("Capacity Upgrade Shop", player): + if (not state.multiworld.worlds[player].options.shuffle_capacity_upgrades) and state.has("Capacity Upgrade Shop", player): bombs += 40 return bombs >= min(quantity, 50) @@ -120,7 +120,7 @@ def can_activate_crystal_switch(state: CollectionState, player: int) -> bool: def can_kill_most_things(state: CollectionState, player: int, enemies: int = 5) -> bool: - if state.multiworld.enemy_shuffle[player]: + if state.multiworld.worlds[player].options.enemy_shuffle: # I don't fully understand Enemizer's logic for placing enemies in spots where they need to be killable, if any. # Just go with maximal requirements for now. return (has_melee_weapon(state, player) @@ -135,7 +135,7 @@ def can_kill_most_things(state: CollectionState, player: int, enemies: int = 5) or (state.has('Cane of Byrna', player) and (enemies < 6 or can_extend_magic(state, player))) or can_shoot_arrows(state, player) or state.has('Fire Rod', player) - or (state.multiworld.enemy_health[player] in ("easy", "default") + or (state.multiworld.worlds[player].options.enemy_health in ("easy", "default") and can_use_bombs(state, player, enemies * 4))) @@ -152,7 +152,7 @@ def can_get_good_bee(state: CollectionState, player: int) -> bool: def can_retrieve_tablet(state: CollectionState, player: int) -> bool: return state.has('Book of Mudora', player) and (has_beam_sword(state, player) or - (state.multiworld.swordless[player] and + (state.multiworld.worlds[player].options.swordless and state.has("Hammer", player))) @@ -179,7 +179,7 @@ def has_fire_source(state: CollectionState, player: int) -> bool: def can_melt_things(state: CollectionState, player: int) -> bool: return state.has('Fire Rod', player) or \ (state.has('Bombos', player) and - (state.multiworld.swordless[player] or + (state.multiworld.worlds[player].options.swordless or has_sword(state, player))) @@ -192,19 +192,19 @@ def has_turtle_rock_medallion(state: CollectionState, player: int) -> bool: def can_boots_clip_lw(state: CollectionState, player: int) -> bool: - if state.multiworld.mode[player] == 'inverted': + if state.multiworld.worlds[player].options.mode == 'inverted': return state.has('Pegasus Boots', player) and state.has('Moon Pearl', player) return state.has('Pegasus Boots', player) def can_boots_clip_dw(state: CollectionState, player: int) -> bool: - if state.multiworld.mode[player] != 'inverted': + if state.multiworld.worlds[player].options.mode != 'inverted': return state.has('Pegasus Boots', player) and state.has('Moon Pearl', player) return state.has('Pegasus Boots', player) def can_get_glitched_speed_dw(state: CollectionState, player: int) -> bool: rules = [state.has('Pegasus Boots', player), any([state.has('Hookshot', player), has_sword(state, player)])] - if state.multiworld.mode[player] != 'inverted': + if state.multiworld.worlds[player].options.mode != 'inverted': rules.append(state.has('Moon Pearl', player)) return all(rules) diff --git a/worlds/alttp/UnderworldGlitchRules.py b/worlds/alttp/UnderworldGlitchRules.py index 2b18f67ed9b7..25511f320d4d 100644 --- a/worlds/alttp/UnderworldGlitchRules.py +++ b/worlds/alttp/UnderworldGlitchRules.py @@ -59,7 +59,7 @@ def dungeon_reentry_rules(world, player, clip: LTTPEntrance, dungeon_region: str # since the clip links directly to the exterior region. -def underworld_glitches_rules(world, player): +def underworld_glitches_rules(world, player): # Ice Palace Entrance Clip # This is the easiest one since it's a simple internal clip. # Need to also add melting to freezor chest since it's otherwise assumed. @@ -88,12 +88,12 @@ def underworld_glitches_rules(world, player): # We need to be able to s+q to old man, then go to either Mire or Hera at either Hera or GT. # First we require a certain type of entrance shuffle, then build the rule from its pieces. if not world.worlds[player].swamp_patch_required: - if world.entrance_shuffle[player] in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: + if world.worlds[player].options.entrance_shuffle in ['vanilla', 'dungeons_simple', 'dungeons_full', 'dungeons_crossed']: rule_map = { 'Misery Mire (Entrance)': (lambda state: True), 'Tower of Hera (Bottom)': (lambda state: state.can_reach('Tower of Hera Big Key Door', 'Entrance', player)) } - inverted = world.mode[player] == 'inverted' + inverted = world.worlds[player].options.mode == 'inverted' hera_rule = lambda state: (state.has('Moon Pearl', player) or not inverted) and \ rule_map.get(world.get_entrance('Tower of Hera', player).connected_region.name, lambda state: False)(state) gt_rule = lambda state: (state.has('Moon Pearl', player) or inverted) and \ diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index 4a026f109b61..1934138afa50 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -313,74 +313,62 @@ def stage_assert_generate(cls, multiworld: MultiWorld): break def generate_early(self): - # write old options - import dataclasses - is_first = self.player == min(self.multiworld.get_game_players(self.game)) - - for field in dataclasses.fields(self.options_dataclass): - if is_first: - setattr(self.multiworld, field.name, {}) - getattr(self.multiworld, field.name)[self.player] = getattr(self.options, field.name) - # end of old options re-establisher - - player = self.player multiworld = self.multiworld - self.fix_trock_doors = (multiworld.entrance_shuffle[player] != 'vanilla' - or multiworld.mode[player] == 'inverted') - self.fix_skullwoods_exit = multiworld.entrance_shuffle[player] not in ['vanilla', 'simple', 'restricted', - 'dungeons_simple'] - self.fix_palaceofdarkness_exit = multiworld.entrance_shuffle[player] not in ['dungeons_simple', 'vanilla', - 'simple', 'restricted'] - self.fix_trock_exit = multiworld.entrance_shuffle[player] not in ['vanilla', 'simple', 'restricted', - 'dungeons_simple'] + self.fix_trock_doors = (self.options.entrance_shuffle != 'vanilla' or self.options.mode == 'inverted') + self.fix_skullwoods_exit = self.options.entrance_shuffle not in ['vanilla', 'simple', 'restricted', 'dungeons_simple'] + self.fix_palaceofdarkness_exit = self.options.entrance_shuffle not in ['dungeons_simple', 'vanilla', 'simple', 'restricted'] + self.fix_trock_exit = self.options.entrance_shuffle not in ['vanilla', 'simple', 'restricted', 'dungeons_simple'] # fairy bottle fills bottle_options = [ "Bottle (Red Potion)", "Bottle (Green Potion)", "Bottle (Blue Potion)", "Bottle (Bee)", "Bottle (Good Bee)" ] - if multiworld.item_pool[player] not in ["hard", "expert"]: + if self.options.item_pool not in ["hard", "expert"]: bottle_options.append("Bottle (Fairy)") self.waterfall_fairy_bottle_fill = self.random.choice(bottle_options) self.pyramid_fairy_bottle_fill = self.random.choice(bottle_options) - if multiworld.mode[player] == 'standard': - if multiworld.small_key_shuffle[player]: - if (multiworld.small_key_shuffle[player] not in - (small_key_shuffle.option_universal, small_key_shuffle.option_own_dungeons, - small_key_shuffle.option_start_with)): + if self.options.mode == 'standard': + if self.options.small_key_shuffle: + if (self.options.small_key_shuffle not in + (small_key_shuffle.option_universal, small_key_shuffle.option_own_dungeons, + small_key_shuffle.option_start_with)): self.multiworld.local_early_items[self.player]["Small Key (Hyrule Castle)"] = 1 - self.multiworld.local_items[self.player].value.add("Small Key (Hyrule Castle)") - self.multiworld.non_local_items[self.player].value.discard("Small Key (Hyrule Castle)") - if multiworld.big_key_shuffle[player]: - self.multiworld.local_items[self.player].value.add("Big Key (Hyrule Castle)") - self.multiworld.non_local_items[self.player].value.discard("Big Key (Hyrule Castle)") + self.options.local_items.value.add("Small Key (Hyrule Castle)") + self.options.non_local_items.value.discard("Small Key (Hyrule Castle)") + if self.options.big_key_shuffle: + self.options.local_items.value.add("Big Key (Hyrule Castle)") + self.options.non_local_items.value.discard("Big Key (Hyrule Castle)") # system for sharing ER layouts self.er_seed = str(multiworld.random.randint(0, 2 ** 64)) - if multiworld.entrance_shuffle[player] != "vanilla" and multiworld.entrance_shuffle_seed[player] != "random": - shuffle = multiworld.entrance_shuffle[player].current_key + if self.options.entrance_shuffle != "vanilla" and self.options.entrance_shuffle_seed != "random": + shuffle = self.options.entrance_shuffle.current_key if shuffle == "vanilla": self.er_seed = "vanilla" - elif (not multiworld.entrance_shuffle_seed[player].value.isdigit()) or multiworld.is_race: + elif (not self.options.entrance_shuffle_seed.value.isdigit()) or multiworld.is_race: self.er_seed = get_same_seed(multiworld, ( - shuffle, multiworld.entrance_shuffle_seed[player].value, multiworld.retro_caves[player], multiworld.mode[player], - multiworld.glitches_required[player])) + shuffle, self.options.entrance_shuffle_seed.value, + self.options.retro_caves, + self.options.mode, + self.options.glitches_required + )) else: # not a race or group seed, use set seed as is. - self.er_seed = int(multiworld.entrance_shuffle_seed[player].value) - elif multiworld.entrance_shuffle[player] == "vanilla": + self.er_seed = int(self.options.entrance_shuffle_seed.value) + elif self.options.entrance_shuffle == "vanilla": self.er_seed = "vanilla" for dungeon_item in ["small_key_shuffle", "big_key_shuffle", "compass_shuffle", "map_shuffle"]: - option = getattr(multiworld, dungeon_item)[player] + option = getattr(self.options, dungeon_item) if option == "own_world": - multiworld.local_items[player].value |= self.item_name_groups[option.item_name_group] + self.options.local_items.value |= self.item_name_groups[option.item_name_group] elif option == "different_world": - multiworld.non_local_items[player].value |= self.item_name_groups[option.item_name_group] - if multiworld.mode[player] == "standard": - multiworld.non_local_items[player].value -= {"Small Key (Hyrule Castle)"} + self.options.non_local_items.value |= self.item_name_groups[option.item_name_group] + if self.options.mode == "standard": + self.options.non_local_items.value -= {"Small Key (Hyrule Castle)"} elif option.in_dungeon: self.dungeon_local_item_names |= self.item_name_groups[option.item_name_group] if option == "original_dungeon": @@ -388,15 +376,15 @@ def generate_early(self): else: self.options.local_items.value |= self.dungeon_local_item_names - self.difficulty_requirements = difficulties[multiworld.item_pool[player].current_key] + self.difficulty_requirements = difficulties[self.options.item_pool.current_key] # enforce pre-defined local items. - if multiworld.goal[player] in ["local_triforce_hunt", "local_ganon_triforce_hunt"]: - multiworld.local_items[player].value.add('Triforce Piece') + if self.options.goal in ["local_triforce_hunt", "local_ganon_triforce_hunt"]: + self.options.local_items.value.add('Triforce Piece') # Not possible to place crystals outside boss prizes yet (might as well make it consistent with pendants too). - multiworld.non_local_items[player].value -= item_name_groups['Pendants'] - multiworld.non_local_items[player].value -= item_name_groups['Crystals'] + self.options.non_local_items.value -= item_name_groups['Pendants'] + self.options.non_local_items.value -= item_name_groups['Crystals'] create_dungeons = create_dungeons @@ -404,15 +392,15 @@ def create_regions(self): player = self.player multiworld = self.multiworld - if multiworld.mode[player] != 'inverted': + if self.options.mode != 'inverted': create_regions(multiworld, player) else: create_inverted_regions(multiworld, player) create_shops(multiworld, player) self.create_dungeons() - if (multiworld.glitches_required[player] not in ["no_glitches", "minor_glitches"] and - multiworld.entrance_shuffle[player] in [ + if (self.options.glitches_required not in ["no_glitches", "minor_glitches"] and + self.options.entrance_shuffle in [ "vanilla", "dungeons_simple", "dungeons_full", "simple", "restricted", "full"]): self.fix_fake_world = False @@ -420,7 +408,7 @@ def create_regions(self): old_random = multiworld.random multiworld.random = random.Random(self.er_seed) - if multiworld.mode[player] != 'inverted': + if self.options.mode != 'inverted': link_entrances(multiworld, player) mark_light_world_regions(multiworld, player) else: @@ -505,8 +493,9 @@ def collect_item(self, state: CollectionState, item: Item, remove=False): if state.has('Silver Bow', item.player): return elif state.has('Bow', item.player) and (self.difficulty_requirements.progressive_bow_limit >= 2 - or self.multiworld.glitches_required[self.player] == 'no_glitches' - or self.multiworld.swordless[self.player]): # modes where silver bow is always required for ganon + or self.options.glitches_required == 'no_glitches' + or self.options.swordless): + # modes where silver bow is always required for ganon return 'Silver Bow' elif self.difficulty_requirements.progressive_bow_limit >= 1: return 'Bow' @@ -549,9 +538,9 @@ def pre_fill(self): break else: raise FillError('Unable to place dungeon prizes') - if world.mode[player] == 'standard' and world.small_key_shuffle[player] \ - and world.small_key_shuffle[player] != small_key_shuffle.option_universal and \ - world.small_key_shuffle[player] != small_key_shuffle.option_own_dungeons: + if self.options.mode == 'standard' and self.options.small_key_shuffle \ + and self.options.small_key_shuffle != small_key_shuffle.option_universal and \ + self.options.small_key_shuffle != small_key_shuffle.option_own_dungeons: world.local_early_items[player]["Small Key (Hyrule Castle)"] = 1 @classmethod @@ -592,27 +581,27 @@ def generate_output(self, output_directory: str): multiworld.spoiler.hashes[player] = get_hash_string(rom.hash) palettes_options = { - 'dungeon': multiworld.uw_palettes[player], - 'overworld': multiworld.ow_palettes[player], - 'hud': multiworld.hud_palettes[player], - 'sword': multiworld.sword_palettes[player], - 'shield': multiworld.shield_palettes[player], + 'dungeon': self.options.uw_palettes, + 'overworld': self.options.ow_palettes, + 'hud': self.options.hud_palettes, + 'sword': self.options.sword_palettes, + 'shield': self.options.shield_palettes, # 'link': world.link_palettes[player] } palettes_options = {key: option.current_key for key, option in palettes_options.items()} - apply_rom_settings(rom, multiworld.heartbeep[player].current_key, - multiworld.heartcolor[player].current_key, - multiworld.quickswap[player], - multiworld.menuspeed[player].current_key, - multiworld.music[player], + apply_rom_settings(rom, self.options.heartbeep.current_key, + self.options.heartcolor.current_key, + self.options.quickswap, + self.options.menuspeed.current_key, + self.options.music, multiworld.sprite[player], None, palettes_options, multiworld, player, True, - reduceflashing=multiworld.reduceflashing[player] or multiworld.is_race, - triforcehud=multiworld.triforcehud[player].current_key, - deathlink=multiworld.death_link[player], - allowcollect=multiworld.allow_collect[player]) + reduceflashing=self.options.reduceflashing or multiworld.is_race, + triforcehud=self.options.triforcehud.current_key, + deathlink=self.options.death_link, + allowcollect=self.options.allow_collect) rompath = os.path.join(output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}.sfc") rom.write_to_file(rompath) @@ -629,7 +618,7 @@ def generate_output(self, output_directory: str): @classmethod def stage_extend_hint_information(cls, world, hint_data: typing.Dict[int, typing.Dict[int, str]]): er_hint_data = {player: {} for player in world.get_game_players("A Link to the Past") if - world.entrance_shuffle[player] != "vanilla" or world.retro_caves[player]} + world.worlds[player].options.entrance_shuffle != "vanilla" or world.worlds[player].options.retro_caves} for region in world.regions: if region.player in er_hint_data and region.locations: @@ -745,7 +734,7 @@ def write_spoiler(self, spoiler_handle: typing.TextIO) -> None: f" {self.pyramid_fairy_bottle_fill}") spoiler_handle.write(f"\nWaterfall Fairy ({player_name}):" f" {self.waterfall_fairy_bottle_fill}") - if self.multiworld.boss_shuffle[self.player] != "none": + if self.options.boss_shuffle != "none": def create_boss_map() -> typing.Dict: boss_map = { "Eastern Palace": self.dungeons["Eastern Palace"].boss.name, @@ -762,7 +751,7 @@ def create_boss_map() -> typing.Dict: "Ganons Tower": "Agahnim 2", "Ganon": "Ganon" } - if self.multiworld.mode[self.player] != 'inverted': + if self.options.mode != 'inverted': boss_map.update({ "Ganons Tower Basement": self.dungeons["Ganons Tower"].bosses["bottom"].name, @@ -847,7 +836,7 @@ def fill_slot_data(self): "triforce_pieces_available", "triforce_pieces_extra", ] - slot_data = {option_name: getattr(self.multiworld, option_name)[self.player].value for option_name in slot_options} + slot_data = {option_name: getattr(self.options, option_name).value for option_name in slot_options} slot_data.update({ 'mm_medalion': self.required_medallions[0], @@ -868,8 +857,8 @@ def get_same_seed(world, seed_def: tuple) -> str: class ALttPLogic(LogicMixin): def _lttp_has_key(self, item, player, count: int = 1): - if self.multiworld.glitches_required[player] == 'no_logic': + if self.multiworld.worlds[player].options.glitches_required == 'no_logic': return True - if self.multiworld.small_key_shuffle[player] == small_key_shuffle.option_universal: + if self.multiworld.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: return can_buy_unlimited(self, 'Small Key (Universal)', player) return self.prog_items[player][item] >= count diff --git a/worlds/alttp/test/dungeons/TestDungeon.py b/worlds/alttp/test/dungeons/TestDungeon.py index 5ab1b23065f2..c06955a12269 100644 --- a/worlds/alttp/test/dungeons/TestDungeon.py +++ b/worlds/alttp/test/dungeons/TestDungeon.py @@ -14,8 +14,8 @@ def setUp(self): self.starting_regions = [] # Where to start exploring self.remove_exits = [] # Block dungeon exits self.multiworld.worlds[1].difficulty_requirements = difficulties['normal'] - self.multiworld.bombless_start[1].value = True - self.multiworld.shuffle_capacity_upgrades[1].value = 2 + self.multiworld.worlds[1].options.bombless_start.value = True + self.multiworld.worlds[1].options.shuffle_capacity_upgrades.value = 2 create_regions(self.multiworld, 1) self.multiworld.worlds[1].create_dungeons() create_shops(self.multiworld, 1) diff --git a/worlds/alttp/test/inverted/TestInverted.py b/worlds/alttp/test/inverted/TestInverted.py index a0a654991b43..3c86b6ba0a78 100644 --- a/worlds/alttp/test/inverted/TestInverted.py +++ b/worlds/alttp/test/inverted/TestInverted.py @@ -14,9 +14,9 @@ class TestInverted(TestBase, LTTPTestBase): def setUp(self): self.world_setup() self.multiworld.worlds[1].difficulty_requirements = difficulties['normal'] - self.multiworld.mode[1].value = 2 - self.multiworld.bombless_start[1].value = True - self.multiworld.shuffle_capacity_upgrades[1].value = 2 + self.multiworld.worlds[1].options.mode.value = 2 + self.multiworld.worlds[1].options.bombless_start.value = True + self.multiworld.worlds[1].options.shuffle_capacity_upgrades.value = 2 create_inverted_regions(self.multiworld, 1) self.world.create_dungeons() create_shops(self.multiworld, 1) diff --git a/worlds/alttp/test/inverted/TestInvertedBombRules.py b/worlds/alttp/test/inverted/TestInvertedBombRules.py index a33beca7a9f9..ab73d91108a1 100644 --- a/worlds/alttp/test/inverted/TestInvertedBombRules.py +++ b/worlds/alttp/test/inverted/TestInvertedBombRules.py @@ -12,7 +12,7 @@ class TestInvertedBombRules(LTTPTestBase): def setUp(self): self.world_setup() self.multiworld.worlds[1].difficulty_requirements = difficulties['normal'] - self.multiworld.mode[1].value = 2 + self.multiworld.worlds[1].options.mode.value = 2 create_inverted_regions(self.multiworld, 1) self.multiworld.worlds[1].create_dungeons() diff --git a/worlds/alttp/test/inverted_minor_glitches/TestInvertedMinor.py b/worlds/alttp/test/inverted_minor_glitches/TestInvertedMinor.py index bf25c5c9a164..972b617a29c6 100644 --- a/worlds/alttp/test/inverted_minor_glitches/TestInvertedMinor.py +++ b/worlds/alttp/test/inverted_minor_glitches/TestInvertedMinor.py @@ -14,10 +14,10 @@ class TestInvertedMinor(TestBase, LTTPTestBase): def setUp(self): self.world_setup() - self.multiworld.mode[1].value = 2 - self.multiworld.glitches_required[1] = GlitchesRequired.from_any("minor_glitches") - self.multiworld.bombless_start[1].value = True - self.multiworld.shuffle_capacity_upgrades[1].value = 2 + self.multiworld.worlds[1].options.mode.value = 2 + self.multiworld.worlds[1].options.glitches_required = GlitchesRequired.from_any("minor_glitches") + self.multiworld.worlds[1].options.bombless_start.value = True + self.multiworld.worlds[1].options.shuffle_capacity_upgrades.value = 2 self.multiworld.worlds[1].difficulty_requirements = difficulties['normal'] create_inverted_regions(self.multiworld, 1) self.world.create_dungeons() diff --git a/worlds/alttp/test/inverted_owg/TestInvertedOWG.py b/worlds/alttp/test/inverted_owg/TestInvertedOWG.py index 1de22b95e593..4be51f629809 100644 --- a/worlds/alttp/test/inverted_owg/TestInvertedOWG.py +++ b/worlds/alttp/test/inverted_owg/TestInvertedOWG.py @@ -14,10 +14,10 @@ class TestInvertedOWG(TestBase, LTTPTestBase): def setUp(self): self.world_setup() - self.multiworld.glitches_required[1] = GlitchesRequired.from_any("overworld_glitches") - self.multiworld.mode[1].value = 2 - self.multiworld.bombless_start[1].value = True - self.multiworld.shuffle_capacity_upgrades[1].value = 2 + self.multiworld.worlds[1].options.glitches_required = GlitchesRequired.from_any("overworld_glitches") + self.multiworld.worlds[1].options.mode.value = 2 + self.multiworld.worlds[1].options.bombless_start.value = True + self.multiworld.worlds[1].options.shuffle_capacity_upgrades.value = 2 self.multiworld.worlds[1].difficulty_requirements = difficulties['normal'] create_inverted_regions(self.multiworld, 1) self.world.create_dungeons() diff --git a/worlds/alttp/test/minor_glitches/TestMinor.py b/worlds/alttp/test/minor_glitches/TestMinor.py index 7663c20a2943..d5ffe8cac570 100644 --- a/worlds/alttp/test/minor_glitches/TestMinor.py +++ b/worlds/alttp/test/minor_glitches/TestMinor.py @@ -11,9 +11,9 @@ class TestMinor(TestBase, LTTPTestBase): def setUp(self): self.world_setup() - self.multiworld.glitches_required[1] = GlitchesRequired.from_any("minor_glitches") - self.multiworld.bombless_start[1].value = True - self.multiworld.shuffle_capacity_upgrades[1].value = 2 + self.multiworld.worlds[1].options.glitches_required = GlitchesRequired.from_any("minor_glitches") + self.multiworld.worlds[1].options.bombless_start.value = True + self.multiworld.worlds[1].options.shuffle_capacity_upgrades.value = 2 self.multiworld.worlds[1].difficulty_requirements = difficulties['normal'] self.world.er_seed = 0 self.world.create_regions() diff --git a/worlds/alttp/test/options/TestOpenPyramid.py b/worlds/alttp/test/options/TestOpenPyramid.py index c7912c43d72b..5769b337fb99 100644 --- a/worlds/alttp/test/options/TestOpenPyramid.py +++ b/worlds/alttp/test/options/TestOpenPyramid.py @@ -23,7 +23,7 @@ class GoalPyramidTest(PyramidTestBase): } def testCrystalsGoalAccess(self): - self.multiworld.goal[1].value = 1 # crystals + self.multiworld.worlds[1].options.goal.value = 1 # crystals self.assertFalse(self.can_reach_entrance("Pyramid Hole")) self.collect_by_name(["Hammer", "Progressive Glove", "Moon Pearl"]) self.assertTrue(self.can_reach_entrance("Pyramid Hole")) diff --git a/worlds/alttp/test/owg/TestVanillaOWG.py b/worlds/alttp/test/owg/TestVanillaOWG.py index e51970bc50b6..6b6db1454b96 100644 --- a/worlds/alttp/test/owg/TestVanillaOWG.py +++ b/worlds/alttp/test/owg/TestVanillaOWG.py @@ -12,9 +12,9 @@ class TestVanillaOWG(TestBase, LTTPTestBase): def setUp(self): self.world_setup() self.multiworld.worlds[1].difficulty_requirements = difficulties['normal'] - self.multiworld.glitches_required[1] = GlitchesRequired.from_any("overworld_glitches") - self.multiworld.bombless_start[1].value = True - self.multiworld.shuffle_capacity_upgrades[1].value = 2 + self.multiworld.worlds[1].options.glitches_required = GlitchesRequired.from_any("overworld_glitches") + self.multiworld.worlds[1].options.bombless_start.value = True + self.multiworld.worlds[1].options.shuffle_capacity_upgrades.value = 2 self.multiworld.worlds[1].er_seed = 0 self.multiworld.worlds[1].create_regions() self.multiworld.worlds[1].create_items() diff --git a/worlds/alttp/test/vanilla/TestVanilla.py b/worlds/alttp/test/vanilla/TestVanilla.py index 9b5db7b12291..031aec1ff914 100644 --- a/worlds/alttp/test/vanilla/TestVanilla.py +++ b/worlds/alttp/test/vanilla/TestVanilla.py @@ -10,10 +10,10 @@ class TestVanilla(TestBase, LTTPTestBase): def setUp(self): self.world_setup() - self.multiworld.glitches_required[1] = GlitchesRequired.from_any("no_glitches") + self.multiworld.worlds[1].options.glitches_required = GlitchesRequired.from_any("no_glitches") self.multiworld.worlds[1].difficulty_requirements = difficulties['normal'] - self.multiworld.bombless_start[1].value = True - self.multiworld.shuffle_capacity_upgrades[1].value = 2 + self.multiworld.worlds[1].options.bombless_start.value = True + self.multiworld.worlds[1].options.shuffle_capacity_upgrades.value = 2 self.multiworld.worlds[1].er_seed = 0 self.multiworld.worlds[1].create_regions() self.multiworld.worlds[1].create_items() From 5088b02bfee5cf2950fac2cd03982a70abc03cb9 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Sat, 19 Apr 2025 08:42:20 -0500 Subject: [PATCH 0328/1218] Unittests: fix world unittests with unittest module (#4895) --- test/worlds/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/worlds/__init__.py b/test/worlds/__init__.py index cf396111bfd3..4bc017511c66 100644 --- a/test/worlds/__init__.py +++ b/test/worlds/__init__.py @@ -12,7 +12,7 @@ def load_tests(loader, standard_tests, pattern): all_tests = [ test_case for folder in folders if os.path.exists(folder) for test_collection in loader.discover(folder, top_level_dir=file_path) - for test_suite in test_collection + for test_suite in test_collection if isinstance(test_suite, unittest.suite.TestSuite) for test_case in test_suite ] From e090153d932a772ac3da43ee044fe6df117a61d8 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 19 Apr 2025 15:44:55 +0200 Subject: [PATCH 0329/1218] LttP: fix generation if other games are involved (#4901) --- worlds/alttp/Rom.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index f69e6bb955fc..99cc78e2d97d 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -850,9 +850,9 @@ def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool): rom.write_byte(0x155C9, local_random.choice([0x11, 0x16])) # Randomize GT music too with map shuffle # patch entrance/exits/holes - for region in world.regions: + for region in world.get_regions(player): for exit in region.exits: - if exit.target is not None and exit.player == player: + if exit.target is not None: if isinstance(exit.addresses, tuple): offset = exit.target room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2 = exit.addresses From efe2b7c539b56fc0bccae75ea5e79f645ddbc240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sat, 19 Apr 2025 11:55:02 -0400 Subject: [PATCH 0330/1218] Core: Support default value with cache_self1 (#4667) * add cache_self1_default and tests * merge the two decorators * just change the defaults of the wrap lol * add test for default and default --- Utils.py | 2 ++ test/utils/test_caches.py | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/Utils.py b/Utils.py index 202b8da17847..e4e94a45f6df 100644 --- a/Utils.py +++ b/Utils.py @@ -114,6 +114,8 @@ def wrap(self: S, arg: T) -> RetType: cache[arg] = res return res + wrap.__defaults__ = function.__defaults__ + return wrap diff --git a/test/utils/test_caches.py b/test/utils/test_caches.py index fc681611f0cf..b6db75c9601a 100644 --- a/test/utils/test_caches.py +++ b/test/utils/test_caches.py @@ -35,6 +35,19 @@ def func(self, _: Any) -> object: self.assertFalse(o1.func(1) is o1.func(2)) self.assertFalse(o1.func(1) is o2.func(1)) + def test_cache_default(self) -> None: + class Cls: + @cache_self1 + def func(self, _: Any = 1) -> object: + return object() + + o1 = Cls() + o2 = Cls() + self.assertIs(o1.func(), o1.func()) + self.assertIs(o1.func(1), o1.func()) + self.assertIsNot(o1.func(2), o1.func()) + self.assertIsNot(o1.func(), o2.func()) + def test_gc(self) -> None: # verify that we don't keep a global reference import gc From f8579337480a7e92b6b2a53c47e6445a9d4ad410 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Sat, 19 Apr 2025 17:27:03 -0400 Subject: [PATCH 0331/1218] Launcher: Add search box (#4863) * Add fuzzy search box to Launcher. * move func bind to the kv and prefer substring matching (#79) * move the func bind to the kv * prefer substr matching * Remove fuzzy results, rely on substring only. * Use early return instead of else. * Add type hint to filter_clients_by_type. * Activate search on keyboard input. * Clear search box when filtering by type. * Update Launcher.py Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --------- Co-authored-by: Aaron Wagener Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- Launcher.py | 31 +++++++++++++++++++++++++++++-- data/launcher.kv | 32 ++++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/Launcher.py b/Launcher.py index 29bd71764e4c..713c0cd318ce 100644 --- a/Launcher.py +++ b/Launcher.py @@ -230,10 +230,11 @@ def run_gui(path: str, args: Any) -> None: from kivy.properties import ObjectProperty from kivy.core.window import Window from kivy.metrics import dp - from kivymd.uix.button import MDIconButton + from kivymd.uix.button import MDIconButton, MDButton from kivymd.uix.card import MDCard from kivymd.uix.menu import MDDropdownMenu from kivymd.uix.snackbar import MDSnackbar, MDSnackbarText + from kivymd.uix.textfield import MDTextField from kivy.lang.builder import Builder @@ -253,6 +254,7 @@ class Launcher(ThemedApp): navigation: MDGridLayout = ObjectProperty(None) grid: MDGridLayout = ObjectProperty(None) button_layout: ScrollBox = ObjectProperty(None) + search_box: MDTextField = ObjectProperty(None) cards: list[LauncherCard] current_filter: Sequence[str | Type] | None @@ -338,14 +340,29 @@ def _refresh_components(self, type_filter: Sequence[str | Type] | None = None) - scroll_percent = self.button_layout.convert_distance_to_scroll(0, top) self.button_layout.scroll_y = max(0, min(1, scroll_percent[1])) - def filter_clients(self, caller): + def filter_clients_by_type(self, caller: MDButton): self._refresh_components(caller.type) + self.search_box.text = "" + + def filter_clients_by_name(self, caller: MDTextField, name: str) -> None: + if len(name) == 0: + self._refresh_components(self.current_filter) + return + + sub_matches = [ + card for card in self.cards + if name.lower() in card.component.display_name.lower() and card.component.type != Type.HIDDEN + ] + self.button_layout.layout.clear_widgets() + for card in sub_matches: + self.button_layout.layout.add_widget(card) def build(self): self.top_screen = Builder.load_file(Utils.local_path("data/launcher.kv")) self.grid = self.top_screen.ids.grid self.navigation = self.top_screen.ids.navigation self.button_layout = self.top_screen.ids.button_layout + self.search_box = self.top_screen.ids.search_box self.set_colors() self.top_screen.md_bg_color = self.theme_cls.backgroundColor @@ -353,6 +370,7 @@ def build(self): refresh_components = self._refresh_components Window.bind(on_drop_file=self._on_drop_file) + Window.bind(on_keyboard=self._on_keyboard) for component in components: self.cards.append(self.build_card(component)) @@ -389,6 +407,15 @@ def _on_drop_file(self, window: Window, filename: bytes, x: int, y: int) -> None else: logging.warning(f"unable to identify component for {file}") + def _on_keyboard(self, window: Window, key: int, scancode: int, codepoint: str, modifier: list[str]): + # Activate search as soon as we start typing, no matter if we are focused on the search box or not. + # Focus first, then capture the first character we type, otherwise it gets swallowed and lost. + # Limit text input to ASCII non-control characters (space bar to tilde). + if not self.search_box.focus: + self.search_box.focus = True + if key in range(32, 126): + self.search_box.text += codepoint + def _stop(self, *largs): # ran into what appears to be https://groups.google.com/g/kivy-users/c/saWDLoYCSZ4 with PyCharm. # Closing the window explicitly cleans it up. diff --git a/data/launcher.kv b/data/launcher.kv index 8c6a8288e485..1cb4e84ab519 100644 --- a/data/launcher.kv +++ b/data/launcher.kv @@ -80,7 +80,7 @@ MDFloatLayout: id: all style: "text" type: (Type.CLIENT, Type.TOOL, Type.ADJUSTER, Type.MISC) - on_release: app.filter_clients(self) + on_release: app.filter_clients_by_type(self) MDButtonIcon: icon: "asterisk" @@ -90,7 +90,7 @@ MDFloatLayout: id: client style: "text" type: (Type.CLIENT, ) - on_release: app.filter_clients(self) + on_release: app.filter_clients_by_type(self) MDButtonIcon: icon: "controller" @@ -100,7 +100,7 @@ MDFloatLayout: id: Tool style: "text" type: (Type.TOOL, ) - on_release: app.filter_clients(self) + on_release: app.filter_clients_by_type(self) MDButtonIcon: icon: "desktop-classic" @@ -110,7 +110,7 @@ MDFloatLayout: id: adjuster style: "text" type: (Type.ADJUSTER, ) - on_release: app.filter_clients(self) + on_release: app.filter_clients_by_type(self) MDButtonIcon: icon: "wrench" @@ -120,7 +120,7 @@ MDFloatLayout: id: misc style: "text" type: (Type.MISC, ) - on_release: app.filter_clients(self) + on_release: app.filter_clients_by_type(self) MDButtonIcon: icon: "dots-horizontal-circle-outline" @@ -131,7 +131,7 @@ MDFloatLayout: id: favorites style: "text" type: ("favorites", ) - on_release: app.filter_clients(self) + on_release: app.filter_clients_by_type(self) MDButtonIcon: icon: "star" @@ -141,5 +141,21 @@ MDFloatLayout: MDNavigationDrawerDivider: - ScrollBox: - id: button_layout \ No newline at end of file + MDGridLayout: + id: main_layout + cols: 1 + spacing: "10dp" + + MDTextField: + id: search_box + mode: "outlined" + set_text: app.filter_clients_by_name + + MDTextFieldLeadingIcon: + icon: "magnify" + + MDTextFieldHintText: + text: "Search" + + ScrollBox: + id: button_layout From 20651df307c9cfc059ebe48b56d78cd21fd3cfcf Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Sat, 19 Apr 2025 18:21:11 -0500 Subject: [PATCH 0332/1218] kvui: fix kwargs on ResizableTextField and ImageButton (#4903) --- kvui.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kvui.py b/kvui.py index 9a8b7109fa66..d0d965c30b22 100644 --- a/kvui.py +++ b/kvui.py @@ -98,7 +98,7 @@ def set_colors(self): class ImageIcon(MDButtonIcon, AsyncImage): def __init__(self, *args, **kwargs): - super().__init__(args, kwargs) + super().__init__(*args, **kwargs) self.image = ApAsyncImage(**kwargs) self.add_widget(self.image) @@ -183,15 +183,17 @@ def __init__(self, *args, **kwargs): height_rule = subclass.properties.get("height", None) if height_rule: height_rule.ignore_prev = True - super().__init__(args, kwargs) + super().__init__(*args, **kwargs) def on_release(self: MDButton, *args): super(MDButton, self).on_release(args) self.on_leave() + MDButton.on_release = on_release + # I was surprised to find this didn't already exist in kivy :( class HoverBehavior(object): """originally from https://stackoverflow.com/a/605348110""" @@ -904,7 +906,7 @@ def connect_bar_validate(sender): pos_hint={"center_y": 0.575}) info_button.bind(on_release=self.command_button_action) bottom_layout.add_widget(info_button) - self.textinput = CommandPromptTextInput(size_hint_y=None, height=dp(30), multiline=False, write_tab=False) + self.textinput = CommandPromptTextInput(size_hint_y=None, multiline=False, write_tab=False) self.textinput.bind(on_text_validate=self.on_message) info_button.height = self.textinput.height self.textinput.text_validate_unfocus = False From e4bc7bd1cd44a44981c6b9387e60a626ce3a7d87 Mon Sep 17 00:00:00 2001 From: SunCat Date: Sun, 20 Apr 2025 07:16:46 +0300 Subject: [PATCH 0333/1218] Checksfinder: Fix the last remnant of outdated game description (#4893) Co-authored-by: Scipio Wright Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/checksfinder/docs/en_ChecksFinder.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/worlds/checksfinder/docs/en_ChecksFinder.md b/worlds/checksfinder/docs/en_ChecksFinder.md index cb33ab39591a..4d8fc1009162 100644 --- a/worlds/checksfinder/docs/en_ChecksFinder.md +++ b/worlds/checksfinder/docs/en_ChecksFinder.md @@ -7,9 +7,9 @@ config file. ## What is considered a location check in ChecksFinder? -Location checks in are completed when the player finds a spot on a board that has the archipelago logo. The bottom of -the screen has a number next to the archipelago logo, that number is how many you can find so far. You can only get as -many checks as you have gained items, plus five to start with being available. +Location checks get cleared when you open all non-bomb cells in a board. The bottom +of the screen has a number next to the Archipelago logo that displays how many location checks are left to be sent with +your current inventory. You can only get as many checks as you have gained items plus five checks to start with. ## When the player receives an item, what happens? From 199b6bdabb0f632fb2ff03127979ea7eaaa0f044 Mon Sep 17 00:00:00 2001 From: qwint Date: Sun, 20 Apr 2025 06:04:56 -0500 Subject: [PATCH 0334/1218] Launcher: Update header docstring (#4777) --- Launcher.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Launcher.py b/Launcher.py index 713c0cd318ce..859ebf0f768b 100644 --- a/Launcher.py +++ b/Launcher.py @@ -1,11 +1,11 @@ """ Archipelago Launcher -* if run with APBP as argument, launch corresponding client. -* if run with executable as argument, run it passing argv[2:] as arguments -* if run without arguments, open launcher GUI +* If run with a patch file as argument, launch corresponding client with the patch file as an argument. +* If run with component name as argument, run it passing argv[2:] as arguments. +* If run without arguments or unknown arguments, open launcher GUI. -Scroll down to components= to add components to the launcher as well as setup.py +Additional components can be added to worlds.LauncherComponents.components. """ import argparse From a26abe079ee203c81ebe42ff2290bc8831a8dc05 Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Sun, 20 Apr 2025 04:07:17 -0700 Subject: [PATCH 0335/1218] Zillion: Some Code Cleaning (#4780) --- worlds/zillion/__init__.py | 4 ++-- worlds/zillion/client.py | 18 +++++++++--------- worlds/zillion/gen_data.py | 4 ++-- worlds/zillion/id_maps.py | 12 ++++++------ worlds/zillion/logic.py | 14 +++++++------- worlds/zillion/options.py | 16 ++++++++-------- worlds/zillion/test/TestGoal.py | 4 ++-- worlds/zillion/test/TestOptions.py | 2 +- 8 files changed, 37 insertions(+), 37 deletions(-) diff --git a/worlds/zillion/__init__.py b/worlds/zillion/__init__.py index d0064b9cb1b4..588654d25978 100644 --- a/worlds/zillion/__init__.py +++ b/worlds/zillion/__init__.py @@ -59,7 +59,7 @@ class ZillionWebWorld(WebWorld): "English", "setup_en.md", "setup/en", - ["beauxq"] + ["beauxq"], )] option_groups = z_option_groups @@ -365,7 +365,7 @@ def finalize_item_locations(self) -> GenData: z_loc.zz_loc.item = multi_item multi_items[z_loc.zz_loc.name] = ( z_loc.item.name, - self.multiworld.get_player_name(z_loc.item.player) + self.multiworld.get_player_name(z_loc.item.player), ) # debug_zz_loc_ids.sort() # for name, id_ in debug_zz_loc_ids.items(): diff --git a/worlds/zillion/client.py b/worlds/zillion/client.py index 71f0615d32bc..1c176e7013aa 100644 --- a/worlds/zillion/client.py +++ b/worlds/zillion/client.py @@ -147,7 +147,7 @@ def run_gui(self) -> None: class ZillionManager(GameManager): logging_pairs = [ - ("Client", "Archipelago") + ("Client", "Archipelago"), ] base_title = "Archipelago Zillion Client" @@ -282,7 +282,7 @@ def on_package(self, cmd: str, args: dict[str, Any]) -> None: payload = { "cmd": "Get", - "keys": [f"zillion-{self.auth}-doors"] + "keys": [f"zillion-{self.auth}-doors"], } async_start(self.send_msgs([payload])) elif cmd == "Retrieved": @@ -326,7 +326,7 @@ def process_from_game_queue(self) -> None: n_locations = len(self.missing_locations) + len(self.checked_locations) - 1 # -1 to ignore win logger.info(f"New Check: {loc_name} ({self.ap_local_count}/{n_locations})") async_start(self.send_msgs([ - {"cmd": "LocationChecks", "locations": [server_id]} + {"cmd": "LocationChecks", "locations": [server_id]}, ])) else: # This will happen a lot in Zillion, @@ -338,7 +338,7 @@ def process_from_game_queue(self) -> None: if not self.finished_game: async_start(self.send_msgs([ {"cmd": "LocationChecks", "locations": [loc_name_to_id["J-6 bottom far left"]]}, - {"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL} + {"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}, ])) self.finished_game = True elif isinstance(event_from_game, events.DoorEventFromGame): @@ -347,7 +347,7 @@ def process_from_game_queue(self) -> None: payload = { "cmd": "Set", "key": f"zillion-{self.auth}-doors", - "operations": [{"operation": "replace", "value": doors_b64}] + "operations": [{"operation": "replace", "value": doors_b64}], } async_start(self.send_msgs([payload])) elif isinstance(event_from_game, events.MapEventFromGame): @@ -367,7 +367,7 @@ def process_items_received(self) -> None: # TODO: colors in this text, like sni client? logger.info(f"received {self.ap_id_to_name[ap_id]} from {from_name}") self.to_game.put_nowait( - events.ItemEventToGame(zz_item_ids) + events.ItemEventToGame(zz_item_ids), ) self.next_item = len(self.items_received) @@ -398,7 +398,7 @@ async def zillion_sync_task(ctx: ZillionContext) -> None: logger.info("Start Zillion in RetroArch, then use the /sms command to connect to it.") await asyncio.wait(( asyncio.create_task(ctx.look_for_retroarch.wait()), - asyncio.create_task(ctx.exit_event.wait()) + asyncio.create_task(ctx.exit_event.wait()), ), return_when=asyncio.FIRST_COMPLETED) last_log = "" @@ -443,7 +443,7 @@ def log_no_spam(msg: str) -> None: await asyncio.wait(( asyncio.create_task(ctx.got_slot_data.wait()), asyncio.create_task(ctx.exit_event.wait()), - asyncio.create_task(asyncio.sleep(6)) + asyncio.create_task(asyncio.sleep(6)), ), return_when=asyncio.FIRST_COMPLETED) # to not spam connect packets else: # not correct seed name log_no_spam("incorrect seed - did you mix up roms?") @@ -467,7 +467,7 @@ def log_no_spam(msg: str) -> None: await asyncio.wait(( asyncio.create_task(ctx.got_room_info.wait()), asyncio.create_task(ctx.exit_event.wait()), - asyncio.create_task(asyncio.sleep(6)) + asyncio.create_task(asyncio.sleep(6)), ), return_when=asyncio.FIRST_COMPLETED) else: # no name found in game if not help_message_shown: diff --git a/worlds/zillion/gen_data.py b/worlds/zillion/gen_data.py index 214073396153..295cfa08898b 100644 --- a/worlds/zillion/gen_data.py +++ b/worlds/zillion/gen_data.py @@ -19,7 +19,7 @@ def to_json(self) -> str: jsonable = { "multi_items": self.multi_items, "zz_game": self.zz_game.to_jsonable(), - "game_id": list(self.game_id) + "game_id": list(self.game_id), } return json.dumps(jsonable) @@ -37,5 +37,5 @@ def from_json(gen_data_str: str) -> "GenData": return GenData( from_json["multi_items"], ZzGame.from_jsonable(from_json["zz_game"]), - bytes(from_json["game_id"]) + bytes(from_json["game_id"]), ) diff --git a/worlds/zillion/id_maps.py b/worlds/zillion/id_maps.py index 25762f99cd6b..d7f746125a5d 100644 --- a/worlds/zillion/id_maps.py +++ b/worlds/zillion/id_maps.py @@ -42,7 +42,7 @@ def make_id_to_others(start_char: Chars) -> tuple[ - dict[int, str], dict[int, int], dict[int, ZzItem] + dict[int, str], dict[int, int], dict[int, ZzItem], ]: """ returns id_to_name, id_to_zz_id, id_to_zz_item """ id_to_name: dict[int, str] = {} @@ -53,19 +53,19 @@ def make_id_to_others(start_char: Chars) -> tuple[ name_to_zz_item = { "Apple": _zz_rescue_0, "Champ": _zz_rescue_1, - "JJ": _zz_empty + "JJ": _zz_empty, } elif start_char == "Apple": name_to_zz_item = { "Apple": _zz_empty, "Champ": _zz_rescue_1, - "JJ": _zz_rescue_0 + "JJ": _zz_rescue_0, } else: # Champ name_to_zz_item = { "Apple": _zz_rescue_0, "Champ": _zz_empty, - "JJ": _zz_rescue_1 + "JJ": _zz_rescue_1, } for name, ap_id in item_name_to_id.items(): @@ -150,10 +150,10 @@ def get_slot_info(regions: Iterable[RegionData], rescues[str(i)] = { "start_char": ri.start_char, "room_code": ri.room_code, - "mask": ri.mask + "mask": ri.mask, } return { "start_char": start_char, "rescues": rescues, - "loc_mem_to_id": loc_memory_to_loc_id + "loc_mem_to_id": loc_memory_to_loc_id, } diff --git a/worlds/zillion/logic.py b/worlds/zillion/logic.py index f3d1814a9e9b..aa7b77398bd7 100644 --- a/worlds/zillion/logic.py +++ b/worlds/zillion/logic.py @@ -25,15 +25,15 @@ def set_randomizer_locs(cs: CollectionState, p: int, zz_r: Randomizer) -> int: z_world = cs.multiworld.worlds[p] assert isinstance(z_world, ZillionWorld) - _hash = p + hash_ = p for z_loc in z_world.my_locations: zz_name = z_loc.zz_loc.name zz_item = z_loc.item.zz_item \ if isinstance(z_loc.item, ZillionItem) and z_loc.item.player == p \ else zz_empty zz_r.locations[zz_name].item = zz_item - _hash += (hash(zz_name) * (z_loc.zz_loc.req.gun + 2)) ^ hash(zz_item) - return _hash + hash_ += (hash(zz_name) * (z_loc.zz_loc.req.gun + 2)) ^ hash(zz_item) + return hash_ def item_counts(cs: CollectionState, p: int) -> tuple[tuple[str, int], ...]: @@ -67,11 +67,11 @@ def cs_to_zz_locs(self, cs: CollectionState) -> frozenset[Location]: returns frozenset of accessible zilliandomizer locations """ # caching this function because it would be slow - _hash = set_randomizer_locs(cs, self._player, self._zz_r) + hash_ = set_randomizer_locs(cs, self._player, self._zz_r) counts = item_counts(cs, self._player) - _hash += hash(counts) + hash_ += hash(counts) - cntr, locs = self._cache.get(_hash, _cache_miss) + cntr, locs = self._cache.get(hash_, _cache_miss) if cntr == cs.prog_items[self._player]: # print("cache hit") return locs @@ -90,6 +90,6 @@ def cs_to_zz_locs(self, cs: CollectionState) -> frozenset[Location]: tr = frozenset(self._zz_r.get_locations(have_req)) # save result in cache - self._cache[_hash] = (cs.prog_items[self._player].copy(), tr) + self._cache[hash_] = (cs.prog_items[self._player].copy(), tr) return tr diff --git a/worlds/zillion/options.py b/worlds/zillion/options.py index 13f3d43ab07f..5669f4da3088 100644 --- a/worlds/zillion/options.py +++ b/worlds/zillion/options.py @@ -6,7 +6,7 @@ from zilliandomizer.options import ( Options as ZzOptions, char_to_gun, char_to_jump, ID, - VBLR as ZzVBLR, Chars, ItemCounts as ZzItemCounts + VBLR as ZzVBLR, Chars, ItemCounts as ZzItemCounts, ) from zilliandomizer.options.parsing import validate as zz_validate @@ -23,7 +23,7 @@ class ZillionContinues(NamedRange): display_name = "continues" special_range_names = { "vanilla": 3, - "infinity": 21 + "infinity": 21, } @@ -247,7 +247,7 @@ class ZillionStartingCards(NamedRange): range_end = 10 display_name = "starting cards" special_range_names = { - "vanilla": 0 + "vanilla": 0, } @@ -315,8 +315,8 @@ class ZillionOptions(PerGameCommonOptions): z_option_groups = [ OptionGroup("item counts", [ ZillionIDCardCount, ZillionBreadCount, ZillionOpaOpaCount, ZillionZillionCount, - ZillionFloppyDiskCount, ZillionScopeCount, ZillionRedIDCardCount - ]) + ZillionFloppyDiskCount, ZillionScopeCount, ZillionRedIDCardCount, + ]), ] @@ -361,7 +361,7 @@ def validate(options: ZillionOptions) -> tuple[ZzOptions, Counter[str]]: "Zillion": options.zillion_count, "Floppy Disk": options.floppy_disk_count, "Scope": options.scope_count, - "Red ID Card": options.red_id_card_count + "Red ID Card": options.red_id_card_count, }) minimums = Counter({ "ID Card": 0, @@ -370,7 +370,7 @@ def validate(options: ZillionOptions) -> tuple[ZzOptions, Counter[str]]: "Zillion": guns_required, "Floppy Disk": floppy_req.value, "Scope": 0, - "Red ID Card": 1 + "Red ID Card": 1, }) for key in minimums: item_counts[key] = max(minimums[key], item_counts[key]) @@ -426,7 +426,7 @@ def validate(options: ZillionOptions) -> tuple[ZzOptions, Counter[str]]: bool(options.early_scope.value), True, # balance defense starting_cards.value, - map_gen + map_gen, ) zz_validate(zz_op) return zz_op, item_counts diff --git a/worlds/zillion/test/TestGoal.py b/worlds/zillion/test/TestGoal.py index 1c7930569913..9b891ddca0be 100644 --- a/worlds/zillion/test/TestGoal.py +++ b/worlds/zillion/test/TestGoal.py @@ -104,7 +104,7 @@ class TestGoalAppleStart(ZillionTestBase): "start_char": "Apple", "jump_levels": "balanced", "gun_levels": "low", - "zillion_count": 5 + "zillion_count": 5, } def test_guns_jj_first(self) -> None: @@ -131,7 +131,7 @@ class TestGoalChampStart(ZillionTestBase): "jump_levels": "low", "gun_levels": "balanced", "opa_opa_count": 5, - "opas_per_level": 1 + "opas_per_level": 1, } def test_jump_jj_first(self) -> None: diff --git a/worlds/zillion/test/TestOptions.py b/worlds/zillion/test/TestOptions.py index 904063fd3cd8..f37a1f24a7f6 100644 --- a/worlds/zillion/test/TestOptions.py +++ b/worlds/zillion/test/TestOptions.py @@ -18,7 +18,7 @@ def test_vblr_ap_to_zz(self) -> None: """ all of the valid values for the AP options map to valid values for ZZ options """ for option_name, vblr_class in ( ("jump_levels", ZillionJumpLevels), - ("gun_levels", ZillionGunLevels) + ("gun_levels", ZillionGunLevels), ): for value in vblr_class.name_lookup.values(): self.options = {option_name: value} From e498cc7d4853b6e7a0ba61f3ffee03b0a0c54501 Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Sun, 20 Apr 2025 04:21:40 -0700 Subject: [PATCH 0336/1218] Tests: Don't use `type` as `Callable` (#4866) --- test/general/test_entrance_rando.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/general/test_entrance_rando.py b/test/general/test_entrance_rando.py index 56a059ecf2dd..65853dfc8b8e 100644 --- a/test/general/test_entrance_rando.py +++ b/test/general/test_entrance_rando.py @@ -1,3 +1,4 @@ +from typing import Callable import unittest from enum import IntEnum @@ -34,7 +35,7 @@ def generate_entrance_pair(region: Region, name_suffix: str, group: int): def generate_disconnected_region_grid(multiworld: MultiWorld, grid_side_length: int, region_size: int = 0, - region_type: type[Region] = Region): + region_creator: Callable[[str, int, MultiWorld], Region] = Region): """ Generates a grid-like region structure for ER testing, where menu is connected to the top-left region, and each region "in vanilla" has 2 2-way exits going either down or to the right, until reaching the goal region in the @@ -44,7 +45,7 @@ def generate_disconnected_region_grid(multiworld: MultiWorld, grid_side_length: for col in range(grid_side_length): index = row * grid_side_length + col name = f"region{index}" - region = region_type(name, 1, multiworld) + region = region_creator(name, 1, multiworld) multiworld.regions.append(region) generate_locations(region_size, 1, region=region, tag=f"_{name}") @@ -465,7 +466,7 @@ class CustomRegion(Region): entrance_type = CustomEntrance multiworld = generate_test_multiworld() - generate_disconnected_region_grid(multiworld, 5, region_type=CustomRegion) + generate_disconnected_region_grid(multiworld, 5, region_creator=CustomRegion) self.assertRaises(EntranceRandomizationError, randomize_entrances, multiworld.worlds[1], False, directionally_matched_group_lookup) From eb1fef1f923a9e6eb37a5cda2bbdab71d7422bc4 Mon Sep 17 00:00:00 2001 From: shananas <47014056+shananas@users.noreply.github.com> Date: Sun, 20 Apr 2025 08:20:23 -0400 Subject: [PATCH 0337/1218] KH2: Update Docs (#4869) --- worlds/kh2/docs/setup_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/kh2/docs/setup_en.md b/worlds/kh2/docs/setup_en.md index 2e1022f3efa7..e0fc23e024d3 100644 --- a/worlds/kh2/docs/setup_en.md +++ b/worlds/kh2/docs/setup_en.md @@ -10,7 +10,7 @@ Kingdom Hearts II Final Mix from the [Epic Games Store](https://store.epicgames.com/en-US/discover/kingdom-hearts) or [Steam](https://store.steampowered.com/app/2552430/KINGDOM_HEARTS_HD_1525_ReMIX/) - Follow this Guide to set up these requirements [KH2Rando.com](https://tommadness.github.io/KH2Randomizer/setup/Panacea-ModLoader/) - 1. Version 25.01.26.0 or greater OpenKH Mod Manager with Panacea + 1. Version 25.03.16.0 or greater OpenKH Mod Manager with Panacea 2. Lua Backend from the OpenKH Mod Manager 3. Install the mod `KH2FM-Mods-Num/GoA-ROM-Edition` using OpenKH Mod Manager - Needed for Archipelago From a76ee010ebdd3e89a69e1fe2705581728cc9c1b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sun, 20 Apr 2025 08:21:02 -0400 Subject: [PATCH 0338/1218] Stardew Valley: Make Bus and Boat Require Money (#4833) --- worlds/stardew_valley/logic/money_logic.py | 12 ++++++------ worlds/stardew_valley/rules.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/worlds/stardew_valley/logic/money_logic.py b/worlds/stardew_valley/logic/money_logic.py index e272436fd8b9..f5ca991e7273 100644 --- a/worlds/stardew_valley/logic/money_logic.py +++ b/worlds/stardew_valley/logic/money_logic.py @@ -35,8 +35,8 @@ class MoneyLogic(BaseLogic[Union[RegionLogicMixin, MoneyLogicMixin, TimeLogicMix @cache_self1 def can_have_earned_total(self, amount: int) -> StardewRule: - if amount < 1000: - return True_() + if amount <= 1000: + return self.logic.true_ pierre_rule = self.logic.region.can_reach_all((Region.pierre_store, Region.forest)) willy_rule = self.logic.region.can_reach_all((Region.fish_shop, LogicRegion.fishing)) @@ -44,19 +44,19 @@ def can_have_earned_total(self, amount: int) -> StardewRule: robin_rule = self.logic.region.can_reach_all((Region.carpenter, Region.secret_woods)) shipping_rule = self.logic.shipping.can_use_shipping_bin - if amount < 2000: + if amount <= 2500: selling_any_rule = pierre_rule | willy_rule | clint_rule | robin_rule | shipping_rule return selling_any_rule - if amount < 5000: + if amount <= 5000: selling_all_rule = (pierre_rule & willy_rule & clint_rule & robin_rule) | shipping_rule return selling_all_rule - if amount < 10000: + if amount <= 10000: return shipping_rule seed_rules = self.logic.region.can_reach(Region.pierre_store) - if amount < 40000: + if amount <= 40000: return shipping_rule & seed_rules percent_progression_items_needed = min(90, amount // 20000) diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index bdfbc2048888..4b1ff2ad5673 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -201,7 +201,7 @@ def set_entrance_rules(logic: StardewLogic, multiworld, player, world_options: S movie_theater_rule = logic.has_movie_theater() set_entrance_rule(multiworld, player, Entrance.enter_movie_theater, movie_theater_rule) set_entrance_rule(multiworld, player, Entrance.purchase_movie_ticket, movie_theater_rule) - set_entrance_rule(multiworld, player, Entrance.take_bus_to_desert, logic.received("Bus Repair")) + set_entrance_rule(multiworld, player, Entrance.take_bus_to_desert, logic.received("Bus Repair") & logic.money.can_spend(500)) set_entrance_rule(multiworld, player, Entrance.enter_skull_cavern, logic.received(Wallet.skull_key)) set_entrance_rule(multiworld, player, LogicEntrance.talk_to_mines_dwarf, logic.wallet.can_speak_dwarf() & logic.tool.has_tool(Tool.pickaxe, ToolMaterial.iron)) @@ -362,7 +362,7 @@ def set_island_entrances_rules(logic: StardewLogic, multiworld, player, world_op Entrance.use_island_obelisk: logic.can_use_obelisk(Transportation.island_obelisk), Entrance.use_farm_obelisk: logic.can_use_obelisk(Transportation.farm_obelisk), Entrance.fish_shop_to_boat_tunnel: boat_repaired, - Entrance.boat_to_ginger_island: boat_repaired, + Entrance.boat_to_ginger_island: boat_repaired & logic.money.can_spend(1000), Entrance.island_south_to_west: logic.received("Island West Turtle"), Entrance.island_south_to_north: logic.received("Island North Turtle"), Entrance.island_west_to_islandfarmhouse: logic.received("Island Farmhouse"), From b756a67c2ac0be869fbb001f6c1d726c94efe821 Mon Sep 17 00:00:00 2001 From: Trevor L <80716066+TRPG0@users.noreply.github.com> Date: Sun, 20 Apr 2025 06:31:58 -0600 Subject: [PATCH 0339/1218] BRC: Update Setup Guide (#4861) Co-authored-by: Scipio Wright Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/bomb_rush_cyberfunk/docs/setup_en.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/worlds/bomb_rush_cyberfunk/docs/setup_en.md b/worlds/bomb_rush_cyberfunk/docs/setup_en.md index 14da25adb32b..aac6e86612ae 100644 --- a/worlds/bomb_rush_cyberfunk/docs/setup_en.md +++ b/worlds/bomb_rush_cyberfunk/docs/setup_en.md @@ -16,8 +16,11 @@ Cyberfunk root folder. *Do not use any pre-release versions of BepInEx 6.* 2. Start Bomb Rush Cyberfunk once so that BepInEx can create its required configuration files. -3. Download the zip archive from the [releases](https://github.com/TRPG0/BRC-Archipelago/releases) page, and extract its -contents into `BepInEx\plugins`. +3. Download `ModLocalizer.dll` from its [releases](https://github.com/TRPG0/BRC-ModLocalizer/releases) page, and put it +in `BepInEx\plugins`. + +4. Download the zip archive for the Archipelago plugin from its [releases](https://github.com/TRPG0/BRC-Archipelago/releases) +page, and extract the contents into `BepInEx\plugins`. After installing Archipelago, there are some additional mods that can also be installed for a better experience: From 04aa4715269c2f7aecfe83e514ea0c042fa73eba Mon Sep 17 00:00:00 2001 From: Omnises Nihilis <38057571+Omnises@users.noreply.github.com> Date: Sun, 20 Apr 2025 05:43:52 -0700 Subject: [PATCH 0340/1218] KH2: Update Docs (#4871) --- worlds/kh2/docs/setup_en.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/worlds/kh2/docs/setup_en.md b/worlds/kh2/docs/setup_en.md index e0fc23e024d3..a1248d109584 100644 --- a/worlds/kh2/docs/setup_en.md +++ b/worlds/kh2/docs/setup_en.md @@ -27,7 +27,7 @@ Kingdom Hearts II Final Mix from the [Epic Games Store](https://store.epicgames. Load this mod just like the GoA ROM you did during the KH2 Rando setup. `JaredWeakStrike/APCompanion`
Have this mod second-highest priority below the .zip seed.
-This mod is based upon Num's Garden of Assemblege Mod and requires it to work. Without Num this could not be possible. +This mod is based upon Num's Garden of Assemblage Mod and requires it to work. Without Num this could not be possible.

Required: Auto Save Mod and KH2 Lua Library

@@ -35,7 +35,7 @@ Load these mods just like you loaded the GoA ROM mod during the KH2 Rando setup.

Optional QoL Mods: AP QoL and Bear Skip

-`JaredWeakStrike/AP_QOL` Makes the urns minigames much faster, makes Cavern of Remembrance orbs drop significantly more drive orbs for refilling drive/leveling master form, skips the animation when using the bulky vendor RC, skips carpet escape auto scroller in Agrabah 2, and prevents the wardrobe in the Beasts Castle wardrobe push minigame from waking up while being pushed. +`JaredWeakStrike/AP_QOL` Makes the urns minigames much faster, makes Cavern of Remembrance orbs drop significantly more drive orbs for refilling drive/leveling master form, skips the animation when using the bulky vendor RC, skips carpet escape auto-scroller in Agrabah 2, and prevents the wardrobe in the Beasts Castle wardrobe push minigame from waking up while being pushed. `shananas/BearSkip` Skips all minigames in 100 Acre Woods except the Spooky Cave minigame since there are chests in Spooky Cave you can only get during the minigame. For Spooky Cave, Pooh is moved to the other side of the invisible wall that prevents you from using his RC to finish the minigame. @@ -83,6 +83,9 @@ Enter The room's port number into the top box where the x's are and pres - Loading into Simulated Twilight Town Instead of the GOA. - To fix this look over the guide at [KH2Rando.com](https://tommadness.github.io/KH2Randomizer/setup/Panacea-ModLoader/). Specifically the Panacea and Lua Backend Steps. +- Using a seed from the standalone KH2 Randomizer Seed Generator. + - The Archipelago version of the KH2 Randomizer does not use this Seed Generator; refer to the [Archipelago Setup](https://archipelago.gg/tutorial/Archipelago/setup/en) to learn how to generate and play a seed through Archipelago. +

Best Practices

- Make a save at the start of the GoA before opening anything. This will be the file to select when loading an autosave if/when your game crashes. @@ -139,4 +142,4 @@ This pack will handle logic, received items, checked locations and autotabbing f - Why should I install the auto save mod at `KH2FM-Mods-equations19/auto-save` and `KH2FM-Mods-equations19/KH2-Lua-Library`? - Because Kingdom Hearts 2 is prone to crashes and will keep you from losing your progress. Both mods are needed for auto save to work. - How do I load an auto save? - - To load an auto-save, hold down the Select or your equivalent on your prefered controller while choosing a file. Make sure to hold the button down the whole time. + - To load an auto-save, hold down the Select or your equivalent on your preferred controller while choosing a file. Make sure to hold the button down the whole time. From b76f2163a4902ddb33d101dd5551e54bc31cc4ef Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Sun, 20 Apr 2025 08:08:30 -0500 Subject: [PATCH 0341/1218] MM2: Fix invalid weakness failsafe and refactor weakness tests (#4899) --- worlds/mm2/rules.py | 4 +-- worlds/mm2/test/test_weakness.py | 50 +++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/worlds/mm2/rules.py b/worlds/mm2/rules.py index d84c13c827b2..67431c9956eb 100644 --- a/worlds/mm2/rules.py +++ b/worlds/mm2/rules.py @@ -215,7 +215,7 @@ def set_rules(world: "MM2World") -> None: continue highest, wp = max(zip(weapon_weight.values(), weapon_weight.keys())) uses = weapon_energy[wp] // weapon_costs[wp] - if int(uses * boss_damage[wp]) > boss_health[boss]: + if int(uses * boss_damage[wp]) >= boss_health[boss]: used = ceil(boss_health[boss] / boss_damage[wp]) weapon_energy[wp] -= weapon_costs[wp] * used boss_health[boss] = 0 @@ -226,7 +226,7 @@ def set_rules(world: "MM2World") -> None: # it should be impossible to be out of energy, simply because even if every boss took 1 from # Quick Boomerang and no other, it would only be 28 off from defeating all 9, # which Metal Blade should be able to cover - wp, max_uses = max((weapon, weapon_energy[weapon] // weapon_costs[weapon]) + max_uses, wp = max((weapon_energy[weapon] // weapon_costs[weapon], weapon) for weapon in weapon_weight if weapon != 0 and (weapon != 8 or boss != 12)) # Wily Machine cannot under any circumstances take damage from Time Stopper, prevent this diff --git a/worlds/mm2/test/test_weakness.py b/worlds/mm2/test/test_weakness.py index c294ce5ac989..817241c40b07 100644 --- a/worlds/mm2/test/test_weakness.py +++ b/worlds/mm2/test/test_weakness.py @@ -2,9 +2,9 @@ from . import MM2TestBase from ..options import bosses +from ..rules import minimum_weakness_requirement -# Need to figure out how this test should work def validate_wily_5(base: MM2TestBase) -> None: world = base.multiworld.worlds[base.player] weapon_damage = world.weapon_damage @@ -67,38 +67,54 @@ def validate_wily_5(base: MM2TestBase) -> None: weapon_weight.pop(wp) -class StrictWeaknessTests(MM2TestBase): +class WeaknessTests(MM2TestBase): options = { - "strict_weakness": True, "yoku_jumps": True, - "enable_lasers": True + "enable_lasers": True, } - def test_that_every_boss_has_a_weakness(self) -> None: world = self.multiworld.worlds[self.player] weapon_damage = world.weapon_damage for boss in range(14): - if not any(weapon_damage[weapon][boss] for weapon in range(9)): + if not any(weapon_damage[weapon][boss] >= minimum_weakness_requirement[weapon] for weapon in range(9)): self.fail(f"Boss {boss} generated without weakness! Seed: {self.multiworld.seed}") def test_wily_5(self) -> None: validate_wily_5(self) -class RandomStrictWeaknessTests(MM2TestBase): +class StrictWeaknessTests(WeaknessTests): options = { "strict_weakness": True, + **WeaknessTests.options + } + + +class RandomWeaknessTests(WeaknessTests): + options = { "random_weakness": "randomized", - "yoku_jumps": True, - "enable_lasers": True + **WeaknessTests.options } - def test_that_every_boss_has_a_weakness(self) -> None: - world = self.multiworld.worlds[self.player] - weapon_damage = world.weapon_damage - for boss in range(14): - if not any(weapon_damage[weapon][boss] for weapon in range(9)): - self.fail(f"Boss {boss} generated without weakness! Seed: {self.multiworld.seed}") - def test_wily_5(self) -> None: - validate_wily_5(self) +class ShuffledWeaknessTests(WeaknessTests): + options = { + "random_weakness": "shuffled", + **WeaknessTests.options + } + + +class RandomStrictWeaknessTests(WeaknessTests): + options = { + "strict_weakness": True, + "random_weakness": "randomized", + **WeaknessTests.options + } + + +class ShuffledStrictWeaknessTests(WeaknessTests): + options = { + "strict_weakness": True, + "random_weakness": "shuffled", + **WeaknessTests.options + } From be0f23beb3ff546fa493f2cbd0831879254e7fb4 Mon Sep 17 00:00:00 2001 From: LiquidCat64 <74896918+LiquidCat64@users.noreply.github.com> Date: Sun, 20 Apr 2025 07:46:57 -0600 Subject: [PATCH 0342/1218] CV64: Some DeathLink Adjustments (#4727) --- worlds/cv64/client.py | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/worlds/cv64/client.py b/worlds/cv64/client.py index cec5f551b9e5..849ca44a8a55 100644 --- a/worlds/cv64/client.py +++ b/worlds/cv64/client.py @@ -10,12 +10,20 @@ if TYPE_CHECKING: from worlds._bizhawk.context import BizHawkClientContext +DEATHLINK_AREA_NUMBERS = [0, 1, 1, 2, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, + 7, 9, 8, 6, 12, 12, 13, 11, 12, 5, 2, 10, 13, 13] + +DEATHLINK_AREA_NAMES = ["Forest of Silence", "Castle Wall", "Villa", "Tunnel", "Underground Waterway", "Castle Center", + "Duel Tower", "Tower of Execution", "Tower of Science", "Tower of Sorcery", "Room of Clocks", + "Clock Tower", "Castle Keep", "Level: You Cheated"] + class Castlevania64Client(BizHawkClient): game = "Castlevania 64" system = "N64" patch_suffix = ".apcv64" self_induced_death = False + time_of_sent_death = None received_deathlinks = 0 death_causes = [] currently_shopping = False @@ -62,15 +70,19 @@ def on_package(self, ctx: "BizHawkClientContext", cmd: str, args: dict) -> None: return if "tags" not in args: return - if "DeathLink" in args["tags"] and args["data"]["source"] != ctx.slot_info[ctx.slot].name: + if "DeathLink" in args["tags"] and args["data"]["time"] != self.time_of_sent_death: self.received_deathlinks += 1 if "cause" in args["data"]: cause = args["data"]["cause"] + # If the other game sent a death with a blank string for the cause, use the default death message. + if cause == "": + cause = f"{args['data']['source']} killed you without a word!" # Truncate the death cause message at 120 characters. if len(cause) > 120: cause = cause[0:120] else: - cause = f"{args['data']['source']} killed you!" + # If the other game sent a death with no cause at all, use the default death message. + cause = f"{args['data']['source']} killed you without a word!" self.death_causes.append(cause) async def game_watcher(self, ctx: "BizHawkClientContext") -> None: @@ -115,11 +127,30 @@ async def game_watcher(self, ctx: "BizHawkClientContext") -> None: if "DeathLink" in ctx.tags and save_struct[0xA4] & 0x80 and not self.self_induced_death and not \ deathlink_induced_death: self.self_induced_death = True + + # If the player died at the Castle Keep exterior map on one of the Room of Clocks boss towers + # (determinable by checking the entrance value as well as the map value), consider Room of Clocks the + # actual area of death. + if save_struct[0xAD] == 0x14 and save_struct[0xAF] in [0, 1]: + area_of_death = DEATHLINK_AREA_NAMES[10] + # Otherwise, determine what area the player perished in from the current map ID. + else: + area_of_death = DEATHLINK_AREA_NAMES[DEATHLINK_AREA_NUMBERS[save_struct[0xAD]]] + + # If we had the Vamp status while dying, use a special message. if save_struct[0xA4] & 0x08: - # Special death message for dying while having the Vamp status. - await ctx.send_death(f"{ctx.player_names[ctx.slot]} became a vampire and drank your blood!") + death_message = (f"{ctx.player_names[ctx.slot]} became a vampire at {area_of_death} and drank your " + f"blood!") + # Otherwise, use the generic one. else: - await ctx.send_death(f"{ctx.player_names[ctx.slot]} perished. Dracula has won!") + death_message = f"{ctx.player_names[ctx.slot]} perished in {area_of_death}. Dracula has won!" + + # Send the death. + await ctx.send_death(death_message) + + # Record the time in which the death was sent so when we receive the packet we can tell it wasn't our + # own death. ctx.on_deathlink overwrites it later, so it MUST be grabbed now. + self.time_of_sent_death = ctx.last_death_link # Write any DeathLinks received along with the corresponding death cause starting with the oldest. # To minimize Bizhawk Write jank, the DeathLink write will be prioritized over the item received one. @@ -208,6 +239,7 @@ async def game_watcher(self, ctx: "BizHawkClientContext") -> None: # Send game clear if we're in either any ending cutscene or the credits state. if not ctx.finished_game and (0x26 <= int(cutscene_value) <= 0x2E or game_state == 0x0000000B): + ctx.finished_game = True await ctx.send_msgs([{ "cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL From 33dc845de8b252a781c80d2d27039f3e74fc0333 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sun, 20 Apr 2025 09:48:09 -0400 Subject: [PATCH 0343/1218] TUNIC: Fix UT Issue with Fewer Shops Option (#4873) --- worlds/tunic/__init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index ff1dc414c340..86a91a336b34 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -162,9 +162,14 @@ def generate_early(self) -> None: self.options.shuffle_ladders.value = self.passthrough["shuffle_ladders"] self.options.grass_randomizer.value = self.passthrough.get("grass_randomizer", 0) self.options.breakable_shuffle.value = self.passthrough.get("breakable_shuffle", 0) - self.options.fixed_shop.value = self.options.fixed_shop.option_false self.options.laurels_location.value = self.options.laurels_location.option_anywhere self.options.combat_logic.value = self.passthrough["combat_logic"] + + self.options.fixed_shop.value = self.options.fixed_shop.option_false + if ("ziggurat2020_3, ziggurat2020_1_zig2_skip" in self.passthrough["Entrance Rando"].keys() + or "ziggurat2020_3, ziggurat2020_1_zig2_skip" in self.passthrough["Entrance Rando"].values()): + self.options.fixed_shop.value = self.options.fixed_shop.option_true + else: self.using_ut = False else: From 22941168cdd475c2ce07bb867bd1171b58b84bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sun, 20 Apr 2025 10:17:22 -0400 Subject: [PATCH 0344/1218] Stardew Valley: Refactor Animals to use Content Packs (#4320) --- worlds/stardew_valley/content/game_content.py | 21 ++++-- worlds/stardew_valley/content/unpacking.py | 4 ++ .../content/vanilla/ginger_island.py | 20 +++++- .../content/vanilla/the_farm.py | 66 ++++++++++++++++++- worlds/stardew_valley/data/animal.py | 23 +++++++ worlds/stardew_valley/data/bundle_data.py | 4 +- worlds/stardew_valley/data/museum_data.py | 7 +- worlds/stardew_valley/logic/animal_logic.py | 59 +++++------------ worlds/stardew_valley/logic/festival_logic.py | 31 +++++++-- worlds/stardew_valley/logic/logic.py | 25 +++---- .../logic/logic_and_mods_design.md | 14 +++- worlds/stardew_valley/logic/source_logic.py | 12 +++- worlds/stardew_valley/strings/animal_names.py | 5 +- .../strings/animal_product_names.py | 19 +++++- worlds/stardew_valley/strings/metal_names.py | 2 - 15 files changed, 228 insertions(+), 84 deletions(-) create mode 100644 worlds/stardew_valley/data/animal.py diff --git a/worlds/stardew_valley/content/game_content.py b/worlds/stardew_valley/content/game_content.py index 8a72a4811dbd..c3f8e9f8e951 100644 --- a/worlds/stardew_valley/content/game_content.py +++ b/worlds/stardew_valley/content/game_content.py @@ -1,9 +1,10 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import Dict, Iterable, Set, Any, Mapping, Type, Tuple, Union +from typing import Iterable, Set, Any, Mapping, Type, Tuple, Union from .feature import booksanity, cropsanity, fishsanity, friendsanity, skill_progression, building_progression, tool_progression +from ..data.animal import Animal from ..data.building import Building from ..data.fish_data import FishItem from ..data.game_item import GameItem, Source, ItemTag @@ -18,12 +19,13 @@ class StardewContent: # regions -> To be used with can reach rule - game_items: Dict[str, GameItem] = field(default_factory=dict) - fishes: Dict[str, FishItem] = field(default_factory=dict) - villagers: Dict[str, Villager] = field(default_factory=dict) - farm_buildings: Dict[str, Building] = field(default_factory=dict) - skills: Dict[str, Skill] = field(default_factory=dict) - quests: Dict[str, Any] = field(default_factory=dict) + game_items: dict[str, GameItem] = field(default_factory=dict) + fishes: dict[str, FishItem] = field(default_factory=dict) + villagers: dict[str, Villager] = field(default_factory=dict) + farm_buildings: dict[str, Building] = field(default_factory=dict) + animals: dict[str, Animal] = field(default_factory=dict) + skills: dict[str, Skill] = field(default_factory=dict) + quests: dict[str, Any] = field(default_factory=dict) def find_sources_of_type(self, types: Union[Type[Source], Tuple[Type[Source]]]) -> Iterable[Source]: for item in self.game_items.values(): @@ -109,6 +111,11 @@ def villager_hook(self, content: StardewContent): def farm_building_hook(self, content: StardewContent): ... + animals: Iterable[Animal] = () + + def animal_hook(self, content: StardewContent): + ... + skills: Iterable[Skill] = () def skill_hook(self, content: StardewContent): diff --git a/worlds/stardew_valley/content/unpacking.py b/worlds/stardew_valley/content/unpacking.py index 2d50f7718bf1..faa7cb5399a9 100644 --- a/worlds/stardew_valley/content/unpacking.py +++ b/worlds/stardew_valley/content/unpacking.py @@ -65,6 +65,10 @@ def register_pack(content: StardewContent, pack: ContentPack): content.farm_buildings[building.name] = building pack.farm_building_hook(content) + for animal in pack.animals: + content.animals[animal.name] = animal + pack.animal_hook(content) + for skill in pack.skills: content.skills[skill.name] = skill pack.skill_hook(content) diff --git a/worlds/stardew_valley/content/vanilla/ginger_island.py b/worlds/stardew_valley/content/vanilla/ginger_island.py index 2fbcb032799e..edb135ea30b1 100644 --- a/worlds/stardew_valley/content/vanilla/ginger_island.py +++ b/worlds/stardew_valley/content/vanilla/ginger_island.py @@ -1,15 +1,19 @@ from .pelican_town import pelican_town as pelican_town_content_pack from ..game_content import ContentPack, StardewContent from ...data import villagers_data, fish_data -from ...data.game_item import ItemTag, Tag +from ...data.animal import Animal, AnimalName, OstrichIncubatorSource +from ...data.game_item import ItemTag, Tag, CustomRuleSource from ...data.harvest import ForagingSource, HarvestFruitTreeSource, HarvestCropSource from ...data.requirement import WalnutRequirement from ...data.shop import ShopSource +from ...strings.animal_product_names import AnimalProduct from ...strings.book_names import Book +from ...strings.building_names import Building from ...strings.crop_names import Fruit, Vegetable from ...strings.fish_names import Fish from ...strings.forageable_names import Forageable, Mushroom from ...strings.fruit_tree_names import Sapling +from ...strings.generic_names import Generic from ...strings.metal_names import Fossil, Mineral from ...strings.region_names import Region, LogicRegion from ...strings.season_names import Season @@ -51,6 +55,13 @@ def harvest_source_hook(self, content: StardewContent): Vegetable.taro_root: (HarvestCropSource(seed=Seed.taro, seasons=(Season.summer,)),), Fruit.pineapple: (HarvestCropSource(seed=Seed.pineapple, seasons=(Season.summer,)),), + # Temporary animal stuff, will be moved once animal products are properly content-packed + AnimalProduct.ostrich_egg_starter: (CustomRuleSource(lambda logic: logic.tool.can_forage(Generic.any, Region.island_north, True) + & logic.has(Forageable.journal_scrap) + & logic.region.can_reach(Region.volcano_floor_5)),), + AnimalProduct.ostrich_egg: (CustomRuleSource(lambda logic: logic.has(AnimalProduct.ostrich_egg_starter) + | logic.animal.has_animal(AnimalName.ostrich)),), + }, shop_sources={ Seed.taro: (ShopSource(items_price=((2, Fossil.bone_fragment),), shop_region=Region.island_trader),), @@ -81,5 +92,12 @@ def harvest_source_hook(self, content: StardewContent): ), villagers=( villagers_data.leo, + ), + animals=( + Animal(AnimalName.ostrich, + required_building=Building.barn, + sources=( + OstrichIncubatorSource(AnimalProduct.ostrich_egg_starter), + )), ) ) diff --git a/worlds/stardew_valley/content/vanilla/the_farm.py b/worlds/stardew_valley/content/vanilla/the_farm.py index 68d0bf10f6b8..183025e43ffb 100644 --- a/worlds/stardew_valley/content/vanilla/the_farm.py +++ b/worlds/stardew_valley/content/vanilla/the_farm.py @@ -1,7 +1,12 @@ from .pelican_town import pelican_town as pelican_town_content_pack from ..game_content import ContentPack +from ...data.animal import IncubatorSource, Animal, AnimalName from ...data.harvest import FruitBatsSource, MushroomCaveSource +from ...data.shop import ShopSource +from ...strings.animal_product_names import AnimalProduct +from ...strings.building_names import Building from ...strings.forageable_names import Forageable, Mushroom +from ...strings.region_names import Region the_farm = ContentPack( "The Farm (Vanilla)", @@ -39,5 +44,64 @@ Mushroom.red: ( MushroomCaveSource(), ), - } + }, + animals=( + Animal(AnimalName.chicken, + required_building=Building.coop, + sources=( + ShopSource(shop_region=Region.ranch, money_price=800), + # For now there is no way to obtain the starter item, so this adds additional rules in the system for nothing. + # IncubatorSource(AnimalProduct.egg_starter) + )), + Animal(AnimalName.cow, + required_building=Building.barn, + sources=( + ShopSource(shop_region=Region.ranch, money_price=1500), + )), + Animal(AnimalName.goat, + required_building=Building.big_barn, + sources=( + ShopSource(shop_region=Region.ranch, money_price=4000), + )), + Animal(AnimalName.duck, + required_building=Building.big_coop, + sources=( + ShopSource(shop_region=Region.ranch, money_price=1200), + # For now there is no way to obtain the starter item, so this adds additional rules in the system for nothing. + # IncubatorSource(AnimalProduct.duck_egg_starter) + )), + Animal(AnimalName.sheep, + required_building=Building.deluxe_barn, + sources=( + ShopSource(shop_region=Region.ranch, money_price=8000), + )), + Animal(AnimalName.rabbit, + required_building=Building.deluxe_coop, + sources=( + ShopSource(shop_region=Region.ranch, money_price=8000), + )), + Animal(AnimalName.pig, + required_building=Building.deluxe_barn, + sources=( + ShopSource(shop_region=Region.ranch, money_price=16000), + )), + Animal(AnimalName.void_chicken, + required_building=Building.big_coop, + sources=( + IncubatorSource(AnimalProduct.void_egg_starter), + )), + Animal(AnimalName.golden_chicken, + required_building=Building.big_coop, + sources=( + IncubatorSource(AnimalProduct.golden_egg_starter), + )), + Animal(AnimalName.dinosaur, + required_building=Building.big_coop, + sources=( + # We should use the starter item here, but since the dinosaur egg is also an artifact, it's part of the museum rules + # and I do not want to touch it yet. + # IncubatorSource(AnimalProduct.dinosaur_egg_starter), + IncubatorSource(AnimalProduct.dinosaur_egg), + )), + ) ) diff --git a/worlds/stardew_valley/data/animal.py b/worlds/stardew_valley/data/animal.py new file mode 100644 index 000000000000..8121b6f681ff --- /dev/null +++ b/worlds/stardew_valley/data/animal.py @@ -0,0 +1,23 @@ +from dataclasses import dataclass, field + +from .game_item import Source +from ..strings.animal_names import Animal as AnimalName + +assert AnimalName + + +@dataclass(frozen=True) +class Animal: + name: str + required_building: str = field(kw_only=True) + sources: tuple[Source, ...] = field(kw_only=True) + + +@dataclass(frozen=True) +class IncubatorSource(Source): + egg_item: str + + +@dataclass(frozen=True) +class OstrichIncubatorSource(Source): + egg_item: str diff --git a/worlds/stardew_valley/data/bundle_data.py b/worlds/stardew_valley/data/bundle_data.py index 75f0f75a23d2..3a5523ecdd3f 100644 --- a/worlds/stardew_valley/data/bundle_data.py +++ b/worlds/stardew_valley/data/bundle_data.py @@ -143,7 +143,7 @@ rabbit_foot = BundleItem(AnimalProduct.rabbit_foot) dinosaur_egg = BundleItem(AnimalProduct.dinosaur_egg) void_egg = BundleItem(AnimalProduct.void_egg) -ostrich_egg = BundleItem(AnimalProduct.ostrich_egg, source=BundleItem.Sources.island, ) +ostrich_egg = BundleItem(AnimalProduct.ostrich_egg, source=BundleItem.Sources.content) golden_egg = BundleItem(AnimalProduct.golden_egg) truffle_oil = BundleItem(ArtisanGood.truffle_oil) @@ -832,7 +832,7 @@ magic_rock_candy, mega_bomb.as_amount(10), mystery_box.as_amount(10), mixed_seeds.as_amount(50), strawberry_seeds.as_amount(20), spicy_eel.as_amount(5), crab_cakes.as_amount(5), eggplant_parmesan.as_amount(5), - pumpkin_soup.as_amount(5), lucky_lunch.as_amount(5)] + pumpkin_soup.as_amount(5), lucky_lunch.as_amount(5) ] calico_bundle = BundleTemplate(CCRoom.bulletin_board, BundleName.calico, calico_items, 2, 2) raccoon_bundle = BundleTemplate(CCRoom.bulletin_board, BundleName.raccoon, raccoon_foraging_items, 4, 4) diff --git a/worlds/stardew_valley/data/museum_data.py b/worlds/stardew_valley/data/museum_data.py index b81c518a37c9..0607261ec605 100644 --- a/worlds/stardew_valley/data/museum_data.py +++ b/worlds/stardew_valley/data/museum_data.py @@ -3,12 +3,13 @@ from dataclasses import dataclass from typing import List, Tuple, Union, Optional -from ..strings.monster_names import Monster +from ..strings.animal_product_names import AnimalProduct from ..strings.fish_names import WaterChest from ..strings.forageable_names import Forageable +from ..strings.geode_names import Geode from ..strings.metal_names import Mineral, Artifact, Fossil +from ..strings.monster_names import Monster from ..strings.region_names import Region -from ..strings.geode_names import Geode @dataclass(frozen=True) @@ -105,7 +106,7 @@ class Artifact: geodes=(Geode.artifact_trove, WaterChest.fishing_chest)) ornamental_fan = create_artifact("Ornamental Fan", 7.4, (Region.beach, Region.forest, Region.town), geodes=(Geode.artifact_trove, WaterChest.fishing_chest)) - dinosaur_egg = create_artifact("Dinosaur Egg", 11.4, (Region.skull_cavern), + dinosaur_egg = create_artifact(AnimalProduct.dinosaur_egg, 11.4, (Region.skull_cavern), monsters=Monster.pepper_rex) rare_disc = create_artifact("Rare Disc", 5.6, Region.stardew_valley, geodes=(Geode.artifact_trove, WaterChest.fishing_chest), diff --git a/worlds/stardew_valley/logic/animal_logic.py b/worlds/stardew_valley/logic/animal_logic.py index eb1ebeeec54b..071133d5ce75 100644 --- a/worlds/stardew_valley/logic/animal_logic.py +++ b/worlds/stardew_valley/logic/animal_logic.py @@ -1,25 +1,15 @@ -from typing import Union +import typing from .base_logic import BaseLogicMixin, BaseLogic -from .building_logic import BuildingLogicMixin -from .has_logic import HasLogicMixin -from .money_logic import MoneyLogicMixin -from ..stardew_rule import StardewRule, true_ -from ..strings.animal_names import Animal, coop_animals, barn_animals +from ..stardew_rule import StardewRule from ..strings.building_names import Building from ..strings.forageable_names import Forageable -from ..strings.generic_names import Generic -from ..strings.region_names import Region +from ..strings.machine_names import Machine -cost_and_building_by_animal = { - Animal.chicken: (800, Building.coop), - Animal.cow: (1500, Building.barn), - Animal.goat: (4000, Building.big_barn), - Animal.duck: (1200, Building.big_coop), - Animal.sheep: (8000, Building.deluxe_barn), - Animal.rabbit: (8000, Building.deluxe_coop), - Animal.pig: (16000, Building.deluxe_barn) -} +if typing.TYPE_CHECKING: + from .logic import StardewLogic +else: + StardewLogic = object class AnimalLogicMixin(BaseLogicMixin): @@ -28,32 +18,19 @@ def __init__(self, *args, **kwargs): self.animal = AnimalLogic(*args, **kwargs) -class AnimalLogic(BaseLogic[Union[HasLogicMixin, MoneyLogicMixin, BuildingLogicMixin]]): +class AnimalLogic(BaseLogic[StardewLogic]): - def can_buy_animal(self, animal: str) -> StardewRule: - try: - price, building = cost_and_building_by_animal[animal] - except KeyError: - return true_ - return self.logic.money.can_spend_at(Region.ranch, price) & self.logic.building.has_building(building) + def can_incubate(self, egg_item: str) -> StardewRule: + return self.logic.building.has_building(Building.coop) & self.logic.has(egg_item) - def has_animal(self, animal: str) -> StardewRule: - if animal == Generic.any: - return self.has_any_animal() - elif animal == Building.coop: - return self.has_any_coop_animal() - elif animal == Building.barn: - return self.has_any_barn_animal() - return self.logic.has(animal) + def can_ostrich_incubate(self, egg_item: str) -> StardewRule: + return self.logic.building.has_building(Building.barn) & self.logic.has(Machine.ostrich_incubator) & self.logic.has(egg_item) - def has_happy_animal(self, animal: str) -> StardewRule: - return self.has_animal(animal) & self.logic.has(Forageable.hay) + def has_animal(self, animal_name: str) -> StardewRule: + animal = self.content.animals.get(animal_name) + assert animal is not None, f"Animal {animal_name} not found." - def has_any_animal(self) -> StardewRule: - return self.has_any_coop_animal() | self.has_any_barn_animal() + return self.logic.source.has_access_to_any(animal.sources) & self.logic.building.has_building(animal.required_building) - def has_any_coop_animal(self) -> StardewRule: - return self.logic.has_any(*coop_animals) - - def has_any_barn_animal(self) -> StardewRule: - return self.logic.has_any(*barn_animals) + def has_happy_animal(self, animal_name: str) -> StardewRule: + return self.logic.animal.has_animal(animal_name) & self.logic.has(Forageable.hay) diff --git a/worlds/stardew_valley/logic/festival_logic.py b/worlds/stardew_valley/logic/festival_logic.py index 2b22617202d8..939e904951bf 100644 --- a/worlds/stardew_valley/logic/festival_logic.py +++ b/worlds/stardew_valley/logic/festival_logic.py @@ -17,6 +17,7 @@ from .time_logic import TimeLogicMixin from ..options import FestivalLocations from ..stardew_rule import StardewRule +from ..strings.animal_product_names import AnimalProduct from ..strings.book_names import Book from ..strings.craftable_names import Fishing from ..strings.crop_names import Fruit, Vegetable @@ -154,18 +155,37 @@ def can_succeed_grange_display(self) -> StardewRule: if self.options.festival_locations != FestivalLocations.option_hard: return self.logic.true_ - animal_rule = self.logic.animal.has_animal(Generic.any) + # Other animal products are not counted in the animal product category + good_animal_products = [ + AnimalProduct.duck_egg, AnimalProduct.duck_feather, AnimalProduct.egg, AnimalProduct.goat_milk, AnimalProduct.golden_egg, AnimalProduct.large_egg, + AnimalProduct.large_goat_milk, AnimalProduct.large_milk, AnimalProduct.milk, AnimalProduct.ostrich_egg, AnimalProduct.rabbit_foot, + AnimalProduct.void_egg, AnimalProduct.wool + ] + if AnimalProduct.ostrich_egg not in self.content.game_items: + # When ginger island is excluded, ostrich egg is not available + good_animal_products.remove(AnimalProduct.ostrich_egg) + animal_rule = self.logic.has_any(*good_animal_products) + artisan_rule = self.logic.artisan.can_keg(Generic.any) | self.logic.artisan.can_preserves_jar(Generic.any) - cooking_rule = self.logic.money.can_spend_at(Region.saloon, 220) # Salads at the bar are good enough + + # Salads at the bar are good enough + cooking_rule = self.logic.money.can_spend_at(Region.saloon, 220) + fish_rule = self.logic.skill.can_fish(difficulty=50) - forage_rule = self.logic.region.can_reach_any((Region.forest, Region.backwoods)) # Hazelnut always available since the grange display is in fall - mineral_rule = self.logic.action.can_open_geode(Generic.any) # More than half the minerals are good enough + + # Hazelnut always available since the grange display is in fall + forage_rule = self.logic.region.can_reach_any((Region.forest, Region.backwoods)) + + # More than half the minerals are good enough + mineral_rule = self.logic.action.can_open_geode(Generic.any) + good_fruits = (fruit for fruit in (Fruit.apple, Fruit.banana, Forageable.coconut, Forageable.crystal_fruit, Fruit.mango, Fruit.orange, Fruit.peach, Fruit.pomegranate, Fruit.strawberry, Fruit.melon, Fruit.rhubarb, Fruit.pineapple, Fruit.ancient_fruit, Fruit.starfruit) if fruit in self.content.game_items) fruit_rule = self.logic.has_any(*good_fruits) + good_vegetables = (vegeteable for vegeteable in (Vegetable.amaranth, Vegetable.artichoke, Vegetable.beet, Vegetable.cauliflower, Forageable.fiddlehead_fern, Vegetable.kale, @@ -173,8 +193,7 @@ def can_succeed_grange_display(self) -> StardewRule: if vegeteable in self.content.game_items) vegetable_rule = self.logic.has_any(*good_vegetables) - return animal_rule & artisan_rule & cooking_rule & fish_rule & \ - forage_rule & fruit_rule & mineral_rule & vegetable_rule + return animal_rule & artisan_rule & cooking_rule & fish_rule & forage_rule & fruit_rule & mineral_rule & vegetable_rule def can_win_fishing_competition(self) -> StardewRule: return self.logic.skill.can_fish(difficulty=60) diff --git a/worlds/stardew_valley/logic/logic.py b/worlds/stardew_valley/logic/logic.py index aa4cd075d391..3848e393d2ce 100644 --- a/worlds/stardew_valley/logic/logic.py +++ b/worlds/stardew_valley/logic/logic.py @@ -149,42 +149,37 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC # self.received("Deluxe Fertilizer Recipe") & self.has(MetalBar.iridium) & self.has(SVItem.sap), # | (self.ability.can_cook() & self.relationship.has_hearts(NPC.emily, 3) & self.has(Forageable.leek) & self.has(Forageable.dandelion) & # | (self.ability.can_cook() & self.relationship.has_hearts(NPC.jodi, 7) & self.has(AnimalProduct.cow_milk) & self.has(Ingredient.sugar)), - Animal.chicken: self.animal.can_buy_animal(Animal.chicken), - Animal.cow: self.animal.can_buy_animal(Animal.cow), - Animal.dinosaur: self.building.has_building(Building.big_coop) & self.has(AnimalProduct.dinosaur_egg), - Animal.duck: self.animal.can_buy_animal(Animal.duck), - Animal.goat: self.animal.can_buy_animal(Animal.goat), - Animal.ostrich: self.building.has_building(Building.barn) & self.has(AnimalProduct.ostrich_egg) & self.has(Machine.ostrich_incubator), - Animal.pig: self.animal.can_buy_animal(Animal.pig), - Animal.rabbit: self.animal.can_buy_animal(Animal.rabbit), - Animal.sheep: self.animal.can_buy_animal(Animal.sheep), AnimalProduct.any_egg: self.has_any(AnimalProduct.chicken_egg, AnimalProduct.duck_egg), AnimalProduct.brown_egg: self.animal.has_animal(Animal.chicken), AnimalProduct.chicken_egg: self.has_any(AnimalProduct.egg, AnimalProduct.brown_egg, AnimalProduct.large_egg, AnimalProduct.large_brown_egg), AnimalProduct.cow_milk: self.has_any(AnimalProduct.milk, AnimalProduct.large_milk), - AnimalProduct.duck_egg: self.animal.has_animal(Animal.duck), + AnimalProduct.duck_egg: self.animal.has_animal(Animal.duck), # Should also check starter AnimalProduct.duck_feather: self.animal.has_happy_animal(Animal.duck), - AnimalProduct.egg: self.animal.has_animal(Animal.chicken), - AnimalProduct.goat_milk: self.has(Animal.goat), - AnimalProduct.golden_egg: self.received(AnimalProduct.golden_egg) & (self.money.can_spend_at(Region.ranch, 100000) | self.money.can_trade_at(Region.qi_walnut_room, Currency.qi_gem, 100)), + AnimalProduct.egg: self.animal.has_animal(Animal.chicken), # Should also check starter + AnimalProduct.goat_milk: self.animal.has_animal(Animal.goat), + AnimalProduct.golden_egg: self.has(AnimalProduct.golden_egg_starter), # Should also check golden chicken if there was an alternative to obtain it without golden egg AnimalProduct.large_brown_egg: self.animal.has_happy_animal(Animal.chicken), AnimalProduct.large_egg: self.animal.has_happy_animal(Animal.chicken), AnimalProduct.large_goat_milk: self.animal.has_happy_animal(Animal.goat), AnimalProduct.large_milk: self.animal.has_happy_animal(Animal.cow), AnimalProduct.milk: self.animal.has_animal(Animal.cow), - AnimalProduct.ostrich_egg: self.tool.can_forage(Generic.any, Region.island_north, True) & self.has(Forageable.journal_scrap) & self.region.can_reach(Region.volcano_floor_5), AnimalProduct.rabbit_foot: self.animal.has_happy_animal(Animal.rabbit), AnimalProduct.roe: self.skill.can_fish() & self.building.has_building(Building.fish_pond), AnimalProduct.squid_ink: self.mine.can_mine_in_the_mines_floor_81_120() | (self.building.has_building(Building.fish_pond) & self.has(Fish.squid)), AnimalProduct.sturgeon_roe: self.has(Fish.sturgeon) & self.building.has_building(Building.fish_pond), AnimalProduct.truffle: self.animal.has_animal(Animal.pig) & self.season.has_any_not_winter(), - AnimalProduct.void_egg: self.money.can_spend_at(Region.sewer, 5000) | (self.building.has_building(Building.fish_pond) & self.has(Fish.void_salmon)), + AnimalProduct.void_egg: self.has(AnimalProduct.void_egg_starter), # Should also check void chicken if there was an alternative to obtain it without void egg AnimalProduct.wool: self.animal.has_animal(Animal.rabbit) | self.animal.has_animal(Animal.sheep), AnimalProduct.slime_egg_green: self.has(Machine.slime_egg_press) & self.has(Loot.slime), AnimalProduct.slime_egg_blue: self.has(Machine.slime_egg_press) & self.has(Loot.slime) & self.time.has_lived_months(3), AnimalProduct.slime_egg_red: self.has(Machine.slime_egg_press) & self.has(Loot.slime) & self.time.has_lived_months(6), AnimalProduct.slime_egg_purple: self.has(Machine.slime_egg_press) & self.has(Loot.slime) & self.time.has_lived_months(9), AnimalProduct.slime_egg_tiger: self.has(Fish.lionfish) & self.building.has_building(Building.fish_pond), + AnimalProduct.duck_egg_starter: self.logic.false_, # It could be purchased at the Feast of the Winter Star, but it's random every year, so not considering it yet... + AnimalProduct.dinosaur_egg_starter: self.logic.false_, # Dinosaur eggs are also part of the museum rules, and I don't want to touch them yet. + AnimalProduct.egg_starter: self.logic.false_, # It could be purchased at the Desert Festival, but festival logic is quite a mess, so not considering it yet... + AnimalProduct.golden_egg_starter: self.received(AnimalProduct.golden_egg) & (self.money.can_spend_at(Region.ranch, 100000) | self.money.can_trade_at(Region.qi_walnut_room, Currency.qi_gem, 100)), + AnimalProduct.void_egg_starter: self.money.can_spend_at(Region.sewer, 5000) | (self.building.has_building(Building.fish_pond) & self.has(Fish.void_salmon)), ArtisanGood.aged_roe: self.artisan.can_preserves_jar(AnimalProduct.roe), ArtisanGood.battery_pack: (self.has(Machine.lightning_rod) & self.season.has_any_not_winter()) | self.has(Machine.solar_panel), ArtisanGood.caviar: self.artisan.can_preserves_jar(AnimalProduct.sturgeon_roe), diff --git a/worlds/stardew_valley/logic/logic_and_mods_design.md b/worlds/stardew_valley/logic/logic_and_mods_design.md index 87631175b391..bf6684a3544a 100644 --- a/worlds/stardew_valley/logic/logic_and_mods_design.md +++ b/worlds/stardew_valley/logic/logic_and_mods_design.md @@ -72,4 +72,16 @@ of source (Monster drop and fish can have foraging sources). if easy logic is disabled. For instance, anything that requires money could be accessible as soon as you can sell something to someone (even wood). Items are classified by their source. An item with a fishing or a crab pot source is considered a fish, an item dropping from a monster is a monster drop. An -item with a foraging source is a forageable. Items can fit in multiple categories. +item with a foraging source is a forageable. Items can fit in multiple categories. + +## Prefer rich class to anemic list of sources + +For game mechanic that might need more logic/interaction than a simple game item, prefer creating a class than just listing the sources and adding generic +requirements to them. This will simplify the implementation of more complex mechanics and increase cohesion. + +For instance, `Building` can be upgraded. Instead of having a simple source for the `Big Coop` being a shop source with an additional requirement being having +the previous building, the `Building` class has knowledge of the upgrade system and know from which building it can be upgraded. + +Another example is `Animal`. Instead of a shopping source with a requirement of having a `Coop`, the `Chicken` knows that a building is required. This way, a +potential source of chicken from incubating an egg would not require an additional requirement of having a coop (assuming the incubator could be obtained +without a big coop). diff --git a/worlds/stardew_valley/logic/source_logic.py b/worlds/stardew_valley/logic/source_logic.py index f1c6fe3d7ba3..67ce55177c4c 100644 --- a/worlds/stardew_valley/logic/source_logic.py +++ b/worlds/stardew_valley/logic/source_logic.py @@ -1,6 +1,7 @@ import functools from typing import Union, Any, Iterable +from .animal_logic import AnimalLogicMixin from .artisan_logic import ArtisanLogicMixin from .base_logic import BaseLogicMixin, BaseLogic from .grind_logic import GrindLogicMixin @@ -11,6 +12,7 @@ from .region_logic import RegionLogicMixin from .requirement_logic import RequirementLogicMixin from .tool_logic import ToolLogicMixin +from ..data.animal import IncubatorSource, OstrichIncubatorSource from ..data.artisan import MachineSource from ..data.game_item import GenericSource, Source, GameItem, CustomRuleSource from ..data.harvest import ForagingSource, FruitBatsSource, MushroomCaveSource, SeasonalForagingSource, \ @@ -25,7 +27,7 @@ def __init__(self, *args, **kwargs): class SourceLogic(BaseLogic[Union[SourceLogicMixin, HasLogicMixin, ReceivedLogicMixin, HarvestingLogicMixin, MoneyLogicMixin, RegionLogicMixin, -ArtisanLogicMixin, ToolLogicMixin, RequirementLogicMixin, GrindLogicMixin]]): +ArtisanLogicMixin, ToolLogicMixin, RequirementLogicMixin, GrindLogicMixin, AnimalLogicMixin]]): def has_access_to_item(self, item: GameItem): rules = [] @@ -81,6 +83,14 @@ def _(self, source: HarvestFruitTreeSource): def _(self, source: HarvestCropSource): return self.logic.harvesting.can_harvest_crop_from(source) + @has_access_to.register + def _(self, source: IncubatorSource): + return self.logic.animal.can_incubate(source.egg_item) + + @has_access_to.register + def _(self, source: OstrichIncubatorSource): + return self.logic.animal.can_ostrich_incubate(source.egg_item) + @has_access_to.register def _(self, source: MachineSource): return self.logic.artisan.can_produce_from(source) diff --git a/worlds/stardew_valley/strings/animal_names.py b/worlds/stardew_valley/strings/animal_names.py index ecae0d7680d2..59f2f3c9c7fa 100644 --- a/worlds/stardew_valley/strings/animal_names.py +++ b/worlds/stardew_valley/strings/animal_names.py @@ -8,6 +8,5 @@ class Animal: rabbit = "Rabbit" goat = "Goat" ostrich = "Ostrich" - -coop_animals = [Animal.chicken, "Rabbit", "Duck", "Dinosaur"] -barn_animals = [Animal.cow, "Sheep", "Pig", "Ostrich"] \ No newline at end of file + void_chicken = "Void Chicken" + golden_chicken = "Golden Chicken" diff --git a/worlds/stardew_valley/strings/animal_product_names.py b/worlds/stardew_valley/strings/animal_product_names.py index f89b610ae89d..1b7490a60756 100644 --- a/worlds/stardew_valley/strings/animal_product_names.py +++ b/worlds/stardew_valley/strings/animal_product_names.py @@ -3,17 +3,32 @@ class AnimalProduct: brown_egg = "Egg (Brown)" chicken_egg = "Chicken Egg" cow_milk = "Cow Milk" + dinosaur_egg_starter = "Dinosaur Egg (Starter)" + """This item does not really exist and should never end up being displayed. + It's there to patch the loop in logic because of the Dinosaur-and-egg problem.""" dinosaur_egg = "Dinosaur Egg" + duck_egg_starter = "Duck Egg (Starter)" + """This item does not really exist and should never end up being displayed. + It's there to patch the loop in logic because of the Chicken-and-egg problem.""" duck_egg = "Duck Egg" duck_feather = "Duck Feather" + egg_starter = "Egg (Starter)" + """This item does not really exist and should never end up being displayed. + It's there to patch the loop in logic because of the Chicken-and-egg problem.""" egg = "Egg" goat_milk = "Goat Milk" + golden_egg_starter = "Golden Egg (Starter)" + """This item does not really exist and should never end up being displayed. + It's there to patch the loop in logic because of the Chicken-and-egg problem.""" golden_egg = "Golden Egg" large_brown_egg = "Large Egg (Brown)" large_egg = "Large Egg" large_goat_milk = "Large Goat Milk" large_milk = "Large Milk" milk = "Milk" + ostrich_egg_starter = "Ostrich Egg (Starter)" + """This item does not really exist and should never end up being displayed. + It's there to patch the loop in logic because of the Chicken-and-egg problem.""" ostrich_egg = "Ostrich Egg" rabbit_foot = "Rabbit's Foot" roe = "Roe" @@ -25,6 +40,8 @@ class AnimalProduct: squid_ink = "Squid Ink" sturgeon_roe = "Sturgeon Roe" truffle = "Truffle" + void_egg_starter = "Void Egg (Starter)" + """This item does not really exist and should never end up being displayed. + It's there to patch the loop in logic because of the Chicken-and-egg problem.""" void_egg = "Void Egg" wool = "Wool" - diff --git a/worlds/stardew_valley/strings/metal_names.py b/worlds/stardew_valley/strings/metal_names.py index 7798c06defeb..7efdc7ed338e 100644 --- a/worlds/stardew_valley/strings/metal_names.py +++ b/worlds/stardew_valley/strings/metal_names.py @@ -142,5 +142,3 @@ class ModFossil: pterodactyl_phalange = "Pterodactyl Phalange" pterodactyl_vertebra = "Pterodactyl Vertebra" pterodactyl_claw = "Pterodactyl Claw" - - From 543dcb27d85510f1eec01c3744172d41440c4cbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sun, 20 Apr 2025 10:51:03 -0400 Subject: [PATCH 0345/1218] Stardew Valley: Exclude maximum one resource packs from pool when in start inventory (#4839) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/stardew_valley/__init__.py | 6 ++--- worlds/stardew_valley/data/items.csv | 4 +-- worlds/stardew_valley/items.py | 27 +++++++++---------- .../strings/wallet_item_names.py | 1 + worlds/stardew_valley/test/TestGeneration.py | 4 +-- worlds/stardew_valley/test/TestItemLink.py | 8 +++--- worlds/stardew_valley/test/TestItems.py | 18 ++++++++++++- 7 files changed, 42 insertions(+), 26 deletions(-) diff --git a/worlds/stardew_valley/__init__.py b/worlds/stardew_valley/__init__.py index bad0ab9e683d..7f420eb81ddb 100644 --- a/worlds/stardew_valley/__init__.py +++ b/worlds/stardew_valley/__init__.py @@ -1,7 +1,7 @@ import logging import typing from random import Random -from typing import Dict, Any, Iterable, Optional, List, TextIO, cast +from typing import Dict, Any, Iterable, Optional, List, TextIO from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState from Options import PerGameCommonOptions @@ -148,8 +148,8 @@ def create_items(self): self.precollect_building_items() items_to_exclude = [excluded_items for excluded_items in self.multiworld.precollected_items[self.player] - if not item_table[excluded_items.name].has_any_group(Group.RESOURCE_PACK, - Group.FRIENDSHIP_PACK)] + if item_table[excluded_items.name].has_any_group(Group.MAXIMUM_ONE) + or not item_table[excluded_items.name].has_any_group(Group.RESOURCE_PACK, Group.FRIENDSHIP_PACK)] if self.options.season_randomization == SeasonRandomization.option_disabled: items_to_exclude = [item for item in items_to_exclude diff --git a/worlds/stardew_valley/data/items.csv b/worlds/stardew_valley/data/items.csv index 44e16c5d5013..11a22e952d07 100644 --- a/worlds/stardew_valley/data/items.csv +++ b/worlds/stardew_valley/data/items.csv @@ -748,7 +748,7 @@ id,name,classification,groups,mod_name 5208,Chest,filler,"RESOURCE_PACK,RESOURCE_PACK_USEFUL", 5209,Stone Chest,filler,"RESOURCE_PACK,RESOURCE_PACK_USEFUL", 5210,Quality Bobber,filler,RESOURCE_PACK, -5211,Mini-Obelisk,filler,"EXACTLY_TWO,RESOURCE_PACK", +5211,Mini-Obelisk,filler,"AT_LEAST_TWO,RESOURCE_PACK", 5212,Monster Musk,filler,RESOURCE_PACK, 5213,Sprinkler,filler,"RESOURCE_PACK,RESOURCE_PACK_USEFUL", 5214,Quality Sprinkler,filler,"RESOURCE_PACK,RESOURCE_PACK_USEFUL", @@ -760,7 +760,7 @@ id,name,classification,groups,mod_name 5220,Lightning Rod,filler,"RESOURCE_PACK,RESOURCE_PACK_USEFUL", 5221,Resource Pack: 5000 Money,useful,"BASE_RESOURCE,RESOURCE_PACK,RESOURCE_PACK_USEFUL", 5222,Resource Pack: 10000 Money,useful,"BASE_RESOURCE,RESOURCE_PACK,RESOURCE_PACK_USEFUL", -5223,Junimo Chest,filler,"EXACTLY_TWO,RESOURCE_PACK", +5223,Junimo Chest,filler,"AT_LEAST_TWO,RESOURCE_PACK", 5224,Horse Flute,useful,"MAXIMUM_ONE,RESOURCE_PACK,RESOURCE_PACK_USEFUL", 5225,Pierre's Missing Stocklist,useful,"MAXIMUM_ONE,RESOURCE_PACK,RESOURCE_PACK_USEFUL", 5226,Hopper,filler,"RESOURCE_PACK,RESOURCE_PACK_USEFUL", diff --git a/worlds/stardew_valley/items.py b/worlds/stardew_valley/items.py index b4b1175c1d72..a0f901a20937 100644 --- a/worlds/stardew_valley/items.py +++ b/worlds/stardew_valley/items.py @@ -69,7 +69,7 @@ class Group(enum.Enum): TRAP = enum.auto() BONUS = enum.auto() MAXIMUM_ONE = enum.auto() - EXACTLY_TWO = enum.auto() + AT_LEAST_TWO = enum.auto() DEPRECATED = enum.auto() RESOURCE_PACK_USEFUL = enum.auto() SPECIAL_ORDER_BOARD = enum.auto() @@ -181,7 +181,7 @@ def create_items(item_factory: StardewItemFactory, locations_count: int, items_t items += unique_filler_items logger.debug(f"Created {len(unique_filler_items)} unique filler items") - resource_pack_items = fill_with_resource_packs_and_traps(item_factory, options, random, items, locations_count) + resource_pack_items = fill_with_resource_packs_and_traps(item_factory, options, random, items + items_to_exclude, locations_count - len(items)) items += resource_pack_items logger.debug(f"Created {len(resource_pack_items)} resource packs") @@ -711,7 +711,7 @@ def weapons_count(options: StardewValleyOptions): def fill_with_resource_packs_and_traps(item_factory: StardewItemFactory, options: StardewValleyOptions, random: Random, items_already_added: List[Item], - number_locations: int) -> List[Item]: + available_item_slots: int) -> List[Item]: include_traps = options.trap_items != TrapItems.option_no_traps items_already_added_names = [item.name for item in items_already_added] useful_resource_packs = [pack for pack in items_by_group[Group.RESOURCE_PACK_USEFUL] @@ -734,10 +734,9 @@ def fill_with_resource_packs_and_traps(item_factory: StardewItemFactory, options priority_filler_items = remove_excluded_items(priority_filler_items, options) number_priority_items = len(priority_filler_items) - required_resource_pack = number_locations - len(items_already_added) - if required_resource_pack < number_priority_items: + if available_item_slots < number_priority_items: chosen_priority_items = [item_factory(resource_pack) for resource_pack in - random.sample(priority_filler_items, required_resource_pack)] + random.sample(priority_filler_items, available_item_slots)] return chosen_priority_items items = [] @@ -745,24 +744,24 @@ def fill_with_resource_packs_and_traps(item_factory: StardewItemFactory, options ItemClassification.trap if resource_pack.classification == ItemClassification.trap else ItemClassification.useful) for resource_pack in priority_filler_items] items.extend(chosen_priority_items) - required_resource_pack -= number_priority_items + available_item_slots -= number_priority_items all_filler_packs = [filler_pack for filler_pack in all_filler_packs if Group.MAXIMUM_ONE not in filler_pack.groups or (filler_pack.name not in [priority_item.name for priority_item in priority_filler_items] and filler_pack.name not in items_already_added_names)] - while required_resource_pack > 0: + while available_item_slots > 0: resource_pack = random.choice(all_filler_packs) - exactly_2 = Group.EXACTLY_TWO in resource_pack.groups - while exactly_2 and required_resource_pack == 1: + exactly_2 = Group.AT_LEAST_TWO in resource_pack.groups + while exactly_2 and available_item_slots == 1: resource_pack = random.choice(all_filler_packs) - exactly_2 = Group.EXACTLY_TWO in resource_pack.groups + exactly_2 = Group.AT_LEAST_TWO in resource_pack.groups classification = ItemClassification.useful if resource_pack.classification == ItemClassification.progression else resource_pack.classification items.append(item_factory(resource_pack, classification)) - required_resource_pack -= 1 + available_item_slots -= 1 if exactly_2: items.append(item_factory(resource_pack, classification)) - required_resource_pack -= 1 + available_item_slots -= 1 if exactly_2 or Group.MAXIMUM_ONE in resource_pack.groups: all_filler_packs.remove(resource_pack) @@ -803,7 +802,7 @@ def generate_filler_choice_pool(options: StardewValleyOptions) -> list[str]: def remove_limited_amount_packs(packs): - return [pack for pack in packs if Group.MAXIMUM_ONE not in pack.groups and Group.EXACTLY_TWO not in pack.groups] + return [pack for pack in packs if Group.MAXIMUM_ONE not in pack.groups and Group.AT_LEAST_TWO not in pack.groups] def get_all_filler_items(include_traps: bool, exclude_ginger_island: bool) -> List[ItemData]: diff --git a/worlds/stardew_valley/strings/wallet_item_names.py b/worlds/stardew_valley/strings/wallet_item_names.py index 32655efe88c2..743d1f0c0155 100644 --- a/worlds/stardew_valley/strings/wallet_item_names.py +++ b/worlds/stardew_valley/strings/wallet_item_names.py @@ -9,3 +9,4 @@ class Wallet: dark_talisman = "Dark Talisman" club_card = "Club Card" mastery_of_the_five_ways = "Mastery Of The Five Ways" + key_to_the_town = "Key To The Town" diff --git a/worlds/stardew_valley/test/TestGeneration.py b/worlds/stardew_valley/test/TestGeneration.py index 35cd2007eb0e..77092c78fcae 100644 --- a/worlds/stardew_valley/test/TestGeneration.py +++ b/worlds/stardew_valley/test/TestGeneration.py @@ -66,7 +66,7 @@ def test_does_not_create_more_than_one_maximum_one_items(self): def test_does_not_create_or_create_two_of_exactly_two_items(self): all_created_items = self.get_all_created_items() - for exactly_two_item in items.items_by_group[items.Group.EXACTLY_TWO]: + for exactly_two_item in items.items_by_group[items.Group.AT_LEAST_TWO]: with self.subTest(f"{exactly_two_item.name}"): count = all_created_items.count(exactly_two_item.name) self.assertTrue(count == 0 or count == 2) @@ -114,7 +114,7 @@ def test_does_not_create_more_than_one_maximum_one_items(self): def test_does_not_create_exactly_two_items(self): all_created_items = self.get_all_created_items() - for exactly_two_item in items.items_by_group[items.Group.EXACTLY_TWO]: + for exactly_two_item in items.items_by_group[items.Group.AT_LEAST_TWO]: with self.subTest(f"{exactly_two_item.name}"): count = all_created_items.count(exactly_two_item.name) self.assertTrue(count == 0 or count == 2) diff --git a/worlds/stardew_valley/test/TestItemLink.py b/worlds/stardew_valley/test/TestItemLink.py index 39bf553cab2d..3a0d976511f7 100644 --- a/worlds/stardew_valley/test/TestItemLink.py +++ b/worlds/stardew_valley/test/TestItemLink.py @@ -19,7 +19,7 @@ def test_filler_of_all_types_generated(self): continue filler_generated.append(filler) self.assertNotIn(Group.MAXIMUM_ONE, item_table[filler].groups) - self.assertNotIn(Group.EXACTLY_TWO, item_table[filler].groups) + self.assertNotIn(Group.AT_LEAST_TWO, item_table[filler].groups) if Group.TRAP in item_table[filler].groups: at_least_one_trap = True if Group.GINGER_ISLAND in item_table[filler].groups: @@ -46,7 +46,7 @@ def test_filler_has_no_island_but_has_traps(self): filler_generated.append(filler) self.assertNotIn(Group.GINGER_ISLAND, item_table[filler].groups) self.assertNotIn(Group.MAXIMUM_ONE, item_table[filler].groups) - self.assertNotIn(Group.EXACTLY_TWO, item_table[filler].groups) + self.assertNotIn(Group.AT_LEAST_TWO, item_table[filler].groups) if Group.TRAP in item_table[filler].groups: at_least_one_trap = True if len(filler_generated) >= max_number_filler: @@ -70,7 +70,7 @@ def test_filler_has_no_traps_but_has_island(self): filler_generated.append(filler) self.assertNotIn(Group.TRAP, item_table[filler].groups) self.assertNotIn(Group.MAXIMUM_ONE, item_table[filler].groups) - self.assertNotIn(Group.EXACTLY_TWO, item_table[filler].groups) + self.assertNotIn(Group.AT_LEAST_TWO, item_table[filler].groups) if Group.GINGER_ISLAND in item_table[filler].groups: at_least_one_island = True if len(filler_generated) >= max_number_filler: @@ -94,7 +94,7 @@ def test_filler_generated_without_island_or_traps(self): self.assertNotIn(Group.GINGER_ISLAND, item_table[filler].groups) self.assertNotIn(Group.TRAP, item_table[filler].groups) self.assertNotIn(Group.MAXIMUM_ONE, item_table[filler].groups) - self.assertNotIn(Group.EXACTLY_TWO, item_table[filler].groups) + self.assertNotIn(Group.AT_LEAST_TWO, item_table[filler].groups) if len(filler_generated) >= max_number_filler: break self.assertGreaterEqual(len(filler_generated), max_number_filler) diff --git a/worlds/stardew_valley/test/TestItems.py b/worlds/stardew_valley/test/TestItems.py index 9cff146597d0..1d6f9689553b 100644 --- a/worlds/stardew_valley/test/TestItems.py +++ b/worlds/stardew_valley/test/TestItems.py @@ -1,4 +1,4 @@ -from BaseClasses import MultiWorld, get_seed +from BaseClasses import MultiWorld, get_seed, ItemClassification from . import setup_solo_multiworld, SVTestCase, solo_multiworld from .options.presets import allsanity_no_mods_6_x_x, get_minsanity_options from .. import StardewValleyWorld @@ -72,6 +72,22 @@ def test_can_start_in_any_season(self): self.assertEqual(len(starting_seasons_rolled), 4) +class TestStartInventoryFillersAreProperlyExcluded(SVTestCase): + def test_given_maximum_one_resource_pack_in_start_inventory_when_create_items_then_item_is_properly_excluded(self): + assert item_table[Wallet.key_to_the_town].classification == ItemClassification.useful \ + and {Group.MAXIMUM_ONE, Group.RESOURCE_PACK_USEFUL}.issubset(item_table[Wallet.key_to_the_town].groups), \ + "'Key to the Town' is no longer suitable to test this usecase." + + options = { + "start_inventory": { + Wallet.key_to_the_town: 1, + } + } + + with solo_multiworld(options, world_caching=False) as (multiworld, world): + self.assertNotIn(world.create_item(Wallet.key_to_the_town), multiworld.get_items()) + + class TestMetalDetectors(SVTestCase): def test_minsanity_1_metal_detector(self): options = get_minsanity_options() From b59162737d7c6b379bf0963ec664208cdc153dfe Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 20 Apr 2025 23:04:40 +0200 Subject: [PATCH 0346/1218] LttP: increase gen rate of pedestal goal with limited rupee pool (#4905) * LttP: increase gen rate of pedestal goal with limited rupee pool * improve chance further if retro bow is involved --- worlds/alttp/ItemPool.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/worlds/alttp/ItemPool.py b/worlds/alttp/ItemPool.py index 2b99ef8a739c..0bcc189f9c3b 100644 --- a/worlds/alttp/ItemPool.py +++ b/worlds/alttp/ItemPool.py @@ -707,13 +707,20 @@ def place_item(loc, item): else: break - if goal == 'pedestal': - place_item('Master Sword Pedestal', 'Triforce') - pool.remove("Rupees (20)") - if retro_bow: replace = {'Single Arrow', 'Arrows (10)', 'Arrow Upgrade (+5)', 'Arrow Upgrade (+10)', 'Arrow Upgrade (70)'} pool = ['Rupees (5)' if item in replace else item for item in pool] + + if goal == 'pedestal': + place_item('Master Sword Pedestal', 'Triforce') + for rupee_name in ("Rupees (5)", "Rupees (20)", "Rupees (50)", "Rupees (100)", "Rupees (300)"): + try: + pool.remove(rupee_name) + except ValueError: + pass + else: + break + if world.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: pool.extend(diff.universal_keys) if mode == 'standard': From b62c1364a9c6c211a25fdfd0fe6ec01c55fda225 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Mon, 21 Apr 2025 00:43:05 +0200 Subject: [PATCH 0347/1218] MultiServer.py: Another Hint Priority + Item Links bug oh boy (#4874) Basically, hints for itemlink worlds' locations get stored in ctx.hints under 1. the location's player 2. **every individual player** that is participating in the itemlink. Right now, the updatehint code tries to replace and resend the hint under the itemlinked player, which doesn't work. --- MultiServer.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index c9e0ad8bfab0..4295f28c58e8 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1983,11 +1983,13 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): new_hint = new_hint.re_prioritize(ctx, status) if hint == new_hint: return - ctx.replace_hint(client.team, hint.finding_player, hint, new_hint) - ctx.replace_hint(client.team, hint.receiving_player, hint, new_hint) + + concerning_slots = ctx.slot_set(hint.receiving_player) | {hint.finding_player} + for slot in concerning_slots: + ctx.replace_hint(client.team, slot, hint, new_hint) ctx.save() - ctx.on_changed_hints(client.team, hint.finding_player) - ctx.on_changed_hints(client.team, hint.receiving_player) + for slot in concerning_slots: + ctx.on_changed_hints(client.team, slot) elif cmd == 'StatusUpdate': update_client_status(ctx, client, args["status"]) From 1a6de25ab6b83fe28ec3031a5bd4815f72182da1 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Mon, 21 Apr 2025 00:43:31 +0200 Subject: [PATCH 0348/1218] Core, all worlds: Hard-deprecate old options API (by August 10th 2024) (#3284) * Core: deprecate old options API * also deprecate assigning options via option_definitions --------- Co-authored-by: alwaysintreble --- BaseClasses.py | 2 +- worlds/AutoWorld.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index ec3fa9cef17a..bf115e3f9c96 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -223,7 +223,7 @@ def set_options(self, args: Namespace) -> None: AutoWorld.AutoWorldRegister.world_types[self.game[player]].options_dataclass.type_hints} for option_key in all_keys: option = Utils.DeprecateDict(f"Getting options from multiworld is now deprecated. " - f"Please use `self.options.{option_key}` instead.") + f"Please use `self.options.{option_key}` instead.", True) option.update(getattr(args, option_key, {})) setattr(self, option_key, option) diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index d1f4a772eeff..b4ff24190f11 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -12,6 +12,7 @@ from Options import item_and_loc_options, ItemsAccessibility, OptionGroup, PerGameCommonOptions from BaseClasses import CollectionState +from Utils import deprecate if TYPE_CHECKING: from BaseClasses import MultiWorld, Item, Location, Tutorial, Region, Entrance @@ -75,9 +76,8 @@ def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> Aut # TODO - remove this once all worlds use options dataclasses if "options_dataclass" not in dct and "option_definitions" in dct: # TODO - switch to deprecate after a version - if __debug__: - logging.warning(f"{name} Assigned options through option_definitions which is now deprecated. " - "Please use options_dataclass instead.") + deprecate(f"{name} Assigned options through option_definitions which is now deprecated. " + "Please use options_dataclass instead.") dct["options_dataclass"] = make_dataclass(f"{name}Options", dct["option_definitions"].items(), bases=(PerGameCommonOptions,)) From 6613c296523185ffd4ea9c37c4c6ffe21e797935 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 21 Apr 2025 00:53:40 +0200 Subject: [PATCH 0349/1218] Core: print both world source paths in case of conflict (#4751) --- worlds/AutoWorld.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index b4ff24190f11..67455a1a218e 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -83,11 +83,13 @@ def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> Aut # construct class new_class = super().__new__(mcs, name, bases, dct) + new_class.__file__ = sys.modules[new_class.__module__].__file__ if "game" in dct: if dct["game"] in AutoWorldRegister.world_types: - raise RuntimeError(f"""Game {dct["game"]} already registered.""") + raise RuntimeError(f"""Game {dct["game"]} already registered in + {AutoWorldRegister.world_types[dct["game"]].__file__} when attempting to register from + {new_class.__file__}.""") AutoWorldRegister.world_types[dct["game"]] = new_class - new_class.__file__ = sys.modules[new_class.__module__].__file__ if ".apworld" in new_class.__file__: new_class.zip_path = pathlib.Path(new_class.__file__).parents[1] if "settings_key" not in dct: From d5d56ede8bfa71b7ec4818b2467fbe16354c82d7 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 21 Apr 2025 15:20:22 -0400 Subject: [PATCH 0350/1218] TUNIC: Remove Outdated Plando Code (#4908) --- worlds/tunic/__init__.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 86a91a336b34..29791b4f43de 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -678,18 +678,6 @@ def fill_slot_data(self) -> Dict[str, Any]: for _ in range(self.options.start_inventory_from_pool[start_item]): slot_data[start_item].extend(["Your Pocket", self.player]) - for plando_item in self.multiworld.plando_items[self.player]: - if plando_item["from_pool"]: - items_to_find = set() - for item_type in [key for key in ["item", "items"] if key in plando_item]: - for item in plando_item[item_type]: - items_to_find.add(item) - for item in items_to_find: - if item in slot_data_item_names: - slot_data[item] = [] - for item_location in self.multiworld.find_item_locations(item, self.player): - slot_data[item].extend(self.get_real_location(item_location)) - return slot_data # for the universal tracker, doesn't get called in standard gen From d309de25570e5132388aee1fecc569f77dce4975 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Mon, 21 Apr 2025 16:06:24 -0400 Subject: [PATCH 0351/1218] Lingo: Rework Early Good Items (#4910) --- worlds/lingo/__init__.py | 37 ++++++++++++++++++++++++---------- worlds/lingo/player_logic.py | 39 ++++++++---------------------------- 2 files changed, 34 insertions(+), 42 deletions(-) diff --git a/worlds/lingo/__init__.py b/worlds/lingo/__init__.py index 05509a394bae..c27aaed73abc 100644 --- a/worlds/lingo/__init__.py +++ b/worlds/lingo/__init__.py @@ -3,7 +3,7 @@ """ from logging import warning -from BaseClasses import CollectionState, Item, ItemClassification, Tutorial +from BaseClasses import CollectionState, Item, ItemClassification, Tutorial, Location, LocationProgressType from Options import OptionError from worlds.AutoWorld import WebWorld, World from .datatypes import Room, RoomEntrance @@ -80,10 +80,6 @@ def create_regions(self): for item in self.player_logic.real_items: state.collect(self.create_item(item), True) - # Exception to the above: a forced good item is not considered a "real item", but needs to be here anyway. - if self.player_logic.forced_good_item != "": - state.collect(self.create_item(self.player_logic.forced_good_item), True) - all_locations = self.multiworld.get_locations(self.player) state.sweep_for_advancements(locations=all_locations) @@ -105,11 +101,6 @@ def create_regions(self): def create_items(self): pool = [self.create_item(name) for name in self.player_logic.real_items] - if self.player_logic.forced_good_item != "": - new_item = self.create_item(self.player_logic.forced_good_item) - location_obj = self.multiworld.get_location("Second Room - Good Luck", self.player) - location_obj.place_locked_item(new_item) - item_difference = len(self.player_logic.real_locations) - len(pool) if item_difference: trap_percentage = self.options.trap_percentage @@ -138,7 +129,7 @@ def create_items(self): trap_counts = {name: int(weight * traps / total_weight) for name, weight in self.options.trap_weights.items()} - + trap_difference = traps - sum(trap_counts.values()) if trap_difference > 0: allowed_traps = [name for name in TRAP_ITEMS if self.options.trap_weights[name] > 0] @@ -169,6 +160,30 @@ def create_item(self, name: str) -> Item: def set_rules(self): self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) + def place_good_item(self, progitempool: list[Item], fill_locations: list[Location]): + if len(self.player_logic.good_item_options) == 0: + return + + good_location = self.get_location("Second Room - Good Luck") + if good_location.progress_type == LocationProgressType.EXCLUDED or good_location not in fill_locations: + return + + good_items = list(filter(lambda progitem: progitem.player == self.player and + progitem.name in self.player_logic.good_item_options, progitempool)) + + if len(good_items) == 0: + return + + good_item = self.random.choice(good_items) + good_location.place_locked_item(good_item) + + progitempool.remove(good_item) + fill_locations.remove(good_location) + + def fill_hook(self, progitempool: list[Item], usefulitempool: list[Item], filleritempool: list[Item], + fill_locations: list[Location]): + self.place_good_item(progitempool, fill_locations) + def fill_slot_data(self): slot_options = [ "death_link", "victory_condition", "shuffle_colors", "shuffle_doors", "shuffle_paintings", "shuffle_panels", diff --git a/worlds/lingo/player_logic.py b/worlds/lingo/player_logic.py index 83217d7311a3..9363dfedb67f 100644 --- a/worlds/lingo/player_logic.py +++ b/worlds/lingo/player_logic.py @@ -95,7 +95,7 @@ class LingoPlayerLogic: painting_mapping: Dict[str, str] - forced_good_item: str + good_item_options: List[str] panel_reqs: Dict[str, Dict[str, AccessRequirements]] door_reqs: Dict[str, Dict[str, AccessRequirements]] @@ -151,7 +151,7 @@ def __init__(self, world: "LingoWorld"): self.mastery_location = "" self.level_2_location = "" self.painting_mapping = {} - self.forced_good_item = "" + self.good_item_options = [] self.panel_reqs = {} self.door_reqs = {} self.mastery_reqs = [] @@ -344,23 +344,23 @@ def __init__(self, world: "LingoWorld"): # Starting Room - Back Right Door gives access to OPEN and DEAD END. # Starting Room - Exit Door gives access to OPEN and TRACE. - good_item_options: List[str] = ["Starting Room - Back Right Door", "Second Room - Exit Door"] + self.good_item_options = ["Starting Room - Back Right Door", "Second Room - Exit Door"] if not color_shuffle: if not world.options.enable_pilgrimage: # HOT CRUST and THIS. - good_item_options.append("Pilgrim Room - Sun Painting") + self.good_item_options.append("Pilgrim Room - Sun Painting") if world.options.group_doors: # WELCOME BACK, CLOCKWISE, and DRAWL + RUNS. - good_item_options.append("Welcome Back Doors") + self.good_item_options.append("Welcome Back Doors") else: # WELCOME BACK and CLOCKWISE. - good_item_options.append("Welcome Back Area - Shortcut to Starting Room") + self.good_item_options.append("Welcome Back Area - Shortcut to Starting Room") if world.options.group_doors: # Color hallways access (NOTE: reconsider when sunwarp shuffling exists). - good_item_options.append("Rhyme Room Doors") + self.good_item_options.append("Rhyme Room Doors") # When painting shuffle is off, most Starting Room paintings give color hallways access. The Wondrous's # painting does not, but it gives access to SHRINK and WELCOME BACK. @@ -376,30 +376,7 @@ def __init__(self, world: "LingoWorld"): continue pdoor = DOORS_BY_ROOM[painting_obj.required_door.room][painting_obj.required_door.door] - good_item_options.append(pdoor.item_name) - - # Copied from The Witness -- remove any plandoed items from the possible good items set. - for v in world.multiworld.plando_items[world.player]: - if v.get("from_pool", True): - for item_key in {"item", "items"}: - if item_key in v: - if type(v[item_key]) is str: - if v[item_key] in good_item_options: - good_item_options.remove(v[item_key]) - elif type(v[item_key]) is dict: - for item, weight in v[item_key].items(): - if weight and item in good_item_options: - good_item_options.remove(item) - else: - # Other type of iterable - for item in v[item_key]: - if item in good_item_options: - good_item_options.remove(item) - - if len(good_item_options) > 0: - self.forced_good_item = world.random.choice(good_item_options) - self.real_items.remove(self.forced_good_item) - self.real_locations.remove("Second Room - Good Luck") + self.good_item_options.append(pdoor.item_name) def randomize_paintings(self, world: "LingoWorld") -> bool: self.painting_mapping.clear() From 57d3c52df96a8af1980397b140e91477893712d2 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 21 Apr 2025 17:41:20 -0400 Subject: [PATCH 0352/1218] TUNIC: More varied reserved locations for local_fill option (#4653) * Make reserved locations more varied * Use CollectionState(self.multiworld) instead of whatever it used to be --- worlds/tunic/__init__.py | 7 ++++--- worlds/tunic/locations.py | 17 ----------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 29791b4f43de..9d97e5711bf7 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -3,7 +3,7 @@ from BaseClasses import Region, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState from .items import (item_name_to_id, item_table, item_name_groups, fool_tiers, filler_items, slot_data_item_names, combat_items) -from .locations import location_table, location_name_groups, standard_location_name_to_id, hexagon_locations, sphere_one +from .locations import location_table, location_name_groups, standard_location_name_to_id, hexagon_locations from .rules import set_location_rules, set_region_rules, randomize_ability_unlocks, gold_hexagon from .er_rules import set_er_location_rules from .regions import tunic_regions @@ -451,9 +451,10 @@ def remove_filler(amount: int) -> None: def pre_fill(self) -> None: if self.options.local_fill > 0 and self.multiworld.players > 1: # we need to reserve a couple locations so that we don't fill up every sphere 1 location - reserved_locations: Set[str] = set(self.random.sample(sphere_one, 2)) + sphere_one_locs = self.multiworld.get_reachable_locations(CollectionState(self.multiworld), self.player) + reserved_locations: Set[Location] = set(self.random.sample(sphere_one_locs, 2)) viable_locations = [loc for loc in self.multiworld.get_unfilled_locations(self.player) - if loc.name not in reserved_locations + if loc not in reserved_locations and loc.name not in self.options.priority_locations.value] if len(viable_locations) < self.amount_to_local_fill: diff --git a/worlds/tunic/locations.py b/worlds/tunic/locations.py index 18c0fb3c134b..ced3d2233b6c 100644 --- a/worlds/tunic/locations.py +++ b/worlds/tunic/locations.py @@ -322,23 +322,6 @@ class TunicLocationData(NamedTuple): "Blue Questagon": "Rooted Ziggurat Lower - Hexagon Blue", } -sphere_one: List[str] = [ - "Overworld - [Central] Chest Across From Well", - "Overworld - [Northwest] Chest Near Quarry Gate", - "Overworld - [Northwest] Shadowy Corner Chest", - "Overworld - [Southwest] Chest Guarded By Turret", - "Overworld - [Southwest] South Chest Near Guard", - "Overworld - [Southwest] Obscured in Tunnel to Beach", - "Overworld - [Northwest] Chest Near Turret", - "Overworld - [Northwest] Page By Well", - "Overworld - [West] Chest Behind Moss Wall", - "Overworld - [Southwest] Key Pickup", - "Overworld - [West] Key Pickup", - "Overworld - [West] Obscured Behind Windmill", - "Overworld - [West] Obscured Near Well", - "Overworld - [West] Page On Teleporter" -] - standard_location_name_to_id: Dict[str, int] = {name: location_base_id + index for index, name in enumerate(location_table)} all_locations = location_table.copy() From bad6a4b211f99d9f439a9971b78e1d06e9f05fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Wed, 23 Apr 2025 11:31:08 -0400 Subject: [PATCH 0353/1218] Stardew Valley: remove BaseLogic generic so importing mixins is no longer needed (#4916) * remove BaseLogic generic so importing mixins is no longer needed * self review --- worlds/stardew_valley/logic/ability_logic.py | 17 +------------- worlds/stardew_valley/logic/action_logic.py | 8 +------ worlds/stardew_valley/logic/animal_logic.py | 7 +----- worlds/stardew_valley/logic/arcade_logic.py | 6 +---- worlds/stardew_valley/logic/artisan_logic.py | 6 +---- worlds/stardew_valley/logic/base_logic.py | 16 +++++++------ worlds/stardew_valley/logic/book_logic.py | 6 +---- worlds/stardew_valley/logic/building_logic.py | 12 +--------- worlds/stardew_valley/logic/bundle_logic.py | 14 ++--------- worlds/stardew_valley/logic/combat_logic.py | 7 +----- worlds/stardew_valley/logic/cooking_logic.py | 13 +---------- worlds/stardew_valley/logic/crafting_logic.py | 13 +---------- worlds/stardew_valley/logic/farming_logic.py | 9 +++----- worlds/stardew_valley/logic/festival_logic.py | 19 +-------------- worlds/stardew_valley/logic/fishing_logic.py | 14 ++--------- worlds/stardew_valley/logic/gift_logic.py | 3 +-- worlds/stardew_valley/logic/goal_logic.py | 9 +------- worlds/stardew_valley/logic/grind_logic.py | 2 +- .../stardew_valley/logic/harvesting_logic.py | 11 +-------- worlds/stardew_valley/logic/has_logic.py | 2 +- .../logic/logic_and_mods_design.md | 2 +- worlds/stardew_valley/logic/mine_logic.py | 12 +--------- worlds/stardew_valley/logic/money_logic.py | 17 +------------- worlds/stardew_valley/logic/monster_logic.py | 2 +- worlds/stardew_valley/logic/museum_logic.py | 2 +- worlds/stardew_valley/logic/pet_logic.py | 7 +----- worlds/stardew_valley/logic/quality_logic.py | 2 +- worlds/stardew_valley/logic/quest_logic.py | 21 ++--------------- worlds/stardew_valley/logic/received_logic.py | 2 +- worlds/stardew_valley/logic/region_logic.py | 2 +- .../logic/relationship_logic.py | 16 +------------ .../stardew_valley/logic/requirement_logic.py | 18 ++------------- worlds/stardew_valley/logic/season_logic.py | 2 +- worlds/stardew_valley/logic/shipping_logic.py | 2 +- worlds/stardew_valley/logic/skill_logic.py | 18 +-------------- worlds/stardew_valley/logic/source_logic.py | 15 ++---------- .../logic/special_order_logic.py | 23 ++----------------- worlds/stardew_valley/logic/time_logic.py | 2 +- worlds/stardew_valley/logic/tool_logic.py | 8 +------ .../logic/traveling_merchant_logic.py | 2 +- worlds/stardew_valley/logic/wallet_logic.py | 2 +- worlds/stardew_valley/logic/walnut_logic.py | 9 +------- .../mods/logic/deepwoods_logic.py | 13 ++--------- .../mods/logic/elevator_logic.py | 3 +-- .../stardew_valley/mods/logic/item_logic.py | 22 ++---------------- .../stardew_valley/mods/logic/magic_logic.py | 7 +----- .../stardew_valley/mods/logic/quests_logic.py | 13 ++--------- .../stardew_valley/mods/logic/skills_logic.py | 16 +------------ .../mods/logic/special_orders_logic.py | 14 +---------- worlds/stardew_valley/mods/logic/sve_logic.py | 19 ++------------- 50 files changed, 70 insertions(+), 417 deletions(-) diff --git a/worlds/stardew_valley/logic/ability_logic.py b/worlds/stardew_valley/logic/ability_logic.py index 2038d995a720..52dbd5abaf27 100644 --- a/worlds/stardew_valley/logic/ability_logic.py +++ b/worlds/stardew_valley/logic/ability_logic.py @@ -1,23 +1,9 @@ -import typing -from typing import Union - from .base_logic import BaseLogicMixin, BaseLogic -from .mine_logic import MineLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .skill_logic import SkillLogicMixin -from .tool_logic import ToolLogicMixin -from ..mods.logic.magic_logic import MagicLogicMixin from ..stardew_rule import StardewRule from ..strings.region_names import Region from ..strings.skill_names import Skill, ModSkill from ..strings.tool_names import ToolMaterial, Tool -if typing.TYPE_CHECKING: - from ..mods.logic.mod_logic import ModLogicMixin -else: - ModLogicMixin = object - class AbilityLogicMixin(BaseLogicMixin): def __init__(self, *args, **kwargs): @@ -25,8 +11,7 @@ def __init__(self, *args, **kwargs): self.ability = AbilityLogic(*args, **kwargs) -class AbilityLogic(BaseLogic[Union[AbilityLogicMixin, RegionLogicMixin, ReceivedLogicMixin, ToolLogicMixin, SkillLogicMixin, MineLogicMixin, MagicLogicMixin, -ModLogicMixin]]): +class AbilityLogic(BaseLogic): def can_mine_perfectly(self) -> StardewRule: return self.logic.mine.can_progress_in_the_mines_from_floor(160) diff --git a/worlds/stardew_valley/logic/action_logic.py b/worlds/stardew_valley/logic/action_logic.py index 5b117de68cf2..64cb18c001bf 100644 --- a/worlds/stardew_valley/logic/action_logic.py +++ b/worlds/stardew_valley/logic/action_logic.py @@ -1,11 +1,5 @@ -from typing import Union - from Utils import cache_self1 from .base_logic import BaseLogic, BaseLogicMixin -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .tool_logic import ToolLogicMixin from ..stardew_rule import StardewRule, True_ from ..strings.generic_names import Generic from ..strings.geode_names import Geode @@ -19,7 +13,7 @@ def __init__(self, *args, **kwargs): self.action = ActionLogic(*args, **kwargs) -class ActionLogic(BaseLogic[Union[ActionLogicMixin, RegionLogicMixin, ReceivedLogicMixin, HasLogicMixin, ToolLogicMixin]]): +class ActionLogic(BaseLogic): def can_watch(self, channel: str = None): tv_rule = True_() diff --git a/worlds/stardew_valley/logic/animal_logic.py b/worlds/stardew_valley/logic/animal_logic.py index 071133d5ce75..701cdeb1aab4 100644 --- a/worlds/stardew_valley/logic/animal_logic.py +++ b/worlds/stardew_valley/logic/animal_logic.py @@ -6,11 +6,6 @@ from ..strings.forageable_names import Forageable from ..strings.machine_names import Machine -if typing.TYPE_CHECKING: - from .logic import StardewLogic -else: - StardewLogic = object - class AnimalLogicMixin(BaseLogicMixin): def __init__(self, *args, **kwargs): @@ -18,7 +13,7 @@ def __init__(self, *args, **kwargs): self.animal = AnimalLogic(*args, **kwargs) -class AnimalLogic(BaseLogic[StardewLogic]): +class AnimalLogic(BaseLogic): def can_incubate(self, egg_item: str) -> StardewRule: return self.logic.building.has_building(Building.coop) & self.logic.has(egg_item) diff --git a/worlds/stardew_valley/logic/arcade_logic.py b/worlds/stardew_valley/logic/arcade_logic.py index 5e6a02a18435..74a239641018 100644 --- a/worlds/stardew_valley/logic/arcade_logic.py +++ b/worlds/stardew_valley/logic/arcade_logic.py @@ -1,8 +1,4 @@ -from typing import Union - from .base_logic import BaseLogic, BaseLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin from .. import options from ..stardew_rule import StardewRule, True_ from ..strings.region_names import Region @@ -14,7 +10,7 @@ def __init__(self, *args, **kwargs): self.arcade = ArcadeLogic(*args, **kwargs) -class ArcadeLogic(BaseLogic[Union[ArcadeLogicMixin, RegionLogicMixin, ReceivedLogicMixin]]): +class ArcadeLogic(BaseLogic): def has_jotpk_power_level(self, power_level: int) -> StardewRule: if self.options.arcade_machine_locations != options.ArcadeMachineLocations.option_full_shuffling: diff --git a/worlds/stardew_valley/logic/artisan_logic.py b/worlds/stardew_valley/logic/artisan_logic.py index 23f0ae03b790..93c45530af73 100644 --- a/worlds/stardew_valley/logic/artisan_logic.py +++ b/worlds/stardew_valley/logic/artisan_logic.py @@ -1,8 +1,4 @@ -from typing import Union - from .base_logic import BaseLogic, BaseLogicMixin -from .has_logic import HasLogicMixin -from .time_logic import TimeLogicMixin from ..data.artisan import MachineSource from ..data.game_item import ItemTag from ..stardew_rule import StardewRule @@ -20,7 +16,7 @@ def __init__(self, *args, **kwargs): self.artisan = ArtisanLogic(*args, **kwargs) -class ArtisanLogic(BaseLogic[Union[ArtisanLogicMixin, TimeLogicMixin, HasLogicMixin]]): +class ArtisanLogic(BaseLogic): def initialize_rules(self): # TODO remove this one too once fish are converted to sources self.registry.artisan_good_rules.update({ArtisanGood.specific_smoked_fish(fish): self.can_smoke(fish) for fish in all_fish}) diff --git a/worlds/stardew_valley/logic/base_logic.py b/worlds/stardew_valley/logic/base_logic.py index 761ee541574a..dce1c328a7bf 100644 --- a/worlds/stardew_valley/logic/base_logic.py +++ b/worlds/stardew_valley/logic/base_logic.py @@ -1,11 +1,15 @@ from __future__ import annotations -from typing import TypeVar, Generic, Dict, Collection +import typing +from typing import Dict, Collection from ..content.game_content import StardewContent from ..options import StardewValleyOptions from ..stardew_rule import StardewRule +if typing.TYPE_CHECKING: + from .logic import StardewLogic + class LogicRegistry: @@ -30,18 +34,16 @@ def __init__(self, *args, **kwargs): pass -T = TypeVar("T", bound=BaseLogicMixin) - - -class BaseLogic(BaseLogicMixin, Generic[T]): +class BaseLogic(BaseLogicMixin): player: int registry: LogicRegistry options: StardewValleyOptions content: StardewContent regions: Collection[str] - logic: T + logic: StardewLogic - def __init__(self, player: int, registry: LogicRegistry, options: StardewValleyOptions, content: StardewContent, regions: Collection[str], logic: T): + def __init__(self, player: int, registry: LogicRegistry, options: StardewValleyOptions, content: StardewContent, regions: Collection[str], + logic: StardewLogic): super().__init__(player, registry, options, content, regions, logic) self.player = player self.registry = registry diff --git a/worlds/stardew_valley/logic/book_logic.py b/worlds/stardew_valley/logic/book_logic.py index 464056ee06ba..50cc38587be9 100644 --- a/worlds/stardew_valley/logic/book_logic.py +++ b/worlds/stardew_valley/logic/book_logic.py @@ -1,9 +1,5 @@ -from typing import Union - from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin from ..stardew_rule import StardewRule @@ -13,7 +9,7 @@ def __init__(self, *args, **kwargs): self.book = BookLogic(*args, **kwargs) -class BookLogic(BaseLogic[Union[ReceivedLogicMixin, HasLogicMixin]]): +class BookLogic(BaseLogic): @cache_self1 def has_book_power(self, book: str) -> StardewRule: diff --git a/worlds/stardew_valley/logic/building_logic.py b/worlds/stardew_valley/logic/building_logic.py index 58a375d046f7..0d96f216e006 100644 --- a/worlds/stardew_valley/logic/building_logic.py +++ b/worlds/stardew_valley/logic/building_logic.py @@ -1,21 +1,11 @@ -import typing from functools import cached_property -from typing import Union from Utils import cache_self1 from .base_logic import BaseLogic, BaseLogicMixin -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin from ..stardew_rule import StardewRule, true_ from ..strings.building_names import Building from ..strings.region_names import Region -if typing.TYPE_CHECKING: - from .source_logic import SourceLogicMixin -else: - SourceLogicMixin = object - AUTO_BUILDING_BUILDINGS = {Building.shipping_bin, Building.pet_bowl, Building.farm_house} @@ -25,7 +15,7 @@ def __init__(self, *args, **kwargs): self.building = BuildingLogic(*args, **kwargs) -class BuildingLogic(BaseLogic[Union[BuildingLogicMixin, RegionLogicMixin, ReceivedLogicMixin, HasLogicMixin, SourceLogicMixin]]): +class BuildingLogic(BaseLogic): @cache_self1 def can_build(self, building_name: str) -> StardewRule: diff --git a/worlds/stardew_valley/logic/bundle_logic.py b/worlds/stardew_valley/logic/bundle_logic.py index 8ede4de5e7c4..9af91c731c8e 100644 --- a/worlds/stardew_valley/logic/bundle_logic.py +++ b/worlds/stardew_valley/logic/bundle_logic.py @@ -1,16 +1,7 @@ from functools import cached_property -from typing import Union, List +from typing import List from .base_logic import BaseLogicMixin, BaseLogic -from .fishing_logic import FishingLogicMixin -from .has_logic import HasLogicMixin -from .money_logic import MoneyLogicMixin -from .quality_logic import QualityLogicMixin -from .quest_logic import QuestLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .skill_logic import SkillLogicMixin -from .time_logic import TimeLogicMixin from ..bundles.bundle import Bundle from ..stardew_rule import StardewRule, True_ from ..strings.ap_names.community_upgrade_names import CommunityUpgrade @@ -27,8 +18,7 @@ def __init__(self, *args, **kwargs): self.bundle = BundleLogic(*args, **kwargs) -class BundleLogic(BaseLogic[Union[ReceivedLogicMixin, HasLogicMixin, TimeLogicMixin, RegionLogicMixin, MoneyLogicMixin, QualityLogicMixin, FishingLogicMixin, -SkillLogicMixin, QuestLogicMixin]]): +class BundleLogic(BaseLogic): # Should be cached def can_complete_bundle(self, bundle: Bundle) -> StardewRule: item_rules = [] diff --git a/worlds/stardew_valley/logic/combat_logic.py b/worlds/stardew_valley/logic/combat_logic.py index 849bf14b2203..14e8978de222 100644 --- a/worlds/stardew_valley/logic/combat_logic.py +++ b/worlds/stardew_valley/logic/combat_logic.py @@ -1,12 +1,7 @@ from functools import cached_property -from typing import Union from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from ..mods.logic.magic_logic import MagicLogicMixin from ..stardew_rule import StardewRule, False_ from ..strings.ap_names.ap_weapon_names import APWeapon from ..strings.performance_names import Performance @@ -20,7 +15,7 @@ def __init__(self, *args, **kwargs): self.combat = CombatLogic(*args, **kwargs) -class CombatLogic(BaseLogic[Union[HasLogicMixin, CombatLogicMixin, RegionLogicMixin, ReceivedLogicMixin, MagicLogicMixin]]): +class CombatLogic(BaseLogic): @cache_self1 def can_fight_at_level(self, level: str) -> StardewRule: if level == Performance.basic: diff --git a/worlds/stardew_valley/logic/cooking_logic.py b/worlds/stardew_valley/logic/cooking_logic.py index 339b2b9817a6..0959b90a8fd2 100644 --- a/worlds/stardew_valley/logic/cooking_logic.py +++ b/worlds/stardew_valley/logic/cooking_logic.py @@ -1,17 +1,7 @@ from functools import cached_property -from typing import Union from Utils import cache_self1 -from .action_logic import ActionLogicMixin from .base_logic import BaseLogicMixin, BaseLogic -from .building_logic import BuildingLogicMixin -from .has_logic import HasLogicMixin -from .money_logic import MoneyLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .relationship_logic import RelationshipLogicMixin -from .season_logic import SeasonLogicMixin -from .skill_logic import SkillLogicMixin from ..data.recipe_data import RecipeSource, StarterSource, ShopSource, SkillSource, FriendshipSource, \ QueenOfSauceSource, CookingRecipe, ShopFriendshipSource from ..data.recipe_source import CutsceneSource, ShopTradeSource @@ -29,8 +19,7 @@ def __init__(self, *args, **kwargs): self.cooking = CookingLogic(*args, **kwargs) -class CookingLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, RegionLogicMixin, SeasonLogicMixin, MoneyLogicMixin, ActionLogicMixin, -BuildingLogicMixin, RelationshipLogicMixin, SkillLogicMixin, CookingLogicMixin]]): +class CookingLogic(BaseLogic): @cached_property def can_cook_in_kitchen(self) -> StardewRule: return self.logic.building.has_building(Building.kitchen) | self.logic.skill.has_level(Skill.foraging, 9) diff --git a/worlds/stardew_valley/logic/crafting_logic.py b/worlds/stardew_valley/logic/crafting_logic.py index b768a74b9201..01dfc5173cb0 100644 --- a/worlds/stardew_valley/logic/crafting_logic.py +++ b/worlds/stardew_valley/logic/crafting_logic.py @@ -1,15 +1,5 @@ -from typing import Union - from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic -from .has_logic import HasLogicMixin -from .money_logic import MoneyLogicMixin -from .quest_logic import QuestLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .relationship_logic import RelationshipLogicMixin -from .skill_logic import SkillLogicMixin -from .special_order_logic import SpecialOrderLogicMixin from .. import options from ..data.craftable_data import CraftingRecipe from ..data.recipe_source import CutsceneSource, ShopTradeSource, ArchipelagoSource, LogicSource, SpecialOrderSource, \ @@ -25,8 +15,7 @@ def __init__(self, *args, **kwargs): self.crafting = CraftingLogic(*args, **kwargs) -class CraftingLogic(BaseLogic[Union[ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, MoneyLogicMixin, RelationshipLogicMixin, -SkillLogicMixin, SpecialOrderLogicMixin, CraftingLogicMixin, QuestLogicMixin]]): +class CraftingLogic(BaseLogic): @cache_self1 def can_craft(self, recipe: CraftingRecipe = None) -> StardewRule: if recipe is None: diff --git a/worlds/stardew_valley/logic/farming_logic.py b/worlds/stardew_valley/logic/farming_logic.py index cb8a55e6b42f..54c8c8af20e8 100644 --- a/worlds/stardew_valley/logic/farming_logic.py +++ b/worlds/stardew_valley/logic/farming_logic.py @@ -3,11 +3,6 @@ from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .season_logic import SeasonLogicMixin -from .tool_logic import ToolLogicMixin from .. import options from ..stardew_rule import StardewRule, True_, false_ from ..strings.fertilizer_names import Fertilizer @@ -29,7 +24,7 @@ def __init__(self, *args, **kwargs): self.farming = FarmingLogic(*args, **kwargs) -class FarmingLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, RegionLogicMixin, SeasonLogicMixin, ToolLogicMixin, FarmingLogicMixin]]): +class FarmingLogic(BaseLogic): @cached_property def has_farming_tools(self) -> StardewRule: @@ -45,6 +40,8 @@ def has_fertilizer(self, tier: int) -> StardewRule: if tier >= 3: return self.logic.has(Fertilizer.deluxe) + return self.logic.false_ + @cache_self1 def can_plant_and_grow_item(self, seasons: Union[str, Tuple[str]]) -> StardewRule: if seasons == (): # indoor farming diff --git a/worlds/stardew_valley/logic/festival_logic.py b/worlds/stardew_valley/logic/festival_logic.py index 939e904951bf..b48668964d71 100644 --- a/worlds/stardew_valley/logic/festival_logic.py +++ b/worlds/stardew_valley/logic/festival_logic.py @@ -1,20 +1,4 @@ -from typing import Union - -from .action_logic import ActionLogicMixin -from .animal_logic import AnimalLogicMixin -from .artisan_logic import ArtisanLogicMixin from .base_logic import BaseLogicMixin, BaseLogic -from .fishing_logic import FishingLogicMixin -from .gift_logic import GiftLogicMixin -from .has_logic import HasLogicMixin -from .money_logic import MoneyLogicMixin -from .monster_logic import MonsterLogicMixin -from .museum_logic import MuseumLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .relationship_logic import RelationshipLogicMixin -from .skill_logic import SkillLogicMixin -from .time_logic import TimeLogicMixin from ..options import FestivalLocations from ..stardew_rule import StardewRule from ..strings.animal_product_names import AnimalProduct @@ -36,8 +20,7 @@ def __init__(self, *args, **kwargs): self.festival = FestivalLogic(*args, **kwargs) -class FestivalLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, FestivalLogicMixin, ArtisanLogicMixin, AnimalLogicMixin, MoneyLogicMixin, TimeLogicMixin, -SkillLogicMixin, RegionLogicMixin, ActionLogicMixin, MonsterLogicMixin, RelationshipLogicMixin, FishingLogicMixin, MuseumLogicMixin, GiftLogicMixin]]): +class FestivalLogic(BaseLogic): def initialize_rules(self): self.registry.festival_rules.update({ diff --git a/worlds/stardew_valley/logic/fishing_logic.py b/worlds/stardew_valley/logic/fishing_logic.py index 1bb4cccea635..85a9b1204076 100644 --- a/worlds/stardew_valley/logic/fishing_logic.py +++ b/worlds/stardew_valley/logic/fishing_logic.py @@ -1,17 +1,8 @@ -from typing import Union - from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .season_logic import SeasonLogicMixin -from .skill_logic import SkillLogicMixin -from .tool_logic import ToolLogicMixin from ..data import fish_data from ..data.fish_data import FishItem -from ..options import ExcludeGingerIsland -from ..options import SpecialOrderLocations +from ..options import ExcludeGingerIsland, SpecialOrderLocations from ..stardew_rule import StardewRule, True_, False_ from ..strings.ap_names.mods.mod_items import SVEQuestItem from ..strings.craftable_names import Fishing @@ -28,8 +19,7 @@ def __init__(self, *args, **kwargs): self.fishing = FishingLogic(*args, **kwargs) -class FishingLogic(BaseLogic[Union[HasLogicMixin, FishingLogicMixin, ReceivedLogicMixin, RegionLogicMixin, SeasonLogicMixin, ToolLogicMixin, -SkillLogicMixin]]): +class FishingLogic(BaseLogic): def can_fish_in_freshwater(self) -> StardewRule: return self.logic.skill.can_fish() & self.logic.region.can_reach_any((Region.forest, Region.town, Region.mountain)) diff --git a/worlds/stardew_valley/logic/gift_logic.py b/worlds/stardew_valley/logic/gift_logic.py index 527da6876411..11667783d696 100644 --- a/worlds/stardew_valley/logic/gift_logic.py +++ b/worlds/stardew_valley/logic/gift_logic.py @@ -1,7 +1,6 @@ from functools import cached_property from .base_logic import BaseLogic, BaseLogicMixin -from .has_logic import HasLogicMixin from ..stardew_rule import StardewRule from ..strings.animal_product_names import AnimalProduct from ..strings.gift_names import Gift @@ -13,7 +12,7 @@ def __init__(self, *args, **kwargs): self.gifts = GiftLogic(*args, **kwargs) -class GiftLogic(BaseLogic[HasLogicMixin]): +class GiftLogic(BaseLogic): @cached_property def has_any_universal_love(self) -> StardewRule: diff --git a/worlds/stardew_valley/logic/goal_logic.py b/worlds/stardew_valley/logic/goal_logic.py index 6ffa4da15a00..6dbb5f898765 100644 --- a/worlds/stardew_valley/logic/goal_logic.py +++ b/worlds/stardew_valley/logic/goal_logic.py @@ -1,5 +1,3 @@ -import typing - from .base_logic import BaseLogic, BaseLogicMixin from ..data.craftable_data import all_crafting_recipes_by_name from ..data.recipe_data import all_cooking_recipes_by_name @@ -12,11 +10,6 @@ from ..strings.season_names import Season from ..strings.wallet_item_names import Wallet -if typing.TYPE_CHECKING: - from .logic import StardewLogic -else: - StardewLogic = object - class GoalLogicMixin(BaseLogicMixin): def __init__(self, *args, **kwargs): @@ -24,7 +17,7 @@ def __init__(self, *args, **kwargs): self.goal = GoalLogic(*args, **kwargs) -class GoalLogic(BaseLogic[StardewLogic]): +class GoalLogic(BaseLogic): def can_complete_community_center(self) -> StardewRule: return self.logic.bundle.can_complete_community_center diff --git a/worlds/stardew_valley/logic/grind_logic.py b/worlds/stardew_valley/logic/grind_logic.py index 9550a128308f..e18c13c15aab 100644 --- a/worlds/stardew_valley/logic/grind_logic.py +++ b/worlds/stardew_valley/logic/grind_logic.py @@ -38,7 +38,7 @@ def __init__(self, *args, **kwargs): self.grind = GrindLogic(*args, **kwargs) -class GrindLogic(BaseLogic[Union[GrindLogicMixin, HasLogicMixin, ReceivedLogicMixin, RegionLogicMixin, BookLogicMixin, TimeLogicMixin, ToolLogicMixin]]): +class GrindLogic(BaseLogic): def can_grind_mystery_boxes(self, quantity: int) -> StardewRule: opening_rule = self.logic.region.can_reach(Region.blacksmith) diff --git a/worlds/stardew_valley/logic/harvesting_logic.py b/worlds/stardew_valley/logic/harvesting_logic.py index 3b4d41953ccd..6478e3495346 100644 --- a/worlds/stardew_valley/logic/harvesting_logic.py +++ b/worlds/stardew_valley/logic/harvesting_logic.py @@ -1,15 +1,7 @@ from functools import cached_property -from typing import Union from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic -from .farming_logic import FarmingLogicMixin -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .season_logic import SeasonLogicMixin -from .time_logic import TimeLogicMixin -from .tool_logic import ToolLogicMixin from ..data.harvest import ForagingSource, HarvestFruitTreeSource, HarvestCropSource from ..stardew_rule import StardewRule from ..strings.ap_names.community_upgrade_names import CommunityUpgrade @@ -22,8 +14,7 @@ def __init__(self, *args, **kwargs): self.harvesting = HarvestingLogic(*args, **kwargs) -class HarvestingLogic(BaseLogic[Union[HarvestingLogicMixin, HasLogicMixin, ReceivedLogicMixin, RegionLogicMixin, SeasonLogicMixin, ToolLogicMixin, -FarmingLogicMixin, TimeLogicMixin]]): +class HarvestingLogic(BaseLogic): @cached_property def can_harvest_from_fruit_bats(self) -> StardewRule: diff --git a/worlds/stardew_valley/logic/has_logic.py b/worlds/stardew_valley/logic/has_logic.py index 5d4b700e3b0b..79c4c53167b3 100644 --- a/worlds/stardew_valley/logic/has_logic.py +++ b/worlds/stardew_valley/logic/has_logic.py @@ -2,7 +2,7 @@ from ..stardew_rule import StardewRule, And, Or, Has, Count, true_, false_, HasProgressionPercent -class HasLogicMixin(BaseLogic[None]): +class HasLogicMixin(BaseLogic): true_ = true_ false_ = false_ diff --git a/worlds/stardew_valley/logic/logic_and_mods_design.md b/worlds/stardew_valley/logic/logic_and_mods_design.md index bf6684a3544a..fc69e2c80796 100644 --- a/worlds/stardew_valley/logic/logic_and_mods_design.md +++ b/worlds/stardew_valley/logic/logic_and_mods_design.md @@ -12,7 +12,7 @@ class TimeLogicMixin(BaseLogicMixin): self.time = TimeLogic(*args, **kwargs) -class TimeLogic(BaseLogic[Union[TimeLogicMixin, ReceivedLogicMixin]]): +class TimeLogic(BaseLogic): def has_lived_months(self, number: int) -> StardewRule: return self.logic.received(Event.month_end, number) diff --git a/worlds/stardew_valley/logic/mine_logic.py b/worlds/stardew_valley/logic/mine_logic.py index e332241c1016..2dacf674603d 100644 --- a/worlds/stardew_valley/logic/mine_logic.py +++ b/worlds/stardew_valley/logic/mine_logic.py @@ -1,14 +1,5 @@ -from typing import Union - from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic -from .combat_logic import CombatLogicMixin -from .cooking_logic import CookingLogicMixin -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .skill_logic import SkillLogicMixin -from .tool_logic import ToolLogicMixin from .. import options from ..stardew_rule import StardewRule, True_ from ..strings.performance_names import Performance @@ -23,8 +14,7 @@ def __init__(self, *args, **kwargs): self.mine = MineLogic(*args, **kwargs) -class MineLogic(BaseLogic[Union[HasLogicMixin, MineLogicMixin, RegionLogicMixin, ReceivedLogicMixin, CombatLogicMixin, ToolLogicMixin, -SkillLogicMixin, CookingLogicMixin]]): +class MineLogic(BaseLogic): # Regions def can_mine_in_the_mines_floor_1_40(self) -> StardewRule: return self.logic.region.can_reach(Region.mines_floor_5) diff --git a/worlds/stardew_valley/logic/money_logic.py b/worlds/stardew_valley/logic/money_logic.py index f5ca991e7273..8f459a172bb1 100644 --- a/worlds/stardew_valley/logic/money_logic.py +++ b/worlds/stardew_valley/logic/money_logic.py @@ -1,25 +1,11 @@ -import typing -from typing import Union - from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic -from .grind_logic import GrindLogicMixin -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .season_logic import SeasonLogicMixin -from .time_logic import TimeLogicMixin from ..data.shop import ShopSource from ..options import SpecialOrderLocations from ..stardew_rule import StardewRule, True_, HasProgressionPercent, False_, true_ from ..strings.currency_names import Currency from ..strings.region_names import Region, LogicRegion -if typing.TYPE_CHECKING: - from .shipping_logic import ShippingLogicMixin -else: - ShippingLogicMixin = object - qi_gem_rewards = ("100 Qi Gems", "50 Qi Gems", "40 Qi Gems", "35 Qi Gems", "25 Qi Gems", "20 Qi Gems", "15 Qi Gems", "10 Qi Gems") @@ -30,8 +16,7 @@ def __init__(self, *args, **kwargs): self.money = MoneyLogic(*args, **kwargs) -class MoneyLogic(BaseLogic[Union[RegionLogicMixin, MoneyLogicMixin, TimeLogicMixin, RegionLogicMixin, ReceivedLogicMixin, HasLogicMixin, SeasonLogicMixin, -GrindLogicMixin, ShippingLogicMixin]]): +class MoneyLogic(BaseLogic): @cache_self1 def can_have_earned_total(self, amount: int) -> StardewRule: diff --git a/worlds/stardew_valley/logic/monster_logic.py b/worlds/stardew_valley/logic/monster_logic.py index 7e6d786972ac..5d2ac3d3f607 100644 --- a/worlds/stardew_valley/logic/monster_logic.py +++ b/worlds/stardew_valley/logic/monster_logic.py @@ -20,7 +20,7 @@ def __init__(self, *args, **kwargs): self.monster = MonsterLogic(*args, **kwargs) -class MonsterLogic(BaseLogic[Union[HasLogicMixin, MonsterLogicMixin, RegionLogicMixin, CombatLogicMixin, TimeLogicMixin]]): +class MonsterLogic(BaseLogic): @cached_property def all_monsters_by_name(self): diff --git a/worlds/stardew_valley/logic/museum_logic.py b/worlds/stardew_valley/logic/museum_logic.py index 36ba62b31fcb..2237cd89ea65 100644 --- a/worlds/stardew_valley/logic/museum_logic.py +++ b/worlds/stardew_valley/logic/museum_logic.py @@ -22,7 +22,7 @@ def __init__(self, *args, **kwargs): self.museum = MuseumLogic(*args, **kwargs) -class MuseumLogic(BaseLogic[Union[ReceivedLogicMixin, HasLogicMixin, TimeLogicMixin, RegionLogicMixin, ActionLogicMixin, ToolLogicMixin, MuseumLogicMixin]]): +class MuseumLogic(BaseLogic): def can_donate_museum_items(self, number: int) -> StardewRule: return self.logic.region.can_reach(Region.museum) & self.logic.museum.can_find_museum_items(number) diff --git a/worlds/stardew_valley/logic/pet_logic.py b/worlds/stardew_valley/logic/pet_logic.py index 0438940a6633..9d66e8f274d9 100644 --- a/worlds/stardew_valley/logic/pet_logic.py +++ b/worlds/stardew_valley/logic/pet_logic.py @@ -1,11 +1,6 @@ import math -from typing import Union from .base_logic import BaseLogicMixin, BaseLogic -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .time_logic import TimeLogicMixin -from .tool_logic import ToolLogicMixin from ..content.feature.friendsanity import pet_heart_item_name from ..stardew_rule import StardewRule, True_ from ..strings.region_names import Region @@ -17,7 +12,7 @@ def __init__(self, *args, **kwargs): self.pet = PetLogic(*args, **kwargs) -class PetLogic(BaseLogic[Union[RegionLogicMixin, ReceivedLogicMixin, TimeLogicMixin, ToolLogicMixin]]): +class PetLogic(BaseLogic): def has_pet_hearts(self, hearts: int = 1) -> StardewRule: assert hearts >= 0, "You can't have negative hearts with a pet." if hearts == 0: diff --git a/worlds/stardew_valley/logic/quality_logic.py b/worlds/stardew_valley/logic/quality_logic.py index 54e2d242654b..7f5da4be538f 100644 --- a/worlds/stardew_valley/logic/quality_logic.py +++ b/worlds/stardew_valley/logic/quality_logic.py @@ -14,7 +14,7 @@ def __init__(self, *args, **kwargs): self.quality = QualityLogic(*args, **kwargs) -class QualityLogic(BaseLogic[Union[SkillLogicMixin, FarmingLogicMixin]]): +class QualityLogic(BaseLogic): @cache_self1 def can_grow_crop_quality(self, quality: str) -> StardewRule: diff --git a/worlds/stardew_valley/logic/quest_logic.py b/worlds/stardew_valley/logic/quest_logic.py index 8779848fed45..e48324680d9f 100644 --- a/worlds/stardew_valley/logic/quest_logic.py +++ b/worlds/stardew_valley/logic/quest_logic.py @@ -1,21 +1,6 @@ -from typing import Dict, Union +from typing import Dict from .base_logic import BaseLogicMixin, BaseLogic -from .building_logic import BuildingLogicMixin -from .combat_logic import CombatLogicMixin -from .cooking_logic import CookingLogicMixin -from .fishing_logic import FishingLogicMixin -from .has_logic import HasLogicMixin -from .mine_logic import MineLogicMixin -from .money_logic import MoneyLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .relationship_logic import RelationshipLogicMixin -from .season_logic import SeasonLogicMixin -from .skill_logic import SkillLogicMixin -from .time_logic import TimeLogicMixin -from .tool_logic import ToolLogicMixin -from .wallet_logic import WalletLogicMixin from ..stardew_rule import StardewRule, Has, True_ from ..strings.ap_names.community_upgrade_names import CommunityUpgrade from ..strings.artisan_good_names import ArtisanGood @@ -43,9 +28,7 @@ def __init__(self, *args, **kwargs): self.quest = QuestLogic(*args, **kwargs) -class QuestLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, MoneyLogicMixin, MineLogicMixin, RegionLogicMixin, RelationshipLogicMixin, ToolLogicMixin, - FishingLogicMixin, CookingLogicMixin, CombatLogicMixin, SeasonLogicMixin, SkillLogicMixin, WalletLogicMixin, QuestLogicMixin, - BuildingLogicMixin, TimeLogicMixin]]): +class QuestLogic(BaseLogic): def initialize_rules(self): self.update_rules({ diff --git a/worlds/stardew_valley/logic/received_logic.py b/worlds/stardew_valley/logic/received_logic.py index f5c5c9f7a206..68d65040c76a 100644 --- a/worlds/stardew_valley/logic/received_logic.py +++ b/worlds/stardew_valley/logic/received_logic.py @@ -8,7 +8,7 @@ from ..stardew_rule import StardewRule, Received, TotalReceived -class ReceivedLogicMixin(BaseLogic[HasLogicMixin], BaseLogicMixin): +class ReceivedLogicMixin(BaseLogic, BaseLogicMixin): def received(self, item: str, count: Optional[int] = 1) -> StardewRule: assert count >= 0, "Can't receive a negative amount of item." diff --git a/worlds/stardew_valley/logic/region_logic.py b/worlds/stardew_valley/logic/region_logic.py index 69afa624f22c..083f56e1676c 100644 --- a/worlds/stardew_valley/logic/region_logic.py +++ b/worlds/stardew_valley/logic/region_logic.py @@ -29,7 +29,7 @@ def __init__(self, *args, **kwargs): self.region = RegionLogic(*args, **kwargs) -class RegionLogic(BaseLogic[Union[RegionLogicMixin, HasLogicMixin]]): +class RegionLogic(BaseLogic): @cache_self1 def can_reach(self, region_name: str) -> StardewRule: diff --git a/worlds/stardew_valley/logic/relationship_logic.py b/worlds/stardew_valley/logic/relationship_logic.py index 2de82bf972cf..e19a6e802b14 100644 --- a/worlds/stardew_valley/logic/relationship_logic.py +++ b/worlds/stardew_valley/logic/relationship_logic.py @@ -1,16 +1,8 @@ import math -import typing from typing import Union from Utils import cache_self1 from .base_logic import BaseLogic, BaseLogicMixin -from .building_logic import BuildingLogicMixin -from .gift_logic import GiftLogicMixin -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .season_logic import SeasonLogicMixin -from .time_logic import TimeLogicMixin from ..content.feature import friendsanity from ..data.villagers_data import Villager from ..stardew_rule import StardewRule, True_, false_, true_ @@ -22,11 +14,6 @@ from ..strings.season_names import Season from ..strings.villager_names import NPC, ModNPC -if typing.TYPE_CHECKING: - from ..mods.logic.mod_logic import ModLogicMixin -else: - ModLogicMixin = object - possible_kids = ("Cute Baby", "Ugly Baby") @@ -43,8 +30,7 @@ def __init__(self, *args, **kwargs): self.relationship = RelationshipLogic(*args, **kwargs) -class RelationshipLogic(BaseLogic[Union[RelationshipLogicMixin, BuildingLogicMixin, SeasonLogicMixin, TimeLogicMixin, GiftLogicMixin, RegionLogicMixin, -ReceivedLogicMixin, HasLogicMixin, ModLogicMixin]]): +class RelationshipLogic(BaseLogic): def can_date(self, npc: str) -> StardewRule: return self.logic.relationship.has_hearts(npc, 8) & self.logic.has(Gift.bouquet) diff --git a/worlds/stardew_valley/logic/requirement_logic.py b/worlds/stardew_valley/logic/requirement_logic.py index 3e83950d5484..1a71810003b0 100644 --- a/worlds/stardew_valley/logic/requirement_logic.py +++ b/worlds/stardew_valley/logic/requirement_logic.py @@ -1,20 +1,7 @@ import functools -from typing import Union, Iterable +from typing import Iterable from .base_logic import BaseLogicMixin, BaseLogic -from .book_logic import BookLogicMixin -from .combat_logic import CombatLogicMixin -from .fishing_logic import FishingLogicMixin -from .has_logic import HasLogicMixin -from .quest_logic import QuestLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .relationship_logic import RelationshipLogicMixin -from .season_logic import SeasonLogicMixin -from .skill_logic import SkillLogicMixin -from .time_logic import TimeLogicMixin -from .tool_logic import ToolLogicMixin -from .walnut_logic import WalnutLogicMixin from ..data.game_item import Requirement from ..data.requirement import ToolRequirement, BookRequirement, SkillRequirement, SeasonRequirement, YearRequirement, CombatRequirement, QuestRequirement, \ RelationshipRequirement, FishingRequirement, WalnutRequirement, RegionRequirement @@ -26,8 +13,7 @@ def __init__(self, *args, **kwargs): self.requirement = RequirementLogic(*args, **kwargs) -class RequirementLogic(BaseLogic[Union[RequirementLogicMixin, HasLogicMixin, ReceivedLogicMixin, ToolLogicMixin, SkillLogicMixin, BookLogicMixin, -SeasonLogicMixin, TimeLogicMixin, CombatLogicMixin, QuestLogicMixin, RelationshipLogicMixin, FishingLogicMixin, WalnutLogicMixin, RegionLogicMixin]]): +class RequirementLogic(BaseLogic): def meet_all_requirements(self, requirements: Iterable[Requirement]): if not requirements: diff --git a/worlds/stardew_valley/logic/season_logic.py b/worlds/stardew_valley/logic/season_logic.py index 6df315c0db94..eecfd485823e 100644 --- a/worlds/stardew_valley/logic/season_logic.py +++ b/worlds/stardew_valley/logic/season_logic.py @@ -18,7 +18,7 @@ def __init__(self, *args, **kwargs): self.season = SeasonLogic(*args, **kwargs) -class SeasonLogic(BaseLogic[Union[HasLogicMixin, SeasonLogicMixin, TimeLogicMixin, ReceivedLogicMixin]]): +class SeasonLogic(BaseLogic): @cached_property def has_spring(self) -> StardewRule: diff --git a/worlds/stardew_valley/logic/shipping_logic.py b/worlds/stardew_valley/logic/shipping_logic.py index d509cc41679b..9f5ff51876e7 100644 --- a/worlds/stardew_valley/logic/shipping_logic.py +++ b/worlds/stardew_valley/logic/shipping_logic.py @@ -20,7 +20,7 @@ def __init__(self, *args, **kwargs): self.shipping = ShippingLogic(*args, **kwargs) -class ShippingLogic(BaseLogic[Union[ReceivedLogicMixin, ShippingLogicMixin, BuildingLogicMixin, RegionLogicMixin, HasLogicMixin]]): +class ShippingLogic(BaseLogic): @cached_property def can_use_shipping_bin(self) -> StardewRule: diff --git a/worlds/stardew_valley/logic/skill_logic.py b/worlds/stardew_valley/logic/skill_logic.py index 6d0cd11baf71..e02b180f6a41 100644 --- a/worlds/stardew_valley/logic/skill_logic.py +++ b/worlds/stardew_valley/logic/skill_logic.py @@ -1,19 +1,9 @@ -import typing from functools import cached_property from typing import Union, Tuple from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic -from .combat_logic import CombatLogicMixin -from .harvesting_logic import HarvestingLogicMixin -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .season_logic import SeasonLogicMixin -from .time_logic import TimeLogicMixin -from .tool_logic import ToolLogicMixin from ..data.harvest import HarvestCropSource -from ..mods.logic.magic_logic import MagicLogicMixin from ..mods.logic.mod_skills_levels import get_mod_skill_levels from ..stardew_rule import StardewRule, true_, True_, False_ from ..strings.craftable_names import Fishing @@ -25,11 +15,6 @@ from ..strings.tool_names import ToolMaterial, Tool from ..strings.wallet_item_names import Wallet -if typing.TYPE_CHECKING: - from ..mods.logic.mod_logic import ModLogicMixin -else: - ModLogicMixin = object - fishing_regions = (Region.beach, Region.town, Region.forest, Region.mountain, Region.island_south, Region.island_west) vanilla_skill_items = ("Farming Level", "Mining Level", "Foraging Level", "Fishing Level", "Combat Level") @@ -40,8 +25,7 @@ def __init__(self, *args, **kwargs): self.skill = SkillLogic(*args, **kwargs) -class SkillLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, RegionLogicMixin, SeasonLogicMixin, TimeLogicMixin, ToolLogicMixin, SkillLogicMixin, -CombatLogicMixin, MagicLogicMixin, HarvestingLogicMixin, ModLogicMixin]]): +class SkillLogic(BaseLogic): # Should be cached def can_earn_level(self, skill: str, level: int) -> StardewRule: diff --git a/worlds/stardew_valley/logic/source_logic.py b/worlds/stardew_valley/logic/source_logic.py index 67ce55177c4c..ecdb6f02a397 100644 --- a/worlds/stardew_valley/logic/source_logic.py +++ b/worlds/stardew_valley/logic/source_logic.py @@ -1,17 +1,7 @@ import functools -from typing import Union, Any, Iterable +from typing import Any, Iterable -from .animal_logic import AnimalLogicMixin -from .artisan_logic import ArtisanLogicMixin from .base_logic import BaseLogicMixin, BaseLogic -from .grind_logic import GrindLogicMixin -from .harvesting_logic import HarvestingLogicMixin -from .has_logic import HasLogicMixin -from .money_logic import MoneyLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .requirement_logic import RequirementLogicMixin -from .tool_logic import ToolLogicMixin from ..data.animal import IncubatorSource, OstrichIncubatorSource from ..data.artisan import MachineSource from ..data.game_item import GenericSource, Source, GameItem, CustomRuleSource @@ -26,8 +16,7 @@ def __init__(self, *args, **kwargs): self.source = SourceLogic(*args, **kwargs) -class SourceLogic(BaseLogic[Union[SourceLogicMixin, HasLogicMixin, ReceivedLogicMixin, HarvestingLogicMixin, MoneyLogicMixin, RegionLogicMixin, -ArtisanLogicMixin, ToolLogicMixin, RequirementLogicMixin, GrindLogicMixin, AnimalLogicMixin]]): +class SourceLogic(BaseLogic): def has_access_to_item(self, item: GameItem): rules = [] diff --git a/worlds/stardew_valley/logic/special_order_logic.py b/worlds/stardew_valley/logic/special_order_logic.py index 8bcd78d7d26e..a81f715c4866 100644 --- a/worlds/stardew_valley/logic/special_order_logic.py +++ b/worlds/stardew_valley/logic/special_order_logic.py @@ -1,22 +1,6 @@ -from typing import Dict, Union +from typing import Dict -from .ability_logic import AbilityLogicMixin -from .arcade_logic import ArcadeLogicMixin -from .artisan_logic import ArtisanLogicMixin from .base_logic import BaseLogicMixin, BaseLogic -from .cooking_logic import CookingLogicMixin -from .has_logic import HasLogicMixin -from .mine_logic import MineLogicMixin -from .money_logic import MoneyLogicMixin -from .monster_logic import MonsterLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .relationship_logic import RelationshipLogicMixin -from .season_logic import SeasonLogicMixin -from .shipping_logic import ShippingLogicMixin -from .skill_logic import SkillLogicMixin -from .time_logic import TimeLogicMixin -from .tool_logic import ToolLogicMixin from ..content.vanilla.ginger_island import ginger_island_content_pack from ..content.vanilla.qi_board import qi_board_content_pack from ..stardew_rule import StardewRule, Has, false_ @@ -44,10 +28,7 @@ def __init__(self, *args, **kwargs): self.special_order = SpecialOrderLogic(*args, **kwargs) -class SpecialOrderLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, RegionLogicMixin, SeasonLogicMixin, TimeLogicMixin, MoneyLogicMixin, -ShippingLogicMixin, ArcadeLogicMixin, ArtisanLogicMixin, RelationshipLogicMixin, ToolLogicMixin, SkillLogicMixin, -MineLogicMixin, CookingLogicMixin, -AbilityLogicMixin, SpecialOrderLogicMixin, MonsterLogicMixin]]): +class SpecialOrderLogic(BaseLogic): def initialize_rules(self): self.update_rules({ diff --git a/worlds/stardew_valley/logic/time_logic.py b/worlds/stardew_valley/logic/time_logic.py index 2ba76579ff45..d26723d2a58b 100644 --- a/worlds/stardew_valley/logic/time_logic.py +++ b/worlds/stardew_valley/logic/time_logic.py @@ -22,7 +22,7 @@ def __init__(self, *args, **kwargs): self.time = TimeLogic(*args, **kwargs) -class TimeLogic(BaseLogic[Union[TimeLogicMixin, HasLogicMixin]]): +class TimeLogic(BaseLogic): @cache_self1 def has_lived_months(self, number: int) -> StardewRule: diff --git a/worlds/stardew_valley/logic/tool_logic.py b/worlds/stardew_valley/logic/tool_logic.py index 8292325af7d8..dba8bb29804c 100644 --- a/worlds/stardew_valley/logic/tool_logic.py +++ b/worlds/stardew_valley/logic/tool_logic.py @@ -2,12 +2,6 @@ from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic -from .has_logic import HasLogicMixin -from .money_logic import MoneyLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .season_logic import SeasonLogicMixin -from ..mods.logic.magic_logic import MagicLogicMixin from ..stardew_rule import StardewRule, True_, False_ from ..strings.ap_names.skill_level_names import ModSkillLevel from ..strings.region_names import Region, LogicRegion @@ -40,7 +34,7 @@ def __init__(self, *args, **kwargs): self.tool = ToolLogic(*args, **kwargs) -class ToolLogic(BaseLogic[Union[ToolLogicMixin, HasLogicMixin, ReceivedLogicMixin, RegionLogicMixin, SeasonLogicMixin, MoneyLogicMixin, MagicLogicMixin]]): +class ToolLogic(BaseLogic): def has_all_tools(self, tools: Iterable[Tuple[str, str]]): return self.logic.and_(*(self.logic.tool.has_tool(tool, material) for tool, material in tools)) diff --git a/worlds/stardew_valley/logic/traveling_merchant_logic.py b/worlds/stardew_valley/logic/traveling_merchant_logic.py index 4123ded5bf24..743ff9949bec 100644 --- a/worlds/stardew_valley/logic/traveling_merchant_logic.py +++ b/worlds/stardew_valley/logic/traveling_merchant_logic.py @@ -12,7 +12,7 @@ def __init__(self, *args, **kwargs): self.traveling_merchant = TravelingMerchantLogic(*args, **kwargs) -class TravelingMerchantLogic(BaseLogic[Union[TravelingMerchantLogicMixin, ReceivedLogicMixin]]): +class TravelingMerchantLogic(BaseLogic): def has_days(self, number_days: int = 1): if number_days <= 0: diff --git a/worlds/stardew_valley/logic/wallet_logic.py b/worlds/stardew_valley/logic/wallet_logic.py index 3a6d12640028..eb7afb9af300 100644 --- a/worlds/stardew_valley/logic/wallet_logic.py +++ b/worlds/stardew_valley/logic/wallet_logic.py @@ -10,7 +10,7 @@ def __init__(self, *args, **kwargs): self.wallet = WalletLogic(*args, **kwargs) -class WalletLogic(BaseLogic[ReceivedLogicMixin]): +class WalletLogic(BaseLogic): def can_speak_dwarf(self) -> StardewRule: return self.logic.received(Wallet.dwarvish_translation_guide) diff --git a/worlds/stardew_valley/logic/walnut_logic.py b/worlds/stardew_valley/logic/walnut_logic.py index 4ab3b46f70d9..fb83b6590717 100644 --- a/worlds/stardew_valley/logic/walnut_logic.py +++ b/worlds/stardew_valley/logic/walnut_logic.py @@ -1,12 +1,6 @@ from functools import cached_property -from typing import Union -from .ability_logic import AbilityLogicMixin from .base_logic import BaseLogic, BaseLogicMixin -from .combat_logic import CombatLogicMixin -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin from ..options import ExcludeGingerIsland, Walnutsanity from ..stardew_rule import StardewRule, False_, True_ from ..strings.ap_names.ap_option_names import WalnutsanityOptionName @@ -24,8 +18,7 @@ def __init__(self, *args, **kwargs): self.walnut = WalnutLogic(*args, **kwargs) -class WalnutLogic(BaseLogic[Union[WalnutLogicMixin, ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, CombatLogicMixin, -AbilityLogicMixin]]): +class WalnutLogic(BaseLogic): def has_walnut(self, number: int) -> StardewRule: if self.options.exclude_ginger_island == ExcludeGingerIsland.option_true: diff --git a/worlds/stardew_valley/mods/logic/deepwoods_logic.py b/worlds/stardew_valley/mods/logic/deepwoods_logic.py index 6e0eadfd5486..17db3c0a6fe5 100644 --- a/worlds/stardew_valley/mods/logic/deepwoods_logic.py +++ b/worlds/stardew_valley/mods/logic/deepwoods_logic.py @@ -1,13 +1,5 @@ -from typing import Union - +from ..mod_data import ModNames from ...logic.base_logic import BaseLogicMixin, BaseLogic -from ...logic.combat_logic import CombatLogicMixin -from ...logic.cooking_logic import CookingLogicMixin -from ...logic.has_logic import HasLogicMixin -from ...logic.received_logic import ReceivedLogicMixin -from ...logic.skill_logic import SkillLogicMixin -from ...logic.tool_logic import ToolLogicMixin -from ...mods.mod_data import ModNames from ...options import ElevatorProgression from ...stardew_rule import StardewRule, True_, true_ from ...strings.ap_names.mods.mod_items import DeepWoodsItem @@ -25,8 +17,7 @@ def __init__(self, *args, **kwargs): self.deepwoods = DeepWoodsLogic(*args, **kwargs) -class DeepWoodsLogic(BaseLogic[Union[SkillLogicMixin, ReceivedLogicMixin, HasLogicMixin, CombatLogicMixin, ToolLogicMixin, SkillLogicMixin, -CookingLogicMixin]]): +class DeepWoodsLogic(BaseLogic): def can_reach_woods_depth(self, depth: int) -> StardewRule: # Assuming you can always do the 10 first floor diff --git a/worlds/stardew_valley/mods/logic/elevator_logic.py b/worlds/stardew_valley/mods/logic/elevator_logic.py index f1d12bcb1c37..8e154492e4c8 100644 --- a/worlds/stardew_valley/mods/logic/elevator_logic.py +++ b/worlds/stardew_valley/mods/logic/elevator_logic.py @@ -1,5 +1,4 @@ from ...logic.base_logic import BaseLogicMixin, BaseLogic -from ...logic.received_logic import ReceivedLogicMixin from ...mods.mod_data import ModNames from ...options import ElevatorProgression from ...stardew_rule import StardewRule, True_ @@ -11,7 +10,7 @@ def __init__(self, *args, **kwargs): self.elevator = ModElevatorLogic(*args, **kwargs) -class ModElevatorLogic(BaseLogic[ReceivedLogicMixin]): +class ModElevatorLogic(BaseLogic): def has_skull_cavern_elevator_to_floor(self, floor: int) -> StardewRule: if self.options.elevator_progression != ElevatorProgression.option_vanilla and ModNames.skull_cavern_elevator in self.options.mods: return self.logic.received("Progressive Skull Cavern Elevator", floor // 25) diff --git a/worlds/stardew_valley/mods/logic/item_logic.py b/worlds/stardew_valley/mods/logic/item_logic.py index fd87a4a0aceb..7394d82ba138 100644 --- a/worlds/stardew_valley/mods/logic/item_logic.py +++ b/worlds/stardew_valley/mods/logic/item_logic.py @@ -1,23 +1,7 @@ -from typing import Dict, Union +from typing import Dict from ..mod_data import ModNames from ...logic.base_logic import BaseLogicMixin, BaseLogic -from ...logic.combat_logic import CombatLogicMixin -from ...logic.cooking_logic import CookingLogicMixin -from ...logic.crafting_logic import CraftingLogicMixin -from ...logic.farming_logic import FarmingLogicMixin -from ...logic.fishing_logic import FishingLogicMixin -from ...logic.has_logic import HasLogicMixin -from ...logic.money_logic import MoneyLogicMixin -from ...logic.museum_logic import MuseumLogicMixin -from ...logic.quest_logic import QuestLogicMixin -from ...logic.received_logic import ReceivedLogicMixin -from ...logic.region_logic import RegionLogicMixin -from ...logic.relationship_logic import RelationshipLogicMixin -from ...logic.season_logic import SeasonLogicMixin -from ...logic.skill_logic import SkillLogicMixin -from ...logic.time_logic import TimeLogicMixin -from ...logic.tool_logic import ToolLogicMixin from ...stardew_rule import StardewRule from ...strings.artisan_good_names import ModArtisanGood from ...strings.craftable_names import ModCraftable @@ -39,9 +23,7 @@ def __init__(self, *args, **kwargs): self.item = ModItemLogic(*args, **kwargs) -class ModItemLogic(BaseLogic[Union[CombatLogicMixin, ReceivedLogicMixin, CookingLogicMixin, FishingLogicMixin, HasLogicMixin, MoneyLogicMixin, -RegionLogicMixin, SeasonLogicMixin, RelationshipLogicMixin, MuseumLogicMixin, ToolLogicMixin, CraftingLogicMixin, SkillLogicMixin, TimeLogicMixin, QuestLogicMixin, -FarmingLogicMixin]]): +class ModItemLogic(BaseLogic): def get_modded_item_rules(self) -> Dict[str, StardewRule]: items = dict() diff --git a/worlds/stardew_valley/mods/logic/magic_logic.py b/worlds/stardew_valley/mods/logic/magic_logic.py index 662ff3acaeb6..2e3a0e1f97b2 100644 --- a/worlds/stardew_valley/mods/logic/magic_logic.py +++ b/worlds/stardew_valley/mods/logic/magic_logic.py @@ -1,9 +1,4 @@ -from typing import Union - from ...logic.base_logic import BaseLogicMixin, BaseLogic -from ...logic.has_logic import HasLogicMixin -from ...logic.received_logic import ReceivedLogicMixin -from ...logic.region_logic import RegionLogicMixin from ...mods.mod_data import ModNames from ...stardew_rule import StardewRule, False_ from ...strings.ap_names.skill_level_names import ModSkillLevel @@ -18,7 +13,7 @@ def __init__(self, *args, **kwargs): # TODO add logic.mods.magic for altar -class MagicLogic(BaseLogic[Union[RegionLogicMixin, ReceivedLogicMixin, HasLogicMixin]]): +class MagicLogic(BaseLogic): def can_use_clear_debris_instead_of_tool_level(self, level: int) -> StardewRule: if ModNames.magic not in self.options.mods: return False_() diff --git a/worlds/stardew_valley/mods/logic/quests_logic.py b/worlds/stardew_valley/mods/logic/quests_logic.py index ef9698266147..8b1eca7fc213 100644 --- a/worlds/stardew_valley/mods/logic/quests_logic.py +++ b/worlds/stardew_valley/mods/logic/quests_logic.py @@ -1,15 +1,7 @@ -from typing import Dict, Union +from typing import Dict from ..mod_data import ModNames from ...logic.base_logic import BaseLogic, BaseLogicMixin -from ...logic.has_logic import HasLogicMixin -from ...logic.monster_logic import MonsterLogicMixin -from ...logic.quest_logic import QuestLogicMixin -from ...logic.received_logic import ReceivedLogicMixin -from ...logic.region_logic import RegionLogicMixin -from ...logic.relationship_logic import RelationshipLogicMixin -from ...logic.season_logic import SeasonLogicMixin -from ...logic.time_logic import TimeLogicMixin from ...stardew_rule import StardewRule from ...strings.animal_product_names import AnimalProduct from ...strings.ap_names.mods.mod_items import SVEQuestItem @@ -34,8 +26,7 @@ def __init__(self, *args, **kwargs): self.quest = ModQuestLogic(*args, **kwargs) -class ModQuestLogic(BaseLogic[Union[HasLogicMixin, QuestLogicMixin, ReceivedLogicMixin, RegionLogicMixin, -TimeLogicMixin, SeasonLogicMixin, RelationshipLogicMixin, MonsterLogicMixin]]): +class ModQuestLogic(BaseLogic): def get_modded_quest_rules(self) -> Dict[str, StardewRule]: quests = dict() quests.update(self._get_juna_quest_rules()) diff --git a/worlds/stardew_valley/mods/logic/skills_logic.py b/worlds/stardew_valley/mods/logic/skills_logic.py index ba9d27741807..b1f10d08b97e 100644 --- a/worlds/stardew_valley/mods/logic/skills_logic.py +++ b/worlds/stardew_valley/mods/logic/skills_logic.py @@ -1,17 +1,4 @@ -from typing import Union - -from .magic_logic import MagicLogicMixin -from ...logic.action_logic import ActionLogicMixin from ...logic.base_logic import BaseLogicMixin, BaseLogic -from ...logic.building_logic import BuildingLogicMixin -from ...logic.cooking_logic import CookingLogicMixin -from ...logic.crafting_logic import CraftingLogicMixin -from ...logic.fishing_logic import FishingLogicMixin -from ...logic.has_logic import HasLogicMixin -from ...logic.received_logic import ReceivedLogicMixin -from ...logic.region_logic import RegionLogicMixin -from ...logic.relationship_logic import RelationshipLogicMixin -from ...logic.tool_logic import ToolLogicMixin from ...mods.mod_data import ModNames from ...stardew_rule import StardewRule, False_, True_, And from ...strings.building_names import Building @@ -30,8 +17,7 @@ def __init__(self, *args, **kwargs): self.skill = ModSkillLogic(*args, **kwargs) -class ModSkillLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, RegionLogicMixin, ActionLogicMixin, RelationshipLogicMixin, BuildingLogicMixin, -ToolLogicMixin, FishingLogicMixin, CookingLogicMixin, CraftingLogicMixin, MagicLogicMixin]]): +class ModSkillLogic(BaseLogic): def has_mod_level(self, skill: str, level: int) -> StardewRule: if level <= 0: return True_() diff --git a/worlds/stardew_valley/mods/logic/special_orders_logic.py b/worlds/stardew_valley/mods/logic/special_orders_logic.py index 1a0934282e09..f697661419a9 100644 --- a/worlds/stardew_valley/mods/logic/special_orders_logic.py +++ b/worlds/stardew_valley/mods/logic/special_orders_logic.py @@ -1,17 +1,6 @@ -from typing import Union - from ..mod_data import ModNames from ...data.craftable_data import all_crafting_recipes_by_name -from ...logic.action_logic import ActionLogicMixin -from ...logic.artisan_logic import ArtisanLogicMixin from ...logic.base_logic import BaseLogicMixin, BaseLogic -from ...logic.crafting_logic import CraftingLogicMixin -from ...logic.has_logic import HasLogicMixin -from ...logic.received_logic import ReceivedLogicMixin -from ...logic.region_logic import RegionLogicMixin -from ...logic.relationship_logic import RelationshipLogicMixin -from ...logic.season_logic import SeasonLogicMixin -from ...logic.wallet_logic import WalletLogicMixin from ...strings.ap_names.community_upgrade_names import CommunityUpgrade from ...strings.artisan_good_names import ArtisanGood from ...strings.craftable_names import Consumable, Edible, Bomb @@ -33,8 +22,7 @@ def __init__(self, *args, **kwargs): self.special_order = ModSpecialOrderLogic(*args, **kwargs) -class ModSpecialOrderLogic(BaseLogic[Union[ActionLogicMixin, ArtisanLogicMixin, CraftingLogicMixin, HasLogicMixin, RegionLogicMixin, -ReceivedLogicMixin, RelationshipLogicMixin, SeasonLogicMixin, WalletLogicMixin]]): +class ModSpecialOrderLogic(BaseLogic): def get_modded_special_orders_rules(self): special_orders = {} if ModNames.juna in self.options.mods: diff --git a/worlds/stardew_valley/mods/logic/sve_logic.py b/worlds/stardew_valley/mods/logic/sve_logic.py index faca8d332d22..7f0c12bc4f1e 100644 --- a/worlds/stardew_valley/mods/logic/sve_logic.py +++ b/worlds/stardew_valley/mods/logic/sve_logic.py @@ -1,21 +1,7 @@ -from typing import Union - from ..mod_regions import SVERegion from ...logic.base_logic import BaseLogicMixin, BaseLogic -from ...logic.combat_logic import CombatLogicMixin -from ...logic.cooking_logic import CookingLogicMixin -from ...logic.has_logic import HasLogicMixin -from ...logic.money_logic import MoneyLogicMixin -from ...logic.quest_logic import QuestLogicMixin -from ...logic.received_logic import ReceivedLogicMixin -from ...logic.region_logic import RegionLogicMixin -from ...logic.relationship_logic import RelationshipLogicMixin -from ...logic.season_logic import SeasonLogicMixin -from ...logic.time_logic import TimeLogicMixin -from ...logic.tool_logic import ToolLogicMixin from ...strings.ap_names.mods.mod_items import SVELocation, SVERunes, SVEQuestItem -from ...strings.quest_names import ModQuest -from ...strings.quest_names import Quest +from ...strings.quest_names import Quest, ModQuest from ...strings.region_names import Region from ...strings.tool_names import Tool, ToolMaterial from ...strings.wallet_item_names import Wallet @@ -27,8 +13,7 @@ def __init__(self, *args, **kwargs): self.sve = SVELogic(*args, **kwargs) -class SVELogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, QuestLogicMixin, RegionLogicMixin, RelationshipLogicMixin, TimeLogicMixin, ToolLogicMixin, - CookingLogicMixin, MoneyLogicMixin, CombatLogicMixin, SeasonLogicMixin]]): +class SVELogic(BaseLogic): def initialize_rules(self): self.registry.sve_location_rules.update({ SVELocation.tempered_galaxy_sword: self.logic.money.can_spend_at(SVERegion.alesia_shop, 350000), From 73964b374c6d502b588e33c6c3c93045f267920b Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Wed, 23 Apr 2025 15:40:36 +0000 Subject: [PATCH 0354/1218] MultiServer: import get_settings from the correct module (#4914) * MultiServer: import get_settings from the correct module * MultiServer: settings: use attr inbstead of dict access --- MultiServer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MultiServer.py b/MultiServer.py index 4295f28c58e8..bdc6b8c84f1e 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -2419,8 +2419,10 @@ async def console(ctx: Context): def parse_args() -> argparse.Namespace: + from settings import get_settings + parser = argparse.ArgumentParser() - defaults = Utils.get_settings()["server_options"].as_dict() + defaults = get_settings().server_options.as_dict() parser.add_argument('multidata', nargs="?", default=defaults["multidata"]) parser.add_argument('--host', default=defaults["host"]) parser.add_argument('--port', default=defaults["port"], type=int) From febd280fba57c2d015b7e9c8a820150b11268ec8 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 23 Apr 2025 20:30:15 +0200 Subject: [PATCH 0355/1218] Setup: use sha256 for timestamp server (#4892) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 00a65330a019..ebef215e2dc9 100644 --- a/setup.py +++ b/setup.py @@ -154,7 +154,7 @@ def download_SNI() -> None: with open("X:/pw.txt", encoding="utf-8-sig") as f: pw = f.read() signtool = r'signtool sign /f X:/_SITS_Zertifikat_.pfx /p "' + pw + \ - r'" /fd sha256 /tr http://timestamp.digicert.com/ ' + r'" /fd sha256 /td sha256 /tr http://timestamp.digicert.com/ ' else: signtool = None From 29e6a10e4271ad5ae024acc32051a102c2f0eed2 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Thu, 24 Apr 2025 08:50:34 +0200 Subject: [PATCH 0356/1218] Setup: offer the default-on option to clean /lib folder on update (#4890) Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- inno_setup.iss | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/inno_setup.iss b/inno_setup.iss index 9d03ca7baf5e..adf9acc83409 100644 --- a/inno_setup.iss +++ b/inno_setup.iss @@ -45,7 +45,8 @@ MinVersion={#min_windows} Name: "english"; MessagesFile: "compiler:Default.isl" [Tasks] -Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; +Name: "deletelib"; Description: "Clean existing /lib folder and subfolders including /worlds (leave checked if unsure)"; Check: ShouldShowDeleteLibTask [Types] Name: "full"; Description: "Full installation" @@ -83,18 +84,8 @@ Filename: "{app}\ArchipelagoLauncher"; Description: "{cm:LaunchProgram,{#StringC Type: dirifempty; Name: "{app}" [InstallDelete] -Type: files; Name: "{app}\lib\worlds\_bizhawk.apworld" -Type: files; Name: "{app}\ArchipelagoLttPClient.exe" -Type: files; Name: "{app}\ArchipelagoPokemonClient.exe" +Type: files; Name: "{app}\*.exe" Type: files; Name: "{app}\data\lua\connector_pkmn_rb.lua" -Type: filesandordirs; Name: "{app}\lib\worlds\rogue-legacy" -Type: dirifempty; Name: "{app}\lib\worlds\rogue-legacy" -Type: files; Name: "{app}\lib\worlds\sc2wol.apworld" -Type: filesandordirs; Name: "{app}\lib\worlds\sc2wol" -Type: dirifempty; Name: "{app}\lib\worlds\sc2wol" -Type: filesandordirs; Name: "{app}\lib\worlds\bk_sudoku" -Type: dirifempty; Name: "{app}\lib\worlds\bk_sudoku" -Type: files; Name: "{app}\ArchipelagoLauncher(DEBUG).exe" Type: filesandordirs; Name: "{app}\SNI\lua*" Type: filesandordirs; Name: "{app}\EnemizerCLI*" #include "installdelete.iss" @@ -261,3 +252,17 @@ begin Result := True; end; end; + +function ShouldShowDeleteLibTask: Boolean; +begin + Result := DirExists(ExpandConstant('{app}\lib')); +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if CurStep = ssInstall then + begin + if WizardIsTaskSelected('deletelib') then + DelTree(ExpandConstant('{app}\lib'), True, True, True); + end; +end; From a84366368f8509485b44e109c775183e8022aefc Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Thu, 24 Apr 2025 09:38:30 -0400 Subject: [PATCH 0357/1218] Docs: Update comment for create_item (#4919) --- docs/world api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/world api.md b/docs/world api.md index e55d4fb9f547..013b02cc2076 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -561,7 +561,7 @@ from .items import is_progression # this is just a dummy def create_item(self, item: str) -> MyGameItem: - # this is called when AP wants to create an item by name (for plando) or when you call it from your own code + # this is called when AP wants to create an item by name (for plando, start inventory, item links) or when you call it from your own code classification = ItemClassification.progression if is_progression(item) else ItemClassification.filler return MyGameItem(item, classification, self.item_name_to_id[item], self.player) From 03768a5f90b44bafc7ca5a37aed7f46067bb8732 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 24 Apr 2025 14:23:51 -0500 Subject: [PATCH 0358/1218] Tests: Test that a world can generate with item links (#2081) Co-authored-by: Fabian Dill Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- test/general/test_items.py | 49 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/test/general/test_items.py b/test/general/test_items.py index f9488e1b250b..1b376b28385c 100644 --- a/test/general/test_items.py +++ b/test/general/test_items.py @@ -1,7 +1,11 @@ import unittest +from argparse import Namespace +from typing import Type -from BaseClasses import CollectionState -from worlds.AutoWorld import AutoWorldRegister, call_all +from BaseClasses import CollectionState, MultiWorld +from Fill import distribute_items_restrictive +from Options import ItemLinks +from worlds.AutoWorld import AutoWorldRegister, World, call_all from . import setup_solo_multiworld @@ -83,6 +87,47 @@ def test_items_in_datapackage(self): multiworld = setup_solo_multiworld(world_type) for item in multiworld.itempool: self.assertIn(item.name, world_type.item_name_to_id) + + def test_item_links(self) -> None: + """ + Tests item link creation by creating a multiworld of 2 worlds for every game and linking their items together. + """ + def setup_link_multiworld(world: Type[World], link_replace: bool) -> None: + multiworld = MultiWorld(2) + multiworld.game = {1: world.game, 2: world.game} + multiworld.player_name = {1: "Linker 1", 2: "Linker 2"} + multiworld.set_seed() + item_link_group = [{ + "name": "ItemLinkTest", + "item_pool": ["Everything"], + "link_replacement": link_replace, + "replacement_item": None, + }] + args = Namespace() + for name, option in world.options_dataclass.type_hints.items(): + setattr(args, name, {1: option.from_any(option.default), 2: option.from_any(option.default)}) + setattr(args, "item_links", + {1: ItemLinks.from_any(item_link_group), 2: ItemLinks.from_any(item_link_group)}) + multiworld.set_options(args) + multiworld.set_item_links() + # groups get added to state during its constructor so this has to be after item links are set + multiworld.state = CollectionState(multiworld) + gen_steps = ("generate_early", "create_regions", "create_items", "set_rules", "connect_entrances", "generate_basic") + for step in gen_steps: + call_all(multiworld, step) + # link the items together and attempt to fill + multiworld.link_items() + multiworld._all_state = None + call_all(multiworld, "pre_fill") + distribute_items_restrictive(multiworld) + call_all(multiworld, "post_fill") + self.assertTrue(multiworld.can_beat_game(CollectionState(multiworld)), f"seed = {multiworld.seed}") + + for game_name, world_type in AutoWorldRegister.world_types.items(): + with self.subTest("Can generate with link replacement", game=game_name): + setup_link_multiworld(world_type, True) + with self.subTest("Can generate without link replacement", game=game_name): + setup_link_multiworld(world_type, False) def test_itempool_not_modified(self): """Test that worlds don't modify the itempool after `create_items`""" From 5bb87c6da5b38f097ff49342470f82cd8b8a140a Mon Sep 17 00:00:00 2001 From: Jarno Date: Thu, 24 Apr 2025 21:33:30 +0200 Subject: [PATCH 0359/1218] Tests: Make overlapping test actually print out the overlaps (#4431) --- test/general/test_ids.py | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/test/general/test_ids.py b/test/general/test_ids.py index e51a070c1fd7..ad8aad11d15c 100644 --- a/test/general/test_ids.py +++ b/test/general/test_ids.py @@ -47,13 +47,39 @@ def test_duplicate_item_ids(self): """Test that a game doesn't have item id overlap within its own datapackage""" for gamename, world_type in AutoWorldRegister.world_types.items(): with self.subTest(game=gamename): - self.assertEqual(len(world_type.item_id_to_name), len(world_type.item_name_to_id)) + len_item_id_to_name = len(world_type.item_id_to_name) + len_item_name_to_id = len(world_type.item_name_to_id) + + if len_item_id_to_name != len_item_name_to_id: + self.assertCountEqual( + world_type.item_id_to_name.values(), + world_type.item_name_to_id.keys(), + "\nThese items have overlapping ids with other items in its own world") + self.assertCountEqual( + world_type.item_id_to_name.keys(), + world_type.item_name_to_id.values(), + "\nThese items have overlapping names with other items in its own world") + + self.assertEqual(len_item_id_to_name, len_item_name_to_id) def test_duplicate_location_ids(self): """Test that a game doesn't have location id overlap within its own datapackage""" for gamename, world_type in AutoWorldRegister.world_types.items(): with self.subTest(game=gamename): - self.assertEqual(len(world_type.location_id_to_name), len(world_type.location_name_to_id)) + len_location_id_to_name = len(world_type.location_id_to_name) + len_location_name_to_id = len(world_type.location_name_to_id) + + if len_location_id_to_name != len_location_name_to_id: + self.assertCountEqual( + world_type.location_id_to_name.values(), + world_type.location_name_to_id.keys(), + "\nThese locations have overlapping ids with other locations in its own world") + self.assertCountEqual( + world_type.location_id_to_name.keys(), + world_type.location_name_to_id.values(), + "\nThese locations have overlapping names with other locations in its own world") + + self.assertEqual(len_location_id_to_name, len_location_name_to_id) def test_postgen_datapackage(self): """Generates a solo multiworld and checks that the datapackage is still valid""" From f288e3469c9fbc1a5a96fd5fdf7574fd0c58aa10 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Thu, 24 Apr 2025 21:55:48 +0200 Subject: [PATCH 0360/1218] Core: Add a function docstring to roll_settings to hopefully prevent the weights fiasco from being repeated (#3388) * Add an option docstring to roll_settings to hopefully prevent the weights fiasco from being repeated * Update Generate.py * Update Generate.py --- Generate.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Generate.py b/Generate.py index 82386644e7f9..5b5219841d66 100644 --- a/Generate.py +++ b/Generate.py @@ -456,6 +456,14 @@ def handle_option(ret: argparse.Namespace, game_weights: dict, option_key: str, def roll_settings(weights: dict, plando_options: PlandoOptions = PlandoOptions.bosses): + """ + Roll options from specified weights, usually originating from a .yaml options file. + + Important note: + The same weights dict is shared between all slots using the same yaml (e.g. generic weights file for filler slots). + This means it should never be modified without making a deepcopy first. + """ + from worlds import AutoWorldRegister if "linked_options" in weights: From e52d8b4dbdbf72050046f98bc8b0fb228b52c7f8 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Thu, 24 Apr 2025 21:56:05 +0200 Subject: [PATCH 0361/1218] The Witness: Remove first-stage requirements of progressive items from the logic files (#4257) * Remove extraneous symbol requirements * Some missed Full Dots cases * Bruh * merge error * merge error 2 --- worlds/witness/data/WitnessLogic.txt | 162 ++++---- worlds/witness/data/WitnessLogicExpert.txt | 400 ++++++++++---------- worlds/witness/data/WitnessLogicVanilla.txt | 116 +++--- worlds/witness/data/WitnessLogicVariety.txt | 252 ++++++------ 4 files changed, 465 insertions(+), 465 deletions(-) diff --git a/worlds/witness/data/WitnessLogic.txt b/worlds/witness/data/WitnessLogic.txt index edc45222b51e..3eea52b85e8d 100644 --- a/worlds/witness/data/WitnessLogic.txt +++ b/worlds/witness/data/WitnessLogic.txt @@ -52,11 +52,11 @@ Outside Tutorial Vault (Outside Tutorial): 158651 - 0x03481 (Vault Box) - True - True Outside Tutorial Path To Outpost (Outside Tutorial) - Outside Tutorial Outpost - 0x0A170: -158011 - 0x0A171 (Outpost Entry Panel) - True - Dots & Full Dots +158011 - 0x0A171 (Outpost Entry Panel) - True - Full Dots Door - 0x0A170 (Outpost Entry) - 0x0A171 Outside Tutorial Outpost (Outside Tutorial) - Outside Tutorial - 0x04CA3: -158012 - 0x04CA4 (Outpost Exit Panel) - True - Dots & Black/White Squares & Full Dots +158012 - 0x04CA4 (Outpost Exit Panel) - True - Black/White Squares & Full Dots Door - 0x04CA3 (Outpost Exit) - 0x04CA4 158600 - 0x17CFB (Discard) - True - Triangles @@ -136,12 +136,12 @@ Door - 0x18269 (Upper) - 0x1C349 159000 - 0x0332B (Glass Factory Black Line Reflection EP) - True - True Symmetry Island Upper (Symmetry Island): -158065 - 0x00A52 (Laser Yellow 1) - True - Symmetry & Colored Dots -158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Symmetry & Colored Dots -158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Symmetry & Colored Dots -158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Symmetry & Colored Dots -158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Symmetry & Colored Dots -158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Symmetry & Colored Dots +158065 - 0x00A52 (Laser Yellow 1) - True - Colored Dots +158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Colored Dots +158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Colored Dots +158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Colored Dots +158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Colored Dots +158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Colored Dots 158700 - 0x0360D (Laser Panel) - 0x00A68 - True Laser - 0x00509 (Laser) - 0x0360D 159001 - 0x03367 (Glass Factory Black Line EP) - True - True @@ -157,7 +157,7 @@ Desert Obelisk (Desert) - Entry - True: 159709 - 0x00359 (Obelisk) - True - True Desert Outside (Desert) - Main Island - True - Desert Light Room - 0x09FEE - Desert Vault - 0x03444: -158652 - 0x0CC7B (Vault Panel) - True - Dots & Shapers & Rotated Shapers & Negative Shapers & Full Dots +158652 - 0x0CC7B (Vault Panel) - True - Shapers & Rotated Shapers & Negative Shapers & Full Dots Door - 0x03444 (Vault Door) - 0x0CC7B 158602 - 0x17CE7 (Discard) - True - Triangles 158076 - 0x00698 (Surface 1) - True - True @@ -335,13 +335,13 @@ Quarry Boathouse Upper Middle (Quarry Boathouse) - Quarry Boathouse Upper Back - Quarry Boathouse Upper Back (Quarry Boathouse) - Quarry Boathouse Upper Middle - 0x3865F: 158155 - 0x38663 (Second Barrier Panel) - True - True Door - 0x3865F (Second Barrier) - 0x38663 -158156 - 0x021B5 (Back First Row 1) - True - Stars & Stars + Same Colored Symbol & Eraser -158157 - 0x021B6 (Back First Row 2) - 0x021B5 - Stars & Stars + Same Colored Symbol & Eraser -158158 - 0x021B7 (Back First Row 3) - 0x021B6 - Stars & Stars + Same Colored Symbol & Eraser -158159 - 0x021BB (Back First Row 4) - 0x021B7 - Stars & Stars + Same Colored Symbol & Eraser -158160 - 0x09DB5 (Back First Row 5) - 0x021BB - Stars & Stars + Same Colored Symbol & Eraser -158161 - 0x09DB1 (Back First Row 6) - 0x09DB5 - Stars & Stars + Same Colored Symbol & Eraser -158162 - 0x3C124 (Back First Row 7) - 0x09DB1 - Stars & Stars + Same Colored Symbol & Eraser +158156 - 0x021B5 (Back First Row 1) - True - Stars + Same Colored Symbol & Eraser +158157 - 0x021B6 (Back First Row 2) - 0x021B5 - Stars + Same Colored Symbol & Eraser +158158 - 0x021B7 (Back First Row 3) - 0x021B6 - Stars + Same Colored Symbol & Eraser +158159 - 0x021BB (Back First Row 4) - 0x021B7 - Stars + Same Colored Symbol & Eraser +158160 - 0x09DB5 (Back First Row 5) - 0x021BB - Stars + Same Colored Symbol & Eraser +158161 - 0x09DB1 (Back First Row 6) - 0x09DB5 - Stars + Same Colored Symbol & Eraser +158162 - 0x3C124 (Back First Row 7) - 0x09DB1 - Stars + Same Colored Symbol & Eraser 158163 - 0x09DB3 (Back First Row 8) - 0x3C124 - Stars & Eraser & Shapers 158164 - 0x09DB4 (Back First Row 9) - 0x09DB3 - Stars & Eraser & Shapers 158165 - 0x275FA (Hook Control) - True - Shapers & Eraser @@ -421,7 +421,7 @@ Door - 0x01A0E (Hedge Maze 4 Exit) - 0x01A0F Keep 2nd Pressure Plate (Keep) - Keep 3rd Pressure Plate - True: 158199 - 0x0A3B9 (Reset Pressure Plates 2) - True - True -158200 - 0x01BE9 (Pressure Plates 2) - 0x0A3B9 - Stars & Stars + Same Colored Symbol & Black/White Squares +158200 - 0x01BE9 (Pressure Plates 2) - 0x0A3B9 - Stars + Same Colored Symbol & Black/White Squares Door - 0x01BEA (Pressure Plates 2 Exit) - 0x01BE9 Keep 3rd Pressure Plate (Keep) - Keep 4th Pressure Plate - 0x01CD5: @@ -441,7 +441,7 @@ Keep Tower (Keep) - Keep - 0x04F8F: 158206 - 0x0361B (Tower Shortcut Panel) - True - True Door - 0x04F8F (Tower Shortcut) - 0x0361B 158704 - 0x0360E (Laser Panel Hedges) - 0x01A0F & 0x019E7 & 0x019DC & 0x00139 - True -158705 - 0x03317 (Laser Panel Pressure Plates) - 0x033EA & 0x01BE9 & 0x01CD3 & 0x01D3F - Shapers & Black/White Squares & Colored Squares & Stars & Stars + Same Colored Symbol & Dots +158705 - 0x03317 (Laser Panel Pressure Plates) - 0x033EA & 0x01BE9 & 0x01CD3 & 0x01D3F - Shapers & Black/White Squares & Colored Squares & Stars + Same Colored Symbol & Dots Laser - 0x014BB (Laser) - 0x0360E | 0x03317 159240 - 0x033BE (Pressure Plates 1 EP) - 0x033EA - True 159241 - 0x033BF (Pressure Plates 2 EP) - 0x01BE9 - True @@ -537,11 +537,11 @@ Door - 0x0A0C9 (Cargo Box Entry) - 0x0A0C8 158221 - 0x28AE3 (Vines) - 0x18590 - True 158222 - 0x28938 (Apple Tree) - 0x28AE3 - True 158223 - 0x079DF (Triple Exit) - 0x28938 - True -158235 - 0x2899C (Wooden Roof Lower Row 1) - True - Rotated Shapers & Dots & Full Dots -158236 - 0x28A33 (Wooden Roof Lower Row 2) - 0x2899C - Shapers & Dots & Full Dots -158237 - 0x28ABF (Wooden Roof Lower Row 3) - 0x28A33 - Shapers & Rotated Shapers & Dots & Full Dots -158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Rotated Shapers & Dots & Full Dots -158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Rotated Shapers & Dots & Full Dots +158235 - 0x2899C (Wooden Roof Lower Row 1) - True - Rotated Shapers & Full Dots +158236 - 0x28A33 (Wooden Roof Lower Row 2) - 0x2899C - Shapers & Full Dots +158237 - 0x28ABF (Wooden Roof Lower Row 3) - 0x28A33 - Shapers & Rotated Shapers & Full Dots +158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Rotated Shapers & Full Dots +158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Rotated Shapers & Full Dots Door - 0x034F5 (Wooden Roof Stairs) - 0x28AC1 158225 - 0x28998 (RGB House Entry Panel) - True - Stars & Rotated Shapers Door - 0x28A61 (RGB House Entry) - 0x28998 @@ -575,7 +575,7 @@ Town Red Rooftop (Town): 158224 - 0x28B39 (Tall Hexagonal) - 0x079DF - True Town Wooden Rooftop (Town): -158240 - 0x28AD9 (Wooden Rooftop) - 0x28AC1 - Rotated Shapers & Dots & Eraser & Full Dots +158240 - 0x28AD9 (Wooden Rooftop) - 0x28AC1 - Rotated Shapers & Eraser & Full Dots Town Church (Town): 158227 - 0x28A69 (Church Lattice) - 0x03BB0 - True @@ -934,29 +934,29 @@ Treehouse Second Purple Bridge (Treehouse) - Treehouse Left Orange Bridge - 0x17 158368 - 0x17DC6 (Second Purple Bridge 7) - 0x17D91 - Stars & Colored Squares Treehouse Left Orange Bridge (Treehouse) - Treehouse Laser Room Front Platform - 0x17DDB - Treehouse Laser Room Back Platform - 0x17DDB - Treehouse Burned House - 0x17DDB: -158376 - 0x17DB3 (Left Orange Bridge 1) - True - Stars & Black/White Squares & Stars + Same Colored Symbol -158377 - 0x17DB5 (Left Orange Bridge 2) - 0x17DB3 - Stars & Black/White Squares & Stars + Same Colored Symbol -158378 - 0x17DB6 (Left Orange Bridge 3) - 0x17DB5 - Stars & Black/White Squares & Stars + Same Colored Symbol -158379 - 0x17DC0 (Left Orange Bridge 4) - 0x17DB6 - Stars & Black/White Squares & Stars + Same Colored Symbol -158380 - 0x17DD7 (Left Orange Bridge 5) - 0x17DC0 - Stars & Black/White Squares & Colored Squares & Stars + Same Colored Symbol -158381 - 0x17DD9 (Left Orange Bridge 6) - 0x17DD7 - Stars & Black/White Squares & Colored Squares & Stars + Same Colored Symbol -158382 - 0x17DB8 (Left Orange Bridge 7) - 0x17DD9 - Stars & Black/White Squares & Colored Squares & Stars + Same Colored Symbol -158383 - 0x17DDC (Left Orange Bridge 8) - 0x17DB8 - Stars & Colored Squares & Stars + Same Colored Symbol -158384 - 0x17DD1 (Left Orange Bridge 9 & Directional) - 0x17DDC - Stars & Colored Squares & Stars + Same Colored Symbol -158385 - 0x17DDE (Left Orange Bridge 10) - 0x17DD1 - Stars & Colored Squares & Stars + Same Colored Symbol -158386 - 0x17DE3 (Left Orange Bridge 11) - 0x17DDE - Stars & Colored Squares & Stars + Same Colored Symbol -158387 - 0x17DEC (Left Orange Bridge 12) - 0x17DE3 - Stars & Black/White Squares & Stars + Same Colored Symbol -158388 - 0x17DAE (Left Orange Bridge 13) - 0x17DEC - Stars & Black/White Squares & Stars + Same Colored Symbol -158389 - 0x17DB0 (Left Orange Bridge 14) - 0x17DAE - Stars & Black/White Squares & Stars + Same Colored Symbol -158390 - 0x17DDB (Left Orange Bridge 15) - 0x17DB0 - Stars & Black/White Squares & Stars + Same Colored Symbol +158376 - 0x17DB3 (Left Orange Bridge 1) - True - Black/White Squares & Stars + Same Colored Symbol +158377 - 0x17DB5 (Left Orange Bridge 2) - 0x17DB3 - Black/White Squares & Stars + Same Colored Symbol +158378 - 0x17DB6 (Left Orange Bridge 3) - 0x17DB5 - Black/White Squares & Stars + Same Colored Symbol +158379 - 0x17DC0 (Left Orange Bridge 4) - 0x17DB6 - Black/White Squares & Stars + Same Colored Symbol +158380 - 0x17DD7 (Left Orange Bridge 5) - 0x17DC0 - Black/White Squares & Colored Squares & Stars + Same Colored Symbol +158381 - 0x17DD9 (Left Orange Bridge 6) - 0x17DD7 - Black/White Squares & Colored Squares & Stars + Same Colored Symbol +158382 - 0x17DB8 (Left Orange Bridge 7) - 0x17DD9 - Black/White Squares & Colored Squares & Stars + Same Colored Symbol +158383 - 0x17DDC (Left Orange Bridge 8) - 0x17DB8 - Colored Squares & Stars + Same Colored Symbol +158384 - 0x17DD1 (Left Orange Bridge 9 & Directional) - 0x17DDC - Colored Squares & Stars + Same Colored Symbol +158385 - 0x17DDE (Left Orange Bridge 10) - 0x17DD1 - Colored Squares & Stars + Same Colored Symbol +158386 - 0x17DE3 (Left Orange Bridge 11) - 0x17DDE - Colored Squares & Stars + Same Colored Symbol +158387 - 0x17DEC (Left Orange Bridge 12) - 0x17DE3 - Black/White Squares & Stars + Same Colored Symbol +158388 - 0x17DAE (Left Orange Bridge 13) - 0x17DEC - Black/White Squares & Stars + Same Colored Symbol +158389 - 0x17DB0 (Left Orange Bridge 14) - 0x17DAE - Black/White Squares & Stars + Same Colored Symbol +158390 - 0x17DDB (Left Orange Bridge 15) - 0x17DB0 - Black/White Squares & Stars + Same Colored Symbol Treehouse Green Bridge (Treehouse) - Treehouse Green Bridge Front House - 0x17E61 - Treehouse Green Bridge Left House - 0x17E61: 158369 - 0x17E3C (Green Bridge 1) - True - Stars & Shapers 158370 - 0x17E4D (Green Bridge 2) - 0x17E3C - Stars & Shapers 158371 - 0x17E4F (Green Bridge 3) - 0x17E4D - Stars & Shapers & Rotated Shapers 158372 - 0x17E52 (Green Bridge 4 & Directional) - 0x17E4F - Stars & Rotated Shapers -158373 - 0x17E5B (Green Bridge 5) - 0x17E52 - Stars & Shapers & Stars + Same Colored Symbol -158374 - 0x17E5F (Green Bridge 6) - 0x17E5B - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol +158373 - 0x17E5B (Green Bridge 5) - 0x17E52 - Shapers & Stars + Same Colored Symbol +158374 - 0x17E5F (Green Bridge 6) - 0x17E5B - Shapers & Negative Shapers & Stars + Same Colored Symbol 158375 - 0x17E61 (Green Bridge 7) - 0x17E5F - Stars & Shapers & Rotated Shapers Treehouse Green Bridge Front House (Treehouse): @@ -1005,7 +1005,7 @@ Mountainside Vault (Mountainside): Mountaintop (Mountaintop) - Mountain Floor 1 - 0x17C34: 158405 - 0x0042D (River Shape) - True - True 158406 - 0x09F7F (Box Short) - 7 Lasers + Redirect - True -158407 - 0x17C34 (Mountain Entry Panel) - 0x09F7F - Stars & Black/White Squares & Stars + Same Colored Symbol +158407 - 0x17C34 (Mountain Entry Panel) - 0x09F7F - Black/White Squares & Stars + Same Colored Symbol 158800 - 0xFFF00 (Box Long) - 11 Lasers + Redirect & 0x17C34 - True 159300 - 0x001A3 (River Shape EP) - True - True 159320 - 0x3370E (Arch Black EP) - True - True @@ -1023,11 +1023,11 @@ Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneW 158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers & Dots 158412 - 0x09E69 (Right Row 4) - 0x09E72 - Black/White Squares & Dots 158413 - 0x09E7B (Right Row 5) - 0x09E69 - Black/White Squares & Dots -158414 - 0x09E73 (Left Row 1) - True - Stars & Black/White Squares & Stars + Same Colored Symbol -158415 - 0x09E75 (Left Row 2) - 0x09E73 - Stars & Black/White Squares & Stars + Same Colored Symbol +158414 - 0x09E73 (Left Row 1) - True - Black/White Squares & Stars + Same Colored Symbol +158415 - 0x09E75 (Left Row 2) - 0x09E73 - Black/White Squares & Stars + Same Colored Symbol 158416 - 0x09E78 (Left Row 3) - 0x09E75 - Shapers 158417 - 0x09E79 (Left Row 4) - 0x09E78 - Shapers & Rotated Shapers -158418 - 0x09E6C (Left Row 5) - 0x09E79 - Stars & Black/White Squares & Stars + Same Colored Symbol +158418 - 0x09E6C (Left Row 5) - 0x09E79 - Black/White Squares & Stars + Same Colored Symbol 158419 - 0x09E6F (Left Row 6) - 0x09E6C - Stars & Rotated Shapers & Shapers 158420 - 0x09E6B (Left Row 7) - 0x09E6F - Stars & Dots 158424 - 0x09EAD (Trash Pillar 1) - True - Black/White Squares & Shapers @@ -1044,10 +1044,10 @@ Mountain Floor 1 At Door (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B Mountain Floor 2 (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Near - 0x09FFB - Mountain Floor 2 Beyond Bridge - 0x09E86 - Mountain Floor 2 Above The Abyss - True - Mountain Pink Bridge EP - TrueOneWay: -158426 - 0x09FD3 (Near Row 1) - True - Stars & Colored Squares & Stars + Same Colored Symbol -158427 - 0x09FD4 (Near Row 2) - 0x09FD3 - Stars & Colored Squares & Stars + Same Colored Symbol -158428 - 0x09FD6 (Near Row 3) - 0x09FD4 - Stars & Colored Squares & Stars + Same Colored Symbol -158429 - 0x09FD7 (Near Row 4) - 0x09FD6 - Stars & Colored Squares & Stars + Same Colored Symbol & Shapers +158426 - 0x09FD3 (Near Row 1) - True - Colored Squares & Stars + Same Colored Symbol +158427 - 0x09FD4 (Near Row 2) - 0x09FD3 - Colored Squares & Stars + Same Colored Symbol +158428 - 0x09FD6 (Near Row 3) - 0x09FD4 - Colored Squares & Stars + Same Colored Symbol +158429 - 0x09FD7 (Near Row 4) - 0x09FD6 - Colored Squares & Stars + Same Colored Symbol & Shapers 158430 - 0x09FD8 (Near Row 5) - 0x09FD7 - Symmetry & Colored Dots Door - 0x09FFB (Staircase Near) - 0x09FD8 @@ -1055,19 +1055,19 @@ Mountain Floor 2 Above The Abyss (Mountain Floor 2) - Mountain Floor 2 Elevator Door - 0x09EDD (Elevator Room Entry) - 0x09ED8 & 0x09E86 Mountain Floor 2 Light Bridge Room Near (Mountain Floor 2): -158431 - 0x09E86 (Light Bridge Controller Near) - True - Stars & Stars + Same Colored Symbol & Rotated Shapers & Eraser +158431 - 0x09E86 (Light Bridge Controller Near) - True - Stars + Same Colored Symbol & Rotated Shapers & Eraser Mountain Floor 2 Beyond Bridge (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Far - 0x09E07 - Mountain Pink Bridge EP - TrueOneWay - Mountain Floor 2 - 0x09ED8: 158432 - 0x09FCC (Far Row 1) - True - Dots 158433 - 0x09FCE (Far Row 2) - 0x09FCC - Black/White Squares 158434 - 0x09FCF (Far Row 3) - 0x09FCE - Stars 158435 - 0x09FD0 (Far Row 4) - 0x09FCF - Rotated Shapers -158436 - 0x09FD1 (Far Row 5) - 0x09FD0 - Stars & Colored Squares & Stars + Same Colored Symbol +158436 - 0x09FD1 (Far Row 5) - 0x09FD0 - Colored Squares & Stars + Same Colored Symbol 158437 - 0x09FD2 (Far Row 6) - 0x09FD1 - Shapers Door - 0x09E07 (Staircase Far) - 0x09FD2 Mountain Floor 2 Light Bridge Room Far (Mountain Floor 2): -158438 - 0x09ED8 (Light Bridge Controller Far) - True - Stars & Stars + Same Colored Symbol & Rotated Shapers & Eraser +158438 - 0x09ED8 (Light Bridge Controller Far) - True - Stars + Same Colored Symbol & Rotated Shapers & Eraser Mountain Floor 2 Elevator Room (Mountain Floor 2) - Mountain Floor 2 Elevator - TrueOneWay: 158613 - 0x17F93 (Elevator Discard) - True - Triangles @@ -1095,7 +1095,7 @@ Door - 0x17F33 (Rock Open) - 0x17FA2 | 0x334E1 Mountain Bottom Floor Pillars Room (Mountain Bottom Floor) - Elevator - 0x339BB & 0x33961: 158522 - 0x0383A (Right Pillar 1) - True - Stars 158523 - 0x09E56 (Right Pillar 2) - 0x0383A - Stars & Dots -158524 - 0x09E5A (Right Pillar 3) - 0x09E56 - Dots & Full Dots +158524 - 0x09E5A (Right Pillar 3) - 0x09E56 - Full Dots 158525 - 0x33961 (Right Pillar 4) - 0x09E5A - Dots & Symmetry 158526 - 0x0383D (Left Pillar 1) - True - Dots 158527 - 0x0383F (Left Pillar 2) - 0x0383D - Black/White Squares @@ -1127,16 +1127,16 @@ Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x01 158451 - 0x335AB (Elevator Inside Control) - True - Dots & Black/White Squares 158452 - 0x335AC (Elevator Upper Outside Control) - 0x335AB - Black/White Squares 158453 - 0x3369D (Elevator Lower Outside Control) - 0x335AB - Black/White Squares & Dots -158454 - 0x00190 (Blue Tunnel Right First 1) - True - Dots & Triangles & Full Dots -158455 - 0x00558 (Blue Tunnel Right First 2) - 0x00190 - Dots & Triangles & Full Dots -158456 - 0x00567 (Blue Tunnel Right First 3) - 0x00558 - Dots & Triangles & Full Dots -158457 - 0x006FE (Blue Tunnel Right First 4) - 0x00567 - Dots & Triangles & Full Dots +158454 - 0x00190 (Blue Tunnel Right First 1) - True - Triangles & Full Dots +158455 - 0x00558 (Blue Tunnel Right First 2) - 0x00190 - Triangles & Full Dots +158456 - 0x00567 (Blue Tunnel Right First 3) - 0x00558 - Triangles & Full Dots +158457 - 0x006FE (Blue Tunnel Right First 4) - 0x00567 - Triangles & Full Dots 158458 - 0x01A0D (Blue Tunnel Left First 1) - True - Symmetry & Triangles 158459 - 0x008B8 (Blue Tunnel Left Second 1) - True - Black/White Squares & Triangles 158460 - 0x00973 (Blue Tunnel Left Second 2) - 0x008B8 - Stars & Triangles -158461 - 0x0097B (Blue Tunnel Left Second 3) - 0x00973 - Stars & Triangles & Stars + Same Colored Symbol -158462 - 0x0097D (Blue Tunnel Left Second 4) - 0x0097B - Stars & Black/White Squares & Stars + Same Colored Symbol & Triangles -158463 - 0x0097E (Blue Tunnel Left Second 5) - 0x0097D - Stars & Black/White Squares & Stars + Same Colored Symbol & Colored Squares +158461 - 0x0097B (Blue Tunnel Left Second 3) - 0x00973 - Triangles & Stars + Same Colored Symbol +158462 - 0x0097D (Blue Tunnel Left Second 4) - 0x0097B - Black/White Squares & Stars + Same Colored Symbol & Triangles +158463 - 0x0097E (Blue Tunnel Left Second 5) - 0x0097D - Black/White Squares & Stars + Same Colored Symbol & Colored Squares 158464 - 0x00994 (Blue Tunnel Right Second 1) - True - Rotated Shapers & Triangles 158465 - 0x334D5 (Blue Tunnel Right Second 2) - 0x00994 - Rotated Shapers & Triangles 158466 - 0x00995 (Blue Tunnel Right Second 3) - 0x334D5 - Rotated Shapers & Triangles @@ -1146,40 +1146,40 @@ Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x01 158470 - 0x018A0 (Blue Tunnel Right Third 1) - True - Shapers & Symmetry 158471 - 0x00A72 (Blue Tunnel Left Fourth 1) - True - Shapers & Negative Shapers 158472 - 0x32962 (First Floor Left) - True - Rotated Shapers -158473 - 0x32966 (First Floor Grounded) - True - Stars & Black/White Squares & Stars + Same Colored Symbol +158473 - 0x32966 (First Floor Grounded) - True - Black/White Squares & Stars + Same Colored Symbol 158474 - 0x01A31 (First Floor Middle) - True - Colored Squares -158475 - 0x00B71 (First Floor Right) - True - Colored Squares & Stars & Stars + Same Colored Symbol & Eraser +158475 - 0x00B71 (First Floor Right) - True - Colored Squares & Stars + Same Colored Symbol & Eraser 158478 - 0x288EA (First Wooden Beam) - True - Shapers 158479 - 0x288FC (Second Wooden Beam) - True - Black/White Squares & Shapers & Rotated Shapers 158480 - 0x289E7 (Third Wooden Beam) - True - Stars & Black/White Squares 158481 - 0x288AA (Fourth Wooden Beam) - True - Stars & Shapers -158482 - 0x17FB9 (Left Upstairs Single) - True - Shapers & Dots & Negative Shapers & Full Dots -158483 - 0x0A16B (Left Upstairs Left Row 1) - True - Dots & Full Dots -158484 - 0x0A2CE (Left Upstairs Left Row 2) - 0x0A16B - Stars & Dots & Full Dots -158485 - 0x0A2D7 (Left Upstairs Left Row 3) - 0x0A2CE - Dots & Black/White Squares & Stars + Same Colored Symbol & Stars & Full Dots -158486 - 0x0A2DD (Left Upstairs Left Row 4) - 0x0A2D7 - Shapers & Dots & Full Dots -158487 - 0x0A2EA (Left Upstairs Left Row 5) - 0x0A2DD - Rotated Shapers & Dots & Full Dots -158488 - 0x0008F (Right Upstairs Left Row 1) - True - Dots & Invisible Dots -158489 - 0x0006B (Right Upstairs Left Row 2) - 0x0008F - Dots & Invisible Dots -158490 - 0x0008B (Right Upstairs Left Row 3) - 0x0006B - Dots & Invisible Dots -158491 - 0x0008C (Right Upstairs Left Row 4) - 0x0008B - Dots & Invisible Dots -158492 - 0x0008A (Right Upstairs Left Row 5) - 0x0008C - Dots & Invisible Dots -158493 - 0x00089 (Right Upstairs Left Row 6) - 0x0008A - Dots & Invisible Dots -158494 - 0x0006A (Right Upstairs Left Row 7) - 0x00089 - Dots & Invisible Dots -158495 - 0x0006C (Right Upstairs Left Row 8) - 0x0006A - Dots & Invisible Dots -158496 - 0x00027 (Right Upstairs Right Row 1) - True - Dots & Invisible Dots & Symmetry -158497 - 0x00028 (Right Upstairs Right Row 2) - 0x00027 - Dots & Invisible Dots & Symmetry -158498 - 0x00029 (Right Upstairs Right Row 3) - 0x00028 - Dots & Invisible Dots & Symmetry +158482 - 0x17FB9 (Left Upstairs Single) - True - Shapers & Negative Shapers & Full Dots +158483 - 0x0A16B (Left Upstairs Left Row 1) - True - Full Dots +158484 - 0x0A2CE (Left Upstairs Left Row 2) - 0x0A16B - Stars & Full Dots +158485 - 0x0A2D7 (Left Upstairs Left Row 3) - 0x0A2CE - Black/White Squares & Stars + Same Colored Symbol & Full Dots +158486 - 0x0A2DD (Left Upstairs Left Row 4) - 0x0A2D7 - Shapers & Full Dots +158487 - 0x0A2EA (Left Upstairs Left Row 5) - 0x0A2DD - Rotated Shapers & Full Dots +158488 - 0x0008F (Right Upstairs Left Row 1) - True - Dots +158489 - 0x0006B (Right Upstairs Left Row 2) - 0x0008F - Dots +158490 - 0x0008B (Right Upstairs Left Row 3) - 0x0006B - Dots +158491 - 0x0008C (Right Upstairs Left Row 4) - 0x0008B - Dots +158492 - 0x0008A (Right Upstairs Left Row 5) - 0x0008C - Dots +158493 - 0x00089 (Right Upstairs Left Row 6) - 0x0008A - Dots +158494 - 0x0006A (Right Upstairs Left Row 7) - 0x00089 - Dots +158495 - 0x0006C (Right Upstairs Left Row 8) - 0x0006A - Dots +158496 - 0x00027 (Right Upstairs Right Row 1) - True - Dots & Symmetry +158497 - 0x00028 (Right Upstairs Right Row 2) - 0x00027 - Dots & Symmetry +158498 - 0x00029 (Right Upstairs Right Row 3) - 0x00028 - Dots & Symmetry 158476 - 0x09DD5 (Lone Pillar) - True - Triangles Door - 0x019A5 (Pillar Door) - 0x09DD5 -158449 - 0x021D7 (Mountain Shortcut Panel) - True - Triangles & Stars & Stars + Same Colored Symbol +158449 - 0x021D7 (Mountain Shortcut Panel) - True - Triangles & Stars + Same Colored Symbol Door - 0x2D73F (Mountain Shortcut Door) - 0x021D7 158450 - 0x17CF2 (Swamp Shortcut Panel) - True - Triangles Door - 0x2D859 (Swamp Shortcut Door) - 0x17CF2 159341 - 0x3397C (Skylight EP) - True - True Caves Path to Challenge (Caves) - Challenge - 0x0A19A: -158477 - 0x0A16E (Challenge Entry Panel) - True - Stars & Shapers & Stars + Same Colored Symbol +158477 - 0x0A16E (Challenge Entry Panel) - True - Shapers & Stars + Same Colored Symbol Door - 0x0A19A (Challenge Entry) - 0x0A16E ==Challenge== diff --git a/worlds/witness/data/WitnessLogicExpert.txt b/worlds/witness/data/WitnessLogicExpert.txt index 23521dddeb5b..936001c243ad 100644 --- a/worlds/witness/data/WitnessLogicExpert.txt +++ b/worlds/witness/data/WitnessLogicExpert.txt @@ -13,8 +13,8 @@ Tutorial (Tutorial) - Outside Tutorial - True: 158002 - 0x00293 (Front Center) - True - Dots 158003 - 0x00295 (Center Left) - 0x00293 - Dots 158004 - 0x002C2 (Front Left) - 0x00295 - Dots -158005 - 0x0A3B5 (Back Left) - True - Dots & Full Dots -158006 - 0x0A3B2 (Back Right) - True - Dots & Full Dots +158005 - 0x0A3B5 (Back Left) - True - Full Dots +158006 - 0x0A3B2 (Back Right) - True - Full Dots 158007 - 0x03629 (Gate Open) - 0x002C2 - Symmetry & Dots 158008 - 0x03505 (Gate Close) - 0x2FAF6 & 0x03629 - True 158009 - 0x0C335 (Pillar) - True - Triangles @@ -26,22 +26,22 @@ Tutorial (Tutorial) - Outside Tutorial - True: ==Tutorial (Outside)== Outside Tutorial (Outside Tutorial) - Outside Tutorial Path To Outpost - 0x03BA2 - Outside Tutorial Vault - 0x033D0: -158650 - 0x033D4 (Vault Panel) - True - Dots & Full Dots & Squares & Black/White Squares +158650 - 0x033D4 (Vault Panel) - True - Full Dots & Black/White Squares Door - 0x033D0 (Vault Door) - 0x033D4 -158013 - 0x0005D (Shed Row 1) - True - Dots & Full Dots -158014 - 0x0005E (Shed Row 2) - 0x0005D - Dots & Full Dots -158015 - 0x0005F (Shed Row 3) - 0x0005E - Dots & Full Dots -158016 - 0x00060 (Shed Row 4) - 0x0005F - Dots & Full Dots -158017 - 0x00061 (Shed Row 5) - 0x00060 - Dots & Full Dots -158018 - 0x018AF (Tree Row 1) - True - Squares & Black/White Squares -158019 - 0x0001B (Tree Row 2) - 0x018AF - Squares & Black/White Squares -158020 - 0x012C9 (Tree Row 3) - 0x0001B - Squares & Black/White Squares -158021 - 0x0001C (Tree Row 4) - 0x012C9 - Squares & Black/White Squares & Dots -158022 - 0x0001D (Tree Row 5) - 0x0001C - Squares & Black/White Squares & Dots -158023 - 0x0001E (Tree Row 6) - 0x0001D - Squares & Black/White Squares & Dots -158024 - 0x0001F (Tree Row 7) - 0x0001E - Squares & Black/White Squares & Dots & Full Dots -158025 - 0x00020 (Tree Row 8) - 0x0001F - Squares & Black/White Squares & Dots & Full Dots -158026 - 0x00021 (Tree Row 9) - 0x00020 - Squares & Black/White Squares & Dots & Full Dots +158013 - 0x0005D (Shed Row 1) - True - Full Dots +158014 - 0x0005E (Shed Row 2) - 0x0005D - Full Dots +158015 - 0x0005F (Shed Row 3) - 0x0005E - Full Dots +158016 - 0x00060 (Shed Row 4) - 0x0005F - Full Dots +158017 - 0x00061 (Shed Row 5) - 0x00060 - Full Dots +158018 - 0x018AF (Tree Row 1) - True - Black/White Squares +158019 - 0x0001B (Tree Row 2) - 0x018AF - Black/White Squares +158020 - 0x012C9 (Tree Row 3) - 0x0001B - Black/White Squares +158021 - 0x0001C (Tree Row 4) - 0x012C9 - Black/White Squares & Dots +158022 - 0x0001D (Tree Row 5) - 0x0001C - Black/White Squares & Dots +158023 - 0x0001E (Tree Row 6) - 0x0001D - Black/White Squares & Dots +158024 - 0x0001F (Tree Row 7) - 0x0001E - Black/White Squares & Full Dots +158025 - 0x00020 (Tree Row 8) - 0x0001F - Black/White Squares & Full Dots +158026 - 0x00021 (Tree Row 9) - 0x00020 - Black/White Squares & Full Dots Door - 0x03BA2 (Outpost Path) - 0x0A3B5 159511 - 0x03D06 (Garden EP) - True - True 159514 - 0x28A2F (Town Sewer EP) - True - True @@ -52,11 +52,11 @@ Outside Tutorial Vault (Outside Tutorial): 158651 - 0x03481 (Vault Box) - True - True Outside Tutorial Path To Outpost (Outside Tutorial) - Outside Tutorial Outpost - 0x0A170: -158011 - 0x0A171 (Outpost Entry Panel) - True - Dots & Full Dots & Triangles +158011 - 0x0A171 (Outpost Entry Panel) - True - Full Dots & Triangles Door - 0x0A170 (Outpost Entry) - 0x0A171 Outside Tutorial Outpost (Outside Tutorial) - Outside Tutorial - 0x04CA3: -158012 - 0x04CA4 (Outpost Exit Panel) - True - Dots & Full Dots & Shapers & Rotated Shapers +158012 - 0x04CA4 (Outpost Exit Panel) - True - Full Dots & Shapers & Rotated Shapers Door - 0x04CA3 (Outpost Exit) - 0x04CA4 158600 - 0x17CFB (Discard) - True - Arrows @@ -136,12 +136,12 @@ Door - 0x18269 (Upper) - 0x1C349 159000 - 0x0332B (Glass Factory Black Line Reflection EP) - True - True Symmetry Island Upper (Symmetry Island): -158065 - 0x00A52 (Laser Yellow 1) - True - Symmetry & Colored Dots -158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Symmetry & Colored Dots -158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Symmetry & Colored Dots -158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Symmetry & Colored Dots -158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Symmetry & Colored Dots -158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Symmetry & Colored Dots +158065 - 0x00A52 (Laser Yellow 1) - True - Colored Dots +158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Colored Dots +158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Colored Dots +158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Colored Dots +158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Colored Dots +158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Colored Dots 158700 - 0x0360D (Laser Panel) - 0x00A68 - True Laser - 0x00509 (Laser) - 0x0360D 159001 - 0x03367 (Glass Factory Black Line EP) - True - True @@ -157,7 +157,7 @@ Desert Obelisk (Desert) - Entry - True: 159709 - 0x00359 (Obelisk) - True - True Desert Outside (Desert) - Main Island - True - Desert Light Room - 0x09FEE - Desert Vault - 0x03444: -158652 - 0x0CC7B (Vault Panel) - True - Dots & Full Dots & Stars & Stars + Same Colored Symbol & Eraser & Triangles & Shapers & Negative Shapers & Colored Squares +158652 - 0x0CC7B (Vault Panel) - True - Full Dots & Stars + Same Colored Symbol & Eraser & Triangles & Shapers & Negative Shapers & Colored Squares Door - 0x03444 (Vault Door) - 0x0CC7B 158602 - 0x17CE7 (Discard) - True - Arrows 158076 - 0x00698 (Surface 1) - True - True @@ -249,9 +249,9 @@ Quarry Obelisk (Quarry) - Entry - True: 159749 - 0x22073 (Obelisk) - True - True Outside Quarry (Quarry) - Main Island - True - Quarry Between Entry Doors - 0x09D6F - Quarry Elevator - 0xFFD00 & 0xFFD01: -158118 - 0x09E57 (Entry 1 Panel) - True - Squares & Black/White Squares & Triangles +158118 - 0x09E57 (Entry 1 Panel) - True - Black/White Squares & Triangles 158603 - 0x17CF0 (Discard) - True - Arrows -158702 - 0x03612 (Laser Panel) - 0x0A3D0 & 0x0367C - Eraser & Triangles & Stars & Stars + Same Colored Symbol +158702 - 0x03612 (Laser Panel) - 0x0A3D0 & 0x0367C - Eraser & Triangles & Stars + Same Colored Symbol Laser - 0x01539 (Laser) - 0x03612 Door - 0x09D6F (Entry 1) - 0x09E57 159404 - 0x28A4A (Shore EP) - True - True @@ -270,7 +270,7 @@ Door - 0x17C07 (Entry 2) - 0x17C09 Quarry (Quarry) - Quarry Stoneworks Ground Floor - 0x02010: 159802 - 0xFFD01 (Inside Reached Independently) - True - True -158121 - 0x01E5A (Stoneworks Entry Left Panel) - True - Squares & Black/White Squares & Stars & Stars + Same Colored Symbol +158121 - 0x01E5A (Stoneworks Entry Left Panel) - True - Black/White Squares & Stars + Same Colored Symbol 158122 - 0x01E59 (Stoneworks Entry Right Panel) - True - Triangles Door - 0x02010 (Stoneworks Entry) - 0x01E59 & 0x01E5A @@ -295,23 +295,23 @@ Quarry Stoneworks Lift (Quarry Stoneworks) - Quarry Stoneworks Middle Floor - 0x Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Lift - 0x03675 - Quarry Stoneworks Ground Floor - 0x0368A: 158132 - 0x03676 (Upper Ramp Control) - True - Dots & Eraser 158133 - 0x03675 (Upper Lift Control) - True - Dots & Eraser -158134 - 0x00557 (Upper Row 1) - True - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol -158135 - 0x005F1 (Upper Row 2) - 0x00557 - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol -158136 - 0x00620 (Upper Row 3) - 0x005F1 - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol -158137 - 0x009F5 (Upper Row 4) - 0x00620 - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol -158138 - 0x0146C (Upper Row 5) - 0x009F5 - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol -158139 - 0x3C12D (Upper Row 6) - 0x0146C - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol -158140 - 0x03686 (Upper Row 7) - 0x3C12D - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol -158141 - 0x014E9 (Upper Row 8) - 0x03686 - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol -158142 - 0x03677 (Stairs Panel) - True - Squares & Colored Squares & Eraser +158134 - 0x00557 (Upper Row 1) - True - Colored Squares & Eraser & Stars + Same Colored Symbol +158135 - 0x005F1 (Upper Row 2) - 0x00557 - Colored Squares & Eraser & Stars + Same Colored Symbol +158136 - 0x00620 (Upper Row 3) - 0x005F1 - Colored Squares & Eraser & Stars + Same Colored Symbol +158137 - 0x009F5 (Upper Row 4) - 0x00620 - Colored Squares & Eraser & Stars + Same Colored Symbol +158138 - 0x0146C (Upper Row 5) - 0x009F5 - Colored Squares & Eraser & Stars + Same Colored Symbol +158139 - 0x3C12D (Upper Row 6) - 0x0146C - Colored Squares & Eraser & Stars + Same Colored Symbol +158140 - 0x03686 (Upper Row 7) - 0x3C12D - Colored Squares & Eraser & Stars + Same Colored Symbol +158141 - 0x014E9 (Upper Row 8) - 0x03686 - Colored Squares & Eraser & Stars + Same Colored Symbol +158142 - 0x03677 (Stairs Panel) - True - Colored Squares & Eraser Door - 0x0368A (Stairs) - 0x03677 -158143 - 0x3C125 (Control Room Left) - 0x014E9 - Squares & Black/White Squares & Dots & Full Dots & Eraser -158144 - 0x0367C (Control Room Right) - 0x014E9 - Squares & Colored Squares & Triangles & Eraser & Stars & Stars + Same Colored Symbol +158143 - 0x3C125 (Control Room Left) - 0x014E9 - Black/White Squares & Full Dots & Eraser +158144 - 0x0367C (Control Room Right) - 0x014E9 - Colored Squares & Triangles & Eraser & Stars + Same Colored Symbol 159411 - 0x0069D (Ramp EP) - 0x03676 & 0x275FF - True 159413 - 0x00614 (Lift EP) - 0x275FF & 0x03675 - True Quarry Boathouse (Quarry Boathouse) - Quarry - True - Quarry Boathouse Upper Front - 0x03852 - Quarry Boathouse Behind Staircase - 0x2769B: -158146 - 0x034D4 (Intro Left) - True - Stars & Stars + Same Colored Symbol & Eraser +158146 - 0x034D4 (Intro Left) - True - Stars + Same Colored Symbol & Eraser 158147 - 0x021D5 (Intro Right) - True - Shapers & Eraser 158148 - 0x03852 (Ramp Height Control) - 0x034D4 & 0x021D5 - Rotated Shapers 158166 - 0x17CA6 (Boat Spawn) - True - Boat @@ -335,19 +335,19 @@ Quarry Boathouse Upper Middle (Quarry Boathouse) - Quarry Boathouse Upper Back - Quarry Boathouse Upper Back (Quarry Boathouse) - Quarry Boathouse Upper Middle - 0x3865F: 158155 - 0x38663 (Second Barrier Panel) - True - True Door - 0x3865F (Second Barrier) - 0x38663 -158156 - 0x021B5 (Back First Row 1) - True - Stars & Stars + Same Colored Symbol & Eraser -158157 - 0x021B6 (Back First Row 2) - 0x021B5 - Stars & Stars + Same Colored Symbol & Eraser -158158 - 0x021B7 (Back First Row 3) - 0x021B6 - Stars & Stars + Same Colored Symbol & Eraser -158159 - 0x021BB (Back First Row 4) - 0x021B7 - Stars & Stars + Same Colored Symbol & Eraser -158160 - 0x09DB5 (Back First Row 5) - 0x021BB - Stars & Stars + Same Colored Symbol & Eraser +158156 - 0x021B5 (Back First Row 1) - True - Stars + Same Colored Symbol & Eraser +158157 - 0x021B6 (Back First Row 2) - 0x021B5 - Stars + Same Colored Symbol & Eraser +158158 - 0x021B7 (Back First Row 3) - 0x021B6 - Stars + Same Colored Symbol & Eraser +158159 - 0x021BB (Back First Row 4) - 0x021B7 - Stars + Same Colored Symbol & Eraser +158160 - 0x09DB5 (Back First Row 5) - 0x021BB - Stars + Same Colored Symbol & Eraser 158161 - 0x09DB1 (Back First Row 6) - 0x09DB5 - Eraser & Shapers 158162 - 0x3C124 (Back First Row 7) - 0x09DB1 - Eraser & Shapers -158163 - 0x09DB3 (Back First Row 8) - 0x3C124 - Eraser & Shapers & Stars & Stars + Same Colored Symbol -158164 - 0x09DB4 (Back First Row 9) - 0x09DB3 - Eraser & Shapers & Stars & Stars + Same Colored Symbol +158163 - 0x09DB3 (Back First Row 8) - 0x3C124 - Eraser & Shapers & Stars + Same Colored Symbol +158164 - 0x09DB4 (Back First Row 9) - 0x09DB3 - Eraser & Shapers & Stars + Same Colored Symbol 158165 - 0x275FA (Hook Control) - True - Shapers & Eraser -158167 - 0x0A3CB (Back Second Row 1) - 0x09DB4 - Stars & Eraser & Shapers & Negative Shapers & Stars + Same Colored Symbol -158168 - 0x0A3CC (Back Second Row 2) - 0x0A3CB - Stars & Eraser & Shapers & Negative Shapers & Stars + Same Colored Symbol -158169 - 0x0A3D0 (Back Second Row 3) - 0x0A3CC - Stars & Eraser & Shapers & Negative Shapers & Stars + Same Colored Symbol +158167 - 0x0A3CB (Back Second Row 1) - 0x09DB4 - Eraser & Shapers & Negative Shapers & Stars + Same Colored Symbol +158168 - 0x0A3CC (Back Second Row 2) - 0x0A3CB - Eraser & Shapers & Negative Shapers & Stars + Same Colored Symbol +158169 - 0x0A3D0 (Back Second Row 3) - 0x0A3CC - Eraser & Shapers & Negative Shapers & Stars + Same Colored Symbol 159401 - 0x005F6 (Hook EP) - 0x275FA & 0x03852 & 0x3865F - True ==Shadows== @@ -400,7 +400,7 @@ Outside Keep (Keep) - Main Island - True: Keep (Keep) - Outside Keep - True - Keep 2nd Maze - 0x01954 - Keep 2nd Pressure Plate - 0x01BEC: 158193 - 0x00139 (Hedge Maze 1) - True - True 158197 - 0x0A3A8 (Reset Pressure Plates 1) - True - True -158198 - 0x033EA (Pressure Plates 1) - 0x0A3A8 - Colored Squares & Triangles & Stars & Stars + Same Colored Symbol +158198 - 0x033EA (Pressure Plates 1) - 0x0A3A8 - Colored Squares & Triangles & Stars + Same Colored Symbol Door - 0x01954 (Hedge Maze 1 Exit) - 0x00139 Door - 0x01BEC (Pressure Plates 1 Exit) - 0x033EA @@ -421,7 +421,7 @@ Door - 0x01A0E (Hedge Maze 4 Exit) - 0x01A0F Keep 2nd Pressure Plate (Keep) - Keep 3rd Pressure Plate - True: 158199 - 0x0A3B9 (Reset Pressure Plates 2) - True - True -158200 - 0x01BE9 (Pressure Plates 2) - PP2 Weirdness - Stars & Stars + Same Colored Symbol & Squares & Black/White Squares & Shapers & Rotated Shapers +158200 - 0x01BE9 (Pressure Plates 2) - PP2 Weirdness - Stars + Same Colored Symbol & Black/White Squares & Shapers & Rotated Shapers Door - 0x01BEA (Pressure Plates 2 Exit) - 0x01BE9 Keep 3rd Pressure Plate (Keep) - Keep 4th Pressure Plate - 0x01CD5: @@ -431,7 +431,7 @@ Door - 0x01CD5 (Pressure Plates 3 Exit) - 0x01CD3 Keep 4th Pressure Plate (Keep) - Shadows - 0x09E3D - Keep Tower - 0x01D40: 158203 - 0x0A3AD (Reset Pressure Plates 4) - True - True -158204 - 0x01D3F (Pressure Plates 4) - 0x0A3AD - Shapers & Triangles & Stars & Stars + Same Colored Symbol +158204 - 0x01D3F (Pressure Plates 4) - 0x0A3AD - Shapers & Triangles & Stars + Same Colored Symbol Door - 0x01D40 (Pressure Plates 4 Exit) - 0x01D3F 158604 - 0x17D27 (Discard) - True - Arrows 158205 - 0x09E49 (Shadows Shortcut Panel) - True - True @@ -441,7 +441,7 @@ Keep Tower (Keep) - Keep - 0x04F8F: 158206 - 0x0361B (Tower Shortcut Panel) - True - True Door - 0x04F8F (Tower Shortcut) - 0x0361B 158704 - 0x0360E (Laser Panel Hedges) - 0x01A0F & 0x019E7 & 0x019DC & 0x00139 - True -158705 - 0x03317 (Laser Panel Pressure Plates) - 0x033EA & 0x01BE9 & 0x01CD3 & 0x01D3F - Shapers & Rotated Shapers & Triangles & Stars & Stars + Same Colored Symbol & Colored Squares & Black/White Squares +158705 - 0x03317 (Laser Panel Pressure Plates) - 0x033EA & 0x01BE9 & 0x01CD3 & 0x01D3F - Shapers & Rotated Shapers & Triangles & Stars + Same Colored Symbol & Colored Squares & Black/White Squares Laser - 0x014BB (Laser) - 0x0360E | 0x03317 159240 - 0x033BE (Pressure Plates 1 EP) - 0x033EA - True 159241 - 0x033BF (Pressure Plates 2 EP) - 0x01BE9 - True @@ -530,20 +530,20 @@ Town Obelisk (Town) - Entry - True: Town (Town) - Main Island - True - The Ocean - 0x0A054 - Town Maze Rooftop - 0x28AA2 - Town Church - True - Town Wooden Rooftop - 0x034F5 - Town RGB House - 0x28A61 - Town Inside Cargo Box - 0x0A0C9 - Outside Windmill - True: 158218 - 0x0A054 (Boat Spawn) - 0x17CA6 | 0x17CDF | 0x09DB8 | 0x17C95 - Boat -158219 - 0x0A0C8 (Cargo Box Entry Panel) - True - Squares & Black/White Squares & Shapers & Triangles +158219 - 0x0A0C8 (Cargo Box Entry Panel) - True - Black/White Squares & Shapers & Triangles Door - 0x0A0C9 (Cargo Box Entry) - 0x0A0C8 158707 - 0x09F98 (Desert Laser Redirect Control) - True - True 158220 - 0x18590 (Transparent) - True - Symmetry 158221 - 0x28AE3 (Vines) - 0x18590 - True 158222 - 0x28938 (Apple Tree) - 0x28AE3 - True 158223 - 0x079DF (Triple Exit) - 0x28938 - True -158235 - 0x2899C (Wooden Roof Lower Row 1) - True - Triangles & Dots & Full Dots -158236 - 0x28A33 (Wooden Roof Lower Row 2) - 0x2899C - Triangles & Dots & Full Dots -158237 - 0x28ABF (Wooden Roof Lower Row 3) - 0x28A33 - Triangles & Dots & Full Dots -158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Triangles & Dots & Full Dots -158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Triangles & Dots & Full Dots +158235 - 0x2899C (Wooden Roof Lower Row 1) - True - Triangles & Full Dots +158236 - 0x28A33 (Wooden Roof Lower Row 2) - 0x2899C - Triangles & Full Dots +158237 - 0x28ABF (Wooden Roof Lower Row 3) - 0x28A33 - Triangles & Full Dots +158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Triangles & Full Dots +158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Triangles & Full Dots Door - 0x034F5 (Wooden Roof Stairs) - 0x28AC1 -158225 - 0x28998 (RGB House Entry Panel) - True - Stars & Rotated Shapers & Stars + Same Colored Symbol +158225 - 0x28998 (RGB House Entry Panel) - True - Rotated Shapers & Stars + Same Colored Symbol Door - 0x28A61 (RGB House Entry) - 0x28A0D 158226 - 0x28A0D (Church Entry Panel) - 0x28998 - Stars Door - 0x03BB0 (Church Entry) - 0x03C08 @@ -575,7 +575,7 @@ Town Red Rooftop (Town): 158224 - 0x28B39 (Tall Hexagonal) - 0x079DF - True Town Wooden Rooftop (Town): -158240 - 0x28AD9 (Wooden Rooftop) - 0x28AC1 - Triangles & Dots & Full Dots & Eraser +158240 - 0x28AD9 (Wooden Rooftop) - 0x28AC1 - Triangles & Full Dots & Eraser Town Church (Town): 158227 - 0x28A69 (Church Lattice) - 0x03BB0 - True @@ -587,8 +587,8 @@ Town RGB House (Town RGB House) - Town RGB House Upstairs - 0x2897B: Door - 0x2897B (Stairs) - 0x034E4 & 0x034E3 Town RGB House Upstairs (Town RGB House Upstairs): -158244 - 0x334D8 (RGB Control) - True - Rotated Shapers & Squares & Colored Squares & Triangles -158245 - 0x03C0C (Left) - 0x334D8 - Squares & Colored Squares & Black/White Squares & Eraser +158244 - 0x334D8 (RGB Control) - True - Rotated Shapers & Colored Squares & Triangles +158245 - 0x03C0C (Left) - 0x334D8 - Colored Squares & Black/White Squares & Eraser 158246 - 0x03C08 (Right) - 0x334D8 & 0x03C0C - Symmetry & Dots & Colored Dots & Triangles Town Tower Bottom (Town Tower) - Town - True - Town Tower After First Door - 0x27799: @@ -620,7 +620,7 @@ Door - 0x1845B (Entry) - 0x17F5F Windmill Interior (Windmill) - Theater - 0x17F88: 158247 - 0x17D02 (Turn Control) - True - Dots -158248 - 0x17F89 (Theater Entry Panel) - True - Squares & Black/White Squares & Eraser & Triangles +158248 - 0x17F89 (Theater Entry Panel) - True - Black/White Squares & Eraser & Triangles Door - 0x17F88 (Theater Entry) - 0x17F89 Theater (Theater) - Town - 0x0A16D | 0x3CCDF: @@ -631,7 +631,7 @@ Theater (Theater) - Town - 0x0A16D | 0x3CCDF: 158660 - 0x03549 (Challenge Video) - 0x00815 & 0x0356B - True 158661 - 0x0354F (Shipwreck Video) - 0x00815 & 0x03535 - True 158662 - 0x03545 (Mountain Video) - 0x00815 & 0x03542 - True -158249 - 0x0A168 (Exit Left Panel) - True - Black/White Squares & Stars & Stars + Same Colored Symbol & Eraser +158249 - 0x0A168 (Exit Left Panel) - True - Black/White Squares & Stars + Same Colored Symbol & Eraser 158250 - 0x33AB2 (Exit Right Panel) - True - Eraser & Triangles & Shapers Door - 0x0A16D (Exit Left) - 0x0A168 Door - 0x3CCDF (Exit Right) - 0x33AB2 @@ -693,33 +693,33 @@ Jungle Vault (Jungle): ==Bunker== Outside Bunker (Bunker) - Main Island - True - Bunker - 0x0C2A4: -158268 - 0x17C2E (Entry Panel) - True - Squares & Black/White Squares +158268 - 0x17C2E (Entry Panel) - True - Black/White Squares Door - 0x0C2A4 (Entry) - 0x17C2E Bunker (Bunker) - Bunker Glass Room - 0x17C79: -158269 - 0x09F7D (Intro Left 1) - True - Squares & Colored Squares -158270 - 0x09FDC (Intro Left 2) - 0x09F7D - Squares & Colored Squares & Black/White Squares -158271 - 0x09FF7 (Intro Left 3) - 0x09FDC - Squares & Colored Squares & Black/White Squares -158272 - 0x09F82 (Intro Left 4) - 0x09FF7 - Squares & Colored Squares & Black/White Squares -158273 - 0x09FF8 (Intro Left 5) - 0x09F82 - Squares & Colored Squares & Black/White Squares -158274 - 0x09D9F (Intro Back 1) - 0x09FF8 - Squares & Colored Squares & Black/White Squares -158275 - 0x09DA1 (Intro Back 2) - 0x09D9F - Squares & Colored Squares -158276 - 0x09DA2 (Intro Back 3) - 0x09DA1 - Squares & Colored Squares -158277 - 0x09DAF (Intro Back 4) - 0x09DA2 - Squares & Colored Squares +158269 - 0x09F7D (Intro Left 1) - True - Colored Squares +158270 - 0x09FDC (Intro Left 2) - 0x09F7D - Colored Squares & Black/White Squares +158271 - 0x09FF7 (Intro Left 3) - 0x09FDC - Colored Squares & Black/White Squares +158272 - 0x09F82 (Intro Left 4) - 0x09FF7 - Colored Squares & Black/White Squares +158273 - 0x09FF8 (Intro Left 5) - 0x09F82 - Colored Squares & Black/White Squares +158274 - 0x09D9F (Intro Back 1) - 0x09FF8 - Colored Squares & Black/White Squares +158275 - 0x09DA1 (Intro Back 2) - 0x09D9F - Colored Squares +158276 - 0x09DA2 (Intro Back 3) - 0x09DA1 - Colored Squares +158277 - 0x09DAF (Intro Back 4) - 0x09DA2 - Colored Squares 158278 - 0x0A099 (Tinted Glass Door Panel) - 0x09DAF - True Door - 0x17C79 (Tinted Glass Door) - 0x0A099 Bunker Glass Room (Bunker) - Bunker Ultraviolet Room - 0x0C2A3: -158279 - 0x0A010 (Glass Room 1) - 0x17C79 - Squares & Colored Squares -158280 - 0x0A01B (Glass Room 2) - 0x17C79 & 0x0A010 - Squares & Colored Squares & Black/White Squares -158281 - 0x0A01F (Glass Room 3) - 0x17C79 & 0x0A01B - Squares & Colored Squares & Black/White Squares +158279 - 0x0A010 (Glass Room 1) - 0x17C79 - Colored Squares +158280 - 0x0A01B (Glass Room 2) - 0x17C79 & 0x0A010 - Colored Squares & Black/White Squares +158281 - 0x0A01F (Glass Room 3) - 0x17C79 & 0x0A01B - Colored Squares & Black/White Squares Door - 0x0C2A3 (UV Room Entry) - 0x0A01F Bunker Ultraviolet Room (Bunker) - Bunker Elevator Section - 0x0A08D: 158282 - 0x34BC5 (Drop-Down Door Open) - True - True 158283 - 0x34BC6 (Drop-Down Door Close) - 0x34BC5 - True -158284 - 0x17E63 (UV Room 1) - 0x34BC5 - Squares & Colored Squares -158285 - 0x17E67 (UV Room 2) - 0x17E63 & 0x34BC6 - Squares & Colored Squares & Black/White Squares +158284 - 0x17E63 (UV Room 1) - 0x34BC5 - Colored Squares +158285 - 0x17E67 (UV Room 2) - 0x17E63 & 0x34BC6 - Colored Squares & Black/White Squares Door - 0x0A08D (Elevator Room Entry) - 0x17E67 Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay - Bunker Under Elevator - 0x0A079 | Bunker Green Room | Bunker Cyan Room | Bunker Laser Platform: @@ -797,31 +797,31 @@ Swamp Between Bridges Near (Swamp) - Swamp Between Bridges Far - 0x18507: Door - 0x18507 (Between Bridges Second Door) - 0x009A1 Swamp Between Bridges Far (Swamp) - Swamp Red Underwater - 0x183F2 - Swamp Rotating Bridge - TrueOneWay: -158319 - 0x00007 (Between Bridges Far Row 1) - 0x009A1 - Rotated Shapers & Dots & Full Dots -158320 - 0x00008 (Between Bridges Far Row 2) - 0x00007 - Rotated Shapers & Dots & Full Dots -158321 - 0x00009 (Between Bridges Far Row 3) - 0x00008 - Rotated Shapers & Shapers & Dots & Full Dots -158322 - 0x0000A (Between Bridges Far Row 4) - 0x00009 - Rotated Shapers & Shapers & Dots & Full Dots +158319 - 0x00007 (Between Bridges Far Row 1) - 0x009A1 - Rotated Shapers & Full Dots +158320 - 0x00008 (Between Bridges Far Row 2) - 0x00007 - Rotated Shapers & Full Dots +158321 - 0x00009 (Between Bridges Far Row 3) - 0x00008 - Rotated Shapers & Shapers & Full Dots +158322 - 0x0000A (Between Bridges Far Row 4) - 0x00009 - Rotated Shapers & Shapers & Full Dots Door - 0x183F2 (Red Water Pump) - 0x00596 Swamp Red Underwater (Swamp) - Swamp Maze - 0x305D5: -158323 - 0x00001 (Red Underwater 1) - True - Shapers & Negative Shapers & Dots & Full Dots -158324 - 0x014D2 (Red Underwater 2) - True - Shapers & Negative Shapers & Dots & Full Dots -158325 - 0x014D4 (Red Underwater 3) - True - Shapers & Negative Shapers & Dots & Full Dots -158326 - 0x014D1 (Red Underwater 4) - True - Shapers & Negative Shapers & Dots & Full Dots +158323 - 0x00001 (Red Underwater 1) - True - Shapers & Negative Shapers & Full Dots +158324 - 0x014D2 (Red Underwater 2) - True - Shapers & Negative Shapers & Full Dots +158325 - 0x014D4 (Red Underwater 3) - True - Shapers & Negative Shapers & Full Dots +158326 - 0x014D1 (Red Underwater 4) - True - Shapers & Negative Shapers & Full Dots Door - 0x305D5 (Red Underwater Exit) - 0x014D1 Swamp Rotating Bridge (Swamp) - Swamp Between Bridges Far - 0x181F5 - Swamp Near Boat - 0x181F5 - Swamp Purple Area - 0x181F5: -158327 - 0x181F5 (Rotating Bridge) - True - Rotated Shapers & Shapers & Stars & Colored Squares & Triangles & Stars + Same Colored Symbol +158327 - 0x181F5 (Rotating Bridge) - True - Rotated Shapers & Shapers & Colored Squares & Triangles & Stars + Same Colored Symbol 159331 - 0x016B2 (Rotating Bridge CCW EP) - 0x181F5 - True 159334 - 0x036CE (Rotating Bridge CW EP) - 0x181F5 - True Swamp Near Boat (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Blue Underwater - 0x18482 - Swamp Long Bridge - 0xFFD00 & 0xFFD02 - The Ocean - 0x09DB8: 159803 - 0xFFD02 (Beyond Rotating Bridge Reached Independently) - True - True 158328 - 0x09DB8 (Boat Spawn) - True - Boat -158329 - 0x003B2 (Beyond Rotating Bridge 1) - 0x0000A - Shapers & Dots & Full Dots -158330 - 0x00A1E (Beyond Rotating Bridge 2) - 0x003B2 - Rotated Shapers & Shapers & Dots & Full Dots -158331 - 0x00C2E (Beyond Rotating Bridge 3) - 0x00A1E - Shapers & Dots & Full Dots -158332 - 0x00E3A (Beyond Rotating Bridge 4) - 0x00C2E - Shapers & Dots & Full Dots +158329 - 0x003B2 (Beyond Rotating Bridge 1) - 0x0000A - Shapers & Full Dots +158330 - 0x00A1E (Beyond Rotating Bridge 2) - 0x003B2 - Rotated Shapers & Shapers & Full Dots +158331 - 0x00C2E (Beyond Rotating Bridge 3) - 0x00A1E - Shapers & Full Dots +158332 - 0x00E3A (Beyond Rotating Bridge 4) - 0x00C2E - Shapers & Full Dots Door - 0x18482 (Blue Water Pump) - 0x00E3A 159332 - 0x3365F (Boat EP) - 0x09DB8 - True 159333 - 0x03731 (Long Bridge Side EP) - 0x17E2B - True @@ -833,7 +833,7 @@ Swamp Purple Area (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Purple Un Door - 0x0A1D6 (Purple Water Pump) - 0x00E3A Swamp Purple Underwater (Swamp): -158333 - 0x009A6 (Purple Underwater) - True - Shapers & Triangles & Black/White Squares & Rotated Shapers & Dots & Full Dots +158333 - 0x009A6 (Purple Underwater) - True - Shapers & Triangles & Black/White Squares & Rotated Shapers & Full Dots 159330 - 0x03A9E (Purple Underwater Right EP) - True - True 159336 - 0x03A93 (Purple Underwater Left EP) - True - True @@ -851,8 +851,8 @@ Swamp Maze (Swamp) - Swamp Laser Area - 0x17C0A & 0x17E07: Swamp Laser Area (Swamp) - Outside Swamp - 0x2D880: 158711 - 0x03615 (Laser Panel) - True - True Laser - 0x00BF6 (Laser) - 0x03615 -158341 - 0x17C05 (Laser Shortcut Left Panel) - True - Shapers & Stars & Negative Shapers & Stars + Same Colored Symbol -158342 - 0x17C02 (Laser Shortcut Right Panel) - 0x17C05 - Shapers & Negative Shapers & Stars & Stars + Same Colored Symbol +158341 - 0x17C05 (Laser Shortcut Left Panel) - True - Shapers & Negative Shapers & Stars + Same Colored Symbol +158342 - 0x17C02 (Laser Shortcut Right Panel) - 0x17C05 - Shapers & Negative Shapers & Stars + Same Colored Symbol Door - 0x2D880 (Laser Shortcut) - 0x17C02 ==Treehouse== @@ -873,91 +873,91 @@ Treehouse Beach (Treehouse Beach) - Main Island - True: Treehouse Entry Area (Treehouse) - Treehouse Between Entry Doors - 0x0C309 - The Ocean - 0x17C95: 158343 - 0x17C95 (Boat Spawn) - True - Boat -158344 - 0x0288C (First Door Panel) - True - Stars & Stars + Same Colored Symbol & Triangles +158344 - 0x0288C (First Door Panel) - True - Stars + Same Colored Symbol & Triangles Door - 0x0C309 (First Door) - 0x0288C 159210 - 0x33721 (Buoy EP) - 0x17C95 - True Treehouse Between Entry Doors (Treehouse) - Treehouse Yellow Bridge - 0x0C310: -158345 - 0x02886 (Second Door Panel) - True - Stars & Stars + Same Colored Symbol & Triangles +158345 - 0x02886 (Second Door Panel) - True - Stars + Same Colored Symbol & Triangles Door - 0x0C310 (Second Door) - 0x02886 Treehouse Yellow Bridge (Treehouse) - Treehouse After Yellow Bridge - 0x17DC4: -158346 - 0x17D72 (Yellow Bridge 1) - True - Stars & Stars + Same Colored Symbol & Triangles -158347 - 0x17D8F (Yellow Bridge 2) - 0x17D72 - Stars & Stars + Same Colored Symbol & Triangles -158348 - 0x17D74 (Yellow Bridge 3) - 0x17D8F - Stars & Stars + Same Colored Symbol & Triangles -158349 - 0x17DAC (Yellow Bridge 4) - 0x17D74 - Stars & Stars + Same Colored Symbol & Triangles -158350 - 0x17D9E (Yellow Bridge 5) - 0x17DAC - Stars & Stars + Same Colored Symbol & Triangles -158351 - 0x17DB9 (Yellow Bridge 6) - 0x17D9E - Stars & Stars + Same Colored Symbol & Triangles -158352 - 0x17D9C (Yellow Bridge 7) - 0x17DB9 - Stars & Stars + Same Colored Symbol & Triangles -158353 - 0x17DC2 (Yellow Bridge 8) - 0x17D9C - Stars & Stars + Same Colored Symbol & Triangles -158354 - 0x17DC4 (Yellow Bridge 9) - 0x17DC2 - Stars & Stars + Same Colored Symbol & Triangles +158346 - 0x17D72 (Yellow Bridge 1) - True - Stars + Same Colored Symbol & Triangles +158347 - 0x17D8F (Yellow Bridge 2) - 0x17D72 - Stars + Same Colored Symbol & Triangles +158348 - 0x17D74 (Yellow Bridge 3) - 0x17D8F - Stars + Same Colored Symbol & Triangles +158349 - 0x17DAC (Yellow Bridge 4) - 0x17D74 - Stars + Same Colored Symbol & Triangles +158350 - 0x17D9E (Yellow Bridge 5) - 0x17DAC - Stars + Same Colored Symbol & Triangles +158351 - 0x17DB9 (Yellow Bridge 6) - 0x17D9E - Stars + Same Colored Symbol & Triangles +158352 - 0x17D9C (Yellow Bridge 7) - 0x17DB9 - Stars + Same Colored Symbol & Triangles +158353 - 0x17DC2 (Yellow Bridge 8) - 0x17D9C - Stars + Same Colored Symbol & Triangles +158354 - 0x17DC4 (Yellow Bridge 9) - 0x17DC2 - Stars + Same Colored Symbol & Triangles Treehouse After Yellow Bridge (Treehouse) - Treehouse Junction - 0x0A181: -158355 - 0x0A182 (Third Door Panel) - True - Stars & Stars + Same Colored Symbol & Triangles & Colored Squares +158355 - 0x0A182 (Third Door Panel) - True - Stars + Same Colored Symbol & Triangles & Colored Squares Door - 0x0A181 (Third Door) - 0x0A182 Treehouse Junction (Treehouse) - Treehouse Right Orange Bridge - True - Treehouse First Purple Bridge - True - Treehouse Green Bridge - True: 158356 - 0x2700B (Laser House Door Timer Outside) - True - True Treehouse First Purple Bridge (Treehouse) - Treehouse Second Purple Bridge - 0x17D6C: -158357 - 0x17DC8 (First Purple Bridge 1) - True - Stars & Dots & Full Dots -158358 - 0x17DC7 (First Purple Bridge 2) - 0x17DC8 - Stars & Dots & Full Dots -158359 - 0x17CE4 (First Purple Bridge 3) - 0x17DC7 - Stars & Dots & Full Dots -158360 - 0x17D2D (First Purple Bridge 4) - 0x17CE4 - Stars & Dots & Full Dots -158361 - 0x17D6C (First Purple Bridge 5) - 0x17D2D - Stars & Dots & Full Dots +158357 - 0x17DC8 (First Purple Bridge 1) - True - Stars & Full Dots +158358 - 0x17DC7 (First Purple Bridge 2) - 0x17DC8 - Stars & Full Dots +158359 - 0x17CE4 (First Purple Bridge 3) - 0x17DC7 - Stars & Full Dots +158360 - 0x17D2D (First Purple Bridge 4) - 0x17CE4 - Stars & Full Dots +158361 - 0x17D6C (First Purple Bridge 5) - 0x17D2D - Stars & Full Dots Treehouse Right Orange Bridge (Treehouse) - Treehouse Drawbridge Platform - 0x17DA2: -158391 - 0x17D88 (Right Orange Bridge 1) - True - Stars & Stars + Same Colored Symbol & Triangles -158392 - 0x17DB4 (Right Orange Bridge 2) - 0x17D88 - Stars & Stars + Same Colored Symbol & Triangles -158393 - 0x17D8C (Right Orange Bridge 3) - 0x17DB4 - Stars & Stars + Same Colored Symbol & Triangles +158391 - 0x17D88 (Right Orange Bridge 1) - True - Stars + Same Colored Symbol & Triangles +158392 - 0x17DB4 (Right Orange Bridge 2) - 0x17D88 - Stars + Same Colored Symbol & Triangles +158393 - 0x17D8C (Right Orange Bridge 3) - 0x17DB4 - Stars + Same Colored Symbol & Triangles 158394 - 0x17CE3 (Right Orange Bridge 4 & Directional) - 0x17D8C - Triangles -158395 - 0x17DCD (Right Orange Bridge 5) - 0x17CE3 - Stars & Stars + Same Colored Symbol & Triangles -158396 - 0x17DB2 (Right Orange Bridge 6) - 0x17DCD - Stars & Stars + Same Colored Symbol & Triangles -158397 - 0x17DCC (Right Orange Bridge 7) - 0x17DB2 - Stars & Stars + Same Colored Symbol & Triangles -158398 - 0x17DCA (Right Orange Bridge 8) - 0x17DCC - Stars & Stars + Same Colored Symbol & Triangles -158399 - 0x17D8E (Right Orange Bridge 9) - 0x17DCA - Stars & Stars + Same Colored Symbol & Triangles +158395 - 0x17DCD (Right Orange Bridge 5) - 0x17CE3 - Stars + Same Colored Symbol & Triangles +158396 - 0x17DB2 (Right Orange Bridge 6) - 0x17DCD - Stars + Same Colored Symbol & Triangles +158397 - 0x17DCC (Right Orange Bridge 7) - 0x17DB2 - Stars + Same Colored Symbol & Triangles +158398 - 0x17DCA (Right Orange Bridge 8) - 0x17DCC - Stars + Same Colored Symbol & Triangles +158399 - 0x17D8E (Right Orange Bridge 9) - 0x17DCA - Stars + Same Colored Symbol & Triangles 158400 - 0x17DB7 (Right Orange Bridge 10 & Directional) - 0x17D8E - Triangles -158401 - 0x17DB1 (Right Orange Bridge 11) - 0x17DB7 - Stars & Stars + Same Colored Symbol & Triangles -158402 - 0x17DA2 (Right Orange Bridge 12) - 0x17DB1 - Stars & Stars + Same Colored Symbol & Triangles +158401 - 0x17DB1 (Right Orange Bridge 11) - 0x17DB7 - Stars + Same Colored Symbol & Triangles +158402 - 0x17DA2 (Right Orange Bridge 12) - 0x17DB1 - Stars + Same Colored Symbol & Triangles Treehouse Drawbridge Platform (Treehouse) - Main Island - 0x0C32D: 158404 - 0x037FF (Drawbridge Panel) - True - Stars Door - 0x0C32D (Drawbridge) - 0x037FF Treehouse Second Purple Bridge (Treehouse) - Treehouse Left Orange Bridge - 0x17DC6: -158362 - 0x17D9B (Second Purple Bridge 1) - True - Stars & Black/White Squares & Triangles & Stars + Same Colored Symbol -158363 - 0x17D99 (Second Purple Bridge 2) - 0x17D9B - Stars & Black/White Squares & Triangles & Stars + Same Colored Symbol -158364 - 0x17DAA (Second Purple Bridge 3) - 0x17D99 - Stars & Black/White Squares & Triangles & Stars + Same Colored Symbol -158365 - 0x17D97 (Second Purple Bridge 4) - 0x17DAA - Stars & Black/White Squares & Colored Squares & Triangles & Stars + Same Colored Symbol -158366 - 0x17BDF (Second Purple Bridge 5) - 0x17D97 - Stars & Colored Squares & Triangles & Stars + Same Colored Symbol -158367 - 0x17D91 (Second Purple Bridge 6) - 0x17BDF - Stars & Colored Squares & Triangles & Stars + Same Colored Symbol -158368 - 0x17DC6 (Second Purple Bridge 7) - 0x17D91 - Stars & Colored Squares & Triangles & Stars + Same Colored Symbol +158362 - 0x17D9B (Second Purple Bridge 1) - True - Black/White Squares & Triangles & Stars + Same Colored Symbol +158363 - 0x17D99 (Second Purple Bridge 2) - 0x17D9B - Black/White Squares & Triangles & Stars + Same Colored Symbol +158364 - 0x17DAA (Second Purple Bridge 3) - 0x17D99 - Black/White Squares & Triangles & Stars + Same Colored Symbol +158365 - 0x17D97 (Second Purple Bridge 4) - 0x17DAA - Black/White Squares & Colored Squares & Triangles & Stars + Same Colored Symbol +158366 - 0x17BDF (Second Purple Bridge 5) - 0x17D97 - Colored Squares & Triangles & Stars + Same Colored Symbol +158367 - 0x17D91 (Second Purple Bridge 6) - 0x17BDF - Colored Squares & Triangles & Stars + Same Colored Symbol +158368 - 0x17DC6 (Second Purple Bridge 7) - 0x17D91 - Colored Squares & Triangles & Stars + Same Colored Symbol Treehouse Left Orange Bridge (Treehouse) - Treehouse Laser Room Front Platform - 0x17DDE - Treehouse Laser Room Back Platform - 0x17DDB - Treehouse Burned House - 0x17DDB: -158376 - 0x17DB3 (Left Orange Bridge 1) - True - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers -158377 - 0x17DB5 (Left Orange Bridge 2) - 0x17DB3 - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers -158378 - 0x17DB6 (Left Orange Bridge 3) - 0x17DB5 - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers -158379 - 0x17DC0 (Left Orange Bridge 4) - 0x17DB6 - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers -158380 - 0x17DD7 (Left Orange Bridge 5) - 0x17DC0 - Stars & Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers -158381 - 0x17DD9 (Left Orange Bridge 6) - 0x17DD7 - Stars & Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers -158382 - 0x17DB8 (Left Orange Bridge 7) - 0x17DD9 - Stars & Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers -158383 - 0x17DDC (Left Orange Bridge 8) - 0x17DB8 - Stars & Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers -158384 - 0x17DD1 (Left Orange Bridge 9 & Directional) - 0x17DDC - Stars & Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Black/White Squares -158385 - 0x17DDE (Left Orange Bridge 10) - 0x17DD1 - Stars & Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Black/White Squares -158386 - 0x17DE3 (Left Orange Bridge 11) - 0x17DDE - Stars & Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Black/White Squares -158387 - 0x17DEC (Left Orange Bridge 12) - 0x17DE3 - Stars & Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Black/White Squares -158388 - 0x17DAE (Left Orange Bridge 13) - 0x17DEC & 0x03613 - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Triangles -158389 - 0x17DB0 (Left Orange Bridge 14) - 0x17DAE - Stars & Black/White Squares & Stars + Same Colored Symbol -158390 - 0x17DDB (Left Orange Bridge 15) - 0x17DB0 - Stars & Black/White Squares & Stars + Same Colored Symbol +158376 - 0x17DB3 (Left Orange Bridge 1) - True - Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers +158377 - 0x17DB5 (Left Orange Bridge 2) - 0x17DB3 - Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers +158378 - 0x17DB6 (Left Orange Bridge 3) - 0x17DB5 - Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers +158379 - 0x17DC0 (Left Orange Bridge 4) - 0x17DB6 - Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers +158380 - 0x17DD7 (Left Orange Bridge 5) - 0x17DC0 - Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers +158381 - 0x17DD9 (Left Orange Bridge 6) - 0x17DD7 - Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers +158382 - 0x17DB8 (Left Orange Bridge 7) - 0x17DD9 - Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers +158383 - 0x17DDC (Left Orange Bridge 8) - 0x17DB8 - Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers +158384 - 0x17DD1 (Left Orange Bridge 9 & Directional) - 0x17DDC - Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Black/White Squares +158385 - 0x17DDE (Left Orange Bridge 10) - 0x17DD1 - Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Black/White Squares +158386 - 0x17DE3 (Left Orange Bridge 11) - 0x17DDE - Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Black/White Squares +158387 - 0x17DEC (Left Orange Bridge 12) - 0x17DE3 - Colored Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Black/White Squares +158388 - 0x17DAE (Left Orange Bridge 13) - 0x17DEC & 0x03613 - Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Triangles +158389 - 0x17DB0 (Left Orange Bridge 14) - 0x17DAE - Black/White Squares & Stars + Same Colored Symbol +158390 - 0x17DDB (Left Orange Bridge 15) - 0x17DB0 - Black/White Squares & Stars + Same Colored Symbol Treehouse Green Bridge (Treehouse) - Treehouse Green Bridge Front House - 0x17E61 - Treehouse Green Bridge Left House - 0x17E61: -158369 - 0x17E3C (Green Bridge 1) - True - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158370 - 0x17E4D (Green Bridge 2) - 0x17E3C - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158371 - 0x17E4F (Green Bridge 3) - 0x17E4D - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158372 - 0x17E52 (Green Bridge 4 & Directional) - 0x17E4F - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158373 - 0x17E5B (Green Bridge 5) - 0x17E52 - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158374 - 0x17E5F (Green Bridge 6) - 0x17E5B - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol & Triangles -158375 - 0x17E61 (Green Bridge 7) - 0x17E5F - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol & Triangles +158369 - 0x17E3C (Green Bridge 1) - True - Shapers & Negative Shapers & Stars + Same Colored Symbol +158370 - 0x17E4D (Green Bridge 2) - 0x17E3C - Shapers & Negative Shapers & Stars + Same Colored Symbol +158371 - 0x17E4F (Green Bridge 3) - 0x17E4D - Shapers & Negative Shapers & Stars + Same Colored Symbol +158372 - 0x17E52 (Green Bridge 4 & Directional) - 0x17E4F - Shapers & Negative Shapers & Stars + Same Colored Symbol +158373 - 0x17E5B (Green Bridge 5) - 0x17E52 - Shapers & Negative Shapers & Stars + Same Colored Symbol +158374 - 0x17E5F (Green Bridge 6) - 0x17E5B - Shapers & Negative Shapers & Stars + Same Colored Symbol & Triangles +158375 - 0x17E61 (Green Bridge 7) - 0x17E5F - Shapers & Negative Shapers & Stars + Same Colored Symbol & Triangles Treehouse Green Bridge Front House (Treehouse): 158610 - 0x17FA9 (Green Bridge Discard) - True - Arrows @@ -993,7 +993,7 @@ Mountainside Obelisk (Mountainside) - Entry - True: Mountainside (Mountainside) - Main Island - True - Mountaintop - True - Mountainside Vault - 0x00085: 159550 - 0x28B91 (Thundercloud EP) - 0xFFD03 - True 158612 - 0x17C42 (Discard) - True - Arrows -158665 - 0x002A6 (Vault Panel) - True - Symmetry & Colored Squares & Triangles & Stars & Stars + Same Colored Symbol +158665 - 0x002A6 (Vault Panel) - True - Symmetry & Colored Squares & Triangles & Stars + Same Colored Symbol Door - 0x00085 (Vault Door) - 0x002A6 159301 - 0x335AE (Cloud Cycle EP) - True - True 159325 - 0x33505 (Bush EP) - True - True @@ -1005,7 +1005,7 @@ Mountainside Vault (Mountainside): Mountaintop (Mountaintop) - Mountain Floor 1 - 0x17C34: 158405 - 0x0042D (River Shape) - True - True 158406 - 0x09F7F (Box Short) - 7 Lasers + Redirect - True -158407 - 0x17C34 (Mountain Entry Panel) - 0x09F7F - Stars & Black/White Squares & Stars + Same Colored Symbol & Triangles +158407 - 0x17C34 (Mountain Entry Panel) - 0x09F7F - Black/White Squares & Stars + Same Colored Symbol & Triangles 158800 - 0xFFF00 (Box Long) - 11 Lasers + Redirect & 0x17C34 - True 159300 - 0x001A3 (River Shape EP) - True - True 159320 - 0x3370E (Arch Black EP) - True - True @@ -1018,18 +1018,18 @@ Mountain Floor 1 (Mountain Floor 1) - Mountain Floor 1 Bridge - 0x09E39: 158408 - 0x09E39 (Light Bridge Controller) - True - Eraser & Triangles Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneWay - Mountain Floor 1 Trash Pillar - TrueOneWay - Mountain Floor 1 Back Section - TrueOneWay: -158409 - 0x09E7A (Right Row 1) - True - Black/White Squares & Dots & Stars & Stars + Same Colored Symbol +158409 - 0x09E7A (Right Row 1) - True - Black/White Squares & Dots & Stars + Same Colored Symbol 158410 - 0x09E71 (Right Row 2) - 0x09E7A - Black/White Squares & Triangles -158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers & Stars & Stars + Same Colored Symbol -158412 - 0x09E69 (Right Row 4) - 0x09E72 - Stars & Black/White Squares & Stars + Same Colored Symbol & Rotated Shapers -158413 - 0x09E7B (Right Row 5) - 0x09E69 - Stars & Black/White Squares & Stars + Same Colored Symbol & Eraser & Dots & Triangles & Shapers +158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers & Stars + Same Colored Symbol +158412 - 0x09E69 (Right Row 4) - 0x09E72 - Black/White Squares & Stars + Same Colored Symbol & Rotated Shapers +158413 - 0x09E7B (Right Row 5) - 0x09E69 - Black/White Squares & Stars + Same Colored Symbol & Eraser & Dots & Triangles & Shapers 158414 - 0x09E73 (Left Row 1) - True - Dots & Black/White Squares & Triangles 158415 - 0x09E75 (Left Row 2) - 0x09E73 - Dots & Black/White Squares & Shapers & Rotated Shapers -158416 - 0x09E78 (Left Row 3) - 0x09E75 - Stars & Triangles & Stars + Same Colored Symbol & Shapers & Rotated Shapers -158417 - 0x09E79 (Left Row 4) - 0x09E78 - Stars & Colored Squares & Stars + Same Colored Symbol & Triangles & Eraser -158418 - 0x09E6C (Left Row 5) - 0x09E79 - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158419 - 0x09E6F (Left Row 6) - 0x09E6C - Symmetry & Stars & Colored Squares & Black/White Squares & Stars + Same Colored Symbol & Symmetry & Eraser -158420 - 0x09E6B (Left Row 7) - 0x09E6F - Symmetry & Dots & Full Dots & Triangles +158416 - 0x09E78 (Left Row 3) - 0x09E75 - Triangles & Stars + Same Colored Symbol & Shapers & Rotated Shapers +158417 - 0x09E79 (Left Row 4) - 0x09E78 - Colored Squares & Stars + Same Colored Symbol & Triangles & Eraser +158418 - 0x09E6C (Left Row 5) - 0x09E79 - Shapers & Negative Shapers & Stars + Same Colored Symbol +158419 - 0x09E6F (Left Row 6) - 0x09E6C - Symmetry & Colored Squares & Black/White Squares & Stars + Same Colored Symbol & Symmetry & Eraser +158420 - 0x09E6B (Left Row 7) - 0x09E6F - Symmetry & Full Dots & Triangles 158424 - 0x09EAD (Trash Pillar 1) - True - Rotated Shapers & Stars 158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Rotated Shapers & Triangles @@ -1037,18 +1037,18 @@ Mountain Floor 1 Trash Pillar (Mountain Floor 1): Mountain Floor 1 Back Section (Mountain Floor 1): 158421 - 0x33AF5 (Back Row 1) - True - Symmetry & Black/White Squares & Triangles -158422 - 0x33AF7 (Back Row 2) - 0x33AF5 - Symmetry & Stars & Triangles & Stars + Same Colored Symbol -158423 - 0x09F6E (Back Row 3) - 0x33AF7 - Symmetry & Stars & Shapers & Stars + Same Colored Symbol +158422 - 0x33AF7 (Back Row 2) - 0x33AF5 - Symmetry & Triangles & Stars + Same Colored Symbol +158423 - 0x09F6E (Back Row 3) - 0x33AF7 - Symmetry & Shapers & Stars + Same Colored Symbol Mountain Floor 1 At Door (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B Mountain Floor 2 (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Near - 0x09FFB - Mountain Floor 2 Beyond Bridge - 0x09E86 - Mountain Floor 2 Above The Abyss - True - Mountain Pink Bridge EP - TrueOneWay: -158426 - 0x09FD3 (Near Row 1) - True - Stars & Colored Squares & Stars + Same Colored Symbol -158427 - 0x09FD4 (Near Row 2) - 0x09FD3 - Stars & Triangles & Stars + Same Colored Symbol -158428 - 0x09FD6 (Near Row 3) - 0x09FD4 - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol +158426 - 0x09FD3 (Near Row 1) - True - Colored Squares & Stars + Same Colored Symbol +158427 - 0x09FD4 (Near Row 2) - 0x09FD3 - Triangles & Stars + Same Colored Symbol +158428 - 0x09FD6 (Near Row 3) - 0x09FD4 - Shapers & Negative Shapers & Stars + Same Colored Symbol 158429 - 0x09FD7 (Near Row 4) - 0x09FD6 - Stars -158430 - 0x09FD8 (Near Row 5) - 0x09FD7 - Stars & Stars + Same Colored Symbol & Rotated Shapers & Eraser +158430 - 0x09FD8 (Near Row 5) - 0x09FD7 - Stars + Same Colored Symbol & Rotated Shapers & Eraser Door - 0x09FFB (Staircase Near) - 0x09FD8 Mountain Floor 2 Above The Abyss (Mountain Floor 2) - Mountain Floor 2 Elevator Room - 0x09EDD & 0x09ED8 & 0x09E86: @@ -1059,8 +1059,8 @@ Mountain Floor 2 Light Bridge Room Near (Mountain Floor 2): Mountain Floor 2 Beyond Bridge (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Far - 0x09E07 - Mountain Pink Bridge EP - TrueOneWay - Mountain Floor 2 - 0x09ED8: 158432 - 0x09FCC (Far Row 1) - True - Triangles -158433 - 0x09FCE (Far Row 2) - 0x09FCC - Black/White Squares & Stars & Stars + Same Colored Symbol -158434 - 0x09FCF (Far Row 3) - 0x09FCE - Stars & Triangles & Stars + Same Colored Symbol +158433 - 0x09FCE (Far Row 2) - 0x09FCC - Black/White Squares & Stars + Same Colored Symbol +158434 - 0x09FCF (Far Row 3) - 0x09FCE - Triangles & Stars + Same Colored Symbol 158435 - 0x09FD0 (Far Row 4) - 0x09FCF - Rotated Shapers & Negative Shapers 158436 - 0x09FD1 (Far Row 5) - 0x09FD0 - Dots 158437 - 0x09FD2 (Far Row 6) - 0x09FD1 - Rotated Shapers @@ -1088,19 +1088,19 @@ Door - 0x09F89 (Exit) - 0x09FDA Mountain Bottom Floor (Mountain Bottom Floor) - Mountain Path to Caves - 0x17F33 - Mountain Bottom Floor Pillars Room - 0x0C141: 158614 - 0x17FA2 (Discard) - 0xFFF00 - Arrows 158445 - 0x01983 (Pillars Room Entry Left) - True - Shapers & Stars -158446 - 0x01987 (Pillars Room Entry Right) - True - Squares & Colored Squares & Dots +158446 - 0x01987 (Pillars Room Entry Right) - True - Colored Squares & Dots Door - 0x0C141 (Pillars Room Entry) - 0x01983 & 0x01987 Door - 0x17F33 (Rock Open) - 0x17FA2 | 0x334E1 Mountain Bottom Floor Pillars Room (Mountain Bottom Floor) - Elevator - 0x339BB & 0x33961: -158522 - 0x0383A (Right Pillar 1) - True - Stars & Eraser & Triangles & Stars + Same Colored Symbol -158523 - 0x09E56 (Right Pillar 2) - 0x0383A - Dots & Full Dots & Triangles & Symmetry -158524 - 0x09E5A (Right Pillar 3) - 0x09E56 - Dots & Shapers & Stars & Negative Shapers & Stars + Same Colored Symbol & Symmetry -158525 - 0x33961 (Right Pillar 4) - 0x09E5A - Eraser & Symmetry & Stars & Stars + Same Colored Symbol & Negative Shapers & Shapers -158526 - 0x0383D (Left Pillar 1) - True - Stars & Black/White Squares & Stars + Same Colored Symbol +158522 - 0x0383A (Right Pillar 1) - True - Eraser & Triangles & Stars + Same Colored Symbol +158523 - 0x09E56 (Right Pillar 2) - 0x0383A - Full Dots & Triangles & Symmetry +158524 - 0x09E5A (Right Pillar 3) - 0x09E56 - Dots & Shapers & Negative Shapers & Stars + Same Colored Symbol & Symmetry +158525 - 0x33961 (Right Pillar 4) - 0x09E5A - Eraser & Symmetry & Stars + Same Colored Symbol & Negative Shapers & Shapers +158526 - 0x0383D (Left Pillar 1) - True - Black/White Squares & Stars + Same Colored Symbol 158527 - 0x0383F (Left Pillar 2) - 0x0383D - Triangles & Symmetry 158528 - 0x03859 (Left Pillar 3) - 0x0383F - Symmetry & Shapers & Black/White Squares -158529 - 0x339BB (Left Pillar 4) - 0x03859 - Symmetry & Black/White Squares & Stars & Stars + Same Colored Symbol & Triangles & Colored Dots +158529 - 0x339BB (Left Pillar 4) - 0x03859 - Symmetry & Black/White Squares & Stars + Same Colored Symbol & Triangles & Colored Dots Elevator (Mountain Bottom Floor): 158530 - 0x3D9A6 (Elevator Door Close Left) - True - True @@ -1124,9 +1124,9 @@ Door - 0x2D77D (Caves Entry) - 0x00FF8 Caves Entry Door (Caves): Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x019A5 - Caves Entry Door - TrueOneWay: -158451 - 0x335AB (Elevator Inside Control) - True - Dots & Squares & Black/White Squares -158452 - 0x335AC (Elevator Upper Outside Control) - 0x335AB - Squares & Black/White Squares -158453 - 0x3369D (Elevator Lower Outside Control) - 0x335AB - Squares & Black/White Squares & Dots +158451 - 0x335AB (Elevator Inside Control) - True - Dots & Black/White Squares +158452 - 0x335AC (Elevator Upper Outside Control) - 0x335AB - Black/White Squares +158453 - 0x3369D (Elevator Lower Outside Control) - 0x335AB - Black/White Squares & Dots 158454 - 0x00190 (Blue Tunnel Right First 1) - True - Arrows 158455 - 0x00558 (Blue Tunnel Right First 2) - 0x00190 - Arrows 158456 - 0x00567 (Blue Tunnel Right First 3) - 0x00558 - Arrows @@ -1145,41 +1145,41 @@ Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x01 158469 - 0x009A4 (Blue Tunnel Left Third 1) - True - Arrows & Stars 158470 - 0x018A0 (Blue Tunnel Right Third 1) - True - Arrows & Symmetry 158471 - 0x00A72 (Blue Tunnel Left Fourth 1) - True - Arrows & Shapers & Negative Shapers -158472 - 0x32962 (First Floor Left) - True - Dots & Full Dots & Rotated Shapers -158473 - 0x32966 (First Floor Grounded) - True - Stars & Triangles & Rotated Shapers & Black/White Squares & Stars + Same Colored Symbol +158472 - 0x32962 (First Floor Left) - True - Full Dots & Rotated Shapers +158473 - 0x32966 (First Floor Grounded) - True - Triangles & Rotated Shapers & Black/White Squares & Stars + Same Colored Symbol 158474 - 0x01A31 (First Floor Middle) - True - Stars -158475 - 0x00B71 (First Floor Right) - True - Dots & Full Dots & Eraser & Stars & Stars + Same Colored Symbol & Colored Squares & Shapers & Negative Shapers +158475 - 0x00B71 (First Floor Right) - True - Full Dots & Eraser & Stars + Same Colored Symbol & Colored Squares & Shapers & Negative Shapers 158478 - 0x288EA (First Wooden Beam) - True - Stars 158479 - 0x288FC (Second Wooden Beam) - True - Shapers & Eraser 158480 - 0x289E7 (Third Wooden Beam) - True - Eraser & Triangles -158481 - 0x288AA (Fourth Wooden Beam) - True - Dots & Full Dots & Negative Shapers & Shapers -158482 - 0x17FB9 (Left Upstairs Single) - True - Dots & Full Dots & Arrows & Black/White Squares -158483 - 0x0A16B (Left Upstairs Left Row 1) - True - Dots & Full Dots & Arrows -158484 - 0x0A2CE (Left Upstairs Left Row 2) - 0x0A16B - Dots & Full Dots & Arrows -158485 - 0x0A2D7 (Left Upstairs Left Row 3) - 0x0A2CE - Dots & Full Dots & Arrows -158486 - 0x0A2DD (Left Upstairs Left Row 4) - 0x0A2D7 - Dots & Full Dots & Arrows -158487 - 0x0A2EA (Left Upstairs Left Row 5) - 0x0A2DD - Dots & Full Dots & Arrows +158481 - 0x288AA (Fourth Wooden Beam) - True - Full Dots & Negative Shapers & Shapers +158482 - 0x17FB9 (Left Upstairs Single) - True - Full Dots & Arrows & Black/White Squares +158483 - 0x0A16B (Left Upstairs Left Row 1) - True - Full Dots & Arrows +158484 - 0x0A2CE (Left Upstairs Left Row 2) - 0x0A16B - Full Dots & Arrows +158485 - 0x0A2D7 (Left Upstairs Left Row 3) - 0x0A2CE - Full Dots & Arrows +158486 - 0x0A2DD (Left Upstairs Left Row 4) - 0x0A2D7 - Full Dots & Arrows +158487 - 0x0A2EA (Left Upstairs Left Row 5) - 0x0A2DD - Full Dots & Arrows 158488 - 0x0008F (Right Upstairs Left Row 1) - True - Dots & Black/White Squares & Colored Squares -158489 - 0x0006B (Right Upstairs Left Row 2) - 0x0008F - Stars & Black/White Squares & Colored Squares & Stars + Same Colored Symbol -158490 - 0x0008B (Right Upstairs Left Row 3) - 0x0006B - Stars & Black/White Squares & Colored Squares & Stars + Same Colored Symbol & Triangles -158491 - 0x0008C (Right Upstairs Left Row 4) - 0x0008B - Stars & Stars + Same Colored Symbol & Shapers & Rotated Shapers -158492 - 0x0008A (Right Upstairs Left Row 5) - 0x0008C - Stars & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Eraser & Triangles +158489 - 0x0006B (Right Upstairs Left Row 2) - 0x0008F - Black/White Squares & Colored Squares & Stars + Same Colored Symbol +158490 - 0x0008B (Right Upstairs Left Row 3) - 0x0006B - Black/White Squares & Colored Squares & Stars + Same Colored Symbol & Triangles +158491 - 0x0008C (Right Upstairs Left Row 4) - 0x0008B - Stars + Same Colored Symbol & Shapers & Rotated Shapers +158492 - 0x0008A (Right Upstairs Left Row 5) - 0x0008C - Stars + Same Colored Symbol & Shapers & Rotated Shapers & Eraser & Triangles 158493 - 0x00089 (Right Upstairs Left Row 6) - 0x0008A - Shapers & Negative Shapers & Dots 158494 - 0x0006A (Right Upstairs Left Row 7) - 0x00089 - Stars & Dots -158495 - 0x0006C (Right Upstairs Left Row 8) - 0x0006A - Dots & Stars & Stars + Same Colored Symbol & Eraser +158495 - 0x0006C (Right Upstairs Left Row 8) - 0x0006A - Dots & Stars + Same Colored Symbol & Eraser 158496 - 0x00027 (Right Upstairs Right Row 1) - True - Colored Squares & Black/White Squares & Eraser 158497 - 0x00028 (Right Upstairs Right Row 2) - 0x00027 - Shapers & Symmetry 158498 - 0x00029 (Right Upstairs Right Row 3) - 0x00028 - Symmetry & Triangles & Eraser 158476 - 0x09DD5 (Lone Pillar) - True - Arrows Door - 0x019A5 (Pillar Door) - 0x09DD5 -158449 - 0x021D7 (Mountain Shortcut Panel) - True - Stars & Stars + Same Colored Symbol & Triangles & Eraser +158449 - 0x021D7 (Mountain Shortcut Panel) - True - Stars + Same Colored Symbol & Triangles & Eraser Door - 0x2D73F (Mountain Shortcut Door) - 0x021D7 158450 - 0x17CF2 (Swamp Shortcut Panel) - True - Arrows Door - 0x2D859 (Swamp Shortcut Door) - 0x17CF2 159341 - 0x3397C (Skylight EP) - True - True Caves Path to Challenge (Caves) - Challenge - 0x0A19A: -158477 - 0x0A16E (Challenge Entry Panel) - True - Stars & Arrows & Stars + Same Colored Symbol +158477 - 0x0A16E (Challenge Entry Panel) - True - Arrows & Stars + Same Colored Symbol Door - 0x0A19A (Challenge Entry) - 0x0A16E ==Challenge== diff --git a/worlds/witness/data/WitnessLogicVanilla.txt b/worlds/witness/data/WitnessLogicVanilla.txt index a967a12e28c0..f3fa51bb9db2 100644 --- a/worlds/witness/data/WitnessLogicVanilla.txt +++ b/worlds/witness/data/WitnessLogicVanilla.txt @@ -52,11 +52,11 @@ Outside Tutorial Vault (Outside Tutorial): 158651 - 0x03481 (Vault Box) - True - True Outside Tutorial Path To Outpost (Outside Tutorial) - Outside Tutorial Outpost - 0x0A170: -158011 - 0x0A171 (Outpost Entry Panel) - True - Dots & Full Dots +158011 - 0x0A171 (Outpost Entry Panel) - True - Full Dots Door - 0x0A170 (Outpost Entry) - 0x0A171 Outside Tutorial Outpost (Outside Tutorial) - Outside Tutorial - 0x04CA3: -158012 - 0x04CA4 (Outpost Exit Panel) - True - Dots & Full Dots +158012 - 0x04CA4 (Outpost Exit Panel) - True - Full Dots Door - 0x04CA3 (Outpost Exit) - 0x04CA4 158600 - 0x17CFB (Discard) - True - Triangles @@ -136,12 +136,12 @@ Door - 0x18269 (Upper) - 0x1C349 159000 - 0x0332B (Glass Factory Black Line Reflection EP) - True - True Symmetry Island Upper (Symmetry Island): -158065 - 0x00A52 (Laser Yellow 1) - True - Symmetry & Colored Dots -158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Symmetry & Colored Dots -158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Symmetry & Colored Dots -158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Symmetry & Colored Dots -158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Symmetry & Colored Dots -158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Symmetry & Colored Dots +158065 - 0x00A52 (Laser Yellow 1) - True - Colored Dots +158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Colored Dots +158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Colored Dots +158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Colored Dots +158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Colored Dots +158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Colored Dots 158700 - 0x0360D (Laser Panel) - 0x00A68 - True Laser - 0x00509 (Laser) - 0x0360D 159001 - 0x03367 (Glass Factory Black Line EP) - True - True @@ -157,7 +157,7 @@ Desert Obelisk (Desert) - Entry - True: 159709 - 0x00359 (Obelisk) - True - True Desert Outside (Desert) - Main Island - True - Desert Light Room - 0x09FEE - Desert Vault - 0x03444: -158652 - 0x0CC7B (Vault Panel) - True - Dots & Shapers & Rotated Shapers & Negative Shapers & Full Dots +158652 - 0x0CC7B (Vault Panel) - True - Shapers & Rotated Shapers & Negative Shapers & Full Dots Door - 0x03444 (Vault Door) - 0x0CC7B 158602 - 0x17CE7 (Discard) - True - Triangles 158076 - 0x00698 (Surface 1) - True - True @@ -285,7 +285,7 @@ Quarry Stoneworks Middle Floor (Quarry Stoneworks) - Quarry Stoneworks Lift - Tr 158125 - 0x00E0C (Lower Row 1) - True - Dots & Eraser 158126 - 0x01489 (Lower Row 2) - 0x00E0C - Dots & Eraser 158127 - 0x0148A (Lower Row 3) - 0x01489 - Dots & Eraser -158128 - 0x014D9 (Lower Row 4) - 0x0148A - Dots & Full Dots & Eraser +158128 - 0x014D9 (Lower Row 4) - 0x0148A - Full Dots & Eraser 158129 - 0x014E7 (Lower Row 5) - 0x014D9 - Dots 158130 - 0x014E8 (Lower Row 6) - 0x014E7 - Dots & Eraser @@ -336,12 +336,12 @@ Quarry Boathouse Upper Back (Quarry Boathouse) - Quarry Boathouse Upper Middle - 158155 - 0x38663 (Second Barrier Panel) - True - True Door - 0x3865F (Second Barrier) - 0x38663 158156 - 0x021B5 (Back First Row 1) - True - Stars & Eraser -158157 - 0x021B6 (Back First Row 2) - 0x021B5 - Stars & Stars + Same Colored Symbol & Eraser +158157 - 0x021B6 (Back First Row 2) - 0x021B5 - Stars + Same Colored Symbol & Eraser 158158 - 0x021B7 (Back First Row 3) - 0x021B6 - Stars & Eraser -158159 - 0x021BB (Back First Row 4) - 0x021B7 - Stars & Stars + Same Colored Symbol & Eraser -158160 - 0x09DB5 (Back First Row 5) - 0x021BB - Stars & Stars + Same Colored Symbol & Eraser -158161 - 0x09DB1 (Back First Row 6) - 0x09DB5 - Stars & Stars + Same Colored Symbol & Eraser -158162 - 0x3C124 (Back First Row 7) - 0x09DB1 - Stars & Stars + Same Colored Symbol & Eraser +158159 - 0x021BB (Back First Row 4) - 0x021B7 - Stars + Same Colored Symbol & Eraser +158160 - 0x09DB5 (Back First Row 5) - 0x021BB - Stars + Same Colored Symbol & Eraser +158161 - 0x09DB1 (Back First Row 6) - 0x09DB5 - Stars + Same Colored Symbol & Eraser +158162 - 0x3C124 (Back First Row 7) - 0x09DB1 - Stars + Same Colored Symbol & Eraser 158163 - 0x09DB3 (Back First Row 8) - 0x3C124 - Stars & Eraser & Shapers 158164 - 0x09DB4 (Back First Row 9) - 0x09DB3 - Stars & Eraser & Shapers 158165 - 0x275FA (Hook Control) - True - Shapers & Eraser @@ -537,11 +537,11 @@ Door - 0x0A0C9 (Cargo Box Entry) - 0x0A0C8 158221 - 0x28AE3 (Vines) - 0x18590 - True 158222 - 0x28938 (Apple Tree) - 0x28AE3 - True 158223 - 0x079DF (Triple Exit) - 0x28938 - True -158235 - 0x2899C (Wooden Roof Lower Row 1) - True - Rotated Shapers & Dots & Full Dots -158236 - 0x28A33 (Wooden Roof Lower Row 2) - 0x2899C - Shapers & Rotated Shapers & Dots & Full Dots -158237 - 0x28ABF (Wooden Roof Lower Row 3) - 0x28A33 - Shapers & Rotated Shapers & Dots & Full Dots -158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Rotated Shapers & Dots & Full Dots -158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Rotated Shapers & Dots & Full Dots +158235 - 0x2899C (Wooden Roof Lower Row 1) - True - Rotated Shapers & Full Dots +158236 - 0x28A33 (Wooden Roof Lower Row 2) - 0x2899C - Shapers & Rotated Shapers & Full Dots +158237 - 0x28ABF (Wooden Roof Lower Row 3) - 0x28A33 - Shapers & Rotated Shapers & Full Dots +158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Rotated Shapers & Full Dots +158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Rotated Shapers & Full Dots Door - 0x034F5 (Wooden Roof Stairs) - 0x28AC1 158225 - 0x28998 (RGB House Entry Panel) - True - Stars & Rotated Shapers Door - 0x28A61 (RGB House Entry) - 0x28998 @@ -575,7 +575,7 @@ Town Red Rooftop (Town): 158224 - 0x28B39 (Tall Hexagonal) - 0x079DF - True Town Wooden Rooftop (Town): -158240 - 0x28AD9 (Wooden Rooftop) - 0x28AC1 - Shapers & Dots & Eraser & Full Dots +158240 - 0x28AD9 (Wooden Rooftop) - 0x28AC1 - Shapers & Eraser & Full Dots Town Church (Town): 158227 - 0x28A69 (Church Lattice) - 0x03BB0 - True @@ -934,28 +934,28 @@ Treehouse Second Purple Bridge (Treehouse) - Treehouse Left Orange Bridge - 0x17 158368 - 0x17DC6 (Second Purple Bridge 7) - 0x17D91 - Stars & Colored Squares Treehouse Left Orange Bridge (Treehouse) - Treehouse Laser Room Front Platform - 0x17DDB - Treehouse Laser Room Back Platform - 0x17DDB - Treehouse Burned House - 0x17DDB: -158376 - 0x17DB3 (Left Orange Bridge 1) - True - Stars & Black/White Squares & Stars + Same Colored Symbol +158376 - 0x17DB3 (Left Orange Bridge 1) - True - Black/White Squares & Stars + Same Colored Symbol 158377 - 0x17DB5 (Left Orange Bridge 2) - 0x17DB3 - Stars & Black/White Squares -158378 - 0x17DB6 (Left Orange Bridge 3) - 0x17DB5 - Stars & Black/White Squares & Stars + Same Colored Symbol -158379 - 0x17DC0 (Left Orange Bridge 4) - 0x17DB6 - Stars & Black/White Squares & Stars + Same Colored Symbol -158380 - 0x17DD7 (Left Orange Bridge 5) - 0x17DC0 - Stars & Black/White Squares & Stars + Same Colored Symbol -158381 - 0x17DD9 (Left Orange Bridge 6) - 0x17DD7 - Stars & Black/White Squares & Colored Squares & Stars + Same Colored Symbol -158382 - 0x17DB8 (Left Orange Bridge 7) - 0x17DD9 - Stars & Black/White Squares & Colored Squares & Stars + Same Colored Symbol -158383 - 0x17DDC (Left Orange Bridge 8) - 0x17DB8 - Stars & Colored Squares & Stars + Same Colored Symbol -158384 - 0x17DD1 (Left Orange Bridge 9 & Directional) - 0x17DDC - Stars & Colored Squares & Stars + Same Colored Symbol -158385 - 0x17DDE (Left Orange Bridge 10) - 0x17DD1 - Stars & Colored Squares & Stars + Same Colored Symbol -158386 - 0x17DE3 (Left Orange Bridge 11) - 0x17DDE - Stars & Colored Squares & Stars + Same Colored Symbol -158387 - 0x17DEC (Left Orange Bridge 12) - 0x17DE3 - Stars & Black/White Squares & Stars + Same Colored Symbol -158388 - 0x17DAE (Left Orange Bridge 13) - 0x17DEC - Stars & Black/White Squares & Stars + Same Colored Symbol -158389 - 0x17DB0 (Left Orange Bridge 14) - 0x17DAE - Stars & Black/White Squares & Stars + Same Colored Symbol -158390 - 0x17DDB (Left Orange Bridge 15) - 0x17DB0 - Stars & Black/White Squares & Stars + Same Colored Symbol +158378 - 0x17DB6 (Left Orange Bridge 3) - 0x17DB5 - Black/White Squares & Stars + Same Colored Symbol +158379 - 0x17DC0 (Left Orange Bridge 4) - 0x17DB6 - Black/White Squares & Stars + Same Colored Symbol +158380 - 0x17DD7 (Left Orange Bridge 5) - 0x17DC0 - Black/White Squares & Stars + Same Colored Symbol +158381 - 0x17DD9 (Left Orange Bridge 6) - 0x17DD7 - Black/White Squares & Colored Squares & Stars + Same Colored Symbol +158382 - 0x17DB8 (Left Orange Bridge 7) - 0x17DD9 - Black/White Squares & Colored Squares & Stars + Same Colored Symbol +158383 - 0x17DDC (Left Orange Bridge 8) - 0x17DB8 - Colored Squares & Stars + Same Colored Symbol +158384 - 0x17DD1 (Left Orange Bridge 9 & Directional) - 0x17DDC - Colored Squares & Stars + Same Colored Symbol +158385 - 0x17DDE (Left Orange Bridge 10) - 0x17DD1 - Colored Squares & Stars + Same Colored Symbol +158386 - 0x17DE3 (Left Orange Bridge 11) - 0x17DDE - Colored Squares & Stars + Same Colored Symbol +158387 - 0x17DEC (Left Orange Bridge 12) - 0x17DE3 - Black/White Squares & Stars + Same Colored Symbol +158388 - 0x17DAE (Left Orange Bridge 13) - 0x17DEC - Black/White Squares & Stars + Same Colored Symbol +158389 - 0x17DB0 (Left Orange Bridge 14) - 0x17DAE - Black/White Squares & Stars + Same Colored Symbol +158390 - 0x17DDB (Left Orange Bridge 15) - 0x17DB0 - Black/White Squares & Stars + Same Colored Symbol Treehouse Green Bridge (Treehouse) - Treehouse Green Bridge Front House - 0x17E61 - Treehouse Green Bridge Left House - 0x17E61: 158369 - 0x17E3C (Green Bridge 1) - True - Stars & Shapers 158370 - 0x17E4D (Green Bridge 2) - 0x17E3C - Stars & Shapers 158371 - 0x17E4F (Green Bridge 3) - 0x17E4D - Stars & Shapers & Rotated Shapers 158372 - 0x17E52 (Green Bridge 4 & Directional) - 0x17E4F - Stars & Rotated Shapers -158373 - 0x17E5B (Green Bridge 5) - 0x17E52 - Stars & Shapers & Stars + Same Colored Symbol +158373 - 0x17E5B (Green Bridge 5) - 0x17E52 - Shapers & Stars + Same Colored Symbol 158374 - 0x17E5F (Green Bridge 6) - 0x17E5B - Stars & Negative Shapers & Rotated Shapers 158375 - 0x17E61 (Green Bridge 7) - 0x17E5F - Stars & Shapers & Rotated Shapers @@ -1046,8 +1046,8 @@ Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B Mountain Floor 2 (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Near - 0x09FFB - Mountain Floor 2 Beyond Bridge - 0x09E86 - Mountain Floor 2 Above The Abyss - True - Mountain Pink Bridge EP - TrueOneWay: 158426 - 0x09FD3 (Near Row 1) - True - Colored Squares 158427 - 0x09FD4 (Near Row 2) - 0x09FD3 - Colored Squares & Dots -158428 - 0x09FD6 (Near Row 3) - 0x09FD4 - Stars & Colored Squares & Stars + Same Colored Symbol -158429 - 0x09FD7 (Near Row 4) - 0x09FD6 - Stars & Colored Squares & Stars + Same Colored Symbol & Shapers +158428 - 0x09FD6 (Near Row 3) - 0x09FD4 - Colored Squares & Stars + Same Colored Symbol +158429 - 0x09FD7 (Near Row 4) - 0x09FD6 - Colored Squares & Stars + Same Colored Symbol & Shapers 158430 - 0x09FD8 (Near Row 5) - 0x09FD7 - Colored Squares Door - 0x09FFB (Staircase Near) - 0x09FD8 @@ -1095,9 +1095,9 @@ Door - 0x17F33 (Rock Open) - 0x17FA2 | 0x334E1 Mountain Bottom Floor Pillars Room (Mountain Bottom Floor) - Elevator - 0x339BB & 0x33961: 158522 - 0x0383A (Right Pillar 1) - True - Stars 158523 - 0x09E56 (Right Pillar 2) - 0x0383A - Stars & Dots -158524 - 0x09E5A (Right Pillar 3) - 0x09E56 - Dots & Full Dots +158524 - 0x09E5A (Right Pillar 3) - 0x09E56 - Full Dots 158525 - 0x33961 (Right Pillar 4) - 0x09E5A - Dots & Symmetry -158526 - 0x0383D (Left Pillar 1) - True - Dots & Full Dots +158526 - 0x0383D (Left Pillar 1) - True - Full Dots 158527 - 0x0383F (Left Pillar 2) - 0x0383D - Black/White Squares 158528 - 0x03859 (Left Pillar 3) - 0x0383F - Shapers 158529 - 0x339BB (Left Pillar 4) - 0x03859 - Black/White Squares & Stars & Symmetry @@ -1148,28 +1148,28 @@ Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x01 158472 - 0x32962 (First Floor Left) - True - Rotated Shapers & Shapers 158473 - 0x32966 (First Floor Grounded) - True - Stars & Black/White Squares 158474 - 0x01A31 (First Floor Middle) - True - Colored Squares -158475 - 0x00B71 (First Floor Right) - True - Colored Squares & Stars & Stars + Same Colored Symbol & Eraser +158475 - 0x00B71 (First Floor Right) - True - Colored Squares & Stars + Same Colored Symbol & Eraser 158478 - 0x288EA (First Wooden Beam) - True - Rotated Shapers 158479 - 0x288FC (Second Wooden Beam) - True - Black/White Squares & Shapers & Rotated Shapers 158480 - 0x289E7 (Third Wooden Beam) - True - Black/White Squares 158481 - 0x288AA (Fourth Wooden Beam) - True - Black/White Squares & Shapers 158482 - 0x17FB9 (Left Upstairs Single) - True - Dots -158483 - 0x0A16B (Left Upstairs Left Row 1) - True - Dots & Full Dots -158484 - 0x0A2CE (Left Upstairs Left Row 2) - 0x0A16B - Dots & Full Dots -158485 - 0x0A2D7 (Left Upstairs Left Row 3) - 0x0A2CE - Dots & Full Dots -158486 - 0x0A2DD (Left Upstairs Left Row 4) - 0x0A2D7 - Dots & Full Dots -158487 - 0x0A2EA (Left Upstairs Left Row 5) - 0x0A2DD - Dots & Full Dots -158488 - 0x0008F (Right Upstairs Left Row 1) - True - Dots & Invisible Dots -158489 - 0x0006B (Right Upstairs Left Row 2) - 0x0008F - Dots & Invisible Dots -158490 - 0x0008B (Right Upstairs Left Row 3) - 0x0006B - Dots & Invisible Dots -158491 - 0x0008C (Right Upstairs Left Row 4) - 0x0008B - Dots & Invisible Dots -158492 - 0x0008A (Right Upstairs Left Row 5) - 0x0008C - Dots & Invisible Dots -158493 - 0x00089 (Right Upstairs Left Row 6) - 0x0008A - Dots & Invisible Dots -158494 - 0x0006A (Right Upstairs Left Row 7) - 0x00089 - Dots & Invisible Dots -158495 - 0x0006C (Right Upstairs Left Row 8) - 0x0006A - Dots & Invisible Dots -158496 - 0x00027 (Right Upstairs Right Row 1) - True - Dots & Invisible Dots & Symmetry -158497 - 0x00028 (Right Upstairs Right Row 2) - 0x00027 - Dots & Invisible Dots & Symmetry -158498 - 0x00029 (Right Upstairs Right Row 3) - 0x00028 - Dots & Invisible Dots & Symmetry +158483 - 0x0A16B (Left Upstairs Left Row 1) - True - Full Dots +158484 - 0x0A2CE (Left Upstairs Left Row 2) - 0x0A16B - Full Dots +158485 - 0x0A2D7 (Left Upstairs Left Row 3) - 0x0A2CE - Full Dots +158486 - 0x0A2DD (Left Upstairs Left Row 4) - 0x0A2D7 - Full Dots +158487 - 0x0A2EA (Left Upstairs Left Row 5) - 0x0A2DD - Full Dots +158488 - 0x0008F (Right Upstairs Left Row 1) - True - Dots +158489 - 0x0006B (Right Upstairs Left Row 2) - 0x0008F - Dots +158490 - 0x0008B (Right Upstairs Left Row 3) - 0x0006B - Dots +158491 - 0x0008C (Right Upstairs Left Row 4) - 0x0008B - Dots +158492 - 0x0008A (Right Upstairs Left Row 5) - 0x0008C - Dots +158493 - 0x00089 (Right Upstairs Left Row 6) - 0x0008A - Dots +158494 - 0x0006A (Right Upstairs Left Row 7) - 0x00089 - Dots +158495 - 0x0006C (Right Upstairs Left Row 8) - 0x0006A - Dots +158496 - 0x00027 (Right Upstairs Right Row 1) - True - Dots & Symmetry +158497 - 0x00028 (Right Upstairs Right Row 2) - 0x00027 - Dots & Symmetry +158498 - 0x00029 (Right Upstairs Right Row 3) - 0x00028 - Dots & Symmetry 158476 - 0x09DD5 (Lone Pillar) - True - Triangles Door - 0x019A5 (Pillar Door) - 0x09DD5 158449 - 0x021D7 (Mountain Shortcut Panel) - True - Stars @@ -1179,7 +1179,7 @@ Door - 0x2D859 (Swamp Shortcut Door) - 0x17CF2 159341 - 0x3397C (Skylight EP) - True - True Caves Path to Challenge (Caves) - Challenge - 0x0A19A: -158477 - 0x0A16E (Challenge Entry Panel) - True - Stars & Shapers & Stars + Same Colored Symbol +158477 - 0x0A16E (Challenge Entry Panel) - True - Shapers & Stars + Same Colored Symbol Door - 0x0A19A (Challenge Entry) - 0x0A16E ==Challenge== diff --git a/worlds/witness/data/WitnessLogicVariety.txt b/worlds/witness/data/WitnessLogicVariety.txt index bc9a40f566f0..1014558a66a3 100644 --- a/worlds/witness/data/WitnessLogicVariety.txt +++ b/worlds/witness/data/WitnessLogicVariety.txt @@ -28,11 +28,11 @@ Tutorial (Tutorial) - Outside Tutorial - True: Outside Tutorial (Outside Tutorial) - Outside Tutorial Path To Outpost - 0x03BA2 - Outside Tutorial Vault - 0x033D0: 158650 - 0x033D4 (Vault Panel) - True - Dots & Black/White Squares & Colored Squares & Symmetry Door - 0x033D0 (Vault Door) - 0x033D4 -158013 - 0x0005D (Shed Row 1) - True - Dots & Full Dots & Black/White Squares & Colored Squares -158014 - 0x0005E (Shed Row 2) - 0x0005D - Dots & Full Dots & Stars -158015 - 0x0005F (Shed Row 3) - 0x0005E - Dots & Full Dots & Shapers & Negative Shapers -158016 - 0x00060 (Shed Row 4) - 0x0005F - Dots & Full Dots & Black/White Squares & Stars & Stars + Same Colored Symbol & Eraser -158017 - 0x00061 (Shed Row 5) - 0x00060 - Dots & Full Dots & Triangles +158013 - 0x0005D (Shed Row 1) - True - Full Dots & Black/White Squares & Colored Squares +158014 - 0x0005E (Shed Row 2) - 0x0005D - Full Dots & Stars +158015 - 0x0005F (Shed Row 3) - 0x0005E - Full Dots & Shapers & Negative Shapers +158016 - 0x00060 (Shed Row 4) - 0x0005F - Full Dots & Black/White Squares & Stars + Same Colored Symbol & Eraser +158017 - 0x00061 (Shed Row 5) - 0x00060 - Full Dots & Triangles 158018 - 0x018AF (Tree Row 1) - True - Arrows 158019 - 0x0001B (Tree Row 2) - 0x018AF - Arrows 158020 - 0x012C9 (Tree Row 3) - 0x0001B - Arrows @@ -52,11 +52,11 @@ Outside Tutorial Vault (Outside Tutorial): 158651 - 0x03481 (Vault Box) - True - True Outside Tutorial Path To Outpost (Outside Tutorial) - Outside Tutorial Outpost - 0x0A170: -158011 - 0x0A171 (Outpost Entry Panel) - True - Dots & Full Dots & Triangles & Black/White Squares +158011 - 0x0A171 (Outpost Entry Panel) - True - Full Dots & Triangles & Black/White Squares Door - 0x0A170 (Outpost Entry) - 0x0A171 Outside Tutorial Outpost (Outside Tutorial) - Outside Tutorial - 0x04CA3: -158012 - 0x04CA4 (Outpost Exit Panel) - True - Dots & Full Dots & Triangles & Black/White Squares +158012 - 0x04CA4 (Outpost Exit Panel) - True - Full Dots & Triangles & Black/White Squares Door - 0x04CA3 (Outpost Exit) - 0x04CA4 158600 - 0x17CFB (Discard) - True - Arrows & Triangles @@ -108,11 +108,11 @@ Outside Symmetry Island (Symmetry Island) - Main Island - True - Symmetry Island Door - 0x17F3E (Lower) - 0x000B0 Symmetry Island Lower (Symmetry Island) - Symmetry Island Upper - 0x18269: -158041 - 0x00022 (Right 1) - True - Symmetry & Dots & Full Dots & Triangles -158042 - 0x00023 (Right 2) - 0x00022 - Symmetry & Dots & Full Dots & Triangles -158043 - 0x00024 (Right 3) - 0x00023 - Symmetry & Dots & Full Dots & Triangles -158044 - 0x00025 (Right 4) - 0x00024 - Symmetry & Dots & Full Dots & Triangles -158045 - 0x00026 (Right 5) - 0x00025 - Symmetry & Dots & Full Dots & Triangles +158041 - 0x00022 (Right 1) - True - Symmetry & Full Dots & Triangles +158042 - 0x00023 (Right 2) - 0x00022 - Symmetry & Full Dots & Triangles +158043 - 0x00024 (Right 3) - 0x00023 - Symmetry & Full Dots & Triangles +158044 - 0x00025 (Right 4) - 0x00024 - Symmetry & Full Dots & Triangles +158045 - 0x00026 (Right 5) - 0x00025 - Symmetry & Full Dots & Triangles 158046 - 0x0007C (Back 1) - 0x00026 - Symmetry & Dots & Colored Dots 158047 - 0x0007E (Back 2) - 0x0007C - Symmetry & Dots & Colored Dots 158048 - 0x00075 (Back 3) - 0x0007E - Symmetry & Dots & Colored Dots @@ -122,8 +122,8 @@ Symmetry Island Lower (Symmetry Island) - Symmetry Island Upper - 0x18269: 158052 - 0x00065 (Left 1) - 0x00079 - Symmetry & Dots & Colored Dots 158053 - 0x0006D (Left 2) - 0x00065 - Symmetry & Colored Squares 158054 - 0x00072 (Left 3) - 0x0006D - Symmetry & Stars -158055 - 0x0006F (Left 4) - 0x00072 - Symmetry & Stars & Stars + Same Colored Symbol & Colored Squares -158056 - 0x00070 (Left 5) - 0x0006F - Symmetry & Stars & Stars + Same Colored Symbol & Colored Squares +158055 - 0x0006F (Left 4) - 0x00072 - Symmetry & Stars + Same Colored Symbol & Colored Squares +158056 - 0x00070 (Left 5) - 0x0006F - Symmetry & Stars + Same Colored Symbol & Colored Squares 158057 - 0x00071 (Left 6) - 0x00070 - Symmetry & Colored Dots & Eraser 158058 - 0x00076 (Left 7) - 0x00071 - Symmetry & Dots & Eraser 158059 - 0x009B8 (Scenery Outlines 1) - True - Symmetry @@ -136,12 +136,12 @@ Door - 0x18269 (Upper) - 0x1C349 159000 - 0x0332B (Glass Factory Black Line Reflection EP) - True - True Symmetry Island Upper (Symmetry Island): -158065 - 0x00A52 (Laser Yellow 1) - True - Symmetry & Colored Dots -158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Symmetry & Colored Dots -158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Symmetry & Colored Dots -158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Symmetry & Colored Dots -158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Symmetry & Colored Dots -158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Symmetry & Colored Dots +158065 - 0x00A52 (Laser Yellow 1) - True - Colored Dots +158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Colored Dots +158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Colored Dots +158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Colored Dots +158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Colored Dots +158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Colored Dots 158700 - 0x0360D (Laser Panel) - 0x00A68 - True Laser - 0x00509 (Laser) - 0x0360D 159001 - 0x03367 (Glass Factory Black Line EP) - True - True @@ -157,7 +157,7 @@ Desert Obelisk (Desert) - Entry - True: 159709 - 0x00359 (Obelisk) - True - True Desert Outside (Desert) - Main Island - True - Desert Light Room - 0x09FEE - Desert Vault - 0x03444: -158652 - 0x0CC7B (Vault Panel) - True - Dots & Full Dots & Rotated Shapers & Negative Shapers & Stars & Stars + Same Colored Symbol +158652 - 0x0CC7B (Vault Panel) - True - Full Dots & Rotated Shapers & Negative Shapers & Stars + Same Colored Symbol Door - 0x03444 (Vault Door) - 0x0CC7B 158602 - 0x17CE7 (Discard) - True - Arrows & Triangles 158076 - 0x00698 (Surface 1) - True - True @@ -270,7 +270,7 @@ Door - 0x17C07 (Entry 2) - 0x17C09 Quarry (Quarry) - Quarry Stoneworks Ground Floor - 0x02010: 159802 - 0xFFD01 (Inside Reached Independently) - True - True -158121 - 0x01E5A (Stoneworks Entry Left Panel) - True - Stars & Stars + Same Colored Symbol & Eraser +158121 - 0x01E5A (Stoneworks Entry Left Panel) - True - Stars + Same Colored Symbol & Eraser 158122 - 0x01E59 (Stoneworks Entry Right Panel) - True - Triangles Door - 0x02010 (Stoneworks Entry) - 0x01E59 & 0x01E5A @@ -299,14 +299,14 @@ Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Lift - 0x0 158135 - 0x005F1 (Upper Row 2) - 0x00557 - Colored Squares & Eraser 158136 - 0x00620 (Upper Row 3) - 0x005F1 - Colored Squares & Eraser 158137 - 0x009F5 (Upper Row 4) - 0x00620 - Colored Squares & Eraser -158138 - 0x0146C (Upper Row 5) - 0x009F5 - Stars & Stars + Same Colored Symbol & Eraser -158139 - 0x3C12D (Upper Row 6) - 0x0146C - Stars & Stars + Same Colored Symbol & Eraser -158140 - 0x03686 (Upper Row 7) - 0x3C12D - Stars & Stars + Same Colored Symbol & Eraser -158141 - 0x014E9 (Upper Row 8) - 0x03686 - Stars & Stars + Same Colored Symbol & Eraser +158138 - 0x0146C (Upper Row 5) - 0x009F5 - Stars + Same Colored Symbol & Eraser +158139 - 0x3C12D (Upper Row 6) - 0x0146C - Stars + Same Colored Symbol & Eraser +158140 - 0x03686 (Upper Row 7) - 0x3C12D - Stars + Same Colored Symbol & Eraser +158141 - 0x014E9 (Upper Row 8) - 0x03686 - Stars + Same Colored Symbol & Eraser 158142 - 0x03677 (Stairs Panel) - True - Colored Squares & Eraser Door - 0x0368A (Stairs) - 0x03677 158143 - 0x3C125 (Control Room Left) - 0x014E9 - Black/White Squares & Dots & Eraser & Symmetry -158144 - 0x0367C (Control Room Right) - 0x014E9 - Colored Squares & Dots & Eraser & Stars & Stars + Same Colored Symbol +158144 - 0x0367C (Control Room Right) - 0x014E9 - Colored Squares & Dots & Eraser & Stars + Same Colored Symbol 159411 - 0x0069D (Ramp EP) - 0x03676 & 0x275FF - True 159413 - 0x00614 (Lift EP) - 0x275FF & 0x03675 - True @@ -340,13 +340,13 @@ Door - 0x3865F (Second Barrier) - 0x38663 158158 - 0x021B7 (Back First Row 3) - 0x021B6 - Shapers & Negative Shapers & Eraser 158159 - 0x021BB (Back First Row 4) - 0x021B7 - Shapers & Negative Shapers & Eraser 158160 - 0x09DB5 (Back First Row 5) - 0x021BB - Shapers & Negative Shapers & Eraser -158161 - 0x09DB1 (Back First Row 6) - 0x09DB5 - Stars & Stars + Same Colored Symbol & Eraser & Colored Squares -158162 - 0x3C124 (Back First Row 7) - 0x09DB1 - Stars & Stars + Same Colored Symbol & Eraser & Colored Squares -158163 - 0x09DB3 (Back First Row 8) - 0x3C124 - Stars & Stars + Same Colored Symbol & Eraser & Colored Squares & Triangles -158164 - 0x09DB4 (Back First Row 9) - 0x09DB3 - Stars & Stars + Same Colored Symbol & Eraser & Colored Squares & Triangles +158161 - 0x09DB1 (Back First Row 6) - 0x09DB5 - Stars + Same Colored Symbol & Eraser & Colored Squares +158162 - 0x3C124 (Back First Row 7) - 0x09DB1 - Stars + Same Colored Symbol & Eraser & Colored Squares +158163 - 0x09DB3 (Back First Row 8) - 0x3C124 - Stars + Same Colored Symbol & Eraser & Colored Squares & Triangles +158164 - 0x09DB4 (Back First Row 9) - 0x09DB3 - Stars + Same Colored Symbol & Eraser & Colored Squares & Triangles 158165 - 0x275FA (Hook Control) - True - Shapers & Eraser 158167 - 0x0A3CB (Back Second Row 1) - 0x09DB4 - Black/White Squares & Colored Squares & Eraser & Shapers -158168 - 0x0A3CC (Back Second Row 2) - 0x0A3CB - Stars & Stars + Same Colored Symbol & Eraser & Shapers +158168 - 0x0A3CC (Back Second Row 2) - 0x0A3CB - Stars + Same Colored Symbol & Eraser & Shapers 158169 - 0x0A3D0 (Back Second Row 3) - 0x0A3CC - Triangles & Eraser & Shapers 159401 - 0x005F6 (Hook EP) - 0x275FA & 0x03852 & 0x3865F - True @@ -421,7 +421,7 @@ Door - 0x01A0E (Hedge Maze 4 Exit) - 0x01A0F Keep 2nd Pressure Plate (Keep) - Keep 3rd Pressure Plate - True: 158199 - 0x0A3B9 (Reset Pressure Plates 2) - True - True -158200 - 0x01BE9 (Pressure Plates 2) - 0x0A3B9 - Stars & Stars + Same Colored Symbol & Triangles +158200 - 0x01BE9 (Pressure Plates 2) - 0x0A3B9 - Stars + Same Colored Symbol & Triangles Door - 0x01BEA (Pressure Plates 2 Exit) - 0x01BE9 Keep 3rd Pressure Plate (Keep) - Keep 4th Pressure Plate - 0x01CD5: @@ -441,7 +441,7 @@ Keep Tower (Keep) - Keep - 0x04F8F: 158206 - 0x0361B (Tower Shortcut Panel) - True - True Door - 0x04F8F (Tower Shortcut) - 0x0361B 158704 - 0x0360E (Laser Panel Hedges) - 0x01A0F & 0x019E7 & 0x019DC & 0x00139 - True -158705 - 0x03317 (Laser Panel Pressure Plates) - 0x033EA & 0x01BE9 & 0x01CD3 & 0x01D3F - Dots & Shapers & Black/White Squares & Colored Squares & Stars & Stars + Same Colored Symbol +158705 - 0x03317 (Laser Panel Pressure Plates) - 0x033EA & 0x01BE9 & 0x01CD3 & 0x01D3F - Dots & Shapers & Black/White Squares & Colored Squares & Stars + Same Colored Symbol Laser - 0x014BB (Laser) - 0x0360E | 0x03317 159240 - 0x033BE (Pressure Plates 1 EP) - 0x033EA - True 159241 - 0x033BF (Pressure Plates 2 EP) - 0x01BE9 - True @@ -537,11 +537,11 @@ Door - 0x0A0C9 (Cargo Box Entry) - 0x0A0C8 158221 - 0x28AE3 (Vines) - 0x18590 - True 158222 - 0x28938 (Apple Tree) - 0x28AE3 - True 158223 - 0x079DF (Triple Exit) - 0x28938 - True -158235 - 0x2899C (Wooden Roof Lower Row 1) - True - Rotated Shapers & Dots & Full Dots & Colored Squares -158236 - 0x28A33 (Wooden Roof Lower Row 2) - 0x2899C - Rotated Shapers & Dots & Full Dots & Stars -158237 - 0x28ABF (Wooden Roof Lower Row 3) - 0x28A33 - Shapers & Negative Shapers & Dots & Full Dots -158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Rotated Shapers & Dots & Full Dots -158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Rotated Shapers & Dots & Full Dots & Triangles +158235 - 0x2899C (Wooden Roof Lower Row 1) - True - Rotated Shapers & Full Dots & Colored Squares +158236 - 0x28A33 (Wooden Roof Lower Row 2) - 0x2899C - Rotated Shapers & Full Dots & Stars +158237 - 0x28ABF (Wooden Roof Lower Row 3) - 0x28A33 - Shapers & Negative Shapers & Full Dots +158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Rotated Shapers & Full Dots +158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Rotated Shapers & Full Dots & Triangles Door - 0x034F5 (Wooden Roof Stairs) - 0x28AC1 158225 - 0x28998 (RGB House Entry Panel) - True - Stars & Rotated Shapers Door - 0x28A61 (RGB House Entry) - 0x28998 @@ -575,7 +575,7 @@ Town Red Rooftop (Town): 158224 - 0x28B39 (Tall Hexagonal) - 0x079DF - True Town Wooden Rooftop (Town): -158240 - 0x28AD9 (Wooden Rooftop) - 0x28AC1 - Rotated Shapers & Dots & Eraser & Full Dots +158240 - 0x28AD9 (Wooden Rooftop) - 0x28AC1 - Rotated Shapers & Eraser & Full Dots Town Church (Town): 158227 - 0x28A69 (Church Lattice) - 0x03BB0 - True @@ -631,8 +631,8 @@ Theater (Theater) - Town - 0x0A16D | 0x3CCDF: 158660 - 0x03549 (Challenge Video) - 0x00815 & 0x0356B - True 158661 - 0x0354F (Shipwreck Video) - 0x00815 & 0x03535 - True 158662 - 0x03545 (Mountain Video) - 0x00815 & 0x03542 - True -158249 - 0x0A168 (Exit Left Panel) - True - Black/White Squares & Stars & Stars + Same Colored Symbol & Shapers -158250 - 0x33AB2 (Exit Right Panel) - True - Black/White Squares & Stars & Stars + Same Colored Symbol & Shapers +158249 - 0x0A168 (Exit Left Panel) - True - Black/White Squares & Stars + Same Colored Symbol & Shapers +158250 - 0x33AB2 (Exit Right Panel) - True - Black/White Squares & Stars + Same Colored Symbol & Shapers Door - 0x0A16D (Exit Left) - 0x0A168 Door - 0x3CCDF (Exit Right) - 0x33AB2 158608 - 0x17CF7 (Discard) - True - Arrows & Triangles @@ -851,8 +851,8 @@ Swamp Maze (Swamp) - Swamp Laser Area - 0x17C0A & 0x17E07: Swamp Laser Area (Swamp) - Outside Swamp - 0x2D880: 158711 - 0x03615 (Laser Panel) - True - True Laser - 0x00BF6 (Laser) - 0x03615 -158341 - 0x17C05 (Laser Shortcut Left Panel) - True - Shapers & Colored Squares & Stars & Stars + Same Colored Symbol -158342 - 0x17C02 (Laser Shortcut Right Panel) - 0x17C05 - Shapers & Colored Squares & Stars & Stars + Same Colored Symbol +158341 - 0x17C05 (Laser Shortcut Left Panel) - True - Shapers & Colored Squares & Stars + Same Colored Symbol +158342 - 0x17C02 (Laser Shortcut Right Panel) - 0x17C05 - Shapers & Colored Squares & Stars + Same Colored Symbol Door - 0x2D880 (Laser Shortcut) - 0x17C02 ==Treehouse== @@ -878,7 +878,7 @@ Door - 0x0C309 (First Door) - 0x0288C 159210 - 0x33721 (Buoy EP) - 0x17C95 - True Treehouse Between Entry Doors (Treehouse) - Treehouse Yellow Bridge - 0x0C310: -158345 - 0x02886 (Second Door Panel) - True - Stars & Stars + Same Colored Symbol & Triangles +158345 - 0x02886 (Second Door Panel) - True - Stars + Same Colored Symbol & Triangles Door - 0x0C310 (Second Door) - 0x02886 Treehouse Yellow Bridge (Treehouse) - Treehouse After Yellow Bridge - 0x17DC4: @@ -907,57 +907,57 @@ Treehouse First Purple Bridge (Treehouse) - Treehouse Second Purple Bridge - 0x1 158361 - 0x17D6C (First Purple Bridge 5) - 0x17D2D - Stars & Dots & Triangles Treehouse Right Orange Bridge (Treehouse) - Treehouse Drawbridge Platform - 0x17DA2: -158391 - 0x17D88 (Right Orange Bridge 1) - True - Stars & Stars + Same Colored Symbol & Colored Squares -158392 - 0x17DB4 (Right Orange Bridge 2) - 0x17D88 - Stars & Stars + Same Colored Symbol & Colored Squares -158393 - 0x17D8C (Right Orange Bridge 3) - 0x17DB4 - Stars & Stars + Same Colored Symbol & Colored Squares -158394 - 0x17CE3 (Right Orange Bridge 4 & Directional) - 0x17D8C - Stars & Stars + Same Colored Symbol & Colored Squares -158395 - 0x17DCD (Right Orange Bridge 5) - 0x17CE3 - Stars & Stars + Same Colored Symbol & Colored Squares -158396 - 0x17DB2 (Right Orange Bridge 6) - 0x17DCD - Stars & Stars + Same Colored Symbol & Colored Squares -158397 - 0x17DCC (Right Orange Bridge 7) - 0x17DB2 - Stars & Stars + Same Colored Symbol & Colored Squares -158398 - 0x17DCA (Right Orange Bridge 8) - 0x17DCC - Stars & Stars + Same Colored Symbol & Colored Squares -158399 - 0x17D8E (Right Orange Bridge 9) - 0x17DCA - Stars & Stars + Same Colored Symbol & Colored Squares -158400 - 0x17DB7 (Right Orange Bridge 10 & Directional) - 0x17D8E - Stars & Stars + Same Colored Symbol & Colored Squares -158401 - 0x17DB1 (Right Orange Bridge 11) - 0x17DB7 - Stars & Stars + Same Colored Symbol & Colored Squares -158402 - 0x17DA2 (Right Orange Bridge 12) - 0x17DB1 - Stars & Stars + Same Colored Symbol & Colored Squares +158391 - 0x17D88 (Right Orange Bridge 1) - True - Stars + Same Colored Symbol & Colored Squares +158392 - 0x17DB4 (Right Orange Bridge 2) - 0x17D88 - Stars + Same Colored Symbol & Colored Squares +158393 - 0x17D8C (Right Orange Bridge 3) - 0x17DB4 - Stars + Same Colored Symbol & Colored Squares +158394 - 0x17CE3 (Right Orange Bridge 4 & Directional) - 0x17D8C - Stars + Same Colored Symbol & Colored Squares +158395 - 0x17DCD (Right Orange Bridge 5) - 0x17CE3 - Stars + Same Colored Symbol & Colored Squares +158396 - 0x17DB2 (Right Orange Bridge 6) - 0x17DCD - Stars + Same Colored Symbol & Colored Squares +158397 - 0x17DCC (Right Orange Bridge 7) - 0x17DB2 - Stars + Same Colored Symbol & Colored Squares +158398 - 0x17DCA (Right Orange Bridge 8) - 0x17DCC - Stars + Same Colored Symbol & Colored Squares +158399 - 0x17D8E (Right Orange Bridge 9) - 0x17DCA - Stars + Same Colored Symbol & Colored Squares +158400 - 0x17DB7 (Right Orange Bridge 10 & Directional) - 0x17D8E - Stars + Same Colored Symbol & Colored Squares +158401 - 0x17DB1 (Right Orange Bridge 11) - 0x17DB7 - Stars + Same Colored Symbol & Colored Squares +158402 - 0x17DA2 (Right Orange Bridge 12) - 0x17DB1 - Stars + Same Colored Symbol & Colored Squares Treehouse Drawbridge Platform (Treehouse) - Main Island - 0x0C32D: 158404 - 0x037FF (Drawbridge Panel) - True - Stars Door - 0x0C32D (Drawbridge) - 0x037FF Treehouse Second Purple Bridge (Treehouse) - Treehouse Left Orange Bridge - 0x17DC6: -158362 - 0x17D9B (Second Purple Bridge 1) - True - Stars & Stars + Same Colored Symbol & Black/White Squares & Colored Squares -158363 - 0x17D99 (Second Purple Bridge 2) - 0x17D9B - Stars & Stars + Same Colored Symbol & Black/White Squares & Colored Squares -158364 - 0x17DAA (Second Purple Bridge 3) - 0x17D99 - Stars & Stars + Same Colored Symbol & Black/White Squares & Colored Squares -158365 - 0x17D97 (Second Purple Bridge 4) - 0x17DAA - Stars & Stars + Same Colored Symbol & Black/White Squares & Colored Squares -158366 - 0x17BDF (Second Purple Bridge 5) - 0x17D97 - Stars & Stars + Same Colored Symbol & Colored Squares -158367 - 0x17D91 (Second Purple Bridge 6) - 0x17BDF - Stars & Stars + Same Colored Symbol & Black/White Squares & Colored Squares -158368 - 0x17DC6 (Second Purple Bridge 7) - 0x17D91 - Stars & Stars + Same Colored Symbol & Colored Squares +158362 - 0x17D9B (Second Purple Bridge 1) - True - Stars + Same Colored Symbol & Black/White Squares & Colored Squares +158363 - 0x17D99 (Second Purple Bridge 2) - 0x17D9B - Stars + Same Colored Symbol & Black/White Squares & Colored Squares +158364 - 0x17DAA (Second Purple Bridge 3) - 0x17D99 - Stars + Same Colored Symbol & Black/White Squares & Colored Squares +158365 - 0x17D97 (Second Purple Bridge 4) - 0x17DAA - Stars + Same Colored Symbol & Black/White Squares & Colored Squares +158366 - 0x17BDF (Second Purple Bridge 5) - 0x17D97 - Stars + Same Colored Symbol & Colored Squares +158367 - 0x17D91 (Second Purple Bridge 6) - 0x17BDF - Stars + Same Colored Symbol & Black/White Squares & Colored Squares +158368 - 0x17DC6 (Second Purple Bridge 7) - 0x17D91 - Stars + Same Colored Symbol & Colored Squares Treehouse Left Orange Bridge (Treehouse) - Treehouse Laser Room Front Platform - 0x17DDB - Treehouse Laser Room Back Platform - 0x17DDB - Treehouse Burned House - 0x17DDB: -158376 - 0x17DB3 (Left Orange Bridge 1) - True - Stars & Stars + Same Colored Symbol & Triangles -158377 - 0x17DB5 (Left Orange Bridge 2) - 0x17DB3 - Stars & Stars + Same Colored Symbol & Triangles -158378 - 0x17DB6 (Left Orange Bridge 3) - 0x17DB5 - Stars & Stars + Same Colored Symbol & Triangles -158379 - 0x17DC0 (Left Orange Bridge 4) - 0x17DB6 - Stars & Stars + Same Colored Symbol & Triangles -158380 - 0x17DD7 (Left Orange Bridge 5) - 0x17DC0 - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers -158381 - 0x17DD9 (Left Orange Bridge 6) - 0x17DD7 - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers -158382 - 0x17DB8 (Left Orange Bridge 7) - 0x17DD9 - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers -158383 - 0x17DDC (Left Orange Bridge 8) - 0x17DB8 - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers -158384 - 0x17DD1 (Left Orange Bridge 9 & Directional) - 0x17DDC - Stars & Black/White Squares & Stars + Same Colored Symbol -158385 - 0x17DDE (Left Orange Bridge 10) - 0x17DD1 - Stars & Stars + Same Colored Symbol & Shapers -158386 - 0x17DE3 (Left Orange Bridge 11) - 0x17DDE - Stars & Stars + Same Colored Symbol & Shapers -158387 - 0x17DEC (Left Orange Bridge 12) - 0x17DE3 - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers -158388 - 0x17DAE (Left Orange Bridge 13) - 0x17DEC - Stars & Stars + Same Colored Symbol & Shapers & Triangles -158389 - 0x17DB0 (Left Orange Bridge 14) - 0x17DAE - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers -158390 - 0x17DDB (Left Orange Bridge 15) - 0x17DB0 - Stars & Stars + Same Colored Symbol & Shapers & Triangles +158376 - 0x17DB3 (Left Orange Bridge 1) - True - Stars + Same Colored Symbol & Triangles +158377 - 0x17DB5 (Left Orange Bridge 2) - 0x17DB3 - Stars + Same Colored Symbol & Triangles +158378 - 0x17DB6 (Left Orange Bridge 3) - 0x17DB5 - Stars + Same Colored Symbol & Triangles +158379 - 0x17DC0 (Left Orange Bridge 4) - 0x17DB6 - Stars + Same Colored Symbol & Triangles +158380 - 0x17DD7 (Left Orange Bridge 5) - 0x17DC0 - Black/White Squares & Stars + Same Colored Symbol & Shapers +158381 - 0x17DD9 (Left Orange Bridge 6) - 0x17DD7 - Black/White Squares & Stars + Same Colored Symbol & Shapers +158382 - 0x17DB8 (Left Orange Bridge 7) - 0x17DD9 - Black/White Squares & Stars + Same Colored Symbol & Shapers +158383 - 0x17DDC (Left Orange Bridge 8) - 0x17DB8 - Black/White Squares & Stars + Same Colored Symbol & Shapers +158384 - 0x17DD1 (Left Orange Bridge 9 & Directional) - 0x17DDC - Black/White Squares & Stars + Same Colored Symbol +158385 - 0x17DDE (Left Orange Bridge 10) - 0x17DD1 - Stars + Same Colored Symbol & Shapers +158386 - 0x17DE3 (Left Orange Bridge 11) - 0x17DDE - Stars + Same Colored Symbol & Shapers +158387 - 0x17DEC (Left Orange Bridge 12) - 0x17DE3 - Black/White Squares & Stars + Same Colored Symbol & Shapers +158388 - 0x17DAE (Left Orange Bridge 13) - 0x17DEC - Stars + Same Colored Symbol & Shapers & Triangles +158389 - 0x17DB0 (Left Orange Bridge 14) - 0x17DAE - Black/White Squares & Stars + Same Colored Symbol & Shapers +158390 - 0x17DDB (Left Orange Bridge 15) - 0x17DB0 - Stars + Same Colored Symbol & Shapers & Triangles Treehouse Green Bridge (Treehouse) - Treehouse Green Bridge Front House - 0x17E61 - Treehouse Green Bridge Left House - 0x17E61: -158369 - 0x17E3C (Green Bridge 1) - True - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158370 - 0x17E4D (Green Bridge 2) - 0x17E3C - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158371 - 0x17E4F (Green Bridge 3) - 0x17E4D - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158372 - 0x17E52 (Green Bridge 4 & Directional) - 0x17E4F - Stars & Rotated Shapers & Negative Shapers & Stars + Same Colored Symbol -158373 - 0x17E5B (Green Bridge 5) - 0x17E52 - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158374 - 0x17E5F (Green Bridge 6) - 0x17E5B - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol -158375 - 0x17E61 (Green Bridge 7) - 0x17E5F - Stars & Shapers & Negative Shapers & Stars + Same Colored Symbol +158369 - 0x17E3C (Green Bridge 1) - True - Shapers & Negative Shapers & Stars + Same Colored Symbol +158370 - 0x17E4D (Green Bridge 2) - 0x17E3C - Shapers & Negative Shapers & Stars + Same Colored Symbol +158371 - 0x17E4F (Green Bridge 3) - 0x17E4D - Shapers & Negative Shapers & Stars + Same Colored Symbol +158372 - 0x17E52 (Green Bridge 4 & Directional) - 0x17E4F - Rotated Shapers & Negative Shapers & Stars + Same Colored Symbol +158373 - 0x17E5B (Green Bridge 5) - 0x17E52 - Shapers & Negative Shapers & Stars + Same Colored Symbol +158374 - 0x17E5F (Green Bridge 6) - 0x17E5B - Shapers & Negative Shapers & Stars + Same Colored Symbol +158375 - 0x17E61 (Green Bridge 7) - 0x17E5F - Shapers & Negative Shapers & Stars + Same Colored Symbol Treehouse Green Bridge Front House (Treehouse): 158610 - 0x17FA9 (Green Bridge Discard) - True - Arrows & Triangles @@ -1019,17 +1019,17 @@ Mountain Floor 1 (Mountain Floor 1) - Mountain Floor 1 Bridge - 0x09E39: Mountain Floor 1 Bridge (Mountain Floor 1) - Mountain Floor 1 At Door - TrueOneWay - Mountain Floor 1 Trash Pillar - TrueOneWay - Mountain Floor 1 Back Section - TrueOneWay: 158409 - 0x09E7A (Right Row 1) - True - Black/White Squares & Dots -158410 - 0x09E71 (Right Row 2) - 0x09E7A - Black/White Squares & Dots & Stars & Stars + Same Colored Symbol -158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers & Stars & Stars + Same Colored Symbol -158412 - 0x09E69 (Right Row 4) - 0x09E72 - Black/White Squares & Eraser & Stars & Stars + Same Colored Symbol -158413 - 0x09E7B (Right Row 5) - 0x09E69 - Dots & Full Dots & Triangles +158410 - 0x09E71 (Right Row 2) - 0x09E7A - Black/White Squares & Dots & Stars + Same Colored Symbol +158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers & Stars + Same Colored Symbol +158412 - 0x09E69 (Right Row 4) - 0x09E72 - Black/White Squares & Eraser & Stars + Same Colored Symbol +158413 - 0x09E7B (Right Row 5) - 0x09E69 - Full Dots & Triangles 158414 - 0x09E73 (Left Row 1) - True - Dots & Black/White Squares 158415 - 0x09E75 (Left Row 2) - 0x09E73 - Arrows & Black/White Squares 158416 - 0x09E78 (Left Row 3) - 0x09E75 - Arrows & Stars 158417 - 0x09E79 (Left Row 4) - 0x09E78 - Arrows & Shapers & Rotated Shapers -158418 - 0x09E6C (Left Row 5) - 0x09E79 - Arrows & Black/White Squares & Stars & Stars + Same Colored Symbol -158419 - 0x09E6F (Left Row 6) - 0x09E6C - Arrows & Dots & Full Dots -158420 - 0x09E6B (Left Row 7) - 0x09E6F - Arrows & Dots & Full Dots +158418 - 0x09E6C (Left Row 5) - 0x09E79 - Arrows & Black/White Squares & Stars + Same Colored Symbol +158419 - 0x09E6F (Left Row 6) - 0x09E6C - Arrows & Full Dots +158420 - 0x09E6B (Left Row 7) - 0x09E6F - Arrows & Full Dots 158424 - 0x09EAD (Trash Pillar 1) - True - Triangles & Arrows 158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Triangles & Arrows @@ -1044,10 +1044,10 @@ Mountain Floor 1 At Door (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B Mountain Floor 2 (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Near - 0x09FFB - Mountain Floor 2 Beyond Bridge - 0x09E86 - Mountain Floor 2 Above The Abyss - True - Mountain Pink Bridge EP - TrueOneWay: -158426 - 0x09FD3 (Near Row 1) - True - Stars & Stars + Same Colored Symbol & Colored Squares -158427 - 0x09FD4 (Near Row 2) - 0x09FD3 - Stars & Stars + Same Colored Symbol & Triangles -158428 - 0x09FD6 (Near Row 3) - 0x09FD4 - Stars & Stars + Same Colored Symbol & Colored Squares & Eraser -158429 - 0x09FD7 (Near Row 4) - 0x09FD6 - Stars & Stars + Same Colored Symbol & Shapers & Eraser +158426 - 0x09FD3 (Near Row 1) - True - Stars + Same Colored Symbol & Colored Squares +158427 - 0x09FD4 (Near Row 2) - 0x09FD3 - Stars + Same Colored Symbol & Triangles +158428 - 0x09FD6 (Near Row 3) - 0x09FD4 - Stars + Same Colored Symbol & Colored Squares & Eraser +158429 - 0x09FD7 (Near Row 4) - 0x09FD6 - Stars + Same Colored Symbol & Shapers & Eraser 158430 - 0x09FD8 (Near Row 5) - 0x09FD7 - Symmetry & Triangles Door - 0x09FFB (Staircase Near) - 0x09FD8 @@ -1055,19 +1055,19 @@ Mountain Floor 2 Above The Abyss (Mountain Floor 2) - Mountain Floor 2 Elevator Door - 0x09EDD (Elevator Room Entry) - 0x09ED8 & 0x09E86 Mountain Floor 2 Light Bridge Room Near (Mountain Floor 2): -158431 - 0x09E86 (Light Bridge Controller Near) - True - Stars & Stars + Same Colored Symbol & Rotated Shapers & Eraser +158431 - 0x09E86 (Light Bridge Controller Near) - True - Stars + Same Colored Symbol & Rotated Shapers & Eraser Mountain Floor 2 Beyond Bridge (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Far - 0x09E07 - Mountain Pink Bridge EP - TrueOneWay - Mountain Floor 2 - 0x09ED8: 158432 - 0x09FCC (Far Row 1) - True - Black/White Squares 158433 - 0x09FCE (Far Row 2) - 0x09FCC - Triangles 158434 - 0x09FCF (Far Row 3) - 0x09FCE - Stars -158435 - 0x09FD0 (Far Row 4) - 0x09FCF - Stars & Stars + Same Colored Symbol & Colored Squares +158435 - 0x09FD0 (Far Row 4) - 0x09FCF - Stars + Same Colored Symbol & Colored Squares 158436 - 0x09FD1 (Far Row 5) - 0x09FD0 - Dots 158437 - 0x09FD2 (Far Row 6) - 0x09FD1 - Shapers Door - 0x09E07 (Staircase Far) - 0x09FD2 Mountain Floor 2 Light Bridge Room Far (Mountain Floor 2): -158438 - 0x09ED8 (Light Bridge Controller Far) - True - Stars & Stars + Same Colored Symbol & Rotated Shapers & Eraser +158438 - 0x09ED8 (Light Bridge Controller Far) - True - Stars + Same Colored Symbol & Rotated Shapers & Eraser Mountain Floor 2 Elevator Room (Mountain Floor 2) - Mountain Floor 2 Elevator - TrueOneWay: 158613 - 0x17F93 (Elevator Discard) - True - Arrows & Triangles @@ -1095,10 +1095,10 @@ Door - 0x17F33 (Rock Open) - 0x17FA2 | 0x334E1 Mountain Bottom Floor Pillars Room (Mountain Bottom Floor) - Elevator - 0x339BB & 0x33961: 158522 - 0x0383A (Right Pillar 1) - True - Stars 158523 - 0x09E56 (Right Pillar 2) - 0x0383A - Stars & Dots -158524 - 0x09E5A (Right Pillar 3) - 0x09E56 - Dots & Full Dots & Triangles +158524 - 0x09E5A (Right Pillar 3) - 0x09E56 - Full Dots & Triangles 158525 - 0x33961 (Right Pillar 4) - 0x09E5A - Dots & Symmetry & Triangles 158526 - 0x0383D (Left Pillar 1) - True - Triangles -158527 - 0x0383F (Left Pillar 2) - 0x0383D - Black/White Squares & Stars & Stars + Same Colored Symbol +158527 - 0x0383F (Left Pillar 2) - 0x0383D - Black/White Squares & Stars + Same Colored Symbol 158528 - 0x03859 (Left Pillar 3) - 0x0383F - Shapers 158529 - 0x339BB (Left Pillar 4) - 0x03859 - Triangles & Symmetry @@ -1127,16 +1127,16 @@ Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x01 158451 - 0x335AB (Elevator Inside Control) - True - Dots & Black/White Squares 158452 - 0x335AC (Elevator Upper Outside Control) - 0x335AB - Black/White Squares 158453 - 0x3369D (Elevator Lower Outside Control) - 0x335AB - Black/White Squares & Dots -158454 - 0x00190 (Blue Tunnel Right First 1) - True - Dots & Full Dots & Triangles & Arrows -158455 - 0x00558 (Blue Tunnel Right First 2) - 0x00190 - Dots & Full Dots & Triangles & Arrows -158456 - 0x00567 (Blue Tunnel Right First 3) - 0x00558 - Dots & Full Dots & Triangles & Arrows -158457 - 0x006FE (Blue Tunnel Right First 4) - 0x00567 - Dots & Full Dots & Triangles & Arrows +158454 - 0x00190 (Blue Tunnel Right First 1) - True - Full Dots & Triangles & Arrows +158455 - 0x00558 (Blue Tunnel Right First 2) - 0x00190 - Full Dots & Triangles & Arrows +158456 - 0x00567 (Blue Tunnel Right First 3) - 0x00558 - Full Dots & Triangles & Arrows +158457 - 0x006FE (Blue Tunnel Right First 4) - 0x00567 - Full Dots & Triangles & Arrows 158458 - 0x01A0D (Blue Tunnel Left First 1) - True - Symmetry & Triangles & Arrows 158459 - 0x008B8 (Blue Tunnel Left Second 1) - True - Triangles & Colored Squares & Arrows 158460 - 0x00973 (Blue Tunnel Left Second 2) - 0x008B8 - Triangles & Colored Squares & Arrows -158461 - 0x0097B (Blue Tunnel Left Second 3) - 0x00973 - Triangles & Colored Squares & Arrows & Stars & Stars + Same Colored Symbol -158462 - 0x0097D (Blue Tunnel Left Second 4) - 0x0097B - Triangles & Colored Squares & Arrows & Stars & Stars + Same Colored Symbol -158463 - 0x0097E (Blue Tunnel Left Second 5) - 0x0097D - Triangles & Colored Squares & Arrows & Stars & Stars + Same Colored Symbol +158461 - 0x0097B (Blue Tunnel Left Second 3) - 0x00973 - Triangles & Colored Squares & Arrows & Stars + Same Colored Symbol +158462 - 0x0097D (Blue Tunnel Left Second 4) - 0x0097B - Triangles & Colored Squares & Arrows & Stars + Same Colored Symbol +158463 - 0x0097E (Blue Tunnel Left Second 5) - 0x0097D - Triangles & Colored Squares & Arrows & Stars + Same Colored Symbol 158464 - 0x00994 (Blue Tunnel Right Second 1) - True - Rotated Shapers & Triangles 158465 - 0x334D5 (Blue Tunnel Right Second 2) - 0x00994 - Rotated Shapers & Triangles 158466 - 0x00995 (Blue Tunnel Right Second 3) - 0x334D5 - Rotated Shapers & Triangles @@ -1146,30 +1146,30 @@ Caves (Caves) - Main Island - 0x2D73F | 0x2D859 - Caves Path to Challenge - 0x01 158470 - 0x018A0 (Blue Tunnel Right Third 1) - True - Shapers & Symmetry & Eraser 158471 - 0x00A72 (Blue Tunnel Left Fourth 1) - True - Shapers & Negative Shapers & Triangles 158472 - 0x32962 (First Floor Left) - True - Rotated Shapers & Dots -158473 - 0x32966 (First Floor Grounded) - True - Stars & Black/White Squares & Stars + Same Colored Symbol & Shapers & Triangles +158473 - 0x32966 (First Floor Grounded) - True - Black/White Squares & Stars + Same Colored Symbol & Shapers & Triangles 158474 - 0x01A31 (First Floor Middle) - True - Colored Squares -158475 - 0x00B71 (First Floor Right) - True - Colored Squares & Stars & Stars + Same Colored Symbol & Eraser & Shapers & Negative Shapers & Dots +158475 - 0x00B71 (First Floor Right) - True - Colored Squares & Stars + Same Colored Symbol & Eraser & Shapers & Negative Shapers & Dots 158478 - 0x288EA (First Wooden Beam) - True - Colored Squares & Black/White Squares & Eraser -158479 - 0x288FC (Second Wooden Beam) - True - Black/White Squares & Stars & Stars + Same Colored Symbol & Eraser -158480 - 0x289E7 (Third Wooden Beam) - True - Black/White Squares & Stars & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Eraser +158479 - 0x288FC (Second Wooden Beam) - True - Black/White Squares & Stars + Same Colored Symbol & Eraser +158480 - 0x289E7 (Third Wooden Beam) - True - Black/White Squares & Stars + Same Colored Symbol & Shapers & Rotated Shapers & Eraser 158481 - 0x288AA (Fourth Wooden Beam) - True - Stars & Shapers & Eraser -158482 - 0x17FB9 (Left Upstairs Single) - True - Stars & Dots & Full Dots -158483 - 0x0A16B (Left Upstairs Left Row 1) - True - Dots & Full Dots & Black/White Squares -158484 - 0x0A2CE (Left Upstairs Left Row 2) - 0x0A16B - Dots & Full Dots & Stars -158485 - 0x0A2D7 (Left Upstairs Left Row 3) - 0x0A2CE - Dots & Full Dots & Shapers -158486 - 0x0A2DD (Left Upstairs Left Row 4) - 0x0A2D7 - Dots & Full Dots & Triangles -158487 - 0x0A2EA (Left Upstairs Left Row 5) - 0x0A2DD - Dots & Full Dots & Triangles & Eraser +158482 - 0x17FB9 (Left Upstairs Single) - True - Stars & Full Dots +158483 - 0x0A16B (Left Upstairs Left Row 1) - True - Full Dots & Black/White Squares +158484 - 0x0A2CE (Left Upstairs Left Row 2) - 0x0A16B - Full Dots & Stars +158485 - 0x0A2D7 (Left Upstairs Left Row 3) - 0x0A2CE - Full Dots & Shapers +158486 - 0x0A2DD (Left Upstairs Left Row 4) - 0x0A2D7 - Full Dots & Triangles +158487 - 0x0A2EA (Left Upstairs Left Row 5) - 0x0A2DD - Full Dots & Triangles & Eraser 158488 - 0x0008F (Right Upstairs Left Row 1) - True - Dots 158489 - 0x0006B (Right Upstairs Left Row 2) - 0x0008F - Black/White Squares & Colored Squares -158490 - 0x0008B (Right Upstairs Left Row 3) - 0x0006B - Black/White Squares & Colored Squares & Stars & Stars + Same Colored Symbol -158491 - 0x0008C (Right Upstairs Left Row 4) - 0x0008B - Black/White Squares & Colored Squares & Stars & Stars + Same Colored Symbol & Shapers -158492 - 0x0008A (Right Upstairs Left Row 5) - 0x0008C - Black/White Squares & Colored Squares & Stars & Stars + Same Colored Symbol -158493 - 0x00089 (Right Upstairs Left Row 6) - 0x0008A - Black/White Squares & Colored Squares & Stars & Stars + Same Colored Symbol & Rotated Shapers -158494 - 0x0006A (Right Upstairs Left Row 7) - 0x00089 - Stars & Stars + Same Colored Symbol & Shapers & Negative Shapers +158490 - 0x0008B (Right Upstairs Left Row 3) - 0x0006B - Black/White Squares & Colored Squares & Stars + Same Colored Symbol +158491 - 0x0008C (Right Upstairs Left Row 4) - 0x0008B - Black/White Squares & Colored Squares & Stars + Same Colored Symbol & Shapers +158492 - 0x0008A (Right Upstairs Left Row 5) - 0x0008C - Black/White Squares & Colored Squares & Stars + Same Colored Symbol +158493 - 0x00089 (Right Upstairs Left Row 6) - 0x0008A - Black/White Squares & Colored Squares & Stars + Same Colored Symbol & Rotated Shapers +158494 - 0x0006A (Right Upstairs Left Row 7) - 0x00089 - Stars + Same Colored Symbol & Shapers & Negative Shapers 158495 - 0x0006C (Right Upstairs Left Row 8) - 0x0006A - Dots & Shapers & Negative Shapers & Eraser 158496 - 0x00027 (Right Upstairs Right Row 1) - True - Black/White Squares & Colored Squares & Eraser & Symmetry 158497 - 0x00028 (Right Upstairs Right Row 2) - 0x00027 - Black/White Squares & Colored Squares & Eraser & Symmetry -158498 - 0x00029 (Right Upstairs Right Row 3) - 0x00028 - Stars & Stars + Same Colored Symbol & Eraser & Symmetry +158498 - 0x00029 (Right Upstairs Right Row 3) - 0x00028 - Stars + Same Colored Symbol & Eraser & Symmetry 158476 - 0x09DD5 (Lone Pillar) - True - Triangles & Dots Door - 0x019A5 (Pillar Door) - 0x09DD5 158449 - 0x021D7 (Mountain Shortcut Panel) - True - Triangles @@ -1179,7 +1179,7 @@ Door - 0x2D859 (Swamp Shortcut Door) - 0x17CF2 159341 - 0x3397C (Skylight EP) - True - True Caves Path to Challenge (Caves) - Challenge - 0x0A19A: -158477 - 0x0A16E (Challenge Entry Panel) - True - Stars & Shapers & Stars + Same Colored Symbol & Triangles +158477 - 0x0A16E (Challenge Entry Panel) - True - Shapers & Stars + Same Colored Symbol & Triangles Door - 0x0A19A (Challenge Entry) - 0x0A16E ==Challenge== From 6ad042b3498d293e8dff5c8dde1539a1e70ca073 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Thu, 24 Apr 2025 21:56:52 +0200 Subject: [PATCH 0362/1218] Core: Add Region.add_event (#2965) * region.add_event function * Make it return the location bc why not * Actually item bc that seems more useful * Update BaseClasses.py Co-authored-by: Aaron Wagener * Update BaseClasses.py Co-authored-by: Aaron Wagener * add all the requested features from code review * oop * roughly sort args in order of importance (imo) * Fix typing --------- Co-authored-by: Aaron Wagener --- BaseClasses.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/BaseClasses.py b/BaseClasses.py index bf115e3f9c96..e59e96e17d1c 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1198,6 +1198,48 @@ def add_locations(self, locations: Dict[str, Optional[int]], for location, address in locations.items(): self.locations.append(location_type(self.player, location, address, self)) + def add_event( + self, + location_name: str, + item_name: str | None = None, + rule: Callable[[CollectionState], bool] | None = None, + location_type: type[Location] | None = None, + item_type: type[Item] | None = None, + show_in_spoiler: bool = True, + ) -> Item: + """ + Adds an event location/item pair to the region. + + :param location_name: Name for the event location. + :param item_name: Name for the event item. If not provided, defaults to location_name. + :param rule: Callable to determine access for this event location within its region. + :param location_type: Location class to create the event location with. Defaults to BaseClasses.Location. + :param item_type: Item class to create the event item with. Defaults to BaseClasses.Item. + :param show_in_spoiler: Will be passed along to the created event Location's show_in_spoiler attribute. + :return: The created Event Item + """ + if location_type is None: + location_type = Location + + if item_name is None: + item_name = location_name + + if item_type is None: + item_type = Item + + event_location = location_type(self.player, location_name, None, self) + event_location.show_in_spoiler = show_in_spoiler + if rule is not None: + event_location.access_rule = rule + + event_item = item_type(item_name, ItemClassification.progression, None, self.player) + + event_location.place_locked_item(event_item) + + self.locations.append(event_location) + + return event_item + def connect(self, connecting_region: Region, name: Optional[str] = None, rule: Optional[Callable[[CollectionState], bool]] = None) -> Entrance: """ From 05c1751d293ea27fa4ee7c6f4797be772d111ae2 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Thu, 24 Apr 2025 22:06:41 +0200 Subject: [PATCH 0363/1218] Core: Add "OptionCounter", use it for generic "StartInventory" and Witness "TrapWeights" (#3756) * CounterOption * bring back the negative exception for ItemDict * Backwards compatibility * ruff on witness * fix in calls * move the contains * comment * comment * Add option min and max values for CounterOption * Use min 0 for TrapWeights * This is safe now * ruff * This fits on one line again now * OptionCounter * Update Options.py * Couple more typing things * Update Options.py * Make StartInventory work again, also make LocationCounter theoretically work * Docs * more forceful wording * forced line break * Fix unit test (that wasn't breaking?) * Add trapweights to witness option presets to 'prove' that the unit test passes * Make it so you can order stuff * Update macros.html --- Options.py | 47 ++++++++++++++++--- Utils.py | 3 ++ WebHostLib/options.py | 4 +- .../templates/playerOptions/macros.html | 13 ++++- .../playerOptions/playerOptions.html | 12 +++-- .../templates/weightedOptions/macros.html | 13 ++++- .../weightedOptions/weightedOptions.html | 6 ++- docs/options api.md | 9 +++- test/webhost/test_option_presets.py | 4 +- worlds/witness/options.py | 28 ++++++----- worlds/witness/presets.py | 6 +++ 11 files changed, 111 insertions(+), 34 deletions(-) diff --git a/Options.py b/Options.py index 95b9b468c6e9..6a6bbe5e7794 100644 --- a/Options.py +++ b/Options.py @@ -1,6 +1,7 @@ from __future__ import annotations import abc +import collections import functools import logging import math @@ -866,15 +867,49 @@ def __iter__(self) -> typing.Iterator[str]: def __len__(self) -> int: return self.value.__len__() + # __getitem__ fallback fails for Counters, so we define this explicitly + def __contains__(self, item) -> bool: + return item in self.value + + +class OptionCounter(OptionDict): + min: int | None = None + max: int | None = None + + def __init__(self, value: dict[str, int]) -> None: + super(OptionCounter, self).__init__(collections.Counter(value)) + + def verify(self, world: type[World], player_name: str, plando_options: PlandoOptions) -> None: + super(OptionCounter, self).verify(world, player_name, plando_options) + + range_errors = [] -class ItemDict(OptionDict): + if self.max is not None: + range_errors += [ + f"\"{key}: {value}\" is higher than maximum allowed value {self.max}." + for key, value in self.value.items() if value > self.max + ] + + if self.min is not None: + range_errors += [ + f"\"{key}: {value}\" is lower than minimum allowed value {self.min}." + for key, value in self.value.items() if value < self.min + ] + + if range_errors: + range_errors = [f"For option {getattr(self, 'display_name', self)}:"] + range_errors + raise OptionError("\n".join(range_errors)) + + +class ItemDict(OptionCounter): verify_item_name = True - def __init__(self, value: typing.Dict[str, int]): - if any(item_count is None for item_count in value.values()): - raise Exception("Items must have counts associated with them. Please provide positive integer values in the format \"item\": count .") - if any(item_count < 1 for item_count in value.values()): - raise Exception("Cannot have non-positive item counts.") + min = 0 + + def __init__(self, value: dict[str, int]) -> None: + # Backwards compatibility: Cull 0s to make "in" checks behave the same as when this wasn't a OptionCounter + value = {item_name: amount for item_name, amount in value.items() if amount != 0} + super(ItemDict, self).__init__(value) diff --git a/Utils.py b/Utils.py index e4e94a45f6df..46a0d106ef85 100644 --- a/Utils.py +++ b/Utils.py @@ -429,6 +429,9 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: def find_class(self, module: str, name: str) -> type: if module == "builtins" and name in safe_builtins: return getattr(builtins, name) + # used by OptionCounter + if module == "collections" and name == "Counter": + return collections.Counter # used by MultiServer -> savegame/multidata if module == "NetUtils" and name in {"NetworkItem", "ClientStatus", "Hint", "SlotType", "NetworkSlot", "HintStatus"}: diff --git a/WebHostLib/options.py b/WebHostLib/options.py index 711762ee5f87..38489cee3c49 100644 --- a/WebHostLib/options.py +++ b/WebHostLib/options.py @@ -108,7 +108,7 @@ def option_presets(game: str) -> Response: f"Expected {option.special_range_names.keys()} or {option.range_start}-{option.range_end}." presets[preset_name][preset_option_name] = option.value - elif isinstance(option, (Options.Range, Options.OptionSet, Options.OptionList, Options.ItemDict)): + elif isinstance(option, (Options.Range, Options.OptionSet, Options.OptionList, Options.OptionCounter)): presets[preset_name][preset_option_name] = option.value elif isinstance(preset_option, str): # Ensure the option value is valid for Choice and Toggle options @@ -222,7 +222,7 @@ def generate_yaml(game: str): for key, val in options.copy().items(): key_parts = key.rsplit("||", 2) - # Detect and build ItemDict options from their name pattern + # Detect and build OptionCounter options from their name pattern if key_parts[-1] == "qty": if key_parts[0] not in options: options[key_parts[0]] = {} diff --git a/WebHostLib/templates/playerOptions/macros.html b/WebHostLib/templates/playerOptions/macros.html index 972f03175d51..bbb3c75d12a3 100644 --- a/WebHostLib/templates/playerOptions/macros.html +++ b/WebHostLib/templates/playerOptions/macros.html @@ -111,10 +111,19 @@
{% endmacro %} -{% macro ItemDict(option_name, option) %} +{% macro OptionCounter(option_name, option) %} + {% set relevant_keys = option.valid_keys %} + {% if not relevant_keys %} + {% if option.verify_item_name %} + {% set relevant_keys = world.item_names %} + {% elif option.verify_location_name %} + {% set relevant_keys = world.location_names %} + {% endif %} + {% endif %} + {{ OptionTitle(option_name, option) }}
- {% for item_name in (option.valid_keys|sort if (option.valid_keys|length > 0) else world.item_names|sort) %} + {% for item_name in (relevant_keys if relevant_keys is ordered else relevant_keys|sort) %}
diff --git a/WebHostLib/templates/playerOptions/playerOptions.html b/WebHostLib/templates/playerOptions/playerOptions.html index 7e2f0ee11cb4..5e82342126f7 100644 --- a/WebHostLib/templates/playerOptions/playerOptions.html +++ b/WebHostLib/templates/playerOptions/playerOptions.html @@ -93,8 +93,10 @@

Player Options

{% elif issubclass(option, Options.FreeText) %} {{ inputs.FreeText(option_name, option) }} - {% elif issubclass(option, Options.ItemDict) and option.verify_item_name %} - {{ inputs.ItemDict(option_name, option) }} + {% elif issubclass(option, Options.OptionCounter) and ( + option.valid_keys or option.verify_item_name or option.verify_location_name + ) %} + {{ inputs.OptionCounter(option_name, option) }} {% elif issubclass(option, Options.OptionList) and option.valid_keys %} {{ inputs.OptionList(option_name, option) }} @@ -133,8 +135,10 @@

Player Options

{% elif issubclass(option, Options.FreeText) %} {{ inputs.FreeText(option_name, option) }} - {% elif issubclass(option, Options.ItemDict) and option.verify_item_name %} - {{ inputs.ItemDict(option_name, option) }} + {% elif issubclass(option, Options.OptionCounter) and ( + option.valid_keys or option.verify_item_name or option.verify_location_name + ) %} + {{ inputs.OptionCounter(option_name, option) }} {% elif issubclass(option, Options.OptionList) and option.valid_keys %} {{ inputs.OptionList(option_name, option) }} diff --git a/WebHostLib/templates/weightedOptions/macros.html b/WebHostLib/templates/weightedOptions/macros.html index d18d0f0b8957..89ba0a0e6e7a 100644 --- a/WebHostLib/templates/weightedOptions/macros.html +++ b/WebHostLib/templates/weightedOptions/macros.html @@ -113,9 +113,18 @@ {{ TextChoice(option_name, option) }} {% endmacro %} -{% macro ItemDict(option_name, option, world) %} +{% macro OptionCounter(option_name, option, world) %} + {% set relevant_keys = option.valid_keys %} + {% if not relevant_keys %} + {% if option.verify_item_name %} + {% set relevant_keys = world.item_names %} + {% elif option.verify_location_name %} + {% set relevant_keys = world.location_names %} + {% endif %} + {% endif %} +
- {% for item_name in (option.valid_keys|sort if (option.valid_keys|length > 0) else world.item_names|sort) %} + {% for item_name in (relevant_keys if relevant_keys is ordered else relevant_keys|sort) %}
{{ option.display_name|default(option_name) }} {% elif issubclass(option, Options.FreeText) %} {{ inputs.FreeText(option_name, option) }} - {% elif issubclass(option, Options.ItemDict) and option.verify_item_name %} - {{ inputs.ItemDict(option_name, option, world) }} + {% elif issubclass(option, Options.OptionCounter) and ( + option.valid_keys or option.verify_item_name or option.verify_location_name + ) %} + {{ inputs.OptionCounter(option_name, option, world) }} {% elif issubclass(option, Options.OptionList) and option.valid_keys %} {{ inputs.OptionList(option_name, option) }} diff --git a/docs/options api.md b/docs/options api.md index 453cbc7e2d36..037b9edb8711 100644 --- a/docs/options api.md +++ b/docs/options api.md @@ -352,8 +352,15 @@ template. If you set a [Schema](https://pypi.org/project/schema/) on the class w options system will automatically validate the user supplied data against the schema to ensure it's in the correct format. +### OptionCounter +This is a special case of OptionDict where the dictionary values can only be integers. +It returns a [collections.Counter](https://docs.python.org/3/library/collections.html#collections.Counter). +This means that if you access a key that isn't present, its value will be 0. +The upside of using an OptionCounter (instead of an OptionDict with integer values) is that an OptionCounter can be +displayed on the Options page on WebHost. + ### ItemDict -Like OptionDict, except this will verify that every key in the dictionary is a valid name for an item for your world. +An OptionCounter that will verify that every key in the dictionary is a valid name for an item for your world. ### OptionList This option defines a List, where the user can add any number of strings to said list, allowing duplicate values. You diff --git a/test/webhost/test_option_presets.py b/test/webhost/test_option_presets.py index 7105c7f80593..efacddb22e6a 100644 --- a/test/webhost/test_option_presets.py +++ b/test/webhost/test_option_presets.py @@ -2,7 +2,7 @@ from BaseClasses import PlandoOptions from worlds import AutoWorldRegister -from Options import ItemDict, NamedRange, NumericOption, OptionList, OptionSet +from Options import OptionCounter, NamedRange, NumericOption, OptionList, OptionSet class TestOptionPresets(unittest.TestCase): @@ -19,7 +19,7 @@ def test_option_presets_have_valid_options(self): # pass in all plando options in case a preset wants to require certain plando options # for some reason option.verify(world_type, "Test Player", PlandoOptions(sum(PlandoOptions))) - supported_types = [NumericOption, OptionSet, OptionList, ItemDict] + supported_types = [NumericOption, OptionSet, OptionList, OptionCounter] if not any([issubclass(option.__class__, t) for t in supported_types]): self.fail(f"'{option_name}' in preset '{preset_name}' for game '{game_name}' " f"is not a supported type for webhost. " diff --git a/worlds/witness/options.py b/worlds/witness/options.py index 050bb7e904e2..6a64fdb3d877 100644 --- a/worlds/witness/options.py +++ b/worlds/witness/options.py @@ -7,7 +7,7 @@ Choice, DefaultOnToggle, LocationSet, - OptionDict, + OptionCounter, OptionError, OptionGroup, OptionSet, @@ -414,23 +414,25 @@ class TrapPercentage(Range): default = 20 -class TrapWeights(OptionDict): +_default_trap_weights = { + trap_name: item_definition.weight + for trap_name, item_definition in static_witness_logic.ALL_ITEMS.items() + if isinstance(item_definition, WeightedItemDefinition) and item_definition.category is ItemCategory.TRAP +} + + +class TrapWeights(OptionCounter): """ Specify the weights determining how many copies of each trap item will be in your itempool. - If you don't want a specific type of trap, you can set the weight for it to 0 (Do not delete the entry outright!). + If you don't want a specific type of trap, you can set the weight for it to 0. If you set all trap weights to 0, you will get no traps, bypassing the "Trap Percentage" option. """ display_name = "Trap Weights" - schema = Schema({ - trap_name: And(int, lambda n: n >= 0) - for trap_name, item_definition in static_witness_logic.ALL_ITEMS.items() - if isinstance(item_definition, WeightedItemDefinition) and item_definition.category is ItemCategory.TRAP - }) - default = { - trap_name: item_definition.weight - for trap_name, item_definition in static_witness_logic.ALL_ITEMS.items() - if isinstance(item_definition, WeightedItemDefinition) and item_definition.category is ItemCategory.TRAP - } + valid_keys = _default_trap_weights.keys() + + min = 0 + + default = _default_trap_weights class PuzzleSkipAmount(Range): diff --git a/worlds/witness/presets.py b/worlds/witness/presets.py index 687d74f771cb..81dd28d68d09 100644 --- a/worlds/witness/presets.py +++ b/worlds/witness/presets.py @@ -40,6 +40,8 @@ "trap_percentage": TrapPercentage.default, "puzzle_skip_amount": PuzzleSkipAmount.default, + "trap_weights": TrapWeights.default, + "hint_amount": HintAmount.default, "area_hint_percentage": AreaHintPercentage.default, "laser_hints": LaserHints.default, @@ -79,6 +81,8 @@ "trap_percentage": TrapPercentage.default, "puzzle_skip_amount": 15, + "trap_weights": TrapWeights.default, + "hint_amount": HintAmount.default, "area_hint_percentage": AreaHintPercentage.default, "laser_hints": LaserHints.default, @@ -118,6 +122,8 @@ "trap_percentage": TrapPercentage.default, "puzzle_skip_amount": 15, + "trap_weights": TrapWeights.default, + "hint_amount": HintAmount.default, "area_hint_percentage": AreaHintPercentage.default, "laser_hints": LaserHints.default, From d4110d3b2a0186b8498b140bc24667641f0def8b Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Thu, 24 Apr 2025 23:10:58 +0200 Subject: [PATCH 0364/1218] LttP: make progression health optional (#4918) --- worlds/alttp/ItemPool.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/worlds/alttp/ItemPool.py b/worlds/alttp/ItemPool.py index 0bcc189f9c3b..57ad01b9e408 100644 --- a/worlds/alttp/ItemPool.py +++ b/worlds/alttp/ItemPool.py @@ -490,12 +490,16 @@ def cut_item(items, item_to_cut, minimum_items): # Otherwise, logic has some branches where having 4 hearts is one possible requirement (of several alternatives) # rather than making all hearts/heart pieces progression items (which slows down generation considerably) # We mark one random heart container as an advancement item (or 4 heart pieces in expert mode) - if world.options.item_pool in ['easy', 'normal', 'hard'] and not (multiworld.custom and multiworld.customitemarray[30] == 0): - next(item for item in items if item.name == 'Boss Heart Container').classification = ItemClassification.progression - elif world.options.item_pool in ['expert'] and not (multiworld.custom and multiworld.customitemarray[29] < 4): + try: + next(item for item in items if item.name == 'Boss Heart Container').classification \ + |= ItemClassification.progression + except StopIteration: adv_heart_pieces = (item for item in items if item.name == 'Piece of Heart') for i in range(4): - next(adv_heart_pieces).classification = ItemClassification.progression + try: + next(adv_heart_pieces).classification |= ItemClassification.progression + except StopIteration: + break # logically health tanking is an option, so rules should still resolve to something beatable world.required_medallions = (world.options.misery_mire_medallion.current_key.title(), world.options.turtle_rock_medallion.current_key.title()) From fc04192c992af1ec7288a774332107293cbbe06b Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Thu, 24 Apr 2025 17:14:42 -0400 Subject: [PATCH 0365/1218] Lingo: Use OptionCounter for trap_weights (#4920) --- worlds/lingo/options.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/worlds/lingo/options.py b/worlds/lingo/options.py index f9d04f68fc8e..faf5316e903c 100644 --- a/worlds/lingo/options.py +++ b/worlds/lingo/options.py @@ -2,7 +2,7 @@ from schema import And, Schema -from Options import Toggle, Choice, DefaultOnToggle, Range, PerGameCommonOptions, StartInventoryPool, OptionDict, \ +from Options import Toggle, Choice, DefaultOnToggle, Range, PerGameCommonOptions, StartInventoryPool, OptionCounter, \ OptionGroup from .items import TRAP_ITEMS @@ -222,13 +222,14 @@ class TrapPercentage(Range): default = 20 -class TrapWeights(OptionDict): +class TrapWeights(OptionCounter): """Specify the distribution of traps that should be placed into the pool. If you don't want a specific type of trap, set the weight to zero. """ display_name = "Trap Weights" - schema = Schema({trap_name: And(int, lambda n: n >= 0) for trap_name in TRAP_ITEMS}) + valid_keys = TRAP_ITEMS + min = 0 default = {trap_name: 1 for trap_name in TRAP_ITEMS} From abb6d7fbdb71ac8d29a867067a4a1abc15a24d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Thu, 24 Apr 2025 17:36:25 -0400 Subject: [PATCH 0366/1218] Stardew Valley: Replace all add_rule by set_rule #4909 --- worlds/stardew_valley/rules.py | 376 ++++++++++++++++----------------- 1 file changed, 188 insertions(+), 188 deletions(-) diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index 4b1ff2ad5673..4257f856c83d 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -3,7 +3,7 @@ from typing import List, Dict, Set from BaseClasses import MultiWorld, CollectionState -from worlds.generic import Rules as MultiWorldRules +from worlds.generic.Rules import set_rule from . import locations from .bundles.bundle_room import BundleRoom from .content import StardewContent @@ -98,28 +98,28 @@ def set_rules(world): def set_isolated_locations_rules(logic: StardewLogic, multiworld, player): - MultiWorldRules.add_rule(multiworld.get_location("Old Master Cannoli", player), - logic.has(Fruit.sweet_gem_berry)) - MultiWorldRules.add_rule(multiworld.get_location("Galaxy Sword Shrine", player), - logic.has("Prismatic Shard")) - MultiWorldRules.add_rule(multiworld.get_location("Krobus Stardrop", player), - logic.money.can_spend(20000)) - MultiWorldRules.add_rule(multiworld.get_location("Demetrius's Breakthrough", player), - logic.money.can_have_earned_total(25000)) - MultiWorldRules.add_rule(multiworld.get_location("Pot Of Gold", player), - logic.season.has(Season.spring)) + set_rule(multiworld.get_location("Old Master Cannoli", player), + logic.has(Fruit.sweet_gem_berry)) + set_rule(multiworld.get_location("Galaxy Sword Shrine", player), + logic.has("Prismatic Shard")) + set_rule(multiworld.get_location("Krobus Stardrop", player), + logic.money.can_spend(20000)) + set_rule(multiworld.get_location("Demetrius's Breakthrough", player), + logic.money.can_have_earned_total(25000)) + set_rule(multiworld.get_location("Pot Of Gold", player), + logic.season.has(Season.spring)) def set_tool_rules(logic: StardewLogic, multiworld, player, content: StardewContent): if not content.features.tool_progression.is_progressive: return - MultiWorldRules.add_rule(multiworld.get_location("Purchase Fiberglass Rod", player), - (logic.skill.has_level(Skill.fishing, 2) & logic.money.can_spend(1800))) - MultiWorldRules.add_rule(multiworld.get_location("Purchase Iridium Rod", player), - (logic.skill.has_level(Skill.fishing, 6) & logic.money.can_spend(7500))) + set_rule(multiworld.get_location("Purchase Fiberglass Rod", player), + (logic.skill.has_level(Skill.fishing, 2) & logic.money.can_spend(1800))) + set_rule(multiworld.get_location("Purchase Iridium Rod", player), + (logic.skill.has_level(Skill.fishing, 6) & logic.money.can_spend(7500))) - MultiWorldRules.add_rule(multiworld.get_location("Copper Pan Cutscene", player), logic.received("Glittering Boulder Removed")) + set_rule(multiworld.get_location("Copper Pan Cutscene", player), logic.received("Glittering Boulder Removed")) materials = [None, "Copper", "Iron", "Gold", "Iridium"] tool = [Tool.hoe, Tool.pickaxe, Tool.axe, Tool.watering_can, Tool.trash_can, Tool.pan] @@ -127,7 +127,7 @@ def set_tool_rules(logic: StardewLogic, multiworld, player, content: StardewCont if previous is None: continue tool_upgrade_location = multiworld.get_location(f"{material} {tool} Upgrade", player) - MultiWorldRules.set_rule(tool_upgrade_location, logic.tool.has_tool(tool, previous)) + set_rule(tool_upgrade_location, logic.tool.has_tool(tool, previous)) def set_building_rules(logic: StardewLogic, multiworld, player, content: StardewContent): @@ -141,8 +141,8 @@ def set_building_rules(logic: StardewLogic, multiworld, player, content: Stardew location_name = building_progression.to_location_name(building.name) - MultiWorldRules.set_rule(multiworld.get_location(location_name, player), - logic.building.can_build(building.name)) + set_rule(multiworld.get_location(location_name, player), + logic.building.can_build(building.name)) def set_bundle_rules(bundle_rooms: List[BundleRoom], logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): @@ -160,11 +160,11 @@ def set_bundle_rules(bundle_rooms: List[BundleRoom], logic: StardewLogic, multiw previous_bundle_name = f"Raccoon Request {num - 1}" bundle_rules = bundle_rules & logic.region.can_reach_location(previous_bundle_name) room_rules.append(bundle_rules) - MultiWorldRules.set_rule(location, bundle_rules) + set_rule(location, bundle_rules) if bundle_room.name == CCRoom.abandoned_joja_mart or bundle_room.name == CCRoom.raccoon_requests: continue room_location = f"Complete {bundle_room.name}" - MultiWorldRules.add_rule(multiworld.get_location(room_location, player), And(*room_rules)) + set_rule(multiworld.get_location(room_location, player), And(*room_rules)) def set_skills_rules(logic: StardewLogic, multiworld: MultiWorld, player: int, content: StardewContent): @@ -176,12 +176,12 @@ def set_skills_rules(logic: StardewLogic, multiworld: MultiWorld, player: int, c for level, level_name in skill_progression.get_randomized_level_names_by_level(skill): rule = logic.skill.can_earn_level(skill.name, level) location = multiworld.get_location(level_name, player) - MultiWorldRules.set_rule(location, rule) + set_rule(location, rule) if skill_progression.is_mastery_randomized(skill): rule = logic.skill.can_earn_mastery(skill.name) location = multiworld.get_location(skill.mastery_name, player) - MultiWorldRules.set_rule(location, rule) + set_rule(location, rule) def set_entrance_rules(logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): @@ -339,20 +339,20 @@ def set_ginger_island_rules(logic: StardewLogic, multiworld, player, world_optio set_boat_repair_rules(logic, multiworld, player) set_island_parrot_rules(logic, multiworld, player) - MultiWorldRules.add_rule(multiworld.get_location("Open Professor Snail Cave", player), - logic.has(Bomb.cherry_bomb)) - MultiWorldRules.add_rule(multiworld.get_location("Complete Island Field Office", player), - logic.walnut.can_complete_field_office()) + set_rule(multiworld.get_location("Open Professor Snail Cave", player), + logic.has(Bomb.cherry_bomb)) + set_rule(multiworld.get_location("Complete Island Field Office", player), + logic.walnut.can_complete_field_office()) set_walnut_rules(logic, multiworld, player, world_options) def set_boat_repair_rules(logic: StardewLogic, multiworld, player): - MultiWorldRules.add_rule(multiworld.get_location("Repair Boat Hull", player), - logic.has(Material.hardwood)) - MultiWorldRules.add_rule(multiworld.get_location("Repair Boat Anchor", player), - logic.has(MetalBar.iridium)) - MultiWorldRules.add_rule(multiworld.get_location("Repair Ticket Machine", player), - logic.has(ArtisanGood.battery_pack)) + set_rule(multiworld.get_location("Repair Boat Hull", player), + logic.has(Material.hardwood)) + set_rule(multiworld.get_location("Repair Boat Anchor", player), + logic.has(MetalBar.iridium)) + set_rule(multiworld.get_location("Repair Ticket Machine", player), + logic.has(ArtisanGood.battery_pack)) def set_island_entrances_rules(logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): @@ -403,29 +403,29 @@ def set_island_parrot_rules(logic: StardewLogic, multiworld, player): has_5_walnut = logic.walnut.has_walnut(15) has_10_walnut = logic.walnut.has_walnut(40) has_20_walnut = logic.walnut.has_walnut(60) - MultiWorldRules.add_rule(multiworld.get_location("Leo's Parrot", player), - has_walnut) - MultiWorldRules.add_rule(multiworld.get_location("Island West Turtle", player), - has_10_walnut & logic.received("Island North Turtle")) - MultiWorldRules.add_rule(multiworld.get_location("Island Farmhouse", player), - has_20_walnut) - MultiWorldRules.add_rule(multiworld.get_location("Island Mailbox", player), - has_5_walnut & logic.received("Island Farmhouse")) - MultiWorldRules.add_rule(multiworld.get_location(Transportation.farm_obelisk, player), - has_20_walnut & logic.received("Island Mailbox")) - MultiWorldRules.add_rule(multiworld.get_location("Dig Site Bridge", player), - has_10_walnut & logic.received("Island West Turtle")) - MultiWorldRules.add_rule(multiworld.get_location("Island Trader", player), - has_10_walnut & logic.received("Island Farmhouse")) - MultiWorldRules.add_rule(multiworld.get_location("Volcano Bridge", player), - has_5_walnut & logic.received("Island West Turtle") & - logic.region.can_reach(Region.volcano_floor_10)) - MultiWorldRules.add_rule(multiworld.get_location("Volcano Exit Shortcut", player), - has_5_walnut & logic.received("Island West Turtle")) - MultiWorldRules.add_rule(multiworld.get_location("Island Resort", player), - has_20_walnut & logic.received("Island Farmhouse")) - MultiWorldRules.add_rule(multiworld.get_location(Transportation.parrot_express, player), - has_10_walnut) + set_rule(multiworld.get_location("Leo's Parrot", player), + has_walnut) + set_rule(multiworld.get_location("Island West Turtle", player), + has_10_walnut & logic.received("Island North Turtle")) + set_rule(multiworld.get_location("Island Farmhouse", player), + has_20_walnut) + set_rule(multiworld.get_location("Island Mailbox", player), + has_5_walnut & logic.received("Island Farmhouse")) + set_rule(multiworld.get_location(Transportation.farm_obelisk, player), + has_20_walnut & logic.received("Island Mailbox")) + set_rule(multiworld.get_location("Dig Site Bridge", player), + has_10_walnut & logic.received("Island West Turtle")) + set_rule(multiworld.get_location("Island Trader", player), + has_10_walnut & logic.received("Island Farmhouse")) + set_rule(multiworld.get_location("Volcano Bridge", player), + has_5_walnut & logic.received("Island West Turtle") & + logic.region.can_reach(Region.volcano_floor_10)) + set_rule(multiworld.get_location("Volcano Exit Shortcut", player), + has_5_walnut & logic.received("Island West Turtle")) + set_rule(multiworld.get_location("Island Resort", player), + has_20_walnut & logic.received("Island Farmhouse")) + set_rule(multiworld.get_location(Transportation.parrot_express, player), + has_10_walnut) def set_walnut_rules(logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): @@ -442,27 +442,27 @@ def set_walnut_puzzle_rules(logic: StardewLogic, multiworld, player, world_optio if WalnutsanityOptionName.puzzles not in world_options.walnutsanity: return - MultiWorldRules.add_rule(multiworld.get_location("Open Golden Coconut", player), logic.has(Geode.golden_coconut)) - MultiWorldRules.add_rule(multiworld.get_location("Banana Altar", player), logic.has(Fruit.banana)) - MultiWorldRules.add_rule(multiworld.get_location("Leo's Tree", player), logic.tool.has_tool(Tool.axe)) - MultiWorldRules.add_rule(multiworld.get_location("Gem Birds Shrine", player), logic.has(Mineral.amethyst) & logic.has(Mineral.aquamarine) & - logic.has(Mineral.emerald) & logic.has(Mineral.ruby) & logic.has(Mineral.topaz) & - logic.region.can_reach_all((Region.island_north, Region.island_west, Region.island_east, Region.island_south))) - MultiWorldRules.add_rule(multiworld.get_location("Gourmand Frog Melon", player), logic.has(Fruit.melon) & logic.region.can_reach(Region.island_west)) - MultiWorldRules.add_rule(multiworld.get_location("Gourmand Frog Wheat", player), logic.has(Vegetable.wheat) & - logic.region.can_reach(Region.island_west) & logic.region.can_reach_location("Gourmand Frog Melon")) - MultiWorldRules.add_rule(multiworld.get_location("Gourmand Frog Garlic", player), logic.has(Vegetable.garlic) & - logic.region.can_reach(Region.island_west) & logic.region.can_reach_location("Gourmand Frog Wheat")) - MultiWorldRules.add_rule(multiworld.get_location("Whack A Mole", player), logic.tool.has_tool(Tool.watering_can, ToolMaterial.iridium)) - MultiWorldRules.add_rule(multiworld.get_location("Complete Large Animal Collection", player), logic.walnut.can_complete_large_animal_collection()) - MultiWorldRules.add_rule(multiworld.get_location("Complete Snake Collection", player), logic.walnut.can_complete_snake_collection()) - MultiWorldRules.add_rule(multiworld.get_location("Complete Mummified Frog Collection", player), logic.walnut.can_complete_frog_collection()) - MultiWorldRules.add_rule(multiworld.get_location("Complete Mummified Bat Collection", player), logic.walnut.can_complete_bat_collection()) - MultiWorldRules.add_rule(multiworld.get_location("Purple Flowers Island Survey", player), logic.walnut.can_start_field_office) - MultiWorldRules.add_rule(multiworld.get_location("Purple Starfish Island Survey", player), logic.walnut.can_start_field_office) - MultiWorldRules.add_rule(multiworld.get_location("Protruding Tree Walnut", player), logic.combat.has_slingshot) - MultiWorldRules.add_rule(multiworld.get_location("Starfish Tide Pool", player), logic.tool.has_fishing_rod(1)) - MultiWorldRules.add_rule(multiworld.get_location("Mermaid Song", player), logic.has(Furniture.flute_block)) + set_rule(multiworld.get_location("Open Golden Coconut", player), logic.has(Geode.golden_coconut)) + set_rule(multiworld.get_location("Banana Altar", player), logic.has(Fruit.banana)) + set_rule(multiworld.get_location("Leo's Tree", player), logic.tool.has_tool(Tool.axe)) + set_rule(multiworld.get_location("Gem Birds Shrine", player), logic.has(Mineral.amethyst) & logic.has(Mineral.aquamarine) & + logic.has(Mineral.emerald) & logic.has(Mineral.ruby) & logic.has(Mineral.topaz) & + logic.region.can_reach_all((Region.island_north, Region.island_west, Region.island_east, Region.island_south))) + set_rule(multiworld.get_location("Gourmand Frog Melon", player), logic.has(Fruit.melon) & logic.region.can_reach(Region.island_west)) + set_rule(multiworld.get_location("Gourmand Frog Wheat", player), logic.has(Vegetable.wheat) & + logic.region.can_reach(Region.island_west) & logic.region.can_reach_location("Gourmand Frog Melon")) + set_rule(multiworld.get_location("Gourmand Frog Garlic", player), logic.has(Vegetable.garlic) & + logic.region.can_reach(Region.island_west) & logic.region.can_reach_location("Gourmand Frog Wheat")) + set_rule(multiworld.get_location("Whack A Mole", player), logic.tool.has_tool(Tool.watering_can, ToolMaterial.iridium)) + set_rule(multiworld.get_location("Complete Large Animal Collection", player), logic.walnut.can_complete_large_animal_collection()) + set_rule(multiworld.get_location("Complete Snake Collection", player), logic.walnut.can_complete_snake_collection()) + set_rule(multiworld.get_location("Complete Mummified Frog Collection", player), logic.walnut.can_complete_frog_collection()) + set_rule(multiworld.get_location("Complete Mummified Bat Collection", player), logic.walnut.can_complete_bat_collection()) + set_rule(multiworld.get_location("Purple Flowers Island Survey", player), logic.walnut.can_start_field_office) + set_rule(multiworld.get_location("Purple Starfish Island Survey", player), logic.walnut.can_start_field_office) + set_rule(multiworld.get_location("Protruding Tree Walnut", player), logic.combat.has_slingshot) + set_rule(multiworld.get_location("Starfish Tide Pool", player), logic.tool.has_fishing_rod(1)) + set_rule(multiworld.get_location("Mermaid Song", player), logic.has(Furniture.flute_block)) def set_walnut_bushes_rules(logic, multiworld, player, world_options): @@ -482,20 +482,20 @@ def set_walnut_dig_spot_rules(logic, multiworld, player, world_options): rule = rule & logic.has(Forageable.journal_scrap) if "Starfish Diamond" in dig_spot_walnut.name: rule = rule & logic.tool.has_tool(Tool.pickaxe, ToolMaterial.iron) - MultiWorldRules.set_rule(multiworld.get_location(dig_spot_walnut.name, player), rule) + set_rule(multiworld.get_location(dig_spot_walnut.name, player), rule) def set_walnut_repeatable_rules(logic, multiworld, player, world_options): if WalnutsanityOptionName.repeatables not in world_options.walnutsanity: return for i in range(1, 6): - MultiWorldRules.set_rule(multiworld.get_location(f"Fishing Walnut {i}", player), logic.tool.has_fishing_rod(1)) - MultiWorldRules.set_rule(multiworld.get_location(f"Harvesting Walnut {i}", player), logic.skill.can_get_farming_xp) - MultiWorldRules.set_rule(multiworld.get_location(f"Mussel Node Walnut {i}", player), logic.tool.has_tool(Tool.pickaxe)) - MultiWorldRules.set_rule(multiworld.get_location(f"Volcano Rocks Walnut {i}", player), logic.tool.has_tool(Tool.pickaxe)) - MultiWorldRules.set_rule(multiworld.get_location(f"Volcano Monsters Walnut {i}", player), logic.combat.has_galaxy_weapon) - MultiWorldRules.set_rule(multiworld.get_location(f"Volcano Crates Walnut {i}", player), logic.combat.has_any_weapon) - MultiWorldRules.set_rule(multiworld.get_location(f"Tiger Slime Walnut", player), logic.monster.can_kill(Monster.tiger_slime)) + set_rule(multiworld.get_location(f"Fishing Walnut {i}", player), logic.tool.has_fishing_rod(1)) + set_rule(multiworld.get_location(f"Harvesting Walnut {i}", player), logic.skill.can_get_farming_xp) + set_rule(multiworld.get_location(f"Mussel Node Walnut {i}", player), logic.tool.has_tool(Tool.pickaxe)) + set_rule(multiworld.get_location(f"Volcano Rocks Walnut {i}", player), logic.tool.has_tool(Tool.pickaxe)) + set_rule(multiworld.get_location(f"Volcano Monsters Walnut {i}", player), logic.combat.has_galaxy_weapon) + set_rule(multiworld.get_location(f"Volcano Crates Walnut {i}", player), logic.combat.has_any_weapon) + set_rule(multiworld.get_location(f"Tiger Slime Walnut", player), logic.monster.can_kill(Monster.tiger_slime)) def set_cropsanity_rules(logic: StardewLogic, multiworld, player, world_content: StardewContent): @@ -505,7 +505,7 @@ def set_cropsanity_rules(logic: StardewLogic, multiworld, player, world_content: for item in world_content.find_tagged_items(ItemTag.CROPSANITY): location = world_content.features.cropsanity.to_location_name(item.name) harvest_sources = (source for source in item.sources if isinstance(source, (HarvestFruitTreeSource, HarvestCropSource))) - MultiWorldRules.set_rule(multiworld.get_location(location, player), logic.source.has_access_to_any(harvest_sources)) + set_rule(multiworld.get_location(location, player), logic.source.has_access_to_any(harvest_sources)) def set_story_quests_rules(all_location_names: Set[str], logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): @@ -513,8 +513,8 @@ def set_story_quests_rules(all_location_names: Set[str], logic: StardewLogic, mu return for quest in locations.locations_by_tag[LocationTags.STORY_QUEST]: if quest.name in all_location_names and (quest.mod_name is None or quest.mod_name in world_options.mods): - MultiWorldRules.set_rule(multiworld.get_location(quest.name, player), - logic.registry.quest_rules[quest.name]) + set_rule(multiworld.get_location(quest.name, player), + logic.registry.quest_rules[quest.name]) def set_special_order_rules(all_location_names: Set[str], logic: StardewLogic, multiworld, player, @@ -524,7 +524,7 @@ def set_special_order_rules(all_location_names: Set[str], logic: StardewLogic, m for board_order in locations.locations_by_tag[LocationTags.SPECIAL_ORDER_BOARD]: if board_order.name in all_location_names: order_rule = board_rule & logic.registry.special_order_rules[board_order.name] - MultiWorldRules.set_rule(multiworld.get_location(board_order.name, player), order_rule) + set_rule(multiworld.get_location(board_order.name, player), order_rule) if world_options.exclude_ginger_island == ExcludeGingerIsland.option_true: return @@ -533,7 +533,7 @@ def set_special_order_rules(all_location_names: Set[str], logic: StardewLogic, m for qi_order in locations.locations_by_tag[LocationTags.SPECIAL_ORDER_QI]: if qi_order.name in all_location_names: order_rule = qi_rule & logic.registry.special_order_rules[qi_order.name] - MultiWorldRules.set_rule(multiworld.get_location(qi_order.name, player), order_rule) + set_rule(multiworld.get_location(qi_order.name, player), order_rule) help_wanted_prefix = "Help Wanted:" @@ -565,22 +565,22 @@ def set_help_wanted_quests_rules(logic: StardewLogic, multiworld, player, world_ def set_help_wanted_delivery_rule(multiworld, player, month_rule, quest_number): location_name = f"{help_wanted_prefix} {item_delivery} {quest_number}" - MultiWorldRules.set_rule(multiworld.get_location(location_name, player), month_rule) + set_rule(multiworld.get_location(location_name, player), month_rule) def set_help_wanted_gathering_rule(multiworld, player, month_rule, quest_number): location_name = f"{help_wanted_prefix} {gathering} {quest_number}" - MultiWorldRules.set_rule(multiworld.get_location(location_name, player), month_rule) + set_rule(multiworld.get_location(location_name, player), month_rule) def set_help_wanted_fishing_rule(multiworld, player, month_rule, quest_number): location_name = f"{help_wanted_prefix} {fishing} {quest_number}" - MultiWorldRules.set_rule(multiworld.get_location(location_name, player), month_rule) + set_rule(multiworld.get_location(location_name, player), month_rule) def set_help_wanted_slay_monsters_rule(multiworld, player, month_rule, quest_number): location_name = f"{help_wanted_prefix} {slay_monsters} {quest_number}" - MultiWorldRules.set_rule(multiworld.get_location(location_name, player), month_rule) + set_rule(multiworld.get_location(location_name, player), month_rule) def set_fishsanity_rules(all_location_names: Set[str], logic: StardewLogic, multiworld: MultiWorld, player: int): @@ -588,8 +588,8 @@ def set_fishsanity_rules(all_location_names: Set[str], logic: StardewLogic, mult for fish_location in locations.locations_by_tag[LocationTags.FISHSANITY]: if fish_location.name in all_location_names: fish_name = fish_location.name[len(fish_prefix):] - MultiWorldRules.set_rule(multiworld.get_location(fish_location.name, player), - logic.has(fish_name)) + set_rule(multiworld.get_location(fish_location.name, player), + logic.has(fish_name)) def set_museumsanity_rules(all_location_names: Set[str], logic: StardewLogic, multiworld: MultiWorld, player: int, @@ -612,8 +612,8 @@ def set_museum_individual_donations_rules(all_location_names, logic: StardewLogi donation_name = museum_location.name[len(museum_prefix):] required_detectors = counter * 3 // number_donations rule = logic.museum.can_find_museum_item(all_museum_items_by_name[donation_name]) & logic.received(Wallet.metal_detector, required_detectors) - MultiWorldRules.set_rule(multiworld.get_location(museum_location.name, player), - rule) + set_rule(multiworld.get_location(museum_location.name, player), + rule) counter += 1 @@ -643,7 +643,7 @@ def set_museum_milestone_rule(logic: StardewLogic, multiworld: MultiWorld, museu rule = logic.museum.can_find_museum_item(Artifact.ancient_seed) & logic.received(metal_detector, 2) if rule is None: return - MultiWorldRules.set_rule(multiworld.get_location(museum_milestone.name, player), rule) + set_rule(multiworld.get_location(museum_milestone.name, player), rule) def get_museum_item_count_rule(logic: StardewLogic, suffix, milestone_name, accepted_items, donation_func): @@ -656,14 +656,14 @@ def get_museum_item_count_rule(logic: StardewLogic, suffix, milestone_name, acce def set_backpack_rules(logic: StardewLogic, multiworld: MultiWorld, player: int, world_options: StardewValleyOptions): if world_options.backpack_progression != BackpackProgression.option_vanilla: - MultiWorldRules.set_rule(multiworld.get_location("Large Pack", player), - logic.money.can_spend(2000)) - MultiWorldRules.set_rule(multiworld.get_location("Deluxe Pack", player), - (logic.money.can_spend(10000) & logic.received("Progressive Backpack"))) + set_rule(multiworld.get_location("Large Pack", player), + logic.money.can_spend(2000)) + set_rule(multiworld.get_location("Deluxe Pack", player), + (logic.money.can_spend(10000) & logic.received("Progressive Backpack"))) if ModNames.big_backpack in world_options.mods: - MultiWorldRules.set_rule(multiworld.get_location("Premium Pack", player), - (logic.money.can_spend(150000) & - logic.received("Progressive Backpack", 2))) + set_rule(multiworld.get_location("Premium Pack", player), + (logic.money.can_spend(150000) & + logic.received("Progressive Backpack", 2))) def set_festival_rules(all_location_names: Set[str], logic: StardewLogic, multiworld, player): @@ -672,8 +672,8 @@ def set_festival_rules(all_location_names: Set[str], logic: StardewLogic, multiw festival_locations.extend(locations.locations_by_tag[LocationTags.FESTIVAL_HARD]) for festival in festival_locations: if festival.name in all_location_names: - MultiWorldRules.set_rule(multiworld.get_location(festival.name, player), - logic.registry.festival_rules[festival.name]) + set_rule(multiworld.get_location(festival.name, player), + logic.registry.festival_rules[festival.name]) monster_eradication_prefix = "Monster Eradication: " @@ -705,7 +705,7 @@ def set_monstersanity_monster_rules(all_location_names: Set[str], logic: Stardew rule = logic.monster.can_kill_many(logic.monster.all_monsters_by_name[monster_name]) else: rule = logic.monster.can_kill(logic.monster.all_monsters_by_name[monster_name]) - MultiWorldRules.set_rule(location, rule) + set_rule(location, rule) def set_monstersanity_progressive_category_rules(all_location_names: Set[str], logic: StardewLogic, multiworld, player): @@ -732,7 +732,7 @@ def set_monstersanity_progressive_category_rule(all_location_names: Set[str], lo rule = logic.monster.can_kill_any(logic.monster.all_monsters_by_category[monster_category], goal_index + 1) else: rule = logic.monster.can_kill_any(logic.monster.all_monsters_by_category[monster_category], goal_index * 2) - MultiWorldRules.set_rule(location, rule) + set_rule(location, rule) def get_monster_eradication_number(location_name, monster_category) -> int: @@ -753,7 +753,7 @@ def set_monstersanity_category_rules(all_location_names: Set[str], logic: Starde rule = logic.monster.can_kill_any(logic.monster.all_monsters_by_category[monster_category]) else: rule = logic.monster.can_kill_any(logic.monster.all_monsters_by_category[monster_category], MAX_MONTHS) - MultiWorldRules.set_rule(location, rule) + set_rule(location, rule) def set_shipsanity_rules(all_location_names: Set[str], logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): @@ -766,7 +766,7 @@ def set_shipsanity_rules(all_location_names: Set[str], logic: StardewLogic, mult if location.name not in all_location_names: continue item_to_ship = location.name[len(shipsanity_prefix):] - MultiWorldRules.set_rule(multiworld.get_location(location.name, player), logic.shipping.can_ship(item_to_ship)) + set_rule(multiworld.get_location(location.name, player), logic.shipping.can_ship(item_to_ship)) def set_cooksanity_rules(all_location_names: Set[str], logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): @@ -781,7 +781,7 @@ def set_cooksanity_rules(all_location_names: Set[str], logic: StardewLogic, mult recipe_name = location.name[len(cooksanity_prefix):] recipe = all_cooking_recipes_by_name[recipe_name] cook_rule = logic.cooking.can_cook(recipe) - MultiWorldRules.set_rule(multiworld.get_location(location.name, player), cook_rule) + set_rule(multiworld.get_location(location.name, player), cook_rule) def set_chefsanity_rules(all_location_names: Set[str], logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): @@ -796,7 +796,7 @@ def set_chefsanity_rules(all_location_names: Set[str], logic: StardewLogic, mult recipe_name = location.name[:-len(chefsanity_suffix)] recipe = all_cooking_recipes_by_name[recipe_name] learn_rule = logic.cooking.can_learn_recipe(recipe.source) - MultiWorldRules.set_rule(multiworld.get_location(location.name, player), learn_rule) + set_rule(multiworld.get_location(location.name, player), learn_rule) def set_craftsanity_rules(all_location_names: Set[str], logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): @@ -817,7 +817,7 @@ def set_craftsanity_rules(all_location_names: Set[str], logic: StardewLogic, mul recipe_name = location.name[len(craft_prefix):] recipe = all_crafting_recipes_by_name[recipe_name] craft_rule = logic.crafting.can_craft(recipe) - MultiWorldRules.set_rule(multiworld.get_location(location.name, player), craft_rule) + set_rule(multiworld.get_location(location.name, player), craft_rule) def set_booksanity_rules(logic: StardewLogic, multiworld, player, content: StardewContent): @@ -827,12 +827,12 @@ def set_booksanity_rules(logic: StardewLogic, multiworld, player, content: Stard for book in content.find_tagged_items(ItemTag.BOOK): if booksanity.is_included(book): - MultiWorldRules.set_rule(multiworld.get_location(booksanity.to_location_name(book.name), player), logic.has(book.name)) + set_rule(multiworld.get_location(booksanity.to_location_name(book.name), player), logic.has(book.name)) for i, book in enumerate(booksanity.get_randomized_lost_books()): if i <= 0: continue - MultiWorldRules.set_rule(multiworld.get_location(booksanity.to_location_name(book), player), logic.received(booksanity.progressive_lost_book, i)) + set_rule(multiworld.get_location(booksanity.to_location_name(book), player), logic.received(booksanity.progressive_lost_book, i)) def set_traveling_merchant_day_rules(logic: StardewLogic, multiworld: MultiWorld, player: int): @@ -856,102 +856,102 @@ def set_arcade_machine_rules(logic: StardewLogic, multiworld: MultiWorld, player set_entrance_rule(multiworld, player, Entrance.play_journey_of_the_prairie_king, logic.has("JotPK Small Buff")) set_entrance_rule(multiworld, player, Entrance.reach_jotpk_world_2, logic.has("JotPK Medium Buff")) set_entrance_rule(multiworld, player, Entrance.reach_jotpk_world_3, logic.has("JotPK Big Buff")) - MultiWorldRules.add_rule(multiworld.get_location("Journey of the Prairie King Victory", player), - logic.has("JotPK Max Buff")) + set_rule(multiworld.get_location("Journey of the Prairie King Victory", player), + logic.has("JotPK Max Buff")) def set_friendsanity_rules(logic: StardewLogic, multiworld: MultiWorld, player: int, content: StardewContent): if not content.features.friendsanity.is_enabled: return - MultiWorldRules.add_rule(multiworld.get_location("Spouse Stardrop", player), - logic.relationship.has_hearts_with_any_bachelor(13)) - MultiWorldRules.add_rule(multiworld.get_location("Have a Baby", player), - logic.relationship.can_reproduce(1)) - MultiWorldRules.add_rule(multiworld.get_location("Have Another Baby", player), - logic.relationship.can_reproduce(2)) + set_rule(multiworld.get_location("Spouse Stardrop", player), + logic.relationship.has_hearts_with_any_bachelor(13)) + set_rule(multiworld.get_location("Have a Baby", player), + logic.relationship.can_reproduce(1)) + set_rule(multiworld.get_location("Have Another Baby", player), + logic.relationship.can_reproduce(2)) for villager in content.villagers.values(): for heart in content.features.friendsanity.get_randomized_hearts(villager): rule = logic.relationship.can_earn_relationship(villager.name, heart) location_name = friendsanity.to_location_name(villager.name, heart) - MultiWorldRules.set_rule(multiworld.get_location(location_name, player), rule) + set_rule(multiworld.get_location(location_name, player), rule) for heart in content.features.friendsanity.get_pet_randomized_hearts(): rule = logic.pet.can_befriend_pet(heart) location_name = friendsanity.to_location_name(NPC.pet, heart) - MultiWorldRules.set_rule(multiworld.get_location(location_name, player), rule) + set_rule(multiworld.get_location(location_name, player), rule) def set_deepwoods_rules(logic: StardewLogic, multiworld: MultiWorld, player: int, world_options: StardewValleyOptions): if ModNames.deepwoods in world_options.mods: - MultiWorldRules.add_rule(multiworld.get_location("Breaking Up Deep Woods Gingerbread House", player), - logic.tool.has_tool(Tool.axe, "Gold")) - MultiWorldRules.add_rule(multiworld.get_location("Chop Down a Deep Woods Iridium Tree", player), - logic.tool.has_tool(Tool.axe, "Iridium")) + set_rule(multiworld.get_location("Breaking Up Deep Woods Gingerbread House", player), + logic.tool.has_tool(Tool.axe, "Gold")) + set_rule(multiworld.get_location("Chop Down a Deep Woods Iridium Tree", player), + logic.tool.has_tool(Tool.axe, "Iridium")) set_entrance_rule(multiworld, player, DeepWoodsEntrance.use_woods_obelisk, logic.received("Woods Obelisk")) for depth in range(10, 100 + 10, 10): set_entrance_rule(multiworld, player, move_to_woods_depth(depth), logic.mod.deepwoods.can_chop_to_depth(depth)) - MultiWorldRules.add_rule(multiworld.get_location("The Sword in the Stone", player), - logic.mod.deepwoods.can_pull_sword() & logic.mod.deepwoods.can_chop_to_depth(100)) + set_rule(multiworld.get_location("The Sword in the Stone", player), + logic.mod.deepwoods.can_pull_sword() & logic.mod.deepwoods.can_chop_to_depth(100)) def set_magic_spell_rules(logic: StardewLogic, multiworld: MultiWorld, player: int, world_options: StardewValleyOptions): if ModNames.magic not in world_options.mods: return - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Clear Debris", player), - (logic.tool.has_tool("Axe", "Basic") | logic.tool.has_tool("Pickaxe", "Basic"))) - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Till", player), - logic.tool.has_tool("Hoe", "Basic")) - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Water", player), - logic.tool.has_tool("Watering Can", "Basic")) - MultiWorldRules.add_rule(multiworld.get_location("Analyze All Toil School Locations", player), - (logic.tool.has_tool("Watering Can", "Basic") & logic.tool.has_tool("Hoe", "Basic") - & (logic.tool.has_tool("Axe", "Basic") | logic.tool.has_tool("Pickaxe", "Basic")))) + set_rule(multiworld.get_location("Analyze: Clear Debris", player), + (logic.tool.has_tool("Axe", "Basic") | logic.tool.has_tool("Pickaxe", "Basic"))) + set_rule(multiworld.get_location("Analyze: Till", player), + logic.tool.has_tool("Hoe", "Basic")) + set_rule(multiworld.get_location("Analyze: Water", player), + logic.tool.has_tool("Watering Can", "Basic")) + set_rule(multiworld.get_location("Analyze All Toil School Locations", player), + (logic.tool.has_tool("Watering Can", "Basic") & logic.tool.has_tool("Hoe", "Basic") + & (logic.tool.has_tool("Axe", "Basic") | logic.tool.has_tool("Pickaxe", "Basic")))) # Do I *want* to add boots into logic when you get them even in vanilla without effort? idk - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Evac", player), - logic.ability.can_mine_perfectly()) - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Haste", player), - logic.has("Coffee")) - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Heal", player), - logic.has("Life Elixir")) - MultiWorldRules.add_rule(multiworld.get_location("Analyze All Life School Locations", player), - (logic.has("Coffee") & logic.has("Life Elixir") - & logic.ability.can_mine_perfectly())) - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Descend", player), - logic.region.can_reach(Region.mines)) - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Fireball", player), - logic.has("Fire Quartz")) - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Frostbolt", player), - logic.region.can_reach(Region.mines_floor_60) & logic.skill.can_fish(difficulty=85)) - MultiWorldRules.add_rule(multiworld.get_location("Analyze All Elemental School Locations", player), - logic.has("Fire Quartz") & logic.region.can_reach(Region.mines_floor_60) & logic.skill.can_fish(difficulty=85)) - # MultiWorldRules.add_rule(multiworld.get_location("Analyze: Lantern", player),) - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Tendrils", player), - logic.region.can_reach(Region.farm)) - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Shockwave", player), - logic.has("Earth Crystal")) - MultiWorldRules.add_rule(multiworld.get_location("Analyze All Nature School Locations", player), - (logic.has("Earth Crystal") & logic.region.can_reach("Farm"))), - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Meteor", player), - (logic.region.can_reach(Region.farm) & logic.time.has_lived_months(12))), - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Lucksteal", player), - logic.region.can_reach(Region.witch_hut)) - MultiWorldRules.add_rule(multiworld.get_location("Analyze: Bloodmana", player), - logic.region.can_reach(Region.mines_floor_100)) - MultiWorldRules.add_rule(multiworld.get_location("Analyze All Eldritch School Locations", player), - (logic.region.can_reach(Region.witch_hut) & - logic.region.can_reach(Region.mines_floor_100) & - logic.region.can_reach(Region.farm) & logic.time.has_lived_months(12))) - MultiWorldRules.add_rule(multiworld.get_location("Analyze Every Magic School Location", player), - (logic.tool.has_tool("Watering Can", "Basic") & logic.tool.has_tool("Hoe", "Basic") - & (logic.tool.has_tool("Axe", "Basic") | logic.tool.has_tool("Pickaxe", "Basic")) & - logic.has("Coffee") & logic.has("Life Elixir") - & logic.ability.can_mine_perfectly() & logic.has("Earth Crystal") & - logic.has("Fire Quartz") & logic.skill.can_fish(difficulty=85) & - logic.region.can_reach(Region.witch_hut) & - logic.region.can_reach(Region.mines_floor_100) & - logic.region.can_reach(Region.farm) & logic.time.has_lived_months(12))) + set_rule(multiworld.get_location("Analyze: Evac", player), + logic.ability.can_mine_perfectly()) + set_rule(multiworld.get_location("Analyze: Haste", player), + logic.has("Coffee")) + set_rule(multiworld.get_location("Analyze: Heal", player), + logic.has("Life Elixir")) + set_rule(multiworld.get_location("Analyze All Life School Locations", player), + (logic.has("Coffee") & logic.has("Life Elixir") + & logic.ability.can_mine_perfectly())) + set_rule(multiworld.get_location("Analyze: Descend", player), + logic.region.can_reach(Region.mines)) + set_rule(multiworld.get_location("Analyze: Fireball", player), + logic.has("Fire Quartz")) + set_rule(multiworld.get_location("Analyze: Frostbolt", player), + logic.region.can_reach(Region.mines_floor_60) & logic.skill.can_fish(difficulty=85)) + set_rule(multiworld.get_location("Analyze All Elemental School Locations", player), + logic.has("Fire Quartz") & logic.region.can_reach(Region.mines_floor_60) & logic.skill.can_fish(difficulty=85)) + # set_rule(multiworld.get_location("Analyze: Lantern", player),) + set_rule(multiworld.get_location("Analyze: Tendrils", player), + logic.region.can_reach(Region.farm)) + set_rule(multiworld.get_location("Analyze: Shockwave", player), + logic.has("Earth Crystal")) + set_rule(multiworld.get_location("Analyze All Nature School Locations", player), + (logic.has("Earth Crystal") & logic.region.can_reach("Farm"))), + set_rule(multiworld.get_location("Analyze: Meteor", player), + (logic.region.can_reach(Region.farm) & logic.time.has_lived_months(12))), + set_rule(multiworld.get_location("Analyze: Lucksteal", player), + logic.region.can_reach(Region.witch_hut)) + set_rule(multiworld.get_location("Analyze: Bloodmana", player), + logic.region.can_reach(Region.mines_floor_100)) + set_rule(multiworld.get_location("Analyze All Eldritch School Locations", player), + (logic.region.can_reach(Region.witch_hut) & + logic.region.can_reach(Region.mines_floor_100) & + logic.region.can_reach(Region.farm) & logic.time.has_lived_months(12))) + set_rule(multiworld.get_location("Analyze Every Magic School Location", player), + (logic.tool.has_tool("Watering Can", "Basic") & logic.tool.has_tool("Hoe", "Basic") + & (logic.tool.has_tool("Axe", "Basic") | logic.tool.has_tool("Pickaxe", "Basic")) & + logic.has("Coffee") & logic.has("Life Elixir") + & logic.ability.can_mine_perfectly() & logic.has("Earth Crystal") & + logic.has("Fire Quartz") & logic.skill.can_fish(difficulty=85) & + logic.region.can_reach(Region.witch_hut) & + logic.region.can_reach(Region.mines_floor_100) & + logic.region.can_reach(Region.farm) & logic.time.has_lived_months(12))) def set_sve_rules(logic: StardewLogic, multiworld: MultiWorld, player: int, world_options: StardewValleyOptions): @@ -980,8 +980,8 @@ def set_sve_rules(logic: StardewLogic, multiworld: MultiWorld, player: int, worl set_entrance_rule(multiworld, player, SVEEntrance.to_aurora_basement, logic.mod.quest.has_completed_aurora_vineyard_bundle()) logic.mod.sve.initialize_rules() for location in logic.registry.sve_location_rules: - MultiWorldRules.set_rule(multiworld.get_location(location, player), - logic.registry.sve_location_rules[location]) + set_rule(multiworld.get_location(location, player), + logic.registry.sve_location_rules[location]) set_sve_ginger_island_rules(logic, multiworld, player, world_options) set_boarding_house_rules(logic, multiworld, player, world_options) @@ -1010,7 +1010,7 @@ def set_entrance_rule(multiworld, player, entrance: str, rule: StardewRule): logger.debug(f"Registering indirect condition for {region} -> {entrance}") multiworld.register_indirect_condition(multiworld.get_region(region, player), multiworld.get_entrance(entrance, player)) - MultiWorldRules.set_rule(multiworld.get_entrance(entrance, player), rule) + set_rule(multiworld.get_entrance(entrance, player), rule) except KeyError as ex: logger.error(f"""Failed to evaluate indirect connection in: {explain(rule, CollectionState(multiworld))}""") raise ex From 8755d5cbc099f79bb347da07cf37d7c5e983ddc4 Mon Sep 17 00:00:00 2001 From: Nicholas Brochu Date: Thu, 24 Apr 2025 19:42:42 -0400 Subject: [PATCH 0367/1218] Remove Game: Zork Grand Inquisitor (#4884) * remove zork grand inquisitor * add apworld to inno setup installdelete --- README.md | 1 - docs/CODEOWNERS | 4 - worlds/zork_grand_inquisitor/LICENSE | 21 - worlds/zork_grand_inquisitor/__init__.py | 17 - worlds/zork_grand_inquisitor/client.py | 188 -- worlds/zork_grand_inquisitor/data/__init__.py | 0 .../data/entrance_rule_data.py | 419 --- .../zork_grand_inquisitor/data/item_data.py | 792 ----- .../data/location_data.py | 1535 --------- ...missable_location_grant_conditions_data.py | 200 -- .../zork_grand_inquisitor/data/region_data.py | 183 -- worlds/zork_grand_inquisitor/data_funcs.py | 247 -- .../docs/en_Zork Grand Inquisitor.md | 102 - worlds/zork_grand_inquisitor/docs/setup_en.md | 42 - worlds/zork_grand_inquisitor/enums.py | 350 -- .../zork_grand_inquisitor/game_controller.py | 1388 -------- .../game_state_manager.py | 370 --- worlds/zork_grand_inquisitor/options.py | 61 - worlds/zork_grand_inquisitor/requirements.txt | 1 - worlds/zork_grand_inquisitor/test/__init__.py | 5 - .../zork_grand_inquisitor/test/test_access.py | 2927 ----------------- .../test/test_data_funcs.py | 132 - .../test/test_locations.py | 49 - worlds/zork_grand_inquisitor/world.py | 205 -- 24 files changed, 9239 deletions(-) delete mode 100644 worlds/zork_grand_inquisitor/LICENSE delete mode 100644 worlds/zork_grand_inquisitor/__init__.py delete mode 100644 worlds/zork_grand_inquisitor/client.py delete mode 100644 worlds/zork_grand_inquisitor/data/__init__.py delete mode 100644 worlds/zork_grand_inquisitor/data/entrance_rule_data.py delete mode 100644 worlds/zork_grand_inquisitor/data/item_data.py delete mode 100644 worlds/zork_grand_inquisitor/data/location_data.py delete mode 100644 worlds/zork_grand_inquisitor/data/missable_location_grant_conditions_data.py delete mode 100644 worlds/zork_grand_inquisitor/data/region_data.py delete mode 100644 worlds/zork_grand_inquisitor/data_funcs.py delete mode 100644 worlds/zork_grand_inquisitor/docs/en_Zork Grand Inquisitor.md delete mode 100644 worlds/zork_grand_inquisitor/docs/setup_en.md delete mode 100644 worlds/zork_grand_inquisitor/enums.py delete mode 100644 worlds/zork_grand_inquisitor/game_controller.py delete mode 100644 worlds/zork_grand_inquisitor/game_state_manager.py delete mode 100644 worlds/zork_grand_inquisitor/options.py delete mode 100644 worlds/zork_grand_inquisitor/requirements.txt delete mode 100644 worlds/zork_grand_inquisitor/test/__init__.py delete mode 100644 worlds/zork_grand_inquisitor/test/test_access.py delete mode 100644 worlds/zork_grand_inquisitor/test/test_data_funcs.py delete mode 100644 worlds/zork_grand_inquisitor/test/test_locations.py delete mode 100644 worlds/zork_grand_inquisitor/world.py diff --git a/README.md b/README.md index 5e14ef5de34e..83fdeea61105 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,6 @@ Currently, the following games are supported: * TUNIC * Kirby's Dream Land 3 * Celeste 64 -* Zork Grand Inquisitor * Castlevania 64 * A Short Hike * Yoshi's Island diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 29de6bbfb627..88b5060dcc61 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -232,10 +232,6 @@ # Zillion /worlds/zillion/ @beauxq -# Zork Grand Inquisitor -/worlds/zork_grand_inquisitor/ @nbrochu - - ## Active Unmaintained Worlds # The following worlds in this repo are currently unmaintained, but currently still work in core. If any update breaks diff --git a/worlds/zork_grand_inquisitor/LICENSE b/worlds/zork_grand_inquisitor/LICENSE deleted file mode 100644 index a94ca6bf9177..000000000000 --- a/worlds/zork_grand_inquisitor/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Serpent.AI - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/worlds/zork_grand_inquisitor/__init__.py b/worlds/zork_grand_inquisitor/__init__.py deleted file mode 100644 index 791f41dd00a2..000000000000 --- a/worlds/zork_grand_inquisitor/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -import worlds.LauncherComponents as LauncherComponents - -from .world import ZorkGrandInquisitorWorld - - -def launch_client() -> None: - from .client import main - LauncherComponents.launch(main, name="ZorkGrandInquisitorClient") - - -LauncherComponents.components.append( - LauncherComponents.Component( - "Zork Grand Inquisitor Client", - func=launch_client, - component_type=LauncherComponents.Type.CLIENT - ) -) diff --git a/worlds/zork_grand_inquisitor/client.py b/worlds/zork_grand_inquisitor/client.py deleted file mode 100644 index 8b8d7d3ebf58..000000000000 --- a/worlds/zork_grand_inquisitor/client.py +++ /dev/null @@ -1,188 +0,0 @@ -import asyncio - -import CommonClient -import NetUtils -import Utils - -from typing import Any, Dict, List, Optional, Set, Tuple - -from .data_funcs import item_names_to_id, location_names_to_id, id_to_items, id_to_locations, id_to_goals -from .enums import ZorkGrandInquisitorItems, ZorkGrandInquisitorLocations -from .game_controller import GameController - - -class ZorkGrandInquisitorCommandProcessor(CommonClient.ClientCommandProcessor): - def _cmd_zork(self) -> None: - """Attach to an open Zork Grand Inquisitor process.""" - result: bool = self.ctx.game_controller.open_process_handle() - - if result: - self.ctx.process_attached_at_least_once = True - self.output("Successfully attached to Zork Grand Inquisitor process.") - else: - self.output("Failed to attach to Zork Grand Inquisitor process.") - - def _cmd_brog(self) -> None: - """List received Brog items.""" - self.ctx.game_controller.list_received_brog_items() - - def _cmd_griff(self) -> None: - """List received Griff items.""" - self.ctx.game_controller.list_received_griff_items() - - def _cmd_lucy(self) -> None: - """List received Lucy items.""" - self.ctx.game_controller.list_received_lucy_items() - - def _cmd_hotspots(self) -> None: - """List received Hotspots.""" - self.ctx.game_controller.list_received_hotspots() - - -class ZorkGrandInquisitorContext(CommonClient.CommonContext): - tags: Set[str] = {"AP"} - game: str = "Zork Grand Inquisitor" - command_processor: CommonClient.ClientCommandProcessor = ZorkGrandInquisitorCommandProcessor - items_handling: int = 0b111 - want_slot_data: bool = True - - item_name_to_id: Dict[str, int] = item_names_to_id() - location_name_to_id: Dict[str, int] = location_names_to_id() - - id_to_items: Dict[int, ZorkGrandInquisitorItems] = id_to_items() - id_to_locations: Dict[int, ZorkGrandInquisitorLocations] = id_to_locations() - - game_controller: GameController - - controller_task: Optional[asyncio.Task] - - process_attached_at_least_once: bool - can_display_process_message: bool - - def __init__(self, server_address: Optional[str], password: Optional[str]) -> None: - super().__init__(server_address, password) - - self.game_controller = GameController(logger=CommonClient.logger) - - self.controller_task = None - - self.process_attached_at_least_once = False - self.can_display_process_message = True - - def run_gui(self) -> None: - from kvui import GameManager - - class TextManager(GameManager): - logging_pairs: List[Tuple[str, str]] = [("Client", "Archipelago")] - base_title: str = "Archipelago Zork Grand Inquisitor Client" - - self.ui = TextManager(self) - self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI") - - async def server_auth(self, password_requested: bool = False): - if password_requested and not self.password: - await super().server_auth(password_requested) - - await self.get_username() - await self.send_connect() - - def on_package(self, cmd: str, _args: Any) -> None: - if cmd == "Connected": - self.game = self.slot_info[self.slot].game - - # Options - self.game_controller.option_goal = id_to_goals()[_args["slot_data"]["goal"]] - self.game_controller.option_deathsanity = _args["slot_data"]["deathsanity"] == 1 - - self.game_controller.option_grant_missable_location_checks = ( - _args["slot_data"]["grant_missable_location_checks"] == 1 - ) - - async def controller(self): - while not self.exit_event.is_set(): - await asyncio.sleep(0.1) - - # Enqueue Received Item Delta - network_item: NetUtils.NetworkItem - for network_item in self.items_received: - item: ZorkGrandInquisitorItems = self.id_to_items[network_item.item] - - if item not in self.game_controller.received_items: - if item not in self.game_controller.received_items_queue: - self.game_controller.received_items_queue.append(item) - - # Game Controller Update - if self.game_controller.is_process_running(): - self.game_controller.update() - self.can_display_process_message = True - else: - process_message: str - - if self.process_attached_at_least_once: - process_message = ( - "Lost connection to Zork Grand Inquisitor process. Please restart the game and use the /zork " - "command to reattach." - ) - else: - process_message = ( - "Please use the /zork command to attach to a running Zork Grand Inquisitor process." - ) - - if self.can_display_process_message: - CommonClient.logger.info(process_message) - self.can_display_process_message = False - - # Send Checked Locations - checked_location_ids: List[int] = list() - - while len(self.game_controller.completed_locations_queue) > 0: - location: ZorkGrandInquisitorLocations = self.game_controller.completed_locations_queue.popleft() - location_id: int = self.location_name_to_id[location.value] - - checked_location_ids.append(location_id) - - await self.send_msgs([ - { - "cmd": "LocationChecks", - "locations": checked_location_ids - } - ]) - - # Check for Goal Completion - if self.game_controller.goal_completed: - await self.send_msgs([ - { - "cmd": "StatusUpdate", - "status": CommonClient.ClientStatus.CLIENT_GOAL - } - ]) - - -def main() -> None: - Utils.init_logging("ZorkGrandInquisitorClient", exception_logger="Client") - - async def _main(): - ctx: ZorkGrandInquisitorContext = ZorkGrandInquisitorContext(None, None) - - ctx.server_task = asyncio.create_task(CommonClient.server_loop(ctx), name="server loop") - ctx.controller_task = asyncio.create_task(ctx.controller(), name="ZorkGrandInquisitorController") - - if CommonClient.gui_enabled: - ctx.run_gui() - - ctx.run_cli() - - await ctx.exit_event.wait() - await ctx.shutdown() - - import colorama - - colorama.just_fix_windows_console() - - asyncio.run(_main()) - - colorama.deinit() - - -if __name__ == "__main__": - main() diff --git a/worlds/zork_grand_inquisitor/data/__init__.py b/worlds/zork_grand_inquisitor/data/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/worlds/zork_grand_inquisitor/data/entrance_rule_data.py b/worlds/zork_grand_inquisitor/data/entrance_rule_data.py deleted file mode 100644 index f48be5eb6b6a..000000000000 --- a/worlds/zork_grand_inquisitor/data/entrance_rule_data.py +++ /dev/null @@ -1,419 +0,0 @@ -from typing import Dict, Tuple, Union - -from ..enums import ZorkGrandInquisitorEvents, ZorkGrandInquisitorItems, ZorkGrandInquisitorRegions - - -entrance_rule_data: Dict[ - Tuple[ - ZorkGrandInquisitorRegions, - ZorkGrandInquisitorRegions, - ], - Union[ - Tuple[ - Tuple[ - Union[ - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorItems, - ZorkGrandInquisitorRegions, - ], - ..., - ], - ..., - ], - None, - ], -] = { - (ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.DM_LAIR): ( - ( - ZorkGrandInquisitorItems.SWORD, - ZorkGrandInquisitorItems.HOTSPOT_DUNGEON_MASTERS_LAIR_ENTRANCE, - ), - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR, - ), - ), - (ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.GUE_TECH): ( - ( - ZorkGrandInquisitorItems.SPELL_REZROV, - ZorkGrandInquisitorItems.HOTSPOT_IN_MAGIC_WE_TRUST_DOOR, - ), - ), - (ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH, - ), - ), - (ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.HADES_SHORE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES, - ), - ), - (ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.PORT_FOOZLE): None, - (ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB, - ), - ), - (ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS): ( - ( - ZorkGrandInquisitorItems.SUBWAY_TOKEN, - ZorkGrandInquisitorItems.HOTSPOT_SUBWAY_TOKEN_SLOT, - ), - ), - (ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.SUBWAY_MONASTERY): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY, - ), - ), - (ZorkGrandInquisitorRegions.DM_LAIR, ZorkGrandInquisitorRegions.CROSSROADS): None, - (ZorkGrandInquisitorRegions.DM_LAIR, ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR): ( - ( - ZorkGrandInquisitorEvents.DOOR_SMOKED_CIGAR, - ZorkGrandInquisitorEvents.DOOR_DRANK_MEAD, - ), - ), - (ZorkGrandInquisitorRegions.DM_LAIR, ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH, - ), - ), - (ZorkGrandInquisitorRegions.DM_LAIR, ZorkGrandInquisitorRegions.HADES_SHORE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES, - ), - ), - (ZorkGrandInquisitorRegions.DM_LAIR, ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB, - ), - ), - (ZorkGrandInquisitorRegions.DM_LAIR, ZorkGrandInquisitorRegions.SUBWAY_MONASTERY): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY, - ), - ), - (ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, ZorkGrandInquisitorRegions.DM_LAIR): None, - (ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, ZorkGrandInquisitorRegions.WALKING_CASTLE): ( - ( - ZorkGrandInquisitorItems.HOTSPOT_BLINDS, - ZorkGrandInquisitorEvents.KNOWS_OBIDIL, - ), - ), - (ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, ZorkGrandInquisitorRegions.WHITE_HOUSE): ( - ( - ZorkGrandInquisitorItems.HOTSPOT_CLOSET_DOOR, - ZorkGrandInquisitorItems.SPELL_NARWILE, - ZorkGrandInquisitorEvents.KNOWS_YASTARD, - ), - ), - (ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO, ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON): ( - ( - ZorkGrandInquisitorItems.TOTEM_GRIFF, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_CLAW, - ), - ), - (ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO, ZorkGrandInquisitorRegions.HADES_BEYOND_GATES): None, - (ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON, ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO): None, - (ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON, ZorkGrandInquisitorRegions.ENDGAME): ( - ( - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS, - ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH, - ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4, - ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY, - ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS, - ZorkGrandInquisitorRegions.WHITE_HOUSE, - ZorkGrandInquisitorItems.TOTEM_BROG, # Needed here since White House is not broken down in 2 regions - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH, - ZorkGrandInquisitorItems.BROGS_GRUE_EGG, - ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT, - ZorkGrandInquisitorItems.BROGS_PLANK, - ZorkGrandInquisitorItems.HOTSPOT_SKULL_CAGE, - ), - ), - (ZorkGrandInquisitorRegions.GUE_TECH, ZorkGrandInquisitorRegions.CROSSROADS): None, - (ZorkGrandInquisitorRegions.GUE_TECH, ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY): ( - ( - ZorkGrandInquisitorItems.SPELL_IGRAM, - ZorkGrandInquisitorItems.HOTSPOT_PURPLE_WORDS, - ), - ), - (ZorkGrandInquisitorRegions.GUE_TECH, ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE): ( - (ZorkGrandInquisitorItems.HOTSPOT_GUE_TECH_DOOR,), - ), - (ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, ZorkGrandInquisitorRegions.GUE_TECH): None, - (ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE): ( - ( - ZorkGrandInquisitorItems.STUDENT_ID, - ZorkGrandInquisitorItems.HOTSPOT_STUDENT_ID_MACHINE, - ), - ), - (ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, ZorkGrandInquisitorRegions.CROSSROADS): ( - (ZorkGrandInquisitorItems.MAP,), - ), - (ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, ZorkGrandInquisitorRegions.DM_LAIR): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR, - ), - ), - (ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, ZorkGrandInquisitorRegions.GUE_TECH): None, - (ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, ZorkGrandInquisitorRegions.HADES_SHORE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES, - ), - ), - (ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB, - ), - ), - (ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, ZorkGrandInquisitorRegions.SUBWAY_MONASTERY): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY, - ), - ), - (ZorkGrandInquisitorRegions.HADES, ZorkGrandInquisitorRegions.HADES_BEYOND_GATES): ( - ( - ZorkGrandInquisitorEvents.KNOWS_SNAVIG, - ZorkGrandInquisitorItems.TOTEM_BROG, # Visually hiding this totem is tied to owning it; no choice - ), - ), - (ZorkGrandInquisitorRegions.HADES, ZorkGrandInquisitorRegions.HADES_SHORE): ( - (ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS,), - ), - (ZorkGrandInquisitorRegions.HADES_BEYOND_GATES, ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO): ( - ( - ZorkGrandInquisitorItems.SPELL_NARWILE, - ZorkGrandInquisitorEvents.KNOWS_YASTARD, - ), - ), - (ZorkGrandInquisitorRegions.HADES_BEYOND_GATES, ZorkGrandInquisitorRegions.HADES): None, - (ZorkGrandInquisitorRegions.HADES_SHORE, ZorkGrandInquisitorRegions.CROSSROADS): ( - (ZorkGrandInquisitorItems.MAP,), - ), - (ZorkGrandInquisitorRegions.HADES_SHORE, ZorkGrandInquisitorRegions.DM_LAIR): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR, - ), - ), - (ZorkGrandInquisitorRegions.HADES_SHORE, ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH, - ), - ), - (ZorkGrandInquisitorRegions.HADES_SHORE, ZorkGrandInquisitorRegions.HADES): ( - ( - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_RECEIVER, - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_BUTTONS, - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS, - ), - ), - (ZorkGrandInquisitorRegions.HADES_SHORE, ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB, - ), - ), - (ZorkGrandInquisitorRegions.HADES_SHORE, ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS): None, - (ZorkGrandInquisitorRegions.HADES_SHORE, ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM): ( - (ZorkGrandInquisitorItems.SUBWAY_DESTINATION_FLOOD_CONTROL_DAM,), - ), - (ZorkGrandInquisitorRegions.HADES_SHORE, ZorkGrandInquisitorRegions.SUBWAY_MONASTERY): ( - (ZorkGrandInquisitorItems.SUBWAY_DESTINATION_MONASTERY,), - ), - (ZorkGrandInquisitorRegions.MENU, ZorkGrandInquisitorRegions.PORT_FOOZLE): None, - (ZorkGrandInquisitorRegions.MONASTERY, ZorkGrandInquisitorRegions.HADES_SHORE): ( - ( - ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_STRAIGHT_TO_HELL, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_WHEELS, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH, - ), - ), - (ZorkGrandInquisitorRegions.MONASTERY, ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT): ( - ( - ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_HALL_OF_INQUISITION, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_WHEELS, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH, - ), - ), - (ZorkGrandInquisitorRegions.MONASTERY, ZorkGrandInquisitorRegions.SUBWAY_MONASTERY): None, - (ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT, ZorkGrandInquisitorRegions.MONASTERY): None, - (ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT, ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST): ( - ( - ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_LEVER, - ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_HAMMER_SLOT, - ZorkGrandInquisitorItems.LARGE_TELEGRAPH_HAMMER, - ZorkGrandInquisitorItems.SPELL_NARWILE, - ZorkGrandInquisitorEvents.KNOWS_YASTARD, - ), - ), - (ZorkGrandInquisitorRegions.PORT_FOOZLE, ZorkGrandInquisitorRegions.CROSSROADS): ( - ( - ZorkGrandInquisitorEvents.LANTERN_DALBOZ_ACCESSIBLE, - ZorkGrandInquisitorItems.ROPE, - ZorkGrandInquisitorItems.HOTSPOT_WELL, - ), - ), - (ZorkGrandInquisitorRegions.PORT_FOOZLE, ZorkGrandInquisitorRegions.PORT_FOOZLE_JACKS_SHOP): ( - ( - ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE, - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL, - ), - ), - (ZorkGrandInquisitorRegions.PORT_FOOZLE_JACKS_SHOP, ZorkGrandInquisitorRegions.PORT_FOOZLE): None, - (ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST, ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT): None, - (ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST, ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN): ( - ( - ZorkGrandInquisitorItems.TOTEM_LUCY, - ZorkGrandInquisitorItems.HOTSPOT_PORT_FOOZLE_PAST_TAVERN_DOOR, - ), - ), - (ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN, ZorkGrandInquisitorRegions.ENDGAME): ( - ( - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4, - ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY, - ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS, - ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON, - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS, - ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH, - ZorkGrandInquisitorRegions.WHITE_HOUSE, - ZorkGrandInquisitorItems.TOTEM_BROG, # Needed here since White House is not broken down in 2 regions - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH, - ZorkGrandInquisitorItems.BROGS_GRUE_EGG, - ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT, - ZorkGrandInquisitorItems.BROGS_PLANK, - ZorkGrandInquisitorItems.HOTSPOT_SKULL_CAGE, - ), - ), - (ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN, ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST): None, - (ZorkGrandInquisitorRegions.SPELL_LAB, ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE): None, - (ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, ZorkGrandInquisitorRegions.CROSSROADS): ( - (ZorkGrandInquisitorItems.MAP,), - ), - (ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, ZorkGrandInquisitorRegions.DM_LAIR): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR, - ), - ), - (ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH, - ), - ), - (ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY): None, - (ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, ZorkGrandInquisitorRegions.HADES_SHORE): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES, - ), - ), - (ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, ZorkGrandInquisitorRegions.SPELL_LAB): ( - ( - ZorkGrandInquisitorItems.SWORD, - ZorkGrandInquisitorItems.HOTSPOT_ROPE_BRIDGE, - ZorkGrandInquisitorEvents.DAM_DESTROYED, - ZorkGrandInquisitorItems.SPELL_GOLGATEM, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_LAB_CHASM, - ), - ), - (ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, ZorkGrandInquisitorRegions.SUBWAY_MONASTERY): ( - ( - ZorkGrandInquisitorItems.MAP, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY, - ), - ), - (ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, ZorkGrandInquisitorRegions.CROSSROADS): None, - (ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, ZorkGrandInquisitorRegions.HADES_SHORE): ( - ( - ZorkGrandInquisitorItems.SPELL_KENDALL, - ZorkGrandInquisitorItems.SUBWAY_DESTINATION_HADES, - ), - ), - (ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM): ( - ( - ZorkGrandInquisitorItems.SPELL_KENDALL, - ZorkGrandInquisitorItems.SUBWAY_DESTINATION_FLOOD_CONTROL_DAM, - ), - ), - (ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, ZorkGrandInquisitorRegions.SUBWAY_MONASTERY): ( - ( - ZorkGrandInquisitorItems.SPELL_KENDALL, - ZorkGrandInquisitorItems.SUBWAY_DESTINATION_MONASTERY, - ), - ), - (ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, ZorkGrandInquisitorRegions.HADES_SHORE): ( - (ZorkGrandInquisitorItems.SUBWAY_DESTINATION_HADES,), - ), - (ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS): None, - (ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, ZorkGrandInquisitorRegions.SUBWAY_MONASTERY): ( - (ZorkGrandInquisitorItems.SUBWAY_DESTINATION_MONASTERY,), - ), - (ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, ZorkGrandInquisitorRegions.HADES_SHORE): ( - (ZorkGrandInquisitorItems.SUBWAY_DESTINATION_HADES,), - ), - (ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, ZorkGrandInquisitorRegions.MONASTERY): ( - ( - ZorkGrandInquisitorItems.SWORD, - ZorkGrandInquisitorEvents.ROPE_GLORFABLE, - ZorkGrandInquisitorItems.HOTSPOT_MONASTERY_VENT, - ), - ), - (ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS): None, - (ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM): ( - (ZorkGrandInquisitorItems.SUBWAY_DESTINATION_FLOOD_CONTROL_DAM,), - ), - (ZorkGrandInquisitorRegions.WALKING_CASTLE, ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR): None, - (ZorkGrandInquisitorRegions.WHITE_HOUSE, ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR): None, - (ZorkGrandInquisitorRegions.WHITE_HOUSE, ZorkGrandInquisitorRegions.ENDGAME): ( - ( - ZorkGrandInquisitorItems.TOTEM_BROG, # Needed here since White House is not broken down in 2 regions - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH, - ZorkGrandInquisitorItems.BROGS_GRUE_EGG, - ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT, - ZorkGrandInquisitorItems.BROGS_PLANK, - ZorkGrandInquisitorItems.HOTSPOT_SKULL_CAGE, - ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON, - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS, - ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH, - ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4, - ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY, - ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS, - ), - ), -} diff --git a/worlds/zork_grand_inquisitor/data/item_data.py b/worlds/zork_grand_inquisitor/data/item_data.py deleted file mode 100644 index c312bbce3d09..000000000000 --- a/worlds/zork_grand_inquisitor/data/item_data.py +++ /dev/null @@ -1,792 +0,0 @@ -from typing import Dict, NamedTuple, Optional, Tuple, Union - -from BaseClasses import ItemClassification - -from ..enums import ZorkGrandInquisitorItems, ZorkGrandInquisitorTags - - -class ZorkGrandInquisitorItemData(NamedTuple): - statemap_keys: Optional[Tuple[int, ...]] - archipelago_id: Optional[int] - classification: ItemClassification - tags: Tuple[ZorkGrandInquisitorTags, ...] - maximum_quantity: Optional[int] = 1 - - -ITEM_OFFSET = 9758067000 - -item_data: Dict[ZorkGrandInquisitorItems, ZorkGrandInquisitorItemData] = { - # Inventory Items - ZorkGrandInquisitorItems.BROGS_BICKERING_TORCH: ZorkGrandInquisitorItemData( - statemap_keys=(67,), # Extinguished = 103 - archipelago_id=ITEM_OFFSET + 0, - classification=ItemClassification.filler, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH: ZorkGrandInquisitorItemData( - statemap_keys=(68,), # Extinguished = 104 - archipelago_id=ITEM_OFFSET + 1, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.BROGS_GRUE_EGG: ZorkGrandInquisitorItemData( - statemap_keys=(70,), # Boiled = 71 - archipelago_id=ITEM_OFFSET + 2, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.BROGS_PLANK: ZorkGrandInquisitorItemData( - statemap_keys=(69,), - archipelago_id=ITEM_OFFSET + 3, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.FLATHEADIA_FUDGE: ZorkGrandInquisitorItemData( - statemap_keys=(54,), - archipelago_id=ITEM_OFFSET + 4, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP: ZorkGrandInquisitorItemData( - statemap_keys=(86,), - archipelago_id=ITEM_OFFSET + 5, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH: ZorkGrandInquisitorItemData( - statemap_keys=(84,), - archipelago_id=ITEM_OFFSET + 6, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT: ZorkGrandInquisitorItemData( - statemap_keys=(9,), - archipelago_id=ITEM_OFFSET + 7, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN: ZorkGrandInquisitorItemData( - statemap_keys=(16,), - archipelago_id=ITEM_OFFSET + 8, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.HAMMER: ZorkGrandInquisitorItemData( - statemap_keys=(23,), - archipelago_id=ITEM_OFFSET + 9, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.HUNGUS_LARD: ZorkGrandInquisitorItemData( - statemap_keys=(55,), - archipelago_id=ITEM_OFFSET + 10, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.JAR_OF_HOTBUGS: ZorkGrandInquisitorItemData( - statemap_keys=(56,), - archipelago_id=ITEM_OFFSET + 11, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.LANTERN: ZorkGrandInquisitorItemData( - statemap_keys=(4,), - archipelago_id=ITEM_OFFSET + 12, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.LARGE_TELEGRAPH_HAMMER: ZorkGrandInquisitorItemData( - statemap_keys=(88,), - archipelago_id=ITEM_OFFSET + 13, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1: ZorkGrandInquisitorItemData( - statemap_keys=(116,), # With fly = 120 - archipelago_id=ITEM_OFFSET + 14, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2: ZorkGrandInquisitorItemData( - statemap_keys=(117,), # With fly = 121 - archipelago_id=ITEM_OFFSET + 15, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3: ZorkGrandInquisitorItemData( - statemap_keys=(118,), # With fly = 122 - archipelago_id=ITEM_OFFSET + 16, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4: ZorkGrandInquisitorItemData( - statemap_keys=(119,), # With fly = 123 - archipelago_id=ITEM_OFFSET + 17, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.MAP: ZorkGrandInquisitorItemData( - statemap_keys=(6,), - archipelago_id=ITEM_OFFSET + 18, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.MEAD_LIGHT: ZorkGrandInquisitorItemData( - statemap_keys=(2,), - archipelago_id=ITEM_OFFSET + 19, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.MOSS_OF_MAREILON: ZorkGrandInquisitorItemData( - statemap_keys=(57,), - archipelago_id=ITEM_OFFSET + 20, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.MUG: ZorkGrandInquisitorItemData( - statemap_keys=(35,), - archipelago_id=ITEM_OFFSET + 21, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.OLD_SCRATCH_CARD: ZorkGrandInquisitorItemData( - statemap_keys=(17,), - archipelago_id=ITEM_OFFSET + 22, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.PERMA_SUCK_MACHINE: ZorkGrandInquisitorItemData( - statemap_keys=(36,), - archipelago_id=ITEM_OFFSET + 23, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.PLASTIC_SIX_PACK_HOLDER: ZorkGrandInquisitorItemData( - statemap_keys=(3,), - archipelago_id=ITEM_OFFSET + 24, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS: ZorkGrandInquisitorItemData( - statemap_keys=(5827,), - archipelago_id=ITEM_OFFSET + 25, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.PROZORK_TABLET: ZorkGrandInquisitorItemData( - statemap_keys=(65,), - archipelago_id=ITEM_OFFSET + 26, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.QUELBEE_HONEYCOMB: ZorkGrandInquisitorItemData( - statemap_keys=(53,), - archipelago_id=ITEM_OFFSET + 27, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.ROPE: ZorkGrandInquisitorItemData( - statemap_keys=(83,), - archipelago_id=ITEM_OFFSET + 28, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.SCROLL_FRAGMENT_ANS: ZorkGrandInquisitorItemData( - statemap_keys=(101,), # SNA = 41 - archipelago_id=ITEM_OFFSET + 29, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.SCROLL_FRAGMENT_GIV: ZorkGrandInquisitorItemData( - statemap_keys=(102,), # VIG = 48 - archipelago_id=ITEM_OFFSET + 30, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.SHOVEL: ZorkGrandInquisitorItemData( - statemap_keys=(49,), - archipelago_id=ITEM_OFFSET + 31, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.SNAPDRAGON: ZorkGrandInquisitorItemData( - statemap_keys=(50,), - archipelago_id=ITEM_OFFSET + 32, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.STUDENT_ID: ZorkGrandInquisitorItemData( - statemap_keys=(39,), - archipelago_id=ITEM_OFFSET + 33, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.SUBWAY_TOKEN: ZorkGrandInquisitorItemData( - statemap_keys=(20,), - archipelago_id=ITEM_OFFSET + 34, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.SWORD: ZorkGrandInquisitorItemData( - statemap_keys=(21,), - archipelago_id=ITEM_OFFSET + 35, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.ZIMDOR_SCROLL: ZorkGrandInquisitorItemData( - statemap_keys=(25,), - archipelago_id=ITEM_OFFSET + 36, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - ZorkGrandInquisitorItems.ZORK_ROCKS: ZorkGrandInquisitorItemData( - statemap_keys=(37,), - archipelago_id=ITEM_OFFSET + 37, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.INVENTORY_ITEM,), - ), - # Hotspots - ZorkGrandInquisitorItems.HOTSPOT_666_MAILBOX: ZorkGrandInquisitorItemData( - statemap_keys=(9116,), - archipelago_id=ITEM_OFFSET + 100 + 0, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS: ZorkGrandInquisitorItemData( - statemap_keys=(15434, 15436, 15438, 15440), - archipelago_id=ITEM_OFFSET + 100 + 1, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_BLANK_SCROLL_BOX: ZorkGrandInquisitorItemData( - statemap_keys=(12096,), - archipelago_id=ITEM_OFFSET + 100 + 2, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_BLINDS: ZorkGrandInquisitorItemData( - statemap_keys=(4799,), - archipelago_id=ITEM_OFFSET + 100 + 3, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_BUTTONS: ZorkGrandInquisitorItemData( - statemap_keys=(12691, 12692, 12693, 12694, 12695, 12696, 12697, 12698, 12699, 12700, 12701), - archipelago_id=ITEM_OFFSET + 100 + 4, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_COIN_SLOT: ZorkGrandInquisitorItemData( - statemap_keys=(12702,), - archipelago_id=ITEM_OFFSET + 100 + 5, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_VACUUM_SLOT: ZorkGrandInquisitorItemData( - statemap_keys=(12909,), - archipelago_id=ITEM_OFFSET + 100 + 6, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_CHANGE_MACHINE_SLOT: ZorkGrandInquisitorItemData( - statemap_keys=(12900,), - archipelago_id=ITEM_OFFSET + 100 + 7, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_CLOSET_DOOR: ZorkGrandInquisitorItemData( - statemap_keys=(5010,), - archipelago_id=ITEM_OFFSET + 100 + 8, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_HAMMER_SLOT: ZorkGrandInquisitorItemData( - statemap_keys=(9539,), - archipelago_id=ITEM_OFFSET + 100 + 9, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_LEVER: ZorkGrandInquisitorItemData( - statemap_keys=(19712,), - archipelago_id=ITEM_OFFSET + 100 + 10, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT: ZorkGrandInquisitorItemData( - statemap_keys=(2586,), - archipelago_id=ITEM_OFFSET + 100 + 11, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_DENTED_LOCKER: ZorkGrandInquisitorItemData( - statemap_keys=(11878,), - archipelago_id=ITEM_OFFSET + 100 + 12, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_DIRT_MOUND: ZorkGrandInquisitorItemData( - statemap_keys=(11751,), - archipelago_id=ITEM_OFFSET + 100 + 13, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_DOCK_WINCH: ZorkGrandInquisitorItemData( - statemap_keys=(15147, 15153), - archipelago_id=ITEM_OFFSET + 100 + 14, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_CLAW: ZorkGrandInquisitorItemData( - statemap_keys=(1705,), - archipelago_id=ITEM_OFFSET + 100 + 15, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS: ZorkGrandInquisitorItemData( - statemap_keys=(1425, 1426), - archipelago_id=ITEM_OFFSET + 100 + 16, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_DUNGEON_MASTERS_LAIR_ENTRANCE: ZorkGrandInquisitorItemData( - statemap_keys=(13106,), - archipelago_id=ITEM_OFFSET + 100 + 17, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_BUTTONS: ZorkGrandInquisitorItemData( - statemap_keys=(13219, 13220, 13221, 13222), - archipelago_id=ITEM_OFFSET + 100 + 18, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_DOORS: ZorkGrandInquisitorItemData( - statemap_keys=(14327, 14332, 14337, 14342), - archipelago_id=ITEM_OFFSET + 100 + 19, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_FROZEN_TREAT_MACHINE_COIN_SLOT: ZorkGrandInquisitorItemData( - statemap_keys=(12528,), - archipelago_id=ITEM_OFFSET + 100 + 20, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_FROZEN_TREAT_MACHINE_DOORS: ZorkGrandInquisitorItemData( - statemap_keys=(12523, 12524, 12525), - archipelago_id=ITEM_OFFSET + 100 + 21, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_GLASS_CASE: ZorkGrandInquisitorItemData( - statemap_keys=(13002,), - archipelago_id=ITEM_OFFSET + 100 + 22, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL: ZorkGrandInquisitorItemData( - statemap_keys=(10726,), - archipelago_id=ITEM_OFFSET + 100 + 23, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_GUE_TECH_DOOR: ZorkGrandInquisitorItemData( - statemap_keys=(12280,), - archipelago_id=ITEM_OFFSET + 100 + 24, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_GUE_TECH_GRASS: ZorkGrandInquisitorItemData( - statemap_keys=( - 17694, - 17695, - 17696, - 17697, - 18200, - 17703, - 17704, - 17705, - 17710, - 17711, - 17712, - 17713, - 17714, - 17715, - 17716, - 17722, - 17723, - 17724, - 17725, - 17726, - 17727 - ), - archipelago_id=ITEM_OFFSET + 100 + 25, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_BUTTONS: ZorkGrandInquisitorItemData( - statemap_keys=(8448, 8449, 8450, 8451, 8452, 8453, 8454, 8455, 8456, 8457, 8458, 8459), - archipelago_id=ITEM_OFFSET + 100 + 26, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_RECEIVER: ZorkGrandInquisitorItemData( - statemap_keys=(8446,), - archipelago_id=ITEM_OFFSET + 100 + 27, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_HARRY: ZorkGrandInquisitorItemData( - statemap_keys=(4260,), - archipelago_id=ITEM_OFFSET + 100 + 28, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_HARRYS_ASHTRAY: ZorkGrandInquisitorItemData( - statemap_keys=(18026,), - archipelago_id=ITEM_OFFSET + 100 + 29, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_HARRYS_BIRD_BATH: ZorkGrandInquisitorItemData( - statemap_keys=(17623,), - archipelago_id=ITEM_OFFSET + 100 + 30, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_IN_MAGIC_WE_TRUST_DOOR: ZorkGrandInquisitorItemData( - statemap_keys=(13140,), - archipelago_id=ITEM_OFFSET + 100 + 31, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR: ZorkGrandInquisitorItemData( - statemap_keys=(10441,), - archipelago_id=ITEM_OFFSET + 100 + 32, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_LOUDSPEAKER_VOLUME_BUTTONS: ZorkGrandInquisitorItemData( - statemap_keys=(19632, 19627), - archipelago_id=ITEM_OFFSET + 100 + 33, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_DOOR: ZorkGrandInquisitorItemData( - statemap_keys=(3025,), - archipelago_id=ITEM_OFFSET + 100 + 34, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_FLAG: ZorkGrandInquisitorItemData( - statemap_keys=(3036,), - archipelago_id=ITEM_OFFSET + 100 + 35, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_MIRROR: ZorkGrandInquisitorItemData( - statemap_keys=(5031,), - archipelago_id=ITEM_OFFSET + 100 + 36, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_MONASTERY_VENT: ZorkGrandInquisitorItemData( - statemap_keys=(13597,), - archipelago_id=ITEM_OFFSET + 100 + 37, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_MOSSY_GRATE: ZorkGrandInquisitorItemData( - statemap_keys=(13390,), - archipelago_id=ITEM_OFFSET + 100 + 38, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_PORT_FOOZLE_PAST_TAVERN_DOOR: ZorkGrandInquisitorItemData( - statemap_keys=(2455, 2447), - archipelago_id=ITEM_OFFSET + 100 + 39, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_PURPLE_WORDS: ZorkGrandInquisitorItemData( - statemap_keys=(12389, 12390), - archipelago_id=ITEM_OFFSET + 100 + 40, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_QUELBEE_HIVE: ZorkGrandInquisitorItemData( - statemap_keys=(4302,), - archipelago_id=ITEM_OFFSET + 100 + 41, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_ROPE_BRIDGE: ZorkGrandInquisitorItemData( - statemap_keys=(16383, 16384), - archipelago_id=ITEM_OFFSET + 100 + 42, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_SKULL_CAGE: ZorkGrandInquisitorItemData( - statemap_keys=(2769,), - archipelago_id=ITEM_OFFSET + 100 + 43, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_SNAPDRAGON: ZorkGrandInquisitorItemData( - statemap_keys=(4149,), - archipelago_id=ITEM_OFFSET + 100 + 44, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_SODA_MACHINE_BUTTONS: ZorkGrandInquisitorItemData( - statemap_keys=(12584, 12585, 12586, 12587), - archipelago_id=ITEM_OFFSET + 100 + 45, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_SODA_MACHINE_COIN_SLOT: ZorkGrandInquisitorItemData( - statemap_keys=(12574,), - archipelago_id=ITEM_OFFSET + 100 + 46, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_SOUVENIR_COIN_SLOT: ZorkGrandInquisitorItemData( - statemap_keys=(13412,), - archipelago_id=ITEM_OFFSET + 100 + 47, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER: ZorkGrandInquisitorItemData( - statemap_keys=(12170,), - archipelago_id=ITEM_OFFSET + 100 + 48, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_SPELL_LAB_CHASM: ZorkGrandInquisitorItemData( - statemap_keys=(16382,), - archipelago_id=ITEM_OFFSET + 100 + 49, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_SPRING_MUSHROOM: ZorkGrandInquisitorItemData( - statemap_keys=(4209,), - archipelago_id=ITEM_OFFSET + 100 + 50, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_STUDENT_ID_MACHINE: ZorkGrandInquisitorItemData( - statemap_keys=(11973,), - archipelago_id=ITEM_OFFSET + 100 + 51, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_SUBWAY_TOKEN_SLOT: ZorkGrandInquisitorItemData( - statemap_keys=(13168,), - archipelago_id=ITEM_OFFSET + 100 + 52, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY: ZorkGrandInquisitorItemData( - statemap_keys=(15396,), - archipelago_id=ITEM_OFFSET + 100 + 53, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH: ZorkGrandInquisitorItemData( - statemap_keys=(9706,), - archipelago_id=ITEM_OFFSET + 100 + 54, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_WHEELS: ZorkGrandInquisitorItemData( - statemap_keys=(9728, 9729, 9730), - archipelago_id=ITEM_OFFSET + 100 + 55, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - ZorkGrandInquisitorItems.HOTSPOT_WELL: ZorkGrandInquisitorItemData( - statemap_keys=(10314,), - archipelago_id=ITEM_OFFSET + 100 + 56, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.HOTSPOT,), - ), - # Spells - ZorkGrandInquisitorItems.SPELL_GLORF: ZorkGrandInquisitorItemData( - statemap_keys=(202,), - archipelago_id=ITEM_OFFSET + 200 + 0, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.SPELL,), - ), - ZorkGrandInquisitorItems.SPELL_GOLGATEM: ZorkGrandInquisitorItemData( - statemap_keys=(192,), - archipelago_id=ITEM_OFFSET + 200 + 1, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.SPELL,), - ), - ZorkGrandInquisitorItems.SPELL_IGRAM: ZorkGrandInquisitorItemData( - statemap_keys=(199,), - archipelago_id=ITEM_OFFSET + 200 + 2, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.SPELL,), - ), - ZorkGrandInquisitorItems.SPELL_KENDALL: ZorkGrandInquisitorItemData( - statemap_keys=(196,), - archipelago_id=ITEM_OFFSET + 200 + 3, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.SPELL,), - ), - ZorkGrandInquisitorItems.SPELL_NARWILE: ZorkGrandInquisitorItemData( - statemap_keys=(197,), - archipelago_id=ITEM_OFFSET + 200 + 4, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.SPELL,), - ), - ZorkGrandInquisitorItems.SPELL_REZROV: ZorkGrandInquisitorItemData( - statemap_keys=(195,), - archipelago_id=ITEM_OFFSET + 200 + 5, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.SPELL,), - ), - ZorkGrandInquisitorItems.SPELL_THROCK: ZorkGrandInquisitorItemData( - statemap_keys=(200,), - archipelago_id=ITEM_OFFSET + 200 + 6, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.SPELL,), - ), - ZorkGrandInquisitorItems.SPELL_VOXAM: ZorkGrandInquisitorItemData( - statemap_keys=(191,), - archipelago_id=ITEM_OFFSET + 200 + 7, - classification=ItemClassification.useful, - tags=(ZorkGrandInquisitorTags.SPELL,), - ), - # Subway Destinations - ZorkGrandInquisitorItems.SUBWAY_DESTINATION_FLOOD_CONTROL_DAM: ZorkGrandInquisitorItemData( - statemap_keys=(13757, 13297, 13486, 13625), - archipelago_id=ITEM_OFFSET + 300 + 0, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.SUBWAY_DESTINATION,), - ), - ZorkGrandInquisitorItems.SUBWAY_DESTINATION_HADES: ZorkGrandInquisitorItemData( - statemap_keys=(13758, 13309, 13498, 13637), - archipelago_id=ITEM_OFFSET + 300 + 1, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.SUBWAY_DESTINATION,), - ), - ZorkGrandInquisitorItems.SUBWAY_DESTINATION_MONASTERY: ZorkGrandInquisitorItemData( - statemap_keys=(13759, 13316, 13505, 13644), - archipelago_id=ITEM_OFFSET + 300 + 2, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.SUBWAY_DESTINATION,), - ), - # Teleporter Destinations - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR: ZorkGrandInquisitorItemData( - statemap_keys=(2203,), - archipelago_id=ITEM_OFFSET + 400 + 0, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.TELEPORTER_DESTINATION,), - ), - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH: ZorkGrandInquisitorItemData( - statemap_keys=(7132,), - archipelago_id=ITEM_OFFSET + 400 + 1, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.TELEPORTER_DESTINATION,), - ), - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES: ZorkGrandInquisitorItemData( - statemap_keys=(7119,), - archipelago_id=ITEM_OFFSET + 400 + 2, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.TELEPORTER_DESTINATION,), - ), - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY: ZorkGrandInquisitorItemData( - statemap_keys=(7148,), - archipelago_id=ITEM_OFFSET + 400 + 3, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.TELEPORTER_DESTINATION,), - ), - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB: ZorkGrandInquisitorItemData( - statemap_keys=(16545,), - archipelago_id=ITEM_OFFSET + 400 + 4, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.TELEPORTER_DESTINATION,), - ), - # Totemizer Destinations - ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_HALL_OF_INQUISITION: ZorkGrandInquisitorItemData( - statemap_keys=(9660,), - archipelago_id=ITEM_OFFSET + 500 + 0, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.TOTEMIZER_DESTINATION,), - ), - ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_INFINITY: ZorkGrandInquisitorItemData( - statemap_keys=(9666,), - archipelago_id=ITEM_OFFSET + 500 + 1, - classification=ItemClassification.filler, - tags=(ZorkGrandInquisitorTags.TOTEMIZER_DESTINATION,), - ), - ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_STRAIGHT_TO_HELL: ZorkGrandInquisitorItemData( - statemap_keys=(9668,), - archipelago_id=ITEM_OFFSET + 500 + 2, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.TOTEMIZER_DESTINATION,), - ), - ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_SURFACE_OF_MERZ: ZorkGrandInquisitorItemData( - statemap_keys=(9662,), - archipelago_id=ITEM_OFFSET + 500 + 3, - classification=ItemClassification.filler, - tags=(ZorkGrandInquisitorTags.TOTEMIZER_DESTINATION,), - ), - # Totems - ZorkGrandInquisitorItems.TOTEM_BROG: ZorkGrandInquisitorItemData( - statemap_keys=(4853,), - archipelago_id=ITEM_OFFSET + 600 + 0, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.TOTEM,), - ), - ZorkGrandInquisitorItems.TOTEM_GRIFF: ZorkGrandInquisitorItemData( - statemap_keys=(4315,), - archipelago_id=ITEM_OFFSET + 600 + 1, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.TOTEM,), - ), - ZorkGrandInquisitorItems.TOTEM_LUCY: ZorkGrandInquisitorItemData( - statemap_keys=(5223,), - archipelago_id=ITEM_OFFSET + 600 + 2, - classification=ItemClassification.progression, - tags=(ZorkGrandInquisitorTags.TOTEM,), - ), - # Filler - ZorkGrandInquisitorItems.FILLER_INQUISITION_PROPAGANDA_FLYER: ZorkGrandInquisitorItemData( - statemap_keys=None, - archipelago_id=ITEM_OFFSET + 700 + 0, - classification=ItemClassification.filler, - tags=(ZorkGrandInquisitorTags.FILLER,), - maximum_quantity=None, - ), - ZorkGrandInquisitorItems.FILLER_UNREADABLE_SPELL_SCROLL: ZorkGrandInquisitorItemData( - statemap_keys=None, - archipelago_id=ITEM_OFFSET + 700 + 1, - classification=ItemClassification.filler, - tags=(ZorkGrandInquisitorTags.FILLER,), - maximum_quantity=None, - ), - ZorkGrandInquisitorItems.FILLER_MAGIC_CONTRABAND: ZorkGrandInquisitorItemData( - statemap_keys=None, - archipelago_id=ITEM_OFFSET + 700 + 2, - classification=ItemClassification.filler, - tags=(ZorkGrandInquisitorTags.FILLER,), - maximum_quantity=None, - ), - ZorkGrandInquisitorItems.FILLER_FROBOZZ_ELECTRIC_GADGET: ZorkGrandInquisitorItemData( - statemap_keys=None, - archipelago_id=ITEM_OFFSET + 700 + 3, - classification=ItemClassification.filler, - tags=(ZorkGrandInquisitorTags.FILLER,), - maximum_quantity=None, - ), - ZorkGrandInquisitorItems.FILLER_NONSENSICAL_INQUISITION_PAPERWORK: ZorkGrandInquisitorItemData( - statemap_keys=None, - archipelago_id=ITEM_OFFSET + 700 + 4, - classification=ItemClassification.filler, - tags=(ZorkGrandInquisitorTags.FILLER,), - maximum_quantity=None, - ), -} diff --git a/worlds/zork_grand_inquisitor/data/location_data.py b/worlds/zork_grand_inquisitor/data/location_data.py deleted file mode 100644 index 8b4e57392de8..000000000000 --- a/worlds/zork_grand_inquisitor/data/location_data.py +++ /dev/null @@ -1,1535 +0,0 @@ -from typing import Dict, NamedTuple, Optional, Tuple, Union - -from ..enums import ( - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorItems, - ZorkGrandInquisitorLocations, - ZorkGrandInquisitorRegions, - ZorkGrandInquisitorTags, -) - - -class ZorkGrandInquisitorLocationData(NamedTuple): - game_state_trigger: Optional[ - Tuple[ - Union[ - Tuple[str, str], - Tuple[int, int], - Tuple[int, Tuple[int, ...]], - ], - ..., - ] - ] - archipelago_id: Optional[int] - region: ZorkGrandInquisitorRegions - tags: Optional[Tuple[ZorkGrandInquisitorTags, ...]] = None - requirements: Optional[ - Tuple[ - Union[ - Union[ - ZorkGrandInquisitorItems, - ZorkGrandInquisitorEvents, - ], - Tuple[ - Union[ - ZorkGrandInquisitorItems, - ZorkGrandInquisitorEvents, - ], - ..., - ], - ], - ..., - ] - ] = None - event_item_name: Optional[str] = None - - -LOCATION_OFFSET = 9758067000 - -location_data: Dict[ - Union[ZorkGrandInquisitorLocations, ZorkGrandInquisitorEvents], ZorkGrandInquisitorLocationData -] = { - ZorkGrandInquisitorLocations.ALARM_SYSTEM_IS_DOWN: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "tr2m"),), - archipelago_id=LOCATION_OFFSET + 0, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.ARREST_THE_VANDAL: ZorkGrandInquisitorLocationData( - game_state_trigger=((10789, 1),), - archipelago_id=LOCATION_OFFSET + 1, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE, - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL, - ), - ), - ZorkGrandInquisitorLocations.ARTIFACTS_EXPLAINED: ZorkGrandInquisitorLocationData( - game_state_trigger=((11787, 1), (11788, 1), (11789, 1)), - archipelago_id=LOCATION_OFFSET + 2, - region=ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.A_BIG_FAT_SASSY_2_HEADED_MONSTER: ZorkGrandInquisitorLocationData( - game_state_trigger=((8929, 1),), - archipelago_id=LOCATION_OFFSET + 3, - region=ZorkGrandInquisitorRegions.HADES, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorEvents.KNOWS_OBIDIL,), - ), - ZorkGrandInquisitorLocations.A_LETTER_FROM_THE_WHITE_HOUSE: ZorkGrandInquisitorLocationData( - game_state_trigger=((9124, 1),), - archipelago_id=LOCATION_OFFSET + 4, - region=ZorkGrandInquisitorRegions.HADES, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.WHITE_HOUSE_LETTER_MAILABLE, - ZorkGrandInquisitorItems.HOTSPOT_666_MAILBOX, - ), - ), - ZorkGrandInquisitorLocations.A_SMALLWAY: ZorkGrandInquisitorLocationData( - game_state_trigger=((11777, 1),), - archipelago_id=LOCATION_OFFSET + 5, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_PURPLE_WORDS, - ZorkGrandInquisitorItems.SPELL_IGRAM, - ), - ), - ZorkGrandInquisitorLocations.BEAUTIFUL_THATS_PLENTY: ZorkGrandInquisitorLocationData( - game_state_trigger=((13278, 1),), - archipelago_id=LOCATION_OFFSET + 6, - region=ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_MOSSY_GRATE, - ZorkGrandInquisitorItems.SPELL_THROCK, - ), - ), - ZorkGrandInquisitorLocations.BEBURTT_DEMYSTIFIED: ZorkGrandInquisitorLocationData( - game_state_trigger=((16315, 1),), - archipelago_id=LOCATION_OFFSET + 7, - region=ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE, - ZorkGrandInquisitorItems.SPELL_KENDALL, - ), - ), - ZorkGrandInquisitorLocations.BETTER_SPELL_MANUFACTURING_IN_UNDER_10_MINUTES: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "th3x"),), - archipelago_id=LOCATION_OFFSET + 8, - region=ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE,), - ), - ZorkGrandInquisitorLocations.BOING_BOING_BOING: ZorkGrandInquisitorLocationData( - game_state_trigger=((4220, 1),), - archipelago_id=LOCATION_OFFSET + 9, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.HAMMER, - ZorkGrandInquisitorItems.SNAPDRAGON, - ZorkGrandInquisitorItems.HOTSPOT_SPRING_MUSHROOM, - ), - ), - ZorkGrandInquisitorLocations.BONK: ZorkGrandInquisitorLocationData( - game_state_trigger=((19491, 1),), - archipelago_id=LOCATION_OFFSET + 10, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.HAMMER, - ZorkGrandInquisitorItems.HOTSPOT_SNAPDRAGON, - ), - ), - ZorkGrandInquisitorLocations.BRAVE_SOULS_WANTED: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "us2g"),), - archipelago_id=LOCATION_OFFSET + 11, - region=ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.BROG_DO_GOOD: ZorkGrandInquisitorLocationData( - game_state_trigger=((2644, 1),), - archipelago_id=LOCATION_OFFSET + 12, - region=ZorkGrandInquisitorRegions.WHITE_HOUSE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.TOTEM_BROG, - ZorkGrandInquisitorItems.BROGS_GRUE_EGG, - ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT, - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH, - ) - ), - ZorkGrandInquisitorLocations.BROG_EAT_ROCKS: ZorkGrandInquisitorLocationData( - game_state_trigger=((2629, 1),), - archipelago_id=LOCATION_OFFSET + 13, - region=ZorkGrandInquisitorRegions.WHITE_HOUSE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.TOTEM_BROG, - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH, - ) - ), - ZorkGrandInquisitorLocations.BROG_KNOW_DUMB_THAT_DUMB: ZorkGrandInquisitorLocationData( - game_state_trigger=((2650, 1),), - archipelago_id=LOCATION_OFFSET + 14, - region=ZorkGrandInquisitorRegions.WHITE_HOUSE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.TOTEM_BROG, - ZorkGrandInquisitorItems.BROGS_GRUE_EGG, - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH, - ) - ), - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME: ZorkGrandInquisitorLocationData( - game_state_trigger=((15715, 1),), - archipelago_id=LOCATION_OFFSET + 15, - region=ZorkGrandInquisitorRegions.WHITE_HOUSE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.TOTEM_BROG, - ZorkGrandInquisitorItems.BROGS_GRUE_EGG, - ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT, - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH, - ZorkGrandInquisitorItems.BROGS_PLANK, - ZorkGrandInquisitorItems.HOTSPOT_SKULL_CAGE, - ) - ), - ZorkGrandInquisitorLocations.CASTLE_WATCHING_A_FIELD_GUIDE: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "dv1t"),), - archipelago_id=LOCATION_OFFSET + 16, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.CAVES_NOTES: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "th3y"),), - archipelago_id=LOCATION_OFFSET + 17, - region=ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE,), - ), - ZorkGrandInquisitorLocations.CLOSING_THE_TIME_TUNNELS: ZorkGrandInquisitorLocationData( - game_state_trigger=((9543, 1),), - archipelago_id=LOCATION_OFFSET + 18, - region=ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.CRISIS_AVERTED: ZorkGrandInquisitorLocationData( - game_state_trigger=((11769, 1),), - archipelago_id=LOCATION_OFFSET + 19, - region=ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.ZORK_ROCKS_ACTIVATED, - ZorkGrandInquisitorItems.SPELL_IGRAM, - ZorkGrandInquisitorItems.HOTSPOT_PURPLE_WORDS, - ZorkGrandInquisitorItems.HOTSPOT_DENTED_LOCKER, - ), - ), - ZorkGrandInquisitorLocations.CUT_THAT_OUT_YOU_LITTLE_CREEP: ZorkGrandInquisitorLocationData( - game_state_trigger=((19350, 1),), - archipelago_id=LOCATION_OFFSET + 20, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.DENIED_BY_THE_LAKE_MONSTER: ZorkGrandInquisitorLocationData( - game_state_trigger=((17632, 1),), - archipelago_id=LOCATION_OFFSET + 21, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_BLINDS, - ZorkGrandInquisitorItems.SPELL_GOLGATEM, - ), - ), - ZorkGrandInquisitorLocations.DESPERATELY_SEEKING_TUTOR: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "tr2q"),), - archipelago_id=LOCATION_OFFSET + 22, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.DONT_EVEN_START_WITH_US_SPARKY: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "hp5e"), (8919, 2), (9, 100)), - archipelago_id=LOCATION_OFFSET + 23, - region=ZorkGrandInquisitorRegions.HADES, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorItems.SWORD,), - ), - ZorkGrandInquisitorLocations.DOOOOOOWN: ZorkGrandInquisitorLocationData( - game_state_trigger=((3619, 3600),), - archipelago_id=LOCATION_OFFSET + 24, - region=ZorkGrandInquisitorRegions.WHITE_HOUSE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.TOTEM_GRIFF, - ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_FLAG, - ), - ), - ZorkGrandInquisitorLocations.DOWN: ZorkGrandInquisitorLocationData( - game_state_trigger=((3619, 5300),), - archipelago_id=LOCATION_OFFSET + 25, - region=ZorkGrandInquisitorRegions.WHITE_HOUSE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.TOTEM_LUCY, - ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_FLAG, - ), - ), - ZorkGrandInquisitorLocations.DRAGON_ARCHIPELAGO_TIME_TUNNEL: ZorkGrandInquisitorLocationData( - game_state_trigger=((9216, 1),), - archipelago_id=LOCATION_OFFSET + 26, - region=ZorkGrandInquisitorRegions.HADES_BEYOND_GATES, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorItems.SPELL_NARWILE,), - ), - ZorkGrandInquisitorLocations.DUNCE_LOCKER: ZorkGrandInquisitorLocationData( - game_state_trigger=((11851, 1),), - archipelago_id=LOCATION_OFFSET + 27, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_COIN_SLOT, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_BUTTONS, - ), - ), - ZorkGrandInquisitorLocations.EGGPLANTS: ZorkGrandInquisitorLocationData( - game_state_trigger=((3816, 11000),), - archipelago_id=LOCATION_OFFSET + 28, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.ELSEWHERE: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "pc1e"),), - archipelago_id=LOCATION_OFFSET + 29, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.EMERGENCY_MAGICATRONIC_MESSAGE: ZorkGrandInquisitorLocationData( - game_state_trigger=((11784, 1),), - archipelago_id=LOCATION_OFFSET + 30, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - ), - ZorkGrandInquisitorLocations.ENJOY_YOUR_TRIP: ZorkGrandInquisitorLocationData( - game_state_trigger=((13743, 1),), - archipelago_id=LOCATION_OFFSET + 31, - region=ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorItems.SPELL_KENDALL,), - ), - ZorkGrandInquisitorLocations.FAT_LOT_OF_GOOD_THATLL_DO_YA: ZorkGrandInquisitorLocationData( - game_state_trigger=((16368, 1),), - archipelago_id=LOCATION_OFFSET + 32, - region=ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorItems.SPELL_IGRAM,), - ), - ZorkGrandInquisitorLocations.FIRE_FIRE: ZorkGrandInquisitorLocationData( - game_state_trigger=((10277, 1),), - archipelago_id=LOCATION_OFFSET + 33, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE, - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL, - ), - ), - ZorkGrandInquisitorLocations.FLOOD_CONTROL_DAM_3_THE_NOT_REMOTELY_BORING_TALE: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "ue1h"),), - archipelago_id=LOCATION_OFFSET + 34, - region=ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.FLYING_SNAPDRAGON: ZorkGrandInquisitorLocationData( - game_state_trigger=((4222, 1),), - archipelago_id=LOCATION_OFFSET + 35, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.SPELL_THROCK, - ZorkGrandInquisitorItems.SNAPDRAGON, - ZorkGrandInquisitorItems.HAMMER, - ZorkGrandInquisitorItems.HOTSPOT_SPRING_MUSHROOM, - ), - ), - ZorkGrandInquisitorLocations.FROBUARY_3_UNDERGROUNDHOG_DAY: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "dw2g"),), - archipelago_id=LOCATION_OFFSET + 36, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.GETTING_SOME_CHANGE: ZorkGrandInquisitorLocationData( - game_state_trigger=((12892, 1),), - archipelago_id=LOCATION_OFFSET + 37, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.ZORKMID_BILL_ACCESSIBLE, - ZorkGrandInquisitorItems.HOTSPOT_CHANGE_MACHINE_SLOT, - ), - ), - ZorkGrandInquisitorLocations.GO_AWAY: ZorkGrandInquisitorLocationData( - game_state_trigger=((10654, 1),), - archipelago_id=LOCATION_OFFSET + 38, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.GUE_TECH_DEANS_LIST: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "tr2k"),), - archipelago_id=LOCATION_OFFSET + 39, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.GUE_TECH_ENTRANCE_EXAM: ZorkGrandInquisitorLocationData( - game_state_trigger=((11082, 1), (11307, 1), (11536, 1)), - archipelago_id=LOCATION_OFFSET + 40, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.GUE_TECH_HEALTH_MEMO: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "tr2j"),), - archipelago_id=LOCATION_OFFSET + 41, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.GUE_TECH_MAGEMEISTERS: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "tr2n"),), - archipelago_id=LOCATION_OFFSET + 42, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.HAVE_A_HELL_OF_A_DAY: ZorkGrandInquisitorLocationData( - game_state_trigger=((8443, 1),), - archipelago_id=LOCATION_OFFSET + 43, - region=ZorkGrandInquisitorRegions.HADES_SHORE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_RECEIVER, - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_BUTTONS, - ) - ), - ZorkGrandInquisitorLocations.HELLO_THIS_IS_SHONA_FROM_GURTH_PUBLISHING: ZorkGrandInquisitorLocationData( - game_state_trigger=((4698, 1),), - archipelago_id=LOCATION_OFFSET + 44, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.HELP_ME_CANT_BREATHE: ZorkGrandInquisitorLocationData( - game_state_trigger=((10421, 1),), - archipelago_id=LOCATION_OFFSET + 45, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_DOCK_WINCH, - ZorkGrandInquisitorItems.PLASTIC_SIX_PACK_HOLDER, - ), - ), - ZorkGrandInquisitorLocations.HEY_FREE_DIRT: ZorkGrandInquisitorLocationData( - game_state_trigger=((11747, 1),), - archipelago_id=LOCATION_OFFSET + 46, - region=ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_DIRT_MOUND, - ZorkGrandInquisitorItems.SHOVEL, - ), - ), - ZorkGrandInquisitorLocations.HI_MY_NAME_IS_DOUG: ZorkGrandInquisitorLocationData( - game_state_trigger=((4698, 2),), - archipelago_id=LOCATION_OFFSET + 47, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.HMMM_INFORMATIVE_YET_DEEPLY_DISTURBING: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "mt2h"),), - archipelago_id=LOCATION_OFFSET + 48, - region=ZorkGrandInquisitorRegions.MONASTERY, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.HOLD_ON_FOR_AN_IMPORTANT_MESSAGE: ZorkGrandInquisitorLocationData( - game_state_trigger=((4698, 5),), - archipelago_id=LOCATION_OFFSET + 49, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.HOW_TO_HYPNOTIZE_YOURSELF: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "uh1e"),), - archipelago_id=LOCATION_OFFSET + 50, - region=ZorkGrandInquisitorRegions.HADES_SHORE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.HOW_TO_WIN_AT_DOUBLE_FANUCCI: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "th3s"),), - archipelago_id=LOCATION_OFFSET + 51, - region=ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorEvents.DALBOZ_LOCKER_OPENABLE,), - ), - ZorkGrandInquisitorLocations.IMBUE_BEBURTT: ZorkGrandInquisitorLocationData( - game_state_trigger=((194, 1),), - archipelago_id=LOCATION_OFFSET + 52, - region=ZorkGrandInquisitorRegions.SPELL_LAB, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_BLANK_SCROLL_BOX, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER, - ), - ), - ZorkGrandInquisitorLocations.IM_COMPLETELY_NUDE: ZorkGrandInquisitorLocationData( - game_state_trigger=((19344, 1),), - archipelago_id=LOCATION_OFFSET + 53, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.INTO_THE_FOLIAGE: ZorkGrandInquisitorLocationData( - game_state_trigger=((13060, 1),), - archipelago_id=LOCATION_OFFSET + 54, - region=ZorkGrandInquisitorRegions.CROSSROADS, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.SWORD, - ZorkGrandInquisitorItems.HOTSPOT_DUNGEON_MASTERS_LAIR_ENTRANCE, - ), - ), - ZorkGrandInquisitorLocations.INVISIBLE_FLOWERS: ZorkGrandInquisitorLocationData( - game_state_trigger=((12967, 1),), - archipelago_id=LOCATION_OFFSET + 55, - region=ZorkGrandInquisitorRegions.CROSSROADS, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorItems.SPELL_IGRAM,), - ), - ZorkGrandInquisitorLocations.IN_CASE_OF_ADVENTURE: ZorkGrandInquisitorLocationData( - game_state_trigger=((12931, 1),), - archipelago_id=LOCATION_OFFSET + 56, - region=ZorkGrandInquisitorRegions.CROSSROADS, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HAMMER, - ZorkGrandInquisitorItems.HOTSPOT_GLASS_CASE, - ), - ), - ZorkGrandInquisitorLocations.IN_MAGIC_WE_TRUST: ZorkGrandInquisitorLocationData( - game_state_trigger=((13062, 1),), - archipelago_id=LOCATION_OFFSET + 57, - region=ZorkGrandInquisitorRegions.CROSSROADS, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.SPELL_REZROV, - ZorkGrandInquisitorItems.HOTSPOT_IN_MAGIC_WE_TRUST_DOOR, - ), - ), - ZorkGrandInquisitorLocations.ITS_ONE_OF_THOSE_ADVENTURERS_AGAIN: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "pe3j"),), - archipelago_id=LOCATION_OFFSET + 58, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.I_DONT_THINK_YOU_WOULDVE_WANTED_THAT_TO_WORK_ANYWAY: ZorkGrandInquisitorLocationData( - game_state_trigger=((3816, 1008),), - archipelago_id=LOCATION_OFFSET + 59, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.SPELL_THROCK, - ZorkGrandInquisitorItems.HOTSPOT_SNAPDRAGON, - ), - ), - ZorkGrandInquisitorLocations.I_DONT_WANT_NO_TROUBLE: ZorkGrandInquisitorLocationData( - game_state_trigger=((10694, 1),), - archipelago_id=LOCATION_OFFSET + 60, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.I_HOPE_YOU_CAN_CLIMB_UP_THERE: ZorkGrandInquisitorLocationData( - game_state_trigger=((9637, 1),), - archipelago_id=LOCATION_OFFSET + 61, - region=ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.SWORD, - ZorkGrandInquisitorEvents.ROPE_GLORFABLE, - ZorkGrandInquisitorItems.HOTSPOT_MONASTERY_VENT, - ), - ), - ZorkGrandInquisitorLocations.I_LIKE_YOUR_STYLE: ZorkGrandInquisitorLocationData( - game_state_trigger=((16374, 1),), - archipelago_id=LOCATION_OFFSET + 62, - region=ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.SWORD, - ZorkGrandInquisitorItems.HOTSPOT_ROPE_BRIDGE, - ZorkGrandInquisitorEvents.DAM_DESTROYED, - ZorkGrandInquisitorItems.SPELL_GOLGATEM, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_LAB_CHASM, - ), - ), - ZorkGrandInquisitorLocations.I_SPIT_ON_YOUR_FILTHY_COINAGE: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "tp1e"), (9, 87), (1011, 1)), - archipelago_id=LOCATION_OFFSET + 63, - region=ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS,), - ), - ZorkGrandInquisitorLocations.LIT_SUNFLOWERS: ZorkGrandInquisitorLocationData( - game_state_trigger=((4129, 1),), - archipelago_id=LOCATION_OFFSET + 64, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorItems.SPELL_THROCK,), - ), - ZorkGrandInquisitorLocations.MAGIC_FOREVER: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "pc1e"), (10304, 1), (5221, 1)), - archipelago_id=LOCATION_OFFSET + 65, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.LANTERN_DALBOZ_ACCESSIBLE, - ZorkGrandInquisitorItems.ROPE, - ZorkGrandInquisitorItems.HOTSPOT_WELL, - ), - ), - ZorkGrandInquisitorLocations.MAILED_IT_TO_HELL: ZorkGrandInquisitorLocationData( - game_state_trigger=((2498, (1, 2)),), - archipelago_id=LOCATION_OFFSET + 66, - region=ZorkGrandInquisitorRegions.WHITE_HOUSE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - (ZorkGrandInquisitorItems.TOTEM_GRIFF, ZorkGrandInquisitorItems.TOTEM_LUCY), - ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_DOOR, - ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_FLAG, - ), - ), - ZorkGrandInquisitorLocations.MAKE_LOVE_NOT_WAR: ZorkGrandInquisitorLocationData( - game_state_trigger=((8623, 21),), - archipelago_id=LOCATION_OFFSET + 67, - region=ZorkGrandInquisitorRegions.HADES_SHORE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.CHARON_CALLED, - ZorkGrandInquisitorItems.SWORD, - ), - ), - ZorkGrandInquisitorLocations.MEAD_LIGHT: ZorkGrandInquisitorLocationData( - game_state_trigger=((10485, 1),), - archipelago_id=LOCATION_OFFSET + 68, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.MEAD_LIGHT, - ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR, - ), - ), - ZorkGrandInquisitorLocations.MIKES_PANTS: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "tr2p"),), - archipelago_id=LOCATION_OFFSET + 69, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.MUSHROOM_HAMMERED: ZorkGrandInquisitorLocationData( - game_state_trigger=((4217, 1),), - archipelago_id=LOCATION_OFFSET + 70, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.HAMMER, - ZorkGrandInquisitorItems.HOTSPOT_SPRING_MUSHROOM, - ), - ), - ZorkGrandInquisitorLocations.NATIONAL_TREASURE: ZorkGrandInquisitorLocationData( - game_state_trigger=((14318, 1),), - archipelago_id=LOCATION_OFFSET + 71, - region=ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.SPELL_REZROV, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_DOORS, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_BUTTONS, - ), - ), - ZorkGrandInquisitorLocations.NATURAL_AND_SUPERNATURAL_CREATURES_OF_QUENDOR: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "dv1p"),), - archipelago_id=LOCATION_OFFSET + 72, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.NOOOOOOOOOOOOO: ZorkGrandInquisitorLocationData( - game_state_trigger=((12706, 1),), - archipelago_id=LOCATION_OFFSET + 73, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_COIN_SLOT, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_BUTTONS, - ), - ), - ZorkGrandInquisitorLocations.NOTHIN_LIKE_A_GOOD_STOGIE: ZorkGrandInquisitorLocationData( - game_state_trigger=((4237, 1),), - archipelago_id=LOCATION_OFFSET + 74, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE, - ZorkGrandInquisitorItems.HOTSPOT_HARRYS_ASHTRAY, - ), - ), - ZorkGrandInquisitorLocations.NOW_YOU_LOOK_LIKE_US_WHICH_IS_AN_IMPROVEMENT: ZorkGrandInquisitorLocationData( - game_state_trigger=((8935, 1),), - archipelago_id=LOCATION_OFFSET + 75, - region=ZorkGrandInquisitorRegions.HADES, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorEvents.KNOWS_SNAVIG,), - ), - ZorkGrandInquisitorLocations.NO_AUTOGRAPHS: ZorkGrandInquisitorLocationData( - game_state_trigger=((10476, 1),), - archipelago_id=LOCATION_OFFSET + 76, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR,), - ), - ZorkGrandInquisitorLocations.NO_BONDAGE: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "pe2e"), (10262, 2), (15150, 83)), - archipelago_id=LOCATION_OFFSET + 77, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.ROPE, - ZorkGrandInquisitorItems.HOTSPOT_DOCK_WINCH, - ), - ), - ZorkGrandInquisitorLocations.OBIDIL_DRIED_UP: ZorkGrandInquisitorLocationData( - game_state_trigger=((12164, 1),), - archipelago_id=LOCATION_OFFSET + 78, - region=ZorkGrandInquisitorRegions.SPELL_LAB, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_OBIDIL, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER, - ), - ), - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON: ZorkGrandInquisitorLocationData( - game_state_trigger=((1300, 1),), - archipelago_id=LOCATION_OFFSET + 79, - region=ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS, - ), - ), - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS: ZorkGrandInquisitorLocationData( - game_state_trigger=((2448, 1),), - archipelago_id=LOCATION_OFFSET + 80, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.TOTEM_BROG, - ZorkGrandInquisitorItems.HOTSPOT_PORT_FOOZLE_PAST_TAVERN_DOOR, - ), - ), - ZorkGrandInquisitorLocations.OH_WOW_TALK_ABOUT_DEJA_VU: ZorkGrandInquisitorLocationData( - game_state_trigger=((4869, 1),), - archipelago_id=LOCATION_OFFSET + 81, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.FLATHEADIA_FUDGE, - ZorkGrandInquisitorItems.HUNGUS_LARD, - ZorkGrandInquisitorItems.JAR_OF_HOTBUGS, - ZorkGrandInquisitorItems.QUELBEE_HONEYCOMB, - ZorkGrandInquisitorItems.MOSS_OF_MAREILON, - ZorkGrandInquisitorItems.MUG, - ), - ), - ZorkGrandInquisitorLocations.OLD_SCRATCH_WINNER: ZorkGrandInquisitorLocationData( - game_state_trigger=((4512, 32),), - archipelago_id=LOCATION_OFFSET + 82, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, # This can be done anywhere if the item requirement is met - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorItems.OLD_SCRATCH_CARD,), - ), - ZorkGrandInquisitorLocations.ONLY_YOU_CAN_PREVENT_FOOZLE_FIRES: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "pe5n"),), - archipelago_id=LOCATION_OFFSET + 83, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.OPEN_THE_GATES_OF_HELL: ZorkGrandInquisitorLocationData( - game_state_trigger=((8730, 1),), - archipelago_id=LOCATION_OFFSET + 84, - region=ZorkGrandInquisitorRegions.HADES, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorEvents.KNOWS_SNAVIG,), - ), - ZorkGrandInquisitorLocations.OUTSMART_THE_QUELBEES: ZorkGrandInquisitorLocationData( - game_state_trigger=((4241, 1),), - archipelago_id=LOCATION_OFFSET + 85, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HUNGUS_LARD, - ZorkGrandInquisitorItems.SWORD, - ZorkGrandInquisitorItems.HOTSPOT_QUELBEE_HIVE, - ), - ), - ZorkGrandInquisitorLocations.PERMASEAL: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "mt1g"),), - archipelago_id=LOCATION_OFFSET + 86, - region=ZorkGrandInquisitorRegions.MONASTERY, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.PLANETFALL: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "pp1j"),), - archipelago_id=LOCATION_OFFSET + 87, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE_JACKS_SHOP, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.PLEASE_DONT_THROCK_THE_GRASS: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "te1g"),), - archipelago_id=LOCATION_OFFSET + 88, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL: ZorkGrandInquisitorLocationData( - game_state_trigger=((9404, 1),), - archipelago_id=LOCATION_OFFSET + 89, - region=ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_LEVER, - ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_HAMMER_SLOT, - ZorkGrandInquisitorItems.LARGE_TELEGRAPH_HAMMER, - ZorkGrandInquisitorItems.SPELL_NARWILE, - ), - ), - ZorkGrandInquisitorLocations.PROZORKED: ZorkGrandInquisitorLocationData( - game_state_trigger=((4115, 1),), - archipelago_id=LOCATION_OFFSET + 90, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.PROZORK_TABLET, - ZorkGrandInquisitorItems.HOTSPOT_SNAPDRAGON, - ), - ), - ZorkGrandInquisitorLocations.REASSEMBLE_SNAVIG: ZorkGrandInquisitorLocationData( - game_state_trigger=((4512, 98),), - archipelago_id=LOCATION_OFFSET + 91, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.SCROLL_FRAGMENT_ANS, - ZorkGrandInquisitorItems.SCROLL_FRAGMENT_GIV, - ZorkGrandInquisitorItems.HOTSPOT_MIRROR, - ), - ), - ZorkGrandInquisitorLocations.RESTOCKED_ON_GRUESDAY: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "tr2h"),), - archipelago_id=LOCATION_OFFSET + 92, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.RIGHT_HELLO_YES_UH_THIS_IS_SNEFFLE: ZorkGrandInquisitorLocationData( - game_state_trigger=((4698, 3),), - archipelago_id=LOCATION_OFFSET + 93, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.RIGHT_UH_SORRY_ITS_ME_AGAIN_SNEFFLE: ZorkGrandInquisitorLocationData( - game_state_trigger=((4698, 4),), - archipelago_id=LOCATION_OFFSET + 94, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.SNAVIG_REPAIRED: ZorkGrandInquisitorLocationData( - game_state_trigger=((201, 1),), - archipelago_id=LOCATION_OFFSET + 95, - region=ZorkGrandInquisitorRegions.SPELL_LAB, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_SNAVIG, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER, - ), - ), - ZorkGrandInquisitorLocations.SOUVENIR: ZorkGrandInquisitorLocationData( - game_state_trigger=((13408, 1),), - archipelago_id=LOCATION_OFFSET + 96, - region=ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS, - ZorkGrandInquisitorItems.HOTSPOT_SOUVENIR_COIN_SLOT, - ), - ), - ZorkGrandInquisitorLocations.STRAIGHT_TO_HELL: ZorkGrandInquisitorLocationData( - game_state_trigger=((9719, 1),), - archipelago_id=LOCATION_OFFSET + 97, - region=ZorkGrandInquisitorRegions.MONASTERY, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_WHEELS, - ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_STRAIGHT_TO_HELL, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH, - ), - ), - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER: ZorkGrandInquisitorLocationData( - game_state_trigger=((14511, 1), (14524, 5)), - archipelago_id=LOCATION_OFFSET + 98, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4, - ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY, - ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS, - ), - ), - ZorkGrandInquisitorLocations.SUCKING_ROCKS: ZorkGrandInquisitorLocationData( - game_state_trigger=((12859, 1),), - archipelago_id=LOCATION_OFFSET + 99, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.ZORK_ROCKS_SUCKABLE, - ZorkGrandInquisitorItems.PERMA_SUCK_MACHINE, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_VACUUM_SLOT, - ), - ), - ZorkGrandInquisitorLocations.TALK_TO_ME_GRAND_INQUISITOR: ZorkGrandInquisitorLocationData( - game_state_trigger=((10299, 1),), - archipelago_id=LOCATION_OFFSET + 100, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL,), - ), - ZorkGrandInquisitorLocations.TAMING_YOUR_SNAPDRAGON: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "dv1h"),), - archipelago_id=LOCATION_OFFSET + 101, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS: ZorkGrandInquisitorLocationData( - game_state_trigger=((1311, 1), (1312, 1)), - archipelago_id=LOCATION_OFFSET + 102, - region=ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS, - ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH, - ), - ), - ZorkGrandInquisitorLocations.THATS_A_ROPE: ZorkGrandInquisitorLocationData( - game_state_trigger=((10486, 1),), - archipelago_id=LOCATION_OFFSET + 103, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.ROPE, - ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR, - ), - ), - ZorkGrandInquisitorLocations.THATS_IT_JUST_KEEP_HITTING_THOSE_BUTTONS: ZorkGrandInquisitorLocationData( - game_state_trigger=((13805, 1),), - archipelago_id=LOCATION_OFFSET + 104, - region=ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - ), - ZorkGrandInquisitorLocations.THATS_STILL_A_ROPE: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "tp1e"), (9, 83), (1011, 1)), - archipelago_id=LOCATION_OFFSET + 105, - region=ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorEvents.ROPE_GLORFABLE,), - ), - ZorkGrandInquisitorLocations.THATS_THE_SPIRIT: ZorkGrandInquisitorLocationData( - game_state_trigger=((10341, 95),), - archipelago_id=LOCATION_OFFSET + 106, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorItems.HOTSPOT_LOUDSPEAKER_VOLUME_BUTTONS,), - ), - ZorkGrandInquisitorLocations.THE_ALCHEMICAL_DEBACLE: ZorkGrandInquisitorLocationData( - game_state_trigger=((9459, 1),), - archipelago_id=LOCATION_OFFSET + 107, - region=ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.THE_ENDLESS_FIRE: ZorkGrandInquisitorLocationData( - game_state_trigger=((9473, 1),), - archipelago_id=LOCATION_OFFSET + 108, - region=ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.THE_FLATHEADIAN_FUDGE_FIASCO: ZorkGrandInquisitorLocationData( - game_state_trigger=((9520, 1),), - archipelago_id=LOCATION_OFFSET + 109, - region=ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.THE_PERILS_OF_MAGIC: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "me1j"),), - archipelago_id=LOCATION_OFFSET + 110, - region=ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.THE_UNDERGROUND_UNDERGROUND: ZorkGrandInquisitorLocationData( - game_state_trigger=((13167, 1),), - archipelago_id=LOCATION_OFFSET + 111, - region=ZorkGrandInquisitorRegions.CROSSROADS, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.SUBWAY_TOKEN, - ZorkGrandInquisitorItems.HOTSPOT_SUBWAY_TOKEN_SLOT, - ), - ), - ZorkGrandInquisitorLocations.THIS_DOESNT_LOOK_ANYTHING_LIKE_THE_BROCHURE: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "cd60"), (1524, 1)), - archipelago_id=LOCATION_OFFSET + 112, - region=ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorItems.TOTEM_LUCY,), - ), - ZorkGrandInquisitorLocations.THROCKED_MUSHROOM_HAMMERED: ZorkGrandInquisitorLocationData( - game_state_trigger=((4219, 1),), - archipelago_id=LOCATION_OFFSET + 113, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HAMMER, - ZorkGrandInquisitorItems.SPELL_THROCK, - ZorkGrandInquisitorItems.HOTSPOT_SPRING_MUSHROOM, - ), - ), - ZorkGrandInquisitorLocations.TIME_TRAVEL_FOR_DUMMIES: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "th3z"),), - archipelago_id=LOCATION_OFFSET + 114, - region=ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE,), - ), - ZorkGrandInquisitorLocations.TOTEMIZED_DAILY_BILLBOARD: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "px1h"),), - archipelago_id=LOCATION_OFFSET + 115, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.UH_OH_BROG_CANT_SWIM: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "cd60"), (1520, 1)), - archipelago_id=LOCATION_OFFSET + 116, - region=ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorItems.TOTEM_BROG,), - ), - ZorkGrandInquisitorLocations.UMBRELLA_FLOWERS: ZorkGrandInquisitorLocationData( - game_state_trigger=((12926, 1),), - archipelago_id=LOCATION_OFFSET + 117, - region=ZorkGrandInquisitorRegions.CROSSROADS, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorEvents.KNOWS_BEBURTT,), - ), - ZorkGrandInquisitorLocations.UP: ZorkGrandInquisitorLocationData( - game_state_trigger=((3619, 5200),), - archipelago_id=LOCATION_OFFSET + 118, - region=ZorkGrandInquisitorRegions.WHITE_HOUSE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.TOTEM_LUCY, - ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_FLAG, - ), - ), - ZorkGrandInquisitorLocations.USELESS_BUT_FUN: ZorkGrandInquisitorLocationData( - game_state_trigger=((14321, 1),), - archipelago_id=LOCATION_OFFSET + 119, - region=ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=(ZorkGrandInquisitorItems.SPELL_GOLGATEM,), - ), - ZorkGrandInquisitorLocations.UUUUUP: ZorkGrandInquisitorLocationData( - game_state_trigger=((3619, 3500),), - archipelago_id=LOCATION_OFFSET + 120, - region=ZorkGrandInquisitorRegions.WHITE_HOUSE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.TOTEM_GRIFF, - ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_FLAG, - ), - ), - ZorkGrandInquisitorLocations.VOYAGE_OF_CAPTAIN_ZAHAB: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "uh1h"),), - archipelago_id=LOCATION_OFFSET + 121, - region=ZorkGrandInquisitorRegions.HADES_SHORE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.WANT_SOME_RYE_COURSE_YA_DO: ZorkGrandInquisitorLocationData( - game_state_trigger=((4034, 1),), - archipelago_id=LOCATION_OFFSET + 122, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorEvents.DOOR_SMOKED_CIGAR, - ZorkGrandInquisitorItems.MEAD_LIGHT, - ZorkGrandInquisitorItems.ZIMDOR_SCROLL, - ZorkGrandInquisitorItems.HOTSPOT_HARRYS_BIRD_BATH, - ), - ), - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE: ZorkGrandInquisitorLocationData( - game_state_trigger=((2461, 1),), - archipelago_id=LOCATION_OFFSET + 123, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.TOTEM_GRIFF, - ZorkGrandInquisitorItems.HOTSPOT_PORT_FOOZLE_PAST_TAVERN_DOOR, - ), - ), - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER: ZorkGrandInquisitorLocationData( - game_state_trigger=((15472, 1),), - archipelago_id=LOCATION_OFFSET + 124, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4, - ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY, - ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS, - ), - ), - ZorkGrandInquisitorLocations.WHAT_ARE_YOU_STUPID: ZorkGrandInquisitorLocationData( - game_state_trigger=((10484, 1),), - archipelago_id=LOCATION_OFFSET + 125, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.PLASTIC_SIX_PACK_HOLDER, - ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR, - ), - ), - ZorkGrandInquisitorLocations.WHITE_HOUSE_TIME_TUNNEL: ZorkGrandInquisitorLocationData( - game_state_trigger=((4983, 1),), - archipelago_id=LOCATION_OFFSET + 126, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_CLOSET_DOOR, - ZorkGrandInquisitorItems.SPELL_NARWILE, - ), - ), - ZorkGrandInquisitorLocations.WOW_IVE_NEVER_GONE_INSIDE_HIM_BEFORE: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "dc10"), (1596, 1)), - archipelago_id=LOCATION_OFFSET + 127, - region=ZorkGrandInquisitorRegions.WALKING_CASTLE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.YAD_GOHDNUORGREDNU_3_YRAUBORF: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "dm2g"),), - archipelago_id=LOCATION_OFFSET + 128, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorItems.HOTSPOT_MIRROR,), - ), - ZorkGrandInquisitorLocations.YOUR_PUNY_WEAPONS_DONT_PHASE_ME_BABY: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "dg4e"), (4266, 1), (9, 21), (4035, 1)), - archipelago_id=LOCATION_OFFSET + 129, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.SWORD, - ZorkGrandInquisitorItems.HOTSPOT_HARRY, - ), - ), - ZorkGrandInquisitorLocations.YOU_DONT_GO_MESSING_WITH_A_MANS_ZIPPER: ZorkGrandInquisitorLocationData( - game_state_trigger=((16405, 1),), - archipelago_id=LOCATION_OFFSET + 130, - region=ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorItems.SPELL_REZROV,), - ), - ZorkGrandInquisitorLocations.YOU_GAINED_86_EXPERIENCE_POINTS: ZorkGrandInquisitorLocationData( - game_state_trigger=((16342, 1),), - archipelago_id=LOCATION_OFFSET + 131, - region=ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - tags=(ZorkGrandInquisitorTags.CORE,), - requirements=( - ZorkGrandInquisitorItems.SWORD, - ZorkGrandInquisitorItems.HOTSPOT_ROPE_BRIDGE, - ), - ), - ZorkGrandInquisitorLocations.YOU_ONE_OF_THEM_AGITATORS_AINT_YA: ZorkGrandInquisitorLocationData( - game_state_trigger=((10586, 1),), - archipelago_id=LOCATION_OFFSET + 132, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE,), - ), - ZorkGrandInquisitorLocations.YOU_WANT_A_PIECE_OF_ME_DOCK_BOY: ZorkGrandInquisitorLocationData( - game_state_trigger=((15151, 1),), - archipelago_id=LOCATION_OFFSET + 133, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.CORE, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorItems.HOTSPOT_DOCK_WINCH,), - ), - # Deathsanity - ZorkGrandInquisitorLocations.DEATH_ARRESTED_WITH_JACK: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 1)), - archipelago_id=LOCATION_OFFSET + 200 + 0, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE, - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL, - ), - ), - ZorkGrandInquisitorLocations.DEATH_ATTACKED_THE_QUELBEES: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 20)), - archipelago_id=LOCATION_OFFSET + 200 + 1, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.SWORD, - ZorkGrandInquisitorItems.HOTSPOT_QUELBEE_HIVE, - ), - ), - ZorkGrandInquisitorLocations.DEATH_CLIMBED_OUT_OF_THE_WELL: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 21)), - archipelago_id=LOCATION_OFFSET + 200 + 2, - region=ZorkGrandInquisitorRegions.CROSSROADS, - tags=(ZorkGrandInquisitorTags.DEATHSANITY,), - ), - ZorkGrandInquisitorLocations.DEATH_EATEN_BY_A_GRUE: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 18)), - archipelago_id=LOCATION_OFFSET + 200 + 3, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.ROPE, - ZorkGrandInquisitorItems.HOTSPOT_WELL, - ), - ), - ZorkGrandInquisitorLocations.DEATH_JUMPED_IN_BOTTOMLESS_PIT: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 3)), - archipelago_id=LOCATION_OFFSET + 200 + 4, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.DEATHSANITY,), - ), - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 37)), - archipelago_id=LOCATION_OFFSET + 200 + 5, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4, - ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY, - ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS, - ), - ), - ZorkGrandInquisitorLocations.DEATH_LOST_SOUL_TO_OLD_SCRATCH: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 23)), - archipelago_id=LOCATION_OFFSET + 200 + 6, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorItems.OLD_SCRATCH_CARD,), - ), - ZorkGrandInquisitorLocations.DEATH_OUTSMARTED_BY_THE_QUELBEES: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 29)), - archipelago_id=LOCATION_OFFSET + 200 + 7, - region=ZorkGrandInquisitorRegions.DM_LAIR, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.HUNGUS_LARD, - ZorkGrandInquisitorItems.HOTSPOT_QUELBEE_HIVE, - ), - ), - ZorkGrandInquisitorLocations.DEATH_SLICED_UP_BY_THE_INVISIBLE_GUARD: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 30)), - archipelago_id=LOCATION_OFFSET + 200 + 8, - region=ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - ), - ZorkGrandInquisitorLocations.DEATH_STEPPED_INTO_THE_INFINITE: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 4)), - archipelago_id=LOCATION_OFFSET + 200 + 9, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.SPELL_IGRAM, - ZorkGrandInquisitorItems.HOTSPOT_PURPLE_WORDS, - ), - ), - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 11)), - archipelago_id=LOCATION_OFFSET + 200 + 10, - region=ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - requirements=( - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS, - ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH, - ), - ), - ZorkGrandInquisitorLocations.DEATH_THROCKED_THE_GRASS: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 34)), - archipelago_id=LOCATION_OFFSET + 200 + 11, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.DEATHSANITY,), - requirements=( - ZorkGrandInquisitorItems.SPELL_THROCK, - ZorkGrandInquisitorItems.HOTSPOT_GUE_TECH_GRASS, - ), - ), - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, (9, 32, 33))), - archipelago_id=LOCATION_OFFSET + 200 + 12, - region=ZorkGrandInquisitorRegions.MONASTERY, - tags=(ZorkGrandInquisitorTags.DEATHSANITY,), - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_WHEELS, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH, - ), - ), - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED_PERMANENTLY: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, (5, 6, 7, 8, 13))), - archipelago_id=LOCATION_OFFSET + 200 + 13, - region=ZorkGrandInquisitorRegions.MONASTERY, - tags=(ZorkGrandInquisitorTags.DEATHSANITY,), - requirements=(ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH,), - ), - ZorkGrandInquisitorLocations.DEATH_YOURE_NOT_CHARON: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 10)), - archipelago_id=LOCATION_OFFSET + 200 + 14, - region=ZorkGrandInquisitorRegions.HADES, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorEvents.KNOWS_SNAVIG,), - ), - ZorkGrandInquisitorLocations.DEATH_ZORK_ROCKS_EXPLODED: ZorkGrandInquisitorLocationData( - game_state_trigger=(("location", "gjde"), (2201, 19)), - archipelago_id=LOCATION_OFFSET + 200 + 15, - region=ZorkGrandInquisitorRegions.GUE_TECH, - tags=(ZorkGrandInquisitorTags.DEATHSANITY, ZorkGrandInquisitorTags.MISSABLE), - requirements=(ZorkGrandInquisitorEvents.ZORK_ROCKS_ACTIVATED,), - ), - # Events - ZorkGrandInquisitorEvents.CHARON_CALLED: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.HADES_SHORE, - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_RECEIVER, - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_BUTTONS, - ), - event_item_name=ZorkGrandInquisitorEvents.CHARON_CALLED.value, - ), - ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - requirements=( - ZorkGrandInquisitorItems.LANTERN, - ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR, - ), - event_item_name=ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE.value, - ), - ZorkGrandInquisitorEvents.DALBOZ_LOCKER_OPENABLE: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.GUE_TECH, - requirements=( - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_COIN_SLOT, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_BUTTONS, - ), - event_item_name=ZorkGrandInquisitorEvents.DALBOZ_LOCKER_OPENABLE.value, - ), - ZorkGrandInquisitorEvents.DAM_DESTROYED: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, - requirements=( - ZorkGrandInquisitorItems.SPELL_REZROV, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_DOORS, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_BUTTONS, - ), - event_item_name=ZorkGrandInquisitorEvents.DAM_DESTROYED.value, - ), - ZorkGrandInquisitorEvents.DOOR_DRANK_MEAD: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.DM_LAIR, - requirements=( - ZorkGrandInquisitorEvents.DOOR_SMOKED_CIGAR, - ZorkGrandInquisitorItems.MEAD_LIGHT, - ZorkGrandInquisitorItems.ZIMDOR_SCROLL, - ZorkGrandInquisitorItems.HOTSPOT_HARRYS_BIRD_BATH, - ), - event_item_name=ZorkGrandInquisitorEvents.DOOR_DRANK_MEAD.value, - ), - ZorkGrandInquisitorEvents.DOOR_SMOKED_CIGAR: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.DM_LAIR, - requirements=( - ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE, - ZorkGrandInquisitorItems.HOTSPOT_HARRYS_ASHTRAY, - ), - event_item_name=ZorkGrandInquisitorEvents.DOOR_SMOKED_CIGAR.value, - ), - ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.GUE_TECH, - requirements=( - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_COIN_SLOT, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_BUTTONS, - ), - event_item_name=ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE.value, - ), - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_OBIDIL: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.GUE_TECH, - requirements=( - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS, - ZorkGrandInquisitorItems.HOTSPOT_FROZEN_TREAT_MACHINE_COIN_SLOT, - ZorkGrandInquisitorItems.HOTSPOT_FROZEN_TREAT_MACHINE_DOORS, - ), - event_item_name=ZorkGrandInquisitorEvents.HAS_REPAIRABLE_OBIDIL.value, - ), - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_SNAVIG: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - requirements=( - ZorkGrandInquisitorItems.SCROLL_FRAGMENT_ANS, - ZorkGrandInquisitorItems.SCROLL_FRAGMENT_GIV, - ZorkGrandInquisitorItems.HOTSPOT_MIRROR, - ), - event_item_name=ZorkGrandInquisitorEvents.HAS_REPAIRABLE_SNAVIG.value, - ), - ZorkGrandInquisitorEvents.KNOWS_BEBURTT: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.SPELL_LAB, - requirements=( - ZorkGrandInquisitorItems.HOTSPOT_BLANK_SCROLL_BOX, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER, - ), - event_item_name=ZorkGrandInquisitorEvents.KNOWS_BEBURTT.value, - ), - ZorkGrandInquisitorEvents.KNOWS_OBIDIL: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.SPELL_LAB, - requirements=( - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_OBIDIL, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER, - ), - event_item_name=ZorkGrandInquisitorEvents.KNOWS_OBIDIL.value, - ), - ZorkGrandInquisitorEvents.KNOWS_SNAVIG: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.SPELL_LAB, - requirements=( - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_SNAVIG, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER, - ), - event_item_name=ZorkGrandInquisitorEvents.KNOWS_SNAVIG.value, - ), - ZorkGrandInquisitorEvents.KNOWS_YASTARD: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - requirements=( - ZorkGrandInquisitorItems.FLATHEADIA_FUDGE, - ZorkGrandInquisitorItems.HUNGUS_LARD, - ZorkGrandInquisitorItems.JAR_OF_HOTBUGS, - ZorkGrandInquisitorItems.QUELBEE_HONEYCOMB, - ZorkGrandInquisitorItems.MOSS_OF_MAREILON, - ZorkGrandInquisitorItems.MUG, - ), - event_item_name=ZorkGrandInquisitorEvents.KNOWS_YASTARD.value, - ), - ZorkGrandInquisitorEvents.LANTERN_DALBOZ_ACCESSIBLE: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - requirements=( - ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE, - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL, - ), - event_item_name=ZorkGrandInquisitorEvents.LANTERN_DALBOZ_ACCESSIBLE.value, - ), - ZorkGrandInquisitorEvents.ROPE_GLORFABLE: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.CROSSROADS, - requirements=(ZorkGrandInquisitorItems.SPELL_GLORF,), - event_item_name=ZorkGrandInquisitorEvents.ROPE_GLORFABLE.value, - ), - ZorkGrandInquisitorEvents.VICTORY: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.ENDGAME, - event_item_name=ZorkGrandInquisitorEvents.VICTORY.value, - ), - ZorkGrandInquisitorEvents.WHITE_HOUSE_LETTER_MAILABLE: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.WHITE_HOUSE, - requirements=( - (ZorkGrandInquisitorItems.TOTEM_GRIFF, ZorkGrandInquisitorItems.TOTEM_LUCY), - ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_FLAG, - ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_DOOR, - ), - event_item_name=ZorkGrandInquisitorEvents.WHITE_HOUSE_LETTER_MAILABLE.value, - ), - ZorkGrandInquisitorEvents.ZORKMID_BILL_ACCESSIBLE: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.PORT_FOOZLE, - requirements=(ZorkGrandInquisitorItems.OLD_SCRATCH_CARD,), - event_item_name=ZorkGrandInquisitorEvents.ZORKMID_BILL_ACCESSIBLE.value, - ), - ZorkGrandInquisitorEvents.ZORK_ROCKS_ACTIVATED: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.GUE_TECH, - requirements=( - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS, - ZorkGrandInquisitorItems.HOTSPOT_SODA_MACHINE_COIN_SLOT, - ZorkGrandInquisitorItems.ZORK_ROCKS, - ZorkGrandInquisitorItems.HOTSPOT_SODA_MACHINE_BUTTONS, - ), - event_item_name=ZorkGrandInquisitorEvents.ZORK_ROCKS_ACTIVATED.value, - ), - ZorkGrandInquisitorEvents.ZORK_ROCKS_SUCKABLE: ZorkGrandInquisitorLocationData( - game_state_trigger=None, - archipelago_id=None, - region=ZorkGrandInquisitorRegions.GUE_TECH, - requirements=( - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_COIN_SLOT, - ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_BUTTONS, - ), - event_item_name=ZorkGrandInquisitorEvents.ZORK_ROCKS_SUCKABLE.value, - ), -} diff --git a/worlds/zork_grand_inquisitor/data/missable_location_grant_conditions_data.py b/worlds/zork_grand_inquisitor/data/missable_location_grant_conditions_data.py deleted file mode 100644 index ef6eacb78ceb..000000000000 --- a/worlds/zork_grand_inquisitor/data/missable_location_grant_conditions_data.py +++ /dev/null @@ -1,200 +0,0 @@ -from typing import Dict, NamedTuple, Optional, Tuple - -from ..enums import ZorkGrandInquisitorItems, ZorkGrandInquisitorLocations - - -class ZorkGrandInquisitorMissableLocationGrantConditionsData(NamedTuple): - location_condition: ZorkGrandInquisitorLocations - item_conditions: Optional[Tuple[ZorkGrandInquisitorItems, ...]] - - -missable_location_grant_conditions_data: Dict[ - ZorkGrandInquisitorLocations, ZorkGrandInquisitorMissableLocationGrantConditionsData -] = { - ZorkGrandInquisitorLocations.BOING_BOING_BOING: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.FLYING_SNAPDRAGON, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.BONK: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.PROZORKED, - item_conditions=(ZorkGrandInquisitorItems.HAMMER,), - ) - , - ZorkGrandInquisitorLocations.DEATH_ARRESTED_WITH_JACK: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.ARREST_THE_VANDAL, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DEATH_ATTACKED_THE_QUELBEES: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.OUTSMART_THE_QUELBEES, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DEATH_EATEN_BY_A_GRUE: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.MAGIC_FOREVER, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DEATH_LOST_SOUL_TO_OLD_SCRATCH: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.OLD_SCRATCH_WINNER, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DEATH_OUTSMARTED_BY_THE_QUELBEES: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.OUTSMART_THE_QUELBEES, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DEATH_SLICED_UP_BY_THE_INVISIBLE_GUARD: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.YOU_GAINED_86_EXPERIENCE_POINTS, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DEATH_STEPPED_INTO_THE_INFINITE: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.A_SMALLWAY, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.THAR_SHE_BLOWS, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DEATH_YOURE_NOT_CHARON: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.OPEN_THE_GATES_OF_HELL, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DEATH_ZORK_ROCKS_EXPLODED: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.CRISIS_AVERTED, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.DENIED_BY_THE_LAKE_MONSTER: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.WOW_IVE_NEVER_GONE_INSIDE_HIM_BEFORE, - item_conditions=(ZorkGrandInquisitorItems.SPELL_GOLGATEM,), - ) - , - ZorkGrandInquisitorLocations.EMERGENCY_MAGICATRONIC_MESSAGE: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.ARTIFACTS_EXPLAINED, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.FAT_LOT_OF_GOOD_THATLL_DO_YA: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.YOU_GAINED_86_EXPERIENCE_POINTS, - item_conditions=(ZorkGrandInquisitorItems.SPELL_IGRAM,), - ) - , - ZorkGrandInquisitorLocations.I_DONT_THINK_YOU_WOULDVE_WANTED_THAT_TO_WORK_ANYWAY: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.PROZORKED, - item_conditions=(ZorkGrandInquisitorItems.SPELL_THROCK,), - ) - , - ZorkGrandInquisitorLocations.I_SPIT_ON_YOUR_FILTHY_COINAGE: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.YOU_GAINED_86_EXPERIENCE_POINTS, - item_conditions=(ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS,), - ) - , - ZorkGrandInquisitorLocations.MEAD_LIGHT: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.FIRE_FIRE, - item_conditions=(ZorkGrandInquisitorItems.MEAD_LIGHT,), - ) - , - ZorkGrandInquisitorLocations.MUSHROOM_HAMMERED: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.THROCKED_MUSHROOM_HAMMERED, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.NO_AUTOGRAPHS: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.FIRE_FIRE, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.NO_BONDAGE: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.HELP_ME_CANT_BREATHE, - item_conditions=(ZorkGrandInquisitorItems.ROPE,), - ) - , - ZorkGrandInquisitorLocations.TALK_TO_ME_GRAND_INQUISITOR: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.FIRE_FIRE, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.THATS_A_ROPE: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.FIRE_FIRE, - item_conditions=(ZorkGrandInquisitorItems.ROPE,), - ) - , - ZorkGrandInquisitorLocations.THATS_IT_JUST_KEEP_HITTING_THOSE_BUTTONS: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.ENJOY_YOUR_TRIP, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.THATS_STILL_A_ROPE: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.YOU_GAINED_86_EXPERIENCE_POINTS, - item_conditions=(ZorkGrandInquisitorItems.SPELL_GLORF,), - ) - , - ZorkGrandInquisitorLocations.WHAT_ARE_YOU_STUPID: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.FIRE_FIRE, - item_conditions=(ZorkGrandInquisitorItems.PLASTIC_SIX_PACK_HOLDER,), - ) - , - ZorkGrandInquisitorLocations.YAD_GOHDNUORGREDNU_3_YRAUBORF: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.REASSEMBLE_SNAVIG, - item_conditions=None, - ) - , - ZorkGrandInquisitorLocations.YOUR_PUNY_WEAPONS_DONT_PHASE_ME_BABY: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.WANT_SOME_RYE_COURSE_YA_DO, - item_conditions=(ZorkGrandInquisitorItems.SWORD, ZorkGrandInquisitorItems.HOTSPOT_HARRY), - ) - , - ZorkGrandInquisitorLocations.YOU_DONT_GO_MESSING_WITH_A_MANS_ZIPPER: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.YOU_GAINED_86_EXPERIENCE_POINTS, - item_conditions=(ZorkGrandInquisitorItems.SPELL_REZROV,), - ) - , - ZorkGrandInquisitorLocations.YOU_WANT_A_PIECE_OF_ME_DOCK_BOY: - ZorkGrandInquisitorMissableLocationGrantConditionsData( - location_condition=ZorkGrandInquisitorLocations.HELP_ME_CANT_BREATHE, - item_conditions=None, - ) - , -} diff --git a/worlds/zork_grand_inquisitor/data/region_data.py b/worlds/zork_grand_inquisitor/data/region_data.py deleted file mode 100644 index 1aed160f3088..000000000000 --- a/worlds/zork_grand_inquisitor/data/region_data.py +++ /dev/null @@ -1,183 +0,0 @@ -from typing import Dict, NamedTuple, Optional, Tuple - -from ..enums import ZorkGrandInquisitorRegions - - -class ZorkGrandInquisitorRegionData(NamedTuple): - exits: Optional[Tuple[ZorkGrandInquisitorRegions, ...]] - - -region_data: Dict[ZorkGrandInquisitorRegions, ZorkGrandInquisitorRegionData] = { - ZorkGrandInquisitorRegions.CROSSROADS: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.DM_LAIR, - ZorkGrandInquisitorRegions.GUE_TECH, - ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, - ZorkGrandInquisitorRegions.HADES_SHORE, - ZorkGrandInquisitorRegions.PORT_FOOZLE, - ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, - ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, - ) - ), - ZorkGrandInquisitorRegions.DM_LAIR: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.CROSSROADS, - ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, - ZorkGrandInquisitorRegions.HADES_SHORE, - ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, - ) - ), - ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.DM_LAIR, - ZorkGrandInquisitorRegions.WALKING_CASTLE, - ZorkGrandInquisitorRegions.WHITE_HOUSE, - ) - ), - ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON, - ZorkGrandInquisitorRegions.HADES_BEYOND_GATES, - ) - ), - ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO, - ZorkGrandInquisitorRegions.ENDGAME, - ) - ), - ZorkGrandInquisitorRegions.ENDGAME: ZorkGrandInquisitorRegionData(exits=None), - ZorkGrandInquisitorRegions.GUE_TECH: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.CROSSROADS, - ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, - ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, - ) - ), - ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.GUE_TECH, - ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - ) - ), - ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.CROSSROADS, - ZorkGrandInquisitorRegions.DM_LAIR, - ZorkGrandInquisitorRegions.GUE_TECH, - ZorkGrandInquisitorRegions.HADES_SHORE, - ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, - ) - ), - ZorkGrandInquisitorRegions.HADES: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.HADES_BEYOND_GATES, - ZorkGrandInquisitorRegions.HADES_SHORE, - ) - ), - ZorkGrandInquisitorRegions.HADES_BEYOND_GATES: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO, - ZorkGrandInquisitorRegions.HADES, - ) - ), - ZorkGrandInquisitorRegions.HADES_SHORE: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.CROSSROADS, - ZorkGrandInquisitorRegions.DM_LAIR, - ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, - ZorkGrandInquisitorRegions.HADES, - ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE, - ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, - ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, - ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, - ) - ), - ZorkGrandInquisitorRegions.MENU: ZorkGrandInquisitorRegionData( - exits=(ZorkGrandInquisitorRegions.PORT_FOOZLE,) - ), - ZorkGrandInquisitorRegions.MONASTERY: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.HADES_SHORE, - ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT, - ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, - ) - ), - ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.MONASTERY, - ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST, - ) - ), - ZorkGrandInquisitorRegions.PORT_FOOZLE: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.CROSSROADS, - ZorkGrandInquisitorRegions.PORT_FOOZLE_JACKS_SHOP, - ) - ), - ZorkGrandInquisitorRegions.PORT_FOOZLE_JACKS_SHOP: ZorkGrandInquisitorRegionData( - exits=(ZorkGrandInquisitorRegions.PORT_FOOZLE,) - ), - ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT, - ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN, - ) - ), - ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.ENDGAME, - ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST, - ) - ), - ZorkGrandInquisitorRegions.SPELL_LAB: ZorkGrandInquisitorRegionData( - exits=(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE,) - ), - ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.CROSSROADS, - ZorkGrandInquisitorRegions.DM_LAIR, - ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, - ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY, - ZorkGrandInquisitorRegions.HADES_SHORE, - ZorkGrandInquisitorRegions.SPELL_LAB, - ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, - ) - ), - ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.CROSSROADS, - ZorkGrandInquisitorRegions.HADES_SHORE, - ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, - ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, - ) - ), - ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.HADES_SHORE, - ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, - ZorkGrandInquisitorRegions.SUBWAY_MONASTERY, - ) - ), - ZorkGrandInquisitorRegions.SUBWAY_MONASTERY: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.HADES_SHORE, - ZorkGrandInquisitorRegions.MONASTERY, - ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS, - ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM, - ) - ), - ZorkGrandInquisitorRegions.WALKING_CASTLE: ZorkGrandInquisitorRegionData( - exits=(ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR,) - ), - ZorkGrandInquisitorRegions.WHITE_HOUSE: ZorkGrandInquisitorRegionData( - exits=( - ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, - ZorkGrandInquisitorRegions.ENDGAME, - ) - ), -} diff --git a/worlds/zork_grand_inquisitor/data_funcs.py b/worlds/zork_grand_inquisitor/data_funcs.py deleted file mode 100644 index 2a7bff1fbb6b..000000000000 --- a/worlds/zork_grand_inquisitor/data_funcs.py +++ /dev/null @@ -1,247 +0,0 @@ -from typing import Dict, List, Set, Tuple, Union - -from .data.entrance_rule_data import entrance_rule_data -from .data.item_data import item_data, ZorkGrandInquisitorItemData -from .data.location_data import location_data, ZorkGrandInquisitorLocationData - -from .enums import ( - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorGoals, - ZorkGrandInquisitorItems, - ZorkGrandInquisitorLocations, - ZorkGrandInquisitorRegions, - ZorkGrandInquisitorTags, -) - - -def item_names_to_id() -> Dict[str, int]: - return {item.value: data.archipelago_id for item, data in item_data.items()} - - -def item_names_to_item() -> Dict[str, ZorkGrandInquisitorItems]: - return {item.value: item for item in item_data} - - -def location_names_to_id() -> Dict[str, int]: - return { - location.value: data.archipelago_id - for location, data in location_data.items() - if data.archipelago_id is not None - } - - -def location_names_to_location() -> Dict[str, ZorkGrandInquisitorLocations]: - return { - location.value: location - for location, data in location_data.items() - if data.archipelago_id is not None - } - - -def id_to_goals() -> Dict[int, ZorkGrandInquisitorGoals]: - return {goal.value: goal for goal in ZorkGrandInquisitorGoals} - - -def id_to_items() -> Dict[int, ZorkGrandInquisitorItems]: - return {data.archipelago_id: item for item, data in item_data.items()} - - -def id_to_locations() -> Dict[int, ZorkGrandInquisitorLocations]: - return { - data.archipelago_id: location - for location, data in location_data.items() - if data.archipelago_id is not None - } - - -def item_groups() -> Dict[str, List[str]]: - groups: Dict[str, List[str]] = dict() - - item: ZorkGrandInquisitorItems - data: ZorkGrandInquisitorItemData - for item, data in item_data.items(): - if data.tags is not None: - for tag in data.tags: - groups.setdefault(tag.value, list()).append(item.value) - - return {k: v for k, v in groups.items() if len(v)} - - -def items_with_tag(tag: ZorkGrandInquisitorTags) -> Set[ZorkGrandInquisitorItems]: - items: Set[ZorkGrandInquisitorItems] = set() - - item: ZorkGrandInquisitorItems - data: ZorkGrandInquisitorItemData - for item, data in item_data.items(): - if data.tags is not None and tag in data.tags: - items.add(item) - - return items - - -def game_id_to_items() -> Dict[int, ZorkGrandInquisitorItems]: - mapping: Dict[int, ZorkGrandInquisitorItems] = dict() - - item: ZorkGrandInquisitorItems - data: ZorkGrandInquisitorItemData - for item, data in item_data.items(): - if data.statemap_keys is not None: - for key in data.statemap_keys: - mapping[key] = item - - return mapping - - -def location_groups() -> Dict[str, List[str]]: - groups: Dict[str, List[str]] = dict() - - tag: ZorkGrandInquisitorTags - for tag in ZorkGrandInquisitorTags: - groups[tag.value] = list() - - location: ZorkGrandInquisitorLocations - data: ZorkGrandInquisitorLocationData - for location, data in location_data.items(): - if data.tags is not None: - for tag in data.tags: - groups[tag.value].append(location.value) - - return {k: v for k, v in groups.items() if len(v)} - - -def locations_by_region(include_deathsanity: bool = False) -> Dict[ - ZorkGrandInquisitorRegions, List[ZorkGrandInquisitorLocations] -]: - mapping: Dict[ZorkGrandInquisitorRegions, List[ZorkGrandInquisitorLocations]] = dict() - - region: ZorkGrandInquisitorRegions - for region in ZorkGrandInquisitorRegions: - mapping[region] = list() - - location: ZorkGrandInquisitorLocations - data: ZorkGrandInquisitorLocationData - for location, data in location_data.items(): - if not include_deathsanity and ZorkGrandInquisitorTags.DEATHSANITY in ( - data.tags or tuple() - ): - continue - - mapping[data.region].append(location) - - return mapping - - -def locations_with_tag(tag: ZorkGrandInquisitorTags) -> Set[ZorkGrandInquisitorLocations]: - location: ZorkGrandInquisitorLocations - data: ZorkGrandInquisitorLocationData - - return {location for location, data in location_data.items() if data.tags is not None and tag in data.tags} - - -def location_access_rule_for(location: ZorkGrandInquisitorLocations, player: int) -> str: - data: ZorkGrandInquisitorLocationData = location_data[location] - - if data.requirements is None: - return "lambda state: True" - - lambda_string: str = "lambda state: " - - i: int - requirement: Union[ - Tuple[ - Union[ - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorItems, - ], - ..., - ], - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorItems - ] - - for i, requirement in enumerate(data.requirements): - if isinstance(requirement, tuple): - lambda_string += "(" - - ii: int - sub_requirement: Union[ZorkGrandInquisitorEvents, ZorkGrandInquisitorItems] - for ii, sub_requirement in enumerate(requirement): - lambda_string += f"state.has(\"{sub_requirement.value}\", {player})" - - if ii < len(requirement) - 1: - lambda_string += " or " - - lambda_string += ")" - else: - lambda_string += f"state.has(\"{requirement.value}\", {player})" - - if i < len(data.requirements) - 1: - lambda_string += " and " - - return lambda_string - - -def entrance_access_rule_for( - region_origin: ZorkGrandInquisitorRegions, - region_destination: ZorkGrandInquisitorRegions, - player: int -) -> str: - data: Union[ - Tuple[ - Tuple[ - Union[ - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorItems, - ZorkGrandInquisitorRegions, - ], - ..., - ], - ..., - ], - None, - ] = entrance_rule_data[(region_origin, region_destination)] - - if data is None: - return "lambda state: True" - - lambda_string: str = "lambda state: " - - i: int - requirement_group: Tuple[ - Union[ - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorItems, - ZorkGrandInquisitorRegions, - ], - ..., - ] - for i, requirement_group in enumerate(data): - lambda_string += "(" - - ii: int - requirement: Union[ - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorItems, - ZorkGrandInquisitorRegions, - ] - for ii, requirement in enumerate(requirement_group): - requirement_type: Union[ - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorItems, - ZorkGrandInquisitorRegions, - ] = type(requirement) - - if requirement_type in (ZorkGrandInquisitorEvents, ZorkGrandInquisitorItems): - lambda_string += f"state.has(\"{requirement.value}\", {player})" - elif requirement_type == ZorkGrandInquisitorRegions: - lambda_string += f"state.can_reach(\"{requirement.value}\", \"Region\", {player})" - - if ii < len(requirement_group) - 1: - lambda_string += " and " - - lambda_string += ")" - - if i < len(data) - 1: - lambda_string += " or " - - return lambda_string diff --git a/worlds/zork_grand_inquisitor/docs/en_Zork Grand Inquisitor.md b/worlds/zork_grand_inquisitor/docs/en_Zork Grand Inquisitor.md deleted file mode 100644 index d5821914beca..000000000000 --- a/worlds/zork_grand_inquisitor/docs/en_Zork Grand Inquisitor.md +++ /dev/null @@ -1,102 +0,0 @@ -# Zork Grand Inquisitor - -## Where is the options page? - -The [player options page for this game](../player-options) contains all the options you need to configure and export a -configuration file. - -## Is a tracker available for this game? - -Yes! You can download the latest PopTracker pack for Zork Grand Inquisitor [here](https://github.com/SerpentAI/ZorkGrandInquisitorAPTracker/releases/latest). - -## What does randomization do to this game? - -A majority of inventory items you can normally pick up are completely removed from the game (e.g. the lantern won't be -in the crate, the mead won't be at the fish market, etc.). Instead, these items will be distributed in the multiworld. -This means that you can expect to access areas and be in a position to solve certain puzzles in a completely different -order than you normally would. - -Subway, teleporter and totemizer destinations are initially locked and need to be unlocked by receiving the -corresponding item in the multiworld. This alone enables creative routing in a game that would otherwise be rather -linear. The Crossroads destination is always unlocked for both the subway and teleporter to prevent softlocks. Until you -receive your first totemizer destination, it will be locked to Newark, New Jersey. - -Important hotspots are also randomized. This means that you will be unable to interact with certain objects until you -receive the corresponding item in the multiworld. This can be a bit confusing at first, but it adds depth to the -randomization and makes the game more interesting to play. - -You can travel back to the surface without dying by looking inside the bucket. This will work as long as the rope is -still attached to the well. - -Attempting to cast VOXAM will teleport you back to the Crossroads. Fast Travel! - -## What item types are distributed in the multiworld? - -- Inventory items -- Pouch of Zorkmids -- Spells -- Totems -- Subway destinations -- Teleporter destinations -- Totemizer destinations -- Hotspots (with option to start with the items enabling them instead if you prefer not playing with the randomization - of hotspots) - -## When the player receives an item, what happens? - -- **Inventory items**: Directly added to the player's inventory. -- **Pouch of Zorkmids**: Appears on the inventory screen. The player can then pick up Zorkmid coins from it. -- **Spells**: Learned and directly added to the spell book. -- **Totems**: Appears on the inventory screen. -- **Subway destinations**: The destination button on the subway map becomes functional. -- **Teleporter destinations**: The destination can show up on the teleporter screen. -- **Totemizer destinations**: The destination button on the panel becomes functional. -- **Hotspots**: The hotspot becomes interactable. - -## What is considered a location check in Zork Grand Inquisitor? - -- Solving puzzles -- Accessing certain areas for the first time -- Triggering certain interactions, even if they aren't puzzles per se -- Dying in unique ways (Optional; Deathsanity option) - -## The location check names are fun but don't always convey well what's needed to unlock them. Is there a guide? - -Yes! You can find a complete guide for the location checks [here](https://gist.github.com/nbrochu/f7bed7a1fef4e2beb67ad6ddbf18b970). - -## What is the victory condition? - -Victory is achieved when the 3 artifacts of magic are retrieved and placed inside the walking castle. - -## Can I use the save system without a problem? - -Absolutely! The save system is fully supported (and its use is in fact strongly encouraged!). You can save and load your -game as you normally would and the client will automatically sync your items and hotspots with what you should have in -that game state. - -Depending on how your game progresses, there's a chance that certain location checks might become missable. This -presents an excellent opportunity to utilize the save system. Simply make it a habit to save before undertaking -irreversible actions, ensuring you can revert to a previous state if necessary. If you prefer not to depend on the save -system for accessing missable location checks, there's an option to automatically unlock them as they become -unavailable. - -## Unique Local Commands -The following commands are only available when using the Zork Grand Inquisitor Client to play the game with Archipelago. - -- `/zork` Attempts to attach to a running instance of Zork Grand Inquisitor. If successful, the client will then be able - to read and control the state of the game. -- `/brog` Lists received items for Brog. -- `/griff` Lists received items for Griff. -- `/lucy` Lists received items for Lucy. -- `/hotspots` Lists received hotspots. - -## Known issues - -- You will get a second rope right after using GLORF (one in your inventory and one on your cursor). This is a harmless - side effect that will go away after you store it in your inventory as duplicates are actively removed. -- After climbing up to the Monastery for the first time, a rope will forever remain in place in the vent. When you come - back to the Monastery, you will be able to climb up without needing to combine the sword and rope again. However, when - arriving at the top, you will receive a duplicate sword on a rope. This is a harmless side effect that will go away - after you store it in your inventory as duplicates are actively removed. -- Since the client is reading and manipulating the game's memory, rare game crashes can happen. If you encounter one, - simply restart the game, load your latest save and use the `/zork` command again in the client. Nothing will be lost. diff --git a/worlds/zork_grand_inquisitor/docs/setup_en.md b/worlds/zork_grand_inquisitor/docs/setup_en.md deleted file mode 100644 index f9078c6d39ba..000000000000 --- a/worlds/zork_grand_inquisitor/docs/setup_en.md +++ /dev/null @@ -1,42 +0,0 @@ -# Zork Grand Inquisitor Randomizer Setup Guide - -## Requirements - -- Windows OS (Hard required. Client is using memory reading / writing through Win32 API) -- A copy of Zork Grand Inquisitor. Only the GOG version is supported. The Steam version can work with some tinkering but - is not officially supported. -- ScummVM 2.7.1 64-bit (Important: Will not work with any other version. [Direct Download](https://downloads.scummvm.org/frs/scummvm/2.7.1/scummvm-2.7.1-win32-x86_64.zip)) -- Archipelago 0.4.4+ - -## Game Setup Instructions - -No game modding is required to play Zork Grand Inquisitor with Archipelago. The client does all the work by attaching to -the game process and reading and manipulating the game state in real-time. - -This being said, the game does need to be played through ScummVM 2.7.1, so some configuration is required around that. - -### GOG - -- Open the directory where you installed Zork Grand Inquisitor. You should see a `Launch Zork Grand Inquisitor` - shortcut. -- Open the `scummvm` directory. Delete the entire contents of that directory. -- Still inside the `scummvm` directory, unzip the contents of the ScummVM 2.7.1 zip file you downloaded earlier. -- Go back to the directory where you installed Zork Grand Inquisitor. -- Verify that the game still launches when using the `Launch Zork Grand Inquisitor` shortcut. -- Your game is now ready to be played with Archipelago. From now on, you can use the `Launch Zork Grand Inquisitor` - shortcut to launch the game. - -## Joining a Multiworld Game - -- Launch Zork Grand Inquisitor and start a new game. -- Open the Archipelago Launcher and click `Zork Grand Inquisitor Client`. -- Using the `Zork Grand Inquisitor Client`: - - Enter the room's hostname and port number (e.g. `archipelago.gg:54321`) in the top box and press `Connect`. - - Input your player name at the bottom when prompted and press `Enter`. - - You should now be connected to the Archipelago room. - - Next, input `/zork` at the bottom and press `Enter`. This will attach the client to the game process. - - If the command is successful, you are now ready to play Zork Grand Inquisitor with Archipelago. - -## Continuing a Multiworld Game - -- Perform the same steps as above, but instead of starting a new game, load your latest save file. diff --git a/worlds/zork_grand_inquisitor/enums.py b/worlds/zork_grand_inquisitor/enums.py deleted file mode 100644 index ecbb38a949b4..000000000000 --- a/worlds/zork_grand_inquisitor/enums.py +++ /dev/null @@ -1,350 +0,0 @@ -import enum - - -class ZorkGrandInquisitorEvents(enum.Enum): - CHARON_CALLED = "Event: Charon Called" - CIGAR_ACCESSIBLE = "Event: Cigar Accessible" - DALBOZ_LOCKER_OPENABLE = "Event: Dalboz Locker Openable" - DAM_DESTROYED = "Event: Dam Destroyed" - DOOR_DRANK_MEAD = "Event: Door Drank Mead" - DOOR_SMOKED_CIGAR = "Event: Door Smoked Cigar" - DUNCE_LOCKER_OPENABLE = "Event: Dunce Locker Openable" - HAS_REPAIRABLE_OBIDIL = "Event: Has Repairable OBIDIL" - HAS_REPAIRABLE_SNAVIG = "Event: Has Repairable SNAVIG" - KNOWS_BEBURTT = "Event: Knows BEBURTT" - KNOWS_OBIDIL = "Event: Knows OBIDIL" - KNOWS_SNAVIG = "Event: Knows SNAVIG" - KNOWS_YASTARD = "Event: Knows YASTARD" - LANTERN_DALBOZ_ACCESSIBLE = "Event: Lantern (Dalboz) Accessible" - ROPE_GLORFABLE = "Event: Rope GLORFable" - VICTORY = "Victory" - WHITE_HOUSE_LETTER_MAILABLE = "Event: White House Letter Mailable" - ZORKMID_BILL_ACCESSIBLE = "Event: 500 Zorkmid Bill Accessible" - ZORK_ROCKS_ACTIVATED = "Event: Zork Rocks Activated" - ZORK_ROCKS_SUCKABLE = "Event: Zork Rocks Suckable" - - -class ZorkGrandInquisitorGoals(enum.Enum): - THREE_ARTIFACTS = 0 - - -class ZorkGrandInquisitorItems(enum.Enum): - BROGS_BICKERING_TORCH = "Brog's Bickering Torch" - BROGS_FLICKERING_TORCH = "Brog's Flickering Torch" - BROGS_GRUE_EGG = "Brog's Grue Egg" - BROGS_PLANK = "Brog's Plank" - FILLER_FROBOZZ_ELECTRIC_GADGET = "Frobozz Electric Gadget" - FILLER_INQUISITION_PROPAGANDA_FLYER = "Inquisition Propaganda Flyer" - FILLER_MAGIC_CONTRABAND = "Magic Contraband" - FILLER_NONSENSICAL_INQUISITION_PAPERWORK = "Nonsensical Inquisition Paperwork" - FILLER_UNREADABLE_SPELL_SCROLL = "Unreadable Spell Scroll" - FLATHEADIA_FUDGE = "Flatheadia Fudge" - GRIFFS_AIR_PUMP = "Griff's Air Pump" - GRIFFS_DRAGON_TOOTH = "Griff's Dragon Tooth" - GRIFFS_INFLATABLE_RAFT = "Griff's Inflatable Raft" - GRIFFS_INFLATABLE_SEA_CAPTAIN = "Griff's Inflatable Sea Captain" - HAMMER = "Hammer" - HOTSPOT_666_MAILBOX = "Hotspot: 666 Mailbox" - HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS = "Hotspot: Alpine's Quandry Card Slots" - HOTSPOT_BLANK_SCROLL_BOX = "Hotspot: Blank Scroll Box" - HOTSPOT_BLINDS = "Hotspot: Blinds" - HOTSPOT_CANDY_MACHINE_BUTTONS = "Hotspot: Candy Machine Buttons" - HOTSPOT_CANDY_MACHINE_COIN_SLOT = "Hotspot: Candy Machine Coin Slot" - HOTSPOT_CANDY_MACHINE_VACUUM_SLOT = "Hotspot: Candy Machine Vacuum Slot" - HOTSPOT_CHANGE_MACHINE_SLOT = "Hotspot: Change Machine Slot" - HOTSPOT_CLOSET_DOOR = "Hotspot: Closet Door" - HOTSPOT_CLOSING_THE_TIME_TUNNELS_HAMMER_SLOT = "Hotspot: Closing the Time Tunnels Hammer Slot" - HOTSPOT_CLOSING_THE_TIME_TUNNELS_LEVER = "Hotspot: Closing the Time Tunnels Lever" - HOTSPOT_COOKING_POT = "Hotspot: Cooking Pot" - HOTSPOT_DENTED_LOCKER = "Hotspot: Dented Locker" - HOTSPOT_DIRT_MOUND = "Hotspot: Dirt Mound" - HOTSPOT_DOCK_WINCH = "Hotspot: Dock Winch" - HOTSPOT_DRAGON_CLAW = "Hotspot: Dragon Claw" - HOTSPOT_DRAGON_NOSTRILS = "Hotspot: Dragon Nostrils" - HOTSPOT_DUNGEON_MASTERS_LAIR_ENTRANCE = "Hotspot: Dungeon Master's Lair Entrance" - HOTSPOT_FLOOD_CONTROL_BUTTONS = "Hotspot: Flood Control Buttons" - HOTSPOT_FLOOD_CONTROL_DOORS = "Hotspot: Flood Control Doors" - HOTSPOT_FROZEN_TREAT_MACHINE_COIN_SLOT = "Hotspot: Frozen Treat Machine Coin Slot" - HOTSPOT_FROZEN_TREAT_MACHINE_DOORS = "Hotspot: Frozen Treat Machine Doors" - HOTSPOT_GLASS_CASE = "Hotspot: Glass Case" - HOTSPOT_GRAND_INQUISITOR_DOLL = "Hotspot: Grand Inquisitor Doll" - HOTSPOT_GUE_TECH_DOOR = "Hotspot: GUE Tech Door" - HOTSPOT_GUE_TECH_GRASS = "Hotspot: GUE Tech Grass" - HOTSPOT_HADES_PHONE_BUTTONS = "Hotspot: Hades Phone Buttons" - HOTSPOT_HADES_PHONE_RECEIVER = "Hotspot: Hades Phone Receiver" - HOTSPOT_HARRY = "Hotspot: Harry" - HOTSPOT_HARRYS_ASHTRAY = "Hotspot: Harry's Ashtray" - HOTSPOT_HARRYS_BIRD_BATH = "Hotspot: Harry's Bird Bath" - HOTSPOT_IN_MAGIC_WE_TRUST_DOOR = "Hotspot: In Magic We Trust Door" - HOTSPOT_JACKS_DOOR = "Hotspot: Jack's Door" - HOTSPOT_LOUDSPEAKER_VOLUME_BUTTONS = "Hotspot: Loudspeaker Volume Buttons" - HOTSPOT_MAILBOX_DOOR = "Hotspot: Mailbox Door" - HOTSPOT_MAILBOX_FLAG = "Hotspot: Mailbox Flag" - HOTSPOT_MIRROR = "Hotspot: Mirror" - HOTSPOT_MONASTERY_VENT = "Hotspot: Monastery Vent" - HOTSPOT_MOSSY_GRATE = "Hotspot: Mossy Grate" - HOTSPOT_PORT_FOOZLE_PAST_TAVERN_DOOR = "Hotspot: Port Foozle Past Tavern Door" - HOTSPOT_PURPLE_WORDS = "Hotspot: Purple Words" - HOTSPOT_QUELBEE_HIVE = "Hotspot: Quelbee Hive" - HOTSPOT_ROPE_BRIDGE = "Hotspot: Rope Bridge" - HOTSPOT_SKULL_CAGE = "Hotspot: Skull Cage" - HOTSPOT_SNAPDRAGON = "Hotspot: Snapdragon" - HOTSPOT_SODA_MACHINE_BUTTONS = "Hotspot: Soda Machine Buttons" - HOTSPOT_SODA_MACHINE_COIN_SLOT = "Hotspot: Soda Machine Coin Slot" - HOTSPOT_SOUVENIR_COIN_SLOT = "Hotspot: Souvenir Coin Slot" - HOTSPOT_SPELL_CHECKER = "Hotspot: Spell Checker" - HOTSPOT_SPELL_LAB_CHASM = "Hotspot: Spell Lab Chasm" - HOTSPOT_SPRING_MUSHROOM = "Hotspot: Spring Mushroom" - HOTSPOT_STUDENT_ID_MACHINE = "Hotspot: Student ID Machine" - HOTSPOT_SUBWAY_TOKEN_SLOT = "Hotspot: Subway Token Slot" - HOTSPOT_TAVERN_FLY = "Hotspot: Tavern Fly" - HOTSPOT_TOTEMIZER_SWITCH = "Hotspot: Totemizer Switch" - HOTSPOT_TOTEMIZER_WHEELS = "Hotspot: Totemizer Wheels" - HOTSPOT_WELL = "Hotspot: Well" - HUNGUS_LARD = "Hungus Lard" - JAR_OF_HOTBUGS = "Jar of Hotbugs" - LANTERN = "Lantern" - LARGE_TELEGRAPH_HAMMER = "Large Telegraph Hammer" - LUCYS_PLAYING_CARD_1 = "Lucy's Playing Card: 1 Pip" - LUCYS_PLAYING_CARD_2 = "Lucy's Playing Card: 2 Pips" - LUCYS_PLAYING_CARD_3 = "Lucy's Playing Card: 3 Pips" - LUCYS_PLAYING_CARD_4 = "Lucy's Playing Card: 4 Pips" - MAP = "Map" - MEAD_LIGHT = "Mead Light" - MOSS_OF_MAREILON = "Moss of Mareilon" - MUG = "Mug" - OLD_SCRATCH_CARD = "Old Scratch Card" - PERMA_SUCK_MACHINE = "Perma-Suck Machine" - PLASTIC_SIX_PACK_HOLDER = "Plastic Six-Pack Holder" - POUCH_OF_ZORKMIDS = "Pouch of Zorkmids" - PROZORK_TABLET = "Prozork Tablet" - QUELBEE_HONEYCOMB = "Quelbee Honeycomb" - ROPE = "Rope" - SCROLL_FRAGMENT_ANS = "Scroll Fragment: ANS" - SCROLL_FRAGMENT_GIV = "Scroll Fragment: GIV" - SHOVEL = "Shovel" - SNAPDRAGON = "Snapdragon" - SPELL_GLORF = "Spell: GLORF" - SPELL_GOLGATEM = "Spell: GOLGATEM" - SPELL_IGRAM = "Spell: IGRAM" - SPELL_KENDALL = "Spell: KENDALL" - SPELL_NARWILE = "Spell: NARWILE" - SPELL_REZROV = "Spell: REZROV" - SPELL_THROCK = "Spell: THROCK" - SPELL_VOXAM = "Spell: VOXAM" - STUDENT_ID = "Student ID" - SUBWAY_DESTINATION_FLOOD_CONTROL_DAM = "Subway Destination: Flood Control Dam #3" - SUBWAY_DESTINATION_HADES = "Subway Destination: Hades" - SUBWAY_DESTINATION_MONASTERY = "Subway Destination: Monastery" - SUBWAY_TOKEN = "Subway Token" - SWORD = "Sword" - TELEPORTER_DESTINATION_DM_LAIR = "Teleporter Destination: Dungeon Master's Lair" - TELEPORTER_DESTINATION_GUE_TECH = "Teleporter Destination: GUE Tech" - TELEPORTER_DESTINATION_HADES = "Teleporter Destination: Hades" - TELEPORTER_DESTINATION_MONASTERY = "Teleporter Destination: Monastery Station" - TELEPORTER_DESTINATION_SPELL_LAB = "Teleporter Destination: Spell Lab" - TOTEM_BROG = "Totem: Brog" - TOTEM_GRIFF = "Totem: Griff" - TOTEM_LUCY = "Totem: Lucy" - TOTEMIZER_DESTINATION_HALL_OF_INQUISITION = "Totemizer Destination: Hall of Inquisition" - TOTEMIZER_DESTINATION_INFINITY = "Totemizer Destination: Infinity" - TOTEMIZER_DESTINATION_STRAIGHT_TO_HELL = "Totemizer Destination: Straight to Hell" - TOTEMIZER_DESTINATION_SURFACE_OF_MERZ = "Totemizer Destination: Surface of Merz" - ZIMDOR_SCROLL = "ZIMDOR Scroll" - ZORK_ROCKS = "Zork Rocks" - - -class ZorkGrandInquisitorLocations(enum.Enum): - ALARM_SYSTEM_IS_DOWN = "Alarm System is Down" - ARREST_THE_VANDAL = "Arrest the Vandal!" - ARTIFACTS_EXPLAINED = "Artifacts, Explained" - A_BIG_FAT_SASSY_2_HEADED_MONSTER = "A Big, Fat, SASSY 2-Headed Monster" - A_LETTER_FROM_THE_WHITE_HOUSE = "A Letter from the White House" - A_SMALLWAY = "A Smallway" - BEAUTIFUL_THATS_PLENTY = "Beautiful, That's Plenty!" - BEBURTT_DEMYSTIFIED = "BEBURTT, Demystified" - BETTER_SPELL_MANUFACTURING_IN_UNDER_10_MINUTES = "Better Spell Manufacturing in Under 10 Minutes" - BOING_BOING_BOING = "Boing, Boing, Boing" - BONK = "Bonk!" - BRAVE_SOULS_WANTED = "Brave Souls Wanted" - BROG_DO_GOOD = "Brog Do Good!" - BROG_EAT_ROCKS = "Brog Eat Rocks" - BROG_KNOW_DUMB_THAT_DUMB = "Brog Know Dumb. That Dumb" - BROG_MUCH_BETTER_AT_THIS_GAME = "Brog Much Better at This Game" - CASTLE_WATCHING_A_FIELD_GUIDE = "Castle Watching: A Field Guide" - CAVES_NOTES = "Cave's Notes" - CLOSING_THE_TIME_TUNNELS = "Closing the Time Tunnels" - CRISIS_AVERTED = "Crisis Averted" - CUT_THAT_OUT_YOU_LITTLE_CREEP = "Cut That Out You Little Creep!" - DEATH_ARRESTED_WITH_JACK = "Death: Arrested With Jack" - DEATH_ATTACKED_THE_QUELBEES = "Death: Attacked the Quelbees" - DEATH_CLIMBED_OUT_OF_THE_WELL = "Death: Climbed Out of the Well" - DEATH_EATEN_BY_A_GRUE = "Death: Eaten by a Grue" - DEATH_JUMPED_IN_BOTTOMLESS_PIT = "Death: Jumped in Bottomless Pit" - DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER = "Death: Lost Game of Strip Grue, Fire, Water" - DEATH_LOST_SOUL_TO_OLD_SCRATCH = "Death: Lost Soul to Old Scratch" - DEATH_OUTSMARTED_BY_THE_QUELBEES = "Death: Outsmarted by the Quelbees" - DEATH_SLICED_UP_BY_THE_INVISIBLE_GUARD = "Death: Sliced up by the Invisible Guard" - DEATH_STEPPED_INTO_THE_INFINITE = "Death: Step Into the Infinite" - DEATH_SWALLOWED_BY_A_DRAGON = "Death: Swallowed by a Dragon" - DEATH_THROCKED_THE_GRASS = "Death: THROCKed the Grass" - DEATH_TOTEMIZED = "Death: Totemized?" - DEATH_TOTEMIZED_PERMANENTLY = "Death: Totemized... Permanently" - DEATH_YOURE_NOT_CHARON = "Death: You're Not Charon!?" - DEATH_ZORK_ROCKS_EXPLODED = "Death: Zork Rocks Exploded" - DENIED_BY_THE_LAKE_MONSTER = "Denied by the Lake Monster" - DESPERATELY_SEEKING_TUTOR = "Desperately Seeking Tutor" - DONT_EVEN_START_WITH_US_SPARKY = "Don't Even Start With Us, Sparky" - DOOOOOOWN = "Doooooown" - DOWN = "Down" - DRAGON_ARCHIPELAGO_TIME_TUNNEL = "Dragon Archipelago Time Tunnel" - DUNCE_LOCKER = "Dunce Locker" - EGGPLANTS = "Eggplants" - ELSEWHERE = "Elsewhere" - EMERGENCY_MAGICATRONIC_MESSAGE = "Emergency Magicatronic Message" - ENJOY_YOUR_TRIP = "Enjoy Your Trip!" - FAT_LOT_OF_GOOD_THATLL_DO_YA = "Fat Lot of Good That'll Do Ya" - FIRE_FIRE = "Fire! Fire!" - FLOOD_CONTROL_DAM_3_THE_NOT_REMOTELY_BORING_TALE = "Flood Control Dam #3: The Not Remotely Boring Tale" - FLYING_SNAPDRAGON = "Flying Snapdragon" - FROBUARY_3_UNDERGROUNDHOG_DAY = "Frobruary 3 - Undergroundhog Day" - GETTING_SOME_CHANGE = "Getting Some Change" - GO_AWAY = "GO AWAY!" - GUE_TECH_DEANS_LIST = "GUE Tech Dean's List" - GUE_TECH_ENTRANCE_EXAM = "GUE Tech Entrance Exam" - GUE_TECH_HEALTH_MEMO = "GUE Tech Health Memo" - GUE_TECH_MAGEMEISTERS = "GUE Tech Magemeisters" - HAVE_A_HELL_OF_A_DAY = "Have a Hell of a Day!" - HELLO_THIS_IS_SHONA_FROM_GURTH_PUBLISHING = "Hello, This is Shona from Gurth Publishing" - HELP_ME_CANT_BREATHE = "Help... Me. Can't... Breathe" - HEY_FREE_DIRT = "Hey, Free Dirt!" - HI_MY_NAME_IS_DOUG = "Hi, My Name is Doug" - HMMM_INFORMATIVE_YET_DEEPLY_DISTURBING = "Hmmm. Informative. Yet Deeply Disturbing" - HOLD_ON_FOR_AN_IMPORTANT_MESSAGE = "Hold on for an Important Message" - HOW_TO_HYPNOTIZE_YOURSELF = "How to Hypnotize Yourself" - HOW_TO_WIN_AT_DOUBLE_FANUCCI = "How to Win at Double Fanucci" - IMBUE_BEBURTT = "Imbue BEBURTT" - IM_COMPLETELY_NUDE = "I'm Completely Nude" - INTO_THE_FOLIAGE = "Into the Foliage" - INVISIBLE_FLOWERS = "Invisible Flowers" - IN_CASE_OF_ADVENTURE = "In Case of Adventure, Break Glass!" - IN_MAGIC_WE_TRUST = "In Magic We Trust" - ITS_ONE_OF_THOSE_ADVENTURERS_AGAIN = "It's One of Those Adventurers Again..." - I_DONT_THINK_YOU_WOULDVE_WANTED_THAT_TO_WORK_ANYWAY = "I Don't Think You Would've Wanted That to Work Anyway" - I_DONT_WANT_NO_TROUBLE = "I Don't Want No Trouble!" - I_HOPE_YOU_CAN_CLIMB_UP_THERE = "I Hope You Can Climb Up There With All This Junk" - I_LIKE_YOUR_STYLE = "I Like Your Style!" - I_SPIT_ON_YOUR_FILTHY_COINAGE = "I Spit on Your Filthy Coinage" - LIT_SUNFLOWERS = "Lit Sunflowers" - MAGIC_FOREVER = "Magic Forever!" - MAILED_IT_TO_HELL = "Mailed it to Hell" - MAKE_LOVE_NOT_WAR = "Make Love, Not War" - MEAD_LIGHT = "Mead Light?" - MIKES_PANTS = "Mike's Pants" - MUSHROOM_HAMMERED = "Mushroom, Hammered" - NATIONAL_TREASURE = "300 Year Old National Treasure" - NATURAL_AND_SUPERNATURAL_CREATURES_OF_QUENDOR = "Natural and Supernatural Creatures of Quendor" - NOOOOOOOOOOOOO = "NOOOOOOOOOOOOO!" - NOTHIN_LIKE_A_GOOD_STOGIE = "Nothin' Like a Good Stogie" - NOW_YOU_LOOK_LIKE_US_WHICH_IS_AN_IMPROVEMENT = "Now You Look Like Us, Which is an Improvement" - NO_AUTOGRAPHS = "No Autographs" - NO_BONDAGE = "No Bondage" - OBIDIL_DRIED_UP = "OBIDIL, Dried Up" - OH_DEAR_GOD_ITS_A_DRAGON = "Oh Dear God, It's a Dragon!" - OH_VERY_FUNNY_GUYS = "Oh, Very Funny Guys" - OH_WOW_TALK_ABOUT_DEJA_VU = "Oh, Wow! Talk About Deja Vu" - OLD_SCRATCH_WINNER = "Old Scratch Winner!" - ONLY_YOU_CAN_PREVENT_FOOZLE_FIRES = "Only You Can Prevent Foozle Fires" - OPEN_THE_GATES_OF_HELL = "Open the Gates of Hell" - OUTSMART_THE_QUELBEES = "Outsmart the Quelbees" - PERMASEAL = "PermaSeal" - PLANETFALL = "Planetfall" - PLEASE_DONT_THROCK_THE_GRASS = "Please Don't THROCK the Grass" - PORT_FOOZLE_TIME_TUNNEL = "Port Foozle Time Tunnel" - PROZORKED = "Prozorked" - REASSEMBLE_SNAVIG = "Reassemble SNAVIG" - RESTOCKED_ON_GRUESDAY = "Restocked on Gruesday" - RIGHT_HELLO_YES_UH_THIS_IS_SNEFFLE = "Right. Hello. Yes. Uh, This is Sneffle" - RIGHT_UH_SORRY_ITS_ME_AGAIN_SNEFFLE = "Right. Uh, Sorry. It's Me Again. Sneffle" - SNAVIG_REPAIRED = "SNAVIG, Repaired" - SOUVENIR = "Souvenir" - STRAIGHT_TO_HELL = "Straight to Hell" - STRIP_GRUE_FIRE_WATER = "Strip Grue, Fire, Water" - SUCKING_ROCKS = "Sucking Rocks" - TALK_TO_ME_GRAND_INQUISITOR = "Talk to Me Grand Inquisitor" - TAMING_YOUR_SNAPDRAGON = "Taming Your Snapdragon" - THAR_SHE_BLOWS = "Thar She Blows!" - THATS_A_ROPE = "That's a Rope" - THATS_IT_JUST_KEEP_HITTING_THOSE_BUTTONS = "That's it! Just Keep Hitting Those Buttons" - THATS_STILL_A_ROPE = "That's Still a Rope" - THATS_THE_SPIRIT = "That's the Spirit!" - THE_ALCHEMICAL_DEBACLE = "The Alchemical Debacle" - THE_ENDLESS_FIRE = "The Endless Fire" - THE_FLATHEADIAN_FUDGE_FIASCO = "The Flatheadian Fudge Fiasco" - THE_PERILS_OF_MAGIC = "The Perils of Magic" - THE_UNDERGROUND_UNDERGROUND = "The Underground Underground" - THIS_DOESNT_LOOK_ANYTHING_LIKE_THE_BROCHURE = "This Doesn't Look Anything Like the Brochure" - THROCKED_MUSHROOM_HAMMERED = "THROCKed Mushroom, Hammered" - TIME_TRAVEL_FOR_DUMMIES = "Time Travel for Dummies" - TOTEMIZED_DAILY_BILLBOARD = "Totemized Daily Billboard Functioning Correctly" - UH_OH_BROG_CANT_SWIM = "Uh-Oh. Brog Can't Swim" - UMBRELLA_FLOWERS = "Umbrella Flowers" - UP = "Up" - USELESS_BUT_FUN = "Useless, But Fun" - UUUUUP = "Uuuuup" - VOYAGE_OF_CAPTAIN_ZAHAB = "Voyage of Captain Zahab" - WANT_SOME_RYE_COURSE_YA_DO = "Want Some Rye? Course Ya Do!" - WE_DONT_SERVE_YOUR_KIND_HERE = "We Don't Serve Your Kind Here" - WE_GOT_A_HIGH_ROLLER = "We Got a High Roller!" - WHAT_ARE_YOU_STUPID = "What Are You, Stupid?" - WHITE_HOUSE_TIME_TUNNEL = "White House Time Tunnel" - WOW_IVE_NEVER_GONE_INSIDE_HIM_BEFORE = "Wow! I've Never Gone Inside Him Before!" - YAD_GOHDNUORGREDNU_3_YRAUBORF = "yaD gohdnuorgrednU - 3 yrauborF" - YOUR_PUNY_WEAPONS_DONT_PHASE_ME_BABY = "Your Puny Weapons Don't Phase Me, Baby!" - YOU_DONT_GO_MESSING_WITH_A_MANS_ZIPPER = "You Don't Go Messing With a Man's Zipper" - YOU_GAINED_86_EXPERIENCE_POINTS = "You Gained 86 Experience Points" - YOU_ONE_OF_THEM_AGITATORS_AINT_YA = "You One of Them Agitators, Ain't Ya?" - YOU_WANT_A_PIECE_OF_ME_DOCK_BOY = "You Want a Piece of Me, Dock Boy? or Girl" - - -class ZorkGrandInquisitorRegions(enum.Enum): - CROSSROADS = "Crossroads" - DM_LAIR = "Dungeon Master's Lair" - DM_LAIR_INTERIOR = "Dungeon Master's Lair - Interior" - DRAGON_ARCHIPELAGO = "Dragon Archipelago" - DRAGON_ARCHIPELAGO_DRAGON = "Dragon Archipelago - Dragon" - ENDGAME = "Endgame" - GUE_TECH = "GUE Tech" - GUE_TECH_HALLWAY = "GUE Tech - Hallway" - GUE_TECH_OUTSIDE = "GUE Tech - Outside" - HADES = "Hades" - HADES_BEYOND_GATES = "Hades - Beyond Gates" - HADES_SHORE = "Hades - Shore" - MENU = "Menu" - MONASTERY = "Monastery" - MONASTERY_EXHIBIT = "Monastery - Exhibit" - PORT_FOOZLE = "Port Foozle" - PORT_FOOZLE_JACKS_SHOP = "Port Foozle - Jack's Shop" - PORT_FOOZLE_PAST = "Port Foozle Past" - PORT_FOOZLE_PAST_TAVERN = "Port Foozle Past - Tavern" - SPELL_LAB = "Spell Lab" - SPELL_LAB_BRIDGE = "Spell Lab - Bridge" - SUBWAY_CROSSROADS = "Subway Platform - Crossroads" - SUBWAY_FLOOD_CONTROL_DAM = "Subway Platform - Flood Control Dam #3" - SUBWAY_MONASTERY = "Subway Platform - Monastery" - WALKING_CASTLE = "Walking Castle" - WHITE_HOUSE = "White House" - - -class ZorkGrandInquisitorTags(enum.Enum): - CORE = "Core" - DEATHSANITY = "Deathsanity" - FILLER = "Filler" - HOTSPOT = "Hotspot" - INVENTORY_ITEM = "Inventory Item" - MISSABLE = "Missable" - SPELL = "Spell" - SUBWAY_DESTINATION = "Subway Destination" - TELEPORTER_DESTINATION = "Teleporter Destination" - TOTEMIZER_DESTINATION = "Totemizer Destination" - TOTEM = "Totem" diff --git a/worlds/zork_grand_inquisitor/game_controller.py b/worlds/zork_grand_inquisitor/game_controller.py deleted file mode 100644 index 7a60a1460829..000000000000 --- a/worlds/zork_grand_inquisitor/game_controller.py +++ /dev/null @@ -1,1388 +0,0 @@ -import collections -import functools -import logging - -from typing import Dict, Optional, Set, Tuple, Union - -from .data.item_data import item_data, ZorkGrandInquisitorItemData -from .data.location_data import location_data, ZorkGrandInquisitorLocationData - -from .data.missable_location_grant_conditions_data import ( - missable_location_grant_conditions_data, - ZorkGrandInquisitorMissableLocationGrantConditionsData, -) - -from .data_funcs import game_id_to_items, items_with_tag, locations_with_tag - -from .enums import ( - ZorkGrandInquisitorGoals, - ZorkGrandInquisitorItems, - ZorkGrandInquisitorLocations, - ZorkGrandInquisitorTags, -) - -from .game_state_manager import GameStateManager - - -class GameController: - logger: Optional[logging.Logger] - - game_state_manager: GameStateManager - - received_items: Set[ZorkGrandInquisitorItems] - completed_locations: Set[ZorkGrandInquisitorLocations] - - completed_locations_queue: collections.deque - received_items_queue: collections.deque - - all_hotspot_items: Set[ZorkGrandInquisitorItems] - - game_id_to_items: Dict[int, ZorkGrandInquisitorItems] - - possible_inventory_items: Set[ZorkGrandInquisitorItems] - - available_inventory_slots: Set[int] - - goal_completed: bool - - option_goal: Optional[ZorkGrandInquisitorGoals] - option_deathsanity: Optional[bool] - option_grant_missable_location_checks: Optional[bool] - - def __init__(self, logger=None) -> None: - self.logger = logger - - self.game_state_manager = GameStateManager() - - self.received_items = set() - self.completed_locations = set() - - self.completed_locations_queue = collections.deque() - self.received_items_queue = collections.deque() - - self.all_hotspot_items = ( - items_with_tag(ZorkGrandInquisitorTags.HOTSPOT) - | items_with_tag(ZorkGrandInquisitorTags.SUBWAY_DESTINATION) - | items_with_tag(ZorkGrandInquisitorTags.TOTEMIZER_DESTINATION) - ) - - self.game_id_to_items = game_id_to_items() - - self.possible_inventory_items = ( - items_with_tag(ZorkGrandInquisitorTags.INVENTORY_ITEM) - | items_with_tag(ZorkGrandInquisitorTags.SPELL) - | items_with_tag(ZorkGrandInquisitorTags.TOTEM) - ) - - self.available_inventory_slots = set() - - self.goal_completed = False - - self.option_goal = None - self.option_deathsanity = None - self.option_grant_missable_location_checks = None - - @functools.cached_property - def brog_items(self) -> Set[ZorkGrandInquisitorItems]: - return { - ZorkGrandInquisitorItems.BROGS_BICKERING_TORCH, - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH, - ZorkGrandInquisitorItems.BROGS_GRUE_EGG, - ZorkGrandInquisitorItems.BROGS_PLANK, - } - - @functools.cached_property - def griff_items(self) -> Set[ZorkGrandInquisitorItems]: - return { - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP, - ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN, - } - - @functools.cached_property - def lucy_items(self) -> Set[ZorkGrandInquisitorItems]: - return { - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4, - } - - @property - def totem_items(self) -> Set[ZorkGrandInquisitorItems]: - return self.brog_items | self.griff_items | self.lucy_items - - @functools.cached_property - def missable_locations(self) -> Set[ZorkGrandInquisitorLocations]: - return locations_with_tag(ZorkGrandInquisitorTags.MISSABLE) - - def log(self, message) -> None: - if self.logger: - self.logger.info(message) - - def log_debug(self, message) -> None: - if self.logger: - self.logger.debug(message) - - def open_process_handle(self) -> bool: - return self.game_state_manager.open_process_handle() - - def close_process_handle(self) -> bool: - return self.game_state_manager.close_process_handle() - - def is_process_running(self) -> bool: - return self.game_state_manager.is_process_running - - def list_received_brog_items(self) -> None: - self.log("Received Brog Items:") - - self._process_received_items() - received_brog_items: Set[ZorkGrandInquisitorItems] = self.received_items & self.brog_items - - if not len(received_brog_items): - self.log(" Nothing") - return - - for item in sorted(i.value for i in received_brog_items): - self.log(f" {item}") - - def list_received_griff_items(self) -> None: - self.log("Received Griff Items:") - - self._process_received_items() - received_griff_items: Set[ZorkGrandInquisitorItems] = self.received_items & self.griff_items - - if not len(received_griff_items): - self.log(" Nothing") - return - - for item in sorted(i.value for i in received_griff_items): - self.log(f" {item}") - - def list_received_lucy_items(self) -> None: - self.log("Received Lucy Items:") - - self._process_received_items() - received_lucy_items: Set[ZorkGrandInquisitorItems] = self.received_items & self.lucy_items - - if not len(received_lucy_items): - self.log(" Nothing") - return - - for item in sorted(i.value for i in received_lucy_items): - self.log(f" {item}") - - def list_received_hotspots(self) -> None: - self.log("Received Hotspots:") - - self._process_received_items() - - hotspot_items: Set[ZorkGrandInquisitorItems] = items_with_tag(ZorkGrandInquisitorTags.HOTSPOT) - received_hotspots: Set[ZorkGrandInquisitorItems] = self.received_items & hotspot_items - - if not len(received_hotspots): - self.log(" Nothing") - return - - for item in sorted(i.value for i in received_hotspots): - self.log(f" {item}") - - def update(self) -> None: - if self.game_state_manager.is_process_still_running(): - try: - self.game_state_manager.refresh_game_location() - - self._apply_permanent_game_state() - self._apply_conditional_game_state() - - self._apply_permanent_game_flags() - - self._check_for_completed_locations() - - if self.option_grant_missable_location_checks: - self._check_for_missable_locations_to_grant() - - self._process_received_items() - - self._manage_hotspots() - self._manage_items() - - self._apply_conditional_teleports() - - self._check_for_victory() - except Exception as e: - self.log_debug(e) - - def _apply_permanent_game_state(self) -> None: - self._write_game_state_value_for(10934, 1) # Rope Taken - self._write_game_state_value_for(10418, 1) # Mead Light Taken - self._write_game_state_value_for(10275, 0) # Lantern in Crate - self._write_game_state_value_for(13929, 1) # Great Underground Door Open - self._write_game_state_value_for(13968, 1) # Subway Token Taken - self._write_game_state_value_for(12930, 1) # Hammer Taken - self._write_game_state_value_for(12935, 1) # Griff Totem Taken - self._write_game_state_value_for(12948, 1) # ZIMDOR Scroll Taken - self._write_game_state_value_for(4058, 1) # Shovel Taken - self._write_game_state_value_for(4059, 1) # THROCK Scroll Taken - self._write_game_state_value_for(11758, 1) # KENDALL Scroll Taken - self._write_game_state_value_for(16959, 1) # Old Scratch Card Taken - self._write_game_state_value_for(12840, 0) # Zork Rocks in Perma-Suck Machine - self._write_game_state_value_for(11886, 1) # Student ID Taken - self._write_game_state_value_for(16279, 1) # Prozork Tablet Taken - self._write_game_state_value_for(13260, 1) # GOLGATEM Scroll Taken - self._write_game_state_value_for(4834, 1) # Flatheadia Fudge Taken - self._write_game_state_value_for(4746, 1) # Jar of Hotbugs Taken - self._write_game_state_value_for(4755, 1) # Hungus Lard Taken - self._write_game_state_value_for(4758, 1) # Mug Taken - self._write_game_state_value_for(3716, 1) # NARWILE Scroll Taken - self._write_game_state_value_for(17147, 1) # Lucy Totem Taken - self._write_game_state_value_for(9818, 1) # Middle Telegraph Hammer Taken - self._write_game_state_value_for(3766, 0) # ANS Scroll in Window - self._write_game_state_value_for(4980, 0) # ANS Scroll in Window - self._write_game_state_value_for(3768, 0) # GIV Scroll in Window - self._write_game_state_value_for(4978, 0) # GIV Scroll in Window - self._write_game_state_value_for(3765, 0) # SNA Scroll in Window - self._write_game_state_value_for(4979, 0) # SNA Scroll in Window - self._write_game_state_value_for(3767, 0) # VIG Scroll in Window - self._write_game_state_value_for(4977, 0) # VIG Scroll in Window - self._write_game_state_value_for(15065, 1) # Brog's Bickering Torch Taken - self._write_game_state_value_for(15088, 1) # Brog's Flickering Torch Taken - self._write_game_state_value_for(2628, 4) # Brog's Grue Eggs Taken - self._write_game_state_value_for(2971, 1) # Brog's Plank Taken - self._write_game_state_value_for(1340, 1) # Griff's Inflatable Sea Captain Taken - self._write_game_state_value_for(1341, 1) # Griff's Inflatable Raft Taken - self._write_game_state_value_for(1477, 1) # Griff's Air Pump Taken - self._write_game_state_value_for(1814, 1) # Griff's Dragon Tooth Taken - self._write_game_state_value_for(15403, 0) # Lucy's Cards Taken - self._write_game_state_value_for(15404, 1) # Lucy's Cards Taken - self._write_game_state_value_for(15405, 4) # Lucy's Cards Taken - self._write_game_state_value_for(5222, 1) # User Has Spell Book - self._write_game_state_value_for(13930, 1) # Skip Well Cutscenes - self._write_game_state_value_for(19057, 1) # Skip Well Cutscenes - self._write_game_state_value_for(13934, 1) # Skip Well Cutscenes - self._write_game_state_value_for(13935, 1) # Skip Well Cutscenes - self._write_game_state_value_for(13384, 1) # Skip Meanwhile... Cutscene - self._write_game_state_value_for(8620, 1) # First Coin Paid to Charon - self._write_game_state_value_for(8731, 1) # First Coin Paid to Charon - - def _apply_conditional_game_state(self): - # Can teleport to Dungeon Master's Lair - if self._player_has(ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR): - self._write_game_state_value_for(2203, 1) - else: - self._write_game_state_value_for(2203, 0) - - # Can teleport to GUE Tech - if self._player_has(ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH): - self._write_game_state_value_for(7132, 1) - else: - self._write_game_state_value_for(7132, 0) - - # Can Teleport to Spell Lab - if self._player_has(ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB): - self._write_game_state_value_for(16545, 1) - else: - self._write_game_state_value_for(16545, 0) - - # Can Teleport to Hades - if self._player_has(ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES): - self._write_game_state_value_for(7119, 1) - else: - self._write_game_state_value_for(7119, 0) - - # Can Teleport to Monastery Station - if self._player_has(ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY): - self._write_game_state_value_for(7148, 1) - else: - self._write_game_state_value_for(7148, 0) - - # Initial Totemizer Destination - should_force_initial_totemizer_destination: bool = True - - if self._player_has(ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_HALL_OF_INQUISITION): - should_force_initial_totemizer_destination = False - elif self._player_has(ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_STRAIGHT_TO_HELL): - should_force_initial_totemizer_destination = False - elif self._player_has(ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_INFINITY): - should_force_initial_totemizer_destination = False - elif self._player_has(ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_SURFACE_OF_MERZ): - should_force_initial_totemizer_destination = False - - if should_force_initial_totemizer_destination: - self._write_game_state_value_for(9617, 2) - - # Pouch of Zorkmids - if self._player_has(ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS): - self._write_game_state_value_for(5827, 1) - else: - self._write_game_state_value_for(5827, 0) - - # Brog Torches - if self._player_is_brog() and self._player_has(ZorkGrandInquisitorItems.BROGS_BICKERING_TORCH): - self._write_game_state_value_for(10999, 1) - else: - self._write_game_state_value_for(10999, 0) - - if self._player_is_brog() and self._player_has(ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH): - self._write_game_state_value_for(10998, 1) - else: - self._write_game_state_value_for(10998, 0) - - # Monastery Rope - if ZorkGrandInquisitorLocations.I_HOPE_YOU_CAN_CLIMB_UP_THERE in self.completed_locations: - self._write_game_state_value_for(9637, 1) - - def _apply_permanent_game_flags(self) -> None: - self._write_game_flags_value_for(9437, 2) # Monastery Exhibit Door to Outside - self._write_game_flags_value_for(3074, 2) # White House Door - self._write_game_flags_value_for(13005, 2) # Map - self._write_game_flags_value_for(13006, 2) # Sword - self._write_game_flags_value_for(13007, 2) # Sword - self._write_game_flags_value_for(13389, 2) # Moss of Mareilon - self._write_game_flags_value_for(4301, 2) # Quelbee Honeycomb - self._write_game_flags_value_for(12895, 2) # Change Machine Money - self._write_game_flags_value_for(4150, 2) # Prozorked Snapdragon - self._write_game_flags_value_for(13413, 2) # Letter Opener - self._write_game_flags_value_for(15403, 2) # Lucy's Cards - - def _check_for_completed_locations(self) -> None: - location: ZorkGrandInquisitorLocations - data: ZorkGrandInquisitorLocationData - for location, data in location_data.items(): - if location in self.completed_locations or not isinstance( - location, ZorkGrandInquisitorLocations - ): - continue - - is_location_completed: bool = True - - trigger: [Union[str, int]] - value: Union[str, int, Tuple[int, ...]] - for trigger, value in data.game_state_trigger: - if trigger == "location": - if not self._player_is_at(value): - is_location_completed = False - break - elif isinstance(trigger, int): - if isinstance(value, int): - if self._read_game_state_value_for(trigger) != value: - is_location_completed = False - break - elif isinstance(value, tuple): - if self._read_game_state_value_for(trigger) not in value: - is_location_completed = False - break - else: - is_location_completed = False - break - else: - is_location_completed = False - break - - if is_location_completed: - self.completed_locations.add(location) - self.completed_locations_queue.append(location) - - def _check_for_missable_locations_to_grant(self) -> None: - missable_location: ZorkGrandInquisitorLocations - for missable_location in self.missable_locations: - if missable_location in self.completed_locations: - continue - - data: ZorkGrandInquisitorLocationData = location_data[missable_location] - - if ZorkGrandInquisitorTags.DEATHSANITY in data.tags and not self.option_deathsanity: - continue - - condition_data: ZorkGrandInquisitorMissableLocationGrantConditionsData = ( - missable_location_grant_conditions_data.get(missable_location) - ) - - if condition_data is None: - self.log_debug(f"Missable Location {missable_location.value} has no grant conditions") - continue - - if condition_data.location_condition in self.completed_locations: - grant_location: bool = True - - item: ZorkGrandInquisitorItems - for item in condition_data.item_conditions or tuple(): - if self._player_doesnt_have(item): - grant_location = False - break - - if grant_location: - self.completed_locations_queue.append(missable_location) - - def _process_received_items(self) -> None: - while len(self.received_items_queue) > 0: - item: ZorkGrandInquisitorItems = self.received_items_queue.popleft() - data: ZorkGrandInquisitorItemData = item_data[item] - - if ZorkGrandInquisitorTags.FILLER in data.tags: - continue - - self.received_items.add(item) - - def _manage_hotspots(self) -> None: - hotspot_item: ZorkGrandInquisitorItems - for hotspot_item in self.all_hotspot_items: - data: ZorkGrandInquisitorItemData = item_data[hotspot_item] - - if hotspot_item not in self.received_items: - key: int - for key in data.statemap_keys: - self._write_game_flags_value_for(key, 2) - else: - if hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_666_MAILBOX: - if self.game_state_manager.game_location == "hp5g": - if self._read_game_state_value_for(9113) == 0: - self._write_game_flags_value_for(9116, 0) - else: - self._write_game_flags_value_for(9116, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS: - if self.game_state_manager.game_location == "qb2g": - if self._read_game_state_value_for(15433) == 0: - self._write_game_flags_value_for(15434, 0) - else: - self._write_game_flags_value_for(15434, 2) - - if self._read_game_state_value_for(15435) == 0: - self._write_game_flags_value_for(15436, 0) - else: - self._write_game_flags_value_for(15436, 2) - - if self._read_game_state_value_for(15437) == 0: - self._write_game_flags_value_for(15438, 0) - else: - self._write_game_flags_value_for(15438, 2) - - if self._read_game_state_value_for(15439) == 0: - self._write_game_flags_value_for(15440, 0) - else: - self._write_game_flags_value_for(15440, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_BLANK_SCROLL_BOX: - if self.game_state_manager.game_location == "tp2g": - if self._read_game_state_value_for(12095) == 1: - self._write_game_flags_value_for(9115, 2) - else: - self._write_game_flags_value_for(9115, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_BLINDS: - if self.game_state_manager.game_location == "dv1e": - if self._read_game_state_value_for(4743) == 0: - self._write_game_flags_value_for(4799, 0) - else: - self._write_game_flags_value_for(4799, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_BUTTONS: - if self.game_state_manager.game_location == "tr5g": - key: int - for key in data.statemap_keys: - self._write_game_flags_value_for(key, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_COIN_SLOT: - if self.game_state_manager.game_location == "tr5g": - self._write_game_flags_value_for(12702, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_VACUUM_SLOT: - if self.game_state_manager.game_location == "tr5m": - self._write_game_flags_value_for(12909, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_CHANGE_MACHINE_SLOT: - if self.game_state_manager.game_location == "tr5j": - if self._read_game_state_value_for(12892) == 0: - self._write_game_flags_value_for(12900, 0) - else: - self._write_game_flags_value_for(12900, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_CLOSET_DOOR: - if self.game_state_manager.game_location == "dw1e": - if self._read_game_state_value_for(4983) == 0: - self._write_game_flags_value_for(5010, 0) - else: - self._write_game_flags_value_for(5010, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_HAMMER_SLOT: - if self.game_state_manager.game_location == "me2j": - if self._read_game_state_value_for(9491) == 2: - self._write_game_flags_value_for(9539, 0) - else: - self._write_game_flags_value_for(9539, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_LEVER: - if self.game_state_manager.game_location == "me2j": - if self._read_game_state_value_for(9546) == 2 or self._read_game_state_value_for(9419) == 1: - self._write_game_flags_value_for(19712, 2) - else: - self._write_game_flags_value_for(19712, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT: - if self.game_state_manager.game_location == "sg1f": - self._write_game_flags_value_for(2586, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_DENTED_LOCKER: - if self.game_state_manager.game_location == "th3j": - five_is_open: bool = self._read_game_state_value_for(11847) == 1 - six_is_open: bool = self._read_game_state_value_for(11840) == 1 - seven_is_open: bool = self._read_game_state_value_for(11841) == 1 - eight_is_open: bool = self._read_game_state_value_for(11848) == 1 - - rocks_in_six: bool = self._read_game_state_value_for(11769) == 1 - six_blasted: bool = self._read_game_state_value_for(11770) == 1 - - if five_is_open or six_is_open or seven_is_open or eight_is_open or rocks_in_six or six_blasted: - self._write_game_flags_value_for(11878, 2) - else: - self._write_game_flags_value_for(11878, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_DIRT_MOUND: - if self.game_state_manager.game_location == "te5e": - if self._read_game_state_value_for(11747) == 0: - self._write_game_flags_value_for(11751, 0) - else: - self._write_game_flags_value_for(11751, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_DOCK_WINCH: - if self.game_state_manager.game_location == "pe2e": - self._write_game_flags_value_for(15147, 0) - self._write_game_flags_value_for(15153, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_DRAGON_CLAW: - if self.game_state_manager.game_location == "cd70": - self._write_game_flags_value_for(1705, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS: - if self.game_state_manager.game_location == "cd3h": - raft_in_left: bool = self._read_game_state_value_for(1301) == 1 - raft_in_right: bool = self._read_game_state_value_for(1304) == 1 - raft_inflated: bool = self._read_game_state_value_for(1379) == 1 - - captain_in_left: bool = self._read_game_state_value_for(1374) == 1 - captain_in_right: bool = self._read_game_state_value_for(1381) == 1 - captain_inflated: bool = self._read_game_state_value_for(1378) == 1 - - left_inflated: bool = (raft_in_left and raft_inflated) or (captain_in_left and captain_inflated) - - right_inflated: bool = (raft_in_right and raft_inflated) or ( - captain_in_right and captain_inflated - ) - - if left_inflated: - self._write_game_flags_value_for(1425, 2) - else: - self._write_game_flags_value_for(1425, 0) - - if right_inflated: - self._write_game_flags_value_for(1426, 2) - else: - self._write_game_flags_value_for(1426, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_DUNGEON_MASTERS_LAIR_ENTRANCE: - if self.game_state_manager.game_location == "uc3e": - if self._read_game_state_value_for(13060) == 0: - self._write_game_flags_value_for(13106, 0) - else: - self._write_game_flags_value_for(13106, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_BUTTONS: - if self.game_state_manager.game_location == "ue1e": - if self._read_game_state_value_for(14318) == 0: - self._write_game_flags_value_for(13219, 0) - self._write_game_flags_value_for(13220, 0) - self._write_game_flags_value_for(13221, 0) - self._write_game_flags_value_for(13222, 0) - else: - self._write_game_flags_value_for(13219, 2) - self._write_game_flags_value_for(13220, 2) - self._write_game_flags_value_for(13221, 2) - self._write_game_flags_value_for(13222, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_DOORS: - if self.game_state_manager.game_location == "ue1e": - if self._read_game_state_value_for(14318) == 0: - self._write_game_flags_value_for(14327, 0) - self._write_game_flags_value_for(14332, 0) - self._write_game_flags_value_for(14337, 0) - self._write_game_flags_value_for(14342, 0) - else: - self._write_game_flags_value_for(14327, 2) - self._write_game_flags_value_for(14332, 2) - self._write_game_flags_value_for(14337, 2) - self._write_game_flags_value_for(14342, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_FROZEN_TREAT_MACHINE_COIN_SLOT: - if self.game_state_manager.game_location == "tr5e": - self._write_game_flags_value_for(12528, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_FROZEN_TREAT_MACHINE_DOORS: - if self.game_state_manager.game_location == "tr5e": - if self._read_game_state_value_for(12220) == 0: - self._write_game_flags_value_for(12523, 2) - self._write_game_flags_value_for(12524, 2) - self._write_game_flags_value_for(12525, 2) - else: - self._write_game_flags_value_for(12523, 0) - self._write_game_flags_value_for(12524, 0) - self._write_game_flags_value_for(12525, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_GLASS_CASE: - if self.game_state_manager.game_location == "uc1g": - if self._read_game_state_value_for(12931) == 1 or self._read_game_state_value_for(12929) == 1: - self._write_game_flags_value_for(13002, 2) - else: - self._write_game_flags_value_for(13002, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL: - if self.game_state_manager.game_location == "pe5e": - if self._read_game_state_value_for(10277) == 0: - self._write_game_flags_value_for(10726, 0) - else: - self._write_game_flags_value_for(10726, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_GUE_TECH_DOOR: - if self.game_state_manager.game_location == "tr1k": - if self._read_game_state_value_for(12212) == 0: - self._write_game_flags_value_for(12280, 0) - else: - self._write_game_flags_value_for(12280, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_GUE_TECH_GRASS: - if self.game_state_manager.game_location in ("te10", "te1g", "te20", "te30", "te40"): - key: int - for key in data.statemap_keys: - self._write_game_flags_value_for(key, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_BUTTONS: - if self.game_state_manager.game_location == "hp1e": - if self._read_game_state_value_for(8431) == 1: - key: int - for key in data.statemap_keys: - self._write_game_flags_value_for(key, 0) - else: - key: int - for key in data.statemap_keys: - self._write_game_flags_value_for(key, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_RECEIVER: - if self.game_state_manager.game_location == "hp1e": - if self._read_game_state_value_for(8431) == 1: - self._write_game_flags_value_for(8446, 2) - else: - self._write_game_flags_value_for(8446, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_HARRY: - if self.game_state_manager.game_location == "dg4e": - if self._read_game_state_value_for(4237) == 1 and self._read_game_state_value_for(4034) == 1: - self._write_game_flags_value_for(4260, 2) - else: - self._write_game_flags_value_for(4260, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_HARRYS_ASHTRAY: - if self.game_state_manager.game_location == "dg4h": - if self._read_game_state_value_for(4279) == 1: - self._write_game_flags_value_for(18026, 2) - else: - self._write_game_flags_value_for(18026, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_HARRYS_BIRD_BATH: - if self.game_state_manager.game_location == "dg4g": - if self._read_game_state_value_for(4034) == 1: - self._write_game_flags_value_for(17623, 2) - else: - self._write_game_flags_value_for(17623, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_IN_MAGIC_WE_TRUST_DOOR: - if self.game_state_manager.game_location == "uc4e": - if self._read_game_state_value_for(13062) == 1: - self._write_game_flags_value_for(13140, 2) - else: - self._write_game_flags_value_for(13140, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR: - if self.game_state_manager.game_location == "pe1e": - if self._read_game_state_value_for(10451) == 1: - self._write_game_flags_value_for(10441, 2) - else: - self._write_game_flags_value_for(10441, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_LOUDSPEAKER_VOLUME_BUTTONS: - if self.game_state_manager.game_location == "pe2j": - self._write_game_flags_value_for(19632, 0) - self._write_game_flags_value_for(19627, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_DOOR: - if self.game_state_manager.game_location == "sw4e": - if self._read_game_state_value_for(2989) == 1: - self._write_game_flags_value_for(3025, 2) - else: - self._write_game_flags_value_for(3025, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_FLAG: - if self.game_state_manager.game_location == "sw4e": - self._write_game_flags_value_for(3036, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_MIRROR: - if self.game_state_manager.game_location == "dw1f": - self._write_game_flags_value_for(5031, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_MONASTERY_VENT: - if self.game_state_manager.game_location == "um1e": - if self._read_game_state_value_for(9637) == 0: - self._write_game_flags_value_for(13597, 0) - else: - self._write_game_flags_value_for(13597, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_MOSSY_GRATE: - if self.game_state_manager.game_location == "ue2g": - if self._read_game_state_value_for(13278) == 0: - self._write_game_flags_value_for(13390, 0) - else: - self._write_game_flags_value_for(13390, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_PORT_FOOZLE_PAST_TAVERN_DOOR: - if self.game_state_manager.game_location == "qe1e": - if self._player_is_brog(): - self._write_game_flags_value_for(2447, 0) - elif self._player_is_griff(): - self._write_game_flags_value_for(2455, 0) - elif self._player_is_lucy(): - if self._read_game_state_value_for(2457) == 0: - self._write_game_flags_value_for(2455, 0) - else: - self._write_game_flags_value_for(2455, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_PURPLE_WORDS: - if self.game_state_manager.game_location == "tr3h": - if self._read_game_state_value_for(11777) == 1: - self._write_game_flags_value_for(12389, 2) - else: - self._write_game_flags_value_for(12389, 0) - - self._write_game_state_value_for(12390, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_QUELBEE_HIVE: - if self.game_state_manager.game_location == "dg4f": - if self._read_game_state_value_for(4241) == 1: - self._write_game_flags_value_for(4302, 2) - else: - self._write_game_flags_value_for(4302, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_ROPE_BRIDGE: - if self.game_state_manager.game_location == "tp1e": - if self._read_game_state_value_for(16342) == 1: - self._write_game_flags_value_for(16383, 2) - self._write_game_flags_value_for(16384, 2) - else: - self._write_game_flags_value_for(16383, 0) - self._write_game_flags_value_for(16384, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_SKULL_CAGE: - if self.game_state_manager.game_location == "sg6e": - if self._read_game_state_value_for(15715) == 1: - self._write_game_flags_value_for(2769, 2) - else: - self._write_game_flags_value_for(2769, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_SNAPDRAGON: - if self.game_state_manager.game_location == "dg2f": - if self._read_game_state_value_for(4114) == 1 or self._read_game_state_value_for(4115) == 1: - self._write_game_flags_value_for(4149, 2) - else: - self._write_game_flags_value_for(4149, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_SODA_MACHINE_BUTTONS: - if self.game_state_manager.game_location == "tr5f": - self._write_game_flags_value_for(12584, 0) - self._write_game_flags_value_for(12585, 0) - self._write_game_flags_value_for(12586, 0) - self._write_game_flags_value_for(12587, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_SODA_MACHINE_COIN_SLOT: - if self.game_state_manager.game_location == "tr5f": - self._write_game_flags_value_for(12574, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_SOUVENIR_COIN_SLOT: - if self.game_state_manager.game_location == "ue2j": - if self._read_game_state_value_for(13408) == 1: - self._write_game_flags_value_for(13412, 2) - else: - self._write_game_flags_value_for(13412, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER: - if self.game_state_manager.game_location == "tp4g": - self._write_game_flags_value_for(12170, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_SPELL_LAB_CHASM: - if self.game_state_manager.game_location == "tp1e": - if self._read_game_state_value_for(16342) == 1 and self._read_game_state_value_for(16374) == 0: - self._write_game_flags_value_for(16382, 0) - else: - self._write_game_flags_value_for(16382, 2) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_SPRING_MUSHROOM: - if self.game_state_manager.game_location == "dg3e": - self._write_game_flags_value_for(4209, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_STUDENT_ID_MACHINE: - if self.game_state_manager.game_location == "th3r": - self._write_game_flags_value_for(11973, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_SUBWAY_TOKEN_SLOT: - if self.game_state_manager.game_location == "uc6e": - self._write_game_flags_value_for(13168, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY: - if self.game_state_manager.game_location == "qb2e": - if self._read_game_state_value_for(15395) == 1: - self._write_game_flags_value_for(15396, 2) - else: - self._write_game_flags_value_for(15396, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH: - if self.game_state_manager.game_location == "mt2e": - self._write_game_flags_value_for(9706, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_WHEELS: - if self.game_state_manager.game_location == "mt2g": - self._write_game_flags_value_for(9728, 0) - self._write_game_flags_value_for(9729, 0) - self._write_game_flags_value_for(9730, 0) - elif hotspot_item == ZorkGrandInquisitorItems.HOTSPOT_WELL: - if self.game_state_manager.game_location == "pc1e": - self._write_game_flags_value_for(10314, 0) - elif hotspot_item == ZorkGrandInquisitorItems.SUBWAY_DESTINATION_FLOOD_CONTROL_DAM: - if self.game_state_manager.game_location == "us2e": - self._write_game_flags_value_for(13757, 0) - elif self.game_state_manager.game_location == "ue2e": - self._write_game_flags_value_for(13297, 0) - elif self.game_state_manager.game_location == "uh2e": - self._write_game_flags_value_for(13486, 0) - elif self.game_state_manager.game_location == "um2e": - self._write_game_flags_value_for(13625, 0) - elif hotspot_item == ZorkGrandInquisitorItems.SUBWAY_DESTINATION_HADES: - if self.game_state_manager.game_location == "us2e": - self._write_game_flags_value_for(13758, 0) - elif self.game_state_manager.game_location == "ue2e": - self._write_game_flags_value_for(13309, 0) - elif self.game_state_manager.game_location == "uh2e": - self._write_game_flags_value_for(13498, 0) - elif self.game_state_manager.game_location == "um2e": - self._write_game_flags_value_for(13637, 0) - elif hotspot_item == ZorkGrandInquisitorItems.SUBWAY_DESTINATION_MONASTERY: - if self.game_state_manager.game_location == "us2e": - self._write_game_flags_value_for(13759, 0) - elif self.game_state_manager.game_location == "ue2e": - self._write_game_flags_value_for(13316, 0) - elif self.game_state_manager.game_location == "uh2e": - self._write_game_flags_value_for(13505, 0) - elif self.game_state_manager.game_location == "um2e": - self._write_game_flags_value_for(13644, 0) - elif hotspot_item == ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_HALL_OF_INQUISITION: - if self.game_state_manager.game_location == "mt1f": - self._write_game_flags_value_for(9660, 0) - elif hotspot_item == ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_INFINITY: - if self.game_state_manager.game_location == "mt1f": - self._write_game_flags_value_for(9666, 0) - elif hotspot_item == ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_STRAIGHT_TO_HELL: - if self.game_state_manager.game_location == "mt1f": - self._write_game_flags_value_for(9668, 0) - elif hotspot_item == ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_SURFACE_OF_MERZ: - if self.game_state_manager.game_location == "mt1f": - self._write_game_flags_value_for(9662, 0) - - def _manage_items(self) -> None: - if self._player_is_afgncaap(): - self.available_inventory_slots = self._determine_available_inventory_slots() - - received_inventory_items: Set[ZorkGrandInquisitorItems] - received_inventory_items = self.received_items & self.possible_inventory_items - - received_inventory_items = self._filter_received_inventory_items(received_inventory_items) - elif self._player_is_totem(): - self.available_inventory_slots = self._determine_available_inventory_slots(is_totem=True) - - received_inventory_items: Set[ZorkGrandInquisitorItems] - - if self._player_is_brog(): - received_inventory_items = self.received_items & self.brog_items - received_inventory_items = self._filter_received_brog_inventory_items(received_inventory_items) - elif self._player_is_griff(): - received_inventory_items = self.received_items & self.griff_items - received_inventory_items = self._filter_received_griff_inventory_items(received_inventory_items) - elif self._player_is_lucy(): - received_inventory_items = self.received_items & self.lucy_items - received_inventory_items = self._filter_received_lucy_inventory_items(received_inventory_items) - else: - return None - else: - return None - - game_state_inventory_items: Set[ZorkGrandInquisitorItems] = self._determine_game_state_inventory() - - inventory_items_to_remove: Set[ZorkGrandInquisitorItems] - inventory_items_to_remove = game_state_inventory_items - received_inventory_items - - inventory_items_to_add: Set[ZorkGrandInquisitorItems] - inventory_items_to_add = received_inventory_items - game_state_inventory_items - - item: ZorkGrandInquisitorItems - for item in inventory_items_to_remove: - self._remove_from_inventory(item) - - item: ZorkGrandInquisitorItems - for item in inventory_items_to_add: - self._add_to_inventory(item) - - # Item Deduplication (Just in Case) - seen_items: Set[int] = set() - - i: int - for i in range(151, 171): - item: int = self._read_game_state_value_for(i) - - if item in seen_items: - self._write_game_state_value_for(i, 0) - else: - seen_items.add(item) - - def _apply_conditional_teleports(self) -> None: - if self._player_is_at("uw1x"): - self.game_state_manager.set_game_location("uw10", 0) - - if self._player_is_at("uw1k") and self._read_game_state_value_for(13938) == 0: - self.game_state_manager.set_game_location("pc10", 250) - - if self._player_is_at("ue1q"): - self.game_state_manager.set_game_location("ue1e", 0) - - if self._player_is_at("ej10"): - self.game_state_manager.set_game_location("uc10", 1200) - - if self._read_game_state_value_for(9) == 224: - self._write_game_state_value_for(9, 0) - self.game_state_manager.set_game_location("uc10", 1200) - - def _check_for_victory(self) -> None: - if self.option_goal == ZorkGrandInquisitorGoals.THREE_ARTIFACTS: - coconut_is_placed = self._read_game_state_value_for(2200) == 1 - cube_is_placed = self._read_game_state_value_for(2322) == 1 - skull_is_placed = self._read_game_state_value_for(2321) == 1 - - self.goal_completed = coconut_is_placed and cube_is_placed and skull_is_placed - - def _determine_game_state_inventory(self) -> Set[ZorkGrandInquisitorItems]: - game_state_inventory: Set[ZorkGrandInquisitorItems] = set() - - # Item on Cursor - item_on_cursor: int = self._read_game_state_value_for(9) - - if item_on_cursor != 0: - if item_on_cursor in self.game_id_to_items: - game_state_inventory.add(self.game_id_to_items[item_on_cursor]) - - # Item in Inspector - item_in_inspector: int = self._read_game_state_value_for(4512) - - if item_in_inspector != 0: - if item_in_inspector in self.game_id_to_items: - game_state_inventory.add(self.game_id_to_items[item_in_inspector]) - - # Items in Inventory Slots - i: int - for i in range(151, 171): - if self._read_game_state_value_for(i) != 0: - if self._read_game_state_value_for(i) in self.game_id_to_items: - game_state_inventory.add( - self.game_id_to_items[self._read_game_state_value_for(i)] - ) - - # Pouch of Zorkmids - if self._read_game_state_value_for(5827) == 1: - game_state_inventory.add(ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS) - - # Spells - i: int - for i in range(191, 203): - if self._read_game_state_value_for(i) == 1: - if i in self.game_id_to_items: - game_state_inventory.add(self.game_id_to_items[i]) - - # Totems - if self._read_game_state_value_for(4853) == 1: - game_state_inventory.add(ZorkGrandInquisitorItems.TOTEM_BROG) - - if self._read_game_state_value_for(4315) == 1: - game_state_inventory.add(ZorkGrandInquisitorItems.TOTEM_GRIFF) - - if self._read_game_state_value_for(5223) == 1: - game_state_inventory.add(ZorkGrandInquisitorItems.TOTEM_LUCY) - - return game_state_inventory - - def _add_to_inventory(self, item: ZorkGrandInquisitorItems) -> None: - if item == ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS: - return None - - data: ZorkGrandInquisitorItemData = item_data[item] - - if ZorkGrandInquisitorTags.INVENTORY_ITEM in data.tags: - if len(self.available_inventory_slots): # Inventory slot overflow protection - inventory_slot: int = self.available_inventory_slots.pop() - self._write_game_state_value_for(inventory_slot, data.statemap_keys[0]) - elif ZorkGrandInquisitorTags.SPELL in data.tags: - self._write_game_state_value_for(data.statemap_keys[0], 1) - elif ZorkGrandInquisitorTags.TOTEM in data.tags: - self._write_game_state_value_for(data.statemap_keys[0], 1) - - def _remove_from_inventory(self, item: ZorkGrandInquisitorItems) -> None: - if item == ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS: - return None - - data: ZorkGrandInquisitorItemData = item_data[item] - - if ZorkGrandInquisitorTags.INVENTORY_ITEM in data.tags: - inventory_slot: Optional[int] = self._inventory_slot_for(item) - - if inventory_slot is None: - return None - - self._write_game_state_value_for(inventory_slot, 0) - - if inventory_slot != 9: - self.available_inventory_slots.add(inventory_slot) - elif ZorkGrandInquisitorTags.SPELL in data.tags: - self._write_game_state_value_for(data.statemap_keys[0], 0) - elif ZorkGrandInquisitorTags.TOTEM in data.tags: - self._write_game_state_value_for(data.statemap_keys[0], 0) - - def _determine_available_inventory_slots(self, is_totem: bool = False) -> Set[int]: - available_inventory_slots: Set[int] = set() - - inventory_slot_range_end: int = 171 - - if is_totem: - if self._player_is_brog(): - inventory_slot_range_end = 161 - elif self._player_is_griff(): - inventory_slot_range_end = 160 - elif self._player_is_lucy(): - inventory_slot_range_end = 157 - - i: int - for i in range(151, inventory_slot_range_end): - if self._read_game_state_value_for(i) == 0: - available_inventory_slots.add(i) - - return available_inventory_slots - - def _inventory_slot_for(self, item) -> Optional[int]: - data: ZorkGrandInquisitorItemData = item_data[item] - - if ZorkGrandInquisitorTags.INVENTORY_ITEM in data.tags: - i: int - for i in range(151, 171): - if self._read_game_state_value_for(i) == data.statemap_keys[0]: - return i - - if self._read_game_state_value_for(9) == data.statemap_keys[0]: - return 9 - - if self._read_game_state_value_for(4512) == data.statemap_keys[0]: - return 4512 - - return None - - def _filter_received_inventory_items( - self, received_inventory_items: Set[ZorkGrandInquisitorItems] - ) -> Set[ZorkGrandInquisitorItems]: - to_filter_inventory_items: Set[ZorkGrandInquisitorItems] = self.totem_items - - inventory_item_values: Set[int] = set() - - i: int - for i in range(151, 171): - inventory_item_values.add(self._read_game_state_value_for(i)) - - cursor_item_value: int = self._read_game_state_value_for(9) - inspector_item_value: int = self._read_game_state_value_for(4512) - - inventory_item_values.add(cursor_item_value) - inventory_item_values.add(inspector_item_value) - - item: ZorkGrandInquisitorItems - for item in received_inventory_items: - if item == ZorkGrandInquisitorItems.FLATHEADIA_FUDGE: - if self._read_game_state_value_for(4766) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(4869) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.HUNGUS_LARD: - if self._read_game_state_value_for(4870) == 1: - to_filter_inventory_items.add(item) - elif ( - self._read_game_state_value_for(4244) == 1 - and self._read_game_state_value_for(4309) == 0 - ): - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.JAR_OF_HOTBUGS: - if self._read_game_state_value_for(4750) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(4869) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.LANTERN: - if self._read_game_state_value_for(10477) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(5221) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.LARGE_TELEGRAPH_HAMMER: - if self._read_game_state_value_for(9491) == 3: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.MAP: - if self._read_game_state_value_for(16618) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.MEAD_LIGHT: - if 105 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(17620) > 0: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(4034) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.MOSS_OF_MAREILON: - if self._read_game_state_value_for(4763) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(4869) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.MUG: - if self._read_game_state_value_for(4772) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(4869) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.OLD_SCRATCH_CARD: - if 32 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(12892) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.PERMA_SUCK_MACHINE: - if self._read_game_state_value_for(12218) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.PLASTIC_SIX_PACK_HOLDER: - if self._read_game_state_value_for(15150) == 3: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(10421) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.PROZORK_TABLET: - if self._read_game_state_value_for(4115) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.QUELBEE_HONEYCOMB: - if self._read_game_state_value_for(4769) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(4869) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.ROPE: - if 22 in inventory_item_values: - to_filter_inventory_items.add(item) - elif 111 in inventory_item_values: - to_filter_inventory_items.add(item) - elif ( - self._read_game_state_value_for(10304) == 1 - and not self._read_game_state_value_for(13938) == 1 - ): - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15150) == 83: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.SCROLL_FRAGMENT_ANS: - if 41 in inventory_item_values: - to_filter_inventory_items.add(item) - elif 98 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(201) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.SCROLL_FRAGMENT_GIV: - if 48 in inventory_item_values: - to_filter_inventory_items.add(item) - elif 98 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(201) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.SNAPDRAGON: - if self._read_game_state_value_for(4199) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.STUDENT_ID: - if self._read_game_state_value_for(11838) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.SUBWAY_TOKEN: - if self._read_game_state_value_for(13167) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.SWORD: - if 22 in inventory_item_values: - to_filter_inventory_items.add(item) - elif 100 in inventory_item_values: - to_filter_inventory_items.add(item) - elif 111 in inventory_item_values: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.ZIMDOR_SCROLL: - if 105 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(17620) == 3: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(4034) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.ZORK_ROCKS: - if self._read_game_state_value_for(12486) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(12487) == 1: - to_filter_inventory_items.add(item) - elif 52 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(11769) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(11840) == 1: - to_filter_inventory_items.add(item) - - return received_inventory_items - to_filter_inventory_items - - def _filter_received_brog_inventory_items( - self, received_inventory_items: Set[ZorkGrandInquisitorItems] - ) -> Set[ZorkGrandInquisitorItems]: - to_filter_inventory_items: Set[ZorkGrandInquisitorItems] = set() - - inventory_item_values: Set[int] = set() - - i: int - for i in range(151, 161): - inventory_item_values.add(self._read_game_state_value_for(i)) - - cursor_item_value: int = self._read_game_state_value_for(9) - inspector_item_value: int = self._read_game_state_value_for(2194) - - inventory_item_values.add(cursor_item_value) - inventory_item_values.add(inspector_item_value) - - item: ZorkGrandInquisitorItems - for item in received_inventory_items: - if item == ZorkGrandInquisitorItems.BROGS_BICKERING_TORCH: - if 103 in inventory_item_values: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH: - if 104 in inventory_item_values: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.BROGS_GRUE_EGG: - if self._read_game_state_value_for(2577) == 1: - to_filter_inventory_items.add(item) - elif 71 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(2641) == 1: - to_filter_inventory_items.add(item) - - return received_inventory_items - to_filter_inventory_items - - def _filter_received_griff_inventory_items( - self, received_inventory_items: Set[ZorkGrandInquisitorItems] - ) -> Set[ZorkGrandInquisitorItems]: - to_filter_inventory_items: Set[ZorkGrandInquisitorItems] = set() - - inventory_item_values: Set[int] = set() - - i: int - for i in range(151, 160): - inventory_item_values.add(self._read_game_state_value_for(i)) - - cursor_item_value: int = self._read_game_state_value_for(9) - inspector_item_value: int = self._read_game_state_value_for(4512) - - inventory_item_values.add(cursor_item_value) - inventory_item_values.add(inspector_item_value) - - item: ZorkGrandInquisitorItems - for item in received_inventory_items: - if item == ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT: - if self._read_game_state_value_for(1301) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(1304) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(16562) == 1: - to_filter_inventory_items.add(item) - if item == ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN: - if self._read_game_state_value_for(1374) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(1381) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(16562) == 1: - to_filter_inventory_items.add(item) - - return received_inventory_items - to_filter_inventory_items - - def _filter_received_lucy_inventory_items( - self, received_inventory_items: Set[ZorkGrandInquisitorItems] - ) -> Set[ZorkGrandInquisitorItems]: - to_filter_inventory_items: Set[ZorkGrandInquisitorItems] = set() - - inventory_item_values: Set[int] = set() - - i: int - for i in range(151, 157): - inventory_item_values.add(self._read_game_state_value_for(i)) - - cursor_item_value: int = self._read_game_state_value_for(9) - inspector_item_value: int = self._read_game_state_value_for(2198) - - inventory_item_values.add(cursor_item_value) - inventory_item_values.add(inspector_item_value) - - item: ZorkGrandInquisitorItems - for item in received_inventory_items: - if item == ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1: - if 120 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15433) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15435) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15437) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15439) == 1: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15472) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2: - if 121 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15433) == 2: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15435) == 2: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15437) == 2: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15439) == 2: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15472) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3: - if 122 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15433) == 3: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15435) == 3: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15437) == 3: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15439) == 3: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15472) == 1: - to_filter_inventory_items.add(item) - elif item == ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4: - if 123 in inventory_item_values: - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15433) in (4, 5): - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15435) in (4, 5): - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15437) in (4, 5): - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15439) in (4, 5): - to_filter_inventory_items.add(item) - elif self._read_game_state_value_for(15472) == 1: - to_filter_inventory_items.add(item) - - return received_inventory_items - to_filter_inventory_items - - def _read_game_state_value_for(self, key: int) -> Optional[int]: - try: - return self.game_state_manager.read_game_state_value_for(key) - except Exception as e: - self.log_debug(f"Exception: {e} while trying to read game state key '{key}'") - raise e - - def _write_game_state_value_for(self, key: int, value: int) -> Optional[bool]: - try: - return self.game_state_manager.write_game_state_value_for(key, value) - except Exception as e: - self.log_debug(f"Exception: {e} while trying to write '{key} = {value}' to game state") - raise e - - def _read_game_flags_value_for(self, key: int) -> Optional[int]: - try: - return self.game_state_manager.read_game_flags_value_for(key) - except Exception as e: - self.log_debug(f"Exception: {e} while trying to read game flags key '{key}'") - raise e - - def _write_game_flags_value_for(self, key: int, value: int) -> Optional[bool]: - try: - return self.game_state_manager.write_game_flags_value_for(key, value) - except Exception as e: - self.log_debug(f"Exception: {e} while trying to write '{key} = {value}' to game flags") - raise e - - def _player_has(self, item: ZorkGrandInquisitorItems) -> bool: - return item in self.received_items - - def _player_doesnt_have(self, item: ZorkGrandInquisitorItems) -> bool: - return item not in self.received_items - - def _player_is_at(self, game_location: str) -> bool: - return self.game_state_manager.game_location == game_location - - def _player_is_afgncaap(self) -> bool: - return self._read_game_state_value_for(1596) == 1 - - def _player_is_totem(self) -> bool: - return self._player_is_brog() or self._player_is_griff() or self._player_is_lucy() - - def _player_is_brog(self) -> bool: - return self._read_game_state_value_for(1520) == 1 - - def _player_is_griff(self) -> bool: - return self._read_game_state_value_for(1296) == 1 - - def _player_is_lucy(self) -> bool: - return self._read_game_state_value_for(1524) == 1 diff --git a/worlds/zork_grand_inquisitor/game_state_manager.py b/worlds/zork_grand_inquisitor/game_state_manager.py deleted file mode 100644 index 25b35969bf5e..000000000000 --- a/worlds/zork_grand_inquisitor/game_state_manager.py +++ /dev/null @@ -1,370 +0,0 @@ -from typing import Optional, Tuple - -from pymem import Pymem -from pymem.process import close_handle - - -class GameStateManager: - process_name = "scummvm.exe" - - process: Optional[Pymem] - is_process_running: bool - - script_manager_struct_address: int - render_manager_struct_address: int - - game_location: Optional[str] - game_location_offset: Optional[int] - - def __init__(self) -> None: - self.process = None - self.is_process_running = False - - self.script_manager_struct_address = 0x0 - self.render_manager_struct_address = 0x0 - - self.game_location = None - self.game_location_offset = None - - @property - def game_state_storage_pointer_address(self) -> int: - return self.script_manager_struct_address + 0x88 - - @property - def game_state_storage_address(self) -> int: - return self.process.read_longlong(self.game_state_storage_pointer_address) - - @property - def game_state_hashmap_size_address(self) -> int: - return self.script_manager_struct_address + 0x90 - - @property - def game_state_key_count_address(self) -> int: - return self.script_manager_struct_address + 0x94 - - @property - def game_state_deleted_key_count_address(self) -> int: - return self.script_manager_struct_address + 0x98 - - @property - def game_flags_storage_pointer_address(self) -> int: - return self.script_manager_struct_address + 0x120 - - @property - def game_flags_storage_address(self) -> int: - return self.process.read_longlong(self.game_flags_storage_pointer_address) - - @property - def game_flags_hashmap_size_address(self) -> int: - return self.script_manager_struct_address + 0x128 - - @property - def game_flags_key_count_address(self) -> int: - return self.script_manager_struct_address + 0x12C - - @property - def game_flags_deleted_key_count_address(self) -> int: - return self.script_manager_struct_address + 0x130 - - @property - def current_location_address(self) -> int: - return self.script_manager_struct_address + 0x400 - - @property - def current_location_offset_address(self) -> int: - return self.script_manager_struct_address + 0x404 - - @property - def next_location_address(self) -> int: - return self.script_manager_struct_address + 0x408 - - @property - def next_location_offset_address(self) -> int: - return self.script_manager_struct_address + 0x40C - - @property - def panorama_reversed_address(self) -> int: - return self.render_manager_struct_address + 0x1C - - def open_process_handle(self) -> bool: - try: - self.process = Pymem(self.process_name) - self.is_process_running = True - - self.script_manager_struct_address = self._resolve_address(0x5276600, (0xC8, 0x0)) - self.render_manager_struct_address = self._resolve_address(0x5276600, (0xD0, 0x120)) - except Exception: - return False - - return True - - def close_process_handle(self) -> bool: - if close_handle(self.process.process_handle): - self.is_process_running = False - self.process = None - - self.script_manager_struct_address = 0x0 - self.render_manager_struct_address = 0x0 - - return True - - return False - - def is_process_still_running(self) -> bool: - try: - self.process.read_int(self.process.base_address) - except Exception: - self.is_process_running = False - self.process = None - - self.script_manager_struct_address = 0x0 - self.render_manager_struct_address = 0x0 - - return False - - return True - - def read_game_state_value_for(self, key: int) -> Optional[int]: - return self.read_statemap_value_for(key, scope="game_state") - - def read_game_flags_value_for(self, key: int) -> Optional[int]: - return self.read_statemap_value_for(key, scope="game_flags") - - def read_statemap_value_for(self, key: int, scope: str = "game_state") -> Optional[int]: - if self.is_process_running: - offset: int - - address: int - address_value: int - - if scope == "game_state": - offset = self._get_game_state_address_read_offset_for(key) - - address = self.game_state_storage_address + offset - address_value = self.process.read_longlong(address) - elif scope == "game_flags": - offset = self._get_game_flags_address_read_offset_for(key) - - address = self.game_flags_storage_address + offset - address_value = self.process.read_longlong(address) - else: - raise ValueError(f"Invalid scope: {scope}") - - if address_value == 0: - return 0 - - statemap_value: int = self.process.read_int(address_value + 0x0) - statemap_key: int = self.process.read_int(address_value + 0x4) - - assert statemap_key == key - - return statemap_value - - return None - - def write_game_state_value_for(self, key: int, value: int) -> Optional[bool]: - return self.write_statemap_value_for(key, value, scope="game_state") - - def write_game_flags_value_for(self, key: int, value: int) -> Optional[bool]: - return self.write_statemap_value_for(key, value, scope="game_flags") - - def write_statemap_value_for(self, key: int, value: int, scope: str = "game_state") -> Optional[bool]: - if self.is_process_running: - offset: int - is_existing_node: bool - is_reused_dummy_node: bool - - key_count_address: int - deleted_key_count_address: int - - storage_address: int - - if scope == "game_state": - offset, is_existing_node, is_reused_dummy_node = self._get_game_state_address_write_offset_for(key) - - key_count_address = self.game_state_key_count_address - deleted_key_count_address = self.game_state_deleted_key_count_address - - storage_address = self.game_state_storage_address - elif scope == "game_flags": - offset, is_existing_node, is_reused_dummy_node = self._get_game_flags_address_write_offset_for(key) - - key_count_address = self.game_flags_key_count_address - deleted_key_count_address = self.game_flags_deleted_key_count_address - - storage_address = self.game_flags_storage_address - else: - raise ValueError(f"Invalid scope: {scope}") - - statemap_key_count: int = self.process.read_int(key_count_address) - statemap_deleted_key_count: int = self.process.read_int(deleted_key_count_address) - - if value == 0: - if not is_existing_node: - return False - - self.process.write_longlong(storage_address + offset, 1) - - self.process.write_int(key_count_address, statemap_key_count - 1) - self.process.write_int(deleted_key_count_address, statemap_deleted_key_count + 1) - else: - if is_existing_node: - address_value: int = self.process.read_longlong(storage_address + offset) - self.process.write_int(address_value + 0x0, value) - else: - write_address: int = self.process.allocate(0x8) - - self.process.write_int(write_address + 0x0, value) - self.process.write_int(write_address + 0x4, key) - - self.process.write_longlong(storage_address + offset, write_address) - - self.process.write_int(key_count_address, statemap_key_count + 1) - - if is_reused_dummy_node: - self.process.write_int(deleted_key_count_address, statemap_deleted_key_count - 1) - - return True - - return None - - def refresh_game_location(self) -> Optional[bool]: - if self.is_process_running: - game_location_bytes: bytes = self.process.read_bytes(self.current_location_address, 4) - - self.game_location = game_location_bytes.decode("ascii") - self.game_location_offset = self.process.read_int(self.current_location_offset_address) - - return True - - return None - - def set_game_location(self, game_location: str, offset: int) -> Optional[bool]: - if self.is_process_running: - game_location_bytes: bytes = game_location.encode("ascii") - - self.process.write_bytes(self.next_location_address, game_location_bytes, 4) - self.process.write_int(self.next_location_offset_address, offset) - - return True - - return None - - def set_panorama_reversed(self, is_reversed: bool) -> Optional[bool]: - if self.is_process_running: - self.process.write_int(self.panorama_reversed_address, 1 if is_reversed else 0) - - return True - - return None - - def _resolve_address(self, base_offset: int, offsets: Tuple[int, ...]): - address: int = self.process.read_longlong(self.process.base_address + base_offset) - - for offset in offsets[:-1]: - address = self.process.read_longlong(address + offset) - - return address + offsets[-1] - - def _get_game_state_address_read_offset_for(self, key: int): - return self._get_statemap_address_read_offset_for(key, scope="game_state") - - def _get_game_flags_address_read_offset_for(self, key: int): - return self._get_statemap_address_read_offset_for(key, scope="game_flags") - - def _get_statemap_address_read_offset_for(self, key: int, scope: str = "game_state") -> int: - hashmap_size_address: int - storage_address: int - - if scope == "game_state": - hashmap_size_address = self.game_state_hashmap_size_address - storage_address = self.game_state_storage_address - elif scope == "game_flags": - hashmap_size_address = self.game_flags_hashmap_size_address - storage_address = self.game_flags_storage_address - else: - raise ValueError(f"Invalid scope: {scope}") - - statemap_hashmap_size: int = self.process.read_int(hashmap_size_address) - - perturb: int = key - perturb_shift: int = 0x5 - - index: int = key & statemap_hashmap_size - offset: int = index * 0x8 - - while True: - offset_value: int = self.process.read_longlong(storage_address + offset) - - if offset_value == 0: # Null Pointer - break - elif offset_value == 1: # Dummy Node - pass - elif offset_value > 1: # Existing Node - if self.process.read_int(offset_value + 0x4) == key: - break - - index = ((0x5 * index) + perturb + 0x1) & statemap_hashmap_size - offset = index * 0x8 - - perturb >>= perturb_shift - - return offset - - def _get_game_state_address_write_offset_for(self, key: int) -> Tuple[int, bool, bool]: - return self._get_statemap_address_write_offset_for(key, scope="game_state") - - def _get_game_flags_address_write_offset_for(self, key: int) -> Tuple[int, bool, bool]: - return self._get_statemap_address_write_offset_for(key, scope="game_flags") - - def _get_statemap_address_write_offset_for(self, key: int, scope: str = "game_state") -> Tuple[int, bool, bool]: - hashmap_size_address: int - storage_address: int - - if scope == "game_state": - hashmap_size_address = self.game_state_hashmap_size_address - storage_address = self.game_state_storage_address - elif scope == "game_flags": - hashmap_size_address = self.game_flags_hashmap_size_address - storage_address = self.game_flags_storage_address - else: - raise ValueError(f"Invalid scope: {scope}") - - statemap_hashmap_size: int = self.process.read_int(hashmap_size_address) - - perturb: int = key - perturb_shift: int = 0x5 - - index: int = key & statemap_hashmap_size - offset: int = index * 0x8 - - node_found: bool = False - - dummy_node_found: bool = False - dummy_node_offset: Optional[int] = None - - while True: - offset_value: int = self.process.read_longlong(storage_address + offset) - - if offset_value == 0: # Null Pointer - break - elif offset_value == 1: # Dummy Node - if not dummy_node_found: - dummy_node_offset = offset - dummy_node_found = True - elif offset_value > 1: # Existing Node - if self.process.read_int(offset_value + 0x4) == key: - node_found = True - break - - index = ((0x5 * index) + perturb + 0x1) & statemap_hashmap_size - offset = index * 0x8 - - perturb >>= perturb_shift - - if not node_found and dummy_node_found: # We should reuse the dummy node - return dummy_node_offset, False, True - elif not node_found and not dummy_node_found: # We should allocate a new node - return offset, False, False - - return offset, True, False # We should update the existing node diff --git a/worlds/zork_grand_inquisitor/options.py b/worlds/zork_grand_inquisitor/options.py deleted file mode 100644 index f06415199934..000000000000 --- a/worlds/zork_grand_inquisitor/options.py +++ /dev/null @@ -1,61 +0,0 @@ -from dataclasses import dataclass - -from Options import Choice, DefaultOnToggle, PerGameCommonOptions, Toggle - - -class Goal(Choice): - """ - Determines the victory condition - - Three Artifacts: Retrieve the three artifacts of magic and place them in the walking castle - """ - display_name: str = "Goal" - - default: int = 0 - option_three_artifacts: int = 0 - - -class QuickPortFoozle(DefaultOnToggle): - """If true, the items needed to go down the well will be found in early locations for a smoother early game""" - - display_name: str = "Quick Port Foozle" - - -class StartWithHotspotItems(DefaultOnToggle): - """ - If true, the player will be given all the hotspot items at the start of the game, effectively removing the need - to enable the important hotspots in the game before interacting with them. Recommended for beginners - - Note: The spots these hotspot items would have occupied in the item pool will instead be filled with junk items. - Expect a higher volume of filler items if you enable this option - """ - - display_name: str = "Start with Hotspot Items" - - -class Deathsanity(Toggle): - """If true, adds 16 player death locations to the world""" - - display_name: str = "Deathsanity" - - -class GrantMissableLocationChecks(Toggle): - """ - If true, performing an irreversible action will grant the locations checks that would have become unobtainable as a - result of that action when you meet the item requirements - - Otherwise, the player is expected to potentially have to use the save system to reach those location checks. If you - don't like the idea of rarely having to reload an earlier save to get a location check, make sure this option is - enabled - """ - - display_name: str = "Grant Missable Checks" - - -@dataclass -class ZorkGrandInquisitorOptions(PerGameCommonOptions): - goal: Goal - quick_port_foozle: QuickPortFoozle - start_with_hotspot_items: StartWithHotspotItems - deathsanity: Deathsanity - grant_missable_location_checks: GrantMissableLocationChecks diff --git a/worlds/zork_grand_inquisitor/requirements.txt b/worlds/zork_grand_inquisitor/requirements.txt deleted file mode 100644 index ca36764fbfaa..000000000000 --- a/worlds/zork_grand_inquisitor/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -Pymem>=1.13.0 diff --git a/worlds/zork_grand_inquisitor/test/__init__.py b/worlds/zork_grand_inquisitor/test/__init__.py deleted file mode 100644 index c8ceda43a7bf..000000000000 --- a/worlds/zork_grand_inquisitor/test/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from test.bases import WorldTestBase - - -class ZorkGrandInquisitorTestBase(WorldTestBase): - game = "Zork Grand Inquisitor" diff --git a/worlds/zork_grand_inquisitor/test/test_access.py b/worlds/zork_grand_inquisitor/test/test_access.py deleted file mode 100644 index 63a5f8c9ab1d..000000000000 --- a/worlds/zork_grand_inquisitor/test/test_access.py +++ /dev/null @@ -1,2927 +0,0 @@ -from typing import List - -from . import ZorkGrandInquisitorTestBase - -from ..enums import ( - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorItems, - ZorkGrandInquisitorLocations, - ZorkGrandInquisitorRegions, -) - - -class AccessTestRegions(ZorkGrandInquisitorTestBase): - options = { - "start_with_hotspot_items": "false", - } - - def test_access_crossroads_to_dm_lair_sword(self) -> None: - self._go_to_crossroads() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SWORD.value, - ZorkGrandInquisitorItems.HOTSPOT_DUNGEON_MASTERS_LAIR_ENTRANCE.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - def test_access_crossroads_to_dm_lair_teleporter(self) -> None: - self._go_to_crossroads() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - def test_access_crossroads_to_gue_tech(self) -> None: - self._go_to_crossroads() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_REZROV.value, - ZorkGrandInquisitorItems.HOTSPOT_IN_MAGIC_WE_TRUST_DOOR.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH.value)) - - def test_access_crossroads_to_gue_tech_outside(self) -> None: - self._go_to_crossroads() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE.value)) - - def test_access_crossroads_to_hades_shore(self) -> None: - self._go_to_crossroads() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - def test_access_crossroads_to_port_foozle(self) -> None: - self._go_to_crossroads() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.PORT_FOOZLE.value)) - - def test_access_crossroads_to_spell_lab_bridge(self) -> None: - self._go_to_crossroads() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - def test_access_crossroads_to_subway_crossroads(self) -> None: - self._go_to_crossroads() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SUBWAY_TOKEN.value, - ZorkGrandInquisitorItems.HOTSPOT_SUBWAY_TOKEN_SLOT.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS.value)) - - def test_access_crossroads_to_subway_monastery(self) -> None: - self._go_to_crossroads() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - def test_access_dm_lair_to_crossroads(self) -> None: - self._go_to_dm_lair() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.CROSSROADS.value)) - - def test_access_dm_lair_to_dm_lair_interior(self) -> None: - self._go_to_dm_lair() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_HARRYS_ASHTRAY.value, - ZorkGrandInquisitorItems.MEAD_LIGHT.value, - ZorkGrandInquisitorItems.ZIMDOR_SCROLL.value, - ZorkGrandInquisitorItems.HOTSPOT_HARRYS_BIRD_BATH.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR.value)) - - def test_access_dm_lair_to_gue_tech_outside(self) -> None: - self._go_to_dm_lair() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH.value)) - - def test_access_dm_lair_to_hades_shore(self) -> None: - self._go_to_dm_lair() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - def test_access_dm_lair_to_spell_lab_bridge(self) -> None: - self._go_to_dm_lair() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - def test_access_dm_lair_to_subway_monastery(self) -> None: - self._go_to_dm_lair() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - def test_access_dm_lair_interior_to_dm_lair(self) -> None: - self._go_to_dm_lair_interior() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - def test_access_dm_lair_interior_to_walking_castle(self) -> None: - self._go_to_dm_lair_interior() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.WALKING_CASTLE.value)) - - self._obtain_obidil() - - self.collect_by_name(ZorkGrandInquisitorItems.HOTSPOT_BLINDS.value) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.WALKING_CASTLE.value)) - - def test_access_dm_lair_interior_to_white_house(self) -> None: - self._go_to_dm_lair_interior() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.WHITE_HOUSE.value)) - - self._obtain_yastard() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_CLOSET_DOOR.value, - ZorkGrandInquisitorItems.SPELL_NARWILE.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.WHITE_HOUSE.value)) - - def test_access_dragon_archipelago_to_dragon_archipelago_dragon(self) -> None: - self._go_to_dragon_archipelago() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.TOTEM_GRIFF.value, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_CLAW.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON.value)) - - def test_access_dragon_archipelago_to_hades_beyond_gates(self) -> None: - self._go_to_dragon_archipelago() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_BEYOND_GATES.value)) - - def test_access_dragon_archipelago_dragon_to_dragon_archipelago(self) -> None: - self._go_to_dragon_archipelago_dragon() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO.value)) - - def test_access_dragon_archipelago_dragon_to_endgame(self) -> None: - self._go_to_dragon_archipelago_dragon() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.ENDGAME.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP.value, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT.value, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN.value, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS.value, - ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH.value, - ) - ) - - self._go_to_port_foozle_past_tavern() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1.value, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2.value, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3.value, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4.value, - ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY.value, - ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS.value, - ) - ) - - self._go_to_white_house() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.TOTEM_BROG.value, - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH.value, - ZorkGrandInquisitorItems.BROGS_GRUE_EGG.value, - ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT.value, - ZorkGrandInquisitorItems.BROGS_PLANK.value, - ZorkGrandInquisitorItems.HOTSPOT_SKULL_CAGE.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.ENDGAME.value)) - - def test_access_gue_tech_to_crossroads(self) -> None: - self._go_to_gue_tech() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.CROSSROADS.value)) - - def test_access_gue_tech_to_gue_tech_hallway(self) -> None: - self._go_to_gue_tech() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_IGRAM.value, - ZorkGrandInquisitorItems.HOTSPOT_PURPLE_WORDS.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY.value)) - - def test_access_gue_tech_to_gue_tech_outside(self) -> None: - self._go_to_gue_tech() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE.value)) - - self.collect_by_name(ZorkGrandInquisitorItems.HOTSPOT_GUE_TECH_DOOR.value) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE.value)) - - def test_access_gue_tech_hallway_to_gue_tech(self) -> None: - self._go_to_gue_tech_hallway() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH.value)) - - def test_access_gue_tech_hallway_to_spell_lab_bridge(self) -> None: - self._go_to_gue_tech_hallway() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.STUDENT_ID.value, - ZorkGrandInquisitorItems.HOTSPOT_STUDENT_ID_MACHINE.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - def test_access_gue_tech_outside_to_crossroads(self) -> None: - self._go_to_gue_tech_outside() - - # Direct connection requires the map but indirect connection is free - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.CROSSROADS.value)) - - def test_access_gue_tech_outside_to_dm_lair(self) -> None: - self._go_to_gue_tech_outside() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - def test_access_gue_tech_outside_to_gue_tech(self) -> None: - self._go_to_gue_tech_outside() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH.value)) - - def test_access_gue_tech_outside_to_hades_shore(self) -> None: - self._go_to_gue_tech_outside() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - def test_access_gue_tech_outside_to_spell_lab_bridge(self) -> None: - self._go_to_gue_tech_outside() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - def test_access_gue_tech_outside_to_subway_monastery(self) -> None: - self._go_to_gue_tech_outside() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - def test_access_hades_to_hades_beyond_gates(self) -> None: - self._go_to_hades() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_BEYOND_GATES.value)) - - self._obtain_snavig() - - self.collect_by_name(ZorkGrandInquisitorItems.TOTEM_BROG.value) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_BEYOND_GATES.value)) - - def test_access_hades_to_hades_shore(self) -> None: - self._go_to_hades() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - def test_access_hades_beyond_gates_to_dragon_archipelago(self) -> None: - self._go_to_hades_beyond_gates() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO.value)) - - self._obtain_yastard() - - self.collect_by_name(ZorkGrandInquisitorItems.SPELL_NARWILE.value) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO.value)) - - def test_access_hades_beyond_gates_to_hades(self) -> None: - self._go_to_hades_beyond_gates() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES.value)) - - def test_access_hades_shore_to_crossroads(self) -> None: - self._go_to_hades_shore() - - # Direct connection requires the map but indirect connection is free - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.CROSSROADS.value)) - - def test_access_hades_shore_to_dm_lair(self) -> None: - self._go_to_hades_shore() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - def test_access_hades_shore_to_gue_tech_outside(self) -> None: - self._go_to_hades_shore() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE.value)) - - def test_access_hades_shore_to_hades(self) -> None: - self._go_to_hades_shore() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.HADES.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_RECEIVER.value, - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_BUTTONS.value, - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES.value)) - - def test_access_hades_shore_to_spell_lab_bridge(self) -> None: - self._go_to_hades_shore() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - def test_access_hades_shore_to_subway_crossroads(self) -> None: - self._go_to_hades_shore() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS.value)) - - def test_access_hades_shore_to_subway_flood_control_dam(self) -> None: - self._go_to_hades_shore() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM.value)) - - self.collect_by_name(ZorkGrandInquisitorItems.SUBWAY_DESTINATION_FLOOD_CONTROL_DAM.value) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM.value)) - - def test_access_hades_shore_to_subway_monastery(self) -> None: - self._go_to_hades_shore() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - self.collect_by_name(ZorkGrandInquisitorItems.SUBWAY_DESTINATION_MONASTERY.value) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - def test_access_monastery_to_hades_shore(self) -> None: - self._go_to_monastery() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_STRAIGHT_TO_HELL.value, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_WHEELS.value, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - def test_access_monastery_to_monastery_exhibit(self) -> None: - self._go_to_monastery() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_HALL_OF_INQUISITION.value, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_WHEELS.value, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT.value)) - - def test_access_monastery_to_subway_monastery(self) -> None: - self._go_to_monastery() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - def test_access_monastery_exhibit_to_monastery(self) -> None: - self._go_to_monastery_exhibit() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.MONASTERY.value)) - - def test_access_monastery_exhibit_to_port_foozle_past(self) -> None: - self._go_to_monastery_exhibit() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST.value)) - - self._obtain_yastard() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_LEVER.value, - ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_HAMMER_SLOT.value, - ZorkGrandInquisitorItems.LARGE_TELEGRAPH_HAMMER.value, - ZorkGrandInquisitorItems.SPELL_NARWILE.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST.value)) - - def test_access_port_foozle_to_crossroads(self) -> None: - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.CROSSROADS.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR.value, - ZorkGrandInquisitorItems.LANTERN.value, - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL.value, - ZorkGrandInquisitorItems.ROPE.value, - ZorkGrandInquisitorItems.HOTSPOT_WELL.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.CROSSROADS.value)) - - def test_access_port_foozle_to_port_foozle_jacks_shop(self) -> None: - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.PORT_FOOZLE_JACKS_SHOP.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR.value, - ZorkGrandInquisitorItems.LANTERN.value, - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.PORT_FOOZLE_JACKS_SHOP.value)) - - def test_access_port_foozle_jacks_shop_to_port_foozle(self) -> None: - self._go_to_port_foozle_jacks_shop() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.PORT_FOOZLE.value)) - - def test_access_port_foozle_past_to_monastery_exhibit(self) -> None: - self._go_to_port_foozle_past() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.MONASTERY_EXHIBIT.value)) - - def test_access_port_foozle_past_to_port_foozle_past_tavern(self) -> None: - self._go_to_port_foozle_past() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.TOTEM_LUCY.value, - ZorkGrandInquisitorItems.HOTSPOT_PORT_FOOZLE_PAST_TAVERN_DOOR.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST_TAVERN.value)) - - def test_access_port_foozle_past_tavern_to_endgame(self) -> None: - self._go_to_port_foozle_past_tavern() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.ENDGAME.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1.value, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2.value, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3.value, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4.value, - ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY.value, - ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS.value, - ) - ) - - self._go_to_dragon_archipelago_dragon() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP.value, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT.value, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN.value, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS.value, - ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH.value, - ) - ) - - self._go_to_white_house() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.TOTEM_BROG.value, - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH.value, - ZorkGrandInquisitorItems.BROGS_GRUE_EGG.value, - ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT.value, - ZorkGrandInquisitorItems.BROGS_PLANK.value, - ZorkGrandInquisitorItems.HOTSPOT_SKULL_CAGE.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.ENDGAME.value)) - - def test_access_port_foozle_past_tavern_to_port_foozle_past(self) -> None: - self._go_to_port_foozle_past_tavern() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.PORT_FOOZLE_PAST.value)) - - def test_access_spell_lab_to_spell_lab_bridge(self) -> None: - self._go_to_spell_lab() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB_BRIDGE.value)) - - def test_access_spell_lab_bridge_to_crossroads(self) -> None: - self._go_to_spell_lab_bridge() - - # Direct connection requires the map but indirect connection is free - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.CROSSROADS.value)) - - def test_access_spell_lab_bridge_to_dm_lair(self) -> None: - self._go_to_spell_lab_bridge() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR.value)) - - def test_access_spell_lab_bridge_to_gue_tech_outside(self) -> None: - self._go_to_spell_lab_bridge() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE.value)) - - def test_access_spell_lab_bridge_to_gue_tech_hallway(self) -> None: - self._go_to_spell_lab_bridge() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.GUE_TECH_HALLWAY.value)) - - def test_access_spell_lab_bridge_to_hades_shore(self) -> None: - self._go_to_spell_lab_bridge() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - def test_access_spell_lab_bridge_to_spell_lab(self) -> None: - self._go_to_spell_lab_bridge() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB.value)) - - self._go_to_subway_flood_control_dam() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_REZROV.value, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_BUTTONS.value, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_DOORS.value, - ZorkGrandInquisitorItems.SWORD.value, - ZorkGrandInquisitorItems.HOTSPOT_ROPE_BRIDGE.value, - ZorkGrandInquisitorItems.SPELL_GOLGATEM.value, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_LAB_CHASM.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SPELL_LAB.value)) - - def test_access_spell_lab_bridge_to_subway_monastery(self) -> None: - self._go_to_spell_lab_bridge() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - def test_access_subway_crossroads_to_crossroads(self) -> None: - self._go_to_subway_crossroads() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.CROSSROADS.value)) - - def test_access_subway_crossroads_to_hades_shore(self) -> None: - self._go_to_subway_crossroads() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_KENDALL.value, - ZorkGrandInquisitorItems.SUBWAY_DESTINATION_HADES.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - def test_access_subway_crossroads_to_subway_flood_control_dam(self) -> None: - self._go_to_subway_crossroads() - - self.assertFalse( - self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM.value) - ) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_KENDALL.value, - ZorkGrandInquisitorItems.SUBWAY_DESTINATION_FLOOD_CONTROL_DAM.value, - ) - ) - - self.assertTrue( - self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM.value) - ) - - def test_access_subway_crossroads_to_subway_monastery(self) -> None: - self._go_to_subway_crossroads() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_KENDALL.value, - ZorkGrandInquisitorItems.SUBWAY_DESTINATION_MONASTERY.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - def test_access_subway_flood_control_dam_to_hades_shore(self) -> None: - self._go_to_subway_flood_control_dam() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - self.collect_by_name(ZorkGrandInquisitorItems.SUBWAY_DESTINATION_HADES.value) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - def test_access_subway_flood_control_dam_to_subway_crossroads(self) -> None: - self._go_to_subway_flood_control_dam() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS.value)) - - def test_access_subway_flood_control_dam_to_subway_monastery(self) -> None: - self._go_to_subway_flood_control_dam() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - self.collect_by_name(ZorkGrandInquisitorItems.SUBWAY_DESTINATION_MONASTERY.value) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_MONASTERY.value)) - - def test_access_subway_monastery_to_hades_shore(self) -> None: - self._go_to_subway_monastery() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - self.collect_by_name(ZorkGrandInquisitorItems.SUBWAY_DESTINATION_HADES.value) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.HADES_SHORE.value)) - - def test_access_subway_monastery_to_monastery(self) -> None: - self._go_to_subway_monastery() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.MONASTERY.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SWORD.value, - ZorkGrandInquisitorItems.SPELL_GLORF.value, - ZorkGrandInquisitorItems.HOTSPOT_MONASTERY_VENT.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.MONASTERY.value)) - - def test_access_subway_monastery_to_subway_crossroads(self) -> None: - self._go_to_subway_monastery() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_CROSSROADS.value)) - - def test_access_subway_monastery_to_subway_flood_control_dam(self) -> None: - self._go_to_subway_monastery() - - self.assertFalse( - self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM.value) - ) - - self.collect_by_name(ZorkGrandInquisitorItems.SUBWAY_DESTINATION_FLOOD_CONTROL_DAM.value) - - self.assertTrue( - self.can_reach_region(ZorkGrandInquisitorRegions.SUBWAY_FLOOD_CONTROL_DAM.value) - ) - - def test_access_walking_castle_to_dm_lair_interior(self) -> None: - self._go_to_walking_castle() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR.value)) - - def test_access_white_house_to_dm_lair_interior(self) -> None: - self._go_to_white_house() - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR.value)) - - def test_access_white_house_to_endgame(self) -> None: - self._go_to_white_house() - - self.assertFalse(self.can_reach_region(ZorkGrandInquisitorRegions.ENDGAME.value)) - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.TOTEM_BROG.value, - ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH.value, - ZorkGrandInquisitorItems.BROGS_GRUE_EGG.value, - ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT.value, - ZorkGrandInquisitorItems.BROGS_PLANK.value, - ZorkGrandInquisitorItems.HOTSPOT_SKULL_CAGE.value, - ) - ) - - self._go_to_dragon_archipelago_dragon() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP.value, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT.value, - ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN.value, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS.value, - ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH.value, - ) - ) - - self._go_to_port_foozle_past_tavern() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1.value, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2.value, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3.value, - ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4.value, - ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY.value, - ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS.value, - ) - ) - - self.assertTrue(self.can_reach_region(ZorkGrandInquisitorRegions.ENDGAME.value)) - - def _go_to_crossroads(self) -> None: - self.collect_by_name( - ( - ZorkGrandInquisitorItems.LANTERN.value, - ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR.value, - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL.value, - ZorkGrandInquisitorItems.ROPE.value, - ZorkGrandInquisitorItems.HOTSPOT_WELL.value, - ) - ) - - def _go_to_dm_lair(self) -> None: - self._go_to_crossroads() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SWORD.value, - ZorkGrandInquisitorItems.HOTSPOT_DUNGEON_MASTERS_LAIR_ENTRANCE.value, - ) - ) - - def _go_to_dm_lair_interior(self) -> None: - self._go_to_dm_lair() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_HARRYS_ASHTRAY.value, - ZorkGrandInquisitorItems.MEAD_LIGHT.value, - ZorkGrandInquisitorItems.ZIMDOR_SCROLL.value, - ZorkGrandInquisitorItems.HOTSPOT_HARRYS_BIRD_BATH.value, - ) - ) - - def _go_to_dragon_archipelago(self) -> None: - self._go_to_hades_beyond_gates() - self._obtain_yastard() - - self.collect_by_name(ZorkGrandInquisitorItems.SPELL_NARWILE.value) - - def _go_to_dragon_archipelago_dragon(self) -> None: - self._go_to_dragon_archipelago() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.TOTEM_GRIFF.value, - ZorkGrandInquisitorItems.HOTSPOT_DRAGON_CLAW.value, - ) - ) - - def _go_to_gue_tech(self) -> None: - self._go_to_crossroads() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_REZROV.value, - ZorkGrandInquisitorItems.HOTSPOT_IN_MAGIC_WE_TRUST_DOOR.value, - ) - ) - - def _go_to_gue_tech_hallway(self) -> None: - self._go_to_gue_tech() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_IGRAM.value, - ZorkGrandInquisitorItems.HOTSPOT_PURPLE_WORDS.value, - ) - ) - - def _go_to_gue_tech_outside(self) -> None: - self._go_to_crossroads() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH.value, - ) - ) - - def _go_to_hades(self) -> None: - self._go_to_hades_shore() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_RECEIVER.value, - ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_BUTTONS.value, - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS.value, - ) - ) - - def _go_to_hades_beyond_gates(self) -> None: - self._go_to_hades() - self._obtain_snavig() - - self.collect_by_name(ZorkGrandInquisitorItems.TOTEM_BROG.value) - - def _go_to_hades_shore(self) -> None: - self._go_to_crossroads() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES.value, - ) - ) - - def _go_to_monastery(self) -> None: - self._go_to_subway_monastery() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SWORD.value, - ZorkGrandInquisitorItems.SPELL_GLORF.value, - ZorkGrandInquisitorItems.HOTSPOT_MONASTERY_VENT.value, - ) - ) - - def _go_to_monastery_exhibit(self) -> None: - self._go_to_monastery() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_HALL_OF_INQUISITION.value, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_WHEELS.value, - ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH.value, - ) - ) - - def _go_to_port_foozle_jacks_shop(self) -> None: - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR.value, - ZorkGrandInquisitorItems.LANTERN.value, - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL.value, - ) - ) - - def _go_to_port_foozle_past(self) -> None: - self._go_to_monastery_exhibit() - - self._obtain_yastard() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_LEVER.value, - ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_HAMMER_SLOT.value, - ZorkGrandInquisitorItems.LARGE_TELEGRAPH_HAMMER.value, - ZorkGrandInquisitorItems.SPELL_NARWILE.value, - ) - ) - - def _go_to_port_foozle_past_tavern(self) -> None: - self._go_to_port_foozle_past() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.TOTEM_LUCY.value, - ZorkGrandInquisitorItems.HOTSPOT_PORT_FOOZLE_PAST_TAVERN_DOOR.value, - ) - ) - - def _go_to_spell_lab(self) -> None: - self._go_to_subway_flood_control_dam() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_REZROV.value, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_BUTTONS.value, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_DOORS.value, - ) - ) - - self._go_to_spell_lab_bridge() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SWORD.value, - ZorkGrandInquisitorItems.HOTSPOT_ROPE_BRIDGE.value, - ZorkGrandInquisitorItems.SPELL_GOLGATEM.value, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_LAB_CHASM.value, - ) - ) - - def _go_to_spell_lab_bridge(self) -> None: - self._go_to_crossroads() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB.value, - ) - ) - - def _go_to_subway_crossroads(self) -> None: - self._go_to_crossroads() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SUBWAY_TOKEN.value, - ZorkGrandInquisitorItems.HOTSPOT_SUBWAY_TOKEN_SLOT.value, - ) - ) - - def _go_to_subway_flood_control_dam(self) -> None: - self._go_to_subway_crossroads() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_KENDALL.value, - ZorkGrandInquisitorItems.SUBWAY_DESTINATION_FLOOD_CONTROL_DAM.value, - ) - ) - - def _go_to_subway_monastery(self) -> None: - self._go_to_crossroads() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.MAP.value, - ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY.value, - ) - ) - - def _go_to_white_house(self) -> None: - self._go_to_dm_lair_interior() - - self._obtain_yastard() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.HOTSPOT_CLOSET_DOOR.value, - ZorkGrandInquisitorItems.SPELL_NARWILE.value, - ) - ) - - def _go_to_walking_castle(self) -> None: - self._go_to_dm_lair_interior() - - self._obtain_obidil() - self.collect_by_name(ZorkGrandInquisitorItems.HOTSPOT_BLINDS.value) - - def _obtain_obidil(self) -> None: - self._go_to_crossroads() - self._go_to_gue_tech() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS.value, - ZorkGrandInquisitorItems.HOTSPOT_FROZEN_TREAT_MACHINE_COIN_SLOT.value, - ZorkGrandInquisitorItems.HOTSPOT_FROZEN_TREAT_MACHINE_DOORS.value, - ) - ) - - self._go_to_subway_flood_control_dam() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_REZROV.value, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_BUTTONS.value, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_DOORS.value, - ) - ) - - self._go_to_spell_lab_bridge() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SWORD.value, - ZorkGrandInquisitorItems.HOTSPOT_ROPE_BRIDGE.value, - ZorkGrandInquisitorItems.SPELL_GOLGATEM.value, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_LAB_CHASM.value, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER.value, - ) - ) - - def _obtain_snavig(self) -> None: - self._go_to_crossroads() - self._go_to_dm_lair_interior() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SCROLL_FRAGMENT_ANS.value, - ZorkGrandInquisitorItems.SCROLL_FRAGMENT_GIV.value, - ZorkGrandInquisitorItems.HOTSPOT_MIRROR.value, - ) - ) - - self._go_to_subway_flood_control_dam() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SPELL_REZROV.value, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_BUTTONS.value, - ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_DOORS.value, - ) - ) - - self._go_to_spell_lab_bridge() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.SWORD.value, - ZorkGrandInquisitorItems.HOTSPOT_ROPE_BRIDGE.value, - ZorkGrandInquisitorItems.SPELL_GOLGATEM.value, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_LAB_CHASM.value, - ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER.value, - ) - ) - - def _obtain_yastard(self) -> None: - self._go_to_crossroads() - self._go_to_dm_lair_interior() - - self.collect_by_name( - ( - ZorkGrandInquisitorItems.FLATHEADIA_FUDGE.value, - ZorkGrandInquisitorItems.HUNGUS_LARD.value, - ZorkGrandInquisitorItems.JAR_OF_HOTBUGS.value, - ZorkGrandInquisitorItems.QUELBEE_HONEYCOMB.value, - ZorkGrandInquisitorItems.MOSS_OF_MAREILON.value, - ZorkGrandInquisitorItems.MUG.value, - ) - ) - - -class AccessTestLocations(ZorkGrandInquisitorTestBase): - options = { - "deathsanity": "true", - "start_with_hotspot_items": "false", - } - - def test_access_locations_requiring_brogs_flickering_torch(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BROG_DO_GOOD.value, - ZorkGrandInquisitorLocations.BROG_EAT_ROCKS.value, - ZorkGrandInquisitorLocations.BROG_KNOW_DUMB_THAT_DUMB.value, - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.BROGS_FLICKERING_TORCH.value,)] - ) - - def test_access_locations_requiring_brogs_grue_egg(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BROG_DO_GOOD.value, - ZorkGrandInquisitorLocations.BROG_KNOW_DUMB_THAT_DUMB.value, - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.BROGS_GRUE_EGG.value,)] - ) - - def test_access_locations_requiring_brogs_plank(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.BROGS_PLANK.value,)] - ) - - def test_access_locations_requiring_flatheadia_fudge(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.OH_WOW_TALK_ABOUT_DEJA_VU.value, - ZorkGrandInquisitorEvents.KNOWS_YASTARD.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.FLATHEADIA_FUDGE.value,)] - ) - - def test_access_locations_requiring_griffs_air_pump(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.GRIFFS_AIR_PUMP.value,)] - ) - - def test_access_locations_requiring_griffs_dragon_tooth(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.GRIFFS_DRAGON_TOOTH.value,)] - ) - - def test_access_locations_requiring_griffs_inflatable_raft(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_RAFT.value,)] - ) - - def test_access_locations_requiring_griffs_inflatable_sea_captain(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.GRIFFS_INFLATABLE_SEA_CAPTAIN.value,)] - ) - - def test_access_locations_requiring_hammer(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BOING_BOING_BOING.value, - ZorkGrandInquisitorLocations.BONK.value, - ZorkGrandInquisitorLocations.FLYING_SNAPDRAGON.value, - ZorkGrandInquisitorLocations.IN_CASE_OF_ADVENTURE.value, - ZorkGrandInquisitorLocations.MUSHROOM_HAMMERED.value, - ZorkGrandInquisitorLocations.THROCKED_MUSHROOM_HAMMERED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HAMMER.value,)] - ) - - def test_access_locations_requiring_hungus_lard(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.OH_WOW_TALK_ABOUT_DEJA_VU.value, - ZorkGrandInquisitorLocations.OUTSMART_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.DEATH_OUTSMARTED_BY_THE_QUELBEES.value, - ZorkGrandInquisitorEvents.KNOWS_YASTARD.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HUNGUS_LARD.value,)] - ) - - def test_access_locations_requiring_jar_of_hotbugs(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.OH_WOW_TALK_ABOUT_DEJA_VU.value, - ZorkGrandInquisitorEvents.KNOWS_YASTARD.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.JAR_OF_HOTBUGS.value,)] - ) - - def test_access_locations_requiring_lantern(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.LANTERN.value,)] - ) - - def test_access_locations_requiring_large_telegraph_hammer(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.LARGE_TELEGRAPH_HAMMER.value,)] - ) - - def test_access_locations_requiring_lucys_playing_cards(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_1.value,)] - ) - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_2.value,)] - ) - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_3.value,)] - ) - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.LUCYS_PLAYING_CARD_4.value,)] - ) - - def test_access_locations_requiring_map(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.MAP.value,)] - ) - - def test_access_locations_requiring_mead_light(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.MEAD_LIGHT.value, - ZorkGrandInquisitorLocations.WANT_SOME_RYE_COURSE_YA_DO.value, - ZorkGrandInquisitorEvents.DOOR_DRANK_MEAD.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.MEAD_LIGHT.value,)] - ) - - def test_access_locations_requiring_moss_of_mareilon(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.OH_WOW_TALK_ABOUT_DEJA_VU.value, - ZorkGrandInquisitorEvents.KNOWS_YASTARD.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.MOSS_OF_MAREILON.value,)] - ) - - def test_access_locations_requiring_mug(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.OH_WOW_TALK_ABOUT_DEJA_VU.value, - ZorkGrandInquisitorEvents.KNOWS_YASTARD.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.MUG.value,)] - ) - - def test_access_locations_requiring_old_scratch_card(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_LOST_SOUL_TO_OLD_SCRATCH.value, - ZorkGrandInquisitorLocations.OLD_SCRATCH_WINNER.value, - ZorkGrandInquisitorEvents.ZORKMID_BILL_ACCESSIBLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.OLD_SCRATCH_CARD.value,)] - ) - - def test_access_locations_requiring_perma_suck_machine(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.SUCKING_ROCKS.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.PERMA_SUCK_MACHINE.value,)] - ) - - def test_access_locations_requiring_plastic_six_pack_holder(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.HELP_ME_CANT_BREATHE.value, - ZorkGrandInquisitorLocations.WHAT_ARE_YOU_STUPID.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.PLASTIC_SIX_PACK_HOLDER.value,)] - ) - - def test_access_locations_requiring_pouch_of_zorkmids(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.A_BIG_FAT_SASSY_2_HEADED_MONSTER.value, - ZorkGrandInquisitorLocations.A_LETTER_FROM_THE_WHITE_HOUSE.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorLocations.DEATH_YOURE_NOT_CHARON.value, - ZorkGrandInquisitorLocations.DONT_EVEN_START_WITH_US_SPARKY.value, - ZorkGrandInquisitorLocations.DRAGON_ARCHIPELAGO_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.DUNCE_LOCKER.value, - ZorkGrandInquisitorLocations.I_SPIT_ON_YOUR_FILTHY_COINAGE.value, - ZorkGrandInquisitorLocations.NOOOOOOOOOOOOO.value, - ZorkGrandInquisitorLocations.NOW_YOU_LOOK_LIKE_US_WHICH_IS_AN_IMPROVEMENT.value, - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.OPEN_THE_GATES_OF_HELL.value, - ZorkGrandInquisitorLocations.SOUVENIR.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.THIS_DOESNT_LOOK_ANYTHING_LIKE_THE_BROCHURE.value, - ZorkGrandInquisitorLocations.UH_OH_BROG_CANT_SWIM.value, - ZorkGrandInquisitorEvents.DALBOZ_LOCKER_OPENABLE.value, - ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE.value, - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_OBIDIL.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ZorkGrandInquisitorEvents.ZORK_ROCKS_ACTIVATED.value, - ZorkGrandInquisitorEvents.ZORK_ROCKS_SUCKABLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.POUCH_OF_ZORKMIDS.value,)] - ) - - def test_access_locations_requiring_prozork_tablet(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.PROZORKED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.PROZORK_TABLET.value,)] - ) - - def test_access_locations_requiring_quelbee_honeycomb(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.OH_WOW_TALK_ABOUT_DEJA_VU.value, - ZorkGrandInquisitorEvents.KNOWS_YASTARD.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.QUELBEE_HONEYCOMB.value,)] - ) - - def test_access_locations_requiring_rope(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.ALARM_SYSTEM_IS_DOWN.value, - ZorkGrandInquisitorLocations.ARTIFACTS_EXPLAINED.value, - ZorkGrandInquisitorLocations.A_BIG_FAT_SASSY_2_HEADED_MONSTER.value, - ZorkGrandInquisitorLocations.A_LETTER_FROM_THE_WHITE_HOUSE.value, - ZorkGrandInquisitorLocations.A_SMALLWAY.value, - ZorkGrandInquisitorLocations.BEAUTIFUL_THATS_PLENTY.value, - ZorkGrandInquisitorLocations.BEBURTT_DEMYSTIFIED.value, - ZorkGrandInquisitorLocations.BETTER_SPELL_MANUFACTURING_IN_UNDER_10_MINUTES.value, - ZorkGrandInquisitorLocations.BOING_BOING_BOING.value, - ZorkGrandInquisitorLocations.BONK.value, - ZorkGrandInquisitorLocations.BRAVE_SOULS_WANTED.value, - ZorkGrandInquisitorLocations.BROG_DO_GOOD.value, - ZorkGrandInquisitorLocations.BROG_EAT_ROCKS.value, - ZorkGrandInquisitorLocations.BROG_KNOW_DUMB_THAT_DUMB.value, - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME.value, - ZorkGrandInquisitorLocations.CASTLE_WATCHING_A_FIELD_GUIDE.value, - ZorkGrandInquisitorLocations.CAVES_NOTES.value, - ZorkGrandInquisitorLocations.CLOSING_THE_TIME_TUNNELS.value, - ZorkGrandInquisitorLocations.CRISIS_AVERTED.value, - ZorkGrandInquisitorLocations.DEATH_ATTACKED_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.DEATH_CLIMBED_OUT_OF_THE_WELL.value, - ZorkGrandInquisitorLocations.DEATH_EATEN_BY_A_GRUE.value, - ZorkGrandInquisitorLocations.DEATH_JUMPED_IN_BOTTOMLESS_PIT.value, - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.DEATH_OUTSMARTED_BY_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.DEATH_SLICED_UP_BY_THE_INVISIBLE_GUARD.value, - ZorkGrandInquisitorLocations.DEATH_STEPPED_INTO_THE_INFINITE.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorLocations.DEATH_THROCKED_THE_GRASS.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED_PERMANENTLY.value, - ZorkGrandInquisitorLocations.DEATH_YOURE_NOT_CHARON.value, - ZorkGrandInquisitorLocations.DEATH_ZORK_ROCKS_EXPLODED.value, - ZorkGrandInquisitorLocations.DENIED_BY_THE_LAKE_MONSTER.value, - ZorkGrandInquisitorLocations.DESPERATELY_SEEKING_TUTOR.value, - ZorkGrandInquisitorLocations.DONT_EVEN_START_WITH_US_SPARKY.value, - ZorkGrandInquisitorLocations.DOOOOOOWN.value, - ZorkGrandInquisitorLocations.DOWN.value, - ZorkGrandInquisitorLocations.DRAGON_ARCHIPELAGO_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.DUNCE_LOCKER.value, - ZorkGrandInquisitorLocations.EGGPLANTS.value, - ZorkGrandInquisitorLocations.EMERGENCY_MAGICATRONIC_MESSAGE.value, - ZorkGrandInquisitorLocations.ENJOY_YOUR_TRIP.value, - ZorkGrandInquisitorLocations.FAT_LOT_OF_GOOD_THATLL_DO_YA.value, - ZorkGrandInquisitorLocations.FLOOD_CONTROL_DAM_3_THE_NOT_REMOTELY_BORING_TALE.value, - ZorkGrandInquisitorLocations.FLYING_SNAPDRAGON.value, - ZorkGrandInquisitorLocations.FROBUARY_3_UNDERGROUNDHOG_DAY.value, - ZorkGrandInquisitorLocations.GETTING_SOME_CHANGE.value, - ZorkGrandInquisitorLocations.GUE_TECH_DEANS_LIST.value, - ZorkGrandInquisitorLocations.GUE_TECH_ENTRANCE_EXAM.value, - ZorkGrandInquisitorLocations.GUE_TECH_HEALTH_MEMO.value, - ZorkGrandInquisitorLocations.GUE_TECH_MAGEMEISTERS.value, - ZorkGrandInquisitorLocations.HAVE_A_HELL_OF_A_DAY.value, - ZorkGrandInquisitorLocations.HELLO_THIS_IS_SHONA_FROM_GURTH_PUBLISHING.value, - ZorkGrandInquisitorLocations.HEY_FREE_DIRT.value, - ZorkGrandInquisitorLocations.HI_MY_NAME_IS_DOUG.value, - ZorkGrandInquisitorLocations.HMMM_INFORMATIVE_YET_DEEPLY_DISTURBING.value, - ZorkGrandInquisitorLocations.HOLD_ON_FOR_AN_IMPORTANT_MESSAGE.value, - ZorkGrandInquisitorLocations.HOW_TO_HYPNOTIZE_YOURSELF.value, - ZorkGrandInquisitorLocations.HOW_TO_WIN_AT_DOUBLE_FANUCCI.value, - ZorkGrandInquisitorLocations.I_DONT_THINK_YOU_WOULDVE_WANTED_THAT_TO_WORK_ANYWAY.value, - ZorkGrandInquisitorLocations.I_SPIT_ON_YOUR_FILTHY_COINAGE.value, - ZorkGrandInquisitorLocations.IMBUE_BEBURTT.value, - ZorkGrandInquisitorLocations.INTO_THE_FOLIAGE.value, - ZorkGrandInquisitorLocations.IN_CASE_OF_ADVENTURE.value, - ZorkGrandInquisitorLocations.IN_MAGIC_WE_TRUST.value, - ZorkGrandInquisitorLocations.INVISIBLE_FLOWERS.value, - ZorkGrandInquisitorLocations.I_HOPE_YOU_CAN_CLIMB_UP_THERE.value, - ZorkGrandInquisitorLocations.I_LIKE_YOUR_STYLE.value, - ZorkGrandInquisitorLocations.LIT_SUNFLOWERS.value, - ZorkGrandInquisitorLocations.MAGIC_FOREVER.value, - ZorkGrandInquisitorLocations.MAILED_IT_TO_HELL.value, - ZorkGrandInquisitorLocations.MAKE_LOVE_NOT_WAR.value, - ZorkGrandInquisitorLocations.MIKES_PANTS.value, - ZorkGrandInquisitorLocations.MUSHROOM_HAMMERED.value, - ZorkGrandInquisitorLocations.NATIONAL_TREASURE.value, - ZorkGrandInquisitorLocations.NATURAL_AND_SUPERNATURAL_CREATURES_OF_QUENDOR.value, - ZorkGrandInquisitorLocations.NO_BONDAGE.value, - ZorkGrandInquisitorLocations.NOOOOOOOOOOOOO.value, - ZorkGrandInquisitorLocations.NOTHIN_LIKE_A_GOOD_STOGIE.value, - ZorkGrandInquisitorLocations.NOW_YOU_LOOK_LIKE_US_WHICH_IS_AN_IMPROVEMENT.value, - ZorkGrandInquisitorLocations.OBIDIL_DRIED_UP.value, - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.OH_WOW_TALK_ABOUT_DEJA_VU.value, - ZorkGrandInquisitorLocations.OPEN_THE_GATES_OF_HELL.value, - ZorkGrandInquisitorLocations.OUTSMART_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.PERMASEAL.value, - ZorkGrandInquisitorLocations.PLEASE_DONT_THROCK_THE_GRASS.value, - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.PROZORKED.value, - ZorkGrandInquisitorLocations.REASSEMBLE_SNAVIG.value, - ZorkGrandInquisitorLocations.RESTOCKED_ON_GRUESDAY.value, - ZorkGrandInquisitorLocations.RIGHT_HELLO_YES_UH_THIS_IS_SNEFFLE.value, - ZorkGrandInquisitorLocations.RIGHT_UH_SORRY_ITS_ME_AGAIN_SNEFFLE.value, - ZorkGrandInquisitorLocations.SNAVIG_REPAIRED.value, - ZorkGrandInquisitorLocations.SOUVENIR.value, - ZorkGrandInquisitorLocations.STRAIGHT_TO_HELL.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.SUCKING_ROCKS.value, - ZorkGrandInquisitorLocations.TAMING_YOUR_SNAPDRAGON.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.THATS_A_ROPE.value, - ZorkGrandInquisitorLocations.THATS_IT_JUST_KEEP_HITTING_THOSE_BUTTONS.value, - ZorkGrandInquisitorLocations.THATS_STILL_A_ROPE.value, - ZorkGrandInquisitorLocations.THE_ALCHEMICAL_DEBACLE.value, - ZorkGrandInquisitorLocations.THE_ENDLESS_FIRE.value, - ZorkGrandInquisitorLocations.THE_FLATHEADIAN_FUDGE_FIASCO.value, - ZorkGrandInquisitorLocations.THE_PERILS_OF_MAGIC.value, - ZorkGrandInquisitorLocations.THE_UNDERGROUND_UNDERGROUND.value, - ZorkGrandInquisitorLocations.THIS_DOESNT_LOOK_ANYTHING_LIKE_THE_BROCHURE.value, - ZorkGrandInquisitorLocations.THROCKED_MUSHROOM_HAMMERED.value, - ZorkGrandInquisitorLocations.TIME_TRAVEL_FOR_DUMMIES.value, - ZorkGrandInquisitorLocations.UH_OH_BROG_CANT_SWIM.value, - ZorkGrandInquisitorLocations.UMBRELLA_FLOWERS.value, - ZorkGrandInquisitorLocations.UP.value, - ZorkGrandInquisitorLocations.USELESS_BUT_FUN.value, - ZorkGrandInquisitorLocations.UUUUUP.value, - ZorkGrandInquisitorLocations.VOYAGE_OF_CAPTAIN_ZAHAB.value, - ZorkGrandInquisitorLocations.WANT_SOME_RYE_COURSE_YA_DO.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorLocations.WHITE_HOUSE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.WOW_IVE_NEVER_GONE_INSIDE_HIM_BEFORE.value, - ZorkGrandInquisitorLocations.YAD_GOHDNUORGREDNU_3_YRAUBORF.value, - ZorkGrandInquisitorLocations.YOU_DONT_GO_MESSING_WITH_A_MANS_ZIPPER.value, - ZorkGrandInquisitorLocations.YOU_GAINED_86_EXPERIENCE_POINTS.value, - ZorkGrandInquisitorLocations.YOUR_PUNY_WEAPONS_DONT_PHASE_ME_BABY.value, - ZorkGrandInquisitorEvents.CHARON_CALLED.value, - ZorkGrandInquisitorEvents.DAM_DESTROYED.value, - ZorkGrandInquisitorEvents.DOOR_DRANK_MEAD.value, - ZorkGrandInquisitorEvents.DOOR_SMOKED_CIGAR.value, - ZorkGrandInquisitorEvents.DALBOZ_LOCKER_OPENABLE.value, - ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE.value, - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_OBIDIL.value, - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_SNAVIG.value, - ZorkGrandInquisitorEvents.KNOWS_BEBURTT.value, - ZorkGrandInquisitorEvents.KNOWS_OBIDIL.value, - ZorkGrandInquisitorEvents.KNOWS_SNAVIG.value, - ZorkGrandInquisitorEvents.KNOWS_YASTARD.value, - ZorkGrandInquisitorEvents.ROPE_GLORFABLE.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ZorkGrandInquisitorEvents.WHITE_HOUSE_LETTER_MAILABLE.value, - ZorkGrandInquisitorEvents.ZORK_ROCKS_ACTIVATED.value, - ZorkGrandInquisitorEvents.ZORK_ROCKS_SUCKABLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.ROPE.value,)] - ) - - def test_access_locations_requiring_scroll_fragment_ans(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.REASSEMBLE_SNAVIG.value, - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_SNAVIG.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SCROLL_FRAGMENT_ANS.value,)] - ) - - def test_access_locations_requiring_scroll_fragment_giv(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.REASSEMBLE_SNAVIG.value, - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_SNAVIG.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SCROLL_FRAGMENT_GIV.value,)] - ) - - def test_access_locations_requiring_shovel(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.HEY_FREE_DIRT.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SHOVEL.value,)] - ) - - def test_access_locations_requiring_snapdragon(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BOING_BOING_BOING.value, - ZorkGrandInquisitorLocations.FLYING_SNAPDRAGON.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SNAPDRAGON.value,)] - ) - - def test_access_locations_requiring_student_id(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.STUDENT_ID.value,)] - ) - - def test_access_locations_requiring_subway_token(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.THE_UNDERGROUND_UNDERGROUND.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SUBWAY_TOKEN.value,)] - ) - - def test_access_locations_requiring_sword(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.CLOSING_THE_TIME_TUNNELS.value, - ZorkGrandInquisitorLocations.DEATH_ATTACKED_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED_PERMANENTLY.value, - ZorkGrandInquisitorLocations.DONT_EVEN_START_WITH_US_SPARKY.value, - ZorkGrandInquisitorLocations.HMMM_INFORMATIVE_YET_DEEPLY_DISTURBING.value, - ZorkGrandInquisitorLocations.I_HOPE_YOU_CAN_CLIMB_UP_THERE.value, - ZorkGrandInquisitorLocations.I_LIKE_YOUR_STYLE.value, - ZorkGrandInquisitorLocations.IMBUE_BEBURTT.value, - ZorkGrandInquisitorLocations.INTO_THE_FOLIAGE.value, - ZorkGrandInquisitorLocations.MAKE_LOVE_NOT_WAR.value, - ZorkGrandInquisitorLocations.OBIDIL_DRIED_UP.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.OUTSMART_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.PERMASEAL.value, - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.SNAVIG_REPAIRED.value, - ZorkGrandInquisitorLocations.STRAIGHT_TO_HELL.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.THE_ALCHEMICAL_DEBACLE.value, - ZorkGrandInquisitorLocations.THE_ENDLESS_FIRE.value, - ZorkGrandInquisitorLocations.THE_FLATHEADIAN_FUDGE_FIASCO.value, - ZorkGrandInquisitorLocations.THE_PERILS_OF_MAGIC.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorLocations.YOU_GAINED_86_EXPERIENCE_POINTS.value, - ZorkGrandInquisitorLocations.YOUR_PUNY_WEAPONS_DONT_PHASE_ME_BABY.value, - ZorkGrandInquisitorEvents.KNOWS_BEBURTT.value, - ZorkGrandInquisitorEvents.KNOWS_OBIDIL.value, - ZorkGrandInquisitorEvents.KNOWS_SNAVIG.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SWORD.value,)] - ) - - def test_access_locations_requiring_zimdor_scroll(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.WANT_SOME_RYE_COURSE_YA_DO.value, - ZorkGrandInquisitorEvents.DOOR_DRANK_MEAD.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.ZIMDOR_SCROLL.value,)] - ) - - def test_access_locations_requiring_zork_rocks(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorEvents.ZORK_ROCKS_ACTIVATED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.ZORK_ROCKS.value,)] - ) - - def test_access_locations_requiring_hotspot_666_mailbox(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.A_LETTER_FROM_THE_WHITE_HOUSE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_666_MAILBOX.value,)] - ) - - def test_access_locations_requiring_hotspot_alpines_quandry_card_slots(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_ALPINES_QUANDRY_CARD_SLOTS.value,)] - ) - - def test_access_locations_requiring_hotspot_blank_scroll_box(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.IMBUE_BEBURTT.value, - ZorkGrandInquisitorEvents.KNOWS_BEBURTT.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_BLANK_SCROLL_BOX.value,)] - ) - - def test_access_locations_requiring_hotspot_blinds(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DENIED_BY_THE_LAKE_MONSTER.value, - ZorkGrandInquisitorLocations.WOW_IVE_NEVER_GONE_INSIDE_HIM_BEFORE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_BLINDS.value,)] - ) - - def test_access_locations_requiring_hotspot_candy_machine_buttons(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DUNCE_LOCKER.value, - ZorkGrandInquisitorLocations.NOOOOOOOOOOOOO.value, - ZorkGrandInquisitorEvents.DALBOZ_LOCKER_OPENABLE.value, - ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE.value, - ZorkGrandInquisitorEvents.ZORK_ROCKS_SUCKABLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_BUTTONS.value,)] - ) - - def test_access_locations_requiring_hotspot_candy_machine_coin_slot(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DUNCE_LOCKER.value, - ZorkGrandInquisitorLocations.NOOOOOOOOOOOOO.value, - ZorkGrandInquisitorEvents.DALBOZ_LOCKER_OPENABLE.value, - ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE.value, - ZorkGrandInquisitorEvents.ZORK_ROCKS_SUCKABLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_COIN_SLOT.value,)] - ) - - def test_access_locations_requiring_hotspot_candy_machine_vacuum_slot(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.SUCKING_ROCKS.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_CANDY_MACHINE_VACUUM_SLOT.value,)] - ) - - def test_access_locations_requiring_hotspot_change_machine_slot(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.GETTING_SOME_CHANGE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_CHANGE_MACHINE_SLOT.value,)] - ) - - def test_access_locations_requiring_hotspot_closet_door(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BROG_DO_GOOD.value, - ZorkGrandInquisitorLocations.BROG_EAT_ROCKS.value, - ZorkGrandInquisitorLocations.BROG_KNOW_DUMB_THAT_DUMB.value, - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME.value, - ZorkGrandInquisitorLocations.DOOOOOOWN.value, - ZorkGrandInquisitorLocations.DOWN.value, - ZorkGrandInquisitorLocations.UP.value, - ZorkGrandInquisitorLocations.UUUUUP.value, - ZorkGrandInquisitorLocations.MAILED_IT_TO_HELL.value, - ZorkGrandInquisitorLocations.WHITE_HOUSE_TIME_TUNNEL.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ZorkGrandInquisitorEvents.WHITE_HOUSE_LETTER_MAILABLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_CLOSET_DOOR.value,)] - ) - - def test_access_locations_requiring_hotspot_closing_the_time_tunnels_hammer_slot(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_HAMMER_SLOT.value,)] - ) - - def test_access_locations_requiring_hotspot_closing_the_time_tunnels_lever(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_CLOSING_THE_TIME_TUNNELS_LEVER.value,)] - ) - - def test_access_locations_requiring_hotspot_cooking_pot(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BROG_DO_GOOD.value, - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_COOKING_POT.value,)] - ) - - def test_access_locations_requiring_hotspot_dented_locker(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.CRISIS_AVERTED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_DENTED_LOCKER.value,)] - ) - - def test_access_locations_requiring_hotspot_dirt_mound(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.HEY_FREE_DIRT.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_DIRT_MOUND.value,)] - ) - - def test_access_locations_requiring_hotspot_dock_winch(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.HELP_ME_CANT_BREATHE.value, - ZorkGrandInquisitorLocations.NO_BONDAGE.value, - ZorkGrandInquisitorLocations.YOU_WANT_A_PIECE_OF_ME_DOCK_BOY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_DOCK_WINCH.value,)] - ) - - def test_access_locations_requiring_hotspot_dragon_claw(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_DRAGON_CLAW.value,)] - ) - - def test_access_locations_requiring_hotspot_dragon_nostrils(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_DRAGON_NOSTRILS.value,)] - ) - - def test_access_locations_requiring_hotspot_dungeon_masters_lair_entrance(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.INTO_THE_FOLIAGE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_DUNGEON_MASTERS_LAIR_ENTRANCE.value,)] - ) - - def test_access_locations_requiring_hotspot_flood_control_buttons(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.NATIONAL_TREASURE.value, - ZorkGrandInquisitorEvents.DAM_DESTROYED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_BUTTONS.value,)] - ) - - def test_access_locations_requiring_hotspot_flood_control_doors(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.NATIONAL_TREASURE.value, - ZorkGrandInquisitorEvents.DAM_DESTROYED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_FLOOD_CONTROL_DOORS.value,)] - ) - - def test_access_locations_requiring_hotspot_frozen_treat_machine_coin_slot(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_OBIDIL.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_FROZEN_TREAT_MACHINE_COIN_SLOT.value,)] - ) - - def test_access_locations_requiring_hotspot_frozen_treat_machine_doors(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_OBIDIL.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_FROZEN_TREAT_MACHINE_DOORS.value,)] - ) - - def test_access_locations_requiring_hotspot_glass_case(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.IN_CASE_OF_ADVENTURE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_GLASS_CASE.value,)] - ) - - def test_access_locations_requiring_hotspot_grand_inquisitor_doll(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.ARREST_THE_VANDAL.value, - ZorkGrandInquisitorLocations.DEATH_ARRESTED_WITH_JACK.value, - ZorkGrandInquisitorLocations.FIRE_FIRE.value, - ZorkGrandInquisitorLocations.PLANETFALL.value, - ZorkGrandInquisitorLocations.TALK_TO_ME_GRAND_INQUISITOR.value, - ZorkGrandInquisitorEvents.LANTERN_DALBOZ_ACCESSIBLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL.value,)] - ) - - def test_access_locations_requiring_hotspot_gue_tech_door(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_GUE_TECH_DOOR.value,)] - ) - - def test_access_locations_requiring_hotspot_gue_tech_grass(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_THROCKED_THE_GRASS.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_GUE_TECH_GRASS.value,)] - ) - - def test_access_locations_requiring_hotspot_hades_phone_buttons(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.A_BIG_FAT_SASSY_2_HEADED_MONSTER.value, - ZorkGrandInquisitorLocations.A_LETTER_FROM_THE_WHITE_HOUSE.value, - ZorkGrandInquisitorLocations.DEATH_YOURE_NOT_CHARON.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorLocations.DONT_EVEN_START_WITH_US_SPARKY.value, - ZorkGrandInquisitorLocations.DRAGON_ARCHIPELAGO_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.HAVE_A_HELL_OF_A_DAY.value, - ZorkGrandInquisitorLocations.NOW_YOU_LOOK_LIKE_US_WHICH_IS_AN_IMPROVEMENT.value, - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.OPEN_THE_GATES_OF_HELL.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.THIS_DOESNT_LOOK_ANYTHING_LIKE_THE_BROCHURE.value, - ZorkGrandInquisitorLocations.UH_OH_BROG_CANT_SWIM.value, - ZorkGrandInquisitorEvents.CHARON_CALLED.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_BUTTONS.value,)] - ) - - def test_access_locations_requiring_hotspot_hades_phone_receiver(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.A_BIG_FAT_SASSY_2_HEADED_MONSTER.value, - ZorkGrandInquisitorLocations.A_LETTER_FROM_THE_WHITE_HOUSE.value, - ZorkGrandInquisitorLocations.DEATH_YOURE_NOT_CHARON.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorLocations.DONT_EVEN_START_WITH_US_SPARKY.value, - ZorkGrandInquisitorLocations.DRAGON_ARCHIPELAGO_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.HAVE_A_HELL_OF_A_DAY.value, - ZorkGrandInquisitorLocations.NOW_YOU_LOOK_LIKE_US_WHICH_IS_AN_IMPROVEMENT.value, - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.OPEN_THE_GATES_OF_HELL.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.THIS_DOESNT_LOOK_ANYTHING_LIKE_THE_BROCHURE.value, - ZorkGrandInquisitorLocations.UH_OH_BROG_CANT_SWIM.value, - ZorkGrandInquisitorEvents.CHARON_CALLED.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_HADES_PHONE_RECEIVER.value,)] - ) - - def test_access_locations_requiring_hotspot_harry(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.YOUR_PUNY_WEAPONS_DONT_PHASE_ME_BABY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_HARRY.value,)] - ) - - def test_access_locations_requiring_hotspot_harrys_ashtray(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.NOTHIN_LIKE_A_GOOD_STOGIE.value, - ZorkGrandInquisitorEvents.DOOR_SMOKED_CIGAR.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_HARRYS_ASHTRAY.value,)] - ) - - def test_access_locations_requiring_hotspot_harrys_bird_bath(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.WANT_SOME_RYE_COURSE_YA_DO.value, - ZorkGrandInquisitorEvents.DOOR_DRANK_MEAD.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_HARRYS_BIRD_BATH.value,)] - ) - - def test_access_locations_requiring_hotspot_in_magic_we_trust_door(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.IN_MAGIC_WE_TRUST.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_IN_MAGIC_WE_TRUST_DOOR.value,)] - ) - - def test_access_locations_requiring_hotspot_jacks_door(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.MEAD_LIGHT.value, - ZorkGrandInquisitorLocations.NO_AUTOGRAPHS.value, - ZorkGrandInquisitorLocations.THATS_A_ROPE.value, - ZorkGrandInquisitorLocations.WHAT_ARE_YOU_STUPID.value, - ZorkGrandInquisitorEvents.CIGAR_ACCESSIBLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR.value,)] - ) - - def test_access_locations_requiring_hotspot_loudspeaker_volume_buttons(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.THATS_THE_SPIRIT.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_LOUDSPEAKER_VOLUME_BUTTONS.value,)] - ) - - def test_access_locations_requiring_hotspot_mailbox_door(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.MAILED_IT_TO_HELL.value, - ZorkGrandInquisitorEvents.WHITE_HOUSE_LETTER_MAILABLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_DOOR.value,)] - ) - - def test_access_locations_requiring_hotspot_mailbox_flag(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DOOOOOOWN.value, - ZorkGrandInquisitorLocations.DOWN.value, - ZorkGrandInquisitorLocations.MAILED_IT_TO_HELL.value, - ZorkGrandInquisitorLocations.UP.value, - ZorkGrandInquisitorLocations.UUUUUP.value, - ZorkGrandInquisitorEvents.WHITE_HOUSE_LETTER_MAILABLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_MAILBOX_FLAG.value,)] - ) - - def test_access_locations_requiring_hotspot_mirror(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.REASSEMBLE_SNAVIG.value, - ZorkGrandInquisitorLocations.YAD_GOHDNUORGREDNU_3_YRAUBORF.value, - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_SNAVIG.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_MIRROR.value,)] - ) - - def test_access_locations_requiring_hotspot_monastery_vent(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.CLOSING_THE_TIME_TUNNELS.value, - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED_PERMANENTLY.value, - ZorkGrandInquisitorLocations.HMMM_INFORMATIVE_YET_DEEPLY_DISTURBING.value, - ZorkGrandInquisitorLocations.I_HOPE_YOU_CAN_CLIMB_UP_THERE.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.PERMASEAL.value, - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.STRAIGHT_TO_HELL.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.THE_ALCHEMICAL_DEBACLE.value, - ZorkGrandInquisitorLocations.THE_ENDLESS_FIRE.value, - ZorkGrandInquisitorLocations.THE_FLATHEADIAN_FUDGE_FIASCO.value, - ZorkGrandInquisitorLocations.THE_PERILS_OF_MAGIC.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_MONASTERY_VENT.value,)] - ) - - def test_access_locations_requiring_hotspot_mossy_grate(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BEAUTIFUL_THATS_PLENTY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_MOSSY_GRATE.value,)] - ) - - def test_access_locations_requiring_hotspot_port_foozle_past_tavern_door(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_PORT_FOOZLE_PAST_TAVERN_DOOR.value,)] - ) - - def test_access_locations_requiring_hotspot_purple_words(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.A_SMALLWAY.value, - ZorkGrandInquisitorLocations.CRISIS_AVERTED.value, - ZorkGrandInquisitorLocations.DEATH_STEPPED_INTO_THE_INFINITE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_PURPLE_WORDS.value,)] - ) - - def test_access_locations_requiring_hotspot_quelbee_hive(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_ATTACKED_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.DEATH_OUTSMARTED_BY_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.OUTSMART_THE_QUELBEES.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_QUELBEE_HIVE.value,)] - ) - - def test_access_locations_requiring_hotspot_rope_bridge(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.I_LIKE_YOUR_STYLE.value, - ZorkGrandInquisitorLocations.IMBUE_BEBURTT.value, - ZorkGrandInquisitorLocations.OBIDIL_DRIED_UP.value, - ZorkGrandInquisitorLocations.SNAVIG_REPAIRED.value, - ZorkGrandInquisitorLocations.YOU_GAINED_86_EXPERIENCE_POINTS.value, - ZorkGrandInquisitorEvents.KNOWS_BEBURTT.value, - ZorkGrandInquisitorEvents.KNOWS_OBIDIL.value, - ZorkGrandInquisitorEvents.KNOWS_SNAVIG.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_ROPE_BRIDGE.value,)] - ) - - def test_access_locations_requiring_hotspot_skull_cage(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_SKULL_CAGE.value,)] - ) - - def test_access_locations_requiring_hotspot_snapdragon(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BONK.value, - ZorkGrandInquisitorLocations.I_DONT_THINK_YOU_WOULDVE_WANTED_THAT_TO_WORK_ANYWAY.value, - ZorkGrandInquisitorLocations.PROZORKED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_SNAPDRAGON.value,)] - ) - - def test_access_locations_requiring_hotspot_soda_machine_buttons(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorEvents.ZORK_ROCKS_ACTIVATED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_SODA_MACHINE_BUTTONS.value,)] - ) - - def test_access_locations_requiring_hotspot_soda_machine_coin_slot(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorEvents.ZORK_ROCKS_ACTIVATED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_SODA_MACHINE_COIN_SLOT.value,)] - ) - - def test_access_locations_requiring_hotspot_souvenir_coin_slot(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.SOUVENIR.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_SOUVENIR_COIN_SLOT.value,)] - ) - - def test_access_locations_requiring_hotspot_spell_checker(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.IMBUE_BEBURTT.value, - ZorkGrandInquisitorLocations.OBIDIL_DRIED_UP.value, - ZorkGrandInquisitorLocations.SNAVIG_REPAIRED.value, - ZorkGrandInquisitorEvents.KNOWS_BEBURTT.value, - ZorkGrandInquisitorEvents.KNOWS_OBIDIL.value, - ZorkGrandInquisitorEvents.KNOWS_SNAVIG.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_SPELL_CHECKER.value,)] - ) - - def test_access_locations_requiring_hotspot_spell_lab_chasm(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.I_LIKE_YOUR_STYLE.value, - ZorkGrandInquisitorLocations.IMBUE_BEBURTT.value, - ZorkGrandInquisitorLocations.OBIDIL_DRIED_UP.value, - ZorkGrandInquisitorLocations.SNAVIG_REPAIRED.value, - ZorkGrandInquisitorEvents.KNOWS_BEBURTT.value, - ZorkGrandInquisitorEvents.KNOWS_OBIDIL.value, - ZorkGrandInquisitorEvents.KNOWS_SNAVIG.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_SPELL_LAB_CHASM.value,)] - ) - - def test_access_locations_requiring_hotspot_spring_mushroom(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BOING_BOING_BOING.value, - ZorkGrandInquisitorLocations.FLYING_SNAPDRAGON.value, - ZorkGrandInquisitorLocations.MUSHROOM_HAMMERED.value, - ZorkGrandInquisitorLocations.THROCKED_MUSHROOM_HAMMERED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_SPRING_MUSHROOM.value,)] - ) - - def test_access_locations_requiring_hotspot_student_id_machine(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_STUDENT_ID_MACHINE.value,)] - ) - - def test_access_locations_requiring_hotspot_subway_token_slot(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.THE_UNDERGROUND_UNDERGROUND.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_SUBWAY_TOKEN_SLOT.value,)] - ) - - def test_access_locations_requiring_hotspot_tavern_fly(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_TAVERN_FLY.value,)] - ) - - def test_access_locations_requiring_hotspot_totemizer_switch(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.CLOSING_THE_TIME_TUNNELS.value, - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED_PERMANENTLY.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.STRAIGHT_TO_HELL.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.THE_ALCHEMICAL_DEBACLE.value, - ZorkGrandInquisitorLocations.THE_ENDLESS_FIRE.value, - ZorkGrandInquisitorLocations.THE_FLATHEADIAN_FUDGE_FIASCO.value, - ZorkGrandInquisitorLocations.THE_PERILS_OF_MAGIC.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_SWITCH.value,)] - ) - - def test_access_locations_requiring_hotspot_totemizer_wheels(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.CLOSING_THE_TIME_TUNNELS.value, - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.STRAIGHT_TO_HELL.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.THE_ALCHEMICAL_DEBACLE.value, - ZorkGrandInquisitorLocations.THE_ENDLESS_FIRE.value, - ZorkGrandInquisitorLocations.THE_FLATHEADIAN_FUDGE_FIASCO.value, - ZorkGrandInquisitorLocations.THE_PERILS_OF_MAGIC.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_TOTEMIZER_WHEELS.value,)] - ) - - def test_access_locations_requiring_hotspot_well(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.ALARM_SYSTEM_IS_DOWN.value, - ZorkGrandInquisitorLocations.ARTIFACTS_EXPLAINED.value, - ZorkGrandInquisitorLocations.A_BIG_FAT_SASSY_2_HEADED_MONSTER.value, - ZorkGrandInquisitorLocations.A_LETTER_FROM_THE_WHITE_HOUSE.value, - ZorkGrandInquisitorLocations.A_SMALLWAY.value, - ZorkGrandInquisitorLocations.BEAUTIFUL_THATS_PLENTY.value, - ZorkGrandInquisitorLocations.BEBURTT_DEMYSTIFIED.value, - ZorkGrandInquisitorLocations.BETTER_SPELL_MANUFACTURING_IN_UNDER_10_MINUTES.value, - ZorkGrandInquisitorLocations.BOING_BOING_BOING.value, - ZorkGrandInquisitorLocations.BONK.value, - ZorkGrandInquisitorLocations.BRAVE_SOULS_WANTED.value, - ZorkGrandInquisitorLocations.BROG_DO_GOOD.value, - ZorkGrandInquisitorLocations.BROG_EAT_ROCKS.value, - ZorkGrandInquisitorLocations.BROG_KNOW_DUMB_THAT_DUMB.value, - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME.value, - ZorkGrandInquisitorLocations.CASTLE_WATCHING_A_FIELD_GUIDE.value, - ZorkGrandInquisitorLocations.CAVES_NOTES.value, - ZorkGrandInquisitorLocations.CLOSING_THE_TIME_TUNNELS.value, - ZorkGrandInquisitorLocations.CRISIS_AVERTED.value, - ZorkGrandInquisitorLocations.DEATH_ATTACKED_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.DEATH_CLIMBED_OUT_OF_THE_WELL.value, - ZorkGrandInquisitorLocations.DEATH_EATEN_BY_A_GRUE.value, - ZorkGrandInquisitorLocations.DEATH_JUMPED_IN_BOTTOMLESS_PIT.value, - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.DEATH_OUTSMARTED_BY_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.DEATH_SLICED_UP_BY_THE_INVISIBLE_GUARD.value, - ZorkGrandInquisitorLocations.DEATH_STEPPED_INTO_THE_INFINITE.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorLocations.DEATH_THROCKED_THE_GRASS.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED.value, - ZorkGrandInquisitorLocations.DEATH_TOTEMIZED_PERMANENTLY.value, - ZorkGrandInquisitorLocations.DEATH_YOURE_NOT_CHARON.value, - ZorkGrandInquisitorLocations.DEATH_ZORK_ROCKS_EXPLODED.value, - ZorkGrandInquisitorLocations.DENIED_BY_THE_LAKE_MONSTER.value, - ZorkGrandInquisitorLocations.DESPERATELY_SEEKING_TUTOR.value, - ZorkGrandInquisitorLocations.DONT_EVEN_START_WITH_US_SPARKY.value, - ZorkGrandInquisitorLocations.DOOOOOOWN.value, - ZorkGrandInquisitorLocations.DOWN.value, - ZorkGrandInquisitorLocations.DRAGON_ARCHIPELAGO_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.DUNCE_LOCKER.value, - ZorkGrandInquisitorLocations.EGGPLANTS.value, - ZorkGrandInquisitorLocations.EMERGENCY_MAGICATRONIC_MESSAGE.value, - ZorkGrandInquisitorLocations.ENJOY_YOUR_TRIP.value, - ZorkGrandInquisitorLocations.FAT_LOT_OF_GOOD_THATLL_DO_YA.value, - ZorkGrandInquisitorLocations.FLOOD_CONTROL_DAM_3_THE_NOT_REMOTELY_BORING_TALE.value, - ZorkGrandInquisitorLocations.FLYING_SNAPDRAGON.value, - ZorkGrandInquisitorLocations.FROBUARY_3_UNDERGROUNDHOG_DAY.value, - ZorkGrandInquisitorLocations.GETTING_SOME_CHANGE.value, - ZorkGrandInquisitorLocations.GUE_TECH_DEANS_LIST.value, - ZorkGrandInquisitorLocations.GUE_TECH_ENTRANCE_EXAM.value, - ZorkGrandInquisitorLocations.GUE_TECH_HEALTH_MEMO.value, - ZorkGrandInquisitorLocations.GUE_TECH_MAGEMEISTERS.value, - ZorkGrandInquisitorLocations.HAVE_A_HELL_OF_A_DAY.value, - ZorkGrandInquisitorLocations.HELLO_THIS_IS_SHONA_FROM_GURTH_PUBLISHING.value, - ZorkGrandInquisitorLocations.HEY_FREE_DIRT.value, - ZorkGrandInquisitorLocations.HI_MY_NAME_IS_DOUG.value, - ZorkGrandInquisitorLocations.HMMM_INFORMATIVE_YET_DEEPLY_DISTURBING.value, - ZorkGrandInquisitorLocations.HOLD_ON_FOR_AN_IMPORTANT_MESSAGE.value, - ZorkGrandInquisitorLocations.HOW_TO_HYPNOTIZE_YOURSELF.value, - ZorkGrandInquisitorLocations.HOW_TO_WIN_AT_DOUBLE_FANUCCI.value, - ZorkGrandInquisitorLocations.I_DONT_THINK_YOU_WOULDVE_WANTED_THAT_TO_WORK_ANYWAY.value, - ZorkGrandInquisitorLocations.I_SPIT_ON_YOUR_FILTHY_COINAGE.value, - ZorkGrandInquisitorLocations.IMBUE_BEBURTT.value, - ZorkGrandInquisitorLocations.INTO_THE_FOLIAGE.value, - ZorkGrandInquisitorLocations.IN_CASE_OF_ADVENTURE.value, - ZorkGrandInquisitorLocations.IN_MAGIC_WE_TRUST.value, - ZorkGrandInquisitorLocations.INVISIBLE_FLOWERS.value, - ZorkGrandInquisitorLocations.I_HOPE_YOU_CAN_CLIMB_UP_THERE.value, - ZorkGrandInquisitorLocations.I_LIKE_YOUR_STYLE.value, - ZorkGrandInquisitorLocations.LIT_SUNFLOWERS.value, - ZorkGrandInquisitorLocations.MAGIC_FOREVER.value, - ZorkGrandInquisitorLocations.MAILED_IT_TO_HELL.value, - ZorkGrandInquisitorLocations.MAKE_LOVE_NOT_WAR.value, - ZorkGrandInquisitorLocations.MIKES_PANTS.value, - ZorkGrandInquisitorLocations.MUSHROOM_HAMMERED.value, - ZorkGrandInquisitorLocations.NATIONAL_TREASURE.value, - ZorkGrandInquisitorLocations.NATURAL_AND_SUPERNATURAL_CREATURES_OF_QUENDOR.value, - ZorkGrandInquisitorLocations.NOOOOOOOOOOOOO.value, - ZorkGrandInquisitorLocations.NOTHIN_LIKE_A_GOOD_STOGIE.value, - ZorkGrandInquisitorLocations.NOW_YOU_LOOK_LIKE_US_WHICH_IS_AN_IMPROVEMENT.value, - ZorkGrandInquisitorLocations.OBIDIL_DRIED_UP.value, - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.OH_WOW_TALK_ABOUT_DEJA_VU.value, - ZorkGrandInquisitorLocations.OPEN_THE_GATES_OF_HELL.value, - ZorkGrandInquisitorLocations.OUTSMART_THE_QUELBEES.value, - ZorkGrandInquisitorLocations.PERMASEAL.value, - ZorkGrandInquisitorLocations.PLEASE_DONT_THROCK_THE_GRASS.value, - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.PROZORKED.value, - ZorkGrandInquisitorLocations.REASSEMBLE_SNAVIG.value, - ZorkGrandInquisitorLocations.RESTOCKED_ON_GRUESDAY.value, - ZorkGrandInquisitorLocations.RIGHT_HELLO_YES_UH_THIS_IS_SNEFFLE.value, - ZorkGrandInquisitorLocations.RIGHT_UH_SORRY_ITS_ME_AGAIN_SNEFFLE.value, - ZorkGrandInquisitorLocations.SNAVIG_REPAIRED.value, - ZorkGrandInquisitorLocations.SOUVENIR.value, - ZorkGrandInquisitorLocations.STRAIGHT_TO_HELL.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.SUCKING_ROCKS.value, - ZorkGrandInquisitorLocations.TAMING_YOUR_SNAPDRAGON.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.THATS_IT_JUST_KEEP_HITTING_THOSE_BUTTONS.value, - ZorkGrandInquisitorLocations.THATS_STILL_A_ROPE.value, - ZorkGrandInquisitorLocations.THE_ALCHEMICAL_DEBACLE.value, - ZorkGrandInquisitorLocations.THE_ENDLESS_FIRE.value, - ZorkGrandInquisitorLocations.THE_FLATHEADIAN_FUDGE_FIASCO.value, - ZorkGrandInquisitorLocations.THE_PERILS_OF_MAGIC.value, - ZorkGrandInquisitorLocations.THE_UNDERGROUND_UNDERGROUND.value, - ZorkGrandInquisitorLocations.THIS_DOESNT_LOOK_ANYTHING_LIKE_THE_BROCHURE.value, - ZorkGrandInquisitorLocations.THROCKED_MUSHROOM_HAMMERED.value, - ZorkGrandInquisitorLocations.TIME_TRAVEL_FOR_DUMMIES.value, - ZorkGrandInquisitorLocations.UH_OH_BROG_CANT_SWIM.value, - ZorkGrandInquisitorLocations.UMBRELLA_FLOWERS.value, - ZorkGrandInquisitorLocations.UP.value, - ZorkGrandInquisitorLocations.USELESS_BUT_FUN.value, - ZorkGrandInquisitorLocations.UUUUUP.value, - ZorkGrandInquisitorLocations.VOYAGE_OF_CAPTAIN_ZAHAB.value, - ZorkGrandInquisitorLocations.WANT_SOME_RYE_COURSE_YA_DO.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorLocations.WHITE_HOUSE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.WOW_IVE_NEVER_GONE_INSIDE_HIM_BEFORE.value, - ZorkGrandInquisitorLocations.YAD_GOHDNUORGREDNU_3_YRAUBORF.value, - ZorkGrandInquisitorLocations.YOU_DONT_GO_MESSING_WITH_A_MANS_ZIPPER.value, - ZorkGrandInquisitorLocations.YOU_GAINED_86_EXPERIENCE_POINTS.value, - ZorkGrandInquisitorLocations.YOUR_PUNY_WEAPONS_DONT_PHASE_ME_BABY.value, - ZorkGrandInquisitorEvents.CHARON_CALLED.value, - ZorkGrandInquisitorEvents.DAM_DESTROYED.value, - ZorkGrandInquisitorEvents.DOOR_DRANK_MEAD.value, - ZorkGrandInquisitorEvents.DOOR_SMOKED_CIGAR.value, - ZorkGrandInquisitorEvents.DALBOZ_LOCKER_OPENABLE.value, - ZorkGrandInquisitorEvents.DUNCE_LOCKER_OPENABLE.value, - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_OBIDIL.value, - ZorkGrandInquisitorEvents.HAS_REPAIRABLE_SNAVIG.value, - ZorkGrandInquisitorEvents.KNOWS_BEBURTT.value, - ZorkGrandInquisitorEvents.KNOWS_OBIDIL.value, - ZorkGrandInquisitorEvents.KNOWS_SNAVIG.value, - ZorkGrandInquisitorEvents.KNOWS_YASTARD.value, - ZorkGrandInquisitorEvents.ROPE_GLORFABLE.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ZorkGrandInquisitorEvents.WHITE_HOUSE_LETTER_MAILABLE.value, - ZorkGrandInquisitorEvents.ZORK_ROCKS_ACTIVATED.value, - ZorkGrandInquisitorEvents.ZORK_ROCKS_SUCKABLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.HOTSPOT_WELL.value,)] - ) - - def test_access_locations_requiring_spell_glorf(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorEvents.ROPE_GLORFABLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SPELL_GLORF.value,)] - ) - - def test_access_locations_requiring_spell_golgatem(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DENIED_BY_THE_LAKE_MONSTER.value, - ZorkGrandInquisitorLocations.I_LIKE_YOUR_STYLE.value, - ZorkGrandInquisitorLocations.IMBUE_BEBURTT.value, - ZorkGrandInquisitorLocations.OBIDIL_DRIED_UP.value, - ZorkGrandInquisitorLocations.SNAVIG_REPAIRED.value, - ZorkGrandInquisitorLocations.USELESS_BUT_FUN.value, - ZorkGrandInquisitorEvents.KNOWS_BEBURTT.value, - ZorkGrandInquisitorEvents.KNOWS_OBIDIL.value, - ZorkGrandInquisitorEvents.KNOWS_SNAVIG.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SPELL_GOLGATEM.value,)] - ) - - def test_access_locations_requiring_spell_igram(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.A_SMALLWAY.value, - ZorkGrandInquisitorLocations.CRISIS_AVERTED.value, - ZorkGrandInquisitorLocations.DEATH_STEPPED_INTO_THE_INFINITE.value, - ZorkGrandInquisitorLocations.FAT_LOT_OF_GOOD_THATLL_DO_YA.value, - ZorkGrandInquisitorLocations.INVISIBLE_FLOWERS.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SPELL_IGRAM.value,)] - ) - - def test_access_locations_requiring_spell_kendall(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BEBURTT_DEMYSTIFIED.value, - ZorkGrandInquisitorLocations.ENJOY_YOUR_TRIP.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SPELL_KENDALL.value,)] - ) - - def test_access_locations_requiring_spell_narwile(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BROG_DO_GOOD.value, - ZorkGrandInquisitorLocations.BROG_EAT_ROCKS.value, - ZorkGrandInquisitorLocations.BROG_KNOW_DUMB_THAT_DUMB.value, - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME.value, - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorLocations.DOOOOOOWN.value, - ZorkGrandInquisitorLocations.DOWN.value, - ZorkGrandInquisitorLocations.DRAGON_ARCHIPELAGO_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.MAILED_IT_TO_HELL.value, - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.THIS_DOESNT_LOOK_ANYTHING_LIKE_THE_BROCHURE.value, - ZorkGrandInquisitorLocations.UH_OH_BROG_CANT_SWIM.value, - ZorkGrandInquisitorLocations.UP.value, - ZorkGrandInquisitorLocations.UUUUUP.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorLocations.WHITE_HOUSE_TIME_TUNNEL.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ZorkGrandInquisitorEvents.WHITE_HOUSE_LETTER_MAILABLE.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SPELL_NARWILE.value,)] - ) - - def test_access_locations_requiring_spell_rezrov(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.IN_MAGIC_WE_TRUST.value, - ZorkGrandInquisitorLocations.NATIONAL_TREASURE.value, - ZorkGrandInquisitorLocations.YOU_DONT_GO_MESSING_WITH_A_MANS_ZIPPER.value, - ZorkGrandInquisitorEvents.DAM_DESTROYED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SPELL_REZROV.value,)] - ) - - def test_access_locations_requiring_spell_throck(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BEAUTIFUL_THATS_PLENTY.value, - ZorkGrandInquisitorLocations.DEATH_THROCKED_THE_GRASS.value, - ZorkGrandInquisitorLocations.FLYING_SNAPDRAGON.value, - ZorkGrandInquisitorLocations.I_DONT_THINK_YOU_WOULDVE_WANTED_THAT_TO_WORK_ANYWAY.value, - ZorkGrandInquisitorLocations.LIT_SUNFLOWERS.value, - ZorkGrandInquisitorLocations.THROCKED_MUSHROOM_HAMMERED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SPELL_THROCK.value,)] - ) - - def test_access_locations_requiring_subway_destination_flood_control_dam(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BEAUTIFUL_THATS_PLENTY.value, - ZorkGrandInquisitorLocations.FLOOD_CONTROL_DAM_3_THE_NOT_REMOTELY_BORING_TALE.value, - ZorkGrandInquisitorLocations.NATIONAL_TREASURE.value, - ZorkGrandInquisitorLocations.SOUVENIR.value, - ZorkGrandInquisitorLocations.USELESS_BUT_FUN.value, - ZorkGrandInquisitorEvents.DAM_DESTROYED.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SUBWAY_DESTINATION_FLOOD_CONTROL_DAM.value,)] - ) - - def test_access_locations_requiring_subway_destination_hades(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SUBWAY_DESTINATION_HADES.value,)] - ) - - def test_access_locations_requiring_subway_destination_monastery(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.SUBWAY_DESTINATION_MONASTERY.value,)] - ) - - def test_access_locations_requiring_teleporter_destination_dm_lair(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_DM_LAIR.value,)] - ) - - def test_access_locations_requiring_teleporter_destination_gue_tech(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_GUE_TECH.value,)] - ) - - def test_access_locations_requiring_teleporter_destination_hades(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_HADES.value,)] - ) - - def test_access_locations_requiring_teleporter_destination_monastery(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_MONASTERY.value,)] - ) - - def test_access_locations_requiring_teleporter_destination_spell_lab(self) -> None: - locations: List[str] = list() - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.TELEPORTER_DESTINATION_SPELL_LAB.value,)] - ) - - def test_access_locations_requiring_totemizer_destination_hall_of_inquisition(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.CLOSING_THE_TIME_TUNNELS.value, - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.PORT_FOOZLE_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.THE_ALCHEMICAL_DEBACLE.value, - ZorkGrandInquisitorLocations.THE_ENDLESS_FIRE.value, - ZorkGrandInquisitorLocations.THE_FLATHEADIAN_FUDGE_FIASCO.value, - ZorkGrandInquisitorLocations.THE_PERILS_OF_MAGIC.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_HALL_OF_INQUISITION.value,)] - ) - - def test_access_locations_requiring_totemizer_destination_straight_to_hell(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.STRAIGHT_TO_HELL.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.TOTEMIZER_DESTINATION_STRAIGHT_TO_HELL.value,)] - ) - - def test_access_locations_requiring_totem_brog(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.BROG_DO_GOOD.value, - ZorkGrandInquisitorLocations.BROG_EAT_ROCKS.value, - ZorkGrandInquisitorLocations.BROG_KNOW_DUMB_THAT_DUMB.value, - ZorkGrandInquisitorLocations.BROG_MUCH_BETTER_AT_THIS_GAME.value, - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorLocations.DRAGON_ARCHIPELAGO_TIME_TUNNEL.value, - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.OH_VERY_FUNNY_GUYS.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.THIS_DOESNT_LOOK_ANYTHING_LIKE_THE_BROCHURE.value, - ZorkGrandInquisitorLocations.UH_OH_BROG_CANT_SWIM.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.TOTEM_BROG.value,)] - ) - - def test_access_locations_requiring_totem_griff(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_SWALLOWED_BY_A_DRAGON.value, - ZorkGrandInquisitorLocations.DOOOOOOWN.value, - ZorkGrandInquisitorLocations.OH_DEAR_GOD_ITS_A_DRAGON.value, - ZorkGrandInquisitorLocations.THAR_SHE_BLOWS.value, - ZorkGrandInquisitorLocations.UUUUUP.value, - ZorkGrandInquisitorLocations.WE_DONT_SERVE_YOUR_KIND_HERE.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.TOTEM_GRIFF.value,)] - ) - - def test_access_locations_requiring_totem_lucy(self) -> None: - locations: List[str] = [ - ZorkGrandInquisitorLocations.DEATH_LOST_GAME_OF_STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.DOWN.value, - ZorkGrandInquisitorLocations.STRIP_GRUE_FIRE_WATER.value, - ZorkGrandInquisitorLocations.THIS_DOESNT_LOOK_ANYTHING_LIKE_THE_BROCHURE.value, - ZorkGrandInquisitorLocations.UP.value, - ZorkGrandInquisitorLocations.WE_GOT_A_HIGH_ROLLER.value, - ZorkGrandInquisitorEvents.VICTORY.value, - ] - - self.assertAccessDependency( - locations, [(ZorkGrandInquisitorItems.TOTEM_LUCY.value,)] - ) diff --git a/worlds/zork_grand_inquisitor/test/test_data_funcs.py b/worlds/zork_grand_inquisitor/test/test_data_funcs.py deleted file mode 100644 index 9d8d5a4ba356..000000000000 --- a/worlds/zork_grand_inquisitor/test/test_data_funcs.py +++ /dev/null @@ -1,132 +0,0 @@ -import unittest - -from ..data_funcs import location_access_rule_for, entrance_access_rule_for -from ..enums import ZorkGrandInquisitorLocations, ZorkGrandInquisitorRegions - - -class DataFuncsTest(unittest.TestCase): - def test_location_access_rule_for(self) -> None: - # No Requirements - self.assertEqual( - "lambda state: True", - location_access_rule_for(ZorkGrandInquisitorLocations.ALARM_SYSTEM_IS_DOWN, 1), - ) - - # Single Item Requirement - self.assertEqual( - 'lambda state: state.has("Sword", 1)', - location_access_rule_for(ZorkGrandInquisitorLocations.DONT_EVEN_START_WITH_US_SPARKY, 1), - ) - - self.assertEqual( - 'lambda state: state.has("Spell: NARWILE", 1)', - location_access_rule_for(ZorkGrandInquisitorLocations.DRAGON_ARCHIPELAGO_TIME_TUNNEL, 1), - ) - - # Single Event Requirement - self.assertEqual( - 'lambda state: state.has("Event: Knows OBIDIL", 1)', - location_access_rule_for(ZorkGrandInquisitorLocations.A_BIG_FAT_SASSY_2_HEADED_MONSTER, 1), - ) - - self.assertEqual( - 'lambda state: state.has("Event: Dunce Locker Openable", 1)', - location_access_rule_for(ZorkGrandInquisitorLocations.BETTER_SPELL_MANUFACTURING_IN_UNDER_10_MINUTES, 1), - ) - - # Multiple Item Requirements - self.assertEqual( - 'lambda state: state.has("Hotspot: Purple Words", 1) and state.has("Spell: IGRAM", 1)', - location_access_rule_for(ZorkGrandInquisitorLocations.A_SMALLWAY, 1), - ) - - self.assertEqual( - 'lambda state: state.has("Hotspot: Mossy Grate", 1) and state.has("Spell: THROCK", 1)', - location_access_rule_for(ZorkGrandInquisitorLocations.BEAUTIFUL_THATS_PLENTY, 1), - ) - - # Multiple Item Requirements OR - self.assertEqual( - 'lambda state: (state.has("Totem: Griff", 1) or state.has("Totem: Lucy", 1)) and state.has("Hotspot: Mailbox Door", 1) and state.has("Hotspot: Mailbox Flag", 1)', - location_access_rule_for(ZorkGrandInquisitorLocations.MAILED_IT_TO_HELL, 1), - ) - - # Multiple Mixed Requirements - self.assertEqual( - 'lambda state: state.has("Event: Cigar Accessible", 1) and state.has("Hotspot: Grand Inquisitor Doll", 1)', - location_access_rule_for(ZorkGrandInquisitorLocations.ARREST_THE_VANDAL, 1), - ) - - self.assertEqual( - 'lambda state: state.has("Sword", 1) and state.has("Event: Rope GLORFable", 1) and state.has("Hotspot: Monastery Vent", 1)', - location_access_rule_for(ZorkGrandInquisitorLocations.I_HOPE_YOU_CAN_CLIMB_UP_THERE, 1), - ) - - def test_entrance_access_rule_for(self) -> None: - # No Requirements - self.assertEqual( - "lambda state: True", - entrance_access_rule_for( - ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.PORT_FOOZLE, 1 - ), - ) - - self.assertEqual( - "lambda state: True", - entrance_access_rule_for( - ZorkGrandInquisitorRegions.DM_LAIR, ZorkGrandInquisitorRegions.CROSSROADS, 1 - ), - ) - - # Single Requirement - self.assertEqual( - 'lambda state: (state.has("Map", 1))', - entrance_access_rule_for( - ZorkGrandInquisitorRegions.GUE_TECH_OUTSIDE, ZorkGrandInquisitorRegions.CROSSROADS, 1 - ), - ) - - self.assertEqual( - 'lambda state: (state.has("Map", 1))', - entrance_access_rule_for( - ZorkGrandInquisitorRegions.HADES_SHORE, ZorkGrandInquisitorRegions.CROSSROADS, 1 - ), - ) - - # Multiple Requirements AND - self.assertEqual( - 'lambda state: (state.has("Spell: REZROV", 1) and state.has("Hotspot: In Magic We Trust Door", 1))', - entrance_access_rule_for( - ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.GUE_TECH, 1 - ), - ) - - self.assertEqual( - 'lambda state: (state.has("Event: Door Smoked Cigar", 1) and state.has("Event: Door Drank Mead", 1))', - entrance_access_rule_for( - ZorkGrandInquisitorRegions.DM_LAIR, ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, 1 - ), - ) - - self.assertEqual( - 'lambda state: (state.has("Hotspot: Closet Door", 1) and state.has("Spell: NARWILE", 1) and state.has("Event: Knows YASTARD", 1))', - entrance_access_rule_for( - ZorkGrandInquisitorRegions.DM_LAIR_INTERIOR, ZorkGrandInquisitorRegions.WHITE_HOUSE, 1 - ), - ) - - # Multiple Requirements AND + OR - self.assertEqual( - 'lambda state: (state.has("Sword", 1) and state.has("Hotspot: Dungeon Master\'s Lair Entrance", 1)) or (state.has("Map", 1) and state.has("Teleporter Destination: Dungeon Master\'s Lair", 1))', - entrance_access_rule_for( - ZorkGrandInquisitorRegions.CROSSROADS, ZorkGrandInquisitorRegions.DM_LAIR, 1 - ), - ) - - # Multiple Requirements Regions - self.assertEqual( - 'lambda state: (state.has("Griff\'s Air Pump", 1) and state.has("Griff\'s Inflatable Raft", 1) and state.has("Griff\'s Inflatable Sea Captain", 1) and state.has("Hotspot: Dragon Nostrils", 1) and state.has("Griff\'s Dragon Tooth", 1) and state.can_reach("Port Foozle Past - Tavern", "Region", 1) and state.has("Lucy\'s Playing Card: 1 Pip", 1) and state.has("Lucy\'s Playing Card: 2 Pips", 1) and state.has("Lucy\'s Playing Card: 3 Pips", 1) and state.has("Lucy\'s Playing Card: 4 Pips", 1) and state.has("Hotspot: Tavern Fly", 1) and state.has("Hotspot: Alpine\'s Quandry Card Slots", 1) and state.can_reach("White House", "Region", 1) and state.has("Totem: Brog", 1) and state.has("Brog\'s Flickering Torch", 1) and state.has("Brog\'s Grue Egg", 1) and state.has("Hotspot: Cooking Pot", 1) and state.has("Brog\'s Plank", 1) and state.has("Hotspot: Skull Cage", 1))', - entrance_access_rule_for( - ZorkGrandInquisitorRegions.DRAGON_ARCHIPELAGO_DRAGON, ZorkGrandInquisitorRegions.ENDGAME, 1 - ), - ) diff --git a/worlds/zork_grand_inquisitor/test/test_locations.py b/worlds/zork_grand_inquisitor/test/test_locations.py deleted file mode 100644 index fa576dd510dc..000000000000 --- a/worlds/zork_grand_inquisitor/test/test_locations.py +++ /dev/null @@ -1,49 +0,0 @@ -from typing import Dict, Set - -from . import ZorkGrandInquisitorTestBase - -from ..data_funcs import location_names_to_location, locations_with_tag -from ..enums import ZorkGrandInquisitorLocations, ZorkGrandInquisitorTags - - -class LocationsTestNoDeathsanity(ZorkGrandInquisitorTestBase): - options = { - "deathsanity": "false", - } - - def test_correct_locations_exist(self) -> None: - expected_locations: Set[ZorkGrandInquisitorLocations] = locations_with_tag( - ZorkGrandInquisitorTags.CORE - ) - - self._assert_expected_locations_exist(expected_locations) - - def _assert_expected_locations_exist(self, expected_locations: Set[ZorkGrandInquisitorLocations]) -> None: - location_name_to_location: Dict[str, ZorkGrandInquisitorLocations] = location_names_to_location() - - for location_object in self.multiworld.get_locations(1): - location: ZorkGrandInquisitorLocations = location_name_to_location.get( - location_object.name - ) - - if location is None: - continue - - self.assertIn(location, expected_locations) - - expected_locations.remove(location) - - self.assertEqual(0, len(expected_locations)) - - -class LocationsTestDeathsanity(LocationsTestNoDeathsanity): - options = { - "deathsanity": "true", - } - - def test_correct_locations_exist(self) -> None: - expected_locations: Set[ZorkGrandInquisitorLocations] = ( - locations_with_tag(ZorkGrandInquisitorTags.CORE) | locations_with_tag(ZorkGrandInquisitorTags.DEATHSANITY) - ) - - self._assert_expected_locations_exist(expected_locations) diff --git a/worlds/zork_grand_inquisitor/world.py b/worlds/zork_grand_inquisitor/world.py deleted file mode 100644 index 3698ad7f8960..000000000000 --- a/worlds/zork_grand_inquisitor/world.py +++ /dev/null @@ -1,205 +0,0 @@ -from typing import Any, Dict, List, Tuple - -from BaseClasses import Item, ItemClassification, Location, Region, Tutorial - -from worlds.AutoWorld import WebWorld, World - -from .data.item_data import item_data, ZorkGrandInquisitorItemData -from .data.location_data import location_data, ZorkGrandInquisitorLocationData -from .data.region_data import region_data - -from .data_funcs import ( - item_names_to_id, - item_names_to_item, - location_names_to_id, - item_groups, - items_with_tag, - location_groups, - locations_by_region, - location_access_rule_for, - entrance_access_rule_for, -) - -from .enums import ( - ZorkGrandInquisitorEvents, - ZorkGrandInquisitorItems, - ZorkGrandInquisitorLocations, - ZorkGrandInquisitorRegions, - ZorkGrandInquisitorTags, -) - -from .options import ZorkGrandInquisitorOptions - - -class ZorkGrandInquisitorItem(Item): - game = "Zork Grand Inquisitor" - - -class ZorkGrandInquisitorLocation(Location): - game = "Zork Grand Inquisitor" - - -class ZorkGrandInquisitorWebWorld(WebWorld): - theme: str = "stone" - - tutorials: List[Tutorial] = [ - Tutorial( - "Multiworld Setup Guide", - "A guide to setting up the Zork Grand Inquisitor randomizer connected to an Archipelago Multiworld", - "English", - "setup_en.md", - "setup/en", - ["Serpent.AI"], - ) - ] - - -class ZorkGrandInquisitorWorld(World): - """ - Zork: Grand Inquisitor is a 1997 point-and-click adventure game for PC. - Magic has been banned from the great Underground Empire of Zork. By edict of the Grand Inquisitor Mir Yannick, the - Empire has been sealed off and the practice of mystic arts declared punishable by "Totemization" (a very bad thing). - The only way to restore magic to the kingdom is to find three hidden artifacts: The Coconut of Quendor, The Cube of - Foundation, and The Skull of Yoruk. - """ - - options_dataclass = ZorkGrandInquisitorOptions - options: ZorkGrandInquisitorOptions - - game = "Zork Grand Inquisitor" - - item_name_to_id = item_names_to_id() - location_name_to_id = location_names_to_id() - - item_name_groups = item_groups() - location_name_groups = location_groups() - - required_client_version: Tuple[int, int, int] = (0, 4, 4) - - web = ZorkGrandInquisitorWebWorld() - - filler_item_names: List[str] = item_groups()["Filler"] - item_name_to_item: Dict[str, ZorkGrandInquisitorItems] = item_names_to_item() - - def create_regions(self) -> None: - deathsanity: bool = bool(self.options.deathsanity) - - region_mapping: Dict[ZorkGrandInquisitorRegions, Region] = dict() - - region_enum_item: ZorkGrandInquisitorRegions - for region_enum_item in region_data.keys(): - region_mapping[region_enum_item] = Region(region_enum_item.value, self.player, self.multiworld) - - region_locations_mapping: Dict[ZorkGrandInquisitorRegions, List[ZorkGrandInquisitorLocations]] - region_locations_mapping = locations_by_region(include_deathsanity=deathsanity) - - region_enum_item: ZorkGrandInquisitorRegions - region: Region - for region_enum_item, region in region_mapping.items(): - regions_locations: List[ZorkGrandInquisitorLocations] = region_locations_mapping[region_enum_item] - - # Locations - location_enum_item: ZorkGrandInquisitorLocations - for location_enum_item in regions_locations: - data: ZorkGrandInquisitorLocationData = location_data[location_enum_item] - - location: ZorkGrandInquisitorLocation = ZorkGrandInquisitorLocation( - self.player, - location_enum_item.value, - data.archipelago_id, - region_mapping[data.region], - ) - - if isinstance(location_enum_item, ZorkGrandInquisitorEvents): - location.place_locked_item( - ZorkGrandInquisitorItem( - data.event_item_name, - ItemClassification.progression, - None, - self.player, - ) - ) - - location_access_rule: str = location_access_rule_for(location_enum_item, self.player) - - if location_access_rule != "lambda state: True": - location.access_rule = eval(location_access_rule) - - region.locations.append(location) - - # Connections - region_exit: ZorkGrandInquisitorRegions - for region_exit in region_data[region_enum_item].exits or tuple(): - entrance_access_rule: str = entrance_access_rule_for(region_enum_item, region_exit, self.player) - - if entrance_access_rule == "lambda state: True": - region.connect(region_mapping[region_exit]) - else: - region.connect(region_mapping[region_exit], rule=eval(entrance_access_rule)) - - self.multiworld.regions.append(region) - - def create_items(self) -> None: - quick_port_foozle: bool = bool(self.options.quick_port_foozle) - start_with_hotspot_items: bool = bool(self.options.start_with_hotspot_items) - - item_pool: List[ZorkGrandInquisitorItem] = list() - - item: ZorkGrandInquisitorItems - data: ZorkGrandInquisitorItemData - for item, data in item_data.items(): - tags: Tuple[ZorkGrandInquisitorTags, ...] = data.tags or tuple() - - if ZorkGrandInquisitorTags.FILLER in tags: - continue - elif ZorkGrandInquisitorTags.HOTSPOT in tags and start_with_hotspot_items: - continue - - item_pool.append(self.create_item(item.value)) - - total_locations: int = len(self.multiworld.get_unfilled_locations(self.player)) - item_pool += [self.create_filler() for _ in range(total_locations - len(item_pool))] - - self.multiworld.itempool += item_pool - - if quick_port_foozle: - self.multiworld.early_items[self.player][ZorkGrandInquisitorItems.ROPE.value] = 1 - self.multiworld.early_items[self.player][ZorkGrandInquisitorItems.LANTERN.value] = 1 - - if not start_with_hotspot_items: - self.multiworld.early_items[self.player][ZorkGrandInquisitorItems.HOTSPOT_WELL.value] = 1 - self.multiworld.early_items[self.player][ZorkGrandInquisitorItems.HOTSPOT_JACKS_DOOR.value] = 1 - - self.multiworld.early_items[self.player][ - ZorkGrandInquisitorItems.HOTSPOT_GRAND_INQUISITOR_DOLL.value - ] = 1 - - if start_with_hotspot_items: - item: ZorkGrandInquisitorItems - for item in sorted(items_with_tag(ZorkGrandInquisitorTags.HOTSPOT), key=lambda item: item.name): - self.multiworld.push_precollected(self.create_item(item.value)) - - def create_item(self, name: str) -> ZorkGrandInquisitorItem: - data: ZorkGrandInquisitorItemData = item_data[self.item_name_to_item[name]] - - return ZorkGrandInquisitorItem( - name, - data.classification, - data.archipelago_id, - self.player, - ) - - def generate_basic(self) -> None: - self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) - - def fill_slot_data(self) -> Dict[str, Any]: - return self.options.as_dict( - "goal", - "quick_port_foozle", - "start_with_hotspot_items", - "deathsanity", - "grant_missable_location_checks", - ) - - def get_filler_item_name(self) -> str: - return self.random.choice(self.filler_item_names) From 2624a0a7ead232c8aa9f73c80d008fb1315bf02c Mon Sep 17 00:00:00 2001 From: KonoTyran Date: Fri, 25 Apr 2025 11:54:53 -0700 Subject: [PATCH 0368/1218] Remove Slay the Spire (#4673) * Remove Slay the Spire * remove slay the spire --- README.md | 1 - docs/CODEOWNERS | 3 - docs/network diagram/network diagram.md | 2 - setup.py | 1 - worlds/generic/docs/advanced_settings_en.md | 4 +- worlds/generic/docs/plando_en.md | 21 ++-- worlds/spire/Items.py | 39 -------- worlds/spire/Locations.py | 35 ------- worlds/spire/Options.py | 74 -------------- worlds/spire/Regions.py | 11 --- worlds/spire/Rules.py | 74 -------------- worlds/spire/__init__.py | 103 -------------------- worlds/spire/docs/en_Slay the Spire.md | 35 ------- worlds/spire/docs/slay-the-spire_en.md | 69 ------------- 14 files changed, 8 insertions(+), 464 deletions(-) delete mode 100644 worlds/spire/Items.py delete mode 100644 worlds/spire/Locations.py delete mode 100644 worlds/spire/Options.py delete mode 100644 worlds/spire/Regions.py delete mode 100644 worlds/spire/Rules.py delete mode 100644 worlds/spire/__init__.py delete mode 100644 worlds/spire/docs/en_Slay the Spire.md delete mode 100644 worlds/spire/docs/slay-the-spire_en.md diff --git a/README.md b/README.md index 83fdeea61105..c1e89bac7ce2 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ Currently, the following games are supported: * Factorio * Minecraft * Subnautica -* Slay the Spire * Risk of Rain 2 * The Legend of Zelda: Ocarina of Time * Timespinner diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 88b5060dcc61..dee8a6fd25d2 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -184,9 +184,6 @@ # Secret of Evermore /worlds/soe/ @black-sliver -# Slay the Spire -/worlds/spire/ @KonoTyran - # Stardew Valley /worlds/stardew_valley/ @agilbert1412 diff --git a/docs/network diagram/network diagram.md b/docs/network diagram/network diagram.md index cd61d9fefd19..d660e8889efa 100644 --- a/docs/network diagram/network diagram.md +++ b/docs/network diagram/network diagram.md @@ -117,8 +117,6 @@ flowchart LR %% Java Based Games subgraph Java JM[Mod with Archipelago.MultiClient.Java] - STS[Slay the Spire] - JM <-- Mod the Spire --> STS subgraph Minecraft MCS[Minecraft Forge Server] JMC[Any Java Minecraft Clients] diff --git a/setup.py b/setup.py index ebef215e2dc9..8d415932d05d 100644 --- a/setup.py +++ b/setup.py @@ -72,7 +72,6 @@ "Ocarina of Time", "Overcooked! 2", "Raft", - "Slay the Spire", "Sudoku", "Super Mario 64", "VVVVVV", diff --git a/worlds/generic/docs/advanced_settings_en.md b/worlds/generic/docs/advanced_settings_en.md index e78eb91592a3..6f0520febc6e 100644 --- a/worlds/generic/docs/advanced_settings_en.md +++ b/worlds/generic/docs/advanced_settings_en.md @@ -278,7 +278,7 @@ one file, removing the need to manage separate files if one chooses to do so. As a precautionary measure, before submitting a multi-game yaml like this one in a synchronous/sync multiworld, please confirm that the other players in the multi are OK with what you are submitting, and please be fairly reasonable about the submission. (i.e. Multiple long games (SMZ3, OoT, HK, etc.) for a game intended to be <2 hrs is not likely considered -reasonable, but submitting a ChecksFinder alongside another game OR submitting multiple Slay the Spire runs is likely +reasonable, but submitting a ChecksFinder alongside another game is likely OK) To configure your file to generate multiple worlds, use 3 dashes `---` on an empty line to separate the ending of one @@ -335,7 +335,7 @@ Minecraft: --- -description: Example of generating multiple worlds. World 3 of 3 +description: Example of generating multiple worlds. World 2 of 2 name: ExampleFinder game: ChecksFinder diff --git a/worlds/generic/docs/plando_en.md b/worlds/generic/docs/plando_en.md index 1980e81cbcc4..946962476286 100644 --- a/worlds/generic/docs/plando_en.md +++ b/worlds/generic/docs/plando_en.md @@ -104,15 +104,7 @@ A list of all available items and locations can be found in the [website's datap - Spirit Temple Silver Gauntlets Chest world: false - # example block 3 - Slay the Spire - - items: - Boss Relic: 3 - locations: - - Boss Relic 1 - - Boss Relic 2 - - Boss Relic 3 - - # example block 4 - Factorio + # example block 3 - Factorio - items: progressive-electric-energy-distribution: 2 electric-energy-accumulators: 1 @@ -125,7 +117,7 @@ A list of all available items and locations can be found in the [website's datap percentage: 80 force: true - # example block 5 - Secret of Evermore + # example block 4 - Secret of Evermore - items: Levitate: 1 Revealer: 1 @@ -136,7 +128,7 @@ A list of all available items and locations can be found in the [website's datap world: true count: 2 - # example block 6 - A Link to the Past + # example block 5 - A Link to the Past - items: Progressive Sword: 4 world: @@ -150,12 +142,11 @@ A list of all available items and locations can be found in the [website's datap player's Starter Chest 1 and removes the chosen item from the item pool. 2. This block will always trigger and will place the player's swords, bow, magic meter, strength upgrades, and hookshots in their own dungeon major item chests. -3. This block will always trigger and will lock boss relics on the bosses. -4. This block has an 80% chance of occurring, and when it does, it will place all but 1 of the items randomly among the +3. This block has an 80% chance of occurring, and when it does, it will place all but 1 of the items randomly among the four locations chosen here. -5. This block will always trigger and will attempt to place a random 2 of Levitate, Revealer and Energize into +4. This block will always trigger and will attempt to place a random 2 of Levitate, Revealer and Energize into other players' Master Sword Pedestals or Boss Relic 1 locations. -6. This block will always trigger and will attempt to place a random number, between 1 and 4, of progressive swords +5. This block will always trigger and will attempt to place a random number, between 1 and 4, of progressive swords into any locations within the game slots named BobsSlaytheSpire and BobsRogueLegacy. diff --git a/worlds/spire/Items.py b/worlds/spire/Items.py deleted file mode 100644 index 188b1e031ee9..000000000000 --- a/worlds/spire/Items.py +++ /dev/null @@ -1,39 +0,0 @@ -import typing - -from BaseClasses import Item -from typing import Dict - - -class ItemData(typing.NamedTuple): - code: typing.Optional[int] - progression: bool - event: bool = False - - -item_table: Dict[str, ItemData] = { - 'Card Draw': ItemData(8000, True), - 'Rare Card Draw': ItemData(8001, True), - 'Relic': ItemData(8002, True), - 'Boss Relic': ItemData(8003, True), - - # Event Items - 'Victory': ItemData(None, True, True), - 'Beat Act 1 Boss': ItemData(None, True, True), - 'Beat Act 2 Boss': ItemData(None, True, True), - 'Beat Act 3 Boss': ItemData(None, True, True), - -} - -item_pool: Dict[str, int] = { - 'Card Draw': 15, - 'Rare Card Draw': 2, - 'Relic': 10, - 'Boss Relic': 2 -} - -event_item_pairs: Dict[str, str] = { - "Heart Room": "Victory", - "Act 1 Boss": "Beat Act 1 Boss", - "Act 2 Boss": "Beat Act 2 Boss", - "Act 3 Boss": "Beat Act 3 Boss" -} diff --git a/worlds/spire/Locations.py b/worlds/spire/Locations.py deleted file mode 100644 index e20ab6f55222..000000000000 --- a/worlds/spire/Locations.py +++ /dev/null @@ -1,35 +0,0 @@ -location_table = { - 'Card Draw 1': 19001, - 'Card Draw 2': 19002, - 'Card Draw 3': 19003, - 'Card Draw 4': 19004, - 'Card Draw 5': 19005, - 'Card Draw 6': 19006, - 'Card Draw 7': 19007, - 'Card Draw 8': 19008, - 'Card Draw 9': 19009, - 'Card Draw 10': 19010, - 'Card Draw 11': 19011, - 'Card Draw 12': 19012, - 'Card Draw 13': 19013, - 'Card Draw 14': 19014, - 'Card Draw 15': 19015, - 'Rare Card Draw 1': 21001, - 'Rare Card Draw 2': 21002, - 'Relic 1': 20001, - 'Relic 2': 20002, - 'Relic 3': 20003, - 'Relic 4': 20004, - 'Relic 5': 20005, - 'Relic 6': 20006, - 'Relic 7': 20007, - 'Relic 8': 20008, - 'Relic 9': 20009, - 'Relic 10': 20010, - 'Boss Relic 1': 22001, - 'Boss Relic 2': 22002, - 'Heart Room': None, - 'Act 1 Boss': None, - 'Act 2 Boss': None, - 'Act 3 Boss': None -} \ No newline at end of file diff --git a/worlds/spire/Options.py b/worlds/spire/Options.py deleted file mode 100644 index 9c94756600d6..000000000000 --- a/worlds/spire/Options.py +++ /dev/null @@ -1,74 +0,0 @@ -import typing -from dataclasses import dataclass - -from Options import TextChoice, Range, Toggle, PerGameCommonOptions - - -class Character(TextChoice): - """Enter the internal ID of the character to use. - - if you don't know the exact ID to enter with the mod installed go to - `Mods -> Archipelago Multi-world -> config` to view a list of installed modded character IDs. - - the downfall characters will only work if you have downfall installed. - - Spire Take the Wheel will have your client pick a random character from the list of all your installed characters - including custom ones. - - if the chosen character mod is not installed it will default back to 'The Ironclad' - """ - display_name = "Character" - option_The_Ironclad = 0 - option_The_Silent = 1 - option_The_Defect = 2 - option_The_Watcher = 3 - option_The_Hermit = 4 - option_The_Slime_Boss = 5 - option_The_Guardian = 6 - option_The_Hexaghost = 7 - option_The_Champ = 8 - option_The_Gremlins = 9 - option_The_Automaton = 10 - option_The_Snecko = 11 - option_spire_take_the_wheel = 12 - - -class Ascension(Range): - """What Ascension do you wish to play with.""" - display_name = "Ascension" - range_start = 0 - range_end = 20 - default = 0 - - -class FinalAct(Toggle): - """Whether you will need to collect the 3 keys and beat the final act to complete the game.""" - display_name = "Final Act" - option_true = 1 - option_false = 0 - default = 0 - - -class Downfall(Toggle): - """When Downfall is Installed this will switch the played mode to Downfall""" - display_name = "Downfall" - option_true = 1 - option_false = 0 - default = 0 - - -class DeathLink(Range): - """Percentage of health to lose when a death link is received.""" - display_name = "Death Link %" - range_start = 0 - range_end = 100 - default = 0 - - -@dataclass -class SpireOptions(PerGameCommonOptions): - character: Character - ascension: Ascension - final_act: FinalAct - downfall: Downfall - death_link: DeathLink diff --git a/worlds/spire/Regions.py b/worlds/spire/Regions.py deleted file mode 100644 index 9e2ac0d3554c..000000000000 --- a/worlds/spire/Regions.py +++ /dev/null @@ -1,11 +0,0 @@ -def create_regions(world, player: int): - from . import create_region - from .Locations import location_table - - world.regions += [ - create_region(world, player, 'Menu', None, ['Neow\'s Room']), - create_region(world, player, 'The Spire', [location for location in location_table]) - ] - - # link up our region with the entrance we just made - world.get_entrance('Neow\'s Room', player).connect(world.get_region('The Spire', player)) diff --git a/worlds/spire/Rules.py b/worlds/spire/Rules.py deleted file mode 100644 index 3c6f09b34dce..000000000000 --- a/worlds/spire/Rules.py +++ /dev/null @@ -1,74 +0,0 @@ -from BaseClasses import MultiWorld -from ..AutoWorld import LogicMixin -from ..generic.Rules import set_rule - - -class SpireLogic(LogicMixin): - def _spire_has_relics(self, player: int, amount: int) -> bool: - count: int = self.count("Relic", player) + self.count("Boss Relic", player) - return count >= amount - - def _spire_has_cards(self, player: int, amount: int) -> bool: - count = self.count("Card Draw", player) + self.count("Rare Card Draw", player) - return count >= amount - - -def set_rules(world: MultiWorld, player: int): - - # Act 1 Card Draws - set_rule(world.get_location("Card Draw 1", player), lambda state: True) - set_rule(world.get_location("Card Draw 2", player), lambda state: True) - set_rule(world.get_location("Card Draw 3", player), lambda state: True) - set_rule(world.get_location("Card Draw 4", player), lambda state: state._spire_has_relics(player, 1)) - set_rule(world.get_location("Card Draw 5", player), lambda state: state._spire_has_relics(player, 1)) - - # Act 1 Relics - set_rule(world.get_location("Relic 1", player), lambda state: state._spire_has_cards(player, 1)) - set_rule(world.get_location("Relic 2", player), lambda state: state._spire_has_cards(player, 2)) - set_rule(world.get_location("Relic 3", player), lambda state: state._spire_has_cards(player, 2)) - - # Act 1 Boss Event - set_rule(world.get_location("Act 1 Boss", player), lambda state: state._spire_has_cards(player, 3) and state._spire_has_relics(player, 2)) - - # Act 1 Boss Rewards - set_rule(world.get_location("Rare Card Draw 1", player), lambda state: state.has("Beat Act 1 Boss", player)) - set_rule(world.get_location("Boss Relic 1", player), lambda state: state.has("Beat Act 1 Boss", player)) - - # Act 2 Card Draws - set_rule(world.get_location("Card Draw 6", player), lambda state: state.has("Beat Act 1 Boss", player)) - set_rule(world.get_location("Card Draw 7", player), lambda state: state.has("Beat Act 1 Boss", player)) - set_rule(world.get_location("Card Draw 8", player), lambda state: state.has("Beat Act 1 Boss", player) and state._spire_has_cards(player, 6) and state._spire_has_relics(player, 3)) - set_rule(world.get_location("Card Draw 9", player), lambda state: state.has("Beat Act 1 Boss", player) and state._spire_has_cards(player, 6) and state._spire_has_relics(player, 4)) - set_rule(world.get_location("Card Draw 10", player), lambda state: state.has("Beat Act 1 Boss", player) and state._spire_has_cards(player, 7) and state._spire_has_relics(player, 4)) - - # Act 2 Relics - set_rule(world.get_location("Relic 4", player), lambda state: state.has("Beat Act 1 Boss", player) and state._spire_has_cards(player, 7) and state._spire_has_relics(player, 2)) - set_rule(world.get_location("Relic 5", player), lambda state: state.has("Beat Act 1 Boss", player) and state._spire_has_cards(player, 7) and state._spire_has_relics(player, 2)) - set_rule(world.get_location("Relic 6", player), lambda state: state.has("Beat Act 1 Boss", player) and state._spire_has_cards(player, 7) and state._spire_has_relics(player, 3)) - - # Act 2 Boss Event - set_rule(world.get_location("Act 2 Boss", player), lambda state: state.has("Beat Act 1 Boss", player) and state._spire_has_cards(player, 7) and state._spire_has_relics(player, 4) and state.has("Boss Relic", player)) - - # Act 2 Boss Rewards - set_rule(world.get_location("Rare Card Draw 2", player), lambda state: state.has("Beat Act 2 Boss", player)) - set_rule(world.get_location("Boss Relic 2", player), lambda state: state.has("Beat Act 2 Boss", player)) - - # Act 3 Card Draws - set_rule(world.get_location("Card Draw 11", player), lambda state: state.has("Beat Act 2 Boss", player)) - set_rule(world.get_location("Card Draw 12", player), lambda state: state.has("Beat Act 2 Boss", player)) - set_rule(world.get_location("Card Draw 13", player), lambda state: state.has("Beat Act 2 Boss", player) and state._spire_has_relics(player, 4)) - set_rule(world.get_location("Card Draw 14", player), lambda state: state.has("Beat Act 2 Boss", player) and state._spire_has_relics(player, 4)) - set_rule(world.get_location("Card Draw 15", player), lambda state: state.has("Beat Act 2 Boss", player) and state._spire_has_relics(player, 4)) - - # Act 3 Relics - set_rule(world.get_location("Relic 7", player), lambda state: state.has("Beat Act 2 Boss", player) and state._spire_has_relics(player, 4)) - set_rule(world.get_location("Relic 8", player), lambda state: state.has("Beat Act 2 Boss", player) and state._spire_has_relics(player, 5)) - set_rule(world.get_location("Relic 9", player), lambda state: state.has("Beat Act 2 Boss", player) and state._spire_has_relics(player, 5)) - set_rule(world.get_location("Relic 10", player), lambda state: state.has("Beat Act 2 Boss", player) and state._spire_has_relics(player, 5)) - - # Act 3 Boss Event - set_rule(world.get_location("Act 3 Boss", player), lambda state: state.has("Beat Act 2 Boss", player) and state._spire_has_relics(player, 7) and state.has("Boss Relic", player, 2)) - - set_rule(world.get_location("Heart Room", player), lambda state: state.has("Beat Act 3 Boss", player)) - - world.completion_condition[player] = lambda state: state.has("Victory", player) diff --git a/worlds/spire/__init__.py b/worlds/spire/__init__.py deleted file mode 100644 index a0a6a794d8a9..000000000000 --- a/worlds/spire/__init__.py +++ /dev/null @@ -1,103 +0,0 @@ -import string - -from BaseClasses import Entrance, Item, ItemClassification, Location, MultiWorld, Region, Tutorial -from .Items import event_item_pairs, item_pool, item_table -from .Locations import location_table -from .Options import SpireOptions -from .Regions import create_regions -from .Rules import set_rules -from ..AutoWorld import WebWorld, World - - -class SpireWeb(WebWorld): - tutorials = [Tutorial( - "Multiworld Setup Guide", - "A guide to setting up Slay the Spire for Archipelago. " - "This guide covers single-player, multiworld, and related software.", - "English", - "slay-the-spire_en.md", - "slay-the-spire/en", - ["Phar"] - )] - - -class SpireWorld(World): - """ - A deck-building roguelike where you must craft a unique deck, encounter bizarre creatures, discover relics of - immense power, and Slay the Spire! - """ - - options_dataclass = SpireOptions - options: SpireOptions - game = "Slay the Spire" - topology_present = False - web = SpireWeb() - required_client_version = (0, 3, 7) - - item_name_to_id = {name: data.code for name, data in item_table.items()} - location_name_to_id = location_table - - def create_items(self): - # Fill out our pool with our items from item_pool, assuming 1 item if not present in item_pool - pool = [] - for name, data in item_table.items(): - if not data.event: - for amount in range(item_pool.get(name, 1)): - item = SpireItem(name, self.player) - pool.append(item) - - self.multiworld.itempool += pool - - # Pair up our event locations with our event items - for event, item in event_item_pairs.items(): - event_item = SpireItem(item, self.player) - self.multiworld.get_location(event, self.player).place_locked_item(event_item) - - def set_rules(self): - set_rules(self.multiworld, self.player) - - def create_item(self, name: str) -> Item: - return SpireItem(name, self.player) - - def create_regions(self): - create_regions(self.multiworld, self.player) - - def fill_slot_data(self) -> dict: - slot_data = { - 'seed': "".join(self.random.choice(string.ascii_letters) for i in range(16)) - } - slot_data.update(self.options.as_dict("character", "ascension", "final_act", "downfall", "death_link")) - return slot_data - - def get_filler_item_name(self) -> str: - return self.random.choice(["Card Draw", "Card Draw", "Card Draw", "Relic", "Relic"]) - - -def create_region(world: MultiWorld, player: int, name: str, locations=None, exits=None): - ret = Region(name, player, world) - if locations: - for location in locations: - loc_id = location_table.get(location, 0) - location = SpireLocation(player, location, loc_id, ret) - ret.locations.append(location) - if exits: - for exit in exits: - ret.exits.append(Entrance(player, exit, ret)) - - return ret - - -class SpireLocation(Location): - game: str = "Slay the Spire" - - -class SpireItem(Item): - game = "Slay the Spire" - - def __init__(self, name, player: int = None): - item_data = item_table[name] - super(SpireItem, self).__init__( - name, - ItemClassification.progression if item_data.progression else ItemClassification.filler, - item_data.code, player - ) diff --git a/worlds/spire/docs/en_Slay the Spire.md b/worlds/spire/docs/en_Slay the Spire.md deleted file mode 100644 index 4591db58dc51..000000000000 --- a/worlds/spire/docs/en_Slay the Spire.md +++ /dev/null @@ -1,35 +0,0 @@ -# Slay the Spire (PC) - -## Where is the options page? - -The [player options page for this game](../player-options) contains all the options you need to configure and export a -config file. - -## What does randomization do to this game? - -Every non-boss relic drop, every boss relic and rare card drop, and every other card draw is replaced with an -archipelago item. In heart runs, the blue key is also disconnected from the Archipelago item, so you can gather both. - -## What items and locations get shuffled? - -15 card packs, 10 relics, and 3 boss relics and rare card drops are shuffled into the item pool and can be found at any -location that would normally give you these items, except for card packs, which are found at every other normal enemy -encounter. - -## Which items can be in another player's world? - -Any of the items which can be shuffled may also be placed into another player's world. It is possible to choose to limit -certain items to your own world. - -## When the player receives an item, what happens? - -When the player receives an item, you will see the counter in the top right corner with the Archipelago symbol increment -by one. By clicking on this icon, it'll open a menu that lists all the items you received, but have not yet accepted. -You can take any relics and card packs sent to you and add them to your current run. It is advised that you do not open -this menu until you are outside an encounter or event to prevent the game from soft-locking. - -## What happens if a player dies in a run? - -When a player dies, they will be taken back to the main menu and will need to reconnect to start climbing the spire from -the beginning, but they will have access to all the items ever sent to them in the Archipelago menu in the top right. -Any items found in an earlier run will not be sent again if you encounter them in the same location. diff --git a/worlds/spire/docs/slay-the-spire_en.md b/worlds/spire/docs/slay-the-spire_en.md deleted file mode 100644 index daeb65415196..000000000000 --- a/worlds/spire/docs/slay-the-spire_en.md +++ /dev/null @@ -1,69 +0,0 @@ -# Slay the Spire Setup Guide - -## Required Software - -For Steam-based installation, subscribe to the following mods: - -- [ModTheSpire](https://steamcommunity.com/sharedfiles/filedetails/?id=1605060445) -- [BaseMod](https://steamcommunity.com/workshop/filedetails/?id=1605833019) -- [Archipelago Multiworld Randomizer](https://steamcommunity.com/sharedfiles/filedetails/?id=2596397288) -- (optional) [Downfall](https://steamcommunity.com/sharedfiles/filedetails/?id=1610056683) -- (required for downfall) [StSLib](https://steamcommunity.com/workshop/filedetails/?id=1609158507) - -For GOG or Xbox PC Game Pass installation: - -1. Download the official Steam Console Client [SteamCMD](https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip). -2. Unpack that .zip file into some folder and double-click on `steamcmd.exe`. -3. The client will now update itself. When it's ready type `login anonymous`. Now you are ready to download the actual - mods. -4. Run the following commands to download the required mod files: - - Mod the Spire: `workshop_download_item 646570 1605060445` - - BaseMod: `workshop_download_item 646570 1605833019` - - ArchipelagoMW: `workshop_download_item 646570 2596397288` - - (optional) Downfall: `workshop_download_item 646570 1610056683` - - (required for Downfall) StSLib: `workshop_download_item 646570 1609158507` -5. Open your Slay the Spire installation directory. By default on GOG this is `C:\GOG Games\Slay the Spire`, on PC Game - Pass this is `C:\XboxGames\Slay The Spire\Content`. -6. In the folder where you unzipped SteamCMD there will now be a `steamapps` folder. Copy ModTheSpire.jar from - `steamapps\workshop\content\646570\1605060445\ModTheSpire.jar` to your Slay The Spire installation directory. -7. Create a folder named `mods` inside the Slay the Spire installation directory. Each folder inside - `steamapps\workshop\content\646570` will have a single .jar file. Copy each of them except ModTheSpire.jar into the - `mods` folder you made. -8. Now open Notepad. Paste in the following text: `jre\bin\java.exe -jar ModTheSpire.jar`. Go to "File -> Save as" and - save it into your Slay the Spire installation directory with the name `"start.bat"`. Make sure to include the quotes - in the file name! - -## Configuring your YAML file - -### What is a YAML file and why do I need one? - -Your YAML file contains a set of configuration options which provide the generator with information about how it should -generate your game. Each player of a multiworld will provide their own YAML file. This setup allows each player to enjoy -an experience customized for their taste, and different players in the same multiworld can all have different options. - -### Where do I get a YAML file? - -you can customize your options by visiting -the [Slay the Spire Options Page](/games/Slay%20the%20Spire/player-options). - -### Connect to the MultiServer - -For Steam-based installations, if you are subscribed to ModTheSpire, when you launch the game, you should have the -option to launch the game with mods. - -For GOG or Xbox PC Game Pass intallations, launch the game by double-clicking the `start.bat` file you created earlier -which will give you the option to launch the game with mods. - -On the mod loader screen, ensure you only have the following mods enabled and then start the game: - -- BaseMod -- Archipelago Multiworld Randomizer - -If playing with Downfall, also make sure the following are enabled: - -- Downfall -- StSLib - -Once you are in-game, you will be able to click the **Archipelago** menu option and enter the ip and port (separated by -a colon) in the hostname field and enter your player slot name in the Slot Name field. Then click connect, and now you -are ready to climb the spire! From 0d9967e8d8720d4721cc8ca3a2684830df512518 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 26 Apr 2025 13:28:07 -0400 Subject: [PATCH 0369/1218] OC2: Account for Multiclass Items in Progression Balancing (#4929) --- worlds/overcooked2/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/overcooked2/__init__.py b/worlds/overcooked2/__init__.py index 44227d4becaa..1691d27ad8fb 100644 --- a/worlds/overcooked2/__init__.py +++ b/worlds/overcooked2/__init__.py @@ -173,7 +173,7 @@ def get_priority_locations(self) -> List[int]: game_item_count = len(self.itempool) game_progression_count = 0 for item in self.itempool: - if item.classification == ItemClassification.progression: + if item.advancement: game_progression_count += 1 game_progression_density = game_progression_count/game_item_count @@ -189,7 +189,7 @@ def get_priority_locations(self) -> List[int]: total_progression_count = 0 for item in self.multiworld.itempool: - if item.classification == ItemClassification.progression: + if item.advancement: total_progression_count += 1 total_progression_density = total_progression_count/total_item_count From 4e3da005d4a814e80939a17f369d22f7c1803a9f Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Sun, 27 Apr 2025 03:43:24 -0400 Subject: [PATCH 0370/1218] TWW: Fix generation failure with output file (#4932) --- worlds/tww/Options.py | 63 ++++++++++++++++++++++++++++++++++++++++++ worlds/tww/__init__.py | 2 +- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/worlds/tww/Options.py b/worlds/tww/Options.py index 6e7724e2a133..d37de3acf490 100644 --- a/worlds/tww/Options.py +++ b/worlds/tww/Options.py @@ -1,4 +1,5 @@ from dataclasses import dataclass +from typing import Any from Options import ( Choice, @@ -752,6 +753,68 @@ class TWWOptions(PerGameCommonOptions): remove_music: RemoveMusic death_link: DeathLink + def get_output_dict(self) -> dict[str, Any]: + """ + Returns a dictionary of option name to value to be placed in + the output APTWW file. + + :return: Dictionary of option name to value for the output file. + """ + + # Note: these options' values must be able to be passed through + # `yaml.safe_dump`. + return self.as_dict( + "progression_dungeons", + "progression_tingle_chests", + "progression_dungeon_secrets", + "progression_puzzle_secret_caves", + "progression_combat_secret_caves", + "progression_savage_labyrinth", + "progression_great_fairies", + "progression_short_sidequests", + "progression_long_sidequests", + "progression_spoils_trading", + "progression_minigames", + "progression_battlesquid", + "progression_free_gifts", + "progression_mail", + "progression_platforms_rafts", + "progression_submarines", + "progression_eye_reef_chests", + "progression_big_octos_gunboats", + "progression_triforce_charts", + "progression_treasure_charts", + "progression_expensive_purchases", + "progression_island_puzzles", + "progression_misc", + "randomize_mapcompass", + "randomize_smallkeys", + "randomize_bigkeys", + "sword_mode", + "required_bosses", + "num_required_bosses", + "chest_type_matches_contents", + "hero_mode", + "logic_obscurity", + "logic_precision", + "randomize_dungeon_entrances", + "randomize_secret_cave_entrances", + "randomize_miniboss_entrances", + "randomize_boss_entrances", + "randomize_secret_cave_inner_entrances", + "randomize_fairy_fountain_entrances", + "mix_entrances", + "randomize_enemies", + "randomize_starting_island", + "randomize_charts", + "swift_sail", + "instant_text_boxes", + "reveal_full_sea_chart", + "add_shortcut_warps_between_dungeons", + "skip_rematch_bosses", + "remove_music", + ) + tww_option_groups: list[OptionGroup] = [ OptionGroup( diff --git a/worlds/tww/__init__.py b/worlds/tww/__init__.py index 36ed77f9c9b1..6b6c3ca33a34 100644 --- a/worlds/tww/__init__.py +++ b/worlds/tww/__init__.py @@ -462,7 +462,7 @@ def generate_output(self, output_directory: str) -> None: "Seed": multiworld.seed_name, "Slot": player, "Name": self.player_name, - "Options": self.options.as_dict(*self.options_dataclass.type_hints), + "Options": self.options.get_output_dict(), "Required Bosses": self.boss_reqs.required_boss_item_locations, "Locations": {}, "Entrances": {}, From ce14f190fb2d15e68c17cb9ff3bfab413bea25f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Mon, 28 Apr 2025 18:12:52 -0400 Subject: [PATCH 0371/1218] Stardew Valley: Replace event creation stardew code with add_event (#4922) * replace event creation stardew code with add_event * delete unnecessary default args --- worlds/stardew_valley/__init__.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/worlds/stardew_valley/__init__.py b/worlds/stardew_valley/__init__.py index 7f420eb81ddb..f48c9bc1a462 100644 --- a/worlds/stardew_valley/__init__.py +++ b/worlds/stardew_valley/__init__.py @@ -299,17 +299,9 @@ def create_item(self, item: str | ItemData, override_classification: ItemClassif return StardewItem(item.name, override_classification, item.code, self.player) - def create_event_location(self, location_data: LocationData, rule: StardewRule = None, item: Optional[str] = None): - if rule is None: - rule = True_() - if item is None: - item = location_data.name - + def create_event_location(self, location_data: LocationData, rule: StardewRule, item: str): region = self.multiworld.get_region(location_data.region, self.player) - location = StardewLocation(self.player, location_data.name, None, region) - location.access_rule = rule - region.locations.append(location) - location.place_locked_item(StardewItem(item, ItemClassification.progression, None, self.player)) + region.add_event(location_data.name, item, rule, StardewLocation, StardewItem) def set_rules(self): set_rules(self) From b580d3c25aba4655e7aaac676ee15a73de2b969a Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Tue, 29 Apr 2025 06:32:36 +0000 Subject: [PATCH 0372/1218] CI: add optional windows release build and build attestation (#4940) * CI: github attestation for manually started builds * CI: include appimage zsync in build attestation * CI: github attestation for Linux release builds * CI: reorder steps in build.yml * CI: add windows builds to release.yml * CI: order jobs in release.yml * CI: add missing permission to release.yml * CI: enable windows build in release.yml * CI: false is skip --- .github/workflows/build.yml | 29 +++++++++++- .github/workflows/release.yml | 83 ++++++++++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7529f693bd7b..d6b80965f0ac 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,12 +21,17 @@ env: ENEMIZER_VERSION: 7.1 APPIMAGETOOL_VERSION: 13 +permissions: # permissions required for attestation + id-token: 'write' + attestations: 'write' + jobs: # build-release-macos: # LF volunteer - build-win: # RCs will still be built and signed by hand + build-win: # RCs and releases may still be built and signed by hand runs-on: windows-latest steps: + # - copy code below to release.yml - - uses: actions/checkout@v4 - name: Install python uses: actions/setup-python@v5 @@ -65,6 +70,18 @@ jobs: $contents = Get-ChildItem -Path setups/*.exe -Force -Recurse $SETUP_NAME=$contents[0].Name echo "SETUP_NAME=$SETUP_NAME" >> $Env:GITHUB_ENV + # - copy code above to release.yml - + - name: Attest Build + if: ${{ github.event_name == 'workflow_dispatch' }} + uses: actions/attest-build-provenance@v2 + with: + subject-path: | + build/exe.*/ArchipelagoLauncher.exe + build/exe.*/ArchipelagoLauncherDebug.exe + build/exe.*/ArchipelagoGenerate.exe + build/exe.*/ArchipelagoServer.exe + dist/${{ env.ZIP_NAME }} + setups/${{ env.SETUP_NAME }} - name: Check build loads expected worlds shell: bash run: | @@ -142,6 +159,16 @@ jobs: echo "APPIMAGE_NAME=$APPIMAGE_NAME" >> $GITHUB_ENV echo "TAR_NAME=$TAR_NAME" >> $GITHUB_ENV # - copy code above to release.yml - + - name: Attest Build + if: ${{ github.event_name == 'workflow_dispatch' }} + uses: actions/attest-build-provenance@v2 + with: + subject-path: | + build/exe.*/ArchipelagoLauncher + build/exe.*/ArchipelagoGenerate + build/exe.*/ArchipelagoServer + dist/${{ env.APPIMAGE_NAME }}* + dist/${{ env.TAR_NAME }} - name: Build Again run: | source venv/bin/activate diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 20d4d2fe3233..a500f9a23b3f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,6 +11,11 @@ env: ENEMIZER_VERSION: 7.1 APPIMAGETOOL_VERSION: 13 +permissions: # permissions required for attestation + id-token: 'write' + attestations: 'write' + contents: 'write' # additionally required for release + jobs: create-release: runs-on: ubuntu-latest @@ -26,11 +31,79 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # build-release-windows: # this is done by hand because of signing # build-release-macos: # LF volunteer + build-release-win: + runs-on: windows-latest + if: ${{ true }} # change to false to skip if release is built by hand + needs: create-release + steps: + - name: Set env + shell: bash + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV + # - code below copied from build.yml - + - uses: actions/checkout@v4 + - name: Install python + uses: actions/setup-python@v5 + with: + python-version: '~3.12.7' + check-latest: true + - name: Download run-time dependencies + run: | + Invoke-WebRequest -Uri https://github.com/Ijwu/Enemizer/releases/download/${Env:ENEMIZER_VERSION}/win-x64.zip -OutFile enemizer.zip + Expand-Archive -Path enemizer.zip -DestinationPath EnemizerCLI -Force + choco install innosetup --version=6.2.2 --allow-downgrade + - name: Build + run: | + python -m pip install --upgrade pip + python setup.py build_exe --yes + if ( $? -eq $false ) { + Write-Error "setup.py failed!" + exit 1 + } + $NAME="$(ls build | Select-String -Pattern 'exe')".Split('.',2)[1] + $ZIP_NAME="Archipelago_$NAME.7z" + echo "$NAME -> $ZIP_NAME" + echo "ZIP_NAME=$ZIP_NAME" >> $Env:GITHUB_ENV + New-Item -Path dist -ItemType Directory -Force + cd build + Rename-Item "exe.$NAME" Archipelago + 7z a -mx=9 -mhe=on -ms "../dist/$ZIP_NAME" Archipelago + Rename-Item Archipelago "exe.$NAME" # inno_setup.iss expects the original name + - name: Build Setup + run: | + & "${env:ProgramFiles(x86)}\Inno Setup 6\iscc.exe" inno_setup.iss /DNO_SIGNTOOL + if ( $? -eq $false ) { + Write-Error "Building setup failed!" + exit 1 + } + $contents = Get-ChildItem -Path setups/*.exe -Force -Recurse + $SETUP_NAME=$contents[0].Name + echo "SETUP_NAME=$SETUP_NAME" >> $Env:GITHUB_ENV + # - code above copied from build.yml - + - name: Attest Build + uses: actions/attest-build-provenance@v2 + with: + subject-path: | + build/exe.*/ArchipelagoLauncher.exe + build/exe.*/ArchipelagoLauncherDebug.exe + build/exe.*/ArchipelagoGenerate.exe + build/exe.*/ArchipelagoServer.exe + setups/* + - name: Add to Release + uses: softprops/action-gh-release@975c1b265e11dd76618af1c374e7981f9a6ff44a + with: + draft: true # see above + prerelease: false + name: Archipelago ${{ env.RELEASE_VERSION }} + files: | + setups/* + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + build-release-ubuntu2204: runs-on: ubuntu-22.04 + needs: create-release steps: - name: Set env run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV @@ -74,6 +147,14 @@ jobs: echo "APPIMAGE_NAME=$APPIMAGE_NAME" >> $GITHUB_ENV echo "TAR_NAME=$TAR_NAME" >> $GITHUB_ENV # - code above copied from build.yml - + - name: Attest Build + uses: actions/attest-build-provenance@v2 + with: + subject-path: | + build/exe.*/ArchipelagoLauncher + build/exe.*/ArchipelagoGenerate + build/exe.*/ArchipelagoServer + dist/* - name: Add to Release uses: softprops/action-gh-release@975c1b265e11dd76618af1c374e7981f9a6ff44a with: From ec768a2e897987e7be9673b46ec5984cf8770335 Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Tue, 29 Apr 2025 10:53:31 -0400 Subject: [PATCH 0373/1218] ALTTP: Swamp Palace West logic fix (#4936) --- worlds/alttp/Rules.py | 4 +--- worlds/alttp/test/dungeons/TestSwampPalace.py | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index 452c15223ca7..2d11d537fbe8 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -393,9 +393,7 @@ def global_rules(multiworld: MultiWorld, player: int): if world.options.pot_shuffle: # it could move the key to the top right platform which can only be reached with bombs add_rule(multiworld.get_location('Swamp Palace - Hookshot Pot Key', player), lambda state: can_use_bombs(state, player)) - set_rule(multiworld.get_entrance('Swamp Palace (West)', player), lambda state: state._lttp_has_key('Small Key (Swamp Palace)', player, 6) - if state.has('Hookshot', player) - else state._lttp_has_key('Small Key (Swamp Palace)', player, 4)) + set_rule(multiworld.get_entrance('Swamp Palace (West)', player), lambda state: state._lttp_has_key('Small Key (Swamp Palace)', player, 6)) set_rule(multiworld.get_location('Swamp Palace - Big Chest', player), lambda state: state.has('Big Key (Swamp Palace)', player)) if world.options.accessibility != 'full': allow_self_locking_items(multiworld.get_location('Swamp Palace - Big Chest', player), 'Big Key (Swamp Palace)') diff --git a/worlds/alttp/test/dungeons/TestSwampPalace.py b/worlds/alttp/test/dungeons/TestSwampPalace.py index fb0672a5a9cc..5bfd90171f26 100644 --- a/worlds/alttp/test/dungeons/TestSwampPalace.py +++ b/worlds/alttp/test/dungeons/TestSwampPalace.py @@ -24,7 +24,7 @@ def testSwampPalace(self): ["Swamp Palace - Big Key Chest", False, [], ['Open Floodgate']], ["Swamp Palace - Big Key Chest", False, [], ['Hammer']], ["Swamp Palace - Big Key Chest", False, [], ['Small Key (Swamp Palace)']], - ["Swamp Palace - Big Key Chest", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer']], + ["Swamp Palace - Big Key Chest", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer']], ["Swamp Palace - Map Chest", False, []], ["Swamp Palace - Map Chest", False, [], ['Flippers']], @@ -38,7 +38,7 @@ def testSwampPalace(self): ["Swamp Palace - West Chest", False, [], ['Open Floodgate']], ["Swamp Palace - West Chest", False, [], ['Hammer']], ["Swamp Palace - West Chest", False, [], ['Small Key (Swamp Palace)']], - ["Swamp Palace - West Chest", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer']], + ["Swamp Palace - West Chest", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer']], ["Swamp Palace - Compass Chest", False, []], ["Swamp Palace - Compass Chest", False, [], ['Flippers']], From 3ef35105c88c7ea44dfa52229b055deb7a45dcf3 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Tue, 29 Apr 2025 22:27:54 -0400 Subject: [PATCH 0374/1218] LADX: Remove copyrighted assets (#4935) --- LinksAwakeningClient.py | 26 +++++++------------------- data/sprites/ladx/Bowwow.bdiff | Bin 7354 -> 0 bytes data/sprites/ladx/Bunny.bdiff | Bin 3083 -> 0 bytes data/sprites/ladx/Luigi.bdiff | Bin 13112 -> 0 bytes data/sprites/ladx/Mario.bdiff | Bin 9025 -> 0 bytes data/sprites/ladx/Richard.bdiff | Bin 8207 -> 0 bytes data/sprites/ladx/Tarin.bdiff | Bin 8309 -> 0 bytes 7 files changed, 7 insertions(+), 19 deletions(-) delete mode 100644 data/sprites/ladx/Bowwow.bdiff delete mode 100644 data/sprites/ladx/Bunny.bdiff delete mode 100644 data/sprites/ladx/Luigi.bdiff delete mode 100644 data/sprites/ladx/Mario.bdiff delete mode 100644 data/sprites/ladx/Richard.bdiff delete mode 100644 data/sprites/ladx/Tarin.bdiff diff --git a/LinksAwakeningClient.py b/LinksAwakeningClient.py index 69f50938d2fb..16896540d664 100644 --- a/LinksAwakeningClient.py +++ b/LinksAwakeningClient.py @@ -52,22 +52,6 @@ class BadRetroArchResponse(GameboyException): pass -def magpie_logo(): - from kivy.uix.image import CoreImage - binary_data = """ -iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXN -SR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA -7DAcdvqGQAAADGSURBVDhPhVLBEcIwDHOYhjHCBuXHj2OTbAL8+ -MEGZIxOQ1CinOOk0Op0bmo7tlXXeR9FJMYDLOD9mwcLjQK7+hSZ -wgcWMZJOAGeGKtChNHFL0j+FZD3jSCuo0w7l03wDrWdg00C4/aW -eDEYNenuzPOfPspBnxf0kssE80vN0L8361j10P03DK4x6FHabuV -ear8fHme+b17rwSjbAXeUMLb+EVTV2QHm46MWQanmnydA98KsVS -XkV+qFpGQXrLhT/fqraQeQLuplpNH5g+WkAAAAASUVORK5CYII=""" - binary_data = base64.b64decode(binary_data) - data = io.BytesIO(binary_data) - return CoreImage(data, ext="png").texture - - class LAClientConstants: # Connector version VERSION = 0x01 @@ -530,7 +514,9 @@ def __init__(self, server_address: typing.Optional[str], password: typing.Option def run_gui(self) -> None: import webbrowser - from kvui import GameManager, ImageButton + from kvui import GameManager + from kivy.metrics import dp + from kivymd.uix.button import MDButton, MDButtonText class LADXManager(GameManager): logging_pairs = [ @@ -543,8 +529,10 @@ def build(self): b = super().build() if self.ctx.magpie_enabled: - button = ImageButton(texture=magpie_logo(), fit_mode="cover", image_size=(32, 32), size_hint_x=None, - on_press=lambda _: webbrowser.open('https://magpietracker.us/?enable_autotracker=1')) + button = MDButton(MDButtonText(text="Open Tracker"), style="filled", size=(dp(100), dp(70)), radius=5, + size_hint_x=None, size_hint_y=None, pos_hint={"center_y": 0.55}, + on_press=lambda _: webbrowser.open('https://magpietracker.us/?enable_autotracker=1')) + button.height = self.server_connect_bar.height self.connect_layout.add_widget(button) return b diff --git a/data/sprites/ladx/Bowwow.bdiff b/data/sprites/ladx/Bowwow.bdiff deleted file mode 100644 index bdfe9f42f23bf24c4ea8901ef9ba1dde5f4827a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7354 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 XNBPQyn4D6uElTZHxZ+2Vu diff --git a/data/sprites/ladx/Luigi.bdiff b/data/sprites/ladx/Luigi.bdiff deleted file mode 100644 index 1897a65d01463797e61e535ea26cb79882f42171..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13112 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 diff --git a/data/sprites/ladx/Mario.bdiff b/data/sprites/ladx/Mario.bdiff deleted file mode 100644 index 389fa94ab12862aef4cb035ff2ae688704ed25bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9025 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 Date: Wed, 30 Apr 2025 03:57:35 +0100 Subject: [PATCH 0375/1218] SM: Fix FakeROM instances sharing the same data dictionary (#4912) FakeROM instances were being created with default arguments, which included a mutable default argument data dictionary, so all FakeROM instances would be writing to and reading the same dictionary, resulting in broken patch data in multiworlds with more than one Super Metroid world. --- worlds/sm/variaRandomizer/rom/rom.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/worlds/sm/variaRandomizer/rom/rom.py b/worlds/sm/variaRandomizer/rom/rom.py index f0f37b76a37e..05218ff52a58 100644 --- a/worlds/sm/variaRandomizer/rom/rom.py +++ b/worlds/sm/variaRandomizer/rom/rom.py @@ -89,9 +89,12 @@ def fillToNextBank(self): class FakeROM(ROM): # to have the same code for real ROM and the webservice - def __init__(self, data={}): + def __init__(self, data=None): super(FakeROM, self).__init__() - self.data = data + if data is None: + self.data = {} + else: + self.data = data self.ipsPatches = [] def write(self, bytes): From 611e1c2b1928ba3ffda7bbef2bae33c4ac1a056d Mon Sep 17 00:00:00 2001 From: PoryGone <98504756+PoryGone@users.noreply.github.com> Date: Wed, 30 Apr 2025 10:24:10 -0400 Subject: [PATCH 0376/1218] SMW: v2.1 Feature Update (#4652) ### Features: - Trap Link - When you receive a trap, you send a copy of it to every other player with Trap Link enabled - Ring Link - Any coin amounts gained and lost by a linked player will be instantly shared with all other active linked players Co-authored-by: TheLX5 --- worlds/smw/CHANGELOG.md | 9 ++ worlds/smw/Client.py | 225 +++++++++++++++++++++++++++++++++--- worlds/smw/Items.py | 46 ++++++++ worlds/smw/Names/TextBox.py | 25 ++++ worlds/smw/Options.py | 16 +++ worlds/smw/Rom.py | 6 +- worlds/smw/__init__.py | 13 +++ 7 files changed, 320 insertions(+), 20 deletions(-) diff --git a/worlds/smw/CHANGELOG.md b/worlds/smw/CHANGELOG.md index 7f62997adcef..f1e031197c9f 100644 --- a/worlds/smw/CHANGELOG.md +++ b/worlds/smw/CHANGELOG.md @@ -1,6 +1,15 @@ # Super Mario World - Changelog +## v2.1 + +### Features: +- Trap Link + - When you receive a trap, you send a copy of it to every other player with Trap Link enabled +- Ring Link + - Any coin amounts gained and lost by a linked player will be instantly shared with all other active linked players + + ## v2.0 ### Features: diff --git a/worlds/smw/Client.py b/worlds/smw/Client.py index 600e1bff8304..85524eb7ad41 100644 --- a/worlds/smw/Client.py +++ b/worlds/smw/Client.py @@ -1,9 +1,11 @@ import logging import time +from typing import Any -from NetUtils import ClientStatus, color +from NetUtils import ClientStatus, NetworkItem, color from worlds.AutoSNIClient import SNIClient -from .Names.TextBox import generate_received_text +from .Names.TextBox import generate_received_text, generate_received_trap_link_text +from .Items import trap_value_to_name, trap_name_to_value snes_logger = logging.getLogger("SNES") @@ -42,10 +44,13 @@ SMW_HIDDEN_1UP_ACTIVE_ADDR = ROM_START + 0x01BFA9 SMW_BONUS_BLOCK_ACTIVE_ADDR = ROM_START + 0x01BFAA SMW_BLOCKSANITY_ACTIVE_ADDR = ROM_START + 0x01BFAB +SMW_TRAP_LINK_ACTIVE_ADDR = ROM_START + 0x01BFB7 +SMW_RING_LINK_ACTIVE_ADDR = ROM_START + 0x01BFB8 SMW_GAME_STATE_ADDR = WRAM_START + 0x100 SMW_MARIO_STATE_ADDR = WRAM_START + 0x71 +SMW_COIN_COUNT_ADDR = WRAM_START + 0xDBF SMW_BOSS_STATE_ADDR = WRAM_START + 0xD9B SMW_ACTIVE_BOSS_ADDR = WRAM_START + 0x13FC SMW_CURRENT_LEVEL_ADDR = WRAM_START + 0x13BF @@ -76,6 +81,7 @@ class SMWSNIClient(SNIClient): game = "Super Mario World" patch_suffix = ".apsmw" + slot_data: dict[str, Any] | None async def deathlink_kill_player(self, ctx): from SNIClient import DeathState, snes_buffered_write, snes_flush_writes, snes_read @@ -111,6 +117,84 @@ async def deathlink_kill_player(self, ctx): ctx.last_death_link = time.time() + def on_package(self, ctx: SNIClient, cmd: str, args: dict[str, Any]) -> None: + super().on_package(ctx, cmd, args) + + if cmd == "Connected": + self.slot_data = args.get("slot_data", None) + + if cmd != "Bounced": + return + if "tags" not in args: + return + + if not hasattr(self, "instance_id"): + self.instance_id = time.time() + + source_name = args["data"]["source"] + if "TrapLink" in ctx.tags and "TrapLink" in args["tags"] and source_name != ctx.slot_info[ctx.slot].name: + trap_name: str = args["data"]["trap_name"] + if trap_name not in trap_name_to_value: + # We don't know how to handle this trap, ignore it + return + + trap_id: int = trap_name_to_value[trap_name] + + if "trap_weights" not in self.slot_data: + return + + if f"{trap_id}" not in self.slot_data["trap_weights"]: + return + + if self.slot_data["trap_weights"][f"{trap_id}"] == 0: + # The player disabled this trap type + return + + self.priority_trap = NetworkItem(trap_id, None, None) + self.priority_trap_message = generate_received_trap_link_text(trap_name, source_name) + self.priority_trap_message_str = f"Received linked {trap_name} from {source_name}" + elif "RingLink" in ctx.tags and "RingLink" in args["tags"] and source_name != self.instance_id: + if not hasattr(self, "pending_ring_link"): + self.pending_ring_link = 0 + self.pending_ring_link += args["data"]["amount"] + + async def send_trap_link(self, ctx: SNIClient, trap_name: str): + if "TrapLink" not in ctx.tags or ctx.slot == None: + return + + await ctx.send_msgs([{ + "cmd": "Bounce", "tags": ["TrapLink"], + "data": { + "time": time.time(), + "source": ctx.player_names[ctx.slot], + "trap_name": trap_name + } + }]) + snes_logger.info(f"Sent linked {trap_name}") + + async def send_ring_link(self, ctx: SNIClient, amount: int): + from SNIClient import DeathState, snes_buffered_write, snes_flush_writes, snes_read + + if "RingLink" not in ctx.tags or ctx.slot == None: + return + + game_state = await snes_read(ctx, SMW_GAME_STATE_ADDR, 0x1) + if game_state[0] != 0x14: + return + + if not hasattr(self, "instance_id"): + self.instance_id = time.time() + + await ctx.send_msgs([{ + "cmd": "Bounce", "tags": ["RingLink"], + "data": { + "time": time.time(), + "source": self.instance_id, + "amount": amount + } + }]) + + async def validate_rom(self, ctx): from SNIClient import snes_buffered_write, snes_flush_writes, snes_read @@ -123,9 +207,11 @@ async def validate_rom(self, ctx): receive_option = await snes_read(ctx, SMW_RECEIVE_MSG_DATA, 0x1) send_option = await snes_read(ctx, SMW_SEND_MSG_DATA, 0x1) + trap_link = await snes_read(ctx, SMW_TRAP_LINK_ACTIVE_ADDR, 0x1) ctx.receive_option = receive_option[0] ctx.send_option = send_option[0] + ctx.trap_link = trap_link[0] ctx.allow_collect = True @@ -133,6 +219,15 @@ async def validate_rom(self, ctx): if death_link: await ctx.update_death_link(bool(death_link[0] & 0b1)) + if trap_link and bool(trap_link[0] & 0b1) and "TrapLink" not in ctx.tags: + ctx.tags.add("TrapLink") + await ctx.send_msgs([{"cmd": "ConnectUpdate", "tags": ctx.tags}]) + + ring_link = await snes_read(ctx, SMW_RING_LINK_ACTIVE_ADDR, 1) + if ring_link and bool(ring_link[0] & 0b1) and "RingLink" not in ctx.tags: + ctx.tags.add("RingLink") + await ctx.send_msgs([{"cmd": "ConnectUpdate", "tags": ctx.tags}]) + if ctx.rom != rom_name: ctx.current_sublevel_value = 0 @@ -142,12 +237,17 @@ async def validate_rom(self, ctx): def add_message_to_queue(self, new_message): - if not hasattr(self, "message_queue"): self.message_queue = [] self.message_queue.append(new_message) + def add_message_to_queue_front(self, new_message): + if not hasattr(self, "message_queue"): + self.message_queue = [] + + self.message_queue.insert(0, new_message) + async def handle_message_queue(self, ctx): from SNIClient import snes_buffered_write, snes_flush_writes, snes_read @@ -206,7 +306,8 @@ def should_show_message(self, ctx, next_item): async def handle_trap_queue(self, ctx): from SNIClient import snes_buffered_write, snes_flush_writes, snes_read - if not hasattr(self, "trap_queue") or len(self.trap_queue) == 0: + if (not hasattr(self, "trap_queue") or len(self.trap_queue) == 0) and\ + (not hasattr(self, "priority_trap") or self.priority_trap == 0): return game_state = await snes_read(ctx, SMW_GAME_STATE_ADDR, 0x1) @@ -221,7 +322,24 @@ async def handle_trap_queue(self, ctx): if pause_state[0] != 0x00: return - next_trap, message = self.trap_queue.pop(0) + + next_trap = None + message = bytearray() + message_str = "" + from_queue = False + + if getattr(self, "priority_trap", None) and self.priority_trap.item != 0: + next_trap = self.priority_trap + message = self.priority_trap_message + message_str = self.priority_trap_message_str + self.priority_trap = None + self.priority_trap_message = bytearray() + self.priority_trap_message_str = "" + elif hasattr(self, "trap_queue") and len(self.trap_queue) > 0: + from_queue = True + next_trap, message = self.trap_queue.pop(0) + else: + return from .Rom import trap_rom_data if next_trap.item in trap_rom_data: @@ -231,16 +349,22 @@ async def handle_trap_queue(self, ctx): # Timer Trap if trap_active[0] == 0 or (trap_active[0] == 1 and trap_active[1] == 0 and trap_active[2] == 0): # Trap already active - self.add_trap_to_queue(next_trap, message) + if from_queue: + self.add_trap_to_queue(next_trap, message) return else: + if len(message_str) > 0: + snes_logger.info(message_str) + if "TrapLink" in ctx.tags and from_queue: + await self.send_trap_link(ctx, trap_value_to_name[next_trap.item]) snes_buffered_write(ctx, WRAM_START + trap_rom_data[next_trap.item][0], bytes([0x01])) snes_buffered_write(ctx, WRAM_START + trap_rom_data[next_trap.item][0] + 1, bytes([0x00])) snes_buffered_write(ctx, WRAM_START + trap_rom_data[next_trap.item][0] + 2, bytes([0x00])) else: if trap_active[0] > 0: # Trap already active - self.add_trap_to_queue(next_trap, message) + if from_queue: + self.add_trap_to_queue(next_trap, message) return else: if next_trap.item == 0xBC001D: @@ -248,12 +372,18 @@ async def handle_trap_queue(self, ctx): # Do not fire if the previous thwimp hasn't reached the player's Y pos active_thwimp = await snes_read(ctx, SMW_ACTIVE_THWIMP_ADDR, 0x1) if active_thwimp[0] != 0xFF: - self.add_trap_to_queue(next_trap, message) + if from_queue: + self.add_trap_to_queue(next_trap, message) return verify_game_state = await snes_read(ctx, SMW_GAME_STATE_ADDR, 0x1) if verify_game_state[0] == 0x14 and len(trap_rom_data[next_trap.item]) > 2: snes_buffered_write(ctx, SMW_SFX_ADDR, bytes([trap_rom_data[next_trap.item][2]])) + if len(message_str) > 0: + snes_logger.info(message_str) + if "TrapLink" in ctx.tags and from_queue: + await self.send_trap_link(ctx, trap_value_to_name[next_trap.item]) + new_item_count = trap_rom_data[next_trap.item][1] snes_buffered_write(ctx, WRAM_START + trap_rom_data[next_trap.item][0], bytes([new_item_count])) @@ -270,9 +400,75 @@ async def handle_trap_queue(self, ctx): return if self.should_show_message(ctx, next_trap): + self.add_message_to_queue_front(message) + elif next_trap.item == 0xBC0015: + if self.should_show_message(ctx, next_trap): + self.add_message_to_queue_front(message) + if len(message_str) > 0: + snes_logger.info(message_str) + if "TrapLink" in ctx.tags and from_queue: + await self.send_trap_link(ctx, trap_value_to_name[next_trap.item]) + + # Handle Literature Trap + from .Names.LiteratureTrap import lit_trap_text_list + import random + rand_trap = random.choice(lit_trap_text_list) + + for message in rand_trap: self.add_message_to_queue(message) + async def handle_ring_link(self, ctx): + from SNIClient import snes_buffered_write, snes_flush_writes, snes_read + + if "RingLink" not in ctx.tags: + return + + if not hasattr(self, "prev_coins"): + self.prev_coins = 0 + + curr_coins_byte = await snes_read(ctx, SMW_COIN_COUNT_ADDR, 0x1) + curr_coins = curr_coins_byte[0] + + if curr_coins < self.prev_coins: + # Coins rolled over from 1-Up + curr_coins += 100 + + coins_diff = curr_coins - self.prev_coins + if coins_diff > 0: + await self.send_ring_link(ctx, coins_diff) + self.prev_coins = curr_coins % 100 + + new_coins = curr_coins + if not hasattr(self, "pending_ring_link"): + self.pending_ring_link = 0 + + if self.pending_ring_link != 0: + new_coins += self.pending_ring_link + new_coins = max(new_coins, 0) + + new_1_ups = 0 + while new_coins >= 100: + new_1_ups += 1 + new_coins -= 100 + + if new_1_ups > 0: + curr_lives_inc_byte = await snes_read(ctx, WRAM_START + 0x18E4, 0x1) + curr_lives_inc = curr_lives_inc_byte[0] + new_lives_inc = curr_lives_inc + new_1_ups + snes_buffered_write(ctx, WRAM_START + 0x18E4, bytes([new_lives_inc])) + + snes_buffered_write(ctx, SMW_COIN_COUNT_ADDR, bytes([new_coins])) + if self.pending_ring_link > 0: + snes_buffered_write(ctx, SMW_SFX_ADDR, bytes([0x01])) + else: + snes_buffered_write(ctx, SMW_SFX_ADDR, bytes([0x2A])) + self.pending_ring_link = 0 + self.prev_coins = new_coins + + await snes_flush_writes(ctx) + + async def game_watcher(self, ctx): from SNIClient import snes_buffered_write, snes_flush_writes, snes_read @@ -333,6 +529,7 @@ async def game_watcher(self, ctx): await self.handle_message_queue(ctx) await self.handle_trap_queue(ctx) + await self.handle_ring_link(ctx) new_checks = [] event_data = await snes_read(ctx, SMW_EVENT_ROM_DATA, 0x60) @@ -506,7 +703,7 @@ async def game_watcher(self, ctx): ctx.location_names.lookup_in_slot(item.location, item.player), recv_index, len(ctx.items_received))) if self.should_show_message(ctx, item): - if item.item != 0xBC0012 and item.item not in trap_rom_data: + if item.item != 0xBC0012 and item.item != 0xBC0015 and item.item not in trap_rom_data: # Don't send messages for Boss Tokens item_name = ctx.item_names.lookup_in_game(item.item) player_name = ctx.player_names[item.player] @@ -515,7 +712,7 @@ async def game_watcher(self, ctx): self.add_message_to_queue(receive_message) snes_buffered_write(ctx, SMW_RECV_PROGRESS_ADDR, bytes([recv_index&0xFF, (recv_index>>8)&0xFF])) - if item.item in trap_rom_data: + if item.item in trap_rom_data or item.item == 0xBC0015: item_name = ctx.item_names.lookup_in_game(item.item) player_name = ctx.player_names[item.player] @@ -572,14 +769,6 @@ async def game_watcher(self, ctx): else: # Extra Powerup? pass - elif item.item == 0xBC0015: - # Handle Literature Trap - from .Names.LiteratureTrap import lit_trap_text_list - import random - rand_trap = random.choice(lit_trap_text_list) - - for message in rand_trap: - self.add_message_to_queue(message) await snes_flush_writes(ctx) diff --git a/worlds/smw/Items.py b/worlds/smw/Items.py index eaf58b9b8e4e..e5f5c2722373 100644 --- a/worlds/smw/Items.py +++ b/worlds/smw/Items.py @@ -75,3 +75,49 @@ class SMWItem(Item): } lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in item_table.items() if data.code} + + +trap_value_to_name: typing.Dict[int, str] = { + 0xBC0013: ItemName.ice_trap, + 0xBC0014: ItemName.stun_trap, + 0xBC0015: ItemName.literature_trap, + 0xBC0016: ItemName.timer_trap, + 0xBC001C: ItemName.reverse_controls_trap, + 0xBC001D: ItemName.thwimp_trap, +} + +trap_name_to_value: typing.Dict[str, int] = { + # Our native Traps + ItemName.ice_trap: 0xBC0013, + ItemName.stun_trap: 0xBC0014, + ItemName.literature_trap: 0xBC0015, + ItemName.timer_trap: 0xBC0016, + ItemName.reverse_controls_trap: 0xBC001C, + ItemName.thwimp_trap: 0xBC001D, + + # Common other trap names + "Chaos Control Trap": 0xBC0014, # Stun Trap + "Confuse Trap": 0xBC001C, # Reverse Trap + "Exposition Trap": 0xBC0015, # Literature Trap + "Cutscene Trap": 0xBC0015, # Literature Trap + "Freeze Trap": 0xBC0014, # Stun Trap + "Frozen Trap": 0xBC0014, # Stun Trap + "Paralyze Trap": 0xBC0014, # Stun Trap + "Reversal Trap": 0xBC001C, # Reverse Trap + "Fuzzy Trap": 0xBC001C, # Reverse Trap + "Confound Trap": 0xBC001C, # Reverse Trap + "Confusion Trap": 0xBC001C, # Reverse Trap + "Police Trap": 0xBC001D, # Thwimp Trap + "Buyon Trap": 0xBC001D, # Thwimp Trap + "Gooey Bag": 0xBC001D, # Thwimp Trap + "TNT Barrel Trap": 0xBC001D, # Thwimp Trap + "Honey Trap": 0xBC0014, # Stun Trap + "Screen Flip Trap": 0xBC001C, # Reverse Trap + "Banana Trap": 0xBC0013, # Ice Trap + "Bomb": 0xBC001D, # Thwimp Trap + "Bonk Trap": 0xBC0014, # Stun Trap + "Ghost": 0xBC001D, # Thwimp Trap + "Fast Trap": 0xBC0016, # Timer Trap + "Nut Trap": 0xBC001D, # Thwimp Trap + "Army Trap": 0xBC001D, # Thwimp Trap +} diff --git a/worlds/smw/Names/TextBox.py b/worlds/smw/Names/TextBox.py index 2302a5f85fc9..fef04627b6e5 100644 --- a/worlds/smw/Names/TextBox.py +++ b/worlds/smw/Names/TextBox.py @@ -117,6 +117,31 @@ def generate_received_text(item_name: str, player_name: str): return out_array +def generate_received_trap_link_text(item_name: str, player_name: str): + out_array = bytearray() + + item_name = item_name[:18] + player_name = player_name[:18] + + item_buffer = max(0, math.floor((18 - len(item_name)) / 2)) + player_buffer = max(0, math.floor((18 - len(player_name)) / 2)) + + out_array += bytearray([0x9F, 0x9F]) + out_array += string_to_bytes(" Received linked") + out_array[-1] += 0x80 + out_array += bytearray([0x1F] * item_buffer) + out_array += string_to_bytes(item_name) + out_array[-1] += 0x80 + out_array += string_to_bytes(" from") + out_array[-1] += 0x80 + out_array += bytearray([0x1F] * player_buffer) + out_array += string_to_bytes(player_name) + out_array[-1] += 0x80 + out_array += bytearray([0x9F, 0x9F]) + + return out_array + + def generate_sent_text(item_name: str, player_name: str): out_array = bytearray() diff --git a/worlds/smw/Options.py b/worlds/smw/Options.py index 545b3c931b42..1dcfb16b85e2 100644 --- a/worlds/smw/Options.py +++ b/worlds/smw/Options.py @@ -398,6 +398,20 @@ class StartingLifeCount(Range): default = 5 +class RingLink(Toggle): + """ + Whether your in-level coin gain/loss is linked to other players + """ + display_name = "Ring Link" + + +class TrapLink(Toggle): + """ + Whether your received traps are linked to other players + """ + display_name = "Trap Link" + + smw_option_groups = [ OptionGroup("Goal Options", [ Goal, @@ -447,6 +461,8 @@ class StartingLifeCount(Range): @dataclass class SMWOptions(PerGameCommonOptions): death_link: DeathLink + ring_link: RingLink + trap_link: TrapLink goal: Goal bosses_required: BossesRequired max_yoshi_egg_cap: NumberOfYoshiEggs diff --git a/worlds/smw/Rom.py b/worlds/smw/Rom.py index ff3b5c31634d..9016e14def91 100644 --- a/worlds/smw/Rom.py +++ b/worlds/smw/Rom.py @@ -719,8 +719,8 @@ def handle_vertical_scroll(rom): 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, # Levels 0D0-0DF 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, # Levels 0E0-0EF 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, # Levels 0F0-0FF - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0x01, # Levels 100-10F - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, # Levels 110-11F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0x01, # Levels 100-10F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, # Levels 110-11F 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, # Levels 120-12F 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, # Levels 130-13F 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, # Levels 140-14F @@ -3160,6 +3160,8 @@ def patch_rom(world: World, rom, player, active_level_dict): rom.write_byte(0x01BFA9, world.options.hidden_1up_checks.value) rom.write_byte(0x01BFAA, world.options.bonus_block_checks.value) rom.write_byte(0x01BFAB, world.options.blocksanity.value) + rom.write_byte(0x01BFB7, world.options.trap_link.value) + rom.write_byte(0x01BFB8, world.options.ring_link.value) from Utils import __version__ diff --git a/worlds/smw/__init__.py b/worlds/smw/__init__.py index 97fc84f003a0..56ca82abb25c 100644 --- a/worlds/smw/__init__.py +++ b/worlds/smw/__init__.py @@ -90,6 +90,7 @@ def fill_slot_data(self) -> dict: "blocksanity", ) slot_data["active_levels"] = self.active_level_dict + slot_data["trap_weights"] = self.output_trap_weights() return slot_data @@ -322,3 +323,15 @@ def get_filler_item_name(self) -> str: def set_rules(self): set_rules(self) + + def output_trap_weights(self) -> dict[int, int]: + trap_data = {} + + trap_data[0xBC0013] = self.options.ice_trap_weight.value + trap_data[0xBC0014] = self.options.stun_trap_weight.value + trap_data[0xBC0015] = self.options.literature_trap_weight.value + trap_data[0xBC0016] = self.options.timer_trap_weight.value + trap_data[0xBC001C] = self.options.reverse_trap_weight.value + trap_data[0xBC001D] = self.options.thwimp_trap_weight.value + + return trap_data From 227f0bce3d8c904a153d993da2da27b26b63aac6 Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Wed, 30 Apr 2025 07:31:33 -0700 Subject: [PATCH 0377/1218] Pokemon Red/Blue: Convert to Procedure Patch (#4801) --- worlds/pokemon_rb/__init__.py | 16 +- worlds/pokemon_rb/pokemon.py | 21 +- worlds/pokemon_rb/rock_tunnel.py | 87 +++-- worlds/pokemon_rb/rom.py | 541 +++++++++++++++---------------- 4 files changed, 335 insertions(+), 330 deletions(-) diff --git a/worlds/pokemon_rb/__init__.py b/worlds/pokemon_rb/__init__.py index 644aa1ed9cab..6bf66a11064a 100644 --- a/worlds/pokemon_rb/__init__.py +++ b/worlds/pokemon_rb/__init__.py @@ -18,7 +18,7 @@ from .options import PokemonRBOptions from .rom_addresses import rom_addresses from .text import encode_text -from .rom import generate_output, get_base_rom_bytes, get_base_rom_path, RedDeltaPatch, BlueDeltaPatch +from .rom import generate_output, PokemonRedProcedurePatch, PokemonBlueProcedurePatch from .pokemon import process_pokemon_data, process_move_data, verify_hm_moves from .encounters import process_pokemon_locations, process_trainer_data from .rules import set_rules @@ -33,12 +33,12 @@ class RedRomFile(settings.UserFilePath): """File names of the Pokemon Red and Blue roms""" description = "Pokemon Red (UE) ROM File" copy_to = "Pokemon Red (UE) [S][!].gb" - md5s = [RedDeltaPatch.hash] + md5s = [PokemonRedProcedurePatch.hash] class BlueRomFile(settings.UserFilePath): description = "Pokemon Blue (UE) ROM File" copy_to = "Pokemon Blue (UE) [S][!].gb" - md5s = [BlueDeltaPatch.hash] + md5s = [PokemonBlueProcedurePatch.hash] red_rom_file: RedRomFile = RedRomFile(RedRomFile.copy_to) blue_rom_file: BlueRomFile = BlueRomFile(BlueRomFile.copy_to) @@ -113,16 +113,6 @@ def __init__(self, multiworld: MultiWorld, player: int): self.local_locs = [] self.pc_item = None - @classmethod - def stage_assert_generate(cls, multiworld: MultiWorld): - versions = set() - for player in multiworld.player_ids: - if multiworld.worlds[player].game == "Pokemon Red and Blue": - versions.add(multiworld.worlds[player].options.game_version.current_key) - for version in versions: - if not os.path.exists(get_base_rom_path(version)): - raise FileNotFoundError(get_base_rom_path(version)) - @classmethod def stage_generate_early(cls, multiworld: MultiWorld): diff --git a/worlds/pokemon_rb/pokemon.py b/worlds/pokemon_rb/pokemon.py index 32c0e36869da..e5d161a43310 100644 --- a/worlds/pokemon_rb/pokemon.py +++ b/worlds/pokemon_rb/pokemon.py @@ -1,9 +1,17 @@ from copy import deepcopy +import typing + +from worlds.Files import APTokenTypes + from . import poke_data, logic from .rom_addresses import rom_addresses +if typing.TYPE_CHECKING: + from . import PokemonRedBlueWorld + from .rom import PokemonRedProcedurePatch, PokemonBlueProcedurePatch + -def set_mon_palettes(world, random, data): +def set_mon_palettes(world: "PokemonRedBlueWorld", patch: "PokemonRedProcedurePatch | PokemonBlueProcedurePatch"): if world.options.randomize_pokemon_palettes == "vanilla": return pallet_map = { @@ -31,12 +39,9 @@ def set_mon_palettes(world, random, data): poke_data.evolves_from and poke_data.evolves_from[mon] != "Eevee"): pallet = palettes[-1] else: # completely_random or follow_evolutions and it is not an evolved form (except eeveelutions) - pallet = random.choice(list(pallet_map.values())) + pallet = world.random.choice(list(pallet_map.values())) palettes.append(pallet) - address = rom_addresses["Mon_Palettes"] - for pallet in palettes: - data[address] = pallet - address += 1 + patch.write_token(APTokenTypes.WRITE, rom_addresses["Mon_Palettes"], bytes(palettes)) def choose_forced_type(chances, random): @@ -253,9 +258,9 @@ def process_pokemon_data(self): mon_data[f"start move {i}"] = learnsets[mon].pop(0) if self.options.randomize_pokemon_catch_rates: - mon_data["catch rate"] = self.random.randint(self.options.minimum_catch_rate, 255) + mon_data["catch rate"] = self.random.randint(self.options.minimum_catch_rate.value, 255) else: - mon_data["catch rate"] = max(self.options.minimum_catch_rate, mon_data["catch rate"]) + mon_data["catch rate"] = max(self.options.minimum_catch_rate.value, mon_data["catch rate"]) def roll_tm_compat(roll_move): if self.local_move_data[roll_move]["type"] in [mon_data["type1"], mon_data["type2"]]: diff --git a/worlds/pokemon_rb/rock_tunnel.py b/worlds/pokemon_rb/rock_tunnel.py index 46b2be3040dc..83b59255c611 100644 --- a/worlds/pokemon_rb/rock_tunnel.py +++ b/worlds/pokemon_rb/rock_tunnel.py @@ -1,5 +1,55 @@ +import random +import typing + +from worlds.Files import APTokenTypes + from .rom_addresses import rom_addresses +if typing.TYPE_CHECKING: + from .rom import PokemonBlueProcedurePatch, PokemonRedProcedurePatch + + +layout1F = [ + [20, 22, 32, 34, 20, 25, 22, 32, 34, 20, 25, 25, 25, 22, 20, 25, 22, 2, 2, 2], + [24, 26, 40, 1, 24, 25, 26, 62, 1, 28, 29, 29, 29, 30, 28, 29, 30, 1, 40, 2], + [28, 30, 1, 1, 28, 29, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 23], + [23, 1, 1, 1, 1, 1, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 31], + [31, 1, 1, 1, 1, 1, 31, 32, 34, 2, 1, 1, 2, 32, 34, 32, 34, 1, 1, 23], + [23, 1, 1, 23, 1, 1, 23, 1, 40, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 31], + [31, 1, 1, 31, 1, 1, 31, 1, 1, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23], + [23, 1, 1, 23, 1, 1, 1, 1, 1, 2, 32, 34, 32, 34, 32, 34, 32, 34, 2, 31], + [31, 1, 1, 31, 1, 1, 1, 1, 1, 1, 1, 23, 1, 1, 1, 23, 1, 1, 40, 23], + [23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 31, 1, 1, 1, 31, 1, 1, 1, 31], + [31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 1, 1, 1, 23, 1, 1, 1, 23], + [23, 32, 34, 32, 34, 32, 34, 32, 34, 32, 34, 31, 1, 1, 1, 31, 1, 1, 1, 31], + [31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 1, 1, 1, 23], + [ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 31, 1, 1, 1, 31], + [20, 21, 21, 21, 22, 42, 1, 1, 1, 1, 20, 21, 22, 1, 1, 1, 1, 1, 1, 23], + [24, 25, 25, 25, 26, 1, 1, 1, 1, 1, 24, 25, 26, 1, 1, 1, 1, 1, 1, 31], + [24, 25, 25, 25, 26, 1, 1, 62, 1, 1, 24, 25, 26, 20, 21, 21, 21, 21, 21, 22], + [28, 29, 29, 29, 30, 78, 81, 82, 77, 78, 28, 29, 30, 28, 29, 29, 29, 29, 29, 30], +] +layout2F = [ + [23, 2, 32, 34, 32, 34, 32, 34, 32, 34, 32, 34, 32, 34, 32, 34, 32, 34, 32, 34], + [31, 62, 1, 23, 1, 1, 23, 1, 1, 1, 1, 1, 23, 62, 1, 1, 1, 1, 1, 2], + [23, 1, 1, 31, 1, 1, 31, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 23], + [31, 1, 1, 23, 1, 1, 23, 1, 1, 23, 1, 1, 23, 1, 1, 23, 23, 1, 1, 31], + [23, 1, 1, 31, 1, 1, 31, 1, 1, 31, 2, 2, 31, 1, 1, 31, 31, 1, 1, 23], + [31, 1, 1, 1, 1, 1, 23, 1, 1, 1, 1, 62, 23, 1, 1, 1, 1, 1, 1, 31], + [23, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 23], + [31, 1, 1, 23, 1, 1, 1, 1, 1, 23, 32, 34, 32, 34, 32, 34, 1, 1, 1, 31], + [23, 1, 1, 31, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23], + [31, 1, 1, 23, 1, 1, 2, 1, 1, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 31], + [23, 1, 1, 31, 1, 1, 2, 1, 1, 31, 1, 1, 1, 32, 34, 32, 34, 32, 34, 23], + [31, 2, 2, 2, 1, 1, 32, 34, 32, 34, 1, 1, 1, 23, 1, 1, 1, 1, 1, 31], + [23, 1, 1, 1, 1, 1, 23, 1, 1, 1, 1, 1, 1, 31, 1, 1, 62, 1, 1, 23], + [31, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 23, 1, 1, 1, 1, 1, 31], + [23, 32, 34, 32, 34, 32, 34, 1, 1, 32, 34, 32, 34, 31, 1, 1, 1, 1, 1, 23], + [31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 31], + [ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23], + [32, 34, 32, 34, 32, 34, 32, 34, 32, 34, 32, 34, 32, 34, 32, 34, 32, 34, 2, 31] +] + disallowed1F = [[2, 2], [3, 2], [1, 8], [2, 8], [7, 7], [8, 7], [10, 4], [11, 4], [11, 12], [11, 13], [16, 10], [17, 10], [18, 10], [16, 12], [17, 12], [18, 12]] disallowed2F = [[16, 2], [17, 2], [18, 2], [15, 5], [15, 6], [10, 10], [11, 10], [12, 10], [7, 14], [8, 14], [1, 15], @@ -7,29 +57,12 @@ [11, 1]] -def randomize_rock_tunnel(data, random): - +def randomize_rock_tunnel(patch: "PokemonRedProcedurePatch | PokemonBlueProcedurePatch", random: random.Random): seed = random.randint(0, 999999999999999999) random.seed(seed) - map1f = [] - map2f = [] - - address = rom_addresses["Map_Rock_Tunnel1F"] - for y in range(0, 18): - row = [] - for x in range(0, 20): - row.append(data[address]) - address += 1 - map1f.append(row) - - address = rom_addresses["Map_Rock_TunnelB1F"] - for y in range(0, 18): - row = [] - for x in range(0, 20): - row.append(data[address]) - address += 1 - map2f.append(row) + map1f = [row.copy() for row in layout1F] + map2f = [row.copy() for row in layout2F] current_map = map1f @@ -305,14 +338,6 @@ def check_addable_block(check_map, disallowed): current_map = map2f check_addable_block(map2f, disallowed2F) - address = rom_addresses["Map_Rock_Tunnel1F"] - for y in map1f: - for x in y: - data[address] = x - address += 1 - address = rom_addresses["Map_Rock_TunnelB1F"] - for y in map2f: - for x in y: - data[address] = x - address += 1 - return seed \ No newline at end of file + patch.write_token(APTokenTypes.WRITE, rom_addresses["Map_Rock_Tunnel1F"], bytes([b for row in map1f for b in row])) + patch.write_token(APTokenTypes.WRITE, rom_addresses["Map_Rock_TunnelB1F"], bytes([b for row in map2f for b in row])) + return seed diff --git a/worlds/pokemon_rb/rom.py b/worlds/pokemon_rb/rom.py index 5ebd204c9abc..e49da82cc4f6 100644 --- a/worlds/pokemon_rb/rom.py +++ b/worlds/pokemon_rb/rom.py @@ -1,21 +1,66 @@ import os -import hashlib -import Utils -import bsdiff4 import pkgutil -from worlds.Files import APDeltaPatch -from .text import encode_text +import typing + +import Utils +from worlds.Files import APProcedurePatch, APTokenMixin, APTokenTypes + +from . import poke_data from .items import item_table +from .text import encode_text from .pokemon import set_mon_palettes +from .regions import PokemonRBWarp, map_ids, town_map_coords from .rock_tunnel import randomize_rock_tunnel from .rom_addresses import rom_addresses -from .regions import PokemonRBWarp, map_ids, town_map_coords -from . import poke_data +if typing.TYPE_CHECKING: + from . import PokemonRedBlueWorld + + +class PokemonRedProcedurePatch(APProcedurePatch, APTokenMixin): + game = "Pokemon Red and Blue" + hash = "3d45c1ee9abd5738df46d2bdda8b57dc" + patch_file_ending = ".apred" + result_file_ending = ".gb" + + procedure = [ + ("apply_bsdiff4", ["base_patch.bsdiff4"]), + ("apply_tokens", ["token_data.bin"]), + ] + + @classmethod + def get_source_data(cls) -> bytes: + from . import PokemonRedBlueWorld + with open(PokemonRedBlueWorld.settings.red_rom_file, "rb") as infile: + base_rom_bytes = bytes(infile.read()) + + return base_rom_bytes + + +class PokemonBlueProcedurePatch(APProcedurePatch, APTokenMixin): + game = "Pokemon Red and Blue" + hash = "50927e843568814f7ed45ec4f944bd8b" + patch_file_ending = ".apblue" + result_file_ending = ".gb" + + procedure = [ + ("apply_bsdiff4", ["base_patch.bsdiff4"]), + ("apply_tokens", ["token_data.bin"]), + ] + + @classmethod + def get_source_data(cls) -> bytes: + from . import PokemonRedBlueWorld + with open(PokemonRedBlueWorld.settings.blue_rom_file, "rb") as infile: + base_rom_bytes = bytes(infile.read()) + + return base_rom_bytes -def write_quizzes(world, data, random): - def get_quiz(q, a): +def write_quizzes(world: "PokemonRedBlueWorld", patch: PokemonBlueProcedurePatch | PokemonRedProcedurePatch): + random = world.random + + def get_quiz(q: int, a: int): if q == 0: r = random.randint(0, 3) if r == 0: @@ -122,13 +167,13 @@ def get_quiz(q, a): elif q2 == 1: if a: state = random.choice( - ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', - 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', - 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', - 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Jersey', 'New Mexico', - 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', - 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', - 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']) + ["Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", + "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", + "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", + "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Jersey", "New Mexico", + "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", + "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", + "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"]) else: state = "New Hampshire" return encode_text( @@ -209,7 +254,7 @@ def get_quiz(q, a): return encode_text(f"{type1} deals{eff}damage to{type2} type?") elif q == 14: fossil_level = world.multiworld.get_location("Fossil Level - Trainer Parties", - world.player).party_data[0]['level'] + world.player).party_data[0]["level"] if not a: fossil_level += random.choice((-5, 5)) return encode_text(f"Fossil #MONrevive at level{fossil_level}?") @@ -224,46 +269,49 @@ def get_quiz(q, a): return encode_text(f"According toMonash Uni.,{fodmap} {are_is}considered highin FODMAPs?") answers = [random.randint(0, 1) for _ in range(6)] - questions = random.sample((range(0, 16)), 6) - - question_texts = [] + question_texts: list[bytearray] = [] for i, question in enumerate(questions): question_texts.append(get_quiz(question, answers[i])) for i, quiz in enumerate(["A", "B", "C", "D", "E", "F"]): - data[rom_addresses[f"Quiz_Answer_{quiz}"]] = int(not answers[i]) << 4 | (i + 1) - write_bytes(data, question_texts[i], rom_addresses[f"Text_Quiz_{quiz}"]) + patch.write_token(APTokenTypes.WRITE, rom_addresses[f"Quiz_Answer_{quiz}"], bytes([int(not answers[i]) << 4 | (i + 1)])) + patch.write_token(APTokenTypes.WRITE, rom_addresses[f"Text_Quiz_{quiz}"], bytes(question_texts[i])) -def generate_output(world, output_directory: str): - random = world.random +def generate_output(world: "PokemonRedBlueWorld", output_directory: str): game_version = world.options.game_version.current_key - data = bytes(get_base_rom_bytes(game_version)) - base_patch = pkgutil.get_data(__name__, f'basepatch_{game_version}.bsdiff4') + patch_type = PokemonBlueProcedurePatch if game_version == "blue" else PokemonRedProcedurePatch + patch = patch_type(player=world.player, player_name=world.player_name) + patch.write_file("base_patch.bsdiff4", pkgutil.get_data(__name__, f"basepatch_{game_version}.bsdiff4")) - data = bytearray(bsdiff4.patch(data, base_patch)) + def write_bytes(address: int, data: typing.Sequence[int] | int): + if isinstance(data, int): + data = bytes([data]) + else: + data = bytes(data) - basemd5 = hashlib.md5() - basemd5.update(data) + patch.write_token(APTokenTypes.WRITE, address, data) pallet_connections = {entrance: world.multiworld.get_entrance(f"Pallet Town to {entrance}", - world.player).connected_region.name for - entrance in ["Player's House 1F", "Oak's Lab", - "Rival's House"]} + world.player).connected_region.name + for entrance in ["Player's House 1F", "Oak's Lab", "Rival's House"]} paths = None + if pallet_connections["Player's House 1F"] == "Oak's Lab": - paths = ((0x00, 4, 0x80, 5, 0x40, 1, 0xE0, 1, 0xFF), (0x40, 2, 0x20, 5, 0x80, 5, 0xFF)) + paths = (bytes([0x00, 4, 0x80, 5, 0x40, 1, 0xE0, 1, 0xFF]), bytes([0x40, 2, 0x20, 5, 0x80, 5, 0xFF])) elif pallet_connections["Rival's House"] == "Oak's Lab": - paths = ((0x00, 4, 0xC0, 3, 0x40, 1, 0xE0, 1, 0xFF), (0x40, 2, 0x10, 3, 0x80, 5, 0xFF)) + paths = (bytes([0x00, 4, 0xC0, 3, 0x40, 1, 0xE0, 1, 0xFF]), bytes([0x40, 2, 0x10, 3, 0x80, 5, 0xFF])) + if paths: - write_bytes(data, paths[0], rom_addresses["Path_Pallet_Oak"]) - write_bytes(data, paths[1], rom_addresses["Path_Pallet_Player"]) + write_bytes(rom_addresses["Path_Pallet_Oak"], paths[0]) + write_bytes(rom_addresses["Path_Pallet_Player"], paths[1]) + if pallet_connections["Rival's House"] == "Player's House 1F": - write_bytes(data, [0x2F, 0xC7, 0x06, 0x0D, 0x00, 0x01], rom_addresses["Pallet_Fly_Coords"]) + write_bytes(rom_addresses["Pallet_Fly_Coords"], [0x2F, 0xC7, 0x06, 0x0D, 0x00, 0x01]) elif pallet_connections["Oak's Lab"] == "Player's House 1F": - write_bytes(data, [0x5F, 0xC7, 0x0C, 0x0C, 0x00, 0x00], rom_addresses["Pallet_Fly_Coords"]) + write_bytes(rom_addresses["Pallet_Fly_Coords"], [0x5F, 0xC7, 0x0C, 0x0C, 0x00, 0x00]) for region in world.multiworld.get_regions(world.player): for entrance in region.exits: @@ -281,16 +329,18 @@ def generate_output(world, output_directory: str): while i > len(warp_to_ids) - 1: i -= len(warp_to_ids) connected_map_name = entrance.connected_region.name.split("-")[0] - data[address] = 0 if "Elevator" in connected_map_name else warp_to_ids[i] - data[address + 1] = map_ids[connected_map_name] + write_bytes(address, [ + 0 if "Elevator" in connected_map_name else warp_to_ids[i], + map_ids[connected_map_name] + ]) if world.options.door_shuffle == "simple": for (entrance, _, _, map_coords_entries, map_name, _) in town_map_coords.values(): destination = world.multiworld.get_entrance(entrance, world.player).connected_region.name (_, x, y, _, _, map_order_entry) = town_map_coords[destination] for map_coord_entry in map_coords_entries: - data[rom_addresses["Town_Map_Coords"] + (map_coord_entry * 4) + 1] = (y << 4) | x - data[rom_addresses["Town_Map_Order"] + map_order_entry] = map_ids[map_name] + write_bytes(rom_addresses["Town_Map_Coords"] + (map_coord_entry * 4) + 1, (y << 4) | x) + write_bytes(rom_addresses["Town_Map_Order"] + map_order_entry, map_ids[map_name]) if not world.options.key_items_only: for i, gym_leader in enumerate(("Pewter Gym - Brock TM", "Cerulean Gym - Misty TM", @@ -302,13 +352,13 @@ def generate_output(world, output_directory: str): try: tm = int(item_name[2:4]) move = poke_data.moves[world.local_tms[tm - 1]]["id"] - data[rom_addresses["Gym_Leader_Moves"] + (2 * i)] = move + write_bytes(rom_addresses["Gym_Leader_Moves"] + (2 * i), move) except KeyError: pass def set_trade_mon(address, loc): mon = world.multiworld.get_location(loc, world.player).item.name - data[rom_addresses[address]] = poke_data.pokemon_data[mon]["id"] + write_bytes(rom_addresses[address], poke_data.pokemon_data[mon]["id"]) world.trade_mons[address] = mon if game_version == "red": @@ -325,141 +375,139 @@ def set_trade_mon(address, loc): set_trade_mon("Trade_Doris", "Cerulean Cave 1F - Wild Pokemon - 9") set_trade_mon("Trade_Crinkles", "Route 12 - Wild Pokemon - 4") - data[rom_addresses['Fly_Location']] = world.fly_map_code - data[rom_addresses['Map_Fly_Location']] = world.town_map_fly_map_code + write_bytes(rom_addresses["Fly_Location"], world.fly_map_code) + write_bytes(rom_addresses["Map_Fly_Location"], world.town_map_fly_map_code) if world.options.fix_combat_bugs: - data[rom_addresses["Option_Fix_Combat_Bugs"]] = 1 - data[rom_addresses["Option_Fix_Combat_Bugs_Focus_Energy"]] = 0x28 # jr z - data[rom_addresses["Option_Fix_Combat_Bugs_HP_Drain_Dream_Eater"]] = 0x1A # ld a, (de) - data[rom_addresses["Option_Fix_Combat_Bugs_PP_Restore"]] = 0xe6 # and a, direct - data[rom_addresses["Option_Fix_Combat_Bugs_PP_Restore"] + 1] = 0b0011111 - data[rom_addresses["Option_Fix_Combat_Bugs_Struggle"]] = 0xe6 # and a, direct - data[rom_addresses["Option_Fix_Combat_Bugs_Struggle"] + 1] = 0x3f - data[rom_addresses["Option_Fix_Combat_Bugs_Dig_Fly"]] = 0b10001100 - data[rom_addresses["Option_Fix_Combat_Bugs_Heal_Effect"]] = 0x20 # jr nz, - data[rom_addresses["Option_Fix_Combat_Bugs_Heal_Effect"] + 1] = 5 # 5 bytes ahead - data[rom_addresses["Option_Fix_Combat_Bugs_Heal_Stat_Modifiers"]] = 1 + write_bytes(rom_addresses["Option_Fix_Combat_Bugs"], 1) + write_bytes(rom_addresses["Option_Fix_Combat_Bugs_Focus_Energy"], 0x28) # jr z + write_bytes(rom_addresses["Option_Fix_Combat_Bugs_HP_Drain_Dream_Eater"], 0x1A) # ld a, (de) + write_bytes(rom_addresses["Option_Fix_Combat_Bugs_PP_Restore"], 0xe6) # and a, direct + write_bytes(rom_addresses["Option_Fix_Combat_Bugs_PP_Restore"] + 1, 0b0011111) + write_bytes(rom_addresses["Option_Fix_Combat_Bugs_Struggle"], 0xe6) # and a, direct + write_bytes(rom_addresses["Option_Fix_Combat_Bugs_Struggle"] + 1, 0x3f) + write_bytes(rom_addresses["Option_Fix_Combat_Bugs_Dig_Fly"], 0b10001100) + write_bytes(rom_addresses["Option_Fix_Combat_Bugs_Heal_Effect"], 0x20) # jr nz, + write_bytes(rom_addresses["Option_Fix_Combat_Bugs_Heal_Effect"] + 1, 5) # 5 bytes ahead + write_bytes(rom_addresses["Option_Fix_Combat_Bugs_Heal_Stat_Modifiers"], 1) if world.options.poke_doll_skip == "in_logic": - data[rom_addresses["Option_Silph_Scope_Skip"]] = 0x00 # nop - data[rom_addresses["Option_Silph_Scope_Skip"] + 1] = 0x00 # nop - data[rom_addresses["Option_Silph_Scope_Skip"] + 2] = 0x00 # nop + write_bytes(rom_addresses["Option_Silph_Scope_Skip"], 0x00) # nop + write_bytes(rom_addresses["Option_Silph_Scope_Skip"] + 1, 0x00) # nop + write_bytes(rom_addresses["Option_Silph_Scope_Skip"] + 2, 0x00) # nop if world.options.bicycle_gate_skips == "patched": - data[rom_addresses["Option_Route_16_Gate_Fix"]] = 0x00 # nop - data[rom_addresses["Option_Route_16_Gate_Fix"] + 1] = 0x00 # nop - data[rom_addresses["Option_Route_18_Gate_Fix"]] = 0x00 # nop - data[rom_addresses["Option_Route_18_Gate_Fix"] + 1] = 0x00 # nop + write_bytes(rom_addresses["Option_Route_16_Gate_Fix"], 0x00) # nop + write_bytes(rom_addresses["Option_Route_16_Gate_Fix"] + 1, 0x00) # nop + write_bytes(rom_addresses["Option_Route_18_Gate_Fix"], 0x00) # nop + write_bytes(rom_addresses["Option_Route_18_Gate_Fix"] + 1, 0x00) # nop if world.options.door_shuffle: - data[rom_addresses["Entrance_Shuffle_Fuji_Warp"]] = 1 # prevent warping to Fuji's House from Pokemon Tower 7F + write_bytes(rom_addresses["Entrance_Shuffle_Fuji_Warp"], 1) # prevent warping to Fuji's House from Pokemon Tower 7F if world.options.all_elevators_locked: - data[rom_addresses["Option_Locked_Elevator_Celadon"]] = 0x20 # jr nz - data[rom_addresses["Option_Locked_Elevator_Silph"]] = 0x20 # jr nz + write_bytes(rom_addresses["Option_Locked_Elevator_Celadon"], 0x20) # jr nz + write_bytes(rom_addresses["Option_Locked_Elevator_Silph"], 0x20) # jr nz if world.options.tea: - data[rom_addresses["Option_Tea"]] = 1 - data[rom_addresses["Guard_Drink_List"]] = 0x54 - data[rom_addresses["Guard_Drink_List"] + 1] = 0 - data[rom_addresses["Guard_Drink_List"] + 2] = 0 - write_bytes(data, encode_text("Gee, I have theworst caffeineheadache though." - "Oh wait there,the road's closed."), - rom_addresses["Text_Saffron_Gate"]) + write_bytes(rom_addresses["Option_Tea"], 1) + write_bytes(rom_addresses["Guard_Drink_List"], 0x54) + write_bytes(rom_addresses["Guard_Drink_List"] + 1, 0) + write_bytes(rom_addresses["Guard_Drink_List"] + 2, 0) + write_bytes(rom_addresses["Text_Saffron_Gate"], + encode_text("Gee, I have theworst caffeineheadache though." + "Oh wait there,the road's closed.")) - data[rom_addresses["Tea_Key_Item_A"]] = 0x28 # jr .z - data[rom_addresses["Tea_Key_Item_B"]] = 0x28 # jr .z - data[rom_addresses["Tea_Key_Item_C"]] = 0x28 # jr .z + write_bytes(rom_addresses["Tea_Key_Item_A"], 0x28) # jr .z + write_bytes(rom_addresses["Tea_Key_Item_B"], 0x28) # jr .z + write_bytes(rom_addresses["Tea_Key_Item_C"], 0x28) # jr .z - data[rom_addresses["Fossils_Needed_For_Second_Item"]] = ( - world.options.second_fossil_check_condition.value) + write_bytes(rom_addresses["Fossils_Needed_For_Second_Item"], world.options.second_fossil_check_condition.value) - data[rom_addresses["Option_Lose_Money"]] = int(not world.options.lose_money_on_blackout.value) + write_bytes(rom_addresses["Option_Lose_Money"], int(not world.options.lose_money_on_blackout.value)) if world.options.extra_key_items: - data[rom_addresses['Option_Extra_Key_Items_A']] = 1 - data[rom_addresses['Option_Extra_Key_Items_B']] = 1 - data[rom_addresses['Option_Extra_Key_Items_C']] = 1 - data[rom_addresses['Option_Extra_Key_Items_D']] = 1 - data[rom_addresses["Option_Split_Card_Key"]] = world.options.split_card_key.value - data[rom_addresses["Option_Blind_Trainers"]] = round(world.options.blind_trainers.value * 2.55) - data[rom_addresses["Option_Cerulean_Cave_Badges"]] = world.options.cerulean_cave_badges_condition.value - data[rom_addresses["Option_Cerulean_Cave_Key_Items"]] = world.options.cerulean_cave_key_items_condition.total - write_bytes(data, encode_text(str(world.options.cerulean_cave_badges_condition.value)), rom_addresses["Text_Cerulean_Cave_Badges"]) - write_bytes(data, encode_text(str(world.options.cerulean_cave_key_items_condition.total) + " key items."), rom_addresses["Text_Cerulean_Cave_Key_Items"]) - data[rom_addresses['Option_Encounter_Minimum_Steps']] = world.options.minimum_steps_between_encounters.value - data[rom_addresses['Option_Route23_Badges']] = world.options.victory_road_condition.value - data[rom_addresses['Option_Victory_Road_Badges']] = world.options.route_22_gate_condition.value - data[rom_addresses['Option_Elite_Four_Pokedex']] = world.options.elite_four_pokedex_condition.total - data[rom_addresses['Option_Elite_Four_Key_Items']] = world.options.elite_four_key_items_condition.total - data[rom_addresses['Option_Elite_Four_Badges']] = world.options.elite_four_badges_condition.value - write_bytes(data, encode_text(str(world.options.elite_four_badges_condition.value)), rom_addresses["Text_Elite_Four_Badges"]) - write_bytes(data, encode_text(str(world.options.elite_four_key_items_condition.total) + " key items, and"), rom_addresses["Text_Elite_Four_Key_Items"]) - write_bytes(data, encode_text(str(world.options.elite_four_pokedex_condition.total) + " #MON"), rom_addresses["Text_Elite_Four_Pokedex"]) - write_bytes(data, encode_text(str(world.total_key_items), length=2), rom_addresses["Trainer_Screen_Total_Key_Items"]) - - data[rom_addresses['Option_Viridian_Gym_Badges']] = world.options.viridian_gym_condition.value - data[rom_addresses['Option_EXP_Modifier']] = world.options.exp_modifier.value + write_bytes(rom_addresses["Option_Extra_Key_Items_A"], 1) + write_bytes(rom_addresses["Option_Extra_Key_Items_B"], 1) + write_bytes(rom_addresses["Option_Extra_Key_Items_C"], 1) + write_bytes(rom_addresses["Option_Extra_Key_Items_D"], 1) + write_bytes(rom_addresses["Option_Split_Card_Key"], world.options.split_card_key.value) + write_bytes(rom_addresses["Option_Blind_Trainers"], round(world.options.blind_trainers.value * 2.55)) + write_bytes(rom_addresses["Option_Cerulean_Cave_Badges"], world.options.cerulean_cave_badges_condition.value) + write_bytes(rom_addresses["Option_Cerulean_Cave_Key_Items"], world.options.cerulean_cave_key_items_condition.total) + write_bytes(rom_addresses["Text_Cerulean_Cave_Badges"], encode_text(str(world.options.cerulean_cave_badges_condition.value))) + write_bytes(rom_addresses["Text_Cerulean_Cave_Key_Items"], encode_text(str(world.options.cerulean_cave_key_items_condition.total) + " key items.")) + write_bytes(rom_addresses["Option_Encounter_Minimum_Steps"], world.options.minimum_steps_between_encounters.value) + write_bytes(rom_addresses["Option_Route23_Badges"], world.options.victory_road_condition.value) + write_bytes(rom_addresses["Option_Victory_Road_Badges"], world.options.route_22_gate_condition.value) + write_bytes(rom_addresses["Option_Elite_Four_Pokedex"], world.options.elite_four_pokedex_condition.total) + write_bytes(rom_addresses["Option_Elite_Four_Key_Items"], world.options.elite_four_key_items_condition.total) + write_bytes(rom_addresses["Option_Elite_Four_Badges"], world.options.elite_four_badges_condition.value) + write_bytes(rom_addresses["Text_Elite_Four_Badges"], encode_text(str(world.options.elite_four_badges_condition.value))) + write_bytes(rom_addresses["Text_Elite_Four_Key_Items"], encode_text(str(world.options.elite_four_key_items_condition.total) + " key items, and")) + write_bytes(rom_addresses["Text_Elite_Four_Pokedex"], encode_text(str(world.options.elite_four_pokedex_condition.total) + " #MON")) + write_bytes(rom_addresses["Trainer_Screen_Total_Key_Items"], encode_text(str(world.total_key_items), length=2)) + + write_bytes(rom_addresses["Option_Viridian_Gym_Badges"], world.options.viridian_gym_condition.value) + write_bytes(rom_addresses["Option_EXP_Modifier"], world.options.exp_modifier.value) if not world.options.require_item_finder: - data[rom_addresses['Option_Itemfinder']] = 0 # nop + write_bytes(rom_addresses["Option_Itemfinder"], 0) # nop if world.options.extra_strength_boulders: for i in range(0, 3): - data[rom_addresses['Option_Boulders'] + (i * 3)] = 0x15 + write_bytes(rom_addresses["Option_Boulders"] + (i * 3), 0x15) if world.options.extra_key_items: for i in range(0, 4): - data[rom_addresses['Option_Rock_Tunnel_Extra_Items'] + (i * 3)] = 0x15 + write_bytes(rom_addresses["Option_Rock_Tunnel_Extra_Items"] + (i * 3), 0x15) if world.options.old_man == "open_viridian_city": - data[rom_addresses['Option_Old_Man']] = 0x11 - data[rom_addresses['Option_Old_Man_Lying']] = 0x15 - data[rom_addresses['Option_Route3_Guard_B']] = world.options.route_3_condition.value + write_bytes(rom_addresses["Option_Old_Man"], 0x11) + write_bytes(rom_addresses["Option_Old_Man_Lying"], 0x15) + write_bytes(rom_addresses["Option_Route3_Guard_B"], world.options.route_3_condition.value) if world.options.route_3_condition == "open": - data[rom_addresses['Option_Route3_Guard_A']] = 0x11 + write_bytes(rom_addresses["Option_Route3_Guard_A"], 0x11) if not world.options.robbed_house_officer: - data[rom_addresses['Option_Trashed_House_Guard_A']] = 0x15 - data[rom_addresses['Option_Trashed_House_Guard_B']] = 0x11 + write_bytes(rom_addresses["Option_Trashed_House_Guard_A"], 0x15) + write_bytes(rom_addresses["Option_Trashed_House_Guard_B"], 0x11) if world.options.require_pokedex: - data[rom_addresses["Require_Pokedex_A"]] = 1 - data[rom_addresses["Require_Pokedex_B"]] = 1 - data[rom_addresses["Require_Pokedex_C"]] = 1 + write_bytes(rom_addresses["Require_Pokedex_A"], 1) + write_bytes(rom_addresses["Require_Pokedex_B"], 1) + write_bytes(rom_addresses["Require_Pokedex_C"], 1) else: - data[rom_addresses["Require_Pokedex_D"]] = 0x18 # jr + write_bytes(rom_addresses["Require_Pokedex_D"], 0x18) # jr if world.options.dexsanity: - data[rom_addresses["Option_Dexsanity_A"]] = 1 - data[rom_addresses["Option_Dexsanity_B"]] = 1 + write_bytes(rom_addresses["Option_Dexsanity_A"], 1) + write_bytes(rom_addresses["Option_Dexsanity_B"], 1) if world.options.all_pokemon_seen: - data[rom_addresses["Option_Pokedex_Seen"]] = 1 + write_bytes(rom_addresses["Option_Pokedex_Seen"], 1) money = str(world.options.starting_money.value).zfill(6) - data[rom_addresses["Starting_Money_High"]] = int(money[:2], 16) - data[rom_addresses["Starting_Money_Middle"]] = int(money[2:4], 16) - data[rom_addresses["Starting_Money_Low"]] = int(money[4:], 16) - data[rom_addresses["Text_Badges_Needed_Viridian_Gym"]] = encode_text( - str(world.options.viridian_gym_condition.value))[0] - data[rom_addresses["Text_Rt23_Badges_A"]] = encode_text( - str(world.options.victory_road_condition.value))[0] - data[rom_addresses["Text_Rt23_Badges_B"]] = encode_text( - str(world.options.victory_road_condition.value))[0] - data[rom_addresses["Text_Rt23_Badges_C"]] = encode_text( - str(world.options.victory_road_condition.value))[0] - data[rom_addresses["Text_Rt23_Badges_D"]] = encode_text( - str(world.options.victory_road_condition.value))[0] - data[rom_addresses["Text_Badges_Needed"]] = encode_text( - str(world.options.elite_four_badges_condition.value))[0] - write_bytes(data, encode_text( - " ".join(world.multiworld.get_location("Route 4 Pokemon Center - Pokemon For Sale", world.player).item.name.upper().split()[1:])), - rom_addresses["Text_Magikarp_Salesman"]) + write_bytes(rom_addresses["Starting_Money_High"], int(money[:2], 16)) + write_bytes(rom_addresses["Starting_Money_Middle"], int(money[2:4], 16)) + write_bytes(rom_addresses["Starting_Money_Low"], int(money[4:], 16)) + write_bytes(rom_addresses["Text_Badges_Needed_Viridian_Gym"], + encode_text(str(world.options.viridian_gym_condition.value))[0]) + write_bytes(rom_addresses["Text_Rt23_Badges_A"], + encode_text(str(world.options.victory_road_condition.value))[0]) + write_bytes(rom_addresses["Text_Rt23_Badges_B"], + encode_text(str(world.options.victory_road_condition.value))[0]) + write_bytes(rom_addresses["Text_Rt23_Badges_C"], + encode_text(str(world.options.victory_road_condition.value))[0]) + write_bytes(rom_addresses["Text_Rt23_Badges_D"], + encode_text(str(world.options.victory_road_condition.value))[0]) + write_bytes(rom_addresses["Text_Badges_Needed"], + encode_text(str(world.options.elite_four_badges_condition.value))[0]) + write_bytes(rom_addresses["Text_Magikarp_Salesman"], + encode_text(" ".join(world.multiworld.get_location("Route 4 Pokemon Center - Pokemon For Sale", world.player).item.name.upper().split()[1:]))) if world.options.badges_needed_for_hm_moves.value == 0: for hm_move in poke_data.hm_moves: - write_bytes(data, bytearray([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), - rom_addresses["HM_" + hm_move + "_Badge_a"]) + write_bytes(rom_addresses["HM_" + hm_move + "_Badge_a"], [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) elif world.extra_badges: written_badges = {} + badge_codes = {"Boulder Badge": 0x47, "Cascade Badge": 0x4F, + "Thunder Badge": 0x57, "Rainbow Badge": 0x5F, + "Soul Badge": 0x67, "Marsh Badge": 0x6F, + "Volcano Badge": 0x77, "Earth Badge": 0x7F} for hm_move, badge in world.extra_badges.items(): - data[rom_addresses["HM_" + hm_move + "_Badge_b"]] = {"Boulder Badge": 0x47, "Cascade Badge": 0x4F, - "Thunder Badge": 0x57, "Rainbow Badge": 0x5F, - "Soul Badge": 0x67, "Marsh Badge": 0x6F, - "Volcano Badge": 0x77, "Earth Badge": 0x7F}[badge] + write_bytes(rom_addresses["HM_" + hm_move + "_Badge_b"], badge_codes[badge]) move_text = hm_move if badge not in ["Marsh Badge", "Volcano Badge", "Earth Badge"]: move_text = ", " + move_text @@ -467,62 +515,58 @@ def set_trade_mon(address, loc): if badge in written_badges: rom_address += len(written_badges[badge]) move_text = ", " + move_text - write_bytes(data, encode_text(move_text.upper()), rom_address) + write_bytes(rom_address, encode_text(move_text.upper())) written_badges[badge] = move_text for badge in ["Marsh Badge", "Volcano Badge", "Earth Badge"]: if badge not in written_badges: - write_bytes(data, encode_text("Nothing"), rom_addresses["Badge_Text_" + badge.replace(" ", "_")]) + write_bytes(rom_addresses["Badge_Text_" + badge.replace(" ", "_")], encode_text("Nothing")) type_loc = rom_addresses["Type_Chart"] for matchup in world.type_chart: if matchup[2] != 10: # don't needlessly divide damage by 10 and multiply by 10 - data[type_loc] = poke_data.type_ids[matchup[0]] - data[type_loc + 1] = poke_data.type_ids[matchup[1]] - data[type_loc + 2] = matchup[2] + write_bytes(type_loc, [poke_data.type_ids[matchup[0]], poke_data.type_ids[matchup[1]], matchup[2]]) type_loc += 3 - data[type_loc] = 0xFF - data[type_loc + 1] = 0xFF - data[type_loc + 2] = 0xFF + write_bytes(type_loc, b"\xFF\xFF\xFF") if world.options.normalize_encounter_chances.value: chances = [25, 51, 77, 103, 129, 155, 180, 205, 230, 255] for i, chance in enumerate(chances): - data[rom_addresses['Encounter_Chances'] + (i * 2)] = chance + write_bytes(rom_addresses["Encounter_Chances"] + (i * 2), chance) for mon, mon_data in world.local_poke_data.items(): if mon == "Mew": address = rom_addresses["Base_Stats_Mew"] else: address = rom_addresses["Base_Stats"] + (28 * (mon_data["dex"] - 1)) - data[address + 1] = world.local_poke_data[mon]["hp"] - data[address + 2] = world.local_poke_data[mon]["atk"] - data[address + 3] = world.local_poke_data[mon]["def"] - data[address + 4] = world.local_poke_data[mon]["spd"] - data[address + 5] = world.local_poke_data[mon]["spc"] - data[address + 6] = poke_data.type_ids[world.local_poke_data[mon]["type1"]] - data[address + 7] = poke_data.type_ids[world.local_poke_data[mon]["type2"]] - data[address + 8] = world.local_poke_data[mon]["catch rate"] - data[address + 15] = poke_data.moves[world.local_poke_data[mon]["start move 1"]]["id"] - data[address + 16] = poke_data.moves[world.local_poke_data[mon]["start move 2"]]["id"] - data[address + 17] = poke_data.moves[world.local_poke_data[mon]["start move 3"]]["id"] - data[address + 18] = poke_data.moves[world.local_poke_data[mon]["start move 4"]]["id"] - write_bytes(data, world.local_poke_data[mon]["tms"], address + 20) + write_bytes(address + 1, world.local_poke_data[mon]["hp"]) + write_bytes(address + 2, world.local_poke_data[mon]["atk"]) + write_bytes(address + 3, world.local_poke_data[mon]["def"]) + write_bytes(address + 4, world.local_poke_data[mon]["spd"]) + write_bytes(address + 5, world.local_poke_data[mon]["spc"]) + write_bytes(address + 6, poke_data.type_ids[world.local_poke_data[mon]["type1"]]) + write_bytes(address + 7, poke_data.type_ids[world.local_poke_data[mon]["type2"]]) + write_bytes(address + 8, world.local_poke_data[mon]["catch rate"]) + write_bytes(address + 15, poke_data.moves[world.local_poke_data[mon]["start move 1"]]["id"]) + write_bytes(address + 16, poke_data.moves[world.local_poke_data[mon]["start move 2"]]["id"]) + write_bytes(address + 17, poke_data.moves[world.local_poke_data[mon]["start move 3"]]["id"]) + write_bytes(address + 18, poke_data.moves[world.local_poke_data[mon]["start move 4"]]["id"]) + write_bytes(address + 20, world.local_poke_data[mon]["tms"]) if mon in world.learnsets and world.learnsets[mon]: address = rom_addresses["Learnset_" + mon.replace(" ", "")] for i, move in enumerate(world.learnsets[mon]): - data[(address + 1) + i * 2] = poke_data.moves[move]["id"] + write_bytes((address + 1) + i * 2, poke_data.moves[move]["id"]) - data[rom_addresses["Option_Aide_Rt2"]] = world.options.oaks_aide_rt_2.value - data[rom_addresses["Option_Aide_Rt11"]] = world.options.oaks_aide_rt_11.value - data[rom_addresses["Option_Aide_Rt15"]] = world.options.oaks_aide_rt_15.value + write_bytes(rom_addresses["Option_Aide_Rt2"], world.options.oaks_aide_rt_2.value) + write_bytes(rom_addresses["Option_Aide_Rt11"], world.options.oaks_aide_rt_11.value) + write_bytes(rom_addresses["Option_Aide_Rt15"], world.options.oaks_aide_rt_15.value) if world.options.safari_zone_normal_battles.value == 1: - data[rom_addresses["Option_Safari_Zone_Battle_Type"]] = 255 + write_bytes(rom_addresses["Option_Safari_Zone_Battle_Type"], 255) if world.options.reusable_tms.value: - data[rom_addresses["Option_Reusable_TMs"]] = 0xC9 + write_bytes(rom_addresses["Option_Reusable_TMs"], 0xC9) - data[rom_addresses["Option_Always_Half_STAB"]] = int(not world.options.same_type_attack_bonus.value) + write_bytes(rom_addresses["Option_Always_Half_STAB"], int(not world.options.same_type_attack_bonus.value)) if world.options.better_shops: inventory = ["Poke Ball", "Great Ball", "Ultra Ball"] @@ -531,43 +575,45 @@ def set_trade_mon(address, loc): inventory += ["Potion", "Super Potion", "Hyper Potion", "Max Potion", "Full Restore", "Revive", "Antidote", "Awakening", "Burn Heal", "Ice Heal", "Paralyze Heal", "Full Heal", "Repel", "Super Repel", "Max Repel", "Escape Rope"] - shop_data = bytearray([0xFE, len(inventory)]) - shop_data += bytearray([item_table[item].id - 172000000 for item in inventory]) + shop_data = [0xFE, len(inventory)] + shop_data += [item_table[item].id - 172000000 for item in inventory] shop_data.append(0xFF) for shop in range(1, 11): - write_bytes(data, shop_data, rom_addresses[f"Shop{shop}"]) + write_bytes(rom_addresses[f"Shop{shop}"], shop_data) if world.options.stonesanity: - write_bytes(data, bytearray([0xFE, 1, item_table["Poke Doll"].id - 172000000, 0xFF]), rom_addresses[f"Shop_Stones"]) + write_bytes(rom_addresses["Shop_Stones"], [0xFE, 1, item_table["Poke Doll"].id - 172000000, 0xFF]) price = str(world.options.master_ball_price.value).zfill(6) - price = bytearray([int(price[:2], 16), int(price[2:4], 16), int(price[4:], 16)]) - write_bytes(data, price, rom_addresses["Price_Master_Ball"]) # Money values in Red and Blue are weird + price = [int(price[:2], 16), int(price[2:4], 16), int(price[4:], 16)] + write_bytes(rom_addresses["Price_Master_Ball"], price) # Money values in Red and Blue are weird - for item in reversed(world.multiworld.precollected_items[world.player]): - if data[rom_addresses["Start_Inventory"] + item.code - 172000000] < 255: - data[rom_addresses["Start_Inventory"] + item.code - 172000000] += 1 + from collections import Counter + start_inventory = Counter(item.code for item in reversed(world.multiworld.precollected_items[world.player])) + for item, value in start_inventory.items(): + write_bytes(rom_addresses["Start_Inventory"] + item - 172000000, min(value, 255)) - set_mon_palettes(world, random, data) + set_mon_palettes(world, patch) for move_data in world.local_move_data.values(): if move_data["id"] == 0: continue address = rom_addresses["Move_Data"] + ((move_data["id"] - 1) * 6) - write_bytes(data, bytearray([move_data["id"], move_data["effect"], move_data["power"], - poke_data.type_ids[move_data["type"]], round(move_data["accuracy"] * 2.55), move_data["pp"]]), address) + write_bytes(address, [move_data["id"], move_data["effect"], move_data["power"], + poke_data.type_ids[move_data["type"]], round(move_data["accuracy"] * 2.55), + move_data["pp"]]) - TM_IDs = bytearray([poke_data.moves[move]["id"] for move in world.local_tms]) - write_bytes(data, TM_IDs, rom_addresses["TM_Moves"]) + TM_IDs = [poke_data.moves[move]["id"] for move in world.local_tms] + write_bytes(rom_addresses["TM_Moves"], TM_IDs) if world.options.randomize_rock_tunnel: - seed = randomize_rock_tunnel(data, random) - write_bytes(data, encode_text(f"SEED: {seed}"), rom_addresses["Text_Rock_Tunnel_Sign"]) + seed = randomize_rock_tunnel(patch, world.random) + write_bytes(rom_addresses["Text_Rock_Tunnel_Sign"], encode_text(f"SEED: {seed}")) mons = [mon["id"] for mon in poke_data.pokemon_data.values()] - random.shuffle(mons) - data[rom_addresses['Title_Mon_First']] = mons.pop() + world.random.shuffle(mons) + write_bytes(rom_addresses["Title_Mon_First"], mons.pop()) for mon in range(0, 16): - data[rom_addresses['Title_Mons'] + mon] = mons.pop() + write_bytes(rom_addresses["Title_Mons"] + mon, mons.pop()) if world.options.game_version.value: mons.sort(key=lambda mon: 0 if mon == world.multiworld.get_location("Oak's Lab - Starter 1", world.player).item.name else 1 if mon == world.multiworld.get_location("Oak's Lab - Starter 2", world.player).item.name else @@ -576,34 +622,34 @@ def set_trade_mon(address, loc): mons.sort(key=lambda mon: 0 if mon == world.multiworld.get_location("Oak's Lab - Starter 2", world.player).item.name else 1 if mon == world.multiworld.get_location("Oak's Lab - Starter 1", world.player).item.name else 2 if mon == world.multiworld.get_location("Oak's Lab - Starter 3", world.player).item.name else 3) - write_bytes(data, encode_text(world.multiworld.seed_name[-20:], 20, True), rom_addresses['Title_Seed']) + write_bytes(rom_addresses["Title_Seed"], encode_text(world.multiworld.seed_name[-20:], 20, True)) slot_name = world.multiworld.player_name[world.player] slot_name.replace("@", " ") slot_name.replace("<", " ") slot_name.replace(">", " ") - write_bytes(data, encode_text(slot_name, 16, True, True), rom_addresses['Title_Slot_Name']) + write_bytes(rom_addresses["Title_Slot_Name"], encode_text(slot_name, 16, True, True)) if world.trainer_name == "choose_in_game": - data[rom_addresses["Skip_Player_Name"]] = 0 + write_bytes(rom_addresses["Skip_Player_Name"], 0) else: - write_bytes(data, world.trainer_name, rom_addresses['Player_Name']) + write_bytes(rom_addresses["Player_Name"], world.trainer_name) if world.rival_name == "choose_in_game": - data[rom_addresses["Skip_Rival_Name"]] = 0 + write_bytes(rom_addresses["Skip_Rival_Name"], 0) else: - write_bytes(data, world.rival_name, rom_addresses['Rival_Name']) + write_bytes(rom_addresses["Rival_Name"], world.rival_name) - data[0xFF00] = 2 # client compatibility version - rom_name = bytearray(f'AP{Utils.__version__.replace(".", "")[0:3]}_{world.player}_{world.multiworld.seed:11}\0', - 'utf8')[:21] + write_bytes(0xFF00, 2) # client compatibility version + rom_name = bytearray(f"AP{Utils.__version__.replace('.', '')[0:3]}_{world.player}_{world.multiworld.seed:11}\0", + "utf8")[:21] rom_name.extend([0] * (21 - len(rom_name))) - write_bytes(data, rom_name, 0xFFC6) - write_bytes(data, world.multiworld.seed_name.encode(), 0xFFDB) - write_bytes(data, world.multiworld.player_name[world.player].encode(), 0xFFF0) + write_bytes(0xFFC6, rom_name) + write_bytes(0xFFDB, world.multiworld.seed_name.encode()) + write_bytes(0xFFF0, world.multiworld.player_name[world.player].encode()) world.finished_level_scaling.wait() - write_quizzes(world, data, random) + write_quizzes(world, patch) for location in world.multiworld.get_locations(world.player): if location.party_data: @@ -617,18 +663,18 @@ def set_trade_mon(address, loc): levels = party["level"] for address, party in zip(addresses, parties): if isinstance(levels, int): - data[address] = levels + write_bytes(address, levels) address += 1 for mon in party: - data[address] = poke_data.pokemon_data[mon]["id"] + write_bytes(address, poke_data.pokemon_data[mon]["id"]) address += 1 else: address += 1 for level, mon in zip(levels, party): - data[address] = level - data[address + 1] = poke_data.pokemon_data[mon]["id"] + write_bytes(address, [level, poke_data.pokemon_data[mon]["id"]]) address += 2 - assert data[address] == 0 or location.name == "Fossil Level - Trainer Parties" + # This assert can't be done with procedure patch tokens. + # assert data[address] == 0 or location.name == "Fossil Level - Trainer Parties" continue elif location.rom_address is None: continue @@ -639,85 +685,24 @@ def set_trade_mon(address, loc): rom_address = [rom_address] for address in rom_address: if location.item.name in poke_data.pokemon_data.keys(): - data[address] = poke_data.pokemon_data[location.item.name]["id"] + write_bytes(address, poke_data.pokemon_data[location.item.name]["id"]) elif " ".join(location.item.name.split()[1:]) in poke_data.pokemon_data.keys(): - data[address] = poke_data.pokemon_data[" ".join(location.item.name.split()[1:])]["id"] + write_bytes(address, poke_data.pokemon_data[" ".join(location.item.name.split()[1:])]["id"]) else: item_id = world.item_name_to_id[location.item.name] - 172000000 if item_id > 255: item_id -= 256 - data[address] = item_id + write_bytes(address, item_id) if location.level: - data[location.level_address] = location.level + write_bytes(location.level_address, location.level) else: rom_address = location.rom_address if not isinstance(rom_address, list): rom_address = [rom_address] for address in rom_address: - data[address] = 0x2C # AP Item - - outfilepname = f'_P{world.player}' - outfilepname += f"_{world.multiworld.get_file_safe_player_name(world.player).replace(' ', '_')}" \ - if world.multiworld.player_name[world.player] != 'Player%d' % world.player else '' - rompath = os.path.join(output_directory, f'AP_{world.multiworld.seed_name}{outfilepname}.gb') - with open(rompath, 'wb') as outfile: - outfile.write(data) - if world.options.game_version.current_key == "red": - patch = RedDeltaPatch(os.path.splitext(rompath)[0] + RedDeltaPatch.patch_file_ending, player=world.player, - player_name=world.multiworld.player_name[world.player], patched_path=rompath) - else: - patch = BlueDeltaPatch(os.path.splitext(rompath)[0] + BlueDeltaPatch.patch_file_ending, player=world.player, - player_name=world.multiworld.player_name[world.player], patched_path=rompath) - - patch.write() - os.unlink(rompath) - - -def write_bytes(data, byte_array, address): - for byte in byte_array: - data[address] = byte - address += 1 - - -def get_base_rom_bytes(game_version: str, hash: str="") -> bytes: - file_name = get_base_rom_path(game_version) - with open(file_name, "rb") as file: - base_rom_bytes = bytes(file.read()) - if hash: - basemd5 = hashlib.md5() - basemd5.update(base_rom_bytes) - if hash != basemd5.hexdigest(): - raise Exception(f"Supplied Base Rom does not match known MD5 for Pokémon {game_version.title()} UE " - "release. Get the correct game and version, then dump it") - return base_rom_bytes - + write_bytes(address, 0x2C) # AP Item -def get_base_rom_path(game_version: str) -> str: - options = Utils.get_options() - file_name = options["pokemon_rb_options"][f"{game_version}_rom_file"] - if not os.path.exists(file_name): - file_name = Utils.user_path(file_name) - return file_name - - -class BlueDeltaPatch(APDeltaPatch): - patch_file_ending = ".apblue" - hash = "50927e843568814f7ed45ec4f944bd8b" - game_version = "blue" - game = "Pokemon Red and Blue" - result_file_ending = ".gb" - @classmethod - def get_source_data(cls) -> bytes: - return get_base_rom_bytes(cls.game_version, cls.hash) - - -class RedDeltaPatch(APDeltaPatch): - patch_file_ending = ".apred" - hash = "3d45c1ee9abd5738df46d2bdda8b57dc" - game_version = "red" - game = "Pokemon Red and Blue" - result_file_ending = ".gb" - @classmethod - def get_source_data(cls) -> bytes: - return get_base_rom_bytes(cls.game_version, cls.hash) + patch.write_file("token_data.bin", patch.get_token_binary()) + out_file_name = world.multiworld.get_out_file_name_base(world.player) + patch.write(os.path.join(output_directory, f"{out_file_name}{patch.patch_file_ending}")) From c46ee7c4209f064e9aa90bc8e6eb141f4a438b6c Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Wed, 30 Apr 2025 15:57:46 -0400 Subject: [PATCH 0378/1218] TUNIC: Lock pre-placed filler to make the game play nicer with prog balancing (#4917) --- worlds/tunic/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 9d97e5711bf7..aa6c8cdfb95f 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -486,10 +486,10 @@ def stage_pre_fill(cls, multiworld: MultiWorld) -> None: multiworld.random.shuffle(non_grass_fill_locations) for filler_item in grass_fill: - multiworld.push_item(grass_fill_locations.pop(), filler_item, collect=False) + grass_fill_locations.pop().place_locked_item(filler_item) for filler_item in non_grass_fill: - multiworld.push_item(non_grass_fill_locations.pop(), filler_item, collect=False) + non_grass_fill_locations.pop().place_locked_item(filler_item) def create_regions(self) -> None: self.tunic_portal_pairs = {} From 6beaacb9058f645dbb3f4cc77702cf02c17e7e83 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 2 May 2025 08:46:34 -0500 Subject: [PATCH 0379/1218] Generate: Better yaml parsing error messaging (#4927) Co-authored-by: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> --- Generate.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Generate.py b/Generate.py index 5b5219841d66..867a5b6c7a61 100644 --- a/Generate.py +++ b/Generate.py @@ -252,7 +252,20 @@ def read_weights_yamls(path) -> Tuple[Any, ...]: except Exception as e: raise Exception(f"Failed to read weights ({path})") from e - return tuple(parse_yamls(yaml)) + from yaml.error import MarkedYAMLError + try: + return tuple(parse_yamls(yaml)) + except MarkedYAMLError as ex: + if ex.problem_mark: + lines = yaml.splitlines() + if ex.context_mark: + relevant_lines = "\n".join(lines[ex.context_mark.line:ex.problem_mark.line+1]) + else: + relevant_lines = lines[ex.problem_mark.line] + error_line = " " * ex.problem_mark.column + "^" + raise Exception(f"{ex.context} {ex.problem} on line {ex.problem_mark.line}:" + f"\n{relevant_lines}\n{error_line}") + raise ex def interpret_on_off(value) -> bool: From 1031fc49237b27f0ab18540fe64a826dc5823e62 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 2 May 2025 15:59:27 +0200 Subject: [PATCH 0380/1218] Factorio: remove FactorioClient executable (#4928) --- FactorioClient.py | 12 ------------ worlds/factorio/__init__.py | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) delete mode 100644 FactorioClient.py diff --git a/FactorioClient.py b/FactorioClient.py deleted file mode 100644 index 070ca503269f..000000000000 --- a/FactorioClient.py +++ /dev/null @@ -1,12 +0,0 @@ -from __future__ import annotations - -import ModuleUpdate -ModuleUpdate.update() - -from worlds.factorio.Client import check_stdin, launch -import Utils - -if __name__ == "__main__": - Utils.init_logging("FactorioClient", exception_logger="Client") - check_stdin() - launch() diff --git a/worlds/factorio/__init__.py b/worlds/factorio/__init__.py index 87e36555a58b..ddebc7e3fdf5 100644 --- a/worlds/factorio/__init__.py +++ b/worlds/factorio/__init__.py @@ -27,7 +27,7 @@ def launch_client(): launch_component(launch, name="FactorioClient") -components.append(Component("Factorio Client", "FactorioClient", func=launch_client, component_type=Type.CLIENT)) +components.append(Component("Factorio Client", func=launch_client, component_type=Type.CLIENT)) class FactorioSettings(settings.Group): From 2455f1158ffff2bc919532374580f79a6f7b4aa9 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Fri, 2 May 2025 11:39:58 -0500 Subject: [PATCH 0381/1218] Options: Cleanup CommonOptions.as_dict (#4921) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- Options.py | 61 +++++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/Options.py b/Options.py index 6a6bbe5e7794..bea3804d1ee5 100644 --- a/Options.py +++ b/Options.py @@ -1292,42 +1292,47 @@ class CommonOptions(metaclass=OptionsMetaProperty): progression_balancing: ProgressionBalancing accessibility: Accessibility - def as_dict(self, - *option_names: str, - casing: typing.Literal["snake", "camel", "pascal", "kebab"] = "snake", - toggles_as_bools: bool = False) -> typing.Dict[str, typing.Any]: + def as_dict( + self, + *option_names: str, + casing: typing.Literal["snake", "camel", "pascal", "kebab"] = "snake", + toggles_as_bools: bool = False, + ) -> dict[str, typing.Any]: """ Returns a dictionary of [str, Option.value] - :param option_names: names of the options to return - :param casing: case of the keys to return. Supports `snake`, `camel`, `pascal`, `kebab` - :param toggles_as_bools: whether toggle options should be output as bools instead of strings + :param option_names: Names of the options to get the values of. + :param casing: Casing of the keys to return. Supports `snake`, `camel`, `pascal`, `kebab`. + :param toggles_as_bools: Whether toggle options should be returned as bools instead of ints. + + :return: A dictionary of each option name to the value of its Option. If the option is an OptionSet, the value + will be returned as a sorted list. """ assert option_names, "options.as_dict() was used without any option names." option_results = {} for option_name in option_names: - if option_name in type(self).type_hints: - if casing == "snake": - display_name = option_name - elif casing == "camel": - split_name = [name.title() for name in option_name.split("_")] - split_name[0] = split_name[0].lower() - display_name = "".join(split_name) - elif casing == "pascal": - display_name = "".join([name.title() for name in option_name.split("_")]) - elif casing == "kebab": - display_name = option_name.replace("_", "-") - else: - raise ValueError(f"{casing} is invalid casing for as_dict. " - "Valid names are 'snake', 'camel', 'pascal', 'kebab'.") - value = getattr(self, option_name).value - if isinstance(value, set): - value = sorted(value) - elif toggles_as_bools and issubclass(type(self).type_hints[option_name], Toggle): - value = bool(value) - option_results[display_name] = value - else: + if option_name not in type(self).type_hints: raise ValueError(f"{option_name} not found in {tuple(type(self).type_hints)}") + + if casing == "snake": + display_name = option_name + elif casing == "camel": + split_name = [name.title() for name in option_name.split("_")] + split_name[0] = split_name[0].lower() + display_name = "".join(split_name) + elif casing == "pascal": + display_name = "".join([name.title() for name in option_name.split("_")]) + elif casing == "kebab": + display_name = option_name.replace("_", "-") + else: + raise ValueError(f"{casing} is invalid casing for as_dict. " + "Valid names are 'snake', 'camel', 'pascal', 'kebab'.") + value = getattr(self, option_name).value + if isinstance(value, set): + value = sorted(value) + elif toggles_as_bools and issubclass(type(self).type_hints[option_name], Toggle): + value = bool(value) + option_results[display_name] = value return option_results From da0207f5cb419baa1f7b05c448bead91dbaa0bd4 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 2 May 2025 23:39:14 +0200 Subject: [PATCH 0382/1218] Factorio: implement custom filler items (#4945) --- worlds/AutoWorld.py | 2 +- worlds/factorio/__init__.py | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 67455a1a218e..f0004a9f1b5b 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -485,7 +485,7 @@ def create_item(self, name: str) -> "Item": def get_filler_item_name(self) -> str: """Called when the item pool needs to be filled with additional items to match location count.""" logging.warning(f"World {self} is generating a filler item without custom filler pool.") - return self.multiworld.random.choice(tuple(self.item_name_to_id.keys())) + return self.random.choice(tuple(self.item_name_to_id.keys())) @classmethod def create_group(cls, multiworld: "MultiWorld", new_player_id: int, players: Set[int]) -> World: diff --git a/worlds/factorio/__init__.py b/worlds/factorio/__init__.py index ddebc7e3fdf5..0e96e7f89bcb 100644 --- a/worlds/factorio/__init__.py +++ b/worlds/factorio/__init__.py @@ -115,6 +115,7 @@ class Factorio(World): settings: typing.ClassVar[FactorioSettings] trap_names: tuple[str] = ("Evolution", "Attack", "Teleport", "Grenade", "Cluster Grenade", "Artillery", "Atomic Rocket", "Atomic Cliff Remover", "Inventory Spill") + want_progressives: dict[str, bool] = collections.defaultdict(lambda: False) def __init__(self, world, player: int): super(Factorio, self).__init__(world, player) @@ -133,6 +134,8 @@ def generate_early(self) -> None: self.options.max_tech_cost.value, self.options.min_tech_cost.value self.tech_mix = self.options.tech_cost_mix.value self.skip_silo = self.options.silo.value == Silo.option_spawn + self.want_progressives = collections.defaultdict( + lambda: self.options.progressive.want_progressives(self.random)) def create_regions(self): player = self.player @@ -201,9 +204,6 @@ def create_items(self) -> None: range(getattr(self.options, f"{trap_name.lower().replace(' ', '_')}_traps"))) - want_progressives = collections.defaultdict(lambda: self.options.progressive. - want_progressives(self.random)) - cost_sorted_locations = sorted(self.science_locations, key=lambda location: location.name) special_index = {"automation": 0, "logistics": 1, @@ -218,7 +218,7 @@ def create_items(self) -> None: for tech_name in base_tech_table: if tech_name not in self.removed_technologies: progressive_item_name = tech_to_progressive_lookup.get(tech_name, tech_name) - want_progressive = want_progressives[progressive_item_name] + want_progressive = self.want_progressives[progressive_item_name] item_name = progressive_item_name if want_progressive else tech_name tech_item = self.create_item(item_name) index = special_index.get(tech_name, None) @@ -233,6 +233,12 @@ def create_items(self) -> None: loc.place_locked_item(tech_item) loc.revealed = True + def get_filler_item_name(self) -> str: + tech_name: str = self.random.choice(tuple(tech_table)) + progressive_item_name: str = tech_to_progressive_lookup.get(tech_name, tech_name) + want_progressive: bool = self.want_progressives[progressive_item_name] + return progressive_item_name if want_progressive else tech_name + def set_rules(self): player = self.player shapes = get_shapes(self) From 68c350b4c060bab81190ffede5f1f1649a949aa1 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 2 May 2025 23:39:52 +0200 Subject: [PATCH 0383/1218] CommonClient: rip out old global name lookup (#4941) --- CommonClient.py | 15 --------------- test/programs/test_common_client.py | 11 ----------- 2 files changed, 26 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index b622fb939bec..5179110061fd 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -196,25 +196,11 @@ def __init__(self, ctx: CommonContext, lookup_type: typing.Literal["item", "loca self.lookup_type: typing.Literal["item", "location"] = lookup_type self._unknown_item: typing.Callable[[int], str] = lambda key: f"Unknown {lookup_type} (ID: {key})" self._archipelago_lookup: typing.Dict[int, str] = {} - self._flat_store: typing.Dict[int, str] = Utils.KeyedDefaultDict(self._unknown_item) self._game_store: typing.Dict[str, typing.ChainMap[int, str]] = collections.defaultdict( lambda: collections.ChainMap(self._archipelago_lookup, Utils.KeyedDefaultDict(self._unknown_item))) - self.warned: bool = False # noinspection PyTypeChecker def __getitem__(self, key: str) -> typing.Mapping[int, str]: - # TODO: In a future version (0.6.0?) this should be simplified by removing implicit id lookups support. - if isinstance(key, int): - if not self.warned: - # Use warnings instead of logger to avoid deprecation message from appearing on user side. - self.warned = True - warnings.warn(f"Implicit name lookup by id only is deprecated and only supported to maintain " - f"backwards compatibility for now. If multiple games share the same id for a " - f"{self.lookup_type}, name could be incorrect. Please use " - f"`{self.lookup_type}_names.lookup_in_game()` or " - f"`{self.lookup_type}_names.lookup_in_slot()` instead.") - return self._flat_store[key] # type: ignore - return self._game_store[key] def __len__(self) -> int: @@ -254,7 +240,6 @@ def update_game(self, game: str, name_to_id_lookup_table: typing.Dict[str, int]) id_to_name_lookup_table = Utils.KeyedDefaultDict(self._unknown_item) id_to_name_lookup_table.update({code: name for name, code in name_to_id_lookup_table.items()}) self._game_store[game] = collections.ChainMap(self._archipelago_lookup, id_to_name_lookup_table) - self._flat_store.update(id_to_name_lookup_table) # Only needed for legacy lookup method. if game == "Archipelago": # Keep track of the Archipelago data package separately so if it gets updated in a custom datapackage, # it updates in all chain maps automatically. diff --git a/test/programs/test_common_client.py b/test/programs/test_common_client.py index 9936240d17b9..eeeba9d44ce1 100644 --- a/test/programs/test_common_client.py +++ b/test/programs/test_common_client.py @@ -47,17 +47,6 @@ async def test_archipelago_datapackage_lookups_exist(self): assert "Archipelago" in self.ctx.item_names, "Archipelago item names entry does not exist" assert "Archipelago" in self.ctx.location_names, "Archipelago location names entry does not exist" - async def test_implicit_name_lookups(self): - # Items - assert self.ctx.item_names[2**54 + 1] == "Test Item 1 - Safe" - assert self.ctx.item_names[2**54 + 3] == f"Unknown item (ID: {2**54+3})" - assert self.ctx.item_names[-1] == "Nothing" - - # Locations - assert self.ctx.location_names[2**54 + 1] == "Test Location 1 - Safe" - assert self.ctx.location_names[2**54 + 3] == f"Unknown location (ID: {2**54+3})" - assert self.ctx.location_names[-1] == "Cheat Console" - async def test_explicit_name_lookups(self): # Items assert self.ctx.item_names["__TestGame1"][2**54+1] == "Test Item 1 - Safe" From f4690e296d4fdc8e817e6e89f99f425b487ac9bb Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 2 May 2025 18:31:40 -0500 Subject: [PATCH 0384/1218] CommonClient: remove Datapackage Version handling (#4487) Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- CommonClient.py | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index 5179110061fd..94c558bf8aec 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -341,7 +341,6 @@ def __init__(self, server_address: typing.Optional[str] = None, password: typing self.item_names = self.NameLookupDict(self, "item") self.location_names = self.NameLookupDict(self, "location") - self.versions = {} self.checksums = {} self.jsontotextparser = JSONtoTextParser(self) @@ -556,7 +555,6 @@ def update_hint(self, location: int, finding_player: int, status: typing.Optiona # DataPackage async def prepare_data_package(self, relevant_games: typing.Set[str], - remote_date_package_versions: typing.Dict[str, int], remote_data_package_checksums: typing.Dict[str, str]): """Validate that all data is present for the current multiworld. Download, assimilate and cache missing data from the server.""" @@ -565,33 +563,26 @@ async def prepare_data_package(self, relevant_games: typing.Set[str], needed_updates: typing.Set[str] = set() for game in relevant_games: - if game not in remote_date_package_versions and game not in remote_data_package_checksums: + if game not in remote_data_package_checksums: continue - remote_version: int = remote_date_package_versions.get(game, 0) remote_checksum: typing.Optional[str] = remote_data_package_checksums.get(game) - if remote_version == 0 and not remote_checksum: # custom data package and no checksum for this game + if not remote_checksum: # custom data package and no checksum for this game needed_updates.add(game) continue - cached_version: int = self.versions.get(game, 0) cached_checksum: typing.Optional[str] = self.checksums.get(game) # no action required if cached version is new enough - if (not remote_checksum and (remote_version > cached_version or remote_version == 0)) \ - or remote_checksum != cached_checksum: - local_version: int = network_data_package["games"].get(game, {}).get("version", 0) + if remote_checksum != cached_checksum: local_checksum: typing.Optional[str] = network_data_package["games"].get(game, {}).get("checksum") - if ((remote_checksum or remote_version <= local_version and remote_version != 0) - and remote_checksum == local_checksum): + if remote_checksum == local_checksum: self.update_game(network_data_package["games"][game], game) else: cached_game = Utils.load_data_package_for_checksum(game, remote_checksum) - cache_version: int = cached_game.get("version", 0) cache_checksum: typing.Optional[str] = cached_game.get("checksum") # download remote version if cache is not new enough - if (not remote_checksum and (remote_version > cache_version or remote_version == 0)) \ - or remote_checksum != cache_checksum: + if remote_checksum != cache_checksum: needed_updates.add(game) else: self.update_game(cached_game, game) @@ -601,7 +592,6 @@ async def prepare_data_package(self, relevant_games: typing.Set[str], def update_game(self, game_package: dict, game: str): self.item_names.update_game(game, game_package["item_name_to_id"]) self.location_names.update_game(game, game_package["location_name_to_id"]) - self.versions[game] = game_package.get("version", 0) self.checksums[game] = game_package.get("checksum") def update_data_package(self, data_package: dict): @@ -872,9 +862,8 @@ async def process_server_cmd(ctx: CommonContext, args: dict): logger.info(' %s (Player %d)' % (network_player.alias, network_player.slot)) # update data package - data_package_versions = args.get("datapackage_versions", {}) data_package_checksums = args.get("datapackage_checksums", {}) - await ctx.prepare_data_package(set(args["games"]), data_package_versions, data_package_checksums) + await ctx.prepare_data_package(set(args["games"]), data_package_checksums) await ctx.server_auth(args['password']) From 83ed3c8b5056590739995cf0bc4ab16d3d266462 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 3 May 2025 11:53:52 +0200 Subject: [PATCH 0385/1218] Core: always embed Archipelago (#4880) --- Main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Main.py b/Main.py index 6f6a09619d17..5d9e1bc2110e 100644 --- a/Main.py +++ b/Main.py @@ -301,6 +301,7 @@ def precollect_hint(location: Location, auto_status: HintStatus): game_world.game: worlds.network_data_package["games"][game_world.game] for game_world in multiworld.worlds.values() } + data_package["Archipelago"] = worlds.network_data_package["games"]["Archipelago"] checks_in_area: Dict[int, Dict[str, Union[int, List[int]]]] = {} From 9425f5b772126a7d8e4bc61132084596c0de39d1 Mon Sep 17 00:00:00 2001 From: Tim Mahan <60069210+Bicoloursnake@users.noreply.github.com> Date: Sat, 3 May 2025 08:42:52 -0400 Subject: [PATCH 0386/1218] Docs: Direct Mac users to Launcher.py (#4767) --- worlds/generic/docs/mac_en.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/worlds/generic/docs/mac_en.md b/worlds/generic/docs/mac_en.md index 76b1ee4a3827..38fd3cd9404a 100644 --- a/worlds/generic/docs/mac_en.md +++ b/worlds/generic/docs/mac_en.md @@ -20,9 +20,11 @@ It is generally recommended that you use a virtual environment to run python bas 3. Run the command `source venv/bin/activate` to activate the virtual environment. 4. If you want to exit the virtual environment, run the command `deactivate`. ## Steps to Run the Clients -1. If your game doesn't have a patch file, run the command `python3 SNIClient.py`, changing the filename with the file of the client you want to run. -2. If your game does have a patch file, move the base rom to the Archipelago directory and run the command `python3 SNIClient.py 'patchfile'` with the filename extension for the patch file (apsm, aplttp, apsmz3, etc.) included and changing the filename with the file of the client you want to run. -3. Your client should now be running and rom created (where applicable). +1. Run the command `python3 Launcher.py`. +2. If your game doesn't have a patch file, just click the desired client in the right side column. +3. If your game does have a patch file, click the 'Open Patch' button and navigate to your patch file (the filename extension will look something like apsm, aplttp, apsmz3, etc.). +4. If the patching process needs a rom, but cannot find it, it will ask you to navigate to your legally obtained rom. +5. Your client should now be running and rom created (where applicable). ## Additional Steps for SNES Games 1. If using RetroArch, the instructions to set up your emulator [here in the Link to the Past setup guide](https://archipelago.gg/tutorial/A%20Link%20to%20the%20Past/multiworld/en) also work on the macOS version of RetroArch. 2. Double click on the SNI tar.gz download to extract the files to an SNI directory. If it isn't already, rename this directory to SNI to make some steps easier. From 1885dab06692e08a4d412c2e343811bb26e57f24 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Sat, 3 May 2025 20:06:16 -0400 Subject: [PATCH 0387/1218] TWW: Documentation Cleanup (#4942) --- worlds/tww/Options.py | 2 ++ worlds/tww/docs/en_The Wind Waker.md | 27 +++++++++++-------- worlds/tww/docs/setup_en.md | 39 ++++++++++++++++------------ 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/worlds/tww/Options.py b/worlds/tww/Options.py index d37de3acf490..ad9c8b3937a5 100644 --- a/worlds/tww/Options.py +++ b/worlds/tww/Options.py @@ -19,6 +19,8 @@ class Dungeons(DefaultOnToggle): """ This controls whether dungeon locations are randomized. + + This means the items found in dungeons will be randomized, not that the entrances to dungeons will be randomized. """ display_name = "Dungeons" diff --git a/worlds/tww/docs/en_The Wind Waker.md b/worlds/tww/docs/en_The Wind Waker.md index 4d6e999cf9ce..0158366b3f08 100644 --- a/worlds/tww/docs/en_The Wind Waker.md +++ b/worlds/tww/docs/en_The Wind Waker.md @@ -19,17 +19,18 @@ a yellow Rupee, which includes a message that the location is not randomized. ## What is the goal of The Wind Waker? Reach and defeat Ganondorf atop Ganon's Tower. This will require all eight shards of the Triforce of Courage, the -fully-powered Master Sword (unless it's swordless mode), Light Arrows, and any other items necessary to reach Ganondorf. +fully-powered Master Sword (unless it's swords optional or swordless mode), Light Arrows, and any other items necessary +to reach Ganondorf. ## What does another world's item look like in TWW? Items belonging to other non-TWW worlds are represented by Father's Letter (the letter Medli gives you to give to Komali), an unused item in the randomizer. -## When the player receives an item, what happens? +## What happens when the player receives an item? -When the player receives an item, it will automatically be added to Link's inventory. Unlike many other Zelda -randomizers, Link **will not** hold the item above his head. +When the player receives an item, it will automatically be added to Link's inventory. Link **will not** hold the item +above his head like many other Zelda randomizers. ## I need help! What do I do? @@ -37,16 +38,20 @@ Refer to the [FAQ](https://lagolunatic.github.io/wwrando/faq/) first. Then, try [setup guide](/tutorial/The%20Wind%20Waker/setup/en). If you are still stuck, please ask in the Wind Waker channel in the Archipelago server. +## I opened the game in Dolphin, but I don't have any of my starting items! + +You must connect to the multiworld room to receive any items, including your starting inventory. + ## Known issues - Randomized freestanding rupees, spoils, and bait will also be given to the player picking up the item. The item will be sent properly, but the collecting player will receive an extra copy. -- Demo items (items which are held over Link's head) which are **not** randomized, such as rupees from salvages from - random light rings or rewards from minigames, will not work. +- Demo items (items held over Link's head) that are **not** randomized, such as rupees from salvages from random light + rings or rewards from minigames, will not work. - Item get messages for progressive items received on locations that send earlier than intended will be incorrect. This does not affect gameplay. - The Heart Piece count in item get messages will be off by one. This does not affect gameplay. -- It has been reported that item links can be buggy. Nothing game-breaking, but do be aware of it. +- It has been reported that item links can be buggy. It is nothing game-breaking, but do be aware of it. Feel free to report any other issues or suggest improvements in the Wind Waker channel in the Archipelago server! @@ -76,14 +81,14 @@ A few presets are available on the [player options page](../player-options) for The preset features 3 required bosses and hard obscurity difficulty, and while the list of enabled progression options may seem intimidating, the preset also excludes several locations. - **Miniblins 2025**: These are (as close to as possible) the settings used in the WWR Racing Server's - [2025 Season of Minblins](https://docs.google.com/document/d/19vT68eU6PepD2BD2ZjR9ikElfqs8pXfqQucZ-TcscV8). This + [2025 Season of Miniblins](https://docs.google.com/document/d/19vT68eU6PepD2BD2ZjR9ikElfqs8pXfqQucZ-TcscV8). This preset is great if you're new to Wind Waker! There aren't too many locations in the world, and you only need to complete two dungeons. You also start with many convenience items, such as double magic, a capacity upgrade for your bow and bombs, and six hearts. - **Mixed Pools**: These are the settings used in the WWR Racing Server's [Mixed Pools Co-op Tournament](https://docs.google.com/document/d/1YGPTtEgP978TIi0PUAD792OtZbE2jBQpI8XCAy63qpg). This - preset features full entrance rando and includes many locations behind a randomized entrance. There are also a bunch - of overworld locations, as these settings were intended to be played in a two-person co-op team. The preset also has 6 + preset features full entrance rando and includes most locations behind a randomized entrance. There are also many + overworld locations, as these settings were intended to be played in a two-person co-op team. The preset also has 6 required bosses, but since entrance pools are randomized, the bosses could be found anywhere! Check your Sea Chart to find out which island the bosses are on. @@ -106,7 +111,7 @@ This randomizer would not be possible without the help from: - CrainWWR: (multiworld and Dolphin memory assistance, additional programming) - Cyb3R: (reference for `TWWClient`) - DeamonHunter: (additional programming) -- Dev5ter: (initial TWW AP implmentation) +- Dev5ter: (initial TWW AP implementation) - Gamma / SageOfMirrors: (additional programming) - LagoLunatic: (base randomizer, additional assistance) - Lunix: (Linux support, additional programming) diff --git a/worlds/tww/docs/setup_en.md b/worlds/tww/docs/setup_en.md index fa22b48bf89e..eea2d9892038 100644 --- a/worlds/tww/docs/setup_en.md +++ b/worlds/tww/docs/setup_en.md @@ -5,11 +5,13 @@ If you're playing The Wind Waker, you must follow a few simple steps to get star ## Requirements -You'll need the following components to be able to play with The Wind Waker: +You'll need the following components to be able to play The Wind Waker: * Install [Dolphin Emulator](https://dolphin-emu.org/download/). **We recommend using the latest release.** - * For Linux users, you can use the flatpak package + * Linux users can use the flatpak package [available on Flathub](https://flathub.org/apps/org.DolphinEmu.dolphin-emu). -* The 2.5.0 version of the [TWW AP Randomizer Build](https://github.com/tanjo3/wwrando/releases/tag/ap_2.5.0). +* The latest version of the [TWW AP Randomizer Build](https://github.com/tanjo3/wwrando/releases?q=tag%3Aap_2). + * Please note that this build is **different** from the one the standalone randomizer uses. This build is + specifically for Archipelago. * A The Wind Waker ISO (North American version), probably named "Legend of Zelda, The - The Wind Waker (USA).iso". Optionally, you can also download: @@ -26,17 +28,17 @@ world. Once you're happy with your settings, provide the room host with your YAM ## Connecting to a Room -The multiworld host will provide you a link to download your `aptww` file or a zip file containing everyone's files. The -`aptww` file should be named `P#__XXXXX.aptww`, where `#` is your player ID, `` is your player name, and +The multiworld host will provide you a link to download your APTWW file or a zip file containing everyone's files. The +APTWW file should be named `P#__XXXXX.aptww`, where `#` is your player ID, `` is your player name, and `XXXXX` is the room ID. The host should also provide you with the room's server name and port number. -Once you do, follow these steps to connect to the room: +Once you're ready, follow these steps to connect to the room: 1. Run the TWW AP Randomizer Build. If this is the first time you've opened the randomizer, you'll need to specify the path to your The Wind Waker ISO and the output folder for the randomized ISO. These will be saved for the next time you open the program. 2. Modify any cosmetic convenience tweaks and player customization options as desired. -3. For the APTWW file, browse and locate the path to your `aptww` file. -4. Click `Randomize` at the bottom-right. This randomizes the ISO and puts it in the output folder you specified. The +3. For the APTWW file, browse and locate the path to your APTWW file. +4. Click `Randomize` at the bottom right. This randomizes the ISO and puts it in the output folder you specified. The file will be named `TWW AP_YYYYY_P# ().iso`, where `YYYYY` is the seed name, `#` is your player ID, and `` is your player (slot) name. Verify that the values are correct for the multiworld. 5. Open Dolphin and use it to open the randomized ISO. @@ -47,7 +49,7 @@ text client. If Dolphin is not already open, or you have yet to start a new file on the website, this will be `archipelago.gg:`, where `` is the port number. If a game is hosted from the `ArchipelagoServer.exe` (without `.exe` on Linux), the port number will default to `38281` but may be changed in the `host.yaml`. -8. If you've opened a ROM corresponding to the multiworld to which you are connected, it should authenticate your slot +8. If you've opened an ISO corresponding to the multiworld to which you are connected, it should authenticate your slot name automatically when you start a new save file. ## Troubleshooting @@ -55,13 +57,18 @@ name automatically when you start a new save file. * Ensure you are running the same version of Archipelago on which the multiworld was generated. * Ensure `tww.apworld` is not in your Archipelago installation's `custom_worlds` folder. * Ensure you are using the correct randomizer build for the version of Archipelago you are using. The build should -provide an error message directing you to the correct version. You can also look at the release notes of TWW AP builds -[here](https://github.com/tanjo3/wwrando/releases) to see which versions of Archipelago each build is compatible with. + provide an error message directing you to the correct version. You can also look at the release notes of TWW AP builds + [here](https://github.com/tanjo3/wwrando/releases?q=tag%3Aap_2) to see which versions of Archipelago each build is + compatible with. +* Do not run the Archipelago Launcher or Dolphin as an administrator on Windows. * If you encounter issues with authenticating, ensure that the randomized ROM is open in Dolphin and corresponds to the -multiworld to which you are connecting. + multiworld to which you are connecting. * Ensure that you do not have any Dolphin cheats or codes enabled. Some cheats or codes can unexpectedly interfere with -emulation and make troubleshooting errors difficult. -* If you get an error message, ensure that `Enable Emulated Memory Size Override` in Dolphin (under `Options` > -`Configuration` > `Advanced`) is **disabled**. + emulation and make troubleshooting errors difficult. +* Ensure that `Enable Emulated Memory Size Override` in Dolphin (under `Options` > `Configuration` > `Advanced`) is + **disabled**. +* If the client cannot connect to Dolphin, ensure Dolphin is on the same drive as Archipelago. Having Dolphin on an + external drive has reportedly caused connection issues. +* Ensure the `Fallback Region` in Dolphin (under `Options` > `Configuration` > `General`) is set to `NTSC-U`. * If you run with a custom GC boot menu, you'll need to skip it by going to `Options` > `Configuration` > `GameCube` -and checking `Skip Main Menu`. + and checking `Skip Main Menu`. From fa2d7797f440a5d1a97a16358d25d024785e9355 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 4 May 2025 15:59:41 +0200 Subject: [PATCH 0388/1218] Core: update certifi (#4954) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ba3c3d84b4b8..951db610d311 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ schema>=0.7.7 kivy>=2.3.1 bsdiff4>=1.2.6 platformdirs>=4.3.6 -certifi>=2025.1.31 +certifi>=2025.4.26 cython>=3.0.12 cymem>=2.0.11 orjson>=3.10.15 From 68e37b8f9a9d31767ac7bd141b443e03c57b87cb Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 4 May 2025 16:22:48 +0200 Subject: [PATCH 0389/1218] Factorio: client cleanup and prevent process bomb (#4882) Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- worlds/factorio/Client.py | 42 +++++++++++++++++++------------------ worlds/factorio/__init__.py | 25 +--------------------- worlds/factorio/settings.py | 26 +++++++++++++++++++++++ 3 files changed, 49 insertions(+), 44 deletions(-) create mode 100644 worlds/factorio/settings.py diff --git a/worlds/factorio/Client.py b/worlds/factorio/Client.py index 7aeb30cb2da4..199cb29b86c0 100644 --- a/worlds/factorio/Client.py +++ b/worlds/factorio/Client.py @@ -9,7 +9,6 @@ import re import string import subprocess - import sys import time import typing @@ -17,15 +16,16 @@ import factorio_rcon -import Utils from CommonClient import ClientCommandProcessor, CommonContext, logger, server_loop, gui_enabled, get_base_parser from MultiServer import mark_raw from NetUtils import ClientStatus, NetworkItem, JSONtoTextParser, JSONMessagePart -from Utils import async_start, get_file_safe_name +from Utils import async_start, get_file_safe_name, is_windows, Version, format_SI_prefix, get_text_between +from .settings import FactorioSettings +from settings import get_settings def check_stdin() -> None: - if Utils.is_windows and sys.stdin: + if is_windows and sys.stdin: print("WARNING: Console input is not routed reliably on Windows, use the GUI instead.") @@ -67,7 +67,7 @@ class FactorioContext(CommonContext): items_handling = 0b111 # full remote # updated by spinup server - mod_version: Utils.Version = Utils.Version(0, 0, 0) + mod_version: Version = Version(0, 0, 0) def __init__(self, server_address, password, filter_item_sends: bool, bridge_chat_out: bool): super(FactorioContext, self).__init__(server_address, password) @@ -133,7 +133,7 @@ def energy_link_status(self) -> str: elif self.current_energy_link_value is None: return "Standby" else: - return f"{Utils.format_SI_prefix(self.current_energy_link_value)}J" + return f"{format_SI_prefix(self.current_energy_link_value)}J" def on_deathlink(self, data: dict): if self.rcon_client: @@ -155,10 +155,10 @@ def on_package(self, cmd: str, args: dict): if self.energy_link_increment and args.get("last_deplete", -1) == self.last_deplete: # it's our deplete request gained = int(args["original_value"] - args["value"]) - gained_text = Utils.format_SI_prefix(gained) + "J" + gained_text = format_SI_prefix(gained) + "J" if gained: logger.debug(f"EnergyLink: Received {gained_text}. " - f"{Utils.format_SI_prefix(args['value'])}J remaining.") + f"{format_SI_prefix(args['value'])}J remaining.") self.rcon_client.send_command(f"/ap-energylink {gained}") def on_user_say(self, text: str) -> typing.Optional[str]: @@ -278,7 +278,7 @@ async def game_watcher(ctx: FactorioContext): }])) ctx.rcon_client.send_command( f"/ap-energylink -{value}") - logger.debug(f"EnergyLink: Sent {Utils.format_SI_prefix(value)}J") + logger.debug(f"EnergyLink: Sent {format_SI_prefix(value)}J") await asyncio.sleep(0.1) @@ -439,9 +439,9 @@ async def factorio_spinup_server(ctx: FactorioContext) -> bool: factorio_server_logger.info(msg) if "Loading mod AP-" in msg and msg.endswith("(data.lua)"): parts = msg.split() - ctx.mod_version = Utils.Version(*(int(number) for number in parts[-2].split("."))) + ctx.mod_version = Version(*(int(number) for number in parts[-2].split("."))) elif "Write data path: " in msg: - ctx.write_data_path = Utils.get_text_between(msg, "Write data path: ", " [") + ctx.write_data_path = get_text_between(msg, "Write data path: ", " [") if "AppData" in ctx.write_data_path: logger.warning("It appears your mods are loaded from Appdata, " "this can lead to problems with multiple Factorio instances. " @@ -521,10 +521,16 @@ def _handle_color(self, node: JSONMessagePart): rcon_password = args.rcon_password if args.rcon_password else ''.join( random.choice(string.ascii_letters) for x in range(32)) factorio_server_logger = logging.getLogger("FactorioServer") -options = Utils.get_settings() -executable = options["factorio_options"]["executable"] +settings: FactorioSettings = get_settings().factorio_options +if os.path.samefile(settings.executable, sys.executable): + selected_executable = settings.executable + settings.executable = FactorioSettings.executable # reset to default + raise Exception(f"FactorioClient was set to run itself {selected_executable}, aborting process bomb.") + +executable = settings.executable + server_settings = args.server_settings if args.server_settings \ - else options["factorio_options"].get("server_settings", None) + else getattr(settings, "server_settings", None) server_args = ("--rcon-port", rcon_port, "--rcon-password", rcon_password) @@ -535,12 +541,8 @@ def launch(): if server_settings: server_settings = os.path.abspath(server_settings) - if not isinstance(options["factorio_options"]["filter_item_sends"], bool): - logging.warning(f"Warning: Option filter_item_sends should be a bool.") - initial_filter_item_sends = bool(options["factorio_options"]["filter_item_sends"]) - if not isinstance(options["factorio_options"]["bridge_chat_out"], bool): - logging.warning(f"Warning: Option bridge_chat_out should be a bool.") - initial_bridge_chat_out = bool(options["factorio_options"]["bridge_chat_out"]) + initial_filter_item_sends = bool(settings.filter_item_sends) + initial_bridge_chat_out = bool(settings.bridge_chat_out) if not os.path.exists(os.path.dirname(executable)): raise FileNotFoundError(f"Path {os.path.dirname(executable)} does not exist or could not be accessed.") diff --git a/worlds/factorio/__init__.py b/worlds/factorio/__init__.py index 0e96e7f89bcb..bfa6ceb894e0 100644 --- a/worlds/factorio/__init__.py +++ b/worlds/factorio/__init__.py @@ -5,7 +5,6 @@ import typing import Utils -import settings from BaseClasses import Region, Location, Item, Tutorial, ItemClassification from worlds.AutoWorld import World, WebWorld from worlds.LauncherComponents import Component, components, Type, launch as launch_component @@ -20,6 +19,7 @@ progressive_technology_table, common_tech_table, tech_to_progressive_lookup, progressive_tech_table, \ get_science_pack_pools, Recipe, recipes, technology_table, tech_table, factorio_base_id, useless_technologies, \ fluids, stacking_items, valid_ingredients, progressive_rows +from .settings import FactorioSettings def launch_client(): @@ -30,29 +30,6 @@ def launch_client(): components.append(Component("Factorio Client", func=launch_client, component_type=Type.CLIENT)) -class FactorioSettings(settings.Group): - class Executable(settings.UserFilePath): - is_exe = True - - class ServerSettings(settings.OptionalUserFilePath): - """ - by default, no settings are loaded if this file does not exist. \ -If this file does exist, then it will be used. - server_settings: "factorio\\\\data\\\\server-settings.json" - """ - - class FilterItemSends(settings.Bool): - """Whether to filter item send messages displayed in-game to only those that involve you.""" - - class BridgeChatOut(settings.Bool): - """Whether to send chat messages from players on the Factorio server to Archipelago.""" - - executable: Executable = Executable("factorio/bin/x64/factorio") - server_settings: typing.Optional[FactorioSettings.ServerSettings] = None - filter_item_sends: typing.Union[FilterItemSends, bool] = False - bridge_chat_out: typing.Union[BridgeChatOut, bool] = True - - class FactorioWeb(WebWorld): tutorials = [Tutorial( "Multiworld Setup Guide", diff --git a/worlds/factorio/settings.py b/worlds/factorio/settings.py new file mode 100644 index 000000000000..a2296e7395a0 --- /dev/null +++ b/worlds/factorio/settings.py @@ -0,0 +1,26 @@ +import typing + +import settings + + +class FactorioSettings(settings.Group): + class Executable(settings.UserFilePath): + is_exe = True + + class ServerSettings(settings.OptionalUserFilePath): + """ + by default, no settings are loaded if this file does not exist. \ +If this file does exist, then it will be used. + server_settings: "factorio\\\\data\\\\server-settings.json" + """ + + class FilterItemSends(settings.Bool): + """Whether to filter item send messages displayed in-game to only those that involve you.""" + + class BridgeChatOut(settings.Bool): + """Whether to send chat messages from players on the Factorio server to Archipelago.""" + + executable: Executable = Executable("factorio/bin/x64/factorio") + server_settings: typing.Optional[ServerSettings] = None + filter_item_sends: typing.Union[FilterItemSends, bool] = False + bridge_chat_out: typing.Union[BridgeChatOut, bool] = True From b2d2c8e5964ae22e8731bc1b8d3f364bbeb166ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sun, 4 May 2025 10:28:38 -0400 Subject: [PATCH 0390/1218] Stardew Valley: Add void mayo requirement for Goblin Problem quest (#4933) This adds the requirement of a void mayo for the Goblin Problem quest. There are also some small adjustments to related rules - Fishing a void mayo is only considered an option during the Goblin Problem quest, as the odds of finding one after the quest drops drastically. - Entrance to the witch hut now requires the goblin problem quest, not just a void mayo. - Fishing rules are all moved to `fishing_logic.py`. - `can_fish_at` no longer check that you have any of the fishing regions and the region you actually want to fish in. - created `can_fish_anywhere` and `can_crab_pot_anywhere` to better illustrate when any fish satisfies the rule. --- worlds/stardew_valley/logic/festival_logic.py | 4 +- worlds/stardew_valley/logic/fishing_logic.py | 55 +++++++++++++++++-- worlds/stardew_valley/logic/goal_logic.py | 2 +- worlds/stardew_valley/logic/logic.py | 38 ++++++------- worlds/stardew_valley/logic/quest_logic.py | 6 +- worlds/stardew_valley/logic/skill_logic.py | 43 +-------------- .../logic/special_order_logic.py | 2 +- .../stardew_valley/mods/logic/skills_logic.py | 4 +- worlds/stardew_valley/rules.py | 8 +-- 9 files changed, 85 insertions(+), 77 deletions(-) diff --git a/worlds/stardew_valley/logic/festival_logic.py b/worlds/stardew_valley/logic/festival_logic.py index b48668964d71..72efffe83a2c 100644 --- a/worlds/stardew_valley/logic/festival_logic.py +++ b/worlds/stardew_valley/logic/festival_logic.py @@ -154,7 +154,7 @@ def can_succeed_grange_display(self) -> StardewRule: # Salads at the bar are good enough cooking_rule = self.logic.money.can_spend_at(Region.saloon, 220) - fish_rule = self.logic.skill.can_fish(difficulty=50) + fish_rule = self.logic.fishing.can_fish_anywhere(50) # Hazelnut always available since the grange display is in fall forage_rule = self.logic.region.can_reach_any((Region.forest, Region.backwoods)) @@ -179,7 +179,7 @@ def can_succeed_grange_display(self) -> StardewRule: return animal_rule & artisan_rule & cooking_rule & fish_rule & forage_rule & fruit_rule & mineral_rule & vegetable_rule def can_win_fishing_competition(self) -> StardewRule: - return self.logic.skill.can_fish(difficulty=60) + return self.logic.fishing.can_fish(60) def has_all_rarecrows(self) -> StardewRule: rules = [] diff --git a/worlds/stardew_valley/logic/fishing_logic.py b/worlds/stardew_valley/logic/fishing_logic.py index 85a9b1204076..c8f9e0a34080 100644 --- a/worlds/stardew_valley/logic/fishing_logic.py +++ b/worlds/stardew_valley/logic/fishing_logic.py @@ -1,3 +1,5 @@ +from functools import cached_property + from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic from ..data import fish_data @@ -12,6 +14,8 @@ from ..strings.region_names import Region from ..strings.skill_names import Skill +fishing_regions = (Region.beach, Region.town, Region.forest, Region.mountain, Region.island_south, Region.island_west) + class FishingLogicMixin(BaseLogicMixin): def __init__(self, *args, **kwargs): @@ -20,17 +24,35 @@ def __init__(self, *args, **kwargs): class FishingLogic(BaseLogic): + @cache_self1 + def can_fish_anywhere(self, difficulty: int = 0) -> StardewRule: + return self.logic.fishing.can_fish(difficulty) & self.logic.region.can_reach_any(fishing_regions) + def can_fish_in_freshwater(self) -> StardewRule: - return self.logic.skill.can_fish() & self.logic.region.can_reach_any((Region.forest, Region.town, Region.mountain)) + return self.logic.fishing.can_fish() & self.logic.region.can_reach_any((Region.forest, Region.town, Region.mountain)) + @cached_property def has_max_fishing(self) -> StardewRule: return self.logic.tool.has_fishing_rod(4) & self.logic.skill.has_level(Skill.fishing, 10) + @cached_property def can_fish_chests(self) -> StardewRule: return self.logic.tool.has_fishing_rod(4) & self.logic.skill.has_level(Skill.fishing, 6) + @cache_self1 def can_fish_at(self, region: str) -> StardewRule: - return self.logic.skill.can_fish() & self.logic.region.can_reach(region) + return self.logic.fishing.can_fish() & self.logic.region.can_reach(region) + + @cache_self1 + def can_fish(self, difficulty: int = 0) -> StardewRule: + skill_required = min(10, max(0, int((difficulty / 10) - 1))) + if difficulty <= 40: + skill_required = 0 + + skill_rule = self.logic.skill.has_level(Skill.fishing, skill_required) + # Training rod only works with fish < 50. Fiberglass does not help you to catch higher difficulty fish, so it's skipped in logic. + number_fishing_rod_required = 1 if difficulty < 50 else (2 if difficulty < 80 else 4) + return self.logic.tool.has_fishing_rod(number_fishing_rod_required) & skill_rule @cache_self1 def can_catch_fish(self, fish: FishItem) -> StardewRule: @@ -39,14 +61,17 @@ def can_catch_fish(self, fish: FishItem) -> StardewRule: quest_rule = self.logic.fishing.can_start_extended_family_quest() region_rule = self.logic.region.can_reach_any(fish.locations) season_rule = self.logic.season.has_any(fish.seasons) + if fish.difficulty == -1: - difficulty_rule = self.logic.skill.can_crab_pot + difficulty_rule = self.logic.fishing.can_crab_pot else: - difficulty_rule = self.logic.skill.can_fish(difficulty=(120 if fish.legendary else fish.difficulty)) + difficulty_rule = self.logic.fishing.can_fish(120 if fish.legendary else fish.difficulty) + if fish.name == SVEFish.kittyfish: item_rule = self.logic.received(SVEQuestItem.kittyfish_spell) else: item_rule = True_() + return quest_rule & region_rule & season_rule & difficulty_rule & item_rule def can_catch_fish_for_fishsanity(self, fish: FishItem) -> StardewRule: @@ -78,7 +103,7 @@ def can_use_tackle(self, tackle: str) -> StardewRule: return self.logic.tool.has_fishing_rod(4) & self.logic.has(tackle) def can_catch_every_fish(self) -> StardewRule: - rules = [self.has_max_fishing()] + rules = [self.has_max_fishing] rules.extend( self.logic.fishing.can_catch_fish(fish) @@ -89,3 +114,23 @@ def can_catch_every_fish(self) -> StardewRule: def has_specific_bait(self, fish: FishItem) -> StardewRule: return self.can_catch_fish(fish) & self.logic.has(Machine.bait_maker) + + @cached_property + def can_crab_pot_anywhere(self) -> StardewRule: + return self.logic.fishing.can_fish() & self.logic.region.can_reach_any(fishing_regions) + + @cache_self1 + def can_crab_pot_at(self, region: str) -> StardewRule: + return self.logic.fishing.can_crab_pot & self.logic.region.can_reach(region) + + @cached_property + def can_crab_pot(self) -> StardewRule: + crab_pot_rule = self.logic.has(Fishing.bait) + + # We can't use the same rule if skills are vanilla, because fishing levels are required to crab pot, which is required to get fishing levels... + if self.content.features.skill_progression.is_progressive: + crab_pot_rule = crab_pot_rule & self.logic.has(Machine.crab_pot) + else: + crab_pot_rule = crab_pot_rule & self.logic.skill.can_get_fishing_xp + + return crab_pot_rule diff --git a/worlds/stardew_valley/logic/goal_logic.py b/worlds/stardew_valley/logic/goal_logic.py index 6dbb5f898765..7995ea2e0ddc 100644 --- a/worlds/stardew_valley/logic/goal_logic.py +++ b/worlds/stardew_valley/logic/goal_logic.py @@ -60,7 +60,7 @@ def can_complete_master_angler(self) -> StardewRule: if not self.content.features.fishsanity.is_enabled: return self.logic.fishing.can_catch_every_fish() - rules = [self.logic.fishing.has_max_fishing()] + rules = [self.logic.fishing.has_max_fishing] rules.extend( self.logic.fishing.can_catch_fish_for_fishsanity(fish) diff --git a/worlds/stardew_valley/logic/logic.py b/worlds/stardew_valley/logic/logic.py index 3848e393d2ce..716dd06571aa 100644 --- a/worlds/stardew_valley/logic/logic.py +++ b/worlds/stardew_valley/logic/logic.py @@ -130,9 +130,9 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC # @formatter:off self.registry.item_rules.update({ "Energy Tonic": self.money.can_spend_at(Region.hospital, 1000), - WaterChest.fishing_chest: self.fishing.can_fish_chests(), - WaterChest.golden_fishing_chest: self.fishing.can_fish_chests() & self.skill.has_mastery(Skill.fishing), - WaterChest.treasure: self.fishing.can_fish_chests(), + WaterChest.fishing_chest: self.fishing.can_fish_chests, + WaterChest.golden_fishing_chest: self.fishing.can_fish_chests & self.skill.has_mastery(Skill.fishing), + WaterChest.treasure: self.fishing.can_fish_chests, Ring.hot_java_ring: self.region.can_reach(Region.volcano_floor_10), "Galaxy Soul": self.money.can_trade_at(Region.qi_walnut_room, Currency.qi_gem, 40), "JotPK Big Buff": self.arcade.has_jotpk_power_level(7), @@ -164,7 +164,7 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC AnimalProduct.large_milk: self.animal.has_happy_animal(Animal.cow), AnimalProduct.milk: self.animal.has_animal(Animal.cow), AnimalProduct.rabbit_foot: self.animal.has_happy_animal(Animal.rabbit), - AnimalProduct.roe: self.skill.can_fish() & self.building.has_building(Building.fish_pond), + AnimalProduct.roe: self.fishing.can_fish_anywhere() & self.building.has_building(Building.fish_pond), AnimalProduct.squid_ink: self.mine.can_mine_in_the_mines_floor_81_120() | (self.building.has_building(Building.fish_pond) & self.has(Fish.squid)), AnimalProduct.sturgeon_roe: self.has(Fish.sturgeon) & self.building.has_building(Building.fish_pond), AnimalProduct.truffle: self.animal.has_animal(Animal.pig) & self.season.has_any_not_winter(), @@ -198,7 +198,7 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC ArtisanGood.targeted_bait: self.artisan.has_targeted_bait(), ArtisanGood.stardrop_tea: self.has(WaterChest.golden_fishing_chest), ArtisanGood.truffle_oil: self.has(AnimalProduct.truffle) & self.has(Machine.oil_maker), - ArtisanGood.void_mayonnaise: (self.skill.can_fish(Region.witch_swamp)) | (self.artisan.can_mayonnaise(AnimalProduct.void_egg)), + ArtisanGood.void_mayonnaise: self.artisan.can_mayonnaise(AnimalProduct.void_egg), Beverage.pina_colada: self.money.can_spend_at(Region.island_resort, 600), Beverage.triple_shot_espresso: self.has("Hot Java Ring"), Consumable.butterfly_powder: self.money.can_spend_at(Region.sewer, 20000), @@ -217,15 +217,15 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC Fertilizer.quality: self.time.has_year_two & self.money.can_spend_at(Region.pierre_store, 150), Fertilizer.tree: self.skill.has_level(Skill.foraging, 7) & self.has(Material.fiber) & self.has(Material.stone), Fish.any: self.logic.or_(*(self.fishing.can_catch_fish(fish) for fish in content.fishes.values())), - Fish.crab: self.skill.can_crab_pot_at(Region.beach), - Fish.crayfish: self.skill.can_crab_pot_at(Region.town), - Fish.lobster: self.skill.can_crab_pot_at(Region.beach), + Fish.crab: self.fishing.can_crab_pot_at(Region.beach), + Fish.crayfish: self.fishing.can_crab_pot_at(Region.town), + Fish.lobster: self.fishing.can_crab_pot_at(Region.beach), Fish.mussel: self.tool.can_forage(Generic.any, Region.beach) or self.has(Fish.mussel_node), Fish.mussel_node: self.region.can_reach(Region.island_west), Fish.oyster: self.tool.can_forage(Generic.any, Region.beach), - Fish.periwinkle: self.skill.can_crab_pot_at(Region.town), - Fish.shrimp: self.skill.can_crab_pot_at(Region.beach), - Fish.snail: self.skill.can_crab_pot_at(Region.town), + Fish.periwinkle: self.fishing.can_crab_pot_at(Region.town), + Fish.shrimp: self.fishing.can_crab_pot_at(Region.beach), + Fish.snail: self.fishing.can_crab_pot_at(Region.town), Fishing.curiosity_lure: self.monster.can_kill(self.monster.all_monsters_by_name[Monster.mummy]), Fishing.lead_bobber: self.skill.has_level(Skill.fishing, 6) & self.money.can_spend_at(Region.fish_shop, 200), Forageable.hay: self.building.has_building(Building.silo) & self.tool.has_tool(Tool.scythe), # @@ -235,7 +235,7 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC Fossil.fossilized_leg: self.region.can_reach(Region.dig_site) & self.tool.has_tool(Tool.pickaxe), Fossil.fossilized_ribs: self.region.can_reach(Region.island_south) & self.tool.has_tool(Tool.hoe), Fossil.fossilized_skull: self.action.can_open_geode(Geode.golden_coconut), - Fossil.fossilized_spine: self.skill.can_fish(Region.dig_site), + Fossil.fossilized_spine: self.fishing.can_fish_at(Region.dig_site), Fossil.fossilized_tail: self.action.can_pan_at(Region.dig_site, ToolMaterial.copper), Fossil.mummified_bat: self.region.can_reach(Region.volcano_floor_10), Fossil.mummified_frog: self.region.can_reach(Region.island_east) & self.tool.has_tool(Tool.scythe), @@ -296,12 +296,12 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC RetainingSoil.quality: self.time.has_year_two & self.money.can_spend_at(Region.pierre_store, 150), SpeedGro.basic: self.money.can_spend_at(Region.pierre_store, 100), SpeedGro.deluxe: self.time.has_year_two & self.money.can_spend_at(Region.pierre_store, 150), - Trash.broken_cd: self.skill.can_crab_pot, - Trash.broken_glasses: self.skill.can_crab_pot, - Trash.driftwood: self.skill.can_crab_pot, + Trash.broken_cd: self.fishing.can_crab_pot_anywhere, + Trash.broken_glasses: self.fishing.can_crab_pot_anywhere, + Trash.driftwood: self.fishing.can_crab_pot_anywhere, Trash.joja_cola: self.money.can_spend_at(Region.saloon, 75), - Trash.soggy_newspaper: self.skill.can_crab_pot, - Trash.trash: self.skill.can_crab_pot, + Trash.soggy_newspaper: self.fishing.can_crab_pot_anywhere, + Trash.trash: self.fishing.can_crab_pot_anywhere, TreeSeed.acorn: self.skill.has_level(Skill.foraging, 1) & self.ability.can_chop_trees(), TreeSeed.mahogany: self.region.can_reach(Region.secret_woods) & self.tool.has_tool(Tool.axe, ToolMaterial.iron) & self.skill.has_level(Skill.foraging, 1), TreeSeed.maple: self.skill.has_level(Skill.foraging, 1) & self.ability.can_chop_trees(), @@ -314,8 +314,8 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC WaterItem.cave_jelly: self.fishing.can_fish_at(Region.mines_floor_100) & self.tool.has_fishing_rod(2), WaterItem.river_jelly: self.fishing.can_fish_at(Region.town) & self.tool.has_fishing_rod(2), WaterItem.sea_jelly: self.fishing.can_fish_at(Region.beach) & self.tool.has_fishing_rod(2), - WaterItem.seaweed: self.skill.can_fish(Region.tide_pools), - WaterItem.white_algae: self.skill.can_fish(Region.mines_floor_20), + WaterItem.seaweed: self.fishing.can_fish_at(Region.tide_pools), + WaterItem.white_algae: self.fishing.can_fish_at(Region.mines_floor_20), WildSeeds.grass_starter: self.money.can_spend_at(Region.pierre_store, 100), }) # @formatter:on diff --git a/worlds/stardew_valley/logic/quest_logic.py b/worlds/stardew_valley/logic/quest_logic.py index e48324680d9f..5bc3f86eae74 100644 --- a/worlds/stardew_valley/logic/quest_logic.py +++ b/worlds/stardew_valley/logic/quest_logic.py @@ -39,7 +39,7 @@ def initialize_rules(self): Quest.raising_animals: self.logic.quest.can_complete_quest(Quest.getting_started) & self.logic.building.has_building(Building.coop), Quest.feeding_animals: self.logic.quest.can_complete_quest(Quest.getting_started) & self.logic.building.has_building(Building.silo), Quest.advancement: self.logic.quest.can_complete_quest(Quest.getting_started) & self.logic.has(Craftable.scarecrow), - Quest.archaeology: self.logic.tool.has_tool(Tool.hoe) | self.logic.mine.can_mine_in_the_mines_floor_1_40() | self.logic.skill.can_fish(), + Quest.archaeology: self.logic.tool.has_tool(Tool.hoe) | self.logic.mine.can_mine_in_the_mines_floor_1_40() | self.logic.fishing.can_fish_chests, Quest.rat_problem: self.logic.region.can_reach_all((Region.town, Region.community_center)), Quest.meet_the_wizard: self.logic.quest.can_complete_quest(Quest.rat_problem), Quest.forging_ahead: self.logic.has(Ore.copper) & self.logic.has(Machine.furnace), @@ -86,7 +86,9 @@ def initialize_rules(self): Quest.catch_a_lingcod: self.logic.season.has(Season.winter) & self.logic.has(Fish.lingcod) & self.logic.relationship.can_meet(NPC.willy), Quest.dark_talisman: self.logic.region.can_reach(Region.railroad) & self.logic.wallet.has_rusty_key() & self.logic.relationship.can_meet( NPC.krobus), - Quest.goblin_problem: self.logic.region.can_reach(Region.witch_swamp), + Quest.goblin_problem: self.logic.region.can_reach(Region.witch_swamp) + # Void mayo can be fished at 5% chance in the witch swamp while the quest is active. It drops a lot after the quest. + & (self.logic.has(ArtisanGood.void_mayonnaise) | self.logic.fishing.can_fish()), Quest.magic_ink: self.logic.relationship.can_meet(NPC.wizard), Quest.the_pirates_wife: self.logic.relationship.can_meet(NPC.kent) & self.logic.relationship.can_meet(NPC.gus) & self.logic.relationship.can_meet(NPC.sandy) & self.logic.relationship.can_meet(NPC.george) & diff --git a/worlds/stardew_valley/logic/skill_logic.py b/worlds/stardew_valley/logic/skill_logic.py index e02b180f6a41..7582e5240f2f 100644 --- a/worlds/stardew_valley/logic/skill_logic.py +++ b/worlds/stardew_valley/logic/skill_logic.py @@ -1,13 +1,10 @@ from functools import cached_property -from typing import Union, Tuple from Utils import cache_self1 from .base_logic import BaseLogicMixin, BaseLogic from ..data.harvest import HarvestCropSource from ..mods.logic.mod_skills_levels import get_mod_skill_levels from ..stardew_rule import StardewRule, true_, True_, False_ -from ..strings.craftable_names import Fishing -from ..strings.machine_names import Machine from ..strings.performance_names import Performance from ..strings.quality_names import ForageQuality from ..strings.region_names import Region @@ -15,7 +12,6 @@ from ..strings.tool_names import ToolMaterial, Tool from ..strings.wallet_item_names import Wallet -fishing_regions = (Region.beach, Region.town, Region.forest, Region.mountain, Region.island_south, Region.island_west) vanilla_skill_items = ("Farming Level", "Mining Level", "Foraging Level", "Fishing Level", "Combat Level") @@ -138,44 +134,9 @@ def can_get_combat_xp(self) -> StardewRule: @cached_property def can_get_fishing_xp(self) -> StardewRule: if self.content.features.skill_progression.is_progressive: - return self.logic.skill.can_fish() | self.logic.skill.can_crab_pot + return self.logic.fishing.can_fish_anywhere() | self.logic.fishing.can_crab_pot - return self.logic.skill.can_fish() - - # Should be cached - def can_fish(self, regions: Union[str, Tuple[str, ...]] = None, difficulty: int = 0) -> StardewRule: - if isinstance(regions, str): - regions = regions, - - if regions is None or len(regions) == 0: - regions = fishing_regions - - skill_required = min(10, max(0, int((difficulty / 10) - 1))) - if difficulty <= 40: - skill_required = 0 - - skill_rule = self.logic.skill.has_level(Skill.fishing, skill_required) - region_rule = self.logic.region.can_reach_any(regions) - # Training rod only works with fish < 50. Fiberglass does not help you to catch higher difficulty fish, so it's skipped in logic. - number_fishing_rod_required = 1 if difficulty < 50 else (2 if difficulty < 80 else 4) - return self.logic.tool.has_fishing_rod(number_fishing_rod_required) & skill_rule & region_rule - - @cache_self1 - def can_crab_pot_at(self, region: str) -> StardewRule: - return self.logic.skill.can_crab_pot & self.logic.region.can_reach(region) - - @cached_property - def can_crab_pot(self) -> StardewRule: - crab_pot_rule = self.logic.has(Fishing.bait) - - # We can't use the same rule if skills are vanilla, because fishing levels are required to crab pot, which is required to get fishing levels... - if self.content.features.skill_progression.is_progressive: - crab_pot_rule = crab_pot_rule & self.logic.has(Machine.crab_pot) - else: - crab_pot_rule = crab_pot_rule & self.logic.skill.can_get_fishing_xp - - water_region_rules = self.logic.region.can_reach_any(fishing_regions) - return crab_pot_rule & water_region_rules + return self.logic.fishing.can_fish_anywhere() def can_forage_quality(self, quality: str) -> StardewRule: if quality == ForageQuality.basic: diff --git a/worlds/stardew_valley/logic/special_order_logic.py b/worlds/stardew_valley/logic/special_order_logic.py index a81f715c4866..73276ce97f38 100644 --- a/worlds/stardew_valley/logic/special_order_logic.py +++ b/worlds/stardew_valley/logic/special_order_logic.py @@ -42,7 +42,7 @@ def initialize_rules(self): SpecialOrder.fragments_of_the_past: self.logic.monster.can_kill(Monster.skeleton), SpecialOrder.gus_famous_omelet: self.logic.has(AnimalProduct.any_egg), SpecialOrder.crop_order: self.logic.ability.can_farm_perfectly() & self.logic.shipping.can_use_shipping_bin, - SpecialOrder.community_cleanup: self.logic.skill.can_crab_pot, + SpecialOrder.community_cleanup: self.logic.fishing.can_crab_pot_anywhere, SpecialOrder.the_strong_stuff: self.logic.has(ArtisanGood.specific_juice(Vegetable.potato)), SpecialOrder.pierres_prime_produce: self.logic.ability.can_farm_perfectly(), SpecialOrder.robins_project: self.logic.relationship.can_meet(NPC.robin) & self.logic.ability.can_chop_perfectly() & diff --git a/worlds/stardew_valley/mods/logic/skills_logic.py b/worlds/stardew_valley/mods/logic/skills_logic.py index b1f10d08b97e..d57e6c59313a 100644 --- a/worlds/stardew_valley/mods/logic/skills_logic.py +++ b/worlds/stardew_valley/mods/logic/skills_logic.py @@ -44,9 +44,9 @@ def can_earn_mod_skill_level(self, skill: str, level: int) -> StardewRule: def can_earn_luck_skill_level(self, level: int) -> StardewRule: if level >= 6: - return self.logic.fishing.can_fish_chests() | self.logic.action.can_open_geode(Geode.magma) + return self.logic.fishing.can_fish_chests | self.logic.action.can_open_geode(Geode.magma) if level >= 3: - return self.logic.fishing.can_fish_chests() | self.logic.action.can_open_geode(Geode.geode) + return self.logic.fishing.can_fish_chests | self.logic.action.can_open_geode(Geode.geode) return True_() # You can literally wake up and or get them by opening starting chests. def can_earn_magic_skill_level(self, level: int) -> StardewRule: diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index 4257f856c83d..51f69a1af853 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -214,7 +214,7 @@ def set_entrance_rules(logic: StardewLogic, multiworld, player, world_options: S set_entrance_rule(multiworld, player, Entrance.mountain_to_railroad, logic.received("Railroad Boulder Removed")) set_entrance_rule(multiworld, player, Entrance.enter_witch_warp_cave, logic.quest.has_dark_talisman() | (logic.mod.magic.can_blink())) - set_entrance_rule(multiworld, player, Entrance.enter_witch_hut, (logic.has(ArtisanGood.void_mayonnaise) | logic.mod.magic.can_blink())) + set_entrance_rule(multiworld, player, Entrance.enter_witch_hut, (logic.quest.can_complete_quest(Quest.goblin_problem) | logic.mod.magic.can_blink())) set_entrance_rule(multiworld, player, Entrance.enter_mutant_bug_lair, (logic.wallet.has_rusty_key() & logic.region.can_reach(Region.railroad) & logic.relationship.can_meet( NPC.krobus)) | logic.mod.magic.can_blink()) @@ -923,9 +923,9 @@ def set_magic_spell_rules(logic: StardewLogic, multiworld: MultiWorld, player: i set_rule(multiworld.get_location("Analyze: Fireball", player), logic.has("Fire Quartz")) set_rule(multiworld.get_location("Analyze: Frostbolt", player), - logic.region.can_reach(Region.mines_floor_60) & logic.skill.can_fish(difficulty=85)) + logic.region.can_reach(Region.mines_floor_60) & logic.fishing.can_fish(85)) set_rule(multiworld.get_location("Analyze All Elemental School Locations", player), - logic.has("Fire Quartz") & logic.region.can_reach(Region.mines_floor_60) & logic.skill.can_fish(difficulty=85)) + logic.has("Fire Quartz") & logic.region.can_reach(Region.mines_floor_60) & logic.fishing.can_fish(85)) # set_rule(multiworld.get_location("Analyze: Lantern", player),) set_rule(multiworld.get_location("Analyze: Tendrils", player), logic.region.can_reach(Region.farm)) @@ -948,7 +948,7 @@ def set_magic_spell_rules(logic: StardewLogic, multiworld: MultiWorld, player: i & (logic.tool.has_tool("Axe", "Basic") | logic.tool.has_tool("Pickaxe", "Basic")) & logic.has("Coffee") & logic.has("Life Elixir") & logic.ability.can_mine_perfectly() & logic.has("Earth Crystal") & - logic.has("Fire Quartz") & logic.skill.can_fish(difficulty=85) & + logic.has("Fire Quartz") & logic.fishing.can_fish(85) & logic.region.can_reach(Region.witch_hut) & logic.region.can_reach(Region.mines_floor_100) & logic.region.can_reach(Region.farm) & logic.time.has_lived_months(12))) From b217372fea536d3af83c92ee19be2e694debcc7c Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 5 May 2025 19:18:20 -0400 Subject: [PATCH 0391/1218] Core: Make Perfect Fuzzy Match Prioritize Casing (#4956) --- Utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Utils.py b/Utils.py index 46a0d106ef85..a3a529d754d6 100644 --- a/Utils.py +++ b/Utils.py @@ -635,6 +635,8 @@ def get_fuzzy_results(input_word: str, word_list: typing.Collection[str], limit: import jellyfish def get_fuzzy_ratio(word1: str, word2: str) -> float: + if word1 == word2: + return 1.01 return (1 - jellyfish.damerau_levenshtein_distance(word1.lower(), word2.lower()) / max(len(word1), len(word2))) @@ -655,8 +657,10 @@ def get_intended_text(input_text: str, possible_answers) -> typing.Tuple[str, bo picks = get_fuzzy_results(input_text, possible_answers, limit=2) if len(picks) > 1: dif = picks[0][1] - picks[1][1] - if picks[0][1] == 100: + if picks[0][1] == 101: return picks[0][0], True, "Perfect Match" + elif picks[0][1] == 100: + return picks[0][0], True, "Case Insensitive Perfect Match" elif picks[0][1] < 75: return picks[0][0], False, f"Didn't find something that closely matches '{input_text}', " \ f"did you mean '{picks[0][0]}'? ({picks[0][1]}% sure)" From b898b9d9e6e01e87f2a5f83fcc97e29be934ef58 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Tue, 6 May 2025 11:32:30 -0500 Subject: [PATCH 0392/1218] The Messenger: fix indentation in setup guide (#4959) * The Messenger: fix indentation in setup guide * just delete the save backup section tbh --- worlds/messenger/docs/setup_en.md | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/worlds/messenger/docs/setup_en.md b/worlds/messenger/docs/setup_en.md index 64b706c2643a..8813e2238174 100644 --- a/worlds/messenger/docs/setup_en.md +++ b/worlds/messenger/docs/setup_en.md @@ -23,21 +23,12 @@ These steps can also be followed to launch the game and check for mod updates af ### Manual Installation 1. Download and install Courier Mod Loader using the instructions on the release page - * [Latest release is currently 0.7.1](https://github.com/Brokemia/Courier/releases) + * [Latest release is currently 0.7.1](https://github.com/Brokemia/Courier/releases) 2. Download and install the randomizer mod - 1. Download the latest TheMessengerRandomizerAP.zip from -[The Messenger Randomizer Mod AP releases page](https://github.com/alwaysintreble/TheMessengerRandomizerModAP/releases) - 2. Extract the zip file to `TheMessenger/Mods/` of your game's install location - * You cannot have both the non-AP randomizer and the AP randomizer installed at the same time - 3. Optionally, Backup your save game - * On Windows - 1. Press `Windows Key + R` to open run - 2. Type `%appdata%` to access AppData - 3. Navigate to `AppData/locallow/SabotageStudios/The Messenger` - 4. Rename `SaveGame.txt` to any name of your choice - * On Linux - 1. Navigate to `steamapps/compatdata/764790/pfx/drive_c/users/steamuser/AppData/LocalLow/Sabotage Studio/The Messenger` - 2. Rename `SaveGame.txt` to any name of your choice + 1. Download the latest TheMessengerRandomizerAP.zip from + [The Messenger Randomizer Mod AP releases page](https://github.com/alwaysintreble/TheMessengerRandomizerModAP/releases) + 2. Extract the zip file to `TheMessenger/Mods/` of your game's install location + * You cannot have both the non-AP randomizer and the AP randomizer installed at the same time ## Joining a MultiWorld Game @@ -57,15 +48,15 @@ These steps can also be followed to launch the game and check for mod updates af 1. Launch the game 2. Navigate to `Options > Archipelago Options` 3. Enter connection info using the relevant option buttons - * **The game is limited to alphanumerical characters, `.`, and `-`.** - * This defaults to `archipelago.gg` and does not need to be manually changed if connecting to a game hosted on the - website. - * If using a name that cannot be entered in the in game menus, there is a config file (APConfig.toml) in the game - directory. When using this, all connection information must be entered in the file. + * **The game is limited to alphanumerical characters, `.`, and `-`.** + * This defaults to `archipelago.gg` and does not need to be manually changed if connecting to a game hosted on the + website. + * If using a name that cannot be entered in the in game menus, there is a config file (APConfig.toml) in the game + directory. When using this, all connection information must be entered in the file. 4. Select the `Connect to Archipelago` button 5. Navigate to save file selection 6. Start a new game - * If you're already connected, deleting an existing save will not disconnect you and is completely safe. + * If you're already connected, deleting an existing save will not disconnect you and is completely safe. ## Continuing a MultiWorld Game From 7bbe62019ad4cad1b8623eed051d058f5ae3cf5c Mon Sep 17 00:00:00 2001 From: Seldom <38388947+Seldom-SE@users.noreply.github.com> Date: Tue, 6 May 2025 09:32:55 -0700 Subject: [PATCH 0393/1218] Terraria: Fix inaccessible Leading Landlord achievement when getfixedboi is enabled #4958 --- worlds/terraria/Rules.dsv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/terraria/Rules.dsv b/worlds/terraria/Rules.dsv index 9ae82d747243..6bc1183e598d 100644 --- a/worlds/terraria/Rules.dsv +++ b/worlds/terraria/Rules.dsv @@ -151,7 +151,7 @@ Magma Stone; // Evil Smashing, Poppet!; Achievement; Arms Dealer; Npc; -Leading Landlord; Achievement; Nurse & Arms Dealer; // The logic is way more complex, but that doesn't affect anything +Leading Landlord; Achievement | Not Getfixedboi; Nurse & Arms Dealer; // The logic is way more complex, but that doesn't affect anything Completely Awesome; Achievement; Arms Dealer; Illegal Gun Parts; ; Arms Dealer | Flamethrower; From a3aac3d7370383d0044fa4e21897a585a9f106a2 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Tue, 6 May 2025 12:33:21 -0400 Subject: [PATCH 0394/1218] TUNIC: Entrance rando Direction Pairs + Decoupled (#3761) * Fix merge conflict * Fix formatting, fix rule for heir access after merge * Writing combat logic helpers * More helpers! * More logic! * Rename has_stick to has_melee, some fixes per Medic's review * Clamp max power from sword upgrades * Wrote the rest of the helpers * Remove unused import * Apply item classifications * Create the combat logic option * Item classification varies based on option * Add the shop sword logic stuff in * Add the rules for the boss-only option * Fix tiny issues * Some early Overworld combat logic * Fill out swamp combat logic * Add note * Bump up Boss Scav and Heir * More revisions to combat logic * Some changes, currently broken * New system for power, kinda jank probably * Revisions to new system, needs more balancing * Cap attack upgrades * Uncap mp power since it's directly related to damage output * Voidlings * Put together a table showing the vanilla-expected stats for each area * Added some info on potion counts * Made new helper functions * Make has_required_stats * Make has_combat_reqs * Update er_rules for new combat reqs * Fix all the broken things ever * Remove outdated todo * Make temp option for testing logic * More flexible choices for combat items * Hard require sword for bosses * Temporarily default combat logic to on * Finish writing overworld combat logic * East Forest combat logic done * Remove a few easy ones * Finish beneath the well * Dark Tomb combat logic * West Garden combat logic * make unit tests checkmark again * Weird west garden dagger house edge case * Try block for that weird west garden edge case * Add quarry combat logic * Update to filter out unreachable regions outside of ER * Fortress Grave Path logic, and a couple fixes to the west garden logic * Fortress east shortcut logic, and rewriting the try except blocks to use finally * Refactor to use a new function cause wow there was a lot of repeated code * Add combat logic to the other two sets of fortress fuses * Add combat rules to beneath the vault * Fix missing cathedral -> elevator connection * Combat logic for cathedral to elevator * Add cathedral main region, rename cathedral -> cathedral entry * Setup cathedral combat logic * Adjust locations' regions for ER * Add laurels zip logic to the chest in the spike room in cathedral * Add combat logic to frog's domain * Move frog's domain locations to regions for combat logic * Add new frog's domain regions for combat logic * Update region name for frog's domain * Fix typo * Add more regions for lower zig * Move around lower zig regions for combat logic * Lower Zig combat logic * Upper zig combat logic * Fix typo * Fix typos * Fix missing world. * Update combat logic description * Add todo * Add todo * Don't make zig skip if er or fixed shop is off * Make it so zig skip is only made with fewer shops and er * Temporarily default combat logic on * Update test to explicitly disable combat logic * Update test_access.py * Slight wording changes * Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples * Run through checks you can do with magic dagger * Run through checks you can do with magic dagger * Add rule for entering town portal of having equipment to deal with enemies * Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm * Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels * Revamp combat logic function to work properly without melee * Add laurels rules to combat logic chests * Modify beneath the vault bridge rule to need a lantern if combat logic is on * Put in money logic * Dagger or combat for swamp big skeleton chest * Remove the 100 moneys from logic * Modify lower zig ls drop region destinations * Remove completed todo * Reword combat logic option description, remove test option * Add combat logic to slot data * Merge Silent's missing slot data bugfix PR #3628 * Remove test combat option * Update combat logic description * Fix secret gathering place issue * Fix secret gathering place issue * Fix lower zig ls rule * Fix accidentally removed librarian rule * Remove redundant rule * Update gauntlet rule to hard-require a sword * Add test for a problematic connection * Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic * Fix create_item classification * Update some comments * Update per exempt's suggestion * Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off * Add EntranceLayout option * Add back LogicRules as an invisible option, to not break old yamls * Fix a bug with seed group, continue changing fixed shop to entrance layout * Fix missed fixed shop -> entrance layout spot * Fix bug in seed groups with fixed shop on and off * Add entrance layout to the UT regen stuff * Put direction. in, will add them later * Remove unused elevation from portal class * Got like half of them in * Finish adding all of the directions * Add combat rule for zig front to back * Update per Medic's suggestion * Update ladder storage without items option description * Mess with state with collect and remove to save like 2 seconds (never again) * Save even more time, still never going to do this again on anything else * Add option check for collect and remove * Add directions to shop portals * Update direction in Portal with default * Move Direction above Portal * Add decoupled option, mess with plando connection stuff * Merge, implement verify plando directions * Condense the stuff in change and remove to less lines (thanks medic) * Remove unused thing * Swap to using logicmixin instead of prog_items (thanks Vi) * Fix consistency in stat counters * Add back something that was needed * Fix mistake when adding back * Making the fix better (thanks medic) * Make it actually return false if it gets to the backup lists and fails them * Fix stuff after merge * Add outlet regions, create new regions as needed for them * Put together part of decoupled and direction pairs * make direction pairs work * Make decoupled work * Make fixed shop work again * Fix a few minor bugs * Fix a few minor bugs * Fix plando * god i love programming * Reorder portal list * Update portal sorter for variable shops * Add missing parameter * Some cleanup of prints and functions * Fix typo * it's aliiiiiive * Make seed groups not sync decoupled * Add test with full-shop plando * Fix bug with vanilla portals * Handle plando connections and direction pair errors * Update plando checking for decoupled * Fix typo * Fix exception text to be shorter * Add some more comments * Add todo note * Remove unused safety thing * Remove extra plando connections definition in options * Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log * Fix weird edge case that is technically user error * Add note to fixed shop * Fix parsing shop names in UT * Remove debug print * Actually make UT work * multiworld. to world. * Fix typo from merge * Make it so the shops show up in the entrance hints * Fix bug in ladder storage rules * Remove blank line * # Conflicts: # worlds/tunic/__init__.py # worlds/tunic/er_data.py # worlds/tunic/er_rules.py # worlds/tunic/er_scripts.py # worlds/tunic/rules.py # worlds/tunic/test/test_access.py * Fix issues after merge * Update plando connections stuff in docs * Fix library mistake * has_stick -> has_melee * has_stick -> has_melee * Add a failsafe for direction pairing * Fix playthrough crash bug * Remove init from logicmixin * Updates per code review (thanks hesto) * has_stick to has_melee in newer update * has_stick to has_melee in newer update * # Conflicts: # worlds/tunic/__init__.py # worlds/tunic/combat_logic.py # worlds/tunic/er_data.py # worlds/tunic/er_rules.py # worlds/tunic/er_scripts.py * Cleanup more stuff after merge * Revert "Cleanup more stuff after merge" This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d. * Revert "# Conflicts:" This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30. * Cleanup more stuff after merge * Swap to .get for decoupled so it works with older games probably maybe * Fix after merge * Fix typo * Fix UT support with fixed shop option * Backport plando connections fix * Fix issue with fixed shop + decoupled * Make the error not duplicate the while loop condition * Fix rule for quarry back to monastery * Fix more stuff after merge * Make it not output anything if you set plando connections but not ER * Add obvious note to plando connections description * Fix after merge * add comment to commented out connection --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/tunic/__init__.py | 133 ++++--- worlds/tunic/combat_logic.py | 1 + worlds/tunic/docs/en_TUNIC.md | 2 +- worlds/tunic/er_data.py | 533 ++++++++++++------------- worlds/tunic/er_rules.py | 21 +- worlds/tunic/er_scripts.py | 642 ++++++++++++++++++++++--------- worlds/tunic/options.py | 73 +++- worlds/tunic/rules.py | 5 +- worlds/tunic/test/test_access.py | 262 ++++++++++++- 9 files changed, 1153 insertions(+), 519 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index aa6c8cdfb95f..7027ab1a6427 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -7,12 +7,12 @@ from .rules import set_location_rules, set_region_rules, randomize_ability_unlocks, gold_hexagon from .er_rules import set_er_location_rules from .regions import tunic_regions -from .er_scripts import create_er_regions +from .er_scripts import create_er_regions, verify_plando_directions from .grass import grass_location_table, grass_location_name_to_id, grass_location_name_groups, excluded_grass_locations from .er_data import portal_mapping, RegionInfo, tunic_er_regions from .options import (TunicOptions, EntranceRando, tunic_option_groups, tunic_option_presets, TunicPlandoConnections, LaurelsLocation, LogicRules, LaurelsZips, IceGrappling, LadderStorage, check_options, - get_hexagons_in_pool, HexagonQuestAbilityUnlockType) + get_hexagons_in_pool, HexagonQuestAbilityUnlockType, EntranceLayout) from .breakables import breakable_location_name_to_id, breakable_location_groups, breakable_location_table from .combat_logic import area_data, CombatState from worlds.AutoWorld import WebWorld, World @@ -61,8 +61,9 @@ class SeedGroup(TypedDict): ice_grappling: int # ice_grappling value ladder_storage: int # ls value laurels_at_10_fairies: bool # laurels location value - fixed_shop: bool # fixed shop value - plando: TunicPlandoConnections # consolidated plando connections for the seed group + entrance_layout: int # entrance layout value + has_decoupled_enabled: bool # for checking that players don't have conflicting options + plando: List[PlandoConnection] # consolidated plando connections for the seed group class TunicWorld(World): @@ -95,7 +96,7 @@ class TunicWorld(World): tunic_portal_pairs: Dict[str, str] er_portal_hints: Dict[int, str] seed_groups: Dict[str, SeedGroup] = {} - shop_num: int = 1 # need to make it so that you can walk out of shops, but also that they aren't all connected + used_shop_numbers: Set[int] er_regions: Dict[str, RegionInfo] # absolutely needed so outlet regions work # for the local_fill option @@ -122,24 +123,35 @@ def generate_early(self) -> None: check_options(self) - if self.options.logic_rules >= LogicRules.option_no_major_glitches: - self.options.laurels_zips.value = LaurelsZips.option_true - self.options.ice_grappling.value = IceGrappling.option_medium - if self.options.logic_rules.value == LogicRules.option_unrestricted: - self.options.ladder_storage.value = LadderStorage.option_medium - self.er_regions = tunic_er_regions.copy() + if self.options.plando_connections and not self.options.entrance_rando: + self.options.plando_connections.value = () if self.options.plando_connections: + def replace_connection(old_cxn: PlandoConnection, new_cxn: PlandoConnection, index: int) -> None: + self.options.plando_connections.value.remove(old_cxn) + self.options.plando_connections.value.insert(index, new_cxn) + for index, cxn in enumerate(self.options.plando_connections): - # making shops second to simplify other things later - if cxn.entrance.startswith("Shop"): - replacement = PlandoConnection(cxn.exit, "Shop Portal", "both") - self.options.plando_connections.value.remove(cxn) - self.options.plando_connections.value.insert(index, replacement) - elif cxn.exit.startswith("Shop"): - replacement = PlandoConnection(cxn.entrance, "Shop Portal", "both") - self.options.plando_connections.value.remove(cxn) - self.options.plando_connections.value.insert(index, replacement) + replacement = None + if self.options.decoupled: + # flip any that are pointing to exit to point to entrance so that I don't have to deal with it + if cxn.direction == "exit": + replacement = PlandoConnection(cxn.exit, cxn.entrance, "entrance", cxn.percentage) + # if decoupled is on and you plando'd an entrance to itself but left the direction as both + if cxn.direction == "both" and cxn.entrance == cxn.exit: + replacement = PlandoConnection(cxn.entrance, cxn.exit, "entrance") + # if decoupled is off, just convert these to both + elif cxn.direction != "both": + replacement = PlandoConnection(cxn.entrance, cxn.exit, "both", cxn.percentage) + + if replacement: + replace_connection(cxn, replacement, index) + + if (self.options.entrance_layout == EntranceLayout.option_direction_pairs + and not verify_plando_directions(cxn)): + raise OptionError(f"TUNIC: Player {self.player_name} has invalid plando connections. " + f"They have Direction Pairs enabled and the connection " + f"{cxn.entrance} --> {cxn.exit} does not abide by this option.") # Universal tracker stuff, shouldn't do anything in standard gen if hasattr(self.multiworld, "re_gen_passthrough"): @@ -160,16 +172,16 @@ def generate_early(self) -> None: self.options.hexagon_quest_ability_type.value = self.passthrough.get("hexagon_quest_ability_type", 0) self.options.entrance_rando.value = self.passthrough["entrance_rando"] self.options.shuffle_ladders.value = self.passthrough["shuffle_ladders"] + self.options.entrance_layout.value = EntranceLayout.option_standard + if ("ziggurat2020_3, ziggurat2020_1_zig2_skip" in self.passthrough["Entrance Rando"].keys() + or "ziggurat2020_3, ziggurat2020_1_zig2_skip" in self.passthrough["Entrance Rando"].values()): + self.options.entrance_layout.value = EntranceLayout.option_fixed_shop + self.options.decoupled = self.passthrough.get("decoupled", 0) + self.options.laurels_location.value = LaurelsLocation.option_anywhere self.options.grass_randomizer.value = self.passthrough.get("grass_randomizer", 0) self.options.breakable_shuffle.value = self.passthrough.get("breakable_shuffle", 0) self.options.laurels_location.value = self.options.laurels_location.option_anywhere - self.options.combat_logic.value = self.passthrough["combat_logic"] - - self.options.fixed_shop.value = self.options.fixed_shop.option_false - if ("ziggurat2020_3, ziggurat2020_1_zig2_skip" in self.passthrough["Entrance Rando"].keys() - or "ziggurat2020_3, ziggurat2020_1_zig2_skip" in self.passthrough["Entrance Rando"].values()): - self.options.fixed_shop.value = self.options.fixed_shop.option_true - + self.options.combat_logic.value = self.passthrough.get("combat_logic", 0) else: self.using_ut = False else: @@ -227,10 +239,14 @@ def stage_generate_early(cls, multiworld: MultiWorld) -> None: ice_grappling=tunic.options.ice_grappling.value, ladder_storage=tunic.options.ladder_storage.value, laurels_at_10_fairies=tunic.options.laurels_location == LaurelsLocation.option_10_fairies, - fixed_shop=bool(tunic.options.fixed_shop), - plando=tunic.options.plando_connections) + entrance_layout=tunic.options.entrance_layout.value, + has_decoupled_enabled=bool(tunic.options.decoupled), + plando=tunic.options.plando_connections.value.copy()) continue - + # I feel that syncing this one is worse than erroring out + if bool(tunic.options.decoupled) != cls.seed_groups[group]["has_decoupled_enabled"]: + raise OptionError(f"TUNIC: All players in the seed group {group} must " + f"have Decoupled either enabled or disabled.") # off is more restrictive if not tunic.options.laurels_zips: cls.seed_groups[group]["laurels_zips"] = False @@ -243,34 +259,52 @@ def stage_generate_early(cls, multiworld: MultiWorld) -> None: # laurels at 10 fairies changes logic for secret gathering place placement if tunic.options.laurels_location == 3: cls.seed_groups[group]["laurels_at_10_fairies"] = True - # more restrictive, overrides the option for others in the same group, which is better than failing imo - if tunic.options.fixed_shop: - cls.seed_groups[group]["fixed_shop"] = True - + # fixed shop and direction pairs override standard, but conflict with each other + if tunic.options.entrance_layout: + if cls.seed_groups[group]["entrance_layout"] == EntranceLayout.option_standard: + cls.seed_groups[group]["entrance_layout"] = tunic.options.entrance_layout.value + elif cls.seed_groups[group]["entrance_layout"] != tunic.options.entrance_layout.value: + raise OptionError(f"TUNIC: Conflict between seed group {group}'s Entrance Layout options. " + f"Seed group cannot have both Fixed Shop and Direction Pairs enabled.") if tunic.options.plando_connections: # loop through the connections in the player's yaml - for cxn in tunic.options.plando_connections: + for index, player_cxn in enumerate(tunic.options.plando_connections): new_cxn = True for group_cxn in cls.seed_groups[group]["plando"]: - # if neither entrance nor exit match anything in the group, add to group - if ((cxn.entrance == group_cxn.entrance and cxn.exit == group_cxn.exit) - or (cxn.exit == group_cxn.entrance and cxn.entrance == group_cxn.exit)): + # verify that it abides by direction pairs if enabled + if (cls.seed_groups[group]["entrance_layout"] == EntranceLayout.option_direction_pairs + and not verify_plando_directions(player_cxn)): + player_dir = "<->" if player_cxn.direction == "both" else "-->" + raise Exception(f"TUNIC: Conflict between Entrance Layout option and Plando Connection: " + f"{player_cxn.entrance} {player_dir} {player_cxn.exit}") + # check if this pair is the same as a pair in the group already + if ((player_cxn.entrance == group_cxn.entrance and player_cxn.exit == group_cxn.exit) + or (player_cxn.entrance == group_cxn.exit and player_cxn.exit == group_cxn.entrance + and "both" in [player_cxn.direction, group_cxn.direction])): new_cxn = False + # if the group's was one-way and the player's was two-way, we replace the group's now + if player_cxn.direction == "both" and group_cxn.direction == "entrance": + cls.seed_groups[group]["plando"].remove(group_cxn) + cls.seed_groups[group]["plando"].insert(index, player_cxn) break - - # check if this pair is the same as a pair in the group already is_mismatched = ( - cxn.entrance == group_cxn.entrance and cxn.exit != group_cxn.exit - or cxn.entrance == group_cxn.exit and cxn.exit != group_cxn.entrance - or cxn.exit == group_cxn.entrance and cxn.entrance != group_cxn.exit - or cxn.exit == group_cxn.exit and cxn.entrance != group_cxn.entrance + player_cxn.entrance == group_cxn.entrance and player_cxn.exit != group_cxn.exit + or player_cxn.exit == group_cxn.exit and player_cxn.entrance != group_cxn.entrance ) + if not tunic.options.decoupled: + is_mismatched = is_mismatched or ( + player_cxn.entrance == group_cxn.exit and player_cxn.exit != group_cxn.entrance + or player_cxn.exit == group_cxn.entrance and player_cxn.entrance != group_cxn.exit + ) if is_mismatched: - raise Exception(f"TUNIC: Conflict between seed group {group}'s plando " - f"connection {group_cxn.entrance} <-> {group_cxn.exit} and " - f"{tunic.player_name}'s plando connection {cxn.entrance} <-> {cxn.exit}") + group_dir = "<->" if group_cxn.direction == "both" else "-->" + player_dir = "<->" if player_cxn.direction == "both" else "-->" + raise OptionError(f"TUNIC: Conflict between seed group {group}'s plando " + f"connection {group_cxn.entrance} {group_dir} {group_cxn.exit} and " + f"{tunic.player_name}'s plando connection " + f"{player_cxn.entrance} {player_dir} {player_cxn.exit}") if new_cxn: - cls.seed_groups[group]["plando"].value.append(cxn) + cls.seed_groups[group]["plando"].append(player_cxn) def create_item(self, name: str, classification: ItemClassification = None) -> TunicItem: item_data = item_table[name] @@ -571,7 +605,7 @@ def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]) -> None: all_state = self.multiworld.get_all_state(True) all_state.update_reachable_regions(self.player) paths = all_state.path - portal_names = [portal.name for portal in portal_mapping] + portal_names = {portal.name for portal in portal_mapping}.union({f"Shop Portal {i + 1}" for i in range(500)}) for location in self.multiworld.get_locations(self.player): # skipping event locations if not location.address: @@ -630,6 +664,7 @@ def fill_slot_data(self) -> Dict[str, Any]: "lanternless": self.options.lanternless.value, "maskless": self.options.maskless.value, "entrance_rando": int(bool(self.options.entrance_rando.value)), + "decoupled": self.options.decoupled.value if self.options.entrance_rando else 0, "shuffle_ladders": self.options.shuffle_ladders.value, "grass_randomizer": self.options.grass_randomizer.value, "combat_logic": self.options.combat_logic.value, diff --git a/worlds/tunic/combat_logic.py b/worlds/tunic/combat_logic.py index 2e9f19dbc296..dbf1e8640ff2 100644 --- a/worlds/tunic/combat_logic.py +++ b/worlds/tunic/combat_logic.py @@ -22,6 +22,7 @@ class AreaStats(NamedTuple): # the vanilla upgrades/equipment you would have area_data: Dict[str, AreaStats] = { + # The upgrade page is right by the Well entrance. Upper Overworld by the chest in the top right might need something "Overworld": AreaStats(1, 1, 1, 1, 1, 1, 0, ["Stick"]), "East Forest": AreaStats(1, 1, 1, 1, 1, 1, 0, ["Sword"]), "Before Well": AreaStats(1, 1, 1, 1, 1, 1, 3, ["Sword", "Shield"]), diff --git a/worlds/tunic/docs/en_TUNIC.md b/worlds/tunic/docs/en_TUNIC.md index 610c7edf481b..0b85772636c5 100644 --- a/worlds/tunic/docs/en_TUNIC.md +++ b/worlds/tunic/docs/en_TUNIC.md @@ -83,7 +83,7 @@ Notes: - The Entrance Randomizer option must be enabled for it to work. - The `direction` field is not supported. Connections are always coupled. - For a list of entrance names, check `er_data.py` in the TUNIC world folder or generate a game with the Entrance Randomizer option enabled and check the spoiler log. -- There is no limit to the number of Shops you can plando. +- You can plando up to 500 additional shops in Decoupled. You should not do this. See the [Archipelago Plando Guide](../../../tutorial/Archipelago/plando/en) for more information on Plando and Connection Plando. diff --git a/worlds/tunic/er_data.py b/worlds/tunic/er_data.py index 0b3a16167a87..744326aa2060 100644 --- a/worlds/tunic/er_data.py +++ b/worlds/tunic/er_data.py @@ -1,15 +1,28 @@ -from typing import Dict, NamedTuple, List, TYPE_CHECKING, Optional +from typing import Dict, NamedTuple, List, Optional, TYPE_CHECKING from enum import IntEnum if TYPE_CHECKING: from . import TunicWorld +# the direction you go to enter a portal +class Direction(IntEnum): + none = 0 # for when the direction isn't relevant + north = 1 + south = 2 + east = 3 + west = 4 + floor = 5 + ladder_up = 6 + ladder_down = 7 + + class Portal(NamedTuple): name: str # human-readable name region: str # AP region destination: str # vanilla destination scene tag: str # vanilla tag + direction: int # the direction you go to enter a portal def scene(self) -> str: # the actual scene name in Tunic if self.region.startswith("Shop"): @@ -25,497 +38,497 @@ def destination_scene(self) -> str: # the vanilla connection portal_mapping: List[Portal] = [ Portal(name="Stick House Entrance", region="Overworld", - destination="Sword Cave", tag="_"), + destination="Sword Cave", tag="_", direction=Direction.north), Portal(name="Windmill Entrance", region="Overworld", - destination="Windmill", tag="_"), + destination="Windmill", tag="_", direction=Direction.north), Portal(name="Well Ladder Entrance", region="Overworld Well Ladder", - destination="Sewer", tag="_entrance"), + destination="Sewer", tag="_entrance", direction=Direction.ladder_down), Portal(name="Entrance to Well from Well Rail", region="Overworld Well to Furnace Rail", - destination="Sewer", tag="_west_aqueduct"), + destination="Sewer", tag="_west_aqueduct", direction=Direction.north), Portal(name="Old House Door Entrance", region="Overworld Old House Door", - destination="Overworld Interiors", tag="_house"), + destination="Overworld Interiors", tag="_house", direction=Direction.east), Portal(name="Old House Waterfall Entrance", region="Overworld", - destination="Overworld Interiors", tag="_under_checkpoint"), + destination="Overworld Interiors", tag="_under_checkpoint", direction=Direction.east), Portal(name="Entrance to Furnace from Well Rail", region="Overworld Well to Furnace Rail", - destination="Furnace", tag="_gyro_upper_north"), + destination="Furnace", tag="_gyro_upper_north", direction=Direction.south), Portal(name="Entrance to Furnace under Windmill", region="Overworld", - destination="Furnace", tag="_gyro_upper_east"), + destination="Furnace", tag="_gyro_upper_east", direction=Direction.west), Portal(name="Entrance to Furnace near West Garden", region="Overworld to West Garden from Furnace", - destination="Furnace", tag="_gyro_west"), + destination="Furnace", tag="_gyro_west", direction=Direction.east), Portal(name="Entrance to Furnace from Beach", region="Overworld Tunnel Turret", - destination="Furnace", tag="_gyro_lower"), + destination="Furnace", tag="_gyro_lower", direction=Direction.north), Portal(name="Caustic Light Cave Entrance", region="Overworld Swamp Lower Entry", - destination="Overworld Cave", tag="_"), + destination="Overworld Cave", tag="_", direction=Direction.north), Portal(name="Swamp Upper Entrance", region="Overworld Swamp Upper Entry", - destination="Swamp Redux 2", tag="_wall"), + destination="Swamp Redux 2", tag="_wall", direction=Direction.south), Portal(name="Swamp Lower Entrance", region="Overworld Swamp Lower Entry", - destination="Swamp Redux 2", tag="_conduit"), + destination="Swamp Redux 2", tag="_conduit", direction=Direction.south), Portal(name="Ruined Passage Not-Door Entrance", region="After Ruined Passage", - destination="Ruins Passage", tag="_east"), + destination="Ruins Passage", tag="_east", direction=Direction.north), Portal(name="Ruined Passage Door Entrance", region="Overworld Ruined Passage Door", - destination="Ruins Passage", tag="_west"), + destination="Ruins Passage", tag="_west", direction=Direction.east), Portal(name="Atoll Upper Entrance", region="Overworld to Atoll Upper", - destination="Atoll Redux", tag="_upper"), + destination="Atoll Redux", tag="_upper", direction=Direction.south), Portal(name="Atoll Lower Entrance", region="Overworld Beach", - destination="Atoll Redux", tag="_lower"), + destination="Atoll Redux", tag="_lower", direction=Direction.south), Portal(name="Special Shop Entrance", region="Overworld Special Shop Entry", - destination="ShopSpecial", tag="_"), + destination="ShopSpecial", tag="_", direction=Direction.east), Portal(name="Maze Cave Entrance", region="Overworld Beach", - destination="Maze Room", tag="_"), + destination="Maze Room", tag="_", direction=Direction.north), Portal(name="West Garden Entrance near Belltower", region="Overworld to West Garden Upper", - destination="Archipelagos Redux", tag="_upper"), + destination="Archipelagos Redux", tag="_upper", direction=Direction.west), Portal(name="West Garden Entrance from Furnace", region="Overworld to West Garden from Furnace", - destination="Archipelagos Redux", tag="_lower"), + destination="Archipelagos Redux", tag="_lower", direction=Direction.west), Portal(name="West Garden Laurels Entrance", region="Overworld West Garden Laurels Entry", - destination="Archipelagos Redux", tag="_lowest"), + destination="Archipelagos Redux", tag="_lowest", direction=Direction.west), Portal(name="Temple Door Entrance", region="Overworld Temple Door", - destination="Temple", tag="_main"), + destination="Temple", tag="_main", direction=Direction.north), Portal(name="Temple Rafters Entrance", region="Overworld after Temple Rafters", - destination="Temple", tag="_rafters"), + destination="Temple", tag="_rafters", direction=Direction.east), Portal(name="Ruined Shop Entrance", region="Overworld", - destination="Ruined Shop", tag="_"), + destination="Ruined Shop", tag="_", direction=Direction.east), Portal(name="Patrol Cave Entrance", region="Overworld at Patrol Cave", - destination="PatrolCave", tag="_"), + destination="PatrolCave", tag="_", direction=Direction.north), Portal(name="Hourglass Cave Entrance", region="Overworld Beach", - destination="Town Basement", tag="_beach"), + destination="Town Basement", tag="_beach", direction=Direction.north), Portal(name="Changing Room Entrance", region="Overworld", - destination="Changing Room", tag="_"), + destination="Changing Room", tag="_", direction=Direction.south), Portal(name="Cube Cave Entrance", region="Cube Cave Entrance Region", - destination="CubeRoom", tag="_"), + destination="CubeRoom", tag="_", direction=Direction.north), Portal(name="Stairs from Overworld to Mountain", region="Upper Overworld", - destination="Mountain", tag="_"), + destination="Mountain", tag="_", direction=Direction.north), Portal(name="Overworld to Fortress", region="East Overworld", - destination="Fortress Courtyard", tag="_"), + destination="Fortress Courtyard", tag="_", direction=Direction.east), Portal(name="Fountain HC Door Entrance", region="Overworld Fountain Cross Door", - destination="Town_FiligreeRoom", tag="_"), + destination="Town_FiligreeRoom", tag="_", direction=Direction.north), Portal(name="Southeast HC Door Entrance", region="Overworld Southeast Cross Door", - destination="EastFiligreeCache", tag="_"), + destination="EastFiligreeCache", tag="_", direction=Direction.north), Portal(name="Overworld to Quarry Connector", region="Overworld Quarry Entry", - destination="Darkwoods Tunnel", tag="_"), + destination="Darkwoods Tunnel", tag="_", direction=Direction.north), Portal(name="Dark Tomb Main Entrance", region="Overworld", - destination="Crypt Redux", tag="_"), + destination="Crypt Redux", tag="_", direction=Direction.north), Portal(name="Overworld to Forest Belltower", region="East Overworld", - destination="Forest Belltower", tag="_"), + destination="Forest Belltower", tag="_", direction=Direction.east), Portal(name="Town to Far Shore", region="Overworld Town Portal", - destination="Transit", tag="_teleporter_town"), + destination="Transit", tag="_teleporter_town", direction=Direction.floor), Portal(name="Spawn to Far Shore", region="Overworld Spawn Portal", - destination="Transit", tag="_teleporter_starting island"), + destination="Transit", tag="_teleporter_starting island", direction=Direction.floor), Portal(name="Secret Gathering Place Entrance", region="Overworld", - destination="Waterfall", tag="_"), - + destination="Waterfall", tag="_", direction=Direction.north), + Portal(name="Secret Gathering Place Exit", region="Secret Gathering Place", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.south), + Portal(name="Windmill Exit", region="Windmill", - destination="Overworld Redux", tag="_"), + destination="Overworld Redux", tag="_", direction=Direction.south), Portal(name="Windmill Shop", region="Windmill", - destination="Shop", tag="_"), - + destination="Shop", tag="_", direction=Direction.north), + Portal(name="Old House Door Exit", region="Old House Front", - destination="Overworld Redux", tag="_house"), + destination="Overworld Redux", tag="_house", direction=Direction.west), Portal(name="Old House to Glyph Tower", region="Old House Front", - destination="g_elements", tag="_"), + destination="g_elements", tag="_", direction=Direction.south), # portal drops you on north side Portal(name="Old House Waterfall Exit", region="Old House Back", - destination="Overworld Redux", tag="_under_checkpoint"), - + destination="Overworld Redux", tag="_under_checkpoint", direction=Direction.west), + Portal(name="Glyph Tower Exit", region="Relic Tower", - destination="Overworld Interiors", tag="_"), - + destination="Overworld Interiors", tag="_", direction=Direction.north), + Portal(name="Changing Room Exit", region="Changing Room", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.north), + Portal(name="Fountain HC Room Exit", region="Fountain Cross Room", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.south), + Portal(name="Cube Cave Exit", region="Cube Cave", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.south), + Portal(name="Guard Patrol Cave Exit", region="Patrol Cave", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.south), + Portal(name="Ruined Shop Exit", region="Ruined Shop", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.west), + Portal(name="Furnace Exit towards Well", region="Furnace Fuse", - destination="Overworld Redux", tag="_gyro_upper_north"), + destination="Overworld Redux", tag="_gyro_upper_north", direction=Direction.north), Portal(name="Furnace Exit to Dark Tomb", region="Furnace Walking Path", - destination="Crypt Redux", tag="_"), + destination="Crypt Redux", tag="_", direction=Direction.east), Portal(name="Furnace Exit towards West Garden", region="Furnace Walking Path", - destination="Overworld Redux", tag="_gyro_west"), + destination="Overworld Redux", tag="_gyro_west", direction=Direction.west), Portal(name="Furnace Exit to Beach", region="Furnace Ladder Area", - destination="Overworld Redux", tag="_gyro_lower"), + destination="Overworld Redux", tag="_gyro_lower", direction=Direction.south), Portal(name="Furnace Exit under Windmill", region="Furnace Ladder Area", - destination="Overworld Redux", tag="_gyro_upper_east"), - + destination="Overworld Redux", tag="_gyro_upper_east", direction=Direction.east), + Portal(name="Stick House Exit", region="Stick House", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.south), + Portal(name="Ruined Passage Not-Door Exit", region="Ruined Passage", - destination="Overworld Redux", tag="_east"), + destination="Overworld Redux", tag="_east", direction=Direction.south), Portal(name="Ruined Passage Door Exit", region="Ruined Passage", - destination="Overworld Redux", tag="_west"), - + destination="Overworld Redux", tag="_west", direction=Direction.west), + Portal(name="Southeast HC Room Exit", region="Southeast Cross Room", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.south), + Portal(name="Caustic Light Cave Exit", region="Caustic Light Cave", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.south), + Portal(name="Maze Cave Exit", region="Maze Cave", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.south), + Portal(name="Hourglass Cave Exit", region="Hourglass Cave", - destination="Overworld Redux", tag="_beach"), - + destination="Overworld Redux", tag="_beach", direction=Direction.south), + Portal(name="Special Shop Exit", region="Special Shop", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.west), + Portal(name="Temple Rafters Exit", region="Sealed Temple Rafters", - destination="Overworld Redux", tag="_rafters"), + destination="Overworld Redux", tag="_rafters", direction=Direction.west), Portal(name="Temple Door Exit", region="Sealed Temple", - destination="Overworld Redux", tag="_main"), + destination="Overworld Redux", tag="_main", direction=Direction.south), Portal(name="Forest Belltower to Fortress", region="Forest Belltower Main behind bushes", - destination="Fortress Courtyard", tag="_"), + destination="Fortress Courtyard", tag="_", direction=Direction.north), Portal(name="Forest Belltower to Forest", region="Forest Belltower Lower", - destination="East Forest Redux", tag="_"), + destination="East Forest Redux", tag="_", direction=Direction.south), Portal(name="Forest Belltower to Overworld", region="Forest Belltower Main", - destination="Overworld Redux", tag="_"), + destination="Overworld Redux", tag="_", direction=Direction.west), Portal(name="Forest Belltower to Guard Captain Room", region="Forest Belltower Upper", - destination="Forest Boss Room", tag="_"), + destination="Forest Boss Room", tag="_", direction=Direction.south), Portal(name="Forest to Belltower", region="East Forest", - destination="Forest Belltower", tag="_"), + destination="Forest Belltower", tag="_", direction=Direction.north), Portal(name="Forest Guard House 1 Lower Entrance", region="East Forest", - destination="East Forest Redux Laddercave", tag="_lower"), + destination="East Forest Redux Laddercave", tag="_lower", direction=Direction.north), Portal(name="Forest Guard House 1 Gate Entrance", region="East Forest", - destination="East Forest Redux Laddercave", tag="_gate"), + destination="East Forest Redux Laddercave", tag="_gate", direction=Direction.north), Portal(name="Forest Dance Fox Outside Doorway", region="East Forest Dance Fox Spot", - destination="East Forest Redux Laddercave", tag="_upper"), + destination="East Forest Redux Laddercave", tag="_upper", direction=Direction.east), Portal(name="Forest to Far Shore", region="East Forest Portal", - destination="Transit", tag="_teleporter_forest teleporter"), + destination="Transit", tag="_teleporter_forest teleporter", direction=Direction.floor), Portal(name="Forest Guard House 2 Lower Entrance", region="Lower Forest", - destination="East Forest Redux Interior", tag="_lower"), + destination="East Forest Redux Interior", tag="_lower", direction=Direction.north), Portal(name="Forest Guard House 2 Upper Entrance", region="East Forest", - destination="East Forest Redux Interior", tag="_upper"), + destination="East Forest Redux Interior", tag="_upper", direction=Direction.east), Portal(name="Forest Grave Path Lower Entrance", region="East Forest", - destination="Sword Access", tag="_lower"), + destination="Sword Access", tag="_lower", direction=Direction.east), Portal(name="Forest Grave Path Upper Entrance", region="East Forest", - destination="Sword Access", tag="_upper"), + destination="Sword Access", tag="_upper", direction=Direction.east), Portal(name="Forest Grave Path Upper Exit", region="Forest Grave Path Upper", - destination="East Forest Redux", tag="_upper"), + destination="East Forest Redux", tag="_upper", direction=Direction.west), Portal(name="Forest Grave Path Lower Exit", region="Forest Grave Path Main", - destination="East Forest Redux", tag="_lower"), + destination="East Forest Redux", tag="_lower", direction=Direction.west), Portal(name="East Forest Hero's Grave", region="Forest Hero's Grave", - destination="RelicVoid", tag="_teleporter_relic plinth"), + destination="RelicVoid", tag="_teleporter_relic plinth", direction=Direction.floor), Portal(name="Guard House 1 Dance Fox Exit", region="Guard House 1 West", - destination="East Forest Redux", tag="_upper"), + destination="East Forest Redux", tag="_upper", direction=Direction.west), Portal(name="Guard House 1 Lower Exit", region="Guard House 1 West", - destination="East Forest Redux", tag="_lower"), + destination="East Forest Redux", tag="_lower", direction=Direction.south), Portal(name="Guard House 1 Upper Forest Exit", region="Guard House 1 East", - destination="East Forest Redux", tag="_gate"), + destination="East Forest Redux", tag="_gate", direction=Direction.south), Portal(name="Guard House 1 to Guard Captain Room", region="Guard House 1 East", - destination="Forest Boss Room", tag="_"), + destination="Forest Boss Room", tag="_", direction=Direction.north), Portal(name="Guard House 2 Lower Exit", region="Guard House 2 Lower", - destination="East Forest Redux", tag="_lower"), + destination="East Forest Redux", tag="_lower", direction=Direction.south), Portal(name="Guard House 2 Upper Exit", region="Guard House 2 Upper before bushes", - destination="East Forest Redux", tag="_upper"), + destination="East Forest Redux", tag="_upper", direction=Direction.west), Portal(name="Guard Captain Room Non-Gate Exit", region="Forest Boss Room", - destination="East Forest Redux Laddercave", tag="_"), + destination="East Forest Redux Laddercave", tag="_", direction=Direction.south), Portal(name="Guard Captain Room Gate Exit", region="Forest Boss Room", - destination="Forest Belltower", tag="_"), + destination="Forest Belltower", tag="_", direction=Direction.north), Portal(name="Well Ladder Exit", region="Beneath the Well Ladder Exit", - destination="Overworld Redux", tag="_entrance"), + destination="Overworld Redux", tag="_entrance", direction=Direction.ladder_up), Portal(name="Well to Well Boss", region="Beneath the Well Back", - destination="Sewer_Boss", tag="_"), + destination="Sewer_Boss", tag="_", direction=Direction.east), Portal(name="Well Exit towards Furnace", region="Beneath the Well Back", - destination="Overworld Redux", tag="_west_aqueduct"), + destination="Overworld Redux", tag="_west_aqueduct", direction=Direction.south), Portal(name="Well Boss to Well", region="Well Boss", - destination="Sewer", tag="_"), + destination="Sewer", tag="_", direction=Direction.west), Portal(name="Checkpoint to Dark Tomb", region="Dark Tomb Checkpoint", - destination="Crypt Redux", tag="_"), + destination="Crypt Redux", tag="_", direction=Direction.ladder_up), Portal(name="Dark Tomb to Overworld", region="Dark Tomb Entry Point", - destination="Overworld Redux", tag="_"), + destination="Overworld Redux", tag="_", direction=Direction.south), Portal(name="Dark Tomb to Furnace", region="Dark Tomb Dark Exit", - destination="Furnace", tag="_"), + destination="Furnace", tag="_", direction=Direction.west), Portal(name="Dark Tomb to Checkpoint", region="Dark Tomb Entry Point", - destination="Sewer_Boss", tag="_"), - + destination="Sewer_Boss", tag="_", direction=Direction.ladder_down), + Portal(name="West Garden Exit near Hero's Grave", region="West Garden before Terry", - destination="Overworld Redux", tag="_lower"), + destination="Overworld Redux", tag="_lower", direction=Direction.east), Portal(name="West Garden to Magic Dagger House", region="West Garden at Dagger House", - destination="archipelagos_house", tag="_"), + destination="archipelagos_house", tag="_", direction=Direction.east), Portal(name="West Garden Exit after Boss", region="West Garden after Boss", - destination="Overworld Redux", tag="_upper"), + destination="Overworld Redux", tag="_upper", direction=Direction.east), Portal(name="West Garden Shop", region="West Garden before Terry", - destination="Shop", tag="_"), + destination="Shop", tag="_", direction=Direction.east), Portal(name="West Garden Laurels Exit", region="West Garden Laurels Exit Region", - destination="Overworld Redux", tag="_lowest"), + destination="Overworld Redux", tag="_lowest", direction=Direction.east), Portal(name="West Garden Hero's Grave", region="West Garden Hero's Grave Region", - destination="RelicVoid", tag="_teleporter_relic plinth"), + destination="RelicVoid", tag="_teleporter_relic plinth", direction=Direction.floor), Portal(name="West Garden to Far Shore", region="West Garden Portal", - destination="Transit", tag="_teleporter_archipelagos_teleporter"), + destination="Transit", tag="_teleporter_archipelagos_teleporter", direction=Direction.floor), Portal(name="Magic Dagger House Exit", region="Magic Dagger House", - destination="Archipelagos Redux", tag="_"), + destination="Archipelagos Redux", tag="_", direction=Direction.west), Portal(name="Fortress Courtyard to Fortress Grave Path Lower", region="Fortress Courtyard", - destination="Fortress Reliquary", tag="_Lower"), + destination="Fortress Reliquary", tag="_Lower", direction=Direction.east), Portal(name="Fortress Courtyard to Fortress Grave Path Upper", region="Fortress Courtyard Upper", - destination="Fortress Reliquary", tag="_Upper"), + destination="Fortress Reliquary", tag="_Upper", direction=Direction.east), Portal(name="Fortress Courtyard to Fortress Interior", region="Fortress Courtyard", - destination="Fortress Main", tag="_Big Door"), + destination="Fortress Main", tag="_Big Door", direction=Direction.north), Portal(name="Fortress Courtyard to East Fortress", region="Fortress Courtyard Upper", - destination="Fortress East", tag="_"), + destination="Fortress East", tag="_", direction=Direction.north), Portal(name="Fortress Courtyard to Beneath the Vault", region="Beneath the Vault Entry", - destination="Fortress Basement", tag="_"), + destination="Fortress Basement", tag="_", direction=Direction.ladder_down), Portal(name="Fortress Courtyard to Forest Belltower", region="Fortress Exterior from East Forest", - destination="Forest Belltower", tag="_"), + destination="Forest Belltower", tag="_", direction=Direction.south), Portal(name="Fortress Courtyard to Overworld", region="Fortress Exterior from Overworld", - destination="Overworld Redux", tag="_"), + destination="Overworld Redux", tag="_", direction=Direction.west), Portal(name="Fortress Courtyard Shop", region="Fortress Exterior near cave", - destination="Shop", tag="_"), + destination="Shop", tag="_", direction=Direction.north), Portal(name="Beneath the Vault to Fortress Interior", region="Beneath the Vault Back", - destination="Fortress Main", tag="_"), + destination="Fortress Main", tag="_", direction=Direction.east), Portal(name="Beneath the Vault to Fortress Courtyard", region="Beneath the Vault Ladder Exit", - destination="Fortress Courtyard", tag="_"), + destination="Fortress Courtyard", tag="_", direction=Direction.ladder_up), Portal(name="Fortress Interior Main Exit", region="Eastern Vault Fortress", - destination="Fortress Courtyard", tag="_Big Door"), + destination="Fortress Courtyard", tag="_Big Door", direction=Direction.south), Portal(name="Fortress Interior to Beneath the Earth", region="Eastern Vault Fortress", - destination="Fortress Basement", tag="_"), + destination="Fortress Basement", tag="_", direction=Direction.west), Portal(name="Fortress Interior to Siege Engine Arena", region="Eastern Vault Fortress Gold Door", - destination="Fortress Arena", tag="_"), + destination="Fortress Arena", tag="_", direction=Direction.north), Portal(name="Fortress Interior Shop", region="Eastern Vault Fortress", - destination="Shop", tag="_"), + destination="Shop", tag="_", direction=Direction.north), Portal(name="Fortress Interior to East Fortress Upper", region="Eastern Vault Fortress", - destination="Fortress East", tag="_upper"), + destination="Fortress East", tag="_upper", direction=Direction.east), Portal(name="Fortress Interior to East Fortress Lower", region="Eastern Vault Fortress", - destination="Fortress East", tag="_lower"), + destination="Fortress East", tag="_lower", direction=Direction.east), Portal(name="East Fortress to Interior Lower", region="Fortress East Shortcut Lower", - destination="Fortress Main", tag="_lower"), + destination="Fortress Main", tag="_lower", direction=Direction.west), Portal(name="East Fortress to Courtyard", region="Fortress East Shortcut Upper", - destination="Fortress Courtyard", tag="_"), + destination="Fortress Courtyard", tag="_", direction=Direction.south), Portal(name="East Fortress to Interior Upper", region="Fortress East Shortcut Upper", - destination="Fortress Main", tag="_upper"), + destination="Fortress Main", tag="_upper", direction=Direction.west), Portal(name="Fortress Grave Path Lower Exit", region="Fortress Grave Path Entry", - destination="Fortress Courtyard", tag="_Lower"), + destination="Fortress Courtyard", tag="_Lower", direction=Direction.west), Portal(name="Fortress Hero's Grave", region="Fortress Hero's Grave Region", - destination="RelicVoid", tag="_teleporter_relic plinth"), + destination="RelicVoid", tag="_teleporter_relic plinth", direction=Direction.floor), Portal(name="Fortress Grave Path Upper Exit", region="Fortress Grave Path Upper", - destination="Fortress Courtyard", tag="_Upper"), + destination="Fortress Courtyard", tag="_Upper", direction=Direction.west), Portal(name="Fortress Grave Path Dusty Entrance", region="Fortress Grave Path Dusty Entrance Region", - destination="Dusty", tag="_"), + destination="Dusty", tag="_", direction=Direction.north), Portal(name="Dusty Exit", region="Fortress Leaf Piles", - destination="Fortress Reliquary", tag="_"), + destination="Fortress Reliquary", tag="_", direction=Direction.south), Portal(name="Siege Engine Arena to Fortress", region="Fortress Arena", - destination="Fortress Main", tag="_"), + destination="Fortress Main", tag="_", direction=Direction.south), Portal(name="Fortress to Far Shore", region="Fortress Arena Portal", - destination="Transit", tag="_teleporter_spidertank"), + destination="Transit", tag="_teleporter_spidertank", direction=Direction.floor), Portal(name="Atoll Upper Exit", region="Ruined Atoll", - destination="Overworld Redux", tag="_upper"), + destination="Overworld Redux", tag="_upper", direction=Direction.north), Portal(name="Atoll Lower Exit", region="Ruined Atoll Lower Entry Area", - destination="Overworld Redux", tag="_lower"), + destination="Overworld Redux", tag="_lower", direction=Direction.north), Portal(name="Atoll Shop", region="Ruined Atoll", - destination="Shop", tag="_"), + destination="Shop", tag="_", direction=Direction.north), Portal(name="Atoll to Far Shore", region="Ruined Atoll Portal", - destination="Transit", tag="_teleporter_atoll"), + destination="Transit", tag="_teleporter_atoll", direction=Direction.floor), Portal(name="Atoll Statue Teleporter", region="Ruined Atoll Statue", - destination="Library Exterior", tag="_"), + destination="Library Exterior", tag="_", direction=Direction.floor), Portal(name="Frog Stairs Eye Entrance", region="Ruined Atoll Frog Eye", - destination="Frog Stairs", tag="_eye"), + destination="Frog Stairs", tag="_eye", direction=Direction.south), # camera rotates, it's fine Portal(name="Frog Stairs Mouth Entrance", region="Ruined Atoll Frog Mouth", - destination="Frog Stairs", tag="_mouth"), + destination="Frog Stairs", tag="_mouth", direction=Direction.east), Portal(name="Frog Stairs Eye Exit", region="Frog Stairs Eye Exit", - destination="Atoll Redux", tag="_eye"), + destination="Atoll Redux", tag="_eye", direction=Direction.north), Portal(name="Frog Stairs Mouth Exit", region="Frog Stairs Upper", - destination="Atoll Redux", tag="_mouth"), + destination="Atoll Redux", tag="_mouth", direction=Direction.west), Portal(name="Frog Stairs to Frog's Domain's Entrance", region="Frog Stairs to Frog's Domain", - destination="frog cave main", tag="_Entrance"), + destination="frog cave main", tag="_Entrance", direction=Direction.ladder_down), Portal(name="Frog Stairs to Frog's Domain's Exit", region="Frog Stairs Lower", - destination="frog cave main", tag="_Exit"), + destination="frog cave main", tag="_Exit", direction=Direction.east), Portal(name="Frog's Domain Ladder Exit", region="Frog's Domain Entry", - destination="Frog Stairs", tag="_Entrance"), + destination="Frog Stairs", tag="_Entrance", direction=Direction.ladder_up), Portal(name="Frog's Domain Orb Exit", region="Frog's Domain Back", - destination="Frog Stairs", tag="_Exit"), + destination="Frog Stairs", tag="_Exit", direction=Direction.west), Portal(name="Library Exterior Tree", region="Library Exterior Tree Region", - destination="Atoll Redux", tag="_"), + destination="Atoll Redux", tag="_", direction=Direction.floor), Portal(name="Library Exterior Ladder", region="Library Exterior Ladder Region", - destination="Library Hall", tag="_"), + destination="Library Hall", tag="_", direction=Direction.west), # camera rotates Portal(name="Library Hall Bookshelf Exit", region="Library Hall Bookshelf", - destination="Library Exterior", tag="_"), + destination="Library Exterior", tag="_", direction=Direction.east), Portal(name="Library Hero's Grave", region="Library Hero's Grave Region", - destination="RelicVoid", tag="_teleporter_relic plinth"), + destination="RelicVoid", tag="_teleporter_relic plinth", direction=Direction.floor), Portal(name="Library Hall to Rotunda", region="Library Hall to Rotunda", - destination="Library Rotunda", tag="_"), + destination="Library Rotunda", tag="_", direction=Direction.ladder_up), Portal(name="Library Rotunda Lower Exit", region="Library Rotunda to Hall", - destination="Library Hall", tag="_"), + destination="Library Hall", tag="_", direction=Direction.ladder_down), Portal(name="Library Rotunda Upper Exit", region="Library Rotunda to Lab", - destination="Library Lab", tag="_"), + destination="Library Lab", tag="_", direction=Direction.ladder_up), Portal(name="Library Lab to Rotunda", region="Library Lab Lower", - destination="Library Rotunda", tag="_"), + destination="Library Rotunda", tag="_", direction=Direction.ladder_down), Portal(name="Library to Far Shore", region="Library Portal", - destination="Transit", tag="_teleporter_library teleporter"), + destination="Transit", tag="_teleporter_library teleporter", direction=Direction.floor), Portal(name="Library Lab to Librarian Arena", region="Library Lab to Librarian", - destination="Library Arena", tag="_"), + destination="Library Arena", tag="_", direction=Direction.ladder_up), Portal(name="Librarian Arena Exit", region="Library Arena", - destination="Library Lab", tag="_"), + destination="Library Lab", tag="_", direction=Direction.ladder_down), Portal(name="Stairs to Top of the Mountain", region="Lower Mountain Stairs", - destination="Mountaintop", tag="_"), + destination="Mountaintop", tag="_", direction=Direction.north), Portal(name="Mountain to Quarry", region="Lower Mountain", - destination="Quarry Redux", tag="_"), + destination="Quarry Redux", tag="_", direction=Direction.south), # connecting is north Portal(name="Mountain to Overworld", region="Lower Mountain", - destination="Overworld Redux", tag="_"), - + destination="Overworld Redux", tag="_", direction=Direction.south), + Portal(name="Top of the Mountain Exit", region="Top of the Mountain", - destination="Mountain", tag="_"), - + destination="Mountain", tag="_", direction=Direction.south), + Portal(name="Quarry Connector to Overworld", region="Quarry Connector", - destination="Overworld Redux", tag="_"), + destination="Overworld Redux", tag="_", direction=Direction.south), Portal(name="Quarry Connector to Quarry", region="Quarry Connector", - destination="Quarry Redux", tag="_"), - + destination="Quarry Redux", tag="_", direction=Direction.north), # rotates, it's fine + Portal(name="Quarry to Overworld Exit", region="Quarry Entry", - destination="Darkwoods Tunnel", tag="_"), + destination="Darkwoods Tunnel", tag="_", direction=Direction.south), # rotates, it's fine Portal(name="Quarry Shop", region="Quarry Entry", - destination="Shop", tag="_"), + destination="Shop", tag="_", direction=Direction.north), Portal(name="Quarry to Monastery Front", region="Quarry Monastery Entry", - destination="Monastery", tag="_front"), + destination="Monastery", tag="_front", direction=Direction.north), Portal(name="Quarry to Monastery Back", region="Monastery Rope", - destination="Monastery", tag="_back"), + destination="Monastery", tag="_back", direction=Direction.east), Portal(name="Quarry to Mountain", region="Quarry Back", - destination="Mountain", tag="_"), + destination="Mountain", tag="_", direction=Direction.north), Portal(name="Quarry to Ziggurat", region="Lower Quarry Zig Door", - destination="ziggurat2020_0", tag="_"), + destination="ziggurat2020_0", tag="_", direction=Direction.north), Portal(name="Quarry to Far Shore", region="Quarry Portal", - destination="Transit", tag="_teleporter_quarry teleporter"), - + destination="Transit", tag="_teleporter_quarry teleporter", direction=Direction.floor), + Portal(name="Monastery Rear Exit", region="Monastery Back", - destination="Quarry Redux", tag="_back"), + destination="Quarry Redux", tag="_back", direction=Direction.west), Portal(name="Monastery Front Exit", region="Monastery Front", - destination="Quarry Redux", tag="_front"), + destination="Quarry Redux", tag="_front", direction=Direction.south), Portal(name="Monastery Hero's Grave", region="Monastery Hero's Grave Region", - destination="RelicVoid", tag="_teleporter_relic plinth"), - + destination="RelicVoid", tag="_teleporter_relic plinth", direction=Direction.floor), + Portal(name="Ziggurat Entry Hallway to Ziggurat Upper", region="Rooted Ziggurat Entry", - destination="ziggurat2020_1", tag="_"), + destination="ziggurat2020_1", tag="_", direction=Direction.north), Portal(name="Ziggurat Entry Hallway to Quarry", region="Rooted Ziggurat Entry", - destination="Quarry Redux", tag="_"), - + destination="Quarry Redux", tag="_", direction=Direction.south), + Portal(name="Ziggurat Upper to Ziggurat Entry Hallway", region="Rooted Ziggurat Upper Entry", - destination="ziggurat2020_0", tag="_"), + destination="ziggurat2020_0", tag="_", direction=Direction.south), Portal(name="Ziggurat Upper to Ziggurat Tower", region="Rooted Ziggurat Upper Back", - destination="ziggurat2020_2", tag="_"), - + destination="ziggurat2020_2", tag="_", direction=Direction.north), # connecting is south + Portal(name="Ziggurat Tower to Ziggurat Upper", region="Rooted Ziggurat Middle Top", - destination="ziggurat2020_1", tag="_"), + destination="ziggurat2020_1", tag="_", direction=Direction.south), Portal(name="Ziggurat Tower to Ziggurat Lower", region="Rooted Ziggurat Middle Bottom", - destination="ziggurat2020_3", tag="_"), - + destination="ziggurat2020_3", tag="_", direction=Direction.south), + Portal(name="Ziggurat Lower to Ziggurat Tower", region="Rooted Ziggurat Lower Entry", - destination="ziggurat2020_2", tag="_"), + destination="ziggurat2020_2", tag="_", direction=Direction.north), Portal(name="Ziggurat Portal Room Entrance", region="Rooted Ziggurat Portal Room Entrance", - destination="ziggurat2020_FTRoom", tag="_"), + destination="ziggurat2020_FTRoom", tag="_", direction=Direction.north), # only if fixed shop is on, removed otherwise - Portal(name="Ziggurat Lower Falling Entrance", region="Zig Skip Exit", - destination="ziggurat2020_1", tag="_zig2_skip"), - + Portal(name="Ziggurat Lower Falling Entrance", region="Zig Skip Exit", # not a real region + destination="ziggurat2020_1", tag="_zig2_skip", direction=Direction.none), + Portal(name="Ziggurat Portal Room Exit", region="Rooted Ziggurat Portal Room Exit", - destination="ziggurat2020_3", tag="_"), + destination="ziggurat2020_3", tag="_", direction=Direction.south), Portal(name="Ziggurat to Far Shore", region="Rooted Ziggurat Portal", - destination="Transit", tag="_teleporter_ziggurat teleporter"), - + destination="Transit", tag="_teleporter_ziggurat teleporter", direction=Direction.floor), + Portal(name="Swamp Lower Exit", region="Swamp Front", - destination="Overworld Redux", tag="_conduit"), + destination="Overworld Redux", tag="_conduit", direction=Direction.north), Portal(name="Swamp to Cathedral Main Entrance", region="Swamp to Cathedral Main Entrance Region", - destination="Cathedral Redux", tag="_main"), + destination="Cathedral Redux", tag="_main", direction=Direction.north), Portal(name="Swamp to Cathedral Secret Legend Room Entrance", region="Swamp to Cathedral Treasure Room", - destination="Cathedral Redux", tag="_secret"), + destination="Cathedral Redux", tag="_secret", direction=Direction.south), # feels a little weird Portal(name="Swamp to Gauntlet", region="Back of Swamp", - destination="Cathedral Arena", tag="_"), + destination="Cathedral Arena", tag="_", direction=Direction.north), Portal(name="Swamp Shop", region="Swamp Front", - destination="Shop", tag="_"), + destination="Shop", tag="_", direction=Direction.north), Portal(name="Swamp Upper Exit", region="Back of Swamp Laurels Area", - destination="Overworld Redux", tag="_wall"), + destination="Overworld Redux", tag="_wall", direction=Direction.north), Portal(name="Swamp Hero's Grave", region="Swamp Hero's Grave Region", - destination="RelicVoid", tag="_teleporter_relic plinth"), - + destination="RelicVoid", tag="_teleporter_relic plinth", direction=Direction.floor), + Portal(name="Cathedral Main Exit", region="Cathedral Entry", - destination="Swamp Redux 2", tag="_main"), + destination="Swamp Redux 2", tag="_main", direction=Direction.south), Portal(name="Cathedral Elevator", region="Cathedral to Gauntlet", - destination="Cathedral Arena", tag="_"), + destination="Cathedral Arena", tag="_", direction=Direction.ladder_down), # elevators are ladders, right? Portal(name="Cathedral Secret Legend Room Exit", region="Cathedral Secret Legend Room", - destination="Swamp Redux 2", tag="_secret"), - + destination="Swamp Redux 2", tag="_secret", direction=Direction.north), + Portal(name="Gauntlet to Swamp", region="Cathedral Gauntlet Exit", - destination="Swamp Redux 2", tag="_"), + destination="Swamp Redux 2", tag="_", direction=Direction.south), Portal(name="Gauntlet Elevator", region="Cathedral Gauntlet Checkpoint", - destination="Cathedral Redux", tag="_"), + destination="Cathedral Redux", tag="_", direction=Direction.ladder_up), Portal(name="Gauntlet Shop", region="Cathedral Gauntlet Checkpoint", - destination="Shop", tag="_"), - + destination="Shop", tag="_", direction=Direction.east), + Portal(name="Hero's Grave to Fortress", region="Hero Relic - Fortress", - destination="Fortress Reliquary", tag="_teleporter_relic plinth"), + destination="Fortress Reliquary", tag="_teleporter_relic plinth", direction=Direction.floor), Portal(name="Hero's Grave to Monastery", region="Hero Relic - Quarry", - destination="Monastery", tag="_teleporter_relic plinth"), + destination="Monastery", tag="_teleporter_relic plinth", direction=Direction.floor), Portal(name="Hero's Grave to West Garden", region="Hero Relic - West Garden", - destination="Archipelagos Redux", tag="_teleporter_relic plinth"), + destination="Archipelagos Redux", tag="_teleporter_relic plinth", direction=Direction.floor), Portal(name="Hero's Grave to East Forest", region="Hero Relic - East Forest", - destination="Sword Access", tag="_teleporter_relic plinth"), + destination="Sword Access", tag="_teleporter_relic plinth", direction=Direction.floor), Portal(name="Hero's Grave to Library", region="Hero Relic - Library", - destination="Library Hall", tag="_teleporter_relic plinth"), + destination="Library Hall", tag="_teleporter_relic plinth", direction=Direction.floor), Portal(name="Hero's Grave to Swamp", region="Hero Relic - Swamp", - destination="Swamp Redux 2", tag="_teleporter_relic plinth"), - + destination="Swamp Redux 2", tag="_teleporter_relic plinth", direction=Direction.floor), + Portal(name="Far Shore to West Garden", region="Far Shore to West Garden Region", - destination="Archipelagos Redux", tag="_teleporter_archipelagos_teleporter"), + destination="Archipelagos Redux", tag="_teleporter_archipelagos_teleporter", direction=Direction.floor), Portal(name="Far Shore to Library", region="Far Shore to Library Region", - destination="Library Lab", tag="_teleporter_library teleporter"), + destination="Library Lab", tag="_teleporter_library teleporter", direction=Direction.floor), Portal(name="Far Shore to Quarry", region="Far Shore to Quarry Region", - destination="Quarry Redux", tag="_teleporter_quarry teleporter"), + destination="Quarry Redux", tag="_teleporter_quarry teleporter", direction=Direction.floor), Portal(name="Far Shore to East Forest", region="Far Shore to East Forest Region", - destination="East Forest Redux", tag="_teleporter_forest teleporter"), + destination="East Forest Redux", tag="_teleporter_forest teleporter", direction=Direction.floor), Portal(name="Far Shore to Fortress", region="Far Shore to Fortress Region", - destination="Fortress Arena", tag="_teleporter_spidertank"), + destination="Fortress Arena", tag="_teleporter_spidertank", direction=Direction.floor), Portal(name="Far Shore to Atoll", region="Far Shore", - destination="Atoll Redux", tag="_teleporter_atoll"), + destination="Atoll Redux", tag="_teleporter_atoll", direction=Direction.floor), Portal(name="Far Shore to Ziggurat", region="Far Shore", - destination="ziggurat2020_FTRoom", tag="_teleporter_ziggurat teleporter"), + destination="ziggurat2020_FTRoom", tag="_teleporter_ziggurat teleporter", direction=Direction.floor), Portal(name="Far Shore to Heir", region="Far Shore", - destination="Spirit Arena", tag="_teleporter_spirit arena"), + destination="Spirit Arena", tag="_teleporter_spirit arena", direction=Direction.floor), Portal(name="Far Shore to Town", region="Far Shore", - destination="Overworld Redux", tag="_teleporter_town"), + destination="Overworld Redux", tag="_teleporter_town", direction=Direction.floor), Portal(name="Far Shore to Spawn", region="Far Shore to Spawn Region", - destination="Overworld Redux", tag="_teleporter_starting island"), - + destination="Overworld Redux", tag="_teleporter_starting island", direction=Direction.floor), + Portal(name="Heir Arena Exit", region="Spirit Arena", - destination="Transit", tag="_teleporter_spirit arena"), - + destination="Transit", tag="_teleporter_spirit arena", direction=Direction.floor), + Portal(name="Purgatory Bottom Exit", region="Purgatory", - destination="Purgatory", tag="_bottom"), + destination="Purgatory", tag="_bottom", direction=Direction.south), Portal(name="Purgatory Top Exit", region="Purgatory", - destination="Purgatory", tag="_top"), + destination="Purgatory", tag="_top", direction=Direction.north), ] @@ -523,6 +536,7 @@ class RegionInfo(NamedTuple): game_scene: str # the name of the scene in the actual game dead_end: int = 0 # if a region has only one exit outlet_region: Optional[str] = None + is_fake_region: bool = False # gets the outlet region name if it exists, the region if it doesn't @@ -540,9 +554,9 @@ class DeadEnd(IntEnum): # key is the AP region name. "Fake" in region info just means the mod won't receive that info at all tunic_er_regions: Dict[str, RegionInfo] = { - "Menu": RegionInfo("Fake", dead_end=DeadEnd.all_cats), + "Menu": RegionInfo("Fake", dead_end=DeadEnd.all_cats, is_fake_region=True), "Overworld": RegionInfo("Overworld Redux"), # main overworld, the central area - "Overworld Holy Cross": RegionInfo("Fake", dead_end=DeadEnd.all_cats), # main overworld holy cross checks + "Overworld Holy Cross": RegionInfo("Fake", dead_end=DeadEnd.all_cats, is_fake_region=True), # main overworld holy cross checks "Overworld Belltower": RegionInfo("Overworld Redux"), # the area with the belltower and chest "Overworld Belltower at Bell": RegionInfo("Overworld Redux"), # being able to ring the belltower, basically "Overworld Swamp Upper Entry": RegionInfo("Overworld Redux"), # upper swamp entry spot @@ -722,7 +736,7 @@ class DeadEnd(IntEnum): "Rooted Ziggurat Lower Front": RegionInfo("ziggurat2020_3"), # the front for combat logic "Rooted Ziggurat Lower Mid Checkpoint": RegionInfo("ziggurat2020_3"), # the mid-checkpoint before double admin "Rooted Ziggurat Lower Back": RegionInfo("ziggurat2020_3"), # the boss side - "Zig Skip Exit": RegionInfo("ziggurat2020_3", dead_end=DeadEnd.special, outlet_region="Rooted Ziggurat Lower Entry"), # for use with fixed shop on + "Zig Skip Exit": RegionInfo("ziggurat2020_3", dead_end=DeadEnd.special, outlet_region="Rooted Ziggurat Lower Entry", is_fake_region=True), # for use with fixed shop on "Rooted Ziggurat Portal Room Entrance": RegionInfo("ziggurat2020_3", outlet_region="Rooted Ziggurat Lower Back"), # the door itself on the zig 3 side "Rooted Ziggurat Portal": RegionInfo("ziggurat2020_FTRoom", outlet_region="Rooted Ziggurat Portal Room"), "Rooted Ziggurat Portal Room": RegionInfo("ziggurat2020_FTRoom"), @@ -758,7 +772,7 @@ class DeadEnd(IntEnum): "Purgatory": RegionInfo("Purgatory"), "Shop": RegionInfo("Shop", dead_end=DeadEnd.all_cats), "Spirit Arena": RegionInfo("Spirit Arena", dead_end=DeadEnd.all_cats), - "Spirit Arena Victory": RegionInfo("Spirit Arena", dead_end=DeadEnd.all_cats), + "Spirit Arena Victory": RegionInfo("Spirit Arena", dead_end=DeadEnd.all_cats, is_fake_region=True), } @@ -813,7 +827,7 @@ class DeadEnd(IntEnum): "Overworld Southeast Cross Door": [], "Overworld Fountain Cross Door": - [], + [], "Overworld Town Portal": [], "Overworld Spawn Portal": @@ -1301,7 +1315,6 @@ class DeadEnd(IntEnum): [], }, - # cannot get from frogs back to front "Library Exterior Ladder Region": { "Library Exterior by Tree": [], @@ -1634,10 +1647,6 @@ class DeadEnd(IntEnum): "Rooted Ziggurat Portal Room Entrance": [], }, - "Zig Skip Exit": { - "Rooted Ziggurat Lower Front": - [], - }, "Rooted Ziggurat Portal Room Entrance": { "Rooted Ziggurat Lower Back": [], diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index 84ebb4830474..8c0979e3e466 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -381,9 +381,11 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Overworld"].connect( connecting_region=regions["Overworld Tunnel Turret"], rule=lambda state: state.has(laurels, player)) - regions["Overworld Tunnel Turret"].connect( - connecting_region=regions["Overworld"], - rule=lambda state: state.has_any({grapple, laurels}, player)) + + # always have access to Overworld, so connecting back isn't needed + # regions["Overworld Tunnel Turret"].connect( + # connecting_region=regions["Overworld"], + # rule=lambda state: state.has_any({grapple, laurels}, player)) cube_entrance = regions["Overworld"].connect( connecting_region=regions["Cube Cave Entrance Region"], @@ -1053,11 +1055,6 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Rooted Ziggurat Portal Room Entrance"].connect( connecting_region=regions["Rooted Ziggurat Lower Back"]) - # zig skip region only gets made if entrance rando and fewer shops are on - if options.entrance_rando and options.fixed_shop: - regions["Zig Skip Exit"].connect( - connecting_region=regions["Rooted Ziggurat Lower Front"]) - regions["Rooted Ziggurat Portal"].connect( connecting_region=regions["Rooted Ziggurat Portal Room"]) regions["Rooted Ziggurat Portal Room"].connect( @@ -1226,14 +1223,6 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: and has_sword(state, player)))) if options.ladder_storage: - def get_portal_info(portal_sd: str) -> Tuple[str, str]: - for portal1, portal2 in portal_pairs.items(): - if portal1.scene_destination() == portal_sd: - return portal1.name, get_portal_outlet_region(portal2, world) - if portal2.scene_destination() == portal_sd: - return portal2.name, get_portal_outlet_region(portal1, world) - raise Exception("no matches found in get_paired_region") - # connect ls elevation regions to their destinations def ls_connect(origin_name: str, portal_sdt: str) -> None: p_name, paired_region_name = get_portal_info(portal_sdt) diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index 597c65b92070..ae1b5fcb454d 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -1,11 +1,12 @@ from typing import Dict, List, Set, Tuple, TYPE_CHECKING from BaseClasses import Region, ItemClassification, Item, Location from .locations import all_locations -from .er_data import Portal, portal_mapping, traversal_requirements, DeadEnd, RegionInfo +from .er_data import (Portal, portal_mapping, traversal_requirements, DeadEnd, Direction, RegionInfo, + get_portal_outlet_region) from .er_rules import set_er_region_rules from .breakables import create_breakable_exclusive_regions, set_breakable_location_rules from Options import PlandoConnection -from .options import EntranceRando +from .options import EntranceRando, EntranceLayout from random import Random from copy import deepcopy @@ -23,17 +24,18 @@ class TunicERLocation(Location): def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]: regions: Dict[str, Region] = {} + world.used_shop_numbers = set() + for region_name, region_data in world.er_regions.items(): if world.options.entrance_rando and region_name == "Zig Skip Exit": # need to check if there's a seed group for this first if world.options.entrance_rando.value not in EntranceRando.options.values(): - if not world.seed_groups[world.options.entrance_rando.value]["fixed_shop"]: + if world.seed_groups[world.options.entrance_rando.value]["entrance_layout"] != EntranceLayout.option_fixed_shop: continue - elif not world.options.fixed_shop: + elif world.options.entrance_layout != EntranceLayout.option_fixed_shop: continue if not world.options.entrance_rando and region_name in ("Zig Skip Exit", "Purgatory"): continue - region = Region(region_name, world.player, world.multiworld) regions[region_name] = region world.multiworld.regions.append(region) @@ -46,13 +48,18 @@ def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]: portal_pairs = pair_portals(world, regions) # output the entrances to the spoiler log here for convenience - sorted_portal_pairs = sort_portals(portal_pairs) - for portal1, portal2 in sorted_portal_pairs.items(): - world.multiworld.spoiler.set_entrance(portal1, portal2, "both", world.player) + sorted_portal_pairs = sort_portals(portal_pairs, world) + if not world.options.decoupled: + for portal1, portal2 in sorted_portal_pairs.items(): + world.multiworld.spoiler.set_entrance(portal1, portal2, "both", world.player) + else: + for portal1, portal2 in sorted_portal_pairs.items(): + world.multiworld.spoiler.set_entrance(portal1, portal2, "entrance", world.player) + else: portal_pairs = vanilla_portals(world, regions) - create_randomized_entrances(portal_pairs, regions) + create_randomized_entrances(world, portal_pairs, regions) set_er_region_rules(world, regions, portal_pairs) @@ -75,6 +82,7 @@ def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]: return portal_pairs +# keys are event names, values are event regions tunic_events: Dict[str, str] = { "Eastern Bell": "Forest Belltower Upper", "Western Bell": "Overworld Belltower at Bell", @@ -111,17 +119,31 @@ def place_event_items(world: "TunicWorld", regions: Dict[str, Region]) -> None: region.locations.append(location) +# keeping track of which shop numbers have been used already to avoid duplicates +# due to plando, shops can be added out of order, so a set is the best way to make this work smoothly +def get_shop_num(world: "TunicWorld") -> int: + portal_num = -1 + for i in range(500): + if i + 1 not in world.used_shop_numbers: + portal_num = i + 1 + world.used_shop_numbers.add(portal_num) + break + if portal_num == -1: + raise Exception(f"TUNIC: {world.player_name} has plando'd too many shops.") + return portal_num + + # all shops are the same shop. however, you cannot get to all shops from the same shop entrance. # so, we need a bunch of shop regions that connect to the actual shop, but the actual shop cannot connect back -def create_shop_region(world: "TunicWorld", regions: Dict[str, Region]) -> None: - new_shop_name = f"Shop {world.shop_num}" +def create_shop_region(world: "TunicWorld", regions: Dict[str, Region], portal_num) -> None: + new_shop_name = f"Shop {portal_num}" world.er_regions[new_shop_name] = RegionInfo("Shop", dead_end=DeadEnd.all_cats) new_shop_region = Region(new_shop_name, world.player, world.multiworld) new_shop_region.connect(regions["Shop"]) regions[new_shop_name] = new_shop_region - world.shop_num += 1 +# for non-ER that uses the ER rules, we create a vanilla set of portal pairs def vanilla_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal, Portal]: portal_pairs: Dict[Portal, Portal] = {} # we don't want the zig skip exit for vanilla portals, since it shouldn't be considered for logic here @@ -135,9 +157,10 @@ def vanilla_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Por portal2_sdt = portal1.destination_scene() if portal2_sdt.startswith("Shop,"): - portal2 = Portal(name=f"Shop Portal {world.shop_num}", region=f"Shop {world.shop_num}", - destination="Previous Region", tag="_") - create_shop_region(world, regions) + portal_num = get_shop_num(world) + portal2 = Portal(name=f"Shop Portal {portal_num}", region=f"Shop {portal_num}", + destination=str(portal_num), tag="_", direction=Direction.none) + create_shop_region(world, regions, portal_num) for portal in portal_map: if portal.scene_destination() == portal2_sdt: @@ -152,7 +175,13 @@ def vanilla_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Por return portal_pairs -# pairing off portals, starting with dead ends +# the really long function that gives us our portal pairs +# before we start pairing, we separate the portals into dead ends and non-dead ends (two_plus) +# then, we do a few other important tasks to accommodate options and seed gropus +# first phase: pick a two_plus in a reachable region and non-reachable region and pair them +# repeat this phase until all regions are reachable +# second phase: randomly pair dead ends to random two_plus +# third phase: randomly pair the remaining two_plus to each other def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal, Portal]: portal_pairs: Dict[Portal, Portal] = {} dead_ends: List[Portal] = [] @@ -162,8 +191,9 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal laurels_zips = world.options.laurels_zips.value ice_grappling = world.options.ice_grappling.value ladder_storage = world.options.ladder_storage.value - fixed_shop = world.options.fixed_shop + entrance_layout = world.options.entrance_layout laurels_location = world.options.laurels_location + decoupled = world.options.decoupled traversal_reqs = deepcopy(traversal_requirements) has_laurels = True waterfall_plando = False @@ -174,7 +204,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal laurels_zips = seed_group["laurels_zips"] ice_grappling = seed_group["ice_grappling"] ladder_storage = seed_group["ladder_storage"] - fixed_shop = seed_group["fixed_shop"] + entrance_layout = seed_group["entrance_layout"] laurels_location = "10_fairies" if seed_group["laurels_at_10_fairies"] is True else False logic_tricks: Tuple[bool, int, int] = (laurels_zips, ice_grappling, ladder_storage) @@ -183,15 +213,18 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal if laurels_location == "10_fairies" and not world.using_ut: has_laurels = False - shop_count = 6 - if fixed_shop: - shop_count = 0 - else: - # if fixed shop is off, remove this portal - for portal in portal_map: - if portal.region == "Zig Skip Exit": - portal_map.remove(portal) - break + # for the direction pairs option with decoupled off + # tracks how many portals are in each direction in each list + two_plus_direction_tracker: Dict[int, int] = {direction: 0 for direction in range(8)} + dead_end_direction_tracker: Dict[int, int] = {direction: 0 for direction in range(8)} + + # for ensuring we have enough entrances in directions left that we don't leave dead ends without any + def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: + if two_plus_direction_tracker[direction] <= (dead_end_direction_tracker[direction_pairs[direction]] + offset): + return False + if two_plus_direction_tracker[direction_pairs[direction]] <= dead_end_direction_tracker[direction] + offset: + return False + return True # If using Universal Tracker, restore portal_map. Could be cleaner, but it does not matter for UT even a little bit if world.using_ut: @@ -202,25 +235,59 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal dead_end_status = world.er_regions[portal.region].dead_end if dead_end_status == DeadEnd.free: two_plus.append(portal) + two_plus_direction_tracker[portal.direction] += 1 elif dead_end_status == DeadEnd.all_cats: dead_ends.append(portal) + dead_end_direction_tracker[portal.direction] += 1 elif dead_end_status == DeadEnd.restricted: if ice_grappling: two_plus.append(portal) + two_plus_direction_tracker[portal.direction] += 1 else: dead_ends.append(portal) + dead_end_direction_tracker[portal.direction] += 1 # these two get special handling elif dead_end_status == DeadEnd.special: if portal.region == "Secret Gathering Place": if laurels_location == "10_fairies": two_plus.append(portal) + two_plus_direction_tracker[portal.direction] += 1 else: dead_ends.append(portal) + dead_end_direction_tracker[portal.direction] += 1 + if portal.region == "Zig Skip Exit" and entrance_layout == EntranceLayout.option_fixed_shop: + # direction isn't meaningful here since zig skip cannot be in direction pairs mode + two_plus.append(portal) + + # now we generate the shops and add them to the dead ends list + shop_count = 6 + if entrance_layout == EntranceLayout.option_fixed_shop: + shop_count = 0 + else: + # if fixed shop is off, remove this portal + for portal in portal_map: if portal.region == "Zig Skip Exit": - if fixed_shop: - two_plus.append(portal) - else: - dead_ends.append(portal) + portal_map.remove(portal) + break + # need 8 shops with direction pairs or there won't be a valid set of pairs + if entrance_layout == EntranceLayout.option_direction_pairs: + shop_count = 8 + + # for universal tracker, we want to skip shop gen since it's essentially full plando + if world.using_ut: + shop_count = 0 + + for _ in range(shop_count): + # 6 of the shops have south exits, 2 of them have west exits + portal_num = get_shop_num(world) + shop_dir = Direction.south + if portal_num > 6: + shop_dir = Direction.west + shop_portal = Portal(name=f"Shop Portal {portal_num}", region=f"Shop {portal_num}", + destination=str(portal_num), tag="_", direction=shop_dir) + create_shop_region(world, regions, portal_num) + dead_ends.append(shop_portal) + dead_end_direction_tracker[shop_portal.direction] += 1 connected_regions: Set[str] = set() # make better start region stuff when/if implementing random start @@ -249,29 +316,68 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal portal_name2 = portal.name # connected_regions.update(add_dependent_regions(portal.region, logic_rules)) # shops have special handling - if not portal_name2 and portal2 == "Shop, Previous Region_": - portal_name2 = "Shop Portal" - plando_connections.append(PlandoConnection(portal_name1, portal_name2, "both")) + if not portal_name1 and portal1.startswith("Shop"): + # it should show up as "Shop, 1_" for shop 1 + portal_name1 = "Shop Portal " + str(portal1).split(", ")[1].split("_")[0] + if not portal_name2 and portal2.startswith("Shop"): + portal_name2 = "Shop Portal " + str(portal2).split(", ")[1].split("_")[0] + if world.options.decoupled: + plando_connections.append(PlandoConnection(portal_name1, portal_name2, "entrance")) + else: + plando_connections.append(PlandoConnection(portal_name1, portal_name2, "both")) + # put together the list of non-deadend regions non_dead_end_regions = set() for region_name, region_info in world.er_regions.items(): - if not region_info.dead_end: + # these are not real regions, they are just here to be descriptive + if region_info.is_fake_region or region_name == "Shop": + continue + # dead ends aren't real in decoupled + if decoupled: + non_dead_end_regions.add(region_name) + elif not region_info.dead_end: non_dead_end_regions.add(region_name) # if ice grappling to places is in logic, both places stop being dead ends elif region_info.dead_end == DeadEnd.restricted and ice_grappling: non_dead_end_regions.add(region_name) - # secret gathering place and zig skip get weird, special handling + # secret gathering place is treated as a non-dead end if 10 fairies is on to assure non-laurels access to it elif region_info.dead_end == DeadEnd.special: - if (region_name == "Secret Gathering Place" and laurels_location == "10_fairies") \ - or (region_name == "Zig Skip Exit" and fixed_shop): + if region_name == "Secret Gathering Place" and laurels_location == "10_fairies": non_dead_end_regions.add(region_name) + if decoupled: + # add the dead ends to the two plus list, since dead ends aren't real in decoupled + two_plus.extend(dead_ends) + dead_ends.clear() + # if decoupled is on, we make a second two_plus list, where the first is entrances and the second is exits + two_plus2 = two_plus.copy() + else: + # if decoupled is off, the two lists are the same list, since entrances and exits are intertwined + two_plus2 = two_plus + if plando_connections: - for connection in plando_connections: + if decoupled: + modified_plando_connections = plando_connections.copy() + for index, cxn in enumerate(modified_plando_connections): + # it's much easier if we split both-direction portals into two one-ways in decoupled + if cxn.direction == "both": + replacement1 = PlandoConnection(cxn.entrance, cxn.exit, "entrance") + replacement2 = PlandoConnection(cxn.exit, cxn.entrance, "entrance") + modified_plando_connections.remove(cxn) + modified_plando_connections.insert(index, replacement1) + modified_plando_connections.append(replacement2) + else: + modified_plando_connections = plando_connections + + connected_shop_portal1s: Set[int] = set() + connected_shop_portal2s: Set[int] = set() + for connection in modified_plando_connections: p_entrance = connection.entrance p_exit = connection.exit # if you plando secret gathering place, need to know that during portal pairing - if "Secret Gathering Place Exit" in [p_entrance, p_exit]: + if p_exit == "Secret Gathering Place Exit": + waterfall_plando = True + if p_entrance == "Secret Gathering Place Exit" and not decoupled: waterfall_plando = True portal1_dead_end = True portal2_dead_end = True @@ -279,118 +385,186 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal portal1 = None portal2 = None - # search two_plus for both at once + # search the two_plus lists (or list) for the portals for portal in two_plus: if p_entrance == portal.name: portal1 = portal portal1_dead_end = False + break + for portal in two_plus2: if p_exit == portal.name: portal2 = portal portal2_dead_end = False + break # search dead_ends individually since we can't really remove items from two_plus during the loop if portal1: two_plus.remove(portal1) else: # if not both, they're both dead ends - if not portal2: + if not portal2 and not decoupled: if world.options.entrance_rando.value not in EntranceRando.options.values(): raise Exception(f"Tunic ER seed group {world.options.entrance_rando.value} paired a dead " "end to a dead end in their plando connections.") else: raise Exception(f"{player_name} paired a dead end to a dead end in their " - "plando connections.") + f"plando connections -- {connection.entrance} to {connection.exit}") for portal in dead_ends: if p_entrance == portal.name: portal1 = portal + dead_ends.remove(portal1) break - if not portal1: - raise Exception(f"Could not find entrance named {p_entrance} for " - f"plando connections in {player_name}'s YAML.") - dead_ends.remove(portal1) + else: + if p_entrance.startswith("Shop Portal "): + portal_num = int(p_entrance.split("Shop Portal ")[-1]) + # shops 1-6 are south, 7 and 8 are east, and after that it just breaks direction pairs + if portal_num <= 6: + pdir = Direction.south + elif portal_num in [7, 8]: + pdir = Direction.east + else: + pdir = Direction.none + portal1 = Portal(name=f"Shop Portal {portal_num}", region=f"Shop {portal_num}", + destination=str(portal_num), tag="_", direction=pdir) + connected_shop_portal1s.add(portal_num) + if portal_num not in world.used_shop_numbers: + create_shop_region(world, regions, portal_num) + world.used_shop_numbers.add(portal_num) + if decoupled and portal_num not in connected_shop_portal2s: + two_plus2.append(portal1) + non_dead_end_regions.add(portal1.region) + else: + raise Exception(f"Could not find entrance named {p_entrance} for " + f"plando connections in {player_name}'s YAML.") if portal2: - two_plus.remove(portal2) + two_plus2.remove(portal2) else: for portal in dead_ends: if p_exit == portal.name: portal2 = portal + dead_ends.remove(portal2) break - # if it's not a dead end, it might be a shop - if p_exit == "Shop Portal": - portal2 = Portal(name=f"Shop Portal {world.shop_num}", region=f"Shop {world.shop_num}", - destination="Previous Region", tag="_") - create_shop_region(world, regions) - shop_count -= 1 - # need to maintain an even number of portals total - if shop_count < 0: - shop_count += 2 - # and if it's neither shop nor dead end, it just isn't correct + # if it's not a dead end, maybe it's a plando'd shop portal that doesn't normally exist else: if not portal2: - raise Exception(f"Could not find entrance named {p_exit} for " - f"plando connections in {player_name}'s YAML.\n" - f"If you are using Universal Tracker, the most likely reason for this error " - f"is that the host generated with a newer version of the APWorld.\n" - f"Please check the TUNIC Randomizer Github and place the newest APWorld in your " - f"custom_worlds folder, and remove the one in lib/worlds if there is one there.") - dead_ends.remove(portal2) - - # update the traversal chart to say you can get from portal1's region to portal2's and vice versa - if not portal1_dead_end and not portal2_dead_end: - traversal_reqs.setdefault(portal1.region, dict())[portal2.region] = [] - traversal_reqs.setdefault(portal2.region, dict())[portal1.region] = [] - - if (portal1.region == "Zig Skip Exit" and (portal2_dead_end or portal2.region == "Secret Gathering Place") - or portal2.region == "Zig Skip Exit" and (portal1_dead_end or portal1.region == "Secret Gathering Place")): - if world.options.entrance_rando.value not in EntranceRando.options.values(): - raise Exception(f"Tunic ER seed group {world.options.entrance_rando.value} paired a dead " - "end to a dead end in their plando connections.") - else: - raise Exception(f"{player_name} paired a dead end to a dead end in their " - "plando connections.") - - if (portal1.region == "Secret Gathering Place" and (portal2_dead_end or portal2.region == "Zig Skip Exit") - or portal2.region == "Secret Gathering Place" and (portal1_dead_end or portal1.region == "Zig Skip Exit")): - # need to make sure you didn't pair this to a dead end or zig skip - if portal1_dead_end or portal2_dead_end or \ - portal1.region == "Zig Skip Exit" or portal2.region == "Zig Skip Exit": + if p_exit.startswith("Shop Portal "): + portal_num = int(p_exit.split("Shop Portal ")[-1]) + if portal_num <= 6: + pdir = Direction.south + elif portal_num in [7, 8]: + pdir = Direction.east + else: + pdir = Direction.none + portal2 = Portal(name=f"Shop Portal {portal_num}", region=f"Shop {portal_num}", + destination=str(portal_num), tag="_", direction=pdir) + connected_shop_portal2s.add(portal_num) + if portal_num not in world.used_shop_numbers: + create_shop_region(world, regions, portal_num) + world.used_shop_numbers.add(portal_num) + if decoupled and portal_num not in connected_shop_portal1s: + two_plus.append(portal2) + non_dead_end_regions.add(portal2.region) + else: + raise Exception(f"Could not find entrance named {p_exit} for " + f"plando connections in {player_name}'s YAML.") + + # if we're doing decoupled, we don't need to do complex checks + if decoupled: + # we turn any plando that uses "exit" to use "entrance" instead + traversal_reqs.setdefault(portal1.region, dict())[get_portal_outlet_region(portal2, world)] = [] + # outside decoupled, we want to use what we were doing before decoupled got added + else: + # update the traversal chart to say you can get from portal1's region to portal2's and vice versa + if not portal1_dead_end and not portal2_dead_end: + traversal_reqs.setdefault(portal1.region, dict())[get_portal_outlet_region(portal2, world)] = [] + traversal_reqs.setdefault(portal2.region, dict())[get_portal_outlet_region(portal1, world)] = [] + + if (portal1.region == "Zig Skip Exit" and (portal2_dead_end or portal2.region == "Secret Gathering Place") + or portal2.region == "Zig Skip Exit" and (portal1_dead_end or portal1.region == "Secret Gathering Place")): if world.options.entrance_rando.value not in EntranceRando.options.values(): raise Exception(f"Tunic ER seed group {world.options.entrance_rando.value} paired a dead " "end to a dead end in their plando connections.") else: raise Exception(f"{player_name} paired a dead end to a dead end in their " "plando connections.") + + if (portal1.region == "Secret Gathering Place" and (portal2_dead_end or portal2.region == "Zig Skip Exit") + or portal2.region == "Secret Gathering Place" and (portal1_dead_end or portal1.region == "Zig Skip Exit")): + # need to make sure you didn't pair this to a dead end or zig skip + if portal1_dead_end or portal2_dead_end or \ + portal1.region == "Zig Skip Exit" or portal2.region == "Zig Skip Exit": + if world.options.entrance_rando.value not in EntranceRando.options.values(): + raise Exception(f"Tunic ER seed group {world.options.entrance_rando.value} paired a dead " + "end to a dead end in their plando connections.") + else: + raise Exception(f"{player_name} paired a dead end to a dead end in their " + "plando connections.") + # okay now that we're done with all of that nonsense, we can finally make the portal pair portal_pairs[portal1] = portal2 + if portal1_dead_end: + dead_end_direction_tracker[portal1.direction] -= 1 + else: + two_plus_direction_tracker[portal1.direction] -= 1 + if portal2_dead_end: + dead_end_direction_tracker[portal2.direction] -= 1 + else: + two_plus_direction_tracker[portal2.direction] -= 1 + # if we have plando connections, our connected regions may change somewhat connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks) - if fixed_shop and not world.using_ut: - portal1 = None + # if there are an odd number of shops after plando, add another one, except in decoupled where it doesn't matter + if not decoupled and len(world.used_shop_numbers) % 2 == 1: + if entrance_layout == EntranceLayout.option_direction_pairs: + raise Exception(f"TUNIC: {world.player_name} plando'd too many shops for the Direction Pairs option.") + portal_num = get_shop_num(world) + shop_portal = Portal(name=f"Shop Portal {portal_num}", region=f"Shop {portal_num}", + destination=str(portal_num), tag="_", direction=Direction.none) + create_shop_region(world, regions, portal_num) + dead_ends.append(shop_portal) + + if entrance_layout == EntranceLayout.option_fixed_shop and not world.using_ut: + windmill = None for portal in two_plus: if portal.scene_destination() == "Overworld Redux, Windmill_": - portal1 = portal + windmill = portal break - if not portal1: - raise Exception(f"Failed to do Fixed Shop option. " - f"Did {player_name} plando connection the Windmill Shop entrance?") + if not windmill: + raise Exception(f"Failed to do Fixed Shop option for Entrance Layout. " + f"Did {player_name} plando the Windmill Shop entrance?") + + portal_num = get_shop_num(world) + shop = Portal(name=f"Shop Portal {portal_num}", region=f"Shop {portal_num}", + destination=str(portal_num), tag="_", direction=Direction.south) + create_shop_region(world, regions, portal_num) + + portal_pairs[windmill] = shop + two_plus.remove(windmill) + if decoupled: + two_plus.append(shop) + non_dead_end_regions.add(shop.region) + connected_regions.add(shop.region) - portal2 = Portal(name=f"Shop Portal {world.shop_num}", region=f"Shop {world.shop_num}", - destination="Previous Region", tag="_") - create_shop_region(world, regions) - - portal_pairs[portal1] = portal2 - two_plus.remove(portal1) - - random_object: Random = world.random # use the seed given in the options to shuffle the portals if isinstance(world.options.entrance_rando.value, str): random_object = Random(world.options.entrance_rando.value) + else: + random_object: Random = world.random + # we want to start by making sure every region is accessible random_object.shuffle(two_plus) - check_success = 0 + + # this is a backup in case we run into that rare direction pairing failure + # so that we don't have to redo the plando bit basically + backup_connected_regions = connected_regions.copy() + backup_portal_pairs = portal_pairs.copy() + backup_two_plus = two_plus.copy() + backup_two_plus_direction_tracker = two_plus_direction_tracker.copy() + rare_failure_count = 0 + portal1 = None portal2 = None previous_conn_num = 0 @@ -403,96 +577,182 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal # should, hopefully, only ever occur if someone plandos connections poorly if previous_conn_num == len(connected_regions): fail_count += 1 - if fail_count >= 500: + if fail_count > 500: raise Exception(f"Failed to pair regions. Check plando connections for {player_name} for errors. " - "Unconnected regions:", non_dead_end_regions - connected_regions) + f"Unconnected regions: {non_dead_end_regions - connected_regions}.\n" + f"Unconnected portals: {[portal.name for portal in two_plus]}") + if (fail_count > 100 and not decoupled + and (world.options.entrance_layout == EntranceLayout.option_direction_pairs or waterfall_plando)): + # in direction pairs, we may run into a case where we run out of pairable directions + # since we need to ensure the dead ends will have something to connect to + # or if fairy cave is plando'd, it may run into an issue where it is trying to get access to 2 separate + # areas at once to give access to laurels + # so, this is basically just resetting entrance pairing + # this should be very rare, so this fail-safe shouldn't be covering up for an actual solution + # this should never happen in decoupled, since it's entirely too flexible for that + portal_pairs = backup_portal_pairs.copy() + two_plus = two_plus2 = backup_two_plus.copy() + two_plus_direction_tracker = backup_two_plus_direction_tracker.copy() + random_object.shuffle(two_plus) + connected_regions = backup_connected_regions.copy() + rare_failure_count += 1 + fail_count = 0 + + if rare_failure_count > 100: + raise Exception(f"Failed to pair regions due to rare pairing issues for {player_name}. " + f"Unconnected regions: {non_dead_end_regions - connected_regions}.\n" + f"Unconnected portals: {[portal.name for portal in two_plus]}") else: fail_count = 0 previous_conn_num = len(connected_regions) # find a portal in a connected region - if check_success == 0: - for portal in two_plus: - if portal.region in connected_regions: - portal1 = portal - two_plus.remove(portal) - check_success = 1 - break + for portal in two_plus: + if portal.region in connected_regions: + # if there's more dead ends of a direction than two plus of the opposite direction, + # then we'll run out of viable connections for those dead ends later + # decoupled does not have this issue since dead ends aren't real in decoupled + if not decoupled and entrance_layout == EntranceLayout.option_direction_pairs: + if not too_few_portals_for_direction_pairs(portal.direction, 0): + continue - # then we find a portal in an inaccessible region - if check_success == 1: - for portal in two_plus: - if portal.region not in connected_regions: - # if secret gathering place happens to get paired really late, you can end up running out - if not has_laurels and len(two_plus) < 80: - # if you plando'd secret gathering place with laurels at 10 fairies, you're the reason for this - if waterfall_plando: - cr = connected_regions.copy() - cr.add(portal.region) - if "Secret Gathering Place" not in update_reachable_regions(cr, traversal_reqs, has_laurels, logic_tricks): - continue - # if not waterfall_plando, then we just want to pair secret gathering place now - elif portal.region != "Secret Gathering Place": + portal1 = portal + two_plus.remove(portal) + break + if not portal1: + raise Exception("TUNIC: Failed to pair portals at first part of first phase.") + + # then we find a portal in an unconnected region + for portal in two_plus2: + if portal.region not in connected_regions: + # if secret gathering place happens to get paired really late, you can end up running out + if not has_laurels and len(two_plus2) < 80: + # if you plando'd secret gathering place with laurels at 10 fairies, you're the reason for this + if waterfall_plando: + cr = connected_regions.copy() + cr.add(portal.region) + if "Secret Gathering Place" not in update_reachable_regions(cr, traversal_reqs, has_laurels, logic_tricks): continue - portal2 = portal - connected_regions.add(portal.region) - two_plus.remove(portal) - check_success = 2 - break + # if not waterfall_plando, then we just want to pair secret gathering place now + elif portal.region != "Secret Gathering Place": + continue + + # if they're not facing opposite directions, just continue + if entrance_layout == EntranceLayout.option_direction_pairs and not verify_direction_pair(portal, portal1): + continue + + # if you have direction pairs, we need to make sure we don't run out of spots for problem portals + # this cuts down on using the failsafe significantly + if not decoupled and entrance_layout == EntranceLayout.option_direction_pairs: + should_continue = False + # these portals are weird since they're one-ways essentially + # we need to make sure they are connected in this first phase + south_problems = ["Ziggurat Upper to Ziggurat Entry Hallway", + "Ziggurat Tower to Ziggurat Upper", "Forest Belltower to Guard Captain Room"] + if (portal.direction == Direction.south and portal.name not in south_problems + and not too_few_portals_for_direction_pairs(portal.direction, 3)): + for test_portal in two_plus: + if test_portal.name in south_problems: + should_continue = True + # at risk of connecting frog's domain entry ladder to librarian exit + if (portal.direction == Direction.ladder_down + or portal.direction == Direction.ladder_up and portal.name != "Frog's Domain Ladder Exit" + and not too_few_portals_for_direction_pairs(portal.direction, 1)): + for test_portal in two_plus: + if test_portal.name == "Frog's Domain Ladder Exit": + should_continue = True + if should_continue: + continue + + portal2 = portal + connected_regions.add(get_portal_outlet_region(portal, world)) + two_plus2.remove(portal) + break + + if not portal2: + if entrance_layout == EntranceLayout.option_direction_pairs or waterfall_plando: + # portal1 doesn't have a valid direction pair yet, throw it back and start over + two_plus.append(portal1) + continue + else: + raise Exception(f"TUNIC: Failed to pair portals at second part of first phase for {world.player_name}.") # once we have both portals, connect them and add the new region(s) to connected_regions - if check_success == 2: - if "Secret Gathering Place" in connected_regions: - has_laurels = True - connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks) - portal_pairs[portal1] = portal2 - check_success = 0 - random_object.shuffle(two_plus) + if not has_laurels and "Secret Gathering Place" in connected_regions: + has_laurels = True + connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks) - # for universal tracker, we want to skip shop gen - if world.using_ut: - shop_count = 0 - - for i in range(shop_count): - portal1 = two_plus.pop() - if portal1 is None: - raise Exception("TUNIC: Too many shops in the pool, or something else went wrong.") - portal2 = Portal(name=f"Shop Portal {world.shop_num}", region=f"Shop {world.shop_num}", - destination="Previous Region", tag="_") - create_shop_region(world, regions) - portal_pairs[portal1] = portal2 + two_plus_direction_tracker[portal1.direction] -= 1 + two_plus_direction_tracker[portal2.direction] -= 1 + portal1 = None + portal2 = None + random_object.shuffle(two_plus) + if two_plus != two_plus2: + random_object.shuffle(two_plus2) # connect dead ends to random non-dead ends - # none of the key events are in dead ends, so we don't need to do gate_before_switch + # there are no dead ends in decoupled while len(dead_ends) > 0: if world.using_ut: break - portal1 = two_plus.pop() - portal2 = dead_ends.pop() - portal_pairs[portal1] = portal2 + portal2 = dead_ends[0] + for portal in two_plus: + if entrance_layout == EntranceLayout.option_direction_pairs and not verify_direction_pair(portal, portal2): + continue + if entrance_layout == EntranceLayout.option_fixed_shop and portal.region == "Zig Skip Exit": + continue + portal1 = portal + portal_pairs[portal1] = portal2 + two_plus.remove(portal1) + dead_ends.remove(portal2) + break + else: + raise Exception(f"Failed to pair {portal2.name} with anything in two_plus for player {world.player_name}.") + # then randomly connect the remaining portals to each other - # every region is accessible, so gate_before_switch is not necessary - while len(two_plus) > 1: + final_pair_number = 0 + while len(two_plus) > 0: if world.using_ut: break - portal1 = two_plus.pop() - portal2 = two_plus.pop() + final_pair_number += 1 + if final_pair_number > 10000: + raise Exception(f"Failed to pair portals while pairing the final entrances off to each other. " + f"Remaining portals in two_plus: {[portal.name for portal in two_plus]}. " + f"Remaining portals in two_plus2: {[portal.name for portal in two_plus2]}.") + portal1 = two_plus[0] + two_plus.remove(portal1) + portal2 = None + if entrance_layout != EntranceLayout.option_direction_pairs: + portal2 = two_plus2.pop() + else: + for portal in two_plus2: + if verify_direction_pair(portal1, portal): + portal2 = portal + two_plus2.remove(portal2) + break + if portal2 is None: + raise Exception("Something went wrong with the remaining two plus portals. Contact the TUNIC rando devs.") portal_pairs[portal1] = portal2 - if len(two_plus) == 1: - raise Exception("two plus had an odd number of portals, investigate this. last portal is " + two_plus[0].name) + if len(two_plus2) > 0: + raise Exception(f"TUNIC: Something went horribly wrong in ER for {world.player_name}. " + f"Please contact the TUNIC rando devs.") return portal_pairs # loop through our list of paired portals and make two-way connections -def create_randomized_entrances(portal_pairs: Dict[Portal, Portal], regions: Dict[str, Region]) -> None: +def create_randomized_entrances(world: "TunicWorld", portal_pairs: Dict[Portal, Portal], regions: Dict[str, Region]) -> None: for portal1, portal2 in portal_pairs.items(): - region1 = regions[portal1.region] - region2 = regions[portal2.region] - region1.connect(connecting_region=region2, name=portal1.name) - region2.connect(connecting_region=region1, name=portal2.name) + # connect to the outlet region if there is one, if not connect to the actual region + regions[portal1.region].connect( + connecting_region=regions[get_portal_outlet_region(portal2, world)], + name=portal1.name) + if not world.options.decoupled or not world.options.entrance_rando: + regions[portal2.region].connect( + connecting_region=regions[get_portal_outlet_region(portal1, world)], + name=portal2.name) def update_reachable_regions(connected_regions: Set[str], traversal_reqs: Dict[str, Dict[str, List[List[str]]]], @@ -541,22 +801,58 @@ def update_reachable_regions(connected_regions: Set[str], traversal_reqs: Dict[s return connected_regions +# which directions are opposites +direction_pairs: Dict[int, int] = { + Direction.north: Direction.south, + Direction.south: Direction.north, + Direction.east: Direction.west, + Direction.west: Direction.east, + Direction.ladder_up: Direction.ladder_down, + Direction.ladder_down: Direction.ladder_up, + Direction.floor: Direction.floor, +} + + +# verify that two portals are in compatible directions +def verify_direction_pair(portal1: Portal, portal2: Portal) -> bool: + return portal1.direction == direction_pairs[portal2.direction] + + +# verify that two plando'd portals are in compatible directions +def verify_plando_directions(connection: PlandoConnection) -> bool: + entrance_portal = None + exit_portal = None + for portal in portal_mapping: + if connection.entrance == portal.name: + entrance_portal = portal + if connection.exit == portal.name: + exit_portal = portal + if entrance_portal and exit_portal: + break + # neither of these are shops, so verify the pair + if entrance_portal and exit_portal: + return verify_direction_pair(entrance_portal, exit_portal) + # this is two shop portals, they can never pair directions + elif not entrance_portal and not exit_portal: + return False + # if one of them is none, it's a shop, which has two possible directions + elif not entrance_portal: + return exit_portal.direction in [Direction.north, Direction.east] + elif not exit_portal: + return entrance_portal.direction in [Direction.north, Direction.east] + else: + # shouldn't be reachable, more of a just in case + raise Exception("Something went very wrong with verify_plando_directions") + + # sort the portal dict by the name of the first portal, referring to the portal order in the master portal list -def sort_portals(portal_pairs: Dict[Portal, Portal]) -> Dict[str, str]: +def sort_portals(portal_pairs: Dict[Portal, Portal], world: "TunicWorld") -> Dict[str, str]: sorted_pairs: Dict[str, str] = {} reference_list: List[str] = [portal.name for portal in portal_mapping] - reference_list.append("Shop Portal") - # note: this is not necessary yet since the shop portals aren't numbered yet -- they will be when decoupled happens # due to plando, there can be a variable number of shops - # I could either do it like this, or just go up to like 200, this seemed better - # shop_count = 0 - # for portal1, portal2 in portal_pairs.items(): - # if portal1.name.startswith("Shop"): - # shop_count += 1 - # if portal2.name.startswith("Shop"): - # shop_count += 1 - # reference_list.extend([f"Shop Portal {i + 1}" for i in range(shop_count)]) + largest_shop_number = max(world.used_shop_numbers) + reference_list.extend([f"Shop Portal {i + 1}" for i in range(largest_shop_number)]) for name in reference_list: for portal1, portal2 in portal_pairs.items(): diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index c17b085b1187..e3fed5b52dfd 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -5,7 +5,7 @@ from decimal import Decimal, ROUND_HALF_UP from Options import (DefaultOnToggle, Toggle, StartInventoryPool, Choice, Range, TextChoice, PlandoConnections, - PerGameCommonOptions, OptionGroup, Visibility, NamedRange) + PerGameCommonOptions, OptionGroup, Removed, Visibility, NamedRange) from .er_data import portal_mapping if TYPE_CHECKING: from . import TunicWorld @@ -147,14 +147,42 @@ class EntranceRando(TextChoice): class FixedShop(Toggle): """ - Forces the Windmill entrance to lead to a shop, and removes the remaining shops from the pool. - Adds another entrance in Rooted Ziggurat Lower to keep an even number of entrances. - Has no effect if Entrance Rando is not enabled. + This option has been superseded by the Entrance Layout option. + If enabled, it will override the Entrance Layout option. + This is kept to keep older yamls working, and will be removed at a later date. """ + visibility = Visibility.none internal_name = "fixed_shop" display_name = "Fewer Shops in Entrance Rando" +class EntranceLayout(Choice): + """ + Decide how the Entrance Randomizer chooses how to pair the entrances. + Standard: Entrances are randomly connected. There are 6 shops in the pool with this option. + Fixed Shop: Forces the Windmill entrance to lead to a shop, and removes the other shops from the pool. + Adds another entrance in Rooted Ziggurat Lower to keep an even number of entrances. + Direction Pairs: Entrances facing opposite directions are paired together. There are 8 shops in the pool with this option. + Note: For seed groups, if one player in a group chooses Fixed Shop and another chooses Direction Pairs, it will error out. + Either of these options will override Standard within a seed group. + """ + internal_name = "entrance_layout" + display_name = "Entrance Layout" + option_standard = 0 + option_fixed_shop = 1 + option_direction_pairs = 2 + default = 0 + + +class Decoupled(Toggle): + """ + Decouple the entrances, so that when you go from one entrance to another, the return trip won't necessarily bring you back to the same place. + Note: For seed groups, all players in the group must have this option enabled or disabled. + """ + internal_name = "decoupled" + display_name = "Decoupled Entrances" + + class LaurelsLocation(Choice): """ Force the Hero's Laurels to be placed at a location in your world. @@ -210,13 +238,22 @@ class LocalFill(NamedRange): class TunicPlandoConnections(PlandoConnections): """ Generic connection plando. Format is: - - entrance: "Entrance Name" - exit: "Exit Name" + - entrance: Entrance Name + exit: Exit Name + direction: Direction percentage: 100 + Direction must be one of entrance, exit, or both, and defaults to both if omitted. + Direction entrance means the entrance leads to the exit. Direction exit means the exit leads to the entrance. + If you do not have Decoupled enabled, you do not need the direction line, as it will only use both. Percentage is an integer from 0 to 100 which determines whether that connection will be made. Defaults to 100 if omitted. + If the Entrance Layout option is set to Standard or Fixed Shop, you can plando multiple shops. + If the Entrance Layout option is set to Direction Pairs, your plando connections must be facing opposite directions. + Shop Portal 1-6 are South portals, and Shop Portal 7-8 are West portals. + This option does nothing if Entrance Rando is disabled. """ - entrances = {*(portal.name for portal in portal_mapping), "Shop", "Shop Portal"} - exits = {*(portal.name for portal in portal_mapping), "Shop", "Shop Portal"} + shops = {f"Shop Portal {i + 1}" for i in range(500)} + entrances = {portal.name for portal in portal_mapping}.union(shops) + exits = {portal.name for portal in portal_mapping}.union(shops) duplicate_exits = True @@ -329,6 +366,7 @@ class TunicOptions(PerGameCommonOptions): start_with_sword: StartWithSword keys_behind_bosses: KeysBehindBosses ability_shuffling: AbilityShuffling + fool_traps: FoolTraps laurels_location: LaurelsLocation @@ -343,7 +381,9 @@ class TunicOptions(PerGameCommonOptions): local_fill: LocalFill entrance_rando: EntranceRando - fixed_shop: FixedShop + entrance_layout: EntranceLayout + decoupled: Decoupled + plando_connections: TunicPlandoConnections combat_logic: CombatLogic lanternless: Lanternless @@ -353,9 +393,8 @@ class TunicOptions(PerGameCommonOptions): ladder_storage: LadderStorage ladder_storage_without_items: LadderStorageWithoutItems - plando_connections: TunicPlandoConnections - - logic_rules: LogicRules + fixed_shop: FixedShop # will be removed at a later date + logic_rules: Removed # fully removed in the direction pairs update tunic_option_groups = [ @@ -372,8 +411,14 @@ class TunicOptions(PerGameCommonOptions): LaurelsZips, IceGrappling, LadderStorage, - LadderStorageWithoutItems - ]) + LadderStorageWithoutItems, + ]), + OptionGroup("Entrance Randomizer", [ + EntranceRando, + EntranceLayout, + Decoupled, + TunicPlandoConnections, + ]), ] tunic_option_presets: Dict[str, Dict[str, Any]] = { diff --git a/worlds/tunic/rules.py b/worlds/tunic/rules.py index 2c5abb424d98..52d5c42e5115 100644 --- a/worlds/tunic/rules.py +++ b/worlds/tunic/rules.py @@ -1,5 +1,4 @@ from typing import Dict, TYPE_CHECKING -from decimal import Decimal, ROUND_HALF_UP from worlds.generic.Rules import set_rule, forbid_item, add_rule from BaseClasses import CollectionState @@ -157,8 +156,8 @@ def set_region_rules(world: "TunicWorld") -> None: if options.ladder_storage >= LadderStorage.option_medium: # ls at any ladder in a safe spot in quarry to get to the monastery rope entrance - world.get_region("Quarry Back").connect(world.get_region("Monastery"), - rule=lambda state: can_ladder_storage(state, world)) + add_rule(world.get_entrance(entrance_name="Quarry Back -> Monastery"), + rule=lambda state: can_ladder_storage(state, world)) def set_location_rules(world: "TunicWorld") -> None: diff --git a/worlds/tunic/test/test_access.py b/worlds/tunic/test/test_access.py index 24551a13d547..6a26180cf026 100644 --- a/worlds/tunic/test/test_access.py +++ b/worlds/tunic/test/test_access.py @@ -78,7 +78,8 @@ class TestERSpecial(TunicTestBase): options = {options.EntranceRando.internal_name: options.EntranceRando.option_yes, options.AbilityShuffling.internal_name: options.AbilityShuffling.option_true, options.HexagonQuest.internal_name: options.HexagonQuest.option_false, - options.FixedShop.internal_name: options.FixedShop.option_false, + options.CombatLogic.internal_name: options.CombatLogic.option_off, + options.EntranceLayout.internal_name: options.EntranceLayout.option_fixed_shop, options.IceGrappling.internal_name: options.IceGrappling.option_easy, "plando_connections": [ { @@ -126,3 +127,262 @@ def test_ls_to_shop_entrance(self) -> None: self.assertFalse(self.can_reach_location("Fortress Courtyard - Page Near Cave")) self.collect_by_name(["Pages 24-25 (Prayer)"]) self.assertTrue(self.can_reach_location("Fortress Courtyard - Page Near Cave")) + + +# check that it still functions if in decoupled and every single normal entrance leads to a shop +class TestERDecoupledPlando(TunicTestBase): + options = {options.EntranceRando.internal_name: options.EntranceRando.option_yes, + options.Decoupled.internal_name: options.Decoupled.option_true, + "plando_connections": [ + {"entrance": "Stick House Entrance", "exit": "Shop Portal 1", "direction": "entrance"}, + {"entrance": "Windmill Entrance", "exit": "Shop Portal 2", "direction": "entrance"}, + {"entrance": "Well Ladder Entrance", "exit": "Shop Portal 3", "direction": "entrance"}, + {"entrance": "Entrance to Well from Well Rail", "exit": "Shop Portal 4", "direction": "entrance"}, + {"entrance": "Old House Door Entrance", "exit": "Shop Portal 5", "direction": "entrance"}, + {"entrance": "Old House Waterfall Entrance", "exit": "Shop Portal 6", "direction": "entrance"}, + {"entrance": "Entrance to Furnace from Well Rail", "exit": "Shop Portal 7", "direction": "entrance"}, + {"entrance": "Entrance to Furnace under Windmill", "exit": "Shop Portal 8", "direction": "entrance"}, + {"entrance": "Entrance to Furnace near West Garden", "exit": "Shop Portal 9", + "direction": "entrance"}, + {"entrance": "Entrance to Furnace from Beach", "exit": "Shop Portal 10", "direction": "entrance"}, + {"entrance": "Caustic Light Cave Entrance", "exit": "Shop Portal 11", "direction": "entrance"}, + {"entrance": "Swamp Upper Entrance", "exit": "Shop Portal 12", "direction": "entrance"}, + {"entrance": "Swamp Lower Entrance", "exit": "Shop Portal 13", "direction": "entrance"}, + {"entrance": "Ruined Passage Not-Door Entrance", "exit": "Shop Portal 14", "direction": "entrance"}, + {"entrance": "Ruined Passage Door Entrance", "exit": "Shop Portal 15", "direction": "entrance"}, + {"entrance": "Atoll Upper Entrance", "exit": "Shop Portal 16", "direction": "entrance"}, + {"entrance": "Atoll Lower Entrance", "exit": "Shop Portal 17", "direction": "entrance"}, + {"entrance": "Special Shop Entrance", "exit": "Shop Portal 18", "direction": "entrance"}, + {"entrance": "Maze Cave Entrance", "exit": "Shop Portal 19", "direction": "entrance"}, + {"entrance": "West Garden Entrance near Belltower", "exit": "Shop Portal 20", + "direction": "entrance"}, + {"entrance": "West Garden Entrance from Furnace", "exit": "Shop Portal 21", "direction": "entrance"}, + {"entrance": "West Garden Laurels Entrance", "exit": "Shop Portal 22", "direction": "entrance"}, + {"entrance": "Temple Door Entrance", "exit": "Shop Portal 23", "direction": "entrance"}, + {"entrance": "Temple Rafters Entrance", "exit": "Shop Portal 24", "direction": "entrance"}, + {"entrance": "Ruined Shop Entrance", "exit": "Shop Portal 25", "direction": "entrance"}, + {"entrance": "Patrol Cave Entrance", "exit": "Shop Portal 26", "direction": "entrance"}, + {"entrance": "Hourglass Cave Entrance", "exit": "Shop Portal 27", "direction": "entrance"}, + {"entrance": "Changing Room Entrance", "exit": "Shop Portal 28", "direction": "entrance"}, + {"entrance": "Cube Cave Entrance", "exit": "Shop Portal 29", "direction": "entrance"}, + {"entrance": "Stairs from Overworld to Mountain", "exit": "Shop Portal 30", "direction": "entrance"}, + {"entrance": "Overworld to Fortress", "exit": "Shop Portal 31", "direction": "entrance"}, + {"entrance": "Fountain HC Door Entrance", "exit": "Shop Portal 32", "direction": "entrance"}, + {"entrance": "Southeast HC Door Entrance", "exit": "Shop Portal 33", "direction": "entrance"}, + {"entrance": "Overworld to Quarry Connector", "exit": "Shop Portal 34", "direction": "entrance"}, + {"entrance": "Dark Tomb Main Entrance", "exit": "Shop Portal 35", "direction": "entrance"}, + {"entrance": "Overworld to Forest Belltower", "exit": "Shop Portal 36", "direction": "entrance"}, + {"entrance": "Town to Far Shore", "exit": "Shop Portal 37", "direction": "entrance"}, + {"entrance": "Spawn to Far Shore", "exit": "Shop Portal 38", "direction": "entrance"}, + {"entrance": "Secret Gathering Place Entrance", "exit": "Shop Portal 39", "direction": "entrance"}, + {"entrance": "Secret Gathering Place Exit", "exit": "Shop Portal 40", "direction": "entrance"}, + {"entrance": "Windmill Exit", "exit": "Shop Portal 41", "direction": "entrance"}, + {"entrance": "Windmill Shop", "exit": "Shop Portal 42", "direction": "entrance"}, + {"entrance": "Old House Door Exit", "exit": "Shop Portal 43", "direction": "entrance"}, + {"entrance": "Old House to Glyph Tower", "exit": "Shop Portal 44", "direction": "entrance"}, + {"entrance": "Old House Waterfall Exit", "exit": "Shop Portal 45", "direction": "entrance"}, + {"entrance": "Glyph Tower Exit", "exit": "Shop Portal 46", "direction": "entrance"}, + {"entrance": "Changing Room Exit", "exit": "Shop Portal 47", "direction": "entrance"}, + {"entrance": "Fountain HC Room Exit", "exit": "Shop Portal 48", "direction": "entrance"}, + {"entrance": "Cube Cave Exit", "exit": "Shop Portal 49", "direction": "entrance"}, + {"entrance": "Guard Patrol Cave Exit", "exit": "Shop Portal 50", "direction": "entrance"}, + {"entrance": "Ruined Shop Exit", "exit": "Shop Portal 51", "direction": "entrance"}, + {"entrance": "Furnace Exit towards Well", "exit": "Shop Portal 52", "direction": "entrance"}, + {"entrance": "Furnace Exit to Dark Tomb", "exit": "Shop Portal 53", "direction": "entrance"}, + {"entrance": "Furnace Exit towards West Garden", "exit": "Shop Portal 54", "direction": "entrance"}, + {"entrance": "Furnace Exit to Beach", "exit": "Shop Portal 55", "direction": "entrance"}, + {"entrance": "Furnace Exit under Windmill", "exit": "Shop Portal 56", "direction": "entrance"}, + {"entrance": "Stick House Exit", "exit": "Shop Portal 57", "direction": "entrance"}, + {"entrance": "Ruined Passage Not-Door Exit", "exit": "Shop Portal 58", "direction": "entrance"}, + {"entrance": "Ruined Passage Door Exit", "exit": "Shop Portal 59", "direction": "entrance"}, + {"entrance": "Southeast HC Room Exit", "exit": "Shop Portal 60", "direction": "entrance"}, + {"entrance": "Caustic Light Cave Exit", "exit": "Shop Portal 61", "direction": "entrance"}, + {"entrance": "Maze Cave Exit", "exit": "Shop Portal 62", "direction": "entrance"}, + {"entrance": "Hourglass Cave Exit", "exit": "Shop Portal 63", "direction": "entrance"}, + {"entrance": "Special Shop Exit", "exit": "Shop Portal 64", "direction": "entrance"}, + {"entrance": "Temple Rafters Exit", "exit": "Shop Portal 65", "direction": "entrance"}, + {"entrance": "Temple Door Exit", "exit": "Shop Portal 66", "direction": "entrance"}, + {"entrance": "Forest Belltower to Fortress", "exit": "Shop Portal 67", "direction": "entrance"}, + {"entrance": "Forest Belltower to Forest", "exit": "Shop Portal 68", "direction": "entrance"}, + {"entrance": "Forest Belltower to Overworld", "exit": "Shop Portal 69", "direction": "entrance"}, + {"entrance": "Forest Belltower to Guard Captain Room", "exit": "Shop Portal 70", + "direction": "entrance"}, + {"entrance": "Forest to Belltower", "exit": "Shop Portal 71", "direction": "entrance"}, + {"entrance": "Forest Guard House 1 Lower Entrance", "exit": "Shop Portal 72", + "direction": "entrance"}, + {"entrance": "Forest Guard House 1 Gate Entrance", "exit": "Shop Portal 73", + "direction": "entrance"}, + {"entrance": "Forest Dance Fox Outside Doorway", "exit": "Shop Portal 74", "direction": "entrance"}, + {"entrance": "Forest to Far Shore", "exit": "Shop Portal 75", "direction": "entrance"}, + {"entrance": "Forest Guard House 2 Lower Entrance", "exit": "Shop Portal 76", + "direction": "entrance"}, + {"entrance": "Forest Guard House 2 Upper Entrance", "exit": "Shop Portal 77", + "direction": "entrance"}, + {"entrance": "Forest Grave Path Lower Entrance", "exit": "Shop Portal 78", "direction": "entrance"}, + {"entrance": "Forest Grave Path Upper Entrance", "exit": "Shop Portal 79", "direction": "entrance"}, + {"entrance": "Forest Grave Path Upper Exit", "exit": "Shop Portal 80", "direction": "entrance"}, + {"entrance": "Forest Grave Path Lower Exit", "exit": "Shop Portal 81", "direction": "entrance"}, + {"entrance": "East Forest Hero's Grave", "exit": "Shop Portal 82", "direction": "entrance"}, + {"entrance": "Guard House 1 Dance Fox Exit", "exit": "Shop Portal 83", "direction": "entrance"}, + {"entrance": "Guard House 1 Lower Exit", "exit": "Shop Portal 84", "direction": "entrance"}, + {"entrance": "Guard House 1 Upper Forest Exit", "exit": "Shop Portal 85", "direction": "entrance"}, + {"entrance": "Guard House 1 to Guard Captain Room", "exit": "Shop Portal 86", + "direction": "entrance"}, + {"entrance": "Guard House 2 Lower Exit", "exit": "Shop Portal 87", "direction": "entrance"}, + {"entrance": "Guard House 2 Upper Exit", "exit": "Shop Portal 88", "direction": "entrance"}, + {"entrance": "Guard Captain Room Non-Gate Exit", "exit": "Shop Portal 89", "direction": "entrance"}, + {"entrance": "Guard Captain Room Gate Exit", "exit": "Shop Portal 90", "direction": "entrance"}, + {"entrance": "Well Ladder Exit", "exit": "Shop Portal 91", "direction": "entrance"}, + {"entrance": "Well to Well Boss", "exit": "Shop Portal 92", "direction": "entrance"}, + {"entrance": "Well Exit towards Furnace", "exit": "Shop Portal 93", "direction": "entrance"}, + {"entrance": "Well Boss to Well", "exit": "Shop Portal 94", "direction": "entrance"}, + {"entrance": "Checkpoint to Dark Tomb", "exit": "Shop Portal 95", "direction": "entrance"}, + {"entrance": "Dark Tomb to Overworld", "exit": "Shop Portal 96", "direction": "entrance"}, + {"entrance": "Dark Tomb to Furnace", "exit": "Shop Portal 97", "direction": "entrance"}, + {"entrance": "Dark Tomb to Checkpoint", "exit": "Shop Portal 98", "direction": "entrance"}, + {"entrance": "West Garden Exit near Hero's Grave", "exit": "Shop Portal 99", + "direction": "entrance"}, + {"entrance": "West Garden to Magic Dagger House", "exit": "Shop Portal 100", + "direction": "entrance"}, + {"entrance": "West Garden Exit after Boss", "exit": "Shop Portal 101", "direction": "entrance"}, + {"entrance": "West Garden Shop", "exit": "Shop Portal 102", "direction": "entrance"}, + {"entrance": "West Garden Laurels Exit", "exit": "Shop Portal 103", "direction": "entrance"}, + {"entrance": "West Garden Hero's Grave", "exit": "Shop Portal 104", "direction": "entrance"}, + {"entrance": "West Garden to Far Shore", "exit": "Shop Portal 105", "direction": "entrance"}, + {"entrance": "Magic Dagger House Exit", "exit": "Shop Portal 106", "direction": "entrance"}, + {"entrance": "Fortress Courtyard to Fortress Grave Path Lower", "exit": "Shop Portal 107", + "direction": "entrance"}, + {"entrance": "Fortress Courtyard to Fortress Grave Path Upper", "exit": "Shop Portal 108", + "direction": "entrance"}, + {"entrance": "Fortress Courtyard to Fortress Interior", "exit": "Shop Portal 109", + "direction": "entrance"}, + {"entrance": "Fortress Courtyard to East Fortress", "exit": "Shop Portal 110", + "direction": "entrance"}, + {"entrance": "Fortress Courtyard to Beneath the Vault", "exit": "Shop Portal 111", + "direction": "entrance"}, + {"entrance": "Fortress Courtyard to Forest Belltower", "exit": "Shop Portal 112", + "direction": "entrance"}, + {"entrance": "Fortress Courtyard to Overworld", "exit": "Shop Portal 113", "direction": "entrance"}, + {"entrance": "Fortress Courtyard Shop", "exit": "Shop Portal 114", "direction": "entrance"}, + {"entrance": "Beneath the Vault to Fortress Interior", "exit": "Shop Portal 115", + "direction": "entrance"}, + {"entrance": "Beneath the Vault to Fortress Courtyard", "exit": "Shop Portal 116", + "direction": "entrance"}, + {"entrance": "Fortress Interior Main Exit", "exit": "Shop Portal 117", "direction": "entrance"}, + {"entrance": "Fortress Interior to Beneath the Earth", "exit": "Shop Portal 118", + "direction": "entrance"}, + {"entrance": "Fortress Interior to Siege Engine Arena", "exit": "Shop Portal 119", + "direction": "entrance"}, + {"entrance": "Fortress Interior Shop", "exit": "Shop Portal 120", "direction": "entrance"}, + {"entrance": "Fortress Interior to East Fortress Upper", "exit": "Shop Portal 121", + "direction": "entrance"}, + {"entrance": "Fortress Interior to East Fortress Lower", "exit": "Shop Portal 122", + "direction": "entrance"}, + {"entrance": "East Fortress to Interior Lower", "exit": "Shop Portal 123", "direction": "entrance"}, + {"entrance": "East Fortress to Courtyard", "exit": "Shop Portal 124", "direction": "entrance"}, + {"entrance": "East Fortress to Interior Upper", "exit": "Shop Portal 125", "direction": "entrance"}, + {"entrance": "Fortress Grave Path Lower Exit", "exit": "Shop Portal 126", "direction": "entrance"}, + {"entrance": "Fortress Hero's Grave", "exit": "Shop Portal 127", "direction": "entrance"}, + {"entrance": "Fortress Grave Path Upper Exit", "exit": "Shop Portal 128", "direction": "entrance"}, + {"entrance": "Fortress Grave Path Dusty Entrance", "exit": "Shop Portal 129", + "direction": "entrance"}, + {"entrance": "Dusty Exit", "exit": "Shop Portal 130", "direction": "entrance"}, + {"entrance": "Siege Engine Arena to Fortress", "exit": "Shop Portal 131", "direction": "entrance"}, + {"entrance": "Fortress to Far Shore", "exit": "Shop Portal 132", "direction": "entrance"}, + {"entrance": "Atoll Upper Exit", "exit": "Shop Portal 133", "direction": "entrance"}, + {"entrance": "Atoll Lower Exit", "exit": "Shop Portal 134", "direction": "entrance"}, + {"entrance": "Atoll Shop", "exit": "Shop Portal 135", "direction": "entrance"}, + {"entrance": "Atoll to Far Shore", "exit": "Shop Portal 136", "direction": "entrance"}, + {"entrance": "Atoll Statue Teleporter", "exit": "Shop Portal 137", "direction": "entrance"}, + {"entrance": "Frog Stairs Eye Entrance", "exit": "Shop Portal 138", "direction": "entrance"}, + {"entrance": "Frog Stairs Mouth Entrance", "exit": "Shop Portal 139", "direction": "entrance"}, + {"entrance": "Frog Stairs Eye Exit", "exit": "Shop Portal 140", "direction": "entrance"}, + {"entrance": "Frog Stairs Mouth Exit", "exit": "Shop Portal 141", "direction": "entrance"}, + {"entrance": "Frog Stairs to Frog's Domain's Entrance", "exit": "Shop Portal 142", + "direction": "entrance"}, + {"entrance": "Frog Stairs to Frog's Domain's Exit", "exit": "Shop Portal 143", + "direction": "entrance"}, + {"entrance": "Frog's Domain Ladder Exit", "exit": "Shop Portal 144", "direction": "entrance"}, + {"entrance": "Frog's Domain Orb Exit", "exit": "Shop Portal 145", "direction": "entrance"}, + {"entrance": "Library Exterior Tree", "exit": "Shop Portal 146", "direction": "entrance"}, + {"entrance": "Library Exterior Ladder", "exit": "Shop Portal 147", "direction": "entrance"}, + {"entrance": "Library Hall Bookshelf Exit", "exit": "Shop Portal 148", "direction": "entrance"}, + {"entrance": "Library Hero's Grave", "exit": "Shop Portal 149", "direction": "entrance"}, + {"entrance": "Library Hall to Rotunda", "exit": "Shop Portal 150", "direction": "entrance"}, + {"entrance": "Library Rotunda Lower Exit", "exit": "Shop Portal 151", "direction": "entrance"}, + {"entrance": "Library Rotunda Upper Exit", "exit": "Shop Portal 152", "direction": "entrance"}, + {"entrance": "Library Lab to Rotunda", "exit": "Shop Portal 153", "direction": "entrance"}, + {"entrance": "Library to Far Shore", "exit": "Shop Portal 154", "direction": "entrance"}, + {"entrance": "Library Lab to Librarian Arena", "exit": "Shop Portal 155", "direction": "entrance"}, + {"entrance": "Librarian Arena Exit", "exit": "Shop Portal 156", "direction": "entrance"}, + {"entrance": "Stairs to Top of the Mountain", "exit": "Shop Portal 157", "direction": "entrance"}, + {"entrance": "Mountain to Quarry", "exit": "Shop Portal 158", "direction": "entrance"}, + {"entrance": "Mountain to Overworld", "exit": "Shop Portal 159", "direction": "entrance"}, + {"entrance": "Top of the Mountain Exit", "exit": "Shop Portal 160", "direction": "entrance"}, + {"entrance": "Quarry Connector to Overworld", "exit": "Shop Portal 161", "direction": "entrance"}, + {"entrance": "Quarry Connector to Quarry", "exit": "Shop Portal 162", "direction": "entrance"}, + {"entrance": "Quarry to Overworld Exit", "exit": "Shop Portal 163", "direction": "entrance"}, + {"entrance": "Quarry Shop", "exit": "Shop Portal 164", "direction": "entrance"}, + {"entrance": "Quarry to Monastery Front", "exit": "Shop Portal 165", "direction": "entrance"}, + {"entrance": "Quarry to Monastery Back", "exit": "Shop Portal 166", "direction": "entrance"}, + {"entrance": "Quarry to Mountain", "exit": "Shop Portal 167", "direction": "entrance"}, + {"entrance": "Quarry to Ziggurat", "exit": "Shop Portal 168", "direction": "entrance"}, + {"entrance": "Quarry to Far Shore", "exit": "Shop Portal 169", "direction": "entrance"}, + {"entrance": "Monastery Rear Exit", "exit": "Shop Portal 170", "direction": "entrance"}, + {"entrance": "Monastery Front Exit", "exit": "Shop Portal 171", "direction": "entrance"}, + {"entrance": "Monastery Hero's Grave", "exit": "Shop Portal 172", "direction": "entrance"}, + {"entrance": "Ziggurat Entry Hallway to Ziggurat Upper", "exit": "Shop Portal 173", + "direction": "entrance"}, + {"entrance": "Ziggurat Entry Hallway to Quarry", "exit": "Shop Portal 174", "direction": "entrance"}, + {"entrance": "Ziggurat Upper to Ziggurat Entry Hallway", "exit": "Shop Portal 175", + "direction": "entrance"}, + {"entrance": "Ziggurat Upper to Ziggurat Tower", "exit": "Shop Portal 176", "direction": "entrance"}, + {"entrance": "Ziggurat Tower to Ziggurat Upper", "exit": "Shop Portal 177", "direction": "entrance"}, + {"entrance": "Ziggurat Tower to Ziggurat Lower", "exit": "Shop Portal 178", "direction": "entrance"}, + {"entrance": "Ziggurat Lower to Ziggurat Tower", "exit": "Shop Portal 179", "direction": "entrance"}, + {"entrance": "Ziggurat Portal Room Entrance", "exit": "Shop Portal 180", "direction": "entrance"}, + {"entrance": "Ziggurat Portal Room Exit", "exit": "Shop Portal 181", "direction": "entrance"}, + {"entrance": "Ziggurat to Far Shore", "exit": "Shop Portal 182", "direction": "entrance"}, + {"entrance": "Swamp Lower Exit", "exit": "Shop Portal 183", "direction": "entrance"}, + {"entrance": "Swamp to Cathedral Main Entrance", "exit": "Shop Portal 184", "direction": "entrance"}, + {"entrance": "Swamp to Cathedral Secret Legend Room Entrance", "exit": "Shop Portal 185", + "direction": "entrance"}, + {"entrance": "Swamp to Gauntlet", "exit": "Shop Portal 186", "direction": "entrance"}, + {"entrance": "Swamp Shop", "exit": "Shop Portal 187", "direction": "entrance"}, + {"entrance": "Swamp Upper Exit", "exit": "Shop Portal 188", "direction": "entrance"}, + {"entrance": "Swamp Hero's Grave", "exit": "Shop Portal 189", "direction": "entrance"}, + {"entrance": "Cathedral Main Exit", "exit": "Shop Portal 190", "direction": "entrance"}, + {"entrance": "Cathedral Elevator", "exit": "Shop Portal 191", "direction": "entrance"}, + {"entrance": "Cathedral Secret Legend Room Exit", "exit": "Shop Portal 192", + "direction": "entrance"}, + {"entrance": "Gauntlet to Swamp", "exit": "Shop Portal 193", "direction": "entrance"}, + {"entrance": "Gauntlet Elevator", "exit": "Shop Portal 194", "direction": "entrance"}, + {"entrance": "Gauntlet Shop", "exit": "Shop Portal 195", "direction": "entrance"}, + {"entrance": "Hero's Grave to Fortress", "exit": "Shop Portal 196", "direction": "entrance"}, + {"entrance": "Hero's Grave to Monastery", "exit": "Shop Portal 197", "direction": "entrance"}, + {"entrance": "Hero's Grave to West Garden", "exit": "Shop Portal 198", "direction": "entrance"}, + {"entrance": "Hero's Grave to East Forest", "exit": "Shop Portal 199", "direction": "entrance"}, + {"entrance": "Hero's Grave to Library", "exit": "Shop Portal 200", "direction": "entrance"}, + {"entrance": "Hero's Grave to Swamp", "exit": "Shop Portal 201", "direction": "entrance"}, + {"entrance": "Far Shore to West Garden", "exit": "Shop Portal 202", "direction": "entrance"}, + {"entrance": "Far Shore to Library", "exit": "Shop Portal 203", "direction": "entrance"}, + {"entrance": "Far Shore to Quarry", "exit": "Shop Portal 204", "direction": "entrance"}, + {"entrance": "Far Shore to East Forest", "exit": "Shop Portal 205", "direction": "entrance"}, + {"entrance": "Far Shore to Fortress", "exit": "Shop Portal 206", "direction": "entrance"}, + {"entrance": "Far Shore to Atoll", "exit": "Shop Portal 207", "direction": "entrance"}, + {"entrance": "Far Shore to Ziggurat", "exit": "Shop Portal 208", "direction": "entrance"}, + {"entrance": "Far Shore to Heir", "exit": "Shop Portal 209", "direction": "entrance"}, + {"entrance": "Far Shore to Town", "exit": "Shop Portal 210", "direction": "entrance"}, + {"entrance": "Far Shore to Spawn", "exit": "Shop Portal 211", "direction": "entrance"}, + {"entrance": "Heir Arena Exit", "exit": "Shop Portal 212", "direction": "entrance"}, + {"entrance": "Purgatory Bottom Exit", "exit": "Shop Portal 213", "direction": "entrance"}, + {"entrance": "Purgatory Top Exit", "exit": "Shop Portal 214", "direction": "entrance"}, + {"entrance": "Shop Portal 215", "exit": "Shop Portal 216", "direction": "entrance"}, + {"entrance": "Shop Portal 217", "exit": "Shop Portal 218", "direction": "entrance"}, + {"entrance": "Shop Portal 219", "exit": "Shop Portal 220", "direction": "entrance"}, + {"entrance": "Shop Portal 221", "exit": "Shop Portal 222", "direction": "entrance"}, + {"entrance": "Shop Portal 223", "exit": "Shop Portal 224", "direction": "entrance"}, + {"entrance": "Shop Portal 225", "exit": "Shop Portal 226", "direction": "entrance"}, + {"entrance": "Shop Portal 227", "exit": "Shop Portal 228", "direction": "entrance"}, + {"entrance": "Shop Portal 229", "exit": "Shop Portal 230", "direction": "entrance"}, + ]} From c40214e20f6c0946506c1367270a8b07e09a11f9 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Wed, 7 May 2025 10:41:37 -0400 Subject: [PATCH 0395/1218] Docs: Minor Changes to apworld_dev_faq.md (#4947) Co-authored-by: qwint --- docs/apworld_dev_faq.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/apworld_dev_faq.md b/docs/apworld_dev_faq.md index 6d7d23b488d1..6c331b849fcf 100644 --- a/docs/apworld_dev_faq.md +++ b/docs/apworld_dev_faq.md @@ -8,7 +8,11 @@ including [Contributing](contributing.md), [Adding Games](), an ### My game has a restrictive start that leads to fill errors -Hint to the Generator that an item needs to be in sphere one with local_early_items. Here, `1` represents the number of "Sword" items to attempt to place in sphere one. +A "restrictive start" here means having a combination of very few sphere 1 locations and potentially requiring more +than one item to get a player to sphere 2. + +One way to fix this is to hint to the Generator that an item needs to be in sphere one with local_early_items. +Here, `1` represents the number of "Sword" items the Generator will attempt to place in sphere one. ```py early_item_name = "Sword" self.multiworld.local_early_items[self.player][early_item_name] = 1 @@ -22,7 +26,7 @@ Some alternative ways to try to fix this problem are: --- -### I have multiple settings that change the item/location pool counts and need to balance them out +### I have multiple options that change the item/location pool counts and need to make sure I am not submitting more/fewer items than locations In an ideal situation your system for producing locations and items wouldn't leave any opportunity for them to be unbalanced. But in real, complex situations, that might be unfeasible. From 0ba9ee0695ebd809ef9e127361223cd39dbc0588 Mon Sep 17 00:00:00 2001 From: qwint Date: Wed, 7 May 2025 09:47:14 -0500 Subject: [PATCH 0396/1218] Docs: update line length in apworld faq doc (#4960) --- docs/apworld_dev_faq.md | 54 ++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/docs/apworld_dev_faq.md b/docs/apworld_dev_faq.md index 6c331b849fcf..e3e571d94949 100644 --- a/docs/apworld_dev_faq.md +++ b/docs/apworld_dev_faq.md @@ -22,15 +22,19 @@ Some alternative ways to try to fix this problem are: * Add more locations to sphere one of your world, potentially only when there would be a restrictive start * Pre-place items yourself, such as during `create_items` * Put items into the player's starting inventory using `push_precollected` -* Raise an exception, such as an `OptionError` during `generate_early`, to disallow options that would lead to a restrictive start +* Raise an exception, such as an `OptionError` during `generate_early`, to disallow options that would lead to a + restrictive start --- ### I have multiple options that change the item/location pool counts and need to make sure I am not submitting more/fewer items than locations -In an ideal situation your system for producing locations and items wouldn't leave any opportunity for them to be unbalanced. But in real, complex situations, that might be unfeasible. +In an ideal situation your system for producing locations and items wouldn't leave any opportunity for them to be +unbalanced. But in real, complex situations, that might be unfeasible. -If that's the case, you can create extra filler based on the difference between your unfilled locations and your itempool by comparing [get_unfilled_locations](https://github.com/ArchipelagoMW/Archipelago/blob/main/BaseClasses.py#:~:text=get_unfilled_locations) to your list of items to submit +If that's the case, you can create extra filler based on the difference between your unfilled locations and your +itempool by comparing [get_unfilled_locations](https://github.com/ArchipelagoMW/Archipelago/blob/main/BaseClasses.py#:~:text=get_unfilled_locations) +to your list of items to submit Note: to use self.create_filler(), self.get_filler_item_name() should be defined to only return valid filler item names ```py @@ -43,7 +47,8 @@ for _ in range(total_locations - len(item_pool)): self.multiworld.itempool += item_pool ``` -A faster alternative to the `for` loop would be to use a [list comprehension](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions): +A faster alternative to the `for` loop would be to use a +[list comprehension](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions): ```py item_pool += [self.create_filler() for _ in range(total_locations - len(item_pool))] ``` @@ -52,24 +57,39 @@ item_pool += [self.create_filler() for _ in range(total_locations - len(item_poo ### I learned about indirect conditions in the world API document, but I want to know more. What are they and why are they necessary? -The world API document mentions how to use `multiworld.register_indirect_condition` to register indirect conditions and **when** you should use them, but not *how* they work and *why* they are necessary. This is because the explanation is quite complicated. +The world API document mentions how to use `multiworld.register_indirect_condition` to register indirect conditions and +**when** you should use them, but not *how* they work and *why* they are necessary. This is because the explanation is +quite complicated. -Region sweep (the algorithm that determines which regions are reachable) is a Breadth-First Search of the region graph. It starts from the origin region, checks entrances one by one, and adds newly reached regions and their entrances to the queue until there is nothing more to check. +Region sweep (the algorithm that determines which regions are reachable) is a Breadth-First Search of the region graph. +It starts from the origin region, checks entrances one by one, and adds newly reached regions and their entrances to +the queue until there is nothing more to check. -For performance reasons, AP only checks every entrance once. However, if an entrance's access_rule depends on region access, then the following may happen: -1. The entrance is checked and determined to be nontraversable because the region in its access_rule hasn't been reached yet during the graph search. +For performance reasons, AP only checks every entrance once. However, if an entrance's access_rule depends on region +access, then the following may happen: +1. The entrance is checked and determined to be nontraversable because the region in its access_rule hasn't been + reached yet during the graph search. 2. Then, the region in its access_rule is determined to be reachable. This entrance *would* be in logic if it were rechecked, but it won't be rechecked this cycle. -To account for this case, AP would have to recheck all entrances every time a new region is reached until no new regions are reached. - -An indirect condition is how you can manually define that a specific entrance needs to be rechecked during region sweep if a specific region is reached during it. -This keeps most of the performance upsides. Even in a game making heavy use of indirect conditions (ex: The Witness), using them is significantly faster than just "rechecking each entrance until nothing new is found". -The reason entrance access rules using `location.can_reach` and `entrance.can_reach` are also affected is because they call `region.can_reach` on their respective parent/source region. - -We recognize it can feel like a trap since it will not alert you when you are missing an indirect condition, and that some games have very complex access rules. -As of [PR #3682 (Core: Region handling customization)](https://github.com/ArchipelagoMW/Archipelago/pull/3682) being merged, it is possible for a world to opt out of indirect conditions entirely, instead using the system of checking each entrance whenever a region has been reached, although this does come with a performance cost. -Opting out of using indirect conditions should only be used by games that *really* need it. For most games, it should be reasonable to know all entrance → region dependencies, making indirect conditions preferred because they are much faster. +To account for this case, AP would have to recheck all entrances every time a new region is reached until no new +regions are reached. + +An indirect condition is how you can manually define that a specific entrance needs to be rechecked during region sweep +if a specific region is reached during it. +This keeps most of the performance upsides. Even in a game making heavy use of indirect conditions (ex: The Witness), +using them is significantly faster than just "rechecking each entrance until nothing new is found". +The reason entrance access rules using `location.can_reach` and `entrance.can_reach` are also affected is because they +call `region.can_reach` on their respective parent/source region. + +We recognize it can feel like a trap since it will not alert you when you are missing an indirect condition, +and that some games have very complex access rules. +As of [PR #3682 (Core: Region handling customization)](https://github.com/ArchipelagoMW/Archipelago/pull/3682) +being merged, it is possible for a world to opt out of indirect conditions entirely, instead using the system of +checking each entrance whenever a region has been reached, although this does come with a performance cost. +Opting out of using indirect conditions should only be used by games that *really* need it. For most games, it should +be reasonable to know all entrance → region dependencies, making indirect conditions preferred because they are +much faster. --- From 17bc184e28f3371eb352a275aaf0bdff6cb20b39 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Wed, 7 May 2025 10:59:16 -0400 Subject: [PATCH 0397/1218] TUNIC: Add Hidden all_random Option (#4635) --- worlds/tunic/__init__.py | 17 ++++++++++++++++- worlds/tunic/options.py | 12 ++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 7027ab1a6427..cdc8f05cb91a 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -1,3 +1,4 @@ +from dataclasses import fields from typing import Dict, List, Any, Tuple, TypedDict, ClassVar, Union, Set, TextIO from logging import warning from BaseClasses import Region, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState @@ -16,7 +17,7 @@ from .breakables import breakable_location_name_to_id, breakable_location_groups, breakable_location_table from .combat_logic import area_data, CombatState from worlds.AutoWorld import WebWorld, World -from Options import PlandoConnection, OptionError +from Options import PlandoConnection, OptionError, PerGameCommonOptions, Removed, Range from settings import Group, Bool @@ -120,6 +121,20 @@ def generate_early(self) -> None: raise Exception("You have a TUNIC APWorld in your lib/worlds folder and custom_worlds folder.\n" "This would cause an error at the end of generation.\n" "Please remove one of them, most likely the one in lib/worlds.") + + if self.options.all_random: + for option_name in (attr.name for attr in fields(TunicOptions) + if attr not in fields(PerGameCommonOptions)): + option = getattr(self.options, option_name) + if option_name == "all_random": + continue + if isinstance(option, Removed): + continue + if option.supports_weighting: + if isinstance(option, Range): + option.value = self.random.randint(option.range_start, option.range_end) + else: + option.value = self.random.choice(list(option.name_lookup)) check_options(self) diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index e3fed5b52dfd..09e2d1d604ca 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -332,6 +332,16 @@ class LadderStorageWithoutItems(Toggle): display_name = "Ladder Storage without Items" +class HiddenAllRandom(Toggle): + """ + Sets all options that can be random to random. + For test gens. + """ + internal_name = "all_random" + display_name = "All Random Debug" + visibility = Visibility.none + + class LogicRules(Choice): """ This option has been superseded by the individual trick options. @@ -392,6 +402,8 @@ class TunicOptions(PerGameCommonOptions): ice_grappling: IceGrappling ladder_storage: LadderStorage ladder_storage_without_items: LadderStorageWithoutItems + + all_random: HiddenAllRandom fixed_shop: FixedShop # will be removed at a later date logic_rules: Removed # fully removed in the direction pairs update From dffde64079860ed815b266b9d957d643ef45bbaf Mon Sep 17 00:00:00 2001 From: Ixrec Date: Wed, 7 May 2025 17:20:21 +0100 Subject: [PATCH 0398/1218] Docs: add a "soft logic" question to apworld_dev_faq.md (#4953) * add a "soft logic" question to apworld_dev_faq.md * Update apworld_dev_faq.md * Update docs/apworld_dev_faq.md Co-authored-by: Scipio Wright * Update docs/apworld_dev_faq.md Co-authored-by: Scipio Wright * add a reminder about progression and how it influences soft logic implementations --------- Co-authored-by: Scipio Wright --- docs/apworld_dev_faq.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/apworld_dev_faq.md b/docs/apworld_dev_faq.md index e3e571d94949..50bee148c60e 100644 --- a/docs/apworld_dev_faq.md +++ b/docs/apworld_dev_faq.md @@ -109,3 +109,16 @@ Common situations where this can happen include: Also, consider using the `options.as_dict("option_name", "option_two")` helper. * Using enums as Location/Item names in the datapackage. When building out `location_name_to_id` and `item_name_to_id`, make sure that you are not using your enum class for either the names or ids in these mappings. + +--- + +### Some locations are technically possible to check with few or no items, but they'd be very tedious or frustrating. How do worlds deal with this? + +Sometimes the game can be modded to skip these locations or make them less tedious. But when this issue is due to a fundamental aspect of the game, then the general answer is "soft logic" (and its subtypes like "combat logic", "money logic", etc.). For example: you can logically require that a player have several helpful items before fighting the final boss, even if a skilled player technically needs no items to beat it. Randomizer logic should describe what's *fun* rather than what's technically possible. + +Concrete examples of soft logic include: +- Defeating a boss might logically require health upgrades, damage upgrades, certain weapons, etc. that aren't strictly necessary. +- Entering a high-level area might logically require access to enough other parts of the game that checking other locations should naturally get the player to the soft-required level. +- Buying expensive shop items might logically require access to a place where you can quickly farm money, or logically require access to enough parts of the game that checking other locations should naturally generate enough money without grinding. + +Remember that all items referenced by logic (however hard or soft) must be `progression`. Since you typically don't want to turn a ton of `filler` items into `progression` just for this, it's common to e.g. write money logic using only the rare "$100" item, so the dozens of "$1" and "$10" items in your world can remain `filler`. From 1ee8e339af92130bb42c74aaec93de7abc1e5742 Mon Sep 17 00:00:00 2001 From: Benjamin S Wolf Date: Wed, 7 May 2025 09:51:26 -0700 Subject: [PATCH 0399/1218] Launcher: Warn if there is no File Browser (#4275) --- Launcher.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Launcher.py b/Launcher.py index 859ebf0f768b..594286fac576 100644 --- a/Launcher.py +++ b/Launcher.py @@ -84,12 +84,16 @@ def browse_files(): def open_folder(folder_path): if is_linux: exe = which('xdg-open') or which('gnome-open') or which('kde-open') - subprocess.Popen([exe, folder_path]) elif is_macos: exe = which("open") - subprocess.Popen([exe, folder_path]) else: webbrowser.open(folder_path) + return + + if exe: + subprocess.Popen([exe, folder_path]) + else: + logging.warning(f"No file browser available to open {folder_path}") def update_settings(): From 703f5a22fda63c15f4bccebb21ee87253efc3b76 Mon Sep 17 00:00:00 2001 From: digiholic Date: Wed, 7 May 2025 11:43:03 -0600 Subject: [PATCH 0400/1218] OSRS: New Tasks, New Options, Compatibility with new Plugin Features (#4688) --- worlds/osrs/Items.py | 2 +- worlds/osrs/LogicCSV/LogicCSVToPython.py | 227 +++++++++++++------- worlds/osrs/LogicCSV/items_generated.py | 57 ++++- worlds/osrs/LogicCSV/locations_generated.py | 53 ++++- worlds/osrs/LogicCSV/regions_generated.py | 36 ++-- worlds/osrs/LogicCSV/resources_generated.py | 7 + worlds/osrs/Names.py | 6 +- worlds/osrs/Options.py | 49 ++++- worlds/osrs/Rules.py | 16 +- worlds/osrs/__init__.py | 40 +++- 10 files changed, 372 insertions(+), 121 deletions(-) diff --git a/worlds/osrs/Items.py b/worlds/osrs/Items.py index 0679c964e772..248544aa15e6 100644 --- a/worlds/osrs/Items.py +++ b/worlds/osrs/Items.py @@ -62,7 +62,7 @@ class OSRSItem(Item): ItemNames.South_Of_Varrock, ItemNames.Central_Varrock, ItemNames.Varrock_Palace, - ItemNames.East_Of_Varrock, + ItemNames.Lumberyard, ItemNames.West_Varrock, ItemNames.Edgeville, ItemNames.Barbarian_Village, diff --git a/worlds/osrs/LogicCSV/LogicCSVToPython.py b/worlds/osrs/LogicCSV/LogicCSVToPython.py index ed8bd8172a01..b66f53cc9db5 100644 --- a/worlds/osrs/LogicCSV/LogicCSVToPython.py +++ b/worlds/osrs/LogicCSV/LogicCSVToPython.py @@ -8,7 +8,9 @@ # The CSVs are updated at this repository to be shared between generator and client. data_repository_address = "https://raw.githubusercontent.com/digiholic/osrs-archipelago-logic/" # The Github tag of the CSVs this was generated with -data_csv_tag = "v1.5" +data_csv_tag = "v2.0.4" +# If true, generate using file names in the repository +debug = False if __name__ == "__main__": import sys @@ -26,98 +28,167 @@ def load_location_csv(): this_dir = os.path.dirname(os.path.abspath(__file__)) - with open(os.path.join(this_dir, "locations_generated.py"), 'w+') as locPyFile: - locPyFile.write('"""\nThis file was auto generated by LogicCSVToPython.py\n"""\n') - locPyFile.write("from ..Locations import LocationRow, SkillRequirement\n") - locPyFile.write("\n") - locPyFile.write("location_rows = [\n") - - with requests.get(data_repository_address + "/" + data_csv_tag + "/locations.csv") as req: - locations_reader = csv.reader(req.text.splitlines()) - for row in locations_reader: - row_line = "LocationRow(" - row_line += str_format(row[0]) - row_line += str_format(row[1].lower()) - - region_strings = row[2].split(", ") if row[2] else [] - row_line += f"{str_list_to_py(region_strings)}, " - - skill_strings = row[3].split(", ") - row_line += "[" - if skill_strings: - split_skills = [skill.split(" ") for skill in skill_strings if skill != ""] - if split_skills: - for split in split_skills: - row_line += f"SkillRequirement('{split[0]}', {split[1]}), " - row_line += "], " - - item_strings = row[4].split(", ") if row[4] else [] - row_line += f"{str_list_to_py(item_strings)}, " - row_line += f"{row[5]})" if row[5] != "" else "0)" - locPyFile.write(f"\t{row_line},\n") - locPyFile.write("]\n") + with open(os.path.join(this_dir, "locations_generated.py"), 'w+') as loc_py_file: + loc_py_file.write('"""\nThis file was auto generated by LogicCSVToPython.py\n"""\n') + loc_py_file.write("from ..Locations import LocationRow, SkillRequirement\n") + loc_py_file.write("\n") + loc_py_file.write("location_rows = [\n") + + if debug: + with open(os.path.join(this_dir, "locations.csv"), "r") as loc_file: + locations_reader = csv.reader(loc_file.read().splitlines()) + parse_loc_file(loc_py_file, locations_reader) + else: + print("Loading: " + data_repository_address + "/" + data_csv_tag + "/locations.csv") + with requests.get(data_repository_address + "/" + data_csv_tag + "/locations.csv") as req: + if req.status_code == 200: + locations_reader = csv.reader(req.text.splitlines()) + parse_loc_file(loc_py_file, locations_reader) + else: + print(str(req.status_code) + ": " + req.reason) + loc_py_file.write("]\n") + + + def parse_loc_file(loc_py_file, locations_reader): + for row in locations_reader: + # Skip the header row, if present + if row[0] == "Location Name": + continue + row_line = "LocationRow(" + row_line += str_format(row[0]) + row_line += str_format(row[1].lower()) + + region_strings = row[2].split(", ") if row[2] else [] + row_line += f"{str_list_to_py(region_strings)}, " + + skill_strings = row[3].split(", ") + row_line += "[" + if skill_strings: + split_skills = [skill.split(" ") for skill in skill_strings if skill != ""] + if split_skills: + for split in split_skills: + row_line += f"SkillRequirement('{split[0]}', {split[1]}), " + row_line += "], " + + item_strings = row[4].split(", ") if row[4] else [] + row_line += f"{str_list_to_py(item_strings)}, " + row_line += f"{row[5]})" if row[5] != "" else "0)" + loc_py_file.write(f"\t{row_line},\n") + def load_region_csv(): this_dir = os.path.dirname(os.path.abspath(__file__)) - with open(os.path.join(this_dir, "regions_generated.py"), 'w+') as regPyFile: - regPyFile.write('"""\nThis file was auto generated by LogicCSVToPython.py\n"""\n') - regPyFile.write("from ..Regions import RegionRow\n") - regPyFile.write("\n") - regPyFile.write("region_rows = [\n") - - with requests.get(data_repository_address + "/" + data_csv_tag + "/regions.csv") as req: - regions_reader = csv.reader(req.text.splitlines()) - for row in regions_reader: - row_line = "RegionRow(" - row_line += str_format(row[0]) - row_line += str_format(row[1]) - connections = row[2].replace("'", "\\'") - row_line += f"{str_list_to_py(connections.split(', '))}, " - resources = row[3].replace("'", "\\'") - row_line += f"{str_list_to_py(resources.split(', '))})" - regPyFile.write(f"\t{row_line},\n") - regPyFile.write("]\n") + with open(os.path.join(this_dir, "regions_generated.py"), 'w+') as reg_py_file: + reg_py_file.write('"""\nThis file was auto generated by LogicCSVToPython.py\n"""\n') + reg_py_file.write("from ..Regions import RegionRow\n") + reg_py_file.write("\n") + reg_py_file.write("region_rows = [\n") + + if debug: + with open(os.path.join(this_dir, "regions.csv"), "r") as region_file: + regions_reader = csv.reader(region_file.read().splitlines()) + parse_region_file(reg_py_file, regions_reader) + else: + print("Loading: "+ data_repository_address + "/" + data_csv_tag + "/regions.csv") + with requests.get(data_repository_address + "/" + data_csv_tag + "/regions.csv") as req: + if req.status_code == 200: + regions_reader = csv.reader(req.text.splitlines()) + parse_region_file(reg_py_file, regions_reader) + else: + print(str(req.status_code) + ": " + req.reason) + reg_py_file.write("]\n") + + + def parse_region_file(reg_py_file, regions_reader): + for row in regions_reader: + # Skip the header row, if present + if row[0] == "Region Name": + continue + + row_line = "RegionRow(" + row_line += str_format(row[0]) + row_line += str_format(row[1]) + connections = row[2] + row_line += f"{str_list_to_py(connections.split(', '))}, " + resources = row[3] + row_line += f"{str_list_to_py(resources.split(', '))})" + reg_py_file.write(f"\t{row_line},\n") + def load_resource_csv(): this_dir = os.path.dirname(os.path.abspath(__file__)) - with open(os.path.join(this_dir, "resources_generated.py"), 'w+') as resPyFile: - resPyFile.write('"""\nThis file was auto generated by LogicCSVToPython.py\n"""\n') - resPyFile.write("from ..Regions import ResourceRow\n") - resPyFile.write("\n") - resPyFile.write("resource_rows = [\n") - - with requests.get(data_repository_address + "/" + data_csv_tag + "/resources.csv") as req: - resource_reader = csv.reader(req.text.splitlines()) - for row in resource_reader: - name = row[0].replace("'", "\\'") - row_line = f"ResourceRow('{name}')" - resPyFile.write(f"\t{row_line},\n") - resPyFile.write("]\n") + with open(os.path.join(this_dir, "resources_generated.py"), 'w+') as res_py_file: + res_py_file.write('"""\nThis file was auto generated by LogicCSVToPython.py\n"""\n') + res_py_file.write("from ..Regions import ResourceRow\n") + res_py_file.write("\n") + res_py_file.write("resource_rows = [\n") + + if debug: + with open(os.path.join(this_dir, "resources.csv"), "r") as region_file: + regions_reader = csv.reader(region_file.read().splitlines()) + parse_resources_file(res_py_file, regions_reader) + else: + print("Loading: " + data_repository_address + "/" + data_csv_tag + "/resources.csv") + with requests.get(data_repository_address + "/" + data_csv_tag + "/resources.csv") as req: + if req.status_code == 200: + resource_reader = csv.reader(req.text.splitlines()) + parse_resources_file(res_py_file, resource_reader) + else: + print(str(req.status_code) + ": " + req.reason) + res_py_file.write("]\n") + + + def parse_resources_file(res_py_file, resource_reader): + for row in resource_reader: + # Skip the header row, if present + if row[0] == "Resource Name": + continue + + name = row[0].replace("'", "\\'") + row_line = f"ResourceRow('{name}')" + res_py_file.write(f"\t{row_line},\n") def load_item_csv(): this_dir = os.path.dirname(os.path.abspath(__file__)) - with open(os.path.join(this_dir, "items_generated.py"), 'w+') as itemPyfile: - itemPyfile.write('"""\nThis file was auto generated by LogicCSVToPython.py\n"""\n') - itemPyfile.write("from BaseClasses import ItemClassification\n") - itemPyfile.write("from ..Items import ItemRow\n") - itemPyfile.write("\n") - itemPyfile.write("item_rows = [\n") + with open(os.path.join(this_dir, "items_generated.py"), 'w+') as item_py_file: + item_py_file.write('"""\nThis file was auto generated by LogicCSVToPython.py\n"""\n') + item_py_file.write("from BaseClasses import ItemClassification\n") + item_py_file.write("from ..Items import ItemRow\n") + item_py_file.write("\n") + item_py_file.write("item_rows = [\n") + + if debug: + with open(os.path.join(this_dir, "items.csv"), "r") as region_file: + regions_reader = csv.reader(region_file.read().splitlines()) + parse_item_file(item_py_file, regions_reader) + else: + print("Loading: " + data_repository_address + "/" + data_csv_tag + "/items.csv") + with requests.get(data_repository_address + "/" + data_csv_tag + "/items.csv") as req: + if req.status_code == 200: + item_reader = csv.reader(req.text.splitlines()) + parse_item_file(item_py_file, item_reader) + else: + print(str(req.status_code) + ": " + req.reason) + item_py_file.write("]\n") + + + def parse_item_file(item_py_file, item_reader): + for row in item_reader: + # Skip the header row, if present + if row[0] == "Name": + continue - with requests.get(data_repository_address + "/" + data_csv_tag + "/items.csv") as req: - item_reader = csv.reader(req.text.splitlines()) - for row in item_reader: - row_line = "ItemRow(" - row_line += str_format(row[0]) - row_line += f"{row[1]}, " + row_line = "ItemRow(" + row_line += str_format(row[0]) + row_line += f"{row[1]}, " - row_line += f"ItemClassification.{row[2]})" + row_line += f"ItemClassification.{row[2]})" - itemPyfile.write(f"\t{row_line},\n") - itemPyfile.write("]\n") + item_py_file.write(f"\t{row_line},\n") def str_format(s) -> str: @@ -128,7 +199,7 @@ def str_format(s) -> str: def str_list_to_py(str_list) -> str: ret_str = "[" for s in str_list: - ret_str += f"'{s}', " + ret_str += str_format(s) ret_str += "]" return ret_str diff --git a/worlds/osrs/LogicCSV/items_generated.py b/worlds/osrs/LogicCSV/items_generated.py index b5e610a6e3ab..3a277b8d5e4f 100644 --- a/worlds/osrs/LogicCSV/items_generated.py +++ b/worlds/osrs/LogicCSV/items_generated.py @@ -10,7 +10,7 @@ ItemRow('Area: HAM Hideout', 1, ItemClassification.progression), ItemRow('Area: Lumbridge Farms', 1, ItemClassification.progression), ItemRow('Area: South of Varrock', 1, ItemClassification.progression), - ItemRow('Area: East Varrock', 1, ItemClassification.progression), + ItemRow('Area: Lumberyard', 1, ItemClassification.progression), ItemRow('Area: Central Varrock', 1, ItemClassification.progression), ItemRow('Area: Varrock Palace', 1, ItemClassification.progression), ItemRow('Area: West Varrock', 1, ItemClassification.progression), @@ -37,7 +37,58 @@ ItemRow('Progressive Armor', 6, ItemClassification.progression), ItemRow('Progressive Weapons', 6, ItemClassification.progression), ItemRow('Progressive Tools', 6, ItemClassification.useful), - ItemRow('Progressive Ranged Weapons', 3, ItemClassification.useful), + ItemRow('Progressive Ranged Weapon', 3, ItemClassification.useful), ItemRow('Progressive Ranged Armor', 3, ItemClassification.useful), - ItemRow('Progressive Magic', 2, ItemClassification.useful), + ItemRow('Progressive Magic Spell', 2, ItemClassification.useful), + ItemRow('An Invitation to the Gielinor Games', 1, ItemClassification.filler), + ItemRow('Settled\'s Crossbow', 1, ItemClassification.filler), + ItemRow('The Stone of Jas', 1, ItemClassification.filler), + ItemRow('Nieve\'s Phone Number', 1, ItemClassification.filler), + ItemRow('Hannanie\'s Lost Sanity', 1, ItemClassification.filler), + ItemRow('XP Waste', 1, ItemClassification.filler), + ItemRow('Ten Free Pulls on the Squeal of Fortune', 1, ItemClassification.filler), + ItemRow('Project Zanaris Beta Invite', 1, ItemClassification.filler), + ItemRow('A Funny Feeling You Would Have Been Followed', 1, ItemClassification.filler), + ItemRow('An Ominous Prediction From Gnome Child', 1, ItemClassification.filler), + ItemRow('A Logic Error', 1, ItemClassification.filler), + ItemRow('The Warding Skill', 1, ItemClassification.filler), + ItemRow('A 1/2500 Chance At Your Very Own Pet Baron Sucellus, Redeemable at your Local Duke, Some Restrictions May Apply', 1, ItemClassification.filler), + ItemRow('A Suspicious Email From Iagex.com Asking for your Password', 1, ItemClassification.filler), + ItemRow('A Review on that Pull Request You\'ve Been Waiting On', 1, ItemClassification.filler), + ItemRow('Fifty Billion RS3 GP (Worthless)', 1, ItemClassification.filler), + ItemRow('Mod Ash\'s Coffee Cup', 1, ItemClassification.filler), + ItemRow('An Embarrasing Photo of Zammorak at the Christmas Party', 1, ItemClassification.filler), + ItemRow('Another Bug To Report', 1, ItemClassification.filler), + ItemRow('1-Up Mushroom', 1, ItemClassification.filler), + ItemRow('Empty White Hallways', 1, ItemClassification.filler), + ItemRow('Area: Menaphos', 1, ItemClassification.filler), + ItemRow('A Ratcatchers Dialogue Rewrite', 1, ItemClassification.filler), + ItemRow('"Nostalgia"', 1, ItemClassification.filler), + ItemRow('A Hornless Unicorn', 1, ItemClassification.filler), + ItemRow('The Ability To Use ::bank', 1, ItemClassification.filler), + ItemRow('Free Haircut at the Falador Hairdresser', 1, ItemClassification.filler), + ItemRow('Nothing Interesting Happens', 1, ItemClassification.filler), + ItemRow('Why Fletch?', 1, ItemClassification.filler), + ItemRow('Evolution of Combat', 1, ItemClassification.filler), + ItemRow('Care Pack: 10,000 GP', 1, ItemClassification.useful), + ItemRow('Care Pack: 90 Steel Nails', 1, ItemClassification.useful), + ItemRow('Care Pack: 25 Swordfish', 1, ItemClassification.useful), + ItemRow('Care Pack: 50 Lobsters', 1, ItemClassification.useful), + ItemRow('Care Pack: 100 Law Runes', 1, ItemClassification.useful), + ItemRow('Care Pack: 300 Each Elemental Rune', 1, ItemClassification.useful), + ItemRow('Care Pack: 100 Chaos Runes', 1, ItemClassification.useful), + ItemRow('Care Pack: 100 Death Runes', 1, ItemClassification.useful), + ItemRow('Care Pack: 100 Oak Logs', 1, ItemClassification.useful), + ItemRow('Care Pack: 50 Willow Logs', 1, ItemClassification.useful), + ItemRow('Care Pack: 50 Bronze Bars', 1, ItemClassification.useful), + ItemRow('Care Pack: 200 Iron Ore', 1, ItemClassification.useful), + ItemRow('Care Pack: 100 Coal Ore', 1, ItemClassification.useful), + ItemRow('Care Pack: 100 Raw Trout', 1, ItemClassification.useful), + ItemRow('Care Pack: 200 Leather', 1, ItemClassification.useful), + ItemRow('Care Pack: 50 Energy Potion (4)', 2, ItemClassification.useful), + ItemRow('Care Pack: 200 Big Bones', 1, ItemClassification.useful), + ItemRow('Care Pack: 10 Each Uncut gems', 1, ItemClassification.useful), + ItemRow('Care Pack: 3 Rings of Forging', 1, ItemClassification.useful), + ItemRow('Care Pack: 500 Rune Essence', 1, ItemClassification.useful), + ItemRow('Care Pack: 200 Mind Runes', 1, ItemClassification.useful), ] diff --git a/worlds/osrs/LogicCSV/locations_generated.py b/worlds/osrs/LogicCSV/locations_generated.py index 2d617a7038fe..4c1cd0bdd893 100644 --- a/worlds/osrs/LogicCSV/locations_generated.py +++ b/worlds/osrs/LogicCSV/locations_generated.py @@ -19,37 +19,56 @@ LocationRow('Quest: Witch\'s Potion', 'quest', ['Rimmington', 'Port Sarim', ], [], [], 0), LocationRow('Quest: The Knight\'s Sword', 'quest', ['Falador', 'Varrock Palace', 'Mudskipper Point', 'South of Varrock', 'Windmill', 'Pie Dish', 'Port Sarim', ], [SkillRequirement('Cooking', 10), SkillRequirement('Mining', 10), ], [], 0), LocationRow('Quest: Goblin Diplomacy', 'quest', ['Goblin Village', 'Draynor Village', 'Falador', 'South of Varrock', 'Onion', ], [], [], 0), - LocationRow('Quest: Pirate\'s Treasure', 'quest', ['Port Sarim', 'Karamja', 'Falador', ], [], [], 0), + LocationRow('Quest: Pirate\'s Treasure', 'quest', ['Port Sarim', 'Karamja', 'Falador', 'Central Varrock', ], [], [], 0), LocationRow('Quest: Rune Mysteries', 'quest', ['Lumbridge', 'Wizard Tower', 'Central Varrock', ], [], [], 0), LocationRow('Quest: Misthalin Mystery', 'quest', ['Lumbridge Swamp', ], [], [], 0), LocationRow('Quest: The Corsair Curse', 'quest', ['Rimmington', 'Falador Farms', 'Corsair Cove', ], [], [], 0), LocationRow('Quest: X Marks the Spot', 'quest', ['Lumbridge', 'Draynor Village', 'Port Sarim', ], [], [], 0), LocationRow('Quest: Below Ice Mountain', 'quest', ['Dwarven Mines', 'Dwarven Mountain Pass', 'Ice Mountain', 'Barbarian Village', 'Falador', 'Central Varrock', 'Edgeville', ], [], [], 16), LocationRow('Quest: Dragon Slayer', 'goal', ['Crandor', 'South of Varrock', 'Edgeville', 'Lumbridge', 'Rimmington', 'Monastery', 'Dwarven Mines', 'Port Sarim', 'Draynor Village', ], [], [], 32), + LocationRow('Bury Some Big Bones', 'prayer', ['Big Bones', ], [SkillRequirement('Prayer', 1), ], [], 0), + LocationRow('Activate the "Sharp Eye" Prayer', 'prayer', [], [SkillRequirement('Prayer', 8), ], [], 0), LocationRow('Activate the "Rock Skin" Prayer', 'prayer', [], [SkillRequirement('Prayer', 10), ], [], 0), LocationRow('Activate the "Protect Item" Prayer', 'prayer', [], [SkillRequirement('Prayer', 25), ], [], 2), LocationRow('Pray at the Edgeville Monastery', 'prayer', ['Monastery', ], [SkillRequirement('Prayer', 31), ], [], 6), LocationRow('Cast Bones To Bananas', 'magic', ['Nature Runes', ], [SkillRequirement('Magic', 15), ], [], 0), + LocationRow('Cast Earth Strike', 'magic', [], [SkillRequirement('Magic', 9), ], [], 0), + LocationRow('Cast Curse', 'magic', [], [SkillRequirement('Magic', 19), ], [], 0), LocationRow('Teleport to Varrock', 'magic', ['Central Varrock', 'Law Runes', ], [SkillRequirement('Magic', 25), ], [], 0), - LocationRow('Teleport to Lumbridge', 'magic', ['Lumbridge', 'Law Runes', ], [SkillRequirement('Magic', 31), ], [], 2), + LocationRow('Teleport to Lumbridge', 'magic', ['Lumbridge', 'Law Runes', ], [SkillRequirement('Magic', 31), ], [], 0), + LocationRow('Telegrab a Gold Bar from the Varrock Bank', 'magic', ['Law Runes', 'West Varrock', ], [SkillRequirement('Magic', 33), ], [], 0), LocationRow('Teleport to Falador', 'magic', ['Falador', 'Law Runes', ], [SkillRequirement('Magic', 37), ], [], 6), LocationRow('Craft an Air Rune', 'runecraft', ['Rune Essence', 'Falador Farms', ], [SkillRequirement('Runecraft', 1), ], [], 0), + LocationRow('Craft a Mind Rune', 'runecraft', ['Rune Essence', 'Goblin Village', ], [SkillRequirement('Runecraft', 2), ], [], 0), + LocationRow('Craft a Water Rune', 'runecraft', ['Rune Essence', 'Lumbridge Swamp', ], [SkillRequirement('Runecraft', 5), ], [], 0), + LocationRow('Craft an Earth Rune', 'runecraft', ['Rune Essence', 'Lumberyard', ], [SkillRequirement('Runecraft', 9), ], [], 0), + LocationRow('Craft a Fire Rune', 'runecraft', ['Rune Essence', 'Al Kharid', ], [SkillRequirement('Runecraft', 14), ], [], 0), + LocationRow('Craft a Body Rune', 'runecraft', ['Rune Essence', 'Dwarven Mountain Pass', ], [SkillRequirement('Runecraft', 20), ], [], 0), LocationRow('Craft runes with a Mind Core', 'runecraft', ['Camdozaal', 'Goblin Village', ], [SkillRequirement('Runecraft', 2), ], [], 0), LocationRow('Craft runes with a Body Core', 'runecraft', ['Camdozaal', 'Dwarven Mountain Pass', ], [SkillRequirement('Runecraft', 20), ], [], 0), + LocationRow('Craft a Pot', 'crafting', ['Clay Ore', 'Barbarian Village', ], [SkillRequirement('Crafting', 1), ], [], 0), + LocationRow('Craft a pair of Leather Boots', 'crafting', ['Milk', 'Al Kharid', ], [SkillRequirement('Crafting', 7), ], [], 0), LocationRow('Make an Unblessed Symbol', 'crafting', ['Silver Ore', 'Furnace', 'Al Kharid', 'Sheep', 'Spinning Wheel', ], [SkillRequirement('Crafting', 16), ], [], 0), LocationRow('Cut a Sapphire', 'crafting', ['Chisel', ], [SkillRequirement('Crafting', 20), ], [], 0), LocationRow('Cut an Emerald', 'crafting', ['Chisel', ], [SkillRequirement('Crafting', 27), ], [], 0), LocationRow('Cut a Ruby', 'crafting', ['Chisel', ], [SkillRequirement('Crafting', 34), ], [], 4), + LocationRow('Enter the Crafting Guild', 'crafting', ['Crafting Guild', ], [SkillRequirement('Crafting', 40), ], [], 0), LocationRow('Cut a Diamond', 'crafting', ['Chisel', ], [SkillRequirement('Crafting', 43), ], [], 8), + LocationRow('Mine Copper', 'crafting', ['Bronze Ores', ], [SkillRequirement('Mining', 1), ], [], 0), + LocationRow('Mine Tin', 'crafting', ['Bronze Ores', ], [SkillRequirement('Mining', 1), ], [], 0), + LocationRow('Mine Clay', 'crafting', ['Clay Ore', ], [SkillRequirement('Mining', 1), ], [], 0), + LocationRow('Mine Iron', 'mining', ['Iron Ore', ], [SkillRequirement('Mining', 1), ], [], 0), LocationRow('Mine a Blurite Ore', 'mining', ['Mudskipper Point', 'Port Sarim', ], [SkillRequirement('Mining', 10), ], [], 0), LocationRow('Crush a Barronite Deposit', 'mining', ['Camdozaal', ], [SkillRequirement('Mining', 14), ], [], 0), LocationRow('Mine Silver', 'mining', ['Silver Ore', ], [SkillRequirement('Mining', 20), ], [], 0), LocationRow('Mine Coal', 'mining', ['Coal Ore', ], [SkillRequirement('Mining', 30), ], [], 2), LocationRow('Mine Gold', 'mining', ['Gold Ore', ], [SkillRequirement('Mining', 40), ], [], 6), + LocationRow('Smelt a Bronze Bar', 'smithing', ['Bronze Ores', 'Furnace', ], [SkillRequirement('Smithing', 1), SkillRequirement('Mining', 1), ], [], 0), LocationRow('Smelt an Iron Bar', 'smithing', ['Iron Ore', 'Furnace', ], [SkillRequirement('Smithing', 15), SkillRequirement('Mining', 15), ], [], 0), LocationRow('Smelt a Silver Bar', 'smithing', ['Silver Ore', 'Furnace', ], [SkillRequirement('Smithing', 20), SkillRequirement('Mining', 20), ], [], 0), LocationRow('Smelt a Steel Bar', 'smithing', ['Coal Ore', 'Iron Ore', 'Furnace', ], [SkillRequirement('Smithing', 30), SkillRequirement('Mining', 30), ], [], 2), LocationRow('Smelt a Gold Bar', 'smithing', ['Gold Ore', 'Furnace', ], [SkillRequirement('Smithing', 40), SkillRequirement('Mining', 40), ], [], 6), + LocationRow('Catch a Sardine', 'fishing', ['Shrimp Spot', ], [SkillRequirement('Fishing', 5), ], [], 0), LocationRow('Catch some Anchovies', 'fishing', ['Shrimp Spot', ], [SkillRequirement('Fishing', 15), ], [], 0), LocationRow('Catch a Trout', 'fishing', ['Fly Fishing Spot', ], [SkillRequirement('Fishing', 20), ], [], 0), LocationRow('Prepare a Tetra', 'fishing', ['Camdozaal', ], [SkillRequirement('Fishing', 33), SkillRequirement('Cooking', 33), ], [], 2), @@ -58,13 +77,16 @@ LocationRow('Bake a Redberry Pie', 'cooking', ['Redberry Bush', 'Wheat', 'Windmill', 'Pie Dish', ], [SkillRequirement('Cooking', 10), ], [], 0), LocationRow('Cook some Stew', 'cooking', ['Bowl', 'Meat', 'Potato', ], [SkillRequirement('Cooking', 25), ], [], 0), LocationRow('Bake an Apple Pie', 'cooking', ['Cooking Apple', 'Wheat', 'Windmill', 'Pie Dish', ], [SkillRequirement('Cooking', 32), ], [], 2), + LocationRow('Enter the Cook\'s Guild', 'cooking', ['Cook\'s Guild', ], [], [], 0), LocationRow('Bake a Cake', 'cooking', ['Wheat', 'Windmill', 'Egg', 'Milk', 'Cake Tin', ], [SkillRequirement('Cooking', 40), ], [], 6), LocationRow('Bake a Meat Pizza', 'cooking', ['Wheat', 'Windmill', 'Cheese', 'Tomato', 'Meat', ], [SkillRequirement('Cooking', 45), ], [], 8), + LocationRow('Burn a Log', 'firemaking', [], [SkillRequirement('Firemaking', 1), SkillRequirement('Woodcutting', 1), ], [], 0), LocationRow('Burn some Oak Logs', 'firemaking', ['Oak Tree', ], [SkillRequirement('Firemaking', 15), SkillRequirement('Woodcutting', 15), ], [], 0), LocationRow('Burn some Willow Logs', 'firemaking', ['Willow Tree', ], [SkillRequirement('Firemaking', 30), SkillRequirement('Woodcutting', 30), ], [], 0), LocationRow('Travel on a Canoe', 'woodcutting', ['Canoe Tree', ], [SkillRequirement('Woodcutting', 12), ], [], 0), LocationRow('Cut an Oak Log', 'woodcutting', ['Oak Tree', ], [SkillRequirement('Woodcutting', 15), ], [], 0), LocationRow('Cut a Willow Log', 'woodcutting', ['Willow Tree', ], [SkillRequirement('Woodcutting', 30), ], [], 0), + LocationRow('Kill a Duck', 'combat', ['Duck', ], [SkillRequirement('Combat', 1), ], [], 0), LocationRow('Kill Jeff', 'combat', ['Dwarven Mountain Pass', ], [SkillRequirement('Combat', 2), ], [], 0), LocationRow('Kill a Goblin', 'combat', ['Goblin', ], [SkillRequirement('Combat', 2), ], [], 0), LocationRow('Kill a Monkey', 'combat', ['Karamja', ], [SkillRequirement('Combat', 3), ], [], 0), @@ -81,19 +103,24 @@ LocationRow('Kill an Ogress Shaman', 'combat', ['Corsair Cove', ], [SkillRequirement('Combat', 82), ], [], 8), LocationRow('Kill Obor', 'combat', ['Edgeville', ], [SkillRequirement('Combat', 106), ], [], 28), LocationRow('Kill Bryophyta', 'combat', ['Central Varrock', ], [SkillRequirement('Combat', 128), ], [], 28), + LocationRow('Die', 'general', [], [], [], 0), + LocationRow('Reach a Level 10', 'general', [], [], [], 0), LocationRow('Total XP 5,000', 'general', [], [], [], 0), LocationRow('Combat Level 5', 'general', [], [], [], 0), LocationRow('Total XP 10,000', 'general', [], [], [], 0), LocationRow('Total Level 50', 'general', [], [], [], 0), + LocationRow('Reach a Level 20', 'general', [], [], [], 0), LocationRow('Total XP 25,000', 'general', [], [], [], 0), LocationRow('Total Level 100', 'general', [], [], [], 0), LocationRow('Total XP 50,000', 'general', [], [], [], 0), LocationRow('Combat Level 15', 'general', [], [], [], 0), LocationRow('Total Level 150', 'general', [], [], [], 2), + LocationRow('Reach a Level 30', 'general', [], [], [], 2), LocationRow('Total XP 75,000', 'general', [], [], [], 2), LocationRow('Combat Level 25', 'general', [], [], [], 2), LocationRow('Total XP 100,000', 'general', [], [], [], 6), LocationRow('Total Level 200', 'general', [], [], [], 6), + LocationRow('Reach a Level 40', 'general', [], [], [], 6), LocationRow('Total XP 125,000', 'general', [], [], [], 6), LocationRow('Combat Level 30', 'general', [], [], [], 10), LocationRow('Total Level 250', 'general', [], [], [], 10), @@ -103,6 +130,28 @@ LocationRow('Open a Simple Lockbox', 'general', ['Camdozaal', ], [], [], 0), LocationRow('Open an Elaborate Lockbox', 'general', ['Camdozaal', ], [], [], 0), LocationRow('Open an Ornate Lockbox', 'general', ['Camdozaal', ], [], [], 0), + LocationRow('Trans your Gender', 'general', ['Makeover', ], [], [], 0), + LocationRow('Read a Flyer from Ali the Leaflet Dropper', 'general', ['Al Kharid', 'South of Varrock', ], [], [], 0), + LocationRow('Cry by the Members Gate to Taverley', 'general', ['Dwarven Mountain Pass', ], [], [], 0), + LocationRow('Get Prompted to Buy Membership', 'general', [], [], [], 0), + LocationRow('Pet the Stray Dog in Varrock', 'general', ['Central Varrock', 'West Varrock', 'South of Varrock', ], [], [], 0), + LocationRow('Get Sent to Jail in Shantay Pass', 'general', ['Al Kharid', 'Port Sarim', ], [], [], 0), + LocationRow('Have the Apothecary Make a Strength Potion', 'general', ['Central Varrock', 'Red Spider Eggs', 'Limpwurt Root', ], [], [], 0), + LocationRow('Put a Whole Banana into a Bottle of Karamjan Rum', 'general', ['Karamja', ], [], [], 0), + LocationRow('Attempt to Shear "The Thing"', 'general', ['Lumbridge Farms West', ], [], [], 0), + LocationRow('Eat a Kebab', 'general', ['Al Kharid', ], [], [], 0), + LocationRow('Return a Beer Glass to a Bar', 'general', ['Falador', ], [], [], 0), + LocationRow('Enter the Varrock Bear Cage', 'general', ['Varrock Palace', ], [], [], 0), + LocationRow('Equip a Cabbage Cape', 'general', ['Draynor Village', ], [], [], 0), + LocationRow('Equip a Pride Scarf', 'general', ['Draynor Village', ], [], [], 0), + LocationRow('Visit the Black Hole', 'general', ['Draynor Village', 'Dwarven Mines', ], [], [], 0), + LocationRow('Try to Equip Goblin Mail', 'general', ['Goblin', ], [], [], 0), + LocationRow('Equip an Orange Cape', 'general', ['Draynor Village', ], [], [], 0), + LocationRow('Find a Needle in a Haystack', 'general', ['Haystack', ], [], [], 0), + LocationRow('Insult the Homeless (but not Charlie he\'s cool)', 'general', ['Central Varrock', 'South of Varrock', ], [], [], 0), + LocationRow('Dance with Party Pete', 'general', ['Falador', ], [], [], 0), + LocationRow('Read a Newspaper', 'general', ['Central Varrock', ], [], [], 0), + LocationRow('Add a Card to the Chronicle', 'general', ['Draynor Village', ], [], [], 0), LocationRow('Points: Cook\'s Assistant', 'points', [], [], [], 0), LocationRow('Points: Demon Slayer', 'points', [], [], [], 0), LocationRow('Points: The Restless Ghost', 'points', [], [], [], 0), diff --git a/worlds/osrs/LogicCSV/regions_generated.py b/worlds/osrs/LogicCSV/regions_generated.py index 87b3747d938e..512cd3b268d5 100644 --- a/worlds/osrs/LogicCSV/regions_generated.py +++ b/worlds/osrs/LogicCSV/regions_generated.py @@ -4,19 +4,19 @@ from ..Regions import RegionRow region_rows = [ - RegionRow('Lumbridge', 'Area: Lumbridge', ['Lumbridge Farms East', 'Lumbridge Farms West', 'Al Kharid', 'Lumbridge Swamp', 'HAM Hideout', 'South of Varrock', 'Barbarian Village', 'Edgeville', 'Wilderness', ], ['Mind Runes', 'Spinning Wheel', 'Furnace', 'Chisel', 'Bronze Anvil', 'Fly Fishing Spot', 'Bowl', 'Cake Tin', 'Oak Tree', 'Willow Tree', 'Canoe Tree', 'Goblin', 'Imps', ]), - RegionRow('Lumbridge Swamp', 'Area: Lumbridge Swamp', ['Lumbridge', 'HAM Hideout', ], ['Bronze Ores', 'Coal Ore', 'Shrimp Spot', 'Meat', 'Goblin', 'Imps', ]), + RegionRow('Lumbridge', 'Area: Lumbridge', ['Lumbridge Farms East', 'Lumbridge Farms West', 'Al Kharid', 'Lumbridge Swamp', 'HAM Hideout', 'South of Varrock', 'Barbarian Village', 'Edgeville', 'Wilderness', ], ['Mind Runes', 'Spinning Wheel', 'Furnace', 'Chisel', 'Bronze Anvil', 'Fly Fishing Spot', 'Bowl', 'Cake Tin', 'Oak Tree', 'Willow Tree', 'Canoe Tree', 'Goblin', 'Imps', 'Duck', 'Bar', ]), + RegionRow('Lumbridge Swamp', 'Area: Lumbridge Swamp', ['Lumbridge', 'HAM Hideout', ], ['Bronze Ores', 'Coal Ore', 'Shrimp Spot', 'Meat', 'Goblin', 'Imps', 'Big Bones', 'Duck', ]), RegionRow('HAM Hideout', 'Area: HAM Hideout', ['Lumbridge Farms West', 'Lumbridge', 'Lumbridge Swamp', 'Draynor Village', ], ['Goblin', ]), - RegionRow('Lumbridge Farms West', 'Area: Lumbridge Farms', ['Sourhog\'s Lair', 'HAM Hideout', 'Draynor Village', ], ['Sheep', 'Meat', 'Wheat', 'Windmill', 'Egg', 'Milk', 'Willow Tree', 'Imps', 'Potato', ]), + RegionRow('Lumbridge Farms West', 'Area: Lumbridge Farms', ['Sourhog\'s Lair', 'HAM Hideout', 'Draynor Village', ], ['Sheep', 'Meat', 'Wheat', 'Windmill', 'Egg', 'Milk', 'Willow Tree', 'Imps', 'Potato', 'Haystack', ]), RegionRow('Lumbridge Farms East', 'Area: Lumbridge Farms', ['South of Varrock', 'Lumbridge', ], ['Meat', 'Egg', 'Milk', 'Willow Tree', 'Goblin', 'Imps', 'Potato', ]), RegionRow('Sourhog\'s Lair', 'Area: South of Varrock', ['Lumbridge Farms West', 'Draynor Manor Outskirts', ], ['', ]), - RegionRow('South of Varrock', 'Area: South of Varrock', ['Al Kharid', 'West Varrock', 'Central Varrock', 'East Varrock', 'Lumbridge Farms East', 'Lumbridge', 'Barbarian Village', 'Edgeville', 'Wilderness', ], ['Sheep', 'Bronze Ores', 'Iron Ore', 'Silver Ore', 'Redberry Bush', 'Meat', 'Wheat', 'Oak Tree', 'Willow Tree', 'Canoe Tree', 'Guard', 'Imps', 'Clay Ore', ]), - RegionRow('East Varrock', 'Area: East Varrock', ['Wilderness', 'South of Varrock', 'Central Varrock', 'Varrock Palace', ], ['Guard', ]), - RegionRow('Central Varrock', 'Area: Central Varrock', ['Varrock Palace', 'East Varrock', 'South of Varrock', 'West Varrock', ], ['Mind Runes', 'Chisel', 'Anvil', 'Bowl', 'Cake Tin', 'Oak Tree', 'Barbarian', 'Guard', 'Rune Essence', 'Imps', ]), - RegionRow('Varrock Palace', 'Area: Varrock Palace', ['Wilderness', 'East Varrock', 'Central Varrock', 'West Varrock', ], ['Pie Dish', 'Oak Tree', 'Zombie', 'Guard', 'Deadly Red Spider', 'Moss Giant', 'Nature Runes', 'Law Runes', ]), + RegionRow('South of Varrock', 'Area: South of Varrock', ['Al Kharid', 'West Varrock', 'Central Varrock', 'Lumberyard', 'Lumbridge Farms East', 'Lumbridge', 'Barbarian Village', 'Edgeville', 'Wilderness', ], ['Sheep', 'Bronze Ores', 'Iron Ore', 'Silver Ore', 'Redberry Bush', 'Meat', 'Wheat', 'Oak Tree', 'Willow Tree', 'Canoe Tree', 'Guard', 'Imps', 'Clay Ore', 'Duck', ]), + RegionRow('Lumberyard', 'Area: Lumberyard', ['Wilderness', 'South of Varrock', 'Central Varrock', 'Varrock Palace', ], ['Guard', 'Bar', ]), + RegionRow('Central Varrock', 'Area: Central Varrock', ['Varrock Palace', 'Lumberyard', 'South of Varrock', 'West Varrock', ], ['Mind Runes', 'Chisel', 'Anvil', 'Bowl', 'Cake Tin', 'Oak Tree', 'Barbarian', 'Guard', 'Rune Essence', 'Imps', 'Makeover', 'Bar', ]), + RegionRow('Varrock Palace', 'Area: Varrock Palace', ['Wilderness', 'Lumberyard', 'Central Varrock', 'West Varrock', ], ['Pie Dish', 'Oak Tree', 'Zombie', 'Guard', 'Deadly Red Spider', 'Moss Giant', 'Nature Runes', 'Law Runes', 'Big Bones', 'Makeover', 'Red Spider Eggs', ]), RegionRow('West Varrock', 'Area: West Varrock', ['Wilderness', 'Varrock Palace', 'South of Varrock', 'Barbarian Village', 'Edgeville', 'Cook\'s Guild', ], ['Anvil', 'Wheat', 'Oak Tree', 'Goblin', 'Guard', 'Onion', ]), RegionRow('Cook\'s Guild', 'Area: West Varrock*', ['West Varrock', ], ['Bowl', 'Cooking Apple', 'Pie Dish', 'Cake Tin', 'Windmill', ]), - RegionRow('Edgeville', 'Area: Edgeville', ['Wilderness', 'West Varrock', 'Barbarian Village', 'South of Varrock', 'Lumbridge', ], ['Furnace', 'Chisel', 'Bronze Ores', 'Iron Ore', 'Coal Ore', 'Bowl', 'Meat', 'Cake Tin', 'Willow Tree', 'Canoe Tree', 'Zombie', 'Guard', 'Hill Giant', 'Nature Runes', 'Law Runes', 'Imps', ]), + RegionRow('Edgeville', 'Area: Edgeville', ['Wilderness', 'West Varrock', 'Barbarian Village', 'South of Varrock', 'Lumbridge', ], ['Furnace', 'Chisel', 'Bronze Ores', 'Iron Ore', 'Coal Ore', 'Bowl', 'Meat', 'Cake Tin', 'Willow Tree', 'Canoe Tree', 'Zombie', 'Guard', 'Hill Giant', 'Nature Runes', 'Law Runes', 'Imps', 'Big Bones', 'Limpwurt Root', 'Haystack', ]), RegionRow('Barbarian Village', 'Area: Barbarian Village', ['Edgeville', 'West Varrock', 'Draynor Manor Outskirts', 'Dwarven Mountain Pass', ], ['Spinning Wheel', 'Coal Ore', 'Anvil', 'Fly Fishing Spot', 'Meat', 'Canoe Tree', 'Barbarian', 'Zombie', 'Law Runes', ]), RegionRow('Draynor Manor Outskirts', 'Area: Draynor Manor', ['Barbarian Village', 'Sourhog\'s Lair', 'Draynor Village', 'Falador East Outskirts', ], ['Goblin', ]), RegionRow('Draynor Manor', 'Area: Draynor Manor', ['Draynor Village', ], ['', ]), @@ -27,21 +27,21 @@ RegionRow('Ice Mountain', 'Area: Ice Mountain', ['Wilderness', 'Monastery', 'Dwarven Mines', 'Camdozaal*', ], ['', ]), RegionRow('Camdozaal', 'Area: Ice Mountain', ['Ice Mountain', ], ['Clay Ore', ]), RegionRow('Monastery', 'Area: Monastery', ['Wilderness', 'Dwarven Mountain Pass', 'Dwarven Mines', 'Ice Mountain', ], ['Sheep', ]), - RegionRow('Falador', 'Area: Falador', ['Dwarven Mountain Pass', 'Falador Farms', 'Dwarven Mines', ], ['Furnace', 'Chisel', 'Bowl', 'Cake Tin', 'Oak Tree', 'Guard', 'Imps', ]), - RegionRow('Falador Farms', 'Area: Falador Farms', ['Falador', 'Falador East Outskirts', 'Draynor Village', 'Port Sarim', 'Rimmington', 'Crafting Guild Outskirts', ], ['Spinning Wheel', 'Meat', 'Egg', 'Milk', 'Oak Tree', 'Imps', ]), + RegionRow('Falador', 'Area: Falador', ['Dwarven Mountain Pass', 'Falador Farms', 'Dwarven Mines', ], ['Furnace', 'Chisel', 'Bowl', 'Cake Tin', 'Oak Tree', 'Guard', 'Imps', 'Duck', 'Makeover', 'Bar', ]), + RegionRow('Falador Farms', 'Area: Falador Farms', ['Falador', 'Falador East Outskirts', 'Draynor Village', 'Port Sarim', 'Rimmington', 'Crafting Guild Outskirts', ], ['Spinning Wheel', 'Meat', 'Egg', 'Milk', 'Oak Tree', 'Imps', 'Duck', ]), RegionRow('Port Sarim', 'Area: Port Sarim', ['Falador Farms', 'Mudskipper Point', 'Rimmington', 'Karamja Docks', 'Crandor', ], ['Mind Runes', 'Shrimp Spot', 'Meat', 'Cheese', 'Tomato', 'Oak Tree', 'Willow Tree', 'Goblin', 'Potato', ]), RegionRow('Karamja Docks', 'Area: Mudskipper Point', ['Port Sarim', 'Karamja', ], ['', ]), - RegionRow('Mudskipper Point', 'Area: Mudskipper Point', ['Rimmington', 'Port Sarim', ], ['Anvil', 'Ice Giant', 'Nature Runes', 'Law Runes', ]), - RegionRow('Karamja', 'Area: Karamja', ['Karamja Docks', 'Crandor', ], ['Gold Ore', 'Lobster Spot', 'Bowl', 'Cake Tin', 'Deadly Red Spider', 'Imps', ]), - RegionRow('Crandor', 'Area: Crandor', ['Karamja', 'Port Sarim', ], ['Coal Ore', 'Gold Ore', 'Moss Giant', 'Lesser Demon', 'Nature Runes', 'Law Runes', ]), + RegionRow('Mudskipper Point', 'Area: Mudskipper Point', ['Rimmington', 'Port Sarim', ], ['Anvil', 'Ice Giant', 'Nature Runes', 'Law Runes', 'Big Bones', 'Limpwurt Root', ]), + RegionRow('Karamja', 'Area: Karamja', ['Karamja Docks', 'Crandor', ], ['Gold Ore', 'Lobster Spot', 'Bowl', 'Cake Tin', 'Deadly Red Spider', 'Imps', 'Red Spider Eggs', ]), + RegionRow('Crandor', 'Area: Crandor', ['Karamja', 'Port Sarim', ], ['Coal Ore', 'Gold Ore', 'Moss Giant', 'Lesser Demon', 'Nature Runes', 'Law Runes', 'Big Bones', 'Limpwurt Root', ]), RegionRow('Rimmington', 'Area: Rimmington', ['Falador Farms', 'Port Sarim', 'Mudskipper Point', 'Crafting Guild Peninsula', 'Corsair Cove', ], ['Chisel', 'Bronze Ores', 'Iron Ore', 'Gold Ore', 'Bowl', 'Cake Tin', 'Wheat', 'Oak Tree', 'Willow Tree', 'Crafting Moulds', 'Imps', 'Clay Ore', 'Onion', ]), - RegionRow('Crafting Guild Peninsula', 'Area: Crafting Guild', ['Falador Farms', 'Rimmington', ], ['', ]), - RegionRow('Crafting Guild Outskirts', 'Area: Crafting Guild', ['Falador Farms', 'Crafting Guild', ], ['Sheep', 'Willow Tree', 'Oak Tree', ]), + RegionRow('Crafting Guild Peninsula', 'Area: Crafting Guild', ['Falador Farms', 'Rimmington', ], ['Limpwurt Root', ]), + RegionRow('Crafting Guild Outskirts', 'Area: Crafting Guild', ['Falador Farms', 'Crafting Guild', ], ['Sheep', 'Willow Tree', 'Oak Tree', 'Makeover', ]), RegionRow('Crafting Guild', 'Area: Crafting Guild*', ['Crafting Guild', ], ['Spinning Wheel', 'Chisel', 'Silver Ore', 'Gold Ore', 'Meat', 'Milk', 'Clay Ore', ]), RegionRow('Draynor Village', 'Area: Draynor Village', ['Draynor Manor', 'Lumbridge Farms West', 'HAM Hideout', 'Wizard Tower', ], ['Anvil', 'Shrimp Spot', 'Wheat', 'Cheese', 'Tomato', 'Willow Tree', 'Goblin', 'Zombie', 'Nature Runes', 'Law Runes', 'Imps', ]), RegionRow('Wizard Tower', 'Area: Wizard Tower', ['Draynor Village', ], ['Lesser Demon', 'Rune Essence', ]), - RegionRow('Corsair Cove', 'Area: Corsair Cove*', ['Rimmington', ], ['Anvil', 'Meat', ]), + RegionRow('Corsair Cove', 'Area: Corsair Cove*', ['Rimmington', ], ['Anvil', 'Meat', 'Limpwurt Root', ]), RegionRow('Al Kharid', 'Area: Al Kharid', ['South of Varrock', 'Citharede Abbey', 'Lumbridge', 'Port Sarim', ], ['Furnace', 'Chisel', 'Bronze Ores', 'Iron Ore', 'Silver Ore', 'Coal Ore', 'Gold Ore', 'Shrimp Spot', 'Bowl', 'Cake Tin', 'Cheese', 'Crafting Moulds', 'Imps', ]), - RegionRow('Citharede Abbey', 'Area: Citharede Abbey', ['Al Kharid', ], ['Iron Ore', 'Coal Ore', 'Anvil', 'Hill Giant', 'Nature Runes', 'Law Runes', ]), - RegionRow('Wilderness', 'Area: Wilderness', ['East Varrock', 'Varrock Palace', 'West Varrock', 'Edgeville', 'Monastery', 'Ice Mountain', 'Goblin Village', 'South of Varrock', 'Lumbridge', ], ['Furnace', 'Chisel', 'Iron Ore', 'Coal Ore', 'Anvil', 'Meat', 'Cake Tin', 'Cheese', 'Tomato', 'Oak Tree', 'Canoe Tree', 'Zombie', 'Hill Giant', 'Deadly Red Spider', 'Moss Giant', 'Ice Giant', 'Lesser Demon', 'Nature Runes', 'Law Runes', ]), + RegionRow('Citharede Abbey', 'Area: Citharede Abbey', ['Al Kharid', ], ['Iron Ore', 'Coal Ore', 'Anvil', 'Hill Giant', 'Nature Runes', 'Law Runes', 'Big Bones', 'Limpwurt Root', ]), + RegionRow('Wilderness', 'Area: Wilderness', ['Lumberyard', 'Varrock Palace', 'West Varrock', 'Edgeville', 'Monastery', 'Ice Mountain', 'Goblin Village', 'South of Varrock', 'Lumbridge', ], ['Furnace', 'Chisel', 'Iron Ore', 'Coal Ore', 'Anvil', 'Meat', 'Cake Tin', 'Cheese', 'Tomato', 'Oak Tree', 'Canoe Tree', 'Zombie', 'Hill Giant', 'Deadly Red Spider', 'Moss Giant', 'Ice Giant', 'Lesser Demon', 'Nature Runes', 'Law Runes', 'Big Bones', 'Limpwurt Root', 'Bar', ]), ] diff --git a/worlds/osrs/LogicCSV/resources_generated.py b/worlds/osrs/LogicCSV/resources_generated.py index 18c2ebe2f317..2b08f119199a 100644 --- a/worlds/osrs/LogicCSV/resources_generated.py +++ b/worlds/osrs/LogicCSV/resources_generated.py @@ -51,4 +51,11 @@ ResourceRow('Clay Ore'), ResourceRow('Onion'), ResourceRow('Potato'), + ResourceRow('Big Bones'), + ResourceRow('Duck'), + ResourceRow('Makeover'), + ResourceRow('Limpwurt Root'), + ResourceRow('Bar'), + ResourceRow('Haystack'), + ResourceRow('Red Spider Eggs'), ] diff --git a/worlds/osrs/Names.py b/worlds/osrs/Names.py index 1a44aa389c6a..138fa848507c 100644 --- a/worlds/osrs/Names.py +++ b/worlds/osrs/Names.py @@ -73,7 +73,7 @@ class ItemNames(str, Enum): South_Of_Varrock = "Area: South of Varrock" Central_Varrock = "Area: Central Varrock" Varrock_Palace = "Area: Varrock Palace" - East_Of_Varrock = "Area: East Varrock" + Lumberyard = "Area: Lumberyard" West_Varrock = "Area: West Varrock" Edgeville = "Area: Edgeville" Barbarian_Village = "Area: Barbarian Village" @@ -94,8 +94,8 @@ class ItemNames(str, Enum): Progressive_Weapons = "Progressive Weapons" Progressive_Tools = "Progressive Tools" Progressive_Range_Armor = "Progressive Ranged Armor" - Progressive_Range_Weapon = "Progressive Ranged Weapons" - Progressive_Magic = "Progressive Magic" + Progressive_Range_Weapon = "Progressive Ranged Weapon" + Progressive_Magic = "Progressive Magic Spell" Lobsters = "10 Lobsters" Swordfish = "5 Swordfish" Energy_Potions = "10 Energy Potions" diff --git a/worlds/osrs/Options.py b/worlds/osrs/Options.py index 81e017eddb34..55a040b0950e 100644 --- a/worlds/osrs/Options.py +++ b/worlds/osrs/Options.py @@ -3,18 +3,19 @@ from Options import Choice, Toggle, Range, PerGameCommonOptions MAX_COMBAT_TASKS = 16 -MAX_PRAYER_TASKS = 3 -MAX_MAGIC_TASKS = 4 -MAX_RUNECRAFT_TASKS = 3 -MAX_CRAFTING_TASKS = 5 -MAX_MINING_TASKS = 5 -MAX_SMITHING_TASKS = 4 -MAX_FISHING_TASKS = 5 -MAX_COOKING_TASKS = 5 -MAX_FIREMAKING_TASKS = 2 + +MAX_PRAYER_TASKS = 5 +MAX_MAGIC_TASKS = 7 +MAX_RUNECRAFT_TASKS = 8 +MAX_CRAFTING_TASKS = 11 +MAX_MINING_TASKS = 6 +MAX_SMITHING_TASKS = 5 +MAX_FISHING_TASKS = 6 +MAX_COOKING_TASKS = 6 +MAX_FIREMAKING_TASKS = 3 MAX_WOODCUTTING_TASKS = 3 -NON_QUEST_LOCATION_COUNT = 22 +NON_QUEST_LOCATION_COUNT = 49 class StartingArea(Choice): @@ -58,6 +59,31 @@ class ProgressiveTasks(Toggle): display_name = "Progressive Tasks" +class EnableDuds(Toggle): + """ + Whether to include filler "Dud" items that serve no purpose but allow for more tasks in the pool. + """ + display_name = "Enable Duds" + + +class DudCount(Range): + """ + How many "Dud" items to include in the pool. This setting is ignored if "Enable Duds" is not included + """ + display_name = "Dud Item Count" + range_start = 0 + range_end = 30 + default = 10 + + +class EnableCarePacks(Toggle): + """ + Whether or not to include useful "Care Pack" items that allow you to trade over specific items. + Note: Requires your account NOT to be an Ironman. Also, requires access to another account to trade over the items, + or gold to purchase off of the grand exchange. + """ + display_name = "Enable Care Packs" + class MaxCombatLevel(Range): """ The highest combat level of monster to possibly be assigned as a task. @@ -472,6 +498,9 @@ class OSRSOptions(PerGameCommonOptions): starting_area: StartingArea brutal_grinds: BrutalGrinds progressive_tasks: ProgressiveTasks + enable_duds: EnableDuds + dud_count: DudCount + enable_carepacks: EnableCarePacks max_combat_level: MaxCombatLevel max_combat_tasks: MaxCombatTasks combat_task_weight: CombatTaskWeight diff --git a/worlds/osrs/Rules.py b/worlds/osrs/Rules.py index 22a19934c8e1..7fd770f0f7a7 100644 --- a/worlds/osrs/Rules.py +++ b/worlds/osrs/Rules.py @@ -212,11 +212,14 @@ def get_skill_rule(skill, level, player, options) -> CollectionRule: return lambda state: True -def generate_special_rules_for(entrance, region_row, outbound_region_name, player, options): +def generate_special_rules_for(entrance, region_row, outbound_region_name, player, options, world): if outbound_region_name == RegionNames.Cooks_Guild: add_rule(entrance, get_cooking_skill_rule(32, player, options)) + # Since there's goblins in this chunk, checking for hat access is superfluous, you'd always have it anyway elif outbound_region_name == RegionNames.Crafting_Guild: add_rule(entrance, get_crafting_skill_rule(40, player, options)) + # Literally the only brown apron access in the entirety of f2p is buying it in varrock + add_rule(entrance, lambda state: state.can_reach_region(RegionNames.Central_Varrock, player)) elif outbound_region_name == RegionNames.Corsair_Cove: # Need to be able to start Corsair Curse in addition to having the item add_rule(entrance, lambda state: state.can_reach(RegionNames.Falador_Farm, "Region", player)) @@ -224,6 +227,17 @@ def generate_special_rules_for(entrance, region_row, outbound_region_name, playe add_rule(entrance, lambda state: state.has(ItemNames.QP_Below_Ice_Mountain, player)) elif region_row.name == "Dwarven Mountain Pass" and outbound_region_name == "Anvil*": add_rule(entrance, lambda state: state.has(ItemNames.QP_Dorics_Quest, player)) + elif outbound_region_name == RegionNames.Crandor: + add_rule(entrance, lambda state: state.can_reach_region(RegionNames.South_Of_Varrock, player)) + add_rule(entrance, lambda state: state.can_reach_region(RegionNames.Edgeville, player)) + add_rule(entrance, lambda state: state.can_reach_region(RegionNames.Lumbridge, player)) + add_rule(entrance, lambda state: state.can_reach_region(RegionNames.Rimmington, player)) + add_rule(entrance, lambda state: state.can_reach_region(RegionNames.Monastery, player)) + add_rule(entrance, lambda state: state.can_reach_region(RegionNames.Dwarven_Mines, player)) + add_rule(entrance, lambda state: state.can_reach_region(RegionNames.Port_Sarim, player)) + add_rule(entrance, lambda state: state.can_reach_region(RegionNames.Draynor_Village, player)) + add_rule(entrance, lambda state: world.quest_points(state) >= 32) + # Special logic for canoes canoe_regions = [RegionNames.Lumbridge, RegionNames.South_Of_Varrock, RegionNames.Barbarian_Village, diff --git a/worlds/osrs/__init__.py b/worlds/osrs/__init__.py index d6ddd63875f4..9e439fe52ce3 100644 --- a/worlds/osrs/__init__.py +++ b/worlds/osrs/__init__.py @@ -168,7 +168,7 @@ def create_regions(self) -> None: item_name = self.region_rows_by_name[parsed_outbound].itemReq entrance.access_rule = lambda state, item_name=item_name.replace("*",""): state.has(item_name, self.player) - generate_special_rules_for(entrance, region_row, outbound_region_name, self.player, self.options) + generate_special_rules_for(entrance, region_row, outbound_region_name, self.player, self.options, self) for resource_region in region_row.resources: if not resource_region: @@ -179,7 +179,7 @@ def create_regions(self) -> None: entrance.connect(self.region_name_to_data[resource_region]) else: entrance.connect(self.region_name_to_data[resource_region.replace('*', '')]) - generate_special_rules_for(entrance, region_row, resource_region, self.player, self.options) + generate_special_rules_for(entrance, region_row, resource_region, self.player, self.options, self) self.roll_locations() @@ -195,7 +195,16 @@ def roll_locations(self): generation_is_fake = hasattr(self.multiworld, "generation_is_fake") # UT specific override locations_required = 0 for item_row in item_rows: + # If it's a filler item, set it aside for later + if item_row.progression == ItemClassification.filler: + continue + + # If it starts with "Care Pack", only add it if Care Packs are enabled + if item_row.name.startswith("Care Pack"): + if not self.options.enable_carepacks: + continue locations_required += item_row.amount + if self.options.enable_duds: locations_required += self.options.dud_count locations_added = 1 # At this point we've already added the starting area, so we start at 1 instead of 0 @@ -232,6 +241,7 @@ def roll_locations(self): max_amount_for_task_type = getattr(self.options, f"max_{task_type}_tasks") tasks_for_this_type = [task for task in self.locations_by_category[task_type] if self.task_within_skill_levels(task.skills)] + max_amount_for_task_type = min(max_amount_for_task_type, len(tasks_for_this_type)) if not self.options.progressive_tasks: rnd.shuffle(tasks_for_this_type) else: @@ -286,16 +296,36 @@ def add_location(self, location): self.create_and_add_location(index) def create_items(self) -> None: + filler_items = [] for item_row in item_rows: if item_row.name != self.starting_area_item: + # If it's a filler item, set it aside for later + if item_row.progression == ItemClassification.filler: + filler_items.append(item_row) + continue + + # If it starts with "Care Pack", only add it if Care Packs are enabled + if item_row.name.startswith("Care Pack"): + if not self.options.enable_carepacks: + continue + for c in range(item_row.amount): item = self.create_item(item_row.name) self.multiworld.itempool.append(item) + if self.options.enable_duds: + self.random.shuffle(filler_items) + filler_items = filler_items[0:self.options.dud_count] + for item_row in filler_items: + item = self.create_item(item_row.name) + self.multiworld.itempool.append(item) def get_filler_item_name(self) -> str: - return self.random.choice( - [ItemNames.Progressive_Armor, ItemNames.Progressive_Weapons, ItemNames.Progressive_Magic, - ItemNames.Progressive_Tools, ItemNames.Progressive_Range_Armor, ItemNames.Progressive_Range_Weapon]) + if self.options.enable_duds: + return self.random.choice([item for item in item_rows if item.progression == ItemClassification.filler]) + else: + return self.random.choice([ItemNames.Progressive_Weapons, ItemNames.Progressive_Magic, + ItemNames.Progressive_Range_Weapon, ItemNames.Progressive_Armor, + ItemNames.Progressive_Range_Armor, ItemNames.Progressive_Tools]) def create_and_add_location(self, row_index) -> None: location_row = location_rows[row_index] From bcd7d62d0bd6f1c72a2727cf15ba931ca5c9bad4 Mon Sep 17 00:00:00 2001 From: kbranch Date: Wed, 7 May 2025 14:53:58 -0400 Subject: [PATCH 0401/1218] LADX: Improve Fake Tracker Items (#4897) --- LinksAwakeningClient.py | 20 ++++++++++++++------ worlds/ladx/ItemTracker.py | 3 +-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/LinksAwakeningClient.py b/LinksAwakeningClient.py index 16896540d664..14aaa415f1da 100644 --- a/LinksAwakeningClient.py +++ b/LinksAwakeningClient.py @@ -33,7 +33,7 @@ from worlds.ladx.ItemTracker import ItemTracker from worlds.ladx.LADXR.checkMetadata import checkMetadataTable from worlds.ladx.Locations import get_locations_to_id, meta_to_name -from worlds.ladx.Tracker import LocationTracker, MagpieBridge +from worlds.ladx.Tracker import LocationTracker, MagpieBridge, Check class GameboyException(Exception): @@ -626,6 +626,11 @@ def on_package(self, cmd: str, args: dict): "password": self.password, }) + # We can process linked items on already-checked checks now that we have slot_data + if self.client.tracker: + checked_checks = set(self.client.tracker.all_checks) - set(self.client.tracker.remaining_checks) + self.add_linked_items(checked_checks) + # TODO - use watcher_event if cmd == "ReceivedItems": for index, item in enumerate(args["items"], start=args["index"]): @@ -641,6 +646,13 @@ async def sync(self): sync_msg = [{'cmd': 'Sync'}] await self.send_msgs(sync_msg) + def add_linked_items(self, checks: typing.List[Check]): + for check in checks: + if check.value and check.linkedItem: + linkedItem = check.linkedItem + if 'condition' not in linkedItem or (self.slot_data and linkedItem['condition'](self.slot_data)): + self.client.item_tracker.setExtraItem(check.linkedItem['item'], check.linkedItem['qty']) + item_id_lookup = get_locations_to_id() async def run_game_loop(self): @@ -649,11 +661,7 @@ def on_item_get(ladxr_checks): checkMetadataTable[check.id])] for check in ladxr_checks] self.new_checks(checks, [check.id for check in ladxr_checks]) - for check in ladxr_checks: - if check.value and check.linkedItem: - linkedItem = check.linkedItem - if 'condition' not in linkedItem or linkedItem['condition'](self.slot_data): - self.client.item_tracker.setExtraItem(check.linkedItem['item'], check.linkedItem['qty']) + self.add_linked_items(ladxr_checks) async def victory(): await self.send_victory() diff --git a/worlds/ladx/ItemTracker.py b/worlds/ladx/ItemTracker.py index b288bba84339..981fd42d2aaa 100644 --- a/worlds/ladx/ItemTracker.py +++ b/worlds/ladx/ItemTracker.py @@ -151,8 +151,7 @@ class ItemTracker: def __init__(self, gameboy) -> None: self.gameboy = gameboy self.loadItems() - pass - extraItems = {} + self.extraItems = {} async def readRamByte(self, byte): return (await self.gameboy.read_memory_cache([byte]))[byte] From b0f42466f0003ab02b408dda6189f94455f6f675 Mon Sep 17 00:00:00 2001 From: digiholic Date: Thu, 8 May 2025 11:31:00 -0600 Subject: [PATCH 0402/1218] MMBN3: Adds Beach Access to Help With Rehab Job Bonus Reward Check (#4963) --- worlds/mmbn3/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/worlds/mmbn3/__init__.py b/worlds/mmbn3/__init__.py index 08165a7df6e2..507ddbc21f7e 100644 --- a/worlds/mmbn3/__init__.py +++ b/worlds/mmbn3/__init__.py @@ -278,6 +278,9 @@ def can_unlock(state): return state.can_reach_region(RegionName.SciLab_Overworld self.multiworld.get_location(LocationName.Help_with_rehab, self.player).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Beach_Overworld, self.player) + self.multiworld.get_location(LocationName.Help_with_rehab_bonus, self.player).access_rule = \ + lambda state: \ + state.can_reach_region(RegionName.Beach_Overworld, self.player) self.multiworld.get_location(LocationName.Old_Master, self.player).access_rule = \ lambda state: \ state.can_reach_region(RegionName.ACDC_Overworld, self.player) and \ From 9a8abeac2821d38920e177831b5fb49cb63a3e76 Mon Sep 17 00:00:00 2001 From: palex00 <32203971+palex00@users.noreply.github.com> Date: Fri, 9 May 2025 16:27:43 +0200 Subject: [PATCH 0403/1218] Add blurb about patch files to the host page (#4974) --- WebHostLib/templates/hostGame.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WebHostLib/templates/hostGame.html b/WebHostLib/templates/hostGame.html index d7d0a9633129..38406351537b 100644 --- a/WebHostLib/templates/hostGame.html +++ b/WebHostLib/templates/hostGame.html @@ -17,7 +17,9 @@

Host Game

This page allows you to host a game which was not generated by the website. For example, if you have generated a game on your own computer, you may upload the zip file created by the generator to host the game here. This will also provide a tracker, and the ability for your players to download - their patch files. + their patch files if the game is core-verified. For Custom Games, you can find the patch files in + the output .zip file you are uploading here. You need to manually distribute those patch files to + your players.

In addition to the zip file created by the generator, you may upload a multidata file here as well.

From cbfcaeba8be2a2b740148f786f0d2b302bdc6f25 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 10 May 2025 00:05:18 +0200 Subject: [PATCH 0404/1218] Subnautica: use less multiworld API (#4977) --- worlds/subnautica/rules.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/worlds/subnautica/rules.py b/worlds/subnautica/rules.py index ea9ec6a8058f..8f90af9b1385 100644 --- a/worlds/subnautica/rules.py +++ b/worlds/subnautica/rules.py @@ -254,8 +254,8 @@ def can_access_location(state: "CollectionState", player: int, loc: LocationDict return get_max_depth(state, player) >= depth -def set_location_rule(world, player: int, loc: LocationDict): - set_rule(world.get_location(loc["name"], player), lambda state: can_access_location(state, player, loc)) +def set_location_rule(world: "SubnauticaWorld", player: int, loc: LocationDict): + set_rule(world.get_location(loc["name"]), lambda state: can_access_location(state, player, loc)) def can_scan_creature(state: "CollectionState", player: int, creature: str) -> bool: @@ -264,8 +264,8 @@ def can_scan_creature(state: "CollectionState", player: int, creature: str) -> b return get_max_depth(state, player) >= all_creatures[creature] -def set_creature_rule(world, player: int, creature_name: str) -> "Location": - location = world.get_location(creature_name + suffix, player) +def set_creature_rule(world: "SubnauticaWorld", player: int, creature_name: str) -> "Location": + location = world.get_location(creature_name + suffix) set_rule(location, lambda state: can_scan_creature(state, player, creature_name)) return location @@ -290,16 +290,15 @@ def get_aggression_rule(option: AggressiveScanLogic, creature_name: str) -> \ def set_rules(subnautica_world: "SubnauticaWorld"): player = subnautica_world.player - multiworld = subnautica_world.multiworld for loc in location_table.values(): - set_location_rule(multiworld, player, loc) + set_location_rule(subnautica_world, player, loc) if subnautica_world.creatures_to_scan: - option = multiworld.worlds[player].options.creature_scan_logic + option = subnautica_world.options.creature_scan_logic for creature_name in subnautica_world.creatures_to_scan: - location = set_creature_rule(multiworld, player, creature_name) + location = set_creature_rule(subnautica_world, player, creature_name) if creature_name in containment: # there is no other way, hard-required containment add_rule(location, lambda state: has_containment(state, player)) elif creature_name in aggressive: @@ -309,7 +308,7 @@ def set_rules(subnautica_world: "SubnauticaWorld"): lambda state, loc_rule=get_aggression_rule(option, creature_name): loc_rule(state, player)) # Victory locations - set_rule(multiworld.get_location("Neptune Launch", player), + set_rule(subnautica_world.get_location("Neptune Launch"), lambda state: get_max_depth(state, player) >= 1444 and has_mobile_vehicle_bay(state, player) and @@ -322,14 +321,14 @@ def set_rules(subnautica_world: "SubnauticaWorld"): state.has("Ion Battery", player) and has_cyclops_shield(state, player)) - set_rule(multiworld.get_location("Disable Quarantine", player), + set_rule(subnautica_world.get_location("Disable Quarantine"), lambda state: get_max_depth(state, player) >= 1444) - set_rule(multiworld.get_location("Full Infection", player), + set_rule(subnautica_world.get_location("Full Infection"), lambda state: get_max_depth(state, player) >= 900) - room = multiworld.get_location("Aurora Drive Room - Upgrade Console", player) - set_rule(multiworld.get_location("Repair Aurora Drive", player), + room = subnautica_world.get_location("Aurora Drive Room - Upgrade Console") + set_rule(subnautica_world.get_location("Repair Aurora Drive"), lambda state: room.can_reach(state)) - multiworld.completion_condition[player] = lambda state: state.has("Victory", player) + subnautica_world.multiworld.completion_condition[player] = lambda state: state.has("Victory", player) From 4e61f1f23c14c20d244766c3c33c8a302d600f29 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 10 May 2025 04:11:39 +0200 Subject: [PATCH 0405/1218] Core: Institute limit of 10000 items on StartInventory (#4972) * Institute limit on StartInventory * Update Options.py * Update Options.py Co-authored-by: Scipio Wright * Update Options.py --------- Co-authored-by: Scipio Wright --- Options.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Options.py b/Options.py index bea3804d1ee5..41c2a77d3a4b 100644 --- a/Options.py +++ b/Options.py @@ -1353,6 +1353,7 @@ class StartInventory(ItemDict): verify_item_name = True display_name = "Start Inventory" rich_text_doc = True + max = 10000 class StartInventoryPool(StartInventory): From 5f24da7e181def3ac51930c931bca164dbc1910b Mon Sep 17 00:00:00 2001 From: Katelyn Gigante Date: Sat, 10 May 2025 23:20:43 +1000 Subject: [PATCH 0406/1218] Core: Use the location of Utils.py rather than __main__ to determine the AP Folder (#4009) --- Utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Utils.py b/Utils.py index a3a529d754d6..f930335b2483 100644 --- a/Utils.py +++ b/Utils.py @@ -139,8 +139,11 @@ def local_path(*path: str) -> str: local_path.cached_path = os.path.dirname(os.path.abspath(sys.argv[0])) else: import __main__ - if hasattr(__main__, "__file__") and os.path.isfile(__main__.__file__): + if globals().get("__file__") and os.path.isfile(__file__): # we are running in a normal Python environment + local_path.cached_path = os.path.dirname(os.path.abspath(__file__)) + elif hasattr(__main__, "__file__") and os.path.isfile(__main__.__file__): + # we are running in a normal Python environment, but AP was imported weirdly local_path.cached_path = os.path.dirname(os.path.abspath(__main__.__file__)) else: # pray From 8f71dac417a901f2175ee5ee65e2a9bbf8789596 Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Sat, 10 May 2025 17:57:24 -0400 Subject: [PATCH 0407/1218] Stardew valley: Add Trap Distribution setting (#4601) Co-authored-by: Jouramie <16137441+Jouramie@users.noreply.github.com> Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/stardew_valley/__init__.py | 8 +- worlds/stardew_valley/items/__init__.py | 1 + .../{items.py => items/item_creation.py} | 200 ++++-------------- worlds/stardew_valley/items/item_data.py | 143 +++++++++++++ worlds/stardew_valley/options/__init__.py | 4 +- .../stardew_valley/options/option_groups.py | 3 +- worlds/stardew_valley/options/options.py | 61 +++++- worlds/stardew_valley/options/presets.py | 16 +- worlds/stardew_valley/test/TestGeneration.py | 20 +- worlds/stardew_valley/test/TestItemLink.py | 8 +- worlds/stardew_valley/test/TestOptions.py | 8 +- worlds/stardew_valley/test/TestTraps.py | 122 +++++++++++ worlds/stardew_valley/test/__init__.py | 27 ++- .../test/options/TestPresets.py | 8 +- worlds/stardew_valley/test/options/presets.py | 6 +- 15 files changed, 426 insertions(+), 209 deletions(-) create mode 100644 worlds/stardew_valley/items/__init__.py rename worlds/stardew_valley/{items.py => items/item_creation.py} (86%) create mode 100644 worlds/stardew_valley/items/item_data.py create mode 100644 worlds/stardew_valley/test/TestTraps.py diff --git a/worlds/stardew_valley/__init__.py b/worlds/stardew_valley/__init__.py index f48c9bc1a462..9a05c04d5107 100644 --- a/worlds/stardew_valley/__init__.py +++ b/worlds/stardew_valley/__init__.py @@ -10,11 +10,13 @@ from .bundles.bundles import get_all_bundles from .content import StardewContent, create_content from .early_items import setup_early_items -from .items import item_table, create_items, ItemData, Group, items_by_group, generate_filler_choice_pool +from .items import item_table, ItemData, Group, items_by_group +from .items.item_creation import create_items, get_all_filler_items, remove_limited_amount_packs, \ + generate_filler_choice_pool from .locations import location_table, create_locations, LocationData, locations_by_tag from .logic.logic import StardewLogic -from .options import StardewValleyOptions, SeasonRandomization, Goal, BundleRandomization, EnabledFillerBuffs, NumberOfMovementBuffs, \ - BuildingProgression, EntranceRandomization, FarmType +from .options import StardewValleyOptions, SeasonRandomization, Goal, BundleRandomization, EnabledFillerBuffs, \ + NumberOfMovementBuffs, BuildingProgression, EntranceRandomization, FarmType from .options.forced_options import force_change_options_if_incompatible from .options.option_groups import sv_option_groups from .options.presets import sv_options_presets diff --git a/worlds/stardew_valley/items/__init__.py b/worlds/stardew_valley/items/__init__.py new file mode 100644 index 000000000000..ddf5e69f68be --- /dev/null +++ b/worlds/stardew_valley/items/__init__.py @@ -0,0 +1 @@ +from .item_data import item_table, ItemData, Group, items_by_group, load_item_csv diff --git a/worlds/stardew_valley/items.py b/worlds/stardew_valley/items/item_creation.py similarity index 86% rename from worlds/stardew_valley/items.py rename to worlds/stardew_valley/items/item_creation.py index a0f901a20937..6928ca8b66cb 100644 --- a/worlds/stardew_valley/items.py +++ b/worlds/stardew_valley/items/item_creation.py @@ -1,165 +1,26 @@ -import csv -import enum import logging -from dataclasses import dataclass, field -from functools import reduce -from pathlib import Path from random import Random -from typing import Dict, List, Protocol, Union, Set, Optional +from typing import List, Set from BaseClasses import Item, ItemClassification -from . import data -from .content.feature import friendsanity -from .content.game_content import StardewContent -from .data.game_item import ItemTag -from .logic.logic_event import all_events -from .mods.mod_data import ModNames -from .options import StardewValleyOptions, TrapItems, FestivalLocations, ExcludeGingerIsland, SpecialOrderLocations, SeasonRandomization, Museumsanity, \ +from .item_data import StardewItemFactory, items_by_group, Group, item_table, ItemData +from ..content.feature import friendsanity +from ..content.game_content import StardewContent +from ..data.game_item import ItemTag +from ..mods.mod_data import ModNames +from ..options import StardewValleyOptions, FestivalLocations, ExcludeGingerIsland, SpecialOrderLocations, SeasonRandomization, Museumsanity, \ ElevatorProgression, BackpackProgression, ArcadeMachineLocations, Monstersanity, Goal, \ - Chefsanity, Craftsanity, BundleRandomization, EntranceRandomization, Shipsanity, Walnutsanity, EnabledFillerBuffs -from .strings.ap_names.ap_option_names import BuffOptionName, WalnutsanityOptionName -from .strings.ap_names.ap_weapon_names import APWeapon -from .strings.ap_names.buff_names import Buff -from .strings.ap_names.community_upgrade_names import CommunityUpgrade -from .strings.ap_names.mods.mod_items import SVEQuestItem -from .strings.currency_names import Currency -from .strings.tool_names import Tool -from .strings.wallet_item_names import Wallet - -ITEM_CODE_OFFSET = 717000 + Chefsanity, Craftsanity, BundleRandomization, EntranceRandomization, Shipsanity, Walnutsanity, EnabledFillerBuffs, TrapDifficulty +from ..strings.ap_names.ap_option_names import BuffOptionName, WalnutsanityOptionName +from ..strings.ap_names.ap_weapon_names import APWeapon +from ..strings.ap_names.buff_names import Buff +from ..strings.ap_names.community_upgrade_names import CommunityUpgrade +from ..strings.ap_names.mods.mod_items import SVEQuestItem +from ..strings.currency_names import Currency +from ..strings.tool_names import Tool +from ..strings.wallet_item_names import Wallet logger = logging.getLogger(__name__) -world_folder = Path(__file__).parent - - -class Group(enum.Enum): - RESOURCE_PACK = enum.auto() - FRIENDSHIP_PACK = enum.auto() - COMMUNITY_REWARD = enum.auto() - TRASH = enum.auto() - FOOTWEAR = enum.auto() - HATS = enum.auto() - RING = enum.auto() - WEAPON = enum.auto() - WEAPON_GENERIC = enum.auto() - WEAPON_SWORD = enum.auto() - WEAPON_CLUB = enum.auto() - WEAPON_DAGGER = enum.auto() - WEAPON_SLINGSHOT = enum.auto() - PROGRESSIVE_TOOLS = enum.auto() - SKILL_LEVEL_UP = enum.auto() - SKILL_MASTERY = enum.auto() - BUILDING = enum.auto() - WIZARD_BUILDING = enum.auto() - ARCADE_MACHINE_BUFFS = enum.auto() - BASE_RESOURCE = enum.auto() - WARP_TOTEM = enum.auto() - GEODE = enum.auto() - ORE = enum.auto() - FERTILIZER = enum.auto() - SEED = enum.auto() - CROPSANITY = enum.auto() - FISHING_RESOURCE = enum.auto() - SEASON = enum.auto() - TRAVELING_MERCHANT_DAY = enum.auto() - MUSEUM = enum.auto() - FRIENDSANITY = enum.auto() - FESTIVAL = enum.auto() - RARECROW = enum.auto() - TRAP = enum.auto() - BONUS = enum.auto() - MAXIMUM_ONE = enum.auto() - AT_LEAST_TWO = enum.auto() - DEPRECATED = enum.auto() - RESOURCE_PACK_USEFUL = enum.auto() - SPECIAL_ORDER_BOARD = enum.auto() - SPECIAL_ORDER_QI = enum.auto() - BABY = enum.auto() - GINGER_ISLAND = enum.auto() - WALNUT_PURCHASE = enum.auto() - TV_CHANNEL = enum.auto() - QI_CRAFTING_RECIPE = enum.auto() - CHEFSANITY = enum.auto() - CHEFSANITY_STARTER = enum.auto() - CHEFSANITY_QOS = enum.auto() - CHEFSANITY_PURCHASE = enum.auto() - CHEFSANITY_FRIENDSHIP = enum.auto() - CHEFSANITY_SKILL = enum.auto() - CRAFTSANITY = enum.auto() - BOOK_POWER = enum.auto() - LOST_BOOK = enum.auto() - PLAYER_BUFF = enum.auto() - # Mods - MAGIC_SPELL = enum.auto() - MOD_WARP = enum.auto() - - -@dataclass(frozen=True) -class ItemData: - code_without_offset: Optional[int] - name: str - classification: ItemClassification - mod_name: Optional[str] = None - groups: Set[Group] = field(default_factory=frozenset) - - def __post_init__(self): - if not isinstance(self.groups, frozenset): - super().__setattr__("groups", frozenset(self.groups)) - - @property - def code(self): - return ITEM_CODE_OFFSET + self.code_without_offset if self.code_without_offset is not None else None - - def has_any_group(self, *group: Group) -> bool: - groups = set(group) - return bool(groups.intersection(self.groups)) - - -class StardewItemFactory(Protocol): - def __call__(self, name: Union[str, ItemData], override_classification: ItemClassification = None) -> Item: - raise NotImplementedError - - -def load_item_csv(): - from importlib.resources import files - - items = [] - with files(data).joinpath("items.csv").open() as file: - item_reader = csv.DictReader(file) - for item in item_reader: - id = int(item["id"]) if item["id"] else None - classification = reduce((lambda a, b: a | b), {ItemClassification[str_classification] for str_classification in item["classification"].split(",")}) - groups = {Group[group] for group in item["groups"].split(",") if group} - mod_name = str(item["mod_name"]) if item["mod_name"] else None - items.append(ItemData(id, item["name"], classification, mod_name, groups)) - return items - - -events = [ - ItemData(None, e, ItemClassification.progression) - for e in sorted(all_events) -] - -all_items: List[ItemData] = load_item_csv() + events -item_table: Dict[str, ItemData] = {} -items_by_group: Dict[Group, List[ItemData]] = {} - - -def initialize_groups(): - for item in all_items: - for group in item.groups: - item_group = items_by_group.get(group, list()) - item_group.append(item) - items_by_group[group] = item_group - - -def initialize_item_table(): - item_table.update({item.name: item for item in all_items}) - - -initialize_item_table() -initialize_groups() - def get_too_many_items_error_message(locations_count: int, items_count: int) -> str: return f"There should be at least as many locations [{locations_count}] as there are mandatory items [{items_count}]" @@ -712,13 +573,15 @@ def weapons_count(options: StardewValleyOptions): def fill_with_resource_packs_and_traps(item_factory: StardewItemFactory, options: StardewValleyOptions, random: Random, items_already_added: List[Item], available_item_slots: int) -> List[Item]: - include_traps = options.trap_items != TrapItems.option_no_traps + include_traps = options.trap_difficulty != TrapDifficulty.option_no_traps items_already_added_names = [item.name for item in items_already_added] useful_resource_packs = [pack for pack in items_by_group[Group.RESOURCE_PACK_USEFUL] if pack.name not in items_already_added_names] trap_items = [trap for trap in items_by_group[Group.TRAP] if trap.name not in items_already_added_names and - (trap.mod_name is None or trap.mod_name in options.mods)] + Group.DEPRECATED not in trap.groups and + (trap.mod_name is None or trap.mod_name in options.mods) and + options.trap_distribution[trap.name] > 0] player_buffs = get_allowed_player_buffs(options.enabled_filler_buffs) priority_filler_items = [] @@ -750,11 +613,13 @@ def fill_with_resource_packs_and_traps(item_factory: StardewItemFactory, options (filler_pack.name not in [priority_item.name for priority_item in priority_filler_items] and filler_pack.name not in items_already_added_names)] + filler_weights = get_filler_weights(options, all_filler_packs) + while available_item_slots > 0: - resource_pack = random.choice(all_filler_packs) + resource_pack = random.choices(all_filler_packs, weights=filler_weights, k=1)[0] exactly_2 = Group.AT_LEAST_TWO in resource_pack.groups while exactly_2 and available_item_slots == 1: - resource_pack = random.choice(all_filler_packs) + resource_pack = random.choices(all_filler_packs, weights=filler_weights, k=1)[0] exactly_2 = Group.AT_LEAST_TWO in resource_pack.groups classification = ItemClassification.useful if resource_pack.classification == ItemClassification.progression else resource_pack.classification items.append(item_factory(resource_pack, classification)) @@ -763,11 +628,24 @@ def fill_with_resource_packs_and_traps(item_factory: StardewItemFactory, options items.append(item_factory(resource_pack, classification)) available_item_slots -= 1 if exactly_2 or Group.MAXIMUM_ONE in resource_pack.groups: - all_filler_packs.remove(resource_pack) + index = all_filler_packs.index(resource_pack) + all_filler_packs.pop(index) + filler_weights.pop(index) return items +def get_filler_weights(options: StardewValleyOptions, all_filler_packs: List[ItemData]): + weights = [] + for filler in all_filler_packs: + if filler.name in options.trap_distribution: + num = options.trap_distribution[filler.name] + else: + num = options.trap_distribution.default_weight + weights.append(num) + return weights + + def filter_deprecated_items(items: List[ItemData]) -> List[ItemData]: return [item for item in items if Group.DEPRECATED not in item.groups] @@ -792,7 +670,7 @@ def remove_excluded_items_island_mods(items, exclude_ginger_island: bool, mods: def generate_filler_choice_pool(options: StardewValleyOptions) -> list[str]: - include_traps = options.trap_items != TrapItems.option_no_traps + include_traps = options.trap_difficulty != TrapDifficulty.option_no_traps exclude_island = options.exclude_ginger_island == ExcludeGingerIsland.option_true available_filler = get_all_filler_items(include_traps, exclude_island) diff --git a/worlds/stardew_valley/items/item_data.py b/worlds/stardew_valley/items/item_data.py new file mode 100644 index 000000000000..e7c3779e275d --- /dev/null +++ b/worlds/stardew_valley/items/item_data.py @@ -0,0 +1,143 @@ +import csv +import enum +from dataclasses import dataclass, field +from functools import reduce +from pathlib import Path +from typing import Dict, List, Protocol, Union, Set, Optional + +from BaseClasses import Item, ItemClassification +from .. import data +from ..logic.logic_event import all_events + +ITEM_CODE_OFFSET = 717000 + +world_folder = Path(__file__).parent + + +class Group(enum.Enum): + RESOURCE_PACK = enum.auto() + FRIENDSHIP_PACK = enum.auto() + COMMUNITY_REWARD = enum.auto() + TRASH = enum.auto() + FOOTWEAR = enum.auto() + HATS = enum.auto() + RING = enum.auto() + WEAPON = enum.auto() + WEAPON_GENERIC = enum.auto() + WEAPON_SWORD = enum.auto() + WEAPON_CLUB = enum.auto() + WEAPON_DAGGER = enum.auto() + WEAPON_SLINGSHOT = enum.auto() + PROGRESSIVE_TOOLS = enum.auto() + SKILL_LEVEL_UP = enum.auto() + SKILL_MASTERY = enum.auto() + BUILDING = enum.auto() + WIZARD_BUILDING = enum.auto() + ARCADE_MACHINE_BUFFS = enum.auto() + BASE_RESOURCE = enum.auto() + WARP_TOTEM = enum.auto() + GEODE = enum.auto() + ORE = enum.auto() + FERTILIZER = enum.auto() + SEED = enum.auto() + CROPSANITY = enum.auto() + FISHING_RESOURCE = enum.auto() + SEASON = enum.auto() + TRAVELING_MERCHANT_DAY = enum.auto() + MUSEUM = enum.auto() + FRIENDSANITY = enum.auto() + FESTIVAL = enum.auto() + RARECROW = enum.auto() + TRAP = enum.auto() + BONUS = enum.auto() + MAXIMUM_ONE = enum.auto() + AT_LEAST_TWO = enum.auto() + DEPRECATED = enum.auto() + RESOURCE_PACK_USEFUL = enum.auto() + SPECIAL_ORDER_BOARD = enum.auto() + SPECIAL_ORDER_QI = enum.auto() + BABY = enum.auto() + GINGER_ISLAND = enum.auto() + WALNUT_PURCHASE = enum.auto() + TV_CHANNEL = enum.auto() + QI_CRAFTING_RECIPE = enum.auto() + CHEFSANITY = enum.auto() + CHEFSANITY_STARTER = enum.auto() + CHEFSANITY_QOS = enum.auto() + CHEFSANITY_PURCHASE = enum.auto() + CHEFSANITY_FRIENDSHIP = enum.auto() + CHEFSANITY_SKILL = enum.auto() + CRAFTSANITY = enum.auto() + BOOK_POWER = enum.auto() + LOST_BOOK = enum.auto() + PLAYER_BUFF = enum.auto() + # Mods + MAGIC_SPELL = enum.auto() + MOD_WARP = enum.auto() + + +@dataclass(frozen=True) +class ItemData: + code_without_offset: Optional[int] + name: str + classification: ItemClassification + mod_name: Optional[str] = None + groups: Set[Group] = field(default_factory=frozenset) + + def __post_init__(self): + if not isinstance(self.groups, frozenset): + super().__setattr__("groups", frozenset(self.groups)) + + @property + def code(self): + return ITEM_CODE_OFFSET + self.code_without_offset if self.code_without_offset is not None else None + + def has_any_group(self, *group: Group) -> bool: + groups = set(group) + return bool(groups.intersection(self.groups)) + + +class StardewItemFactory(Protocol): + def __call__(self, name: Union[str, ItemData], override_classification: ItemClassification = None) -> Item: + raise NotImplementedError + + +def load_item_csv(): + from importlib.resources import files + + items = [] + with files(data).joinpath("items.csv").open() as file: + item_reader = csv.DictReader(file) + for item in item_reader: + id = int(item["id"]) if item["id"] else None + classification = reduce((lambda a, b: a | b), {ItemClassification[str_classification] for str_classification in item["classification"].split(",")}) + groups = {Group[group] for group in item["groups"].split(",") if group} + mod_name = str(item["mod_name"]) if item["mod_name"] else None + items.append(ItemData(id, item["name"], classification, mod_name, groups)) + return items + + +events = [ + ItemData(None, e, ItemClassification.progression) + for e in sorted(all_events) +] + +all_items: List[ItemData] = load_item_csv() + events +item_table: Dict[str, ItemData] = {} +items_by_group: Dict[Group, List[ItemData]] = {} + + +def initialize_groups(): + for item in all_items: + for group in item.groups: + item_group = items_by_group.get(group, list()) + item_group.append(item) + items_by_group[group] = item_group + + +def initialize_item_table(): + item_table.update({item.name: item for item in all_items}) + + +initialize_item_table() +initialize_groups() diff --git a/worlds/stardew_valley/options/__init__.py b/worlds/stardew_valley/options/__init__.py index 713d3e9537a6..12c0d7c647ff 100644 --- a/worlds/stardew_valley/options/__init__.py +++ b/worlds/stardew_valley/options/__init__.py @@ -1,6 +1,6 @@ from .options import StardewValleyOption, Goal, FarmType, StartingMoney, ProfitMargin, BundleRandomization, BundlePrice, EntranceRandomization, \ SeasonRandomization, Cropsanity, BackpackProgression, ToolProgression, ElevatorProgression, SkillProgression, BuildingProgression, FestivalLocations, \ ArcadeMachineLocations, SpecialOrderLocations, QuestLocations, Fishsanity, Museumsanity, Monstersanity, Shipsanity, Cooksanity, Chefsanity, Craftsanity, \ - Friendsanity, FriendsanityHeartSize, Booksanity, Walnutsanity, NumberOfMovementBuffs, EnabledFillerBuffs, ExcludeGingerIsland, TrapItems, \ + Friendsanity, FriendsanityHeartSize, Booksanity, Walnutsanity, NumberOfMovementBuffs, EnabledFillerBuffs, ExcludeGingerIsland, TrapDifficulty, \ MultipleDaySleepEnabled, MultipleDaySleepCost, ExperienceMultiplier, FriendshipMultiplier, DebrisMultiplier, QuickStart, Gifting, Mods, BundlePlando, \ - StardewValleyOptions, enabled_mods, disabled_mods, all_mods + StardewValleyOptions, enabled_mods, disabled_mods, all_mods, TrapDistribution, TrapItems, StardewValleyOptions diff --git a/worlds/stardew_valley/options/option_groups.py b/worlds/stardew_valley/options/option_groups.py index bcb9bee77ff4..4ae1fc3c4d7e 100644 --- a/worlds/stardew_valley/options/option_groups.py +++ b/worlds/stardew_valley/options/option_groups.py @@ -52,7 +52,8 @@ options.DebrisMultiplier, options.NumberOfMovementBuffs, options.EnabledFillerBuffs, - options.TrapItems, + options.TrapDifficulty, + options.TrapDistribution, options.MultipleDaySleepEnabled, options.MultipleDaySleepCost, options.QuickStart, diff --git a/worlds/stardew_valley/options/options.py b/worlds/stardew_valley/options/options.py index 84026387c57f..f81cdaac813b 100644 --- a/worlds/stardew_valley/options/options.py +++ b/worlds/stardew_valley/options/options.py @@ -3,7 +3,8 @@ from dataclasses import dataclass from typing import Protocol, ClassVar -from Options import Range, NamedRange, Toggle, Choice, OptionSet, PerGameCommonOptions, DeathLink, OptionList, Visibility +from Options import Range, NamedRange, Toggle, Choice, OptionSet, PerGameCommonOptions, DeathLink, OptionList, Visibility, Removed, OptionCounter +from ..items import items_by_group, Group from ..mods.mod_data import ModNames from ..strings.ap_names.ap_option_names import BuffOptionName, WalnutsanityOptionName from ..strings.bundle_names import all_cc_bundle_names @@ -658,13 +659,29 @@ class ExcludeGingerIsland(Toggle): default = 0 -class TrapItems(Choice): - """When rolling filler items, including resource packs, the game can also roll trap items. - Trap items are negative items that cause problems or annoyances for the player - This setting is for choosing if traps will be in the item pool, and if so, how punishing they will be. +class TrapItems(Removed): + """Deprecated setting, replaced by TrapDifficulty """ internal_name = "trap_items" display_name = "Trap Items" + default = "" + visibility = Visibility.none + + def __init__(self, value: str): + if value: + raise Exception("Option trap_items was replaced by trap_difficulty, please update your options file") + super().__init__(value) + + +class TrapDifficulty(Choice): + """When rolling filler items, including resource packs, the game can also roll trap items. + Trap items are negative items that cause problems or annoyances for the player. + This setting is for choosing how punishing traps will be. + Lower difficulties will be on the funny annoyance side, higher difficulty will be on the extreme problems side. + Only play Nightmare at your own risk. + """ + internal_name = "trap_difficulty" + display_name = "Trap Difficulty" default = 2 option_no_traps = 0 option_easy = 1 @@ -674,6 +691,34 @@ class TrapItems(Choice): option_nightmare = 5 +trap_default_weight = 100 + + +class TrapDistribution(OptionCounter): + """ + Specify the weighted chance of rolling individual traps when rolling random filler items. + The average filler item should be considered to be "100", as in 100%. + So a trap on "200" will be twice as likely to roll as any filler item. A trap on "10" will be 10% as likely. + You can use weight "0" to disable this trap entirely. The maximum weight is 1000, for x10 chance + """ + internal_name = "trap_distribution" + display_name = "Trap Distribution" + default_weight = trap_default_weight + visibility = Visibility.all ^ Visibility.simple_ui + min = 0 + max = 1000 + valid_keys = frozenset({ + trap_data.name + for trap_data in items_by_group[Group.TRAP] + if Group.DEPRECATED not in trap_data.groups + }) + default = { + trap_data.name: trap_default_weight + for trap_data in items_by_group[Group.TRAP] + if Group.DEPRECATED not in trap_data.groups + } + + class MultipleDaySleepEnabled(Toggle): """Enable the ability to sleep automatically for multiple days straight?""" internal_name = "multiple_day_sleep_enabled" @@ -851,10 +896,14 @@ class StardewValleyOptions(PerGameCommonOptions): debris_multiplier: DebrisMultiplier movement_buff_number: NumberOfMovementBuffs enabled_filler_buffs: EnabledFillerBuffs - trap_items: TrapItems + trap_difficulty: TrapDifficulty + trap_distribution: TrapDistribution multiple_day_sleep_enabled: MultipleDaySleepEnabled multiple_day_sleep_cost: MultipleDaySleepCost gifting: Gifting mods: Mods bundle_plando: BundlePlando death_link: DeathLink + + # removed: + trap_items: TrapItems \ No newline at end of file diff --git a/worlds/stardew_valley/options/presets.py b/worlds/stardew_valley/options/presets.py index 3dbb5ab3f554..a711fe08ff86 100644 --- a/worlds/stardew_valley/options/presets.py +++ b/worlds/stardew_valley/options/presets.py @@ -38,7 +38,7 @@ options.Booksanity.internal_name: "random", options.NumberOfMovementBuffs.internal_name: "random", options.ExcludeGingerIsland.internal_name: "random", - options.TrapItems.internal_name: "random", + options.TrapDifficulty.internal_name: "random", options.MultipleDaySleepEnabled.internal_name: "random", options.MultipleDaySleepCost.internal_name: "random", options.ExperienceMultiplier.internal_name: "random", @@ -82,7 +82,7 @@ options.NumberOfMovementBuffs.internal_name: 8, options.EnabledFillerBuffs.internal_name: options.EnabledFillerBuffs.preset_all, options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true, - options.TrapItems.internal_name: options.TrapItems.option_easy, + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_easy, options.MultipleDaySleepEnabled.internal_name: options.MultipleDaySleepEnabled.option_true, options.MultipleDaySleepCost.internal_name: "free", options.ExperienceMultiplier.internal_name: "triple", @@ -126,7 +126,7 @@ options.NumberOfMovementBuffs.internal_name: 6, options.EnabledFillerBuffs.internal_name: options.EnabledFillerBuffs.preset_all, options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true, - options.TrapItems.internal_name: options.TrapItems.option_medium, + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_medium, options.MultipleDaySleepEnabled.internal_name: options.MultipleDaySleepEnabled.option_true, options.MultipleDaySleepCost.internal_name: "free", options.ExperienceMultiplier.internal_name: "double", @@ -170,7 +170,7 @@ options.NumberOfMovementBuffs.internal_name: 4, options.EnabledFillerBuffs.internal_name: options.EnabledFillerBuffs.default, options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_false, - options.TrapItems.internal_name: options.TrapItems.option_hard, + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_hard, options.MultipleDaySleepEnabled.internal_name: options.MultipleDaySleepEnabled.option_true, options.MultipleDaySleepCost.internal_name: "cheap", options.ExperienceMultiplier.internal_name: "vanilla", @@ -214,7 +214,7 @@ options.NumberOfMovementBuffs.internal_name: 2, options.EnabledFillerBuffs.internal_name: options.EnabledFillerBuffs.preset_none, options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_false, - options.TrapItems.internal_name: options.TrapItems.option_hell, + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_hell, options.MultipleDaySleepEnabled.internal_name: options.MultipleDaySleepEnabled.option_true, options.MultipleDaySleepCost.internal_name: "expensive", options.ExperienceMultiplier.internal_name: "half", @@ -258,7 +258,7 @@ options.NumberOfMovementBuffs.internal_name: 10, options.EnabledFillerBuffs.internal_name: options.EnabledFillerBuffs.preset_all, options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true, - options.TrapItems.internal_name: options.TrapItems.option_easy, + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_easy, options.MultipleDaySleepEnabled.internal_name: options.MultipleDaySleepEnabled.option_true, options.MultipleDaySleepCost.internal_name: "free", options.ExperienceMultiplier.internal_name: "quadruple", @@ -302,7 +302,7 @@ options.NumberOfMovementBuffs.internal_name: options.NumberOfMovementBuffs.default, options.EnabledFillerBuffs.internal_name: options.EnabledFillerBuffs.default, options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true, - options.TrapItems.internal_name: options.TrapItems.default, + options.TrapDifficulty.internal_name: options.TrapDifficulty.default, options.MultipleDaySleepEnabled.internal_name: options.MultipleDaySleepEnabled.default, options.MultipleDaySleepCost.internal_name: options.MultipleDaySleepCost.default, options.ExperienceMultiplier.internal_name: options.ExperienceMultiplier.default, @@ -346,7 +346,7 @@ options.NumberOfMovementBuffs.internal_name: 12, options.EnabledFillerBuffs.internal_name: options.EnabledFillerBuffs.preset_all, options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_false, - options.TrapItems.internal_name: options.TrapItems.default, + options.TrapDifficulty.internal_name: options.TrapDifficulty.default, options.MultipleDaySleepEnabled.internal_name: options.MultipleDaySleepEnabled.default, options.MultipleDaySleepCost.internal_name: options.MultipleDaySleepCost.default, options.ExperienceMultiplier.internal_name: options.ExperienceMultiplier.default, diff --git a/worlds/stardew_valley/test/TestGeneration.py b/worlds/stardew_valley/test/TestGeneration.py index 77092c78fcae..6d0846f8c1d5 100644 --- a/worlds/stardew_valley/test/TestGeneration.py +++ b/worlds/stardew_valley/test/TestGeneration.py @@ -2,8 +2,8 @@ from BaseClasses import ItemClassification, Item from . import SVTestBase -from .. import items, location_table, options -from ..items import Group, ItemData +from .. import location_table, options, items +from ..items import Group, ItemData, item_data from ..locations import LocationTags from ..options import Friendsanity, SpecialOrderLocations, Shipsanity, Chefsanity, SeasonRandomization, Craftsanity, ExcludeGingerIsland, SkillProgression, \ Booksanity, Walnutsanity @@ -15,10 +15,10 @@ def get_all_permanent_progression_items() -> List[ItemData]: """ return [ item - for item in items.all_items + for item in item_data.all_items if ItemClassification.progression in item.classification if item.mod_name is None - if item.name not in {event.name for event in items.events} + if item.name not in {event.name for event in item_data.events} if item.name not in {deprecated.name for deprecated in items.items_by_group[Group.DEPRECATED]} if item.name not in {season.name for season in items.items_by_group[Group.SEASON]} if item.name not in {weapon.name for weapon in items.items_by_group[Group.WEAPON]} @@ -54,19 +54,19 @@ def test_creates_as_many_item_as_non_event_locations(self): def test_does_not_create_deprecated_items(self): all_created_items = set(self.get_all_created_items()) - for deprecated_item in items.items_by_group[items.Group.DEPRECATED]: + for deprecated_item in item_data.items_by_group[item_data.Group.DEPRECATED]: with self.subTest(f"{deprecated_item.name}"): self.assertNotIn(deprecated_item.name, all_created_items) def test_does_not_create_more_than_one_maximum_one_items(self): all_created_items = self.get_all_created_items() - for maximum_one_item in items.items_by_group[items.Group.MAXIMUM_ONE]: + for maximum_one_item in item_data.items_by_group[item_data.Group.MAXIMUM_ONE]: with self.subTest(f"{maximum_one_item.name}"): self.assertLessEqual(all_created_items.count(maximum_one_item.name), 1) def test_does_not_create_or_create_two_of_exactly_two_items(self): all_created_items = self.get_all_created_items() - for exactly_two_item in items.items_by_group[items.Group.AT_LEAST_TWO]: + for exactly_two_item in item_data.items_by_group[item_data.Group.AT_LEAST_TWO]: with self.subTest(f"{exactly_two_item.name}"): count = all_created_items.count(exactly_two_item.name) self.assertTrue(count == 0 or count == 2) @@ -102,19 +102,19 @@ def test_creates_as_many_item_as_non_event_locations(self): def test_does_not_create_deprecated_items(self): all_created_items = self.get_all_created_items() - for deprecated_item in items.items_by_group[items.Group.DEPRECATED]: + for deprecated_item in item_data.items_by_group[item_data.Group.DEPRECATED]: with self.subTest(f"Deprecated item: {deprecated_item.name}"): self.assertNotIn(deprecated_item.name, all_created_items) def test_does_not_create_more_than_one_maximum_one_items(self): all_created_items = self.get_all_created_items() - for maximum_one_item in items.items_by_group[items.Group.MAXIMUM_ONE]: + for maximum_one_item in item_data.items_by_group[item_data.Group.MAXIMUM_ONE]: with self.subTest(f"{maximum_one_item.name}"): self.assertLessEqual(all_created_items.count(maximum_one_item.name), 1) def test_does_not_create_exactly_two_items(self): all_created_items = self.get_all_created_items() - for exactly_two_item in items.items_by_group[items.Group.AT_LEAST_TWO]: + for exactly_two_item in item_data.items_by_group[item_data.Group.AT_LEAST_TWO]: with self.subTest(f"{exactly_two_item.name}"): count = all_created_items.count(exactly_two_item.name) self.assertTrue(count == 0 or count == 2) diff --git a/worlds/stardew_valley/test/TestItemLink.py b/worlds/stardew_valley/test/TestItemLink.py index 3a0d976511f7..f1c8346142ad 100644 --- a/worlds/stardew_valley/test/TestItemLink.py +++ b/worlds/stardew_valley/test/TestItemLink.py @@ -6,7 +6,7 @@ class TestItemLinksEverythingIncluded(SVTestBase): options = {options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_false, - options.TrapItems.internal_name: options.TrapItems.option_medium} + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_medium} def test_filler_of_all_types_generated(self): max_number_filler = 114 @@ -33,7 +33,7 @@ def test_filler_of_all_types_generated(self): class TestItemLinksNoIsland(SVTestBase): options = {options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true, - options.TrapItems.internal_name: options.TrapItems.option_medium} + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_medium} def test_filler_has_no_island_but_has_traps(self): max_number_filler = 109 @@ -57,7 +57,7 @@ def test_filler_has_no_island_but_has_traps(self): class TestItemLinksNoTraps(SVTestBase): options = {options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_false, - options.TrapItems.internal_name: options.TrapItems.option_no_traps} + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_no_traps} def test_filler_has_no_traps_but_has_island(self): max_number_filler = 99 @@ -81,7 +81,7 @@ def test_filler_has_no_traps_but_has_island(self): class TestItemLinksNoTrapsAndIsland(SVTestBase): options = {options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true, - options.TrapItems.internal_name: options.TrapItems.option_no_traps} + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_no_traps} def test_filler_generated_without_island_or_traps(self): max_number_filler = 94 diff --git a/worlds/stardew_valley/test/TestOptions.py b/worlds/stardew_valley/test/TestOptions.py index 4894ea55f241..11b0a0141533 100644 --- a/worlds/stardew_valley/test/TestOptions.py +++ b/worlds/stardew_valley/test/TestOptions.py @@ -9,7 +9,7 @@ from .options.presets import allsanity_no_mods_6_x_x, allsanity_mods_6_x_x from .. import items_by_group, Group from ..locations import locations_by_tag, LocationTags, location_table -from ..options import ExcludeGingerIsland, ToolProgression, Goal, SeasonRandomization, TrapItems, SpecialOrderLocations, ArcadeMachineLocations +from ..options import ExcludeGingerIsland, ToolProgression, Goal, SeasonRandomization, TrapDifficulty, SpecialOrderLocations, ArcadeMachineLocations from ..strings.goal_names import Goal as GoalName from ..strings.season_names import Season from ..strings.special_order_names import SpecialOrder @@ -126,7 +126,7 @@ def test_given_choice_when_generate_exclude_ginger_island_then_ginger_island_is_ class TestTraps(SVTestCase): def test_given_no_traps_when_generate_then_no_trap_in_pool(self): world_options = allsanity_no_mods_6_x_x().copy() - world_options[TrapItems.internal_name] = TrapItems.option_no_traps + world_options[TrapDifficulty.internal_name] = TrapDifficulty.option_no_traps with solo_multiworld(world_options) as (multi_world, _): trap_items = [item_data.name for item_data in items_by_group[Group.TRAP]] multiworld_items = [item.name for item in multi_world.get_items()] @@ -136,12 +136,12 @@ def test_given_no_traps_when_generate_then_no_trap_in_pool(self): self.assertNotIn(item, multiworld_items) def test_given_traps_when_generate_then_all_traps_in_pool(self): - trap_option = TrapItems + trap_option = TrapDifficulty for value in trap_option.options: if value == "no_traps": continue world_options = allsanity_mods_6_x_x() - world_options.update({TrapItems.internal_name: trap_option.options[value]}) + world_options.update({TrapDifficulty.internal_name: trap_option.options[value]}) with solo_multiworld(world_options) as (multi_world, _): trap_items = [item_data.name for item_data in items_by_group[Group.TRAP] if Group.DEPRECATED not in item_data.groups and item_data.mod_name is None] diff --git a/worlds/stardew_valley/test/TestTraps.py b/worlds/stardew_valley/test/TestTraps.py new file mode 100644 index 000000000000..9df07a6d74c8 --- /dev/null +++ b/worlds/stardew_valley/test/TestTraps.py @@ -0,0 +1,122 @@ +import unittest + +from . import SVTestBase +from .assertion import WorldAssertMixin +from .. import options, items_by_group, Group +from ..options import TrapDistribution + +default_distribution = {trap.name: TrapDistribution.default_weight for trap in items_by_group[Group.TRAP] if Group.DEPRECATED not in trap.groups} +threshold_difference = 2 +threshold_ballpark = 3 + + +class TestTrapDifficultyCanRemoveAllTraps(WorldAssertMixin, SVTestBase): + options = { + options.QuestLocations.internal_name: 56, + options.Fishsanity.internal_name: options.Fishsanity.option_all, + options.Museumsanity.internal_name: options.Museumsanity.option_all, + options.SpecialOrderLocations.internal_name: options.SpecialOrderLocations.option_board_qi, + options.Shipsanity.internal_name: options.Shipsanity.option_everything, + options.Cooksanity.internal_name: options.Cooksanity.option_all, + options.Craftsanity.internal_name: options.Craftsanity.option_all, + options.Mods.internal_name: frozenset(options.Mods.valid_keys), + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_no_traps, + } + + def test_no_traps_in_item_pool(self): + items = self.multiworld.get_items() + item_names = set(item.name for item in items) + for trap in items_by_group[Group.TRAP]: + if Group.DEPRECATED in trap.groups: + continue + self.assertNotIn(trap.name, item_names) + + +class TestDefaultDistributionHasAllTraps(WorldAssertMixin, SVTestBase): + options = { + options.QuestLocations.internal_name: 56, + options.Fishsanity.internal_name: options.Fishsanity.option_all, + options.Museumsanity.internal_name: options.Museumsanity.option_all, + options.SpecialOrderLocations.internal_name: options.SpecialOrderLocations.option_board_qi, + options.Shipsanity.internal_name: options.Shipsanity.option_everything, + options.Cooksanity.internal_name: options.Cooksanity.option_all, + options.Craftsanity.internal_name: options.Craftsanity.option_all, + options.Mods.internal_name: frozenset(options.Mods.valid_keys), + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_medium, + } + + def test_all_traps_in_item_pool(self): + items = self.multiworld.get_items() + item_names = set(item.name for item in items) + for trap in items_by_group[Group.TRAP]: + if Group.DEPRECATED in trap.groups: + continue + self.assertIn(trap.name, item_names) + + +class TestDistributionIsRespectedAllTraps(WorldAssertMixin, SVTestBase): + options = { + options.QuestLocations.internal_name: 56, + options.Fishsanity.internal_name: options.Fishsanity.option_all, + options.Museumsanity.internal_name: options.Museumsanity.option_all, + options.SpecialOrderLocations.internal_name: options.SpecialOrderLocations.option_board_qi, + options.Shipsanity.internal_name: options.Shipsanity.option_everything, + options.Cooksanity.internal_name: options.Cooksanity.option_all, + options.Craftsanity.internal_name: options.Craftsanity.option_all, + options.Mods.internal_name: frozenset(options.Mods.valid_keys), + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_medium, + options.TrapDistribution.internal_name: default_distribution | {"Nudge Trap": 100, "Bark Trap": 1, "Meow Trap": 1000, "Shuffle Trap": 0} + } + + @classmethod + def setUpClass(cls) -> None: + super().setUpClass() + if cls.skip_long_tests: + raise unittest.SkipTest("Unstable tests disabled to not annoy anyone else when it rarely fails") + + def test_about_as_many_nudges_as_other_filler(self): + items = self.multiworld.get_items() + item_names = [item.name for item in items] + num_nudge = len([item for item in item_names if item == "Nudge Trap"]) + other_fillers = ["Resource Pack: 4 Frozen Geode", "Resource Pack: 50 Wood", "Resource Pack: 5 Warp Totem: Farm", + "Resource Pack: 500 Money", "Resource Pack: 75 Copper Ore", "Resource Pack: 30 Speed-Gro"] + at_least_one_in_ballpark = False + for filler_item in other_fillers: + num_filler = len([item for item in item_names if item == filler_item]) + diff_num = abs(num_filler - num_nudge) + is_in_ballpark = diff_num <= threshold_ballpark + at_least_one_in_ballpark = at_least_one_in_ballpark or is_in_ballpark + self.assertTrue(at_least_one_in_ballpark) + + def test_fewer_barks_than_nudges_in_item_pool(self): + items = self.multiworld.get_items() + item_names = [item.name for item in items] + num_nudge = len([item for item in item_names if item == "Nudge Trap"]) + num_bark = len([item for item in item_names if item == "Bark Trap"]) + self.assertLess(num_bark, num_nudge - threshold_difference) + + def test_more_meows_than_nudges_in_item_pool(self): + items = self.multiworld.get_items() + item_names = [item.name for item in items] + num_nudge = len([item for item in item_names if item == "Nudge Trap"]) + num_meow = len([item for item in item_names if item == "Meow Trap"]) + self.assertGreater(num_meow, num_nudge + threshold_difference) + + def test_no_shuffles_in_item_pool(self): + items = self.multiworld.get_items() + item_names = [item.name for item in items] + num_shuffle = len([item for item in item_names if item == "Shuffle Trap"]) + self.assertEqual(0, num_shuffle) + + def test_omitted_item_same_as_nudge_in_item_pool(self): + items = self.multiworld.get_items() + item_names = [item.name for item in items] + num_time_flies = len([item for item in item_names if item == "Time Flies Trap"]) + num_debris = len([item for item in item_names if item == "Debris Trap"]) + num_bark = len([item for item in item_names if item == "Bark Trap"]) + num_meow = len([item for item in item_names if item == "Meow Trap"]) + self.assertLess(num_bark, num_time_flies - threshold_difference) + self.assertLess(num_bark, num_debris - threshold_difference) + self.assertGreater(num_meow, num_time_flies + threshold_difference) + self.assertGreater(num_meow, num_debris + threshold_difference) + diff --git a/worlds/stardew_valley/test/__init__.py b/worlds/stardew_valley/test/__init__.py index 702f590221f5..6a8011a37d5f 100644 --- a/worlds/stardew_valley/test/__init__.py +++ b/worlds/stardew_valley/test/__init__.py @@ -14,7 +14,7 @@ from .options.utils import fill_namespace_with_default, parse_class_option_keys, fill_dataclass_with_default from .. import StardewValleyWorld, StardewItem, StardewRule from ..logic.time_logic import MONTH_COEFFICIENT -from ..options import StardewValleyOption +from ..options import StardewValleyOption, options logger = logging.getLogger(__name__) @@ -221,9 +221,9 @@ def setup_solo_multiworld(test_options: Optional[Dict[Union[str, StardewValleyOp # Yes I reuse the worlds generated between tests, its speeds the execution by a couple seconds # If the simple dict caching ends up taking too much memory, we could replace it with some kind of lru cache. - should_cache = "start_inventory" not in test_options + should_cache = should_cache_world(test_options) if should_cache: - frozen_options = frozenset(test_options.items()).union({("seed", seed)}) + frozen_options = make_hashable(test_options, seed) cached_multi_world = search_world_cache(_cache, frozen_options) if cached_multi_world: print(f"Using cached solo multi world [Seed = {cached_multi_world.seed}] [Cache size = {len(_cache)}]") @@ -252,6 +252,27 @@ def setup_solo_multiworld(test_options: Optional[Dict[Union[str, StardewValleyOp return multiworld +def should_cache_world(test_options): + if "start_inventory" in test_options: + return False + + trap_distribution_key = "trap_distribution" + if trap_distribution_key not in test_options: + return True + + trap_distribution = test_options[trap_distribution_key] + for key in trap_distribution: + if trap_distribution[key] != options.TrapDistribution.default_weight: + return False + + return True + + + +def make_hashable(test_options, seed): + return frozenset(test_options.items()).union({("seed", seed)}) + + def search_world_cache(cache: Dict[frozenset, MultiWorld], frozen_options: frozenset) -> Optional[MultiWorld]: try: return cache[frozen_options] diff --git a/worlds/stardew_valley/test/options/TestPresets.py b/worlds/stardew_valley/test/options/TestPresets.py index 9384acd77060..5d9e89531c87 100644 --- a/worlds/stardew_valley/test/options/TestPresets.py +++ b/worlds/stardew_valley/test/options/TestPresets.py @@ -1,16 +1,16 @@ -from Options import PerGameCommonOptions, OptionSet +from Options import PerGameCommonOptions, OptionSet, OptionDict from .. import SVTestCase -from ...options import StardewValleyOptions +from ...options import StardewValleyOptions, TrapItems from ...options.presets import sv_options_presets class TestPresets(SVTestCase): def test_all_presets_explicitly_set_all_options(self): all_option_names = {option_key for option_key in StardewValleyOptions.type_hints} - omitted_option_names = {option_key for option_key in PerGameCommonOptions.type_hints} + omitted_option_names = {option_key for option_key in PerGameCommonOptions.type_hints} | {TrapItems.internal_name} mandatory_option_names = {option_key for option_key in all_option_names if option_key not in omitted_option_names and - not issubclass(StardewValleyOptions.type_hints[option_key], OptionSet)} + not issubclass(StardewValleyOptions.type_hints[option_key], OptionSet | OptionDict)} for preset_name in sv_options_presets: with self.subTest(f"{preset_name}"): diff --git a/worlds/stardew_valley/test/options/presets.py b/worlds/stardew_valley/test/options/presets.py index 57f8b0beb960..86b21c693e69 100644 --- a/worlds/stardew_valley/test/options/presets.py +++ b/worlds/stardew_valley/test/options/presets.py @@ -70,7 +70,7 @@ def allsanity_no_mods_6_x_x(): options.SkillProgression.internal_name: options.SkillProgression.option_progressive_with_masteries, options.SpecialOrderLocations.internal_name: options.SpecialOrderLocations.option_board_qi, options.ToolProgression.internal_name: options.ToolProgression.option_progressive, - options.TrapItems.internal_name: options.TrapItems.option_nightmare, + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_nightmare, options.Walnutsanity.internal_name: options.Walnutsanity.preset_all } @@ -119,7 +119,7 @@ def get_minsanity_options(): options.SkillProgression.internal_name: options.SkillProgression.option_vanilla, options.SpecialOrderLocations.internal_name: options.SpecialOrderLocations.option_vanilla, options.ToolProgression.internal_name: options.ToolProgression.option_vanilla, - options.TrapItems.internal_name: options.TrapItems.option_no_traps, + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_no_traps, options.Walnutsanity.internal_name: options.Walnutsanity.preset_none } @@ -156,7 +156,7 @@ def minimal_locations_maximal_items(): options.SkillProgression.internal_name: options.SkillProgression.option_vanilla, options.SpecialOrderLocations.internal_name: options.SpecialOrderLocations.option_vanilla, options.ToolProgression.internal_name: options.ToolProgression.option_vanilla, - options.TrapItems.internal_name: options.TrapItems.option_nightmare, + options.TrapDifficulty.internal_name: options.TrapDifficulty.option_nightmare, options.Walnutsanity.internal_name: options.Walnutsanity.preset_none } return min_max_options From 68ed20861364c4f734a21aa9aac91667b18d7818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szab=C3=B3=20Benedek=20Zolt=C3=A1n?= <99742992+TVV1GK@users.noreply.github.com> Date: Sun, 11 May 2025 00:31:05 +0200 Subject: [PATCH 0408/1218] DS3: "US: Homeward Bone - foot, drop overlook" (#4875) --- worlds/dark_souls_3/Locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index c5cdbba85d82..7b30997581dc 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -706,7 +706,7 @@ def __init__( DS3LocationData("US: Whip - back alley, behind wooden wall", "Whip", hidden=True), DS3LocationData("US: Great Scythe - building by white tree, balcony", "Great Scythe"), DS3LocationData("US: Homeward Bone - foot, drop overlook", "Homeward Bone", - static='02,0:53100540::'), + static='02,0:53100950::'), DS3LocationData("US: Large Soul of a Deserted Corpse - around corner by Cliff Underside", "Large Soul of a Deserted Corpse", hidden=True), # Hidden corner DS3LocationData("US: Ember - behind burning tree", "Ember"), From a166dc77bcb2c3828d028bf8a69a1253ed894934 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Sat, 10 May 2025 17:49:49 -0500 Subject: [PATCH 0409/1218] Core: Plando Items "Rewrite" (#3046) --- BaseClasses.py | 37 +- Fill.py | 363 +++++++++--------- Generate.py | 14 +- Main.py | 14 +- Options.py | 140 ++++++- test/general/test_implemented.py | 16 + test/general/test_state.py | 2 +- worlds/alttp/EntranceRandomizer.py | 5 +- worlds/alttp/__init__.py | 37 +- worlds/blasphemous/__init__.py | 1 - worlds/hylics2/__init__.py | 4 + worlds/kh2/__init__.py | 4 + worlds/ladx/test/testShop.py | 12 +- worlds/oot/__init__.py | 4 +- worlds/pokemon_rb/__init__.py | 11 +- worlds/pokemon_rb/pokemon.py | 2 +- worlds/sc2/Locations.py | 7 +- worlds/shivers/__init__.py | 23 +- .../test/stability/TestUniversalTracker.py | 3 - worlds/witness/player_items.py | 25 +- 20 files changed, 455 insertions(+), 269 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index e59e96e17d1c..f480cbbda3de 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -9,8 +9,9 @@ from collections import Counter, deque from collections.abc import Collection, MutableSequence from enum import IntEnum, IntFlag -from typing import (AbstractSet, Any, Callable, ClassVar, Dict, Iterable, Iterator, List, Mapping, NamedTuple, +from typing import (AbstractSet, Any, Callable, ClassVar, Dict, Iterable, Iterator, List, Literal, Mapping, NamedTuple, Optional, Protocol, Set, Tuple, Union, TYPE_CHECKING) +import dataclasses from typing_extensions import NotRequired, TypedDict @@ -54,12 +55,21 @@ class HasNameAndPlayer(Protocol): player: int +@dataclasses.dataclass +class PlandoItemBlock: + player: int + from_pool: bool + force: bool | Literal["silent"] + worlds: set[int] = dataclasses.field(default_factory=set) + items: list[str] = dataclasses.field(default_factory=list) + locations: list[str] = dataclasses.field(default_factory=list) + resolved_locations: list[Location] = dataclasses.field(default_factory=list) + count: dict[str, int] = dataclasses.field(default_factory=dict) + + class MultiWorld(): debug_types = False player_name: Dict[int, str] - plando_texts: List[Dict[str, str]] - plando_items: List[List[Dict[str, Any]]] - plando_connections: List worlds: Dict[int, "AutoWorld.World"] groups: Dict[int, Group] regions: RegionManager @@ -83,6 +93,8 @@ class MultiWorld(): start_location_hints: Dict[int, Options.StartLocationHints] item_links: Dict[int, Options.ItemLinks] + plando_item_blocks: Dict[int, List[PlandoItemBlock]] + game: Dict[int, str] random: random.Random @@ -160,13 +172,12 @@ def __init__(self, players: int): self.local_early_items = {player: {} for player in self.player_ids} self.indirect_connections = {} self.start_inventory_from_pool: Dict[int, Options.StartInventoryPool] = {} + self.plando_item_blocks = {} for player in range(1, players + 1): def set_player_attr(attr: str, val) -> None: self.__dict__.setdefault(attr, {})[player] = val - set_player_attr('plando_items', []) - set_player_attr('plando_texts', {}) - set_player_attr('plando_connections', []) + set_player_attr('plando_item_blocks', []) set_player_attr('game', "Archipelago") set_player_attr('completion_condition', lambda state: True) self.worlds = {} @@ -427,7 +438,8 @@ def get_entrance(self, entrance_name: str, player: int) -> Entrance: def get_location(self, location_name: str, player: int) -> Location: return self.regions.location_cache[player][location_name] - def get_all_state(self, use_cache: bool, allow_partial_entrances: bool = False) -> CollectionState: + def get_all_state(self, use_cache: bool, allow_partial_entrances: bool = False, + collect_pre_fill_items: bool = True) -> CollectionState: cached = getattr(self, "_all_state", None) if use_cache and cached: return cached.copy() @@ -436,10 +448,11 @@ def get_all_state(self, use_cache: bool, allow_partial_entrances: bool = False) for item in self.itempool: self.worlds[item.player].collect(ret, item) - for player in self.player_ids: - subworld = self.worlds[player] - for item in subworld.get_pre_fill_items(): - subworld.collect(ret, item) + if collect_pre_fill_items: + for player in self.player_ids: + subworld = self.worlds[player] + for item in subworld.get_pre_fill_items(): + subworld.collect(ret, item) ret.sweep_for_advancements() if use_cache: diff --git a/Fill.py b/Fill.py index cce7aec2091e..ff59aa22cb47 100644 --- a/Fill.py +++ b/Fill.py @@ -4,7 +4,7 @@ import typing from collections import Counter, deque -from BaseClasses import CollectionState, Item, Location, LocationProgressType, MultiWorld +from BaseClasses import CollectionState, Item, Location, LocationProgressType, MultiWorld, PlandoItemBlock from Options import Accessibility from worlds.AutoWorld import call_all @@ -100,7 +100,7 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati # if minimal accessibility, only check whether location is reachable if game not beatable if multiworld.worlds[item_to_place.player].options.accessibility == Accessibility.option_minimal: perform_access_check = not multiworld.has_beaten_game(maximum_exploration_state, - item_to_place.player) \ + item_to_place.player) \ if single_player_placement else not has_beaten_game else: perform_access_check = True @@ -242,7 +242,7 @@ def remaining_fill(multiworld: MultiWorld, unplaced_items: typing.List[Item] = [] placements: typing.List[Location] = [] swapped_items: typing.Counter[typing.Tuple[int, str]] = Counter() - total = min(len(itempool), len(locations)) + total = min(len(itempool), len(locations)) placed = 0 # Optimisation: Decide whether to do full location.can_fill check (respect excluded), or only check the item rule @@ -343,8 +343,10 @@ def fast_fill(multiworld: MultiWorld, def accessibility_corrections(multiworld: MultiWorld, state: CollectionState, locations, pool=[]): maximum_exploration_state = sweep_from_pool(state, pool) - minimal_players = {player for player in multiworld.player_ids if multiworld.worlds[player].options.accessibility == "minimal"} - unreachable_locations = [location for location in multiworld.get_locations() if location.player in minimal_players and + minimal_players = {player for player in multiworld.player_ids if + multiworld.worlds[player].options.accessibility == "minimal"} + unreachable_locations = [location for location in multiworld.get_locations() if + location.player in minimal_players and not location.can_reach(maximum_exploration_state)] for location in unreachable_locations: if (location.item is not None and location.item.advancement and location.address is not None and not @@ -365,7 +367,7 @@ def inaccessible_location_rules(multiworld: MultiWorld, state: CollectionState, unreachable_locations = [location for location in locations if not location.can_reach(maximum_exploration_state)] if unreachable_locations: def forbid_important_item_rule(item: Item): - return not ((item.classification & 0b0011) and multiworld.worlds[item.player].options.accessibility != 'minimal') + return not ((item.classification & 0b0011) and multiworld.worlds[item.player].options.accessibility != "minimal") for location in unreachable_locations: add_item_rule(location, forbid_important_item_rule) @@ -677,9 +679,9 @@ def balance_multiworld_progression(multiworld: MultiWorld) -> None: if multiworld.worlds[player].options.progression_balancing > 0 } if not balanceable_players: - logging.info('Skipping multiworld progression balancing.') + logging.info("Skipping multiworld progression balancing.") else: - logging.info(f'Balancing multiworld progression for {len(balanceable_players)} Players.') + logging.info(f"Balancing multiworld progression for {len(balanceable_players)} Players.") logging.debug(balanceable_players) state: CollectionState = CollectionState(multiworld) checked_locations: typing.Set[Location] = set() @@ -777,7 +779,7 @@ def item_percentage(player: int, num: int) -> float: if player in threshold_percentages): break elif not balancing_sphere: - raise RuntimeError('Not all required items reachable. Something went terribly wrong here.') + raise RuntimeError("Not all required items reachable. Something went terribly wrong here.") # Gather a set of locations which we can swap items into unlocked_locations: typing.Dict[int, typing.Set[Location]] = collections.defaultdict(set) for l in unchecked_locations: @@ -793,8 +795,8 @@ def item_percentage(player: int, num: int) -> float: testing = items_to_test.pop() reducing_state = state.copy() for location in itertools.chain(( - l for l in items_to_replace - if l.item.player == player + l for l in items_to_replace + if l.item.player == player ), items_to_test): reducing_state.collect(location.item, True, location) @@ -867,52 +869,30 @@ def swap_location_item(location_1: Location, location_2: Location, check_locked: location_2.item.location = location_2 -def distribute_planned(multiworld: MultiWorld) -> None: - def warn(warning: str, force: typing.Union[bool, str]) -> None: - if force in [True, 'fail', 'failure', 'none', False, 'warn', 'warning']: - logging.warning(f'{warning}') +def parse_planned_blocks(multiworld: MultiWorld) -> dict[int, list[PlandoItemBlock]]: + def warn(warning: str, force: bool | str) -> None: + if isinstance(force, bool): + logging.warning(f"{warning}") else: - logging.debug(f'{warning}') + logging.debug(f"{warning}") - def failed(warning: str, force: typing.Union[bool, str]) -> None: - if force in [True, 'fail', 'failure']: + def failed(warning: str, force: bool | str) -> None: + if force is True: raise Exception(warning) else: warn(warning, force) - swept_state = multiworld.state.copy() - swept_state.sweep_for_advancements() - reachable = frozenset(multiworld.get_reachable_locations(swept_state)) - early_locations: typing.Dict[int, typing.List[str]] = collections.defaultdict(list) - non_early_locations: typing.Dict[int, typing.List[str]] = collections.defaultdict(list) - for loc in multiworld.get_unfilled_locations(): - if loc in reachable: - early_locations[loc.player].append(loc.name) - else: # not reachable with swept state - non_early_locations[loc.player].append(loc.name) - world_name_lookup = multiworld.world_name_lookup - block_value = typing.Union[typing.List[str], typing.Dict[str, typing.Any], str] - plando_blocks: typing.List[typing.Dict[str, typing.Any]] = [] - player_ids = set(multiworld.player_ids) + plando_blocks: dict[int, list[PlandoItemBlock]] = dict() + player_ids: set[int] = set(multiworld.player_ids) for player in player_ids: - for block in multiworld.plando_items[player]: - block['player'] = player - if 'force' not in block: - block['force'] = 'silent' - if 'from_pool' not in block: - block['from_pool'] = True - elif not isinstance(block['from_pool'], bool): - from_pool_type = type(block['from_pool']) - raise Exception(f'Plando "from_pool" has to be boolean, not {from_pool_type} for player {player}.') - if 'world' not in block: - target_world = False - else: - target_world = block['world'] - + plando_blocks[player] = [] + for block in multiworld.worlds[player].options.plando_items: + new_block: PlandoItemBlock = PlandoItemBlock(player, block.from_pool, block.force) + target_world = block.world if target_world is False or multiworld.players == 1: # target own world - worlds: typing.Set[int] = {player} + worlds: set[int] = {player} elif target_world is True: # target any worlds besides own worlds = set(multiworld.player_ids) - {player} elif target_world is None: # target all worlds @@ -922,172 +902,197 @@ def failed(warning: str, force: typing.Union[bool, str]) -> None: for listed_world in target_world: if listed_world not in world_name_lookup: failed(f"Cannot place item to {target_world}'s world as that world does not exist.", - block['force']) + block.force) continue worlds.add(world_name_lookup[listed_world]) elif type(target_world) == int: # target world by slot number if target_world not in range(1, multiworld.players + 1): failed( f"Cannot place item in world {target_world} as it is not in range of (1, {multiworld.players})", - block['force']) + block.force) continue worlds = {target_world} else: # target world by slot name if target_world not in world_name_lookup: failed(f"Cannot place item to {target_world}'s world as that world does not exist.", - block['force']) + block.force) continue worlds = {world_name_lookup[target_world]} - block['world'] = worlds - - items: block_value = [] - if "items" in block: - items = block["items"] - if 'count' not in block: - block['count'] = False - elif "item" in block: - items = block["item"] - if 'count' not in block: - block['count'] = 1 - else: - failed("You must specify at least one item to place items with plando.", block['force']) - continue + new_block.worlds = worlds + + items: list[str] | dict[str, typing.Any] = block.items if isinstance(items, dict): - item_list: typing.List[str] = [] + item_list: list[str] = [] for key, value in items.items(): if value is True: value = multiworld.itempool.count(multiworld.worlds[player].create_item(key)) item_list += [key] * value items = item_list - if isinstance(items, str): - items = [items] - block['items'] = items - - locations: block_value = [] - if 'location' in block: - locations = block['location'] # just allow 'location' to keep old yamls compatible - elif 'locations' in block: - locations = block['locations'] + new_block.items = items + + locations: list[str] = block.locations if isinstance(locations, str): locations = [locations] - if isinstance(locations, dict): - location_list = [] - for key, value in locations.items(): - location_list += [key] * value - locations = location_list + locations_from_groups: list[str] = [] + resolved_locations: list[Location] = [] + for target_player in worlds: + world_locations = multiworld.get_unfilled_locations(target_player) + for group in multiworld.worlds[target_player].location_name_groups: + if group in locations: + locations_from_groups.extend(multiworld.worlds[target_player].location_name_groups[group]) + resolved_locations.extend(location for location in world_locations + if location.name in [*locations, *locations_from_groups]) + new_block.locations = sorted(dict.fromkeys(locations)) + new_block.resolved_locations = sorted(set(resolved_locations)) + + count = block.count + if not count: + count = len(new_block.items) + if isinstance(count, int): + count = {"min": count, "max": count} + if "min" not in count: + count["min"] = 0 + if "max" not in count: + count["max"] = len(new_block.items) + + new_block.count = count + plando_blocks[player].append(new_block) + + return plando_blocks + + +def resolve_early_locations_for_planned(multiworld: MultiWorld): + def warn(warning: str, force: bool | str) -> None: + if isinstance(force, bool): + logging.warning(f"{warning}") + else: + logging.debug(f"{warning}") + + def failed(warning: str, force: bool | str) -> None: + if force is True: + raise Exception(warning) + else: + warn(warning, force) + swept_state = multiworld.state.copy() + swept_state.sweep_for_advancements() + reachable = frozenset(multiworld.get_reachable_locations(swept_state)) + early_locations: dict[int, list[Location]] = collections.defaultdict(list) + non_early_locations: dict[int, list[Location]] = collections.defaultdict(list) + for loc in multiworld.get_unfilled_locations(): + if loc in reachable: + early_locations[loc.player].append(loc) + else: # not reachable with swept state + non_early_locations[loc.player].append(loc) + + for player in multiworld.plando_item_blocks: + removed = [] + for block in multiworld.plando_item_blocks[player]: + locations = block.locations + resolved_locations = block.resolved_locations + worlds = block.worlds if "early_locations" in locations: - locations.remove("early_locations") for target_player in worlds: - locations += early_locations[target_player] + resolved_locations += early_locations[target_player] if "non_early_locations" in locations: - locations.remove("non_early_locations") for target_player in worlds: - locations += non_early_locations[target_player] - - block['locations'] = list(dict.fromkeys(locations)) - - if not block['count']: - block['count'] = (min(len(block['items']), len(block['locations'])) if - len(block['locations']) > 0 else len(block['items'])) - if isinstance(block['count'], int): - block['count'] = {'min': block['count'], 'max': block['count']} - if 'min' not in block['count']: - block['count']['min'] = 0 - if 'max' not in block['count']: - block['count']['max'] = (min(len(block['items']), len(block['locations'])) if - len(block['locations']) > 0 else len(block['items'])) - if block['count']['max'] > len(block['items']): - count = block['count'] - failed(f"Plando count {count} greater than items specified", block['force']) - block['count'] = len(block['items']) - if block['count']['max'] > len(block['locations']) > 0: - count = block['count'] - failed(f"Plando count {count} greater than locations specified", block['force']) - block['count'] = len(block['locations']) - block['count']['target'] = multiworld.random.randint(block['count']['min'], block['count']['max']) - - if block['count']['target'] > 0: - plando_blocks.append(block) + resolved_locations += non_early_locations[target_player] + + if block.count["max"] > len(block.items): + count = block.count["max"] + failed(f"Plando count {count} greater than items specified", block.force) + block.count["max"] = len(block.items) + if block.count["min"] > len(block.items): + block.count["min"] = len(block.items) + if block.count["max"] > len(block.resolved_locations) > 0: + count = block.count["max"] + failed(f"Plando count {count} greater than locations specified", block.force) + block.count["max"] = len(block.resolved_locations) + if block.count["min"] > len(block.resolved_locations): + block.count["min"] = len(block.resolved_locations) + block.count["target"] = multiworld.random.randint(block.count["min"], + block.count["max"]) + + if not block.count["target"]: + removed.append(block) + + for block in removed: + multiworld.plando_item_blocks[player].remove(block) + + +def distribute_planned_blocks(multiworld: MultiWorld, plando_blocks: list[PlandoItemBlock]): + def warn(warning: str, force: bool | str) -> None: + if isinstance(force, bool): + logging.warning(f"{warning}") + else: + logging.debug(f"{warning}") + + def failed(warning: str, force: bool | str) -> None: + if force is True: + raise Exception(warning) + else: + warn(warning, force) # shuffle, but then sort blocks by number of locations minus number of items, # so less-flexible blocks get priority multiworld.random.shuffle(plando_blocks) - plando_blocks.sort(key=lambda block: (len(block['locations']) - block['count']['target'] - if len(block['locations']) > 0 - else len(multiworld.get_unfilled_locations(player)) - block['count']['target'])) - + plando_blocks.sort(key=lambda block: (len(block.resolved_locations) - block.count["target"] + if len(block.resolved_locations) > 0 + else len(multiworld.get_unfilled_locations(block.player)) - + block.count["target"])) for placement in plando_blocks: - player = placement['player'] + player = placement.player try: - worlds = placement['world'] - locations = placement['locations'] - items = placement['items'] - maxcount = placement['count']['target'] - from_pool = placement['from_pool'] - - candidates = list(multiworld.get_unfilled_locations_for_players(locations, sorted(worlds))) - multiworld.random.shuffle(candidates) - multiworld.random.shuffle(items) - count = 0 - err: typing.List[str] = [] - successful_pairs: typing.List[typing.Tuple[int, Item, Location]] = [] - claimed_indices: typing.Set[typing.Optional[int]] = set() - for item_name in items: - index_to_delete: typing.Optional[int] = None - if from_pool: - try: - # If from_pool, try to find an existing item with this name & player in the itempool and use it - index_to_delete, item = next( - (i, item) for i, item in enumerate(multiworld.itempool) - if item.player == player and item.name == item_name and i not in claimed_indices - ) - except StopIteration: - warn( - f"Could not remove {item_name} from pool for {multiworld.player_name[player]} as it's already missing from it.", - placement['force']) - item = multiworld.worlds[player].create_item(item_name) - else: - item = multiworld.worlds[player].create_item(item_name) - - for location in reversed(candidates): - if (location.address is None) == (item.code is None): # either both None or both not None - if not location.item: - if location.item_rule(item): - if location.can_fill(multiworld.state, item, False): - successful_pairs.append((index_to_delete, item, location)) - claimed_indices.add(index_to_delete) - candidates.remove(location) - count = count + 1 - break - else: - err.append(f"Can't place item at {location} due to fill condition not met.") - else: - err.append(f"{item_name} not allowed at {location}.") - else: - err.append(f"Cannot place {item_name} into already filled location {location}.") + worlds = placement.worlds + locations = placement.resolved_locations + items = placement.items + maxcount = placement.count["target"] + from_pool = placement.from_pool + + item_candidates = [] + if from_pool: + instances = [item for item in multiworld.itempool if item.player == player and item.name in items] + for item in multiworld.random.sample(items, maxcount): + candidate = next((i for i in instances if i.name == item), None) + if candidate is None: + warn(f"Could not remove {item} from pool for {multiworld.player_name[player]} as " + f"it's already missing from it", placement.force) + candidate = multiworld.worlds[player].create_item(item) else: - err.append(f"Mismatch between {item_name} and {location}, only one is an event.") - - if count == maxcount: - break - if count < placement['count']['min']: - m = placement['count']['min'] - failed( - f"Plando block failed to place {m - count} of {m} item(s) for {multiworld.player_name[player]}, error(s): {' '.join(err)}", - placement['force']) - - # Sort indices in reverse so we can remove them one by one - successful_pairs = sorted(successful_pairs, key=lambda successful_pair: successful_pair[0] or 0, reverse=True) - - for (index, item, location) in successful_pairs: - multiworld.push_item(location, item, collect=False) - location.locked = True - logging.debug(f"Plando placed {item} at {location}") - if index is not None: # If this item is from_pool and was found in the pool, remove it. - multiworld.itempool.pop(index) - + multiworld.itempool.remove(candidate) + instances.remove(candidate) + item_candidates.append(candidate) + else: + item_candidates = [multiworld.worlds[player].create_item(item) + for item in multiworld.random.sample(items, maxcount)] + if any(item.code is None for item in item_candidates) \ + and not all(item.code is None for item in item_candidates): + failed(f"Plando block for player {player} ({multiworld.player_name[player]}) contains both " + f"event items and non-event items. " + f"Event items: {[item for item in item_candidates if item.code is None]}, " + f"Non-event items: {[item for item in item_candidates if item.code is not None]}", + placement.force) + continue + else: + is_real = item_candidates[0].code is not None + candidates = [candidate for candidate in locations if candidate.item is None + and bool(candidate.address) == is_real] + multiworld.random.shuffle(candidates) + allstate = multiworld.get_all_state(False) + mincount = placement.count["min"] + allowed_margin = len(item_candidates) - mincount + fill_restrictive(multiworld, allstate, candidates, item_candidates, lock=True, + allow_partial=True, name="Plando Main Fill") + + if len(item_candidates) > allowed_margin: + failed(f"Could not place {len(item_candidates)} " + f"of {mincount + allowed_margin} item(s) " + f"for {multiworld.player_name[player]}, " + f"remaining items: {item_candidates}", + placement.force) + if from_pool: + multiworld.itempool.extend([item for item in item_candidates if item.code is not None]) except Exception as e: raise Exception( f"Error running plando for player {player} ({multiworld.player_name[player]})") from e diff --git a/Generate.py b/Generate.py index 867a5b6c7a61..e72887c26c2c 100644 --- a/Generate.py +++ b/Generate.py @@ -334,12 +334,6 @@ def handle_name(name: str, player: int, name_counter: Counter): return new_name -def roll_percentage(percentage: Union[int, float]) -> bool: - """Roll a percentage chance. - percentage is expected to be in range [0, 100]""" - return random.random() < (float(percentage) / 100) - - def update_weights(weights: dict, new_weights: dict, update_type: str, name: str) -> dict: logging.debug(f'Applying {new_weights}') cleaned_weights = {} @@ -405,7 +399,7 @@ def roll_linked_options(weights: dict) -> dict: if "name" not in option_set: raise ValueError("One of your linked options does not have a name.") try: - if roll_percentage(option_set["percentage"]): + if Options.roll_percentage(option_set["percentage"]): logging.debug(f"Linked option {option_set['name']} triggered.") new_options = option_set["options"] for category_name, category_options in new_options.items(): @@ -438,7 +432,7 @@ def roll_triggers(weights: dict, triggers: list, valid_keys: set) -> dict: trigger_result = get_choice("option_result", option_set) result = get_choice(key, currently_targeted_weights) currently_targeted_weights[key] = result - if result == trigger_result and roll_percentage(get_choice("percentage", option_set, 100)): + if result == trigger_result and Options.roll_percentage(get_choice("percentage", option_set, 100)): for category_name, category_options in option_set["options"].items(): currently_targeted_weights = weights if category_name: @@ -542,10 +536,6 @@ def roll_settings(weights: dict, plando_options: PlandoOptions = PlandoOptions.b handle_option(ret, game_weights, option_key, option, plando_options) valid_keys.add(option_key) - # TODO remove plando_items after moving it to the options system - valid_keys.add("plando_items") - if PlandoOptions.items in plando_options: - ret.plando_items = copy.deepcopy(game_weights.get("plando_items", [])) if ret.game == "A Link to the Past": # TODO there are still more LTTP options not on the options system valid_keys |= {"sprite_pool", "sprite", "random_sprite_on_event"} diff --git a/Main.py b/Main.py index 5d9e1bc2110e..147fa382e249 100644 --- a/Main.py +++ b/Main.py @@ -11,8 +11,8 @@ import worlds from BaseClasses import CollectionState, Item, Location, LocationProgressType, MultiWorld, Region -from Fill import FillError, balance_multiworld_progression, distribute_items_restrictive, distribute_planned, \ - flood_items +from Fill import FillError, balance_multiworld_progression, distribute_items_restrictive, flood_items, \ + parse_planned_blocks, distribute_planned_blocks, resolve_early_locations_for_planned from Options import StartInventoryPool from Utils import __version__, output_path, version_tuple, get_settings from settings import get_settings @@ -37,9 +37,6 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No logger = logging.getLogger() multiworld.set_seed(seed, args.race, str(args.outputname) if args.outputname else None) multiworld.plando_options = args.plando_options - multiworld.plando_items = args.plando_items.copy() - multiworld.plando_texts = args.plando_texts.copy() - multiworld.plando_connections = args.plando_connections.copy() multiworld.game = args.game.copy() multiworld.player_name = args.name.copy() multiworld.sprite = args.sprite.copy() @@ -135,6 +132,8 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No multiworld.worlds[1].options.non_local_items.value = set() multiworld.worlds[1].options.local_items.value = set() + multiworld.plando_item_blocks = parse_planned_blocks(multiworld) + AutoWorld.call_all(multiworld, "connect_entrances") AutoWorld.call_all(multiworld, "generate_basic") @@ -179,8 +178,9 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No multiworld._all_state = None logger.info("Running Item Plando.") - - distribute_planned(multiworld) + resolve_early_locations_for_planned(multiworld) + distribute_planned_blocks(multiworld, [x for player in multiworld.plando_item_blocks + for x in multiworld.plando_item_blocks[player]]) logger.info('Running Pre Main Fill.') diff --git a/Options.py b/Options.py index 41c2a77d3a4b..86e58ca64aba 100644 --- a/Options.py +++ b/Options.py @@ -24,6 +24,12 @@ import pathlib +def roll_percentage(percentage: int | float) -> bool: + """Roll a percentage chance. + percentage is expected to be in range [0, 100]""" + return random.random() < (float(percentage) / 100) + + class OptionError(ValueError): pass @@ -1019,7 +1025,7 @@ def from_any(cls, data: PlandoTextsFromAnyType) -> Self: if isinstance(data, typing.Iterable): for text in data: if isinstance(text, typing.Mapping): - if random.random() < float(text.get("percentage", 100)/100): + if roll_percentage(text.get("percentage", 100)): at = text.get("at", None) if at is not None: if isinstance(at, dict): @@ -1045,7 +1051,7 @@ def from_any(cls, data: PlandoTextsFromAnyType) -> Self: else: raise OptionError("\"at\" must be a valid string or weighted list of strings!") elif isinstance(text, PlandoText): - if random.random() < float(text.percentage/100): + if roll_percentage(text.percentage): texts.append(text) else: raise Exception(f"Cannot create plando text from non-dictionary type, got {type(text)}") @@ -1169,7 +1175,7 @@ def from_any(cls, data: PlandoConFromAnyType) -> Self: for connection in data: if isinstance(connection, typing.Mapping): percentage = connection.get("percentage", 100) - if random.random() < float(percentage / 100): + if roll_percentage(percentage): entrance = connection.get("entrance", None) if is_iterable_except_str(entrance): entrance = random.choice(sorted(entrance)) @@ -1187,7 +1193,7 @@ def from_any(cls, data: PlandoConFromAnyType) -> Self: percentage )) elif isinstance(connection, PlandoConnection): - if random.random() < float(connection.percentage / 100): + if roll_percentage(connection.percentage): value.append(connection) else: raise Exception(f"Cannot create connection from non-Dict type, got {type(connection)}.") @@ -1469,6 +1475,131 @@ def verify(self, world: typing.Type[World], player_name: str, plando_options: "P link["item_pool"] = list(pool) +@dataclass(frozen=True) +class PlandoItem: + items: list[str] | dict[str, typing.Any] + locations: list[str] + world: int | str | bool | None | typing.Iterable[str] | set[int] = False + from_pool: bool = True + force: bool | typing.Literal["silent"] = "silent" + count: int | bool | dict[str, int] = False + percentage: int = 100 + + +class PlandoItems(Option[typing.List[PlandoItem]]): + """Generic items plando.""" + default = () + supports_weighting = False + display_name = "Plando Items" + + def __init__(self, value: typing.Iterable[PlandoItem]) -> None: + self.value = list(deepcopy(value)) + super().__init__() + + @classmethod + def from_any(cls, data: typing.Any) -> Option[typing.List[PlandoItem]]: + if not isinstance(data, typing.Iterable): + raise OptionError(f"Cannot create plando items from non-Iterable type, got {type(data)}") + + value: typing.List[PlandoItem] = [] + for item in data: + if isinstance(item, typing.Mapping): + percentage = item.get("percentage", 100) + if not isinstance(percentage, int): + raise OptionError(f"Plando `percentage` has to be int, not {type(percentage)}.") + if not (0 <= percentage <= 100): + raise OptionError(f"Plando `percentage` has to be between 0 and 100 (inclusive) not {percentage}.") + if roll_percentage(percentage): + count = item.get("count", False) + items = item.get("items", []) + if not items: + items = item.get("item", None) # explicitly throw an error here if not present + if not items: + raise OptionError("You must specify at least one item to place items with plando.") + count = 1 + if isinstance(items, str): + items = [items] + elif not isinstance(items, (dict, list)): + raise OptionError(f"Plando 'items' has to be string, list, or " + f"dictionary, not {type(items)}") + locations = item.get("locations", []) + if not locations: + locations = item.get("location", ["Everywhere"]) + if locations: + count = 1 + if isinstance(locations, str): + locations = [locations] + if not isinstance(locations, list): + raise OptionError(f"Plando `location` has to be string or list, not {type(locations)}") + world = item.get("world", False) + from_pool = item.get("from_pool", True) + force = item.get("force", "silent") + if not isinstance(from_pool, bool): + raise OptionError(f"Plando 'from_pool' has to be true or false, not {from_pool!r}.") + if not (isinstance(force, bool) or force == "silent"): + raise OptionError(f"Plando `force` has to be true or false or `silent`, not {force!r}.") + value.append(PlandoItem(items, locations, world, from_pool, force, count, percentage)) + elif isinstance(item, PlandoItem): + if roll_percentage(item.percentage): + value.append(item) + else: + raise OptionError(f"Cannot create plando item from non-Dict type, got {type(item)}.") + return cls(value) + + def verify(self, world: typing.Type[World], player_name: str, plando_options: "PlandoOptions") -> None: + if not self.value: + return + from BaseClasses import PlandoOptions + if not (PlandoOptions.items & plando_options): + # plando is disabled but plando options were given so overwrite the options + self.value = [] + logging.warning(f"The plando items module is turned off, " + f"so items for {player_name} will be ignored.") + else: + # filter down item groups + for plando in self.value: + # confirm a valid count + if isinstance(plando.count, dict): + if "min" in plando.count and "max" in plando.count: + if plando.count["min"] > plando.count["max"]: + raise OptionError("Plando cannot have count `min` greater than `max`.") + items_copy = plando.items.copy() + if isinstance(plando.items, dict): + for item in items_copy: + if item in world.item_name_groups: + value = plando.items.pop(item) + group = world.item_name_groups[item] + filtered_items = sorted(group.difference(list(plando.items.keys()))) + if not filtered_items: + raise OptionError(f"Plando `items` contains the group \"{item}\" " + f"and every item in it. This is not allowed.") + if value is True: + for key in filtered_items: + plando.items[key] = True + else: + for key in random.choices(filtered_items, k=value): + plando.items[key] = plando.items.get(key, 0) + 1 + else: + assert isinstance(plando.items, list) # pycharm can't figure out the hinting without the hint + for item in items_copy: + if item in world.item_name_groups: + plando.items.remove(item) + plando.items.extend(sorted(world.item_name_groups[item])) + + @classmethod + def get_option_name(cls, value: list[PlandoItem]) -> str: + return ", ".join(["(%s: %s)" % (item.items, item.locations) for item in value]) #TODO: see what a better way to display would be + + def __getitem__(self, index: typing.SupportsIndex) -> PlandoItem: + return self.value.__getitem__(index) + + def __iter__(self) -> typing.Iterator[PlandoItem]: + yield from self.value + + def __len__(self) -> int: + return len(self.value) + + class Removed(FreeText): """This Option has been Removed.""" rich_text_doc = True @@ -1491,6 +1622,7 @@ class PerGameCommonOptions(CommonOptions): exclude_locations: ExcludeLocations priority_locations: PriorityLocations item_links: ItemLinks + plando_items: PlandoItems @dataclass diff --git a/test/general/test_implemented.py b/test/general/test_implemented.py index 1082a02912a8..b74f82b738b5 100644 --- a/test/general/test_implemented.py +++ b/test/general/test_implemented.py @@ -53,6 +53,22 @@ def test_no_failed_world_loads(self): if failed_world_loads: self.fail(f"The following worlds failed to load: {failed_world_loads}") + def test_prefill_items(self): + """Test that every world can reach every location from allstate before pre_fill.""" + for gamename, world_type in AutoWorldRegister.world_types.items(): + if gamename not in ("Archipelago", "Sudoku", "Final Fantasy", "Test Game"): + with self.subTest(gamename): + multiworld = setup_solo_multiworld(world_type, ("generate_early", "create_regions", "create_items", + "set_rules", "connect_entrances", "generate_basic")) + allstate = multiworld.get_all_state(False) + locations = multiworld.get_locations() + reachable = multiworld.get_reachable_locations(allstate) + unreachable = [location for location in locations if location not in reachable] + + self.assertTrue(not unreachable, + f"Locations were not reachable with all state before prefill: " + f"{unreachable}. Seed: {multiworld.seed}") + def test_explicit_indirect_conditions_spheres(self): """Tests that worlds using explicit indirect conditions produce identical spheres as when using implicit indirect conditions""" diff --git a/test/general/test_state.py b/test/general/test_state.py index 460fc3d60846..06c4046a6942 100644 --- a/test/general/test_state.py +++ b/test/general/test_state.py @@ -26,4 +26,4 @@ def test_all_state_is_available(self): for step in self.test_steps: with self.subTest("Step", step=step): call_all(multiworld, step) - self.assertTrue(multiworld.get_all_state(False, True)) + self.assertTrue(multiworld.get_all_state(False, allow_partial_entrances=True)) diff --git a/worlds/alttp/EntranceRandomizer.py b/worlds/alttp/EntranceRandomizer.py index e62088c1e05c..569e6a5d7ef3 100644 --- a/worlds/alttp/EntranceRandomizer.py +++ b/worlds/alttp/EntranceRandomizer.py @@ -54,16 +54,13 @@ def defval(value): ret = parser.parse_args(argv) # cannot be set through CLI currently - ret.plando_items = [] - ret.plando_texts = {} - ret.plando_connections = [] if multiargs.multi: defaults = copy.deepcopy(ret) for player in range(1, multiargs.multi + 1): playerargs = parse_arguments(shlex.split(getattr(ret, f"p{player}")), True) - for name in ["plando_items", "plando_texts", "plando_connections", "game", "sprite", "sprite_pool"]: + for name in ["game", "sprite", "sprite_pool"]: value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) if player == 1: setattr(ret, name, {1: value}) diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index 1934138afa50..7f8d6ddf68ac 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -505,20 +505,20 @@ def collect_item(self, state: CollectionState, item: Item, remove=False): def pre_fill(self): from Fill import fill_restrictive, FillError attempts = 5 - world = self.multiworld - player = self.player - all_state = world.get_all_state(use_cache=True) + all_state = self.multiworld.get_all_state(use_cache=False) crystals = [self.create_item(name) for name in ['Red Pendant', 'Blue Pendant', 'Green Pendant', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 7', 'Crystal 5', 'Crystal 6']] - crystal_locations = [world.get_location('Turtle Rock - Prize', player), - world.get_location('Eastern Palace - Prize', player), - world.get_location('Desert Palace - Prize', player), - world.get_location('Tower of Hera - Prize', player), - world.get_location('Palace of Darkness - Prize', player), - world.get_location('Thieves\' Town - Prize', player), - world.get_location('Skull Woods - Prize', player), - world.get_location('Swamp Palace - Prize', player), - world.get_location('Ice Palace - Prize', player), - world.get_location('Misery Mire - Prize', player)] + for crystal in crystals: + all_state.remove(crystal) + crystal_locations = [self.get_location('Turtle Rock - Prize'), + self.get_location('Eastern Palace - Prize'), + self.get_location('Desert Palace - Prize'), + self.get_location('Tower of Hera - Prize'), + self.get_location('Palace of Darkness - Prize'), + self.get_location('Thieves\' Town - Prize'), + self.get_location('Skull Woods - Prize'), + self.get_location('Swamp Palace - Prize'), + self.get_location('Ice Palace - Prize'), + self.get_location('Misery Mire - Prize')] placed_prizes = {loc.item.name for loc in crystal_locations if loc.item} unplaced_prizes = [crystal for crystal in crystals if crystal.name not in placed_prizes] empty_crystal_locations = [loc for loc in crystal_locations if not loc.item] @@ -526,8 +526,8 @@ def pre_fill(self): try: prizepool = unplaced_prizes.copy() prize_locs = empty_crystal_locations.copy() - world.random.shuffle(prize_locs) - fill_restrictive(world, all_state, prize_locs, prizepool, True, lock=True, + self.multiworld.random.shuffle(prize_locs) + fill_restrictive(self.multiworld, all_state, prize_locs, prizepool, True, lock=True, name="LttP Dungeon Prizes") except FillError as e: lttp_logger.exception("Failed to place dungeon prizes (%s). Will retry %s more times", e, @@ -541,7 +541,7 @@ def pre_fill(self): if self.options.mode == 'standard' and self.options.small_key_shuffle \ and self.options.small_key_shuffle != small_key_shuffle.option_universal and \ self.options.small_key_shuffle != small_key_shuffle.option_own_dungeons: - world.local_early_items[player]["Small Key (Hyrule Castle)"] = 1 + self.multiworld.local_early_items[self.player]["Small Key (Hyrule Castle)"] = 1 @classmethod def stage_pre_fill(cls, world): @@ -811,12 +811,15 @@ def get_filler_item_name(self) -> str: return GetBeemizerItem(self.multiworld, self.player, item) def get_pre_fill_items(self): - res = [] + res = [self.create_item(name) for name in ('Red Pendant', 'Blue Pendant', 'Green Pendant', 'Crystal 1', + 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 7', 'Crystal 5', + 'Crystal 6')] if self.dungeon_local_item_names: for dungeon in self.dungeons.values(): for item in dungeon.all_items: if item.name in self.dungeon_local_item_names: res.append(item) + return res def fill_slot_data(self): diff --git a/worlds/blasphemous/__init__.py b/worlds/blasphemous/__init__.py index a643e91c9b89..9dffc6c6d286 100644 --- a/worlds/blasphemous/__init__.py +++ b/worlds/blasphemous/__init__.py @@ -207,7 +207,6 @@ def create_items(self): if not self.options.skill_randomizer: self.place_items_from_dict(skill_dict) - def place_items_from_set(self, location_set: Set[str], name: str): for loc in location_set: self.get_location(loc).place_locked_item(self.create_item(name)) diff --git a/worlds/hylics2/__init__.py b/worlds/hylics2/__init__.py index 18bcb0edc143..f94d9c225373 100644 --- a/worlds/hylics2/__init__.py +++ b/worlds/hylics2/__init__.py @@ -127,6 +127,10 @@ def pre_fill(self): tv = tvs.pop() self.get_location(tv).place_locked_item(self.create_item(gesture)) + def get_pre_fill_items(self) -> List["Item"]: + if self.options.gesture_shuffle: + return [self.create_item(gesture["name"]) for gesture in Items.gesture_item_table.values()] + return [] def fill_slot_data(self) -> Dict[str, Any]: slot_data: Dict[str, Any] = { diff --git a/worlds/kh2/__init__.py b/worlds/kh2/__init__.py index edc4305accaf..defb285d509c 100644 --- a/worlds/kh2/__init__.py +++ b/worlds/kh2/__init__.py @@ -436,6 +436,10 @@ def keyblade_pre_fill(self): for location in keyblade_locations: location.locked = True + def get_pre_fill_items(self) -> List["Item"]: + return [self.create_item(item) for item in [*DonaldAbility_Table.keys(), *GoofyAbility_Table.keys(), + *SupportAbility_Table.keys()]] + def starting_invo_verify(self): """ Making sure the player doesn't put too many abilities in their starting inventory. diff --git a/worlds/ladx/test/testShop.py b/worlds/ladx/test/testShop.py index 91d504d521b4..a28ba39b2f7c 100644 --- a/worlds/ladx/test/testShop.py +++ b/worlds/ladx/test/testShop.py @@ -1,6 +1,7 @@ from typing import Optional -from Fill import distribute_planned +from Fill import parse_planned_blocks, distribute_planned_blocks, resolve_early_locations_for_planned +from Options import PlandoItems from test.general import setup_solo_multiworld from worlds.AutoWorld import call_all from . import LADXTestBase @@ -19,14 +20,17 @@ class PlandoTest(LADXTestBase): ], }], } - + def world_setup(self, seed: Optional[int] = None) -> None: self.multiworld = setup_solo_multiworld( LinksAwakeningWorld, ("generate_early", "create_regions", "create_items", "set_rules", "generate_basic") ) - self.multiworld.plando_items[1] = self.options["plando_items"] - distribute_planned(self.multiworld) + self.multiworld.worlds[1].options.plando_items = PlandoItems.from_any(self.options["plando_items"]) + self.multiworld.plando_item_blocks = parse_planned_blocks(self.multiworld) + resolve_early_locations_for_planned(self.multiworld) + distribute_planned_blocks(self.multiworld, [x for player in self.multiworld.plando_item_blocks + for x in self.multiworld.plando_item_blocks[player]]) call_all(self.multiworld, "pre_fill") def test_planned(self): diff --git a/worlds/oot/__init__.py b/worlds/oot/__init__.py index 136439ee96f2..401c387d5e05 100644 --- a/worlds/oot/__init__.py +++ b/worlds/oot/__init__.py @@ -32,7 +32,7 @@ from settings import get_settings from BaseClasses import MultiWorld, CollectionState, Tutorial, LocationProgressType -from Options import Range, Toggle, VerifyKeys, Accessibility, PlandoConnections +from Options import Range, Toggle, VerifyKeys, Accessibility, PlandoConnections, PlandoItems from Fill import fill_restrictive, fast_fill, FillError from worlds.generic.Rules import exclusion_rules, add_item_rule from worlds.AutoWorld import World, AutoLogicRegister, WebWorld @@ -220,6 +220,8 @@ def generate_early(self): option_value = result.value elif isinstance(result, PlandoConnections): option_value = result.value + elif isinstance(result, PlandoItems): + option_value = result.value else: option_value = result.current_key setattr(self, option_name, option_value) diff --git a/worlds/pokemon_rb/__init__.py b/worlds/pokemon_rb/__init__.py index 6bf66a11064a..a455e38f2934 100644 --- a/worlds/pokemon_rb/__init__.py +++ b/worlds/pokemon_rb/__init__.py @@ -321,7 +321,7 @@ def fill_hook(self, progitempool, usefulitempool, filleritempool, fill_locations "Fuchsia Gym - Koga Prize", "Saffron Gym - Sabrina Prize", "Cinnabar Gym - Blaine Prize", "Viridian Gym - Giovanni Prize" ] if self.multiworld.get_location(loc, self.player).item is None] - state = self.multiworld.get_all_state(False) + state = self.multiworld.get_all_state(False, True, False) # Give it two tries to place badges with wild Pokemon and learnsets as-is. # If it can't, then try with all Pokemon collected, and we'll try to fix HM move availability after. if attempt > 1: @@ -395,7 +395,7 @@ def pre_fill(self) -> None: # Delete evolution events for Pokémon that are not in logic in an all_state so that accessibility check does not # fail. Re-use test_state from previous final loop. - all_state = self.multiworld.get_all_state(False) + all_state = self.multiworld.get_all_state(False, True, False) evolutions_region = self.multiworld.get_region("Evolution", self.player) for location in evolutions_region.locations.copy(): if not all_state.can_reach(location, player=self.player): @@ -448,7 +448,7 @@ def pre_fill(self) -> None: self.local_locs = locs - all_state = self.multiworld.get_all_state(False) + all_state = self.multiworld.get_all_state(False, True, False) reachable_mons = set() for mon in poke_data.pokemon_data: @@ -516,6 +516,11 @@ def pre_fill(self) -> None: loc.item = None loc.place_locked_item(self.pc_item) + def get_pre_fill_items(self) -> typing.List["Item"]: + pool = [self.create_item(mon) for mon in poke_data.pokemon_data] + pool.append(self.pc_item) + return pool + @classmethod def stage_post_fill(cls, multiworld): # Convert all but one of each instance of a wild Pokemon to useful classification. diff --git a/worlds/pokemon_rb/pokemon.py b/worlds/pokemon_rb/pokemon.py index e5d161a43310..f1c171b88deb 100644 --- a/worlds/pokemon_rb/pokemon.py +++ b/worlds/pokemon_rb/pokemon.py @@ -400,7 +400,7 @@ def number_of_zones(mon): last_intervene = None while True: intervene_move = None - test_state = multiworld.get_all_state(False) + test_state = multiworld.get_all_state(False, True, False) if not logic.can_learn_hm(test_state, world, "Surf", player): intervene_move = "Surf" elif not logic.can_learn_hm(test_state, world, "Strength", player): diff --git a/worlds/sc2/Locations.py b/worlds/sc2/Locations.py index b9c30bb70106..42b1dd4d4eb0 100644 --- a/worlds/sc2/Locations.py +++ b/worlds/sc2/Locations.py @@ -66,11 +66,8 @@ def get_plando_locations(world: World) -> List[str]: if world is None: return [] plando_locations = [] - for plando_setting in world.multiworld.plando_items[world.player]: - plando_locations += plando_setting.get("locations", []) - plando_setting_location = plando_setting.get("location", None) - if plando_setting_location is not None: - plando_locations.append(plando_setting_location) + for plando_setting in world.options.plando_items: + plando_locations += plando_setting.locations return plando_locations diff --git a/worlds/shivers/__init__.py b/worlds/shivers/__init__.py index 85f2cf1861a7..3430a5a02d4e 100644 --- a/worlds/shivers/__init__.py +++ b/worlds/shivers/__init__.py @@ -245,7 +245,7 @@ def pre_fill(self) -> None: storage_items += [self.create_item("Empty") for _ in range(3)] - state = self.multiworld.get_all_state(False) + state = self.multiworld.get_all_state(False, True, False) self.random.shuffle(storage_locs) self.random.shuffle(storage_items) @@ -255,6 +255,27 @@ def pre_fill(self) -> None: self.storage_placements = {location.name.replace("Storage: ", ""): location.item.name.replace(" DUPE", "") for location in storage_locs} + def get_pre_fill_items(self) -> List[Item]: + if self.options.full_pots == "pieces": + return [self.create_item(name) for name, data in item_table.items() if + data.type == ItemType.POT_DUPLICATE] + elif self.options.full_pots == "complete": + return [self.create_item(name) for name, data in item_table.items() if + data.type == ItemType.POT_COMPELTE_DUPLICATE] + else: + pool = [] + pieces = [self.create_item(name) for name, data in item_table.items() if + data.type == ItemType.POT_DUPLICATE] + complete = [self.create_item(name) for name, data in item_table.items() if + data.type == ItemType.POT_COMPELTE_DUPLICATE] + for i in range(10): + if self.pot_completed_list[i] == 0: + pool.append(pieces[i]) + pool.append(pieces[i + 10]) + else: + pool.append(complete[i]) + return pool + def fill_slot_data(self) -> dict: return { "StoragePlacements": self.storage_placements, diff --git a/worlds/stardew_valley/test/stability/TestUniversalTracker.py b/worlds/stardew_valley/test/stability/TestUniversalTracker.py index 0268d9e515ec..7590635aa193 100644 --- a/worlds/stardew_valley/test/stability/TestUniversalTracker.py +++ b/worlds/stardew_valley/test/stability/TestUniversalTracker.py @@ -35,9 +35,6 @@ def test_all_locations_and_items_are_the_same_between_two_generations(self): args.multi = 1 args.race = None args.plando_options = self.multiworld.plando_options - args.plando_items = self.multiworld.plando_items - args.plando_texts = self.multiworld.plando_texts - args.plando_connections = self.multiworld.plando_connections args.game = self.multiworld.game args.name = self.multiworld.player_name args.sprite = {} diff --git a/worlds/witness/player_items.py b/worlds/witness/player_items.py index 7b71e3c1f933..d13ebcafdcaf 100644 --- a/worlds/witness/player_items.py +++ b/worlds/witness/player_items.py @@ -214,20 +214,17 @@ def get_early_items(self) -> List[str]: # Remove items that are mentioned in any plando options. (Hopefully, in the future, plando will get resolved # before create_items so that we'll be able to check placed items instead of just removing all items mentioned # regardless of whether or not they actually wind up being manually placed. - for plando_setting in self._multiworld.plando_items[self._player_id]: - if plando_setting.get("from_pool", True): - for item_setting_key in [key for key in ["item", "items"] if key in plando_setting]: - if isinstance(plando_setting[item_setting_key], str): - output -= {plando_setting[item_setting_key]} - elif isinstance(plando_setting[item_setting_key], dict): - output -= {item for item, weight in plando_setting[item_setting_key].items() if weight} - else: - # Assume this is some other kind of iterable. - for inner_item in plando_setting[item_setting_key]: - if isinstance(inner_item, str): - output -= {inner_item} - elif isinstance(inner_item, dict): - output -= {item for item, weight in inner_item.items() if weight} + for plando_setting in self._world.options.plando_items: + if plando_setting.from_pool: + if isinstance(plando_setting.items, dict): + output -= {item for item, weight in plando_setting.items.items() if weight} + else: + # Assume this is some other kind of iterable. + for inner_item in plando_setting.items: + if isinstance(inner_item, str): + output -= {inner_item} + elif isinstance(inner_item, dict): + output -= {item for item, weight in inner_item.items() if weight} # Sort the output for consistency across versions if the implementation changes but the logic does not. return sorted(output) From 53defd310835e064c9ca10d142d13185be717ae3 Mon Sep 17 00:00:00 2001 From: qwint Date: Sat, 10 May 2025 17:51:44 -0500 Subject: [PATCH 0410/1218] MultiServer: More Guardrails for Nolocation Clients (#4470) --- MultiServer.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index bdc6b8c84f1e..9bcf8f6f4caa 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1826,7 +1826,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): ctx.clients[team][slot].append(client) client.version = args['version'] client.tags = args['tags'] - client.no_locations = "TextOnly" in client.tags or "Tracker" in client.tags + client.no_locations = bool(client.tags & _non_game_messages.keys()) # set NoText for old PopTracker clients that predate the tag to save traffic client.no_text = "NoText" in client.tags or ("PopTracker" in client.tags and client.version < (0, 5, 1)) connected_packet = { @@ -1900,7 +1900,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): old_tags = client.tags client.tags = args["tags"] if set(old_tags) != set(client.tags): - client.no_locations = 'TextOnly' in client.tags or 'Tracker' in client.tags + client.no_locations = bool(client.tags & _non_game_messages.keys()) client.no_text = "NoText" in client.tags or ( "PopTracker" in client.tags and client.version < (0, 5, 1) ) @@ -1990,9 +1990,14 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): ctx.save() for slot in concerning_slots: ctx.on_changed_hints(client.team, slot) - + elif cmd == 'StatusUpdate': - update_client_status(ctx, client, args["status"]) + if client.no_locations and args["status"] == ClientStatus.CLIENT_GOAL: + await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "cmd", + "text": "Trackers can't register Goal Complete", + "original_cmd": cmd}]) + else: + update_client_status(ctx, client, args["status"]) elif cmd == 'Say': if "text" not in args or type(args["text"]) is not str or not args["text"].isprintable(): From e809b9328bbbbf7c65599cb8d3bbb726f7f1ab0f Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Sat, 10 May 2025 17:57:16 -0500 Subject: [PATCH 0411/1218] The Messenger: do all empty state validation during portal shuffle (#4971) --- worlds/messenger/__init__.py | 6 ++-- worlds/messenger/portals.py | 6 ++-- worlds/messenger/subclasses.py | 17 ---------- worlds/messenger/transitions.py | 55 +++++++++++++++++---------------- 4 files changed, 34 insertions(+), 50 deletions(-) diff --git a/worlds/messenger/__init__.py b/worlds/messenger/__init__.py index 2382a46c314f..09911fd531dd 100644 --- a/worlds/messenger/__init__.py +++ b/worlds/messenger/__init__.py @@ -16,8 +16,8 @@ from .regions import LEVELS, MEGA_SHARDS, LOCATIONS, REGION_CONNECTIONS from .rules import MessengerHardRules, MessengerOOBRules, MessengerRules from .shop import FIGURINES, PROG_SHOP_ITEMS, SHOP_ITEMS, USEFUL_SHOP_ITEMS, shuffle_shop_prices -from .subclasses import MessengerEntrance, MessengerItem, MessengerRegion, MessengerShopLocation -from .transitions import shuffle_transitions +from .subclasses import MessengerItem, MessengerRegion, MessengerShopLocation +from .transitions import disconnect_entrances, shuffle_transitions components.append( Component("The Messenger", component_type=Type.CLIENT, func=launch_game, game_name="The Messenger", supports_uri=True) @@ -266,6 +266,8 @@ def set_rules(self) -> None: # MessengerOOBRules(self).set_messenger_rules() def connect_entrances(self) -> None: + if self.options.shuffle_transitions: + disconnect_entrances(self) add_closed_portal_reqs(self) # i need portal shuffle to happen after rules exist so i can validate it attempts = 5 diff --git a/worlds/messenger/portals.py b/worlds/messenger/portals.py index 704285896ccf..c04fc696e982 100644 --- a/worlds/messenger/portals.py +++ b/worlds/messenger/portals.py @@ -292,12 +292,10 @@ def disconnect_portals(world: "MessengerWorld") -> None: def validate_portals(world: "MessengerWorld") -> bool: - if world.options.shuffle_transitions: - return True - new_state = CollectionState(world.multiworld) + new_state = CollectionState(world.multiworld, True) new_state.update_reachable_regions(world.player) reachable_locs = 0 - for loc in world.multiworld.get_locations(world.player): + for loc in world.get_locations(): reachable_locs += loc.can_reach(new_state) if reachable_locs > 5: return True diff --git a/worlds/messenger/subclasses.py b/worlds/messenger/subclasses.py index 0138a3f07428..2e438fdbfdc7 100644 --- a/worlds/messenger/subclasses.py +++ b/worlds/messenger/subclasses.py @@ -10,25 +10,8 @@ from . import MessengerWorld -class MessengerEntrance(Entrance): - world: "MessengerWorld | None" = None - - def can_connect_to(self, other: Entrance, dead_end: bool, state: "ERPlacementState") -> bool: - can_connect = super().can_connect_to(other, dead_end, state) - world: MessengerWorld = getattr(self, "world", None) - if not world or world.reachable_locs or not can_connect: - return can_connect - empty_state = CollectionState(world.multiworld, True) - self.connected_region = other.connected_region - empty_state.update_reachable_regions(world.player) - world.reachable_locs = any(loc.can_reach(empty_state) and not loc.is_event for loc in world.get_locations()) - self.connected_region = None - return world.reachable_locs and (not state.coupled or self.name != other.name) - - class MessengerRegion(Region): parent: str | None - entrance_type = MessengerEntrance def __init__(self, name: str, world: "MessengerWorld", parent: str | None = None) -> None: super().__init__(name, world.player, world.multiworld) diff --git a/worlds/messenger/transitions.py b/worlds/messenger/transitions.py index 53cfd836d5ce..c0ae64c5489e 100644 --- a/worlds/messenger/transitions.py +++ b/worlds/messenger/transitions.py @@ -1,6 +1,6 @@ from typing import TYPE_CHECKING -from BaseClasses import Region +from BaseClasses import Entrance, Region from entrance_rando import EntranceType, randomize_entrances from .connections import RANDOMIZED_CONNECTIONS, TRANSITIONS from .options import ShuffleTransitions, TransitionPlando @@ -9,6 +9,33 @@ from . import MessengerWorld +def disconnect_entrances(world: "MessengerWorld") -> None: + def disconnect_entrance() -> None: + child = entrance.connected_region.name + child_region = entrance.connected_region + child_region.entrances.remove(entrance) + entrance.connected_region = None + + er_type = EntranceType.ONE_WAY if child == "Glacial Peak - Left" else \ + EntranceType.TWO_WAY if child in RANDOMIZED_CONNECTIONS else EntranceType.ONE_WAY + if er_type == EntranceType.TWO_WAY: + mock_entrance = entrance.parent_region.create_er_target(entrance.name) + else: + mock_entrance = child_region.create_er_target(child) + + entrance.randomization_type = er_type + mock_entrance.randomization_type = er_type + + + for parent, child in RANDOMIZED_CONNECTIONS.items(): + if child == "Corrupted Future": + entrance = world.get_entrance("Artificer's Portal") + elif child == "Tower of Time - Left": + entrance = world.get_entrance("Artificer's Challenge") + else: + entrance = world.get_entrance(f"{parent} -> {child}") + disconnect_entrance() + def connect_plando(world: "MessengerWorld", plando_connections: TransitionPlando) -> None: def remove_dangling_exit(region: Region) -> None: # find the disconnected exit and remove references to it @@ -59,32 +86,6 @@ def remove_dangling_entrance(region: Region) -> None: def shuffle_transitions(world: "MessengerWorld") -> None: coupled = world.options.shuffle_transitions == ShuffleTransitions.option_coupled - def disconnect_entrance() -> None: - child_region.entrances.remove(entrance) - entrance.connected_region = None - - er_type = EntranceType.ONE_WAY if child == "Glacial Peak - Left" else \ - EntranceType.TWO_WAY if child in RANDOMIZED_CONNECTIONS else EntranceType.ONE_WAY - if er_type == EntranceType.TWO_WAY: - mock_entrance = parent_region.create_er_target(entrance.name) - else: - mock_entrance = child_region.create_er_target(child) - - entrance.randomization_type = er_type - mock_entrance.randomization_type = er_type - - for parent, child in RANDOMIZED_CONNECTIONS.items(): - if child == "Corrupted Future": - entrance = world.get_entrance("Artificer's Portal") - elif child == "Tower of Time - Left": - entrance = world.get_entrance("Artificer's Challenge") - else: - entrance = world.get_entrance(f"{parent} -> {child}") - parent_region = entrance.parent_region - child_region = entrance.connected_region - entrance.world = world - disconnect_entrance() - plando = world.options.plando_connections if plando: connect_plando(world, plando) From c0b3fa9ff74e89b33b668cbfe0201ebc65f1a31c Mon Sep 17 00:00:00 2001 From: lordlou <87331798+lordlou@users.noreply.github.com> Date: Sun, 11 May 2025 02:10:51 -0400 Subject: [PATCH 0412/1218] SMZ3: replace copyright credits music (#4978) --- worlds/smz3/data/zsm.ips | Bin 1470841 -> 1404088 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/worlds/smz3/data/zsm.ips b/worlds/smz3/data/zsm.ips index 87a4f924f1933fcf59493753c034192ef03a328c..54c558185045dd59fcfbeae1d71a2b8ad01303bd 100644 GIT binary patch delta 1027 zcmZ{iTSyd97{|Z4?HMP}?zpLWDLp#|=0ma7BHh!XlG^SBU0!uUcz%W3~y+*v>S z_?f|EPf&aL3&5>gcc(Kq49$vF;$%lw^U`)bn3sw)Mb|-pS?Gzv)yl}#hRE~h>bFT7 zz+4_NS4LQ{He#-3f%f#gZm$Z$MS|;5(7sbaW(9*u@`fiT1hR`2_5fT1zkPiCEdlQ< z*(8h-n=_?^&6_A;%cg9ds>HiRt@yld4OQYD9dSOpBnRNfa~$|92iS%;EfcE8f_7bW#NVuo^11B4vf_QEvj<#bh0gg zVO^}kCF~GM4>7N#F3~QGBy(w`2DG1o+lK;w^U!>6m3tcn?3~5982GWA3Vw-R@7_Uy z(WKYfF)&*63iev)a{<0g(!M;|y+_mYb(kD4oK+O1Prt`TY(%qBe<~g421!f7(yDP; z#e0G28?%k<3y4hu>5J(Et?kvgd1t3UZVD4}06T!t2;e7(ATw=q00%>D;%ESJr~ypF zNl;mxIt?nwql7kMgPBOU6D@(MCEQQeyK3CTmx@l^T-?f4%!v$#PqvigrAx~`sL-1& zCyHdiEYP82Q51l=icw`HtjHMpVf&uh?q8lF|% zEnf#p-%ypWx-8Qe7CJTfTt^;xLb@Fdyg+nVzRX(Rn{Gn`BZ!5VO<^AU9~LsvL)xQ{ zH(Cbr=yC61a!9)Juc*w3O2rYFnkgL-!_pa3>Q~3^W_`LgbY<6d@Onc4ll$3@(7P@4 zw%*p_vZZ;nzt^6cA|qm`jvzy%XZgL0{*;~QuYJSm3)TXH=W-XE4Fq3n;c5=L_g3G7NaA~j@TLcH!*opAIPJ6yHlhyD=;YXjL2dS zAR)%97wmV7x)=!tlJx>Jf~r9119zd;bN!WK?a2e!wj%9;j%|h77|D*%=*RTvuCokK z2ACM_@1J`{_kAXS^ymQu(xYjQ;y3euqA(_Lfc-&Xm1rR1ox*2njfRw z3j8|gxJ<}RG~E`X-45`HrUd}Q>zWqENLe8E1c+rrZlcK;qnQ9MZ88H4H(6qo9FSTH zQn`?uXj%mDm8LrYRyN%!Jad*gIu8uFOL%608EyK7@J!Xt3$G?w@)tdWaI|`P+3Kv- zDu~pFa4KqJ!ay$`-#qDH1##K9QQCyRliDrIiheDYu z`3IWPizd${1;H${h$adGB?xgl_a01SpbZBSy?5asO3B1d$!mVbw7zP3<|mzwkNu|S z-T2L!o--S)a1t{=o5Uu8-o@|#YW-J_e)ZH>JHC47s|#Pv{(4t18qDFp=5s=A!Cj$U zp$%vy`gfE9a3z|x^Vs7`!!im{&{q_gA{U#2eFwiuxcjh4F%Jz_&D{5@kvcOo3C;YZ zNE&0`Xy1)??lkpFbJ*9>>&Onjzr#;JLT{Xtco>@^dgJcGJ=6C^|1N2j{5`HM?)6#r zSuq`npfe7UH#8?9GzX0ci%_Rx!_S4C6t8>=qb$`8dfFIemVEMouO=1>f9yBgqENxlmHN} zcw`a~dR=VLNthKX_D)cHCwf%meSh`D5{Hq>4hhEHb$SG?Kl*phbKQ-45uWe)t``vi zPgzyT`<9Hne*Uk-$jS2;2il=ewR!}D^tPnK zar`Vt!lTQUdK81~Qu)<4<>$lb>bvsw|9yS}MF%dFU06JnRyup#y79-;9-loHLHzY6 zNABvXYAA7)*ydaRbDkTsj!Ue+y48(~c+TzCXKw>-eDa~c5yO8Y);aKlONUkmpukGk zN*gu&E#XP9_Rex6YgAIXQZgjrX*X)Z?wK_61Z#E4^7E7L@l04%@xYvv^iHCwN%Zt2 z@_ZY)f@*$Bm`u2m(4T;BL%=!wxh>9WN!-?Q`0tJ{hvpdW@$`5z*{X)}svSJu`yes( zEYVv1Dcx{#8-AjPFJN`9U4pZR}}_k8P8bxtw(XiC@R)G3C= zM^#-SSd^YwWh&*q)~Q(nja&KpXT%=X|1(`rW0wuPcg<%zx|Y+DD&+A9a)&k2|0 zd>lF-kIv6Rt~uMNFWw=d*MH)UTNM&s>9&8l_Os845#;)}`j!W*ZONC{Rrbvq4iO&p z&;#e$5HYgZ^}q~;mjT)J04NU;K&ja%@Xu}x@t19bR@BQev+H?**3w->b)a{X{QE^m>R($1b&JWc>ObPnT=0Yon{e zRqiTwRoZ88>ej+7JDR58R2!aU#eqJAQmQ3dnkL1$!OSV&&Hpk}JKiufc z4KVS(EQP7J>CMfaYAc(W=(%OGp0`;KB)wVh;ipXaCDW7{zhpKJnHUH+*33jxTGl(6 zvm#eV3VJd8NG2J%$`|xfB4;B9Q!q8r_~{MjB&=z1QwYDbIWmReU0x4%>e5q2!a6Lq zK9($60OPPUVW@&nK5<{|s!bL6i3;}es-ca1%8BaQs>@X;ep~y{rj79@HeRk8eeCi> zLu+~YiFLL2Z(56=SbO>YCSk+(ttG4rq%%>YCOvX>ZgSSuImubxb&;!%WIo|vrjsTQ ze$pJNff0#N@%8V2Ue!>!Exzlrs%jTf?aEJy1&h0viSvtBACFxbquTuNI#M$lx`-D~U`^uNl0$*F@A@+MWfS(OV9& z!%TF7-}M#}-rgdjrq?0%Qtw_7UOLv>4l$_r7?eJSXKh21$2#BsmM!gd;x#b%os5_C6b9_=%aJ;ze>jE{=cib|@Be*&5N6VU2+n*7!FOSnn4d8UsB`RD7NL% zdbZ`kZ#Rl|wH7s>4-6ok?+aRF8!ZtCqB!SuX1QZ^E5`fav z)0eP9{R?^9o~)F`yDDpLbj|!GoH8mW?Vi$qnKoYY6o^xuPi~S>*4q;|QQsM}0E0P~ z_KLs`0M;B>ax&T8dg!kQiR<U2G$gpVycR8Q8nX_(-g5pIJFJEoi&2q z4t!h6PSEj}RVU=TRW+8xmlEGdJf7H=_|L?V#P1S?L`9M+NuOj)s!Dn^X?xOViI${0 zk{(F@Z!K`u7ql&8=<@JC0om^byMio`B|4tt1Eyt&{MAy_xB3(&i>0X=I(oq^#uWhOk zv>O)8gLDpkz6R>Qth$`KEKuc1+Qn*8N6OWL9lTY!Fy!jL# zH-h(XUN>3qx@FRI-F#Uk&Q)G*nl)`Igh_jC~Tj|>>wKz$b6kt4kjFCCk*!-iom z4jT;@ot|#Pmk5!`V;e)ZxJQB^uxjKJO2S$%4J$<}?7Vz(FEr~ZU~U$fVAn@6yN-^ooZ1WVwrYnRue8es zlox2LC;7?Im0cH9O(CuIGvSm*!U6-G=?!kwb-@Bwt{;OXvu7pk7BZ-rVFDETb{v!D$>Af(;`Rl{K%R;BHFwzyn!XS?m7ofr0|f;>C;0N=u513X2L0e^Cb4 zqTk$i|NZ4~Sy;#cqqz77P*ez{!m`Dp+{zMK!eU5?6y(4$t zA~M@ptFP5#`fJ*L?LV|(?Wp!K{qOaZHc$Jl(lXb;)G_Os6ee!&Z|5wYvtrKubM~YT zYs*t}Qllw<(EL(Yr#qu#bVl7G9j=q=Qg!$1H|VSNZ5d(po9c7wH#PB^+x12IFcYu6 znqtu33qOoGs=1~)r`g78U(>#!eV6%&aWR*eLFQv^o7SbhpzYSaqy4k?sP;*1owio3 zRsTu-TXo~yx91+8``5V*b6-lmH~sbW=hNR!|5e8NjHfd8)6Zr6R~j>W@9dV0Pcn|A z{4K+s@nyz9#(2gz8TYC0QQxV)Gu@DWd9E-QQzxk9>J;@{^;2^`Nb{z#rL!NOePwq1 zoLkbe(|ot2-15)VbE*4Mnp4=6|47-I5>cI}52|*ko>gsERx7iW2IU;(nK{{Mq%uVR zi+**EN%I!{IQ=~RE80kB(0V$P?xDA)JWKzF@@>^6)u}m8r2fY(3)1Gy{kOSI%;Sue z>C=3Z-mUve*QEQiZkm~|dxX_3)BReLr2pS~E{m;tqh^My@)eftFN6z z)|19fA!Pj6SQkQBA0sY-t=@kVFE7L*W1CS8%r?Zy;#Kb@u-bUNvqq%EljI> z&hR{^G;C_%Qs-Z5K!*CCNi5RUZBMPIj*|X%o{UqSbtb9X&s1fi(?Co>E$K;rb&;y}Gf8S^ zTbk;WDd`kqISlH6NYX0SaSoLJkWNEwQZ;0g&WkCLeljK_<}zdSpAjwp6EQDF{8^{n zS@S%XvIP2gI9r%V!y7fiF)@v^! z9XQ|}hH`XmKT6wUn1R)qGk8t|w04V)l=Yg9lgLm`X{CLYr z#4V!hcGK0n>GIul-fou8+)b-?gUd=$OG4(S9JOTe-^8h~^+gGKF>ULM;KEGawHBm0 zm|hNuIyk2qko;iURzT8&X){oyL1yg?T0Da?XOJp}5XVUKnwK<-RxDOsYen%NOG6(a zHvZ%IA2R>uaK>Pum1fuJqu!%+0F`c5T z?`M<#5JPH+U68ZPpv5z2?N5-X7DN`WjiEd-9PVc`i(&{W5pyc2L-g-h9eWYGmrVkb zSiowrn!Pjn_p&kld)b)&A5fjBcrW{?s2GUQBtYePF;tWpLl)2vM78Qh`2BzP!%R1b z>Y({xpx7BReLzdMUfYGFJ7I!I_oanU$~*8nbr(m|BAMO^l(avmhLG|dvijN%M81{+ zBKx6I#U5!n#9XP34k6kOfZUasckLCF_%aFUJpiOT;xl2+$G<45-UZdo-Htf+C*eMo zs;mDKr=sf`AntRihPvm{&~rbFU8%s5{)x+$);0X;Ph4t3-JhiB#TXV>i|08N@S#Y& z$|*rkTIGyK&YROSu`3HyOBq&cAmW#~R2n@mHvDJQH1zz>N~+@PUbe-*Y=ic4squ9$zWn0LG^4Z&z066hb&#{p z8dQEoRzS zQSx?aHSCzu4RtVq3@^hJOMMwOCDm_;w8cN6<;7@qusj-UqTFjY$=ytwk=uIh9hA1q zFaxV+(ApWaIEG;UrNd&o3#Gkdn1R(ZXzdJI97Ey=LX1vNgT79C%@9I5SjE35LD}sh z3A*t%_U7n06Fg_aBn;1fag6q}Gl6m@K#GA8NH+pwdRq0h=TO>A^P%OCwV|{Z#a4ok z-Nvq+iOiKTHDc)8&%)Lc;7k=;Z=%d_XC%c~xt|q7B}C*Hyiwn6o7Y}@1F@Um5O=KX z8?0F9jhM<@xJ4TK4GFQwU}ucW;!ePvr3dM!3d#clCT8#TnuTaxz|#Oc7#mTa{n zE@#QseTZ9Ns!O`|9?FD01tfn+CH$Ojj=~Ho#psi|C^-r@~(arhUpyX2|Z4rCst(XIW|A~Gi zg&NXff!TrRUE=cbx(J#9P_H6x)=i9^KX7+^FG9ceykpZg@PNA3SJaKvcKbS1yQWCbd zerjmrX2r%>`mR{~m{=0F<%r1q_*3zha54>^&@id`RNEW?SSnJ)@To#G)Ho4~ z)PywfDTq05i3Wn(B*X^$rYv~mPuSw<-^5nmoQ+$ul?A6O13ikWJm{YF2jS5chGjp> zf`Ob5k6C{~NuL@3QlI`L!=)JD=}Ea67OWIlu|d`Z&7Tp!fx!G3DHQ`!sf9m?%1st{ z627s+XMcFs$$;)Z029M-?JcAQJCaS+U_-JgF9y{BXD4jky#(r-ov`=@&Wzzi)7m6p zCz{G*FllWJWyYXbF3yy+79McpKuknwYd;cUQVg+aYm*==i?4pGYAZ}>8M7GtRt-BS z8I$=#N_`_0U$qtLk55Cps>HhDH;YxpZ(a-#p4)cPJEhe-=pE8>oA{1EW`F|^)kvh4 zqaA5GqyqJc}8yfON z4Hi*@`p3#FF%9aN2Gz|PEIV1z3Uy3{>V}G~d-hcA0rTUbZdAQXx>m&HyOu0QJF1Y_ ztIQG$#HBcC^&Zn6j;<1yt*Za3f@Np}Y`l`=ApnUzIXhwPUhWogS=B*kOfqPXi%=1R zGJvovLZ?o_{ELf6Yfr(;21Kb_O=@rr_>%9S)DDyS6iSOueL~=~0ZNGYSGZ3w#Js?L zLQu01H-gvC5-IfwBIFQ2cqtED%qe-H`4hsP82$E>S@t-QZWl{o_E}L#+hRJ=?3ny) zHu@^4W<&;xe}Q8ON-78Fk;ULGK#z0CAsy!+qEjs4oc#hoY*sYPV)aR{OtBbBc!7uN z@t8U+2AL`56PzOD4CslEf;PuOfD)7`rjhbncqNU}0LG))*I5eG5id}mBq03Ti=V`y z#OUNFI6}{I<*1&#E}F9NJFzeoQ>TbQItFo&!RwO%VpUj79{=AWB|TP+D35zYdHCr5 z0>@$=Byj93I|eY`gp1HY0A%Bx=`lup435;tK0ptjBQopxSp)ZOTLzzTnowMLj$1yg z!DAmk&woa^x?M+HZx08E^G(EXkU0MeUgNI%^6k$)gRfiXvx#rtu78&#;G@%dHQ_z4 zA%@=O-`j}s`^0Z0Zuv`Z!(0Dhk~nW9M%bkDmGJSV2~lo2yoaxWqYOOJ1c!kVpTYQB zhA>y0E0KTK%QK}Id<&j4)a}VK{`(N-nf29Y1fOL5GZ4~;;ynMWrU~!9Vf(-wu;CTl zbp&jy+0;F4eQN$lz4bo|hT=@hb8!jVHoIRRu^VS^`^J5IL|}~yktT>~WBj(0z~eeD z5TE^(I6p0(_XyuRG}8wom*3O!uM)u*Lf?n_J{8dBe4d;xA>Tjv`iwQ#Vu!NRDeonRbF1+diaRCe%qEN2|cxE zKJe2?7{IRRD)ky-2~FE${vLefW340oN|L;5b0MOLqP$ z;X35n<9h3S7I9ui4381#w-LkR#QB%;o;hymFqMHT& z9_Y%2#J79u-<8FNGaZIAgBaT5!D?VU--?Z=^rb!Gc*+Q~2b+>Io&0`pDV|As6ho}cbC;Ml!G~+%*2-UG4&feZ2k@j$K2gt3*4 zfKAXJXT`C78Fw9mR@7{g4G+a!-B0K})Ahx1GO6)LGxk1iHx+H+GHi;M)#2 zNlV>Q_-;N@2wu?h{eX%h@2qF1GH#pc8pu1}S+{Qe)a={N=M%BU&uAGIwTvA8@=y~x z?3TvHYo@GN^nd7_oAf|$tRw2*ol*Ce_z{*mzZAM~8FV495POex-`suRNr(72Ft)N_ z=q-M>_<<1kZ;9QTPeg|E;Nu`LVVcC;q*`>7GnqfQ$(hXaS>Pss7J{2dxy^Vzz^Ykr z7>wIYpd^4;JqE!HLjW^pp)5#m#tFkdlY}D#c7m6$hkSiC z#mCu*$`b`ciZAR0dx09keogU`^i9tB#4+Ukwg{2FYwi6i{ zRDTU{fxZXo0`k4LPuW=_J>pPaeVgjtPPnqJzD4!g2-m{O+ZJ4XTXBP=_?`sq0DWM+ z>W1}FFg`&%*&wzbjJFe)>@%knrecQ&rr?ZBJw7z2{@r%MH3w`K6VReBOW`bwIPKdB zcHTLHpKG|+bIZ`ZRnLLgOb8gB0JjC%2?8puvA%LU7z;fqn!g=Bj@pRJ3#S~=4u{x| z<^^{z9Ci}1R=d%^7V=%DJI0*E7srUZ7yfIZi!x=7oh86a-AK$+vh_n05T=1rXJlnJ zk~7SWoQJ4n3N~Kj?}1}U_e13on7Cjk%v`bg#|Wr0tb`=to=%bQ7kHadELwF zK3Xr{p7l>ui}$X_xyQeH{Oc#hJ8shlTg3aG|62Kict7!iqUq*)_1odS;k~K*-g$4y zp(TeNK2&(be(d}Ez_ABDtorbOefau^$3E=%u;xt7nc071{#M)}{CNFBKv5L^r+d8n z=XcYUlD-XneSP*T+rR!%UJ%g5)S=WN^AH?7UBbf34?7_&B5rbEYsd;i|Z=62brzM6M@Mmy>4$dNEZCf`|fS~M=ZA&X<@!|=j*>ETi&g8w|dY}ffd=h{gC-Q2*i4FJivY~rp zGj?Vw*1!;ErCAJ-zF&*rw-y9O)puufo_GqM=nU%Lz9nzPcgcla~`X>&NN&dW(E-rsC; zFFKxYE>btMT^D77bOJkS*Ld69B&MUAxypjU9bu2UC9v>LM06VH7BX*u#DW=A^Xt$Bzrv0lt;=Z3;}j*WT*%2Gm}J zb&R#H_JrHkn+8J;tM3G_PHk&*l7haZVzLl#&GS!;u8bR7=2-pPiK5fqIf9e%(;>=A z>Rf{hC)B;)6}lYlzLnO{*WP2T9~kjffzZb?rx4aggXWTsOO%GC=uq}qwG%rsj++_G z?6k-!qEt_hIs3Z{qV3YK%wlB0tRauv8V zeu0**aJB!ss2^`xMmim%4Py^km;8myTS@^ngK5V;-lp7!`Os{UHZue}WCG z$AUc$1+lzBmv`u#>tZw{!S4Nv?lDD|Z%gmd;YA%>Mtw1y{bvpUL6^)YCI@J@DWLm4koSIIBTz;}g;mSXo zKbSFJ$~zgQVyrEcPPKls*Q57VJ&@~&o^b#7=bd|KX94ns!U!L8a7^-<9Ai7@3TJ86 z97i#ZanCd%TsW(3MG8i$y{PSUE>>8h!>n9qc6>eU^1CzIcek#m&lEiI5ntqtV1vtP z9oQHe|A10^sfcTkDi{nD1q`i;bVq6H_^%_a5~kyh02ws5s*65K(%d0KPM*>#4O+zt zr;pP|u15#u&M+163TSS?b;%q+h|~w2N=0@^rPDA@LBJ+9_}DR(Gn?c>g1o=j`O9vJ z6_|n6HNpH-#H#6ExFmwdXc0)4Bakt!()E!}C&gK!%G~S;S5zI&@ftC|OVAX_ux|ZX zC-N_pdxY_T<4A}npWYn_J5VlpPl$Z5xHSm7reAgzI$ebkenK4?Fgf-Y3c*5pg2kO? z!wPL!K}B0HN*v@e<1p{Ab|6DIU_!0;PVvXr3HUL`v?jbF`MnDbWGm>feBZB^x9hs@Zu!f6qwvxG z%4P@iv}aZ79m+ySiJVKv+#SJI%@p@|BtJ*$U;kaC;|DvC*jSsi#tD-SCm~-=eUdjT#qXISyP_!W=6K2OV-9@z7_7rx!V7T@j7Xk7qkB7L&P@som<(JRFi8 z#RRXT+l%QH%l&4D-pX_azWk_ zjNIog{$j!7jx&@VkwgyjNmhAKAryr6JNlh&AtIY(S|{BqDm`qpIxxTXVI75rTc;^r zd6-cTv|6J~Se-rZYsZJ?5L>L*uO7FT_kJDsq_TXd^-@NcUP^UStr?eAWC%k>jiYM~ zVZk-!eJ=rxH2W@Xop!}!pLS7 zT3SP#*-M7AU5-f5BI{l*cYs&-le(O_!A}N;-32KFCm(KI+9ja|eFK;yn&qA(Wmu`B z_@pu?Ovt>gv^q3BFWsnh;Bq}u@JQzH(^nX;4_CIzr&YR)af8MoXoEV6b%(T$Xs2&^ zn52A;@eVqI^El%m)M4$K0z%drmqCxy?vjocx)`IhLF_$;Ie;lvb0)vtP_%d&AD#ZX zCAX*WX#10){MMf0air;9;df*Vu7D}#=4g$45)$(+{i zXo-ijvO(m)i@ezmjYn|!IMOoRV;XdCwP~$!n=@URLY~kiL>2Petw1>~OKtOhdz*RvL8`Q})$+Xg))8ZrZ_g zz_9~b=x;3{JC#`jD_Fl>>gKJ}(Rq9ASJJzFn-^4a4)S6?c(|T)_zLAtDm0E9SmE_^ z*68?vLnDMH7{wLZ{@pFOMpc%0(ZSIAn$tlDnnKC6R38dbE%$kuy`|$+sKsx1bAKHEO(@~e}(AH3v{2Neb*U(m%mgifIZQ-_?6B4ou^1&tH-l}8un^#!rh z4tWmWEmzQjU0y~e&FkBfVlOc!yBB*Wl&u;5XrT}`@^<=CjZQtUh<1<@7HL#(y3(40 zf|y)K^5Ot@;JV}ihi)v)=*Mu(VN?p*02YQB$cJm%=!{ScD>=$!$<~qoXvI8*@<~l# zd23w1Oo^#Igu^5R6mD6U(vj}OiX%Lub@){lnQ{fmw=CMzvV6fEql`o2Lzk7p zBEfL+rB>rO3Kb}#L#_ECE@JLpKGb?|yH-A>j%pon5Ft2Cm@haq-8w`mHKapxk|SiD zMdJ=?EH|i+3Ute_i9@Mb0xowbyebmU;v@EbMPFZb&Qq1zt(U`85lU@q+2Fq$Gq)Q% z9exZWb4cZN`>Ri}es{FpBy|WpA2J0b%N<=9rYB{S`Ht=kzk(8obo+$RWl}{nA-hr- zH-yOQF-N3bOHffF+wNN)R0X*lwSzaxgiv-*#1Xepq6so2

TS6{ARUI;eo3BGM;K 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 Date: Sun, 11 May 2025 03:41:35 -0700 Subject: [PATCH 0413/1218] Docs: clarify that ModuleUpdate.py is a prerequisite for running tests (#4970) * Update tests.md Spelled out that tests will not run without running UpdateModule.py first and including a link to the instructions on how to do that. * Applied black-silver's feedback and also I ran into tests that don't run correctly unless you also have run Webhost.py once. I have included that in the documentation as well. * More black-silver feedback. --- docs/tests.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/tests.md b/docs/tests.md index a9a1962685b9..13d62b0132ef 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -119,8 +119,12 @@ variable to keep all the benefits of the test framework while not running the ma #### Using Pycharm In PyCharm, running all tests can be done by right-clicking the root test directory and selecting Run 'Archipelago Unittests'. -Unless you configured PyCharm to use pytest as a test runner, you may get import failures. To solve this, edit the run configuration, -and set the working directory to the Archipelago directory which contains all the project files. +If you have never previously run ModuleUpdate.py, then you will need to do this once before the tests will run. +You can run ModuleUpdate.py by right-clicking ModuleUpdate.py and selecting `Run 'ModuleUpdate'`. +After running ModuleUpdate.py you may still get a `ModuleNotFoundError: No module named 'flask'` for the webhost tests. +If this happens, run WebHost.py by right-clicking it and selecting `Run 'WebHost'`. Make sure to press enter when prompted. +Unless you configured PyCharm to use pytest as a test runner, you may get import failures. To solve this, +edit the run configuration, and set the working directory to the Archipelago directory which contains all the project files. If you only want to run your world's defined tests, repeat the steps for the test directory within your world. Your working directory should be the directory of your world in the worlds directory and the script should be the From 8340371f9c27d59f674369f079844736d75ade91 Mon Sep 17 00:00:00 2001 From: Justus Lind Date: Tue, 13 May 2025 08:47:19 +1000 Subject: [PATCH 0414/1218] Muse Dash: Update to Otaku Pack Vol 20 (#4924) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/musedash/MuseDashCollection.py | 2 ++ worlds/musedash/MuseDashData.py | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/worlds/musedash/MuseDashCollection.py b/worlds/musedash/MuseDashCollection.py index 96a506f2fa2a..2a9f56750e8a 100644 --- a/worlds/musedash/MuseDashCollection.py +++ b/worlds/musedash/MuseDashCollection.py @@ -36,6 +36,8 @@ class MuseDashCollections: "Yume Ou Mono Yo Secret", "Echo over you... Secret", "Tsukuyomi Ni Naru Replaced", + "Heart Message feat. Aoi Tokimori Secret", + "Meow Rock feat. Chun Ge, Yuan Shen", ] song_items = SONG_DATA diff --git a/worlds/musedash/MuseDashData.py b/worlds/musedash/MuseDashData.py index 71d69eecb58d..f2bcf1220fa1 100644 --- a/worlds/musedash/MuseDashData.py +++ b/worlds/musedash/MuseDashData.py @@ -627,10 +627,18 @@ "Sharp Bubbles": SongData(2900751, "83-3", "Cosmic Radio 2024", True, 7, 9, 11), "Replay": SongData(2900752, "83-4", "Cosmic Radio 2024", True, 5, 7, 9), "Cosmic Dusty Girl": SongData(2900753, "83-5", "Cosmic Radio 2024", True, 5, 7, 9), - "Meow Rock feat. Chun Ge, Yuan Shen": SongData(2900754, "84-0", "Muse Dash Legend", True, None, None, None), - "Even if you make an old radio song with AI": SongData(2900755, "84-1", "Muse Dash Legend", False, 3, 6, 8), - "Unusual Sketchbook": SongData(2900756, "84-2", "Muse Dash Legend", True, 6, 8, 11), - "TransientTears": SongData(2900757, "84-3", "Muse Dash Legend", True, 6, 8, 11), - "SHOOTING*STAR": SongData(2900758, "84-4", "Muse Dash Legend", False, 5, 7, 9), - "But the Blue Bird is Already Dead": SongData(2900759, "84-5", "Muse Dash Legend", False, 6, 8, 10), + "Meow Rock feat. Chun Ge, Yuan Shen": SongData(2900754, "84-0", "Muse Dash・Legend", True, None, None, None), + "Even if you make an old radio song with AI": SongData(2900755, "84-1", "Muse Dash・Legend", False, 3, 6, 8), + "Unusual Sketchbook": SongData(2900756, "84-2", "Muse Dash・Legend", True, 6, 8, 11), + "TransientTears": SongData(2900757, "84-3", "Muse Dash・Legend", True, 6, 8, 11), + "SHOOTING*STAR": SongData(2900758, "84-4", "Muse Dash・Legend", False, 5, 7, 9), + "But the Blue Bird is Already Dead": SongData(2900759, "84-5", "Muse Dash・Legend", False, 6, 8, 10), + "Heart Message feat. Aoi Tokimori Secret": SongData(2900760, "0-57", "Default Music", True, None, 7, 10), + "Heart Message feat. Aoi Tokimori": SongData(2900761, "0-58", "Default Music", True, 1, 3, 6), + "Aventyr": SongData(2900762, "85-0", "Happy Otaku Pack Vol.20", True, 4, 7, 10), + "Raintain": SongData(2900763, "85-1", "Happy Otaku Pack Vol.20", False, 6, 8, 10), + "Piercing the Clouds and Waves": SongData(2900764, "85-2", "Happy Otaku Pack Vol.20", True, 3, 6, 8), + "Save Yourself": SongData(2900765, "85-3", "Happy Otaku Pack Vol.20", True, 5, 7, 10), + "Menace": SongData(2900766, "85-4", "Happy Otaku Pack Vol.20", True, 7, 9, 11), + "Dangling": SongData(2900767, "85-5", "Happy Otaku Pack Vol.20", True, 6, 8, 10), } From feaed7ea00bcae83bebf0844ca4ee8e1bd1f83a6 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Tue, 13 May 2025 07:49:43 +0000 Subject: [PATCH 0415/1218] Docs: tests: add naming / file naming conventions (#4982) * Docs: tests: add naming / file naming conventions Deprecates putting stuff into `__init__.py`. This may be relevant for test discovery in the future. * Docs: tests: fix class naming * Docs: tests: update examples * Punctuation is hard Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Revert part of one suggestion The first set of () make the sentence make less sense. * Docs: tests: clarify that __init__.py may be empty * Make sentence nicer to read I simply kept the original wording, but I agree that it reads somewhat odd Co-authored-by: Ixrec --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: Ixrec --- docs/tests.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/tests.md b/docs/tests.md index 13d62b0132ef..78cedbc514d5 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -11,8 +11,13 @@ found in the [general test directory](/test/general). ## Defining World Tests In order to run tests from your world, you will need to create a `test` package within your world package. This can be -done by creating a `test` directory with a file named `__init__.py` inside it inside your world. By convention, a base -for your world tests can be created in this file that you can then import into other modules. +done by creating a `test` directory inside your world with an (empty) `__init__.py` inside it. By convention, a base +for your world tests can be created in `bases.py` or any file that does not start with `test`, that you can then import +into other modules. All tests should be defined in files named `test_*.py` (all lower case) and be member functions +(named `test_*`) of classes (named `Test*` or `*Test`) that inherit from `unittest.TestCase` or a test base. + +Defining anything inside `test/__init__.py` is deprecated. Defining TestBase there was previously the norm; however, +it complicates test discovery because some worlds also put actual tests into `__init__.py`. ### WorldTestBase @@ -21,7 +26,7 @@ interactions in the world interact as expected, you will want to use the [WorldT comes with the basics for test setup as well as a few preloaded tests that most worlds might want to check on varying options combinations. -Example `/worlds//test/__init__.py`: +Example `/worlds//test/bases.py`: ```python from test.bases import WorldTestBase @@ -49,7 +54,7 @@ with `test_`. Example `/worlds//test/test_chest_access.py`: ```python -from . import MyGameTestBase +from .bases import MyGameTestBase class TestChestAccess(MyGameTestBase): From 7d5693e0fb6c09d185d02850a3c69d3a2508ea6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Tue, 13 May 2025 03:58:03 -0400 Subject: [PATCH 0416/1218] Stardew Valley: Move BaseTest out of `__init__.py` to comply with future conventions (#4991) * move everything out of init; fix from imports and some typing errors * why is there a change in multiserver * fix some relative shits --- worlds/stardew_valley/test/TestBackpack.py | 2 +- worlds/stardew_valley/test/TestBooksanity.py | 2 +- worlds/stardew_valley/test/TestBundles.py | 3 +- worlds/stardew_valley/test/TestCrops.py | 2 +- .../stardew_valley/test/TestDynamicGoals.py | 2 +- worlds/stardew_valley/test/TestFarmType.py | 4 +- worlds/stardew_valley/test/TestFill.py | 2 +- worlds/stardew_valley/test/TestFishsanity.py | 2 +- .../stardew_valley/test/TestFriendsanity.py | 2 +- worlds/stardew_valley/test/TestGeneration.py | 2 +- worlds/stardew_valley/test/TestItemLink.py | 2 +- worlds/stardew_valley/test/TestItems.py | 2 +- worlds/stardew_valley/test/TestLogic.py | 2 +- .../test/TestMultiplePlayers.py | 2 +- .../test/TestNumberLocations.py | 2 +- worlds/stardew_valley/test/TestOptionFlags.py | 2 +- worlds/stardew_valley/test/TestOptions.py | 2 +- .../stardew_valley/test/TestOptionsPairs.py | 2 +- .../stardew_valley/test/TestRandomWorlds.py | 2 +- worlds/stardew_valley/test/TestRegions.py | 2 +- .../stardew_valley/test/TestStartInventory.py | 2 +- worlds/stardew_valley/test/TestTraps.py | 3 +- .../stardew_valley/test/TestWalnutsanity.py | 2 +- worlds/stardew_valley/test/__init__.py | 308 ------------------ worlds/stardew_valley/test/bases.py | 306 +++++++++++++++++ .../test/content/TestGingerIsland.py | 2 +- .../test/content/mods/TestSVE.py | 2 +- .../stardew_valley/test/long/TestModsLong.py | 2 +- .../test/long/TestOptionsLong.py | 2 +- .../test/long/TestPreRolledRandomness.py | 2 +- .../test/mods/TestBiggerBackpack.py | 2 +- worlds/stardew_valley/test/mods/TestMods.py | 2 +- .../stardew_valley/test/mods/TestModsFill.py | 2 +- worlds/stardew_valley/test/mods/TestSVE.py | 2 +- .../test/options/TestPresets.py | 2 +- .../test/performance/TestPerformance.py | 2 +- .../stardew_valley/test/rules/TestArcades.py | 2 +- worlds/stardew_valley/test/rules/TestBooks.py | 2 +- .../test/rules/TestBuildings.py | 2 +- .../stardew_valley/test/rules/TestBundles.py | 2 +- .../test/rules/TestCookingRecipes.py | 2 +- .../test/rules/TestCraftingRecipes.py | 2 +- .../test/rules/TestDonations.py | 2 +- .../stardew_valley/test/rules/TestFishing.py | 2 +- .../test/rules/TestFriendship.py | 2 +- .../stardew_valley/test/rules/TestMuseum.py | 2 +- .../stardew_valley/test/rules/TestShipping.py | 2 +- .../stardew_valley/test/rules/TestSkills.py | 2 +- .../test/rules/TestStateRules.py | 2 +- worlds/stardew_valley/test/rules/TestTools.py | 2 +- .../stardew_valley/test/rules/TestWeapons.py | 2 +- .../test/script/benchmark_locations.py | 9 +- .../test/stability/StabilityOutputScript.py | 2 +- .../test/stability/TestStability.py | 2 +- .../test/stability/TestUniversalTracker.py | 6 +- 55 files changed, 367 insertions(+), 368 deletions(-) create mode 100644 worlds/stardew_valley/test/bases.py diff --git a/worlds/stardew_valley/test/TestBackpack.py b/worlds/stardew_valley/test/TestBackpack.py index 378c90e40a7f..bccafd15e55f 100644 --- a/worlds/stardew_valley/test/TestBackpack.py +++ b/worlds/stardew_valley/test/TestBackpack.py @@ -1,4 +1,4 @@ -from . import SVTestBase +from .bases import SVTestBase from .. import options diff --git a/worlds/stardew_valley/test/TestBooksanity.py b/worlds/stardew_valley/test/TestBooksanity.py index c25924aa3b62..f1678de0db16 100644 --- a/worlds/stardew_valley/test/TestBooksanity.py +++ b/worlds/stardew_valley/test/TestBooksanity.py @@ -1,4 +1,4 @@ -from . import SVTestBase +from .bases import SVTestBase from ..options import ExcludeGingerIsland, Booksanity, Shipsanity from ..strings.book_names import Book, LostBook diff --git a/worlds/stardew_valley/test/TestBundles.py b/worlds/stardew_valley/test/TestBundles.py index 091f39b2568e..5b70158f5f54 100644 --- a/worlds/stardew_valley/test/TestBundles.py +++ b/worlds/stardew_valley/test/TestBundles.py @@ -1,6 +1,6 @@ import unittest -from . import SVTestBase +from .bases import SVTestBase from .. import BundleRandomization from ..data.bundle_data import all_bundle_items_except_money, quality_crops_items_thematic, quality_foraging_items, quality_fish_items from ..options import BundlePlando @@ -87,4 +87,3 @@ def test_all_plando_bundles_are_there(self): for bundle_name in self.fish_bundle_names: with self.subTest(f"{bundle_name}"): self.assertIn(bundle_name, location_names) - diff --git a/worlds/stardew_valley/test/TestCrops.py b/worlds/stardew_valley/test/TestCrops.py index 53048259ab0e..bf8f4f719e8a 100644 --- a/worlds/stardew_valley/test/TestCrops.py +++ b/worlds/stardew_valley/test/TestCrops.py @@ -1,4 +1,4 @@ -from . import SVTestBase +from .bases import SVTestBase from .. import options from ..strings.ap_names.transport_names import Transportation from ..strings.building_names import Building diff --git a/worlds/stardew_valley/test/TestDynamicGoals.py b/worlds/stardew_valley/test/TestDynamicGoals.py index b0e6d6c62655..23f453e9f073 100644 --- a/worlds/stardew_valley/test/TestDynamicGoals.py +++ b/worlds/stardew_valley/test/TestDynamicGoals.py @@ -1,7 +1,7 @@ from typing import List, Tuple -from . import SVTestBase from .assertion import WorldAssertMixin +from .bases import SVTestBase from .. import options, StardewItem from ..strings.ap_names.ap_weapon_names import APWeapon from ..strings.ap_names.transport_names import Transportation diff --git a/worlds/stardew_valley/test/TestFarmType.py b/worlds/stardew_valley/test/TestFarmType.py index 1bb4404ae61f..2c4fe4ec36d2 100644 --- a/worlds/stardew_valley/test/TestFarmType.py +++ b/worlds/stardew_valley/test/TestFarmType.py @@ -1,7 +1,7 @@ from collections import Counter -from . import SVTestBase from .assertion import WorldAssertMixin +from .bases import SVTestBase from .. import options @@ -13,7 +13,7 @@ class TestStartInventoryStandardFarm(WorldAssertMixin, SVTestBase): def test_start_inventory_progressive_coops(self): start_items = Counter((i.name for i in self.multiworld.precollected_items[self.player])) items = Counter((i.name for i in self.multiworld.itempool)) - + self.assertIn("Progressive Coop", items) self.assertEqual(items["Progressive Coop"], 3) self.assertNotIn("Progressive Coop", start_items) diff --git a/worlds/stardew_valley/test/TestFill.py b/worlds/stardew_valley/test/TestFill.py index f8565f4f218d..2205c49cdfbb 100644 --- a/worlds/stardew_valley/test/TestFill.py +++ b/worlds/stardew_valley/test/TestFill.py @@ -1,5 +1,5 @@ -from . import SVTestBase from .assertion import WorldAssertMixin +from .bases import SVTestBase from .options.presets import minimal_locations_maximal_items from .. import options from ..mods.mod_data import ModNames diff --git a/worlds/stardew_valley/test/TestFishsanity.py b/worlds/stardew_valley/test/TestFishsanity.py index c5d87c0f8dd7..953255c4d077 100644 --- a/worlds/stardew_valley/test/TestFishsanity.py +++ b/worlds/stardew_valley/test/TestFishsanity.py @@ -1,8 +1,8 @@ import unittest from typing import ClassVar, Set -from . import SVTestBase from .assertion import WorldAssertMixin +from .bases import SVTestBase from ..content.feature import fishsanity from ..mods.mod_data import ModNames from ..options import Fishsanity, ExcludeGingerIsland, Mods, SpecialOrderLocations, Goal, QuestLocations diff --git a/worlds/stardew_valley/test/TestFriendsanity.py b/worlds/stardew_valley/test/TestFriendsanity.py index 842c0edd0980..a346df7d2aec 100644 --- a/worlds/stardew_valley/test/TestFriendsanity.py +++ b/worlds/stardew_valley/test/TestFriendsanity.py @@ -2,7 +2,7 @@ from collections import Counter from typing import ClassVar, Set -from . import SVTestBase +from .bases import SVTestBase from ..content.feature import friendsanity from ..options import Friendsanity, FriendsanityHeartSize diff --git a/worlds/stardew_valley/test/TestGeneration.py b/worlds/stardew_valley/test/TestGeneration.py index 6d0846f8c1d5..1e843ea69094 100644 --- a/worlds/stardew_valley/test/TestGeneration.py +++ b/worlds/stardew_valley/test/TestGeneration.py @@ -1,7 +1,7 @@ from typing import List from BaseClasses import ItemClassification, Item -from . import SVTestBase +from .bases import SVTestBase from .. import location_table, options, items from ..items import Group, ItemData, item_data from ..locations import LocationTags diff --git a/worlds/stardew_valley/test/TestItemLink.py b/worlds/stardew_valley/test/TestItemLink.py index f1c8346142ad..c3029b60704d 100644 --- a/worlds/stardew_valley/test/TestItemLink.py +++ b/worlds/stardew_valley/test/TestItemLink.py @@ -1,4 +1,4 @@ -from . import SVTestBase +from .bases import SVTestBase from .. import options, item_table, Group max_iterations = 2000 diff --git a/worlds/stardew_valley/test/TestItems.py b/worlds/stardew_valley/test/TestItems.py index 1d6f9689553b..d4fa9e832a8e 100644 --- a/worlds/stardew_valley/test/TestItems.py +++ b/worlds/stardew_valley/test/TestItems.py @@ -1,5 +1,5 @@ from BaseClasses import MultiWorld, get_seed, ItemClassification -from . import setup_solo_multiworld, SVTestCase, solo_multiworld +from .bases import SVTestCase, solo_multiworld, setup_solo_multiworld from .options.presets import allsanity_no_mods_6_x_x, get_minsanity_options from .. import StardewValleyWorld from ..items import Group, item_table diff --git a/worlds/stardew_valley/test/TestLogic.py b/worlds/stardew_valley/test/TestLogic.py index 7a6b81ea7402..047e0226c6e0 100644 --- a/worlds/stardew_valley/test/TestLogic.py +++ b/worlds/stardew_valley/test/TestLogic.py @@ -3,8 +3,8 @@ from unittest import TestCase, SkipTest from BaseClasses import MultiWorld -from . import setup_solo_multiworld from .assertion import RuleAssertMixin +from .bases import setup_solo_multiworld from .options.presets import allsanity_mods_6_x_x, minimal_locations_maximal_items from .. import StardewValleyWorld from ..data.bundle_data import all_bundle_items_except_money diff --git a/worlds/stardew_valley/test/TestMultiplePlayers.py b/worlds/stardew_valley/test/TestMultiplePlayers.py index d8db616f66f4..3b5710559548 100644 --- a/worlds/stardew_valley/test/TestMultiplePlayers.py +++ b/worlds/stardew_valley/test/TestMultiplePlayers.py @@ -1,4 +1,4 @@ -from . import SVTestCase, setup_multiworld +from .bases import SVTestCase, setup_multiworld from .. import True_ from ..options import FestivalLocations, StartingMoney from ..strings.festival_check_names import FestivalCheck diff --git a/worlds/stardew_valley/test/TestNumberLocations.py b/worlds/stardew_valley/test/TestNumberLocations.py index 2ed528086ab8..dd57a5e39b7b 100644 --- a/worlds/stardew_valley/test/TestNumberLocations.py +++ b/worlds/stardew_valley/test/TestNumberLocations.py @@ -1,4 +1,4 @@ -from . import SVTestBase +from .bases import SVTestBase from .options.presets import default_6_x_x, allsanity_no_mods_6_x_x, allsanity_mods_6_x_x_exclude_disabled, get_minsanity_options, \ minimal_locations_maximal_items, minimal_locations_maximal_items_with_island from .. import location_table diff --git a/worlds/stardew_valley/test/TestOptionFlags.py b/worlds/stardew_valley/test/TestOptionFlags.py index 2833649e35fa..d93015756486 100644 --- a/worlds/stardew_valley/test/TestOptionFlags.py +++ b/worlds/stardew_valley/test/TestOptionFlags.py @@ -1,4 +1,4 @@ -from . import SVTestBase +from .bases import SVTestBase from .. import BuildingProgression from ..options import ToolProgression diff --git a/worlds/stardew_valley/test/TestOptions.py b/worlds/stardew_valley/test/TestOptions.py index 11b0a0141533..738753fe8362 100644 --- a/worlds/stardew_valley/test/TestOptions.py +++ b/worlds/stardew_valley/test/TestOptions.py @@ -3,8 +3,8 @@ from BaseClasses import ItemClassification from test.param import classvar_matrix -from . import SVTestCase, solo_multiworld, SVTestBase from .assertion import WorldAssertMixin +from .bases import SVTestCase, SVTestBase, solo_multiworld from .options.option_names import all_option_choices from .options.presets import allsanity_no_mods_6_x_x, allsanity_mods_6_x_x from .. import items_by_group, Group diff --git a/worlds/stardew_valley/test/TestOptionsPairs.py b/worlds/stardew_valley/test/TestOptionsPairs.py index d489ab1ff282..addd748c424c 100644 --- a/worlds/stardew_valley/test/TestOptionsPairs.py +++ b/worlds/stardew_valley/test/TestOptionsPairs.py @@ -1,5 +1,5 @@ -from . import SVTestBase from .assertion import WorldAssertMixin +from .bases import SVTestBase from .. import options diff --git a/worlds/stardew_valley/test/TestRandomWorlds.py b/worlds/stardew_valley/test/TestRandomWorlds.py index 550ae14b5520..0c4ad6ae2999 100644 --- a/worlds/stardew_valley/test/TestRandomWorlds.py +++ b/worlds/stardew_valley/test/TestRandomWorlds.py @@ -2,8 +2,8 @@ from BaseClasses import MultiWorld, get_seed from test.param import classvar_matrix -from . import SVTestCase, skip_long_tests, solo_multiworld from .assertion import GoalAssertMixin, OptionAssertMixin, WorldAssertMixin +from .bases import skip_long_tests, SVTestCase, solo_multiworld from .options.option_names import generate_random_world_options diff --git a/worlds/stardew_valley/test/TestRegions.py b/worlds/stardew_valley/test/TestRegions.py index bd1b67297473..07e3094fb2e2 100644 --- a/worlds/stardew_valley/test/TestRegions.py +++ b/worlds/stardew_valley/test/TestRegions.py @@ -3,7 +3,7 @@ from typing import Set from BaseClasses import get_seed -from . import SVTestCase +from .bases import SVTestCase from .options.utils import fill_dataclass_with_default from .. import create_content from ..options import EntranceRandomization, ExcludeGingerIsland, SkillProgression diff --git a/worlds/stardew_valley/test/TestStartInventory.py b/worlds/stardew_valley/test/TestStartInventory.py index dc44a1bb4598..43ee0e132961 100644 --- a/worlds/stardew_valley/test/TestStartInventory.py +++ b/worlds/stardew_valley/test/TestStartInventory.py @@ -1,5 +1,5 @@ -from . import SVTestBase from .assertion import WorldAssertMixin +from .bases import SVTestBase from .. import options diff --git a/worlds/stardew_valley/test/TestTraps.py b/worlds/stardew_valley/test/TestTraps.py index 9df07a6d74c8..130674a35da4 100644 --- a/worlds/stardew_valley/test/TestTraps.py +++ b/worlds/stardew_valley/test/TestTraps.py @@ -1,7 +1,7 @@ import unittest -from . import SVTestBase from .assertion import WorldAssertMixin +from .bases import SVTestBase from .. import options, items_by_group, Group from ..options import TrapDistribution @@ -119,4 +119,3 @@ def test_omitted_item_same_as_nudge_in_item_pool(self): self.assertLess(num_bark, num_debris - threshold_difference) self.assertGreater(num_meow, num_time_flies + threshold_difference) self.assertGreater(num_meow, num_debris + threshold_difference) - diff --git a/worlds/stardew_valley/test/TestWalnutsanity.py b/worlds/stardew_valley/test/TestWalnutsanity.py index 5cc2f79e91bc..e3411edd0224 100644 --- a/worlds/stardew_valley/test/TestWalnutsanity.py +++ b/worlds/stardew_valley/test/TestWalnutsanity.py @@ -1,4 +1,4 @@ -from . import SVTestBase +from .bases import SVTestBase from ..options import ExcludeGingerIsland, Walnutsanity, ToolProgression, SkillProgression from ..strings.ap_names.ap_option_names import WalnutsanityOptionName diff --git a/worlds/stardew_valley/test/__init__.py b/worlds/stardew_valley/test/__init__.py index 6a8011a37d5f..e69de29bb2d1 100644 --- a/worlds/stardew_valley/test/__init__.py +++ b/worlds/stardew_valley/test/__init__.py @@ -1,308 +0,0 @@ -import itertools -import logging -import os -import threading -import unittest -from contextlib import contextmanager -from typing import Dict, ClassVar, Iterable, Tuple, Optional, List, Union, Any - -from BaseClasses import MultiWorld, CollectionState, get_seed, Location, Item -from test.bases import WorldTestBase -from test.general import gen_steps, setup_solo_multiworld as setup_base_solo_multiworld -from worlds.AutoWorld import call_all -from .assertion import RuleAssertMixin -from .options.utils import fill_namespace_with_default, parse_class_option_keys, fill_dataclass_with_default -from .. import StardewValleyWorld, StardewItem, StardewRule -from ..logic.time_logic import MONTH_COEFFICIENT -from ..options import StardewValleyOption, options - -logger = logging.getLogger(__name__) - -DEFAULT_TEST_SEED = get_seed() -logger.info(f"Default Test Seed: {DEFAULT_TEST_SEED}") - - -def skip_default_tests() -> bool: - return not bool(os.environ.get("base", False)) - - -def skip_long_tests() -> bool: - return not bool(os.environ.get("long", False)) - - -class SVTestCase(unittest.TestCase): - skip_default_tests: bool = skip_default_tests() - """Set False to not skip the base fill tests""" - skip_long_tests: bool = skip_long_tests() - """Set False to run tests that take long""" - - @contextmanager - def solo_world_sub_test(self, msg: Optional[str] = None, - /, - world_options: Optional[Dict[Union[str, StardewValleyOption], Any]] = None, - *, - seed=DEFAULT_TEST_SEED, - world_caching=True, - **kwargs) -> Tuple[MultiWorld, StardewValleyWorld]: - if msg is not None: - msg += " " - else: - msg = "" - msg += f"[Seed = {seed}]" - - with self.subTest(msg, **kwargs): - with solo_multiworld(world_options, seed=seed, world_caching=world_caching) as (multiworld, world): - yield multiworld, world - - -class SVTestBase(RuleAssertMixin, WorldTestBase, SVTestCase): - game = "Stardew Valley" - world: StardewValleyWorld - player: ClassVar[int] = 1 - - seed = DEFAULT_TEST_SEED - - @classmethod - def setUpClass(cls) -> None: - if cls is SVTestBase: - raise unittest.SkipTest("No running tests on SVTestBase import.") - - super().setUpClass() - - def world_setup(self, *args, **kwargs): - self.options = parse_class_option_keys(self.options) - - self.multiworld = setup_solo_multiworld(self.options, seed=self.seed) - self.multiworld.lock.acquire() - world = self.multiworld.worlds[self.player] - - self.original_state = self.multiworld.state.copy() - self.original_itempool = self.multiworld.itempool.copy() - self.unfilled_locations = self.multiworld.get_unfilled_locations(1) - if self.constructed: - self.world = world # noqa - - def tearDown(self) -> None: - self.multiworld.state = self.original_state - self.multiworld.itempool = self.original_itempool - for location in self.unfilled_locations: - location.item = None - - self.multiworld.lock.release() - - @property - def run_default_tests(self) -> bool: - if self.skip_default_tests: - return False - return super().run_default_tests - - def collect_months(self, months: int) -> None: - real_total_prog_items = self.world.total_progression_items - percent = months * MONTH_COEFFICIENT - self.collect("Stardrop", real_total_prog_items * 100 // percent) - self.world.total_progression_items = real_total_prog_items - - def collect_lots_of_money(self, percent: float = 0.25): - self.collect("Shipping Bin") - real_total_prog_items = self.world.total_progression_items - required_prog_items = int(round(real_total_prog_items * percent)) - self.collect("Stardrop", required_prog_items) - - def collect_all_the_money(self): - self.collect_lots_of_money(0.95) - - def collect_everything(self): - non_event_items = [item for item in self.multiworld.get_items() if item.code] - for item in non_event_items: - self.multiworld.state.collect(item) - - def collect_all_except(self, item_to_not_collect: str): - non_event_items = [item for item in self.multiworld.get_items() if item.code] - for item in non_event_items: - if item.name != item_to_not_collect: - self.multiworld.state.collect(item) - - def get_real_locations(self) -> List[Location]: - return [location for location in self.multiworld.get_locations(self.player) if location.address is not None] - - def get_real_location_names(self) -> List[str]: - return [location.name for location in self.get_real_locations()] - - def collect(self, item: Union[str, Item, Iterable[Item]], count: int = 1) -> Union[None, Item, List[Item]]: - assert count > 0 - - if not isinstance(item, str): - super().collect(item) - return - - if count == 1: - item = self.create_item(item) - self.multiworld.state.collect(item) - return item - - items = [] - for i in range(count): - item = self.create_item(item) - self.multiworld.state.collect(item) - items.append(item) - - return items - - def create_item(self, item: str) -> StardewItem: - return self.world.create_item(item) - - def get_all_created_items(self) -> list[str]: - return [item.name for item in itertools.chain(self.multiworld.get_items(), self.multiworld.precollected_items[self.player])] - - def remove_one_by_name(self, item: str) -> None: - self.remove(self.create_item(item)) - - def reset_collection_state(self) -> None: - self.multiworld.state = self.original_state.copy() - - def assert_rule_true(self, rule: StardewRule, state: CollectionState | None = None) -> None: - if state is None: - state = self.multiworld.state - super().assert_rule_true(rule, state) - - def assert_rule_false(self, rule: StardewRule, state: CollectionState | None = None) -> None: - if state is None: - state = self.multiworld.state - super().assert_rule_false(rule, state) - - def assert_can_reach_location(self, location: Location | str, state: CollectionState | None = None) -> None: - if state is None: - state = self.multiworld.state - super().assert_can_reach_location(location, state) - - def assert_cannot_reach_location(self, location: Location | str, state: CollectionState | None = None) -> None: - if state is None: - state = self.multiworld.state - super().assert_cannot_reach_location(location, state) - - -pre_generated_worlds = {} - - -@contextmanager -def solo_multiworld(world_options: Optional[Dict[Union[str, StardewValleyOption], Any]] = None, - *, - seed=DEFAULT_TEST_SEED, - world_caching=True) -> Tuple[MultiWorld, StardewValleyWorld]: - if not world_caching: - multiworld = setup_solo_multiworld(world_options, seed, _cache={}) - yield multiworld, multiworld.worlds[1] - else: - multiworld = setup_solo_multiworld(world_options, seed) - try: - multiworld.lock.acquire() - world = multiworld.worlds[1] - - original_state = multiworld.state.copy() - original_itempool = multiworld.itempool.copy() - unfilled_locations = multiworld.get_unfilled_locations(1) - - yield multiworld, world - - multiworld.state = original_state - multiworld.itempool = original_itempool - for location in unfilled_locations: - location.item = None - finally: - multiworld.lock.release() - - -# Mostly a copy of test.general.setup_solo_multiworld, I just don't want to change the core. -def setup_solo_multiworld(test_options: Optional[Dict[Union[str, StardewValleyOption], str]] = None, - seed=DEFAULT_TEST_SEED, - _cache: Dict[frozenset, MultiWorld] = {}, # noqa - _steps=gen_steps) -> MultiWorld: - test_options = parse_class_option_keys(test_options) - - # Yes I reuse the worlds generated between tests, its speeds the execution by a couple seconds - # If the simple dict caching ends up taking too much memory, we could replace it with some kind of lru cache. - should_cache = should_cache_world(test_options) - if should_cache: - frozen_options = make_hashable(test_options, seed) - cached_multi_world = search_world_cache(_cache, frozen_options) - if cached_multi_world: - print(f"Using cached solo multi world [Seed = {cached_multi_world.seed}] [Cache size = {len(_cache)}]") - return cached_multi_world - - multiworld = setup_base_solo_multiworld(StardewValleyWorld, (), seed=seed) - # print(f"Seed: {multiworld.seed}") # Uncomment to print the seed for every test - - args = fill_namespace_with_default(test_options) - multiworld.set_options(args) - - if "start_inventory" in test_options: - for item, amount in test_options["start_inventory"].items(): - for _ in range(amount): - multiworld.push_precollected(multiworld.create_item(item, 1)) - - for step in _steps: - call_all(multiworld, step) - - if should_cache: - add_to_world_cache(_cache, frozen_options, multiworld) # noqa - - # Lock is needed for multi-threading tests - setattr(multiworld, "lock", threading.Lock()) - - return multiworld - - -def should_cache_world(test_options): - if "start_inventory" in test_options: - return False - - trap_distribution_key = "trap_distribution" - if trap_distribution_key not in test_options: - return True - - trap_distribution = test_options[trap_distribution_key] - for key in trap_distribution: - if trap_distribution[key] != options.TrapDistribution.default_weight: - return False - - return True - - - -def make_hashable(test_options, seed): - return frozenset(test_options.items()).union({("seed", seed)}) - - -def search_world_cache(cache: Dict[frozenset, MultiWorld], frozen_options: frozenset) -> Optional[MultiWorld]: - try: - return cache[frozen_options] - except KeyError: - for cached_options, multi_world in cache.items(): - if frozen_options.issubset(cached_options): - return multi_world - return None - - -def add_to_world_cache(cache: Dict[frozenset, MultiWorld], frozen_options: frozenset, multi_world: MultiWorld) -> None: - # We could complete the key with all the default options, but that does not seem to improve performances. - cache[frozen_options] = multi_world - - -def setup_multiworld(test_options: Iterable[Dict[str, int]] = None, seed=None) -> MultiWorld: # noqa - if test_options is None: - test_options = [] - - multiworld = MultiWorld(len(test_options)) - multiworld.player_name = {} - multiworld.set_seed(seed) - multiworld.state = CollectionState(multiworld) - for i in range(1, len(test_options) + 1): - multiworld.game[i] = StardewValleyWorld.game - multiworld.player_name.update({i: f"Tester{i}"}) - args = fill_namespace_with_default(test_options) - multiworld.set_options(args) - - for step in gen_steps: - call_all(multiworld, step) - - return multiworld diff --git a/worlds/stardew_valley/test/bases.py b/worlds/stardew_valley/test/bases.py new file mode 100644 index 000000000000..64ada395682c --- /dev/null +++ b/worlds/stardew_valley/test/bases.py @@ -0,0 +1,306 @@ +import itertools +import logging +import os +import threading +import typing +import unittest +from contextlib import contextmanager +from typing import Optional, Dict, Union, Any, List, Iterable + +from BaseClasses import get_seed, MultiWorld, Location, Item, CollectionState +from test.bases import WorldTestBase +from test.general import gen_steps, setup_solo_multiworld as setup_base_solo_multiworld +from worlds.AutoWorld import call_all +from .assertion import RuleAssertMixin +from .options.utils import parse_class_option_keys, fill_namespace_with_default +from .. import StardewValleyWorld, StardewItem, StardewRule +from ..logic.time_logic import MONTH_COEFFICIENT +from ..options import StardewValleyOption, options + +logger = logging.getLogger(__name__) +DEFAULT_TEST_SEED = get_seed() +logger.info(f"Default Test Seed: {DEFAULT_TEST_SEED}") + + +def skip_default_tests() -> bool: + return not bool(os.environ.get("base", False)) + + +def skip_long_tests() -> bool: + return not bool(os.environ.get("long", False)) + + +class SVTestCase(unittest.TestCase): + skip_default_tests: bool = skip_default_tests() + """Set False to not skip the base fill tests""" + skip_long_tests: bool = skip_long_tests() + """Set False to run tests that take long""" + + @contextmanager + def solo_world_sub_test(self, msg: str | None = None, + /, + world_options: dict[str | type[StardewValleyOption], Any] | None = None, + *, + seed=DEFAULT_TEST_SEED, + world_caching=True, + **kwargs) -> Iterable[tuple[MultiWorld, StardewValleyWorld]]: + if msg is not None: + msg += " " + else: + msg = "" + msg += f"[Seed = {seed}]" + + with self.subTest(msg, **kwargs): + with solo_multiworld(world_options, seed=seed, world_caching=world_caching) as (multiworld, world): + yield multiworld, world + + +class SVTestBase(RuleAssertMixin, WorldTestBase, SVTestCase): + game = "Stardew Valley" + world: StardewValleyWorld + + seed = DEFAULT_TEST_SEED + + @classmethod + def setUpClass(cls) -> None: + if cls is SVTestBase: + raise unittest.SkipTest("No running tests on SVTestBase import.") + + super().setUpClass() + + def world_setup(self, *args, **kwargs): + self.options = parse_class_option_keys(self.options) + + self.multiworld = setup_solo_multiworld(self.options, seed=self.seed) + self.multiworld.lock.acquire() + world = self.multiworld.worlds[self.player] + + self.original_state = self.multiworld.state.copy() + self.original_itempool = self.multiworld.itempool.copy() + self.unfilled_locations = self.multiworld.get_unfilled_locations(1) + if self.constructed: + self.world = world # noqa + + def tearDown(self) -> None: + self.multiworld.state = self.original_state + self.multiworld.itempool = self.original_itempool + for location in self.unfilled_locations: + location.item = None + + self.multiworld.lock.release() + + @property + def run_default_tests(self) -> bool: + if self.skip_default_tests: + return False + return super().run_default_tests + + def collect_months(self, months: int) -> None: + real_total_prog_items = self.world.total_progression_items + percent = months * MONTH_COEFFICIENT + self.collect("Stardrop", real_total_prog_items * 100 // percent) + self.world.total_progression_items = real_total_prog_items + + def collect_lots_of_money(self, percent: float = 0.25): + self.collect("Shipping Bin") + real_total_prog_items = self.world.total_progression_items + required_prog_items = int(round(real_total_prog_items * percent)) + self.collect("Stardrop", required_prog_items) + + def collect_all_the_money(self): + self.collect_lots_of_money(0.95) + + def collect_everything(self): + non_event_items = [item for item in self.multiworld.get_items() if item.code] + for item in non_event_items: + self.multiworld.state.collect(item) + + def collect_all_except(self, item_to_not_collect: str): + non_event_items = [item for item in self.multiworld.get_items() if item.code] + for item in non_event_items: + if item.name != item_to_not_collect: + self.multiworld.state.collect(item) + + def get_real_locations(self) -> List[Location]: + return [location for location in self.multiworld.get_locations(self.player) if location.address is not None] + + def get_real_location_names(self) -> List[str]: + return [location.name for location in self.get_real_locations()] + + def collect(self, item: Union[str, Item, Iterable[Item]], count: int = 1) -> Union[None, Item, List[Item]]: + assert count > 0 + + if not isinstance(item, str): + super().collect(item) + return + + if count == 1: + item = self.create_item(item) + self.multiworld.state.collect(item) + return item + + items = [] + for i in range(count): + item = self.create_item(item) + self.multiworld.state.collect(item) + items.append(item) + + return items + + def create_item(self, item: str) -> StardewItem: + return self.world.create_item(item) + + def get_all_created_items(self) -> list[str]: + return [item.name for item in itertools.chain(self.multiworld.get_items(), self.multiworld.precollected_items[self.player])] + + def remove_one_by_name(self, item: str) -> None: + self.remove(self.create_item(item)) + + def reset_collection_state(self) -> None: + self.multiworld.state = self.original_state.copy() + + def assert_rule_true(self, rule: StardewRule, state: CollectionState | None = None) -> None: + if state is None: + state = self.multiworld.state + super().assert_rule_true(rule, state) + + def assert_rule_false(self, rule: StardewRule, state: CollectionState | None = None) -> None: + if state is None: + state = self.multiworld.state + super().assert_rule_false(rule, state) + + def assert_can_reach_location(self, location: Location | str, state: CollectionState | None = None) -> None: + if state is None: + state = self.multiworld.state + super().assert_can_reach_location(location, state) + + def assert_cannot_reach_location(self, location: Location | str, state: CollectionState | None = None) -> None: + if state is None: + state = self.multiworld.state + super().assert_cannot_reach_location(location, state) + + +pre_generated_worlds = {} + + +@contextmanager +def solo_multiworld(world_options: dict[str | type[StardewValleyOption], Any] | None = None, + *, + seed=DEFAULT_TEST_SEED, + world_caching=True) -> Iterable[tuple[MultiWorld, StardewValleyWorld]]: + if not world_caching: + multiworld = setup_solo_multiworld(world_options, seed, _cache={}) + yield multiworld, typing.cast(StardewValleyWorld, multiworld.worlds[1]) + else: + multiworld = setup_solo_multiworld(world_options, seed) + try: + multiworld.lock.acquire() + world = multiworld.worlds[1] + + original_state = multiworld.state.copy() + original_itempool = multiworld.itempool.copy() + unfilled_locations = multiworld.get_unfilled_locations(1) + + yield multiworld, typing.cast(StardewValleyWorld, world) + + multiworld.state = original_state + multiworld.itempool = original_itempool + for location in unfilled_locations: + location.item = None + finally: + multiworld.lock.release() + + +# Mostly a copy of test.general.setup_solo_multiworld, I just don't want to change the core. +def setup_solo_multiworld(test_options: Optional[Dict[Union[str, StardewValleyOption], str]] = None, + seed=DEFAULT_TEST_SEED, + _cache: Dict[frozenset, MultiWorld] = {}, # noqa + _steps=gen_steps) -> MultiWorld: + test_options = parse_class_option_keys(test_options) + + # Yes I reuse the worlds generated between tests, its speeds the execution by a couple seconds + # If the simple dict caching ends up taking too much memory, we could replace it with some kind of lru cache. + should_cache = should_cache_world(test_options) + if should_cache: + frozen_options = make_hashable(test_options, seed) + cached_multi_world = search_world_cache(_cache, frozen_options) + if cached_multi_world: + print(f"Using cached solo multi world [Seed = {cached_multi_world.seed}] [Cache size = {len(_cache)}]") + return cached_multi_world + + multiworld = setup_base_solo_multiworld(StardewValleyWorld, (), seed=seed) + # print(f"Seed: {multiworld.seed}") # Uncomment to print the seed for every test + + args = fill_namespace_with_default(test_options) + multiworld.set_options(args) + + if "start_inventory" in test_options: + for item, amount in test_options["start_inventory"].items(): + for _ in range(amount): + multiworld.push_precollected(multiworld.create_item(item, 1)) + + for step in _steps: + call_all(multiworld, step) + + if should_cache: + add_to_world_cache(_cache, frozen_options, multiworld) # noqa + + # Lock is needed for multi-threading tests + setattr(multiworld, "lock", threading.Lock()) + + return multiworld + + +def should_cache_world(test_options): + if "start_inventory" in test_options: + return False + + trap_distribution_key = "trap_distribution" + if trap_distribution_key not in test_options: + return True + + trap_distribution = test_options[trap_distribution_key] + for key in trap_distribution: + if trap_distribution[key] != options.TrapDistribution.default_weight: + return False + + return True + + +def make_hashable(test_options, seed): + return frozenset(test_options.items()).union({("seed", seed)}) + + +def search_world_cache(cache: Dict[frozenset, MultiWorld], frozen_options: frozenset) -> Optional[MultiWorld]: + try: + return cache[frozen_options] + except KeyError: + for cached_options, multi_world in cache.items(): + if frozen_options.issubset(cached_options): + return multi_world + return None + + +def add_to_world_cache(cache: Dict[frozenset, MultiWorld], frozen_options: frozenset, multi_world: MultiWorld) -> None: + # We could complete the key with all the default options, but that does not seem to improve performances. + cache[frozen_options] = multi_world + + +def setup_multiworld(test_options: Iterable[Dict[str, int]] = None, seed=None) -> MultiWorld: # noqa + if test_options is None: + test_options = [] + + multiworld = MultiWorld(len(test_options)) + multiworld.player_name = {} + multiworld.set_seed(seed) + multiworld.state = CollectionState(multiworld) + for i in range(1, len(test_options) + 1): + multiworld.game[i] = StardewValleyWorld.game + multiworld.player_name.update({i: f"Tester{i}"}) + args = fill_namespace_with_default(test_options) + multiworld.set_options(args) + + for step in gen_steps: + call_all(multiworld, step) + + return multiworld diff --git a/worlds/stardew_valley/test/content/TestGingerIsland.py b/worlds/stardew_valley/test/content/TestGingerIsland.py index 7e7f866dfc8e..c1f16b48c4f8 100644 --- a/worlds/stardew_valley/test/content/TestGingerIsland.py +++ b/worlds/stardew_valley/test/content/TestGingerIsland.py @@ -1,5 +1,5 @@ from . import SVContentPackTestBase -from .. import SVTestBase +from ..bases import SVTestBase from ... import options from ...content import content_packs from ...data.artisan import MachineSource diff --git a/worlds/stardew_valley/test/content/mods/TestSVE.py b/worlds/stardew_valley/test/content/mods/TestSVE.py index 4065498d6be7..7cd0a822a152 100644 --- a/worlds/stardew_valley/test/content/mods/TestSVE.py +++ b/worlds/stardew_valley/test/content/mods/TestSVE.py @@ -1,5 +1,5 @@ from .. import SVContentPackTestBase -from ... import SVTestBase +from ...bases import SVTestBase from .... import options from ....content import content_packs from ....mods.mod_data import ModNames diff --git a/worlds/stardew_valley/test/long/TestModsLong.py b/worlds/stardew_valley/test/long/TestModsLong.py index bc5e8bfff8ac..d14af8bc5501 100644 --- a/worlds/stardew_valley/test/long/TestModsLong.py +++ b/worlds/stardew_valley/test/long/TestModsLong.py @@ -4,8 +4,8 @@ from BaseClasses import get_seed from test.param import classvar_matrix -from .. import SVTestCase, solo_multiworld, skip_long_tests from ..assertion import WorldAssertMixin, ModAssertMixin +from ..bases import skip_long_tests, SVTestCase, solo_multiworld from ..options.option_names import all_option_choices from ... import options from ...mods.mod_data import ModNames diff --git a/worlds/stardew_valley/test/long/TestOptionsLong.py b/worlds/stardew_valley/test/long/TestOptionsLong.py index db467964e7c4..3c9690e2e6bf 100644 --- a/worlds/stardew_valley/test/long/TestOptionsLong.py +++ b/worlds/stardew_valley/test/long/TestOptionsLong.py @@ -4,8 +4,8 @@ from BaseClasses import get_seed from test.param import classvar_matrix -from .. import SVTestCase, solo_multiworld, skip_long_tests from ..assertion.world_assert import WorldAssertMixin +from ..bases import skip_long_tests, SVTestCase, solo_multiworld from ..options.option_names import all_option_choices from ... import options diff --git a/worlds/stardew_valley/test/long/TestPreRolledRandomness.py b/worlds/stardew_valley/test/long/TestPreRolledRandomness.py index 3b6f818ec43c..3d3e0da13bf7 100644 --- a/worlds/stardew_valley/test/long/TestPreRolledRandomness.py +++ b/worlds/stardew_valley/test/long/TestPreRolledRandomness.py @@ -3,8 +3,8 @@ from BaseClasses import get_seed from test.param import classvar_matrix -from .. import SVTestCase, solo_multiworld, skip_long_tests from ..assertion import WorldAssertMixin +from ..bases import skip_long_tests, SVTestCase, solo_multiworld from ... import options if skip_long_tests(): diff --git a/worlds/stardew_valley/test/mods/TestBiggerBackpack.py b/worlds/stardew_valley/test/mods/TestBiggerBackpack.py index f6d312976c45..8ec2e539b7e1 100644 --- a/worlds/stardew_valley/test/mods/TestBiggerBackpack.py +++ b/worlds/stardew_valley/test/mods/TestBiggerBackpack.py @@ -1,4 +1,4 @@ -from .. import SVTestBase +from ..bases import SVTestBase from ...mods.mod_data import ModNames from ...options import Mods, BackpackProgression diff --git a/worlds/stardew_valley/test/mods/TestMods.py b/worlds/stardew_valley/test/mods/TestMods.py index bd5d7d626dfc..be6ce710768d 100644 --- a/worlds/stardew_valley/test/mods/TestMods.py +++ b/worlds/stardew_valley/test/mods/TestMods.py @@ -3,9 +3,9 @@ from BaseClasses import get_seed from test.param import classvar_matrix -from .. import SVTestBase, SVTestCase, solo_multiworld from ..TestGeneration import get_all_permanent_progression_items from ..assertion import ModAssertMixin, WorldAssertMixin +from ..bases import SVTestCase, SVTestBase, solo_multiworld from ..options.presets import allsanity_mods_6_x_x from ..options.utils import fill_dataclass_with_default from ... import options, Group, create_content diff --git a/worlds/stardew_valley/test/mods/TestModsFill.py b/worlds/stardew_valley/test/mods/TestModsFill.py index a140f5abae14..334a4ff9e47d 100644 --- a/worlds/stardew_valley/test/mods/TestModsFill.py +++ b/worlds/stardew_valley/test/mods/TestModsFill.py @@ -1,4 +1,4 @@ -from .. import SVTestBase +from ..bases import SVTestBase from ... import options diff --git a/worlds/stardew_valley/test/mods/TestSVE.py b/worlds/stardew_valley/test/mods/TestSVE.py index ca63dcb351aa..a6b6f6a3dc99 100644 --- a/worlds/stardew_valley/test/mods/TestSVE.py +++ b/worlds/stardew_valley/test/mods/TestSVE.py @@ -1,4 +1,4 @@ -from .. import SVTestBase +from ..bases import SVTestBase from ... import options from ...mods.mod_data import ModNames from ...strings.ap_names.mods.mod_items import SVEQuestItem diff --git a/worlds/stardew_valley/test/options/TestPresets.py b/worlds/stardew_valley/test/options/TestPresets.py index 5d9e89531c87..5c1cee4a58b9 100644 --- a/worlds/stardew_valley/test/options/TestPresets.py +++ b/worlds/stardew_valley/test/options/TestPresets.py @@ -1,5 +1,5 @@ from Options import PerGameCommonOptions, OptionSet, OptionDict -from .. import SVTestCase +from ..bases import SVTestCase from ...options import StardewValleyOptions, TrapItems from ...options.presets import sv_options_presets diff --git a/worlds/stardew_valley/test/performance/TestPerformance.py b/worlds/stardew_valley/test/performance/TestPerformance.py index ca63ee5e2c73..2951e6d00a70 100644 --- a/worlds/stardew_valley/test/performance/TestPerformance.py +++ b/worlds/stardew_valley/test/performance/TestPerformance.py @@ -8,7 +8,7 @@ from BaseClasses import get_seed from Fill import distribute_items_restrictive, balance_multiworld_progression from worlds import AutoWorld -from .. import SVTestCase, setup_multiworld +from ..bases import SVTestCase, setup_multiworld from ..options.presets import default_6_x_x, allsanity_no_mods_6_x_x, allsanity_mods_6_x_x, minimal_locations_maximal_items assert default_6_x_x diff --git a/worlds/stardew_valley/test/rules/TestArcades.py b/worlds/stardew_valley/test/rules/TestArcades.py index 5fdf7df13d5d..407f299992c3 100644 --- a/worlds/stardew_valley/test/rules/TestArcades.py +++ b/worlds/stardew_valley/test/rules/TestArcades.py @@ -1,5 +1,5 @@ +from ..bases import SVTestBase from ... import options -from ...test import SVTestBase class TestArcadeMachinesLogic(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestBooks.py b/worlds/stardew_valley/test/rules/TestBooks.py index 4cd84a77a278..eb26b2744492 100644 --- a/worlds/stardew_valley/test/rules/TestBooks.py +++ b/worlds/stardew_valley/test/rules/TestBooks.py @@ -1,5 +1,5 @@ +from ..bases import SVTestBase from ... import options -from ...test import SVTestBase class TestBooksLogic(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestBuildings.py b/worlds/stardew_valley/test/rules/TestBuildings.py index 8eeb9d295af1..0b1f41d2c56b 100644 --- a/worlds/stardew_valley/test/rules/TestBuildings.py +++ b/worlds/stardew_valley/test/rules/TestBuildings.py @@ -1,5 +1,5 @@ +from ..bases import SVTestBase from ...options import BuildingProgression, FarmType -from ...test import SVTestBase class TestBuildingLogic(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestBundles.py b/worlds/stardew_valley/test/rules/TestBundles.py index 918cb8aba6a7..357269a25ba0 100644 --- a/worlds/stardew_valley/test/rules/TestBundles.py +++ b/worlds/stardew_valley/test/rules/TestBundles.py @@ -1,7 +1,7 @@ +from ..bases import SVTestBase from ... import options from ...options import BundleRandomization from ...strings.bundle_names import BundleName -from ...test import SVTestBase class TestBundlesLogic(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestCookingRecipes.py b/worlds/stardew_valley/test/rules/TestCookingRecipes.py index b3aafdb690a3..b468a72d4117 100644 --- a/worlds/stardew_valley/test/rules/TestCookingRecipes.py +++ b/worlds/stardew_valley/test/rules/TestCookingRecipes.py @@ -1,6 +1,6 @@ +from ..bases import SVTestBase from ... import options from ...options import BuildingProgression, ExcludeGingerIsland, Chefsanity -from ...test import SVTestBase class TestRecipeLearnLogic(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestCraftingRecipes.py b/worlds/stardew_valley/test/rules/TestCraftingRecipes.py index 94d6bc145ae2..f875dc539d46 100644 --- a/worlds/stardew_valley/test/rules/TestCraftingRecipes.py +++ b/worlds/stardew_valley/test/rules/TestCraftingRecipes.py @@ -1,7 +1,7 @@ +from ..bases import SVTestBase from ... import options from ...data.craftable_data import all_crafting_recipes_by_name from ...options import BuildingProgression, ExcludeGingerIsland, Craftsanity, SeasonRandomization -from ...test import SVTestBase class TestCraftsanityLogic(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestDonations.py b/worlds/stardew_valley/test/rules/TestDonations.py index d50f87d3e9a6..2cddcad39521 100644 --- a/worlds/stardew_valley/test/rules/TestDonations.py +++ b/worlds/stardew_valley/test/rules/TestDonations.py @@ -1,8 +1,8 @@ +from ..bases import SVTestBase from ... import options from ...locations import locations_by_tag, LocationTags, location_table from ...strings.entrance_names import Entrance from ...strings.region_names import Region -from ...test import SVTestBase class TestDonationLogicAll(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestFishing.py b/worlds/stardew_valley/test/rules/TestFishing.py index 6a6a4bb3159d..3649592301c4 100644 --- a/worlds/stardew_valley/test/rules/TestFishing.py +++ b/worlds/stardew_valley/test/rules/TestFishing.py @@ -1,6 +1,6 @@ +from ..bases import SVTestBase from ...options import SeasonRandomization, Fishsanity, ExcludeGingerIsland, SkillProgression, ToolProgression, ElevatorProgression, SpecialOrderLocations from ...strings.fish_names import Fish -from ...test import SVTestBase class TestNeedRegionToCatchFish(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestFriendship.py b/worlds/stardew_valley/test/rules/TestFriendship.py index 9cd3127aa355..dc5935580ad0 100644 --- a/worlds/stardew_valley/test/rules/TestFriendship.py +++ b/worlds/stardew_valley/test/rules/TestFriendship.py @@ -1,5 +1,5 @@ +from ..bases import SVTestBase from ...options import SeasonRandomization, Friendsanity, FriendsanityHeartSize -from ...test import SVTestBase class TestFriendsanityDatingRules(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestMuseum.py b/worlds/stardew_valley/test/rules/TestMuseum.py index 35dad8f43ebc..231bbafe2290 100644 --- a/worlds/stardew_valley/test/rules/TestMuseum.py +++ b/worlds/stardew_valley/test/rules/TestMuseum.py @@ -1,7 +1,7 @@ from collections import Counter +from ..bases import SVTestBase from ...options import Museumsanity -from .. import SVTestBase class TestMuseumMilestones(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestShipping.py b/worlds/stardew_valley/test/rules/TestShipping.py index fc61ae8e2a99..c1f29d934255 100644 --- a/worlds/stardew_valley/test/rules/TestShipping.py +++ b/worlds/stardew_valley/test/rules/TestShipping.py @@ -1,6 +1,6 @@ +from ..bases import SVTestBase from ...locations import LocationTags, location_table from ...options import BuildingProgression, Shipsanity -from ...test import SVTestBase class TestShipsanityNone(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestSkills.py b/worlds/stardew_valley/test/rules/TestSkills.py index a5957488a1a2..fd513a1becc7 100644 --- a/worlds/stardew_valley/test/rules/TestSkills.py +++ b/worlds/stardew_valley/test/rules/TestSkills.py @@ -1,7 +1,7 @@ +from ..bases import SVTestBase from ... import HasProgressionPercent, StardewLogic from ...options import ToolProgression, SkillProgression, Mods from ...strings.skill_names import all_skills, all_vanilla_skills, Skill -from ...test import SVTestBase class TestSkillProgressionVanilla(SVTestBase): diff --git a/worlds/stardew_valley/test/rules/TestStateRules.py b/worlds/stardew_valley/test/rules/TestStateRules.py index db56e8220c05..57573c7f8b55 100644 --- a/worlds/stardew_valley/test/rules/TestStateRules.py +++ b/worlds/stardew_valley/test/rules/TestStateRules.py @@ -1,4 +1,4 @@ -from .. import SVTestBase +from ..bases import SVTestBase from ..options.presets import allsanity_mods_6_x_x from ...stardew_rule import HasProgressionPercent diff --git a/worlds/stardew_valley/test/rules/TestTools.py b/worlds/stardew_valley/test/rules/TestTools.py index bda29e3d74c6..54b9ec8f2f26 100644 --- a/worlds/stardew_valley/test/rules/TestTools.py +++ b/worlds/stardew_valley/test/rules/TestTools.py @@ -1,6 +1,6 @@ from collections import Counter -from .. import SVTestBase +from ..bases import SVTestBase from ... import options from ...options import ToolProgression, SeasonRandomization from ...strings.entrance_names import Entrance diff --git a/worlds/stardew_valley/test/rules/TestWeapons.py b/worlds/stardew_valley/test/rules/TestWeapons.py index 383f26e841d2..e95e706ded12 100644 --- a/worlds/stardew_valley/test/rules/TestWeapons.py +++ b/worlds/stardew_valley/test/rules/TestWeapons.py @@ -1,6 +1,6 @@ +from ..bases import SVTestBase from ... import options from ...options import ToolProgression -from ...test import SVTestBase class TestWeaponsLogic(SVTestBase): diff --git a/worlds/stardew_valley/test/script/benchmark_locations.py b/worlds/stardew_valley/test/script/benchmark_locations.py index 04553e39968e..3dcfc4dbebfb 100644 --- a/worlds/stardew_valley/test/script/benchmark_locations.py +++ b/worlds/stardew_valley/test/script/benchmark_locations.py @@ -15,8 +15,9 @@ from BaseClasses import CollectionState, Location from Utils import init_logging -from worlds.stardew_valley.stardew_rule.rule_explain import explain -from ... import test +from ..bases import setup_solo_multiworld +from ..options import presets +from ...stardew_rule.rule_explain import explain def run_locations_benchmark(): @@ -56,12 +57,12 @@ def main(self): parser.add_argument('--state', help="Define the state in which the location will be benchmarked.", type=str, default=None) args = parser.parse_args() options_set = args.options - options = getattr(test, options_set)() + options = getattr(presets, options_set)() seed = args.seed location = args.location state = args.state - multiworld = test.setup_solo_multiworld(options, seed) + multiworld = setup_solo_multiworld(options, seed) gc.collect() if location: diff --git a/worlds/stardew_valley/test/stability/StabilityOutputScript.py b/worlds/stardew_valley/test/stability/StabilityOutputScript.py index 9b4b608d4e0d..29fd90309511 100644 --- a/worlds/stardew_valley/test/stability/StabilityOutputScript.py +++ b/worlds/stardew_valley/test/stability/StabilityOutputScript.py @@ -1,7 +1,7 @@ import argparse import json -from .. import setup_solo_multiworld +from ..bases import setup_solo_multiworld from ..options.presets import allsanity_mods_6_x_x_exclude_disabled from ...options import FarmType, EntranceRandomization diff --git a/worlds/stardew_valley/test/stability/TestStability.py b/worlds/stardew_valley/test/stability/TestStability.py index b4d0f30ea51f..f3dfb9fdaae7 100644 --- a/worlds/stardew_valley/test/stability/TestStability.py +++ b/worlds/stardew_valley/test/stability/TestStability.py @@ -5,7 +5,7 @@ import unittest from BaseClasses import get_seed -from .. import SVTestCase +from ..bases import SVTestCase # at 0x102ca98a0> lambda_regex = re.compile(r"^ at (.*)>$") diff --git a/worlds/stardew_valley/test/stability/TestUniversalTracker.py b/worlds/stardew_valley/test/stability/TestUniversalTracker.py index 7590635aa193..301abfff22bc 100644 --- a/worlds/stardew_valley/test/stability/TestUniversalTracker.py +++ b/worlds/stardew_valley/test/stability/TestUniversalTracker.py @@ -1,9 +1,11 @@ import unittest from unittest.mock import Mock -from .. import SVTestBase, fill_namespace_with_default, skip_long_tests +from ..bases import skip_long_tests, SVTestBase from ..options.presets import allsanity_mods_6_x_x -from ... import STARDEW_VALLEY, FarmType, BundleRandomization, EntranceRandomization +from ..options.utils import fill_namespace_with_default +from ... import STARDEW_VALLEY +from ...options import FarmType, BundleRandomization, EntranceRandomization @unittest.skipIf(skip_long_tests(), "Long tests disabled") From 0994afa25bc393b3d68dbaffc2a79b9f9afd8b74 Mon Sep 17 00:00:00 2001 From: Ixrec Date: Tue, 13 May 2025 08:59:41 +0100 Subject: [PATCH 0417/1218] Tests: actually run tests in __init__.py files (#4969) * demonstrate our pytest/CI configuration missing a __init__ test failure * tell pytest/CI to run tests in __init__.py files * revert the demonstration test failure --------- Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- pytest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index cd8fd8dfce37..4469a7c30d64 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,5 +1,5 @@ [pytest] -python_files = test_*.py Test*.py # TODO: remove Test* once all worlds have been ported +python_files = test_*.py Test*.py __init__.py # TODO: remove Test* once all worlds have been ported python_classes = Test python_functions = test testpaths = From b71c8005e7b38e42fa76b27869b7b1862de21886 Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Wed, 14 May 2025 05:18:36 -0600 Subject: [PATCH 0418/1218] AHiT: Fix Client Argument Handling (#4992) --- AHITClient.py | 3 ++- worlds/ahit/Client.py | 4 ++-- worlds/ahit/__init__.py | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/AHITClient.py b/AHITClient.py index 6ed7d7b49d48..edcbbd842e56 100644 --- a/AHITClient.py +++ b/AHITClient.py @@ -1,3 +1,4 @@ +import sys from worlds.ahit.Client import launch import Utils import ModuleUpdate @@ -5,4 +6,4 @@ if __name__ == "__main__": Utils.init_logging("AHITClient", exception_logger="Client") - launch() + launch(*sys.argv[1:]) diff --git a/worlds/ahit/Client.py b/worlds/ahit/Client.py index 0a9d8d6042a3..64c1124fa853 100644 --- a/worlds/ahit/Client.py +++ b/worlds/ahit/Client.py @@ -238,10 +238,10 @@ async def proxy_loop(ctx: AHITContext): logger.info("Aborting AHIT Proxy Client due to errors") -def launch(): +def launch(*launch_args: str): async def main(): parser = get_base_parser() - args = parser.parse_args() + args = parser.parse_args(launch_args) ctx = AHITContext(args.connect, args.password) logger.info("Starting A Hat in Time proxy server") diff --git a/worlds/ahit/__init__.py b/worlds/ahit/__init__.py index 16b54064c691..1bcc840ae6cb 100644 --- a/worlds/ahit/__init__.py +++ b/worlds/ahit/__init__.py @@ -16,9 +16,9 @@ from Utils import local_path -def launch_client(): +def launch_client(*args: str): from .Client import launch - launch_component(launch, name="AHITClient") + launch_component(launch, name="AHITClient", args=args) components.append(Component("A Hat in Time Client", "AHITClient", func=launch_client, From 72854cde44dff707109ad66e489fa100e7db18ee Mon Sep 17 00:00:00 2001 From: Ixrec Date: Wed, 14 May 2025 12:21:40 +0100 Subject: [PATCH 0419/1218] Docs: Add a "Missable Locations" Question to apworld FAQ (#4965) * Docs: add a "missable locations" question to apworld_dev_faq.md Basically turning the conversation at https://discord.com/channels/731205301247803413/1214608557077700720/1368996789260128388 into a FAQ entry. * feedback * qwint feedback * Update docs/apworld_dev_faq.md Co-authored-by: Scipio Wright --------- Co-authored-by: Scipio Wright --- docs/apworld_dev_faq.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/apworld_dev_faq.md b/docs/apworld_dev_faq.md index 50bee148c60e..6e1c102c6a36 100644 --- a/docs/apworld_dev_faq.md +++ b/docs/apworld_dev_faq.md @@ -122,3 +122,21 @@ Concrete examples of soft logic include: - Buying expensive shop items might logically require access to a place where you can quickly farm money, or logically require access to enough parts of the game that checking other locations should naturally generate enough money without grinding. Remember that all items referenced by logic (however hard or soft) must be `progression`. Since you typically don't want to turn a ton of `filler` items into `progression` just for this, it's common to e.g. write money logic using only the rare "$100" item, so the dozens of "$1" and "$10" items in your world can remain `filler`. + +--- + +### What if my game has "missable" or "one-time-only" locations or region connections? + +Archipelago logic assumes that once a region or location becomes reachable, it stays reachable forever, no matter what +the player does in-game. Slightly more formally: Receiving an AP item must never cause a region connection or location +to "go out of logic" (become unreachable when it was previously reachable), and receiving AP items is the only kind of +state change that AP logic acknowledges. No other actions or events can change reachability. + +So when the game itself does not follow this assumption, the options are: +- Modify the game to make that location/connection repeatable +- If there are both missable and repeatable ways to check the location/traverse the connection, then write logic for + only the repeatable ways +- Don't generate the missable location/connection at all + - For connections, any logical regions will still need to be reachable through other, *repeatable* connections + - For locations, this may require game changes to remove the vanilla item if it affects logic +- Decide that resetting the save file is part of the game's logic, and warn players about that From 11842d396ab11ca5099a8f071c38e004438eeae7 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 14 May 2025 04:23:12 -0700 Subject: [PATCH 0420/1218] DS3: Fix the Name of "Red and White Round Shield" (#4994) This item name is unusual in that it loses the word "round" when it's infused, *and* the only guaranteed drop in the base game is the infused "Blessed Red and White Round Shield +1". But since we're just listing the uninfused version, we should use the uninfused name. --- worlds/dark_souls_3/Items.py | 2 +- worlds/dark_souls_3/Locations.py | 5 +++-- worlds/dark_souls_3/docs/locations_en.md | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 044e3616f703..0980781ae882 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -511,7 +511,7 @@ def event(name: str, player: int) -> "DarkSouls3Item": DS3ItemData("Elkhorn Round Shield", 0x0133C510, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Warrior's Round Shield", 0x0133EC20, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Caduceus Round Shield", 0x01341330, DS3ItemCategory.SHIELD_INFUSIBLE), - DS3ItemData("Red and White Shield", 0x01343A40, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Red and White Round Shield", 0x01343A40, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Blessed Red and White Shield+1", 0x01343FB9, DS3ItemCategory.SHIELD), DS3ItemData("Plank Shield", 0x01346150, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Leather Shield", 0x01348860, DS3ItemCategory.SHIELD_INFUSIBLE), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 7b30997581dc..c84d91e516c2 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -732,8 +732,9 @@ def __init__( missable=True), # requires projectile DS3LocationData("US: Flame Stoneplate Ring - hanging corpse by Mound-Maker transport", "Flame Stoneplate Ring"), - DS3LocationData("US: Red and White Shield - chasm, hanging corpse", "Red and White Shield", - static="02,0:53100740::", missable=True), # requires projectile + DS3LocationData("US: Red and White Round Shield - chasm, hanging corpse", + "Red and White Round Shield", static="02,0:53100740::", + missable=True), # requires projectile DS3LocationData("US: Small Leather Shield - first building, hanging corpse by entrance", "Small Leather Shield"), DS3LocationData("US: Pale Tongue - tower village, hanging corpse", "Pale Tongue"), diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index 8411b8c42aa0..4f0160a96d99 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -2239,7 +2239,7 @@ static _Dark Souls III_ randomizer]. US: Pyromancy Flame - CornyxGiven by Cornyx in Firelink Shrine or dropped. US: Red Bug Pellet - tower village building, basementOn the floor of the building after the Fire Demon encounter US: Red Hilted Halberd - chasm cryptIn the skeleton area accessible from Grave Key or dropping down from near Eygon -US: Red and White Shield - chasm, hanging corpseOn a hanging corpse in the ravine accessible with the Grave Key or dropping down near Eygon, to the entrance of Irina's prison. Must be shot down with an arrow or projective. +US: Red and White Round Shield - chasm, hanging corpseOn a hanging corpse in the ravine accessible with the Grave Key or dropping down near Eygon, to the entrance of Irina's prison. Must be shot down with an arrow or projective. US: Reinforced Club - by white treeNear the Birch Tree where giant shoots arrows US: Repair Powder - first building, balconyOn the balcony of the first Undead Settlement building US: Rusted Coin - awning above Dilapidated BridgeOn a wooden ledge near the Dilapidated Bridge bonfire. Must be jumped to from near Cathedral Evangelist enemy From a87fec0cbd682148b7ee1aad84bea2552070af14 Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Wed, 14 May 2025 07:27:15 -0400 Subject: [PATCH 0421/1218] SDV: Add Missing Marriage Requirement for Spouse Stardrop (#4988) --- worlds/stardew_valley/rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index 51f69a1af853..ba71c058742a 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -864,7 +864,7 @@ def set_friendsanity_rules(logic: StardewLogic, multiworld: MultiWorld, player: if not content.features.friendsanity.is_enabled: return set_rule(multiworld.get_location("Spouse Stardrop", player), - logic.relationship.has_hearts_with_any_bachelor(13)) + logic.relationship.has_hearts_with_any_bachelor(13) & logic.relationship.can_get_married()) set_rule(multiworld.get_location("Have a Baby", player), logic.relationship.can_reproduce(1)) set_rule(multiworld.get_location("Have Another Baby", player), From 02fd75c018b7172ddad306a2851af482a753cfef Mon Sep 17 00:00:00 2001 From: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> Date: Wed, 14 May 2025 07:40:38 -0400 Subject: [PATCH 0422/1218] Core: Update Some Outdated Typing (#4986) --- Generate.py | 14 +++++----- Launcher.py | 13 +++++----- Main.py | 21 ++++++++------- settings.py | 59 ++++++++++++++++++++++--------------------- setup.py | 46 ++++++++++++++++----------------- test/hosting/world.py | 3 +-- 6 files changed, 77 insertions(+), 79 deletions(-) diff --git a/Generate.py b/Generate.py index e72887c26c2c..9bc8d1066f59 100644 --- a/Generate.py +++ b/Generate.py @@ -10,8 +10,8 @@ import urllib.parse import urllib.request from collections import Counter -from typing import Any, Dict, Tuple, Union from itertools import chain +from typing import Any import ModuleUpdate @@ -77,7 +77,7 @@ def get_seed_name(random_source) -> str: return f"{random_source.randint(0, pow(10, seeddigits) - 1)}".zfill(seeddigits) -def main(args=None) -> Tuple[argparse.Namespace, int]: +def main(args=None) -> tuple[argparse.Namespace, int]: # __name__ == "__main__" check so unittests that already imported worlds don't trip this. if __name__ == "__main__" and "worlds" in sys.modules: raise Exception("Worlds system should not be loaded before logging init.") @@ -95,7 +95,7 @@ def main(args=None) -> Tuple[argparse.Namespace, int]: logging.info("Race mode enabled. Using non-deterministic random source.") random.seed() # reset to time-based random source - weights_cache: Dict[str, Tuple[Any, ...]] = {} + weights_cache: dict[str, tuple[Any, ...]] = {} if args.weights_file_path and os.path.exists(args.weights_file_path): try: weights_cache[args.weights_file_path] = read_weights_yamls(args.weights_file_path) @@ -180,7 +180,7 @@ def main(args=None) -> Tuple[argparse.Namespace, int]: erargs.name = {} erargs.csv_output = args.csv_output - settings_cache: Dict[str, Tuple[argparse.Namespace, ...]] = \ + settings_cache: dict[str, tuple[argparse.Namespace, ...]] = \ {fname: (tuple(roll_settings(yaml, args.plando) for yaml in yamls) if args.sameoptions else None) for fname, yamls in weights_cache.items()} @@ -212,7 +212,7 @@ def main(args=None) -> Tuple[argparse.Namespace, int]: path = player_path_cache[player] if path: try: - settings: Tuple[argparse.Namespace, ...] = settings_cache[path] if settings_cache[path] else \ + settings: tuple[argparse.Namespace, ...] = settings_cache[path] if settings_cache[path] else \ tuple(roll_settings(yaml, args.plando) for yaml in weights_cache[path]) for settingsObject in settings: for k, v in vars(settingsObject).items(): @@ -242,7 +242,7 @@ def main(args=None) -> Tuple[argparse.Namespace, int]: return erargs, seed -def read_weights_yamls(path) -> Tuple[Any, ...]: +def read_weights_yamls(path) -> tuple[Any, ...]: try: if urllib.parse.urlparse(path).scheme in ('https', 'file'): yaml = str(urllib.request.urlopen(path).read(), "utf-8-sig") @@ -378,7 +378,7 @@ def update_weights(weights: dict, new_weights: dict, update_type: str, name: str return weights -def roll_meta_option(option_key, game: str, category_dict: Dict) -> Any: +def roll_meta_option(option_key, game: str, category_dict: dict) -> Any: from worlds import AutoWorldRegister if not game: diff --git a/Launcher.py b/Launcher.py index 594286fac576..503490243d87 100644 --- a/Launcher.py +++ b/Launcher.py @@ -16,9 +16,10 @@ import sys import urllib.parse import webbrowser +from collections.abc import Callable, Sequence from os.path import isfile from shutil import which -from typing import Callable, Optional, Sequence, Tuple, Union, Any +from typing import Any if __name__ == "__main__": import ModuleUpdate @@ -114,7 +115,7 @@ def update_settings(): ]) -def handle_uri(path: str, launch_args: Tuple[str, ...]) -> None: +def handle_uri(path: str, launch_args: tuple[str, ...]) -> None: url = urllib.parse.urlparse(path) queries = urllib.parse.parse_qs(url.query) launch_args = (path, *launch_args) @@ -162,7 +163,7 @@ def handle_uri(path: str, launch_args: Tuple[str, ...]) -> None: ).open() -def identify(path: Union[None, str]) -> Tuple[Union[None, str], Union[None, Component]]: +def identify(path: None | str) -> tuple[None | str, None | Component]: if path is None: return None, None for component in components: @@ -173,7 +174,7 @@ def identify(path: Union[None, str]) -> Tuple[Union[None, str], Union[None, Comp return None, None -def get_exe(component: Union[str, Component]) -> Optional[Sequence[str]]: +def get_exe(component: str | Component) -> Sequence[str] | None: if isinstance(component, str): name = component component = None @@ -226,7 +227,7 @@ def create_shortcut(button: Any, component: Component) -> None: button.menu.dismiss() -refresh_components: Optional[Callable[[], None]] = None +refresh_components: Callable[[], None] | None = None def run_gui(path: str, args: Any) -> None: @@ -451,7 +452,7 @@ def run_component(component: Component, *args): logging.warning(f"Component {component} does not appear to be executable.") -def main(args: Optional[Union[argparse.Namespace, dict]] = None): +def main(args: argparse.Namespace | dict | None = None): if isinstance(args, argparse.Namespace): args = {k: v for k, v in args._get_kwargs()} elif not args: diff --git a/Main.py b/Main.py index 147fa382e249..442c2ff40441 100644 --- a/Main.py +++ b/Main.py @@ -7,14 +7,13 @@ import time import zipfile import zlib -from typing import Dict, List, Optional, Set, Tuple, Union import worlds -from BaseClasses import CollectionState, Item, Location, LocationProgressType, MultiWorld, Region +from BaseClasses import CollectionState, Item, Location, LocationProgressType, MultiWorld from Fill import FillError, balance_multiworld_progression, distribute_items_restrictive, flood_items, \ parse_planned_blocks, distribute_planned_blocks, resolve_early_locations_for_planned from Options import StartInventoryPool -from Utils import __version__, output_path, version_tuple, get_settings +from Utils import __version__, output_path, version_tuple from settings import get_settings from worlds import AutoWorld from worlds.generic.Rules import exclusion_rules, locality_rules @@ -22,7 +21,7 @@ __all__ = ["main"] -def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = None): +def main(args, seed=None, baked_server_options: dict[str, object] | None = None): if not baked_server_options: baked_server_options = get_settings().server_options.as_dict() assert isinstance(baked_server_options, dict) @@ -140,7 +139,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No # remove starting inventory from pool items. # Because some worlds don't actually create items during create_items this has to be as late as possible. fallback_inventory = StartInventoryPool({}) - depletion_pool: Dict[int, Dict[str, int]] = { + depletion_pool: dict[int, dict[str, int]] = { player: getattr(multiworld.worlds[player].options, "start_inventory_from_pool", fallback_inventory).value.copy() for player in multiworld.player_ids } @@ -149,7 +148,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No } if target_per_player: - new_itempool: List[Item] = [] + new_itempool: list[Item] = [] # Make new itempool with start_inventory_from_pool items removed for item in multiworld.itempool: @@ -233,7 +232,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No pool.submit(AutoWorld.call_single, multiworld, "generate_output", player, temp_dir)) # collect ER hint info - er_hint_data: Dict[int, Dict[int, str]] = {} + er_hint_data: dict[int, dict[int, str]] = {} AutoWorld.call_all(multiworld, 'extend_hint_information', er_hint_data) def write_multidata(): @@ -274,7 +273,7 @@ def precollect_hint(location: Location, auto_status: HintStatus): for player in multiworld.groups[location.item.player]["players"]: precollected_hints[player].add(hint) - locations_data: Dict[int, Dict[int, Tuple[int, int, int]]] = {player: {} for player in multiworld.player_ids} + locations_data: dict[int, dict[int, tuple[int, int, int]]] = {player: {} for player in multiworld.player_ids} for location in multiworld.get_filled_locations(): if type(location.address) == int: assert location.item.code is not None, "item code None should be event, " \ @@ -303,12 +302,12 @@ def precollect_hint(location: Location, auto_status: HintStatus): } data_package["Archipelago"] = worlds.network_data_package["games"]["Archipelago"] - checks_in_area: Dict[int, Dict[str, Union[int, List[int]]]] = {} + checks_in_area: dict[int, dict[str, int | list[int]]] = {} # get spheres -> filter address==None -> skip empty - spheres: List[Dict[int, Set[int]]] = [] + spheres: list[dict[int, set[int]]] = [] for sphere in multiworld.get_sendable_spheres(): - current_sphere: Dict[int, Set[int]] = collections.defaultdict(set) + current_sphere: dict[int, set[int]] = collections.defaultdict(set) for sphere_location in sphere: current_sphere[sphere_location.player].add(sphere_location.address) diff --git a/settings.py b/settings.py index 255c537fe09a..ef1ea9adf741 100644 --- a/settings.py +++ b/settings.py @@ -10,9 +10,10 @@ import types import typing import warnings +from collections.abc import Iterator, Sequence from enum import IntEnum from threading import Lock -from typing import cast, Any, BinaryIO, ClassVar, Dict, Iterator, List, Optional, TextIO, Tuple, Union, TypeVar +from typing import cast, Any, BinaryIO, ClassVar, TextIO, TypeVar, Union __all__ = [ "get_settings", "fmt_doc", "no_gui", @@ -23,7 +24,7 @@ no_gui = False skip_autosave = False -_world_settings_name_cache: Dict[str, str] = {} # TODO: cache on disk and update when worlds change +_world_settings_name_cache: dict[str, str] = {} # TODO: cache on disk and update when worlds change _world_settings_name_cache_updated = False _lock = Lock() @@ -53,7 +54,7 @@ def fmt_doc(cls: type, level: int) -> str: class Group: - _type_cache: ClassVar[Optional[Dict[str, Any]]] = None + _type_cache: ClassVar[dict[str, Any] | None] = None _dumping: bool = False _has_attr: bool = False _changed: bool = False @@ -106,7 +107,7 @@ def changed(self) -> bool: self.__dict__.values())) @classmethod - def get_type_hints(cls) -> Dict[str, Any]: + def get_type_hints(cls) -> dict[str, Any]: """Returns resolved type hints for the class""" if cls._type_cache is None: if not cls.__annotations__ or not isinstance(next(iter(cls.__annotations__.values())), str): @@ -124,10 +125,10 @@ def get(self, key: str, default: Any = None) -> Any: return self[key] return default - def items(self) -> List[Tuple[str, Any]]: + def items(self) -> list[tuple[str, Any]]: return [(key, getattr(self, key)) for key in self] - def update(self, dct: Dict[str, Any]) -> None: + def update(self, dct: dict[str, Any]) -> None: assert isinstance(dct, dict), f"{self.__class__.__name__}.update called with " \ f"{dct.__class__.__name__} instead of dict." @@ -196,7 +197,7 @@ def update(self, dct: Dict[str, Any]) -> None: warnings.warn(f"{self.__class__.__name__}.{k} " f"assigned from incompatible type {type(v).__name__}") - def as_dict(self, *args: str, downcast: bool = True) -> Dict[str, Any]: + def as_dict(self, *args: str, downcast: bool = True) -> dict[str, Any]: return { name: _to_builtin(cast(object, getattr(self, name))) if downcast else getattr(self, name) for name in self if not args or name in args @@ -211,7 +212,7 @@ def _dump_value(cls, value: Any, f: TextIO, indent: str) -> None: f.write(f"{indent}{yaml_line}") @classmethod - def _dump_item(cls, name: Optional[str], attr: object, f: TextIO, level: int) -> None: + def _dump_item(cls, name: str | None, attr: object, f: TextIO, level: int) -> None: """Write a group, dict or sequence item to f, where attr can be a scalar or a collection""" # lazy construction of yaml Dumper to avoid loading Utils early @@ -223,7 +224,7 @@ class Dumper(BaseDumper): def represent_mapping(self, tag: str, mapping: Any, flow_style: Any = None) -> MappingNode: from yaml import ScalarNode res: MappingNode = super().represent_mapping(tag, mapping, flow_style) - pairs = cast(List[Tuple[ScalarNode, Any]], res.value) + pairs = cast(list[tuple[ScalarNode, Any]], res.value) for k, v in pairs: k.style = None # remove quotes from keys return res @@ -329,9 +330,9 @@ class Path(str): """Marks the file as required and opens a file browser when missing""" is_exe: bool = False """Special cross-platform handling for executables""" - description: Optional[str] = None + description: str | None = None """Title to display when browsing for the file""" - copy_to: Optional[str] = None + copy_to: str | None = None """If not None, copy to AP folder instead of linking it""" @classmethod @@ -339,7 +340,7 @@ def validate(cls, path: str) -> None: """Overload and raise to validate input files from browse""" pass - def browse(self: T, **kwargs: Any) -> Optional[T]: + def browse(self: T, **kwargs: Any) -> T | None: """Opens a file browser to search for the file""" raise NotImplementedError(f"Please use a subclass of Path for {self.__class__.__name__}") @@ -369,12 +370,12 @@ def resolve(self) -> str: class FilePath(Path): # path to a file - md5s: ClassVar[List[Union[str, bytes]]] = [] + md5s: ClassVar[list[str | bytes]] = [] """MD5 hashes for default validator.""" def browse(self: T, - filetypes: Optional[typing.Sequence[typing.Tuple[str, typing.Sequence[str]]]] = None, **kwargs: Any)\ - -> Optional[T]: + filetypes: Sequence[tuple[str, Sequence[str]]] | None = None, **kwargs: Any)\ + -> T | None: from Utils import open_filename, is_windows if not filetypes: if self.is_exe: @@ -439,7 +440,7 @@ def validate(cls, path: str) -> None: class FolderPath(Path): # path to a folder - def browse(self: T, **kwargs: Any) -> Optional[T]: + def browse(self: T, **kwargs: Any) -> T | None: from Utils import open_directory res = open_directory(f"Select {self.description or self.__class__.__name__}", self) if res: @@ -597,16 +598,16 @@ class LogNetwork(IntEnum): OFF = 0 ON = 1 - host: Optional[str] = None + host: str | None = None port: int = 38281 - password: Optional[str] = None - multidata: Optional[str] = None - savefile: Optional[str] = None + password: str | None = None + multidata: str | None = None + savefile: str | None = None disable_save: bool = False loglevel: str = "info" logtime: bool = False - server_password: Optional[ServerPassword] = None - disable_item_cheat: Union[DisableItemCheat, bool] = False + server_password: ServerPassword | None = None + disable_item_cheat: DisableItemCheat | bool = False location_check_points: LocationCheckPoints = LocationCheckPoints(1) hint_cost: HintCost = HintCost(10) release_mode: ReleaseMode = ReleaseMode("auto") @@ -702,7 +703,7 @@ class SnesRomStart(str): """ sni_path: SNIPath = SNIPath("SNI") - snes_rom_start: Union[SnesRomStart, bool] = True + snes_rom_start: SnesRomStart | bool = True class BizHawkClientOptions(Group): @@ -721,7 +722,7 @@ class RomStart(str): """ emuhawk_path: EmuHawkPath = EmuHawkPath(None) - rom_start: Union[RomStart, bool] = True + rom_start: RomStart | bool = True # Top-level group with lazy loading of worlds @@ -733,7 +734,7 @@ class Settings(Group): sni_options: SNIOptions = SNIOptions() bizhawkclient_options: BizHawkClientOptions = BizHawkClientOptions() - _filename: Optional[str] = None + _filename: str | None = None def __getattribute__(self, key: str) -> Any: if key.startswith("_") or key in self.__class__.__dict__: @@ -787,7 +788,7 @@ def __getattribute__(self, key: str) -> Any: return super().__getattribute__(key) - def __init__(self, location: Optional[str]): # change to PathLike[str] once we drop 3.8? + def __init__(self, location: str | None): # change to PathLike[str] once we drop 3.8? super().__init__() if location: from Utils import parse_yaml @@ -821,7 +822,7 @@ def autosave() -> None: import atexit atexit.register(autosave) - def save(self, location: Optional[str] = None) -> None: # as above + def save(self, location: str | None = None) -> None: # as above from Utils import parse_yaml location = location or self._filename assert location, "No file specified" @@ -854,7 +855,7 @@ def dump(self, f: TextIO, level: int = 0) -> None: super().dump(f, level) @property - def filename(self) -> Optional[str]: + def filename(self) -> str | None: return self._filename @@ -867,7 +868,7 @@ def get_settings() -> Settings: if not res: from Utils import user_path, local_path filenames = ("options.yaml", "host.yaml") - locations: List[str] = [] + locations: list[str] = [] if os.path.join(os.getcwd()) != local_path(): locations += filenames # use files from cwd only if it's not the local_path locations += [user_path(filename) for filename in filenames] diff --git a/setup.py b/setup.py index 8d415932d05d..2654cc69da92 100644 --- a/setup.py +++ b/setup.py @@ -1,22 +1,20 @@ import base64 import datetime +import io +import json import os import platform import shutil +import subprocess import sys import sysconfig +import threading +import urllib.request import warnings import zipfile -import urllib.request -import io -import json -import threading -import subprocess - +from collections.abc import Iterable, Sequence from hashlib import sha3_512 from pathlib import Path -from typing import Dict, Iterable, List, Optional, Sequence, Set, Tuple, Union - # This is a bit jank. We need cx-Freeze to be able to run anything from this script, so install it requirement = 'cx-Freeze==8.0.0' @@ -60,7 +58,7 @@ # On Python < 3.10 LogicMixin is not currently supported. -non_apworlds: Set[str] = { +non_apworlds: set[str] = { "A Link to the Past", "Adventure", "ArchipIDLE", @@ -147,7 +145,7 @@ def download_SNI() -> None: print(f"No SNI found for system spec {platform_name} {machine_name}") -signtool: Optional[str] +signtool: str | None if os.path.exists("X:/pw.txt"): print("Using signtool") with open("X:/pw.txt", encoding="utf-8-sig") as f: @@ -205,7 +203,7 @@ def remove_sprites_from_folder(folder: Path) -> None: os.remove(folder / file) -def _threaded_hash(filepath: Union[str, Path]) -> str: +def _threaded_hash(filepath: str | Path) -> str: hasher = sha3_512() hasher.update(open(filepath, "rb").read()) return base64.b85encode(hasher.digest()).decode() @@ -255,7 +253,7 @@ def finalize_options(self) -> None: self.libfolder = Path(self.buildfolder, "lib") self.library = Path(self.libfolder, "library.zip") - def installfile(self, path: Path, subpath: Optional[Union[str, Path]] = None, keep_content: bool = False) -> None: + def installfile(self, path: Path, subpath: str | Path | None = None, keep_content: bool = False) -> None: folder = self.buildfolder if subpath: folder /= subpath @@ -374,7 +372,7 @@ def run(self) -> None: from worlds.AutoWorld import AutoWorldRegister assert not non_apworlds - set(AutoWorldRegister.world_types), \ f"Unknown world {non_apworlds - set(AutoWorldRegister.world_types)} designated for .apworld" - folders_to_remove: List[str] = [] + folders_to_remove: list[str] = [] disabled_worlds_folder = "worlds_disabled" for entry in os.listdir(disabled_worlds_folder): if os.path.isdir(os.path.join(disabled_worlds_folder, entry)): @@ -446,12 +444,12 @@ class AppImageCommand(setuptools.Command): ("app-exec=", None, "The application to run inside the image."), ("yes", "y", 'Answer "yes" to all questions.'), ] - build_folder: Optional[Path] - dist_file: Optional[Path] - app_dir: Optional[Path] + build_folder: Path | None + dist_file: Path | None + app_dir: Path | None app_name: str - app_exec: Optional[Path] - app_icon: Optional[Path] # source file + app_exec: Path | None + app_icon: Path | None # source file app_id: str # lower case name, used for icon and .desktop yes: bool @@ -493,7 +491,7 @@ def write_launcher(self, default_exe: Path) -> None: """) launcher_filename.chmod(0o755) - def install_icon(self, src: Path, name: Optional[str] = None, symlink: Optional[Path] = None) -> None: + def install_icon(self, src: Path, name: str | None = None, symlink: Path | None = None) -> None: assert self.app_dir, "Invalid app_dir" try: from PIL import Image @@ -556,7 +554,7 @@ def run(self) -> None: subprocess.call(f'ARCH={build_arch} ./appimagetool -n "{self.app_dir}" "{self.dist_file}"', shell=True) -def find_libs(*args: str) -> Sequence[Tuple[str, str]]: +def find_libs(*args: str) -> Sequence[tuple[str, str]]: """Try to find system libraries to be included.""" if not args: return [] @@ -564,7 +562,7 @@ def find_libs(*args: str) -> Sequence[Tuple[str, str]]: arch = build_arch.replace('_', '-') libc = 'libc6' # we currently don't support musl - def parse(line: str) -> Tuple[Tuple[str, str, str], str]: + def parse(line: str) -> tuple[tuple[str, str, str], str]: lib, path = line.strip().split(' => ') lib, typ = lib.split(' ', 1) for test_arch in ('x86-64', 'i386', 'aarch64'): @@ -589,8 +587,8 @@ def parse(line: str) -> Tuple[Tuple[str, str, str], str]: k: v for k, v in (parse(line) for line in data if "=>" in line) } - def find_lib(lib: str, arch: str, libc: str) -> Optional[str]: - cache: Dict[Tuple[str, str, str], str] = getattr(find_libs, "cache") + def find_lib(lib: str, arch: str, libc: str) -> str | None: + cache: dict[tuple[str, str, str], str] = getattr(find_libs, "cache") for k, v in cache.items(): if k == (lib, arch, libc): return v @@ -599,7 +597,7 @@ def find_lib(lib: str, arch: str, libc: str) -> Optional[str]: return v return None - res: List[Tuple[str, str]] = [] + res: list[tuple[str, str]] = [] for arg in args: # try exact match, empty libc, empty arch, empty arch and libc file = find_lib(arg, arch, libc) diff --git a/test/hosting/world.py b/test/hosting/world.py index e083e027fee1..74126412017e 100644 --- a/test/hosting/world.py +++ b/test/hosting/world.py @@ -1,13 +1,12 @@ import re import shutil from pathlib import Path -from typing import Dict __all__ = ["copy", "delete"] -_new_worlds: Dict[str, str] = {} +_new_worlds: dict[str, str] = {} def copy(src: str, dst: str) -> None: From 2a0d0b4224eb818f83d0426f7c042a334608b41b Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Wed, 14 May 2025 07:55:45 -0400 Subject: [PATCH 0423/1218] Noita: Modernization Refactor (#4980) --- worlds/noita/__init__.py | 2 +- worlds/noita/events.py | 10 +++---- worlds/noita/items.py | 42 ++++++++++------------------ worlds/noita/locations.py | 10 +++---- worlds/noita/regions.py | 23 ++++++--------- worlds/noita/rules.py | 59 +++++++++++++++++---------------------- 6 files changed, 59 insertions(+), 87 deletions(-) diff --git a/worlds/noita/__init__.py b/worlds/noita/__init__.py index af2921768d6a..a0b94458c205 100644 --- a/worlds/noita/__init__.py +++ b/worlds/noita/__init__.py @@ -38,7 +38,7 @@ class NoitaWorld(World): web = NoitaWeb() def generate_early(self) -> None: - if not self.multiworld.get_player_name(self.player).isascii(): + if not self.player_name.isascii(): raise Exception("Noita yaml's slot name has invalid character(s).") # Returned items will be sent over to the client diff --git a/worlds/noita/events.py b/worlds/noita/events.py index 4ec04e98b457..2ae524d9ec87 100644 --- a/worlds/noita/events.py +++ b/worlds/noita/events.py @@ -1,4 +1,4 @@ -from typing import Dict, TYPE_CHECKING +from typing import TYPE_CHECKING from BaseClasses import Item, ItemClassification, Location, Region from . import items, locations @@ -6,7 +6,7 @@ from . import NoitaWorld -def create_event(player: int, name: str) -> Item: +def create_event_item(player: int, name: str) -> Item: return items.NoitaItem(name, ItemClassification.progression, None, player) @@ -16,13 +16,13 @@ def create_location(player: int, name: str, region: Region) -> Location: def create_locked_location_event(player: int, region: Region, item: str) -> Location: new_location = create_location(player, item, region) - new_location.place_locked_item(create_event(player, item)) + new_location.place_locked_item(create_event_item(player, item)) region.locations.append(new_location) return new_location -def create_all_events(world: "NoitaWorld", created_regions: Dict[str, Region]) -> None: +def create_all_events(world: "NoitaWorld", created_regions: dict[str, Region]) -> None: for region_name, event in event_locks.items(): region = created_regions[region_name] create_locked_location_event(world.player, region, event) @@ -31,7 +31,7 @@ def create_all_events(world: "NoitaWorld", created_regions: Dict[str, Region]) - # Maps region names to event names -event_locks: Dict[str, str] = { +event_locks: dict[str, str] = { "The Work": "Victory", "Mines": "Portal to Holy Mountain 1", "Coal Pits": "Portal to Holy Mountain 2", diff --git a/worlds/noita/items.py b/worlds/noita/items.py index 20d9ff1930de..4cd0b5ef87ff 100644 --- a/worlds/noita/items.py +++ b/worlds/noita/items.py @@ -1,6 +1,6 @@ import itertools from collections import Counter -from typing import Dict, List, NamedTuple, Set, TYPE_CHECKING +from typing import NamedTuple, TYPE_CHECKING from BaseClasses import Item, ItemClassification from .options import BossesAsChecks, VictoryCondition, ExtraOrbs @@ -27,12 +27,12 @@ def create_item(player: int, name: str) -> Item: return NoitaItem(name, item_data.classification, item_data.code, player) -def create_fixed_item_pool() -> List[str]: - required_items: Dict[str, int] = {name: data.required_num for name, data in item_table.items()} +def create_fixed_item_pool() -> list[str]: + required_items: dict[str, int] = {name: data.required_num for name, data in item_table.items()} return list(Counter(required_items).elements()) -def create_orb_items(victory_condition: VictoryCondition, extra_orbs: ExtraOrbs) -> List[str]: +def create_orb_items(victory_condition: VictoryCondition, extra_orbs: ExtraOrbs) -> list[str]: orb_count = extra_orbs.value if victory_condition == VictoryCondition.option_pure_ending: orb_count = orb_count + 11 @@ -41,15 +41,15 @@ def create_orb_items(victory_condition: VictoryCondition, extra_orbs: ExtraOrbs) return ["Orb" for _ in range(orb_count)] -def create_spatial_awareness_item(bosses_as_checks: BossesAsChecks) -> List[str]: +def create_spatial_awareness_item(bosses_as_checks: BossesAsChecks) -> list[str]: return ["Spatial Awareness Perk"] if bosses_as_checks.value >= BossesAsChecks.option_all_bosses else [] -def create_kantele(victory_condition: VictoryCondition) -> List[str]: +def create_kantele(victory_condition: VictoryCondition) -> list[str]: return ["Kantele"] if victory_condition.value >= VictoryCondition.option_pure_ending else [] -def create_random_items(world: NoitaWorld, weights: Dict[str, int], count: int) -> List[str]: +def create_random_items(world: NoitaWorld, weights: dict[str, int], count: int) -> list[str]: filler_pool = weights.copy() if not world.options.bad_effects: filler_pool["Trap"] = 0 @@ -87,7 +87,7 @@ def create_all_items(world: NoitaWorld) -> None: # 110000 - 110032 -item_table: Dict[str, ItemData] = { +item_table: dict[str, ItemData] = { "Trap": ItemData(110000, "Traps", ItemClassification.trap), "Extra Max HP": ItemData(110001, "Pickups", ItemClassification.useful), "Spell Refresher": ItemData(110002, "Pickups", ItemClassification.filler), @@ -122,7 +122,7 @@ def create_all_items(world: NoitaWorld) -> None: "Broken Wand": ItemData(110031, "Items", ItemClassification.filler), } -shop_only_filler_weights: Dict[str, int] = { +shop_only_filler_weights: dict[str, int] = { "Trap": 15, "Extra Max HP": 25, "Spell Refresher": 20, @@ -135,7 +135,7 @@ def create_all_items(world: NoitaWorld) -> None: "Extra Life Perk": 10, } -filler_weights: Dict[str, int] = { +filler_weights: dict[str, int] = { **shop_only_filler_weights, "Gold (200)": 15, "Gold (1000)": 6, @@ -152,22 +152,10 @@ def create_all_items(world: NoitaWorld) -> None: } -# These helper functions make the comprehensions below more readable -def get_item_group(item_name: str) -> str: - return item_table[item_name].group +filler_items: list[str] = list(filter(lambda item: item_table[item].classification == ItemClassification.filler, + item_table.keys())) +item_name_to_id: dict[str, int] = {name: data.code for name, data in item_table.items()} - -def item_is_filler(item_name: str) -> bool: - return item_table[item_name].classification == ItemClassification.filler - - -def item_is_perk(item_name: str) -> bool: - return item_table[item_name].group == "Perks" - - -filler_items: List[str] = list(filter(item_is_filler, item_table.keys())) -item_name_to_id: Dict[str, int] = {name: data.code for name, data in item_table.items()} - -item_name_groups: Dict[str, Set[str]] = { - group: set(item_names) for group, item_names in itertools.groupby(item_table, get_item_group) +item_name_groups: dict[str, set[str]] = { + group: set(item_names) for group, item_names in itertools.groupby(item_table, lambda item: item_table[item].group) } diff --git a/worlds/noita/locations.py b/worlds/noita/locations.py index 5dd87b5b0387..319955769ad0 100644 --- a/worlds/noita/locations.py +++ b/worlds/noita/locations.py @@ -1,6 +1,6 @@ # Locations are specific points that you would obtain an item at. from enum import IntEnum -from typing import Dict, NamedTuple, Optional, Set +from typing import NamedTuple from BaseClasses import Location @@ -27,7 +27,7 @@ class LocationFlag(IntEnum): # Only the first Hidden Chest and Pedestal are mapped here, the others are created in Regions. # ltype key: "Chest" = Hidden Chests, "Pedestal" = Pedestals, "Boss" = Boss, "Orb" = Orb. # 110000-110671 -location_region_mapping: Dict[str, Dict[str, LocationData]] = { +location_region_mapping: dict[str, dict[str, LocationData]] = { "Coal Pits Holy Mountain": { "Coal Pits Holy Mountain Shop Item 1": LocationData(110000), "Coal Pits Holy Mountain Shop Item 2": LocationData(110001), @@ -207,15 +207,15 @@ class LocationFlag(IntEnum): } -def make_location_range(location_name: str, base_id: int, amt: int) -> Dict[str, int]: +def make_location_range(location_name: str, base_id: int, amt: int) -> dict[str, int]: if amt == 1: return {location_name: base_id} return {f"{location_name} {i+1}": base_id + i for i in range(amt)} -location_name_groups: Dict[str, Set[str]] = {"Shop": set(), "Orb": set(), "Boss": set(), "Chest": set(), +location_name_groups: dict[str, set[str]] = {"Shop": set(), "Orb": set(), "Boss": set(), "Chest": set(), "Pedestal": set()} -location_name_to_id: Dict[str, int] = {} +location_name_to_id: dict[str, int] = {} for region_name, location_group in location_region_mapping.items(): diff --git a/worlds/noita/regions.py b/worlds/noita/regions.py index 184cd96018cf..55a0ad1fc8e1 100644 --- a/worlds/noita/regions.py +++ b/worlds/noita/regions.py @@ -1,5 +1,5 @@ # Regions are areas in your game that you travel to. -from typing import Dict, List, TYPE_CHECKING +from typing import TYPE_CHECKING from BaseClasses import Entrance, Region from . import locations @@ -36,28 +36,21 @@ def create_region(world: "NoitaWorld", region_name: str) -> Region: return new_region -def create_regions(world: "NoitaWorld") -> Dict[str, Region]: +def create_regions(world: "NoitaWorld") -> dict[str, Region]: return {name: create_region(world, name) for name in noita_regions} -# An "Entrance" is really just a connection between two regions -def create_entrance(player: int, source: str, destination: str, regions: Dict[str, Region]) -> Entrance: - entrance = Entrance(player, f"From {source} To {destination}", regions[source]) - entrance.connect(regions[destination]) - return entrance - - # Creates connections based on our access mapping in `noita_connections`. -def create_connections(player: int, regions: Dict[str, Region]) -> None: +def create_connections(regions: dict[str, Region]) -> None: for source, destinations in noita_connections.items(): - new_entrances = [create_entrance(player, source, destination, regions) for destination in destinations] - regions[source].exits = new_entrances + for destination in destinations: + regions[source].connect(regions[destination]) # Creates all regions and connections. Called from NoitaWorld. def create_all_regions_and_connections(world: "NoitaWorld") -> None: created_regions = create_regions(world) - create_connections(world.player, created_regions) + create_connections(created_regions) create_all_events(world, created_regions) world.multiworld.regions += created_regions.values() @@ -75,7 +68,7 @@ def create_all_regions_and_connections(world: "NoitaWorld") -> None: # - Lake is connected to The Laboratory, since the bosses are hard without specific set-ups (which means late game) # - Snowy Depths connects to Lava Lake orb since you need digging for it, so fairly early is acceptable # - Ancient Laboratory is connected to the Coal Pits, so that Ylialkemisti isn't sphere 1 -noita_connections: Dict[str, List[str]] = { +noita_connections: dict[str, list[str]] = { "Menu": ["Forest"], "Forest": ["Mines", "Floating Island", "Desert", "Snowy Wasteland"], "Frozen Vault": ["The Vault"], @@ -117,4 +110,4 @@ def create_all_regions_and_connections(world: "NoitaWorld") -> None: ### } -noita_regions: List[str] = sorted(set(noita_connections.keys()).union(*noita_connections.values())) +noita_regions: list[str] = sorted(set(noita_connections.keys()).union(*noita_connections.values())) diff --git a/worlds/noita/rules.py b/worlds/noita/rules.py index 65871a804ea0..c2c483248804 100644 --- a/worlds/noita/rules.py +++ b/worlds/noita/rules.py @@ -1,6 +1,5 @@ -from typing import List, NamedTuple, Set, TYPE_CHECKING +from typing import NamedTuple, TYPE_CHECKING -from BaseClasses import CollectionState from . import items, locations from .options import BossesAsChecks, VictoryCondition from worlds.generic import Rules as GenericRules @@ -16,7 +15,7 @@ class EntranceLock(NamedTuple): items_needed: int -entrance_locks: List[EntranceLock] = [ +entrance_locks: list[EntranceLock] = [ EntranceLock("Mines", "Coal Pits Holy Mountain", "Portal to Holy Mountain 1", 1), EntranceLock("Coal Pits", "Snowy Depths Holy Mountain", "Portal to Holy Mountain 2", 2), EntranceLock("Snowy Depths", "Hiisi Base Holy Mountain", "Portal to Holy Mountain 3", 3), @@ -27,7 +26,7 @@ class EntranceLock(NamedTuple): ] -holy_mountain_regions: List[str] = [ +holy_mountain_regions: list[str] = [ "Coal Pits Holy Mountain", "Snowy Depths Holy Mountain", "Hiisi Base Holy Mountain", @@ -38,7 +37,7 @@ class EntranceLock(NamedTuple): ] -wand_tiers: List[str] = [ +wand_tiers: list[str] = [ "Wand (Tier 1)", # Coal Pits "Wand (Tier 2)", # Snowy Depths "Wand (Tier 3)", # Hiisi Base @@ -48,29 +47,21 @@ class EntranceLock(NamedTuple): ] -items_hidden_from_shops: Set[str] = {"Gold (200)", "Gold (1000)", "Potion", "Random Potion", "Secret Potion", +items_hidden_from_shops: set[str] = {"Gold (200)", "Gold (1000)", "Potion", "Random Potion", "Secret Potion", "Chaos Die", "Greed Die", "Kammi", "Refreshing Gourd", "Sädekivi", "Broken Wand", "Powder Pouch"} -perk_list: List[str] = list(filter(items.item_is_perk, items.item_table.keys())) +perk_list: list[str] = list(filter(lambda item: items.item_table[item].group == "Perks", items.item_table.keys())) # ---------------- -# Helper Functions +# Helper Function # ---------------- -def has_perk_count(state: CollectionState, player: int, amount: int) -> bool: - return sum(state.count(perk, player) for perk in perk_list) >= amount - - -def has_orb_count(state: CollectionState, player: int, amount: int) -> bool: - return state.count("Orb", player) >= amount - - -def forbid_items_at_locations(world: "NoitaWorld", shop_locations: Set[str], forbidden_items: Set[str]) -> None: +def forbid_items_at_locations(world: "NoitaWorld", shop_locations: set[str], forbidden_items: set[str]) -> None: for shop_location in shop_locations: - location = world.multiworld.get_location(shop_location, world.player) + location = world.get_location(shop_location) GenericRules.forbid_items_for_player(location, forbidden_items, world.player) @@ -104,38 +95,38 @@ def ban_early_high_tier_wands(world: "NoitaWorld") -> None: def lock_holy_mountains_into_spheres(world: "NoitaWorld") -> None: for lock in entrance_locks: - location = world.multiworld.get_entrance(f"From {lock.source} To {lock.destination}", world.player) + location = world.get_entrance(f"{lock.source} -> {lock.destination}") GenericRules.set_rule(location, lambda state, evt=lock.event: state.has(evt, world.player)) def holy_mountain_unlock_conditions(world: "NoitaWorld") -> None: victory_condition = world.options.victory_condition.value for lock in entrance_locks: - location = world.multiworld.get_location(lock.event, world.player) + location = world.get_location(lock.event) if victory_condition == VictoryCondition.option_greed_ending: location.access_rule = lambda state, items_needed=lock.items_needed: ( - has_perk_count(state, world.player, items_needed//2) + state.has_group_unique("Perks", world.player, items_needed // 2) ) elif victory_condition == VictoryCondition.option_pure_ending: location.access_rule = lambda state, items_needed=lock.items_needed: ( - has_perk_count(state, world.player, items_needed//2) and - has_orb_count(state, world.player, items_needed) + state.has_group_unique("Perks", world.player, items_needed // 2) and + state.has("Orb", world.player, items_needed) ) elif victory_condition == VictoryCondition.option_peaceful_ending: location.access_rule = lambda state, items_needed=lock.items_needed: ( - has_perk_count(state, world.player, items_needed//2) and - has_orb_count(state, world.player, items_needed * 3) + state.has_group_unique("Perks", world.player, items_needed // 2) and + state.has("Orb", world.player, items_needed * 3) ) def biome_unlock_conditions(world: "NoitaWorld") -> None: - lukki_entrances = world.multiworld.get_region("Lukki Lair", world.player).entrances - magical_entrances = world.multiworld.get_region("Magical Temple", world.player).entrances - wizard_entrances = world.multiworld.get_region("Wizards' Den", world.player).entrances + lukki_entrances = world.get_region("Lukki Lair").entrances + magical_entrances = world.get_region("Magical Temple").entrances + wizard_entrances = world.get_region("Wizards' Den").entrances for entrance in lukki_entrances: - entrance.access_rule = lambda state: state.has("Melee Immunity Perk", world.player) and\ - state.has("All-Seeing Eye Perk", world.player) + entrance.access_rule = lambda state: ( + state.has_all(("Melee Immunity Perk", "All-Seeing Eye Perk"), world.player)) for entrance in magical_entrances: entrance.access_rule = lambda state: state.has("All-Seeing Eye Perk", world.player) for entrance in wizard_entrances: @@ -144,12 +135,12 @@ def biome_unlock_conditions(world: "NoitaWorld") -> None: def victory_unlock_conditions(world: "NoitaWorld") -> None: victory_condition = world.options.victory_condition.value - victory_location = world.multiworld.get_location("Victory", world.player) + victory_location = world.get_location("Victory") if victory_condition == VictoryCondition.option_pure_ending: - victory_location.access_rule = lambda state: has_orb_count(state, world.player, 11) + victory_location.access_rule = lambda state: state.has("Orb", world.player, 11) elif victory_condition == VictoryCondition.option_peaceful_ending: - victory_location.access_rule = lambda state: has_orb_count(state, world.player, 33) + victory_location.access_rule = lambda state: state.has("Orb", world.player, 33) # ---------------- @@ -168,5 +159,5 @@ def create_all_rules(world: "NoitaWorld") -> None: # Prevent the Map perk (used to find Toveri) from being on Toveri (boss) if world.options.bosses_as_checks.value >= BossesAsChecks.option_all_bosses: - toveri = world.multiworld.get_location("Toveri", world.player) + toveri = world.get_location("Toveri") GenericRules.forbid_items_for_player(toveri, {"Spatial Awareness Perk"}, world.player) From 15e6383aadc27eba861ab5391e3facb2f953881b Mon Sep 17 00:00:00 2001 From: el-u <109771707+el-u@users.noreply.github.com> Date: Thu, 15 May 2025 19:58:10 +0200 Subject: [PATCH 0424/1218] lufia2ac: rearrange tests to comply with new conventions (#5001) --- worlds/lufia2ac/test/__init__.py | 5 ----- worlds/lufia2ac/test/bases.py | 5 +++++ .../test/{TestCustomItemPool.py => test_custom_item_pool.py} | 2 +- worlds/lufia2ac/test/{TestGoal.py => test_goal.py} | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 worlds/lufia2ac/test/bases.py rename worlds/lufia2ac/test/{TestCustomItemPool.py => test_custom_item_pool.py} (98%) rename worlds/lufia2ac/test/{TestGoal.py => test_goal.py} (98%) diff --git a/worlds/lufia2ac/test/__init__.py b/worlds/lufia2ac/test/__init__.py index 306ffa771660..e69de29bb2d1 100644 --- a/worlds/lufia2ac/test/__init__.py +++ b/worlds/lufia2ac/test/__init__.py @@ -1,5 +0,0 @@ -from test.bases import WorldTestBase - - -class L2ACTestBase(WorldTestBase): - game = "Lufia II Ancient Cave" diff --git a/worlds/lufia2ac/test/bases.py b/worlds/lufia2ac/test/bases.py new file mode 100644 index 000000000000..306ffa771660 --- /dev/null +++ b/worlds/lufia2ac/test/bases.py @@ -0,0 +1,5 @@ +from test.bases import WorldTestBase + + +class L2ACTestBase(WorldTestBase): + game = "Lufia II Ancient Cave" diff --git a/worlds/lufia2ac/test/TestCustomItemPool.py b/worlds/lufia2ac/test/test_custom_item_pool.py similarity index 98% rename from worlds/lufia2ac/test/TestCustomItemPool.py rename to worlds/lufia2ac/test/test_custom_item_pool.py index 33f72273daae..2244b03f296b 100644 --- a/worlds/lufia2ac/test/TestCustomItemPool.py +++ b/worlds/lufia2ac/test/test_custom_item_pool.py @@ -2,7 +2,7 @@ from BaseClasses import PlandoOptions from Generate import handle_option -from . import L2ACTestBase +from .bases import L2ACTestBase from ..Options import CustomItemPool diff --git a/worlds/lufia2ac/test/TestGoal.py b/worlds/lufia2ac/test/test_goal.py similarity index 98% rename from worlds/lufia2ac/test/TestGoal.py rename to worlds/lufia2ac/test/test_goal.py index 1eaf5a151584..deb98ccac9c0 100644 --- a/worlds/lufia2ac/test/TestGoal.py +++ b/worlds/lufia2ac/test/test_goal.py @@ -1,4 +1,4 @@ -from . import L2ACTestBase +from .bases import L2ACTestBase class TestDefault(L2ACTestBase): From 90ee9ffe367a8766bea9b685ac5bdf6e43ee1f83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sat, 17 May 2025 09:20:53 -0400 Subject: [PATCH 0425/1218] Stardew Valley: Remove Crab Pot Requirement for Help Wanted Fishing (#4985) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/stardew_valley/logic/fishing_logic.py | 12 ++---------- worlds/stardew_valley/logic/skill_logic.py | 5 +++-- worlds/stardew_valley/regions.py | 5 +++-- worlds/stardew_valley/rules.py | 4 ++-- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/worlds/stardew_valley/logic/fishing_logic.py b/worlds/stardew_valley/logic/fishing_logic.py index c8f9e0a34080..544f322057e9 100644 --- a/worlds/stardew_valley/logic/fishing_logic.py +++ b/worlds/stardew_valley/logic/fishing_logic.py @@ -117,7 +117,7 @@ def has_specific_bait(self, fish: FishItem) -> StardewRule: @cached_property def can_crab_pot_anywhere(self) -> StardewRule: - return self.logic.fishing.can_fish() & self.logic.region.can_reach_any(fishing_regions) + return self.logic.fishing.can_crab_pot & self.logic.region.can_reach_any(fishing_regions) @cache_self1 def can_crab_pot_at(self, region: str) -> StardewRule: @@ -125,12 +125,4 @@ def can_crab_pot_at(self, region: str) -> StardewRule: @cached_property def can_crab_pot(self) -> StardewRule: - crab_pot_rule = self.logic.has(Fishing.bait) - - # We can't use the same rule if skills are vanilla, because fishing levels are required to crab pot, which is required to get fishing levels... - if self.content.features.skill_progression.is_progressive: - crab_pot_rule = crab_pot_rule & self.logic.has(Machine.crab_pot) - else: - crab_pot_rule = crab_pot_rule & self.logic.skill.can_get_fishing_xp - - return crab_pot_rule + return self.logic.has(Machine.crab_pot) & self.logic.has(Fishing.bait) diff --git a/worlds/stardew_valley/logic/skill_logic.py b/worlds/stardew_valley/logic/skill_logic.py index 7582e5240f2f..b582eb361329 100644 --- a/worlds/stardew_valley/logic/skill_logic.py +++ b/worlds/stardew_valley/logic/skill_logic.py @@ -34,7 +34,8 @@ def can_earn_level(self, skill: str, level: int) -> StardewRule: previous_level_rule = self.logic.skill.has_previous_level(skill, level) if skill == Skill.fishing: - xp_rule = self.logic.tool.has_fishing_rod(max(tool_level, 3)) + # Not checking crab pot as this is used for not randomized skills logic, for which players need a fishing rod to start gaining xp. + xp_rule = self.logic.tool.has_fishing_rod(max(tool_level, 3)) & self.logic.fishing.can_fish_anywhere() elif skill == Skill.farming: xp_rule = self.can_get_farming_xp & self.logic.tool.has_tool(Tool.hoe, tool_material) & self.logic.tool.can_water(tool_level) elif skill == Skill.foraging: @@ -134,7 +135,7 @@ def can_get_combat_xp(self) -> StardewRule: @cached_property def can_get_fishing_xp(self) -> StardewRule: if self.content.features.skill_progression.is_progressive: - return self.logic.fishing.can_fish_anywhere() | self.logic.fishing.can_crab_pot + return self.logic.fishing.can_fish_anywhere() | self.logic.fishing.can_crab_pot_anywhere return self.logic.fishing.can_fish_anywhere() diff --git a/worlds/stardew_valley/regions.py b/worlds/stardew_valley/regions.py index d5be53ba866c..4d06d598d32d 100644 --- a/worlds/stardew_valley/regions.py +++ b/worlds/stardew_valley/regions.py @@ -24,7 +24,8 @@ def __call__(self, name: str, regions: Iterable[str]) -> Region: RegionData(RegionName.farm, [Entrance.farm_to_backwoods, Entrance.farm_to_bus_stop, Entrance.farm_to_forest, Entrance.farm_to_farmcave, Entrance.enter_greenhouse, Entrance.enter_coop, Entrance.enter_barn, Entrance.enter_shed, Entrance.enter_slime_hutch, LogicEntrance.grow_spring_crops, - LogicEntrance.grow_summer_crops, LogicEntrance.grow_fall_crops, LogicEntrance.grow_winter_crops, LogicEntrance.shipping]), + LogicEntrance.grow_summer_crops, LogicEntrance.grow_fall_crops, LogicEntrance.grow_winter_crops, LogicEntrance.shipping, + LogicEntrance.fishing, ]), RegionData(RegionName.backwoods, [Entrance.backwoods_to_mountain]), RegionData(RegionName.bus_stop, [Entrance.bus_stop_to_town, Entrance.take_bus_to_desert, Entrance.bus_stop_to_tunnel_entrance]), @@ -54,7 +55,7 @@ def __call__(self, name: str, regions: Iterable[str]) -> Region: Entrance.purchase_movie_ticket, LogicEntrance.buy_experience_books, LogicEntrance.attend_egg_festival, LogicEntrance.attend_fair, LogicEntrance.attend_spirit_eve, LogicEntrance.attend_winter_star]), RegionData(RegionName.beach, - [Entrance.beach_to_willy_fish_shop, Entrance.enter_elliott_house, Entrance.enter_tide_pools, LogicEntrance.fishing, LogicEntrance.attend_luau, + [Entrance.beach_to_willy_fish_shop, Entrance.enter_elliott_house, Entrance.enter_tide_pools, LogicEntrance.attend_luau, LogicEntrance.attend_moonlight_jellies, LogicEntrance.attend_night_market, LogicEntrance.attend_squidfest]), RegionData(RegionName.railroad, [Entrance.enter_bathhouse_entrance, Entrance.enter_witch_warp_cave]), RegionData(RegionName.ranch), diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index ba71c058742a..e5d7e8863e5a 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -284,7 +284,7 @@ def set_skull_cavern_floor_entrance_rules(logic, multiworld, player): set_entrance_rule(multiworld, player, dig_to_skull_floor(floor), rule) -def set_skill_entrance_rules(logic, multiworld, player, world_options: StardewValleyOptions): +def set_skill_entrance_rules(logic: StardewLogic, multiworld, player, world_options: StardewValleyOptions): set_entrance_rule(multiworld, player, LogicEntrance.grow_spring_crops, logic.farming.has_farming_tools & logic.season.has_spring) set_entrance_rule(multiworld, player, LogicEntrance.grow_summer_crops, logic.farming.has_farming_tools & logic.season.has_summer) set_entrance_rule(multiworld, player, LogicEntrance.grow_fall_crops, logic.farming.has_farming_tools & logic.season.has_fall) @@ -299,7 +299,7 @@ def set_skill_entrance_rules(logic, multiworld, player, world_options: StardewVa set_entrance_rule(multiworld, player, LogicEntrance.grow_summer_fall_crops_in_summer, true_) set_entrance_rule(multiworld, player, LogicEntrance.grow_summer_fall_crops_in_fall, true_) - set_entrance_rule(multiworld, player, LogicEntrance.fishing, logic.skill.can_get_fishing_xp) + set_entrance_rule(multiworld, player, LogicEntrance.fishing, logic.fishing.can_fish_anywhere()) def set_blacksmith_entrance_rules(logic, multiworld, player): From d3dbdb4491fa2c6b03c6ba45f6a893478b9c3f8a Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Sun, 18 May 2025 18:08:39 -0500 Subject: [PATCH 0426/1218] Kivy: Add a button prompt box (#3470) * Kivy: Add a button prompt box * auto format the buttons to display 2 per row to look nicer * update to kivymd * have the uri popup use the new API * have messenger use the new API * make the buttonprompt import even more lazy * messenger needs to be lazy too * make the buttons take up the full dialog width --------- Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- Launcher.py | 40 +++----- data/client.kv | 5 + kvui.py | 54 +++++++++-- worlds/messenger/client_setup.py | 154 +++++++++++++++++++------------ 4 files changed, 160 insertions(+), 93 deletions(-) diff --git a/Launcher.py b/Launcher.py index 503490243d87..2520fd6b5f51 100644 --- a/Launcher.py +++ b/Launcher.py @@ -121,46 +121,28 @@ def handle_uri(path: str, launch_args: tuple[str, ...]) -> None: launch_args = (path, *launch_args) client_component = [] text_client_component = None - if "game" in queries: - game = queries["game"][0] - else: # TODO around 0.6.0 - this is for pre this change webhost uri's - game = "Archipelago" + game = queries["game"][0] for component in components: if component.supports_uri and component.game_name == game: client_component.append(component) elif component.display_name == "Text Client": text_client_component = component - from kvui import MDButton, MDButtonText - from kivymd.uix.dialog import MDDialog, MDDialogHeadlineText, MDDialogContentContainer, MDDialogSupportingText - from kivymd.uix.divider import MDDivider if not client_component: run_component(text_client_component, *launch_args) return else: - popup_text = MDDialogSupportingText(text="Select client to open and connect with.") - component_buttons = [MDDivider()] - for component in [text_client_component, *client_component]: - component_buttons.append(MDButton( - MDButtonText(text=component.display_name), - on_release=lambda *args, comp=component: run_component(comp, *launch_args), - style="text" - )) - component_buttons.append(MDDivider()) - - MDDialog( - # Headline - MDDialogHeadlineText(text="Connect to Multiworld"), - # Text - popup_text, - # Content - MDDialogContentContainer( - *component_buttons, - orientation="vertical" - ), - - ).open() + from kvui import ButtonsPrompt + component_options = { + text_client_component.display_name: text_client_component, + **{component.display_name: component for component in client_component} + } + popup = ButtonsPrompt("Connect to Multiworld", + "Select client to open and connect with.", + lambda component_name: run_component(component_options[component_name], *launch_args), + *component_options.keys()) + popup.open() def identify(path: None | str) -> tuple[None | str, None | Component]: diff --git a/data/client.kv b/data/client.kv index 562986cd17a4..53000dfe41f2 100644 --- a/data/client.kv +++ b/data/client.kv @@ -222,3 +222,8 @@ spacing: 10 size_hint_y: None height: self.minimum_height +: + valign: "middle" + halign: "center" + text_size: self.width, None + height: self.texture_size[1] diff --git a/kvui.py b/kvui.py index d0d965c30b22..172b7e554394 100644 --- a/kvui.py +++ b/kvui.py @@ -6,7 +6,6 @@ import io import pkgutil from collections import deque - assert "kivy" not in sys.modules, "kvui should be imported before kivy for frozen compatibility" if sys.platform == "win32": @@ -57,6 +56,7 @@ from kivy.uix.popup import Popup from kivy.uix.image import AsyncImage from kivymd.app import MDApp +from kivymd.uix.dialog import MDDialog, MDDialogHeadlineText, MDDialogSupportingText, MDDialogButtonContainer from kivymd.uix.gridlayout import MDGridLayout from kivymd.uix.floatlayout import MDFloatLayout from kivymd.uix.boxlayout import MDBoxLayout @@ -710,20 +710,62 @@ def _change_to_history_text_if_available(self, new_index: int) -> None: self.text = self._command_history[self._command_history_index] +class MessageBoxLabel(MDLabel): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self._label.refresh() + + class MessageBox(Popup): - class MessageBoxLabel(MDLabel): - def __init__(self, **kwargs): - super().__init__(**kwargs) - self._label.refresh() def __init__(self, title, text, error=False, **kwargs): - label = MessageBox.MessageBoxLabel(text=text) + label = MessageBoxLabel(text=text) separator_color = [217 / 255, 129 / 255, 122 / 255, 1.] if error else [47 / 255., 167 / 255., 212 / 255, 1.] super().__init__(title=title, content=label, size_hint=(0.5, None), width=max(100, int(label.width) + 40), separator_color=separator_color, **kwargs) self.height += max(0, label.height - 18) +class ButtonsPrompt(MDDialog): + def __init__(self, title: str, text: str, response: typing.Callable[[str], None], + *prompts: str, **kwargs) -> None: + """ + Customizable popup box that lets you create any number of buttons. The text of the pressed button is returned to + the callback. + + :param title: The title of the popup. + :param text: The message prompt in the popup. + :param response: A callable that will get called when the user presses a button. The prompt will not close + itself so should be done here if you want to close it when certain buttons are pressed. + :param prompts: Any number of strings to be used for the buttons. + """ + layout = MDBoxLayout(orientation="vertical") + label = MessageBoxLabel(text=text) + layout.add_widget(label) + + def on_release(button: MDButton, *args) -> None: + response(button.text) + + buttons = [MDDivider()] + for prompt in prompts: + button = MDButton( + MDButtonText(text=prompt, pos_hint={"center_x": 0.5, "center_y": 0.5}), + on_release=on_release, + style="text", + theme_width="Custom", + size_hint_x=1, + ) + button.text = prompt + buttons.extend([button, MDDivider()]) + + super().__init__( + MDDialogHeadlineText(text=title), + MDDialogSupportingText(text=text), + MDDialogButtonContainer(*buttons, orientation="vertical"), + **kwargs, + ) + + class ClientTabs(MDTabsSecondary): carousel: MDTabsCarousel lock_swiping = True diff --git a/worlds/messenger/client_setup.py b/worlds/messenger/client_setup.py index 6b98a1b44013..3ef1df75cc13 100644 --- a/worlds/messenger/client_setup.py +++ b/worlds/messenger/client_setup.py @@ -2,35 +2,28 @@ import io import logging import os.path +import requests import subprocess import urllib.request from shutil import which -from typing import Any +from typing import Any, Callable, TYPE_CHECKING from zipfile import ZipFile -from Utils import open_file - -import requests +from Utils import is_windows, messagebox, open_file, tuplize_version -from Utils import is_windows, messagebox, tuplize_version +if TYPE_CHECKING: + from kvui import ButtonsPrompt MOD_URL = "https://api.github.com/repos/alwaysintreble/TheMessengerRandomizerModAP/releases/latest" -def ask_yes_no_cancel(title: str, text: str) -> bool | None: - """ - Wrapper for tkinter.messagebox.askyesnocancel, that creates a popup dialog box with yes, no, and cancel buttons. +def create_yes_no_popup(title: str, text: str, callback: Callable[[str], None]) -> "ButtonsPrompt": + from kvui import ButtonsPrompt + buttons = ["Yes", "No", "Cancel"] - :param title: Title to be displayed at the top of the message box. - :param text: Text to be displayed inside the message box. - :return: Returns True if yes, False if no, None if cancel. - """ - from tkinter import Tk, messagebox - root = Tk() - root.withdraw() - ret = messagebox.askyesnocancel(title, text) - root.update() - return ret + prompt = ButtonsPrompt(title, text, callback, *buttons) + prompt.open() + return prompt def launch_game(*args) -> None: @@ -151,6 +144,76 @@ def available_mod_update(latest_version: str) -> bool: # one of the alpha builds return "alpha" in latest_version or tuplize_version(latest_version) > tuplize_version(installed_version) + def after_courier_install_popup(answer: str) -> None: + """Gets called if the user doesn't have courier installed. Handle the button they pressed.""" + nonlocal prompt + + prompt.dismiss() + if answer in ("No", "Cancel"): + return + logging.info("Installing Courier") + install_courier() + prompt = create_yes_no_popup("Install Mod", + "No randomizer mod detected. Would you like to install now?", + after_mod_install_popup) + + def after_mod_install_popup(answer: str) -> None: + """Gets called if the user has courier but mod isn't installed, or there's an available update.""" + nonlocal prompt + + prompt.dismiss() + if answer in ("No", "Cancel"): + return + logging.info("Installing Mod") + install_mod() + prompt = create_yes_no_popup("Launch Game", + "Courier and Game mod installed successfully. Launch game now?", + launch) + + def after_mod_update_popup(answer: str) -> None: + """Gets called if there's an available update.""" + nonlocal prompt + + prompt.dismiss() + if answer == "Cancel": + return + if answer == "Yes": + logging.info("Updating Mod") + install_mod() + prompt = create_yes_no_popup("Launch Game", + "Courier and Game mod installed successfully. Launch game now?", + launch) + else: + prompt = create_yes_no_popup("Launch Game", + "Game Mod not updated. Launch game now?", + launch) + + def launch(answer: str | None = None) -> None: + """Launch the game.""" + nonlocal args + + if prompt: + prompt.dismiss() + if answer and answer in ("No", "Cancel"): + return + + parser = argparse.ArgumentParser(description="Messenger Client Launcher") + parser.add_argument("url", type=str, nargs="?", help="Archipelago Webhost uri to auto connect to.") + args = parser.parse_args(args) + + if not is_windows: + if args.url: + open_file(f"steam://rungameid/764790//{args.url}/") + else: + open_file("steam://rungameid/764790") + else: + os.chdir(game_folder) + if args.url: + subprocess.Popen([MessengerWorld.settings.game_path, str(args.url)]) + else: + subprocess.Popen(MessengerWorld.settings.game_path) + os.chdir(working_directory) + from . import MessengerWorld try: game_folder = os.path.dirname(MessengerWorld.settings.game_path) @@ -172,49 +235,24 @@ def available_mod_update(latest_version: str) -> bool: except ImportError: pass if not courier_installed(): - should_install = ask_yes_no_cancel("Install Courier", - "No Courier installation detected. Would you like to install now?") - if not should_install: - return - logging.info("Installing Courier") - install_courier() + prompt = create_yes_no_popup("Install Courier", + "No Courier installation detected. Would you like to install now?", + after_courier_install_popup) + return if not mod_installed(): - should_install = ask_yes_no_cancel("Install Mod", - "No randomizer mod detected. Would you like to install now?") - if not should_install: - return - logging.info("Installing Mod") - install_mod() + prompt = create_yes_no_popup("Install Mod", + "No randomizer mod detected. Would you like to install now?", + after_mod_install_popup) + return else: latest = request_data(MOD_URL)["tag_name"] if available_mod_update(latest): - should_update = ask_yes_no_cancel("Update Mod", - f"New mod version detected. Would you like to update to {latest} now?") - if should_update: - logging.info("Updating mod") - install_mod() - elif should_update is None: - return - - if not args: - should_launch = ask_yes_no_cancel("Launch Game", - "Mod installed and up to date. Would you like to launch the game now?") - if not should_launch: + prompt = create_yes_no_popup("Update Mod", + f"New mod version detected. Would you like to update to {latest} now?", + after_mod_update_popup) return - parser = argparse.ArgumentParser(description="Messenger Client Launcher") - parser.add_argument("url", type=str, nargs="?", help="Archipelago Webhost uri to auto connect to.") - args = parser.parse_args(args) - - if not is_windows: - if args.url: - open_file(f"steam://rungameid/764790//{args.url}/") - else: - open_file("steam://rungameid/764790") - else: - os.chdir(game_folder) - if args.url: - subprocess.Popen([MessengerWorld.settings.game_path, str(args.url)]) - else: - subprocess.Popen(MessengerWorld.settings.game_path) - os.chdir(working_directory) + if not args: + prompt = create_yes_no_popup("Launch Game", + "Mod installed and up to date. Would you like to launch the game now?", + launch) From 07664c4d543431676ce24844a0abd44b9e6bf31b Mon Sep 17 00:00:00 2001 From: PoryGone <98504756+PoryGone@users.noreply.github.com> Date: Mon, 19 May 2025 18:48:31 -0400 Subject: [PATCH 0427/1218] SA2B: Logic Fixes (#5009) - Fixes Shadow's mission count being set by Sonic's mission count option - Fixes one small logic error on `Security Hall - 5` on Hard Logic difficulty - Removes stray character that was probably harmless --- worlds/sa2b/Missions.py | 2 +- worlds/sa2b/Rules.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/worlds/sa2b/Missions.py b/worlds/sa2b/Missions.py index 0c43834fb114..a5aac267a27a 100644 --- a/worlds/sa2b/Missions.py +++ b/worlds/sa2b/Missions.py @@ -241,7 +241,7 @@ def get_mission_count_table(multiworld: MultiWorld, world: World, player: int): sonic_active_missions = min(sonic_active_missions, world.options.sonic_mission_count.value) tails_active_missions = min(tails_active_missions, world.options.tails_mission_count.value) knuckles_active_missions = min(knuckles_active_missions, world.options.knuckles_mission_count.value) - shadow_active_missions = min(shadow_active_missions, world.options.sonic_mission_count.value) + shadow_active_missions = min(shadow_active_missions, world.options.shadow_mission_count.value) eggman_active_missions = min(eggman_active_missions, world.options.eggman_mission_count.value) rouge_active_missions = min(rouge_active_missions, world.options.rouge_mission_count.value) kart_active_missions = min(kart_active_missions, world.options.kart_mission_count.value) diff --git a/worlds/sa2b/Rules.py b/worlds/sa2b/Rules.py index 53edc686b638..9019a5b0330b 100644 --- a/worlds/sa2b/Rules.py +++ b/worlds/sa2b/Rules.py @@ -2257,7 +2257,7 @@ def set_mission_upgrade_rules_hard(multiworld: MultiWorld, world: World, player: add_rule_safe(multiworld, LocationName.weapons_bed_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule_safe(multiworld, LocationName.security_hall_5, player, - lambda state: state.has(ItemName.rouge_treasure_scope, player)) + lambda state: state.has(ItemName.rouge_pick_nails, player)) add_rule_safe(multiworld, LocationName.cosmic_wall_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) @@ -2971,7 +2971,7 @@ def set_mission_upgrade_rules_hard(multiworld: MultiWorld, world: World, player: add_rule(multiworld.get_location(LocationName.mission_street_lifebox_2, player), lambda state: (state.has(ItemName.tails_booster, player) and -- state.has(ItemName.tails_mystic_melody, player))) + state.has(ItemName.tails_mystic_melody, player))) add_rule(multiworld.get_location(LocationName.eternal_engine_lifebox_2, player), lambda state: state.has(ItemName.tails_booster, player)) From 9ac628f020bfa5999ce03208d8dcaa0528e4137c Mon Sep 17 00:00:00 2001 From: Seldom <38388947+Seldom-SE@users.noreply.github.com> Date: Tue, 20 May 2025 11:11:44 -0700 Subject: [PATCH 0428/1218] Terraria: remove 1.4.3-specific docs #5013 --- worlds/terraria/docs/setup_en.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/worlds/terraria/docs/setup_en.md b/worlds/terraria/docs/setup_en.md index 55a4df1df30d..b41595533743 100644 --- a/worlds/terraria/docs/setup_en.md +++ b/worlds/terraria/docs/setup_en.md @@ -10,13 +10,6 @@ and [tModLoader](https://store.steampowered.com/app/1281930/tModLoader/) on Stea 1. Subscribe to [the mod](https://steamcommunity.com/sharedfiles/filedetails/?id=2922217554) on Steam 2. Open tModLoader 3. Go to **Workshop -> Manage Mods** and enable the Archipelago mod - - If tModLoader states that you need version 1.4.3, follow the following steps - 1. Close tModLoader - 2. Right-Click tModLoader in Steam and select **Properties** - 3. Navigate to **Betas -> Beta Participation** - 4. Select **1.4.3-legacy - Legacy - Stable tModLoader for Terraria 1.4.3** - 5. Update tModLoader through Steam - 6. Open tModLoader and navigate back to the **Manage Mods** menu 4. tModLoader will say that it needs to refresh; exit this menu, and it will do this automatically 5. Once tModLoader finishes loading, the Archipelago mod is finished installing; you can now [connect to an Archipelago game](#joining-an-archipelago-game-in-terraria). From 485387ebbe93daa2bb8435568bcb8f7145a6d5ac Mon Sep 17 00:00:00 2001 From: SunCat Date: Tue, 20 May 2025 21:12:13 +0300 Subject: [PATCH 0429/1218] ChecksFinder: Update setup guide (#4973) * Update setup_en.md * Update worlds/checksfinder/docs/setup_en.md Co-authored-by: Scipio Wright * Update worlds/checksfinder/docs/setup_en.md Co-authored-by: Scipio Wright * Update worlds/checksfinder/docs/setup_en.md Co-authored-by: Scipio Wright --------- Co-authored-by: Scipio Wright --- worlds/checksfinder/docs/setup_en.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/worlds/checksfinder/docs/setup_en.md b/worlds/checksfinder/docs/setup_en.md index e15763ab3110..fc1fb518488f 100644 --- a/worlds/checksfinder/docs/setup_en.md +++ b/worlds/checksfinder/docs/setup_en.md @@ -3,7 +3,8 @@ ## Required Software - ChecksFinder from - the [Github releases Page for the game](https://github.com/jonloveslegos/ChecksFinder/releases) (latest version) + the [Github releases Page for the game](https://github.com/jonloveslegos/ChecksFinder/releases) (latest version), or + from the [itch.io Page for the game](https://suncat0.itch.io/checksfinder) (including web version) ## Configuring your YAML file @@ -18,13 +19,13 @@ You can customize your options by visiting the [ChecksFinder Player Options Page ## Joining a MultiWorld Game -1. Start ChecksFinder -2. Enter the following information: - - Enter the server url (starting from `wss://` for https connection like archipelago.gg, and starting from `ws://` for http connection and local multiserver) - - Enter server port - - Enter the name of the slot you wish to connect to - - Enter the room password (optional) - - Press `Play Online` to connect -3. Start playing! - -Game options and controls are described in the readme on the github repository for the game +1. Start ChecksFinder and press `Play Online` +2. Switch to the console window/tab +3. Enter the following information: + - Server url + - Server port + - The name of the slot you wish to connect to + - The room password (optional) +4. Press `Connect` to connect +5. Switch to the game window/tab +6. Start playing! From e0d31010664cc03e24900ccd7f4216c69647feac Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Tue, 20 May 2025 20:23:44 +0100 Subject: [PATCH 0430/1218] Core: Remove redundant reachable location counting in swap (#4990) `prev_state` starts off as a copy of `swap_state` and then `swap_state` collects `item_to_place`. Collecting an item must never reduce accessibility (otherwise generation breaks horribly), so it is guaranteed that `swap_state` will always be able to reach at least as many locations as `prev_state`, so `new_loc_count >= prev_loc_count` is always `True`. As a sideeffect of this change, this fixes generation of Pokemon Emerald with locally shuffled Badges/HMs when there are worlds with unconnected entrances present in the multiworld e.g. KH1. This is because this location counting did not respect `single_player_placement=True` and counted reachable locations across the entire multiworld. Fixes #4834 as a sideeffect of removing the redundant code. --- Fill.py | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/Fill.py b/Fill.py index ff59aa22cb47..d0a42c07ebcd 100644 --- a/Fill.py +++ b/Fill.py @@ -138,32 +138,21 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati # to clean that up later, so there is a chance generation fails. if (not single_player_placement or location.player == item_to_place.player) \ and location.can_fill(swap_state, item_to_place, perform_access_check): + # Add this item to the existing placement, and + # add the old item to the back of the queue + spot_to_fill = placements.pop(i) - # Verify placing this item won't reduce available locations, which would be a useless swap. - prev_state = swap_state.copy() - prev_loc_count = len( - multiworld.get_reachable_locations(prev_state)) + swap_count += 1 + swapped_items[placed_item.player, placed_item.name, unsafe] = swap_count - swap_state.collect(item_to_place, True) - new_loc_count = len( - multiworld.get_reachable_locations(swap_state)) + reachable_items[placed_item.player].appendleft( + placed_item) + item_pool.append(placed_item) - if new_loc_count >= prev_loc_count: - # Add this item to the existing placement, and - # add the old item to the back of the queue - spot_to_fill = placements.pop(i) + # cleanup at the end to hopefully get better errors + cleanup_required = True - swap_count += 1 - swapped_items[placed_item.player, placed_item.name, unsafe] = swap_count - - reachable_items[placed_item.player].appendleft( - placed_item) - item_pool.append(placed_item) - - # cleanup at the end to hopefully get better errors - cleanup_required = True - - break + break # Item can't be placed here, restore original item location.item = placed_item From 9adbd4031f74ab5066e2993bdc317b0466cc8c25 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 20 May 2025 23:55:16 +0200 Subject: [PATCH 0431/1218] Core: prepare worlds.Files for APWorldContainer (#4331) Co-authored-by: Doug Hoskisson --- worlds/Files.py | 62 +++++++++++++++++++++++++++--------------- worlds/factorio/Mod.py | 2 +- worlds/kh2/OpenKH.py | 4 +-- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/worlds/Files.py b/worlds/Files.py index 69a88218efd4..e451d08cd9a9 100644 --- a/worlds/Files.py +++ b/worlds/Files.py @@ -78,24 +78,15 @@ class InvalidDataError(Exception): class APContainer: - """A zipfile containing at least archipelago.json""" - version: int = container_version - compression_level: int = 9 - compression_method: int = zipfile.ZIP_DEFLATED - game: Optional[str] = None + """A zipfile containing at least archipelago.json, which contains a manifest json payload.""" + version: ClassVar[int] = container_version + compression_level: ClassVar[int] = 9 + compression_method: ClassVar[int] = zipfile.ZIP_DEFLATED - # instance attributes: path: Optional[str] - player: Optional[int] - player_name: str - server: str - def __init__(self, path: Optional[str] = None, player: Optional[int] = None, - player_name: str = "", server: str = ""): + def __init__(self, path: Optional[str] = None): self.path = path - self.player = player - self.player_name = player_name - self.server = server def write(self, file: Optional[Union[str, BinaryIO]] = None) -> None: zip_file = file if file else self.path @@ -135,31 +126,58 @@ def read(self, file: Optional[Union[str, BinaryIO]] = None) -> None: message = f"{arg0} - " raise InvalidDataError(f"{message}This might be the incorrect world version for this file") from e - def read_contents(self, opened_zipfile: zipfile.ZipFile) -> None: + def read_contents(self, opened_zipfile: zipfile.ZipFile) -> Dict[str, Any]: with opened_zipfile.open("archipelago.json", "r") as f: manifest = json.load(f) if manifest["compatible_version"] > self.version: raise Exception(f"File (version: {manifest['compatible_version']}) too new " f"for this handler (version: {self.version})") + return manifest + + def get_manifest(self) -> Dict[str, Any]: + return { + # minimum version of patch system expected for patching to be successful + "compatible_version": 5, + "version": container_version, + } + + +class APPlayerContainer(APContainer): + """A zipfile containing at least archipelago.json meant for a player""" + game: ClassVar[Optional[str]] = None + + player: Optional[int] + player_name: str + server: str + + def __init__(self, path: Optional[str] = None, player: Optional[int] = None, + player_name: str = "", server: str = ""): + super().__init__(path) + self.player = player + self.player_name = player_name + self.server = server + + def read_contents(self, opened_zipfile: zipfile.ZipFile) -> Dict[str, Any]: + manifest = super().read_contents(opened_zipfile) self.player = manifest["player"] self.server = manifest["server"] self.player_name = manifest["player_name"] + return manifest def get_manifest(self) -> Dict[str, Any]: - return { + manifest = super().get_manifest() + manifest.update({ "server": self.server, # allow immediate connection to server in multiworld. Empty string otherwise "player": self.player, "player_name": self.player_name, "game": self.game, - # minimum version of patch system expected for patching to be successful - "compatible_version": 5, - "version": container_version, - } + }) + return manifest -class APPatch(APContainer): +class APPatch(APPlayerContainer): """ - An `APContainer` that represents a patch file. + An `APPlayerContainer` that represents a patch file. It includes the `procedure` key in the manifest to indicate that it is a patch. Your implementation should inherit from this if your output file diff --git a/worlds/factorio/Mod.py b/worlds/factorio/Mod.py index 8ea0b24c3d27..eb305897f435 100644 --- a/worlds/factorio/Mod.py +++ b/worlds/factorio/Mod.py @@ -63,7 +63,7 @@ } -class FactorioModFile(worlds.Files.APContainer): +class FactorioModFile(worlds.Files.APPlayerContainer): game = "Factorio" compression_method = zipfile.ZIP_DEFLATED # Factorio can't load LZMA archives writing_tasks: List[Callable[[], Tuple[str, Union[str, bytes]]]] diff --git a/worlds/kh2/OpenKH.py b/worlds/kh2/OpenKH.py index 7226525d0c4b..985c9913abe8 100644 --- a/worlds/kh2/OpenKH.py +++ b/worlds/kh2/OpenKH.py @@ -8,10 +8,10 @@ from .Items import item_dictionary_table from .Locations import all_locations, SoraLevels, exclusion_table from .XPValues import lvlStats, formExp, soraExp -from worlds.Files import APContainer +from worlds.Files import APPlayerContainer -class KH2Container(APContainer): +class KH2Container(APPlayerContainer): game: str = 'Kingdom Hearts 2' def __init__(self, patch_data: dict, base_path: str, output_directory: str, From feef0f484d2c5851bbbcabfe9e8a1a3cb2965aef Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 21 May 2025 00:52:00 +0200 Subject: [PATCH 0432/1218] Core: disable worlds_disabled (#5014) --- .github/labeler.yml | 1 - docs/CODEOWNERS | 11 +- docs/world maintainer.md | 4 +- setup.py | 4 - worlds_disabled/README.md | 13 -- worlds_disabled/oribf/Items.py | 10 -- worlds_disabled/oribf/Locations.py | 262 ----------------------------- worlds_disabled/oribf/Options.py | 12 -- worlds_disabled/oribf/README.md | 7 - worlds_disabled/oribf/Regions.py | 251 --------------------------- worlds_disabled/oribf/Rules.py | 59 ------- worlds_disabled/oribf/RulesData.py | 6 - worlds_disabled/oribf/Types.py | 5 - worlds_disabled/oribf/__init__.py | 71 -------- 14 files changed, 3 insertions(+), 713 deletions(-) delete mode 100644 worlds_disabled/README.md delete mode 100644 worlds_disabled/oribf/Items.py delete mode 100644 worlds_disabled/oribf/Locations.py delete mode 100644 worlds_disabled/oribf/Options.py delete mode 100644 worlds_disabled/oribf/README.md delete mode 100644 worlds_disabled/oribf/Regions.py delete mode 100644 worlds_disabled/oribf/Rules.py delete mode 100644 worlds_disabled/oribf/RulesData.py delete mode 100644 worlds_disabled/oribf/Types.py delete mode 100644 worlds_disabled/oribf/__init__.py diff --git a/.github/labeler.yml b/.github/labeler.yml index 2743104f410e..d0aa61c8cfc0 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -21,7 +21,6 @@ - '!data/**' - '!.run/**' - '!.github/**' - - '!worlds_disabled/**' - '!worlds/**' - '!WebHost.py' - '!WebHostLib/**' diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index dee8a6fd25d2..b89f668c0472 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -232,7 +232,7 @@ ## Active Unmaintained Worlds # The following worlds in this repo are currently unmaintained, but currently still work in core. If any update breaks -# compatibility, these worlds may be moved to `worlds_disabled`. If you are interested in stepping up as maintainer for +# compatibility, these worlds may be deleted. If you are interested in stepping up as maintainer for # any of these worlds, please review `/docs/world maintainer.md` documentation. # Final Fantasy (1) @@ -241,15 +241,6 @@ # Ocarina of Time # /worlds/oot/ -## Disabled Unmaintained Worlds - -# The following worlds in this repo are currently unmaintained and disabled as they do not work in core. If you are -# interested in stepping up as maintainer for any of these worlds, please review `/docs/world maintainer.md` -# documentation. - -# Ori and the Blind Forest -# /worlds_disabled/oribf/ - ################### ## Documentation ## ################### diff --git a/docs/world maintainer.md b/docs/world maintainer.md index 17aacdf8c269..6971a9822744 100644 --- a/docs/world maintainer.md +++ b/docs/world maintainer.md @@ -65,5 +65,5 @@ date, voting members and final result in the commit message. ## Handling of Unmaintained Worlds -As long as worlds are known to work for the most part, they can stay included. Once a world becomes broken it shall be -moved from `worlds/` to `worlds_disabled/`. +As long as worlds are known to work for the most part, they can stay included. Once the world becomes broken, it shall +be deleted. diff --git a/setup.py b/setup.py index 2654cc69da92..ccca46390b02 100644 --- a/setup.py +++ b/setup.py @@ -373,10 +373,6 @@ def run(self) -> None: assert not non_apworlds - set(AutoWorldRegister.world_types), \ f"Unknown world {non_apworlds - set(AutoWorldRegister.world_types)} designated for .apworld" folders_to_remove: list[str] = [] - disabled_worlds_folder = "worlds_disabled" - for entry in os.listdir(disabled_worlds_folder): - if os.path.isdir(os.path.join(disabled_worlds_folder, entry)): - folders_to_remove.append(entry) generate_yaml_templates(self.buildfolder / "Players" / "Templates", False) for worldname, worldtype in AutoWorldRegister.world_types.items(): if worldname not in non_apworlds: diff --git a/worlds_disabled/README.md b/worlds_disabled/README.md deleted file mode 100644 index a7bffe222b14..000000000000 --- a/worlds_disabled/README.md +++ /dev/null @@ -1,13 +0,0 @@ -## Folder Purpose - -This folder is for already merged worlds that are unmaintained and currently broken. If you are interested in fixing and -stepping up as maintainer for any of these worlds, please review the [world maintainer](/docs/world%20maintainer.md) -documentation. - -## Information for Disabled Worlds - -For each disabled world, a README file can be found detailing when the world was disabled and the reasons that it -was disabled. In order to be considered for reactivation, these concerns should be handled at a bare minimum. However, -each world may have additional issues that also need to be handled, such as deprecated API calls or missing components. - - diff --git a/worlds_disabled/oribf/Items.py b/worlds_disabled/oribf/Items.py deleted file mode 100644 index 788b802de387..000000000000 --- a/worlds_disabled/oribf/Items.py +++ /dev/null @@ -1,10 +0,0 @@ -# generated by https://github.com/Berserker66/ori_rando_server -# do not edit manually - -from typing import Dict - -item_table: Dict[str, int] = \ - {'EX100': 262144, 'AC': 262145, 'Bash': 262146, 'HC': 262147, 'Plant': 262148, 'MapStone': 262149, 'ChargeFlame': 262150, 'ChargeJump': 262151, 'Climb': 262152, 'MS': 262153, 'Dash': 262154, 'EC': 262155, 'EX200': 262156, 'DoubleJump': 262157, 'EX15': 262158, 'Wind': 262159, 'KS': 262160, 'Water': 262161, 'Glide': 262162, 'Grenade': 262163, 'ForlornKey': 262164, 'CS': 262165, 'Stomp': 262166, 'HoruKey': 262167, 'WallJump': 262168, 'GinsoKey': 262169} - -default_pool: Dict[str, int] = \ - {'EX100': 53, 'AC': 33, 'Bash': 1, 'HC': 12, 'Plant': 24, 'MapStone': 9, 'ChargeFlame': 1, 'ChargeJump': 1, 'Climb': 1, 'MS': 9, 'Dash': 1, 'EC': 14, 'EX200': 29, 'DoubleJump': 1, 'EX15': 6, 'Wind': 1, 'KS': 40, 'Water': 1, 'Glide': 1, 'Grenade': 1, 'ForlornKey': 1, 'CS': 8, 'Stomp': 1, 'HoruKey': 1, 'WallJump': 1, 'GinsoKey': 1} \ No newline at end of file diff --git a/worlds_disabled/oribf/Locations.py b/worlds_disabled/oribf/Locations.py deleted file mode 100644 index 1522fb557ea1..000000000000 --- a/worlds_disabled/oribf/Locations.py +++ /dev/null @@ -1,262 +0,0 @@ -# generated by https://github.com/Berserker66/ori_rando_server -# do not edit manually - -from .Types import * - -locations_data = \ - {'AboveChargeFlameTreeExp': Location(code=262144, vanilla_item='EX100'), - 'AboveChargeJumpAbilityCell': Location(code=262145, vanilla_item='AC'), - 'AboveFourthHealth': Location(code=262146, vanilla_item='AC'), - 'AboveGrottoTeleporterExp': Location(code=262147, vanilla_item='EX100'), - 'BashAreaExp': Location(code=262148, vanilla_item='EX100'), - 'BashSkillTree': Location(code=262149, vanilla_item='SKBash'), - 'BelowGrottoTeleporterHealthCell': Location(code=262150, vanilla_item='HC'), - 'BelowGrottoTeleporterPlant': Location(code=262151, vanilla_item='Plant'), - 'BlackrootBoulderExp': Location(code=262152, vanilla_item='EX100'), - 'BlackrootMap': Location(code=262153, vanilla_item='MapStone'), - 'BlackrootTeleporterHealthCell': Location(code=262154, vanilla_item='HC'), - 'ChargeFlameAreaExp': Location(code=262155, vanilla_item='EX100'), - 'ChargeFlameAreaPlant': Location(code=262156, vanilla_item='Plant'), - 'ChargeFlameSkillTree': Location(code=262157, vanilla_item='SKChargeFlame'), - 'ChargeJumpSkillTree': Location(code=262158, vanilla_item='SKChargeJump'), - 'ClimbSkillTree': Location(code=262159, vanilla_item='SKClimb'), - 'DashAreaAbilityCell': Location(code=262160, vanilla_item='AC'), - 'DashAreaMapstone': Location(code=262161, vanilla_item='MS'), - 'DashAreaOrbRoomExp': Location(code=262162, vanilla_item='EX100'), - 'DashAreaPlant': Location(code=262163, vanilla_item='Plant'), - 'DashAreaRoofExp': Location(code=262164, vanilla_item='EX100'), - 'DashSkillTree': Location(code=262165, vanilla_item='SKDash'), - 'DeathGauntletEnergyCell': Location(code=262166, vanilla_item='EC'), - 'DeathGauntletExp': Location(code=262167, vanilla_item='EX100'), - 'DeathGauntletRoofHealthCell': Location(code=262168, vanilla_item='HC'), - 'DeathGauntletRoofPlant': Location(code=262169, vanilla_item='Plant'), - 'DeathGauntletStompSwim': Location(code=262170, vanilla_item='EX200'), - 'DeathGauntletSwimEnergyDoor': Location(code=262171, vanilla_item='AC'), - 'DoorWarpExp': Location(code=262172, vanilla_item='EX200'), - 'DoubleJumpAreaExp': Location(code=262173, vanilla_item='EX100'), - 'DoubleJumpSkillTree': Location(code=262174, vanilla_item='SKDoubleJump'), - 'FarLeftGumoHideoutExp': Location(code=262175, vanilla_item='EX100'), - 'FirstPickup': Location(code=262176, vanilla_item='EX15'), - 'ForlornEntranceExp': Location(code=262177, vanilla_item='EX200'), - 'ForlornEscape': Location(code=262178, vanilla_item='EVWind'), - 'ForlornHiddenSpiderExp': Location(code=262179, vanilla_item='EX100'), - 'ForlornKeystone1': Location(code=262180, vanilla_item='KS'), - 'ForlornKeystone2': Location(code=262181, vanilla_item='KS'), - 'ForlornKeystone3': Location(code=262182, vanilla_item='KS'), - 'ForlornKeystone4': Location(code=262183, vanilla_item='KS'), - 'ForlornMap': Location(code=262184, vanilla_item='MapStone'), - 'ForlornPlant': Location(code=262185, vanilla_item='Plant'), - 'FourthHealthCell': Location(code=262186, vanilla_item='HC'), - 'FronkeyFight': Location(code=262187, vanilla_item='EX15'), - 'FronkeyWalkRoof': Location(code=262188, vanilla_item='EX200'), - 'GinsoEscapeExit': Location(code=262189, vanilla_item='EVWater'), - 'GinsoEscapeHangingExp': Location(code=262190, vanilla_item='EX100'), - 'GinsoEscapeJumpPadExp': Location(code=262191, vanilla_item='EX100'), - 'GinsoEscapeProjectileExp': Location(code=262192, vanilla_item='EX100'), - 'GinsoEscapeSpiderExp': Location(code=262193, vanilla_item='EX200'), - 'GladesGrenadePool': Location(code=262194, vanilla_item='EX200'), - 'GladesGrenadeTree': Location(code=262195, vanilla_item='AC'), - 'GladesKeystone1': Location(code=262196, vanilla_item='KS'), - 'GladesKeystone2': Location(code=262197, vanilla_item='KS'), - 'GladesLaser': Location(code=262198, vanilla_item='EC'), - 'GladesLaserGrenade': Location(code=262199, vanilla_item='AC'), - 'GladesMainPool': Location(code=262200, vanilla_item='EX100'), - 'GladesMainPoolDeep': Location(code=262201, vanilla_item='EC'), - 'GladesMap': Location(code=262202, vanilla_item='MapStone'), - 'GladesMapKeystone': Location(code=262203, vanilla_item='KS'), - 'GlideSkillFeather': Location(code=262204, vanilla_item='SKGlide'), - 'GrenadeAreaAbilityCell': Location(code=262205, vanilla_item='AC'), - 'GrenadeAreaExp': Location(code=262206, vanilla_item='EX100'), - 'GrenadeSkillTree': Location(code=262207, vanilla_item='SKGrenade'), - 'GrottoEnergyDoorHealthCell': Location(code=262208, vanilla_item='HC'), - 'GrottoEnergyDoorSwim': Location(code=262209, vanilla_item='EX100'), - 'GrottoHideoutFallAbilityCell': Location(code=262210, vanilla_item='AC'), - 'GrottoLasersRoofExp': Location(code=262211, vanilla_item='EX100'), - 'GrottoSwampDrainAccessExp': Location(code=262212, vanilla_item='EX100'), - 'GrottoSwampDrainAccessPlant': Location(code=262213, vanilla_item='Plant'), - 'GroveAboveSpiderWaterEnergyCell': Location(code=262214, vanilla_item='EC'), - 'GroveAboveSpiderWaterExp': Location(code=262215, vanilla_item='EX200'), - 'GroveAboveSpiderWaterHealthCell': Location(code=262216, vanilla_item='HC'), - 'GroveSpiderWaterSwim': Location(code=262217, vanilla_item='EX100'), - 'GroveWaterStompAbilityCell': Location(code=262218, vanilla_item='AC'), - 'GumoHideoutCrusherExp': Location(code=262219, vanilla_item='EX100'), - 'GumoHideoutCrusherKeystone': Location(code=262220, vanilla_item='KS'), - 'GumoHideoutEnergyCell': Location(code=262221, vanilla_item='EC'), - 'GumoHideoutLeftHangingExp': Location(code=262222, vanilla_item='EX15'), - 'GumoHideoutMap': Location(code=262223, vanilla_item='MapStone'), - 'GumoHideoutMapstone': Location(code=262224, vanilla_item='MS'), - 'GumoHideoutMiniboss': Location(code=262225, vanilla_item='KS'), - 'GumoHideoutRedirectAbilityCell': Location(code=262226, vanilla_item='AC'), - 'GumoHideoutRedirectEnergyCell': Location(code=262227, vanilla_item='EC'), - 'GumoHideoutRedirectExp': Location(code=262228, vanilla_item='EX200'), - 'GumoHideoutRedirectPlant': Location(code=262229, vanilla_item='Plant'), - 'GumoHideoutRightHangingExp': Location(code=262230, vanilla_item='EX15'), - 'GumoHideoutRockfallExp': Location(code=262231, vanilla_item='EX100'), - 'GumonSeal': Location(code=262232, vanilla_item='EVForlornKey'), - 'HollowGroveMap': Location(code=262233, vanilla_item='MapStone'), - 'HollowGroveMapPlant': Location(code=262234, vanilla_item='Plant'), - 'HollowGroveMapstone': Location(code=262235, vanilla_item='MS'), - 'HollowGroveTreeAbilityCell': Location(code=262236, vanilla_item='AC'), - 'HollowGroveTreePlant': Location(code=262237, vanilla_item='Plant'), - 'HoruFieldsAbilityCell': Location(code=262238, vanilla_item='AC'), - 'HoruFieldsEnergyCell': Location(code=262239, vanilla_item='EC'), - 'HoruFieldsHealthCell': Location(code=262240, vanilla_item='HC'), - 'HoruFieldsHiddenExp': Location(code=262241, vanilla_item='EX200'), - 'HoruFieldsPlant': Location(code=262242, vanilla_item='Plant'), - 'HoruL1': Location(code=262243, vanilla_item='CS'), - 'HoruL2': Location(code=262244, vanilla_item='CS'), - 'HoruL3': Location(code=262245, vanilla_item='CS'), - 'HoruL4': Location(code=262246, vanilla_item='CS'), - 'HoruL4ChaseExp': Location(code=262247, vanilla_item='EX200'), - 'HoruL4LowerExp': Location(code=262248, vanilla_item='EX200'), - 'HoruLavaDrainedLeftExp': Location(code=262249, vanilla_item='EX200'), - 'HoruLavaDrainedRightExp': Location(code=262250, vanilla_item='EX200'), - 'HoruMap': Location(code=262251, vanilla_item='MapStone'), - 'HoruR1': Location(code=262252, vanilla_item='CS'), - 'HoruR1EnergyCell': Location(code=262253, vanilla_item='EC'), - 'HoruR1HangingExp': Location(code=262254, vanilla_item='EX100'), - 'HoruR1Mapstone': Location(code=262255, vanilla_item='MS'), - 'HoruR2': Location(code=262256, vanilla_item='CS'), - 'HoruR3': Location(code=262257, vanilla_item='CS'), - 'HoruR3Plant': Location(code=262258, vanilla_item='Plant'), - 'HoruR4': Location(code=262259, vanilla_item='CS'), - 'HoruR4DrainedExp': Location(code=262260, vanilla_item='EX200'), - 'HoruR4LaserExp': Location(code=262261, vanilla_item='EX200'), - 'HoruR4StompExp': Location(code=262262, vanilla_item='EX200'), - 'HoruTeleporterExp': Location(code=262263, vanilla_item='EX200'), - 'IcelessExp': Location(code=262264, vanilla_item='EX100'), - 'InnerSwampDrainExp': Location(code=262265, vanilla_item='EX100'), - 'InnerSwampEnergyCell': Location(code=262266, vanilla_item='EC'), - 'InnerSwampHiddenSwimExp': Location(code=262267, vanilla_item='EX100'), - 'InnerSwampStompExp': Location(code=262268, vanilla_item='EX100'), - 'InnerSwampSwimLeftKeystone': Location(code=262269, vanilla_item='KS'), - 'InnerSwampSwimMapstone': Location(code=262270, vanilla_item='MS'), - 'InnerSwampSwimRightKeystone': Location(code=262271, vanilla_item='KS'), - 'KuroPerchExp': Location(code=262272, vanilla_item='EX200'), - 'LeftGladesExp': Location(code=262273, vanilla_item='EX15'), - 'LeftGladesHiddenExp': Location(code=262274, vanilla_item='EX15'), - 'LeftGladesKeystone': Location(code=262275, vanilla_item='KS'), - 'LeftGladesMapstone': Location(code=262276, vanilla_item='MS'), - 'LeftGrottoTeleporterExp': Location(code=262277, vanilla_item='EX200'), - 'LeftGumoHideoutExp': Location(code=262278, vanilla_item='EX100'), - 'LeftGumoHideoutHealthCell': Location(code=262279, vanilla_item='HC'), - 'LeftGumoHideoutLowerPlant': Location(code=262280, vanilla_item='Plant'), - 'LeftGumoHideoutSwim': Location(code=262281, vanilla_item='EX100'), - 'LeftGumoHideoutUpperPlant': Location(code=262282, vanilla_item='Plant'), - 'LeftSorrowAbilityCell': Location(code=262283, vanilla_item='AC'), - 'LeftSorrowEnergyCell': Location(code=262284, vanilla_item='EC'), - 'LeftSorrowGrenade': Location(code=262285, vanilla_item='EX200'), - 'LeftSorrowKeystone1': Location(code=262286, vanilla_item='KS'), - 'LeftSorrowKeystone2': Location(code=262287, vanilla_item='KS'), - 'LeftSorrowKeystone3': Location(code=262288, vanilla_item='KS'), - 'LeftSorrowKeystone4': Location(code=262289, vanilla_item='KS'), - 'LeftSorrowPlant': Location(code=262290, vanilla_item='Plant'), - 'LostGroveAbilityCell': Location(code=262291, vanilla_item='AC'), - 'LostGroveHiddenExp': Location(code=262292, vanilla_item='EX100'), - 'LostGroveLongSwim': Location(code=262293, vanilla_item='AC'), - 'LostGroveTeleporter': Location(code=262294, vanilla_item='EX100'), - 'LowerBlackrootAbilityCell': Location(code=262295, vanilla_item='AC'), - 'LowerBlackrootGrenadeThrow': Location(code=262296, vanilla_item='AC'), - 'LowerBlackrootLaserAbilityCell': Location(code=262297, vanilla_item='AC'), - 'LowerBlackrootLaserExp': Location(code=262298, vanilla_item='EX100'), - 'LowerGinsoHiddenExp': Location(code=262299, vanilla_item='EX100'), - 'LowerGinsoKeystone1': Location(code=262300, vanilla_item='KS'), - 'LowerGinsoKeystone2': Location(code=262301, vanilla_item='KS'), - 'LowerGinsoKeystone3': Location(code=262302, vanilla_item='KS'), - 'LowerGinsoKeystone4': Location(code=262303, vanilla_item='KS'), - 'LowerGinsoPlant': Location(code=262304, vanilla_item='Plant'), - 'LowerValleyExp': Location(code=262305, vanilla_item='EX100'), - 'LowerValleyMapstone': Location(code=262306, vanilla_item='MS'), - 'MistyAbilityCell': Location(code=262307, vanilla_item='AC'), - 'MistyEntranceStompExp': Location(code=262308, vanilla_item='EX100'), - 'MistyEntranceTreeExp': Location(code=262309, vanilla_item='EX100'), - 'MistyFrogNookExp': Location(code=262310, vanilla_item='EX100'), - 'MistyGrenade': Location(code=262311, vanilla_item='EX200'), - 'MistyKeystone1': Location(code=262312, vanilla_item='KS'), - 'MistyKeystone2': Location(code=262313, vanilla_item='KS'), - 'MistyKeystone3': Location(code=262314, vanilla_item='KS'), - 'MistyKeystone4': Location(code=262315, vanilla_item='KS'), - 'MistyMortarCorridorHiddenExp': Location(code=262316, vanilla_item='EX100'), - 'MistyMortarCorridorUpperExp': Location(code=262317, vanilla_item='EX100'), - 'MistyPlant': Location(code=262318, vanilla_item='Plant'), - 'MistyPostClimbAboveSpikePit': Location(code=262319, vanilla_item='EX200'), - 'MistyPostClimbSpikeCave': Location(code=262320, vanilla_item='EX100'), - 'MoonGrottoStompPlant': Location(code=262321, vanilla_item='Plant'), - 'OuterSwampAbilityCell': Location(code=262322, vanilla_item='AC'), - 'OuterSwampGrenadeExp': Location(code=262323, vanilla_item='EX200'), - 'OuterSwampHealthCell': Location(code=262324, vanilla_item='HC'), - 'OuterSwampMortarAbilityCell': Location(code=262325, vanilla_item='AC'), - 'OuterSwampMortarPlant': Location(code=262326, vanilla_item='Plant'), - 'OuterSwampStompExp': Location(code=262327, vanilla_item='EX100'), - 'OutsideForlornCliffExp': Location(code=262328, vanilla_item='EX200'), - 'OutsideForlornTreeExp': Location(code=262329, vanilla_item='EX100'), - 'OutsideForlornWaterExp': Location(code=262330, vanilla_item='EX100'), - 'RazielNo': Location(code=262331, vanilla_item='EX100'), - 'RightForlornHealthCell': Location(code=262332, vanilla_item='HC'), - 'RightForlornPlant': Location(code=262333, vanilla_item='Plant'), - 'SorrowEntranceAbilityCell': Location(code=262334, vanilla_item='AC'), - 'SorrowHealthCell': Location(code=262335, vanilla_item='HC'), - 'SorrowHiddenKeystone': Location(code=262336, vanilla_item='KS'), - 'SorrowLowerLeftKeystone': Location(code=262337, vanilla_item='KS'), - 'SorrowMainShaftKeystone': Location(code=262338, vanilla_item='KS'), - 'SorrowMap': Location(code=262339, vanilla_item='MapStone'), - 'SorrowMapstone': Location(code=262340, vanilla_item='MS'), - 'SorrowSpikeKeystone': Location(code=262341, vanilla_item='KS'), - 'SpiderSacEnergyCell': Location(code=262342, vanilla_item='EC'), - 'SpiderSacEnergyDoor': Location(code=262343, vanilla_item='AC'), - 'SpiderSacGrenadeDoor': Location(code=262344, vanilla_item='AC'), - 'SpiderSacHealthCell': Location(code=262345, vanilla_item='HC'), - 'SpiritCavernsAbilityCell': Location(code=262346, vanilla_item='AC'), - 'SpiritCavernsKeystone1': Location(code=262347, vanilla_item='KS'), - 'SpiritCavernsKeystone2': Location(code=262348, vanilla_item='KS'), - 'SpiritCavernsTopLeftKeystone': Location(code=262349, vanilla_item='KS'), - 'SpiritCavernsTopRightKeystone': Location(code=262350, vanilla_item='KS'), - 'StompAreaExp': Location(code=262351, vanilla_item='EX100'), - 'StompAreaGrenadeExp': Location(code=262352, vanilla_item='EX200'), - 'StompAreaRoofExp': Location(code=262353, vanilla_item='EX200'), - 'StompSkillTree': Location(code=262354, vanilla_item='SKStomp'), - 'Sunstone': Location(code=262355, vanilla_item='EVHoruKey'), - 'SunstonePlant': Location(code=262356, vanilla_item='Plant'), - 'SwampEntranceAbilityCell': Location(code=262357, vanilla_item='AC'), - 'SwampEntrancePlant': Location(code=262358, vanilla_item='Plant'), - 'SwampEntranceSwim': Location(code=262359, vanilla_item='EX200'), - 'SwampMap': Location(code=262360, vanilla_item='MapStone'), - 'SwampTeleporterAbilityCell': Location(code=262361, vanilla_item='AC'), - 'TopGinsoLeftLowerExp': Location(code=262362, vanilla_item='EX100'), - 'TopGinsoLeftUpperExp': Location(code=262363, vanilla_item='EX100'), - 'TopGinsoRightPlant': Location(code=262364, vanilla_item='Plant'), - 'UpperGinsoEnergyCell': Location(code=262365, vanilla_item='EC'), - 'UpperGinsoLowerKeystone': Location(code=262366, vanilla_item='KS'), - 'UpperGinsoRedirectLowerExp': Location(code=262367, vanilla_item='EX100'), - 'UpperGinsoRedirectUpperExp': Location(code=262368, vanilla_item='EX100'), - 'UpperGinsoRightKeystone': Location(code=262369, vanilla_item='KS'), - 'UpperGinsoUpperLeftKeystone': Location(code=262370, vanilla_item='KS'), - 'UpperGinsoUpperRightKeystone': Location(code=262371, vanilla_item='KS'), - 'UpperSorrowFarLeftKeystone': Location(code=262372, vanilla_item='KS'), - 'UpperSorrowFarRightKeystone': Location(code=262373, vanilla_item='KS'), - 'UpperSorrowLeftKeystone': Location(code=262374, vanilla_item='KS'), - 'UpperSorrowRightKeystone': Location(code=262375, vanilla_item='KS'), - 'UpperSorrowSpikeExp': Location(code=262376, vanilla_item='EX100'), - 'ValleyEntryAbilityCell': Location(code=262377, vanilla_item='AC'), - 'ValleyEntryGrenadeLongSwim': Location(code=262378, vanilla_item='EC'), - 'ValleyEntryTreeExp': Location(code=262379, vanilla_item='EX100'), - 'ValleyEntryTreePlant': Location(code=262380, vanilla_item='Plant'), - 'ValleyForlornApproachGrenade': Location(code=262381, vanilla_item='AC'), - 'ValleyForlornApproachMapstone': Location(code=262382, vanilla_item='MS'), - 'ValleyMainFACS': Location(code=262383, vanilla_item='AC'), - 'ValleyMainPlant': Location(code=262384, vanilla_item='Plant'), - 'ValleyMap': Location(code=262385, vanilla_item='MapStone'), - 'ValleyRightBirdStompCell': Location(code=262386, vanilla_item='AC'), - 'ValleyRightExp': Location(code=262387, vanilla_item='EX100'), - 'ValleyRightFastStomplessCell': Location(code=262388, vanilla_item='AC'), - 'ValleyRightSwimExp': Location(code=262389, vanilla_item='EX100'), - 'ValleyThreeBirdAbilityCell': Location(code=262390, vanilla_item='AC'), - 'WallJumpAreaEnergyCell': Location(code=262391, vanilla_item='EC'), - 'WallJumpAreaExp': Location(code=262392, vanilla_item='EX200'), - 'WallJumpSkillTree': Location(code=262393, vanilla_item='SKWallJump'), - 'WaterVein': Location(code=262394, vanilla_item='EVGinsoKey'), - 'WilhelmExp': Location(code=262395, vanilla_item='EX200')} - - - -lookup_name_to_id = {location_name: location_data.code for location_name, location_data in locations_data.items()} \ No newline at end of file diff --git a/worlds_disabled/oribf/Options.py b/worlds_disabled/oribf/Options.py deleted file mode 100644 index ac6808aa8d34..000000000000 --- a/worlds_disabled/oribf/Options.py +++ /dev/null @@ -1,12 +0,0 @@ -from .RulesData import location_rules -from Options import Toggle - - -options = { - "open" : Toggle, - "openworld": Toggle -} - -for logic_set in location_rules: - if logic_set != "casual-core": - options[logic_set.replace("-", "_")] = Toggle diff --git a/worlds_disabled/oribf/README.md b/worlds_disabled/oribf/README.md deleted file mode 100644 index 0c78c23bea0d..000000000000 --- a/worlds_disabled/oribf/README.md +++ /dev/null @@ -1,7 +0,0 @@ -### Ori and the Blind Forest - -This world was disabled for the following reasons: - -* Missing client -* Unmaintained -* Outdated, fails tests as of Jun 29, 2023 diff --git a/worlds_disabled/oribf/Regions.py b/worlds_disabled/oribf/Regions.py deleted file mode 100644 index c86608732cdf..000000000000 --- a/worlds_disabled/oribf/Regions.py +++ /dev/null @@ -1,251 +0,0 @@ -# generated by https://github.com/Berserker66/ori_rando_server -# do not edit manually - -locations_by_region = \ - {'AboveChargeJumpArea': {'AboveChargeJumpAbilityCell'}, 'BashTree': {'BashAreaExp', 'BashSkillTree'}, - 'BashTreeDoorClosed': set(), 'BashTreeDoorOpened': set(), 'BelowSunstoneArea': set(), - 'BlackrootDarknessRoom': {'DashAreaOrbRoomExp', 'DashAreaAbilityCell', 'DashAreaRoofExp'}, - 'BlackrootGrottoConnection': {'BlackrootBoulderExp', 'BlackrootMap', 'BlackrootTeleporterHealthCell'}, - 'ChargeFlameAreaPlantAccess': {'ChargeFlameAreaPlant'}, 'ChargeFlameAreaStump': set(), - 'ChargeFlameSkillTreeChamber': {'ChargeFlameSkillTree'}, 'ChargeJumpArea': {'ChargeJumpSkillTree'}, - 'ChargeJumpDoor': set(), 'ChargeJumpDoorOpen': set(), - 'ChargeJumpDoorOpenLeft': {'UpperSorrowSpikeExp', 'UpperSorrowRightKeystone', 'UpperSorrowLeftKeystone', - 'UpperSorrowFarRightKeystone', 'UpperSorrowFarLeftKeystone'}, - 'DashArea': {'DashAreaMapstone', 'DashSkillTree'}, 'DashPlantAccess': {'DashAreaPlant'}, - 'DeathGauntlet': {'DeathGauntletEnergyCell', 'DeathGauntletStompSwim', 'DeathGauntletExp'}, - 'DeathGauntletDoor': set(), 'DeathGauntletDoorOpened': set(), 'DeathGauntletMoat': {'DeathGauntletSwimEnergyDoor'}, - 'DeathGauntletRoof': {'DeathGauntletRoofHealthCell'}, 'DeathGauntletRoofPlantAccess': {'DeathGauntletRoofPlant'}, - 'DoubleJumpKeyDoor': set(), 'DoubleJumpKeyDoorOpened': {'DoubleJumpSkillTree', 'DoubleJumpAreaExp'}, - 'ForlornGravityRoom': {'ForlornKeystone2', 'ForlornHiddenSpiderExp', 'ForlornKeystone1'}, - 'ForlornInnerDoor': {'ForlornEntranceExp'}, 'ForlornKeyDoor': set(), 'ForlornLaserRoom': {'ForlornEscape'}, - 'ForlornMapArea': {'ForlornMap', 'ForlornKeystone4'}, - 'ForlornOrbPossession': {'ForlornKeystone2', 'ForlornHiddenSpiderExp', 'ForlornKeystone1', 'ForlornKeystone4', - 'ForlornKeystone3'}, 'ForlornOuterDoor': set(), 'ForlornPlantAccess': {'ForlornPlant'}, - 'ForlornStompDoor': set(), 'ForlornTeleporter': {'ForlornKeystone3'}, 'GinsoEscape': set(), - 'GinsoEscapeComplete': {'GinsoEscapeExit', 'GinsoEscapeSpiderExp', 'GinsoEscapeProjectileExp', - 'GinsoEscapeJumpPadExp', 'GinsoEscapeHangingExp'}, 'GinsoInnerDoor': set(), - 'GinsoMiniBossDoor': {'LowerGinsoKeystone2', 'LowerGinsoKeystone1', 'LowerGinsoKeystone3', 'LowerGinsoKeystone4'}, - 'GinsoOuterDoor': set(), 'GinsoTeleporter': set(), 'GladesLaserArea': {'GladesLaserGrenade', 'GladesLaser'}, - 'GladesMain': {'FourthHealthCell', 'GladesMap', 'GladesMapKeystone'}, 'GladesMainAttic': {'AboveFourthHealth'}, - 'GrenadeArea': {'GrenadeAreaAbilityCell', 'GrenadeAreaExp', 'GrenadeSkillTree'}, 'GrenadeAreaAccess': set(), - 'GumoHideout': {'GumoHideoutMapstone', 'GumoHideoutCrusherExp', 'GumoHideoutRightHangingExp', - 'GumoHideoutEnergyCell', 'GumoHideoutCrusherKeystone', 'GumoHideoutMap', 'GumoHideoutMiniboss'}, - 'GumoHideoutRedirectArea': {'GumoHideoutRedirectAbilityCell', 'GumoHideoutRedirectPlant'}, - 'GumoHideoutRedirectEnergyVault': {'GumoHideoutRedirectExp', 'GumoHideoutRedirectEnergyCell'}, - 'HollowGrove': {'GroveWaterStompAbilityCell', 'HollowGroveTreeAbilityCell', 'HollowGroveMapPlant', - 'HoruFieldsHealthCell', 'HollowGroveMap', 'SwampTeleporterAbilityCell', 'HollowGroveMapstone', - 'HollowGroveTreePlant'}, 'HoruBasement': {'DoorWarpExp'}, 'HoruEscapeInnerDoor': set(), - 'HoruEscapeOuterDoor': set(), 'HoruFields': set(), - 'HoruFieldsPushBlock': {'HoruFieldsEnergyCell', 'HoruFieldsPlant', 'HoruFieldsHiddenExp', 'HoruFieldsAbilityCell'}, - 'HoruInnerDoor': {'HoruLavaDrainedLeftExp', 'HoruLavaDrainedRightExp'}, - 'HoruL4CutscenePeg': {'HoruL4', 'HoruL4LowerExp'}, 'HoruL4LavaChasePeg': {'HoruL4ChaseExp'}, - 'HoruMapLedge': {'HoruMap'}, 'HoruOuterDoor': set(), 'HoruR1CutsceneTrigger': {'HoruR1EnergyCell', 'HoruR1'}, - 'HoruR1MapstoneSecret': {'HoruR1Mapstone'}, 'HoruR3CutsceneTrigger': {'HoruR3'}, 'HoruR3ElevatorLever': set(), - 'HoruR3PlantCove': {'HoruR3Plant'}, 'HoruR4CutsceneTrigger': {'HoruR4DrainedExp', 'HoruR4'}, - 'HoruR4PuzzleEntrance': {'HoruR4LaserExp'}, 'HoruR4StompHideout': {'HoruR4StompExp'}, - 'HoruTeleporter': {'HoruTeleporterExp'}, 'Iceless': {'IcelessExp'}, 'InnerSwampAboveDrainArea': set(), - 'InnerSwampDrainBroken': {'InnerSwampDrainExp'}, 'InnerSwampSkyArea': {'InnerSwampEnergyCell'}, 'L1': {'HoruL1'}, - 'L1InnerDoor': set(), 'L1OuterDoor': set(), 'L2': {'HoruL2'}, 'L2InnerDoor': set(), 'L2OuterDoor': set(), - 'L3': {'HoruL3'}, 'L3InnerDoor': set(), 'L3OuterDoor': set(), 'L4': set(), 'L4InnerDoor': set(), - 'L4OuterDoor': {'HoruLavaDrainedLeftExp'}, - 'LeftGlades': {'WallJumpAreaEnergyCell', 'LeftGladesHiddenExp', 'WallJumpAreaExp', 'WallJumpSkillTree'}, - 'LeftGumoHideout': {'FarLeftGumoHideoutExp', 'LeftGumoHideoutUpperPlant'}, - 'LeftSorrow': {'LeftSorrowAbilityCell', 'LeftSorrowPlant', 'LeftSorrowGrenade'}, - 'LeftSorrowKeystones': {'LeftSorrowEnergyCell', 'LeftSorrowKeystone1', 'LeftSorrowKeystone2', - 'LeftSorrowKeystone4', 'LeftSorrowKeystone3'}, 'LeftSorrowLowerDoor': set(), - 'LeftSorrowMiddleDoor': set(), 'LostGrove': {'LostGroveLongSwim'}, - 'LostGroveExit': {'LostGroveTeleporter', 'LostGroveAbilityCell', 'LostGroveHiddenExp'}, - 'LowerBlackroot': {'LowerBlackrootAbilityCell', 'LowerBlackrootLaserAbilityCell', 'LowerBlackrootGrenadeThrow', - 'LowerBlackrootLaserExp'}, 'LowerChargeFlameArea': {'ChargeFlameAreaExp'}, - 'LowerGinsoTree': {'LowerGinsoPlant', 'LowerGinsoHiddenExp'}, - 'LowerLeftGumoHideout': {'LeftGumoHideoutSwim', 'LeftGumoHideoutHealthCell', 'LeftGumoHideoutExp', - 'GumoHideoutLeftHangingExp', 'GumoHideoutRightHangingExp', 'LeftGumoHideoutLowerPlant'}, - 'LowerSorrow': {'SorrowLowerLeftKeystone', 'SorrowHiddenKeystone', 'SorrowEntranceAbilityCell', 'SorrowHealthCell', - 'SorrowSpikeKeystone'}, - 'LowerSpiritCaverns': {'SpiritCavernsKeystone1', 'SpiritCavernsAbilityCell', 'SpiritCavernsKeystone2'}, - 'LowerValley': {'LowerValleyExp', 'LowerValleyMapstone', 'KuroPerchExp'}, - 'LowerValleyPlantApproach': {'ValleyMainPlant'}, 'MidSpiritCaverns': set(), 'MiddleSorrow': set(), - 'MistyAbove200xp': {'MistyGrenade'}, 'MistyBeforeDocks': set(), 'MistyBeforeMiniBoss': set(), - 'MistyEntrance': {'MistyEntranceStompExp', 'MistyEntranceTreeExp'}, 'MistyKeystone3Ledge': {'MistyKeystone3'}, - 'MistyKeystone4Ledge': {'MistyKeystone4'}, 'MistyMortarSpikeCave': {'MistyPostClimbAboveSpikePit'}, - 'MistyOrbRoom': {'GumonSeal'}, 'MistyPostClimb': set(), - 'MistyPostFeatherTutorial': {'MistyFrogNookExp', 'MistyKeystone1'}, 'MistyPostKeystone1': set(), - 'MistyPostLasers': {'MistyPostClimbSpikeCave'}, 'MistyPostMortarCorridor': set(), - 'MistyPreClimb': {'ClimbSkillTree'}, 'MistyPreKeystone2': {'MistyKeystone2', 'MistyAbilityCell'}, - 'MistyPreLasers': set(), 'MistyPreMortarCorridor': {'MistyMortarCorridorUpperExp', 'MistyMortarCorridorHiddenExp'}, - 'MistyPrePlantLedge': {'MistyPlant'}, 'MistySpikeCave': set(), - 'MoonGrotto': {'GrottoEnergyDoorHealthCell', 'GrottoEnergyDoorSwim'}, - 'MoonGrottoAboveTeleporter': {'LeftGrottoTeleporterExp', 'AboveGrottoTeleporterExp'}, - 'MoonGrottoBelowTeleporter': {'BelowGrottoTeleporterPlant', 'BelowGrottoTeleporterHealthCell'}, - 'MoonGrottoStompPlantAccess': {'MoonGrottoStompPlant'}, - 'MoonGrottoSwampAccessArea': {'GrottoSwampDrainAccessExp', 'GrottoSwampDrainAccessPlant'}, - 'OuterSwampAbilityCellNook': {'OuterSwampAbilityCell'}, - 'OuterSwampLowerArea': {'OuterSwampHealthCell', 'OuterSwampStompExp'}, - 'OuterSwampMortarAbilityCellLedge': {'OuterSwampMortarAbilityCell'}, - 'OuterSwampMortarPlantAccess': {'OuterSwampMortarPlant'}, 'OuterSwampUpperArea': {'OuterSwampGrenadeExp'}, - 'OutsideForlorn': {'OutsideForlornTreeExp', 'OutsideForlornWaterExp'}, - 'OutsideForlornCliff': {'OutsideForlornCliffExp'}, 'R1': {'HoruR1HangingExp'}, 'R1InnerDoor': set(), - 'R1OuterDoor': set(), 'R2': {'HoruR2'}, 'R2InnerDoor': set(), 'R2OuterDoor': set(), 'R3': set(), - 'R3InnerDoor': set(), 'R3OuterDoor': set(), 'R4': {'HoruR4DrainedExp'}, 'R4InnerDoor': set(), - 'R4OuterDoor': {'HoruLavaDrainedRightExp'}, 'RazielNoArea': {'RazielNo'}, - 'RightForlorn': {'RightForlornPlant', 'RightForlornHealthCell'}, - 'RightSwamp': {'StompAreaGrenadeExp', 'StompSkillTree', 'StompAreaExp', 'StompAreaRoofExp'}, - 'SideFallCell': {'GrottoHideoutFallAbilityCell'}, 'SorrowBashLedge': set(), - 'SorrowMainShaftKeystoneArea': {'SorrowMainShaftKeystone'}, 'SorrowMapstoneArea': {'SorrowMap', 'SorrowMapstone'}, - 'SorrowTeleporter': set(), 'SpiderSacArea': {'AboveChargeFlameTreeExp'}, - 'SpiderSacEnergyNook': {'SpiderSacEnergyCell'}, - 'SpiderSacTetherArea': {'SpiderSacGrenadeDoor', 'SpiderSacEnergyDoor', 'SpiderSacHealthCell'}, - 'SpiderWaterArea': {'GroveSpiderWaterSwim', 'GroveAboveSpiderWaterEnergyCell', 'GroveAboveSpiderWaterExp', - 'GroveAboveSpiderWaterHealthCell'}, 'SpiritCavernsDoor': set(), - 'SpiritCavernsDoorOpened': set(), 'SpiritTreeDoor': set(), 'SpiritTreeDoorOpened': set(), - 'SpiritTreeRefined': {'AboveChargeFlameTreeExp'}, - 'SunkenGladesRunaway': {'FronkeyWalkRoof', 'GladesGrenadePool', 'GladesMainPoolDeep', 'FirstPickup', - 'FronkeyFight', 'GladesMainPool', 'GladesKeystone1', 'GladesGrenadeTree', - 'GladesKeystone2'}, 'SunstoneArea': {'Sunstone', 'SunstonePlant'}, - 'Swamp': {'InnerSwampDrainExp', 'SwampMap'}, 'SwampDrainlessArea': {'SwampEntranceAbilityCell'}, - 'SwampEntryArea': {'SwampEntrancePlant', 'SwampEntranceSwim'}, 'SwampKeyDoorOpened': set(), - 'SwampKeyDoorPlatform': {'InnerSwampStompExp'}, 'SwampTeleporter': set(), - 'SwampWater': {'InnerSwampSwimRightKeystone', 'InnerSwampSwimMapstone', 'InnerSwampHiddenSwimExp', - 'InnerSwampSwimLeftKeystone'}, - 'TopGinsoTree': {'TopGinsoLeftLowerExp', 'TopGinsoLeftUpperExp', 'TopGinsoRightPlant'}, - 'UpperGinsoDoorClosed': set(), 'UpperGinsoDoorOpened': set(), - 'UpperGinsoRedirectArea': {'BashAreaExp', 'UpperGinsoRedirectUpperExp', 'UpperGinsoRedirectLowerExp'}, - 'UpperGinsoTree': {'UpperGinsoUpperLeftKeystone', 'UpperGinsoLowerKeystone', 'UpperGinsoRightKeystone', - 'UpperGinsoUpperRightKeystone', 'UpperGinsoEnergyCell'}, 'UpperGrotto': {'GrottoLasersRoofExp'}, - 'UpperLeftGlades': {'LeftGladesKeystone', 'LeftGladesExp', 'LeftGladesMapstone'}, - 'UpperSorrow': {'UpperSorrowSpikeExp', 'UpperSorrowRightKeystone', 'UpperSorrowLeftKeystone', - 'UpperSorrowFarRightKeystone', 'UpperSorrowFarLeftKeystone'}, - 'UpperSpiritCaverns': {'SpiritCavernsTopRightKeystone', 'SpiritCavernsTopLeftKeystone'}, - 'ValleyEntry': {'ValleyEntryAbilityCell', 'ValleyThreeBirdAbilityCell'}, - 'ValleyEntryTree': {'ValleyEntryTreeExp', 'ValleyEntryGrenadeLongSwim'}, - 'ValleyEntryTreePlantAccess': {'ValleyEntryTreePlant'}, - 'ValleyForlornApproach': {'ValleyMap', 'ValleyForlornApproachGrenade', 'ValleyForlornApproachMapstone'}, - 'ValleyMain': {'GlideSkillFeather', 'KuroPerchExp'}, 'ValleyPostStompDoor': {'ValleyRightSwimExp'}, - 'ValleyRight': set(), 'ValleyStompFloor': set(), 'ValleyStompless': {'KuroPerchExp'}, - 'ValleyStomplessApproach': {'ValleyRightFastStomplessCell', 'ValleyRightBirdStompCell', 'ValleyRightExp'}, - 'ValleyTeleporter': set(), 'ValleyThreeBirdLever': {'ValleyThreeBirdAbilityCell', 'ValleyMainFACS'}, - 'WaterVeinArea': {'WaterVein', 'GumoHideoutRockfallExp'}, 'WilhelmLedge': {'WilhelmExp', 'KuroPerchExp'}} - -connectors = \ - {'AboveChargeJumpArea': {'SorrowTeleporter', 'ChargeJumpArea'}, - 'BashTree': {'BashTreeDoorClosed', 'UpperGinsoRedirectArea'}, 'BashTreeDoorClosed': {'BashTreeDoorOpened'}, - 'BashTreeDoorOpened': {'GinsoMiniBossDoor', 'BashTree'}, 'BelowSunstoneArea': {'SunstoneArea', 'UpperSorrow'}, - 'BlackrootDarknessRoom': {'DashArea'}, 'BlackrootGrottoConnection': {'SideFallCell'}, - 'ChargeFlameAreaStump': {'LowerChargeFlameArea', 'ChargeFlameSkillTreeChamber', 'ChargeFlameAreaPlantAccess'}, - 'ChargeFlameSkillTreeChamber': {'SpiritTreeRefined', 'ChargeFlameAreaStump'}, - 'ChargeJumpArea': {'AboveChargeJumpArea', 'ChargeJumpDoor'}, 'ChargeJumpDoor': {'ChargeJumpDoorOpen'}, - 'ChargeJumpDoorOpen': {'ChargeJumpDoorOpenLeft', 'ChargeJumpArea'}, 'ChargeJumpDoorOpenLeft': {'UpperSorrow'}, - 'DashArea': {'RazielNoArea', 'GrenadeAreaAccess', 'DashPlantAccess'}, - 'DeathGauntlet': {'DeathGauntletRoofPlantAccess', 'MoonGrotto', 'DeathGauntletMoat', 'MoonGrottoAboveTeleporter', - 'DeathGauntletRoof', 'DeathGauntletDoor'}, 'DeathGauntletDoor': {'DeathGauntletDoorOpened'}, - 'DeathGauntletDoorOpened': {'SunkenGladesRunaway', 'DeathGauntlet', 'DeathGauntletMoat'}, - 'DeathGauntletRoof': {'DeathGauntlet', 'DeathGauntletRoofPlantAccess'}, - 'DoubleJumpKeyDoor': {'DoubleJumpKeyDoorOpened'}, 'ForlornGravityRoom': {'ForlornMapArea', 'ForlornInnerDoor'}, - 'ForlornInnerDoor': {'ForlornGravityRoom', 'ForlornOrbPossession', 'ForlornOuterDoor'}, - 'ForlornKeyDoor': {'ForlornLaserRoom'}, 'ForlornLaserRoom': {'ForlornStompDoor'}, - 'ForlornMapArea': {'ForlornGravityRoom', 'ForlornKeyDoor', 'ForlornPlantAccess', 'ForlornTeleporter'}, - 'ForlornOrbPossession': {'ForlornMapArea', 'ForlornKeyDoor', 'ForlornPlantAccess', 'ForlornInnerDoor'}, - 'ForlornOuterDoor': {'OutsideForlorn', 'ForlornInnerDoor'}, 'ForlornStompDoor': {'RightForlorn'}, - 'ForlornTeleporter': {'ForlornMapArea', 'ForlornGravityRoom', 'ForlornOrbPossession'}, - 'GinsoEscape': {'GinsoEscapeComplete'}, 'GinsoEscapeComplete': {'Swamp'}, 'GinsoInnerDoor': {'LowerGinsoTree'}, - 'GinsoMiniBossDoor': {'BashTreeDoorClosed'}, 'GinsoOuterDoor': {'GinsoInnerDoor'}, - 'GinsoTeleporter': {'UpperGinsoDoorClosed', 'TopGinsoTree'}, 'GladesLaserArea': {'MidSpiritCaverns', 'GladesMain'}, - 'GladesMain': {'LeftGlades', 'SpiritCavernsDoor', 'LowerChargeFlameArea', 'GladesMainAttic', 'GladesLaserArea'}, - 'GladesMainAttic': {'LowerChargeFlameArea', 'GladesMain'}, 'GrenadeAreaAccess': {'LowerBlackroot', 'GrenadeArea'}, - 'GumoHideout': {'SideFallCell', 'LeftGumoHideout', 'LowerLeftGumoHideout', 'DoubleJumpKeyDoor'}, - 'GumoHideoutRedirectArea': {'GumoHideoutRedirectEnergyVault'}, - 'HollowGrove': {'MoonGrottoStompPlantAccess', 'Iceless', 'SwampTeleporter', 'SpiderWaterArea', 'HoruFields', - 'OuterSwampUpperArea'}, 'HoruBasement': {'HoruEscapeOuterDoor'}, - 'HoruEscapeOuterDoor': {'HoruEscapeInnerDoor'}, 'HoruFields': {'HoruOuterDoor', 'HoruFieldsPushBlock'}, - 'HoruFieldsPushBlock': {'HollowGrove'}, - 'HoruInnerDoor': {'HoruBasement', 'R2OuterDoor', 'HoruMapLedge', 'L1OuterDoor', 'L2OuterDoor', 'HoruTeleporter', - 'L3OuterDoor', 'R1OuterDoor', 'R4OuterDoor', 'HoruOuterDoor', 'L4OuterDoor', 'R3OuterDoor'}, - 'HoruL4LavaChasePeg': {'HoruL4CutscenePeg'}, 'HoruOuterDoor': {'HoruFieldsPushBlock', 'HoruInnerDoor'}, - 'HoruR1CutsceneTrigger': {'LowerGinsoTree'}, 'HoruR1MapstoneSecret': {'HoruR1CutsceneTrigger'}, - 'HoruR3CutsceneTrigger': {'HoruR3PlantCove'}, 'HoruR3ElevatorLever': {'HoruR3PlantCove', 'HoruR3CutsceneTrigger'}, - 'HoruR4PuzzleEntrance': {'HoruR4CutsceneTrigger'}, - 'HoruR4StompHideout': {'HoruR4CutsceneTrigger', 'HoruR4PuzzleEntrance'}, 'HoruTeleporter': {'HoruInnerDoor'}, - 'Iceless': {'HollowGrove', 'UpperGrotto'}, 'InnerSwampAboveDrainArea': {'InnerSwampDrainBroken'}, - 'InnerSwampDrainBroken': {'Swamp'}, 'InnerSwampSkyArea': {'SwampKeyDoorPlatform', 'Swamp'}, 'L1InnerDoor': {'L1'}, - 'L1OuterDoor': {'L1InnerDoor', 'HoruInnerDoor'}, 'L2InnerDoor': {'L2'}, - 'L2OuterDoor': {'L2InnerDoor', 'HoruInnerDoor'}, 'L3InnerDoor': {'L3'}, - 'L3OuterDoor': {'L3InnerDoor', 'HoruInnerDoor'}, 'L4': {'HoruL4CutscenePeg', 'HoruL4LavaChasePeg'}, - 'L4InnerDoor': {'L4'}, 'L4OuterDoor': {'L4InnerDoor', 'HoruInnerDoor'}, - 'LeftGlades': {'UpperLeftGlades', 'GladesMain'}, 'LeftGumoHideout': {'WaterVeinArea', 'LowerLeftGumoHideout'}, - 'LeftSorrow': {'LeftSorrowKeystones'}, 'LeftSorrowKeystones': {'LeftSorrowMiddleDoor', 'MiddleSorrow'}, - 'LeftSorrowLowerDoor': {'LeftSorrow'}, 'LeftSorrowMiddleDoor': {'MiddleSorrow'}, 'LostGrove': {'LostGroveExit'}, - 'LowerBlackroot': {'LostGrove'}, 'LowerChargeFlameArea': {'ChargeFlameAreaStump', 'GladesMain'}, - 'LowerGinsoTree': {'R4InnerDoor', 'GinsoMiniBossDoor'}, - 'LowerLeftGumoHideout': {'LowerBlackroot', 'GumoHideoutRedirectArea'}, - 'LowerSorrow': {'SorrowMainShaftKeystoneArea', 'SorrowMapstoneArea', 'LeftSorrowLowerDoor', 'LeftSorrow', - 'SunstoneArea', 'WilhelmLedge', 'MiddleSorrow'}, - 'LowerSpiritCaverns': {'SpiritCavernsDoor', 'MidSpiritCaverns', 'GladesLaserArea'}, - 'LowerValley': {'ValleyThreeBirdLever', 'LowerValleyPlantApproach', 'ValleyTeleporter', 'MistyEntrance'}, - 'MidSpiritCaverns': {'UpperSpiritCaverns', 'LowerSpiritCaverns', 'GladesLaserArea'}, - 'MiddleSorrow': {'SorrowMainShaftKeystoneArea', 'LeftSorrowKeystones', 'LeftSorrow', 'LowerSorrow', 'UpperSorrow', - 'SunstoneArea'}, 'MistyAbove200xp': {'MistyBeforeMiniBoss'}, - 'MistyBeforeDocks': {'MistyAbove200xp'}, 'MistyBeforeMiniBoss': {'MistyOrbRoom'}, - 'MistyEntrance': {'MistyPostFeatherTutorial'}, 'MistyKeystone3Ledge': {'MistyPreLasers'}, - 'MistyKeystone4Ledge': {'MistyBeforeDocks'}, 'MistyMortarSpikeCave': {'MistyKeystone4Ledge'}, - 'MistyOrbRoom': {'MistyPreKeystone2'}, 'MistyPostClimb': {'MistySpikeCave'}, - 'MistyPostFeatherTutorial': {'MistyPostKeystone1'}, 'MistyPostKeystone1': {'MistyPreMortarCorridor'}, - 'MistyPostLasers': {'MistyMortarSpikeCave'}, 'MistyPostMortarCorridor': {'MistyPrePlantLedge'}, - 'MistyPreClimb': {'MistyPostClimb', 'ForlornTeleporter', 'RightForlorn'}, 'MistyPreLasers': {'MistyPostLasers'}, - 'MistyPreMortarCorridor': {'MistyPostMortarCorridor', 'RightForlorn'}, 'MistyPrePlantLedge': {'MistyPreClimb'}, - 'MistySpikeCave': {'MistyKeystone3Ledge'}, - 'MoonGrotto': {'MoonGrottoBelowTeleporter', 'MoonGrottoAboveTeleporter', 'WaterVeinArea', 'DeathGauntlet', - 'GumoHideout'}, - 'MoonGrottoAboveTeleporter': {'MoonGrottoSwampAccessArea', 'MoonGrottoBelowTeleporter', - 'MoonGrottoStompPlantAccess', 'MoonGrotto', 'DeathGauntletRoof', 'UpperGrotto'}, - 'MoonGrottoSwampAccessArea': {'InnerSwampAboveDrainArea'}, 'OuterSwampAbilityCellNook': {'InnerSwampSkyArea'}, - 'OuterSwampLowerArea': {'OuterSwampAbilityCellNook', 'OuterSwampMortarPlantAccess', 'SwampEntryArea', - 'OuterSwampMortarAbilityCellLedge', 'UpperGrotto', 'OuterSwampUpperArea'}, - 'OuterSwampMortarAbilityCellLedge': {'OuterSwampMortarPlantAccess', 'UpperGrotto'}, - 'OuterSwampUpperArea': {'OuterSwampLowerArea', 'OuterSwampAbilityCellNook', 'GinsoOuterDoor'}, - 'OutsideForlorn': {'OutsideForlornCliff', 'RightForlorn', 'ForlornOuterDoor'}, - 'OutsideForlornCliff': {'OutsideForlorn', 'ValleyForlornApproach'}, 'R1': {'HoruR1MapstoneSecret'}, - 'R1InnerDoor': {'R1'}, 'R1OuterDoor': {'R1InnerDoor', 'L1OuterDoor'}, 'R2InnerDoor': {'R2'}, - 'R2OuterDoor': {'R2InnerDoor', 'HoruInnerDoor'}, 'R3': {'HoruR3ElevatorLever'}, 'R3InnerDoor': {'R3'}, - 'R3OuterDoor': {'R3InnerDoor', 'HoruInnerDoor'}, 'R4': {'HoruR4StompHideout'}, 'R4InnerDoor': {'R4'}, - 'R4OuterDoor': {'R4InnerDoor', 'HoruInnerDoor'}, 'RazielNoArea': {'GumoHideout', 'BlackrootGrottoConnection'}, - 'SideFallCell': {'LeftGumoHideout', 'GumoHideout'}, 'SorrowBashLedge': {'LowerSorrow'}, - 'SorrowMainShaftKeystoneArea': {'LowerSorrow'}, 'SorrowMapstoneArea': {'HoruInnerDoor'}, - 'SorrowTeleporter': {'AboveChargeJumpArea', 'BelowSunstoneArea'}, - 'SpiderSacArea': {'SpiritTreeRefined', 'SpiderWaterArea', 'SpiderSacTetherArea', 'SpiderSacEnergyNook'}, - 'SpiderSacEnergyNook': {'ChargeFlameAreaPlantAccess'}, - 'SpiderSacTetherArea': {'SpiderWaterArea', 'SpiderSacEnergyNook'}, - 'SpiderWaterArea': {'HollowGrove', 'DeathGauntletRoof', 'SpiderSacEnergyNook', 'SpiderSacArea'}, - 'SpiritCavernsDoor': {'SpiritCavernsDoorOpened'}, 'SpiritCavernsDoorOpened': {'LowerSpiritCaverns', 'GladesMain'}, - 'SpiritTreeDoor': {'SpiritTreeDoorOpened'}, 'SpiritTreeDoorOpened': {'SpiritTreeRefined', 'UpperSpiritCaverns'}, - 'SpiritTreeRefined': {'ChargeFlameAreaStump', 'SpiritTreeDoor', 'ChargeFlameSkillTreeChamber', 'ValleyEntry', - 'SpiderSacArea'}, - 'SunkenGladesRunaway': {'MoonGrotto', 'LowerChargeFlameArea', 'ValleyTeleporter', 'SorrowTeleporter', - 'HoruTeleporter', 'GladesMain', 'GinsoTeleporter', 'SwampTeleporter', 'SpiritTreeRefined', - 'BlackrootDarknessRoom', 'DeathGauntletDoor', 'ForlornTeleporter'}, - 'SunstoneArea': {'SorrowTeleporter', 'UpperSorrow'}, - 'Swamp': {'SwampKeyDoorPlatform', 'SwampDrainlessArea', 'SwampWater'}, - 'SwampEntryArea': {'SwampDrainlessArea', 'Swamp'}, 'SwampKeyDoorOpened': {'RightSwamp'}, - 'SwampKeyDoorPlatform': {'SwampKeyDoorOpened', 'InnerSwampSkyArea'}, - 'SwampTeleporter': {'HollowGrove', 'OuterSwampMortarAbilityCellLedge'}, 'TopGinsoTree': {'GinsoEscape'}, - 'UpperGinsoDoorClosed': {'UpperGinsoDoorOpened'}, 'UpperGinsoDoorOpened': {'GinsoTeleporter', 'UpperGinsoTree'}, - 'UpperGinsoRedirectArea': {'UpperGinsoTree', 'BashTree'}, - 'UpperGinsoTree': {'UpperGinsoDoorClosed', 'UpperGinsoRedirectArea'}, - 'UpperGrotto': {'MoonGrottoStompPlantAccess', 'Iceless', 'MoonGrottoAboveTeleporter', - 'OuterSwampMortarAbilityCellLedge', 'OuterSwampLowerArea'}, 'UpperLeftGlades': {'LeftGlades'}, - 'UpperSorrow': {'SunstoneArea', 'MiddleSorrow', 'SorrowTeleporter', 'ChargeJumpDoor'}, - 'UpperSpiritCaverns': {'SpiritTreeDoor', 'MidSpiritCaverns'}, - 'ValleyEntry': {'ValleyThreeBirdLever', 'ValleyStompFloor', 'ValleyPostStompDoor', 'ValleyEntryTreePlantAccess', - 'ValleyEntryTree', 'SpiritTreeRefined'}, - 'ValleyEntryTree': {'ValleyPostStompDoor', 'ValleyEntryTreePlantAccess'}, - 'ValleyForlornApproach': {'ValleyStompFloor', 'OutsideForlornCliff'}, - 'ValleyMain': {'LowerValleyPlantApproach', 'LowerValley', 'MistyEntrance', 'WilhelmLedge', 'ValleyStompless'}, - 'ValleyPostStompDoor': {'ValleyEntry', 'ValleyRight', 'ValleyEntryTree'}, - 'ValleyRight': {'ValleyPostStompDoor', 'ValleyStomplessApproach'}, - 'ValleyStompFloor': {'ValleyThreeBirdLever', 'ValleyEntry', 'ValleyForlornApproach'}, - 'ValleyStompless': {'LowerValleyPlantApproach', 'ValleyMain', 'LowerValley', 'WilhelmLedge', 'MistyEntrance', - 'ValleyStomplessApproach'}, 'ValleyStomplessApproach': {'ValleyRight', 'ValleyStompless'}, - 'ValleyTeleporter': {'LowerValleyPlantApproach', 'ValleyRight', 'ValleyPostStompDoor', 'LowerValley', - 'MistyEntrance', 'ValleyStompless'}, - 'ValleyThreeBirdLever': {'ValleyStompFloor', 'ValleyEntry', 'LowerValley'}, - 'WaterVeinArea': {'MoonGrotto', 'LeftGumoHideout', 'LowerLeftGumoHideout'}, - 'WilhelmLedge': {'ValleyMain', 'SorrowBashLedge', 'ValleyStompless'}} diff --git a/worlds_disabled/oribf/Rules.py b/worlds_disabled/oribf/Rules.py deleted file mode 100644 index e59bc6412fe4..000000000000 --- a/worlds_disabled/oribf/Rules.py +++ /dev/null @@ -1,59 +0,0 @@ -from typing import Set - -from .RulesData import location_rules -from worlds.generic.Rules import set_rule -from BaseClasses import Location, CollectionState - - -# TODO: implement Mapstone counting, Open, OpenWorld, connection rules - -def oribf_has_all(state: CollectionState, items: Set[str], player:int) -> bool: - return all(state.prog_items[item, player] if type(item) == str - else state.prog_items[item[0], player] >= item[1] for item in items) - -def set_rules(world): - temp_base_rule(world.multiworld, world.player) - for logicset in world.logic_sets: - apply_or_ruleset(world.multiworld, world.player, logicset) - - -def tautology(state): - return True - - -def add_or_rule_check_first(world, location: str, player: int, conditionsets): - location = world.get_location(location, player) - for set in conditionsets: - if "Free" in set: - location.access_rule = tautology - return - rule = lambda state, conditionsets=conditionsets: any( - oribf_has_all(state, conditionset, player) for conditionset in conditionsets) - if location.access_rule is Location.access_rule: - location.access_rule = rule - else: - old_rule = location.access_rule - location.access_rule = lambda state: rule(state) or old_rule(state) - - -def temp_base_rule(world, player): - world.completion_condition[player] = lambda state: oribf_has_all(state, - {"Bash", "ChargeFlame", "ChargeJump", "Climb", "Dash", "DoubleJump", "Glide", "Grenade", "Stomp", "WallJump"}, - player) - - -def base_rule(world, player): - if world.logic[player] != 'nologic': - # Victory gets placed on Escaped Horu Event - world.completion_condition[player] = lambda state: state.has('Victory', player) - # Events - # Also add: can complete goal - set_rule(world.get_location("Escaped Horu", player), - lambda state: state.can_reach("HoruEscapeInnerDoor", player) - and state.has_any({"Dash", "Stomp", "ChargeJump", "ChargeFlame"}, player)) - - -def apply_or_ruleset(world, player, rulesetname): - rules = location_rules[rulesetname] - for location, conditionsets in rules.items(): - add_or_rule_check_first(world, location, player, conditionsets) diff --git a/worlds_disabled/oribf/RulesData.py b/worlds_disabled/oribf/RulesData.py deleted file mode 100644 index 11a51c07637d..000000000000 --- a/worlds_disabled/oribf/RulesData.py +++ /dev/null @@ -1,6 +0,0 @@ -# generated by https://github.com/Berserker66/ori_rando_server -# 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)})}}} -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'})}}}} diff --git a/worlds_disabled/oribf/Types.py b/worlds_disabled/oribf/Types.py deleted file mode 100644 index 1ed2423a487b..000000000000 --- a/worlds_disabled/oribf/Types.py +++ /dev/null @@ -1,5 +0,0 @@ -from typing import NamedTuple - -class Location(NamedTuple): - code: int - vanilla_item: str \ No newline at end of file diff --git a/worlds_disabled/oribf/__init__.py b/worlds_disabled/oribf/__init__.py deleted file mode 100644 index 6400961a5a8c..000000000000 --- a/worlds_disabled/oribf/__init__.py +++ /dev/null @@ -1,71 +0,0 @@ -from typing import Set - -from worlds.AutoWorld import World -from .Items import item_table, default_pool -from .Locations import lookup_name_to_id -from .Rules import set_rules, location_rules -from .Regions import locations_by_region, connectors -from .Options import options -from BaseClasses import Region, Item, Location, Entrance, ItemClassification - - -class OriBlindForest(World): - game: str = "Ori and the Blind Forest" - - topology_present = True - data_version = 1 - - item_name_to_id = item_table - location_name_to_id = lookup_name_to_id - - option_definitions = options - - hidden = True - - def generate_early(self): - logic_sets = {"casual-core"} - for logic_set in location_rules: - if logic_set != "casual-core" and getattr(self.multiworld, logic_set.replace("-", "_")): - logic_sets.add(logic_set) - self.logic_sets = logic_sets - - set_rules = set_rules - - def create_region(self, name: str): - return Region(name, self.player, self.multiworld) - - def create_regions(self): - world = self.multiworld - menu = self.create_region("Menu") - world.regions.append(menu) - start = Entrance(self.player, "Start Game", menu) - menu.exits.append(start) - - # workaround for now, remove duplicate locations - already_placed_locations = set() - - for region_name, locations in locations_by_region.items(): - locations -= already_placed_locations - already_placed_locations |= locations - region = self.create_region(region_name) - if region_name == "SunkenGladesRunaway": # starting point - start.connect(region) - region.locations = {Location(self.player, location, lookup_name_to_id[location], region) - for location in locations} - world.regions.append(region) - - for region_name, exits in connectors.items(): - parent = world.get_region(region_name, self.player) - for exit in exits: - connection = Entrance(self.player, exit, parent) - connection.connect(world.get_region(exit, self.player)) - parent.exits.append(connection) - - def generate_basic(self): - for item_name, count in default_pool.items(): - self.multiworld.itempool.extend([self.create_item(item_name) for _ in range(count)]) - - def create_item(self, name: str) -> Item: - return Item(name, - ItemClassification.progression if not name.startswith("EX") else ItemClassification.filler, - item_table[name], self.player) From f3e00b6d62ec773a35a1abdc867a2d95fb546d43 Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Tue, 20 May 2025 16:48:24 -0700 Subject: [PATCH 0433/1218] Zillion: fix `read_contents` to be compatible with base class (#5015) --- worlds/zillion/patch.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/worlds/zillion/patch.py b/worlds/zillion/patch.py index 0eee3315f4a1..e28d70f18182 100644 --- a/worlds/zillion/patch.py +++ b/worlds/zillion/patch.py @@ -1,5 +1,5 @@ import os -from typing import BinaryIO +from typing import Any, BinaryIO import zipfile from typing_extensions import override @@ -46,9 +46,10 @@ def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None: compress_type=zipfile.ZIP_DEFLATED) @override - def read_contents(self, opened_zipfile: zipfile.ZipFile) -> None: - super().read_contents(opened_zipfile) + def read_contents(self, opened_zipfile: zipfile.ZipFile) -> dict[str, Any]: + manifest = super().read_contents(opened_zipfile) self.gen_data_str = opened_zipfile.read("gen_data.json").decode() + return manifest @override def patch(self, target: str) -> None: From 7f4bf71807f7b6fc2fb70082abeff4376b1a0e34 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Wed, 21 May 2025 14:12:00 +0200 Subject: [PATCH 0434/1218] Adventure: Update AdventureDeltaPatch.read_contents to return the manifest as required by #4331 (#5016) --- worlds/adventure/Rom.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/worlds/adventure/Rom.py b/worlds/adventure/Rom.py index 4d56cd19e529..cb104c56d867 100644 --- a/worlds/adventure/Rom.py +++ b/worlds/adventure/Rom.py @@ -182,10 +182,11 @@ def write_contents(self, opened_zipfile: zipfile.ZipFile): json.dumps(self.rom_deltas), compress_type=zipfile.ZIP_LZMA) - def read_contents(self, opened_zipfile: zipfile.ZipFile): - super(AdventureDeltaPatch, self).read_contents(opened_zipfile) + def read_contents(self, opened_zipfile: zipfile.ZipFile) -> dict[str, Any]: + manifest = super(AdventureDeltaPatch, self).read_contents(opened_zipfile) self.foreign_items = AdventureDeltaPatch.read_foreign_items(opened_zipfile) self.autocollect_items = AdventureDeltaPatch.read_autocollect_items(opened_zipfile) + return manifest @classmethod def get_source_data(cls) -> bytes: From 3069deb019cf06a21af4625224be78d5118d61c6 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Wed, 21 May 2025 08:12:27 -0400 Subject: [PATCH 0435/1218] Jak and Daxter: Implement New Game (#3291) * Jak 1: Initial commit: Cell Locations, Items, and Regions modeled. * Jak 1: Wrote Regions, Rules, init. Untested. * Jak 1: Fixed mistakes, need better understanding of Entrances. * Jak 1: Fixed bugs, refactored Regions, added missing Special Checks. First spoiler log generated. * Jak 1: Add Scout Fly Locations, code and style cleanup. * Jak 1: Add Scout Flies to Regions. * Jak 1: Add version info. * Jak 1: Reduced code smell. * Jak 1: Fixed UT bugs, added Free The Sages as Locations. * Jak 1: Refactor ID scheme to better fit game's scheme. Add more subregions and rules, but still missing one-way Entrances. * Jak 1: Add some one-ways, adjust scout fly offset. * Jak 1: Found Scout Fly ID's for first 4 maps. * Jak 1: Add more scout fly ID's, refactor game/AP ID translation for easier reading and code reuse. * Jak 1: Fixed a few things. Four maps to go. * Jak 1: Last of the scout flies mapped! * Jak 1: simplify citadel sages logic. * Jak 1: WebWorld setup, some documentation. * Jak 1: Initial checkin of Client. Removed the colon from the game name. * Jak 1: Refactored client into components, working on async communication between the client and the game. * Jak 1: In tandem with new ArchipelaGOAL memory structure, define read_memory. * Jak 1: There's magic in the air... * Jak 1: Fixed bug translating scout fly ID's. * Jak 1: Make the REPL a little more verbose, easier to debug. * Jak 1: Did you know Snowy Mountain had such specific unlock requirements? I didn't. * Jak 1: Update Documentation. * Jak 1: Simplify user interaction with agents, make process more robust/less dependent on order of ops. * Jak 1: Simplified startup process, updated docs, prayed. * Jak 1: quick fix to settings. * Jak and Daxter: Implement New Game (#1) * Jak 1: Initial commit: Cell Locations, Items, and Regions modeled. * Jak 1: Wrote Regions, Rules, init. Untested. * Jak 1: Fixed mistakes, need better understanding of Entrances. * Jak 1: Fixed bugs, refactored Regions, added missing Special Checks. First spoiler log generated. * Jak 1: Add Scout Fly Locations, code and style cleanup. * Jak 1: Add Scout Flies to Regions. * Jak 1: Add version info. * Jak 1: Reduced code smell. * Jak 1: Fixed UT bugs, added Free The Sages as Locations. * Jak 1: Refactor ID scheme to better fit game's scheme. Add more subregions and rules, but still missing one-way Entrances. * Jak 1: Add some one-ways, adjust scout fly offset. * Jak 1: Found Scout Fly ID's for first 4 maps. * Jak 1: Add more scout fly ID's, refactor game/AP ID translation for easier reading and code reuse. * Jak 1: Fixed a few things. Four maps to go. * Jak 1: Last of the scout flies mapped! * Jak 1: simplify citadel sages logic. * Jak 1: WebWorld setup, some documentation. * Jak 1: Initial checkin of Client. Removed the colon from the game name. * Jak 1: Refactored client into components, working on async communication between the client and the game. * Jak 1: In tandem with new ArchipelaGOAL memory structure, define read_memory. * Jak 1: There's magic in the air... * Jak 1: Fixed bug translating scout fly ID's. * Jak 1: Make the REPL a little more verbose, easier to debug. * Jak 1: Did you know Snowy Mountain had such specific unlock requirements? I didn't. * Jak 1: Update Documentation. * Jak 1: Simplify user interaction with agents, make process more robust/less dependent on order of ops. * Jak 1: Simplified startup process, updated docs, prayed. * Jak 1: quick fix to settings. * Jak and Daxter: Genericize Items, Update Scout Fly logic, Add Victory Condition. (#3) * Jak 1: Update to 0.4.6. Decouple locations from items, support filler items. * Jak 1: Total revamp of Items. This is where everything broke. * Jak 1: Decouple 7 scout fly checks from normal checks, update regions/rules for orb counts/traders. * Jak 1: correct regions/rules, account for sequential oracle/miner locations. * Jak 1: make nicer strings. * Jak 1: Add logic for finished game. First full run complete! * Jak 1: update group names. * Jak and Daxter - Gondola, Pontoons, Rules, Regions, and Client Update * Jak 1: Overhaul of regions, rules, and special locations. Updated game info page. * Jak 1: Preparations for Alpha. Reintroducing automatic startup in client. Updating docs, readme, codeowners. * Alpha Updates (#15) * Jak 1: Consolidate client into apworld, create launcher icon, improve setup docs. * Jak 1: Update setup guide. * Jak 1: Load title screen, save states of in/outboxes. * Logging Update (#16) * Jak 1: Separate info and debug logs. * Jak 1: Update world info to refer to Archipelago Options menu. * Deathlink (#18) * Jak 1: Implement Deathlink. TODO: make it optional... * Jak 1: Issue a proper send-event for deathlink deaths. * Jak 1: Added cause of death to deathlink, fixed typo. * Jak 1: Make Deathlink toggleable. * Jak 1: Added player name to death text, added zoomer/flut/fishing text, simplified GOAL call for deathlink. * Jak 1: Fix death text in client logger. * Move Randomizer (#26) * Finally remove debug-segment text, update Python imports to relative paths. * HUGE refactor to Regions/Rules to support move rando, first hub area coded. * More refactoring. * Another refactor - may squash. * Fix some Rules, reuse some code by returning key regions from build_regions. * More regions added. A couple of TODOs. * Fixed trade logic, added LPC regions. * Added Spider, Snowy, Boggy. Fixed Misty's orbs. * Fix circular import, assert orb counts per level, fix a few naming errors. * Citadel added, missing locs and connections fixed. First move rando seed generated. * Add Move Rando to Options class. * Fixed rules for prerequisite moves. * Implement client functionality for move rando, add blurbs to game info page. * Fix wrong address for cache checks. * Fix byte alignment of offsets, refactor read_memory for better code reuse. * Refactor memory offsets and add some unit tests. * Make green eco the filler item, also define a maximum ID. Fix Boggy tether locations. * Move rando fixes (#29) * Fix virtual regions in Snowy. Fix some GMC problems. * Fix Deathlink on sunken slides. * Removed unncessary code causing build failure. * Orbsanity (#32) * My big dumb shortcut: a 2000 item array. * A better idea: bundle orbs as a numerical option and make array variable size. * Have Item/Region generation respect the chosen Orbsanity bundle size. Fix trade logic. * Separate Global/Local Orbsanity options. TODO - re-introduce orb factory for per-level option. * Per-level Orbsanity implemented w/ orb bundle factory. * Implement Orbsanity for client, fix some things up for regions. * Fix location name/id mappings. * Fix client orb collection on connection. * Fix minor Deathlink bug, add Update instructions. * Finishing Touches (#36) * Set up connector level thresholds, completion goal choices. * Send AP sender/recipient info to game via client. * Slight refactors. * Refactor option checking, add DataStorage handling of traded orbs. * Update instructions to change order of load/connect. * Add Option check to ensure enough Locations exist for Cell Count thresholds. Fix Final Door region. * Need some height move to get LPC sunken chamber cell. * Rename completion_condition to jak_completion_condition (#41) * The Afterparty (#42) * Fixes to Jak client, rules, options, and more. * Post-rebase fixes. * Remove orbsanity reset code, optimize game text in client. * More game text optimization. * Added more specific troubleshooting/setup instructions. * Add known issue about large releases taking time. (Dodge 6,666th commit.) * Remove "Bundle of", Add location name groups, set better default RootDirectory for new players. * Make orb trade amounts configurable, make orbsanity defaults more reasonable. * Add HUD info to doc. * Exempt's Code Review Updates (#43) * Round 1 of code review updates, the easy stuff. * Factor options checking away from region/rule creation. * Code review updates round 2, more complex stuff. * Code review updates round 3: the mental health annihilator * Code review updates part 4: redemption. * More code review feedback, simplifying code, etc. * Added a host.yaml option to override friendly limits, plus a couple of code review updates. * Added singleplayer limits, player names to enforcement rules. * Updated friendly limits to be more strict, optimized recalculate logic. * Today's the big day Jak: updates docs for mod support in OpenGOAL Launcher * Rearranged and clarified some instructions, ADDED PATH-SPACE FIX TO CLIENT. * Fix deathlink reset stalls on a busy client. (#47) * Jak & Daxter Client : queue game text messages to get items faster during release (#48) * queue game text messages to write them during the main_tick function and empty the message queue faster during release * wrap comment for code style character limit Co-authored-by: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> * remove useless blank line Co-authored-by: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> * whitespace code style Co-authored-by: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> * Move JsonMessageData dataclass outside of ReplClient class for code clarity --------- Co-authored-by: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> * Item Classifications (and REPL fixes) (#49) * Changes to item classifications * Bugfixes to power cell thresholds. * Fix bugs in item_type_helper. * Refactor 100 cell door to pass unit tests. * Quick fix to ReplClient. * Not so quick fix to ReplClient. * Display friendly limits in options tooltips. * Use math.ceil like a normal person. * Missed a space. * Fix non-accessibility due to bad orb calculation. * Updated documentation. * More Options, More Docs, More Tests (#51) * Reorder cell counts, require punch for Klaww. * Friendlier friendly friendlies. * Removed custom_worlds references from docs/setup guide, focused OpenGOAL Launcher language. * Increased breadth of unit tests. * Clean imports of unit tests. * Create OptionGroups. * Fix region rule bug with Punch for Klaww. * Include Punch For Klaww in slot data. * Update worlds/jakanddaxter/__init__.py Co-authored-by: Scipio Wright * Temper and Harden Text Client (#52) * Provide config path so OpenGOAL can use mod-specific saves and settings. * Add versioning to MemoryReader. Harden the client against user errors. * Updated comments. * Add Deathlink as a "statement of intent" to the YAML. Small updates to client. * Revert deathlink changes. * Update error message. * Added color markup to log messages printed in text client. * Separate loggers by agent, write markup to GUI and non-markup to disk simultaneously. * Refactor MemoryReader callbacks from main_tick to constructor. * Make callback names more... informative. * Give users explicit instructions in error messages. * Stellar Messaging (#54) * Use new ap-messenger functions for text writing. * Remove Powershell requirement, bump memory version to 3. * Error message update w/ instructions for game crash. * Create no console window for gk. * ISO Data Enhancement (#58) * Add iso-path as argument to GOAL compiler. # Conflicts: # worlds/jakanddaxter/Client.py * More resilient handling of iso_path. * Fixed scout fly ID mismatches. * Corrected iso_data subpath. * Update memory version to 4. * Docs update for iso_data. * Auto Detect OpenGOAL Install (#63) * Auto detect OpenGOAL install path. Also fix Deathlink on server connection. * Updated docs, add instructions to error messages. * Slight tweak to error text. * J&D : add per region location groups (#64) * add per region power cells location group * add per region scout flies location group * add per zone orb bundle groups (I'm not particularly happy about this code, but I figured doing it this way was the point of least friction/duplication) * guess who forgot 9 very important characters in each line of the last commit * Rearrange location group names, quick fix to client error handling. * Fix pycharm warnings. * Fix more pycharm warnings. * Light cleanup: fix icons, add bug report page, remove py 3.8 code. * Update worlds/jakanddaxter/Options.py Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update worlds/jakanddaxter/Options.py Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update worlds/jakanddaxter/Options.py Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update worlds/jakanddaxter/Options.py Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Code review updates on comments, tooltips, and type hints. * Update type hint for lists in regions. * Missed todo removal. * More type hint updates. * Small region updates for location accessibility, small updates to world guide and README.md. * Add GMC scout fly location group. * Improved sanitization of game text. * Traps 2 (#70) * Add trap items, relevant options, and citadel orb caches. * Update REPL to send traps to game. * Fix item counter. * Allow player to select which traps to use. * Fix host.yaml doc strings, ap-setup-options typing, bump memory version to 5. * Alter some trap names. * Update world doc. * Add health trap. * Added 3 more trap types. * Protect against empty trap list. * Reword traps paragraph in world doc. * Another update to trap paragraph. * Concisify trap option docstring. * Timestamp on game log file. * Update client to handle waiting on title screen. * Send slot name and seed to game. * Use self.random instead. * Update setup doc for new title screen. * Quick clarification of orb caches in world doc. * Sanitize slot info earlier. * Added to and improved unit tests. * Light cleanup on world. * Optimizations to movement rules, docs: known issues update. * Quick fixes for beta 0.5.0 release: template options and LPC logic. * Quick fix to spoiler counts. * Reorganize world guide for faster navigation. * Fix links. * Update HUD section. * Found a way to render apostrophes in item names. * March Refactors (#77) * Reorg imports, small fix to Rock Village movement. * Fix wait-on-title message never going to ready message. * Colorama init fix. * Swap trap list for a dictionary of trap weights. * The more laws, the less justice. * Quick readability update. * Have memory reader provide instructions for slow booting games. * Revert some things. * Update setup_en.md * Update HUD mode lingo for combined msgs. * Remade launcher icon, sized correctly. * I don't know why I can't be satisfied with things. * Apply suggestions from Scipio Co-authored-by: Scipio Wright * Properly use the settings API instead of Utils. * Newline on requirements.txt. * Add __init__ files for frozen builds. * Replace an ap_inform function with a CommonClient built-in. * Resize icon to match kivymd expected size. * First round of Treble code reviews. * Second round of Treble code reviews. * Third round of Treble code reviews. * Missed an unncessary if condition. * Missed unnecessary comments. * Fourth round of Treble code reviews. * Switch trap dictionary to OptionCounter. * Use existing slot name/seed from network protocol. * Violet code review updates. * Violet code review updates part 2. * Refactor to avoid floating imports (Violet part 3). * Found a few more valid characters for messaging. * Move tests out of init, add colon to game name (now that it's safe). * But don't include those chars for file text. * Implement Vi suggestion on webhost-capable friendly limits. * Revert "Implement Vi suggestion on webhost-capable friendly limits." This reverts commit 2d012b7f4a9a4c13985ecd7303bb1fc646831c86. * Rename all files for PEP8. * Refactor how maximums work on webhost. * Fix rogue UT. * Don't rush. * Fix client post-PEP8. --------- Co-authored-by: Justus Lind Co-authored-by: Romain BERNARD <30secondstodraw@gmail.com> Co-authored-by: Scipio Wright Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> --- README.md | 1 + docs/CODEOWNERS | 3 + worlds/jakanddaxter/__init__.py | 504 +++++++++++++++ worlds/jakanddaxter/agents/__init__.py | 0 worlds/jakanddaxter/agents/memory_reader.py | 489 ++++++++++++++ worlds/jakanddaxter/agents/repl_client.py | 527 +++++++++++++++ worlds/jakanddaxter/client.py | 600 ++++++++++++++++++ .../en_Jak and Daxter The Precursor Legacy.md | 258 ++++++++ worlds/jakanddaxter/docs/setup_en.md | 182 ++++++ worlds/jakanddaxter/game_id.py | 8 + worlds/jakanddaxter/icons/precursor_orb.ico | Bin 0 -> 6142 bytes worlds/jakanddaxter/icons/precursor_orb.png | Bin 0 -> 4698 bytes worlds/jakanddaxter/items.py | 156 +++++ worlds/jakanddaxter/levels.py | 76 +++ worlds/jakanddaxter/locations.py | 66 ++ worlds/jakanddaxter/locs/__init__.py | 0 worlds/jakanddaxter/locs/cell_locations.py | 194 ++++++ .../jakanddaxter/locs/orb_cache_locations.py | 52 ++ worlds/jakanddaxter/locs/orb_locations.py | 123 ++++ worlds/jakanddaxter/locs/scout_locations.py | 230 +++++++ worlds/jakanddaxter/locs/special_locations.py | 51 ++ worlds/jakanddaxter/options.py | 262 ++++++++ worlds/jakanddaxter/regions.py | 132 ++++ worlds/jakanddaxter/regs/__init__.py | 0 .../jakanddaxter/regs/boggy_swamp_regions.py | 174 +++++ .../jakanddaxter/regs/fire_canyon_regions.py | 38 ++ .../regs/forbidden_jungle_regions.py | 103 +++ .../jakanddaxter/regs/geyser_rock_regions.py | 48 ++ .../regs/gol_and_maias_citadel_regions.py | 137 ++++ worlds/jakanddaxter/regs/lava_tube_regions.py | 38 ++ .../regs/lost_precursor_city_regions.py | 155 +++++ .../jakanddaxter/regs/misty_island_regions.py | 131 ++++ .../regs/mountain_pass_regions.py | 67 ++ .../regs/precursor_basin_regions.py | 38 ++ worlds/jakanddaxter/regs/region_base.py | 91 +++ .../jakanddaxter/regs/rock_village_regions.py | 75 +++ .../regs/sandover_village_regions.py | 83 +++ .../regs/sentinel_beach_regions.py | 108 ++++ .../regs/snowy_mountain_regions.py | 203 ++++++ .../jakanddaxter/regs/spider_cave_regions.py | 127 ++++ .../regs/volcanic_crater_regions.py | 52 ++ worlds/jakanddaxter/requirements.txt | 1 + worlds/jakanddaxter/rules.py | 230 +++++++ worlds/jakanddaxter/test/__init__.py | 0 worlds/jakanddaxter/test/bases.py | 107 ++++ worlds/jakanddaxter/test/test_locations.py | 52 ++ worlds/jakanddaxter/test/test_moverando.py | 32 + worlds/jakanddaxter/test/test_orbsanity.py | 61 ++ .../test/test_orderedcellcounts.py | 29 + worlds/jakanddaxter/test/test_trades.py | 39 ++ worlds/jakanddaxter/test/test_traps.py | 80 +++ 51 files changed, 6213 insertions(+) create mode 100644 worlds/jakanddaxter/__init__.py create mode 100644 worlds/jakanddaxter/agents/__init__.py create mode 100644 worlds/jakanddaxter/agents/memory_reader.py create mode 100644 worlds/jakanddaxter/agents/repl_client.py create mode 100644 worlds/jakanddaxter/client.py create mode 100644 worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md create mode 100644 worlds/jakanddaxter/docs/setup_en.md create mode 100644 worlds/jakanddaxter/game_id.py create mode 100644 worlds/jakanddaxter/icons/precursor_orb.ico create mode 100644 worlds/jakanddaxter/icons/precursor_orb.png create mode 100644 worlds/jakanddaxter/items.py create mode 100644 worlds/jakanddaxter/levels.py create mode 100644 worlds/jakanddaxter/locations.py create mode 100644 worlds/jakanddaxter/locs/__init__.py create mode 100644 worlds/jakanddaxter/locs/cell_locations.py create mode 100644 worlds/jakanddaxter/locs/orb_cache_locations.py create mode 100644 worlds/jakanddaxter/locs/orb_locations.py create mode 100644 worlds/jakanddaxter/locs/scout_locations.py create mode 100644 worlds/jakanddaxter/locs/special_locations.py create mode 100644 worlds/jakanddaxter/options.py create mode 100644 worlds/jakanddaxter/regions.py create mode 100644 worlds/jakanddaxter/regs/__init__.py create mode 100644 worlds/jakanddaxter/regs/boggy_swamp_regions.py create mode 100644 worlds/jakanddaxter/regs/fire_canyon_regions.py create mode 100644 worlds/jakanddaxter/regs/forbidden_jungle_regions.py create mode 100644 worlds/jakanddaxter/regs/geyser_rock_regions.py create mode 100644 worlds/jakanddaxter/regs/gol_and_maias_citadel_regions.py create mode 100644 worlds/jakanddaxter/regs/lava_tube_regions.py create mode 100644 worlds/jakanddaxter/regs/lost_precursor_city_regions.py create mode 100644 worlds/jakanddaxter/regs/misty_island_regions.py create mode 100644 worlds/jakanddaxter/regs/mountain_pass_regions.py create mode 100644 worlds/jakanddaxter/regs/precursor_basin_regions.py create mode 100644 worlds/jakanddaxter/regs/region_base.py create mode 100644 worlds/jakanddaxter/regs/rock_village_regions.py create mode 100644 worlds/jakanddaxter/regs/sandover_village_regions.py create mode 100644 worlds/jakanddaxter/regs/sentinel_beach_regions.py create mode 100644 worlds/jakanddaxter/regs/snowy_mountain_regions.py create mode 100644 worlds/jakanddaxter/regs/spider_cave_regions.py create mode 100644 worlds/jakanddaxter/regs/volcanic_crater_regions.py create mode 100644 worlds/jakanddaxter/requirements.txt create mode 100644 worlds/jakanddaxter/rules.py create mode 100644 worlds/jakanddaxter/test/__init__.py create mode 100644 worlds/jakanddaxter/test/bases.py create mode 100644 worlds/jakanddaxter/test/test_locations.py create mode 100644 worlds/jakanddaxter/test/test_moverando.py create mode 100644 worlds/jakanddaxter/test/test_orbsanity.py create mode 100644 worlds/jakanddaxter/test/test_orderedcellcounts.py create mode 100644 worlds/jakanddaxter/test/test_trades.py create mode 100644 worlds/jakanddaxter/test/test_traps.py diff --git a/README.md b/README.md index c1e89bac7ce2..861a6eed1d27 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ Currently, the following games are supported: * Inscryption * Civilization VI * The Legend of Zelda: The Wind Waker +* Jak and Daxter: The Precursor Legacy For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index b89f668c0472..ca19d27da906 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -87,6 +87,9 @@ # Inscryption /worlds/inscryption/ @DrBibop @Glowbuzz +# Jak and Daxter: The Precursor Legacy +/worlds/jakanddaxter/ @massimilianodelliubaldini + # Kirby's Dream Land 3 /worlds/kdl3/ @Silvris diff --git a/worlds/jakanddaxter/__init__.py b/worlds/jakanddaxter/__init__.py new file mode 100644 index 000000000000..d508e967ae9b --- /dev/null +++ b/worlds/jakanddaxter/__init__.py @@ -0,0 +1,504 @@ +# Python standard libraries +from collections import defaultdict +from math import ceil +from typing import Any, ClassVar, Callable, Union, cast + +# Archipelago imports +import settings +from worlds.AutoWorld import World, WebWorld +from worlds.LauncherComponents import components, Component, launch_subprocess, Type, icon_paths +from BaseClasses import (Item, + ItemClassification as ItemClass, + Tutorial, + CollectionState) +from Options import OptionGroup + +# Jak imports +from . import options +from .game_id import jak1_id, jak1_name, jak1_max +from .items import (JakAndDaxterItem, + OrbAssoc, + item_table, + cell_item_table, + scout_item_table, + special_item_table, + move_item_table, + orb_item_table, + trap_item_table) +from .levels import level_table, level_table_with_global +from .locations import (JakAndDaxterLocation, + location_table, + cell_location_table, + scout_location_table, + special_location_table, + cache_location_table, + orb_location_table) +from .regions import create_regions +from .rules import (enforce_multiplayer_limits, + enforce_singleplayer_limits, + verify_orb_trade_amounts, + set_orb_trade_rule) +from .locs import (cell_locations as cells, + scout_locations as scouts, + special_locations as specials, + orb_cache_locations as caches, + orb_locations as orbs) +from .regs.region_base import JakAndDaxterRegion + + +def launch_client(): + from . import client + launch_subprocess(client.launch, name="JakAndDaxterClient") + + +components.append(Component("Jak and Daxter Client", + func=launch_client, + component_type=Type.CLIENT, + icon="precursor_orb")) + +icon_paths["precursor_orb"] = f"ap:{__name__}/icons/precursor_orb.png" + + +class JakAndDaxterSettings(settings.Group): + class RootDirectory(settings.UserFolderPath): + """Path to folder containing the ArchipelaGOAL mod executables (gk.exe and goalc.exe). + Ensure this path contains forward slashes (/) only. This setting only applies if + Auto Detect Root Directory is set to false.""" + description = "ArchipelaGOAL Root Directory" + + class AutoDetectRootDirectory(settings.Bool): + """Attempt to find the OpenGOAL installation and the mod executables (gk.exe and goalc.exe) + automatically. If set to true, the ArchipelaGOAL Root Directory setting is ignored.""" + description = "ArchipelaGOAL Auto Detect Root Directory" + + class EnforceFriendlyOptions(settings.Bool): + """Enforce friendly player options in both single and multiplayer seeds. Disabling this allows for + more disruptive and challenging options, but may impact seed generation. Use at your own risk!""" + description = "ArchipelaGOAL Enforce Friendly Options" + + root_directory: RootDirectory = RootDirectory( + "%programfiles%/OpenGOAL-Launcher/features/jak1/mods/JakMods/archipelagoal") + # Don't ever change these type hints again. + auto_detect_root_directory: Union[AutoDetectRootDirectory, bool] = True + enforce_friendly_options: Union[EnforceFriendlyOptions, bool] = True + + +class JakAndDaxterWebWorld(WebWorld): + setup_en = Tutorial( + "Multiworld Setup Guide", + "A guide to setting up ArchipelaGOAL (Archipelago on OpenGOAL).", + "English", + "setup_en.md", + "setup/en", + ["markustulliuscicero"] + ) + + tutorials = [setup_en] + bug_report_page = "https://github.com/ArchipelaGOAL/Archipelago/issues" + + option_groups = [ + OptionGroup("Orbsanity", [ + options.EnableOrbsanity, + options.GlobalOrbsanityBundleSize, + options.PerLevelOrbsanityBundleSize, + ]), + OptionGroup("Power Cell Counts", [ + options.EnableOrderedCellCounts, + options.FireCanyonCellCount, + options.MountainPassCellCount, + options.LavaTubeCellCount, + ]), + OptionGroup("Orb Trade Counts", [ + options.CitizenOrbTradeAmount, + options.OracleOrbTradeAmount, + ]), + OptionGroup("Traps", [ + options.FillerPowerCellsReplacedWithTraps, + options.FillerOrbBundlesReplacedWithTraps, + options.TrapEffectDuration, + options.TrapWeights, + ]), + ] + + +class JakAndDaxterWorld(World): + """ + Jak and Daxter: The Precursor Legacy is a 2001 action platformer developed by Naughty Dog + for the PlayStation 2. The game follows the eponymous protagonists, a young boy named Jak + and his friend Daxter, who has been transformed into an ottsel. With the help of Samos + the Sage of Green Eco and his daughter Keira, the pair travel north in search of a cure for Daxter, + discovering artifacts created by an ancient race known as the Precursors along the way. When the + rogue sages Gol and Maia Acheron plan to flood the world with Dark Eco, they must stop their evil plan + and save the world. + """ + # ID, name, version + game = jak1_name + required_client_version = (0, 5, 0) + + # Options + settings: ClassVar[JakAndDaxterSettings] + options_dataclass = options.JakAndDaxterOptions + options: options.JakAndDaxterOptions + + # Web world + web = JakAndDaxterWebWorld() + + # Stored as {ID: Name} pairs, these must now be swapped to {Name: ID} pairs. + # Remember, the game ID and various offsets for each item type have already been calculated. + item_name_to_id = {name: k for k, name in item_table.items()} + location_name_to_id = {name: k for k, name in location_table.items()} + item_name_groups = { + "Power Cells": set(cell_item_table.values()), + "Scout Flies": set(scout_item_table.values()), + "Specials": set(special_item_table.values()), + "Moves": set(move_item_table.values()), + "Precursor Orbs": set(orb_item_table.values()), + "Traps": set(trap_item_table.values()), + } + location_name_groups = { + "Power Cells": set(cell_location_table.values()), + "Power Cells - GR": set(cells.locGR_cellTable.values()), + "Power Cells - SV": set(cells.locSV_cellTable.values()), + "Power Cells - FJ": set(cells.locFJ_cellTable.values()), + "Power Cells - SB": set(cells.locSB_cellTable.values()), + "Power Cells - MI": set(cells.locMI_cellTable.values()), + "Power Cells - FC": set(cells.locFC_cellTable.values()), + "Power Cells - RV": set(cells.locRV_cellTable.values()), + "Power Cells - PB": set(cells.locPB_cellTable.values()), + "Power Cells - LPC": set(cells.locLPC_cellTable.values()), + "Power Cells - BS": set(cells.locBS_cellTable.values()), + "Power Cells - MP": set(cells.locMP_cellTable.values()), + "Power Cells - VC": set(cells.locVC_cellTable.values()), + "Power Cells - SC": set(cells.locSC_cellTable.values()), + "Power Cells - SM": set(cells.locSM_cellTable.values()), + "Power Cells - LT": set(cells.locLT_cellTable.values()), + "Power Cells - GMC": set(cells.locGMC_cellTable.values()), + "Scout Flies": set(scout_location_table.values()), + "Scout Flies - GR": set(scouts.locGR_scoutTable.values()), + "Scout Flies - SV": set(scouts.locSV_scoutTable.values()), + "Scout Flies - FJ": set(scouts.locFJ_scoutTable.values()), + "Scout Flies - SB": set(scouts.locSB_scoutTable.values()), + "Scout Flies - MI": set(scouts.locMI_scoutTable.values()), + "Scout Flies - FC": set(scouts.locFC_scoutTable.values()), + "Scout Flies - RV": set(scouts.locRV_scoutTable.values()), + "Scout Flies - PB": set(scouts.locPB_scoutTable.values()), + "Scout Flies - LPC": set(scouts.locLPC_scoutTable.values()), + "Scout Flies - BS": set(scouts.locBS_scoutTable.values()), + "Scout Flies - MP": set(scouts.locMP_scoutTable.values()), + "Scout Flies - VC": set(scouts.locVC_scoutTable.values()), + "Scout Flies - SC": set(scouts.locSC_scoutTable.values()), + "Scout Flies - SM": set(scouts.locSM_scoutTable.values()), + "Scout Flies - LT": set(scouts.locLT_scoutTable.values()), + "Scout Flies - GMC": set(scouts.locGMC_scoutTable.values()), + "Specials": set(special_location_table.values()), + "Orb Caches": set(cache_location_table.values()), + "Precursor Orbs": set(orb_location_table.values()), + "Precursor Orbs - GR": set(orbs.locGR_orbBundleTable.values()), + "Precursor Orbs - SV": set(orbs.locSV_orbBundleTable.values()), + "Precursor Orbs - FJ": set(orbs.locFJ_orbBundleTable.values()), + "Precursor Orbs - SB": set(orbs.locSB_orbBundleTable.values()), + "Precursor Orbs - MI": set(orbs.locMI_orbBundleTable.values()), + "Precursor Orbs - FC": set(orbs.locFC_orbBundleTable.values()), + "Precursor Orbs - RV": set(orbs.locRV_orbBundleTable.values()), + "Precursor Orbs - PB": set(orbs.locPB_orbBundleTable.values()), + "Precursor Orbs - LPC": set(orbs.locLPC_orbBundleTable.values()), + "Precursor Orbs - BS": set(orbs.locBS_orbBundleTable.values()), + "Precursor Orbs - MP": set(orbs.locMP_orbBundleTable.values()), + "Precursor Orbs - VC": set(orbs.locVC_orbBundleTable.values()), + "Precursor Orbs - SC": set(orbs.locSC_orbBundleTable.values()), + "Precursor Orbs - SM": set(orbs.locSM_orbBundleTable.values()), + "Precursor Orbs - LT": set(orbs.locLT_orbBundleTable.values()), + "Precursor Orbs - GMC": set(orbs.locGMC_orbBundleTable.values()), + "Trades": {location_table[cells.to_ap_id(k)] for k in + {11, 12, 31, 32, 33, 96, 97, 98, 99, 13, 14, 34, 35, 100, 101}}, + "'Free 7 Scout Flies' Power Cells": set(cells.loc7SF_cellTable.values()), + } + + # These functions and variables are Options-driven, keep them as instance variables here so that we don't clog up + # the seed generation routines with options checking. So we set these once, and then just use them as needed. + can_trade: Callable[[CollectionState, int, int | None], bool] + total_orbs: int = 2000 + orb_bundle_item_name: str = "" + orb_bundle_size: int = 0 + total_trade_orbs: int = 0 + total_prog_orb_bundles: int = 0 + total_trap_orb_bundles: int = 0 + total_filler_orb_bundles: int = 0 + total_power_cells: int = 101 + total_prog_cells: int = 0 + total_trap_cells: int = 0 + total_filler_cells: int = 0 + power_cell_thresholds: list[int] + power_cell_thresholds_minus_one: list[int] + trap_weights: tuple[list[str], list[int]] + + # Store these dictionaries for speed improvements. + level_to_regions: dict[str, list[JakAndDaxterRegion]] # Contains all levels and regions. + level_to_orb_regions: dict[str, list[JakAndDaxterRegion]] # Contains only regions which contain orbs. + + # Handles various options validation, rules enforcement, and caching of important information. + def generate_early(self) -> None: + + # Initialize the level-region dictionary. + self.level_to_regions = defaultdict(list) + self.level_to_orb_regions = defaultdict(list) + + # Cache the power cell threshold values for quicker reference. + self.power_cell_thresholds = [ + self.options.fire_canyon_cell_count.value, + self.options.mountain_pass_cell_count.value, + self.options.lava_tube_cell_count.value, + 100, # The 100 Power Cell Door. + ] + + # Order the thresholds ascending and set the options values to the new order. + if self.options.enable_ordered_cell_counts: + self.power_cell_thresholds.sort() + self.options.fire_canyon_cell_count.value = self.power_cell_thresholds[0] + self.options.mountain_pass_cell_count.value = self.power_cell_thresholds[1] + self.options.lava_tube_cell_count.value = self.power_cell_thresholds[2] + + # Store this for remove function. + self.power_cell_thresholds_minus_one = [x - 1 for x in self.power_cell_thresholds] + + # For the fairness of other players in a multiworld game, enforce some friendly limitations on our options, + # so we don't cause chaos during seed generation. These friendly limits should **guarantee** a successful gen. + # We would have done this earlier, but we needed to sort the power cell thresholds first. + enforce_friendly_options = self.settings.enforce_friendly_options + if enforce_friendly_options: + if self.multiworld.players > 1: + enforce_multiplayer_limits(self) + else: + enforce_singleplayer_limits(self) + + # Calculate the number of power cells needed for full region access, the number being replaced by traps, + # and the number of remaining filler. + if self.options.jak_completion_condition == options.CompletionCondition.option_open_100_cell_door: + self.total_prog_cells = 100 + else: + self.total_prog_cells = max(self.power_cell_thresholds[:3]) + non_prog_cells = self.total_power_cells - self.total_prog_cells + self.total_trap_cells = min(self.options.filler_power_cells_replaced_with_traps.value, non_prog_cells) + self.options.filler_power_cells_replaced_with_traps.value = self.total_trap_cells + self.total_filler_cells = non_prog_cells - self.total_trap_cells + + # Verify that we didn't overload the trade amounts with more orbs than exist in the world. + # This is easy to do by accident even in a singleplayer world. + self.total_trade_orbs = (9 * self.options.citizen_orb_trade_amount) + (6 * self.options.oracle_orb_trade_amount) + verify_orb_trade_amounts(self) + + # Cache the orb bundle size and item name for quicker reference. + if self.options.enable_orbsanity == options.EnableOrbsanity.option_per_level: + self.orb_bundle_size = self.options.level_orbsanity_bundle_size.value + self.orb_bundle_item_name = orb_item_table[self.orb_bundle_size] + elif self.options.enable_orbsanity == options.EnableOrbsanity.option_global: + self.orb_bundle_size = self.options.global_orbsanity_bundle_size.value + self.orb_bundle_item_name = orb_item_table[self.orb_bundle_size] + else: + self.orb_bundle_size = 0 + self.orb_bundle_item_name = "" + + # Calculate the number of orb bundles needed for trades, the number being replaced by traps, + # and the number of remaining filler. If Orbsanity is off, default values of 0 will prevail for all. + if self.orb_bundle_size > 0: + total_orb_bundles = self.total_orbs // self.orb_bundle_size + self.total_prog_orb_bundles = ceil(self.total_trade_orbs / self.orb_bundle_size) + non_prog_orb_bundles = total_orb_bundles - self.total_prog_orb_bundles + self.total_trap_orb_bundles = min(self.options.filler_orb_bundles_replaced_with_traps.value, + non_prog_orb_bundles) + self.options.filler_orb_bundles_replaced_with_traps.value = self.total_trap_orb_bundles + self.total_filler_orb_bundles = non_prog_orb_bundles - self.total_trap_orb_bundles + else: + self.options.filler_orb_bundles_replaced_with_traps.value = 0 + + self.trap_weights = self.options.trap_weights.weights_pair + + # Options drive which trade rules to use, so they need to be setup before we create_regions. + set_orb_trade_rule(self) + + # This will also set Locations, Location access rules, Region access rules, etc. + def create_regions(self) -> None: + create_regions(self) + + # Don't forget to add the created regions to the multiworld! + for level in self.level_to_regions: + self.multiworld.regions.extend(self.level_to_regions[level]) + + # As a lazy measure, let's also fill level_to_orb_regions here. + # This should help speed up orbsanity calculations. + self.level_to_orb_regions[level] = [reg for reg in self.level_to_regions[level] if reg.orb_count > 0] + + # from Utils import visualize_regions + # visualize_regions(self.multiworld.get_region("Menu", self.player), "jakanddaxter.puml") + + def item_data_helper(self, item: int) -> list[tuple[int, ItemClass, OrbAssoc, int]]: + """ + Helper function to reuse some nasty if/else trees. This outputs a list of pairs of item count and class. + For instance, not all 101 power cells need to be marked progression if you only need 72 to beat the game. + So we will have 72 Progression Power Cells, and 29 Filler Power Cells. + """ + data: list[tuple[int, ItemClass, OrbAssoc, int]] = [] + + # Make N Power Cells. We only want AP's Progression Fill routine to handle the amount of cells we need + # to reach the furthest possible region. Even for early completion goals, all areas in the game must be + # reachable or generation will fail. TODO - Option-driven region creation would be an enormous refactor. + if item in range(jak1_id, jak1_id + scouts.fly_offset): + data.append((self.total_prog_cells, ItemClass.progression_skip_balancing, OrbAssoc.IS_POWER_CELL, 0)) + data.append((self.total_filler_cells, ItemClass.filler, OrbAssoc.IS_POWER_CELL, 0)) + + # Make 7 Scout Flies per level. + elif item in range(jak1_id + scouts.fly_offset, jak1_id + specials.special_offset): + data.append((7, ItemClass.progression_skip_balancing, OrbAssoc.NEVER_UNLOCKS_ORBS, 0)) + + # Make only 1 of each Special Item. + elif item in range(jak1_id + specials.special_offset, jak1_id + caches.orb_cache_offset): + data.append((1, ItemClass.progression | ItemClass.useful, OrbAssoc.ALWAYS_UNLOCKS_ORBS, 0)) + + # Make only 1 of each Move Item. + elif item in range(jak1_id + caches.orb_cache_offset, jak1_id + orbs.orb_offset): + data.append((1, ItemClass.progression | ItemClass.useful, OrbAssoc.ALWAYS_UNLOCKS_ORBS, 0)) + + # Make N Precursor Orb bundles. Like Power Cells, only a fraction of these will be marked as Progression + # with the remainder as Filler, but they are still entirely fungible. See collect function for why these + # are OrbAssoc.NEVER_UNLOCKS_ORBS. + elif item in range(jak1_id + orbs.orb_offset, jak1_max - max(trap_item_table)): + data.append((self.total_prog_orb_bundles, ItemClass.progression_skip_balancing, + OrbAssoc.NEVER_UNLOCKS_ORBS, self.orb_bundle_size)) + data.append((self.total_filler_orb_bundles, ItemClass.filler, + OrbAssoc.NEVER_UNLOCKS_ORBS, self.orb_bundle_size)) + + # We will manually create trap items as needed. + elif item in range(jak1_max - max(trap_item_table), jak1_max): + data.append((0, ItemClass.trap, OrbAssoc.NEVER_UNLOCKS_ORBS, 0)) + + # We will manually create filler items as needed. + elif item == jak1_max: + data.append((0, ItemClass.filler, OrbAssoc.NEVER_UNLOCKS_ORBS, 0)) + + # If we try to make items with ID's higher than we've defined, something has gone wrong. + else: + raise KeyError(f"Tried to fill item pool with unknown ID {item}.") + + return data + + def create_items(self) -> None: + items_made: int = 0 + for item_name in self.item_name_to_id: + item_id = self.item_name_to_id[item_name] + + # Handle Move Randomizer option. + # If it is OFF, put all moves in your starting inventory instead of the item pool, + # then fill the item pool with a corresponding amount of filler items. + if item_name in self.item_name_groups["Moves"] and not self.options.enable_move_randomizer: + self.multiworld.push_precollected(self.create_item(item_name)) + self.multiworld.itempool.append(self.create_filler()) + items_made += 1 + continue + + # Handle Orbsanity option. + # If it is OFF, don't add any orb bundles to the item pool, period. + # If it is ON, don't add any orb bundles that don't match the chosen option. + if (item_name in self.item_name_groups["Precursor Orbs"] + and (self.options.enable_orbsanity == options.EnableOrbsanity.option_off + or item_name != self.orb_bundle_item_name)): + continue + + # Skip Traps for now. + if item_name in self.item_name_groups["Traps"]: + continue + + # In almost every other scenario, do this. Not all items with the same name will have the same item class. + data = self.item_data_helper(item_id) + for (count, classification, orb_assoc, orb_amount) in data: + self.multiworld.itempool += [JakAndDaxterItem(item_name, classification, item_id, + self.player, orb_assoc, orb_amount) + for _ in range(count)] + items_made += count + + # Handle Traps (for real). + # Manually fill the item pool with a weighted assortment of trap items, equal to the sum of + # total_trap_cells + total_trap_orb_bundles. Only do this if one or more traps have weights > 0. + names, weights = self.trap_weights + if sum(weights): + total_traps = self.total_trap_cells + self.total_trap_orb_bundles + trap_list = self.random.choices(names, weights=weights, k=total_traps) + self.multiworld.itempool += [self.create_item(trap_name) for trap_name in trap_list] + items_made += total_traps + + # Handle Unfilled Locations. + # Add an amount of filler items equal to the number of locations yet to be filled. + # This is the final set of items we will add to the pool. + all_regions = self.multiworld.get_regions(self.player) + total_locations = sum(reg.location_count for reg in cast(list[JakAndDaxterRegion], all_regions)) + total_filler = total_locations - items_made + self.multiworld.itempool += [self.create_filler() for _ in range(total_filler)] + + def create_item(self, name: str) -> Item: + item_id = self.item_name_to_id[name] + + # Use first tuple (will likely be the most important). + _, classification, orb_assoc, orb_amount = self.item_data_helper(item_id)[0] + return JakAndDaxterItem(name, classification, item_id, self.player, orb_assoc, orb_amount) + + def get_filler_item_name(self) -> str: + return "Green Eco Pill" + + def collect(self, state: CollectionState, item: JakAndDaxterItem) -> bool: + change = super().collect(state, item) + if change: + # Orbsanity as an option is no-factor to these conditions. Matching the item name implies Orbsanity is ON, + # so we don't need to check the option. When Orbsanity is OFF, there won't even be any orb bundle items + # to collect. + + # Orb items do not intrinsically unlock anything that contains more Reachable Orbs, so they do not need to + # set the cache to stale. They just change how many orbs you have to trade with. + if item.orb_amount > 0: + state.prog_items[self.player]["Tradeable Orbs"] += self.orb_bundle_size # Give a bundle of Trade Orbs + + # Power Cells DO unlock new regions that contain more Reachable Orbs - the connector levels and new + # hub levels - BUT they only do that when you have a number of them equal to one of the threshold values. + elif (item.orb_assoc == OrbAssoc.ALWAYS_UNLOCKS_ORBS + or (item.orb_assoc == OrbAssoc.IS_POWER_CELL + and state.count("Power Cell", self.player) in self.power_cell_thresholds)): + state.prog_items[self.player]["Reachable Orbs Fresh"] = False + + # However, every other item that does not have an appropriate OrbAssoc that changes the CollectionState + # should NOT set the cache to stale, because they did not make it possible to reach more orb locations + # (level unlocks, region unlocks, etc.). + return change + + def remove(self, state: CollectionState, item: JakAndDaxterItem) -> bool: + change = super().remove(state, item) + if change: + + # Do the same thing we did in collect, except subtract trade orbs instead of add. + if item.orb_amount > 0: + state.prog_items[self.player]["Tradeable Orbs"] -= self.orb_bundle_size # Take a bundle of Trade Orbs + + # Ditto Power Cells, but check thresholds - 1, because we potentially crossed the threshold in the opposite + # direction. E.g. we've removed the 20th power cell, our count is now 19, so we should stale the cache. + elif (item.orb_assoc == OrbAssoc.ALWAYS_UNLOCKS_ORBS + or (item.orb_assoc == OrbAssoc.IS_POWER_CELL + and state.count("Power Cell", self.player) in self.power_cell_thresholds_minus_one)): + state.prog_items[self.player]["Reachable Orbs Fresh"] = False + + return change + + def fill_slot_data(self) -> dict[str, Any]: + options_dict = self.options.as_dict("enable_move_randomizer", + "enable_orbsanity", + "global_orbsanity_bundle_size", + "level_orbsanity_bundle_size", + "fire_canyon_cell_count", + "mountain_pass_cell_count", + "lava_tube_cell_count", + "citizen_orb_trade_amount", + "oracle_orb_trade_amount", + "filler_power_cells_replaced_with_traps", + "filler_orb_bundles_replaced_with_traps", + "trap_effect_duration", + "trap_weights", + "jak_completion_condition", + "require_punch_for_klaww", + ) + return options_dict diff --git a/worlds/jakanddaxter/agents/__init__.py b/worlds/jakanddaxter/agents/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/worlds/jakanddaxter/agents/memory_reader.py b/worlds/jakanddaxter/agents/memory_reader.py new file mode 100644 index 000000000000..01035c4a2e1d --- /dev/null +++ b/worlds/jakanddaxter/agents/memory_reader.py @@ -0,0 +1,489 @@ +import logging +import random +import struct +from typing import ByteString, Callable +import json +import pymem +from pymem import pattern +from pymem.exception import ProcessNotFound, ProcessError, MemoryReadError, WinAPIError +from dataclasses import dataclass + +from ..locs import (orb_locations as orbs, + cell_locations as cells, + scout_locations as flies, + special_locations as specials, + orb_cache_locations as caches) + + +logger = logging.getLogger("MemoryReader") + + +# Some helpful constants. +sizeof_uint64 = 8 +sizeof_uint32 = 4 +sizeof_uint8 = 1 +sizeof_float = 4 + + +# ***************************************************************************** +# **** This number must match (-> *ap-info-jak1* version) in ap-struct.gc! **** +# ***************************************************************************** +expected_memory_version = 5 + + +# IMPORTANT: OpenGOAL memory structures are particular about the alignment, in memory, of member elements according to +# their size in bits. The address for an N-bit field must be divisible by N. Use this class to define the memory offsets +# of important values in the struct. It will also do the byte alignment properly for you. +# See https://opengoal.dev/docs/reference/type_system/#arrays +@dataclass +class OffsetFactory: + current_offset: int = 0 + + def define(self, size: int, length: int = 1) -> int: + + # If necessary, align current_offset to the current size first. + bytes_to_alignment = self.current_offset % size + if bytes_to_alignment != 0: + self.current_offset += (size - bytes_to_alignment) + + # Increment current_offset so the next definition can be made. + offset_to_use = self.current_offset + self.current_offset += (size * length) + return offset_to_use + + +# Start defining important memory address offsets here. They must be in the same order, have the same sizes, and have +# the same lengths, as defined in `ap-info-jak1`. +offsets = OffsetFactory() + +# Cell, Buzzer, and Special information. +next_cell_index_offset = offsets.define(sizeof_uint64) +next_buzzer_index_offset = offsets.define(sizeof_uint64) +next_special_index_offset = offsets.define(sizeof_uint64) + +cells_checked_offset = offsets.define(sizeof_uint32, 101) +buzzers_checked_offset = offsets.define(sizeof_uint32, 112) +specials_checked_offset = offsets.define(sizeof_uint32, 32) + +buzzers_received_offset = offsets.define(sizeof_uint8, 16) +specials_received_offset = offsets.define(sizeof_uint8, 32) + +# Deathlink information. +death_count_offset = offsets.define(sizeof_uint32) +death_cause_offset = offsets.define(sizeof_uint8) +deathlink_enabled_offset = offsets.define(sizeof_uint8) + +# Move Rando information. +next_orb_cache_index_offset = offsets.define(sizeof_uint64) +orb_caches_checked_offset = offsets.define(sizeof_uint32, 16) +moves_received_offset = offsets.define(sizeof_uint8, 16) +moverando_enabled_offset = offsets.define(sizeof_uint8) + +# Orbsanity information. +orbsanity_option_offset = offsets.define(sizeof_uint8) +orbsanity_bundle_offset = offsets.define(sizeof_uint32) +collected_bundle_offset = offsets.define(sizeof_uint32, 17) + +# Progression and Completion information. +fire_canyon_unlock_offset = offsets.define(sizeof_float) +mountain_pass_unlock_offset = offsets.define(sizeof_float) +lava_tube_unlock_offset = offsets.define(sizeof_float) +citizen_orb_amount_offset = offsets.define(sizeof_float) +oracle_orb_amount_offset = offsets.define(sizeof_float) +completion_goal_offset = offsets.define(sizeof_uint8) +completed_offset = offsets.define(sizeof_uint8) + +# Text to display in the HUD (32 char max per string). +their_item_name_offset = offsets.define(sizeof_uint8, 32) +their_item_owner_offset = offsets.define(sizeof_uint8, 32) +my_item_name_offset = offsets.define(sizeof_uint8, 32) +my_item_finder_offset = offsets.define(sizeof_uint8, 32) + +# Version of the memory struct, to cut down on mod/apworld version mismatches. +memory_version_offset = offsets.define(sizeof_uint32) + +# Connection status to AP server (not the game!) +server_connection_offset = offsets.define(sizeof_uint8) +slot_name_offset = offsets.define(sizeof_uint8, 16) +slot_seed_offset = offsets.define(sizeof_uint8, 8) + +# Trap information. +trap_duration_offset = offsets.define(sizeof_float) + +# The End. +end_marker_offset = offsets.define(sizeof_uint8, 4) + + +# Can't believe this is easier to do in GOAL than Python but that's how it be sometimes. +def as_float(value: int) -> int: + return int(struct.unpack('f', value.to_bytes(sizeof_float, "little"))[0]) + + +# "Jak" to be replaced by player name in the Client. +def autopsy(cause: int) -> str: + if cause in [1, 2, 3, 4]: + return random.choice(["Jak said goodnight.", + "Jak stepped into the light.", + "Jak gave Daxter his insect collection.", + "Jak did not follow Step 1."]) + if cause == 5: + return "Jak fell into an endless pit." + if cause == 6: + return "Jak drowned in the spicy water." + if cause == 7: + return "Jak tried to tackle a Lurker Shark." + if cause == 8: + return "Jak hit 500 degrees." + if cause == 9: + return "Jak took a bath in a pool of dark eco." + if cause == 10: + return "Jak got bombarded with flaming 30-ton boulders." + if cause == 11: + return "Jak hit 800 degrees." + if cause == 12: + return "Jak ceased to be." + if cause == 13: + return "Jak got eaten by the dark eco plant." + if cause == 14: + return "Jak burned up." + if cause == 15: + return "Jak hit the ground hard." + if cause == 16: + return "Jak crashed the zoomer." + if cause == 17: + return "Jak got Flut Flut hurt." + if cause == 18: + return "Jak poisoned the whole darn catch." + if cause == 19: + return "Jak collided with too many obstacles." + return "Jak died." + + +class JakAndDaxterMemoryReader: + marker: ByteString + goal_address: int | None = None + connected: bool = False + initiated_connect: bool = False + + # The memory reader just needs the game running. + gk_process: pymem.process = None + + location_outbox: list[int] = [] + outbox_index: int = 0 + finished_game: bool = False + + # Deathlink handling + deathlink_enabled: bool = False + send_deathlink: bool = False + cause_of_death: str = "" + death_count: int = 0 + + # Orbsanity handling + orbsanity_enabled: bool = False + orbs_paid: int = 0 + + # Game-related callbacks (inform the AP server of changes to game state) + inform_checked_location: Callable + inform_finished_game: Callable + inform_died: Callable + inform_toggled_deathlink: Callable + inform_traded_orbs: Callable + + # Logging callbacks + # These will write to the provided logger, as well as the Client GUI with color markup. + log_error: Callable # Red + log_warn: Callable # Orange + log_success: Callable # Green + log_info: Callable # White (default) + + def __init__(self, + location_check_callback: Callable, + finish_game_callback: Callable, + send_deathlink_callback: Callable, + toggle_deathlink_callback: Callable, + orb_trade_callback: Callable, + log_error_callback: Callable, + log_warn_callback: Callable, + log_success_callback: Callable, + log_info_callback: Callable, + marker: ByteString = b'UnLiStEdStRaTs_JaK1\x00'): + self.marker = marker + + self.inform_checked_location = location_check_callback + self.inform_finished_game = finish_game_callback + self.inform_died = send_deathlink_callback + self.inform_toggled_deathlink = toggle_deathlink_callback + self.inform_traded_orbs = orb_trade_callback + + self.log_error = log_error_callback + self.log_warn = log_warn_callback + self.log_success = log_success_callback + self.log_info = log_info_callback + + async def main_tick(self): + if self.initiated_connect: + await self.connect() + self.initiated_connect = False + + if self.connected: + try: + self.gk_process.read_bool(self.gk_process.base_address) # Ping to see if it's alive. + except (ProcessError, MemoryReadError, WinAPIError): + msg = (f"Error reading game memory! (Did the game crash?)\n" + f"Please close all open windows and reopen the Jak and Daxter Client " + f"from the Archipelago Launcher.\n" + f"If the game and compiler do not restart automatically, please follow these steps:\n" + f" Run the OpenGOAL Launcher, click Jak and Daxter > Features > Mods > ArchipelaGOAL.\n" + f" Then click Advanced > Play in Debug Mode.\n" + f" Then click Advanced > Open REPL.\n" + f" Then close and reopen the Jak and Daxter Client from the Archipelago Launcher.") + self.log_error(logger, msg) + self.connected = False + else: + return + + if self.connected: + + # Save some state variables temporarily. + old_deathlink_enabled = self.deathlink_enabled + + # Read the memory address to check the state of the game. + self.read_memory() + + # Checked Locations in game. Handle the entire outbox every tick until we're up to speed. + if len(self.location_outbox) > self.outbox_index: + self.inform_checked_location(self.location_outbox) + self.save_data() + self.outbox_index += 1 + + if self.finished_game: + self.inform_finished_game() + + if old_deathlink_enabled != self.deathlink_enabled: + self.inform_toggled_deathlink() + logger.debug("Toggled DeathLink " + ("ON" if self.deathlink_enabled else "OFF")) + + if self.send_deathlink: + self.inform_died() + + if self.orbs_paid > 0: + self.inform_traded_orbs(self.orbs_paid) + self.orbs_paid = 0 + + async def connect(self): + try: + self.gk_process = pymem.Pymem("gk.exe") # The GOAL Kernel + logger.debug("Found the gk process: " + str(self.gk_process.process_id)) + except ProcessNotFound: + self.log_error(logger, "Could not find the game process.") + self.connected = False + return + + # If we don't find the marker in the first loaded module, we've failed. + modules = list(self.gk_process.list_modules()) + marker_address = pattern.pattern_scan_module(self.gk_process.process_handle, modules[0], self.marker) + if marker_address: + # At this address is another address that contains the struct we're looking for: the game's state. + # From here we need to add the length in bytes for the marker and 4 bytes of padding, + # and the struct address is 8 bytes long (it's an uint64). + goal_pointer = marker_address + len(self.marker) + 4 + self.goal_address = int.from_bytes(self.gk_process.read_bytes(goal_pointer, sizeof_uint64), + byteorder="little", + signed=False) + logger.debug("Found the archipelago memory address: " + str(self.goal_address)) + await self.verify_memory_version() + else: + self.log_error(logger, "Could not find the Archipelago marker address!") + self.connected = False + + async def verify_memory_version(self): + if self.goal_address is None: + self.log_error(logger, "Could not find the Archipelago memory address!") + self.connected = False + return + + memory_version: int | None = None + try: + memory_version = self.read_goal_address(memory_version_offset, sizeof_uint32) + if memory_version == expected_memory_version: + self.log_success(logger, "The Memory Reader is ready!") + self.connected = True + else: + raise MemoryReadError(memory_version_offset, sizeof_uint32) + except (ProcessError, MemoryReadError, WinAPIError): + if memory_version is None: + msg = (f"Could not find a version number in the OpenGOAL memory structure!\n" + f" Expected Version: {str(expected_memory_version)}\n" + f" Found Version: {str(memory_version)}\n" + f"Please follow these steps:\n" + f" If the game is running, try entering '/memr connect' in the client.\n" + f" You should see 'The Memory Reader is ready!'\n" + f" If that did not work, or the game is not running, run the OpenGOAL Launcher.\n" + f" Click Jak and Daxter > Features > Mods > ArchipelaGOAL.\n" + f" Then click Advanced > Play in Debug Mode.\n" + f" Try entering '/memr connect' in the client again.") + else: + msg = (f"The OpenGOAL memory structure is incompatible with the current Archipelago client!\n" + f" Expected Version: {str(expected_memory_version)}\n" + f" Found Version: {str(memory_version)}\n" + f"Please follow these steps:\n" + f" Run the OpenGOAL Launcher, click Jak and Daxter > Features > Mods > ArchipelaGOAL.\n" + f" Click Update (if one is available).\n" + f" Click Advanced > Compile. When this is done, click Continue.\n" + f" Click Versions and verify the latest version is marked 'Active'.\n" + f" Close all launchers, games, clients, and console windows, then restart Archipelago.") + self.log_error(logger, msg) + self.connected = False + + async def print_status(self): + proc_id = str(self.gk_process.process_id) if self.gk_process else "None" + last_loc = str(self.location_outbox[self.outbox_index - 1] if self.outbox_index else "None") + msg = (f"Memory Reader Status:\n" + f" Game process ID: {proc_id}\n" + f" Game state memory address: {str(self.goal_address)}\n" + f" Last location checked: {last_loc}") + await self.verify_memory_version() + self.log_info(logger, msg) + + def read_memory(self) -> list[int]: + try: + # Need to grab these first and convert to floats, see below. + citizen_orb_amount = self.read_goal_address(citizen_orb_amount_offset, sizeof_float) + oracle_orb_amount = self.read_goal_address(oracle_orb_amount_offset, sizeof_float) + + next_cell_index = self.read_goal_address(next_cell_index_offset, sizeof_uint64) + for k in range(0, next_cell_index): + next_cell = self.read_goal_address(cells_checked_offset + (k * sizeof_uint32), sizeof_uint32) + cell_ap_id = cells.to_ap_id(next_cell) + if cell_ap_id not in self.location_outbox: + self.location_outbox.append(cell_ap_id) + logger.debug("Checked power cell: " + str(next_cell)) + + # If orbsanity is ON and next_cell is one of the traders or oracles, then run a callback + # to add their amount to the DataStorage value holding our current orb trade total. + if next_cell in {11, 12, 31, 32, 33, 96, 97, 98, 99}: + citizen_orb_amount = as_float(citizen_orb_amount) + self.orbs_paid += citizen_orb_amount + logger.debug(f"Traded {citizen_orb_amount} orbs!") + + if next_cell in {13, 14, 34, 35, 100, 101}: + oracle_orb_amount = as_float(oracle_orb_amount) + self.orbs_paid += oracle_orb_amount + logger.debug(f"Traded {oracle_orb_amount} orbs!") + + next_buzzer_index = self.read_goal_address(next_buzzer_index_offset, sizeof_uint64) + for k in range(0, next_buzzer_index): + next_buzzer = self.read_goal_address(buzzers_checked_offset + (k * sizeof_uint32), sizeof_uint32) + buzzer_ap_id = flies.to_ap_id(next_buzzer) + if buzzer_ap_id not in self.location_outbox: + self.location_outbox.append(buzzer_ap_id) + logger.debug("Checked scout fly: " + str(next_buzzer)) + + next_special_index = self.read_goal_address(next_special_index_offset, sizeof_uint64) + for k in range(0, next_special_index): + next_special = self.read_goal_address(specials_checked_offset + (k * sizeof_uint32), sizeof_uint32) + special_ap_id = specials.to_ap_id(next_special) + if special_ap_id not in self.location_outbox: + self.location_outbox.append(special_ap_id) + logger.debug("Checked special: " + str(next_special)) + + death_count = self.read_goal_address(death_count_offset, sizeof_uint32) + death_cause = self.read_goal_address(death_cause_offset, sizeof_uint8) + if death_count > self.death_count: + self.cause_of_death = autopsy(death_cause) # The way he names his variables? Wack! + self.send_deathlink = True + self.death_count += 1 + + # Listen for any changes to this setting. + deathlink_flag = self.read_goal_address(deathlink_enabled_offset, sizeof_uint8) + self.deathlink_enabled = bool(deathlink_flag) + + next_cache_index = self.read_goal_address(next_orb_cache_index_offset, sizeof_uint64) + for k in range(0, next_cache_index): + next_cache = self.read_goal_address(orb_caches_checked_offset + (k * sizeof_uint32), sizeof_uint32) + cache_ap_id = caches.to_ap_id(next_cache) + if cache_ap_id not in self.location_outbox: + self.location_outbox.append(cache_ap_id) + logger.debug("Checked orb cache: " + str(next_cache)) + + # Listen for any changes to this setting. + # moverando_flag = self.read_goal_address(moverando_enabled_offset, sizeof_uint8) + # self.moverando_enabled = bool(moverando_flag) + + orbsanity_option = self.read_goal_address(orbsanity_option_offset, sizeof_uint8) + bundle_size = self.read_goal_address(orbsanity_bundle_offset, sizeof_uint32) + self.orbsanity_enabled = orbsanity_option > 0 + + # Per Level Orbsanity option. Only need to do this loop if we chose this setting. + if orbsanity_option == 1: + for level in range(0, 16): + collected_bundles = self.read_goal_address(collected_bundle_offset + (level * sizeof_uint32), + sizeof_uint32) + + # Count up from the first bundle, by bundle size, until you reach the latest collected bundle. + # e.g. {25, 50, 75, 100, 125...} + if collected_bundles > 0: + for bundle in range(bundle_size, + bundle_size + collected_bundles, # Range max is non-inclusive. + bundle_size): + + bundle_ap_id = orbs.to_ap_id(orbs.find_address(level, bundle, bundle_size)) + if bundle_ap_id not in self.location_outbox: + self.location_outbox.append(bundle_ap_id) + logger.debug(f"Checked orb bundle: L{level} {bundle}") + + # Global Orbsanity option. Index 16 refers to all orbs found regardless of level. + if orbsanity_option == 2: + collected_bundles = self.read_goal_address(collected_bundle_offset + (16 * sizeof_uint32), + sizeof_uint32) + if collected_bundles > 0: + for bundle in range(bundle_size, + bundle_size + collected_bundles, # Range max is non-inclusive. + bundle_size): + + bundle_ap_id = orbs.to_ap_id(orbs.find_address(16, bundle, bundle_size)) + if bundle_ap_id not in self.location_outbox: + self.location_outbox.append(bundle_ap_id) + logger.debug(f"Checked orb bundle: G {bundle}") + + completed = self.read_goal_address(completed_offset, sizeof_uint8) + if completed > 0 and not self.finished_game: + self.finished_game = True + self.log_success(logger, "Congratulations! You finished the game!") + + except (ProcessError, MemoryReadError, WinAPIError): + msg = (f"Error reading game memory! (Did the game crash?)\n" + f"Please close all open windows and reopen the Jak and Daxter Client " + f"from the Archipelago Launcher.\n" + f"If the game and compiler do not restart automatically, please follow these steps:\n" + f" Run the OpenGOAL Launcher, click Jak and Daxter > Features > Mods > ArchipelaGOAL.\n" + f" Then click Advanced > Play in Debug Mode.\n" + f" Then click Advanced > Open REPL.\n" + f" Then close and reopen the Jak and Daxter Client from the Archipelago Launcher.") + self.log_error(logger, msg) + self.connected = False + + return self.location_outbox + + def read_goal_address(self, offset: int, length: int) -> int: + return int.from_bytes( + self.gk_process.read_bytes(self.goal_address + offset, length), + byteorder="little", + signed=False) + + def save_data(self): + with open("jakanddaxter_location_outbox.json", "w+") as f: + dump = { + "outbox_index": self.outbox_index, + "location_outbox": self.location_outbox + } + json.dump(dump, f, indent=4) + + def load_data(self): + try: + with open("jakanddaxter_location_outbox.json", "r") as f: + load = json.load(f) + self.outbox_index = load["outbox_index"] + self.location_outbox = load["location_outbox"] + except FileNotFoundError: + pass diff --git a/worlds/jakanddaxter/agents/repl_client.py b/worlds/jakanddaxter/agents/repl_client.py new file mode 100644 index 000000000000..b207bba281c3 --- /dev/null +++ b/worlds/jakanddaxter/agents/repl_client.py @@ -0,0 +1,527 @@ +import json +import logging +import queue +import time +import struct +import random +from dataclasses import dataclass +from queue import Queue +from typing import Callable + +import pymem +from pymem.exception import ProcessNotFound, ProcessError + +import asyncio +from asyncio import StreamReader, StreamWriter, Lock + +from NetUtils import NetworkItem +from ..game_id import jak1_id, jak1_max +from ..items import item_table, trap_item_table +from ..locs import ( + orb_locations as orbs, + cell_locations as cells, + scout_locations as flies, + special_locations as specials, + orb_cache_locations as caches) + + +logger = logging.getLogger("ReplClient") + + +@dataclass +class JsonMessageData: + my_item_name: str | None = None + my_item_finder: str | None = None + their_item_name: str | None = None + their_item_owner: str | None = None + + +ALLOWED_CHARACTERS = frozenset({ + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", + "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", + "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", + "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", + "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", + "y", "z", " ", "!", ":", ",", ".", "/", "?", "-", + "=", "+", "'", "(", ")", "\"" +}) + + +class JakAndDaxterReplClient: + ip: str + port: int + reader: StreamReader + writer: StreamWriter + lock: Lock + connected: bool = False + initiated_connect: bool = False # Signals when user tells us to try reconnecting. + received_deathlink: bool = False + balanced_orbs: bool = False + + # Variables to handle the title screen and initial game connection. + initial_item_count = -1 # Brand new games have 0 items, so initialize this to -1. + received_initial_items = False + processed_initial_items = False + + # The REPL client needs the REPL/compiler process running, but that process + # also needs the game running. Therefore, the REPL client needs both running. + gk_process: pymem.process = None + goalc_process: pymem.process = None + + item_inbox: dict[int, NetworkItem] = {} + inbox_index = 0 + json_message_queue: Queue[JsonMessageData] = queue.Queue() + + # Logging callbacks + # These will write to the provided logger, as well as the Client GUI with color markup. + log_error: Callable # Red + log_warn: Callable # Orange + log_success: Callable # Green + log_info: Callable # White (default) + + def __init__(self, + log_error_callback: Callable, + log_warn_callback: Callable, + log_success_callback: Callable, + log_info_callback: Callable, + ip: str = "127.0.0.1", + port: int = 8181): + self.ip = ip + self.port = port + self.lock = asyncio.Lock() + self.log_error = log_error_callback + self.log_warn = log_warn_callback + self.log_success = log_success_callback + self.log_info = log_info_callback + + async def main_tick(self): + if self.initiated_connect: + await self.connect() + self.initiated_connect = False + + if self.connected: + try: + self.gk_process.read_bool(self.gk_process.base_address) # Ping to see if it's alive. + except ProcessError: + msg = (f"Error reading game memory! (Did the game crash?)\n" + f"Please close all open windows and reopen the Jak and Daxter Client " + f"from the Archipelago Launcher.\n" + f"If the game and compiler do not restart automatically, please follow these steps:\n" + f" Run the OpenGOAL Launcher, click Jak and Daxter > Features > Mods > ArchipelaGOAL.\n" + f" Then click Advanced > Play in Debug Mode.\n" + f" Then click Advanced > Open REPL.\n" + f" Then close and reopen the Jak and Daxter Client from the Archipelago Launcher.") + self.log_error(logger, msg) + self.connected = False + try: + self.goalc_process.read_bool(self.goalc_process.base_address) # Ping to see if it's alive. + except ProcessError: + msg = (f"Error sending data to compiler! (Did the compiler crash?)\n" + f"Please close all open windows and reopen the Jak and Daxter Client " + f"from the Archipelago Launcher.\n" + f"If the game and compiler do not restart automatically, please follow these steps:\n" + f" Run the OpenGOAL Launcher, click Jak and Daxter > Features > Mods > ArchipelaGOAL.\n" + f" Then click Advanced > Play in Debug Mode.\n" + f" Then click Advanced > Open REPL.\n" + f" Then close and reopen the Jak and Daxter Client from the Archipelago Launcher.") + self.log_error(logger, msg) + self.connected = False + else: + return + + # When connecting the game to the AP server on the title screen, we may be processing items from starting + # inventory or items received in an async game. Once we have caught up to the initial count, tell the player + # that we are ready to start. New items may even come in during the title screen, so if we go over the count, + # we should still send the ready signal. + if not self.processed_initial_items: + if self.inbox_index >= self.initial_item_count >= 0: + self.processed_initial_items = True + await self.send_connection_status("ready") + + # Receive Items from AP. Handle 1 item per tick. + if len(self.item_inbox) > self.inbox_index: + await self.receive_item() + await self.save_data() + self.inbox_index += 1 + + if self.received_deathlink: + await self.receive_deathlink() + self.received_deathlink = False + + # Progressively empty the queue during each tick + # if text messages happen to be too slow we could pool dequeuing here, + # but it'd slow down the ItemReceived message during release + if not self.json_message_queue.empty(): + json_txt_data = self.json_message_queue.get_nowait() + await self.write_game_text(json_txt_data) + + # This helper function formats and sends `form` as a command to the REPL. + # ALL commands to the REPL should be sent using this function. + async def send_form(self, form: str, print_ok: bool = True) -> bool: + header = struct.pack(" str: + result = "".join([c if c in ALLOWED_CHARACTERS else "?" for c in text[:32]]).upper() + result = result.replace("'", "\\c12") + return f"\"{result}\"" + + # Like sanitize_game_text, but the settings file will NOT allow any whitespace in the slot_name or slot_seed data. + # And don't replace any chars with "?" for good measure. + @staticmethod + def sanitize_file_text(text: str) -> str: + allowed_chars_no_extras = ALLOWED_CHARACTERS - {" ", "'", "(", ")", "\""} + result = "".join([c if c in allowed_chars_no_extras else "" for c in text[:16]]).upper() + return f"\"{result}\"" + + # Pushes a JsonMessageData object to the json message queue to be processed during the repl main_tick + def queue_game_text(self, my_item_name, my_item_finder, their_item_name, their_item_owner): + self.json_message_queue.put(JsonMessageData(my_item_name, my_item_finder, their_item_name, their_item_owner)) + + # OpenGOAL can handle both its own string datatype and C-like character pointers (charp). + async def write_game_text(self, data: JsonMessageData): + logger.debug(f"Sending info to the in-game messenger!") + body = "" + if data.my_item_name and data.my_item_finder: + body += (f" (append-messages (-> *ap-messenger* 0) \'recv " + f" {self.sanitize_game_text(data.my_item_name)} " + f" {self.sanitize_game_text(data.my_item_finder)})") + if data.their_item_name and data.their_item_owner: + body += (f" (append-messages (-> *ap-messenger* 0) \'sent " + f" {self.sanitize_game_text(data.their_item_name)} " + f" {self.sanitize_game_text(data.their_item_owner)})") + await self.send_form(f"(begin {body} (none))", print_ok=False) + + async def receive_item(self): + ap_id = getattr(self.item_inbox[self.inbox_index], "item") + + # Determine the type of item to receive. + if ap_id in range(jak1_id, jak1_id + flies.fly_offset): + await self.receive_power_cell(ap_id) + elif ap_id in range(jak1_id + flies.fly_offset, jak1_id + specials.special_offset): + await self.receive_scout_fly(ap_id) + elif ap_id in range(jak1_id + specials.special_offset, jak1_id + caches.orb_cache_offset): + await self.receive_special(ap_id) + elif ap_id in range(jak1_id + caches.orb_cache_offset, jak1_id + orbs.orb_offset): + await self.receive_move(ap_id) + elif ap_id in range(jak1_id + orbs.orb_offset, jak1_max - max(trap_item_table)): + await self.receive_precursor_orb(ap_id) # Ponder the orbs. + elif ap_id in range(jak1_max - max(trap_item_table), jak1_max): + await self.receive_trap(ap_id) + elif ap_id == jak1_max: + await self.receive_green_eco() # Ponder why I chose to do ID's this way. + else: + self.log_error(logger, f"Tried to receive item with unknown AP ID {ap_id}!") + + async def receive_power_cell(self, ap_id: int) -> bool: + cell_id = cells.to_game_id(ap_id) + ok = await self.send_form("(send-event " + "*target* \'get-archipelago " + "(pickup-type fuel-cell) " + "(the float " + str(cell_id) + "))") + if ok: + logger.debug(f"Received a Power Cell!") + else: + self.log_error(logger, f"Unable to receive a Power Cell!") + return ok + + async def receive_scout_fly(self, ap_id: int) -> bool: + fly_id = flies.to_game_id(ap_id) + ok = await self.send_form("(send-event " + "*target* \'get-archipelago " + "(pickup-type buzzer) " + "(the float " + str(fly_id) + "))") + if ok: + logger.debug(f"Received a {item_table[ap_id]}!") + else: + self.log_error(logger, f"Unable to receive a {item_table[ap_id]}!") + return ok + + async def receive_special(self, ap_id: int) -> bool: + special_id = specials.to_game_id(ap_id) + ok = await self.send_form("(send-event " + "*target* \'get-archipelago " + "(pickup-type ap-special) " + "(the float " + str(special_id) + "))") + if ok: + logger.debug(f"Received special unlock {item_table[ap_id]}!") + else: + self.log_error(logger, f"Unable to receive special unlock {item_table[ap_id]}!") + return ok + + async def receive_move(self, ap_id: int) -> bool: + move_id = caches.to_game_id(ap_id) + ok = await self.send_form("(send-event " + "*target* \'get-archipelago " + "(pickup-type ap-move) " + "(the float " + str(move_id) + "))") + if ok: + logger.debug(f"Received the ability to {item_table[ap_id]}!") + else: + self.log_error(logger, f"Unable to receive the ability to {item_table[ap_id]}!") + return ok + + async def receive_precursor_orb(self, ap_id: int) -> bool: + orb_amount = orbs.to_game_id(ap_id) + ok = await self.send_form("(send-event " + "*target* \'get-archipelago " + "(pickup-type money) " + "(the float " + str(orb_amount) + "))") + if ok: + logger.debug(f"Received {orb_amount} Precursor orbs!") + else: + self.log_error(logger, f"Unable to receive {orb_amount} Precursor orbs!") + return ok + + async def receive_trap(self, ap_id: int) -> bool: + trap_id = jak1_max - ap_id + ok = await self.send_form("(send-event " + "*target* \'get-archipelago " + "(pickup-type ap-trap) " + "(the float " + str(trap_id) + "))") + if ok: + logger.debug(f"Received a {item_table[ap_id]}!") + else: + self.log_error(logger, f"Unable to receive a {item_table[ap_id]}!") + return ok + + # Green eco pills are our filler item. Use the get-pickup event instead to handle being full health. + async def receive_green_eco(self) -> bool: + ok = await self.send_form("(send-event *target* \'get-pickup (pickup-type eco-pill) (the float 1))") + if ok: + logger.debug(f"Received a green eco pill!") + else: + self.log_error(logger, f"Unable to receive a green eco pill!") + return ok + + async def receive_deathlink(self) -> bool: + + # Because it should at least be funny sometimes. + death_types = ["\'death", + "\'death", + "\'death", + "\'death", + "\'endlessfall", + "\'drown-death", + "\'melt", + "\'dark-eco-pool"] + chosen_death = random.choice(death_types) + + ok = await self.send_form("(ap-deathlink-received! " + chosen_death + ")") + if ok: + logger.debug(f"Received deathlink signal!") + else: + self.log_error(logger, f"Unable to receive deathlink signal!") + return ok + + async def subtract_traded_orbs(self, orb_count: int) -> bool: + + # To protect against momentary server disconnects, + # this should only be done once per client session. + if not self.balanced_orbs: + self.balanced_orbs = True + + ok = await self.send_form(f"(-! (-> *game-info* money) (the float {orb_count}))") + if ok: + logger.debug(f"Subtracting {orb_count} traded orbs!") + else: + self.log_error(logger, f"Unable to subtract {orb_count} traded orbs!") + return ok + + return True + + # OpenGOAL has a limit of 8 parameters per function. We've already hit this limit. So, define a new datatype + # in OpenGOAL that holds all these options, instantiate the type here, and have ap-setup-options! function take + # that instance as input. + async def setup_options(self, + os_option: int, os_bundle: int, + fc_count: int, mp_count: int, + lt_count: int, ct_amount: int, + ot_amount: int, trap_time: int, + goal_id: int, slot_name: str, + slot_seed: str) -> bool: + sanitized_name = self.sanitize_file_text(slot_name) + sanitized_seed = self.sanitize_file_text(slot_seed) + + # I didn't want to have to do this with floats but GOAL's compile-time vs runtime types leave me no choice. + ok = await self.send_form(f"(ap-setup-options! (new 'static 'ap-seed-options " + f":orbsanity-option {os_option} " + f":orbsanity-bundle {os_bundle} " + f":fire-canyon-unlock {fc_count}.0 " + f":mountain-pass-unlock {mp_count}.0 " + f":lava-tube-unlock {lt_count}.0 " + f":citizen-orb-amount {ct_amount}.0 " + f":oracle-orb-amount {ot_amount}.0 " + f":trap-duration {trap_time}.0 " + f":completion-goal {goal_id} " + f":slot-name {sanitized_name} " + f":slot-seed {sanitized_seed} ))") + message = (f"Setting options: \n" + f" orbsanity Option {os_option}, orbsanity Bundle {os_bundle}, \n" + f" FC Cell Count {fc_count}, MP Cell Count {mp_count}, \n" + f" LT Cell Count {lt_count}, Citizen Orb Amt {ct_amount}, \n" + f" Oracle Orb Amt {ot_amount}, Trap Duration {trap_time}, \n" + f" Completion GOAL {goal_id}, Slot Name {sanitized_name}, \n" + f" Slot Seed {sanitized_seed}... ") + if ok: + logger.debug(message + "Success!") + else: + self.log_error(logger, message + "Failed!") + + return ok + + async def send_connection_status(self, status: str) -> bool: + ok = await self.send_form(f"(ap-set-connection-status! (connection-status {status}))") + if ok: + logger.debug(f"Connection Status {status} set!") + else: + self.log_error(logger, f"Connection Status {status} failed to set!") + + return ok + + async def save_data(self): + with open("jakanddaxter_item_inbox.json", "w+") as f: + dump = { + "inbox_index": self.inbox_index, + "item_inbox": [{ + "item": self.item_inbox[k].item, + "location": self.item_inbox[k].location, + "player": self.item_inbox[k].player, + "flags": self.item_inbox[k].flags + } for k in self.item_inbox + ] + } + json.dump(dump, f, indent=4) + + def load_data(self): + try: + with open("jakanddaxter_item_inbox.json", "r") as f: + load = json.load(f) + self.inbox_index = load["inbox_index"] + self.item_inbox = {k: NetworkItem( + item=load["item_inbox"][k]["item"], + location=load["item_inbox"][k]["location"], + player=load["item_inbox"][k]["player"], + flags=load["item_inbox"][k]["flags"] + ) for k in range(0, len(load["item_inbox"])) + } + except FileNotFoundError: + pass diff --git a/worlds/jakanddaxter/client.py b/worlds/jakanddaxter/client.py new file mode 100644 index 000000000000..2b669d384714 --- /dev/null +++ b/worlds/jakanddaxter/client.py @@ -0,0 +1,600 @@ +# Python standard libraries +import asyncio +import json +import logging +import os +import subprocess +import sys + +from asyncio import Task +from datetime import datetime +from logging import Logger +from typing import Awaitable + +# Misc imports +import colorama +import pymem + +from pymem.exception import ProcessNotFound + +# Archipelago imports +import ModuleUpdate +import Utils + +from CommonClient import ClientCommandProcessor, CommonContext, server_loop, gui_enabled +from NetUtils import ClientStatus + +# Jak imports +from .game_id import jak1_name +from .options import EnableOrbsanity +from .agents.memory_reader import JakAndDaxterMemoryReader +from .agents.repl_client import JakAndDaxterReplClient +from . import JakAndDaxterWorld + + +ModuleUpdate.update() +logger = logging.getLogger("JakClient") +all_tasks: set[Task] = set() + + +def create_task_log_exception(awaitable: Awaitable) -> asyncio.Task: + async def _log_exception(a): + try: + return await a + except Exception as e: + logger.exception(e) + finally: + all_tasks.remove(task) + task = asyncio.create_task(_log_exception(awaitable)) + all_tasks.add(task) + return task + + +class JakAndDaxterClientCommandProcessor(ClientCommandProcessor): + ctx: "JakAndDaxterContext" + + # The command processor is not async so long-running operations like the /repl connect command + # (which takes 10-15 seconds to compile the game) have to be requested with user-initiated flags. + # The flags are checked by the agents every main_tick. + def _cmd_repl(self, *arguments: str): + """Sends a command to the OpenGOAL REPL. Arguments: + - connect : connect the client to the REPL (goalc). + - status : check internal status of the REPL.""" + if arguments: + if arguments[0] == "connect": + self.ctx.on_log_info(logger, "This may take a bit... Wait for the success audio cue before continuing!") + self.ctx.repl.initiated_connect = True + if arguments[0] == "status": + create_task_log_exception(self.ctx.repl.print_status()) + + def _cmd_memr(self, *arguments: str): + """Sends a command to the Memory Reader. Arguments: + - connect : connect the memory reader to the game process (gk). + - status : check the internal status of the Memory Reader.""" + if arguments: + if arguments[0] == "connect": + self.ctx.memr.initiated_connect = True + if arguments[0] == "status": + create_task_log_exception(self.ctx.memr.print_status()) + + +class JakAndDaxterContext(CommonContext): + game = jak1_name + items_handling = 0b111 # Full item handling + command_processor = JakAndDaxterClientCommandProcessor + + # We'll need two agents working in tandem to handle two-way communication with the game. + # The REPL Client will handle the server->game direction by issuing commands directly to the running game. + # But the REPL cannot send information back to us, it only ingests information we send it. + # Luckily OpenGOAL sets up memory addresses to write to, that AutoSplit can read from, for speedrunning. + # We'll piggyback off this system with a Memory Reader, and that will handle the game->server direction. + repl: JakAndDaxterReplClient + memr: JakAndDaxterMemoryReader + + # And two associated tasks, so we have handles on them. + repl_task: asyncio.Task + memr_task: asyncio.Task + + # Storing some information for writing save slot identifiers. + slot_seed: str + + def __init__(self, server_address: str | None, password: str | None) -> None: + self.repl = JakAndDaxterReplClient(self.on_log_error, + self.on_log_warn, + self.on_log_success, + self.on_log_info) + self.memr = JakAndDaxterMemoryReader(self.on_location_check, + self.on_finish_check, + self.on_deathlink_check, + self.on_deathlink_toggle, + self.on_orb_trade, + self.on_log_error, + self.on_log_warn, + self.on_log_success, + self.on_log_info) + # self.repl.load_data() + # self.memr.load_data() + super().__init__(server_address, password) + + def run_gui(self): + from kvui import GameManager + + class JakAndDaxterManager(GameManager): + logging_pairs = [ + ("Client", "Archipelago") + ] + base_title = "Jak and Daxter ArchipelaGOAL Client" + + self.ui = JakAndDaxterManager(self) + self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI") + + async def server_auth(self, password_requested: bool = False): + if password_requested and not self.password: + await super(JakAndDaxterContext, self).server_auth(password_requested) + await self.get_username() + self.tags = set() + await self.send_connect() + + def on_package(self, cmd: str, args: dict): + + if cmd == "RoomInfo": + self.slot_seed = args["seed_name"] + + if cmd == "Connected": + slot_data = args["slot_data"] + orbsanity_option = slot_data["enable_orbsanity"] + if orbsanity_option == EnableOrbsanity.option_per_level: + orbsanity_bundle = slot_data["level_orbsanity_bundle_size"] + elif orbsanity_option == EnableOrbsanity.option_global: + orbsanity_bundle = slot_data["global_orbsanity_bundle_size"] + else: + orbsanity_bundle = 1 + + # Connected packet is unaware of starting inventory or if player is returning to an existing game. + # Set initial_item_count to 0, see below comments for more info. + if not self.repl.received_initial_items and self.repl.initial_item_count < 0: + self.repl.initial_item_count = 0 + + create_task_log_exception( + self.repl.setup_options(orbsanity_option, + orbsanity_bundle, + slot_data["fire_canyon_cell_count"], + slot_data["mountain_pass_cell_count"], + slot_data["lava_tube_cell_count"], + slot_data["citizen_orb_trade_amount"], + slot_data["oracle_orb_trade_amount"], + slot_data["trap_effect_duration"], + slot_data["jak_completion_condition"], + self.auth[:16], # The slot name + self.slot_seed[:8])) + + # Because Orbsanity and the orb traders in the game are intrinsically linked, we need the server + # to track our trades at all times to support async play. "Retrieved" will tell us the orbs we lost, + # while "ReceivedItems" will tell us the orbs we gained. This will give us the correct balance. + if orbsanity_option in [EnableOrbsanity.option_per_level, EnableOrbsanity.option_global]: + async def get_orb_balance(): + await self.send_msgs([{"cmd": "Get", "keys": [f"jakanddaxter_{self.auth}_orbs_paid"]}]) + + create_task_log_exception(get_orb_balance()) + + # Tell the server if Deathlink is enabled or disabled in the in-game options. + # This allows us to "remember" the user's choice. + self.on_deathlink_toggle() + + if cmd == "Retrieved": + if f"jakanddaxter_{self.auth}_orbs_paid" in args["keys"]: + orbs_traded = args["keys"][f"jakanddaxter_{self.auth}_orbs_paid"] + orbs_traded = orbs_traded if orbs_traded is not None else 0 + create_task_log_exception(self.repl.subtract_traded_orbs(orbs_traded)) + + if cmd == "ReceivedItems": + + # If you have a starting inventory or are returning to a game where you have items, a ReceivedItems will be + # in the same network packet as Connected. This guarantees it is the first of any ReceivedItems we process. + # In this case, we should set the initial_item_count to > 0, even if already set to 0 by Connected, as well + # as the received_initial_items flag. Finally, use send_connection_status to tell the player to wait while + # we process the initial items. However, we will skip all this if there was no initial ReceivedItems and + # the REPL indicates it already handled any initial items (0 or otherwise). + if not self.repl.received_initial_items and not self.repl.processed_initial_items: + self.repl.received_initial_items = True + self.repl.initial_item_count = len(args["items"]) + create_task_log_exception(self.repl.send_connection_status("wait")) + + # This enumeration should run on every ReceivedItems packet, + # regardless of it being on initial connection or midway through a game. + for index, item in enumerate(args["items"], start=args["index"]): + logger.debug(f"index: {str(index)}, item: {str(item)}") + self.repl.item_inbox[index] = item + + async def json_to_game_text(self, args: dict): + if "type" in args and args["type"] in {"ItemSend"}: + my_item_name: str | None = None + my_item_finder: str | None = None + their_item_name: str | None = None + their_item_owner: str | None = None + + item = args["item"] + recipient = args["receiving"] + + # Receiving an item from the server. + if self.slot_concerns_self(recipient): + my_item_name = self.item_names.lookup_in_game(item.item) + + # Did we find it, or did someone else? + if self.slot_concerns_self(item.player): + my_item_finder = "MYSELF" + else: + my_item_finder = self.player_names[item.player] + + # Sending an item to the server. + if self.slot_concerns_self(item.player): + their_item_name = self.item_names.lookup_in_slot(item.item, recipient) + + # Does it belong to us, or to someone else? + if self.slot_concerns_self(recipient): + their_item_owner = "MYSELF" + else: + their_item_owner = self.player_names[recipient] + + # Write to game display. + self.repl.queue_game_text(my_item_name, my_item_finder, their_item_name, their_item_owner) + + # Even though N items come in as 1 ReceivedItems packet, there are still N PrintJson packets to process, + # and they all arrive before the ReceivedItems packet does. Defer processing of these packets as + # async tasks to speed up large releases of items. + def on_print_json(self, args: dict) -> None: + create_task_log_exception(self.json_to_game_text(args)) + super(JakAndDaxterContext, self).on_print_json(args) + + # We need to do a little more than just use CommonClient's on_deathlink. + def on_deathlink(self, data: dict): + if self.memr.deathlink_enabled: + self.repl.received_deathlink = True + super().on_deathlink(data) + + # We don't need an ap_inform function because check_locations solves that need. + def on_location_check(self, location_ids: list[int]): + create_task_log_exception(self.check_locations(location_ids)) + + # CommonClient has no finished_game function, so we will have to craft our own. TODO - Update if that changes. + async def ap_inform_finished_game(self): + if not self.finished_game and self.memr.finished_game: + message = [{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}] + await self.send_msgs(message) + self.finished_game = True + + def on_finish_check(self): + create_task_log_exception(self.ap_inform_finished_game()) + + # We need to do a little more than just use CommonClient's send_death. + async def ap_inform_deathlink(self): + if self.memr.deathlink_enabled: + player = self.player_names[self.slot] if self.slot is not None else "Jak" + death_text = self.memr.cause_of_death.replace("Jak", player) + await self.send_death(death_text) + self.on_log_warn(logger, death_text) + + # Reset all flags, but leave the death count alone. + self.memr.send_deathlink = False + self.memr.cause_of_death = "" + + def on_deathlink_check(self): + create_task_log_exception(self.ap_inform_deathlink()) + + # We don't need an ap_inform function because update_death_link solves that need. + def on_deathlink_toggle(self): + create_task_log_exception(self.update_death_link(self.memr.deathlink_enabled)) + + # Orb trades are situations unique to Jak, so we have to craft our own function. + async def ap_inform_orb_trade(self, orbs_changed: int): + if self.memr.orbsanity_enabled: + await self.send_msgs([{"cmd": "Set", + "key": f"jakanddaxter_{self.auth}_orbs_paid", + "default": 0, + "want_reply": False, + "operations": [{"operation": "add", "value": orbs_changed}] + }]) + + def on_orb_trade(self, orbs_changed: int): + create_task_log_exception(self.ap_inform_orb_trade(orbs_changed)) + + def _markup_panels(self, msg: str, c: str = None): + color = self.jsontotextparser.color_codes[c] if c else None + message = f"[color={color}]{msg}[/color]" if c else msg + + self.ui.log_panels["Archipelago"].on_message_markup(message) + self.ui.log_panels["All"].on_message_markup(message) + + def on_log_error(self, lg: Logger, message: str): + lg.error(message) + if self.ui: + self._markup_panels(message, "red") + + def on_log_warn(self, lg: Logger, message: str): + lg.warning(message) + if self.ui: + self._markup_panels(message, "orange") + + def on_log_success(self, lg: Logger, message: str): + lg.info(message) + if self.ui: + self._markup_panels(message, "green") + + def on_log_info(self, lg: Logger, message: str): + lg.info(message) + if self.ui: + self._markup_panels(message) + + async def run_repl_loop(self): + while True: + await self.repl.main_tick() + await asyncio.sleep(0.1) + + async def run_memr_loop(self): + while True: + await self.memr.main_tick() + await asyncio.sleep(0.1) + + +def find_root_directory(ctx: JakAndDaxterContext): + + # The path to this file is platform-dependent. + if Utils.is_windows: + appdata = os.getenv("APPDATA") + settings_path = os.path.normpath(f"{appdata}/OpenGOAL-Launcher/settings.json") + elif Utils.is_linux: + home = os.path.expanduser("~") + settings_path = os.path.normpath(f"{home}/.config/OpenGOAL-Launcher/settings.json") + elif Utils.is_macos: + home = os.path.expanduser("~") + settings_path = os.path.normpath(f"{home}/Library/Application Support/OpenGOAL-Launcher/settings.json") + else: + ctx.on_log_error(logger, f"Unknown operating system: {sys.platform}!") + return + + # Boilerplate messages that all error messages in this function should have. + err_title = "Unable to locate the ArchipelaGOAL install directory" + alt_instructions = (f"Please verify that OpenGOAL and ArchipelaGOAL are installed properly. " + f"If the problem persists, follow these steps:\n" + f" Run the OpenGOAL Launcher, click Jak and Daxter > Features > Mods > ArchipelaGOAL.\n" + f" Then click Advanced > Open Game Data Folder.\n" + f" Go up one folder, then copy this path.\n" + f" Run the Archipelago Launcher, click Open host.yaml.\n" + f" Set the value of 'jakanddaxter_options > root_directory' to this path.\n" + f" Replace all backslashes in the path with forward slashes.\n" + f" Set the value of 'jakanddaxter_options > auto_detect_root_directory' to false, " + f"then save and close the host.yaml file.\n" + f" Close all launchers, games, clients, and console windows, then restart Archipelago.") + + if not os.path.exists(settings_path): + msg = (f"{err_title}: the OpenGOAL settings file does not exist.\n" + f"{alt_instructions}") + ctx.on_log_error(logger, msg) + return + + with open(settings_path, "r") as f: + load = json.load(f) + + jak1_installed = load["games"]["Jak 1"]["isInstalled"] + if not jak1_installed: + msg = (f"{err_title}: The OpenGOAL Launcher is missing a normal install of Jak 1!\n" + f"{alt_instructions}") + ctx.on_log_error(logger, msg) + return + + mod_sources = load["games"]["Jak 1"]["modsInstalledVersion"] + if mod_sources is None: + msg = (f"{err_title}: No mod sources have been configured in the OpenGOAL Launcher!\n" + f"{alt_instructions}") + ctx.on_log_error(logger, msg) + return + + # Mods can come from multiple user-defined sources. + # Make no assumptions about where ArchipelaGOAL comes from, we should find it ourselves. + archipelagoal_source = None + for src in mod_sources: + for mod in mod_sources[src].keys(): + if mod == "archipelagoal": + archipelagoal_source = src + # Using this file, we could verify the right version is installed, but we don't need to. + if archipelagoal_source is None: + msg = (f"{err_title}: The ArchipelaGOAL mod is not installed in the OpenGOAL Launcher!\n" + f"{alt_instructions}") + ctx.on_log_error(logger, msg) + return + + # This is just the base OpenGOAL directory, we need to go deeper. + base_path = load["installationDir"] + mod_relative_path = f"features/jak1/mods/{archipelagoal_source}/archipelagoal" + mod_path = os.path.normpath( + os.path.join( + os.path.normpath(base_path), + os.path.normpath(mod_relative_path))) + + return mod_path + + +async def run_game(ctx: JakAndDaxterContext): + + # These may already be running. If they are not running, try to start them. + # TODO - Support other OS's. 1: Pymem is Windows-only. 2: on Linux, there's no ".exe." + gk_running = False + try: + pymem.Pymem("gk.exe") # The GOAL Kernel + gk_running = True + except ProcessNotFound: + ctx.on_log_warn(logger, "Game not running, attempting to start.") + + goalc_running = False + try: + pymem.Pymem("goalc.exe") # The GOAL Compiler and REPL + goalc_running = True + except ProcessNotFound: + ctx.on_log_warn(logger, "Compiler not running, attempting to start.") + + try: + auto_detect_root_directory = JakAndDaxterWorld.settings.auto_detect_root_directory + if auto_detect_root_directory: + root_path = find_root_directory(ctx) + else: + root_path = JakAndDaxterWorld.settings.root_directory + + # Always trust your instincts... the user may not have entered their root_directory properly. + # We don't have to do this check if the root directory was auto-detected. + if "/" not in root_path: + msg = (f"The ArchipelaGOAL root directory contains no path. (Are you missing forward slashes?)\n" + f"Please check your host.yaml file.\n" + f"Verify the value of 'jakanddaxter_options > root_directory' is a valid existing path, " + f"and all backslashes have been replaced with forward slashes.") + ctx.on_log_error(logger, msg) + return + + # Start by checking the existence of the root directory provided in the host.yaml file (or found automatically). + root_path = os.path.normpath(root_path) + if not os.path.exists(root_path): + msg = (f"The ArchipelaGOAL root directory does not exist, unable to locate the Game and Compiler.\n" + f"Please check your host.yaml file.\n" + f"If the value of 'jakanddaxter_options > auto_detect_root_directory' is true, verify that OpenGOAL " + f"is installed properly.\n" + f"If it is false, check the value of 'jakanddaxter_options > root_directory'. " + f"Verify it is a valid existing path, and all backslashes have been replaced with forward slashes.") + ctx.on_log_error(logger, msg) + return + + # Now double-check the existence of the two executables we need. + gk_path = os.path.join(root_path, "gk.exe") + goalc_path = os.path.join(root_path, "goalc.exe") + if not os.path.exists(gk_path) or not os.path.exists(goalc_path): + msg = (f"The Game and Compiler could not be found in the ArchipelaGOAL root directory.\n" + f"Please check your host.yaml file.\n" + f"If the value of 'jakanddaxter_options > auto_detect_root_directory' is true, verify that OpenGOAL " + f"is installed properly.\n" + f"If it is false, check the value of 'jakanddaxter_options > root_directory'. " + f"Verify it is a valid existing path, and all backslashes have been replaced with forward slashes.") + ctx.on_log_error(logger, msg) + return + + # Now we can FINALLY attempt to start the programs. + if not gk_running: + # Per-mod saves and settings are stored outside the ArchipelaGOAL root folder, so we have to traverse + # a relative path, normalize it, and pass it in as an argument to gk. This folder will be created if + # it does not exist. + config_relative_path = "../_settings/archipelagoal" + config_path = os.path.normpath( + os.path.join( + root_path, + os.path.normpath(config_relative_path))) + + # The game freezes if text is inadvertently selected in the stdout/stderr data streams. Let's pipe those + # streams to a file, and let's not clutter the screen with another console window. + timestamp = datetime.now().strftime("%Y_%m_%d_%H_%M_%S") + log_path = os.path.join(Utils.user_path("logs"), f"JakAndDaxterGame_{timestamp}.txt") + log_path = os.path.normpath(log_path) + with open(log_path, "w") as log_file: + gk_process = subprocess.Popen( + [gk_path, "--game", "jak1", + "--config-path", config_path, + "--", "-v", "-boot", "-fakeiso", "-debug"], + stdout=log_file, + stderr=log_file, + creationflags=subprocess.CREATE_NO_WINDOW) + + if not goalc_running: + # For the OpenGOAL Compiler, the existence of the "data" subfolder indicates you are running it from + # a built package. This subfolder is treated as its proj_path. + proj_path = os.path.join(root_path, "data") + if os.path.exists(proj_path): + + # Look for "iso_data" path to automate away an oft-forgotten manual step of mod updates. + # All relative paths should start from root_path and end with "jak1". + goalc_args = [] + possible_relative_paths = { + "../../../../../active/jak1/data/iso_data/jak1", + "./data/iso_data/jak1", + } + + for iso_relative_path in possible_relative_paths: + iso_path = os.path.normpath( + os.path.join( + root_path, + os.path.normpath(iso_relative_path))) + + if os.path.exists(iso_path): + goalc_args = [goalc_path, "--game", "jak1", "--proj-path", proj_path, "--iso-path", iso_path] + logger.debug(f"iso_data folder found: {iso_path}") + break + else: + logger.debug(f"iso_data folder not found, continuing: {iso_path}") + + if not goalc_args: + msg = (f"The iso_data folder could not be found.\n" + f"Please follow these steps:\n" + f" Run the OpenGOAL Launcher, click Jak and Daxter > Advanced > Open Game Data Folder.\n" + f" Copy the iso_data folder from this location.\n" + f" Click Jak and Daxter > Features > Mods > ArchipelaGOAL > Advanced > " + f"Open Game Data Folder.\n" + f" Paste the iso_data folder in this location.\n" + f" Click Advanced > Compile. When this is done, click Continue.\n" + f" Close all launchers, games, clients, and console windows, then restart Archipelago.\n" + f"(See Setup Guide for more details.)") + ctx.on_log_error(logger, msg) + return + + # The non-existence of the "data" subfolder indicates you are running it from source, as a developer. + # The compiler will traverse upward to find the project path on its own. It will also assume your + # "iso_data" folder is at the root of your repository. Therefore, we don't need any of those arguments. + else: + goalc_args = [goalc_path, "--game", "jak1"] + + # This needs to be a new console. The REPL console cannot share a window with any other process. + goalc_process = subprocess.Popen(goalc_args, creationflags=subprocess.CREATE_NEW_CONSOLE) + + except AttributeError as e: + if " " in e.args[0]: + # YAML keys in Host.yaml ought to contain no spaces, which means this is a much more important error. + ctx.on_log_error(logger, e.args[0]) + else: + ctx.on_log_error(logger, + f"Host.yaml does not contain {e.args[0]}, unable to locate game executables.") + return + except FileNotFoundError as e: + msg = (f"The following path could not be found: {e.filename}\n" + f"Please check your host.yaml file.\n" + f"If the value of 'jakanddaxter_options > auto_detect_root_directory' is true, verify that OpenGOAL " + f"is installed properly.\n" + f"If it is false, check the value of 'jakanddaxter_options > root_directory'." + f"Verify it is a valid existing path, and all backslashes have been replaced with forward slashes.") + ctx.on_log_error(logger, msg) + return + + # Auto connect the repl and memr agents. Sleep 5 because goalc takes just a little bit of time to load, + # and it's not something we can await. + ctx.on_log_info(logger, "This may take a bit... Wait for the game's title sequence before continuing!") + await asyncio.sleep(5) + ctx.repl.initiated_connect = True + ctx.memr.initiated_connect = True + + +async def main(): + Utils.init_logging("JakAndDaxterClient", exception_logger="Client") + + ctx = JakAndDaxterContext(None, None) + ctx.server_task = asyncio.create_task(server_loop(ctx), name="server loop") + ctx.repl_task = create_task_log_exception(ctx.run_repl_loop()) + ctx.memr_task = create_task_log_exception(ctx.run_memr_loop()) + + if gui_enabled: + ctx.run_gui() + ctx.run_cli() + + # Find and run the game (gk) and compiler/repl (goalc). + create_task_log_exception(run_game(ctx)) + await ctx.exit_event.wait() + await ctx.shutdown() + + +def launch(): + # use colorama to display colored text highlighting + colorama.just_fix_windows_console() + asyncio.run(main()) + colorama.deinit() diff --git a/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md b/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md new file mode 100644 index 000000000000..6cf8ae54a529 --- /dev/null +++ b/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md @@ -0,0 +1,258 @@ +# Jak And Daxter (ArchipelaGOAL) + +## FAQ +- [Where is the Options page?](#where-is-the-options-page) +- [What does randomization do to this game?](#what-does-randomization-do-to-this-game) +- [What are the Special Checks and how do I check them?](#what-are-the-special-checks-and-how-do-i-check-them) +- [What are the Special Items and what do they unlock?](#what-are-the-special-items-and-what-do-they-unlock) +- [How do I know which Special Items I have?](#how-do-i-know-which-special-items-i-have) +- [What is the goal of the game once randomized?](#what-is-the-goal-of-the-game-once-randomized) +- [What happens when I pick up or receive a Power Cell?](#what-happens-when-i-pick-up-or-receive-a-power-cell) +- [What happens when I pick up or receive a Scout Fly?](#what-happens-when-i-pick-up-or-receive-a-scout-fly) +- [How do I check the 'Free 7 Scout Flies' Power Cell?](#how-do-i-check-the-free-7-scout-flies-power-cell) +- [What does Death Link do?](#what-does-death-link-do) +- [What does Move Randomizer do?](#what-does-move-randomizer-do) +- [What are the movement options in Move Randomizer?](#what-are-the-movement-options-in-move-randomizer) +- [How do I know which moves I have?](#how-do-i-know-which-moves-i-have) +- [What does Orbsanity do?](#what-does-orbsanity-do) +- [What do Traps do?](#what-do-traps-do) +- [What kind of Traps are there?](#what-kind-of-traps-are-there) +- [I got soft-locked and cannot leave, how do I get out of here?](#i-got-soft-locked-and-cannot-leave-how-do-i-get-out-of-here) +- [Why did I get an Option Error when generating a seed, and how do I fix it?](#why-did-i-get-an-option-error-when-generating-a-seed-and-how-do-i-fix-it) +- [How do I check my player options in-game?](#how-do-i-check-my-player-options-in-game) +- [How does the HUD work?](#how-does-the-hud-work) +- [I think I found a bug, where should I report it?](#i-think-i-found-a-bug-where-should-i-report-it) + +## Where is the options page + +The [Player Options Page](../player-options) for this game contains all the options you need to configure and export +a config file. + +At this time, there are several caveats and restrictions: +- Power Cells and Scout Flies are **always** randomized. +- **All** the traders in the game become in-logic checks **if and only if** you have enough Orbs to pay all of them at once. + - This is to prevent hard locks, where an item required for progression is locked behind a trade you can't afford because you spent the orbs elsewhere. + - By default, that total is 1530. + +## What does randomization do to this game +The game now contains the following Location checks: +- All 101 Power Cells +- All 112 Scout Flies +- All 14 Orb Caches (collect every orb in the cache and let it close) + +These may contain Items for different games, as well as different Items from within Jak and Daxter. +Additionally, several special checks and corresponding items have been added that are required to complete the game. + +## What are the special checks and how do I check them +| Check Name | How To Check | +|------------------------|------------------------------------------------------------------------------| +| Fisherman's Boat | Complete the fishing minigame in Forbidden Jungle | +| Jungle Elevator | Collect the power cell at the top of the temple in Forbidden Jungle | +| Blue Eco Switch | Collect the power cell on the blue vent switch in Forbidden Jungle | +| Flut Flut | Push the egg off the cliff in Sentinel Beach and talk to the bird lady | +| Warrior's Pontoons | Talk to the Warrior in Rock Village once (you do NOT have to trade with him) | +| Snowy Mountain Gondola | Approach the gondola in Volcanic Crater | +| Yellow Eco Switch | Collect the power cell on the yellow vent switch in Snowy Mountain | +| Snowy Fort Gate | Ride the Flut Flut in Snowy Mountain and press the fort gate switch | +| Freed The Blue Sage | Free the Blue Sage in Gol and Maia's Citadel | +| Freed The Red Sage | Free the Red Sage in Gol and Maia's Citadel | +| Freed The Yellow Sage | Free the Yellow Sage in Gol and Maia's Citadel | +| Freed The Green Sage | Free the Green Sage in Gol and Maia's Citadel | + +## What are the special items and what do they unlock +| Item Name | What it Unlocks | +|--------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------| +| Fisherman's Boat | Misty Island | +| Jungle Elevator | The blue vent switch inside the temple in Forbidden Jungle | +| Blue Eco Switch | The plant boss inside the temple in Forbidden Jungle
The cannon tower in Sentinel Beach | +| Flut Flut | The upper platforms in Boggy Swamp
The fort gate switch in Snowy Mountain | +| Warrior's Pontoons | Boggy Swamp and Mountain Pass | +| Snowy Mountain Gondola | Snowy Mountain | +| Yellow Eco Switch | The frozen box in Snowy Mountain
The shortcut in Mountain Pass | +| Snowy Fort Gate | The fort in Snowy Mountain | +| Freed The Blue Sage
Freed The Red Sage
Freed The Yellow Sage | The final staircase in Gol and Maia's Citadel | +| Freed The Green Sage | The final elevator in Gol and Maia's Citadel | + +## How do I know which special items I have +Open the game's menu, navigate to `Options`, then `Archipelago Options`, then `Item Tracker`. +This will show you a list of all the special items in the game, ones not normally tracked as power cells or scout flies. +Gray items indicate you do not possess that item, light blue items indicate you possess that item. + +## What is the goal of the game once randomized +By default, to complete the game you must defeat the Gol and Maia and stop them from opening the Dark Eco silo. In order +to reach them, you will need at least 72 Power Cells to cross the Lava Tube, as well as the four special items for +freeing the Red, Blue, Yellow, and Green Sages. + +Alternatively, you can choose from a handful of other completion conditions like defeating a particular boss, crossing +a particular connector level, or opening the 100 Power Cell door after defeating the final boss. You can also customize +the thresholds for connector levels and orb trades. These options allow you to tailor the expected length and difficulty +of your run as you see fit. + +## What happens when I pick up or receive a power cell +When you pick up a power cell, Jak and Daxter will perform their victory animation. Your power cell count will +NOT change. The pause menu will say "Task Completed" below the picked-up Power Cell. If your power cell was related +to one of the special checks listed above, you will automatically check that location as well - a 2 for 1 deal! +Finally, your text client will inform you what you found and who it belongs to. + +When you receive a power cell, your power cell count will tick up by 1. Gameplay will otherwise continue as normal. +Finally, your text client will inform you where you received the power cell from. + +## What happens when I pick up or receive a scout fly +When you pick up a scout fly, your scout fly count will NOT change. The pause menu will show you the number of +scout flies you picked up per-region, and this number will have ticked up by 1 for the region that scout fly belongs to. +Finally, your text client will inform you what you found and who it belongs to. + +When you receive a scout fly, your total scout fly count will tick up by 1. The pause menu will show you the number of +scout flies you received per-region, and this number will have ticked up by 1 for the region that scout fly belongs to. +Finally, your text client will inform you where you received the scout fly from, and which one it is. + +## How do I check the Free 7 Scout Flies power cell +You will automatically check this power cell when you _receive_ your 7th scout fly, NOT when you _pick up_ your 7th +scout fly. So in short: + +- When you _pick up_ your 7th fly, the normal rules apply. +- When you _receive_ your 7th fly, 2 things will happen in quick succession. + - First, you will receive that scout fly, as normal. + - Second, you will immediately complete the "Free 7 Scout Flies" check, which will send out another item. + +## What does Death Link do +If you enable Death Link, all the other players in your Multiworld who also have it enabled will be linked by death. +That means when Jak dies in your game, the players in with Death Link also die. Likewise, if any of the other +players with Death Link die, Jak will also die in a random, possibly spectacular fashion. + +You can turn off Death Link at any time in the game by opening the game's menu and navigating to `Options`, +then `Archipelago Options`, then `Deathlink`. + +## What does Move Randomizer do +If you enable Move Randomizer, most of Jak's movement set will be added to the randomized item pool, and you will need +to receive the move in order to use it (i.e. you must find it, or another player must send it to you). Some moves have +prerequisite moves that you must also have in order to use them (e.g. Crouch Jump is dependent on Crouch). Jak will only +be able to run, swim (including underwater), perform single jumps, and shoot yellow eco from his goggles ("firing from +the hip" requires Punch). Note that Flut Flut and the Zoomer will have access to their full movement sets at all times. + +You can turn off Move Rando at any time in the game by opening the game's menu, navigate to `Options`, +then `Archipelago Options`, then `Move Randomizer`. This will give you access to the full movement set again. + +## What are the movement options in Move Randomizer +| Move Name | Prerequisite Moves | +|-----------------|--------------------| +| Crouch | | +| Crouch Jump | Crouch | +| Crouch Uppercut | Crouch | +| Roll | | +| Roll Jump | Roll | +| Double Jump | | +| Jump Dive | | +| Jump Kick | | +| Punch | | +| Punch Uppercut | Punch | +| Kick | | + +## How do I know which moves I have +Open the game's menu, navigate to `Options`, then `Archipelago Options`, then `Move Tracker`. +This will show you a list of all the moves in the game. +- Gray items indicate you do not possess that move. +- Yellow items indicate you possess that move, but you are missing its prerequisites. +- Light blue items indicate you possess that move, as well as its prerequisites. + +## What does Orbsanity do +If you enable Orbsanity, bundles of Precursor Orbs will be turned into checks. Every time you collect the chosen number +of orbs, i.e. a "bundle," you will trigger another check. Likewise, the orbs will be added to the random item pool. +There are several options to change the difficulty of this challenge. + +- "Per Level" Orbsanity means the bundles are for each level in the game. (Geyser Rock, Sandover Village, etc.) +- "Global" Orbsanity means orbs collected from any level count toward the next bundle. +- The options with "Bundle Size" in the name indicate how many orbs are in a bundle. This adds a number of Items + and Locations to the pool inversely proportional to the size of the bundle. + - For example, if your bundle size is 20 orbs, you will add 100 items to the pool. If your bundle size is 250 orbs, + you will add 8 items to the pool. + +## What do Traps do +When creating your player YAML, you can choose to replace some of the game's extraneous Power Cells and Precursor Orbs +with traps. You can choose which traps you want to generate in your seed and how long they last. A random assortment +will then be chosen to populate the item pool. + +When you receive one, you will hear a buzzer and some kind of negative effect will occur in game. These effects may be +challenging, maddening, or entertaining. When the trap duration ends, the game should return to its previous state. +Multiple traps can be active at the same time, and they may interact with each other in strange ways. If they become +too frustrating, you can lower their duration by navigating to `Options`, then `Archipelago Options`, then +`Seed Options`, then `Trap Duration`. Lowering this number to zero will disable traps entirely. + +## What kind of Traps are there +| Trap Name | Effect | +|-----------------|--------------------------------------------------------------------------------| +| Trip Trap | Jak trips and falls | +| Slippery Trap | The world gains the physical properties of Snowy Mountain's ice lake | +| Gravity Trap | Jak falls to the ground faster and takes fall damage more easily | +| Camera Trap | The camera remains fixed in place no matter how far away Jak moves | +| Darkness Trap | The world gains the lighting properties of Dark Cave | +| Earthquake Trap | The world and camera shake | +| Teleport Trap | Jak immediately teleports to Samos's Hut | +| Despair Trap | The Warrior sobs profusely | +| Pacifism Trap | Jak's attacks have no effect on enemies, crates, or buttons | +| Ecoless Trap | Jak's eco is drained and he cannot collect new eco | +| Health Trap | Jak's health is set to 0 - not dead yet, but he will die to any attack or bonk | +| Ledge Trap | Jak cannot grab onto ledges | +| Zoomer Trap | Jak mounts an invisible zoomer (model loads properly depending on level) | +| Mirror Trap | The world is mirrored | + +## I got soft-locked and cannot leave how do I get out of here +Open the game's menu, navigate to `Options`, then `Archipelago Options`, then `Warp To Home`. +Selecting this option will ask if you want to be teleported to Geyser Rock. From there, you can teleport back +to the nearest sage's hut to continue your journey. + +## Why did I get an Option Error when generating a seed and how do I fix it +Depending on your player YAML, Jak and Daxter can have a lot of items, which can sometimes be overwhelming or +disruptive to multiworld games. There are also options that are mutually incompatible with each other, even in a solo +game. To prevent the game from disrupting multiworlds, or generating an impossible solo seed, some options have +Singleplayer and Multiplayer Minimums and Maximums, collectively called "friendly limits." + +If you're generating a solo game, or your multiworld host agrees to your request, you can override those limits by +editing the `host.yaml`. In the Archipelago Launcher, click `Open host.yaml`, then search for `jakanddaxter_options`, +then search for `enforce_friendly_options`, then change this value from `true` to `false`. Disabling this allows for +more disruptive and challenging options, but it may cause seed generation to fail. **Use at your own risk!** + +## How do I check my player options in-game +When you connect your text client to the Archipelago Server, the server will tell the game what options were chosen +for this seed, and the game will apply those settings automatically. + +You can verify these options by navigating to `Options`, then `Archipelago Options`, then `Seed Options`. **You can open +each option to verify them, but you should NOT alter them during a run.** This may cause you to miss important +progression items and prevent you (and others) from completing the run. + +## How does the HUD work +The game's normal HUD shows you how many power cells, precursor orbs, and scout flies you currently have. But if you +hold `L2 or R2` and press a direction on the D-Pad, the HUD will show you alternate modes. Here is how the HUD works: + +| HUD Mode | Button Combo | What the HUD Shows | Text Messages | +|---------------|------------------------------|-----------------------------------|---------------------------------------| +| Per-Level | `L2 or R2` + `Down` | Locations Checked (in this level) | `SENT {Other Item} TO {Other Player}` | +| Global | `L2 or R2` + `Up` | Locations Checked (in the game) | `GOT {Your Item} FROM {Other Player}` | +| Normal | `L2 or R2` + `Left or Right` | Items Received | Both Sent and Got Messages | +| | | | | +| (In Any Mode) | | (If you sent an Item to Yourself) | `FOUND {Your Item}` | + +In all modes, the last 3 sent/received items and the player who sent/received it will be displayed in the +bottom left corner. This will help you quickly reference information about newly received or sent items. Items in blue +are Progression (or non-Jak items), in green are Filler, and in red are Traps. You can turn this off by navigating +to `Options`, then `Archipelago Options`, then set `Item Messages` to `Off`. + +## I think I found a bug where should I report it +Depending on the nature of the bug, there are a couple of different options. + +* If you found a logical error in the randomizer, please create a new Issue +[here](https://github.com/ArchipelaGOAL/Archipelago/issues). Use this page if: + * An item required for progression is unreachable. + * The randomizer did not respect one of the Options you chose. + * You see a mistake, typo, etc. on this webpage. + * You see an error or stack trace appear on the text client. + +* If you encountered an error in OpenGOAL, please create a new Issue +[here](https://github.com/ArchipelaGOAL/ArchipelaGOAL/issues). Use this page if: + * You encounter a crash, freeze, reset, etc. in the game. + * You fail to send Items you find in the game to the Archipelago server. + * You fail to receive Items the server sends to you. + * Your game disconnects from the server and cannot reconnect. + * You go looking for a game item that has already disappeared before you could reach it. + +* Please upload your config file, spoiler log file, and any other generated logs in the Issue, so we can troubleshoot the problem. \ No newline at end of file diff --git a/worlds/jakanddaxter/docs/setup_en.md b/worlds/jakanddaxter/docs/setup_en.md new file mode 100644 index 000000000000..509fb3ad8dcb --- /dev/null +++ b/worlds/jakanddaxter/docs/setup_en.md @@ -0,0 +1,182 @@ +# Jak And Daxter (ArchipelaGOAL) Setup Guide + +## Required Software + +- A legally purchased copy of *Jak And Daxter: The Precursor Legacy.* +- [The OpenGOAL Launcher](https://opengoal.dev/) +- [The Jak and Daxter .APWORLD package](https://github.com/ArchipelaGOAL/Archipelago/releases) + +At this time, this method of setup works on Windows only, but Linux support is a strong likelihood in the near future as OpenGOAL itself supports Linux. + +## Installation via OpenGOAL Launcher + +**You must set up a vanilla installation of Jak and Daxter before you can install mods for it.** + +- Follow the installation process for the official OpenGOAL Launcher. See [here](https://opengoal.dev/docs/usage/installation). +- Follow the setup process for adding mods to the OpenGOAL Launcher. See [here](https://jakmods.dev/). +- Run the OpenGOAL Launcher (if you had it open before, close it and reopen it). +- Click the Jak and Daxter logo on the left sidebar. +- Click `Features` in the bottom right corner, then click `Mods`. +- Under `Available Mods`, click `ArchipelaGOAL`. The mod should begin installing. When it is done, click `Continue` in the bottom right corner. +- **DO NOT PLAY AN ARCHIPELAGO GAME THROUGH THE OPENGOAL LAUNCHER.** The Archipelago Client should handle everything for you. + +### For NTSC versions of the game, follow these steps. + +- Run the OpenGOAL Launcher (if you had it open before, close it and reopen it). +- Click the Jak and Daxter logo on the left sidebar. +- Click `Features` in the bottom right corner, then click `Mods`, then under `Installed Mods`, click `ArchipelaGOAL`. +- In the bottom right corner, click `Advanced`, then click `Compile`. + +### For PAL versions of the game, follow these steps. + +PAL versions of the game seem to require additional troubleshooting/setup in order to work properly. +Below are some instructions that may help. +If you see `-- Compilation Error! --` after pressing `Compile` or Launching the ArchipelaGOAL mod, try these steps. + +- Remove these folders if you have them: + - `/iso_data` + - `/iso_data` + - `/data/iso_data` +- Place your Jak1 ISO in `` and rename it to `JakAndDaxter.iso` +- Type `cmd` in Windows search, right click `Command Prompt`, and pick `Run as Administrator` +- Run `cd ` +- Then run `.\extractor.exe --extract --extract-path .\data\iso_data "JakAndDaxter.iso"` + - This command should end by saying `Uses Decompiler Config Version - ntsc_v1` or `... - pal`. Take note of this message. +- If you saw `ntsc_v1`: + - In cmd, run `.\decompiler.exe data\decompiler\config\jak1\jak1_config.jsonc --version "ntsc_v1" data\iso_data data\decompiler_out` +- If you saw `pal`: + - Rename `\data\iso_data\jak1` to `jak1_pal` + - Back in cmd, run `.\decompiler.exe data\decompiler\config\jak1\jak1_config.jsonc --version "pal" data\iso_data data\decompiler_out` + - Rename `\data\iso_data\jak1_pal` back to `jak1` + - Rename `\data\decompiler_out\jak1_pal` back to `jak1` +- Open a **brand new** console window and launch the compiler: + - `cd ` + - `.\goalc.exe --user-auto --game jak1` + - From the compiler (in the same window): `(mi)`. This should compile the game. **Note that the parentheses are important.** + - **Don't close this first terminal, you will need it at the end.** +- Then, open **another brand new** console window and execute the game: + - `cd ` + - `.\gk.exe -v --game jak1 -- -boot -fakeiso -debug` +- Finally, **from the first console still in the GOALC compiler**, connect to the game: `(lt)`. + +## Updates and New Releases via OpenGOAL Launcher + +If you are in the middle of an async game, and you do not want to update the mod, you do not need to do this step. The mod will only update when you tell it to. + +- Run the OpenGOAL Launcher (if you had it open before, close it and reopen it). +- Click the Jak and Daxter logo on the left sidebar. +- Click `Features` in the bottom right corner, then click `Mods`, then under `Installed Mods`, click `ArchipelaGOAL`. +- Click `Update` to download and install any new updates that have been released. +- You can verify your version by clicking `Versions`. The version you are using will say `(Active)` next to it. +- **Then you must click `Advanced`, then click `Compile` to make the update take effect.** + +## Starting a Game + +### New Game + +- Run the Archipelago Launcher. +- From the right-most list, find and click `Jak and Daxter Client`. +- 3 new windows should appear: + - The OpenGOAL compiler will launch and compile the game. They should take about 30 seconds to compile. + - You should hear a musical cue to indicate the compilation was a success. If you do not, see the Troubleshooting section. + - You can **MINIMIZE** the Compiler window, **BUT DO NOT CLOSE IT.** It is required for Archipelago and the game to communicate with each other. + - The game window itself will launch, and Jak will be standing outside Samos's Hut. + - Once compilation is complete, the title sequence will start. + - Finally, the Archipelago text client will open. + - If you see **BOTH** `The REPL is ready!` and `The Memory Reader is ready!` then that should indicate a successful startup. If you do not, see the Troubleshooting section. +- Once you see `CONNECT TO ARCHIPELAGO NOW` on the title screen, use the text client to connect to the Archipelago server. This will communicate your current settings and slot info to the game. +- If you see `RECEIVING ITEMS, PLEASE WAIT...`, the game is busy receiving items from your starting inventory, assuming you have some. +- Once you see `READY! PRESS START TO CONTINUE` on the title screen, you can press Start. +- Choose `New Game`, choose a save file, and play through the opening cutscenes. +- Once you reach Geyser Rock, the game has begun! + - You can leave Geyser Rock immediately if you so choose - just step on the warp gate button. + +### Returning / Async Game +The same steps as New Game apply, with some exceptions: + +- Once you reach the title screen, connect to the Archipelago server **BEFORE** you load your save file. + - This is to allow AP to give the game your current settings and all the items you had previously. + - **THESE SETTINGS AFFECT LOADING AND SAVING OF SAVE FILES, SO IT IS IMPORTANT TO DO THIS FIRST.** +- Once you see `READY! PRESS START TO CONTINUE` on the title screen, you can press Start. +- Instead of choosing `New Game` in the title menu, choose `Load Game`, then choose the save file **THAT HAS YOUR CURRENT SLOT NAME.** + - To help you find the correct save file, highlighting a save will show you that save's slot name and the first 8 digits of the multiworld seed number. + +## Troubleshooting + +### The Text Client Says "Unable to locate the OpenGOAL install directory" + +Normally, the Archipelago client should be able to find your OpenGOAL installation automatically. + +If it cannot, you may have to tell it yourself. Follow these instructions. + +- Run the OpenGOAL Launcher (if you had it open before, close it and reopen it). +- Click the Jak and Daxter logo on the left sidebar. +- Click `Features` in the bottom right corner, then click `Mods`, then under `Installed Mods`, click `ArchipelaGOAL`. +- Click `Advanced` in the bottom right corner, then click `Open Game Data Folder`. You should see a new File Explorer open to that directory. +- In the File Explorer, go to the parent directory called `archipelagoal`, and you should see the `gk.exe` and `goalc.exe` executables. Copy this path. +- Run the Archipelago Launcher, then click on `Open host.yaml`. You should see a new text editor open that file. +- Search for `jakanddaxter_options`, and you will need to make 2 changes here. +- First, find the `root_directory` entry. Paste the path you noted earlier (the one containing gk.exe and goalc.exe) inside the double quotes. +- **MAKE SURE YOU CHANGE ALL BACKSLASHES `\ ` TO FORWARD SLASHES `/`.** + +```yaml + root_directory: "%programfiles%/OpenGOAL-Launcher/features/jak1/mods/JakMods/archipelagoal" +``` + +- Second, find the `root_directory` entry. Change this to `false`. You do not need to use double quotes. + +```yaml + auto_detect_root_directory: true +``` + +- Save the file and close it. + +### The Game Fails To Load The Title Screen + +You may start the game via the Text Client, but it never loads in the title screen. Check the Compiler window: you may see red and yellow errors like this. + +``` +-- Compilation Error! -- +``` + +If this happens, follow these instructions. If you are using a PAL version of the game, you should skip these instructions and follow the `Special PAL Instructions` above. + +- Run the OpenGOAL Launcher (if you had it open before, close it and reopen it). +- Click the Jak and Daxter logo on the left sidebar, then click `Advanced`, then click `Open Game Data Folder`. Copy the `iso_data` folder from this directory. +- Back in the OpenGOAL Launcher, click the Jak and Daxter logo on the left sidebar. +- Click `Features` in the bottom right corner, then click `Mods`, then under `Installed Mods`, click `ArchipelaGOAL`. +- In the bottom right corner, click `Advanced`, then click `Open Game Data Folder`. +- Paste the `iso_data` folder you copied earlier. +- Back in the OpenGOAL Launcher, click the Jak and Daxter logo on the left sidebar. +- Click `Features` in the bottom right corner, then click `Mods`, then under `Installed Mods`, click `ArchipelaGOAL`. +- In the bottom right corner, click `Advanced`, then click `Compile`. + +### The Text Client Says "Error reading game memory!" or "Error sending data to compiler" + +If at any point the text client says this, you will need to restart the **all** of these applications. + +- Close all open windows: the client, the compiler, and the game. +- Run the OpenGOAL Launcher, then click `Features`, then click `Mods`, then click `ArchipelaGOAL`. +- Click `Advanced`, then click `Play in Debug Mode`. +- Click `Advanced`, then click `Open REPL`. +- Then close and reopen the Jak and Daxter Client from the Archipelago Launcher. +- Once these are done, you can enter `/repl status` and `/memr status` in the text client to verify. + +### The Client Cannot Open A REPL Connection + +If the client cannot open a REPL connection to the game, you may need to check the following steps: + +- Ensure you are not hosting anything on ports `8181` and `8112`. Those are for the REPL (goalc) and the game (gk) respectively. +- Ensure that Windows Defender and Windows Firewall are not blocking those programs from hosting or listening on those ports. +- You can use Windows Resource Monitor to verify those ports are open when the programs are running. +- Ensure that you only opened those ports for your local network, not the wider internet. + +## Known Issues + +- The game needs to boot in debug mode in order to allow the compiler to connect to it. **Clicking "Play" on the mod page in the OpenGOAL Launcher will not work.** +- The Compiler console window is orphaned once you close the game - you will have to kill it manually when you stop playing. +- The console windows cannot be run as background processes due to how the REPL works, so the best we can do is minimize them. +- Orbsanity checks may show up out of order in the text client. +- Large item releases may take up to several minutes for the game to process them all. Item Messages will usually take longer to appear than Items themselves. +- In Lost Precursor City, if you die in the Color Platforms room, the game may crash after you respawn. The cause is unknown. +- Darkness Trap may cause some visual glitches on certain levels. This is temporary, and terrain and object collision are unaffected. diff --git a/worlds/jakanddaxter/game_id.py b/worlds/jakanddaxter/game_id.py new file mode 100644 index 000000000000..d596a6cc824a --- /dev/null +++ b/worlds/jakanddaxter/game_id.py @@ -0,0 +1,8 @@ +# All Jak And Daxter Archipelago IDs must be offset by this number. +jak1_id = 741000000 + +# This is maximum ID we will allow. +jak1_max = jak1_id + 999999 + +# The name of the game. +jak1_name = "Jak and Daxter: The Precursor Legacy" diff --git a/worlds/jakanddaxter/icons/precursor_orb.ico b/worlds/jakanddaxter/icons/precursor_orb.ico new file mode 100644 index 0000000000000000000000000000000000000000..f0cd1a0eec251f861be3798a5c5059f236c4e786 GIT binary patch literal 6142 zcmcJT2Ut{B7RR3zr43~m`Ybp|9jr!GrJ#P)Fi9l;m$4d?(dy*?m6cU!?dIS zG8sdECCp7cIVuHZiwj@wmazzk06vEI^@CmD?b|gH4hQd{p4WGbX=Um-Yb4;cT z&2w+?oL>-&*(8xT|Fgi@21s>_A<@i7h-w~!m9r6~n1R69DF}#efPZ8i{AA5=UWG9I3P`le5TaR1Y_CJCT8QAdKM~t( zVw(Z~=*jSld$HXLecx=LpyTqSjfjl@05a|L5K1cH9b5t@XU)!pgzU~w-1t`}Dl1=Z=i;5UIWBbzq7ya| z*Cs?IZ2m=}?VI_r$oLP5_XA=jM$@`xKHW;*#+>c~<*yu1N9Apo;9=1A+zn;g zZm2W%L7%k;UJ>KLbWQ~0))T?%S7CJQ=Xp8q=)|qO4x8=$7erdu!Y`%)OnVDLHFL?| zUWRY@1hVHyc#DUjQ&;`jDN`17Yy+XqAun&`c*e~RrlS#oaWi1(eHi9GjXVqEWTBS0 zTxq_80iNMwV5E6v+8)x~F4F5qysabSHzGFi12FAOa3|Y^>zDFp)h}`qe57NEZ8%(f za^US9mD?sn8-oI&xry;e0mtA${%X%ZL;k&#=U@cM;ODq`_arb33pQg1*q#TW$@rA? zyC3RwvTyQ7q_5S)rGu+@D59*Z5Tu+(zBZN4K^=U^o<5Rt2)t}N+CXSEl#-Gi$#l?w zagL`wRfw{`jfBE;@KumKI9+i(zX&ms&g9AO!Ipc1*mlBAQVsXeT4LJ+RoXUshL-eh zMoc{U8@q&$A^y>1&xi@|m5zpsSH@47nME$GKw1olM6o5Js2X(kFGhszO;`tl_(v6ik;-Jsm1#{oeVd?uByuxe1bTYv$q>^;@4#kiKWKTK=G4<%^ z-G}Drz2pgrEihVjJw&N<9hEl_U+^X3i<_YBe;nHU6EGDWB`(re7uuV%A1CC0oq`9$ zHmC{K!V|<434eJV?0MviUDDthG6IIo?d11*{+(o&m2^Jepx8SX!HQ|IHbp#!q^!WzZ5lvt#FG4xw4B|>o@ocJs<51@w1>5fk zw2s3tI6i~ES0f*Lx!l#9uU3;Smq4PP1F3pCgaMA-tw34~cm!ph?kpYxCZGsRAW1O! zlbHO2lMoUK_qmvujzc&0I+T^?p(s7~UpDf8RsJ!kbB;jM`wM8Z4nsw8O`iHOpRXb) z_w%)gZaF+dM$&n-!NZf?(gLGZS89B5zrLgqiUIqeDBh3Qk^_(rIS5s0BlMM@!#wf` z^h5tjHWb5Ja~Aq>9NPt+jkC3?_!LwFNN0IRq3Qc2#gNaTp_r@ewwuodk+zMbvvmkJ zu0Ti6Tm;8XgpXh1>Q*2v2Eq*E)+SVa4Ndt4sD@vJYV;)-YOW%o_8X*5yovPs@6c=N zJ*12|LTtfE7)LRp?iQ`N4&&%6FjQWGvGf8=gPUL;c$W7wbHAg!JvAAhK-Fyr`PvqE zOJAgVayF#wTsn{187(kcbvtyGH`r^wfwGLwTLt+~)mN~NyNcAhZ_snnw{SFkhu*K; zM$U}Cq5IflJe#+58l1KDaG|*28ut?1Mim4C?WP@6Pv>0%9mN;~!M|fQ+M_zEEMp=6&?1 zHgDz+=sw{r#gXlh@j1EMlFK$f-+vLuQP@vA95tfE?%YHxNS0+n;f zjw=yvSPmiOaH@AyEihVjDL?wi`mFmmTYVL}nk&$je*wpoyU3Yx2Su;mN7-u+kT>x> zhA;XV#dCf{F0p0Leh541Q&D~bx=~kPp))KaE?vPFd=9hapN5#~Fr%Xpy3Bouv{8La zcZ6`mGOAw(eLrs8v}daMLldVRG{0~Yw%QvA>9G=t75gxF?gNy~{X51l1BzcF`#B|` zV*U^4*Kmbw83tJ&s{8YIL0@$h?BK)vxsYd3+@*XGne;xo291U_`*RvMQ{BeJ{nx?O zcS8RjYg#Gii35@&6)A$7#b_>sh7VEq}gZSiIdTl|o6 zUM~7ne~Ow#_h~<8BxWzdw08kx-dYsS`T>r~cac51 z{}v26Z=-^2m_79_GAVYnj~EWm_<3}GZ$LMU{LiHa!jqRHGIc%l6u;P>hsfs-B0xF4 zImY{E-Qn*MPbF!+z&9*oW}k+OFb&#@+*ht+(5$;CnsOD@OCO<>&Sn1ed+7D@Ef^^$ znMhB%nrl#1T!6NW;(zWZQ1scupGQMq%9UA-6ffSV`#>EO_O~Duv6ZcNe6|s~*E+}a ze66W)!6OvRegH?^1#};E2$>X53n^ygQfy79SZkYb9cs!83W~#Vlq)qu&cZbG0`vop zk-jMJP+U-U+fH}8gD}zkN#LKqH!W>I`)8wQdzFVr1S{{o~B*8Y6EKV@}iMY(O%;YTU;clg|7I-$ z7Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!T39Da!_}?@`hGZe!*aVl$gJ2+pXqYN! z_2`#ug*7b$$EsVfX48(?L10T3@Qdb)^vFdikPJ-o0oy*hbI#!T(+c3Ks6cyL2g2bf zqLCOP1do^ou?QEp8jT({OBx1df8vG9#VD{cANXU4kp}0Z)ZLrx=VYOIb&>IkmM5zQX z;F5i3rxONl*ZpvouH?Y6Wpy#QdFp~a@vnGb&GJ0$roU}^5Z+el;!|t-(`w--?L8i=MHg%f<9$%!2b?UvMJ+&O_pAGq^HQKc zbA?vf@A>21)6A(Rz!ySIMIDZvsX{0e!RR4*m{2&H#|hlt44>D{g!QtFdRT#2k-~h9 zBrgmwC#OKCGvUZrm8h(@L$5VpXm%C`4;%=s!GH>v4~yRT@Zdn;aw@@+(6^jd5;HFE z+kC@itESE>M7X8_T4OR&hmSqHD7=&Y`b$H<3CsDlnQy?cF&prPtbOqzl(&#EEQmnl<`9+us*5jX$uK9rQ4!uE~;h9iX8Yi`H=_dbv7XI+Y$@7sitc{X}x z1pF>1GSaMQarsgB`~j?+I|lu&R_r-aj^Yz`d{y6!W_ugP=I6re^bSvEbe>XM=n2-MYL=Lb)tI^QV$Qld@x*gmU`?^X?+;+fiYrwh?>dcgTIJO`4?+wr z@q)$Dk71=nWm7AL@Y?n7?8n5R`N-hA`G#x-CV}*+09obF-@1FA5p^}_bdpEb*W;cS z-a+iGckn>TX)K(3IcP@AUvnEaOdEw6Prrtg2`jMnj@w{hLh6|VEHmm^mlO=;+jKa} zed%Y9&KQZiu3rQlo7~n9_JPeB6>UC{5Q1d_@9aN>^$VsL9mK$&2_>NdWR((LtL9E0 zOMcVF#Ein-+Jb{SH?V1uD^POh%>bHM+)Gd3SFgW-b)yGJ!eiUpd!Wh8fIgXCXmcq* zMTNrvw~Jw?iUJl~I);6~hZnZ*f-4X~T8b6FzIh?mFPa9@3jF<08D@AMM@az z2^FBd=RP=XKn`3Tj8U(uEIuC}*V2qP-rSDYmR-iAZbYn;&CEqRojHXi^QS@@>>aC? z(|sP;{_{=jJ@_Tok~Dc4?~axh+`YH}WxS@bshQO&hU3j)%q|*_29m(pf7yc+gBH&( zpQi?hpr;E&5HnPOpM^Pp(-2%P++3_reNB3zv= z6b%`O_x2sd%<&_!vLFvtb#-X7w`1X`TxBq0vKf0D+uc-RS2whOlD-<*+1M+0jHo|F z$`B5dvsf6@W*FE}%@!LK)Uj^M?Q|k7sny0<_jT+AT?leT!_3rJfDJ967-+y3W@C#o zH%u@aEd=jTRKlP)@mX3p-CYQT!ibVog~Abd0zq{8gV0!0aqI3wWK|fcP<=~!Rlo`i z8gD>-$&0H|aqM$m6@@;@Oa+p;O=jYmpw%a-K}AFQNwQ4(ENnCavndHl8SLG9QH%-9 z2BpeSkUo{UfZGT&HmtTh#7hKtfDO<`&^``9Vlao(g?2Vat=WPHb{zn_#h^w;UL4^! zlE?$go?9?{$DJf(we?kqGO~39Y%rP`N+fQ2E{2reki^`GQ3(z!WTZBm6}sG9Xs-Kh z_hT+j-neoa{4~J!V`V65_gzB@wX^%w*OEwqhd*3B>+wsoO|Z9-kuW^8dW}*-&k)dx z5;|I+Wl=--Yqc77S{rmZdC*+{Bz~OBI{)%RfP={`SskMFIn1biu{xIwH?j?JE7lLN z-1_MWv3?*JMgy(CX~#a?e8psZT3L&26)nGFVL8V#i4@pU{m6>jY!N5iUA#>jC16^b zK=nzYKsz$zQtj2<_`a4z3cMfOeE$y(K^OawUnQuH zPz$&+#LWS>#a#a{zgihQ#lA;p&b36X9GNy$Y4@j!$X%_mie%IlcGe<(hoy7wSr zV#}Nwf7>^b$OEThyEcwNV-0s1s5CSTyi_NP`*N2ohLjT0=oq_nV?!f6U0xm#OUH+K zaF~}665tX>vh4|@umUe(6Qv^YFp^u`tVC|+fnUC4un$C7!k_%)a2Yd7K9>EHbR#%N zPQ{*GGp791m$XtCF%3&3l`tChuvq)?#UZ{dh%ntR6-Y$*e~cEDhL>b8swMp2(cx4I zh(a=zrP|WfR|y$}Bypuly4)U?O{eMsI>x@8CDcP@{8ZA*XL@LajbD6K#vC|r1&;Zi zxc!pav!@6)2tyL5DOMp{Y6_ltZ4VaBE5z(c1+bG=G`6-OJtG6znd!XF$eb{uw4xE8 zl~zEH{BiM1(bQ~-z z$Hx_R&Tt&fiVCpl$X8!7tS83deIulcy^7PrvC-Nu1pSVS-;X*n$@pO@e$CP3Dq; zJ|!g;H+*y&_iTO_T^_IcmMFlbt?pPl6JxV8S(0`5p94qLJP@Mi7EK<5m6J!qO0POd zGYC}dagHSNK(&kU`_adT6$=;xeX?K_n^QGB?p9TYB^~*{d5N@yRfcOr;b1H+ z9EA=(Qz%IpL0foSjMU(8qWDZBPILbr&f@J|jRI7hevb4SLRR4DdxwwV9$HdDVaSF* z!QJ6NUaAexY~7(M>C1~ILMP;l-Bu_;M_VU8T{REocP+z5C10rLTz~l#INF`CT2k=9 zmhJLf6tMAK!tMIwHE8#dsgjOJ$oOe-@%EhTG)x~e3Jb^N;YUL<;bo<2?NT`)?cf~g zRRID#@p470%W5*<$hs9cw(3fRz3h!z12%uzAj}ZgOr3<5mNu5kIIDEC-D~OU42H(e zPY$Z*%pE%l4s!k&=iPGNBsn4MRk)MvJ3PL)N2o|{I@>tqedgH7nmUrh7+a423I)Z7dQ2bWI9qmN3A;0YMxl@{*rFMW6uL_9JLff_qb zIL;AzJ*rwAl84)PxK~Nk$izZMLaZ!byCSEhrb>;DdX~DZ0RwTkybAr3jj$OF>dUlz zQIi>z@xhUkU6zmKyr#bQhyrq4Vm;YxhABCj96!W@(5cF!pESZNT!{C`1g2*XaJaqj zF)xA|J>IKrX-v`Uht`JK`g@UtGclV;gsuylysj%}j2;Fj+q;1AcsW)e5~lZ;rIOFqB!D5bW% zLKG3@j0x!Y%`)VO2$56&cw9c0@aNYG2zVJ%f?NRtj4KdR9*8e0K?VGB zo=QbY1ou`qg-kl#6f94?hi@mC`}(*G z+Fn~T?TSk;VYy^-G87cRo{-^nqEHWL;q_7m6)>I<@I6+SaFH=tlDFrWgpI~%!of<; z6u`zh;L-To`iQmz9>!TsXNSzN}3%$(w4QH0k_28bbfNd3W%^e6);L) zns36K8)sgM{_F?x_1e$rN|jNDmGTNf%I7W_)MacG@KI6;SsM0>c6Ro|RZXx1#a5l} zXVsBNuY|2H`Ii*v5jMM}Y<3TkoK0OYE+2!_(_kSmp%3xy9abJtpGgEb%Wo%nPi>n6 zrFQlM4(h2|?Gshe=s6#(&Q~r^5n&Z`4Giy)w)Tk?%!;e-wJ9A9Garchipelago communication. +scout_item_table = { + 95: "Scout Fly - Geyser Rock", + 75: "Scout Fly - Sandover Village", + 7: "Scout Fly - Forbidden Jungle", + 20: "Scout Fly - Sentinel Beach", + 28: "Scout Fly - Misty Island", + 68: "Scout Fly - Fire Canyon", + 76: "Scout Fly - Rock Village", + 57: "Scout Fly - Precursor Basin", + 49: "Scout Fly - Lost Precursor City", + 43: "Scout Fly - Boggy Swamp", + 88: "Scout Fly - Mountain Pass", + 77: "Scout Fly - Volcanic Crater", + 85: "Scout Fly - Spider Cave", + 65: "Scout Fly - Snowy Mountain", + 90: "Scout Fly - Lava Tube", + 91: "Scout Fly - Citadel", # Had to shorten, it was >32 characters. +} + +# Orbs are also generic and interchangeable. +# These items are only used by Orbsanity, and only one of these +# items will be used corresponding to the chosen bundle size. +orb_item_table = { + 1: "1 Precursor Orb", + 2: "2 Precursor Orbs", + 4: "4 Precursor Orbs", + 5: "5 Precursor Orbs", + 8: "8 Precursor Orbs", + 10: "10 Precursor Orbs", + 16: "16 Precursor Orbs", + 20: "20 Precursor Orbs", + 25: "25 Precursor Orbs", + 40: "40 Precursor Orbs", + 50: "50 Precursor Orbs", + 80: "80 Precursor Orbs", + 100: "100 Precursor Orbs", + 125: "125 Precursor Orbs", + 200: "200 Precursor Orbs", + 250: "250 Precursor Orbs", + 400: "400 Precursor Orbs", + 500: "500 Precursor Orbs", + 1000: "1000 Precursor Orbs", + 2000: "2000 Precursor Orbs", +} + +# These are special items representing unique unlocks in the world. Notice that their Item ID equals their +# respective Location ID. Like scout flies, this is necessary for game<->archipelago communication. +special_item_table = { + 5: "Fisherman's Boat", # Unlocks Misty Island + 4: "Jungle Elevator", # Unlocks the Forbidden Jungle Temple + 2: "Blue Eco Switch", # Unlocks Blue Eco Vents + 17: "Flut Flut", # Unlocks Flut Flut sections in Boggy Swamp and Snowy Mountain + 33: "Warrior's Pontoons", # Unlocks Boggy Swamp and everything post-Rock Village + 105: "Snowy Mountain Gondola", # Unlocks Snowy Mountain + 60: "Yellow Eco Switch", # Unlocks Yellow Eco Vents + 63: "Snowy Fort Gate", # Unlocks the Snowy Mountain Fort + 71: "Freed The Blue Sage", # 1 of 3 unlocks for the final staircase in Citadel + 72: "Freed The Red Sage", # 1 of 3 unlocks for the final staircase in Citadel + 73: "Freed The Yellow Sage", # 1 of 3 unlocks for the final staircase in Citadel + 70: "Freed The Green Sage", # Unlocks the final boss elevator in Citadel +} + +# These are the move items for move randomizer. Notice that their Item ID equals some of the Orb Cache Location ID's. +# This was 100% arbitrary. There's no reason to tie moves to orb caches except that I need a place to put them. ;_; +move_item_table = { + 10344: "Crouch", + 10369: "Crouch Jump", + 11072: "Crouch Uppercut", + 12634: "Roll", + 12635: "Roll Jump", + 10945: "Double Jump", + 14507: "Jump Dive", + 14838: "Jump Kick", + 23348: "Punch", + 23349: "Punch Uppercut", + 23350: "Kick", + # 24038: "Orb Cache at End of Blast Furnace", # Hold onto these ID's for future use. + # 24039: "Orb Cache at End of Launch Pad Room", + # 24040: "Orb Cache at Start of Launch Pad Room", +} + +# These are trap items. Their Item ID is to be subtracted from the base game ID. They do not have corresponding +# game locations because they are intended to replace other items that have been marked as filler. +trap_item_table = { + 1: "Trip Trap", + 2: "Slippery Trap", + 3: "Gravity Trap", + 4: "Camera Trap", + 5: "Darkness Trap", + 6: "Earthquake Trap", + 7: "Teleport Trap", + 8: "Despair Trap", + 9: "Pacifism Trap", + 10: "Ecoless Trap", + 11: "Health Trap", + 12: "Ledge Trap", + 13: "Zoomer Trap", + 14: "Mirror Trap", +} + +# All Items +# While we're here, do all the ID conversions needed. +item_table = { + **{cells.to_ap_id(k): name for k, name in cell_item_table.items()}, + **{scouts.to_ap_id(k): name for k, name in scout_item_table.items()}, + **{specials.to_ap_id(k): name for k, name in special_item_table.items()}, + **{caches.to_ap_id(k): name for k, name in move_item_table.items()}, + **{orbs.to_ap_id(k): name for k, name in orb_item_table.items()}, + **{jak1_max - k: name for k, name in trap_item_table.items()}, + jak1_max: "Green Eco Pill" # Filler item. +} diff --git a/worlds/jakanddaxter/levels.py b/worlds/jakanddaxter/levels.py new file mode 100644 index 000000000000..2deb2d20879d --- /dev/null +++ b/worlds/jakanddaxter/levels.py @@ -0,0 +1,76 @@ +# This contains the list of levels in Jak and Daxter. +# Not to be confused with Regions - there can be multiple Regions in every Level. +level_table = { + "Geyser Rock": { + "level_index": 0, + "orbs": 50 + }, + "Sandover Village": { + "level_index": 1, + "orbs": 50 + }, + "Sentinel Beach": { + "level_index": 2, + "orbs": 150 + }, + "Forbidden Jungle": { + "level_index": 3, + "orbs": 150 + }, + "Misty Island": { + "level_index": 4, + "orbs": 150 + }, + "Fire Canyon": { + "level_index": 5, + "orbs": 50 + }, + "Rock Village": { + "level_index": 6, + "orbs": 50 + }, + "Lost Precursor City": { + "level_index": 7, + "orbs": 200 + }, + "Boggy Swamp": { + "level_index": 8, + "orbs": 200 + }, + "Precursor Basin": { + "level_index": 9, + "orbs": 200 + }, + "Mountain Pass": { + "level_index": 10, + "orbs": 50 + }, + "Volcanic Crater": { + "level_index": 11, + "orbs": 50 + }, + "Snowy Mountain": { + "level_index": 12, + "orbs": 200 + }, + "Spider Cave": { + "level_index": 13, + "orbs": 200 + }, + "Lava Tube": { + "level_index": 14, + "orbs": 50 + }, + "Gol and Maia's Citadel": { + "level_index": 15, + "orbs": 200 + } +} + +level_table_with_global = { + **level_table, + "": { + "level_index": 16, # Global + "orbs": 2000 + } +} diff --git a/worlds/jakanddaxter/locations.py b/worlds/jakanddaxter/locations.py new file mode 100644 index 000000000000..901c9811db09 --- /dev/null +++ b/worlds/jakanddaxter/locations.py @@ -0,0 +1,66 @@ +from BaseClasses import Location +from .game_id import jak1_name +from .locs import (orb_locations as orbs, + cell_locations as cells, + scout_locations as scouts, + special_locations as specials, + orb_cache_locations as caches) + + +class JakAndDaxterLocation(Location): + game: str = jak1_name + + +# Different tables for location groups. +# Each Item ID == its corresponding Location ID. While we're here, do all the ID conversions needed. +cell_location_table = { + **{cells.to_ap_id(k): name for k, name in cells.loc7SF_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locGR_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locSV_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locFJ_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locSB_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locMI_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locFC_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locRV_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locPB_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locLPC_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locBS_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locMP_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locVC_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locSC_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locSM_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locLT_cellTable.items()}, + **{cells.to_ap_id(k): name for k, name in cells.locGMC_cellTable.items()}, +} + +scout_location_table = { + **{scouts.to_ap_id(k): name for k, name in scouts.locGR_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locSV_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locFJ_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locSB_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locMI_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locFC_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locRV_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locPB_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locLPC_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locBS_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locMP_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locVC_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locSC_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locSM_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locLT_scoutTable.items()}, + **{scouts.to_ap_id(k): name for k, name in scouts.locGMC_scoutTable.items()}, +} + +special_location_table = {specials.to_ap_id(k): name for k, name in specials.loc_specialTable.items()} +cache_location_table = {caches.to_ap_id(k): name for k, name in caches.loc_orbCacheTable.items()} +orb_location_table = {orbs.to_ap_id(k): name for k, name in orbs.loc_orbBundleTable.items()} + +# All Locations +location_table = { + **cell_location_table, + **scout_location_table, + **special_location_table, + **cache_location_table, + **orb_location_table +} diff --git a/worlds/jakanddaxter/locs/__init__.py b/worlds/jakanddaxter/locs/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/worlds/jakanddaxter/locs/cell_locations.py b/worlds/jakanddaxter/locs/cell_locations.py new file mode 100644 index 000000000000..62f63e07df78 --- /dev/null +++ b/worlds/jakanddaxter/locs/cell_locations.py @@ -0,0 +1,194 @@ +from ..game_id import jak1_id + +# Power Cells are given ID's between 0 and 116 by the game. + +# The game tracks all game-tasks as integers. +# 101 of these ID's correspond directly to power cells, but they are not +# necessarily ordered, nor are they the first 101 in the task list. +# The remaining ones are cutscenes and other events. + + +# These helper functions do all the math required to get information about each +# power cell and translate its ID between AP and OpenGOAL. +def to_ap_id(game_id: int) -> int: + if game_id >= jak1_id: + raise ValueError(f"Attempted to convert {game_id} to an AP ID, but it already is one.") + return jak1_id + game_id + + +def to_game_id(ap_id: int) -> int: + if ap_id < jak1_id: + raise ValueError(f"Attempted to convert {ap_id} to a Jak 1 ID, but it already is one.") + return ap_id - jak1_id + + +# The ID's you see below correspond directly to that cell's game-task ID. + +# The "Free 7 Scout Flies" Power Cells will be unlocked separately from their respective levels. +loc7SF_cellTable = { + 95: "GR: Free 7 Scout Flies", + 75: "SV: Free 7 Scout Flies", + 7: "FJ: Free 7 Scout Flies", + 20: "SB: Free 7 Scout Flies", + 28: "MI: Free 7 Scout Flies", + 68: "FC: Free 7 Scout Flies", + 76: "RV: Free 7 Scout Flies", + 57: "PB: Free 7 Scout Flies", + 49: "LPC: Free 7 Scout Flies", + 43: "BS: Free 7 Scout Flies", + 88: "MP: Free 7 Scout Flies", + 77: "VC: Free 7 Scout Flies", + 85: "SC: Free 7 Scout Flies", + 65: "SM: Free 7 Scout Flies", + 90: "LT: Free 7 Scout Flies", + 91: "GMC: Free 7 Scout Flies", +} + +# Geyser Rock +locGR_cellTable = { + 92: "GR: Find The Cell On The Path", + 93: "GR: Open The Precursor Door", + 94: "GR: Climb Up The Cliff", +} + +# Sandover Village +locSV_cellTable = { + 11: "SV: Bring 90 Orbs To The Mayor", + 12: "SV: Bring 90 Orbs to Your Uncle", + 10: "SV: Herd The Yakows Into The Pen", + 13: "SV: Bring 120 Orbs To The Oracle (1)", + 14: "SV: Bring 120 Orbs To The Oracle (2)", +} + +# Forbidden Jungle +locFJ_cellTable = { + 3: "FJ: Connect The Eco Beams", + 4: "FJ: Get To The Top Of The Temple", + 2: "FJ: Find The Blue Vent Switch", + 6: "FJ: Defeat The Dark Eco Plant", + 5: "FJ: Catch 200 Pounds Of Fish", + 8: "FJ: Follow The Canyon To The Sea", + 9: "FJ: Open The Locked Temple Door", +} + +# Sentinel Beach +locSB_cellTable = { + 15: "SB: Unblock The Eco Harvesters", + 17: "SB: Push The Flut Flut Egg Off The Cliff", + 16: "SB: Get The Power Cell From The Pelican", + 18: "SB: Chase The Seagulls", + 19: "SB: Launch Up To The Cannon Tower", + 21: "SB: Explore The Beach", + 22: "SB: Climb The Sentinel", +} + +# Misty Island +locMI_cellTable = { + 23: "MI: Catch The Sculptor's Muse", + 24: "MI: Climb The Lurker Ship", + 26: "MI: Stop The Cannon", + 25: "MI: Return To The Dark Eco Pool", + 27: "MI: Destroy the Balloon Lurkers", + 29: "MI: Use Zoomer To Reach Power Cell", + 30: "MI: Use Blue Eco To Reach Power Cell", +} + +# Fire Canyon +locFC_cellTable = { + 69: "FC: Reach The End Of Fire Canyon", +} + +# Rock Village +locRV_cellTable = { + 31: "RV: Bring 90 Orbs To The Gambler", + 32: "RV: Bring 90 Orbs To The Geologist", + 33: "RV: Bring 90 Orbs To The Warrior", + 34: "RV: Bring 120 Orbs To The Oracle (1)", + 35: "RV: Bring 120 Orbs To The Oracle (2)", +} + +# Precursor Basin +locPB_cellTable = { + 54: "PB: Herd The Moles Into Their Hole", + 53: "PB: Catch The Flying Lurkers", + 52: "PB: Beat Record Time On The Gorge", + 56: "PB: Get The Power Cell Over The Lake", + 55: "PB: Cure Dark Eco Infected Plants", + 58: "PB: Navigate The Purple Precursor Rings", + 59: "PB: Navigate The Blue Precursor Rings", +} + +# Lost Precursor City +locLPC_cellTable = { + 47: "LPC: Raise The Chamber", + 45: "LPC: Follow The Colored Pipes", + 46: "LPC: Reach The Bottom Of The City", + 48: "LPC: Quickly Cross The Dangerous Pool", + 44: "LPC: Match The Platform Colors", + 50: "LPC: Climb The Slide Tube", + 51: "LPC: Reach The Center Of The Complex", +} + +# Boggy Swamp +locBS_cellTable = { + 37: "BS: Ride The Flut Flut", + 36: "BS: Protect Farthy's Snacks", + 38: "BS: Defeat The Lurker Ambush", + 39: "BS: Break The Tethers To The Zeppelin (1)", + 40: "BS: Break The Tethers To The Zeppelin (2)", + 41: "BS: Break The Tethers To The Zeppelin (3)", + 42: "BS: Break The Tethers To The Zeppelin (4)", +} + +# Mountain Pass +locMP_cellTable = { + 86: "MP: Defeat Klaww", + 87: "MP: Reach The End Of The Mountain Pass", + 110: "MP: Find The Hidden Power Cell", +} + +# Volcanic Crater +locVC_cellTable = { + 96: "VC: Bring 90 Orbs To The Miners (1)", + 97: "VC: Bring 90 Orbs To The Miners (2)", + 98: "VC: Bring 90 Orbs To The Miners (3)", + 99: "VC: Bring 90 Orbs To The Miners (4)", + 100: "VC: Bring 120 Orbs To The Oracle (1)", + 101: "VC: Bring 120 Orbs To The Oracle (2)", + 74: "VC: Find The Hidden Power Cell", +} + +# Spider Cave +locSC_cellTable = { + 78: "SC: Use Your Goggles To Shoot The Gnawing Lurkers", + 79: "SC: Destroy The Dark Eco Crystals", + 80: "SC: Explore The Dark Cave", + 81: "SC: Climb The Giant Robot", + 82: "SC: Launch To The Poles", + 83: "SC: Navigate The Spider Tunnel", + 84: "SC: Climb the Precursor Platforms", +} + +# Snowy Mountain +locSM_cellTable = { + 60: "SM: Find The Yellow Vent Switch", + 61: "SM: Stop The 3 Lurker Glacier Troops", + 66: "SM: Deactivate The Precursor Blockers", + 67: "SM: Open The Frozen Crate", + 63: "SM: Open The Lurker Fort Gate", + 62: "SM: Get Through The Lurker Fort", + 64: "SM: Survive The Lurker Infested Cave", +} + +# Lava Tube +locLT_cellTable = { + 89: "LT: Cross The Lava Tube", +} + +# Gol and Maias Citadel +locGMC_cellTable = { + 71: "GMC: Free The Blue Sage", + 72: "GMC: Free The Red Sage", + 73: "GMC: Free The Yellow Sage", + 70: "GMC: Free The Green Sage", +} diff --git a/worlds/jakanddaxter/locs/orb_cache_locations.py b/worlds/jakanddaxter/locs/orb_cache_locations.py new file mode 100644 index 000000000000..b0ed6c1c979c --- /dev/null +++ b/worlds/jakanddaxter/locs/orb_cache_locations.py @@ -0,0 +1,52 @@ +from ..game_id import jak1_id + +# These are the locations of Orb Caches throughout the game, unlockable only with blue eco. +# They are not game collectables and thus don't have the same kinds of game ID's. They do, however, have actor ID's. +# There are a total of 14 in the game. + +# When these are opened, we can execute a hook in the mod that might be able to tell us which orb cache we opened, +# by ID, and that will allow us to map a Location object to it. We'll be using these for Move Randomizer, +# where each move is "mapped" to an Orb Cache being unlocked. Obviously, they will then be randomized, but with moves +# not being considered Items by the game, we need to conjure SOME kind of Location for them, and Orb Caches is the best +# we can do. + +# We can use 2^12 to offset these from special checks, just like we offset those from scout flies +# by 2^11. Special checks don't exceed an ID of (jak1_id + 2153). +orb_cache_offset = 4096 + + +# These helper functions do all the math required to get information about each +# special check and translate its ID between AP and OpenGOAL. Similar to Scout Flies, these large numbers are not +# necessary, and we can flatten out the range in which these numbers lie. +def to_ap_id(game_id: int) -> int: + if game_id >= jak1_id: + raise ValueError(f"Attempted to convert {game_id} to an AP ID, but it already is one.") + uncompressed_id = jak1_id + orb_cache_offset + game_id # Add the offsets and the orb cache Actor ID. + return uncompressed_id - 10344 # Subtract the smallest Actor ID. + + +def to_game_id(ap_id: int) -> int: + if ap_id < jak1_id: + raise ValueError(f"Attempted to convert {ap_id} to a Jak 1 ID, but it already is one.") + uncompressed_id = ap_id + 10344 # Reverse process, add back the smallest Actor ID. + return uncompressed_id - jak1_id - orb_cache_offset # Subtract the offsets. + + +# The ID's you see below correlate to the Actor ID of each Orb Cache. + +loc_orbCacheTable = { + 10344: "Orb Cache in Sandover Village", + 10369: "Orb Cache in Forbidden Jungle", + 11072: "Orb Cache on Misty Island", + 12634: "Orb Cache near Flut Flut Egg", + 12635: "Orb Cache near Pelican's Nest", + 10945: "Orb Cache in Rock Village", + 14507: "Orb Cache in First Sunken Chamber", + 14838: "Orb Cache in Second Sunken Chamber", + 23348: "Orb Cache in Snowy Fort (1)", + 23349: "Orb Cache in Snowy Fort (2)", + 23350: "Orb Cache in Snowy Fort (3)", + 24038: "Orb Cache at End of Blast Furnace", + 24039: "Orb Cache at End of Launch Pad Room", + 24040: "Orb Cache at Start of Launch Pad Room", +} diff --git a/worlds/jakanddaxter/locs/orb_locations.py b/worlds/jakanddaxter/locs/orb_locations.py new file mode 100644 index 000000000000..2b69465a98fa --- /dev/null +++ b/worlds/jakanddaxter/locs/orb_locations.py @@ -0,0 +1,123 @@ +from ..game_id import jak1_id +from ..levels import level_table_with_global + +# Precursor Orbs are not necessarily given ID's by the game. + +# Of the 2000 orbs (or "money") you can pick up, only 1233 are standalone ones you find in the overworld. +# We can identify them by Actor ID's, which run from 549 to 24433. Other actors reside in this range, +# so like Power Cells these are not ordered, nor contiguous, nor exclusively orbs. + +# In fact, other ID's in this range belong to actors that spawn orbs when they are activated or when they die, +# like steel crates, orb caches, Spider Cave gnawers, or jumping on the Plant Boss's head. These orbs that spawn +# from parent actors DON'T have an Actor ID themselves - the parent object keeps track of how many of its orbs +# have been picked up. + +# In order to deal with this mess, we're creating 2 extra functions that will create and identify Orb Locations for us. +# These will be compatible with both Global Orbsanity and Per-Level Orbsanity, allowing us to create any +# number of Locations depending on the bundle size chosen, while also guaranteeing that each has a unique address. + +# We can use 2^15 to offset them from Orb Caches, because Orb Cache ID's max out at (jak1_id + 17792). +orb_offset = 32768 + + +# These helper functions do all the math required to get information about each +# precursor orb and translate its ID between AP and OpenGOAL. +def to_ap_id(game_id: int) -> int: + if game_id >= jak1_id: + raise ValueError(f"Attempted to convert {game_id} to an AP ID, but it already is one.") + return jak1_id + orb_offset + game_id # Add the offsets and the orb Actor ID. + + +def to_game_id(ap_id: int) -> int: + if ap_id < jak1_id: + raise ValueError(f"Attempted to convert {ap_id} to a Jak 1 ID, but it already is one.") + return ap_id - jak1_id - orb_offset # Reverse process, subtract the offsets. + + +# Use this when the Memory Reader learns that you checked a specific bundle. +# Offset each level by 200 orbs (max number in any level), {200, 400, ...} +# then divide orb count by bundle size, {201, 202, ...} +# then subtract 1. {200, 201, ...} +def find_address(level_index: int, orb_count: int, bundle_size: int) -> int: + result = (level_index * 200) + (orb_count // bundle_size) - 1 + return result + + +# Use this when assigning addresses during region generation. +def create_address(level_index: int, bundle_index: int) -> int: + result = (level_index * 200) + bundle_index + return result + + +# What follows is our methods of generating all the name/ID pairs for location_name_to_id. +# Remember that not every bundle will be used in the actual seed, we just need a static map of strings to ints. +locGR_orbBundleTable = {create_address(level_table_with_global["Geyser Rock"]["level_index"], index): + f"Geyser Rock Orb Bundle {index + 1}" + for index in range(level_table_with_global["Geyser Rock"]["orbs"])} +locSV_orbBundleTable = {create_address(level_table_with_global["Sandover Village"]["level_index"], index): + f"Sandover Village Orb Bundle {index + 1}" + for index in range(level_table_with_global["Sandover Village"]["orbs"])} +locFJ_orbBundleTable = {create_address(level_table_with_global["Forbidden Jungle"]["level_index"], index): + f"Forbidden Jungle Orb Bundle {index + 1}" + for index in range(level_table_with_global["Forbidden Jungle"]["orbs"])} +locSB_orbBundleTable = {create_address(level_table_with_global["Sentinel Beach"]["level_index"], index): + f"Sentinel Beach Orb Bundle {index + 1}" + for index in range(level_table_with_global["Sentinel Beach"]["orbs"])} +locMI_orbBundleTable = {create_address(level_table_with_global["Misty Island"]["level_index"], index): + f"Misty Island Orb Bundle {index + 1}" + for index in range(level_table_with_global["Misty Island"]["orbs"])} +locFC_orbBundleTable = {create_address(level_table_with_global["Fire Canyon"]["level_index"], index): + f"Fire Canyon Orb Bundle {index + 1}" + for index in range(level_table_with_global["Fire Canyon"]["orbs"])} +locRV_orbBundleTable = {create_address(level_table_with_global["Rock Village"]["level_index"], index): + f"Rock Village Orb Bundle {index + 1}" + for index in range(level_table_with_global["Rock Village"]["orbs"])} +locLPC_orbBundleTable = {create_address(level_table_with_global["Lost Precursor City"]["level_index"], index): + f"Lost Precursor City Orb Bundle {index + 1}" + for index in range(level_table_with_global["Lost Precursor City"]["orbs"])} +locBS_orbBundleTable = {create_address(level_table_with_global["Boggy Swamp"]["level_index"], index): + f"Boggy Swamp Orb Bundle {index + 1}" + for index in range(level_table_with_global["Boggy Swamp"]["orbs"])} +locPB_orbBundleTable = {create_address(level_table_with_global["Precursor Basin"]["level_index"], index): + f"Precursor Basin Orb Bundle {index + 1}" + for index in range(level_table_with_global["Precursor Basin"]["orbs"])} +locMP_orbBundleTable = {create_address(level_table_with_global["Mountain Pass"]["level_index"], index): + f"Mountain Pass Orb Bundle {index + 1}" + for index in range(level_table_with_global["Mountain Pass"]["orbs"])} +locVC_orbBundleTable = {create_address(level_table_with_global["Volcanic Crater"]["level_index"], index): + f"Volcanic Crater Orb Bundle {index + 1}" + for index in range(level_table_with_global["Volcanic Crater"]["orbs"])} +locSM_orbBundleTable = {create_address(level_table_with_global["Snowy Mountain"]["level_index"], index): + f"Snowy Mountain Orb Bundle {index + 1}" + for index in range(level_table_with_global["Snowy Mountain"]["orbs"])} +locSC_orbBundleTable = {create_address(level_table_with_global["Spider Cave"]["level_index"], index): + f"Spider Cave Orb Bundle {index + 1}" + for index in range(level_table_with_global["Spider Cave"]["orbs"])} +locLT_orbBundleTable = {create_address(level_table_with_global["Lava Tube"]["level_index"], index): + f"Lava Tube Orb Bundle {index + 1}" + for index in range(level_table_with_global["Lava Tube"]["orbs"])} +locGMC_orbBundleTable = {create_address(level_table_with_global["Gol and Maia's Citadel"]["level_index"], index): + f"Gol and Maia's Citadel Orb Bundle {index + 1}" + for index in range(level_table_with_global["Gol and Maia's Citadel"]["orbs"])} +locGlobal_orbBundleTable = {create_address(level_table_with_global[""]["level_index"], index): + f"Orb Bundle {index + 1}" + for index in range(level_table_with_global[""]["orbs"])} +loc_orbBundleTable = { + **locGR_orbBundleTable, + **locSV_orbBundleTable, + **locSB_orbBundleTable, + **locFJ_orbBundleTable, + **locMI_orbBundleTable, + **locFC_orbBundleTable, + **locRV_orbBundleTable, + **locLPC_orbBundleTable, + **locBS_orbBundleTable, + **locPB_orbBundleTable, + **locMP_orbBundleTable, + **locVC_orbBundleTable, + **locSM_orbBundleTable, + **locSC_orbBundleTable, + **locLT_orbBundleTable, + **locGMC_orbBundleTable, + **locGlobal_orbBundleTable +} diff --git a/worlds/jakanddaxter/locs/scout_locations.py b/worlds/jakanddaxter/locs/scout_locations.py new file mode 100644 index 000000000000..892bb973e054 --- /dev/null +++ b/worlds/jakanddaxter/locs/scout_locations.py @@ -0,0 +1,230 @@ +from ..game_id import jak1_id + +# Scout Flies are given ID's between 0 and 393311 by the game, explanation below. + +# Each fly (or "buzzer") is given a unique 32-bit number broken into two 16-bit numbers. +# The lower 16 bits are the game-task ID of the power cell the fly corresponds to. +# The higher 16 bits are the index of the fly itself, from 000 (0) to 110 (6). + +# Ex: The final scout fly on Geyser Rock +# 0000000000000110 0000000001011111 +# ( Index: 6 ) ( Cell: 95 ) + +# Because flies are indexed from 0, each 0th fly's full ID == the power cell's ID. +# So we need to offset all of their ID's in order for Archipelago to separate them +# from their power cells. We can use 1024 (2^10) for this purpose, because scout flies +# only ever need 10 bits to identify themselves (3 for the index, 7 for the cell ID). + +# We're also going to compress the ID by bit-shifting the fly index down to lower bits, +# keeping the scout fly ID range to a smaller set of numbers (1000 -> 2000, instead of 1 -> 400000). +fly_offset = 1024 + + +# These helper functions do all the math required to get information about each +# scout fly and translate its ID between AP and OpenGOAL. +def to_ap_id(game_id: int) -> int: + if game_id >= jak1_id: + raise ValueError(f"Attempted to convert {game_id} to an AP ID, but it already is one.") + cell_id = get_cell_id(game_id) # Get the power cell ID from the lowest 7 bits. + buzzer_index = (game_id - cell_id) >> 9 # Get the index, bit shift it down 9 places. + compressed_id = fly_offset + buzzer_index + cell_id # Add the offset, the bit-shifted index, and the cell ID. + return jak1_id + compressed_id # Last thing: add the game's ID. + + +def to_game_id(ap_id: int) -> int: + if ap_id < jak1_id: + raise ValueError(f"Attempted to convert {ap_id} to a Jak 1 ID, but it already is one.") + compressed_id = ap_id - jak1_id # Reverse process. First thing: subtract the game's ID. + cell_id = get_cell_id(compressed_id) # Get the power cell ID from the lowest 7 bits. + buzzer_index = compressed_id - fly_offset - cell_id # Get the bit-shifted index. + return (buzzer_index << 9) + cell_id # Return the index to its normal place, re-add the cell ID. + + +# Get the power cell ID from the lowest 7 bits. +# Make sure to use this function ONLY when the input argument does NOT include jak1_id, +# because that number may flip some of the bottom 7 bits, and that will throw off this bit mask. +def get_cell_id(buzzer_id: int) -> int: + if buzzer_id >= jak1_id: + raise ValueError(f"Attempted to bit mask {buzzer_id}, but it is polluted by the game's ID {jak1_id}.") + return buzzer_id & 0b1111111 + + +# The ID's you see below correspond directly to that fly's 32-bit ID in the game. +# I used the decompiled entity JSON's and Jak's X/Y coordinates in Debug Mode +# to determine which box ID is which location. + +# Geyser Rock +locGR_scoutTable = { + 95: "GR: Scout Fly On Ground, Front", + 327775: "GR: Scout Fly On Ground, Back", + 393311: "GR: Scout Fly On Left Ledge", + 65631: "GR: Scout Fly On Right Ledge", + 262239: "GR: Scout Fly On Middle Ledge, Left", + 131167: "GR: Scout Fly On Middle Ledge, Right", + 196703: "GR: Scout Fly On Top Ledge" +} + +# Sandover Village +locSV_scoutTable = { + 262219: "SV: Scout Fly In Fisherman's House", + 327755: "SV: Scout Fly In Mayor's House", + 131147: "SV: Scout Fly Under Bridge", + 65611: "SV: Scout Fly Behind Sculptor's House", + 75: "SV: Scout Fly Overlooking Farmer's House", + 393291: "SV: Scout Fly Near Oracle", + 196683: "SV: Scout Fly In Farmer's House" +} + +# Forbidden Jungle +locFJ_scoutTable = { + 393223: "FJ: Scout Fly At End Of Path", + 262151: "FJ: Scout Fly On Spiral Of Stumps", + 7: "FJ: Scout Fly Near Dark Eco Boxes", + 196615: "FJ: Scout Fly At End Of River", + 131079: "FJ: Scout Fly Behind Lurker Machine", + 327687: "FJ: Scout Fly Around Temple Spire", + 65543: "FJ: Scout Fly On Top Of Temple" +} + +# Sentinel Beach +locSB_scoutTable = { + 327700: "SB: Scout Fly At Entrance", + 20: "SB: Scout Fly Overlooking Locked Boxes", + 65556: "SB: Scout Fly On Path To Flut Flut", + 262164: "SB: Scout Fly Under Wood Pillars", + 196628: "SB: Scout Fly Overlooking Blue Eco Vent", + 131092: "SB: Scout Fly Overlooking Green Eco Vents", + 393236: "SB: Scout Fly On Sentinel" +} + +# Misty Island +locMI_scoutTable = { + 327708: "MI: Scout Fly Overlooking Entrance", + 65564: "MI: Scout Fly On Ledge Near Arena Entrance", + 262172: "MI: Scout Fly Near Arena Door", + 28: "MI: Scout Fly On Ledge Near Arena Exit", + 131100: "MI: Scout Fly On Ship", + 196636: "MI: Scout Fly On Barrel Ramps", + 393244: "MI: Scout Fly On Zoomer Ramps" +} + +# Fire Canyon +locFC_scoutTable = { + 393284: "FC: Scout Fly 1", + 68: "FC: Scout Fly 2", + 65604: "FC: Scout Fly 3", + 196676: "FC: Scout Fly 4", + 131140: "FC: Scout Fly 5", + 262212: "FC: Scout Fly 6", + 327748: "FC: Scout Fly 7" +} + +# Rock Village +locRV_scoutTable = { + 76: "RV: Scout Fly Behind Sage's Hut", + 131148: "RV: Scout Fly Near Waterfall", + 196684: "RV: Scout Fly Behind Geologist", + 262220: "RV: Scout Fly Behind Fiery Boulder", + 65612: "RV: Scout Fly On Dock", + 327756: "RV: Scout Fly At Pontoon Bridge", + 393292: "RV: Scout Fly At Boggy Swamp Entrance" +} + +# Precursor Basin +locPB_scoutTable = { + 196665: "PB: Scout Fly Overlooking Entrance", + 393273: "PB: Scout Fly Near Mole Hole", + 131129: "PB: Scout Fly At Purple Ring Start", + 65593: "PB: Scout Fly Near Dark Eco Plant, Above", + 57: "PB: Scout Fly At Blue Ring Start", + 262201: "PB: Scout Fly Before Big Jump", + 327737: "PB: Scout Fly Near Dark Eco Plant, Below" +} + +# Lost Precursor City +locLPC_scoutTable = { + 262193: "LPC: Scout Fly First Room", + 131121: "LPC: Scout Fly Before Second Room", + 393265: "LPC: Scout Fly Second Room, Near Orb Vent", + 196657: "LPC: Scout Fly Second Room, On Path To Cell", + 49: "LPC: Scout Fly Second Room, Green Pipe", # Sunken Pipe Game, special cases. See `got-buzzer?` + 65585: "LPC: Scout Fly Second Room, Blue Pipe", # Sunken Pipe Game, special cases. See `got-buzzer?` + 327729: "LPC: Scout Fly Across Steam Vents" +} + +# Boggy Swamp +locBS_scoutTable = { + 43: "BS: Scout Fly Near Entrance", + 393259: "BS: Scout Fly Over First Jump Pad", + 65579: "BS: Scout Fly Over Second Jump Pad", + 262187: "BS: Scout Fly Across Black Swamp", + 327723: "BS: Scout Fly Overlooking Flut Flut", + 131115: "BS: Scout Fly On Flut Flut Platforms", + 196651: "BS: Scout Fly In Field Of Boxes" +} + +# Mountain Pass +locMP_scoutTable = { + 88: "MP: Scout Fly 1", + 65624: "MP: Scout Fly 2", + 131160: "MP: Scout Fly 3", + 196696: "MP: Scout Fly 4", + 262232: "MP: Scout Fly 5", + 327768: "MP: Scout Fly 6", + 393304: "MP: Scout Fly 7" +} + +# Volcanic Crater +locVC_scoutTable = { + 262221: "VC: Scout Fly In Miner's Cave", + 393293: "VC: Scout Fly Near Oracle", + 196685: "VC: Scout Fly On Stone Platforms", + 131149: "VC: Scout Fly Near Lava Tube", + 77: "VC: Scout Fly At Minecart Junction", + 65613: "VC: Scout Fly Near Spider Cave", + 327757: "VC: Scout Fly Near Mountain Pass" +} + +# Spider Cave +locSC_scoutTable = { + 327765: "SC: Scout Fly Near Dark Cave Entrance", + 262229: "SC: Scout Fly In Dark Cave", + 393301: "SC: Scout Fly Main Cave, Overlooking Entrance", + 196693: "SC: Scout Fly Main Cave, Near Dark Crystal", + 131157: "SC: Scout Fly Main Cave, Near Robot Cave Entrance", + 85: "SC: Scout Fly Robot Cave, At Bottom Level", + 65621: "SC: Scout Fly Robot Cave, At Top Level", +} + +# Snowy Mountain +locSM_scoutTable = { + 65: "SM: Scout Fly Near Entrance", + 327745: "SM: Scout Fly Near Frozen Box", + 65601: "SM: Scout Fly Near Yellow Eco Switch", + 131137: "SM: Scout Fly On Cliff near Flut Flut", + 393281: "SM: Scout Fly Under Bridge To Fort", + 196673: "SM: Scout Fly On Top Of Fort Tower", + 262209: "SM: Scout Fly On Top Of Fort" +} + +# Lava Tube +locLT_scoutTable = { + 90: "LT: Scout Fly 1", + 65626: "LT: Scout Fly 2", + 327770: "LT: Scout Fly 3", + 262234: "LT: Scout Fly 4", + 131162: "LT: Scout Fly 5", + 196698: "LT: Scout Fly 6", + 393306: "LT: Scout Fly 7" +} + +# Gol and Maias Citadel +locGMC_scoutTable = { + 91: "GMC: Scout Fly At Entrance", + 65627: "GMC: Scout Fly Main Room, Left of Robot", + 196699: "GMC: Scout Fly Main Room, Right of Robot", + 262235: "GMC: Scout Fly Before Jumping Lurkers", + 393307: "GMC: Scout Fly At Blast Furnace", + 131163: "GMC: Scout Fly At Launch Pad Room", + 327771: "GMC: Scout Fly Top Of Rotating Tower" +} diff --git a/worlds/jakanddaxter/locs/special_locations.py b/worlds/jakanddaxter/locs/special_locations.py new file mode 100644 index 000000000000..95081eb2e3e9 --- /dev/null +++ b/worlds/jakanddaxter/locs/special_locations.py @@ -0,0 +1,51 @@ +from ..game_id import jak1_id + +# These are special checks that the game normally does not track. They are not game entities and thus +# don't have game ID's. + +# Normally, for example, completing the fishing minigame is what gives you access to the +# fisherman's boat to get to Misty Island. The game treats completion of the fishing minigame as well as the +# power cell you receive as one and the same. The fisherman only gives you one item, a power cell. + +# We're significantly altering the game logic here to decouple these concepts. First, completing the fishing minigame +# now counts as 2 Location checks. Second, the fisherman should give you a power cell (a generic item) as well as +# the "keys" to his boat (a special item). It is the "keys" that we are defining in this file, and the respective +# Item representing those keys will be defined in Items.py. These aren't real in the sense that +# they have a model and texture, they are just the logical representation of the boat unlock. + +# We can use 2^11 to offset these from scout flies, just like we offset scout flies from power cells +# by 2^10. Even with the high-16 reminder bits, scout flies don't exceed an ID of (jak1_id + 1887). +special_offset = 2048 + + +# These helper functions do all the math required to get information about each +# special check and translate its ID between AP and OpenGOAL. +def to_ap_id(game_id: int) -> int: + if game_id >= jak1_id: + raise ValueError(f"Attempted to convert {game_id} to an AP ID, but it already is one.") + return jak1_id + special_offset + game_id # Add the offsets and the orb Actor ID. + + +def to_game_id(ap_id: int) -> int: + if ap_id < jak1_id: + raise ValueError(f"Attempted to convert {ap_id} to a Jak 1 ID, but it already is one.") + return ap_id - jak1_id - special_offset # Reverse process, subtract the offsets. + + +# The ID's you see below correlate to each of their respective game-tasks, even though they are separate. +# This makes it easier for the new game logic to know what relates to what. I hope. God I hope. + +loc_specialTable = { + 5: "Fisherman's Boat", + 4: "Jungle Elevator", + 2: "Blue Eco Switch", + 17: "Flut Flut", + 33: "Warrior's Pontoons", + 105: "Snowy Mountain Gondola", + 60: "Yellow Eco Switch", + 63: "Snowy Fort Gate", + 71: "Freed The Blue Sage", + 72: "Freed The Red Sage", + 73: "Freed The Yellow Sage", + 70: "Freed The Green Sage", +} diff --git a/worlds/jakanddaxter/options.py b/worlds/jakanddaxter/options.py new file mode 100644 index 000000000000..bd007e264af8 --- /dev/null +++ b/worlds/jakanddaxter/options.py @@ -0,0 +1,262 @@ +from dataclasses import dataclass +from functools import cached_property +from Options import PerGameCommonOptions, StartInventoryPool, Toggle, Choice, Range, DefaultOnToggle, OptionCounter +from .items import trap_item_table + + +class StaticGetter: + def __init__(self, func): + self.fget = func + + def __get__(self, instance, owner): + return self.fget(owner) + + +@StaticGetter +def determine_range_end(cls) -> int: + from . import JakAndDaxterWorld + enforce_friendly_options = JakAndDaxterWorld.settings.enforce_friendly_options + return cls.friendly_maximum if enforce_friendly_options else cls.absolute_maximum + + +class EnableMoveRandomizer(Toggle): + """Include movement options as items in the randomizer. Until you find his other moves, Jak is limited to + running, swimming, single-jumping, and shooting yellow eco through his goggles. + + This adds 11 items to the pool.""" + display_name = "Enable Move Randomizer" + + +class EnableOrbsanity(Choice): + """Include bundles of Precursor Orbs as checks. Every time you collect the chosen number of orbs, you will trigger + another check. + + Per Level: bundles are for each level in the game. + Global: bundles carry over level to level. + + This adds a number of Items and Locations to the pool inversely proportional to the size of the bundle. + For example, if your bundle size is 20 orbs, you will add 100 items to the pool. If your bundle size is 250 orbs, + you will add 8 items to the pool.""" + display_name = "Enable Orbsanity" + option_off = 0 + option_per_level = 1 + option_global = 2 + default = 0 + + +class GlobalOrbsanityBundleSize(Choice): + """The orb bundle size for Global Orbsanity. This only applies if "Enable Orbsanity" is set to "Global." + There are 2000 orbs in the game, so your bundle size must be a factor of 2000. + + Multiplayer Minimum: 10 + Multiplayer Maximum: 200""" + display_name = "Global Orbsanity Bundle Size" + option_1_orb = 1 + option_2_orbs = 2 + option_4_orbs = 4 + option_5_orbs = 5 + option_8_orbs = 8 + option_10_orbs = 10 + option_16_orbs = 16 + option_20_orbs = 20 + option_25_orbs = 25 + option_40_orbs = 40 + option_50_orbs = 50 + option_80_orbs = 80 + option_100_orbs = 100 + option_125_orbs = 125 + option_200_orbs = 200 + option_250_orbs = 250 + option_400_orbs = 400 + option_500_orbs = 500 + option_1000_orbs = 1000 + option_2000_orbs = 2000 + friendly_minimum = 10 + friendly_maximum = 200 + default = 20 + + +class PerLevelOrbsanityBundleSize(Choice): + """The orb bundle size for Per Level Orbsanity. This only applies if "Enable Orbsanity" is set to "Per Level." + There are 50, 150, or 200 orbs per level, so your bundle size must be a factor of 50. + + Multiplayer Minimum: 10""" + display_name = "Per Level Orbsanity Bundle Size" + option_1_orb = 1 + option_2_orbs = 2 + option_5_orbs = 5 + option_10_orbs = 10 + option_25_orbs = 25 + option_50_orbs = 50 + friendly_minimum = 10 + default = 25 + + +class FireCanyonCellCount(Range): + """The number of power cells you need to cross Fire Canyon. This value is restricted to a safe maximum value to + ensure valid singleplayer games and non-disruptive multiplayer games, but the host can remove this restriction by + turning off enforce_friendly_options in host.yaml.""" + display_name = "Fire Canyon Cell Count" + friendly_maximum = 30 + absolute_maximum = 100 + range_start = 0 + range_end = determine_range_end + default = 20 + + +class MountainPassCellCount(Range): + """The number of power cells you need to reach Klaww and cross Mountain Pass. This value is restricted to a safe + maximum value to ensure valid singleplayer games and non-disruptive multiplayer games, but the host can + remove this restriction by turning off enforce_friendly_options in host.yaml.""" + display_name = "Mountain Pass Cell Count" + friendly_maximum = 60 + absolute_maximum = 100 + range_start = 0 + range_end = determine_range_end + default = 45 + + +class LavaTubeCellCount(Range): + """The number of power cells you need to cross Lava Tube. This value is restricted to a safe maximum value to + ensure valid singleplayer games and non-disruptive multiplayer games, but the host can remove this restriction by + turning off enforce_friendly_options in host.yaml.""" + display_name = "Lava Tube Cell Count" + friendly_maximum = 90 + absolute_maximum = 100 + range_start = 0 + range_end = determine_range_end + default = 72 + + +class EnableOrderedCellCounts(DefaultOnToggle): + """Reorder the Cell Count requirements for vehicle sections to be in ascending order. + + For example, if Fire Canyon Cell Count, Mountain Pass Cell Count, and Lava Tube Cell Count are 60, 30, and 40 + respectively, they will be reordered to 30, 40, and 60.""" + display_name = "Enable Ordered Cell Counts" + + +class RequirePunchForKlaww(DefaultOnToggle): + """Force the Punch move to come before Klaww. Disabling this setting may require Jak to fight Klaww + and Gol and Maia by shooting yellow eco through his goggles. This only applies if "Enable Move Randomizer" is ON.""" + display_name = "Require Punch For Klaww" + + +# 222 is the absolute maximum because there are 9 citizen trades and 2000 orbs to trade (2000/9 = 222). +class CitizenOrbTradeAmount(Range): + """The number of orbs you need to trade to citizens for a power cell (Mayor, Uncle, etc.). + + Along with Oracle Orb Trade Amount, this setting cannot exceed the total number of orbs in the game (2000). + The equation to determine the total number of trade orbs is (9 * Citizen Trades) + (6 * Oracle Trades). + + This value is restricted to a safe maximum value to ensure valid singleplayer games and non-disruptive + multiplayer games, but the host can remove this restriction by turning off enforce_friendly_options in host.yaml.""" + display_name = "Citizen Orb Trade Amount" + friendly_maximum = 120 + absolute_maximum = 222 + range_start = 0 + range_end = determine_range_end + default = 90 + + +# 333 is the absolute maximum because there are 6 oracle trades and 2000 orbs to trade (2000/6 = 333). +class OracleOrbTradeAmount(Range): + """The number of orbs you need to trade to the Oracles for a power cell. + + Along with Citizen Orb Trade Amount, this setting cannot exceed the total number of orbs in the game (2000). + The equation to determine the total number of trade orbs is (9 * Citizen Trades) + (6 * Oracle Trades). + + This value is restricted to a safe maximum value to ensure valid singleplayer games and non-disruptive + multiplayer games, but the host can remove this restriction by turning off enforce_friendly_options in host.yaml.""" + display_name = "Oracle Orb Trade Amount" + friendly_maximum = 150 + absolute_maximum = 333 + range_start = 0 + range_end = determine_range_end + default = 120 + + +class FillerPowerCellsReplacedWithTraps(Range): + """ + The number of filler power cells that will be replaced with traps. This does not affect the number of progression + power cells. + + If this value is greater than the number of filler power cells, then they will all be replaced with traps. + """ + display_name = "Filler Power Cells Replaced With Traps" + range_start = 0 + range_end = 100 + default = 0 + + +class FillerOrbBundlesReplacedWithTraps(Range): + """ + The number of filler orb bundles that will be replaced with traps. This does not affect the number of progression + orb bundles. This only applies if "Enable Orbsanity" is set to "Per Level" or "Global." + + If this value is greater than the number of filler orb bundles, then they will all be replaced with traps. + """ + display_name = "Filler Orb Bundles Replaced With Traps" + range_start = 0 + range_end = 2000 + default = 0 + + +class TrapEffectDuration(Range): + """ + The length of time, in seconds, that a trap effect lasts. + """ + display_name = "Trap Effect Duration" + range_start = 5 + range_end = 60 + default = 30 + + +class TrapWeights(OptionCounter): + """ + The list of traps and corresponding weights that will be randomly added to the item pool. A trap with weight 10 is + twice as likely to appear as a trap with weight 5. Set a weight to 0 to prevent that trap from appearing altogether. + If all weights are 0, no traps are created, overriding the values of "Filler * Replaced With Traps." + """ + display_name = "Trap Weights" + min = 0 + default = {trap: 1 for trap in trap_item_table.values()} + valid_keys = sorted({trap for trap in trap_item_table.values()}) + + @cached_property + def weights_pair(self) -> tuple[list[str], list[int]]: + return list(self.value.keys()), list(self.value.values()) + + +class CompletionCondition(Choice): + """Set the goal for completing the game.""" + display_name = "Completion Condition" + option_cross_fire_canyon = 69 + option_cross_mountain_pass = 87 + option_cross_lava_tube = 89 + option_defeat_dark_eco_plant = 6 + option_defeat_klaww = 86 + option_defeat_gol_and_maia = 112 + option_open_100_cell_door = 116 + default = 112 + + +@dataclass +class JakAndDaxterOptions(PerGameCommonOptions): + enable_move_randomizer: EnableMoveRandomizer + enable_orbsanity: EnableOrbsanity + global_orbsanity_bundle_size: GlobalOrbsanityBundleSize + level_orbsanity_bundle_size: PerLevelOrbsanityBundleSize + fire_canyon_cell_count: FireCanyonCellCount + mountain_pass_cell_count: MountainPassCellCount + lava_tube_cell_count: LavaTubeCellCount + enable_ordered_cell_counts: EnableOrderedCellCounts + require_punch_for_klaww: RequirePunchForKlaww + citizen_orb_trade_amount: CitizenOrbTradeAmount + oracle_orb_trade_amount: OracleOrbTradeAmount + filler_power_cells_replaced_with_traps: FillerPowerCellsReplacedWithTraps + filler_orb_bundles_replaced_with_traps: FillerOrbBundlesReplacedWithTraps + trap_effect_duration: TrapEffectDuration + trap_weights: TrapWeights + jak_completion_condition: CompletionCondition + start_inventory_from_pool: StartInventoryPool diff --git a/worlds/jakanddaxter/regions.py b/worlds/jakanddaxter/regions.py new file mode 100644 index 000000000000..8447f72e8ed0 --- /dev/null +++ b/worlds/jakanddaxter/regions.py @@ -0,0 +1,132 @@ +import typing +from Options import OptionError +from .items import item_table +from .options import EnableOrbsanity, CompletionCondition +from .rules import can_reach_orbs_global +from .locs import cell_locations as cells, scout_locations as scouts +from .regs import (geyser_rock_regions as geyser_rock, + sandover_village_regions as sandover_village, + forbidden_jungle_regions as forbidden_jungle, + sentinel_beach_regions as sentinel_beach, + misty_island_regions as misty_island, + fire_canyon_regions as fire_canyon, + rock_village_regions as rock_village, + precursor_basin_regions as precursor_basin, + lost_precursor_city_regions as lost_precursor_city, + boggy_swamp_regions as boggy_swamp, + mountain_pass_regions as mountain_pass, + volcanic_crater_regions as volcanic_crater, + spider_cave_regions as spider_cave, + snowy_mountain_regions as snowy_mountain, + lava_tube_regions as lava_tube, + gol_and_maias_citadel_regions as gol_and_maias_citadel) +from .regs.region_base import JakAndDaxterRegion + +if typing.TYPE_CHECKING: + from . import JakAndDaxterWorld + + +def create_regions(world: "JakAndDaxterWorld"): + multiworld = world.multiworld + options = world.options + player = world.player + + # Always start with Menu. + menu = JakAndDaxterRegion("Menu", player, multiworld) + multiworld.regions.append(menu) + + # Build the special "Free 7 Scout Flies" Region. This is a virtual region always accessible to Menu. + # The Locations within are automatically checked when you receive the 7th scout fly for the corresponding cell. + free7 = JakAndDaxterRegion("'Free 7 Scout Flies' Power Cells", player, multiworld) + free7.add_cell_locations(cells.loc7SF_cellTable.keys()) + for scout_fly_cell in free7.locations: + + # Translate from Cell AP ID to Scout AP ID using game ID as an intermediary. + scout_fly_id = scouts.to_ap_id(cells.to_game_id(typing.cast(int, scout_fly_cell.address))) + scout_fly_cell.access_rule = lambda state, flies=scout_fly_id: state.has(item_table[flies], player, 7) + multiworld.regions.append(free7) + menu.connect(free7) + + # If Global Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Menu. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_global: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld) + + bundle_count = 2000 // world.orb_bundle_size + for bundle_index in range(bundle_count): + + # Unlike Per-Level Orbsanity, Global Orbsanity Locations always have a level_index of 16. + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(16, + bundle_index, + access_rule=lambda state, orb_amount=amount: + can_reach_orbs_global(state, player, world, orb_amount)) + multiworld.regions.append(orbs) + menu.connect(orbs) + + # Build all regions. Include their intra-connecting Rules, their Locations, and their Location access rules. + gr = geyser_rock.build_regions("Geyser Rock", world) + sv = sandover_village.build_regions("Sandover Village", world) + fj, fjp = forbidden_jungle.build_regions("Forbidden Jungle", world) + sb = sentinel_beach.build_regions("Sentinel Beach", world) + mi = misty_island.build_regions("Misty Island", world) + fc = fire_canyon.build_regions("Fire Canyon", world) + rv, rvp, rvc = rock_village.build_regions("Rock Village", world) + pb = precursor_basin.build_regions("Precursor Basin", world) + lpc = lost_precursor_city.build_regions("Lost Precursor City", world) + bs = boggy_swamp.build_regions("Boggy Swamp", world) + mp, mpr = mountain_pass.build_regions("Mountain Pass", world) + vc = volcanic_crater.build_regions("Volcanic Crater", world) + sc = spider_cave.build_regions("Spider Cave", world) + sm = snowy_mountain.build_regions("Snowy Mountain", world) + lt = lava_tube.build_regions("Lava Tube", world) + gmc, fb, fd = gol_and_maias_citadel.build_regions("Gol and Maia's Citadel", world) + + # Configurable counts of cells for connector levels. + fc_count = options.fire_canyon_cell_count.value + mp_count = options.mountain_pass_cell_count.value + lt_count = options.lava_tube_cell_count.value + + # Define the interconnecting rules. + menu.connect(gr) + gr.connect(sv) # Geyser Rock modified to let you leave at any time. + sv.connect(fj) + sv.connect(sb) + sv.connect(mi, rule=lambda state: state.has("Fisherman's Boat", player)) + sv.connect(fc, rule=lambda state: state.has("Power Cell", player, fc_count)) # Normally 20. + fc.connect(rv) + rv.connect(pb) + rv.connect(lpc) + rvp.connect(bs) # rv->rvp/rvc connections defined internally by RockVillageRegions. + rvc.connect(mp, rule=lambda state: state.has("Power Cell", player, mp_count)) # Normally 45. + mpr.connect(vc) # mp->mpr connection defined internally by MountainPassRegions. + vc.connect(sc) + vc.connect(sm, rule=lambda state: state.has("Snowy Mountain Gondola", player)) + vc.connect(lt, rule=lambda state: state.has("Power Cell", player, lt_count)) # Normally 72. + lt.connect(gmc) # gmc->fb connection defined internally by GolAndMaiasCitadelRegions. + + # Set the completion condition. + if options.jak_completion_condition == CompletionCondition.option_cross_fire_canyon: + multiworld.completion_condition[player] = lambda state: state.can_reach(rv, "Region", player) + + elif options.jak_completion_condition == CompletionCondition.option_cross_mountain_pass: + multiworld.completion_condition[player] = lambda state: state.can_reach(vc, "Region", player) + + elif options.jak_completion_condition == CompletionCondition.option_cross_lava_tube: + multiworld.completion_condition[player] = lambda state: state.can_reach(gmc, "Region", player) + + elif options.jak_completion_condition == CompletionCondition.option_defeat_dark_eco_plant: + multiworld.completion_condition[player] = lambda state: state.can_reach(fjp, "Region", player) + + elif options.jak_completion_condition == CompletionCondition.option_defeat_klaww: + multiworld.completion_condition[player] = lambda state: state.can_reach(mp, "Region", player) + + elif options.jak_completion_condition == CompletionCondition.option_defeat_gol_and_maia: + multiworld.completion_condition[player] = lambda state: state.can_reach(fb, "Region", player) + + elif options.jak_completion_condition == CompletionCondition.option_open_100_cell_door: + multiworld.completion_condition[player] = lambda state: state.can_reach(fd, "Region", player) + + else: + raise OptionError(f"{world.player_name}: Unknown completion goal ID " + f"({options.jak_completion_condition.value}).") diff --git a/worlds/jakanddaxter/regs/__init__.py b/worlds/jakanddaxter/regs/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/worlds/jakanddaxter/regs/boggy_swamp_regions.py b/worlds/jakanddaxter/regs/boggy_swamp_regions.py new file mode 100644 index 000000000000..a548f2e41069 --- /dev/null +++ b/worlds/jakanddaxter/regs/boggy_swamp_regions.py @@ -0,0 +1,174 @@ +from BaseClasses import CollectionState +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_fight, can_reach_orbs_level + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + # This level is full of short-medium gaps that cannot be crossed by single jump alone. + # These helper functions list out the moves that can cross all these gaps (painting with a broad brush but...) + def can_jump_farther(state: CollectionState, p: int) -> bool: + return (state.has_any(("Double Jump", "Jump Kick"), p) + or state.has_all(("Punch", "Punch Uppercut"), p)) + + def can_jump_higher(state: CollectionState, p: int) -> bool: + return (state.has("Double Jump", p) + or state.has_all(("Crouch", "Crouch Jump"), p) + or state.has_all(("Crouch", "Crouch Uppercut"), p) + or state.has_all(("Punch", "Punch Uppercut"), p)) + + # Orb crates and fly box in this area can be gotten with yellow eco and goggles. + # Start with the first yellow eco cluster near first_bats and work your way backward toward the entrance. + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 23) + main_area.add_fly_locations([43]) + + # Includes 4 orbs collectable with the blue eco vent. + first_bats = JakAndDaxterRegion("First Bats Area", player, multiworld, level_name, 4) + + first_jump_pad = JakAndDaxterRegion("First Jump Pad", player, multiworld, level_name, 0) + first_jump_pad.add_fly_locations([393259]) + + # The tethers in this level are all out of order... a casual playthrough has the following order for the cell ID's: + # 42, 39, 40, 41. So that is the order we're calling "first, second, third, fourth". + + # First tether cell is collectable with yellow eco and goggles. + first_tether = JakAndDaxterRegion("First Tether", player, multiworld, level_name, 7) + first_tether.add_cell_locations([42]) + + # This rat colony has 3 orbs on top of it, requires special movement. + first_tether_rat_colony = JakAndDaxterRegion("First Tether Rat Colony", player, multiworld, level_name, 3) + + # If quick enough, combat not required. + second_jump_pad = JakAndDaxterRegion("Second Jump Pad", player, multiworld, level_name, 0) + second_jump_pad.add_fly_locations([65579]) + + first_pole_course = JakAndDaxterRegion("First Pole Course", player, multiworld, level_name, 28) + + # You can break this tether with a yellow eco vent and goggles, + # but you can't reach the platform unless you can jump high. + second_tether = JakAndDaxterRegion("Second Tether", player, multiworld, level_name, 0) + second_tether.add_cell_locations([39], access_rule=lambda state: can_jump_higher(state, player)) + + # Fly and orbs are collectable with nearby blue eco cluster. + second_bats = JakAndDaxterRegion("Second Bats Area", player, multiworld, level_name, 27) + second_bats.add_fly_locations([262187], access_rule=lambda state: can_jump_farther(state, player)) + + third_jump_pad = JakAndDaxterRegion("Third Jump Pad (Arena)", player, multiworld, level_name, 0) + third_jump_pad.add_cell_locations([38], access_rule=lambda state: can_fight(state, player)) + + # The platform for the third tether might look high, but you can get a boost from the yellow eco vent. + fourth_jump_pad = JakAndDaxterRegion("Fourth Jump Pad (Third Tether)", player, multiworld, level_name, 9) + fourth_jump_pad.add_cell_locations([40]) + + # Orbs collectable here with yellow eco and goggles. + flut_flut_pad = JakAndDaxterRegion("Flut Flut Pad", player, multiworld, level_name, 36) + + flut_flut_course = JakAndDaxterRegion("Flut Flut Course", player, multiworld, level_name, 23) + flut_flut_course.add_cell_locations([37]) + flut_flut_course.add_fly_locations([327723, 131115]) + + # Includes some orbs on the way to the cabin, blue+yellow eco to collect. + farthy_snacks = JakAndDaxterRegion("Farthy's Snacks", player, multiworld, level_name, 7) + farthy_snacks.add_cell_locations([36]) + + # Scout fly in this field can be broken with yellow eco. + box_field = JakAndDaxterRegion("Field of Boxes", player, multiworld, level_name, 10) + box_field.add_fly_locations([196651]) + + last_tar_pit = JakAndDaxterRegion("Last Tar Pit", player, multiworld, level_name, 12) + + fourth_tether = JakAndDaxterRegion("Fourth Tether", player, multiworld, level_name, 11) + fourth_tether.add_cell_locations([41], access_rule=lambda state: can_jump_higher(state, player)) + + main_area.connect(first_bats, rule=lambda state: can_jump_farther(state, player)) + + first_bats.connect(main_area) + first_bats.connect(first_jump_pad) + first_bats.connect(first_tether) + + first_jump_pad.connect(first_bats) + + first_tether.connect(first_bats) + first_tether.connect(first_tether_rat_colony, rule=lambda state: + (state.has_all(("Roll", "Roll Jump"), player) + or state.has_all(("Double Jump", "Jump Kick"), player))) + first_tether.connect(second_jump_pad) + first_tether.connect(first_pole_course) + + first_tether_rat_colony.connect(first_tether) + + second_jump_pad.connect(first_tether) + + first_pole_course.connect(first_tether) + first_pole_course.connect(second_tether) + + second_tether.connect(first_pole_course, rule=lambda state: can_jump_higher(state, player)) + second_tether.connect(second_bats) + + second_bats.connect(second_tether) + second_bats.connect(third_jump_pad) + second_bats.connect(fourth_jump_pad) + second_bats.connect(flut_flut_pad) + + third_jump_pad.connect(second_bats) + fourth_jump_pad.connect(second_bats) + + flut_flut_pad.connect(second_bats) + flut_flut_pad.connect(flut_flut_course, rule=lambda state: state.has("Flut Flut", player)) # Naturally. + flut_flut_pad.connect(farthy_snacks) + + flut_flut_course.connect(flut_flut_pad) + + farthy_snacks.connect(flut_flut_pad) + farthy_snacks.connect(box_field, rule=lambda state: can_jump_higher(state, player)) + + box_field.connect(farthy_snacks, rule=lambda state: can_jump_higher(state, player)) + box_field.connect(last_tar_pit, rule=lambda state: can_jump_farther(state, player)) + + last_tar_pit.connect(box_field, rule=lambda state: can_jump_farther(state, player)) + last_tar_pit.connect(fourth_tether, rule=lambda state: can_jump_farther(state, player)) + + fourth_tether.connect(last_tar_pit, rule=lambda state: can_jump_farther(state, player)) + fourth_tether.connect(main_area) # Fall down. + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(first_bats) + world.level_to_regions[level_name].append(first_jump_pad) + world.level_to_regions[level_name].append(first_tether) + world.level_to_regions[level_name].append(first_tether_rat_colony) + world.level_to_regions[level_name].append(second_jump_pad) + world.level_to_regions[level_name].append(first_pole_course) + world.level_to_regions[level_name].append(second_tether) + world.level_to_regions[level_name].append(second_bats) + world.level_to_regions[level_name].append(third_jump_pad) + world.level_to_regions[level_name].append(fourth_jump_pad) + world.level_to_regions[level_name].append(flut_flut_pad) + world.level_to_regions[level_name].append(flut_flut_course) + world.level_to_regions[level_name].append(farthy_snacks) + world.level_to_regions[level_name].append(box_field) + world.level_to_regions[level_name].append(last_tar_pit) + world.level_to_regions[level_name].append(fourth_tether) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 200 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(8, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/fire_canyon_regions.py b/worlds/jakanddaxter/regs/fire_canyon_regions.py new file mode 100644 index 000000000000..9ce0f5dae24e --- /dev/null +++ b/worlds/jakanddaxter/regs/fire_canyon_regions.py @@ -0,0 +1,38 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_reach_orbs_level +from ..locs import cell_locations as cells, scout_locations as scouts + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 50) + + # Everything is accessible by making contact with the zoomer. + main_area.add_cell_locations(cells.locFC_cellTable.keys()) + main_area.add_fly_locations(scouts.locFC_scoutTable.keys()) + + world.level_to_regions[level_name].append(main_area) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 50 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(5, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/forbidden_jungle_regions.py b/worlds/jakanddaxter/regs/forbidden_jungle_regions.py new file mode 100644 index 000000000000..601a802e55d2 --- /dev/null +++ b/worlds/jakanddaxter/regs/forbidden_jungle_regions.py @@ -0,0 +1,103 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_free_scout_flies, can_fight, can_reach_orbs_level + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> tuple[JakAndDaxterRegion, ...]: + multiworld = world.multiworld + options = world.options + player = world.player + + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 25) + + # You can get this scout fly by running from the blue eco vent across the temple bridge, + # falling onto the river, collecting the 3 blue clusters, using the jump pad, and running straight to the box. + main_area.add_fly_locations([393223]) + + lurker_machine = JakAndDaxterRegion("Lurker Machine", player, multiworld, level_name, 5) + lurker_machine.add_cell_locations([3], access_rule=lambda state: can_fight(state, player)) + + # This cell and this scout fly can both be gotten with the blue eco clusters near the jump pad. + lurker_machine.add_cell_locations([9]) + lurker_machine.add_fly_locations([131079]) + + river = JakAndDaxterRegion("River", player, multiworld, level_name, 42) + + # All of these can be gotten with blue eco, hitting the dark eco boxes, or by running. + river.add_cell_locations([5, 8]) + river.add_fly_locations([7, 196615]) + river.add_special_locations([5]) + river.add_cache_locations([10369]) + + temple_exit = JakAndDaxterRegion("Temple Exit", player, multiworld, level_name, 12) + + # This fly is too far from accessible blue eco sources. + temple_exit.add_fly_locations([262151], access_rule=lambda state: can_free_scout_flies(state, player)) + + temple_exterior = JakAndDaxterRegion("Temple Exterior", player, multiworld, level_name, 10) + + # All of these can be gotten with blue eco and running. + temple_exterior.add_cell_locations([4]) + temple_exterior.add_fly_locations([327687, 65543]) + temple_exterior.add_special_locations([4]) + + temple_int_pre_blue = JakAndDaxterRegion("Temple Interior (Pre Blue Eco)", player, multiworld, level_name, 17) + temple_int_pre_blue.add_cell_locations([2]) + temple_int_pre_blue.add_special_locations([2]) + + temple_int_post_blue = JakAndDaxterRegion("Temple Interior (Post Blue Eco)", player, multiworld, level_name, 39) + temple_int_post_blue.add_cell_locations([6], access_rule=lambda state: can_fight(state, player)) + + main_area.connect(lurker_machine) # Run and jump (tree stump platforms). + main_area.connect(river) # Jump down. + main_area.connect(temple_exit) # Run and jump (bridges). + + lurker_machine.connect(main_area) # Jump down. + lurker_machine.connect(river) # Jump down. + lurker_machine.connect(temple_exterior) # Jump down (ledge). + + river.connect(main_area) # Jump up (ledges near fisherman). + river.connect(lurker_machine) # Jump pad (aim toward machine). + river.connect(temple_exit) # Run and jump (trampolines). + river.connect(temple_exterior) # Jump pad (aim toward temple door). + + temple_exit.connect(main_area) # Run and jump (bridges). + temple_exit.connect(river) # Jump down. + temple_exit.connect(temple_exterior) # Run and jump (bridges, dodge spikes). + + # Requires Jungle Elevator. + temple_exterior.connect(temple_int_pre_blue, rule=lambda state: state.has("Jungle Elevator", player)) + + # Requires Blue Eco Switch. + temple_int_pre_blue.connect(temple_int_post_blue, rule=lambda state: state.has("Blue Eco Switch", player)) + + # Requires defeating the plant boss (combat). + temple_int_post_blue.connect(temple_exit, rule=lambda state: can_fight(state, player)) + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(lurker_machine) + world.level_to_regions[level_name].append(river) + world.level_to_regions[level_name].append(temple_exit) + world.level_to_regions[level_name].append(temple_exterior) + world.level_to_regions[level_name].append(temple_int_pre_blue) + world.level_to_regions[level_name].append(temple_int_post_blue) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 150 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(3, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area, temple_int_post_blue diff --git a/worlds/jakanddaxter/regs/geyser_rock_regions.py b/worlds/jakanddaxter/regs/geyser_rock_regions.py new file mode 100644 index 000000000000..10783067c358 --- /dev/null +++ b/worlds/jakanddaxter/regs/geyser_rock_regions.py @@ -0,0 +1,48 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_reach_orbs_level +from ..locs import scout_locations as scouts + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 48) + main_area.add_cell_locations([92, 93]) + main_area.add_fly_locations(scouts.locGR_scoutTable.keys()) # All Flies here are accessible with blue eco. + + # The last 2 orbs are barely gettable with the blue eco vent, but it's pushing accessibility. So I moved them here. + cliff = JakAndDaxterRegion("Cliff", player, multiworld, level_name, 2) + cliff.add_cell_locations([94]) + + main_area.connect(cliff, rule=lambda state: + state.has("Double Jump", player) + or state.has_all(("Crouch", "Crouch Jump"), player) + or state.has_all(("Crouch", "Crouch Uppercut"), player)) + + cliff.connect(main_area) # Jump down or ride blue eco elevator. + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(cliff) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 50 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(0, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/gol_and_maias_citadel_regions.py b/worlds/jakanddaxter/regs/gol_and_maias_citadel_regions.py new file mode 100644 index 000000000000..83d2d51f1d8d --- /dev/null +++ b/worlds/jakanddaxter/regs/gol_and_maias_citadel_regions.py @@ -0,0 +1,137 @@ +from BaseClasses import CollectionState +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity, CompletionCondition +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_free_scout_flies, can_fight, can_reach_orbs_level + + +# God help me... here we go. +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> tuple[JakAndDaxterRegion | None, ...]: + multiworld = world.multiworld + options = world.options + player = world.player + + # This level is full of short-medium gaps that cannot be crossed by single jump alone. + # These helper functions list out the moves that can cross all these gaps (painting with a broad brush but...) + def can_jump_farther(state: CollectionState, p: int) -> bool: + return (state.has_any(("Double Jump", "Jump Kick"), p) + or state.has_all(("Punch", "Punch Uppercut"), p)) + + def can_triple_jump(state: CollectionState, p: int) -> bool: + return state.has_all(("Double Jump", "Jump Kick"), p) + + def can_jump_stairs(state: CollectionState, p: int) -> bool: + return (state.has("Double Jump", p) + or state.has("Jump Dive", p) + or state.has_all(("Crouch", "Crouch Jump"), p) + or state.has_all(("Crouch", "Crouch Uppercut"), p)) + + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 0) + main_area.add_fly_locations([91], access_rule=lambda state: can_free_scout_flies(state, player)) + + robot_scaffolding = JakAndDaxterRegion("Scaffolding Around Robot", player, multiworld, level_name, 8) + robot_scaffolding.add_fly_locations([196699], access_rule=lambda state: can_free_scout_flies(state, player)) + + jump_pad_room = JakAndDaxterRegion("Jump Pad Chamber", player, multiworld, level_name, 88) + jump_pad_room.add_cell_locations([73], access_rule=lambda state: can_fight(state, player)) + jump_pad_room.add_special_locations([73], access_rule=lambda state: can_fight(state, player)) + jump_pad_room.add_fly_locations([131163]) # Blue eco vent is right next to it. + jump_pad_room.add_fly_locations([65627], access_rule=lambda state: + can_free_scout_flies(state, player) and can_jump_farther(state, player)) + jump_pad_room.add_cache_locations([24039, 24040]) # First, blue eco vent, second, blue eco cluster near sage. + + blast_furnace = JakAndDaxterRegion("Blast Furnace", player, multiworld, level_name, 39) + blast_furnace.add_cell_locations([71], access_rule=lambda state: can_fight(state, player)) + blast_furnace.add_special_locations([71], access_rule=lambda state: can_fight(state, player)) + blast_furnace.add_fly_locations([393307]) # Blue eco vent nearby. + blast_furnace.add_cache_locations([24038]) # Blue eco cluster near sage. + + bunny_room = JakAndDaxterRegion("Bunny Chamber", player, multiworld, level_name, 45) + bunny_room.add_cell_locations([72], access_rule=lambda state: can_fight(state, player)) + bunny_room.add_special_locations([72], access_rule=lambda state: can_fight(state, player)) + bunny_room.add_fly_locations([262235], access_rule=lambda state: can_free_scout_flies(state, player)) + + rotating_tower = JakAndDaxterRegion("Rotating Tower", player, multiworld, level_name, 20) + rotating_tower.add_cell_locations([70], access_rule=lambda state: can_fight(state, player)) + rotating_tower.add_special_locations([70], access_rule=lambda state: can_fight(state, player)) + rotating_tower.add_fly_locations([327771], access_rule=lambda state: can_free_scout_flies(state, player)) + + final_boss = JakAndDaxterRegion("Final Boss", player, multiworld, level_name, 0) + + # Jump Dive required for a lot of buttons, prepare yourself. + main_area.connect(robot_scaffolding, rule=lambda state: + state.has("Jump Dive", player) or state.has_all(("Roll", "Roll Jump"), player)) + main_area.connect(jump_pad_room) + + robot_scaffolding.connect(main_area, rule=lambda state: state.has("Jump Dive", player)) + robot_scaffolding.connect(blast_furnace, rule=lambda state: + state.has("Jump Dive", player) + and can_jump_farther(state, player) + and (can_triple_jump(state, player) or state.has_all(("Roll", "Roll Jump"), player))) + robot_scaffolding.connect(bunny_room, rule=lambda state: + state.has("Jump Dive", player) + and can_jump_farther(state, player) + and (can_triple_jump(state, player) or state.has_all(("Roll", "Roll Jump"), player))) + + jump_pad_room.connect(main_area) + jump_pad_room.connect(robot_scaffolding, rule=lambda state: + state.has("Jump Dive", player) + and (can_triple_jump(state, player) or state.has_all(("Roll", "Roll Jump"), player))) + + blast_furnace.connect(robot_scaffolding) # Blue eco elevator takes you right back. + + bunny_room.connect(robot_scaffolding, rule=lambda state: + state.has("Jump Dive", player) + and (can_jump_farther(state, player) or state.has_all(("Roll", "Roll Jump"), player))) + + # Final climb. + robot_scaffolding.connect(rotating_tower, rule=lambda state: + can_jump_stairs(state, player) + and state.has_all(("Freed The Blue Sage", + "Freed The Red Sage", + "Freed The Yellow Sage"), player)) + + rotating_tower.connect(main_area) # Take stairs back down. + + # Final elevator. Need to break boxes at summit to get blue eco for platform. + rotating_tower.connect(final_boss, rule=lambda state: + can_fight(state, player) + and state.has("Freed The Green Sage", player)) + + final_boss.connect(rotating_tower) # Take elevator back down. + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(robot_scaffolding) + world.level_to_regions[level_name].append(jump_pad_room) + world.level_to_regions[level_name].append(blast_furnace) + world.level_to_regions[level_name].append(bunny_room) + world.level_to_regions[level_name].append(rotating_tower) + world.level_to_regions[level_name].append(final_boss) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 200 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(15, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + # Final door. Need 100 power cells. + if options.jak_completion_condition == CompletionCondition.option_open_100_cell_door: + final_door = JakAndDaxterRegion("Final Door", player, multiworld, level_name, 0) + final_boss.connect(final_door, rule=lambda state: state.has("Power Cell", player, 100)) + + world.level_to_regions[level_name].append(final_door) + + return main_area, final_boss, final_door + else: + return main_area, final_boss, None diff --git a/worlds/jakanddaxter/regs/lava_tube_regions.py b/worlds/jakanddaxter/regs/lava_tube_regions.py new file mode 100644 index 000000000000..c3a4c5b24d3f --- /dev/null +++ b/worlds/jakanddaxter/regs/lava_tube_regions.py @@ -0,0 +1,38 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_reach_orbs_level +from ..locs import cell_locations as cells, scout_locations as scouts + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 50) + + # Everything is accessible by making contact with the zoomer. + main_area.add_cell_locations(cells.locLT_cellTable.keys()) + main_area.add_fly_locations(scouts.locLT_scoutTable.keys()) + + world.level_to_regions[level_name].append(main_area) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 50 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(14, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/lost_precursor_city_regions.py b/worlds/jakanddaxter/regs/lost_precursor_city_regions.py new file mode 100644 index 000000000000..f4a2ed6b5190 --- /dev/null +++ b/worlds/jakanddaxter/regs/lost_precursor_city_regions.py @@ -0,0 +1,155 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_free_scout_flies, can_fight, can_reach_orbs_level + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + # Just the starting area. + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 4) + + first_room_upper = JakAndDaxterRegion("First Chamber (Upper)", player, multiworld, level_name, 21) + + first_room_lower = JakAndDaxterRegion("First Chamber (Lower)", player, multiworld, level_name, 0) + first_room_lower.add_fly_locations([262193], access_rule=lambda state: can_free_scout_flies(state, player)) + + first_room_orb_cache = JakAndDaxterRegion("First Chamber Orb Cache", player, multiworld, level_name, 22) + + # Need jump dive to activate button, double jump to reach blue eco to unlock cache. + first_room_orb_cache.add_cache_locations([14507], access_rule=lambda state: + state.has_all(("Jump Dive", "Double Jump"), player)) + + first_hallway = JakAndDaxterRegion("First Hallway", player, multiworld, level_name, 10) + first_hallway.add_fly_locations([131121], access_rule=lambda state: can_free_scout_flies(state, player)) + + # This entire room is accessible with floating platforms and single jump. + second_room = JakAndDaxterRegion("Second Chamber", player, multiworld, level_name, 28) + + # These items can only be gotten with jump dive to activate a button. + second_room.add_cell_locations([45], access_rule=lambda state: state.has("Jump Dive", player)) + second_room.add_fly_locations([49, 65585], access_rule=lambda state: state.has("Jump Dive", player)) + + # This is the scout fly on the way to the pipe cell, requires normal breaking moves. + second_room.add_fly_locations([196657], access_rule=lambda state: can_free_scout_flies(state, player)) + + # This orb vent and scout fly are right next to each other, can be gotten with blue eco and the floating platforms. + second_room.add_fly_locations([393265]) + second_room.add_cache_locations([14838]) + + # Named after the cell, includes the armored lurker room. + center_complex = JakAndDaxterRegion("Center of the Complex", player, multiworld, level_name, 17) + center_complex.add_cell_locations([51]) + + color_platforms = JakAndDaxterRegion("Color Platforms", player, multiworld, level_name, 6) + color_platforms.add_cell_locations([44], access_rule=lambda state: can_fight(state, player)) + + quick_platforms = JakAndDaxterRegion("Quick Platforms", player, multiworld, level_name, 3) + + # Jump dive to activate button. + quick_platforms.add_cell_locations([48], access_rule=lambda state: state.has("Jump Dive", player)) + + first_slide = JakAndDaxterRegion("First Slide", player, multiworld, level_name, 22) + + # Raised chamber room, includes vent room with scout fly prior to second slide. + capsule_room = JakAndDaxterRegion("Capsule Chamber", player, multiworld, level_name, 6) + + # Use jump dive to activate button inside the capsule. Blue eco vent can ready the chamber and get the scout fly. + capsule_room.add_cell_locations([47], access_rule=lambda state: + state.has("Jump Dive", player) + and (state.has_any(("Double Jump", "Jump Kick"), player) + or state.has_all(("Punch", "Punch Uppercut"), player))) + capsule_room.add_fly_locations([327729]) + + # You can slide to the bottom of the city, but if you spawn down there, you have no momentum from the slide. + # So you need some kind of jump to reach this cell. + second_slide = JakAndDaxterRegion("Second Slide", player, multiworld, level_name, 31) + second_slide.add_cell_locations([46], access_rule=lambda state: + state.has_any(("Double Jump", "Jump Kick"), player) + or state.has_all(("Punch", "Punch Uppercut"), player)) + + # If you can enter the helix room, you can jump or fight your way to the top. But you need some kind of movement + # to enter it in the first place. + helix_room = JakAndDaxterRegion("Helix Chamber", player, multiworld, level_name, 30) + helix_room.add_cell_locations([50], access_rule=lambda state: + state.has("Double Jump", player) + or can_fight(state, player)) + + main_area.connect(first_room_upper) # Run. + + first_room_upper.connect(main_area) # Run. + first_room_upper.connect(first_hallway) # Run and jump (floating platforms). + first_room_upper.connect(first_room_lower) # Run and jump down. + + first_room_lower.connect(first_room_upper) # Run and jump (floating platforms). + + # Needs some movement to reach these orbs and orb cache. + first_room_lower.connect(first_room_orb_cache, rule=lambda state: + state.has_all(("Jump Dive", "Double Jump"), player)) + first_room_orb_cache.connect(first_room_lower, rule=lambda state: + state.has_all(("Jump Dive", "Double Jump"), player)) + + first_hallway.connect(first_room_upper) # Run and jump down. + first_hallway.connect(second_room) # Run and jump (floating platforms). + + second_room.connect(first_hallway) # Run and jump. + second_room.connect(center_complex) # Run and jump down. + + center_complex.connect(second_room) # Run and jump (swim). + center_complex.connect(color_platforms) # Run and jump (swim). + center_complex.connect(quick_platforms) # Run and jump (swim). + + color_platforms.connect(center_complex) # Run and jump (swim). + + quick_platforms.connect(center_complex) # Run and jump (swim). + quick_platforms.connect(first_slide) # Slide. + + first_slide.connect(capsule_room) # Slide. + + capsule_room.connect(second_slide) # Slide. + capsule_room.connect(main_area, rule=lambda state: # Chamber goes back to surface. + state.has("Jump Dive", player)) # (Assume one-way for sanity.) + + second_slide.connect(helix_room, rule=lambda state: # As stated above, you need to jump + state.has_any(("Double Jump", "Jump Kick"), player) # across the dark eco pool before + or state.has_all(("Punch", "Punch Uppercut"), player)) # you can climb the helix room. + + helix_room.connect(quick_platforms, rule=lambda state: # Escape to get back to here. + state.has("Double Jump", player) # Capsule is a convenient exit to the level. + or can_fight(state, player)) + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(first_room_upper) + world.level_to_regions[level_name].append(first_room_lower) + world.level_to_regions[level_name].append(first_room_orb_cache) + world.level_to_regions[level_name].append(first_hallway) + world.level_to_regions[level_name].append(second_room) + world.level_to_regions[level_name].append(center_complex) + world.level_to_regions[level_name].append(color_platforms) + world.level_to_regions[level_name].append(quick_platforms) + world.level_to_regions[level_name].append(first_slide) + world.level_to_regions[level_name].append(capsule_room) + world.level_to_regions[level_name].append(second_slide) + world.level_to_regions[level_name].append(helix_room) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 200 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(7, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/misty_island_regions.py b/worlds/jakanddaxter/regs/misty_island_regions.py new file mode 100644 index 000000000000..a6ae6122476b --- /dev/null +++ b/worlds/jakanddaxter/regs/misty_island_regions.py @@ -0,0 +1,131 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_free_scout_flies, can_fight, can_reach_orbs_level + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 9) + + muse_course = JakAndDaxterRegion("Muse Course", player, multiworld, level_name, 21) + muse_course.add_cell_locations([23]) + muse_course.add_fly_locations([327708], access_rule=lambda state: can_free_scout_flies(state, player)) + + zoomer = JakAndDaxterRegion("Zoomer", player, multiworld, level_name, 32) + zoomer.add_cell_locations([27, 29]) + zoomer.add_fly_locations([393244]) + + ship = JakAndDaxterRegion("Ship", player, multiworld, level_name, 10) + ship.add_cell_locations([24]) + ship.add_fly_locations([131100], access_rule=lambda state: can_free_scout_flies(state, player)) + + far_side = JakAndDaxterRegion("Far Side", player, multiworld, level_name, 16) + + # In order to even reach this fly, you must use the seesaw or crouch jump. + far_side_cliff = JakAndDaxterRegion("Far Side Cliff", player, multiworld, level_name, 5) + far_side_cliff.add_fly_locations([28], access_rule=lambda state: can_free_scout_flies(state, player)) + + # To carry the blue eco fast enough to open this cache, you need to break the bone bridges along the way. + far_side_cache = JakAndDaxterRegion("Far Side Orb Cache", player, multiworld, level_name, 15) + far_side_cache.add_cache_locations([11072], access_rule=lambda state: can_fight(state, player)) + + barrel_course = JakAndDaxterRegion("Barrel Course", player, multiworld, level_name, 10) + barrel_course.add_fly_locations([196636], access_rule=lambda state: can_free_scout_flies(state, player)) + + # 14 orbs for the boxes you can only break with the cannon. + cannon = JakAndDaxterRegion("Cannon", player, multiworld, level_name, 14) + cannon.add_cell_locations([26], access_rule=lambda state: can_fight(state, player)) + + upper_approach = JakAndDaxterRegion("Upper Arena Approach", player, multiworld, level_name, 6) + upper_approach.add_fly_locations([65564, 262172], access_rule=lambda state: + can_free_scout_flies(state, player)) + + lower_approach = JakAndDaxterRegion("Lower Arena Approach", player, multiworld, level_name, 7) + lower_approach.add_cell_locations([30]) + + arena = JakAndDaxterRegion("Arena", player, multiworld, level_name, 5) + arena.add_cell_locations([25], access_rule=lambda state: can_fight(state, player)) + + main_area.connect(muse_course) # TODO - What do you need to chase the muse the whole way around? + main_area.connect(zoomer) # Run and jump down. + main_area.connect(ship) # Run and jump. + main_area.connect(lower_approach) # Run and jump. + + # Need to break the bone bridge to access. + main_area.connect(upper_approach, rule=lambda state: can_fight(state, player)) + + muse_course.connect(main_area) # Run and jump down. + + # The zoomer pad is low enough that it requires Crouch Jump specifically. + zoomer.connect(main_area, rule=lambda state: state.has_all(("Crouch", "Crouch Jump"), player)) + + ship.connect(main_area) # Run and jump down. + ship.connect(far_side) # Run and jump down. + ship.connect(barrel_course) # Run and jump (dodge barrels). + + far_side.connect(ship) # Run and jump. + far_side.connect(arena) # Run and jump. + + # Only if you can use the seesaw or Crouch Jump from the seesaw's edge. + far_side.connect(far_side_cliff, rule=lambda state: + state.has("Jump Dive", player) + or state.has_all(("Crouch", "Crouch Jump"), player)) + + # Only if you can break the bone bridges to carry blue eco over the mud pit. + far_side.connect(far_side_cache, rule=lambda state: can_fight(state, player)) + + far_side_cliff.connect(far_side) # Run and jump down. + + barrel_course.connect(cannon) # Run and jump (dodge barrels). + + cannon.connect(barrel_course) # Run and jump (dodge barrels). + cannon.connect(arena) # Run and jump down. + cannon.connect(upper_approach) # Run and jump down. + + upper_approach.connect(lower_approach) # Jump down. + upper_approach.connect(arena) # Jump down. + + # One cliff is accessible, but only via Crouch Jump. + lower_approach.connect(upper_approach, rule=lambda state: state.has_all(("Crouch", "Crouch Jump"), player)) + + # Requires breaking bone bridges. + lower_approach.connect(arena, rule=lambda state: can_fight(state, player)) + + arena.connect(lower_approach) # Run. + arena.connect(far_side) # Run. + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(muse_course) + world.level_to_regions[level_name].append(zoomer) + world.level_to_regions[level_name].append(ship) + world.level_to_regions[level_name].append(far_side) + world.level_to_regions[level_name].append(far_side_cliff) + world.level_to_regions[level_name].append(far_side_cache) + world.level_to_regions[level_name].append(barrel_course) + world.level_to_regions[level_name].append(cannon) + world.level_to_regions[level_name].append(upper_approach) + world.level_to_regions[level_name].append(lower_approach) + world.level_to_regions[level_name].append(arena) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 150 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(4, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/mountain_pass_regions.py b/worlds/jakanddaxter/regs/mountain_pass_regions.py new file mode 100644 index 000000000000..bd26be8dd2bd --- /dev/null +++ b/worlds/jakanddaxter/regs/mountain_pass_regions.py @@ -0,0 +1,67 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_reach_orbs_level +from ..locs import scout_locations as scouts +from worlds.generic.Rules import add_rule + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> tuple[JakAndDaxterRegion, ...]: + multiworld = world.multiworld + options = world.options + player = world.player + + # This is basically just Klaww. + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 0) + main_area.add_cell_locations([86]) + + # Some folks prefer firing Yellow Eco from the hip, so optionally put this rule before Klaww. Klaww is the only + # location in main_area, so he's at index 0. + if world.options.require_punch_for_klaww: + add_rule(main_area.locations[0], lambda state: state.has("Punch", player)) + + race = JakAndDaxterRegion("Race", player, multiworld, level_name, 50) + race.add_cell_locations([87]) + + # All scout flies can be broken with the zoomer. + race.add_fly_locations(scouts.locMP_scoutTable.keys()) + + shortcut = JakAndDaxterRegion("Shortcut", player, multiworld, level_name, 0) + shortcut.add_cell_locations([110]) + + # Of course, in order to make it to the race region, you must defeat Klaww. He's not optional. + # So we need to set up this inter-region rule as well (or make it free if the setting is off). + if world.options.require_punch_for_klaww: + main_area.connect(race, rule=lambda state: state.has("Punch", player)) + else: + main_area.connect(race) + + # You actually can go backwards from the race back to Klaww's area. + race.connect(main_area) + race.connect(shortcut, rule=lambda state: state.has("Yellow Eco Switch", player)) + + shortcut.connect(race) + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(race) + world.level_to_regions[level_name].append(shortcut) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 50 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(10, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + # Return race required for inter-level connections. + return main_area, race diff --git a/worlds/jakanddaxter/regs/precursor_basin_regions.py b/worlds/jakanddaxter/regs/precursor_basin_regions.py new file mode 100644 index 000000000000..25a109155b92 --- /dev/null +++ b/worlds/jakanddaxter/regs/precursor_basin_regions.py @@ -0,0 +1,38 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_reach_orbs_level +from ..locs import cell_locations as cells, scout_locations as scouts + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 200) + + # Everything is accessible by making contact with the zoomer. + main_area.add_cell_locations(cells.locPB_cellTable.keys()) + main_area.add_fly_locations(scouts.locPB_scoutTable.keys()) + + world.level_to_regions[level_name].append(main_area) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 200 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(9, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/region_base.py b/worlds/jakanddaxter/regs/region_base.py new file mode 100644 index 000000000000..cb1005aa7a0c --- /dev/null +++ b/worlds/jakanddaxter/regs/region_base.py @@ -0,0 +1,91 @@ +from typing import Iterable +from BaseClasses import MultiWorld, Region +from ..game_id import jak1_name +from ..locations import JakAndDaxterLocation, location_table +from ..locs import (orb_locations as orbs, + cell_locations as cells, + scout_locations as scouts, + special_locations as specials, + orb_cache_locations as caches) +from worlds.generic.Rules import CollectionRule + + +class JakAndDaxterRegion(Region): + """ + Holds region information such as name, level name, number of orbs available, etc. + We especially need orb counts to be tracked because we need to know when you can + afford the Citizen and Oracle orb payments for more checks. + """ + game: str = jak1_name + level_name: str + orb_count: int + location_count: int = 0 + + def __init__(self, name: str, player: int, multiworld: MultiWorld, level_name: str = "", orb_count: int = 0): + formatted_name = f"{level_name} {name}".strip() + super().__init__(formatted_name, player, multiworld) + self.level_name = level_name + self.orb_count = orb_count + + def add_cell_locations(self, locations: Iterable[int], access_rule: CollectionRule | None = None) -> None: + """ + Adds a Power Cell Location to this region with the given access rule. + Converts Game ID's to AP ID's for you. + """ + for loc in locations: + ap_id = cells.to_ap_id(loc) + self.add_jak_location(ap_id, location_table[ap_id], access_rule) + + def add_fly_locations(self, locations: Iterable[int], access_rule: CollectionRule | None = None) -> None: + """ + Adds a Scout Fly Location to this region with the given access rule. + Converts Game ID's to AP ID's for you. + """ + for loc in locations: + ap_id = scouts.to_ap_id(loc) + self.add_jak_location(ap_id, location_table[ap_id], access_rule) + + def add_special_locations(self, locations: Iterable[int], access_rule: CollectionRule | None = None) -> None: + """ + Adds a Special Location to this region with the given access rule. + Converts Game ID's to AP ID's for you. + Special Locations should be matched alongside their respective + Power Cell Locations, so you get 2 unlocks for these rather than 1. + """ + for loc in locations: + ap_id = specials.to_ap_id(loc) + self.add_jak_location(ap_id, location_table[ap_id], access_rule) + + def add_cache_locations(self, locations: Iterable[int], access_rule: CollectionRule | None = None) -> None: + """ + Adds an Orb Cache Location to this region with the given access rule. + Converts Game ID's to AP ID's for you. + """ + for loc in locations: + ap_id = caches.to_ap_id(loc) + self.add_jak_location(ap_id, location_table[ap_id], access_rule) + + def add_orb_locations(self, level_index: int, bundle_index: int, access_rule: CollectionRule | None = None) -> None: + """ + Adds Orb Bundle Locations to this region equal to `bundle_count`. Used only when Per-Level Orbsanity is enabled. + The orb factory class will handle AP ID enumeration. + """ + bundle_address = orbs.create_address(level_index, bundle_index) + location = JakAndDaxterLocation(self.player, + f"{self.level_name} Orb Bundle {bundle_index + 1}".strip(), + orbs.to_ap_id(bundle_address), + self) + if access_rule: + location.access_rule = access_rule + self.locations.append(location) + self.location_count += 1 + + def add_jak_location(self, ap_id: int, name: str, access_rule: CollectionRule | None = None) -> None: + """ + Helper function to add Locations. Not to be used directly. + """ + location = JakAndDaxterLocation(self.player, name, ap_id, self) + if access_rule: + location.access_rule = access_rule + self.locations.append(location) + self.location_count += 1 diff --git a/worlds/jakanddaxter/regs/rock_village_regions.py b/worlds/jakanddaxter/regs/rock_village_regions.py new file mode 100644 index 000000000000..2138eb119404 --- /dev/null +++ b/worlds/jakanddaxter/regs/rock_village_regions.py @@ -0,0 +1,75 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_free_scout_flies, can_reach_orbs_level + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> tuple[JakAndDaxterRegion, ...]: + multiworld = world.multiworld + options = world.options + player = world.player + + # This includes most of the area surrounding LPC as well, for orb_count purposes. You can swim and single jump. + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 23) + main_area.add_cell_locations([31], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, None)) + main_area.add_cell_locations([32], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, None)) + main_area.add_cell_locations([33], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, None)) + main_area.add_cell_locations([34], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, None)) + main_area.add_cell_locations([35], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, 34)) + + # These 2 scout fly boxes can be broken by running with nearby blue eco. + main_area.add_fly_locations([196684, 262220]) + main_area.add_fly_locations([76, 131148, 65612, 327756], access_rule=lambda state: + can_free_scout_flies(state, player)) + + # Warrior Pontoon check. You just talk to him and get his introduction. + main_area.add_special_locations([33]) + + orb_cache = JakAndDaxterRegion("Orb Cache", player, multiworld, level_name, 20) + + # You need roll jump to be able to reach this before the blue eco runs out. + orb_cache.add_cache_locations([10945], access_rule=lambda state: state.has_all(("Roll", "Roll Jump"), player)) + + # Fly here can be gotten with Yellow Eco from Boggy, goggles, and no extra movement options (see fly ID 43). + pontoon_bridge = JakAndDaxterRegion("Pontoon Bridge", player, multiworld, level_name, 7) + pontoon_bridge.add_fly_locations([393292]) + + klaww_cliff = JakAndDaxterRegion("Klaww's Cliff", player, multiworld, level_name, 0) + + main_area.connect(orb_cache, rule=lambda state: state.has_all(("Roll", "Roll Jump"), player)) + main_area.connect(pontoon_bridge, rule=lambda state: state.has("Warrior's Pontoons", player)) + + orb_cache.connect(main_area) + + pontoon_bridge.connect(main_area, rule=lambda state: state.has("Warrior's Pontoons", player)) + pontoon_bridge.connect(klaww_cliff, rule=lambda state: + state.has("Double Jump", player) + or state.has_all(("Crouch", "Crouch Jump"), player) + or state.has_all(("Crouch", "Crouch Uppercut", "Jump Kick"), player)) + + klaww_cliff.connect(pontoon_bridge) # Just jump back down. + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(orb_cache) + world.level_to_regions[level_name].append(pontoon_bridge) + world.level_to_regions[level_name].append(klaww_cliff) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 50 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(6, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + # Return klaww_cliff required for inter-level connections. + return main_area, pontoon_bridge, klaww_cliff diff --git a/worlds/jakanddaxter/regs/sandover_village_regions.py b/worlds/jakanddaxter/regs/sandover_village_regions.py new file mode 100644 index 000000000000..3969cdb41ad2 --- /dev/null +++ b/worlds/jakanddaxter/regs/sandover_village_regions.py @@ -0,0 +1,83 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_free_scout_flies, can_reach_orbs_level + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 26) + + # Yakows requires no combat. + main_area.add_cell_locations([10]) + main_area.add_cell_locations([11], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, None)) + main_area.add_cell_locations([12], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, None)) + + # These 4 scout fly boxes can be broken by running with all the blue eco from Sentinel Beach. + main_area.add_fly_locations([262219, 327755, 131147, 65611]) + + # The farmer's scout fly. You can either get the Orb Cache Cliff blue eco, or break it normally. + main_area.add_fly_locations([196683], access_rule=lambda state: + state.has("Double Jump", player) + or state.has_all(("Crouch", "Crouch Jump"), player) + or can_free_scout_flies(state, player)) + + orb_cache_cliff = JakAndDaxterRegion("Orb Cache Cliff", player, multiworld, level_name, 15) + orb_cache_cliff.add_cache_locations([10344]) + + yakow_cliff = JakAndDaxterRegion("Yakow Cliff", player, multiworld, level_name, 3) + yakow_cliff.add_fly_locations([75], access_rule=lambda state: can_free_scout_flies(state, player)) + + oracle_platforms = JakAndDaxterRegion("Oracle Platforms", player, multiworld, level_name, 6) + oracle_platforms.add_cell_locations([13], access_rule=lambda state: + world.can_trade(state, world.total_trade_orbs, None)) + oracle_platforms.add_cell_locations([14], access_rule=lambda state: + world.can_trade(state, world.total_trade_orbs, 13)) + oracle_platforms.add_fly_locations([393291], access_rule=lambda state: + can_free_scout_flies(state, player)) + + main_area.connect(orb_cache_cliff, rule=lambda state: + state.has("Double Jump", player) + or state.has_all(("Crouch", "Crouch Jump"), player) + or state.has_all(("Crouch", "Crouch Uppercut", "Jump Kick"), player)) + + main_area.connect(yakow_cliff, rule=lambda state: + state.has("Double Jump", player) + or state.has_all(("Crouch", "Crouch Jump"), player) + or state.has_all(("Crouch", "Crouch Uppercut", "Jump Kick"), player)) + + main_area.connect(oracle_platforms, rule=lambda state: + state.has_all(("Roll", "Roll Jump"), player) + or state.has_all(("Double Jump", "Jump Kick"), player)) + + # All these can go back to main_area immediately. + orb_cache_cliff.connect(main_area) + yakow_cliff.connect(main_area) + oracle_platforms.connect(main_area) + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(orb_cache_cliff) + world.level_to_regions[level_name].append(yakow_cliff) + world.level_to_regions[level_name].append(oracle_platforms) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 50 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(1, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/sentinel_beach_regions.py b/worlds/jakanddaxter/regs/sentinel_beach_regions.py new file mode 100644 index 000000000000..293215ea8232 --- /dev/null +++ b/worlds/jakanddaxter/regs/sentinel_beach_regions.py @@ -0,0 +1,108 @@ +from BaseClasses import CollectionState +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_free_scout_flies, can_fight, can_reach_orbs_level + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 128) + main_area.add_cell_locations([18, 21, 22]) + + # These scout fly boxes can be broken by running with freely accessible blue eco. + # The 3 clusters by the Flut Flut egg can go surprisingly far. + main_area.add_fly_locations([327700, 20, 65556, 262164]) + + # This scout fly box can be broken with the locked blue eco vent, or by normal combat tricks. + main_area.add_fly_locations([393236], access_rule=lambda state: + state.has("Blue Eco Switch", player) + or can_free_scout_flies(state, player)) + + # No need for the blue eco vent for either of the orb caches. + main_area.add_cache_locations([12634, 12635]) + + pelican = JakAndDaxterRegion("Pelican", player, multiworld, level_name, 0) + pelican.add_cell_locations([16], access_rule=lambda state: can_fight(state, player)) + + # Only these specific attacks can push the flut flut egg off the cliff. + flut_flut_egg = JakAndDaxterRegion("Flut Flut Egg", player, multiworld, level_name, 0) + flut_flut_egg.add_cell_locations([17], access_rule=lambda state: + state.has_any(("Punch", "Kick", "Jump Kick"), player)) + flut_flut_egg.add_special_locations([17], access_rule=lambda state: + state.has_any(("Punch", "Kick", "Jump Kick"), player)) + + eco_harvesters = JakAndDaxterRegion("Eco Harvesters", player, multiworld, level_name, 0) + eco_harvesters.add_cell_locations([15], access_rule=lambda state: can_fight(state, player)) + + green_ridge = JakAndDaxterRegion("Ridge Near Green Vents", player, multiworld, level_name, 5) + green_ridge.add_fly_locations([131092], access_rule=lambda state: can_free_scout_flies(state, player)) + + blue_ridge = JakAndDaxterRegion("Ridge Near Blue Vent", player, multiworld, level_name, 5) + blue_ridge.add_fly_locations([196628], access_rule=lambda state: + state.has("Blue Eco Switch", player) + or can_free_scout_flies(state, player)) + + cannon_tower = JakAndDaxterRegion("Cannon Tower", player, multiworld, level_name, 12) + cannon_tower.add_cell_locations([19], access_rule=lambda state: can_fight(state, player)) + + main_area.connect(pelican) # Swim and jump. + main_area.connect(flut_flut_egg) # Run and jump. + main_area.connect(eco_harvesters) # Run. + + # We need a helper function for the uppercut logs. + def can_uppercut_and_jump_logs(state: CollectionState, p: int) -> bool: + return (state.has_any(("Double Jump", "Jump Kick"), p) + and (state.has_all(("Crouch", "Crouch Uppercut"), p) + or state.has_all(("Punch", "Punch Uppercut"), p))) + + # If you have double jump or crouch jump, you don't need the logs to reach this place. + main_area.connect(green_ridge, rule=lambda state: + state.has("Double Jump", player) + or state.has_all(("Crouch", "Crouch Jump"), player) + or can_uppercut_and_jump_logs(state, player)) + + # If you have the blue eco jump pad, you don't need the logs to reach this place. + main_area.connect(blue_ridge, rule=lambda state: + state.has("Blue Eco Switch", player) + or can_uppercut_and_jump_logs(state, player)) + + main_area.connect(cannon_tower, rule=lambda state: state.has("Blue Eco Switch", player)) + + # All these can go back to main_area immediately. + pelican.connect(main_area) + flut_flut_egg.connect(main_area) + eco_harvesters.connect(main_area) + green_ridge.connect(main_area) + blue_ridge.connect(main_area) + cannon_tower.connect(main_area) + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(pelican) + world.level_to_regions[level_name].append(flut_flut_egg) + world.level_to_regions[level_name].append(eco_harvesters) + world.level_to_regions[level_name].append(green_ridge) + world.level_to_regions[level_name].append(blue_ridge) + world.level_to_regions[level_name].append(cannon_tower) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 150 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(2, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/snowy_mountain_regions.py b/worlds/jakanddaxter/regs/snowy_mountain_regions.py new file mode 100644 index 000000000000..5adc3e9d2228 --- /dev/null +++ b/worlds/jakanddaxter/regs/snowy_mountain_regions.py @@ -0,0 +1,203 @@ +from BaseClasses import CollectionState +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_free_scout_flies, can_fight, can_reach_orbs_level + + +# God help me... here we go. +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + # We need a few helper functions. + def can_cross_long_gap(state: CollectionState, p: int) -> bool: + return (state.has_all(("Roll", "Roll Jump"), p) + or state.has_all(("Double Jump", "Jump Kick"), p)) + + def can_jump_blockers(state: CollectionState, p: int) -> bool: + return (state.has_any(("Double Jump", "Jump Kick"), p) + or state.has_all(("Crouch", "Crouch Jump"), p) + or state.has_all(("Punch", "Punch Uppercut"), p)) + + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 0) + main_area.add_fly_locations([65], access_rule=lambda state: can_free_scout_flies(state, player)) + + # We need a few virtual regions like we had for Dark Crystals in Spider Cave. + # First, a virtual region for the glacier lurkers. + glacier_lurkers = JakAndDaxterRegion("Glacier Lurkers", player, multiworld, level_name, 0) + + # Need to fight all the troops. + # Troop in snowball_canyon: cross main_area. + # Troop in ice_skating_rink: cross main_area and fort_exterior. + # Troop in fort_exterior: cross main_area and fort_exterior. + glacier_lurkers.add_cell_locations([61], access_rule=lambda state: + can_fight(state, player) + and can_cross_long_gap(state, player)) + + # Second, a virtual region for the precursor blockers. Unlike the others, this contains orbs: + # the total number of orbs that sit on top of the blockers. Yes, there are only 8. + blockers = JakAndDaxterRegion("Precursor Blockers", player, multiworld, level_name, 8) + + # 1 in main_area + # 2 in snowball_canyon + # 4 in ice_skating_rink + # 3 in fort_exterior + # 3 in bunny_cave_start + blockers.add_cell_locations([66], access_rule=lambda state: + can_fight(state, player) + and can_cross_long_gap(state, player)) + + snowball_canyon = JakAndDaxterRegion("Snowball Canyon", player, multiworld, level_name, 28) + + # The scout fly box *can* be broken without YES, so leave it in this region. + frozen_box_cave = JakAndDaxterRegion("Frozen Box Cave", player, multiworld, level_name, 12) + frozen_box_cave.add_fly_locations([327745], access_rule=lambda state: + state.has("Yellow Eco Switch", player) + or can_free_scout_flies(state, player)) + + # This region has crates that can *only* be broken with YES. + frozen_box_cave_crates = JakAndDaxterRegion("Frozen Box Cave Orb Crates", player, multiworld, level_name, 8) + frozen_box_cave_crates.add_cell_locations([67], access_rule=lambda state: + state.has("Yellow Eco Switch", player)) + + # Include 6 orbs on the twin elevator ice ramp. + ice_skating_rink = JakAndDaxterRegion("Ice Skating Rink", player, multiworld, level_name, 20) + ice_skating_rink.add_fly_locations([131137], access_rule=lambda state: can_free_scout_flies(state, player)) + + flut_flut_course = JakAndDaxterRegion("Flut Flut Course", player, multiworld, level_name, 15) + flut_flut_course.add_cell_locations([63], access_rule=lambda state: state.has("Flut Flut", player)) + flut_flut_course.add_special_locations([63], access_rule=lambda state: state.has("Flut Flut", player)) + + # Includes the bridge from snowball_canyon, the area beneath that bridge, and the areas around the fort. + fort_exterior = JakAndDaxterRegion("Fort Exterior", player, multiworld, level_name, 20) + fort_exterior.add_fly_locations([65601, 393281], access_rule=lambda state: + can_free_scout_flies(state, player)) + + # Includes the icy island and bridge outside the cave entrance. + bunny_cave_start = JakAndDaxterRegion("Bunny Cave (Start)", player, multiworld, level_name, 10) + + # Includes the cell and 3 orbs at the exit. + bunny_cave_end = JakAndDaxterRegion("Bunny Cave (End)", player, multiworld, level_name, 3) + bunny_cave_end.add_cell_locations([64]) + + switch_cave = JakAndDaxterRegion("Yellow Eco Switch Cave", player, multiworld, level_name, 4) + switch_cave.add_cell_locations([60]) + switch_cave.add_special_locations([60]) + + # Only what can be covered by single jump. + fort_interior = JakAndDaxterRegion("Fort Interior (Main)", player, multiworld, level_name, 19) + + # Reaching the top of the watch tower, getting the fly with the blue eco, and falling down to get the caches. + fort_interior_caches = JakAndDaxterRegion("Fort Interior (Caches)", player, multiworld, level_name, 51) + fort_interior_caches.add_fly_locations([196673]) + fort_interior_caches.add_cache_locations([23348, 23349, 23350]) + + # Need higher jump. + fort_interior_base = JakAndDaxterRegion("Fort Interior (Base)", player, multiworld, level_name, 0) + fort_interior_base.add_fly_locations([262209], access_rule=lambda state: + can_free_scout_flies(state, player)) + + # Need farther jump. + fort_interior_course_end = JakAndDaxterRegion("Fort Interior (Course End)", player, multiworld, level_name, 2) + fort_interior_course_end.add_cell_locations([62]) + + # Wire up the virtual regions first. + main_area.connect(blockers, rule=lambda state: can_jump_blockers(state, player)) + main_area.connect(glacier_lurkers, rule=lambda state: can_fight(state, player)) + + # Yes, the only way into the rest of the level requires advanced movement. + main_area.connect(snowball_canyon, rule=lambda state: can_cross_long_gap(state, player)) + + snowball_canyon.connect(main_area) # But you can just jump down and run up the ramp. + snowball_canyon.connect(bunny_cave_start) # Jump down from the glacier troop cliff. + snowball_canyon.connect(fort_exterior) # Jump down, to the left of frozen box cave. + snowball_canyon.connect(frozen_box_cave, rule=lambda state: # More advanced movement. + can_cross_long_gap(state, player)) + + frozen_box_cave.connect(snowball_canyon, rule=lambda state: # Same movement to go back. + can_cross_long_gap(state, player)) + frozen_box_cave.connect(frozen_box_cave_crates, rule=lambda state: # YES to get these crates. + state.has("Yellow Eco Switch", player)) + frozen_box_cave.connect(ice_skating_rink, rule=lambda state: # Same movement to go forward. + can_cross_long_gap(state, player)) + + frozen_box_cave_crates.connect(frozen_box_cave) # Semi-virtual region, no moves req'd. + + ice_skating_rink.connect(frozen_box_cave, rule=lambda state: # Same movement to go back. + can_cross_long_gap(state, player)) + ice_skating_rink.connect(flut_flut_course, rule=lambda state: # Duh. + state.has("Flut Flut", player)) + ice_skating_rink.connect(fort_exterior) # Just slide down the elevator ramp. + + fort_exterior.connect(ice_skating_rink, rule=lambda state: # Twin elevators OR scout fly ledge. + can_cross_long_gap(state, player)) # Both doable with main_gap logic. + fort_exterior.connect(snowball_canyon) # Run across bridge. + fort_exterior.connect(fort_interior, rule=lambda state: # Duh. + state.has("Snowy Fort Gate", player)) + fort_exterior.connect(bunny_cave_start) # Run across bridge. + fort_exterior.connect(switch_cave, rule=lambda state: # Yes, blocker jumps work here. + can_jump_blockers(state, player)) + + fort_interior.connect(fort_interior_caches, rule=lambda state: # Just need a little height. + state.has("Double Jump", player) + or state.has_all(("Crouch", "Crouch Jump"), player)) + fort_interior.connect(fort_interior_base, rule=lambda state: # Just need a little height. + state.has("Double Jump", player) + or state.has_all(("Crouch", "Crouch Jump"), player)) + fort_interior.connect(fort_interior_course_end, rule=lambda state: # Just need a little distance. + state.has_any(("Double Jump", "Jump Kick"), player) + or state.has_all(("Punch", "Punch Uppercut"), player)) + + flut_flut_course.connect(fort_exterior) # Ride the elevator. + + # Must fight way through cave, but there is also a grab-less ledge we must jump over. + bunny_cave_start.connect(bunny_cave_end, rule=lambda state: + can_fight(state, player) + and (state.has("Double Jump", player) + or state.has_all(("Crouch", "Crouch Jump"), player))) + + # All jump down. + fort_interior_caches.connect(fort_interior) + fort_interior_base.connect(fort_interior) + fort_interior_course_end.connect(fort_interior) + switch_cave.connect(fort_exterior) + bunny_cave_end.connect(fort_exterior) + + # I really hope that is everything. + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(glacier_lurkers) + world.level_to_regions[level_name].append(blockers) + world.level_to_regions[level_name].append(snowball_canyon) + world.level_to_regions[level_name].append(frozen_box_cave) + world.level_to_regions[level_name].append(frozen_box_cave_crates) + world.level_to_regions[level_name].append(ice_skating_rink) + world.level_to_regions[level_name].append(flut_flut_course) + world.level_to_regions[level_name].append(fort_exterior) + world.level_to_regions[level_name].append(bunny_cave_start) + world.level_to_regions[level_name].append(bunny_cave_end) + world.level_to_regions[level_name].append(switch_cave) + world.level_to_regions[level_name].append(fort_interior) + world.level_to_regions[level_name].append(fort_interior_caches) + world.level_to_regions[level_name].append(fort_interior_base) + world.level_to_regions[level_name].append(fort_interior_course_end) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 200 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(12, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/spider_cave_regions.py b/worlds/jakanddaxter/regs/spider_cave_regions.py new file mode 100644 index 000000000000..6069bbb80c2b --- /dev/null +++ b/worlds/jakanddaxter/regs/spider_cave_regions.py @@ -0,0 +1,127 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_free_scout_flies, can_fight, can_reach_orbs_level + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + # A large amount of this area can be covered by single jump, floating platforms, web trampolines, and goggles. + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 63) + main_area.add_cell_locations([78, 84]) + main_area.add_fly_locations([327765, 393301, 196693, 131157]) + + # This is a virtual region describing what you need to DO to get the Dark Crystal power cell, + # rather than describing where each of the crystals ARE, because you can destroy them in any order, + # and you need to destroy ALL of them to get the cell. + dark_crystals = JakAndDaxterRegion("Dark Crystals", player, multiworld, level_name, 0) + + # can_fight = The underwater crystal in dark cave. + # Roll Jump = The underwater crystal across a long dark eco pool. + # The rest of the crystals can be destroyed with yellow eco in main_area. + dark_crystals.add_cell_locations([79], access_rule=lambda state: + can_fight(state, player) + and state.has_all(("Roll", "Roll Jump"), player)) + + dark_cave = JakAndDaxterRegion("Dark Cave", player, multiworld, level_name, 5) + dark_cave.add_cell_locations([80]) + dark_cave.add_fly_locations([262229], access_rule=lambda state: can_free_scout_flies(state, player)) + + robot_cave = JakAndDaxterRegion("Robot Cave", player, multiworld, level_name, 0) + + # Need double jump for orbs. + scaffolding_level_zero = JakAndDaxterRegion("Robot Scaffolding Level 0", player, multiworld, level_name, 12) + + scaffolding_level_one = JakAndDaxterRegion("Robot Scaffolding Level 1", player, multiworld, level_name, 53) + scaffolding_level_one.add_fly_locations([85]) # Shootable. + + scaffolding_level_two = JakAndDaxterRegion("Robot Scaffolding Level 2", player, multiworld, level_name, 4) + + # Using the blue eco from the pole course, you can single jump to the scout fly up here. + scaffolding_level_three = JakAndDaxterRegion("Robot Scaffolding Level 3", player, multiworld, level_name, 29) + scaffolding_level_three.add_cell_locations([81]) + scaffolding_level_three.add_fly_locations([65621]) + + pole_course = JakAndDaxterRegion("Pole Course", player, multiworld, level_name, 18) + pole_course.add_cell_locations([82]) + + # You only need combat to fight through the spiders, but to collect the orb crates, + # you will need the yellow eco vent unlocked. + spider_tunnel = JakAndDaxterRegion("Spider Tunnel", player, multiworld, level_name, 4) + spider_tunnel.add_cell_locations([83]) + + spider_tunnel_crates = JakAndDaxterRegion("Spider Tunnel Orb Crates", player, multiworld, level_name, 12) + + main_area.connect(dark_crystals) + main_area.connect(robot_cave) + main_area.connect(dark_cave, rule=lambda state: + can_fight(state, player) + and (state.has("Double Jump", player) + or state.has_all(("Crouch", "Crouch Jump"), player))) + + robot_cave.connect(main_area) + robot_cave.connect(pole_course) # Nothing special required. + robot_cave.connect(scaffolding_level_one) # Ramps lead to level 1. + robot_cave.connect(spider_tunnel) # Web trampolines (bounce twice on each to gain momentum). + + pole_course.connect(robot_cave) # Blue eco platform down. + + scaffolding_level_one.connect(robot_cave) # All scaffolding (level 1+) connects back by jumping down. + + # Elevator, but the orbs need double jump or jump kick. + scaffolding_level_one.connect(scaffolding_level_zero, rule=lambda state: + state.has_any(("Double Jump", "Jump Kick"), player)) + + # Narrow enough that enemies are unavoidable. + scaffolding_level_one.connect(scaffolding_level_two, rule=lambda state: can_fight(state, player)) + + scaffolding_level_zero.connect(scaffolding_level_one) # Elevator. + + scaffolding_level_two.connect(robot_cave) # Jump down. + scaffolding_level_two.connect(scaffolding_level_one) # Elevator. + + # Elevator, but narrow enough that enemies are unavoidable. + scaffolding_level_two.connect(scaffolding_level_three, rule=lambda state: can_fight(state, player)) + + scaffolding_level_three.connect(robot_cave) # Jump down. + scaffolding_level_three.connect(scaffolding_level_two) # Elevator. + + spider_tunnel.connect(robot_cave) # Back to web trampolines. + spider_tunnel.connect(main_area) # Escape with jump pad. + + # Requires yellow eco switch. + spider_tunnel.connect(spider_tunnel_crates, rule=lambda state: state.has("Yellow Eco Switch", player)) + + world.level_to_regions[level_name].append(main_area) + world.level_to_regions[level_name].append(dark_crystals) + world.level_to_regions[level_name].append(dark_cave) + world.level_to_regions[level_name].append(robot_cave) + world.level_to_regions[level_name].append(scaffolding_level_zero) + world.level_to_regions[level_name].append(scaffolding_level_one) + world.level_to_regions[level_name].append(scaffolding_level_two) + world.level_to_regions[level_name].append(scaffolding_level_three) + world.level_to_regions[level_name].append(pole_course) + world.level_to_regions[level_name].append(spider_tunnel) + world.level_to_regions[level_name].append(spider_tunnel_crates) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 200 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(13, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/regs/volcanic_crater_regions.py b/worlds/jakanddaxter/regs/volcanic_crater_regions.py new file mode 100644 index 000000000000..47bfccfd2b7d --- /dev/null +++ b/worlds/jakanddaxter/regs/volcanic_crater_regions.py @@ -0,0 +1,52 @@ +from .region_base import JakAndDaxterRegion +from ..options import EnableOrbsanity +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .. import JakAndDaxterWorld +from ..rules import can_free_scout_flies, can_reach_orbs_level +from ..locs import scout_locations as scouts + + +def build_regions(level_name: str, world: "JakAndDaxterWorld") -> JakAndDaxterRegion: + multiworld = world.multiworld + options = world.options + player = world.player + + # No area is inaccessible in VC even with only running and jumping. + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 50) + main_area.add_cell_locations([96], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, None)) + main_area.add_cell_locations([97], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, 96)) + main_area.add_cell_locations([98], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, 97)) + main_area.add_cell_locations([99], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, 98)) + main_area.add_cell_locations([100], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, None)) + main_area.add_cell_locations([101], access_rule=lambda state: world.can_trade(state, world.total_trade_orbs, 100)) + + # Hidden Power Cell: you can carry yellow eco from Spider Cave just by running and jumping + # and using your Goggles to shoot the box (you do not need Punch to shoot from FP mode). + main_area.add_cell_locations([74]) + + # No blue eco sources in this area, all boxes must be broken by hand (yellow eco can't be carried far enough). + main_area.add_fly_locations(scouts.locVC_scoutTable.keys(), access_rule=lambda state: + can_free_scout_flies(state, player)) + + # Approach the gondola to get this check. + main_area.add_special_locations([105]) + + world.level_to_regions[level_name].append(main_area) + + # If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always + # accessible to Main Area. The Locations within are automatically checked when you collect enough orbs. + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + orbs = JakAndDaxterRegion("Orbsanity", player, multiworld, level_name) + + bundle_count = 50 // world.orb_bundle_size + for bundle_index in range(bundle_count): + amount = world.orb_bundle_size * (bundle_index + 1) + orbs.add_orb_locations(11, + bundle_index, + access_rule=lambda state, level=level_name, orb_amount=amount: + can_reach_orbs_level(state, player, world, level, orb_amount)) + multiworld.regions.append(orbs) + main_area.connect(orbs) + + return main_area diff --git a/worlds/jakanddaxter/requirements.txt b/worlds/jakanddaxter/requirements.txt new file mode 100644 index 000000000000..ca36764fbfaa --- /dev/null +++ b/worlds/jakanddaxter/requirements.txt @@ -0,0 +1 @@ +Pymem>=1.13.0 diff --git a/worlds/jakanddaxter/rules.py b/worlds/jakanddaxter/rules.py new file mode 100644 index 000000000000..71b94df885c8 --- /dev/null +++ b/worlds/jakanddaxter/rules.py @@ -0,0 +1,230 @@ +import typing +from BaseClasses import CollectionState +from Options import OptionError +from .options import (EnableOrbsanity, + GlobalOrbsanityBundleSize, + PerLevelOrbsanityBundleSize, + FireCanyonCellCount, + MountainPassCellCount, + LavaTubeCellCount, + CitizenOrbTradeAmount, + OracleOrbTradeAmount) +from .locs import cell_locations as cells +from .locations import location_table +from .levels import level_table + +if typing.TYPE_CHECKING: + from . import JakAndDaxterWorld + + +def set_orb_trade_rule(world: "JakAndDaxterWorld"): + options = world.options + player = world.player + + if options.enable_orbsanity == EnableOrbsanity.option_off: + world.can_trade = lambda state, required_orbs, required_previous_trade: ( + can_trade_vanilla(state, player, world, required_orbs, required_previous_trade)) + else: + world.can_trade = lambda state, required_orbs, required_previous_trade: ( + can_trade_orbsanity(state, player, world, required_orbs, required_previous_trade)) + + +def recalculate_reachable_orbs(state: CollectionState, player: int, world: "JakAndDaxterWorld") -> None: + + # Recalculate every level, every time the cache is stale, because you don't know + # when a specific bundle of orbs in one level may unlock access to another. + accessible_total_orbs = 0 + for level in level_table: + accessible_level_orbs = count_reachable_orbs_level(state, world, level) + accessible_total_orbs += accessible_level_orbs + state.prog_items[player][f"{level} Reachable Orbs".lstrip()] = accessible_level_orbs + + # Also recalculate the global count, still used even when Orbsanity is Off. + state.prog_items[player]["Reachable Orbs"] = accessible_total_orbs + state.prog_items[player]["Reachable Orbs Fresh"] = True + + +def count_reachable_orbs_global(state: CollectionState, + world: "JakAndDaxterWorld") -> int: + + accessible_orbs = 0 + for level_regions in world.level_to_orb_regions.values(): + for region in level_regions: + if region.can_reach(state): + accessible_orbs += region.orb_count + return accessible_orbs + + +def count_reachable_orbs_level(state: CollectionState, + world: "JakAndDaxterWorld", + level_name: str = "") -> int: + + accessible_orbs = 0 + for region in world.level_to_orb_regions[level_name]: + if region.can_reach(state): + accessible_orbs += region.orb_count + return accessible_orbs + + +def can_reach_orbs_global(state: CollectionState, + player: int, + world: "JakAndDaxterWorld", + orb_amount: int) -> bool: + + if not state.prog_items[player]["Reachable Orbs Fresh"]: + recalculate_reachable_orbs(state, player, world) + + return state.has("Reachable Orbs", player, orb_amount) + + +def can_reach_orbs_level(state: CollectionState, + player: int, + world: "JakAndDaxterWorld", + level_name: str, + orb_amount: int) -> bool: + + if not state.prog_items[player]["Reachable Orbs Fresh"]: + recalculate_reachable_orbs(state, player, world) + + return state.has(f"{level_name} Reachable Orbs", player, orb_amount) + + +def can_trade_vanilla(state: CollectionState, + player: int, + world: "JakAndDaxterWorld", + required_orbs: int, + required_previous_trade: typing.Optional[int] = None) -> bool: + + # With Orbsanity Off, Reachable Orbs are in fact Tradeable Orbs. + if not state.prog_items[player]["Reachable Orbs Fresh"]: + recalculate_reachable_orbs(state, player, world) + + if required_previous_trade: + name_of_previous_trade = location_table[cells.to_ap_id(required_previous_trade)] + return (state.has("Reachable Orbs", player, required_orbs) + and state.can_reach_location(name_of_previous_trade, player=player)) + return state.has("Reachable Orbs", player, required_orbs) + + +def can_trade_orbsanity(state: CollectionState, + player: int, + world: "JakAndDaxterWorld", + required_orbs: int, + required_previous_trade: typing.Optional[int] = None) -> bool: + + # Yes, even Orbsanity trades may unlock access to new Reachable Orbs. + if not state.prog_items[player]["Reachable Orbs Fresh"]: + recalculate_reachable_orbs(state, player, world) + + if required_previous_trade: + name_of_previous_trade = location_table[cells.to_ap_id(required_previous_trade)] + return (state.has("Tradeable Orbs", player, required_orbs) + and state.can_reach_location(name_of_previous_trade, player=player)) + return state.has("Tradeable Orbs", player, required_orbs) + + +def can_free_scout_flies(state: CollectionState, player: int) -> bool: + return state.has("Jump Dive", player) or state.has_all({"Crouch", "Crouch Uppercut"}, player) + + +def can_fight(state: CollectionState, player: int) -> bool: + return state.has_any(("Jump Dive", "Jump Kick", "Punch", "Kick"), player) + + +def enforce_multiplayer_limits(world: "JakAndDaxterWorld"): + options = world.options + friendly_message = "" + + if (options.enable_orbsanity == EnableOrbsanity.option_global + and (options.global_orbsanity_bundle_size.value < GlobalOrbsanityBundleSize.friendly_minimum + or options.global_orbsanity_bundle_size.value > GlobalOrbsanityBundleSize.friendly_maximum)): + friendly_message += (f" " + f"{options.global_orbsanity_bundle_size.display_name} must be no less than " + f"{GlobalOrbsanityBundleSize.friendly_minimum} and no greater than " + f"{GlobalOrbsanityBundleSize.friendly_maximum} (currently " + f"{options.global_orbsanity_bundle_size.value}).\n") + + if (options.enable_orbsanity == EnableOrbsanity.option_per_level + and options.level_orbsanity_bundle_size.value < PerLevelOrbsanityBundleSize.friendly_minimum): + friendly_message += (f" " + f"{options.level_orbsanity_bundle_size.display_name} must be no less than " + f"{PerLevelOrbsanityBundleSize.friendly_minimum} (currently " + f"{options.level_orbsanity_bundle_size.value}).\n") + + if options.fire_canyon_cell_count.value > FireCanyonCellCount.friendly_maximum: + friendly_message += (f" " + f"{options.fire_canyon_cell_count.display_name} must be no greater than " + f"{FireCanyonCellCount.friendly_maximum} (currently " + f"{options.fire_canyon_cell_count.value}).\n") + + if options.mountain_pass_cell_count.value > MountainPassCellCount.friendly_maximum: + friendly_message += (f" " + f"{options.mountain_pass_cell_count.display_name} must be no greater than " + f"{MountainPassCellCount.friendly_maximum} (currently " + f"{options.mountain_pass_cell_count.value}).\n") + + if options.lava_tube_cell_count.value > LavaTubeCellCount.friendly_maximum: + friendly_message += (f" " + f"{options.lava_tube_cell_count.display_name} must be no greater than " + f"{LavaTubeCellCount.friendly_maximum} (currently " + f"{options.lava_tube_cell_count.value}).\n") + + if options.citizen_orb_trade_amount.value > CitizenOrbTradeAmount.friendly_maximum: + friendly_message += (f" " + f"{options.citizen_orb_trade_amount.display_name} must be no greater than " + f"{CitizenOrbTradeAmount.friendly_maximum} (currently " + f"{options.citizen_orb_trade_amount.value}).\n") + + if options.oracle_orb_trade_amount.value > OracleOrbTradeAmount.friendly_maximum: + friendly_message += (f" " + f"{options.oracle_orb_trade_amount.display_name} must be no greater than " + f"{OracleOrbTradeAmount.friendly_maximum} (currently " + f"{options.oracle_orb_trade_amount.value}).\n") + + if friendly_message != "": + raise OptionError(f"{world.player_name}: The options you have chosen may disrupt the multiworld. \n" + f"Please adjust the following Options for a multiplayer game. \n" + f"{friendly_message}" + f"Or use 'random-range-x-y' instead of 'random' in your player yaml.\n" + f"Or set 'enforce_friendly_options' in the seed generator's host.yaml to false. " + f"(Use at your own risk!)") + + +def enforce_singleplayer_limits(world: "JakAndDaxterWorld"): + options = world.options + friendly_message = "" + + if options.fire_canyon_cell_count.value > FireCanyonCellCount.friendly_maximum: + friendly_message += (f" " + f"{options.fire_canyon_cell_count.display_name} must be no greater than " + f"{FireCanyonCellCount.friendly_maximum} (currently " + f"{options.fire_canyon_cell_count.value}).\n") + + if options.mountain_pass_cell_count.value > MountainPassCellCount.friendly_maximum: + friendly_message += (f" " + f"{options.mountain_pass_cell_count.display_name} must be no greater than " + f"{MountainPassCellCount.friendly_maximum} (currently " + f"{options.mountain_pass_cell_count.value}).\n") + + if options.lava_tube_cell_count.value > LavaTubeCellCount.friendly_maximum: + friendly_message += (f" " + f"{options.lava_tube_cell_count.display_name} must be no greater than " + f"{LavaTubeCellCount.friendly_maximum} (currently " + f"{options.lava_tube_cell_count.value}).\n") + + if friendly_message != "": + raise OptionError(f"The options you have chosen may result in seed generation failures. \n" + f"Please adjust the following Options for a singleplayer game. \n" + f"{friendly_message}" + f"Or use 'random-range-x-y' instead of 'random' in your player yaml.\n" + f"Or set 'enforce_friendly_options' in your host.yaml to false. " + f"(Use at your own risk!)") + + +def verify_orb_trade_amounts(world: "JakAndDaxterWorld"): + + if world.total_trade_orbs > 2000: + raise OptionError(f"{world.player_name}: Required number of orbs for all trades ({world.total_trade_orbs}) " + f"is more than all the orbs in the game (2000). Reduce the value of either " + f"{world.options.citizen_orb_trade_amount.display_name} " + f"or {world.options.oracle_orb_trade_amount.display_name}.") diff --git a/worlds/jakanddaxter/test/__init__.py b/worlds/jakanddaxter/test/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/worlds/jakanddaxter/test/bases.py b/worlds/jakanddaxter/test/bases.py new file mode 100644 index 000000000000..73d18b80bf3c --- /dev/null +++ b/worlds/jakanddaxter/test/bases.py @@ -0,0 +1,107 @@ +from worlds.jakanddaxter import JakAndDaxterWorld +from ..game_id import jak1_name +from test.bases import WorldTestBase + + +class JakAndDaxterTestBase(WorldTestBase): + game = jak1_name + world: JakAndDaxterWorld + + level_info = { + "Geyser Rock": { + "cells": 4, + "flies": 7, + "orbs": 50, + "caches": 0, + }, + "Sandover Village": { + "cells": 6, + "flies": 7, + "orbs": 50, + "caches": 1, + }, + "Forbidden Jungle": { + "cells": 8, + "flies": 7, + "orbs": 150, + "caches": 1, + }, + "Sentinel Beach": { + "cells": 8, + "flies": 7, + "orbs": 150, + "caches": 2, + }, + "Misty Island": { + "cells": 8, + "flies": 7, + "orbs": 150, + "caches": 1, + }, + "Fire Canyon": { + "cells": 2, + "flies": 7, + "orbs": 50, + "caches": 0, + }, + "Rock Village": { + "cells": 6, + "flies": 7, + "orbs": 50, + "caches": 1, + }, + "Precursor Basin": { + "cells": 8, + "flies": 7, + "orbs": 200, + "caches": 0, + }, + "Lost Precursor City": { + "cells": 8, + "flies": 7, + "orbs": 200, + "caches": 2, + }, + "Boggy Swamp": { + "cells": 8, + "flies": 7, + "orbs": 200, + "caches": 0, + }, + "Mountain Pass": { + "cells": 4, + "flies": 7, + "orbs": 50, + "caches": 0, + }, + "Volcanic Crater": { + "cells": 8, + "flies": 7, + "orbs": 50, + "caches": 0, + }, + "Spider Cave": { + "cells": 8, + "flies": 7, + "orbs": 200, + "caches": 0, + }, + "Snowy Mountain": { + "cells": 8, + "flies": 7, + "orbs": 200, + "caches": 3, + }, + "Lava Tube": { + "cells": 2, + "flies": 7, + "orbs": 50, + "caches": 0, + }, + "Gol and Maia's Citadel": { + "cells": 5, + "flies": 7, + "orbs": 200, + "caches": 3, + }, + } diff --git a/worlds/jakanddaxter/test/test_locations.py b/worlds/jakanddaxter/test/test_locations.py new file mode 100644 index 000000000000..1d47066b9314 --- /dev/null +++ b/worlds/jakanddaxter/test/test_locations.py @@ -0,0 +1,52 @@ +import typing + +from .bases import JakAndDaxterTestBase +from ..game_id import jak1_id +from ..regs.region_base import JakAndDaxterRegion +from ..locs import (scout_locations as scouts, + special_locations as specials, + orb_cache_locations as caches, + orb_locations as orbs) + + +class LocationsTest(JakAndDaxterTestBase): + + def get_regions(self): + return [typing.cast(JakAndDaxterRegion, reg) for reg in self.multiworld.get_regions(self.player)] + + def test_count_cells(self): + + for level in self.level_info: + cell_count = 0 + sublevels = [reg for reg in self.get_regions() if reg.level_name == level] + for sl in sublevels: + for loc in sl.locations: + if loc.address in range(jak1_id, jak1_id + scouts.fly_offset): + cell_count += 1 + self.assertEqual(self.level_info[level]["cells"] - 1, cell_count, level) # Don't count the Free 7 Cells. + + def test_count_flies(self): + for level in self.level_info: + fly_count = 0 + sublevels = [reg for reg in self.get_regions() if reg.level_name == level] + for sl in sublevels: + for loc in sl.locations: + if loc.address in range(jak1_id + scouts.fly_offset, jak1_id + specials.special_offset): + fly_count += 1 + self.assertEqual(self.level_info[level]["flies"], fly_count, level) + + def test_count_orbs(self): + for level in self.level_info: + sublevels = [reg for reg in self.get_regions() if reg.level_name == level] + orb_count = sum([reg.orb_count for reg in sublevels]) + self.assertEqual(self.level_info[level]["orbs"], orb_count, level) + + def test_count_caches(self): + for level in self.level_info: + cache_count = 0 + sublevels = [reg for reg in self.get_regions() if reg.level_name == level] + for sl in sublevels: + for loc in sl.locations: + if loc.address in range(jak1_id + caches.orb_cache_offset, jak1_id + orbs.orb_offset): + cache_count += 1 + self.assertEqual(self.level_info[level]["caches"], cache_count, level) diff --git a/worlds/jakanddaxter/test/test_moverando.py b/worlds/jakanddaxter/test/test_moverando.py new file mode 100644 index 000000000000..d912d43af810 --- /dev/null +++ b/worlds/jakanddaxter/test/test_moverando.py @@ -0,0 +1,32 @@ +from .bases import JakAndDaxterTestBase +from ..items import move_item_table + + +class MoveRandoTest(JakAndDaxterTestBase): + options = { + "enable_move_randomizer": True + } + + def test_move_items_in_pool(self): + for move in move_item_table: + self.assertIn(move_item_table[move], {item.name for item in self.multiworld.itempool}) + self.assertNotIn(move_item_table[move], + {item.name for item in self.multiworld.precollected_items[self.player]}) + + def test_cannot_reach_without_move(self): + self.assertAccessDependency( + ["GR: Climb Up The Cliff"], + [["Double Jump"], ["Crouch"]], + only_check_listed=True) + + +class NoMoveRandoTest(JakAndDaxterTestBase): + options = { + "enable_move_randomizer": False + } + + def test_move_items_in_inventory(self): + for move in move_item_table: + self.assertNotIn(move_item_table[move], {item.name for item in self.multiworld.itempool}) + self.assertIn(move_item_table[move], + {item.name for item in self.multiworld.precollected_items[self.player]}) diff --git a/worlds/jakanddaxter/test/test_orbsanity.py b/worlds/jakanddaxter/test/test_orbsanity.py new file mode 100644 index 000000000000..5f871c855247 --- /dev/null +++ b/worlds/jakanddaxter/test/test_orbsanity.py @@ -0,0 +1,61 @@ +from .bases import JakAndDaxterTestBase +from ..items import orb_item_table + + +class NoOrbsanityTest(JakAndDaxterTestBase): + options = { + "enable_orbsanity": 0, # Off + "level_orbsanity_bundle_size": 25, + "global_orbsanity_bundle_size": 16 + } + + def test_orb_bundles_not_exist_in_pool(self): + for bundle in orb_item_table: + self.assertNotIn(orb_item_table[bundle], {item.name for item in self.multiworld.itempool}) + + def test_orb_bundle_count(self): + bundle_name = orb_item_table[self.options["level_orbsanity_bundle_size"]] + count = len([item.name for item in self.multiworld.itempool if item.name == bundle_name]) + self.assertEqual(0, count) + + bundle_name = orb_item_table[self.options["global_orbsanity_bundle_size"]] + count = len([item.name for item in self.multiworld.itempool if item.name == bundle_name]) + self.assertEqual(0, count) + + +class PerLevelOrbsanityTest(JakAndDaxterTestBase): + options = { + "enable_orbsanity": 1, # Per Level + "level_orbsanity_bundle_size": 25 + } + + def test_orb_bundles_exist_in_pool(self): + for bundle in orb_item_table: + if bundle == self.options["level_orbsanity_bundle_size"]: + self.assertIn(orb_item_table[bundle], {item.name for item in self.multiworld.itempool}) + else: + self.assertNotIn(orb_item_table[bundle], {item.name for item in self.multiworld.itempool}) + + def test_orb_bundle_count(self): + bundle_name = orb_item_table[self.options["level_orbsanity_bundle_size"]] + count = len([item.name for item in self.multiworld.itempool if item.name == bundle_name]) + self.assertEqual(80, count) + + +class GlobalOrbsanityTest(JakAndDaxterTestBase): + options = { + "enable_orbsanity": 2, # Global + "global_orbsanity_bundle_size": 16 + } + + def test_orb_bundles_exist_in_pool(self): + for bundle in orb_item_table: + if bundle == self.options["global_orbsanity_bundle_size"]: + self.assertIn(orb_item_table[bundle], {item.name for item in self.multiworld.itempool}) + else: + self.assertNotIn(orb_item_table[bundle], {item.name for item in self.multiworld.itempool}) + + def test_orb_bundle_count(self): + bundle_name = orb_item_table[self.options["global_orbsanity_bundle_size"]] + count = len([item.name for item in self.multiworld.itempool if item.name == bundle_name]) + self.assertEqual(125, count) diff --git a/worlds/jakanddaxter/test/test_orderedcellcounts.py b/worlds/jakanddaxter/test/test_orderedcellcounts.py new file mode 100644 index 000000000000..7ad0d76ca50a --- /dev/null +++ b/worlds/jakanddaxter/test/test_orderedcellcounts.py @@ -0,0 +1,29 @@ +from .bases import JakAndDaxterTestBase + + +class ReorderedCellCountsTest(JakAndDaxterTestBase): + options = { + "enable_ordered_cell_counts": True, + "fire_canyon_cell_count": 20, + "mountain_pass_cell_count": 15, + "lava_tube_cell_count": 10, + } + + def test_reordered_cell_counts(self): + self.world.generate_early() + self.assertLessEqual(self.world.options.fire_canyon_cell_count, self.world.options.mountain_pass_cell_count) + self.assertLessEqual(self.world.options.mountain_pass_cell_count, self.world.options.lava_tube_cell_count) + + +class UnorderedCellCountsTest(JakAndDaxterTestBase): + options = { + "enable_ordered_cell_counts": False, + "fire_canyon_cell_count": 20, + "mountain_pass_cell_count": 15, + "lava_tube_cell_count": 10, + } + + def test_unordered_cell_counts(self): + self.world.generate_early() + self.assertGreaterEqual(self.world.options.fire_canyon_cell_count, self.world.options.mountain_pass_cell_count) + self.assertGreaterEqual(self.world.options.mountain_pass_cell_count, self.world.options.lava_tube_cell_count) diff --git a/worlds/jakanddaxter/test/test_trades.py b/worlds/jakanddaxter/test/test_trades.py new file mode 100644 index 000000000000..e1d1a2e53dec --- /dev/null +++ b/worlds/jakanddaxter/test/test_trades.py @@ -0,0 +1,39 @@ +from .bases import JakAndDaxterTestBase + + +class TradesCostNothingTest(JakAndDaxterTestBase): + options = { + "enable_orbsanity": 2, + "global_orbsanity_bundle_size": 5, + "citizen_orb_trade_amount": 0, + "oracle_orb_trade_amount": 0 + } + + def test_orb_items_are_filler(self): + self.collect_all_but("") + self.assertNotIn("5 Precursor Orbs", self.multiworld.state.prog_items) + + def test_trades_are_accessible(self): + self.assertTrue(self.multiworld + .get_location("SV: Bring 90 Orbs To The Mayor", self.player) + .can_reach(self.multiworld.state)) + + +class TradesCostEverythingTest(JakAndDaxterTestBase): + options = { + "enable_orbsanity": 2, + "global_orbsanity_bundle_size": 5, + "citizen_orb_trade_amount": 120, + "oracle_orb_trade_amount": 150 + } + + def test_orb_items_are_progression(self): + self.collect_all_but("") + self.assertIn("5 Precursor Orbs", self.multiworld.state.prog_items[self.player]) + self.assertEqual(396, self.multiworld.state.prog_items[self.player]["5 Precursor Orbs"]) + + def test_trades_are_accessible(self): + self.collect_all_but("") + self.assertTrue(self.multiworld + .get_location("SV: Bring 90 Orbs To The Mayor", self.player) + .can_reach(self.multiworld.state)) diff --git a/worlds/jakanddaxter/test/test_traps.py b/worlds/jakanddaxter/test/test_traps.py new file mode 100644 index 000000000000..841997798bf8 --- /dev/null +++ b/worlds/jakanddaxter/test/test_traps.py @@ -0,0 +1,80 @@ +from BaseClasses import ItemClassification +from .bases import JakAndDaxterTestBase + + +class NoTrapsTest(JakAndDaxterTestBase): + options = { + "filler_power_cells_replaced_with_traps": 0, + "filler_orb_bundles_replaced_with_traps": 0, + "trap_weights": {"Trip Trap": 1}, + } + + def test_trap_count(self): + count = len([item.name for item in self.multiworld.itempool + if item.name == "Trip Trap" + and item.classification == ItemClassification.trap]) + self.assertEqual(0, count) + + def test_prog_power_cells_count(self): + count = len([item.name for item in self.multiworld.itempool + if item.name == "Power Cell" + and item.classification == ItemClassification.progression_skip_balancing]) + self.assertEqual(72, count) + + def test_fill_power_cells_count(self): + count = len([item.name for item in self.multiworld.itempool + if item.name == "Power Cell" + and item.classification == ItemClassification.filler]) + self.assertEqual(29, count) + + +class SomeTrapsTest(JakAndDaxterTestBase): + options = { + "filler_power_cells_replaced_with_traps": 10, + "filler_orb_bundles_replaced_with_traps": 10, + "trap_weights": {"Trip Trap": 1}, + } + + def test_trap_count(self): + count = len([item.name for item in self.multiworld.itempool + if item.name == "Trip Trap" + and item.classification == ItemClassification.trap]) + self.assertEqual(10, count) + + def test_prog_power_cells_count(self): + count = len([item.name for item in self.multiworld.itempool + if item.name == "Power Cell" + and item.classification == ItemClassification.progression_skip_balancing]) + self.assertEqual(72, count) + + def test_fill_power_cells_count(self): + count = len([item.name for item in self.multiworld.itempool + if item.name == "Power Cell" + and item.classification == ItemClassification.filler]) + self.assertEqual(19, count) + + +class MaximumTrapsTest(JakAndDaxterTestBase): + options = { + "filler_power_cells_replaced_with_traps": 100, + "filler_orb_bundles_replaced_with_traps": 100, + "trap_weights": {"Trip Trap": 1}, + } + + def test_trap_count(self): + count = len([item.name for item in self.multiworld.itempool + if item.name == "Trip Trap" + and item.classification == ItemClassification.trap]) + self.assertEqual(29, count) + + def test_prog_power_cells_count(self): + count = len([item.name for item in self.multiworld.itempool + if item.name == "Power Cell" + and item.classification == ItemClassification.progression_skip_balancing]) + self.assertEqual(72, count) + + def test_fill_power_cells_count(self): + count = len([item.name for item in self.multiworld.itempool + if item.name == "Power Cell" + and item.classification == ItemClassification.filler]) + self.assertEqual(0, count) From d5bacaba639a9fc14a8148ea005112a76c700b56 Mon Sep 17 00:00:00 2001 From: BlastSlimey <89539656+BlastSlimey@users.noreply.github.com> Date: Wed, 21 May 2025 14:30:39 +0200 Subject: [PATCH 0436/1218] shapez: Implement New Game (#3960) Adds shapez as a supported game in AP. --- worlds/shapez/__init__.py | 417 + worlds/shapez/common/__init__.py | 0 worlds/shapez/common/options.py | 190 + worlds/shapez/data/__init__.py | 0 worlds/shapez/data/generate.py | 134 + worlds/shapez/data/options.json | 4 + worlds/shapez/data/shapesanity_pool.py | 75814 ++++++++++++++++ worlds/shapez/data/strings.py | 337 + worlds/shapez/docs/datapackage_settings_de.md | 35 + worlds/shapez/docs/datapackage_settings_en.md | 33 + worlds/shapez/docs/de_shapez.md | 71 + worlds/shapez/docs/en_shapez.md | 65 + worlds/shapez/docs/setup_de.md | 62 + worlds/shapez/docs/setup_en.md | 58 + worlds/shapez/docs/shapesanity_full.png | Bin 0 -> 127240 bytes worlds/shapez/items.py | 279 + worlds/shapez/locations.py | 546 + worlds/shapez/options.py | 310 + worlds/shapez/presets.py | 49 + worlds/shapez/regions.py | 277 + worlds/shapez/test/__init__.py | 213 + 21 files changed, 78894 insertions(+) create mode 100644 worlds/shapez/__init__.py create mode 100644 worlds/shapez/common/__init__.py create mode 100644 worlds/shapez/common/options.py create mode 100644 worlds/shapez/data/__init__.py create mode 100644 worlds/shapez/data/generate.py create mode 100644 worlds/shapez/data/options.json create mode 100644 worlds/shapez/data/shapesanity_pool.py create mode 100644 worlds/shapez/data/strings.py create mode 100644 worlds/shapez/docs/datapackage_settings_de.md create mode 100644 worlds/shapez/docs/datapackage_settings_en.md create mode 100644 worlds/shapez/docs/de_shapez.md create mode 100644 worlds/shapez/docs/en_shapez.md create mode 100644 worlds/shapez/docs/setup_de.md create mode 100644 worlds/shapez/docs/setup_en.md create mode 100644 worlds/shapez/docs/shapesanity_full.png create mode 100644 worlds/shapez/items.py create mode 100644 worlds/shapez/locations.py create mode 100644 worlds/shapez/options.py create mode 100644 worlds/shapez/presets.py create mode 100644 worlds/shapez/regions.py create mode 100644 worlds/shapez/test/__init__.py diff --git a/worlds/shapez/__init__.py b/worlds/shapez/__init__.py new file mode 100644 index 000000000000..2a77ed8c9c96 --- /dev/null +++ b/worlds/shapez/__init__.py @@ -0,0 +1,417 @@ +import math +from typing import Any, List, Dict, Tuple, Mapping + +from Options import OptionError +from .data.strings import OTHER, ITEMS, CATEGORY, LOCATIONS, SLOTDATA, GOALS, OPTIONS +from .items import item_descriptions, item_table, ShapezItem, \ + buildings_routing, buildings_processing, buildings_other, \ + buildings_top_row, buildings_wires, gameplay_unlocks, upgrades, \ + big_upgrades, filler, trap, bundles, belt_and_extractor, standard_traps, random_draining_trap, split_draining_traps, \ + whacky_upgrade_traps +from .locations import ShapezLocation, addlevels, addupgrades, addachievements, location_description, \ + addshapesanity, addshapesanity_ut, shapesanity_simple, init_shapesanity_pool, achievement_locations, \ + level_locations, upgrade_locations, shapesanity_locations, categories +from .presets import options_presets +from .options import ShapezOptions +from worlds.AutoWorld import World, WebWorld +from BaseClasses import Item, Tutorial, LocationProgressType, MultiWorld +from .regions import create_shapez_regions, has_x_belt_multiplier +from ..generic.Rules import add_rule + + +class ShapezWeb(WebWorld): + options_presets = options_presets + rich_text_options_doc = True + theme = "stone" + game_info_languages = ['en', 'de'] + setup_en = Tutorial( + "Multiworld Setup Guide", + "A guide to playing shapez with Archipelago:", + "English", + "setup_en.md", + "setup/en", + ["BlastSlimey"] + ) + setup_de = Tutorial( + setup_en.tutorial_name, + setup_en.description, + "Deutsch", + "setup_de.md", + "setup/de", + ["BlastSlimey"] + ) + datapackage_settings_en = Tutorial( + "Changing datapackage settings", + "3000 locations are too many or not enough? Here's how you can change that:", + "English", + "datapackage_settings_en.md", + "datapackage_settings/en", + ["BlastSlimey"] + ) + datapackage_settings_de = Tutorial( + datapackage_settings_en.tutorial_name, + datapackage_settings_en.description, + "Deutsch", + "datapackage_settings_de.md", + "datapackage_settings/de", + ["BlastSlimey"] + ) + tutorials = [setup_en, setup_de, datapackage_settings_en, datapackage_settings_de] + item_descriptions = item_descriptions + location_descriptions = location_description + + +class ShapezWorld(World): + """ + shapez is an automation game about cutting, rotating, stacking, and painting shapes, that you extract from randomly + generated patches on an infinite canvas, without the need to manage your infinite resources or to pay for building + your factories. + """ + game = OTHER.game_name + options_dataclass = ShapezOptions + options: ShapezOptions + topology_present = True + web = ShapezWeb() + base_id = 20010707 + item_name_to_id = {name: id for id, name in enumerate(item_table.keys(), base_id)} + location_name_to_id = {name: id for id, name in enumerate(level_locations + upgrade_locations + + achievement_locations + shapesanity_locations, base_id)} + item_name_groups = { + "Main Buildings": {ITEMS.cutter, ITEMS.rotator, ITEMS.painter, ITEMS.color_mixer, ITEMS.stacker}, + "Processing Buildings": {*buildings_processing}, + "Goal Buildings": {ITEMS.cutter, ITEMS.rotator, ITEMS.painter, ITEMS.rotator_ccw, ITEMS.color_mixer, + ITEMS.stacker, ITEMS.cutter_quad, ITEMS.painter_double, ITEMS.painter_quad, ITEMS.wires, + ITEMS.switch, ITEMS.const_signal}, + "Most Useful Buildings": {ITEMS.balancer, ITEMS.tunnel, ITEMS.tunnel_tier_ii, ITEMS.comp_merger, + ITEMS.comp_splitter, ITEMS.trash, ITEMS.extractor_chain}, + "Most Important Buildings": {*belt_and_extractor}, + "Top Row Buildings": {*buildings_top_row}, + "Wires Layer Buildings": {*buildings_wires}, + "Gameplay Mechanics": {ITEMS.blueprints, ITEMS.wires}, + "Upgrades": {*{ITEMS.upgrade(size, cat) + for size in {CATEGORY.big, CATEGORY.small, CATEGORY.gigantic, CATEGORY.rising} + for cat in {CATEGORY.belt, CATEGORY.miner, CATEGORY.processors, CATEGORY.painting}}, + *{ITEMS.trap_upgrade(cat, size) + for cat in {CATEGORY.belt, CATEGORY.miner, CATEGORY.processors, CATEGORY.painting} + for size in {"", CATEGORY.demonic}}, + *{ITEMS.upgrade(size, CATEGORY.random) + for size in {CATEGORY.big, CATEGORY.small}}}, + **{f"{cat} Upgrades": {*{ITEMS.upgrade(size, cat) + for size in {CATEGORY.big, CATEGORY.small, CATEGORY.gigantic, CATEGORY.rising}}, + *{ITEMS.trap_upgrade(cat, size) + for size in {"", CATEGORY.demonic}}} + for cat in {CATEGORY.belt, CATEGORY.miner, CATEGORY.processors, CATEGORY.painting}}, + "Bundles": {*bundles}, + "Traps": {*standard_traps, *random_draining_trap, *split_draining_traps, *whacky_upgrade_traps}, + } + location_name_groups = { + "Levels": {*level_locations}, + "Upgrades": {*upgrade_locations}, + "Achievements": {*achievement_locations}, + "Shapesanity": {*shapesanity_locations}, + **{f"{cat} Upgrades": {loc for loc in upgrade_locations if loc.startswith(cat)} for cat in categories}, + "Only Belt and Extractor": {LOCATIONS.level(1), LOCATIONS.level(1, 1), + LOCATIONS.my_eyes, LOCATIONS.its_a_mess, LOCATIONS.getting_into_it, + LOCATIONS.perfectionist, LOCATIONS.oops, LOCATIONS.i_need_trains, LOCATIONS.gps, + LOCATIONS.a_long_time, LOCATIONS.addicted, + LOCATIONS.shapesanity(1), LOCATIONS.shapesanity(2), LOCATIONS.shapesanity(3)}, + } + + def __init__(self, multiworld: MultiWorld, player: int): + super().__init__(multiworld, player) + + # Defining instance attributes for each shapez world + # These are set to default values that should fail unit tests if not replaced with correct values + self.location_count: int = 0 + self.level_logic: List[str] = [] + self.upgrade_logic: List[str] = [] + self.level_logic_type: str = "" + self.upgrade_logic_type: str = "" + self.random_logic_phase_length: List[int] = [] + self.category_random_logic_amounts: Dict[str, int] = {} + self.maxlevel: int = 0 + self.finaltier: int = 0 + self.included_locations: Dict[str, Tuple[str, LocationProgressType]] = {} + self.client_seed: int = 0 + self.shapesanity_names: List[str] = [] + self.upgrade_traps_allowed: bool = False + + # Universal Tracker support + self.ut_active: bool = False + self.passthrough: Dict[str, any] = {} + self.location_id_to_alias: Dict[int, str] = {} + + @classmethod + def stage_generate_early(cls, multiworld: MultiWorld) -> None: + # Import the 75800 entries long shapesanity pool only once and only if it's actually needed + if len(shapesanity_simple) == 0: + init_shapesanity_pool() + + def generate_early(self) -> None: + # Calculate all the important values used for generating a shapez world, with some of them being random + self.upgrade_traps_allowed: bool = (self.options.include_whacky_upgrades and + (not self.options.goal == GOALS.efficiency_iii) and + self.options.throughput_levels_ratio == 0) + + # Load values from UT if this is a regenerated world + if hasattr(self.multiworld, "re_gen_passthrough"): + if OTHER.game_name in self.multiworld.re_gen_passthrough: + self.ut_active = True + self.passthrough = self.multiworld.re_gen_passthrough[OTHER.game_name] + self.maxlevel = self.passthrough[SLOTDATA.maxlevel] + self.finaltier = self.passthrough[SLOTDATA.finaltier] + self.client_seed = self.passthrough[SLOTDATA.seed] + self.level_logic = [self.passthrough[SLOTDATA.level_building(i+1)] for i in range(5)] + self.upgrade_logic = [self.passthrough[SLOTDATA.upgrade_building(i+1)] for i in range(5)] + self.level_logic_type = self.passthrough[SLOTDATA.rand_level_logic] + self.upgrade_logic_type = self.passthrough[SLOTDATA.rand_upgrade_logic] + self.random_logic_phase_length = [self.passthrough[SLOTDATA.phase_length(i)] for i in range(5)] + self.category_random_logic_amounts = {cat: self.passthrough[SLOTDATA.cat_buildings_amount(cat)] + for cat in [CATEGORY.belt_low, CATEGORY.miner_low, + CATEGORY.processors_low, CATEGORY.painting_low]} + # Forces balancers, tunnel, and trash to not appear in regen to make UT more accurate + self.options.early_balancer_tunnel_and_trash.value = 0 + return + + # "MAM" goal is supposed to be longer than vanilla, but to not have more options than necessary, + # both goal amounts for "MAM" and "Even fasterer" are set in a single option. + if self.options.goal == GOALS.mam and self.options.goal_amount < 27: + raise OptionError(self.player_name + + ": When setting goal to 1 ('mam'), goal_amount must be at least 27 and not " + + str(self.options.goal_amount.value)) + + # If lock_belt_and_extractor is true, the only sphere 1 locations will be achievements + if self.options.lock_belt_and_extractor and not self.options.include_achievements: + raise OptionError(self.player_name + ": Achievements must be included when belt and extractor are locked") + + # Determines maxlevel and finaltier, which are needed for location and item generation + if self.options.goal == GOALS.vanilla: + self.maxlevel = 25 + self.finaltier = 8 + elif self.options.goal == GOALS.mam: + self.maxlevel = self.options.goal_amount - 1 + self.finaltier = 8 + elif self.options.goal == GOALS.even_fasterer: + self.maxlevel = 26 + self.finaltier = self.options.goal_amount.value + else: # goal == efficiency_iii + self.maxlevel = 26 + self.finaltier = 8 + + # Setting the seed for the game before any other randomization call is done + self.client_seed = self.random.randint(0, 100000) + + # Determines the order of buildings for levels logic + if self.options.randomize_level_requirements: + self.level_logic_type = self.options.randomize_level_logic.current_key + if self.level_logic_type.endswith(OPTIONS.logic_shuffled) or self.level_logic_type == OPTIONS.logic_dopamine: + vanilla_list = [ITEMS.cutter, ITEMS.painter, ITEMS.stacker] + while len(vanilla_list) > 0: + index = self.random.randint(0, len(vanilla_list)-1) + next_building = vanilla_list.pop(index) + if next_building == ITEMS.cutter: + vanilla_list.append(ITEMS.rotator) + if next_building == ITEMS.painter: + vanilla_list.append(ITEMS.color_mixer) + self.level_logic.append(next_building) + else: + self.level_logic = [ITEMS.cutter, ITEMS.rotator, ITEMS.painter, ITEMS.color_mixer, ITEMS.stacker] + else: + self.level_logic_type = OPTIONS.logic_vanilla + self.level_logic = [ITEMS.cutter, ITEMS.rotator, ITEMS.painter, ITEMS.color_mixer, ITEMS.stacker] + + # Determines the order of buildings for upgrades logic + if self.options.randomize_upgrade_requirements: + self.upgrade_logic_type = self.options.randomize_upgrade_logic.current_key + if self.upgrade_logic_type == OPTIONS.logic_hardcore: + self.upgrade_logic = [ITEMS.cutter, ITEMS.rotator, ITEMS.painter, ITEMS.color_mixer, ITEMS.stacker] + elif self.upgrade_logic_type == OPTIONS.logic_category: + self.upgrade_logic = [ITEMS.cutter, ITEMS.rotator, ITEMS.stacker, ITEMS.painter, ITEMS.color_mixer] + else: + vanilla_list = [ITEMS.cutter, ITEMS.painter, ITEMS.stacker] + while len(vanilla_list) > 0: + index = self.random.randint(0, len(vanilla_list)-1) + next_building = vanilla_list.pop(index) + if next_building == ITEMS.cutter: + vanilla_list.append(ITEMS.rotator) + if next_building == ITEMS.painter: + vanilla_list.append(ITEMS.color_mixer) + self.upgrade_logic.append(next_building) + else: + self.upgrade_logic_type = OPTIONS.logic_vanilla_like + self.upgrade_logic = [ITEMS.cutter, ITEMS.rotator, ITEMS.painter, ITEMS.color_mixer, ITEMS.stacker] + + # Determine lenghts of phases in level logic type "random" + self.random_logic_phase_length = [1, 1, 1, 1, 1] + if self.level_logic_type.startswith(OPTIONS.logic_random_steps): + remaininglength = self.maxlevel - 1 + for phase in range(0, 5): + if self.random.random() < 0.1: # Make sure that longer phases are less frequent + self.random_logic_phase_length[phase] = self.random.randint(0, remaininglength) + else: + self.random_logic_phase_length[phase] = self.random.randint(0, remaininglength // (6 - phase)) + remaininglength -= self.random_logic_phase_length[phase] + + # Determine amount of needed buildings for each category in upgrade logic type "category_random" + self.category_random_logic_amounts = {CATEGORY.belt_low: 0, CATEGORY.miner_low: 1, + CATEGORY.processors_low: 2, CATEGORY.painting_low: 3} + if self.upgrade_logic_type == OPTIONS.logic_category_random: + cats = [CATEGORY.belt_low, CATEGORY.miner_low, CATEGORY.processors_low, CATEGORY.painting_low] + nextcat = self.random.choice(cats) + self.category_random_logic_amounts[nextcat] = 0 + cats.remove(nextcat) + for cat in cats: + self.category_random_logic_amounts[cat] = self.random.randint(0, 5) + + def create_item(self, name: str) -> Item: + return ShapezItem(name, item_table[name](self.options), self.item_name_to_id[name], self.player) + + def get_filler_item_name(self) -> str: + return filler(self.random.random(), bool(self.options.include_whacky_upgrades)) + + def append_shapesanity(self, name: str) -> None: + """This method is given as a parameter when creating the locations for shapesanity.""" + self.shapesanity_names.append(name) + + def add_alias(self, location_name: str, alias: str): + """This method is given as a parameter when locations with helpful aliases for UT are created.""" + if self.ut_active: + self.location_id_to_alias[self.location_name_to_id[location_name]] = alias + + def create_regions(self) -> None: + # Create list of all included level and upgrade locations based on player options + # This already includes the region to be placed in and the LocationProgressType + self.included_locations = {**addlevels(self.maxlevel, self.level_logic_type, + self.random_logic_phase_length), + **addupgrades(self.finaltier, self.upgrade_logic_type, + self.category_random_logic_amounts)} + + # Add shapesanity to included location and creates the corresponding list based on player options + if self.ut_active: + self.shapesanity_names = self.passthrough[SLOTDATA.shapesanity] + self.included_locations.update(addshapesanity_ut(self.shapesanity_names, self.add_alias)) + else: + self.included_locations.update(addshapesanity(self.options.shapesanity_amount.value, self.random, + self.append_shapesanity, self.add_alias)) + + # Add achievements to included locations based on player options + if self.options.include_achievements: + self.included_locations.update(addachievements( + bool(self.options.exclude_softlock_achievements), bool(self.options.exclude_long_playtime_achievements), + bool(self.options.exclude_progression_unreasonable), self.maxlevel, self.upgrade_logic_type, + self.category_random_logic_amounts, self.options.goal.current_key, self.included_locations, + self.add_alias, self.upgrade_traps_allowed)) + + # Save the final amount of to-be-filled locations + self.location_count = len(self.included_locations) + + # Create regions and entrances based on included locations and player options + self.multiworld.regions.extend(create_shapez_regions(self.player, self.multiworld, + bool(self.options.allow_floating_layers.value), + self.included_locations, self.location_name_to_id, + self.level_logic, self.upgrade_logic, + self.options.early_balancer_tunnel_and_trash.current_key, + self.options.goal.current_key)) + + def create_items(self) -> None: + # Include guaranteed items (game mechanic unlocks and 7x4 big upgrades) + included_items: List[Item] = ([self.create_item(name) for name in buildings_processing.keys()] + + [self.create_item(name) for name in buildings_routing.keys()] + + [self.create_item(name) for name in buildings_other.keys()] + + [self.create_item(name) for name in buildings_top_row.keys()] + + [self.create_item(name) for name in buildings_wires.keys()] + + [self.create_item(name) for name in gameplay_unlocks.keys()] + + [self.create_item(name) for name in big_upgrades for _ in range(7)]) + + if not self.options.lock_belt_and_extractor: + for name in belt_and_extractor: + self.multiworld.push_precollected(self.create_item(name)) + else: # This also requires self.options.include_achievements to be true + included_items.extend([self.create_item(name) for name in belt_and_extractor.keys()]) + + # Give a detailed error message if there are already more items than available locations. + # At the moment, this won't happen, but it's better for debugging in case a future update breaks things. + if len(included_items) > self.location_count: + raise RuntimeError(self.player_name + ": There are more guaranteed items than available locations") + + # Get value from traps probability option and convert to float + traps_probability = self.options.traps_percentage/100 + split_draining = bool(self.options.split_inventory_draining_trap) + # Fill remaining locations with fillers + for x in range(self.location_count - len(included_items)): + if self.random.random() < traps_probability: + # Fill with trap + included_items.append(self.create_item(trap(self.random.random(), split_draining, + self.upgrade_traps_allowed))) + else: + # Fil with random filler item + included_items.append(self.create_item(self.get_filler_item_name())) + + # Add correct number of items to itempool + self.multiworld.itempool += included_items + + # Add balancer, tunnel, and trash to early items if player options say so + if self.options.early_balancer_tunnel_and_trash == OPTIONS.sphere_1: + self.multiworld.early_items[self.player][ITEMS.balancer] = 1 + self.multiworld.early_items[self.player][ITEMS.tunnel] = 1 + self.multiworld.early_items[self.player][ITEMS.trash] = 1 + + def set_rules(self) -> None: + # Levels might need more belt speed if they require throughput per second. As the randomization of what levels + # need throughput happens in the client mod, this logic needs to be applied to all levels. This is applied to + # every individual level instead of regions, because they would need a much more complex calculation to prevent + # softlocks. + + def f(x: int, name: str): + # These calculations are taken from the client mod + if x < 26: + throughput = math.ceil((2.999+x*0.333)*self.options.required_shapes_multiplier/10) + else: + throughput = min((4+(x-26)*0.25)*self.options.required_shapes_multiplier/10, 200) + if throughput/32 >= 1: + add_rule(self.get_location(name), + lambda state: has_x_belt_multiplier(state, self.player, throughput/32)) + + if not self.options.throughput_levels_ratio == 0: + f(0, LOCATIONS.level(1, 1)) + f(19, LOCATIONS.level(20, 1)) + f(19, LOCATIONS.level(20, 2)) + for _x in range(self.maxlevel): + f(_x, LOCATIONS.level(_x+1)) + if self.options.goal.current_key in [GOALS.vanilla, GOALS.mam]: + f(self.maxlevel, LOCATIONS.goal) + + def fill_slot_data(self) -> Mapping[str, Any]: + # Buildings logic; all buildings as individual parameters + level_logic_data = {SLOTDATA.level_building(x+1): self.level_logic[x] for x in range(5)} + upgrade_logic_data = {SLOTDATA.upgrade_building(x+1): self.upgrade_logic[x] for x in range(5)} + # Randomized values for certain logic types + logic_type_random_data = {SLOTDATA.phase_length(x): self.random_logic_phase_length[x] for x in range(0, 5)} + logic_type_cat_random_data = {SLOTDATA.cat_buildings_amount(cat): self.category_random_logic_amounts[cat] + for cat in [CATEGORY.belt_low, CATEGORY.miner_low, + CATEGORY.processors_low, CATEGORY.painting_low]} + + # Options that are relevant to the mod + option_data = { + SLOTDATA.goal: self.options.goal.current_key, + SLOTDATA.maxlevel: self.maxlevel, + SLOTDATA.finaltier: self.finaltier, + SLOTDATA.req_shapes_mult: self.options.required_shapes_multiplier.value, + SLOTDATA.allow_float_layers: bool(self.options.allow_floating_layers), + SLOTDATA.rand_level_req: bool(self.options.randomize_level_requirements), + SLOTDATA.rand_upgrade_req: bool(self.options.randomize_upgrade_requirements), + SLOTDATA.rand_level_logic: self.level_logic_type, + SLOTDATA.rand_upgrade_logic: self.upgrade_logic_type, + SLOTDATA.throughput_levels_ratio: self.options.throughput_levels_ratio.value, + SLOTDATA.comp_growth_gradient: self.options.complexity_growth_gradient.value, + SLOTDATA.same_late: bool(self.options.same_late_upgrade_requirements), + SLOTDATA.toolbar_shuffling: bool(self.options.toolbar_shuffling), + } + + return {**level_logic_data, **upgrade_logic_data, **option_data, **logic_type_random_data, + **logic_type_cat_random_data, SLOTDATA.seed: self.client_seed, + SLOTDATA.shapesanity: self.shapesanity_names} + + def interpret_slot_data(self, slot_data: Dict[str, Any]) -> Dict[str, Any]: + """Helper function for Universal Tracker""" + return slot_data diff --git a/worlds/shapez/common/__init__.py b/worlds/shapez/common/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/worlds/shapez/common/options.py b/worlds/shapez/common/options.py new file mode 100644 index 000000000000..aa66ced03294 --- /dev/null +++ b/worlds/shapez/common/options.py @@ -0,0 +1,190 @@ +import random +import typing + +from Options import FreeText, NumericOption + + +class FloatRangeText(FreeText, NumericOption): + """FreeText option optimized for entering float numbers. + Supports everything that Range supports. + range_start and range_end have to be floats, while default has to be a string.""" + + default = "0.0" + value: float + range_start: float = 0.0 + range_end: float = 1.0 + + def __init__(self, value: str): + super().__init__(value) + value = value.lower() + if value.startswith("random"): + self.value = self.weighted_range(value) + elif value == "default" and hasattr(self, "default"): + self.value = float(self.default) + elif value == "high": + self.value = self.range_end + elif value == "low": + self.value = self.range_start + elif self.range_start == 0.0 \ + and hasattr(self, "default") \ + and self.default != "0.0" \ + and value in ("true", "false"): + # these are the conditions where "true" and "false" make sense + if value == "true": + self.value = float(self.default) + else: # "false" + self.value = 0.0 + else: + try: + self.value = float(value) + except ValueError: + raise Exception(f"Invalid value for option {self.__class__.__name__}: {value}") + except OverflowError: + raise Exception(f"Out of range floating value for option {self.__class__.__name__}: {value}") + if self.value < self.range_start: + raise Exception(f"{value} is lower than minimum {self.range_start} for option {self.__class__.__name__}") + if self.value > self.range_end: + raise Exception(f"{value} is higher than maximum {self.range_end} for option {self.__class__.__name__}") + + @classmethod + def from_text(cls, text: str) -> typing.Any: + return cls(text) + + @classmethod + def weighted_range(cls, text: str) -> float: + if text == "random-low": + return random.triangular(cls.range_start, cls.range_end, cls.range_start) + elif text == "random-high": + return random.triangular(cls.range_start, cls.range_end, cls.range_end) + elif text == "random-middle": + return random.triangular(cls.range_start, cls.range_end) + elif text.startswith("random-range-"): + return cls.custom_range(text) + elif text == "random": + return random.uniform(cls.range_start, cls.range_end) + else: + raise Exception(f"random text \"{text}\" did not resolve to a recognized pattern. " + f"Acceptable values are: random, random-high, random-middle, random-low, " + f"random-range-low--, random-range-middle--, " + f"random-range-high--, or random-range--.") + + @classmethod + def custom_range(cls, text: str) -> float: + textsplit = text.split("-") + try: + random_range = [float(textsplit[len(textsplit) - 2]), float(textsplit[len(textsplit) - 1])] + except ValueError: + raise ValueError(f"Invalid random range {text} for option {cls.__name__}") + except OverflowError: + raise Exception(f"Out of range floating value for option {cls.__name__}: {text}") + random_range.sort() + if random_range[0] < cls.range_start or random_range[1] > cls.range_end: + raise Exception( + f"{random_range[0]}-{random_range[1]} is outside allowed range " + f"{cls.range_start}-{cls.range_end} for option {cls.__name__}") + if text.startswith("random-range-low"): + return random.triangular(random_range[0], random_range[1], random_range[0]) + elif text.startswith("random-range-middle"): + return random.triangular(random_range[0], random_range[1]) + elif text.startswith("random-range-high"): + return random.triangular(random_range[0], random_range[1], random_range[1]) + else: + return random.uniform(random_range[0], random_range[1]) + + @property + def current_key(self) -> str: + return str(self.value) + + @classmethod + def get_option_name(cls, value: float) -> str: + return str(value) + + def __eq__(self, other: typing.Any): + if isinstance(other, NumericOption): + return self.value == other.value + else: + return typing.cast(bool, self.value == other) + + def __lt__(self, other: typing.Union[int, float, NumericOption]) -> bool: + if isinstance(other, NumericOption): + return self.value < other.value + else: + return self.value < other + + def __le__(self, other: typing.Union[int, float, NumericOption]) -> bool: + if isinstance(other, NumericOption): + return self.value <= other.value + else: + return self.value <= other + + def __gt__(self, other: typing.Union[int, float, NumericOption]) -> bool: + if isinstance(other, NumericOption): + return self.value > other.value + else: + return self.value > other + + def __ge__(self, other: typing.Union[int, float, NumericOption]) -> bool: + if isinstance(other, NumericOption): + return self.value >= other.value + else: + return self.value >= other + + def __int__(self) -> int: + return int(self.value) + + def __and__(self, other: typing.Any) -> int: + raise TypeError("& operator not supported for float values") + + def __floordiv__(self, other: typing.Any) -> int: + return int(self.value // float(other)) + + def __invert__(self) -> int: + raise TypeError("~ operator not supported for float values") + + def __lshift__(self, other: typing.Any) -> int: + raise TypeError("<< operator not supported for float values") + + def __mod__(self, other: typing.Any) -> float: + return self.value % float(other) + + def __neg__(self) -> float: + return -self.value + + def __or__(self, other: typing.Any) -> int: + raise TypeError("| operator not supported for float values") + + def __pos__(self) -> float: + return +self.value + + def __rand__(self, other: typing.Any) -> int: + raise TypeError("& operator not supported for float values") + + def __rfloordiv__(self, other: typing.Any) -> int: + return int(float(other) // self.value) + + def __rlshift__(self, other: typing.Any) -> int: + raise TypeError("<< operator not supported for float values") + + def __rmod__(self, other: typing.Any) -> float: + return float(other) % self.value + + def __ror__(self, other: typing.Any) -> int: + raise TypeError("| operator not supported for float values") + + def __round__(self, ndigits: typing.Optional[int] = None) -> float: + return round(self.value, ndigits) + + def __rpow__(self, base: typing.Any) -> typing.Any: + return base ** self.value + + def __rrshift__(self, other: typing.Any) -> int: + raise TypeError(">> operator not supported for float values") + + def __rshift__(self, other: typing.Any) -> int: + raise TypeError(">> operator not supported for float values") + + def __rxor__(self, other: typing.Any) -> int: + raise TypeError("^ operator not supported for float values") + + def __xor__(self, other: typing.Any) -> int: + raise TypeError("^ operator not supported for float values") diff --git a/worlds/shapez/data/__init__.py b/worlds/shapez/data/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/worlds/shapez/data/generate.py b/worlds/shapez/data/generate.py new file mode 100644 index 000000000000..27d74e865d08 --- /dev/null +++ b/worlds/shapez/data/generate.py @@ -0,0 +1,134 @@ +import itertools +import time +from typing import Dict, List + +from worlds.shapez.data.strings import SHAPESANITY, REGIONS + +shapesanity_simple: Dict[str, str] = {} +shapesanity_1_4: Dict[str, str] = {} +shapesanity_two_sided: Dict[str, str] = {} +shapesanity_three_parts: Dict[str, str] = {} +shapesanity_four_parts: Dict[str, str] = {} +subshape_names = [SHAPESANITY.circle, SHAPESANITY.square, SHAPESANITY.star, SHAPESANITY.windmill] +color_names = [SHAPESANITY.red, SHAPESANITY.blue, SHAPESANITY.green, SHAPESANITY.yellow, SHAPESANITY.purple, + SHAPESANITY.cyan, SHAPESANITY.white, SHAPESANITY.uncolored] +short_subshapes = ["C", "R", "S", "W"] +short_colors = ["b", "c", "g", "p", "r", "u", "w", "y"] + + +def color_to_needed_building(color_list: List[str]) -> str: + for next_color in color_list: + if next_color in [SHAPESANITY.yellow, SHAPESANITY.purple, SHAPESANITY.cyan, SHAPESANITY.white, + "y", "p", "c", "w"]: + return REGIONS.mixed + for next_color in color_list: + if next_color not in [SHAPESANITY.uncolored, "u"]: + return REGIONS.painted + return REGIONS.uncol + + +def generate_shapesanity_pool() -> None: + # same shapes && same color + for color in color_names: + color_region = color_to_needed_building([color]) + shapesanity_simple[SHAPESANITY.full(color, SHAPESANITY.circle)] = REGIONS.sanity(REGIONS.full, color_region) + shapesanity_simple[SHAPESANITY.full(color, SHAPESANITY.square)] = REGIONS.sanity(REGIONS.full, color_region) + shapesanity_simple[SHAPESANITY.full(color, SHAPESANITY.star)] = REGIONS.sanity(REGIONS.full, color_region) + shapesanity_simple[SHAPESANITY.full(color, SHAPESANITY.windmill)] = REGIONS.sanity(REGIONS.east_wind, color_region) + for shape in subshape_names: + for color in color_names: + color_region = color_to_needed_building([color]) + shapesanity_simple[SHAPESANITY.half(color, shape)] = REGIONS.sanity(REGIONS.half, color_region) + shapesanity_simple[SHAPESANITY.piece(color, shape)] = REGIONS.sanity(REGIONS.piece, color_region) + shapesanity_simple[SHAPESANITY.cutout(color, shape)] = REGIONS.sanity(REGIONS.stitched, color_region) + shapesanity_simple[SHAPESANITY.cornered(color, shape)] = REGIONS.sanity(REGIONS.stitched, color_region) + + # one color && 4 shapes (including empty) + for first_color, second_color, third_color, fourth_color in itertools.combinations(short_colors+["-"], 4): + colors = [first_color, second_color, third_color, fourth_color] + color_region = color_to_needed_building(colors) + shape_regions = [REGIONS.stitched, REGIONS.stitched] if fourth_color == "-" else [REGIONS.col_full, REGIONS.col_east_wind] + color_code = ''.join(colors) + shapesanity_1_4[SHAPESANITY.full(color_code, SHAPESANITY.circle)] = REGIONS.sanity(shape_regions[0], color_region) + shapesanity_1_4[SHAPESANITY.full(color_code, SHAPESANITY.square)] = REGIONS.sanity(shape_regions[0], color_region) + shapesanity_1_4[SHAPESANITY.full(color_code, SHAPESANITY.star)] = REGIONS.sanity(shape_regions[0], color_region) + shapesanity_1_4[SHAPESANITY.full(color_code, SHAPESANITY.windmill)] = REGIONS.sanity(shape_regions[1], color_region) + + # one shape && 4 colors (including empty) + for first_shape, second_shape, third_shape, fourth_shape in itertools.combinations(short_subshapes+["-"], 4): + for color in color_names: + shapesanity_1_4[SHAPESANITY.full(color, ''.join([first_shape, second_shape, third_shape, fourth_shape]))] \ + = REGIONS.sanity(REGIONS.stitched, color_to_needed_building([color])) + + combos = [shape + color for shape in short_subshapes for color in short_colors] + for first_combo, second_combo in itertools.permutations(combos, 2): + # 2-sided shapes + color_region = color_to_needed_building([first_combo[1], second_combo[1]]) + ordered_combo = " ".join(sorted([first_combo, second_combo])) + shape_regions = (([REGIONS.east_wind, REGIONS.east_wind, REGIONS.col_half] + if first_combo[0] == "W" else [REGIONS.col_full, REGIONS.col_full, REGIONS.col_half]) + if first_combo[0] == second_combo[0] else [REGIONS.stitched, REGIONS.half_half, REGIONS.stitched]) + shapesanity_two_sided[SHAPESANITY.three_one(first_combo, second_combo)] = REGIONS.sanity(shape_regions[0], color_region) + shapesanity_two_sided[SHAPESANITY.halfhalf(ordered_combo)] = REGIONS.sanity(shape_regions[1], color_region) + shapesanity_two_sided[SHAPESANITY.checkered(ordered_combo)] = REGIONS.sanity(shape_regions[0], color_region) + shapesanity_two_sided[SHAPESANITY.singles(ordered_combo, SHAPESANITY.adjacent_pos)] = REGIONS.sanity(shape_regions[2], color_region) + shapesanity_two_sided[SHAPESANITY.singles(ordered_combo, SHAPESANITY.cornered_pos)] = REGIONS.sanity(REGIONS.stitched, color_region) + shapesanity_two_sided[SHAPESANITY.two_one(first_combo, second_combo, SHAPESANITY.adjacent_pos)] = REGIONS.sanity(REGIONS.stitched, color_region) + shapesanity_two_sided[SHAPESANITY.two_one(first_combo, second_combo, SHAPESANITY.cornered_pos)] = REGIONS.sanity(REGIONS.stitched, color_region) + for third_combo in combos: + if third_combo in [first_combo, second_combo]: + continue + # 3-part shapes + colors = [first_combo[1], second_combo[1], third_combo[1]] + color_region = color_to_needed_building(colors) + ordered_two = " ".join(sorted([second_combo, third_combo])) + if not (first_combo[1] == second_combo[1] == third_combo[1] or + first_combo[0] == second_combo[0] == third_combo[0]): + ordered_all = " ".join(sorted([first_combo, second_combo, third_combo])) + shapesanity_three_parts[SHAPESANITY.singles(ordered_all)] = REGIONS.sanity(REGIONS.stitched, color_region) + shape_regions = ([REGIONS.stitched, REGIONS.stitched] if not second_combo[0] == third_combo[0] + else (([REGIONS.east_wind, REGIONS.east_wind] if first_combo[0] == "W" + else [REGIONS.col_full, REGIONS.col_full]) + if first_combo[0] == second_combo[0] else [REGIONS.col_half_half, REGIONS.stitched])) + shapesanity_three_parts[SHAPESANITY.two_one_one(first_combo, ordered_two, SHAPESANITY.adjacent_pos)] \ + = REGIONS.sanity(shape_regions[0], color_region) + shapesanity_three_parts[SHAPESANITY.two_one_one(first_combo, ordered_two, SHAPESANITY.cornered_pos)] \ + = REGIONS.sanity(shape_regions[1], color_region) + for fourth_combo in combos: + if fourth_combo in [first_combo, second_combo, third_combo]: + continue + if (first_combo[1] == second_combo[1] == third_combo[1] == fourth_combo[1] or + first_combo[0] == second_combo[0] == third_combo[0] == fourth_combo[0]): + continue + colors = [first_combo[1], second_combo[1], third_combo[1], fourth_combo[1]] + color_region = color_to_needed_building(colors) + ordered_all = " ".join(sorted([first_combo, second_combo, third_combo, fourth_combo])) + if ((first_combo[0] == second_combo[0] and third_combo[0] == fourth_combo[0]) or + (first_combo[0] == third_combo[0] and second_combo[0] == fourth_combo[0]) or + (first_combo[0] == fourth_combo[0] and third_combo[0] == second_combo[0])): + shapesanity_four_parts[SHAPESANITY.singles(ordered_all)] = REGIONS.sanity(REGIONS.col_half_half, color_region) + else: + shapesanity_four_parts[SHAPESANITY.singles(ordered_all)] = REGIONS.sanity(REGIONS.stitched, color_region) + + +if __name__ == "__main__": + start = time.time() + generate_shapesanity_pool() + print(time.time() - start) + with open("shapesanity_pool.py", "w") as outfile: + outfile.writelines(["shapesanity_simple = {\n"] + + [f" \"{name}\": \"{shapesanity_simple[name]}\",\n" + for name in shapesanity_simple] + + ["}\n\nshapesanity_1_4 = {\n"] + + [f" \"{name}\": \"{shapesanity_1_4[name]}\",\n" + for name in shapesanity_1_4] + + ["}\n\nshapesanity_two_sided = {\n"] + + [f" \"{name}\": \"{shapesanity_two_sided[name]}\",\n" + for name in shapesanity_two_sided] + + ["}\n\nshapesanity_three_parts = {\n"] + + [f" \"{name}\": \"{shapesanity_three_parts[name]}\",\n" + for name in shapesanity_three_parts] + + ["}\n\nshapesanity_four_parts = {\n"] + + [f" \"{name}\": \"{shapesanity_four_parts[name]}\",\n" + for name in shapesanity_four_parts] + + ["}\n"]) diff --git a/worlds/shapez/data/options.json b/worlds/shapez/data/options.json new file mode 100644 index 000000000000..d60f02e0fd93 --- /dev/null +++ b/worlds/shapez/data/options.json @@ -0,0 +1,4 @@ +{ + "max_levels_and_upgrades": 500, + "max_shapesanity": 1000 +} diff --git a/worlds/shapez/data/shapesanity_pool.py b/worlds/shapez/data/shapesanity_pool.py new file mode 100644 index 000000000000..b0ae132e5432 --- /dev/null +++ b/worlds/shapez/data/shapesanity_pool.py @@ -0,0 +1,75814 @@ +shapesanity_simple = { + "Red Circle": "Shapesanity Full Painted", + "Red Square": "Shapesanity Full Painted", + "Red Star": "Shapesanity Full Painted", + "Red Windmill": "Shapesanity East Windmill Painted", + "Blue Circle": "Shapesanity Full Painted", + "Blue Square": "Shapesanity Full Painted", + "Blue Star": "Shapesanity Full Painted", + "Blue Windmill": "Shapesanity East Windmill Painted", + "Green Circle": "Shapesanity Full Painted", + "Green Square": "Shapesanity Full Painted", + "Green Star": "Shapesanity Full Painted", + "Green Windmill": "Shapesanity East Windmill Painted", + "Yellow Circle": "Shapesanity Full Mixed", + "Yellow Square": "Shapesanity Full Mixed", + "Yellow Star": "Shapesanity Full Mixed", + "Yellow Windmill": "Shapesanity East Windmill Mixed", + "Purple Circle": "Shapesanity Full Mixed", + "Purple Square": "Shapesanity Full Mixed", + "Purple Star": "Shapesanity Full Mixed", + "Purple Windmill": "Shapesanity East Windmill Mixed", + "Cyan Circle": "Shapesanity Full Mixed", + "Cyan Square": "Shapesanity Full Mixed", + "Cyan Star": "Shapesanity Full Mixed", + "Cyan Windmill": "Shapesanity East Windmill Mixed", + "White Circle": "Shapesanity Full Mixed", + "White Square": "Shapesanity Full Mixed", + "White Star": "Shapesanity Full Mixed", + "White Windmill": "Shapesanity East Windmill Mixed", + "Uncolored Circle": "Shapesanity Full Uncolored", + "Uncolored Square": "Shapesanity Full Uncolored", + "Uncolored Star": "Shapesanity Full Uncolored", + "Uncolored Windmill": "Shapesanity East Windmill Uncolored", + "Half Red Circle": "Shapesanity Half Painted", + "Red Circle Piece": "Shapesanity Piece Painted", + "Cut Out Red Circle": "Shapesanity Stitched Painted", + "Cornered Red Circle": "Shapesanity Stitched Painted", + "Half Blue Circle": "Shapesanity Half Painted", + "Blue Circle Piece": "Shapesanity Piece Painted", + "Cut Out Blue Circle": "Shapesanity Stitched Painted", + "Cornered Blue Circle": "Shapesanity Stitched Painted", + "Half Green Circle": "Shapesanity Half Painted", + "Green Circle Piece": "Shapesanity Piece Painted", + "Cut Out Green Circle": "Shapesanity Stitched Painted", + "Cornered Green Circle": "Shapesanity Stitched Painted", + "Half Yellow Circle": "Shapesanity Half Mixed", + "Yellow Circle Piece": "Shapesanity Piece Mixed", + "Cut Out Yellow Circle": "Shapesanity Stitched Mixed", + "Cornered Yellow Circle": "Shapesanity Stitched Mixed", + "Half Purple Circle": "Shapesanity Half Mixed", + "Purple Circle Piece": "Shapesanity Piece Mixed", + "Cut Out Purple Circle": "Shapesanity Stitched Mixed", + "Cornered Purple Circle": "Shapesanity Stitched Mixed", + "Half Cyan Circle": "Shapesanity Half Mixed", + "Cyan Circle Piece": "Shapesanity Piece Mixed", + "Cut Out Cyan Circle": "Shapesanity Stitched Mixed", + "Cornered Cyan Circle": "Shapesanity Stitched Mixed", + "Half White Circle": "Shapesanity Half Mixed", + "White Circle Piece": "Shapesanity Piece Mixed", + "Cut Out White Circle": "Shapesanity Stitched Mixed", + "Cornered White Circle": "Shapesanity Stitched Mixed", + "Half Uncolored Circle": "Shapesanity Half Uncolored", + "Uncolored Circle Piece": "Shapesanity Piece Uncolored", + "Cut Out Uncolored Circle": "Shapesanity Stitched Uncolored", + "Cornered Uncolored Circle": "Shapesanity Stitched Uncolored", + "Half Red Square": "Shapesanity Half Painted", + "Red Square Piece": "Shapesanity Piece Painted", + "Cut Out Red Square": "Shapesanity Stitched Painted", + "Cornered Red Square": "Shapesanity Stitched Painted", + "Half Blue Square": "Shapesanity Half Painted", + "Blue Square Piece": "Shapesanity Piece Painted", + "Cut Out Blue Square": "Shapesanity Stitched Painted", + "Cornered Blue Square": "Shapesanity Stitched Painted", + "Half Green Square": "Shapesanity Half Painted", + "Green Square Piece": "Shapesanity Piece Painted", + "Cut Out Green Square": "Shapesanity Stitched Painted", + "Cornered Green Square": "Shapesanity Stitched Painted", + "Half Yellow Square": "Shapesanity Half Mixed", + "Yellow Square Piece": "Shapesanity Piece Mixed", + "Cut Out Yellow Square": "Shapesanity Stitched Mixed", + "Cornered Yellow Square": "Shapesanity Stitched Mixed", + "Half Purple Square": "Shapesanity Half Mixed", + "Purple Square Piece": "Shapesanity Piece Mixed", + "Cut Out Purple Square": "Shapesanity Stitched Mixed", + "Cornered Purple Square": "Shapesanity Stitched Mixed", + "Half Cyan Square": "Shapesanity Half Mixed", + "Cyan Square Piece": "Shapesanity Piece Mixed", + "Cut Out Cyan Square": "Shapesanity Stitched Mixed", + "Cornered Cyan Square": "Shapesanity Stitched Mixed", + "Half White Square": "Shapesanity Half Mixed", + "White Square Piece": "Shapesanity Piece Mixed", + "Cut Out White Square": "Shapesanity Stitched Mixed", + "Cornered White Square": "Shapesanity Stitched Mixed", + "Half Uncolored Square": "Shapesanity Half Uncolored", + "Uncolored Square Piece": "Shapesanity Piece Uncolored", + "Cut Out Uncolored Square": "Shapesanity Stitched Uncolored", + "Cornered Uncolored Square": "Shapesanity Stitched Uncolored", + "Half Red Star": "Shapesanity Half Painted", + "Red Star Piece": "Shapesanity Piece Painted", + "Cut Out Red Star": "Shapesanity Stitched Painted", + "Cornered Red Star": "Shapesanity Stitched Painted", + "Half Blue Star": "Shapesanity Half Painted", + "Blue Star Piece": "Shapesanity Piece Painted", + "Cut Out Blue Star": "Shapesanity Stitched Painted", + "Cornered Blue Star": "Shapesanity Stitched Painted", + "Half Green Star": "Shapesanity Half Painted", + "Green Star Piece": "Shapesanity Piece Painted", + "Cut Out Green Star": "Shapesanity Stitched Painted", + "Cornered Green Star": "Shapesanity Stitched Painted", + "Half Yellow Star": "Shapesanity Half Mixed", + "Yellow Star Piece": "Shapesanity Piece Mixed", + "Cut Out Yellow Star": "Shapesanity Stitched Mixed", + "Cornered Yellow Star": "Shapesanity Stitched Mixed", + "Half Purple Star": "Shapesanity Half Mixed", + "Purple Star Piece": "Shapesanity Piece Mixed", + "Cut Out Purple Star": "Shapesanity Stitched Mixed", + "Cornered Purple Star": "Shapesanity Stitched Mixed", + "Half Cyan Star": "Shapesanity Half Mixed", + "Cyan Star Piece": "Shapesanity Piece Mixed", + "Cut Out Cyan Star": "Shapesanity Stitched Mixed", + "Cornered Cyan Star": "Shapesanity Stitched Mixed", + "Half White Star": "Shapesanity Half Mixed", + "White Star Piece": "Shapesanity Piece Mixed", + "Cut Out White Star": "Shapesanity Stitched Mixed", + "Cornered White Star": "Shapesanity Stitched Mixed", + "Half Uncolored Star": "Shapesanity Half Uncolored", + "Uncolored Star Piece": "Shapesanity Piece Uncolored", + "Cut Out Uncolored Star": "Shapesanity Stitched Uncolored", + "Cornered Uncolored Star": "Shapesanity Stitched Uncolored", + "Half Red Windmill": "Shapesanity Half Painted", + "Red Windmill Piece": "Shapesanity Piece Painted", + "Cut Out Red Windmill": "Shapesanity Stitched Painted", + "Cornered Red Windmill": "Shapesanity Stitched Painted", + "Half Blue Windmill": "Shapesanity Half Painted", + "Blue Windmill Piece": "Shapesanity Piece Painted", + "Cut Out Blue Windmill": "Shapesanity Stitched Painted", + "Cornered Blue Windmill": "Shapesanity Stitched Painted", + "Half Green Windmill": "Shapesanity Half Painted", + "Green Windmill Piece": "Shapesanity Piece Painted", + "Cut Out Green Windmill": "Shapesanity Stitched Painted", + "Cornered Green Windmill": "Shapesanity Stitched Painted", + "Half Yellow Windmill": "Shapesanity Half Mixed", + "Yellow Windmill Piece": "Shapesanity Piece Mixed", + "Cut Out Yellow Windmill": "Shapesanity Stitched Mixed", + "Cornered Yellow Windmill": "Shapesanity Stitched Mixed", + "Half Purple Windmill": "Shapesanity Half Mixed", + "Purple Windmill Piece": "Shapesanity Piece Mixed", + "Cut Out Purple Windmill": "Shapesanity Stitched Mixed", + "Cornered Purple Windmill": "Shapesanity Stitched Mixed", + "Half Cyan Windmill": "Shapesanity Half Mixed", + "Cyan Windmill Piece": "Shapesanity Piece Mixed", + "Cut Out Cyan Windmill": "Shapesanity Stitched Mixed", + "Cornered Cyan Windmill": "Shapesanity Stitched Mixed", + "Half White Windmill": "Shapesanity Half Mixed", + "White Windmill Piece": "Shapesanity Piece Mixed", + "Cut Out White Windmill": "Shapesanity Stitched Mixed", + "Cornered White Windmill": "Shapesanity Stitched Mixed", + "Half Uncolored Windmill": "Shapesanity Half Uncolored", + "Uncolored Windmill Piece": "Shapesanity Piece Uncolored", + "Cut Out Uncolored Windmill": "Shapesanity Stitched Uncolored", + "Cornered Uncolored Windmill": "Shapesanity Stitched Uncolored", +} + +shapesanity_1_4 = { + "bcgp Circle": "Shapesanity Colorful Full Mixed", + "bcgp Square": "Shapesanity Colorful Full Mixed", + "bcgp Star": "Shapesanity Colorful Full Mixed", + "bcgp Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcgr Circle": "Shapesanity Colorful Full Mixed", + "bcgr Square": "Shapesanity Colorful Full Mixed", + "bcgr Star": "Shapesanity Colorful Full Mixed", + "bcgr Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcgu Circle": "Shapesanity Colorful Full Mixed", + "bcgu Square": "Shapesanity Colorful Full Mixed", + "bcgu Star": "Shapesanity Colorful Full Mixed", + "bcgu Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcgw Circle": "Shapesanity Colorful Full Mixed", + "bcgw Square": "Shapesanity Colorful Full Mixed", + "bcgw Star": "Shapesanity Colorful Full Mixed", + "bcgw Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcgy Circle": "Shapesanity Colorful Full Mixed", + "bcgy Square": "Shapesanity Colorful Full Mixed", + "bcgy Star": "Shapesanity Colorful Full Mixed", + "bcgy Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcg- Circle": "Shapesanity Stitched Mixed", + "bcg- Square": "Shapesanity Stitched Mixed", + "bcg- Star": "Shapesanity Stitched Mixed", + "bcg- Windmill": "Shapesanity Stitched Mixed", + "bcpr Circle": "Shapesanity Colorful Full Mixed", + "bcpr Square": "Shapesanity Colorful Full Mixed", + "bcpr Star": "Shapesanity Colorful Full Mixed", + "bcpr Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcpu Circle": "Shapesanity Colorful Full Mixed", + "bcpu Square": "Shapesanity Colorful Full Mixed", + "bcpu Star": "Shapesanity Colorful Full Mixed", + "bcpu Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcpw Circle": "Shapesanity Colorful Full Mixed", + "bcpw Square": "Shapesanity Colorful Full Mixed", + "bcpw Star": "Shapesanity Colorful Full Mixed", + "bcpw Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcpy Circle": "Shapesanity Colorful Full Mixed", + "bcpy Square": "Shapesanity Colorful Full Mixed", + "bcpy Star": "Shapesanity Colorful Full Mixed", + "bcpy Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcp- Circle": "Shapesanity Stitched Mixed", + "bcp- Square": "Shapesanity Stitched Mixed", + "bcp- Star": "Shapesanity Stitched Mixed", + "bcp- Windmill": "Shapesanity Stitched Mixed", + "bcru Circle": "Shapesanity Colorful Full Mixed", + "bcru Square": "Shapesanity Colorful Full Mixed", + "bcru Star": "Shapesanity Colorful Full Mixed", + "bcru Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcrw Circle": "Shapesanity Colorful Full Mixed", + "bcrw Square": "Shapesanity Colorful Full Mixed", + "bcrw Star": "Shapesanity Colorful Full Mixed", + "bcrw Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcry Circle": "Shapesanity Colorful Full Mixed", + "bcry Square": "Shapesanity Colorful Full Mixed", + "bcry Star": "Shapesanity Colorful Full Mixed", + "bcry Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcr- Circle": "Shapesanity Stitched Mixed", + "bcr- Square": "Shapesanity Stitched Mixed", + "bcr- Star": "Shapesanity Stitched Mixed", + "bcr- Windmill": "Shapesanity Stitched Mixed", + "bcuw Circle": "Shapesanity Colorful Full Mixed", + "bcuw Square": "Shapesanity Colorful Full Mixed", + "bcuw Star": "Shapesanity Colorful Full Mixed", + "bcuw Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcuy Circle": "Shapesanity Colorful Full Mixed", + "bcuy Square": "Shapesanity Colorful Full Mixed", + "bcuy Star": "Shapesanity Colorful Full Mixed", + "bcuy Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcu- Circle": "Shapesanity Stitched Mixed", + "bcu- Square": "Shapesanity Stitched Mixed", + "bcu- Star": "Shapesanity Stitched Mixed", + "bcu- Windmill": "Shapesanity Stitched Mixed", + "bcwy Circle": "Shapesanity Colorful Full Mixed", + "bcwy Square": "Shapesanity Colorful Full Mixed", + "bcwy Star": "Shapesanity Colorful Full Mixed", + "bcwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "bcw- Circle": "Shapesanity Stitched Mixed", + "bcw- Square": "Shapesanity Stitched Mixed", + "bcw- Star": "Shapesanity Stitched Mixed", + "bcw- Windmill": "Shapesanity Stitched Mixed", + "bcy- Circle": "Shapesanity Stitched Mixed", + "bcy- Square": "Shapesanity Stitched Mixed", + "bcy- Star": "Shapesanity Stitched Mixed", + "bcy- Windmill": "Shapesanity Stitched Mixed", + "bgpr Circle": "Shapesanity Colorful Full Mixed", + "bgpr Square": "Shapesanity Colorful Full Mixed", + "bgpr Star": "Shapesanity Colorful Full Mixed", + "bgpr Windmill": "Shapesanity Colorful East Windmill Mixed", + "bgpu Circle": "Shapesanity Colorful Full Mixed", + "bgpu Square": "Shapesanity Colorful Full Mixed", + "bgpu Star": "Shapesanity Colorful Full Mixed", + "bgpu Windmill": "Shapesanity Colorful East Windmill Mixed", + "bgpw Circle": "Shapesanity Colorful Full Mixed", + "bgpw Square": "Shapesanity Colorful Full Mixed", + "bgpw Star": "Shapesanity Colorful Full Mixed", + "bgpw Windmill": "Shapesanity Colorful East Windmill Mixed", + "bgpy Circle": "Shapesanity Colorful Full Mixed", + "bgpy Square": "Shapesanity Colorful Full Mixed", + "bgpy Star": "Shapesanity Colorful Full Mixed", + "bgpy Windmill": "Shapesanity Colorful East Windmill Mixed", + "bgp- Circle": "Shapesanity Stitched Mixed", + "bgp- Square": "Shapesanity Stitched Mixed", + "bgp- Star": "Shapesanity Stitched Mixed", + "bgp- Windmill": "Shapesanity Stitched Mixed", + "bgru Circle": "Shapesanity Colorful Full Painted", + "bgru Square": "Shapesanity Colorful Full Painted", + "bgru Star": "Shapesanity Colorful Full Painted", + "bgru Windmill": "Shapesanity Colorful East Windmill Painted", + "bgrw Circle": "Shapesanity Colorful Full Mixed", + "bgrw Square": "Shapesanity Colorful Full Mixed", + "bgrw Star": "Shapesanity Colorful Full Mixed", + "bgrw Windmill": "Shapesanity Colorful East Windmill Mixed", + "bgry Circle": "Shapesanity Colorful Full Mixed", + "bgry Square": "Shapesanity Colorful Full Mixed", + "bgry Star": "Shapesanity Colorful Full Mixed", + "bgry Windmill": "Shapesanity Colorful East Windmill Mixed", + "bgr- Circle": "Shapesanity Stitched Painted", + "bgr- Square": "Shapesanity Stitched Painted", + "bgr- Star": "Shapesanity Stitched Painted", + "bgr- Windmill": "Shapesanity Stitched Painted", + "bguw Circle": "Shapesanity Colorful Full Mixed", + "bguw Square": "Shapesanity Colorful Full Mixed", + "bguw Star": "Shapesanity Colorful Full Mixed", + "bguw Windmill": "Shapesanity Colorful East Windmill Mixed", + "bguy Circle": "Shapesanity Colorful Full Mixed", + "bguy Square": "Shapesanity Colorful Full Mixed", + "bguy Star": "Shapesanity Colorful Full Mixed", + "bguy Windmill": "Shapesanity Colorful East Windmill Mixed", + "bgu- Circle": "Shapesanity Stitched Painted", + "bgu- Square": "Shapesanity Stitched Painted", + "bgu- Star": "Shapesanity Stitched Painted", + "bgu- Windmill": "Shapesanity Stitched Painted", + "bgwy Circle": "Shapesanity Colorful Full Mixed", + "bgwy Square": "Shapesanity Colorful Full Mixed", + "bgwy Star": "Shapesanity Colorful Full Mixed", + "bgwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "bgw- Circle": "Shapesanity Stitched Mixed", + "bgw- Square": "Shapesanity Stitched Mixed", + "bgw- Star": "Shapesanity Stitched Mixed", + "bgw- Windmill": "Shapesanity Stitched Mixed", + "bgy- Circle": "Shapesanity Stitched Mixed", + "bgy- Square": "Shapesanity Stitched Mixed", + "bgy- Star": "Shapesanity Stitched Mixed", + "bgy- Windmill": "Shapesanity Stitched Mixed", + "bpru Circle": "Shapesanity Colorful Full Mixed", + "bpru Square": "Shapesanity Colorful Full Mixed", + "bpru Star": "Shapesanity Colorful Full Mixed", + "bpru Windmill": "Shapesanity Colorful East Windmill Mixed", + "bprw Circle": "Shapesanity Colorful Full Mixed", + "bprw Square": "Shapesanity Colorful Full Mixed", + "bprw Star": "Shapesanity Colorful Full Mixed", + "bprw Windmill": "Shapesanity Colorful East Windmill Mixed", + "bpry Circle": "Shapesanity Colorful Full Mixed", + "bpry Square": "Shapesanity Colorful Full Mixed", + "bpry Star": "Shapesanity Colorful Full Mixed", + "bpry Windmill": "Shapesanity Colorful East Windmill Mixed", + "bpr- Circle": "Shapesanity Stitched Mixed", + "bpr- Square": "Shapesanity Stitched Mixed", + "bpr- Star": "Shapesanity Stitched Mixed", + "bpr- Windmill": "Shapesanity Stitched Mixed", + "bpuw Circle": "Shapesanity Colorful Full Mixed", + "bpuw Square": "Shapesanity Colorful Full Mixed", + "bpuw Star": "Shapesanity Colorful Full Mixed", + "bpuw Windmill": "Shapesanity Colorful East Windmill Mixed", + "bpuy Circle": "Shapesanity Colorful Full Mixed", + "bpuy Square": "Shapesanity Colorful Full Mixed", + "bpuy Star": "Shapesanity Colorful Full Mixed", + "bpuy Windmill": "Shapesanity Colorful East Windmill Mixed", + "bpu- Circle": "Shapesanity Stitched Mixed", + "bpu- Square": "Shapesanity Stitched Mixed", + "bpu- Star": "Shapesanity Stitched Mixed", + "bpu- Windmill": "Shapesanity Stitched Mixed", + "bpwy Circle": "Shapesanity Colorful Full Mixed", + "bpwy Square": "Shapesanity Colorful Full Mixed", + "bpwy Star": "Shapesanity Colorful Full Mixed", + "bpwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "bpw- Circle": "Shapesanity Stitched Mixed", + "bpw- Square": "Shapesanity Stitched Mixed", + "bpw- Star": "Shapesanity Stitched Mixed", + "bpw- Windmill": "Shapesanity Stitched Mixed", + "bpy- Circle": "Shapesanity Stitched Mixed", + "bpy- Square": "Shapesanity Stitched Mixed", + "bpy- Star": "Shapesanity Stitched Mixed", + "bpy- Windmill": "Shapesanity Stitched Mixed", + "bruw Circle": "Shapesanity Colorful Full Mixed", + "bruw Square": "Shapesanity Colorful Full Mixed", + "bruw Star": "Shapesanity Colorful Full Mixed", + "bruw Windmill": "Shapesanity Colorful East Windmill Mixed", + "bruy Circle": "Shapesanity Colorful Full Mixed", + "bruy Square": "Shapesanity Colorful Full Mixed", + "bruy Star": "Shapesanity Colorful Full Mixed", + "bruy Windmill": "Shapesanity Colorful East Windmill Mixed", + "bru- Circle": "Shapesanity Stitched Painted", + "bru- Square": "Shapesanity Stitched Painted", + "bru- Star": "Shapesanity Stitched Painted", + "bru- Windmill": "Shapesanity Stitched Painted", + "brwy Circle": "Shapesanity Colorful Full Mixed", + "brwy Square": "Shapesanity Colorful Full Mixed", + "brwy Star": "Shapesanity Colorful Full Mixed", + "brwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "brw- Circle": "Shapesanity Stitched Mixed", + "brw- Square": "Shapesanity Stitched Mixed", + "brw- Star": "Shapesanity Stitched Mixed", + "brw- Windmill": "Shapesanity Stitched Mixed", + "bry- Circle": "Shapesanity Stitched Mixed", + "bry- Square": "Shapesanity Stitched Mixed", + "bry- Star": "Shapesanity Stitched Mixed", + "bry- Windmill": "Shapesanity Stitched Mixed", + "buwy Circle": "Shapesanity Colorful Full Mixed", + "buwy Square": "Shapesanity Colorful Full Mixed", + "buwy Star": "Shapesanity Colorful Full Mixed", + "buwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "buw- Circle": "Shapesanity Stitched Mixed", + "buw- Square": "Shapesanity Stitched Mixed", + "buw- Star": "Shapesanity Stitched Mixed", + "buw- Windmill": "Shapesanity Stitched Mixed", + "buy- Circle": "Shapesanity Stitched Mixed", + "buy- Square": "Shapesanity Stitched Mixed", + "buy- Star": "Shapesanity Stitched Mixed", + "buy- Windmill": "Shapesanity Stitched Mixed", + "bwy- Circle": "Shapesanity Stitched Mixed", + "bwy- Square": "Shapesanity Stitched Mixed", + "bwy- Star": "Shapesanity Stitched Mixed", + "bwy- Windmill": "Shapesanity Stitched Mixed", + "cgpr Circle": "Shapesanity Colorful Full Mixed", + "cgpr Square": "Shapesanity Colorful Full Mixed", + "cgpr Star": "Shapesanity Colorful Full Mixed", + "cgpr Windmill": "Shapesanity Colorful East Windmill Mixed", + "cgpu Circle": "Shapesanity Colorful Full Mixed", + "cgpu Square": "Shapesanity Colorful Full Mixed", + "cgpu Star": "Shapesanity Colorful Full Mixed", + "cgpu Windmill": "Shapesanity Colorful East Windmill Mixed", + "cgpw Circle": "Shapesanity Colorful Full Mixed", + "cgpw Square": "Shapesanity Colorful Full Mixed", + "cgpw Star": "Shapesanity Colorful Full Mixed", + "cgpw Windmill": "Shapesanity Colorful East Windmill Mixed", + "cgpy Circle": "Shapesanity Colorful Full Mixed", + "cgpy Square": "Shapesanity Colorful Full Mixed", + "cgpy Star": "Shapesanity Colorful Full Mixed", + "cgpy Windmill": "Shapesanity Colorful East Windmill Mixed", + "cgp- Circle": "Shapesanity Stitched Mixed", + "cgp- Square": "Shapesanity Stitched Mixed", + "cgp- Star": "Shapesanity Stitched Mixed", + "cgp- Windmill": "Shapesanity Stitched Mixed", + "cgru Circle": "Shapesanity Colorful Full Mixed", + "cgru Square": "Shapesanity Colorful Full Mixed", + "cgru Star": "Shapesanity Colorful Full Mixed", + "cgru Windmill": "Shapesanity Colorful East Windmill Mixed", + "cgrw Circle": "Shapesanity Colorful Full Mixed", + "cgrw Square": "Shapesanity Colorful Full Mixed", + "cgrw Star": "Shapesanity Colorful Full Mixed", + "cgrw Windmill": "Shapesanity Colorful East Windmill Mixed", + "cgry Circle": "Shapesanity Colorful Full Mixed", + "cgry Square": "Shapesanity Colorful Full Mixed", + "cgry Star": "Shapesanity Colorful Full Mixed", + "cgry Windmill": "Shapesanity Colorful East Windmill Mixed", + "cgr- Circle": "Shapesanity Stitched Mixed", + "cgr- Square": "Shapesanity Stitched Mixed", + "cgr- Star": "Shapesanity Stitched Mixed", + "cgr- Windmill": "Shapesanity Stitched Mixed", + "cguw Circle": "Shapesanity Colorful Full Mixed", + "cguw Square": "Shapesanity Colorful Full Mixed", + "cguw Star": "Shapesanity Colorful Full Mixed", + "cguw Windmill": "Shapesanity Colorful East Windmill Mixed", + "cguy Circle": "Shapesanity Colorful Full Mixed", + "cguy Square": "Shapesanity Colorful Full Mixed", + "cguy Star": "Shapesanity Colorful Full Mixed", + "cguy Windmill": "Shapesanity Colorful East Windmill Mixed", + "cgu- Circle": "Shapesanity Stitched Mixed", + "cgu- Square": "Shapesanity Stitched Mixed", + "cgu- Star": "Shapesanity Stitched Mixed", + "cgu- Windmill": "Shapesanity Stitched Mixed", + "cgwy Circle": "Shapesanity Colorful Full Mixed", + "cgwy Square": "Shapesanity Colorful Full Mixed", + "cgwy Star": "Shapesanity Colorful Full Mixed", + "cgwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "cgw- Circle": "Shapesanity Stitched Mixed", + "cgw- Square": "Shapesanity Stitched Mixed", + "cgw- Star": "Shapesanity Stitched Mixed", + "cgw- Windmill": "Shapesanity Stitched Mixed", + "cgy- Circle": "Shapesanity Stitched Mixed", + "cgy- Square": "Shapesanity Stitched Mixed", + "cgy- Star": "Shapesanity Stitched Mixed", + "cgy- Windmill": "Shapesanity Stitched Mixed", + "cpru Circle": "Shapesanity Colorful Full Mixed", + "cpru Square": "Shapesanity Colorful Full Mixed", + "cpru Star": "Shapesanity Colorful Full Mixed", + "cpru Windmill": "Shapesanity Colorful East Windmill Mixed", + "cprw Circle": "Shapesanity Colorful Full Mixed", + "cprw Square": "Shapesanity Colorful Full Mixed", + "cprw Star": "Shapesanity Colorful Full Mixed", + "cprw Windmill": "Shapesanity Colorful East Windmill Mixed", + "cpry Circle": "Shapesanity Colorful Full Mixed", + "cpry Square": "Shapesanity Colorful Full Mixed", + "cpry Star": "Shapesanity Colorful Full Mixed", + "cpry Windmill": "Shapesanity Colorful East Windmill Mixed", + "cpr- Circle": "Shapesanity Stitched Mixed", + "cpr- Square": "Shapesanity Stitched Mixed", + "cpr- Star": "Shapesanity Stitched Mixed", + "cpr- Windmill": "Shapesanity Stitched Mixed", + "cpuw Circle": "Shapesanity Colorful Full Mixed", + "cpuw Square": "Shapesanity Colorful Full Mixed", + "cpuw Star": "Shapesanity Colorful Full Mixed", + "cpuw Windmill": "Shapesanity Colorful East Windmill Mixed", + "cpuy Circle": "Shapesanity Colorful Full Mixed", + "cpuy Square": "Shapesanity Colorful Full Mixed", + "cpuy Star": "Shapesanity Colorful Full Mixed", + "cpuy Windmill": "Shapesanity Colorful East Windmill Mixed", + "cpu- Circle": "Shapesanity Stitched Mixed", + "cpu- Square": "Shapesanity Stitched Mixed", + "cpu- Star": "Shapesanity Stitched Mixed", + "cpu- Windmill": "Shapesanity Stitched Mixed", + "cpwy Circle": "Shapesanity Colorful Full Mixed", + "cpwy Square": "Shapesanity Colorful Full Mixed", + "cpwy Star": "Shapesanity Colorful Full Mixed", + "cpwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "cpw- Circle": "Shapesanity Stitched Mixed", + "cpw- Square": "Shapesanity Stitched Mixed", + "cpw- Star": "Shapesanity Stitched Mixed", + "cpw- Windmill": "Shapesanity Stitched Mixed", + "cpy- Circle": "Shapesanity Stitched Mixed", + "cpy- Square": "Shapesanity Stitched Mixed", + "cpy- Star": "Shapesanity Stitched Mixed", + "cpy- Windmill": "Shapesanity Stitched Mixed", + "cruw Circle": "Shapesanity Colorful Full Mixed", + "cruw Square": "Shapesanity Colorful Full Mixed", + "cruw Star": "Shapesanity Colorful Full Mixed", + "cruw Windmill": "Shapesanity Colorful East Windmill Mixed", + "cruy Circle": "Shapesanity Colorful Full Mixed", + "cruy Square": "Shapesanity Colorful Full Mixed", + "cruy Star": "Shapesanity Colorful Full Mixed", + "cruy Windmill": "Shapesanity Colorful East Windmill Mixed", + "cru- Circle": "Shapesanity Stitched Mixed", + "cru- Square": "Shapesanity Stitched Mixed", + "cru- Star": "Shapesanity Stitched Mixed", + "cru- Windmill": "Shapesanity Stitched Mixed", + "crwy Circle": "Shapesanity Colorful Full Mixed", + "crwy Square": "Shapesanity Colorful Full Mixed", + "crwy Star": "Shapesanity Colorful Full Mixed", + "crwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "crw- Circle": "Shapesanity Stitched Mixed", + "crw- Square": "Shapesanity Stitched Mixed", + "crw- Star": "Shapesanity Stitched Mixed", + "crw- Windmill": "Shapesanity Stitched Mixed", + "cry- Circle": "Shapesanity Stitched Mixed", + "cry- Square": "Shapesanity Stitched Mixed", + "cry- Star": "Shapesanity Stitched Mixed", + "cry- Windmill": "Shapesanity Stitched Mixed", + "cuwy Circle": "Shapesanity Colorful Full Mixed", + "cuwy Square": "Shapesanity Colorful Full Mixed", + "cuwy Star": "Shapesanity Colorful Full Mixed", + "cuwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "cuw- Circle": "Shapesanity Stitched Mixed", + "cuw- Square": "Shapesanity Stitched Mixed", + "cuw- Star": "Shapesanity Stitched Mixed", + "cuw- Windmill": "Shapesanity Stitched Mixed", + "cuy- Circle": "Shapesanity Stitched Mixed", + "cuy- Square": "Shapesanity Stitched Mixed", + "cuy- Star": "Shapesanity Stitched Mixed", + "cuy- Windmill": "Shapesanity Stitched Mixed", + "cwy- Circle": "Shapesanity Stitched Mixed", + "cwy- Square": "Shapesanity Stitched Mixed", + "cwy- Star": "Shapesanity Stitched Mixed", + "cwy- Windmill": "Shapesanity Stitched Mixed", + "gpru Circle": "Shapesanity Colorful Full Mixed", + "gpru Square": "Shapesanity Colorful Full Mixed", + "gpru Star": "Shapesanity Colorful Full Mixed", + "gpru Windmill": "Shapesanity Colorful East Windmill Mixed", + "gprw Circle": "Shapesanity Colorful Full Mixed", + "gprw Square": "Shapesanity Colorful Full Mixed", + "gprw Star": "Shapesanity Colorful Full Mixed", + "gprw Windmill": "Shapesanity Colorful East Windmill Mixed", + "gpry Circle": "Shapesanity Colorful Full Mixed", + "gpry Square": "Shapesanity Colorful Full Mixed", + "gpry Star": "Shapesanity Colorful Full Mixed", + "gpry Windmill": "Shapesanity Colorful East Windmill Mixed", + "gpr- Circle": "Shapesanity Stitched Mixed", + "gpr- Square": "Shapesanity Stitched Mixed", + "gpr- Star": "Shapesanity Stitched Mixed", + "gpr- Windmill": "Shapesanity Stitched Mixed", + "gpuw Circle": "Shapesanity Colorful Full Mixed", + "gpuw Square": "Shapesanity Colorful Full Mixed", + "gpuw Star": "Shapesanity Colorful Full Mixed", + "gpuw Windmill": "Shapesanity Colorful East Windmill Mixed", + "gpuy Circle": "Shapesanity Colorful Full Mixed", + "gpuy Square": "Shapesanity Colorful Full Mixed", + "gpuy Star": "Shapesanity Colorful Full Mixed", + "gpuy Windmill": "Shapesanity Colorful East Windmill Mixed", + "gpu- Circle": "Shapesanity Stitched Mixed", + "gpu- Square": "Shapesanity Stitched Mixed", + "gpu- Star": "Shapesanity Stitched Mixed", + "gpu- Windmill": "Shapesanity Stitched Mixed", + "gpwy Circle": "Shapesanity Colorful Full Mixed", + "gpwy Square": "Shapesanity Colorful Full Mixed", + "gpwy Star": "Shapesanity Colorful Full Mixed", + "gpwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "gpw- Circle": "Shapesanity Stitched Mixed", + "gpw- Square": "Shapesanity Stitched Mixed", + "gpw- Star": "Shapesanity Stitched Mixed", + "gpw- Windmill": "Shapesanity Stitched Mixed", + "gpy- Circle": "Shapesanity Stitched Mixed", + "gpy- Square": "Shapesanity Stitched Mixed", + "gpy- Star": "Shapesanity Stitched Mixed", + "gpy- Windmill": "Shapesanity Stitched Mixed", + "gruw Circle": "Shapesanity Colorful Full Mixed", + "gruw Square": "Shapesanity Colorful Full Mixed", + "gruw Star": "Shapesanity Colorful Full Mixed", + "gruw Windmill": "Shapesanity Colorful East Windmill Mixed", + "gruy Circle": "Shapesanity Colorful Full Mixed", + "gruy Square": "Shapesanity Colorful Full Mixed", + "gruy Star": "Shapesanity Colorful Full Mixed", + "gruy Windmill": "Shapesanity Colorful East Windmill Mixed", + "gru- Circle": "Shapesanity Stitched Painted", + "gru- Square": "Shapesanity Stitched Painted", + "gru- Star": "Shapesanity Stitched Painted", + "gru- Windmill": "Shapesanity Stitched Painted", + "grwy Circle": "Shapesanity Colorful Full Mixed", + "grwy Square": "Shapesanity Colorful Full Mixed", + "grwy Star": "Shapesanity Colorful Full Mixed", + "grwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "grw- Circle": "Shapesanity Stitched Mixed", + "grw- Square": "Shapesanity Stitched Mixed", + "grw- Star": "Shapesanity Stitched Mixed", + "grw- Windmill": "Shapesanity Stitched Mixed", + "gry- Circle": "Shapesanity Stitched Mixed", + "gry- Square": "Shapesanity Stitched Mixed", + "gry- Star": "Shapesanity Stitched Mixed", + "gry- Windmill": "Shapesanity Stitched Mixed", + "guwy Circle": "Shapesanity Colorful Full Mixed", + "guwy Square": "Shapesanity Colorful Full Mixed", + "guwy Star": "Shapesanity Colorful Full Mixed", + "guwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "guw- Circle": "Shapesanity Stitched Mixed", + "guw- Square": "Shapesanity Stitched Mixed", + "guw- Star": "Shapesanity Stitched Mixed", + "guw- Windmill": "Shapesanity Stitched Mixed", + "guy- Circle": "Shapesanity Stitched Mixed", + "guy- Square": "Shapesanity Stitched Mixed", + "guy- Star": "Shapesanity Stitched Mixed", + "guy- Windmill": "Shapesanity Stitched Mixed", + "gwy- Circle": "Shapesanity Stitched Mixed", + "gwy- Square": "Shapesanity Stitched Mixed", + "gwy- Star": "Shapesanity Stitched Mixed", + "gwy- Windmill": "Shapesanity Stitched Mixed", + "pruw Circle": "Shapesanity Colorful Full Mixed", + "pruw Square": "Shapesanity Colorful Full Mixed", + "pruw Star": "Shapesanity Colorful Full Mixed", + "pruw Windmill": "Shapesanity Colorful East Windmill Mixed", + "pruy Circle": "Shapesanity Colorful Full Mixed", + "pruy Square": "Shapesanity Colorful Full Mixed", + "pruy Star": "Shapesanity Colorful Full Mixed", + "pruy Windmill": "Shapesanity Colorful East Windmill Mixed", + "pru- Circle": "Shapesanity Stitched Mixed", + "pru- Square": "Shapesanity Stitched Mixed", + "pru- Star": "Shapesanity Stitched Mixed", + "pru- Windmill": "Shapesanity Stitched Mixed", + "prwy Circle": "Shapesanity Colorful Full Mixed", + "prwy Square": "Shapesanity Colorful Full Mixed", + "prwy Star": "Shapesanity Colorful Full Mixed", + "prwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "prw- Circle": "Shapesanity Stitched Mixed", + "prw- Square": "Shapesanity Stitched Mixed", + "prw- Star": "Shapesanity Stitched Mixed", + "prw- Windmill": "Shapesanity Stitched Mixed", + "pry- Circle": "Shapesanity Stitched Mixed", + "pry- Square": "Shapesanity Stitched Mixed", + "pry- Star": "Shapesanity Stitched Mixed", + "pry- Windmill": "Shapesanity Stitched Mixed", + "puwy Circle": "Shapesanity Colorful Full Mixed", + "puwy Square": "Shapesanity Colorful Full Mixed", + "puwy Star": "Shapesanity Colorful Full Mixed", + "puwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "puw- Circle": "Shapesanity Stitched Mixed", + "puw- Square": "Shapesanity Stitched Mixed", + "puw- Star": "Shapesanity Stitched Mixed", + "puw- Windmill": "Shapesanity Stitched Mixed", + "puy- Circle": "Shapesanity Stitched Mixed", + "puy- Square": "Shapesanity Stitched Mixed", + "puy- Star": "Shapesanity Stitched Mixed", + "puy- Windmill": "Shapesanity Stitched Mixed", + "pwy- Circle": "Shapesanity Stitched Mixed", + "pwy- Square": "Shapesanity Stitched Mixed", + "pwy- Star": "Shapesanity Stitched Mixed", + "pwy- Windmill": "Shapesanity Stitched Mixed", + "ruwy Circle": "Shapesanity Colorful Full Mixed", + "ruwy Square": "Shapesanity Colorful Full Mixed", + "ruwy Star": "Shapesanity Colorful Full Mixed", + "ruwy Windmill": "Shapesanity Colorful East Windmill Mixed", + "ruw- Circle": "Shapesanity Stitched Mixed", + "ruw- Square": "Shapesanity Stitched Mixed", + "ruw- Star": "Shapesanity Stitched Mixed", + "ruw- Windmill": "Shapesanity Stitched Mixed", + "ruy- Circle": "Shapesanity Stitched Mixed", + "ruy- Square": "Shapesanity Stitched Mixed", + "ruy- Star": "Shapesanity Stitched Mixed", + "ruy- Windmill": "Shapesanity Stitched Mixed", + "rwy- Circle": "Shapesanity Stitched Mixed", + "rwy- Square": "Shapesanity Stitched Mixed", + "rwy- Star": "Shapesanity Stitched Mixed", + "rwy- Windmill": "Shapesanity Stitched Mixed", + "uwy- Circle": "Shapesanity Stitched Mixed", + "uwy- Square": "Shapesanity Stitched Mixed", + "uwy- Star": "Shapesanity Stitched Mixed", + "uwy- Windmill": "Shapesanity Stitched Mixed", + "Red CRSW": "Shapesanity Stitched Painted", + "Blue CRSW": "Shapesanity Stitched Painted", + "Green CRSW": "Shapesanity Stitched Painted", + "Yellow CRSW": "Shapesanity Stitched Mixed", + "Purple CRSW": "Shapesanity Stitched Mixed", + "Cyan CRSW": "Shapesanity Stitched Mixed", + "White CRSW": "Shapesanity Stitched Mixed", + "Uncolored CRSW": "Shapesanity Stitched Uncolored", + "Red CRS-": "Shapesanity Stitched Painted", + "Blue CRS-": "Shapesanity Stitched Painted", + "Green CRS-": "Shapesanity Stitched Painted", + "Yellow CRS-": "Shapesanity Stitched Mixed", + "Purple CRS-": "Shapesanity Stitched Mixed", + "Cyan CRS-": "Shapesanity Stitched Mixed", + "White CRS-": "Shapesanity Stitched Mixed", + "Uncolored CRS-": "Shapesanity Stitched Uncolored", + "Red CRW-": "Shapesanity Stitched Painted", + "Blue CRW-": "Shapesanity Stitched Painted", + "Green CRW-": "Shapesanity Stitched Painted", + "Yellow CRW-": "Shapesanity Stitched Mixed", + "Purple CRW-": "Shapesanity Stitched Mixed", + "Cyan CRW-": "Shapesanity Stitched Mixed", + "White CRW-": "Shapesanity Stitched Mixed", + "Uncolored CRW-": "Shapesanity Stitched Uncolored", + "Red CSW-": "Shapesanity Stitched Painted", + "Blue CSW-": "Shapesanity Stitched Painted", + "Green CSW-": "Shapesanity Stitched Painted", + "Yellow CSW-": "Shapesanity Stitched Mixed", + "Purple CSW-": "Shapesanity Stitched Mixed", + "Cyan CSW-": "Shapesanity Stitched Mixed", + "White CSW-": "Shapesanity Stitched Mixed", + "Uncolored CSW-": "Shapesanity Stitched Uncolored", + "Red RSW-": "Shapesanity Stitched Painted", + "Blue RSW-": "Shapesanity Stitched Painted", + "Green RSW-": "Shapesanity Stitched Painted", + "Yellow RSW-": "Shapesanity Stitched Mixed", + "Purple RSW-": "Shapesanity Stitched Mixed", + "Cyan RSW-": "Shapesanity Stitched Mixed", + "White RSW-": "Shapesanity Stitched Mixed", + "Uncolored RSW-": "Shapesanity Stitched Uncolored", +} + +shapesanity_two_sided = { + "3-1 Cb Cc": "Shapesanity Colorful Full Mixed", + "Half-Half Cb Cc": "Shapesanity Colorful Full Mixed", + "Checkered Cb Cc": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cb Cc": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Cc": "Shapesanity Stitched Mixed", + "3-1 Cb Cg": "Shapesanity Colorful Full Painted", + "Half-Half Cb Cg": "Shapesanity Colorful Full Painted", + "Checkered Cb Cg": "Shapesanity Colorful Full Painted", + "Adjacent Singles Cb Cg": "Shapesanity Colorful Half Painted", + "Cornered Singles Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Cg": "Shapesanity Stitched Painted", + "3-1 Cb Cp": "Shapesanity Colorful Full Mixed", + "Half-Half Cb Cp": "Shapesanity Colorful Full Mixed", + "Checkered Cb Cp": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cb Cp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Cp": "Shapesanity Stitched Mixed", + "3-1 Cb Cr": "Shapesanity Colorful Full Painted", + "Half-Half Cb Cr": "Shapesanity Colorful Full Painted", + "Checkered Cb Cr": "Shapesanity Colorful Full Painted", + "Adjacent Singles Cb Cr": "Shapesanity Colorful Half Painted", + "Cornered Singles Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Cr": "Shapesanity Stitched Painted", + "3-1 Cb Cu": "Shapesanity Colorful Full Painted", + "Half-Half Cb Cu": "Shapesanity Colorful Full Painted", + "Checkered Cb Cu": "Shapesanity Colorful Full Painted", + "Adjacent Singles Cb Cu": "Shapesanity Colorful Half Painted", + "Cornered Singles Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Cu": "Shapesanity Stitched Painted", + "3-1 Cb Cw": "Shapesanity Colorful Full Mixed", + "Half-Half Cb Cw": "Shapesanity Colorful Full Mixed", + "Checkered Cb Cw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cb Cw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Cw": "Shapesanity Stitched Mixed", + "3-1 Cb Cy": "Shapesanity Colorful Full Mixed", + "Half-Half Cb Cy": "Shapesanity Colorful Full Mixed", + "Checkered Cb Cy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cb Cy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Cy": "Shapesanity Stitched Mixed", + "3-1 Cb Rb": "Shapesanity Stitched Painted", + "Half-Half Cb Rb": "Shapesanity Half-Half Painted", + "Checkered Cb Rb": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Rb": "Shapesanity Stitched Painted", + "Cornered Singles Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Rb": "Shapesanity Stitched Painted", + "3-1 Cb Rc": "Shapesanity Stitched Mixed", + "Half-Half Cb Rc": "Shapesanity Half-Half Mixed", + "Checkered Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Rc": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Rc": "Shapesanity Stitched Mixed", + "3-1 Cb Rg": "Shapesanity Stitched Painted", + "Half-Half Cb Rg": "Shapesanity Half-Half Painted", + "Checkered Cb Rg": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Rg": "Shapesanity Stitched Painted", + "Cornered Singles Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Rg": "Shapesanity Stitched Painted", + "3-1 Cb Rp": "Shapesanity Stitched Mixed", + "Half-Half Cb Rp": "Shapesanity Half-Half Mixed", + "Checkered Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Rp": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Rp": "Shapesanity Stitched Mixed", + "3-1 Cb Rr": "Shapesanity Stitched Painted", + "Half-Half Cb Rr": "Shapesanity Half-Half Painted", + "Checkered Cb Rr": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Rr": "Shapesanity Stitched Painted", + "Cornered Singles Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Rr": "Shapesanity Stitched Painted", + "3-1 Cb Ru": "Shapesanity Stitched Painted", + "Half-Half Cb Ru": "Shapesanity Half-Half Painted", + "Checkered Cb Ru": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Ru": "Shapesanity Stitched Painted", + "Cornered Singles Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Ru": "Shapesanity Stitched Painted", + "3-1 Cb Rw": "Shapesanity Stitched Mixed", + "Half-Half Cb Rw": "Shapesanity Half-Half Mixed", + "Checkered Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Rw": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Rw": "Shapesanity Stitched Mixed", + "3-1 Cb Ry": "Shapesanity Stitched Mixed", + "Half-Half Cb Ry": "Shapesanity Half-Half Mixed", + "Checkered Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Ry": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Ry": "Shapesanity Stitched Mixed", + "3-1 Cb Sb": "Shapesanity Stitched Painted", + "Half-Half Cb Sb": "Shapesanity Half-Half Painted", + "Checkered Cb Sb": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Sb": "Shapesanity Stitched Painted", + "Cornered Singles Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Sb": "Shapesanity Stitched Painted", + "3-1 Cb Sc": "Shapesanity Stitched Mixed", + "Half-Half Cb Sc": "Shapesanity Half-Half Mixed", + "Checkered Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Sc": "Shapesanity Stitched Mixed", + "3-1 Cb Sg": "Shapesanity Stitched Painted", + "Half-Half Cb Sg": "Shapesanity Half-Half Painted", + "Checkered Cb Sg": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Sg": "Shapesanity Stitched Painted", + "Cornered Singles Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Sg": "Shapesanity Stitched Painted", + "3-1 Cb Sp": "Shapesanity Stitched Mixed", + "Half-Half Cb Sp": "Shapesanity Half-Half Mixed", + "Checkered Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Sp": "Shapesanity Stitched Mixed", + "3-1 Cb Sr": "Shapesanity Stitched Painted", + "Half-Half Cb Sr": "Shapesanity Half-Half Painted", + "Checkered Cb Sr": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Sr": "Shapesanity Stitched Painted", + "Cornered Singles Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Sr": "Shapesanity Stitched Painted", + "3-1 Cb Su": "Shapesanity Stitched Painted", + "Half-Half Cb Su": "Shapesanity Half-Half Painted", + "Checkered Cb Su": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Su": "Shapesanity Stitched Painted", + "Cornered Singles Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Su": "Shapesanity Stitched Painted", + "3-1 Cb Sw": "Shapesanity Stitched Mixed", + "Half-Half Cb Sw": "Shapesanity Half-Half Mixed", + "Checkered Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Sw": "Shapesanity Stitched Mixed", + "3-1 Cb Sy": "Shapesanity Stitched Mixed", + "Half-Half Cb Sy": "Shapesanity Half-Half Mixed", + "Checkered Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Sy": "Shapesanity Stitched Mixed", + "3-1 Cb Wb": "Shapesanity Stitched Painted", + "Half-Half Cb Wb": "Shapesanity Half-Half Painted", + "Checkered Cb Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Wb": "Shapesanity Stitched Painted", + "Cornered Singles Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Wb": "Shapesanity Stitched Painted", + "3-1 Cb Wc": "Shapesanity Stitched Mixed", + "Half-Half Cb Wc": "Shapesanity Half-Half Mixed", + "Checkered Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Wc": "Shapesanity Stitched Mixed", + "3-1 Cb Wg": "Shapesanity Stitched Painted", + "Half-Half Cb Wg": "Shapesanity Half-Half Painted", + "Checkered Cb Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Wg": "Shapesanity Stitched Painted", + "Cornered Singles Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Wg": "Shapesanity Stitched Painted", + "3-1 Cb Wp": "Shapesanity Stitched Mixed", + "Half-Half Cb Wp": "Shapesanity Half-Half Mixed", + "Checkered Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Wp": "Shapesanity Stitched Mixed", + "3-1 Cb Wr": "Shapesanity Stitched Painted", + "Half-Half Cb Wr": "Shapesanity Half-Half Painted", + "Checkered Cb Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Wr": "Shapesanity Stitched Painted", + "Cornered Singles Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Wr": "Shapesanity Stitched Painted", + "3-1 Cb Wu": "Shapesanity Stitched Painted", + "Half-Half Cb Wu": "Shapesanity Half-Half Painted", + "Checkered Cb Wu": "Shapesanity Stitched Painted", + "Adjacent Singles Cb Wu": "Shapesanity Stitched Painted", + "Cornered Singles Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Cb Wu": "Shapesanity Stitched Painted", + "3-1 Cb Ww": "Shapesanity Stitched Mixed", + "Half-Half Cb Ww": "Shapesanity Half-Half Mixed", + "Checkered Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Ww": "Shapesanity Stitched Mixed", + "3-1 Cb Wy": "Shapesanity Stitched Mixed", + "Half-Half Cb Wy": "Shapesanity Half-Half Mixed", + "Checkered Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cb Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cb Wy": "Shapesanity Stitched Mixed", + "3-1 Cc Cb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cc Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Cb": "Shapesanity Stitched Mixed", + "3-1 Cc Cg": "Shapesanity Colorful Full Mixed", + "Half-Half Cc Cg": "Shapesanity Colorful Full Mixed", + "Checkered Cc Cg": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cc Cg": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Cg": "Shapesanity Stitched Mixed", + "3-1 Cc Cp": "Shapesanity Colorful Full Mixed", + "Half-Half Cc Cp": "Shapesanity Colorful Full Mixed", + "Checkered Cc Cp": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cc Cp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Cp": "Shapesanity Stitched Mixed", + "3-1 Cc Cr": "Shapesanity Colorful Full Mixed", + "Half-Half Cc Cr": "Shapesanity Colorful Full Mixed", + "Checkered Cc Cr": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cc Cr": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Cr": "Shapesanity Stitched Mixed", + "3-1 Cc Cu": "Shapesanity Colorful Full Mixed", + "Half-Half Cc Cu": "Shapesanity Colorful Full Mixed", + "Checkered Cc Cu": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cc Cu": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Cu": "Shapesanity Stitched Mixed", + "3-1 Cc Cw": "Shapesanity Colorful Full Mixed", + "Half-Half Cc Cw": "Shapesanity Colorful Full Mixed", + "Checkered Cc Cw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cc Cw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Cw": "Shapesanity Stitched Mixed", + "3-1 Cc Cy": "Shapesanity Colorful Full Mixed", + "Half-Half Cc Cy": "Shapesanity Colorful Full Mixed", + "Checkered Cc Cy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cc Cy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Cy": "Shapesanity Stitched Mixed", + "3-1 Cc Rb": "Shapesanity Stitched Mixed", + "Half-Half Cc Rb": "Shapesanity Half-Half Mixed", + "Checkered Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Rb": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Rb": "Shapesanity Stitched Mixed", + "3-1 Cc Rc": "Shapesanity Stitched Mixed", + "Half-Half Cc Rc": "Shapesanity Half-Half Mixed", + "Checkered Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Rc": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Rc": "Shapesanity Stitched Mixed", + "3-1 Cc Rg": "Shapesanity Stitched Mixed", + "Half-Half Cc Rg": "Shapesanity Half-Half Mixed", + "Checkered Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Rg": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Rg": "Shapesanity Stitched Mixed", + "3-1 Cc Rp": "Shapesanity Stitched Mixed", + "Half-Half Cc Rp": "Shapesanity Half-Half Mixed", + "Checkered Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Rp": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Rp": "Shapesanity Stitched Mixed", + "3-1 Cc Rr": "Shapesanity Stitched Mixed", + "Half-Half Cc Rr": "Shapesanity Half-Half Mixed", + "Checkered Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Rr": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Rr": "Shapesanity Stitched Mixed", + "3-1 Cc Ru": "Shapesanity Stitched Mixed", + "Half-Half Cc Ru": "Shapesanity Half-Half Mixed", + "Checkered Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Ru": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Ru": "Shapesanity Stitched Mixed", + "3-1 Cc Rw": "Shapesanity Stitched Mixed", + "Half-Half Cc Rw": "Shapesanity Half-Half Mixed", + "Checkered Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Rw": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Rw": "Shapesanity Stitched Mixed", + "3-1 Cc Ry": "Shapesanity Stitched Mixed", + "Half-Half Cc Ry": "Shapesanity Half-Half Mixed", + "Checkered Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Ry": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Ry": "Shapesanity Stitched Mixed", + "3-1 Cc Sb": "Shapesanity Stitched Mixed", + "Half-Half Cc Sb": "Shapesanity Half-Half Mixed", + "Checkered Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Sb": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Sb": "Shapesanity Stitched Mixed", + "3-1 Cc Sc": "Shapesanity Stitched Mixed", + "Half-Half Cc Sc": "Shapesanity Half-Half Mixed", + "Checkered Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Sc": "Shapesanity Stitched Mixed", + "3-1 Cc Sg": "Shapesanity Stitched Mixed", + "Half-Half Cc Sg": "Shapesanity Half-Half Mixed", + "Checkered Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Sg": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Sg": "Shapesanity Stitched Mixed", + "3-1 Cc Sp": "Shapesanity Stitched Mixed", + "Half-Half Cc Sp": "Shapesanity Half-Half Mixed", + "Checkered Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Sp": "Shapesanity Stitched Mixed", + "3-1 Cc Sr": "Shapesanity Stitched Mixed", + "Half-Half Cc Sr": "Shapesanity Half-Half Mixed", + "Checkered Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Sr": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Sr": "Shapesanity Stitched Mixed", + "3-1 Cc Su": "Shapesanity Stitched Mixed", + "Half-Half Cc Su": "Shapesanity Half-Half Mixed", + "Checkered Cc Su": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Su": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Su": "Shapesanity Stitched Mixed", + "3-1 Cc Sw": "Shapesanity Stitched Mixed", + "Half-Half Cc Sw": "Shapesanity Half-Half Mixed", + "Checkered Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Sw": "Shapesanity Stitched Mixed", + "3-1 Cc Sy": "Shapesanity Stitched Mixed", + "Half-Half Cc Sy": "Shapesanity Half-Half Mixed", + "Checkered Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Sy": "Shapesanity Stitched Mixed", + "3-1 Cc Wb": "Shapesanity Stitched Mixed", + "Half-Half Cc Wb": "Shapesanity Half-Half Mixed", + "Checkered Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Wb": "Shapesanity Stitched Mixed", + "3-1 Cc Wc": "Shapesanity Stitched Mixed", + "Half-Half Cc Wc": "Shapesanity Half-Half Mixed", + "Checkered Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Wc": "Shapesanity Stitched Mixed", + "3-1 Cc Wg": "Shapesanity Stitched Mixed", + "Half-Half Cc Wg": "Shapesanity Half-Half Mixed", + "Checkered Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Wg": "Shapesanity Stitched Mixed", + "3-1 Cc Wp": "Shapesanity Stitched Mixed", + "Half-Half Cc Wp": "Shapesanity Half-Half Mixed", + "Checkered Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Wp": "Shapesanity Stitched Mixed", + "3-1 Cc Wr": "Shapesanity Stitched Mixed", + "Half-Half Cc Wr": "Shapesanity Half-Half Mixed", + "Checkered Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Wr": "Shapesanity Stitched Mixed", + "3-1 Cc Wu": "Shapesanity Stitched Mixed", + "Half-Half Cc Wu": "Shapesanity Half-Half Mixed", + "Checkered Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Wu": "Shapesanity Stitched Mixed", + "3-1 Cc Ww": "Shapesanity Stitched Mixed", + "Half-Half Cc Ww": "Shapesanity Half-Half Mixed", + "Checkered Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Ww": "Shapesanity Stitched Mixed", + "3-1 Cc Wy": "Shapesanity Stitched Mixed", + "Half-Half Cc Wy": "Shapesanity Half-Half Mixed", + "Checkered Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cc Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cc Wy": "Shapesanity Stitched Mixed", + "3-1 Cg Cb": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Cg Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Cb": "Shapesanity Stitched Painted", + "3-1 Cg Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cg Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Cc": "Shapesanity Stitched Mixed", + "3-1 Cg Cp": "Shapesanity Colorful Full Mixed", + "Half-Half Cg Cp": "Shapesanity Colorful Full Mixed", + "Checkered Cg Cp": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cg Cp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Cp": "Shapesanity Stitched Mixed", + "3-1 Cg Cr": "Shapesanity Colorful Full Painted", + "Half-Half Cg Cr": "Shapesanity Colorful Full Painted", + "Checkered Cg Cr": "Shapesanity Colorful Full Painted", + "Adjacent Singles Cg Cr": "Shapesanity Colorful Half Painted", + "Cornered Singles Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Cr": "Shapesanity Stitched Painted", + "3-1 Cg Cu": "Shapesanity Colorful Full Painted", + "Half-Half Cg Cu": "Shapesanity Colorful Full Painted", + "Checkered Cg Cu": "Shapesanity Colorful Full Painted", + "Adjacent Singles Cg Cu": "Shapesanity Colorful Half Painted", + "Cornered Singles Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Cu": "Shapesanity Stitched Painted", + "3-1 Cg Cw": "Shapesanity Colorful Full Mixed", + "Half-Half Cg Cw": "Shapesanity Colorful Full Mixed", + "Checkered Cg Cw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cg Cw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Cw": "Shapesanity Stitched Mixed", + "3-1 Cg Cy": "Shapesanity Colorful Full Mixed", + "Half-Half Cg Cy": "Shapesanity Colorful Full Mixed", + "Checkered Cg Cy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cg Cy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Cy": "Shapesanity Stitched Mixed", + "3-1 Cg Rb": "Shapesanity Stitched Painted", + "Half-Half Cg Rb": "Shapesanity Half-Half Painted", + "Checkered Cg Rb": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Rb": "Shapesanity Stitched Painted", + "Cornered Singles Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Rb": "Shapesanity Stitched Painted", + "3-1 Cg Rc": "Shapesanity Stitched Mixed", + "Half-Half Cg Rc": "Shapesanity Half-Half Mixed", + "Checkered Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Rc": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Rc": "Shapesanity Stitched Mixed", + "3-1 Cg Rg": "Shapesanity Stitched Painted", + "Half-Half Cg Rg": "Shapesanity Half-Half Painted", + "Checkered Cg Rg": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Rg": "Shapesanity Stitched Painted", + "Cornered Singles Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Rg": "Shapesanity Stitched Painted", + "3-1 Cg Rp": "Shapesanity Stitched Mixed", + "Half-Half Cg Rp": "Shapesanity Half-Half Mixed", + "Checkered Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Rp": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Rp": "Shapesanity Stitched Mixed", + "3-1 Cg Rr": "Shapesanity Stitched Painted", + "Half-Half Cg Rr": "Shapesanity Half-Half Painted", + "Checkered Cg Rr": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Rr": "Shapesanity Stitched Painted", + "Cornered Singles Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Rr": "Shapesanity Stitched Painted", + "3-1 Cg Ru": "Shapesanity Stitched Painted", + "Half-Half Cg Ru": "Shapesanity Half-Half Painted", + "Checkered Cg Ru": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Ru": "Shapesanity Stitched Painted", + "Cornered Singles Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Ru": "Shapesanity Stitched Painted", + "3-1 Cg Rw": "Shapesanity Stitched Mixed", + "Half-Half Cg Rw": "Shapesanity Half-Half Mixed", + "Checkered Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Rw": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Rw": "Shapesanity Stitched Mixed", + "3-1 Cg Ry": "Shapesanity Stitched Mixed", + "Half-Half Cg Ry": "Shapesanity Half-Half Mixed", + "Checkered Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Ry": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Ry": "Shapesanity Stitched Mixed", + "3-1 Cg Sb": "Shapesanity Stitched Painted", + "Half-Half Cg Sb": "Shapesanity Half-Half Painted", + "Checkered Cg Sb": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Sb": "Shapesanity Stitched Painted", + "Cornered Singles Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Sb": "Shapesanity Stitched Painted", + "3-1 Cg Sc": "Shapesanity Stitched Mixed", + "Half-Half Cg Sc": "Shapesanity Half-Half Mixed", + "Checkered Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Sc": "Shapesanity Stitched Mixed", + "3-1 Cg Sg": "Shapesanity Stitched Painted", + "Half-Half Cg Sg": "Shapesanity Half-Half Painted", + "Checkered Cg Sg": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Sg": "Shapesanity Stitched Painted", + "Cornered Singles Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Sg": "Shapesanity Stitched Painted", + "3-1 Cg Sp": "Shapesanity Stitched Mixed", + "Half-Half Cg Sp": "Shapesanity Half-Half Mixed", + "Checkered Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Sp": "Shapesanity Stitched Mixed", + "3-1 Cg Sr": "Shapesanity Stitched Painted", + "Half-Half Cg Sr": "Shapesanity Half-Half Painted", + "Checkered Cg Sr": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Sr": "Shapesanity Stitched Painted", + "Cornered Singles Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Sr": "Shapesanity Stitched Painted", + "3-1 Cg Su": "Shapesanity Stitched Painted", + "Half-Half Cg Su": "Shapesanity Half-Half Painted", + "Checkered Cg Su": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Su": "Shapesanity Stitched Painted", + "Cornered Singles Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Su": "Shapesanity Stitched Painted", + "3-1 Cg Sw": "Shapesanity Stitched Mixed", + "Half-Half Cg Sw": "Shapesanity Half-Half Mixed", + "Checkered Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Sw": "Shapesanity Stitched Mixed", + "3-1 Cg Sy": "Shapesanity Stitched Mixed", + "Half-Half Cg Sy": "Shapesanity Half-Half Mixed", + "Checkered Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Sy": "Shapesanity Stitched Mixed", + "3-1 Cg Wb": "Shapesanity Stitched Painted", + "Half-Half Cg Wb": "Shapesanity Half-Half Painted", + "Checkered Cg Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Wb": "Shapesanity Stitched Painted", + "Cornered Singles Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Wb": "Shapesanity Stitched Painted", + "3-1 Cg Wc": "Shapesanity Stitched Mixed", + "Half-Half Cg Wc": "Shapesanity Half-Half Mixed", + "Checkered Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Wc": "Shapesanity Stitched Mixed", + "3-1 Cg Wg": "Shapesanity Stitched Painted", + "Half-Half Cg Wg": "Shapesanity Half-Half Painted", + "Checkered Cg Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Wg": "Shapesanity Stitched Painted", + "Cornered Singles Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Wg": "Shapesanity Stitched Painted", + "3-1 Cg Wp": "Shapesanity Stitched Mixed", + "Half-Half Cg Wp": "Shapesanity Half-Half Mixed", + "Checkered Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Wp": "Shapesanity Stitched Mixed", + "3-1 Cg Wr": "Shapesanity Stitched Painted", + "Half-Half Cg Wr": "Shapesanity Half-Half Painted", + "Checkered Cg Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Wr": "Shapesanity Stitched Painted", + "Cornered Singles Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Wr": "Shapesanity Stitched Painted", + "3-1 Cg Wu": "Shapesanity Stitched Painted", + "Half-Half Cg Wu": "Shapesanity Half-Half Painted", + "Checkered Cg Wu": "Shapesanity Stitched Painted", + "Adjacent Singles Cg Wu": "Shapesanity Stitched Painted", + "Cornered Singles Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Cg Wu": "Shapesanity Stitched Painted", + "3-1 Cg Ww": "Shapesanity Stitched Mixed", + "Half-Half Cg Ww": "Shapesanity Half-Half Mixed", + "Checkered Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Ww": "Shapesanity Stitched Mixed", + "3-1 Cg Wy": "Shapesanity Stitched Mixed", + "Half-Half Cg Wy": "Shapesanity Half-Half Mixed", + "Checkered Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cg Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cg Wy": "Shapesanity Stitched Mixed", + "3-1 Cp Cb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cp Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Cb": "Shapesanity Stitched Mixed", + "3-1 Cp Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cp Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Cc": "Shapesanity Stitched Mixed", + "3-1 Cp Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cp Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Cg": "Shapesanity Stitched Mixed", + "3-1 Cp Cr": "Shapesanity Colorful Full Mixed", + "Half-Half Cp Cr": "Shapesanity Colorful Full Mixed", + "Checkered Cp Cr": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cp Cr": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Cr": "Shapesanity Stitched Mixed", + "3-1 Cp Cu": "Shapesanity Colorful Full Mixed", + "Half-Half Cp Cu": "Shapesanity Colorful Full Mixed", + "Checkered Cp Cu": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cp Cu": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Cu": "Shapesanity Stitched Mixed", + "3-1 Cp Cw": "Shapesanity Colorful Full Mixed", + "Half-Half Cp Cw": "Shapesanity Colorful Full Mixed", + "Checkered Cp Cw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cp Cw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Cw": "Shapesanity Stitched Mixed", + "3-1 Cp Cy": "Shapesanity Colorful Full Mixed", + "Half-Half Cp Cy": "Shapesanity Colorful Full Mixed", + "Checkered Cp Cy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cp Cy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Cy": "Shapesanity Stitched Mixed", + "3-1 Cp Rb": "Shapesanity Stitched Mixed", + "Half-Half Cp Rb": "Shapesanity Half-Half Mixed", + "Checkered Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Rb": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Rb": "Shapesanity Stitched Mixed", + "3-1 Cp Rc": "Shapesanity Stitched Mixed", + "Half-Half Cp Rc": "Shapesanity Half-Half Mixed", + "Checkered Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Rc": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Rc": "Shapesanity Stitched Mixed", + "3-1 Cp Rg": "Shapesanity Stitched Mixed", + "Half-Half Cp Rg": "Shapesanity Half-Half Mixed", + "Checkered Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Rg": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Rg": "Shapesanity Stitched Mixed", + "3-1 Cp Rp": "Shapesanity Stitched Mixed", + "Half-Half Cp Rp": "Shapesanity Half-Half Mixed", + "Checkered Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Rp": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Rp": "Shapesanity Stitched Mixed", + "3-1 Cp Rr": "Shapesanity Stitched Mixed", + "Half-Half Cp Rr": "Shapesanity Half-Half Mixed", + "Checkered Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Rr": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Rr": "Shapesanity Stitched Mixed", + "3-1 Cp Ru": "Shapesanity Stitched Mixed", + "Half-Half Cp Ru": "Shapesanity Half-Half Mixed", + "Checkered Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Ru": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Ru": "Shapesanity Stitched Mixed", + "3-1 Cp Rw": "Shapesanity Stitched Mixed", + "Half-Half Cp Rw": "Shapesanity Half-Half Mixed", + "Checkered Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Rw": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Rw": "Shapesanity Stitched Mixed", + "3-1 Cp Ry": "Shapesanity Stitched Mixed", + "Half-Half Cp Ry": "Shapesanity Half-Half Mixed", + "Checkered Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Ry": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Ry": "Shapesanity Stitched Mixed", + "3-1 Cp Sb": "Shapesanity Stitched Mixed", + "Half-Half Cp Sb": "Shapesanity Half-Half Mixed", + "Checkered Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Sb": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Sb": "Shapesanity Stitched Mixed", + "3-1 Cp Sc": "Shapesanity Stitched Mixed", + "Half-Half Cp Sc": "Shapesanity Half-Half Mixed", + "Checkered Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Sc": "Shapesanity Stitched Mixed", + "3-1 Cp Sg": "Shapesanity Stitched Mixed", + "Half-Half Cp Sg": "Shapesanity Half-Half Mixed", + "Checkered Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Sg": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Sg": "Shapesanity Stitched Mixed", + "3-1 Cp Sp": "Shapesanity Stitched Mixed", + "Half-Half Cp Sp": "Shapesanity Half-Half Mixed", + "Checkered Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Sp": "Shapesanity Stitched Mixed", + "3-1 Cp Sr": "Shapesanity Stitched Mixed", + "Half-Half Cp Sr": "Shapesanity Half-Half Mixed", + "Checkered Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Sr": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Sr": "Shapesanity Stitched Mixed", + "3-1 Cp Su": "Shapesanity Stitched Mixed", + "Half-Half Cp Su": "Shapesanity Half-Half Mixed", + "Checkered Cp Su": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Su": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Su": "Shapesanity Stitched Mixed", + "3-1 Cp Sw": "Shapesanity Stitched Mixed", + "Half-Half Cp Sw": "Shapesanity Half-Half Mixed", + "Checkered Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Sw": "Shapesanity Stitched Mixed", + "3-1 Cp Sy": "Shapesanity Stitched Mixed", + "Half-Half Cp Sy": "Shapesanity Half-Half Mixed", + "Checkered Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Sy": "Shapesanity Stitched Mixed", + "3-1 Cp Wb": "Shapesanity Stitched Mixed", + "Half-Half Cp Wb": "Shapesanity Half-Half Mixed", + "Checkered Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Wb": "Shapesanity Stitched Mixed", + "3-1 Cp Wc": "Shapesanity Stitched Mixed", + "Half-Half Cp Wc": "Shapesanity Half-Half Mixed", + "Checkered Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Wc": "Shapesanity Stitched Mixed", + "3-1 Cp Wg": "Shapesanity Stitched Mixed", + "Half-Half Cp Wg": "Shapesanity Half-Half Mixed", + "Checkered Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Wg": "Shapesanity Stitched Mixed", + "3-1 Cp Wp": "Shapesanity Stitched Mixed", + "Half-Half Cp Wp": "Shapesanity Half-Half Mixed", + "Checkered Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Wp": "Shapesanity Stitched Mixed", + "3-1 Cp Wr": "Shapesanity Stitched Mixed", + "Half-Half Cp Wr": "Shapesanity Half-Half Mixed", + "Checkered Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Wr": "Shapesanity Stitched Mixed", + "3-1 Cp Wu": "Shapesanity Stitched Mixed", + "Half-Half Cp Wu": "Shapesanity Half-Half Mixed", + "Checkered Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Wu": "Shapesanity Stitched Mixed", + "3-1 Cp Ww": "Shapesanity Stitched Mixed", + "Half-Half Cp Ww": "Shapesanity Half-Half Mixed", + "Checkered Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Ww": "Shapesanity Stitched Mixed", + "3-1 Cp Wy": "Shapesanity Stitched Mixed", + "Half-Half Cp Wy": "Shapesanity Half-Half Mixed", + "Checkered Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cp Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cp Wy": "Shapesanity Stitched Mixed", + "3-1 Cr Cb": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Cr Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Cb": "Shapesanity Stitched Painted", + "3-1 Cr Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cr Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Cc": "Shapesanity Stitched Mixed", + "3-1 Cr Cg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Cr Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Cg": "Shapesanity Stitched Painted", + "3-1 Cr Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cr Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Cp": "Shapesanity Stitched Mixed", + "3-1 Cr Cu": "Shapesanity Colorful Full Painted", + "Half-Half Cr Cu": "Shapesanity Colorful Full Painted", + "Checkered Cr Cu": "Shapesanity Colorful Full Painted", + "Adjacent Singles Cr Cu": "Shapesanity Colorful Half Painted", + "Cornered Singles Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Cu": "Shapesanity Stitched Painted", + "3-1 Cr Cw": "Shapesanity Colorful Full Mixed", + "Half-Half Cr Cw": "Shapesanity Colorful Full Mixed", + "Checkered Cr Cw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cr Cw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Cw": "Shapesanity Stitched Mixed", + "3-1 Cr Cy": "Shapesanity Colorful Full Mixed", + "Half-Half Cr Cy": "Shapesanity Colorful Full Mixed", + "Checkered Cr Cy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cr Cy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Cy": "Shapesanity Stitched Mixed", + "3-1 Cr Rb": "Shapesanity Stitched Painted", + "Half-Half Cr Rb": "Shapesanity Half-Half Painted", + "Checkered Cr Rb": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Rb": "Shapesanity Stitched Painted", + "Cornered Singles Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Rb": "Shapesanity Stitched Painted", + "3-1 Cr Rc": "Shapesanity Stitched Mixed", + "Half-Half Cr Rc": "Shapesanity Half-Half Mixed", + "Checkered Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Rc": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Rc": "Shapesanity Stitched Mixed", + "3-1 Cr Rg": "Shapesanity Stitched Painted", + "Half-Half Cr Rg": "Shapesanity Half-Half Painted", + "Checkered Cr Rg": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Rg": "Shapesanity Stitched Painted", + "Cornered Singles Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Rg": "Shapesanity Stitched Painted", + "3-1 Cr Rp": "Shapesanity Stitched Mixed", + "Half-Half Cr Rp": "Shapesanity Half-Half Mixed", + "Checkered Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Rp": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Rp": "Shapesanity Stitched Mixed", + "3-1 Cr Rr": "Shapesanity Stitched Painted", + "Half-Half Cr Rr": "Shapesanity Half-Half Painted", + "Checkered Cr Rr": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Rr": "Shapesanity Stitched Painted", + "Cornered Singles Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Rr": "Shapesanity Stitched Painted", + "3-1 Cr Ru": "Shapesanity Stitched Painted", + "Half-Half Cr Ru": "Shapesanity Half-Half Painted", + "Checkered Cr Ru": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Ru": "Shapesanity Stitched Painted", + "Cornered Singles Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Ru": "Shapesanity Stitched Painted", + "3-1 Cr Rw": "Shapesanity Stitched Mixed", + "Half-Half Cr Rw": "Shapesanity Half-Half Mixed", + "Checkered Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Rw": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Rw": "Shapesanity Stitched Mixed", + "3-1 Cr Ry": "Shapesanity Stitched Mixed", + "Half-Half Cr Ry": "Shapesanity Half-Half Mixed", + "Checkered Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Ry": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Ry": "Shapesanity Stitched Mixed", + "3-1 Cr Sb": "Shapesanity Stitched Painted", + "Half-Half Cr Sb": "Shapesanity Half-Half Painted", + "Checkered Cr Sb": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Sb": "Shapesanity Stitched Painted", + "Cornered Singles Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Sb": "Shapesanity Stitched Painted", + "3-1 Cr Sc": "Shapesanity Stitched Mixed", + "Half-Half Cr Sc": "Shapesanity Half-Half Mixed", + "Checkered Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Sc": "Shapesanity Stitched Mixed", + "3-1 Cr Sg": "Shapesanity Stitched Painted", + "Half-Half Cr Sg": "Shapesanity Half-Half Painted", + "Checkered Cr Sg": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Sg": "Shapesanity Stitched Painted", + "Cornered Singles Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Sg": "Shapesanity Stitched Painted", + "3-1 Cr Sp": "Shapesanity Stitched Mixed", + "Half-Half Cr Sp": "Shapesanity Half-Half Mixed", + "Checkered Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Sp": "Shapesanity Stitched Mixed", + "3-1 Cr Sr": "Shapesanity Stitched Painted", + "Half-Half Cr Sr": "Shapesanity Half-Half Painted", + "Checkered Cr Sr": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Sr": "Shapesanity Stitched Painted", + "Cornered Singles Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Sr": "Shapesanity Stitched Painted", + "3-1 Cr Su": "Shapesanity Stitched Painted", + "Half-Half Cr Su": "Shapesanity Half-Half Painted", + "Checkered Cr Su": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Su": "Shapesanity Stitched Painted", + "Cornered Singles Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Su": "Shapesanity Stitched Painted", + "3-1 Cr Sw": "Shapesanity Stitched Mixed", + "Half-Half Cr Sw": "Shapesanity Half-Half Mixed", + "Checkered Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Sw": "Shapesanity Stitched Mixed", + "3-1 Cr Sy": "Shapesanity Stitched Mixed", + "Half-Half Cr Sy": "Shapesanity Half-Half Mixed", + "Checkered Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Sy": "Shapesanity Stitched Mixed", + "3-1 Cr Wb": "Shapesanity Stitched Painted", + "Half-Half Cr Wb": "Shapesanity Half-Half Painted", + "Checkered Cr Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Wb": "Shapesanity Stitched Painted", + "Cornered Singles Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Wb": "Shapesanity Stitched Painted", + "3-1 Cr Wc": "Shapesanity Stitched Mixed", + "Half-Half Cr Wc": "Shapesanity Half-Half Mixed", + "Checkered Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Wc": "Shapesanity Stitched Mixed", + "3-1 Cr Wg": "Shapesanity Stitched Painted", + "Half-Half Cr Wg": "Shapesanity Half-Half Painted", + "Checkered Cr Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Wg": "Shapesanity Stitched Painted", + "Cornered Singles Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Wg": "Shapesanity Stitched Painted", + "3-1 Cr Wp": "Shapesanity Stitched Mixed", + "Half-Half Cr Wp": "Shapesanity Half-Half Mixed", + "Checkered Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Wp": "Shapesanity Stitched Mixed", + "3-1 Cr Wr": "Shapesanity Stitched Painted", + "Half-Half Cr Wr": "Shapesanity Half-Half Painted", + "Checkered Cr Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Wr": "Shapesanity Stitched Painted", + "Cornered Singles Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Wr": "Shapesanity Stitched Painted", + "3-1 Cr Wu": "Shapesanity Stitched Painted", + "Half-Half Cr Wu": "Shapesanity Half-Half Painted", + "Checkered Cr Wu": "Shapesanity Stitched Painted", + "Adjacent Singles Cr Wu": "Shapesanity Stitched Painted", + "Cornered Singles Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Cr Wu": "Shapesanity Stitched Painted", + "3-1 Cr Ww": "Shapesanity Stitched Mixed", + "Half-Half Cr Ww": "Shapesanity Half-Half Mixed", + "Checkered Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Ww": "Shapesanity Stitched Mixed", + "3-1 Cr Wy": "Shapesanity Stitched Mixed", + "Half-Half Cr Wy": "Shapesanity Half-Half Mixed", + "Checkered Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cr Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cr Wy": "Shapesanity Stitched Mixed", + "3-1 Cu Cb": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Cu Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Cb": "Shapesanity Stitched Painted", + "3-1 Cu Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cu Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Cc": "Shapesanity Stitched Mixed", + "3-1 Cu Cg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Cu Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Cg": "Shapesanity Stitched Painted", + "3-1 Cu Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cu Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Cp": "Shapesanity Stitched Mixed", + "3-1 Cu Cr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Cu Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Cr": "Shapesanity Stitched Painted", + "3-1 Cu Cw": "Shapesanity Colorful Full Mixed", + "Half-Half Cu Cw": "Shapesanity Colorful Full Mixed", + "Checkered Cu Cw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cu Cw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Cw": "Shapesanity Stitched Mixed", + "3-1 Cu Cy": "Shapesanity Colorful Full Mixed", + "Half-Half Cu Cy": "Shapesanity Colorful Full Mixed", + "Checkered Cu Cy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cu Cy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Cy": "Shapesanity Stitched Mixed", + "3-1 Cu Rb": "Shapesanity Stitched Painted", + "Half-Half Cu Rb": "Shapesanity Half-Half Painted", + "Checkered Cu Rb": "Shapesanity Stitched Painted", + "Adjacent Singles Cu Rb": "Shapesanity Stitched Painted", + "Cornered Singles Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Rb": "Shapesanity Stitched Painted", + "3-1 Cu Rc": "Shapesanity Stitched Mixed", + "Half-Half Cu Rc": "Shapesanity Half-Half Mixed", + "Checkered Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Rc": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Rc": "Shapesanity Stitched Mixed", + "3-1 Cu Rg": "Shapesanity Stitched Painted", + "Half-Half Cu Rg": "Shapesanity Half-Half Painted", + "Checkered Cu Rg": "Shapesanity Stitched Painted", + "Adjacent Singles Cu Rg": "Shapesanity Stitched Painted", + "Cornered Singles Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Rg": "Shapesanity Stitched Painted", + "3-1 Cu Rp": "Shapesanity Stitched Mixed", + "Half-Half Cu Rp": "Shapesanity Half-Half Mixed", + "Checkered Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Rp": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Rp": "Shapesanity Stitched Mixed", + "3-1 Cu Rr": "Shapesanity Stitched Painted", + "Half-Half Cu Rr": "Shapesanity Half-Half Painted", + "Checkered Cu Rr": "Shapesanity Stitched Painted", + "Adjacent Singles Cu Rr": "Shapesanity Stitched Painted", + "Cornered Singles Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Rr": "Shapesanity Stitched Painted", + "3-1 Cu Ru": "Shapesanity Stitched Uncolored", + "Half-Half Cu Ru": "Shapesanity Half-Half Uncolored", + "Checkered Cu Ru": "Shapesanity Stitched Uncolored", + "Adjacent Singles Cu Ru": "Shapesanity Stitched Uncolored", + "Cornered Singles Cu Ru": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Cu Ru": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Cu Ru": "Shapesanity Stitched Uncolored", + "3-1 Cu Rw": "Shapesanity Stitched Mixed", + "Half-Half Cu Rw": "Shapesanity Half-Half Mixed", + "Checkered Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Rw": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Rw": "Shapesanity Stitched Mixed", + "3-1 Cu Ry": "Shapesanity Stitched Mixed", + "Half-Half Cu Ry": "Shapesanity Half-Half Mixed", + "Checkered Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Ry": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Ry": "Shapesanity Stitched Mixed", + "3-1 Cu Sb": "Shapesanity Stitched Painted", + "Half-Half Cu Sb": "Shapesanity Half-Half Painted", + "Checkered Cu Sb": "Shapesanity Stitched Painted", + "Adjacent Singles Cu Sb": "Shapesanity Stitched Painted", + "Cornered Singles Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Sb": "Shapesanity Stitched Painted", + "3-1 Cu Sc": "Shapesanity Stitched Mixed", + "Half-Half Cu Sc": "Shapesanity Half-Half Mixed", + "Checkered Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Sc": "Shapesanity Stitched Mixed", + "3-1 Cu Sg": "Shapesanity Stitched Painted", + "Half-Half Cu Sg": "Shapesanity Half-Half Painted", + "Checkered Cu Sg": "Shapesanity Stitched Painted", + "Adjacent Singles Cu Sg": "Shapesanity Stitched Painted", + "Cornered Singles Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Sg": "Shapesanity Stitched Painted", + "3-1 Cu Sp": "Shapesanity Stitched Mixed", + "Half-Half Cu Sp": "Shapesanity Half-Half Mixed", + "Checkered Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Sp": "Shapesanity Stitched Mixed", + "3-1 Cu Sr": "Shapesanity Stitched Painted", + "Half-Half Cu Sr": "Shapesanity Half-Half Painted", + "Checkered Cu Sr": "Shapesanity Stitched Painted", + "Adjacent Singles Cu Sr": "Shapesanity Stitched Painted", + "Cornered Singles Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Sr": "Shapesanity Stitched Painted", + "3-1 Cu Su": "Shapesanity Stitched Uncolored", + "Half-Half Cu Su": "Shapesanity Half-Half Uncolored", + "Checkered Cu Su": "Shapesanity Stitched Uncolored", + "Adjacent Singles Cu Su": "Shapesanity Stitched Uncolored", + "Cornered Singles Cu Su": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Cu Su": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Cu Su": "Shapesanity Stitched Uncolored", + "3-1 Cu Sw": "Shapesanity Stitched Mixed", + "Half-Half Cu Sw": "Shapesanity Half-Half Mixed", + "Checkered Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Sw": "Shapesanity Stitched Mixed", + "3-1 Cu Sy": "Shapesanity Stitched Mixed", + "Half-Half Cu Sy": "Shapesanity Half-Half Mixed", + "Checkered Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Sy": "Shapesanity Stitched Mixed", + "3-1 Cu Wb": "Shapesanity Stitched Painted", + "Half-Half Cu Wb": "Shapesanity Half-Half Painted", + "Checkered Cu Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Cu Wb": "Shapesanity Stitched Painted", + "Cornered Singles Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Wb": "Shapesanity Stitched Painted", + "3-1 Cu Wc": "Shapesanity Stitched Mixed", + "Half-Half Cu Wc": "Shapesanity Half-Half Mixed", + "Checkered Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Wc": "Shapesanity Stitched Mixed", + "3-1 Cu Wg": "Shapesanity Stitched Painted", + "Half-Half Cu Wg": "Shapesanity Half-Half Painted", + "Checkered Cu Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Cu Wg": "Shapesanity Stitched Painted", + "Cornered Singles Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Wg": "Shapesanity Stitched Painted", + "3-1 Cu Wp": "Shapesanity Stitched Mixed", + "Half-Half Cu Wp": "Shapesanity Half-Half Mixed", + "Checkered Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Wp": "Shapesanity Stitched Mixed", + "3-1 Cu Wr": "Shapesanity Stitched Painted", + "Half-Half Cu Wr": "Shapesanity Half-Half Painted", + "Checkered Cu Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Cu Wr": "Shapesanity Stitched Painted", + "Cornered Singles Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Cu Wr": "Shapesanity Stitched Painted", + "3-1 Cu Wu": "Shapesanity Stitched Uncolored", + "Half-Half Cu Wu": "Shapesanity Half-Half Uncolored", + "Checkered Cu Wu": "Shapesanity Stitched Uncolored", + "Adjacent Singles Cu Wu": "Shapesanity Stitched Uncolored", + "Cornered Singles Cu Wu": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Cu Wu": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Cu Wu": "Shapesanity Stitched Uncolored", + "3-1 Cu Ww": "Shapesanity Stitched Mixed", + "Half-Half Cu Ww": "Shapesanity Half-Half Mixed", + "Checkered Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Ww": "Shapesanity Stitched Mixed", + "3-1 Cu Wy": "Shapesanity Stitched Mixed", + "Half-Half Cu Wy": "Shapesanity Half-Half Mixed", + "Checkered Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cu Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cu Wy": "Shapesanity Stitched Mixed", + "3-1 Cw Cb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cw Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Cb": "Shapesanity Stitched Mixed", + "3-1 Cw Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cw Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Cc": "Shapesanity Stitched Mixed", + "3-1 Cw Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cw Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Cg": "Shapesanity Stitched Mixed", + "3-1 Cw Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cw Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Cp": "Shapesanity Stitched Mixed", + "3-1 Cw Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cw Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Cr": "Shapesanity Stitched Mixed", + "3-1 Cw Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cw Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Cu": "Shapesanity Stitched Mixed", + "3-1 Cw Cy": "Shapesanity Colorful Full Mixed", + "Half-Half Cw Cy": "Shapesanity Colorful Full Mixed", + "Checkered Cw Cy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Cw Cy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Cy": "Shapesanity Stitched Mixed", + "3-1 Cw Rb": "Shapesanity Stitched Mixed", + "Half-Half Cw Rb": "Shapesanity Half-Half Mixed", + "Checkered Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Rb": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Rb": "Shapesanity Stitched Mixed", + "3-1 Cw Rc": "Shapesanity Stitched Mixed", + "Half-Half Cw Rc": "Shapesanity Half-Half Mixed", + "Checkered Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Rc": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Rc": "Shapesanity Stitched Mixed", + "3-1 Cw Rg": "Shapesanity Stitched Mixed", + "Half-Half Cw Rg": "Shapesanity Half-Half Mixed", + "Checkered Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Rg": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Rg": "Shapesanity Stitched Mixed", + "3-1 Cw Rp": "Shapesanity Stitched Mixed", + "Half-Half Cw Rp": "Shapesanity Half-Half Mixed", + "Checkered Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Rp": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Rp": "Shapesanity Stitched Mixed", + "3-1 Cw Rr": "Shapesanity Stitched Mixed", + "Half-Half Cw Rr": "Shapesanity Half-Half Mixed", + "Checkered Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Rr": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Rr": "Shapesanity Stitched Mixed", + "3-1 Cw Ru": "Shapesanity Stitched Mixed", + "Half-Half Cw Ru": "Shapesanity Half-Half Mixed", + "Checkered Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Ru": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Ru": "Shapesanity Stitched Mixed", + "3-1 Cw Rw": "Shapesanity Stitched Mixed", + "Half-Half Cw Rw": "Shapesanity Half-Half Mixed", + "Checkered Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Rw": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Rw": "Shapesanity Stitched Mixed", + "3-1 Cw Ry": "Shapesanity Stitched Mixed", + "Half-Half Cw Ry": "Shapesanity Half-Half Mixed", + "Checkered Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Ry": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Ry": "Shapesanity Stitched Mixed", + "3-1 Cw Sb": "Shapesanity Stitched Mixed", + "Half-Half Cw Sb": "Shapesanity Half-Half Mixed", + "Checkered Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Sb": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Sb": "Shapesanity Stitched Mixed", + "3-1 Cw Sc": "Shapesanity Stitched Mixed", + "Half-Half Cw Sc": "Shapesanity Half-Half Mixed", + "Checkered Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Sc": "Shapesanity Stitched Mixed", + "3-1 Cw Sg": "Shapesanity Stitched Mixed", + "Half-Half Cw Sg": "Shapesanity Half-Half Mixed", + "Checkered Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Sg": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Sg": "Shapesanity Stitched Mixed", + "3-1 Cw Sp": "Shapesanity Stitched Mixed", + "Half-Half Cw Sp": "Shapesanity Half-Half Mixed", + "Checkered Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Sp": "Shapesanity Stitched Mixed", + "3-1 Cw Sr": "Shapesanity Stitched Mixed", + "Half-Half Cw Sr": "Shapesanity Half-Half Mixed", + "Checkered Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Sr": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Sr": "Shapesanity Stitched Mixed", + "3-1 Cw Su": "Shapesanity Stitched Mixed", + "Half-Half Cw Su": "Shapesanity Half-Half Mixed", + "Checkered Cw Su": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Su": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Su": "Shapesanity Stitched Mixed", + "3-1 Cw Sw": "Shapesanity Stitched Mixed", + "Half-Half Cw Sw": "Shapesanity Half-Half Mixed", + "Checkered Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Sw": "Shapesanity Stitched Mixed", + "3-1 Cw Sy": "Shapesanity Stitched Mixed", + "Half-Half Cw Sy": "Shapesanity Half-Half Mixed", + "Checkered Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Sy": "Shapesanity Stitched Mixed", + "3-1 Cw Wb": "Shapesanity Stitched Mixed", + "Half-Half Cw Wb": "Shapesanity Half-Half Mixed", + "Checkered Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Wb": "Shapesanity Stitched Mixed", + "3-1 Cw Wc": "Shapesanity Stitched Mixed", + "Half-Half Cw Wc": "Shapesanity Half-Half Mixed", + "Checkered Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Wc": "Shapesanity Stitched Mixed", + "3-1 Cw Wg": "Shapesanity Stitched Mixed", + "Half-Half Cw Wg": "Shapesanity Half-Half Mixed", + "Checkered Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Wg": "Shapesanity Stitched Mixed", + "3-1 Cw Wp": "Shapesanity Stitched Mixed", + "Half-Half Cw Wp": "Shapesanity Half-Half Mixed", + "Checkered Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Wp": "Shapesanity Stitched Mixed", + "3-1 Cw Wr": "Shapesanity Stitched Mixed", + "Half-Half Cw Wr": "Shapesanity Half-Half Mixed", + "Checkered Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Wr": "Shapesanity Stitched Mixed", + "3-1 Cw Wu": "Shapesanity Stitched Mixed", + "Half-Half Cw Wu": "Shapesanity Half-Half Mixed", + "Checkered Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Wu": "Shapesanity Stitched Mixed", + "3-1 Cw Ww": "Shapesanity Stitched Mixed", + "Half-Half Cw Ww": "Shapesanity Half-Half Mixed", + "Checkered Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Ww": "Shapesanity Stitched Mixed", + "3-1 Cw Wy": "Shapesanity Stitched Mixed", + "Half-Half Cw Wy": "Shapesanity Half-Half Mixed", + "Checkered Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cw Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cw Wy": "Shapesanity Stitched Mixed", + "3-1 Cy Cb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cy Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Cb": "Shapesanity Stitched Mixed", + "3-1 Cy Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cy Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Cc": "Shapesanity Stitched Mixed", + "3-1 Cy Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cy Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Cg": "Shapesanity Stitched Mixed", + "3-1 Cy Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cy Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Cp": "Shapesanity Stitched Mixed", + "3-1 Cy Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cy Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Cr": "Shapesanity Stitched Mixed", + "3-1 Cy Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cy Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Cu": "Shapesanity Stitched Mixed", + "3-1 Cy Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Cy Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Cw": "Shapesanity Stitched Mixed", + "3-1 Cy Rb": "Shapesanity Stitched Mixed", + "Half-Half Cy Rb": "Shapesanity Half-Half Mixed", + "Checkered Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Rb": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Rb": "Shapesanity Stitched Mixed", + "3-1 Cy Rc": "Shapesanity Stitched Mixed", + "Half-Half Cy Rc": "Shapesanity Half-Half Mixed", + "Checkered Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Rc": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Rc": "Shapesanity Stitched Mixed", + "3-1 Cy Rg": "Shapesanity Stitched Mixed", + "Half-Half Cy Rg": "Shapesanity Half-Half Mixed", + "Checkered Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Rg": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Rg": "Shapesanity Stitched Mixed", + "3-1 Cy Rp": "Shapesanity Stitched Mixed", + "Half-Half Cy Rp": "Shapesanity Half-Half Mixed", + "Checkered Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Rp": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Rp": "Shapesanity Stitched Mixed", + "3-1 Cy Rr": "Shapesanity Stitched Mixed", + "Half-Half Cy Rr": "Shapesanity Half-Half Mixed", + "Checkered Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Rr": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Rr": "Shapesanity Stitched Mixed", + "3-1 Cy Ru": "Shapesanity Stitched Mixed", + "Half-Half Cy Ru": "Shapesanity Half-Half Mixed", + "Checkered Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Ru": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Ru": "Shapesanity Stitched Mixed", + "3-1 Cy Rw": "Shapesanity Stitched Mixed", + "Half-Half Cy Rw": "Shapesanity Half-Half Mixed", + "Checkered Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Rw": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Rw": "Shapesanity Stitched Mixed", + "3-1 Cy Ry": "Shapesanity Stitched Mixed", + "Half-Half Cy Ry": "Shapesanity Half-Half Mixed", + "Checkered Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Ry": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Ry": "Shapesanity Stitched Mixed", + "3-1 Cy Sb": "Shapesanity Stitched Mixed", + "Half-Half Cy Sb": "Shapesanity Half-Half Mixed", + "Checkered Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Sb": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Sb": "Shapesanity Stitched Mixed", + "3-1 Cy Sc": "Shapesanity Stitched Mixed", + "Half-Half Cy Sc": "Shapesanity Half-Half Mixed", + "Checkered Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Sc": "Shapesanity Stitched Mixed", + "3-1 Cy Sg": "Shapesanity Stitched Mixed", + "Half-Half Cy Sg": "Shapesanity Half-Half Mixed", + "Checkered Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Sg": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Sg": "Shapesanity Stitched Mixed", + "3-1 Cy Sp": "Shapesanity Stitched Mixed", + "Half-Half Cy Sp": "Shapesanity Half-Half Mixed", + "Checkered Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Sp": "Shapesanity Stitched Mixed", + "3-1 Cy Sr": "Shapesanity Stitched Mixed", + "Half-Half Cy Sr": "Shapesanity Half-Half Mixed", + "Checkered Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Sr": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Sr": "Shapesanity Stitched Mixed", + "3-1 Cy Su": "Shapesanity Stitched Mixed", + "Half-Half Cy Su": "Shapesanity Half-Half Mixed", + "Checkered Cy Su": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Su": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Su": "Shapesanity Stitched Mixed", + "3-1 Cy Sw": "Shapesanity Stitched Mixed", + "Half-Half Cy Sw": "Shapesanity Half-Half Mixed", + "Checkered Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Sw": "Shapesanity Stitched Mixed", + "3-1 Cy Sy": "Shapesanity Stitched Mixed", + "Half-Half Cy Sy": "Shapesanity Half-Half Mixed", + "Checkered Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Sy": "Shapesanity Stitched Mixed", + "3-1 Cy Wb": "Shapesanity Stitched Mixed", + "Half-Half Cy Wb": "Shapesanity Half-Half Mixed", + "Checkered Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Wb": "Shapesanity Stitched Mixed", + "3-1 Cy Wc": "Shapesanity Stitched Mixed", + "Half-Half Cy Wc": "Shapesanity Half-Half Mixed", + "Checkered Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Wc": "Shapesanity Stitched Mixed", + "3-1 Cy Wg": "Shapesanity Stitched Mixed", + "Half-Half Cy Wg": "Shapesanity Half-Half Mixed", + "Checkered Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Wg": "Shapesanity Stitched Mixed", + "3-1 Cy Wp": "Shapesanity Stitched Mixed", + "Half-Half Cy Wp": "Shapesanity Half-Half Mixed", + "Checkered Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Wp": "Shapesanity Stitched Mixed", + "3-1 Cy Wr": "Shapesanity Stitched Mixed", + "Half-Half Cy Wr": "Shapesanity Half-Half Mixed", + "Checkered Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Wr": "Shapesanity Stitched Mixed", + "3-1 Cy Wu": "Shapesanity Stitched Mixed", + "Half-Half Cy Wu": "Shapesanity Half-Half Mixed", + "Checkered Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Wu": "Shapesanity Stitched Mixed", + "3-1 Cy Ww": "Shapesanity Stitched Mixed", + "Half-Half Cy Ww": "Shapesanity Half-Half Mixed", + "Checkered Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Ww": "Shapesanity Stitched Mixed", + "3-1 Cy Wy": "Shapesanity Stitched Mixed", + "Half-Half Cy Wy": "Shapesanity Half-Half Mixed", + "Checkered Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Cy Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Cy Wy": "Shapesanity Stitched Mixed", + "3-1 Rb Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Cb": "Shapesanity Stitched Painted", + "3-1 Rb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Cc": "Shapesanity Stitched Mixed", + "3-1 Rb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Cg": "Shapesanity Stitched Painted", + "3-1 Rb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Cp": "Shapesanity Stitched Mixed", + "3-1 Rb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Cr": "Shapesanity Stitched Painted", + "3-1 Rb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Cu": "Shapesanity Stitched Painted", + "3-1 Rb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Cw": "Shapesanity Stitched Mixed", + "3-1 Rb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Cy": "Shapesanity Stitched Mixed", + "3-1 Rb Rc": "Shapesanity Colorful Full Mixed", + "Half-Half Rb Rc": "Shapesanity Colorful Full Mixed", + "Checkered Rb Rc": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rb Rc": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Rc": "Shapesanity Stitched Mixed", + "3-1 Rb Rg": "Shapesanity Colorful Full Painted", + "Half-Half Rb Rg": "Shapesanity Colorful Full Painted", + "Checkered Rb Rg": "Shapesanity Colorful Full Painted", + "Adjacent Singles Rb Rg": "Shapesanity Colorful Half Painted", + "Cornered Singles Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Rg": "Shapesanity Stitched Painted", + "3-1 Rb Rp": "Shapesanity Colorful Full Mixed", + "Half-Half Rb Rp": "Shapesanity Colorful Full Mixed", + "Checkered Rb Rp": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rb Rp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Rp": "Shapesanity Stitched Mixed", + "3-1 Rb Rr": "Shapesanity Colorful Full Painted", + "Half-Half Rb Rr": "Shapesanity Colorful Full Painted", + "Checkered Rb Rr": "Shapesanity Colorful Full Painted", + "Adjacent Singles Rb Rr": "Shapesanity Colorful Half Painted", + "Cornered Singles Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Rr": "Shapesanity Stitched Painted", + "3-1 Rb Ru": "Shapesanity Colorful Full Painted", + "Half-Half Rb Ru": "Shapesanity Colorful Full Painted", + "Checkered Rb Ru": "Shapesanity Colorful Full Painted", + "Adjacent Singles Rb Ru": "Shapesanity Colorful Half Painted", + "Cornered Singles Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Ru": "Shapesanity Stitched Painted", + "3-1 Rb Rw": "Shapesanity Colorful Full Mixed", + "Half-Half Rb Rw": "Shapesanity Colorful Full Mixed", + "Checkered Rb Rw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rb Rw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Rw": "Shapesanity Stitched Mixed", + "3-1 Rb Ry": "Shapesanity Colorful Full Mixed", + "Half-Half Rb Ry": "Shapesanity Colorful Full Mixed", + "Checkered Rb Ry": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rb Ry": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Ry": "Shapesanity Stitched Mixed", + "3-1 Rb Sb": "Shapesanity Stitched Painted", + "Half-Half Rb Sb": "Shapesanity Half-Half Painted", + "Checkered Rb Sb": "Shapesanity Stitched Painted", + "Adjacent Singles Rb Sb": "Shapesanity Stitched Painted", + "Cornered Singles Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Sb": "Shapesanity Stitched Painted", + "3-1 Rb Sc": "Shapesanity Stitched Mixed", + "Half-Half Rb Sc": "Shapesanity Half-Half Mixed", + "Checkered Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rb Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Sc": "Shapesanity Stitched Mixed", + "3-1 Rb Sg": "Shapesanity Stitched Painted", + "Half-Half Rb Sg": "Shapesanity Half-Half Painted", + "Checkered Rb Sg": "Shapesanity Stitched Painted", + "Adjacent Singles Rb Sg": "Shapesanity Stitched Painted", + "Cornered Singles Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Sg": "Shapesanity Stitched Painted", + "3-1 Rb Sp": "Shapesanity Stitched Mixed", + "Half-Half Rb Sp": "Shapesanity Half-Half Mixed", + "Checkered Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rb Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Sp": "Shapesanity Stitched Mixed", + "3-1 Rb Sr": "Shapesanity Stitched Painted", + "Half-Half Rb Sr": "Shapesanity Half-Half Painted", + "Checkered Rb Sr": "Shapesanity Stitched Painted", + "Adjacent Singles Rb Sr": "Shapesanity Stitched Painted", + "Cornered Singles Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Sr": "Shapesanity Stitched Painted", + "3-1 Rb Su": "Shapesanity Stitched Painted", + "Half-Half Rb Su": "Shapesanity Half-Half Painted", + "Checkered Rb Su": "Shapesanity Stitched Painted", + "Adjacent Singles Rb Su": "Shapesanity Stitched Painted", + "Cornered Singles Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Su": "Shapesanity Stitched Painted", + "3-1 Rb Sw": "Shapesanity Stitched Mixed", + "Half-Half Rb Sw": "Shapesanity Half-Half Mixed", + "Checkered Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Rb Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Sw": "Shapesanity Stitched Mixed", + "3-1 Rb Sy": "Shapesanity Stitched Mixed", + "Half-Half Rb Sy": "Shapesanity Half-Half Mixed", + "Checkered Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rb Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Sy": "Shapesanity Stitched Mixed", + "3-1 Rb Wb": "Shapesanity Stitched Painted", + "Half-Half Rb Wb": "Shapesanity Half-Half Painted", + "Checkered Rb Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Rb Wb": "Shapesanity Stitched Painted", + "Cornered Singles Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Wb": "Shapesanity Stitched Painted", + "3-1 Rb Wc": "Shapesanity Stitched Mixed", + "Half-Half Rb Wc": "Shapesanity Half-Half Mixed", + "Checkered Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rb Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Wc": "Shapesanity Stitched Mixed", + "3-1 Rb Wg": "Shapesanity Stitched Painted", + "Half-Half Rb Wg": "Shapesanity Half-Half Painted", + "Checkered Rb Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Rb Wg": "Shapesanity Stitched Painted", + "Cornered Singles Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Wg": "Shapesanity Stitched Painted", + "3-1 Rb Wp": "Shapesanity Stitched Mixed", + "Half-Half Rb Wp": "Shapesanity Half-Half Mixed", + "Checkered Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rb Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Wp": "Shapesanity Stitched Mixed", + "3-1 Rb Wr": "Shapesanity Stitched Painted", + "Half-Half Rb Wr": "Shapesanity Half-Half Painted", + "Checkered Rb Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Rb Wr": "Shapesanity Stitched Painted", + "Cornered Singles Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Wr": "Shapesanity Stitched Painted", + "3-1 Rb Wu": "Shapesanity Stitched Painted", + "Half-Half Rb Wu": "Shapesanity Half-Half Painted", + "Checkered Rb Wu": "Shapesanity Stitched Painted", + "Adjacent Singles Rb Wu": "Shapesanity Stitched Painted", + "Cornered Singles Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Rb Wu": "Shapesanity Stitched Painted", + "3-1 Rb Ww": "Shapesanity Stitched Mixed", + "Half-Half Rb Ww": "Shapesanity Half-Half Mixed", + "Checkered Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Rb Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Ww": "Shapesanity Stitched Mixed", + "3-1 Rb Wy": "Shapesanity Stitched Mixed", + "Half-Half Rb Wy": "Shapesanity Half-Half Mixed", + "Checkered Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rb Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rb Wy": "Shapesanity Stitched Mixed", + "3-1 Rc Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Cb": "Shapesanity Stitched Mixed", + "3-1 Rc Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Cc": "Shapesanity Stitched Mixed", + "3-1 Rc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Cg": "Shapesanity Stitched Mixed", + "3-1 Rc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Cp": "Shapesanity Stitched Mixed", + "3-1 Rc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Cr": "Shapesanity Stitched Mixed", + "3-1 Rc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Cu": "Shapesanity Stitched Mixed", + "3-1 Rc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Cw": "Shapesanity Stitched Mixed", + "3-1 Rc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Cy": "Shapesanity Stitched Mixed", + "3-1 Rc Rb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Rb": "Shapesanity Stitched Mixed", + "3-1 Rc Rg": "Shapesanity Colorful Full Mixed", + "Half-Half Rc Rg": "Shapesanity Colorful Full Mixed", + "Checkered Rc Rg": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rc Rg": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Rg": "Shapesanity Stitched Mixed", + "3-1 Rc Rp": "Shapesanity Colorful Full Mixed", + "Half-Half Rc Rp": "Shapesanity Colorful Full Mixed", + "Checkered Rc Rp": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rc Rp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Rp": "Shapesanity Stitched Mixed", + "3-1 Rc Rr": "Shapesanity Colorful Full Mixed", + "Half-Half Rc Rr": "Shapesanity Colorful Full Mixed", + "Checkered Rc Rr": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rc Rr": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Rr": "Shapesanity Stitched Mixed", + "3-1 Rc Ru": "Shapesanity Colorful Full Mixed", + "Half-Half Rc Ru": "Shapesanity Colorful Full Mixed", + "Checkered Rc Ru": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rc Ru": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Ru": "Shapesanity Stitched Mixed", + "3-1 Rc Rw": "Shapesanity Colorful Full Mixed", + "Half-Half Rc Rw": "Shapesanity Colorful Full Mixed", + "Checkered Rc Rw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rc Rw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Rw": "Shapesanity Stitched Mixed", + "3-1 Rc Ry": "Shapesanity Colorful Full Mixed", + "Half-Half Rc Ry": "Shapesanity Colorful Full Mixed", + "Checkered Rc Ry": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rc Ry": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Ry": "Shapesanity Stitched Mixed", + "3-1 Rc Sb": "Shapesanity Stitched Mixed", + "Half-Half Rc Sb": "Shapesanity Half-Half Mixed", + "Checkered Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Sb": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Sb": "Shapesanity Stitched Mixed", + "3-1 Rc Sc": "Shapesanity Stitched Mixed", + "Half-Half Rc Sc": "Shapesanity Half-Half Mixed", + "Checkered Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Sc": "Shapesanity Stitched Mixed", + "3-1 Rc Sg": "Shapesanity Stitched Mixed", + "Half-Half Rc Sg": "Shapesanity Half-Half Mixed", + "Checkered Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Sg": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Sg": "Shapesanity Stitched Mixed", + "3-1 Rc Sp": "Shapesanity Stitched Mixed", + "Half-Half Rc Sp": "Shapesanity Half-Half Mixed", + "Checkered Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Sp": "Shapesanity Stitched Mixed", + "3-1 Rc Sr": "Shapesanity Stitched Mixed", + "Half-Half Rc Sr": "Shapesanity Half-Half Mixed", + "Checkered Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Sr": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Sr": "Shapesanity Stitched Mixed", + "3-1 Rc Su": "Shapesanity Stitched Mixed", + "Half-Half Rc Su": "Shapesanity Half-Half Mixed", + "Checkered Rc Su": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Su": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Su": "Shapesanity Stitched Mixed", + "3-1 Rc Sw": "Shapesanity Stitched Mixed", + "Half-Half Rc Sw": "Shapesanity Half-Half Mixed", + "Checkered Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Sw": "Shapesanity Stitched Mixed", + "3-1 Rc Sy": "Shapesanity Stitched Mixed", + "Half-Half Rc Sy": "Shapesanity Half-Half Mixed", + "Checkered Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Sy": "Shapesanity Stitched Mixed", + "3-1 Rc Wb": "Shapesanity Stitched Mixed", + "Half-Half Rc Wb": "Shapesanity Half-Half Mixed", + "Checkered Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Wb": "Shapesanity Stitched Mixed", + "3-1 Rc Wc": "Shapesanity Stitched Mixed", + "Half-Half Rc Wc": "Shapesanity Half-Half Mixed", + "Checkered Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Wc": "Shapesanity Stitched Mixed", + "3-1 Rc Wg": "Shapesanity Stitched Mixed", + "Half-Half Rc Wg": "Shapesanity Half-Half Mixed", + "Checkered Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Wg": "Shapesanity Stitched Mixed", + "3-1 Rc Wp": "Shapesanity Stitched Mixed", + "Half-Half Rc Wp": "Shapesanity Half-Half Mixed", + "Checkered Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Wp": "Shapesanity Stitched Mixed", + "3-1 Rc Wr": "Shapesanity Stitched Mixed", + "Half-Half Rc Wr": "Shapesanity Half-Half Mixed", + "Checkered Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Wr": "Shapesanity Stitched Mixed", + "3-1 Rc Wu": "Shapesanity Stitched Mixed", + "Half-Half Rc Wu": "Shapesanity Half-Half Mixed", + "Checkered Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Wu": "Shapesanity Stitched Mixed", + "3-1 Rc Ww": "Shapesanity Stitched Mixed", + "Half-Half Rc Ww": "Shapesanity Half-Half Mixed", + "Checkered Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Ww": "Shapesanity Stitched Mixed", + "3-1 Rc Wy": "Shapesanity Stitched Mixed", + "Half-Half Rc Wy": "Shapesanity Half-Half Mixed", + "Checkered Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rc Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rc Wy": "Shapesanity Stitched Mixed", + "3-1 Rg Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Cb": "Shapesanity Stitched Painted", + "3-1 Rg Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Cc": "Shapesanity Stitched Mixed", + "3-1 Rg Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Cg": "Shapesanity Stitched Painted", + "3-1 Rg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Cp": "Shapesanity Stitched Mixed", + "3-1 Rg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Cr": "Shapesanity Stitched Painted", + "3-1 Rg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Cu": "Shapesanity Stitched Painted", + "3-1 Rg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Cw": "Shapesanity Stitched Mixed", + "3-1 Rg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Cy": "Shapesanity Stitched Mixed", + "3-1 Rg Rb": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Rg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Rb": "Shapesanity Stitched Painted", + "3-1 Rg Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Rc": "Shapesanity Stitched Mixed", + "3-1 Rg Rp": "Shapesanity Colorful Full Mixed", + "Half-Half Rg Rp": "Shapesanity Colorful Full Mixed", + "Checkered Rg Rp": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rg Rp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Rp": "Shapesanity Stitched Mixed", + "3-1 Rg Rr": "Shapesanity Colorful Full Painted", + "Half-Half Rg Rr": "Shapesanity Colorful Full Painted", + "Checkered Rg Rr": "Shapesanity Colorful Full Painted", + "Adjacent Singles Rg Rr": "Shapesanity Colorful Half Painted", + "Cornered Singles Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Rr": "Shapesanity Stitched Painted", + "3-1 Rg Ru": "Shapesanity Colorful Full Painted", + "Half-Half Rg Ru": "Shapesanity Colorful Full Painted", + "Checkered Rg Ru": "Shapesanity Colorful Full Painted", + "Adjacent Singles Rg Ru": "Shapesanity Colorful Half Painted", + "Cornered Singles Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Ru": "Shapesanity Stitched Painted", + "3-1 Rg Rw": "Shapesanity Colorful Full Mixed", + "Half-Half Rg Rw": "Shapesanity Colorful Full Mixed", + "Checkered Rg Rw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rg Rw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Rw": "Shapesanity Stitched Mixed", + "3-1 Rg Ry": "Shapesanity Colorful Full Mixed", + "Half-Half Rg Ry": "Shapesanity Colorful Full Mixed", + "Checkered Rg Ry": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rg Ry": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Ry": "Shapesanity Stitched Mixed", + "3-1 Rg Sb": "Shapesanity Stitched Painted", + "Half-Half Rg Sb": "Shapesanity Half-Half Painted", + "Checkered Rg Sb": "Shapesanity Stitched Painted", + "Adjacent Singles Rg Sb": "Shapesanity Stitched Painted", + "Cornered Singles Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Sb": "Shapesanity Stitched Painted", + "3-1 Rg Sc": "Shapesanity Stitched Mixed", + "Half-Half Rg Sc": "Shapesanity Half-Half Mixed", + "Checkered Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rg Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Sc": "Shapesanity Stitched Mixed", + "3-1 Rg Sg": "Shapesanity Stitched Painted", + "Half-Half Rg Sg": "Shapesanity Half-Half Painted", + "Checkered Rg Sg": "Shapesanity Stitched Painted", + "Adjacent Singles Rg Sg": "Shapesanity Stitched Painted", + "Cornered Singles Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Sg": "Shapesanity Stitched Painted", + "3-1 Rg Sp": "Shapesanity Stitched Mixed", + "Half-Half Rg Sp": "Shapesanity Half-Half Mixed", + "Checkered Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rg Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Sp": "Shapesanity Stitched Mixed", + "3-1 Rg Sr": "Shapesanity Stitched Painted", + "Half-Half Rg Sr": "Shapesanity Half-Half Painted", + "Checkered Rg Sr": "Shapesanity Stitched Painted", + "Adjacent Singles Rg Sr": "Shapesanity Stitched Painted", + "Cornered Singles Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Sr": "Shapesanity Stitched Painted", + "3-1 Rg Su": "Shapesanity Stitched Painted", + "Half-Half Rg Su": "Shapesanity Half-Half Painted", + "Checkered Rg Su": "Shapesanity Stitched Painted", + "Adjacent Singles Rg Su": "Shapesanity Stitched Painted", + "Cornered Singles Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Su": "Shapesanity Stitched Painted", + "3-1 Rg Sw": "Shapesanity Stitched Mixed", + "Half-Half Rg Sw": "Shapesanity Half-Half Mixed", + "Checkered Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Rg Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Sw": "Shapesanity Stitched Mixed", + "3-1 Rg Sy": "Shapesanity Stitched Mixed", + "Half-Half Rg Sy": "Shapesanity Half-Half Mixed", + "Checkered Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rg Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Sy": "Shapesanity Stitched Mixed", + "3-1 Rg Wb": "Shapesanity Stitched Painted", + "Half-Half Rg Wb": "Shapesanity Half-Half Painted", + "Checkered Rg Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Rg Wb": "Shapesanity Stitched Painted", + "Cornered Singles Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Wb": "Shapesanity Stitched Painted", + "3-1 Rg Wc": "Shapesanity Stitched Mixed", + "Half-Half Rg Wc": "Shapesanity Half-Half Mixed", + "Checkered Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rg Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Wc": "Shapesanity Stitched Mixed", + "3-1 Rg Wg": "Shapesanity Stitched Painted", + "Half-Half Rg Wg": "Shapesanity Half-Half Painted", + "Checkered Rg Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Rg Wg": "Shapesanity Stitched Painted", + "Cornered Singles Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Wg": "Shapesanity Stitched Painted", + "3-1 Rg Wp": "Shapesanity Stitched Mixed", + "Half-Half Rg Wp": "Shapesanity Half-Half Mixed", + "Checkered Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rg Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Wp": "Shapesanity Stitched Mixed", + "3-1 Rg Wr": "Shapesanity Stitched Painted", + "Half-Half Rg Wr": "Shapesanity Half-Half Painted", + "Checkered Rg Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Rg Wr": "Shapesanity Stitched Painted", + "Cornered Singles Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Wr": "Shapesanity Stitched Painted", + "3-1 Rg Wu": "Shapesanity Stitched Painted", + "Half-Half Rg Wu": "Shapesanity Half-Half Painted", + "Checkered Rg Wu": "Shapesanity Stitched Painted", + "Adjacent Singles Rg Wu": "Shapesanity Stitched Painted", + "Cornered Singles Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Rg Wu": "Shapesanity Stitched Painted", + "3-1 Rg Ww": "Shapesanity Stitched Mixed", + "Half-Half Rg Ww": "Shapesanity Half-Half Mixed", + "Checkered Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Rg Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Ww": "Shapesanity Stitched Mixed", + "3-1 Rg Wy": "Shapesanity Stitched Mixed", + "Half-Half Rg Wy": "Shapesanity Half-Half Mixed", + "Checkered Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rg Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rg Wy": "Shapesanity Stitched Mixed", + "3-1 Rp Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Cb": "Shapesanity Stitched Mixed", + "3-1 Rp Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Cc": "Shapesanity Stitched Mixed", + "3-1 Rp Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Cg": "Shapesanity Stitched Mixed", + "3-1 Rp Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Cp": "Shapesanity Stitched Mixed", + "3-1 Rp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Cr": "Shapesanity Stitched Mixed", + "3-1 Rp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Cu": "Shapesanity Stitched Mixed", + "3-1 Rp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Cw": "Shapesanity Stitched Mixed", + "3-1 Rp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Cy": "Shapesanity Stitched Mixed", + "3-1 Rp Rb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Rb": "Shapesanity Stitched Mixed", + "3-1 Rp Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Rc": "Shapesanity Stitched Mixed", + "3-1 Rp Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Rg": "Shapesanity Stitched Mixed", + "3-1 Rp Rr": "Shapesanity Colorful Full Mixed", + "Half-Half Rp Rr": "Shapesanity Colorful Full Mixed", + "Checkered Rp Rr": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rp Rr": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Rr": "Shapesanity Stitched Mixed", + "3-1 Rp Ru": "Shapesanity Colorful Full Mixed", + "Half-Half Rp Ru": "Shapesanity Colorful Full Mixed", + "Checkered Rp Ru": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rp Ru": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Ru": "Shapesanity Stitched Mixed", + "3-1 Rp Rw": "Shapesanity Colorful Full Mixed", + "Half-Half Rp Rw": "Shapesanity Colorful Full Mixed", + "Checkered Rp Rw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rp Rw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Rw": "Shapesanity Stitched Mixed", + "3-1 Rp Ry": "Shapesanity Colorful Full Mixed", + "Half-Half Rp Ry": "Shapesanity Colorful Full Mixed", + "Checkered Rp Ry": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rp Ry": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Ry": "Shapesanity Stitched Mixed", + "3-1 Rp Sb": "Shapesanity Stitched Mixed", + "Half-Half Rp Sb": "Shapesanity Half-Half Mixed", + "Checkered Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Sb": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Sb": "Shapesanity Stitched Mixed", + "3-1 Rp Sc": "Shapesanity Stitched Mixed", + "Half-Half Rp Sc": "Shapesanity Half-Half Mixed", + "Checkered Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Sc": "Shapesanity Stitched Mixed", + "3-1 Rp Sg": "Shapesanity Stitched Mixed", + "Half-Half Rp Sg": "Shapesanity Half-Half Mixed", + "Checkered Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Sg": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Sg": "Shapesanity Stitched Mixed", + "3-1 Rp Sp": "Shapesanity Stitched Mixed", + "Half-Half Rp Sp": "Shapesanity Half-Half Mixed", + "Checkered Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Sp": "Shapesanity Stitched Mixed", + "3-1 Rp Sr": "Shapesanity Stitched Mixed", + "Half-Half Rp Sr": "Shapesanity Half-Half Mixed", + "Checkered Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Sr": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Sr": "Shapesanity Stitched Mixed", + "3-1 Rp Su": "Shapesanity Stitched Mixed", + "Half-Half Rp Su": "Shapesanity Half-Half Mixed", + "Checkered Rp Su": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Su": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Su": "Shapesanity Stitched Mixed", + "3-1 Rp Sw": "Shapesanity Stitched Mixed", + "Half-Half Rp Sw": "Shapesanity Half-Half Mixed", + "Checkered Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Sw": "Shapesanity Stitched Mixed", + "3-1 Rp Sy": "Shapesanity Stitched Mixed", + "Half-Half Rp Sy": "Shapesanity Half-Half Mixed", + "Checkered Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Sy": "Shapesanity Stitched Mixed", + "3-1 Rp Wb": "Shapesanity Stitched Mixed", + "Half-Half Rp Wb": "Shapesanity Half-Half Mixed", + "Checkered Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Wb": "Shapesanity Stitched Mixed", + "3-1 Rp Wc": "Shapesanity Stitched Mixed", + "Half-Half Rp Wc": "Shapesanity Half-Half Mixed", + "Checkered Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Wc": "Shapesanity Stitched Mixed", + "3-1 Rp Wg": "Shapesanity Stitched Mixed", + "Half-Half Rp Wg": "Shapesanity Half-Half Mixed", + "Checkered Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Wg": "Shapesanity Stitched Mixed", + "3-1 Rp Wp": "Shapesanity Stitched Mixed", + "Half-Half Rp Wp": "Shapesanity Half-Half Mixed", + "Checkered Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Wp": "Shapesanity Stitched Mixed", + "3-1 Rp Wr": "Shapesanity Stitched Mixed", + "Half-Half Rp Wr": "Shapesanity Half-Half Mixed", + "Checkered Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Wr": "Shapesanity Stitched Mixed", + "3-1 Rp Wu": "Shapesanity Stitched Mixed", + "Half-Half Rp Wu": "Shapesanity Half-Half Mixed", + "Checkered Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Wu": "Shapesanity Stitched Mixed", + "3-1 Rp Ww": "Shapesanity Stitched Mixed", + "Half-Half Rp Ww": "Shapesanity Half-Half Mixed", + "Checkered Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Ww": "Shapesanity Stitched Mixed", + "3-1 Rp Wy": "Shapesanity Stitched Mixed", + "Half-Half Rp Wy": "Shapesanity Half-Half Mixed", + "Checkered Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rp Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rp Wy": "Shapesanity Stitched Mixed", + "3-1 Rr Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Cb": "Shapesanity Stitched Painted", + "3-1 Rr Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Cc": "Shapesanity Stitched Mixed", + "3-1 Rr Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Cg": "Shapesanity Stitched Painted", + "3-1 Rr Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Cp": "Shapesanity Stitched Mixed", + "3-1 Rr Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Cr": "Shapesanity Stitched Painted", + "3-1 Rr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Cu": "Shapesanity Stitched Painted", + "3-1 Rr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Cw": "Shapesanity Stitched Mixed", + "3-1 Rr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Cy": "Shapesanity Stitched Mixed", + "3-1 Rr Rb": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Rr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Rb": "Shapesanity Stitched Painted", + "3-1 Rr Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Rc": "Shapesanity Stitched Mixed", + "3-1 Rr Rg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Rr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Rg": "Shapesanity Stitched Painted", + "3-1 Rr Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Rp": "Shapesanity Stitched Mixed", + "3-1 Rr Ru": "Shapesanity Colorful Full Painted", + "Half-Half Rr Ru": "Shapesanity Colorful Full Painted", + "Checkered Rr Ru": "Shapesanity Colorful Full Painted", + "Adjacent Singles Rr Ru": "Shapesanity Colorful Half Painted", + "Cornered Singles Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Ru": "Shapesanity Stitched Painted", + "3-1 Rr Rw": "Shapesanity Colorful Full Mixed", + "Half-Half Rr Rw": "Shapesanity Colorful Full Mixed", + "Checkered Rr Rw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rr Rw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Rw": "Shapesanity Stitched Mixed", + "3-1 Rr Ry": "Shapesanity Colorful Full Mixed", + "Half-Half Rr Ry": "Shapesanity Colorful Full Mixed", + "Checkered Rr Ry": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rr Ry": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Ry": "Shapesanity Stitched Mixed", + "3-1 Rr Sb": "Shapesanity Stitched Painted", + "Half-Half Rr Sb": "Shapesanity Half-Half Painted", + "Checkered Rr Sb": "Shapesanity Stitched Painted", + "Adjacent Singles Rr Sb": "Shapesanity Stitched Painted", + "Cornered Singles Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Sb": "Shapesanity Stitched Painted", + "3-1 Rr Sc": "Shapesanity Stitched Mixed", + "Half-Half Rr Sc": "Shapesanity Half-Half Mixed", + "Checkered Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rr Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Sc": "Shapesanity Stitched Mixed", + "3-1 Rr Sg": "Shapesanity Stitched Painted", + "Half-Half Rr Sg": "Shapesanity Half-Half Painted", + "Checkered Rr Sg": "Shapesanity Stitched Painted", + "Adjacent Singles Rr Sg": "Shapesanity Stitched Painted", + "Cornered Singles Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Sg": "Shapesanity Stitched Painted", + "3-1 Rr Sp": "Shapesanity Stitched Mixed", + "Half-Half Rr Sp": "Shapesanity Half-Half Mixed", + "Checkered Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rr Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Sp": "Shapesanity Stitched Mixed", + "3-1 Rr Sr": "Shapesanity Stitched Painted", + "Half-Half Rr Sr": "Shapesanity Half-Half Painted", + "Checkered Rr Sr": "Shapesanity Stitched Painted", + "Adjacent Singles Rr Sr": "Shapesanity Stitched Painted", + "Cornered Singles Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Sr": "Shapesanity Stitched Painted", + "3-1 Rr Su": "Shapesanity Stitched Painted", + "Half-Half Rr Su": "Shapesanity Half-Half Painted", + "Checkered Rr Su": "Shapesanity Stitched Painted", + "Adjacent Singles Rr Su": "Shapesanity Stitched Painted", + "Cornered Singles Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Su": "Shapesanity Stitched Painted", + "3-1 Rr Sw": "Shapesanity Stitched Mixed", + "Half-Half Rr Sw": "Shapesanity Half-Half Mixed", + "Checkered Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Rr Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Sw": "Shapesanity Stitched Mixed", + "3-1 Rr Sy": "Shapesanity Stitched Mixed", + "Half-Half Rr Sy": "Shapesanity Half-Half Mixed", + "Checkered Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rr Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Sy": "Shapesanity Stitched Mixed", + "3-1 Rr Wb": "Shapesanity Stitched Painted", + "Half-Half Rr Wb": "Shapesanity Half-Half Painted", + "Checkered Rr Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Rr Wb": "Shapesanity Stitched Painted", + "Cornered Singles Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Wb": "Shapesanity Stitched Painted", + "3-1 Rr Wc": "Shapesanity Stitched Mixed", + "Half-Half Rr Wc": "Shapesanity Half-Half Mixed", + "Checkered Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rr Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Wc": "Shapesanity Stitched Mixed", + "3-1 Rr Wg": "Shapesanity Stitched Painted", + "Half-Half Rr Wg": "Shapesanity Half-Half Painted", + "Checkered Rr Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Rr Wg": "Shapesanity Stitched Painted", + "Cornered Singles Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Wg": "Shapesanity Stitched Painted", + "3-1 Rr Wp": "Shapesanity Stitched Mixed", + "Half-Half Rr Wp": "Shapesanity Half-Half Mixed", + "Checkered Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rr Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Wp": "Shapesanity Stitched Mixed", + "3-1 Rr Wr": "Shapesanity Stitched Painted", + "Half-Half Rr Wr": "Shapesanity Half-Half Painted", + "Checkered Rr Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Rr Wr": "Shapesanity Stitched Painted", + "Cornered Singles Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Wr": "Shapesanity Stitched Painted", + "3-1 Rr Wu": "Shapesanity Stitched Painted", + "Half-Half Rr Wu": "Shapesanity Half-Half Painted", + "Checkered Rr Wu": "Shapesanity Stitched Painted", + "Adjacent Singles Rr Wu": "Shapesanity Stitched Painted", + "Cornered Singles Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Rr Wu": "Shapesanity Stitched Painted", + "3-1 Rr Ww": "Shapesanity Stitched Mixed", + "Half-Half Rr Ww": "Shapesanity Half-Half Mixed", + "Checkered Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Rr Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Ww": "Shapesanity Stitched Mixed", + "3-1 Rr Wy": "Shapesanity Stitched Mixed", + "Half-Half Rr Wy": "Shapesanity Half-Half Mixed", + "Checkered Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rr Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rr Wy": "Shapesanity Stitched Mixed", + "3-1 Ru Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Ru Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Cb": "Shapesanity Stitched Painted", + "3-1 Ru Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Cc": "Shapesanity Stitched Mixed", + "3-1 Ru Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Ru Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Cg": "Shapesanity Stitched Painted", + "3-1 Ru Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Cp": "Shapesanity Stitched Mixed", + "3-1 Ru Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Ru Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Cr": "Shapesanity Stitched Painted", + "3-1 Ru Cu": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Ru Cu": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Ru Cu": "Shapesanity Stitched Uncolored", + "3-1 Ru Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Cw": "Shapesanity Stitched Mixed", + "3-1 Ru Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Cy": "Shapesanity Stitched Mixed", + "3-1 Ru Rb": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Ru Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Rb": "Shapesanity Stitched Painted", + "3-1 Ru Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Ru Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Rc": "Shapesanity Stitched Mixed", + "3-1 Ru Rg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Ru Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Rg": "Shapesanity Stitched Painted", + "3-1 Ru Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Ru Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Rp": "Shapesanity Stitched Mixed", + "3-1 Ru Rr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Ru Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Rr": "Shapesanity Stitched Painted", + "3-1 Ru Rw": "Shapesanity Colorful Full Mixed", + "Half-Half Ru Rw": "Shapesanity Colorful Full Mixed", + "Checkered Ru Rw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Ru Rw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Rw": "Shapesanity Stitched Mixed", + "3-1 Ru Ry": "Shapesanity Colorful Full Mixed", + "Half-Half Ru Ry": "Shapesanity Colorful Full Mixed", + "Checkered Ru Ry": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Ru Ry": "Shapesanity Colorful Half Mixed", + "Cornered Singles Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Ry": "Shapesanity Stitched Mixed", + "3-1 Ru Sb": "Shapesanity Stitched Painted", + "Half-Half Ru Sb": "Shapesanity Half-Half Painted", + "Checkered Ru Sb": "Shapesanity Stitched Painted", + "Adjacent Singles Ru Sb": "Shapesanity Stitched Painted", + "Cornered Singles Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Sb": "Shapesanity Stitched Painted", + "3-1 Ru Sc": "Shapesanity Stitched Mixed", + "Half-Half Ru Sc": "Shapesanity Half-Half Mixed", + "Checkered Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Ru Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Sc": "Shapesanity Stitched Mixed", + "3-1 Ru Sg": "Shapesanity Stitched Painted", + "Half-Half Ru Sg": "Shapesanity Half-Half Painted", + "Checkered Ru Sg": "Shapesanity Stitched Painted", + "Adjacent Singles Ru Sg": "Shapesanity Stitched Painted", + "Cornered Singles Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Sg": "Shapesanity Stitched Painted", + "3-1 Ru Sp": "Shapesanity Stitched Mixed", + "Half-Half Ru Sp": "Shapesanity Half-Half Mixed", + "Checkered Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Ru Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Sp": "Shapesanity Stitched Mixed", + "3-1 Ru Sr": "Shapesanity Stitched Painted", + "Half-Half Ru Sr": "Shapesanity Half-Half Painted", + "Checkered Ru Sr": "Shapesanity Stitched Painted", + "Adjacent Singles Ru Sr": "Shapesanity Stitched Painted", + "Cornered Singles Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Sr": "Shapesanity Stitched Painted", + "3-1 Ru Su": "Shapesanity Stitched Uncolored", + "Half-Half Ru Su": "Shapesanity Half-Half Uncolored", + "Checkered Ru Su": "Shapesanity Stitched Uncolored", + "Adjacent Singles Ru Su": "Shapesanity Stitched Uncolored", + "Cornered Singles Ru Su": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Ru Su": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Ru Su": "Shapesanity Stitched Uncolored", + "3-1 Ru Sw": "Shapesanity Stitched Mixed", + "Half-Half Ru Sw": "Shapesanity Half-Half Mixed", + "Checkered Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Ru Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Sw": "Shapesanity Stitched Mixed", + "3-1 Ru Sy": "Shapesanity Stitched Mixed", + "Half-Half Ru Sy": "Shapesanity Half-Half Mixed", + "Checkered Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Ru Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Sy": "Shapesanity Stitched Mixed", + "3-1 Ru Wb": "Shapesanity Stitched Painted", + "Half-Half Ru Wb": "Shapesanity Half-Half Painted", + "Checkered Ru Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Ru Wb": "Shapesanity Stitched Painted", + "Cornered Singles Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Wb": "Shapesanity Stitched Painted", + "3-1 Ru Wc": "Shapesanity Stitched Mixed", + "Half-Half Ru Wc": "Shapesanity Half-Half Mixed", + "Checkered Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Ru Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Wc": "Shapesanity Stitched Mixed", + "3-1 Ru Wg": "Shapesanity Stitched Painted", + "Half-Half Ru Wg": "Shapesanity Half-Half Painted", + "Checkered Ru Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Ru Wg": "Shapesanity Stitched Painted", + "Cornered Singles Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Wg": "Shapesanity Stitched Painted", + "3-1 Ru Wp": "Shapesanity Stitched Mixed", + "Half-Half Ru Wp": "Shapesanity Half-Half Mixed", + "Checkered Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Ru Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Wp": "Shapesanity Stitched Mixed", + "3-1 Ru Wr": "Shapesanity Stitched Painted", + "Half-Half Ru Wr": "Shapesanity Half-Half Painted", + "Checkered Ru Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Ru Wr": "Shapesanity Stitched Painted", + "Cornered Singles Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Ru Wr": "Shapesanity Stitched Painted", + "3-1 Ru Wu": "Shapesanity Stitched Uncolored", + "Half-Half Ru Wu": "Shapesanity Half-Half Uncolored", + "Checkered Ru Wu": "Shapesanity Stitched Uncolored", + "Adjacent Singles Ru Wu": "Shapesanity Stitched Uncolored", + "Cornered Singles Ru Wu": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Ru Wu": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Ru Wu": "Shapesanity Stitched Uncolored", + "3-1 Ru Ww": "Shapesanity Stitched Mixed", + "Half-Half Ru Ww": "Shapesanity Half-Half Mixed", + "Checkered Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Ru Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Ww": "Shapesanity Stitched Mixed", + "3-1 Ru Wy": "Shapesanity Stitched Mixed", + "Half-Half Ru Wy": "Shapesanity Half-Half Mixed", + "Checkered Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Ru Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ru Wy": "Shapesanity Stitched Mixed", + "3-1 Rw Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Cb": "Shapesanity Stitched Mixed", + "3-1 Rw Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Cc": "Shapesanity Stitched Mixed", + "3-1 Rw Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Cg": "Shapesanity Stitched Mixed", + "3-1 Rw Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Cp": "Shapesanity Stitched Mixed", + "3-1 Rw Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Cr": "Shapesanity Stitched Mixed", + "3-1 Rw Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Cu": "Shapesanity Stitched Mixed", + "3-1 Rw Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Cw": "Shapesanity Stitched Mixed", + "3-1 Rw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Cy": "Shapesanity Stitched Mixed", + "3-1 Rw Rb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Rb": "Shapesanity Stitched Mixed", + "3-1 Rw Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Rc": "Shapesanity Stitched Mixed", + "3-1 Rw Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Rg": "Shapesanity Stitched Mixed", + "3-1 Rw Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Rp": "Shapesanity Stitched Mixed", + "3-1 Rw Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Rr": "Shapesanity Stitched Mixed", + "3-1 Rw Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Rw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Ru": "Shapesanity Stitched Mixed", + "3-1 Rw Ry": "Shapesanity Colorful Full Mixed", + "Half-Half Rw Ry": "Shapesanity Colorful Full Mixed", + "Checkered Rw Ry": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Rw Ry": "Shapesanity Colorful Half Mixed", + "Cornered Singles Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Ry": "Shapesanity Stitched Mixed", + "3-1 Rw Sb": "Shapesanity Stitched Mixed", + "Half-Half Rw Sb": "Shapesanity Half-Half Mixed", + "Checkered Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Sb": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Sb": "Shapesanity Stitched Mixed", + "3-1 Rw Sc": "Shapesanity Stitched Mixed", + "Half-Half Rw Sc": "Shapesanity Half-Half Mixed", + "Checkered Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Sc": "Shapesanity Stitched Mixed", + "3-1 Rw Sg": "Shapesanity Stitched Mixed", + "Half-Half Rw Sg": "Shapesanity Half-Half Mixed", + "Checkered Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Sg": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Sg": "Shapesanity Stitched Mixed", + "3-1 Rw Sp": "Shapesanity Stitched Mixed", + "Half-Half Rw Sp": "Shapesanity Half-Half Mixed", + "Checkered Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Sp": "Shapesanity Stitched Mixed", + "3-1 Rw Sr": "Shapesanity Stitched Mixed", + "Half-Half Rw Sr": "Shapesanity Half-Half Mixed", + "Checkered Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Sr": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Sr": "Shapesanity Stitched Mixed", + "3-1 Rw Su": "Shapesanity Stitched Mixed", + "Half-Half Rw Su": "Shapesanity Half-Half Mixed", + "Checkered Rw Su": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Su": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Su": "Shapesanity Stitched Mixed", + "3-1 Rw Sw": "Shapesanity Stitched Mixed", + "Half-Half Rw Sw": "Shapesanity Half-Half Mixed", + "Checkered Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Sw": "Shapesanity Stitched Mixed", + "3-1 Rw Sy": "Shapesanity Stitched Mixed", + "Half-Half Rw Sy": "Shapesanity Half-Half Mixed", + "Checkered Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Sy": "Shapesanity Stitched Mixed", + "3-1 Rw Wb": "Shapesanity Stitched Mixed", + "Half-Half Rw Wb": "Shapesanity Half-Half Mixed", + "Checkered Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Wb": "Shapesanity Stitched Mixed", + "3-1 Rw Wc": "Shapesanity Stitched Mixed", + "Half-Half Rw Wc": "Shapesanity Half-Half Mixed", + "Checkered Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Wc": "Shapesanity Stitched Mixed", + "3-1 Rw Wg": "Shapesanity Stitched Mixed", + "Half-Half Rw Wg": "Shapesanity Half-Half Mixed", + "Checkered Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Wg": "Shapesanity Stitched Mixed", + "3-1 Rw Wp": "Shapesanity Stitched Mixed", + "Half-Half Rw Wp": "Shapesanity Half-Half Mixed", + "Checkered Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Wp": "Shapesanity Stitched Mixed", + "3-1 Rw Wr": "Shapesanity Stitched Mixed", + "Half-Half Rw Wr": "Shapesanity Half-Half Mixed", + "Checkered Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Wr": "Shapesanity Stitched Mixed", + "3-1 Rw Wu": "Shapesanity Stitched Mixed", + "Half-Half Rw Wu": "Shapesanity Half-Half Mixed", + "Checkered Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Wu": "Shapesanity Stitched Mixed", + "3-1 Rw Ww": "Shapesanity Stitched Mixed", + "Half-Half Rw Ww": "Shapesanity Half-Half Mixed", + "Checkered Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Ww": "Shapesanity Stitched Mixed", + "3-1 Rw Wy": "Shapesanity Stitched Mixed", + "Half-Half Rw Wy": "Shapesanity Half-Half Mixed", + "Checkered Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Rw Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Rw Wy": "Shapesanity Stitched Mixed", + "3-1 Ry Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Cb": "Shapesanity Stitched Mixed", + "3-1 Ry Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Cc": "Shapesanity Stitched Mixed", + "3-1 Ry Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Cg": "Shapesanity Stitched Mixed", + "3-1 Ry Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Cp": "Shapesanity Stitched Mixed", + "3-1 Ry Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Cr": "Shapesanity Stitched Mixed", + "3-1 Ry Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Cu": "Shapesanity Stitched Mixed", + "3-1 Ry Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Cw": "Shapesanity Stitched Mixed", + "3-1 Ry Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Cy": "Shapesanity Stitched Mixed", + "3-1 Ry Rb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Ry Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Rb": "Shapesanity Stitched Mixed", + "3-1 Ry Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Ry Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Rc": "Shapesanity Stitched Mixed", + "3-1 Ry Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Ry Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Rg": "Shapesanity Stitched Mixed", + "3-1 Ry Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Ry Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Rp": "Shapesanity Stitched Mixed", + "3-1 Ry Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Ry Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Rr": "Shapesanity Stitched Mixed", + "3-1 Ry Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Ry Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Ru": "Shapesanity Stitched Mixed", + "3-1 Ry Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Ry Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Rw": "Shapesanity Stitched Mixed", + "3-1 Ry Sb": "Shapesanity Stitched Mixed", + "Half-Half Ry Sb": "Shapesanity Half-Half Mixed", + "Checkered Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Sb": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Sb": "Shapesanity Stitched Mixed", + "3-1 Ry Sc": "Shapesanity Stitched Mixed", + "Half-Half Ry Sc": "Shapesanity Half-Half Mixed", + "Checkered Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Sc": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Sc": "Shapesanity Stitched Mixed", + "3-1 Ry Sg": "Shapesanity Stitched Mixed", + "Half-Half Ry Sg": "Shapesanity Half-Half Mixed", + "Checkered Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Sg": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Sg": "Shapesanity Stitched Mixed", + "3-1 Ry Sp": "Shapesanity Stitched Mixed", + "Half-Half Ry Sp": "Shapesanity Half-Half Mixed", + "Checkered Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Sp": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Sp": "Shapesanity Stitched Mixed", + "3-1 Ry Sr": "Shapesanity Stitched Mixed", + "Half-Half Ry Sr": "Shapesanity Half-Half Mixed", + "Checkered Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Sr": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Sr": "Shapesanity Stitched Mixed", + "3-1 Ry Su": "Shapesanity Stitched Mixed", + "Half-Half Ry Su": "Shapesanity Half-Half Mixed", + "Checkered Ry Su": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Su": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Su": "Shapesanity Stitched Mixed", + "3-1 Ry Sw": "Shapesanity Stitched Mixed", + "Half-Half Ry Sw": "Shapesanity Half-Half Mixed", + "Checkered Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Sw": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Sw": "Shapesanity Stitched Mixed", + "3-1 Ry Sy": "Shapesanity Stitched Mixed", + "Half-Half Ry Sy": "Shapesanity Half-Half Mixed", + "Checkered Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Sy": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Sy": "Shapesanity Stitched Mixed", + "3-1 Ry Wb": "Shapesanity Stitched Mixed", + "Half-Half Ry Wb": "Shapesanity Half-Half Mixed", + "Checkered Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Wb": "Shapesanity Stitched Mixed", + "3-1 Ry Wc": "Shapesanity Stitched Mixed", + "Half-Half Ry Wc": "Shapesanity Half-Half Mixed", + "Checkered Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Wc": "Shapesanity Stitched Mixed", + "3-1 Ry Wg": "Shapesanity Stitched Mixed", + "Half-Half Ry Wg": "Shapesanity Half-Half Mixed", + "Checkered Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Wg": "Shapesanity Stitched Mixed", + "3-1 Ry Wp": "Shapesanity Stitched Mixed", + "Half-Half Ry Wp": "Shapesanity Half-Half Mixed", + "Checkered Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Wp": "Shapesanity Stitched Mixed", + "3-1 Ry Wr": "Shapesanity Stitched Mixed", + "Half-Half Ry Wr": "Shapesanity Half-Half Mixed", + "Checkered Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Wr": "Shapesanity Stitched Mixed", + "3-1 Ry Wu": "Shapesanity Stitched Mixed", + "Half-Half Ry Wu": "Shapesanity Half-Half Mixed", + "Checkered Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Wu": "Shapesanity Stitched Mixed", + "3-1 Ry Ww": "Shapesanity Stitched Mixed", + "Half-Half Ry Ww": "Shapesanity Half-Half Mixed", + "Checkered Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Ww": "Shapesanity Stitched Mixed", + "3-1 Ry Wy": "Shapesanity Stitched Mixed", + "Half-Half Ry Wy": "Shapesanity Half-Half Mixed", + "Checkered Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Ry Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ry Wy": "Shapesanity Stitched Mixed", + "3-1 Sb Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Cb": "Shapesanity Stitched Painted", + "3-1 Sb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Cc": "Shapesanity Stitched Mixed", + "3-1 Sb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Cg": "Shapesanity Stitched Painted", + "3-1 Sb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Cp": "Shapesanity Stitched Mixed", + "3-1 Sb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Cr": "Shapesanity Stitched Painted", + "3-1 Sb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Cu": "Shapesanity Stitched Painted", + "3-1 Sb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Cw": "Shapesanity Stitched Mixed", + "3-1 Sb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Cy": "Shapesanity Stitched Mixed", + "3-1 Sb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Rb": "Shapesanity Stitched Painted", + "3-1 Sb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Rc": "Shapesanity Stitched Mixed", + "3-1 Sb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Rg": "Shapesanity Stitched Painted", + "3-1 Sb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Rp": "Shapesanity Stitched Mixed", + "3-1 Sb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Rr": "Shapesanity Stitched Painted", + "3-1 Sb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Ru": "Shapesanity Stitched Painted", + "3-1 Sb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Rw": "Shapesanity Stitched Mixed", + "3-1 Sb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Ry": "Shapesanity Stitched Mixed", + "3-1 Sb Sc": "Shapesanity Colorful Full Mixed", + "Half-Half Sb Sc": "Shapesanity Colorful Full Mixed", + "Checkered Sb Sc": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sb Sc": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Sc": "Shapesanity Stitched Mixed", + "3-1 Sb Sg": "Shapesanity Colorful Full Painted", + "Half-Half Sb Sg": "Shapesanity Colorful Full Painted", + "Checkered Sb Sg": "Shapesanity Colorful Full Painted", + "Adjacent Singles Sb Sg": "Shapesanity Colorful Half Painted", + "Cornered Singles Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Sg": "Shapesanity Stitched Painted", + "3-1 Sb Sp": "Shapesanity Colorful Full Mixed", + "Half-Half Sb Sp": "Shapesanity Colorful Full Mixed", + "Checkered Sb Sp": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sb Sp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Sp": "Shapesanity Stitched Mixed", + "3-1 Sb Sr": "Shapesanity Colorful Full Painted", + "Half-Half Sb Sr": "Shapesanity Colorful Full Painted", + "Checkered Sb Sr": "Shapesanity Colorful Full Painted", + "Adjacent Singles Sb Sr": "Shapesanity Colorful Half Painted", + "Cornered Singles Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Sr": "Shapesanity Stitched Painted", + "3-1 Sb Su": "Shapesanity Colorful Full Painted", + "Half-Half Sb Su": "Shapesanity Colorful Full Painted", + "Checkered Sb Su": "Shapesanity Colorful Full Painted", + "Adjacent Singles Sb Su": "Shapesanity Colorful Half Painted", + "Cornered Singles Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Su": "Shapesanity Stitched Painted", + "3-1 Sb Sw": "Shapesanity Colorful Full Mixed", + "Half-Half Sb Sw": "Shapesanity Colorful Full Mixed", + "Checkered Sb Sw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sb Sw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Sw": "Shapesanity Stitched Mixed", + "3-1 Sb Sy": "Shapesanity Colorful Full Mixed", + "Half-Half Sb Sy": "Shapesanity Colorful Full Mixed", + "Checkered Sb Sy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sb Sy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Sy": "Shapesanity Stitched Mixed", + "3-1 Sb Wb": "Shapesanity Stitched Painted", + "Half-Half Sb Wb": "Shapesanity Half-Half Painted", + "Checkered Sb Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Sb Wb": "Shapesanity Stitched Painted", + "Cornered Singles Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Wb": "Shapesanity Stitched Painted", + "3-1 Sb Wc": "Shapesanity Stitched Mixed", + "Half-Half Sb Wc": "Shapesanity Half-Half Mixed", + "Checkered Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Sb Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Wc": "Shapesanity Stitched Mixed", + "3-1 Sb Wg": "Shapesanity Stitched Painted", + "Half-Half Sb Wg": "Shapesanity Half-Half Painted", + "Checkered Sb Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Sb Wg": "Shapesanity Stitched Painted", + "Cornered Singles Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Wg": "Shapesanity Stitched Painted", + "3-1 Sb Wp": "Shapesanity Stitched Mixed", + "Half-Half Sb Wp": "Shapesanity Half-Half Mixed", + "Checkered Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Sb Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Wp": "Shapesanity Stitched Mixed", + "3-1 Sb Wr": "Shapesanity Stitched Painted", + "Half-Half Sb Wr": "Shapesanity Half-Half Painted", + "Checkered Sb Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Sb Wr": "Shapesanity Stitched Painted", + "Cornered Singles Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Wr": "Shapesanity Stitched Painted", + "3-1 Sb Wu": "Shapesanity Stitched Painted", + "Half-Half Sb Wu": "Shapesanity Half-Half Painted", + "Checkered Sb Wu": "Shapesanity Stitched Painted", + "Adjacent Singles Sb Wu": "Shapesanity Stitched Painted", + "Cornered Singles Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Sb Wu": "Shapesanity Stitched Painted", + "3-1 Sb Ww": "Shapesanity Stitched Mixed", + "Half-Half Sb Ww": "Shapesanity Half-Half Mixed", + "Checkered Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Sb Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Ww": "Shapesanity Stitched Mixed", + "3-1 Sb Wy": "Shapesanity Stitched Mixed", + "Half-Half Sb Wy": "Shapesanity Half-Half Mixed", + "Checkered Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Sb Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sb Wy": "Shapesanity Stitched Mixed", + "3-1 Sc Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Cb": "Shapesanity Stitched Mixed", + "3-1 Sc Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Cc": "Shapesanity Stitched Mixed", + "3-1 Sc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Cg": "Shapesanity Stitched Mixed", + "3-1 Sc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Cp": "Shapesanity Stitched Mixed", + "3-1 Sc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Cr": "Shapesanity Stitched Mixed", + "3-1 Sc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Cu": "Shapesanity Stitched Mixed", + "3-1 Sc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Cw": "Shapesanity Stitched Mixed", + "3-1 Sc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Cy": "Shapesanity Stitched Mixed", + "3-1 Sc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Rb": "Shapesanity Stitched Mixed", + "3-1 Sc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Rc": "Shapesanity Stitched Mixed", + "3-1 Sc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Rg": "Shapesanity Stitched Mixed", + "3-1 Sc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Rp": "Shapesanity Stitched Mixed", + "3-1 Sc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Rr": "Shapesanity Stitched Mixed", + "3-1 Sc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Ru": "Shapesanity Stitched Mixed", + "3-1 Sc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Rw": "Shapesanity Stitched Mixed", + "3-1 Sc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Ry": "Shapesanity Stitched Mixed", + "3-1 Sc Sb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Sb": "Shapesanity Stitched Mixed", + "3-1 Sc Sg": "Shapesanity Colorful Full Mixed", + "Half-Half Sc Sg": "Shapesanity Colorful Full Mixed", + "Checkered Sc Sg": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sc Sg": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Sg": "Shapesanity Stitched Mixed", + "3-1 Sc Sp": "Shapesanity Colorful Full Mixed", + "Half-Half Sc Sp": "Shapesanity Colorful Full Mixed", + "Checkered Sc Sp": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sc Sp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Sp": "Shapesanity Stitched Mixed", + "3-1 Sc Sr": "Shapesanity Colorful Full Mixed", + "Half-Half Sc Sr": "Shapesanity Colorful Full Mixed", + "Checkered Sc Sr": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sc Sr": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Sr": "Shapesanity Stitched Mixed", + "3-1 Sc Su": "Shapesanity Colorful Full Mixed", + "Half-Half Sc Su": "Shapesanity Colorful Full Mixed", + "Checkered Sc Su": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sc Su": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Su": "Shapesanity Stitched Mixed", + "3-1 Sc Sw": "Shapesanity Colorful Full Mixed", + "Half-Half Sc Sw": "Shapesanity Colorful Full Mixed", + "Checkered Sc Sw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sc Sw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Sw": "Shapesanity Stitched Mixed", + "3-1 Sc Sy": "Shapesanity Colorful Full Mixed", + "Half-Half Sc Sy": "Shapesanity Colorful Full Mixed", + "Checkered Sc Sy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sc Sy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Sy": "Shapesanity Stitched Mixed", + "3-1 Sc Wb": "Shapesanity Stitched Mixed", + "Half-Half Sc Wb": "Shapesanity Half-Half Mixed", + "Checkered Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Sc Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Wb": "Shapesanity Stitched Mixed", + "3-1 Sc Wc": "Shapesanity Stitched Mixed", + "Half-Half Sc Wc": "Shapesanity Half-Half Mixed", + "Checkered Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Sc Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Wc": "Shapesanity Stitched Mixed", + "3-1 Sc Wg": "Shapesanity Stitched Mixed", + "Half-Half Sc Wg": "Shapesanity Half-Half Mixed", + "Checkered Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Sc Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Wg": "Shapesanity Stitched Mixed", + "3-1 Sc Wp": "Shapesanity Stitched Mixed", + "Half-Half Sc Wp": "Shapesanity Half-Half Mixed", + "Checkered Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Sc Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Wp": "Shapesanity Stitched Mixed", + "3-1 Sc Wr": "Shapesanity Stitched Mixed", + "Half-Half Sc Wr": "Shapesanity Half-Half Mixed", + "Checkered Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Sc Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Wr": "Shapesanity Stitched Mixed", + "3-1 Sc Wu": "Shapesanity Stitched Mixed", + "Half-Half Sc Wu": "Shapesanity Half-Half Mixed", + "Checkered Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Sc Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Wu": "Shapesanity Stitched Mixed", + "3-1 Sc Ww": "Shapesanity Stitched Mixed", + "Half-Half Sc Ww": "Shapesanity Half-Half Mixed", + "Checkered Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Sc Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Ww": "Shapesanity Stitched Mixed", + "3-1 Sc Wy": "Shapesanity Stitched Mixed", + "Half-Half Sc Wy": "Shapesanity Half-Half Mixed", + "Checkered Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Sc Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sc Wy": "Shapesanity Stitched Mixed", + "3-1 Sg Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Cb": "Shapesanity Stitched Painted", + "3-1 Sg Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Cc": "Shapesanity Stitched Mixed", + "3-1 Sg Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Cg": "Shapesanity Stitched Painted", + "3-1 Sg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Cp": "Shapesanity Stitched Mixed", + "3-1 Sg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Cr": "Shapesanity Stitched Painted", + "3-1 Sg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Cu": "Shapesanity Stitched Painted", + "3-1 Sg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Cw": "Shapesanity Stitched Mixed", + "3-1 Sg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Cy": "Shapesanity Stitched Mixed", + "3-1 Sg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Rb": "Shapesanity Stitched Painted", + "3-1 Sg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Rc": "Shapesanity Stitched Mixed", + "3-1 Sg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Rg": "Shapesanity Stitched Painted", + "3-1 Sg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Rp": "Shapesanity Stitched Mixed", + "3-1 Sg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Rr": "Shapesanity Stitched Painted", + "3-1 Sg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Ru": "Shapesanity Stitched Painted", + "3-1 Sg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Rw": "Shapesanity Stitched Mixed", + "3-1 Sg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Ry": "Shapesanity Stitched Mixed", + "3-1 Sg Sb": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Sg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Sb": "Shapesanity Stitched Painted", + "3-1 Sg Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Sc": "Shapesanity Stitched Mixed", + "3-1 Sg Sp": "Shapesanity Colorful Full Mixed", + "Half-Half Sg Sp": "Shapesanity Colorful Full Mixed", + "Checkered Sg Sp": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sg Sp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Sp": "Shapesanity Stitched Mixed", + "3-1 Sg Sr": "Shapesanity Colorful Full Painted", + "Half-Half Sg Sr": "Shapesanity Colorful Full Painted", + "Checkered Sg Sr": "Shapesanity Colorful Full Painted", + "Adjacent Singles Sg Sr": "Shapesanity Colorful Half Painted", + "Cornered Singles Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Sr": "Shapesanity Stitched Painted", + "3-1 Sg Su": "Shapesanity Colorful Full Painted", + "Half-Half Sg Su": "Shapesanity Colorful Full Painted", + "Checkered Sg Su": "Shapesanity Colorful Full Painted", + "Adjacent Singles Sg Su": "Shapesanity Colorful Half Painted", + "Cornered Singles Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Su": "Shapesanity Stitched Painted", + "3-1 Sg Sw": "Shapesanity Colorful Full Mixed", + "Half-Half Sg Sw": "Shapesanity Colorful Full Mixed", + "Checkered Sg Sw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sg Sw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Sw": "Shapesanity Stitched Mixed", + "3-1 Sg Sy": "Shapesanity Colorful Full Mixed", + "Half-Half Sg Sy": "Shapesanity Colorful Full Mixed", + "Checkered Sg Sy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sg Sy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Sy": "Shapesanity Stitched Mixed", + "3-1 Sg Wb": "Shapesanity Stitched Painted", + "Half-Half Sg Wb": "Shapesanity Half-Half Painted", + "Checkered Sg Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Sg Wb": "Shapesanity Stitched Painted", + "Cornered Singles Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Wb": "Shapesanity Stitched Painted", + "3-1 Sg Wc": "Shapesanity Stitched Mixed", + "Half-Half Sg Wc": "Shapesanity Half-Half Mixed", + "Checkered Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Sg Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Wc": "Shapesanity Stitched Mixed", + "3-1 Sg Wg": "Shapesanity Stitched Painted", + "Half-Half Sg Wg": "Shapesanity Half-Half Painted", + "Checkered Sg Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Sg Wg": "Shapesanity Stitched Painted", + "Cornered Singles Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Wg": "Shapesanity Stitched Painted", + "3-1 Sg Wp": "Shapesanity Stitched Mixed", + "Half-Half Sg Wp": "Shapesanity Half-Half Mixed", + "Checkered Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Sg Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Wp": "Shapesanity Stitched Mixed", + "3-1 Sg Wr": "Shapesanity Stitched Painted", + "Half-Half Sg Wr": "Shapesanity Half-Half Painted", + "Checkered Sg Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Sg Wr": "Shapesanity Stitched Painted", + "Cornered Singles Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Wr": "Shapesanity Stitched Painted", + "3-1 Sg Wu": "Shapesanity Stitched Painted", + "Half-Half Sg Wu": "Shapesanity Half-Half Painted", + "Checkered Sg Wu": "Shapesanity Stitched Painted", + "Adjacent Singles Sg Wu": "Shapesanity Stitched Painted", + "Cornered Singles Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Sg Wu": "Shapesanity Stitched Painted", + "3-1 Sg Ww": "Shapesanity Stitched Mixed", + "Half-Half Sg Ww": "Shapesanity Half-Half Mixed", + "Checkered Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Sg Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Ww": "Shapesanity Stitched Mixed", + "3-1 Sg Wy": "Shapesanity Stitched Mixed", + "Half-Half Sg Wy": "Shapesanity Half-Half Mixed", + "Checkered Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Sg Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sg Wy": "Shapesanity Stitched Mixed", + "3-1 Sp Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Cb": "Shapesanity Stitched Mixed", + "3-1 Sp Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Cc": "Shapesanity Stitched Mixed", + "3-1 Sp Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Cg": "Shapesanity Stitched Mixed", + "3-1 Sp Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Cp": "Shapesanity Stitched Mixed", + "3-1 Sp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Cr": "Shapesanity Stitched Mixed", + "3-1 Sp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Cu": "Shapesanity Stitched Mixed", + "3-1 Sp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Cw": "Shapesanity Stitched Mixed", + "3-1 Sp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Cy": "Shapesanity Stitched Mixed", + "3-1 Sp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Rb": "Shapesanity Stitched Mixed", + "3-1 Sp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Rc": "Shapesanity Stitched Mixed", + "3-1 Sp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Rg": "Shapesanity Stitched Mixed", + "3-1 Sp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Rp": "Shapesanity Stitched Mixed", + "3-1 Sp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Rr": "Shapesanity Stitched Mixed", + "3-1 Sp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Ru": "Shapesanity Stitched Mixed", + "3-1 Sp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Rw": "Shapesanity Stitched Mixed", + "3-1 Sp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Ry": "Shapesanity Stitched Mixed", + "3-1 Sp Sb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Sb": "Shapesanity Stitched Mixed", + "3-1 Sp Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Sc": "Shapesanity Stitched Mixed", + "3-1 Sp Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Sg": "Shapesanity Stitched Mixed", + "3-1 Sp Sr": "Shapesanity Colorful Full Mixed", + "Half-Half Sp Sr": "Shapesanity Colorful Full Mixed", + "Checkered Sp Sr": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sp Sr": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Sr": "Shapesanity Stitched Mixed", + "3-1 Sp Su": "Shapesanity Colorful Full Mixed", + "Half-Half Sp Su": "Shapesanity Colorful Full Mixed", + "Checkered Sp Su": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sp Su": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Su": "Shapesanity Stitched Mixed", + "3-1 Sp Sw": "Shapesanity Colorful Full Mixed", + "Half-Half Sp Sw": "Shapesanity Colorful Full Mixed", + "Checkered Sp Sw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sp Sw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Sw": "Shapesanity Stitched Mixed", + "3-1 Sp Sy": "Shapesanity Colorful Full Mixed", + "Half-Half Sp Sy": "Shapesanity Colorful Full Mixed", + "Checkered Sp Sy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sp Sy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Sy": "Shapesanity Stitched Mixed", + "3-1 Sp Wb": "Shapesanity Stitched Mixed", + "Half-Half Sp Wb": "Shapesanity Half-Half Mixed", + "Checkered Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Sp Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Wb": "Shapesanity Stitched Mixed", + "3-1 Sp Wc": "Shapesanity Stitched Mixed", + "Half-Half Sp Wc": "Shapesanity Half-Half Mixed", + "Checkered Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Sp Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Wc": "Shapesanity Stitched Mixed", + "3-1 Sp Wg": "Shapesanity Stitched Mixed", + "Half-Half Sp Wg": "Shapesanity Half-Half Mixed", + "Checkered Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Sp Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Wg": "Shapesanity Stitched Mixed", + "3-1 Sp Wp": "Shapesanity Stitched Mixed", + "Half-Half Sp Wp": "Shapesanity Half-Half Mixed", + "Checkered Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Sp Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Wp": "Shapesanity Stitched Mixed", + "3-1 Sp Wr": "Shapesanity Stitched Mixed", + "Half-Half Sp Wr": "Shapesanity Half-Half Mixed", + "Checkered Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Sp Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Wr": "Shapesanity Stitched Mixed", + "3-1 Sp Wu": "Shapesanity Stitched Mixed", + "Half-Half Sp Wu": "Shapesanity Half-Half Mixed", + "Checkered Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Sp Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Wu": "Shapesanity Stitched Mixed", + "3-1 Sp Ww": "Shapesanity Stitched Mixed", + "Half-Half Sp Ww": "Shapesanity Half-Half Mixed", + "Checkered Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Sp Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Ww": "Shapesanity Stitched Mixed", + "3-1 Sp Wy": "Shapesanity Stitched Mixed", + "Half-Half Sp Wy": "Shapesanity Half-Half Mixed", + "Checkered Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Sp Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sp Wy": "Shapesanity Stitched Mixed", + "3-1 Sr Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Cb": "Shapesanity Stitched Painted", + "3-1 Sr Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Cc": "Shapesanity Stitched Mixed", + "3-1 Sr Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Cg": "Shapesanity Stitched Painted", + "3-1 Sr Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Cp": "Shapesanity Stitched Mixed", + "3-1 Sr Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Cr": "Shapesanity Stitched Painted", + "3-1 Sr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Cu": "Shapesanity Stitched Painted", + "3-1 Sr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Cw": "Shapesanity Stitched Mixed", + "3-1 Sr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Cy": "Shapesanity Stitched Mixed", + "3-1 Sr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Rb": "Shapesanity Stitched Painted", + "3-1 Sr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Rc": "Shapesanity Stitched Mixed", + "3-1 Sr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Rg": "Shapesanity Stitched Painted", + "3-1 Sr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Rp": "Shapesanity Stitched Mixed", + "3-1 Sr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Rr": "Shapesanity Stitched Painted", + "3-1 Sr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Ru": "Shapesanity Stitched Painted", + "3-1 Sr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Rw": "Shapesanity Stitched Mixed", + "3-1 Sr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Ry": "Shapesanity Stitched Mixed", + "3-1 Sr Sb": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Sr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Sb": "Shapesanity Stitched Painted", + "3-1 Sr Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Sc": "Shapesanity Stitched Mixed", + "3-1 Sr Sg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Sr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Sg": "Shapesanity Stitched Painted", + "3-1 Sr Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Sp": "Shapesanity Stitched Mixed", + "3-1 Sr Su": "Shapesanity Colorful Full Painted", + "Half-Half Sr Su": "Shapesanity Colorful Full Painted", + "Checkered Sr Su": "Shapesanity Colorful Full Painted", + "Adjacent Singles Sr Su": "Shapesanity Colorful Half Painted", + "Cornered Singles Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Su": "Shapesanity Stitched Painted", + "3-1 Sr Sw": "Shapesanity Colorful Full Mixed", + "Half-Half Sr Sw": "Shapesanity Colorful Full Mixed", + "Checkered Sr Sw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sr Sw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Sw": "Shapesanity Stitched Mixed", + "3-1 Sr Sy": "Shapesanity Colorful Full Mixed", + "Half-Half Sr Sy": "Shapesanity Colorful Full Mixed", + "Checkered Sr Sy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sr Sy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Sy": "Shapesanity Stitched Mixed", + "3-1 Sr Wb": "Shapesanity Stitched Painted", + "Half-Half Sr Wb": "Shapesanity Half-Half Painted", + "Checkered Sr Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Sr Wb": "Shapesanity Stitched Painted", + "Cornered Singles Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Wb": "Shapesanity Stitched Painted", + "3-1 Sr Wc": "Shapesanity Stitched Mixed", + "Half-Half Sr Wc": "Shapesanity Half-Half Mixed", + "Checkered Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Sr Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Wc": "Shapesanity Stitched Mixed", + "3-1 Sr Wg": "Shapesanity Stitched Painted", + "Half-Half Sr Wg": "Shapesanity Half-Half Painted", + "Checkered Sr Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Sr Wg": "Shapesanity Stitched Painted", + "Cornered Singles Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Wg": "Shapesanity Stitched Painted", + "3-1 Sr Wp": "Shapesanity Stitched Mixed", + "Half-Half Sr Wp": "Shapesanity Half-Half Mixed", + "Checkered Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Sr Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Wp": "Shapesanity Stitched Mixed", + "3-1 Sr Wr": "Shapesanity Stitched Painted", + "Half-Half Sr Wr": "Shapesanity Half-Half Painted", + "Checkered Sr Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Sr Wr": "Shapesanity Stitched Painted", + "Cornered Singles Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Wr": "Shapesanity Stitched Painted", + "3-1 Sr Wu": "Shapesanity Stitched Painted", + "Half-Half Sr Wu": "Shapesanity Half-Half Painted", + "Checkered Sr Wu": "Shapesanity Stitched Painted", + "Adjacent Singles Sr Wu": "Shapesanity Stitched Painted", + "Cornered Singles Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Sr Wu": "Shapesanity Stitched Painted", + "3-1 Sr Ww": "Shapesanity Stitched Mixed", + "Half-Half Sr Ww": "Shapesanity Half-Half Mixed", + "Checkered Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Sr Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Ww": "Shapesanity Stitched Mixed", + "3-1 Sr Wy": "Shapesanity Stitched Mixed", + "Half-Half Sr Wy": "Shapesanity Half-Half Mixed", + "Checkered Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Sr Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sr Wy": "Shapesanity Stitched Mixed", + "3-1 Su Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Su Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Cb": "Shapesanity Stitched Painted", + "3-1 Su Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Cc": "Shapesanity Stitched Mixed", + "3-1 Su Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Su Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Cg": "Shapesanity Stitched Painted", + "3-1 Su Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Cp": "Shapesanity Stitched Mixed", + "3-1 Su Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Su Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Cr": "Shapesanity Stitched Painted", + "3-1 Su Cu": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Su Cu": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Su Cu": "Shapesanity Stitched Uncolored", + "3-1 Su Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Cw": "Shapesanity Stitched Mixed", + "3-1 Su Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Cy": "Shapesanity Stitched Mixed", + "3-1 Su Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Su Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Rb": "Shapesanity Stitched Painted", + "3-1 Su Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Rc": "Shapesanity Stitched Mixed", + "3-1 Su Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Su Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Rg": "Shapesanity Stitched Painted", + "3-1 Su Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Rp": "Shapesanity Stitched Mixed", + "3-1 Su Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Su Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Rr": "Shapesanity Stitched Painted", + "3-1 Su Ru": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Su Ru": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Su Ru": "Shapesanity Stitched Uncolored", + "3-1 Su Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Rw": "Shapesanity Stitched Mixed", + "3-1 Su Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Ry": "Shapesanity Stitched Mixed", + "3-1 Su Sb": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Su Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Sb": "Shapesanity Stitched Painted", + "3-1 Su Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Su Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Sc": "Shapesanity Stitched Mixed", + "3-1 Su Sg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Su Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Sg": "Shapesanity Stitched Painted", + "3-1 Su Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Su Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Sp": "Shapesanity Stitched Mixed", + "3-1 Su Sr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1 Su Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Sr": "Shapesanity Stitched Painted", + "3-1 Su Sw": "Shapesanity Colorful Full Mixed", + "Half-Half Su Sw": "Shapesanity Colorful Full Mixed", + "Checkered Su Sw": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Su Sw": "Shapesanity Colorful Half Mixed", + "Cornered Singles Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Sw": "Shapesanity Stitched Mixed", + "3-1 Su Sy": "Shapesanity Colorful Full Mixed", + "Half-Half Su Sy": "Shapesanity Colorful Full Mixed", + "Checkered Su Sy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Su Sy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Sy": "Shapesanity Stitched Mixed", + "3-1 Su Wb": "Shapesanity Stitched Painted", + "Half-Half Su Wb": "Shapesanity Half-Half Painted", + "Checkered Su Wb": "Shapesanity Stitched Painted", + "Adjacent Singles Su Wb": "Shapesanity Stitched Painted", + "Cornered Singles Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Wb": "Shapesanity Stitched Painted", + "3-1 Su Wc": "Shapesanity Stitched Mixed", + "Half-Half Su Wc": "Shapesanity Half-Half Mixed", + "Checkered Su Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Su Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Wc": "Shapesanity Stitched Mixed", + "3-1 Su Wg": "Shapesanity Stitched Painted", + "Half-Half Su Wg": "Shapesanity Half-Half Painted", + "Checkered Su Wg": "Shapesanity Stitched Painted", + "Adjacent Singles Su Wg": "Shapesanity Stitched Painted", + "Cornered Singles Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Wg": "Shapesanity Stitched Painted", + "3-1 Su Wp": "Shapesanity Stitched Mixed", + "Half-Half Su Wp": "Shapesanity Half-Half Mixed", + "Checkered Su Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Su Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Wp": "Shapesanity Stitched Mixed", + "3-1 Su Wr": "Shapesanity Stitched Painted", + "Half-Half Su Wr": "Shapesanity Half-Half Painted", + "Checkered Su Wr": "Shapesanity Stitched Painted", + "Adjacent Singles Su Wr": "Shapesanity Stitched Painted", + "Cornered Singles Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Su Wr": "Shapesanity Stitched Painted", + "3-1 Su Wu": "Shapesanity Stitched Uncolored", + "Half-Half Su Wu": "Shapesanity Half-Half Uncolored", + "Checkered Su Wu": "Shapesanity Stitched Uncolored", + "Adjacent Singles Su Wu": "Shapesanity Stitched Uncolored", + "Cornered Singles Su Wu": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Su Wu": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Su Wu": "Shapesanity Stitched Uncolored", + "3-1 Su Ww": "Shapesanity Stitched Mixed", + "Half-Half Su Ww": "Shapesanity Half-Half Mixed", + "Checkered Su Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Su Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Ww": "Shapesanity Stitched Mixed", + "3-1 Su Wy": "Shapesanity Stitched Mixed", + "Half-Half Su Wy": "Shapesanity Half-Half Mixed", + "Checkered Su Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Su Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Su Wy": "Shapesanity Stitched Mixed", + "3-1 Sw Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Cb": "Shapesanity Stitched Mixed", + "3-1 Sw Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Cc": "Shapesanity Stitched Mixed", + "3-1 Sw Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Cg": "Shapesanity Stitched Mixed", + "3-1 Sw Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Cp": "Shapesanity Stitched Mixed", + "3-1 Sw Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Cr": "Shapesanity Stitched Mixed", + "3-1 Sw Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Cu": "Shapesanity Stitched Mixed", + "3-1 Sw Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Cw": "Shapesanity Stitched Mixed", + "3-1 Sw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Cy": "Shapesanity Stitched Mixed", + "3-1 Sw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Rb": "Shapesanity Stitched Mixed", + "3-1 Sw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Rc": "Shapesanity Stitched Mixed", + "3-1 Sw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Rg": "Shapesanity Stitched Mixed", + "3-1 Sw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Rp": "Shapesanity Stitched Mixed", + "3-1 Sw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Rr": "Shapesanity Stitched Mixed", + "3-1 Sw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Ru": "Shapesanity Stitched Mixed", + "3-1 Sw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Rw": "Shapesanity Stitched Mixed", + "3-1 Sw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Ry": "Shapesanity Stitched Mixed", + "3-1 Sw Sb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Sb": "Shapesanity Stitched Mixed", + "3-1 Sw Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Sc": "Shapesanity Stitched Mixed", + "3-1 Sw Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Sg": "Shapesanity Stitched Mixed", + "3-1 Sw Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Sp": "Shapesanity Stitched Mixed", + "3-1 Sw Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Sr": "Shapesanity Stitched Mixed", + "3-1 Sw Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Su": "Shapesanity Stitched Mixed", + "3-1 Sw Sy": "Shapesanity Colorful Full Mixed", + "Half-Half Sw Sy": "Shapesanity Colorful Full Mixed", + "Checkered Sw Sy": "Shapesanity Colorful Full Mixed", + "Adjacent Singles Sw Sy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Sy": "Shapesanity Stitched Mixed", + "3-1 Sw Wb": "Shapesanity Stitched Mixed", + "Half-Half Sw Wb": "Shapesanity Half-Half Mixed", + "Checkered Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Sw Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Wb": "Shapesanity Stitched Mixed", + "3-1 Sw Wc": "Shapesanity Stitched Mixed", + "Half-Half Sw Wc": "Shapesanity Half-Half Mixed", + "Checkered Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Sw Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Wc": "Shapesanity Stitched Mixed", + "3-1 Sw Wg": "Shapesanity Stitched Mixed", + "Half-Half Sw Wg": "Shapesanity Half-Half Mixed", + "Checkered Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Sw Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Wg": "Shapesanity Stitched Mixed", + "3-1 Sw Wp": "Shapesanity Stitched Mixed", + "Half-Half Sw Wp": "Shapesanity Half-Half Mixed", + "Checkered Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Sw Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Wp": "Shapesanity Stitched Mixed", + "3-1 Sw Wr": "Shapesanity Stitched Mixed", + "Half-Half Sw Wr": "Shapesanity Half-Half Mixed", + "Checkered Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Sw Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Wr": "Shapesanity Stitched Mixed", + "3-1 Sw Wu": "Shapesanity Stitched Mixed", + "Half-Half Sw Wu": "Shapesanity Half-Half Mixed", + "Checkered Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Sw Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Wu": "Shapesanity Stitched Mixed", + "3-1 Sw Ww": "Shapesanity Stitched Mixed", + "Half-Half Sw Ww": "Shapesanity Half-Half Mixed", + "Checkered Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Sw Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Ww": "Shapesanity Stitched Mixed", + "3-1 Sw Wy": "Shapesanity Stitched Mixed", + "Half-Half Sw Wy": "Shapesanity Half-Half Mixed", + "Checkered Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Sw Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sw Wy": "Shapesanity Stitched Mixed", + "3-1 Sy Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Cb": "Shapesanity Stitched Mixed", + "3-1 Sy Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Cc": "Shapesanity Stitched Mixed", + "3-1 Sy Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Cg": "Shapesanity Stitched Mixed", + "3-1 Sy Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Cp": "Shapesanity Stitched Mixed", + "3-1 Sy Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Cr": "Shapesanity Stitched Mixed", + "3-1 Sy Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Cu": "Shapesanity Stitched Mixed", + "3-1 Sy Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Cw": "Shapesanity Stitched Mixed", + "3-1 Sy Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Cy": "Shapesanity Stitched Mixed", + "3-1 Sy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Rb": "Shapesanity Stitched Mixed", + "3-1 Sy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Rc": "Shapesanity Stitched Mixed", + "3-1 Sy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Rg": "Shapesanity Stitched Mixed", + "3-1 Sy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Rp": "Shapesanity Stitched Mixed", + "3-1 Sy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Rr": "Shapesanity Stitched Mixed", + "3-1 Sy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Ru": "Shapesanity Stitched Mixed", + "3-1 Sy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Rw": "Shapesanity Stitched Mixed", + "3-1 Sy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Ry": "Shapesanity Stitched Mixed", + "3-1 Sy Sb": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Sb": "Shapesanity Stitched Mixed", + "3-1 Sy Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Sc": "Shapesanity Stitched Mixed", + "3-1 Sy Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Sg": "Shapesanity Stitched Mixed", + "3-1 Sy Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Sp": "Shapesanity Stitched Mixed", + "3-1 Sy Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Sr": "Shapesanity Stitched Mixed", + "3-1 Sy Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Su": "Shapesanity Stitched Mixed", + "3-1 Sy Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1 Sy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Sw": "Shapesanity Stitched Mixed", + "3-1 Sy Wb": "Shapesanity Stitched Mixed", + "Half-Half Sy Wb": "Shapesanity Half-Half Mixed", + "Checkered Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent Singles Sy Wb": "Shapesanity Stitched Mixed", + "Cornered Singles Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Wb": "Shapesanity Stitched Mixed", + "3-1 Sy Wc": "Shapesanity Stitched Mixed", + "Half-Half Sy Wc": "Shapesanity Half-Half Mixed", + "Checkered Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent Singles Sy Wc": "Shapesanity Stitched Mixed", + "Cornered Singles Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Wc": "Shapesanity Stitched Mixed", + "3-1 Sy Wg": "Shapesanity Stitched Mixed", + "Half-Half Sy Wg": "Shapesanity Half-Half Mixed", + "Checkered Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent Singles Sy Wg": "Shapesanity Stitched Mixed", + "Cornered Singles Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Wg": "Shapesanity Stitched Mixed", + "3-1 Sy Wp": "Shapesanity Stitched Mixed", + "Half-Half Sy Wp": "Shapesanity Half-Half Mixed", + "Checkered Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent Singles Sy Wp": "Shapesanity Stitched Mixed", + "Cornered Singles Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Wp": "Shapesanity Stitched Mixed", + "3-1 Sy Wr": "Shapesanity Stitched Mixed", + "Half-Half Sy Wr": "Shapesanity Half-Half Mixed", + "Checkered Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent Singles Sy Wr": "Shapesanity Stitched Mixed", + "Cornered Singles Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Wr": "Shapesanity Stitched Mixed", + "3-1 Sy Wu": "Shapesanity Stitched Mixed", + "Half-Half Sy Wu": "Shapesanity Half-Half Mixed", + "Checkered Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent Singles Sy Wu": "Shapesanity Stitched Mixed", + "Cornered Singles Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Wu": "Shapesanity Stitched Mixed", + "3-1 Sy Ww": "Shapesanity Stitched Mixed", + "Half-Half Sy Ww": "Shapesanity Half-Half Mixed", + "Checkered Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent Singles Sy Ww": "Shapesanity Stitched Mixed", + "Cornered Singles Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Ww": "Shapesanity Stitched Mixed", + "3-1 Sy Wy": "Shapesanity Stitched Mixed", + "Half-Half Sy Wy": "Shapesanity Half-Half Mixed", + "Checkered Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent Singles Sy Wy": "Shapesanity Stitched Mixed", + "Cornered Singles Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Sy Wy": "Shapesanity Stitched Mixed", + "3-1 Wb Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Cb": "Shapesanity Stitched Painted", + "3-1 Wb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Cc": "Shapesanity Stitched Mixed", + "3-1 Wb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Cg": "Shapesanity Stitched Painted", + "3-1 Wb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Cp": "Shapesanity Stitched Mixed", + "3-1 Wb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Cr": "Shapesanity Stitched Painted", + "3-1 Wb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Cu": "Shapesanity Stitched Painted", + "3-1 Wb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Cw": "Shapesanity Stitched Mixed", + "3-1 Wb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Cy": "Shapesanity Stitched Mixed", + "3-1 Wb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Rb": "Shapesanity Stitched Painted", + "3-1 Wb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Rc": "Shapesanity Stitched Mixed", + "3-1 Wb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Rg": "Shapesanity Stitched Painted", + "3-1 Wb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Rp": "Shapesanity Stitched Mixed", + "3-1 Wb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Rr": "Shapesanity Stitched Painted", + "3-1 Wb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Ru": "Shapesanity Stitched Painted", + "3-1 Wb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Rw": "Shapesanity Stitched Mixed", + "3-1 Wb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Ry": "Shapesanity Stitched Mixed", + "3-1 Wb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Sb": "Shapesanity Stitched Painted", + "3-1 Wb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Sc": "Shapesanity Stitched Mixed", + "3-1 Wb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Sg": "Shapesanity Stitched Painted", + "3-1 Wb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Sp": "Shapesanity Stitched Mixed", + "3-1 Wb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Sr": "Shapesanity Stitched Painted", + "3-1 Wb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Su": "Shapesanity Stitched Painted", + "3-1 Wb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Sw": "Shapesanity Stitched Mixed", + "3-1 Wb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Sy": "Shapesanity Stitched Mixed", + "3-1 Wb Wc": "Shapesanity East Windmill Mixed", + "Half-Half Wb Wc": "Shapesanity East Windmill Mixed", + "Checkered Wb Wc": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wb Wc": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Wc": "Shapesanity Stitched Mixed", + "3-1 Wb Wg": "Shapesanity East Windmill Painted", + "Half-Half Wb Wg": "Shapesanity East Windmill Painted", + "Checkered Wb Wg": "Shapesanity East Windmill Painted", + "Adjacent Singles Wb Wg": "Shapesanity Colorful Half Painted", + "Cornered Singles Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Wg": "Shapesanity Stitched Painted", + "3-1 Wb Wp": "Shapesanity East Windmill Mixed", + "Half-Half Wb Wp": "Shapesanity East Windmill Mixed", + "Checkered Wb Wp": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wb Wp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Wp": "Shapesanity Stitched Mixed", + "3-1 Wb Wr": "Shapesanity East Windmill Painted", + "Half-Half Wb Wr": "Shapesanity East Windmill Painted", + "Checkered Wb Wr": "Shapesanity East Windmill Painted", + "Adjacent Singles Wb Wr": "Shapesanity Colorful Half Painted", + "Cornered Singles Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Wr": "Shapesanity Stitched Painted", + "3-1 Wb Wu": "Shapesanity East Windmill Painted", + "Half-Half Wb Wu": "Shapesanity East Windmill Painted", + "Checkered Wb Wu": "Shapesanity East Windmill Painted", + "Adjacent Singles Wb Wu": "Shapesanity Colorful Half Painted", + "Cornered Singles Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Wb Wu": "Shapesanity Stitched Painted", + "3-1 Wb Ww": "Shapesanity East Windmill Mixed", + "Half-Half Wb Ww": "Shapesanity East Windmill Mixed", + "Checkered Wb Ww": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wb Ww": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Ww": "Shapesanity Stitched Mixed", + "3-1 Wb Wy": "Shapesanity East Windmill Mixed", + "Half-Half Wb Wy": "Shapesanity East Windmill Mixed", + "Checkered Wb Wy": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wb Wy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wb Wy": "Shapesanity Stitched Mixed", + "3-1 Wc Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Cb": "Shapesanity Stitched Mixed", + "3-1 Wc Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Cc": "Shapesanity Stitched Mixed", + "3-1 Wc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Cg": "Shapesanity Stitched Mixed", + "3-1 Wc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Cp": "Shapesanity Stitched Mixed", + "3-1 Wc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Cr": "Shapesanity Stitched Mixed", + "3-1 Wc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Cu": "Shapesanity Stitched Mixed", + "3-1 Wc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Cw": "Shapesanity Stitched Mixed", + "3-1 Wc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Cy": "Shapesanity Stitched Mixed", + "3-1 Wc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Rb": "Shapesanity Stitched Mixed", + "3-1 Wc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Rc": "Shapesanity Stitched Mixed", + "3-1 Wc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Rg": "Shapesanity Stitched Mixed", + "3-1 Wc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Rp": "Shapesanity Stitched Mixed", + "3-1 Wc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Rr": "Shapesanity Stitched Mixed", + "3-1 Wc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Ru": "Shapesanity Stitched Mixed", + "3-1 Wc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Rw": "Shapesanity Stitched Mixed", + "3-1 Wc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Ry": "Shapesanity Stitched Mixed", + "3-1 Wc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Sb": "Shapesanity Stitched Mixed", + "3-1 Wc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Sc": "Shapesanity Stitched Mixed", + "3-1 Wc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Sg": "Shapesanity Stitched Mixed", + "3-1 Wc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Sp": "Shapesanity Stitched Mixed", + "3-1 Wc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Sr": "Shapesanity Stitched Mixed", + "3-1 Wc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Su": "Shapesanity Stitched Mixed", + "3-1 Wc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Sw": "Shapesanity Stitched Mixed", + "3-1 Wc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Sy": "Shapesanity Stitched Mixed", + "3-1 Wc Wb": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Wb": "Shapesanity Stitched Mixed", + "3-1 Wc Wg": "Shapesanity East Windmill Mixed", + "Half-Half Wc Wg": "Shapesanity East Windmill Mixed", + "Checkered Wc Wg": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wc Wg": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Wg": "Shapesanity Stitched Mixed", + "3-1 Wc Wp": "Shapesanity East Windmill Mixed", + "Half-Half Wc Wp": "Shapesanity East Windmill Mixed", + "Checkered Wc Wp": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wc Wp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Wp": "Shapesanity Stitched Mixed", + "3-1 Wc Wr": "Shapesanity East Windmill Mixed", + "Half-Half Wc Wr": "Shapesanity East Windmill Mixed", + "Checkered Wc Wr": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wc Wr": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Wr": "Shapesanity Stitched Mixed", + "3-1 Wc Wu": "Shapesanity East Windmill Mixed", + "Half-Half Wc Wu": "Shapesanity East Windmill Mixed", + "Checkered Wc Wu": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wc Wu": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Wu": "Shapesanity Stitched Mixed", + "3-1 Wc Ww": "Shapesanity East Windmill Mixed", + "Half-Half Wc Ww": "Shapesanity East Windmill Mixed", + "Checkered Wc Ww": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wc Ww": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Ww": "Shapesanity Stitched Mixed", + "3-1 Wc Wy": "Shapesanity East Windmill Mixed", + "Half-Half Wc Wy": "Shapesanity East Windmill Mixed", + "Checkered Wc Wy": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wc Wy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wc Wy": "Shapesanity Stitched Mixed", + "3-1 Wg Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Cb": "Shapesanity Stitched Painted", + "3-1 Wg Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Cc": "Shapesanity Stitched Mixed", + "3-1 Wg Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Cg": "Shapesanity Stitched Painted", + "3-1 Wg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Cp": "Shapesanity Stitched Mixed", + "3-1 Wg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Cr": "Shapesanity Stitched Painted", + "3-1 Wg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Cu": "Shapesanity Stitched Painted", + "3-1 Wg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Cw": "Shapesanity Stitched Mixed", + "3-1 Wg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Cy": "Shapesanity Stitched Mixed", + "3-1 Wg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Rb": "Shapesanity Stitched Painted", + "3-1 Wg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Rc": "Shapesanity Stitched Mixed", + "3-1 Wg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Rg": "Shapesanity Stitched Painted", + "3-1 Wg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Rp": "Shapesanity Stitched Mixed", + "3-1 Wg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Rr": "Shapesanity Stitched Painted", + "3-1 Wg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Ru": "Shapesanity Stitched Painted", + "3-1 Wg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Rw": "Shapesanity Stitched Mixed", + "3-1 Wg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Ry": "Shapesanity Stitched Mixed", + "3-1 Wg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Sb": "Shapesanity Stitched Painted", + "3-1 Wg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Sc": "Shapesanity Stitched Mixed", + "3-1 Wg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Sg": "Shapesanity Stitched Painted", + "3-1 Wg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Sp": "Shapesanity Stitched Mixed", + "3-1 Wg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Sr": "Shapesanity Stitched Painted", + "3-1 Wg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Su": "Shapesanity Stitched Painted", + "3-1 Wg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Sw": "Shapesanity Stitched Mixed", + "3-1 Wg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Sy": "Shapesanity Stitched Mixed", + "3-1 Wg Wb": "Shapesanity East Windmill Painted", + "Adjacent 2-1 Wg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Wb": "Shapesanity Stitched Painted", + "3-1 Wg Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Wc": "Shapesanity Stitched Mixed", + "3-1 Wg Wp": "Shapesanity East Windmill Mixed", + "Half-Half Wg Wp": "Shapesanity East Windmill Mixed", + "Checkered Wg Wp": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wg Wp": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Wp": "Shapesanity Stitched Mixed", + "3-1 Wg Wr": "Shapesanity East Windmill Painted", + "Half-Half Wg Wr": "Shapesanity East Windmill Painted", + "Checkered Wg Wr": "Shapesanity East Windmill Painted", + "Adjacent Singles Wg Wr": "Shapesanity Colorful Half Painted", + "Cornered Singles Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Wr": "Shapesanity Stitched Painted", + "3-1 Wg Wu": "Shapesanity East Windmill Painted", + "Half-Half Wg Wu": "Shapesanity East Windmill Painted", + "Checkered Wg Wu": "Shapesanity East Windmill Painted", + "Adjacent Singles Wg Wu": "Shapesanity Colorful Half Painted", + "Cornered Singles Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Wg Wu": "Shapesanity Stitched Painted", + "3-1 Wg Ww": "Shapesanity East Windmill Mixed", + "Half-Half Wg Ww": "Shapesanity East Windmill Mixed", + "Checkered Wg Ww": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wg Ww": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Ww": "Shapesanity Stitched Mixed", + "3-1 Wg Wy": "Shapesanity East Windmill Mixed", + "Half-Half Wg Wy": "Shapesanity East Windmill Mixed", + "Checkered Wg Wy": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wg Wy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wg Wy": "Shapesanity Stitched Mixed", + "3-1 Wp Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Cb": "Shapesanity Stitched Mixed", + "3-1 Wp Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Cc": "Shapesanity Stitched Mixed", + "3-1 Wp Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Cg": "Shapesanity Stitched Mixed", + "3-1 Wp Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Cp": "Shapesanity Stitched Mixed", + "3-1 Wp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Cr": "Shapesanity Stitched Mixed", + "3-1 Wp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Cu": "Shapesanity Stitched Mixed", + "3-1 Wp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Cw": "Shapesanity Stitched Mixed", + "3-1 Wp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Cy": "Shapesanity Stitched Mixed", + "3-1 Wp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Rb": "Shapesanity Stitched Mixed", + "3-1 Wp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Rc": "Shapesanity Stitched Mixed", + "3-1 Wp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Rg": "Shapesanity Stitched Mixed", + "3-1 Wp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Rp": "Shapesanity Stitched Mixed", + "3-1 Wp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Rr": "Shapesanity Stitched Mixed", + "3-1 Wp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Ru": "Shapesanity Stitched Mixed", + "3-1 Wp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Rw": "Shapesanity Stitched Mixed", + "3-1 Wp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Ry": "Shapesanity Stitched Mixed", + "3-1 Wp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Sb": "Shapesanity Stitched Mixed", + "3-1 Wp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Sc": "Shapesanity Stitched Mixed", + "3-1 Wp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Sg": "Shapesanity Stitched Mixed", + "3-1 Wp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Sp": "Shapesanity Stitched Mixed", + "3-1 Wp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Sr": "Shapesanity Stitched Mixed", + "3-1 Wp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Su": "Shapesanity Stitched Mixed", + "3-1 Wp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Sw": "Shapesanity Stitched Mixed", + "3-1 Wp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Sy": "Shapesanity Stitched Mixed", + "3-1 Wp Wb": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Wb": "Shapesanity Stitched Mixed", + "3-1 Wp Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Wc": "Shapesanity Stitched Mixed", + "3-1 Wp Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Wg": "Shapesanity Stitched Mixed", + "3-1 Wp Wr": "Shapesanity East Windmill Mixed", + "Half-Half Wp Wr": "Shapesanity East Windmill Mixed", + "Checkered Wp Wr": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wp Wr": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Wr": "Shapesanity Stitched Mixed", + "3-1 Wp Wu": "Shapesanity East Windmill Mixed", + "Half-Half Wp Wu": "Shapesanity East Windmill Mixed", + "Checkered Wp Wu": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wp Wu": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Wu": "Shapesanity Stitched Mixed", + "3-1 Wp Ww": "Shapesanity East Windmill Mixed", + "Half-Half Wp Ww": "Shapesanity East Windmill Mixed", + "Checkered Wp Ww": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wp Ww": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Ww": "Shapesanity Stitched Mixed", + "3-1 Wp Wy": "Shapesanity East Windmill Mixed", + "Half-Half Wp Wy": "Shapesanity East Windmill Mixed", + "Checkered Wp Wy": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wp Wy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wp Wy": "Shapesanity Stitched Mixed", + "3-1 Wr Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Cb": "Shapesanity Stitched Painted", + "3-1 Wr Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Cc": "Shapesanity Stitched Mixed", + "3-1 Wr Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Cg": "Shapesanity Stitched Painted", + "3-1 Wr Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Cp": "Shapesanity Stitched Mixed", + "3-1 Wr Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Cr": "Shapesanity Stitched Painted", + "3-1 Wr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Cu": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Cu": "Shapesanity Stitched Painted", + "3-1 Wr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Cw": "Shapesanity Stitched Mixed", + "3-1 Wr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Cy": "Shapesanity Stitched Mixed", + "3-1 Wr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Rb": "Shapesanity Stitched Painted", + "3-1 Wr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Rc": "Shapesanity Stitched Mixed", + "3-1 Wr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Rg": "Shapesanity Stitched Painted", + "3-1 Wr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Rp": "Shapesanity Stitched Mixed", + "3-1 Wr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Rr": "Shapesanity Stitched Painted", + "3-1 Wr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Ru": "Shapesanity Stitched Painted", + "3-1 Wr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Rw": "Shapesanity Stitched Mixed", + "3-1 Wr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Ry": "Shapesanity Stitched Mixed", + "3-1 Wr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Sb": "Shapesanity Stitched Painted", + "3-1 Wr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Sc": "Shapesanity Stitched Mixed", + "3-1 Wr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Sg": "Shapesanity Stitched Painted", + "3-1 Wr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Sp": "Shapesanity Stitched Mixed", + "3-1 Wr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Sr": "Shapesanity Stitched Painted", + "3-1 Wr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Su": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Su": "Shapesanity Stitched Painted", + "3-1 Wr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Sw": "Shapesanity Stitched Mixed", + "3-1 Wr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Sy": "Shapesanity Stitched Mixed", + "3-1 Wr Wb": "Shapesanity East Windmill Painted", + "Adjacent 2-1 Wr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Wb": "Shapesanity Stitched Painted", + "3-1 Wr Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Wc": "Shapesanity Stitched Mixed", + "3-1 Wr Wg": "Shapesanity East Windmill Painted", + "Adjacent 2-1 Wr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Wg": "Shapesanity Stitched Painted", + "3-1 Wr Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Wp": "Shapesanity Stitched Mixed", + "3-1 Wr Wu": "Shapesanity East Windmill Painted", + "Half-Half Wr Wu": "Shapesanity East Windmill Painted", + "Checkered Wr Wu": "Shapesanity East Windmill Painted", + "Adjacent Singles Wr Wu": "Shapesanity Colorful Half Painted", + "Cornered Singles Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1 Wr Wu": "Shapesanity Stitched Painted", + "3-1 Wr Ww": "Shapesanity East Windmill Mixed", + "Half-Half Wr Ww": "Shapesanity East Windmill Mixed", + "Checkered Wr Ww": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wr Ww": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Ww": "Shapesanity Stitched Mixed", + "3-1 Wr Wy": "Shapesanity East Windmill Mixed", + "Half-Half Wr Wy": "Shapesanity East Windmill Mixed", + "Checkered Wr Wy": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wr Wy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wr Wy": "Shapesanity Stitched Mixed", + "3-1 Wu Cb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wu Cb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Cb": "Shapesanity Stitched Painted", + "3-1 Wu Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Cc": "Shapesanity Stitched Mixed", + "3-1 Wu Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wu Cg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Cg": "Shapesanity Stitched Painted", + "3-1 Wu Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Cp": "Shapesanity Stitched Mixed", + "3-1 Wu Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wu Cr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Cr": "Shapesanity Stitched Painted", + "3-1 Wu Cu": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Wu Cu": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Wu Cu": "Shapesanity Stitched Uncolored", + "3-1 Wu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Cw": "Shapesanity Stitched Mixed", + "3-1 Wu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Cy": "Shapesanity Stitched Mixed", + "3-1 Wu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Rb": "Shapesanity Stitched Painted", + "3-1 Wu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Rc": "Shapesanity Stitched Mixed", + "3-1 Wu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Rg": "Shapesanity Stitched Painted", + "3-1 Wu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Rp": "Shapesanity Stitched Mixed", + "3-1 Wu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Rr": "Shapesanity Stitched Painted", + "3-1 Wu Ru": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Wu Ru": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Wu Ru": "Shapesanity Stitched Uncolored", + "3-1 Wu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Rw": "Shapesanity Stitched Mixed", + "3-1 Wu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Ry": "Shapesanity Stitched Mixed", + "3-1 Wu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Sb": "Shapesanity Stitched Painted", + "3-1 Wu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Sc": "Shapesanity Stitched Mixed", + "3-1 Wu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Sg": "Shapesanity Stitched Painted", + "3-1 Wu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Sp": "Shapesanity Stitched Mixed", + "3-1 Wu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1 Wu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Sr": "Shapesanity Stitched Painted", + "3-1 Wu Su": "Shapesanity Stitched Uncolored", + "Adjacent 2-1 Wu Su": "Shapesanity Stitched Uncolored", + "Cornered 2-1 Wu Su": "Shapesanity Stitched Uncolored", + "3-1 Wu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Sw": "Shapesanity Stitched Mixed", + "3-1 Wu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Sy": "Shapesanity Stitched Mixed", + "3-1 Wu Wb": "Shapesanity East Windmill Painted", + "Adjacent 2-1 Wu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Wb": "Shapesanity Stitched Painted", + "3-1 Wu Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Wc": "Shapesanity Stitched Mixed", + "3-1 Wu Wg": "Shapesanity East Windmill Painted", + "Adjacent 2-1 Wu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Wg": "Shapesanity Stitched Painted", + "3-1 Wu Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Wp": "Shapesanity Stitched Mixed", + "3-1 Wu Wr": "Shapesanity East Windmill Painted", + "Adjacent 2-1 Wu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1 Wu Wr": "Shapesanity Stitched Painted", + "3-1 Wu Ww": "Shapesanity East Windmill Mixed", + "Half-Half Wu Ww": "Shapesanity East Windmill Mixed", + "Checkered Wu Ww": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wu Ww": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Ww": "Shapesanity Stitched Mixed", + "3-1 Wu Wy": "Shapesanity East Windmill Mixed", + "Half-Half Wu Wy": "Shapesanity East Windmill Mixed", + "Checkered Wu Wy": "Shapesanity East Windmill Mixed", + "Adjacent Singles Wu Wy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wu Wy": "Shapesanity Stitched Mixed", + "3-1 Ww Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Cb": "Shapesanity Stitched Mixed", + "3-1 Ww Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Cc": "Shapesanity Stitched Mixed", + "3-1 Ww Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Cg": "Shapesanity Stitched Mixed", + "3-1 Ww Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Cp": "Shapesanity Stitched Mixed", + "3-1 Ww Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Cr": "Shapesanity Stitched Mixed", + "3-1 Ww Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Cu": "Shapesanity Stitched Mixed", + "3-1 Ww Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Cw": "Shapesanity Stitched Mixed", + "3-1 Ww Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Cy": "Shapesanity Stitched Mixed", + "3-1 Ww Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Rb": "Shapesanity Stitched Mixed", + "3-1 Ww Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Rc": "Shapesanity Stitched Mixed", + "3-1 Ww Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Rg": "Shapesanity Stitched Mixed", + "3-1 Ww Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Rp": "Shapesanity Stitched Mixed", + "3-1 Ww Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Rr": "Shapesanity Stitched Mixed", + "3-1 Ww Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Ru": "Shapesanity Stitched Mixed", + "3-1 Ww Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Rw": "Shapesanity Stitched Mixed", + "3-1 Ww Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Ry": "Shapesanity Stitched Mixed", + "3-1 Ww Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Sb": "Shapesanity Stitched Mixed", + "3-1 Ww Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Sc": "Shapesanity Stitched Mixed", + "3-1 Ww Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Sg": "Shapesanity Stitched Mixed", + "3-1 Ww Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Sp": "Shapesanity Stitched Mixed", + "3-1 Ww Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Sr": "Shapesanity Stitched Mixed", + "3-1 Ww Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Su": "Shapesanity Stitched Mixed", + "3-1 Ww Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Sw": "Shapesanity Stitched Mixed", + "3-1 Ww Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Sy": "Shapesanity Stitched Mixed", + "3-1 Ww Wb": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Ww Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Wb": "Shapesanity Stitched Mixed", + "3-1 Ww Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Ww Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Wc": "Shapesanity Stitched Mixed", + "3-1 Ww Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Ww Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Wg": "Shapesanity Stitched Mixed", + "3-1 Ww Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Ww Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Wp": "Shapesanity Stitched Mixed", + "3-1 Ww Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Ww Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Wr": "Shapesanity Stitched Mixed", + "3-1 Ww Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Ww Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Wu": "Shapesanity Stitched Mixed", + "3-1 Ww Wy": "Shapesanity East Windmill Mixed", + "Half-Half Ww Wy": "Shapesanity East Windmill Mixed", + "Checkered Ww Wy": "Shapesanity East Windmill Mixed", + "Adjacent Singles Ww Wy": "Shapesanity Colorful Half Mixed", + "Cornered Singles Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Ww Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Ww Wy": "Shapesanity Stitched Mixed", + "3-1 Wy Cb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Cb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Cb": "Shapesanity Stitched Mixed", + "3-1 Wy Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Cc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Cc": "Shapesanity Stitched Mixed", + "3-1 Wy Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Cg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Cg": "Shapesanity Stitched Mixed", + "3-1 Wy Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Cp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Cp": "Shapesanity Stitched Mixed", + "3-1 Wy Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Cr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Cr": "Shapesanity Stitched Mixed", + "3-1 Wy Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Cu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Cu": "Shapesanity Stitched Mixed", + "3-1 Wy Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Cw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Cw": "Shapesanity Stitched Mixed", + "3-1 Wy Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Cy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Cy": "Shapesanity Stitched Mixed", + "3-1 Wy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Rb": "Shapesanity Stitched Mixed", + "3-1 Wy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Rc": "Shapesanity Stitched Mixed", + "3-1 Wy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Rg": "Shapesanity Stitched Mixed", + "3-1 Wy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Rp": "Shapesanity Stitched Mixed", + "3-1 Wy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Rr": "Shapesanity Stitched Mixed", + "3-1 Wy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Ru": "Shapesanity Stitched Mixed", + "3-1 Wy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Rw": "Shapesanity Stitched Mixed", + "3-1 Wy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Ry": "Shapesanity Stitched Mixed", + "3-1 Wy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Sb": "Shapesanity Stitched Mixed", + "3-1 Wy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Sc": "Shapesanity Stitched Mixed", + "3-1 Wy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Sg": "Shapesanity Stitched Mixed", + "3-1 Wy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Sp": "Shapesanity Stitched Mixed", + "3-1 Wy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Sr": "Shapesanity Stitched Mixed", + "3-1 Wy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Su": "Shapesanity Stitched Mixed", + "3-1 Wy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Sw": "Shapesanity Stitched Mixed", + "3-1 Wy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1 Wy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Sy": "Shapesanity Stitched Mixed", + "3-1 Wy Wb": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Wb": "Shapesanity Stitched Mixed", + "3-1 Wy Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Wc": "Shapesanity Stitched Mixed", + "3-1 Wy Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Wg": "Shapesanity Stitched Mixed", + "3-1 Wy Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Wp": "Shapesanity Stitched Mixed", + "3-1 Wy Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Wr": "Shapesanity Stitched Mixed", + "3-1 Wy Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Wu": "Shapesanity Stitched Mixed", + "3-1 Wy Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1 Wy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1 Wy Ww": "Shapesanity Stitched Mixed", +} + +shapesanity_three_parts = { + "Adjacent 2-1-1 Cb Cc Cg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cc Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cc Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cc Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cc Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cc Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cc Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cc Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cc Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cc Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cc Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cc Cy": "Shapesanity Colorful Full Mixed", + "Singles Cb Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cg Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cg Cr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cb Cg Cr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cb Cg Cu": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cb Cg Cu": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cb Cg Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cg Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cg Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cg Cy": "Shapesanity Colorful Full Mixed", + "Singles Cb Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Rb": "Shapesanity Stitched Painted", + "Singles Cb Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Rg": "Shapesanity Stitched Painted", + "Singles Cb Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Rr": "Shapesanity Stitched Painted", + "Singles Cb Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Ru": "Shapesanity Stitched Painted", + "Singles Cb Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Sb": "Shapesanity Stitched Painted", + "Singles Cb Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Sg": "Shapesanity Stitched Painted", + "Singles Cb Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Sr": "Shapesanity Stitched Painted", + "Singles Cb Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Su": "Shapesanity Stitched Painted", + "Singles Cb Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cg Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cp Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cp Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cp Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cp Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cp Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cp Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cp Cy": "Shapesanity Colorful Full Mixed", + "Singles Cb Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Cu": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cb Cr Cu": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cb Cr Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cr Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cr Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cr Cy": "Shapesanity Colorful Full Mixed", + "Singles Cb Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Rb": "Shapesanity Stitched Painted", + "Singles Cb Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Rg": "Shapesanity Stitched Painted", + "Singles Cb Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Rr": "Shapesanity Stitched Painted", + "Singles Cb Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Ru": "Shapesanity Stitched Painted", + "Singles Cb Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Sb": "Shapesanity Stitched Painted", + "Singles Cb Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Sg": "Shapesanity Stitched Painted", + "Singles Cb Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Sr": "Shapesanity Stitched Painted", + "Singles Cb Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Su": "Shapesanity Stitched Painted", + "Singles Cb Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Wb": "Shapesanity Stitched Painted", + "Singles Cb Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Wg": "Shapesanity Stitched Painted", + "Singles Cb Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Wr": "Shapesanity Stitched Painted", + "Singles Cb Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cr Wu": "Shapesanity Stitched Painted", + "Singles Cb Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cu Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cb Cu Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cu Cy": "Shapesanity Colorful Full Mixed", + "Singles Cb Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Rb": "Shapesanity Stitched Painted", + "Singles Cb Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Rg": "Shapesanity Stitched Painted", + "Singles Cb Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Rr": "Shapesanity Stitched Painted", + "Singles Cb Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Ru": "Shapesanity Stitched Painted", + "Singles Cb Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Sb": "Shapesanity Stitched Painted", + "Singles Cb Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Sg": "Shapesanity Stitched Painted", + "Singles Cb Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Sr": "Shapesanity Stitched Painted", + "Singles Cb Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Su": "Shapesanity Stitched Painted", + "Singles Cb Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Wb": "Shapesanity Stitched Painted", + "Singles Cb Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Wg": "Shapesanity Stitched Painted", + "Singles Cb Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Wr": "Shapesanity Stitched Painted", + "Singles Cb Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Cu Wu": "Shapesanity Stitched Painted", + "Singles Cb Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cb Cw Cy": "Shapesanity Colorful Full Mixed", + "Singles Cb Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Su": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rb Rc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Rb Rg": "Shapesanity Stitched Painted", + "Singles Cb Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rb Rp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Rb Rr": "Shapesanity Stitched Painted", + "Singles Cb Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Rb Ru": "Shapesanity Stitched Painted", + "Singles Cb Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rb Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rb Sb": "Shapesanity Stitched Painted", + "Singles Cb Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rb Sg": "Shapesanity Stitched Painted", + "Singles Cb Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rb Sr": "Shapesanity Stitched Painted", + "Singles Cb Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rb Su": "Shapesanity Stitched Painted", + "Singles Cb Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rb Wb": "Shapesanity Stitched Painted", + "Singles Cb Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rb Wg": "Shapesanity Stitched Painted", + "Singles Cb Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rb Wr": "Shapesanity Stitched Painted", + "Singles Cb Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rb Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Rg Rr": "Shapesanity Stitched Painted", + "Singles Cb Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Rg Ru": "Shapesanity Stitched Painted", + "Singles Cb Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rg Sb": "Shapesanity Stitched Painted", + "Singles Cb Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rg Sg": "Shapesanity Stitched Painted", + "Singles Cb Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rg Sr": "Shapesanity Stitched Painted", + "Singles Cb Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rg Su": "Shapesanity Stitched Painted", + "Singles Cb Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rg Wb": "Shapesanity Stitched Painted", + "Singles Cb Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rg Wg": "Shapesanity Stitched Painted", + "Singles Cb Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rg Wr": "Shapesanity Stitched Painted", + "Singles Cb Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rg Wu": "Shapesanity Stitched Painted", + "Singles Cb Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Rr Ru": "Shapesanity Stitched Painted", + "Singles Cb Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rr Sb": "Shapesanity Stitched Painted", + "Singles Cb Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rr Sg": "Shapesanity Stitched Painted", + "Singles Cb Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rr Sr": "Shapesanity Stitched Painted", + "Singles Cb Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rr Su": "Shapesanity Stitched Painted", + "Singles Cb Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rr Wb": "Shapesanity Stitched Painted", + "Singles Cb Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rr Wg": "Shapesanity Stitched Painted", + "Singles Cb Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rr Wr": "Shapesanity Stitched Painted", + "Singles Cb Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Rr Wu": "Shapesanity Stitched Painted", + "Singles Cb Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Ru Sb": "Shapesanity Stitched Painted", + "Singles Cb Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Ru Sg": "Shapesanity Stitched Painted", + "Singles Cb Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Ru Sr": "Shapesanity Stitched Painted", + "Singles Cb Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Ru Su": "Shapesanity Stitched Painted", + "Singles Cb Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Ru Wb": "Shapesanity Stitched Painted", + "Singles Cb Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Ru Wg": "Shapesanity Stitched Painted", + "Singles Cb Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Ru Wr": "Shapesanity Stitched Painted", + "Singles Cb Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Ru Wu": "Shapesanity Stitched Painted", + "Singles Cb Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Sb Sg": "Shapesanity Stitched Painted", + "Singles Cb Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Sb Sr": "Shapesanity Stitched Painted", + "Singles Cb Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Sb Su": "Shapesanity Stitched Painted", + "Singles Cb Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sb Wb": "Shapesanity Stitched Painted", + "Singles Cb Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sb Wg": "Shapesanity Stitched Painted", + "Singles Cb Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sb Wr": "Shapesanity Stitched Painted", + "Singles Cb Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sb Wu": "Shapesanity Stitched Painted", + "Singles Cb Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Sg Sr": "Shapesanity Stitched Painted", + "Singles Cb Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Sg Su": "Shapesanity Stitched Painted", + "Singles Cb Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sg Wb": "Shapesanity Stitched Painted", + "Singles Cb Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sg Wg": "Shapesanity Stitched Painted", + "Singles Cb Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sg Wr": "Shapesanity Stitched Painted", + "Singles Cb Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sg Wu": "Shapesanity Stitched Painted", + "Singles Cb Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Sr Su": "Shapesanity Stitched Painted", + "Singles Cb Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sr Wb": "Shapesanity Stitched Painted", + "Singles Cb Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sr Wg": "Shapesanity Stitched Painted", + "Singles Cb Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sr Wr": "Shapesanity Stitched Painted", + "Singles Cb Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Sr Wu": "Shapesanity Stitched Painted", + "Singles Cb Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cb Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Wb Wg": "Shapesanity Stitched Painted", + "Singles Cb Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Wb Wr": "Shapesanity Stitched Painted", + "Singles Cb Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Wb Wu": "Shapesanity Stitched Painted", + "Singles Cb Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cb Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cb Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cb Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cb Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cb Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Cg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cb Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cb Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cb Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cb Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cb Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cb Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cb Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cb Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cb Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cb Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cb Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cg Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cg Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cg Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cg Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cg Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cg Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cg Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cg Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cg Cy": "Shapesanity Colorful Full Mixed", + "Singles Cc Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cp Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cp Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cp Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cp Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cp Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cp Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cp Cy": "Shapesanity Colorful Full Mixed", + "Singles Cc Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cr Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cr Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cr Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cr Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cr Cy": "Shapesanity Colorful Full Mixed", + "Singles Cc Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cu Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cc Cu Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cu Cy": "Shapesanity Colorful Full Mixed", + "Singles Cc Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cc Cw Cy": "Shapesanity Colorful Full Mixed", + "Singles Cc Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Su": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rb Rc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rb Rg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rb Rp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rb Rr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rb Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rb Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rb Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Su": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sb Su": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sc Su": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cc Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cc Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Cc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cb Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cb Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cb Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cb Cr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cg Cb Cr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cg Cb Cu": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cg Cb Cu": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cg Cb Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cb Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cb Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cb Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cc Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cc Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cc Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cc Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cc Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cc Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cc Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cc Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cc Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cp Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cp Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cp Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cp Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cp Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cp Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cp Cy": "Shapesanity Colorful Full Mixed", + "Singles Cg Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Cu": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cg Cr Cu": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cg Cr Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cr Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cr Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cr Cy": "Shapesanity Colorful Full Mixed", + "Singles Cg Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Rb": "Shapesanity Stitched Painted", + "Singles Cg Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Rg": "Shapesanity Stitched Painted", + "Singles Cg Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Rr": "Shapesanity Stitched Painted", + "Singles Cg Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Ru": "Shapesanity Stitched Painted", + "Singles Cg Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Sb": "Shapesanity Stitched Painted", + "Singles Cg Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Sg": "Shapesanity Stitched Painted", + "Singles Cg Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Sr": "Shapesanity Stitched Painted", + "Singles Cg Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Su": "Shapesanity Stitched Painted", + "Singles Cg Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Wb": "Shapesanity Stitched Painted", + "Singles Cg Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Wg": "Shapesanity Stitched Painted", + "Singles Cg Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Wr": "Shapesanity Stitched Painted", + "Singles Cg Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cr Wu": "Shapesanity Stitched Painted", + "Singles Cg Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cu Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cg Cu Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cu Cy": "Shapesanity Colorful Full Mixed", + "Singles Cg Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Rb": "Shapesanity Stitched Painted", + "Singles Cg Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Rg": "Shapesanity Stitched Painted", + "Singles Cg Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Rr": "Shapesanity Stitched Painted", + "Singles Cg Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Ru": "Shapesanity Stitched Painted", + "Singles Cg Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Sb": "Shapesanity Stitched Painted", + "Singles Cg Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Sg": "Shapesanity Stitched Painted", + "Singles Cg Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Sr": "Shapesanity Stitched Painted", + "Singles Cg Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Su": "Shapesanity Stitched Painted", + "Singles Cg Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Wb": "Shapesanity Stitched Painted", + "Singles Cg Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Wg": "Shapesanity Stitched Painted", + "Singles Cg Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Wr": "Shapesanity Stitched Painted", + "Singles Cg Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Cu Wu": "Shapesanity Stitched Painted", + "Singles Cg Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cg Cw Cy": "Shapesanity Colorful Full Mixed", + "Singles Cg Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Su": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Su": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rb Rc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Rb Rg": "Shapesanity Stitched Painted", + "Singles Cg Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rb Rp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Rb Rr": "Shapesanity Stitched Painted", + "Singles Cg Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Rb Ru": "Shapesanity Stitched Painted", + "Singles Cg Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rb Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rb Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rb Sb": "Shapesanity Stitched Painted", + "Singles Cg Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rb Sg": "Shapesanity Stitched Painted", + "Singles Cg Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rb Sr": "Shapesanity Stitched Painted", + "Singles Cg Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rb Su": "Shapesanity Stitched Painted", + "Singles Cg Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rb Wb": "Shapesanity Stitched Painted", + "Singles Cg Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rb Wg": "Shapesanity Stitched Painted", + "Singles Cg Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rb Wr": "Shapesanity Stitched Painted", + "Singles Cg Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rb Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Rg Rr": "Shapesanity Stitched Painted", + "Singles Cg Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Rg Ru": "Shapesanity Stitched Painted", + "Singles Cg Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rg Sb": "Shapesanity Stitched Painted", + "Singles Cg Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rg Sg": "Shapesanity Stitched Painted", + "Singles Cg Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rg Sr": "Shapesanity Stitched Painted", + "Singles Cg Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rg Su": "Shapesanity Stitched Painted", + "Singles Cg Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rg Wb": "Shapesanity Stitched Painted", + "Singles Cg Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rg Wg": "Shapesanity Stitched Painted", + "Singles Cg Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rg Wr": "Shapesanity Stitched Painted", + "Singles Cg Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rg Wu": "Shapesanity Stitched Painted", + "Singles Cg Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Rr Ru": "Shapesanity Stitched Painted", + "Singles Cg Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rr Sb": "Shapesanity Stitched Painted", + "Singles Cg Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rr Sg": "Shapesanity Stitched Painted", + "Singles Cg Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rr Sr": "Shapesanity Stitched Painted", + "Singles Cg Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rr Su": "Shapesanity Stitched Painted", + "Singles Cg Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rr Wb": "Shapesanity Stitched Painted", + "Singles Cg Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rr Wg": "Shapesanity Stitched Painted", + "Singles Cg Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rr Wr": "Shapesanity Stitched Painted", + "Singles Cg Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Rr Wu": "Shapesanity Stitched Painted", + "Singles Cg Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Ru Sb": "Shapesanity Stitched Painted", + "Singles Cg Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Ru Sg": "Shapesanity Stitched Painted", + "Singles Cg Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Ru Sr": "Shapesanity Stitched Painted", + "Singles Cg Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Ru Su": "Shapesanity Stitched Painted", + "Singles Cg Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Ru Wb": "Shapesanity Stitched Painted", + "Singles Cg Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Ru Wg": "Shapesanity Stitched Painted", + "Singles Cg Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Ru Wr": "Shapesanity Stitched Painted", + "Singles Cg Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Ru Wu": "Shapesanity Stitched Painted", + "Singles Cg Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Sb Sg": "Shapesanity Stitched Painted", + "Singles Cg Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Sb Sr": "Shapesanity Stitched Painted", + "Singles Cg Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Sb Su": "Shapesanity Stitched Painted", + "Singles Cg Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sb Wb": "Shapesanity Stitched Painted", + "Singles Cg Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sb Wg": "Shapesanity Stitched Painted", + "Singles Cg Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sb Wr": "Shapesanity Stitched Painted", + "Singles Cg Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sb Wu": "Shapesanity Stitched Painted", + "Singles Cg Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sc Su": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Sg Sr": "Shapesanity Stitched Painted", + "Singles Cg Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Sg Su": "Shapesanity Stitched Painted", + "Singles Cg Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sg Wb": "Shapesanity Stitched Painted", + "Singles Cg Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sg Wg": "Shapesanity Stitched Painted", + "Singles Cg Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sg Wr": "Shapesanity Stitched Painted", + "Singles Cg Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sg Wu": "Shapesanity Stitched Painted", + "Singles Cg Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Sr Su": "Shapesanity Stitched Painted", + "Singles Cg Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sr Wb": "Shapesanity Stitched Painted", + "Singles Cg Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sr Wg": "Shapesanity Stitched Painted", + "Singles Cg Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sr Wr": "Shapesanity Stitched Painted", + "Singles Cg Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Sr Wu": "Shapesanity Stitched Painted", + "Singles Cg Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Su Wb": "Shapesanity Stitched Painted", + "Singles Cg Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Su Wg": "Shapesanity Stitched Painted", + "Singles Cg Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Su Wr": "Shapesanity Stitched Painted", + "Singles Cg Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cg Su Wu": "Shapesanity Stitched Painted", + "Singles Cg Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Wb Wg": "Shapesanity Stitched Painted", + "Singles Cg Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Wb Wr": "Shapesanity Stitched Painted", + "Singles Cg Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Wb Wu": "Shapesanity Stitched Painted", + "Singles Cg Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Wg Wr": "Shapesanity Stitched Painted", + "Singles Cg Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Wg Wu": "Shapesanity Stitched Painted", + "Singles Cg Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cg Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cg Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cg Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Cc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cb Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cb Cg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cb Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cb Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cb Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cb Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cb Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cb Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cb Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cb Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cb Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Cg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cc Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cc Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cc Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cc Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cc Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cc Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cc Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cc Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cc Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cg Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cg Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cg Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cg Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cg Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cg Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cg Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cr Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cr Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cr Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cr Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cr Cy": "Shapesanity Colorful Full Mixed", + "Singles Cp Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Rb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Rc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Rg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Rp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Rr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Ru": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Rw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Ry": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cu Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cp Cu Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cu Cy": "Shapesanity Colorful Full Mixed", + "Singles Cp Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Rb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Rg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Rr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Ru": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cp Cw Cy": "Shapesanity Colorful Full Mixed", + "Singles Cp Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Su": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Su": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rb Rc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rb Rg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rb Rp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rb Rr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rb Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rb Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rb Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Su": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sb Su": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sc Su": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cp Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Cc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cb Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cb Cg": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cr Cb Cg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cr Cb Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cb Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cb Cu": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cr Cb Cu": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cr Cb Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cb Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cb Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cb Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Cg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cc Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cc Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cc Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cc Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cc Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cc Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cc Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cc Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cc Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cg Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cg Cu": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cr Cg Cu": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cr Cg Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cg Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cg Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cg Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cp Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cp Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cp Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cp Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cp Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cu Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cr Cu Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cu Cy": "Shapesanity Colorful Full Mixed", + "Singles Cr Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Rb": "Shapesanity Stitched Painted", + "Singles Cr Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Rg": "Shapesanity Stitched Painted", + "Singles Cr Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Rr": "Shapesanity Stitched Painted", + "Singles Cr Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Ru": "Shapesanity Stitched Painted", + "Singles Cr Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Sb": "Shapesanity Stitched Painted", + "Singles Cr Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Sg": "Shapesanity Stitched Painted", + "Singles Cr Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Sr": "Shapesanity Stitched Painted", + "Singles Cr Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Su": "Shapesanity Stitched Painted", + "Singles Cr Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Wb": "Shapesanity Stitched Painted", + "Singles Cr Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Wg": "Shapesanity Stitched Painted", + "Singles Cr Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Wr": "Shapesanity Stitched Painted", + "Singles Cr Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Cu Wu": "Shapesanity Stitched Painted", + "Singles Cr Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cr Cw Cy": "Shapesanity Colorful Full Mixed", + "Singles Cr Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Su": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Su": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rb Rc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Rb Rg": "Shapesanity Stitched Painted", + "Singles Cr Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rb Rp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Rb Rr": "Shapesanity Stitched Painted", + "Singles Cr Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Rb Ru": "Shapesanity Stitched Painted", + "Singles Cr Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rb Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rb Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rb Sb": "Shapesanity Stitched Painted", + "Singles Cr Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rb Sg": "Shapesanity Stitched Painted", + "Singles Cr Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rb Sr": "Shapesanity Stitched Painted", + "Singles Cr Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rb Su": "Shapesanity Stitched Painted", + "Singles Cr Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rb Wb": "Shapesanity Stitched Painted", + "Singles Cr Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rb Wg": "Shapesanity Stitched Painted", + "Singles Cr Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rb Wr": "Shapesanity Stitched Painted", + "Singles Cr Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rb Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Rg Rr": "Shapesanity Stitched Painted", + "Singles Cr Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Rg Ru": "Shapesanity Stitched Painted", + "Singles Cr Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rg Sb": "Shapesanity Stitched Painted", + "Singles Cr Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rg Sg": "Shapesanity Stitched Painted", + "Singles Cr Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rg Sr": "Shapesanity Stitched Painted", + "Singles Cr Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rg Su": "Shapesanity Stitched Painted", + "Singles Cr Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rg Wb": "Shapesanity Stitched Painted", + "Singles Cr Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rg Wg": "Shapesanity Stitched Painted", + "Singles Cr Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rg Wr": "Shapesanity Stitched Painted", + "Singles Cr Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rg Wu": "Shapesanity Stitched Painted", + "Singles Cr Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Su": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Rr Ru": "Shapesanity Stitched Painted", + "Singles Cr Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rr Sb": "Shapesanity Stitched Painted", + "Singles Cr Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rr Sg": "Shapesanity Stitched Painted", + "Singles Cr Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rr Sr": "Shapesanity Stitched Painted", + "Singles Cr Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rr Su": "Shapesanity Stitched Painted", + "Singles Cr Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rr Wb": "Shapesanity Stitched Painted", + "Singles Cr Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rr Wg": "Shapesanity Stitched Painted", + "Singles Cr Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rr Wr": "Shapesanity Stitched Painted", + "Singles Cr Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Rr Wu": "Shapesanity Stitched Painted", + "Singles Cr Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Ru Sb": "Shapesanity Stitched Painted", + "Singles Cr Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Ru Sg": "Shapesanity Stitched Painted", + "Singles Cr Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Ru Sr": "Shapesanity Stitched Painted", + "Singles Cr Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Ru Su": "Shapesanity Stitched Painted", + "Singles Cr Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Ru Wb": "Shapesanity Stitched Painted", + "Singles Cr Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Ru Wg": "Shapesanity Stitched Painted", + "Singles Cr Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Ru Wr": "Shapesanity Stitched Painted", + "Singles Cr Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Ru Wu": "Shapesanity Stitched Painted", + "Singles Cr Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Sb Sg": "Shapesanity Stitched Painted", + "Singles Cr Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Sb Sr": "Shapesanity Stitched Painted", + "Singles Cr Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Sb Su": "Shapesanity Stitched Painted", + "Singles Cr Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sb Wb": "Shapesanity Stitched Painted", + "Singles Cr Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sb Wg": "Shapesanity Stitched Painted", + "Singles Cr Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sb Wr": "Shapesanity Stitched Painted", + "Singles Cr Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sb Wu": "Shapesanity Stitched Painted", + "Singles Cr Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sc Su": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Sg Sr": "Shapesanity Stitched Painted", + "Singles Cr Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Sg Su": "Shapesanity Stitched Painted", + "Singles Cr Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sg Wb": "Shapesanity Stitched Painted", + "Singles Cr Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sg Wg": "Shapesanity Stitched Painted", + "Singles Cr Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sg Wr": "Shapesanity Stitched Painted", + "Singles Cr Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sg Wu": "Shapesanity Stitched Painted", + "Singles Cr Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Sr Su": "Shapesanity Stitched Painted", + "Singles Cr Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sr Wb": "Shapesanity Stitched Painted", + "Singles Cr Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sr Wg": "Shapesanity Stitched Painted", + "Singles Cr Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sr Wr": "Shapesanity Stitched Painted", + "Singles Cr Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Sr Wu": "Shapesanity Stitched Painted", + "Singles Cr Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Su Wb": "Shapesanity Stitched Painted", + "Singles Cr Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Su Wg": "Shapesanity Stitched Painted", + "Singles Cr Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Su Wr": "Shapesanity Stitched Painted", + "Singles Cr Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cr Su Wu": "Shapesanity Stitched Painted", + "Singles Cr Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Wb Wg": "Shapesanity Stitched Painted", + "Singles Cr Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Wb Wr": "Shapesanity Stitched Painted", + "Singles Cr Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Wb Wu": "Shapesanity Stitched Painted", + "Singles Cr Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Wg Wr": "Shapesanity Stitched Painted", + "Singles Cr Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Wg Wu": "Shapesanity Stitched Painted", + "Singles Cr Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cr Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cr Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cr Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Cc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cb Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cb Cg": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cu Cb Cg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cu Cb Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cb Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cb Cr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cu Cb Cr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cu Cb Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cb Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cb Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cb Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Cg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cc Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cc Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cc Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cc Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cc Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cc Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cc Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cc Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cc Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cg Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cg Cr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Cu Cg Cr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Cu Cg Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cg Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cg Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cg Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cp Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cp Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cp Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cp Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cp Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cr Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cr Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cr Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cu Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cu Cw Cy": "Shapesanity Colorful Full Mixed", + "Singles Cu Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Su": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Su": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rb Rc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Rb Rg": "Shapesanity Stitched Painted", + "Singles Cu Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rb Rp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Rb Rr": "Shapesanity Stitched Painted", + "Singles Cu Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Rb Ru": "Shapesanity Stitched Painted", + "Singles Cu Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rb Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rb Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rb Sb": "Shapesanity Stitched Painted", + "Singles Cu Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rb Sg": "Shapesanity Stitched Painted", + "Singles Cu Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rb Sr": "Shapesanity Stitched Painted", + "Singles Cu Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rb Su": "Shapesanity Stitched Painted", + "Singles Cu Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rb Wb": "Shapesanity Stitched Painted", + "Singles Cu Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rb Wg": "Shapesanity Stitched Painted", + "Singles Cu Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rb Wr": "Shapesanity Stitched Painted", + "Singles Cu Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rb Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Rg Rr": "Shapesanity Stitched Painted", + "Singles Cu Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Rg Ru": "Shapesanity Stitched Painted", + "Singles Cu Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rg Sb": "Shapesanity Stitched Painted", + "Singles Cu Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rg Sg": "Shapesanity Stitched Painted", + "Singles Cu Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rg Sr": "Shapesanity Stitched Painted", + "Singles Cu Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rg Su": "Shapesanity Stitched Painted", + "Singles Cu Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rg Wb": "Shapesanity Stitched Painted", + "Singles Cu Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rg Wg": "Shapesanity Stitched Painted", + "Singles Cu Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rg Wr": "Shapesanity Stitched Painted", + "Singles Cu Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rg Wu": "Shapesanity Stitched Painted", + "Singles Cu Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Su": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Rr Ru": "Shapesanity Stitched Painted", + "Singles Cu Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rr Sb": "Shapesanity Stitched Painted", + "Singles Cu Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rr Sg": "Shapesanity Stitched Painted", + "Singles Cu Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rr Sr": "Shapesanity Stitched Painted", + "Singles Cu Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rr Su": "Shapesanity Stitched Painted", + "Singles Cu Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rr Wb": "Shapesanity Stitched Painted", + "Singles Cu Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rr Wg": "Shapesanity Stitched Painted", + "Singles Cu Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rr Wr": "Shapesanity Stitched Painted", + "Singles Cu Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Rr Wu": "Shapesanity Stitched Painted", + "Singles Cu Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Ru Sb": "Shapesanity Stitched Painted", + "Singles Cu Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Ru Sg": "Shapesanity Stitched Painted", + "Singles Cu Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Ru Su": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Cu Ru Su": "Shapesanity Stitched Uncolored", + "Singles Cu Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Ru Wb": "Shapesanity Stitched Painted", + "Singles Cu Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Ru Wg": "Shapesanity Stitched Painted", + "Singles Cu Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Ru Wu": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Cu Ru Wu": "Shapesanity Stitched Uncolored", + "Singles Cu Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Su": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Su": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Sb Sg": "Shapesanity Stitched Painted", + "Singles Cu Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Sb Sr": "Shapesanity Stitched Painted", + "Singles Cu Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Sb Su": "Shapesanity Stitched Painted", + "Singles Cu Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sb Wb": "Shapesanity Stitched Painted", + "Singles Cu Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sb Wg": "Shapesanity Stitched Painted", + "Singles Cu Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sb Wr": "Shapesanity Stitched Painted", + "Singles Cu Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sb Wu": "Shapesanity Stitched Painted", + "Singles Cu Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sc Su": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Sg Sr": "Shapesanity Stitched Painted", + "Singles Cu Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Sg Su": "Shapesanity Stitched Painted", + "Singles Cu Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sg Wb": "Shapesanity Stitched Painted", + "Singles Cu Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sg Wg": "Shapesanity Stitched Painted", + "Singles Cu Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sg Wr": "Shapesanity Stitched Painted", + "Singles Cu Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sg Wu": "Shapesanity Stitched Painted", + "Singles Cu Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Sr Su": "Shapesanity Stitched Painted", + "Singles Cu Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sr Wb": "Shapesanity Stitched Painted", + "Singles Cu Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sr Wg": "Shapesanity Stitched Painted", + "Singles Cu Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sr Wr": "Shapesanity Stitched Painted", + "Singles Cu Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Sr Wu": "Shapesanity Stitched Painted", + "Singles Cu Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Su Wb": "Shapesanity Stitched Painted", + "Singles Cu Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Su Wg": "Shapesanity Stitched Painted", + "Singles Cu Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Cu Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Su Wu": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Cu Su Wu": "Shapesanity Stitched Uncolored", + "Singles Cu Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cu Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Wb Wg": "Shapesanity Stitched Painted", + "Singles Cu Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Wb Wr": "Shapesanity Stitched Painted", + "Singles Cu Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Wb Wu": "Shapesanity Stitched Painted", + "Singles Cu Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Wg Wr": "Shapesanity Stitched Painted", + "Singles Cu Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Wg Wu": "Shapesanity Stitched Painted", + "Singles Cu Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Cu Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Cu Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cu Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cu Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Cc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cb Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cb Cg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cb Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cb Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cb Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cb Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cb Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cb Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cb Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cb Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cb Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Cg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cc Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cc Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cc Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cc Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cc Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cc Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cc Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cc Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cc Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cg Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cg Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cg Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cg Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cg Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cg Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cg Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cp Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cp Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cp Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cp Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cp Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cr Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cr Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cr Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Cy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cw Cu Cy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cw Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Su": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rb Rc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rb Rg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rb Rp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rb Rr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rb Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rb Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rb Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Su": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Su": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sb Su": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sc Su": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cw Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Cc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cb Cc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cb Cg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cb Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cb Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cb Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cb Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cb Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cb Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cb Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cb Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cb Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Cg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cc Cg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cc Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cc Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cc Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cc Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cc Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cc Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cc Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cc Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Cp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cg Cp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cg Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cg Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cg Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cg Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cg Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cg Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Cr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cp Cr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cp Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cp Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cp Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cp Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Cu": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cr Cu": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cr Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cr Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Cw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Cy Cu Cw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Cy Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rb Rc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rb Rg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rb Rp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rb Rr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rb Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rb Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rb Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Su": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Su": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Su": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Su": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sb Su": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sc Su": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Cy Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Cy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Cy Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Rg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rc Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rc Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rc Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rc Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rc Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rc Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rc Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rc Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rc Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rc Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rc Ry": "Shapesanity Colorful Full Mixed", + "Singles Rb Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Su": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rg Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rg Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rg Rr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Rb Rg Rr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Rb Rg Ru": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Rb Rg Ru": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Rb Rg Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rg Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rg Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rg Ry": "Shapesanity Colorful Full Mixed", + "Singles Rb Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rg Sb": "Shapesanity Stitched Painted", + "Singles Rb Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rg Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rg Sg": "Shapesanity Stitched Painted", + "Singles Rb Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rg Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rg Sr": "Shapesanity Stitched Painted", + "Singles Rb Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rg Su": "Shapesanity Stitched Painted", + "Singles Rb Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rg Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rg Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rg Wb": "Shapesanity Stitched Painted", + "Singles Rb Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rg Wg": "Shapesanity Stitched Painted", + "Singles Rb Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rg Wr": "Shapesanity Stitched Painted", + "Singles Rb Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rg Wu": "Shapesanity Stitched Painted", + "Singles Rb Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rp Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rp Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rp Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rp Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rp Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rp Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rp Ry": "Shapesanity Colorful Full Mixed", + "Singles Rb Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Su": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rr Ru": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Rb Rr Ru": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Rb Rr Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rr Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Rr Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rr Ry": "Shapesanity Colorful Full Mixed", + "Singles Rb Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rr Sb": "Shapesanity Stitched Painted", + "Singles Rb Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rr Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rr Sg": "Shapesanity Stitched Painted", + "Singles Rb Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rr Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rr Sr": "Shapesanity Stitched Painted", + "Singles Rb Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rr Su": "Shapesanity Stitched Painted", + "Singles Rb Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rr Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rr Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rr Wb": "Shapesanity Stitched Painted", + "Singles Rb Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rr Wg": "Shapesanity Stitched Painted", + "Singles Rb Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rr Wr": "Shapesanity Stitched Painted", + "Singles Rb Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Rr Wu": "Shapesanity Stitched Painted", + "Singles Rb Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ru Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Ru Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rb Ru Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Ru Ry": "Shapesanity Colorful Full Mixed", + "Singles Rb Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Ru Sb": "Shapesanity Stitched Painted", + "Singles Rb Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Ru Sg": "Shapesanity Stitched Painted", + "Singles Rb Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Ru Sr": "Shapesanity Stitched Painted", + "Singles Rb Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Ru Su": "Shapesanity Stitched Painted", + "Singles Rb Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Ru Wb": "Shapesanity Stitched Painted", + "Singles Rb Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Ru Wg": "Shapesanity Stitched Painted", + "Singles Rb Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Ru Wr": "Shapesanity Stitched Painted", + "Singles Rb Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Ru Wu": "Shapesanity Stitched Painted", + "Singles Rb Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rb Rw Ry": "Shapesanity Colorful Full Mixed", + "Singles Rb Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Su": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rb Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Su": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rb Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sb Sc": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Sb Sg": "Shapesanity Stitched Painted", + "Singles Rb Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sb Sp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Sb Sr": "Shapesanity Stitched Painted", + "Singles Rb Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Sb Su": "Shapesanity Stitched Painted", + "Singles Rb Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sb Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sb Wb": "Shapesanity Stitched Painted", + "Singles Rb Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sb Wg": "Shapesanity Stitched Painted", + "Singles Rb Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sb Wr": "Shapesanity Stitched Painted", + "Singles Rb Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sb Wu": "Shapesanity Stitched Painted", + "Singles Rb Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sc Su": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Sg Sr": "Shapesanity Stitched Painted", + "Singles Rb Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Sg Su": "Shapesanity Stitched Painted", + "Singles Rb Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sg Wb": "Shapesanity Stitched Painted", + "Singles Rb Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sg Wg": "Shapesanity Stitched Painted", + "Singles Rb Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sg Wr": "Shapesanity Stitched Painted", + "Singles Rb Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sg Wu": "Shapesanity Stitched Painted", + "Singles Rb Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sp Su": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Sr Su": "Shapesanity Stitched Painted", + "Singles Rb Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sr Wb": "Shapesanity Stitched Painted", + "Singles Rb Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sr Wg": "Shapesanity Stitched Painted", + "Singles Rb Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sr Wr": "Shapesanity Stitched Painted", + "Singles Rb Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Sr Wu": "Shapesanity Stitched Painted", + "Singles Rb Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Su Sw": "Shapesanity Stitched Mixed", + "Singles Rb Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Su Sy": "Shapesanity Stitched Mixed", + "Singles Rb Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Su Wb": "Shapesanity Stitched Painted", + "Singles Rb Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Su Wg": "Shapesanity Stitched Painted", + "Singles Rb Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Su Wr": "Shapesanity Stitched Painted", + "Singles Rb Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rb Su Wu": "Shapesanity Stitched Painted", + "Singles Rb Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Wb Wg": "Shapesanity Stitched Painted", + "Singles Rb Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Wb Wr": "Shapesanity Stitched Painted", + "Singles Rb Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Wb Wu": "Shapesanity Stitched Painted", + "Singles Rb Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Wg Wr": "Shapesanity Stitched Painted", + "Singles Rb Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Wg Wu": "Shapesanity Stitched Painted", + "Singles Rb Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rb Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rb Wr Wu": "Shapesanity Stitched Painted", + "Singles Rb Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rb Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rb Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Rg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rb Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rb Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rb Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rb Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rb Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rb Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rb Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rb Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rb Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rb Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rb Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rg Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rg Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rg Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rg Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rg Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rg Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rg Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rg Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rg Ry": "Shapesanity Colorful Full Mixed", + "Singles Rc Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Su": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rp Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rp Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rp Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rp Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rp Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rp Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rp Ry": "Shapesanity Colorful Full Mixed", + "Singles Rc Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Su": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rr Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rr Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rr Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Rr Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rr Ry": "Shapesanity Colorful Full Mixed", + "Singles Rc Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Su": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Ru Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rc Ru Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Ru Ry": "Shapesanity Colorful Full Mixed", + "Singles Rc Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Su": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rc Rw Ry": "Shapesanity Colorful Full Mixed", + "Singles Rc Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Su": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rc Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Su": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rc Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sb Sc": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sb Sg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sb Sp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sb Sr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sb Su": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sb Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sb Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sc Su": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sg Su": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sp Su": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sr Su": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Su Sw": "Shapesanity Stitched Mixed", + "Singles Rc Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Su Sy": "Shapesanity Stitched Mixed", + "Singles Rc Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rc Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rc Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rb Rc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rb Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rb Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rb Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rb Rr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Rg Rb Rr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Rg Rb Ru": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Rg Rb Ru": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Rg Rb Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rb Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rb Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rb Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rc Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rc Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rc Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rc Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rc Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rc Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rc Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rc Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rc Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rp Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rp Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rp Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rp Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rp Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rp Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rp Ry": "Shapesanity Colorful Full Mixed", + "Singles Rg Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rr Ru": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Rg Rr Ru": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Rg Rr Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rr Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Rr Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rr Ry": "Shapesanity Colorful Full Mixed", + "Singles Rg Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rr Sb": "Shapesanity Stitched Painted", + "Singles Rg Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rr Sg": "Shapesanity Stitched Painted", + "Singles Rg Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rr Sr": "Shapesanity Stitched Painted", + "Singles Rg Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rr Su": "Shapesanity Stitched Painted", + "Singles Rg Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rr Wb": "Shapesanity Stitched Painted", + "Singles Rg Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rr Wg": "Shapesanity Stitched Painted", + "Singles Rg Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rr Wr": "Shapesanity Stitched Painted", + "Singles Rg Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Rr Wu": "Shapesanity Stitched Painted", + "Singles Rg Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ru Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Ru Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rg Ru Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Ru Ry": "Shapesanity Colorful Full Mixed", + "Singles Rg Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Ru Sb": "Shapesanity Stitched Painted", + "Singles Rg Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Ru Sg": "Shapesanity Stitched Painted", + "Singles Rg Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Ru Sr": "Shapesanity Stitched Painted", + "Singles Rg Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Ru Su": "Shapesanity Stitched Painted", + "Singles Rg Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Ru Wb": "Shapesanity Stitched Painted", + "Singles Rg Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Ru Wg": "Shapesanity Stitched Painted", + "Singles Rg Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Ru Wr": "Shapesanity Stitched Painted", + "Singles Rg Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Ru Wu": "Shapesanity Stitched Painted", + "Singles Rg Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rg Rw Ry": "Shapesanity Colorful Full Mixed", + "Singles Rg Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rg Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rg Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sb Sc": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Sb Sg": "Shapesanity Stitched Painted", + "Singles Rg Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sb Sp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Sb Sr": "Shapesanity Stitched Painted", + "Singles Rg Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Sb Su": "Shapesanity Stitched Painted", + "Singles Rg Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sb Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sb Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sb Wb": "Shapesanity Stitched Painted", + "Singles Rg Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sb Wg": "Shapesanity Stitched Painted", + "Singles Rg Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sb Wr": "Shapesanity Stitched Painted", + "Singles Rg Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sb Wu": "Shapesanity Stitched Painted", + "Singles Rg Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sc Su": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Sg Sr": "Shapesanity Stitched Painted", + "Singles Rg Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Sg Su": "Shapesanity Stitched Painted", + "Singles Rg Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sg Wb": "Shapesanity Stitched Painted", + "Singles Rg Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sg Wg": "Shapesanity Stitched Painted", + "Singles Rg Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sg Wr": "Shapesanity Stitched Painted", + "Singles Rg Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sg Wu": "Shapesanity Stitched Painted", + "Singles Rg Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sp Su": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Sr Su": "Shapesanity Stitched Painted", + "Singles Rg Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sr Wb": "Shapesanity Stitched Painted", + "Singles Rg Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sr Wg": "Shapesanity Stitched Painted", + "Singles Rg Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sr Wr": "Shapesanity Stitched Painted", + "Singles Rg Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Sr Wu": "Shapesanity Stitched Painted", + "Singles Rg Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Su Sw": "Shapesanity Stitched Mixed", + "Singles Rg Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Su Sy": "Shapesanity Stitched Mixed", + "Singles Rg Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Su Wb": "Shapesanity Stitched Painted", + "Singles Rg Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Su Wg": "Shapesanity Stitched Painted", + "Singles Rg Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Su Wr": "Shapesanity Stitched Painted", + "Singles Rg Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rg Su Wu": "Shapesanity Stitched Painted", + "Singles Rg Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Wb Wg": "Shapesanity Stitched Painted", + "Singles Rg Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Wb Wr": "Shapesanity Stitched Painted", + "Singles Rg Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Wb Wu": "Shapesanity Stitched Painted", + "Singles Rg Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Wg Wr": "Shapesanity Stitched Painted", + "Singles Rg Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Wg Wu": "Shapesanity Stitched Painted", + "Singles Rg Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rg Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rg Wr Wu": "Shapesanity Stitched Painted", + "Singles Rg Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rg Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rg Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Rc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rb Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rb Rg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rb Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rb Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rb Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rb Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rb Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rb Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rb Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rb Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rb Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Rg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rc Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rc Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rc Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rc Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rc Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rc Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rc Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rc Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rc Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rg Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rg Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rg Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rg Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rg Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rg Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rg Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rr Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rr Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rr Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Rr Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rr Ry": "Shapesanity Colorful Full Mixed", + "Singles Rp Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Ru Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rp Ru Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Ru Ry": "Shapesanity Colorful Full Mixed", + "Singles Rp Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rp Rw Ry": "Shapesanity Colorful Full Mixed", + "Singles Rp Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rp Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rp Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sb Sc": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sb Sg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sb Sp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sb Sr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sb Su": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sb Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sb Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sc Su": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sg Su": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sp Su": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sr Su": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Su Sw": "Shapesanity Stitched Mixed", + "Singles Rp Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Su Sy": "Shapesanity Stitched Mixed", + "Singles Rp Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Rp Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Rp Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Rp Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Rp Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Rp Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Rp Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Rp Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rp Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rb Rc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rb Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rb Rg": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Rr Rb Rg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Rr Rb Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rb Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rb Ru": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Rr Rb Ru": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Rr Rb Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rb Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rb Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rb Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Rg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rc Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rc Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rc Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rc Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rc Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rc Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rc Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rc Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rc Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rg Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rg Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rg Ru": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Rr Rg Ru": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Rr Rg Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rg Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rg Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rg Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rp Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rp Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rp Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rp Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rp Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ru Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Ru Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rr Ru Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Ru Ry": "Shapesanity Colorful Full Mixed", + "Singles Rr Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Ru Sb": "Shapesanity Stitched Painted", + "Singles Rr Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Ru Sg": "Shapesanity Stitched Painted", + "Singles Rr Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Ru Sr": "Shapesanity Stitched Painted", + "Singles Rr Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Ru Su": "Shapesanity Stitched Painted", + "Singles Rr Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Ru Wb": "Shapesanity Stitched Painted", + "Singles Rr Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Ru Wg": "Shapesanity Stitched Painted", + "Singles Rr Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Ru Wr": "Shapesanity Stitched Painted", + "Singles Rr Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Ru Wu": "Shapesanity Stitched Painted", + "Singles Rr Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rr Rw Ry": "Shapesanity Colorful Full Mixed", + "Singles Rr Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rr Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rr Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sb Sc": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Sb Sg": "Shapesanity Stitched Painted", + "Singles Rr Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sb Sp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Sb Sr": "Shapesanity Stitched Painted", + "Singles Rr Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Sb Su": "Shapesanity Stitched Painted", + "Singles Rr Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sb Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sb Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sb Wb": "Shapesanity Stitched Painted", + "Singles Rr Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sb Wg": "Shapesanity Stitched Painted", + "Singles Rr Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sb Wr": "Shapesanity Stitched Painted", + "Singles Rr Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sb Wu": "Shapesanity Stitched Painted", + "Singles Rr Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sc Su": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Sg Sr": "Shapesanity Stitched Painted", + "Singles Rr Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Sg Su": "Shapesanity Stitched Painted", + "Singles Rr Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sg Wb": "Shapesanity Stitched Painted", + "Singles Rr Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sg Wg": "Shapesanity Stitched Painted", + "Singles Rr Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sg Wr": "Shapesanity Stitched Painted", + "Singles Rr Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sg Wu": "Shapesanity Stitched Painted", + "Singles Rr Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sp Su": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Sr Su": "Shapesanity Stitched Painted", + "Singles Rr Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sr Wb": "Shapesanity Stitched Painted", + "Singles Rr Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sr Wg": "Shapesanity Stitched Painted", + "Singles Rr Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sr Wr": "Shapesanity Stitched Painted", + "Singles Rr Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Sr Wu": "Shapesanity Stitched Painted", + "Singles Rr Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Su Sw": "Shapesanity Stitched Mixed", + "Singles Rr Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Su Sy": "Shapesanity Stitched Mixed", + "Singles Rr Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Su Wb": "Shapesanity Stitched Painted", + "Singles Rr Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rr Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Su Wg": "Shapesanity Stitched Painted", + "Singles Rr Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rr Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Su Wr": "Shapesanity Stitched Painted", + "Singles Rr Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Rr Su Wu": "Shapesanity Stitched Painted", + "Singles Rr Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rr Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Wb Wg": "Shapesanity Stitched Painted", + "Singles Rr Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Wb Wr": "Shapesanity Stitched Painted", + "Singles Rr Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Wb Wu": "Shapesanity Stitched Painted", + "Singles Rr Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Wg Wr": "Shapesanity Stitched Painted", + "Singles Rr Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Wg Wu": "Shapesanity Stitched Painted", + "Singles Rr Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Rr Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Rr Wr Wu": "Shapesanity Stitched Painted", + "Singles Rr Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rr Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cu Su": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Ru Cu Su": "Shapesanity Stitched Uncolored", + "Adjacent 2-1-1 Ru Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Cu Wu": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Ru Cu Wu": "Shapesanity Stitched Uncolored", + "Adjacent 2-1-1 Ru Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rb Rc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rb Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rb Rg": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Ru Rb Rg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Ru Rb Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rb Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rb Rr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Ru Rb Rr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Ru Rb Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rb Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rb Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rb Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Rg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rc Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rc Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rc Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rc Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rc Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rc Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rc Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rc Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rc Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rg Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rg Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rg Rr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Ru Rg Rr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Ru Rg Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rg Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rg Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rg Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rp Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rp Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rp Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rp Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rp Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rr Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rr Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rr Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rr Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ru Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ru Rw Ry": "Shapesanity Colorful Full Mixed", + "Singles Ru Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Ru Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Ru Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Ru Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Ru Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Ru Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Ru Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Ru Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Ru Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Ru Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Ru Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sb Sc": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Sb Sg": "Shapesanity Stitched Painted", + "Singles Ru Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sb Sp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Sb Sr": "Shapesanity Stitched Painted", + "Singles Ru Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Sb Su": "Shapesanity Stitched Painted", + "Singles Ru Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sb Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sb Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sb Wb": "Shapesanity Stitched Painted", + "Singles Ru Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sb Wg": "Shapesanity Stitched Painted", + "Singles Ru Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sb Wr": "Shapesanity Stitched Painted", + "Singles Ru Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sb Wu": "Shapesanity Stitched Painted", + "Singles Ru Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sc Sg": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sc Sp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sc Sr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sc Su": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sc Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sc Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sg Sp": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Sg Sr": "Shapesanity Stitched Painted", + "Singles Ru Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Sg Su": "Shapesanity Stitched Painted", + "Singles Ru Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sg Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sg Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sg Wb": "Shapesanity Stitched Painted", + "Singles Ru Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sg Wg": "Shapesanity Stitched Painted", + "Singles Ru Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sg Wr": "Shapesanity Stitched Painted", + "Singles Ru Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sg Wu": "Shapesanity Stitched Painted", + "Singles Ru Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sp Sr": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sp Su": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sp Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sp Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Sr Su": "Shapesanity Stitched Painted", + "Singles Ru Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sr Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sr Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sr Wb": "Shapesanity Stitched Painted", + "Singles Ru Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sr Wg": "Shapesanity Stitched Painted", + "Singles Ru Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sr Wr": "Shapesanity Stitched Painted", + "Singles Ru Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Sr Wu": "Shapesanity Stitched Painted", + "Singles Ru Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Su Sw": "Shapesanity Stitched Mixed", + "Singles Ru Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Su Sy": "Shapesanity Stitched Mixed", + "Singles Ru Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Su Wb": "Shapesanity Stitched Painted", + "Singles Ru Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Ru Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Su Wg": "Shapesanity Stitched Painted", + "Singles Ru Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Ru Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Ru Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Su Wu": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Ru Su Wu": "Shapesanity Stitched Uncolored", + "Singles Ru Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Ru Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Wb Wg": "Shapesanity Stitched Painted", + "Singles Ru Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Wb Wr": "Shapesanity Stitched Painted", + "Singles Ru Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Wb Wu": "Shapesanity Stitched Painted", + "Singles Ru Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Wg Wr": "Shapesanity Stitched Painted", + "Singles Ru Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Wg Wu": "Shapesanity Stitched Painted", + "Singles Ru Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Ru Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Ru Wr Wu": "Shapesanity Stitched Painted", + "Singles Ru Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ru Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ru Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Rc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rb Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rb Rg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rb Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rb Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rb Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rb Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rb Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rb Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rb Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rb Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rb Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Rg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rc Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rc Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rc Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rc Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rc Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rc Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rc Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rc Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rc Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rg Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rg Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rg Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rg Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rg Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rg Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rg Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rp Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rp Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rp Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rp Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rp Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rr Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rr Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Rr Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Ry": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Rw Ru Ry": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Rw Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rw Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rw Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rw Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rw Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rw Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rw Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rw Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rw Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sb Sc": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sb Sg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sb Sp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sb Sr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sb Su": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sb Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sb Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sc Su": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sg Su": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sp Su": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sr Su": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Su Sw": "Shapesanity Stitched Mixed", + "Singles Rw Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Su Sy": "Shapesanity Stitched Mixed", + "Singles Rw Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Rw Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Rw Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Rw Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Rw Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Rw Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Rw Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Rw Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Rw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Rw Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Rc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rb Rc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rb Rg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rb Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rb Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rb Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rb Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rb Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rb Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rb Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rb Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rb Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Rg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rc Rg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rc Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rc Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rc Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rc Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rc Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rc Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rc Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rc Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Rp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rg Rp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rg Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rg Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rg Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rg Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rg Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rg Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Rr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rp Rr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rp Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rp Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rp Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rp Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Ru": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rr Ru": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rr Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Rr Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Rw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Ry Ru Rw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Ry Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Rw Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sb Sc": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sb Sg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sb Sp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sb Sr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sb Su": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sb Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sb Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sc Sg": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sc Sp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sc Sr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sc Su": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sc Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sc Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sg Sp": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sg Sr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sg Su": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sg Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sg Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sp Sr": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sp Su": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sp Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sp Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sr Su": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sr Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sr Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Su Sw": "Shapesanity Stitched Mixed", + "Singles Ry Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Su Sy": "Shapesanity Stitched Mixed", + "Singles Ry Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Ry Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Ry Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Ry Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Ry Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Ry Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Ry Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Ry Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ry Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ry Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sc Sg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sc Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sc Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sc Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sc Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sc Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sc Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sc Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sc Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sc Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sc Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sc Sy": "Shapesanity Colorful Full Mixed", + "Singles Sb Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sg Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sg Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sg Sr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Sb Sg Sr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Sb Sg Su": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Sb Sg Su": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Sb Sg Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sg Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sg Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sg Sy": "Shapesanity Colorful Full Mixed", + "Singles Sb Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Sg Wb": "Shapesanity Stitched Painted", + "Singles Sb Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Sg Wg": "Shapesanity Stitched Painted", + "Singles Sb Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Sg Wr": "Shapesanity Stitched Painted", + "Singles Sb Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Sg Wu": "Shapesanity Stitched Painted", + "Singles Sb Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sp Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sp Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sp Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sp Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sp Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sp Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sp Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sp Sy": "Shapesanity Colorful Full Mixed", + "Singles Sb Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sr Su": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Sb Sr Su": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Sb Sr Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sr Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Sr Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sr Sy": "Shapesanity Colorful Full Mixed", + "Singles Sb Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Sr Wb": "Shapesanity Stitched Painted", + "Singles Sb Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Sr Wg": "Shapesanity Stitched Painted", + "Singles Sb Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Sr Wr": "Shapesanity Stitched Painted", + "Singles Sb Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Sr Wu": "Shapesanity Stitched Painted", + "Singles Sb Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Su Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Su Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sb Su Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Su Sy": "Shapesanity Colorful Full Mixed", + "Singles Sb Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Su Wb": "Shapesanity Stitched Painted", + "Singles Sb Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Sb Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Su Wg": "Shapesanity Stitched Painted", + "Singles Sb Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Sb Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Su Wr": "Shapesanity Stitched Painted", + "Singles Sb Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sb Su Wu": "Shapesanity Stitched Painted", + "Singles Sb Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Sb Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sw Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sb Sw Sy": "Shapesanity Colorful Full Mixed", + "Singles Sb Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Wb Wg": "Shapesanity Stitched Painted", + "Singles Sb Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Wb Wr": "Shapesanity Stitched Painted", + "Singles Sb Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Wb Wu": "Shapesanity Stitched Painted", + "Singles Sb Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sb Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Wg Wr": "Shapesanity Stitched Painted", + "Singles Sb Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Wg Wu": "Shapesanity Stitched Painted", + "Singles Sb Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sb Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sb Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sb Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sb Wr Wu": "Shapesanity Stitched Painted", + "Singles Sb Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sb Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sb Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sb Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sb Sg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sb Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sb Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sb Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sb Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sb Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sb Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sb Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sb Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sb Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sb Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sb Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sg Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sg Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sg Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sg Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sg Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sg Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sg Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sg Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sg Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sg Sy": "Shapesanity Colorful Full Mixed", + "Singles Sc Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sp Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sp Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sp Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sp Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sp Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sp Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sp Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sp Sy": "Shapesanity Colorful Full Mixed", + "Singles Sc Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sr Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sr Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sr Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sr Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Sr Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sr Sy": "Shapesanity Colorful Full Mixed", + "Singles Sc Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Su Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Su Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sc Su Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Su Sy": "Shapesanity Colorful Full Mixed", + "Singles Sc Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Sc Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Sc Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Sc Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Sc Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Sc Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Sc Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Sc Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sw Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sc Sw Sy": "Shapesanity Colorful Full Mixed", + "Singles Sc Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sc Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sc Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sc Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sc Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sb Sc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sb Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sb Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sb Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sb Sr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Sg Sb Sr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Sg Sb Su": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Sg Sb Su": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Sg Sb Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sb Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sb Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sb Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sc Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sc Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sc Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sc Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sc Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sc Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sc Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sc Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sc Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sc Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sp Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sp Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sp Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sp Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sp Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sp Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sp Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sp Sy": "Shapesanity Colorful Full Mixed", + "Singles Sg Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Sg Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Sg Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Sg Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Sg Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sr Su": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Sg Sr Su": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Sg Sr Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sr Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Sr Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sr Sy": "Shapesanity Colorful Full Mixed", + "Singles Sg Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Sr Wb": "Shapesanity Stitched Painted", + "Singles Sg Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Sr Wg": "Shapesanity Stitched Painted", + "Singles Sg Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Sr Wr": "Shapesanity Stitched Painted", + "Singles Sg Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Sr Wu": "Shapesanity Stitched Painted", + "Singles Sg Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Su Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Su Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sg Su Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Su Sy": "Shapesanity Colorful Full Mixed", + "Singles Sg Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Su Wb": "Shapesanity Stitched Painted", + "Singles Sg Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Sg Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Su Wg": "Shapesanity Stitched Painted", + "Singles Sg Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Sg Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Su Wr": "Shapesanity Stitched Painted", + "Singles Sg Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sg Su Wu": "Shapesanity Stitched Painted", + "Singles Sg Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Sg Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sw Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sg Sw Sy": "Shapesanity Colorful Full Mixed", + "Singles Sg Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sg Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sg Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sg Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sg Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sg Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sg Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sg Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sg Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sg Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Wb Wg": "Shapesanity Stitched Painted", + "Singles Sg Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Wb Wr": "Shapesanity Stitched Painted", + "Singles Sg Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Wb Wu": "Shapesanity Stitched Painted", + "Singles Sg Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sg Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Wg Wr": "Shapesanity Stitched Painted", + "Singles Sg Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Wg Wu": "Shapesanity Stitched Painted", + "Singles Sg Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sg Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sg Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sg Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sg Wr Wu": "Shapesanity Stitched Painted", + "Singles Sg Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sg Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sg Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sg Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sb Sc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sb Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sb Sg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sb Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sb Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sb Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sb Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sb Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sb Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sb Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sb Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sb Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sc Sg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sc Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sc Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sc Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sc Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sc Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sc Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sc Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sc Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sc Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sg Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sg Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sg Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sg Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sg Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sg Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sg Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sg Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sr Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sr Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sr Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sr Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Sr Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sr Sy": "Shapesanity Colorful Full Mixed", + "Singles Sp Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Sp Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Sp Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Sp Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Sp Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Sp Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Sp Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Sp Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Su Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Su Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sp Su Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Su Sy": "Shapesanity Colorful Full Mixed", + "Singles Sp Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Sp Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Sp Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Sp Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Sp Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Sp Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Sp Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Sp Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sw Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sp Sw Sy": "Shapesanity Colorful Full Mixed", + "Singles Sp Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sp Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sp Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sp Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sp Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sp Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sp Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sp Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sp Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sp Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sp Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sp Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sp Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sp Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sp Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sp Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sp Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sp Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sp Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sb Sc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sb Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sb Sg": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Sr Sb Sg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Sr Sb Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sb Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sb Su": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Sr Sb Su": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Sr Sb Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sb Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sb Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sb Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sc Sg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sc Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sc Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sc Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sc Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sc Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sc Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sc Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sc Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sc Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sg Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sg Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sg Su": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Sr Sg Su": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Sr Sg Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sg Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sg Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sg Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sp Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sp Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sp Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sp Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sp Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sp Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Su Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Su Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sr Su Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Su Sy": "Shapesanity Colorful Full Mixed", + "Singles Sr Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Sr Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Sr Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Sr Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Sr Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Sr Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Sr Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Sr Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sw Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sr Sw Sy": "Shapesanity Colorful Full Mixed", + "Singles Sr Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sr Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sr Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sr Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sr Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sr Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sr Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sr Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sr Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sr Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sr Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sr Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sr Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sr Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sr Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sr Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Wb Wg": "Shapesanity Stitched Painted", + "Singles Sr Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Wb Wr": "Shapesanity Stitched Painted", + "Singles Sr Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Wb Wu": "Shapesanity Stitched Painted", + "Singles Sr Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sr Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Wg Wr": "Shapesanity Stitched Painted", + "Singles Sr Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Wg Wu": "Shapesanity Stitched Painted", + "Singles Sr Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sr Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sr Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Sr Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Sr Wr Wu": "Shapesanity Stitched Painted", + "Singles Sr Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sr Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sr Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cu Ru": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Su Cu Ru": "Shapesanity Stitched Uncolored", + "Adjacent 2-1-1 Su Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Cu Wu": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Su Cu Wu": "Shapesanity Stitched Uncolored", + "Adjacent 2-1-1 Su Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Ru Wu": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Su Ru Wu": "Shapesanity Stitched Uncolored", + "Adjacent 2-1-1 Su Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sb Sc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sb Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sb Sg": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Su Sb Sg": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Su Sb Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sb Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sb Sr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Su Sb Sr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Su Sb Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sb Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sb Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sb Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sc Sg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sc Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sc Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sc Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sc Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sc Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sc Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sc Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sc Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sc Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sg Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sg Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sg Sr": "Shapesanity Colorful Full Painted", + "Cornered 2-1-1 Su Sg Sr": "Shapesanity Colorful Full Painted", + "Adjacent 2-1-1 Su Sg Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sg Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sg Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sg Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sp Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sp Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sp Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sp Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sp Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sp Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sr Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sr Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sr Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sr Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Su Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Su Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sw Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Su Sw Sy": "Shapesanity Colorful Full Mixed", + "Singles Su Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Su Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Su Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Su Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Su Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Su Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Su Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Su Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Su Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Su Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Su Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Su Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Su Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Su Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Su Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Su Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Su Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Su Wb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Wb Wg": "Shapesanity Stitched Painted", + "Singles Su Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Su Wb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Wb Wr": "Shapesanity Stitched Painted", + "Singles Su Wb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Wb Wu": "Shapesanity Stitched Painted", + "Singles Su Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Su Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Su Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Su Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Su Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Su Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Su Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Su Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Su Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Su Wg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Wg Wr": "Shapesanity Stitched Painted", + "Singles Su Wg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Wg Wu": "Shapesanity Stitched Painted", + "Singles Su Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Su Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Su Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Su Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Su Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Su Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Su Wr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Su Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Su Wr Wu": "Shapesanity Stitched Painted", + "Singles Su Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Su Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Su Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Su Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Su Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Su Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Su Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sb Sc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sb Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sb Sg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sb Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sb Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sb Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sb Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sb Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sb Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sb Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sb Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sb Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sc Sg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sc Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sc Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sc Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sc Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sc Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sc Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sc Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sc Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sc Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sg Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sg Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sg Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sg Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sg Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sg Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sg Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sg Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sp Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sp Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sp Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sp Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sp Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sp Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sr Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sr Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sr Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Sr Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Su Sy": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sw Su Sy": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sw Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Su Wy": "Shapesanity Stitched Mixed", + "Singles Sw Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sw Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sw Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sw Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sw Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sw Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sw Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sw Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sw Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sw Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sw Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sb Sc": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sb Sc": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sb Sg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sb Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sb Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sb Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sb Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sb Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sb Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sb Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sb Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sb Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sc Sg": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sc Sg": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sc Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sc Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sc Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sc Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sc Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sc Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sc Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sc Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sg Sp": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sg Sp": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sg Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sg Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sg Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sg Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sg Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sg Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sp Sr": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sp Sr": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sp Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sp Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sp Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sp Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sr Su": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sr Su": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sr Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Sr Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Su Sw": "Shapesanity Colorful Full Mixed", + "Cornered 2-1-1 Sy Su Sw": "Shapesanity Colorful Full Mixed", + "Adjacent 2-1-1 Sy Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Sy Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sy Wp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sy Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Sy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Sy Ww Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wb Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wb Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wb Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wb Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wb Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wb Wc Wg": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wc Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wc Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wc Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wc Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wc Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wc Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wc Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wc Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wc Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wc Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wc Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wg Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wg Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wg Wr": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wb Wg Wr": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wb Wg Wu": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wb Wg Wu": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wb Wg Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wg Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wg Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wg Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wp Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wp Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wp Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wp Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wp Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wp Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wp Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wp Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wr Wu": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wb Wr Wu": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wb Wr Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wr Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wr Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wr Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wu Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wu Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Wu Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Wu Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wb Ww Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wb Ww Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wc Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wc Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wc Wb Wg": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wb Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wb Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wb Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wb Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wb Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wb Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wb Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wb Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wb Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wb Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wb Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wg Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wg Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wg Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wg Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wg Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wg Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wg Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wg Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wg Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wg Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wp Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wp Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wp Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wp Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wp Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wp Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wp Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wp Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wr Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wr Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wr Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wr Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wr Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wr Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wu Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wu Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Wu Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Wu Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wc Ww Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wc Ww Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wg Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wg Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wg Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wg Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wg Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wg Wb Wc": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wb Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wb Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wb Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wb Wr": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wg Wb Wr": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wg Wb Wu": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wg Wb Wu": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wg Wb Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wb Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wb Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wb Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wc Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wc Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wc Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wc Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wc Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wc Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wc Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wc Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wc Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wc Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wp Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wp Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wp Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wp Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wp Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wp Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wp Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wp Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wr Wu": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wg Wr Wu": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wg Wr Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wr Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wr Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wr Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wu Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wu Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Wu Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Wu Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wg Ww Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wg Ww Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wp Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wp Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wp Wb Wc": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wb Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wb Wg": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wb Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wb Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wb Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wb Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wb Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wb Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wb Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wb Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wb Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wc Wg": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wc Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wc Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wc Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wc Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wc Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wc Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wc Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wc Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wc Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wg Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wg Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wg Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wg Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wg Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wg Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wg Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wg Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wr Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wr Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wr Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wr Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wr Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wr Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wu Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wu Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Wu Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Wu Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wp Ww Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wp Ww Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Cu Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Rr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Ru Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Ru Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ru Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Ru Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sb Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Sb Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sg Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Sg Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wr Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sr Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Sr Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Su Wu": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wr Su Wu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wr Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wr Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wr Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wr Wb Wc": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wb Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wb Wg": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wr Wb Wg": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wr Wb Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wb Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wb Wu": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wr Wb Wu": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wr Wb Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wb Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wb Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wb Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wc Wg": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wc Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wc Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wc Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wc Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wc Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wc Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wc Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wc Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wc Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wg Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wg Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wg Wu": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wr Wg Wu": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wr Wg Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wg Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wg Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wg Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wp Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wp Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wp Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wp Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wp Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wp Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wu Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wu Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Wu Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Wu Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wr Ww Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wr Ww Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Cg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Cb Cg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Cb Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Cb Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Cr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Cg Cr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Cg Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Cu": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Cr Cu": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Ru": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Rb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cu Rb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Rg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cu Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Rr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cu Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cu Ru": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Wu Cu Ru": "Shapesanity Stitched Uncolored", + "Adjacent 2-1-1 Wu Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cu Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cu Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cu Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cu Su": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Wu Cu Su": "Shapesanity Stitched Uncolored", + "Adjacent 2-1-1 Wu Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cu Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cu Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Cu Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Rb Rg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Rb Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Rb Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rb Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rb Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Rg Rr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Rg Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rg Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rg Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rg Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Rr Ru": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rr Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rr Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rr Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rr Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rr Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rr Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rr Su": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Rr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ru Sb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Ru Sb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ru Sg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Ru Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ru Sr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Ru Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Ru Su": "Shapesanity Stitched Uncolored", + "Cornered 2-1-1 Wu Ru Su": "Shapesanity Stitched Uncolored", + "Adjacent 2-1-1 Wu Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ru Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Ru Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ru Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Ru Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ru Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Ru Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Sb Sg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Sb Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sb Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Sb Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sb Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Sb Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sb Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Sb Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sb Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Sb Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Sg Sr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sg Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Sg Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sg Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Sg Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sg Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Sg Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sg Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Sg Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sr Su": "Shapesanity Colorful Half-Half Painted", + "Cornered 2-1-1 Wu Sr Su": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sr Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Sr Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sr Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Sr Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sr Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Sr Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Su Wb": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Su Wb": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Su Wg": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Su Wg": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Su Wr": "Shapesanity Stitched Painted", + "Cornered 2-1-1 Wu Su Wr": "Shapesanity Stitched Painted", + "Adjacent 2-1-1 Wu Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wu Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wu Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wu Wb Wc": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wb Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wb Wg": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wu Wb Wg": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wu Wb Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wb Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wb Wr": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wu Wb Wr": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wu Wb Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wb Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wb Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wb Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wc Wg": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wc Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wc Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wc Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wc Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wc Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wc Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wc Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wc Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wc Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wg Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wg Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wg Wr": "Shapesanity East Windmill Painted", + "Cornered 2-1-1 Wu Wg Wr": "Shapesanity East Windmill Painted", + "Adjacent 2-1-1 Wu Wg Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wg Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wg Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wg Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wp Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wp Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wp Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wp Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wp Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wp Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wr Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wr Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Wr Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Wr Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wu Ww Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wu Ww Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cu Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cu Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Cy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Cy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ru Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ru Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Rw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Rw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Ry Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Ry Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sb Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sb Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sc Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sc Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sg Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sg Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sp Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sp Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sr Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sr Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Su Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Su Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Ww Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sw Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sw Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Sy Wy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Ww Sy Wy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Ww Wb Wc": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wb Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wb Wg": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wb Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wb Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wb Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wb Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wb Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wb Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wb Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wb Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wb Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wc Wg": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wc Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wc Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wc Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wc Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wc Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wc Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wc Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wc Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wc Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wg Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wg Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wg Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wg Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wg Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wg Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wg Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wg Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wp Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wp Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wp Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wp Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wp Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wp Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wr Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wr Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wr Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wr Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Ww Wu Wy": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Ww Wu Wy": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Cb Cc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cb Cc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cb Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cb Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cb Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cb Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cb Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cb Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Cg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cc Cg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cc Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cc Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cc Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cc Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cc Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Cp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cg Cp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cg Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cg Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cg Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cg Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Cr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cp Cr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cp Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cp Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cp Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Cu": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cr Cu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cr Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cr Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Cw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cu Cw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cu Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cu Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cu Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Cy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Cw Cy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Rb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Rb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Rc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Rg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Rp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Rr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Ru": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Rw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Ry": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Cy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Cy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rb Rc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rb Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rb Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rb Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rb Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rb Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rb Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rc Rg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rc Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rc Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rc Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rc Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rc Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rg Rp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rg Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rg Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rg Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rg Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rp Rr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rp Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rp Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rp Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rr Ru": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rr Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rr Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Ru Rw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Ru Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ru Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ru Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Rw Ry": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Rw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Rw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Sb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Sb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Sc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Sg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Sp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Sr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Su": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Sw": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Sy": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Ry Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Ry Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sb Sc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sb Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sb Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sb Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sb Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sb Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sb Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sb Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sb Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sb Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sb Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sb Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sb Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sb Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sb Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sc Sg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sc Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sc Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sc Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sc Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sc Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sc Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sc Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sc Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sc Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sc Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sc Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sc Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sc Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sg Sp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sg Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sg Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sg Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sg Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sg Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sg Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sg Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sg Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sg Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sg Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sg Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sg Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sp Sr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sp Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sp Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sp Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sp Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sp Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sp Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sp Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sp Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sp Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sp Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sp Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sr Su": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sr Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sr Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sr Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sr Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sr Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sr Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sr Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sr Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sr Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sr Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sr Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sr Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sr Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sr Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sr Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sr Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Su Sw": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Su Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Su Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Su Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Su Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Su Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Su Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Su Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Su Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Su Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Su Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Su Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Su Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Su Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Su Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Su Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Cornered 2-1-1 Wy Sw Sy": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sw Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sw Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sw Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sw Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sw Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sw Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sw Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sw Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sw Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sw Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sw Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sw Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sw Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sw Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sy Wb": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sy Wb": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sy Wc": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sy Wc": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sy Wg": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sy Wg": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sy Wp": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sy Wp": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sy Wr": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sy Wr": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sy Wu": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sy Wu": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Sy Ww": "Shapesanity Stitched Mixed", + "Cornered 2-1-1 Wy Sy Ww": "Shapesanity Stitched Mixed", + "Adjacent 2-1-1 Wy Wb Wc": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wb Wc": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wb Wg": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wb Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wb Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wb Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wb Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wb Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wb Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wb Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wb Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wb Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wc Wg": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wc Wg": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wc Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wc Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wc Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wc Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wc Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wc Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wc Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wc Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wg Wp": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wg Wp": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wg Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wg Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wg Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wg Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wg Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wg Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wp Wr": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wp Wr": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wp Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wp Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wp Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wp Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wr Wu": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wr Wu": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wr Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wr Ww": "Shapesanity East Windmill Mixed", + "Adjacent 2-1-1 Wy Wu Ww": "Shapesanity East Windmill Mixed", + "Cornered 2-1-1 Wy Wu Ww": "Shapesanity East Windmill Mixed", +} + +shapesanity_four_parts = { + "Singles Cb Cc Cg Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cc Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cc Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Cp Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Su": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Rb": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Rg": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Rr": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Ru": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Sb": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Sg": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Sr": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Su": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Cr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Rb": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Rg": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Rr": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Ru": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Sb": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Sg": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Sr": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Su": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Su": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rb Sb": "Shapesanity Stitched Painted", + "Singles Cb Cg Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rb Sg": "Shapesanity Stitched Painted", + "Singles Cb Cg Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rb Sr": "Shapesanity Stitched Painted", + "Singles Cb Cg Rb Su": "Shapesanity Stitched Painted", + "Singles Cb Cg Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rb Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rb Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rb Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Rb Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Su": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rg Sb": "Shapesanity Stitched Painted", + "Singles Cb Cg Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rg Sg": "Shapesanity Stitched Painted", + "Singles Cb Cg Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rg Sr": "Shapesanity Stitched Painted", + "Singles Cb Cg Rg Su": "Shapesanity Stitched Painted", + "Singles Cb Cg Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rg Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rg Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rg Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Rg Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rr Sb": "Shapesanity Stitched Painted", + "Singles Cb Cg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rr Sg": "Shapesanity Stitched Painted", + "Singles Cb Cg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rr Sr": "Shapesanity Stitched Painted", + "Singles Cb Cg Rr Su": "Shapesanity Stitched Painted", + "Singles Cb Cg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rr Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rr Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rr Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Rr Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Ru Sb": "Shapesanity Stitched Painted", + "Singles Cb Cg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ru Sg": "Shapesanity Stitched Painted", + "Singles Cb Cg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ru Sr": "Shapesanity Stitched Painted", + "Singles Cb Cg Ru Su": "Shapesanity Stitched Painted", + "Singles Cb Cg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ru Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ru Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ru Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Ru Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sb Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sb Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sb Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Sb Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sg Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sg Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sg Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Sg Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sr Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sr Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sr Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Sr Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Cg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Cg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Cg Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Cg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cg Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cg Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cg Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Cr Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Cu Rb": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Rg": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Rr": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Ru": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Sb": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Sg": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Sr": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Su": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Wb": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Wg": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Wr": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Wu": "Shapesanity Stitched Painted", + "Singles Cb Cr Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Su": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rb Sb": "Shapesanity Stitched Painted", + "Singles Cb Cr Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rb Sg": "Shapesanity Stitched Painted", + "Singles Cb Cr Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rb Sr": "Shapesanity Stitched Painted", + "Singles Cb Cr Rb Su": "Shapesanity Stitched Painted", + "Singles Cb Cr Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rb Wb": "Shapesanity Stitched Painted", + "Singles Cb Cr Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rb Wg": "Shapesanity Stitched Painted", + "Singles Cb Cr Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rb Wr": "Shapesanity Stitched Painted", + "Singles Cb Cr Rb Wu": "Shapesanity Stitched Painted", + "Singles Cb Cr Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Su": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rg Sb": "Shapesanity Stitched Painted", + "Singles Cb Cr Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rg Sg": "Shapesanity Stitched Painted", + "Singles Cb Cr Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rg Sr": "Shapesanity Stitched Painted", + "Singles Cb Cr Rg Su": "Shapesanity Stitched Painted", + "Singles Cb Cr Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rg Wb": "Shapesanity Stitched Painted", + "Singles Cb Cr Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rg Wg": "Shapesanity Stitched Painted", + "Singles Cb Cr Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rg Wr": "Shapesanity Stitched Painted", + "Singles Cb Cr Rg Wu": "Shapesanity Stitched Painted", + "Singles Cb Cr Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rr Sb": "Shapesanity Stitched Painted", + "Singles Cb Cr Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rr Sg": "Shapesanity Stitched Painted", + "Singles Cb Cr Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rr Sr": "Shapesanity Stitched Painted", + "Singles Cb Cr Rr Su": "Shapesanity Stitched Painted", + "Singles Cb Cr Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rr Wb": "Shapesanity Stitched Painted", + "Singles Cb Cr Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rr Wg": "Shapesanity Stitched Painted", + "Singles Cb Cr Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rr Wr": "Shapesanity Stitched Painted", + "Singles Cb Cr Rr Wu": "Shapesanity Stitched Painted", + "Singles Cb Cr Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Ru Sb": "Shapesanity Stitched Painted", + "Singles Cb Cr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ru Sg": "Shapesanity Stitched Painted", + "Singles Cb Cr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ru Sr": "Shapesanity Stitched Painted", + "Singles Cb Cr Ru Su": "Shapesanity Stitched Painted", + "Singles Cb Cr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ru Wb": "Shapesanity Stitched Painted", + "Singles Cb Cr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ru Wg": "Shapesanity Stitched Painted", + "Singles Cb Cr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ru Wr": "Shapesanity Stitched Painted", + "Singles Cb Cr Ru Wu": "Shapesanity Stitched Painted", + "Singles Cb Cr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sb Wb": "Shapesanity Stitched Painted", + "Singles Cb Cr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sb Wg": "Shapesanity Stitched Painted", + "Singles Cb Cr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sb Wr": "Shapesanity Stitched Painted", + "Singles Cb Cr Sb Wu": "Shapesanity Stitched Painted", + "Singles Cb Cr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sg Wb": "Shapesanity Stitched Painted", + "Singles Cb Cr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sg Wg": "Shapesanity Stitched Painted", + "Singles Cb Cr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sg Wr": "Shapesanity Stitched Painted", + "Singles Cb Cr Sg Wu": "Shapesanity Stitched Painted", + "Singles Cb Cr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sr Wb": "Shapesanity Stitched Painted", + "Singles Cb Cr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sr Wg": "Shapesanity Stitched Painted", + "Singles Cb Cr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sr Wr": "Shapesanity Stitched Painted", + "Singles Cb Cr Sr Wu": "Shapesanity Stitched Painted", + "Singles Cb Cr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Cr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Cr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Cr Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Cr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Su": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rb Sb": "Shapesanity Stitched Painted", + "Singles Cb Cu Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rb Sg": "Shapesanity Stitched Painted", + "Singles Cb Cu Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rb Sr": "Shapesanity Stitched Painted", + "Singles Cb Cu Rb Su": "Shapesanity Stitched Painted", + "Singles Cb Cu Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rb Wb": "Shapesanity Stitched Painted", + "Singles Cb Cu Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rb Wg": "Shapesanity Stitched Painted", + "Singles Cb Cu Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rb Wr": "Shapesanity Stitched Painted", + "Singles Cb Cu Rb Wu": "Shapesanity Stitched Painted", + "Singles Cb Cu Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Su": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rg Sb": "Shapesanity Stitched Painted", + "Singles Cb Cu Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rg Sg": "Shapesanity Stitched Painted", + "Singles Cb Cu Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rg Sr": "Shapesanity Stitched Painted", + "Singles Cb Cu Rg Su": "Shapesanity Stitched Painted", + "Singles Cb Cu Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rg Wb": "Shapesanity Stitched Painted", + "Singles Cb Cu Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rg Wg": "Shapesanity Stitched Painted", + "Singles Cb Cu Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rg Wr": "Shapesanity Stitched Painted", + "Singles Cb Cu Rg Wu": "Shapesanity Stitched Painted", + "Singles Cb Cu Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rr Sb": "Shapesanity Stitched Painted", + "Singles Cb Cu Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rr Sg": "Shapesanity Stitched Painted", + "Singles Cb Cu Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rr Sr": "Shapesanity Stitched Painted", + "Singles Cb Cu Rr Su": "Shapesanity Stitched Painted", + "Singles Cb Cu Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rr Wb": "Shapesanity Stitched Painted", + "Singles Cb Cu Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rr Wg": "Shapesanity Stitched Painted", + "Singles Cb Cu Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rr Wr": "Shapesanity Stitched Painted", + "Singles Cb Cu Rr Wu": "Shapesanity Stitched Painted", + "Singles Cb Cu Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Ru Sb": "Shapesanity Stitched Painted", + "Singles Cb Cu Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ru Sg": "Shapesanity Stitched Painted", + "Singles Cb Cu Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ru Sr": "Shapesanity Stitched Painted", + "Singles Cb Cu Ru Su": "Shapesanity Stitched Painted", + "Singles Cb Cu Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ru Wb": "Shapesanity Stitched Painted", + "Singles Cb Cu Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ru Wg": "Shapesanity Stitched Painted", + "Singles Cb Cu Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ru Wr": "Shapesanity Stitched Painted", + "Singles Cb Cu Ru Wu": "Shapesanity Stitched Painted", + "Singles Cb Cu Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sb Wb": "Shapesanity Stitched Painted", + "Singles Cb Cu Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sb Wg": "Shapesanity Stitched Painted", + "Singles Cb Cu Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sb Wr": "Shapesanity Stitched Painted", + "Singles Cb Cu Sb Wu": "Shapesanity Stitched Painted", + "Singles Cb Cu Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sg Wb": "Shapesanity Stitched Painted", + "Singles Cb Cu Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sg Wg": "Shapesanity Stitched Painted", + "Singles Cb Cu Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sg Wr": "Shapesanity Stitched Painted", + "Singles Cb Cu Sg Wu": "Shapesanity Stitched Painted", + "Singles Cb Cu Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sr Wb": "Shapesanity Stitched Painted", + "Singles Cb Cu Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sr Wg": "Shapesanity Stitched Painted", + "Singles Cb Cu Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sr Wr": "Shapesanity Stitched Painted", + "Singles Cb Cu Sr Wu": "Shapesanity Stitched Painted", + "Singles Cb Cu Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Cu Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Cu Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Cu Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Cu Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cu Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cu Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cb Cu Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cu Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Su": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Su": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Su": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Su": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Su": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Su": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Su": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Su": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Su": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Su": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Su": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Su Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Su Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Su Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Su Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Cy Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Cy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Cy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cb Rb Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Su": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Rr": "Shapesanity Stitched Painted", + "Singles Cb Rb Rg Ru": "Shapesanity Stitched Painted", + "Singles Cb Rb Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Sb": "Shapesanity Stitched Painted", + "Singles Cb Rb Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Sg": "Shapesanity Stitched Painted", + "Singles Cb Rb Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Sr": "Shapesanity Stitched Painted", + "Singles Cb Rb Rg Su": "Shapesanity Stitched Painted", + "Singles Cb Rb Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Wb": "Shapesanity Stitched Painted", + "Singles Cb Rb Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Wg": "Shapesanity Stitched Painted", + "Singles Cb Rb Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Wr": "Shapesanity Stitched Painted", + "Singles Cb Rb Rg Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr Ru": "Shapesanity Stitched Painted", + "Singles Cb Rb Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr Sb": "Shapesanity Stitched Painted", + "Singles Cb Rb Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr Sg": "Shapesanity Stitched Painted", + "Singles Cb Rb Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr Sr": "Shapesanity Stitched Painted", + "Singles Cb Rb Rr Su": "Shapesanity Stitched Painted", + "Singles Cb Rb Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr Wb": "Shapesanity Stitched Painted", + "Singles Cb Rb Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr Wg": "Shapesanity Stitched Painted", + "Singles Cb Rb Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr Wr": "Shapesanity Stitched Painted", + "Singles Cb Rb Rr Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ru Sb": "Shapesanity Stitched Painted", + "Singles Cb Rb Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ru Sg": "Shapesanity Stitched Painted", + "Singles Cb Rb Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ru Sr": "Shapesanity Stitched Painted", + "Singles Cb Rb Ru Su": "Shapesanity Stitched Painted", + "Singles Cb Rb Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ru Wb": "Shapesanity Stitched Painted", + "Singles Cb Rb Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ru Wg": "Shapesanity Stitched Painted", + "Singles Cb Rb Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ru Wr": "Shapesanity Stitched Painted", + "Singles Cb Rb Ru Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sb Sg": "Shapesanity Stitched Painted", + "Singles Cb Rb Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sb Sr": "Shapesanity Stitched Painted", + "Singles Cb Rb Sb Su": "Shapesanity Stitched Painted", + "Singles Cb Rb Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sb Wg": "Shapesanity Stitched Painted", + "Singles Cb Rb Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sb Wr": "Shapesanity Stitched Painted", + "Singles Cb Rb Sb Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sg Sr": "Shapesanity Stitched Painted", + "Singles Cb Rb Sg Su": "Shapesanity Stitched Painted", + "Singles Cb Rb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sg Wb": "Shapesanity Stitched Painted", + "Singles Cb Rb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sg Wg": "Shapesanity Stitched Painted", + "Singles Cb Rb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sg Wr": "Shapesanity Stitched Painted", + "Singles Cb Rb Sg Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sr Su": "Shapesanity Stitched Painted", + "Singles Cb Rb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sr Wb": "Shapesanity Stitched Painted", + "Singles Cb Rb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sr Wg": "Shapesanity Stitched Painted", + "Singles Cb Rb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sr Wr": "Shapesanity Stitched Painted", + "Singles Cb Rb Sr Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Rb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Rb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Rb Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wb Wg": "Shapesanity Stitched Painted", + "Singles Cb Rb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wb Wr": "Shapesanity Stitched Painted", + "Singles Cb Rb Wb Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cb Rb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Rb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr Ru": "Shapesanity Stitched Painted", + "Singles Cb Rg Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr Sb": "Shapesanity Stitched Painted", + "Singles Cb Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr Sg": "Shapesanity Stitched Painted", + "Singles Cb Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr Sr": "Shapesanity Stitched Painted", + "Singles Cb Rg Rr Su": "Shapesanity Stitched Painted", + "Singles Cb Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr Wb": "Shapesanity Stitched Painted", + "Singles Cb Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr Wg": "Shapesanity Stitched Painted", + "Singles Cb Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr Wr": "Shapesanity Stitched Painted", + "Singles Cb Rg Rr Wu": "Shapesanity Stitched Painted", + "Singles Cb Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ru Sb": "Shapesanity Stitched Painted", + "Singles Cb Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ru Sg": "Shapesanity Stitched Painted", + "Singles Cb Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ru Sr": "Shapesanity Stitched Painted", + "Singles Cb Rg Ru Su": "Shapesanity Stitched Painted", + "Singles Cb Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ru Wb": "Shapesanity Stitched Painted", + "Singles Cb Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ru Wg": "Shapesanity Stitched Painted", + "Singles Cb Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ru Wr": "Shapesanity Stitched Painted", + "Singles Cb Rg Ru Wu": "Shapesanity Stitched Painted", + "Singles Cb Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sb Sg": "Shapesanity Stitched Painted", + "Singles Cb Rg Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sb Sr": "Shapesanity Stitched Painted", + "Singles Cb Rg Sb Su": "Shapesanity Stitched Painted", + "Singles Cb Rg Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sb Wb": "Shapesanity Stitched Painted", + "Singles Cb Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sb Wg": "Shapesanity Stitched Painted", + "Singles Cb Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sb Wr": "Shapesanity Stitched Painted", + "Singles Cb Rg Sb Wu": "Shapesanity Stitched Painted", + "Singles Cb Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Su": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sg Sr": "Shapesanity Stitched Painted", + "Singles Cb Rg Sg Su": "Shapesanity Stitched Painted", + "Singles Cb Rg Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sg Wb": "Shapesanity Stitched Painted", + "Singles Cb Rg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sg Wg": "Shapesanity Stitched Painted", + "Singles Cb Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sg Wr": "Shapesanity Stitched Painted", + "Singles Cb Rg Sg Wu": "Shapesanity Stitched Painted", + "Singles Cb Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sr Su": "Shapesanity Stitched Painted", + "Singles Cb Rg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sr Wb": "Shapesanity Stitched Painted", + "Singles Cb Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sr Wg": "Shapesanity Stitched Painted", + "Singles Cb Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sr Wr": "Shapesanity Stitched Painted", + "Singles Cb Rg Sr Wu": "Shapesanity Stitched Painted", + "Singles Cb Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Rg Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wb Wg": "Shapesanity Stitched Painted", + "Singles Cb Rg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wb Wr": "Shapesanity Stitched Painted", + "Singles Cb Rg Wb Wu": "Shapesanity Stitched Painted", + "Singles Cb Rg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wg Wr": "Shapesanity Stitched Painted", + "Singles Cb Rg Wg Wu": "Shapesanity Stitched Painted", + "Singles Cb Rg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Rg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Su": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Su": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Su": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru Sb": "Shapesanity Stitched Painted", + "Singles Cb Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru Sg": "Shapesanity Stitched Painted", + "Singles Cb Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru Sr": "Shapesanity Stitched Painted", + "Singles Cb Rr Ru Su": "Shapesanity Stitched Painted", + "Singles Cb Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru Wb": "Shapesanity Stitched Painted", + "Singles Cb Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru Wg": "Shapesanity Stitched Painted", + "Singles Cb Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru Wr": "Shapesanity Stitched Painted", + "Singles Cb Rr Ru Wu": "Shapesanity Stitched Painted", + "Singles Cb Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sb Sg": "Shapesanity Stitched Painted", + "Singles Cb Rr Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sb Sr": "Shapesanity Stitched Painted", + "Singles Cb Rr Sb Su": "Shapesanity Stitched Painted", + "Singles Cb Rr Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sb Wb": "Shapesanity Stitched Painted", + "Singles Cb Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sb Wg": "Shapesanity Stitched Painted", + "Singles Cb Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sb Wr": "Shapesanity Stitched Painted", + "Singles Cb Rr Sb Wu": "Shapesanity Stitched Painted", + "Singles Cb Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Su": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sg Sr": "Shapesanity Stitched Painted", + "Singles Cb Rr Sg Su": "Shapesanity Stitched Painted", + "Singles Cb Rr Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sg Wb": "Shapesanity Stitched Painted", + "Singles Cb Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sg Wg": "Shapesanity Stitched Painted", + "Singles Cb Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sg Wr": "Shapesanity Stitched Painted", + "Singles Cb Rr Sg Wu": "Shapesanity Stitched Painted", + "Singles Cb Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sr Su": "Shapesanity Stitched Painted", + "Singles Cb Rr Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sr Wb": "Shapesanity Stitched Painted", + "Singles Cb Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sr Wg": "Shapesanity Stitched Painted", + "Singles Cb Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sr Wr": "Shapesanity Stitched Painted", + "Singles Cb Rr Sr Wu": "Shapesanity Stitched Painted", + "Singles Cb Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Rr Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wb Wg": "Shapesanity Stitched Painted", + "Singles Cb Rr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wb Wr": "Shapesanity Stitched Painted", + "Singles Cb Rr Wb Wu": "Shapesanity Stitched Painted", + "Singles Cb Rr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wg Wr": "Shapesanity Stitched Painted", + "Singles Cb Rr Wg Wu": "Shapesanity Stitched Painted", + "Singles Cb Rr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Rr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sb Sg": "Shapesanity Stitched Painted", + "Singles Cb Ru Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sb Sr": "Shapesanity Stitched Painted", + "Singles Cb Ru Sb Su": "Shapesanity Stitched Painted", + "Singles Cb Ru Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sb Wb": "Shapesanity Stitched Painted", + "Singles Cb Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sb Wg": "Shapesanity Stitched Painted", + "Singles Cb Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sb Wr": "Shapesanity Stitched Painted", + "Singles Cb Ru Sb Wu": "Shapesanity Stitched Painted", + "Singles Cb Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Su": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sg Sr": "Shapesanity Stitched Painted", + "Singles Cb Ru Sg Su": "Shapesanity Stitched Painted", + "Singles Cb Ru Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sg Wb": "Shapesanity Stitched Painted", + "Singles Cb Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sg Wg": "Shapesanity Stitched Painted", + "Singles Cb Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sg Wr": "Shapesanity Stitched Painted", + "Singles Cb Ru Sg Wu": "Shapesanity Stitched Painted", + "Singles Cb Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sr Su": "Shapesanity Stitched Painted", + "Singles Cb Ru Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sr Wb": "Shapesanity Stitched Painted", + "Singles Cb Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sr Wg": "Shapesanity Stitched Painted", + "Singles Cb Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sr Wr": "Shapesanity Stitched Painted", + "Singles Cb Ru Sr Wu": "Shapesanity Stitched Painted", + "Singles Cb Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ru Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Ru Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wb Wg": "Shapesanity Stitched Painted", + "Singles Cb Ru Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wb Wr": "Shapesanity Stitched Painted", + "Singles Cb Ru Wb Wu": "Shapesanity Stitched Painted", + "Singles Cb Ru Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wg Wr": "Shapesanity Stitched Painted", + "Singles Cb Ru Wg Wu": "Shapesanity Stitched Painted", + "Singles Cb Ru Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Ru Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ru Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ru Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Su": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Su": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Su": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Su": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Rw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Rw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Su": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Su": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Su": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Su": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Ry Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Ry Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sg Sr": "Shapesanity Stitched Painted", + "Singles Cb Sb Sg Su": "Shapesanity Stitched Painted", + "Singles Cb Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sg Wb": "Shapesanity Stitched Painted", + "Singles Cb Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sg Wg": "Shapesanity Stitched Painted", + "Singles Cb Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sg Wr": "Shapesanity Stitched Painted", + "Singles Cb Sb Sg Wu": "Shapesanity Stitched Painted", + "Singles Cb Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sr Su": "Shapesanity Stitched Painted", + "Singles Cb Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sr Wb": "Shapesanity Stitched Painted", + "Singles Cb Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sr Wg": "Shapesanity Stitched Painted", + "Singles Cb Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sr Wr": "Shapesanity Stitched Painted", + "Singles Cb Sb Sr Wu": "Shapesanity Stitched Painted", + "Singles Cb Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sb Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Sb Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wb Wg": "Shapesanity Stitched Painted", + "Singles Cb Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wb Wr": "Shapesanity Stitched Painted", + "Singles Cb Sb Wb Wu": "Shapesanity Stitched Painted", + "Singles Cb Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cb Sb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cb Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sr Su": "Shapesanity Stitched Painted", + "Singles Cb Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sr Wb": "Shapesanity Stitched Painted", + "Singles Cb Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sr Wg": "Shapesanity Stitched Painted", + "Singles Cb Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sr Wr": "Shapesanity Stitched Painted", + "Singles Cb Sg Sr Wu": "Shapesanity Stitched Painted", + "Singles Cb Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sg Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sg Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Sg Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wb Wg": "Shapesanity Stitched Painted", + "Singles Cb Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wb Wr": "Shapesanity Stitched Painted", + "Singles Cb Sg Wb Wu": "Shapesanity Stitched Painted", + "Singles Cb Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wg Wr": "Shapesanity Stitched Painted", + "Singles Cb Sg Wg Wu": "Shapesanity Stitched Painted", + "Singles Cb Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cb Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Cb Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Cb Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Cb Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Cb Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wb Wg": "Shapesanity Stitched Painted", + "Singles Cb Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wb Wr": "Shapesanity Stitched Painted", + "Singles Cb Sr Wb Wu": "Shapesanity Stitched Painted", + "Singles Cb Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wg Wr": "Shapesanity Stitched Painted", + "Singles Cb Sr Wg Wu": "Shapesanity Stitched Painted", + "Singles Cb Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cb Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cb Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cb Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cb Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cb Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cb Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cb Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cb Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cb Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Su Wb Wg": "Shapesanity Stitched Painted", + "Singles Cb Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Su Wb Wr": "Shapesanity Stitched Painted", + "Singles Cb Su Wb Wu": "Shapesanity Stitched Painted", + "Singles Cb Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Su Wg Wr": "Shapesanity Stitched Painted", + "Singles Cb Su Wg Wu": "Shapesanity Stitched Painted", + "Singles Cb Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Su Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cb Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cb Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cb Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cb Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cb Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cb Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cb Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cg Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cg Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Cr Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Cu Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cu Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cu Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cu Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Su": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Su": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Su": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Su": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Su": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Su": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Su": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Su": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Su": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Cy Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Cy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Cy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cc Rb Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Su": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Su": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Su": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Su": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Su": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Su": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Su": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ru Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ru Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Su": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Su": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Rw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Rw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Su": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Su": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Ry Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Ry Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cc Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cc Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cc Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cc Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cc Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cc Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cc Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cc Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cc Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Su Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Su Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Su Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Su Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Su Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Su Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cc Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cc Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cc Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cc Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Cu Rb": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Rg": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Rr": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Ru": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Sb": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Sg": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Sr": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Su": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Wb": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Wg": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Wr": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Wu": "Shapesanity Stitched Painted", + "Singles Cg Cr Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Su": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Su": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rb Sb": "Shapesanity Stitched Painted", + "Singles Cg Cr Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rb Sg": "Shapesanity Stitched Painted", + "Singles Cg Cr Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rb Sr": "Shapesanity Stitched Painted", + "Singles Cg Cr Rb Su": "Shapesanity Stitched Painted", + "Singles Cg Cr Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rb Wb": "Shapesanity Stitched Painted", + "Singles Cg Cr Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rb Wg": "Shapesanity Stitched Painted", + "Singles Cg Cr Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rb Wr": "Shapesanity Stitched Painted", + "Singles Cg Cr Rb Wu": "Shapesanity Stitched Painted", + "Singles Cg Cr Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Su": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rg Sb": "Shapesanity Stitched Painted", + "Singles Cg Cr Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rg Sg": "Shapesanity Stitched Painted", + "Singles Cg Cr Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rg Sr": "Shapesanity Stitched Painted", + "Singles Cg Cr Rg Su": "Shapesanity Stitched Painted", + "Singles Cg Cr Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rg Wb": "Shapesanity Stitched Painted", + "Singles Cg Cr Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rg Wg": "Shapesanity Stitched Painted", + "Singles Cg Cr Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rg Wr": "Shapesanity Stitched Painted", + "Singles Cg Cr Rg Wu": "Shapesanity Stitched Painted", + "Singles Cg Cr Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Su": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rr Sb": "Shapesanity Stitched Painted", + "Singles Cg Cr Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rr Sg": "Shapesanity Stitched Painted", + "Singles Cg Cr Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rr Sr": "Shapesanity Stitched Painted", + "Singles Cg Cr Rr Su": "Shapesanity Stitched Painted", + "Singles Cg Cr Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rr Wb": "Shapesanity Stitched Painted", + "Singles Cg Cr Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rr Wg": "Shapesanity Stitched Painted", + "Singles Cg Cr Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rr Wr": "Shapesanity Stitched Painted", + "Singles Cg Cr Rr Wu": "Shapesanity Stitched Painted", + "Singles Cg Cr Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Ru Sb": "Shapesanity Stitched Painted", + "Singles Cg Cr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ru Sg": "Shapesanity Stitched Painted", + "Singles Cg Cr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ru Sr": "Shapesanity Stitched Painted", + "Singles Cg Cr Ru Su": "Shapesanity Stitched Painted", + "Singles Cg Cr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ru Wb": "Shapesanity Stitched Painted", + "Singles Cg Cr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ru Wg": "Shapesanity Stitched Painted", + "Singles Cg Cr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ru Wr": "Shapesanity Stitched Painted", + "Singles Cg Cr Ru Wu": "Shapesanity Stitched Painted", + "Singles Cg Cr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sb Wb": "Shapesanity Stitched Painted", + "Singles Cg Cr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sb Wg": "Shapesanity Stitched Painted", + "Singles Cg Cr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sb Wr": "Shapesanity Stitched Painted", + "Singles Cg Cr Sb Wu": "Shapesanity Stitched Painted", + "Singles Cg Cr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sg Wb": "Shapesanity Stitched Painted", + "Singles Cg Cr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sg Wg": "Shapesanity Stitched Painted", + "Singles Cg Cr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sg Wr": "Shapesanity Stitched Painted", + "Singles Cg Cr Sg Wu": "Shapesanity Stitched Painted", + "Singles Cg Cr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sr Wb": "Shapesanity Stitched Painted", + "Singles Cg Cr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sr Wg": "Shapesanity Stitched Painted", + "Singles Cg Cr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sr Wr": "Shapesanity Stitched Painted", + "Singles Cg Cr Sr Wu": "Shapesanity Stitched Painted", + "Singles Cg Cr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Su Wb": "Shapesanity Stitched Painted", + "Singles Cg Cr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Su Wg": "Shapesanity Stitched Painted", + "Singles Cg Cr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Su Wr": "Shapesanity Stitched Painted", + "Singles Cg Cr Su Wu": "Shapesanity Stitched Painted", + "Singles Cg Cr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Su": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Su": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rb Sb": "Shapesanity Stitched Painted", + "Singles Cg Cu Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rb Sg": "Shapesanity Stitched Painted", + "Singles Cg Cu Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rb Sr": "Shapesanity Stitched Painted", + "Singles Cg Cu Rb Su": "Shapesanity Stitched Painted", + "Singles Cg Cu Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rb Wb": "Shapesanity Stitched Painted", + "Singles Cg Cu Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rb Wg": "Shapesanity Stitched Painted", + "Singles Cg Cu Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rb Wr": "Shapesanity Stitched Painted", + "Singles Cg Cu Rb Wu": "Shapesanity Stitched Painted", + "Singles Cg Cu Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Su": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rg Sb": "Shapesanity Stitched Painted", + "Singles Cg Cu Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rg Sg": "Shapesanity Stitched Painted", + "Singles Cg Cu Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rg Sr": "Shapesanity Stitched Painted", + "Singles Cg Cu Rg Su": "Shapesanity Stitched Painted", + "Singles Cg Cu Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rg Wb": "Shapesanity Stitched Painted", + "Singles Cg Cu Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rg Wg": "Shapesanity Stitched Painted", + "Singles Cg Cu Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rg Wr": "Shapesanity Stitched Painted", + "Singles Cg Cu Rg Wu": "Shapesanity Stitched Painted", + "Singles Cg Cu Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Su": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rr Sb": "Shapesanity Stitched Painted", + "Singles Cg Cu Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rr Sg": "Shapesanity Stitched Painted", + "Singles Cg Cu Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rr Sr": "Shapesanity Stitched Painted", + "Singles Cg Cu Rr Su": "Shapesanity Stitched Painted", + "Singles Cg Cu Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rr Wb": "Shapesanity Stitched Painted", + "Singles Cg Cu Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rr Wg": "Shapesanity Stitched Painted", + "Singles Cg Cu Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rr Wr": "Shapesanity Stitched Painted", + "Singles Cg Cu Rr Wu": "Shapesanity Stitched Painted", + "Singles Cg Cu Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Ru Sb": "Shapesanity Stitched Painted", + "Singles Cg Cu Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ru Sg": "Shapesanity Stitched Painted", + "Singles Cg Cu Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ru Sr": "Shapesanity Stitched Painted", + "Singles Cg Cu Ru Su": "Shapesanity Stitched Painted", + "Singles Cg Cu Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ru Wb": "Shapesanity Stitched Painted", + "Singles Cg Cu Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ru Wg": "Shapesanity Stitched Painted", + "Singles Cg Cu Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ru Wr": "Shapesanity Stitched Painted", + "Singles Cg Cu Ru Wu": "Shapesanity Stitched Painted", + "Singles Cg Cu Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sb Wb": "Shapesanity Stitched Painted", + "Singles Cg Cu Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sb Wg": "Shapesanity Stitched Painted", + "Singles Cg Cu Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sb Wr": "Shapesanity Stitched Painted", + "Singles Cg Cu Sb Wu": "Shapesanity Stitched Painted", + "Singles Cg Cu Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sg Wb": "Shapesanity Stitched Painted", + "Singles Cg Cu Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sg Wg": "Shapesanity Stitched Painted", + "Singles Cg Cu Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sg Wr": "Shapesanity Stitched Painted", + "Singles Cg Cu Sg Wu": "Shapesanity Stitched Painted", + "Singles Cg Cu Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sr Wb": "Shapesanity Stitched Painted", + "Singles Cg Cu Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sr Wg": "Shapesanity Stitched Painted", + "Singles Cg Cu Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sr Wr": "Shapesanity Stitched Painted", + "Singles Cg Cu Sr Wu": "Shapesanity Stitched Painted", + "Singles Cg Cu Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Su Wb": "Shapesanity Stitched Painted", + "Singles Cg Cu Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Su Wg": "Shapesanity Stitched Painted", + "Singles Cg Cu Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Su Wr": "Shapesanity Stitched Painted", + "Singles Cg Cu Su Wu": "Shapesanity Stitched Painted", + "Singles Cg Cu Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cu Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cu Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cg Cu Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cu Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Su": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Su": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Su": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Su": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Su": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Su": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Su": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Su": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Su": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Su": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Su": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Su": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Su": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Su Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Su Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Su Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Su Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Cy Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Cy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Cy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cg Rb Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Su": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Rr": "Shapesanity Stitched Painted", + "Singles Cg Rb Rg Ru": "Shapesanity Stitched Painted", + "Singles Cg Rb Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Sb": "Shapesanity Stitched Painted", + "Singles Cg Rb Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Sg": "Shapesanity Stitched Painted", + "Singles Cg Rb Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Sr": "Shapesanity Stitched Painted", + "Singles Cg Rb Rg Su": "Shapesanity Stitched Painted", + "Singles Cg Rb Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Wb": "Shapesanity Stitched Painted", + "Singles Cg Rb Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Wg": "Shapesanity Stitched Painted", + "Singles Cg Rb Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Wr": "Shapesanity Stitched Painted", + "Singles Cg Rb Rg Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Su": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr Ru": "Shapesanity Stitched Painted", + "Singles Cg Rb Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr Sb": "Shapesanity Stitched Painted", + "Singles Cg Rb Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr Sg": "Shapesanity Stitched Painted", + "Singles Cg Rb Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr Sr": "Shapesanity Stitched Painted", + "Singles Cg Rb Rr Su": "Shapesanity Stitched Painted", + "Singles Cg Rb Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr Wb": "Shapesanity Stitched Painted", + "Singles Cg Rb Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr Wg": "Shapesanity Stitched Painted", + "Singles Cg Rb Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr Wr": "Shapesanity Stitched Painted", + "Singles Cg Rb Rr Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ru Sb": "Shapesanity Stitched Painted", + "Singles Cg Rb Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ru Sg": "Shapesanity Stitched Painted", + "Singles Cg Rb Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ru Sr": "Shapesanity Stitched Painted", + "Singles Cg Rb Ru Su": "Shapesanity Stitched Painted", + "Singles Cg Rb Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ru Wb": "Shapesanity Stitched Painted", + "Singles Cg Rb Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ru Wg": "Shapesanity Stitched Painted", + "Singles Cg Rb Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ru Wr": "Shapesanity Stitched Painted", + "Singles Cg Rb Ru Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sb Sg": "Shapesanity Stitched Painted", + "Singles Cg Rb Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sb Sr": "Shapesanity Stitched Painted", + "Singles Cg Rb Sb Su": "Shapesanity Stitched Painted", + "Singles Cg Rb Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sb Wb": "Shapesanity Stitched Painted", + "Singles Cg Rb Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sb Wg": "Shapesanity Stitched Painted", + "Singles Cg Rb Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sb Wr": "Shapesanity Stitched Painted", + "Singles Cg Rb Sb Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sg Sr": "Shapesanity Stitched Painted", + "Singles Cg Rb Sg Su": "Shapesanity Stitched Painted", + "Singles Cg Rb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sg Wb": "Shapesanity Stitched Painted", + "Singles Cg Rb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sg Wg": "Shapesanity Stitched Painted", + "Singles Cg Rb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sg Wr": "Shapesanity Stitched Painted", + "Singles Cg Rb Sg Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sr Su": "Shapesanity Stitched Painted", + "Singles Cg Rb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sr Wb": "Shapesanity Stitched Painted", + "Singles Cg Rb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sr Wg": "Shapesanity Stitched Painted", + "Singles Cg Rb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sr Wr": "Shapesanity Stitched Painted", + "Singles Cg Rb Sr Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Su Wb": "Shapesanity Stitched Painted", + "Singles Cg Rb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Su Wg": "Shapesanity Stitched Painted", + "Singles Cg Rb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Su Wr": "Shapesanity Stitched Painted", + "Singles Cg Rb Su Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wb Wg": "Shapesanity Stitched Painted", + "Singles Cg Rb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wb Wr": "Shapesanity Stitched Painted", + "Singles Cg Rb Wb Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cg Rb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Rb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr Ru": "Shapesanity Stitched Painted", + "Singles Cg Rg Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr Sb": "Shapesanity Stitched Painted", + "Singles Cg Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr Sg": "Shapesanity Stitched Painted", + "Singles Cg Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr Sr": "Shapesanity Stitched Painted", + "Singles Cg Rg Rr Su": "Shapesanity Stitched Painted", + "Singles Cg Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr Wb": "Shapesanity Stitched Painted", + "Singles Cg Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr Wg": "Shapesanity Stitched Painted", + "Singles Cg Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr Wr": "Shapesanity Stitched Painted", + "Singles Cg Rg Rr Wu": "Shapesanity Stitched Painted", + "Singles Cg Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ru Sb": "Shapesanity Stitched Painted", + "Singles Cg Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ru Sg": "Shapesanity Stitched Painted", + "Singles Cg Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ru Sr": "Shapesanity Stitched Painted", + "Singles Cg Rg Ru Su": "Shapesanity Stitched Painted", + "Singles Cg Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ru Wb": "Shapesanity Stitched Painted", + "Singles Cg Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ru Wg": "Shapesanity Stitched Painted", + "Singles Cg Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ru Wr": "Shapesanity Stitched Painted", + "Singles Cg Rg Ru Wu": "Shapesanity Stitched Painted", + "Singles Cg Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sb Sg": "Shapesanity Stitched Painted", + "Singles Cg Rg Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sb Sr": "Shapesanity Stitched Painted", + "Singles Cg Rg Sb Su": "Shapesanity Stitched Painted", + "Singles Cg Rg Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sb Wb": "Shapesanity Stitched Painted", + "Singles Cg Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sb Wg": "Shapesanity Stitched Painted", + "Singles Cg Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sb Wr": "Shapesanity Stitched Painted", + "Singles Cg Rg Sb Wu": "Shapesanity Stitched Painted", + "Singles Cg Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Su": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sg Sr": "Shapesanity Stitched Painted", + "Singles Cg Rg Sg Su": "Shapesanity Stitched Painted", + "Singles Cg Rg Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sg Wb": "Shapesanity Stitched Painted", + "Singles Cg Rg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sg Wr": "Shapesanity Stitched Painted", + "Singles Cg Rg Sg Wu": "Shapesanity Stitched Painted", + "Singles Cg Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sr Su": "Shapesanity Stitched Painted", + "Singles Cg Rg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sr Wb": "Shapesanity Stitched Painted", + "Singles Cg Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sr Wg": "Shapesanity Stitched Painted", + "Singles Cg Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sr Wr": "Shapesanity Stitched Painted", + "Singles Cg Rg Sr Wu": "Shapesanity Stitched Painted", + "Singles Cg Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Su Wb": "Shapesanity Stitched Painted", + "Singles Cg Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Su Wg": "Shapesanity Stitched Painted", + "Singles Cg Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Su Wr": "Shapesanity Stitched Painted", + "Singles Cg Rg Su Wu": "Shapesanity Stitched Painted", + "Singles Cg Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wb Wg": "Shapesanity Stitched Painted", + "Singles Cg Rg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wb Wr": "Shapesanity Stitched Painted", + "Singles Cg Rg Wb Wu": "Shapesanity Stitched Painted", + "Singles Cg Rg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wg Wr": "Shapesanity Stitched Painted", + "Singles Cg Rg Wg Wu": "Shapesanity Stitched Painted", + "Singles Cg Rg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Rg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Su": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Su": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Su": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru Sb": "Shapesanity Stitched Painted", + "Singles Cg Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru Sg": "Shapesanity Stitched Painted", + "Singles Cg Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru Sr": "Shapesanity Stitched Painted", + "Singles Cg Rr Ru Su": "Shapesanity Stitched Painted", + "Singles Cg Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru Wb": "Shapesanity Stitched Painted", + "Singles Cg Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru Wg": "Shapesanity Stitched Painted", + "Singles Cg Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru Wr": "Shapesanity Stitched Painted", + "Singles Cg Rr Ru Wu": "Shapesanity Stitched Painted", + "Singles Cg Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sb Sg": "Shapesanity Stitched Painted", + "Singles Cg Rr Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sb Sr": "Shapesanity Stitched Painted", + "Singles Cg Rr Sb Su": "Shapesanity Stitched Painted", + "Singles Cg Rr Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sb Wb": "Shapesanity Stitched Painted", + "Singles Cg Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sb Wg": "Shapesanity Stitched Painted", + "Singles Cg Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sb Wr": "Shapesanity Stitched Painted", + "Singles Cg Rr Sb Wu": "Shapesanity Stitched Painted", + "Singles Cg Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Su": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sg Sr": "Shapesanity Stitched Painted", + "Singles Cg Rr Sg Su": "Shapesanity Stitched Painted", + "Singles Cg Rr Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sg Wb": "Shapesanity Stitched Painted", + "Singles Cg Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sg Wg": "Shapesanity Stitched Painted", + "Singles Cg Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sg Wr": "Shapesanity Stitched Painted", + "Singles Cg Rr Sg Wu": "Shapesanity Stitched Painted", + "Singles Cg Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sr Su": "Shapesanity Stitched Painted", + "Singles Cg Rr Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sr Wb": "Shapesanity Stitched Painted", + "Singles Cg Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sr Wg": "Shapesanity Stitched Painted", + "Singles Cg Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sr Wr": "Shapesanity Stitched Painted", + "Singles Cg Rr Sr Wu": "Shapesanity Stitched Painted", + "Singles Cg Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Su Wb": "Shapesanity Stitched Painted", + "Singles Cg Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Su Wg": "Shapesanity Stitched Painted", + "Singles Cg Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Su Wr": "Shapesanity Stitched Painted", + "Singles Cg Rr Su Wu": "Shapesanity Stitched Painted", + "Singles Cg Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wb Wg": "Shapesanity Stitched Painted", + "Singles Cg Rr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wb Wr": "Shapesanity Stitched Painted", + "Singles Cg Rr Wb Wu": "Shapesanity Stitched Painted", + "Singles Cg Rr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wg Wr": "Shapesanity Stitched Painted", + "Singles Cg Rr Wg Wu": "Shapesanity Stitched Painted", + "Singles Cg Rr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Rr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sb Sg": "Shapesanity Stitched Painted", + "Singles Cg Ru Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sb Sr": "Shapesanity Stitched Painted", + "Singles Cg Ru Sb Su": "Shapesanity Stitched Painted", + "Singles Cg Ru Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sb Wb": "Shapesanity Stitched Painted", + "Singles Cg Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sb Wg": "Shapesanity Stitched Painted", + "Singles Cg Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sb Wr": "Shapesanity Stitched Painted", + "Singles Cg Ru Sb Wu": "Shapesanity Stitched Painted", + "Singles Cg Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Su": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sg Sr": "Shapesanity Stitched Painted", + "Singles Cg Ru Sg Su": "Shapesanity Stitched Painted", + "Singles Cg Ru Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sg Wb": "Shapesanity Stitched Painted", + "Singles Cg Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sg Wg": "Shapesanity Stitched Painted", + "Singles Cg Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sg Wr": "Shapesanity Stitched Painted", + "Singles Cg Ru Sg Wu": "Shapesanity Stitched Painted", + "Singles Cg Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sr Su": "Shapesanity Stitched Painted", + "Singles Cg Ru Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sr Wb": "Shapesanity Stitched Painted", + "Singles Cg Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sr Wg": "Shapesanity Stitched Painted", + "Singles Cg Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sr Wr": "Shapesanity Stitched Painted", + "Singles Cg Ru Sr Wu": "Shapesanity Stitched Painted", + "Singles Cg Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ru Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Su Wb": "Shapesanity Stitched Painted", + "Singles Cg Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Su Wg": "Shapesanity Stitched Painted", + "Singles Cg Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Su Wr": "Shapesanity Stitched Painted", + "Singles Cg Ru Su Wu": "Shapesanity Stitched Painted", + "Singles Cg Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wb Wg": "Shapesanity Stitched Painted", + "Singles Cg Ru Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wb Wr": "Shapesanity Stitched Painted", + "Singles Cg Ru Wb Wu": "Shapesanity Stitched Painted", + "Singles Cg Ru Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wg Wr": "Shapesanity Stitched Painted", + "Singles Cg Ru Wg Wu": "Shapesanity Stitched Painted", + "Singles Cg Ru Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Ru Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ru Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ru Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Su": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Su": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Su": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Su": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Rw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Rw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Su": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Su": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Su": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Su": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Ry Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Ry Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sg Sr": "Shapesanity Stitched Painted", + "Singles Cg Sb Sg Su": "Shapesanity Stitched Painted", + "Singles Cg Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sg Wb": "Shapesanity Stitched Painted", + "Singles Cg Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sg Wg": "Shapesanity Stitched Painted", + "Singles Cg Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sg Wr": "Shapesanity Stitched Painted", + "Singles Cg Sb Sg Wu": "Shapesanity Stitched Painted", + "Singles Cg Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sr Su": "Shapesanity Stitched Painted", + "Singles Cg Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sr Wb": "Shapesanity Stitched Painted", + "Singles Cg Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sr Wg": "Shapesanity Stitched Painted", + "Singles Cg Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sr Wr": "Shapesanity Stitched Painted", + "Singles Cg Sb Sr Wu": "Shapesanity Stitched Painted", + "Singles Cg Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Su Wb": "Shapesanity Stitched Painted", + "Singles Cg Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sb Su Wg": "Shapesanity Stitched Painted", + "Singles Cg Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Su Wr": "Shapesanity Stitched Painted", + "Singles Cg Sb Su Wu": "Shapesanity Stitched Painted", + "Singles Cg Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wb Wg": "Shapesanity Stitched Painted", + "Singles Cg Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wb Wr": "Shapesanity Stitched Painted", + "Singles Cg Sb Wb Wu": "Shapesanity Stitched Painted", + "Singles Cg Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cg Sb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cg Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sr Su": "Shapesanity Stitched Painted", + "Singles Cg Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sr Wb": "Shapesanity Stitched Painted", + "Singles Cg Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sr Wg": "Shapesanity Stitched Painted", + "Singles Cg Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sr Wr": "Shapesanity Stitched Painted", + "Singles Cg Sg Sr Wu": "Shapesanity Stitched Painted", + "Singles Cg Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Su Wb": "Shapesanity Stitched Painted", + "Singles Cg Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sg Su Wg": "Shapesanity Stitched Painted", + "Singles Cg Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sg Su Wr": "Shapesanity Stitched Painted", + "Singles Cg Sg Su Wu": "Shapesanity Stitched Painted", + "Singles Cg Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wb Wg": "Shapesanity Stitched Painted", + "Singles Cg Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wb Wr": "Shapesanity Stitched Painted", + "Singles Cg Sg Wb Wu": "Shapesanity Stitched Painted", + "Singles Cg Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wg Wr": "Shapesanity Stitched Painted", + "Singles Cg Sg Wg Wu": "Shapesanity Stitched Painted", + "Singles Cg Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cg Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Cg Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Cg Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Cg Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Cg Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wb Wg": "Shapesanity Stitched Painted", + "Singles Cg Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wb Wr": "Shapesanity Stitched Painted", + "Singles Cg Sr Wb Wu": "Shapesanity Stitched Painted", + "Singles Cg Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wg Wr": "Shapesanity Stitched Painted", + "Singles Cg Sr Wg Wu": "Shapesanity Stitched Painted", + "Singles Cg Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cg Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cg Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cg Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cg Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cg Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cg Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cg Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cg Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cg Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Su Wb Wg": "Shapesanity Stitched Painted", + "Singles Cg Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Su Wb Wr": "Shapesanity Stitched Painted", + "Singles Cg Su Wb Wu": "Shapesanity Stitched Painted", + "Singles Cg Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Su Wg Wr": "Shapesanity Stitched Painted", + "Singles Cg Su Wg Wu": "Shapesanity Stitched Painted", + "Singles Cg Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Su Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cg Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cg Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cg Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cg Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cg Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cg Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cg Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Rb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Rc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Rg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Rp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Rr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Ru": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Rw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Ry": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cu Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cu Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cu Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Su": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Su": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Su": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Su": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Su": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Su": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Su": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Su": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Su": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Su": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Su": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Su": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Su": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Cy Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Cy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Cy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cp Rb Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Su": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Su": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Su": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Su": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Su": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Su": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Su": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ru Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ru Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Su": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Su": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Rw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Rw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Su": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Su": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Ry Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Ry Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cp Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cp Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cp Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cp Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cp Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cp Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cp Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cp Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cp Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Su Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Su Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Su Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Su Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Su Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Su Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cp Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cp Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cp Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cp Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Rb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Rc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Rg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Rp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Rr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Ru": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Rw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Ry": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Su": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Su": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rb Rg": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rb Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Rb Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rb Sb": "Shapesanity Stitched Painted", + "Singles Cr Cu Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rb Sg": "Shapesanity Stitched Painted", + "Singles Cr Cu Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rb Sr": "Shapesanity Stitched Painted", + "Singles Cr Cu Rb Su": "Shapesanity Stitched Painted", + "Singles Cr Cu Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rb Wb": "Shapesanity Stitched Painted", + "Singles Cr Cu Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rb Wg": "Shapesanity Stitched Painted", + "Singles Cr Cu Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rb Wr": "Shapesanity Stitched Painted", + "Singles Cr Cu Rb Wu": "Shapesanity Stitched Painted", + "Singles Cr Cu Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Su": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rg Rr": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Rg Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rg Sb": "Shapesanity Stitched Painted", + "Singles Cr Cu Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rg Sg": "Shapesanity Stitched Painted", + "Singles Cr Cu Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rg Sr": "Shapesanity Stitched Painted", + "Singles Cr Cu Rg Su": "Shapesanity Stitched Painted", + "Singles Cr Cu Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rg Wb": "Shapesanity Stitched Painted", + "Singles Cr Cu Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rg Wg": "Shapesanity Stitched Painted", + "Singles Cr Cu Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rg Wr": "Shapesanity Stitched Painted", + "Singles Cr Cu Rg Wu": "Shapesanity Stitched Painted", + "Singles Cr Cu Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Su": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rr Ru": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rr Sb": "Shapesanity Stitched Painted", + "Singles Cr Cu Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rr Sg": "Shapesanity Stitched Painted", + "Singles Cr Cu Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rr Sr": "Shapesanity Stitched Painted", + "Singles Cr Cu Rr Su": "Shapesanity Stitched Painted", + "Singles Cr Cu Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rr Wb": "Shapesanity Stitched Painted", + "Singles Cr Cu Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rr Wg": "Shapesanity Stitched Painted", + "Singles Cr Cu Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rr Wr": "Shapesanity Stitched Painted", + "Singles Cr Cu Rr Wu": "Shapesanity Stitched Painted", + "Singles Cr Cu Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Ru Sb": "Shapesanity Stitched Painted", + "Singles Cr Cu Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ru Sg": "Shapesanity Stitched Painted", + "Singles Cr Cu Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ru Sr": "Shapesanity Stitched Painted", + "Singles Cr Cu Ru Su": "Shapesanity Stitched Painted", + "Singles Cr Cu Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ru Wb": "Shapesanity Stitched Painted", + "Singles Cr Cu Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ru Wg": "Shapesanity Stitched Painted", + "Singles Cr Cu Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ru Wr": "Shapesanity Stitched Painted", + "Singles Cr Cu Ru Wu": "Shapesanity Stitched Painted", + "Singles Cr Cu Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Su": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sb Wb": "Shapesanity Stitched Painted", + "Singles Cr Cu Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sb Wg": "Shapesanity Stitched Painted", + "Singles Cr Cu Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sb Wr": "Shapesanity Stitched Painted", + "Singles Cr Cu Sb Wu": "Shapesanity Stitched Painted", + "Singles Cr Cu Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sg Wb": "Shapesanity Stitched Painted", + "Singles Cr Cu Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sg Wg": "Shapesanity Stitched Painted", + "Singles Cr Cu Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sg Wr": "Shapesanity Stitched Painted", + "Singles Cr Cu Sg Wu": "Shapesanity Stitched Painted", + "Singles Cr Cu Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sr Wb": "Shapesanity Stitched Painted", + "Singles Cr Cu Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sr Wg": "Shapesanity Stitched Painted", + "Singles Cr Cu Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sr Wr": "Shapesanity Stitched Painted", + "Singles Cr Cu Sr Wu": "Shapesanity Stitched Painted", + "Singles Cr Cu Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Su Wb": "Shapesanity Stitched Painted", + "Singles Cr Cu Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Su Wg": "Shapesanity Stitched Painted", + "Singles Cr Cu Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Su Wr": "Shapesanity Stitched Painted", + "Singles Cr Cu Su Wu": "Shapesanity Stitched Painted", + "Singles Cr Cu Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cu Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cu Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Cr Cu Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cu Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Su": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Su": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Su": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Su": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Su": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Su": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Su": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Su": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Su": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Su": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Su": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Su": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Su": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Su": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Su": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Su Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Su Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Su Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Su Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Cy Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Cy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Cy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cr Rb Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Su": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Rr": "Shapesanity Stitched Painted", + "Singles Cr Rb Rg Ru": "Shapesanity Stitched Painted", + "Singles Cr Rb Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Sb": "Shapesanity Stitched Painted", + "Singles Cr Rb Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Sg": "Shapesanity Stitched Painted", + "Singles Cr Rb Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Sr": "Shapesanity Stitched Painted", + "Singles Cr Rb Rg Su": "Shapesanity Stitched Painted", + "Singles Cr Rb Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Wb": "Shapesanity Stitched Painted", + "Singles Cr Rb Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Wg": "Shapesanity Stitched Painted", + "Singles Cr Rb Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Wr": "Shapesanity Stitched Painted", + "Singles Cr Rb Rg Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Su": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr Ru": "Shapesanity Stitched Painted", + "Singles Cr Rb Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr Sb": "Shapesanity Stitched Painted", + "Singles Cr Rb Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr Sg": "Shapesanity Stitched Painted", + "Singles Cr Rb Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr Sr": "Shapesanity Stitched Painted", + "Singles Cr Rb Rr Su": "Shapesanity Stitched Painted", + "Singles Cr Rb Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr Wb": "Shapesanity Stitched Painted", + "Singles Cr Rb Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr Wg": "Shapesanity Stitched Painted", + "Singles Cr Rb Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr Wr": "Shapesanity Stitched Painted", + "Singles Cr Rb Rr Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ru Sb": "Shapesanity Stitched Painted", + "Singles Cr Rb Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ru Sg": "Shapesanity Stitched Painted", + "Singles Cr Rb Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ru Sr": "Shapesanity Stitched Painted", + "Singles Cr Rb Ru Su": "Shapesanity Stitched Painted", + "Singles Cr Rb Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ru Wb": "Shapesanity Stitched Painted", + "Singles Cr Rb Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ru Wg": "Shapesanity Stitched Painted", + "Singles Cr Rb Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ru Wr": "Shapesanity Stitched Painted", + "Singles Cr Rb Ru Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Su": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sb Sg": "Shapesanity Stitched Painted", + "Singles Cr Rb Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sb Sr": "Shapesanity Stitched Painted", + "Singles Cr Rb Sb Su": "Shapesanity Stitched Painted", + "Singles Cr Rb Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sb Wb": "Shapesanity Stitched Painted", + "Singles Cr Rb Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sb Wg": "Shapesanity Stitched Painted", + "Singles Cr Rb Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sb Wr": "Shapesanity Stitched Painted", + "Singles Cr Rb Sb Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sg Sr": "Shapesanity Stitched Painted", + "Singles Cr Rb Sg Su": "Shapesanity Stitched Painted", + "Singles Cr Rb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sg Wb": "Shapesanity Stitched Painted", + "Singles Cr Rb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sg Wg": "Shapesanity Stitched Painted", + "Singles Cr Rb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sg Wr": "Shapesanity Stitched Painted", + "Singles Cr Rb Sg Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sr Su": "Shapesanity Stitched Painted", + "Singles Cr Rb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sr Wb": "Shapesanity Stitched Painted", + "Singles Cr Rb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sr Wg": "Shapesanity Stitched Painted", + "Singles Cr Rb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sr Wr": "Shapesanity Stitched Painted", + "Singles Cr Rb Sr Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Su Wb": "Shapesanity Stitched Painted", + "Singles Cr Rb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Su Wg": "Shapesanity Stitched Painted", + "Singles Cr Rb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Su Wr": "Shapesanity Stitched Painted", + "Singles Cr Rb Su Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wb Wg": "Shapesanity Stitched Painted", + "Singles Cr Rb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wb Wr": "Shapesanity Stitched Painted", + "Singles Cr Rb Wb Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cr Rb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Rb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr Ru": "Shapesanity Stitched Painted", + "Singles Cr Rg Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr Sb": "Shapesanity Stitched Painted", + "Singles Cr Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr Sg": "Shapesanity Stitched Painted", + "Singles Cr Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr Sr": "Shapesanity Stitched Painted", + "Singles Cr Rg Rr Su": "Shapesanity Stitched Painted", + "Singles Cr Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr Wb": "Shapesanity Stitched Painted", + "Singles Cr Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr Wg": "Shapesanity Stitched Painted", + "Singles Cr Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr Wr": "Shapesanity Stitched Painted", + "Singles Cr Rg Rr Wu": "Shapesanity Stitched Painted", + "Singles Cr Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ru Sb": "Shapesanity Stitched Painted", + "Singles Cr Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ru Sg": "Shapesanity Stitched Painted", + "Singles Cr Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ru Sr": "Shapesanity Stitched Painted", + "Singles Cr Rg Ru Su": "Shapesanity Stitched Painted", + "Singles Cr Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ru Wb": "Shapesanity Stitched Painted", + "Singles Cr Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ru Wg": "Shapesanity Stitched Painted", + "Singles Cr Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ru Wr": "Shapesanity Stitched Painted", + "Singles Cr Rg Ru Wu": "Shapesanity Stitched Painted", + "Singles Cr Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sb Sg": "Shapesanity Stitched Painted", + "Singles Cr Rg Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sb Sr": "Shapesanity Stitched Painted", + "Singles Cr Rg Sb Su": "Shapesanity Stitched Painted", + "Singles Cr Rg Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sb Wb": "Shapesanity Stitched Painted", + "Singles Cr Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sb Wg": "Shapesanity Stitched Painted", + "Singles Cr Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sb Wr": "Shapesanity Stitched Painted", + "Singles Cr Rg Sb Wu": "Shapesanity Stitched Painted", + "Singles Cr Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Su": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sg Sr": "Shapesanity Stitched Painted", + "Singles Cr Rg Sg Su": "Shapesanity Stitched Painted", + "Singles Cr Rg Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sg Wb": "Shapesanity Stitched Painted", + "Singles Cr Rg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sg Wg": "Shapesanity Stitched Painted", + "Singles Cr Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sg Wr": "Shapesanity Stitched Painted", + "Singles Cr Rg Sg Wu": "Shapesanity Stitched Painted", + "Singles Cr Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sr Su": "Shapesanity Stitched Painted", + "Singles Cr Rg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sr Wb": "Shapesanity Stitched Painted", + "Singles Cr Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sr Wg": "Shapesanity Stitched Painted", + "Singles Cr Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sr Wr": "Shapesanity Stitched Painted", + "Singles Cr Rg Sr Wu": "Shapesanity Stitched Painted", + "Singles Cr Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Su Wb": "Shapesanity Stitched Painted", + "Singles Cr Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Su Wg": "Shapesanity Stitched Painted", + "Singles Cr Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Su Wr": "Shapesanity Stitched Painted", + "Singles Cr Rg Su Wu": "Shapesanity Stitched Painted", + "Singles Cr Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wb Wg": "Shapesanity Stitched Painted", + "Singles Cr Rg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wb Wr": "Shapesanity Stitched Painted", + "Singles Cr Rg Wb Wu": "Shapesanity Stitched Painted", + "Singles Cr Rg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wg Wr": "Shapesanity Stitched Painted", + "Singles Cr Rg Wg Wu": "Shapesanity Stitched Painted", + "Singles Cr Rg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Rg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Su": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Su": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Su": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru Sb": "Shapesanity Stitched Painted", + "Singles Cr Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru Sg": "Shapesanity Stitched Painted", + "Singles Cr Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru Sr": "Shapesanity Stitched Painted", + "Singles Cr Rr Ru Su": "Shapesanity Stitched Painted", + "Singles Cr Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru Wb": "Shapesanity Stitched Painted", + "Singles Cr Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru Wg": "Shapesanity Stitched Painted", + "Singles Cr Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru Wr": "Shapesanity Stitched Painted", + "Singles Cr Rr Ru Wu": "Shapesanity Stitched Painted", + "Singles Cr Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sb Sg": "Shapesanity Stitched Painted", + "Singles Cr Rr Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sb Sr": "Shapesanity Stitched Painted", + "Singles Cr Rr Sb Su": "Shapesanity Stitched Painted", + "Singles Cr Rr Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sb Wb": "Shapesanity Stitched Painted", + "Singles Cr Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sb Wg": "Shapesanity Stitched Painted", + "Singles Cr Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sb Wr": "Shapesanity Stitched Painted", + "Singles Cr Rr Sb Wu": "Shapesanity Stitched Painted", + "Singles Cr Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Su": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sg Sr": "Shapesanity Stitched Painted", + "Singles Cr Rr Sg Su": "Shapesanity Stitched Painted", + "Singles Cr Rr Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sg Wb": "Shapesanity Stitched Painted", + "Singles Cr Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sg Wg": "Shapesanity Stitched Painted", + "Singles Cr Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sg Wr": "Shapesanity Stitched Painted", + "Singles Cr Rr Sg Wu": "Shapesanity Stitched Painted", + "Singles Cr Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sr Su": "Shapesanity Stitched Painted", + "Singles Cr Rr Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sr Wb": "Shapesanity Stitched Painted", + "Singles Cr Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sr Wg": "Shapesanity Stitched Painted", + "Singles Cr Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sr Wu": "Shapesanity Stitched Painted", + "Singles Cr Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Su Wb": "Shapesanity Stitched Painted", + "Singles Cr Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Su Wg": "Shapesanity Stitched Painted", + "Singles Cr Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Su Wr": "Shapesanity Stitched Painted", + "Singles Cr Rr Su Wu": "Shapesanity Stitched Painted", + "Singles Cr Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wb Wg": "Shapesanity Stitched Painted", + "Singles Cr Rr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wb Wr": "Shapesanity Stitched Painted", + "Singles Cr Rr Wb Wu": "Shapesanity Stitched Painted", + "Singles Cr Rr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wg Wr": "Shapesanity Stitched Painted", + "Singles Cr Rr Wg Wu": "Shapesanity Stitched Painted", + "Singles Cr Rr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Rr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sb Sg": "Shapesanity Stitched Painted", + "Singles Cr Ru Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sb Sr": "Shapesanity Stitched Painted", + "Singles Cr Ru Sb Su": "Shapesanity Stitched Painted", + "Singles Cr Ru Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sb Wb": "Shapesanity Stitched Painted", + "Singles Cr Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sb Wg": "Shapesanity Stitched Painted", + "Singles Cr Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sb Wr": "Shapesanity Stitched Painted", + "Singles Cr Ru Sb Wu": "Shapesanity Stitched Painted", + "Singles Cr Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Su": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sg Sr": "Shapesanity Stitched Painted", + "Singles Cr Ru Sg Su": "Shapesanity Stitched Painted", + "Singles Cr Ru Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sg Wb": "Shapesanity Stitched Painted", + "Singles Cr Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sg Wg": "Shapesanity Stitched Painted", + "Singles Cr Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sg Wr": "Shapesanity Stitched Painted", + "Singles Cr Ru Sg Wu": "Shapesanity Stitched Painted", + "Singles Cr Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sr Su": "Shapesanity Stitched Painted", + "Singles Cr Ru Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sr Wb": "Shapesanity Stitched Painted", + "Singles Cr Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sr Wg": "Shapesanity Stitched Painted", + "Singles Cr Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sr Wr": "Shapesanity Stitched Painted", + "Singles Cr Ru Sr Wu": "Shapesanity Stitched Painted", + "Singles Cr Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ru Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Su Wb": "Shapesanity Stitched Painted", + "Singles Cr Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Su Wg": "Shapesanity Stitched Painted", + "Singles Cr Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Su Wr": "Shapesanity Stitched Painted", + "Singles Cr Ru Su Wu": "Shapesanity Stitched Painted", + "Singles Cr Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wb Wg": "Shapesanity Stitched Painted", + "Singles Cr Ru Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wb Wr": "Shapesanity Stitched Painted", + "Singles Cr Ru Wb Wu": "Shapesanity Stitched Painted", + "Singles Cr Ru Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wg Wr": "Shapesanity Stitched Painted", + "Singles Cr Ru Wg Wu": "Shapesanity Stitched Painted", + "Singles Cr Ru Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Ru Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ru Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ru Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Su": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Su": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Su": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Su": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Rw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Rw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Su": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Su": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Su": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Su": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Ry Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Ry Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sg Sr": "Shapesanity Stitched Painted", + "Singles Cr Sb Sg Su": "Shapesanity Stitched Painted", + "Singles Cr Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sg Wb": "Shapesanity Stitched Painted", + "Singles Cr Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sg Wg": "Shapesanity Stitched Painted", + "Singles Cr Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sg Wr": "Shapesanity Stitched Painted", + "Singles Cr Sb Sg Wu": "Shapesanity Stitched Painted", + "Singles Cr Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sr Su": "Shapesanity Stitched Painted", + "Singles Cr Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sr Wb": "Shapesanity Stitched Painted", + "Singles Cr Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sr Wg": "Shapesanity Stitched Painted", + "Singles Cr Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sr Wr": "Shapesanity Stitched Painted", + "Singles Cr Sb Sr Wu": "Shapesanity Stitched Painted", + "Singles Cr Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Su Wb": "Shapesanity Stitched Painted", + "Singles Cr Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sb Su Wg": "Shapesanity Stitched Painted", + "Singles Cr Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Su Wr": "Shapesanity Stitched Painted", + "Singles Cr Sb Su Wu": "Shapesanity Stitched Painted", + "Singles Cr Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wb Wg": "Shapesanity Stitched Painted", + "Singles Cr Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wb Wr": "Shapesanity Stitched Painted", + "Singles Cr Sb Wb Wu": "Shapesanity Stitched Painted", + "Singles Cr Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cr Sb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cr Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sr Su": "Shapesanity Stitched Painted", + "Singles Cr Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sr Wb": "Shapesanity Stitched Painted", + "Singles Cr Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sr Wg": "Shapesanity Stitched Painted", + "Singles Cr Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sr Wr": "Shapesanity Stitched Painted", + "Singles Cr Sg Sr Wu": "Shapesanity Stitched Painted", + "Singles Cr Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Su Wb": "Shapesanity Stitched Painted", + "Singles Cr Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sg Su Wg": "Shapesanity Stitched Painted", + "Singles Cr Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sg Su Wr": "Shapesanity Stitched Painted", + "Singles Cr Sg Su Wu": "Shapesanity Stitched Painted", + "Singles Cr Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wb Wg": "Shapesanity Stitched Painted", + "Singles Cr Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wb Wr": "Shapesanity Stitched Painted", + "Singles Cr Sg Wb Wu": "Shapesanity Stitched Painted", + "Singles Cr Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wg Wr": "Shapesanity Stitched Painted", + "Singles Cr Sg Wg Wu": "Shapesanity Stitched Painted", + "Singles Cr Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cr Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Cr Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Cr Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Cr Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Cr Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wb Wg": "Shapesanity Stitched Painted", + "Singles Cr Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wb Wr": "Shapesanity Stitched Painted", + "Singles Cr Sr Wb Wu": "Shapesanity Stitched Painted", + "Singles Cr Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wg Wr": "Shapesanity Stitched Painted", + "Singles Cr Sr Wg Wu": "Shapesanity Stitched Painted", + "Singles Cr Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cr Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cr Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cr Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cr Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cr Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cr Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cr Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cr Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cr Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Su Wb Wg": "Shapesanity Stitched Painted", + "Singles Cr Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Su Wb Wr": "Shapesanity Stitched Painted", + "Singles Cr Su Wb Wu": "Shapesanity Stitched Painted", + "Singles Cr Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Su Wg Wr": "Shapesanity Stitched Painted", + "Singles Cr Su Wg Wu": "Shapesanity Stitched Painted", + "Singles Cr Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Su Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cr Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cr Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cr Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cr Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cr Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cr Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cr Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Rb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Rc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Rg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Rp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Rr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Ru": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Rw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Ry": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Su": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Cy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Su": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Su": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Su": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Su": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Su": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Su": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Su": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Su": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Su": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Su": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Su": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Su": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Su": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Su": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Su": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Su Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Su Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Su Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Su Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Cy Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Cy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Cy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cu Rb Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Su": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Rr": "Shapesanity Stitched Painted", + "Singles Cu Rb Rg Ru": "Shapesanity Stitched Painted", + "Singles Cu Rb Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Sb": "Shapesanity Stitched Painted", + "Singles Cu Rb Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Sg": "Shapesanity Stitched Painted", + "Singles Cu Rb Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Sr": "Shapesanity Stitched Painted", + "Singles Cu Rb Rg Su": "Shapesanity Stitched Painted", + "Singles Cu Rb Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Wb": "Shapesanity Stitched Painted", + "Singles Cu Rb Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Wg": "Shapesanity Stitched Painted", + "Singles Cu Rb Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Wr": "Shapesanity Stitched Painted", + "Singles Cu Rb Rg Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Su": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr Ru": "Shapesanity Stitched Painted", + "Singles Cu Rb Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr Sb": "Shapesanity Stitched Painted", + "Singles Cu Rb Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr Sg": "Shapesanity Stitched Painted", + "Singles Cu Rb Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr Sr": "Shapesanity Stitched Painted", + "Singles Cu Rb Rr Su": "Shapesanity Stitched Painted", + "Singles Cu Rb Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr Wb": "Shapesanity Stitched Painted", + "Singles Cu Rb Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr Wg": "Shapesanity Stitched Painted", + "Singles Cu Rb Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr Wr": "Shapesanity Stitched Painted", + "Singles Cu Rb Rr Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ru Sb": "Shapesanity Stitched Painted", + "Singles Cu Rb Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ru Sg": "Shapesanity Stitched Painted", + "Singles Cu Rb Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ru Sr": "Shapesanity Stitched Painted", + "Singles Cu Rb Ru Su": "Shapesanity Stitched Painted", + "Singles Cu Rb Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ru Wb": "Shapesanity Stitched Painted", + "Singles Cu Rb Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ru Wg": "Shapesanity Stitched Painted", + "Singles Cu Rb Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ru Wr": "Shapesanity Stitched Painted", + "Singles Cu Rb Ru Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Su": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Su": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sb Sg": "Shapesanity Stitched Painted", + "Singles Cu Rb Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sb Sr": "Shapesanity Stitched Painted", + "Singles Cu Rb Sb Su": "Shapesanity Stitched Painted", + "Singles Cu Rb Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sb Wb": "Shapesanity Stitched Painted", + "Singles Cu Rb Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sb Wg": "Shapesanity Stitched Painted", + "Singles Cu Rb Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sb Wr": "Shapesanity Stitched Painted", + "Singles Cu Rb Sb Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sg Sr": "Shapesanity Stitched Painted", + "Singles Cu Rb Sg Su": "Shapesanity Stitched Painted", + "Singles Cu Rb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sg Wb": "Shapesanity Stitched Painted", + "Singles Cu Rb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sg Wg": "Shapesanity Stitched Painted", + "Singles Cu Rb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sg Wr": "Shapesanity Stitched Painted", + "Singles Cu Rb Sg Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sr Su": "Shapesanity Stitched Painted", + "Singles Cu Rb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sr Wb": "Shapesanity Stitched Painted", + "Singles Cu Rb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sr Wg": "Shapesanity Stitched Painted", + "Singles Cu Rb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sr Wr": "Shapesanity Stitched Painted", + "Singles Cu Rb Sr Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Su Wb": "Shapesanity Stitched Painted", + "Singles Cu Rb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Su Wg": "Shapesanity Stitched Painted", + "Singles Cu Rb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Su Wr": "Shapesanity Stitched Painted", + "Singles Cu Rb Su Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wb Wg": "Shapesanity Stitched Painted", + "Singles Cu Rb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wb Wr": "Shapesanity Stitched Painted", + "Singles Cu Rb Wb Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cu Rb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Rb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr Ru": "Shapesanity Stitched Painted", + "Singles Cu Rg Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr Sb": "Shapesanity Stitched Painted", + "Singles Cu Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr Sg": "Shapesanity Stitched Painted", + "Singles Cu Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr Sr": "Shapesanity Stitched Painted", + "Singles Cu Rg Rr Su": "Shapesanity Stitched Painted", + "Singles Cu Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr Wb": "Shapesanity Stitched Painted", + "Singles Cu Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr Wg": "Shapesanity Stitched Painted", + "Singles Cu Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr Wr": "Shapesanity Stitched Painted", + "Singles Cu Rg Rr Wu": "Shapesanity Stitched Painted", + "Singles Cu Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ru Sb": "Shapesanity Stitched Painted", + "Singles Cu Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ru Sg": "Shapesanity Stitched Painted", + "Singles Cu Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ru Sr": "Shapesanity Stitched Painted", + "Singles Cu Rg Ru Su": "Shapesanity Stitched Painted", + "Singles Cu Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ru Wb": "Shapesanity Stitched Painted", + "Singles Cu Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ru Wg": "Shapesanity Stitched Painted", + "Singles Cu Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ru Wr": "Shapesanity Stitched Painted", + "Singles Cu Rg Ru Wu": "Shapesanity Stitched Painted", + "Singles Cu Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sb Sg": "Shapesanity Stitched Painted", + "Singles Cu Rg Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sb Sr": "Shapesanity Stitched Painted", + "Singles Cu Rg Sb Su": "Shapesanity Stitched Painted", + "Singles Cu Rg Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sb Wb": "Shapesanity Stitched Painted", + "Singles Cu Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sb Wg": "Shapesanity Stitched Painted", + "Singles Cu Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sb Wr": "Shapesanity Stitched Painted", + "Singles Cu Rg Sb Wu": "Shapesanity Stitched Painted", + "Singles Cu Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Su": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sg Sr": "Shapesanity Stitched Painted", + "Singles Cu Rg Sg Su": "Shapesanity Stitched Painted", + "Singles Cu Rg Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sg Wb": "Shapesanity Stitched Painted", + "Singles Cu Rg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sg Wg": "Shapesanity Stitched Painted", + "Singles Cu Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sg Wr": "Shapesanity Stitched Painted", + "Singles Cu Rg Sg Wu": "Shapesanity Stitched Painted", + "Singles Cu Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sr Su": "Shapesanity Stitched Painted", + "Singles Cu Rg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sr Wb": "Shapesanity Stitched Painted", + "Singles Cu Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sr Wg": "Shapesanity Stitched Painted", + "Singles Cu Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sr Wr": "Shapesanity Stitched Painted", + "Singles Cu Rg Sr Wu": "Shapesanity Stitched Painted", + "Singles Cu Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Su Wb": "Shapesanity Stitched Painted", + "Singles Cu Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Su Wg": "Shapesanity Stitched Painted", + "Singles Cu Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Su Wr": "Shapesanity Stitched Painted", + "Singles Cu Rg Su Wu": "Shapesanity Stitched Painted", + "Singles Cu Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wb Wg": "Shapesanity Stitched Painted", + "Singles Cu Rg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wb Wr": "Shapesanity Stitched Painted", + "Singles Cu Rg Wb Wu": "Shapesanity Stitched Painted", + "Singles Cu Rg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wg Wr": "Shapesanity Stitched Painted", + "Singles Cu Rg Wg Wu": "Shapesanity Stitched Painted", + "Singles Cu Rg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Rg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Su": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Su": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Su": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru Sb": "Shapesanity Stitched Painted", + "Singles Cu Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru Sg": "Shapesanity Stitched Painted", + "Singles Cu Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru Sr": "Shapesanity Stitched Painted", + "Singles Cu Rr Ru Su": "Shapesanity Stitched Painted", + "Singles Cu Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru Wb": "Shapesanity Stitched Painted", + "Singles Cu Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru Wg": "Shapesanity Stitched Painted", + "Singles Cu Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru Wr": "Shapesanity Stitched Painted", + "Singles Cu Rr Ru Wu": "Shapesanity Stitched Painted", + "Singles Cu Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sb Sg": "Shapesanity Stitched Painted", + "Singles Cu Rr Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sb Sr": "Shapesanity Stitched Painted", + "Singles Cu Rr Sb Su": "Shapesanity Stitched Painted", + "Singles Cu Rr Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sb Wb": "Shapesanity Stitched Painted", + "Singles Cu Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sb Wg": "Shapesanity Stitched Painted", + "Singles Cu Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sb Wr": "Shapesanity Stitched Painted", + "Singles Cu Rr Sb Wu": "Shapesanity Stitched Painted", + "Singles Cu Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Su": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sg Sr": "Shapesanity Stitched Painted", + "Singles Cu Rr Sg Su": "Shapesanity Stitched Painted", + "Singles Cu Rr Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sg Wb": "Shapesanity Stitched Painted", + "Singles Cu Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sg Wg": "Shapesanity Stitched Painted", + "Singles Cu Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sg Wr": "Shapesanity Stitched Painted", + "Singles Cu Rr Sg Wu": "Shapesanity Stitched Painted", + "Singles Cu Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sr Su": "Shapesanity Stitched Painted", + "Singles Cu Rr Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sr Wb": "Shapesanity Stitched Painted", + "Singles Cu Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sr Wg": "Shapesanity Stitched Painted", + "Singles Cu Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sr Wr": "Shapesanity Stitched Painted", + "Singles Cu Rr Sr Wu": "Shapesanity Stitched Painted", + "Singles Cu Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Su Wb": "Shapesanity Stitched Painted", + "Singles Cu Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Su Wg": "Shapesanity Stitched Painted", + "Singles Cu Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Su Wr": "Shapesanity Stitched Painted", + "Singles Cu Rr Su Wu": "Shapesanity Stitched Painted", + "Singles Cu Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wb Wg": "Shapesanity Stitched Painted", + "Singles Cu Rr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wb Wr": "Shapesanity Stitched Painted", + "Singles Cu Rr Wb Wu": "Shapesanity Stitched Painted", + "Singles Cu Rr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wg Wr": "Shapesanity Stitched Painted", + "Singles Cu Rr Wg Wu": "Shapesanity Stitched Painted", + "Singles Cu Rr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Rr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sb Sg": "Shapesanity Stitched Painted", + "Singles Cu Ru Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sb Sr": "Shapesanity Stitched Painted", + "Singles Cu Ru Sb Su": "Shapesanity Stitched Painted", + "Singles Cu Ru Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sb Wb": "Shapesanity Stitched Painted", + "Singles Cu Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sb Wg": "Shapesanity Stitched Painted", + "Singles Cu Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sb Wr": "Shapesanity Stitched Painted", + "Singles Cu Ru Sb Wu": "Shapesanity Stitched Painted", + "Singles Cu Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Su": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sg Sr": "Shapesanity Stitched Painted", + "Singles Cu Ru Sg Su": "Shapesanity Stitched Painted", + "Singles Cu Ru Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sg Wb": "Shapesanity Stitched Painted", + "Singles Cu Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sg Wg": "Shapesanity Stitched Painted", + "Singles Cu Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sg Wr": "Shapesanity Stitched Painted", + "Singles Cu Ru Sg Wu": "Shapesanity Stitched Painted", + "Singles Cu Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sr Su": "Shapesanity Stitched Painted", + "Singles Cu Ru Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sr Wb": "Shapesanity Stitched Painted", + "Singles Cu Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sr Wg": "Shapesanity Stitched Painted", + "Singles Cu Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sr Wr": "Shapesanity Stitched Painted", + "Singles Cu Ru Sr Wu": "Shapesanity Stitched Painted", + "Singles Cu Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ru Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Su Wb": "Shapesanity Stitched Painted", + "Singles Cu Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Su Wg": "Shapesanity Stitched Painted", + "Singles Cu Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Su Wr": "Shapesanity Stitched Painted", + "Singles Cu Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wb Wg": "Shapesanity Stitched Painted", + "Singles Cu Ru Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wb Wr": "Shapesanity Stitched Painted", + "Singles Cu Ru Wb Wu": "Shapesanity Stitched Painted", + "Singles Cu Ru Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wg Wr": "Shapesanity Stitched Painted", + "Singles Cu Ru Wg Wu": "Shapesanity Stitched Painted", + "Singles Cu Ru Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Ru Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ru Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ru Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Su": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Su": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Su": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Su": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Rw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Rw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Su": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Su": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Su": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Su": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Ry Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Ry Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sg Sr": "Shapesanity Stitched Painted", + "Singles Cu Sb Sg Su": "Shapesanity Stitched Painted", + "Singles Cu Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sg Wb": "Shapesanity Stitched Painted", + "Singles Cu Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sg Wg": "Shapesanity Stitched Painted", + "Singles Cu Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sg Wr": "Shapesanity Stitched Painted", + "Singles Cu Sb Sg Wu": "Shapesanity Stitched Painted", + "Singles Cu Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sr Su": "Shapesanity Stitched Painted", + "Singles Cu Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sr Wb": "Shapesanity Stitched Painted", + "Singles Cu Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sr Wg": "Shapesanity Stitched Painted", + "Singles Cu Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sr Wr": "Shapesanity Stitched Painted", + "Singles Cu Sb Sr Wu": "Shapesanity Stitched Painted", + "Singles Cu Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Su Wb": "Shapesanity Stitched Painted", + "Singles Cu Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sb Su Wg": "Shapesanity Stitched Painted", + "Singles Cu Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Su Wr": "Shapesanity Stitched Painted", + "Singles Cu Sb Su Wu": "Shapesanity Stitched Painted", + "Singles Cu Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wb Wg": "Shapesanity Stitched Painted", + "Singles Cu Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wb Wr": "Shapesanity Stitched Painted", + "Singles Cu Sb Wb Wu": "Shapesanity Stitched Painted", + "Singles Cu Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cu Sb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cu Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sr Su": "Shapesanity Stitched Painted", + "Singles Cu Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sr Wb": "Shapesanity Stitched Painted", + "Singles Cu Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sr Wg": "Shapesanity Stitched Painted", + "Singles Cu Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sr Wr": "Shapesanity Stitched Painted", + "Singles Cu Sg Sr Wu": "Shapesanity Stitched Painted", + "Singles Cu Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Su Wb": "Shapesanity Stitched Painted", + "Singles Cu Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sg Su Wg": "Shapesanity Stitched Painted", + "Singles Cu Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sg Su Wr": "Shapesanity Stitched Painted", + "Singles Cu Sg Su Wu": "Shapesanity Stitched Painted", + "Singles Cu Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wb Wg": "Shapesanity Stitched Painted", + "Singles Cu Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wb Wr": "Shapesanity Stitched Painted", + "Singles Cu Sg Wb Wu": "Shapesanity Stitched Painted", + "Singles Cu Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wg Wr": "Shapesanity Stitched Painted", + "Singles Cu Sg Wg Wu": "Shapesanity Stitched Painted", + "Singles Cu Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cu Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Cu Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Cu Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Cu Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Cu Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wb Wg": "Shapesanity Stitched Painted", + "Singles Cu Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wb Wr": "Shapesanity Stitched Painted", + "Singles Cu Sr Wb Wu": "Shapesanity Stitched Painted", + "Singles Cu Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wg Wr": "Shapesanity Stitched Painted", + "Singles Cu Sr Wg Wu": "Shapesanity Stitched Painted", + "Singles Cu Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cu Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cu Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cu Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cu Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cu Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cu Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cu Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cu Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cu Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Su Wb Wg": "Shapesanity Stitched Painted", + "Singles Cu Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Su Wb Wr": "Shapesanity Stitched Painted", + "Singles Cu Su Wb Wu": "Shapesanity Stitched Painted", + "Singles Cu Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Su Wg Wr": "Shapesanity Stitched Painted", + "Singles Cu Su Wg Wu": "Shapesanity Stitched Painted", + "Singles Cu Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Su Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cu Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Cu Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Cu Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Cu Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cu Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cu Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cu Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Rc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rb Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rb Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rb Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rb Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rb Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rb Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rb Sb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Su": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Rg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rc Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rc Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rc Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rc Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rc Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Su": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Rp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rg Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rg Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rg Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rg Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Su": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Rr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rp Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rp Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rp Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Su": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Ru": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rr Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rr Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Su": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Rw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Ru Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Su": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Ry": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Su": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Su": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Cy Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Cy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Cy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Cw Rb Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Su": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Su": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Su": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Su": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Su": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Su": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Su": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ru Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ru Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Su": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Su": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Rw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Rw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Su": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Su": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Ry Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Ry Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cw Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cw Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cw Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cw Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cw Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cw Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cw Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cw Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cw Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Su Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Su Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Su Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Su Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Su Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Su Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cw Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cw Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cw Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cw Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Rg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Rp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Rr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Rp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Rr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Rr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Ru": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Su": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Su": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Rw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Su": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Su": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Su": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Ry": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Su": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Su": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ru Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ru Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Su": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Su": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Rw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Rw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Sc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Sg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Sp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Su": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Su": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Ry Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Ry Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Cy Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Cy Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Cy Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Cy Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Cy Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Cy Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Cy Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Cy Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Cy Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Su Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Su Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Su Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Su Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Su Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Su Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Cy Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Cy Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Cy Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Cy Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Su": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Su": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Su": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Su": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Su": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Su": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Su Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Su Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Su Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Su Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rc Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rc Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rr Sb": "Shapesanity Stitched Painted", + "Singles Rb Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rr Sg": "Shapesanity Stitched Painted", + "Singles Rb Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rr Sr": "Shapesanity Stitched Painted", + "Singles Rb Rg Rr Su": "Shapesanity Stitched Painted", + "Singles Rb Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rr Wb": "Shapesanity Stitched Painted", + "Singles Rb Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rr Wg": "Shapesanity Stitched Painted", + "Singles Rb Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rr Wr": "Shapesanity Stitched Painted", + "Singles Rb Rg Rr Wu": "Shapesanity Stitched Painted", + "Singles Rb Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ru Sb": "Shapesanity Stitched Painted", + "Singles Rb Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ru Sg": "Shapesanity Stitched Painted", + "Singles Rb Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ru Sr": "Shapesanity Stitched Painted", + "Singles Rb Rg Ru Su": "Shapesanity Stitched Painted", + "Singles Rb Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ru Wb": "Shapesanity Stitched Painted", + "Singles Rb Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ru Wg": "Shapesanity Stitched Painted", + "Singles Rb Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ru Wr": "Shapesanity Stitched Painted", + "Singles Rb Rg Ru Wu": "Shapesanity Stitched Painted", + "Singles Rb Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sb Wb": "Shapesanity Stitched Painted", + "Singles Rb Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sb Wg": "Shapesanity Stitched Painted", + "Singles Rb Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sb Wr": "Shapesanity Stitched Painted", + "Singles Rb Rg Sb Wu": "Shapesanity Stitched Painted", + "Singles Rb Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sg Wb": "Shapesanity Stitched Painted", + "Singles Rb Rg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sg Wg": "Shapesanity Stitched Painted", + "Singles Rb Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sg Wr": "Shapesanity Stitched Painted", + "Singles Rb Rg Sg Wu": "Shapesanity Stitched Painted", + "Singles Rb Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sr Wb": "Shapesanity Stitched Painted", + "Singles Rb Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sr Wg": "Shapesanity Stitched Painted", + "Singles Rb Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sr Wr": "Shapesanity Stitched Painted", + "Singles Rb Rg Sr Wu": "Shapesanity Stitched Painted", + "Singles Rb Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Su Wb": "Shapesanity Stitched Painted", + "Singles Rb Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Su Wg": "Shapesanity Stitched Painted", + "Singles Rb Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Su Wr": "Shapesanity Stitched Painted", + "Singles Rb Rg Su Wu": "Shapesanity Stitched Painted", + "Singles Rb Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rg Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rg Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rg Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Ru Sb": "Shapesanity Stitched Painted", + "Singles Rb Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ru Sg": "Shapesanity Stitched Painted", + "Singles Rb Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ru Sr": "Shapesanity Stitched Painted", + "Singles Rb Rr Ru Su": "Shapesanity Stitched Painted", + "Singles Rb Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ru Wb": "Shapesanity Stitched Painted", + "Singles Rb Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ru Wg": "Shapesanity Stitched Painted", + "Singles Rb Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ru Wr": "Shapesanity Stitched Painted", + "Singles Rb Rr Ru Wu": "Shapesanity Stitched Painted", + "Singles Rb Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sb Wb": "Shapesanity Stitched Painted", + "Singles Rb Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sb Wg": "Shapesanity Stitched Painted", + "Singles Rb Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sb Wr": "Shapesanity Stitched Painted", + "Singles Rb Rr Sb Wu": "Shapesanity Stitched Painted", + "Singles Rb Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sg Wb": "Shapesanity Stitched Painted", + "Singles Rb Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sg Wg": "Shapesanity Stitched Painted", + "Singles Rb Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sg Wr": "Shapesanity Stitched Painted", + "Singles Rb Rr Sg Wu": "Shapesanity Stitched Painted", + "Singles Rb Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sr Wb": "Shapesanity Stitched Painted", + "Singles Rb Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sr Wg": "Shapesanity Stitched Painted", + "Singles Rb Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sr Wr": "Shapesanity Stitched Painted", + "Singles Rb Rr Sr Wu": "Shapesanity Stitched Painted", + "Singles Rb Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Su Wb": "Shapesanity Stitched Painted", + "Singles Rb Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Su Wg": "Shapesanity Stitched Painted", + "Singles Rb Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Su Wr": "Shapesanity Stitched Painted", + "Singles Rb Rr Su Wu": "Shapesanity Stitched Painted", + "Singles Rb Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Rr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sb Wb": "Shapesanity Stitched Painted", + "Singles Rb Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sb Wg": "Shapesanity Stitched Painted", + "Singles Rb Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sb Wr": "Shapesanity Stitched Painted", + "Singles Rb Ru Sb Wu": "Shapesanity Stitched Painted", + "Singles Rb Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sg Wb": "Shapesanity Stitched Painted", + "Singles Rb Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sg Wg": "Shapesanity Stitched Painted", + "Singles Rb Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sg Wr": "Shapesanity Stitched Painted", + "Singles Rb Ru Sg Wu": "Shapesanity Stitched Painted", + "Singles Rb Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sr Wb": "Shapesanity Stitched Painted", + "Singles Rb Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sr Wg": "Shapesanity Stitched Painted", + "Singles Rb Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sr Wr": "Shapesanity Stitched Painted", + "Singles Rb Ru Sr Wu": "Shapesanity Stitched Painted", + "Singles Rb Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Su Wb": "Shapesanity Stitched Painted", + "Singles Rb Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Su Wg": "Shapesanity Stitched Painted", + "Singles Rb Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Su Wr": "Shapesanity Stitched Painted", + "Singles Rb Ru Su Wu": "Shapesanity Stitched Painted", + "Singles Rb Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ru Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rb Ru Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ru Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Rw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Rw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ry Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Ry Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Ry Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rb Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sg Sr": "Shapesanity Stitched Painted", + "Singles Rb Sb Sg Su": "Shapesanity Stitched Painted", + "Singles Rb Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sg Wb": "Shapesanity Stitched Painted", + "Singles Rb Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sg Wg": "Shapesanity Stitched Painted", + "Singles Rb Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sg Wr": "Shapesanity Stitched Painted", + "Singles Rb Sb Sg Wu": "Shapesanity Stitched Painted", + "Singles Rb Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sr Su": "Shapesanity Stitched Painted", + "Singles Rb Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sr Wb": "Shapesanity Stitched Painted", + "Singles Rb Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sr Wg": "Shapesanity Stitched Painted", + "Singles Rb Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sr Wr": "Shapesanity Stitched Painted", + "Singles Rb Sb Sr Wu": "Shapesanity Stitched Painted", + "Singles Rb Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Su Wb": "Shapesanity Stitched Painted", + "Singles Rb Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sb Su Wg": "Shapesanity Stitched Painted", + "Singles Rb Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Su Wr": "Shapesanity Stitched Painted", + "Singles Rb Sb Su Wu": "Shapesanity Stitched Painted", + "Singles Rb Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wb Wg": "Shapesanity Stitched Painted", + "Singles Rb Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wb Wr": "Shapesanity Stitched Painted", + "Singles Rb Sb Wb Wu": "Shapesanity Stitched Painted", + "Singles Rb Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wg Wr": "Shapesanity Stitched Painted", + "Singles Rb Sb Wg Wu": "Shapesanity Stitched Painted", + "Singles Rb Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wr Wu": "Shapesanity Stitched Painted", + "Singles Rb Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sr Su": "Shapesanity Stitched Painted", + "Singles Rb Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sr Wb": "Shapesanity Stitched Painted", + "Singles Rb Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sr Wg": "Shapesanity Stitched Painted", + "Singles Rb Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sr Wr": "Shapesanity Stitched Painted", + "Singles Rb Sg Sr Wu": "Shapesanity Stitched Painted", + "Singles Rb Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Su Wb": "Shapesanity Stitched Painted", + "Singles Rb Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sg Su Wg": "Shapesanity Stitched Painted", + "Singles Rb Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sg Su Wr": "Shapesanity Stitched Painted", + "Singles Rb Sg Su Wu": "Shapesanity Stitched Painted", + "Singles Rb Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wb Wg": "Shapesanity Stitched Painted", + "Singles Rb Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wb Wr": "Shapesanity Stitched Painted", + "Singles Rb Sg Wb Wu": "Shapesanity Stitched Painted", + "Singles Rb Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wg Wr": "Shapesanity Stitched Painted", + "Singles Rb Sg Wg Wu": "Shapesanity Stitched Painted", + "Singles Rb Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wr Wu": "Shapesanity Stitched Painted", + "Singles Rb Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Rb Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Rb Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Rb Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Rb Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Rb Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wb Wg": "Shapesanity Stitched Painted", + "Singles Rb Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wb Wr": "Shapesanity Stitched Painted", + "Singles Rb Sr Wb Wu": "Shapesanity Stitched Painted", + "Singles Rb Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wg Wr": "Shapesanity Stitched Painted", + "Singles Rb Sr Wg Wu": "Shapesanity Stitched Painted", + "Singles Rb Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wr Wu": "Shapesanity Stitched Painted", + "Singles Rb Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rb Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rb Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rb Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rb Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rb Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rb Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rb Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rb Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rb Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Su Wb Wg": "Shapesanity Stitched Painted", + "Singles Rb Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Su Wb Wr": "Shapesanity Stitched Painted", + "Singles Rb Su Wb Wu": "Shapesanity Stitched Painted", + "Singles Rb Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Su Wg Wr": "Shapesanity Stitched Painted", + "Singles Rb Su Wg Wu": "Shapesanity Stitched Painted", + "Singles Rb Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Su Wr Wu": "Shapesanity Stitched Painted", + "Singles Rb Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rb Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Rb Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Rb Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Rb Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Rb Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rb Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rb Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rb Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Su": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Su": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Su": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Su": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Su": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rg Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rg Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Ru Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Su": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ru Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ru Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Rw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Rw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ry Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Ry Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Ry Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rc Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Su": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Su": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Su": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rc Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rc Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rc Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rc Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rc Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rc Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rc Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rc Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rc Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Su Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Su Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Su Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Su Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Su Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Su Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rc Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rc Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rc Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rc Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Sb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Sg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Sr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Su": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Sb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Sg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Sr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Su": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Su": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Su": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Su Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Su Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Su Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Su Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Ru Sb": "Shapesanity Stitched Painted", + "Singles Rg Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ru Sg": "Shapesanity Stitched Painted", + "Singles Rg Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ru Sr": "Shapesanity Stitched Painted", + "Singles Rg Rr Ru Su": "Shapesanity Stitched Painted", + "Singles Rg Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ru Wb": "Shapesanity Stitched Painted", + "Singles Rg Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ru Wg": "Shapesanity Stitched Painted", + "Singles Rg Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ru Wr": "Shapesanity Stitched Painted", + "Singles Rg Rr Ru Wu": "Shapesanity Stitched Painted", + "Singles Rg Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sb Wb": "Shapesanity Stitched Painted", + "Singles Rg Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sb Wg": "Shapesanity Stitched Painted", + "Singles Rg Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sb Wr": "Shapesanity Stitched Painted", + "Singles Rg Rr Sb Wu": "Shapesanity Stitched Painted", + "Singles Rg Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sg Wb": "Shapesanity Stitched Painted", + "Singles Rg Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sg Wg": "Shapesanity Stitched Painted", + "Singles Rg Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sg Wr": "Shapesanity Stitched Painted", + "Singles Rg Rr Sg Wu": "Shapesanity Stitched Painted", + "Singles Rg Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sr Wb": "Shapesanity Stitched Painted", + "Singles Rg Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sr Wg": "Shapesanity Stitched Painted", + "Singles Rg Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sr Wr": "Shapesanity Stitched Painted", + "Singles Rg Rr Sr Wu": "Shapesanity Stitched Painted", + "Singles Rg Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Su Wb": "Shapesanity Stitched Painted", + "Singles Rg Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Su Wg": "Shapesanity Stitched Painted", + "Singles Rg Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Su Wr": "Shapesanity Stitched Painted", + "Singles Rg Rr Su Wu": "Shapesanity Stitched Painted", + "Singles Rg Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Rr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sb Wb": "Shapesanity Stitched Painted", + "Singles Rg Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sb Wg": "Shapesanity Stitched Painted", + "Singles Rg Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sb Wr": "Shapesanity Stitched Painted", + "Singles Rg Ru Sb Wu": "Shapesanity Stitched Painted", + "Singles Rg Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sg Wb": "Shapesanity Stitched Painted", + "Singles Rg Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sg Wg": "Shapesanity Stitched Painted", + "Singles Rg Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sg Wr": "Shapesanity Stitched Painted", + "Singles Rg Ru Sg Wu": "Shapesanity Stitched Painted", + "Singles Rg Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sr Wb": "Shapesanity Stitched Painted", + "Singles Rg Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sr Wg": "Shapesanity Stitched Painted", + "Singles Rg Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sr Wr": "Shapesanity Stitched Painted", + "Singles Rg Ru Sr Wu": "Shapesanity Stitched Painted", + "Singles Rg Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Su Wb": "Shapesanity Stitched Painted", + "Singles Rg Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Su Wg": "Shapesanity Stitched Painted", + "Singles Rg Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Su Wr": "Shapesanity Stitched Painted", + "Singles Rg Ru Su Wu": "Shapesanity Stitched Painted", + "Singles Rg Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ru Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rg Ru Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ru Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Rw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Rw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ry Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Ry Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Ry Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rg Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sg Sr": "Shapesanity Stitched Painted", + "Singles Rg Sb Sg Su": "Shapesanity Stitched Painted", + "Singles Rg Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sg Wb": "Shapesanity Stitched Painted", + "Singles Rg Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sg Wg": "Shapesanity Stitched Painted", + "Singles Rg Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sg Wr": "Shapesanity Stitched Painted", + "Singles Rg Sb Sg Wu": "Shapesanity Stitched Painted", + "Singles Rg Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sr Su": "Shapesanity Stitched Painted", + "Singles Rg Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sr Wb": "Shapesanity Stitched Painted", + "Singles Rg Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sr Wg": "Shapesanity Stitched Painted", + "Singles Rg Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sr Wr": "Shapesanity Stitched Painted", + "Singles Rg Sb Sr Wu": "Shapesanity Stitched Painted", + "Singles Rg Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Su Wb": "Shapesanity Stitched Painted", + "Singles Rg Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sb Su Wg": "Shapesanity Stitched Painted", + "Singles Rg Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Su Wr": "Shapesanity Stitched Painted", + "Singles Rg Sb Su Wu": "Shapesanity Stitched Painted", + "Singles Rg Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wb Wg": "Shapesanity Stitched Painted", + "Singles Rg Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wb Wr": "Shapesanity Stitched Painted", + "Singles Rg Sb Wb Wu": "Shapesanity Stitched Painted", + "Singles Rg Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wg Wr": "Shapesanity Stitched Painted", + "Singles Rg Sb Wg Wu": "Shapesanity Stitched Painted", + "Singles Rg Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wr Wu": "Shapesanity Stitched Painted", + "Singles Rg Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sr Su": "Shapesanity Stitched Painted", + "Singles Rg Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sr Wb": "Shapesanity Stitched Painted", + "Singles Rg Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sr Wg": "Shapesanity Stitched Painted", + "Singles Rg Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sr Wr": "Shapesanity Stitched Painted", + "Singles Rg Sg Sr Wu": "Shapesanity Stitched Painted", + "Singles Rg Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Su Wb": "Shapesanity Stitched Painted", + "Singles Rg Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sg Su Wg": "Shapesanity Stitched Painted", + "Singles Rg Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sg Su Wr": "Shapesanity Stitched Painted", + "Singles Rg Sg Su Wu": "Shapesanity Stitched Painted", + "Singles Rg Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wb Wg": "Shapesanity Stitched Painted", + "Singles Rg Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wb Wr": "Shapesanity Stitched Painted", + "Singles Rg Sg Wb Wu": "Shapesanity Stitched Painted", + "Singles Rg Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wg Wr": "Shapesanity Stitched Painted", + "Singles Rg Sg Wg Wu": "Shapesanity Stitched Painted", + "Singles Rg Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wr Wu": "Shapesanity Stitched Painted", + "Singles Rg Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Rg Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Rg Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Rg Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Rg Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Rg Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wb Wg": "Shapesanity Stitched Painted", + "Singles Rg Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wb Wr": "Shapesanity Stitched Painted", + "Singles Rg Sr Wb Wu": "Shapesanity Stitched Painted", + "Singles Rg Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wg Wr": "Shapesanity Stitched Painted", + "Singles Rg Sr Wg Wu": "Shapesanity Stitched Painted", + "Singles Rg Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wr Wu": "Shapesanity Stitched Painted", + "Singles Rg Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rg Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rg Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rg Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rg Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rg Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rg Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rg Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rg Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rg Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Su Wb Wg": "Shapesanity Stitched Painted", + "Singles Rg Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Su Wb Wr": "Shapesanity Stitched Painted", + "Singles Rg Su Wb Wu": "Shapesanity Stitched Painted", + "Singles Rg Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Su Wg Wr": "Shapesanity Stitched Painted", + "Singles Rg Su Wg Wu": "Shapesanity Stitched Painted", + "Singles Rg Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Su Wr Wu": "Shapesanity Stitched Painted", + "Singles Rg Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rg Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Rg Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Rg Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Rg Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Rg Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rg Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rg Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rg Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Sb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Sc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Sg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Sp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Sr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Su": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Sw": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Sy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ru Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Su": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Su": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Su Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Su Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Su Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Su Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Su Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Su Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Su Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Su Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ru Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ru Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Rw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Rw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ry Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Ry Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Ry Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rp Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Su": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Su": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Su": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rp Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rp Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rp Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rp Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rp Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rp Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rp Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rp Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rp Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Su Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Su Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Su Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Su Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Su Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Su Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rp Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rp Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rp Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rp Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Sb": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Sc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Sg": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Sp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Sr": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Su": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Sw": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Sy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Rw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Su": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sb Sg": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sb Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Sb Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sb Wb": "Shapesanity Stitched Painted", + "Singles Rr Ru Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sb Wg": "Shapesanity Stitched Painted", + "Singles Rr Ru Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sb Wr": "Shapesanity Stitched Painted", + "Singles Rr Ru Sb Wu": "Shapesanity Stitched Painted", + "Singles Rr Ru Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sg Sr": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Sg Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sg Wb": "Shapesanity Stitched Painted", + "Singles Rr Ru Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sg Wg": "Shapesanity Stitched Painted", + "Singles Rr Ru Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sg Wr": "Shapesanity Stitched Painted", + "Singles Rr Ru Sg Wu": "Shapesanity Stitched Painted", + "Singles Rr Ru Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sr Su": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sr Wb": "Shapesanity Stitched Painted", + "Singles Rr Ru Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sr Wg": "Shapesanity Stitched Painted", + "Singles Rr Ru Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sr Wr": "Shapesanity Stitched Painted", + "Singles Rr Ru Sr Wu": "Shapesanity Stitched Painted", + "Singles Rr Ru Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Su Wb": "Shapesanity Stitched Painted", + "Singles Rr Ru Su Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Su Wg": "Shapesanity Stitched Painted", + "Singles Rr Ru Su Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Su Wr": "Shapesanity Stitched Painted", + "Singles Rr Ru Su Wu": "Shapesanity Stitched Painted", + "Singles Rr Ru Su Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Su Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ru Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ru Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Rr Ru Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ru Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Rr Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Rr Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Rr Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Rw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Rw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ry Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Ry Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Ry Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rr Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sg Sr": "Shapesanity Stitched Painted", + "Singles Rr Sb Sg Su": "Shapesanity Stitched Painted", + "Singles Rr Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sg Wb": "Shapesanity Stitched Painted", + "Singles Rr Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sg Wg": "Shapesanity Stitched Painted", + "Singles Rr Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sg Wr": "Shapesanity Stitched Painted", + "Singles Rr Sb Sg Wu": "Shapesanity Stitched Painted", + "Singles Rr Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sr Su": "Shapesanity Stitched Painted", + "Singles Rr Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sr Wb": "Shapesanity Stitched Painted", + "Singles Rr Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sr Wg": "Shapesanity Stitched Painted", + "Singles Rr Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sr Wr": "Shapesanity Stitched Painted", + "Singles Rr Sb Sr Wu": "Shapesanity Stitched Painted", + "Singles Rr Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Su Wb": "Shapesanity Stitched Painted", + "Singles Rr Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sb Su Wg": "Shapesanity Stitched Painted", + "Singles Rr Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Su Wr": "Shapesanity Stitched Painted", + "Singles Rr Sb Su Wu": "Shapesanity Stitched Painted", + "Singles Rr Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wb Wg": "Shapesanity Stitched Painted", + "Singles Rr Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wb Wr": "Shapesanity Stitched Painted", + "Singles Rr Sb Wb Wu": "Shapesanity Stitched Painted", + "Singles Rr Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wg Wr": "Shapesanity Stitched Painted", + "Singles Rr Sb Wg Wu": "Shapesanity Stitched Painted", + "Singles Rr Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wr Wu": "Shapesanity Stitched Painted", + "Singles Rr Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sr Su": "Shapesanity Stitched Painted", + "Singles Rr Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sr Wb": "Shapesanity Stitched Painted", + "Singles Rr Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sr Wg": "Shapesanity Stitched Painted", + "Singles Rr Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sr Wr": "Shapesanity Stitched Painted", + "Singles Rr Sg Sr Wu": "Shapesanity Stitched Painted", + "Singles Rr Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Su Wb": "Shapesanity Stitched Painted", + "Singles Rr Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sg Su Wg": "Shapesanity Stitched Painted", + "Singles Rr Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sg Su Wr": "Shapesanity Stitched Painted", + "Singles Rr Sg Su Wu": "Shapesanity Stitched Painted", + "Singles Rr Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wb Wg": "Shapesanity Stitched Painted", + "Singles Rr Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wb Wr": "Shapesanity Stitched Painted", + "Singles Rr Sg Wb Wu": "Shapesanity Stitched Painted", + "Singles Rr Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wg Wr": "Shapesanity Stitched Painted", + "Singles Rr Sg Wg Wu": "Shapesanity Stitched Painted", + "Singles Rr Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wr Wu": "Shapesanity Stitched Painted", + "Singles Rr Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Rr Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Rr Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Rr Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Rr Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Rr Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wb Wg": "Shapesanity Stitched Painted", + "Singles Rr Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wb Wr": "Shapesanity Stitched Painted", + "Singles Rr Sr Wb Wu": "Shapesanity Stitched Painted", + "Singles Rr Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wg Wr": "Shapesanity Stitched Painted", + "Singles Rr Sr Wg Wu": "Shapesanity Stitched Painted", + "Singles Rr Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wr Wu": "Shapesanity Stitched Painted", + "Singles Rr Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rr Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rr Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rr Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rr Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rr Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rr Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rr Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rr Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rr Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Su Wb Wg": "Shapesanity Stitched Painted", + "Singles Rr Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Su Wb Wr": "Shapesanity Stitched Painted", + "Singles Rr Su Wb Wu": "Shapesanity Stitched Painted", + "Singles Rr Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Su Wg Wr": "Shapesanity Stitched Painted", + "Singles Rr Su Wg Wu": "Shapesanity Stitched Painted", + "Singles Rr Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Su Wr Wu": "Shapesanity Stitched Painted", + "Singles Rr Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rr Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Rr Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Rr Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Rr Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Rr Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rr Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rr Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rr Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Sb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Sc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Sg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Sp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Sr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Su": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Sw": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Sy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Wb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Wc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Wg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Wp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Wr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Wu": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Ww": "Shapesanity Stitched Mixed", + "Singles Ru Rw Ry Wy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sb Wb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sb Wg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sb Wr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sb Wu": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sc Wb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sc Wc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sg Wb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sg Wc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sg Wg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sg Wr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sg Wu": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sp Wb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sp Wc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sp Wg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sp Wp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sr Wb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sr Wg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sr Wr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sr Wu": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Su Wb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Su Wc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Su Wg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Su Wp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Su Wr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Su Wu": "Shapesanity Stitched Mixed", + "Singles Ru Rw Su Ww": "Shapesanity Stitched Mixed", + "Singles Ru Rw Su Wy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ru Rw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ru Rw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Rw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Ry Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Ru Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Ru Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Ru Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Ru Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Ru Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Ru Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Ru Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ru Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ru Ry Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Ry Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Ru Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sg Sr": "Shapesanity Stitched Painted", + "Singles Ru Sb Sg Su": "Shapesanity Stitched Painted", + "Singles Ru Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sg Wb": "Shapesanity Stitched Painted", + "Singles Ru Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sg Wg": "Shapesanity Stitched Painted", + "Singles Ru Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sg Wr": "Shapesanity Stitched Painted", + "Singles Ru Sb Sg Wu": "Shapesanity Stitched Painted", + "Singles Ru Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sr Su": "Shapesanity Stitched Painted", + "Singles Ru Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sr Wb": "Shapesanity Stitched Painted", + "Singles Ru Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sr Wg": "Shapesanity Stitched Painted", + "Singles Ru Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sr Wr": "Shapesanity Stitched Painted", + "Singles Ru Sb Sr Wu": "Shapesanity Stitched Painted", + "Singles Ru Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Su Wb": "Shapesanity Stitched Painted", + "Singles Ru Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sb Su Wg": "Shapesanity Stitched Painted", + "Singles Ru Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Su Wr": "Shapesanity Stitched Painted", + "Singles Ru Sb Su Wu": "Shapesanity Stitched Painted", + "Singles Ru Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wb Wg": "Shapesanity Stitched Painted", + "Singles Ru Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wb Wr": "Shapesanity Stitched Painted", + "Singles Ru Sb Wb Wu": "Shapesanity Stitched Painted", + "Singles Ru Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wg Wr": "Shapesanity Stitched Painted", + "Singles Ru Sb Wg Wu": "Shapesanity Stitched Painted", + "Singles Ru Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wr Wu": "Shapesanity Stitched Painted", + "Singles Ru Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sr Su": "Shapesanity Stitched Painted", + "Singles Ru Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sr Wb": "Shapesanity Stitched Painted", + "Singles Ru Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sr Wg": "Shapesanity Stitched Painted", + "Singles Ru Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sr Wr": "Shapesanity Stitched Painted", + "Singles Ru Sg Sr Wu": "Shapesanity Stitched Painted", + "Singles Ru Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Su Wb": "Shapesanity Stitched Painted", + "Singles Ru Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sg Su Wg": "Shapesanity Stitched Painted", + "Singles Ru Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sg Su Wr": "Shapesanity Stitched Painted", + "Singles Ru Sg Su Wu": "Shapesanity Stitched Painted", + "Singles Ru Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wb Wg": "Shapesanity Stitched Painted", + "Singles Ru Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wb Wr": "Shapesanity Stitched Painted", + "Singles Ru Sg Wb Wu": "Shapesanity Stitched Painted", + "Singles Ru Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wg Wr": "Shapesanity Stitched Painted", + "Singles Ru Sg Wg Wu": "Shapesanity Stitched Painted", + "Singles Ru Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wr Wu": "Shapesanity Stitched Painted", + "Singles Ru Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Ru Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Ru Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Ru Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Ru Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Ru Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wb Wg": "Shapesanity Stitched Painted", + "Singles Ru Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wb Wr": "Shapesanity Stitched Painted", + "Singles Ru Sr Wb Wu": "Shapesanity Stitched Painted", + "Singles Ru Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wg Wr": "Shapesanity Stitched Painted", + "Singles Ru Sr Wg Wu": "Shapesanity Stitched Painted", + "Singles Ru Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wr Wu": "Shapesanity Stitched Painted", + "Singles Ru Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ru Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ru Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ru Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ru Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ru Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ru Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ru Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ru Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ru Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ru Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ru Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ru Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ru Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ru Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ru Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ru Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ru Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Su Wb Wg": "Shapesanity Stitched Painted", + "Singles Ru Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Su Wb Wr": "Shapesanity Stitched Painted", + "Singles Ru Su Wb Wu": "Shapesanity Stitched Painted", + "Singles Ru Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Su Wg Wr": "Shapesanity Stitched Painted", + "Singles Ru Su Wg Wu": "Shapesanity Stitched Painted", + "Singles Ru Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Su Wr Wu": "Shapesanity Stitched Painted", + "Singles Ru Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ru Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Ru Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Ru Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Ru Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Ru Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ru Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ru Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ru Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sb Sc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sb Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sb Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sb Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sb Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sb Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sb Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sb Wb": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sc Sg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sc Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sc Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sc Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sc Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sc Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sg Sp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sg Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sg Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sg Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sg Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sp Sr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sp Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sp Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sp Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sr Su": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sr Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sr Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Su Sw": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Su Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Su Wb": "Shapesanity Stitched Mixed", + "Singles Rw Ry Su Wc": "Shapesanity Stitched Mixed", + "Singles Rw Ry Su Wg": "Shapesanity Stitched Mixed", + "Singles Rw Ry Su Wp": "Shapesanity Stitched Mixed", + "Singles Rw Ry Su Wr": "Shapesanity Stitched Mixed", + "Singles Rw Ry Su Wu": "Shapesanity Stitched Mixed", + "Singles Rw Ry Su Ww": "Shapesanity Stitched Mixed", + "Singles Rw Ry Su Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sw Sy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rw Ry Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rw Ry Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Ry Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Rw Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Su": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Su": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Su": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Rw Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Rw Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Rw Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Rw Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Rw Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Rw Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Rw Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Rw Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Rw Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rw Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rw Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rw Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rw Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rw Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rw Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rw Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rw Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Su Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Su Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Su Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Su Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Su Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Su Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Rw Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Rw Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Rw Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Rw Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Sg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Sp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Sr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Su": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Sp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Sr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Su": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Sr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Su": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Su": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Su Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Sp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Sr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Su": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Sr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Su": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Su": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Sr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Su": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Su": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Su": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su Sw": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Su Sw Sy": "Shapesanity Stitched Mixed", + "Singles Ry Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Ry Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Ry Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Ry Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Ry Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Ry Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Ry Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Ry Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Ry Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ry Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ry Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ry Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ry Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ry Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ry Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ry Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ry Su Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ry Su Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ry Su Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ry Su Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ry Su Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ry Su Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ry Su Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ry Su Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Su Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Su Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Su Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Su Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Su Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Su Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Su Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Su Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Su Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Su Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Su Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Su Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Su Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Su Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Su Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Su Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Su Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Su Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Su Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Su Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Ry Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sw Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sw Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wb Wc": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wb Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wb Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wb Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wb Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wb Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wb Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Sy Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Sy Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Ry Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Ry Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Ry Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sg Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sg Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sg Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sg Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sg Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sg Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sg Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sg Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sp Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sp Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sp Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sp Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sp Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sp Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sp Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sp Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sr Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sr Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sr Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sr Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sr Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sr Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sr Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sr Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sc Su Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sc Su Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sc Su Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sc Su Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sc Su Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sc Su Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sc Su Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sc Su Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sc Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sc Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sc Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sr Wb": "Shapesanity Stitched Painted", + "Singles Sb Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sr Wg": "Shapesanity Stitched Painted", + "Singles Sb Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sr Wr": "Shapesanity Stitched Painted", + "Singles Sb Sg Sr Wu": "Shapesanity Stitched Painted", + "Singles Sb Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sg Su Wb": "Shapesanity Stitched Painted", + "Singles Sb Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sg Su Wg": "Shapesanity Stitched Painted", + "Singles Sb Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sg Su Wr": "Shapesanity Stitched Painted", + "Singles Sb Sg Su Wu": "Shapesanity Stitched Painted", + "Singles Sb Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sg Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sg Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sg Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sg Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sg Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sg Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sg Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sg Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Sb Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Sb Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Sb Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Sb Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sr Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sr Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Sr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sb Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sb Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sb Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sb Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sb Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sb Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sb Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sb Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sb Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sb Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sb Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sb Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sb Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sb Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sb Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sb Su Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Su Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Su Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Su Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Su Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Su Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sb Su Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Su Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sb Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sb Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sb Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sb Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sb Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sb Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sb Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sb Sw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Sy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sb Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Sb Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Sb Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Sb Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Sb Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sb Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sb Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sb Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sp Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sp Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sp Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sp Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sp Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sp Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sp Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sp Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sr Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sr Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sr Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sr Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sr Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sr Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sr Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sr Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sg Su Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sg Su Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sg Su Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sg Su Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sg Su Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sg Su Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sg Su Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sg Su Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sg Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sg Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sg Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Su Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sr Su Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sr Su Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sr Su Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sc Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sc Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sc Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sc Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sc Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sc Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sc Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sc Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sc Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sc Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sc Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sc Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sc Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sc Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sc Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sc Su Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Su Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sc Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sc Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sc Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sc Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sc Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sc Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sc Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sc Sw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Sy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sc Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sc Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sc Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sc Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sr Wb": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sr Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sr Wg": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sr Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sr Wr": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sr Wu": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sr Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sr Wy": "Shapesanity Stitched Mixed", + "Singles Sg Sp Su Wb": "Shapesanity Stitched Mixed", + "Singles Sg Sp Su Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sp Su Wg": "Shapesanity Stitched Mixed", + "Singles Sg Sp Su Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sp Su Wr": "Shapesanity Stitched Mixed", + "Singles Sg Sp Su Wu": "Shapesanity Stitched Mixed", + "Singles Sg Sp Su Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sp Su Wy": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sp Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sg Sp Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sp Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Su Wb": "Shapesanity Stitched Painted", + "Singles Sg Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sr Su Wg": "Shapesanity Stitched Painted", + "Singles Sg Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sr Su Wr": "Shapesanity Stitched Painted", + "Singles Sg Sr Su Wu": "Shapesanity Stitched Painted", + "Singles Sg Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sg Sr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Sr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Sr Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Sr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Sr Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Sr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Sr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sg Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sg Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sg Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sg Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sg Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sg Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sg Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sg Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sg Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sg Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sg Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sg Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sg Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sg Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sg Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sg Su Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Su Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Su Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Su Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Su Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Su Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sg Su Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Su Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sg Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sg Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sg Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sg Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sg Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sg Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sg Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sg Sw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Sy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sg Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Sg Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Sg Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Sg Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Sg Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sg Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sg Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sg Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sp Sr Su Wb": "Shapesanity Stitched Mixed", + "Singles Sp Sr Su Wc": "Shapesanity Stitched Mixed", + "Singles Sp Sr Su Wg": "Shapesanity Stitched Mixed", + "Singles Sp Sr Su Wp": "Shapesanity Stitched Mixed", + "Singles Sp Sr Su Wr": "Shapesanity Stitched Mixed", + "Singles Sp Sr Su Wu": "Shapesanity Stitched Mixed", + "Singles Sp Sr Su Ww": "Shapesanity Stitched Mixed", + "Singles Sp Sr Su Wy": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sp Sr Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sp Sr Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sr Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sp Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sp Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sp Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sp Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sp Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sp Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sp Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sp Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sp Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sp Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sp Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sp Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sp Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sp Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sp Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sp Su Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Su Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sp Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sp Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sp Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sp Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sp Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sp Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sp Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sp Sw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Sy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sp Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sp Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sp Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sp Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sr Su Sw Wb": "Shapesanity Stitched Mixed", + "Singles Sr Su Sw Wc": "Shapesanity Stitched Mixed", + "Singles Sr Su Sw Wg": "Shapesanity Stitched Mixed", + "Singles Sr Su Sw Wp": "Shapesanity Stitched Mixed", + "Singles Sr Su Sw Wr": "Shapesanity Stitched Mixed", + "Singles Sr Su Sw Wu": "Shapesanity Stitched Mixed", + "Singles Sr Su Sw Ww": "Shapesanity Stitched Mixed", + "Singles Sr Su Sw Wy": "Shapesanity Stitched Mixed", + "Singles Sr Su Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sr Su Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sr Su Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sr Su Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sr Su Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sr Su Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sr Su Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sr Su Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sr Su Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wb Wg": "Shapesanity Colorful Half-Half Painted", + "Singles Sr Su Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wb Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sr Su Wb Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sr Su Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wg Wr": "Shapesanity Colorful Half-Half Painted", + "Singles Sr Su Wg Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sr Su Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wr Wu": "Shapesanity Colorful Half-Half Painted", + "Singles Sr Su Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Su Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Sr Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Sr Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Sr Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Sr Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Sr Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Sr Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Sr Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Sr Sw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Sy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sr Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Sr Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Sr Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Sr Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Sr Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sr Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sr Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sr Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Su Sw Sy Wb": "Shapesanity Stitched Mixed", + "Singles Su Sw Sy Wc": "Shapesanity Stitched Mixed", + "Singles Su Sw Sy Wg": "Shapesanity Stitched Mixed", + "Singles Su Sw Sy Wp": "Shapesanity Stitched Mixed", + "Singles Su Sw Sy Wr": "Shapesanity Stitched Mixed", + "Singles Su Sw Sy Wu": "Shapesanity Stitched Mixed", + "Singles Su Sw Sy Ww": "Shapesanity Stitched Mixed", + "Singles Su Sw Sy Wy": "Shapesanity Stitched Mixed", + "Singles Su Sw Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sw Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Sy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Su Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Su Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Su Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Su Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Su Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Su Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Su Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Su Wb Wg Wr": "Shapesanity Stitched Painted", + "Singles Su Wb Wg Wu": "Shapesanity Stitched Painted", + "Singles Su Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Su Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Su Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Su Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Su Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Su Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Su Wb Wr Wu": "Shapesanity Stitched Painted", + "Singles Su Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Su Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Su Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Su Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Su Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Su Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Su Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Su Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Su Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Su Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Su Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Su Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Su Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Su Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Su Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Su Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Su Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Su Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Su Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Su Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Su Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Su Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Su Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Su Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Su Wg Wr Wu": "Shapesanity Stitched Painted", + "Singles Su Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Su Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Su Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Su Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Su Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Su Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Su Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Su Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Su Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Su Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Su Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Su Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Su Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Su Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Su Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sw Sy Wb Wc": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wb Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wb Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wb Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wb Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wb Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wb Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wc Wg": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wc Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wc Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wc Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wc Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wc Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wg Wp": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wg Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wg Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wg Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wg Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wp Wr": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wp Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wp Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wp Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wr Wu": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wr Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wr Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wu Ww": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Wu Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Sy Ww Wy": "Shapesanity Colorful Half-Half Mixed", + "Singles Sw Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sw Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sw Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sw Wu Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wc Wg": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wc Wp": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wc Wr": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wc Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wc Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wc Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wb Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wb Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wg Wp": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wg Wr": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wg Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wg Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wg Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wc Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wc Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wp Wr": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wp Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wp Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wp Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wg Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wg Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wp Wr Wu": "Shapesanity Stitched Mixed", + "Singles Sy Wp Wr Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wp Wr Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wp Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wp Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wp Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wr Wu Ww": "Shapesanity Stitched Mixed", + "Singles Sy Wr Wu Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wr Ww Wy": "Shapesanity Stitched Mixed", + "Singles Sy Wu Ww Wy": "Shapesanity Stitched Mixed", +} diff --git a/worlds/shapez/data/strings.py b/worlds/shapez/data/strings.py new file mode 100644 index 000000000000..261ca5317e14 --- /dev/null +++ b/worlds/shapez/data/strings.py @@ -0,0 +1,337 @@ + +class OTHER: + game_name = "shapez" + + +class SLOTDATA: + goal = "goal" + maxlevel = "maxlevel" + finaltier = "finaltier" + req_shapes_mult = "required_shapes_multiplier" + allow_float_layers = "allow_floating_layers" + rand_level_req = "randomize_level_requirements" + rand_upgrade_req = "randomize_upgrade_requirements" + rand_level_logic = "randomize_level_logic" + rand_upgrade_logic = "randomize_upgrade_logic" + throughput_levels_ratio = "throughput_levels_ratio" + comp_growth_gradient = "complexity_growth_gradient" + same_late = "same_late_upgrade_requirements" + toolbar_shuffling = "toolbar_shuffling" + seed = "seed" + shapesanity = "shapesanity" + + @staticmethod + def level_building(number: int) -> str: + return f"Level building {number}" + + @staticmethod + def upgrade_building(number: int) -> str: + return f"Upgrade building {number}" + + @staticmethod + def phase_length(number: int) -> str: + return f"Phase {number} length" + + @staticmethod + def cat_buildings_amount(category: str) -> str: + return f"{category} category buildings amount" + + +class GOALS: + vanilla = "vanilla" + mam = "mam" + even_fasterer = "even_fasterer" + efficiency_iii = "efficiency_iii" + + +class CATEGORY: + belt = "Belt" + miner = "Miner" + processors = "Processors" + painting = "Painting" + random = "Random" + belt_low = "belt" + miner_low = "miner" + processors_low = "processors" + painting_low = "painting" + big = "Big" + small = "Small" + gigantic = "Gigantic" + rising = "Rising" + demonic = "Demonic" + + +class OPTIONS: + logic_vanilla = "vanilla" + logic_stretched = "stretched" + logic_quick = "quick" + logic_random_steps = "random_steps" + logic_hardcore = "hardcore" + logic_dopamine = "dopamine" + logic_dopamine_overflow = "dopamine_overflow" + logic_vanilla_like = "vanilla_like" + logic_linear = "linear" + logic_category = "category" + logic_category_random = "category_random" + logic_shuffled = "shuffled" + sphere_1 = "sphere_1" + buildings_3 = "3_buildings" + buildings_5 = "5_buildings" + + +class REGIONS: + menu = "Menu" + belt = "Shape transportation" + extract = "Shape extraction" + main = "Main" + levels_1 = "Levels with 1 building" + levels_2 = "Levels with 2 buildings" + levels_3 = "Levels with 3 buildings" + levels_4 = "Levels with 4 buildings" + levels_5 = "Levels with 5 buildings" + upgrades_1 = "Upgrades with 1 building" + upgrades_2 = "Upgrades with 2 buildings" + upgrades_3 = "Upgrades with 3 buildings" + upgrades_4 = "Upgrades with 4 buildings" + upgrades_5 = "Upgrades with 5 buildings" + paint_not_quad = "Achievements with (double) painter" + cut_not_quad = "Achievements with half cutter" + rotate_cw = "Achievements with clockwise rotator" + stack_shape = "Achievements with stacker" + store_shape = "Achievements with storage" + trash_shape = "Achievements with trash" + blueprint = "Achievements with blueprints" + wiring = "Achievements with wires" + mam = "Achievements needing a MAM" + any_building = "Achievements with any placeable building" + all_buildings = "Achievements with all main buildings" + all_buildings_x1_6_belt = "Achievements with x1.6 belt speed" + full = "Full" + half = "Half" + piece = "Piece" + stitched = "Stitched" + east_wind = "East Windmill" + half_half = "Half-Half" + col_east_wind = "Colorful East Windmill" + col_half_half = "Colorful Half-Half" + col_full = "Colorful Full" + col_half = "Colorful Half" + uncol = "Uncolored" + painted = "Painted" + mixed = "Mixed" + + @staticmethod + def sanity(processing: str, coloring: str): + return f"Shapesanity {processing} {coloring}" + + +class LOCATIONS: + my_eyes = "My eyes no longer hurt" + painter = "Painter" + cutter = "Cutter" + rotater = "Rotater" + wait_they_stack = "Wait, they stack?" + wires = "Wires" + storage = "Storage" + freedom = "Freedom" + the_logo = "The logo!" + to_the_moon = "To the moon" + its_piling_up = "It's piling up" + use_it_later = "I'll use it later" + efficiency_1 = "Efficiency 1" + preparing_to_launch = "Preparing to launch" + spacey = "SpaceY" + stack_overflow = "Stack overflow" + its_a_mess = "It's a mess" + faster = "Faster" + even_faster = "Even faster" + get_rid_of_them = "Get rid of them" + a_long_time = "It's been a long time" + addicted = "Addicted" + cant_stop = "Can't stop" + is_this_the_end = "Is this the end?" + getting_into_it = "Getting into it" + now_its_easy = "Now it's easy" + computer_guy = "Computer Guy" + speedrun_master = "Speedrun Master" + speedrun_novice = "Speedrun Novice" + not_idle_game = "Not an idle game" + efficiency_2 = "Efficiency 2" + branding_1 = "Branding specialist 1" + branding_2 = "Branding specialist 2" + king_of_inefficiency = "King of Inefficiency" + its_so_slow = "It's so slow" + mam = "MAM (Make Anything Machine)" + perfectionist = "Perfectionist" + next_dimension = "The next dimension" + oops = "Oops" + copy_pasta = "Copy-Pasta" + ive_seen_that_before = "I've seen that before ..." + memories = "Memories from the past" + i_need_trains = "I need trains" + a_bit_early = "A bit early?" + gps = "GPS" + goal = "Goal" + + @staticmethod + def level(number: int, additional: int = 0) -> str: + if not additional: + return f"Level {number}" + elif additional == 1: + return f"Level {number} Additional" + else: + return f"Level {number} Additional {additional}" + + @staticmethod + def upgrade(category: str, tier: str) -> str: + return f"{category} Upgrade Tier {tier}" + + @staticmethod + def shapesanity(number: int) -> str: + return f"Shapesanity {number}" + + +class ITEMS: + cutter = "Cutter" + cutter_quad = "Quad Cutter" + rotator = "Rotator" + rotator_ccw = "Rotator (CCW)" + rotator_180 = "Rotator (180°)" + stacker = "Stacker" + painter = "Painter" + painter_double = "Double Painter" + painter_quad = "Quad Painter" + color_mixer = "Color Mixer" + + belt = "Belt" + extractor = "Extractor" + extractor_chain = "Chaining Extractor" + balancer = "Balancer" + comp_merger = "Compact Merger" + comp_splitter = "Compact Splitter" + tunnel = "Tunnel" + tunnel_tier_ii = "Tunnel Tier II" + trash = "Trash" + + belt_reader = "Belt Reader" + storage = "Storage" + switch = "Switch" + item_filter = "Item Filter" + display = "Display" + wires = "Wires" + const_signal = "Constant Signal" + logic_gates = "Logic Gates" + virtual_proc = "Virtual Processing" + blueprints = "Blueprints" + + upgrade_big_belt = "Big Belt Upgrade" + upgrade_big_miner = "Big Miner Upgrade" + upgrade_big_proc = "Big Processors Upgrade" + upgrade_big_paint = "Big Painting Upgrade" + upgrade_small_belt = "Small Belt Upgrade" + upgrade_small_miner = "Small Miner Upgrade" + upgrade_small_proc = "Small Processors Upgrade" + upgrade_small_paint = "Small Painting Upgrade" + upgrade_gigantic_belt = "Gigantic Belt Upgrade" + upgrade_gigantic_miner = "Gigantic Miner Upgrade" + upgrade_gigantic_proc = "Gigantic Processors Upgrade" + upgrade_gigantic_paint = "Gigantic Painting Upgrade" + upgrade_rising_belt = "Rising Belt Upgrade" + upgrade_rising_miner = "Rising Miner Upgrade" + upgrade_rising_proc = "Rising Processors Upgrade" + upgrade_rising_paint = "Rising Painting Upgrade" + trap_upgrade_belt = "Belt Upgrade Trap" + trap_upgrade_miner = "Miner Upgrade Trap" + trap_upgrade_proc = "Processors Upgrade Trap" + trap_upgrade_paint = "Painting Upgrade Trap" + trap_upgrade_demonic_belt = "Demonic Belt Upgrade Trap" + trap_upgrade_demonic_miner = "Demonic Miner Upgrade Trap" + trap_upgrade_demonic_proc = "Demonic Processors Upgrade Trap" + trap_upgrade_demonic_paint = "Demonic Painting Upgrade Trap" + upgrade_big_random = "Big Random Upgrade" + upgrade_small_random = "Small Random Upgrade" + + @staticmethod + def upgrade(size: str, category: str) -> str: + return f"{size} {category} Upgrade" + + @staticmethod + def trap_upgrade(category: str, size: str = "") -> str: + return f"{size} {category} Upgrade Trap".strip() + + bundle_blueprint = "Blueprint Shapes Bundle" + bundle_level = "Level Shapes Bundle" + bundle_upgrade = "Upgrade Shapes Bundle" + + trap_locked = "Locked Building Trap" + trap_throttled = "Throttled Building Trap" + trap_malfunction = "Malfunctioning Trap" + trap_inflation = "Inflation Trap" + trap_draining_inv = "Inventory Draining Trap" + trap_draining_blueprint = "Blueprint Shapes Draining Trap" + trap_draining_level = "Level Shapes Draining Trap" + trap_draining_upgrade = "Upgrade Shapes Draining Trap" + trap_clear_belts = "Belts Clearing Trap" + + goal = "Goal" + + +class SHAPESANITY: + circle = "Circle" + square = "Square" + star = "Star" + windmill = "Windmill" + red = "Red" + blue = "Blue" + green = "Green" + yellow = "Yellow" + purple = "Purple" + cyan = "Cyan" + white = "White" + uncolored = "Uncolored" + adjacent_pos = "Adjacent" + cornered_pos = "Cornered" + + @staticmethod + def full(color: str, subshape: str): + return f"{color} {subshape}" + + @staticmethod + def half(color: str, subshape: str): + return f"Half {color} {subshape}" + + @staticmethod + def piece(color: str, subshape: str): + return f"{color} {subshape} Piece" + + @staticmethod + def cutout(color: str, subshape: str): + return f"Cut Out {color} {subshape}" + + @staticmethod + def cornered(color: str, subshape: str): + return f"Cornered {color} {subshape}" + + @staticmethod + def three_one(first: str, second: str): + return f"3-1 {first} {second}" + + @staticmethod + def halfhalf(combo: str): + return f"Half-Half {combo}" + + @staticmethod + def checkered(combo: str): + return f"Checkered {combo}" + + @staticmethod + def singles(combo: str, position: str = ""): + return f"{position} Singles {combo}".strip() + + @staticmethod + def two_one(first: str, second: str, position: str): + return f"{position} 2-1 {first} {second}" + + @staticmethod + def two_one_one(first: str, second: str, position: str): + return f"{position} 2-1-1 {first} {second}" diff --git a/worlds/shapez/docs/datapackage_settings_de.md b/worlds/shapez/docs/datapackage_settings_de.md new file mode 100644 index 000000000000..ae375f3e3c66 --- /dev/null +++ b/worlds/shapez/docs/datapackage_settings_de.md @@ -0,0 +1,35 @@ +# Anleitung zum Ändern der maximalen Anzahl an Locations in shapez + +## Wo finde ich die Einstellungen zum Erhöhen/Verringern der maximalen Anzahl an Locations? + +Die Maximalwerte von `goal_amount` und `shapesanity_amount` sind fest eingebaute Einstellungen, die das Datenpaket des +Spiels beeinflussen. Sie sind in einer Datei names `options.json` innerhalb der APWorld festgelegt. Durch das Ändern +dieser Werte erschaffst du eine custom APWorld, die nur auf deinem PC existiert. + +## Wie du die Datenpaket-Einstellungen änderst + +Diese Anleitung ist für erfahrene Nutzer und kann in nicht richtig funktionierender Software resultieren, wenn sie nicht +ordnungsgemäß befolgt wird. Anwendung auf eigene Gefahr. + +1. Navigiere zu `/lib/worlds`. +2. Benenne `shapez.apworld` zu `shapez.zip` um. +3. Öffne die Zip-Datei und navigiere zu `shapez/data/options.json`. +4. Ändere die Werte in dieser Datei nach Belieben und speichere die Datei. + - `max_shapesanity` kann nicht weniger als `4` sein, da dies die benötigte Mindestanzahl zum Verhindern von + FillErrors ist. + - `max_shapesanity` kann auch nicht mehr als `75800` sein, da dies die maximale Anzahl an möglichen Shapesanity-Namen + ist. Ansonsten könnte die Generierung der Multiworld fehlschlagen. + - `max_levels_and_upgrades` kann nicht weniger als `27` sein, da dies die Mindestanzahl für das `mam`-Ziel ist. +5. Schließe die Zip-Datei und benenne sie zurück zu `shapez.apworld`. + +## Warum muss ich das ganze selbst machen? + +Alle Spiele in Archipelago müssen eine Liste aller möglichen Locations **unabhängig der Spieler-Optionen** +bereitstellen. Diese Listen aller in einer Multiworld inkludierten Spiele werden in den Daten der Multiworld gespeichert +und an alle verbundenen Clients gesendet. Je mehr mögliche Locations, desto größer das Datenpaket. Und mit ~80000 +möglichen Locations hatte shapez zu einem gewissen Zeitpunkt ein (von der Datenmenge her) größeres Datenpaket als alle +supporteten Spiele zusammen. Um also diese Datenmenge zu reduzieren wurden die ausgeschriebenen +Shapesanity-Locations-Namen (`Shapesanity Uncolored Circle`, `Shapesanity Blue Rectangle`, ...) durch standardisierte +Namen (`Shapesanity 1`, `Shapesanity 2`, ...) ersetzt. Durch das Ändern dieser Maximalwerte, und damit das Erstellen +einer custom APWorld, kannst du die Anzahl der möglichen Locations erhöhen, wirst aber auch gleichzeitig das Datenpaket +vergrößern. diff --git a/worlds/shapez/docs/datapackage_settings_en.md b/worlds/shapez/docs/datapackage_settings_en.md new file mode 100644 index 000000000000..fd0ed1673d9e --- /dev/null +++ b/worlds/shapez/docs/datapackage_settings_en.md @@ -0,0 +1,33 @@ +# Guide to change maximum locations in shapez + +## Where do I find the settings to increase/decrease the amount of possible locations? + +The maximum values of the `goal_amount` and `shapesanity_amount` are hardcoded settings that affect the datapackage. +They are stored in a file called `options.json` inside the apworld. By changing them, you will create a custom apworld +on your local machine. + +## How to change datapackage options + +This tutorial is for advanced users and can result in the software not working properly, if not read carefully. +Proceed at your own risk. + +1. Go to `/lib/worlds`. +2. Rename `shapez.apworld` to `shapez.zip`. +3. Open the zip file and go to `shapez/data/options.json`. +4. Edit the values in this file to your desire and save the file. + - `max_shapesanity` cannot be lower than `4`, as this is the minimum amount to prevent FillErrors. + - `max_shapesanity` also cannot be higher than `75800`, as this is the maximum amount of possible shapesanity names. + Else the multiworld generation might fail. + - `max_levels_and_upgrades` cannot be lower than `27`, as this is the minimum amount for the `mam` goal to properly + work. +5. Close the zip and rename it back to `shapez.apworld`. + +## Why do I have to do this manually? + +For every game in Archipelago, there must be a list of all possible locations, **regardless of player options**. When +generating a multiworld, a list of all locations of all included games will be saved in the multiworld data and sent to +all clients. The higher the amount of possible locations, the bigger the datapackage. And having ~80000 possible +locations at one point made the datapackage for shapez bigger than all other supported games combined. So to reduce the +datapackage of shapez, the locations for shapesanity are named `Shapesanity 1`, `Shapesanity 2` etc. instead of their +actual names. By creating a custom apworld, you can increase the amount of possible locations, but you will also +increase the size of the datapackage at the same time. diff --git a/worlds/shapez/docs/de_shapez.md b/worlds/shapez/docs/de_shapez.md new file mode 100644 index 000000000000..5ef8f13f7963 --- /dev/null +++ b/worlds/shapez/docs/de_shapez.md @@ -0,0 +1,71 @@ +# shapez + +## Was für ein Spiel ist das? + +shapez ist ein Automatisierungsspiel, in dem du Formen aus zufällig generierten Vorkommen in einer endlosen Welt +extrahierst, zerschneidest, rotierst, stapelst, anmalst und schließlich zum Zentrum beförderst, um Level abzuschließen +und Upgrades zu kaufen. Das Tutorial beinhaltet 26 Level, in denen du (fast) immer ein neues Gebäude oder eine neue +Spielmechanik freischaltest. Danach folgen endlos weitere Level mit zufällig generierten Vorgaben. Um das Spiel bzw. +deine Gebäude schneller zu machen, kannst du bis zu 1000 Upgrades (pro Kategorie) kaufen. + +## Wo ist die Optionen-Seite? + +Die [Spieler-Optionen-Seite für dieses Spiel](../player-options) enthält alle Optionen zum Erstellen und exportieren +einer YAML-Datei. +Zusätzlich gibt es zu diesem Spiel "Datenpaket-Einstellungen", die du nach +[dieser Anleitung](/tutorial/shapez/datapackage_settings/de) einstellen kannst. + +## Inwiefern wird das Spiel randomisiert? + +Alle Belohnungen aus den Tutorial-Level (das Freischalten von Gebäuden und Spielmechaniken) und Verbesserungen durch +Upgrades werden dem Itempool der Multiworld hinzugefügt. Außerdem werden, wenn so in den Spieler-Optionen festgelegt, +die Bedingungen zum Abschließen eines Levels und zum Kaufen der Upgrades randomisiert. + +## Was ist das Ziel von shapez in Archipelago? + +Da das Spiel eigentlich kein konkretes Ziel (nach dem Tutorial) hat, kann man sich zwischen (momentan) 4 verschiedenen +Zielen entscheiden: +1. Vanilla: Schließe Level 26 ab (eigentlich das Ende des Tutorials). +2. MAM: Schließe ein bestimmtes Level nach Level 26 ab, das zuvor in den Spieler-Optionen festgelegt wurde. Es ist +empfohlen, eine Maschine zu bauen, die alles automatisch herstellt ("Make-Anything-Machine", kurz MAM). +3. Even Fasterer: Kaufe alle Upgrades bis zu einer in den Spieler-Optionen festgelegten Stufe (nach Stufe 8). +4. Efficiency III: Liefere 256 Blaupausen-Formen pro Sekunde ins Zentrum. + +## Welche Items können in den Welten anderer Spieler erscheinen? + +- Freischalten verschiedener Gebäude +- Blaupausen freischalten +- Große Upgrades (addiert 1 zum Geschwindigkeitsmultiplikator) +- Kleine Upgrades (addiert 0.1 zum Geschwindigkeitsmultiplikator) +- Andere ungewöhnliche Upgrades (optional) +- Verschiedene Bündel, die bestimmte Formen enthalten +- Fallen, die bestimmte Formen aus dem Zentrum dränieren (ja, das Wort gibt es) +- Fallen, die zufällige Gebäude oder andere Spielmechaniken betreffen + +## Was ist eine Location / ein Check? + +- Level (minimum 1-25, bis zu 499 je nach Spieler-Optionen, mit zusätzlichen Checks für Level 1 und 20) +- Upgrades (minimum Stufen II-VIII (2-8), bis zu D (500) je nach Spieler-Optionen) +- Bestimmte Formen mindestens einmal ins Zentrum liefern ("Shapesanity", bis zu 1000 zufällig gewählte Definitionen) +- Errungenschaften (bis zu 45) + +## Was passiert, wenn der Spieler ein Item erhält? + +Ein Pop-Up erscheint, das das/die erhaltene(n) Item(s) und eventuell weitere Informationen auflistet. + +## Was bedeuten die Namen dieser ganzen Shapesanity Dinger? + +Hier ist ein Spicker für die Englischarbeit (bloß nicht dem Lehrer zeigen): + +![image](https://raw.githubusercontent.com/BlastSlimey/Archipelago/refs/heads/main/worlds/shapez/docs/shapesanity_full.png) + +## Kann ich auch weitere Mods neben dem AP Client installieren? + +Zurzeit wird Kompatibilität mit anderen Mods nicht unterstützt, aber niemand kann dich davon abhalten, es trotzdem zu +versuchen. Mods, die das Gameplay verändern, werden wahrscheinlich nicht funktionieren, indem sie das Laden der +jeweiligen Mods verhindern oder das Spiel zum Abstürzen bringen, während einfache QoL-Mods vielleicht problemlos +funktionieren könnten. Wenn du es versuchst, dann also auf eigene Gefahr. + +## Hast du wirklich eine deutschsprachige Infoseite geschrieben, obwohl man sie aktuell nur über Umwege erreichen kann und du eigentlich an dem Praktikumsportfolio arbeiten solltest? + +Ja diff --git a/worlds/shapez/docs/en_shapez.md b/worlds/shapez/docs/en_shapez.md new file mode 100644 index 000000000000..4af398c5f17e --- /dev/null +++ b/worlds/shapez/docs/en_shapez.md @@ -0,0 +1,65 @@ +# shapez + +## What is this game? + +shapez is an automation game about cutting, rotating, stacking, and painting shapes, that you extract from randomly +generated patches on an infinite canvas, and sending them to the hub to complete levels. The "tutorial", where you +unlock a new building or game mechanic (almost) each level, lasts until level 26, where you unlock freeplay with +infinitely more levels, that require a new, randomly generated shape. Alongside the levels, you can unlock upgrades, +that make your buildings work faster. + +## Where is the options page? + +The [player options page for this game](../player-options) contains all the options you need to configure +and export a config file. +There are also some advanced "datapackage settings" that can be changed by following +[this guide](/tutorial/shapez/datapackage_settings/en). + +## What does randomization do to this game? + +Buildings and gameplay mechanics, that you normally unlock by completing a level, and upgrade improvements are put +into the item pool of the multiworld. Also, if enabled, the requirements for completing a level or buying an upgrade are +randomized. + +## What is the goal of shapez in Archipelago? + +As the game has no actual goal where the game ends, there are (currently) 4 different goals you can choose from in the +player options: +1. Vanilla: Complete level 26 (the end of the tutorial). +2. MAM: Complete a player-specified level after level 26. It's recommended to build a Make-Anything-Machine (MAM). +3. Even Fasterer: Upgrade everything to a player-specified tier after tier 8. +4. Efficiency III: Deliver 256 blueprint shapes per second to the hub. + +## Which items can be in another player's world? + +- Unlock different buildings +- Unlock blueprints +- Big upgrade improvements (adds 1 to the multiplier) +- Small upgrade improvements (adds .1 to the multiplier) +- Other unusual upgrade improvements (optional) +- Different shapes bundles +- Inventory draining traps +- Different traps afflicting random buildings and game mechanics + +## What is considered a location check? + +- Levels (minimum 1-25, up to 499 depending on player options, with additional checks for levels 1 and 20) +- Upgrades (minimum tiers II-VIII (2-8), up to D (500) depending on player options) +- Delivering certain shapes at least once to the hub ("shapesanity", up to 1000 from a 75800 names pool) +- Achievements (up to 45) + +## When the player receives an item, what happens? + +A pop-up will show, which item(s) were received, with additional information on some of them. + +## What do the names of all these shapesanity locations mean? + +Here's a cheat sheet: + +![image](https://raw.githubusercontent.com/BlastSlimey/Archipelago/refs/heads/main/worlds/shapez/docs/shapesanity_full.png) + +## Can I use other mods alongside the AP client? + +At the moment, compatibility with other mods is not supported, but not forbidden. Gameplay altering mods will most +likely crash the game or disable loading the afflicted mods, while QoL mods might work without problems. Try at your own +risk. diff --git a/worlds/shapez/docs/setup_de.md b/worlds/shapez/docs/setup_de.md new file mode 100644 index 000000000000..1b927f379056 --- /dev/null +++ b/worlds/shapez/docs/setup_de.md @@ -0,0 +1,62 @@ +# Setup-Anleitung für shapez: Archipelago + +## Schnelle Links + +- Info-Seite zum Spiel + * [English](/games/shapez/info/en) + * [Deutsch](/games/shapez/info/de) +- [Spieler-Optionen-Seite](/games/shapez/player-options) + +## Benötigte Software + +- Eine installierbare und aktuelle PC-Version von shapez ([Steam](https://store.steampowered.com/app/1318690/shapez/)). +- Die shapezipelago Mod von der [mod.io-Seite](https://mod.io/g/shapez/m/shapezipelago). + +## Optionale Software + +- Archipelago von der [Archipelago-Release-Seite](https://github.com/ArchipelagoMW/Archipelago/releases) + * (Für den Text-Client) + * (Alternativ kannst du auch die eingebaute Konsole (nur lesbar) nutzen, indem du beim Starten des Spiels den + `-dev`-Parameter verwendest) +- Universal Tracker (schau im `#future-game-design`-Thread für UT auf dem Discord-Server nach der aktuellen Anleitung) + +## Installation + +Da das Spiel einen eingebauten Mod-Loader hat, musst du nur die "shapezipelago@X.X.X.js"-Datei in den dafür vorgesehenen +Ordner kopieren. Wenn du nicht weißt, wo dieser ist, dann öffne das Spiel, drücke auf "MODS" und schließlich auf +"MODORDNER ÖFFNEN". + +Du solltest (egal ob vor oder nach der Installation) die Einstellungen des Spiels öffnen und `HINWEISE & TUTORIALS` im +Reiter `BENUTZEROBERFLÄCHE` ausschalten, da sie sonst den Upgrade-Shop verstecken wird, bis du ein paar Level +abgeschlossen hast. + +## Erstellen deiner YAML-Datei + +### Was ist eine YAML-Datei und wofür brauche ich die? + +Deine persönliche YAML-Datei beinhaltet eine Reihe von Optionen, die der Zufallsgenerator zum Erstellen von deinem +Spiel benötigt. Jeder Spieler einer Multiworld stellt seine eigene YAML-Datei zur Verfügung. Dadurch kann jeder Spieler +sein Spiel nach seinem eigenen Geschmack gestalten, während andere Spieler unabhängig davon ihre eigenen Optionen +wählen können! + +### Wo bekomme ich so eine YAML-Datei her? + +Du kannst auf der [shapez-Spieler-Optionen-Seite](/games/shapez/player-options) eine YAML-Datei generieren oder ein +Template herunterladen. + +## Einer MultiWorld beitreten + +1. Öffne das Spiel. +2. Gib im Hauptmenü den Slot-Namen, die Adresse, den Port und das Passwort (optional) in die dafür vorgesehene Box ein. +3. Drücke auf "Connect". + - Erneutes Drücken trennt die Verbindung zum Server. + - Ob du verbunden bist, steht direkt daneben. +4. Starte ein neues Spiel. + +Nachdem der Speicherstand erstellt wurde und du zum Hauptmenü zurückkehrst, wird das erneute Öffnen des Speicherstandes +erneut verbinden. + +### Der Port/Die Adresse der MultiWorld hat sich geändert, wie trete ich mit meinem existierenden Speicherstand bei? + +Wiederhole die Schritte 1-3 und öffne den existierenden Speicherstand. Dies wird außerdem die gespeicherten Login-Daten +überschreiben, sodass du dies nur einmal machen musst. \ No newline at end of file diff --git a/worlds/shapez/docs/setup_en.md b/worlds/shapez/docs/setup_en.md new file mode 100644 index 000000000000..4c91c16a0b5b --- /dev/null +++ b/worlds/shapez/docs/setup_en.md @@ -0,0 +1,58 @@ +# Setup Guide for shapez: Archipelago + +## Quick Links + +- Game Info Page + * [English](/games/shapez/info/en) + * [Deutsch](/games/shapez/info/de) +- [Player Options Page](/games/shapez/player-options) + +## Required Software + +- An installable, up-to-date PC version of shapez ([Steam](https://store.steampowered.com/app/1318690/shapez/)). +- The shapezipelago mod from the [mod.io page](https://mod.io/g/shapez/m/shapezipelago). + +## Optional Software + +- Archipelago from the [Archipelago Releases Page](https://github.com/ArchipelagoMW/Archipelago/releases) + * (Only for the TextClient) + * (If you want, you can use the built-in console as a read-only text client by launching the game + with the `-dev` parameter) +- Universal Tracker (check UT's `#future-game-design` thread in the discord server for instructions) + +## Installation + +As the game has a built-in mod loader, all you need to do is copy the `shapezipelago@X.X.X.js` mod file into the mods +folder. If you don't know where that is, open the game, click on `MODS`, and then `OPEN MODS FOLDER`. + +It is recommended to go into the settings of the game and disable `HINTS & TUTORIALS` in the `USER INTERFACE` tab, as +this setting will disable the upgrade shop until you complete a few levels. + +## Configuring your YAML file + +### What is a YAML file and why do I need one? + +Your YAML file contains a set of configuration options which provide the generator with information about how it should +generate your game. Each player of a multiworld will provide their own YAML file. This setup allows each player to enjoy +an experience customized for their taste, and different players in the same multiworld can all have different options. + +### Where do I get a YAML file? + +You can generate a yaml or download a template by visiting the +[shapez Player Options Page](/games/shapez/player-options) + +## Joining a MultiWorld Game + +1. Open the game. +2. In the main menu, type the slot name, address, port, and password (optional) into the input box. +3. Click "Connect". + - To disconnect, just press this button again. + - The status of your connection is shown right next to the button. +4. Create a new game. + +After creating the save file and returning to the main menu, opening the save file again will automatically reconnect. + +### The MultiWorld changed its port/address, how do I reconnect correctly with my existing save file? + +Repeat steps 1-3 and open the existing save file. This will also overwrite the saved connection details, so you will +only have to do this once. diff --git a/worlds/shapez/docs/shapesanity_full.png b/worlds/shapez/docs/shapesanity_full.png new file mode 100644 index 0000000000000000000000000000000000000000..494065d51454bded26be04c191e080028a17eef5 GIT binary patch literal 127240 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%0D8uo? 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∓OIY_C6szbNeM% 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 literal 0 HcmV?d00001 diff --git a/worlds/shapez/items.py b/worlds/shapez/items.py new file mode 100644 index 000000000000..aef4c03317ea --- /dev/null +++ b/worlds/shapez/items.py @@ -0,0 +1,279 @@ +from typing import Dict, Callable, Any, List + +from BaseClasses import Item, ItemClassification as IClass +from .options import ShapezOptions +from .data.strings import GOALS, ITEMS, OTHER + + +def is_mam_achievement_included(options: ShapezOptions) -> IClass: + return IClass.progression if options.include_achievements and (not options.goal == GOALS.vanilla) else IClass.useful + + +def is_achievements_included(options: ShapezOptions) -> IClass: + return IClass.progression if options.include_achievements else IClass.useful + + +def is_goal_efficiency_iii(options: ShapezOptions) -> IClass: + return IClass.progression if options.goal == GOALS.efficiency_iii else IClass.useful + + +def always_progression(options: ShapezOptions) -> IClass: + return IClass.progression + + +def always_useful(options: ShapezOptions) -> IClass: + return IClass.useful + + +def always_filler(options: ShapezOptions) -> IClass: + return IClass.filler + + +def always_trap(options: ShapezOptions) -> IClass: + return IClass.trap + + +# Routing buildings are not needed to complete the game, but building factories without balancers and tunnels +# would be unreasonably complicated and time-consuming. +# Some buildings are not needed to complete the game, but are "logically needed" for the "MAM" achievement. + +buildings_processing: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.cutter: always_progression, + ITEMS.cutter_quad: always_progression, + ITEMS.rotator: always_progression, + ITEMS.rotator_ccw: always_progression, + ITEMS.rotator_180: always_progression, + ITEMS.stacker: always_progression, + ITEMS.painter: always_progression, + ITEMS.painter_double: always_progression, + ITEMS.painter_quad: always_progression, + ITEMS.color_mixer: always_progression, +} + +buildings_routing: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.balancer: always_progression, + ITEMS.comp_merger: always_progression, + ITEMS.comp_splitter: always_progression, + ITEMS.tunnel: always_progression, + ITEMS.tunnel_tier_ii: is_mam_achievement_included, +} + +buildings_other: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.trash: always_progression, + ITEMS.extractor_chain: always_useful +} + +buildings_top_row: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.belt_reader: is_mam_achievement_included, + ITEMS.storage: is_achievements_included, + ITEMS.switch: always_progression, + ITEMS.item_filter: is_mam_achievement_included, + ITEMS.display: always_useful +} + +buildings_wires: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.wires: always_progression, + ITEMS.const_signal: always_progression, + ITEMS.logic_gates: is_mam_achievement_included, + ITEMS.virtual_proc: is_mam_achievement_included +} + +gameplay_unlocks: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.blueprints: is_achievements_included +} + +upgrades: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.upgrade_big_belt: always_progression, + ITEMS.upgrade_big_miner: always_useful, + ITEMS.upgrade_big_proc: always_useful, + ITEMS.upgrade_big_paint: always_useful, + ITEMS.upgrade_small_belt: always_filler, + ITEMS.upgrade_small_miner: always_filler, + ITEMS.upgrade_small_proc: always_filler, + ITEMS.upgrade_small_paint: always_filler +} + +whacky_upgrades: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.upgrade_gigantic_belt: always_progression, + ITEMS.upgrade_gigantic_miner: always_useful, + ITEMS.upgrade_gigantic_proc: always_useful, + ITEMS.upgrade_gigantic_paint: always_useful, + ITEMS.upgrade_rising_belt: always_progression, + ITEMS.upgrade_rising_miner: always_useful, + ITEMS.upgrade_rising_proc: always_useful, + ITEMS.upgrade_rising_paint: always_useful, + ITEMS.upgrade_big_random: always_useful, + ITEMS.upgrade_small_random: always_filler, +} + +whacky_upgrade_traps: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.trap_upgrade_belt: always_trap, + ITEMS.trap_upgrade_miner: always_trap, + ITEMS.trap_upgrade_proc: always_trap, + ITEMS.trap_upgrade_paint: always_trap, + ITEMS.trap_upgrade_demonic_belt: always_trap, + ITEMS.trap_upgrade_demonic_miner: always_trap, + ITEMS.trap_upgrade_demonic_proc: always_trap, + ITEMS.trap_upgrade_demonic_paint: always_trap, +} + +bundles: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.bundle_blueprint: always_filler, + ITEMS.bundle_level: always_filler, + ITEMS.bundle_upgrade: always_filler +} + +standard_traps: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.trap_locked: always_trap, + ITEMS.trap_throttled: always_trap, + ITEMS.trap_malfunction: always_trap, + ITEMS.trap_inflation: always_trap, + ITEMS.trap_clear_belts: always_trap, +} + +random_draining_trap: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.trap_draining_inv: always_trap +} + +split_draining_traps: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.trap_draining_blueprint: always_trap, + ITEMS.trap_draining_level: always_trap, + ITEMS.trap_draining_upgrade: always_trap +} + +belt_and_extractor: Dict[str, Callable[[ShapezOptions], IClass]] = { + ITEMS.belt: always_progression, + ITEMS.extractor: always_progression +} + +item_table: Dict[str, Callable[[ShapezOptions], IClass]] = { + **buildings_processing, + **buildings_routing, + **buildings_other, + **buildings_top_row, + **buildings_wires, + **gameplay_unlocks, + **upgrades, + **whacky_upgrades, + **whacky_upgrade_traps, + **bundles, + **standard_traps, + **random_draining_trap, + **split_draining_traps, + **belt_and_extractor +} + +big_upgrades = [ + ITEMS.upgrade_big_belt, + ITEMS.upgrade_big_miner, + ITEMS.upgrade_big_proc, + ITEMS.upgrade_big_paint +] + +small_upgrades = [ + ITEMS.upgrade_small_belt, + ITEMS.upgrade_small_miner, + ITEMS.upgrade_small_proc, + ITEMS.upgrade_small_paint +] + + +def filler(random: float, whacky_allowed: bool) -> str: + """Returns a random filler item.""" + bundles_list = [*bundles] + return random_choice_nested(random, [ + small_upgrades, + [ + bundles_list, + bundles_list, + [ + big_upgrades, + [*whacky_upgrades] if whacky_allowed else big_upgrades, + ], + ], + ]) + + +def trap(random: float, split_draining: bool, whacky_allowed: bool) -> str: + """Returns a random trap item.""" + pool = [ + *standard_traps, + ITEMS.trap_draining_inv if not split_draining else [*split_draining_traps], + ] + if whacky_allowed: + pool.append([*whacky_upgrade_traps]) + return random_choice_nested(random, pool) + + +def random_choice_nested(random: float, nested: List[Any]) -> Any: + """Helper function for getting a random element from a nested list.""" + current: Any = nested + while isinstance(current, List): + index_float = random*len(current) + current = current[int(index_float)] + random = index_float-int(index_float) + return current + + +item_descriptions = { # TODO replace keys with global strings and update with whacky upgrades + "Balancer": "A routing building, that can merge two belts into one, split a belt in two, " + + "or balance the items of two belts", + "Tunnel": "A routing building consisting of two parts, that allows for gaps in belts", + "Compact Merger": "A small routing building, that merges two belts into one", + "Tunnel Tier II": "A routing building consisting of two parts, that allows for even longer gaps in belts", + "Compact Splitter": "A small routing building, that splits a belt in two", + "Cutter": "A processing building, that cuts shapes vertically in two halves", + "Rotator": "A processing building, that rotates shapes 90 degrees clockwise", + "Painter": "A processing building, that paints shapes in a given color", + "Rotator (CCW)": "A processing building, that rotates shapes 90 degrees counter-clockwise", + "Color Mixer": "A processing building, that mixes two colors together to create a new one", + "Stacker": "A processing building, that combines two shapes with missing parts or puts one on top of the other", + "Quad Cutter": "A processing building, that cuts shapes in four quarter parts", + "Double Painter": "A processing building, that paints two shapes in a given color", + "Rotator (180°)": "A processing building, that rotates shapes 180 degrees", + "Quad Painter": "A processing building, that paint each quarter of a shape in another given color and requires " + + "wire inputs for each color to work", + "Trash": "A building, that destroys unused shapes", + "Chaining Extractor": "An upgrade to extractors, that can increase the output without balancers or mergers", + "Belt Reader": "A wired building, that shows the average amount of items passing through per second", + "Storage": "A building, that stores up to 5000 of a certain shape", + "Switch": "A building, that sends a constant boolean signal", + "Item Filter": "A wired building, that filters items based on wire input", + "Display": "A wired building, that displays a shape or color based on wire input", + "Wires": "The main building of the wires layer, that carries signals between other buildings", + "Constant Signal": "A building on the wires layer, that sends a constant shape, color, or boolean signal", + "Logic Gates": "Multiple buildings on the wires layer, that perform logical operations on wire signals", + "Virtual Processing": "Multiple buildings on the wires layer, that process wire signals like processor buildings", + "Blueprints": "A game mechanic, that allows copy-pasting multiple buildings at once", + "Big Belt Upgrade": "An upgrade, that adds 1 to the speed multiplier of belts, distributors, and tunnels", + "Big Miner Upgrade": "An upgrade, that adds 1 to the speed multiplier of extractors", + "Big Processors Upgrade": "An upgrade, that adds 1 to the speed multiplier of cutters, rotators, and stackers", + "Big Painting Upgrade": "An upgrade, that adds 1 to the speed multiplier of painters and color mixers", + "Small Belt Upgrade": "An upgrade, that adds 0.1 to the speed multiplier of belts, distributors, and tunnels", + "Small Miner Upgrade": "An upgrade, that adds 0.1 to the speed multiplier of extractors", + "Small Processors Upgrade": "An upgrade, that adds 0.1 to the speed multiplier of cutters, rotators, and stackers", + "Small Painting Upgrade": "An upgrade, that adds 0.1 to the speed multiplier of painters and color mixers", + "Blueprint Shapes Bundle": "A bundle with 1000 blueprint shapes, instantly delivered to the hub", + "Level Shapes Bundle": "A bundle with some shapes needed for the current level, " + + "instantly delivered to the hub", + "Upgrade Shapes Bundle": "A bundle with some shapes needed for a random upgrade, " + + "instantly delivered to the hub", + "Inventory Draining Trap": "Randomly drains either blueprint shapes, current level requirement shapes, " + + "or random upgrade requirement shapes, by half", + "Blueprint Shapes Draining Trap": "Drains the stored blueprint shapes by half", + "Level Shapes Draining Trap": "Drains the current level requirement shapes by half", + "Upgrade Shapes Draining Trap": "Drains a random upgrade requirement shape by half", + "Locked Building Trap": "Locks a random building from being placed for 15-60 seconds", + "Throttled Building Trap": "Halves the speed of a random building for 15-60 seconds", + "Malfunctioning Trap": "Makes a random building process items incorrectly for 15-60 seconds", + "Inflation Trap": "Permanently increases the required shapes multiplier by 1. " + "In other words: Permanently increases required shapes by 10% of the standard amount.", + "Belt": "One of the most important buildings in the game, that transports your shapes and colors from one " + + "place to another", + "Extractor": "One of the most important buildings in the game, that extracts shapes from those randomly " + + "generated patches" +} + + +class ShapezItem(Item): + game = OTHER.game_name diff --git a/worlds/shapez/locations.py b/worlds/shapez/locations.py new file mode 100644 index 000000000000..6d069afaa899 --- /dev/null +++ b/worlds/shapez/locations.py @@ -0,0 +1,546 @@ +from random import Random +from typing import List, Tuple, Dict, Optional, Callable + +from BaseClasses import Location, LocationProgressType, Region +from .data.strings import CATEGORY, LOCATIONS, REGIONS, OPTIONS, GOALS, OTHER, SHAPESANITY +from .options import max_shapesanity, max_levels_and_upgrades + +categories = [CATEGORY.belt, CATEGORY.miner, CATEGORY.processors, CATEGORY.painting] + +translate: List[Tuple[int, str]] = [ + (1000, "M"), + (900, "CM"), + (500, "D"), + (400, "CD"), + (100, "C"), + (90, "XC"), + (50, "L"), + (40, "XL"), + (10, "X"), + (9, "IX"), + (5, "V"), + (4, "IV"), + (1, "I") +] + + +def roman(num: int) -> str: + """Converts positive non-zero integers into roman numbers.""" + rom: str = "" + for key, val in translate: + while num >= key: + rom += val + num -= key + return rom + + +location_description = { # TODO change keys to global strings + "Level 1": "Levels are completed by delivering certain shapes in certain amounts to the hub. The required shape " + "and amount for the current level are always displayed on the hub.", + "Level 1 Additional": "In the vanilla game, levels 1 and 20 have unlock more than one building.", + "Level 20 Additional": "In the vanilla game, levels 1 and 20 have unlock more than one building.", + "Level 20 Additional 2": "In the vanilla game, levels 1 and 20 have unlock more than one building.", + "Level 26": "In the vanilla game, level 26 is the final level of the tutorial, unlocking freeplay.", + f"Level {max_levels_and_upgrades-1}": "This is the highest possible level that can contains an item, if your goal " + "is set to \"mam\"", + "Belt Upgrade Tier II": "Upgrades can be purchased by having certain shapes in certain amounts stored in your hub. " + "This is the first upgrade in the belt, balancers, and tunnel category.", + "Miner Upgrade Tier II": "Upgrades can be purchased by having certain shapes in certain amounts stored in your " + "hub. This is the first upgrade in the extractor category.", + "Processors Upgrade Tier II": "Upgrades can be purchased by having certain shapes in certain amounts stored in " + "your hub. This is the first upgrade in the cutter, rotators, and stacker category.", + "Painting Upgrade Tier II": "Upgrades can be purchased by having certain shapes in certain amounts stored in your " + "hub. This is the first upgrade in the painters and color mixer category.", + "Belt Upgrade Tier VIII": "This is the final upgrade in the belt, balancers, and tunnel category, if your goal is " + "**not** set to \"even_fasterer\".", + "Miner Upgrade Tier VIII": "This is the final upgrade in the extractor category, if your goal is **not** set to " + "\"even_fasterer\".", + "Processors Upgrade Tier VIII": "This is the final upgrade in the cutter, rotators, and stacker category, if your " + "goal is **not** set to \"even_fasterer\".", + "Painting Upgrade Tier VIII": "This is the final upgrade in the painters and color mixer category, if your goal is " + "**not** set to \"even_fasterer\".", + f"Belt Upgrade Tier {roman(max_levels_and_upgrades)}": "This is the highest possible upgrade in the belt, " + "balancers, and tunnel category, if your goal is set to " + "\"even_fasterer\".", + f"Miner Upgrade Tier {roman(max_levels_and_upgrades)}": "This is the highest possible upgrade in the extractor " + "category, if your goal is set to \"even_fasterer\".", + f"Processors Upgrade Tier {roman(max_levels_and_upgrades)}": "This is the highest possible upgrade in the cutter, " + "rotators, and stacker category, if your goal is set " + "to \"even_fasterer\".", + f"Painting Upgrade Tier {roman(max_levels_and_upgrades)}": "This is the highest possible upgrade in the painters " + "and color mixer category, if your goal is set to " + "\"even_fasterer\".", + "My eyes no longer hurt": "This is an achievement, that is unlocked by activating dark mode.", + "Painter": "This is an achievement, that is unlocked by painting a shape using the painter or double painter.", + "Cutter": "This is an achievement, that is unlocked by cutting a shape in half using the cutter.", + "Rotater": "This is an achievement, that is unlocked by rotating a shape clock wise.", + "Wait, they stack?": "This is an achievement, that is unlocked by stacking two shapes on top of each other.", + "Wires": "This is an achievement, that is unlocked by completing level 20.", + "Storage": "This is an achievement, that is unlocked by storing a shape in a storage.", + "Freedom": "This is an achievement, that is unlocked by completing level 20. It is only included if the goal is " + "**not** set to vanilla.", + "The logo!": "This is an achievement, that is unlocked by producing the logo of the game.", + "To the moon": "This is an achievement, that is unlocked by producing the rocket shape.", + "It's piling up": "This is an achievement, that is unlocked by having 100.000 blueprint shapes stored in the hub.", + "I'll use it later": "This is an achievement, that is unlocked by having one million blueprint shapes stored in " + "the hub.", + "Efficiency 1": "This is an achievement, that is unlocked by delivering 25 blueprint shapes per second to the hub.", + "Preparing to launch": "This is an achievement, that is unlocked by delivering 10 rocket shapes per second to the " + "hub.", + "SpaceY": "This is an achievement, that is unlocked by 20 rocket shapes per second to the hub.", + "Stack overflow": "This is an achievement, that is unlocked by stacking 4 layers on top of each other.", + "It's a mess": "This is an achievement, that is unlocked by having 100 different shapes stored in the hub.", + "Faster": "This is an achievement, that is unlocked by upgrading everything to at least tier V.", + "Even faster": "This is an achievement, that is unlocked by upgrading everything to at least tier VIII.", + "Get rid of them": "This is an achievement, that is unlocked by transporting 1000 shapes into a trash can.", + "It's been a long time": "This is an achievement, that is unlocked by playing your save file for 10 hours " + "(combined playtime).", + "Addicted": "This is an achievement, that is unlocked by playing your save file for 20 hours (combined playtime).", + "Can't stop": "This is an achievement, that is unlocked by reaching level 50.", + "Is this the end?": "This is an achievement, that is unlocked by reaching level 100.", + "Getting into it": "This is an achievement, that is unlocked by playing your save file for 1 hour (combined " + "playtime).", + "Now it's easy": "This is an achievement, that is unlocked by placing a blueprint.", + "Computer Guy": "This is an achievement, that is unlocked by placing 5000 wires.", + "Speedrun Master": "This is an achievement, that is unlocked by completing level 12 in under 30 Minutes. This " + "location is excluded by default, as it can become inaccessible in a save file after that time.", + "Speedrun Novice": "This is an achievement, that is unlocked by completing level 12 in under 60 Minutes. This " + "location is excluded by default, as it can become inaccessible in a save file after that time.", + "Not an idle game": "This is an achievement, that is unlocked by completing level 12 in under 120 Minutes. This " + "location is excluded by default, as it can become inaccessible in a save file after that time.", + "Efficiency 2": "This is an achievement, that is unlocked by delivering 50 blueprint shapes per second to the hub.", + "Branding specialist 1": "This is an achievement, that is unlocked by delivering 25 logo shapes per second to the " + "hub.", + "Branding specialist 2": "This is an achievement, that is unlocked by delivering 50 logo shapes per second to the " + "hub.", + "King of Inefficiency": "This is an achievement, that is unlocked by **not** placing a counter clock wise rotator " + "until level 14. This location is excluded by default, as it can become inaccessible in a " + "save file after placing that building.", + "It's so slow": "This is an achievement, that is unlocked by completing level 12 **without** buying any belt " + "upgrade. This location is excluded by default, as it can become inaccessible in a save file after " + "buying that upgrade.", + "MAM (Make Anything Machine)": "This is an achievement, that is unlocked by completing any level after level 26 " + "**without** modifying your factory. It is recommended to build a Make Anything " + "Machine.", + "Perfectionist": "This is an achievement, that is unlocked by destroying more than 1000 buildings at once.", + "The next dimension": "This is an achievement, that is unlocked by opening the wires layer.", + "Oops": "This is an achievement, that is unlocked by delivering a shape, that neither a level requirement nor an " + "upgrade requirement.", + "Copy-Pasta": "This is an achievement, that is unlocked by placing a blueprint with at least 1000 buildings.", + "I've seen that before ...": "This is an achievement, that is unlocked by producing RgRyRbRr.", + "Memories from the past": "This is an achievement, that is unlocked by producing WrRgWrRg:CwCrCwCr:SgSgSgSg.", + "I need trains": "This is an achievement, that is unlocked by placing a 500 tiles long belt.", + "A bit early?": "This is an achievement, that is unlocked by producing the logo shape before reaching level 18. " + "This location is excluded by default, as it can become inaccessible in a save file after reaching " + "that level.", + "GPS": "This is an achievement, that is unlocked by placing 15 or more map markers.", + "Shapesanity 1": "Shapesanity locations can be checked by delivering a described shape to the hub, without " + "requiring a certain roation, orientation, or ordering. Shapesanity 1 is always an uncolored " + "circle.", + "Shapesanity 2": "Shapesanity locations can be checked by delivering a described shape to the hub, without " + "requiring a certain roation, orientation, or ordering. Shapesanity 2 is always an uncolored " + "square.", + "Shapesanity 3": "Shapesanity locations can be checked by delivering a described shape to the hub, without " + "requiring a certain roation, orientation, or ordering. Shapesanity 3 is always an uncolored " + "star.", + "Shapesanity 4": "Shapesanity locations can be checked by delivering a described shape to the hub, without " + "requiring a certain roation, orientation, or ordering. Shapesanity 4 is always an uncolored " + "windmill.", +} + +shapesanity_simple: Dict[str, str] = {} +shapesanity_1_4: Dict[str, str] = {} +shapesanity_two_sided: Dict[str, str] = {} +shapesanity_three_parts: Dict[str, str] = {} +shapesanity_four_parts: Dict[str, str] = {} + +level_locations: List[str] = ([LOCATIONS.level(1, 1), LOCATIONS.level(20, 1), LOCATIONS.level(20, 2)] + + [LOCATIONS.level(x) for x in range(1, max_levels_and_upgrades)]) +upgrade_locations: List[str] = [LOCATIONS.upgrade(cat, roman(x)) + for cat in categories for x in range(2, max_levels_and_upgrades+1)] +achievement_locations: List[str] = [LOCATIONS.my_eyes, LOCATIONS.painter, LOCATIONS.cutter, LOCATIONS.rotater, + LOCATIONS.wait_they_stack, LOCATIONS.wires, LOCATIONS.storage, LOCATIONS.freedom, + LOCATIONS.the_logo, LOCATIONS.to_the_moon, LOCATIONS.its_piling_up, + LOCATIONS.use_it_later, LOCATIONS.efficiency_1, LOCATIONS.preparing_to_launch, + LOCATIONS.spacey, LOCATIONS.stack_overflow, LOCATIONS.its_a_mess, LOCATIONS.faster, + LOCATIONS.even_faster, LOCATIONS.get_rid_of_them, LOCATIONS.a_long_time, + LOCATIONS.addicted, LOCATIONS.cant_stop, LOCATIONS.is_this_the_end, + LOCATIONS.getting_into_it, LOCATIONS.now_its_easy, LOCATIONS.computer_guy, + LOCATIONS.speedrun_master, LOCATIONS.speedrun_novice, LOCATIONS.not_idle_game, + LOCATIONS.efficiency_2, LOCATIONS.branding_1, + LOCATIONS.branding_2, LOCATIONS.king_of_inefficiency, LOCATIONS.its_so_slow, + LOCATIONS.mam, LOCATIONS.perfectionist, LOCATIONS.next_dimension, LOCATIONS.oops, + LOCATIONS.copy_pasta, LOCATIONS.ive_seen_that_before, LOCATIONS.memories, + LOCATIONS.i_need_trains, LOCATIONS.a_bit_early, LOCATIONS.gps] +shapesanity_locations: List[str] = [LOCATIONS.shapesanity(x) for x in range(1, max_shapesanity+1)] + + +def init_shapesanity_pool() -> None: + """Imports the pregenerated shapesanity pool.""" + from .data import shapesanity_pool + shapesanity_simple.update(shapesanity_pool.shapesanity_simple) + shapesanity_1_4.update(shapesanity_pool.shapesanity_1_4) + shapesanity_two_sided.update(shapesanity_pool.shapesanity_two_sided) + shapesanity_three_parts.update(shapesanity_pool.shapesanity_three_parts) + shapesanity_four_parts.update(shapesanity_pool.shapesanity_four_parts) + + +def addlevels(maxlevel: int, logictype: str, + random_logic_phase_length: List[int]) -> Dict[str, Tuple[str, LocationProgressType]]: + """Returns a dictionary with all level locations based on player options (maxlevel INCLUDED). + If shape requirements are not randomized, the logic type is expected to be vanilla.""" + + # Level 1 is always directly accessible + locations: Dict[str, Tuple[str, LocationProgressType]] \ + = {LOCATIONS.level(1): (REGIONS.main, LocationProgressType.PRIORITY), + LOCATIONS.level(1, 1): (REGIONS.main, LocationProgressType.PRIORITY)} + level_regions = [REGIONS.main, REGIONS.levels_1, REGIONS.levels_2, REGIONS.levels_3, + REGIONS.levels_4, REGIONS.levels_5] + + def f(name: str, region: str, progress: LocationProgressType = LocationProgressType.DEFAULT) -> None: + locations[name] = (region, progress) + + if logictype.startswith(OPTIONS.logic_vanilla): + f(LOCATIONS.level(20, 1), REGIONS.levels_5) + f(LOCATIONS.level(20, 2), REGIONS.levels_5) + f(LOCATIONS.level(2), REGIONS.levels_1) + f(LOCATIONS.level(3), REGIONS.levels_1) + f(LOCATIONS.level(4), REGIONS.levels_1) + f(LOCATIONS.level(5), REGIONS.levels_2) + f(LOCATIONS.level(6), REGIONS.levels_2) + f(LOCATIONS.level(7), REGIONS.levels_3) + f(LOCATIONS.level(8), REGIONS.levels_3) + f(LOCATIONS.level(9), REGIONS.levels_4) + f(LOCATIONS.level(10), REGIONS.levels_4) + for x in range(11, maxlevel+1): + f(LOCATIONS.level(x), REGIONS.levels_5) + + elif logictype.startswith(OPTIONS.logic_stretched): + phaselength = maxlevel//6 + f(LOCATIONS.level(20, 1), level_regions[20//phaselength]) + f(LOCATIONS.level(20, 2), level_regions[20//phaselength]) + for x in range(2, phaselength): + f(LOCATIONS.level(x), REGIONS.main) + for x in range(phaselength, phaselength*2): + f(LOCATIONS.level(x), REGIONS.levels_1) + for x in range(phaselength*2, phaselength*3): + f(LOCATIONS.level(x), REGIONS.levels_2) + for x in range(phaselength*3, phaselength*4): + f(LOCATIONS.level(x), REGIONS.levels_3) + for x in range(phaselength*4, phaselength*5): + f(LOCATIONS.level(x), REGIONS.levels_4) + for x in range(phaselength*5, maxlevel+1): + f(LOCATIONS.level(x), REGIONS.levels_5) + + elif logictype.startswith(OPTIONS.logic_quick): + f(LOCATIONS.level(20, 1), REGIONS.levels_5) + f(LOCATIONS.level(20, 2), REGIONS.levels_5) + f(LOCATIONS.level(2), REGIONS.levels_1) + f(LOCATIONS.level(3), REGIONS.levels_2) + f(LOCATIONS.level(4), REGIONS.levels_3) + f(LOCATIONS.level(5), REGIONS.levels_4) + for x in range(6, maxlevel+1): + f(LOCATIONS.level(x), REGIONS.levels_5) + + elif logictype.startswith(OPTIONS.logic_random_steps): + next_level = 2 + for phase in range(5): + for x in range(random_logic_phase_length[phase]): + f(LOCATIONS.level(next_level+x), level_regions[phase]) + next_level += random_logic_phase_length[phase] + if next_level > 20: + f(LOCATIONS.level(20, 1), level_regions[phase]) + f(LOCATIONS.level(20, 2), level_regions[phase]) + for x in range(next_level, maxlevel+1): + f(LOCATIONS.level(x), REGIONS.levels_5) + if next_level <= 20: + f(LOCATIONS.level(20, 1), REGIONS.levels_5) + f(LOCATIONS.level(20, 2), REGIONS.levels_5) + + elif logictype == OPTIONS.logic_hardcore: + f(LOCATIONS.level(20, 1), REGIONS.levels_5) + f(LOCATIONS.level(20, 2), REGIONS.levels_5) + for x in range(2, maxlevel+1): + f(LOCATIONS.level(x), REGIONS.levels_5) + + elif logictype == OPTIONS.logic_dopamine: + f(LOCATIONS.level(20, 1), REGIONS.levels_2) + f(LOCATIONS.level(20, 2), REGIONS.levels_2) + for x in range(2, maxlevel+1): + f(LOCATIONS.level(x), REGIONS.levels_2) + + elif logictype == OPTIONS.logic_dopamine_overflow: + f(LOCATIONS.level(20, 1), REGIONS.main) + f(LOCATIONS.level(20, 2), REGIONS.main) + for x in range(2, maxlevel+1): + f(LOCATIONS.level(x), REGIONS.main) + + else: + raise Exception(f"Illegal level logic type {logictype}") + + return locations + + +def addupgrades(finaltier: int, logictype: str, + category_random_logic_amounts: Dict[str, int]) -> Dict[str, Tuple[str, LocationProgressType]]: + """Returns a dictionary with all upgrade locations based on player options (finaltier INCLUDED). + If shape requirements are not randomized, give logic type 0.""" + + locations: Dict[str, Tuple[str, LocationProgressType]] = {} + upgrade_regions = [REGIONS.main, REGIONS.upgrades_1, REGIONS.upgrades_2, REGIONS.upgrades_3, + REGIONS.upgrades_4, REGIONS.upgrades_5] + + def f(name: str, region: str, progress: LocationProgressType = LocationProgressType.DEFAULT) -> None: + locations[name] = (region, progress) + + if logictype == OPTIONS.logic_vanilla_like: + f(LOCATIONS.upgrade(CATEGORY.belt, "II"), REGIONS.main) + f(LOCATIONS.upgrade(CATEGORY.miner, "II"), REGIONS.main) + f(LOCATIONS.upgrade(CATEGORY.processors, "II"), REGIONS.main) + f(LOCATIONS.upgrade(CATEGORY.painting, "II"), REGIONS.upgrades_3) + f(LOCATIONS.upgrade(CATEGORY.belt, "III"), REGIONS.upgrades_2) + f(LOCATIONS.upgrade(CATEGORY.miner, "III"), REGIONS.upgrades_2) + f(LOCATIONS.upgrade(CATEGORY.processors, "III"), REGIONS.upgrades_1) + f(LOCATIONS.upgrade(CATEGORY.painting, "III"), REGIONS.upgrades_3) + for x in range(4, finaltier+1): + tier = roman(x) + for cat in categories: + f(LOCATIONS.upgrade(cat, tier), REGIONS.upgrades_5) + + elif logictype == OPTIONS.logic_linear: + for x in range(2, 7): + tier = roman(x) + for cat in categories: + f(LOCATIONS.upgrade(cat, tier), upgrade_regions[x-2]) + for x in range(7, finaltier+1): + tier = roman(x) + for cat in categories: + f(LOCATIONS.upgrade(cat, tier), REGIONS.upgrades_5) + + elif logictype == OPTIONS.logic_category: + for x in range(2, 7): + tier = roman(x) + f(LOCATIONS.upgrade(CATEGORY.belt, tier), REGIONS.main) + f(LOCATIONS.upgrade(CATEGORY.miner, tier), REGIONS.main) + for x in range(7, finaltier + 1): + tier = roman(x) + f(LOCATIONS.upgrade(CATEGORY.belt, tier), REGIONS.upgrades_5) + f(LOCATIONS.upgrade(CATEGORY.miner, tier), REGIONS.upgrades_5) + f(LOCATIONS.upgrade(CATEGORY.processors, "II"), REGIONS.upgrades_1) + f(LOCATIONS.upgrade(CATEGORY.processors, "III"), REGIONS.upgrades_2) + f(LOCATIONS.upgrade(CATEGORY.processors, "IV"), REGIONS.upgrades_2) + f(LOCATIONS.upgrade(CATEGORY.processors, "V"), REGIONS.upgrades_3) + f(LOCATIONS.upgrade(CATEGORY.processors, "VI"), REGIONS.upgrades_3) + for x in range(7, finaltier+1): + f(LOCATIONS.upgrade(CATEGORY.processors, roman(x)), REGIONS.upgrades_5) + for x in range(2, 4): + f(LOCATIONS.upgrade(CATEGORY.painting, roman(x)), REGIONS.upgrades_4) + for x in range(4, finaltier+1): + f(LOCATIONS.upgrade(CATEGORY.painting, roman(x)), REGIONS.upgrades_5) + + elif logictype == OPTIONS.logic_category_random: + for x in range(2, 7): + tier = roman(x) + f(LOCATIONS.upgrade(CATEGORY.belt, tier), + upgrade_regions[category_random_logic_amounts[CATEGORY.belt_low]]) + f(LOCATIONS.upgrade(CATEGORY.miner, tier), + upgrade_regions[category_random_logic_amounts[CATEGORY.miner_low]]) + f(LOCATIONS.upgrade(CATEGORY.processors, tier), + upgrade_regions[category_random_logic_amounts[CATEGORY.processors_low]]) + f(LOCATIONS.upgrade(CATEGORY.painting, tier), + upgrade_regions[category_random_logic_amounts[CATEGORY.painting_low]]) + for x in range(7, finaltier+1): + tier = roman(x) + for cat in categories: + f(LOCATIONS.upgrade(cat, tier), REGIONS.upgrades_5) + + else: # logictype == hardcore + for cat in categories: + f(LOCATIONS.upgrade(cat, "II"), REGIONS.main) + for x in range(3, finaltier+1): + tier = roman(x) + for cat in categories: + f(LOCATIONS.upgrade(cat, tier), REGIONS.upgrades_5) + + return locations + + +def addachievements(excludesoftlock: bool, excludelong: bool, excludeprogressive: bool, + maxlevel: int, upgradelogictype: str, category_random_logic_amounts: Dict[str, int], + goal: str, presentlocations: Dict[str, Tuple[str, LocationProgressType]], + add_alias: Callable[[str, str], None], has_upgrade_traps: bool + ) -> Dict[str, Tuple[str, LocationProgressType]]: + """Returns a dictionary with all achievement locations based on player options.""" + + locations: Dict[str, Tuple[str, LocationProgressType]] = dict() + upgrade_regions = [REGIONS.main, REGIONS.upgrades_1, REGIONS.upgrades_2, REGIONS.upgrades_3, + REGIONS.upgrades_4, REGIONS.upgrades_5] + + def f(name: str, region: str, alias: str, progress: LocationProgressType = LocationProgressType.DEFAULT): + locations[name] = (region, progress) + add_alias(name, alias) + + f(LOCATIONS.my_eyes, REGIONS.menu, "Activate dark mode") + f(LOCATIONS.painter, REGIONS.paint_not_quad, "Paint a shape (no Quad Painter)") + f(LOCATIONS.cutter, REGIONS.cut_not_quad, "Cut a shape (no Quad Cutter)") + f(LOCATIONS.rotater, REGIONS.rotate_cw, "Rotate a shape clock wise") + f(LOCATIONS.wait_they_stack, REGIONS.stack_shape, "Stack a shape") + f(LOCATIONS.storage, REGIONS.store_shape, "Store a shape in the storage") + f(LOCATIONS.the_logo, REGIONS.all_buildings, "Produce the shapez logo") + f(LOCATIONS.to_the_moon, REGIONS.all_buildings, "Produce the rocket shape") + f(LOCATIONS.its_piling_up, REGIONS.all_buildings, "100k blueprint shapes") + f(LOCATIONS.use_it_later, REGIONS.all_buildings, "1 million blueprint shapes") + + f(LOCATIONS.stack_overflow, REGIONS.stack_shape, "4 layers shape") + f(LOCATIONS.its_a_mess, REGIONS.main, "100 different shapes in hub") + f(LOCATIONS.get_rid_of_them, REGIONS.trash_shape, "1000 shapes trashed") + f(LOCATIONS.getting_into_it, REGIONS.menu, "1 hour") + f(LOCATIONS.now_its_easy, REGIONS.blueprint, "Place a blueprint") + f(LOCATIONS.computer_guy, REGIONS.wiring, "Place 5000 wires") + f(LOCATIONS.perfectionist, REGIONS.any_building, "Destroy more than 1000 objects at once") + f(LOCATIONS.next_dimension, REGIONS.wiring, "Open the wires layer") + f(LOCATIONS.copy_pasta, REGIONS.blueprint, "Place a 1000 buildings blueprint") + f(LOCATIONS.ive_seen_that_before, REGIONS.all_buildings, "Produce RgRyRbRr") + f(LOCATIONS.memories, REGIONS.all_buildings, "Produce WrRgWrRg:CwCrCwCr:SgSgSgSg") + f(LOCATIONS.i_need_trains, REGIONS.belt, "Have a 500 tiles belt") + f(LOCATIONS.gps, REGIONS.menu, "15 map markers") + + # Per second delivery achievements + f(LOCATIONS.preparing_to_launch, REGIONS.all_buildings, "10 rocket shapes / second") + if not has_upgrade_traps: + f(LOCATIONS.spacey, REGIONS.all_buildings, "20 rocket shapes / second") + f(LOCATIONS.efficiency_1, REGIONS.all_buildings, "25 blueprints shapes / second") + f(LOCATIONS.efficiency_2, REGIONS.all_buildings_x1_6_belt, "50 blueprints shapes / second") + f(LOCATIONS.branding_1, REGIONS.all_buildings, "25 logo shapes / second") + f(LOCATIONS.branding_2, REGIONS.all_buildings_x1_6_belt, "50 logo shapes / second") + + # Achievements that depend on upgrades + f(LOCATIONS.even_faster, REGIONS.upgrades_5, "All upgrades on tier VIII") + if upgradelogictype == OPTIONS.logic_linear: + f(LOCATIONS.faster, REGIONS.upgrades_3, "All upgrades on tier V") + elif upgradelogictype == OPTIONS.logic_category_random: + f(LOCATIONS.faster, upgrade_regions[ + max(category_random_logic_amounts[CATEGORY.belt_low], + category_random_logic_amounts[CATEGORY.miner_low], + category_random_logic_amounts[CATEGORY.processors_low], + category_random_logic_amounts[CATEGORY.painting_low]) + ], "All upgrades on tier V") + else: + f(LOCATIONS.faster, REGIONS.upgrades_5, "All upgrades on tier V") + + # Achievements that depend on the level + f(LOCATIONS.wires, presentlocations[LOCATIONS.level(20)][0], "Complete level 20") + if not goal == GOALS.vanilla: + f(LOCATIONS.freedom, presentlocations[LOCATIONS.level(26)][0], "Complete level 26") + f(LOCATIONS.mam, REGIONS.mam, "Complete any level > 26 without modifications") + if maxlevel >= 50: + f(LOCATIONS.cant_stop, presentlocations[LOCATIONS.level(50)][0], "Reach level 50") + elif goal not in [GOALS.vanilla, GOALS.mam]: + f(LOCATIONS.cant_stop, REGIONS.levels_5, "Reach level 50") + if maxlevel >= 100: + f(LOCATIONS.is_this_the_end, presentlocations[LOCATIONS.level(100)][0], "Reach level 100") + elif goal not in [GOALS.vanilla, GOALS.mam]: + f(LOCATIONS.is_this_the_end, REGIONS.levels_5, "Reach level 100") + + # Achievements that depend on player preferences + if excludeprogressive: + unreasonable_type = LocationProgressType.EXCLUDED + else: + unreasonable_type = LocationProgressType.DEFAULT + if not excludesoftlock: + f(LOCATIONS.speedrun_master, presentlocations[LOCATIONS.level(12)][0], + "Complete level 12 in under 30 min", unreasonable_type) + f(LOCATIONS.speedrun_novice, presentlocations[LOCATIONS.level(12)][0], + "Complete level 12 in under 60 min", unreasonable_type) + f(LOCATIONS.not_idle_game, presentlocations[LOCATIONS.level(12)][0], + "Complete level 12 in under 120 min", unreasonable_type) + f(LOCATIONS.its_so_slow, presentlocations[LOCATIONS.level(12)][0], + "Complete level 12 without upgrading belts", unreasonable_type) + f(LOCATIONS.king_of_inefficiency, presentlocations[LOCATIONS.level(14)][0], + "No ccw rotator until level 14", unreasonable_type) + f(LOCATIONS.a_bit_early, REGIONS.all_buildings, + "Produce logo shape before level 18", unreasonable_type) + if not excludelong: + f(LOCATIONS.a_long_time, REGIONS.menu, "10 hours") + f(LOCATIONS.addicted, REGIONS.menu, "20 hours") + + # Achievements with a softlock chance of less than + # 1 divided by 2 to the power of the number of all atoms in the universe + f(LOCATIONS.oops, REGIONS.main, "Deliver an irrelevant shape") + + return locations + + +def addshapesanity(amount: int, random: Random, append_shapesanity: Callable[[str], None], + add_alias: Callable[[str, str], None]) -> Dict[str, Tuple[str, LocationProgressType]]: + """Returns a dictionary with a given number of random shapesanity locations.""" + + included_shapes: Dict[str, Tuple[str, LocationProgressType]] = {} + + def f(name: str, region: str, alias: str, progress: LocationProgressType = LocationProgressType.DEFAULT) -> None: + included_shapes[name] = (region, progress) + append_shapesanity(alias) + shapes_list.remove((alias, region)) + add_alias(name, alias) + + # Always have at least 4 shapesanity checks because of sphere 1 usefulls + both hardcore logic + shapes_list = list(shapesanity_simple.items()) + f(LOCATIONS.shapesanity(1), REGIONS.sanity(REGIONS.full, REGIONS.uncol), + SHAPESANITY.full(SHAPESANITY.uncolored, SHAPESANITY.circle)) + f(LOCATIONS.shapesanity(2), REGIONS.sanity(REGIONS.full, REGIONS.uncol), + SHAPESANITY.full(SHAPESANITY.uncolored, SHAPESANITY.square)) + f(LOCATIONS.shapesanity(3), REGIONS.sanity(REGIONS.full, REGIONS.uncol), + SHAPESANITY.full(SHAPESANITY.uncolored, SHAPESANITY.star)) + f(LOCATIONS.shapesanity(4), REGIONS.sanity(REGIONS.east_wind, REGIONS.uncol), + SHAPESANITY.full(SHAPESANITY.uncolored, SHAPESANITY.windmill)) + + # The pool switches dynamically depending on if either it's ratio or limit is reached + switched = 0 + for counting in range(4, amount): + if switched == 0 and (len(shapes_list) == 0 or counting == amount//2): + shapes_list = list(shapesanity_1_4.items()) + switched = 1 + elif switched == 1 and (len(shapes_list) == 0 or counting == amount*7//12): + shapes_list = list(shapesanity_two_sided.items()) + switched = 2 + elif switched == 2 and (len(shapes_list) == 0 or counting == amount*5//6): + shapes_list = list(shapesanity_three_parts.items()) + switched = 3 + elif switched == 3 and (len(shapes_list) == 0 or counting == amount*11//12): + shapes_list = list(shapesanity_four_parts.items()) + switched = 4 + x = random.randint(0, len(shapes_list)-1) + next_shape = shapes_list.pop(x) + included_shapes[LOCATIONS.shapesanity(counting+1)] = (next_shape[1], LocationProgressType.DEFAULT) + append_shapesanity(next_shape[0]) + add_alias(LOCATIONS.shapesanity(counting+1), next_shape[0]) + + return included_shapes + + +def addshapesanity_ut(shapesanity_names: List[str], add_alias: Callable[[str, str], None] + ) -> Dict[str, Tuple[str, LocationProgressType]]: + """Returns the same information as addshapesanity but will add specific values based on a UT rebuild.""" + + included_shapes: Dict[str, Tuple[str, LocationProgressType]] = {} + + for name in shapesanity_names: + for options in [shapesanity_simple, shapesanity_1_4, shapesanity_two_sided, shapesanity_three_parts, + shapesanity_four_parts]: + if name in options: + next_shape = options[name] + break + else: + raise ValueError(f"Could not find shapesanity name {name}") + included_shapes[LOCATIONS.shapesanity(len(included_shapes)+1)] = (next_shape, LocationProgressType.DEFAULT) + add_alias(LOCATIONS.shapesanity(len(included_shapes)), name) + return included_shapes + + +class ShapezLocation(Location): + game = OTHER.game_name + + def __init__(self, player: int, name: str, address: Optional[int], region: Region, + progress_type: LocationProgressType): + super(ShapezLocation, self).__init__(player, name, address, region) + self.progress_type = progress_type diff --git a/worlds/shapez/options.py b/worlds/shapez/options.py new file mode 100644 index 000000000000..bc3fc1ed2fbc --- /dev/null +++ b/worlds/shapez/options.py @@ -0,0 +1,310 @@ +import pkgutil +from dataclasses import dataclass + +import orjson + +from Options import Toggle, Choice, PerGameCommonOptions, NamedRange, Range +from .common.options import FloatRangeText + +datapackage_options = orjson.loads(pkgutil.get_data(__name__, "data/options.json")) +max_levels_and_upgrades = datapackage_options["max_levels_and_upgrades"] +max_shapesanity = datapackage_options["max_shapesanity"] +del datapackage_options + + +class Goal(Choice): + """Sets the goal of your world. + + - **Vanilla:** Complete level 26. + - **MAM:** Complete a specified level after level 26. Every level before that will be a location. It's recommended + to build a Make-Anything-Machine (MAM). + - **Even fasterer:** Upgrade everything to a specified tier after tier 8. Every upgrade before that will be a + location. + - **Efficiency III:** Deliver 256 blueprint shapes per second to the hub.""" + display_name = "Goal" + rich_text_doc = True + option_vanilla = 0 + option_mam = 1 + option_even_fasterer = 2 + option_efficiency_iii = 3 + default = 0 + + +class GoalAmount(NamedRange): + """Specify, what level or tier (when either MAM or Even Fasterer is chosen as goal) is required to reach the goal. + + If MAM is set as the goal, this has to be set to 27 or more. Else it will raise an error.""" + display_name = "Goal amount" + rich_text_doc = True + range_start = 9 + range_end = max_levels_and_upgrades + default = 27 + special_range_names = { + "minimum_mam": 27, + "recommended_mam": 50, + "long_game_mam": 120, + "minimum_even_fasterer": 9, + "recommended_even_fasterer": 16, + "long_play_even_fasterer": 35, + } + + +class RequiredShapesMultiplier(Range): + """Multiplies the amount of required shapes for levels and upgrades by value/10. + + For level 1, the amount of shapes ranges from 3 to 300. + + For level 26, it ranges from 5k to 500k.""" + display_name = "Required shapes multiplier" + rich_text_doc = True + range_start = 1 + range_end = 100 + default = 10 + + +class AllowFloatingLayers(Toggle): + """Toggle whether shape requirements are allowed to have floating layers (like the logo or the rocket shape). + + However, be aware that floating shapes make MAMs much more complex.""" + display_name = "Allow floating layers" + rich_text_doc = True + default = False + + +class RandomizeLevelRequirements(Toggle): + """Randomize the required shapes to complete levels.""" + display_name = "Randomize level requirements" + rich_text_doc = True + default = True + + +class RandomizeUpgradeRequirements(Toggle): + """Randomize the required shapes to buy upgrades.""" + display_name = "Randomize upgrade requirements" + rich_text_doc = True + default = True + + +class RandomizeLevelLogic(Choice): + """If level requirements are randomized, this sets how those random shapes are generated and how logic works for + levels. The shuffled variants shuffle the order of progression buildings obtained in the multiworld. The standard + order is: **cutter -> rotator -> painter -> color mixer -> stacker** + + - **Vanilla:** Level 1 requires nothing, 2-4 require the first building, 5-6 require also the second, 7-8 the + third, 9-10 the fourth, and 11 and onwards the fifth and thereby all buildings. + - **Stretched:** After every floor(maxlevel/6) levels, another building is required. + - **Quick:** Every Level, except level 1, requires another building, with level 6 and onwards requiring all + buildings. + - **Random steps:** After a random amount of levels, another building is required, with level 1 always requiring + none. This can potentially generate like any other option. + - **Hardcore:** All levels (except level 1) have completely random shape requirements and thus require all + buildings. Expect early BKs. + - **Dopamine (overflow):** All levels (except level 1 and the goal) require 2 random buildings (or none in case of + overflow).""" + display_name = "Randomize level logic" + rich_text_doc = True + option_vanilla = 0 + option_vanilla_shuffled = 1 + option_stretched = 2 + option_stretched_shuffled = 3 + option_quick = 4 + option_quick_shuffled = 5 + option_random_steps = 6 + option_random_steps_shuffled = 7 + option_hardcore = 8 + option_dopamine = 9 + option_dopamine_overflow = 10 + default = 2 + + +class RandomizeUpgradeLogic(Choice): + """If upgrade requirements are randomized, this sets how those random shapes are generated + and how logic works for upgrades. + + - **Vanilla-like:** Tier II requires up to two random buildings, III requires up to three random buildings, + and IV and onwards require all processing buildings. + - **Linear:** Tier II requires nothing, III-VI require another random building each, + and VII and onwards require all buildings. + - **Category:** Belt and miner upgrades require no building up to tier V, but onwards all buildings, processors + upgrades require the cutter (all tiers), rotator (tier III and onwards), and stacker (tier V and onwards), and + painting upgrades require the cutter, rotator, stacker, painter (all tiers) and color mixer (tiers V and onwards). + Tier VII and onwards will always require all buildings. + - **Category random:** Each upgrades category (up to tier VI) requires a random amount of buildings (in order), + with one category always requiring no buildings. Tier VII and onwards will always require all buildings. + - **Hardcore:** All tiers (except each tier II) have completely random shape requirements and thus require all + buildings. Expect early BKs.""" + display_name = "Randomize upgrade logic" + rich_text_doc = True + option_vanilla_like = 0 + option_linear = 1 + option_category = 2 + option_category_random = 3 + option_hardcore = 4 + default = 1 + + +class ThroughputLevelsRatio(NamedRange): + """If level requirements are randomized, this sets the ratio of how many levels (approximately) will require either + a total amount or per second amount (throughput) of shapes delivered. + + 0 means only total, 100 means only throughput, and vanilla (-1) means only levels 14, 27 and beyond have throughput. + """ + display_name = "Throughput levels ratio" + rich_text_doc = True + range_start = 0 + range_end = 100 + default = 0 + special_range_names = { + "vanilla": -1, + "only_total": 0, + "half_half": 50, + "only_throughput": 100, + } + + +class ComplexityGrowthGradient(FloatRangeText): + """If level requirements are randomized, this determines how fast complexity will grow each level. In other words: + The higher you set this value, the more difficult lategame shapes will be. + + Allowed values are floating numbers ranging from 0.0 to 10.0.""" + display_name = "Complexity growth gradient" + rich_text_doc = True + range_start = 0.0 + range_end = 10.0 + default = "0.5" + + +class SameLateUpgradeRequirements(Toggle): + """If upgrade requirements are randomized, should the last 3 shapes for each category be the same, + as in vanilla?""" + display_name = "Same late upgrade requirements" + rich_text_doc = True + default = True + + +class EarlyBalancerTunnelAndTrash(Choice): + """Makes the balancer, tunnel, and trash appear in earlier spheres. + + - **None:** Complete randomization. + - **5 buildings:** Should be accessible before getting all 5 main buildings. + - **3 buildings:** Should be accessible before getting the first 3 main buildings for levels and upgrades. + - **Sphere 1:** Always accessible from start. **Beware of generation failures.**""" + display_name = "Early balancer, tunnel, and trash" + rich_text_doc = True + option_none = 0 + option_5_buildings = 1 + option_3_buildings = 2 + option_sphere_1 = 3 + default = 2 + + +class LockBeltAndExtractor(Toggle): + """Locks Belts and Extractors and adds them to the item pool. + + **If you set this to true, achievements must also be included.**""" + display_name = "Lock Belt and Extractor" + rich_text_doc = True + default = False + + +class IncludeAchievements(Toggle): + """Include up to 45 achievements (depending on other options) as additional locations.""" + display_name = "Include Achievements" + rich_text_doc = True + default = True + + +class ExcludeSoftlockAchievements(Toggle): + """Exclude 6 achievements, that can become unreachable in a save file, if not achieved until a certain level.""" + display_name = "Exclude softlock achievements" + rich_text_doc = True + default = True + + +class ExcludeLongPlaytimeAchievements(Toggle): + """Exclude 2 achievements, that require actively playing for a really long time.""" + display_name = "Exclude long playtime achievements" + rich_text_doc = True + default = True + + +class ExcludeProgressionUnreasonable(Toggle): + """Exclude progression and useful items from being placed into softlock and long playtime achievements.""" + display_name = "Exclude progression items in softlock and long playtime achievements" + rich_text_doc = True + default = True + + +class ShapesanityAmount(Range): + """Amount of single-layer shapes that will be included as locations.""" + display_name = "Shapesanity amount" + rich_text_doc = True + range_start = 4 + range_end = max_shapesanity + default = 50 + + +class TrapsProbability(NamedRange): + """The probability of any filler item (in percent) being replaced by a trap.""" + display_name = "Traps Percentage" + rich_text_doc = True + range_start = 0 + range_end = 100 + default = 0 + special_range_names = { + "none": 0, + "rare": 4, + "occasionally": 10, + "maximum_suffering": 100, + } + + +class IncludeWhackyUpgrades(Toggle): + """Includes some very unusual upgrade items in generation (and logic), that greatly increase or decrease building + speeds. If the goal is set to Efficiency III or throughput levels ratio is not 0, decreasing upgrades (aka traps) + will always be disabled.""" + display_name = "Include Whacky Upgrades" + rich_text_doc = True + default = False + + +class SplitInventoryDrainingTrap(Toggle): + """If set to true, the inventory draining trap will be split into level, upgrade, and blueprint draining traps + instead of executing as one of those 3 randomly.""" + display_name = "Split Inventory Draining Trap" + rich_text_doc = True + default = False + + +class ToolbarShuffling(Toggle): + """If set to true, the toolbars (main and wires layer) will be shuffled (including bottom and top row). + However, keybindings will still select the same building to place.""" + display_name = "Toolbar Shuffling" + rich_text_doc = True + default = True + + +@dataclass +class ShapezOptions(PerGameCommonOptions): + goal: Goal + goal_amount: GoalAmount + required_shapes_multiplier: RequiredShapesMultiplier + allow_floating_layers: AllowFloatingLayers + randomize_level_requirements: RandomizeLevelRequirements + randomize_upgrade_requirements: RandomizeUpgradeRequirements + randomize_level_logic: RandomizeLevelLogic + randomize_upgrade_logic: RandomizeUpgradeLogic + throughput_levels_ratio: ThroughputLevelsRatio + complexity_growth_gradient: ComplexityGrowthGradient + same_late_upgrade_requirements: SameLateUpgradeRequirements + early_balancer_tunnel_and_trash: EarlyBalancerTunnelAndTrash + lock_belt_and_extractor: LockBeltAndExtractor + include_achievements: IncludeAchievements + exclude_softlock_achievements: ExcludeSoftlockAchievements + exclude_long_playtime_achievements: ExcludeLongPlaytimeAchievements + exclude_progression_unreasonable: ExcludeProgressionUnreasonable + shapesanity_amount: ShapesanityAmount + traps_percentage: TrapsProbability + include_whacky_upgrades: IncludeWhackyUpgrades + split_inventory_draining_trap: SplitInventoryDrainingTrap + toolbar_shuffling: ToolbarShuffling diff --git a/worlds/shapez/presets.py b/worlds/shapez/presets.py new file mode 100644 index 000000000000..e01192d594e9 --- /dev/null +++ b/worlds/shapez/presets.py @@ -0,0 +1,49 @@ +from .options import max_levels_and_upgrades, max_shapesanity + +options_presets = { + "Most vanilla": { + "goal": "vanilla", + "randomize_level_requirements": False, + "randomize_upgrade_requirements": False, + "early_balancer_tunnel_and_trash": "3_buildings", + "include_achievements": True, + "exclude_softlock_achievements": False, + "exclude_long_playtime_achievements": False, + "shapesanity_amount": 4, + "toolbar_shuffling": False, + }, + "Minimum checks": { + "goal": "vanilla", + "include_achievements": False, + "shapesanity_amount": 4 + }, + "Maximum checks": { + "goal": "even_fasterer", + "goal_amount": max_levels_and_upgrades, + "include_achievements": True, + "exclude_softlock_achievements": False, + "exclude_long_playtime_achievements": False, + "shapesanity_amount": max_shapesanity + }, + "Restrictive start": { + "goal": "vanilla", + "randomize_level_requirements": True, + "randomize_upgrade_requirements": True, + "randomize_level_logic": "hardcore", + "randomize_upgrade_logic": "hardcore", + "early_balancer_tunnel_and_trash": "sphere_1", + "include_achievements": False, + "shapesanity_amount": 4 + }, + "Quick game": { + "goal": "efficiency_iii", + "required_shapes_multiplier": 1, + "randomize_level_requirements": True, + "randomize_upgrade_requirements": True, + "randomize_level_logic": "hardcore", + "randomize_upgrade_logic": "hardcore", + "include_achievements": False, + "shapesanity_amount": 4, + "include_whacky_upgrades": True, + } +} diff --git a/worlds/shapez/regions.py b/worlds/shapez/regions.py new file mode 100644 index 000000000000..c4ca1d0c816e --- /dev/null +++ b/worlds/shapez/regions.py @@ -0,0 +1,277 @@ +from typing import Dict, Tuple, List + +from BaseClasses import Region, MultiWorld, LocationProgressType, ItemClassification, CollectionState +from .items import ShapezItem +from .locations import ShapezLocation +from .data.strings import ITEMS, REGIONS, GOALS, LOCATIONS, OPTIONS +from worlds.generic.Rules import add_rule + +shapesanity_processing = [REGIONS.full, REGIONS.half, REGIONS.piece, REGIONS.stitched, REGIONS.east_wind, + REGIONS.half_half, REGIONS.col_east_wind, REGIONS.col_half_half, REGIONS.col_full, + REGIONS.col_half] +shapesanity_coloring = [REGIONS.uncol, REGIONS.painted, REGIONS.mixed] + +all_regions = [ + REGIONS.menu, REGIONS.belt, REGIONS.extract, REGIONS.main, + REGIONS.levels_1, REGIONS.levels_2, REGIONS.levels_3, REGIONS.levels_4, REGIONS.levels_5, + REGIONS.upgrades_1, REGIONS.upgrades_2, REGIONS.upgrades_3, REGIONS.upgrades_4, REGIONS.upgrades_5, + REGIONS.paint_not_quad, REGIONS.cut_not_quad, REGIONS.rotate_cw, REGIONS.stack_shape, REGIONS.store_shape, + REGIONS.trash_shape, REGIONS.blueprint, REGIONS.wiring, REGIONS.mam, REGIONS.any_building, + REGIONS.all_buildings, REGIONS.all_buildings_x1_6_belt, + *[REGIONS.sanity(processing, coloring) + for processing in shapesanity_processing + for coloring in shapesanity_coloring], +] + + +def can_cut_half(state: CollectionState, player: int) -> bool: + return state.has(ITEMS.cutter, player) + + +def can_rotate_90(state: CollectionState, player: int) -> bool: + return state.has_any((ITEMS.rotator, ITEMS.rotator_ccw), player) + + +def can_rotate_180(state: CollectionState, player: int) -> bool: + return state.has_any((ITEMS.rotator, ITEMS.rotator_ccw, ITEMS.rotator_180), player) + + +def can_stack(state: CollectionState, player: int) -> bool: + return state.has(ITEMS.stacker, player) + + +def can_paint(state: CollectionState, player: int) -> bool: + return state.has_any((ITEMS.painter, ITEMS.painter_double), player) or can_use_quad_painter(state, player) + + +def can_mix_colors(state: CollectionState, player: int) -> bool: + return state.has(ITEMS.color_mixer, player) + + +def has_tunnel(state: CollectionState, player: int) -> bool: + return state.has_any((ITEMS.tunnel, ITEMS.tunnel_tier_ii), player) + + +def has_balancer(state: CollectionState, player: int) -> bool: + return state.has(ITEMS.balancer, player) or state.has_all((ITEMS.comp_merger, ITEMS.comp_splitter), player) + + +def can_use_quad_painter(state: CollectionState, player: int) -> bool: + return (state.has_all((ITEMS.painter_quad, ITEMS.wires), player) and + state.has_any((ITEMS.switch, ITEMS.const_signal), player)) + + +def can_make_stitched_shape(state: CollectionState, player: int, floating: bool) -> bool: + return (can_stack(state, player) and + ((state.has(ITEMS.cutter_quad, player) and not floating) or + (can_cut_half(state, player) and can_rotate_90(state, player)))) + + +def can_build_mam(state: CollectionState, player: int, floating: bool) -> bool: + return (can_make_stitched_shape(state, player, floating) and can_paint(state, player) and + can_mix_colors(state, player) and has_balancer(state, player) and has_tunnel(state, player) and + state.has_all((ITEMS.belt_reader, ITEMS.storage, ITEMS.item_filter, + ITEMS.wires, ITEMS.logic_gates, ITEMS.virtual_proc), player)) + + +def can_make_east_windmill(state: CollectionState, player: int) -> bool: + # Only used for shapesanity => single layers + return (can_stack(state, player) and + (state.has(ITEMS.cutter_quad, player) or (can_cut_half(state, player) and can_rotate_180(state, player)))) + + +def can_make_half_half_shape(state: CollectionState, player: int) -> bool: + # Only used for shapesanity => single layers + return can_stack(state, player) and state.has_any((ITEMS.cutter, ITEMS.cutter_quad), player) + + +def can_make_half_shape(state: CollectionState, player: int) -> bool: + # Only used for shapesanity => single layers + return can_cut_half(state, player) or state.has_all((ITEMS.cutter_quad, ITEMS.stacker), player) + + +def has_x_belt_multiplier(state: CollectionState, player: int, needed: float) -> bool: + # Assumes there are no upgrade traps + multiplier = 1.0 + # Rising upgrades do the least improvement if received before other upgrades + for _ in range(state.count(ITEMS.upgrade_rising_belt, player)): + multiplier *= 2 + multiplier += state.count(ITEMS.upgrade_gigantic_belt, player)*10 + multiplier += state.count(ITEMS.upgrade_big_belt, player) + multiplier += state.count(ITEMS.upgrade_small_belt, player)*0.1 + return multiplier >= needed + + +def has_logic_list_building(state: CollectionState, player: int, buildings: List[str], index: int, + includeuseful: bool) -> bool: + + # Includes balancer, tunnel, and trash in logic in order to make them appear in earlier spheres + if includeuseful and not (state.has(ITEMS.trash, player) and has_balancer(state, player) and + has_tunnel(state, player)): + return False + + if buildings[index] == ITEMS.cutter: + if buildings.index(ITEMS.stacker) < index: + return state.has_any((ITEMS.cutter, ITEMS.cutter_quad), player) + else: + return can_cut_half(state, player) + elif buildings[index] == ITEMS.rotator: + return can_rotate_90(state, player) + elif buildings[index] == ITEMS.stacker: + return can_stack(state, player) + elif buildings[index] == ITEMS.painter: + return can_paint(state, player) + elif buildings[index] == ITEMS.color_mixer: + return can_mix_colors(state, player) + + +def create_shapez_regions(player: int, multiworld: MultiWorld, floating: bool, + included_locations: Dict[str, Tuple[str, LocationProgressType]], + location_name_to_id: Dict[str, int], level_logic_buildings: List[str], + upgrade_logic_buildings: List[str], early_useful: str, goal: str) -> List[Region]: + """Creates and returns a list of all regions with entrances and all locations placed correctly.""" + regions: Dict[str, Region] = {name: Region(name, player, multiworld) for name in all_regions} + + # Creates ShapezLocations for every included location and puts them into the correct region + for name, data in included_locations.items(): + regions[data[0]].locations.append(ShapezLocation(player, name, location_name_to_id[name], + regions[data[0]], data[1])) + + # Create goal event + if goal in [GOALS.vanilla, GOALS.mam]: + goal_region = regions[REGIONS.levels_5] + elif goal == GOALS.even_fasterer: + goal_region = regions[REGIONS.upgrades_5] + else: + goal_region = regions[REGIONS.all_buildings] + goal_location = ShapezLocation(player, LOCATIONS.goal, None, goal_region, LocationProgressType.DEFAULT) + goal_location.place_locked_item(ShapezItem(ITEMS.goal, ItemClassification.progression_skip_balancing, None, player)) + if goal == GOALS.efficiency_iii: + add_rule(goal_location, lambda state: has_x_belt_multiplier(state, player, 8)) + goal_region.locations.append(goal_location) + multiworld.completion_condition[player] = lambda state: state.has(ITEMS.goal, player) + + # Connect Menu to rest of regions + regions[REGIONS.menu].connect(regions[REGIONS.belt], "Placing belts", lambda state: state.has(ITEMS.belt, player)) + regions[REGIONS.menu].connect(regions[REGIONS.extract], "Extracting shapes from patches", + lambda state: state.has_any((ITEMS.extractor, ITEMS.extractor_chain), player)) + regions[REGIONS.extract].connect( + regions[REGIONS.main], "Transporting shapes over the canvas", + lambda state: state.has_any((ITEMS.belt, ITEMS.comp_merger, ITEMS.comp_splitter), player) + ) + + # Connect achievement regions + regions[REGIONS.main].connect(regions[REGIONS.paint_not_quad], "Painting with (double) painter", + lambda state: state.has_any((ITEMS.painter, ITEMS.painter_double), player)) + regions[REGIONS.extract].connect(regions[REGIONS.cut_not_quad], "Cutting with half cutter", + lambda state: can_cut_half(state, player)) + regions[REGIONS.extract].connect(regions[REGIONS.rotate_cw], "Rotating clockwise", + lambda state: state.has(ITEMS.rotator, player)) + regions[REGIONS.extract].connect(regions[REGIONS.stack_shape], "Stacking shapes", + lambda state: can_stack(state, player)) + regions[REGIONS.extract].connect(regions[REGIONS.store_shape], "Storing shapes", + lambda state: state.has(ITEMS.storage, player)) + regions[REGIONS.extract].connect(regions[REGIONS.trash_shape], "Trashing shapes", + lambda state: state.has(ITEMS.trash, player)) + regions[REGIONS.main].connect(regions[REGIONS.blueprint], "Copying and placing blueprints", + lambda state: state.has(ITEMS.blueprints, player) and + can_make_stitched_shape(state, player, floating) and + can_paint(state, player) and can_mix_colors(state, player)) + regions[REGIONS.menu].connect(regions[REGIONS.wiring], "Using the wires layer", + lambda state: state.has(ITEMS.wires, player)) + regions[REGIONS.main].connect(regions[REGIONS.mam], "Building a MAM", + lambda state: can_build_mam(state, player, floating)) + regions[REGIONS.menu].connect(regions[REGIONS.any_building], "Placing any building", lambda state: state.has_any(( + ITEMS.belt, ITEMS.balancer, ITEMS.comp_merger, ITEMS.comp_splitter, ITEMS.tunnel, ITEMS.tunnel_tier_ii, + ITEMS.extractor, ITEMS.extractor_chain, ITEMS.cutter, ITEMS.cutter_quad, ITEMS.rotator, ITEMS.rotator_ccw, + ITEMS.rotator_180, ITEMS.stacker, ITEMS.painter, ITEMS.painter_double, ITEMS.painter_quad, ITEMS.color_mixer, + ITEMS.trash, ITEMS.belt_reader, ITEMS.storage, ITEMS.switch, ITEMS.item_filter, ITEMS.display, ITEMS.wires + ), player)) + regions[REGIONS.main].connect(regions[REGIONS.all_buildings], "Using all main buildings", + lambda state: can_make_stitched_shape(state, player, floating) and + can_paint(state, player) and can_mix_colors(state, player)) + regions[REGIONS.all_buildings].connect(regions[REGIONS.all_buildings_x1_6_belt], + "Delivering per second with 1.6x belt speed", + lambda state: has_x_belt_multiplier(state, player, 1.6)) + + # Progressively connect level and upgrade regions + regions[REGIONS.main].connect( + regions[REGIONS.levels_1], "Using first level building", + lambda state: has_logic_list_building(state, player, level_logic_buildings, 0, False)) + regions[REGIONS.levels_1].connect( + regions[REGIONS.levels_2], "Using second level building", + lambda state: has_logic_list_building(state, player, level_logic_buildings, 1, False)) + regions[REGIONS.levels_2].connect( + regions[REGIONS.levels_3], "Using third level building", + lambda state: has_logic_list_building(state, player, level_logic_buildings, 2, + early_useful == OPTIONS.buildings_3)) + regions[REGIONS.levels_3].connect( + regions[REGIONS.levels_4], "Using fourth level building", + lambda state: has_logic_list_building(state, player, level_logic_buildings, 3, False)) + regions[REGIONS.levels_4].connect( + regions[REGIONS.levels_5], "Using fifth level building", + lambda state: has_logic_list_building(state, player, level_logic_buildings, 4, + early_useful == OPTIONS.buildings_5)) + regions[REGIONS.main].connect( + regions[REGIONS.upgrades_1], "Using first upgrade building", + lambda state: has_logic_list_building(state, player, upgrade_logic_buildings, 0, False)) + regions[REGIONS.upgrades_1].connect( + regions[REGIONS.upgrades_2], "Using second upgrade building", + lambda state: has_logic_list_building(state, player, upgrade_logic_buildings, 1, False)) + regions[REGIONS.upgrades_2].connect( + regions[REGIONS.upgrades_3], "Using third upgrade building", + lambda state: has_logic_list_building(state, player, upgrade_logic_buildings, 2, + early_useful == OPTIONS.buildings_3)) + regions[REGIONS.upgrades_3].connect( + regions[REGIONS.upgrades_4], "Using fourth upgrade building", + lambda state: has_logic_list_building(state, player, upgrade_logic_buildings, 3, False)) + regions[REGIONS.upgrades_4].connect( + regions[REGIONS.upgrades_5], "Using fifth upgrade building", + lambda state: has_logic_list_building(state, player, upgrade_logic_buildings, 4, + early_useful == OPTIONS.buildings_5)) + + # Connect Uncolored shapesanity regions to Main + regions[REGIONS.main].connect( + regions[REGIONS.sanity(REGIONS.full, REGIONS.uncol)], "Delivering unprocessed", lambda state: True) + regions[REGIONS.main].connect( + regions[REGIONS.sanity(REGIONS.half, REGIONS.uncol)], "Cutting in single half", + lambda state: can_make_half_shape(state, player)) + regions[REGIONS.main].connect( + regions[REGIONS.sanity(REGIONS.piece, REGIONS.uncol)], "Cutting in single piece", + lambda state: (can_cut_half(state, player) and can_rotate_90(state, player)) or + state.has(ITEMS.cutter_quad, player)) + regions[REGIONS.main].connect( + regions[REGIONS.sanity(REGIONS.half_half, REGIONS.uncol)], "Cutting and stacking into two halves", + lambda state: can_make_half_half_shape(state, player)) + regions[REGIONS.main].connect( + regions[REGIONS.sanity(REGIONS.stitched, REGIONS.uncol)], "Stitching complex shapes", + lambda state: can_make_stitched_shape(state, player, floating)) + regions[REGIONS.main].connect( + regions[REGIONS.sanity(REGIONS.east_wind, REGIONS.uncol)], "Rotating and stitching a single windmill half", + lambda state: can_make_east_windmill(state, player)) + regions[REGIONS.main].connect( + regions[REGIONS.sanity(REGIONS.col_full, REGIONS.uncol)], "Painting with a quad painter or stitching", + lambda state: can_make_stitched_shape(state, player, floating) or can_use_quad_painter(state, player)) + regions[REGIONS.main].connect( + regions[REGIONS.sanity(REGIONS.col_east_wind, REGIONS.uncol)], "Why windmill, why?", + lambda state: can_make_stitched_shape(state, player, floating) or + (can_use_quad_painter(state, player) and can_make_east_windmill(state, player))) + regions[REGIONS.main].connect( + regions[REGIONS.sanity(REGIONS.col_half_half, REGIONS.uncol)], "Quad painting a half-half shape", + lambda state: can_make_stitched_shape(state, player, floating) or + (can_use_quad_painter(state, player) and can_make_half_half_shape(state, player))) + regions[REGIONS.main].connect( + regions[REGIONS.sanity(REGIONS.col_half, REGIONS.uncol)], "Quad painting a half shape", + lambda state: can_make_stitched_shape(state, player, floating) or + (can_use_quad_painter(state, player) and can_make_half_shape(state, player))) + + # Progressively connect colored shapesanity regions + for processing in shapesanity_processing: + regions[REGIONS.sanity(processing, REGIONS.uncol)].connect( + regions[REGIONS.sanity(processing, REGIONS.painted)], f"Painting a {processing.lower()} shape", + lambda state: can_paint(state, player)) + regions[REGIONS.sanity(processing, REGIONS.painted)].connect( + regions[REGIONS.sanity(processing, REGIONS.mixed)], f"Mixing colors for a {processing.lower()} shape", + lambda state: can_mix_colors(state, player)) + + return [region for region in regions.values() if len(region.locations) or len(region.exits)] diff --git a/worlds/shapez/test/__init__.py b/worlds/shapez/test/__init__.py new file mode 100644 index 000000000000..3ab626e63936 --- /dev/null +++ b/worlds/shapez/test/__init__.py @@ -0,0 +1,213 @@ +from unittest import TestCase + +from test.bases import WorldTestBase +from .. import options_presets, ShapezWorld +from ..data.strings import GOALS, OTHER, ITEMS, LOCATIONS, CATEGORY, OPTIONS, SHAPESANITY +from ..options import max_levels_and_upgrades, max_shapesanity + + +class ShapezTestBase(WorldTestBase): + game = OTHER.game_name + world: ShapezWorld + + def test_location_count(self): + self.assertTrue(self.world.location_count > 0, + f"location_count is {self.world.location_count} for some reason.") + + def test_logic_lists(self): + logic_buildings = [ITEMS.cutter, ITEMS.rotator, ITEMS.painter, ITEMS.color_mixer, ITEMS.stacker] + for building in logic_buildings: + count = self.world.level_logic.count(building) + self.assertTrue(count == 1, f"{building} was found {count} times in level_logic.") + count = self.world.upgrade_logic.count(building) + self.assertTrue(count == 1, f"{building} was found {count} times in upgrade_logic.") + self.assertTrue(len(self.world.level_logic) == 5, + f"level_logic contains {len(self.world.level_logic)} entries instead of the expected 5.") + self.assertTrue(len(self.world.upgrade_logic) == 5, + f"upgrade_logic contains {len(self.world.upgrade_logic)} entries instead of the expected 5.") + + def test_random_logic_phase_length(self): + self.assertTrue(len(self.world.random_logic_phase_length) == 5, + f"random_logic_phase_length contains {len(self.world.random_logic_phase_length)} entries " + + f"instead of the expected 5.") + self.assertTrue(sum(self.world.random_logic_phase_length) < self.world.maxlevel, + f"The sum of all random phase lengths is greater than allowed: " + + str(sum(self.world.random_logic_phase_length))) + for length in self.world.random_logic_phase_length: + self.assertTrue(length in range(self.world.maxlevel), + f"Found an illegal value in random_logic_phase_length: {length}") + + def test_category_random_logic_amounts(self): + self.assertTrue(len(self.world.category_random_logic_amounts) == 4, + f"Found {len(self.world.category_random_logic_amounts)} instead of 4 keys in " + f"category_random_logic_amounts.") + self.assertTrue(min(self.world.category_random_logic_amounts.values()) == 0, + "Found a value less than or no 0 in category_random_logic_amounts.") + self.assertTrue(max(self.world.category_random_logic_amounts.values()) <= 5, + "Found a value greater than 5 in category_random_logic_amounts.") + + def test_maxlevel_and_finaltier(self): + self.assertTrue(self.world.maxlevel in range(25, max_levels_and_upgrades), + f"Found an illegal value for maxlevel: {self.world.maxlevel}") + self.assertTrue(self.world.finaltier in range(8, max_levels_and_upgrades+1), + f"Found an illegal value for finaltier: {self.world.finaltier}") + + def test_included_locations(self): + self.assertTrue(len(self.world.included_locations) > 0, "Found no locations cached in included_locations.") + self.assertTrue(LOCATIONS.level(1) in self.world.included_locations.keys(), + "Could not find Level 1 (guraranteed location) cached in included_locations.") + self.assertTrue(LOCATIONS.upgrade(CATEGORY.belt, "II") in self.world.included_locations.keys(), + "Could not find Belt Upgrade Tier II (guraranteed location) cached in included_locations.") + self.assertTrue(LOCATIONS.shapesanity(1) in self.world.included_locations.keys(), + "Could not find Shapesanity 1 (guraranteed location) cached in included_locations.") + + def test_shapesanity_names(self): + names_length = len(self.world.shapesanity_names) + locations_length = len([0 for loc in self.multiworld.get_locations(self.player) if "Shapesanity" in loc.name]) + self.assertEqual(names_length, locations_length, + f"The amount of shapesanity names ({names_length}) does not match the amount of included " + + f"shapesanity locations ({locations_length}).") + self.assertTrue(SHAPESANITY.full(SHAPESANITY.uncolored, SHAPESANITY.circle) in self.world.shapesanity_names, + "Uncolored Circle is guaranteed but was not found in shapesanity_names.") + + def test_efficiency_iii_no_softlock(self): + if self.world.options.goal == GOALS.efficiency_iii: + for item in self.multiworld.itempool: + self.assertFalse(item.name.endswith("Upgrade Trap"), + "Item pool contains an upgrade trap, which could make the efficiency_iii goal " + "unreachable if collected.") + + +class TestGlobalOptionsImport(TestCase): + + def test_global_options_import(self): + self.assertTrue(isinstance(max_levels_and_upgrades, int), f"The global option max_levels_and_upgrades is not " + + f"an integer, but instead a " + + f"{type(max_levels_and_upgrades)}.") + self.assertTrue(max_levels_and_upgrades >= 27, f"max_levels_and_upgrades must be at least 27, but is " + + f"{max_levels_and_upgrades} instead.") + self.assertTrue(isinstance(max_shapesanity, int), f"The global option max_shapesanity is not an integer, but " + + f"instead a {type(max_levels_and_upgrades)}.") + self.assertTrue(max_shapesanity >= 4, f"max_shapesanity must be at least 4, but is " + + f"{max_levels_and_upgrades} instead.") + + +class TestMinimum(ShapezTestBase): + options = options_presets["Minimum checks"] + + +class TestMaximum(ShapezTestBase): + options = options_presets["Maximum checks"] + + +class TestRestrictive(ShapezTestBase): + options = options_presets["Restrictive start"] + + +class TestAllRelevantOptions1(ShapezTestBase): + options = { + "goal": GOALS.vanilla, + "randomize_level_requirements": False, + "randomize_upgrade_requirements": False, + "complexity_growth_gradient": "0.1234", + "early_balancer_tunnel_and_trash": "none", + "lock_belt_and_extractor": True, + "include_achievements": True, + "exclude_softlock_achievements": False, + "exclude_long_playtime_achievements": False, + "exclude_progression_unreasonable": True, + "shapesanity_amount": max_shapesanity, + "traps_percentage": "random" + } + + +class TestAllRelevantOptions2(ShapezTestBase): + options = { + "goal": GOALS.mam, + "goal_amount": max_levels_and_upgrades, + "randomize_level_requirements": True, + "randomize_upgrade_requirements": True, + "randomize_level_logic": OPTIONS.logic_random_steps, + "randomize_upgrade_logic": OPTIONS.logic_vanilla_like, + "complexity_growth_gradient": "2", + "early_balancer_tunnel_and_trash": OPTIONS.buildings_5, + "lock_belt_and_extractor": False, + "include_achievements": True, + "exclude_softlock_achievements": False, + "exclude_long_playtime_achievements": False, + "exclude_progression_unreasonable": False, + "shapesanity_amount": 4, + "traps_percentage": 0 + } + + +class TestAllRelevantOptions3(ShapezTestBase): + options = { + "goal": GOALS.even_fasterer, + "goal_amount": max_levels_and_upgrades, + "randomize_level_requirements": True, + "randomize_upgrade_requirements": True, + "randomize_level_logic": f"{OPTIONS.logic_vanilla}_shuffled", + "randomize_upgrade_logic": OPTIONS.logic_linear, + "complexity_growth_gradient": "1e-003", + "early_balancer_tunnel_and_trash": OPTIONS.buildings_3, + "lock_belt_and_extractor": False, + "include_achievements": True, + "exclude_softlock_achievements": True, + "exclude_long_playtime_achievements": True, + "shapesanity_amount": "random", + "traps_percentage": 100, + "include_whacky_upgrades": True, + "split_inventory_draining_trap": True + } + + +class TestAllRelevantOptions4(ShapezTestBase): + options = { + "goal": GOALS.efficiency_iii, + "randomize_level_requirements": True, + "randomize_upgrade_requirements": True, + "randomize_level_logic": f"{OPTIONS.logic_stretched}_shuffled", + "randomize_upgrade_logic": OPTIONS.logic_category, + "early_balancer_tunnel_and_trash": OPTIONS.sphere_1, + "lock_belt_and_extractor": False, + "include_achievements": True, + "exclude_softlock_achievements": True, + "exclude_long_playtime_achievements": True, + "shapesanity_amount": "random", + "traps_percentage": "random", + "include_whacky_upgrades": True, + } + + +class TestAllRelevantOptions5(ShapezTestBase): + options = { + "goal": GOALS.mam, + "goal_amount": "random-range-27-500", + "randomize_level_requirements": True, + "randomize_upgrade_requirements": True, + "randomize_level_logic": f"{OPTIONS.logic_quick}_shuffled", + "randomize_upgrade_logic": OPTIONS.logic_category_random, + "lock_belt_and_extractor": False, + "include_achievements": True, + "exclude_softlock_achievements": True, + "exclude_long_playtime_achievements": True, + "shapesanity_amount": "random", + "traps_percentage": 100, + "split_inventory_draining_trap": False + } + + +class TestAllRelevantOptions6(ShapezTestBase): + options = { + "goal": GOALS.mam, + "goal_amount": "random-range-27-500", + "randomize_level_requirements": True, + "randomize_upgrade_requirements": True, + "randomize_level_logic": OPTIONS.logic_hardcore, + "randomize_upgrade_logic": OPTIONS.logic_hardcore, + "lock_belt_and_extractor": False, + "include_achievements": False, + "shapesanity_amount": "random", + "traps_percentage": "random" + } From 955a86803fe42006a3fd4d2e3915183a849a5df2 Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Wed, 21 May 2025 11:02:30 -0400 Subject: [PATCH 0437/1218] Super Mario Land 2: Implement New Game (#2730) Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: alchav --- README.md | 1 + docs/CODEOWNERS | 3 + worlds/marioland2/LICENSE | 21 + worlds/marioland2/__init__.py | 449 ++++++++ worlds/marioland2/basepatch.bsdiff4 | Bin 0 -> 1241 bytes worlds/marioland2/client.py | 250 ++++ .../marioland2/docs/en_Super Mario Land 2.md | 64 ++ worlds/marioland2/docs/setup_en.md | 75 ++ worlds/marioland2/items.py | 79 ++ worlds/marioland2/locations.py | 498 ++++++++ worlds/marioland2/logic.py | 608 ++++++++++ worlds/marioland2/options.py | 198 ++++ worlds/marioland2/rom.py | 146 +++ worlds/marioland2/rom_addresses.py | 39 + worlds/marioland2/sprite_randomizer.py | 131 +++ worlds/marioland2/sprites.py | 1016 +++++++++++++++++ 16 files changed, 3578 insertions(+) create mode 100644 worlds/marioland2/LICENSE create mode 100644 worlds/marioland2/__init__.py create mode 100644 worlds/marioland2/basepatch.bsdiff4 create mode 100644 worlds/marioland2/client.py create mode 100644 worlds/marioland2/docs/en_Super Mario Land 2.md create mode 100644 worlds/marioland2/docs/setup_en.md create mode 100644 worlds/marioland2/items.py create mode 100644 worlds/marioland2/locations.py create mode 100644 worlds/marioland2/logic.py create mode 100644 worlds/marioland2/options.py create mode 100644 worlds/marioland2/rom.py create mode 100644 worlds/marioland2/rom_addresses.py create mode 100644 worlds/marioland2/sprite_randomizer.py create mode 100644 worlds/marioland2/sprites.py diff --git a/README.md b/README.md index 861a6eed1d27..84e62b15280a 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ Currently, the following games are supported: * Civilization VI * The Legend of Zelda: The Wind Waker * Jak and Daxter: The Precursor Legacy +* Super Mario Land 2: 6 Golden Coins For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index ca19d27da906..2289daad072a 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -178,6 +178,9 @@ # Super Mario 64 /worlds/sm64ex/ @N00byKing +# Super Mario Land 2: 6 Golden Coins +/worlds/marioland2/ @Alchav + # Super Mario World /worlds/smw/ @PoryGone diff --git a/worlds/marioland2/LICENSE b/worlds/marioland2/LICENSE new file mode 100644 index 000000000000..7ac515f432f1 --- /dev/null +++ b/worlds/marioland2/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-2023 Alex "Alchav" Avery + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/worlds/marioland2/__init__.py b/worlds/marioland2/__init__.py new file mode 100644 index 000000000000..ea1354db6e65 --- /dev/null +++ b/worlds/marioland2/__init__.py @@ -0,0 +1,449 @@ +import base64 +import Utils +import settings +from copy import deepcopy + +from worlds.AutoWorld import World, WebWorld +from BaseClasses import Region, Location, Item, ItemClassification, Tutorial + +from . import client +from .rom import generate_output, SuperMarioLand2ProcedurePatch +from .options import SML2Options +from .locations import (locations, location_name_to_id, level_name_to_id, level_id_to_name, START_IDS, coins_coords, + auto_scroll_max) +from .items import items +from .sprites import level_sprites +from .sprite_randomizer import randomize_enemies, randomize_platforms +from .logic import has_pipe_up, has_pipe_down, has_pipe_left, has_pipe_right, has_level_progression, is_auto_scroll +from . import logic + + +class MarioLand2Settings(settings.Group): + class SML2RomFile(settings.UserFilePath): + """File name of the Super Mario Land 2 1.0 ROM""" + description = "Super Mario Land 2 - 6 Golden Coins (USA, Europe) 1.0 ROM File" + copy_to = "Super Mario Land 2 - 6 Golden Coins (USA, Europe).gb" + md5s = [SuperMarioLand2ProcedurePatch.hash] + + rom_file: SML2RomFile = SML2RomFile(SML2RomFile.copy_to) + + +class MarioLand2WebWorld(WebWorld): + setup_en = Tutorial( + "Multiworld Setup Guide", + "A guide to playing Super Mario Land 2 with Archipelago.", + "English", + "setup_en.md", + "setup/en", + ["Alchav"] + ) + + tutorials = [setup_en] + + +class MarioLand2World(World): + """Super Mario Land 2 is a classic platformer that follows Mario on a quest to reclaim his castle from the + villainous Wario. This iconic game features 32 levels, unique power-ups, and introduces Wario as Mario's + arch-rival.""" # -ChatGPT + + game = "Super Mario Land 2" + + settings_key = "sml2_options" + settings: MarioLand2Settings + + location_name_to_id = location_name_to_id + item_name_to_id = {item_name: ID for ID, item_name in enumerate(items, START_IDS)} + + web = MarioLand2WebWorld() + + item_name_groups = { + "Level Progression": { + item_name for item_name in items if item_name.endswith(("Progression", "Secret", "Secret 1", "Secret 2")) + and "Auto Scroll" not in item_name + }, + "Bells": {item_name for item_name in items if "Bell" in item_name}, + "Golden Coins": {"Mario Coin", "Macro Coin", "Space Coin", "Tree Coin", "Turtle Coin", "Pumpkin Coin"}, + "Coins": {"1 Coin", *{f"{i} Coins" for i in range(2, 169)}}, + "Powerups": {"Mushroom", "Fire Flower", "Carrot"}, + "Difficulties": {"Easy Mode", "Normal Mode"}, + "Auto Scroll Traps": {item_name for item_name in items + if "Auto Scroll" in item_name and "Cancel" not in item_name}, + "Cancel Auto Scrolls": {item_name for item_name in items if "Cancel Auto Scroll" in item_name}, + } + + location_name_groups = { + "Bosses": { + "Tree Zone 5 - Boss", "Space Zone 2 - Boss", "Macro Zone 4 - Boss", + "Pumpkin Zone 4 - Boss", "Mario Zone 4 - Boss", "Turtle Zone 3 - Boss" + }, + "Normal Exits": {location for location in locations if locations[location]["type"] == "level"}, + "Secret Exits": {location for location in locations if locations[location]["type"] == "secret"}, + "Bells": {location for location in locations if locations[location]["type"] == "bell"}, + "Coins": {location for location in location_name_to_id if "Coin" in location} + } + + options_dataclass = SML2Options + options: SML2Options + + generate_output = generate_output + + def __init__(self, world, player: int): + super().__init__(world, player) + self.auto_scroll_levels = [] + self.num_coin_locations = [] + self.max_coin_locations = {} + self.sprite_data = {} + self.coin_fragments_required = 0 + + def generate_early(self): + self.sprite_data = deepcopy(level_sprites) + if self.options.randomize_enemies: + randomize_enemies(self.sprite_data, self.random) + if self.options.randomize_platforms: + randomize_platforms(self.sprite_data, self.random) + + if self.options.marios_castle_midway_bell: + self.sprite_data["Mario's Castle"][35]["sprite"] = "Midway Bell" + + if self.options.auto_scroll_chances == "vanilla": + self.auto_scroll_levels = [int(i in [19, 25, 30]) for i in range(32)] + else: + self.auto_scroll_levels = [int(self.random.randint(1, 100) <= self.options.auto_scroll_chances) + for _ in range(32)] + + self.auto_scroll_levels[level_name_to_id["Mario's Castle"]] = 0 + unbeatable_scroll_levels = ["Tree Zone 3", "Macro Zone 2", "Space Zone 1", "Turtle Zone 2", "Pumpkin Zone 2"] + if not self.options.shuffle_midway_bells: + unbeatable_scroll_levels.append("Pumpkin Zone 1") + for level, i in enumerate(self.auto_scroll_levels): + if i == 1: + if self.options.auto_scroll_mode in ("global_cancel_item", "level_cancel_items"): + self.auto_scroll_levels[level] = 2 + elif self.options.auto_scroll_mode == "chaos": + if (self.options.accessibility == "full" + and level_id_to_name[level] in unbeatable_scroll_levels): + self.auto_scroll_levels[level] = 2 + else: + self.auto_scroll_levels[level] = self.random.randint(1, 3) + elif (self.options.accessibility == "full" + and level_id_to_name[level] in unbeatable_scroll_levels): + self.auto_scroll_levels[level] = 0 + if self.auto_scroll_levels[level] == 1 and "trap" in self.options.auto_scroll_mode.current_key: + self.auto_scroll_levels[level] = 3 + + def create_regions(self): + menu_region = Region("Menu", self.player, self.multiworld) + self.multiworld.regions.append(menu_region) + created_regions = [] + for location_name, data in locations.items(): + region_name = location_name.split(" -")[0] + if region_name in created_regions: + region = self.multiworld.get_region(region_name, self.player) + else: + region = Region(region_name, self.player, self.multiworld) + if region_name == "Tree Zone Secret Course": + region_to_connect = self.multiworld.get_region("Tree Zone 2", self.player) + elif region_name == "Space Zone Secret Course": + region_to_connect = self.multiworld.get_region("Space Zone 1", self.player) + elif region_name == "Macro Zone Secret Course": + region_to_connect = self.multiworld.get_region("Macro Zone 1", self.player) + elif region_name == "Pumpkin Zone Secret Course 1": + region_to_connect = self.multiworld.get_region("Pumpkin Zone 2", self.player) + elif region_name == "Pumpkin Zone Secret Course 2": + region_to_connect = self.multiworld.get_region("Pumpkin Zone 3", self.player) + elif region_name == "Turtle Zone Secret Course": + region_to_connect = self.multiworld.get_region("Turtle Zone 2", self.player) + elif region_name.split(" ")[-1].isdigit() and int(region_name.split(" ")[-1]) > 1: + region_to_connect = self.multiworld.get_region(" ".join(region_name.split(" ")[:2]) + + f" {int(region_name.split(' ')[2]) - 1}", + self.player) + else: + region_to_connect = menu_region + region_to_connect.connect(region) + self.multiworld.regions.append(region) + created_regions.append(region_name) + + if location_name == "Mario's Castle - Midway Bell" and not self.options.marios_castle_midway_bell: + continue + region.locations.append(MarioLand2Location(self.player, location_name, + self.location_name_to_id[location_name], region)) + self.multiworld.get_region("Macro Zone Secret Course", self.player).connect( + self.multiworld.get_region("Macro Zone 4", self.player)) + self.multiworld.get_region("Macro Zone 4", self.player).connect( + self.multiworld.get_region("Macro Zone Secret Course", self.player)) + + castle = self.multiworld.get_region("Mario's Castle", self.player) + wario = MarioLand2Location(self.player, "Mario's Castle - Wario", parent=castle) + castle.locations.append(wario) + wario.place_locked_item(MarioLand2Item("Wario Defeated", ItemClassification.progression, None, self.player)) + + if self.options.coinsanity: + coinsanity_checks = self.options.coinsanity_checks.value + self.num_coin_locations = [[region, 1] for region in created_regions if region != "Mario's Castle"] + self.max_coin_locations = {region: len(coins_coords[region]) for region in created_regions + if region != "Mario's Castle"} + if self.options.accessibility == "full" or self.options.auto_scroll_mode == "always": + for level in self.max_coin_locations: + if level in auto_scroll_max and self.auto_scroll_levels[level_name_to_id[level]] in (1, 3): + if isinstance(auto_scroll_max[level], tuple): + self.max_coin_locations[level] = min( + auto_scroll_max[level][int(self.options.shuffle_midway_bells.value)], + self.max_coin_locations[level]) + else: + self.max_coin_locations[level] = min(auto_scroll_max[level], self.max_coin_locations[level]) + coinsanity_checks = min(sum(self.max_coin_locations.values()), coinsanity_checks) + for i in range(coinsanity_checks - 31): + self.num_coin_locations.sort(key=lambda region: self.max_coin_locations[region[0]] / region[1]) + self.num_coin_locations[-1][1] += 1 + coin_locations = [] + for level, coins in self.num_coin_locations: + if self.max_coin_locations[level]: + coin_thresholds = self.random.sample(range(1, self.max_coin_locations[level] + 1), coins) + coin_locations += [f"{level} - {i} Coin{'s' if i > 1 else ''}" for i in coin_thresholds] + for location_name in coin_locations: + region = self.multiworld.get_region(location_name.split(" -")[0], self.player) + region.locations.append(MarioLand2Location(self.player, location_name, + self.location_name_to_id[location_name], parent=region)) + + def set_rules(self): + entrance_rules = { + "Menu -> Space Zone 1": lambda state: state.has("Hippo Bubble", self.player) + or (state.has("Carrot", self.player) + and not is_auto_scroll(state, self.player, "Hippo Zone")), + "Space Zone 1 -> Space Zone Secret Course": lambda state: state.has("Space Zone Secret", self.player), + "Space Zone 1 -> Space Zone 2": lambda state: has_level_progression(state, "Space Zone Progression", self.player), + "Tree Zone 1 -> Tree Zone 2": lambda state: has_level_progression(state, "Tree Zone Progression", self.player), + "Tree Zone 2 -> Tree Zone Secret Course": lambda state: state.has("Tree Zone Secret", self.player), + "Tree Zone 2 -> Tree Zone 3": lambda state: has_level_progression(state, "Tree Zone Progression", self.player, 2), + "Tree Zone 4 -> Tree Zone 5": lambda state: has_level_progression(state, "Tree Zone Progression", self.player, 3), + "Macro Zone 1 -> Macro Zone Secret Course": lambda state: state.has("Macro Zone Secret 1", self.player), + "Macro Zone Secret Course -> Macro Zone 4": lambda state: state.has("Macro Zone Secret 2", self.player), + "Macro Zone 1 -> Macro Zone 2": lambda state: has_level_progression(state, "Macro Zone Progression", self.player), + "Macro Zone 2 -> Macro Zone 3": lambda state: has_level_progression(state, "Macro Zone Progression", self.player, 2), + "Macro Zone 3 -> Macro Zone 4": lambda state: has_level_progression(state, "Macro Zone Progression", self.player, 3), + "Macro Zone 4 -> Macro Zone Secret Course": lambda state: state.has("Macro Zone Secret 2", self.player), + "Pumpkin Zone 1 -> Pumpkin Zone 2": lambda state: has_level_progression(state, "Pumpkin Zone Progression", self.player), + "Pumpkin Zone 2 -> Pumpkin Zone Secret Course 1": lambda state: state.has("Pumpkin Zone Secret 1", self.player), + "Pumpkin Zone 2 -> Pumpkin Zone 3": lambda state: has_level_progression(state, "Pumpkin Zone Progression", self.player, 2), + "Pumpkin Zone 3 -> Pumpkin Zone Secret Course 2": lambda state: state.has("Pumpkin Zone Secret 2", self.player), + "Pumpkin Zone 3 -> Pumpkin Zone 4": lambda state: has_level_progression(state, "Pumpkin Zone Progression", self.player, 3), + "Mario Zone 1 -> Mario Zone 2": lambda state: has_level_progression(state, "Mario Zone Progression", self.player), + "Mario Zone 2 -> Mario Zone 3": lambda state: has_level_progression(state, "Mario Zone Progression", self.player, 2), + "Mario Zone 3 -> Mario Zone 4": lambda state: has_level_progression(state, "Mario Zone Progression", self.player, 3), + "Turtle Zone 1 -> Turtle Zone 2": lambda state: has_level_progression(state, "Turtle Zone Progression", self.player), + "Turtle Zone 2 -> Turtle Zone Secret Course": lambda state: state.has("Turtle Zone Secret", self.player), + "Turtle Zone 2 -> Turtle Zone 3": lambda state: has_level_progression(state, "Turtle Zone Progression", self.player, 2), + } + + if self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + # Require the other coins just to ensure they are being added to start inventory properly, + # and so they show up in Playthrough as required + entrance_rules["Menu -> Mario's Castle"] = lambda state: (state.has_all( + ["Tree Coin", "Space Coin", "Macro Coin", "Pumpkin Coin", "Turtle Coin"], self.player) + and state.has("Mario Coin Fragment", self.player, self.coin_fragments_required)) + else: + entrance_rules["Menu -> Mario's Castle"] = lambda state: state.has_from_list_unique([ + "Tree Coin", "Space Coin", "Macro Coin", "Pumpkin Coin", "Mario Coin", "Turtle Coin" + ], self.player, self.options.required_golden_coins) + + + for entrance, rule in entrance_rules.items(): + self.multiworld.get_entrance(entrance, self.player).access_rule = rule + + for location in self.multiworld.get_locations(self.player): + if location.name.endswith(("Coins", "Coin")): + rule = getattr(logic, location.parent_region.name.lower().replace(" ", "_") + "_coins", None) + if rule: + coins = int(location.name.split(" ")[-2]) + location.access_rule = lambda state, coin_rule=rule, num_coins=coins: \ + coin_rule(state, self.player, num_coins) + else: + rule = getattr(logic, location.name.lower().replace( + " - ", "_").replace(" ", "_").replace("'", ""), None) + if rule: + location.access_rule = lambda state, loc_rule=rule: loc_rule(state, self.player) + self.multiworld.completion_condition[self.player] = lambda state: state.has("Wario Defeated", self.player) + + def create_items(self): + item_counts = { + "Space Zone Progression": 1, + "Space Zone Secret": 1, + "Tree Zone Progression": 3, + "Tree Zone Secret": 1, + "Macro Zone Progression": 3, + "Macro Zone Secret 1": 1, + "Macro Zone Secret 2": 1, + "Pumpkin Zone Progression": 3, + "Pumpkin Zone Secret 1": 1, + "Pumpkin Zone Secret 2": 1, + "Mario Zone Progression": 3, + "Turtle Zone Progression": 2, + "Turtle Zone Secret": 1, + "Mushroom": 1, + "Fire Flower": 1, + "Carrot": 1, + "Space Physics": 1, + "Hippo Bubble": 1, + "Water Physics": 1, + "Super Star Duration Increase": 2, + "Mario Coin Fragment": 0, + } + + if self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + # There are 5 Zone Progression items that can be condensed. + item_counts["Mario Coin Fragment"] = 1 + ((5 * self.options.mario_coin_fragment_percentage) // 100) + + if self.options.coinsanity: + coin_count = sum([level[1] for level in self.num_coin_locations]) + max_coins = sum(self.max_coin_locations.values()) + if self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + removed_coins = (coin_count * self.options.mario_coin_fragment_percentage) // 100 + coin_count -= removed_coins + item_counts["Mario Coin Fragment"] += removed_coins + # Randomly remove some coin items for variety + coin_count -= (coin_count // self.random.randint(100, max(100, coin_count))) + + if coin_count: + coin_bundle_sizes = [max_coins // coin_count] * coin_count + remainder = max_coins - sum(coin_bundle_sizes) + for i in range(remainder): + coin_bundle_sizes[i] += 1 + for a, b in zip(range(1, len(coin_bundle_sizes), 2), range(2, len(coin_bundle_sizes), 2)): + split = self.random.randint(1, coin_bundle_sizes[a] + coin_bundle_sizes[b] - 1) + coin_bundle_sizes[a], coin_bundle_sizes[b] = split, coin_bundle_sizes[a] + coin_bundle_sizes[b] - split + for coin_bundle_size in coin_bundle_sizes: + item_name = f"{coin_bundle_size} Coin{'s' if coin_bundle_size > 1 else ''}" + if item_name in item_counts: + item_counts[item_name] += 1 + else: + item_counts[item_name] = 1 + + if self.options.shuffle_golden_coins == "shuffle": + for item in self.item_name_groups["Golden Coins"]: + item_counts[item] = 1 + elif self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + for item in ("Tree Coin", "Space Coin", "Macro Coin", "Pumpkin Coin", "Turtle Coin"): + self.multiworld.push_precollected(self.create_item(item)) + else: + for item, location_name in ( + ("Mario Coin", "Mario Zone 4 - Boss"), + ("Tree Coin", "Tree Zone 5 - Boss"), + ("Space Coin", "Space Zone 2 - Boss"), + ("Macro Coin", "Macro Zone 4 - Boss"), + ("Pumpkin Coin", "Pumpkin Zone 4 - Boss"), + ("Turtle Coin", "Turtle Zone 3 - Boss") + ): + location = self.multiworld.get_location(location_name, self.player) + location.place_locked_item(self.create_item(item)) + location.address = None + location.item.code = None + + if self.options.shuffle_midway_bells: + for item in [item for item in items if "Midway Bell" in item]: + if item != "Mario's Castle Midway Bell" or self.options.marios_castle_midway_bell: + item_counts[item] = 1 + + if self.options.difficulty_mode == "easy_to_normal": + item_counts["Normal Mode"] = 1 + elif self.options.difficulty_mode == "normal_to_easy": + item_counts["Easy Mode"] = 1 + + if self.options.shuffle_pipe_traversal == "single": + item_counts["Pipe Traversal"] = 1 + elif self.options.shuffle_pipe_traversal == "split": + item_counts["Pipe Traversal - Right"] = 1 + item_counts["Pipe Traversal - Left"] = 1 + item_counts["Pipe Traversal - Up"] = 1 + item_counts["Pipe Traversal - Down"] = 1 + else: + self.multiworld.push_precollected(self.create_item("Pipe Traversal")) + + if any(self.auto_scroll_levels): + if self.options.auto_scroll_mode == "global_trap_item": + item_counts["Auto Scroll"] = 1 + elif self.options.auto_scroll_mode == "global_cancel_item": + item_counts["Cancel Auto Scroll"] = 1 + else: + for level, i in enumerate(self.auto_scroll_levels): + if i == 3: + item_counts[f"Auto Scroll - {level_id_to_name[level]}"] = 1 + elif i == 2: + item_counts[f"Cancel Auto Scroll - {level_id_to_name[level]}"] = 1 + + for item in self.multiworld.precollected_items[self.player]: + if item.name in item_counts and item_counts[item.name] > 0: + item_counts[item.name] -= 1 + + location_count = len(self.multiworld.get_unfilled_locations(self.player)) + items_to_add = location_count - sum(item_counts.values()) + if items_to_add > 0: + mario_coin_frags = 0 + if self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + mario_coin_frags = (items_to_add * self.options.mario_coin_fragment_percentage) // 100 + item_counts["Mario Coin Fragment"] += mario_coin_frags + item_counts["Super Star Duration Increase"] += items_to_add - mario_coin_frags + elif items_to_add < 0: + if self.options.coinsanity: + for i in range(1, 168): + coin_name = f"{i} Coin{'s' if i > 1 else ''}" + if coin_name in item_counts: + amount_to_remove = min(-items_to_add, item_counts[coin_name]) + item_counts[coin_name] -= amount_to_remove + items_to_add += amount_to_remove + if items_to_add >= 0: + break + + double_progression_items = ["Tree Zone Progression", "Macro Zone Progression", "Pumpkin Zone Progression", + "Mario Zone Progression", "Turtle Zone Progression"] + self.random.shuffle(double_progression_items) + while sum(item_counts.values()) > location_count: + if double_progression_items: + double_progression_item = double_progression_items.pop() + item_counts[double_progression_item] -= 2 + item_counts[double_progression_item + " x2"] = 1 + continue + if self.options.auto_scroll_mode in ("level_trap_items", "level_cancel_items", + "chaos"): + auto_scroll_item = self.random.choice([item for item in item_counts if "Auto Scroll" in item]) + level = auto_scroll_item.split("- ")[1] + self.auto_scroll_levels[level_name_to_id[level]] = 0 + del item_counts[auto_scroll_item] + continue + raise Exception(f"Too many items in the item pool for Super Mario Land 2 player {self.player_name}") + # item = self.random.choice(list(item_counts)) + # item_counts[item] -= 1 + # if item_counts[item] == 0: + # del item_counts[item] + # self.multiworld.push_precollected(self.create_item(item)) + + self.coin_fragments_required = max((item_counts["Mario Coin Fragment"] + * self.options.mario_coin_fragments_required_percentage) // 100, 1) + + for item_name, count in item_counts.items(): + self.multiworld.itempool += [self.create_item(item_name) for _ in range(count)] + + def fill_slot_data(self): + return { + "energy_link": self.options.energy_link.value + } + + def create_item(self, name: str) -> Item: + return MarioLand2Item(name, items[name], self.item_name_to_id[name], self.player) + + def get_filler_item_name(self): + return "1 Coin" + + def modify_multidata(self, multidata: dict): + rom_name = bytearray(f'AP{Utils.__version__.replace(".", "")[0:3]}_{self.player}_{self.multiworld.seed:11}\0', + 'utf8')[:21] + rom_name.extend([0] * (21 - len(rom_name))) + new_name = base64.b64encode(bytes(rom_name)).decode() + multidata["connect_names"][new_name] = multidata["connect_names"][self.player_name] + + +class MarioLand2Location(Location): + game = "Super Mario Land 2" + + +class MarioLand2Item(Item): + game = "Super Mario Land 2" diff --git a/worlds/marioland2/basepatch.bsdiff4 b/worlds/marioland2/basepatch.bsdiff4 new file mode 100644 index 0000000000000000000000000000000000000000..a8818419a6b8896c9621fe26d74f82f9cc173853 GIT binary patch literal 1241 zcmV;~1Sb1JQ$$HdMl>*h000000002;0ssI200000KnMT;0000&T4*^jL0KkKS#~;f zH2?ri-+TYPfItwC00;sA0sue|7yyI_2m$~=0ssL3pa4`wJg2Fqh9G2Vp|l2+*q|9b zMu0K`A_X-_ndNQ|xy<#0GXMw=V&WbO0F;~vXAOI&Z4iip`XKa#LRcZH=$@MVraG@aVbm(eAT4*^jL0KkKStk;|jsO5GfB*mgeR|_@_g4L)1?k2JXhQsW^)ulW z!LfZ*OhoVAeg41#R|J_&q6HMmrXxTAWCo1@0iZMu0ie*((?9?XJw`zFG01XW^&;S4c27mwn01W}482|vgpaG--qwh9;N-GBm_7Fal)20Wu93 z00J^$GGGaWV39>JO&X0f@`tIDLnB6-00u)(Pyl2A00E#f0BPy~(9j2yQX3xJ2~$2@ zJ21$J6O9XSlL(A791}By!FMS-oFx`6rBp!vM>V^ayeN(};1e_6@ZGDG(`r~iZ!;Q^ zMHZ5>ve8om-Vj}fi%PJ;}gjg%dr*=CqmQWYu zgTgtC547Q`uYzC)WxP*Qcz{sPTly|=0;Q&s=%NiAK;-3@@(`fNtce(jHI4-XW&aKu zq|H;wNz2Nj&_%)Zbdd2V3|ie?LD+K6BSL+&i3uc<+RILq>1R)dG)_#E42S^+gkiIU z>b0$Fs?2=^5Ln39#T(}EAcat8Plw~#|D;I7CS)Srw{i-1p8;7pc*#A4RdgD?Id@Pe z0N<=ioatGZ4ezWZ5+|f65E_RL8|#*V(*_P(h^s^%2?#KRi%0SmC+S2N$cGo}RGoki zUoK-7xV_OUJKUZmaagaINa!6XATHP~r+y2y`+!yM9f^HniTRU-#uOwK`7URXh{WR( zanFs_L*1<(7VU+4#tfGNfC6A(0fbyMa4Zpg&BpE%Zw-)oKNw0BvXY60&y$&;6hqxIWa+5CR15%ul&LQ z0F!_J`JjNrbG6`we$?W{;qZam_CN#xR6y7O3~T^EVh}_bumJg{h*SV*05k@G0002c z0017Eo~NV{H5m{90iXZ?0ilop000^RB&McBdYLpd&@=!5Gyni-8V#iNJws|{rO^pm zct}as+zv=dvdTC&i5@2fZTE?a?^J>sH4{SvGYl6Sxz^>Ot@2fCHB-zcW_&+{Oe2~p zF3qD?UvhJ@04vvn@PH>Z$RR;)$jdU}J%PxtDGX3U!oXr4Ab~y#5k5_j_=q9$za4!c zEM!&}fXMM?Z(nbHD5yXqcJ(@HEOTy?pXs#&NY@$6_Vk42ez{qOWD?!#5g(nIKRzx* zWfOwyi9L{oGLlOmr~1&zbxG>AL;?VY)3H1%;sBTk2&?*#iRFSZAL8yvrwS4c)&H14 DQEB>< literal 0 HcmV?d00001 diff --git a/worlds/marioland2/client.py b/worlds/marioland2/client.py new file mode 100644 index 000000000000..41e6468f9393 --- /dev/null +++ b/worlds/marioland2/client.py @@ -0,0 +1,250 @@ +import base64 +import logging + +from NetUtils import ClientStatus +from worlds._bizhawk.client import BizHawkClient +from worlds._bizhawk import read, write, guarded_write + +from .rom_addresses import rom_addresses + +logger = logging.getLogger("Client") + +BANK_EXCHANGE_RATE = 20000000000 + +overworld_music = (0x05, 0x06, 0x0D, 0x0E, 0x10, 0x12, 0x1B, 0x1C, 0x1E) + +class MarioLand2Client(BizHawkClient): + system = ("GB", "SGB") + patch_suffix = ".apsml2" + game = "Super Mario Land 2" + + def __init__(self): + super().__init__() + self.locations_array = [] + self.previous_level = None + + async def validate_rom(self, ctx): + game_name = await read(ctx.bizhawk_ctx, [(0x134, 10, "ROM")]) + game_name = game_name[0].decode("ascii") + if game_name == "MARIOLAND2": + ctx.game = self.game + ctx.items_handling = 0b111 + return True + return False + + async def set_auth(self, ctx): + auth_name = await read(ctx.bizhawk_ctx, [(0x77777, 21, "ROM")]) + auth_name = base64.b64encode(auth_name[0]).decode() + ctx.auth = auth_name + + async def game_watcher(self, ctx): + from . import START_IDS + from .items import items + from .locations import locations, level_id_to_name, coins_coords, location_name_to_id + + (game_loaded_check, level_data, music, auto_scroll_levels, current_level, + midway_point, bcd_lives, num_items_received, coins, options) = \ + await read(ctx.bizhawk_ctx, [(0x0046, 10, "CartRAM"), (0x0848, 42, "CartRAM"), (0x0469, 1, "CartRAM"), + (rom_addresses["Auto_Scroll_Levels_B"], 32, "ROM"), + (0x0269, 1, "CartRAM"), (0x02A0, 1, "CartRAM"), (0x022C, 1, "CartRAM"), + (0x00F0, 2, "CartRAM"), (0x0262, 2, "CartRAM"), + (rom_addresses["Coins_Required"], 8, "ROM")]) + + coins_required = int.from_bytes(options[:2], "big") + difficulty_mode = options[2] + star_count = int.from_bytes(options[3:5], "big") + midway_bells = options[5] + energy_link = options[6] + coin_mode = options[7] + + current_level = int.from_bytes(current_level, "big") + auto_scroll_levels = list(auto_scroll_levels) + midway_point = int.from_bytes(midway_point, "big") + music = int.from_bytes(music, "big") + level_data = list(level_data) + lives = bcd_lives.hex() + num_items_received = int.from_bytes(num_items_received, "big") + if num_items_received == 0xFFFF: + num_items_received = 0 + + items_received = [list(items.keys())[item.item - START_IDS] for item in ctx.items_received] + write_num_items_received = len(items_received).to_bytes(2, "big") + + level_progression = { + "Space Zone Progression", + "Tree Zone Progression", + "Macro Zone Progression", + "Pumpkin Zone Progression", + "Mario Zone Progression", + "Turtle Zone Progression", + } + for level_item in level_progression: + for _ in range(items_received.count(level_item + " x2")): + items_received += ([level_item] * 2) + + if "Pipe Traversal" in items_received: + items_received += ["Pipe Traversal - Left", "Pipe Traversal - Right", + "Pipe Traversal - Up", "Pipe Traversal - Down"] + + if coin_mode == 2 and items_received.count("Mario Coin Fragment") >= coins_required: + items_received.append("Mario Coin") + + if current_level == 255 and self.previous_level != 255: + if coin_mode < 2: + logger.info(f"Golden Coins required: {coins_required}") + else: + logger.info(f"Mario Coin Fragments required: {coins_required}. " + f"You have {items_received.count('Mario Coin Fragment')}") + self.previous_level = current_level + + # There is no music in the title screen demos, this is how we guard against anything in the demos registering. + # There is also no music at the door to Mario's Castle, which is why the above is before this check. + if game_loaded_check != b'\x124Vx\xff\xff\xff\xff\xff\xff' or music == 0: + return + + locations_checked = [] + if current_level in level_id_to_name: + level_name = level_id_to_name[current_level] + coin_tile_data = await read(ctx.bizhawk_ctx, [(0xB000 + ((coords[1] * 256) + coords[0]), 1, "System Bus") + for coords in coins_coords[level_name]]) + num_coins = len([tile[0] for tile in coin_tile_data if tile[0] in (0x7f, 0x60, 0x07)]) + locations_checked = [location_name_to_id[f"{level_name} - {i} Coin{'s' if i > 1 else ''}"] + for i in range(1, num_coins + 1)] + + new_lives = int(lives) + energy_link_add = None + if energy_link: + if new_lives == 0: + if (f"EnergyLink{ctx.team}" in ctx.stored_data + and ctx.stored_data[f"EnergyLink{ctx.team}"] + and ctx.stored_data[f"EnergyLink{ctx.team}"] >= BANK_EXCHANGE_RATE): + new_lives = 1 + energy_link_add = -BANK_EXCHANGE_RATE + elif new_lives > 1: + energy_link_add = BANK_EXCHANGE_RATE * (new_lives - 1) + new_lives = 1 + # Convert back to binary-coded-decimal + new_lives = int(str(new_lives), 16) + + new_coins = coins.hex() + new_coins = int(new_coins[2:] + new_coins[:2]) + for item in items_received[num_items_received:]: + if item.endswith("Coins") or item == "1 Coin": + new_coins += int(item.split(" ")[0]) + # Limit to 999 and convert back to binary-coded-decimal + new_coins = int(str(min(new_coins, 999)), 16).to_bytes(2, "little") + + modified_level_data = level_data.copy() + for ID, (location, data) in enumerate(locations.items(), START_IDS): + if "clear_condition" in data: + if items_received.count(data["clear_condition"][0]) >= data["clear_condition"][1]: + modified_level_data[data["ram_index"]] |= (0x08 if data["type"] == "bell" + else 0x01 if data["type"] == "secret" else 0x80) + + if data["type"] == "level" and level_data[data["ram_index"]] & 0x40: + locations_checked.append(ID) + if data["type"] == "secret" and level_data[data["ram_index"]] & 0x02: + locations_checked.append(ID) + elif data["type"] == "bell" and data["id"] == current_level and midway_point == 0xFF: + locations_checked.append(ID) + + invincibility_length = int((832.0 / (star_count + 1)) + * (items_received.count("Super Star Duration Increase") + 1)) + + if "Easy Mode" in items_received: + difficulty_mode = 1 + elif "Normal Mode" in items_received: + difficulty_mode = 0 + + data_writes = [ + (rom_addresses["Space_Physics"], [0x7e] if "Space Physics" in items_received else [0xaf], "ROM"), + (rom_addresses["Get_Hurt_To_Big_Mario"], [1] if "Mushroom" in items_received else [0], "ROM"), + (rom_addresses["Get_Mushroom_A"], [0xea, 0x16, 0xa2] if "Mushroom" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Mushroom_B"], [0xea, 0x16, 0xa2] if "Mushroom" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Mushroom_C"], [00] if "Mushroom" in items_received else [0xd8], "ROM"), + (rom_addresses["Get_Carrot_A"], [0xea, 0x16, 0xa2] if "Carrot" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Carrot_B"], [0xea, 0x16, 0xa2] if "Carrot" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Carrot_C"], [00] if "Carrot" in items_received else [0xc8], "ROM"), + (rom_addresses["Get_Fire_Flower_A"], [0xea, 0x16, 0xa2] if "Fire Flower" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Fire_Flower_B"], [0xea, 0x16, 0xa2] if "Fire Flower" in items_received else [0, 0, 0], "ROM"), + (rom_addresses["Get_Fire_Flower_C"], [00] if "Fire Flower" in items_received else [0xc8], "ROM"), + (rom_addresses["Invincibility_Star_A"], [(invincibility_length >> 8) + 1], "ROM"), + (rom_addresses["Invincibility_Star_B"], [invincibility_length & 0xFF], "ROM"), + (rom_addresses["Enable_Bubble"], [0xcb, 0xd7] if "Hippo Bubble" in items_received else [0, 0], "ROM"), + (rom_addresses["Enable_Swim"], [0xcb, 0xcf] if "Water Physics" in items_received else [0, 0], "ROM"), + (rom_addresses["Pipe_Traversal_A"], [16] if "Pipe Traversal - Down" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_B"], [32] if "Pipe Traversal - Up" in items_received else [10], "ROM"), + (rom_addresses["Pipe_Traversal_C"], [48] if "Pipe Traversal - Right" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_D"], [64] if "Pipe Traversal - Left" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_SFX_A"], [5] if "Pipe Traversal - Down" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_SFX_B"], [5] if "Pipe Traversal - Up" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_SFX_C"], [5] if "Pipe Traversal - Right" in items_received else [0], "ROM"), + (rom_addresses["Pipe_Traversal_SFX_D"], [5] if "Pipe Traversal - Left" in items_received else [0], "ROM"), + (0x022c, [new_lives], "CartRAM"), + (0x02E4, [difficulty_mode], "CartRAM"), + (0x0848, modified_level_data, "CartRAM"), + (0x0262, new_coins, "CartRAM"), + ] + + if items_received: + data_writes.append((0x00F0, write_num_items_received, "CartRAM")) + + if midway_point == 0xFF and (midway_bells or music in overworld_music): + # after registering the check for the midway bell, clear the value just for safety. + data_writes.append((0x02A0, [0], "CartRAM")) + + for i in range(32): + if auto_scroll_levels[i] == 3: + if "Auto Scroll" in items_received or f"Auto Scroll - {level_id_to_name[i]}" in items_received: + auto_scroll_levels[i] = 1 + if i == current_level: + data_writes.append((0x02C8, [0x01], "CartRAM")) + else: + auto_scroll_levels[i] = 0 + elif auto_scroll_levels[i] == 2: + if ("Cancel Auto Scroll" in items_received + or f"Cancel Auto Scroll - {level_id_to_name[i]}" in items_received): + auto_scroll_levels[i] = 0 + if i == current_level: + data_writes.append((0x02C8, [0x00], "CartRAM")) + else: + auto_scroll_levels[i] = 1 + data_writes.append((rom_addresses["Auto_Scroll_Levels"], auto_scroll_levels, "ROM")) + + success = await guarded_write(ctx.bizhawk_ctx, data_writes, [(0x0848, level_data, "CartRAM"), + (0x022C, [int.from_bytes(bcd_lives, "big")], + "CartRAM"), + [0x0262, coins, "CartRAM"]]) + + if success and energy_link_add is not None: + await ctx.send_msgs([{ + "cmd": "Set", "key": f"EnergyLink{ctx.team}", "operations": + [{"operation": "add", "value": energy_link_add}, + {"operation": "max", "value": 0}], + }]) + + if not ctx.server or not ctx.server.socket.open or ctx.server.socket.closed: + return + + if locations_checked and locations_checked != self.locations_array: + self.locations_array = locations_checked + await ctx.send_msgs([{"cmd": "LocationChecks", "locations": locations_checked}]) + + if music == 0x18: + await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) + ctx.finished_game = True + + def on_package(self, ctx, cmd: str, args: dict): + super().on_package(ctx, cmd, args) + if cmd == 'Connected': + if ctx.slot_data["energy_link"]: + ctx.set_notify(f"EnergyLink{ctx.team}") + if ctx.ui: + ctx.ui.enable_energy_link() + ctx.ui.energy_link_label.text = "Lives: Standby" + elif cmd == "SetReply" and args["key"].startswith("EnergyLink"): + if ctx.ui: + ctx.ui.energy_link_label.text = f"Lives: {int(args['value'] / BANK_EXCHANGE_RATE)}" + elif cmd == "Retrieved": + if f"EnergyLink{ctx.team}" in args["keys"] and args['keys'][f'EnergyLink{ctx.team}'] and ctx.ui: + ctx.ui.energy_link_label.text = f"Lives: {int(args['keys'][f'EnergyLink{ctx.team}'] / BANK_EXCHANGE_RATE)}" diff --git a/worlds/marioland2/docs/en_Super Mario Land 2.md b/worlds/marioland2/docs/en_Super Mario Land 2.md new file mode 100644 index 000000000000..7be02a2a287a --- /dev/null +++ b/worlds/marioland2/docs/en_Super Mario Land 2.md @@ -0,0 +1,64 @@ +# Super Mario Land 2: 6 Golden Coins + +## Where is the options page? + +The [player options page for this game](../player-options) contains all the options you need to configure and export a +config file. + +## What items and locations get shuffled? + +Completing a level's exits results in a location check instead of automatically bringing you to the next level. +Where there are secret exits, the secret exit will be a separate location check. There is one exception, Hippo Zone, +that does not have a separate check for its secret exit. The Hippo Zone secret exit will still bring you to the Space +Zone. + +Ringing the Midway Bells in each level that has one will register a location check. If the "Shuffle Midway Bells" option +is turned on, then ringing the bell will not grant the checkpoint, and instead you must obtain the Midway Bell item from +the item pool to gain the checkpoint for that level. Holding SELECT while loading into a level where you have unlocked +the Midway Bell checkpoint will start you at the beginning of the level. + +Unlocking paths to new levels requires finding or receiving Zone Progression items. For example, receiving the first +"Turtle Zone Progression" will unlock the path from Turtle Zone 1 to Turtle Zone 2. Paths to secret levels are separate +items, so Turtle Zone Secret will open the path from Turtle Zone 2 to the Turtle Zone Secret Course. + +Depending on settings, there may be some "Zone Progression x2" items that open two paths at once. + +The path from Tree Zone 2 to the branch to Tree Zone 3 and 4 is one unlock, so both levels will open at this point. + +Besides the zone progression unlocks, the following items are always shuffled: +- Mushroom: required to become Big Mario. If you are Fire or Bunny Mario and take damage, and have not obtained the +Mushroom, you will drop straight down to Small Mario. +- Fire Flower: required to become Fire Mario. +- Carrot: required to become Bunny Mario. +- Hippo Bubble: required to use the bubbles in Hippo Zone to fly. +- Water Physics: Mario will fall through water as though it is air until this is obtained. +- Space Physics: the Space Zone levels will have normal gravity until this is obtained. +- Super Star Duration Increase: you begin with a drastically lowered invincibility star duration, and these items will +increase it. + +Additionally, the following items can be shuffled depending on your YAML options: +- The 6 Golden Coins: note that the game will still show you the coin being sent to the castle when defeating a boss +regardless of whether the coin is actually obtained in that location. +- Mario Coin Fragments: As an alternative to shuffling the 6 Golden Coins, you can shuffle Mario Coin Fragments, +a chosen percentage of which are needed to assemble the Mario Coin. You will start with the other 5 coins. +- Normal Mode/Easy Mode: you can start the game in Normal Mode with an Easy Mode "upgrade" in the item pool, or start in +Easy Mode with a Normal Mode "trap" item, swapping the difficulty. +- Auto Scroll: auto-scrolling levels can be set to not auto scroll until this trap item is received. +- Pipe Traversal: required to enter pipes. Can also be split into 4 items, each enabling pipe entry from a different +direction. +- Coins: if Coinsanity is enabled, coins will be shuffled into the item pool. A number of checks will be added to each +level for obtaining a specific number of coins within a single playthrough of the level. + + +## When the player receives an item, what happens? + +There is no in-game indication that an item has been received. You will need to watch the client or web tracker to be +sure you're aware of the items you've received. + +## Special Thanks to: + +- [froggestspirit](https://github.com/froggestspirit) for his Super Mario Land 2 disassembly. While very incomplete, it +had enough memory values mapped out to make my work significantly easier. +- [slashinfty](https://github.com/slashinfty), the author of the +[Super Mario Land 2 Randomizer](https://sml2r.download/) for permitting me to port features such as Randomize Enemies +and Randomize Platforms directly from it. \ No newline at end of file diff --git a/worlds/marioland2/docs/setup_en.md b/worlds/marioland2/docs/setup_en.md new file mode 100644 index 000000000000..581d36e7864f --- /dev/null +++ b/worlds/marioland2/docs/setup_en.md @@ -0,0 +1,75 @@ +# Setup Guide for Super Mario Land 2: 6 Golden Coins + +## Important + +As we are using BizHawk, this guide is only applicable to Windows and Linux systems. + +## Required Software + +- BizHawk: [BizHawk Releases from TASVideos](https://tasvideos.org/BizHawk/ReleaseHistory) + - Version 2.9.1 is recommended. + - Detailed installation instructions for BizHawk can be found at the above link. + - Windows users must run the prereq installer first, which can also be found at the above link. +- The built-in Archipelago client, which can be installed [here](https://github.com/ArchipelagoMW/Archipelago/releases) +- A Super Mario Land 2: 6 Golden Coins version 1.0 ROM file. The Archipelago community cannot provide this. + +## Configuring BizHawk + +Once BizHawk has been installed, open EmuHawk and change the following settings: + +- Under Config > Customize > Advanced, make sure the box for AutoSaveRAM is checked, and click the 5s button. + This reduces the possibility of losing save data in emulator crashes. +- Under Config > Customize, check the "Run in background" box. This will prevent disconnecting from the client while +EmuHawk is running in the background. + +It is strongly recommended to associate Game Boy ROM extensions (\*.gb) to the EmuHawk we've just installed. +To do so, we simply have to search any Game Boy ROM we happened to own, right click and select "Open with...", unfold +the list that appears and select the bottom option "Look for another application", then browse to the BizHawk folder +and select EmuHawk.exe. + +## Configuring your YAML file + +### What is a YAML file and why do I need one? + +Your YAML file contains a set of configuration options which provide the generator with information about how it should +generate your game. Each player of a multiworld will provide their own YAML file. This setup allows each player to enjoy +an experience customized for their taste, and different players in the same multiworld can all have different options. + +### Where do I get a YAML file? + +You can generate a yaml or download a template by visiting the [Super Mario Land 2 Player Options Page](/games/Super%20Mario%20Land%202/player-options) + +## Joining a MultiWorld Game + +### Generating and Patching a Game + +1. Create your options file (YAML). +2. Follow the general Archipelago instructions for [generating a game](../../Archipelago/setup/en#generating-a-game). +This will generate an output file for you. Your patch file will have a `.apsml2` file extension. +3. Open `ArchipelagoLauncher.exe` +4. Select "Open Patch" on the left side and select your patch file. +5. If this is your first time patching, you will be prompted to locate your vanilla ROM. +6. A patched `.gb` file will be created in the same place as the patch file. +7. On your first time opening a patch with BizHawk Client, you will also be asked to locate `EmuHawk.exe` in your +BizHawk install. + +You must connect Super Mario Land 2 to a server, even for a single player game, or progress cannot be made. + +### Connect to the Multiserver + +By default, opening a patch file will do steps 1-5 below for you automatically. Even so, keep them in your memory just +in case you have to close and reopen a window mid-game for some reason. + +1. Super Mario Land 2 uses Archipelago's BizHawk Client. If the client isn't still open from when you patched your +game, you can re-open it from the launcher. +2. Ensure EmuHawk is running the patched ROM. +3. In EmuHawk, go to `Tools > Lua Console`. This window must stay open while playing. +4. In the Lua Console window, go to `Script > Open Script…`. +5. Navigate to your Archipelago install folder and open `data/lua/connector_bizhawk_generic.lua`. +6. The emulator may freeze every few seconds until it manages to connect to the client. This is expected. The BizHawk +Client window should indicate that it connected and recognized Super Mario Land 2. +7. To connect the client to the server, enter your room's address and port (e.g. `archipelago.gg:38281`) into the +top text field of the client and click Connect. + +To connect the client to the multiserver simply put `

:` on the textfield on top and press enter (if the +server uses password, type in the bottom textfield `/connect
: [password]`) \ No newline at end of file diff --git a/worlds/marioland2/items.py b/worlds/marioland2/items.py new file mode 100644 index 000000000000..041ffe99f976 --- /dev/null +++ b/worlds/marioland2/items.py @@ -0,0 +1,79 @@ +from BaseClasses import ItemClassification +from .locations import level_name_to_id +from .options import CoinsanityChecks + +items = { + "Space Zone Progression": ItemClassification.progression, + "Space Zone Secret": ItemClassification.progression, + "Tree Zone Progression": ItemClassification.progression, + "Tree Zone Progression x2": ItemClassification.progression, + "Tree Zone Secret": ItemClassification.progression, + "Macro Zone Progression": ItemClassification.progression, + "Macro Zone Progression x2": ItemClassification.progression, + "Macro Zone Secret 1": ItemClassification.progression, + "Macro Zone Secret 2": ItemClassification.progression_skip_balancing, + "Pumpkin Zone Progression": ItemClassification.progression, + "Pumpkin Zone Progression x2": ItemClassification.progression, + "Pumpkin Zone Secret 1": ItemClassification.progression, + "Pumpkin Zone Secret 2": ItemClassification.progression, + "Mario Zone Progression": ItemClassification.progression, + "Mario Zone Progression x2": ItemClassification.progression, + "Turtle Zone Progression": ItemClassification.progression, + "Turtle Zone Progression x2": ItemClassification.progression, + "Turtle Zone Secret": ItemClassification.progression, + "Tree Coin": ItemClassification.progression_skip_balancing, + "Space Coin": ItemClassification.progression_skip_balancing, + "Macro Coin": ItemClassification.progression_skip_balancing, + "Pumpkin Coin": ItemClassification.progression_skip_balancing, + "Mario Coin": ItemClassification.progression_skip_balancing, + "Turtle Coin": ItemClassification.progression_skip_balancing, + "Mario Coin Fragment": ItemClassification.progression_skip_balancing, + "Mushroom": ItemClassification.progression, + "Fire Flower": ItemClassification.progression, + "Carrot": ItemClassification.progression, + "Space Physics": ItemClassification.progression_skip_balancing, + "Hippo Bubble": ItemClassification.progression_skip_balancing, + "Water Physics": ItemClassification.progression, + "Pipe Traversal": ItemClassification.progression, + "Pipe Traversal - Down": ItemClassification.progression, + "Pipe Traversal - Up": ItemClassification.progression, + "Pipe Traversal - Right": ItemClassification.progression, + "Pipe Traversal - Left": ItemClassification.progression_skip_balancing, + "Super Star Duration Increase": ItemClassification.filler, + "Easy Mode": ItemClassification.useful, + "Normal Mode": ItemClassification.trap, + "Auto Scroll": ItemClassification.trap, + **{f"Auto Scroll - {level}": ItemClassification.trap for level in level_name_to_id if level != "Wario's Castle"}, + "Cancel Auto Scroll": ItemClassification.progression, + **{f"Cancel Auto Scroll - {level}": ItemClassification.progression for level in level_name_to_id + if level != "Wario's Castle"}, + "Mushroom Zone Midway Bell": ItemClassification.filler, + "Tree Zone 1 Midway Bell": ItemClassification.filler, + "Tree Zone 2 Midway Bell": ItemClassification.progression_skip_balancing, + "Tree Zone 4 Midway Bell": ItemClassification.progression_skip_balancing, + "Tree Zone 5 Midway Bell": ItemClassification.filler, + "Space Zone 1 Midway Bell": ItemClassification.filler, + "Space Zone 2 Midway Bell": ItemClassification.progression_skip_balancing, + "Macro Zone 1 Midway Bell": ItemClassification.progression_skip_balancing, + "Macro Zone 2 Midway Bell": ItemClassification.progression_skip_balancing, + "Macro Zone 3 Midway Bell": ItemClassification.progression_skip_balancing, + "Macro Zone 4 Midway Bell": ItemClassification.filler, + "Pumpkin Zone 1 Midway Bell": ItemClassification.progression_skip_balancing, + "Pumpkin Zone 2 Midway Bell": ItemClassification.filler, + "Pumpkin Zone 3 Midway Bell": ItemClassification.filler, + "Pumpkin Zone 4 Midway Bell": ItemClassification.filler, + "Mario Zone 1 Midway Bell": ItemClassification.progression_skip_balancing, + "Mario Zone 2 Midway Bell": ItemClassification.filler, + "Mario Zone 3 Midway Bell": ItemClassification.filler, + "Mario Zone 4 Midway Bell": ItemClassification.filler, + "Turtle Zone 1 Midway Bell": ItemClassification.filler, + "Turtle Zone 2 Midway Bell": ItemClassification.progression_skip_balancing, + "Turtle Zone 3 Midway Bell": ItemClassification.filler, + "Mario's Castle Midway Bell": ItemClassification.progression_skip_balancing, + "1 Coin": ItemClassification.filler, + **{f"{i} Coins": ItemClassification.filler for i in range(2, CoinsanityChecks.range_end + 1)} +} + +for level in {"Turtle Zone Secret Course", "Macro Zone Secret Course", "Turtle Zone 3", "Scenic Course", + "Mario Zone 2"}: + items[f"Cancel Auto Scroll - {level}"] = ItemClassification.useful diff --git a/worlds/marioland2/locations.py b/worlds/marioland2/locations.py new file mode 100644 index 000000000000..02ae1cca9dc5 --- /dev/null +++ b/worlds/marioland2/locations.py @@ -0,0 +1,498 @@ +START_IDS = 1 + +locations = { + "Mushroom Zone - Normal Exit": {"id": 0x00, "ram_index": 0, "type": "level"}, + "Mushroom Zone - Midway Bell": {"id": 0x00, "ram_index": 0, "clear_condition": ("Mushroom Zone Midway Bell", 1), "type": "bell"}, + "Scenic Course - Normal Exit": {"id": 0x19, "ram_index": 40, "type": "level"}, + "Tree Zone 1 - Normal Exit": {"id": 0x01, "ram_index": 1, "clear_condition": ("Tree Zone Progression", 1), "type": "level"}, + "Tree Zone 1 - Midway Bell": {"id": 0x01, "ram_index": 1, "clear_condition": ("Tree Zone 1 Midway Bell", 1), "type": "bell"}, + "Tree Zone 2 - Normal Exit": {"id": 0x02, "ram_index": 2, "clear_condition": ("Tree Zone Progression", 2), "type": "level"}, + "Tree Zone 2 - Secret Exit": {"id": 0x02, "ram_index": 2, "clear_condition": ("Tree Zone Secret", 1), "type": "secret"}, + "Tree Zone 2 - Midway Bell": {"id": 0x02, "ram_index": 2, "clear_condition": ("Tree Zone 2 Midway Bell", 1), "type": "bell"}, + "Tree Zone 3 - Normal Exit": {"id": 0x04, "ram_index": 4, "clear_condition": ("Tree Zone Progression", 3), "type": "level"}, + "Tree Zone 4 - Normal Exit": {"id": 0x03, "ram_index": 3, "clear_condition": ("Tree Zone Progression", 3), "type": "level"}, + "Tree Zone 4 - Midway Bell": {"id": 0x03, "ram_index": 3, "clear_condition": ("Tree Zone 4 Midway Bell", 1), "type": "bell"}, + "Tree Zone 5 - Boss": {"id": 0x05, "ram_index": 5, "clear_condition": ("Tree Coin", 1), "type": "level"}, + "Tree Zone 5 - Midway Bell": {"id": 0x05, "ram_index": 5, "clear_condition": ("Tree Zone 5 Midway Bell", 1), "type": "bell"}, + "Tree Zone Secret Course - Normal Exit": {"id": 0x1D, "ram_index": 36, "type": "level"}, + "Hippo Zone - Normal or Secret Exit": {"id": 0x11, "ram_index": 31, "type": "level"}, + "Space Zone 1 - Normal Exit": {"id": 0x12, "ram_index": 16, "clear_condition": ("Space Zone Progression", 1), "type": "level"}, + "Space Zone 1 - Secret Exit": {"id": 0x12, "ram_index": 16, "clear_condition": ("Space Zone Secret", 1), "type": "secret"}, + "Space Zone 1 - Midway Bell": {"id": 0x12, "ram_index": 16, "clear_condition": ("Space Zone 1 Midway Bell", 1), "type": "bell"}, + "Space Zone Secret Course - Normal Exit": {"id": 0x1C, "ram_index": 41, "type": "level"}, + "Space Zone 2 - Boss": {"id": 0x13, "ram_index": 17, "clear_condition": ("Space Coin", 1), "type": "level"}, + "Space Zone 2 - Midway Bell": {"id": 0x13, "ram_index": 17, "clear_condition": ("Space Zone 2 Midway Bell", 1), "type": "bell"}, + "Macro Zone 1 - Normal Exit": {"id": 0x14, "ram_index": 11, "clear_condition": ("Macro Zone Progression", 1), "type": "level"}, + "Macro Zone 1 - Secret Exit": {"id": 0x14, "ram_index": 11, "clear_condition": ("Macro Zone Secret 1", 1), "type": "secret"}, + "Macro Zone 1 - Midway Bell": {"id": 0x14, "ram_index": 11, "clear_condition": ("Macro Zone 1 Midway Bell", 1), "type": "bell"}, + "Macro Zone 2 - Normal Exit": {"id": 0x15, "ram_index": 12, "clear_condition": ("Macro Zone Progression", 2), "type": "level"}, + "Macro Zone 2 - Midway Bell": {"id": 0x15, "ram_index": 12, "clear_condition": ("Macro Zone 2 Midway Bell", 1), "type": "bell"}, + "Macro Zone 3 - Normal Exit": {"id": 0x16, "ram_index": 13, "clear_condition": ("Macro Zone Progression", 3), "type": "level"}, + "Macro Zone 3 - Midway Bell": {"id": 0x16, "ram_index": 13, "clear_condition": ("Macro Zone 3 Midway Bell", 1), "type": "bell"}, + "Macro Zone 4 - Boss": {"id": 0x17, "ram_index": 14, "clear_condition": ("Macro Coin", 1), "type": "level"}, + "Macro Zone 4 - Midway Bell": {"id": 0x17, "ram_index": 14, "clear_condition": ("Macro Zone 4 Midway Bell", 1), "type": "bell"}, + "Macro Zone Secret Course - Normal Exit": {"id": 0x1E, "ram_index": 35, "clear_condition": ("Macro Zone Secret 2", 1), "type": "level"}, + "Pumpkin Zone 1 - Normal Exit": {"id": 0x06, "ram_index": 6, "clear_condition": ("Pumpkin Zone Progression", 1), "type": "level"}, + "Pumpkin Zone 1 - Midway Bell": {"id": 0x06, "ram_index": 6, "clear_condition": ("Pumpkin Zone 1 Midway Bell", 1), "type": "bell"}, + "Pumpkin Zone 2 - Normal Exit": {"id": 0x07, "ram_index": 7, "clear_condition": ("Pumpkin Zone Progression", 2), "type": "level"}, + "Pumpkin Zone 2 - Secret Exit": {"id": 0x07, "ram_index": 7, "clear_condition": ("Pumpkin Zone Secret 1", 1), "type": "secret"}, + "Pumpkin Zone 2 - Midway Bell": {"id": 0x07, "ram_index": 7, "clear_condition": ("Pumpkin Zone 2 Midway Bell", 2), "type": "bell"}, + "Pumpkin Zone 3 - Normal Exit": {"id": 0x08, "ram_index": 8, "clear_condition": ("Pumpkin Zone Progression", 3), "type": "level"}, + "Pumpkin Zone 3 - Secret Exit": {"id": 0x08, "ram_index": 8, "clear_condition": ("Pumpkin Zone Secret 2", 1), "type": "secret"}, + "Pumpkin Zone 3 - Midway Bell": {"id": 0x08, "ram_index": 8, "clear_condition": ("Pumpkin Zone 3 Midway Bell", 3), "type": "bell"}, + "Pumpkin Zone 4 - Boss": {"id": 0x09, "ram_index": 9, "clear_condition": ("Pumpkin Coin", 1), "type": "level"}, + "Pumpkin Zone 4 - Midway Bell": {"id": 0x09, "ram_index": 9, "clear_condition": ("Pumpkin Zone 4 Midway Bell", 1), "type": "bell"}, + "Pumpkin Zone Secret Course 1 - Normal Exit": {"id": 0x1B, "ram_index": 38, "type": "level"}, + "Pumpkin Zone Secret Course 2 - Normal Exit": {"id": 0x1F, "ram_index": 39, "type": "level"}, + "Mario Zone 1 - Normal Exit": {"id": 0x0A, "ram_index": 26, "clear_condition": ("Mario Zone Progression", 1), "type": "level"}, + "Mario Zone 1 - Midway Bell": {"id": 0x0A, "ram_index": 26, "clear_condition": ("Mario Zone 1 Midway Bell", 1), "type": "bell"}, + "Mario Zone 2 - Normal Exit": {"id": 0x0B, "ram_index": 27, "clear_condition": ("Mario Zone Progression", 2), "type": "level"}, + "Mario Zone 2 - Midway Bell": {"id": 0x0B, "ram_index": 27, "clear_condition": ("Mario Zone 2 Midway Bell", 1), "type": "bell"}, + "Mario Zone 3 - Normal Exit": {"id": 0x0C, "ram_index": 28, "clear_condition": ("Mario Zone Progression", 3), "type": "level"}, + "Mario Zone 3 - Midway Bell": {"id": 0x0C, "ram_index": 28, "clear_condition": ("Mario Zone 3 Midway Bell", 1), "type": "bell"}, + "Mario Zone 4 - Boss": {"id": 0x0D, "ram_index": 29, "clear_condition": ("Mario Coin", 1), "type": "level"}, + "Mario Zone 4 - Midway Bell": {"id": 0x0D, "ram_index": 29, "clear_condition": ("Mario Zone 4 Midway Bell", 1), "type": "bell"}, + "Turtle Zone 1 - Normal Exit": {"id": 0x0E, "ram_index": 21, "clear_condition": ("Turtle Zone Progression", 1), "type": "level"}, + "Turtle Zone 1 - Midway Bell": {"id": 0x0E, "ram_index": 21, "clear_condition": ("Turtle Zone 1 Midway Bell", 1), "type": "bell"}, + "Turtle Zone 2 - Normal Exit": {"id": 0x0F, "ram_index": 22, "clear_condition": ("Turtle Zone Progression", 2), "type": "level"}, + "Turtle Zone 2 - Secret Exit": {"id": 0x0F, "ram_index": 22, "clear_condition": ("Turtle Zone Secret", 1), "type": "secret"}, + "Turtle Zone 2 - Midway Bell": {"id": 0x0F, "ram_index": 22, "clear_condition": ("Turtle Zone 2 Midway Bell", 1), "type": "bell"}, + "Turtle Zone 3 - Boss": {"id": 0x10, "ram_index": 23, "clear_condition": ("Turtle Coin", 1), "type": "level"}, + "Turtle Zone 3 - Midway Bell": {"id": 0x10, "ram_index": 23, "clear_condition": ("Turtle Zone 3 Midway Bell", 1), "type": "bell"}, + "Turtle Zone Secret Course - Normal Exit": {"id": 0x1A, "ram_index": 37, "type": "level"}, + "Mario's Castle - Midway Bell": {"id": 24, "ram_index": 24, "clear_condition": ("Mario's Castle Midway Bell", 1), "type": "bell"}, +} + + +coins_coords = { + "Mushroom Zone": + [(22, 28), (24, 28), (42, 28), (43, 28), (74, 36), (74, 37), (74, 38), (76, 36), (76, 37), + (76, 38), (78, 36), (78, 37), (78, 38), (80, 36), (80, 37), (80, 38), (82, 36), (82, 37), + (82, 38), (83, 25), (84, 25), (84, 36), (84, 37), (84, 38), (85, 25), (86, 25), (86, 36), + (86, 37), (86, 38), (87, 25), (88, 36), (88, 37), (88, 38), (116, 24), (117, 24), (118, 24), + (151, 28), (152, 28), (180, 28), (181, 24), (181, 28), (182, 24), (182, 28), (183, 24), (183, 28), + (184, 24), (184, 28), (185, 24), (185, 28), (186, 24), (186, 28), (187, 24), (187, 28), (188, 24), + (188, 28), (189, 28), (211, 25), (212, 25), (212, 36), (212, 37), (212, 38), (212, 39), (213, 25), + (213, 36), (213, 37), (213, 38), (213, 39), (214, 25), (214, 36), (214, 37), (214, 38), (214, 39), + (215, 25), (216, 25), (217, 25), (217, 36), (217, 37), (217, 38), (217, 39), (218, 25), (218, 36), + (218, 37), (218, 38), (218, 39), (219, 25), (219, 36), (219, 37), (219, 38), (219, 39), (220, 25), + (231, 24), (232, 24)], + "Tree Zone 1": + [(27, 30), (28, 30), (29, 30), (33, 27), (34, 27), (35, 27), (40, 30), (41, 30), (42, 30), (47, 27), + (48, 27), (49, 27), (56, 30), (57, 30), (58, 30), (64, 30), (65, 30), (66, 30), (88, 30), (89, 30), + (90, 30), (94, 30), (95, 30), (96, 30), (100, 30), (101, 30), (102, 30), (106, 27), (107, 27), + (108, 27), (112, 30), (113, 30), (114, 30), (119, 28), (138, 30), (139, 30), (140, 30), (150, 28), + (151, 20), (151, 28), (152, 20), (152, 26), (152, 28), (153, 26), (153, 28), (154, 26), (154, 28), + (155, 26), (155, 28), (156, 26), (156, 28), (157, 20), (157, 26), (157, 28), (158, 20), (158, 26), + (158, 28), (159, 26), (159, 28), (160, 28), (161, 28), (176, 13), (177, 13), (177, 29), (178, 13), + (178, 29), (179, 13), (179, 29), (180, 13), (181, 13), (182, 13), (183, 13), (184, 13), (185, 13), + (186, 13), (187, 13), (187, 29), (188, 13), (188, 29), (189, 13), (189, 29), (190, 13), (191, 13), + (192, 13), (193, 13), (194, 13), (195, 13), (196, 13), (197, 13), (197, 29), (198, 13), (198, 29), + (199, 13), (199, 29), (200, 13), (201, 13), (202, 13), (203, 13), (204, 13), (205, 13), (206, 13), + (207, 27), (208, 13), (208, 27), (209, 14), (209, 27), (210, 10), (210, 11), (210, 12), (210, 13), + (210, 14), (210, 15), (211, 14), (212, 13), (219, 30), (220, 30), (221, 30), (229, 27), (230, 27), + (231, 27)], + "Tree Zone 2": + [(27, 11), (28, 11), (42, 10), (43, 10), (44, 10), (51, 28), (61, 9), (65, 26), (66, 26), (67, 26), + (70, 24), (71, 24), (72, 10), (72, 24), (73, 10), (73, 24), (75, 10), (76, 10), (76, 26), (77, 26), + (78, 10), (78, 26), (79, 10), (80, 24), (81, 10), (81, 24), (82, 10), (82, 24), (83, 24), (127, 7), + (128, 7), (129, 7), (130, 7), (136, 43), (138, 9), (138, 10), (138, 11), (139, 41), (140, 41), + (141, 41), (142, 9), (142, 10), (142, 11), (144, 41), (145, 41), (146, 9), (146, 10), (146, 11), + (146, 41), (149, 41), (150, 41), (151, 41), (154, 41), (155, 41), (156, 41), (159, 41), (160, 41), + (161, 41), (164, 41), (165, 41), (166, 41), (169, 41), (170, 41), (171, 41), (174, 41), (175, 41), + (176, 41), (182, 3), (188, 42), (188, 43), (188, 44), (189, 42), (189, 43), (189, 44), (190, 42), + (190, 43), (190, 44), (191, 42), (191, 43), (191, 44), (192, 42), (192, 43), (192, 44), (193, 42), + (193, 43), (193, 44), (213, 8), (213, 9), (213, 10), (213, 11), (213, 12), (213, 13), (213, 14), + (213, 15), (213, 16), (213, 17), (213, 18), (213, 19), (213, 20), (213, 21), (213, 22), (213, 23), + (213, 24), (213, 25)], + "Tree Zone Secret Course": + [(10, 24), (11, 24), (12, 24), (17, 23), (39, 24), (40, 24), (41, 24), (42, 24), (45, 24), + (46, 24), (47, 24), (48, 24), (51, 25), (52, 25), (53, 25), (54, 25), (58, 26), (59, 26), + (60, 26), (61, 24), (61, 25), (62, 24), (62, 25), (63, 24), (63, 25), (64, 24), (64, 25), + (67, 25), (68, 26), (69, 27), (70, 27), (73, 26), (74, 27), (75, 27), (76, 27), (80, 23), + (80, 24), (81, 23), (81, 24), (82, 23), (82, 24), (83, 23), (83, 24), (87, 25), (88, 24), + (89, 24), (90, 25), (91, 26), (100, 23), (114, 27), (114, 28), (115, 27), (115, 28), (116, 27), + (116, 28), (117, 27), (117, 28), (118, 27), (118, 28), (119, 27), (119, 28), (120, 27), + (120, 28), (121, 27), (121, 28), (128, 27), (128, 28), (131, 27), (131, 28), (134, 27), + (134, 28), (137, 27), (137, 28), (138, 27), (138, 28), (143, 27), (143, 28), (159, 23)], + "Tree Zone 4": + [(22, 10), (24, 12), (26, 10), (28, 27), (29, 11), (30, 11), (31, 11), (32, 11), (33, 11), (34, 11), + (35, 11), (37, 10), (38, 12), (41, 11), (43, 12), (61, 11), (70, 11), (79, 11), (89, 11), (103, 22), + (103, 25), (103, 28), (105, 22), (105, 25), (105, 28), (107, 22), (107, 25), (107, 28), (109, 22), + (109, 25), (109, 28), (111, 22), (111, 25), (111, 28), (113, 22), (113, 25), (113, 28), (115, 22), + (115, 25), (115, 28), (117, 22), (117, 25), (117, 28), (122, 22), (122, 25), (122, 28), (124, 22), + (124, 25), (124, 28), (126, 22), (126, 25), (126, 28), (128, 22), (128, 25), (128, 28), (130, 22), + (130, 25), (130, 28), (132, 22), (132, 25), (132, 28), (134, 22), (134, 25), (134, 28), (136, 22), + (136, 25), (136, 28), (171, 10), (196, 26), (196, 29), (197, 26), (197, 29), (198, 26), (198, 29), + (199, 26), (199, 29), (200, 26), (200, 29)], + "Tree Zone 3": + [(18, 11), (18, 12), (19, 11), (19, 12), (20, 11), (20, 12), (21, 11), (21, 12), (22, 11), (22, 12), + (26, 40), (27, 11), (27, 12), (28, 11), (28, 12), (29, 11), (29, 12), (30, 11), (30, 12), (31, 11), + (31, 12), (48, 41), (49, 41), (50, 41), (51, 41), (61, 25), (77, 24)], + "Tree Zone 5": + [(23, 41), (84, 39), (85, 39), (116, 42), (123, 39), (132, 39), (134, 36), (134, 39), (134, 43), + (134, 44), (135, 43), (135, 44), (136, 36), (136, 39), (136, 43), (136, 44), (137, 43), (137, 44), + (138, 36), (138, 39), (138, 43), (138, 44), (139, 43), (139, 44), (140, 36), (140, 39), (140, 43), + (140, 44), (141, 43), (141, 44), (142, 36), (142, 39), (142, 43), (142, 44), (144, 36), (144, 39), + (146, 36), (146, 39)], + "Scenic Course": + [(24, 28), (39, 28), (54, 28), (72, 28), (87, 28), (103, 28), (117, 28)], + "Hippo Zone": + [(2, 20), (3, 3), (15, 26), (16, 26), (17, 26), (28, 4), (28, 7), (28, 10), (28, 13), (29, 4), + (29, 7), (29, 10), (29, 13), (29, 21), (30, 4), (30, 7), (30, 10), (30, 13), (32, 15), (33, 15), + (34, 15), (35, 15), (36, 15), (37, 15), (41, 12), (41, 13), (42, 11), (43, 10), (44, 10), (45, 10), + (46, 11), (47, 12), (47, 13), (48, 14), (49, 15), (50, 15), (51, 15), (52, 14), (53, 12), (53, 13), + (54, 11), (55, 10), (56, 10), (57, 10), (58, 11), (59, 12), (59, 13), (60, 14), (61, 15), (62, 15), + (63, 15), (64, 14), (65, 12), (65, 13), (66, 11), (67, 10), (68, 10), (69, 10), (70, 11), (71, 12), + (71, 13), (72, 14), (73, 15), (74, 15), (75, 15), (76, 14), (77, 12), (77, 13), (84, 11), (85, 11), + (85, 22), (86, 22), (91, 6), (92, 6), (92, 11), (93, 6), (93, 11), (94, 11), (95, 16), (96, 12), + (96, 16), (97, 8), (97, 12), (97, 16), (98, 8), (98, 12), (99, 8), (112, 6), (112, 7), (112, 12), + (112, 13), (113, 2), (113, 5), (113, 8), (113, 11), (113, 14), (113, 17), (114, 2), (114, 5), + (114, 8), (114, 11), (114, 14), (114, 17), (115, 3), (115, 4), (115, 9), (115, 10), (115, 15), + (115, 16), (124, 3), (124, 4), (124, 9), (124, 10), (124, 15), (124, 16), (125, 2), (125, 5), + (125, 8), (125, 11), (125, 14), (125, 17), (126, 2), (126, 5), (126, 8), (126, 11), (126, 14), + (126, 17), (127, 6), (127, 7), (127, 12), (127, 13), (129, 13), (130, 13), (131, 13), (132, 13), + (132, 22), (133, 13), (134, 13), (135, 13), (136, 13), (136, 21), (137, 13), (138, 13), (139, 13), + (139, 22), (140, 13), (141, 13), (142, 13), (154, 7), (155, 7), (156, 7), (157, 10), (158, 10), + (159, 10), (162, 15), (162, 16), (162, 17), (164, 15), (164, 16), (164, 17), (166, 15), (166, 16), + (166, 17), (168, 15), (168, 16), (168, 17), (170, 15), (170, 16), (170, 17), (172, 15), (172, 16), + (172, 17), (174, 15), (174, 16), (174, 17), (176, 15), (176, 16), (176, 17)], + "Space Zone 1": + [(38, 26), (45, 25), (46, 25), (47, 25), (57, 24), (58, 24), (59, 24), (60, 19), (60, 23), (61, 23), + (62, 23), (63, 23), (75, 24), (89, 16), (89, 17), (89, 18), (89, 19), (90, 16), (90, 17), (90, 18), + (90, 19), (91, 16), (91, 17), (91, 18), (91, 19), (92, 16), (92, 17), (92, 18), (92, 19), (93, 16), + (93, 17), (93, 18), (93, 19), (104, 22), (105, 22), (114, 22), (115, 22), (125, 10), (126, 9), + (127, 8), (128, 8), (129, 8), (130, 8), (131, 8), (132, 9), (133, 10), (136, 10), (137, 9), + (138, 8), (139, 8), (140, 8), (141, 8), (142, 8), (143, 9), (144, 10), (147, 10), (148, 9), + (149, 8), (150, 8), (151, 8), (152, 8), (153, 8), (154, 9), (155, 10), (155, 18), (155, 19), + (155, 20), (156, 17), (156, 18), (156, 19), (156, 20), (156, 21), (157, 16), (157, 17), (157, 18), + (157, 19), (157, 20), (157, 21), (157, 22), (158, 10), (158, 16), (158, 17), (158, 18), (158, 19), + (158, 20), (158, 21), (158, 22), (159, 9), (159, 16), (159, 17), (159, 18), (159, 19), (159, 20), + (159, 21), (159, 22), (160, 8), (160, 16), (160, 17), (160, 18), (160, 19), (160, 20), (160, 21), + (160, 22), (161, 8), (161, 16), (161, 17), (161, 18), (161, 19), (161, 20), (161, 21), (161, 22), + (162, 8), (162, 17), (162, 18), (162, 19), (162, 20), (162, 21), (163, 8), (163, 18), (163, 19), + (163, 20), (164, 8), (165, 9), (166, 10), (168, 10), (169, 9), (170, 8), (171, 8), (172, 8), + (173, 8), (174, 8), (175, 9), (176, 10)], + "Space Zone Secret Course": + [(16, 22), (16, 23), (16, 24), (18, 21), (18, 22), (18, 23), (20, 21), (20, 22), (20, 23), + (22, 20), (22, 21), (22, 22), (24, 19), (24, 20), (24, 21), (26, 18), (26, 19), (26, 20), + (28, 18), (28, 19), (28, 20), (30, 17), (30, 18), (30, 19), (36, 15), (36, 16), (36, 17), + (38, 14), (38, 15), (38, 16), (40, 13), (40, 14), (40, 15), (40, 24), (41, 24), (42, 13), + (42, 14), (42, 15), (44, 12), (44, 13), (44, 14), (46, 12), (46, 13), (46, 14), (48, 12), + (48, 13), (48, 14), (50, 11), (50, 12), (50, 13), (50, 27), (51, 27), (52, 10), (52, 11), + (52, 12), (52, 27), (53, 27), (54, 27), (58, 11), (58, 12), (58, 13), (60, 12), (60, 13), + (60, 14), (62, 12), (62, 13), (62, 14), (64, 12), (64, 13), (64, 14), (66, 13), (66, 14), + (66, 15), (68, 13), (68, 14), (68, 15), (70, 14), (70, 15), (70, 16), (72, 15), (72, 16), + (72, 17), (74, 16), (74, 17), (74, 18), (80, 18), (80, 19), (80, 20), (82, 19), (82, 20), + (82, 21), (84, 19), (84, 20), (84, 21), (86, 20), (86, 21), (86, 22), (88, 21), (88, 22), + (88, 23)], + "Space Zone 2": + [(11, 13), (12, 13), (13, 13), (20, 8), (21, 8), (22, 8), (25, 5), (26, 5), (27, 5), (33, 6), + (34, 6), (35, 6), (36, 10), (37, 10), (38, 10), (45, 7), (46, 7), (47, 7), (59, 5), (60, 5), + (61, 5), (64, 3), (93, 8), (94, 8), (95, 8), (96, 11), (97, 11), (98, 11), (100, 6), (101, 6), + (102, 6), (102, 8), (120, 5), (124, 12), (124, 13), (125, 12), (125, 13), (126, 12), (126, 13), + (127, 3), (127, 12), (127, 13), (128, 3), (128, 7), (129, 3), (129, 7), (130, 7), (148, 6), + (148, 7), (148, 8), (149, 5), (149, 6), (149, 7), (149, 8), (149, 9), (150, 5), (150, 6), (150, 7), + (150, 8), (150, 9), (151, 5), (151, 6), (151, 7), (151, 8), (151, 9), (152, 5), (152, 6), (152, 7), + (152, 8), (152, 9), (153, 6), (153, 7), (153, 8), (165, 7), (165, 8), (166, 7), (166, 8), (167, 7), + (167, 8), (168, 7), (168, 8), (169, 7), (169, 8), (170, 7), (170, 8), (171, 7), (171, 8), (181, 9), + (185, 4), (200, 3), (200, 6), (200, 9), (201, 3), (201, 6), (201, 9), (202, 3), (202, 6), (202, 9), + (203, 3), (203, 6), (203, 9), (204, 3), (204, 6), (204, 9), (205, 3), (205, 6), (205, 9), (206, 3), + (206, 6), (206, 9), (207, 3), (207, 6), (207, 9), (208, 3), (208, 6), (208, 9), (209, 3), (209, 6), + (209, 9), (210, 3), (210, 6), (210, 9), (230, 12), (231, 12), (232, 12), (236, 2), (236, 3), + (236, 4), (236, 5), (237, 2), (237, 3), (237, 4), (237, 5), (238, 2), (238, 3), (238, 4), (238, 5), + (248, 10)], + "Turtle Zone 1": + [(22, 34), (27, 37), (28, 37), (29, 37), (30, 37), (31, 37), (32, 37), (33, 37), (34, 37), + (35, 37), (36, 37), (46, 32), (46, 33), (47, 32), (47, 33), (50, 32), (50, 33), (51, 32), + (51, 33), (54, 32), (54, 33), (55, 32), (55, 33), (56, 33), (57, 33), (58, 32), (58, 33), + (59, 32), (59, 33), (62, 32), (62, 33), (63, 32), (63, 33), (66, 32), (66, 33), (67, 32), + (67, 33), (73, 43), (74, 43), (75, 43), (77, 41), (78, 41), (79, 41), (81, 40), (82, 40), + (83, 40), (85, 41), (86, 41), (87, 41), (122, 36), (123, 36), (124, 36), (125, 36), (126, 36), + (127, 36), (130, 36), (131, 36), (132, 36), (133, 36), (134, 36), (135, 36), (136, 36), (137, 36), + (138, 36), (139, 36), (140, 36), (141, 36), (143, 34), (163, 36), (164, 36), (166, 36), (167, 36), + (169, 36), (170, 36), (180, 37), (181, 37), (182, 37), (183, 37), (184, 37), (185, 37), (188, 44), + (189, 44)], + "Turtle Zone 2": + [(6, 34), (11, 34), (15, 43), (48, 36), (51, 28), (56, 35), (57, 35), (59, 42), (61, 20), (62, 20), + (62, 35), (63, 20), (63, 35), (64, 20), (65, 20), (67, 35), (68, 35), (72, 39), (79, 34), + (82, 35), (87, 42), (96, 43), (105, 43), (107, 43), (109, 43), (118, 28), (121, 28), (139, 39), + (142, 39)], + "Turtle Zone Secret Course": + [(19, 27), (39, 27), (39, 28), (40, 26), (40, 27), (41, 25), (41, 27), (42, 25), (42, 27), + (43, 26), (43, 27), (44, 27), (44, 28), (48, 25), (48, 26), (48, 27), (48, 28), (49, 25), + (49, 27), (50, 25), (50, 27), (51, 25), (51, 27), (52, 26), (52, 28), (53, 27), (61, 25), + (61, 28), (62, 25), (62, 26), (62, 27), (62, 28), (63, 25), (63, 28), (64, 26), (73, 26), + (73, 27), (74, 25), (74, 28), (75, 25), (75, 28), (76, 25), (76, 28), (77, 26), (77, 27), + (82, 25), (82, 26), (82, 27), (82, 28), (83, 28), (84, 28), (85, 28), (87, 27), (89, 27), + (89, 28), (90, 26), (90, 27), (91, 25), (91, 27), (92, 25), (92, 27), (93, 26), (93, 27), + (94, 27), (94, 28), (98, 24), (98, 25), (98, 26), (98, 27), (99, 25), (100, 26), (101, 27), + (102, 24), (102, 25), (102, 26), (102, 27), (108, 24), (108, 25), (108, 26), (108, 27), + (109, 24), (109, 27), (110, 24), (110, 27), (111, 24), (111, 27), (112, 25), (112, 26), + (116, 24), (116, 27), (117, 23), (117, 26), (117, 27), (118, 23), (118, 25), (118, 27), + (119, 23), (119, 25), (119, 27), (120, 24), (120, 27), (121, 28), (122, 28), (123, 28)], + "Turtle Zone 3": + [(16, 25), (17, 25), (18, 25), (19, 25), (20, 25), (21, 25), (22, 25), (23, 25), (24, 25), + (35, 24), (36, 24), (37, 24), (38, 24), (39, 24), (40, 24), (41, 24), (42, 24), (43, 24), + (75, 28), (75, 29), (76, 28), (76, 29), (81, 28), (81, 29), (82, 28), (82, 29), (92, 26), + (93, 26), (94, 26), (98, 26), (99, 26), (100, 26), (123, 26), (124, 26), (126, 26), (127, 26), + (129, 26), (130, 26), (146, 22), (146, 29), (147, 22), (147, 29), (148, 22), (150, 22), (151, 22), + (152, 23), (152, 29), (153, 29), (154, 22), (155, 22), (156, 22), (158, 29), (159, 29), (161, 22), + (162, 22), (163, 22), (165, 22), (166, 22), (167, 22), (169, 22), (170, 22), (171, 22)], + "Mario Zone 1": + [(18, 44), (47, 36), (47, 37), (47, 38), (47, 39), (49, 36), (49, 37), (49, 38), (50, 36), (50, 37), + (50, 38), (52, 36), (52, 37), (52, 38), (53, 36), (53, 37), (53, 38), (60, 35), (60, 36), (60, 37), + (61, 35), (61, 36), (61, 37), (64, 35), (64, 36), (64, 37), (65, 35), (65, 36), (65, 37), (71, 36), + (78, 36), (78, 37), (78, 38), (98, 38), (145, 42), (146, 22), (146, 23), (146, 25), (146, 26), + (146, 42), (147, 22), (147, 23), (147, 25), (147, 26), (147, 30), (147, 31), (147, 32), (147, 42), + (148, 22), (148, 23), (148, 25), (148, 30), (148, 31), (148, 32), (148, 42), (149, 21), (149, 22), + (149, 23), (149, 24), (149, 30), (149, 31), (149, 42), (150, 21), (150, 22), (150, 23), (150, 24), + (150, 26), (150, 27), (150, 28), (150, 30), (150, 31), (150, 42), (151, 27), (151, 28), (151, 30), + (151, 31), (151, 42), (152, 27), (152, 29), (152, 30), (152, 31), (152, 42), (153, 27), (153, 29), + (153, 30), (153, 42), (154, 27), (154, 29), (154, 30), (164, 20), (167, 21), (167, 26), (167, 34), + (168, 21), (168, 25), (168, 27), (168, 33), (168, 35), (169, 20), (169, 24), (169, 28), (169, 33), + (169, 35), (170, 20), (170, 23), (170, 29), (170, 32), (170, 35), (171, 20), (171, 23), (171, 29), + (171, 32), (171, 36), (171, 37), (172, 21), (172, 22), (172, 30), (172, 31)], + "Mario Zone 2": + [(25, 24), (25, 27), (26, 24), (26, 27), (27, 24), (27, 27), (81, 27), (112, 24), (113, 24), + (114, 24), (115, 24), (116, 24), (117, 24), (118, 24), (121, 24), (122, 24), (123, 24), (124, 24), + (125, 24), (126, 24), (127, 24), (138, 26), (139, 26), (140, 24), (140, 28), (141, 24), (141, 28), + (144, 26), (145, 26), (146, 24), (146, 28), (147, 28), (151, 26), (152, 24), (152, 28), (153, 24), + (153, 28), (156, 26), (157, 26), (158, 24), (158, 28), (159, 24), (159, 28), (162, 26), (163, 26), + (164, 28), (165, 28)], + "Mario Zone 3": + [(8, 28), (11, 28), (14, 28), (17, 28), (20, 28), (23, 28), (54, 25), (100, 27), (109, 18), + (109, 19), (110, 18), (110, 19), (111, 17), (111, 18), (111, 19), (112, 17), (112, 18), (112, 19), + (127, 17), (127, 18), (127, 19), (128, 17), (128, 18), (128, 19), (129, 18), (129, 19), (130, 18), + (130, 19), (130, 20), (131, 18), (131, 19), (131, 20), (132, 18), (132, 19), (132, 20), (133, 18), + (133, 19), (133, 20), (133, 27), (134, 18), (134, 19), (134, 20), (157, 28), (158, 28), (159, 28), + (160, 28), (161, 28), (168, 28), (169, 28), (170, 28), (171, 28), (172, 28), (189, 44), (199, 28), + (200, 28), (201, 28), (202, 28), (203, 28), (214, 27), (217, 27), (220, 27), (223, 27)], + "Mario Zone 4": + [(20, 25), (114, 24), (114, 25), (114, 26), (115, 24), (115, 25), (115, 26), (115, 27), (115, 28), + (115, 29), (116, 24), (116, 25), (116, 26), (116, 27), (116, 29), (117, 24), (117, 25), (117, 26), + (117, 27), (117, 28), (117, 29), (118, 24), (118, 25), (118, 26), (118, 27), (118, 28), (118, 29), + (119, 24), (119, 25), (119, 27), (119, 28), (119, 29), (120, 24), (120, 25), (120, 26), (120, 27), + (120, 28), (120, 29), (121, 24), (121, 25), (121, 26), (121, 27), (121, 28), (121, 29), (122, 12), + (122, 24), (122, 25), (122, 26), (122, 27), (122, 29), (123, 12), (123, 24), (123, 25), (123, 26), + (123, 27), (123, 28), (123, 29), (124, 12), (124, 24), (124, 25), (124, 26), (124, 27), (124, 28), + (124, 29), (125, 12), (179, 12)], + "Pumpkin Zone 1": + [(23, 12), (55, 24), (55, 26), (56, 27), (57, 24), (57, 26), (63, 24), (63, 26), (64, 27), + (65, 24), (65, 26), (71, 24), (71, 26), (72, 27), (73, 24), (73, 26), (79, 24), (79, 26), + (80, 27), (81, 24), (81, 26), (86, 25), (86, 27), (92, 4), (93, 27), (95, 25), (95, 27), (98, 4), + (102, 26), (102, 28), (104, 4), (104, 26), (104, 28), (165, 14), (166, 15), (171, 20), (172, 21), + (173, 22), (175, 24), (176, 25), (177, 26), (179, 28), (180, 29), (189, 6)], + "Pumpkin Zone 2": + [(34, 26), (40, 21), (41, 21), (42, 21), (43, 21), (48, 20), (49, 20), (50, 20), (50, 41), + (51, 20), (51, 41), (52, 41), (53, 41), (54, 41), (56, 21), (57, 21), (58, 21), (59, 21), + (61, 41), (62, 41), (64, 20), (65, 20), (66, 20), (67, 20), (114, 36), (115, 35), (115, 36), + (116, 34), (116, 35), (116, 36), (132, 20), (132, 21), (132, 22), (132, 23), (132, 24), + (144, 23), (169, 27)], + "Pumpkin Zone 3": + [(18, 26), (20, 26), (22, 26), (24, 26), (26, 26), (31, 18), (32, 18), (33, 18), (34, 18), + (35, 18), (36, 18), (37, 18), (38, 18), (39, 18), (40, 18), (41, 18), (42, 18), (48, 24), + (52, 20), (52, 24), (56, 24), (87, 27), (88, 27), (89, 27), (90, 27), (94, 27), (95, 27), + (96, 27), (97, 27), (101, 27), (102, 27), (103, 27), (104, 27), (104, 42), (108, 27), (109, 27), + (110, 27), (111, 27), (115, 27), (116, 27), (117, 27), (118, 27), (134, 35), (134, 41), + (135, 35), (135, 41), (136, 35), (136, 41), (137, 35), (137, 41), (138, 35), (138, 41), + (139, 35), (139, 41), (140, 41), (225, 38), (226, 37), (227, 36), (227, 37), (227, 38), + (227, 39), (227, 40), (227, 41), (228, 37), (229, 38)], + "Pumpkin Zone Secret Course 1": + [(14, 15), (16, 9), (16, 10), (16, 11), (16, 12), (16, 13), (16, 14), (16, 15), (16, 16), + (17, 9), (17, 10), (17, 11), (17, 12), (17, 13), (17, 14), (17, 15), (17, 16), (18, 9), + (18, 10), (18, 11), (18, 12), (18, 13), (18, 14), (18, 15), (18, 16), (19, 9), (19, 10), + (19, 11), (19, 12), (19, 13), (19, 14), (19, 15), (19, 16), (20, 9), (20, 10), (20, 11), + (20, 12), (20, 13), (20, 14), (20, 15), (20, 16), (21, 9), (21, 10), (21, 11), (21, 12), + (21, 13), (21, 14), (21, 15), (21, 16), (22, 9), (22, 10), (22, 11), (22, 12), (22, 13), + (22, 14), (22, 15), (22, 16), (23, 9), (23, 10), (23, 11), (23, 12), (23, 13), (23, 14), + (23, 15), (23, 16), (24, 9), (24, 10), (24, 11), (24, 12), (24, 13), (24, 14), (24, 15), + (24, 16), (25, 9), (25, 10), (25, 11), (25, 12), (25, 13), (25, 14), (25, 15), (25, 16), + (26, 9), (26, 10), (26, 11), (26, 12), (26, 13), (26, 14), (26, 15), (27, 16), (28, 9), + (28, 10), (28, 11), (28, 12), (28, 13), (28, 14), (28, 15), (28, 16), (29, 9), (29, 10), + (29, 11), (29, 12), (29, 13), (29, 14), (29, 15), (29, 16), (30, 9), (30, 10), (30, 11), + (30, 12), (30, 13), (30, 14), (30, 15), (30, 16), (31, 9), (31, 10), (31, 11), (31, 12), + (31, 13), (31, 14), (31, 15), (31, 16), (32, 9), (32, 10), (32, 11), (32, 12), (32, 13), + (32, 14), (32, 15), (32, 16), (33, 9), (33, 10), (33, 11), (33, 12), (33, 13), (33, 14), + (33, 15), (33, 16), (34, 9), (34, 10), (34, 11), (34, 12), (34, 13), (34, 14), (34, 15), + (34, 16), (35, 9), (35, 10), (35, 11), (35, 12), (35, 13), (35, 14), (35, 15), (35, 16), + (36, 9), (36, 10), (36, 11), (36, 12), (36, 13), (36, 14), (36, 15), (36, 16), (37, 9), + (37, 10), (37, 11), (37, 12), (37, 13), (37, 14), (37, 15), (37, 16), (39, 16), (40, 9), + (40, 10), (40, 11), (40, 12), (40, 13), (40, 14), (40, 15), (40, 16), (41, 9), (41, 10), + (41, 11), (41, 12), (41, 13), (41, 14), (41, 15), (41, 16), (42, 9), (42, 10), (42, 11), + (42, 12), (42, 13), (42, 14), (42, 15), (42, 16), (43, 9), (43, 10), (43, 11), (43, 12), + (43, 13), (43, 14), (43, 15), (43, 16), (44, 9), (44, 10), (44, 11), (44, 12), (44, 13), + (44, 14), (44, 15), (44, 16), (45, 9), (45, 10), (45, 11), (45, 12), (45, 13), (45, 14), + (45, 15), (45, 16), (46, 9), (46, 10), (46, 11), (46, 12), (46, 13), (46, 14), (46, 15), + (46, 16), (47, 9), (47, 10), (47, 11), (47, 12), (47, 13), (47, 14), (47, 15), (47, 16), + (48, 9), (48, 10), (48, 11), (48, 12), (48, 13), (48, 14), (48, 15), (48, 16), (49, 9), + (49, 10), (49, 11), (49, 12), (49, 13), (49, 14), (49, 15), (49, 16), (52, 9), (52, 10), + (52, 11), (52, 12), (52, 13), (52, 14), (52, 15), (52, 16), (53, 9), (53, 10), (53, 11), + (53, 12), (53, 13), (53, 14), (53, 15), (53, 16), (54, 9), (54, 10), (54, 11), (54, 12), + (54, 13), (54, 14), (54, 15), (54, 16), (55, 9), (55, 10), (55, 11), (55, 12), (55, 13), + (55, 14), (55, 15), (55, 16), (56, 9), (56, 10), (56, 11), (56, 12), (56, 13), (56, 14), + (56, 15), (56, 16), (57, 9), (57, 10), (57, 11), (57, 12), (57, 13), (57, 14), (57, 15), + (57, 16), (58, 9), (58, 10), (58, 11), (58, 12), (58, 13), (58, 14), (58, 15), (58, 16), + (59, 9), (59, 10), (59, 11), (59, 12), (59, 13), (59, 14), (59, 15), (59, 16), (60, 9), + (60, 10), (60, 11), (60, 12), (60, 13), (60, 14), (60, 15), (60, 16), (61, 9), (61, 10), + (61, 11), (61, 12), (61, 13), (61, 14), (61, 15), (61, 16), (64, 9), (64, 10), (64, 11), + (64, 12), (64, 13), (64, 14), (64, 15), (64, 16), (65, 9), (65, 10), (65, 11), (65, 12), + (65, 13), (65, 14), (65, 15), (65, 16), (66, 9), (66, 10), (66, 11), (66, 12), (66, 13), + (66, 14), (66, 15), (66, 16), (67, 9), (67, 10), (67, 11), (67, 12), (67, 13), (67, 14), + (67, 15), (67, 16), (68, 9), (68, 10), (68, 11), (68, 12), (68, 13), (68, 14), (68, 15), + (68, 16), (69, 9), (69, 10), (69, 11), (69, 12), (69, 13), (69, 14), (69, 15), (69, 16), + (70, 9), (70, 10), (70, 11), (70, 12), (70, 13), (70, 14), (70, 15), (70, 16), (71, 9), + (71, 10), (71, 11), (71, 12), (71, 13), (71, 14), (71, 15), (71, 16), (72, 9), (72, 10), + (72, 11), (72, 12), (72, 13), (72, 14), (72, 15), (72, 16), (73, 9), (73, 10), (73, 11), + (73, 12), (73, 13), (73, 14), (73, 15), (73, 16)], + "Pumpkin Zone Secret Course 2": + [(12, 6), (72, 7), (73, 7), (80, 7), (81, 7), (85, 8), (90, 10), (91, 10), (94, 10), + (95, 10), (98, 9), (99, 9), (102, 9), (103, 9)], + "Pumpkin Zone 4": + [(18, 28), (19, 28), (20, 28), (21, 28), (83, 37), (83, 38), (84, 37), (84, 38), (85, 37), + (85, 38), (85, 39), (86, 37), (87, 37), (87, 40), (88, 37), (88, 38), (88, 39), (88, 40), + (89, 37), (89, 38), (89, 39), (89, 40), (90, 37), (90, 38), (91, 37), (91, 38), (92, 37), + (92, 38), (92, 39), (92, 40), (93, 23), (93, 37), (93, 40), (94, 23), (94, 37), (94, 40), + (103, 23), (104, 23), (113, 23), (114, 23), (169, 30), (170, 28), (170, 30), (171, 26), + (171, 28), (171, 30), (172, 24), (172, 26), (172, 28), (172, 30), (173, 24), (173, 26), + (173, 28), (173, 30), (174, 26), (174, 28), (174, 30), (175, 28), (175, 30), (176, 30), + (198, 37), (198, 38), (199, 37), (199, 38), (204, 37), (204, 38), (205, 37), (205, 38), + (210, 37), (210, 38), (211, 37), (211, 38), (216, 37), (216, 38), (217, 37), (217, 38)], + "Macro Zone 1": + [(22, 32), (22, 33), (22, 34), (23, 20), (23, 21), (23, 22), (23, 38), (23, 39), (23, 40), (24, 26), + (24, 27), (24, 28), (39, 42), (40, 41), (41, 40), (42, 39), (49, 43), (62, 42), (62, 43), (62, 44), + (68, 42), (68, 43), (68, 44), (75, 42), (75, 43), (75, 44), (84, 40), (84, 41), (84, 42), (87, 39), + (89, 42), (89, 43), (89, 44), (107, 42), (108, 42), (109, 42), (118, 42), (119, 42), (120, 42), + (121, 42), (122, 42), (128, 42), (128, 43), (130, 42), (130, 43), (134, 42), (134, 43), (140, 42), + (141, 42), (142, 42), (143, 42), (144, 42), (154, 42), (155, 42), (156, 42), (163, 22), (163, 23), + (164, 21), (164, 22), (164, 23), (165, 22), (165, 23), (166, 21), (166, 22), (166, 23), (167, 22), + (167, 23), (168, 21), (168, 22), (168, 23), (169, 22), (169, 23), (170, 21), (170, 22), (170, 23), + (171, 22), (171, 23), (177, 40), (182, 40), (189, 41), (189, 42), (189, 43), (189, 44), (189, 45), + (205, 46), (206, 46), (208, 37), (209, 37), (212, 41), (213, 41), (214, 41), (215, 41), (216, 41), + (220, 37), (221, 37), (224, 46), (225, 46), (234, 43), (246, 38), (246, 39), (246, 40), (246, 41), + (246, 42), (246, 43)], + "Macro Zone 2": + [(18, 28), (19, 27), (22, 28), (23, 27), (25, 26), (27, 27), (28, 27), (31, 27), (32, 27), (41, 29), + (42, 29), (43, 29), (55, 29), (57, 29), (60, 29), (62, 29), (69, 27), (70, 27), (71, 27), (74, 27), + (75, 27), (76, 27), (79, 27), (80, 27), (81, 27), (84, 27), (85, 27), (86, 27), (99, 40), + (137, 37), (180, 40), (181, 8), (182, 8), (183, 8), (184, 8), (185, 8), (186, 8), (187, 8), + (188, 8), (189, 8), (190, 8), (191, 8), (192, 8), (193, 8), (194, 8), (195, 8), (196, 8), (197, 8), + (198, 8), (199, 8), (200, 8), (201, 8), (202, 8), (204, 8), (205, 8), (206, 8), (207, 8), (208, 8), + (209, 8), (210, 8), (211, 8), (212, 8), (213, 8), (215, 8), (216, 8), (217, 8), (217, 11), + (218, 8), (218, 9), (218, 10), (218, 11), (218, 12), (219, 11)], + "Macro Zone 3": + [(24, 23), (37, 28), (38, 28), (39, 28), (40, 28), (57, 30), (58, 30), (59, 30), (65, 17), (65, 18), + (65, 19), (66, 17), (66, 18), (66, 19), (67, 17), (67, 18), (67, 19), (68, 17), (68, 18), (68, 19), + (69, 17), (69, 18), (69, 19), (70, 17), (70, 18), (70, 19), (73, 17), (73, 18), (73, 19), (74, 17), + (74, 18), (74, 19), (75, 17), (75, 18), (75, 19), (76, 17), (76, 18), (76, 19), (77, 17), (77, 18), + (77, 19), (78, 17), (78, 18), (78, 19), (85, 43), (95, 17), (95, 18), (95, 19), (95, 20), (96, 17), + (96, 18), (96, 19), (96, 20), (97, 17), (97, 18), (97, 19), (97, 20), (98, 17), (98, 18), (98, 19), + (98, 20), (100, 17), (100, 18), (100, 19), (100, 20), (101, 17), (101, 18), (101, 19), (101, 20), + (103, 42), (104, 42), (105, 42), (106, 42), (107, 42), (116, 42), (117, 42), (118, 42), (119, 42), + (120, 42), (121, 42), (122, 42), (129, 19), (131, 42), (132, 42), (133, 42), (134, 42), (135, 42), + (136, 42), (165, 21), (165, 22), (166, 21), (166, 22), (171, 21), (171, 22), (172, 21), (172, 22), + (176, 20), (176, 21), (176, 22), (179, 20), (179, 21), (179, 22), (183, 21), (183, 22), (184, 21), + (184, 22), (194, 27), (194, 28), (197, 27), (197, 28), (200, 27), (200, 28), (203, 25), (203, 27), + (203, 28), (205, 18), (205, 19), (206, 18), (206, 19)], + "Macro Zone 4": + [(16, 28), (34, 28), (39, 28), (39, 29), (39, 30), (40, 28), (40, 29), (40, 30), (41, 28), (41, 29), + (41, 30), (62, 29), (63, 29), (64, 29), (65, 29), (66, 29), (67, 29), (68, 29), (69, 29), (81, 17), + (81, 18), (82, 17), (82, 18), (83, 17), (83, 18), (84, 17), (84, 18), (85, 17), (85, 18), (86, 17), + (86, 18), (87, 17), (87, 18), (87, 28), (88, 17), (88, 18), (114, 28), (144, 22), (146, 27), + (146, 28), (147, 27), (147, 28), (148, 27), (148, 28), (149, 27), (149, 28), (150, 27), (150, 28), + (151, 27), (151, 28), (152, 27), (152, 28), (153, 27), (153, 28), (154, 27), (154, 28), (155, 27), + (155, 28), (156, 27), (156, 28), (157, 27), (157, 28), (158, 27), (158, 28)], + "Macro Zone Secret Course": + [(21, 24), (70, 27), (70, 28), (71, 27), (71, 28), (72, 27), (72, 28), (73, 27), (73, 28), + (74, 27), (74, 28), (75, 27), (75, 28), (76, 24), (76, 25), (76, 26), (76, 27), (76, 28), + (77, 24), (77, 25), (77, 26), (77, 27), (77, 28), (78, 24), (78, 25), (78, 26), (78, 27), + (78, 28), (79, 24), (79, 25), (79, 26), (79, 27), (80, 25), (80, 26), (81, 25), (81, 26), + (88, 25), (108, 30)], + "Mario's Castle": + [(7, 25), (160, 44), (167, 28), (247, 26)], +} +powerup_coords = { + "Mushroom Zone": [(42, 28), (151, 28), (152, 28), (188, 28)], + "Scenic Course": [(39, 28), (72, 28), (117, 28)], + "Tree Zone 1": [(119, 28), (152, 28)], + "Tree Zone 2": [(43, 10), (61, 9), (51, 28), (130, 7), (182, 3), (136, 43)], + "Tree Zone Secret Course": [(17, 23), (100, 23), (159, 23)], + "Tree Zone 3": [(26, 40), (77, 24)], + "Tree Zone 4": [(28, 27), (105, 25), (136, 22), (171, 10)], + "Tree Zone 5": [(123, 39), (138, 39), (146, 36)], + "Pumpkin Zone 1": [(23, 12), (72, 27), (98, 4), (189, 6)], + "Pumpkin Zone 2": [(144, 23)], + "Pumpkin Zone Secret Course 1": [(14, 15)], + "Pumpkin Zone 3": [(52, 20), (104, 42), (139, 35), (140, 41)], + "Pumpkin Zone Secret Course 2": [(12, 6), (85, 8)], + "Pumpkin Zone 4": [(83, 38), (94, 40), (104, 23)], + "Mario Zone 1": [(18, 44), (98, 38), (145, 42), (164, 20)], + "Mario Zone 2": [(81, 27)], + "Mario Zone 3": [(54, 25), (100, 27), (134, 18), (189, 44), (214, 27)], + "Mario Zone 4": [(20, 25), (124, 12), (179, 12)], + "Turtle Zone 1": [(22, 34), (56, 33), (57, 33), (143, 34), (189, 44)], + "Turtle Zone 2": [(82, 35), (139, 39), ], + "Turtle Zone Secret Course": [(19, 27), (53, 27), (64, 26), (87, 27), (121, 28), (122, 28), (123, 28)], + "Turtle Zone 3": [(39, 24), (94, 26), (152, 23)], + "Hippo Zone": [(3, 3), (2, 20), (15, 26), (16, 26), (29, 21), (86, 22), (137, 13)], + "Space Zone 1": [(75, 24), (114, 22)], + # "Space Zone Secret Course": [], + "Space Zone 2": [(64, 3), (102, 8), (120, 5), (207, 6), (210, 9), (248, 10)], + "Macro Zone 1": [(49, 43), (87, 39), (177, 40), (164, 21), (166, 21), (170, 21), (234, 43)], + "Macro Zone 2": [(25, 26), (99, 40), (137, 37), (180, 40)], + "Macro Zone 3": [(24, 23), (85, 43), (129, 19), (203, 25)], + "Macro Zone 4": [(16, 28), (87, 28), (144, 22)], + "Macro Zone Secret Course": [(21, 24), (88, 25), (108, 30)], + "Mario's Castle": [(7, 25), (160, 44), (167, 28), (247, 26)] +} +for zone, coords_list in powerup_coords.items(): + for coords in coords_list: + coins_coords[zone].remove(coords) + +location_name_to_id = {location_name: ID for ID, location_name in enumerate(locations, START_IDS)} +loc_id = START_IDS + len(locations) +for level, coin_coords in coins_coords.items(): + for i in range(1, len(coin_coords) + 1): + location_name_to_id[f"{level} - {i} Coin{'s' if i > 1 else ''}"] = loc_id + loc_id += 1 + +# eligible_levels = [0, 1, 2, 3, 5, 8, 9, 11, 13, 14, 16, 19, 20, 22, 23, 25, 30, 31] + +level_id_to_name = { + 0: "Mushroom Zone", 25: "Scenic Course", 1: "Tree Zone 1", 2: "Tree Zone 2", 4: "Tree Zone 3", 3: "Tree Zone 4", + 5: "Tree Zone 5", 29: "Tree Zone Secret Course", 17: "Hippo Zone", 18: "Space Zone 1", + 28: "Space Zone Secret Course", 19: "Space Zone 2", 20: "Macro Zone 1", 21: "Macro Zone 2", 22: "Macro Zone 3", + 23: "Macro Zone 4", 30: "Macro Zone Secret Course", 6: "Pumpkin Zone 1", 7: "Pumpkin Zone 2", + 8: "Pumpkin Zone 3", 9: "Pumpkin Zone 4", 27: "Pumpkin Zone Secret Course 1", 31: "Pumpkin Zone Secret Course 2", + 10: "Mario Zone 1", 11: "Mario Zone 2", 12: "Mario Zone 3", 13: "Mario Zone 4", 14: "Turtle Zone 1", + 15: "Turtle Zone 2", 16: "Turtle Zone 3", 26: "Turtle Zone Secret Course", 24: "Mario's Castle" +} + +level_name_to_id = {name: level_id for level_id, name in level_id_to_name.items()} + +auto_scroll_max = { + "Mushroom Zone": 84, + "Hippo Zone": 160, + "Tree Zone 1": 87, + "Tree Zone 2": 68, + "Tree Zone 3": 4, + "Tree Zone 4": 28, + "Tree Zone 5": 22, + "Space Zone 1": 72, + "Space Zone 2": 113, + "Space Zone Secret Course": 96, + "Macro Zone 1": 74, + "Macro Zone 2": 27, + "Macro Zone 3": 63, + "Macro Zone 4": 59, + "Pumpkin Zone 1": (0, 12), + "Pumpkin Zone 2": 23, + "Pumpkin Zone 3": 50, + "Pumpkin Zone 4": 45, + "Pumpkin Zone Secret Course 1": 172, + "Mario Zone 1": 68, + "Mario Zone 3": 29, + "Mario Zone 4": 60, + "Turtle Zone 1": 66, + "Turtle Zone 2": 8, +} diff --git a/worlds/marioland2/logic.py b/worlds/marioland2/logic.py new file mode 100644 index 000000000000..9934535572f9 --- /dev/null +++ b/worlds/marioland2/logic.py @@ -0,0 +1,608 @@ +from .locations import level_name_to_id + + +def is_auto_scroll(state, player, level): + level_id = level_name_to_id[level] + if state.has_any(["Cancel Auto Scroll", f"Cancel Auto Scroll - {level}"], player): + return False + return state.multiworld.worlds[player].auto_scroll_levels[level_id] > 0 + + +def has_pipe_right(state, player): + return state.has_any(["Pipe Traversal - Right", "Pipe Traversal"], player) + + +def has_pipe_left(state, player): + return state.has_any(["Pipe Traversal - Left", "Pipe Traversal"], player) + + +def has_pipe_down(state, player): + return state.has_any(["Pipe Traversal - Down", "Pipe Traversal"], player) + + +def has_pipe_up(state, player): + return state.has_any(["Pipe Traversal - Up", "Pipe Traversal"], player) + + +def has_level_progression(state, item, player, count=1): + return state.count(item, player) + (state.count(item + " x2", player) * 2) >= count + + +def mushroom_zone_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Mushroom Zone") + reachable_coins = 38 + if state.has_any(["Mushroom", "Fire Flower"], player) or not auto_scroll: + # Was able to get all but 1, being lenient. + reachable_coins += 2 + if has_pipe_down(state, player): + # There's 24 in each of the underground sections. + # The first one requires missing some question mark blocks if auto scrolling (the last +4). + # If you go in the second without pipe up, you can get everything except the last 5 plus the ones in the first + # underground section. + reachable_coins += 19 + if has_pipe_up(state, player) or not auto_scroll: + reachable_coins += 5 + if has_pipe_up(state, player): + reachable_coins += 20 + if not auto_scroll: + reachable_coins += 4 + return coins <= reachable_coins + + +def tree_zone_1_coins(state, player, coins): + return coins <= 87 or not is_auto_scroll(state, player, "Tree Zone 1") + + +def tree_zone_2_normal_exit(state, player): + return has_pipe_right(state, player) or state.has("Tree Zone 2 Midway Bell", player) + + +def tree_zone_2_secret_exit(state, player): + return has_pipe_right(state, player) and state.has("Carrot", player) + + +def tree_zone_2_midway_bell(state, player): + return has_pipe_right(state, player) or state.has("Tree Zone 2 Midway Bell", player) + + +def tree_zone_2_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Tree Zone 2") + reachable_coins = 18 + if has_pipe_right(state, player): + reachable_coins += 38 + if state.has("Carrot", player): + reachable_coins += 12 + if not auto_scroll: + reachable_coins += 30 + elif state.has("Tree Zone 2 Midway Bell", player): + reachable_coins = 30 + if not auto_scroll: + reachable_coins += 8 + return coins <= reachable_coins + + +def tree_zone_3_normal_exit(state, player): + return not is_auto_scroll(state, player, "Tree Zone 3") + + +def tree_zone_3_coins(state, player, coins): + if is_auto_scroll(state, player, "Tree Zone 3"): + return coins <= 4 + if coins <= 19: + return True + elif state.has_any(["Mushroom", "Fire Flower"], player) and coins <= 21: + return True + return state.has("Carrot", player) + + +def tree_zone_4_normal_exit(state, player): + return has_pipe_down(state, player) and tree_zone_4_midway_bell(state, player) + + +def tree_zone_4_midway_bell(state, player): + return ((has_pipe_right(state, player) and has_pipe_up(state, player)) + or state.has("Tree Zone 4 Midway Bell", player)) + + +def tree_zone_4_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Tree Zone 4") + reachable_coins = 0 + if has_pipe_up(state, player): + reachable_coins += 14 + if has_pipe_right(state, player): + reachable_coins += 4 + if has_pipe_down(state, player): + reachable_coins += 10 + if not auto_scroll: + reachable_coins += 46 + elif state.has("Tree Zone 4 Midway Bell", player): + if not auto_scroll: + if has_pipe_left(state, player): + reachable_coins += 18 + if has_pipe_down(state, player): + reachable_coins += 10 + if has_pipe_up(state, player): + reachable_coins += 46 + elif has_pipe_down(state, player): + reachable_coins += 10 + return coins <= reachable_coins + + +def tree_zone_5_boss(state, player): + return has_pipe_right(state, player) and (has_pipe_up(state, player) or state.has("Carrot", player)) + + +def tree_zone_5_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Tree Zone 5") + reachable_coins = 0 + # Not actually sure if these platforms can be randomized / can make the coin blocks unreachable from below + if ((not state.multiworld.worlds[player].options.randomize_platforms) + or state.has_any(["Mushroom", "Fire Flower"], player)): + reachable_coins += 2 + if state.has_any(["Mushroom", "Fire Flower"], player): + reachable_coins += 2 + if state.has("Carrot", player): + reachable_coins += 18 + if has_pipe_up(state, player) and not auto_scroll: + reachable_coins += 13 + elif has_pipe_up(state, player): + reachable_coins += 13 + return coins <= reachable_coins + + +def pumpkin_zone_1_normal_exit(state, player): + return pumpkin_zone_1_midway_bell(state, player) + + +def pumpkin_zone_1_midway_bell(state, player): + return ((has_pipe_down(state, player) and not is_auto_scroll(state, player, "Pumpkin Zone 1")) + or state.has("Pumpkin Zone 1 Midway Bell", player)) + + +def pumpkin_zone_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Pumpkin Zone 1") + if auto_scroll: + return coins <= 12 and state.has("Pumpkin Zone 1 Midway Bell", player) + reachable_coins = 0 + if state.has("Pumpkin Zone 1 Midway Bell", player) or has_pipe_down(state, player): + reachable_coins += 38 + if has_pipe_up(state, player): + reachable_coins += 2 + return coins <= reachable_coins + + +def pumpkin_zone_2_normal_exit(state, player): + return has_pipe_down(state, player) and has_pipe_up(state, player) and has_pipe_right(state, player) and state.has( + "Water Physics", player) and not is_auto_scroll(state, player, "Pumpkin Zone 2") + + +def pumpkin_zone_2_secret_exit(state, player): + return pumpkin_zone_2_normal_exit(state, player) and state.has_any(["Mushroom", "Fire Flower"], player) + + +def pumpkin_zone_2_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Pumpkin Zone 2") + reachable_coins = 17 + if has_pipe_down(state, player): + if not auto_scroll: + reachable_coins += 7 + if (has_pipe_up(state, player) or auto_scroll) and state.has("Water Physics", player): + reachable_coins += 6 + if has_pipe_right(state, player) and not auto_scroll: + reachable_coins += 1 + if state.has_any(["Mushroom", "Fire Flower"], player): + reachable_coins += 5 + return coins <= reachable_coins + + +def pumpkin_zone_secret_course_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Pumpkin Zone Secret Course 1") + # We'll be a bit forgiving. I was able to reach 43 while small. + if coins <= 40: + return True + if state.has("Carrot", player): + if auto_scroll: + return coins <= 172 + return True + return False + + +def pumpkin_zone_3_secret_exit(state, player): + return state.has("Carrot", player) + + +def pumpkin_zone_3_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Pumpkin Zone 3") + reachable_coins = 38 + if has_pipe_up(state, player) and ((not auto_scroll) or has_pipe_down(state, player)): + reachable_coins += 12 + if has_pipe_down(state, player) and not auto_scroll: + reachable_coins += 11 + return coins <= reachable_coins + + +def pumpkin_zone_4_boss(state, player): + return has_pipe_right(state, player) + + +def pumpkin_zone_4_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Pumpkin Zone 4") + reachable_coins = 29 + if has_pipe_down(state, player): + if auto_scroll: + if has_pipe_up(state, player): + reachable_coins += 16 + else: + reachable_coins += 4 + else: + reachable_coins += 28 + # both sets of coins are down, but you need pipe up to return to go down to the next set in one playthrough + if has_pipe_up(state, player): + reachable_coins += 16 + return coins <= reachable_coins + + +def mario_zone_1_normal_exit(state, player): + if has_pipe_right(state, player): + if state.has_any(["Mushroom", "Fire Flower", "Carrot", "Mario Zone 1 Midway Bell"], player): + return True + if is_auto_scroll(state, player, "Mario Zone 1"): + return True + return False + + +def mario_zone_1_midway_bell(state, player): + # It is possible to get as small mario, but it is a very precise jump and you will die afterward. + return ((state.has_any(["Mushroom", "Fire Flower", "Carrot"], player) and has_pipe_right(state, player)) + or state.has("Mario Zone 1 Midway Bell", player)) + + +def mario_zone_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Mario Zone 1") + reachable_coins = 0 + if has_pipe_right(state, player) or (has_pipe_left(state, player) + and state.has("Mario Zone 1 Midway Bell", player) and not auto_scroll): + reachable_coins += 32 + if has_pipe_right(state, player) and (state.has_any(["Mushroom", "Fire Flower", "Carrot"], player) + or not auto_scroll): + reachable_coins += 8 + # coins from end section. I was able to get 13 as small mario, giving some leniency + if state.has("Carrot", player): + reachable_coins += 28 + else: + reachable_coins += 12 + if state.has("Fire Flower", player) and not auto_scroll: + reachable_coins += 46 + return coins <= reachable_coins + + +def mario_zone_3_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Mario Zone 3") + reachable_coins = 10 + if state.has("Carrot", player): + reachable_spike_coins = 15 + else: + sprites = state.multiworld.worlds[player].sprite_data["Mario Zone 3"] + reachable_spike_coins = min(3, len({sprites[i]["sprite"] == "Claw Grabber" for i in (17, 18, 25)}) + + state.has("Mushroom", player) + state.has("Fire Flower", player)) * 5 + reachable_coins += reachable_spike_coins + if not auto_scroll: + reachable_coins += 10 + if state.has("Fire Flower", player): + reachable_coins += 22 + if auto_scroll: + reachable_coins -= 3 + reachable_spike_coins + return coins <= reachable_coins + + +def mario_zone_4_boss(state, player): + return has_pipe_right(state, player) + + +def mario_zone_4_coins(state, player, coins): + return coins <= 60 or not is_auto_scroll(state, player, "Mario Zone 4") + + +def not_blocked_by_sharks(state, player): + sharks = [state.multiworld.worlds[player].sprite_data["Turtle Zone 1"][i]["sprite"] + for i in (27, 28)].count("Shark") + if state.has("Carrot", player) or not sharks: + return True + if sharks == 2: + return state.has_all(["Mushroom", "Fire Flower"], player) + if sharks == 1: + return state.has_any(["Mushroom", "Fire Flower"], player) + return False + + +def turtle_zone_1_normal_exit(state, player): + return not_blocked_by_sharks(state, player) + + +def turtle_zone_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Turtle Zone 1") + reachable_coins = 30 + if not_blocked_by_sharks(state, player): + reachable_coins += 13 + if auto_scroll: + reachable_coins -= 1 + if state.has("Water Physics", player) or state.has("Carrot", player): + reachable_coins += 10 + if state.has("Carrot", player): + reachable_coins += 24 + if auto_scroll: + reachable_coins -= 10 + return coins <= reachable_coins + + +def turtle_zone_2_normal_exit(state, player): + return (has_pipe_up(state, player) and has_pipe_down(state, player) and has_pipe_right(state, player) and + has_pipe_left(state, player) and state.has("Water Physics", player) + and not is_auto_scroll(state, player, "Turtle Zone 2")) + + +def turtle_zone_2_secret_exit(state, player): + return (has_pipe_up(state, player) and state.has("Water Physics", player) + and not is_auto_scroll(state, player, "Turtle Zone 2")) + + +def turtle_zone_2_midway_bell(state, player): + return ((state.has("Water Physics", player) and not is_auto_scroll(state, player, "Turtle Zone 2")) + or state.has("Turtle Zone 2 Midway Bell", player)) + + +def turtle_zone_2_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Turtle Zone 2") + reachable_coins = 2 + if auto_scroll: + if state.has("Water Physics", player): + reachable_coins += 6 + else: + reachable_coins += 2 + if state.has("Water Physics", player): + reachable_coins += 20 + elif state.has("Turtle Zone 2 Midway Bell", player): + reachable_coins += 4 + if (has_pipe_right(state, player) and has_pipe_down(state, player) + and state.has_any(["Water Physics", "Turtle Zone 2 Midway Bell"], player)): + reachable_coins += 1 + if has_pipe_left(state, player) and has_pipe_up(state, player): + reachable_coins += 1 + if state.has("Water Physics", player): + reachable_coins += 1 + return coins <= reachable_coins + + +def turtle_zone_secret_course_normal_exit(state, player): + return state.has_any(["Fire Flower", "Carrot"], player) + + +def turtle_zone_secret_course_coins(state, player, coins): + reachable_coins = 53 + if state.has("Carrot", player): + reachable_coins += 44 + elif state.has("Fire Flower", player): + reachable_coins += 36 # was able to get 38, some leniency + return coins <= reachable_coins + + +def turtle_zone_3_boss(state, player): + return has_pipe_right(state, player) + + +def turtle_zone_3_coins(state, player, coins): + return state.has_any(["Water Physics", "Mushroom", "Fire Flower", "Carrot"], player) or coins <= 51 + + +def hippo_zone_normal_or_secret_exit(state, player): + return (state.has_any(["Hippo Bubble", "Water Physics"], player) + or (state.has("Carrot", player) + and not is_auto_scroll(state, player, "Hippo Zone"))) + + +def hippo_zone_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Hippo Zone") + # This is all somewhat forgiving. + reachable_coins = 4 + if auto_scroll: + if state.has("Hippo Bubble", player): + reachable_coins = 160 + elif state.has("Carrot", player): + reachable_coins = 90 + elif state.has("Water Physics", player): + reachable_coins = 28 + else: + if state.has_any(["Water Physics", "Hippo Bubble", "Carrot"], player): + reachable_coins += 108 + if state.has_any(["Mushroom", "Fire Flower", "Hippo Bubble"], player): + reachable_coins += 6 + if state.has_all(["Fire Flower", "Water Physics"], player): + reachable_coins += 1 + if state.has("Hippo Bubble", player): + reachable_coins += 52 + return coins <= reachable_coins + + +def space_zone_1_normal_exit(state, player): + # It is possible, however tricky, to beat the Moon Stage without Carrot or Space Physics. + # However, it requires somewhat precisely jumping off enemies. Enemy shuffle may make this impossible. + # Instead, I will just always make one or the other required, since it is difficult without them anyway. + return state.has_any(["Space Physics", "Carrot"], player) + + +def space_zone_1_secret_exit(state, player): + # One or the other is actually necessary for the secret exit. + return state.has_any(["Space Physics", "Carrot"], player) and not is_auto_scroll(state, player, "Space Zone 1") + + +def space_zone_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Space Zone 1") + if auto_scroll: + reachable_coins = 12 + if state.has_any(["Carrot", "Space Physics"], player): + reachable_coins += 20 + # If you have Space Physics, you can't make it up to the upper section. We have to assume you might have it, + # so the coins up there must be out of logic if there is auto scrolling. + if state.has("Space Physics", player): + reachable_coins += 40 + return coins <= reachable_coins + return (coins <= 21 or (coins <= 50 and state.has_any(["Mushroom", "Fire Flower"], player)) + or state.has_any(["Carrot", "Space Physics"], player)) + + +def space_zone_2_midway_bell(state, player): + return state.has_any(["Space Physics", "Space Zone 2 Midway Bell", "Mushroom", "Fire Flower", "Carrot"], player) + + +def space_zone_2_boss(state, player): + if has_pipe_right(state, player): + if state.has("Space Physics", player): + return True + if (state.has("Space Zone 2 Midway Bell", player) + or not state.multiworld.worlds[player].options.shuffle_midway_bells): + # Reaching the midway bell without space physics requires taking damage once. Reaching the end pipe from the + # midway bell also requires taking damage once. + if state.has_any(["Mushroom", "Fire Flower", "Carrot"], player): + return True + else: + # With no midway bell, you'll have to be able to take damage twice. + if state.has("Mushroom", player) and state.has_any(["Fire Flower", "Carrot"], player): + return True + return False + + +def space_zone_2_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Space Zone 2") + reachable_coins = 12 + if state.has_any(["Mushroom", "Fire Flower", "Carrot", "Space Physics"], player): + reachable_coins += 15 + if state.has("Space Physics", player) or not auto_scroll: + reachable_coins += 4 # last few bottom row question mark blocks that are hard to get when auto scrolling. + if (state.has("Space Physics", player) or ( + state.has("Mushroom", player) and state.has_any(["Fire Flower", "Carrot"], player))): + reachable_coins += 3 + if state.has("Space Physics", player): + reachable_coins += 79 + if not auto_scroll: + reachable_coins += 21 + return coins <= reachable_coins + + +def space_zone_secret_course_coins(state, player, coins): + return coins <= 96 or not is_auto_scroll(state, player, "Space Zone Secret Course") + + +def macro_zone_1_normal_exit(state, player): + return has_pipe_down(state, player) or state.has("Macro Zone 1 Midway Bell", player) + + +def macro_zone_1_secret_exit(state, player): + return state.has("Fire Flower", player) and has_pipe_up(state, player) and macro_zone_1_midway_bell(state, player) + + +def macro_zone_1_midway_bell(state, player): + return has_pipe_down(state, player) or state.has("Macro Zone 1 Midway Bell", player) + + +def macro_zone_1_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Macro Zone 1") + reachable_coins = 0 + if has_pipe_down(state, player): + reachable_coins += 69 + if auto_scroll: + if state.has_any(["Mushroom", "Fire Flower"], player): + reachable_coins += 5 + else: + reachable_coins += 9 + if state.has("Fire Flower", player): + reachable_coins += 19 + elif state.has("Macro Zone 1 Midway Bell", player): + if auto_scroll: + reachable_coins += 16 + if state.has_any(["Mushroom", "Fire Flower"], player): + reachable_coins += 5 + else: + reachable_coins += 67 + return coins <= reachable_coins + + +def macro_zone_secret_course_coins(state, player, coins): + return state.has_any(["Mushroom", "Fire Flower"], player) + + +def macro_zone_2_normal_exit(state, player): + return (has_pipe_down(state, player) or state.has("Macro Zone 2 Midway Bell", player)) and state.has( + "Water Physics", player) and has_pipe_up(state, player) and not is_auto_scroll(state, player, "Macro Zone 2") + + +def macro_zone_2_midway_bell(state, player): + return ((has_pipe_down(state, player) and state.has("Water Physics", player)) + or state.has("Macro Zone 2 Midway Bell", player)) + + +def macro_zone_2_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Macro Zone 2") + if coins <= 27: + return True + if has_pipe_up(state, player) and state.has("Water Physics", player) and not auto_scroll: + if has_pipe_down(state, player): + return True + if state.has("Macro Zone 2 Midway Bell", player): + # Cannot return to the first section from the bell + return coins <= 42 + return False + + +def macro_zone_3_normal_exit(state, player): + return ((has_pipe_down(state, player) and has_pipe_up(state, player)) + or state.has("Macro Zone 3 Midway Bell", player)) + + +def macro_zone_3_midway_bell(state, player): + return macro_zone_3_normal_exit(state, player) + + +def macro_zone_3_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Macro Zone 3") + reachable_coins = 7 + if not auto_scroll: + reachable_coins += 17 + if has_pipe_up(state, player) and has_pipe_down(state, player): + if auto_scroll: + reachable_coins += 56 + else: + return True + elif has_pipe_up(state, player): + if auto_scroll: + reachable_coins += 12 + else: + reachable_coins += 36 + elif has_pipe_down(state, player): + reachable_coins += 18 + if state.has("Macro Zone 3 - Midway Bell", player): + reachable_coins = max(reachable_coins, 30) + return coins <= reachable_coins + + +def macro_zone_4_boss(state, player): + return has_pipe_right(state, player) + + +def macro_zone_4_coins(state, player, coins): + auto_scroll = is_auto_scroll(state, player, "Macro Zone 4") + reachable_coins = 61 + if auto_scroll: + reachable_coins -= 8 + if state.has("Carrot", player): + reachable_coins += 6 + return coins <= reachable_coins + + +def marios_castle_wario(state, player): + return ((has_pipe_right(state, player) and has_pipe_left(state, player)) + or state.has("Mario's Castle Midway Bell", player)) + + +def marios_castle_midway_bell(state, player): + return ((has_pipe_right(state, player) and has_pipe_left(state, player)) + or state.has("Mario's Castle Midway Bell", player)) diff --git a/worlds/marioland2/options.py b/worlds/marioland2/options.py new file mode 100644 index 000000000000..ace8444b3fb6 --- /dev/null +++ b/worlds/marioland2/options.py @@ -0,0 +1,198 @@ +from Options import Toggle, Choice, NamedRange, Range, PerGameCommonOptions, ItemsAccessibility +from dataclasses import dataclass + + +class ShuffleGoldenCoins(Choice): + """ + Vanilla: Golden Coins are received when defeating bosses. + Shuffle: Shuffle the Golden Coins into the item pool and make bosses location checks. + Mario Coin Fragment Hunt: You start with all Golden Coins except the Mario Coin, which has been fragmented into many pieces. + You will see a Golden Coin being received when defeating bosses regardless of whether you are actually getting a coin. + """ + display_name = "Shuffle Golden Coins" + default = 0 + option_vanilla = 0 + option_shuffle = 1 + option_mario_coin_fragment_hunt = 2 + + +class GoldenCoinsRequired(Range): + """ + Number of Golden Coins required to enter Mario's Castle. Ignored on Mario Coin Fragment Hunt. + """ + display_name = "Golden Coins Required" + range_start = 0 + range_end = 6 + default = 6 + + +class MarioCoinFragmentPercentage(Range): + """ + Percentage of filler items to be replaced with Mario Coin Fragments. Note that the Coinsanity and Coinsanity + Checks options will greatly impact the number of replaceable filler items. + """ + display_name = "Mario Coin Fragment Percentage" + range_start = 1 + range_end = 50 + default = 20 + + +class MarioCoinFragmentsRequiredPercentage(Range): + """ + Percentage of the Mario Coins in the item pool that are required to put the Mario Coin together. + """ + display_name = "Mario Coin Fragments Required Percentage" + range_start = 1 + range_end = 100 + default = 75 + + +class ShuffleMidwayBells(Toggle): + """ + Shuffle Midway Bells into the item pool. You can always start at the beginning of a level after obtaining the + Midway Bell by holding SELECT while entering the level (until you load into the level). + The Midway Bells in levels will trigger location checks whether this option is on or not, but they will only + set the checkpoint if this is off, otherwise you must obtain the Midway Bell item from the item pool. + """ + display_name = "Shuffle Midway Bells" + + +class MariosCastleMidwayBell(Toggle): + """ + Adds a Midway Bell to the final stage, just before the Wario fight. + """ + display_name = "Mario's Castle Midway Bell" + + +class Coinsanity(Toggle): + """ + Shuffles the singular coins found freestanding and in question mark blocks into the item pool, and adds location + checks made by obtaining a sufficient number of coins in particular levels within a single playthrough. + """ + display_name = "Coinsanity" + + +class CoinsanityChecks(Range): + """ + Number of Coinsanity checks. + A higher number means more checks, and smaller coin amounts per coin item in the item pool. + If Accessibility is set to Full, auto-scroll levels may have a lower maximum count, which may lead to this + value being limited. + """ + display_name = "Coinsanity Checks" + range_start = 31 + range_end = 2599 + default = 150 + + +class DifficultyMode(Choice): + """ + Play in normal or easy mode. You can also start in Normal Mode with an "upgrade" to Easy Mode in the item pool, + or start in Easy Mode with a Normal Mode "trap" in the item pool. + """ + display_name = "Difficulty Mode" + option_normal = 0 + option_easy = 1 + option_normal_to_easy = 2 + option_easy_to_normal = 3 + default = 0 + + +class ShufflePipeTraversal(Choice): + """ + Single: Shuffle a Pipe Traversal item into the item pool, which is required to enter any pipes. + Split: Shuffle 4 Pipe Traversal items, one required for entering pipes from each direction. + Note that being unable to enter pipes is very limiting and affects nearly half of all levels. + """ + display_name = "Shuffle Pipe Traversal" + option_off = 0 + option_single = 1 + option_split = 2 + default = 0 + + +class RandomizeEnemies(Toggle): + """ + Randomize enemies throughout levels. + """ + display_name = "Randomize Enemies" + + +class RandomizePlatforms(Toggle): + """ + Randomize platforms throughout levels. + """ + display_name = "Randomize Platforms" + + +class AutoScrollChances(NamedRange): + """ + Chance per eligible level to be made into an auto scroll level. Can also set to Vanilla to leave them unchanged. + """ + display_name = "Auto Scroll Chance" + range_start = 0 + range_end = 100 + special_range_names = {"vanilla": -1, "none": 0, "all": 100} + default = -1 + + +class AutoScrollMode(Choice): + """ + Always: Any auto scroll levels will always auto-scroll. + Global Trap Item: Auto scroll levels will only auto-scroll after obtaining the Auto Scroll trap item. + Level Trap Items: As with Trap Item, but there is a separate trap item for each auto scroll level. + Global Cancel Item: Auto Scroll levels will stop auto-scrolling after obtaining the Auto Scroll Cancel item. + Level Cancel Items: As with Cancel Item, but there is a separate cancel item for each auto scroll level. + Chaos: Each level will randomly always auto scroll, have an Auto Scroll Trap, or have an Auto Scroll Cancel item. + The effects of Trap and Cancel items are permanent! If Accessibility is not set to Full, + Traps may cause locations to become permanently unreachable. + With individual level items, the number of auto scroll levels may be limited by the available space in the item + pool. + """ + display_name = "Auto Scroll Mode" + option_always = 0 + option_global_trap_item = 1 + option_level_trap_items = 2 + option_global_cancel_item = 3 + option_level_cancel_items = 4 + option_chaos = 5 + default = 0 + + +class RandomizeMusic(Toggle): + """ + Randomize the music that plays in levels and overworld areas. + """ + display_name = "Randomize Music" + + +class EnergyLink(Toggle): + """ + All extra lives beyond 1 are transferred into the server's shared EnergyLink storage. If you drop to 0, + 1 will be replenished if there is sufficient energy stored. + """ + display_name = "Energy Link" + default = 1 + + + + +@dataclass +class SML2Options(PerGameCommonOptions): + accessibility: ItemsAccessibility + shuffle_golden_coins: ShuffleGoldenCoins + required_golden_coins: GoldenCoinsRequired + mario_coin_fragment_percentage: MarioCoinFragmentPercentage + mario_coin_fragments_required_percentage: MarioCoinFragmentsRequiredPercentage + coinsanity: Coinsanity + coinsanity_checks: CoinsanityChecks + shuffle_midway_bells: ShuffleMidwayBells + marios_castle_midway_bell: MariosCastleMidwayBell + shuffle_pipe_traversal: ShufflePipeTraversal + auto_scroll_mode: AutoScrollMode + auto_scroll_chances: AutoScrollChances + difficulty_mode: DifficultyMode + randomize_enemies: RandomizeEnemies + randomize_platforms: RandomizePlatforms + randomize_music: RandomizeMusic + energy_link: EnergyLink diff --git a/worlds/marioland2/rom.py b/worlds/marioland2/rom.py new file mode 100644 index 000000000000..2a19a9cb8cad --- /dev/null +++ b/worlds/marioland2/rom.py @@ -0,0 +1,146 @@ +import hashlib +import os +import pkgutil + +import Utils + +from worlds.Files import APProcedurePatch, APTokenMixin, APTokenTypes +from settings import get_settings + +from .rom_addresses import rom_addresses +from .sprites import sprite_name_to_id + + +def randomize_music(patch, random): + # overworld + overworld_music_tracks = [0x05, 0x06, 0x0D, 0x0E, 0x10, 0x12, 0x1B, 0x1C, 0x1E] + random.shuffle(overworld_music_tracks) + for i, track in zip([0x3004F, 0x3EA9B, 0x3D186, 0x3D52B, 0x3D401, 0x3D297, 0x3D840, 0x3D694, 0x3D758], + overworld_music_tracks): + patch.write_bytes(i, track) + # levels + for i in range(0x5619, 0x5899, 0x14): + patch.write_bytes(i, random.choice([0x01, 0x0B, 0x11, 0x13, 0x14, 0x17, 0x1D, 0x1F, 0x28])) + + +def generate_output(self, output_directory: str): + + patch = SuperMarioLand2ProcedurePatch(player=self.player, player_name=self.player_name) + + patch.write_file("basepatch.bsdiff4", pkgutil.get_data(__name__, "basepatch.bsdiff4")) + random = self.random + + if self.options.marios_castle_midway_bell: + # Remove Question Mark Block + patch.write_bytes(0x4F012, 0x5D) + # Fix level pointer to read midway bell flag + patch.write_bytes(0x3E569, 0x18) + patch.write_bytes(0x3E56A, 0x18) + # Position and screen coordinates + patch.write_bytes(0x383B, [0xD4, 0x01, 0x4D, 0x0A, 0xC0, 0x01, 0x50, 0x0A]) + + if self.options.coinsanity: + # Add platform to return to start of Pumpkin Zone Secret Course 1 + patch.write_bytes(0x258B6, 0x3B) + patch.write_bytes(0x258F8, 0x7a) + patch.write_bytes(0x2594D, 0x67) + patch.write_bytes(0x259A8, 0x68) + patch.write_bytes(0x259A9, 0x60) + + i = 0xe077 + for level, sprites in self.sprite_data.items(): + for sprite_data in sprites: + sprite_id = sprite_name_to_id[sprite_data["sprite"]] + data = [((sprite_id & 0b01000000) >> 2) | ((sprite_id & 0b00111000) << 2) | sprite_data["screen"], + ((sprite_id & 0b00000111) << 5) | sprite_data["x"], + sprite_data["misc"] | sprite_data["y"]] + patch.write_bytes(i, data) + i += 3 + patch.write_bytes(i, 255) + i += 1 + + if self.options.randomize_music: + randomize_music(patch, random) + + if self.options.shuffle_golden_coins: + patch.write_bytes(rom_addresses["Coin_Shuffle"], 0x40) + if self.options.shuffle_midway_bells: + patch.write_bytes(rom_addresses["Disable_Midway_Bell"], 0xC9) + + if self.options.coinsanity: + for section in ("A", "B"): + for i in range(0, 30): + patch.write_bytes(rom_addresses[f"Coinsanity_{section}"] + i, 0x00) + + star_count = max(len([loc for loc in self.multiworld.get_filled_locations() if loc.item.player == self.player + and loc.item.name == "Super Star Duration Increase"]), 1) + patch.write_bytes(rom_addresses["Star_Count"], star_count // 256) + patch.write_bytes(rom_addresses["Star_Count"] + 1, star_count - (star_count // 256)) + if self.options.shuffle_golden_coins == "mario_coin_fragment_hunt": + patch.write_bytes(rom_addresses["Coins_Required"], self.coin_fragments_required // 256) + patch.write_bytes(rom_addresses["Coins_Required"] + 1, self.coin_fragments_required % 256) + patch.write_bytes(rom_addresses["Required_Golden_Coins"], 6) + else: + patch.write_bytes(rom_addresses["Coins_Required"] + 1, self.options.required_golden_coins.value) + patch.write_bytes(rom_addresses["Required_Golden_Coins"], self.options.required_golden_coins.value) + patch.write_bytes(rom_addresses["Midway_Bells"], self.options.shuffle_midway_bells.value) + patch.write_bytes(rom_addresses["Energy_Link"], self.options.energy_link.value) + patch.write_bytes(rom_addresses["Difficulty_Mode"], self.options.difficulty_mode.value) + patch.write_bytes(rom_addresses["Coin_Mode"], self.options.shuffle_golden_coins.value) + + for level, i in enumerate(self.auto_scroll_levels): + # We set 0 if no auto scroll or auto scroll trap, so it defaults to no auto scroll. 1 if always or cancel items. + patch.write_bytes(rom_addresses["Auto_Scroll_Levels"] + level, max(0, i - 1)) + patch.write_bytes(rom_addresses["Auto_Scroll_Levels_B"] + level, i) + + if self.options.energy_link: + # start with 1 life if Energy Link is on so that you don't deposit lives at the start of the game. + patch.write_bytes(rom_addresses["Starting_Lives"], 1) + + rom_name = bytearray(f'AP{Utils.__version__.replace(".", "")[0:3]}_{self.player}_{self.multiworld.seed:11}\0', + 'utf8')[:21] + rom_name.extend([0] * (21 - len(rom_name))) + patch.write_bytes(0x77777, rom_name) + patch.write_file("tokens.bin", patch.get_token_binary()) + patch.write(os.path.join(output_directory, + f"{self.multiworld.get_out_file_name_base(self.player)}{patch.patch_file_ending}")) + + +class SuperMarioLand2ProcedurePatch(APProcedurePatch, APTokenMixin): + hash = "a8413347d5df8c9d14f97f0330d67bce" + patch_file_ending = ".apsml2" + game = "Super Mario Land 2" + result_file_ending = ".gb" + procedure = [ + ("apply_bsdiff4", ["basepatch.bsdiff4"]), + ("apply_tokens", ["tokens.bin"]), + ] + + @classmethod + def get_source_data(cls) -> bytes: + return get_base_rom_bytes() + + def write_bytes(self, offset, value): + if isinstance(value, int): + value = [value] + self.write_token(APTokenTypes.WRITE, offset, bytes(value)) + + +def get_base_rom_bytes(): + file_name = get_base_rom_path() + with open(file_name, "rb") as file: + base_rom_bytes = bytes(file.read()) + + basemd5 = hashlib.md5() + basemd5.update(base_rom_bytes) + if SuperMarioLand2ProcedurePatch.hash != basemd5.hexdigest(): + raise Exception("Supplied Base Rom does not match known MD5 for Super Mario Land 1.0. " + "Get the correct game and version, then dump it") + return base_rom_bytes + + +def get_base_rom_path(): + file_name = get_settings()["sml2_options"]["rom_file"] + if not os.path.exists(file_name): + file_name = Utils.user_path(file_name) + return file_name \ No newline at end of file diff --git a/worlds/marioland2/rom_addresses.py b/worlds/marioland2/rom_addresses.py new file mode 100644 index 000000000000..e4b4f69cd71e --- /dev/null +++ b/worlds/marioland2/rom_addresses.py @@ -0,0 +1,39 @@ +rom_addresses = { + "Space_Physics": 0x4e7, + "Pipe_Traversal_A": 0x11a4, + "Pipe_Traversal_SFX_A": 0x11a9, + "Pipe_Traversal_B": 0x11d6, + "Pipe_Traversal_SFX_B": 0x11e7, + "Pipe_Traversal_C": 0x1226, + "Pipe_Traversal_SFX_C": 0x123f, + "Pipe_Traversal_D": 0x1256, + "Pipe_Traversal_SFX_D": 0x125b, + "Enable_Swim": 0x1d17, + "Coinsanity_B": 0x1d86, + "Auto_Scroll_Levels": 0x1f71, + "Starting_Lives": 0x2920, + "Get_Hurt_To_Big_Mario": 0x31c7, + "Get_Mushroom_A": 0x345c, + "Get_Fire_Flower_A": 0x346d, + "Get_Carrot_A": 0x347e, + "Invincibility_Star_A": 0x349e, + "Invincibility_Star_B": 0x34a3, + "Enable_Bubble": 0x34e5, + "Coinsanity_A": 0x591f, + "Coin_Shuffle": 0x304ce, + "Required_Golden_Coins": 0x306e9, + "Disable_Midway_Bell": 0x3ef1e, + "Get_Carrot_C": 0x6092f, + "Get_Mushroom_C": 0x60930, + "Get_Fire_Flower_C": 0x60933, + "Get_Mushroom_B": 0x60ddb, + "Get_Carrot_B": 0x60de7, + "Get_Fire_Flower_B": 0x60df3, + "Coins_Required": 0x80139, + "Difficulty_Mode": 0x8013b, + "Star_Count": 0x8013c, + "Midway_Bells": 0x8013e, + "Energy_Link": 0x8013f, + "Coin_Mode": 0x80140, + "Auto_Scroll_Levels_B": 0x80141, +} diff --git a/worlds/marioland2/sprite_randomizer.py b/worlds/marioland2/sprite_randomizer.py new file mode 100644 index 000000000000..8440da2b37f6 --- /dev/null +++ b/worlds/marioland2/sprite_randomizer.py @@ -0,0 +1,131 @@ +# Based on SML2R enemy and platform randomizer +# # https://github.com/slashinfty/sml2r-node/blob/862128c73d336d6cbfbf6290c09f3eff103688e8/src/index.ts#L284 + +def randomize_enemies(sprite_data, random): + for level, level_sprite_data in sprite_data.items(): + shuffle = () + if level in ("Mushroom Zone", "Macro Zone 4"): + shuffle = ("Koopa Troopa", "Goomba", "Paragoomba (Vertical)", "Paragoomba (Diagonal)") + elif level in ("Scenic Course", "Pumpkin Zone Secret Course 1"): + shuffle = ("Goomba", "Paragoomba (Vertical)", "Paragoomba (Diagonal)") + elif level == "Tree Zone 1": + shuffle = ("Money Bag/Bopping Toady", "Ragumo/Aqua Kuribo", "Pencil/Spikey", "Kyotonbo") + elif level == "Tree Zone 2": + shuffle = ("Noko Bombette/Bear", "No 48/Mogyo") + elif level == "Tree Zone 3": + shuffle = ("Battle Beetle", "Be", "Ant") + elif level == "Tree Zone 5": + shuffle = ("Paragoomba (Diagonal)", "Dondon", "Paragoomba (Vertical)") + elif level == "Pumpkin Zone 2": + shuffle = ("Boo/Bomubomu", "Kyororo", "Honebon/F Boy", "Karakara", "Star (Vertical)/Blurp (Horizontal)", + "Star (Horizontal)/Blurp (Vertical)") + elif level == "Pumpkin Zone 3": + shuffle = ("Boo/Bomubomu", "Unibo/Terekuribo") + elif level == "Mario Zone 1": + shuffle = ("Koopa Troopa", "Neiji/Buichi", "Tatenoko") + elif level == "Mario Zone 2": + shuffle = ("Paragoomba (Diagonal)", "Goomba", "Paragoomba (Vertical)", "Noko Bombette/Bear", + "Boo/Bomubomu") + elif level == "Turtle Zone 1": + shuffle = ("Horizontal Blurp", "Shark", "Cheep Cheep (Vertical)", "Paragoomba (Diagonal)", "Goomba", + "Spiny Cheep Cheep", "Paragoomba (Vertical)", + "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)") + elif level == "Hippo Zone": + shuffle = ("Horizontal Blurp", "Dondon", "Unibo/Terekuribo", "Toriuo") + elif level == "Space Zone 2": + shuffle = ("Tosenbo/Pikku", "Star (Vertical)/Blurp (Horizontal)", "Star (Horizontal)/Blurp (Vertical)") + elif level == "Macro Zone 1": + shuffle = ("Kyotonbo", "Goronto", "Dokanto", "Chikunto") + elif level == "Macro Zone 2": + shuffle = ("Cheep Cheep (Vertical)", "Battle Beetle", "Be", + "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "Ant") + elif level == "Macro Zone 3": + shuffle = ("Koopa Troopa", "Paragoomba (Diagonal)", "Goomba", "Be", "Paragoomba (Vertical)", + "Honebon/F Boy") + elif level == "Pumpkin Zone Secret Course 2": + shuffle = ("Koopa Troopa", "Goomba") + for sprite in level_sprite_data: + if level == "Pumpkin Zone 1": + if sprite["sprite"] == "Falling Spike": + shuffle = ("Boo/Bomubomu", "Falling Spike", "Kurokyura/Jack-in-the-Box", "Masked Ghoul/Bullet Bill") + elif sprite["sprite"] == "Falling Spike on Chain": + shuffle = ("Boo/Bomubomu", "Falling Spike on Chain", "Kurokyura/Jack-in-the-Box", + "Masked Ghoul/Bullet Bill") + else: + shuffle = ("Boo/Bomubomu", "Kurokyura/Jack-in-the-Box", "Masked Ghoul/Bullet Bill") + elif level == "Pumpkin Zone 4": + if sprite["sprite"] == "Falling Spike on Chain": + shuffle = ("Boo/Bomubomu", "Falling Spike on Chain", "Masked Ghoul/Bullet Bill", "Rerere/Poro", + "Tosenbo/Pikku") + else: + shuffle = ("Boo/Bomubomu", "Masked Ghoul/Bullet Bill", "Rerere/Poro", "Tosenbo/Pikku") + elif level == "Mario Zone 3": + if sprite["sprite"] == "Claw Grabber": + shuffle = ("Koopa Troopa", "Diagonal Ball on Chain", "Kiddokatto", "Claw Grabber", + "Masked Ghoul/Bullet Bill") + elif sprite["sprite"] in ("Koopa Troopa", "Diagonal Ball on Chain", "Kiddokatto"): + shuffle = ("Koopa Troopa", "Diagonal Ball on Chain", "Kiddokatto", "Masked Ghoul/Bullet Bill") + else: + shuffle = () + elif level == "Mario Zone 4": + if sprite["sprite"] == "Spinning Spike/Tamara": + shuffle = ("Goomba", "Spinning Spike/Tamara", "Boo/Bomubomu", "Masked Ghoul/Bullet Bill") + elif sprite["sprite"] == "Moving Saw (Floor)": + shuffle = ("Goomba", "Moving Saw (Floor)", "Boo/Bomubomu", "Masked Ghoul/Bullet Bill") + else: + shuffle = ("Goomba", "Boo/Bomubomu", "Masked Ghoul/Bullet Bill") + elif level == "Turtle Zone 3": + if sprite["sprite"] == "Pencil/Spikey": + shuffle = ("Koopa Troopa", "Paragoomba (Diagonal)", "Ragumo/Aqua Kuribo", "Pencil/Spikey", + "Paragoomba (Vertical)", "Honebon/F Boy") + else: + shuffle = ("Koopa Troopa", "Paragoomba (Diagonal)", "Ragumo/Aqua Kuribo", + "Paragoomba (Vertical)", "Honebon/F Boy") + elif level == "Space Zone 1": + if sprite["sprite"] == "Boo/Bomubomu": + shuffle = ("Boo/Bomubomu", "No 48/Mogyo") + else: + shuffle = ("Boo/Bomubomu", "No 48/Mogyo", "Rerere/Poro") + elif level == "Mario's Castle": + if sprite["sprite"] in ("Fire Pakkun Zo (Large)", "Fire Pakkun Zo (Left)"): + shuffle = ("Fire Pakkun Zo (Large)", "Fire Pakkun Zo (Left)") + else: + shuffle = ("Spike Ball (Large)", "Spike Ball (Small)") + elif level == "Tree Zone 4": + # Deviation from SML2R: No Buichis placed into non-Buichi locations, as they can place under the + # underground question mark blocks. Potentially could make a list of which ones are allowed to become + # Buichis? + if sprite["sprite"] in ("Runaway Heart Block/Bibi", "Piranha Plant (Downward)/Grubby", + "Spinning Platform (Horizontal)/Skeleton Bee", + "Spinning Spike (Horizontal)/Unera"): + shuffle = ("Runaway Heart Block/Bibi", "Piranha Plant (Downward)/Grubby", + "Spinning Platform (Horizontal)/Skeleton Bee", "Spinning Spike (Horizontal)/Unera") + elif sprite["sprite"] == "Neiji/Buichi": + shuffle = ("Runaway Heart Block/Bibi", "Neiji/Buichi", "Piranha Plant (Downward)/Grubby", + "Spinning Platform (Horizontal)/Skeleton Bee", "Spinning Spike (Horizontal)/Unera") + else: + shuffle = () + if sprite["sprite"] in ("Piranha Plant", "Fire Piranha Plant"): + if level not in ("Pumpkin Zone 2", "Pumpkin Zone 4", "Macro Zone 3"): + shuffle = ("Piranha Plant", "Fire Piranha Plant") + if sprite["sprite"] in shuffle: + sprite["sprite"] = random.choice(shuffle) + elif level == "Mario's Castle" and sprite["sprite"] == "Karamenbo" and not random.randint(0, 9): + sprite["y"] += 1 + + +def randomize_platforms(sprite_data, random): + shuffle = ("Moving Platform (Small, Vertical)", "Moving Platform (Large, Vertical)", + "Moving Platform (Small, Horizontal)", "Moving Platform (Large, Horizontal)", + "Moving Platform (Large, Diagonal)", "Falling Platform") + for sprite in sprite_data["Tree Zone 3"]: + if sprite["sprite"] in shuffle: + sprite["sprite"] = random.choice(shuffle) + shuffle = ("Cloud Platform (Horizontal)", "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)") + for sprite in sprite_data["Tree Zone 5"]: + if sprite["sprite"] in shuffle: + sprite["sprite"] = random.choice(shuffle) + shuffle = ("Falling Bone Platform", "Rising Bone Platform", "Skull Platform") + for sprite in sprite_data["Mario's Castle"]: + if sprite["sprite"] in shuffle: + sprite["sprite"] = random.choice(shuffle) diff --git a/worlds/marioland2/sprites.py b/worlds/marioland2/sprites.py new file mode 100644 index 000000000000..33a14731295e --- /dev/null +++ b/worlds/marioland2/sprites.py @@ -0,0 +1,1016 @@ +sprite_name_to_id = { + "Ant": 93, "Ragumo/Aqua Kuribo": 32, "Battle Beetle": 51, "Be": 52, "Noko Bombette/Bear": 68, + "Runaway Heart Block/Bibi": 53, "Star (Vertical)/Blurp (Horizontal)": 94, + "Star (Horizontal)/Blurp (Vertical)": 95, "Boo/Bomubomu": 77, + "Money Bag/Bopping Toady": 31, "Neiji/Buichi": 64, "Masked Ghoul/Bullet Bill": 83, + "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)": 61, "Cheep Cheep (Vertical)": 7, + "Chikunto": 39, "Dokanto": 37, "Dondon": 57, "Honebon/F Boy": 85, "Fire Pakkun Zo (Large)": 104, + "Fire Pakkun Zo (Left)": 105, "Fire Pakkun Zo (Right)": 106, "Fire Piranha Plant": 13, "Floating Face": 100, + "Genkottsu (1.5 Tiles)": 99, "Genkottsu (2 Tiles)": 98, "Goomba": 9, "Goronto": 35, + "Piranha Plant (Downward)/Grubby": 66, "Kurokyura/Jack-in-the-Box": 81, + "Karakara": 86, "Karamenbo": 102, "Kiddokatto": 72, "Koopa Troopa": 1, "Kyororo": 84, "Kyotonbo": 34, + "No 48/Mogyo": 88, "Paragoomba (Diagonal)": 8, "Paragoomba (Vertical)": 58, "Tosenbo/Pikku": 92, + "Piranha Plant": 12, "Rerere/Poro": 90, "Shark": 6, + "Spinning Platform (Horizontal)/Skeleton Bee": 62, "Pencil/Spikey": 33, + "Spiny Cheep Cheep": 11, "Spinning Spike/Tamara": 67, "Tatenoko": 75, "Unibo/Terekuribo": 87, + "Toriuo": 91, "Spinning Spike (Horizontal)/Unera": 65, "Claw Grabber": 73, + "Diagonal Ball on Chain": 71, "Falling Spike": 78, "Falling Spike on Chain": 79, "Spinning Spike (Vertical)": 80, + "Spike Ball (Large)": 110, "Spike Ball (Small)": 111, "Moving Saw (Ceiling)": 74, "Moving Saw (Floor)": 76, + "Moving Platform (Small, Vertical)": 40, "Moving Platform (Large, Vertical)": 41, + "Moving Platform (Small, Horizontal)": 42, "Moving Platform (Large, Horizontal)": 43, + "Moving Platform (Large, Diagonal)": 45, "Falling Platform": 46, "Rising Platform": 47, + "Rotating Platform (Small)": 48, "Owl Platform (Vertical)": 55, "Cloud Platform (Horizontal)": 56, + "Spinning Platform (Vertical)": 63, "Falling Bone Platform": 96, "Rising Bone Platform": 97, "Skull Platform": 103, + "Propeller Platform": 107, "Heart": 15, "Mushroom": 27, "Flower": 28, "Carrot": 29, "Star": 30, + "Mushroom Block": 17, "Flower Block": 18, "Carrot Block": 19, "Star Block": 20, "Heart Block": 21, + "Money Bag Block": 25, "Bubble": 24, "Midway Bell": 23, "Bonus Bell": 22, "Horizontal Blurp": 5, + "Big Diagonal Moving Platform": 44} + +sprite_id_to_name = {a: b for b, a in sprite_name_to_id.items()} + +level_sprites = { + "Mushroom Zone": [ + {"screen": 1, "sprite": "Goomba", "x": 27, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 9, "y": 24, "misc": 32}, + {"screen": 2, "sprite": "Mushroom Block", "x": 21, "y": 23, "misc": 32}, + {"screen": 4, "sprite": "Goomba", "x": 7, "y": 26, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 11, "y": 18, "misc": 32}, + {"screen": 6, "sprite": "Paragoomba (Diagonal)", "x": 19, "y": 22, "misc": 160}, + {"screen": 8, "sprite": "Piranha Plant", "x": 6, "y": 30, "misc": 160}, + {"screen": 8, "sprite": "Piranha Plant", "x": 22, "y": 30, "misc": 160}, + {"screen": 9, "sprite": "Heart Block", "x": 15, "y": 23, "misc": 32}, + {"screen": 9, "sprite": "Star Block", "x": 17, "y": 23, "misc": 32}, + {"screen": 10, "sprite": "Goomba", "x": 5, "y": 30, "misc": 32}, + {"screen": 10, "sprite": "Goomba", "x": 17, "y": 30, "misc": 32}, + {"screen": 10, "sprite": "Midway Bell", "x": 29, "y": 20, "misc": 32}, + {"screen": 11, "sprite": "Goomba", "x": 1, "y": 30, "misc": 32}, + {"screen": 11, "sprite": "Koopa Troopa", "x": 13, "y": 24, "misc": 32}, + {"screen": 11, "sprite": "Koopa Troopa", "x": 20, "y": 24, "misc": 32}, + {"screen": 11, "sprite": "Flower Block", "x": 25, "y": 23, "misc": 32}, + {"screen": 12, "sprite": "Heart", "x": 15, "y": 30, "misc": 32}, + {"screen": 13, "sprite": "Goomba", "x": 3, "y": 30, "misc": 32}, + {"screen": 13, "sprite": "Piranha Plant", "x": 16, "y": 30, "misc": 32}, + {"screen": 14, "sprite": "Goomba", "x": 11, "y": 22, "misc": 32}, + {"screen": 14, "sprite": "Koopa Troopa", "x": 20, "y": 22, "misc": 160}, + {"screen": 15, "sprite": "Bonus Bell", "x": 21, "y": 13, "misc": 32}], + "Tree Zone 1": [ + {"screen": 1, "sprite": "Star Block", "x": 17, "y": 21, "misc": 32}, + {"screen": 2, "sprite": "Ragumo/Aqua Kuribo", "x": 5, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Heart", "x": 19, "y": 30, "misc": 0}, + {"screen": 2, "sprite": "Ragumo/Aqua Kuribo", "x": 23, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Money Bag/Bopping Toady", "x": 1, "y": 30, "misc": 160}, + {"screen": 3, "sprite": "Money Bag/Bopping Toady", "x": 20, "y": 24, "misc": 160}, + {"screen": 4, "sprite": "Money Bag/Bopping Toady", "x": 9, "y": 24, "misc": 32}, + {"screen": 4, "sprite": "Heart", "x": 13, "y": 30, "misc": 0}, + {"screen": 4, "sprite": "Money Bag/Bopping Toady", "x": 31, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Pencil/Spikey", "x": 3, "y": 24, "misc": 160}, + {"screen": 5, "sprite": "Kyotonbo", "x": 21, "y": 22, "misc": 160}, + {"screen": 6, "sprite": "Money Bag/Bopping Toady", "x": 11, "y": 24, "misc": 160}, + {"screen": 6, "sprite": "Money Bag/Bopping Toady", "x": 23, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Mushroom Block", "x": 15, "y": 23, "misc": 32}, + {"screen": 7, "sprite": "Pencil/Spikey", "x": 28, "y": 24, "misc": 160}, + {"screen": 7, "sprite": "Heart Block", "x": 29, "y": 5, "misc": 32}, + {"screen": 8, "sprite": "Midway Bell", "x": 13, "y": 22, "misc": 32}, + {"screen": 8, "sprite": "Money Bag/Bopping Toady", "x": 29, "y": 24, "misc": 32}, + {"screen": 9, "sprite": "Ragumo/Aqua Kuribo", "x": 10, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Kyotonbo", "x": 15, "y": 10, "misc": 160}, + {"screen": 9, "sprite": "Mushroom Block", "x": 17, "y": 23, "misc": 32}, + {"screen": 10, "sprite": "Kyotonbo", "x": 3, "y": 10, "misc": 160}, + {"screen": 10, "sprite": "Pencil/Spikey", "x": 19, "y": 24, "misc": 160}, + {"screen": 10, "sprite": "Star Block", "x": 25, "y": 21, "misc": 32}, + {"screen": 11, "sprite": "Money Bag/Bopping Toady", "x": 7, "y": 24, "misc": 32}, + {"screen": 11, "sprite": "Money Bag/Bopping Toady", "x": 27, "y": 24, "misc": 32}, + {"screen": 11, "sprite": "Money Bag/Bopping Toady", "x": 31, "y": 24, "misc": 32}, + {"screen": 12, "sprite": "Money Bag/Bopping Toady", "x": 15, "y": 24, "misc": 32}, + {"screen": 13, "sprite": "Ragumo/Aqua Kuribo", "x": 3, "y": 30, "misc": 32}, + {"screen": 13, "sprite": "Money Bag/Bopping Toady", "x": 23, "y": 24, "misc": 32}, + {"screen": 14, "sprite": "Money Bag/Bopping Toady", "x": 15, "y": 30, "misc": 160}, + {"screen": 14, "sprite": "Kyotonbo", "x": 31, "y": 24, "misc": 160}, + {"screen": 15, "sprite": "Bonus Bell", "x": 19, "y": 13, "misc": 32}, + {"screen": 15, "sprite": "Heart Block", "x": 25, "y": 15, "misc": 32}], + "Tree Zone 2": [ + {"screen": 2, "sprite": "No 48/Mogyo", "x": 9, "y": 30, "misc": 0}, + {"screen": 2, "sprite": "Mushroom Block", "x": 23, "y": 19, "misc": 0}, + {"screen": 2, "sprite": "No 48/Mogyo", "x": 27, "y": 30, "misc": 0}, + {"screen": 3, "sprite": "Mushroom Block", "x": 7, "y": 23, "misc": 32}, + {"screen": 3, "sprite": "No 48/Mogyo", "x": 15, "y": 28, "misc": 160}, + {"screen": 3, "sprite": "Heart Block", "x": 27, "y": 17, "misc": 0}, + {"screen": 4, "sprite": "No 48/Mogyo", "x": 3, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "No 48/Mogyo", "x": 17, "y": 28, "misc": 160}, + {"screen": 5, "sprite": "Noko Bombette/Bear", "x": 1, "y": 30, "misc": 128}, + {"screen": 5, "sprite": "No 48/Mogyo", "x": 7, "y": 28, "misc": 32}, + {"screen": 6, "sprite": "Falling Platform", "x": 22, "y": 22, "misc": 0}, + {"screen": 7, "sprite": "Midway Bell", "x": 3, "y": 14, "misc": 0}, + {"screen": 7, "sprite": "No 48/Mogyo", "x": 15, "y": 30, "misc": 0}, + {"screen": 7, "sprite": "No 48/Mogyo", "x": 17, "y": 8, "misc": 32}, + {"screen": 7, "sprite": "Money Bag Block", "x": 19, "y": 19, "misc": 32}, + {"screen": 7, "sprite": "No 48/Mogyo", "x": 19, "y": 0, "misc": 32}, + {"screen": 8, "sprite": "Mushroom Block", "x": 5, "y": 13, "misc": 0}, + {"screen": 8, "sprite": "Noko Bombette/Bear", "x": 11, "y": 24, "misc": 0}, + {"screen": 8, "sprite": "Carrot Block", "x": 17, "y": 21, "misc": 64}, + {"screen": 9, "sprite": "Noko Bombette/Bear", "x": 3, "y": 30, "misc": 64}, + {"screen": 9, "sprite": "Noko Bombette/Bear", "x": 23, "y": 30, "misc": 64}, + {"screen": 10, "sprite": "Noko Bombette/Bear", "x": 11, "y": 30, "misc": 64}, + {"screen": 10, "sprite": "Noko Bombette/Bear", "x": 31, "y": 30, "misc": 64}, + {"screen": 11, "sprite": "Money Bag Block", "x": 5, "y": 19, "misc": 0}, + {"screen": 11, "sprite": "Mushroom Block", "x": 13, "y": 5, "misc": 0}, + {"screen": 11, "sprite": "Heart", "x": 19, "y": 24, "misc": 64}, + {"screen": 13, "sprite": "Noko Bombette/Bear", "x": 3, "y": 28, "misc": 192}, + {"screen": 13, "sprite": "Noko Bombette/Bear", "x": 5, "y": 16, "misc": 0}, + {"screen": 13, "sprite": "Noko Bombette/Bear", "x": 13, "y": 28, "misc": 192}, + {"screen": 13, "sprite": "Heart", "x": 27, "y": 8, "misc": 32}, + {"screen": 14, "sprite": "Bonus Bell", "x": 21, "y": 15, "misc": 32}], + "Tree Zone 4": [ + {"screen": 1, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 11, "y": 26, "misc": 160}, + {"screen": 1, "sprite": "Runaway Heart Block/Bibi", "x": 20, "y": 24, "misc": 0}, + {"screen": 1, "sprite": "Flower Block", "x": 25, "y": 21, "misc": 32}, + {"screen": 2, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 16, "y": 24, "misc": 128}, + {"screen": 3, "sprite": "Neiji/Buichi", "x": 18, "y": 18, "misc": 0}, + {"screen": 3, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 28, "y": 30, "misc": 0}, + {"screen": 4, "sprite": "Neiji/Buichi", "x": 4, "y": 18, "misc": 0}, + {"screen": 4, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 12, "y": 30, "misc": 0}, + {"screen": 4, "sprite": "Neiji/Buichi", "x": 22, "y": 18, "misc": 0}, + {"screen": 4, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 28, "y": 30, "misc": 0}, + {"screen": 5, "sprite": "Neiji/Buichi", "x": 8, "y": 18, "misc": 128}, + {"screen": 6, "sprite": "Runaway Heart Block/Bibi", "x": 12, "y": 24, "misc": 0}, + {"screen": 6, "sprite": "Piranha Plant (Downward)/Grubby", "x": 13, "y": 12, "misc": 160}, + {"screen": 6, "sprite": "Mushroom Block", "x": 19, "y": 17, "misc": 32}, + {"screen": 6, "sprite": "Piranha Plant (Downward)/Grubby", "x": 23, "y": 28, "misc": 128}, + {"screen": 6, "sprite": "Piranha Plant (Downward)/Grubby", "x": 25, "y": 18, "misc": 160}, + {"screen": 6, "sprite": "Piranha Plant (Downward)/Grubby", "x": 31, "y": 24, "misc": 160}, + {"screen": 7, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 2, "y": 24, "misc": 0}, + {"screen": 7, "sprite": "Runaway Heart Block/Bibi", "x": 28, "y": 24, "misc": 128}, + {"screen": 8, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 1, "y": 12, "misc": 32}, + {"screen": 8, "sprite": "Piranha Plant (Downward)/Grubby", "x": 5, "y": 28, "misc": 0}, + {"screen": 8, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 5, "y": 18, "misc": 32}, + {"screen": 8, "sprite": "Runaway Heart Block/Bibi", "x": 14, "y": 24, "misc": 0}, + {"screen": 8, "sprite": "Star Block", "x": 17, "y": 11, "misc": 32}, + {"screen": 8, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 19, "y": 24, "misc": 32}, + {"screen": 9, "sprite": "Star Block", "x": 17, "y": 19, "misc": 0}, + {"screen": 9, "sprite": "Piranha Plant (Downward)/Grubby", "x": 21, "y": 20, "misc": 0}, + {"screen": 9, "sprite": "Spinning Spike/Tamara", "x": 23, "y": 27, "misc": 0}, + {"screen": 10, "sprite": "Midway Bell", "x": 0, "y": 18, "misc": 0}, + {"screen": 10, "sprite": "Spinning Spike/Tamara", "x": 5, "y": 27, "misc": 0}, + {"screen": 10, "sprite": "Piranha Plant (Downward)/Grubby", "x": 11, "y": 20, "misc": 0}, + {"screen": 10, "sprite": "Spinning Spike/Tamara", "x": 17, "y": 27, "misc": 0}, + {"screen": 10, "sprite": "Mushroom Block", "x": 23, "y": 19, "misc": 0}, + {"screen": 12, "sprite": "Runaway Heart Block/Bibi", "x": 2, "y": 24, "misc": 32}, + {"screen": 12, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 28, "y": 24, "misc": 32}, + {"screen": 13, "sprite": "Bonus Bell", "x": 21, "y": 17, "misc": 32}], + "Tree Zone 3": [ + {"screen": 0, "sprite": "Moving Platform (Large, Vertical)", "x": 19, "y": 10, "misc": 32}, + {"screen": 0, "sprite": "Carrot Block", "x": 25, "y": 25, "misc": 0}, + {"screen": 0, "sprite": "Ant", "x": 28, "y": 18, "misc": 32}, + {"screen": 1, "sprite": "Ant", "x": 0, "y": 22, "misc": 64}, + {"screen": 1, "sprite": "Battle Beetle", "x": 10, "y": 24, "misc": 64}, + {"screen": 1, "sprite": "Moving Platform (Large, Diagonal)", "x": 11, "y": 22, "misc": 32}, + {"screen": 1, "sprite": "Fire Piranha Plant", "x": 18, "y": 20, "misc": 128}, + {"screen": 1, "sprite": "Cheep Cheep (Vertical)", "x": 18, "y": 21, "misc": 0}, + {"screen": 1, "sprite": "Mushroom Block", "x": 21, "y": 15, "misc": 64}, + {"screen": 1, "sprite": "Heart Block", "x": 21, "y": 7, "misc": 64}, + {"screen": 1, "sprite": "Be", "x": 30, "y": 26, "misc": 32}, + {"screen": 2, "sprite": "Piranha Plant", "x": 4, "y": 24, "misc": 192}, + {"screen": 2, "sprite": "Be", "x": 14, "y": 26, "misc": 32}, + {"screen": 2, "sprite": "Fire Piranha Plant", "x": 20, "y": 24, "misc": 192}, + {"screen": 2, "sprite": "Falling Platform", "x": 24, "y": 27, "misc": 0}, + {"screen": 2, "sprite": "Heart Block", "x": 25, "y": 19, "misc": 0}, + {"screen": 3, "sprite": "Falling Platform", "x": 0, "y": 25, "misc": 0}, + {"screen": 3, "sprite": "Falling Platform", "x": 0, "y": 31, "misc": 32}, + {"screen": 3, "sprite": "Cheep Cheep (Vertical)", "x": 4, "y": 15, "misc": 64}, + {"screen": 3, "sprite": "Falling Platform", "x": 8, "y": 31, "misc": 32}, + {"screen": 3, "sprite": "Ant", "x": 20, "y": 30, "misc": 0}, + {"screen": 3, "sprite": "Heart Block", "x": 27, "y": 17, "misc": 32}, + {"screen": 3, "sprite": "Heart Block", "x": 29, "y": 5, "misc": 32}, + {"screen": 4, "sprite": "Fire Piranha Plant", "x": 4, "y": 22, "misc": 192}, + {"screen": 4, "sprite": "Moving Platform (Small, Horizontal)", "x": 8, "y": 19, "misc": 0}, + {"screen": 4, "sprite": "Ant", "x": 12, "y": 20, "misc": 64}, + {"screen": 4, "sprite": "Moving Platform (Small, Vertical)", "x": 14, "y": 2, "misc": 64}, + {"screen": 4, "sprite": "Bonus Bell", "x": 21, "y": 17, "misc": 0}, + {"screen": 4, "sprite": "Money Bag Block", "x": 27, "y": 15, "misc": 32}, + {"screen": 4, "sprite": "Heart Block", "x": 27, "y": 17, "misc": 64}], + "Tree Zone 5": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 15, "y": 17, "misc": 64}, + {"screen": 1, "sprite": "Rotating Platform (Small)", "x": 15, "y": 19, "misc": 64}, + {"screen": 2, "sprite": "Paragoomba (Vertical)", "x": 2, "y": 26, "misc": 192}, + {"screen": 2, "sprite": "Paragoomba (Vertical)", "x": 16, "y": 26, "misc": 192}, + {"screen": 2, "sprite": "Heart Block", "x": 17, "y": 13, "misc": 64}, + {"screen": 2, "sprite": "Paragoomba (Vertical)", "x": 26, "y": 26, "misc": 192}, + {"screen": 3, "sprite": "Paragoomba (Vertical)", "x": 6, "y": 22, "misc": 192}, + {"screen": 3, "sprite": "Owl Platform (Vertical)", "x": 23, "y": 28, "misc": 64}, + {"screen": 4, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 11, "y": 19, "misc": 64}, + {"screen": 5, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 1, "y": 21, "misc": 64}, + {"screen": 5, "sprite": "Cloud Platform (Horizontal)", "x": 18, "y": 20, "misc": 64}, + {"screen": 5, "sprite": "Cloud Platform (Horizontal)", "x": 26, "y": 26, "misc": 64}, + {"screen": 6, "sprite": "Cloud Platform (Horizontal)", "x": 2, "y": 20, "misc": 64}, + {"screen": 6, "sprite": "Midway Bell", "x": 18, "y": 20, "misc": 64}, + {"screen": 6, "sprite": "Heart Block", "x": 23, "y": 21, "misc": 64}, + {"screen": 6, "sprite": "Dondon", "x": 30, "y": 14, "misc": 64}, + {"screen": 7, "sprite": "Carrot Block", "x": 9, "y": 19, "misc": 64}, + {"screen": 7, "sprite": "Rotating Platform (Small)", "x": 9, "y": 21, "misc": 64}, + {"screen": 7, "sprite": "Heart Block", "x": 23, "y": 13, "misc": 64}, + {"screen": 7, "sprite": "Rotating Platform (Small)", "x": 23, "y": 23, "misc": 64}, + {"screen": 8, "sprite": "Mushroom Block", "x": 21, "y": 13, "misc": 64}, + {"screen": 9, "sprite": "Star Block", "x": 5, "y": 7, "misc": 64}, + {"screen": 9, "sprite": "Paragoomba (Vertical)", "x": 7, "y": 14, "misc": 64}, + {"screen": 9, "sprite": "Paragoomba (Vertical)", "x": 27, "y": 20, "misc": 64}, + {"screen": 9, "sprite": "Paragoomba (Vertical)", "x": 31, "y": 16, "misc": 64}, + {"screen": 10, "sprite": "Cloud Platform (Horizontal)", "x": 20, "y": 22, "misc": 64}, + {"screen": 10, "sprite": "Paragoomba (Vertical)", "x": 31, "y": 18, "misc": 64}, + {"screen": 11, "sprite": "Cloud Platform (Horizontal)", "x": 8, "y": 22, "misc": 64}, + {"screen": 11, "sprite": "Paragoomba (Vertical)", "x": 16, "y": 25, "misc": 64}], + "Pumpkin Zone 1": [ + {"screen": 1, "sprite": "Falling Spike on Chain", "x": 9, "y": 14, "misc": 160}, + {"screen": 1, "sprite": "Mushroom Block", "x": 15, "y": 23, "misc": 0}, + {"screen": 1, "sprite": "Masked Ghoul/Bullet Bill", "x": 19, "y": 30, "misc": 0}, + {"screen": 1, "sprite": "Falling Spike on Chain", "x": 27, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Falling Spike on Chain", "x": 17, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Falling Spike on Chain", "x": 23, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Falling Spike on Chain", "x": 29, "y": 22, "misc": 32}, + {"screen": 3, "sprite": "Masked Ghoul/Bullet Bill", "x": 1, "y": 30, "misc": 160}, + {"screen": 3, "sprite": "Masked Ghoul/Bullet Bill", "x": 21, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Masked Ghoul/Bullet Bill", "x": 5, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Carrot Block", "x": 17, "y": 21, "misc": 32}, + {"screen": 4, "sprite": "Masked Ghoul/Bullet Bill", "x": 21, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Falling Spike", "x": 27, "y": 20, "misc": 32}, + {"screen": 6, "sprite": "Boo/Bomubomu", "x": 1, "y": 28, "misc": 0}, + {"screen": 6, "sprite": "Masked Ghoul/Bullet Bill", "x": 2, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Heart Block", "x": 5, "y": 7, "misc": 0}, + {"screen": 6, "sprite": "Boo/Bomubomu", "x": 9, "y": 28, "misc": 128}, + {"screen": 6, "sprite": "Fire Piranha Plant", "x": 16, "y": 2, "misc": 192}, + {"screen": 6, "sprite": "Midway Bell", "x": 24, "y": 22, "misc": 32}, + {"screen": 7, "sprite": "Falling Spike", "x": 1, "y": 20, "misc": 32}, + {"screen": 7, "sprite": "Masked Ghoul/Bullet Bill", "x": 9, "y": 30, "misc": 160}, + {"screen": 7, "sprite": "Falling Spike", "x": 27, "y": 20, "misc": 32}, + {"screen": 7, "sprite": "Masked Ghoul/Bullet Bill", "x": 31, "y": 30, "misc": 160}, + {"screen": 8, "sprite": "Piranha Plant", "x": 16, "y": 28, "misc": 32}, + {"screen": 8, "sprite": "Masked Ghoul/Bullet Bill", "x": 17, "y": 24, "misc": 160}, + {"screen": 8, "sprite": "Fire Piranha Plant", "x": 24, "y": 30, "misc": 160}, + {"screen": 9, "sprite": "Masked Ghoul/Bullet Bill", "x": 7, "y": 22, "misc": 160}, + {"screen": 9, "sprite": "Falling Spike on Chain", "x": 11, "y": 10, "misc": 160}, + {"screen": 9, "sprite": "Piranha Plant", "x": 20, "y": 14, "misc": 32}, + {"screen": 9, "sprite": "Falling Spike on Chain", "x": 23, "y": 30, "misc": 128}, + {"screen": 10, "sprite": "Cheep Cheep (Vertical)", "x": 30, "y": 11, "misc": 160}, + {"screen": 11, "sprite": "Cheep Cheep (Vertical)", "x": 6, "y": 19, "misc": 32}, + {"screen": 11, "sprite": "Kurokyura/Jack-in-the-Box", "x": 11, "y": 30, "misc": 0}, + {"screen": 11, "sprite": "Bonus Bell", "x": 21, "y": 3, "misc": 32}, + {"screen": 11, "sprite": "Heart Block", "x": 27, "y": 11, "misc": 0}], + "Pumpkin Zone 2": [ + {"screen": 1, "sprite": "Karakara", "x": 7, "y": 30, "misc": 160}, + {"screen": 1, "sprite": "Karakara", "x": 15, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Karakara", "x": 23, "y": 30, "misc": 160}, + {"screen": 2, "sprite": "Piranha Plant", "x": 20, "y": 30, "misc": 160}, + {"screen": 3, "sprite": "Honebon/F Boy", "x": 4, "y": 11, "misc": 160}, + {"screen": 3, "sprite": "Cheep Cheep (Vertical)", "x": 4, "y": 23, "misc": 32}, + {"screen": 3, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 13, "y": 28, "misc": 192}, + {"screen": 3, "sprite": "Mushroom Block", "x": 17, "y": 21, "misc": 64}, + {"screen": 4, "sprite": "Kyororo", "x": 29, "y": 30, "misc": 160}, + {"screen": 5, "sprite": "Honebon/F Boy", "x": 6, "y": 24, "misc": 32}, + {"screen": 5, "sprite": "Kyororo", "x": 13, "y": 30, "misc": 160}, + {"screen": 5, "sprite": "Kyororo", "x": 29, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Midway Bell", "x": 1, "y": 16, "misc": 32}, + {"screen": 6, "sprite": "Star (Horizontal)/Blurp (Vertical)", "x": 21, "y": 30, "misc": 192}, + {"screen": 6, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 28, "y": 25, "misc": 64}, + {"screen": 7, "sprite": "Mushroom", "x": 3, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Boo/Bomubomu", "x": 9, "y": 13, "misc": 160}, + {"screen": 7, "sprite": "Boo/Bomubomu", "x": 13, "y": 21, "misc": 160}, + {"screen": 7, "sprite": "Heart", "x": 29, "y": 14, "misc": 32}, + {"screen": 8, "sprite": "Carrot", "x": 7, "y": 22, "misc": 32}, + {"screen": 8, "sprite": "Flower", "x": 13, "y": 14, "misc": 32}, + {"screen": 8, "sprite": "Heart", "x": 19, "y": 20, "misc": 32}, + {"screen": 9, "sprite": "Star Block", "x": 1, "y": 13, "misc": 32}, + {"screen": 9, "sprite": "Kyororo", "x": 19, "y": 30, "misc": 64}, + {"screen": 9, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 20, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Kyororo", "x": 21, "y": 16, "misc": 32}, + {"screen": 10, "sprite": "Kyororo", "x": 5, "y": 14, "misc": 32}, + {"screen": 10, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 7, "y": 28, "misc": 32}, + {"screen": 10, "sprite": "Kyororo", "x": 22, "y": 14, "misc": 32}, + {"screen": 11, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 0, "y": 26, "misc": 192}, + {"screen": 11, "sprite": "Falling Spike", "x": 5, "y": 24, "misc": 64}, + {"screen": 11, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 7, "y": 30, "misc": 32}, + {"screen": 11, "sprite": "Kyororo", "x": 10, "y": 16, "misc": 32}, + {"screen": 11, "sprite": "Falling Spike", "x": 15, "y": 24, "misc": 64}, + {"screen": 11, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 19, "y": 28, "misc": 192}, + {"screen": 12, "sprite": "Karakara", "x": 9, "y": 30, "misc": 32}, + {"screen": 12, "sprite": "Karakara", "x": 17, "y": 30, "misc": 32}, + {"screen": 12, "sprite": "Karakara", "x": 25, "y": 30, "misc": 32}, + {"screen": 13, "sprite": "Karakara", "x": 19, "y": 30, "misc": 32}, + {"screen": 13, "sprite": "Bonus Bell", "x": 21, "y": 11, "misc": 32}], + "Pumpkin Zone 3": [ + {"screen": 1, "sprite": "Unibo/Terekuribo", "x": 21, "y": 26, "misc": 160}, + {"screen": 2, "sprite": "Unibo/Terekuribo", "x": 21, "y": 20, "misc": 160}, + {"screen": 3, "sprite": "Carrot Block", "x": 9, "y": 7, "misc": 32}, + {"screen": 3, "sprite": "Boo/Bomubomu", "x": 19, "y": 23, "misc": 32}, + {"screen": 4, "sprite": "Boo/Bomubomu", "x": 1, "y": 21, "misc": 32}, + {"screen": 4, "sprite": "Boo/Bomubomu", "x": 19, "y": 14, "misc": 160}, + {"screen": 6, "sprite": "Moving Platform (Small, Horizontal)", "x": 0, "y": 8, "misc": 64}, + {"screen": 6, "sprite": "Moving Platform (Small, Horizontal)", "x": 0, "y": 14, "misc": 64}, + {"screen": 6, "sprite": "Flower Block", "x": 17, "y": 19, "misc": 64}, + {"screen": 7, "sprite": "Unibo/Terekuribo", "x": 1, "y": 26, "misc": 32}, + {"screen": 7, "sprite": "Boo/Bomubomu", "x": 17, "y": 18, "misc": 64}, + {"screen": 8, "sprite": "Fire Piranha Plant", "x": 16, "y": 28, "misc": 32}, + {"screen": 8, "sprite": "Heart Block", "x": 23, "y": 5, "misc": 64}, + {"screen": 8, "sprite": "Flower Block", "x": 25, "y": 17, "misc": 64}, + {"screen": 9, "sprite": "Midway Bell", "x": 5, "y": 22, "misc": 32}, + {"screen": 9, "sprite": "Boo/Bomubomu", "x": 19, "y": 22, "misc": 160}, + {"screen": 10, "sprite": "Boo/Bomubomu", "x": 2, "y": 27, "misc": 32}, + {"screen": 10, "sprite": "Boo/Bomubomu", "x": 25, "y": 14, "misc": 160}, + {"screen": 11, "sprite": "Carrot Block", "x": 7, "y": 13, "misc": 32}, + {"screen": 11, "sprite": "Boo/Bomubomu", "x": 23, "y": 18, "misc": 160}, + {"screen": 13, "sprite": "Boo/Bomubomu", "x": 3, "y": 28, "misc": 32}, + {"screen": 13, "sprite": "Boo/Bomubomu", "x": 12, "y": 5, "misc": 64}, + {"screen": 14, "sprite": "Unibo/Terekuribo", "x": 3, "y": 28, "misc": 160}, + {"screen": 14, "sprite": "Boo/Bomubomu", "x": 5, "y": 18, "misc": 192}, + {"screen": 14, "sprite": "Unibo/Terekuribo", "x": 14, "y": 24, "misc": 32}, + {"screen": 14, "sprite": "Bonus Bell", "x": 21, "y": 13, "misc": 64}], + "Pumpkin Zone 4": [ + {"screen": 1, "sprite": "Tosenbo/Pikku", "x": 19, "y": 30, "misc": 160}, + {"screen": 1, "sprite": "Piranha Plant", "x": 24, "y": 0, "misc": 64}, + {"screen": 2, "sprite": "Boo/Bomubomu", "x": 9, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Boo/Bomubomu", "x": 24, "y": 21, "misc": 160}, + {"screen": 3, "sprite": "Boo/Bomubomu", "x": 23, "y": 26, "misc": 160}, + {"screen": 3, "sprite": "Falling Spike on Chain", "x": 29, "y": 22, "misc": 32}, + {"screen": 4, "sprite": "Falling Spike on Chain", "x": 3, "y": 22, "misc": 32}, + {"screen": 4, "sprite": "Falling Spike on Chain", "x": 9, "y": 22, "misc": 32}, + {"screen": 4, "sprite": "Tosenbo/Pikku", "x": 28, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Mushroom Block", "x": 7, "y": 11, "misc": 64}, + {"screen": 5, "sprite": "Boo/Bomubomu", "x": 17, "y": 26, "misc": 192}, + {"screen": 5, "sprite": "Heart Block", "x": 29, "y": 15, "misc": 64}, + {"screen": 6, "sprite": "Carrot Block", "x": 17, "y": 13, "misc": 32}, + {"screen": 7, "sprite": "Midway Bell", "x": 15, "y": 24, "misc": 32}, + {"screen": 8, "sprite": "Falling Spike on Chain", "x": 3, "y": 22, "misc": 32}, + {"screen": 8, "sprite": "Rerere/Poro", "x": 10, "y": 30, "misc": 160}, + {"screen": 8, "sprite": "Falling Spike on Chain", "x": 17, "y": 22, "misc": 160}, + {"screen": 8, "sprite": "Falling Spike on Chain", "x": 27, "y": 22, "misc": 160}, + {"screen": 9, "sprite": "Rerere/Poro", "x": 3, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Falling Spike on Chain", "x": 9, "y": 22, "misc": 160}, + {"screen": 10, "sprite": "Masked Ghoul/Bullet Bill", "x": 19, "y": 30, "misc": 32}, + {"screen": 10, "sprite": "Masked Ghoul/Bullet Bill", "x": 25, "y": 26, "misc": 160}, + {"screen": 10, "sprite": "Masked Ghoul/Bullet Bill", "x": 31, "y": 22, "misc": 32}, + {"screen": 11, "sprite": "Masked Ghoul/Bullet Bill", "x": 5, "y": 18, "misc": 32}, + {"screen": 12, "sprite": "Masked Ghoul/Bullet Bill", "x": 14, "y": 16, "misc": 192}, + {"screen": 12, "sprite": "Masked Ghoul/Bullet Bill", "x": 25, "y": 16, "misc": 192}, + {"screen": 13, "sprite": "Masked Ghoul/Bullet Bill", "x": 6, "y": 16, "misc": 192}, + {"screen": 13, "sprite": "Flower Block", "x": 13, "y": 23, "misc": 32}, + {"screen": 13, "sprite": "Masked Ghoul/Bullet Bill", "x": 18, "y": 16, "misc": 192}, + {"screen": 13, "sprite": "Money Bag Block", "x": 25, "y": 23, "misc": 32}, + {"screen": 14, "sprite": "Boo/Bomubomu", "x": 13, "y": 30, "misc": 160}], + "Mario Zone 1": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 5, "y": 23, "misc": 64}, + {"screen": 1, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 7, "y": 9, "misc": 64}, + {"screen": 1, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 13, "y": 13, "misc": 32}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 13, "y": 30, "misc": 192}, + {"screen": 1, "sprite": "Spinning Spike (Vertical)", "x": 19, "y": 22, "misc": 0}, + {"screen": 1, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 19, "y": 15, "misc": 32}, + {"screen": 2, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 13, "y": 27, "misc": 64}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 25, "y": 18, "misc": 64}, + {"screen": 3, "sprite": "Spinning Platform (Vertical)", "x": 1, "y": 18, "misc": 64}, + {"screen": 3, "sprite": "Spinning Platform (Vertical)", "x": 7, "y": 18, "misc": 64}, + {"screen": 3, "sprite": "Koopa Troopa", "x": 19, "y": 26, "misc": 192}, + {"screen": 3, "sprite": "Koopa Troopa", "x": 31, "y": 14, "misc": 192}, + {"screen": 4, "sprite": "Spinning Platform (Vertical)", "x": 23, "y": 20, "misc": 64}, + {"screen": 4, "sprite": "Tatenoko", "x": 26, "y": 15, "misc": 192}, + {"screen": 4, "sprite": "Spinning Platform (Vertical)", "x": 29, "y": 20, "misc": 64}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 11, "y": 16, "misc": 192}, + {"screen": 5, "sprite": "Spinning Platform (Vertical)", "x": 19, "y": 22, "misc": 64}, + {"screen": 5, "sprite": "Spinning Platform (Vertical)", "x": 23, "y": 22, "misc": 64}, + {"screen": 6, "sprite": "Carrot Block", "x": 5, "y": 11, "misc": 64}, + {"screen": 6, "sprite": "Midway Bell", "x": 16, "y": 12, "misc": 64}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 19, "y": 20, "misc": 64}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 21, "y": 24, "misc": 192}, + {"screen": 8, "sprite": "Spinning Spike (Horizontal)/Unera", "x": 12, "y": 30, "misc": 64}, + {"screen": 8, "sprite": "Heart Block", "x": 13, "y": 17, "misc": 64}, + {"screen": 9, "sprite": "Mushroom Block", "x": 3, "y": 19, "misc": 64}, + {"screen": 9, "sprite": "Neiji/Buichi", "x": 3, "y": 0, "misc": 96}, + {"screen": 9, "sprite": "Neiji/Buichi", "x": 11, "y": 0, "misc": 224}, + {"screen": 9, "sprite": "Neiji/Buichi", "x": 19, "y": 0, "misc": 224}, + {"screen": 9, "sprite": "Heart Block", "x": 27, "y": 7, "misc": 32}, + {"screen": 9, "sprite": "Spinning Platform (Vertical)", "x": 29, "y": 30, "misc": 32}, + {"screen": 10, "sprite": "Tatenoko", "x": 4, "y": 13, "misc": 32}, + {"screen": 10, "sprite": "Spinning Platform (Horizontal)/Skeleton Bee", "x": 7, "y": 21, "misc": 64}, + {"screen": 10, "sprite": "Carrot Block", "x": 9, "y": 7, "misc": 32}, + {"screen": 10, "sprite": "Spinning Platform (Vertical)", "x": 9, "y": 18, "misc": 32}, + {"screen": 10, "sprite": "Bonus Bell", "x": 19, "y": 17, "misc": 64}], + "Mario Zone 2": [ + {"screen": 1, "sprite": "Boo/Bomubomu", "x": 9, "y": 28, "misc": 32}, + {"screen": 1, "sprite": "Boo/Bomubomu", "x": 31, "y": 22, "misc": 160}, + {"screen": 3, "sprite": "Paragoomba (Vertical)", "x": 6, "y": 18, "misc": 160}, + {"screen": 3, "sprite": "Paragoomba (Vertical)", "x": 15, "y": 21, "misc": 160}, + {"screen": 4, "sprite": "Paragoomba (Vertical)", "x": 3, "y": 20, "misc": 160}, + {"screen": 4, "sprite": "Paragoomba (Vertical)", "x": 12, "y": 18, "misc": 160}, + {"screen": 4, "sprite": "Paragoomba (Vertical)", "x": 28, "y": 21, "misc": 32}, + {"screen": 5, "sprite": "Mushroom Block", "x": 3, "y": 21, "misc": 32}, + {"screen": 5, "sprite": "Heart", "x": 8, "y": 28, "misc": 32}, + {"screen": 5, "sprite": "Goomba", "x": 9, "y": 20, "misc": 192}, + {"screen": 5, "sprite": "Carrot Block", "x": 17, "y": 11, "misc": 64}, + {"screen": 5, "sprite": "Goomba", "x": 25, "y": 26, "misc": 192}, + {"screen": 5, "sprite": "Money Bag Block", "x": 27, "y": 19, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 3, "y": 26, "misc": 64}, + {"screen": 6, "sprite": "Star Block", "x": 7, "y": 11, "misc": 64}, + {"screen": 7, "sprite": "Noko Bombette/Bear", "x": 6, "y": 28, "misc": 32}, + {"screen": 8, "sprite": "Midway Bell", "x": 5, "y": 18, "misc": 32}, + {"screen": 8, "sprite": "Boo/Bomubomu", "x": 21, "y": 28, "misc": 160}, + {"screen": 8, "sprite": "Boo/Bomubomu", "x": 31, "y": 16, "misc": 32}, + {"screen": 9, "sprite": "Mushroom Block", "x": 11, "y": 15, "misc": 32}, + {"screen": 9, "sprite": "Boo/Bomubomu", "x": 19, "y": 20, "misc": 160}, + {"screen": 10, "sprite": "Boo/Bomubomu", "x": 5, "y": 24, "misc": 32}, + {"screen": 11, "sprite": "Mushroom", "x": 1, "y": 14, "misc": 32}, + {"screen": 11, "sprite": "Goomba", "x": 9, "y": 14, "misc": 32}, + {"screen": 11, "sprite": "Flower", "x": 17, "y": 14, "misc": 32}, + {"screen": 11, "sprite": "Carrot", "x": 25, "y": 14, "misc": 32}, + {"screen": 12, "sprite": "Boo/Bomubomu", "x": 12, "y": 16, "misc": 32}, + {"screen": 12, "sprite": "Boo/Bomubomu", "x": 24, "y": 20, "misc": 160}, + {"screen": 13, "sprite": "Noko Bombette/Bear", "x": 16, "y": 28, "misc": 32}, + {"screen": 14, "sprite": "Noko Bombette/Bear", "x": 12, "y": 28, "misc": 32}, + {"screen": 14, "sprite": "Bonus Bell", "x": 21, "y": 17, "misc": 32}], + "Mario Zone 3": [ + {"screen": 1, "sprite": "Kurokyura/Jack-in-the-Box", "x": 15, "y": 23, "misc": 160}, + {"screen": 1, "sprite": "Kiddokatto", "x": 21, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Masked Ghoul/Bullet Bill", "x": 4, "y": 26, "misc": 160}, + {"screen": 2, "sprite": "Diagonal Ball on Chain", "x": 9, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Diagonal Ball on Chain", "x": 1, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Mushroom Block", "x": 13, "y": 17, "misc": 32}, + {"screen": 3, "sprite": "Diagonal Ball on Chain", "x": 25, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Masked Ghoul/Bullet Bill", "x": 14, "y": 24, "misc": 160}, + {"screen": 4, "sprite": "Diagonal Ball on Chain", "x": 27, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Masked Ghoul/Bullet Bill", "x": 14, "y": 24, "misc": 160}, + {"screen": 6, "sprite": "Carrot Block", "x": 9, "y": 21, "misc": 32}, + {"screen": 6, "sprite": "Kiddokatto", "x": 25, "y": 30, "misc": 160}, + {"screen": 7, "sprite": "Masked Ghoul/Bullet Bill", "x": 26, "y": 28, "misc": 32}, + {"screen": 7, "sprite": "Midway Bell", "x": 27, "y": 22, "misc": 32}, + {"screen": 8, "sprite": "Kurokyura/Jack-in-the-Box", "x": 11, "y": 21, "misc": 32}, + {"screen": 8, "sprite": "Heart Block", "x": 13, "y": 3, "misc": 32}, + {"screen": 8, "sprite": "Kiddokatto", "x": 31, "y": 30, "misc": 160}, + {"screen": 9, "sprite": "Claw Grabber", "x": 23, "y": 28, "misc": 32}, + {"screen": 10, "sprite": "Claw Grabber", "x": 13, "y": 28, "misc": 32}, + {"screen": 11, "sprite": "Masked Ghoul/Bullet Bill", "x": 4, "y": 28, "misc": 64}, + {"screen": 11, "sprite": "Koopa Troopa", "x": 5, "y": 20, "misc": 160}, + {"screen": 11, "sprite": "Masked Ghoul/Bullet Bill", "x": 8, "y": 12, "misc": 192}, + {"screen": 11, "sprite": "Kiddokatto", "x": 26, "y": 20, "misc": 32}, + {"screen": 11, "sprite": "Heart Block", "x": 27, "y": 23, "misc": 64}, + {"screen": 11, "sprite": "Masked Ghoul/Bullet Bill", "x": 28, "y": 18, "misc": 192}, + {"screen": 12, "sprite": "Claw Grabber", "x": 11, "y": 28, "misc": 32}, + {"screen": 12, "sprite": "Kiddokatto", "x": 21, "y": 20, "misc": 32}, + {"screen": 13, "sprite": "Mushroom Block", "x": 13, "y": 21, "misc": 32}, + {"screen": 13, "sprite": "Masked Ghoul/Bullet Bill", "x": 18, "y": 28, "misc": 160}, + {"screen": 13, "sprite": "Kurokyura/Jack-in-the-Box", "x": 25, "y": 21, "misc": 32}, + {"screen": 14, "sprite": "Diagonal Ball on Chain", "x": 9, "y": 30, "misc": 32}, + {"screen": 14, "sprite": "Masked Ghoul/Bullet Bill", "x": 26, "y": 24, "misc": 160}, + {"screen": 15, "sprite": "Claw Grabber", "x": 3, "y": 18, "misc": 32}, + {"screen": 15, "sprite": "Bonus Bell", "x": 21, "y": 17, "misc": 32}], + "Mario Zone 4": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 9, "y": 17, "misc": 32}, + {"screen": 1, "sprite": "Spinning Spike/Tamara", "x": 9, "y": 25, "misc": 160}, + {"screen": 1, "sprite": "Spinning Spike/Tamara", "x": 29, "y": 25, "misc": 32}, + {"screen": 2, "sprite": "Masked Ghoul/Bullet Bill", "x": 12, "y": 26, "misc": 160}, + {"screen": 2, "sprite": "Spinning Spike/Tamara", "x": 29, "y": 21, "misc": 160}, + {"screen": 3, "sprite": "Spinning Spike/Tamara", "x": 15, "y": 21, "misc": 32}, + {"screen": 4, "sprite": "Masked Ghoul/Bullet Bill", "x": 14, "y": 26, "misc": 160}, + {"screen": 4, "sprite": "Masked Ghoul/Bullet Bill", "x": 24, "y": 21, "misc": 32}, + {"screen": 5, "sprite": "Masked Ghoul/Bullet Bill", "x": 2, "y": 26, "misc": 32}, + {"screen": 5, "sprite": "Goomba", "x": 22, "y": 20, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 2, "y": 14, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 14, "y": 8, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 26, "y": 2, "misc": 32}, + {"screen": 7, "sprite": "Spinning Spike/Tamara", "x": 9, "y": 25, "misc": 160}, + {"screen": 7, "sprite": "Spinning Spike/Tamara", "x": 15, "y": 21, "misc": 32}, + {"screen": 7, "sprite": "Spinning Spike/Tamara", "x": 21, "y": 25, "misc": 160}, + {"screen": 7, "sprite": "Mushroom Block", "x": 25, "y": 23, "misc": 0}, + {"screen": 8, "sprite": "Boo/Bomubomu", "x": 17, "y": 26, "misc": 128}, + {"screen": 8, "sprite": "Masked Ghoul/Bullet Bill", "x": 30, "y": 24, "misc": 0}, + {"screen": 9, "sprite": "Boo/Bomubomu", "x": 11, "y": 30, "misc": 128}, + {"screen": 9, "sprite": "Midway Bell", "x": 16, "y": 24, "misc": 0}, + {"screen": 9, "sprite": "Goomba", "x": 26, "y": 30, "misc": 0}, + {"screen": 10, "sprite": "Moving Saw (Ceiling)", "x": 17, "y": 26, "misc": 0}, + {"screen": 10, "sprite": "Moving Saw (Floor)", "x": 19, "y": 22, "misc": 128}, + {"screen": 11, "sprite": "Mushroom Block", "x": 7, "y": 23, "misc": 0}, + {"screen": 11, "sprite": "Moving Saw (Ceiling)", "x": 25, "y": 26, "misc": 128}, + {"screen": 11, "sprite": "Moving Saw (Floor)", "x": 27, "y": 22, "misc": 0}, + {"screen": 11, "sprite": "Money Bag/Bopping Toady", "x": 29, "y": 30, "misc": 0}, + {"screen": 13, "sprite": "Moving Saw (Floor)", "x": 9, "y": 28, "misc": 128}, + {"screen": 13, "sprite": "Moving Saw (Floor)", "x": 19, "y": 28, "misc": 0}, + {"screen": 14, "sprite": "Spinning Spike/Tamara", "x": 13, "y": 25, "misc": 0}, + {"screen": 14, "sprite": "Goomba", "x": 21, "y": 30, "misc": 128}], + "Turtle Zone 1": [ + {"screen": 1, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 2, "y": 16, "misc": 192}, + {"screen": 1, "sprite": "Horizontal Blurp", "x": 12, "y": 21, "misc": 64}, + {"screen": 1, "sprite": "Mushroom Block", "x": 13, "y": 3, "misc": 64}, + {"screen": 2, "sprite": "Horizontal Blurp", "x": 1, "y": 18, "misc": 64}, + {"screen": 2, "sprite": "Spiny Cheep Cheep", "x": 11, "y": 26, "misc": 64}, + {"screen": 2, "sprite": "Cheep Cheep (Vertical)", "x": 26, "y": 28, "misc": 192}, + {"screen": 3, "sprite": "Goomba", "x": 3, "y": 8, "misc": 64}, + {"screen": 3, "sprite": "Goomba", "x": 17, "y": 8, "misc": 64}, + {"screen": 3, "sprite": "Star Block", "x": 17, "y": 1, "misc": 64}, + {"screen": 3, "sprite": "Cheep Cheep (Vertical)", "x": 18, "y": 28, "misc": 192}, + {"screen": 3, "sprite": "Heart Block", "x": 19, "y": 1, "misc": 64}, + {"screen": 3, "sprite": "Shark", "x": 27, "y": 26, "misc": 192}, + {"screen": 4, "sprite": "Paragoomba (Diagonal)", "x": 1, "y": 4, "misc": 64}, + {"screen": 4, "sprite": "Goomba", "x": 10, "y": 8, "misc": 64}, + {"screen": 5, "sprite": "Horizontal Blurp", "x": 1, "y": 16, "misc": 64}, + {"screen": 5, "sprite": "Horizontal Blurp", "x": 9, "y": 22, "misc": 192}, + {"screen": 5, "sprite": "Horizontal Blurp", "x": 16, "y": 26, "misc": 64}, + {"screen": 6, "sprite": "Shark", "x": 12, "y": 21, "misc": 64}, + {"screen": 6, "sprite": "Midway Bell", "x": 21, "y": 18, "misc": 64}, + {"screen": 6, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 25, "y": 16, "misc": 64}, + {"screen": 7, "sprite": "Spiny Cheep Cheep", "x": 21, "y": 17, "misc": 64}, + {"screen": 7, "sprite": "Horizontal Blurp", "x": 25, "y": 26, "misc": 64}, + {"screen": 8, "sprite": "Cheep Cheep (Vertical)", "x": 7, "y": 20, "misc": 64}, + {"screen": 8, "sprite": "Shark", "x": 15, "y": 14, "misc": 192}, + {"screen": 8, "sprite": "Spiny Cheep Cheep", "x": 25, "y": 24, "misc": 192}, + {"screen": 8, "sprite": "Mushroom Block", "x": 31, "y": 3, "misc": 64}, + {"screen": 9, "sprite": "Cheep Cheep (Vertical)", "x": 15, "y": 24, "misc": 64}, + {"screen": 9, "sprite": "Cheep Cheep (Vertical)", "x": 23, "y": 20, "misc": 192}, + {"screen": 9, "sprite": "Cheep Cheep (Vertical)", "x": 29, "y": 26, "misc": 192}, + {"screen": 10, "sprite": "Shark", "x": 10, "y": 18, "misc": 192}, + {"screen": 10, "sprite": "Money Bag Block", "x": 11, "y": 31, "misc": 32}, + {"screen": 11, "sprite": "Shark", "x": 5, "y": 22, "misc": 64}, + {"screen": 11, "sprite": "Horizontal Blurp", "x": 16, "y": 28, "misc": 192}, + {"screen": 11, "sprite": "Bonus Bell", "x": 21, "y": 9, "misc": 64}, + {"screen": 11, "sprite": "Heart Block", "x": 27, "y": 23, "misc": 64}], + "Turtle Zone 2": [ + {"screen": 0, "sprite": "Shark", "x": 17, "y": 12, "misc": 192}, + {"screen": 0, "sprite": "Carrot Block", "x": 21, "y": 19, "misc": 64}, + {"screen": 0, "sprite": "Masked Ghoul/Bullet Bill", "x": 22, "y": 28, "misc": 192}, + {"screen": 1, "sprite": "Honebon/F Boy", "x": 13, "y": 12, "misc": 192}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 19, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Karakara", "x": 28, "y": 27, "misc": 64}, + {"screen": 2, "sprite": "Shark", "x": 7, "y": 10, "misc": 64}, + {"screen": 2, "sprite": "Karakara", "x": 17, "y": 27, "misc": 64}, + {"screen": 2, "sprite": "Karakara", "x": 23, "y": 22, "misc": 64}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 25, "y": 14, "misc": 32}, + {"screen": 3, "sprite": "Karakara", "x": 2, "y": 1, "misc": 64}, + {"screen": 3, "sprite": "Karakara", "x": 6, "y": 14, "misc": 192}, + {"screen": 3, "sprite": "Masked Ghoul/Bullet Bill", "x": 14, "y": 24, "misc": 192}, + {"screen": 3, "sprite": "Flower Block", "x": 21, "y": 11, "misc": 64}, + {"screen": 4, "sprite": "Pencil/Spikey", "x": 7, "y": 26, "misc": 192}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 10, "y": 14, "misc": 160}, + {"screen": 4, "sprite": "Pencil/Spikey", "x": 11, "y": 26, "misc": 192}, + {"screen": 4, "sprite": "Karakara", "x": 21, "y": 22, "misc": 64}, + {"screen": 4, "sprite": "Karakara", "x": 28, "y": 12, "misc": 192}, + {"screen": 5, "sprite": "Pencil/Spikey", "x": 1, "y": 24, "misc": 192}, + {"screen": 5, "sprite": "Star Block", "x": 5, "y": 5, "misc": 64}, + {"screen": 5, "sprite": "Masked Ghoul/Bullet Bill", "x": 26, "y": 24, "misc": 192}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 30, "y": 10, "misc": 32}, + {"screen": 6, "sprite": "Masked Ghoul/Bullet Bill", "x": 6, "y": 28, "misc": 64}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 10, "y": 22, "misc": 32}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 14, "y": 26, "misc": 32}, + {"screen": 6, "sprite": "Midway Bell", "x": 15, "y": 4, "misc": 32}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 18, "y": 10, "misc": 64}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 26, "y": 2, "misc": 64}, + {"screen": 7, "sprite": "Karakara", "x": 8, "y": 14, "misc": 160}, + {"screen": 7, "sprite": "Karakara", "x": 19, "y": 27, "misc": 192}, + {"screen": 8, "sprite": "Flower", "x": 5, "y": 4, "misc": 64}, + {"screen": 8, "sprite": "Heart Block", "x": 7, "y": 3, "misc": 64}, + {"screen": 8, "sprite": "Pencil/Spikey", "x": 11, "y": 24, "misc": 32}, + {"screen": 8, "sprite": "Money Bag Block", "x": 23, "y": 13, "misc": 64}, + {"screen": 9, "sprite": "Pencil/Spikey", "x": 9, "y": 24, "misc": 192}, + {"screen": 9, "sprite": "Pencil/Spikey", "x": 19, "y": 24, "misc": 64}, + {"screen": 10, "sprite": "Rising Platform", "x": 4, "y": 22, "misc": 64}, + {"screen": 10, "sprite": "Rising Platform", "x": 10, "y": 16, "misc": 64}, + {"screen": 10, "sprite": "Bonus Bell", "x": 21, "y": 9, "misc": 64}, + {"screen": 12, "sprite": "Pencil/Spikey", "x": 5, "y": 24, "misc": 192}, + {"screen": 12, "sprite": "Pencil/Spikey", "x": 9, "y": 24, "misc": 192}, + {"screen": 12, "sprite": "Karakara", "x": 19, "y": 24, "misc": 64}, + {"screen": 12, "sprite": "Karakara", "x": 26, "y": 28, "misc": 192}, + {"screen": 13, "sprite": "Karakara", "x": 1, "y": 26, "misc": 192}, + {"screen": 13, "sprite": "Pencil/Spikey", "x": 15, "y": 24, "misc": 64}, + {"screen": 13, "sprite": "Honebon/F Boy", "x": 24, "y": 28, "misc": 192}, + {"screen": 14, "sprite": "Pencil/Spikey", "x": 1, "y": 24, "misc": 192}, + {"screen": 14, "sprite": "Shark", "x": 14, "y": 26, "misc": 64}], + "Turtle Zone 3": [ + {"screen": 1, "sprite": "Ragumo/Aqua Kuribo", "x": 1, "y": 26, "misc": 160}, + {"screen": 1, "sprite": "Ragumo/Aqua Kuribo", "x": 31, "y": 22, "misc": 160}, + {"screen": 2, "sprite": "Carrot Block", "x": 15, "y": 15, "misc": 32}, + {"screen": 2, "sprite": "Pencil/Spikey", "x": 29, "y": 14, "misc": 160}, + {"screen": 3, "sprite": "Pencil/Spikey", "x": 13, "y": 22, "misc": 160}, + {"screen": 3, "sprite": "Pencil/Spikey", "x": 21, "y": 26, "misc": 32}, + {"screen": 4, "sprite": "Ragumo/Aqua Kuribo", "x": 5, "y": 24, "misc": 32}, + {"screen": 5, "sprite": "Paragoomba (Vertical)", "x": 0, "y": 24, "misc": 160}, + {"screen": 5, "sprite": "Midway Bell", "x": 12, "y": 18, "misc": 32}, + {"screen": 5, "sprite": "Ragumo/Aqua Kuribo", "x": 27, "y": 20, "misc": 32}, + {"screen": 5, "sprite": "Mushroom Block", "x": 29, "y": 19, "misc": 32}, + {"screen": 6, "sprite": "Honebon/F Boy", "x": 1, "y": 30, "misc": 160}, + {"screen": 6, "sprite": "Ragumo/Aqua Kuribo", "x": 7, "y": 20, "misc": 160}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 24, "y": 20, "misc": 160}, + {"screen": 7, "sprite": "Ragumo/Aqua Kuribo", "x": 6, "y": 28, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 27, "y": 28, "misc": 160}, + {"screen": 8, "sprite": "Ragumo/Aqua Kuribo", "x": 7, "y": 28, "misc": 160}, + {"screen": 8, "sprite": "Ragumo/Aqua Kuribo", "x": 19, "y": 28, "misc": 32}, + {"screen": 9, "sprite": "Mushroom Block", "x": 17, "y": 13, "misc": 32}, + {"screen": 9, "sprite": "Honebon/F Boy", "x": 27, "y": 22, "misc": 160}, + {"screen": 9, "sprite": "Money Bag Block", "x": 29, "y": 11, "misc": 32}, + {"screen": 11, "sprite": "Paragoomba (Diagonal)", "x": 13, "y": 24, "misc": 160}, + {"screen": 11, "sprite": "Koopa Troopa", "x": 19, "y": 30, "misc": 160}], + "Hippo Zone": [ + {"screen": 0, "sprite": "Money Bag Block", "x": 5, "y": 7, "misc": 32}, + {"screen": 0, "sprite": "Heart Block", "x": 7, "y": 5, "misc": 0}, + {"screen": 0, "sprite": "Heart Block", "x": 31, "y": 19, "misc": 32}, + {"screen": 1, "sprite": "Heart Block", "x": 1, "y": 19, "misc": 32}, + {"screen": 1, "sprite": "Bubble", "x": 6, "y": 24, "misc": 0}, + {"screen": 1, "sprite": "Mushroom Block", "x": 27, "y": 9, "misc": 32}, + {"screen": 2, "sprite": "Toriuo", "x": 11, "y": 8, "misc": 160}, + {"screen": 2, "sprite": "Unibo/Terekuribo", "x": 25, "y": 26, "misc": 128}, + {"screen": 2, "sprite": "Toriuo", "x": 29, "y": 8, "misc": 160}, + {"screen": 3, "sprite": "Toriuo", "x": 11, "y": 8, "misc": 32}, + {"screen": 3, "sprite": "Unibo/Terekuribo", "x": 17, "y": 26, "misc": 128}, + {"screen": 3, "sprite": "Heart Block", "x": 17, "y": 25, "misc": 0}, + {"screen": 4, "sprite": "Toriuo", "x": 3, "y": 8, "misc": 160}, + {"screen": 4, "sprite": "Unibo/Terekuribo", "x": 9, "y": 26, "misc": 128}, + {"screen": 4, "sprite": "Toriuo", "x": 21, "y": 8, "misc": 32}, + {"screen": 5, "sprite": "Horizontal Blurp", "x": 6, "y": 10, "misc": 160}, + {"screen": 5, "sprite": "Mushroom Block", "x": 13, "y": 11, "misc": 32}, + {"screen": 5, "sprite": "Horizontal Blurp", "x": 19, "y": 12, "misc": 32}, + {"screen": 5, "sprite": "Unibo/Terekuribo", "x": 25, "y": 10, "misc": 128}, + {"screen": 5, "sprite": "Unibo/Terekuribo", "x": 27, "y": 18, "misc": 0}, + {"screen": 6, "sprite": "Unibo/Terekuribo", "x": 7, "y": 22, "misc": 128}, + {"screen": 6, "sprite": "Unibo/Terekuribo", "x": 11, "y": 12, "misc": 128}, + {"screen": 6, "sprite": "Horizontal Blurp", "x": 13, "y": 14, "misc": 160}, + {"screen": 6, "sprite": "Bubble", "x": 14, "y": 30, "misc": 0}, + {"screen": 7, "sprite": "Dondon", "x": 13, "y": 10, "misc": 128}, + {"screen": 7, "sprite": "Dondon", "x": 15, "y": 18, "misc": 128}, + {"screen": 7, "sprite": "Dondon", "x": 17, "y": 26, "misc": 0}, + {"screen": 7, "sprite": "Toriuo", "x": 25, "y": 8, "misc": 160}, + {"screen": 8, "sprite": "Toriuo", "x": 5, "y": 8, "misc": 160}, + {"screen": 8, "sprite": "Flower Block", "x": 19, "y": 25, "misc": 0}, + {"screen": 8, "sprite": "Toriuo", "x": 21, "y": 8, "misc": 160}, + {"screen": 8, "sprite": "Toriuo", "x": 31, "y": 8, "misc": 32}, + {"screen": 9, "sprite": "Money Bag Block", "x": 11, "y": 5, "misc": 0}, + {"screen": 9, "sprite": "Horizontal Blurp", "x": 15, "y": 12, "misc": 160}, + {"screen": 9, "sprite": "Horizontal Blurp", "x": 27, "y": 10, "misc": 160}, + {"screen": 10, "sprite": "Dondon", "x": 9, "y": 14, "misc": 0}, + {"screen": 10, "sprite": "Dondon", "x": 13, "y": 24, "misc": 0}, + {"screen": 10, "sprite": "Toriuo", "x": 19, "y": 8, "misc": 32}, + {"screen": 11, "sprite": "Bonus Bell", "x": 21, "y": 5, "misc": 0}], + "Space Zone 1": [ + {"screen": 1, "sprite": "Boo/Bomubomu", "x": 19, "y": 26, "misc": 160}, + {"screen": 2, "sprite": "Boo/Bomubomu", "x": 3, "y": 26, "misc": 160}, + {"screen": 3, "sprite": "Boo/Bomubomu", "x": 5, "y": 26, "misc": 160}, + {"screen": 3, "sprite": "Rerere/Poro", "x": 25, "y": 5, "misc": 160}, + {"screen": 4, "sprite": "Money Bag Block", "x": 9, "y": 21, "misc": 0}, + {"screen": 4, "sprite": "Money Bag Block", "x": 11, "y": 29, "misc": 0}, + {"screen": 4, "sprite": "Heart", "x": 13, "y": 6, "misc": 32}, + {"screen": 4, "sprite": "Mushroom Block", "x": 23, "y": 15, "misc": 32}, + {"screen": 5, "sprite": "No 48/Mogyo", "x": 1, "y": 21, "misc": 32}, + {"screen": 5, "sprite": "Heart", "x": 5, "y": 16, "misc": 0}, + {"screen": 5, "sprite": "Boo/Bomubomu", "x": 23, "y": 28, "misc": 160}, + {"screen": 6, "sprite": "Rerere/Poro", "x": 18, "y": 20, "misc": 32}, + {"screen": 7, "sprite": "Flower Block", "x": 5, "y": 11, "misc": 32}, + {"screen": 7, "sprite": "Rerere/Poro", "x": 6, "y": 20, "misc": 160}, + {"screen": 7, "sprite": "Midway Bell", "x": 15, "y": 22, "misc": 32}, + {"screen": 7, "sprite": "Rerere/Poro", "x": 19, "y": 13, "misc": 32}, + {"screen": 8, "sprite": "Boo/Bomubomu", "x": 1, "y": 28, "misc": 32}, + {"screen": 8, "sprite": "Money Bag Block", "x": 7, "y": 21, "misc": 32}, + {"screen": 8, "sprite": "Boo/Bomubomu", "x": 17, "y": 28, "misc": 32}, + {"screen": 9, "sprite": "Heart Block", "x": 3, "y": 15, "misc": 0}, + {"screen": 9, "sprite": "Boo/Bomubomu", "x": 8, "y": 24, "misc": 32}, + {"screen": 9, "sprite": "Rerere/Poro", "x": 31, "y": 15, "misc": 160}, + {"screen": 10, "sprite": "Boo/Bomubomu", "x": 31, "y": 20, "misc": 32}, + {"screen": 11, "sprite": "Boo/Bomubomu", "x": 3, "y": 28, "misc": 32}, + {"screen": 11, "sprite": "Bonus Bell", "x": 21, "y": 11, "misc": 32}], + "Space Zone 2": [ + {"screen": 2, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 5, "y": 22, "misc": 128}, + {"screen": 2, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 25, "y": 16, "misc": 128}, + {"screen": 2, "sprite": "Star (Horizontal)/Blurp (Vertical)", "x": 27, "y": 30, "misc": 128}, + {"screen": 3, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 11, "y": 10, "misc": 128}, + {"screen": 4, "sprite": "Mushroom", "x": 1, "y": 6, "misc": 0}, + {"screen": 4, "sprite": "Star (Horizontal)/Blurp (Vertical)", "x": 3, "y": 30, "misc": 128}, + {"screen": 4, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 23, "y": 26, "misc": 128}, + {"screen": 5, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 1, "y": 22, "misc": 128}, + {"screen": 5, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 9, "y": 26, "misc": 128}, + {"screen": 5, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 27, "y": 14, "misc": 0}, + {"screen": 6, "sprite": "Mushroom Block", "x": 13, "y": 15, "misc": 0}, + {"screen": 6, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 19, "y": 18, "misc": 128}, + {"screen": 7, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 13, "y": 22, "misc": 128}, + {"screen": 7, "sprite": "Mushroom Block", "x": 17, "y": 9, "misc": 0}, + {"screen": 7, "sprite": "Tosenbo/Pikku", "x": 27, "y": 24, "misc": 128}, + {"screen": 8, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 3, "y": 16, "misc": 128}, + {"screen": 9, "sprite": "Tosenbo/Pikku", "x": 3, "y": 16, "misc": 0}, + {"screen": 9, "sprite": "Tosenbo/Pikku", "x": 25, "y": 16, "misc": 0}, + {"screen": 10, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 13, "y": 16, "misc": 128}, + {"screen": 10, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 25, "y": 16, "misc": 128}, + {"screen": 11, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 15, "y": 20, "misc": 128}, + {"screen": 11, "sprite": "Star (Horizontal)/Blurp (Vertical)", "x": 25, "y": 22, "misc": 0}, + {"screen": 12, "sprite": "Star (Vertical)/Blurp (Horizontal)", "x": 5, "y": 16, "misc": 128}, + {"screen": 12, "sprite": "Mushroom Block", "x": 31, "y": 11, "misc": 0}, + {"screen": 13, "sprite": "Star Block", "x": 5, "y": 17, "misc": 0}, + {"screen": 13, "sprite": "Tosenbo/Pikku", "x": 7, "y": 17, "misc": 128}, + {"screen": 13, "sprite": "Midway Bell", "x": 19, "y": 20, "misc": 0}, + {"screen": 13, "sprite": "Mushroom", "x": 31, "y": 6, "misc": 0}, + {"screen": 15, "sprite": "Tosenbo/Pikku", "x": 1, "y": 26, "misc": 128}, + {"screen": 15, "sprite": "Mushroom Block", "x": 17, "y": 19, "misc": 0}], + "Macro Zone 1": [ + {"screen": 1, "sprite": "Kyotonbo", "x": 1, "y": 22, "misc": 0}, + {"screen": 1, "sprite": "Goronto", "x": 23, "y": 26, "misc": 128}, + {"screen": 2, "sprite": "Moving Platform (Large, Horizontal)", "x": 20, "y": 31, + "misc": 64}, {"screen": 3, "sprite": "Chikunto", "x": 1, "y": 16, "misc": 64}, + {"screen": 3, "sprite": "Mushroom Block", "x": 3, "y": 21, "misc": 64}, + {"screen": 4, "sprite": "Chikunto", "x": 19, "y": 28, "misc": 192}, + {"screen": 5, "sprite": "Big Diagonal Moving Platform", "x": 12, "y": 23, + "misc": 64}, + {"screen": 5, "sprite": "Moving Platform (Large, Horizontal)", "x": 14, "y": 31, + "misc": 64}, + {"screen": 5, "sprite": "Carrot Block", "x": 15, "y": 13, "misc": 64}, + {"screen": 6, "sprite": "Dokanto", "x": 25, "y": 28, "misc": 64}, + {"screen": 6, "sprite": "Carrot Block", "x": 31, "y": 27, "misc": 64}, + {"screen": 7, "sprite": "Kyotonbo", "x": 27, "y": 28, "misc": 64}, + {"screen": 8, "sprite": "Flower Block", "x": 1, "y": 27, "misc": 64}, + {"screen": 8, "sprite": "Chikunto", "x": 9, "y": 28, "misc": 64}, + {"screen": 9, "sprite": "Heart Block", "x": 11, "y": 27, "misc": 64}, + {"screen": 9, "sprite": "Chikunto", "x": 19, "y": 28, "misc": 192}, + {"screen": 9, "sprite": "Money Bag Block", "x": 25, "y": 27, "misc": 64}, + {"screen": 9, "sprite": "Goronto", "x": 29, "y": 28, "misc": 64}, + {"screen": 10, "sprite": "Heart Block", "x": 9, "y": 9, "misc": 32}, + {"screen": 10, "sprite": "Heart Block", "x": 13, "y": 9, "misc": 32}, + {"screen": 10, "sprite": "Midway Bell", "x": 15, "y": 26, "misc": 64}, + {"screen": 10, "sprite": "Heart Block", "x": 21, "y": 9, "misc": 32}, + {"screen": 10, "sprite": "Moving Platform (Large, Horizontal)", "x": 30, "y": 31, + "misc": 64}, + {"screen": 11, "sprite": "Carrot Block", "x": 3, "y": 15, "misc": 64}, + {"screen": 11, "sprite": "Falling Platform", "x": 26, "y": 17, "misc": 64}, + {"screen": 12, "sprite": "Moving Platform (Large, Horizontal)", "x": 28, "y": 31, + "misc": 64}, {"screen": 13, "sprite": "Kyotonbo", "x": 3, "y": 18, "misc": 192}, + {"screen": 13, "sprite": "Chikunto", "x": 17, "y": 28, "misc": 64}, + {"screen": 13, "sprite": "Dokanto", "x": 25, "y": 18, "misc": 64}, + {"screen": 14, "sprite": "Kyotonbo", "x": 0, "y": 28, "misc": 32}, + {"screen": 14, "sprite": "Moving Platform (Large, Horizontal)", "x": 0, "y": 31, + "misc": 64}, {"screen": 14, "sprite": "Goronto", "x": 12, "y": 26, "misc": 32}, + {"screen": 14, "sprite": "Dokanto", "x": 19, "y": 28, "misc": 192}, + {"screen": 14, "sprite": "Flower Block", "x": 21, "y": 21, "misc": 64}, + {"screen": 15, "sprite": "Big Diagonal Moving Platform", "x": 13, "y": 21, + "misc": 64}, + {"screen": 15, "sprite": "Bonus Bell", "x": 21, "y": 11, "misc": 64}], + "Macro Zone 2": [ + {"screen": 1, "sprite": "Ant", "x": 10, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Mushroom Block", "x": 19, "y": 19, "misc": 32}, + {"screen": 1, "sprite": "Piranha Plant", "x": 28, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Ant", "x": 21, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Battle Beetle", "x": 23, "y": 24, "misc": 32}, + {"screen": 3, "sprite": "Ant", "x": 5, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Fire Piranha Plant", "x": 22, "y": 2, "misc": 192}, + {"screen": 4, "sprite": "Ant", "x": 8, "y": 26, "misc": 160}, + {"screen": 4, "sprite": "Fire Piranha Plant", "x": 18, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Piranha Plant", "x": 6, "y": 30, "misc": 160}, + {"screen": 5, "sprite": "Battle Beetle", "x": 16, "y": 26, "misc": 32}, + {"screen": 6, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 5, "y": 26, "misc": 192}, + {"screen": 6, "sprite": "Carrot Block", "x": 7, "y": 15, "misc": 64}, + {"screen": 6, "sprite": "Ant", "x": 16, "y": 18, "misc": 64}, + {"screen": 7, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 0, "y": 23, "misc": 192}, + {"screen": 7, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 11, "y": 28, "misc": 64}, + {"screen": 7, "sprite": "Fire Piranha Plant", "x": 30, "y": 20, "misc": 192}, + {"screen": 8, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 15, "y": 28, "misc": 64}, + {"screen": 8, "sprite": "Star Block", "x": 19, "y": 9, "misc": 64}, + {"screen": 8, "sprite": "Piranha Plant", "x": 30, "y": 22, "misc": 64}, + {"screen": 9, "sprite": "Cheep Cheep (Vertical)", "x": 11, "y": 28, "misc": 64}, + {"screen": 9, "sprite": "Cheep Cheep (Vertical)", "x": 17, "y": 28, "misc": 64}, + {"screen": 9, "sprite": "Midway Bell", "x": 31, "y": 14, "misc": 64}, + {"screen": 10, "sprite": "Ant", "x": 1, "y": 18, "misc": 64}, + {"screen": 10, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 31, "y": 28, "misc": 64}, + {"screen": 11, "sprite": "Ant", "x": 3, "y": 16, "misc": 64}, + {"screen": 11, "sprite": "Star Block", "x": 9, "y": 15, "misc": 64}, + {"screen": 11, "sprite": "Owl Platform (Horizontal)/Cheep Cheep (Horizontal)", "x": 19, "y": 15, "misc": 160}, + {"screen": 11, "sprite": "Cheep Cheep (Vertical)", "x": 21, "y": 29, "misc": 64}, + {"screen": 12, "sprite": "Be", "x": 9, "y": 14, "misc": 32}, + {"screen": 12, "sprite": "Be", "x": 21, "y": 24, "misc": 32}, + {"screen": 12, "sprite": "Be", "x": 27, "y": 24, "misc": 32}, + {"screen": 13, "sprite": "Mushroom Block", "x": 7, "y": 23, "misc": 32}, + {"screen": 13, "sprite": "Bonus Bell", "x": 21, "y": 15, "misc": 32}], + "Macro Zone 3": [ + {"screen": 1, "sprite": "Koopa Troopa", "x": 0, "y": 26, "misc": 32}, + {"screen": 1, "sprite": "Goomba", "x": 9, "y": 22, "misc": 32}, + {"screen": 1, "sprite": "Carrot Block", "x": 17, "y": 13, "misc": 32}, + {"screen": 1, "sprite": "Goomba", "x": 23, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Goomba", "x": 4, "y": 26, "misc": 32}, + {"screen": 2, "sprite": "Goomba", "x": 29, "y": 26, "misc": 32}, + {"screen": 3, "sprite": "Piranha Plant", "x": 28, "y": 2, "misc": 64}, + {"screen": 4, "sprite": "Piranha Plant (Downward)/Grubby", "x": 4, "y": 25, "misc": 160}, + {"screen": 4, "sprite": "Goomba", "x": 14, "y": 30, "misc": 160}, + {"screen": 4, "sprite": "Goomba", "x": 30, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Piranha Plant (Downward)/Grubby", "x": 8, "y": 25, "misc": 32}, + {"screen": 5, "sprite": "Money Bag Block", "x": 11, "y": 21, "misc": 64}, + {"screen": 5, "sprite": "Honebon/F Boy", "x": 11, "y": 30, "misc": 64}, + {"screen": 5, "sprite": "Paragoomba (Diagonal)", "x": 23, "y": 28, "misc": 32}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 15, "y": 26, "misc": 64}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 23, "y": 26, "misc": 64}, + {"screen": 7, "sprite": "Mushroom Block", "x": 1, "y": 23, "misc": 64}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 11, "y": 26, "misc": 64}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 21, "y": 26, "misc": 64}, + {"screen": 8, "sprite": "Heart Block", "x": 3, "y": 5, "misc": 32}, + {"screen": 8, "sprite": "Koopa Troopa", "x": 7, "y": 26, "misc": 64}, + {"screen": 8, "sprite": "Koopa Troopa", "x": 17, "y": 26, "misc": 64}, + {"screen": 8, "sprite": "Star Block", "x": 29, "y": 23, "misc": 64}, + {"screen": 8, "sprite": "Midway Bell", "x": 31, "y": 22, "misc": 32}, + {"screen": 9, "sprite": "Be", "x": 31, "y": 18, "misc": 32}, + {"screen": 10, "sprite": "Be", "x": 11, "y": 18, "misc": 32}, + {"screen": 11, "sprite": "Piranha Plant", "x": 16, "y": 24, "misc": 160}, + {"screen": 12, "sprite": "Carrot Block", "x": 23, "y": 17, "misc": 32}, + {"screen": 13, "sprite": "Koopa Troopa", "x": 7, "y": 4, "misc": 160}, + {"screen": 13, "sprite": "Paragoomba (Vertical)", "x": 15, "y": 24, "misc": 128}, + {"screen": 13, "sprite": "Bonus Bell", "x": 23, "y": 5, "misc": 0}], + "Macro Zone 4": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 1, "y": 23, "misc": 32}, + {"screen": 1, "sprite": "Goomba", "x": 7, "y": 28, "misc": 160}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 17, "y": 24, "misc": 32}, + {"screen": 2, "sprite": "Runaway Heart Block/Bibi", "x": 5, "y": 23, "misc": 32}, + {"screen": 3, "sprite": "Goomba", "x": 11, "y": 24, "misc": 32}, + {"screen": 3, "sprite": "Goomba", "x": 21, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Piranha Plant", "x": 6, "y": 24, "misc": 32}, + {"screen": 5, "sprite": "Piranha Plant (Downward)/Grubby", "x": 4, "y": 25, "misc": 32}, + {"screen": 5, "sprite": "Money Bag Block", "x": 11, "y": 7, "misc": 32}, + {"screen": 5, "sprite": "Carrot Block", "x": 15, "y": 23, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 19, "y": 30, "misc": 160}, + {"screen": 6, "sprite": "Goomba", "x": 7, "y": 30, "misc": 160}, + {"screen": 6, "sprite": "Goomba", "x": 11, "y": 18, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 25, "y": 30, "misc": 160}, + {"screen": 7, "sprite": "Runaway Heart Block/Bibi", "x": 5, "y": 23, "misc": 32}, + {"screen": 7, "sprite": "Fire Piranha Plant", "x": 24, "y": 30, "misc": 160}, + {"screen": 8, "sprite": "Midway Bell", "x": 3, "y": 20, "misc": 32}, + {"screen": 8, "sprite": "Piranha Plant", "x": 8, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Goomba", "x": 26, "y": 24, "misc": 32}, + {"screen": 9, "sprite": "Mushroom Block", "x": 1, "y": 11, "misc": 32}, + {"screen": 9, "sprite": "Goomba", "x": 1, "y": 20, "misc": 32}, + {"screen": 9, "sprite": "Paragoomba (Diagonal)", "x": 13, "y": 16, "misc": 160}, + {"screen": 10, "sprite": "Paragoomba (Diagonal)", "x": 29, "y": 26, "misc": 160}, + {"screen": 11, "sprite": "Paragoomba (Diagonal)", "x": 13, "y": 26, "misc": 32}], + "Mario's Castle": [ + {"screen": 0, "sprite": "Mushroom Block", "x": 15, "y": 17, "misc": 32}, + {"screen": 1, "sprite": "Falling Bone Platform", "x": 14, "y": 27, "misc": 32}, + {"screen": 1, "sprite": "Falling Bone Platform", "x": 22, "y": 27, "misc": 32}, + {"screen": 1, "sprite": "Skull Platform", "x": 25, "y": 30, "misc": 64}, + {"screen": 1, "sprite": "Rising Bone Platform", "x": 30, "y": 28, "misc": 32}, + {"screen": 2, "sprite": "Skull Platform", "x": 5, "y": 30, "misc": 64}, + {"screen": 2, "sprite": "Falling Bone Platform", "x": 16, "y": 27, "misc": 32}, + {"screen": 2, "sprite": "Falling Bone Platform", "x": 24, "y": 27, "misc": 32}, + {"screen": 2, "sprite": "Skull Platform", "x": 29, "y": 30, "misc": 64}, + {"screen": 3, "sprite": "Rising Bone Platform", "x": 0, "y": 28, "misc": 32}, + {"screen": 3, "sprite": "Skull Platform", "x": 3, "y": 30, "misc": 64}, + {"screen": 3, "sprite": "Rising Bone Platform", "x": 18, "y": 28, "misc": 32}, + {"screen": 3, "sprite": "Skull Platform", "x": 25, "y": 30, "misc": 64}, + {"screen": 3, "sprite": "Falling Bone Platform", "x": 26, "y": 27, "misc": 32}, + {"screen": 3, "sprite": "Skull Platform", "x": 27, "y": 30, "misc": 64}, + {"screen": 4, "sprite": "Rising Bone Platform", "x": 2, "y": 28, "misc": 32}, + {"screen": 4, "sprite": "Genkottsu (1.5 Tiles)", "x": 22, "y": 31, "misc": 64}, + {"screen": 5, "sprite": "Genkottsu (2 Tiles)", "x": 6, "y": 31, "misc": 64}, + {"screen": 5, "sprite": "Karamenbo", "x": 14, "y": 20, "misc": 32}, + {"screen": 5, "sprite": "Karamenbo", "x": 20, "y": 20, "misc": 32}, + {"screen": 5, "sprite": "Genkottsu (2 Tiles)", "x": 22, "y": 31, "misc": 64}, + {"screen": 6, "sprite": "Karamenbo", "x": 1, "y": 20, "misc": 32}, + {"screen": 6, "sprite": "Karamenbo", "x": 8, "y": 20, "misc": 32}, + {"screen": 6, "sprite": "Karamenbo", "x": 21, "y": 20, "misc": 32}, + {"screen": 7, "sprite": "Propeller Platform", "x": 4, "y": 30, "misc": 64}, + {"screen": 7, "sprite": "Propeller Platform", "x": 16, "y": 30, "misc": 64}, + {"screen": 7, "sprite": "Floating Face", "x": 19, "y": 26, "misc": 32}, + {"screen": 8, "sprite": "Propeller Platform", "x": 4, "y": 30, "misc": 64}, + {"screen": 8, "sprite": "Floating Face", "x": 17, "y": 29, "misc": 32}, + {"screen": 8, "sprite": "Floating Face", "x": 17, "y": 23, "misc": 32}, + {"screen": 8, "sprite": "Propeller Platform", "x": 18, "y": 30, "misc": 64}, + {"screen": 9, "sprite": "Floating Face", "x": 15, "y": 28, "misc": 32}, + {"screen": 9, "sprite": "Floating Face", "x": 16, "y": 22, "misc": 32}, + {"screen": 10, "sprite": "Mushroom Block", "x": 1, "y": 23, "misc": 64}, + {"screen": 10, "sprite": "Spike Ball (Large)", "x": 11, "y": 28, "misc": 64}, + {"screen": 10, "sprite": "Mushroom Block", "x": 15, "y": 23, "misc": 32}, + {"screen": 10, "sprite": "Spike Ball (Small)", "x": 29, "y": 30, "misc": 64}, + {"screen": 11, "sprite": "Fire Pakkun Zo (Left)", "x": 8, "y": 28, "misc": 192}, + {"screen": 11, "sprite": "Fire Pakkun Zo (Left)", "x": 14, "y": 26, "misc": 64}, + {"screen": 11, "sprite": "Spike Ball (Large)", "x": 31, "y": 30, "misc": 192}, + {"screen": 12, "sprite": "Fire Pakkun Zo (Large)", "x": 15, "y": 26, "misc": 64}, + {"screen": 12, "sprite": "Fire Pakkun Zo (Left)", "x": 24, "y": 28, "misc": 192}, + {"screen": 13, "sprite": "Fire Pakkun Zo (Left)", "x": 0, "y": 24, "misc": 64}, + {"screen": 13, "sprite": "Fire Pakkun Zo (Left)", "x": 8, "y": 24, "misc": 64}, + {"screen": 13, "sprite": "Spike Ball (Large)", "x": 29, "y": 30, "misc": 64}, + {"screen": 14, "sprite": "Spike Ball (Small)", "x": 12, "y": 26, "misc": 192}, + {"screen": 15, "sprite": "Fire Pakkun Zo (Right)", "x": 4, "y": 16, "misc": 64}, + {"screen": 15, "sprite": "Mushroom Block", "x": 15, "y": 19, "misc": 32}], + "Scenic Course": [ + {"screen": 1, "sprite": "Paragoomba (Diagonal)", "x": 1, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Goomba", "x": 11, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Paragoomba (Diagonal)", "x": 21, "y": 30, "misc": 32}, + {"screen": 1, "sprite": "Goomba", "x": 31, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Paragoomba (Diagonal)", "x": 9, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Mushroom Block", "x": 15, "y": 23, "misc": 32}, + {"screen": 2, "sprite": "Goomba", "x": 19, "y": 30, "misc": 32}, + {"screen": 2, "sprite": "Paragoomba (Diagonal)", "x": 29, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Paragoomba (Diagonal)", "x": 7, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Goomba", "x": 17, "y": 30, "misc": 32}, + {"screen": 3, "sprite": "Star Block", "x": 19, "y": 23, "misc": 32}, + {"screen": 3, "sprite": "Paragoomba (Diagonal)", "x": 27, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Goomba", "x": 5, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Goomba", "x": 15, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Mushroom Block", "x": 17, "y": 23, "misc": 32}, + {"screen": 4, "sprite": "Paragoomba (Diagonal)", "x": 25, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Paragoomba (Diagonal)", "x": 3, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Paragoomba (Diagonal)", "x": 13, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Goomba", "x": 17, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 1, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Paragoomba (Diagonal)", "x": 11, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 21, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Paragoomba (Diagonal)", "x": 31, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Paragoomba (Diagonal)", "x": 9, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Flower Block", "x": 11, "y": 23, "misc": 32}, + {"screen": 7, "sprite": "Paragoomba (Diagonal)", "x": 19, "y": 30, "misc": 32}], + "Turtle Zone Secret Course": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 7, "y": 21, "misc": 32}, + {"screen": 1, "sprite": "Heart Block", "x": 27, "y": 15, "misc": 32}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 29, "y": 28, "misc": 32}, + {"screen": 3, "sprite": "Flower Block", "x": 11, "y": 21, "misc": 32}, + {"screen": 4, "sprite": "Money Bag Block", "x": 1, "y": 19, "misc": 32}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 31, "y": 28, "misc": 32}, + {"screen": 5, "sprite": "Carrot Block", "x": 15, "y": 21, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 1, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Piranha Plant", "x": 6, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Mushroom Block", "x": 19, "y": 23, "misc": 32}, + {"screen": 7, "sprite": "Flower Block", "x": 21, "y": 23, "misc": 32}, + {"screen": 7, "sprite": "Carrot Block", "x": 23, "y": 23, "misc": 32}], + "Pumpkin Zone Secret Course 1": [ + {"screen": 0, "sprite": "Carrot Block", "x": 29, "y": 29, "misc": 0}, + {"screen": 1, "sprite": "Paragoomba (Vertical)", "x": 22, "y": 0, "misc": 32}, + {"screen": 2, "sprite": "Paragoomba (Vertical)", "x": 14, "y": 2, "misc": 32}, + {"screen": 3, "sprite": "Paragoomba (Vertical)", "x": 6, "y": 4, "misc": 32}, + {"screen": 3, "sprite": "Paragoomba (Vertical)", "x": 30, "y": 30, "misc": 0}, + {"screen": 4, "sprite": "Paragoomba (Vertical)", "x": 23, "y": 4, "misc": 32}, + {"screen": 5, "sprite": "Goomba", "x": 15, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Goomba", "x": 25, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 19, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Goomba", "x": 29, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Goomba", "x": 11, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Goomba", "x": 29, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Goomba", "x": 15, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Star", "x": 25, "y": 24, "misc": 32}], + "Space Zone Secret Course": [ + {"screen": 2, "sprite": "Rerere/Poro", "x": 2, "y": 2, "misc": 32}, + {"screen": 3, "sprite": "Rerere/Poro", "x": 14, "y": 20, "misc": 0}, + {"screen": 4, "sprite": "Heart", "x": 3, "y": 22, "misc": 32}, + {"screen": 4, "sprite": "Heart", "x": 5, "y": 22, "misc": 32}, + {"screen": 4, "sprite": "Rerere/Poro", "x": 26, "y": 2, "misc": 32}, + {"screen": 5, "sprite": "Heart Block", "x": 21, "y": 19, "misc": 0}], + "Tree Zone Secret Course": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 3, "y": 13, "misc": 32}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 9, "y": 24, "misc": 32}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 13, "y": 14, "misc": 32}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 25, "y": 16, "misc": 32}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 3, "y": 20, "misc": 32}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 19, "y": 22, "misc": 32}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 27, "y": 22, "misc": 32}, + {"screen": 3, "sprite": "Koopa Troopa", "x": 11, "y": 24, "misc": 32}, + {"screen": 3, "sprite": "Koopa Troopa", "x": 19, "y": 24, "misc": 32}, + {"screen": 3, "sprite": "Koopa Troopa", "x": 31, "y": 26, "misc": 32}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 9, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 17, "y": 30, "misc": 32}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 25, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 1, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 11, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 17, "y": 30, "misc": 32}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 29, "y": 30, "misc": 32}, + {"screen": 6, "sprite": "Heart Block", "x": 9, "y": 13, "misc": 32}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 17, "y": 26, "misc": 32}, + {"screen": 6, "sprite": "Koopa Troopa", "x": 27, "y": 26, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 1, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 11, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 21, "y": 30, "misc": 32}, + {"screen": 7, "sprite": "Koopa Troopa", "x": 31, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Koopa Troopa", "x": 7, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Koopa Troopa", "x": 17, "y": 30, "misc": 32}, + {"screen": 8, "sprite": "Koopa Troopa", "x": 27, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Koopa Troopa", "x": 5, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Koopa Troopa", "x": 13, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Koopa Troopa", "x": 21, "y": 30, "misc": 32}, + {"screen": 9, "sprite": "Heart Block", "x": 31, "y": 13, "misc": 32}], + "Macro Zone Secret Course": [ + {"screen": 1, "sprite": "Mushroom Block", "x": 11, "y": 15, "misc": 32}, + {"screen": 1, "sprite": "Falling Platform", "x": 28, "y": 26, "misc": 32}, + {"screen": 2, "sprite": "Falling Platform", "x": 12, "y": 26, "misc": 32}, + {"screen": 2, "sprite": "Falling Platform", "x": 18, "y": 26, "misc": 32}, + {"screen": 3, "sprite": "Heart Block", "x": 11, "y": 21, "misc": 32}, + {"screen": 5, "sprite": "Flower Block", "x": 17, "y": 17, "misc": 32}, + {"screen": 6, "sprite": "Heart Block", "x": 25, "y": 27, "misc": 32}], + "Pumpkin Zone Secret Course 2": [ + {"screen": 0, "sprite": "Flower Block", "x": 25, "y": 11, "misc": 0}, + {"screen": 1, "sprite": "Heart Block", "x": 9, "y": 17, "misc": 0}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 16, "y": 20, "misc": 0}, + {"screen": 1, "sprite": "Heart Block", "x": 23, "y": 15, "misc": 0}, + {"screen": 1, "sprite": "Koopa Troopa", "x": 29, "y": 20, "misc": 0}, + {"screen": 2, "sprite": "Heart Block", "x": 5, "y": 13, "misc": 0}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 13, "y": 20, "misc": 0}, + {"screen": 2, "sprite": "Goomba", "x": 21, "y": 20, "misc": 0}, + {"screen": 2, "sprite": "Koopa Troopa", "x": 31, "y": 20, "misc": 0}, + {"screen": 3, "sprite": "Heart Block", "x": 17, "y": 17, "misc": 0}, + {"screen": 3, "sprite": "Heart Block", "x": 25, "y": 13, "misc": 0}, + {"screen": 4, "sprite": "Koopa Troopa", "x": 1, "y": 20, "misc": 0}, + {"screen": 4, "sprite": "Falling Platform", "x": 18, "y": 24, "misc": 0}, + {"screen": 5, "sprite": "Falling Platform", "x": 2, "y": 22, "misc": 0}, + {"screen": 5, "sprite": "Koopa Troopa", "x": 10, "y": 22, "misc": 0}, + {"screen": 5, "sprite": "Mushroom Block", "x": 11, "y": 15, "misc": 0}, + {"screen": 5, "sprite": "Falling Platform", "x": 18, "y": 24, "misc": 0}, + {"screen": 5, "sprite": "Falling Platform", "x": 26, "y": 24, "misc": 0}, + {"screen": 6, "sprite": "Falling Platform", "x": 2, "y": 24, "misc": 0}, + {"screen": 6, "sprite": "Falling Platform", "x": 10, "y": 24, "misc": 0}, + {"screen": 6, "sprite": "Falling Platform", "x": 18, "y": 24, "misc": 0}, + {"screen": 7, "sprite": "Goomba", "x": 13, "y": 18, "misc": 0}, + {"screen": 7, "sprite": "Heart Block", "x": 15, "y": 17, "misc": 0}, + {"screen": 7, "sprite": "Goomba", "x": 29, "y": 18, "misc": 0}, + {"screen": 8, "sprite": "Heart Block", "x": 9, "y": 17, "misc": 0}, + {"screen": 8, "sprite": "Goomba", "x": 11, "y": 18, "misc": 0}, + {"screen": 8, "sprite": "Heart Block", "x": 23, "y": 17, "misc": 0}, + {"screen": 8, "sprite": "Goomba", "x": 25, "y": 18, "misc": 0}, + {"screen": 9, "sprite": "Falling Platform", "x": 12, "y": 20, "misc": 0}, + {"screen": 9, "sprite": "Heart", "x": 23, "y": 16, "misc": 0}, + {"screen": 10, "sprite": "Falling Platform", "x": 0, "y": 22, "misc": 0}, + {"screen": 10, "sprite": "Heart", "x": 17, "y": 14, "misc": 0}]} From 7e772b4ee9462045b0b0aff54e5fe7431ec4067f Mon Sep 17 00:00:00 2001 From: Sunny Bat Date: Wed, 21 May 2025 09:12:37 -0700 Subject: [PATCH 0438/1218] Raft: Small Raft doc update, bugfix (#5008) * Small doc touchups * Advanced Scarecrow progressive * Add period to doc Co-authored-by: Duck <31627079+duckboycool@users.noreply.github.com> --------- Co-authored-by: Duck <31627079+duckboycool@users.noreply.github.com> --- worlds/raft/docs/setup_en.md | 3 ++- worlds/raft/progressives.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/worlds/raft/docs/setup_en.md b/worlds/raft/docs/setup_en.md index 16e7883776c3..25e2c16bc536 100644 --- a/worlds/raft/docs/setup_en.md +++ b/worlds/raft/docs/setup_en.md @@ -45,7 +45,8 @@ ## Multiplayer Raft You're able to have multiple Raft players on a single Raftipelago world. This will work, with a few notes: -- Only the player that creates/loads the world can connect to Archipelago (this is the "host" of the Raft world). Other players do not need to connect; everything will be routed through the the host. +- Every player that joins the Raft world must have the Raftipelago mod loaded. +- Only the player that creates/loads the world can connect to Archipelago (this is the "host" of the Raft world). Other players do not need to run */connect*; everything will be routed through the the host. - Players other than the host will be labeled as a "Raft Player (Steam name)" when using ingame chat, which will be routed through Archipelago chat. - Ingame chat will only work when the host is connected to the Archipelago server. diff --git a/worlds/raft/progressives.json b/worlds/raft/progressives.json index 11bd614ab04b..6f3900738ed2 100644 --- a/worlds/raft/progressives.json +++ b/worlds/raft/progressives.json @@ -30,7 +30,7 @@ "Steering Wheel": "progressive-engine", "Engine controls": "progressive-engine", "Scarecrow": "progressive-scarecrow", - "Advanced scarecrow": "progressive-scarecrow", + "Advanced Scarecrow": "progressive-scarecrow", "Simple collection net": "progressive-net", "Advanced collection net": "progressive-net", "Storage": "progressive-storage", From a076b9257d3c15da7f7a96ae6b6aa0c2684244d7 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 21 May 2025 09:59:04 -0700 Subject: [PATCH 0439/1218] DS3: Don't make unrandomized items into events (#5018) The DS3 static randomizer uses the relative ordering of location names to map between Archipelago's notion of location IDs and the static randomizer's. Treating unrandomized locations as excluded can break this behavior by removing some locations from the list, causing further locations to be incorrectly assigned. The only reason this wasn't a bigger problem up to this point was that location order only matters on a per-region and per-item basis. That means this only causes problems in practice when a single region has multiple locations with the same default item, and some of those locations are randomized while others are not. Since exclusions (and thus randomization) are usually done based on item types, we managed to dodge this bullet for a long time. --- worlds/dark_souls_3/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index b9f32a8d4015..5e1003d2a9a2 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -273,9 +273,7 @@ def create_region(self, region_name, location_table) -> Region: self.player, location, parent = new_region, - event = True, ) - event_item.code = None new_location.place_locked_item(event_item) if location.name in excluded: excluded.remove(location.name) From a409167f6479caa4b896daa4a9fbdee71ae1d0ae Mon Sep 17 00:00:00 2001 From: Katelyn Gigante Date: Thu, 22 May 2025 04:27:03 +1000 Subject: [PATCH 0440/1218] core: Reconfigure stdout to utf8 (#5017) --- Utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Utils.py b/Utils.py index f930335b2483..f4752448e2c3 100644 --- a/Utils.py +++ b/Utils.py @@ -540,6 +540,7 @@ def filter(self, record: logging.LogRecord) -> bool: if add_timestamp: stream_handler.setFormatter(formatter) root_logger.addHandler(stream_handler) + sys.stdout.reconfigure(encoding="utf-8", errors="replace") # Relay unhandled exceptions to logger. if not getattr(sys.excepthook, "_wrapped", False): # skip if already modified From 6827368e60c1a3ef95002ea1b43b2a0f643dc8d4 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Thu, 22 May 2025 00:45:49 +0200 Subject: [PATCH 0441/1218] Core: generate templates faster and "cleaner" (#5019) --- Options.py | 13 ++++++++----- data/options.yaml | 5 ++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Options.py b/Options.py index 86e58ca64aba..3d08c5f00370 100644 --- a/Options.py +++ b/Options.py @@ -1676,6 +1676,7 @@ def get_option_groups(world: typing.Type[World], visibility_level: Visibility = def generate_yaml_templates(target_folder: typing.Union[str, "pathlib.Path"], generate_hidden: bool = True) -> None: import os + from inspect import cleandoc import yaml from jinja2 import Template @@ -1714,19 +1715,21 @@ def yaml_dump_scalar(scalar) -> str: # yaml dump may add end of document marker and newlines. return yaml.dump(scalar).replace("...\n", "").strip() + with open(local_path("data", "options.yaml")) as f: + file_data = f.read() + template = Template(file_data) + for game_name, world in AutoWorldRegister.world_types.items(): if not world.hidden or generate_hidden: option_groups = get_option_groups(world) - with open(local_path("data", "options.yaml")) as f: - file_data = f.read() - res = Template(file_data).render( + + res = template.render( option_groups=option_groups, __version__=__version__, game=game_name, yaml_dump=yaml_dump_scalar, dictify_range=dictify_range, + cleandoc=cleandoc, ) - del file_data - with open(os.path.join(target_folder, get_file_safe_name(game_name) + ".yaml"), "w", encoding="utf-8-sig") as f: f.write(res) diff --git a/data/options.yaml b/data/options.yaml index 09bfcdcec1f6..3fbe25a9211f 100644 --- a/data/options.yaml +++ b/data/options.yaml @@ -51,10 +51,9 @@ requires: {%- for option_key, option in group_options.items() %} {{ option_key }}: {%- if option.__doc__ %} - # {{ option.__doc__ + # {{ cleandoc(option.__doc__) | trim - | replace('\n\n', '\n \n') - | replace('\n ', '\n# ') + | replace('\n', '\n# ') | indent(4, first=False) }} {%- endif -%} From defdf34e609ea91a9ce7373aa3dea4771d050ec0 Mon Sep 17 00:00:00 2001 From: Fly Hyping Date: Wed, 21 May 2025 19:00:45 -0400 Subject: [PATCH 0442/1218] Wargroove: apworld (#4764) - Players and AI can sacrifice their own units and upload them to the multiworld. - Players and AI can summon random units from the multiworld. - Has 4 new separate options for how many sacrifices and summons either the player or the AI can make per level attempt. - New /sacrifice_summon command to toggle sacrifices and summons on/off. Useful if the AI makes a level impossible with their summons. - Linux Support. - Is an apworld now. --------- Co-authored-by: Raspberry Floof Co-authored-by: KScl Co-authored-by: Abigail Fox Co-authored-by: qwint Co-authored-by: Fabian Dill --- .../wargroove/Client.py | 229 +++++++++++++++--- worlds/wargroove/Options.py | 63 ++++- worlds/wargroove/__init__.py | 37 ++- .../data/mods/ArchipelagoMod/maps.dat | Bin 276454 -> 391423 bytes .../data/mods/ArchipelagoMod/mod.dat | Bin 594 -> 593 bytes .../data/mods/ArchipelagoMod/modAssets.dat | Bin 53878 -> 67643 bytes ...paign-c40a6e5b0cdf86ddac03b276691c483d.cmp | Bin 114384 -> 114528 bytes ...n-c40a6e5b0cdf86ddac03b276691c483d.cmp.bak | Bin 114384 -> 114416 bytes worlds/wargroove/docs/en_Wargroove.md | 4 +- worlds/wargroove/docs/wargroove_en.md | 14 +- 10 files changed, 298 insertions(+), 49 deletions(-) rename WargrooveClient.py => worlds/wargroove/Client.py (63%) diff --git a/WargrooveClient.py b/worlds/wargroove/Client.py similarity index 63% rename from WargrooveClient.py rename to worlds/wargroove/Client.py index 595a221cd252..3dc5d6eb0ca9 100644 --- a/WargrooveClient.py +++ b/worlds/wargroove/Client.py @@ -2,14 +2,15 @@ import atexit import os +import pkgutil import sys import asyncio import random -import shutil +import typing from typing import Tuple, List, Iterable, Dict -from worlds.wargroove import WargrooveWorld -from worlds.wargroove.Items import item_table, faction_table, CommanderData, ItemData +from . import WargrooveWorld +from .Items import item_table, faction_table, CommanderData, ItemData import ModuleUpdate ModuleUpdate.update() @@ -21,7 +22,7 @@ if __name__ == "__main__": Utils.init_logging("WargrooveClient", exception_logger="Client") -from NetUtils import NetworkItem, ClientStatus +from NetUtils import ClientStatus from CommonClient import gui_enabled, logger, get_base_parser, ClientCommandProcessor, \ CommonContext, server_loop @@ -29,6 +30,34 @@ class WargrooveClientCommandProcessor(ClientCommandProcessor): + def _cmd_sacrifice_summon(self): + """Toggles sacrifices and summons On/Off""" + if isinstance(self.ctx, WargrooveContext): + self.ctx.has_sacrifice_summon = not self.ctx.has_sacrifice_summon + if self.ctx.has_sacrifice_summon: + self.output(f"Sacrifices and summons are enabled.") + else: + unit_summon_response_file = os.path.join(self.ctx.game_communication_path, "unitSummonResponse") + if os.path.exists(unit_summon_response_file): + os.remove(unit_summon_response_file) + self.output(f"Sacrifices and summons are disabled.") + + def _cmd_deathlink(self): + """Toggles deathlink On/Off""" + if isinstance(self.ctx, WargrooveContext): + self.ctx.has_death_link = not self.ctx.has_death_link + Utils.async_start(self.ctx.update_death_link(self.ctx.has_death_link), name="Update Deathlink") + if self.ctx.has_death_link: + death_link_send_file = os.path.join(self.ctx.game_communication_path, "deathLinkSend") + if os.path.exists(death_link_send_file): + os.remove(death_link_send_file) + self.output(f"Deathlink enabled.") + else: + death_link_receive_file = os.path.join(self.ctx.game_communication_path, "deathLinkReceive") + if os.path.exists(death_link_receive_file): + os.remove(death_link_receive_file) + self.output(f"Deathlink disabled.") + def _cmd_resync(self): """Manually trigger a resync.""" self.output(f"Syncing items.") @@ -58,6 +87,11 @@ class WargrooveContext(CommonContext): commander_defense_boost_multiplier: int = 0 income_boost_multiplier: int = 0 starting_groove_multiplier: float + has_death_link: bool = False + has_sacrifice_summon: bool = True + player_stored_units_key: str = "" + ai_stored_units_key: str = "" + max_stored_units: int = 1000 faction_item_ids = { 'Starter': 0, 'Cherrystone': 52025, @@ -71,6 +105,31 @@ class WargrooveContext(CommonContext): 'Income Boost': 52023, 'Commander Defense Boost': 52024, } + unit_classes = { + "archer", + "ballista", + "balloon", + "dog", + "dragon", + "giant", + "harpoonship", + "harpy", + "knight", + "mage", + "merman", + "rifleman", + "soldier", + "spearman", + "thief", + "thief_with_gold", + "travelboat", + "trebuchet", + "turtle", + "villager", + "wagon", + "warship", + "witch", + } def __init__(self, server_address, password): super(WargrooveContext, self).__init__(server_address, password) @@ -78,31 +137,80 @@ def __init__(self, server_address, password): self.syncing = False self.awaiting_bridge = False # self.game_communication_path: files go in this path to pass data between us and the actual game + game_options = WargrooveWorld.settings + + # Validate the AppData directory with Wargroove save data. + # By default, Windows sets an environment variable we can leverage. + # However, other OSes don't usually have this value set, so we need to rely on a settings value instead. + appdata_wargroove = None if "appdata" in os.environ: - options = Utils.get_options() - root_directory = os.path.join(options["wargroove_options"]["root_directory"]) - data_directory = os.path.join("lib", "worlds", "wargroove", "data") - dev_data_directory = os.path.join("worlds", "wargroove", "data") - appdata_wargroove = os.path.expandvars(os.path.join("%APPDATA%", "Chucklefish", "Wargroove")) - if not os.path.isfile(os.path.join(root_directory, "win64_bin", "wargroove64.exe")): - print_error_and_close("WargrooveClient couldn't find wargroove64.exe. " - "Unable to infer required game_communication_path") - self.game_communication_path = os.path.join(root_directory, "AP") - if not os.path.exists(self.game_communication_path): - os.makedirs(self.game_communication_path) - self.remove_communication_files() - atexit.register(self.remove_communication_files) - if not os.path.isdir(appdata_wargroove): - print_error_and_close("WargrooveClient couldn't find Wargoove in appdata!" - "Boot Wargroove and then close it to attempt to fix this error") - if not os.path.isdir(data_directory): - data_directory = dev_data_directory - if not os.path.isdir(data_directory): - print_error_and_close("WargrooveClient couldn't find Wargoove mod and save files in install!") - shutil.copytree(data_directory, appdata_wargroove, dirs_exist_ok=True) + appdata_wargroove = os.environ['appdata'] else: - print_error_and_close("WargrooveClient couldn't detect system type. " - "Unable to infer required game_communication_path") + try: + appdata_wargroove = game_options.save_directory + except FileNotFoundError: + print_error_and_close("WargrooveClient couldn't detect a path to the AppData folder.\n" + "Unable to infer required game_communication_path.\n" + "Try setting the \"save_directory\" value in your local options file " + "to the AppData folder containing your Wargroove saves.") + appdata_wargroove = os.path.expandvars(os.path.join(appdata_wargroove, "Chucklefish", "Wargroove")) + if not os.path.isdir(appdata_wargroove): + print_error_and_close(f"WargrooveClient couldn't find Wargroove data in your AppData folder.\n" + f"Looked in \"{appdata_wargroove}\".\n" + f"If you haven't yet booted the game at least once, boot Wargroove " + f"and then close it to attempt to fix this error.\n" + f"If the AppData folder above seems wrong, try setting the " + f"\"save_directory\" value in your local options file " + f"to the AppData folder containing your Wargroove saves.") + + # Check for the Wargroove game executable path. + # This should always be set regardless of the OS. + root_directory = game_options["root_directory"] + if not os.path.isfile(os.path.join(root_directory, "win64_bin", "wargroove64.exe")): + print_error_and_close(f"WargrooveClient couldn't find wargroove64.exe in " + f"\"{root_directory}/win64_bin/\".\n" + f"Unable to infer required game_communication_path.\n" + f"Please verify the \"root_directory\" value in your local " + f"options file is set correctly.") + self.game_communication_path = os.path.join(root_directory, "AP") + if not os.path.exists(self.game_communication_path): + os.makedirs(self.game_communication_path) + self.remove_communication_files() + atexit.register(self.remove_communication_files) + if not os.path.isdir(appdata_wargroove): + print_error_and_close("WargrooveClient couldn't find Wargoove in appdata!" + "Boot Wargroove and then close it to attempt to fix this error") + mods_directory = os.path.join(appdata_wargroove, "mods", "ArchipelagoMod") + save_directory = os.path.join(appdata_wargroove, "save") + + # Wargroove doesn't always create the mods directory, so we have to do it + if not os.path.isdir(mods_directory): + os.makedirs(mods_directory) + resources = ["data/mods/ArchipelagoMod/maps.dat", + "data/mods/ArchipelagoMod/mod.dat", + "data/mods/ArchipelagoMod/modAssets.dat", + "data/save/campaign-c40a6e5b0cdf86ddac03b276691c483d.cmp", + "data/save/campaign-c40a6e5b0cdf86ddac03b276691c483d.cmp.bak"] + file_paths = [os.path.join(mods_directory, "maps.dat"), + os.path.join(mods_directory, "mod.dat"), + os.path.join(mods_directory, "modAssets.dat"), + os.path.join(save_directory, "campaign-c40a6e5b0cdf86ddac03b276691c483d.cmp"), + os.path.join(save_directory, "campaign-c40a6e5b0cdf86ddac03b276691c483d.cmp.bak")] + for resource, destination in zip(resources, file_paths): + file_data = pkgutil.get_data("worlds.wargroove", resource) + if file_data is None: + print_error_and_close("WargrooveClient couldn't find Wargoove mod and save files in install!") + with open(destination, 'wb') as f: + f.write(file_data) + + def on_deathlink(self, data: typing.Dict[str, typing.Any]) -> None: + with open(os.path.join(self.game_communication_path, "deathLinkReceive"), 'w+') as f: + text = data.get("cause", "") + if text: + f.write(f"DeathLink: {text}") + else: + f.write(f"DeathLink: Received from {data['source']}") + super(WargrooveContext, self).on_deathlink(data) async def server_auth(self, password_requested: bool = False): if password_requested and not self.password: @@ -138,20 +246,25 @@ def remove_communication_files(self): def on_package(self, cmd: str, args: dict): if cmd in {"Connected"}: + slot_data = args["slot_data"] + self.has_death_link = slot_data.get("death_link", False) filename = f"AP_settings.json" with open(os.path.join(self.game_communication_path, filename), 'w') as f: - slot_data = args["slot_data"] - json.dump(args["slot_data"], f) + json.dump(slot_data, f) self.can_choose_commander = slot_data["can_choose_commander"] print('can choose commander:', self.can_choose_commander) self.starting_groove_multiplier = slot_data["starting_groove_multiplier"] self.income_boost_multiplier = slot_data["income_boost"] self.commander_defense_boost_multiplier = slot_data["commander_defense_boost"] - f.close() for ss in self.checked_locations: filename = f"send{ss}" with open(os.path.join(self.game_communication_path, filename), 'w') as f: - f.close() + pass + + self.player_stored_units_key = f"wargroove_player_units_{self.team}" + self.ai_stored_units_key = f"wargroove_ai_units_{self.team}" + self.set_notify(self.player_stored_units_key, self.ai_stored_units_key) + self.update_commander_data() self.ui.update_tracker() @@ -161,7 +274,6 @@ def on_package(self, cmd: str, args: dict): filename = f"seed{i}" with open(os.path.join(self.game_communication_path, filename), 'w') as f: f.write(str(random.randint(0, 4294967295))) - f.close() if cmd in {"RoomInfo"}: self.seed_name = args["seed_name"] @@ -189,7 +301,6 @@ def on_package(self, cmd: str, args: dict): f.write(f"{item_count * self.commander_defense_boost_multiplier}") else: f.write(f"{item_count}") - f.close() print_filename = f"AP_{str(network_item.item)}.item.print" print_path = os.path.join(self.game_communication_path, print_filename) @@ -200,7 +311,6 @@ def on_package(self, cmd: str, args: dict): self.item_names.lookup_in_game(network_item.item) + " from " + self.player_names[network_item.player]) - f.close() self.update_commander_data() self.ui.update_tracker() @@ -209,7 +319,7 @@ def on_package(self, cmd: str, args: dict): for ss in self.checked_locations: filename = f"send{ss}" with open(os.path.join(self.game_communication_path, filename), 'w') as f: - f.close() + pass def run_gui(self): """Import kivy UI system and start running it as self.ui_task.""" @@ -385,7 +495,6 @@ def get_commanders(self) -> List[Tuple[CommanderData, bool]]: async def game_watcher(ctx: WargrooveContext): - from worlds.wargroove.Locations import location_table while not ctx.exit_event.is_set(): if ctx.syncing == True: sync_msg = [{'cmd': 'Sync'}] @@ -397,6 +506,12 @@ async def game_watcher(ctx: WargrooveContext): victory = False for root, dirs, files in os.walk(ctx.game_communication_path): for file in files: + if file == "deathLinkSend" and ctx.has_death_link: + with open(os.path.join(ctx.game_communication_path, file), 'r') as f: + failed_mission = f.read() + if ctx.slot is not None: + await ctx.send_death(f"{ctx.player_names[ctx.slot]} failed {failed_mission}") + os.remove(os.path.join(ctx.game_communication_path, file)) if file.find("send") > -1: st = file.split("send", -1)[1] sending = sending+[(int(st))] @@ -404,6 +519,40 @@ async def game_watcher(ctx: WargrooveContext): if file.find("victory") > -1: victory = True os.remove(os.path.join(ctx.game_communication_path, file)) + if file == "unitSacrifice" or file == "unitSacrificeAI": + if ctx.has_sacrifice_summon: + stored_units_key = ctx.player_stored_units_key + if file == "unitSacrificeAI": + stored_units_key = ctx.ai_stored_units_key + with open(os.path.join(ctx.game_communication_path, file), 'r') as f: + unit_class = f.read() + message = [{"cmd": 'Set', "key": stored_units_key, + "default": [], + "want_reply": True, + "operations": [{"operation": "add", "value": [unit_class[:64]]}]}] + await ctx.send_msgs(message) + os.remove(os.path.join(ctx.game_communication_path, file)) + if file == "unitSummonRequestAI" or file == "unitSummonRequest": + if ctx.has_sacrifice_summon: + stored_units_key = ctx.player_stored_units_key + if file == "unitSummonRequestAI": + stored_units_key = ctx.ai_stored_units_key + with open(os.path.join(ctx.game_communication_path, "unitSummonResponse"), 'w') as f: + if stored_units_key in ctx.stored_data: + stored_units = ctx.stored_data[stored_units_key] + if stored_units is None: + stored_units = [] + wg1_stored_units = [unit for unit in stored_units if unit in ctx.unit_classes] + if len(wg1_stored_units) != 0: + summoned_unit = random.choice(wg1_stored_units) + message = [{"cmd": 'Set', "key": stored_units_key, + "default": [], + "want_reply": True, + "operations": [{"operation": "remove", "value": summoned_unit[:64]}]}] + await ctx.send_msgs(message) + f.write(summoned_unit) + os.remove(os.path.join(ctx.game_communication_path, file)) + ctx.locations_checked = sending message = [{"cmd": 'LocationChecks', "locations": sending}] await ctx.send_msgs(message) @@ -418,8 +567,9 @@ def print_error_and_close(msg): Utils.messagebox("Error", msg, error=True) sys.exit(1) -if __name__ == '__main__': - async def main(args): +def launch(*launch_args: str): + async def main(): + args = parser.parse_args(launch_args) ctx = WargrooveContext(args.connect, args.password) ctx.server_task = asyncio.create_task(server_loop(ctx), name="server loop") if gui_enabled: @@ -439,7 +589,6 @@ async def main(args): parser = get_base_parser(description="Wargroove Client, for text interfacing.") - args, rest = parser.parse_known_args() colorama.just_fix_windows_console() - asyncio.run(main(args)) + asyncio.run(main()) colorama.deinit() diff --git a/worlds/wargroove/Options.py b/worlds/wargroove/Options.py index 1af077206556..a933cdb17b81 100644 --- a/worlds/wargroove/Options.py +++ b/worlds/wargroove/Options.py @@ -1,6 +1,6 @@ -import typing from dataclasses import dataclass -from Options import Choice, Option, Range, PerGameCommonOptions +from Options import Choice, Range, PerGameCommonOptions, StartInventoryPool, OptionDict, OptionGroup, \ + DeathLinkMixin class IncomeBoost(Range): @@ -31,8 +31,65 @@ class CommanderChoice(Choice): option_unlockable_factions = 1 option_random_starting_faction = 2 + +class PlayerSacrificeLimit(Range): + """How many times the player can sacrifice a unit at the Stronghold per level attempt. + Sacrificed units are stored in the multiworld for other players to summon.""" + display_name = "Player Sacrifice Limit" + range_start = 0 + range_end = 5 + default = 0 + + +class PlayerSummonLimit(Range): + """How many times the player can summon a unit at the Stronghold per level attempt. + Summoned units are from the multiworld which were sacrificed by other players.""" + display_name = "Player Summon Limit" + range_start = 0 + range_end = 5 + default = 0 + + +class AISacrificeLimit(Range): + """How many times the AI can sacrifice a unit at the Stronghold per level attempt. + Sacrificed units are stored in the multiworld for other AIs to summon.""" + display_name = "AI Sacrifice Limit" + range_start = 0 + range_end = 5 + default = 0 + + +class AISummonLimit(Range): + """How many times the AI can summon a unit at the Stronghold per level attempt. + Summoned units are from the multiworld which were sacrificed by other AIs. + AI summoning can be overwhelming, use /sacrifice_summon in the client if a level becomes impossible.""" + display_name = "AI Summon Limit" + range_start = 0 + range_end = 5 + default = 0 + + +wargroove_option_groups = [ + OptionGroup("General Options", [ + IncomeBoost, + CommanderDefenseBoost, + CommanderChoice + ]), + OptionGroup("Sacrifice and Summon Options", [ + PlayerSacrificeLimit, + PlayerSummonLimit, + AISacrificeLimit, + AISummonLimit, + ]), +] + @dataclass -class WargrooveOptions(PerGameCommonOptions): +class WargrooveOptions(DeathLinkMixin, PerGameCommonOptions): income_boost: IncomeBoost commander_defense_boost: CommanderDefenseBoost commander_choice: CommanderChoice + player_sacrifice_limit: PlayerSacrificeLimit + player_summon_limit: PlayerSummonLimit + ai_sacrifice_limit: AISacrificeLimit + ai_summon_limit: AISummonLimit + start_inventory_from_pool: StartInventoryPool diff --git a/worlds/wargroove/__init__.py b/worlds/wargroove/__init__.py index f204f468d1ab..e6bcc6288a4a 100644 --- a/worlds/wargroove/__init__.py +++ b/worlds/wargroove/__init__.py @@ -8,18 +8,42 @@ from .Regions import create_regions from .Rules import set_rules from worlds.AutoWorld import World, WebWorld -from .Options import WargrooveOptions +from .Options import WargrooveOptions, wargroove_option_groups +from worlds.LauncherComponents import Component, components, Type, launch as launch_component + + +def launch_client(*args: str): + from .Client import launch + launch_component(launch, name="WargrooveClient", args=args) + + +components.append(Component("Wargroove Client", game_name="Wargroove", func=launch_client, component_type=Type.CLIENT)) class WargrooveSettings(settings.Group): class RootDirectory(settings.UserFolderPath): """ - Locate the Wargroove root directory on your system. - This is used by the Wargroove client, so it knows where to send communication files to + Locates the Wargroove root directory on your system. + This is used by the Wargroove client, so it knows where to send communication files to. """ description = "Wargroove root directory" + class SaveDirectory(settings.UserFolderPath): + """ + Locates the Wargroove save file directory on your system. + This is used by the Wargroove client, so it knows where to send mod and save files to. + """ + description = "Wargroove save file/appdata directory" + + def browse(self, **kwargs): + from Utils import messagebox + messagebox("AppData folder not found", + "WargrooveClient couldn't detect a path to the AppData folder.\n" + "Please select the folder containing the \"/Chucklefish/Wargroove/\" directories.") + super().browse(**kwargs) + root_directory: RootDirectory = RootDirectory("C:/Program Files (x86)/Steam/steamapps/common/Wargroove") + save_directory: SaveDirectory = SaveDirectory("%APPDATA%") class WargrooveWeb(WebWorld): @@ -32,6 +56,8 @@ class WargrooveWeb(WebWorld): ["Fly Sniper"] )] + option_groups = wargroove_option_groups + class WargrooveWorld(World): """ @@ -55,6 +81,11 @@ def _get_slot_data(self): 'commander_defense_boost': self.options.commander_defense_boost.value, 'can_choose_commander': self.options.commander_choice.value != 0, 'commander_choice': self.options.commander_choice.value, + 'player_sacrifice_limit': self.options.player_sacrifice_limit.value, + 'player_summon_limit': self.options.player_summon_limit.value, + 'ai_sacrifice_limit': self.options.ai_sacrifice_limit.value, + 'ai_summon_limit': self.options.ai_summon_limit.value, + 'death_link': self.options.death_link.value, 'starting_groove_multiplier': 20 # Backwards compatibility in case this ever becomes an option } diff --git a/worlds/wargroove/data/mods/ArchipelagoMod/maps.dat b/worlds/wargroove/data/mods/ArchipelagoMod/maps.dat index a7ffb0733133a55cc128eaef62b7f70b23849699..fca94c194eaed831d7daafcb9a654136bd3110d1 100644 GIT binary patch delta 321539 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�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Ξ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
    K^L*`dw`Y%8+Wc|7M$BShcJP3@W9ulH?atO{w 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

    m!rr?h3(}kr3$c`1`8I1n3{={Hh6(VGe+O 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

    T-VUF4v6uc!5)1));jow{JbgdzcRX;6LYimK#^x zcLQ=_Bs4#Au|*#gI@Ml+hUAq%H?|%Z&1$30dfyIMm|M%!bc!MZc?K$7X&7HZ=dZUw zg>*U95~wu~V=n)#uf)mf$egJ8^#JgwV#N9u$TgaBf@mCS{@|GrJHs<<05U124X(5_*i+zJ z80Rb#wqoIhD$BAv)IC@CpvC}RgtP#Q`8h42n~Va(q{NdWda1_PE+{UJ4q#0*^wR!= zCVJ>ecjS^vvIfF4iz;*?Xy!$OX}r8g_xPo#K6jTTYu(*~28x2+d4MEX2~jR++bINv zW=Wr6L+;aYwYiyyhZbo2zYsIFxH_L61nXx&T2Q>T_=1jso12}bbw@MUp5Js5Z`kvk z3+b`jUio3XZTF_Q?P=5801JyVMn0%|%fvT+jhyFA;inhxp=IShTz<9JQuU;Pv5oqs zAcw$6>j`9@4>q_N$so5G>Xzgbz$gqTEF%WfFyMFbz?vUFpx6R{vbS4cV2qCQ%Uj0N`W zs%OHW>Uul|ago{Ek^{GqZ+u^gJaTEnL+v+=sm1V_iC?ikG8;?(ZKW>DYA8CLmc3t$ z=jpQc^=zjvy0$Pi6n0ZEhhnDr^!pdSv=cr`spTS@^zcsPbwm zazRO3JKY*g{u{V47tMG6!6;&{8B--5mYC>Xamr|!A%CrddVI>lFFm-WOUxvX%;4vM_vcx4MJe|xy1E;@#$ zn-L70+Xj>%!Eb}vPbxw%U7wvW zhTaaOO+&AK$LR7<9q!(DZ`5Nh-vavordn4}%p8pU>^)?V^yKSDQ&vQi4$Rm-k!V)4tc z$>A@*!-PhxeR_~ohXdiixpO747;f8luS47S5n}B+iEy4@x2)pEp~+#iA6k0B<6dM{ zW?y-bQ)JIFIwTM1N{jsk{hq1h6!foRV4|5WHoTqf?|=8~wku=_csjoI^vo42`~fm3 z;rFP_96+R~=D=Ft3RAVSR@>XFKLtV8-iQ*YR*Dszj~xZ;+WL(6s7+M=NRM~L5Ocsu@656*;GZH-VF0>SlZ3wrq_Hsi{CqtaQg?b-{b! z&DY-eVWNS=mJWD-S2g>E68}ZR0SN2RzS_ritg0Ik!Qwa5p5-fkY22bjI$p()f?QGh zf6J+$p%0qV+CkZ6LAAJ{fa1wwuN1yfZ95Gf<&8S6lc6h=;I{Yv-Z5ftuc1Vb@o0(m z88~T#{*72~@ip!^&I#T*((TQW;VcuULyM=&~O{08;+d-vmmj z6{p-l4lMZ+hM9H2nMh)q7i|1Tp84*>yf}DX8 z(!rDM^Vn|DTRhdBH91-A^~n88M+gZQ>*TAs zZ0xvcoH}!4Iod}6sk!~n7lSc&2kreNc7w?wtEqsX!pJfevLZ_T)8A09fZF_P5vKX@ z6dJQg1ez1dmgqT39C1$zORKuQ?JEcD7yYQhv#<4F|F^f6d3@G>p43S!S2ex87 z{_qLMpT_5$K1-RRYhX&{dIm03z^?ilVQe9{@M*j#io`pQ5O|vDw z>~h9Yqn11MIuqi>T8kpKZ1SJzX@euaCC@`hM`Qw~DN@0{T)nwV#2@4w^RN0V1+Q7t72n+{Kj>>ih5609XweHXZI`H@O((l()nnBSo0 za?(UMF9C>67;*mZ1T1&b*7Kj{$p$?E(`+77vUBjiCZ^urgafPsBC5=faray8k=&ohL9$D=K1e`O5OA~ zRdb0Zs>HyW7benAtquBet#PTDXPu?HAOyzyBGQEu*f3Ev=C0$DY_zL=cO6ERujy6< z#ylomnu0AO;fd)8a^jJpb9(1?(Jl3>7#~jCG~7cndQMZbY_Q1nC@qAmZ@_~z+>u!o zAic=Cx(_o{UszL%3U0$dxdKbxoGadq9+7V*h9cqUJ?#z7?Bc(%DOP@xOMt`-7gFd3 zKCx*0DBy9|P!~P-Guc$%Co}115*(||6@Z%GJSpwN_>tL_zoVJf-lQe*kGLN2@F?!c zkb;HL>w;BaO8DMY)uBPb&8Js)QdimmRMJh0ulrrY+#*PoN>xdRe0^=M6P&CeouGLBI}bUjkq_Q5sKek0~_O0pm7bT5_hGQs@fqfhxu&-b|C%>3q;xo4EE^9u-c7k2(sDgk38(I(vM zE*J74GQ6<_DgbeEhFt4$)E`gxs4*%~8)%CR7=*)AfHf!yC&(L0`L#0WdrAshp+qJQ zHMR_l4Y>TK;;=rv{C>cfQ>|9PsELH5?cH)kGVD5h?8#&qX()dRyShNis zOS)kS6)vS%z(D_)r$PBR3f2ghmyCK&aR*y~F;KE@y zuCpOHEIU@>M6SO4t0T$h>UP7wV3b3JAmliLE%~T?4?wa%8C+m@U7+}bt$P=Y!%RKj z0W|+`XYy1(VB{W1lfYdu@42E*tl(k(v62o+!WLnP>|yL~4*lJP;-7QXi9U<#Fm4fK z9-7RB3Lju7sK-Qz43I7ppoy(Ab-{wn`9gm88!zmiSTt6O1xv zkZE*m(X_H?$h&a^Yl(ZEAjhJKY1Tvp3m7`!!j+LyjvFuVIw$ZJyD~Sz<-0PwKpX6( zC1-&?yI4`+k(Kb}$L7xOf$45kWUA=7uZz!Mx$ud~bENAvPXFU+trhRkl7;7BHQ{Hq z8_*IAi{%HfC>j)uC4eBplBP`5Sx`-lS0x&9xk#Nfa|x*{wfLbpwR(=?mL33<(B`gc zbym}Al@9XdWD(!9Vp;yFBwj%kn^!a-ScdSlU8{bNR-&K$4~}z5F~6=$ch;1Az+kNh zC66_^VCC~hI}y(|p-0m1JI*(O9Uw7iN(Ri09NZo2;p0?)WT5tD&Z%0ts{9P9?`MX; zAq^fdeElugTxo$4lxKrg@CbOtV>;XnHqhk-VRT}mvm#MJ8DK-t-u&X{;?(&|h>ewOHsq>Xg(X;A)+u`82$nGxzq&AT!r6y6*Eek{`&7(Eqe z`faQENF%T7r~suHQhOs*1jDGAf!)69D~luxeY@mB`X0Sjef@qLYxI-ayqQXFwu-b;dn6v*Q?kZ1S za$uy02CA~qG+BNUn@(u2Co0*cF=ojxToWu)h#h{+Yx^Ma=EMpYA&f*F;~F~!6_`#9 zedNC4K(?HSaaw$r9QUoa z%GeEP1?6fI42HgGB${EG-diBNf91W-+D4oU0MYwj_T^wCSA<+JlHGrC;vG-KA_~Zc zlC!ubg)cS7c$O&B5<}NTc&scn73IMUIKiW4P(f1v@&iHSYSbo9q-NBn_ujPvx6rg& zAXBf#X$M~TX8S$}tD`C4PvfyEUuC4H7H?a`JuY-J%doYePs2&7F048L!BtrN_zJYg z-kJp{$w2Q%yh5iGeI5iGJEB*tkb~=exY+(f#LYvfDjVgRUJ81g+m4B;N4q$D`&lCq z6cHEXF*y+9gfmuUf{4(GweFQdpi8DfdhZDFCpq8z!8dSim%c6Zkg4XQB4JE+-!5fpTs&* z=<5#H5f1T~8H^2H9(<@4*B#oECDNfnick$jnGV*Voh|C$ADzaISGiU!e%xkS0H4CadA`7T zZor0MUlAP4E^jz<4Ha-FD~RpYL(!^xoyP;nMdEm#-u8SqtI{gbI>#jF|3Gl^q{3or z*`eJ35DgV4IrjbJxcWmtb?lU9Tw^(|ciTjdskJf4elyWfy})&jvRGvrL44p%Auq@r zp+{FsKCzKw$usXes15@tz=*kQqeGbgtugt^JA*H}=&yuCb+A*dOhawpr zYO_a9>Bv=roEl^FKQ~pnx@ZjIuVN0{9H7Q@S115(8q!cl7HcW3trnY#$L4X#w=q$kr&3*XhM7S z;t;~FQ&zOgV6pX9AZki1J1%3+pXeSiuyUdT@fThZe+S%bT&O^%Kl%63BbT61&0&>g z{rOo4JOb$%FF^PF2e`RzN+D~~$kzk(nC*UcF4-&|4GI1jTVo2d7?o-E{pa#4hEK81 z7CE|&P!Zk?Q<;@i?Ra}=?8}4;O|;e7Dw~`a(RS~^=}oGkAhj+*zf$l1Ze1OK@6cQD ziqG#u3Eh9gQnQ#?+Fud)53D`uo>JkeSz5g%Xy~3jmz9o)@x=@hh!FKAjP_A_mzl$d zEpjAkh9&{Nkk;fkdJ#R*44}(~S?{%LXZ^?Vy3aq4tM#n+F{IaKZXfSQ4y$tH#`X^P zo^9!jSJZ|biox;o(__0-W0U4U}m#em4Nozj3a@v{lhc80-BpAKq#Qsf*UcRKq`;3a+^{?9} zNOOzR^S_>RK157g!LJ=}mw!3~`ualLTySa_LlyGKc#Ee06q&U*^F-vgKRR%x45Mbn zKLB5l*m3I;J}}=+V+F2K}I%s5kB z!ZC^N)%HALo!>hg8QcA7WPo6mPhWK6Ir?`rnyNm;gw}`46osP|D@5;2w^|sTl>wgA z`glaUU|f%IJ|JeN1ck#pFZH=PpUL@=LJYp z7;8;D1f}fkra~Nv*+jPE$PVr+O2l>&^m}kP+s~amUvNkbn2BdxqT=<#q4vwX$a!w! zkB`p560EP78an*pBg2Gp0r{V0?GvNTjW6}O*xPQ=fL1gldGRUy<z8n8t@>mpnJ!9cTqN9laF4l{n^H?R$?(B_W+HXtsqa! z&-;IfAt8u}h$<)kA^$`-1zTP(0}w+n#g291rC5-A$@uqGk3yWmJJeZ<-iqJ6#Ew*V zho@|f^L}oJxur)Yn0(BXCQJ!SQaKnON;~}fMP7xBf9zsUUdqspF3ZSGxpLR|GYqS? zy!pW2@z@u4Hss@1XBiW+>;qt6LUyp|Yi^Htmy?M9@zvmAT08af2L)En0fFDL#VZsn z0`Yd^=FMJ?{`>%Sma)Up4o4--6+>E)9$_r<_6@&xEs+6pb$#B~+C1iB zLbOEjzZN+R>636q*nXaJ(%<;%tMkMlxl+6aDW-a5$<-}a7JdkHi{{G8b;M~qpJNby zfN3LUE)j3sYgcb(DvRADrYyoEqRkw53dtukx@dZl3vTG>R7vQ{HV-bmYIG=4HAwf_ z*9Q!xzw8k*cL;;m-C=?Dt5?n;<hQqFW*sJ){$x| z)gQs^Cx3#8_~wDXw^&^gET~aWrb$-23vs1D`&sPYa3O69-o9CjM?>WDti7~ zwlvWe7#A3n=4aBb)~gyiS`I$t2Zvd8H(Q~ir27Dcc2CAI ztSKNZo40lTR1}qU7 zLmI>+r2f6Im&<}Y+{BX|MJG7DN{^^<5zu*x<#~)sdES6!XJbQ&HfwwzTs!q!$TLfy zt8t+$Bf;1R(O|lb;li+9Y2@V$)znN$OIr@_)^U)wm-#T~)3@TVB&l7ekk%Z9&&hj~bmD}*nBDQ>8v2j#rQEg)HH=6o+FwM! zGHTaS4(!9XaQq|=kFRkEC&7a;YPz=Fns+YgUlrP!_^;iMSmNaXAdp-lGjrc$1LDGaBuOn|NU3Z0zA zGMjfs-%E}@f(gx|Gw%L28;Vrh9X0S6)iS>XwO{C_N`X6MYqWkaObUWg3*z~N=tMNd zCBmG}H`vH5P1iK5sGd5qL^<3?Z`h8Hkm()0o1#}W%VQMLMIGzWt#2qT`Jx2cw;G`Z zWvB@E9tVHqVn*$zGTZmU1_Gk=2DZ8BucZtg#cw=4uP&DqNCdsyv9}}=A|xKJ*suRR z^rl0T$}g7iEsQ!4N71^`Af(|EG*V!fW;SSHM$L!5|l>Pp~49Fi*zQ^+0C$q zRPH>8^ZNQ%u*EXU60v&`x_zwG6^L(N;OJ4Qjfv`zRgOPTWe#rF2b7qCu%6R|;6{vb zX0E;m80YwEF6i(LCwB}gQN}pZ{4hHQJ;?u+w8&bLU^9@w`vg>Fl>!TV5H5 zmqlQqs)%+(^@3>`FJgQLhLB}J-YewhoPo0!Zs7r*>BWb0<#$a1sTJ2BC4S_~C?-9W z7oD?h(O83fJI_Tk+)Q02}gZLxyM84HQcq*cl8}FLlAn zPu@M0q7a`;O$vdhbr;V$EQt~8Z-WVYQ@ae>NSuICvD$b2E5}x~X{AUVeASbWWkfF+ zog`kNb19$irUGW#^(Gx&*a&r~kB`_2-eXURqh8-JbH1$k{m~Re(fC*@1GM8dh<-nC@Ui>c{-l4sKA2|1v5O3?)$@7Qb3wIR>)Ka(CREkYB8+qBk~V^# zJdM}9g=P2SRv)7f^HOY)O06a~djEn~1TsIxYw5#&*k1Rr`p8z>OSw>aEBf&Soo>z< z-|%HI-M8}CK*I^LFsr;Edwb7G$+KvQ&b1aP0R;TY$o<9c_YmvQVBw;M;0z5rzmgz5 zZ!#SH#J4%P>deoN-{>XssL$jY;xb&gNT|zE@c-y|F4t67jKZT7_zvwZZJa$ilJU*PkDD6no8`#e zjZ=du&zpB5kIwq=PrBcuzhHDEi-IS#snZ^qGFngyX=q;5QEvt)z;uFw@yCX+*BSc< zKPovoB112AQ(H>Ftu&U77q^Mp9!0-&poVc;jtW$c1Eyk3-QOcl(G^Zj6zG$6x?fU? zc-+&-;R8F|cR#o3>1Hx8abNH)G3s`_rfHXx9t~TPcYABJvtfSuPG6rLz_Q8Xig%|I zw1Og`x1FL;4Ile{3OQxF8lC{gHRYumo)?bX_1g8nihZU8j6jZ*3&!{2|I1bKx`xGs zfe}cF{0p^^h&@wxIQ!rqIE<}ci$foaTArSjo*DhKjb?$reHFsfOS6SQQ|0v@3rElQ zgImAa)-d_}>3MqPap}pQGEbd3_I9eM;l=N7Cky49&ugDMB#>6{v)gx^Q zVg%Lnw6U{cucVG>clWu~lI*G?6nc1y9Z=@lU}Wygfc*jC+o7zwoZzcQP$fvMECzEh ziyvyrRzXG>CU=yp;9ZEZM{&<=ce>wLBehw99-)B&A{nn!oW@d)Jf}yJtna73$uc(>rF=5OBIhYpovK`v zFI8PefcAbFYQI+njttD*XMklG44EAyn=o6Mxgq&n!u!#jR~FUkcArSRpug^+2Jo>( zS`1GrE-`wjZG<-pslychSqkhCA}49Z z)r8QV^#-wgPli%`kRTv zQmFs27r2X~g^GXM@JE|GB|?+ExR!J$B^l~7^=p1(oM-lgrv4`C2mud-rGWbQY^54@h^y^5GS^D|x~%mFC+(fgNezQwceMmRaB5Yhn6ebY3@fR>^gsgQq{ z*VIpCf&H`}ee2=#Xw}*A>RS2J;+;)SSV7;}Qn*egpT+O0YR?7d!05pf8O9Ln(q?I4 z;=bxxR?i4^VQPp{{J{nQO`L=DouCEH5sABm_kd>^B#NbT?+1s-M86~tgvbT5N+U(~ z8^D@`V$6v+bwSFziAoHP?5$aO?-3YSol{{Vs;wqKnH)?0Gg3}a*SB%s&Vv8m;9T;Z z(QrzJzVWMe!H+rJvG1b@pDMMh=d`aYFOvh`pH-@7F5?pv#jt>w4W-ZGbqBq8+YQ)I2>xG&J<5UFoll zqT)}_3C@9SmUuAO!q0$Lgv_pKlfmIII^9ll*B9zjDtXY9b3;IO$nqq@7`*W~kM8Ik zodX^Bq0Q$uipVFtkxi`vP*>w|bRp>NpEk3dkP+1cNI1&nxh=iR7K5I)7Me1Mz*Nif zWC;@Zn9FUp{l+x*iu-nd-+jE_cnNf2!v{pb0WhDfLx=++qAjwhE!g0ZVv0 zTcq{pbr&Np3OYAnK@xQW4T$qhVDC(|qJQg#R>7w(x_+#HLXXH3Y7}F6xqbxjuIhpi zN@25w1Hug%ldVNA3O5>cl+Zq7_FfNw1in~DEO6gb_h&n)d)L_iCLGiBR*(zrZfw#= z18VMlO)9(6QJ?7rpwUW>S*`L(`QHNmlTRccwQc8;3PUdj-B$**WWZ1rVz3pjdIl^K z2wlL|xBIB7YOIh0O;`5Z{6i5sPf9A4Pw3C-&nIac2h% zyK$uZ@zGnab1>1UYWD9PA&L?pNbYIzmd`W+X#7WR&dg68`G-i{8Ds3*Cd7ECGI5JjnXxCcN-8V!UMGJEGD zx#yf}I$?oUhHRX`ywAugD}gkB7n>kZOkFTz<$_^nU^BI3WmDq*=~o1--lWa&EQ>PV z2UD`ib9KVq&bPFE^qU?1Ar9WBT;1Ql7Ncg;6^9W1Zpoaw?(dvSGG8Qf(h@tJu{4$j z_H+8+eRMz-$4vj*$UhqiT||t6Jm&@A5W;x_gguDpUR@;$uLYB} ziEyakA&X-S9+>wTECWp@#k0i7CoGKK?w;&Bg4N$2-{x70$Awz1wx@uqRgqS>CJY>G zVLKKK(m9KzROQGzTPPv}xwWrn94(l&H2v$+ZCzw9=I);phDxl0I29nGxb zlf5auEHKR3rWntFv&IpP@f5)MEN<=otx~G>z)x^n^LkdDib@?m*#H|=2qr&ws@S7Jle(N}U z_4hhC+HAAlrl6y1^5YJ($SL!(Nq=En076o4oH!%$dSLp9PRN)?OMfCX;E#{2Vz#YK zlUUwfCV>|&J4mW<;^UNLa=GNyb9gvhXg6*ua>S~|WFW;Ay@KMIjQ3SWAI81^SOiR! z>J1tECYx}mF)A+{SjaW<=>w{`ncVisUsuYJa+-J^X7lp0%0@&Q!JSA(g|4EnK+75H zel;9=UTT%KebukdYY5Zo9Il$KV)~P&MZy`=_4xlX8>r&c5sxE018w(8jR09x#L-V86?Wy zc!j^^3tW!tOi2iPk1X=x>`jT`3~(M_^nSZ*6b|Us2AsTK0KBmmnP(ry;DP6oo1FW8 zv+G!t<1De=kvSTLl|cEU2W;;fb6E-Ky+G8_&obvB2a=c_N~Yu`o{?yQte0@dTWa}0 z&*Dg6IBoe$)Mz6aznuJ$g-`g<_D^9uey7bS$1m;({_w|m2kuG2Jja>fZBnC$i zDw)B!A!ua!Djo{cD{&D}83LUw>AZ@RL^owJL5vE4MkUomSMFX7*I(7;CsjKTW9cK7 z%k-ErdzK5jVo`T4pY}p$%**8cWq2lW47_AMXwFc@#6*|9qh{|3IAJx&XRDnba&h;i zx?+$InvtHL3rPuKYDr|!w4a>il&~Q1WqeuVvBgGn6b5=WckG$|XegEo z^E}!`xZ%s|Fs_Sf)tc8)+G+JO)5Si^-W2j{T~z$mE=%w;)t{ZjsfO3pX;Eron@A++k_OhcqoM zaEvO+Jal5XWZ9(e`MaqEjt#kRQj+B`>L0cD0**c2oypGYmj+ol7aY5V1s65`Y;B+mYk4}Wi282?~7`5DeB_V`f3)iMs8 zxO@L&99p#@0unzsi8t0NI+3!~RQ*QeQErK;Yj)!qCHNo-L}=h|O|Zixn~0}P6?&92 z$Qfl4KlO>mlsSS1{EJU^UrAqF^4#|i&NIX%s$j`|5C}Sljo-LRPbis6k|!`wlWRN% z3Dr%_9ebQt%xA;c1B2BYWmA41ldSP_9%BTzk8>ze0GMCzu7jRp2XRg@LmFhkiwxMh z?4e#$sZygbYI;rJZ861nRbBVlnTu`=n@rP^)+%oZSrD^UFD0Op+SP$q@8tXD;8EAP z&-sX@mSm0|yEW>{rN^bFH{&UF;PzQO0WbNaZkeNez8ZK&X!wl~^>AYQh8sPj50G%E z9k(C{YKVs({i(B+Naol-%muM#8sDn5SH?@JxF(P9eLlfAWn4k8d$LNR9#Q1(+HI-5 z*IB2?a+@KP*8~JIGfFIphGouuTeqb1I-TnEKk`ILrmOo;kDZ72I+=SQ za_2BzyO~pzPQVaCIl%h5-+UYO*)wyRK5WuKccWE%6I^wXOmmCqdgYL`@ymlG?uIQM zlXftUV3(ekmo=IIRhyNgW0=J_H8}osSuUt6$WIX%A?C&lWNzK{RIbfHAr?7|9#2_~ z{pxFJk*borrjJHWHg^7f4U>jU?H~t|Ac!tf((U9pPoE=9MC7{%ip+I7vHGdEAnG@B zv&;k%k9YdD6|lj~l2w=8-CkO>q=>I4m9hm7M+0=fv4cDDEbR4k#D+ByH9<6zKkMW^ zyY(PVhsTk?=0P76BKla=%Mm$HUEw|!4!kmhJNryms|t}sSUT~#3z5WF>7#Y-q+Y1# zCA%|Fys<_!PGsI${Ep_8-C8{HC5QgsY3+)4x?~REAbmN}4gr*M@8ymWBe4EG^$>q7 z2c{8c@EzQHV+}l+$e%RnMP6_5N+28Tf{3^#FH#s3O(G^#1S6kt^(14k^;b~h1`rCI z@Jz}@<6MSKPK%lMZZyTByKsW0zX_}$_SubpE9u_LX$cM$@G-Le5|2u$#d-r^dHnW! z?0(ZunLA~T5H10Tf=V7j?Lm{zusSXI<0tLoRXdp;Jj`Cds!pC9D`R=7`O@u&rsx7ru?xAz#@q8+gD27fg4 z=KQQso6A;zs|bCq@!wL&9zOn24%tgJHmVs{A2b$T&E*yCd)7Azr7-~R31+x;hHeNc+> zKWB`xV;*g30${#Q}%dofTR6burA__rYHtB9~aPWVR ztZj94`3Z^PiO{>g9`@Ak)@iPA$ ziRMM4Bn*cqV$dLN!saAa;Q4t@IV^UNNh--RA>SzB`&h_-QF8}i^V;`>LeS>&yF)?~ zq3I`^lC;q}2Ot98_Z78d1f+_|2)WHWNSm7E4Co?HNRRX2F6~+XI=4Gg;ARNzb3}uW zSw9>kc((}57=cWBeJXKtGZ&P#Kyp_tl2x#ue-XT=d)uu3M>XqIDPkw}C!AoH^Bvmm z7o#v}xGJ1zdf%&!Sg=G=nT6%{-XtQEsvq7DbnoB%F`&^$Ov*%?Gx{;utfD^*J+enq z9{v~NFJQP|oWS?-h0FJ6Z@evwxuj)p&ugT6H=Z|uS6vK84zJeEatw(hQYUUVzj5eq zlvyL8e(hb$iEB8M)SpF8#Lgg@&Fnp1SCw4M*@(4jA6>*Hx*NQ~ADqDsjYT~ycS*@0 zHrW{B_gpj0qSJl`5c20!ETM0qSTB&bs_%MModrWIRlw+z^d=0n>$P+N!-m8ze}=6~ zPiD5^j3q(evvwpfFeXPtFucVMs$u4H&**Nt80kwItlhr}BZ&)n^GnZJw9kY8<%0tE z`fCsEHW_)1z1fRlPh&eDIw87Koc9=>95COb$t5TKtU|5Df{sfM1X$?*Es*Ztcs3Y@ z8pHR71H^gp(AcDhU`6hUNd2YE5qI>xG{pjkiK@~hl!|By!%_l@68!27s1YoJYP$?|?2{8#`# z5O7<9P+8GK<)#n61H2U%-T$c0V-@Rp-N}XM#{8M;IY(3Fh1(1xEtr|c?<4=5Xy7@1 zAYwW5ETbBH5g?UZrW~_fui3R8uX72UZT+9Nt}-aDt=ZzPfxzIdK?WE!NCLs#0}Spi zg9IJiCD`B++yVqoE(|ib2MECe!QCZT;LZK+-}iH$+NbKA)vH(6uHM~^ckt{dDgi{x zppEorY$3zuK(u&h0NE>?E<DGDoaWRHbZ9 zJ<5&jb<9D)+m3fs6~l`^a_j>{l&sBJKk8MuUX1ceD*@ zFRreJyaFPs|FA7rZ-iRbSP#`Fjna&SX>tP@x!p_Oj6fsGG3k(AazbBYUFP`%8L0M9 zkXpDBjN{0wwyEQ!%xyNtvq^P8oe_l>ZnPtswbpzhpZw)Y~ zBTx6|SSdqj(LNDoq<7vr8QS^3?eeXQN@*3FCN_9R4DPg(gp^Besk$d%>5iAsg@s*^ z@$XV&$)MT6rg%`uQP8F6fqI_1|J`osAUK`$$pvy!V{;O1bMkG&XfFG8>bQV$G7UsM ztN)L~%fKJm=13DsQbElS5h?%-qu*WRQl96Qj7#H8IuH0GTKg3=Fv}q}X;@Zg z(Xk=0w4)6lucFhLxszKd;`4yV>UhEmLUI)C#d2)4xmLfL{pwBEmmIQ%l2w7Xw+HJw zbVKO3H|m+k^pMRHW@jr>oK5a{hCZlUZVxtLmixy;;Gz}ak006_O%od6+h zBE5dYL2ttdRs_Lq?xEUd-E`)YwIkiN8L^@@xseM9R^ZZ9*wur6D8;mP1ASt0y2{VE z)D|Bqja5@z+~2zt@3rr^os69^w^Hfz28lCBRTGg`uI&VNnkvVSQp*^#u^F*r>{5o` z@B7J1z=xHLpHPZ6s$81-VEhJ{abFe67R3q^hPVP8eA6_WMr=00+(lw{;WJA50VM2; z0u-7hSBtx~lDtrWushyWw^>}Fe`t!bj@h1x4=tO1H>dgRNa3qt{2-l#t>Zz@dYy}H zyyq&fEtY^^(gkYl3_&ECrNpO$ejCc(S$})|PF7@sJ%}|=;^qoc!_|~zM?^B*np2_=sj$mG!GR2Y0y-omSElA2eUrpYiU@z;81mh)|Cb9zxDF%bM?%Et! zd}PGC?OIX@j@C~5o?_EAOHUx|+!11_k@?D9L&Jl7YCw5Mf3hiZ>2wLN-6kh}v5u(Z zXO=lBhCVc?mbply&MKExN$3=-Lwy3#k+(4$E1_h1B3|+{ur)gI@cM|Oby>hCF0o%W zlKe%Jb5+68!_zpn?ksKdY?%?aVM?OYfOWo1y^@=>C%~Wwr*@8WL}apFeSuBf(q;X# z&nR=c7JoX`8&e~1y=v!#RKxoKi~CWxiS7(#b`Vr5n6moX8__#fTdY4SyOBom;_;4T z?(**jQ~@U1%H()T?H1edCuq zs3$C@)!sH=$xZ<_E&W`v;gDY~)-Pn+4UHDftXaPkUXOkpS3G=tU#<9Rq0?rkJ$6*R z00E8pfhy=zjIE^7Sv(-Mdey&NSxLh<)E7^p5bG-PtDojVh~YCtyqX;*miA4^Bx2)K zrb@fqSy))4>d#Y6v9X}q-zW9{sgj!zRujigX|RQ$9(~(Ub-IZgGtpg63hcfyDo3m2 z@{<-l{rmQ**v#?q>{|HRhcrjB;U|tc_TSK7_-OOC3Yk;o@*KS1z8h$XU)Cw=zjF9G zs(XIEP6b8BH8bk&aswPl=*FH3#lgo5FKDXj)4gh(7OlV=82ruPQrmcT%Dj4NbwRHH z+s{pr1im>=q5Yf3S@n1?ou!X-w{Ja^(rztc%ze%PnmmK9-4o{dqW(41yV`1^PC8IT zA=qvp4u$!JSt0*VolL{MuJ*3zrHkEVvrgXeOU@7jM%;H0h$p~x@@lhnRZ?_~-Pdi* zt?SbQ>@R(K)Ac=u&8G9U?LPv~m0<;f;7(&;S$xHhWiSL0vV>?tKC5Gvgf0$n>P;9T4R@T74Z` zUN~}>Eiq071I2xPDCWB{3QvGN056R;eil=6l+NrNxbmu#_n+p(l628k@bn?lZ7kJ1DjvaV?>P?dhrs1P&B+^o7jru}%lSS}dXi&*$#2g&WL7(Mecw7Yo7?13`i)wDD8ZP;qyN}9Fj_eSE;}#rDJbS?19% zj!4?Zsk|e|ur$}iWkAv2GiditAN|9MZIR^Hk{=hN1v{f55TB6tySHwCZZVDZl?_&y zJemhSj2LrZX?uWyH^%~uYH}0D?G45;@G#HcU!APFok--&G`n+`or~0ClHmtZ;ibXI z0nwX$khZ7V68|GsC zC)w&TC$9t)j{0H|Bz8UH-$~_sYFCA_7AY}+VgY_CKdYiLkB4>x0mxz8JU|fTB$vSZ zng}5mixo#{YJygh;sKno);6~MI1PLP93c-|hfv*#o~*Y33{Dna4`iAsjb(30@>o~6c-i=m1Ya9JEVcYluFCd_8EQu*waaG}o0s7LP*jU`!l=yoit zNeuAsxvnCA$|j3Qu>6whkxSDvfW>*X2P4^YbjALDe5f^RcqL-<0-)_Ymfdd-#UFEC zuk)g*>6d`ZGErdD6lb9>V7|09%NI;5wX>+C4fQ0f6IZP47dyU6!|96>5&#P!i`+!v zS7~ZExCJ=C4O#^%YZN42#S=aj7|r6?1UUcZc&X4>_o>(;CEkdT1=HWEhE!1M;$s?+?Q4_LjWS zWpK5!EQSGCqk*U?Xy5kHQ?(O^Uu&u3^bsg2;P%EDqfZOs2sKVv(mr5iJuP6eKz-}V zW71Psq633z*g<u5xzO;Ucx*uA0d&J&606##-n;bJk`uwUwVhriP$ zt~iB%2IfP`U0-iz$Z(lMbs9oo%E7Jf&=Y>!Ok zjqdmSFiiANAkY6Cd=aK$PRF_$9xuc6l#BRaz$_6A95kfvdoPTofK3OD%?N67c!uLD z#8h^Lhmu<6Bc^GwTv?92-VLh&K|jO3|3t{(2w7;miVDZP+_kyxaH_{dyhrBQkxr8q zi}KR~F!YszfMw#>m!VJ~dLfg9L6=l6L~6l08;02EnIQ5TWt%S|o)dx!vCQ_x5Z5;Q7c)anZ}3lX~e&pQVHtEY4Y zCKe6dI!&UY_Yr_!ob&$meV2rTpABFmm3=%eN4V*iTZ|wRtKO2qiy*>iV;|36;0zo+ z+Tror?O`4C8J)-dO(C+c4DUU~EFF+>JhgyVqI01m8%nP}DLm=pr3<9buA?r^J_$v& zG|p5>bQa?cr{bzYN0&=(tp1_2A!i$!upvsdW|NpxRFmbz6dM#m(4~cL&a)1 zo`#b`8;%PKZ8^u{BqSzRctMPH{C4BAPmJ-H9o7WRYld94&STpv^)LC}`uns+X zkRZdH{hFtfdUXUQ%lkuqpf~IN=Vt8HR%Z`VO^d)u93-3aSo+t@B({Jv;01!Pw|zKN z{jp_?5ViQJw?Cld+bYLrh_ zN^k<$<0R@^XRsgwYUQF)R7e%BjR`8r3;wOx0mv-Qg)Q8=1AW^RWsOM`<_?Cn6toZB zAVmW;0!WlYa}mQC0Bu!oV~aQ0EStz4OeomLa@hv!1T5rKFTGv^nV~#{mfum#C&Wpr z!ju6Djt-)6NS?0Om0r=-VMycU9dfZMR23%^l*rOSeA)P5C4IF_z&*klhpb5j*n35 z+d&hgVhJ&xcdzk%Nk!5j(bWxH>G?DuIw{5YXKq01&U9qQ6FbvLhZ>tJBbkI z_wGr(I|`{x(X5@NS|8P0-^9QtGCdPK=9_h?mlNb#2|dyqr!Kws-~&9%NeB2yrv;n} zh&f_Mf9qw$`jUlQf52lq2J}Kzep}*yrTe55<5n8H*`63AT-nrlTLfRz#p)=VCPE5} zIFdT3LXi^F@(?;-ntk+F1Q*|#J%JNGM;4JSgh&lBkV5LYzI2eQTTm{`zgkn82(j#X z$uc>x@p&@=^2H|hZ1rF)(%qE^8S+DF#WMs~PMl6eCO=!A6z@R$mcXH-6{$PGn$q=J zHMr-=8>(W9H)3sog9vTPM4YbHP5*}fnHog-<2mP(TzfB$fx2Nkmx^?|J^Oop`O9QM z-$)H*91W6ounz{YQvf@|;0<#-r!cly1`&qoTY$#m>md()lKG7w0UX@@K&uWr5u~l= z`g%O3r6V1oq^EQ$a-se;TclvH;>X147GMX3f|74yQ1rOGpL4M+v8M^Ggf)(N{YR5B z{sDk9A9${h(~v|^shTNV5f#1~KQJKxqJ*uD@xH0(FJ?jNOjvR-fQkmGv9v_Ehv_N= zfY!#zc`q74-Q+_XkQR)lQuiip8|W0fxd8yILYK6S4JuLo{j|^TMPgEs9e$K7H^DvR zO9G~mJ_L2-5^p%;f2S%DXvBT`yLvdkSI$Hb=*d}aRpx~wbY_INi6IUz4PS|F5*H-E ziWF~}A;G%Fhw3>X!xQ~B(<>fV1Y_rW?7&0<()y)&fjlBQgh{XxWWlSf!SVPNIvPFn zB|&E0KQI4$M&mgU@A*pJ*HYZzMRO2L5VNU)!AcOJa%6VQ!=6Wj@?X%%bR#%^y+!wL z2scupRc(txs$n!xlCX4!m%@PwJ93df*r&WOS;d#tvgBNbI1QFywdx@2_Sg_!mf&A7 z6Yd5M$_!=)@z&ZDW)2M6J}pDB?ESsqo?-mgk`E!q;j`Pe0TCR18Nhp zv+Ix6Y-RnX7EAMzpP`V(fbP^qiDsrzE77W-d5#>s%}sc`G9J?7w3TC9yPhUkdnd`o zj`HMm+mb)Wyb-$xA)E|cwJ1udy<*PO-f7!z_KF%1{hbzty#wo3KERj0<)G!u2|hb3 z9U_+bfULkcpG`?-2!`I??$2&2O5k=FW$?$>iP=xDSL}Yv`GpZcs&gXxf^G4#Msn;T z^G^Z0zfPIA@B_^lyrejt-@%x-=}sjokg&hAq%z?ueDYKEV)(_#>C{|RCw%wODIk-) zsbk!I$8#zr(y?%2Odq@+eBx%$#Sh`~q=ay*3)tPj{lu(?F^zEEuMSU!5jM3gVIMKU(|M9qLtDdrHLSRS_rfR$<-)K`s5tvm!t?8)PZACDpxy94W zz)<#3(vw5qARa34lj|RiT9-ix4}5mS*6y^-->9wW00WDSgi_B2-9(b!B(JWtZ+wkrp&y<4?9m?|~zW;&yXkGSmeBpPS zdX=ddO-dga9u4Pc`ju>QxL0RjL9jHhs+~5aViBu+S_1U#7yxolsJ^?%HegJ@)_k8( zc6(DRuRjM)W>8M+ZkvP1JDxkjrW#zGs~^PWG;19<-wM-Ufj6w($+2Y5>;Gf0)CBky%oHhE_m6%^R{i*&!h%Ghzq zym;!gP=R(A|EPRv+f2Ui#YibNV$N!Kt=z>K|H@VqW+hzbwLiTwVc5^U+htXTW2K*? zwk0inQCH{CwX;dLJ@M&eOM`A{Dy}UAA=`_CTe34e3P*XCXp!GvId17Oo^^hcyM$oS) zoodps#~iJoYiU*AOwVi5^-A}Phb&BGGq%~N z4IEzn<3O|Q<+s?Y(Nio6IK`IHYWhpkdQYbCU^oOn+57(C`@{2`5+P`|@mz#7@Vl5M z)PT=89Lo$W1frKda^`3-Aboh`TZ+Cr3oG~TBU87QWaeu)C7l``|6suCnUj=|TbK{~ ztcT&0x94tFYMxd4jqzdJ`E0}7d@@ZBQaHb0+58a|JU`~lo;1*oz-;$%BkA6{UrSQL zJr!*r=X3NOaOuh~9Cy^PxBX$2o=c4jJvE!>V)V4CsstezeNldiNC>~hN6=L`bGAgS z-TZ*uvG}^HT31NH`@bgz>k(|?NOL=}| z>+;_asnA;L3M=tEHKmZa%MDSOGo-IDJfO~+qD;$BFH=FB=4T2soKY|8jXyd;+r02Q zK6)-F7223*<3?D?rNX^A-4upU0d ztT_qQXudn>?-M_=HQ-NsJS>B5Or74L#D0-YGpd#EJjGNVlsm+Ks+q&h4VuS#fT6AC z?d0F+g%ph%3({qs!xB}?g?#u&It$L;CfIzDcF&`e@whV$LQdu2W^BM@s>bS;59Z?-0Ly{ zQL(FNa521M)g9M9ZhxU)Jg0F#MEy-UV0m9Q_jK|Lm+~}garJ__BsRC`A-c<8sAID_ z4#!W>HOZZ?`_HXfMGKp*fjR`mT|ldX?7ZpQg7@_ft?Dkv&;vF@U0`1Jsof>tQA2H0 zXIW5>jK#sP;N*Ig}!pHT-hVhH}LP5kVLD$@RU4^st| z3@9uD6c7;wiir!02?~jbi;D?ng}I?orkm$tWv#rz$RPiJcA#XDCZLhEySt)|p=Q;& Nq0zU8@?reK|3AKIShfHF diff --git a/worlds/wargroove/data/mods/ArchipelagoMod/mod.dat b/worlds/wargroove/data/mods/ArchipelagoMod/mod.dat index 22464857e0da7e4892304c934203d3a3f729cf9c..6a12724d9acc3dbeedfa137f9a6940ba30bddc6c 100644 GIT binary patch delta 489 zcmVO;6iE5KSD)M`-vc74$%* z?H>RoL_m&QP%o9LmU}euPVH6KyVmYH5&iX@u_h2gt6=HL^7_rZnR&BWr_<>Xx`Zu4 z<#o*Do6q+M+XQG*=>wnk3HSC<{dA_r@Q%LT6ZQ!jV;)SMjCV|&FwqBp)kIValS&04 zFDb@C;V+6pfzv9LxO%K|sA@2U`@*#x6FC1bWAUjd#yR2cIqI9&msIy%jF{quhIC5* zcL}FbJjWW%kq56LGvP991NTdk`vSU zT!CBCXkQB7m7fofb*nO9i)d@6v&L9$T(K`R>kFCRrP1h{v`J%J@K%ij(HIDMhtQ6C zgTT>$1o*NC+x-bl@+F#_}y delta 490 zcmVO;6iE5KSD)M`$RNiuORI z?H_PM1Or}tO*UFRj~AAdHrVI%)HsG)9LgGUBVWj z@;YYn&F6cBZ2~l@^np+Ngd6*)?wzSIyrHkRgnfd>mq(? zuD~s6v@eD4%Fl<#x>XslMYJ{3S!1j=uGp8E^@Ysu(rENe+N3dEc&)~PXbgnBLug06 zLE!K|0(@B_!c+bu$$z-AhsiH6Y!WzrZ3iDjVM$(IX`UXL8EH|!LoB;uT?O^U@M<)? g7=0U#Cs*UkucOIie7Ph3XJTk3=t?<%0N>fov#uuc!2kdN diff --git a/worlds/wargroove/data/mods/ArchipelagoMod/modAssets.dat b/worlds/wargroove/data/mods/ArchipelagoMod/modAssets.dat index 54026ab2c2dd7ed3f6ed0bb5da5ba1889d1e8385..a51c17e954fd2622701520f283a919b375f3aae7 100644 GIT binary patch delta 10313 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 AKmY&$ delta 1880 zcmV-e2dDVEkOcOm1CStp1p)v700000_5=U`00000c$|%rO>fjN5I{>MR6rmBCqzY$ zKoPM1ievi*m!3d~KM;8nlNz#dWP2CEuVC(+gNi>p^ym=l^=Je#|dOSq4)vIsc zzg~TW#Y1?e9Aibe5D7XT0NdJVbz}dUYNg9)T^kbr2tIQnrNRV%?v!vblTf<0vj62^ z!3a_q5qWHr%5*N+I2MH^V^VR<6900BH#^hD$xjgCREb>n{M#A6_Rj505lsUd`Bqbt!=&CXu3?)04fX{tT|22!=DNa>4p0JspVXZCx8bmCdk} zOktXlL_Hs217GLOYq6J1m zK?+awDZ~SaONd%;OxNf?Q>o+MFN#mTytbWbbnU*l>OR2G0>p1Pj61av6M|Jv7s+2A%KPa&VwM>LGhbqUb7+q4xA8~Rgu_7RIA5Z^*jM)>HfN*^ z<%*z1KkyYS1I$HRhm~nRTz$SPOhcOy!eJzkTvX&g#U@)yvpWK!2eV@etp$H^0RR91 z0001ZoJEk`3c@f9h4<$sA~F;&y!YBYgm|luP-+dMFx%3#;^UjtY#V%poaCHsDY7gp zksMheAMnqyV1Wh=QXyJdL)saMx}$dNqR~M}6|^;i6rrS1FkGDJDPx0B)vug856VaK zI8xS}ZR8uMKc;MvQqzYB-Y-qrPB;&@FQ^!jh3vscsIj)ZF)FWJxN~Sb{Z+TTykUJy zZs~gnS3B6~X}_K|%HAV~S$V`TXamdgZXOBypV1Lde7}k--C%ltA=XHIlYtRnlaLVz zv*8i34YRx-uq(6YOuqrM{!T*zvm{j76|+QY14gsFvFrr1#kMgIlLN?Vlc;%zvupHM z4}ZuF00000004NLomcyB8$}RKfr4o13sg$q+w_sRrALyMf{JLHI1)rWRF%N5*7|O3 zFPwL+-MyH|^8enMy*Ybr-@|I8knJfi1rk$&C@tbxf7Nh=I`15 zTh=Z%%@z-E(<9jM6WI0|teJ8h>BJC;E+Y}HSOmva8+{3D5!mBKEUDlOf!jA0-3G)X z|3&WOCcNEQ%SZI16AwiE-x-Q#8-G~V(}uZ$VB&violvo0x;JfV~S#Qsqm1!7?jVKlCE{l(PJ=k@iH! zPMcHY#qwyUTn>GL|H)rO7b!SD)_+6I0-q`A=rA28QZdrTmk<{6G5yA)6&n`LhMObI z^eeFM>KUtuUM~^hcdTas9rC?Mt26{{9!m7Uji#o5GtoK#{jo=CIrcLGjAe;p? zlWU8bMoAA^WD2Vu&$*u@2!HEe zfF*4r1e|N@u()vuAHiItC4;Lg+*k;O8T3h=>`mD=Bq@b4b|PBQXMdE^&3fWMnOBOz z70#_o6pWJV+6<;qqc6a60i~zx4}B8M53I?&4w)V+h+Oy7AB8(Mc{Yu3c;UV6+Zy^R z)<1&@#(0`~t~m)X`f-MAVSI6P;Vc7swryo9Kt4aS$@6I|dP0hC1>VG3C9>>FFyMBk zM?A)HzQHot!z+m}j(^MfT?#Hbyo-^c+e&nYwr!Sj6^%6{`GPv@uiW~{aGO&1s1zYA zf@N31DOj2}4G>-4Mlfg?uQ)RX5?yW#2Q32+!nd)bT1Wwe+=$p@ zaH~*a%=!kP5`W9E5o^OOlcyFxkqVkXjP2^*%!uNPU5d=jGEvHbOoYxHG5%JE2Y(ak)O(Gr+)H S;z0joBmdtG|K0;O>@zcn1CAa5 diff --git a/worlds/wargroove/data/save/campaign-c40a6e5b0cdf86ddac03b276691c483d.cmp b/worlds/wargroove/data/save/campaign-c40a6e5b0cdf86ddac03b276691c483d.cmp index 93c4f3c88742c3707352898f964916160dcef92e..f823aa0477dbdc330023f131eab4c0129d50126f 100644 GIT binary patch literal 114528 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 MW#eAJ=f4h>cX+6{@Bjb+ literal 114384 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�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 YsKucDTR*UVFL5>3j; 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 EF^?_;R{#J2 literal 114384 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 YzL6%1ni#KQq68%R^WF2=>-cUHPzhnK=Kufz diff --git a/worlds/wargroove/docs/en_Wargroove.md b/worlds/wargroove/docs/en_Wargroove.md index 31fd8c81301c..b8dcc7aca852 100644 --- a/worlds/wargroove/docs/en_Wargroove.md +++ b/worlds/wargroove/docs/en_Wargroove.md @@ -1,4 +1,4 @@ -# Wargroove (Steam, Windows) +# Wargroove (Steam, Windows, Linux) ## Where is the options page? @@ -39,3 +39,5 @@ The following commands are only available when using the WargrooveClient to play - `/resync` Manually trigger a resync. - `/commander` Set the current commander to the given commander. +- `/deathlink` Toggle deathlink between On and Off. +- `/sacrifice_summon` Toggle sacrificing and summoning units between On and Off. diff --git a/worlds/wargroove/docs/wargroove_en.md b/worlds/wargroove/docs/wargroove_en.md index 9c2645178aa2..e4a6b0e393b7 100644 --- a/worlds/wargroove/docs/wargroove_en.md +++ b/worlds/wargroove/docs/wargroove_en.md @@ -2,8 +2,8 @@ ## Required Files -- Wargroove with the Double Trouble DLC installed through Steam on Windows - - Only the Steam Windows version is supported. MAC, Switch, Xbox, and Playstation are not supported. +- Wargroove with the Double Trouble DLC installed through Steam on Windows and Linux + - Only the Steam versions on Windows and Linux are supported. MAC, Switch, Xbox, and Playstation are not supported. - [The most recent Archipelago release](https://github.com/ArchipelagoMW/Archipelago/releases) ## Backup playerProgress files @@ -23,6 +23,16 @@ is strongly recommended in case they become corrupted. - You may have to replace all single \\ with \\\\. 4. Start the Wargroove client. +## Linux Only: Select AppData equivalent when starting the client +1. Shut down Wargroove if it is open. +2. Start the ArchipelagoWargrooveClient from the Archipelago installation. +3. A file select dialogue will appear, claiming it cannot detect a path to the AppData folder. +4. Navigate to your Steam install directory and select . +`/steamapps/compatdata/607050/pfx/drive_c/users/steamuser/AppData/Roaming` as the save directory. +5. Using a default Steam install path, the full AppData path is +`~/.steam/steam/steamapps/compatdata/607050/pfx/drive_c/users/steamuser/AppData/Roaming`. +6. The client should start. + ## Installing the Archipelago Wargroove Mod and Campaign files 1. Shut down Wargroove if it is open. From 3b8450036abf1861cf20129978e291f0e2baf9a3 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Wed, 21 May 2025 23:22:55 +0000 Subject: [PATCH 0443/1218] core: don't reconfigure stdout if it's fake (#5020) --- Utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Utils.py b/Utils.py index f4752448e2c3..b38809ba1b9e 100644 --- a/Utils.py +++ b/Utils.py @@ -540,7 +540,8 @@ def filter(self, record: logging.LogRecord) -> bool: if add_timestamp: stream_handler.setFormatter(formatter) root_logger.addHandler(stream_handler) - sys.stdout.reconfigure(encoding="utf-8", errors="replace") + if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8", errors="replace") # Relay unhandled exceptions to logger. if not getattr(sys.excepthook, "_wrapped", False): # skip if already modified From 7079c17a0f761935b464e4949b0f08aab2535e00 Mon Sep 17 00:00:00 2001 From: Fly Hyping Date: Thu, 22 May 2025 03:11:34 -0400 Subject: [PATCH 0444/1218] Wargroove: apworld doc fixes (#5023) --- worlds/wargroove/docs/wargroove_en.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/wargroove/docs/wargroove_en.md b/worlds/wargroove/docs/wargroove_en.md index e4a6b0e393b7..d23f58309b5d 100644 --- a/worlds/wargroove/docs/wargroove_en.md +++ b/worlds/wargroove/docs/wargroove_en.md @@ -25,7 +25,7 @@ is strongly recommended in case they become corrupted. ## Linux Only: Select AppData equivalent when starting the client 1. Shut down Wargroove if it is open. -2. Start the ArchipelagoWargrooveClient from the Archipelago installation. +2. Start the Archipelago Wargroove Client from the Archipelago Launcher. 3. A file select dialogue will appear, claiming it cannot detect a path to the AppData folder. 4. Navigate to your Steam install directory and select . `/steamapps/compatdata/607050/pfx/drive_c/users/steamuser/AppData/Roaming` as the save directory. @@ -36,7 +36,7 @@ is strongly recommended in case they become corrupted. ## Installing the Archipelago Wargroove Mod and Campaign files 1. Shut down Wargroove if it is open. -2. Start the ArchipelagoWargrooveClient.exe from the Archipelago installation. +2. Start the Archipelago Wargroove Client from the Archipelago Launcher. This should install the mod and campaign for you. 3. Start Wargroove. From e3219ba45253132b932c1bad93d9d567d85e91c6 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Thu, 22 May 2025 02:47:48 -0500 Subject: [PATCH 0445/1218] WebHost: allow APPlayerContainers from "custom" worlds to be displayed in rooms (#4981) Gives WebHost the ability to verify that a patch file is an APPlayerContainer (defined by #4331 as a APContainer containing the "player" field), and allowed it to display any patch file that it can verify is an APPlayerContainer. --- WebHostLib/__init__.py | 4 +--- WebHostLib/templates/hostGame.html | 4 +--- WebHostLib/templates/macros.html | 14 +------------- worlds/Files.py | 13 +++++++++++++ 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/WebHostLib/__init__.py b/WebHostLib/__init__.py index 9c713419c986..934cc2498d03 100644 --- a/WebHostLib/__init__.py +++ b/WebHostLib/__init__.py @@ -80,10 +80,8 @@ def register(): """Import submodules, triggering their registering on flask routing. Note: initializes worlds subsystem.""" # has automatic patch integration - import worlds.AutoWorld import worlds.Files - app.jinja_env.filters['supports_apdeltapatch'] = lambda game_name: \ - game_name in worlds.Files.AutoPatchRegister.patch_types + app.jinja_env.filters['is_applayercontainer'] = worlds.Files.is_ap_player_container from WebHostLib.customserver import run_server_process # to trigger app routing picking up on it diff --git a/WebHostLib/templates/hostGame.html b/WebHostLib/templates/hostGame.html index 38406351537b..d7d0a9633129 100644 --- a/WebHostLib/templates/hostGame.html +++ b/WebHostLib/templates/hostGame.html @@ -17,9 +17,7 @@

    Host Game

    This page allows you to host a game which was not generated by the website. For example, if you have generated a game on your own computer, you may upload the zip file created by the generator to host the game here. This will also provide a tracker, and the ability for your players to download - their patch files if the game is core-verified. For Custom Games, you can find the patch files in - the output .zip file you are uploading here. You need to manually distribute those patch files to - your players. + their patch files.

    In addition to the zip file created by the generator, you may upload a multidata file here as well.

    diff --git a/WebHostLib/templates/macros.html b/WebHostLib/templates/macros.html index b95b8820a72f..0416658dde28 100644 --- a/WebHostLib/templates/macros.html +++ b/WebHostLib/templates/macros.html @@ -29,27 +29,15 @@ {% if patch.game == "Minecraft" %} Download APMC File... - {% elif patch.game == "Factorio" %} - - Download Factorio Mod... - {% elif patch.game == "Kingdom Hearts 2" %} - - Download Kingdom Hearts 2 Mod... - {% elif patch.game == "Ocarina of Time" %} - - Download APZ5 File... {% elif patch.game == "VVVVVV" and room.seed.slots|length == 1 %} Download APV6 File... {% elif patch.game == "Super Mario 64" and room.seed.slots|length == 1 %} Download APSM64EX File... - {% elif patch.game | supports_apdeltapatch %} + {% elif patch.game | is_applayercontainer(patch.data, patch.player_id) %} Download Patch File... - {% elif patch.game == "Final Fantasy Mystic Quest" %} - - Download APMQ File... {% else %} No file to download for this game. {% endif %} diff --git a/worlds/Files.py b/worlds/Files.py index e451d08cd9a9..447219bd191b 100644 --- a/worlds/Files.py +++ b/worlds/Files.py @@ -6,6 +6,7 @@ from enum import IntEnum import os import threading +from io import BytesIO from typing import ClassVar, Dict, List, Literal, Tuple, Any, Optional, Union, BinaryIO, overload, Sequence @@ -70,6 +71,18 @@ def get_handler(game: Optional[str]) -> Union[AutoPatchExtensionRegister, List[A container_version: int = 6 +def is_ap_player_container(game: str, data: bytes, player: int): + if not zipfile.is_zipfile(BytesIO(data)): + return False + with zipfile.ZipFile(BytesIO(data), mode='r') as zf: + if "archipelago.json" in zf.namelist(): + manifest = json.loads(zf.read("archipelago.json")) + if "game" in manifest and "player" in manifest: + if game == manifest["game"] and player == manifest["player"]: + return True + return False + + class InvalidDataError(Exception): """ Since games can override `read_contents` in APContainer, From b52310f641a07a579169ce0ce3b07e7f26f946cb Mon Sep 17 00:00:00 2001 From: qwint Date: Thu, 22 May 2025 08:12:28 -0500 Subject: [PATCH 0446/1218] Wargroove: Cleanup `script_name` Component in `LauncherComponents` (#5021) --- worlds/LauncherComponents.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index d587e65d33cc..b3e3d9006092 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -232,8 +232,6 @@ def install_apworld(apworld_path: str = "") -> None: Component('ChecksFinder Client', 'ChecksFinderClient'), # Starcraft 2 Component('Starcraft 2 Client', 'Starcraft2Client'), - # Wargroove - Component('Wargroove Client', 'WargrooveClient'), # Zillion Component('Zillion Client', 'ZillionClient', file_identifier=SuffixIdentifier('.apzl')), From e0918a7a89513fc13ad648b20c1cdf9a2502fd19 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Thu, 22 May 2025 09:24:50 -0400 Subject: [PATCH 0447/1218] TUNIC: Move some UT stuff out of init, put in UT poptracker integration support (#4967) --- worlds/tunic/__init__.py | 44 +---- worlds/tunic/ut_stuff.py | 383 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 393 insertions(+), 34 deletions(-) create mode 100644 worlds/tunic/ut_stuff.py diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index cdc8f05cb91a..84f1338ad5e3 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -16,9 +16,10 @@ get_hexagons_in_pool, HexagonQuestAbilityUnlockType, EntranceLayout) from .breakables import breakable_location_name_to_id, breakable_location_groups, breakable_location_table from .combat_logic import area_data, CombatState +from . import ut_stuff from worlds.AutoWorld import WebWorld, World from Options import PlandoConnection, OptionError, PerGameCommonOptions, Removed, Range -from settings import Group, Bool +from settings import Group, Bool, FilePath class TunicSettings(Group): @@ -27,9 +28,15 @@ class DisableLocalSpoiler(Bool): class LimitGrassRando(Bool): """Limits the impact of Grass Randomizer on the multiworld by disallowing local_fill percentages below 95.""" + + class UTPoptrackerPath(FilePath): + """Path to the user's TUNIC Poptracker Pack.""" + description = "TUNIC Poptracker Pack zip file" + required = False disable_local_spoiler: Union[DisableLocalSpoiler, bool] = False limit_grass_rando: Union[LimitGrassRando, bool] = True + ut_poptracker_path: Union[UTPoptrackerPath, str] = UTPoptrackerPath() class TunicWeb(WebWorld): @@ -113,6 +120,7 @@ class TunicWorld(World): using_ut: bool # so we can check if we're using UT only once passthrough: Dict[str, Any] ut_can_gen_without_yaml = True # class var that tells it to ignore the player yaml + tracker_world: ClassVar = ut_stuff.tracker_world def generate_early(self) -> None: try: @@ -168,39 +176,7 @@ def replace_connection(old_cxn: PlandoConnection, new_cxn: PlandoConnection, ind f"They have Direction Pairs enabled and the connection " f"{cxn.entrance} --> {cxn.exit} does not abide by this option.") - # Universal tracker stuff, shouldn't do anything in standard gen - if hasattr(self.multiworld, "re_gen_passthrough"): - if "TUNIC" in self.multiworld.re_gen_passthrough: - self.using_ut = True - self.passthrough = self.multiworld.re_gen_passthrough["TUNIC"] - self.options.start_with_sword.value = self.passthrough["start_with_sword"] - self.options.keys_behind_bosses.value = self.passthrough["keys_behind_bosses"] - self.options.sword_progression.value = self.passthrough["sword_progression"] - self.options.ability_shuffling.value = self.passthrough["ability_shuffling"] - self.options.laurels_zips.value = self.passthrough["laurels_zips"] - self.options.ice_grappling.value = self.passthrough["ice_grappling"] - self.options.ladder_storage.value = self.passthrough["ladder_storage"] - self.options.ladder_storage_without_items = self.passthrough["ladder_storage_without_items"] - self.options.lanternless.value = self.passthrough["lanternless"] - self.options.maskless.value = self.passthrough["maskless"] - self.options.hexagon_quest.value = self.passthrough["hexagon_quest"] - self.options.hexagon_quest_ability_type.value = self.passthrough.get("hexagon_quest_ability_type", 0) - self.options.entrance_rando.value = self.passthrough["entrance_rando"] - self.options.shuffle_ladders.value = self.passthrough["shuffle_ladders"] - self.options.entrance_layout.value = EntranceLayout.option_standard - if ("ziggurat2020_3, ziggurat2020_1_zig2_skip" in self.passthrough["Entrance Rando"].keys() - or "ziggurat2020_3, ziggurat2020_1_zig2_skip" in self.passthrough["Entrance Rando"].values()): - self.options.entrance_layout.value = EntranceLayout.option_fixed_shop - self.options.decoupled = self.passthrough.get("decoupled", 0) - self.options.laurels_location.value = LaurelsLocation.option_anywhere - self.options.grass_randomizer.value = self.passthrough.get("grass_randomizer", 0) - self.options.breakable_shuffle.value = self.passthrough.get("breakable_shuffle", 0) - self.options.laurels_location.value = self.options.laurels_location.option_anywhere - self.options.combat_logic.value = self.passthrough.get("combat_logic", 0) - else: - self.using_ut = False - else: - self.using_ut = False + ut_stuff.setup_options_from_slot_data(self) self.player_location_table = standard_location_name_to_id.copy() diff --git a/worlds/tunic/ut_stuff.py b/worlds/tunic/ut_stuff.py new file mode 100644 index 000000000000..8296452c73ec --- /dev/null +++ b/worlds/tunic/ut_stuff.py @@ -0,0 +1,383 @@ +from typing import Any, TYPE_CHECKING + +from .options import EntranceLayout, LaurelsLocation + +if TYPE_CHECKING: + from . import TunicWorld + + +def setup_options_from_slot_data(world: "TunicWorld") -> None: + if hasattr(world.multiworld, "re_gen_passthrough"): + if "TUNIC" in world.multiworld.re_gen_passthrough: + world.using_ut = True + world.passthrough = world.multiworld.re_gen_passthrough["TUNIC"] + world.options.start_with_sword.value = world.passthrough["start_with_sword"] + world.options.keys_behind_bosses.value = world.passthrough["keys_behind_bosses"] + world.options.sword_progression.value = world.passthrough["sword_progression"] + world.options.ability_shuffling.value = world.passthrough["ability_shuffling"] + world.options.laurels_zips.value = world.passthrough["laurels_zips"] + world.options.ice_grappling.value = world.passthrough["ice_grappling"] + world.options.ladder_storage.value = world.passthrough["ladder_storage"] + world.options.ladder_storage_without_items = world.passthrough["ladder_storage_without_items"] + world.options.lanternless.value = world.passthrough["lanternless"] + world.options.maskless.value = world.passthrough["maskless"] + world.options.hexagon_quest.value = world.passthrough["hexagon_quest"] + world.options.hexagon_quest_ability_type.value = world.passthrough.get("hexagon_quest_ability_type", 0) + world.options.entrance_rando.value = world.passthrough["entrance_rando"] + world.options.shuffle_ladders.value = world.passthrough["shuffle_ladders"] + # world.options.shuffle_fuses.value = world.passthrough.get("shuffle_fuses", 0) + # world.options.shuffle_bells.value = world.passthrough.get("shuffle_bells", 0) + world.options.grass_randomizer.value = world.passthrough.get("grass_randomizer", 0) + world.options.breakable_shuffle.value = world.passthrough.get("breakable_shuffle", 0) + world.options.entrance_layout.value = EntranceLayout.option_standard + if ("ziggurat2020_3, ziggurat2020_1_zig2_skip" in world.passthrough["Entrance Rando"].keys() + or "ziggurat2020_3, ziggurat2020_1_zig2_skip" in world.passthrough["Entrance Rando"].values()): + world.options.entrance_layout.value = EntranceLayout.option_fixed_shop + world.options.decoupled = world.passthrough.get("decoupled", 0) + world.options.laurels_location.value = LaurelsLocation.option_anywhere + world.options.combat_logic.value = world.passthrough.get("combat_logic", 0) + else: + world.using_ut = False + else: + world.using_ut = False + + +# for UT poptracker integration map tab switching +def map_page_index(data: Any) -> int: + mapping: dict[str, int] = { + "Beneath the Earth": 1, + "Beneath the Well": 2, + "The Cathedral": 3, + "Dark Tomb": 4, + "Eastern Vault": 5, + "Frog's Domain": 6, + "Swamp": 7, + "Overworld": 8, + "The Quarry": 9, + "Ruined Atoll": 10, + "West Gardens": 11, + "The Grand Library": 12, + "East Forest": 13, + "The Far Shore": 14, + "The Rooted Ziggurat": 15, + } + return mapping.get(data, 0) + + +# mapping of everything after the second to last slash and the location id +# lua used for the name: string.match(full_name, "[^/]*/[^/]*$") +poptracker_data: dict[str, int] = { + "[Powered Secret Room] Chest/Follow the Purple Energy Road": 509342400, + "[Entryway] Chest/Mind the Slorms": 509342401, + "[Third Room] Beneath Platform Chest/Run from the tentacles!": 509342402, + "[Third Room] Tentacle Chest/Water Sucks": 509342403, + "[Entryway] Obscured Behind Waterfall/You can just go in there": 509342404, + "[Save Room] Upper Floor Chest 1/Through the Power of Prayer": 509342405, + "[Save Room] Upper Floor Chest 2/Above the Fox Shrine": 509342406, + "[Second Room] Underwater Chest/Hidden Passage": 509342407, + "[Back Corridor] Right Secret/Hidden Path": 509342408, + "[Back Corridor] Left Secret/Behind the Slorms": 509342409, + "[Second Room] Obscured Behind Waterfall/Just go in there": 509342410, + "[Side Room] Chest By Pots/Just Climb up There": 509342411, + "[Side Room] Chest By Phrends/So Many Phrends!": 509342412, + "[Second Room] Page/Ruined Atoll Map": 509342413, + "[Passage To Dark Tomb] Page Pickup/Siege Engine": 509342414, + "[1F] Guarded By Lasers/Beside 3 Miasma Seekers": 509342415, + "[1F] Near Spikes/Mind the Miasma Seeker": 509342416, + "Birdcage Room/[2F] Bird Room": 509342417, + "[2F] Entryway Upper Walkway/Overlooking Miasma": 509342418, + "[1F] Library/By the Books": 509342419, + "[2F] Library/Behind the Ladder": 509342420, + "[2F] Guarded By Lasers/Before the big reveal...": 509342421, + "Birdcage Room/[2F] Bird Room Secret": 509342422, + "[1F] Library Secret/Pray to the Wallman": 509342423, + "Spike Maze Near Exit/Watch out!": 509342424, + "2nd Laser Room/Can you roll?": 509342425, + "1st Laser Room/Use a bomb?": 509342426, + "Spike Maze Upper Walkway/Just walk right!": 509342427, + "Skulls Chest/Move the Grave": 509342428, + "Spike Maze Near Stairs/In the Corner": 509342429, + "1st Laser Room Obscured/Follow the red laser of death": 509342430, + "Guardhouse 2 - Upper Floor/In the Mound": 509342431, + "Guardhouse 2 - Bottom Floor Secret/Hidden Hallway": 509342432, + "Guardhouse 1 Obscured/Upper Floor Obscured": 509342433, + "Guardhouse 1/Upper Floor": 509342434, + "Guardhouse 1 Ledge HC/Dancing Fox Spirit Holy Cross": 509342435, + "Golden Obelisk Holy Cross/Use the Holy Cross": 509342436, + "Ice Rod Grapple Chest/Freeze the Blob and ascend With Orb": 509342437, + "Above Save Point/Chest": 509342438, + "Above Save Point Obscured/Hidden Path": 509342439, + "Guardhouse 1 Ledge/From Guardhouse 1 Chest": 509342440, + "Near Save Point/Chest": 509342441, + "Ambushed by Spiders/Beneath Spider Chest": 509342442, + "Near Telescope/Up on the Wall": 509342443, + "Ambushed by Spiders/Spider Chest": 509342444, + "Lower Dash Chest/Dash Across": 509342445, + "Lower Grapple Chest/Grapple Across": 509342446, + "Bombable Wall/Follow the Flowers": 509342447, + "Page On Teleporter/Page": 509342448, + "Forest Belltower Save Point/Near Save Point": 509342449, + "Forest Belltower - After Guard Captain/Chest": 509342450, + "East Bell/Forest Belltower - Obscured Near Bell Top Floor": 509342451, + "Forest Belltower Obscured/Obscured Beneath Bell Bottom Floor": 509342452, + "Forest Belltower Page/Page Pickup": 509342453, + "Forest Grave Path - Holy Cross Code by Grave/Single Money Chest": 509342454, + "Forest Grave Path - Above Gate/Chest": 509342455, + "Forest Grave Path - Obscured Chest/Behind the Trees": 509342456, + "Forest Grave Path - Upper Walkway/From the top of the Guardhouse": 509342457, + "The Hero's Sword/Forest Grave Path - Sword Pickup": 509342458, + "The Hero's Sword/Hero's Grave - Tooth Relic": 509342459, + "Fortress Courtyard - From East Belltower/Crack in the Wall": 509342460, + "Fortress Leaf Piles - Secret Chest/Dusty": 509342461, + "Fortress Arena/Hexagon Red": 509342462, + "Fortress Arena/Siege Engine|Vault Key Pickup": 509342463, + "Fortress East Shortcut - Chest Near Slimes/Mind the Custodians": 509342464, + "[West Wing] Candles Holy Cross/Use the Holy Cross": 509342465, + "Westmost Upper Room/[West Wing] Dark Room Chest 1": 509342466, + "Westmost Upper Room/[West Wing] Dark Room Chest 2": 509342467, + "[East Wing] Bombable Wall/Bomb the Wall": 509342468, + "[West Wing] Page Pickup/He will never visit the Far Shore": 509342469, + "Fortress Grave Path - Upper Walkway/Go Around the East Wing": 509342470, + "Vault Hero's Grave/Fortress Grave Path - Chest Right of Grave": 509342471, + "Vault Hero's Grave/Fortress Grave Path - Obscured Chest Left of Grave": 509342472, + "Vault Hero's Grave/Hero's Grave - Flowers Relic": 509342473, + "Bridge/Chest": 509342474, + "Cell Chest 1/Drop the Shortcut Rope": 509342475, + "Obscured Behind Waterfall/Muffling Bell": 509342476, + "Back Room Chest/Lose the Lure or take 2 Damage": 509342477, + "Cell Chest 2/Mind the Custodian": 509342478, + "Near Vault/Already Stolen": 509342479, + "Slorm Room/Tobias was Trapped Here Once...": 509342480, + "Escape Chest/Don't Kick Fimbleton!": 509342481, + "Grapple Above Hot Tub/Look Up": 509342482, + "Above Vault/Obscured Doorway Ledge": 509342483, + "Main Room Top Floor/Mind the Adult Frog": 509342484, + "Main Room Bottom Floor/Altar Chest": 509342485, + "Side Room Secret Passage/Upper Right Corner": 509342486, + "Side Room Chest/Oh No! Our Frogs! They're Dead!": 509342487, + "Side Room Grapple Secret/Grapple on Over": 509342488, + "Magic Orb Pickup/Frult Meeting": 509342489, + "The Librarian/Hexagon Green": 509342490, + "Library Hall/Holy Cross Chest": 509342491, + "Library Lab Chest by Shrine 2/Chest": 509342492, + "Library Lab Chest by Shrine 1/Chest": 509342493, + "Library Lab Chest by Shrine 3/Chest": 509342494, + "Library Lab by Fuse/Behind Chalkboard": 509342495, + "Library Lab Page 3/Page": 509342496, + "Library Lab Page 1/Page": 509342497, + "Library Lab Page 2/Page": 509342498, + "Hero's Grave/Mushroom Relic": 509342499, + "Mountain Door/Lower Mountain - Page Before Door": 509342500, + "Changing Room/Normal Chest": 509342501, + "Fortress Courtyard - Chest Near Cave/Next to the Obelisk": 509342502, + "Fortress Courtyard - Near Fuse/Pray": 509342503, + "Fortress Courtyard - Below Walkway/Under the Stairs": 509342504, + "Fortress Courtyard - Page Near Cave/Heir-To-The-Heir": 509342505, + "West Furnace/Lantern Pickup": 509342506, + "Maze Cave/Maze Room Chest": 509342507, + "Inside the Old House/Normal Chest": 509342508, + "Inside the Old House/Shield Pickup": 509342509, + "[West] Obscured Behind Windmill/Behind the Trees": 509342510, + "[South] Beach Chest/Beside the Bridge": 509342511, + "[West] Obscured Near Well/Hidden by Trees": 509342512, + "[Central] Bombable Wall/Let the flowers guide you": 509342513, + "[Northwest] Chest Near Turret/Mind the Autobolt...": 509342514, + "[East] Chest Near Pots/Chest": 509342515, + "[Northwest] Chest Near Golden Obelisk/Underneath the Staff": 509342516, + "[Southwest] South Chest Near Guard/End of the Bridge": 509342517, + "[Southwest] West Beach Guarded By Turret/Chest": 509342518, + "[Southwest] Chest Guarded By Turret/Behind the Trees": 509342519, + "[Northwest] Shadowy Corner Chest/Dark Ramps Chest": 509342520, + "[Southwest] Obscured In Tunnel To Beach/Deep in the Wall": 509342521, + "[Southwest] Grapple Chest Over Walkway/Jeffry": 509342522, + "[Northwest] Chest Beneath Quarry Gate/Across the Bridge": 509342523, + "[Southeast] Chest Near Swamp/Under the Bridge": 509342524, + "[Southwest] From West Garden/Dash Across": 509342525, + "[East] Grapple Chest/Grapple Across": 509342526, + "[Southwest] West Beach Guarded By Turret 2/Get Across": 509342527, + "Sand Hook/[Southwest] Beach Chest Near Flowers": 509342528, + "[Southwest] Bombable Wall Near Fountain/Let the flowers guide you": 509342529, + "[West] Chest After Bell/Post-Dong!": 509342530, + "[Southwest] Tunnel Guarded By Turret/Below Jeffry": 509342531, + "[East] Between ladders near Ruined Passage/Chest": 509342532, + "[Northeast] Chest Above Patrol Cave/Behind Blue Rudelings": 509342533, + "[Southwest] Beach Chest Beneath Guard/Under Bridge": 509342534, + "[Central] Chest Across From Well/Across the Bridge": 509342535, + "[Northwest] Chest Near Quarry Gate/Rudeling Camp": 509342536, + "[East] Chest In Trees/Above Locked House": 509342537, + "[West] Chest Behind Moss Wall/Around the Corner": 509342538, + "[South] Beach Page/Page": 509342539, + "[Southeast] Page on Pillar by Swamp/Dash Across": 509342540, + "[Southwest] Key Pickup/Old House Key": 509342541, + "[West] Key Pickup/Hero's Path Key": 509342542, + "[East] Page Near Secret Shop/Page": 509342543, + "Fountain/[Southwest] Fountain Page": 509342544, + "[Northwest] Page on Pillar by Dark Tomb/A Terrible Power Rises": 509342545, + "Magic Staff/[Northwest] Fire Wand Pickup": 509342546, + "[West] Page on Teleporter/Treasures and Tools": 509342547, + "[Northwest] Page By Well/If you seek to increase your power...": 509342548, + "Patrol Cave/Normal Chest": 509342549, + "Ruined Shop/Chest 1": 509342550, + "Ruined Shop/Chest 2": 509342551, + "Ruined Shop/Chest 3": 509342552, + "Ruined Passage/Page Pickup": 509342553, + "Shop/Potion 1": 509342554, + "Shop/Potion 2": 509342555, + "Shop/Coin 1": 509342556, + "Shop/Coin 2": 509342557, + "Special Shop/Secret Page Pickup": 509342558, + "Stick House/Stick Chest": 509342559, + "Sealed Temple/Page Pickup": 509342560, + "Inside Hourglass Cave/Hourglass Chest": 509342561, + "Secret Chest/Dash Across": 509342562, + "Page Pickup/A Long, Long Time Ago...": 509342563, + "Coins in the Well/10 Coins": 509342564, + "Coins in the Well/15 Coins": 509342565, + "Coins in the Well/3 Coins": 509342566, + "Coins in the Well/6 Coins": 509342567, + "Secret Gathering Place/20 Fairy Reward": 509342568, + "Secret Gathering Place/10 Fairy Reward": 509342569, + "[West] Moss Wall Holy Cross/Use the Holy Cross": 509342570, + "[Southwest] Flowers Holy Cross/Use the Holy Cross": 509342571, + "Fountain/[Southwest] Fountain Holy Cross": 509342572, + "[Northeast] Flowers Holy Cross/Use the Holy Cross": 509342573, + "[East] Weathervane Holy Cross/Use the Holy Cross": 509342574, + "[West] Windmill Holy Cross/Sacred Geometry": 509342575, + "Sand Hook/[Southwest] Haiku Holy Cross": 509342576, + "[West] Windchimes Holy Cross/Power Up!": 509342577, + "[South] Starting Platform Holy Cross/Back to Work": 509342578, + "Magic Staff/[Northwest] Golden Obelisk Page": 509342579, + "Inside the Old House/Holy Cross Door Page": 509342580, + "Cube Cave/Holy Cross Chest": 509342581, + "Southeast Cross Door/Chest 3": 509342582, + "Southeast Cross Door/Chest 2": 509342583, + "Southeast Cross Door/Chest 1": 509342584, + "Maze Cave/Maze Room Holy Cross": 509342585, + "Caustic Light Cave/Holy Cross Chest": 509342586, + "Inside the Old House/Holy Cross Chest": 509342587, + "Patrol Cave/Holy Cross Chest": 509342588, + "Ruined Passage/Holy Cross Chest": 509342589, + "Inside Hourglass Cave/Holy Cross Chest": 509342590, + "Sealed Temple/Holy Cross Chest": 509342591, + "Fountain Cross Door/Page Pickup": 509342592, + "Secret Gathering Place/Holy Cross Chest": 509342593, + "Mountain Door/Top of the Mountain - Page At The Peak": 509342594, + "Monastery/Monastery Chest": 509342595, + "[Back Entrance] Bushes Holy Cross/Use the Holy Cross": 509342596, + "[Back Entrance] Chest/Peaceful Chest": 509342597, + "[Central] Near Shortcut Ladder/By the Boxes": 509342598, + "[East] Near Telescope/Spoopy": 509342599, + "[East] Upper Floor/Reminds me of Blighttown": 509342600, + "[Central] Below Entry Walkway/Even more Stairs!": 509342601, + "[East] Obscured Near Winding Staircase/At the Bottom": 509342602, + "[East] Obscured Beneath Scaffolding/In the Miasma Mound": 509342603, + "[East] Obscured Near Telescope/Weird path?": 509342604, + "[Back Entrance] Obscured Behind Wall/Happy Water!": 509342605, + "[Central] Obscured Below Entry Walkway/Down the Stairs": 509342606, + "[Central] Top Floor Overhang/End of the ruined bridge": 509342607, + "[East] Near Bridge/Drop that Bridge!": 509342608, + "[Central] Above Ladder/Climb Ladder": 509342609, + "[Central] Obscured Behind Staircase/At the Bottom": 509342610, + "[Central] Above Ladder Dash Chest/Dash Across": 509342611, + "[West] Upper Area Bombable Wall/Boomy": 509342612, + "[East] Bombable Wall/Flowers Guide Thee": 509342613, + "Monastery/Hero's Grave - Ash Relic": 509342614, + "[West] Shooting Range Secret Path/Obscured Path": 509342615, + "[West] Near Shooting Range/End of bridge": 509342616, + "[West] Below Shooting Range/Clever little sneak!": 509342617, + "[Lowlands] Below Broken Ladder/Miasma Pits": 509342618, + "[West] Upper Area Near Waterfall/Yummy Polygons": 509342619, + "[Lowlands] Upper Walkway/Hate them Snipers": 509342620, + "[West] Lower Area Below Bridge/Go Around": 509342621, + "[West] Lower Area Isolated Chest/Burn Pots": 509342622, + "[Lowlands] Near Elevator/End of the Tracks": 509342623, + "[West] Lower Area After Bridge/Drop that Bridge!": 509342624, + "Upper - Near Bridge Switch/You can shoot it": 509342625, + "Upper - Beneath Bridge To Administrator/End of the First Floor": 509342626, + "Tower - Inside Tower/I'm Scared": 509342627, + "Lower - Near Corpses/They are Dead": 509342628, + "Lower - Spider Ambush/Use the Gun": 509342629, + "Lower - Left Of Checkpoint Before Fuse/Moment of Reprieve": 509342630, + "Lower - After Guarded Fuse/Defeat those Mechs": 509342631, + "Lower - Guarded By Double Turrets/Help": 509342632, + "Lower - After 2nd Double Turret Chest/Haircut Time!": 509342633, + "Lower - Guarded By Double Turrets 2/Oh god they're everywhere": 509342634, + "Lower - Hexagon Blue/Scavenger Queen": 509342635, + "[West] Near Kevin Block/Phonomath": 509342636, + "[South] Upper Floor On Power Line/Hidden Ladder Chest": 509342637, + "[South] Chest Near Big Crabs/His Name is Tom": 509342638, + "[North] Guarded By Bird/Skraw!": 509342639, + "[Northeast] Chest Beneath Brick Walkway/Mind the Crabbits": 509342640, + "[Northwest] Bombable Wall/Flowers Guide Thee": 509342641, + "[North] Obscured Beneath Bridge/In the shallow water": 509342642, + "[South] Upper Floor On Bricks/Up the Ladder": 509342643, + "[South] Near Birds/Danlarry and Thranmire ate Jerry!": 509342644, + "[Northwest] Behind Envoy/Mind the Fairies": 509342645, + "[Southwest] Obscured Behind Fuse/Saved by the Prayer": 509342646, + "Locked Brick House/[East] Locked Room Upper Chest": 509342647, + "[North] From Lower Overworld Entrance/Come from the Overworld": 509342648, + "Locked Brick House/[East] Locked Room Lower Chest": 509342649, + "[Northeast] Chest On Brick Walkway/Near Domain": 509342650, + "[Southeast] Chest Near Fuse/Around the Tower": 509342651, + "[Northeast] Key Pickup/Around the Hill": 509342652, + "Cathedral Gauntlet/Gauntlet Reward": 509342653, + "Secret Legend Trophy Chest/You can use the Holy Cross from the outside": 509342654, + "[Upper Graveyard] Obscured Behind Hill/Between Two Hills": 509342655, + "[South Graveyard] 4 Orange Skulls/DJ Khaled - Let's go Golfing!": 509342656, + "[Central] Near Ramps Up/Up them Ramps": 509342657, + "[Upper Graveyard] Near Shield Fleemers/Alternatively, Before the Cathedral": 509342658, + "[South Graveyard] Obscured Behind Ridge/Hidden passage by ladder": 509342659, + "[South Graveyard] Obscured Beneath Telescope/Through the Nook": 509342660, + "[Entrance] Above Entryway/Dash Across": 509342661, + "[Central] South Secret Passage/Wall Man Approves these Vibes": 509342662, + "[South Graveyard] Upper Walkway On Pedestal/Gazing out over the Graves": 509342663, + "[South Graveyard] Guarded By Tentacles/Isolated Island": 509342664, + "[Upper Graveyard] Near Telescope/Overlooking the Graves": 509342665, + "[Outside Cathedral] Near Moonlight Bridge Door/Down the Hidden Ladder": 509342666, + "[Entrance] Obscured Inside Watchtower/Go Inside": 509342667, + "[Entrance] South Near Fence/DAGGER STRAP!!!!!": 509342668, + "[South Graveyard] Guarded By Big Skeleton/Super Clipping": 509342669, + "[South Graveyard] Chest Near Graves/The Rest of Our Entire Life is Death": 509342670, + "[Entrance] North Small Island/Mildly Hidden": 509342671, + "First Hero's Grave/[Outside Cathedral] Obscured Behind Memorial": 509342672, + "[Central] Obscured Behind Northern Mountain/Hug the Wall": 509342673, + "[South Graveyard] Upper Walkway Dash Chest/Around the Hill": 509342674, + "[South Graveyard] Above Big Skeleton/End of Ledge": 509342675, + "[Central] Beneath Memorial/Do You Even Live?": 509342676, + "First Hero's Grave/Hero's Grave - Feathers Relic": 509342677, + "West Furnace/Chest": 509342678, + "[West] Near Gardens Entrance/Effigy Skip": 509342679, + "[Central Highlands] Holy Cross (Blue Lines)/Use the Holy Cross": 509342680, + "[West Lowlands] Tree Holy Cross Chest/Use the Holy Cross": 509342681, + "[Southeast Lowlands] Outside Cave/Mind the Chompignoms!": 509342682, + "[Central Lowlands] Chest Beneath Faeries/As you walk by": 509342683, + "[North] Behind Holy Cross Door/Extra Sword!": 509342684, + "[Central Highlands] Top of Ladder Before Boss/Try to be This Strong": 509342685, + "[Central Lowlands] Passage Beneath Bridge/Take the lower path": 509342686, + "[North] Across From Page Pickup/I Love Fish!": 509342687, + "[Central Lowlands] Below Left Walkway/Dash Across": 509342688, + "[West] In Flooded Walkway/Dash through the water": 509342689, + "[West] Past Flooded Walkway/Through the Shallow Water": 509342690, + "[North] Obscured Beneath Hero's Memorial/Take the Long Way Around": 509342691, + "[Central Lowlands] Chest Near Shortcut Bridge/Between a Rope and a Bridge Place": 509342692, + "[West Highlands] Upper Left Walkway/By the Rudeling": 509342693, + "[Central Lowlands] Chest Beneath Save Point/Behind the Way": 509342694, + "[Central Highlands] Behind Guard Captain/Under Boss Ladder": 509342695, + "[Central Highlands] After Garden Knight/Did Not Kill You": 509342696, + "[South Highlands] Secret Chest Beneath Fuse/Pray to the Wall Man": 509342697, + "[East Lowlands] Page Behind Ice Dagger House/Come from the Far Shore": 509342698, + "[North] Page Pickup/Survival Tips": 509342699, + "[Southeast Lowlands] Ice Dagger Pickup/Ice Dagger Cave": 509342700, + "Hero's Grave/Effigy Relic": 509342701, +} + + +# for setting up the poptracker integration +tracker_world = { + "map_page_maps": ["maps/maps_pop.json"], + "map_page_locations": ["locations/locations_pop_er.json"], + "map_page_setting_key": "Slot:{player}:Current Map", + "map_page_index": map_page_index, + "external_pack_key": "ut_poptracker_path", + "poptracker_name_mapping": poptracker_data +} From 44a78cc821002a4b59feb3ffc9a195a8e28d5143 Mon Sep 17 00:00:00 2001 From: josephwhite <22449090+josephwhite@users.noreply.github.com> Date: Thu, 22 May 2025 09:26:28 -0400 Subject: [PATCH 0448/1218] OoT: Stop Using Utils.get_options (#4957) --- OoTClient.py | 5 +++-- worlds/oot/__init__.py | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/OoTClient.py b/OoTClient.py index 6a87b9e72201..571300ed36f5 100644 --- a/OoTClient.py +++ b/OoTClient.py @@ -12,6 +12,7 @@ import Utils from Utils import async_start from worlds import network_data_package +from worlds.oot import OOTWorld from worlds.oot.Rom import Rom, compress_rom_file from worlds.oot.N64Patch import apply_patch_file from worlds.oot.Utils import data_path @@ -280,7 +281,7 @@ async def n64_sync_task(ctx: OoTContext): async def run_game(romfile): - auto_start = Utils.get_options()["oot_options"].get("rom_start", True) + auto_start = OOTWorld.settings.rom_start if auto_start is True: import webbrowser webbrowser.open(romfile) @@ -295,7 +296,7 @@ async def patch_and_run_game(apz5_file): decomp_path = base_name + '-decomp.z64' comp_path = base_name + '.z64' # Load vanilla ROM, patch file, compress ROM - rom_file_name = Utils.get_options()["oot_options"]["rom_file"] + rom_file_name = OOTWorld.settings.rom_file rom = Rom(rom_file_name) sub_file = None diff --git a/worlds/oot/__init__.py b/worlds/oot/__init__.py index 401c387d5e05..ed025f49719c 100644 --- a/worlds/oot/__init__.py +++ b/worlds/oot/__init__.py @@ -30,7 +30,6 @@ from .N64Patch import create_patch_file from .Cosmetics import patch_cosmetics -from settings import get_settings from BaseClasses import MultiWorld, CollectionState, Tutorial, LocationProgressType from Options import Range, Toggle, VerifyKeys, Accessibility, PlandoConnections, PlandoItems from Fill import fill_restrictive, fast_fill, FillError @@ -203,7 +202,8 @@ def __init__(self, world, player): @classmethod def stage_assert_generate(cls, multiworld: MultiWorld): - rom = Rom(file=get_settings()['oot_options']['rom_file']) + oot_settings = OOTWorld.settings + rom = Rom(file=oot_settings.rom_file) # Option parsing, handling incompatible options, building useful-item table @@ -1089,7 +1089,8 @@ def generate_output(self, output_directory: str): self.hint_rng = self.random outfile_name = self.multiworld.get_out_file_name_base(self.player) - rom = Rom(file=get_settings()['oot_options']['rom_file']) + oot_settings = OOTWorld.settings + rom = Rom(file=oot_settings.rom_file) try: if self.hints != 'none': buildWorldGossipHints(self) From 95efcf6803c7d60e0994e15dd18d1f00e9ff31a7 Mon Sep 17 00:00:00 2001 From: qwint Date: Thu, 22 May 2025 08:27:18 -0500 Subject: [PATCH 0449/1218] Tests: Create CollectionState after MultiWorld.worlds (#4949) --- BaseClasses.py | 1 + test/bases.py | 2 +- test/benchmark/locations.py | 2 +- test/general/__init__.py | 2 +- worlds/alttp/test/__init__.py | 2 +- worlds/kdl3/test/__init__.py | 2 +- worlds/stardew_valley/test/bases.py | 2 +- 7 files changed, 7 insertions(+), 6 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index f480cbbda3de..9e1a0a0d7a49 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -736,6 +736,7 @@ class CollectionState(): additional_copy_functions: List[Callable[[CollectionState, CollectionState], CollectionState]] = [] def __init__(self, parent: MultiWorld, allow_partial_entrances: bool = False): + assert parent.worlds, "CollectionState created without worlds initialized in parent" self.prog_items = {player: Counter() for player in parent.get_all_ids()} self.multiworld = parent self.reachable_regions = {player: set() for player in parent.get_all_ids()} diff --git a/test/bases.py b/test/bases.py index a3ea233174dd..c9610c862da7 100644 --- a/test/bases.py +++ b/test/bases.py @@ -159,7 +159,6 @@ def world_setup(self, seed: typing.Optional[int] = None) -> None: self.multiworld.game[self.player] = self.game self.multiworld.player_name = {self.player: "Tester"} self.multiworld.set_seed(seed) - self.multiworld.state = CollectionState(self.multiworld) random.seed(self.multiworld.seed) self.multiworld.seed_name = get_seed_name(random) # only called to get same RNG progression as Generate.py args = Namespace() @@ -168,6 +167,7 @@ def world_setup(self, seed: typing.Optional[int] = None) -> None: 1: option.from_any(self.options.get(name, option.default)) }) self.multiworld.set_options(args) + self.multiworld.state = CollectionState(self.multiworld) self.world = self.multiworld.worlds[self.player] for step in gen_steps: call_all(self.multiworld, step) diff --git a/test/benchmark/locations.py b/test/benchmark/locations.py index 857e1882368b..16667a17b9af 100644 --- a/test/benchmark/locations.py +++ b/test/benchmark/locations.py @@ -59,13 +59,13 @@ def main(self): multiworld.game[1] = game multiworld.player_name = {1: "Tester"} multiworld.set_seed(0) - multiworld.state = CollectionState(multiworld) args = argparse.Namespace() for name, option in AutoWorld.AutoWorldRegister.world_types[game].options_dataclass.type_hints.items(): setattr(args, name, { 1: option.from_any(getattr(option, "default")) }) multiworld.set_options(args) + multiworld.state = CollectionState(multiworld) gc.collect() for step in self.gen_steps: diff --git a/test/general/__init__.py b/test/general/__init__.py index 6c4d5092cf13..34df741a8ca6 100644 --- a/test/general/__init__.py +++ b/test/general/__init__.py @@ -49,7 +49,6 @@ def setup_multiworld(worlds: Union[List[Type[World]], Type[World]], steps: Tuple multiworld.game = {player: world_type.game for player, world_type in enumerate(worlds, 1)} multiworld.player_name = {player: f"Tester{player}" for player in multiworld.player_ids} multiworld.set_seed(seed) - multiworld.state = CollectionState(multiworld) args = Namespace() for player, world_type in enumerate(worlds, 1): for key, option in world_type.options_dataclass.type_hints.items(): @@ -57,6 +56,7 @@ def setup_multiworld(worlds: Union[List[Type[World]], Type[World]], steps: Tuple updated_options[player] = option.from_any(option.default) setattr(args, key, updated_options) multiworld.set_options(args) + multiworld.state = CollectionState(multiworld) for step in steps: call_all(multiworld, step) return multiworld diff --git a/worlds/alttp/test/__init__.py b/worlds/alttp/test/__init__.py index 307e75381d7e..031d508604d4 100644 --- a/worlds/alttp/test/__init__.py +++ b/worlds/alttp/test/__init__.py @@ -10,12 +10,12 @@ def world_setup(self): from worlds.alttp.Options import Medallion self.multiworld = MultiWorld(1) self.multiworld.game[1] = "A Link to the Past" - self.multiworld.state = CollectionState(self.multiworld) self.multiworld.set_seed(None) args = Namespace() for name, option in AutoWorldRegister.world_types["A Link to the Past"].options_dataclass.type_hints.items(): setattr(args, name, {1: option.from_any(getattr(option, "default"))}) self.multiworld.set_options(args) + self.multiworld.state = CollectionState(self.multiworld) self.world = self.multiworld.worlds[1] # by default medallion access is randomized, for unittests we set it to vanilla self.world.options.misery_mire_medallion.value = Medallion.option_ether diff --git a/worlds/kdl3/test/__init__.py b/worlds/kdl3/test/__init__.py index 92f1d7261f1f..46f78aadaa3d 100644 --- a/worlds/kdl3/test/__init__.py +++ b/worlds/kdl3/test/__init__.py @@ -26,13 +26,13 @@ def world_setup(self, seed: typing.Optional[int] = None) -> None: self.multiworld.game[1] = self.game self.multiworld.player_name = {1: "Tester"} self.multiworld.set_seed(seed) - self.multiworld.state = CollectionState(self.multiworld) args = Namespace() for name, option in AutoWorld.AutoWorldRegister.world_types[self.game].options_dataclass.type_hints.items(): setattr(args, name, { 1: option.from_any(self.options.get(name, getattr(option, "default"))) }) self.multiworld.set_options(args) + self.multiworld.state = CollectionState(self.multiworld) self.multiworld.plando_options = PlandoOptions.connections for step in gen_steps: call_all(self.multiworld, step) diff --git a/worlds/stardew_valley/test/bases.py b/worlds/stardew_valley/test/bases.py index 64ada395682c..affc20cde191 100644 --- a/worlds/stardew_valley/test/bases.py +++ b/worlds/stardew_valley/test/bases.py @@ -293,12 +293,12 @@ def setup_multiworld(test_options: Iterable[Dict[str, int]] = None, seed=None) - multiworld = MultiWorld(len(test_options)) multiworld.player_name = {} multiworld.set_seed(seed) - multiworld.state = CollectionState(multiworld) for i in range(1, len(test_options) + 1): multiworld.game[i] = StardewValleyWorld.game multiworld.player_name.update({i: f"Tester{i}"}) args = fill_namespace_with_default(test_options) multiworld.set_options(args) + multiworld.state = CollectionState(multiworld) for step in gen_steps: call_all(multiworld, step) From aeac83d643aaa91c2ab310414c959447d2be5cda Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 22 May 2025 08:29:24 -0500 Subject: [PATCH 0450/1218] Generate: Don't Force Player Name for Weights Files (#4943) --- Generate.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Generate.py b/Generate.py index 9bc8d1066f59..f9607e328bc8 100644 --- a/Generate.py +++ b/Generate.py @@ -224,10 +224,14 @@ def main(args=None) -> tuple[argparse.Namespace, int]: except Exception as e: raise Exception(f"Error setting {k} to {v} for player {player}") from e - if path == args.weights_file_path: # if name came from the weights file, just use base player name - erargs.name[player] = f"Player{player}" - elif player not in erargs.name: # if name was not specified, generate it from filename - erargs.name[player] = os.path.splitext(os.path.split(path)[-1])[0] + # name was not specified + if player not in erargs.name: + if path == args.weights_file_path: + # weights file, so we need to make the name unique + erargs.name[player] = f"Player{player}" + else: + # use the filename + erargs.name[player] = os.path.splitext(os.path.split(path)[-1])[0] erargs.name[player] = handle_name(erargs.name[player], player, name_counter) player += 1 From 8cc6f1063475433e80f62107b95bb58769e3ed6b Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 22 May 2025 08:40:50 -0500 Subject: [PATCH 0451/1218] The Messenger: Swap Options Docstrings to use rst, Add Option Groups (#4913) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/messenger/__init__.py | 4 +- worlds/messenger/options.py | 78 +++++++++++++++++++++++++++++------- 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/worlds/messenger/__init__.py b/worlds/messenger/__init__.py index 09911fd531dd..4e2c870dae8f 100644 --- a/worlds/messenger/__init__.py +++ b/worlds/messenger/__init__.py @@ -11,7 +11,7 @@ from .connections import CONNECTIONS, RANDOMIZED_CONNECTIONS, TRANSITIONS from .constants import ALL_ITEMS, ALWAYS_LOCATIONS, BOSS_LOCATIONS, FILLER, NOTES, PHOBEKINS, PROG_ITEMS, TRAPS, \ USEFUL_ITEMS -from .options import AvailablePortals, Goal, Logic, MessengerOptions, NotesNeeded, ShuffleTransitions +from .options import AvailablePortals, Goal, Logic, MessengerOptions, NotesNeeded, option_groups, ShuffleTransitions from .portals import PORTALS, add_closed_portal_reqs, disconnect_portals, shuffle_portals, validate_portals from .regions import LEVELS, MEGA_SHARDS, LOCATIONS, REGION_CONNECTIONS from .rules import MessengerHardRules, MessengerOOBRules, MessengerRules @@ -35,6 +35,7 @@ class GamePath(FilePath): class MessengerWeb(WebWorld): theme = "ocean" + rich_text_options_doc = True bug_report_page = "https://github.com/alwaysintreble/TheMessengerRandomizerModAP/issues" @@ -56,6 +57,7 @@ class MessengerWeb(WebWorld): ) tutorials = [tut_en, plando_en] + option_groups = option_groups class MessengerWorld(World): diff --git a/worlds/messenger/options.py b/worlds/messenger/options.py index 6b04118893b1..5010f40b4bfa 100644 --- a/worlds/messenger/options.py +++ b/worlds/messenger/options.py @@ -2,8 +2,11 @@ from schema import And, Optional, Or, Schema -from Options import Choice, DeathLinkMixin, DefaultOnToggle, ItemsAccessibility, OptionDict, PerGameCommonOptions, \ - PlandoConnections, Range, StartInventoryPool, Toggle +from Options import ( + Choice, DeathLinkMixin, DefaultOnToggle, ItemsAccessibility, OptionDict, OptionGroup, + PerGameCommonOptions, + PlandoConnections, Range, StartInventoryPool, Toggle, +) from . import RANDOMIZED_CONNECTIONS from .portals import CHECKPOINTS, PORTALS, SHOP_POINTS @@ -48,8 +51,10 @@ class Logic(Choice): """ The level of logic to use when determining what locations in your world are accessible. - Normal: Can require damage boosts, but otherwise approachable for someone who has beaten the game. - Hard: Expects more knowledge and tighter execution. Has leashing, normal clips and much tighter d-boosting in logic. + **Normal:** Can require damage boosts, but otherwise approachable for someone who has beaten the game. + + **Hard:** Expects more knowledge and tighter execution. + Has leashing, normal clips and much tighter d-boosting in logic. """ display_name = "Logic Level" option_normal = 0 @@ -76,7 +81,10 @@ class EarlyMed(Toggle): class AvailablePortals(Range): - """Number of portals that are available from the start. Autumn Hills, Howling Grotto, and Glacial Peak are always available. If portal outputs are not randomized, Searing Crags will also be available.""" + """ + Number of portals that are available from the start. Autumn Hills, Howling Grotto, and Glacial Peak are always + available. If portal outputs are not randomized, Searing Crags will also be available. + """ display_name = "Available Starting Portals" range_start = 3 range_end = 6 @@ -89,10 +97,14 @@ class ShufflePortals(Choice): Entering a portal from its vanilla area will always lead to HQ, and will unlock it if relevant. Supports plando. - None: Portals will take you where they're supposed to. - Shops: Portals can lead to any area except Music Box and Elemental Skylands, with each portal output guaranteed to not overlap with another portal's. Will only put you at a portal or a shop. - Checkpoints: Like Shops except checkpoints without shops are also valid drop points. - Anywhere: Like Checkpoints except it's possible for multiple portals to output to the same map. + **None:** Portals will take you where they're supposed to. + + **Shops:** Portals can lead to any area except Music Box and Elemental Skylands, with each portal output guaranteed + to not overlap with another portal's. Will only put you at a portal or a shop. + + **Checkpoints:** Like Shops except checkpoints without shops are also valid drop points. + + **Anywhere:** Like Checkpoints except it's possible for multiple portals to output to the same map. """ display_name = "Shuffle Portal Outputs" option_none = 0 @@ -107,9 +119,11 @@ class ShuffleTransitions(Choice): Whether the transitions between the levels should be randomized. Supports plando. - None: Level transitions lead where they should. - Coupled: Returning through a transition will take you from whence you came. - Decoupled: Any level transition can take you to any other level transition. + **None:** Level transitions lead where they should. + + **Coupled:** Returning through a transition will take you from whence you came. + + **Decoupled:** Any level transition can take you to any other level transition. """ display_name = "Shuffle Level Transitions" option_none = 0 @@ -119,7 +133,10 @@ class ShuffleTransitions(Choice): class Goal(Choice): - """Requirement to finish the game. To win with the power seal hunt goal, you must enter the Music Box through the shop chest.""" + """ + Requirement to finish the game. + To win with the power seal hunt goal, you must enter the Music Box through the shop chest. + """ display_name = "Goal" option_open_music_box = 0 option_power_seal_hunt = 1 @@ -132,7 +149,8 @@ class MusicBox(DefaultOnToggle): class NotesNeeded(Range): """ - How many notes need to be found in order to access the Music Box. 6 are always needed to enter, so this places the others in your start inventory. + How many notes need to be found in order to access the Music Box. + 6 are always needed to enter, so this places the others in your start inventory. """ display_name = "Notes Needed" range_start = 1 @@ -240,3 +258,35 @@ class MessengerOptions(DeathLinkMixin, PerGameCommonOptions): shop_price_plan: PlannedShopPrices portal_plando: PortalPlando plando_connections: TransitionPlando + + +option_groups = [ + OptionGroup( + "Difficulty", + [ + EarlyMed, + Logic, + LimitedMovement, + ], + ), + OptionGroup( + "Goal", + [ + Goal, + MusicBox, + NotesNeeded, + AmountSeals, + RequiredSeals, + ], + ), + OptionGroup( + "Entrances", + [ + AvailablePortals, + ShufflePortals, + ShuffleTransitions, + PortalPlando, + TransitionPlando, + ], + ), +] From c5e768ffe32fcea48ecfc81adca330e4a0b11d38 Mon Sep 17 00:00:00 2001 From: FlitPix <8645405+FlitPix@users.noreply.github.com> Date: Thu, 22 May 2025 09:42:54 -0400 Subject: [PATCH 0452/1218] Minecraft: Stop Using Utils.get_options (#4879) --- MinecraftClient.py | 15 +++++++++------ worlds/minecraft/__init__.py | 8 +++++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/MinecraftClient.py b/MinecraftClient.py index 93385ec5385e..3047dc540e86 100644 --- a/MinecraftClient.py +++ b/MinecraftClient.py @@ -14,6 +14,7 @@ import Utils from Utils import is_windows +from settings import get_settings atexit.register(input, "Press enter to exit.") @@ -147,9 +148,11 @@ def find_jdk(version: str) -> str: if os.path.isfile(jdk_exe): return jdk_exe else: - jdk_exe = shutil.which(options["minecraft_options"].get("java", "java")) + jdk_exe = shutil.which(options.java) if not jdk_exe: - raise Exception("Could not find Java. Is Java installed on the system?") + jdk_exe = shutil.which("java") # try to fall back to system java + if not jdk_exe: + raise Exception("Could not find Java. Is Java installed on the system?") return jdk_exe @@ -285,8 +288,8 @@ def is_correct_forge(forge_dir) -> bool: # Change to executable's working directory os.chdir(os.path.abspath(os.path.dirname(sys.argv[0]))) - options = Utils.get_options() - channel = args.channel or options["minecraft_options"]["release_channel"] + options = get_settings().minecraft_options + channel = args.channel or options.release_channel apmc_data = None data_version = args.data_version or None @@ -299,8 +302,8 @@ def is_correct_forge(forge_dir) -> bool: versions = get_minecraft_versions(data_version, channel) - forge_dir = options["minecraft_options"]["forge_directory"] - max_heap = options["minecraft_options"]["max_heap_size"] + forge_dir = options.forge_directory + max_heap = options.max_heap_size forge_version = args.forge or versions["forge"] java_version = args.java or versions["java"] mod_url = versions["url"] diff --git a/worlds/minecraft/__init__.py b/worlds/minecraft/__init__.py index 75539fcf2ea6..7ec9b4b2b8d9 100644 --- a/worlds/minecraft/__init__.py +++ b/worlds/minecraft/__init__.py @@ -27,9 +27,15 @@ class ReleaseChannel(str): any games played on the "beta" channel have a high likelihood of no longer working on the "release" channel. """ - forge_directory: ForgeDirectory = ForgeDirectory("Minecraft Forge server") + class JavaExecutable(settings.OptionalUserFilePath): + """ + Path to Java executable. If not set, will attempt to fall back to Java system installation. + """ + + forge_directory: ForgeDirectory = ForgeDirectory("Minecraft NeoForge server") max_heap_size: str = "2G" release_channel: ReleaseChannel = ReleaseChannel("release") + java: JavaExecutable = JavaExecutable("") class MinecraftWebWorld(WebWorld): From 1d655a07cdffb6c58715ec1b97837a8be5bf8fab Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 22 May 2025 08:46:33 -0500 Subject: [PATCH 0453/1218] Core: Add State add/remove/set Helpers (#4845) --- BaseClasses.py | 38 ++++++++++++++++++++++++++++++++++++ worlds/AutoWorld.py | 6 ++---- worlds/messenger/__init__.py | 4 ++-- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 9e1a0a0d7a49..377dee7d631e 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1013,6 +1013,17 @@ def collect(self, item: Item, prevent_sweep: bool = False, location: Optional[Lo return changed + def add_item(self, item: str, player: int, count: int = 1) -> None: + """ + Adds the item to state. + + :param item: The item to be added. + :param player: The player the item is for. + :param count: How many of the item to add. + """ + assert count > 0 + self.prog_items[player][item] += count + def remove(self, item: Item): changed = self.multiworld.worlds[item.player].remove(self, item) if changed: @@ -1021,6 +1032,33 @@ def remove(self, item: Item): self.blocked_connections[item.player] = set() self.stale[item.player] = True + def remove_item(self, item: str, player: int, count: int = 1) -> None: + """ + Removes the item from state. + + :param item: The item to be removed. + :param player: The player the item is for. + :param count: How many of the item to remove. + """ + assert count > 0 + self.prog_items[player][item] -= count + if self.prog_items[player][item] < 1: + del (self.prog_items[player][item]) + + def set_item(self, item: str, player: int, count: int) -> None: + """ + Sets the item in state equal to the provided count. + + :param item: The item to modify. + :param player: The player the item is for. + :param count: How many of the item to now have. + """ + assert count >= 0 + if count == 0: + del (self.prog_items[player][item]) + else: + self.prog_items[player][item] = count + class EntranceType(IntEnum): ONE_WAY = 1 diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index f0004a9f1b5b..6ea6c237d970 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -528,7 +528,7 @@ def collect(self, state: "CollectionState", item: "Item") -> bool: """Called when an item is collected in to state. Useful for things such as progressive items or currency.""" name = self.collect_item(state, item) if name: - state.prog_items[self.player][name] += 1 + state.add_item(name, self.player) return True return False @@ -536,9 +536,7 @@ def remove(self, state: "CollectionState", item: "Item") -> bool: """Called when an item is removed from to state. Useful for things such as progressive items or currency.""" name = self.collect_item(state, item, True) if name: - state.prog_items[self.player][name] -= 1 - if state.prog_items[self.player][name] < 1: - del (state.prog_items[self.player][name]) + state.remove_item(name, self.player) return True return False diff --git a/worlds/messenger/__init__.py b/worlds/messenger/__init__.py index 4e2c870dae8f..8df59d9b2942 100644 --- a/worlds/messenger/__init__.py +++ b/worlds/messenger/__init__.py @@ -428,13 +428,13 @@ def create_group(cls, multiworld: "MultiWorld", new_player_id: int, players: set def collect(self, state: "CollectionState", item: "Item") -> bool: change = super().collect(state, item) if change and "Time Shard" in item.name: - state.prog_items[self.player]["Shards"] += int(item.name.strip("Time Shard ()")) + state.add_item("Shards", self.player, int(item.name.strip("Time Shard ()"))) return change def remove(self, state: "CollectionState", item: "Item") -> bool: change = super().remove(state, item) if change and "Time Shard" in item.name: - state.prog_items[self.player]["Shards"] -= int(item.name.strip("Time Shard ()")) + state.remove_item("Shards", self.player, int(item.name.strip("Time Shard ()"))) return change @classmethod From 45e3027f81fc0eba4ccd06b5e1ed1f3a1597a38d Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 22 May 2025 09:06:44 -0500 Subject: [PATCH 0454/1218] The Messenger: Add a Component Icon and Description (#4850) Co-authored-by: qwint Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/messenger/__init__.py | 13 +++++++++++-- worlds/messenger/assets/component_icon.png | Bin 0 -> 19691 bytes 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 worlds/messenger/assets/component_icon.png diff --git a/worlds/messenger/__init__.py b/worlds/messenger/__init__.py index 8df59d9b2942..e403ff59d862 100644 --- a/worlds/messenger/__init__.py +++ b/worlds/messenger/__init__.py @@ -6,7 +6,7 @@ from Utils import output_path from settings import FilePath, Group from worlds.AutoWorld import WebWorld, World -from worlds.LauncherComponents import Component, Type, components +from worlds.LauncherComponents import Component, Type, components, icon_paths from .client_setup import launch_game from .connections import CONNECTIONS, RANDOMIZED_CONNECTIONS, TRANSITIONS from .constants import ALL_ITEMS, ALWAYS_LOCATIONS, BOSS_LOCATIONS, FILLER, NOTES, PHOBEKINS, PROG_ITEMS, TRAPS, \ @@ -20,9 +20,18 @@ from .transitions import disconnect_entrances, shuffle_transitions components.append( - Component("The Messenger", component_type=Type.CLIENT, func=launch_game, game_name="The Messenger", supports_uri=True) + Component( + "The Messenger", + component_type=Type.CLIENT, + func=launch_game, + game_name="The Messenger", + supports_uri=True, + icon="The Messenger", + description="Launch The Messenger.\nInstalls and checks for updates for the randomizer.") ) +icon_paths["The Messenger"] = f"ap:{__name__}/assets/component_icon.png" + class MessengerSettings(Group): class GamePath(FilePath): diff --git a/worlds/messenger/assets/component_icon.png b/worlds/messenger/assets/component_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5ee91224ca069e806a7b976a3dbdcc55026390ae GIT binary patch literal 19691 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 Date: Thu, 22 May 2025 15:16:16 +0100 Subject: [PATCH 0455/1218] AHiT: Add Dweller Mask Requirement to Normal Logic Rush Hour (#4499) --- worlds/ahit/Locations.py | 2 +- worlds/ahit/Rules.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/ahit/Locations.py b/worlds/ahit/Locations.py index 713113e6919b..9937c774d1c8 100644 --- a/worlds/ahit/Locations.py +++ b/worlds/ahit/Locations.py @@ -477,7 +477,7 @@ def get_location_names() -> Dict[str, int]: "Act Completion (Rush Hour)": LocData(2000311210, "Rush Hour", dlc_flags=HatDLC.dlc2, hookshot=True, - required_hats=[HatType.ICE, HatType.BREWING]), + required_hats=[HatType.ICE, HatType.BREWING, HatType.DWELLER]), "Act Completion (Time Rift - Rumbi Factory)": LocData(2000312736, "Time Rift - Rumbi Factory", dlc_flags=HatDLC.dlc2), diff --git a/worlds/ahit/Rules.py b/worlds/ahit/Rules.py index 2ca0628a6875..1c2c5845dbda 100644 --- a/worlds/ahit/Rules.py +++ b/worlds/ahit/Rules.py @@ -455,7 +455,7 @@ def set_moderate_rules(world: "HatInTimeWorld"): if "Pink Paw Station Thug" in key and is_location_valid(world, key): set_rule(world.multiworld.get_location(key, world.player), lambda state: True) - # Moderate: clear Rush Hour without Hookshot + # Moderate: clear Rush Hour without Hookshot or Dweller Mask set_rule(world.multiworld.get_location("Act Completion (Rush Hour)", world.player), lambda state: state.has("Metro Ticket - Pink", world.player) and state.has("Metro Ticket - Yellow", world.player) From 984df75f837044aa55168816109ea284efba52f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Thu, 22 May 2025 10:24:04 -0400 Subject: [PATCH 0456/1218] Stardew Valley: Move and Rework Monstersanity Tests (#4911) --- worlds/stardew_valley/test/TestGeneration.py | 159 ------------------ .../stardew_valley/test/TestMonstersanity.py | 132 +++++++++++++++ 2 files changed, 132 insertions(+), 159 deletions(-) create mode 100644 worlds/stardew_valley/test/TestMonstersanity.py diff --git a/worlds/stardew_valley/test/TestGeneration.py b/worlds/stardew_valley/test/TestGeneration.py index 1e843ea69094..5e60f8e80abb 100644 --- a/worlds/stardew_valley/test/TestGeneration.py +++ b/worlds/stardew_valley/test/TestGeneration.py @@ -120,165 +120,6 @@ def test_does_not_create_exactly_two_items(self): self.assertTrue(count == 0 or count == 2) -class TestMonstersanityNone(SVTestBase): - options = { - options.Monstersanity.internal_name: options.Monstersanity.option_none, - # Not really necessary, but it adds more locations, so we don't have to remove useful items. - options.Fishsanity.internal_name: options.Fishsanity.option_all - } - - @property - def run_default_tests(self) -> bool: - # None is default - return False - - def test_when_generate_world_then_5_generic_weapons_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Weapon"), 5) - - def test_when_generate_world_then_zero_specific_weapons_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Sword"), 0) - self.assertEqual(item_pool.count("Progressive Club"), 0) - self.assertEqual(item_pool.count("Progressive Dagger"), 0) - - def test_when_generate_world_then_2_slingshots_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Slingshot"), 2) - - def test_when_generate_world_then_3_shoes_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Footwear"), 3) - - -class TestMonstersanityGoals(SVTestBase): - options = {options.Monstersanity.internal_name: options.Monstersanity.option_goals} - - def test_when_generate_world_then_no_generic_weapons_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Weapon"), 0) - - def test_when_generate_world_then_5_specific_weapons_of_each_type_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Sword"), 5) - self.assertEqual(item_pool.count("Progressive Club"), 5) - self.assertEqual(item_pool.count("Progressive Dagger"), 5) - - def test_when_generate_world_then_2_slingshots_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Slingshot"), 2) - - def test_when_generate_world_then_4_shoes_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Footwear"), 4) - - def test_when_generate_world_then_all_monster_checks_are_inaccessible(self): - for location in self.get_real_locations(): - if LocationTags.MONSTERSANITY not in location_table[location.name].tags: - continue - with self.subTest(location.name): - self.assertFalse(location.can_reach(self.multiworld.state)) - - -class TestMonstersanityOnePerCategory(SVTestBase): - options = {options.Monstersanity.internal_name: options.Monstersanity.option_one_per_category} - - def test_when_generate_world_then_no_generic_weapons_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Weapon"), 0) - - def test_when_generate_world_then_5_specific_weapons_of_each_type_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Sword"), 5) - self.assertEqual(item_pool.count("Progressive Club"), 5) - self.assertEqual(item_pool.count("Progressive Dagger"), 5) - - def test_when_generate_world_then_2_slingshots_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Slingshot"), 2) - - def test_when_generate_world_then_4_shoes_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Footwear"), 4) - - def test_when_generate_world_then_all_monster_checks_are_inaccessible(self): - for location in self.get_real_locations(): - if LocationTags.MONSTERSANITY not in location_table[location.name].tags: - continue - with self.subTest(location.name): - self.assertFalse(location.can_reach(self.multiworld.state)) - - -class TestMonstersanityProgressive(SVTestBase): - options = {options.Monstersanity.internal_name: options.Monstersanity.option_progressive_goals} - - def test_when_generate_world_then_no_generic_weapons_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Weapon"), 0) - - def test_when_generate_world_then_5_specific_weapons_of_each_type_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Sword"), 5) - self.assertEqual(item_pool.count("Progressive Club"), 5) - self.assertEqual(item_pool.count("Progressive Dagger"), 5) - - def test_when_generate_world_then_2_slingshots_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Slingshot"), 2) - - def test_when_generate_world_then_4_shoes_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Footwear"), 4) - - def test_when_generate_world_then_many_rings_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertIn("Hot Java Ring", item_pool) - self.assertIn("Wedding Ring", item_pool) - self.assertIn("Slime Charmer Ring", item_pool) - - def test_when_generate_world_then_all_monster_checks_are_inaccessible(self): - for location in self.get_real_locations(): - if LocationTags.MONSTERSANITY not in location_table[location.name].tags: - continue - with self.subTest(location.name): - self.assertFalse(location.can_reach(self.multiworld.state)) - - -class TestMonstersanitySplit(SVTestBase): - options = {options.Monstersanity.internal_name: options.Monstersanity.option_split_goals} - - def test_when_generate_world_then_no_generic_weapons_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Weapon"), 0) - - def test_when_generate_world_then_5_specific_weapons_of_each_type_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Sword"), 5) - self.assertEqual(item_pool.count("Progressive Club"), 5) - self.assertEqual(item_pool.count("Progressive Dagger"), 5) - - def test_when_generate_world_then_2_slingshots_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Slingshot"), 2) - - def test_when_generate_world_then_4_shoes_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertEqual(item_pool.count("Progressive Footwear"), 4) - - def test_when_generate_world_then_many_rings_in_the_pool(self): - item_pool = [item.name for item in self.multiworld.itempool] - self.assertIn("Hot Java Ring", item_pool) - self.assertIn("Wedding Ring", item_pool) - self.assertIn("Slime Charmer Ring", item_pool) - - def test_when_generate_world_then_all_monster_checks_are_inaccessible(self): - for location in self.get_real_locations(): - if LocationTags.MONSTERSANITY not in location_table[location.name].tags: - continue - with self.subTest(location.name): - self.assertFalse(location.can_reach(self.multiworld.state)) - - class TestProgressiveElevator(SVTestBase): options = { options.ElevatorProgression.internal_name: options.ElevatorProgression.option_progressive, diff --git a/worlds/stardew_valley/test/TestMonstersanity.py b/worlds/stardew_valley/test/TestMonstersanity.py new file mode 100644 index 000000000000..8393715474fb --- /dev/null +++ b/worlds/stardew_valley/test/TestMonstersanity.py @@ -0,0 +1,132 @@ +import unittest +from typing import ClassVar + +from . import SVTestBase +from .. import options +from ..locations import LocationTags, location_table +from ..mods.mod_data import ModNames + + +class SVMonstersanityTestBase(SVTestBase): + expected_progressive_generic_weapon: ClassVar[int] = 0 + expected_progressive_specific_weapon: ClassVar[int] = 0 + expected_progressive_slingshot: ClassVar[int] = 0 + expected_progressive_footwear: ClassVar[int] = 0 + expected_rings: ClassVar[list[str]] = [] + + @classmethod + def setUpClass(cls) -> None: + if cls is SVMonstersanityTestBase: + raise unittest.SkipTest("Base tests disabled") + + super().setUpClass() + + def test_when_generate_world_then_expected_generic_weapons_in_the_pool(self): + item_pool = [item.name for item in self.multiworld.itempool] + self.assertEqual(item_pool.count("Progressive Weapon"), self.expected_progressive_generic_weapon) + + def test_when_generate_world_then_expected_specific_weapons_in_the_pool(self): + item_pool = [item.name for item in self.multiworld.itempool] + self.assertEqual(item_pool.count("Progressive Sword"), self.expected_progressive_specific_weapon) + self.assertEqual(item_pool.count("Progressive Club"), self.expected_progressive_specific_weapon) + self.assertEqual(item_pool.count("Progressive Dagger"), self.expected_progressive_specific_weapon) + + def test_when_generate_world_then_expected_slingshots_in_the_pool(self): + item_pool = [item.name for item in self.multiworld.itempool] + self.assertEqual(item_pool.count("Progressive Slingshot"), self.expected_progressive_slingshot) + + def test_when_generate_world_then_expected_shoes_in_the_pool(self): + item_pool = [item.name for item in self.multiworld.itempool] + self.assertEqual(item_pool.count("Progressive Footwear"), self.expected_progressive_footwear) + + def test_when_generate_world_then_many_rings_in_the_pool(self): + item_pool = [item.name for item in self.multiworld.itempool] + for expected_ring in self.expected_rings: + self.assertIn(expected_ring, item_pool) + + def test_when_generate_world_then_all_monster_checks_are_inaccessible_with_empty_inventory(self): + for location in self.get_real_locations(): + if LocationTags.MONSTERSANITY not in location_table[location.name].tags: + continue + with self.subTest(location.name): + self.assert_cannot_reach_location(location.name) + + +class TestMonstersanityNone(SVMonstersanityTestBase): + options = { + options.Monstersanity: options.Monstersanity.option_none, + # Not really necessary, but it adds more locations, so we don't have to remove useful items. + options.Fishsanity: options.Fishsanity.option_all, + } + expected_progressive_generic_weapon = 5 + expected_progressive_slingshot = 2 + expected_progressive_footwear = 3 + + @property + def run_default_tests(self) -> bool: + # None is default + return False + + +class TestMonstersanityNoneWithSVE(SVMonstersanityTestBase): + options = { + options.Monstersanity: options.Monstersanity.option_none, + options.Mods: ModNames.sve, + } + expected_progressive_generic_weapon = 6 + expected_progressive_slingshot = 2 + expected_progressive_footwear = 3 + + @property + def run_default_tests(self) -> bool: + # None is default + return False + + +class TestMonstersanityGoals(SVMonstersanityTestBase): + options = { + options.Monstersanity: options.Monstersanity.option_goals, + } + expected_progressive_specific_weapon = 5 + expected_progressive_slingshot = 2 + expected_progressive_footwear = 4 + + +class TestMonstersanityOnePerCategory(SVMonstersanityTestBase): + options = { + options.Monstersanity: options.Monstersanity.option_one_per_category, + } + expected_progressive_specific_weapon = 5 + expected_progressive_slingshot = 2 + expected_progressive_footwear = 4 + + +class TestMonstersanityProgressive(SVMonstersanityTestBase): + options = { + options.Monstersanity: options.Monstersanity.option_progressive_goals, + } + expected_progressive_specific_weapon = 5 + expected_progressive_slingshot = 2 + expected_progressive_footwear = 4 + expected_rings = ["Hot Java Ring", "Wedding Ring", "Slime Charmer Ring"] + + +class TestMonstersanitySplit(SVMonstersanityTestBase): + options = { + options.Monstersanity: options.Monstersanity.option_split_goals, + } + expected_progressive_specific_weapon = 5 + expected_progressive_slingshot = 2 + expected_progressive_footwear = 4 + expected_rings = ["Hot Java Ring", "Wedding Ring", "Slime Charmer Ring"] + + +class TestMonstersanitySplitWithSVE(SVMonstersanityTestBase): + options = { + options.Monstersanity: options.Monstersanity.option_split_goals, + options.Mods: ModNames.sve, + } + expected_progressive_specific_weapon = 6 + expected_progressive_slingshot = 2 + expected_progressive_footwear = 4 + expected_rings = ["Hot Java Ring", "Wedding Ring", "Slime Charmer Ring"] From 0351698ef71f3aa7b8fe178a6517c69e93e49053 Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Thu, 22 May 2025 11:07:57 -0400 Subject: [PATCH 0457/1218] SDV: Fixed Import bases (#5025) --- worlds/stardew_valley/test/TestMonstersanity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/stardew_valley/test/TestMonstersanity.py b/worlds/stardew_valley/test/TestMonstersanity.py index 8393715474fb..dd058274326f 100644 --- a/worlds/stardew_valley/test/TestMonstersanity.py +++ b/worlds/stardew_valley/test/TestMonstersanity.py @@ -1,7 +1,7 @@ import unittest from typing import ClassVar -from . import SVTestBase +from .bases import SVTestBase from .. import options from ..locations import LocationTags, location_table from ..mods.mod_data import ModNames From 88b529593f655084b64040b731ad57a93a243e5a Mon Sep 17 00:00:00 2001 From: qwint Date: Thu, 22 May 2025 10:08:15 -0500 Subject: [PATCH 0458/1218] CommonClient: Add docs for Attributes (#5003) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- CommonClient.py | 75 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index 94c558bf8aec..3a5f51aeee33 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -266,38 +266,71 @@ def update_game(self, game: str, name_to_id_lookup_table: typing.Dict[str, int]) last_death_link: float = time.time() # last send/received death link on AP layer # remaining type info - slot_info: typing.Dict[int, NetworkSlot] - server_address: typing.Optional[str] - password: typing.Optional[str] - hint_cost: typing.Optional[int] - hint_points: typing.Optional[int] - player_names: typing.Dict[int, str] + slot_info: dict[int, NetworkSlot] + """Slot Info from the server for the current connection""" + server_address: str | None + """Autoconnect address provided by the ctx constructor""" + password: str | None + """Password used for Connecting, expected by server_auth""" + hint_cost: int | None + """Current Hint Cost per Hint from the server""" + hint_points: int | None + """Current avaliable Hint Points from the server""" + player_names: dict[int, str] + """Current lookup of slot number to player display name from server (includes aliases)""" finished_game: bool + """ + Bool to signal that status should be updated to Goal after reconnecting + to be used to ensure that a StatusUpdate packet does not get lost when disconnected + """ ready: bool - team: typing.Optional[int] - slot: typing.Optional[int] - auth: typing.Optional[str] - seed_name: typing.Optional[str] + """Bool to keep track of state for the /ready command""" + team: int | None + """Team number of currently connected slot""" + slot: int | None + """Slot number of currently connected slot""" + auth: str | None + """Name used in Connect packet""" + seed_name: str | None + """Seed name that will be validated on opening a socket if present""" # locations - locations_checked: typing.Set[int] # local state - locations_scouted: typing.Set[int] - items_received: typing.List[NetworkItem] - missing_locations: typing.Set[int] # server state - checked_locations: typing.Set[int] # server state - server_locations: typing.Set[int] # all locations the server knows of, missing_location | checked_locations - locations_info: typing.Dict[int, NetworkItem] + locations_checked: set[int] + """ + Local container of location ids checked to signal that LocationChecks should be resent after reconnecting + to be used to ensure that a LocationChecks packet does not get lost when disconnected + """ + locations_scouted: set[int] + """ + Local container of location ids scouted to signal that LocationScouts should be resent after reconnecting + to be used to ensure that a LocationScouts packet does not get lost when disconnected + """ + items_received: list[NetworkItem] + """List of NetworkItems recieved from the server""" + missing_locations: set[int] + """Container of Locations that are unchecked per server state""" + checked_locations: set[int] + """Container of Locations that are checked per server state""" + server_locations: set[int] + """Container of Locations that exist per server state; a combination between missing and checked locations""" + locations_info: dict[int, NetworkItem] + """Dict of location id: NetworkItem info from LocationScouts request""" # data storage - stored_data: typing.Dict[str, typing.Any] - stored_data_notification_keys: typing.Set[str] + stored_data: dict[str, typing.Any] + """ + Data Storage values by key that were retrieved from the server + any keys subscribed to with SetNotify will be kept up to date + """ + stored_data_notification_keys: set[str] + """Current container of watched Data Storage keys, managed by ctx.set_notify""" # internals - # current message box through kvui _messagebox: typing.Optional["kvui.MessageBox"] = None - # message box reporting a loss of connection + """Current message box through kvui""" _messagebox_connection_loss: typing.Optional["kvui.MessageBox"] = None + """Message box reporting a loss of connection""" def __init__(self, server_address: typing.Optional[str] = None, password: typing.Optional[str] = None) -> None: # server state From 9c0ad2b825ac3f95216a34b529291e3a1c02b8c1 Mon Sep 17 00:00:00 2001 From: Rosalie <61372066+Rosalie-A@users.noreply.github.com> Date: Thu, 22 May 2025 11:35:38 -0400 Subject: [PATCH 0459/1218] FF1: Bizhawk Client and APWorld Support (#4448) Co-authored-by: beauxq Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- FF1Client.py | 267 ---------------- data/lua/connector_ff1.lua | 462 ---------------------------- inno_setup.iss | 1 + setup.py | 1 - worlds/LauncherComponents.py | 2 - worlds/ff1/Client.py | 328 ++++++++++++++++++++ worlds/ff1/Items.py | 18 +- worlds/ff1/Locations.py | 14 +- worlds/ff1/__init__.py | 1 + worlds/ff1/docs/en_Final Fantasy.md | 9 +- worlds/ff1/docs/multiworld_en.md | 25 +- 11 files changed, 356 insertions(+), 772 deletions(-) delete mode 100644 FF1Client.py delete mode 100644 data/lua/connector_ff1.lua create mode 100644 worlds/ff1/Client.py diff --git a/FF1Client.py b/FF1Client.py deleted file mode 100644 index 748a95b72cf4..000000000000 --- a/FF1Client.py +++ /dev/null @@ -1,267 +0,0 @@ -import asyncio -import copy -import json -import time -from asyncio import StreamReader, StreamWriter -from typing import List - - -import Utils -from Utils import async_start -from CommonClient import CommonContext, server_loop, gui_enabled, ClientCommandProcessor, logger, \ - get_base_parser - -SYSTEM_MESSAGE_ID = 0 - -CONNECTION_TIMING_OUT_STATUS = "Connection timing out. Please restart your emulator, then restart connector_ff1.lua" -CONNECTION_REFUSED_STATUS = "Connection Refused. Please start your emulator and make sure connector_ff1.lua is running" -CONNECTION_RESET_STATUS = "Connection was reset. Please restart your emulator, then restart connector_ff1.lua" -CONNECTION_TENTATIVE_STATUS = "Initial Connection Made" -CONNECTION_CONNECTED_STATUS = "Connected" -CONNECTION_INITIAL_STATUS = "Connection has not been initiated" - -DISPLAY_MSGS = True - - -class FF1CommandProcessor(ClientCommandProcessor): - def __init__(self, ctx: CommonContext): - super().__init__(ctx) - - def _cmd_nes(self): - """Check NES Connection State""" - if isinstance(self.ctx, FF1Context): - logger.info(f"NES Status: {self.ctx.nes_status}") - - def _cmd_toggle_msgs(self): - """Toggle displaying messages in EmuHawk""" - global DISPLAY_MSGS - DISPLAY_MSGS = not DISPLAY_MSGS - logger.info(f"Messages are now {'enabled' if DISPLAY_MSGS else 'disabled'}") - - -class FF1Context(CommonContext): - command_processor = FF1CommandProcessor - game = 'Final Fantasy' - items_handling = 0b111 # full remote - - def __init__(self, server_address, password): - super().__init__(server_address, password) - self.nes_streams: (StreamReader, StreamWriter) = None - self.nes_sync_task = None - self.messages = {} - self.locations_array = None - self.nes_status = CONNECTION_INITIAL_STATUS - self.awaiting_rom = False - self.display_msgs = True - - async def server_auth(self, password_requested: bool = False): - if password_requested and not self.password: - await super(FF1Context, self).server_auth(password_requested) - if not self.auth: - self.awaiting_rom = True - logger.info('Awaiting connection to NES to get Player information') - return - - await self.send_connect() - - def _set_message(self, msg: str, msg_id: int): - if DISPLAY_MSGS: - self.messages[time.time(), msg_id] = msg - - def on_package(self, cmd: str, args: dict): - if cmd == 'Connected': - async_start(parse_locations(self.locations_array, self, True)) - elif cmd == 'Print': - msg = args['text'] - if ': !' not in msg: - self._set_message(msg, SYSTEM_MESSAGE_ID) - - def on_print_json(self, args: dict): - if self.ui: - self.ui.print_json(copy.deepcopy(args["data"])) - else: - text = self.jsontotextparser(copy.deepcopy(args["data"])) - logger.info(text) - relevant = args.get("type", None) in {"Hint", "ItemSend"} - if relevant: - item = args["item"] - # goes to this world - if self.slot_concerns_self(args["receiving"]): - relevant = True - # found in this world - elif self.slot_concerns_self(item.player): - relevant = True - # not related - else: - relevant = False - if relevant: - item = args["item"] - msg = self.raw_text_parser(copy.deepcopy(args["data"])) - self._set_message(msg, item.item) - - def run_gui(self): - from kvui import GameManager - - class FF1Manager(GameManager): - logging_pairs = [ - ("Client", "Archipelago") - ] - base_title = "Archipelago Final Fantasy 1 Client" - - self.ui = FF1Manager(self) - self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI") - - -def get_payload(ctx: FF1Context): - current_time = time.time() - return json.dumps( - { - "items": [item.item for item in ctx.items_received], - "messages": {f'{key[0]}:{key[1]}': value for key, value in ctx.messages.items() - if key[0] > current_time - 10} - } - ) - - -async def parse_locations(locations_array: List[int], ctx: FF1Context, force: bool): - if locations_array == ctx.locations_array and not force: - return - else: - # print("New values") - ctx.locations_array = locations_array - locations_checked = [] - if len(locations_array) > 0xFE and locations_array[0xFE] & 0x02 != 0 and not ctx.finished_game: - await ctx.send_msgs([ - {"cmd": "StatusUpdate", - "status": 30} - ]) - ctx.finished_game = True - for location in ctx.missing_locations: - # index will be - 0x100 or 0x200 - index = location - if location < 0x200: - # Location is a chest - index -= 0x100 - flag = 0x04 - else: - # Location is an NPC - index -= 0x200 - flag = 0x02 - - # print(f"Location: {ctx.location_names[location]}") - # print(f"Index: {str(hex(index))}") - # print(f"value: {locations_array[index] & flag != 0}") - if locations_array[index] & flag != 0: - locations_checked.append(location) - if locations_checked: - # print([ctx.location_names[location] for location in locations_checked]) - await ctx.send_msgs([ - {"cmd": "LocationChecks", - "locations": locations_checked} - ]) - - -async def nes_sync_task(ctx: FF1Context): - logger.info("Starting nes connector. Use /nes for status information") - while not ctx.exit_event.is_set(): - error_status = None - if ctx.nes_streams: - (reader, writer) = ctx.nes_streams - msg = get_payload(ctx).encode() - writer.write(msg) - writer.write(b'\n') - try: - await asyncio.wait_for(writer.drain(), timeout=1.5) - try: - # Data will return a dict with up to two fields: - # 1. A keepalive response of the Players Name (always) - # 2. An array representing the memory values of the locations area (if in game) - data = await asyncio.wait_for(reader.readline(), timeout=5) - data_decoded = json.loads(data.decode()) - # print(data_decoded) - if ctx.game is not None and 'locations' in data_decoded: - # Not just a keep alive ping, parse - async_start(parse_locations(data_decoded['locations'], ctx, False)) - if not ctx.auth: - ctx.auth = ''.join([chr(i) for i in data_decoded['playerName'] if i != 0]) - if ctx.auth == '': - logger.info("Invalid ROM detected. No player name built into the ROM. Please regenerate" - "the ROM using the same link but adding your slot name") - if ctx.awaiting_rom: - await ctx.server_auth(False) - except asyncio.TimeoutError: - logger.debug("Read Timed Out, Reconnecting") - error_status = CONNECTION_TIMING_OUT_STATUS - writer.close() - ctx.nes_streams = None - except ConnectionResetError as e: - logger.debug("Read failed due to Connection Lost, Reconnecting") - error_status = CONNECTION_RESET_STATUS - writer.close() - ctx.nes_streams = None - except TimeoutError: - logger.debug("Connection Timed Out, Reconnecting") - error_status = CONNECTION_TIMING_OUT_STATUS - writer.close() - ctx.nes_streams = None - except ConnectionResetError: - logger.debug("Connection Lost, Reconnecting") - error_status = CONNECTION_RESET_STATUS - writer.close() - ctx.nes_streams = None - if ctx.nes_status == CONNECTION_TENTATIVE_STATUS: - if not error_status: - logger.info("Successfully Connected to NES") - ctx.nes_status = CONNECTION_CONNECTED_STATUS - else: - ctx.nes_status = f"Was tentatively connected but error occured: {error_status}" - elif error_status: - ctx.nes_status = error_status - logger.info("Lost connection to nes and attempting to reconnect. Use /nes for status updates") - else: - try: - logger.debug("Attempting to connect to NES") - ctx.nes_streams = await asyncio.wait_for(asyncio.open_connection("localhost", 52980), timeout=10) - ctx.nes_status = CONNECTION_TENTATIVE_STATUS - except TimeoutError: - logger.debug("Connection Timed Out, Trying Again") - ctx.nes_status = CONNECTION_TIMING_OUT_STATUS - continue - except ConnectionRefusedError: - logger.debug("Connection Refused, Trying Again") - ctx.nes_status = CONNECTION_REFUSED_STATUS - continue - - -if __name__ == '__main__': - # Text Mode to use !hint and such with games that have no text entry - Utils.init_logging("FF1Client") - - options = Utils.get_options() - DISPLAY_MSGS = options["ffr_options"]["display_msgs"] - - async def main(args): - ctx = FF1Context(args.connect, args.password) - ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop") - if gui_enabled: - ctx.run_gui() - ctx.run_cli() - ctx.nes_sync_task = asyncio.create_task(nes_sync_task(ctx), name="NES Sync") - - await ctx.exit_event.wait() - ctx.server_address = None - - await ctx.shutdown() - - if ctx.nes_sync_task: - await ctx.nes_sync_task - - - import colorama - - parser = get_base_parser() - args = parser.parse_args() - colorama.just_fix_windows_console() - - asyncio.run(main(args)) - colorama.deinit() diff --git a/data/lua/connector_ff1.lua b/data/lua/connector_ff1.lua deleted file mode 100644 index afae5d3c81dc..000000000000 --- a/data/lua/connector_ff1.lua +++ /dev/null @@ -1,462 +0,0 @@ -local socket = require("socket") -local json = require('json') -local math = require('math') -require("common") - -local STATE_OK = "Ok" -local STATE_TENTATIVELY_CONNECTED = "Tentatively Connected" -local STATE_INITIAL_CONNECTION_MADE = "Initial Connection Made" -local STATE_UNINITIALIZED = "Uninitialized" - -local ITEM_INDEX = 0x03 -local WEAPON_INDEX = 0x07 -local ARMOR_INDEX = 0x0B - -local goldLookup = { - [0x16C] = 10, - [0x16D] = 20, - [0x16E] = 25, - [0x16F] = 30, - [0x170] = 55, - [0x171] = 70, - [0x172] = 85, - [0x173] = 110, - [0x174] = 135, - [0x175] = 155, - [0x176] = 160, - [0x177] = 180, - [0x178] = 240, - [0x179] = 255, - [0x17A] = 260, - [0x17B] = 295, - [0x17C] = 300, - [0x17D] = 315, - [0x17E] = 330, - [0x17F] = 350, - [0x180] = 385, - [0x181] = 400, - [0x182] = 450, - [0x183] = 500, - [0x184] = 530, - [0x185] = 575, - [0x186] = 620, - [0x187] = 680, - [0x188] = 750, - [0x189] = 795, - [0x18A] = 880, - [0x18B] = 1020, - [0x18C] = 1250, - [0x18D] = 1455, - [0x18E] = 1520, - [0x18F] = 1760, - [0x190] = 1975, - [0x191] = 2000, - [0x192] = 2750, - [0x193] = 3400, - [0x194] = 4150, - [0x195] = 5000, - [0x196] = 5450, - [0x197] = 6400, - [0x198] = 6720, - [0x199] = 7340, - [0x19A] = 7690, - [0x19B] = 7900, - [0x19C] = 8135, - [0x19D] = 9000, - [0x19E] = 9300, - [0x19F] = 9500, - [0x1A0] = 9900, - [0x1A1] = 10000, - [0x1A2] = 12350, - [0x1A3] = 13000, - [0x1A4] = 13450, - [0x1A5] = 14050, - [0x1A6] = 14720, - [0x1A7] = 15000, - [0x1A8] = 17490, - [0x1A9] = 18010, - [0x1AA] = 19990, - [0x1AB] = 20000, - [0x1AC] = 20010, - [0x1AD] = 26000, - [0x1AE] = 45000, - [0x1AF] = 65000 -} - -local extensionConsumableLookup = { - [432] = 0x3C, - [436] = 0x3C, - [440] = 0x3C, - [433] = 0x3D, - [437] = 0x3D, - [441] = 0x3D, - [434] = 0x3E, - [438] = 0x3E, - [442] = 0x3E, - [435] = 0x3F, - [439] = 0x3F, - [443] = 0x3F -} - -local noOverworldItemsLookup = { - [499] = 0x2B, - [500] = 0x12, -} - -local consumableStacks = nil -local prevstate = "" -local curstate = STATE_UNINITIALIZED -local ff1Socket = nil -local frame = 0 - -local isNesHawk = false - - ---Sets correct memory access functions based on whether NesHawk or QuickNES is loaded -local function defineMemoryFunctions() - local memDomain = {} - local domains = memory.getmemorydomainlist() - if domains[1] == "System Bus" then - --NesHawk - isNesHawk = true - memDomain["systembus"] = function() memory.usememorydomain("System Bus") end - memDomain["saveram"] = function() memory.usememorydomain("Battery RAM") end - memDomain["rom"] = function() memory.usememorydomain("PRG ROM") end - elseif domains[1] == "WRAM" then - --QuickNES - memDomain["systembus"] = function() memory.usememorydomain("System Bus") end - memDomain["saveram"] = function() memory.usememorydomain("WRAM") end - memDomain["rom"] = function() memory.usememorydomain("PRG ROM") end - end - return memDomain -end - -local memDomain = defineMemoryFunctions() - -local function StateOKForMainLoop() - memDomain.saveram() - local A = u8(0x102) -- Party Made - local B = u8(0x0FC) - local C = u8(0x0A3) - return A ~= 0x00 and not (A== 0xF2 and B == 0xF2 and C == 0xF2) -end - -function generateLocationChecked() - memDomain.saveram() - data = uRange(0x01FF, 0x101) - data[0] = nil - return data -end - -function setConsumableStacks() - memDomain.rom() - consumableStacks = {} - -- In order shards, tent, cabin, house, heal, pure, soft, ext1, ext2, ext3, ex4 - consumableStacks[0x35] = 1 - consumableStacks[0x36] = u8(0x47400) + 1 - consumableStacks[0x37] = u8(0x47401) + 1 - consumableStacks[0x38] = u8(0x47402) + 1 - consumableStacks[0x39] = u8(0x47403) + 1 - consumableStacks[0x3A] = u8(0x47404) + 1 - consumableStacks[0x3B] = u8(0x47405) + 1 - consumableStacks[0x3C] = u8(0x47406) + 1 - consumableStacks[0x3D] = u8(0x47407) + 1 - consumableStacks[0x3E] = u8(0x47408) + 1 - consumableStacks[0x3F] = u8(0x47409) + 1 -end - -function getEmptyWeaponSlots() - memDomain.saveram() - ret = {} - count = 1 - slot1 = uRange(0x118, 0x4) - slot2 = uRange(0x158, 0x4) - slot3 = uRange(0x198, 0x4) - slot4 = uRange(0x1D8, 0x4) - for i,v in pairs(slot1) do - if v == 0 then - ret[count] = 0x118 + i - count = count + 1 - end - end - for i,v in pairs(slot2) do - if v == 0 then - ret[count] = 0x158 + i - count = count + 1 - end - end - for i,v in pairs(slot3) do - if v == 0 then - ret[count] = 0x198 + i - count = count + 1 - end - end - for i,v in pairs(slot4) do - if v == 0 then - ret[count] = 0x1D8 + i - count = count + 1 - end - end - return ret -end - -function getEmptyArmorSlots() - memDomain.saveram() - ret = {} - count = 1 - slot1 = uRange(0x11C, 0x4) - slot2 = uRange(0x15C, 0x4) - slot3 = uRange(0x19C, 0x4) - slot4 = uRange(0x1DC, 0x4) - for i,v in pairs(slot1) do - if v == 0 then - ret[count] = 0x11C + i - count = count + 1 - end - end - for i,v in pairs(slot2) do - if v == 0 then - ret[count] = 0x15C + i - count = count + 1 - end - end - for i,v in pairs(slot3) do - if v == 0 then - ret[count] = 0x19C + i - count = count + 1 - end - end - for i,v in pairs(slot4) do - if v == 0 then - ret[count] = 0x1DC + i - count = count + 1 - end - end - return ret -end -local function slice (tbl, s, e) - local pos, new = 1, {} - for i = s + 1, e do - new[pos] = tbl[i] - pos = pos + 1 - end - return new -end -function processBlock(block) - local msgBlock = block['messages'] - if msgBlock ~= nil then - for i, v in pairs(msgBlock) do - if itemMessages[i] == nil then - local msg = {TTL=450, message=v, color=0xFFFF0000} - itemMessages[i] = msg - end - end - end - local itemsBlock = block["items"] - memDomain.saveram() - isInGame = u8(0x102) - if itemsBlock ~= nil and isInGame ~= 0x00 then - if consumableStacks == nil then - setConsumableStacks() - end - memDomain.saveram() --- print('ITEMBLOCK: ') --- print(itemsBlock) - itemIndex = u8(ITEM_INDEX) --- print('ITEMINDEX: '..itemIndex) - for i, v in pairs(slice(itemsBlock, itemIndex, #itemsBlock)) do - -- Minus the offset and add to the correct domain - local memoryLocation = v - if v >= 0x100 and v <= 0x114 then - -- This is a key item - memoryLocation = memoryLocation - 0x0E0 - wU8(memoryLocation, 0x01) - elseif v >= 0x1E0 and v <= 0x1F2 then - -- This is a movement item - -- Minus Offset (0x100) - movement offset (0xE0) - memoryLocation = memoryLocation - 0x1E0 - -- Canal is a flipped bit - if memoryLocation == 0x0C then - wU8(memoryLocation, 0x00) - else - wU8(memoryLocation, 0x01) - end - elseif v >= 0x1F3 and v <= 0x1F4 then - -- NoOverworld special items - memoryLocation = noOverworldItemsLookup[v] - wU8(memoryLocation, 0x01) - elseif v >= 0x16C and v <= 0x1AF then - -- This is a gold item - amountToAdd = goldLookup[v] - biggest = u8(0x01E) - medium = u8(0x01D) - smallest = u8(0x01C) - currentValue = 0x10000 * biggest + 0x100 * medium + smallest - newValue = currentValue + amountToAdd - newBiggest = math.floor(newValue / 0x10000) - newMedium = math.floor(math.fmod(newValue, 0x10000) / 0x100) - newSmallest = math.floor(math.fmod(newValue, 0x100)) - wU8(0x01E, newBiggest) - wU8(0x01D, newMedium) - wU8(0x01C, newSmallest) - elseif v >= 0x115 and v <= 0x11B then - -- This is a regular consumable OR a shard - -- Minus Offset (0x100) + item offset (0x20) - memoryLocation = memoryLocation - 0x0E0 - currentValue = u8(memoryLocation) - amountToAdd = consumableStacks[memoryLocation] - if currentValue < 99 then - wU8(memoryLocation, currentValue + amountToAdd) - end - elseif v >= 0x1B0 and v <= 0x1BB then - -- This is an extension consumable - memoryLocation = extensionConsumableLookup[v] - currentValue = u8(memoryLocation) - amountToAdd = consumableStacks[memoryLocation] - if currentValue < 99 then - value = currentValue + amountToAdd - if value > 99 then - value = 99 - end - wU8(memoryLocation, value) - end - end - end - if #itemsBlock > itemIndex then - wU8(ITEM_INDEX, #itemsBlock) - end - - memDomain.saveram() - weaponIndex = u8(WEAPON_INDEX) - emptyWeaponSlots = getEmptyWeaponSlots() - lastUsedWeaponIndex = weaponIndex --- print('WEAPON_INDEX: '.. weaponIndex) - memDomain.saveram() - for i, v in pairs(slice(itemsBlock, weaponIndex, #itemsBlock)) do - if v >= 0x11C and v <= 0x143 then - -- Minus the offset and add to the correct domain - local itemValue = v - 0x11B - if #emptyWeaponSlots > 0 then - slot = table.remove(emptyWeaponSlots, 1) - wU8(slot, itemValue) - lastUsedWeaponIndex = weaponIndex + i - else - break - end - end - end - if lastUsedWeaponIndex ~= weaponIndex then - wU8(WEAPON_INDEX, lastUsedWeaponIndex) - end - memDomain.saveram() - armorIndex = u8(ARMOR_INDEX) - emptyArmorSlots = getEmptyArmorSlots() - lastUsedArmorIndex = armorIndex --- print('ARMOR_INDEX: '.. armorIndex) - memDomain.saveram() - for i, v in pairs(slice(itemsBlock, armorIndex, #itemsBlock)) do - if v >= 0x144 and v <= 0x16B then - -- Minus the offset and add to the correct domain - local itemValue = v - 0x143 - if #emptyArmorSlots > 0 then - slot = table.remove(emptyArmorSlots, 1) - wU8(slot, itemValue) - lastUsedArmorIndex = armorIndex + i - else - break - end - end - end - if lastUsedArmorIndex ~= armorIndex then - wU8(ARMOR_INDEX, lastUsedArmorIndex) - end - end -end - -function receive() - l, e = ff1Socket:receive() - if e == 'closed' then - if curstate == STATE_OK then - print("Connection closed") - end - curstate = STATE_UNINITIALIZED - return - elseif e == 'timeout' then - print("timeout") - return - elseif e ~= nil then - print(e) - curstate = STATE_UNINITIALIZED - return - end - processBlock(json.decode(l)) - - -- Determine Message to send back - memDomain.rom() - local playerName = uRange(0x7BCBF, 0x41) - playerName[0] = nil - local retTable = {} - retTable["playerName"] = playerName - if StateOKForMainLoop() then - retTable["locations"] = generateLocationChecked() - end - msg = json.encode(retTable).."\n" - local ret, error = ff1Socket:send(msg) - if ret == nil then - print(error) - elseif curstate == STATE_INITIAL_CONNECTION_MADE then - curstate = STATE_TENTATIVELY_CONNECTED - elseif curstate == STATE_TENTATIVELY_CONNECTED then - print("Connected!") - itemMessages["(0,0)"] = {TTL=240, message="Connected", color="green"} - curstate = STATE_OK - end -end - -function main() - if not checkBizHawkVersion() then - return - end - server, error = socket.bind('localhost', 52980) - - while true do - gui.drawEllipse(248, 9, 6, 6, "Black", "Yellow") - frame = frame + 1 - drawMessages() - if not (curstate == prevstate) then - -- console.log("Current state: "..curstate) - prevstate = curstate - end - if (curstate == STATE_OK) or (curstate == STATE_INITIAL_CONNECTION_MADE) or (curstate == STATE_TENTATIVELY_CONNECTED) then - if (frame % 60 == 0) then - gui.drawEllipse(248, 9, 6, 6, "Black", "Blue") - receive() - else - gui.drawEllipse(248, 9, 6, 6, "Black", "Green") - end - elseif (curstate == STATE_UNINITIALIZED) then - gui.drawEllipse(248, 9, 6, 6, "Black", "White") - if (frame % 60 == 0) then - gui.drawEllipse(248, 9, 6, 6, "Black", "Yellow") - - drawText(5, 8, "Waiting for client", 0xFFFF0000) - drawText(5, 32, "Please start FF1Client.exe", 0xFFFF0000) - - -- Advance so the messages are drawn - emu.frameadvance() - server:settimeout(2) - print("Attempting to connect") - local client, timeout = server:accept() - if timeout == nil then - -- print('Initial Connection Made') - curstate = STATE_INITIAL_CONNECTION_MADE - ff1Socket = client - ff1Socket:settimeout(0) - end - end - end - emu.frameadvance() - end -end - -main() diff --git a/inno_setup.iss b/inno_setup.iss index adf9acc83409..d9d4d7fb0178 100644 --- a/inno_setup.iss +++ b/inno_setup.iss @@ -86,6 +86,7 @@ Type: dirifempty; Name: "{app}" [InstallDelete] Type: files; Name: "{app}\*.exe" Type: files; Name: "{app}\data\lua\connector_pkmn_rb.lua" +Type: files; Name: "{app}\data\lua\connector_ff1.lua" Type: filesandordirs; Name: "{app}\SNI\lua*" Type: filesandordirs; Name: "{app}\EnemizerCLI*" #include "installdelete.iss" diff --git a/setup.py b/setup.py index ccca46390b02..a46b1e8ce5df 100644 --- a/setup.py +++ b/setup.py @@ -64,7 +64,6 @@ "ArchipIDLE", "Archipelago", "Clique", - "Final Fantasy", "Lufia II Ancient Cave", "Meritous", "Ocarina of Time", diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index b3e3d9006092..2bd96369313e 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -224,8 +224,6 @@ def install_apworld(apworld_path: str = "") -> None: Component('OoT Client', 'OoTClient', file_identifier=SuffixIdentifier('.apz5')), Component('OoT Adjuster', 'OoTAdjuster'), - # FF1 - Component('FF1 Client', 'FF1Client'), # TLoZ Component('Zelda 1 Client', 'Zelda1Client', file_identifier=SuffixIdentifier('.aptloz')), # ChecksFinder diff --git a/worlds/ff1/Client.py b/worlds/ff1/Client.py new file mode 100644 index 000000000000..f7315f69f0ad --- /dev/null +++ b/worlds/ff1/Client.py @@ -0,0 +1,328 @@ +import logging +from collections import deque +from typing import TYPE_CHECKING + +from NetUtils import ClientStatus + +import worlds._bizhawk as bizhawk +from worlds._bizhawk.client import BizHawkClient + +if TYPE_CHECKING: + from worlds._bizhawk.context import BizHawkClientContext + + +base_id = 7000 +logger = logging.getLogger("Client") + + +rom_name_location = 0x07FFE3 +locations_array_start = 0x200 +locations_array_length = 0x100 +items_obtained = 0x03 +gp_location_low = 0x1C +gp_location_middle = 0x1D +gp_location_high = 0x1E +weapons_arrays_starts = [0x118, 0x158, 0x198, 0x1D8] +armors_arrays_starts = [0x11C, 0x15C, 0x19C, 0x1DC] +status_a_location = 0x102 +status_b_location = 0x0FC +status_c_location = 0x0A3 + +key_items = ["Lute", "Crown", "Crystal", "Herb", "Key", "Tnt", "Adamant", "Slab", "Ruby", "Rod", + "Floater", "Chime", "Tail", "Cube", "Bottle", "Oxyale", "EarthOrb", "FireOrb", "WaterOrb", "AirOrb"] + +consumables = ["Shard", "Tent", "Cabin", "House", "Heal", "Pure", "Soft"] + +weapons = ["WoodenNunchucks", "SmallKnife", "WoodenRod", "Rapier", "IronHammer", "ShortSword", "HandAxe", "Scimitar", + "IronNunchucks", "LargeKnife", "IronStaff", "Sabre", "LongSword", "GreatAxe", "Falchon", "SilverKnife", + "SilverSword", "SilverHammer", "SilverAxe", "FlameSword", "IceSword", "DragonSword", "GiantSword", + "SunSword", "CoralSword", "WereSword", "RuneSword", "PowerRod", "LightAxe", "HealRod", "MageRod", "Defense", + "WizardRod", "Vorpal", "CatClaw", "ThorHammer", "BaneSword", "Katana", "Xcalber", "Masamune"] + +armor = ["Cloth", "WoodenArmor", "ChainArmor", "IronArmor", "SteelArmor", "SilverArmor", "FlameArmor", "IceArmor", + "OpalArmor", "DragonArmor", "Copper", "Silver", "Gold", "Opal", "WhiteShirt", "BlackShirt", "WoodenShield", + "IronShield", "SilverShield", "FlameShield", "IceShield", "OpalShield", "AegisShield", "Buckler", "ProCape", + "Cap", "WoodenHelm", "IronHelm", "SilverHelm", "OpalHelm", "HealHelm", "Ribbon", "Gloves", "CopperGauntlets", + "IronGauntlets", "SilverGauntlets", "ZeusGauntlets", "PowerGauntlets", "OpalGauntlets", "ProRing"] + +gold_items = ["Gold10", "Gold20", "Gold25", "Gold30", "Gold55", "Gold70", "Gold85", "Gold110", "Gold135", "Gold155", + "Gold160", "Gold180", "Gold240", "Gold255", "Gold260", "Gold295", "Gold300", "Gold315", "Gold330", + "Gold350", "Gold385", "Gold400", "Gold450", "Gold500", "Gold530", "Gold575", "Gold620", "Gold680", + "Gold750", "Gold795", "Gold880", "Gold1020", "Gold1250", "Gold1455", "Gold1520", "Gold1760", "Gold1975", + "Gold2000", "Gold2750", "Gold3400", "Gold4150", "Gold5000", "Gold5450", "Gold6400", "Gold6720", + "Gold7340", "Gold7690", "Gold7900", "Gold8135", "Gold9000", "Gold9300", "Gold9500", "Gold9900", + "Gold10000", "Gold12350", "Gold13000", "Gold13450", "Gold14050", "Gold14720", "Gold15000", "Gold17490", + "Gold18010", "Gold19990", "Gold20000", "Gold20010", "Gold26000", "Gold45000", "Gold65000"] + +extended_consumables = ["FullCure", "Phoenix", "Blast", "Smoke", + "Refresh", "Flare", "Black", "Guard", + "Quick", "HighPotion", "Wizard", "Cloak"] + +ext_consumables_lookup = {"FullCure": "Ext1", "Phoenix": "Ext2", "Blast": "Ext3", "Smoke": "Ext4", + "Refresh": "Ext1", "Flare": "Ext2", "Black": "Ext3", "Guard": "Ext4", + "Quick": "Ext1", "HighPotion": "Ext2", "Wizard": "Ext3", "Cloak": "Ext4"} + +ext_consumables_locations = {"Ext1": 0x3C, "Ext2": 0x3D, "Ext3": 0x3E, "Ext4": 0x3F} + + +movement_items = ["Ship", "Bridge", "Canal", "Canoe"] + +no_overworld_items = ["Sigil", "Mark"] + + +class FF1Client(BizHawkClient): + game = "Final Fantasy" + system = "NES" + + weapons_queue: deque[int] + armor_queue: deque[int] + consumable_stack_amounts: dict[str, int] | None + + def __init__(self) -> None: + self.wram = "RAM" + self.sram = "WRAM" + self.rom = "PRG ROM" + self.consumable_stack_amounts = None + self.weapons_queue = deque() + self.armor_queue = deque() + self.guard_character = 0x00 + + async def validate_rom(self, ctx: "BizHawkClientContext") -> bool: + try: + # Check ROM name/patch version + rom_name = ((await bizhawk.read(ctx.bizhawk_ctx, [(rom_name_location, 0x0D, self.rom)]))[0]) + rom_name = rom_name.decode("ascii") + if rom_name != "FINAL FANTASY": + return False # Not a Final Fantasy 1 ROM + except bizhawk.RequestFailedError: + return False # Not able to get a response, say no for now + + ctx.game = self.game + ctx.items_handling = 0b111 + ctx.want_slot_data = True + # Resetting these in case of switching ROMs + self.consumable_stack_amounts = None + self.weapons_queue = deque() + self.armor_queue = deque() + + return True + + async def game_watcher(self, ctx: "BizHawkClientContext") -> None: + if ctx.server is None: + return + + if ctx.slot is None: + return + try: + self.guard_character = await self.read_sram_value(ctx, status_a_location) + # If the first character's name starts with a 0 value, we're at the title screen/character creation. + # In that case, don't allow any read/writes. + # We do this by setting the guard to 1 because that's neither a valid character nor the initial value. + if self.guard_character == 0: + self.guard_character = 0x01 + + if self.consumable_stack_amounts is None: + self.consumable_stack_amounts = {} + self.consumable_stack_amounts["Shard"] = 1 + other_consumable_amounts = await self.read_rom(ctx, 0x47400, 10) + self.consumable_stack_amounts["Tent"] = other_consumable_amounts[0] + 1 + self.consumable_stack_amounts["Cabin"] = other_consumable_amounts[1] + 1 + self.consumable_stack_amounts["House"] = other_consumable_amounts[2] + 1 + self.consumable_stack_amounts["Heal"] = other_consumable_amounts[3] + 1 + self.consumable_stack_amounts["Pure"] = other_consumable_amounts[4] + 1 + self.consumable_stack_amounts["Soft"] = other_consumable_amounts[5] + 1 + self.consumable_stack_amounts["Ext1"] = other_consumable_amounts[6] + 1 + self.consumable_stack_amounts["Ext2"] = other_consumable_amounts[7] + 1 + self.consumable_stack_amounts["Ext3"] = other_consumable_amounts[8] + 1 + self.consumable_stack_amounts["Ext4"] = other_consumable_amounts[9] + 1 + + await self.location_check(ctx) + await self.received_items_check(ctx) + await self.process_weapons_queue(ctx) + await self.process_armor_queue(ctx) + + except bizhawk.RequestFailedError: + # The connector didn't respond. Exit handler and return to main loop to reconnect + pass + + async def location_check(self, ctx: "BizHawkClientContext"): + locations_data = await self.read_sram_values_guarded(ctx, locations_array_start, locations_array_length) + if locations_data is None: + return + locations_checked = [] + if len(locations_data) > 0xFE and locations_data[0xFE] & 0x02 != 0 and not ctx.finished_game: + await ctx.send_msgs([ + {"cmd": "StatusUpdate", + "status": ClientStatus.CLIENT_GOAL} + ]) + ctx.finished_game = True + for location in ctx.missing_locations: + # index will be - 0x100 or 0x200 + index = location + if location < 0x200: + # Location is a chest + index -= 0x100 + flag = 0x04 + else: + # Location is an NPC + index -= 0x200 + flag = 0x02 + if locations_data[index] & flag != 0: + locations_checked.append(location) + + found_locations = await ctx.check_locations(locations_checked) + for location in found_locations: + ctx.locations_checked.add(location) + location_name = ctx.location_names.lookup_in_game(location) + logger.info( + f'New Check: {location_name} ({len(ctx.locations_checked)}/' + f'{len(ctx.missing_locations) + len(ctx.checked_locations)})') + + + async def received_items_check(self, ctx: "BizHawkClientContext") -> None: + assert self.consumable_stack_amounts, "shouldn't call this function without reading consumable_stack_amounts" + write_list: list[tuple[int, list[int], str]] = [] + items_received_count = await self.read_sram_value_guarded(ctx, items_obtained) + if items_received_count is None: + return + if items_received_count < len(ctx.items_received): + current_item = ctx.items_received[items_received_count] + current_item_id = current_item.item + current_item_name = ctx.item_names.lookup_in_game(current_item_id, ctx.game) + if current_item_name in key_items: + location = current_item_id - 0xE0 + write_list.append((location, [1], self.sram)) + elif current_item_name in movement_items: + location = current_item_id - 0x1E0 + if current_item_name != "Canal": + write_list.append((location, [1], self.sram)) + else: + write_list.append((location, [0], self.sram)) + elif current_item_name in no_overworld_items: + if current_item_name == "Sigil": + location = 0x28 + else: + location = 0x12 + write_list.append((location, [1], self.sram)) + elif current_item_name in gold_items: + gold_amount = int(current_item_name[4:]) + current_gold_value = await self.read_sram_values_guarded(ctx, gp_location_low, 3) + if current_gold_value is None: + return + current_gold = int.from_bytes(current_gold_value, "little") + new_gold = min(gold_amount + current_gold, 999999) + lower_byte = new_gold % (2 ** 8) + middle_byte = (new_gold // (2 ** 8)) % (2 ** 8) + upper_byte = new_gold // (2 ** 16) + write_list.append((gp_location_low, [lower_byte], self.sram)) + write_list.append((gp_location_middle, [middle_byte], self.sram)) + write_list.append((gp_location_high, [upper_byte], self.sram)) + elif current_item_name in consumables: + location = current_item_id - 0xE0 + current_value = await self.read_sram_value_guarded(ctx, location) + if current_value is None: + return + amount_to_add = self.consumable_stack_amounts[current_item_name] + new_value = min(current_value + amount_to_add, 99) + write_list.append((location, [new_value], self.sram)) + elif current_item_name in extended_consumables: + ext_name = ext_consumables_lookup[current_item_name] + location = ext_consumables_locations[ext_name] + current_value = await self.read_sram_value_guarded(ctx, location) + if current_value is None: + return + amount_to_add = self.consumable_stack_amounts[ext_name] + new_value = min(current_value + amount_to_add, 99) + write_list.append((location, [new_value], self.sram)) + elif current_item_name in weapons: + self.weapons_queue.appendleft(current_item_id - 0x11B) + elif current_item_name in armor: + self.armor_queue.appendleft(current_item_id - 0x143) + write_list.append((items_obtained, [items_received_count + 1], self.sram)) + write_successful = await self.write_sram_values_guarded(ctx, write_list) + if write_successful: + await bizhawk.display_message(ctx.bizhawk_ctx, f"Received {current_item_name}") + + async def process_weapons_queue(self, ctx: "BizHawkClientContext"): + empty_slots = deque() + char1_slots = await self.read_sram_values_guarded(ctx, weapons_arrays_starts[0], 4) + char2_slots = await self.read_sram_values_guarded(ctx, weapons_arrays_starts[1], 4) + char3_slots = await self.read_sram_values_guarded(ctx, weapons_arrays_starts[2], 4) + char4_slots = await self.read_sram_values_guarded(ctx, weapons_arrays_starts[3], 4) + if char1_slots is None or char2_slots is None or char3_slots is None or char4_slots is None: + return + for i, slot in enumerate(char1_slots): + if slot == 0: + empty_slots.appendleft(weapons_arrays_starts[0] + i) + for i, slot in enumerate(char2_slots): + if slot == 0: + empty_slots.appendleft(weapons_arrays_starts[1] + i) + for i, slot in enumerate(char3_slots): + if slot == 0: + empty_slots.appendleft(weapons_arrays_starts[2] + i) + for i, slot in enumerate(char4_slots): + if slot == 0: + empty_slots.appendleft(weapons_arrays_starts[3] + i) + while len(empty_slots) > 0 and len(self.weapons_queue) > 0: + current_slot = empty_slots.pop() + current_weapon = self.weapons_queue.pop() + await self.write_sram_guarded(ctx, current_slot, current_weapon) + + async def process_armor_queue(self, ctx: "BizHawkClientContext"): + empty_slots = deque() + char1_slots = await self.read_sram_values_guarded(ctx, armors_arrays_starts[0], 4) + char2_slots = await self.read_sram_values_guarded(ctx, armors_arrays_starts[1], 4) + char3_slots = await self.read_sram_values_guarded(ctx, armors_arrays_starts[2], 4) + char4_slots = await self.read_sram_values_guarded(ctx, armors_arrays_starts[3], 4) + if char1_slots is None or char2_slots is None or char3_slots is None or char4_slots is None: + return + for i, slot in enumerate(char1_slots): + if slot == 0: + empty_slots.appendleft(armors_arrays_starts[0] + i) + for i, slot in enumerate(char2_slots): + if slot == 0: + empty_slots.appendleft(armors_arrays_starts[1] + i) + for i, slot in enumerate(char3_slots): + if slot == 0: + empty_slots.appendleft(armors_arrays_starts[2] + i) + for i, slot in enumerate(char4_slots): + if slot == 0: + empty_slots.appendleft(armors_arrays_starts[3] + i) + while len(empty_slots) > 0 and len(self.armor_queue) > 0: + current_slot = empty_slots.pop() + current_armor = self.armor_queue.pop() + await self.write_sram_guarded(ctx, current_slot, current_armor) + + + async def read_sram_value(self, ctx: "BizHawkClientContext", location: int): + value = ((await bizhawk.read(ctx.bizhawk_ctx, [(location, 1, self.sram)]))[0]) + return int.from_bytes(value, "little") + + async def read_sram_values_guarded(self, ctx: "BizHawkClientContext", location: int, size: int): + value = await bizhawk.guarded_read(ctx.bizhawk_ctx, + [(location, size, self.sram)], + [(status_a_location, [self.guard_character], self.sram)]) + if value is None: + return None + return value[0] + + async def read_sram_value_guarded(self, ctx: "BizHawkClientContext", location: int): + value = await bizhawk.guarded_read(ctx.bizhawk_ctx, + [(location, 1, self.sram)], + [(status_a_location, [self.guard_character], self.sram)]) + if value is None: + return None + return int.from_bytes(value[0], "little") + + async def read_rom(self, ctx: "BizHawkClientContext", location: int, size: int): + return (await bizhawk.read(ctx.bizhawk_ctx, [(location, size, self.rom)]))[0] + + async def write_sram_guarded(self, ctx: "BizHawkClientContext", location: int, value: int): + return await bizhawk.guarded_write(ctx.bizhawk_ctx, + [(location, [value], self.sram)], + [(status_a_location, [self.guard_character], self.sram)]) + + async def write_sram_values_guarded(self, ctx: "BizHawkClientContext", write_list): + return await bizhawk.guarded_write(ctx.bizhawk_ctx, + write_list, + [(status_a_location, [self.guard_character], self.sram)]) diff --git a/worlds/ff1/Items.py b/worlds/ff1/Items.py index 469cf6f05193..5d674a17b386 100644 --- a/worlds/ff1/Items.py +++ b/worlds/ff1/Items.py @@ -1,5 +1,5 @@ import json -from pathlib import Path +import pkgutil from typing import Dict, Set, NamedTuple, List from BaseClasses import Item, ItemClassification @@ -37,15 +37,13 @@ class FF1Items: _item_table_lookup: Dict[str, ItemData] = {} def _populate_item_table_from_data(self): - base_path = Path(__file__).parent - file_path = (base_path / "data/items.json").resolve() - with open(file_path) as file: - items = json.load(file) - # Hardcode progression and categories for now - self._item_table = [ItemData(name, code, "FF1Item", ItemClassification.progression if name in - FF1_PROGRESSION_LIST else ItemClassification.useful if name in FF1_USEFUL_LIST else - ItemClassification.filler) for name, code in items.items()] - self._item_table_lookup = {item.name: item for item in self._item_table} + file = pkgutil.get_data(__name__, "data/items.json").decode("utf-8") + items = json.loads(file) + # Hardcode progression and categories for now + self._item_table = [ItemData(name, code, "FF1Item", ItemClassification.progression if name in + FF1_PROGRESSION_LIST else ItemClassification.useful if name in FF1_USEFUL_LIST else + ItemClassification.filler) for name, code in items.items()] + self._item_table_lookup = {item.name: item for item in self._item_table} def _get_item_table(self) -> List[ItemData]: if not self._item_table or not self._item_table_lookup: diff --git a/worlds/ff1/Locations.py b/worlds/ff1/Locations.py index b0353f94fbdb..47facad985e5 100644 --- a/worlds/ff1/Locations.py +++ b/worlds/ff1/Locations.py @@ -1,5 +1,5 @@ import json -from pathlib import Path +import pkgutil from typing import Dict, NamedTuple, List, Optional from BaseClasses import Region, Location, MultiWorld @@ -18,13 +18,11 @@ class FF1Locations: _location_table_lookup: Dict[str, LocationData] = {} def _populate_item_table_from_data(self): - base_path = Path(__file__).parent - file_path = (base_path / "data/locations.json").resolve() - with open(file_path) as file: - locations = json.load(file) - # Hardcode progression and categories for now - self._location_table = [LocationData(name, code) for name, code in locations.items()] - self._location_table_lookup = {item.name: item for item in self._location_table} + file = pkgutil.get_data(__name__, "data/locations.json") + locations = json.loads(file) + # Hardcode progression and categories for now + self._location_table = [LocationData(name, code) for name, code in locations.items()] + self._location_table_lookup = {item.name: item for item in self._location_table} def _get_location_table(self) -> List[LocationData]: if not self._location_table or not self._location_table_lookup: diff --git a/worlds/ff1/__init__.py b/worlds/ff1/__init__.py index 3a5047506850..39df9020e529 100644 --- a/worlds/ff1/__init__.py +++ b/worlds/ff1/__init__.py @@ -7,6 +7,7 @@ from .Locations import EventId, FF1Locations, generate_rule, CHAOS_TERMINATED_EVENT from .Options import FF1Options from ..AutoWorld import World, WebWorld +from .Client import FF1Client class FF1Settings(settings.Group): diff --git a/worlds/ff1/docs/en_Final Fantasy.md b/worlds/ff1/docs/en_Final Fantasy.md index 889bb46e0c35..a05aef63bc8c 100644 --- a/worlds/ff1/docs/en_Final Fantasy.md +++ b/worlds/ff1/docs/en_Final Fantasy.md @@ -22,11 +22,6 @@ All items can appear in other players worlds, including consumables, shards, wea ## What does another world's item look like in Final Fantasy -All local and remote items appear the same. Final Fantasy will say that you received an item, then BOTH the client log and the -emulator will display what was found external to the in-game text box. +All local and remote items appear the same. Final Fantasy will say that you received an item, then the client log will +display what was found external to the in-game text box. -## Unique Local Commands -The following commands are only available when using the FF1Client for the Final Fantasy Randomizer. - -- `/nes` Shows the current status of the NES connection. -- `/toggle_msgs` Toggle displaying messages in EmuHawk diff --git a/worlds/ff1/docs/multiworld_en.md b/worlds/ff1/docs/multiworld_en.md index d3dc457f01be..1f1147bb31b5 100644 --- a/worlds/ff1/docs/multiworld_en.md +++ b/worlds/ff1/docs/multiworld_en.md @@ -2,10 +2,10 @@ ## Required Software -- The FF1Client - - Bundled with Archipelago: [Archipelago Releases Page](https://github.com/ArchipelagoMW/Archipelago/releases) -- The BizHawk emulator. Versions 2.3.1 and higher are supported. Version 2.7 is recommended - - [BizHawk at TASVideos](https://tasvideos.org/BizHawk) +- BizHawk: [BizHawk Releases from TASVideos](https://tasvideos.org/BizHawk/ReleaseHistory) + - Detailed installation instructions for BizHawk can be found at the above link. + - Windows users must run the prerequisite installer first, which can also be found at the above link. +- The built-in BizHawk client, which can be installed [here](https://github.com/ArchipelagoMW/Archipelago/releases) - Your legally obtained Final Fantasy (USA Edition) ROM file, probably named `Final Fantasy (USA).nes`. Neither Archipelago.gg nor the Final Fantasy Randomizer Community can supply you with this. @@ -13,7 +13,7 @@ 1. Download and install the latest version of Archipelago. 1. On Windows, download Setup.Archipelago..exe and run it -2. Assign EmuHawk version 2.3.1 or higher as your default program for launching `.nes` files. +2. Assign EmuHawk as your default program for launching `.nes` files. 1. Extract your BizHawk folder to your Desktop, or somewhere you will remember. Below are optional additional steps for loading ROMs more conveniently 1. Right-click on a ROM file and select **Open with...** @@ -46,7 +46,7 @@ please refer to the [game agnostic setup guide](/tutorial/Archipelago/setup/en). Once the Archipelago server has been hosted: -1. Navigate to your Archipelago install folder and run `ArchipelagoFF1Client.exe` +1. Navigate to your Archipelago install folder and run `ArchipelagoBizhawkClient.exe` 2. Notice the `/connect command` on the server hosting page (It should look like `/connect archipelago.gg:*****` where ***** are numbers) 3. Type the connect command into the client OR add the port to the pre-populated address on the top bar (it should @@ -54,16 +54,11 @@ Once the Archipelago server has been hosted: ### Running Your Game and Connecting to the Client Program -1. Open EmuHawk 2.3.1 or higher and load your ROM OR click your ROM file if it is already associated with the +1. Open EmuHawk and load your ROM OR click your ROM file if it is already associated with the extension `*.nes` -2. Navigate to where you installed Archipelago, then to `data/lua`, and drag+drop the `connector_ff1.lua` script onto - the main EmuHawk window. - 1. You could instead open the Lua Console manually, click `Script` 〉 `Open Script`, and navigate to - `connector_ff1.lua` with the file picker. - 2. If it gives a `NLua.Exceptions.LuaScriptException: .\socket.lua:13: module 'socket.core' not found:` exception - close your emulator entirely, restart it and re-run these steps - 3. If it says `Must use a version of BizHawk 2.3.1 or higher`, double-check your BizHawk version by clicking ** - Help** -> **About** +2. Navigate to where you installed Archipelago, then to `data/lua`, and drag+drop the `connector_bizhawk_generic.lua` +script onto the main EmuHawk window. You can also instead open the Lua Console manually, click `Script` 〉 `Open Script`, +and navigate to `connector_bizhawk_generic.lua` with the file picker. ## Play the game From 62694b1ce77f881e0b3915358d1ab9867502d7fc Mon Sep 17 00:00:00 2001 From: qwint Date: Thu, 22 May 2025 10:37:23 -0500 Subject: [PATCH 0460/1218] Launcher: Fix on File Drop Error Message (#5026) --- Launcher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Launcher.py b/Launcher.py index 2520fd6b5f51..8b533a505f31 100644 --- a/Launcher.py +++ b/Launcher.py @@ -392,7 +392,7 @@ def _on_drop_file(self, window: Window, filename: bytes, x: int, y: int) -> None if file and component: run_component(component, file) else: - logging.warning(f"unable to identify component for {file}") + logging.warning(f"unable to identify component for {filename}") def _on_keyboard(self, window: Window, key: int, scancode: int, codepoint: str, modifier: list[str]): # Activate search as soon as we start typing, no matter if we are focused on the search box or not. From 653ee2b625cc64461589abe3c836e87f3ca21bc3 Mon Sep 17 00:00:00 2001 From: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> Date: Thu, 22 May 2025 15:00:30 -0400 Subject: [PATCH 0461/1218] Docs: Update Snippets to Modern Type Hints (#4987) --- docs/network protocol.md | 24 ++++++++++++------------ docs/options api.md | 2 +- docs/settings api.md | 11 +++++------ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/docs/network protocol.md b/docs/network protocol.md index 6688c101ab4b..8c07ff10fdf6 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -231,11 +231,11 @@ Sent to clients after a client requested this message be sent to them, more info Sent to clients if the server caught a problem with a packet. This only occurs for errors that are explicitly checked for. #### Arguments -| Name | Type | Notes | -| ---- | ---- | ----- | -| type | str | The [PacketProblemType](#PacketProblemType) that was detected in the packet. | -| original_cmd | Optional[str] | The `cmd` argument of the faulty packet, will be `None` if the `cmd` failed to be parsed. | -| text | str | A descriptive message of the problem at hand. | +| Name | Type | Notes | +| ---- |-------------| ----- | +| type | str | The [PacketProblemType](#PacketProblemType) that was detected in the packet. | +| original_cmd | str \| None | The `cmd` argument of the faulty packet, will be `None` if the `cmd` failed to be parsed. | +| text | str | A descriptive message of the problem at hand. | ##### PacketProblemType `PacketProblemType` indicates the type of problem that was detected in the faulty packet, the known problem types are below but others may be added in the future. @@ -551,14 +551,14 @@ In JSON this may look like: Message nodes sent along with [PrintJSON](#PrintJSON) packet to be reconstructed into a legible message. The nodes are intended to be read in the order they are listed in the packet. ```python -from typing import TypedDict, Optional +from typing import TypedDict class JSONMessagePart(TypedDict): - type: Optional[str] - text: Optional[str] - color: Optional[str] # only available if type is a color - flags: Optional[int] # only available if type is an item_id or item_name - player: Optional[int] # only available if type is either item or location - hint_status: Optional[HintStatus] # only available if type is hint_status + type: str | None + text: str | None + color: str | None # only available if type is a color + flags: int | None # only available if type is an item_id or item_name + player: int | None # only available if type is either item or location + hint_status: HintStatus | None # only available if type is hint_status ``` `type` is used to denote the intent of the message part. This can be used to indicate special information which may be rendered differently depending on client. How these types are displayed in Archipelago's ALttP client is not the end-all be-all. Other clients may choose to interpret and display these messages differently. diff --git a/docs/options api.md b/docs/options api.md index 037b9edb8711..c9b7c422fec8 100644 --- a/docs/options api.md +++ b/docs/options api.md @@ -333,7 +333,7 @@ within the world. ### TextChoice Like choice allows you to predetermine options and has all of the same comparison methods and handling. Also accepts any user defined string as a valid option, so will either need to be validated by adding a validation step to the option -class or within world, if necessary. Value for this class is `Union[str, int]` so if you need the value at a specified +class or within world, if necessary. Value for this class is `str | int` so if you need the value at a specified point, `self.options.my_option.current_key` will always return a string. ### PlandoBosses diff --git a/docs/settings api.md b/docs/settings api.md index bfc642d4b50c..ef1f20d09815 100644 --- a/docs/settings api.md +++ b/docs/settings api.md @@ -102,17 +102,16 @@ In worlds, this should only be used for the top level to avoid issues when upgra ### Bool -Since `bool` can not be subclassed, use the `settings.Bool` helper in a `typing.Union` to get a comment in host.yaml. +Since `bool` can not be subclassed, use the `settings.Bool` helper in a union to get a comment in host.yaml. ```python import settings -import typing class MySettings(settings.Group): class MyBool(settings.Bool): """Doc string""" - my_value: typing.Union[MyBool, bool] = True + my_value: MyBool | bool = True ``` ### UserFilePath @@ -134,15 +133,15 @@ Checks the file against [md5s](#md5s) by default. Resolves to an executable (varying file extension based on platform) -#### description: Optional\[str\] +#### description: str | None Human-readable name to use in file browser -#### copy_to: Optional\[str\] +#### copy_to: str | None Instead of storing the path, copy the file. -#### md5s: List[Union[str, bytes]] +#### md5s: list[str | bytes] Provide md5 hashes as hex digests or raw bytes for automatic validation. From de71677208f43730ce62191290901759363e407c Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Thu, 22 May 2025 21:30:30 +0200 Subject: [PATCH 0462/1218] Core: only raise min_client_version for new gens (#4896) --- MultiServer.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MultiServer.py b/MultiServer.py index 9bcf8f6f4caa..f12f327c3f62 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -458,8 +458,12 @@ def _load(self, decoded_obj: dict, game_data_packages: typing.Dict[str, typing.A self.generator_version = Version(*decoded_obj["version"]) clients_ver = decoded_obj["minimum_versions"].get("clients", {}) self.minimum_client_versions = {} + if self.generator_version < Version(0, 6, 2): + min_version = Version(0, 1, 6) + else: + min_version = min_client_version for player, version in clients_ver.items(): - self.minimum_client_versions[player] = max(Version(*version), min_client_version) + self.minimum_client_versions[player] = max(Version(*version), min_version) self.slot_info = decoded_obj["slot_info"] self.games = {slot: slot_info.game for slot, slot_info in self.slot_info.items()} From 5491f8c4598b93c179761014c5d4d6fc7ee3ed62 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 22 May 2025 21:28:56 -0500 Subject: [PATCH 0463/1218] Core: Make `get_all_state` Sweeping Optional (#4828) --- BaseClasses.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 377dee7d631e..1a06ef6b7355 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -439,7 +439,7 @@ def get_location(self, location_name: str, player: int) -> Location: return self.regions.location_cache[player][location_name] def get_all_state(self, use_cache: bool, allow_partial_entrances: bool = False, - collect_pre_fill_items: bool = True) -> CollectionState: + collect_pre_fill_items: bool = True, perform_sweep: bool = True) -> CollectionState: cached = getattr(self, "_all_state", None) if use_cache and cached: return cached.copy() @@ -453,7 +453,8 @@ def get_all_state(self, use_cache: bool, allow_partial_entrances: bool = False, subworld = self.worlds[player] for item in subworld.get_pre_fill_items(): subworld.collect(ret, item) - ret.sweep_for_advancements() + if perform_sweep: + ret.sweep_for_advancements() if use_cache: self._all_state = ret From e9f51e330211743f52d20a9a1b570da8db4db6af Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 23 May 2025 19:26:37 +0000 Subject: [PATCH 0464/1218] Linux: avoid adding cwd to LD_LIBRARY_PATH (#5029) When LD_LIBRARY_PATH is not set, the old code would also add the current working directory to LD_LIBRARY_PATH, which is bad. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a46b1e8ce5df..959746717a17 100644 --- a/setup.py +++ b/setup.py @@ -481,7 +481,7 @@ def write_launcher(self, default_exe: Path) -> None: if [ ! "${{#tmp}}" -lt "${{#exe}}" ]; then exe="{default_exe.parent}/$exe" fi -export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$APPDIR/{default_exe.parent}/lib" +export LD_LIBRARY_PATH="${{LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}}$APPDIR/{default_exe.parent}/lib" $APPDIR/$exe "$@" """) launcher_filename.chmod(0o755) From a7de89f45cadb885ee01a6216af836a34bc8b843 Mon Sep 17 00:00:00 2001 From: BlastSlimey <89539656+BlastSlimey@users.noreply.github.com> Date: Fri, 23 May 2025 21:41:27 +0200 Subject: [PATCH 0465/1218] shapez: Add game to README and CODEOWNERS (#5034) * Aktualisieren von README.md * Aktualisieren von CODEOWNERS --- README.md | 1 + docs/CODEOWNERS | 3 +++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 84e62b15280a..9ce6caf0cfc7 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Currently, the following games are supported: * The Legend of Zelda: The Wind Waker * Jak and Daxter: The Precursor Legacy * Super Mario Land 2: 6 Golden Coins +* shapez For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 2289daad072a..1fb5578e9998 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -160,6 +160,9 @@ # Saving Princess /worlds/saving_princess/ @LeonarthCG +# shapez +/worlds/shapez/ @BlastSlimey + # Shivers /worlds/shivers/ @GodlFire @korydondzila From 8671e9a39150d1efa41e04e12f00edecf916bb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Fri, 23 May 2025 15:52:47 -0400 Subject: [PATCH 0466/1218] Stardew Valley: Make animal catalog logically year 2 (#5032) --- worlds/stardew_valley/content/vanilla/pelican_town.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/stardew_valley/content/vanilla/pelican_town.py b/worlds/stardew_valley/content/vanilla/pelican_town.py index aeae4c14316a..d1d024b54c55 100644 --- a/worlds/stardew_valley/content/vanilla/pelican_town.py +++ b/worlds/stardew_valley/content/vanilla/pelican_town.py @@ -3,7 +3,7 @@ from ...data.building import Building from ...data.game_item import GenericSource, ItemTag, Tag, CustomRuleSource from ...data.harvest import ForagingSource, SeasonalForagingSource, ArtifactSpotSource -from ...data.requirement import ToolRequirement, BookRequirement, SkillRequirement +from ...data.requirement import ToolRequirement, BookRequirement, SkillRequirement, YearRequirement from ...data.shop import ShopSource, MysteryBoxSource, ArtifactTroveSource, PrizeMachineSource, FishingTreasureChestSource from ...strings.artisan_good_names import ArtisanGood from ...strings.book_names import Book @@ -209,7 +209,7 @@ # Books Book.animal_catalogue: ( Tag(ItemTag.BOOK, ItemTag.BOOK_POWER), - ShopSource(money_price=5000, shop_region=Region.ranch),), + ShopSource(money_price=5000, shop_region=Region.ranch, other_requirements=(YearRequirement(2),)),), Book.book_of_mysteries: ( Tag(ItemTag.BOOK, ItemTag.BOOK_POWER), MysteryBoxSource(amount=38),), # After 38 boxes, there are 49.99% chances player received the book. From 13ca134d125d573af1394512a0ef4f78d60f0e7e Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Fri, 23 May 2025 23:47:21 +0200 Subject: [PATCH 0467/1218] Core: Fix a playthrough crash when a world uses "placement based logic" (#3915) * Fix playthrough * oops * oops 2 * I don't like this * that should do it * Update BaseClasses.py Co-authored-by: Doug Hoskisson * Update BaseClasses.py --------- Co-authored-by: Doug Hoskisson --- BaseClasses.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 1a06ef6b7355..1de23bc1eab4 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -559,7 +559,9 @@ def has_beaten_game(self, state: CollectionState, player: Optional[int] = None) 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) -> bool: + def can_beat_game(self, + starting_state: Optional[CollectionState] = None, + locations: Optional[Iterable[Location]] = None) -> bool: if starting_state: if self.has_beaten_game(starting_state): return True @@ -568,7 +570,9 @@ def can_beat_game(self, starting_state: Optional[CollectionState] = None) -> boo state = CollectionState(self) if self.has_beaten_game(state): return True - prog_locations = {location for location in self.get_locations() if location.item + + base_locations = self.get_locations() if locations is None else locations + prog_locations = {location for location in base_locations if location.item and location.item.advancement and location not in state.locations_checked} while prog_locations: @@ -1603,21 +1607,19 @@ def create_playthrough(self, create_paths: bool = True) -> None: # in the second phase, we cull each sphere such that the game is still beatable, # reducing each range of influence to the bare minimum required inside it - restore_later: Dict[Location, Item] = {} + required_locations = {location for sphere in collection_spheres for location in sphere} for num, sphere in reversed(tuple(enumerate(collection_spheres))): to_delete: Set[Location] = set() for location in sphere: - # we remove the item at location and check if game is still beatable + # we remove the location from required_locations to sweep from, and check if the game is still beatable logging.debug('Checking if %s (Player %d) is required to beat the game.', location.item.name, location.item.player) - old_item = location.item - location.item = None - if multiworld.can_beat_game(state_cache[num]): + required_locations.remove(location) + if multiworld.can_beat_game(state_cache[num], required_locations): to_delete.add(location) - restore_later[location] = old_item else: # still required, got to keep it around - location.item = old_item + required_locations.add(location) # cull entries in spheres for spoiler walkthrough at end sphere -= to_delete @@ -1634,7 +1636,7 @@ def create_playthrough(self, create_paths: bool = True) -> None: logging.debug('Checking if %s (Player %d) is required to beat the game.', item.name, item.player) precollected_items.remove(item) multiworld.state.remove(item) - if not multiworld.can_beat_game(): + if not multiworld.can_beat_game(multiworld.state, required_locations): # Add the item back into `precollected_items` and collect it into `multiworld.state`. multiworld.push_precollected(item) else: @@ -1676,9 +1678,6 @@ def create_playthrough(self, create_paths: bool = True) -> None: self.create_paths(state, collection_spheres) # repair the multiworld again - for location, item in restore_later.items(): - location.item = item - for item in removed_precollected: multiworld.push_precollected(item) From 0a7aa9e3e2a1a9aea371a471f6102e554a042bd4 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 23 May 2025 17:02:50 -0500 Subject: [PATCH 0468/1218] Launcher: skip launcher gui when opening webhost list with no game handlers (#4888) * calc relevant components before opening the launcher app so it can be skipped for text client only uri launches * generically passthrough the url arg * Apply suggestions from code review Co-authored-by: Aaron Wagener * flip if not else * Update Launcher.py * pluralize --------- Co-authored-by: Aaron Wagener --- Launcher.py | 58 ++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/Launcher.py b/Launcher.py index 8b533a505f31..e9751f2c2350 100644 --- a/Launcher.py +++ b/Launcher.py @@ -115,34 +115,30 @@ def update_settings(): ]) -def handle_uri(path: str, launch_args: tuple[str, ...]) -> None: +def handle_uri(path: str) -> tuple[list[Component], Component]: url = urllib.parse.urlparse(path) queries = urllib.parse.parse_qs(url.query) - launch_args = (path, *launch_args) - client_component = [] + client_components = [] text_client_component = None game = queries["game"][0] for component in components: if component.supports_uri and component.game_name == game: - client_component.append(component) + client_components.append(component) elif component.display_name == "Text Client": text_client_component = component + return client_components, text_client_component - if not client_component: - run_component(text_client_component, *launch_args) - return - else: - from kvui import ButtonsPrompt - component_options = { - text_client_component.display_name: text_client_component, - **{component.display_name: component for component in client_component} - } - popup = ButtonsPrompt("Connect to Multiworld", - "Select client to open and connect with.", - lambda component_name: run_component(component_options[component_name], *launch_args), - *component_options.keys()) - popup.open() +def build_uri_popup(component_list: list[Component], launch_args: tuple[str, ...]) -> None: + from kvui import ButtonsPrompt + component_options = { + component.display_name: component for component in component_list + } + popup = ButtonsPrompt("Connect to Multiworld", + "Select client to open and connect with.", + lambda component_name: run_component(component_options[component_name], *launch_args), + *component_options.keys()) + popup.open() def identify(path: None | str) -> tuple[None | str, None | Component]: @@ -212,7 +208,7 @@ def create_shortcut(button: Any, component: Component) -> None: refresh_components: Callable[[], None] | None = None -def run_gui(path: str, args: Any) -> None: +def run_gui(launch_components: list[Component], args: Any) -> None: from kvui import (ThemedApp, MDFloatLayout, MDGridLayout, ScrollBox) from kivy.properties import ObjectProperty from kivy.core.window import Window @@ -245,12 +241,12 @@ class Launcher(ThemedApp): cards: list[LauncherCard] current_filter: Sequence[str | Type] | None - def __init__(self, ctx=None, path=None, args=None): + def __init__(self, ctx=None, components=None, args=None): self.title = self.base_title + " " + Utils.__version__ self.ctx = ctx self.icon = r"data/icon.png" self.favorites = [] - self.launch_uri = path + self.launch_components = components self.launch_args = args self.cards = [] self.current_filter = (Type.CLIENT, Type.TOOL, Type.ADJUSTER, Type.MISC) @@ -372,9 +368,9 @@ def build(self): return self.top_screen def on_start(self): - if self.launch_uri: - handle_uri(self.launch_uri, self.launch_args) - self.launch_uri = None + if self.launch_components: + build_uri_popup(self.launch_components, self.launch_args) + self.launch_components = None self.launch_args = None @staticmethod @@ -415,7 +411,7 @@ def on_stop(self): for filter in self.current_filter)) super().on_stop() - Launcher(path=path, args=args).run() + Launcher(components=launch_components, args=args).run() # avoiding Launcher reference leak # and don't try to do something with widgets after window closed @@ -442,7 +438,15 @@ def main(args: argparse.Namespace | dict | None = None): path = args.get("Patch|Game|Component|url", None) if path is not None: - if not path.startswith("archipelago://"): + if path.startswith("archipelago://"): + args["args"] = (path, *args.get("args", ())) + # add the url arg to the passthrough args + components, text_client_component = handle_uri(path) + if not components: + args["component"] = text_client_component + else: + args['launch_components'] = [text_client_component, *components] + else: file, component = identify(path) if file: args['file'] = file @@ -458,7 +462,7 @@ def main(args: argparse.Namespace | dict | None = None): elif "component" in args: run_component(args["component"], *args["args"]) elif not args["update_settings"]: - run_gui(path, args.get("args", ())) + run_gui(args.get("launch_components", None), args.get("args", ())) if __name__ == '__main__': From e82d50a3c5cdc67091a42059f922520dec691f9c Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Fri, 23 May 2025 17:13:34 -0500 Subject: [PATCH 0469/1218] The Messenger: more generous portal validation (#5011) * The Messenger: more generous portal validation * remove the while and just go for 20 attempts. hopefully that's enough --- worlds/messenger/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/messenger/__init__.py b/worlds/messenger/__init__.py index e403ff59d862..88a0cec2caad 100644 --- a/worlds/messenger/__init__.py +++ b/worlds/messenger/__init__.py @@ -281,7 +281,7 @@ def connect_entrances(self) -> None: disconnect_entrances(self) add_closed_portal_reqs(self) # i need portal shuffle to happen after rules exist so i can validate it - attempts = 5 + attempts = 20 if self.options.shuffle_portals: self.portal_mapping = [] self.spoiler_portal_mapping = {} From c64791e3a8b0c51378182ad12da8d6f2a72e132e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sat, 24 May 2025 01:15:41 -0400 Subject: [PATCH 0470/1218] Stardew Valley: Replace current naive entrance rando with GER (#4624) --- worlds/stardew_valley/__init__.py | 25 +- worlds/stardew_valley/content/mods/sve.py | 21 +- worlds/stardew_valley/mods/logic/sve_logic.py | 3 +- .../mods/{mod_regions.py => region_data.py} | 296 +++---- worlds/stardew_valley/region_classes.py | 67 -- worlds/stardew_valley/regions.py | 775 ------------------ worlds/stardew_valley/regions/__init__.py | 2 + .../stardew_valley/regions/entrance_rando.py | 73 ++ worlds/stardew_valley/regions/model.py | 94 +++ worlds/stardew_valley/regions/mods.py | 46 ++ worlds/stardew_valley/regions/regions.py | 61 ++ worlds/stardew_valley/regions/vanilla_data.py | 522 ++++++++++++ worlds/stardew_valley/test/TestRegions.py | 173 ---- .../test/assertion/rule_assert.py | 12 +- worlds/stardew_valley/test/bases.py | 7 +- worlds/stardew_valley/test/mods/TestMods.py | 39 +- .../regions/TestEntranceClassifications.py | 36 + .../test/regions/TestEntranceRandomization.py | 167 ++++ .../test/regions/TestRandomizationFlag.py | 88 ++ .../test/regions/TestRegionConnections.py | 66 ++ .../stardew_valley/test/regions/__init__.py | 0 21 files changed, 1350 insertions(+), 1223 deletions(-) rename worlds/stardew_valley/mods/{mod_regions.py => region_data.py} (61%) delete mode 100644 worlds/stardew_valley/region_classes.py delete mode 100644 worlds/stardew_valley/regions.py create mode 100644 worlds/stardew_valley/regions/__init__.py create mode 100644 worlds/stardew_valley/regions/entrance_rando.py create mode 100644 worlds/stardew_valley/regions/model.py create mode 100644 worlds/stardew_valley/regions/mods.py create mode 100644 worlds/stardew_valley/regions/regions.py create mode 100644 worlds/stardew_valley/regions/vanilla_data.py delete mode 100644 worlds/stardew_valley/test/TestRegions.py create mode 100644 worlds/stardew_valley/test/regions/TestEntranceClassifications.py create mode 100644 worlds/stardew_valley/test/regions/TestEntranceRandomization.py create mode 100644 worlds/stardew_valley/test/regions/TestRandomizationFlag.py create mode 100644 worlds/stardew_valley/test/regions/TestRegionConnections.py create mode 100644 worlds/stardew_valley/test/regions/__init__.py diff --git a/worlds/stardew_valley/__init__.py b/worlds/stardew_valley/__init__.py index 9a05c04d5107..ea0ce9e1232d 100644 --- a/worlds/stardew_valley/__init__.py +++ b/worlds/stardew_valley/__init__.py @@ -1,9 +1,10 @@ import logging import typing from random import Random -from typing import Dict, Any, Iterable, Optional, List, TextIO +from typing import Dict, Any, Optional, List, TextIO -from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState +import entrance_rando +from BaseClasses import Region, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState from Options import PerGameCommonOptions from worlds.AutoWorld import World, WebWorld from .bundles.bundle_room import BundleRoom @@ -21,7 +22,7 @@ from .options.option_groups import sv_option_groups from .options.presets import sv_options_presets from .options.worlds_group import apply_most_restrictive_options -from .regions import create_regions +from .regions import create_regions, prepare_mod_data from .rules import set_rules from .stardew_rule import True_, StardewRule, HasProgressionPercent from .strings.ap_names.event_names import Event @@ -124,18 +125,13 @@ def generate_early(self): self.content = create_content(self.options) def create_regions(self): - def create_region(name: str, exits: Iterable[str]) -> Region: - region = Region(name, self.player, self.multiworld) - region.exits = [Entrance(self.player, exit_name, region) for exit_name in exits] - return region + def create_region(name: str) -> Region: + return Region(name, self.player, self.multiworld) - world_regions, world_entrances, self.randomized_entrances = create_regions(create_region, self.random, self.options, self.content) + world_regions = create_regions(create_region, self.options, self.content) self.logic = StardewLogic(self.player, self.options, self.content, world_regions.keys()) - self.modified_bundles = get_all_bundles(self.random, - self.logic, - self.content, - self.options) + self.modified_bundles = get_all_bundles(self.random, self.logic, self.content, self.options) def add_location(name: str, code: Optional[int], region: str): region: Region = world_regions[region] @@ -308,6 +304,11 @@ def create_event_location(self, location_data: LocationData, rule: StardewRule, def set_rules(self): set_rules(self) + def connect_entrances(self) -> None: + no_target_groups = {0: [0]} + placement = entrance_rando.randomize_entrances(self, coupled=True, target_group_lookup=no_target_groups) + self.randomized_entrances = prepare_mod_data(placement) + def generate_basic(self): pass diff --git a/worlds/stardew_valley/content/mods/sve.py b/worlds/stardew_valley/content/mods/sve.py index 12b3e3558a67..2c9edc810615 100644 --- a/worlds/stardew_valley/content/mods/sve.py +++ b/worlds/stardew_valley/content/mods/sve.py @@ -24,6 +24,9 @@ from ...strings.tool_names import Tool, ToolMaterial from ...strings.villager_names import ModNPC +# Used to adapt content not yet moved to content packs to easily detect when SVE and Ginger Island are both enabled. +SVE_GINGER_ISLAND_PACK = ModNames.sve + "+" + ginger_island_content_pack.name + class SVEContentPack(ContentPack): @@ -67,6 +70,10 @@ def harvest_source_hook(self, content: StardewContent): content.game_items.pop(SVESeed.slime) content.game_items.pop(SVEFruit.slime_berry) + def finalize_hook(self, content: StardewContent): + if ginger_island_content_pack.name in content.registered_packs: + content.registered_packs.add(SVE_GINGER_ISLAND_PACK) + register_mod_content_pack(SVEContentPack( ModNames.sve, @@ -80,8 +87,9 @@ def harvest_source_hook(self, content: StardewContent): ModEdible.lightning_elixir: (ShopSource(money_price=12000, shop_region=SVERegion.galmoran_outpost),), ModEdible.barbarian_elixir: (ShopSource(money_price=22000, shop_region=SVERegion.galmoran_outpost),), ModEdible.gravity_elixir: (ShopSource(money_price=4000, shop_region=SVERegion.galmoran_outpost),), - SVEMeal.grampleton_orange_chicken: ( - ShopSource(money_price=650, shop_region=Region.saloon, other_requirements=(RelationshipRequirement(ModNPC.sophia, 6),)),), + SVEMeal.grampleton_orange_chicken: (ShopSource(money_price=650, + shop_region=Region.saloon, + other_requirements=(RelationshipRequirement(ModNPC.sophia, 6),)),), ModEdible.hero_elixir: (ShopSource(money_price=8000, shop_region=SVERegion.isaac_shop),), ModEdible.aegis_elixir: (ShopSource(money_price=28000, shop_region=SVERegion.galmoran_outpost),), SVEBeverage.sports_drink: (ShopSource(money_price=750, shop_region=Region.hospital),), @@ -118,8 +126,8 @@ def harvest_source_hook(self, content: StardewContent): ModLoot.green_mushroom: (ForagingSource(regions=(SVERegion.highlands_pond,), seasons=Season.not_winter),), ModLoot.ornate_treasure_chest: (ForagingSource(regions=(SVERegion.highlands_outside,), - other_requirements=( - CombatRequirement(Performance.galaxy), ToolRequirement(Tool.axe, ToolMaterial.iron))),), + other_requirements=(CombatRequirement(Performance.galaxy), + ToolRequirement(Tool.axe, ToolMaterial.iron))),), ModLoot.swirl_stone: (ForagingSource(regions=(SVERegion.crimson_badlands,), other_requirements=(CombatRequirement(Performance.galaxy),)),), ModLoot.void_soul: (ForagingSource(regions=(SVERegion.crimson_badlands,), other_requirements=(CombatRequirement(Performance.good),)),), SVEForage.winter_star_rose: (ForagingSource(regions=(SVERegion.summit,), seasons=(Season.winter,)),), @@ -139,8 +147,9 @@ def harvest_source_hook(self, content: StardewContent): SVEForage.thistle: (ForagingSource(regions=(SVERegion.summit,)),), ModLoot.void_pebble: (ForagingSource(regions=(SVERegion.crimson_badlands,), other_requirements=(CombatRequirement(Performance.great),)),), ModLoot.void_shard: (ForagingSource(regions=(SVERegion.crimson_badlands,), - other_requirements=( - CombatRequirement(Performance.galaxy), SkillRequirement(Skill.combat, 10), YearRequirement(3),)),), + other_requirements=(CombatRequirement(Performance.galaxy), + SkillRequirement(Skill.combat, 10), + YearRequirement(3),)),), SVEWaterItem.dulse_seaweed: (ForagingSource(regions=(Region.beach,), other_requirements=(FishingRequirement(Region.beach),)),), # Fable Reef diff --git a/worlds/stardew_valley/mods/logic/sve_logic.py b/worlds/stardew_valley/mods/logic/sve_logic.py index 7f0c12bc4f1e..03f1737c5919 100644 --- a/worlds/stardew_valley/mods/logic/sve_logic.py +++ b/worlds/stardew_valley/mods/logic/sve_logic.py @@ -1,8 +1,7 @@ -from ..mod_regions import SVERegion from ...logic.base_logic import BaseLogicMixin, BaseLogic from ...strings.ap_names.mods.mod_items import SVELocation, SVERunes, SVEQuestItem from ...strings.quest_names import Quest, ModQuest -from ...strings.region_names import Region +from ...strings.region_names import Region, SVERegion from ...strings.tool_names import Tool, ToolMaterial from ...strings.wallet_item_names import Wallet diff --git a/worlds/stardew_valley/mods/mod_regions.py b/worlds/stardew_valley/mods/region_data.py similarity index 61% rename from worlds/stardew_valley/mods/mod_regions.py rename to worlds/stardew_valley/mods/region_data.py index a402ba606868..5dc4a3dff28b 100644 --- a/worlds/stardew_valley/mods/mod_regions.py +++ b/worlds/stardew_valley/mods/region_data.py @@ -1,15 +1,14 @@ -from typing import Dict, List - from .mod_data import ModNames -from ..region_classes import RegionData, ConnectionData, ModificationFlag, RandomizationFlag, ModRegionData +from ..content.mods.sve import SVE_GINGER_ISLAND_PACK +from ..regions.model import RegionData, ConnectionData, MergeFlag, RandomizationFlag, ModRegionsData from ..strings.entrance_names import Entrance, DeepWoodsEntrance, EugeneEntrance, LaceyEntrance, BoardingHouseEntrance, \ JasperEntrance, AlecEntrance, YobaEntrance, JunaEntrance, MagicEntrance, AyeishaEntrance, RileyEntrance, SVEEntrance, AlectoEntrance from ..strings.region_names import Region, DeepWoodsRegion, EugeneRegion, JasperRegion, BoardingHouseRegion, \ AlecRegion, YobaRegion, JunaRegion, MagicRegion, AyeishaRegion, RileyRegion, SVERegion, AlectoRegion, LaceyRegion deep_woods_regions = [ - RegionData(Region.farm, [DeepWoodsEntrance.use_woods_obelisk]), - RegionData(DeepWoodsRegion.woods_obelisk_menu, [DeepWoodsEntrance.deep_woods_depth_1, + RegionData(Region.farm, (DeepWoodsEntrance.use_woods_obelisk,)), + RegionData(DeepWoodsRegion.woods_obelisk_menu, (DeepWoodsEntrance.deep_woods_depth_1, DeepWoodsEntrance.deep_woods_depth_10, DeepWoodsEntrance.deep_woods_depth_20, DeepWoodsEntrance.deep_woods_depth_30, @@ -19,9 +18,9 @@ DeepWoodsEntrance.deep_woods_depth_70, DeepWoodsEntrance.deep_woods_depth_80, DeepWoodsEntrance.deep_woods_depth_90, - DeepWoodsEntrance.deep_woods_depth_100]), - RegionData(Region.secret_woods, [DeepWoodsEntrance.secret_woods_to_deep_woods]), - RegionData(DeepWoodsRegion.main_lichtung, [DeepWoodsEntrance.deep_woods_house]), + DeepWoodsEntrance.deep_woods_depth_100)), + RegionData(Region.secret_woods, (DeepWoodsEntrance.secret_woods_to_deep_woods,)), + RegionData(DeepWoodsRegion.main_lichtung, (DeepWoodsEntrance.deep_woods_house,)), RegionData(DeepWoodsRegion.abandoned_home), RegionData(DeepWoodsRegion.floor_10), RegionData(DeepWoodsRegion.floor_20), @@ -32,14 +31,13 @@ RegionData(DeepWoodsRegion.floor_70), RegionData(DeepWoodsRegion.floor_80), RegionData(DeepWoodsRegion.floor_90), - RegionData(DeepWoodsRegion.floor_100) + RegionData(DeepWoodsRegion.floor_100), ] deep_woods_entrances = [ ConnectionData(DeepWoodsEntrance.use_woods_obelisk, DeepWoodsRegion.woods_obelisk_menu), ConnectionData(DeepWoodsEntrance.secret_woods_to_deep_woods, DeepWoodsRegion.main_lichtung), - ConnectionData(DeepWoodsEntrance.deep_woods_house, DeepWoodsRegion.abandoned_home, - flag=RandomizationFlag.NON_PROGRESSION), + ConnectionData(DeepWoodsEntrance.deep_woods_house, DeepWoodsRegion.abandoned_home, flag=RandomizationFlag.BUILDINGS), ConnectionData(DeepWoodsEntrance.deep_woods_depth_1, DeepWoodsRegion.main_lichtung), ConnectionData(DeepWoodsEntrance.deep_woods_depth_10, DeepWoodsRegion.floor_10), ConnectionData(DeepWoodsEntrance.deep_woods_depth_20, DeepWoodsRegion.floor_20), @@ -50,165 +48,166 @@ ConnectionData(DeepWoodsEntrance.deep_woods_depth_70, DeepWoodsRegion.floor_70), ConnectionData(DeepWoodsEntrance.deep_woods_depth_80, DeepWoodsRegion.floor_80), ConnectionData(DeepWoodsEntrance.deep_woods_depth_90, DeepWoodsRegion.floor_90), - ConnectionData(DeepWoodsEntrance.deep_woods_depth_100, DeepWoodsRegion.floor_100) + ConnectionData(DeepWoodsEntrance.deep_woods_depth_100, DeepWoodsRegion.floor_100), ] eugene_regions = [ - RegionData(Region.forest, [EugeneEntrance.forest_to_garden]), - RegionData(EugeneRegion.eugene_garden, [EugeneEntrance.garden_to_bedroom]), - RegionData(EugeneRegion.eugene_bedroom) + RegionData(Region.forest, (EugeneEntrance.forest_to_garden,)), + RegionData(EugeneRegion.eugene_garden, (EugeneEntrance.garden_to_bedroom,)), + RegionData(EugeneRegion.eugene_bedroom), ] eugene_entrances = [ ConnectionData(EugeneEntrance.forest_to_garden, EugeneRegion.eugene_garden, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(EugeneEntrance.garden_to_bedroom, EugeneRegion.eugene_bedroom, flag=RandomizationFlag.BUILDINGS) + ConnectionData(EugeneEntrance.garden_to_bedroom, EugeneRegion.eugene_bedroom, flag=RandomizationFlag.BUILDINGS), ] magic_regions = [ - RegionData(Region.pierre_store, [MagicEntrance.store_to_altar]), - RegionData(MagicRegion.altar) + RegionData(Region.pierre_store, (MagicEntrance.store_to_altar,)), + RegionData(MagicRegion.altar), ] magic_entrances = [ - ConnectionData(MagicEntrance.store_to_altar, MagicRegion.altar, flag=RandomizationFlag.NOT_RANDOMIZED) + ConnectionData(MagicEntrance.store_to_altar, MagicRegion.altar, flag=RandomizationFlag.NOT_RANDOMIZED), ] jasper_regions = [ - RegionData(Region.museum, [JasperEntrance.museum_to_bedroom]), - RegionData(JasperRegion.jasper_bedroom) + RegionData(Region.museum, (JasperEntrance.museum_to_bedroom,)), + RegionData(JasperRegion.jasper_bedroom), ] jasper_entrances = [ - ConnectionData(JasperEntrance.museum_to_bedroom, JasperRegion.jasper_bedroom, flag=RandomizationFlag.BUILDINGS) + ConnectionData(JasperEntrance.museum_to_bedroom, JasperRegion.jasper_bedroom, flag=RandomizationFlag.BUILDINGS), ] alec_regions = [ - RegionData(Region.forest, [AlecEntrance.forest_to_petshop]), - RegionData(AlecRegion.pet_store, [AlecEntrance.petshop_to_bedroom]), - RegionData(AlecRegion.alec_bedroom) + RegionData(Region.forest, (AlecEntrance.forest_to_petshop,)), + RegionData(AlecRegion.pet_store, (AlecEntrance.petshop_to_bedroom,)), + RegionData(AlecRegion.alec_bedroom), ] alec_entrances = [ ConnectionData(AlecEntrance.forest_to_petshop, AlecRegion.pet_store, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(AlecEntrance.petshop_to_bedroom, AlecRegion.alec_bedroom, flag=RandomizationFlag.BUILDINGS) + ConnectionData(AlecEntrance.petshop_to_bedroom, AlecRegion.alec_bedroom, flag=RandomizationFlag.BUILDINGS), ] yoba_regions = [ - RegionData(Region.secret_woods, [YobaEntrance.secret_woods_to_clearing]), - RegionData(YobaRegion.yoba_clearing) + RegionData(Region.secret_woods, (YobaEntrance.secret_woods_to_clearing,)), + RegionData(YobaRegion.yoba_clearing), ] yoba_entrances = [ - ConnectionData(YobaEntrance.secret_woods_to_clearing, YobaRegion.yoba_clearing, flag=RandomizationFlag.BUILDINGS) + ConnectionData(YobaEntrance.secret_woods_to_clearing, YobaRegion.yoba_clearing, flag=RandomizationFlag.BUILDINGS), ] juna_regions = [ - RegionData(Region.forest, [JunaEntrance.forest_to_juna_cave]), - RegionData(JunaRegion.juna_cave) + RegionData(Region.forest, (JunaEntrance.forest_to_juna_cave,)), + RegionData(JunaRegion.juna_cave), ] juna_entrances = [ ConnectionData(JunaEntrance.forest_to_juna_cave, JunaRegion.juna_cave, - flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA) + flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), ] ayeisha_regions = [ - RegionData(Region.bus_stop, [AyeishaEntrance.bus_stop_to_mail_van]), - RegionData(AyeishaRegion.mail_van) + RegionData(Region.bus_stop, (AyeishaEntrance.bus_stop_to_mail_van,)), + RegionData(AyeishaRegion.mail_van), ] ayeisha_entrances = [ ConnectionData(AyeishaEntrance.bus_stop_to_mail_van, AyeishaRegion.mail_van, - flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA) + flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), ] riley_regions = [ - RegionData(Region.town, [RileyEntrance.town_to_riley]), - RegionData(RileyRegion.riley_house) + RegionData(Region.town, (RileyEntrance.town_to_riley,)), + RegionData(RileyRegion.riley_house), ] riley_entrances = [ ConnectionData(RileyEntrance.town_to_riley, RileyRegion.riley_house, - flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA) + flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), ] -stardew_valley_expanded_regions = [ - RegionData(Region.backwoods, [SVEEntrance.backwoods_to_grove]), - RegionData(SVERegion.enchanted_grove, [SVEEntrance.grove_to_outpost_warp, SVEEntrance.grove_to_wizard_warp, +sve_main_land_regions = [ + RegionData(Region.backwoods, (SVEEntrance.backwoods_to_grove,)), + RegionData(SVERegion.enchanted_grove, (SVEEntrance.grove_to_outpost_warp, SVEEntrance.grove_to_wizard_warp, SVEEntrance.grove_to_farm_warp, SVEEntrance.grove_to_guild_warp, SVEEntrance.grove_to_junimo_warp, - SVEEntrance.grove_to_spring_warp, SVEEntrance.grove_to_aurora_warp]), - RegionData(SVERegion.grove_farm_warp, [SVEEntrance.farm_warp_to_farm]), - RegionData(SVERegion.grove_aurora_warp, [SVEEntrance.aurora_warp_to_aurora]), - RegionData(SVERegion.grove_guild_warp, [SVEEntrance.guild_warp_to_guild]), - RegionData(SVERegion.grove_junimo_warp, [SVEEntrance.junimo_warp_to_junimo]), - RegionData(SVERegion.grove_spring_warp, [SVEEntrance.spring_warp_to_spring]), - RegionData(SVERegion.grove_outpost_warp, [SVEEntrance.outpost_warp_to_outpost]), - RegionData(SVERegion.grove_wizard_warp, [SVEEntrance.wizard_warp_to_wizard]), - RegionData(SVERegion.galmoran_outpost, [SVEEntrance.outpost_to_badlands_entrance, SVEEntrance.use_alesia_shop, - SVEEntrance.use_isaac_shop]), - RegionData(SVERegion.badlands_entrance, [SVEEntrance.badlands_entrance_to_badlands]), - RegionData(SVERegion.crimson_badlands, [SVEEntrance.badlands_to_cave]), + SVEEntrance.grove_to_spring_warp, SVEEntrance.grove_to_aurora_warp)), + RegionData(SVERegion.grove_farm_warp, (SVEEntrance.farm_warp_to_farm,)), + RegionData(SVERegion.grove_aurora_warp, (SVEEntrance.aurora_warp_to_aurora,)), + RegionData(SVERegion.grove_guild_warp, (SVEEntrance.guild_warp_to_guild,)), + RegionData(SVERegion.grove_junimo_warp, (SVEEntrance.junimo_warp_to_junimo,)), + RegionData(SVERegion.grove_spring_warp, (SVEEntrance.spring_warp_to_spring,)), + RegionData(SVERegion.grove_outpost_warp, (SVEEntrance.outpost_warp_to_outpost,)), + RegionData(SVERegion.grove_wizard_warp, (SVEEntrance.wizard_warp_to_wizard,)), + RegionData(SVERegion.galmoran_outpost, (SVEEntrance.outpost_to_badlands_entrance, SVEEntrance.use_alesia_shop, SVEEntrance.use_isaac_shop)), + RegionData(SVERegion.badlands_entrance, (SVEEntrance.badlands_entrance_to_badlands,)), + RegionData(SVERegion.crimson_badlands, (SVEEntrance.badlands_to_cave,)), RegionData(SVERegion.badlands_cave), - RegionData(Region.bus_stop, [SVEEntrance.bus_stop_to_shed]), - RegionData(SVERegion.grandpas_shed, [SVEEntrance.grandpa_shed_to_interior, SVEEntrance.grandpa_shed_to_town]), - RegionData(SVERegion.grandpas_shed_interior, [SVEEntrance.grandpa_interior_to_upstairs]), + RegionData(Region.bus_stop, (SVEEntrance.bus_stop_to_shed,)), + RegionData(SVERegion.grandpas_shed, (SVEEntrance.grandpa_shed_to_interior, SVEEntrance.grandpa_shed_to_town)), + RegionData(SVERegion.grandpas_shed_interior, (SVEEntrance.grandpa_interior_to_upstairs,)), RegionData(SVERegion.grandpas_shed_upstairs), RegionData(Region.forest, - [SVEEntrance.forest_to_fairhaven, SVEEntrance.forest_to_west, SVEEntrance.forest_to_lost_woods, - SVEEntrance.forest_to_bmv, SVEEntrance.forest_to_marnie_shed]), + (SVEEntrance.forest_to_fairhaven, SVEEntrance.forest_to_west, SVEEntrance.forest_to_lost_woods, + SVEEntrance.forest_to_bmv, SVEEntrance.forest_to_marnie_shed)), RegionData(SVERegion.marnies_shed), RegionData(SVERegion.fairhaven_farm), - RegionData(Region.town, [SVEEntrance.town_to_bmv, SVEEntrance.town_to_jenkins, - SVEEntrance.town_to_bridge, SVEEntrance.town_to_plot]), - RegionData(SVERegion.blue_moon_vineyard, [SVEEntrance.bmv_to_sophia, SVEEntrance.bmv_to_beach]), + RegionData(Region.town, (SVEEntrance.town_to_bmv, SVEEntrance.town_to_jenkins, SVEEntrance.town_to_bridge, SVEEntrance.town_to_plot)), + RegionData(SVERegion.blue_moon_vineyard, (SVEEntrance.bmv_to_sophia, SVEEntrance.bmv_to_beach)), RegionData(SVERegion.sophias_house), - RegionData(SVERegion.jenkins_residence, [SVEEntrance.jenkins_to_cellar]), + RegionData(SVERegion.jenkins_residence, (SVEEntrance.jenkins_to_cellar,)), RegionData(SVERegion.jenkins_cellar), - RegionData(SVERegion.unclaimed_plot, [SVEEntrance.plot_to_bridge]), + RegionData(SVERegion.unclaimed_plot, (SVEEntrance.plot_to_bridge,)), RegionData(SVERegion.shearwater), - RegionData(Region.museum, [SVEEntrance.museum_to_gunther_bedroom]), + RegionData(Region.museum, (SVEEntrance.museum_to_gunther_bedroom,)), RegionData(SVERegion.gunther_bedroom), - RegionData(Region.fish_shop, [SVEEntrance.fish_shop_to_willy_bedroom]), + RegionData(Region.fish_shop, (SVEEntrance.fish_shop_to_willy_bedroom,)), RegionData(SVERegion.willy_bedroom), - RegionData(Region.mountain, [SVEEntrance.mountain_to_guild_summit]), - RegionData(SVERegion.guild_summit, [SVEEntrance.guild_to_interior, SVEEntrance.guild_to_mines, - SVEEntrance.summit_to_highlands]), - RegionData(Region.railroad, [SVEEntrance.to_susan_house, SVEEntrance.enter_summit, SVEEntrance.railroad_to_grampleton_station]), - RegionData(SVERegion.grampleton_station, [SVEEntrance.grampleton_station_to_grampleton_suburbs]), - RegionData(SVERegion.grampleton_suburbs, [SVEEntrance.grampleton_suburbs_to_scarlett_house]), + RegionData(Region.mountain, (SVEEntrance.mountain_to_guild_summit,)), + # These entrances are removed from the mountain region when SVE is enabled + RegionData(Region.mountain, (Entrance.mountain_to_adventurer_guild, Entrance.mountain_to_the_mines), flag=MergeFlag.REMOVE_EXITS), + RegionData(SVERegion.guild_summit, (SVEEntrance.guild_to_interior, SVEEntrance.guild_to_mines)), + RegionData(Region.railroad, (SVEEntrance.to_susan_house, SVEEntrance.enter_summit, SVEEntrance.railroad_to_grampleton_station)), + RegionData(SVERegion.grampleton_station, (SVEEntrance.grampleton_station_to_grampleton_suburbs,)), + RegionData(SVERegion.grampleton_suburbs, (SVEEntrance.grampleton_suburbs_to_scarlett_house,)), RegionData(SVERegion.scarlett_house), - RegionData(Region.wizard_basement, [SVEEntrance.wizard_to_fable_reef]), - RegionData(SVERegion.fable_reef, [SVEEntrance.fable_reef_to_guild], is_ginger_island=True), - RegionData(SVERegion.first_slash_guild, [SVEEntrance.first_slash_guild_to_hallway], is_ginger_island=True), - RegionData(SVERegion.first_slash_hallway, [SVEEntrance.first_slash_hallway_to_room], is_ginger_island=True), - RegionData(SVERegion.first_slash_spare_room, is_ginger_island=True), - RegionData(SVERegion.highlands_outside, [SVEEntrance.highlands_to_lance, SVEEntrance.highlands_to_cave, SVEEntrance.highlands_to_pond], is_ginger_island=True), - RegionData(SVERegion.highlands_pond, is_ginger_island=True), - RegionData(SVERegion.highlands_cavern, [SVEEntrance.to_dwarf_prison], is_ginger_island=True), - RegionData(SVERegion.dwarf_prison, is_ginger_island=True), - RegionData(SVERegion.lances_house, [SVEEntrance.lance_to_ladder], is_ginger_island=True), - RegionData(SVERegion.lances_ladder, [SVEEntrance.lance_ladder_to_highlands], is_ginger_island=True), - RegionData(SVERegion.forest_west, [SVEEntrance.forest_west_to_spring, SVEEntrance.west_to_aurora, - SVEEntrance.use_bear_shop]), - RegionData(SVERegion.aurora_vineyard, [SVEEntrance.to_aurora_basement]), + RegionData(SVERegion.forest_west, (SVEEntrance.forest_west_to_spring, SVEEntrance.west_to_aurora, SVEEntrance.use_bear_shop,)), + RegionData(SVERegion.aurora_vineyard, (SVEEntrance.to_aurora_basement,)), RegionData(SVERegion.aurora_vineyard_basement), - RegionData(Region.secret_woods, [SVEEntrance.secret_woods_to_west]), + RegionData(Region.secret_woods, (SVEEntrance.secret_woods_to_west,)), RegionData(SVERegion.bear_shop), - RegionData(SVERegion.sprite_spring, [SVEEntrance.sprite_spring_to_cave]), + RegionData(SVERegion.sprite_spring, (SVEEntrance.sprite_spring_to_cave,)), RegionData(SVERegion.sprite_spring_cave), - RegionData(SVERegion.lost_woods, [SVEEntrance.lost_woods_to_junimo_woods]), - RegionData(SVERegion.junimo_woods, [SVEEntrance.use_purple_junimo]), + RegionData(SVERegion.lost_woods, (SVEEntrance.lost_woods_to_junimo_woods,)), + RegionData(SVERegion.junimo_woods, (SVEEntrance.use_purple_junimo,)), RegionData(SVERegion.purple_junimo_shop), RegionData(SVERegion.alesia_shop), RegionData(SVERegion.isaac_shop), RegionData(SVERegion.summit), RegionData(SVERegion.susans_house), - RegionData(Region.mountain, [Entrance.mountain_to_adventurer_guild, Entrance.mountain_to_the_mines], ModificationFlag.MODIFIED) +] + +sve_ginger_island_regions = [ + RegionData(Region.wizard_basement, (SVEEntrance.wizard_to_fable_reef,)), + RegionData(SVERegion.fable_reef, (SVEEntrance.fable_reef_to_guild,)), + RegionData(SVERegion.first_slash_guild, (SVEEntrance.first_slash_guild_to_hallway,)), + RegionData(SVERegion.first_slash_hallway, (SVEEntrance.first_slash_hallway_to_room,)), + RegionData(SVERegion.first_slash_spare_room), + RegionData(SVERegion.guild_summit, (SVEEntrance.summit_to_highlands,)), + RegionData(SVERegion.highlands_outside, (SVEEntrance.highlands_to_lance, SVEEntrance.highlands_to_cave, SVEEntrance.highlands_to_pond), ), + RegionData(SVERegion.highlands_pond), + RegionData(SVERegion.highlands_cavern, (SVEEntrance.to_dwarf_prison,)), + RegionData(SVERegion.dwarf_prison), + RegionData(SVERegion.lances_house, (SVEEntrance.lance_to_ladder,)), + RegionData(SVERegion.lances_ladder, (SVEEntrance.lance_ladder_to_highlands,)), ] -mandatory_sve_connections = [ +sve_main_land_connections = [ ConnectionData(SVEEntrance.town_to_jenkins, SVERegion.jenkins_residence, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), ConnectionData(SVEEntrance.jenkins_to_cellar, SVERegion.jenkins_cellar, flag=RandomizationFlag.BUILDINGS), ConnectionData(SVEEntrance.forest_to_bmv, SVERegion.blue_moon_vineyard), @@ -223,7 +222,7 @@ ConnectionData(SVEEntrance.grandpa_interior_to_upstairs, SVERegion.grandpas_shed_upstairs, flag=RandomizationFlag.BUILDINGS), ConnectionData(SVEEntrance.grandpa_shed_to_town, Region.town), ConnectionData(SVEEntrance.bmv_to_sophia, SVERegion.sophias_house, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(SVEEntrance.summit_to_highlands, SVERegion.highlands_outside, flag=RandomizationFlag.GINGER_ISLAND), + ConnectionData(SVEEntrance.summit_to_highlands, SVERegion.highlands_outside), ConnectionData(SVEEntrance.guild_to_interior, Region.adventurer_guild, flag=RandomizationFlag.BUILDINGS), ConnectionData(SVEEntrance.backwoods_to_grove, SVERegion.enchanted_grove, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), ConnectionData(SVEEntrance.grove_to_outpost_warp, SVERegion.grove_outpost_warp), @@ -242,8 +241,6 @@ ConnectionData(SVEEntrance.use_purple_junimo, SVERegion.purple_junimo_shop), ConnectionData(SVEEntrance.grove_to_spring_warp, SVERegion.grove_spring_warp), ConnectionData(SVEEntrance.spring_warp_to_spring, SVERegion.sprite_spring, flag=RandomizationFlag.BUILDINGS), - ConnectionData(SVEEntrance.wizard_to_fable_reef, SVERegion.fable_reef, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(SVEEntrance.fable_reef_to_guild, SVERegion.first_slash_guild, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), ConnectionData(SVEEntrance.outpost_to_badlands_entrance, SVERegion.badlands_entrance, flag=RandomizationFlag.BUILDINGS), ConnectionData(SVEEntrance.badlands_entrance_to_badlands, SVERegion.crimson_badlands, flag=RandomizationFlag.BUILDINGS), ConnectionData(SVEEntrance.badlands_to_cave, SVERegion.badlands_cave, flag=RandomizationFlag.BUILDINGS), @@ -259,71 +256,75 @@ ConnectionData(SVEEntrance.to_susan_house, SVERegion.susans_house, flag=RandomizationFlag.BUILDINGS), ConnectionData(SVEEntrance.enter_summit, SVERegion.summit, flag=RandomizationFlag.BUILDINGS), ConnectionData(SVEEntrance.forest_to_fairhaven, SVERegion.fairhaven_farm, flag=RandomizationFlag.NON_PROGRESSION), - ConnectionData(SVEEntrance.highlands_to_lance, SVERegion.lances_house, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(SVEEntrance.lance_to_ladder, SVERegion.lances_ladder, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(SVEEntrance.lance_ladder_to_highlands, SVERegion.highlands_outside, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(SVEEntrance.highlands_to_cave, SVERegion.highlands_cavern, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), ConnectionData(SVEEntrance.use_bear_shop, SVERegion.bear_shop), ConnectionData(SVEEntrance.use_purple_junimo, SVERegion.purple_junimo_shop), ConnectionData(SVEEntrance.use_alesia_shop, SVERegion.alesia_shop), ConnectionData(SVEEntrance.use_isaac_shop, SVERegion.isaac_shop), - ConnectionData(SVEEntrance.to_dwarf_prison, SVERegion.dwarf_prison, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), ConnectionData(SVEEntrance.railroad_to_grampleton_station, SVERegion.grampleton_station), ConnectionData(SVEEntrance.grampleton_station_to_grampleton_suburbs, SVERegion.grampleton_suburbs), ConnectionData(SVEEntrance.grampleton_suburbs_to_scarlett_house, SVERegion.scarlett_house, flag=RandomizationFlag.BUILDINGS), - ConnectionData(SVEEntrance.first_slash_guild_to_hallway, SVERegion.first_slash_hallway, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(SVEEntrance.first_slash_hallway_to_room, SVERegion.first_slash_spare_room, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), ConnectionData(SVEEntrance.sprite_spring_to_cave, SVERegion.sprite_spring_cave, flag=RandomizationFlag.BUILDINGS), ConnectionData(SVEEntrance.fish_shop_to_willy_bedroom, SVERegion.willy_bedroom, flag=RandomizationFlag.BUILDINGS), ConnectionData(SVEEntrance.museum_to_gunther_bedroom, SVERegion.gunther_bedroom, flag=RandomizationFlag.BUILDINGS), ConnectionData(SVEEntrance.highlands_to_pond, SVERegion.highlands_pond), ] +sve_ginger_island_connections = [ + ConnectionData(SVEEntrance.wizard_to_fable_reef, SVERegion.fable_reef, flag=RandomizationFlag.BUILDINGS), + ConnectionData(SVEEntrance.fable_reef_to_guild, SVERegion.first_slash_guild, flag=RandomizationFlag.BUILDINGS), + ConnectionData(SVEEntrance.highlands_to_lance, SVERegion.lances_house, flag=RandomizationFlag.BUILDINGS), + ConnectionData(SVEEntrance.lance_to_ladder, SVERegion.lances_ladder), + ConnectionData(SVEEntrance.lance_ladder_to_highlands, SVERegion.highlands_outside, flag=RandomizationFlag.BUILDINGS), + ConnectionData(SVEEntrance.highlands_to_cave, SVERegion.highlands_cavern, flag=RandomizationFlag.BUILDINGS), + ConnectionData(SVEEntrance.to_dwarf_prison, SVERegion.dwarf_prison, flag=RandomizationFlag.BUILDINGS), + ConnectionData(SVEEntrance.first_slash_guild_to_hallway, SVERegion.first_slash_hallway, flag=RandomizationFlag.BUILDINGS), + ConnectionData(SVEEntrance.first_slash_hallway_to_room, SVERegion.first_slash_spare_room, flag=RandomizationFlag.BUILDINGS), +] + alecto_regions = [ - RegionData(Region.witch_hut, [AlectoEntrance.witch_hut_to_witch_attic]), - RegionData(AlectoRegion.witch_attic) + RegionData(Region.witch_hut, (AlectoEntrance.witch_hut_to_witch_attic,)), + RegionData(AlectoRegion.witch_attic), ] alecto_entrances = [ - ConnectionData(AlectoEntrance.witch_hut_to_witch_attic, AlectoRegion.witch_attic, flag=RandomizationFlag.BUILDINGS) + ConnectionData(AlectoEntrance.witch_hut_to_witch_attic, AlectoRegion.witch_attic, flag=RandomizationFlag.BUILDINGS), ] lacey_regions = [ - RegionData(Region.forest, [LaceyEntrance.forest_to_hat_house]), - RegionData(LaceyRegion.hat_house) + RegionData(Region.forest, (LaceyEntrance.forest_to_hat_house,)), + RegionData(LaceyRegion.hat_house), ] lacey_entrances = [ - ConnectionData(LaceyEntrance.forest_to_hat_house, LaceyRegion.hat_house, flag=RandomizationFlag.BUILDINGS) + ConnectionData(LaceyEntrance.forest_to_hat_house, LaceyRegion.hat_house, flag=RandomizationFlag.BUILDINGS), ] boarding_house_regions = [ - RegionData(Region.bus_stop, [BoardingHouseEntrance.bus_stop_to_boarding_house_plateau]), - RegionData(BoardingHouseRegion.boarding_house_plateau, [BoardingHouseEntrance.boarding_house_plateau_to_boarding_house_first, + RegionData(Region.bus_stop, (BoardingHouseEntrance.bus_stop_to_boarding_house_plateau,)), + RegionData(BoardingHouseRegion.boarding_house_plateau, (BoardingHouseEntrance.boarding_house_plateau_to_boarding_house_first, BoardingHouseEntrance.boarding_house_plateau_to_buffalo_ranch, - BoardingHouseEntrance.boarding_house_plateau_to_abandoned_mines_entrance]), - RegionData(BoardingHouseRegion.boarding_house_first, [BoardingHouseEntrance.boarding_house_first_to_boarding_house_second]), + BoardingHouseEntrance.boarding_house_plateau_to_abandoned_mines_entrance)), + RegionData(BoardingHouseRegion.boarding_house_first, (BoardingHouseEntrance.boarding_house_first_to_boarding_house_second,)), RegionData(BoardingHouseRegion.boarding_house_second), RegionData(BoardingHouseRegion.buffalo_ranch), - RegionData(BoardingHouseRegion.abandoned_mines_entrance, [BoardingHouseEntrance.abandoned_mines_entrance_to_abandoned_mines_1a, - BoardingHouseEntrance.abandoned_mines_entrance_to_the_lost_valley]), - RegionData(BoardingHouseRegion.abandoned_mines_1a, [BoardingHouseEntrance.abandoned_mines_1a_to_abandoned_mines_1b]), - RegionData(BoardingHouseRegion.abandoned_mines_1b, [BoardingHouseEntrance.abandoned_mines_1b_to_abandoned_mines_2a]), - RegionData(BoardingHouseRegion.abandoned_mines_2a, [BoardingHouseEntrance.abandoned_mines_2a_to_abandoned_mines_2b]), - RegionData(BoardingHouseRegion.abandoned_mines_2b, [BoardingHouseEntrance.abandoned_mines_2b_to_abandoned_mines_3]), - RegionData(BoardingHouseRegion.abandoned_mines_3, [BoardingHouseEntrance.abandoned_mines_3_to_abandoned_mines_4]), - RegionData(BoardingHouseRegion.abandoned_mines_4, [BoardingHouseEntrance.abandoned_mines_4_to_abandoned_mines_5]), - RegionData(BoardingHouseRegion.abandoned_mines_5, [BoardingHouseEntrance.abandoned_mines_5_to_the_lost_valley]), - RegionData(BoardingHouseRegion.the_lost_valley, [BoardingHouseEntrance.the_lost_valley_to_gregory_tent, + RegionData(BoardingHouseRegion.abandoned_mines_entrance, (BoardingHouseEntrance.abandoned_mines_entrance_to_abandoned_mines_1a, + BoardingHouseEntrance.abandoned_mines_entrance_to_the_lost_valley)), + RegionData(BoardingHouseRegion.abandoned_mines_1a, (BoardingHouseEntrance.abandoned_mines_1a_to_abandoned_mines_1b,)), + RegionData(BoardingHouseRegion.abandoned_mines_1b, (BoardingHouseEntrance.abandoned_mines_1b_to_abandoned_mines_2a,)), + RegionData(BoardingHouseRegion.abandoned_mines_2a, (BoardingHouseEntrance.abandoned_mines_2a_to_abandoned_mines_2b,)), + RegionData(BoardingHouseRegion.abandoned_mines_2b, (BoardingHouseEntrance.abandoned_mines_2b_to_abandoned_mines_3,)), + RegionData(BoardingHouseRegion.abandoned_mines_3, (BoardingHouseEntrance.abandoned_mines_3_to_abandoned_mines_4,)), + RegionData(BoardingHouseRegion.abandoned_mines_4, (BoardingHouseEntrance.abandoned_mines_4_to_abandoned_mines_5,)), + RegionData(BoardingHouseRegion.abandoned_mines_5, (BoardingHouseEntrance.abandoned_mines_5_to_the_lost_valley,)), + RegionData(BoardingHouseRegion.the_lost_valley, (BoardingHouseEntrance.the_lost_valley_to_gregory_tent, BoardingHouseEntrance.lost_valley_to_lost_valley_minecart, - BoardingHouseEntrance.the_lost_valley_to_lost_valley_ruins]), + BoardingHouseEntrance.the_lost_valley_to_lost_valley_ruins)), RegionData(BoardingHouseRegion.gregory_tent), - RegionData(BoardingHouseRegion.lost_valley_ruins, [BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_1, - BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_2]), + RegionData(BoardingHouseRegion.lost_valley_ruins, (BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_1, + BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_2)), RegionData(BoardingHouseRegion.lost_valley_minecart), RegionData(BoardingHouseRegion.lost_valley_house_1), - RegionData(BoardingHouseRegion.lost_valley_house_2) + RegionData(BoardingHouseRegion.lost_valley_house_2), ] boarding_house_entrances = [ @@ -351,30 +352,29 @@ ConnectionData(BoardingHouseEntrance.lost_valley_to_lost_valley_minecart, BoardingHouseRegion.lost_valley_minecart), ConnectionData(BoardingHouseEntrance.the_lost_valley_to_lost_valley_ruins, BoardingHouseRegion.lost_valley_ruins, flag=RandomizationFlag.BUILDINGS), ConnectionData(BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_1, BoardingHouseRegion.lost_valley_house_1, flag=RandomizationFlag.BUILDINGS), - ConnectionData(BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_2, BoardingHouseRegion.lost_valley_house_2, flag=RandomizationFlag.BUILDINGS) + ConnectionData(BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_2, BoardingHouseRegion.lost_valley_house_2, flag=RandomizationFlag.BUILDINGS), ] -vanilla_connections_to_remove_by_mod: Dict[str, List[ConnectionData]] = { - ModNames.sve: [ - ConnectionData(Entrance.mountain_to_the_mines, Region.mines, - flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.mountain_to_adventurer_guild, Region.adventurer_guild, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ] +vanilla_connections_to_remove_by_content_pack: dict[str, tuple[str, ...]] = { + ModNames.sve: ( + Entrance.mountain_to_the_mines, + Entrance.mountain_to_adventurer_guild, + ) } -ModDataList = { - ModNames.deepwoods: ModRegionData(ModNames.deepwoods, deep_woods_regions, deep_woods_entrances), - ModNames.eugene: ModRegionData(ModNames.eugene, eugene_regions, eugene_entrances), - ModNames.jasper: ModRegionData(ModNames.jasper, jasper_regions, jasper_entrances), - ModNames.alec: ModRegionData(ModNames.alec, alec_regions, alec_entrances), - ModNames.yoba: ModRegionData(ModNames.yoba, yoba_regions, yoba_entrances), - ModNames.juna: ModRegionData(ModNames.juna, juna_regions, juna_entrances), - ModNames.magic: ModRegionData(ModNames.magic, magic_regions, magic_entrances), - ModNames.ayeisha: ModRegionData(ModNames.ayeisha, ayeisha_regions, ayeisha_entrances), - ModNames.riley: ModRegionData(ModNames.riley, riley_regions, riley_entrances), - ModNames.sve: ModRegionData(ModNames.sve, stardew_valley_expanded_regions, mandatory_sve_connections), - ModNames.alecto: ModRegionData(ModNames.alecto, alecto_regions, alecto_entrances), - ModNames.lacey: ModRegionData(ModNames.lacey, lacey_regions, lacey_entrances), - ModNames.boarding_house: ModRegionData(ModNames.boarding_house, boarding_house_regions, boarding_house_entrances), +region_data_by_content_pack = { + ModNames.deepwoods: ModRegionsData(ModNames.deepwoods, deep_woods_regions, deep_woods_entrances), + ModNames.eugene: ModRegionsData(ModNames.eugene, eugene_regions, eugene_entrances), + ModNames.jasper: ModRegionsData(ModNames.jasper, jasper_regions, jasper_entrances), + ModNames.alec: ModRegionsData(ModNames.alec, alec_regions, alec_entrances), + ModNames.yoba: ModRegionsData(ModNames.yoba, yoba_regions, yoba_entrances), + ModNames.juna: ModRegionsData(ModNames.juna, juna_regions, juna_entrances), + ModNames.magic: ModRegionsData(ModNames.magic, magic_regions, magic_entrances), + ModNames.ayeisha: ModRegionsData(ModNames.ayeisha, ayeisha_regions, ayeisha_entrances), + ModNames.riley: ModRegionsData(ModNames.riley, riley_regions, riley_entrances), + ModNames.sve: ModRegionsData(ModNames.sve, sve_main_land_regions, sve_main_land_connections), + SVE_GINGER_ISLAND_PACK: ModRegionsData(SVE_GINGER_ISLAND_PACK, sve_ginger_island_regions, sve_ginger_island_connections), + ModNames.alecto: ModRegionsData(ModNames.alecto, alecto_regions, alecto_entrances), + ModNames.lacey: ModRegionsData(ModNames.lacey, lacey_regions, lacey_entrances), + ModNames.boarding_house: ModRegionsData(ModNames.boarding_house, boarding_house_regions, boarding_house_entrances), } diff --git a/worlds/stardew_valley/region_classes.py b/worlds/stardew_valley/region_classes.py deleted file mode 100644 index d3d16e3878bb..000000000000 --- a/worlds/stardew_valley/region_classes.py +++ /dev/null @@ -1,67 +0,0 @@ -from copy import deepcopy -from dataclasses import dataclass, field -from enum import IntFlag -from typing import Optional, List, Set - -connector_keyword = " to " - - -class ModificationFlag(IntFlag): - NOT_MODIFIED = 0 - MODIFIED = 1 - - -class RandomizationFlag(IntFlag): - NOT_RANDOMIZED = 0b0 - PELICAN_TOWN = 0b00011111 - NON_PROGRESSION = 0b00011110 - BUILDINGS = 0b00011100 - EVERYTHING = 0b00011000 - GINGER_ISLAND = 0b00100000 - LEAD_TO_OPEN_AREA = 0b01000000 - MASTERIES = 0b10000000 - - -@dataclass(frozen=True) -class RegionData: - name: str - exits: List[str] = field(default_factory=list) - flag: ModificationFlag = ModificationFlag.NOT_MODIFIED - is_ginger_island: bool = False - - def get_merged_with(self, exits: List[str]): - merged_exits = [] - merged_exits.extend(self.exits) - if exits is not None: - merged_exits.extend(exits) - merged_exits = sorted(set(merged_exits)) - return RegionData(self.name, merged_exits, is_ginger_island=self.is_ginger_island) - - def get_without_exits(self, exits_to_remove: Set[str]): - exits = [exit_ for exit_ in self.exits if exit_ not in exits_to_remove] - return RegionData(self.name, exits, is_ginger_island=self.is_ginger_island) - - def get_clone(self): - return deepcopy(self) - - -@dataclass(frozen=True) -class ConnectionData: - name: str - destination: str - origin: Optional[str] = None - reverse: Optional[str] = None - flag: RandomizationFlag = RandomizationFlag.NOT_RANDOMIZED - - def __post_init__(self): - if connector_keyword in self.name: - origin, destination = self.name.split(connector_keyword) - if self.reverse is None: - super().__setattr__("reverse", f"{destination}{connector_keyword}{origin}") - - -@dataclass(frozen=True) -class ModRegionData: - mod_name: str - regions: List[RegionData] - connections: List[ConnectionData] diff --git a/worlds/stardew_valley/regions.py b/worlds/stardew_valley/regions.py deleted file mode 100644 index 4d06d598d32d..000000000000 --- a/worlds/stardew_valley/regions.py +++ /dev/null @@ -1,775 +0,0 @@ -from random import Random -from typing import Iterable, Dict, Protocol, List, Tuple, Set - -from BaseClasses import Region, Entrance -from .content import content_packs, StardewContent -from .mods.mod_regions import ModDataList, vanilla_connections_to_remove_by_mod -from .options import EntranceRandomization, ExcludeGingerIsland, StardewValleyOptions -from .region_classes import RegionData, ConnectionData, RandomizationFlag, ModificationFlag -from .strings.entrance_names import Entrance, LogicEntrance -from .strings.region_names import Region as RegionName, LogicRegion - - -class RegionFactory(Protocol): - def __call__(self, name: str, regions: Iterable[str]) -> Region: - raise NotImplementedError - - -vanilla_regions = [ - RegionData(RegionName.menu, [Entrance.to_stardew_valley]), - RegionData(RegionName.stardew_valley, [Entrance.to_farmhouse]), - RegionData(RegionName.farm_house, - [Entrance.farmhouse_to_farm, Entrance.downstairs_to_cellar, LogicEntrance.farmhouse_cooking, LogicEntrance.watch_queen_of_sauce]), - RegionData(RegionName.cellar), - RegionData(RegionName.farm, - [Entrance.farm_to_backwoods, Entrance.farm_to_bus_stop, Entrance.farm_to_forest, Entrance.farm_to_farmcave, Entrance.enter_greenhouse, - Entrance.enter_coop, Entrance.enter_barn, Entrance.enter_shed, Entrance.enter_slime_hutch, LogicEntrance.grow_spring_crops, - LogicEntrance.grow_summer_crops, LogicEntrance.grow_fall_crops, LogicEntrance.grow_winter_crops, LogicEntrance.shipping, - LogicEntrance.fishing, ]), - RegionData(RegionName.backwoods, [Entrance.backwoods_to_mountain]), - RegionData(RegionName.bus_stop, - [Entrance.bus_stop_to_town, Entrance.take_bus_to_desert, Entrance.bus_stop_to_tunnel_entrance]), - RegionData(RegionName.forest, - [Entrance.forest_to_town, Entrance.enter_secret_woods, Entrance.forest_to_wizard_tower, Entrance.forest_to_marnie_ranch, - Entrance.forest_to_leah_cottage, Entrance.forest_to_sewer, Entrance.forest_to_mastery_cave, LogicEntrance.buy_from_traveling_merchant, - LogicEntrance.complete_raccoon_requests, LogicEntrance.fish_in_waterfall, LogicEntrance.attend_flower_dance, LogicEntrance.attend_trout_derby, - LogicEntrance.attend_festival_of_ice]), - RegionData(LogicRegion.forest_waterfall), - RegionData(RegionName.farm_cave), - RegionData(RegionName.greenhouse, - [LogicEntrance.grow_spring_crops_in_greenhouse, LogicEntrance.grow_summer_crops_in_greenhouse, LogicEntrance.grow_fall_crops_in_greenhouse, - LogicEntrance.grow_winter_crops_in_greenhouse, LogicEntrance.grow_indoor_crops_in_greenhouse]), - RegionData(RegionName.mountain, - [Entrance.mountain_to_railroad, Entrance.mountain_to_tent, Entrance.mountain_to_carpenter_shop, - Entrance.mountain_to_the_mines, Entrance.enter_quarry, Entrance.mountain_to_adventurer_guild, - Entrance.mountain_to_town, Entrance.mountain_to_maru_room, - Entrance.mountain_to_leo_treehouse]), - RegionData(RegionName.leo_treehouse, is_ginger_island=True), - RegionData(RegionName.maru_room), - RegionData(RegionName.tunnel_entrance, [Entrance.tunnel_entrance_to_bus_tunnel]), - RegionData(RegionName.bus_tunnel), - RegionData(RegionName.town, - [Entrance.town_to_community_center, Entrance.town_to_beach, Entrance.town_to_hospital, Entrance.town_to_pierre_general_store, - Entrance.town_to_saloon, Entrance.town_to_alex_house, Entrance.town_to_trailer, Entrance.town_to_mayor_manor, Entrance.town_to_sam_house, - Entrance.town_to_haley_house, Entrance.town_to_sewer, Entrance.town_to_clint_blacksmith, Entrance.town_to_museum, Entrance.town_to_jojamart, - Entrance.purchase_movie_ticket, LogicEntrance.buy_experience_books, LogicEntrance.attend_egg_festival, LogicEntrance.attend_fair, - LogicEntrance.attend_spirit_eve, LogicEntrance.attend_winter_star]), - RegionData(RegionName.beach, - [Entrance.beach_to_willy_fish_shop, Entrance.enter_elliott_house, Entrance.enter_tide_pools, LogicEntrance.attend_luau, - LogicEntrance.attend_moonlight_jellies, LogicEntrance.attend_night_market, LogicEntrance.attend_squidfest]), - RegionData(RegionName.railroad, [Entrance.enter_bathhouse_entrance, Entrance.enter_witch_warp_cave]), - RegionData(RegionName.ranch), - RegionData(RegionName.leah_house), - RegionData(RegionName.mastery_cave), - RegionData(RegionName.sewer, [Entrance.enter_mutant_bug_lair]), - RegionData(RegionName.mutant_bug_lair), - RegionData(RegionName.wizard_tower, [Entrance.enter_wizard_basement, Entrance.use_desert_obelisk, Entrance.use_island_obelisk]), - RegionData(RegionName.wizard_basement), - RegionData(RegionName.tent), - RegionData(RegionName.carpenter, [Entrance.enter_sebastian_room]), - RegionData(RegionName.sebastian_room), - RegionData(RegionName.adventurer_guild, [Entrance.adventurer_guild_to_bedroom]), - RegionData(RegionName.adventurer_guild_bedroom), - RegionData(RegionName.community_center, - [Entrance.access_crafts_room, Entrance.access_pantry, Entrance.access_fish_tank, - Entrance.access_boiler_room, Entrance.access_bulletin_board, Entrance.access_vault]), - RegionData(RegionName.crafts_room), - RegionData(RegionName.pantry), - RegionData(RegionName.fish_tank), - RegionData(RegionName.boiler_room), - RegionData(RegionName.bulletin_board), - RegionData(RegionName.vault), - RegionData(RegionName.hospital, [Entrance.enter_harvey_room]), - RegionData(RegionName.harvey_room), - RegionData(RegionName.pierre_store, [Entrance.enter_sunroom]), - RegionData(RegionName.sunroom), - RegionData(RegionName.saloon, [Entrance.play_journey_of_the_prairie_king, Entrance.play_junimo_kart]), - RegionData(RegionName.jotpk_world_1, [Entrance.reach_jotpk_world_2]), - RegionData(RegionName.jotpk_world_2, [Entrance.reach_jotpk_world_3]), - RegionData(RegionName.jotpk_world_3), - RegionData(RegionName.junimo_kart_1, [Entrance.reach_junimo_kart_2]), - RegionData(RegionName.junimo_kart_2, [Entrance.reach_junimo_kart_3]), - RegionData(RegionName.junimo_kart_3, [Entrance.reach_junimo_kart_4]), - RegionData(RegionName.junimo_kart_4), - RegionData(RegionName.alex_house), - RegionData(RegionName.trailer), - RegionData(RegionName.mayor_house), - RegionData(RegionName.sam_house), - RegionData(RegionName.haley_house), - RegionData(RegionName.blacksmith, [LogicEntrance.blacksmith_copper]), - RegionData(RegionName.museum), - RegionData(RegionName.jojamart, [Entrance.enter_abandoned_jojamart]), - RegionData(RegionName.abandoned_jojamart, [Entrance.enter_movie_theater]), - RegionData(RegionName.movie_ticket_stand), - RegionData(RegionName.movie_theater), - RegionData(RegionName.fish_shop, [Entrance.fish_shop_to_boat_tunnel]), - RegionData(RegionName.boat_tunnel, [Entrance.boat_to_ginger_island], is_ginger_island=True), - RegionData(RegionName.elliott_house), - RegionData(RegionName.tide_pools), - RegionData(RegionName.bathhouse_entrance, [Entrance.enter_locker_room]), - RegionData(RegionName.locker_room, [Entrance.enter_public_bath]), - RegionData(RegionName.public_bath), - RegionData(RegionName.witch_warp_cave, [Entrance.enter_witch_swamp]), - RegionData(RegionName.witch_swamp, [Entrance.enter_witch_hut]), - RegionData(RegionName.witch_hut, [Entrance.witch_warp_to_wizard_basement]), - RegionData(RegionName.quarry, [Entrance.enter_quarry_mine_entrance]), - RegionData(RegionName.quarry_mine_entrance, [Entrance.enter_quarry_mine]), - RegionData(RegionName.quarry_mine), - RegionData(RegionName.secret_woods), - RegionData(RegionName.desert, [Entrance.enter_skull_cavern_entrance, Entrance.enter_oasis, LogicEntrance.attend_desert_festival]), - RegionData(RegionName.oasis, [Entrance.enter_casino]), - RegionData(RegionName.casino), - RegionData(RegionName.skull_cavern_entrance, [Entrance.enter_skull_cavern]), - RegionData(RegionName.skull_cavern, [Entrance.mine_to_skull_cavern_floor_25]), - RegionData(RegionName.skull_cavern_25, [Entrance.mine_to_skull_cavern_floor_50]), - RegionData(RegionName.skull_cavern_50, [Entrance.mine_to_skull_cavern_floor_75]), - RegionData(RegionName.skull_cavern_75, [Entrance.mine_to_skull_cavern_floor_100]), - RegionData(RegionName.skull_cavern_100, [Entrance.mine_to_skull_cavern_floor_125]), - RegionData(RegionName.skull_cavern_125, [Entrance.mine_to_skull_cavern_floor_150]), - RegionData(RegionName.skull_cavern_150, [Entrance.mine_to_skull_cavern_floor_175]), - RegionData(RegionName.skull_cavern_175, [Entrance.mine_to_skull_cavern_floor_200]), - RegionData(RegionName.skull_cavern_200, [Entrance.enter_dangerous_skull_cavern]), - RegionData(RegionName.dangerous_skull_cavern, is_ginger_island=True), - RegionData(RegionName.island_south, - [Entrance.island_south_to_west, Entrance.island_south_to_north, Entrance.island_south_to_east, Entrance.island_south_to_southeast, - Entrance.use_island_resort, Entrance.parrot_express_docks_to_volcano, Entrance.parrot_express_docks_to_dig_site, - Entrance.parrot_express_docks_to_jungle], - is_ginger_island=True), - RegionData(RegionName.island_resort, is_ginger_island=True), - RegionData(RegionName.island_west, - [Entrance.island_west_to_islandfarmhouse, Entrance.island_west_to_gourmand_cave, Entrance.island_west_to_crystals_cave, - Entrance.island_west_to_shipwreck, Entrance.island_west_to_qi_walnut_room, Entrance.use_farm_obelisk, Entrance.parrot_express_jungle_to_docks, - Entrance.parrot_express_jungle_to_dig_site, Entrance.parrot_express_jungle_to_volcano, LogicEntrance.grow_spring_crops_on_island, - LogicEntrance.grow_summer_crops_on_island, LogicEntrance.grow_fall_crops_on_island, LogicEntrance.grow_winter_crops_on_island, - LogicEntrance.grow_indoor_crops_on_island], - is_ginger_island=True), - RegionData(RegionName.island_east, [Entrance.island_east_to_leo_hut, Entrance.island_east_to_island_shrine], is_ginger_island=True), - RegionData(RegionName.island_shrine, is_ginger_island=True), - RegionData(RegionName.island_south_east, [Entrance.island_southeast_to_pirate_cove], is_ginger_island=True), - RegionData(RegionName.island_north, - [Entrance.talk_to_island_trader, Entrance.island_north_to_field_office, Entrance.island_north_to_dig_site, Entrance.island_north_to_volcano, - Entrance.parrot_express_volcano_to_dig_site, Entrance.parrot_express_volcano_to_jungle, Entrance.parrot_express_volcano_to_docks], - is_ginger_island=True), - RegionData(RegionName.volcano, [Entrance.climb_to_volcano_5, Entrance.volcano_to_secret_beach], is_ginger_island=True), - RegionData(RegionName.volcano_secret_beach, is_ginger_island=True), - RegionData(RegionName.volcano_floor_5, [Entrance.talk_to_volcano_dwarf, Entrance.climb_to_volcano_10], is_ginger_island=True), - RegionData(RegionName.volcano_dwarf_shop, is_ginger_island=True), - RegionData(RegionName.volcano_floor_10, is_ginger_island=True), - RegionData(RegionName.island_trader, is_ginger_island=True), - RegionData(RegionName.island_farmhouse, [LogicEntrance.island_cooking], is_ginger_island=True), - RegionData(RegionName.gourmand_frog_cave, is_ginger_island=True), - RegionData(RegionName.colored_crystals_cave, is_ginger_island=True), - RegionData(RegionName.shipwreck, is_ginger_island=True), - RegionData(RegionName.qi_walnut_room, is_ginger_island=True), - RegionData(RegionName.leo_hut, is_ginger_island=True), - RegionData(RegionName.pirate_cove, is_ginger_island=True), - RegionData(RegionName.field_office, is_ginger_island=True), - RegionData(RegionName.dig_site, - [Entrance.dig_site_to_professor_snail_cave, Entrance.parrot_express_dig_site_to_volcano, - Entrance.parrot_express_dig_site_to_docks, Entrance.parrot_express_dig_site_to_jungle], - is_ginger_island=True), - RegionData(RegionName.professor_snail_cave, is_ginger_island=True), - RegionData(RegionName.coop), - RegionData(RegionName.barn), - RegionData(RegionName.shed), - RegionData(RegionName.slime_hutch), - - RegionData(RegionName.mines, [LogicEntrance.talk_to_mines_dwarf, - Entrance.dig_to_mines_floor_5]), - RegionData(RegionName.mines_floor_5, [Entrance.dig_to_mines_floor_10]), - RegionData(RegionName.mines_floor_10, [Entrance.dig_to_mines_floor_15]), - RegionData(RegionName.mines_floor_15, [Entrance.dig_to_mines_floor_20]), - RegionData(RegionName.mines_floor_20, [Entrance.dig_to_mines_floor_25]), - RegionData(RegionName.mines_floor_25, [Entrance.dig_to_mines_floor_30]), - RegionData(RegionName.mines_floor_30, [Entrance.dig_to_mines_floor_35]), - RegionData(RegionName.mines_floor_35, [Entrance.dig_to_mines_floor_40]), - RegionData(RegionName.mines_floor_40, [Entrance.dig_to_mines_floor_45]), - RegionData(RegionName.mines_floor_45, [Entrance.dig_to_mines_floor_50]), - RegionData(RegionName.mines_floor_50, [Entrance.dig_to_mines_floor_55]), - RegionData(RegionName.mines_floor_55, [Entrance.dig_to_mines_floor_60]), - RegionData(RegionName.mines_floor_60, [Entrance.dig_to_mines_floor_65]), - RegionData(RegionName.mines_floor_65, [Entrance.dig_to_mines_floor_70]), - RegionData(RegionName.mines_floor_70, [Entrance.dig_to_mines_floor_75]), - RegionData(RegionName.mines_floor_75, [Entrance.dig_to_mines_floor_80]), - RegionData(RegionName.mines_floor_80, [Entrance.dig_to_mines_floor_85]), - RegionData(RegionName.mines_floor_85, [Entrance.dig_to_mines_floor_90]), - RegionData(RegionName.mines_floor_90, [Entrance.dig_to_mines_floor_95]), - RegionData(RegionName.mines_floor_95, [Entrance.dig_to_mines_floor_100]), - RegionData(RegionName.mines_floor_100, [Entrance.dig_to_mines_floor_105]), - RegionData(RegionName.mines_floor_105, [Entrance.dig_to_mines_floor_110]), - RegionData(RegionName.mines_floor_110, [Entrance.dig_to_mines_floor_115]), - RegionData(RegionName.mines_floor_115, [Entrance.dig_to_mines_floor_120]), - RegionData(RegionName.mines_floor_120, [Entrance.dig_to_dangerous_mines_20, Entrance.dig_to_dangerous_mines_60, Entrance.dig_to_dangerous_mines_100]), - RegionData(RegionName.dangerous_mines_20, is_ginger_island=True), - RegionData(RegionName.dangerous_mines_60, is_ginger_island=True), - RegionData(RegionName.dangerous_mines_100, is_ginger_island=True), - - RegionData(LogicRegion.mines_dwarf_shop), - RegionData(LogicRegion.blacksmith_copper, [LogicEntrance.blacksmith_iron]), - RegionData(LogicRegion.blacksmith_iron, [LogicEntrance.blacksmith_gold]), - RegionData(LogicRegion.blacksmith_gold, [LogicEntrance.blacksmith_iridium]), - RegionData(LogicRegion.blacksmith_iridium), - RegionData(LogicRegion.kitchen), - RegionData(LogicRegion.queen_of_sauce), - RegionData(LogicRegion.fishing), - - RegionData(LogicRegion.spring_farming), - RegionData(LogicRegion.summer_farming, [LogicEntrance.grow_summer_fall_crops_in_summer]), - RegionData(LogicRegion.fall_farming, [LogicEntrance.grow_summer_fall_crops_in_fall]), - RegionData(LogicRegion.winter_farming), - RegionData(LogicRegion.summer_or_fall_farming), - RegionData(LogicRegion.indoor_farming), - - RegionData(LogicRegion.shipping), - RegionData(LogicRegion.traveling_cart, [LogicEntrance.buy_from_traveling_merchant_sunday, - LogicEntrance.buy_from_traveling_merchant_monday, - LogicEntrance.buy_from_traveling_merchant_tuesday, - LogicEntrance.buy_from_traveling_merchant_wednesday, - LogicEntrance.buy_from_traveling_merchant_thursday, - LogicEntrance.buy_from_traveling_merchant_friday, - LogicEntrance.buy_from_traveling_merchant_saturday]), - RegionData(LogicRegion.traveling_cart_sunday), - RegionData(LogicRegion.traveling_cart_monday), - RegionData(LogicRegion.traveling_cart_tuesday), - RegionData(LogicRegion.traveling_cart_wednesday), - RegionData(LogicRegion.traveling_cart_thursday), - RegionData(LogicRegion.traveling_cart_friday), - RegionData(LogicRegion.traveling_cart_saturday), - RegionData(LogicRegion.raccoon_daddy, [LogicEntrance.buy_from_raccoon]), - RegionData(LogicRegion.raccoon_shop), - - RegionData(LogicRegion.egg_festival), - RegionData(LogicRegion.desert_festival), - RegionData(LogicRegion.flower_dance), - RegionData(LogicRegion.luau), - RegionData(LogicRegion.trout_derby), - RegionData(LogicRegion.moonlight_jellies), - RegionData(LogicRegion.fair), - RegionData(LogicRegion.spirit_eve), - RegionData(LogicRegion.festival_of_ice), - RegionData(LogicRegion.night_market), - RegionData(LogicRegion.winter_star), - RegionData(LogicRegion.squidfest), - RegionData(LogicRegion.bookseller_1, [LogicEntrance.buy_year1_books]), - RegionData(LogicRegion.bookseller_2, [LogicEntrance.buy_year3_books]), - RegionData(LogicRegion.bookseller_3), -] - -# Exists and where they lead -vanilla_connections = [ - ConnectionData(Entrance.to_stardew_valley, RegionName.stardew_valley), - ConnectionData(Entrance.to_farmhouse, RegionName.farm_house), - ConnectionData(Entrance.farmhouse_to_farm, RegionName.farm), - ConnectionData(Entrance.downstairs_to_cellar, RegionName.cellar), - ConnectionData(Entrance.farm_to_backwoods, RegionName.backwoods), - ConnectionData(Entrance.farm_to_bus_stop, RegionName.bus_stop), - ConnectionData(Entrance.farm_to_forest, RegionName.forest), - ConnectionData(Entrance.farm_to_farmcave, RegionName.farm_cave, flag=RandomizationFlag.NON_PROGRESSION), - ConnectionData(Entrance.enter_greenhouse, RegionName.greenhouse), - ConnectionData(Entrance.enter_coop, RegionName.coop), - ConnectionData(Entrance.enter_barn, RegionName.barn), - ConnectionData(Entrance.enter_shed, RegionName.shed), - ConnectionData(Entrance.enter_slime_hutch, RegionName.slime_hutch), - ConnectionData(Entrance.use_desert_obelisk, RegionName.desert), - ConnectionData(Entrance.use_island_obelisk, RegionName.island_south, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.use_farm_obelisk, RegionName.farm), - ConnectionData(Entrance.backwoods_to_mountain, RegionName.mountain), - ConnectionData(Entrance.bus_stop_to_town, RegionName.town), - ConnectionData(Entrance.bus_stop_to_tunnel_entrance, RegionName.tunnel_entrance), - ConnectionData(Entrance.tunnel_entrance_to_bus_tunnel, RegionName.bus_tunnel, flag=RandomizationFlag.NON_PROGRESSION), - ConnectionData(Entrance.take_bus_to_desert, RegionName.desert), - ConnectionData(Entrance.forest_to_town, RegionName.town), - ConnectionData(Entrance.forest_to_wizard_tower, RegionName.wizard_tower, - flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_wizard_basement, RegionName.wizard_basement, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.forest_to_marnie_ranch, RegionName.ranch, - flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.forest_to_leah_cottage, RegionName.leah_house, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_secret_woods, RegionName.secret_woods), - ConnectionData(Entrance.forest_to_sewer, RegionName.sewer, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.forest_to_mastery_cave, RegionName.mastery_cave, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.MASTERIES), - ConnectionData(Entrance.town_to_sewer, RegionName.sewer, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_mutant_bug_lair, RegionName.mutant_bug_lair, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.mountain_to_railroad, RegionName.railroad), - ConnectionData(Entrance.mountain_to_tent, RegionName.tent, - flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.mountain_to_leo_treehouse, RegionName.leo_treehouse, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.mountain_to_carpenter_shop, RegionName.carpenter, - flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.mountain_to_maru_room, RegionName.maru_room, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_sebastian_room, RegionName.sebastian_room, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.mountain_to_adventurer_guild, RegionName.adventurer_guild, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.adventurer_guild_to_bedroom, RegionName.adventurer_guild_bedroom), - ConnectionData(Entrance.enter_quarry, RegionName.quarry), - ConnectionData(Entrance.enter_quarry_mine_entrance, RegionName.quarry_mine_entrance, - flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_quarry_mine, RegionName.quarry_mine), - ConnectionData(Entrance.mountain_to_town, RegionName.town), - ConnectionData(Entrance.town_to_community_center, RegionName.community_center, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.access_crafts_room, RegionName.crafts_room), - ConnectionData(Entrance.access_pantry, RegionName.pantry), - ConnectionData(Entrance.access_fish_tank, RegionName.fish_tank), - ConnectionData(Entrance.access_boiler_room, RegionName.boiler_room), - ConnectionData(Entrance.access_bulletin_board, RegionName.bulletin_board), - ConnectionData(Entrance.access_vault, RegionName.vault), - ConnectionData(Entrance.town_to_hospital, RegionName.hospital, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_harvey_room, RegionName.harvey_room, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.town_to_pierre_general_store, RegionName.pierre_store, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_sunroom, RegionName.sunroom, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.town_to_clint_blacksmith, RegionName.blacksmith, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_saloon, RegionName.saloon, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.play_journey_of_the_prairie_king, RegionName.jotpk_world_1), - ConnectionData(Entrance.reach_jotpk_world_2, RegionName.jotpk_world_2), - ConnectionData(Entrance.reach_jotpk_world_3, RegionName.jotpk_world_3), - ConnectionData(Entrance.play_junimo_kart, RegionName.junimo_kart_1), - ConnectionData(Entrance.reach_junimo_kart_2, RegionName.junimo_kart_2), - ConnectionData(Entrance.reach_junimo_kart_3, RegionName.junimo_kart_3), - ConnectionData(Entrance.reach_junimo_kart_4, RegionName.junimo_kart_4), - ConnectionData(Entrance.town_to_sam_house, RegionName.sam_house, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_haley_house, RegionName.haley_house, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_mayor_manor, RegionName.mayor_house, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_alex_house, RegionName.alex_house, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_trailer, RegionName.trailer, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_museum, RegionName.museum, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.town_to_jojamart, RegionName.jojamart, - flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.purchase_movie_ticket, RegionName.movie_ticket_stand), - ConnectionData(Entrance.enter_abandoned_jojamart, RegionName.abandoned_jojamart), - ConnectionData(Entrance.enter_movie_theater, RegionName.movie_theater), - ConnectionData(Entrance.town_to_beach, RegionName.beach), - ConnectionData(Entrance.enter_elliott_house, RegionName.elliott_house, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.beach_to_willy_fish_shop, RegionName.fish_shop, - flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.fish_shop_to_boat_tunnel, RegionName.boat_tunnel, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.boat_to_ginger_island, RegionName.island_south, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.enter_tide_pools, RegionName.tide_pools), - ConnectionData(Entrance.mountain_to_the_mines, RegionName.mines, - flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.dig_to_mines_floor_5, RegionName.mines_floor_5), - ConnectionData(Entrance.dig_to_mines_floor_10, RegionName.mines_floor_10), - ConnectionData(Entrance.dig_to_mines_floor_15, RegionName.mines_floor_15), - ConnectionData(Entrance.dig_to_mines_floor_20, RegionName.mines_floor_20), - ConnectionData(Entrance.dig_to_mines_floor_25, RegionName.mines_floor_25), - ConnectionData(Entrance.dig_to_mines_floor_30, RegionName.mines_floor_30), - ConnectionData(Entrance.dig_to_mines_floor_35, RegionName.mines_floor_35), - ConnectionData(Entrance.dig_to_mines_floor_40, RegionName.mines_floor_40), - ConnectionData(Entrance.dig_to_mines_floor_45, RegionName.mines_floor_45), - ConnectionData(Entrance.dig_to_mines_floor_50, RegionName.mines_floor_50), - ConnectionData(Entrance.dig_to_mines_floor_55, RegionName.mines_floor_55), - ConnectionData(Entrance.dig_to_mines_floor_60, RegionName.mines_floor_60), - ConnectionData(Entrance.dig_to_mines_floor_65, RegionName.mines_floor_65), - ConnectionData(Entrance.dig_to_mines_floor_70, RegionName.mines_floor_70), - ConnectionData(Entrance.dig_to_mines_floor_75, RegionName.mines_floor_75), - ConnectionData(Entrance.dig_to_mines_floor_80, RegionName.mines_floor_80), - ConnectionData(Entrance.dig_to_mines_floor_85, RegionName.mines_floor_85), - ConnectionData(Entrance.dig_to_mines_floor_90, RegionName.mines_floor_90), - ConnectionData(Entrance.dig_to_mines_floor_95, RegionName.mines_floor_95), - ConnectionData(Entrance.dig_to_mines_floor_100, RegionName.mines_floor_100), - ConnectionData(Entrance.dig_to_mines_floor_105, RegionName.mines_floor_105), - ConnectionData(Entrance.dig_to_mines_floor_110, RegionName.mines_floor_110), - ConnectionData(Entrance.dig_to_mines_floor_115, RegionName.mines_floor_115), - ConnectionData(Entrance.dig_to_mines_floor_120, RegionName.mines_floor_120), - ConnectionData(Entrance.dig_to_dangerous_mines_20, RegionName.dangerous_mines_20, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.dig_to_dangerous_mines_60, RegionName.dangerous_mines_60, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.dig_to_dangerous_mines_100, RegionName.dangerous_mines_100, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.enter_skull_cavern_entrance, RegionName.skull_cavern_entrance, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_oasis, RegionName.oasis, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_casino, RegionName.casino, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_skull_cavern, RegionName.skull_cavern), - ConnectionData(Entrance.mine_to_skull_cavern_floor_25, RegionName.skull_cavern_25), - ConnectionData(Entrance.mine_to_skull_cavern_floor_50, RegionName.skull_cavern_50), - ConnectionData(Entrance.mine_to_skull_cavern_floor_75, RegionName.skull_cavern_75), - ConnectionData(Entrance.mine_to_skull_cavern_floor_100, RegionName.skull_cavern_100), - ConnectionData(Entrance.mine_to_skull_cavern_floor_125, RegionName.skull_cavern_125), - ConnectionData(Entrance.mine_to_skull_cavern_floor_150, RegionName.skull_cavern_150), - ConnectionData(Entrance.mine_to_skull_cavern_floor_175, RegionName.skull_cavern_175), - ConnectionData(Entrance.mine_to_skull_cavern_floor_200, RegionName.skull_cavern_200), - ConnectionData(Entrance.enter_dangerous_skull_cavern, RegionName.dangerous_skull_cavern, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.enter_witch_warp_cave, RegionName.witch_warp_cave, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_witch_swamp, RegionName.witch_swamp, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_witch_hut, RegionName.witch_hut, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.witch_warp_to_wizard_basement, RegionName.wizard_basement, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_bathhouse_entrance, RegionName.bathhouse_entrance, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), - ConnectionData(Entrance.enter_locker_room, RegionName.locker_room, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.enter_public_bath, RegionName.public_bath, flag=RandomizationFlag.BUILDINGS), - ConnectionData(Entrance.island_south_to_west, RegionName.island_west, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_south_to_north, RegionName.island_north, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_south_to_east, RegionName.island_east, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_south_to_southeast, RegionName.island_south_east, - flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.use_island_resort, RegionName.island_resort, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_west_to_islandfarmhouse, RegionName.island_farmhouse, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_west_to_gourmand_cave, RegionName.gourmand_frog_cave, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_west_to_crystals_cave, RegionName.colored_crystals_cave, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_west_to_shipwreck, RegionName.shipwreck, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_west_to_qi_walnut_room, RegionName.qi_walnut_room, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_east_to_leo_hut, RegionName.leo_hut, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_east_to_island_shrine, RegionName.island_shrine, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_southeast_to_pirate_cove, RegionName.pirate_cove, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_north_to_field_office, RegionName.field_office, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_north_to_dig_site, RegionName.dig_site, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.dig_site_to_professor_snail_cave, RegionName.professor_snail_cave, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.island_north_to_volcano, RegionName.volcano, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.volcano_to_secret_beach, RegionName.volcano_secret_beach, - flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.talk_to_island_trader, RegionName.island_trader, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.climb_to_volcano_5, RegionName.volcano_floor_5, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.talk_to_volcano_dwarf, RegionName.volcano_dwarf_shop, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.climb_to_volcano_10, RegionName.volcano_floor_10, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_jungle_to_docks, RegionName.island_south, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_dig_site_to_docks, RegionName.island_south, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_volcano_to_docks, RegionName.island_south, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_volcano_to_jungle, RegionName.island_west, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_docks_to_jungle, RegionName.island_west, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_dig_site_to_jungle, RegionName.island_west, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_docks_to_dig_site, RegionName.dig_site, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_volcano_to_dig_site, RegionName.dig_site, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_jungle_to_dig_site, RegionName.dig_site, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_dig_site_to_volcano, RegionName.island_north, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_docks_to_volcano, RegionName.island_north, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(Entrance.parrot_express_jungle_to_volcano, RegionName.island_north, flag=RandomizationFlag.GINGER_ISLAND), - - ConnectionData(LogicEntrance.talk_to_mines_dwarf, LogicRegion.mines_dwarf_shop), - - ConnectionData(LogicEntrance.buy_from_traveling_merchant, LogicRegion.traveling_cart), - ConnectionData(LogicEntrance.buy_from_traveling_merchant_sunday, LogicRegion.traveling_cart_sunday), - ConnectionData(LogicEntrance.buy_from_traveling_merchant_monday, LogicRegion.traveling_cart_monday), - ConnectionData(LogicEntrance.buy_from_traveling_merchant_tuesday, LogicRegion.traveling_cart_tuesday), - ConnectionData(LogicEntrance.buy_from_traveling_merchant_wednesday, LogicRegion.traveling_cart_wednesday), - ConnectionData(LogicEntrance.buy_from_traveling_merchant_thursday, LogicRegion.traveling_cart_thursday), - ConnectionData(LogicEntrance.buy_from_traveling_merchant_friday, LogicRegion.traveling_cart_friday), - ConnectionData(LogicEntrance.buy_from_traveling_merchant_saturday, LogicRegion.traveling_cart_saturday), - ConnectionData(LogicEntrance.complete_raccoon_requests, LogicRegion.raccoon_daddy), - ConnectionData(LogicEntrance.fish_in_waterfall, LogicRegion.forest_waterfall), - ConnectionData(LogicEntrance.buy_from_raccoon, LogicRegion.raccoon_shop), - ConnectionData(LogicEntrance.farmhouse_cooking, LogicRegion.kitchen), - ConnectionData(LogicEntrance.watch_queen_of_sauce, LogicRegion.queen_of_sauce), - - ConnectionData(LogicEntrance.grow_spring_crops, LogicRegion.spring_farming), - ConnectionData(LogicEntrance.grow_summer_crops, LogicRegion.summer_farming), - ConnectionData(LogicEntrance.grow_fall_crops, LogicRegion.fall_farming), - ConnectionData(LogicEntrance.grow_winter_crops, LogicRegion.winter_farming), - ConnectionData(LogicEntrance.grow_spring_crops_in_greenhouse, LogicRegion.spring_farming), - ConnectionData(LogicEntrance.grow_summer_crops_in_greenhouse, LogicRegion.summer_farming), - ConnectionData(LogicEntrance.grow_fall_crops_in_greenhouse, LogicRegion.fall_farming), - ConnectionData(LogicEntrance.grow_winter_crops_in_greenhouse, LogicRegion.winter_farming), - ConnectionData(LogicEntrance.grow_indoor_crops_in_greenhouse, LogicRegion.indoor_farming), - ConnectionData(LogicEntrance.grow_spring_crops_on_island, LogicRegion.spring_farming, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(LogicEntrance.grow_summer_crops_on_island, LogicRegion.summer_farming, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(LogicEntrance.grow_fall_crops_on_island, LogicRegion.fall_farming, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(LogicEntrance.grow_winter_crops_on_island, LogicRegion.winter_farming, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(LogicEntrance.grow_indoor_crops_on_island, LogicRegion.indoor_farming, flag=RandomizationFlag.GINGER_ISLAND), - ConnectionData(LogicEntrance.grow_summer_fall_crops_in_summer, LogicRegion.summer_or_fall_farming), - ConnectionData(LogicEntrance.grow_summer_fall_crops_in_fall, LogicRegion.summer_or_fall_farming), - - ConnectionData(LogicEntrance.shipping, LogicRegion.shipping), - ConnectionData(LogicEntrance.blacksmith_copper, LogicRegion.blacksmith_copper), - ConnectionData(LogicEntrance.blacksmith_iron, LogicRegion.blacksmith_iron), - ConnectionData(LogicEntrance.blacksmith_gold, LogicRegion.blacksmith_gold), - ConnectionData(LogicEntrance.blacksmith_iridium, LogicRegion.blacksmith_iridium), - ConnectionData(LogicEntrance.fishing, LogicRegion.fishing), - ConnectionData(LogicEntrance.island_cooking, LogicRegion.kitchen), - ConnectionData(LogicEntrance.attend_egg_festival, LogicRegion.egg_festival), - ConnectionData(LogicEntrance.attend_desert_festival, LogicRegion.desert_festival), - ConnectionData(LogicEntrance.attend_flower_dance, LogicRegion.flower_dance), - ConnectionData(LogicEntrance.attend_luau, LogicRegion.luau), - ConnectionData(LogicEntrance.attend_trout_derby, LogicRegion.trout_derby), - ConnectionData(LogicEntrance.attend_moonlight_jellies, LogicRegion.moonlight_jellies), - ConnectionData(LogicEntrance.attend_fair, LogicRegion.fair), - ConnectionData(LogicEntrance.attend_spirit_eve, LogicRegion.spirit_eve), - ConnectionData(LogicEntrance.attend_festival_of_ice, LogicRegion.festival_of_ice), - ConnectionData(LogicEntrance.attend_night_market, LogicRegion.night_market), - ConnectionData(LogicEntrance.attend_winter_star, LogicRegion.winter_star), - ConnectionData(LogicEntrance.attend_squidfest, LogicRegion.squidfest), - ConnectionData(LogicEntrance.buy_experience_books, LogicRegion.bookseller_1), - ConnectionData(LogicEntrance.buy_year1_books, LogicRegion.bookseller_2), - ConnectionData(LogicEntrance.buy_year3_books, LogicRegion.bookseller_3), -] - - -def create_final_regions(world_options) -> List[RegionData]: - final_regions = [] - final_regions.extend(vanilla_regions) - if world_options.mods is None: - return final_regions - for mod in sorted(world_options.mods.value): - if mod not in ModDataList: - continue - for mod_region in ModDataList[mod].regions: - existing_region = next( - (region for region in final_regions if region.name == mod_region.name), None) - if existing_region: - final_regions.remove(existing_region) - if ModificationFlag.MODIFIED in mod_region.flag: - mod_region = modify_vanilla_regions(existing_region, mod_region) - final_regions.append(existing_region.get_merged_with(mod_region.exits)) - continue - final_regions.append(mod_region.get_clone()) - - return final_regions - - -def create_final_connections_and_regions(world_options) -> Tuple[Dict[str, ConnectionData], Dict[str, RegionData]]: - regions_data: Dict[str, RegionData] = {region.name: region for region in create_final_regions(world_options)} - connections = {connection.name: connection for connection in vanilla_connections} - connections = modify_connections_for_mods(connections, sorted(world_options.mods.value)) - include_island = world_options.exclude_ginger_island == ExcludeGingerIsland.option_false - return remove_ginger_island_regions_and_connections(regions_data, connections, include_island) - - -def remove_ginger_island_regions_and_connections(regions_by_name: Dict[str, RegionData], connections: Dict[str, ConnectionData], include_island: bool): - if include_island: - return connections, regions_by_name - - removed_connections = set() - - for connection_name in tuple(connections): - connection = connections[connection_name] - if connection.flag & RandomizationFlag.GINGER_ISLAND: - connections.pop(connection_name) - removed_connections.add(connection_name) - - for region_name in tuple(regions_by_name): - region = regions_by_name[region_name] - if region.is_ginger_island: - regions_by_name.pop(region_name) - else: - regions_by_name[region_name] = region.get_without_exits(removed_connections) - - return connections, regions_by_name - - -def modify_connections_for_mods(connections: Dict[str, ConnectionData], mods: Iterable) -> Dict[str, ConnectionData]: - for mod in mods: - if mod not in ModDataList: - continue - if mod in vanilla_connections_to_remove_by_mod: - for connection_data in vanilla_connections_to_remove_by_mod[mod]: - connections.pop(connection_data.name) - connections.update({connection.name: connection for connection in ModDataList[mod].connections}) - return connections - - -def modify_vanilla_regions(existing_region: RegionData, modified_region: RegionData) -> RegionData: - updated_region = existing_region - region_exits = updated_region.exits - modified_exits = modified_region.exits - for exits in modified_exits: - region_exits.remove(exits) - - return updated_region - - -def create_regions(region_factory: RegionFactory, random: Random, world_options: StardewValleyOptions, content: StardewContent) \ - -> Tuple[Dict[str, Region], Dict[str, Entrance], Dict[str, str]]: - entrances_data, regions_data = create_final_connections_and_regions(world_options) - regions_by_name: Dict[str: Region] = {region_name: region_factory(region_name, regions_data[region_name].exits) for region_name in regions_data} - entrances_by_name: Dict[str: Entrance] = { - entrance.name: entrance - for region in regions_by_name.values() - for entrance in region.exits - if entrance.name in entrances_data - } - - connections, randomized_data = randomize_connections(random, world_options, content, regions_data, entrances_data) - - for connection in connections: - if connection.name in entrances_by_name: - entrances_by_name[connection.name].connect(regions_by_name[connection.destination]) - return regions_by_name, entrances_by_name, randomized_data - - -def randomize_connections(random: Random, world_options: StardewValleyOptions, content: StardewContent, regions_by_name: Dict[str, RegionData], - connections_by_name: Dict[str, ConnectionData]) -> Tuple[List[ConnectionData], Dict[str, str]]: - connections_to_randomize: List[ConnectionData] = [] - if world_options.entrance_randomization == EntranceRandomization.option_pelican_town: - connections_to_randomize = [connections_by_name[connection] for connection in connections_by_name if - RandomizationFlag.PELICAN_TOWN in connections_by_name[connection].flag] - elif world_options.entrance_randomization == EntranceRandomization.option_non_progression: - connections_to_randomize = [connections_by_name[connection] for connection in connections_by_name if - RandomizationFlag.NON_PROGRESSION in connections_by_name[connection].flag] - elif world_options.entrance_randomization == EntranceRandomization.option_buildings or world_options.entrance_randomization == EntranceRandomization.option_buildings_without_house: - connections_to_randomize = [connections_by_name[connection] for connection in connections_by_name if - RandomizationFlag.BUILDINGS in connections_by_name[connection].flag] - elif world_options.entrance_randomization == EntranceRandomization.option_chaos: - connections_to_randomize = [connections_by_name[connection] for connection in connections_by_name if - RandomizationFlag.BUILDINGS in connections_by_name[connection].flag] - connections_to_randomize = remove_excluded_entrances(connections_to_randomize, content) - - # On Chaos, we just add the connections to randomize, unshuffled, and the client does it every day - randomized_data_for_mod = {} - for connection in connections_to_randomize: - randomized_data_for_mod[connection.name] = connection.name - randomized_data_for_mod[connection.reverse] = connection.reverse - return list(connections_by_name.values()), randomized_data_for_mod - - connections_to_randomize = remove_excluded_entrances(connections_to_randomize, content) - random.shuffle(connections_to_randomize) - destination_pool = list(connections_to_randomize) - random.shuffle(destination_pool) - - randomized_connections = randomize_chosen_connections(connections_to_randomize, destination_pool) - add_non_randomized_connections(list(connections_by_name.values()), connections_to_randomize, randomized_connections) - - swap_connections_until_valid(regions_by_name, connections_by_name, randomized_connections, connections_to_randomize, random) - randomized_connections_for_generation = create_connections_for_generation(randomized_connections) - randomized_data_for_mod = create_data_for_mod(randomized_connections, connections_to_randomize) - - return randomized_connections_for_generation, randomized_data_for_mod - - -def remove_excluded_entrances(connections_to_randomize: List[ConnectionData], content: StardewContent) -> List[ConnectionData]: - # FIXME remove when regions are handled in content packs - if content_packs.ginger_island_content_pack.name not in content.registered_packs: - connections_to_randomize = [connection for connection in connections_to_randomize if RandomizationFlag.GINGER_ISLAND not in connection.flag] - if not content.features.skill_progression.are_masteries_shuffled: - connections_to_randomize = [connection for connection in connections_to_randomize if RandomizationFlag.MASTERIES not in connection.flag] - - return connections_to_randomize - - -def randomize_chosen_connections(connections_to_randomize: List[ConnectionData], - destination_pool: List[ConnectionData]) -> Dict[ConnectionData, ConnectionData]: - randomized_connections = {} - for connection in connections_to_randomize: - destination = destination_pool.pop() - randomized_connections[connection] = destination - return randomized_connections - - -def create_connections_for_generation(randomized_connections: Dict[ConnectionData, ConnectionData]) -> List[ConnectionData]: - connections = [] - for connection in randomized_connections: - destination = randomized_connections[connection] - connections.append(ConnectionData(connection.name, destination.destination, destination.reverse)) - return connections - - -def create_data_for_mod(randomized_connections: Dict[ConnectionData, ConnectionData], - connections_to_randomize: List[ConnectionData]) -> Dict[str, str]: - randomized_data_for_mod = {} - for connection in randomized_connections: - if connection not in connections_to_randomize: - continue - destination = randomized_connections[connection] - add_to_mod_data(connection, destination, randomized_data_for_mod) - return randomized_data_for_mod - - -def add_to_mod_data(connection: ConnectionData, destination: ConnectionData, randomized_data_for_mod: Dict[str, str]): - randomized_data_for_mod[connection.name] = destination.name - randomized_data_for_mod[destination.reverse] = connection.reverse - - -def add_non_randomized_connections(all_connections: List[ConnectionData], connections_to_randomize: List[ConnectionData], - randomized_connections: Dict[ConnectionData, ConnectionData]): - for connection in all_connections: - if connection in connections_to_randomize: - continue - randomized_connections[connection] = connection - - -def swap_connections_until_valid(regions_by_name, connections_by_name: Dict[str, ConnectionData], randomized_connections: Dict[ConnectionData, ConnectionData], - connections_to_randomize: List[ConnectionData], random: Random): - while True: - reachable_regions, unreachable_regions = find_reachable_regions(regions_by_name, connections_by_name, randomized_connections) - if not unreachable_regions: - return randomized_connections - swap_one_random_connection(regions_by_name, connections_by_name, randomized_connections, reachable_regions, - unreachable_regions, connections_to_randomize, random) - - -def region_should_be_reachable(region_name: str, connections_in_slot: Iterable[ConnectionData]) -> bool: - if region_name == RegionName.menu: - return True - for connection in connections_in_slot: - if region_name == connection.destination: - return True - return False - - -def find_reachable_regions(regions_by_name, connections_by_name, - randomized_connections: Dict[ConnectionData, ConnectionData]): - reachable_regions = {RegionName.menu} - unreachable_regions = {region for region in regions_by_name.keys()} - # unreachable_regions = {region for region in regions_by_name.keys() if region_should_be_reachable(region, connections_by_name.values())} - unreachable_regions.remove(RegionName.menu) - exits_to_explore = list(regions_by_name[RegionName.menu].exits) - while exits_to_explore: - exit_name = exits_to_explore.pop() - # if exit_name not in connections_by_name: - # continue - exit_connection = connections_by_name[exit_name] - replaced_connection = randomized_connections[exit_connection] - target_region_name = replaced_connection.destination - if target_region_name in reachable_regions: - continue - - target_region = regions_by_name[target_region_name] - reachable_regions.add(target_region_name) - unreachable_regions.remove(target_region_name) - exits_to_explore.extend(target_region.exits) - return reachable_regions, unreachable_regions - - -def swap_one_random_connection(regions_by_name, connections_by_name, randomized_connections: Dict[ConnectionData, ConnectionData], - reachable_regions: Set[str], unreachable_regions: Set[str], - connections_to_randomize: List[ConnectionData], random: Random): - randomized_connections_already_shuffled = {connection: randomized_connections[connection] - for connection in randomized_connections - if connection != randomized_connections[connection]} - unreachable_regions_names_leading_somewhere = [region for region in sorted(unreachable_regions) if len(regions_by_name[region].exits) > 0] - unreachable_regions_leading_somewhere = [regions_by_name[region_name] for region_name in unreachable_regions_names_leading_somewhere] - unreachable_regions_exits_names = [exit_name for region in unreachable_regions_leading_somewhere for exit_name in region.exits] - unreachable_connections = [connections_by_name[exit_name] for exit_name in unreachable_regions_exits_names] - unreachable_connections_that_can_be_randomized = [connection for connection in unreachable_connections if connection in connections_to_randomize] - - chosen_unreachable_entrance = random.choice(unreachable_connections_that_can_be_randomized) - - chosen_reachable_entrance = None - while chosen_reachable_entrance is None or chosen_reachable_entrance not in randomized_connections_already_shuffled: - chosen_reachable_region_name = random.choice(sorted(reachable_regions)) - chosen_reachable_region = regions_by_name[chosen_reachable_region_name] - if not any(chosen_reachable_region.exits): - continue - chosen_reachable_entrance_name = random.choice(chosen_reachable_region.exits) - chosen_reachable_entrance = connections_by_name[chosen_reachable_entrance_name] - - swap_two_connections(chosen_reachable_entrance, chosen_unreachable_entrance, randomized_connections) - - -def swap_two_connections(entrance_1, entrance_2, randomized_connections): - reachable_destination = randomized_connections[entrance_1] - unreachable_destination = randomized_connections[entrance_2] - randomized_connections[entrance_1] = unreachable_destination - randomized_connections[entrance_2] = reachable_destination diff --git a/worlds/stardew_valley/regions/__init__.py b/worlds/stardew_valley/regions/__init__.py new file mode 100644 index 000000000000..63e8afc2fba5 --- /dev/null +++ b/worlds/stardew_valley/regions/__init__.py @@ -0,0 +1,2 @@ +from .entrance_rando import prepare_mod_data +from .regions import create_regions, RegionFactory diff --git a/worlds/stardew_valley/regions/entrance_rando.py b/worlds/stardew_valley/regions/entrance_rando.py new file mode 100644 index 000000000000..7aa91685e894 --- /dev/null +++ b/worlds/stardew_valley/regions/entrance_rando.py @@ -0,0 +1,73 @@ +from BaseClasses import Region +from entrance_rando import ERPlacementState +from .model import ConnectionData, RandomizationFlag, reverse_connection_name, RegionData +from ..content import StardewContent +from ..options import EntranceRandomization + + +def create_player_randomization_flag(entrance_randomization_choice: EntranceRandomization, content: StardewContent): + """Return the flag that a connection is expected to have to be randomized. Only the bit corresponding to the player randomization choice will be enabled. + + Other bits for content exclusion might also be enabled, tho the preferred solution to exclude content should be to not create those regions at alls, when possible. + """ + flag = RandomizationFlag.NOT_RANDOMIZED + + if entrance_randomization_choice.value == EntranceRandomization.option_disabled: + return flag + + if entrance_randomization_choice == EntranceRandomization.option_pelican_town: + flag |= RandomizationFlag.BIT_PELICAN_TOWN + elif entrance_randomization_choice == EntranceRandomization.option_non_progression: + flag |= RandomizationFlag.BIT_NON_PROGRESSION + elif entrance_randomization_choice in ( + EntranceRandomization.option_buildings, + EntranceRandomization.option_buildings_without_house, + EntranceRandomization.option_chaos + ): + flag |= RandomizationFlag.BIT_BUILDINGS + + if not content.features.skill_progression.are_masteries_shuffled: + flag |= RandomizationFlag.EXCLUDE_MASTERIES + + return flag + + +def connect_regions(region_data_by_name: dict[str, RegionData], connection_data_by_name: dict[str, ConnectionData], regions_by_name: dict[str, Region], + player_randomization_flag: RandomizationFlag) -> None: + for region_name, region_data in region_data_by_name.items(): + origin_region = regions_by_name[region_name] + + for exit_name in region_data.exits: + connection_data = connection_data_by_name[exit_name] + destination_region = regions_by_name[connection_data.destination] + + if connection_data.is_eligible_for_randomization(player_randomization_flag): + create_entrance_rando_target(origin_region, destination_region, connection_data) + else: + origin_region.connect(destination_region, connection_data.name) + + +def create_entrance_rando_target(origin: Region, destination: Region, connection_data: ConnectionData) -> None: + """We need our own function to create the GER targets, because the Stardew Mod have very specific expectations for the name of the entrances. + We need to know exactly which entrances to swap in both directions.""" + origin.create_exit(connection_data.name) + destination.create_er_target(connection_data.reverse) + + +def prepare_mod_data(placements: ERPlacementState) -> dict[str, str]: + """Take the placements from GER and prepare the data for the mod. + The mod require a dictionary detailing which connections need to be swapped. It acts as if the connections are decoupled, so both directions are required. + + For instance, GER will provide placements like (Town to Community Center, Hospital to Town), meaning that the door of the Community Center will instead lead + to the Hospital, and that the exit of the Hospital will lead to the Town by the Community Center door. The StardewAP mod need to know both swaps, being the + original destination of the "Town to Community Center" connection is to be replaced by the original destination of "Town to Hospital", and the original + destination of "Hospital to Town" is to be replaced by the original destination of "Community Center to Town". + """ + + swapped_connections = {} + + for entrance, exit_ in placements.pairings: + swapped_connections[entrance] = reverse_connection_name(exit_) + swapped_connections[exit_] = reverse_connection_name(entrance) + + return swapped_connections diff --git a/worlds/stardew_valley/regions/model.py b/worlds/stardew_valley/regions/model.py new file mode 100644 index 000000000000..07c390155895 --- /dev/null +++ b/worlds/stardew_valley/regions/model.py @@ -0,0 +1,94 @@ +from __future__ import annotations + +from collections.abc import Container +from dataclasses import dataclass, field +from enum import IntFlag + +connector_keyword = " to " + + +def reverse_connection_name(name: str) -> str | None: + try: + origin, destination = name.split(connector_keyword) + except ValueError: + return None + return f"{destination}{connector_keyword}{origin}" + + +class MergeFlag(IntFlag): + ADD_EXITS = 0 + REMOVE_EXITS = 1 + + +class RandomizationFlag(IntFlag): + NOT_RANDOMIZED = 0 + + # Randomization options + # The first 4 bits are used to mark if an entrance is eligible for randomization according to the entrance randomization options. + BIT_PELICAN_TOWN = 1 # 0b0001 + BIT_NON_PROGRESSION = 1 << 1 # 0b0010 + BIT_BUILDINGS = 1 << 2 # 0b0100 + BIT_EVERYTHING = 1 << 3 # 0b1000 + + # Content flag for entrances exclusions + # The next 2 bits are used to mark if an entrance is to be excluded from randomization according to the content options. + # Those bits must be removed from an entrance flags when then entrance must be excluded. + __UNUSED = 1 << 4 # 0b010000 + EXCLUDE_MASTERIES = 1 << 5 # 0b100000 + + # Entrance groups + # The last bit is used to add additional qualifiers on entrances to group them + # Those bits should be added when an entrance need additional qualifiers. + LEAD_TO_OPEN_AREA = 1 << 6 + + # Tags to apply on connections + EVERYTHING = EXCLUDE_MASTERIES | BIT_EVERYTHING + BUILDINGS = EVERYTHING | BIT_BUILDINGS + NON_PROGRESSION = BUILDINGS | BIT_NON_PROGRESSION + PELICAN_TOWN = NON_PROGRESSION | BIT_PELICAN_TOWN + + +@dataclass(frozen=True) +class RegionData: + name: str + exits: tuple[str, ...] = field(default_factory=tuple) + flag: MergeFlag = MergeFlag.ADD_EXITS + + def __post_init__(self): + assert not isinstance(self.exits, str), "Exits must be a tuple of strings, you probably forgot a trailing comma." + + def merge_with(self, other: RegionData) -> RegionData: + assert self.name == other.name, "Regions must have the same name to be merged" + + if other.flag == MergeFlag.REMOVE_EXITS: + return self.get_without_exits(other.exits) + + merged_exits = self.exits + other.exits + assert len(merged_exits) == len(set(merged_exits)), "Two regions getting merged have duplicated exists..." + + return RegionData(self.name, merged_exits) + + def get_without_exits(self, exits_to_remove: Container[str]) -> RegionData: + exits = tuple(exit_ for exit_ in self.exits if exit_ not in exits_to_remove) + return RegionData(self.name, exits) + + +@dataclass(frozen=True) +class ConnectionData: + name: str + destination: str + flag: RandomizationFlag = RandomizationFlag.NOT_RANDOMIZED + + @property + def reverse(self) -> str | None: + return reverse_connection_name(self.name) + + def is_eligible_for_randomization(self, chosen_randomization_flag: RandomizationFlag) -> bool: + return chosen_randomization_flag and chosen_randomization_flag in self.flag + + +@dataclass(frozen=True) +class ModRegionsData: + mod_name: str + regions: list[RegionData] + connections: list[ConnectionData] diff --git a/worlds/stardew_valley/regions/mods.py b/worlds/stardew_valley/regions/mods.py new file mode 100644 index 000000000000..fca54619f518 --- /dev/null +++ b/worlds/stardew_valley/regions/mods.py @@ -0,0 +1,46 @@ +from collections.abc import Iterable + +from .model import ConnectionData, RegionData, ModRegionsData +from ..mods.region_data import region_data_by_content_pack, vanilla_connections_to_remove_by_content_pack + + +def modify_regions_for_mods(current_regions_by_name: dict[str, RegionData], active_content_packs: Iterable[str]) -> None: + for content_pack in active_content_packs: + try: + region_data = region_data_by_content_pack[content_pack] + except KeyError: + continue + + merge_mod_regions(current_regions_by_name, region_data) + + +def merge_mod_regions(current_regions_by_name: dict[str, RegionData], mod_region_data: ModRegionsData) -> None: + for new_region in mod_region_data.regions: + region_name = new_region.name + try: + current_region = current_regions_by_name[region_name] + except KeyError: + current_regions_by_name[region_name] = new_region + continue + + current_regions_by_name[region_name] = current_region.merge_with(new_region) + + +def modify_connections_for_mods(connections: dict[str, ConnectionData], active_mods: Iterable[str]) -> None: + for active_mod in active_mods: + try: + region_data = region_data_by_content_pack[active_mod] + except KeyError: + continue + + try: + vanilla_connections_to_remove = vanilla_connections_to_remove_by_content_pack[active_mod] + for connection_name in vanilla_connections_to_remove: + connections.pop(connection_name) + except KeyError: + pass + + connections.update({ + connection.name: connection + for connection in region_data.connections + }) diff --git a/worlds/stardew_valley/regions/regions.py b/worlds/stardew_valley/regions/regions.py new file mode 100644 index 000000000000..ceaec5b2ac0d --- /dev/null +++ b/worlds/stardew_valley/regions/regions.py @@ -0,0 +1,61 @@ +from typing import Protocol + +from BaseClasses import Region +from . import vanilla_data, mods +from .entrance_rando import create_player_randomization_flag, connect_regions +from .model import ConnectionData, RegionData +from ..content import StardewContent +from ..content.vanilla.ginger_island import ginger_island_content_pack +from ..options import StardewValleyOptions + + +class RegionFactory(Protocol): + def __call__(self, name: str) -> Region: + raise NotImplementedError + + +def create_regions(region_factory: RegionFactory, world_options: StardewValleyOptions, content: StardewContent) -> dict[str, Region]: + connection_data_by_name, region_data_by_name = create_connections_and_regions(content.registered_packs) + + regions_by_name: dict[str: Region] = { + region_name: region_factory(region_name) + for region_name in region_data_by_name + } + + randomization_flag = create_player_randomization_flag(world_options.entrance_randomization, content) + connect_regions(region_data_by_name, connection_data_by_name, regions_by_name, randomization_flag) + + return regions_by_name + + +def create_connections_and_regions(active_content_packs: set[str]) -> tuple[dict[str, ConnectionData], dict[str, RegionData]]: + regions_by_name = create_all_regions(active_content_packs) + connections_by_name = create_all_connections(active_content_packs) + + return connections_by_name, regions_by_name + + +def create_all_regions(active_content_packs: set[str]) -> dict[str, RegionData]: + current_regions_by_name = create_vanilla_regions(active_content_packs) + mods.modify_regions_for_mods(current_regions_by_name, sorted(active_content_packs)) + return current_regions_by_name + + +def create_vanilla_regions(active_content_packs: set[str]) -> dict[str, RegionData]: + if ginger_island_content_pack.name in active_content_packs: + return {**vanilla_data.regions_with_ginger_island_by_name} + else: + return {**vanilla_data.regions_without_ginger_island_by_name} + + +def create_all_connections(active_content_packs: set[str]) -> dict[str, ConnectionData]: + connections = create_vanilla_connections(active_content_packs) + mods.modify_connections_for_mods(connections, sorted(active_content_packs)) + return connections + + +def create_vanilla_connections(active_content_packs: set[str]) -> dict[str, ConnectionData]: + if ginger_island_content_pack.name in active_content_packs: + return {**vanilla_data.connections_with_ginger_island_by_name} + else: + return {**vanilla_data.connections_without_ginger_island_by_name} diff --git a/worlds/stardew_valley/regions/vanilla_data.py b/worlds/stardew_valley/regions/vanilla_data.py new file mode 100644 index 000000000000..dbb83e1063c3 --- /dev/null +++ b/worlds/stardew_valley/regions/vanilla_data.py @@ -0,0 +1,522 @@ +from collections.abc import Mapping +from types import MappingProxyType + +from .model import ConnectionData, RandomizationFlag, RegionData +from ..strings.entrance_names import LogicEntrance, Entrance +from ..strings.region_names import LogicRegion, Region as RegionName + +vanilla_regions: tuple[RegionData, ...] = ( + RegionData(RegionName.menu, (Entrance.to_stardew_valley,)), + RegionData(RegionName.stardew_valley, (Entrance.to_farmhouse,)), + RegionData(RegionName.farm_house, + (Entrance.farmhouse_to_farm, Entrance.downstairs_to_cellar, LogicEntrance.farmhouse_cooking, LogicEntrance.watch_queen_of_sauce)), + RegionData(RegionName.cellar), + RegionData(RegionName.farm, + (Entrance.farm_to_backwoods, Entrance.farm_to_bus_stop, Entrance.farm_to_forest, Entrance.farm_to_farmcave, Entrance.enter_greenhouse, + Entrance.enter_coop, Entrance.enter_barn, Entrance.enter_shed, Entrance.enter_slime_hutch, LogicEntrance.grow_spring_crops, + LogicEntrance.grow_summer_crops, LogicEntrance.grow_fall_crops, LogicEntrance.grow_winter_crops, LogicEntrance.shipping, + LogicEntrance.fishing,)), + RegionData(RegionName.backwoods, (Entrance.backwoods_to_mountain,)), + RegionData(RegionName.bus_stop, + (Entrance.bus_stop_to_town, Entrance.take_bus_to_desert, Entrance.bus_stop_to_tunnel_entrance)), + RegionData(RegionName.forest, + (Entrance.forest_to_town, Entrance.enter_secret_woods, Entrance.forest_to_wizard_tower, Entrance.forest_to_marnie_ranch, + Entrance.forest_to_leah_cottage, Entrance.forest_to_sewer, Entrance.forest_to_mastery_cave, LogicEntrance.buy_from_traveling_merchant, + LogicEntrance.complete_raccoon_requests, LogicEntrance.fish_in_waterfall, LogicEntrance.attend_flower_dance, LogicEntrance.attend_trout_derby, + LogicEntrance.attend_festival_of_ice)), + RegionData(LogicRegion.forest_waterfall), + RegionData(RegionName.farm_cave), + RegionData(RegionName.greenhouse, + (LogicEntrance.grow_spring_crops_in_greenhouse, LogicEntrance.grow_summer_crops_in_greenhouse, LogicEntrance.grow_fall_crops_in_greenhouse, + LogicEntrance.grow_winter_crops_in_greenhouse, LogicEntrance.grow_indoor_crops_in_greenhouse)), + RegionData(RegionName.mountain, + (Entrance.mountain_to_railroad, Entrance.mountain_to_tent, Entrance.mountain_to_carpenter_shop, + Entrance.mountain_to_the_mines, Entrance.enter_quarry, Entrance.mountain_to_adventurer_guild, + Entrance.mountain_to_town, Entrance.mountain_to_maru_room)), + RegionData(RegionName.maru_room), + RegionData(RegionName.tunnel_entrance, (Entrance.tunnel_entrance_to_bus_tunnel,)), + RegionData(RegionName.bus_tunnel), + RegionData(RegionName.town, + (Entrance.town_to_community_center, Entrance.town_to_beach, Entrance.town_to_hospital, Entrance.town_to_pierre_general_store, + Entrance.town_to_saloon, Entrance.town_to_alex_house, Entrance.town_to_trailer, Entrance.town_to_mayor_manor, Entrance.town_to_sam_house, + Entrance.town_to_haley_house, Entrance.town_to_sewer, Entrance.town_to_clint_blacksmith, Entrance.town_to_museum, Entrance.town_to_jojamart, + Entrance.purchase_movie_ticket, LogicEntrance.buy_experience_books, LogicEntrance.attend_egg_festival, LogicEntrance.attend_fair, + LogicEntrance.attend_spirit_eve, LogicEntrance.attend_winter_star)), + RegionData(RegionName.beach, + (Entrance.beach_to_willy_fish_shop, Entrance.enter_elliott_house, Entrance.enter_tide_pools, LogicEntrance.attend_luau, + LogicEntrance.attend_moonlight_jellies, LogicEntrance.attend_night_market, LogicEntrance.attend_squidfest)), + RegionData(RegionName.railroad, (Entrance.enter_bathhouse_entrance, Entrance.enter_witch_warp_cave)), + RegionData(RegionName.ranch), + RegionData(RegionName.leah_house), + RegionData(RegionName.mastery_cave), + RegionData(RegionName.sewer, (Entrance.enter_mutant_bug_lair,)), + RegionData(RegionName.mutant_bug_lair), + RegionData(RegionName.wizard_tower, (Entrance.enter_wizard_basement, Entrance.use_desert_obelisk)), + RegionData(RegionName.wizard_basement), + RegionData(RegionName.tent), + RegionData(RegionName.carpenter, (Entrance.enter_sebastian_room,)), + RegionData(RegionName.sebastian_room), + RegionData(RegionName.adventurer_guild, (Entrance.adventurer_guild_to_bedroom,)), + RegionData(RegionName.adventurer_guild_bedroom), + RegionData(RegionName.community_center, + (Entrance.access_crafts_room, Entrance.access_pantry, Entrance.access_fish_tank, + Entrance.access_boiler_room, Entrance.access_bulletin_board, Entrance.access_vault)), + RegionData(RegionName.crafts_room), + RegionData(RegionName.pantry), + RegionData(RegionName.fish_tank), + RegionData(RegionName.boiler_room), + RegionData(RegionName.bulletin_board), + RegionData(RegionName.vault), + RegionData(RegionName.hospital, (Entrance.enter_harvey_room,)), + RegionData(RegionName.harvey_room), + RegionData(RegionName.pierre_store, (Entrance.enter_sunroom,)), + RegionData(RegionName.sunroom), + RegionData(RegionName.saloon, (Entrance.play_journey_of_the_prairie_king, Entrance.play_junimo_kart)), + RegionData(RegionName.jotpk_world_1, (Entrance.reach_jotpk_world_2,)), + RegionData(RegionName.jotpk_world_2, (Entrance.reach_jotpk_world_3,)), + RegionData(RegionName.jotpk_world_3), + RegionData(RegionName.junimo_kart_1, (Entrance.reach_junimo_kart_2,)), + RegionData(RegionName.junimo_kart_2, (Entrance.reach_junimo_kart_3,)), + RegionData(RegionName.junimo_kart_3, (Entrance.reach_junimo_kart_4,)), + RegionData(RegionName.junimo_kart_4), + RegionData(RegionName.alex_house), + RegionData(RegionName.trailer), + RegionData(RegionName.mayor_house), + RegionData(RegionName.sam_house), + RegionData(RegionName.haley_house), + RegionData(RegionName.blacksmith, (LogicEntrance.blacksmith_copper,)), + RegionData(RegionName.museum), + RegionData(RegionName.jojamart, (Entrance.enter_abandoned_jojamart,)), + RegionData(RegionName.abandoned_jojamart, (Entrance.enter_movie_theater,)), + RegionData(RegionName.movie_ticket_stand), + RegionData(RegionName.movie_theater), + RegionData(RegionName.fish_shop), + RegionData(RegionName.elliott_house), + RegionData(RegionName.tide_pools), + RegionData(RegionName.bathhouse_entrance, (Entrance.enter_locker_room,)), + RegionData(RegionName.locker_room, (Entrance.enter_public_bath,)), + RegionData(RegionName.public_bath), + RegionData(RegionName.witch_warp_cave, (Entrance.enter_witch_swamp,)), + RegionData(RegionName.witch_swamp, (Entrance.enter_witch_hut,)), + RegionData(RegionName.witch_hut, (Entrance.witch_warp_to_wizard_basement,)), + RegionData(RegionName.quarry, (Entrance.enter_quarry_mine_entrance,)), + RegionData(RegionName.quarry_mine_entrance, (Entrance.enter_quarry_mine,)), + RegionData(RegionName.quarry_mine), + RegionData(RegionName.secret_woods), + RegionData(RegionName.desert, (Entrance.enter_skull_cavern_entrance, Entrance.enter_oasis, LogicEntrance.attend_desert_festival)), + RegionData(RegionName.oasis, (Entrance.enter_casino,)), + RegionData(RegionName.casino), + RegionData(RegionName.skull_cavern_entrance, (Entrance.enter_skull_cavern,)), + RegionData(RegionName.skull_cavern, (Entrance.mine_to_skull_cavern_floor_25,)), + RegionData(RegionName.skull_cavern_25, (Entrance.mine_to_skull_cavern_floor_50,)), + RegionData(RegionName.skull_cavern_50, (Entrance.mine_to_skull_cavern_floor_75,)), + RegionData(RegionName.skull_cavern_75, (Entrance.mine_to_skull_cavern_floor_100,)), + RegionData(RegionName.skull_cavern_100, (Entrance.mine_to_skull_cavern_floor_125,)), + RegionData(RegionName.skull_cavern_125, (Entrance.mine_to_skull_cavern_floor_150,)), + RegionData(RegionName.skull_cavern_150, (Entrance.mine_to_skull_cavern_floor_175,)), + RegionData(RegionName.skull_cavern_175, (Entrance.mine_to_skull_cavern_floor_200,)), + RegionData(RegionName.skull_cavern_200), + + RegionData(RegionName.coop), + RegionData(RegionName.barn), + RegionData(RegionName.shed), + RegionData(RegionName.slime_hutch), + + RegionData(RegionName.mines, (LogicEntrance.talk_to_mines_dwarf, Entrance.dig_to_mines_floor_5)), + RegionData(RegionName.mines_floor_5, (Entrance.dig_to_mines_floor_10,)), + RegionData(RegionName.mines_floor_10, (Entrance.dig_to_mines_floor_15,)), + RegionData(RegionName.mines_floor_15, (Entrance.dig_to_mines_floor_20,)), + RegionData(RegionName.mines_floor_20, (Entrance.dig_to_mines_floor_25,)), + RegionData(RegionName.mines_floor_25, (Entrance.dig_to_mines_floor_30,)), + RegionData(RegionName.mines_floor_30, (Entrance.dig_to_mines_floor_35,)), + RegionData(RegionName.mines_floor_35, (Entrance.dig_to_mines_floor_40,)), + RegionData(RegionName.mines_floor_40, (Entrance.dig_to_mines_floor_45,)), + RegionData(RegionName.mines_floor_45, (Entrance.dig_to_mines_floor_50,)), + RegionData(RegionName.mines_floor_50, (Entrance.dig_to_mines_floor_55,)), + RegionData(RegionName.mines_floor_55, (Entrance.dig_to_mines_floor_60,)), + RegionData(RegionName.mines_floor_60, (Entrance.dig_to_mines_floor_65,)), + RegionData(RegionName.mines_floor_65, (Entrance.dig_to_mines_floor_70,)), + RegionData(RegionName.mines_floor_70, (Entrance.dig_to_mines_floor_75,)), + RegionData(RegionName.mines_floor_75, (Entrance.dig_to_mines_floor_80,)), + RegionData(RegionName.mines_floor_80, (Entrance.dig_to_mines_floor_85,)), + RegionData(RegionName.mines_floor_85, (Entrance.dig_to_mines_floor_90,)), + RegionData(RegionName.mines_floor_90, (Entrance.dig_to_mines_floor_95,)), + RegionData(RegionName.mines_floor_95, (Entrance.dig_to_mines_floor_100,)), + RegionData(RegionName.mines_floor_100, (Entrance.dig_to_mines_floor_105,)), + RegionData(RegionName.mines_floor_105, (Entrance.dig_to_mines_floor_110,)), + RegionData(RegionName.mines_floor_110, (Entrance.dig_to_mines_floor_115,)), + RegionData(RegionName.mines_floor_115, (Entrance.dig_to_mines_floor_120,)), + RegionData(RegionName.mines_floor_120), + + RegionData(LogicRegion.mines_dwarf_shop), + RegionData(LogicRegion.blacksmith_copper, (LogicEntrance.blacksmith_iron,)), + RegionData(LogicRegion.blacksmith_iron, (LogicEntrance.blacksmith_gold,)), + RegionData(LogicRegion.blacksmith_gold, (LogicEntrance.blacksmith_iridium,)), + RegionData(LogicRegion.blacksmith_iridium), + RegionData(LogicRegion.kitchen), + RegionData(LogicRegion.queen_of_sauce), + RegionData(LogicRegion.fishing), + + RegionData(LogicRegion.spring_farming), + RegionData(LogicRegion.summer_farming, (LogicEntrance.grow_summer_fall_crops_in_summer,)), + RegionData(LogicRegion.fall_farming, (LogicEntrance.grow_summer_fall_crops_in_fall,)), + RegionData(LogicRegion.winter_farming), + RegionData(LogicRegion.summer_or_fall_farming), + RegionData(LogicRegion.indoor_farming), + + RegionData(LogicRegion.shipping), + RegionData(LogicRegion.traveling_cart, (LogicEntrance.buy_from_traveling_merchant_sunday, + LogicEntrance.buy_from_traveling_merchant_monday, + LogicEntrance.buy_from_traveling_merchant_tuesday, + LogicEntrance.buy_from_traveling_merchant_wednesday, + LogicEntrance.buy_from_traveling_merchant_thursday, + LogicEntrance.buy_from_traveling_merchant_friday, + LogicEntrance.buy_from_traveling_merchant_saturday)), + RegionData(LogicRegion.traveling_cart_sunday), + RegionData(LogicRegion.traveling_cart_monday), + RegionData(LogicRegion.traveling_cart_tuesday), + RegionData(LogicRegion.traveling_cart_wednesday), + RegionData(LogicRegion.traveling_cart_thursday), + RegionData(LogicRegion.traveling_cart_friday), + RegionData(LogicRegion.traveling_cart_saturday), + RegionData(LogicRegion.raccoon_daddy, (LogicEntrance.buy_from_raccoon,)), + RegionData(LogicRegion.raccoon_shop), + + RegionData(LogicRegion.egg_festival), + RegionData(LogicRegion.desert_festival), + RegionData(LogicRegion.flower_dance), + RegionData(LogicRegion.luau), + RegionData(LogicRegion.trout_derby), + RegionData(LogicRegion.moonlight_jellies), + RegionData(LogicRegion.fair), + RegionData(LogicRegion.spirit_eve), + RegionData(LogicRegion.festival_of_ice), + RegionData(LogicRegion.night_market), + RegionData(LogicRegion.winter_star), + RegionData(LogicRegion.squidfest), + RegionData(LogicRegion.bookseller_1, (LogicEntrance.buy_year1_books,)), + RegionData(LogicRegion.bookseller_2, (LogicEntrance.buy_year3_books,)), + RegionData(LogicRegion.bookseller_3), +) +ginger_island_regions = ( + # This overrides the regions from vanilla... When regions are moved to content packs, overriding existing entrances should no longer be necessary. + RegionData(RegionName.mountain, + (Entrance.mountain_to_railroad, Entrance.mountain_to_tent, Entrance.mountain_to_carpenter_shop, + Entrance.mountain_to_the_mines, Entrance.enter_quarry, Entrance.mountain_to_adventurer_guild, + Entrance.mountain_to_town, Entrance.mountain_to_maru_room, Entrance.mountain_to_leo_treehouse)), + RegionData(RegionName.wizard_tower, (Entrance.enter_wizard_basement, Entrance.use_desert_obelisk, Entrance.use_island_obelisk,)), + RegionData(RegionName.fish_shop, (Entrance.fish_shop_to_boat_tunnel,)), + RegionData(RegionName.mines_floor_120, (Entrance.dig_to_dangerous_mines_20, Entrance.dig_to_dangerous_mines_60, Entrance.dig_to_dangerous_mines_100)), + RegionData(RegionName.skull_cavern_200, (Entrance.enter_dangerous_skull_cavern,)), + + RegionData(RegionName.leo_treehouse), + RegionData(RegionName.boat_tunnel, (Entrance.boat_to_ginger_island,)), + RegionData(RegionName.dangerous_skull_cavern), + RegionData(RegionName.island_south, + (Entrance.island_south_to_west, Entrance.island_south_to_north, Entrance.island_south_to_east, Entrance.island_south_to_southeast, + Entrance.use_island_resort, Entrance.parrot_express_docks_to_volcano, Entrance.parrot_express_docks_to_dig_site, + Entrance.parrot_express_docks_to_jungle), ), + RegionData(RegionName.island_resort), + RegionData(RegionName.island_west, + (Entrance.island_west_to_islandfarmhouse, Entrance.island_west_to_gourmand_cave, Entrance.island_west_to_crystals_cave, + Entrance.island_west_to_shipwreck, Entrance.island_west_to_qi_walnut_room, Entrance.use_farm_obelisk, Entrance.parrot_express_jungle_to_docks, + Entrance.parrot_express_jungle_to_dig_site, Entrance.parrot_express_jungle_to_volcano, LogicEntrance.grow_spring_crops_on_island, + LogicEntrance.grow_summer_crops_on_island, LogicEntrance.grow_fall_crops_on_island, LogicEntrance.grow_winter_crops_on_island, + LogicEntrance.grow_indoor_crops_on_island), ), + RegionData(RegionName.island_east, (Entrance.island_east_to_leo_hut, Entrance.island_east_to_island_shrine)), + RegionData(RegionName.island_shrine), + RegionData(RegionName.island_south_east, (Entrance.island_southeast_to_pirate_cove,)), + RegionData(RegionName.island_north, + (Entrance.talk_to_island_trader, Entrance.island_north_to_field_office, Entrance.island_north_to_dig_site, Entrance.island_north_to_volcano, + Entrance.parrot_express_volcano_to_dig_site, Entrance.parrot_express_volcano_to_jungle, Entrance.parrot_express_volcano_to_docks), ), + RegionData(RegionName.volcano, (Entrance.climb_to_volcano_5, Entrance.volcano_to_secret_beach)), + RegionData(RegionName.volcano_secret_beach), + RegionData(RegionName.volcano_floor_5, (Entrance.talk_to_volcano_dwarf, Entrance.climb_to_volcano_10)), + RegionData(RegionName.volcano_dwarf_shop), + RegionData(RegionName.volcano_floor_10), + RegionData(RegionName.island_trader), + RegionData(RegionName.island_farmhouse, (LogicEntrance.island_cooking,)), + RegionData(RegionName.gourmand_frog_cave), + RegionData(RegionName.colored_crystals_cave), + RegionData(RegionName.shipwreck), + RegionData(RegionName.qi_walnut_room), + RegionData(RegionName.leo_hut), + RegionData(RegionName.pirate_cove), + RegionData(RegionName.field_office), + RegionData(RegionName.dig_site, + (Entrance.dig_site_to_professor_snail_cave, Entrance.parrot_express_dig_site_to_volcano, + Entrance.parrot_express_dig_site_to_docks, Entrance.parrot_express_dig_site_to_jungle), ), + + RegionData(RegionName.professor_snail_cave), + RegionData(RegionName.dangerous_mines_20), + RegionData(RegionName.dangerous_mines_60), + RegionData(RegionName.dangerous_mines_100), +) + +# Exists and where they lead +vanilla_connections: tuple[ConnectionData, ...] = ( + ConnectionData(Entrance.to_stardew_valley, RegionName.stardew_valley), + ConnectionData(Entrance.to_farmhouse, RegionName.farm_house), + ConnectionData(Entrance.farmhouse_to_farm, RegionName.farm), + ConnectionData(Entrance.downstairs_to_cellar, RegionName.cellar), + ConnectionData(Entrance.farm_to_backwoods, RegionName.backwoods), + ConnectionData(Entrance.farm_to_bus_stop, RegionName.bus_stop), + ConnectionData(Entrance.farm_to_forest, RegionName.forest), + ConnectionData(Entrance.farm_to_farmcave, RegionName.farm_cave, flag=RandomizationFlag.NON_PROGRESSION), + ConnectionData(Entrance.enter_greenhouse, RegionName.greenhouse), + ConnectionData(Entrance.enter_coop, RegionName.coop), + ConnectionData(Entrance.enter_barn, RegionName.barn), + ConnectionData(Entrance.enter_shed, RegionName.shed), + ConnectionData(Entrance.enter_slime_hutch, RegionName.slime_hutch), + ConnectionData(Entrance.use_desert_obelisk, RegionName.desert), + ConnectionData(Entrance.backwoods_to_mountain, RegionName.mountain), + ConnectionData(Entrance.bus_stop_to_town, RegionName.town), + ConnectionData(Entrance.bus_stop_to_tunnel_entrance, RegionName.tunnel_entrance), + ConnectionData(Entrance.tunnel_entrance_to_bus_tunnel, RegionName.bus_tunnel, flag=RandomizationFlag.NON_PROGRESSION), + ConnectionData(Entrance.take_bus_to_desert, RegionName.desert), + ConnectionData(Entrance.forest_to_town, RegionName.town), + ConnectionData(Entrance.forest_to_wizard_tower, RegionName.wizard_tower, + flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.enter_wizard_basement, RegionName.wizard_basement, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.forest_to_marnie_ranch, RegionName.ranch, + flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.forest_to_leah_cottage, RegionName.leah_house, + flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.enter_secret_woods, RegionName.secret_woods), + ConnectionData(Entrance.forest_to_sewer, RegionName.sewer, flag=RandomizationFlag.BUILDINGS), + # We remove the bit for masteries, because the mastery cave is to be excluded from the randomization if masteries are not shuffled. + ConnectionData(Entrance.forest_to_mastery_cave, RegionName.mastery_cave, flag=RandomizationFlag.BUILDINGS ^ RandomizationFlag.EXCLUDE_MASTERIES), + ConnectionData(Entrance.town_to_sewer, RegionName.sewer, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_mutant_bug_lair, RegionName.mutant_bug_lair, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.mountain_to_railroad, RegionName.railroad), + ConnectionData(Entrance.mountain_to_tent, RegionName.tent, + flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.mountain_to_carpenter_shop, RegionName.carpenter, + flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.mountain_to_maru_room, RegionName.maru_room, + flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.enter_sebastian_room, RegionName.sebastian_room, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.mountain_to_adventurer_guild, RegionName.adventurer_guild, + flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.adventurer_guild_to_bedroom, RegionName.adventurer_guild_bedroom), + ConnectionData(Entrance.enter_quarry, RegionName.quarry), + ConnectionData(Entrance.enter_quarry_mine_entrance, RegionName.quarry_mine_entrance, + flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_quarry_mine, RegionName.quarry_mine), + ConnectionData(Entrance.mountain_to_town, RegionName.town), + ConnectionData(Entrance.town_to_community_center, RegionName.community_center, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.access_crafts_room, RegionName.crafts_room), + ConnectionData(Entrance.access_pantry, RegionName.pantry), + ConnectionData(Entrance.access_fish_tank, RegionName.fish_tank), + ConnectionData(Entrance.access_boiler_room, RegionName.boiler_room), + ConnectionData(Entrance.access_bulletin_board, RegionName.bulletin_board), + ConnectionData(Entrance.access_vault, RegionName.vault), + ConnectionData(Entrance.town_to_hospital, RegionName.hospital, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.enter_harvey_room, RegionName.harvey_room, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.town_to_pierre_general_store, RegionName.pierre_store, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.enter_sunroom, RegionName.sunroom, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.town_to_clint_blacksmith, RegionName.blacksmith, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.town_to_saloon, RegionName.saloon, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.play_journey_of_the_prairie_king, RegionName.jotpk_world_1), + ConnectionData(Entrance.reach_jotpk_world_2, RegionName.jotpk_world_2), + ConnectionData(Entrance.reach_jotpk_world_3, RegionName.jotpk_world_3), + ConnectionData(Entrance.play_junimo_kart, RegionName.junimo_kart_1), + ConnectionData(Entrance.reach_junimo_kart_2, RegionName.junimo_kart_2), + ConnectionData(Entrance.reach_junimo_kart_3, RegionName.junimo_kart_3), + ConnectionData(Entrance.reach_junimo_kart_4, RegionName.junimo_kart_4), + ConnectionData(Entrance.town_to_sam_house, RegionName.sam_house, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.town_to_haley_house, RegionName.haley_house, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.town_to_mayor_manor, RegionName.mayor_house, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.town_to_alex_house, RegionName.alex_house, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.town_to_trailer, RegionName.trailer, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.town_to_museum, RegionName.museum, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.town_to_jojamart, RegionName.jojamart, + flag=RandomizationFlag.PELICAN_TOWN | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.purchase_movie_ticket, RegionName.movie_ticket_stand), + ConnectionData(Entrance.enter_abandoned_jojamart, RegionName.abandoned_jojamart), + ConnectionData(Entrance.enter_movie_theater, RegionName.movie_theater), + ConnectionData(Entrance.town_to_beach, RegionName.beach), + ConnectionData(Entrance.enter_elliott_house, RegionName.elliott_house, + flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.beach_to_willy_fish_shop, RegionName.fish_shop, + flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.enter_tide_pools, RegionName.tide_pools), + ConnectionData(Entrance.mountain_to_the_mines, RegionName.mines, + flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.dig_to_mines_floor_5, RegionName.mines_floor_5), + ConnectionData(Entrance.dig_to_mines_floor_10, RegionName.mines_floor_10), + ConnectionData(Entrance.dig_to_mines_floor_15, RegionName.mines_floor_15), + ConnectionData(Entrance.dig_to_mines_floor_20, RegionName.mines_floor_20), + ConnectionData(Entrance.dig_to_mines_floor_25, RegionName.mines_floor_25), + ConnectionData(Entrance.dig_to_mines_floor_30, RegionName.mines_floor_30), + ConnectionData(Entrance.dig_to_mines_floor_35, RegionName.mines_floor_35), + ConnectionData(Entrance.dig_to_mines_floor_40, RegionName.mines_floor_40), + ConnectionData(Entrance.dig_to_mines_floor_45, RegionName.mines_floor_45), + ConnectionData(Entrance.dig_to_mines_floor_50, RegionName.mines_floor_50), + ConnectionData(Entrance.dig_to_mines_floor_55, RegionName.mines_floor_55), + ConnectionData(Entrance.dig_to_mines_floor_60, RegionName.mines_floor_60), + ConnectionData(Entrance.dig_to_mines_floor_65, RegionName.mines_floor_65), + ConnectionData(Entrance.dig_to_mines_floor_70, RegionName.mines_floor_70), + ConnectionData(Entrance.dig_to_mines_floor_75, RegionName.mines_floor_75), + ConnectionData(Entrance.dig_to_mines_floor_80, RegionName.mines_floor_80), + ConnectionData(Entrance.dig_to_mines_floor_85, RegionName.mines_floor_85), + ConnectionData(Entrance.dig_to_mines_floor_90, RegionName.mines_floor_90), + ConnectionData(Entrance.dig_to_mines_floor_95, RegionName.mines_floor_95), + ConnectionData(Entrance.dig_to_mines_floor_100, RegionName.mines_floor_100), + ConnectionData(Entrance.dig_to_mines_floor_105, RegionName.mines_floor_105), + ConnectionData(Entrance.dig_to_mines_floor_110, RegionName.mines_floor_110), + ConnectionData(Entrance.dig_to_mines_floor_115, RegionName.mines_floor_115), + ConnectionData(Entrance.dig_to_mines_floor_120, RegionName.mines_floor_120), + ConnectionData(Entrance.enter_skull_cavern_entrance, RegionName.skull_cavern_entrance, + flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.enter_oasis, RegionName.oasis, + flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.enter_casino, RegionName.casino, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_skull_cavern, RegionName.skull_cavern), + ConnectionData(Entrance.mine_to_skull_cavern_floor_25, RegionName.skull_cavern_25), + ConnectionData(Entrance.mine_to_skull_cavern_floor_50, RegionName.skull_cavern_50), + ConnectionData(Entrance.mine_to_skull_cavern_floor_75, RegionName.skull_cavern_75), + ConnectionData(Entrance.mine_to_skull_cavern_floor_100, RegionName.skull_cavern_100), + ConnectionData(Entrance.mine_to_skull_cavern_floor_125, RegionName.skull_cavern_125), + ConnectionData(Entrance.mine_to_skull_cavern_floor_150, RegionName.skull_cavern_150), + ConnectionData(Entrance.mine_to_skull_cavern_floor_175, RegionName.skull_cavern_175), + ConnectionData(Entrance.mine_to_skull_cavern_floor_200, RegionName.skull_cavern_200), + ConnectionData(Entrance.enter_witch_warp_cave, RegionName.witch_warp_cave, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_witch_swamp, RegionName.witch_swamp, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_witch_hut, RegionName.witch_hut, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.witch_warp_to_wizard_basement, RegionName.wizard_basement, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_bathhouse_entrance, RegionName.bathhouse_entrance, + flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.enter_locker_room, RegionName.locker_room, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.enter_public_bath, RegionName.public_bath, flag=RandomizationFlag.BUILDINGS), + ConnectionData(LogicEntrance.talk_to_mines_dwarf, LogicRegion.mines_dwarf_shop), + + ConnectionData(LogicEntrance.buy_from_traveling_merchant, LogicRegion.traveling_cart), + ConnectionData(LogicEntrance.buy_from_traveling_merchant_sunday, LogicRegion.traveling_cart_sunday), + ConnectionData(LogicEntrance.buy_from_traveling_merchant_monday, LogicRegion.traveling_cart_monday), + ConnectionData(LogicEntrance.buy_from_traveling_merchant_tuesday, LogicRegion.traveling_cart_tuesday), + ConnectionData(LogicEntrance.buy_from_traveling_merchant_wednesday, LogicRegion.traveling_cart_wednesday), + ConnectionData(LogicEntrance.buy_from_traveling_merchant_thursday, LogicRegion.traveling_cart_thursday), + ConnectionData(LogicEntrance.buy_from_traveling_merchant_friday, LogicRegion.traveling_cart_friday), + ConnectionData(LogicEntrance.buy_from_traveling_merchant_saturday, LogicRegion.traveling_cart_saturday), + ConnectionData(LogicEntrance.complete_raccoon_requests, LogicRegion.raccoon_daddy), + ConnectionData(LogicEntrance.fish_in_waterfall, LogicRegion.forest_waterfall), + ConnectionData(LogicEntrance.buy_from_raccoon, LogicRegion.raccoon_shop), + ConnectionData(LogicEntrance.farmhouse_cooking, LogicRegion.kitchen), + ConnectionData(LogicEntrance.watch_queen_of_sauce, LogicRegion.queen_of_sauce), + + ConnectionData(LogicEntrance.grow_spring_crops, LogicRegion.spring_farming), + ConnectionData(LogicEntrance.grow_summer_crops, LogicRegion.summer_farming), + ConnectionData(LogicEntrance.grow_fall_crops, LogicRegion.fall_farming), + ConnectionData(LogicEntrance.grow_winter_crops, LogicRegion.winter_farming), + ConnectionData(LogicEntrance.grow_spring_crops_in_greenhouse, LogicRegion.spring_farming), + ConnectionData(LogicEntrance.grow_summer_crops_in_greenhouse, LogicRegion.summer_farming), + ConnectionData(LogicEntrance.grow_fall_crops_in_greenhouse, LogicRegion.fall_farming), + ConnectionData(LogicEntrance.grow_winter_crops_in_greenhouse, LogicRegion.winter_farming), + ConnectionData(LogicEntrance.grow_indoor_crops_in_greenhouse, LogicRegion.indoor_farming), + ConnectionData(LogicEntrance.grow_summer_fall_crops_in_summer, LogicRegion.summer_or_fall_farming), + ConnectionData(LogicEntrance.grow_summer_fall_crops_in_fall, LogicRegion.summer_or_fall_farming), + + ConnectionData(LogicEntrance.shipping, LogicRegion.shipping), + ConnectionData(LogicEntrance.blacksmith_copper, LogicRegion.blacksmith_copper), + ConnectionData(LogicEntrance.blacksmith_iron, LogicRegion.blacksmith_iron), + ConnectionData(LogicEntrance.blacksmith_gold, LogicRegion.blacksmith_gold), + ConnectionData(LogicEntrance.blacksmith_iridium, LogicRegion.blacksmith_iridium), + ConnectionData(LogicEntrance.fishing, LogicRegion.fishing), + ConnectionData(LogicEntrance.attend_egg_festival, LogicRegion.egg_festival), + ConnectionData(LogicEntrance.attend_desert_festival, LogicRegion.desert_festival), + ConnectionData(LogicEntrance.attend_flower_dance, LogicRegion.flower_dance), + ConnectionData(LogicEntrance.attend_luau, LogicRegion.luau), + ConnectionData(LogicEntrance.attend_trout_derby, LogicRegion.trout_derby), + ConnectionData(LogicEntrance.attend_moonlight_jellies, LogicRegion.moonlight_jellies), + ConnectionData(LogicEntrance.attend_fair, LogicRegion.fair), + ConnectionData(LogicEntrance.attend_spirit_eve, LogicRegion.spirit_eve), + ConnectionData(LogicEntrance.attend_festival_of_ice, LogicRegion.festival_of_ice), + ConnectionData(LogicEntrance.attend_night_market, LogicRegion.night_market), + ConnectionData(LogicEntrance.attend_winter_star, LogicRegion.winter_star), + ConnectionData(LogicEntrance.attend_squidfest, LogicRegion.squidfest), + ConnectionData(LogicEntrance.buy_experience_books, LogicRegion.bookseller_1), + ConnectionData(LogicEntrance.buy_year1_books, LogicRegion.bookseller_2), + ConnectionData(LogicEntrance.buy_year3_books, LogicRegion.bookseller_3), +) + +ginger_island_connections = ( + ConnectionData(Entrance.use_island_obelisk, RegionName.island_south), + ConnectionData(Entrance.use_farm_obelisk, RegionName.farm), + ConnectionData(Entrance.mountain_to_leo_treehouse, RegionName.leo_treehouse, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA), + ConnectionData(Entrance.fish_shop_to_boat_tunnel, RegionName.boat_tunnel, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.boat_to_ginger_island, RegionName.island_south), + ConnectionData(Entrance.enter_dangerous_skull_cavern, RegionName.dangerous_skull_cavern), + ConnectionData(Entrance.dig_to_dangerous_mines_20, RegionName.dangerous_mines_20), + ConnectionData(Entrance.dig_to_dangerous_mines_60, RegionName.dangerous_mines_60), + ConnectionData(Entrance.dig_to_dangerous_mines_100, RegionName.dangerous_mines_100), + ConnectionData(Entrance.island_south_to_west, RegionName.island_west), + ConnectionData(Entrance.island_south_to_north, RegionName.island_north), + ConnectionData(Entrance.island_south_to_east, RegionName.island_east), + ConnectionData(Entrance.island_south_to_southeast, RegionName.island_south_east), + ConnectionData(Entrance.use_island_resort, RegionName.island_resort), + ConnectionData(Entrance.island_west_to_islandfarmhouse, RegionName.island_farmhouse, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_west_to_gourmand_cave, RegionName.gourmand_frog_cave, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_west_to_crystals_cave, RegionName.colored_crystals_cave, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_west_to_shipwreck, RegionName.shipwreck, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_west_to_qi_walnut_room, RegionName.qi_walnut_room, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_east_to_leo_hut, RegionName.leo_hut, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_east_to_island_shrine, RegionName.island_shrine, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_southeast_to_pirate_cove, RegionName.pirate_cove, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_north_to_field_office, RegionName.field_office, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_north_to_dig_site, RegionName.dig_site), + ConnectionData(Entrance.dig_site_to_professor_snail_cave, RegionName.professor_snail_cave, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.island_north_to_volcano, RegionName.volcano, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.volcano_to_secret_beach, RegionName.volcano_secret_beach, flag=RandomizationFlag.BUILDINGS), + ConnectionData(Entrance.talk_to_island_trader, RegionName.island_trader), + ConnectionData(Entrance.climb_to_volcano_5, RegionName.volcano_floor_5), + ConnectionData(Entrance.talk_to_volcano_dwarf, RegionName.volcano_dwarf_shop), + ConnectionData(Entrance.climb_to_volcano_10, RegionName.volcano_floor_10), + ConnectionData(Entrance.parrot_express_jungle_to_docks, RegionName.island_south), + ConnectionData(Entrance.parrot_express_dig_site_to_docks, RegionName.island_south), + ConnectionData(Entrance.parrot_express_volcano_to_docks, RegionName.island_south), + ConnectionData(Entrance.parrot_express_volcano_to_jungle, RegionName.island_west), + ConnectionData(Entrance.parrot_express_docks_to_jungle, RegionName.island_west), + ConnectionData(Entrance.parrot_express_dig_site_to_jungle, RegionName.island_west), + ConnectionData(Entrance.parrot_express_docks_to_dig_site, RegionName.dig_site), + ConnectionData(Entrance.parrot_express_volcano_to_dig_site, RegionName.dig_site), + ConnectionData(Entrance.parrot_express_jungle_to_dig_site, RegionName.dig_site), + ConnectionData(Entrance.parrot_express_dig_site_to_volcano, RegionName.island_north), + ConnectionData(Entrance.parrot_express_docks_to_volcano, RegionName.island_north), + ConnectionData(Entrance.parrot_express_jungle_to_volcano, RegionName.island_north), + ConnectionData(LogicEntrance.grow_spring_crops_on_island, LogicRegion.spring_farming), + ConnectionData(LogicEntrance.grow_summer_crops_on_island, LogicRegion.summer_farming), + ConnectionData(LogicEntrance.grow_fall_crops_on_island, LogicRegion.fall_farming), + ConnectionData(LogicEntrance.grow_winter_crops_on_island, LogicRegion.winter_farming), + ConnectionData(LogicEntrance.grow_indoor_crops_on_island, LogicRegion.indoor_farming), + ConnectionData(LogicEntrance.island_cooking, LogicRegion.kitchen), +) + +connections_without_ginger_island_by_name: Mapping[str, ConnectionData] = MappingProxyType({ + connection.name: connection + for connection in vanilla_connections +}) +regions_without_ginger_island_by_name: Mapping[str, RegionData] = MappingProxyType({ + region.name: region + for region in vanilla_regions +}) + +connections_with_ginger_island_by_name: Mapping[str, ConnectionData] = MappingProxyType({ + connection.name: connection + for connection in vanilla_connections + ginger_island_connections +}) +regions_with_ginger_island_by_name: Mapping[str, RegionData] = MappingProxyType({ + region.name: region + for region in vanilla_regions + ginger_island_regions +}) diff --git a/worlds/stardew_valley/test/TestRegions.py b/worlds/stardew_valley/test/TestRegions.py deleted file mode 100644 index 07e3094fb2e2..000000000000 --- a/worlds/stardew_valley/test/TestRegions.py +++ /dev/null @@ -1,173 +0,0 @@ -import random -import unittest -from typing import Set - -from BaseClasses import get_seed -from .bases import SVTestCase -from .options.utils import fill_dataclass_with_default -from .. import create_content -from ..options import EntranceRandomization, ExcludeGingerIsland, SkillProgression -from ..regions import vanilla_regions, vanilla_connections, randomize_connections, RandomizationFlag, create_final_connections_and_regions -from ..strings.entrance_names import Entrance as EntranceName -from ..strings.region_names import Region as RegionName - -connections_by_name = {connection.name for connection in vanilla_connections} -regions_by_name = {region.name for region in vanilla_regions} - - -class TestRegions(unittest.TestCase): - def test_region_exits_lead_somewhere(self): - for region in vanilla_regions: - with self.subTest(region=region): - for exit in region.exits: - self.assertIn(exit, connections_by_name, - f"{region.name} is leading to {exit} but it does not exist.") - - def test_connection_lead_somewhere(self): - for connection in vanilla_connections: - with self.subTest(connection=connection): - self.assertIn(connection.destination, regions_by_name, - f"{connection.name} is leading to {connection.destination} but it does not exist.") - - -def explore_connections_tree_up_to_blockers(blocked_entrances: Set[str], connections_by_name, regions_by_name): - explored_entrances = set() - explored_regions = set() - entrances_to_explore = set() - current_node_name = "Menu" - current_node = regions_by_name[current_node_name] - entrances_to_explore.update(current_node.exits) - while entrances_to_explore: - current_entrance_name = entrances_to_explore.pop() - current_entrance = connections_by_name[current_entrance_name] - current_node_name = current_entrance.destination - - explored_entrances.add(current_entrance_name) - explored_regions.add(current_node_name) - - if current_entrance_name in blocked_entrances: - continue - - current_node = regions_by_name[current_node_name] - entrances_to_explore.update({entrance for entrance in current_node.exits if entrance not in explored_entrances}) - return explored_regions - - -class TestEntranceRando(SVTestCase): - - def test_entrance_randomization(self): - for option, flag in [(EntranceRandomization.option_pelican_town, RandomizationFlag.PELICAN_TOWN), - (EntranceRandomization.option_non_progression, RandomizationFlag.NON_PROGRESSION), - (EntranceRandomization.option_buildings_without_house, RandomizationFlag.BUILDINGS), - (EntranceRandomization.option_buildings, RandomizationFlag.BUILDINGS)]: - sv_options = fill_dataclass_with_default({ - EntranceRandomization.internal_name: option, - ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_false, - SkillProgression.internal_name: SkillProgression.option_progressive_with_masteries, - }) - content = create_content(sv_options) - seed = get_seed() - rand = random.Random(seed) - with self.subTest(flag=flag, msg=f"Seed: {seed}"): - entrances, regions = create_final_connections_and_regions(sv_options) - _, randomized_connections = randomize_connections(rand, sv_options, content, regions, entrances) - - for connection in vanilla_connections: - if flag in connection.flag: - connection_in_randomized = connection.name in randomized_connections - reverse_in_randomized = connection.reverse in randomized_connections - self.assertTrue(connection_in_randomized, f"Connection {connection.name} should be randomized but it is not in the output.") - self.assertTrue(reverse_in_randomized, f"Connection {connection.reverse} should be randomized but it is not in the output.") - - self.assertEqual(len(set(randomized_connections.values())), len(randomized_connections.values()), - f"Connections are duplicated in randomization.") - - def test_entrance_randomization_without_island(self): - for option, flag in [(EntranceRandomization.option_pelican_town, RandomizationFlag.PELICAN_TOWN), - (EntranceRandomization.option_non_progression, RandomizationFlag.NON_PROGRESSION), - (EntranceRandomization.option_buildings_without_house, RandomizationFlag.BUILDINGS), - (EntranceRandomization.option_buildings, RandomizationFlag.BUILDINGS)]: - - sv_options = fill_dataclass_with_default({ - EntranceRandomization.internal_name: option, - ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_true, - SkillProgression.internal_name: SkillProgression.option_progressive_with_masteries, - }) - content = create_content(sv_options) - seed = get_seed() - rand = random.Random(seed) - with self.subTest(option=option, flag=flag, seed=seed): - entrances, regions = create_final_connections_and_regions(sv_options) - _, randomized_connections = randomize_connections(rand, sv_options, content, regions, entrances) - - for connection in vanilla_connections: - if flag in connection.flag: - if RandomizationFlag.GINGER_ISLAND in connection.flag: - self.assertNotIn(connection.name, randomized_connections, - f"Connection {connection.name} should not be randomized but it is in the output.") - self.assertNotIn(connection.reverse, randomized_connections, - f"Connection {connection.reverse} should not be randomized but it is in the output.") - else: - self.assertIn(connection.name, randomized_connections, - f"Connection {connection.name} should be randomized but it is not in the output.") - self.assertIn(connection.reverse, randomized_connections, - f"Connection {connection.reverse} should be randomized but it is not in the output.") - - self.assertEqual(len(set(randomized_connections.values())), len(randomized_connections.values()), - f"Connections are duplicated in randomization.") - - def test_cannot_put_island_access_on_island(self): - sv_options = fill_dataclass_with_default({ - EntranceRandomization.internal_name: EntranceRandomization.option_buildings, - ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_false, - SkillProgression.internal_name: SkillProgression.option_progressive_with_masteries, - }) - content = create_content(sv_options) - - for i in range(0, 100 if self.skip_long_tests else 10000): - seed = get_seed() - rand = random.Random(seed) - with self.subTest(msg=f"Seed: {seed}"): - entrances, regions = create_final_connections_and_regions(sv_options) - randomized_connections, randomized_data = randomize_connections(rand, sv_options, content, regions, entrances) - connections_by_name = {connection.name: connection for connection in randomized_connections} - - blocked_entrances = {EntranceName.use_island_obelisk, EntranceName.boat_to_ginger_island} - required_regions = {RegionName.wizard_tower, RegionName.boat_tunnel} - self.assert_can_reach_any_region_before_blockers(required_regions, blocked_entrances, connections_by_name, regions) - - def assert_can_reach_any_region_before_blockers(self, required_regions, blocked_entrances, connections_by_name, regions_by_name): - explored_regions = explore_connections_tree_up_to_blockers(blocked_entrances, connections_by_name, regions_by_name) - self.assertTrue(any(region in explored_regions for region in required_regions)) - - -class TestEntranceClassifications(SVTestCase): - - def test_non_progression_are_all_accessible_with_empty_inventory(self): - for option, flag in [(EntranceRandomization.option_pelican_town, RandomizationFlag.PELICAN_TOWN), - (EntranceRandomization.option_non_progression, RandomizationFlag.NON_PROGRESSION)]: - world_options = { - EntranceRandomization.internal_name: option - } - with self.solo_world_sub_test(world_options=world_options, flag=flag) as (multiworld, sv_world): - ap_entrances = {entrance.name: entrance for entrance in multiworld.get_entrances()} - for randomized_entrance in sv_world.randomized_entrances: - if randomized_entrance in ap_entrances: - ap_entrance_origin = ap_entrances[randomized_entrance] - self.assertTrue(ap_entrance_origin.access_rule(multiworld.state)) - if sv_world.randomized_entrances[randomized_entrance] in ap_entrances: - ap_entrance_destination = multiworld.get_entrance(sv_world.randomized_entrances[randomized_entrance], 1) - self.assertTrue(ap_entrance_destination.access_rule(multiworld.state)) - - def test_no_ginger_island_entrances_when_excluded(self): - world_options = { - EntranceRandomization.internal_name: EntranceRandomization.option_disabled, - ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_true - } - with self.solo_world_sub_test(world_options=world_options) as (multiworld, _): - ap_entrances = {entrance.name: entrance for entrance in multiworld.get_entrances()} - entrance_data_by_name = {entrance.name: entrance for entrance in vanilla_connections} - for entrance_name in ap_entrances: - entrance_data = entrance_data_by_name[entrance_name] - with self.subTest(f"{entrance_name}: {entrance_data.flag}"): - self.assertFalse(entrance_data.flag & RandomizationFlag.GINGER_ISLAND) diff --git a/worlds/stardew_valley/test/assertion/rule_assert.py b/worlds/stardew_valley/test/assertion/rule_assert.py index 02362f2d150d..39b69a529f74 100644 --- a/worlds/stardew_valley/test/assertion/rule_assert.py +++ b/worlds/stardew_valley/test/assertion/rule_assert.py @@ -1,7 +1,7 @@ from typing import List from unittest import TestCase -from BaseClasses import CollectionState, Location, Region +from BaseClasses import CollectionState, Location, Region, Entrance from ...stardew_rule import StardewRule, false_, MISSING_ITEM, Reach from ...stardew_rule.rule_explain import explain @@ -79,3 +79,13 @@ def assert_cannot_reach_region(self, region: Region | str, state: CollectionStat except KeyError as e: raise AssertionError(f"Error while checking region {region_name}: {e}" f"\nExplanation: {expl}") + + def assert_can_reach_entrance(self, entrance: Entrance | str, state: CollectionState) -> None: + entrance_name = entrance.name if isinstance(entrance, Entrance) else entrance + expl = explain(Reach(entrance_name, "Entrance", 1), state) + try: + can_reach = state.can_reach_entrance(entrance_name, 1) + self.assertTrue(can_reach, expl) + except KeyError as e: + raise AssertionError(f"Error while checking entrance {entrance_name}: {e}" + f"\nExplanation: {expl}") diff --git a/worlds/stardew_valley/test/bases.py b/worlds/stardew_valley/test/bases.py index affc20cde191..a2852183996d 100644 --- a/worlds/stardew_valley/test/bases.py +++ b/worlds/stardew_valley/test/bases.py @@ -7,7 +7,7 @@ from contextlib import contextmanager from typing import Optional, Dict, Union, Any, List, Iterable -from BaseClasses import get_seed, MultiWorld, Location, Item, CollectionState +from BaseClasses import get_seed, MultiWorld, Location, Item, CollectionState, Entrance from test.bases import WorldTestBase from test.general import gen_steps, setup_solo_multiworld as setup_base_solo_multiworld from worlds.AutoWorld import call_all @@ -179,6 +179,11 @@ def assert_cannot_reach_location(self, location: Location | str, state: Collecti state = self.multiworld.state super().assert_cannot_reach_location(location, state) + def assert_can_reach_entrance(self, entrance: Entrance | str, state: CollectionState | None = None) -> None: + if state is None: + state = self.multiworld.state + super().assert_can_reach_entrance(entrance, state) + pre_generated_worlds = {} diff --git a/worlds/stardew_valley/test/mods/TestMods.py b/worlds/stardew_valley/test/mods/TestMods.py index be6ce710768d..8cff10b4fc3b 100644 --- a/worlds/stardew_valley/test/mods/TestMods.py +++ b/worlds/stardew_valley/test/mods/TestMods.py @@ -1,17 +1,13 @@ -import random from typing import ClassVar -from BaseClasses import get_seed from test.param import classvar_matrix from ..TestGeneration import get_all_permanent_progression_items from ..assertion import ModAssertMixin, WorldAssertMixin from ..bases import SVTestCase, SVTestBase, solo_multiworld from ..options.presets import allsanity_mods_6_x_x -from ..options.utils import fill_dataclass_with_default -from ... import options, Group, create_content +from ... import options, Group from ...mods.mod_data import ModNames from ...options.options import all_mods -from ...regions import RandomizationFlag, randomize_connections, create_final_connections_and_regions class TestCanGenerateAllsanityWithMods(WorldAssertMixin, ModAssertMixin, SVTestCase): @@ -117,39 +113,6 @@ def test_all_progression_items_except_island_are_added_to_the_pool(self): self.assertIn(progression_item.name, all_created_items) -class TestModEntranceRando(SVTestCase): - - def test_mod_entrance_randomization(self): - for option, flag in [(options.EntranceRandomization.option_pelican_town, RandomizationFlag.PELICAN_TOWN), - (options.EntranceRandomization.option_non_progression, RandomizationFlag.NON_PROGRESSION), - (options.EntranceRandomization.option_buildings_without_house, RandomizationFlag.BUILDINGS), - (options.EntranceRandomization.option_buildings, RandomizationFlag.BUILDINGS)]: - sv_options = fill_dataclass_with_default({ - options.EntranceRandomization.internal_name: option, - options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_false, - options.SkillProgression.internal_name: options.SkillProgression.option_progressive_with_masteries, - options.Mods.internal_name: frozenset(options.Mods.valid_keys) - }) - content = create_content(sv_options) - seed = get_seed() - rand = random.Random(seed) - with self.subTest(option=option, flag=flag, seed=seed): - final_connections, final_regions = create_final_connections_and_regions(sv_options) - - _, randomized_connections = randomize_connections(rand, sv_options, content, final_regions, final_connections) - - for connection_name in final_connections: - connection = final_connections[connection_name] - if flag in connection.flag: - connection_in_randomized = connection_name in randomized_connections - reverse_in_randomized = connection.reverse in randomized_connections - self.assertTrue(connection_in_randomized, f"Connection {connection_name} should be randomized but it is not in the output") - self.assertTrue(reverse_in_randomized, f"Connection {connection.reverse} should be randomized but it is not in the output.") - - self.assertEqual(len(set(randomized_connections.values())), len(randomized_connections.values()), - f"Connections are duplicated in randomization.") - - class TestVanillaLogicAlternativeWhenQuestsAreNotRandomized(WorldAssertMixin, SVTestBase): """We often forget to add an alternative rule that works when quests are not randomized. When this happens, some Location are not reachable because they depend on items that are only added to the pool when quests are randomized. diff --git a/worlds/stardew_valley/test/regions/TestEntranceClassifications.py b/worlds/stardew_valley/test/regions/TestEntranceClassifications.py new file mode 100644 index 000000000000..43a7090482b9 --- /dev/null +++ b/worlds/stardew_valley/test/regions/TestEntranceClassifications.py @@ -0,0 +1,36 @@ +from ..bases import SVTestBase +from ... import options +from ...regions.model import RandomizationFlag +from ...regions.regions import create_all_connections + + +class EntranceRandomizationAssertMixin: + + def assert_non_progression_are_all_accessible_with_empty_inventory(self: SVTestBase): + all_connections = create_all_connections(self.world.content.registered_packs) + non_progression_connections = [connection for connection in all_connections.values() if RandomizationFlag.BIT_NON_PROGRESSION in connection.flag] + + for non_progression_connections in non_progression_connections: + with self.subTest(connection=non_progression_connections): + self.assert_can_reach_entrance(non_progression_connections.name) + + +# This test does not actually need to generate with entrance randomization. Entrances rules are the same regardless of the randomization. +class TestVanillaEntranceClassifications(EntranceRandomizationAssertMixin, SVTestBase): + options = { + options.ExcludeGingerIsland: options.ExcludeGingerIsland.option_false, + options.Mods: frozenset() + } + + def test_non_progression_are_all_accessible_with_empty_inventory(self): + self.assert_non_progression_are_all_accessible_with_empty_inventory() + + +class TestModdedEntranceClassifications(EntranceRandomizationAssertMixin, SVTestBase): + options = { + options.ExcludeGingerIsland: options.ExcludeGingerIsland.option_false, + options.Mods: frozenset(options.Mods.valid_keys) + } + + def test_non_progression_are_all_accessible_with_empty_inventory(self): + self.assert_non_progression_are_all_accessible_with_empty_inventory() diff --git a/worlds/stardew_valley/test/regions/TestEntranceRandomization.py b/worlds/stardew_valley/test/regions/TestEntranceRandomization.py new file mode 100644 index 000000000000..15c46637ab05 --- /dev/null +++ b/worlds/stardew_valley/test/regions/TestEntranceRandomization.py @@ -0,0 +1,167 @@ +from collections import deque +from collections.abc import Collection +from unittest.mock import patch, Mock + +from BaseClasses import get_seed, MultiWorld, Entrance +from ..assertion import WorldAssertMixin +from ..bases import SVTestCase, solo_multiworld +from ... import options +from ...mods.mod_data import ModNames +from ...options import EntranceRandomization, ExcludeGingerIsland, SkillProgression +from ...options.options import all_mods +from ...regions.entrance_rando import create_entrance_rando_target, prepare_mod_data, connect_regions +from ...regions.model import RegionData, ConnectionData, RandomizationFlag +from ...strings.entrance_names import Entrance as EntranceName +from ...strings.region_names import Region as RegionName + + +class TestEntranceRando(SVTestCase): + + def test_given_connection_matching_randomization_when_connect_regions_then_make_connection_entrance_rando_target(self): + region_data_by_name = { + "Region1": RegionData("Region1", ("randomized_connection", "not_randomized")), + "Region2": RegionData("Region2"), + "Region3": RegionData("Region3"), + } + connection_data_by_name = { + "randomized_connection": ConnectionData("randomized_connection", "Region2", flag=RandomizationFlag.PELICAN_TOWN), + "not_randomized": ConnectionData("not_randomized", "Region2", flag=RandomizationFlag.BUILDINGS), + } + regions_by_name = { + "Region1": Mock(), + "Region2": Mock(), + "Region3": Mock(), + } + player_randomization_flag = RandomizationFlag.BIT_PELICAN_TOWN + + with patch("worlds.stardew_valley.regions.entrance_rando.create_entrance_rando_target") as mock_create_entrance_rando_target: + connect_regions(region_data_by_name, connection_data_by_name, regions_by_name, player_randomization_flag) + + expected_origin, expected_destination = regions_by_name["Region1"], regions_by_name["Region2"] + expected_connection = connection_data_by_name["randomized_connection"] + mock_create_entrance_rando_target.assert_called_once_with(expected_origin, expected_destination, expected_connection) + + def test_when_create_entrance_rando_target_then_create_exit_and_er_target(self): + origin = Mock() + destination = Mock() + connection_data = ConnectionData("origin to destination", "destination") + + create_entrance_rando_target(origin, destination, connection_data) + + origin.create_exit.assert_called_once_with("origin to destination") + destination.create_er_target.assert_called_once_with("destination to origin") + + def test_when_prepare_mod_data_then_swapped_connections_contains_both_directions(self): + placements = Mock(pairings=[("A to B", "C to A"), ("C to D", "A to C")]) + + swapped_connections = prepare_mod_data(placements) + + self.assertEqual({"A to B": "A to C", "C to A": "B to A", "C to D": "C to A", "A to C": "D to C"}, swapped_connections) + + +class TestEntranceRandoCreatesValidWorlds(WorldAssertMixin, SVTestCase): + + # The following tests validate that ER still generates winnable and logically-sane games with given mods. + # Mods that do not interact with entrances are skipped + # Not all ER settings are tested, because 'buildings' is, essentially, a superset of all others + def test_ginger_island_excluded_buildings(self): + world_options = { + options.EntranceRandomization: options.EntranceRandomization.option_buildings, + options.ExcludeGingerIsland: options.ExcludeGingerIsland.option_true + } + with solo_multiworld(world_options) as (multi_world, _): + self.assert_basic_checks(multi_world) + + def test_deepwoods_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.deepwoods, options.EntranceRandomization.option_buildings) + + def test_juna_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.juna, options.EntranceRandomization.option_buildings) + + def test_jasper_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.jasper, options.EntranceRandomization.option_buildings) + + def test_alec_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.alec, options.EntranceRandomization.option_buildings) + + def test_yoba_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.yoba, options.EntranceRandomization.option_buildings) + + def test_eugene_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.eugene, options.EntranceRandomization.option_buildings) + + def test_ayeisha_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.ayeisha, options.EntranceRandomization.option_buildings) + + def test_riley_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.riley, options.EntranceRandomization.option_buildings) + + def test_sve_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.sve, options.EntranceRandomization.option_buildings) + + def test_alecto_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.alecto, options.EntranceRandomization.option_buildings) + + def test_lacey_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.lacey, options.EntranceRandomization.option_buildings) + + def test_boarding_house_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(ModNames.boarding_house, options.EntranceRandomization.option_buildings) + + def test_all_mods_entrance_randomization_buildings(self): + self.perform_basic_checks_on_mod_with_er(all_mods, options.EntranceRandomization.option_buildings) + + def perform_basic_checks_on_mod_with_er(self, mods: str | set[str], er_option: int) -> None: + if isinstance(mods, str): + mods = {mods} + world_options = { + options.EntranceRandomization: er_option, + options.Mods: frozenset(mods), + options.ExcludeGingerIsland: options.ExcludeGingerIsland.option_false + } + with solo_multiworld(world_options) as (multi_world, _): + self.assert_basic_checks(multi_world) + + +# GER should have this covered, but it's good to have a backup +class TestGingerIslandEntranceRando(SVTestCase): + def test_cannot_put_island_access_on_island(self): + test_options = { + options.EntranceRandomization: EntranceRandomization.option_buildings, + options.ExcludeGingerIsland: ExcludeGingerIsland.option_false, + options.SkillProgression: SkillProgression.option_progressive_with_masteries, + } + + blocked_entrances = {EntranceName.use_island_obelisk, EntranceName.boat_to_ginger_island} + required_regions = {RegionName.wizard_tower, RegionName.boat_tunnel} + + for i in range(0, 10 if self.skip_long_tests else 1000): + seed = get_seed() + with self.solo_world_sub_test(f"Seed: {seed}", world_options=test_options, world_caching=False, seed=seed) as (multiworld, world): + self.assert_can_reach_any_region_before_blockers(required_regions, blocked_entrances, multiworld) + + def assert_can_reach_any_region_before_blockers(self, required_regions: Collection[str], blocked_entrances: Collection[str], multiworld: MultiWorld): + explored_regions = explore_regions_up_to_blockers(blocked_entrances, multiworld) + self.assertTrue(any(region in explored_regions for region in required_regions)) + + +def explore_regions_up_to_blockers(blocked_entrances: Collection[str], multiworld: MultiWorld) -> set[str]: + explored_regions: set[str] = set() + regions_by_name = multiworld.regions.region_cache[1] + regions_to_explore = deque([regions_by_name["Menu"]]) + + while regions_to_explore: + region = regions_to_explore.pop() + + if region.name in explored_regions: + continue + + explored_regions.add(region.name) + + for exit_ in region.exits: + exit_: Entrance + if exit_.name in blocked_entrances: + continue + regions_to_explore.append(exit_.connected_region) + + return explored_regions diff --git a/worlds/stardew_valley/test/regions/TestRandomizationFlag.py b/worlds/stardew_valley/test/regions/TestRandomizationFlag.py new file mode 100644 index 000000000000..6a01ef07e96d --- /dev/null +++ b/worlds/stardew_valley/test/regions/TestRandomizationFlag.py @@ -0,0 +1,88 @@ +import unittest + +from ..options.utils import fill_dataclass_with_default +from ... import create_content, options +from ...regions.entrance_rando import create_player_randomization_flag +from ...regions.model import RandomizationFlag, ConnectionData + + +class TestConnectionData(unittest.TestCase): + + def test_given_entrances_not_randomized_when_is_eligible_for_randomization_then_not_eligible(self): + player_flag = RandomizationFlag.NOT_RANDOMIZED + + connection = ConnectionData("Go to Somewhere", "Somewhere", RandomizationFlag.PELICAN_TOWN) + is_eligible = connection.is_eligible_for_randomization(player_flag) + + self.assertFalse(is_eligible) + + def test_given_pelican_town_connection_when_is_eligible_for_pelican_town_randomization_then_eligible(self): + player_flag = RandomizationFlag.BIT_PELICAN_TOWN + connection = ConnectionData("Go to Somewhere", "Somewhere", RandomizationFlag.PELICAN_TOWN) + + is_eligible = connection.is_eligible_for_randomization(player_flag) + + self.assertTrue(is_eligible) + + def test_given_pelican_town_connection_when_is_eligible_for_buildings_randomization_then_eligible(self): + player_flag = RandomizationFlag.BIT_BUILDINGS + connection = ConnectionData("Go to Somewhere", "Somewhere", RandomizationFlag.PELICAN_TOWN) + + is_eligible = connection.is_eligible_for_randomization(player_flag) + + self.assertTrue(is_eligible) + + def test_given_non_progression_connection_when_is_eligible_for_pelican_town_randomization_then_not_eligible(self): + player_flag = RandomizationFlag.BIT_PELICAN_TOWN + connection = ConnectionData("Go to Somewhere", "Somewhere", RandomizationFlag.NON_PROGRESSION) + + is_eligible = connection.is_eligible_for_randomization(player_flag) + + self.assertFalse(is_eligible) + + def test_given_non_progression_masteries_connection_when_is_eligible_for_non_progression_randomization_then_eligible(self): + player_flag = RandomizationFlag.BIT_NON_PROGRESSION + connection = ConnectionData("Go to Somewhere", "Somewhere", RandomizationFlag.NON_PROGRESSION ^ RandomizationFlag.EXCLUDE_MASTERIES) + + is_eligible = connection.is_eligible_for_randomization(player_flag) + + self.assertTrue(is_eligible) + + def test_given_non_progression_masteries_connection_when_is_eligible_for_non_progression_without_masteries_randomization_then_not_eligible(self): + player_flag = RandomizationFlag.BIT_NON_PROGRESSION | RandomizationFlag.EXCLUDE_MASTERIES + connection = ConnectionData("Go to Somewhere", "Somewhere", RandomizationFlag.NON_PROGRESSION ^ RandomizationFlag.EXCLUDE_MASTERIES) + + is_eligible = connection.is_eligible_for_randomization(player_flag) + + self.assertFalse(is_eligible) + + +class TestRandomizationFlag(unittest.TestCase): + + def test_given_entrance_randomization_choice_when_create_player_randomization_flag_then_only_relevant_bit_is_enabled(self): + for entrance_randomization_choice, expected_bit in ( + (options.EntranceRandomization.option_disabled, RandomizationFlag.NOT_RANDOMIZED), + (options.EntranceRandomization.option_pelican_town, RandomizationFlag.BIT_PELICAN_TOWN), + (options.EntranceRandomization.option_non_progression, RandomizationFlag.BIT_NON_PROGRESSION), + (options.EntranceRandomization.option_buildings_without_house, RandomizationFlag.BIT_BUILDINGS), + (options.EntranceRandomization.option_buildings, RandomizationFlag.BIT_BUILDINGS), + (options.EntranceRandomization.option_chaos, RandomizationFlag.BIT_BUILDINGS), + ): + player_options = fill_dataclass_with_default({options.EntranceRandomization: entrance_randomization_choice}) + content = create_content(player_options) + + flag = create_player_randomization_flag(player_options.entrance_randomization, content) + + self.assertEqual(flag, expected_bit) + + def test_given_masteries_not_randomized_when_create_player_randomization_flag_then_exclude_masteries_bit_enabled(self): + for entrance_randomization_choice in set(options.EntranceRandomization.options.values()) ^ {options.EntranceRandomization.option_disabled}: + player_options = fill_dataclass_with_default({ + options.EntranceRandomization: entrance_randomization_choice, + options.SkillProgression: options.SkillProgression.option_progressive + }) + content = create_content(player_options) + + flag = create_player_randomization_flag(player_options.entrance_randomization, content) + + self.assertIn(RandomizationFlag.EXCLUDE_MASTERIES, flag) diff --git a/worlds/stardew_valley/test/regions/TestRegionConnections.py b/worlds/stardew_valley/test/regions/TestRegionConnections.py new file mode 100644 index 000000000000..42a2e36124aa --- /dev/null +++ b/worlds/stardew_valley/test/regions/TestRegionConnections.py @@ -0,0 +1,66 @@ +import unittest + +from ..options.utils import fill_dataclass_with_default +from ... import options +from ...content import create_content +from ...mods.region_data import region_data_by_content_pack +from ...regions import vanilla_data +from ...regions.model import MergeFlag +from ...regions.regions import create_all_regions, create_all_connections + + +class TestVanillaRegionsConnectionsWithGingerIsland(unittest.TestCase): + def test_region_exits_lead_somewhere(self): + for region in vanilla_data.regions_with_ginger_island_by_name.values(): + with self.subTest(region=region): + for exit_ in region.exits: + self.assertIn(exit_, vanilla_data.connections_with_ginger_island_by_name, + f"{region.name} is leading to {exit_} but it does not exist.") + + def test_connection_lead_somewhere(self): + for connection in vanilla_data.connections_with_ginger_island_by_name.values(): + with self.subTest(connection=connection): + self.assertIn(connection.destination, vanilla_data.regions_with_ginger_island_by_name, + f"{connection.name} is leading to {connection.destination} but it does not exist.") + + +class TestVanillaRegionsConnectionsWithoutGingerIsland(unittest.TestCase): + def test_region_exits_lead_somewhere(self): + for region in vanilla_data.regions_without_ginger_island_by_name.values(): + with self.subTest(region=region): + for exit_ in region.exits: + self.assertIn(exit_, vanilla_data.connections_without_ginger_island_by_name, + f"{region.name} is leading to {exit_} but it does not exist.") + + def test_connection_lead_somewhere(self): + for connection in vanilla_data.connections_without_ginger_island_by_name.values(): + with self.subTest(connection=connection): + self.assertIn(connection.destination, vanilla_data.regions_without_ginger_island_by_name, + f"{connection.name} is leading to {connection.destination} but it does not exist.") + + +class TestModsConnections(unittest.TestCase): + options = { + options.ExcludeGingerIsland: options.ExcludeGingerIsland.option_false, + options.Mods: frozenset(options.Mods.valid_keys) + } + content = create_content(fill_dataclass_with_default(options)) + all_regions_by_name = create_all_regions(content.registered_packs) + all_connections_by_name = create_all_connections(content.registered_packs) + + def test_region_exits_lead_somewhere(self): + for mod_region_data in region_data_by_content_pack.values(): + for region in mod_region_data.regions: + if MergeFlag.REMOVE_EXITS in region.flag: + continue + + with self.subTest(mod=mod_region_data.mod_name, region=region.name): + for exit_ in region.exits: + self.assertIn(exit_, self.all_connections_by_name, f"{region.name} is leading to {exit_} but it does not exist.") + + def test_connection_lead_somewhere(self): + for mod_region_data in region_data_by_content_pack.values(): + for connection in mod_region_data.connections: + with self.subTest(mod=mod_region_data.mod_name, connection=connection.name): + self.assertIn(connection.destination, self.all_regions_by_name, + f"{connection.name} is leading to {connection.destination} but it does not exist.") diff --git a/worlds/stardew_valley/test/regions/__init__.py b/worlds/stardew_valley/test/regions/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 From 47a0dd696f9dd292788be284012e920c1b35067d Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Sat, 24 May 2025 01:28:25 -0400 Subject: [PATCH 0471/1218] Stardew Valley: Added moss to statue of blessings recipe (#5038) --- worlds/stardew_valley/data/craftable_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/stardew_valley/data/craftable_data.py b/worlds/stardew_valley/data/craftable_data.py index de371b7c3a9b..66466d89b189 100644 --- a/worlds/stardew_valley/data/craftable_data.py +++ b/worlds/stardew_valley/data/craftable_data.py @@ -305,7 +305,7 @@ def create_recipe(name: str, ingredients: Dict[str, int], source: RecipeSource, cookout_kit = skill_recipe(Craftable.cookout_kit, Skill.foraging, 3, {Material.wood: 15, Material.fiber: 10, Material.coal: 3}) tent_kit = skill_recipe(Craftable.tent_kit, Skill.foraging, 8, {Material.hardwood: 10, Material.fiber: 25, ArtisanGood.cloth: 1}) -statue_of_blessings = mastery_recipe(Statue.blessings, Skill.farming, {Material.sap: 999, Material.fiber: 999, Material.stone: 999}) +statue_of_blessings = mastery_recipe(Statue.blessings, Skill.farming, {Material.sap: 999, Material.fiber: 999, Material.stone: 999, Material.moss: 333}) statue_of_dwarf_king = mastery_recipe(Statue.dwarf_king, Skill.mining, {MetalBar.iridium: 20}) heavy_furnace = mastery_recipe(Machine.heavy_furnace, Skill.mining, {Machine.furnace: 2, MetalBar.iron: 3, Material.stone: 50}) mystic_tree_seed = mastery_recipe(TreeSeed.mystic, Skill.foraging, {TreeSeed.acorn: 5, TreeSeed.maple: 5, TreeSeed.pine: 5, TreeSeed.mahogany: 5}) From 704cd97f211a44b3a792f11a906f523da8554627 Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Fri, 23 May 2025 22:33:01 -0700 Subject: [PATCH 0472/1218] BizHawkClient: Fix script to list all cores instead of explicit mapping (#5033) --- data/lua/connector_bizhawk_generic.lua | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/data/lua/connector_bizhawk_generic.lua b/data/lua/connector_bizhawk_generic.lua index c2e8f91c0d97..387ca2c6f3b4 100644 --- a/data/lua/connector_bizhawk_generic.lua +++ b/data/lua/connector_bizhawk_generic.lua @@ -365,18 +365,14 @@ request_handlers = { ["PREFERRED_CORES"] = function (req) local res = {} local preferred_cores = client.getconfig().PreferredCores + local systems_enumerator = preferred_cores.Keys:GetEnumerator() res["type"] = "PREFERRED_CORES_RESPONSE" res["value"] = {} - res["value"]["NES"] = preferred_cores.NES - res["value"]["SNES"] = preferred_cores.SNES - res["value"]["GB"] = preferred_cores.GB - res["value"]["GBC"] = preferred_cores.GBC - res["value"]["DGB"] = preferred_cores.DGB - res["value"]["SGB"] = preferred_cores.SGB - res["value"]["PCE"] = preferred_cores.PCE - res["value"]["PCECD"] = preferred_cores.PCECD - res["value"]["SGX"] = preferred_cores.SGX + + while systems_enumerator:MoveNext() do + res["value"][systems_enumerator.Current] = preferred_cores[systems_enumerator.Current] + end return res end, From e830a6d6f56a5c97603c86599dbd9726aeaaf51b Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Sat, 24 May 2025 09:17:54 -0400 Subject: [PATCH 0473/1218] TWW: Only add Filler for Excluded Locations Which are Progress Locations (#4993) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/tww/randomizers/ItemPool.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/tww/randomizers/ItemPool.py b/worlds/tww/randomizers/ItemPool.py index 86c02f393212..679d1939dffe 100644 --- a/worlds/tww/randomizers/ItemPool.py +++ b/worlds/tww/randomizers/ItemPool.py @@ -117,7 +117,8 @@ def get_pool_core(world: "TWWWorld") -> tuple[list[str], list[str]]: world.filler_pool = filler_pool # Add filler items to place into excluded locations. - pool.extend([world.get_filler_item_name() for _ in world.options.exclude_locations]) + excluded_locations = world.progress_locations.intersection(world.options.exclude_locations) + pool.extend([world.get_filler_item_name() for _ in excluded_locations]) # The remaining of items left to place should be the same as the number of non-excluded locations in the world. nonexcluded_locations = [ From 4119763e23f948ccf9f2d2c7658456d33b953eb4 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sat, 24 May 2025 09:35:06 -0400 Subject: [PATCH 0474/1218] Lingo: Fix The Bearer's Pilgrimage Logic (#5005) --- worlds/lingo/data/LL1.yaml | 94 +++++++++++++++-------- worlds/lingo/data/generated.dat | Bin 149504 -> 149835 bytes worlds/lingo/data/ids.yaml | 8 +- worlds/lingo/datatypes.py | 1 + worlds/lingo/regions.py | 9 ++- worlds/lingo/utils/pickle_static_data.py | 2 + worlds/lingo/utils/validate_config.rb | 2 +- 7 files changed, 75 insertions(+), 41 deletions(-) diff --git a/worlds/lingo/data/LL1.yaml b/worlds/lingo/data/LL1.yaml index 6410ffea3bd4..4c41f3236f62 100644 --- a/worlds/lingo/data/LL1.yaml +++ b/worlds/lingo/data/LL1.yaml @@ -4956,10 +4956,16 @@ Outside The Initiated: room: Art Gallery door: Exit - The Bearer (East): True - The Bearer (North): True - The Bearer (South): True - The Bearer (West): True + The Bearer (East): + static_painting: True + The Bearer (North): + static_painting: True + The Bearer (South): + static_painting: True + The Bearer (West): + - static_painting: True + - room: The Bearer (West) + door: Side Area Shortcut Roof: True panels: Achievement: @@ -5053,7 +5059,8 @@ - MIDDLE The Bearer (East): entrances: - Cross Tower (East): True + Cross Tower (East): + static_painting: True Bearer Side Area: door: Side Area Access Roof: True @@ -5084,7 +5091,8 @@ panel: SPACE The Bearer (North): entrances: - Cross Tower (East): True + Cross Tower (North): + static_painting: True Roof: True panels: SILENT (1): @@ -5128,7 +5136,8 @@ panel: POTS The Bearer (South): entrances: - Cross Tower (North): True + Cross Tower (South): + static_painting: True Bearer Side Area: door: Side Area Shortcut Roof: True @@ -5162,7 +5171,10 @@ panel: SILENT (1) The Bearer (West): entrances: - Cross Tower (West): True + Cross Tower (West): + static_painting: True + The Bearer: + door: Side Area Shortcut Bearer Side Area: door: Side Area Shortcut Roof: True @@ -5235,6 +5247,7 @@ The Bearer: room: The Bearer door: East Entrance + static_painting: True Roof: True panels: WINTER: @@ -5250,6 +5263,7 @@ The Bearer (East): room: The Bearer (East) door: North Entrance + static_painting: True Roof: True panels: NORTH: @@ -5270,6 +5284,7 @@ The Bearer (North): room: The Bearer (North) door: South Entrance + static_painting: True panels: FIRE: id: Cross Room/Panel_fire_fire @@ -5284,6 +5299,7 @@ Bearer Side Area: room: Bearer Side Area door: West Entrance + static_painting: True Roof: True panels: DIAMONDS: @@ -7108,6 +7124,8 @@ entrances: Orange Tower Third Floor: warp: True + Art Gallery (First Floor): + warp: True Art Gallery (Second Floor): warp: True Art Gallery (Third Floor): @@ -7125,22 +7143,6 @@ required_door: room: Number Hunt door: Eights - EON: - id: Painting Room/Panel_eon_one - colors: yellow - tag: midyellow - TRUSTWORTHY: - id: Painting Room/Panel_to_two - colors: red - tag: midred - FREE: - id: Painting Room/Panel_free_three - colors: purple - tag: midpurp - OUR: - id: Painting Room/Panel_our_four - colors: blue - tag: midblue ORDER: id: Painting Room/Panel_order_onepathmanyturns tag: forbid @@ -7159,15 +7161,8 @@ - scenery_painting_2c skip_location: True panels: - - EON - First Floor Puzzles: - skip_item: True - location_name: Art Gallery - First Floor Puzzles - panels: - - EON - - TRUSTWORTHY - - FREE - - OUR + - room: Art Gallery (First Floor) + panel: EON Third Floor: painting_id: - scenery_painting_3b @@ -7227,11 +7222,42 @@ - Third Floor - Fourth Floor - Fifth Floor + Art Gallery (First Floor): + entrances: + Art Gallery: + static_painting: True + panels: + EON: + id: Painting Room/Panel_eon_one + colors: yellow + tag: midyellow + TRUSTWORTHY: + id: Painting Room/Panel_to_two + colors: red + tag: midred + FREE: + id: Painting Room/Panel_free_three + colors: purple + tag: midpurp + OUR: + id: Painting Room/Panel_our_four + colors: blue + tag: midblue + doors: + Puzzles: + skip_item: True + location_name: Art Gallery - First Floor Puzzles + panels: + - EON + - TRUSTWORTHY + - FREE + - OUR Art Gallery (Second Floor): entrances: Art Gallery: room: Art Gallery door: Second Floor + static_painting: True panels: HOUSE: id: Painting Room/Panel_house_neighborhood @@ -7263,6 +7289,7 @@ Art Gallery: room: Art Gallery door: Third Floor + static_painting: True panels: AN: id: Painting Room/Panel_an_many @@ -7294,6 +7321,7 @@ Art Gallery: room: Art Gallery door: Fourth Floor + static_painting: True panels: URNS: id: Painting Room/Panel_urns_turns diff --git a/worlds/lingo/data/generated.dat b/worlds/lingo/data/generated.dat index 14f5570db1d17d881dcefbed05323ac89b10a701..f5eb3e069927f30aa069594bd3a98e6caa17e001 100644 GIT binary patch delta 31001 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 delta 30985 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 None: regions[pilgrimage_region_name] = Region(pilgrimage_region_name, world.player, world.multiworld) # Connect all created regions now that they exist. - allowed_entrance_types = EntranceType.NORMAL | EntranceType.WARP | EntranceType.CROSSROADS_ROOF_ACCESS + allowed_entrance_types = EntranceType.NORMAL | EntranceType.WARP | EntranceType.CROSSROADS_ROOF_ACCESS | \ + EntranceType.STATIC_PAINTING if not painting_shuffle: # Don't use the vanilla painting connections if we are shuffling paintings. @@ -156,11 +157,11 @@ def create_regions(world: "LingoWorld") -> None: regions[from_room].connect(regions[to_room], f"Pilgrimage Part {i+1}") else: connect_entrance(regions, regions["Starting Room"], regions["Pilgrim Antechamber"], "Sun Painting", - RoomAndDoor("Pilgrim Antechamber", "Sun Painting"), EntranceType.PAINTING, False, world) + RoomAndDoor("Pilgrim Antechamber", "Sun Painting"), EntranceType.STATIC_PAINTING, False, world) if early_color_hallways: connect_entrance(regions, regions["Starting Room"], regions["Color Hallways"], "Early Color Hallways", - None, EntranceType.PAINTING, False, world) + None, EntranceType.STATIC_PAINTING, False, world) if painting_shuffle: for warp_enter, warp_exit in world.player_logic.painting_mapping.items(): diff --git a/worlds/lingo/utils/pickle_static_data.py b/worlds/lingo/utils/pickle_static_data.py index 740e129bcb6c..7f39b798367e 100644 --- a/worlds/lingo/utils/pickle_static_data.py +++ b/worlds/lingo/utils/pickle_static_data.py @@ -138,6 +138,8 @@ def process_single_entrance(source_room: str, room_name: str, door_obj) -> RoomE entrance_type = EntranceType.WARP elif source_room == "Crossroads" and room_name == "Roof": entrance_type = EntranceType.CROSSROADS_ROOF_ACCESS + elif "static_painting" in door_obj and door_obj["static_painting"]: + entrance_type = EntranceType.STATIC_PAINTING if "painting" in door_obj and door_obj["painting"]: PAINTING_EXIT_ROOMS.add(room_name) diff --git a/worlds/lingo/utils/validate_config.rb b/worlds/lingo/utils/validate_config.rb index 2a765fbcad00..e2704226849f 100644 --- a/worlds/lingo/utils/validate_config.rb +++ b/worlds/lingo/utils/validate_config.rb @@ -2,7 +2,7 @@ # the file are consistent. It also checks that the panel and door IDs mentioned # all exist in the map file. # -# Usage: validate_config.rb [config file] [map file] +# Usage: validate_config.rb [config file] [ids path] [map file] require 'set' require 'yaml' From eba757d2cd468182f4d0500ab87c45d379b225d2 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 24 May 2025 23:02:27 +0200 Subject: [PATCH 0475/1218] Raft: Implement get_filler_item_name and refactor filler item code a bit (#4782) * refactor filler item creation for Raft, implement get_filler_item_name * wrong indent * Update worlds/raft/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/raft/__init__.py | 112 +++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 47 deletions(-) diff --git a/worlds/raft/__init__.py b/worlds/raft/__init__.py index 3e33b417c04b..74ab9291b26e 100644 --- a/worlds/raft/__init__.py +++ b/worlds/raft/__init__.py @@ -40,6 +40,8 @@ class RaftWorld(World): options_dataclass = RaftOptions options: RaftOptions + extraItemNamePool: list[str] | None = None + required_client_version = (0, 3, 4) def create_items(self): @@ -52,52 +54,52 @@ def create_items(self): pool = [] frequencyItems = [] for item in item_table: - raft_item = self.create_item_replaceAsNecessary(item["name"]) + raft_item = self.create_item(self.replace_item_name_as_necessary(item["name"])) if isFillingFrequencies and "Frequency" in item["name"]: frequencyItems.append(raft_item) else: pool.append(raft_item) - extraItemNamePool = [] + self.extraItemNamePool = [] extras = len(location_table) - len(item_table) - 1 # Victory takes up 1 unaccounted-for slot - if extras > 0: - if (self.options.filler_item_types != self.options.filler_item_types.option_duplicates): # Use resource packs - for packItem in resourcePackItems: - for i in range(minimumResourcePackAmount, maximumResourcePackAmount + 1): - extraItemNamePool.append(createResourcePackName(i, packItem)) - - if self.options.filler_item_types != self.options.filler_item_types.option_resource_packs: # Use duplicate items - dupeItemPool = item_table.copy() - # Remove frequencies if necessary - if self.options.island_frequency_locations != self.options.island_frequency_locations.option_anywhere: # Not completely random locations - # If we let frequencies stay in with progressive-frequencies, the progressive-frequency item - # will be included 7 times. This is a massive flood of progressive-frequency items, so we - # instead add progressive-frequency as its own item a smaller amount of times to prevent - # flooding the duplicate item pool with them. - if self.options.island_frequency_locations == self.options.island_frequency_locations.option_progressive: - for _ in range(2): - # Progressives are not in item_pool, need to create faux item for duplicate item pool - # This can still be filtered out later by duplicate_items setting - dupeItemPool.append({ "name": "progressive-frequency", "progression": True }) # Progressive frequencies need to be included - # Always remove non-progressive Frequency items - dupeItemPool = (itm for itm in dupeItemPool if "Frequency" not in itm["name"]) - - # Remove progression or non-progression items if necessary - if (self.options.duplicate_items == self.options.duplicate_items.option_progression): # Progression only - dupeItemPool = (itm for itm in dupeItemPool if itm["progression"] == True) - elif (self.options.duplicate_items == self.options.duplicate_items.option_non_progression): # Non-progression only - dupeItemPool = (itm for itm in dupeItemPool if itm["progression"] == False) - - dupeItemPool = list(dupeItemPool) - # Finally, add items as necessary - if len(dupeItemPool) > 0: - for item in dupeItemPool: - extraItemNamePool.append(item["name"]) + + if (self.options.filler_item_types != self.options.filler_item_types.option_duplicates): # Use resource packs + for packItem in resourcePackItems: + for i in range(minimumResourcePackAmount, maximumResourcePackAmount + 1): + self.extraItemNamePool.append(createResourcePackName(i, packItem)) + + if self.options.filler_item_types != self.options.filler_item_types.option_resource_packs: # Use duplicate items + dupeItemPool = item_table.copy() + # Remove frequencies if necessary + if self.options.island_frequency_locations != self.options.island_frequency_locations.option_anywhere: # Not completely random locations + # If we let frequencies stay in with progressive-frequencies, the progressive-frequency item + # will be included 7 times. This is a massive flood of progressive-frequency items, so we + # instead add progressive-frequency as its own item a smaller amount of times to prevent + # flooding the duplicate item pool with them. + if self.options.island_frequency_locations == self.options.island_frequency_locations.option_progressive: + for _ in range(2): + # Progressives are not in item_pool, need to create faux item for duplicate item pool + # This can still be filtered out later by duplicate_items setting + dupeItemPool.append({ "name": "progressive-frequency", "progression": True }) # Progressive frequencies need to be included + # Always remove non-progressive Frequency items + dupeItemPool = (itm for itm in dupeItemPool if "Frequency" not in itm["name"]) + + # Remove progression or non-progression items if necessary + if (self.options.duplicate_items == self.options.duplicate_items.option_progression): # Progression only + dupeItemPool = (itm for itm in dupeItemPool if itm["progression"] == True) + elif (self.options.duplicate_items == self.options.duplicate_items.option_non_progression): # Non-progression only + dupeItemPool = (itm for itm in dupeItemPool if itm["progression"] == False) + + dupeItemPool = list(dupeItemPool) + # Finally, add items as necessary + for item in dupeItemPool: + self.extraItemNamePool.append(self.replace_item_name_as_necessary(item)) - if (len(extraItemNamePool) > 0): - for randomItem in self.random.choices(extraItemNamePool, k=extras): - raft_item = self.create_item_replaceAsNecessary(randomItem) - pool.append(raft_item) + assert self.extraItemNamePool, f"Don't know what extra items to create for {self.player_name}." + + for randomItem in self.random.choices(self.extraItemNamePool, k=extras): + raft_item = self.create_item(randomItem) + pool.append(raft_item) self.multiworld.itempool += pool @@ -108,19 +110,35 @@ def create_items(self): if frequencyItems: self.place_frequencyItems(frequencyItems) + def get_filler_item_name(self) -> str: + # A normal Raft world will have an extraItemNamePool defined after create_items. + if self.extraItemNamePool: + return self.random.choice(self.extraItemNamePool) + + # If this is a "fake" world, e.g. item links with link replacement: Resource packs are always be safe to create + minRPSpecified = self.options.minimum_resource_pack_amount.value + maxRPSpecified = self.options.maximum_resource_pack_amount.value + minimumResourcePackAmount = min(minRPSpecified, maxRPSpecified) + maximumResourcePackAmount = max(minRPSpecified, maxRPSpecified) + resource_amount = self.random.randint(minimumResourcePackAmount, maximumResourcePackAmount) + resource_type = self.random.choice(resourcePackItems) + return createResourcePackName(resource_amount, resource_type) + def set_rules(self): set_rules(self.multiworld, self.player) def create_regions(self): create_regions(self.multiworld, self.player) - - def create_item_replaceAsNecessary(self, name: str) -> Item: - isFrequency = "Frequency" in name - shouldUseProgressive = bool((isFrequency and self.options.island_frequency_locations == self.options.island_frequency_locations.option_progressive) - or (not isFrequency and self.options.progressive_items)) - if shouldUseProgressive and name in progressive_table: - name = progressive_table[name] - return self.create_item(name) + + def replace_item_name_as_necessary(self, name: str) -> str: + if name not in progressive_table: + return name + if "Frequency" in name: + if self.options.island_frequency_locations == self.options.island_frequency_locations.option_progressive: + return progressive_table[name] + elif self.options.progressive_items: + return progressive_table[name] + return name def create_item(self, name: str) -> Item: item = lookup_name_to_item[name] From e7545cbc28d41e781a996a9fbe28dcf4c683174c Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Sat, 24 May 2025 17:59:55 -0400 Subject: [PATCH 0476/1218] SDV: Fixed Region for two Parrot Locations (#5042) --- worlds/stardew_valley/data/locations.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/stardew_valley/data/locations.csv b/worlds/stardew_valley/data/locations.csv index 66a9157b3437..2829a1252240 100644 --- a/worlds/stardew_valley/data/locations.csv +++ b/worlds/stardew_valley/data/locations.csv @@ -1129,8 +1129,8 @@ id,region,name,tags,mod_name 2204,Leo's Hut,Leo's Parrot,"GINGER_ISLAND,WALNUT_PURCHASE", 2205,Island South,Island West Turtle,"GINGER_ISLAND,WALNUT_PURCHASE", 2206,Island West,Island Farmhouse,"GINGER_ISLAND,WALNUT_PURCHASE", -2207,Island Farmhouse,Island Mailbox,"GINGER_ISLAND,WALNUT_PURCHASE", -2208,Island Farmhouse,Farm Obelisk,"GINGER_ISLAND,WALNUT_PURCHASE", +2207,Island West,Island Mailbox,"GINGER_ISLAND,WALNUT_PURCHASE", +2208,Island West,Farm Obelisk,"GINGER_ISLAND,WALNUT_PURCHASE", 2209,Island North,Dig Site Bridge,"GINGER_ISLAND,WALNUT_PURCHASE", 2210,Island North,Island Trader,"GINGER_ISLAND,WALNUT_PURCHASE", 2211,Volcano Entrance,Volcano Bridge,"GINGER_ISLAND,WALNUT_PURCHASE", From f327ab30a653acdd56376f53ee54577c9e0e06ed Mon Sep 17 00:00:00 2001 From: LiquidCat64 <74896918+LiquidCat64@users.noreply.github.com> Date: Sun, 25 May 2025 03:20:25 -0600 Subject: [PATCH 0477/1218] CV64: Allow Holding Z to Use the Regular Shimmy Speed (#4730) * Add the shimmy modifier hack. * Update the Increase Shimmy Speed option description. --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/cv64/data/patches.py | 15 +++++++++++++++ worlds/cv64/options.py | 1 + worlds/cv64/rom.py | 5 +++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/worlds/cv64/data/patches.py b/worlds/cv64/data/patches.py index 6ef4eafb67d3..4a964612f03e 100644 --- a/worlds/cv64/data/patches.py +++ b/worlds/cv64/data/patches.py @@ -2893,3 +2893,18 @@ 0x25291CB8, # ADDIU T1, T1, 0x1CB8 0x01200008 # JR T1 ] + +shimmy_speed_modifier = [ + # Increases the player's speed while shimmying as long as they are not holding down Z. If they are holding Z, it + # will be the normal speed, allowing it to still be used to set up any tricks that might require the normal speed + # (like Left Tower Skip). + 0x3C088038, # LUI T0, 0x8038 + 0x91087D7E, # LBU T0, 0x7D7E (T0) + 0x31090020, # ANDI T1, T0, 0x0020 + 0x3C0A800A, # LUI T2, 0x800A + 0x240B005A, # ADDIU T3, R0, 0x005A + 0x55200001, # BNEZL T1, [forward 0x01] + 0x240B0032, # ADDIU T3, R0, 0x0032 + 0xA14B3641, # SB T3, 0x3641 (T2) + 0x0800B7C3 # J 0x8002DF0C +] diff --git a/worlds/cv64/options.py b/worlds/cv64/options.py index 07e86347bda6..da1e1aba9440 100644 --- a/worlds/cv64/options.py +++ b/worlds/cv64/options.py @@ -424,6 +424,7 @@ class PantherDash(Choice): class IncreaseShimmySpeed(Toggle): """ Increases the speed at which characters shimmy left and right while hanging on ledges. + Hold Z to use the regular speed in case it's needed to do something. """ display_name = "Increase Shimmy Speed" diff --git a/worlds/cv64/rom.py b/worlds/cv64/rom.py index 1833c7812bc3..830bed27796e 100644 --- a/worlds/cv64/rom.py +++ b/worlds/cv64/rom.py @@ -607,9 +607,10 @@ def apply_patches(caller: APProcedurePatch, rom: bytes, options_file: str) -> by rom_data.write_int32(0xAA530, 0x080FF880) # J 0x803FE200 rom_data.write_int32s(0xBFE200, patches.coffin_cutscene_skipper) - # Increase shimmy speed + # Shimmy speed increase hack if options["increase_shimmy_speed"]: - rom_data.write_byte(0xA4241, 0x5A) + rom_data.write_int32(0x97EB4, 0x803FE9F0) + rom_data.write_int32s(0xBFE9F0, patches.shimmy_speed_modifier) # Disable landing fall damage if options["fall_guard"]: From 32487137e81d23139820aa2a6d3fd86d6ac104f5 Mon Sep 17 00:00:00 2001 From: FlitPix <8645405+FlitPix@users.noreply.github.com> Date: Sun, 25 May 2025 17:17:30 -0400 Subject: [PATCH 0478/1218] Core: Add descriptions to Components (#4849) * Add descriptions to components * Adhere to style guide * Tweak BHC wording * Trim Open Patch description * Update text client description for consistency Co-authored-by: Scipio Wright * Remove newlines --------- Co-authored-by: Scipio Wright --- Launcher.py | 21 ++++++++++++++------- worlds/LauncherComponents.py | 12 ++++++++---- worlds/_bizhawk/client.py | 3 ++- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Launcher.py b/Launcher.py index e9751f2c2350..88e2070e9c4c 100644 --- a/Launcher.py +++ b/Launcher.py @@ -104,14 +104,21 @@ def update_settings(): components.extend([ # Functions - Component("Open host.yaml", func=open_host_yaml), - Component("Open Patch", func=open_patch), - Component("Generate Template Options", func=generate_yamls), - Component("Archipelago Website", func=lambda: webbrowser.open("https://archipelago.gg/")), - Component("Discord Server", icon="discord", func=lambda: webbrowser.open("https://discord.gg/8Z65BR2")), + Component("Open host.yaml", func=open_host_yaml, + description="Open the host.yaml file to change settings for generation, games, and more."), + Component("Open Patch", func=open_patch, + description="Open a patch file, downloaded from the room page or provided by the host."), + Component("Generate Template Options", func=generate_yamls, + description="Generate template YAMLs for currently installed games."), + Component("Archipelago Website", func=lambda: webbrowser.open("https://archipelago.gg/"), + description="Open archipelago.gg in your browser."), + Component("Discord Server", icon="discord", func=lambda: webbrowser.open("https://discord.gg/8Z65BR2"), + description="Join the Discord server to play public multiworlds, report issues, or just chat!"), Component("Unrated/18+ Discord Server", icon="discord", - func=lambda: webbrowser.open("https://discord.gg/fqvNCCRsu4")), - Component("Browse Files", func=browse_files), + func=lambda: webbrowser.open("https://discord.gg/fqvNCCRsu4"), + description="Find unrated and 18+ games in the After Dark Discord server."), + Component("Browse Files", func=browse_files, + description="Open the Archipelago installation folder in your file browser."), ]) diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index 2bd96369313e..e650889a7377 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -210,10 +210,14 @@ def install_apworld(apworld_path: str = "") -> None: Component('Launcher', 'Launcher', component_type=Type.HIDDEN), # Core Component('Host', 'MultiServer', 'ArchipelagoServer', cli=True, - file_identifier=SuffixIdentifier('.archipelago', '.zip')), - Component('Generate', 'Generate', cli=True), - Component("Install APWorld", func=install_apworld, file_identifier=SuffixIdentifier(".apworld")), - Component('Text Client', 'CommonClient', 'ArchipelagoTextClient', func=launch_textclient), + file_identifier=SuffixIdentifier('.archipelago', '.zip'), + description="Host a generated multiworld on your computer."), + Component('Generate', 'Generate', cli=True, + description="Generate a multiworld with the YAMLs in the players folder."), + Component("Install APWorld", func=install_apworld, file_identifier=SuffixIdentifier(".apworld"), + description="Install an APWorld to play games not included with Archipelago by default."), + Component('Text Client', 'CommonClient', 'ArchipelagoTextClient', func=launch_textclient, + description="Connect to a multiworld using the text client."), Component('Links Awakening DX Client', 'LinksAwakeningClient', file_identifier=SuffixIdentifier('.apladx')), Component('LttP Adjuster', 'LttPAdjuster'), diff --git a/worlds/_bizhawk/client.py b/worlds/_bizhawk/client.py index 16a8325a10f7..fe8e97e65cda 100644 --- a/worlds/_bizhawk/client.py +++ b/worlds/_bizhawk/client.py @@ -19,7 +19,8 @@ def launch_client(*args) -> None: component = Component("BizHawk Client", "BizHawkClient", component_type=Type.CLIENT, func=launch_client, - file_identifier=SuffixIdentifier()) + file_identifier=SuffixIdentifier(), + description="Open the BizHawk client, to play games using the Bizhawk emulator.") components.append(component) From 002202ff5fa9ced9fd100fc394f22323cc5efe73 Mon Sep 17 00:00:00 2001 From: ScootyPuffJr1 <77215594+ScootyPuffJr1@users.noreply.github.com> Date: Mon, 26 May 2025 03:25:39 -0400 Subject: [PATCH 0479/1218] Update OOT Guides (#5041) * Update OOT Guides * Minor update per review --- worlds/oot/docs/setup_de.md | 4 ++-- worlds/oot/docs/setup_en.md | 4 ++-- worlds/oot/docs/setup_fr.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/worlds/oot/docs/setup_de.md b/worlds/oot/docs/setup_de.md index 92c3150a7d2f..c35dd2769f1a 100644 --- a/worlds/oot/docs/setup_de.md +++ b/worlds/oot/docs/setup_de.md @@ -7,13 +7,13 @@ Da wir BizHawk benutzen, gilt diese Anleitung nur für Windows und Linux. ## Benötigte Software - BizHawk: [BizHawk Veröffentlichungen von TASVideos](https://tasvideos.org/BizHawk/ReleaseHistory) - - Version 2.3.1 und später werden unterstützt. Version 2.9 ist empfohlen. + - Version 2.3.1 und später werden unterstützt. Version 2.10 ist empfohlen. - Detailierte Installtionsanweisungen für BizHawk können über den obrigen Link gefunden werden. - Windows-Benutzer müssen die Prerequisiten installiert haben. Diese können ebenfalls über den obrigen Link gefunden werden. - Der integrierte Archipelago-Client, welcher [hier](https://github.com/ArchipelagoMW/Archipelago/releases) installiert werden kann. -- Eine `Ocarina of Time v1.0 US(?) ROM`. (Nicht aus Europa und keine Master-Quest oder Debug-Rom!) +- Eine `Ocarina of Time v1.0 US ROM`. (Nicht aus Europa und keine Master-Quest oder Debug-Rom!) ## Konfigurieren von BizHawk diff --git a/worlds/oot/docs/setup_en.md b/worlds/oot/docs/setup_en.md index 553f1820c3ea..31b7137bd8b1 100644 --- a/worlds/oot/docs/setup_en.md +++ b/worlds/oot/docs/setup_en.md @@ -7,11 +7,11 @@ As we are using BizHawk, this guide is only applicable to Windows and Linux syst ## Required Software - BizHawk: [BizHawk Releases from TASVideos](https://tasvideos.org/BizHawk/ReleaseHistory) - - Version 2.3.1 and later are supported. Version 2.7 is recommended for stability. + - Version 2.3.1 and later are supported. Version 2.10 is recommended for stability. - Detailed installation instructions for BizHawk can be found at the above link. - Windows users must run the prereq installer first, which can also be found at the above link. - The built-in Archipelago client, which can be installed [here](https://github.com/ArchipelagoMW/Archipelago/releases). -- An Ocarina of Time v1.0 ROM. +- A US Ocarina of Time v1.0 ROM. ## Configuring BizHawk diff --git a/worlds/oot/docs/setup_fr.md b/worlds/oot/docs/setup_fr.md index 40b0e8f571df..eb2e97384afa 100644 --- a/worlds/oot/docs/setup_fr.md +++ b/worlds/oot/docs/setup_fr.md @@ -7,12 +7,12 @@ Comme nous utilisons BizHawk, ce guide s'applique uniquement aux systèmes Windo ## Logiciel requis - BizHawk : [Sorties BizHawk de TASVideos](https://tasvideos.org/BizHawk/ReleaseHistory) - - Les versions 2.3.1 et ultérieures sont prises en charge. La version 2.7 est recommandée pour des raisons de stabilité. + - Les versions 2.3.1 et ultérieures sont prises en charge. La version 2.10 est recommandée pour des raisons de stabilité. - Des instructions d'installation détaillées pour BizHawk peuvent être trouvées sur le lien ci-dessus. - Les utilisateurs Windows doivent d'abord exécuter le programme d'installation des prérequis, qui peut également être trouvé sur le lien ci-dessus. - Le client Archipelago intégré, qui peut être installé [ici](https://github.com/ArchipelagoMW/Archipelago/releases) (sélectionnez « Ocarina of Time Client » lors de l'installation). -- Une ROM Ocarina of Time v1.0. +- Un fichier ROM v1.0 US d'Ocarina of Time. ## Configuration de BizHawk From 20ca7e71c765899007756490669b041878cc4e55 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Tue, 27 May 2025 01:57:20 -0400 Subject: [PATCH 0480/1218] TWW: Update patch class (#5046) --- worlds/tww/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/tww/__init__.py b/worlds/tww/__init__.py index 6b6c3ca33a34..918d68478f32 100644 --- a/worlds/tww/__init__.py +++ b/worlds/tww/__init__.py @@ -11,7 +11,7 @@ from BaseClasses import MultiWorld, Region, Tutorial from Options import Toggle from worlds.AutoWorld import WebWorld, World -from worlds.Files import APContainer, AutoPatchRegister +from worlds.Files import APPlayerContainer, AutoPatchRegister from worlds.generic.Rules import add_item_rule from worlds.LauncherComponents import Component, SuffixIdentifier, Type, components, icon_paths, launch_subprocess @@ -51,7 +51,7 @@ def run_client() -> None: icon_paths["The Wind Waker"] = "ap:worlds.tww/assets/icon.png" -class TWWContainer(APContainer, metaclass=AutoPatchRegister): +class TWWContainer(APPlayerContainer, metaclass=AutoPatchRegister): """ This class defines the container file for The Wind Waker. """ From 19a21099ed11fa0fb92fa46606e62a8ac8dbdd43 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Tue, 27 May 2025 16:21:43 +0000 Subject: [PATCH 0481/1218] Webhost: update Flask to 3.1.1 (#5052) --- WebHostLib/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebHostLib/requirements.txt b/WebHostLib/requirements.txt index a9cd33dd6d4d..4e6bf25df038 100644 --- a/WebHostLib/requirements.txt +++ b/WebHostLib/requirements.txt @@ -1,4 +1,4 @@ -flask>=3.1.0 +flask>=3.1.1 werkzeug>=3.1.3 pony>=0.7.19 waitress>=3.0.2 From fcb3efee01b2bdad2d29e099e8de9e19c85e95ad Mon Sep 17 00:00:00 2001 From: LiquidCat64 <74896918+LiquidCat64@users.noreply.github.com> Date: Wed, 28 May 2025 08:47:24 -0600 Subject: [PATCH 0482/1218] CVCotM: Add Nerf Roc Wing to Slot Data and HoD Max Ups to `other_game_item_appearances` (#5051) --- worlds/cvcotm/__init__.py | 3 ++- worlds/cvcotm/aesthetics.py | 8 +++++++- worlds/cvcotm/docs/en_Castlevania - Circle of the Moon.md | 2 +- worlds/cvcotm/docs/setup_en.md | 4 ++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/worlds/cvcotm/__init__.py b/worlds/cvcotm/__init__.py index 0f5077e7098a..a2d52b3ecc41 100644 --- a/worlds/cvcotm/__init__.py +++ b/worlds/cvcotm/__init__.py @@ -211,7 +211,8 @@ def fill_slot_data(self) -> dict: "ignore_cleansing": self.options.ignore_cleansing.value, "skip_tutorials": self.options.skip_tutorials.value, "required_last_keys": self.required_last_keys, - "completion_goal": self.options.completion_goal.value} + "completion_goal": self.options.completion_goal.value, + "nerf_roc_wing": self.options.nerf_roc_wing.value} def get_filler_item_name(self) -> str: return self.random.choice(FILLER_ITEM_NAMES) diff --git a/worlds/cvcotm/aesthetics.py b/worlds/cvcotm/aesthetics.py index d1668b1db18d..d52165d076a1 100644 --- a/worlds/cvcotm/aesthetics.py +++ b/worlds/cvcotm/aesthetics.py @@ -48,11 +48,17 @@ class OtherGameAppearancesInfo(TypedDict): other_game_item_appearances: Dict[str, Dict[str, OtherGameAppearancesInfo]] = { - # NOTE: Symphony of the Night is currently an unsupported world not in main. + # NOTE: Symphony of the Night and Harmony of Dissonance are custom worlds that are not core verified. "Symphony of the Night": {"Life Vessel": {"type": 0xE4, "appearance": 0x01}, "Heart Vessel": {"type": 0xE4, "appearance": 0x00}}, + + "Castlevania - Harmony of Dissonance": {"Life Max Up": {"type": 0xE4, + "appearance": 0x01}, + "Heart Max Up": {"type": 0xE4, + "appearance": 0x00}}, + "Timespinner": {"Max HP": {"type": 0xE4, "appearance": 0x01}, "Max Aura": {"type": 0xE4, diff --git a/worlds/cvcotm/docs/en_Castlevania - Circle of the Moon.md b/worlds/cvcotm/docs/en_Castlevania - Circle of the Moon.md index 695c5f0ff9c8..611a1a376e2a 100644 --- a/worlds/cvcotm/docs/en_Castlevania - Circle of the Moon.md +++ b/worlds/cvcotm/docs/en_Castlevania - Circle of the Moon.md @@ -3,7 +3,7 @@ ## Quick Links - [Setup](/tutorial/Castlevania%20-%20Circle%20of%20the%20Moon/setup/en) - [Options Page](/games/Castlevania%20-%20Circle%20of%20the%20Moon/player-options) -- [PopTracker Pack](https://github.com/sassyvania/Circle-of-the-Moon-Rando-AP-Map-Tracker-/releases/latest) +- [PopTracker Pack](https://github.com/BowserCrusher/Circle-of-the-Moon-AP-Tracker/releases/latest) - [Repo for the original, standalone CotMR](https://github.com/calm-palm/cotm-randomizer) - [Web version of the above randomizer](https://rando.circleofthemoon.com/) - [A more in-depth guide to CotMR's nuances](https://docs.google.com/document/d/1uot4BD9XW7A--A8ecgoY8mLK_vSoQRpY5XCkzgas87c/view?usp=sharing) diff --git a/worlds/cvcotm/docs/setup_en.md b/worlds/cvcotm/docs/setup_en.md index 459e0d6afb97..4c34dcb836ef 100644 --- a/worlds/cvcotm/docs/setup_en.md +++ b/worlds/cvcotm/docs/setup_en.md @@ -22,7 +22,7 @@ clear it. ## Optional Software -- [Castlevania: Circle of the Moon AP Tracker](https://github.com/sassyvania/Circle-of-the-Moon-Rando-AP-Map-Tracker-/releases/latest), for use with +- [Castlevania: Circle of the Moon AP Tracker](https://github.com/BowserCrusher/Circle-of-the-Moon-AP-Tracker/releases/latest), for use with [PopTracker](https://github.com/black-sliver/PopTracker/releases). ## Generating and Patching a Game @@ -64,7 +64,7 @@ perfectly safe to make progress offline; everything will re-sync when you reconn Castlevania: Circle of the Moon has a fully functional map tracker that supports auto-tracking. -1. Download [Castlevania: Circle of the Moon AP Tracker](https://github.com/sassyvania/Circle-of-the-Moon-Rando-AP-Map-Tracker-/releases/latest) and +1. Download [Castlevania: Circle of the Moon AP Tracker](https://github.com/BowserCrusher/Circle-of-the-Moon-AP-Tracker/releases/latest) and [PopTracker](https://github.com/black-sliver/PopTracker/releases). 2. Put the tracker pack into `packs/` in your PopTracker install. 3. Open PopTracker, and load the Castlevania: Circle of the Moon pack. From fde203379d9a844da8cea2bd620a0b48d9765429 Mon Sep 17 00:00:00 2001 From: Ehseezed <97066152+Ehseezed@users.noreply.github.com> Date: Wed, 28 May 2025 14:04:57 -0500 Subject: [PATCH 0483/1218] Timespinner: Fix Logic (#4803) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/timespinner/Locations.py | 4 ++-- worlds/timespinner/Regions.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/worlds/timespinner/Locations.py b/worlds/timespinner/Locations.py index 644304733a9e..82f284c656f2 100644 --- a/worlds/timespinner/Locations.py +++ b/worlds/timespinner/Locations.py @@ -92,7 +92,7 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio LocationData('Military Fortress (hangar)', 'Military Fortress: Pedestal', 1337065, lambda state: state.has('Water Mask', player) if flooded.flood_lab else (logic.has_doublejump_of_npc(state) or logic.has_forwarddash_doublejump(state))), LocationData('The lab', 'Lab: Coffee break', 1337066), LocationData('The lab', 'Lab: Lower trash right', 1337067, logic.has_doublejump), - LocationData('The lab', 'Lab: Lower trash left', 1337068, lambda state: logic.has_doublejump_of_npc(state) if options.lock_key_amadeus else logic.has_upwarddash ), + LocationData('The lab', 'Lab: Lower trash left', 1337068, lambda state: logic.has_doublejump_of_npc(state) if options.lock_key_amadeus else logic.has_upwarddash(state) ), LocationData('The lab', 'Lab: Below lab entrance', 1337069, logic.has_doublejump), LocationData('The lab (power off)', 'Lab: Trash jump room', 1337070, lambda state: not options.lock_key_amadeus or logic.has_doublejump_of_npc(state) ), LocationData('The lab (power off)', 'Lab: Dynamo Works', 1337071, lambda state: not options.lock_key_amadeus or (state.has_all(('Lab Access Research', 'Lab Access Dynamo'), player)) ), @@ -100,7 +100,7 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio LocationData('The lab (power off)', 'Lab: Experiment #13', 1337073, lambda state: not options.lock_key_amadeus or state.has('Lab Access Experiment', player) ), LocationData('The lab (upper)', 'Lab: Download and chest room chest', 1337074), LocationData('The lab (upper)', 'Lab: Lab secret', 1337075, logic.can_break_walls), - LocationData('The lab (power off)', 'Lab: Spider Hell', 1337076, lambda state: logic.has_keycard_A and not options.lock_key_amadeus or state.has('Lab Access Research', player)), + LocationData('The lab (power off)', 'Lab: Spider Hell', 1337076, lambda state: logic.has_keycard_A(state) and not options.lock_key_amadeus or state.has('Lab Access Research', player)), LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard bottom chest', 1337077), LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard floor secret', 1337078, lambda state: logic.has_upwarddash(state) and logic.can_break_walls(state)), LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard upper chest', 1337079, lambda state: logic.has_upwarddash(state)), diff --git a/worlds/timespinner/Regions.py b/worlds/timespinner/Regions.py index 51b1688f1a6d..b00396f222cc 100644 --- a/worlds/timespinner/Regions.py +++ b/worlds/timespinner/Regions.py @@ -141,7 +141,7 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'Lower Lake Serene', 'Left Side forest Caves') connect(world, player, 'Lower Lake Serene', 'Caves of Banishment (upper)', lambda state: flooded.flood_lake_serene or logic.has_doublejump(state)) connect(world, player, 'Caves of Banishment (upper)', 'Lower Lake Serene', lambda state: not flooded.flood_lake_serene or state.has('Water Mask', player)) - connect(world, player, 'Caves of Banishment (upper)', 'Caves of Banishment (Maw)', lambda state: logic.has_doublejump(state) or state.has_any({'Gas Mask', 'Talaria Attachment'} or logic.has_teleport(state), player)) + connect(world, player, 'Caves of Banishment (upper)', 'Caves of Banishment (Maw)', lambda state: logic.has_doublejump(state) or state.has_any({'Gas Mask', 'Talaria Attachment'}, player) or logic.has_teleport(state)) connect(world, player, 'Caves of Banishment (upper)', 'Space time continuum', logic.has_teleport) connect(world, player, 'Caves of Banishment (Maw)', 'Caves of Banishment (upper)', lambda state: logic.has_doublejump(state) if not flooded.flood_maw else state.has('Water Mask', player)) connect(world, player, 'Caves of Banishment (Maw)', 'Caves of Banishment (Sirens)', lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player) ) From dd6007b3094e4cf3be4d13dc55b9ceb692e23123 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Wed, 28 May 2025 18:27:03 -0400 Subject: [PATCH 0484/1218] TWW: Remove unnecessary items from slot data (#5045) --- worlds/tww/Options.py | 47 ++++++++++++++++++++++++++++++++++++++++++ worlds/tww/__init__.py | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/worlds/tww/Options.py b/worlds/tww/Options.py index ad9c8b3937a5..d02c606f9fb9 100644 --- a/worlds/tww/Options.py +++ b/worlds/tww/Options.py @@ -755,6 +755,53 @@ class TWWOptions(PerGameCommonOptions): remove_music: RemoveMusic death_link: DeathLink + def get_slot_data_dict(self) -> dict[str, Any]: + """ + Returns a dictionary of option name to value to be placed in + the slot data network package. + + :return: Dictionary of option name to value for the slot data. + """ + return self.as_dict( + "progression_dungeons", + "progression_tingle_chests", + "progression_dungeon_secrets", + "progression_puzzle_secret_caves", + "progression_combat_secret_caves", + "progression_savage_labyrinth", + "progression_great_fairies", + "progression_short_sidequests", + "progression_long_sidequests", + "progression_spoils_trading", + "progression_minigames", + "progression_battlesquid", + "progression_free_gifts", + "progression_mail", + "progression_platforms_rafts", + "progression_submarines", + "progression_eye_reef_chests", + "progression_big_octos_gunboats", + "progression_triforce_charts", + "progression_treasure_charts", + "progression_expensive_purchases", + "progression_island_puzzles", + "progression_misc", + "sword_mode", + "required_bosses", + "logic_obscurity", + "logic_precision", + "enable_tuner_logic", + "randomize_dungeon_entrances", + "randomize_secret_cave_entrances", + "randomize_miniboss_entrances", + "randomize_boss_entrances", + "randomize_secret_cave_inner_entrances", + "randomize_fairy_fountain_entrances", + "swift_sail", + "skip_rematch_bosses", + "remove_music", + ) + def get_output_dict(self) -> dict[str, Any]: """ Returns a dictionary of option name to value to be placed in diff --git a/worlds/tww/__init__.py b/worlds/tww/__init__.py index 918d68478f32..71044d78a8f0 100644 --- a/worlds/tww/__init__.py +++ b/worlds/tww/__init__.py @@ -586,7 +586,7 @@ def fill_slot_data(self) -> Mapping[str, Any]: :return: A dictionary to be sent to the client when it connects to the server. """ - slot_data = self.options.as_dict(*self.options_dataclass.type_hints) + slot_data = self.options.get_slot_data_dict() # Add entrances to `slot_data`. This is the same data that is written to the .aptww file. entrances = { From 6ebd60feaa4f70ca73ba473c1e40186e7383e901 Mon Sep 17 00:00:00 2001 From: sgrunt Date: Wed, 28 May 2025 18:37:39 -0600 Subject: [PATCH 0485/1218] Timespinner: Fix Logic Error with Risky Warp to Emperor's Tower and Lab Access (#4784) Co-authored-by: sgrunt --- worlds/timespinner/Regions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/timespinner/Regions.py b/worlds/timespinner/Regions.py index b00396f222cc..702e237355e0 100644 --- a/worlds/timespinner/Regions.py +++ b/worlds/timespinner/Regions.py @@ -115,7 +115,7 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'The lab', 'The lab (power off)', lambda state: options.lock_key_amadeus or logic.has_doublejump_of_npc(state)) connect(world, player, 'The lab (power off)', 'The lab', lambda state: not flooded.flood_lab or state.has('Water Mask', player)) connect(world, player, 'The lab (power off)', 'The lab (upper)', lambda state: logic.has_forwarddash_doublejump(state) and ((not options.lock_key_amadeus) or state.has('Lab Access Genza', player))) - connect(world, player, 'The lab (upper)', 'The lab (power off)') + connect(world, player, 'The lab (upper)', 'The lab (power off)', lambda state: options.lock_key_amadeus and state.has('Lab Access Genza', player)) connect(world, player, 'The lab (upper)', 'Emperors tower', logic.has_forwarddash_doublejump) connect(world, player, 'The lab (upper)', 'Ancient Pyramid (entrance)', lambda state: state.has_all({'Timespinner Wheel', 'Timespinner Spindle', 'Timespinner Gear 1', 'Timespinner Gear 2', 'Timespinner Gear 3'}, player)) connect(world, player, 'Emperors tower', 'The lab (upper)') From b0f41c0360bdd7621d6733204a03448dc82f42aa Mon Sep 17 00:00:00 2001 From: sgrunt Date: Wed, 28 May 2025 18:40:24 -0600 Subject: [PATCH 0486/1218] Timespinner: Fix Connection Logic from Maw Cave Entrance to Maw (#4831) Co-authored-by: sgrunt --- worlds/timespinner/Locations.py | 10 +++++----- worlds/timespinner/Regions.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/worlds/timespinner/Locations.py b/worlds/timespinner/Locations.py index 82f284c656f2..21e5501e580f 100644 --- a/worlds/timespinner/Locations.py +++ b/worlds/timespinner/Locations.py @@ -150,10 +150,10 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Jackpot room chest 3', 1337118, lambda state: flooded.flood_maw or logic.has_forwarddash_doublejump(state)), LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Jackpot room chest 4', 1337119, lambda state: flooded.flood_maw or logic.has_forwarddash_doublejump(state)), LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Pedestal', 1337120, lambda state: not flooded.flood_maw or state.has('Water Mask', player)), - LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Last chance before Maw', 1337121, lambda state: state.has('Water Mask', player) if flooded.flood_maw else logic.has_doublejump(state)), - LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Plasma Crystal', 1337173, lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player) and (not flooded.flood_maw or state.has('Water Mask', player))), - LocationData('Caves of Banishment (Maw)', 'Killed Maw', EventId, lambda state: state.has('Gas Mask', player) and (not flooded.flood_maw or state.has('Water Mask', player))), - LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Mineshaft', 1337122, lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player) and (not flooded.flood_maw or state.has('Water Mask', player))), + LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Last chance before Maw', 1337121, lambda state: flooded.flood_maw or logic.has_doublejump(state)), + LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Plasma Crystal', 1337173, lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), + LocationData('Caves of Banishment (Maw)', 'Killed Maw', EventId, lambda state: state.has('Gas Mask', player)), + LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Mineshaft', 1337122, lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Wyvern room', 1337123), LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Siren room above water chest', 1337124), LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Siren room underwater left chest', 1337125, lambda state: state.has('Water Mask', player)), @@ -251,7 +251,7 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio LocationData('Royal towers (upper)', 'Royal Towers: Journal - Top Struggle Juggle Base (War of the Sisters)', 1337195), LocationData('Royal towers (upper)', 'Royal Towers: Journal - Aelana Boss (Stained Letter)', 1337196), LocationData('Royal towers', 'Royal Towers: Journal - Near Bottom Struggle Juggle (Mission Findings)', 1337197, lambda state: flooded.flood_courtyard or logic.has_doublejump_of_npc(state)), - LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Journal - Lower Left Caves (Naivety)', 1337198, lambda state: not flooded.flood_maw or state.has('Water Mask', player)) + LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Journal - Lower Left Caves (Naivety)', 1337198) ) # 1337199 - 1337232 Reserved for future use diff --git a/worlds/timespinner/Regions.py b/worlds/timespinner/Regions.py index 702e237355e0..cb55d9810d57 100644 --- a/worlds/timespinner/Regions.py +++ b/worlds/timespinner/Regions.py @@ -141,7 +141,7 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'Lower Lake Serene', 'Left Side forest Caves') connect(world, player, 'Lower Lake Serene', 'Caves of Banishment (upper)', lambda state: flooded.flood_lake_serene or logic.has_doublejump(state)) connect(world, player, 'Caves of Banishment (upper)', 'Lower Lake Serene', lambda state: not flooded.flood_lake_serene or state.has('Water Mask', player)) - connect(world, player, 'Caves of Banishment (upper)', 'Caves of Banishment (Maw)', lambda state: logic.has_doublejump(state) or state.has_any({'Gas Mask', 'Talaria Attachment'}, player) or logic.has_teleport(state)) + connect(world, player, 'Caves of Banishment (upper)', 'Caves of Banishment (Maw)', lambda state: not flooded.flood_maw or state.has('Water Mask', player)) connect(world, player, 'Caves of Banishment (upper)', 'Space time continuum', logic.has_teleport) connect(world, player, 'Caves of Banishment (Maw)', 'Caves of Banishment (upper)', lambda state: logic.has_doublejump(state) if not flooded.flood_maw else state.has('Water Mask', player)) connect(world, player, 'Caves of Banishment (Maw)', 'Caves of Banishment (Sirens)', lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player) ) From d19bf98dc4d977372759e73bd97356f3c3cd08c4 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Fri, 30 May 2025 10:31:00 -0400 Subject: [PATCH 0487/1218] Jak and Daxter: Post-merge Polish (#5031) - Cleans up a few missed references in the setup guide. - Refactors Options class to use metaclass and decorators to enforce friendly limits on multiple levels. - Templates generated from the website, even ones with `random` should not fail generation because the website will only allow values inside the friendly limits. - _Uploaded_ yamls to the website with `random`, should also now respect friendly limits without the need for `random-range` shenanigans. - _Uploaded_ yamls to the website, or yamls that are used to generate locally, that have hard-defined values outside the friendly limits, will be clamped/dragged/massaged into those limits (with logged warnings). - Removed an early completion goal that was playing havoc with fill. Not enough people seem to use this goal, so its loss will not be mourned. --- worlds/jakanddaxter/__init__.py | 44 +++-- .../en_Jak and Daxter The Precursor Legacy.md | 17 +- worlds/jakanddaxter/docs/setup_en.md | 3 +- worlds/jakanddaxter/options.py | 122 +++++++++++-- worlds/jakanddaxter/regions.py | 4 +- worlds/jakanddaxter/rules.py | 168 +++++++++++------- worlds/jakanddaxter/test/test_trades.py | 10 +- 7 files changed, 254 insertions(+), 114 deletions(-) diff --git a/worlds/jakanddaxter/__init__.py b/worlds/jakanddaxter/__init__.py index d508e967ae9b..9a2cb30293f0 100644 --- a/worlds/jakanddaxter/__init__.py +++ b/worlds/jakanddaxter/__init__.py @@ -34,9 +34,9 @@ cache_location_table, orb_location_table) from .regions import create_regions -from .rules import (enforce_multiplayer_limits, - enforce_singleplayer_limits, - verify_orb_trade_amounts, +from .rules import (enforce_mp_absolute_limits, + enforce_mp_friendly_limits, + enforce_sp_limits, set_orb_trade_rule) from .locs import (cell_locations as cells, scout_locations as scouts, @@ -258,18 +258,31 @@ def generate_early(self) -> None: self.options.mountain_pass_cell_count.value = self.power_cell_thresholds[1] self.options.lava_tube_cell_count.value = self.power_cell_thresholds[2] - # Store this for remove function. - self.power_cell_thresholds_minus_one = [x - 1 for x in self.power_cell_thresholds] - - # For the fairness of other players in a multiworld game, enforce some friendly limitations on our options, - # so we don't cause chaos during seed generation. These friendly limits should **guarantee** a successful gen. - # We would have done this earlier, but we needed to sort the power cell thresholds first. + # We would have done this earlier, but we needed to sort the power cell thresholds first. Don't worry, we'll + # come back to them. enforce_friendly_options = self.settings.enforce_friendly_options - if enforce_friendly_options: - if self.multiworld.players > 1: - enforce_multiplayer_limits(self) + if self.multiworld.players == 1: + # For singleplayer games, always enforce/clamp the cell counts to valid values. + enforce_sp_limits(self) + else: + if enforce_friendly_options: + # For multiplayer games, we have a host setting to make options fair/sane for other players. + # If this setting is enabled, enforce/clamp some friendly limitations on our options. + enforce_mp_friendly_limits(self) else: - enforce_singleplayer_limits(self) + # Even if the setting is disabled, some values must be clamped to avoid generation errors. + enforce_mp_absolute_limits(self) + + # That's right, set the collection of thresholds again. Don't just clamp the values without updating this list! + self.power_cell_thresholds = [ + self.options.fire_canyon_cell_count.value, + self.options.mountain_pass_cell_count.value, + self.options.lava_tube_cell_count.value, + 100, # The 100 Power Cell Door. + ] + + # Now that the threshold list is finalized, store this for the remove function. + self.power_cell_thresholds_minus_one = [x - 1 for x in self.power_cell_thresholds] # Calculate the number of power cells needed for full region access, the number being replaced by traps, # and the number of remaining filler. @@ -282,11 +295,6 @@ def generate_early(self) -> None: self.options.filler_power_cells_replaced_with_traps.value = self.total_trap_cells self.total_filler_cells = non_prog_cells - self.total_trap_cells - # Verify that we didn't overload the trade amounts with more orbs than exist in the world. - # This is easy to do by accident even in a singleplayer world. - self.total_trade_orbs = (9 * self.options.citizen_orb_trade_amount) + (6 * self.options.oracle_orb_trade_amount) - verify_orb_trade_amounts(self) - # Cache the orb bundle size and item name for quicker reference. if self.options.enable_orbsanity == options.EnableOrbsanity.option_per_level: self.orb_bundle_size = self.options.level_orbsanity_bundle_size.value diff --git a/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md b/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md index 6cf8ae54a529..77fbd514cbe8 100644 --- a/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md +++ b/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md @@ -18,7 +18,7 @@ - [What do Traps do?](#what-do-traps-do) - [What kind of Traps are there?](#what-kind-of-traps-are-there) - [I got soft-locked and cannot leave, how do I get out of here?](#i-got-soft-locked-and-cannot-leave-how-do-i-get-out-of-here) -- [Why did I get an Option Error when generating a seed, and how do I fix it?](#why-did-i-get-an-option-error-when-generating-a-seed-and-how-do-i-fix-it) +- [How do I generate seeds with 1 Orb Orbsanity and other extreme options?](#how-do-i-generate-seeds-with-1-orb-orbsanity-and-other-extreme-options) - [How do I check my player options in-game?](#how-do-i-check-my-player-options-in-game) - [How does the HUD work?](#how-does-the-hud-work) - [I think I found a bug, where should I report it?](#i-think-i-found-a-bug-where-should-i-report-it) @@ -201,16 +201,19 @@ Open the game's menu, navigate to `Options`, then `Archipelago Options`, then `W Selecting this option will ask if you want to be teleported to Geyser Rock. From there, you can teleport back to the nearest sage's hut to continue your journey. -## Why did I get an Option Error when generating a seed and how do I fix it +## How do I generate seeds with 1 orb orbsanity and other extreme options? Depending on your player YAML, Jak and Daxter can have a lot of items, which can sometimes be overwhelming or disruptive to multiworld games. There are also options that are mutually incompatible with each other, even in a solo game. To prevent the game from disrupting multiworlds, or generating an impossible solo seed, some options have -Singleplayer and Multiplayer Minimums and Maximums, collectively called "friendly limits." +"friendly limits" that prevent you from choosing more extreme values. -If you're generating a solo game, or your multiworld host agrees to your request, you can override those limits by -editing the `host.yaml`. In the Archipelago Launcher, click `Open host.yaml`, then search for `jakanddaxter_options`, -then search for `enforce_friendly_options`, then change this value from `true` to `false`. Disabling this allows for -more disruptive and challenging options, but it may cause seed generation to fail. **Use at your own risk!** +You can override **some**, not all, of those limits by editing the `host.yaml`. In the Archipelago Launcher, click +`Open host.yaml`, then search for `jakanddaxter_options`, then search for `enforce_friendly_options`, then change this +value from `true` to `false`. You can then generate a seed locally, and upload that to the Archipelago website to host +for you (or host it yourself). + +**Remember:** disabling this setting allows for more disruptive and challenging options, but it may cause seed +generation to fail. **Use at your own risk!** ## How do I check my player options in-game When you connect your text client to the Archipelago Server, the server will tell the game what options were chosen diff --git a/worlds/jakanddaxter/docs/setup_en.md b/worlds/jakanddaxter/docs/setup_en.md index 509fb3ad8dcb..9cd892a9b2c7 100644 --- a/worlds/jakanddaxter/docs/setup_en.md +++ b/worlds/jakanddaxter/docs/setup_en.md @@ -4,7 +4,6 @@ - A legally purchased copy of *Jak And Daxter: The Precursor Legacy.* - [The OpenGOAL Launcher](https://opengoal.dev/) -- [The Jak and Daxter .APWORLD package](https://github.com/ArchipelaGOAL/Archipelago/releases) At this time, this method of setup works on Windows only, but Linux support is a strong likelihood in the near future as OpenGOAL itself supports Linux. @@ -75,7 +74,7 @@ If you are in the middle of an async game, and you do not want to update the mod ### New Game - Run the Archipelago Launcher. -- From the right-most list, find and click `Jak and Daxter Client`. +- From the client list, find and click `Jak and Daxter Client`. - 3 new windows should appear: - The OpenGOAL compiler will launch and compile the game. They should take about 30 seconds to compile. - You should hear a musical cue to indicate the compilation was a success. If you do not, see the Troubleshooting section. diff --git a/worlds/jakanddaxter/options.py b/worlds/jakanddaxter/options.py index bd007e264af8..d36303b0759e 100644 --- a/worlds/jakanddaxter/options.py +++ b/worlds/jakanddaxter/options.py @@ -1,22 +1,78 @@ from dataclasses import dataclass from functools import cached_property -from Options import PerGameCommonOptions, StartInventoryPool, Toggle, Choice, Range, DefaultOnToggle, OptionCounter +from Options import PerGameCommonOptions, StartInventoryPool, Toggle, Choice, Range, DefaultOnToggle, OptionCounter, \ + AssembleOptions from .items import trap_item_table -class StaticGetter: - def __init__(self, func): - self.fget = func +class readonly_classproperty: + """This decorator is used for getting friendly or unfriendly range_end values for options like FireCanyonCellCount + and CitizenOrbTradeAmount. We only need to provide a getter as we will only be setting a single int to one of two + values.""" + def __init__(self, getter): + self.getter = getter def __get__(self, instance, owner): - return self.fget(owner) + return self.getter(owner) -@StaticGetter +@readonly_classproperty def determine_range_end(cls) -> int: - from . import JakAndDaxterWorld - enforce_friendly_options = JakAndDaxterWorld.settings.enforce_friendly_options - return cls.friendly_maximum if enforce_friendly_options else cls.absolute_maximum + from . import JakAndDaxterWorld # Avoid circular imports. + friendly = JakAndDaxterWorld.settings.enforce_friendly_options + return cls.friendly_maximum if friendly else cls.absolute_maximum + + +class classproperty: + """This decorator (?) is used for getting and setting friendly or unfriendly option values for the Orbsanity + options.""" + def __init__(self, getter, setter): + self.getter = getter + self.setter = setter + + def __get__(self, obj, value): + return self.getter(obj) + + def __set__(self, obj, value): + self.setter(obj, value) + + +class AllowedChoiceMeta(AssembleOptions): + """This metaclass overrides AssembleOptions and provides inheriting classes a way to filter out "disallowed" values + by way of implementing get_disallowed_options. This function is used by Jak and Daxter to check host.yaml settings + without circular imports or breaking the settings API.""" + _name_lookup: dict[int, str] + _options: dict[str, int] + + def __new__(mcs, name, bases, attrs): + ret = super().__new__(mcs, name, bases, attrs) + ret._name_lookup = attrs["name_lookup"] + ret._options = attrs["options"] + return ret + + def set_name_lookup(cls, value : dict[int, str]): + cls._name_lookup = value + + def get_name_lookup(cls) -> dict[int, str]: + cls._name_lookup = {k: v for k, v in cls._name_lookup.items() if k not in cls.get_disallowed_options()} + return cls._name_lookup + + def set_options(cls, value: dict[str, int]): + cls._options = value + + def get_options(cls) -> dict[str, int]: + cls._options = {k: v for k, v in cls._options.items() if v not in cls.get_disallowed_options()} + return cls._options + + def get_disallowed_options(cls): + return {} + + name_lookup = classproperty(get_name_lookup, set_name_lookup) + options = classproperty(get_options, set_options) + + +class AllowedChoice(Choice, metaclass=AllowedChoiceMeta): + pass class EnableMoveRandomizer(Toggle): @@ -44,12 +100,13 @@ class EnableOrbsanity(Choice): default = 0 -class GlobalOrbsanityBundleSize(Choice): +class GlobalOrbsanityBundleSize(AllowedChoice): """The orb bundle size for Global Orbsanity. This only applies if "Enable Orbsanity" is set to "Global." There are 2000 orbs in the game, so your bundle size must be a factor of 2000. - Multiplayer Minimum: 10 - Multiplayer Maximum: 200""" + This value is restricted to safe minimum and maximum values to ensure valid singleplayer games and + non-disruptive multiplayer games, but the host can remove this restriction by turning off enforce_friendly_options + in host.yaml.""" display_name = "Global Orbsanity Bundle Size" option_1_orb = 1 option_2_orbs = 2 @@ -75,12 +132,33 @@ class GlobalOrbsanityBundleSize(Choice): friendly_maximum = 200 default = 20 - -class PerLevelOrbsanityBundleSize(Choice): + @classmethod + def get_disallowed_options(cls) -> set[int]: + try: + from . import JakAndDaxterWorld + if JakAndDaxterWorld.settings.enforce_friendly_options: + return {cls.option_1_orb, + cls.option_2_orbs, + cls.option_4_orbs, + cls.option_5_orbs, + cls.option_8_orbs, + cls.option_250_orbs, + cls.option_400_orbs, + cls.option_500_orbs, + cls.option_1000_orbs, + cls.option_2000_orbs} + except ImportError: + pass + return set() + + +class PerLevelOrbsanityBundleSize(AllowedChoice): """The orb bundle size for Per Level Orbsanity. This only applies if "Enable Orbsanity" is set to "Per Level." There are 50, 150, or 200 orbs per level, so your bundle size must be a factor of 50. - Multiplayer Minimum: 10""" + This value is restricted to safe minimum and maximum values to ensure valid singleplayer games and + non-disruptive multiplayer games, but the host can remove this restriction by turning off enforce_friendly_options + in host.yaml.""" display_name = "Per Level Orbsanity Bundle Size" option_1_orb = 1 option_2_orbs = 2 @@ -91,6 +169,18 @@ class PerLevelOrbsanityBundleSize(Choice): friendly_minimum = 10 default = 25 + @classmethod + def get_disallowed_options(cls) -> set[int]: + try: + from . import JakAndDaxterWorld + if JakAndDaxterWorld.settings.enforce_friendly_options: + return {cls.option_1_orb, + cls.option_2_orbs, + cls.option_5_orbs} + except ImportError: + pass + return set() + class FireCanyonCellCount(Range): """The number of power cells you need to cross Fire Canyon. This value is restricted to a safe maximum value to @@ -234,7 +324,7 @@ class CompletionCondition(Choice): option_cross_fire_canyon = 69 option_cross_mountain_pass = 87 option_cross_lava_tube = 89 - option_defeat_dark_eco_plant = 6 + # option_defeat_dark_eco_plant = 6 option_defeat_klaww = 86 option_defeat_gol_and_maia = 112 option_open_100_cell_door = 116 diff --git a/worlds/jakanddaxter/regions.py b/worlds/jakanddaxter/regions.py index 8447f72e8ed0..87186c3a0226 100644 --- a/worlds/jakanddaxter/regions.py +++ b/worlds/jakanddaxter/regions.py @@ -115,8 +115,8 @@ def create_regions(world: "JakAndDaxterWorld"): elif options.jak_completion_condition == CompletionCondition.option_cross_lava_tube: multiworld.completion_condition[player] = lambda state: state.can_reach(gmc, "Region", player) - elif options.jak_completion_condition == CompletionCondition.option_defeat_dark_eco_plant: - multiworld.completion_condition[player] = lambda state: state.can_reach(fjp, "Region", player) + # elif options.jak_completion_condition == CompletionCondition.option_defeat_dark_eco_plant: + # multiworld.completion_condition[player] = lambda state: state.can_reach(fjp, "Region", player) elif options.jak_completion_condition == CompletionCondition.option_defeat_klaww: multiworld.completion_condition[player] = lambda state: state.can_reach(mp, "Region", player) diff --git a/worlds/jakanddaxter/rules.py b/worlds/jakanddaxter/rules.py index 71b94df885c8..25a8323f4dff 100644 --- a/worlds/jakanddaxter/rules.py +++ b/worlds/jakanddaxter/rules.py @@ -1,3 +1,5 @@ +import logging +import math import typing from BaseClasses import CollectionState from Options import OptionError @@ -131,100 +133,138 @@ def can_fight(state: CollectionState, player: int) -> bool: return state.has_any(("Jump Dive", "Jump Kick", "Punch", "Kick"), player) -def enforce_multiplayer_limits(world: "JakAndDaxterWorld"): +def clamp_cell_limits(world: "JakAndDaxterWorld") -> str: options = world.options friendly_message = "" - if (options.enable_orbsanity == EnableOrbsanity.option_global - and (options.global_orbsanity_bundle_size.value < GlobalOrbsanityBundleSize.friendly_minimum - or options.global_orbsanity_bundle_size.value > GlobalOrbsanityBundleSize.friendly_maximum)): - friendly_message += (f" " - f"{options.global_orbsanity_bundle_size.display_name} must be no less than " - f"{GlobalOrbsanityBundleSize.friendly_minimum} and no greater than " - f"{GlobalOrbsanityBundleSize.friendly_maximum} (currently " - f"{options.global_orbsanity_bundle_size.value}).\n") - - if (options.enable_orbsanity == EnableOrbsanity.option_per_level - and options.level_orbsanity_bundle_size.value < PerLevelOrbsanityBundleSize.friendly_minimum): - friendly_message += (f" " - f"{options.level_orbsanity_bundle_size.display_name} must be no less than " - f"{PerLevelOrbsanityBundleSize.friendly_minimum} (currently " - f"{options.level_orbsanity_bundle_size.value}).\n") - if options.fire_canyon_cell_count.value > FireCanyonCellCount.friendly_maximum: + old_value = options.fire_canyon_cell_count.value + options.fire_canyon_cell_count.value = FireCanyonCellCount.friendly_maximum friendly_message += (f" " f"{options.fire_canyon_cell_count.display_name} must be no greater than " - f"{FireCanyonCellCount.friendly_maximum} (currently " - f"{options.fire_canyon_cell_count.value}).\n") + f"{FireCanyonCellCount.friendly_maximum} (was {old_value}), " + f"changed option to appropriate value.\n") if options.mountain_pass_cell_count.value > MountainPassCellCount.friendly_maximum: + old_value = options.mountain_pass_cell_count.value + options.mountain_pass_cell_count.value = MountainPassCellCount.friendly_maximum friendly_message += (f" " f"{options.mountain_pass_cell_count.display_name} must be no greater than " - f"{MountainPassCellCount.friendly_maximum} (currently " - f"{options.mountain_pass_cell_count.value}).\n") + f"{MountainPassCellCount.friendly_maximum} (was {old_value}), " + f"changed option to appropriate value.\n") if options.lava_tube_cell_count.value > LavaTubeCellCount.friendly_maximum: + old_value = options.lava_tube_cell_count.value + options.lava_tube_cell_count.value = LavaTubeCellCount.friendly_maximum friendly_message += (f" " f"{options.lava_tube_cell_count.display_name} must be no greater than " - f"{LavaTubeCellCount.friendly_maximum} (currently " - f"{options.lava_tube_cell_count.value}).\n") + f"{LavaTubeCellCount.friendly_maximum} (was {old_value}), " + f"changed option to appropriate value.\n") + + return friendly_message + + +def clamp_trade_total_limits(world: "JakAndDaxterWorld"): + """Check if we need to recalculate the 2 trade orb options so the total fits under 2000. If so let's keep them + proportional relative to each other. Then we'll recalculate total_trade_orbs. Remember this situation is + only possible if both values are greater than 0, otherwise the absolute maximums would keep them under 2000.""" + options = world.options + friendly_message = "" + + world.total_trade_orbs = (9 * options.citizen_orb_trade_amount) + (6 * options.oracle_orb_trade_amount) + if world.total_trade_orbs > 2000: + old_total = world.total_trade_orbs + old_citizen_value = options.citizen_orb_trade_amount.value + old_oracle_value = options.oracle_orb_trade_amount.value + + coefficient = old_oracle_value / old_citizen_value + + options.citizen_orb_trade_amount.value = math.floor(2000 / (9 + (6 * coefficient))) + options.oracle_orb_trade_amount.value = math.floor(coefficient * options.citizen_orb_trade_amount.value) + world.total_trade_orbs = (9 * options.citizen_orb_trade_amount) + (6 * options.oracle_orb_trade_amount) + + friendly_message += (f" " + f"Required number of orbs ({old_total}) must be no greater than total orbs in the game " + f"(2000). Reduced the value of {world.options.citizen_orb_trade_amount.display_name} " + f"from {old_citizen_value} to {options.citizen_orb_trade_amount.value} and " + f"{world.options.oracle_orb_trade_amount.display_name} from {old_oracle_value} to " + f"{options.oracle_orb_trade_amount.value}.\n") + + return friendly_message + + +def enforce_mp_friendly_limits(world: "JakAndDaxterWorld"): + options = world.options + friendly_message = "" + + if options.enable_orbsanity == EnableOrbsanity.option_global: + if options.global_orbsanity_bundle_size.value < GlobalOrbsanityBundleSize.friendly_minimum: + old_value = options.global_orbsanity_bundle_size.value + options.global_orbsanity_bundle_size.value = GlobalOrbsanityBundleSize.friendly_minimum + friendly_message += (f" " + f"{options.global_orbsanity_bundle_size.display_name} must be no less than " + f"{GlobalOrbsanityBundleSize.friendly_minimum} (was {old_value}), " + f"changed option to appropriate value.\n") + + if options.global_orbsanity_bundle_size.value > GlobalOrbsanityBundleSize.friendly_maximum: + old_value = options.global_orbsanity_bundle_size.value + options.global_orbsanity_bundle_size.value = GlobalOrbsanityBundleSize.friendly_maximum + friendly_message += (f" " + f"{options.global_orbsanity_bundle_size.display_name} must be no greater than " + f"{GlobalOrbsanityBundleSize.friendly_maximum} (was {old_value}), " + f"changed option to appropriate value.\n") + + if options.enable_orbsanity == EnableOrbsanity.option_per_level: + if options.level_orbsanity_bundle_size.value < PerLevelOrbsanityBundleSize.friendly_minimum: + old_value = options.level_orbsanity_bundle_size.value + options.level_orbsanity_bundle_size.value = PerLevelOrbsanityBundleSize.friendly_minimum + friendly_message += (f" " + f"{options.level_orbsanity_bundle_size.display_name} must be no less than " + f"{PerLevelOrbsanityBundleSize.friendly_minimum} (was {old_value}), " + f"changed option to appropriate value.\n") if options.citizen_orb_trade_amount.value > CitizenOrbTradeAmount.friendly_maximum: + old_value = options.citizen_orb_trade_amount.value + options.citizen_orb_trade_amount.value = CitizenOrbTradeAmount.friendly_maximum friendly_message += (f" " f"{options.citizen_orb_trade_amount.display_name} must be no greater than " - f"{CitizenOrbTradeAmount.friendly_maximum} (currently " - f"{options.citizen_orb_trade_amount.value}).\n") + f"{CitizenOrbTradeAmount.friendly_maximum} (was {old_value}), " + f"changed option to appropriate value.\n") if options.oracle_orb_trade_amount.value > OracleOrbTradeAmount.friendly_maximum: + old_value = options.oracle_orb_trade_amount.value + options.oracle_orb_trade_amount.value = OracleOrbTradeAmount.friendly_maximum friendly_message += (f" " f"{options.oracle_orb_trade_amount.display_name} must be no greater than " - f"{OracleOrbTradeAmount.friendly_maximum} (currently " - f"{options.oracle_orb_trade_amount.value}).\n") + f"{OracleOrbTradeAmount.friendly_maximum} (was {old_value}), " + f"changed option to appropriate value.\n") + + friendly_message += clamp_cell_limits(world) + friendly_message += clamp_trade_total_limits(world) if friendly_message != "": - raise OptionError(f"{world.player_name}: The options you have chosen may disrupt the multiworld. \n" - f"Please adjust the following Options for a multiplayer game. \n" - f"{friendly_message}" - f"Or use 'random-range-x-y' instead of 'random' in your player yaml.\n" - f"Or set 'enforce_friendly_options' in the seed generator's host.yaml to false. " - f"(Use at your own risk!)") + logging.warning(f"{world.player_name}: Your options have been modified to avoid disrupting the multiworld.\n" + f"{friendly_message}" + f"You can access more advanced options by setting 'enforce_friendly_options' in the seed " + f"generator's host.yaml to false and generating locally. (Use at your own risk!)") -def enforce_singleplayer_limits(world: "JakAndDaxterWorld"): - options = world.options +def enforce_mp_absolute_limits(world: "JakAndDaxterWorld"): friendly_message = "" - if options.fire_canyon_cell_count.value > FireCanyonCellCount.friendly_maximum: - friendly_message += (f" " - f"{options.fire_canyon_cell_count.display_name} must be no greater than " - f"{FireCanyonCellCount.friendly_maximum} (currently " - f"{options.fire_canyon_cell_count.value}).\n") - - if options.mountain_pass_cell_count.value > MountainPassCellCount.friendly_maximum: - friendly_message += (f" " - f"{options.mountain_pass_cell_count.display_name} must be no greater than " - f"{MountainPassCellCount.friendly_maximum} (currently " - f"{options.mountain_pass_cell_count.value}).\n") - - if options.lava_tube_cell_count.value > LavaTubeCellCount.friendly_maximum: - friendly_message += (f" " - f"{options.lava_tube_cell_count.display_name} must be no greater than " - f"{LavaTubeCellCount.friendly_maximum} (currently " - f"{options.lava_tube_cell_count.value}).\n") + friendly_message += clamp_trade_total_limits(world) if friendly_message != "": - raise OptionError(f"The options you have chosen may result in seed generation failures. \n" - f"Please adjust the following Options for a singleplayer game. \n" - f"{friendly_message}" - f"Or use 'random-range-x-y' instead of 'random' in your player yaml.\n" - f"Or set 'enforce_friendly_options' in your host.yaml to false. " - f"(Use at your own risk!)") + logging.warning(f"{world.player_name}: Your options have been modified to avoid seed generation failures.\n" + f"{friendly_message}") -def verify_orb_trade_amounts(world: "JakAndDaxterWorld"): +def enforce_sp_limits(world: "JakAndDaxterWorld"): + friendly_message = "" - if world.total_trade_orbs > 2000: - raise OptionError(f"{world.player_name}: Required number of orbs for all trades ({world.total_trade_orbs}) " - f"is more than all the orbs in the game (2000). Reduce the value of either " - f"{world.options.citizen_orb_trade_amount.display_name} " - f"or {world.options.oracle_orb_trade_amount.display_name}.") + friendly_message += clamp_cell_limits(world) + friendly_message += clamp_trade_total_limits(world) + + if friendly_message != "": + logging.warning(f"{world.player_name}: Your options have been modified to avoid seed generation failures.\n" + f"{friendly_message}") diff --git a/worlds/jakanddaxter/test/test_trades.py b/worlds/jakanddaxter/test/test_trades.py index e1d1a2e53dec..0277a92353f9 100644 --- a/worlds/jakanddaxter/test/test_trades.py +++ b/worlds/jakanddaxter/test/test_trades.py @@ -4,14 +4,14 @@ class TradesCostNothingTest(JakAndDaxterTestBase): options = { "enable_orbsanity": 2, - "global_orbsanity_bundle_size": 5, + "global_orbsanity_bundle_size": 10, "citizen_orb_trade_amount": 0, "oracle_orb_trade_amount": 0 } def test_orb_items_are_filler(self): self.collect_all_but("") - self.assertNotIn("5 Precursor Orbs", self.multiworld.state.prog_items) + self.assertNotIn("10 Precursor Orbs", self.multiworld.state.prog_items) def test_trades_are_accessible(self): self.assertTrue(self.multiworld @@ -22,15 +22,15 @@ def test_trades_are_accessible(self): class TradesCostEverythingTest(JakAndDaxterTestBase): options = { "enable_orbsanity": 2, - "global_orbsanity_bundle_size": 5, + "global_orbsanity_bundle_size": 10, "citizen_orb_trade_amount": 120, "oracle_orb_trade_amount": 150 } def test_orb_items_are_progression(self): self.collect_all_but("") - self.assertIn("5 Precursor Orbs", self.multiworld.state.prog_items[self.player]) - self.assertEqual(396, self.multiworld.state.prog_items[self.player]["5 Precursor Orbs"]) + self.assertIn("10 Precursor Orbs", self.multiworld.state.prog_items[self.player]) + self.assertEqual(198, self.multiworld.state.prog_items[self.player]["10 Precursor Orbs"]) def test_trades_are_accessible(self): self.collect_all_but("") From fab75d3a32ee16198b7bc67215dcef252e726250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sat, 31 May 2025 07:57:42 -0400 Subject: [PATCH 0488/1218] Stardew Valley: Fix Wizard Tower and Entrance Randomizer Softlocks (#4631) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/stardew_valley/content/mods/sve.py | 3 +-- worlds/stardew_valley/logic/quest_logic.py | 2 +- worlds/stardew_valley/logic/region_logic.py | 16 ++++++++-------- worlds/stardew_valley/rules.py | 1 + 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/worlds/stardew_valley/content/mods/sve.py b/worlds/stardew_valley/content/mods/sve.py index 2c9edc810615..378472373749 100644 --- a/worlds/stardew_valley/content/mods/sve.py +++ b/worlds/stardew_valley/content/mods/sve.py @@ -216,7 +216,6 @@ def finalize_hook(self, content: StardewContent): villagers_data.scarlett, villagers_data.susan, villagers_data.morris, - # The wizard leaves his tower on sunday, for like 1 hour... Good enough for entrance rando! - override(villagers_data.wizard, locations=(Region.wizard_tower, Region.forest), bachelor=True, mod_name=ModNames.sve), + override(villagers_data.wizard, bachelor=True, mod_name=ModNames.sve), ) )) diff --git a/worlds/stardew_valley/logic/quest_logic.py b/worlds/stardew_valley/logic/quest_logic.py index 5bc3f86eae74..af52d06e30bf 100644 --- a/worlds/stardew_valley/logic/quest_logic.py +++ b/worlds/stardew_valley/logic/quest_logic.py @@ -89,7 +89,7 @@ def initialize_rules(self): Quest.goblin_problem: self.logic.region.can_reach(Region.witch_swamp) # Void mayo can be fished at 5% chance in the witch swamp while the quest is active. It drops a lot after the quest. & (self.logic.has(ArtisanGood.void_mayonnaise) | self.logic.fishing.can_fish()), - Quest.magic_ink: self.logic.relationship.can_meet(NPC.wizard), + Quest.magic_ink: self.logic.region.can_reach(Region.witch_hut) & self.logic.relationship.can_meet(NPC.wizard), Quest.the_pirates_wife: self.logic.relationship.can_meet(NPC.kent) & self.logic.relationship.can_meet(NPC.gus) & self.logic.relationship.can_meet(NPC.sandy) & self.logic.relationship.can_meet(NPC.george) & self.logic.relationship.can_meet(NPC.wizard) & self.logic.relationship.can_meet(NPC.willy), diff --git a/worlds/stardew_valley/logic/region_logic.py b/worlds/stardew_valley/logic/region_logic.py index 083f56e1676c..81c79be097b8 100644 --- a/worlds/stardew_valley/logic/region_logic.py +++ b/worlds/stardew_valley/logic/region_logic.py @@ -1,23 +1,23 @@ -from typing import Tuple, Union +from typing import Tuple from Utils import cache_self1 from .base_logic import BaseLogic, BaseLogicMixin -from .has_logic import HasLogicMixin from ..options import EntranceRandomization from ..stardew_rule import StardewRule, Reach, false_, true_ from ..strings.region_names import Region main_outside_area = {Region.menu, Region.stardew_valley, Region.farm_house, Region.farm, Region.town, Region.beach, Region.mountain, Region.forest, Region.bus_stop, Region.backwoods, Region.bus_tunnel, Region.tunnel_entrance} -always_accessible_regions_without_er = {*main_outside_area, Region.community_center, Region.pantry, Region.crafts_room, Region.fish_tank, Region.boiler_room, - Region.vault, Region.bulletin_board, Region.mines, Region.hospital, Region.carpenter, Region.alex_house, - Region.elliott_house, Region.ranch, Region.farm_cave, Region.wizard_tower, Region.tent, Region.pierre_store, - Region.saloon, Region.blacksmith, Region.trailer, Region.museum, Region.mayor_house, Region.haley_house, - Region.sam_house, Region.jojamart, Region.fish_shop} +always_accessible_regions_with_non_progression_er = {*main_outside_area, Region.mines, Region.hospital, Region.carpenter, Region.alex_house, + Region.ranch, Region.farm_cave, Region.wizard_tower, Region.tent, + Region.pierre_store, Region.saloon, Region.blacksmith, Region.trailer, Region.museum, Region.mayor_house, + Region.haley_house, Region.sam_house, Region.jojamart, Region.fish_shop} +always_accessible_regions_without_er = {*always_accessible_regions_with_non_progression_er, Region.community_center, Region.pantry, Region.crafts_room, + Region.fish_tank, Region.boiler_room, Region.vault, Region.bulletin_board} always_regions_by_setting = {EntranceRandomization.option_disabled: always_accessible_regions_without_er, EntranceRandomization.option_pelican_town: always_accessible_regions_without_er, - EntranceRandomization.option_non_progression: always_accessible_regions_without_er, + EntranceRandomization.option_non_progression: always_accessible_regions_with_non_progression_er, EntranceRandomization.option_buildings_without_house: main_outside_area, EntranceRandomization.option_buildings: main_outside_area, EntranceRandomization.option_chaos: always_accessible_regions_without_er} diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index e5d7e8863e5a..350da064a103 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -195,6 +195,7 @@ def set_entrance_rules(logic: StardewLogic, multiworld, player, world_options: S set_entrance_rule(multiworld, player, Entrance.enter_tide_pools, logic.received("Beach Bridge") | (logic.mod.magic.can_blink())) set_entrance_rule(multiworld, player, Entrance.enter_quarry, logic.received("Bridge Repair") | (logic.mod.magic.can_blink())) set_entrance_rule(multiworld, player, Entrance.enter_secret_woods, logic.tool.has_tool(Tool.axe, "Iron") | (logic.mod.magic.can_blink())) + set_entrance_rule(multiworld, player, Entrance.forest_to_wizard_tower, logic.region.can_reach(Region.community_center)) set_entrance_rule(multiworld, player, Entrance.forest_to_sewer, logic.wallet.has_rusty_key()) set_entrance_rule(multiworld, player, Entrance.town_to_sewer, logic.wallet.has_rusty_key()) set_entrance_rule(multiworld, player, Entrance.enter_abandoned_jojamart, logic.has_abandoned_jojamart()) From 8f68bb342dcd9e4a38f41bbeb605a6e5c81319a4 Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 2 Jun 2025 10:53:18 -0500 Subject: [PATCH 0489/1218] Core and Various Worlds: define patch_file_ending to APPlayerContainer (#5058) * move to playercontainer * moves patch_file_ending handling to APPlayerContainer and updates the worlds using it to define their extensions * give oot a patch_file_ending as well --- worlds/Files.py | 4 ++-- worlds/civ_6/Container.py | 18 +++++++----------- worlds/factorio/Mod.py | 1 + worlds/kh2/OpenKH.py | 1 + worlds/oot/Patches.py | 1 + worlds/tww/__init__.py | 4 ++-- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/worlds/Files.py b/worlds/Files.py index 447219bd191b..fa3739a5a919 100644 --- a/worlds/Files.py +++ b/worlds/Files.py @@ -158,6 +158,7 @@ def get_manifest(self) -> Dict[str, Any]: class APPlayerContainer(APContainer): """A zipfile containing at least archipelago.json meant for a player""" game: ClassVar[Optional[str]] = None + patch_file_ending: str = "" player: Optional[int] player_name: str @@ -184,6 +185,7 @@ def get_manifest(self) -> Dict[str, Any]: "player": self.player, "player_name": self.player_name, "game": self.game, + "patch_file_ending": self.patch_file_ending, }) return manifest @@ -223,7 +225,6 @@ class APProcedurePatch(APAutoPatchInterface): """ hash: Optional[str] # base checksum of source file source_data: bytes - patch_file_ending: str = "" files: Dict[str, bytes] @classmethod @@ -245,7 +246,6 @@ def get_manifest(self) -> Dict[str, Any]: manifest = super(APProcedurePatch, self).get_manifest() manifest["base_checksum"] = self.hash manifest["result_file_ending"] = self.result_file_ending - manifest["patch_file_ending"] = self.patch_file_ending manifest["procedure"] = self.procedure if self.procedure == APDeltaPatch.procedure: manifest["compatible_version"] = 5 diff --git a/worlds/civ_6/Container.py b/worlds/civ_6/Container.py index 0c5340d9c2e5..a5790c1ec474 100644 --- a/worlds/civ_6/Container.py +++ b/worlds/civ_6/Container.py @@ -1,10 +1,9 @@ from dataclasses import dataclass import os -import io from typing import TYPE_CHECKING, Dict, List, Optional, cast import zipfile from BaseClasses import Location -from worlds.Files import APContainer, AutoPatchRegister +from worlds.Files import APPlayerContainer from .Enum import CivVICheckType from .Locations import CivVILocation, CivVILocationData @@ -26,22 +25,19 @@ class CivTreeItem: ui_tree_row: int -class CivVIContainer(APContainer, metaclass=AutoPatchRegister): +class CivVIContainer(APPlayerContainer): """ Responsible for generating the dynamic mod files for the Civ VI multiworld """ game: Optional[str] = "Civilization VI" patch_file_ending = ".apcivvi" - def __init__(self, patch_data: Dict[str, str] | io.BytesIO, base_path: str = "", output_directory: str = "", + def __init__(self, patch_data: Dict[str, str], base_path: str = "", output_directory: str = "", player: Optional[int] = None, player_name: str = "", server: str = ""): - if isinstance(patch_data, io.BytesIO): - super().__init__(patch_data, player, player_name, server) - else: - self.patch_data = patch_data - self.file_path = base_path - container_path = os.path.join(output_directory, base_path + ".apcivvi") - super().__init__(container_path, player, player_name, server) + self.patch_data = patch_data + self.file_path = base_path + container_path = os.path.join(output_directory, base_path + ".apcivvi") + super().__init__(container_path, player, player_name, server) def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None: for filename, yml in self.patch_data.items(): diff --git a/worlds/factorio/Mod.py b/worlds/factorio/Mod.py index eb305897f435..3cc156112d32 100644 --- a/worlds/factorio/Mod.py +++ b/worlds/factorio/Mod.py @@ -67,6 +67,7 @@ class FactorioModFile(worlds.Files.APPlayerContainer): game = "Factorio" compression_method = zipfile.ZIP_DEFLATED # Factorio can't load LZMA archives writing_tasks: List[Callable[[], Tuple[str, Union[str, bytes]]]] + patch_file_ending = ".zip" def __init__(self, *args: Any, **kwargs: Any): super().__init__(*args, **kwargs) diff --git a/worlds/kh2/OpenKH.py b/worlds/kh2/OpenKH.py index 985c9913abe8..7c67fc07def4 100644 --- a/worlds/kh2/OpenKH.py +++ b/worlds/kh2/OpenKH.py @@ -13,6 +13,7 @@ class KH2Container(APPlayerContainer): game: str = 'Kingdom Hearts 2' + patch_file_ending = ".zip" def __init__(self, patch_data: dict, base_path: str, output_directory: str, player=None, player_name: str = "", server: str = ""): diff --git a/worlds/oot/Patches.py b/worlds/oot/Patches.py index cd940e052a2b..db7be3d4ddc5 100644 --- a/worlds/oot/Patches.py +++ b/worlds/oot/Patches.py @@ -38,6 +38,7 @@ class OoTContainer(APPatch): game: str = 'Ocarina of Time' + patch_file_ending = ".apz5" def __init__(self, patch_data: bytes, base_path: str, output_directory: str, player = None, player_name: str = "", server: str = ""): diff --git a/worlds/tww/__init__.py b/worlds/tww/__init__.py index 71044d78a8f0..5432d200ae3f 100644 --- a/worlds/tww/__init__.py +++ b/worlds/tww/__init__.py @@ -11,7 +11,7 @@ from BaseClasses import MultiWorld, Region, Tutorial from Options import Toggle from worlds.AutoWorld import WebWorld, World -from worlds.Files import APPlayerContainer, AutoPatchRegister +from worlds.Files import APPlayerContainer from worlds.generic.Rules import add_item_rule from worlds.LauncherComponents import Component, SuffixIdentifier, Type, components, icon_paths, launch_subprocess @@ -51,7 +51,7 @@ def run_client() -> None: icon_paths["The Wind Waker"] = "ap:worlds.tww/assets/icon.png" -class TWWContainer(APPlayerContainer, metaclass=AutoPatchRegister): +class TWWContainer(APPlayerContainer): """ This class defines the container file for The Wind Waker. """ From cabde313b563990171c39bf2b644bf8f779df81b Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 2 Jun 2025 10:53:57 -0500 Subject: [PATCH 0490/1218] WebHost: Use expected APPlayerContainer manifest location directly when ingesting them #4754 --- WebHostLib/upload.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/WebHostLib/upload.py b/WebHostLib/upload.py index 45b26b175eb3..66b6f5560bae 100644 --- a/WebHostLib/upload.py +++ b/WebHostLib/upload.py @@ -119,9 +119,9 @@ def upload_zip_to_db(zfile: zipfile.ZipFile, owner=None, meta={"race": False}, s # AP Container elif handler: data = zfile.open(file, "r").read() - patch = handler(BytesIO(data)) - patch.read() - files[patch.player] = data + with zipfile.ZipFile(BytesIO(data)) as container: + player = json.loads(container.open("archipelago.json").read())["player"] + files[player] = data # Spoiler elif file.filename.endswith(".txt"): From 0c5cb17d96af6091a5c35f13cc2fc62551679b09 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Mon, 2 Jun 2025 16:56:11 +0100 Subject: [PATCH 0491/1218] DLCQuest: Add missing indirect conditions (#5074) The `Behind Rocks` and `Pickaxe Hard Cave` Entrances require being able to reach the `Cut Content` region, but no indirect conditions were being registered for this region. The `set_lfod_self_obtained_items_rules` function was also using a `world` parameter that was actually expecting a `MultiWorld` instance, so I have renamed it for clarity and updated the function to use `world.get_entrance()` rather than `multiworld.get_entrance()`. Much of the rest of the file passes `MultiWorld` instances to `world` parameters, but fixing all of these is out of the scope of the changes in this patch, so has not been included. --- worlds/dlcquest/Rules.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/worlds/dlcquest/Rules.py b/worlds/dlcquest/Rules.py index 3461d0633ef1..5dfd80165a01 100644 --- a/worlds/dlcquest/Rules.py +++ b/worlds/dlcquest/Rules.py @@ -280,16 +280,19 @@ def set_boss_door_requirements_rules(player, world): set_rule(world.get_entrance("Boss Door", player), has_3_swords) -def set_lfod_self_obtained_items_rules(world_options, player, world): +def set_lfod_self_obtained_items_rules(world_options, player, multiworld): if world_options.item_shuffle != Options.ItemShuffle.option_disabled: return - set_rule(world.get_entrance("Vines", player), + world = multiworld.worlds[player] + set_rule(world.get_entrance("Vines"), lambda state: state.has("Incredibly Important Pack", player)) - set_rule(world.get_entrance("Behind Rocks", player), + set_rule(world.get_entrance("Behind Rocks"), lambda state: state.can_reach("Cut Content", 'region', player)) - set_rule(world.get_entrance("Pickaxe Hard Cave", player), + multiworld.register_indirect_condition(world.get_region("Cut Content"), world.get_entrance("Behind Rocks")) + set_rule(world.get_entrance("Pickaxe Hard Cave"), lambda state: state.can_reach("Cut Content", 'region', player) and state.has("Name Change Pack", player)) + multiworld.register_indirect_condition(world.get_region("Cut Content"), world.get_entrance("Pickaxe Hard Cave")) def set_lfod_shuffled_items_rules(world_options, player, world): From 99142fd6625b3bf3ef013bbd3bc1813c5d95923f Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:01:21 -0400 Subject: [PATCH 0492/1218] Plando Items: Fix count with empty locations/location #5040 --- Options.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Options.py b/Options.py index 3d08c5f00370..26e145926edc 100644 --- a/Options.py +++ b/Options.py @@ -1524,9 +1524,11 @@ def from_any(cls, data: typing.Any) -> Option[typing.List[PlandoItem]]: f"dictionary, not {type(items)}") locations = item.get("locations", []) if not locations: - locations = item.get("location", ["Everywhere"]) + locations = item.get("location", []) if locations: count = 1 + else: + locations = ["Everywhere"] if isinstance(locations, str): locations = [locations] if not isinstance(locations, list): From 04c707f8740c25373f090c8f03199d8c56f067de Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Mon, 2 Jun 2025 17:06:54 +0100 Subject: [PATCH 0493/1218] DKC3: Add missing indirect conditions (#5073) A couple of Entrance access rules were checking for being able to reach a Location, but a Location first checks for being able to reach its parent Region, so it needs to be registered that access to that parent Region can give access to the Entrance. --- worlds/dkc3/Regions.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/worlds/dkc3/Regions.py b/worlds/dkc3/Regions.py index 6e968dbe1e30..c6c7dd362efd 100644 --- a/worlds/dkc3/Regions.py +++ b/worlds/dkc3/Regions.py @@ -802,8 +802,10 @@ def connect_regions(world: World, level_list): for i in range(0, len(kremwood_forest_levels) - 1): connect(world, world.player, names, LocationName.kremwood_forest_region, kremwood_forest_levels[i]) - connect(world, world.player, names, LocationName.kremwood_forest_region, kremwood_forest_levels[-1], - lambda state: (state.can_reach(LocationName.riverside_race_flag, "Location", world.player))) + connection = connect(world, world.player, names, LocationName.kremwood_forest_region, kremwood_forest_levels[-1], + lambda state: (state.can_reach(LocationName.riverside_race_flag, "Location", world.player))) + world.multiworld.register_indirect_condition(world.get_location(LocationName.riverside_race_flag).parent_region, + connection) # Cotton-Top Cove Connections cotton_top_cove_levels = [ @@ -837,8 +839,11 @@ def connect_regions(world: World, level_list): connect(world, world.player, names, LocationName.mekanos_region, LocationName.sky_high_secret_region, lambda state: (state.has(ItemName.bowling_ball, world.player, 1))) else: - connect(world, world.player, names, LocationName.mekanos_region, LocationName.sky_high_secret_region, - lambda state: (state.can_reach(LocationName.bleaks_house, "Location", world.player))) + connection = connect(world, world.player, names, LocationName.mekanos_region, + LocationName.sky_high_secret_region, + lambda state: (state.can_reach(LocationName.bleaks_house, "Location", world.player))) + world.multiworld.register_indirect_condition(world.get_location(LocationName.bleaks_house).parent_region, + connection) # K3 Connections k3_levels = [ @@ -946,3 +951,4 @@ def connect(world: World, player: int, used_names: typing.Dict[str, int], source source_region.exits.append(connection) connection.connect(target_region) + return connection From b85b18cf5fb5db4dbcbd736ff4a3dafcfeeb0f3b Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Mon, 2 Jun 2025 16:39:42 +0000 Subject: [PATCH 0494/1218] SoE: remove outdated info from guide (#5064) The client does not depend on Animation Frame anymore, so it can be backgrounded. --- worlds/soe/docs/multiworld_en.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/worlds/soe/docs/multiworld_en.md b/worlds/soe/docs/multiworld_en.md index a2944d4c012b..9378626df4f6 100644 --- a/worlds/soe/docs/multiworld_en.md +++ b/worlds/soe/docs/multiworld_en.md @@ -130,9 +130,7 @@ page: [usb2snes Supported Platforms Page](http://usb2snes.com/#supported-platfor ### Open the client -Open ap-soeclient ([Evermizer Archipelago Client Page](http://evermizer.com/apclient)) in a modern browser. Do not -switch tabs, open it in a new window if you want to use the browser while playing. Do not minimize the window with the -client. +Open ap-soeclient ([Evermizer Archipelago Client Page](http://evermizer.com/apclient)) in a modern browser. The client should automatically connect to SNI, the "SNES" status should change to green. From 694e6bcae36bab4e49c60c3c8f097d2f440a0979 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Tue, 3 Jun 2025 10:42:37 +0000 Subject: [PATCH 0495/1218] Launcher/Utils: reset LD_LIBRARY_PATH for system EXEs (#5022) --- Launcher.py | 15 ++++++++++++--- Utils.py | 36 ++++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/Launcher.py b/Launcher.py index 88e2070e9c4c..82326aacd70a 100644 --- a/Launcher.py +++ b/Launcher.py @@ -11,6 +11,7 @@ import argparse import logging import multiprocessing +import os import shlex import subprocess import sys @@ -41,13 +42,17 @@ def open_host_yaml(): if is_linux: exe = which('sensible-editor') or which('gedit') or \ which('xdg-open') or which('gnome-open') or which('kde-open') - subprocess.Popen([exe, file]) elif is_macos: exe = which("open") - subprocess.Popen([exe, file]) else: webbrowser.open(file) + return + env = os.environ + if "LD_LIBRARY_PATH" in env: + env = env.copy() + del env["LD_LIBRARY_PATH"] # exe is a system binary, so reset LD_LIBRARY_PATH + subprocess.Popen([exe, file], env=env) def open_patch(): suffixes = [] @@ -92,7 +97,11 @@ def open_folder(folder_path): return if exe: - subprocess.Popen([exe, folder_path]) + env = os.environ + if "LD_LIBRARY_PATH" in env: + env = env.copy() + del env["LD_LIBRARY_PATH"] # exe is a system binary, so reset LD_LIBRARY_PATH + subprocess.Popen([exe, folder_path], env=env) else: logging.warning(f"No file browser available to open {folder_path}") diff --git a/Utils.py b/Utils.py index b38809ba1b9e..f20389055008 100644 --- a/Utils.py +++ b/Utils.py @@ -226,7 +226,12 @@ def open_file(filename: typing.Union[str, "pathlib.Path"]) -> None: from shutil import which open_command = which("open") if is_macos else (which("xdg-open") or which("gnome-open") or which("kde-open")) assert open_command, "Didn't find program for open_file! Please report this together with system details." - subprocess.call([open_command, filename]) + + env = os.environ + if "LD_LIBRARY_PATH" in env: + env = env.copy() + del env["LD_LIBRARY_PATH"] # exe is a system binary, so reset LD_LIBRARY_PATH + subprocess.call([open_command, filename], env=env) # from https://gist.github.com/pypt/94d747fe5180851196eb#gistcomment-4015118 with some changes @@ -708,25 +713,30 @@ def _mp_open_filename(res: "multiprocessing.Queue[typing.Optional[str]]", *args: res.put(open_filename(*args)) +def _run_for_stdout(*args: str): + env = os.environ + if "LD_LIBRARY_PATH" in env: + env = env.copy() + del env["LD_LIBRARY_PATH"] # exe is a system binary, so reset LD_LIBRARY_PATH + return subprocess.run(args, capture_output=True, text=True, env=env).stdout.split("\n", 1)[0] or None + + def open_filename(title: str, filetypes: typing.Iterable[typing.Tuple[str, typing.Iterable[str]]], suggest: str = "") \ -> typing.Optional[str]: logging.info(f"Opening file input dialog for {title}.") - def run(*args: str): - return subprocess.run(args, capture_output=True, text=True).stdout.split("\n", 1)[0] or None - if is_linux: # prefer native dialog from shutil import which kdialog = which("kdialog") if kdialog: k_filters = '|'.join((f'{text} (*{" *".join(ext)})' for (text, ext) in filetypes)) - return run(kdialog, f"--title={title}", "--getopenfilename", suggest or ".", k_filters) + return _run_for_stdout(kdialog, f"--title={title}", "--getopenfilename", suggest or ".", k_filters) zenity = which("zenity") if zenity: z_filters = (f'--file-filter={text} ({", ".join(ext)}) | *{" *".join(ext)}' for (text, ext) in filetypes) selection = (f"--filename={suggest}",) if suggest else () - return run(zenity, f"--title={title}", "--file-selection", *z_filters, *selection) + return _run_for_stdout(zenity, f"--title={title}", "--file-selection", *z_filters, *selection) # fall back to tk try: @@ -760,21 +770,18 @@ def _mp_open_directory(res: "multiprocessing.Queue[typing.Optional[str]]", *args def open_directory(title: str, suggest: str = "") -> typing.Optional[str]: - def run(*args: str): - return subprocess.run(args, capture_output=True, text=True).stdout.split("\n", 1)[0] or None - if is_linux: # prefer native dialog from shutil import which kdialog = which("kdialog") if kdialog: - return run(kdialog, f"--title={title}", "--getexistingdirectory", + return _run_for_stdout(kdialog, f"--title={title}", "--getexistingdirectory", os.path.abspath(suggest) if suggest else ".") zenity = which("zenity") if zenity: z_filters = ("--directory",) selection = (f"--filename={os.path.abspath(suggest)}/",) if suggest else () - return run(zenity, f"--title={title}", "--file-selection", *z_filters, *selection) + return _run_for_stdout(zenity, f"--title={title}", "--file-selection", *z_filters, *selection) # fall back to tk try: @@ -801,9 +808,6 @@ def run(*args: str): def messagebox(title: str, text: str, error: bool = False) -> None: - def run(*args: str): - return subprocess.run(args, capture_output=True, text=True).stdout.split("\n", 1)[0] or None - if is_kivy_running(): from kvui import MessageBox MessageBox(title, text, error).open() @@ -814,10 +818,10 @@ def run(*args: str): from shutil import which kdialog = which("kdialog") if kdialog: - return run(kdialog, f"--title={title}", "--error" if error else "--msgbox", text) + return _run_for_stdout(kdialog, f"--title={title}", "--error" if error else "--msgbox", text) zenity = which("zenity") if zenity: - return run(zenity, f"--title={title}", f"--text={text}", "--error" if error else "--info") + return _run_for_stdout(zenity, f"--title={title}", f"--text={text}", "--error" if error else "--info") elif is_windows: import ctypes From a76cec15397efc4758fc1d487fc5cbc97e663d7c Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Tue, 3 Jun 2025 06:51:06 -0400 Subject: [PATCH 0496/1218] =?UTF-8?q?TUNIC:=20Fix=20decoupled=20ER=20+=20l?= =?UTF-8?q?adder=20storage=20making=20invalid=20entrances=C2=A0#5075?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worlds/tunic/er_rules.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index 8c0979e3e466..edd6021cba6c 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -56,18 +56,18 @@ def get_portal_info(portal_sd: str) -> Tuple[str, str]: for portal1, portal2 in portal_pairs.items(): if portal1.scene_destination() == portal_sd: return portal1.name, get_portal_outlet_region(portal2, world) - if portal2.scene_destination() == portal_sd: + if portal2.scene_destination() == portal_sd and not (options.decoupled and options.entrance_rando): return portal2.name, get_portal_outlet_region(portal1, world) - raise Exception("No matches found in get_portal_info") + raise Exception(f"No matches found in get_portal_info for {portal_sd}") # input scene destination tag, returns paired portal's name and region def get_paired_portal(portal_sd: str) -> Tuple[str, str]: for portal1, portal2 in portal_pairs.items(): if portal1.scene_destination() == portal_sd: return portal2.name, portal2.region - if portal2.scene_destination() == portal_sd: + if portal2.scene_destination() == portal_sd and not (options.decoupled and options.entrance_rando): return portal1.name, portal1.region - raise Exception("no matches found in get_paired_portal") + raise Exception(f"No matches found in get_paired_portal for {portal_sd}") regions["Menu"].connect( connecting_region=regions["Overworld"]) From b4f68bce7671e83e1fd4a358e506705777228eb6 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 3 Jun 2025 13:49:44 +0200 Subject: [PATCH 0497/1218] Factorio: revamp args parsing and passing (#5036) --- worlds/factorio/Client.py | 88 ++++++++++++++++++++++--------------- worlds/factorio/__init__.py | 4 +- 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/worlds/factorio/Client.py b/worlds/factorio/Client.py index 199cb29b86c0..d7992c327635 100644 --- a/worlds/factorio/Client.py +++ b/worlds/factorio/Client.py @@ -69,7 +69,9 @@ class FactorioContext(CommonContext): # updated by spinup server mod_version: Version = Version(0, 0, 0) - def __init__(self, server_address, password, filter_item_sends: bool, bridge_chat_out: bool): + def __init__(self, server_address, password, filter_item_sends: bool, bridge_chat_out: bool, + rcon_port: int, rcon_password: str, server_settings_path: str | None, + factorio_server_args: tuple[str, ...]): super(FactorioContext, self).__init__(server_address, password) self.send_index: int = 0 self.rcon_client = None @@ -82,6 +84,10 @@ def __init__(self, server_address, password, filter_item_sends: bool, bridge_cha self.filter_item_sends: bool = filter_item_sends self.multiplayer: bool = False # whether multiple different players have connected self.bridge_chat_out: bool = bridge_chat_out + self.rcon_port: int = rcon_port + self.rcon_password: str = rcon_password + self.server_settings_path: str = server_settings_path + self.additional_factorio_server_args = factorio_server_args @property def energylink_key(self) -> str: @@ -126,6 +132,18 @@ def print_to_game(self, text): self.rcon_client.send_command(f"/ap-print [font=default-large-bold]Archipelago:[/font] " f"{text}") + @property + def server_args(self) -> tuple[str, ...]: + if self.server_settings_path: + return ( + "--rcon-port", str(self.rcon_port), + "--rcon-password", self.rcon_password, + "--server-settings", self.server_settings_path, + *self.additional_factorio_server_args) + else: + return ("--rcon-port", str(self.rcon_port), "--rcon-password", self.rcon_password, + *self.additional_factorio_server_args) + @property def energy_link_status(self) -> str: if not self.energy_link_increment: @@ -311,7 +329,7 @@ async def factorio_server_watcher(ctx: FactorioContext): executable, "--create", savegame_name, "--preset", "archipelago" )) factorio_process = subprocess.Popen((executable, "--start-server", savegame_name, - *(str(elem) for elem in server_args)), + *ctx.server_args), stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, @@ -331,7 +349,7 @@ async def factorio_server_watcher(ctx: FactorioContext): factorio_queue.task_done() if not ctx.rcon_client and "Starting RCON interface at IP ADDR:" in msg: - ctx.rcon_client = factorio_rcon.RCONClient("localhost", rcon_port, rcon_password, + ctx.rcon_client = factorio_rcon.RCONClient("localhost", ctx.rcon_port, ctx.rcon_password, timeout=5) if not ctx.server: logger.info("Established bridge to Factorio Server. " @@ -422,7 +440,7 @@ async def factorio_spinup_server(ctx: FactorioContext) -> bool: executable, "--create", savegame_name )) factorio_process = subprocess.Popen( - (executable, "--start-server", savegame_name, *(str(elem) for elem in server_args)), + (executable, "--start-server", savegame_name, *ctx.server_args), stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, @@ -451,7 +469,7 @@ async def factorio_spinup_server(ctx: FactorioContext) -> bool: "or a Factorio sharing data directories is already running. " "Server could not start up.") if not rcon_client and "Starting RCON interface at IP ADDR:" in msg: - rcon_client = factorio_rcon.RCONClient("localhost", rcon_port, rcon_password) + rcon_client = factorio_rcon.RCONClient("localhost", ctx.rcon_port, ctx.rcon_password) if ctx.mod_version == ctx.__class__.mod_version: raise Exception("No Archipelago mod was loaded. Aborting.") await get_info(ctx, rcon_client) @@ -474,9 +492,8 @@ async def factorio_spinup_server(ctx: FactorioContext) -> bool: return False -async def main(args, filter_item_sends: bool, filter_bridge_chat_out: bool): - ctx = FactorioContext(args.connect, args.password, filter_item_sends, filter_bridge_chat_out) - +async def main(make_context): + ctx = make_context() ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop") if gui_enabled: @@ -509,38 +526,42 @@ def _handle_color(self, node: JSONMessagePart): return self._handle_text(node) -parser = get_base_parser(description="Optional arguments to FactorioClient follow. " - "Remaining arguments get passed into bound Factorio instance." - "Refer to Factorio --help for those.") -parser.add_argument('--rcon-port', default='24242', type=int, help='Port to use to communicate with Factorio') -parser.add_argument('--rcon-password', help='Password to authenticate with RCON.') -parser.add_argument('--server-settings', help='Factorio server settings configuration file.') - -args, rest = parser.parse_known_args() -rcon_port = args.rcon_port -rcon_password = args.rcon_password if args.rcon_password else ''.join( - random.choice(string.ascii_letters) for x in range(32)) factorio_server_logger = logging.getLogger("FactorioServer") settings: FactorioSettings = get_settings().factorio_options if os.path.samefile(settings.executable, sys.executable): selected_executable = settings.executable settings.executable = FactorioSettings.executable # reset to default - raise Exception(f"FactorioClient was set to run itself {selected_executable}, aborting process bomb.") + raise Exception(f"Factorio Client was set to run itself {selected_executable}, aborting process bomb.") executable = settings.executable -server_settings = args.server_settings if args.server_settings \ - else getattr(settings, "server_settings", None) -server_args = ("--rcon-port", rcon_port, "--rcon-password", rcon_password) - -def launch(): +def launch(*new_args: str): import colorama - global executable, server_settings, server_args + global executable colorama.just_fix_windows_console() + # args handling + parser = get_base_parser(description="Optional arguments to Factorio Client follow. " + "Remaining arguments get passed into bound Factorio instance." + "Refer to Factorio --help for those.") + parser.add_argument('--rcon-port', default='24242', type=int, help='Port to use to communicate with Factorio') + parser.add_argument('--rcon-password', help='Password to authenticate with RCON.') + parser.add_argument('--server-settings', help='Factorio server settings configuration file.') + + args, rest = parser.parse_known_args(args=new_args) + rcon_port = args.rcon_port + rcon_password = args.rcon_password if args.rcon_password else ''.join( + random.choice(string.ascii_letters) for _ in range(32)) + + server_settings = args.server_settings if args.server_settings \ + else getattr(settings, "server_settings", None) + if server_settings: server_settings = os.path.abspath(server_settings) + if not os.path.isfile(server_settings): + raise FileNotFoundError(f"Could not find file {server_settings} for server_settings. Aborting.") + initial_filter_item_sends = bool(settings.filter_item_sends) initial_bridge_chat_out = bool(settings.bridge_chat_out) @@ -554,14 +575,9 @@ def launch(): else: raise FileNotFoundError(f"Path {executable} is not an executable file.") - if server_settings and os.path.isfile(server_settings): - server_args = ( - "--rcon-port", rcon_port, - "--rcon-password", rcon_password, - "--server-settings", server_settings, - *rest) - else: - server_args = ("--rcon-port", rcon_port, "--rcon-password", rcon_password, *rest) - - asyncio.run(main(args, initial_filter_item_sends, initial_bridge_chat_out)) + asyncio.run(main(lambda: FactorioContext( + args.connect, args.password, + initial_filter_item_sends, initial_bridge_chat_out, + rcon_port, rcon_password, server_settings, rest + ))) colorama.deinit() diff --git a/worlds/factorio/__init__.py b/worlds/factorio/__init__.py index bfa6ceb894e0..8dc654099bac 100644 --- a/worlds/factorio/__init__.py +++ b/worlds/factorio/__init__.py @@ -22,9 +22,9 @@ from .settings import FactorioSettings -def launch_client(): +def launch_client(*args: str): from .Client import launch - launch_component(launch, name="FactorioClient") + launch_component(launch, name="Factorio Client", args=args) components.append(Component("Factorio Client", func=launch_client, component_type=Type.CLIENT)) From 603a5005e2f5d055f1b66ac5d75c133459240868 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 3 Jun 2025 08:49:10 -0400 Subject: [PATCH 0498/1218] DS3: Fix Non-Crow Itemlinking and Mark Aldrich Ruby and Twin Dragon Greatshield As Missable (#4510) * Fix Branch (Not Crow) * Oops * Mark Aldrich Ruby as missable * Expand comment * Short circuit * Mark Twin Dragon Greatshield as missable * Add missable cause --- worlds/dark_souls_3/Locations.py | 4 ++-- worlds/dark_souls_3/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index c84d91e516c2..b4e45fb57791 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -884,7 +884,7 @@ def __init__( DS3LocationData("RS: Homeward Bone - balcony by Farron Keep", "Homeward Bone x2"), DS3LocationData("RS: Titanite Shard - woods, surrounded by enemies", "Titanite Shard"), DS3LocationData("RS: Twin Dragon Greatshield - woods by Crucifixion Woods bonfire", - "Twin Dragon Greatshield"), + "Twin Dragon Greatshield", missable=True), # After Eclipse DS3LocationData("RS: Sorcerer Hood - water beneath stronghold", "Sorcerer Hood", hidden=True), # Hidden fall DS3LocationData("RS: Sorcerer Robe - water beneath stronghold", "Sorcerer Robe", @@ -1887,7 +1887,7 @@ def __init__( DS3LocationData("AL: Twinkling Titanite - lizard after light cathedral #2", "Twinkling Titanite", lizard=True), DS3LocationData("AL: Aldrich's Ruby - dark cathedral, miniboss", "Aldrich's Ruby", - miniboss=True), # Deep Accursed drop + miniboss=True, missable=True), # Deep Accursed drop, missable after defeating Aldrich DS3LocationData("AL: Aldrich Faithful - water reserves, talk to McDonnel", "Aldrich Faithful", hidden=True), # Behind illusory wall diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 5e1003d2a9a2..94150faf0571 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -705,7 +705,7 @@ def set_rules(self) -> None: if self._is_location_available("US: Young White Branch - by white tree #2"): self._add_item_rule( "US: Young White Branch - by white tree #2", - lambda item: item.player == self.player and not item.data.unique + lambda item: item.player != self.player or not item.data.unique ) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant From a2708edc37ff98e70b58f0f552deb14282f5a7ad Mon Sep 17 00:00:00 2001 From: Ehseezed <97066152+Ehseezed@users.noreply.github.com> Date: Wed, 4 Jun 2025 12:51:08 -0500 Subject: [PATCH 0499/1218] Timespinner: Fix Castle Ramparts Region Connection #5082 Co-authored-by: ehseezed --- worlds/timespinner/Regions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/timespinner/Regions.py b/worlds/timespinner/Regions.py index cb55d9810d57..b9b1d10445ce 100644 --- a/worlds/timespinner/Regions.py +++ b/worlds/timespinner/Regions.py @@ -178,7 +178,7 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'Space time continuum', 'Upper Lake Serene', lambda state: logic.can_teleport_to(state, "Past", "GateLakeSereneLeft")) connect(world, player, 'Space time continuum', 'Left Side forest Caves', lambda state: logic.can_teleport_to(state, "Past", "GateLakeSereneRight")) connect(world, player, 'Space time continuum', 'Refugee Camp', lambda state: logic.can_teleport_to(state, "Past", "GateAccessToPast")) - connect(world, player, 'Space time continuum', 'Castle Ramparts', lambda state: logic.can_teleport_to(state, "Past", "GateCastleRamparts")) + connect(world, player, 'Space time continuum', 'Forest', lambda state: logic.can_teleport_to(state, "Past", "GateCastleRamparts")) connect(world, player, 'Space time continuum', 'Castle Keep', lambda state: logic.can_teleport_to(state, "Past", "GateCastleKeep")) connect(world, player, 'Space time continuum', 'Royal towers (lower)', lambda state: logic.can_teleport_to(state, "Past", "GateRoyalTowers")) connect(world, player, 'Space time continuum', 'Caves of Banishment (Maw)', lambda state: logic.can_teleport_to(state, "Past", "GateMaw")) From 50db922cefbde107dd33d588ce621336b956a397 Mon Sep 17 00:00:00 2001 From: Jarno Date: Thu, 5 Jun 2025 15:05:00 +0200 Subject: [PATCH 0500/1218] Timespinner: Fixed generation error because of timezone locking (#5084) * Fixed generation error because of timezone locking * Refactored logic + prevent excluding warps when unchained keys in on --- worlds/timespinner/PreCalculatedWeights.py | 9 ++++++--- worlds/timespinner/__init__.py | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/worlds/timespinner/PreCalculatedWeights.py b/worlds/timespinner/PreCalculatedWeights.py index 3ad7c2c78af0..96551ea7f152 100644 --- a/worlds/timespinner/PreCalculatedWeights.py +++ b/worlds/timespinner/PreCalculatedWeights.py @@ -88,12 +88,15 @@ def get_pyramid_keys_unlocks(options: TimespinnerOptions, random: Random, if options.risky_warps: past_teleportation_gates.append("GateLakeSereneLeft") - present_teleportation_gates.append("GateDadsTower") if not is_xarion_flooded: present_teleportation_gates.append("GateXarion") - if not is_lab_flooded: - present_teleportation_gates.append("GateLabEntrance") + # Prevent going past the lazers without a way to the past + if options.unchained_keys or options.prism_break or not options.pyramid_start: + present_teleportation_gates.append("GateDadsTower") + if not is_lab_flooded: + present_teleportation_gates.append("GateLabEntrance") + # Prevent getting stuck in the past without a way back to the future if options.inverted or (options.pyramid_start and not options.back_to_the_future): all_gates: Tuple[str, ...] = present_teleportation_gates else: diff --git a/worlds/timespinner/__init__.py b/worlds/timespinner/__init__.py index 4d1efc41e53f..77314d40ec7b 100644 --- a/worlds/timespinner/__init__.py +++ b/worlds/timespinner/__init__.py @@ -42,6 +42,7 @@ class TimespinnerWorld(World): topology_present = True web = TimespinnerWebWorld() required_client_version = (0, 4, 2) + ut_can_gen_without_yaml = True item_name_to_id = {name: data.code for name, data in item_table.items()} location_name_to_id = {location.name: location.code for location in get_location_datas(-1, None, None)} From ab7d3ce4aadfc647c42c8d4dd0c7aa10f9e0e49d Mon Sep 17 00:00:00 2001 From: BlastSlimey <89539656+BlastSlimey@users.noreply.github.com> Date: Fri, 6 Jun 2025 00:05:53 +0200 Subject: [PATCH 0501/1218] shapez: Remove preset unittests #5086 --- worlds/shapez/test/__init__.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/worlds/shapez/test/__init__.py b/worlds/shapez/test/__init__.py index 3ab626e63936..d2dfad97da6f 100644 --- a/worlds/shapez/test/__init__.py +++ b/worlds/shapez/test/__init__.py @@ -92,17 +92,7 @@ def test_global_options_import(self): f"{max_levels_and_upgrades} instead.") -class TestMinimum(ShapezTestBase): - options = options_presets["Minimum checks"] - - -class TestMaximum(ShapezTestBase): - options = options_presets["Maximum checks"] - - -class TestRestrictive(ShapezTestBase): - options = options_presets["Restrictive start"] - +# The following unittests are intended to test all code paths of the generator class TestAllRelevantOptions1(ShapezTestBase): options = { From f25ef639f2d127bb991b6bf30913d1da832816c0 Mon Sep 17 00:00:00 2001 From: qwint Date: Sun, 8 Jun 2025 17:43:23 -0500 Subject: [PATCH 0502/1218] Launcher: Fix Cli Components when installed to a directory with a space (#5091) --- Launcher.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Launcher.py b/Launcher.py index 82326aacd70a..5720012cf9a7 100644 --- a/Launcher.py +++ b/Launcher.py @@ -196,7 +196,8 @@ def get_exe(component: str | Component) -> Sequence[str] | None: def launch(exe, in_terminal=False): if in_terminal: if is_windows: - subprocess.Popen(['start', *exe], shell=True) + # intentionally using a window title with a space so it gets quoted and treated as a title + subprocess.Popen(["start", "Running Archipelago", *exe], shell=True) return elif is_linux: terminal = which('x-terminal-emulator') or which('gnome-terminal') or which('xterm') From ddb3240591feab473e76b1363fe4b45ff1110610 Mon Sep 17 00:00:00 2001 From: JaredWeakStrike <96694163+JaredWeakStrike@users.noreply.github.com> Date: Mon, 9 Jun 2025 08:58:08 -0400 Subject: [PATCH 0503/1218] KH2: Give warning when client has cached locations (#5000) * a * disconnect when connect to wrong slot * connection to the wrong seed fix * seed_name is always none --- worlds/kh2/Client.py | 58 ++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/worlds/kh2/Client.py b/worlds/kh2/Client.py index 96b406c72f2f..fcd27c4c3cb6 100644 --- a/worlds/kh2/Client.py +++ b/worlds/kh2/Client.py @@ -34,7 +34,7 @@ def __init__(self, server_address, password): self.growthlevel = None self.kh2connected = False self.kh2_finished_game = False - self.serverconneced = False + self.serverconnected = False self.item_name_to_data = {name: data for name, data, in item_dictionary_table.items()} self.location_name_to_data = {name: data for name, data, in all_locations.items()} self.kh2_data_package = {} @@ -47,6 +47,8 @@ def __init__(self, server_address, password): self.location_name_to_worlddata = {name: data for name, data, in all_world_locations.items()} self.sending = [] + self.slot_name = None + self.disconnect_from_server = False # list used to keep track of locations+items player has. Used for disoneccting self.kh2_seed_save_cache = { "itemIndex": -1, @@ -185,11 +187,20 @@ async def server_auth(self, password_requested: bool = False): if password_requested and not self.password: await super(KH2Context, self).server_auth(password_requested) await self.get_username() - await self.send_connect() + # if slot name != first time login or previous name + # and seed name is none or saved seed name + if not self.slot_name and not self.kh2seedname: + await self.send_connect() + elif self.slot_name == self.auth and self.kh2seedname: + await self.send_connect() + else: + logger.info(f"You are trying to connect with data still cached in the client. Close client or connect to the correct slot: {self.slot_name}") + self.serverconnected = False + self.disconnect_from_server = True async def connection_closed(self): self.kh2connected = False - self.serverconneced = False + self.serverconnected = False if self.kh2seedname is not None and self.auth is not None: with open(self.kh2_seed_save_path_join, 'w') as f: f.write(json.dumps(self.kh2_seed_save, indent=4)) @@ -197,7 +208,8 @@ async def connection_closed(self): async def disconnect(self, allow_autoreconnect: bool = False): self.kh2connected = False - self.serverconneced = False + self.serverconnected = False + self.locations_checked = [] if self.kh2seedname not in {None} and self.auth not in {None}: with open(self.kh2_seed_save_path_join, 'w') as f: f.write(json.dumps(self.kh2_seed_save, indent=4)) @@ -239,7 +251,15 @@ def kh2_read_string(self, address, length): def on_package(self, cmd: str, args: dict): if cmd == "RoomInfo": - self.kh2seedname = args['seed_name'] + if not self.kh2seedname: + self.kh2seedname = args['seed_name'] + elif self.kh2seedname != args['seed_name']: + self.disconnect_from_server = True + self.serverconnected = False + self.kh2connected = False + logger.info("Connection to the wrong seed, connect to the correct seed or close the client.") + return + self.kh2_seed_save_path = f"kh2save2{self.kh2seedname}{self.auth}.json" self.kh2_seed_save_path_join = os.path.join(self.game_communication_path, self.kh2_seed_save_path) @@ -338,7 +358,7 @@ def on_package(self, cmd: str, args: dict): }, }, } - if start_index > self.kh2_seed_save_cache["itemIndex"] and self.serverconneced: + if start_index > self.kh2_seed_save_cache["itemIndex"] and self.serverconnected: self.kh2_seed_save_cache["itemIndex"] = start_index for item in args['items']: asyncio.create_task(self.give_item(item.item, item.location)) @@ -370,12 +390,14 @@ def connect_to_game(self): if not self.kh2: self.kh2 = pymem.Pymem(process_name="KINGDOM HEARTS II FINAL MIX") self.get_addresses() - +# except Exception as e: if self.kh2connected: self.kh2connected = False logger.info("Game is not open.") - self.serverconneced = True + + self.serverconnected = True + self.slot_name = self.auth def data_package_kh2_cache(self, loc_to_id, item_to_id): self.kh2_loc_name_to_id = loc_to_id @@ -930,7 +952,7 @@ def finishedGame(ctx: KH2Context): async def kh2_watcher(ctx: KH2Context): while not ctx.exit_event.is_set(): try: - if ctx.kh2connected and ctx.serverconneced: + if ctx.kh2connected and ctx.serverconnected: ctx.sending = [] await asyncio.create_task(ctx.checkWorldLocations()) await asyncio.create_task(ctx.checkLevels()) @@ -944,13 +966,19 @@ async def kh2_watcher(ctx: KH2Context): if ctx.sending: message = [{"cmd": 'LocationChecks', "locations": ctx.sending}] await ctx.send_msgs(message) - elif not ctx.kh2connected and ctx.serverconneced: - logger.info("Game Connection lost. waiting 15 seconds until trying to reconnect.") + elif not ctx.kh2connected and ctx.serverconnected: + logger.info("Game Connection lost. trying to reconnect.") ctx.kh2 = None - while not ctx.kh2connected and ctx.serverconneced: - await asyncio.sleep(15) - ctx.kh2 = pymem.Pymem(process_name="KINGDOM HEARTS II FINAL MIX") - ctx.get_addresses() + while not ctx.kh2connected and ctx.serverconnected: + try: + ctx.kh2 = pymem.Pymem(process_name="KINGDOM HEARTS II FINAL MIX") + ctx.get_addresses() + logger.info("Game Connection Established.") + except Exception as e: + await asyncio.sleep(5) + if ctx.disconnect_from_server: + ctx.disconnect_from_server = False + await ctx.disconnect() except Exception as e: if ctx.kh2connected: ctx.kh2connected = False From a8c87ce54ba68007e5f8f291355ffeeeed408ca1 Mon Sep 17 00:00:00 2001 From: BadMagic100 Date: Mon, 9 Jun 2025 20:55:40 -0700 Subject: [PATCH 0504/1218] CI: Add GH_REPO environment variable to labeler (#5081) --- .github/workflows/label-pull-requests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/label-pull-requests.yml b/.github/workflows/label-pull-requests.yml index bc0f6999b6a8..4a7d4034590a 100644 --- a/.github/workflows/label-pull-requests.yml +++ b/.github/workflows/label-pull-requests.yml @@ -6,6 +6,8 @@ on: permissions: contents: read pull-requests: write +env: + GH_REPO: ${{ github.repository }} jobs: labeler: From 52b11083fe23a6fdbf01ee4cda1dd2bc97800006 Mon Sep 17 00:00:00 2001 From: JaredWeakStrike <96694163+JaredWeakStrike@users.noreply.github.com> Date: Wed, 11 Jun 2025 15:52:47 -0400 Subject: [PATCH 0505/1218] KH2: Raise Exception for Misusing DonaldGoofyStatsanity Option (#4710) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/kh2/Client.py | 30 +++++++++++++++++++++++++----- worlds/kh2/__init__.py | 11 ++++++----- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/worlds/kh2/Client.py b/worlds/kh2/Client.py index fcd27c4c3cb6..5a26231c0cad 100644 --- a/worlds/kh2/Client.py +++ b/worlds/kh2/Client.py @@ -515,23 +515,38 @@ async def verifyLevel(self): async def give_item(self, item, location): try: - # todo: ripout all the itemtype stuff and just have one dictionary. the only thing that needs to be tracked from the server/local is abilites - #sleep so we can get the datapackage and not miss any items that were sent to us while we didnt have our item id dicts + # sleep so we can get the datapackage and not miss any items that were sent to us while we didnt have our item id dicts while not self.lookup_id_to_item: await asyncio.sleep(0.5) itemname = self.lookup_id_to_item[item] itemdata = self.item_name_to_data[itemname] - # itemcode = self.kh2_item_name_to_id[itemname] if itemdata.ability: if location in self.all_weapon_location_id: return + # growth have reserved ability slots because of how the goa handles them if itemname in {"High Jump", "Quick Run", "Dodge Roll", "Aerial Dodge", "Glide"}: self.kh2_seed_save_cache["AmountInvo"]["Growth"][itemname] += 1 return if itemname not in self.kh2_seed_save_cache["AmountInvo"]["Ability"]: self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname] = [] - # appending the slot that the ability should be in + # appending the slot that the ability should be in + # abilities have a limit amount of slots. + # we start from the back going down to not mess with stuff. + # Front of Invo + # Sora: Save+24F0+0x54 : 0x2546 + # Donald: Save+2604+0x54 : 0x2658 + # Goofy: Save+2718+0x54 : 0x276C + # Back of Invo. Sora has 6 ability slots that are reserved + # Sora: Save+24F0+0x54+0x92 : 0x25D8 + # Donald: Save+2604+0x54+0x9C : 0x26F4 + # Goofy: Save+2718+0x54+0x9C : 0x2808 + # seed has 2 scans in sora's abilities + # recieved second scan + # if len(seed_save(Scan:[ability slot 52]) < (2)amount of that ability they should have from slot data + # ability_slot = back of inventory that isnt taken + # add ability_slot to seed_save(Scan[]) so now its Scan:[ability slot 52,50] + # decrease back of inventory since its ability_slot is already taken if len(self.kh2_seed_save_cache["AmountInvo"]["Ability"][itemname]) < \ self.AbilityQuantityDict[itemname]: if itemname in self.sora_ability_set: @@ -550,18 +565,21 @@ async def give_item(self, item, location): if ability_slot in self.front_ability_slots: self.front_ability_slots.remove(ability_slot) + # if itemdata in {bitmask} all the forms,summons and a few other things are bitmasks elif itemdata.memaddr in {0x36C4, 0x36C5, 0x36C6, 0x36C0, 0x36CA}: # if memaddr is in a bitmask location in memory if itemname not in self.kh2_seed_save_cache["AmountInvo"]["Bitmask"]: self.kh2_seed_save_cache["AmountInvo"]["Bitmask"].append(itemname) + # if itemdata in {magic} elif itemdata.memaddr in {0x3594, 0x3595, 0x3596, 0x3597, 0x35CF, 0x35D0}: - # if memaddr is in magic addresses self.kh2_seed_save_cache["AmountInvo"]["Magic"][itemname] += 1 + # equipment is a list instead of dict because you can only have 1 currently elif itemname in self.all_equipment: self.kh2_seed_save_cache["AmountInvo"]["Equipment"].append(itemname) + # weapons are done differently since you can only have one and has to check it differently elif itemname in self.all_weapons: if itemname in self.keyblade_set: self.kh2_seed_save_cache["AmountInvo"]["Weapon"]["Sora"].append(itemname) @@ -570,9 +588,11 @@ async def give_item(self, item, location): else: self.kh2_seed_save_cache["AmountInvo"]["Weapon"]["Goofy"].append(itemname) + # TODO: this can just be removed and put into the else below it elif itemname in self.stat_increase_set: self.kh2_seed_save_cache["AmountInvo"]["StatIncrease"][itemname] += 1 else: + # "normal" items. They have a unique byte reserved for how many they have if itemname in self.kh2_seed_save_cache["AmountInvo"]["Amount"]: self.kh2_seed_save_cache["AmountInvo"]["Amount"][itemname] += 1 else: diff --git a/worlds/kh2/__init__.py b/worlds/kh2/__init__.py index defb285d509c..19c2aee61f12 100644 --- a/worlds/kh2/__init__.py +++ b/worlds/kh2/__init__.py @@ -277,9 +277,7 @@ def generate_early(self) -> None: if self.options.FillerItemsLocal: for item in filler_items: self.options.local_items.value.add(item) - # By imitating remote this doesn't have to be plandoded filler anymore - # for location in {LocationName.JunkMedal, LocationName.JunkMedal}: - # self.plando_locations[location] = random_stt_item + if not self.options.SummonLevelLocationToggle: self.total_locations -= 6 @@ -400,6 +398,8 @@ def goofy_pre_fill(self): # plando goofy get bonuses goofy_get_bonus_location_pool = [self.multiworld.get_location(location, self.player) for location in Goofy_Checks.keys() if Goofy_Checks[location].yml != "Keyblade"] + if len(goofy_get_bonus_location_pool) > len(self.goofy_get_bonus_abilities): + raise Exception(f"Too little abilities to fill goofy get bonus locations for player {self.player_name}.") for location in goofy_get_bonus_location_pool: self.random.choice(self.goofy_get_bonus_abilities) random_ability = self.random.choice(self.goofy_get_bonus_abilities) @@ -416,11 +416,12 @@ def donald_pre_fill(self): random_ability = self.random.choice(self.donald_weapon_abilities) location.place_locked_item(random_ability) self.donald_weapon_abilities.remove(random_ability) - + # if option is turned off if not self.options.DonaldGoofyStatsanity: - # plando goofy get bonuses donald_get_bonus_location_pool = [self.multiworld.get_location(location, self.player) for location in Donald_Checks.keys() if Donald_Checks[location].yml != "Keyblade"] + if len(donald_get_bonus_location_pool) > len(self.donald_get_bonus_abilities): + raise Exception(f"Too little abilities to fill donald get bonus locations for player {self.player_name}.") for location in donald_get_bonus_location_pool: random_ability = self.random.choice(self.donald_get_bonus_abilities) location.place_locked_item(random_ability) From aecbb2ab0259e8683dc848b538ac2ab7d5ee1fb9 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 13 Jun 2025 05:28:58 -0500 Subject: [PATCH 0506/1218] fix saving princess's use of subprocess helpers (#5103) --- worlds/saving_princess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/saving_princess/__init__.py b/worlds/saving_princess/__init__.py index 4109f356fd2e..f731012abc8e 100644 --- a/worlds/saving_princess/__init__.py +++ b/worlds/saving_princess/__init__.py @@ -12,7 +12,7 @@ def launch_client(*args: str): from .Client import launch - launch_subprocess(launch(*args), name=CLIENT_NAME) + launch_subprocess(launch, name=CLIENT_NAME, args=args) components.append( From 8c6327d024e6d18503b018b3555c0f24d88b13a6 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 13 Jun 2025 14:56:09 -0500 Subject: [PATCH 0507/1218] LTTP/SDV: use .name when appropriate in subtests (#5107) --- worlds/alttp/test/options/test_dungeon_fill.py | 4 ++-- .../test/regions/TestEntranceClassifications.py | 2 +- .../stardew_valley/test/regions/TestRegionConnections.py | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/worlds/alttp/test/options/test_dungeon_fill.py b/worlds/alttp/test/options/test_dungeon_fill.py index 17501b65d87c..4a0d30f7d9ad 100644 --- a/worlds/alttp/test/options/test_dungeon_fill.py +++ b/worlds/alttp/test/options/test_dungeon_fill.py @@ -38,7 +38,7 @@ def generate_with_options(self, option_value: int): def test_original_dungeons(self): self.generate_with_options(DungeonItem.option_original_dungeon) for location in self.multiworld.get_filled_locations(): - with (self.subTest(location=location)): + with (self.subTest(location_name=location.name)): if location.parent_region.dungeon is None: self.assertIs(location.item.dungeon, None) else: @@ -52,7 +52,7 @@ def test_original_dungeons(self): def test_own_dungeons(self): self.generate_with_options(DungeonItem.option_own_dungeons) for location in self.multiworld.get_filled_locations(): - with self.subTest(location=location): + with self.subTest(location_name=location.name): if location.parent_region.dungeon is None: self.assertIs(location.item.dungeon, None) else: diff --git a/worlds/stardew_valley/test/regions/TestEntranceClassifications.py b/worlds/stardew_valley/test/regions/TestEntranceClassifications.py index 43a7090482b9..4bc13cb51cf8 100644 --- a/worlds/stardew_valley/test/regions/TestEntranceClassifications.py +++ b/worlds/stardew_valley/test/regions/TestEntranceClassifications.py @@ -11,7 +11,7 @@ def assert_non_progression_are_all_accessible_with_empty_inventory(self: SVTestB non_progression_connections = [connection for connection in all_connections.values() if RandomizationFlag.BIT_NON_PROGRESSION in connection.flag] for non_progression_connections in non_progression_connections: - with self.subTest(connection=non_progression_connections): + with self.subTest(connection=non_progression_connections.name): self.assert_can_reach_entrance(non_progression_connections.name) diff --git a/worlds/stardew_valley/test/regions/TestRegionConnections.py b/worlds/stardew_valley/test/regions/TestRegionConnections.py index 42a2e36124aa..f20ef7943c90 100644 --- a/worlds/stardew_valley/test/regions/TestRegionConnections.py +++ b/worlds/stardew_valley/test/regions/TestRegionConnections.py @@ -12,14 +12,14 @@ class TestVanillaRegionsConnectionsWithGingerIsland(unittest.TestCase): def test_region_exits_lead_somewhere(self): for region in vanilla_data.regions_with_ginger_island_by_name.values(): - with self.subTest(region=region): + with self.subTest(region=region.name): for exit_ in region.exits: self.assertIn(exit_, vanilla_data.connections_with_ginger_island_by_name, f"{region.name} is leading to {exit_} but it does not exist.") def test_connection_lead_somewhere(self): for connection in vanilla_data.connections_with_ginger_island_by_name.values(): - with self.subTest(connection=connection): + with self.subTest(connection=connection.name): self.assertIn(connection.destination, vanilla_data.regions_with_ginger_island_by_name, f"{connection.name} is leading to {connection.destination} but it does not exist.") @@ -27,14 +27,14 @@ def test_connection_lead_somewhere(self): class TestVanillaRegionsConnectionsWithoutGingerIsland(unittest.TestCase): def test_region_exits_lead_somewhere(self): for region in vanilla_data.regions_without_ginger_island_by_name.values(): - with self.subTest(region=region): + with self.subTest(region=region.name): for exit_ in region.exits: self.assertIn(exit_, vanilla_data.connections_without_ginger_island_by_name, f"{region.name} is leading to {exit_} but it does not exist.") def test_connection_lead_somewhere(self): for connection in vanilla_data.connections_without_ginger_island_by_name.values(): - with self.subTest(connection=connection): + with self.subTest(connection=connection.name): self.assertIn(connection.destination, vanilla_data.regions_without_ginger_island_by_name, f"{connection.name} is leading to {connection.destination} but it does not exist.") From 0ad4527719c60caacbb6b1777b256556c7ad52d9 Mon Sep 17 00:00:00 2001 From: PoryGone <98504756+PoryGone@users.noreply.github.com> Date: Fri, 13 Jun 2025 16:01:19 -0400 Subject: [PATCH 0508/1218] SA2B: Logic Fixes (#5095) - Fixed King Boom Boo being able to appear in multiple boss gates - `Final Rush - 16 Animals (Expert)` no longer requires `Sonic - Bounce Bracelet` - `Dry Lagoon - 5 (Standard)` now requires `Rouge - Pick Nails` - `Sand Ocean - Extra Life Box 2 (Standard/Hard/Expert)` no longer requires `Eggman - Jet Engine` - `Security Hall - 8 Animals (Expert)` no longer requires `Rouge - Pick Nails` - `Sky Rail - Item Box 8 (Standard)` now requires `Shadow - Air Shoes` and `Shadow - Mystic Melody` - `Cosmic Wall - Chao Key 1 (Standard/Hard/Expert)` no longer requires `Eggman - Mystic Melody` - `Cannon's Core - Pipe 2 (Expert)` no longer requires `Tails - Booster` - `Cannon's Core - Gold Beetle` no longer requires `Tails - Booster` nor `Knuckles - Hammer Gloves` --- worlds/sa2b/GateBosses.py | 13 ++++++++----- worlds/sa2b/Rules.py | 33 +++++++++------------------------ 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/worlds/sa2b/GateBosses.py b/worlds/sa2b/GateBosses.py index 9e1a81bae94b..02e089359bfe 100644 --- a/worlds/sa2b/GateBosses.py +++ b/worlds/sa2b/GateBosses.py @@ -1,6 +1,7 @@ import typing from BaseClasses import MultiWorld +from Options import OptionError from worlds.AutoWorld import World from .Names import LocationName @@ -99,8 +100,9 @@ def get_gate_bosses(world: World): pass if boss in plando_bosses: - # TODO: Raise error here. Duplicates not allowed - pass + raise OptionError(f"Invalid input for option `plando_bosses`: " + f"No Duplicate Bosses permitted ({boss}) - for " + f"{world.player_name}") plando_bosses[boss_num] = boss @@ -108,13 +110,14 @@ def get_gate_bosses(world: World): available_bosses.remove(boss) for x in range(world.options.number_of_level_gates): - if ("king boom boo" not in selected_bosses) and ("king boom boo" not in available_bosses) and ((x + 1) / world.options.number_of_level_gates) > 0.5: - available_bosses.extend(gate_bosses_with_requirements_table) + if (10 not in selected_bosses) and (king_boom_boo not in available_bosses) and ((x + 1) / world.options.number_of_level_gates) > 0.5: + available_bosses.extend(gate_bosses_with_requirements_table.keys()) world.random.shuffle(available_bosses) chosen_boss = available_bosses[0] if plando_bosses[x] != "None": - available_bosses.append(plando_bosses[x]) + if plando_bosses[x] not in available_bosses: + available_bosses.append(plando_bosses[x]) chosen_boss = plando_bosses[x] selected_bosses.append(all_gate_bosses_table[chosen_boss]) diff --git a/worlds/sa2b/Rules.py b/worlds/sa2b/Rules.py index 9019a5b0330b..a7ea9becb1cf 100644 --- a/worlds/sa2b/Rules.py +++ b/worlds/sa2b/Rules.py @@ -324,7 +324,8 @@ def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, pla add_rule_safe(multiworld, LocationName.iron_gate_5, player, lambda state: state.has(ItemName.eggman_large_cannon, player)) add_rule_safe(multiworld, LocationName.dry_lagoon_5, player, - lambda state: state.has(ItemName.rouge_treasure_scope, player)) + lambda state: state.has(ItemName.rouge_pick_nails, player) and + state.has(ItemName.rouge_treasure_scope, player)) add_rule_safe(multiworld, LocationName.sand_ocean_5, player, lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule_safe(multiworld, LocationName.egg_quarters_5, player, @@ -407,8 +408,7 @@ def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, pla lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_1, player), - lambda state: state.has(ItemName.eggman_mystic_melody, player) and - state.has(ItemName.eggman_jet_engine, player)) + lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule(multiworld.get_location(LocationName.cannon_core_chao_1, player), lambda state: state.has(ItemName.tails_booster, player) and @@ -1402,8 +1402,6 @@ def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, pla state.has(ItemName.eggman_large_cannon, player))) add_rule(multiworld.get_location(LocationName.dry_lagoon_lifebox_2, player), lambda state: state.has(ItemName.rouge_treasure_scope, player)) - add_rule(multiworld.get_location(LocationName.sand_ocean_lifebox_2, player), - lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule(multiworld.get_location(LocationName.egg_quarters_lifebox_2, player), lambda state: (state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_treasure_scope, player))) @@ -1724,6 +1722,9 @@ def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, pla lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule(multiworld.get_location(LocationName.white_jungle_itembox_8, player), lambda state: state.has(ItemName.shadow_air_shoes, player)) + add_rule(multiworld.get_location(LocationName.sky_rail_itembox_8, player), + lambda state: (state.has(ItemName.shadow_air_shoes, player) and + state.has(ItemName.shadow_mystic_melody, player))) add_rule(multiworld.get_location(LocationName.mad_space_itembox_8, player), lambda state: state.has(ItemName.rouge_iron_boots, player)) add_rule(multiworld.get_location(LocationName.cosmic_wall_itembox_8, player), @@ -2308,8 +2309,7 @@ def set_mission_upgrade_rules_hard(multiworld: MultiWorld, world: World, player: lambda state: state.has(ItemName.tails_booster, player)) add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_1, player), - lambda state: state.has(ItemName.eggman_mystic_melody, player) and - state.has(ItemName.eggman_jet_engine, player)) + lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule(multiworld.get_location(LocationName.cannon_core_chao_1, player), lambda state: state.has(ItemName.tails_booster, player) and @@ -2980,8 +2980,6 @@ def set_mission_upgrade_rules_hard(multiworld: MultiWorld, world: World, player: state.has(ItemName.eggman_jet_engine, player))) add_rule(multiworld.get_location(LocationName.dry_lagoon_lifebox_2, player), lambda state: state.has(ItemName.rouge_treasure_scope, player)) - add_rule(multiworld.get_location(LocationName.sand_ocean_lifebox_2, player), - lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule(multiworld.get_location(LocationName.egg_quarters_lifebox_2, player), lambda state: (state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_treasure_scope, player))) @@ -3593,8 +3591,7 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe lambda state: state.has(ItemName.tails_booster, player)) add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_1, player), - lambda state: state.has(ItemName.eggman_mystic_melody, player) and - state.has(ItemName.eggman_jet_engine, player)) + lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule(multiworld.get_location(LocationName.cannon_core_chao_1, player), lambda state: state.has(ItemName.eggman_jet_engine, player) and @@ -3643,9 +3640,6 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_2, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(multiworld.get_location(LocationName.cannon_core_pipe_2, player), - lambda state: state.has(ItemName.tails_booster, player)) - add_rule(multiworld.get_location(LocationName.prison_lane_pipe_3, player), lambda state: state.has(ItemName.tails_bazooka, player)) add_rule(multiworld.get_location(LocationName.mission_street_pipe_3, player), @@ -3771,10 +3765,6 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe add_rule(multiworld.get_location(LocationName.cosmic_wall_beetle, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) - add_rule(multiworld.get_location(LocationName.cannon_core_beetle, player), - lambda state: state.has(ItemName.tails_booster, player) and - state.has(ItemName.knuckles_hammer_gloves, player)) - # Animal Upgrade Requirements if world.options.animalsanity: add_rule(multiworld.get_location(LocationName.hidden_base_animal_2, player), @@ -3839,8 +3829,7 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe add_rule(multiworld.get_location(LocationName.weapons_bed_animal_8, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule(multiworld.get_location(LocationName.security_hall_animal_8, player), - lambda state: state.has(ItemName.rouge_pick_nails, player) and - state.has(ItemName.rouge_iron_boots, player)) + lambda state: state.has(ItemName.rouge_iron_boots, player)) add_rule(multiworld.get_location(LocationName.cosmic_wall_animal_8, player), lambda state: state.has(ItemName.eggman_jet_engine, player)) @@ -3976,8 +3965,6 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe state.has(ItemName.tails_bazooka, player)) add_rule(multiworld.get_location(LocationName.crazy_gadget_animal_16, player), lambda state: state.has(ItemName.sonic_flame_ring, player)) - add_rule(multiworld.get_location(LocationName.final_rush_animal_16, player), - lambda state: state.has(ItemName.sonic_bounce_bracelet, player)) add_rule(multiworld.get_location(LocationName.final_chase_animal_17, player), lambda state: state.has(ItemName.shadow_flame_ring, player)) @@ -4035,8 +4022,6 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule(multiworld.get_location(LocationName.dry_lagoon_lifebox_2, player), lambda state: state.has(ItemName.rouge_treasure_scope, player)) - add_rule(multiworld.get_location(LocationName.sand_ocean_lifebox_2, player), - lambda state: state.has(ItemName.eggman_jet_engine, player)) add_rule(multiworld.get_location(LocationName.egg_quarters_lifebox_2, player), lambda state: state.has(ItemName.rouge_treasure_scope, player)) From 068a7573737078d413cdd0fe1ea4c94bc2903821 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Fri, 13 Jun 2025 20:29:06 -0400 Subject: [PATCH 0509/1218] Item Plando: Fix `count` value (#5101) --- Fill.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Fill.py b/Fill.py index d0a42c07ebcd..87d6b02e0921 100644 --- a/Fill.py +++ b/Fill.py @@ -937,13 +937,16 @@ def failed(warning: str, force: bool | str) -> None: count = block.count if not count: - count = len(new_block.items) + count = (min(len(new_block.items), len(new_block.resolved_locations)) + if new_block.resolved_locations else len(new_block.items)) if isinstance(count, int): count = {"min": count, "max": count} if "min" not in count: count["min"] = 0 if "max" not in count: - count["max"] = len(new_block.items) + count["max"] = (min(len(new_block.items), len(new_block.resolved_locations)) + if new_block.resolved_locations else len(new_block.items)) + new_block.count = count plando_blocks[player].append(new_block) From e83e178b63272d2a1ec96dd2ae04dbae64c3f737 Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Fri, 13 Jun 2025 20:29:23 -0400 Subject: [PATCH 0510/1218] Stardew Valley: Fix 3 Logic Issues (#5094) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/stardew_valley/data/bundle_data.py | 10 ++++---- worlds/stardew_valley/logic/logic.py | 24 +++++++++++-------- .../strings/monster_drop_names.py | 5 ---- .../stardew_valley/test/rules/TestFishing.py | 9 +++---- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/worlds/stardew_valley/data/bundle_data.py b/worlds/stardew_valley/data/bundle_data.py index 3a5523ecdd3f..3f289d33cd1a 100644 --- a/worlds/stardew_valley/data/bundle_data.py +++ b/worlds/stardew_valley/data/bundle_data.py @@ -271,11 +271,11 @@ void_essence = BundleItem(Loot.void_essence) petrified_slime = BundleItem(Mineral.petrified_slime) -blue_slime_egg = BundleItem(Loot.blue_slime_egg) -red_slime_egg = BundleItem(Loot.red_slime_egg) -purple_slime_egg = BundleItem(Loot.purple_slime_egg) -green_slime_egg = BundleItem(Loot.green_slime_egg) -tiger_slime_egg = BundleItem(Loot.tiger_slime_egg, source=BundleItem.Sources.island) +blue_slime_egg = BundleItem(AnimalProduct.slime_egg_blue) +red_slime_egg = BundleItem(AnimalProduct.slime_egg_red) +purple_slime_egg = BundleItem(AnimalProduct.slime_egg_purple) +green_slime_egg = BundleItem(AnimalProduct.slime_egg_green) +tiger_slime_egg = BundleItem(AnimalProduct.slime_egg_tiger, source=BundleItem.Sources.island) cherry_bomb = BundleItem(Bomb.cherry_bomb, 5) bomb = BundleItem(Bomb.bomb, 2) diff --git a/worlds/stardew_valley/logic/logic.py b/worlds/stardew_valley/logic/logic.py index 716dd06571aa..42bfb9cc2604 100644 --- a/worlds/stardew_valley/logic/logic.py +++ b/worlds/stardew_valley/logic/logic.py @@ -168,15 +168,16 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC AnimalProduct.squid_ink: self.mine.can_mine_in_the_mines_floor_81_120() | (self.building.has_building(Building.fish_pond) & self.has(Fish.squid)), AnimalProduct.sturgeon_roe: self.has(Fish.sturgeon) & self.building.has_building(Building.fish_pond), AnimalProduct.truffle: self.animal.has_animal(Animal.pig) & self.season.has_any_not_winter(), - AnimalProduct.void_egg: self.has(AnimalProduct.void_egg_starter), # Should also check void chicken if there was an alternative to obtain it without void egg + AnimalProduct.void_egg: self.has(AnimalProduct.void_egg_starter), # Should also check void chicken if there was an alternative to obtain it without void egg AnimalProduct.wool: self.animal.has_animal(Animal.rabbit) | self.animal.has_animal(Animal.sheep), AnimalProduct.slime_egg_green: self.has(Machine.slime_egg_press) & self.has(Loot.slime), AnimalProduct.slime_egg_blue: self.has(Machine.slime_egg_press) & self.has(Loot.slime) & self.time.has_lived_months(3), AnimalProduct.slime_egg_red: self.has(Machine.slime_egg_press) & self.has(Loot.slime) & self.time.has_lived_months(6), AnimalProduct.slime_egg_purple: self.has(Machine.slime_egg_press) & self.has(Loot.slime) & self.time.has_lived_months(9), - AnimalProduct.slime_egg_tiger: self.has(Fish.lionfish) & self.building.has_building(Building.fish_pond), - AnimalProduct.duck_egg_starter: self.logic.false_, # It could be purchased at the Feast of the Winter Star, but it's random every year, so not considering it yet... - AnimalProduct.dinosaur_egg_starter: self.logic.false_, # Dinosaur eggs are also part of the museum rules, and I don't want to touch them yet. + AnimalProduct.slime_egg_tiger: self.can_fish_pond(Fish.lionfish, *(Forageable.ginger, Fruit.pineapple, Fruit.mango)) & self.time.has_lived_months(12) & + self.building.has_building(Building.slime_hutch) & self.monster.can_kill(Monster.tiger_slime), + AnimalProduct.duck_egg_starter: self.logic.false_, # It could be purchased at the Feast of the Winter Star, but it's random every year, so not considering it yet... + AnimalProduct.dinosaur_egg_starter: self.logic.false_, # Dinosaur eggs are also part of the museum rules, and I don't want to touch them yet. AnimalProduct.egg_starter: self.logic.false_, # It could be purchased at the Desert Festival, but festival logic is quite a mess, so not considering it yet... AnimalProduct.golden_egg_starter: self.received(AnimalProduct.golden_egg) & (self.money.can_spend_at(Region.ranch, 100000) | self.money.can_trade_at(Region.qi_walnut_room, Currency.qi_gem, 100)), AnimalProduct.void_egg_starter: self.money.can_spend_at(Region.sewer, 5000) | (self.building.has_building(Building.fish_pond) & self.has(Fish.void_salmon)), @@ -233,7 +234,7 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC Forageable.secret_note: self.quest.has_magnifying_glass() & (self.ability.can_chop_trees() | self.mine.can_mine_in_the_mines_floor_1_40()), # Fossil.bone_fragment: (self.region.can_reach(Region.dig_site) & self.tool.has_tool(Tool.pickaxe)) | self.monster.can_kill(Monster.skeleton), Fossil.fossilized_leg: self.region.can_reach(Region.dig_site) & self.tool.has_tool(Tool.pickaxe), - Fossil.fossilized_ribs: self.region.can_reach(Region.island_south) & self.tool.has_tool(Tool.hoe), + Fossil.fossilized_ribs: self.region.can_reach(Region.island_south) & self.tool.has_tool(Tool.hoe) & self.received("Open Professor Snail Cave"), Fossil.fossilized_skull: self.action.can_open_geode(Geode.golden_coconut), Fossil.fossilized_spine: self.fishing.can_fish_at(Region.dig_site), Fossil.fossilized_tail: self.action.can_pan_at(Region.dig_site, ToolMaterial.copper), @@ -288,9 +289,9 @@ def __init__(self, player: int, options: StardewValleyOptions, content: StardewC MetalBar.quartz: self.can_smelt(Mineral.quartz) | self.can_smelt("Fire Quartz") | (self.has(Machine.recycling_machine) & (self.has(Trash.broken_cd) | self.has(Trash.broken_glasses))), MetalBar.radioactive: self.can_smelt(Ore.radioactive), Ore.copper: self.mine.can_mine_in_the_mines_floor_1_40() | self.mine.can_mine_in_the_skull_cavern() | self.tool.has_tool(Tool.pan, ToolMaterial.copper), - Ore.gold: self.mine.can_mine_in_the_mines_floor_81_120() | self.mine.can_mine_in_the_skull_cavern() | self.tool.has_tool(Tool.pan, ToolMaterial.iron), - Ore.iridium: self.mine.can_mine_in_the_skull_cavern() | self.can_fish_pond(Fish.super_cucumber) | self.tool.has_tool(Tool.pan, ToolMaterial.gold), - Ore.iron: self.mine.can_mine_in_the_mines_floor_41_80() | self.mine.can_mine_in_the_skull_cavern() | self.tool.has_tool(Tool.pan, ToolMaterial.copper), + Ore.gold: self.mine.can_mine_in_the_mines_floor_81_120() | self.mine.can_mine_in_the_skull_cavern() | self.tool.has_tool(Tool.pan, ToolMaterial.gold), + Ore.iridium: self.count(2, *(self.mine.can_mine_in_the_skull_cavern(), self.can_fish_pond(Fish.super_cucumber), self.tool.has_tool(Tool.pan, ToolMaterial.iridium))), + Ore.iron: self.mine.can_mine_in_the_mines_floor_41_80() | self.mine.can_mine_in_the_skull_cavern() | self.tool.has_tool(Tool.pan, ToolMaterial.iron), Ore.radioactive: self.ability.can_mine_perfectly() & self.region.can_reach(Region.qi_walnut_room), RetainingSoil.basic: self.money.can_spend_at(Region.pierre_store, 100), RetainingSoil.quality: self.time.has_year_two & self.money.can_spend_at(Region.pierre_store, 150), @@ -381,5 +382,8 @@ def has_movie_theater(self) -> StardewRule: def can_use_obelisk(self, obelisk: str) -> StardewRule: return self.region.can_reach(Region.farm) & self.received(obelisk) - def can_fish_pond(self, fish: str) -> StardewRule: - return self.building.has_building(Building.fish_pond) & self.has(fish) + def can_fish_pond(self, fish: str, *items: str) -> StardewRule: + rule = self.building.has_building(Building.fish_pond) & self.has(fish) + if items: + rule = rule & self.has_all(*items) + return rule diff --git a/worlds/stardew_valley/strings/monster_drop_names.py b/worlds/stardew_valley/strings/monster_drop_names.py index df2cacf0c6aa..8612b3c7b52c 100644 --- a/worlds/stardew_valley/strings/monster_drop_names.py +++ b/worlds/stardew_valley/strings/monster_drop_names.py @@ -1,9 +1,4 @@ class Loot: - blue_slime_egg = "Blue Slime Egg" - red_slime_egg = "Red Slime Egg" - purple_slime_egg = "Purple Slime Egg" - green_slime_egg = "Green Slime Egg" - tiger_slime_egg = "Tiger Slime Egg" slime = "Slime" bug_meat = "Bug Meat" bat_wing = "Bat Wing" diff --git a/worlds/stardew_valley/test/rules/TestFishing.py b/worlds/stardew_valley/test/rules/TestFishing.py index 3649592301c4..22e6321a7a93 100644 --- a/worlds/stardew_valley/test/rules/TestFishing.py +++ b/worlds/stardew_valley/test/rules/TestFishing.py @@ -8,7 +8,7 @@ class TestNeedRegionToCatchFish(SVTestBase): SeasonRandomization.internal_name: SeasonRandomization.option_disabled, ElevatorProgression.internal_name: ElevatorProgression.option_vanilla, SkillProgression.internal_name: SkillProgression.option_vanilla, - ToolProgression.internal_name: ToolProgression.option_vanilla, + ToolProgression.internal_name: ToolProgression.option_progressive, Fishsanity.internal_name: Fishsanity.option_all, ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_false, SpecialOrderLocations.internal_name: SpecialOrderLocations.option_board_qi, @@ -18,7 +18,7 @@ def test_catch_fish_requires_region_unlock(self): fish_and_items = { Fish.crimsonfish: ["Beach Bridge"], Fish.void_salmon: ["Railroad Boulder Removed", "Dark Talisman"], - Fish.woodskip: ["Glittering Boulder Removed", "Progressive Weapon"], # For the ores to get the axe upgrades + Fish.woodskip: ["Progressive Axe", "Progressive Axe", "Progressive Weapon"], # For the ores to get the axe upgrades Fish.mutant_carp: ["Rusty Key"], Fish.slimejack: ["Railroad Boulder Removed", "Rusty Key"], Fish.lionfish: ["Boat Repair"], @@ -26,8 +26,8 @@ def test_catch_fish_requires_region_unlock(self): Fish.stingray: ["Boat Repair", "Island Resort"], Fish.ghostfish: ["Progressive Weapon"], Fish.stonefish: ["Progressive Weapon"], - Fish.ice_pip: ["Progressive Weapon", "Progressive Weapon"], - Fish.lava_eel: ["Progressive Weapon", "Progressive Weapon", "Progressive Weapon"], + Fish.ice_pip: ["Progressive Weapon", "Progressive Weapon", "Progressive Pickaxe", "Progressive Pickaxe"], + Fish.lava_eel: ["Progressive Weapon", "Progressive Weapon", "Progressive Weapon", "Progressive Pickaxe", "Progressive Pickaxe", "Progressive Pickaxe"], Fish.sandfish: ["Bus Repair"], Fish.scorpion_carp: ["Desert Obelisk"], # Starting the extended family quest requires having caught all the legendaries before, so they all have the rules of every other legendary @@ -37,6 +37,7 @@ def test_catch_fish_requires_region_unlock(self): Fish.legend_ii: ["Beach Bridge", "Island Obelisk", "Island West Turtle", "Qi Walnut Room", "Rusty Key"], Fish.ms_angler: ["Beach Bridge", "Island Obelisk", "Island West Turtle", "Qi Walnut Room", "Rusty Key"], } + self.collect("Progressive Fishing Rod", 4) self.original_state = self.multiworld.state.copy() for fish in fish_and_items: with self.subTest(f"Region rules for {fish}"): From 2ff611167a4415f2d06b6904434e814cf6595174 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 14 Jun 2025 12:21:25 +0200 Subject: [PATCH 0511/1218] =?UTF-8?q?ALTTP:=20Fix=20take=5Fany=20leaving?= =?UTF-8?q?=20a=20placed=20item=20in=20the=20multiworld=20itempool=C2=A0#5?= =?UTF-8?q?108?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worlds/alttp/ItemPool.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/worlds/alttp/ItemPool.py b/worlds/alttp/ItemPool.py index 57ad01b9e408..9f1a58e5466d 100644 --- a/worlds/alttp/ItemPool.py +++ b/worlds/alttp/ItemPool.py @@ -548,10 +548,12 @@ def set_up_take_anys(multiworld, world, player): old_man_take_any.shop = TakeAny(old_man_take_any, 0x0112, 0xE2, True, True, total_shop_slots) multiworld.shops.append(old_man_take_any.shop) - swords = [item for item in multiworld.itempool if item.player == player and item.type == 'Sword'] - if swords: - sword = multiworld.random.choice(swords) - multiworld.itempool.remove(sword) + sword_indices = [ + index for index, item in enumerate(multiworld.itempool) if item.player == player and item.type == 'Sword' + ] + if sword_indices: + sword_index = multiworld.random.choice(sword_indices) + sword = multiworld.itempool.pop(sword_index) multiworld.itempool.append(item_factory('Rupees (20)', world)) old_man_take_any.shop.add_inventory(0, sword.name, 0, 0) loc_name = "Old Man Sword Cave" From 27a67705692e5abafbfc5dbd5753feb81294855c Mon Sep 17 00:00:00 2001 From: Louis M Date: Sat, 14 Jun 2025 07:17:33 -0400 Subject: [PATCH 0512/1218] Aquaria: Fixing open waters urns not breakable with nature forms logic bug (#5072) * Fixing open waters urns not breakable with nature forms logic bug * Using list in comprehension only when useful * Replacing damaging items by a constant * Removing comprehension list creating from lambda --- worlds/aquaria/Regions.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/worlds/aquaria/Regions.py b/worlds/aquaria/Regions.py index 40170e0c3262..3436374ac7ea 100755 --- a/worlds/aquaria/Regions.py +++ b/worlds/aquaria/Regions.py @@ -4,7 +4,7 @@ Description: Used to manage Regions in the Aquaria game multiworld randomizer """ -from typing import Dict, Optional +from typing import Dict, Optional, Iterable from BaseClasses import MultiWorld, Region, Entrance, Item, ItemClassification, CollectionState from .Items import AquariaItem, ItemNames from .Locations import AquariaLocations, AquariaLocation, AquariaLocationNames @@ -34,10 +34,15 @@ def _has_li(state: CollectionState, player: int) -> bool: return state.has(ItemNames.LI_AND_LI_SONG, player) -def _has_damaging_item(state: CollectionState, player: int) -> bool: - """`player` in `state` has the shield song item""" - return state.has_any({ItemNames.ENERGY_FORM, ItemNames.NATURE_FORM, ItemNames.BEAST_FORM, ItemNames.LI_AND_LI_SONG, - ItemNames.BABY_NAUTILUS, ItemNames.BABY_PIRANHA, ItemNames.BABY_BLASTER}, player) +DAMAGING_ITEMS:Iterable[str] = [ + ItemNames.ENERGY_FORM, ItemNames.NATURE_FORM, ItemNames.BEAST_FORM, + ItemNames.LI_AND_LI_SONG, ItemNames.BABY_NAUTILUS, ItemNames.BABY_PIRANHA, + ItemNames.BABY_BLASTER +] + +def _has_damaging_item(state: CollectionState, player: int, damaging_items:Iterable[str] = DAMAGING_ITEMS) -> bool: + """`player` in `state` has the an item that do damage other than the ones in `to_remove`""" + return state.has_any(damaging_items, player) def _has_energy_attack_item(state: CollectionState, player: int) -> bool: @@ -566,9 +571,11 @@ def __connect_open_water_regions(self) -> None: self.__connect_one_way_regions(self.openwater_tr, self.openwater_tr_turtle, lambda state: _has_beast_form_or_arnassi_armor(state, self.player)) self.__connect_one_way_regions(self.openwater_tr_turtle, self.openwater_tr) + damaging_items_minus_nature_form = [item for item in DAMAGING_ITEMS if item != ItemNames.NATURE_FORM] self.__connect_one_way_regions(self.openwater_tr, self.openwater_tr_urns, lambda state: _has_bind_song(state, self.player) or - _has_damaging_item(state, self.player)) + _has_damaging_item(state, self.player, + damaging_items_minus_nature_form)) self.__connect_regions(self.openwater_tr, self.openwater_br) self.__connect_regions(self.openwater_tr, self.mithalas_city) self.__connect_regions(self.openwater_tr, self.veil_b) From 3b72140435d4d587a60865ea5e325f5b6aa1d950 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 14 Jun 2025 09:26:22 -0400 Subject: [PATCH 0513/1218] Shivers: Fix get_pre_fill_items (#5113) --- worlds/shivers/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/shivers/__init__.py b/worlds/shivers/__init__.py index 3430a5a02d4e..dd941b9212bb 100644 --- a/worlds/shivers/__init__.py +++ b/worlds/shivers/__init__.py @@ -261,13 +261,13 @@ def get_pre_fill_items(self) -> List[Item]: data.type == ItemType.POT_DUPLICATE] elif self.options.full_pots == "complete": return [self.create_item(name) for name, data in item_table.items() if - data.type == ItemType.POT_COMPELTE_DUPLICATE] + data.type == ItemType.POT_COMPLETE_DUPLICATE] else: pool = [] pieces = [self.create_item(name) for name, data in item_table.items() if data.type == ItemType.POT_DUPLICATE] complete = [self.create_item(name) for name, data in item_table.items() if - data.type == ItemType.POT_COMPELTE_DUPLICATE] + data.type == ItemType.POT_COMPLETE_DUPLICATE] for i in range(10): if self.pot_completed_list[i] == 0: pool.append(pieces[i]) From ecb739ce96716f83d128648d0350df69b5aae7eb Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 14 Jun 2025 09:26:58 -0400 Subject: [PATCH 0514/1218] Plando Items: Fix Location Groups Unfolding (#5099) --- Fill.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fill.py b/Fill.py index 87d6b02e0921..9d460e49c4da 100644 --- a/Fill.py +++ b/Fill.py @@ -923,9 +923,9 @@ def failed(warning: str, force: bool | str) -> None: if isinstance(locations, str): locations = [locations] - locations_from_groups: list[str] = [] resolved_locations: list[Location] = [] for target_player in worlds: + locations_from_groups: list[str] = [] world_locations = multiworld.get_unfilled_locations(target_player) for group in multiworld.worlds[target_player].location_name_groups: if group in locations: From aa9e6175108afb16caec2411486e2f1a054ae4a6 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 14 Jun 2025 09:27:22 -0400 Subject: [PATCH 0515/1218] DS3: Apply Rules to Non-Randomized Locations (#5106) --- worlds/dark_souls_3/__init__.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 94150faf0571..6584ccec8778 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -75,6 +75,13 @@ class DarkSouls3World(World): """The pool of all items within this particular world. This is a subset of `self.multiworld.itempool`.""" + missable_dupe_prog_locs: Set[str] = {"PC: Storm Ruler - Siegward", + "US: Pyromancy Flame - Cornyx", + "US: Tower Key - kill Irina"} + """Locations whose vanilla item is a missable duplicate of a non-missable progression item. + If vanilla, these locations shouldn't be expected progression, so they aren't created and don't get rules. + """ + def __init__(self, multiworld: MultiWorld, player: int): super().__init__(multiworld, player) self.all_excluded_locations = set() @@ -258,10 +265,7 @@ def create_region(self, region_name, location_table) -> Region: new_location.progress_type = LocationProgressType.EXCLUDED else: # Don't allow missable duplicates of progression items to be expected progression. - if location.name in {"PC: Storm Ruler - Siegward", - "US: Pyromancy Flame - Cornyx", - "US: Tower Key - kill Irina"}: - continue + if location.name in self.missable_dupe_prog_locs: continue # Replace non-randomized items with events that give the default item event_item = ( @@ -1286,8 +1290,9 @@ def _add_location_rule(self, location: Union[str, List[str]], rule: Union[Collec data = location_dictionary[location] if data.dlc and not self.options.enable_dlc: continue if data.ngp and not self.options.enable_ngp: continue + # Don't add rules to missable duplicates of progression items + if location in self.missable_dupe_prog_locs and not self._is_location_available(location): continue - if not self._is_location_available(location): continue if isinstance(rule, str): assert item_dictionary[rule].classification == ItemClassification.progression rule = lambda state, item=rule: state.has(item, self.player) From ec5b4e704f8167dd262579120a9aa99d746ab04d Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 14 Jun 2025 09:28:02 -0400 Subject: [PATCH 0516/1218] Plando Items: Better Warning for Nonexisting Worlds (#5112) --- Fill.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fill.py b/Fill.py index 9d460e49c4da..abdad4407097 100644 --- a/Fill.py +++ b/Fill.py @@ -890,7 +890,7 @@ def failed(warning: str, force: bool | str) -> None: worlds = set() for listed_world in target_world: if listed_world not in world_name_lookup: - failed(f"Cannot place item to {target_world}'s world as that world does not exist.", + failed(f"Cannot place item to {listed_world}'s world as that world does not exist.", block.force) continue worlds.add(world_name_lookup[listed_world]) From 135647941527b601248b8ba1331a82732a685806 Mon Sep 17 00:00:00 2001 From: JusticePS <5125765+JusticePS@users.noreply.github.com> Date: Sun, 15 Jun 2025 16:30:45 -0700 Subject: [PATCH 0517/1218] AdventureClient: Replace Utils.get_settings with settings.get_settings #5043 --- AdventureClient.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/AdventureClient.py b/AdventureClient.py index 91567fc0a0e9..a4839c902dd0 100644 --- a/AdventureClient.py +++ b/AdventureClient.py @@ -11,6 +11,7 @@ import Utils +from settings import get_settings from NetUtils import ClientStatus from Utils import async_start from CommonClient import CommonContext, server_loop, gui_enabled, ClientCommandProcessor, logger, \ @@ -80,8 +81,8 @@ def __init__(self, server_address, password): self.local_item_locations = {} self.dragon_speed_info = {} - options = Utils.get_settings() - self.display_msgs = options["adventure_options"]["display_msgs"] + options = get_settings().adventure_options + self.display_msgs = options.display_msgs async def server_auth(self, password_requested: bool = False): if password_requested and not self.password: @@ -102,7 +103,7 @@ def _set_message(self, msg: str, msg_id: int): def on_package(self, cmd: str, args: dict): if cmd == 'Connected': self.locations_array = None - if Utils.get_settings()["adventure_options"].get("death_link", False): + if get_settings().adventure_options.as_dict().get("death_link", False): self.set_deathlink = True async_start(self.get_freeincarnates_used()) elif cmd == "RoomInfo": @@ -415,8 +416,9 @@ async def atari_sync_task(ctx: AdventureContext): async def run_game(romfile): - auto_start = Utils.get_settings()["adventure_options"].get("rom_start", True) - rom_args = Utils.get_settings()["adventure_options"].get("rom_args") + options = get_settings().adventure_options + auto_start = options.rom_start + rom_args = options.rom_args if auto_start is True: import webbrowser webbrowser.open(romfile) From b408bb4f6eedc797ac693e4a9aacc40b1922a2a7 Mon Sep 17 00:00:00 2001 From: qwint Date: Sun, 15 Jun 2025 19:31:12 -0500 Subject: [PATCH 0518/1218] Core: Docstring typo on Region.add_exits (#5089) * doc typo * Update BaseClasses.py --- BaseClasses.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 1de23bc1eab4..dbcd65ab55fa 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1337,8 +1337,8 @@ def add_exits(self, exits: Union[Iterable[str], Dict[str, Optional[str]]], Connects current region to regions in exit dictionary. Passed region names must exist first. :param exits: exits from the region. format is {"connecting_region": "exit_name"}. if a non dict is provided, - created entrances will be named "self.name -> connecting_region" - :param rules: rules for the exits from this region. format is {"connecting_region", rule} + created entrances will be named "self.name -> connecting_region" + :param rules: rules for the exits from this region. format is {"connecting_region": rule} """ if not isinstance(exits, Dict): exits = dict.fromkeys(exits) From 0e759f25fd4a241cbd1a8793ff0a891a2b3bc322 Mon Sep 17 00:00:00 2001 From: KonoTyran Date: Mon, 16 Jun 2025 03:31:16 -0700 Subject: [PATCH 0519/1218] Remove Minecraft (#4672) * Remove Minecraft * remove minecraft * remove minecraft * elif -> if --------- Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- .gitignore | 7 - MinecraftClient.py | 347 ---- README.md | 1 - WebHostLib/downloads.py | 7 +- WebHostLib/static/styles/minecraftTracker.css | 102 -- WebHostLib/templates/macros.html | 5 +- WebHostLib/templates/tracker__Minecraft.html | 84 - WebHostLib/tracker.py | 121 -- WebHostLib/upload.py | 5 - data/mcicon.ico | Bin 2686 -> 0 bytes docs/CODEOWNERS | 3 - docs/network diagram/network diagram.md | 6 - inno_setup.iss | 5 - worlds/LauncherComponents.py | 4 - worlds/generic/docs/advanced_settings_en.md | 29 +- worlds/generic/docs/plando_en.md | 14 +- worlds/minecraft/Constants.py | 26 - worlds/minecraft/ItemPool.py | 55 - worlds/minecraft/Options.py | 143 -- worlds/minecraft/Rules.py | 508 ------ worlds/minecraft/Structures.py | 59 - worlds/minecraft/__init__.py | 203 --- worlds/minecraft/data/excluded_locations.json | 40 - worlds/minecraft/data/items.json | 128 -- worlds/minecraft/data/locations.json | 250 --- worlds/minecraft/data/regions.json | 28 - worlds/minecraft/docs/en_Minecraft.md | 113 -- worlds/minecraft/docs/minecraft_en.md | 74 - worlds/minecraft/docs/minecraft_es.md | 148 -- worlds/minecraft/docs/minecraft_fr.md | 74 - worlds/minecraft/docs/minecraft_sv.md | 132 -- worlds/minecraft/requirements.txt | 1 - worlds/minecraft/test/TestAdvancements.py | 1410 ----------------- worlds/minecraft/test/TestDataLoad.py | 60 - worlds/minecraft/test/TestEntrances.py | 97 -- worlds/minecraft/test/TestOptions.py | 49 - worlds/minecraft/test/__init__.py | 33 - 37 files changed, 6 insertions(+), 4365 deletions(-) delete mode 100644 MinecraftClient.py delete mode 100644 WebHostLib/static/styles/minecraftTracker.css delete mode 100644 WebHostLib/templates/tracker__Minecraft.html delete mode 100644 data/mcicon.ico delete mode 100644 worlds/minecraft/Constants.py delete mode 100644 worlds/minecraft/ItemPool.py delete mode 100644 worlds/minecraft/Options.py delete mode 100644 worlds/minecraft/Rules.py delete mode 100644 worlds/minecraft/Structures.py delete mode 100644 worlds/minecraft/__init__.py delete mode 100644 worlds/minecraft/data/excluded_locations.json delete mode 100644 worlds/minecraft/data/items.json delete mode 100644 worlds/minecraft/data/locations.json delete mode 100644 worlds/minecraft/data/regions.json delete mode 100644 worlds/minecraft/docs/en_Minecraft.md delete mode 100644 worlds/minecraft/docs/minecraft_en.md delete mode 100644 worlds/minecraft/docs/minecraft_es.md delete mode 100644 worlds/minecraft/docs/minecraft_fr.md delete mode 100644 worlds/minecraft/docs/minecraft_sv.md delete mode 100644 worlds/minecraft/requirements.txt delete mode 100644 worlds/minecraft/test/TestAdvancements.py delete mode 100644 worlds/minecraft/test/TestDataLoad.py delete mode 100644 worlds/minecraft/test/TestEntrances.py delete mode 100644 worlds/minecraft/test/TestOptions.py delete mode 100644 worlds/minecraft/test/__init__.py diff --git a/.gitignore b/.gitignore index f50fc17e23c6..3bb4e68c9924 100644 --- a/.gitignore +++ b/.gitignore @@ -56,7 +56,6 @@ success.txt output/ Output Logs/ /factorio/ -/Minecraft Forge Server/ /WebHostLib/static/generated /freeze_requirements.txt /Archipelago.zip @@ -184,12 +183,6 @@ _speedups.c _speedups.cpp _speedups.html -# minecraft server stuff -jdk*/ -minecraft*/ -minecraft_versions.json -!worlds/minecraft/ - # pyenv .python-version diff --git a/MinecraftClient.py b/MinecraftClient.py deleted file mode 100644 index 3047dc540e86..000000000000 --- a/MinecraftClient.py +++ /dev/null @@ -1,347 +0,0 @@ -import argparse -import json -import os -import sys -import re -import atexit -import shutil -from subprocess import Popen -from shutil import copyfile -from time import strftime -import logging - -import requests - -import Utils -from Utils import is_windows -from settings import get_settings - -atexit.register(input, "Press enter to exit.") - -# 1 or more digits followed by m or g, then optional b -max_heap_re = re.compile(r"^\d+[mMgG][bB]?$") - - -def prompt_yes_no(prompt): - yes_inputs = {'yes', 'ye', 'y'} - no_inputs = {'no', 'n'} - while True: - choice = input(prompt + " [y/n] ").lower() - if choice in yes_inputs: - return True - elif choice in no_inputs: - return False - else: - print('Please respond with "y" or "n".') - - -def find_ap_randomizer_jar(forge_dir): - """Create mods folder if needed; find AP randomizer jar; return None if not found.""" - mods_dir = os.path.join(forge_dir, 'mods') - if os.path.isdir(mods_dir): - for entry in os.scandir(mods_dir): - if entry.name.startswith("aprandomizer") and entry.name.endswith(".jar"): - logging.info(f"Found AP randomizer mod: {entry.name}") - return entry.name - return None - else: - os.mkdir(mods_dir) - logging.info(f"Created mods folder in {forge_dir}") - return None - - -def replace_apmc_files(forge_dir, apmc_file): - """Create APData folder if needed; clean .apmc files from APData; copy given .apmc into directory.""" - if apmc_file is None: - return - apdata_dir = os.path.join(forge_dir, 'APData') - copy_apmc = True - if not os.path.isdir(apdata_dir): - os.mkdir(apdata_dir) - logging.info(f"Created APData folder in {forge_dir}") - for entry in os.scandir(apdata_dir): - if entry.name.endswith(".apmc") and entry.is_file(): - if not os.path.samefile(apmc_file, entry.path): - os.remove(entry.path) - logging.info(f"Removed {entry.name} in {apdata_dir}") - else: # apmc already in apdata - copy_apmc = False - if copy_apmc: - copyfile(apmc_file, os.path.join(apdata_dir, os.path.basename(apmc_file))) - logging.info(f"Copied {os.path.basename(apmc_file)} to {apdata_dir}") - - -def read_apmc_file(apmc_file): - from base64 import b64decode - - with open(apmc_file, 'r') as f: - return json.loads(b64decode(f.read())) - - -def update_mod(forge_dir, url: str): - """Check mod version, download new mod from GitHub releases page if needed. """ - ap_randomizer = find_ap_randomizer_jar(forge_dir) - os.path.basename(url) - if ap_randomizer is not None: - logging.info(f"Your current mod is {ap_randomizer}.") - else: - logging.info(f"You do not have the AP randomizer mod installed.") - - if ap_randomizer != os.path.basename(url): - logging.info(f"A new release of the Minecraft AP randomizer mod was found: " - f"{os.path.basename(url)}") - if prompt_yes_no("Would you like to update?"): - old_ap_mod = os.path.join(forge_dir, 'mods', ap_randomizer) if ap_randomizer is not None else None - new_ap_mod = os.path.join(forge_dir, 'mods', os.path.basename(url)) - logging.info("Downloading AP randomizer mod. This may take a moment...") - apmod_resp = requests.get(url) - if apmod_resp.status_code == 200: - with open(new_ap_mod, 'wb') as f: - f.write(apmod_resp.content) - logging.info(f"Wrote new mod file to {new_ap_mod}") - if old_ap_mod is not None: - os.remove(old_ap_mod) - logging.info(f"Removed old mod file from {old_ap_mod}") - else: - logging.error(f"Error retrieving the randomizer mod (status code {apmod_resp.status_code}).") - logging.error(f"Please report this issue on the Archipelago Discord server.") - sys.exit(1) - - -def check_eula(forge_dir): - """Check if the EULA is agreed to, and prompt the user to read and agree if necessary.""" - eula_path = os.path.join(forge_dir, "eula.txt") - if not os.path.isfile(eula_path): - # Create eula.txt - with open(eula_path, 'w') as f: - f.write("#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).\n") - f.write(f"#{strftime('%a %b %d %X %Z %Y')}\n") - f.write("eula=false\n") - with open(eula_path, 'r+') as f: - text = f.read() - if 'false' in text: - # Prompt user to agree to the EULA - logging.info("You need to agree to the Minecraft EULA in order to run the server.") - logging.info("The EULA can be found at https://account.mojang.com/documents/minecraft_eula") - if prompt_yes_no("Do you agree to the EULA?"): - f.seek(0) - f.write(text.replace('false', 'true')) - f.truncate() - logging.info(f"Set {eula_path} to true") - else: - sys.exit(0) - - -def find_jdk_dir(version: str) -> str: - """get the specified versions jdk directory""" - for entry in os.listdir(): - if os.path.isdir(entry) and entry.startswith(f"jdk{version}"): - return os.path.abspath(entry) - - -def find_jdk(version: str) -> str: - """get the java exe location""" - - if is_windows: - jdk = find_jdk_dir(version) - jdk_exe = os.path.join(jdk, "bin", "java.exe") - if os.path.isfile(jdk_exe): - return jdk_exe - else: - jdk_exe = shutil.which(options.java) - if not jdk_exe: - jdk_exe = shutil.which("java") # try to fall back to system java - if not jdk_exe: - raise Exception("Could not find Java. Is Java installed on the system?") - return jdk_exe - - -def download_java(java: str): - """Download Corretto (Amazon JDK)""" - - jdk = find_jdk_dir(java) - if jdk is not None: - print(f"Removing old JDK...") - from shutil import rmtree - rmtree(jdk) - - print(f"Downloading Java...") - jdk_url = f"https://corretto.aws/downloads/latest/amazon-corretto-{java}-x64-windows-jdk.zip" - resp = requests.get(jdk_url) - if resp.status_code == 200: # OK - print(f"Extracting...") - import zipfile - from io import BytesIO - with zipfile.ZipFile(BytesIO(resp.content)) as zf: - zf.extractall() - else: - print(f"Error downloading Java (status code {resp.status_code}).") - print(f"If this was not expected, please report this issue on the Archipelago Discord server.") - if not prompt_yes_no("Continue anyways?"): - sys.exit(0) - - -def install_forge(directory: str, forge_version: str, java_version: str): - """download and install forge""" - - java_exe = find_jdk(java_version) - if java_exe is not None: - print(f"Downloading Forge {forge_version}...") - forge_url = f"https://maven.minecraftforge.net/net/minecraftforge/forge/{forge_version}/forge-{forge_version}-installer.jar" - resp = requests.get(forge_url) - if resp.status_code == 200: # OK - forge_install_jar = os.path.join(directory, "forge_install.jar") - if not os.path.exists(directory): - os.mkdir(directory) - with open(forge_install_jar, 'wb') as f: - f.write(resp.content) - print(f"Installing Forge...") - install_process = Popen([java_exe, "-jar", forge_install_jar, "--installServer", directory]) - install_process.wait() - os.remove(forge_install_jar) - - -def run_forge_server(forge_dir: str, java_version: str, heap_arg: str) -> Popen: - """Run the Forge server.""" - - java_exe = find_jdk(java_version) - if not os.path.isfile(java_exe): - java_exe = "java" # try to fall back on java in the PATH - - heap_arg = max_heap_re.match(heap_arg).group() - if heap_arg[-1] in ['b', 'B']: - heap_arg = heap_arg[:-1] - heap_arg = "-Xmx" + heap_arg - - os_args = "win_args.txt" if is_windows else "unix_args.txt" - args_file = os.path.join(forge_dir, "libraries", "net", "minecraftforge", "forge", forge_version, os_args) - forge_args = [] - with open(args_file) as argfile: - for line in argfile: - forge_args.extend(line.strip().split(" ")) - - args = [java_exe, heap_arg, *forge_args, "-nogui"] - logging.info(f"Running Forge server: {args}") - os.chdir(forge_dir) - return Popen(args) - - -def get_minecraft_versions(version, release_channel="release"): - version_file_endpoint = "https://raw.githubusercontent.com/KonoTyran/Minecraft_AP_Randomizer/master/versions/minecraft_versions.json" - resp = requests.get(version_file_endpoint) - local = False - if resp.status_code == 200: # OK - try: - data = resp.json() - except requests.exceptions.JSONDecodeError: - logging.warning(f"Unable to fetch version update file, using local version. (status code {resp.status_code}).") - local = True - else: - logging.warning(f"Unable to fetch version update file, using local version. (status code {resp.status_code}).") - local = True - - if local: - with open(Utils.user_path("minecraft_versions.json"), 'r') as f: - data = json.load(f) - else: - with open(Utils.user_path("minecraft_versions.json"), 'w') as f: - json.dump(data, f) - - try: - if version: - return next(filter(lambda entry: entry["version"] == version, data[release_channel])) - else: - return resp.json()[release_channel][0] - except (StopIteration, KeyError): - logging.error(f"No compatible mod version found for client version {version} on \"{release_channel}\" channel.") - if release_channel != "release": - logging.error("Consider switching \"release_channel\" to \"release\" in your Host.yaml file") - else: - logging.error("No suitable mod found on the \"release\" channel. Please Contact us on discord to report this error.") - sys.exit(0) - - -def is_correct_forge(forge_dir) -> bool: - if os.path.isdir(os.path.join(forge_dir, "libraries", "net", "minecraftforge", "forge", forge_version)): - return True - return False - - -if __name__ == '__main__': - Utils.init_logging("MinecraftClient") - parser = argparse.ArgumentParser() - parser.add_argument("apmc_file", default=None, nargs='?', help="Path to an Archipelago Minecraft data file (.apmc)") - parser.add_argument('--install', '-i', dest='install', default=False, action='store_true', - help="Download and install Java and the Forge server. Does not launch the client afterwards.") - parser.add_argument('--release_channel', '-r', dest="channel", type=str, action='store', - help="Specify release channel to use.") - parser.add_argument('--java', '-j', metavar='17', dest='java', type=str, default=False, action='store', - help="specify java version.") - parser.add_argument('--forge', '-f', metavar='1.18.2-40.1.0', dest='forge', type=str, default=False, action='store', - help="specify forge version. (Minecraft Version-Forge Version)") - parser.add_argument('--version', '-v', metavar='9', dest='data_version', type=int, action='store', - help="specify Mod data version to download.") - - args = parser.parse_args() - apmc_file = os.path.abspath(args.apmc_file) if args.apmc_file else None - - # Change to executable's working directory - os.chdir(os.path.abspath(os.path.dirname(sys.argv[0]))) - - options = get_settings().minecraft_options - channel = args.channel or options.release_channel - apmc_data = None - data_version = args.data_version or None - - if apmc_file is None and not args.install: - apmc_file = Utils.open_filename('Select APMC file', (('APMC File', ('.apmc',)),)) - - if apmc_file is not None and data_version is None: - apmc_data = read_apmc_file(apmc_file) - data_version = apmc_data.get('client_version', '') - - versions = get_minecraft_versions(data_version, channel) - - forge_dir = options.forge_directory - max_heap = options.max_heap_size - forge_version = args.forge or versions["forge"] - java_version = args.java or versions["java"] - mod_url = versions["url"] - java_dir = find_jdk_dir(java_version) - - if args.install: - if is_windows: - print("Installing Java") - download_java(java_version) - if not is_correct_forge(forge_dir): - print("Installing Minecraft Forge") - install_forge(forge_dir, forge_version, java_version) - else: - print("Correct Forge version already found, skipping install.") - sys.exit(0) - - if apmc_data is None: - raise FileNotFoundError(f"APMC file does not exist or is inaccessible at the given location ({apmc_file})") - - if is_windows: - if java_dir is None or not os.path.isdir(java_dir): - if prompt_yes_no("Did not find java directory. Download and install java now?"): - download_java(java_version) - java_dir = find_jdk_dir(java_version) - if java_dir is None or not os.path.isdir(java_dir): - raise NotADirectoryError(f"Path {java_dir} does not exist or could not be accessed.") - - if not is_correct_forge(forge_dir): - if prompt_yes_no(f"Did not find forge version {forge_version} download and install it now?"): - install_forge(forge_dir, forge_version, java_version) - if not os.path.isdir(forge_dir): - raise NotADirectoryError(f"Path {forge_dir} does not exist or could not be accessed.") - - if not max_heap_re.match(max_heap): - raise Exception(f"Max heap size {max_heap} in incorrect format. Use a number followed by M or G, e.g. 512M or 2G.") - - update_mod(forge_dir, mod_url) - replace_apmc_files(forge_dir, apmc_file) - check_eula(forge_dir) - server_process = run_forge_server(forge_dir, java_version, max_heap) - server_process.wait() diff --git a/README.md b/README.md index 9ce6caf0cfc7..afad4b15f0b7 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ Currently, the following games are supported: * The Legend of Zelda: A Link to the Past * Factorio -* Minecraft * Subnautica * Risk of Rain 2 * The Legend of Zelda: Ocarina of Time diff --git a/WebHostLib/downloads.py b/WebHostLib/downloads.py index a09ca7017181..388a6dc73cb1 100644 --- a/WebHostLib/downloads.py +++ b/WebHostLib/downloads.py @@ -61,12 +61,7 @@ def download_slot_file(room_id, player_id: int): else: import io - if slot_data.game == "Minecraft": - from worlds.minecraft import mc_update_output - fname = f"AP_{app.jinja_env.filters['suuid'](room_id)}_P{slot_data.player_id}_{slot_data.player_name}.apmc" - data = mc_update_output(slot_data.data, server=app.config['HOST_ADDRESS'], port=room.last_port) - return send_file(io.BytesIO(data), as_attachment=True, download_name=fname) - elif slot_data.game == "Factorio": + if slot_data.game == "Factorio": with zipfile.ZipFile(io.BytesIO(slot_data.data)) as zf: for name in zf.namelist(): if name.endswith("info.json"): diff --git a/WebHostLib/static/styles/minecraftTracker.css b/WebHostLib/static/styles/minecraftTracker.css deleted file mode 100644 index 224cdcdc55a0..000000000000 --- a/WebHostLib/static/styles/minecraftTracker.css +++ /dev/null @@ -1,102 +0,0 @@ -#player-tracker-wrapper{ - margin: 0; -} - -#inventory-table{ - border-top: 2px solid #000000; - border-left: 2px solid #000000; - border-right: 2px solid #000000; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - padding: 3px 3px 10px; - width: 384px; - background-color: #42b149; -} - -#inventory-table td{ - width: 40px; - height: 40px; - text-align: center; - vertical-align: middle; -} - -#inventory-table img{ - height: 100%; - max-width: 40px; - max-height: 40px; - filter: grayscale(100%) contrast(75%) brightness(30%); -} - -#inventory-table img.acquired{ - filter: none; -} - -#inventory-table div.counted-item { - position: relative; -} - -#inventory-table div.item-count { - position: absolute; - color: white; - font-family: "Minecraftia", monospace; - font-weight: bold; - bottom: 0; - right: 0; -} - -#location-table{ - width: 384px; - border-left: 2px solid #000000; - border-right: 2px solid #000000; - border-bottom: 2px solid #000000; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - background-color: #42b149; - padding: 0 3px 3px; - font-family: "Minecraftia", monospace; - font-size: 14px; - cursor: default; -} - -#location-table th{ - vertical-align: middle; - text-align: left; - padding-right: 10px; -} - -#location-table td{ - padding-top: 2px; - padding-bottom: 2px; - line-height: 20px; -} - -#location-table td.counter { - text-align: right; - font-size: 14px; -} - -#location-table td.toggle-arrow { - text-align: right; -} - -#location-table tr#Total-header { - font-weight: bold; -} - -#location-table img{ - height: 100%; - max-width: 30px; - max-height: 30px; -} - -#location-table tbody.locations { - font-size: 12px; -} - -#location-table td.location-name { - padding-left: 16px; -} - -.hide { - display: none; -} diff --git a/WebHostLib/templates/macros.html b/WebHostLib/templates/macros.html index 0416658dde28..be664274e621 100644 --- a/WebHostLib/templates/macros.html +++ b/WebHostLib/templates/macros.html @@ -26,10 +26,7 @@ {{ patch.game }} {% if patch.data %} - {% if patch.game == "Minecraft" %} - - Download APMC File... - {% elif patch.game == "VVVVVV" and room.seed.slots|length == 1 %} + {% if patch.game == "VVVVVV" and room.seed.slots|length == 1 %} Download APV6 File... {% elif patch.game == "Super Mario 64" and room.seed.slots|length == 1 %} diff --git a/WebHostLib/templates/tracker__Minecraft.html b/WebHostLib/templates/tracker__Minecraft.html deleted file mode 100644 index 248f2778bda1..000000000000 --- a/WebHostLib/templates/tracker__Minecraft.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - {{ player_name }}'s Tracker - - - - - - - {# TODO: Replace this with a proper wrapper for each tracker when developing TrackerAPI. #} - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - -
    {{ pearls_count }}
    -
    -
    -
    - -
    {{ scrap_count }}
    -
    -
    -
    - -
    {{ shard_count }}
    -
    -
    - - {% for area in checks_done %} - - - - - - {% for location in location_info[area] %} - - - - - {% endfor %} - - {% endfor %} -
    {{ area }} {{'▼' if area != 'Total'}}{{ checks_done[area] }} / {{ checks_in_area[area] }}
    {{ location }}{{ '✔' if location_info[area][location] else '' }}
    -
    - - diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py index 3748de97a4bf..4b92f4b416ba 100644 --- a/WebHostLib/tracker.py +++ b/WebHostLib/tracker.py @@ -706,127 +706,6 @@ def render_ALinkToThePast_tracker(tracker_data: TrackerData, team: int, player: _multiworld_trackers["A Link to the Past"] = render_ALinkToThePast_multiworld_tracker _player_trackers["A Link to the Past"] = render_ALinkToThePast_tracker -if "Minecraft" in network_data_package["games"]: - def render_Minecraft_tracker(tracker_data: TrackerData, team: int, player: int) -> str: - icons = { - "Wooden Pickaxe": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/d/d2/Wooden_Pickaxe_JE3_BE3.png", - "Stone Pickaxe": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/c/c4/Stone_Pickaxe_JE2_BE2.png", - "Iron Pickaxe": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/d/d1/Iron_Pickaxe_JE3_BE2.png", - "Diamond Pickaxe": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/e/e7/Diamond_Pickaxe_JE3_BE3.png", - "Wooden Sword": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/d/d5/Wooden_Sword_JE2_BE2.png", - "Stone Sword": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/b/b1/Stone_Sword_JE2_BE2.png", - "Iron Sword": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/8/8e/Iron_Sword_JE2_BE2.png", - "Diamond Sword": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/4/44/Diamond_Sword_JE3_BE3.png", - "Leather Tunic": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/b/b7/Leather_Tunic_JE4_BE2.png", - "Iron Chestplate": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/3/31/Iron_Chestplate_JE2_BE2.png", - "Diamond Chestplate": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/e/e0/Diamond_Chestplate_JE3_BE2.png", - "Iron Ingot": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/f/fc/Iron_Ingot_JE3_BE2.png", - "Block of Iron": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/7/7e/Block_of_Iron_JE4_BE3.png", - "Brewing Stand": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/b/b3/Brewing_Stand_%28empty%29_JE10.png", - "Ender Pearl": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/f/f6/Ender_Pearl_JE3_BE2.png", - "Bucket": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/f/fc/Bucket_JE2_BE2.png", - "Bow": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/a/ab/Bow_%28Pull_2%29_JE1_BE1.png", - "Shield": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/c/c6/Shield_JE2_BE1.png", - "Red Bed": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/6/6a/Red_Bed_%28N%29.png", - "Netherite Scrap": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/3/33/Netherite_Scrap_JE2_BE1.png", - "Flint and Steel": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/9/94/Flint_and_Steel_JE4_BE2.png", - "Enchanting Table": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/3/31/Enchanting_Table.gif", - "Fishing Rod": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/7/7f/Fishing_Rod_JE2_BE2.png", - "Campfire": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/9/91/Campfire_JE2_BE2.gif", - "Water Bottle": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/7/75/Water_Bottle_JE2_BE2.png", - "Spyglass": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/c/c1/Spyglass_JE2_BE1.png", - "Dragon Egg Shard": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/3/38/Dragon_Egg_JE4.png", - "Lead": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/1/1f/Lead_JE2_BE2.png", - "Saddle": "https://i.imgur.com/2QtDyR0.png", - "Channeling Book": "https://i.imgur.com/J3WsYZw.png", - "Silk Touch Book": "https://i.imgur.com/iqERxHQ.png", - "Piercing IV Book": "https://i.imgur.com/OzJptGz.png", - } - - minecraft_location_ids = { - "Story": [42073, 42023, 42027, 42039, 42002, 42009, 42010, 42070, - 42041, 42049, 42004, 42031, 42025, 42029, 42051, 42077], - "Nether": [42017, 42044, 42069, 42058, 42034, 42060, 42066, 42076, 42064, 42071, 42021, - 42062, 42008, 42061, 42033, 42011, 42006, 42019, 42000, 42040, 42001, 42015, 42104, 42014], - "The End": [42052, 42005, 42012, 42032, 42030, 42042, 42018, 42038, 42046], - "Adventure": [42047, 42050, 42096, 42097, 42098, 42059, 42055, 42072, 42003, 42109, 42035, 42016, 42020, - 42048, 42054, 42068, 42043, 42106, 42074, 42075, 42024, 42026, 42037, 42045, 42056, 42105, - 42099, 42103, 42110, 42100], - "Husbandry": [42065, 42067, 42078, 42022, 42113, 42107, 42007, 42079, 42013, 42028, 42036, 42108, 42111, - 42112, - 42057, 42063, 42053, 42102, 42101, 42092, 42093, 42094, 42095], - "Archipelago": [42080, 42081, 42082, 42083, 42084, 42085, 42086, 42087, 42088, 42089, 42090, 42091], - } - - display_data = {} - - # Determine display for progressive items - progressive_items = { - "Progressive Tools": 45013, - "Progressive Weapons": 45012, - "Progressive Armor": 45014, - "Progressive Resource Crafting": 45001 - } - progressive_names = { - "Progressive Tools": ["Wooden Pickaxe", "Stone Pickaxe", "Iron Pickaxe", "Diamond Pickaxe"], - "Progressive Weapons": ["Wooden Sword", "Stone Sword", "Iron Sword", "Diamond Sword"], - "Progressive Armor": ["Leather Tunic", "Iron Chestplate", "Diamond Chestplate"], - "Progressive Resource Crafting": ["Iron Ingot", "Iron Ingot", "Block of Iron"] - } - - inventory = tracker_data.get_player_inventory_counts(team, player) - for item_name, item_id in progressive_items.items(): - level = min(inventory[item_id], len(progressive_names[item_name]) - 1) - display_name = progressive_names[item_name][level] - base_name = item_name.split(maxsplit=1)[1].lower().replace(" ", "_") - display_data[base_name + "_url"] = icons[display_name] - - # Multi-items - multi_items = { - "3 Ender Pearls": 45029, - "8 Netherite Scrap": 45015, - "Dragon Egg Shard": 45043 - } - for item_name, item_id in multi_items.items(): - base_name = item_name.split()[-1].lower() - count = inventory[item_id] - if count >= 0: - display_data[base_name + "_count"] = count - - # Victory condition - game_state = tracker_data.get_player_client_status(team, player) - display_data["game_finished"] = game_state == 30 - - # Turn location IDs into advancement tab counts - checked_locations = tracker_data.get_player_checked_locations(team, player) - lookup_name = lambda id: tracker_data.location_id_to_name["Minecraft"][id] - location_info = {tab_name: {lookup_name(id): (id in checked_locations) for id in tab_locations} - for tab_name, tab_locations in minecraft_location_ids.items()} - checks_done = {tab_name: len([id for id in tab_locations if id in checked_locations]) - for tab_name, tab_locations in minecraft_location_ids.items()} - checks_done["Total"] = len(checked_locations) - checks_in_area = {tab_name: len(tab_locations) for tab_name, tab_locations in minecraft_location_ids.items()} - checks_in_area["Total"] = sum(checks_in_area.values()) - - lookup_any_item_id_to_name = tracker_data.item_id_to_name["Minecraft"] - return render_template( - "tracker__Minecraft.html", - inventory=inventory, - icons=icons, - acquired_items={lookup_any_item_id_to_name[id] for id, count in inventory.items() if count > 0}, - player=player, - team=team, - room=tracker_data.room, - player_name=tracker_data.get_player_name(team, player), - saving_second=tracker_data.get_room_saving_second(), - checks_done=checks_done, - checks_in_area=checks_in_area, - location_info=location_info, - **display_data, - ) - - _player_trackers["Minecraft"] = render_Minecraft_tracker - if "Ocarina of Time" in network_data_package["games"]: def render_OcarinaOfTime_tracker(tracker_data: TrackerData, team: int, player: int) -> str: icons = { diff --git a/WebHostLib/upload.py b/WebHostLib/upload.py index 66b6f5560bae..ee4ba6a53e71 100644 --- a/WebHostLib/upload.py +++ b/WebHostLib/upload.py @@ -135,11 +135,6 @@ def upload_zip_to_db(zfile: zipfile.ZipFile, owner=None, meta={"race": False}, s flash("Could not load multidata. File may be corrupted or incompatible.") multidata = None - # Minecraft - elif file.filename.endswith(".apmc"): - data = zfile.open(file, "r").read() - metadata = json.loads(base64.b64decode(data).decode("utf-8")) - files[metadata["player_id"]] = data # Factorio elif file.filename.endswith(".zip"): diff --git a/data/mcicon.ico b/data/mcicon.ico deleted file mode 100644 index 3df0be06f8b021c3d207262d9d48e45ea08acd48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2686 zcmeH{v1-FW42J(grc!W1pxtjWWc1Q0c(|==ycDlBeS=%`R(_8_hCV|Uzd<6M;@Yk) z(+;8pqHrhU@1*}fVFEnRFVB~>FYx&YJOfB+<+S#+`2AcwrLS0TcX)aGzqR>lhxpN_S3eAHp=k7%jVoZ6k<#IQfueca`u;tDbh4;>7F?jx+ z2mTuDc?hlg*aPcZ^G?00#6gzH9K2_JYu;*#df$W0- JMC - end - JM <-- Forge Mod Loader --> MCS end AS <-- WebSockets --> JM diff --git a/inno_setup.iss b/inno_setup.iss index d9d4d7fb0178..6f41b20496a1 100644 --- a/inno_setup.iss +++ b/inno_setup.iss @@ -138,11 +138,6 @@ Root: HKCR; Subkey: "{#MyAppName}kdl3patch"; ValueData: "Arc Root: HKCR; Subkey: "{#MyAppName}kdl3patch\DefaultIcon"; ValueData: "{app}\ArchipelagoSNIClient.exe,0"; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}kdl3patch\shell\open\command"; ValueData: """{app}\ArchipelagoSNIClient.exe"" ""%1"""; ValueType: string; ValueName: ""; -Root: HKCR; Subkey: ".apmc"; ValueData: "{#MyAppName}mcdata"; Flags: uninsdeletevalue; ValueType: string; ValueName: ""; -Root: HKCR; Subkey: "{#MyAppName}mcdata"; ValueData: "Archipelago Minecraft Data"; Flags: uninsdeletekey; ValueType: string; ValueName: ""; -Root: HKCR; Subkey: "{#MyAppName}mcdata\DefaultIcon"; ValueData: "{app}\ArchipelagoMinecraftClient.exe,0"; ValueType: string; ValueName: ""; -Root: HKCR; Subkey: "{#MyAppName}mcdata\shell\open\command"; ValueData: """{app}\ArchipelagoMinecraftClient.exe"" ""%1"""; ValueType: string; ValueName: ""; - Root: HKCR; Subkey: ".apz5"; ValueData: "{#MyAppName}n64zpf"; Flags: uninsdeletevalue; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}n64zpf"; ValueData: "Archipelago Ocarina of Time Patch"; Flags: uninsdeletekey; ValueType: string; ValueName: ""; Root: HKCR; Subkey: "{#MyAppName}n64zpf\DefaultIcon"; ValueData: "{app}\ArchipelagoOoTClient.exe,0"; ValueType: string; ValueName: ""; diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index e650889a7377..06c77ab060e3 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -221,9 +221,6 @@ def install_apworld(apworld_path: str = "") -> None: Component('Links Awakening DX Client', 'LinksAwakeningClient', file_identifier=SuffixIdentifier('.apladx')), Component('LttP Adjuster', 'LttPAdjuster'), - # Minecraft - Component('Minecraft Client', 'MinecraftClient', icon='mcicon', cli=True, - file_identifier=SuffixIdentifier('.apmc')), # Ocarina of Time Component('OoT Client', 'OoTClient', file_identifier=SuffixIdentifier('.apz5')), @@ -246,6 +243,5 @@ def install_apworld(apworld_path: str = "") -> None: # if registering an icon from within an apworld, the format "ap:module.name/path/to/file.png" can be used icon_paths = { 'icon': local_path('data', 'icon.png'), - 'mcicon': local_path('data', 'mcicon.png'), 'discord': local_path('data', 'discord-mark-blue.png'), } diff --git a/worlds/generic/docs/advanced_settings_en.md b/worlds/generic/docs/advanced_settings_en.md index 6f0520febc6e..db93981bc9c8 100644 --- a/worlds/generic/docs/advanced_settings_en.md +++ b/worlds/generic/docs/advanced_settings_en.md @@ -288,7 +288,7 @@ world and the beginning of another world. You can also combine multiple files by ### Example ```yaml -description: Example of generating multiple worlds. World 1 of 3 +description: Example of generating multiple worlds. World 1 of 2 name: Mario game: Super Mario 64 requires: @@ -310,31 +310,6 @@ Super Mario 64: --- -description: Example of generating multiple worlds. World 2 of 3 -name: Minecraft -game: Minecraft -Minecraft: - progression_balancing: 50 - accessibility: items - advancement_goal: 40 - combat_difficulty: hard - include_hard_advancements: false - include_unreasonable_advancements: false - include_postgame_advancements: false - shuffle_structures: true - structure_compasses: true - send_defeated_mobs: true - bee_traps: 15 - egg_shards_required: 7 - egg_shards_available: 10 - required_bosses: - none: 0 - ender_dragon: 1 - wither: 0 - both: 0 - ---- - description: Example of generating multiple worlds. World 2 of 2 name: ExampleFinder game: ChecksFinder @@ -344,6 +319,6 @@ ChecksFinder: accessibility: items ``` -The above example will generate 3 worlds - one Super Mario 64, one Minecraft, and one ChecksFinder. +The above example will generate 2 worlds - one Super Mario 64 and one ChecksFinder. diff --git a/worlds/generic/docs/plando_en.md b/worlds/generic/docs/plando_en.md index 946962476286..b383239d8d11 100644 --- a/worlds/generic/docs/plando_en.md +++ b/worlds/generic/docs/plando_en.md @@ -194,7 +194,7 @@ relevant guide: [A Link to the Past Plando Guide](/tutorial/A%20Link%20to%20the% ## Connection Plando -This is currently only supported by a few games, including A Link to the Past, Minecraft, and Ocarina of Time. As the way that these games interact with their +This is currently only supported by a few games, including A Link to the Past and Ocarina of Time. As the way that these games interact with their connections is different, only the basics are explained here. More specific information for connection plando in A Link to the Past can be found in its [plando guide](/tutorial/A%20Link%20to%20the%20Past/plando/en#connections). @@ -207,7 +207,6 @@ its [plando guide](/tutorial/A%20Link%20to%20the%20Past/plando/en#connections). [A Link to the Past connections](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/alttp/EntranceShuffle.py#L3852) -[Minecraft connections](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/minecraft/data/regions.json#L18****) ### Examples @@ -223,19 +222,10 @@ its [plando guide](/tutorial/A%20Link%20to%20the%20Past/plando/en#connections). - entrance: Agahnims Tower exit: Old Man Cave Exit (West) direction: exit - - # example block 2 - Minecraft - - entrance: Overworld Structure 1 - exit: Nether Fortress - direction: both - - entrance: Overworld Structure 2 - exit: Village - direction: both + ``` 1. These connections are decoupled, so going into the Lake Hylia Cave Shop will take you to the inside of Cave 45, and when you leave the interior, you will exit to the Cave 45 ledge. Going into the Cave 45 entrance will then take you to the Lake Hylia Cave Shop. Walking into the entrance for the Old Man Cave and Agahnim's Tower entrance will both take you to their locations as normal, but leaving Old Man Cave will exit at Agahnim's Tower. -2. This will force a Nether fortress and a village to be the Overworld structures for your game. Note that for the - Minecraft connection plando to work structure shuffle must be enabled. diff --git a/worlds/minecraft/Constants.py b/worlds/minecraft/Constants.py deleted file mode 100644 index 1f7b6fa6acef..000000000000 --- a/worlds/minecraft/Constants.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -import json -import pkgutil - -def load_data_file(*args) -> dict: - fname = "/".join(["data", *args]) - return json.loads(pkgutil.get_data(__name__, fname).decode()) - -# For historical reasons, these values are different. -# They remain different to ensure datapackage consistency. -# Do not separate other games' location and item IDs like this. -item_id_offset: int = 45000 -location_id_offset: int = 42000 - -item_info = load_data_file("items.json") -item_name_to_id = {name: item_id_offset + index \ - for index, name in enumerate(item_info["all_items"])} -item_name_to_id["Bee Trap"] = item_id_offset + 100 # historical reasons - -location_info = load_data_file("locations.json") -location_name_to_id = {name: location_id_offset + index \ - for index, name in enumerate(location_info["all_locations"])} - -exclusion_info = load_data_file("excluded_locations.json") - -region_info = load_data_file("regions.json") diff --git a/worlds/minecraft/ItemPool.py b/worlds/minecraft/ItemPool.py deleted file mode 100644 index 19bb70ed6402..000000000000 --- a/worlds/minecraft/ItemPool.py +++ /dev/null @@ -1,55 +0,0 @@ -from math import ceil -from typing import List - -from BaseClasses import Item - -from . import Constants -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from . import MinecraftWorld - - -def get_junk_item_names(rand, k: int) -> str: - junk_weights = Constants.item_info["junk_weights"] - junk = rand.choices( - list(junk_weights.keys()), - weights=list(junk_weights.values()), - k=k) - return junk - -def build_item_pool(world: "MinecraftWorld") -> List[Item]: - multiworld = world.multiworld - player = world.player - - itempool = [] - total_location_count = len(multiworld.get_unfilled_locations(player)) - - required_pool = Constants.item_info["required_pool"] - - # Add required progression items - for item_name, num in required_pool.items(): - itempool += [world.create_item(item_name) for _ in range(num)] - - # Add structure compasses - if world.options.structure_compasses: - compasses = [name for name in world.item_name_to_id if "Structure Compass" in name] - for item_name in compasses: - itempool.append(world.create_item(item_name)) - - # Dragon egg shards - if world.options.egg_shards_required > 0: - num = world.options.egg_shards_available - itempool += [world.create_item("Dragon Egg Shard") for _ in range(num)] - - # Bee traps - bee_trap_percentage = world.options.bee_traps * 0.01 - if bee_trap_percentage > 0: - bee_trap_qty = ceil(bee_trap_percentage * (total_location_count - len(itempool))) - itempool += [world.create_item("Bee Trap") for _ in range(bee_trap_qty)] - - # Fill remaining itempool with randomly generated junk - junk = get_junk_item_names(world.random, total_location_count - len(itempool)) - itempool += [world.create_item(name) for name in junk] - - return itempool diff --git a/worlds/minecraft/Options.py b/worlds/minecraft/Options.py deleted file mode 100644 index 7d1377233e4c..000000000000 --- a/worlds/minecraft/Options.py +++ /dev/null @@ -1,143 +0,0 @@ -from Options import Choice, Toggle, DefaultOnToggle, Range, OptionList, DeathLink, PlandoConnections, \ - PerGameCommonOptions -from .Constants import region_info -from dataclasses import dataclass - - -class AdvancementGoal(Range): - """Number of advancements required to spawn bosses.""" - display_name = "Advancement Goal" - range_start = 0 - range_end = 114 - default = 40 - - -class EggShardsRequired(Range): - """Number of dragon egg shards to collect to spawn bosses.""" - display_name = "Egg Shards Required" - range_start = 0 - range_end = 50 - default = 0 - - -class EggShardsAvailable(Range): - """Number of dragon egg shards available to collect.""" - display_name = "Egg Shards Available" - range_start = 0 - range_end = 50 - default = 0 - - -class BossGoal(Choice): - """Bosses which must be defeated to finish the game.""" - display_name = "Required Bosses" - option_none = 0 - option_ender_dragon = 1 - option_wither = 2 - option_both = 3 - default = 1 - - @property - def dragon(self): - return self.value % 2 == 1 - - @property - def wither(self): - return self.value > 1 - - -class ShuffleStructures(DefaultOnToggle): - """Enables shuffling of villages, outposts, fortresses, bastions, and end cities.""" - display_name = "Shuffle Structures" - - -class StructureCompasses(DefaultOnToggle): - """Adds structure compasses to the item pool, which point to the nearest indicated structure.""" - display_name = "Structure Compasses" - - -class BeeTraps(Range): - """Replaces a percentage of junk items with bee traps, which spawn multiple angered bees around every player when - received.""" - display_name = "Bee Trap Percentage" - range_start = 0 - range_end = 100 - default = 0 - - -class CombatDifficulty(Choice): - """Modifies the level of items logically required for exploring dangerous areas and fighting bosses.""" - display_name = "Combat Difficulty" - option_easy = 0 - option_normal = 1 - option_hard = 2 - default = 1 - - -class HardAdvancements(Toggle): - """Enables certain RNG-reliant or tedious advancements.""" - display_name = "Include Hard Advancements" - - -class UnreasonableAdvancements(Toggle): - """Enables the extremely difficult advancements "How Did We Get Here?" and "Adventuring Time.\"""" - display_name = "Include Unreasonable Advancements" - - -class PostgameAdvancements(Toggle): - """Enables advancements that require spawning and defeating the required bosses.""" - display_name = "Include Postgame Advancements" - - -class SendDefeatedMobs(Toggle): - """Send killed mobs to other Minecraft worlds which have this option enabled.""" - display_name = "Send Defeated Mobs" - - -class StartingItems(OptionList): - """Start with these items. Each entry should be of this format: {item: "item_name", amount: #} - `item` can include components, and should be in an identical format to a `/give` command with - `"` escaped for json reasons. - - `amount` is optional and will default to 1 if omitted. - - example: - ``` - starting_items: [ - { "item": "minecraft:stick[minecraft:custom_name=\"{'text':'pointy stick'}\"]" }, - { "item": "minecraft:arrow[minecraft:rarity=epic]", amount: 64 } - ] - ``` - """ - display_name = "Starting Items" - - -class MCPlandoConnections(PlandoConnections): - entrances = set(connection[0] for connection in region_info["default_connections"]) - exits = set(connection[1] for connection in region_info["default_connections"]) - - @classmethod - def can_connect(cls, entrance, exit): - if exit in region_info["illegal_connections"] and entrance in region_info["illegal_connections"][exit]: - return False - return True - - -@dataclass -class MinecraftOptions(PerGameCommonOptions): - plando_connections: MCPlandoConnections - advancement_goal: AdvancementGoal - egg_shards_required: EggShardsRequired - egg_shards_available: EggShardsAvailable - required_bosses: BossGoal - shuffle_structures: ShuffleStructures - structure_compasses: StructureCompasses - - combat_difficulty: CombatDifficulty - include_hard_advancements: HardAdvancements - include_unreasonable_advancements: UnreasonableAdvancements - include_postgame_advancements: PostgameAdvancements - bee_traps: BeeTraps - send_defeated_mobs: SendDefeatedMobs - death_link: DeathLink - starting_items: StartingItems diff --git a/worlds/minecraft/Rules.py b/worlds/minecraft/Rules.py deleted file mode 100644 index 9a7be09a4a84..000000000000 --- a/worlds/minecraft/Rules.py +++ /dev/null @@ -1,508 +0,0 @@ -from BaseClasses import CollectionState -from worlds.generic.Rules import exclusion_rules - -from . import Constants -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from . import MinecraftWorld - - -# Helper functions -# moved from logicmixin - -def has_iron_ingots(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return state.has('Progressive Tools', player) and state.has('Progressive Resource Crafting', player) - - -def has_copper_ingots(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return state.has('Progressive Tools', player) and state.has('Progressive Resource Crafting', player) - - -def has_gold_ingots(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return (state.has('Progressive Resource Crafting', player) - and ( - state.has('Progressive Tools', player, 2) - or state.can_reach_region('The Nether', player) - ) - ) - - -def has_diamond_pickaxe(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return state.has('Progressive Tools', player, 3) and has_iron_ingots(world, state, player) - - -def craft_crossbow(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return state.has('Archery', player) and has_iron_ingots(world, state, player) - - -def has_bottle(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return state.has('Bottles', player) and state.has('Progressive Resource Crafting', player) - - -def has_spyglass(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return (has_copper_ingots(world, state, player) - and state.has('Spyglass', player) - and can_adventure(world, state, player) - ) - - -def can_enchant(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return state.has('Enchanting', player) and has_diamond_pickaxe(world, state, player) # mine obsidian and lapis - - -def can_use_anvil(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return (state.has('Enchanting', player) - and state.has('Progressive Resource Crafting', player,2) - and has_iron_ingots(world, state, player) - ) - - -def fortress_loot(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: # saddles, blaze rods, wither skulls - return state.can_reach_region('Nether Fortress', player) and basic_combat(world, state, player) - - -def can_brew_potions(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return state.has('Blaze Rods', player) and state.has('Brewing', player) and has_bottle(world, state, player) - - -def can_piglin_trade(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return (has_gold_ingots(world, state, player) - and ( - state.can_reach_region('The Nether', player) - or state.can_reach_region('Bastion Remnant', player) - )) - - -def overworld_villager(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - village_region = state.multiworld.get_region('Village', player).entrances[0].parent_region.name - if village_region == 'The Nether': # 2 options: cure zombie villager or build portal in village - return (state.can_reach_location('Zombie Doctor', player) - or ( - has_diamond_pickaxe(world, state, player) - and state.can_reach_region('Village', player) - )) - elif village_region == 'The End': - return state.can_reach_location('Zombie Doctor', player) - return state.can_reach_region('Village', player) - - -def enter_stronghold(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return state.has('Blaze Rods', player) and state.has('Brewing', player) and state.has('3 Ender Pearls', player) - - -# Difficulty-dependent functions -def combat_difficulty(world: "MinecraftWorld", state: CollectionState, player: int) -> str: - return world.options.combat_difficulty.current_key - - -def can_adventure(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - death_link_check = not world.options.death_link or state.has('Bed', player) - if combat_difficulty(world, state, player) == 'easy': - return state.has('Progressive Weapons', player, 2) and has_iron_ingots(world, state, player) and death_link_check - elif combat_difficulty(world, state, player) == 'hard': - return True - return (state.has('Progressive Weapons', player) and death_link_check and - (state.has('Progressive Resource Crafting', player) or state.has('Campfire', player))) - - -def basic_combat(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - if combat_difficulty(world, state, player) == 'easy': - return (state.has('Progressive Weapons', player, 2) - and state.has('Progressive Armor', player) - and state.has('Shield', player) - and has_iron_ingots(world, state, player) - ) - elif combat_difficulty(world, state, player) == 'hard': - return True - return (state.has('Progressive Weapons', player) - and ( - state.has('Progressive Armor', player) - or state.has('Shield', player) - ) - and has_iron_ingots(world, state, player) - ) - - -def complete_raid(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - reach_regions = (state.can_reach_region('Village', player) - and state.can_reach_region('Pillager Outpost', player)) - if combat_difficulty(world, state, player) == 'easy': - return (reach_regions - and state.has('Progressive Weapons', player, 3) - and state.has('Progressive Armor', player, 2) - and state.has('Shield', player) - and state.has('Archery', player) - and state.has('Progressive Tools', player, 2) - and has_iron_ingots(world, state, player) - ) - elif combat_difficulty(world, state, player) == 'hard': # might be too hard? - return (reach_regions - and state.has('Progressive Weapons', player, 2) - and has_iron_ingots(world, state, player) - and ( - state.has('Progressive Armor', player) - or state.has('Shield', player) - ) - ) - return (reach_regions - and state.has('Progressive Weapons', player, 2) - and has_iron_ingots(world, state, player) - and state.has('Progressive Armor', player) - and state.has('Shield', player) - ) - - -def can_kill_wither(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - normal_kill = (state.has("Progressive Weapons", player, 3) - and state.has("Progressive Armor", player, 2) - and can_brew_potions(world, state, player) - and can_enchant(world, state, player) - ) - if combat_difficulty(world, state, player) == 'easy': - return (fortress_loot(world, state, player) - and normal_kill - and state.has('Archery', player) - ) - elif combat_difficulty(world, state, player) == 'hard': # cheese kill using bedrock ceilings - return (fortress_loot(world, state, player) - and ( - normal_kill - or state.can_reach_region('The Nether', player) - or state.can_reach_region('The End', player) - ) - ) - - return fortress_loot(world, state, player) and normal_kill - - -def can_respawn_ender_dragon(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - return (state.can_reach_region('The Nether', player) - and state.can_reach_region('The End', player) - and state.has('Progressive Resource Crafting', player) # smelt sand into glass - ) - - -def can_kill_ender_dragon(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: - if combat_difficulty(world, state, player) == 'easy': - return (state.has("Progressive Weapons", player, 3) - and state.has("Progressive Armor", player, 2) - and state.has('Archery', player) - and can_brew_potions(world, state, player) - and can_enchant(world, state, player) - ) - if combat_difficulty(world, state, player) == 'hard': - return ( - ( - state.has('Progressive Weapons', player, 2) - and state.has('Progressive Armor', player) - ) or ( - state.has('Progressive Weapons', player, 1) - and state.has('Bed', player) # who needs armor when you can respawn right outside the chamber - ) - ) - return (state.has('Progressive Weapons', player, 2) - and state.has('Progressive Armor', player) - and state.has('Archery', player) - ) - - -def has_structure_compass(world: "MinecraftWorld", state: CollectionState, entrance_name: str, player: int) -> bool: - if not world.options.structure_compasses: - return True - return state.has(f"Structure Compass ({state.multiworld.get_entrance(entrance_name, player).connected_region.name})", player) - - -def get_rules_lookup(world, player: int): - rules_lookup = { - "entrances": { - "Nether Portal": lambda state: state.has('Flint and Steel', player) - and ( - state.has('Bucket', player) - or state.has('Progressive Tools', player, 3) - ) - and has_iron_ingots(world, state, player), - "End Portal": lambda state: enter_stronghold(world, state, player) - and state.has('3 Ender Pearls', player, 4), - "Overworld Structure 1": lambda state: can_adventure(world, state, player) - and has_structure_compass(world, state, "Overworld Structure 1", player), - "Overworld Structure 2": lambda state: can_adventure(world, state, player) - and has_structure_compass(world, state, "Overworld Structure 2", player), - "Nether Structure 1": lambda state: can_adventure(world, state, player) - and has_structure_compass(world, state, "Nether Structure 1", player), - "Nether Structure 2": lambda state: can_adventure(world, state, player) - and has_structure_compass(world, state, "Nether Structure 2", player), - "The End Structure": lambda state: can_adventure(world, state, player) - and has_structure_compass(world, state, "The End Structure", player), - }, - "locations": { - "Ender Dragon": lambda state: can_respawn_ender_dragon(world, state, player) - and can_kill_ender_dragon(world, state, player), - "Wither": lambda state: can_kill_wither(world, state, player), - "Blaze Rods": lambda state: fortress_loot(world, state, player), - "Who is Cutting Onions?": lambda state: can_piglin_trade(world, state, player), - "Oh Shiny": lambda state: can_piglin_trade(world, state, player), - "Suit Up": lambda state: state.has("Progressive Armor", player) - and has_iron_ingots(world, state, player), - "Very Very Frightening": lambda state: state.has("Channeling Book", player) - and can_use_anvil(world, state, player) - and can_enchant(world, state, player) - and overworld_villager(world, state, player), - "Hot Stuff": lambda state: state.has("Bucket", player) - and has_iron_ingots(world, state, player), - "Free the End": lambda state: can_respawn_ender_dragon(world, state, player) - and can_kill_ender_dragon(world, state, player), - "A Furious Cocktail": lambda state: (can_brew_potions(world, state, player) - and state.has("Fishing Rod", player) # Water Breathing - and state.can_reach_region("The Nether", player) # Regeneration, Fire Resistance, gold nuggets - and state.can_reach_region("Village", player) # Night Vision, Invisibility - and state.can_reach_location("Bring Home the Beacon", player)), - # Resistance - "Bring Home the Beacon": lambda state: can_kill_wither(world, state, player) - and has_diamond_pickaxe(world, state, player) - and state.has("Progressive Resource Crafting", player, 2), - "Not Today, Thank You": lambda state: state.has("Shield", player) - and has_iron_ingots(world, state, player), - "Isn't It Iron Pick": lambda state: state.has("Progressive Tools", player, 2) - and has_iron_ingots(world, state, player), - "Local Brewery": lambda state: can_brew_potions(world, state, player), - "The Next Generation": lambda state: can_respawn_ender_dragon(world, state, player) - and can_kill_ender_dragon(world, state, player), - "Fishy Business": lambda state: state.has("Fishing Rod", player), - "This Boat Has Legs": lambda state: ( - fortress_loot(world, state, player) - or complete_raid(world, state, player) - ) - and state.has("Saddle", player) - and state.has("Fishing Rod", player), - "Sniper Duel": lambda state: state.has("Archery", player), - "Great View From Up Here": lambda state: basic_combat(world, state, player), - "How Did We Get Here?": lambda state: (can_brew_potions(world, state, player) - and has_gold_ingots(world, state, player) # Absorption - and state.can_reach_region('End City', player) # Levitation - and state.can_reach_region('The Nether', player) # potion ingredients - and state.has("Fishing Rod", player) # Pufferfish, Nautilus Shells; spectral arrows - and state.has("Archery", player) - and state.can_reach_location("Bring Home the Beacon", player) # Haste - and state.can_reach_location("Hero of the Village", player)), # Bad Omen, Hero of the Village - "Bullseye": lambda state: state.has("Archery", player) - and state.has("Progressive Tools", player, 2) - and has_iron_ingots(world, state, player), - "Spooky Scary Skeleton": lambda state: basic_combat(world, state, player), - "Two by Two": lambda state: has_iron_ingots(world, state, player) - and state.has("Bucket", player) - and can_adventure(world, state, player), - "Two Birds, One Arrow": lambda state: craft_crossbow(world, state, player) - and can_enchant(world, state, player), - "Who's the Pillager Now?": lambda state: craft_crossbow(world, state, player), - "Getting an Upgrade": lambda state: state.has("Progressive Tools", player), - "Tactical Fishing": lambda state: state.has("Bucket", player) - and has_iron_ingots(world, state, player), - "Zombie Doctor": lambda state: can_brew_potions(world, state, player) - and has_gold_ingots(world, state, player), - "Ice Bucket Challenge": lambda state: has_diamond_pickaxe(world, state, player), - "Into Fire": lambda state: basic_combat(world, state, player), - "War Pigs": lambda state: basic_combat(world, state, player), - "Take Aim": lambda state: state.has("Archery", player), - "Total Beelocation": lambda state: state.has("Silk Touch Book", player) - and can_use_anvil(world, state, player) - and can_enchant(world, state, player), - "Arbalistic": lambda state: (craft_crossbow(world, state, player) - and state.has("Piercing IV Book", player) - and can_use_anvil(world, state, player) - and can_enchant(world, state, player) - ), - "The End... Again...": lambda state: can_respawn_ender_dragon(world, state, player) - and can_kill_ender_dragon(world, state, player), - "Acquire Hardware": lambda state: has_iron_ingots(world, state, player), - "Not Quite \"Nine\" Lives": lambda state: can_piglin_trade(world, state, player) - and state.has("Progressive Resource Crafting", player, 2), - "Cover Me With Diamonds": lambda state: state.has("Progressive Armor", player, 2) - and state.has("Progressive Tools", player, 2) - and has_iron_ingots(world, state, player), - "Sky's the Limit": lambda state: basic_combat(world, state, player), - "Hired Help": lambda state: state.has("Progressive Resource Crafting", player, 2) - and has_iron_ingots(world, state, player), - "Sweet Dreams": lambda state: state.has("Bed", player) - or state.can_reach_region('Village', player), - "You Need a Mint": lambda state: can_respawn_ender_dragon(world, state, player) - and has_bottle(world, state, player), - "Monsters Hunted": lambda state: (can_respawn_ender_dragon(world, state, player) - and can_kill_ender_dragon(world, state, player) - and can_kill_wither(world, state, player) - and state.has("Fishing Rod", player)), - "Enchanter": lambda state: can_enchant(world, state, player), - "Voluntary Exile": lambda state: basic_combat(world, state, player), - "Eye Spy": lambda state: enter_stronghold(world, state, player), - "Serious Dedication": lambda state: (can_brew_potions(world, state, player) - and state.has("Bed", player) - and has_diamond_pickaxe(world, state, player) - and has_gold_ingots(world, state, player)), - "Postmortal": lambda state: complete_raid(world, state, player), - "Adventuring Time": lambda state: can_adventure(world, state, player), - "Hero of the Village": lambda state: complete_raid(world, state, player), - "Hidden in the Depths": lambda state: can_brew_potions(world, state, player) - and state.has("Bed", player) - and has_diamond_pickaxe(world, state, player), - "Beaconator": lambda state: (can_kill_wither(world, state, player) - and has_diamond_pickaxe(world, state, player) - and state.has("Progressive Resource Crafting", player, 2)), - "Withering Heights": lambda state: can_kill_wither(world, state, player), - "A Balanced Diet": lambda state: (has_bottle(world, state, player) - and has_gold_ingots(world, state, player) - and state.has("Progressive Resource Crafting", player, 2) - and state.can_reach_region('The End', player)), - # notch apple, chorus fruit - "Subspace Bubble": lambda state: has_diamond_pickaxe(world, state, player), - "Country Lode, Take Me Home": lambda state: state.can_reach_location("Hidden in the Depths", player) - and has_gold_ingots(world, state, player), - "Bee Our Guest": lambda state: state.has("Campfire", player) - and has_bottle(world, state, player), - "Uneasy Alliance": lambda state: has_diamond_pickaxe(world, state, player) - and state.has('Fishing Rod', player), - "Diamonds!": lambda state: state.has("Progressive Tools", player, 2) - and has_iron_ingots(world, state, player), - "A Throwaway Joke": lambda state: can_adventure(world, state, player), - "Sticky Situation": lambda state: state.has("Campfire", player) - and has_bottle(world, state, player), - "Ol' Betsy": lambda state: craft_crossbow(world, state, player), - "Cover Me in Debris": lambda state: state.has("Progressive Armor", player, 2) - and state.has("8 Netherite Scrap", player, 2) - and state.has("Progressive Resource Crafting", player) - and has_diamond_pickaxe(world, state, player) - and has_iron_ingots(world, state, player) - and can_brew_potions(world, state, player) - and state.has("Bed", player), - "Hot Topic": lambda state: state.has("Progressive Resource Crafting", player), - "The Lie": lambda state: has_iron_ingots(world, state, player) - and state.has("Bucket", player), - "On a Rail": lambda state: has_iron_ingots(world, state, player) - and state.has('Progressive Tools', player, 2), - "When Pigs Fly": lambda state: ( - fortress_loot(world, state, player) - or complete_raid(world, state, player) - ) - and state.has("Saddle", player) - and state.has("Fishing Rod", player) - and can_adventure(world, state, player), - "Overkill": lambda state: can_brew_potions(world, state, player) - and ( - state.has("Progressive Weapons", player) - or state.can_reach_region('The Nether', player) - ), - "Librarian": lambda state: state.has("Enchanting", player), - "Overpowered": lambda state: has_iron_ingots(world, state, player) - and state.has('Progressive Tools', player, 2) - and basic_combat(world, state, player), - "Wax On": lambda state: has_copper_ingots(world, state, player) - and state.has('Campfire', player) - and state.has('Progressive Resource Crafting', player, 2), - "Wax Off": lambda state: has_copper_ingots(world, state, player) - and state.has('Campfire', player) - and state.has('Progressive Resource Crafting', player, 2), - "The Cutest Predator": lambda state: has_iron_ingots(world, state, player) - and state.has('Bucket', player), - "The Healing Power of Friendship": lambda state: has_iron_ingots(world, state, player) - and state.has('Bucket', player), - "Is It a Bird?": lambda state: has_spyglass(world, state, player) - and can_adventure(world, state, player), - "Is It a Balloon?": lambda state: has_spyglass(world, state, player), - "Is It a Plane?": lambda state: has_spyglass(world, state, player) - and can_respawn_ender_dragon(world, state, player), - "Surge Protector": lambda state: state.has("Channeling Book", player) - and can_use_anvil(world, state, player) - and can_enchant(world, state, player) - and overworld_villager(world, state, player), - "Light as a Rabbit": lambda state: can_adventure(world, state, player) - and has_iron_ingots(world, state, player) - and state.has('Bucket', player), - "Glow and Behold!": lambda state: can_adventure(world, state, player), - "Whatever Floats Your Goat!": lambda state: can_adventure(world, state, player), - "Caves & Cliffs": lambda state: has_iron_ingots(world, state, player) - and state.has('Bucket', player) - and state.has('Progressive Tools', player, 2), - "Feels like home": lambda state: has_iron_ingots(world, state, player) - and state.has('Bucket', player) - and state.has('Fishing Rod', player) - and ( - fortress_loot(world, state, player) - or complete_raid(world, state, player) - ) - and state.has("Saddle", player), - "Sound of Music": lambda state: state.has("Progressive Tools", player, 2) - and has_iron_ingots(world, state, player) - and basic_combat(world, state, player), - "Star Trader": lambda state: has_iron_ingots(world, state, player) - and state.has('Bucket', player) - and ( - state.can_reach_region("The Nether", player) # soul sand in nether - or state.can_reach_region("Nether Fortress", player) # soul sand in fortress if not in nether for water elevator - or can_piglin_trade(world, state, player) # piglins give soul sand - ) - and overworld_villager(world, state, player), - "Birthday Song": lambda state: state.can_reach_location("The Lie", player) - and state.has("Progressive Tools", player, 2) - and has_iron_ingots(world, state, player), - "Bukkit Bukkit": lambda state: state.has("Bucket", player) - and has_iron_ingots(world, state, player) - and can_adventure(world, state, player), - "It Spreads": lambda state: can_adventure(world, state, player) - and has_iron_ingots(world, state, player) - and state.has("Progressive Tools", player, 2), - "Sneak 100": lambda state: can_adventure(world, state, player) - and has_iron_ingots(world, state, player) - and state.has("Progressive Tools", player, 2), - "When the Squad Hops into Town": lambda state: can_adventure(world, state, player) - and state.has("Lead", player), - "With Our Powers Combined!": lambda state: can_adventure(world, state, player) - and state.has("Lead", player), - } - } - return rules_lookup - - -def set_rules(self: "MinecraftWorld") -> None: - multiworld = self.multiworld - player = self.player - - rules_lookup = get_rules_lookup(self, player) - - # Set entrance rules - for entrance_name, rule in rules_lookup["entrances"].items(): - multiworld.get_entrance(entrance_name, player).access_rule = rule - - # Set location rules - for location_name, rule in rules_lookup["locations"].items(): - multiworld.get_location(location_name, player).access_rule = rule - - # Set rules surrounding completion - bosses = self.options.required_bosses - postgame_advancements = set() - if bosses.dragon: - postgame_advancements.update(Constants.exclusion_info["ender_dragon"]) - if bosses.wither: - postgame_advancements.update(Constants.exclusion_info["wither"]) - - def location_count(state: CollectionState) -> int: - return len([location for location in multiworld.get_locations(player) if - location.address is not None and - location.can_reach(state)]) - - def defeated_bosses(state: CollectionState) -> bool: - return ((not bosses.dragon or state.has("Ender Dragon", player)) - and (not bosses.wither or state.has("Wither", player))) - - egg_shards = min(self.options.egg_shards_required.value, self.options.egg_shards_available.value) - completion_requirements = lambda state: (location_count(state) >= self.options.advancement_goal - and state.has("Dragon Egg Shard", player, egg_shards)) - multiworld.completion_condition[player] = lambda state: completion_requirements(state) and defeated_bosses(state) - - # Set exclusions on hard/unreasonable/postgame - excluded_advancements = set() - if not self.options.include_hard_advancements: - excluded_advancements.update(Constants.exclusion_info["hard"]) - if not self.options.include_unreasonable_advancements: - excluded_advancements.update(Constants.exclusion_info["unreasonable"]) - if not self.options.include_postgame_advancements: - excluded_advancements.update(postgame_advancements) - exclusion_rules(multiworld, player, excluded_advancements) diff --git a/worlds/minecraft/Structures.py b/worlds/minecraft/Structures.py deleted file mode 100644 index d4f62f3498e9..000000000000 --- a/worlds/minecraft/Structures.py +++ /dev/null @@ -1,59 +0,0 @@ -from . import Constants -from typing import TYPE_CHECKING -if TYPE_CHECKING: - from . import MinecraftWorld - - -def shuffle_structures(self: "MinecraftWorld") -> None: - multiworld = self.multiworld - player = self.player - - default_connections = Constants.region_info["default_connections"] - illegal_connections = Constants.region_info["illegal_connections"] - - # Get all unpaired exits and all regions without entrances (except the Menu) - # This function is destructive on these lists. - exits = [exit.name for r in multiworld.regions if r.player == player for exit in r.exits if exit.connected_region is None] - structs = [r.name for r in multiworld.regions if r.player == player and r.entrances == [] and r.name != 'Menu'] - exits_spoiler = exits[:] # copy the original order for the spoiler log - - pairs = {} - - def set_pair(exit, struct): - if (exit in exits) and (struct in structs) and (exit not in illegal_connections.get(struct, [])): - pairs[exit] = struct - exits.remove(exit) - structs.remove(struct) - else: - raise Exception(f"Invalid connection: {exit} => {struct} for player {player} ({multiworld.player_name[player]})") - - # Connect plando structures first - if self.options.plando_connections: - for conn in self.options.plando_connections: - set_pair(conn.entrance, conn.exit) - - # The algorithm tries to place the most restrictive structures first. This algorithm always works on the - # relatively small set of restrictions here, but does not work on all possible inputs with valid configurations. - if self.options.shuffle_structures: - structs.sort(reverse=True, key=lambda s: len(illegal_connections.get(s, []))) - for struct in structs[:]: - try: - exit = self.random.choice([e for e in exits if e not in illegal_connections.get(struct, [])]) - except IndexError: - raise Exception(f"No valid structure placements remaining for player {player} ({self.player_name})") - set_pair(exit, struct) - else: # write remaining default connections - for (exit, struct) in default_connections: - if exit in exits: - set_pair(exit, struct) - - # Make sure we actually paired everything; might fail if plando - try: - assert len(exits) == len(structs) == 0 - except AssertionError: - raise Exception(f"Failed to connect all Minecraft structures for player {player} ({self.player_name})") - - for exit in exits_spoiler: - multiworld.get_entrance(exit, player).connect(multiworld.get_region(pairs[exit], player)) - if self.options.shuffle_structures or self.options.plando_connections: - multiworld.spoiler.set_entrance(exit, pairs[exit], 'entrance', player) diff --git a/worlds/minecraft/__init__.py b/worlds/minecraft/__init__.py deleted file mode 100644 index 7ec9b4b2b8d9..000000000000 --- a/worlds/minecraft/__init__.py +++ /dev/null @@ -1,203 +0,0 @@ -import os -import json -import settings -import typing -from base64 import b64encode, b64decode -from typing import Dict, Any - -from BaseClasses import Region, Entrance, Item, Tutorial, ItemClassification, Location -from worlds.AutoWorld import World, WebWorld - -from . import Constants -from .Options import MinecraftOptions -from .Structures import shuffle_structures -from .ItemPool import build_item_pool, get_junk_item_names -from .Rules import set_rules - -client_version = 9 - - -class MinecraftSettings(settings.Group): - class ForgeDirectory(settings.OptionalUserFolderPath): - pass - - class ReleaseChannel(str): - """ - release channel, currently "release", or "beta" - any games played on the "beta" channel have a high likelihood of no longer working on the "release" channel. - """ - - class JavaExecutable(settings.OptionalUserFilePath): - """ - Path to Java executable. If not set, will attempt to fall back to Java system installation. - """ - - forge_directory: ForgeDirectory = ForgeDirectory("Minecraft NeoForge server") - max_heap_size: str = "2G" - release_channel: ReleaseChannel = ReleaseChannel("release") - java: JavaExecutable = JavaExecutable("") - - -class MinecraftWebWorld(WebWorld): - theme = "jungle" - bug_report_page = "https://github.com/KonoTyran/Minecraft_AP_Randomizer/issues/new?assignees=&labels=bug&template=bug_report.yaml&title=%5BBug%5D%3A+Brief+Description+of+bug+here" - - setup = Tutorial( - "Multiworld Setup Guide", - "A guide to setting up the Archipelago Minecraft software on your computer. This guide covers" - "single-player, multiworld, and related software.", - "English", - "minecraft_en.md", - "minecraft/en", - ["Kono Tyran"] - ) - - setup_es = Tutorial( - setup.tutorial_name, - setup.description, - "Español", - "minecraft_es.md", - "minecraft/es", - ["Edos"] - ) - - setup_sv = Tutorial( - setup.tutorial_name, - setup.description, - "Swedish", - "minecraft_sv.md", - "minecraft/sv", - ["Albinum"] - ) - - setup_fr = Tutorial( - setup.tutorial_name, - setup.description, - "Français", - "minecraft_fr.md", - "minecraft/fr", - ["TheLynk"] - ) - - tutorials = [setup, setup_es, setup_sv, setup_fr] - - -class MinecraftWorld(World): - """ - Minecraft is a game about creativity. In a world made entirely of cubes, you explore, discover, mine, - craft, and try not to explode. Delve deep into the earth and discover abandoned mines, ancient - structures, and materials to create a portal to another world. Defeat the Ender Dragon, and claim - victory! - """ - game = "Minecraft" - options_dataclass = MinecraftOptions - options: MinecraftOptions - settings: typing.ClassVar[MinecraftSettings] - topology_present = True - web = MinecraftWebWorld() - - item_name_to_id = Constants.item_name_to_id - location_name_to_id = Constants.location_name_to_id - - def _get_mc_data(self) -> Dict[str, Any]: - exits = [connection[0] for connection in Constants.region_info["default_connections"]] - return { - 'world_seed': self.random.getrandbits(32), - 'seed_name': self.multiworld.seed_name, - 'player_name': self.player_name, - 'player_id': self.player, - 'client_version': client_version, - 'structures': {exit: self.multiworld.get_entrance(exit, self.player).connected_region.name for exit in exits}, - 'advancement_goal': self.options.advancement_goal.value, - 'egg_shards_required': min(self.options.egg_shards_required.value, - self.options.egg_shards_available.value), - 'egg_shards_available': self.options.egg_shards_available.value, - 'required_bosses': self.options.required_bosses.current_key, - 'MC35': bool(self.options.send_defeated_mobs.value), - 'death_link': bool(self.options.death_link.value), - 'starting_items': json.dumps(self.options.starting_items.value), - 'race': self.multiworld.is_race, - } - - def create_item(self, name: str) -> Item: - item_class = ItemClassification.filler - if name in Constants.item_info["progression_items"]: - item_class = ItemClassification.progression - elif name in Constants.item_info["useful_items"]: - item_class = ItemClassification.useful - elif name in Constants.item_info["trap_items"]: - item_class = ItemClassification.trap - - return MinecraftItem(name, item_class, self.item_name_to_id.get(name, None), self.player) - - def create_event(self, region_name: str, event_name: str) -> None: - region = self.multiworld.get_region(region_name, self.player) - loc = MinecraftLocation(self.player, event_name, None, region) - loc.place_locked_item(self.create_event_item(event_name)) - region.locations.append(loc) - - def create_event_item(self, name: str) -> Item: - item = self.create_item(name) - item.classification = ItemClassification.progression - return item - - def create_regions(self) -> None: - # Create regions - for region_name, exits in Constants.region_info["regions"]: - r = Region(region_name, self.player, self.multiworld) - for exit_name in exits: - r.exits.append(Entrance(self.player, exit_name, r)) - self.multiworld.regions.append(r) - - # Bind mandatory connections - for entr_name, region_name in Constants.region_info["mandatory_connections"]: - e = self.multiworld.get_entrance(entr_name, self.player) - r = self.multiworld.get_region(region_name, self.player) - e.connect(r) - - # Add locations - for region_name, locations in Constants.location_info["locations_by_region"].items(): - region = self.multiworld.get_region(region_name, self.player) - for loc_name in locations: - loc = MinecraftLocation(self.player, loc_name, - self.location_name_to_id.get(loc_name, None), region) - region.locations.append(loc) - - # Add events - self.create_event("Nether Fortress", "Blaze Rods") - self.create_event("The End", "Ender Dragon") - self.create_event("Nether Fortress", "Wither") - - # Shuffle the connections - shuffle_structures(self) - - def create_items(self) -> None: - self.multiworld.itempool += build_item_pool(self) - - set_rules = set_rules - - def generate_output(self, output_directory: str) -> None: - data = self._get_mc_data() - filename = f"{self.multiworld.get_out_file_name_base(self.player)}.apmc" - with open(os.path.join(output_directory, filename), 'wb') as f: - f.write(b64encode(bytes(json.dumps(data), 'utf-8'))) - - def fill_slot_data(self) -> dict: - return self._get_mc_data() - - def get_filler_item_name(self) -> str: - return get_junk_item_names(self.random, 1)[0] - - -class MinecraftLocation(Location): - game = "Minecraft" - -class MinecraftItem(Item): - game = "Minecraft" - - -def mc_update_output(raw_data, server, port): - data = json.loads(b64decode(raw_data)) - data['server'] = server - data['port'] = port - return b64encode(bytes(json.dumps(data), 'utf-8')) diff --git a/worlds/minecraft/data/excluded_locations.json b/worlds/minecraft/data/excluded_locations.json deleted file mode 100644 index 2f6fbbba6d22..000000000000 --- a/worlds/minecraft/data/excluded_locations.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "hard": [ - "Very Very Frightening", - "A Furious Cocktail", - "Two by Two", - "Two Birds, One Arrow", - "Arbalistic", - "Monsters Hunted", - "Beaconator", - "A Balanced Diet", - "Uneasy Alliance", - "Cover Me in Debris", - "A Complete Catalogue", - "Surge Protector", - "Sound of Music", - "Star Trader", - "When the Squad Hops into Town", - "With Our Powers Combined!" - ], - "unreasonable": [ - "How Did We Get Here?", - "Adventuring Time" - ], - "ender_dragon": [ - "Free the End", - "The Next Generation", - "The End... Again...", - "You Need a Mint", - "Monsters Hunted", - "Is It a Plane?" - ], - "wither": [ - "Withering Heights", - "Bring Home the Beacon", - "Beaconator", - "A Furious Cocktail", - "How Did We Get Here?", - "Monsters Hunted" - ] -} \ No newline at end of file diff --git a/worlds/minecraft/data/items.json b/worlds/minecraft/data/items.json deleted file mode 100644 index 7d35d18aeb01..000000000000 --- a/worlds/minecraft/data/items.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "all_items": [ - "Archery", - "Progressive Resource Crafting", - "Resource Blocks", - "Brewing", - "Enchanting", - "Bucket", - "Flint and Steel", - "Bed", - "Bottles", - "Shield", - "Fishing Rod", - "Campfire", - "Progressive Weapons", - "Progressive Tools", - "Progressive Armor", - "8 Netherite Scrap", - "8 Emeralds", - "4 Emeralds", - "Channeling Book", - "Silk Touch Book", - "Sharpness III Book", - "Piercing IV Book", - "Looting III Book", - "Infinity Book", - "4 Diamond Ore", - "16 Iron Ore", - "500 XP", - "100 XP", - "50 XP", - "3 Ender Pearls", - "4 Lapis Lazuli", - "16 Porkchops", - "8 Gold Ore", - "Rotten Flesh", - "Single Arrow", - "32 Arrows", - "Saddle", - "Structure Compass (Village)", - "Structure Compass (Pillager Outpost)", - "Structure Compass (Nether Fortress)", - "Structure Compass (Bastion Remnant)", - "Structure Compass (End City)", - "Shulker Box", - "Dragon Egg Shard", - "Spyglass", - "Lead", - "Bee Trap" - ], - "progression_items": [ - "Archery", - "Progressive Resource Crafting", - "Resource Blocks", - "Brewing", - "Enchanting", - "Bucket", - "Flint and Steel", - "Bed", - "Bottles", - "Shield", - "Fishing Rod", - "Campfire", - "Progressive Weapons", - "Progressive Tools", - "Progressive Armor", - "8 Netherite Scrap", - "Channeling Book", - "Silk Touch Book", - "Piercing IV Book", - "3 Ender Pearls", - "Saddle", - "Structure Compass (Village)", - "Structure Compass (Pillager Outpost)", - "Structure Compass (Nether Fortress)", - "Structure Compass (Bastion Remnant)", - "Structure Compass (End City)", - "Dragon Egg Shard", - "Spyglass", - "Lead" - ], - "useful_items": [ - "Sharpness III Book", - "Looting III Book", - "Infinity Book" - ], - "trap_items": [ - "Bee Trap" - ], - - "required_pool": { - "Archery": 1, - "Progressive Resource Crafting": 2, - "Brewing": 1, - "Enchanting": 1, - "Bucket": 1, - "Flint and Steel": 1, - "Bed": 1, - "Bottles": 1, - "Shield": 1, - "Fishing Rod": 1, - "Campfire": 1, - "Progressive Weapons": 3, - "Progressive Tools": 3, - "Progressive Armor": 2, - "8 Netherite Scrap": 2, - "Channeling Book": 1, - "Silk Touch Book": 1, - "Sharpness III Book": 1, - "Piercing IV Book": 1, - "Looting III Book": 1, - "Infinity Book": 1, - "3 Ender Pearls": 4, - "Saddle": 1, - "Spyglass": 1, - "Lead": 1 - }, - "junk_weights": { - "4 Emeralds": 2, - "4 Diamond Ore": 1, - "16 Iron Ore": 1, - "50 XP": 4, - "16 Porkchops": 2, - "8 Gold Ore": 1, - "Rotten Flesh": 1, - "32 Arrows": 1 - } -} \ No newline at end of file diff --git a/worlds/minecraft/data/locations.json b/worlds/minecraft/data/locations.json deleted file mode 100644 index 7cd00e58519c..000000000000 --- a/worlds/minecraft/data/locations.json +++ /dev/null @@ -1,250 +0,0 @@ -{ - "all_locations": [ - "Who is Cutting Onions?", - "Oh Shiny", - "Suit Up", - "Very Very Frightening", - "Hot Stuff", - "Free the End", - "A Furious Cocktail", - "Best Friends Forever", - "Bring Home the Beacon", - "Not Today, Thank You", - "Isn't It Iron Pick", - "Local Brewery", - "The Next Generation", - "Fishy Business", - "Hot Tourist Destinations", - "This Boat Has Legs", - "Sniper Duel", - "Nether", - "Great View From Up Here", - "How Did We Get Here?", - "Bullseye", - "Spooky Scary Skeleton", - "Two by Two", - "Stone Age", - "Two Birds, One Arrow", - "We Need to Go Deeper", - "Who's the Pillager Now?", - "Getting an Upgrade", - "Tactical Fishing", - "Zombie Doctor", - "The City at the End of the Game", - "Ice Bucket Challenge", - "Remote Getaway", - "Into Fire", - "War Pigs", - "Take Aim", - "Total Beelocation", - "Arbalistic", - "The End... Again...", - "Acquire Hardware", - "Not Quite \"Nine\" Lives", - "Cover Me With Diamonds", - "Sky's the Limit", - "Hired Help", - "Return to Sender", - "Sweet Dreams", - "You Need a Mint", - "Adventure", - "Monsters Hunted", - "Enchanter", - "Voluntary Exile", - "Eye Spy", - "The End", - "Serious Dedication", - "Postmortal", - "Monster Hunter", - "Adventuring Time", - "A Seedy Place", - "Those Were the Days", - "Hero of the Village", - "Hidden in the Depths", - "Beaconator", - "Withering Heights", - "A Balanced Diet", - "Subspace Bubble", - "Husbandry", - "Country Lode, Take Me Home", - "Bee Our Guest", - "What a Deal!", - "Uneasy Alliance", - "Diamonds!", - "A Terrible Fortress", - "A Throwaway Joke", - "Minecraft", - "Sticky Situation", - "Ol' Betsy", - "Cover Me in Debris", - "The End?", - "The Parrots and the Bats", - "A Complete Catalogue", - "Getting Wood", - "Time to Mine!", - "Hot Topic", - "Bake Bread", - "The Lie", - "On a Rail", - "Time to Strike!", - "Cow Tipper", - "When Pigs Fly", - "Overkill", - "Librarian", - "Overpowered", - "Wax On", - "Wax Off", - "The Cutest Predator", - "The Healing Power of Friendship", - "Is It a Bird?", - "Is It a Balloon?", - "Is It a Plane?", - "Surge Protector", - "Light as a Rabbit", - "Glow and Behold!", - "Whatever Floats Your Goat!", - "Caves & Cliffs", - "Feels like home", - "Sound of Music", - "Star Trader", - "Birthday Song", - "Bukkit Bukkit", - "It Spreads", - "Sneak 100", - "When the Squad Hops into Town", - "With Our Powers Combined!", - "You've Got a Friend in Me" - ], - "locations_by_region": { - "Overworld": [ - "Who is Cutting Onions?", - "Oh Shiny", - "Suit Up", - "Very Very Frightening", - "Hot Stuff", - "Best Friends Forever", - "Not Today, Thank You", - "Isn't It Iron Pick", - "Fishy Business", - "Sniper Duel", - "Bullseye", - "Stone Age", - "Two Birds, One Arrow", - "Getting an Upgrade", - "Tactical Fishing", - "Zombie Doctor", - "Ice Bucket Challenge", - "Take Aim", - "Total Beelocation", - "Arbalistic", - "Acquire Hardware", - "Cover Me With Diamonds", - "Hired Help", - "Sweet Dreams", - "Adventure", - "Monsters Hunted", - "Enchanter", - "Eye Spy", - "Monster Hunter", - "Adventuring Time", - "A Seedy Place", - "Husbandry", - "Bee Our Guest", - "Diamonds!", - "A Throwaway Joke", - "Minecraft", - "Sticky Situation", - "Ol' Betsy", - "The Parrots and the Bats", - "Getting Wood", - "Time to Mine!", - "Hot Topic", - "Bake Bread", - "The Lie", - "On a Rail", - "Time to Strike!", - "Cow Tipper", - "When Pigs Fly", - "Librarian", - "Wax On", - "Wax Off", - "The Cutest Predator", - "The Healing Power of Friendship", - "Is It a Bird?", - "Surge Protector", - "Light as a Rabbit", - "Glow and Behold!", - "Whatever Floats Your Goat!", - "Caves & Cliffs", - "Sound of Music", - "Bukkit Bukkit", - "It Spreads", - "Sneak 100", - "When the Squad Hops into Town" - ], - "The Nether": [ - "Hot Tourist Destinations", - "This Boat Has Legs", - "Nether", - "Two by Two", - "We Need to Go Deeper", - "Not Quite \"Nine\" Lives", - "Return to Sender", - "Serious Dedication", - "Hidden in the Depths", - "Subspace Bubble", - "Country Lode, Take Me Home", - "Uneasy Alliance", - "Cover Me in Debris", - "Is It a Balloon?", - "Feels like home", - "With Our Powers Combined!" - ], - "The End": [ - "Free the End", - "The Next Generation", - "Remote Getaway", - "The End... Again...", - "You Need a Mint", - "The End", - "The End?", - "Is It a Plane?" - ], - "Village": [ - "Postmortal", - "Hero of the Village", - "A Balanced Diet", - "What a Deal!", - "A Complete Catalogue", - "Star Trader" - ], - "Nether Fortress": [ - "A Furious Cocktail", - "Bring Home the Beacon", - "Local Brewery", - "How Did We Get Here?", - "Spooky Scary Skeleton", - "Into Fire", - "Beaconator", - "Withering Heights", - "A Terrible Fortress", - "Overkill" - ], - "Pillager Outpost": [ - "Who's the Pillager Now?", - "Voluntary Exile", - "Birthday Song", - "You've Got a Friend in Me" - ], - "Bastion Remnant": [ - "War Pigs", - "Those Were the Days", - "Overpowered" - ], - "End City": [ - "Great View From Up Here", - "The City at the End of the Game", - "Sky's the Limit" - ] - } -} \ No newline at end of file diff --git a/worlds/minecraft/data/regions.json b/worlds/minecraft/data/regions.json deleted file mode 100644 index c9e51e48292e..000000000000 --- a/worlds/minecraft/data/regions.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "regions": [ - ["Menu", ["New World"]], - ["Overworld", ["Nether Portal", "End Portal", "Overworld Structure 1", "Overworld Structure 2"]], - ["The Nether", ["Nether Structure 1", "Nether Structure 2"]], - ["The End", ["The End Structure"]], - ["Village", []], - ["Pillager Outpost", []], - ["Nether Fortress", []], - ["Bastion Remnant", []], - ["End City", []] - ], - "mandatory_connections": [ - ["New World", "Overworld"], - ["Nether Portal", "The Nether"], - ["End Portal", "The End"] - ], - "default_connections": [ - ["Overworld Structure 1", "Village"], - ["Overworld Structure 2", "Pillager Outpost"], - ["Nether Structure 1", "Nether Fortress"], - ["Nether Structure 2", "Bastion Remnant"], - ["The End Structure", "End City"] - ], - "illegal_connections": { - "Nether Fortress": ["The End Structure"] - } -} \ No newline at end of file diff --git a/worlds/minecraft/docs/en_Minecraft.md b/worlds/minecraft/docs/en_Minecraft.md deleted file mode 100644 index 3a69a7f59a22..000000000000 --- a/worlds/minecraft/docs/en_Minecraft.md +++ /dev/null @@ -1,113 +0,0 @@ -# Minecraft - -## Where is the options page? - -The [player options page for this game](../player-options) contains all the options you need to configure and export a -config file. - -## What does randomization do to this game? - -Some recipes are locked from being able to be crafted and shuffled into the item pool. It can also optionally change which -structures appear in each dimension. Crafting recipes are re-learned when they are received from other players as item -checks, and occasionally when completing your own achievements. See below for which recipes are shuffled. - -## What is considered a location check in Minecraft? - -Location checks are completed when the player completes various Minecraft achievements. Opening the advancements menu -in-game by pressing "L" will display outstanding achievements. - -## When the player receives an item, what happens? - -When the player receives an item in Minecraft, it either unlocks crafting recipes or puts items into the player's -inventory directly. - -## What is the victory condition? - -Victory is achieved when the player kills the Ender Dragon, enters the portal in The End, and completes the credits -sequence either by skipping it or watching it play out. - -## Which recipes are locked? - -* Archery - * Bow - * Arrow - * Crossbow -* Brewing - * Blaze Powder - * Brewing Stand -* Enchanting - * Enchanting Table - * Bookshelf -* Bucket -* Flint & Steel -* All Beds -* Bottles -* Shield -* Fishing Rod - * Fishing Rod - * Carrot on a Stick - * Warped Fungus on a Stick -* Campfire - * Campfire - * Soul Campfire -* Spyglass -* Lead -* Progressive Weapons - * Tier I - * Stone Sword - * Stone Axe - * Tier II - * Iron Sword - * Iron Axe - * Tier III - * Diamond Sword - * Diamond Axe -* Progessive Tools - * Tier I - * Stone Pickaxe - * Stone Shovel - * Stone Hoe - * Tier II - * Iron Pickaxe - * Iron Shovel - * Iron Hoe - * Tier III - * Diamond Pickaxe - * Diamond Shovel - * Diamond Hoe - * Netherite Ingot -* Progressive Armor - * Tier I - * Iron Helmet - * Iron Chestplate - * Iron Leggings - * Iron Boots - * Tier II - * Diamond Helmet - * Diamond Chestplate - * Diamond Leggings - * Diamond Boots -* Progressive Resource Crafting - * Tier I - * Iron Ingot from Nuggets - * Iron Nugget - * Gold Ingot from Nuggets - * Gold Nugget - * Furnace - * Blast Furnace - * Tier II - * Redstone - * Redstone Block - * Glowstone - * Iron Ingot from Iron Block - * Iron Block - * Gold Ingot from Gold Block - * Gold Block - * Diamond - * Diamond Block - * Netherite Block - * Netherite Ingot from Netherite Block - * Anvil - * Emerald - * Emerald Block - * Copper Block diff --git a/worlds/minecraft/docs/minecraft_en.md b/worlds/minecraft/docs/minecraft_en.md deleted file mode 100644 index e0b5ae3b98b5..000000000000 --- a/worlds/minecraft/docs/minecraft_en.md +++ /dev/null @@ -1,74 +0,0 @@ -# Minecraft Randomizer Setup Guide - -## Required Software - -- Minecraft Java Edition from - the [Minecraft Java Edition Store Page](https://www.minecraft.net/en-us/store/minecraft-java-edition) -- Archipelago from the [Archipelago Releases Page](https://github.com/ArchipelagoMW/Archipelago/releases) - -## Configuring your YAML file - -### What is a YAML file and why do I need one? - -See the guide on setting up a basic YAML at the Archipelago setup -guide: [Basic Multiworld Setup Guide](/tutorial/Archipelago/setup/en) - -### Where do I get a YAML file? - -You can customize your options by visiting the [Minecraft Player Options Page](/games/Minecraft/player-options) - -## Joining a MultiWorld Game - -### Obtain Your Minecraft Data File - -**Only one yaml file needs to be submitted per minecraft world regardless of how many players play on it.** - -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 `.apmc` extension. - -Double-click on your `.apmc` file to have the Minecraft client auto-launch the installed forge server. Make sure to -leave this window open as this is your server console. - -### Connect to the MultiServer - -Open Minecraft, go to `Multiplayer > Direct Connection`, and join the `localhost` server address. - -If you are using the website to host the game then it should auto-connect to the AP server without the need to `/connect` - -otherwise once you are in game type `/connect (Port) (Password)` where `` is the address of the -Archipelago server. `(Port)` is only required if the Archipelago server is not using the default port of 38281. Note that there is no colon between `` and `(Port)`. -`(Password)` is only required if the Archipelago server you are using has a password set. - -### Play the game - -When the console tells you that you have joined the room, you're all set. Congratulations on successfully joining a -multiworld game! At this point any additional minecraft players may connect to your forge server. To start the game once -everyone is ready use the command `/start`. - -## Non-Windows Installation - -The Minecraft Client will install forge and the mod for other operating systems but Java has to be provided by the -user. Head to [minecraft_versions.json on the MC AP GitHub](https://raw.githubusercontent.com/KonoTyran/Minecraft_AP_Randomizer/master/versions/minecraft_versions.json) -to see which java version is required. New installations will default to the topmost "release" version. -- Install the matching Amazon Corretto JDK - - see [Manual Installation Software Links](#manual-installation-software-links) - - or package manager provided by your OS / distribution -- Open your `host.yaml` and add the path to your Java below the `minecraft_options` key - - ` java: "path/to/java-xx-amazon-corretto/bin/java"` -- Run the Minecraft Client and select your .apmc file - -## Full Manual Installation - -It is highly recommended to ues the Archipelago installer to handle the installation of the forge server for you. -Support will not be given for those wishing to manually install forge. For those of you who know how, and wish to do so, -the following links are the versions of the software we use. - -### Manual Installation Software Links - -- [Minecraft Forge Download Page](https://files.minecraftforge.net/net/minecraftforge/forge/) -- [Minecraft Archipelago Randomizer Mod Releases Page](https://github.com/KonoTyran/Minecraft_AP_Randomizer/releases) - - **DO NOT INSTALL THIS ON YOUR CLIENT** -- [Amazon Corretto](https://docs.aws.amazon.com/corretto/) - - pick the matching version and select "Downloads" on the left - diff --git a/worlds/minecraft/docs/minecraft_es.md b/worlds/minecraft/docs/minecraft_es.md deleted file mode 100644 index 4f4899212240..000000000000 --- a/worlds/minecraft/docs/minecraft_es.md +++ /dev/null @@ -1,148 +0,0 @@ -# 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 - -- [Minecraft Java Edition](https://www.minecraft.net/en-us/store/minecraft-java-edition) - -## Configura tu fichero YAML - -### Que es un fichero YAML y potque 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 minecraft tendra este aspecto. - -```yaml -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 - -# Opciones compartidas por todos los juegos: -accessibility: full -progression_balancing: 50 -# 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 - -### Obten tu ficheros de datos Minecraft - -**Solo un fichero yaml es necesario por mundo minecraft, sin importar el numero de jugadores que jueguen en el.** - -Cuando te unes a un juego multiworld, se te pedirá que entregues tu fichero YAML a quien sea que hospede el juego -multiworld (no confundir con hospedar el mundo minecraft). 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`. - -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 (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) - **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. - -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 diff --git a/worlds/minecraft/docs/minecraft_fr.md b/worlds/minecraft/docs/minecraft_fr.md deleted file mode 100644 index 31c48151f491..000000000000 --- a/worlds/minecraft/docs/minecraft_fr.md +++ /dev/null @@ -1,74 +0,0 @@ -# Guide de configuration du randomiseur Minecraft - -## Logiciel requis - -- Minecraft Java Edition à partir de - la [page de la boutique Minecraft Java Edition](https://www.minecraft.net/en-us/store/minecraft-java-edition) -- Archipelago depuis la [page des versions d'Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) - - (sélectionnez `Minecraft Client` lors de l'installation.) - -## Configuration de votre fichier YAML - -### Qu'est-ce qu'un fichier YAML et pourquoi en ai-je besoin ? - -Voir le guide sur la configuration d'un YAML de base lors de la configuration d'Archipelago -guide : [Guide de configuration de base de Multiworld](/tutorial/Archipelago/setup/en) - -### Où puis-je obtenir un fichier YAML ? - -Vous pouvez personnaliser vos paramètres Minecraft en allant sur la [page des paramètres de joueur](/games/Minecraft/player-options) - -## Rejoindre une partie MultiWorld - -### Obtenez votre fichier de données Minecraft - -**Un seul fichier yaml doit être soumis par monde minecraft, quel que soit le nombre de joueurs qui y jouent.** - -Lorsque vous rejoignez un jeu multimonde, il vous sera demandé de fournir votre fichier YAML à l'hébergeur. Une fois cela fait, -l'hébergeur vous fournira soit un lien pour télécharger votre fichier de données, soit un fichier zip contenant les données de chacun -des dossiers. Votre fichier de données doit avoir une extension `.apmc`. - -Double-cliquez sur votre fichier `.apmc` pour que le client Minecraft lance automatiquement le serveur forge installé. Assurez-vous de -laissez cette fenêtre ouverte car il s'agit de votre console serveur. - -### Connectez-vous au multiserveur - -Ouvrez Minecraft, accédez à "Multijoueur> Connexion directe" et rejoignez l'adresse du serveur "localhost". - -Si vous utilisez le site Web pour héberger le jeu, il devrait se connecter automatiquement au serveur AP sans avoir besoin de `/connect` - -sinon, une fois que vous êtes dans le jeu, tapez `/connect (Port) (Password)` où `` est l'adresse du -Serveur Archipelago. `(Port)` n'est requis que si le serveur Archipelago n'utilise pas le port par défaut 38281. Notez qu'il n'y a pas de deux-points entre `` et `(Port)` mais un espace. -`(Mot de passe)` n'est requis que si le serveur Archipelago que vous utilisez a un mot de passe défini. - -### Jouer le jeu - -Lorsque la console vous indique que vous avez rejoint la salle, vous êtes prêt. Félicitations pour avoir rejoint avec succès un -jeu multimonde ! À ce stade, tous les joueurs minecraft supplémentaires peuvent se connecter à votre serveur forge. Pour commencer le jeu une fois -que tout le monde est prêt utilisez la commande `/start`. - -## Installation non Windows - -Le client Minecraft installera forge et le mod pour d'autres systèmes d'exploitation, mais Java doit être fourni par l' -utilisateur. Rendez-vous sur [minecraft_versions.json sur le MC AP GitHub](https://raw.githubusercontent.com/KonoTyran/Minecraft_AP_Randomizer/master/versions/minecraft_versions.json) -pour voir quelle version de Java est requise. Les nouvelles installations utiliseront par défaut la version "release" la plus élevée. -- Installez le JDK Amazon Corretto correspondant - - voir les [Liens d'installation manuelle du logiciel](#manual-installation-software-links) - - ou gestionnaire de paquets fourni par votre OS/distribution -- Ouvrez votre `host.yaml` et ajoutez le chemin vers votre Java sous la clé `minecraft_options` - - ` java : "chemin/vers/java-xx-amazon-corretto/bin/java"` -- Exécutez le client Minecraft et sélectionnez votre fichier .apmc - -## Installation manuelle complète - -Il est fortement recommandé d'utiliser le programme d'installation d'Archipelago pour gérer l'installation du serveur forge pour vous. -Le support ne sera pas fourni pour ceux qui souhaitent installer manuellement forge. Pour ceux d'entre vous qui savent comment faire et qui souhaitent le faire, -les liens suivants sont les versions des logiciels que nous utilisons. - -### Liens d'installation manuelle du logiciel - -- [Page de téléchargement de Minecraft Forge] (https://files.minecraftforge.net/net/minecraftforge/forge/) -- [Page des versions du mod Minecraft Archipelago Randomizer] (https://github.com/KonoTyran/Minecraft_AP_Randomizer/releases) - - **NE PAS INSTALLER CECI SUR VOTRE CLIENT** -- [Amazon Corretto](https://docs.aws.amazon.com/corretto/) - - choisissez la version correspondante et sélectionnez "Téléchargements" sur la gauche diff --git a/worlds/minecraft/docs/minecraft_sv.md b/worlds/minecraft/docs/minecraft_sv.md deleted file mode 100644 index ab8c1b5d8ea7..000000000000 --- a/worlds/minecraft/docs/minecraft_sv.md +++ /dev/null @@ -1,132 +0,0 @@ -# Minecraft Randomizer Uppsättningsguide - -## Nödvändig Mjukvara - -### Server Värd - -- [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) - -### Spelare - -- [Minecraft Java Edition](https://www.minecraft.net/en-us/store/minecraft-java-edition) - -## Installationsprocedurer - -### Tillägnad - -Bara en person behöver göra denna uppsättning och vara värd för en server för alla andra spelare att koppla till. - -1. Ladda ner 1.16.5 **Minecraft Forge** installeraren från länken ovanför och se till att ladda ner den senaste - rekommenderade versionen. - -2. Kör `forge-1.16.5-xx.x.x-installer.jar` filen och välj **installera server**. - - På denna sida kommer du också välja vart du ska installera servern för att komma ihåg denna katalog. Detta är - viktigt för nästa steg. - -3. Navigera till vart du har installerat servern och öppna `forge-1.16.5-xx.x.x-installer.jar` - - Under första serverstart så kommer den att stängas ner och fråga dig att acceptera Minecrafts EULA. En ny fil - kommer skapas vid namn `eula.txt` som har en länk till Minecrafts EULA, och en linje som du behöver byta - till `eula=true` för att acceptera Minecrafts EULA. - - Detta kommer skapa de lämpliga katalogerna för dig att placera filerna i de följande steget. - -4. Placera `aprandomizer-x.x.x.jar` länken ovanför i `mods` mappen som ligger ovanför installationen av din forge - server. - - Kör servern igen. Den kommer ladda up och generera den nödvändiga katalogen `APData` för när du är redo att spela! - -### Grundläggande Spelaruppsättning - -- Köp och installera Minecraft från länken ovanför. - - **Du är klar**. - - Andra spelare behöver endast ha en 'Vanilla' omodifierad version av Minecraft för att kunna spela! - -### Avancerad Spelaruppsättning - -***Detta är inte nödvändigt för att spela ett slumpmässigt Minecraftspel.*** -Dock så är det rekommenderat eftersom det hjälper att göra upplevelsen mer trevligt. - -#### Rekommenderade Moddar - -- [JourneyMap](https://www.curseforge.com/minecraft/mc-mods/journeymap) (Minimap) - - -1. Installera och Kör Minecraft från länken ovanför minst en gång. -2. Kör `forge-1.16.5-xx.x.x-installer.jar` filen och välj **installera klient**. - - Starta Minecraft Forge minst en gång för att skapa katalogerna som behövs för de nästa stegen. -3. Navigera till din Minecraft installationskatalog och placera de önskade moddarna med `.jar` i `mods` -katalogen. - - Standardinstallationskatalogerna är som följande; - - Windows `%APPDATA%\.minecraft\mods` - - macOS `~/Library/Application Support/minecraft/mods` - - Linux `~/.minecraft/mods` - -## Konfigurera Din YAML-fil - -### Vad är en YAML-fil och varför behöver jag en? - -Din YAML-fil behåller en uppsättning av konfigurationsalternativ som ger generatorn med information om hur den borde -generera ditt spel. Varje spelare i en multivärld kommer behöva ge deras egen YAML-fil. Denna uppsättning tillåter varje -spelare att an njuta av en upplevelse anpassade för deras smaker, och olika spelare i samma multivärld kan ha helt olika -alternativ. - -### Vart kan jag få tag i en YAML-fil? - -En grundläggande Minecraft YAML kommer se ut så här. - -```yaml -description: Template Name -# Ditt spelnamn. Mellanslag kommer bli omplacerad med understräck och det är en 16-karaktärsgräns. -name: YourName -game: Minecraft -accessibility: full -progression_balancing: 0 -advancement_goal: - few: 0 - normal: 1 - many: 0 -combat_difficulty: - easy: 0 - normal: 1 - hard: 0 -include_hard_advancements: - on: 0 - off: 1 -include_insane_advancements: - on: 0 - off: 1 -include_postgame_advancements: - on: 0 - off: 1 -shuffle_structures: - on: 1 - off: 0 -``` - - -## Gå med i ett Multivärld-spel - -### Skaffa din Minecraft data-fil - -**Endast en YAML-fil behöver användats per Minecraft-värld oavsett hur många spelare det är som spelar.** - -När du går med it ett Multivärld spel så kommer du bli ombedd att lämna in din YAML-fil till personen som värdar. När -detta är klart så kommer värden att ge dig antingen en länk till att ladda ner din data-fil, eller mer en zip-fil som -innehåller allas data-filer. Din data-fil borde ha en `.apmc` -extension. - -Lägg din data-fil i dina forge-servrar `APData` -mapp. Se till att ta bort alla tidigare data-filer som var i där förut. - -### Koppla till Multiservern - -Efter du har placerat din data-fil i `APData` -mappen, starta forge-servern och se till att you har OP-status genom att -skriva `/op DittAnvändarnamn` i forger-serverns konsol innan du kopplar dig till din Minecraft klient. När du är inne i -spelet, skriv `/connect ()` där `` är addressen av -Archipelago-servern. `()` är endast nödvändigt om Archipelago-servern som du använder har ett tillsatt -lösenord. - -### Spela spelet - -När konsolen har informerat att du har gått med i rummet så är du redo att börja spela. Grattis att du har lykats med -att gått med i ett Multivärld-spel! Vid detta tillfälle, alla ytterligare Minecraft-spelare må koppla in till din -forge-server. - diff --git a/worlds/minecraft/requirements.txt b/worlds/minecraft/requirements.txt deleted file mode 100644 index 85fe230fe57b..000000000000 --- a/worlds/minecraft/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests >= 2.28.1 # used by client diff --git a/worlds/minecraft/test/TestAdvancements.py b/worlds/minecraft/test/TestAdvancements.py deleted file mode 100644 index 321aef1af934..000000000000 --- a/worlds/minecraft/test/TestAdvancements.py +++ /dev/null @@ -1,1410 +0,0 @@ -from . import MCTestBase - - -# Format: -# [location, expected_result, given_items, [excluded_items]] -# Every advancement has its own test, named by its internal ID number. -class TestAdvancements(MCTestBase): - options = { - "shuffle_structures": False, - "structure_compasses": False - } - - def test_42000(self): - self.run_location_tests([ - ["Who is Cutting Onions?", False, []], - ["Who is Cutting Onions?", False, [], ['Progressive Resource Crafting']], - ["Who is Cutting Onions?", False, [], ['Flint and Steel']], - ["Who is Cutting Onions?", False, [], ['Progressive Tools']], - ["Who is Cutting Onions?", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Who is Cutting Onions?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], - ["Who is Cutting Onions?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], - ]) - - def test_42001(self): - self.run_location_tests([ - ["Oh Shiny", False, []], - ["Oh Shiny", False, [], ['Progressive Resource Crafting']], - ["Oh Shiny", False, [], ['Flint and Steel']], - ["Oh Shiny", False, [], ['Progressive Tools']], - ["Oh Shiny", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Oh Shiny", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], - ["Oh Shiny", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], - ]) - - def test_42002(self): - self.run_location_tests([ - ["Suit Up", False, []], - ["Suit Up", False, [], ["Progressive Armor"]], - ["Suit Up", False, [], ["Progressive Resource Crafting"]], - ["Suit Up", False, [], ["Progressive Tools"]], - ["Suit Up", True, ["Progressive Armor", "Progressive Resource Crafting", "Progressive Tools"]], - ]) - - def test_42003(self): - self.run_location_tests([ - ["Very Very Frightening", False, []], - ["Very Very Frightening", False, [], ['Channeling Book']], - ["Very Very Frightening", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["Very Very Frightening", False, [], ['Enchanting']], - ["Very Very Frightening", False, [], ['Progressive Tools']], - ["Very Very Frightening", False, [], ['Progressive Weapons']], - ["Very Very Frightening", True, ['Progressive Weapons', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', - 'Enchanting', 'Progressive Resource Crafting', 'Progressive Resource Crafting', 'Channeling Book']], - ]) - - def test_42004(self): - self.run_location_tests([ - ["Hot Stuff", False, []], - ["Hot Stuff", False, [], ["Bucket"]], - ["Hot Stuff", False, [], ["Progressive Resource Crafting"]], - ["Hot Stuff", False, [], ["Progressive Tools"]], - ["Hot Stuff", True, ["Bucket", "Progressive Resource Crafting", "Progressive Tools"]], - ]) - - def test_42005(self): - self.run_location_tests([ - ["Free the End", False, []], - ["Free the End", False, [], ['Progressive Resource Crafting']], - ["Free the End", False, [], ['Flint and Steel']], - ["Free the End", False, [], ['Progressive Tools']], - ["Free the End", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], - ["Free the End", False, [], ['Progressive Armor']], - ["Free the End", False, [], ['Brewing']], - ["Free the End", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Free the End", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["Free the End", False, [], ['Archery']], - ["Free the End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["Free the End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42006(self): - self.run_location_tests([ - ["A Furious Cocktail", False, []], - ["A Furious Cocktail", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["A Furious Cocktail", False, [], ['Flint and Steel']], - ["A Furious Cocktail", False, [], ['Progressive Tools']], - ["A Furious Cocktail", False, [], ['Progressive Weapons']], - ["A Furious Cocktail", False, [], ['Progressive Armor', 'Shield']], - ["A Furious Cocktail", False, [], ['Brewing']], - ["A Furious Cocktail", False, [], ['Bottles']], - ["A Furious Cocktail", False, [], ['Fishing Rod']], - ["A Furious Cocktail", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["A Furious Cocktail", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', - 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', - 'Progressive Armor', 'Progressive Armor', - 'Enchanting', 'Brewing', 'Bottles', 'Fishing Rod']], - ]) - - def test_42007(self): - self.run_location_tests([ - ["Best Friends Forever", True, []], - ]) - - def test_42008(self): - self.run_location_tests([ - ["Bring Home the Beacon", False, []], - ["Bring Home the Beacon", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["Bring Home the Beacon", False, [], ['Flint and Steel']], - ["Bring Home the Beacon", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Bring Home the Beacon", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], - ["Bring Home the Beacon", False, ['Progressive Armor'], ['Progressive Armor']], - ["Bring Home the Beacon", False, [], ['Enchanting']], - ["Bring Home the Beacon", False, [], ['Brewing']], - ["Bring Home the Beacon", False, [], ['Bottles']], - ["Bring Home the Beacon", True, [], ['Bucket']], - ["Bring Home the Beacon", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', - 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', - 'Progressive Armor', 'Progressive Armor', - 'Enchanting', 'Brewing', 'Bottles']], - ]) - - def test_42009(self): - self.run_location_tests([ - ["Not Today, Thank You", False, []], - ["Not Today, Thank You", False, [], ["Shield"]], - ["Not Today, Thank You", False, [], ["Progressive Resource Crafting"]], - ["Not Today, Thank You", False, [], ["Progressive Tools"]], - ["Not Today, Thank You", True, ["Shield", "Progressive Resource Crafting", "Progressive Tools"]], - ]) - - def test_42010(self): - self.run_location_tests([ - ["Isn't It Iron Pick", False, []], - ["Isn't It Iron Pick", True, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools"]], - ["Isn't It Iron Pick", False, [], ["Progressive Tools", "Progressive Tools"]], - ["Isn't It Iron Pick", False, [], ["Progressive Resource Crafting"]], - ["Isn't It Iron Pick", False, ["Progressive Tools", "Progressive Resource Crafting"]], - ["Isn't It Iron Pick", True, ["Progressive Tools", "Progressive Tools", "Progressive Resource Crafting"]], - ]) - - def test_42011(self): - self.run_location_tests([ - ["Local Brewery", False, []], - ["Local Brewery", False, [], ['Progressive Resource Crafting']], - ["Local Brewery", False, [], ['Flint and Steel']], - ["Local Brewery", False, [], ['Progressive Tools']], - ["Local Brewery", False, [], ['Progressive Weapons']], - ["Local Brewery", False, [], ['Progressive Armor', 'Shield']], - ["Local Brewery", False, [], ['Brewing']], - ["Local Brewery", False, [], ['Bottles']], - ["Local Brewery", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Local Brewery", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], - ["Local Brewery", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], - ["Local Brewery", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], - ["Local Brewery", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], - ]) - - def test_42012(self): - self.run_location_tests([ - ["The Next Generation", False, []], - ["The Next Generation", False, [], ['Progressive Resource Crafting']], - ["The Next Generation", False, [], ['Flint and Steel']], - ["The Next Generation", False, [], ['Progressive Tools']], - ["The Next Generation", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], - ["The Next Generation", False, [], ['Progressive Armor']], - ["The Next Generation", False, [], ['Brewing']], - ["The Next Generation", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["The Next Generation", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["The Next Generation", False, [], ['Archery']], - ["The Next Generation", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The Next Generation", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42013(self): - self.run_location_tests([ - ["Fishy Business", False, []], - ["Fishy Business", False, [], ['Fishing Rod']], - ["Fishy Business", True, ['Fishing Rod']], - ]) - - def test_42014(self): - self.run_location_tests([ - ["Hot Tourist Destinations", False, []], - ["Hot Tourist Destinations", False, [], ['Progressive Resource Crafting']], - ["Hot Tourist Destinations", False, [], ['Flint and Steel']], - ["Hot Tourist Destinations", False, [], ['Progressive Tools']], - ["Hot Tourist Destinations", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Hot Tourist Destinations", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], - ["Hot Tourist Destinations", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], - ]) - - def test_42015(self): - self.run_location_tests([ - ["This Boat Has Legs", False, []], - ["This Boat Has Legs", False, [], ['Progressive Resource Crafting']], - ["This Boat Has Legs", False, [], ['Flint and Steel']], - ["This Boat Has Legs", False, [], ['Progressive Tools']], - ["This Boat Has Legs", False, [], ['Progressive Weapons']], - ["This Boat Has Legs", False, [], ['Progressive Armor', 'Shield']], - ["This Boat Has Legs", False, [], ['Fishing Rod']], - ["This Boat Has Legs", False, [], ['Saddle']], - ["This Boat Has Legs", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["This Boat Has Legs", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor', 'Flint and Steel', 'Bucket', 'Fishing Rod']], - ["This Boat Has Legs", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Fishing Rod']], - ["This Boat Has Legs", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Weapons', 'Shield', 'Flint and Steel', 'Bucket', 'Fishing Rod']], - ["This Boat Has Legs", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Weapons', 'Shield', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Fishing Rod']], - ]) - - def test_42016(self): - self.run_location_tests([ - ["Sniper Duel", False, []], - ["Sniper Duel", False, [], ['Archery']], - ["Sniper Duel", True, ['Archery']], - ]) - - def test_42017(self): - self.run_location_tests([ - ["Nether", False, []], - ["Nether", False, [], ['Progressive Resource Crafting']], - ["Nether", False, [], ['Flint and Steel']], - ["Nether", False, [], ['Progressive Tools']], - ["Nether", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Nether", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], - ["Nether", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], - ]) - - def test_42018(self): - self.run_location_tests([ - ["Great View From Up Here", False, []], - ["Great View From Up Here", False, [], ['Progressive Resource Crafting']], - ["Great View From Up Here", False, [], ['Flint and Steel']], - ["Great View From Up Here", False, [], ['Progressive Tools']], - ["Great View From Up Here", False, [], ['Progressive Weapons']], - ["Great View From Up Here", False, [], ['Progressive Armor', 'Shield']], - ["Great View From Up Here", False, [], ['Brewing']], - ["Great View From Up Here", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Great View From Up Here", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["Great View From Up Here", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["Great View From Up Here", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["Great View From Up Here", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["Great View From Up Here", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42019(self): - self.run_location_tests([ - ["How Did We Get Here?", False, []], - ["How Did We Get Here?", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["How Did We Get Here?", False, [], ['Flint and Steel']], - ["How Did We Get Here?", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["How Did We Get Here?", False, ['Progressive Weapons', 'Progressive Weapons'], ['Progressive Weapons']], - ["How Did We Get Here?", False, ['Progressive Armor'], ['Progressive Armor']], - ["How Did We Get Here?", False, [], ['Shield']], - ["How Did We Get Here?", False, [], ['Enchanting']], - ["How Did We Get Here?", False, [], ['Brewing']], - ["How Did We Get Here?", False, [], ['Bottles']], - ["How Did We Get Here?", False, [], ['Archery']], - ["How Did We Get Here?", False, [], ['Fishing Rod']], - ["How Did We Get Here?", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["How Did We Get Here?", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', 'Flint and Steel', - 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', - 'Progressive Armor', 'Progressive Armor', 'Shield', - 'Enchanting', 'Brewing', 'Archery', 'Bottles', 'Fishing Rod', - '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42020(self): - self.run_location_tests([ - ["Bullseye", False, []], - ["Bullseye", False, [], ['Archery']], - ["Bullseye", False, [], ['Progressive Resource Crafting']], - ["Bullseye", False, [], ['Progressive Tools']], - ["Bullseye", True, ['Progressive Tools', 'Progressive Tools', 'Progressive Resource Crafting', 'Archery']], - ]) - - def test_42021(self): - self.run_location_tests([ - ["Spooky Scary Skeleton", False, []], - ["Spooky Scary Skeleton", False, [], ['Progressive Resource Crafting']], - ["Spooky Scary Skeleton", False, [], ['Flint and Steel']], - ["Spooky Scary Skeleton", False, [], ['Progressive Tools']], - ["Spooky Scary Skeleton", False, [], ['Progressive Weapons']], - ["Spooky Scary Skeleton", False, [], ['Progressive Armor', 'Shield']], - ["Spooky Scary Skeleton", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Spooky Scary Skeleton", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Progressive Armor']], - ["Spooky Scary Skeleton", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor']], - ["Spooky Scary Skeleton", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield']], - ["Spooky Scary Skeleton", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Shield']], - ]) - - def test_42022(self): - self.run_location_tests([ - ["Two by Two", False, []], - ["Two by Two", False, [], ['Progressive Resource Crafting']], - ["Two by Two", False, [], ['Flint and Steel']], - ["Two by Two", False, [], ['Progressive Tools']], - ["Two by Two", False, [], ['Progressive Weapons']], - ["Two by Two", False, [], ['Bucket']], - ["Two by Two", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Two by Two", False, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons']], - ["Two by Two", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons']], - ]) - - def test_42023(self): - self.run_location_tests([ - ["Stone Age", True, []], - ]) - - def test_42024(self): - self.run_location_tests([ - ["Two Birds, One Arrow", False, []], - ["Two Birds, One Arrow", False, [], ['Archery']], - ["Two Birds, One Arrow", False, [], ['Progressive Resource Crafting']], - ["Two Birds, One Arrow", False, ['Progressive Tools'], ['Progressive Tools', 'Progressive Tools']], - ["Two Birds, One Arrow", False, [], ['Enchanting']], - ["Two Birds, One Arrow", True, ['Archery', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Enchanting']], - ]) - - def test_42025(self): - self.run_location_tests([ - ["We Need to Go Deeper", False, []], - ["We Need to Go Deeper", False, [], ['Progressive Resource Crafting']], - ["We Need to Go Deeper", False, [], ['Flint and Steel']], - ["We Need to Go Deeper", False, [], ['Progressive Tools']], - ["We Need to Go Deeper", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["We Need to Go Deeper", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], - ["We Need to Go Deeper", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], - ]) - - def test_42026(self): - self.run_location_tests([ - ["Who's the Pillager Now?", False, []], - ["Who's the Pillager Now?", False, [], ['Archery']], - ["Who's the Pillager Now?", False, [], ['Progressive Resource Crafting']], - ["Who's the Pillager Now?", False, [], ['Progressive Tools']], - ["Who's the Pillager Now?", False, [], ['Progressive Weapons']], - ["Who's the Pillager Now?", True, ['Archery', 'Progressive Tools', 'Progressive Weapons', 'Progressive Resource Crafting']], - ]) - - def test_42027(self): - self.run_location_tests([ - ["Getting an Upgrade", False, []], - ["Getting an Upgrade", True, ["Progressive Tools"]], - ]) - - def test_42028(self): - self.run_location_tests([ - ["Tactical Fishing", False, []], - ["Tactical Fishing", False, [], ['Progressive Resource Crafting']], - ["Tactical Fishing", False, [], ['Progressive Tools']], - ["Tactical Fishing", False, [], ['Bucket']], - ["Tactical Fishing", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Bucket']], - ]) - - def test_42029(self): - self.run_location_tests([ - ["Zombie Doctor", False, []], - ["Zombie Doctor", False, [], ['Progressive Resource Crafting']], - ["Zombie Doctor", False, [], ['Flint and Steel']], - ["Zombie Doctor", False, [], ['Progressive Tools']], - ["Zombie Doctor", False, [], ['Progressive Weapons']], - ["Zombie Doctor", False, [], ['Progressive Armor', 'Shield']], - ["Zombie Doctor", False, [], ['Brewing']], - ["Zombie Doctor", False, [], ['Bottles']], - ["Zombie Doctor", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Zombie Doctor", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], - ["Zombie Doctor", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], - ["Zombie Doctor", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], - ["Zombie Doctor", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], - ]) - - def test_42030(self): - self.run_location_tests([ - ["The City at the End of the Game", False, []], - ["The City at the End of the Game", False, [], ['Progressive Resource Crafting']], - ["The City at the End of the Game", False, [], ['Flint and Steel']], - ["The City at the End of the Game", False, [], ['Progressive Tools']], - ["The City at the End of the Game", False, [], ['Progressive Weapons']], - ["The City at the End of the Game", False, [], ['Progressive Armor', 'Shield']], - ["The City at the End of the Game", False, [], ['Brewing']], - ["The City at the End of the Game", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["The City at the End of the Game", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["The City at the End of the Game", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The City at the End of the Game", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The City at the End of the Game", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The City at the End of the Game", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42031(self): - self.run_location_tests([ - ["Ice Bucket Challenge", False, []], - ["Ice Bucket Challenge", False, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools"]], - ["Ice Bucket Challenge", False, [], ["Progressive Resource Crafting"]], - ["Ice Bucket Challenge", True, ["Progressive Tools", "Progressive Tools", "Progressive Tools", "Progressive Resource Crafting"]], - ]) - - def test_42032(self): - self.run_location_tests([ - ["Remote Getaway", False, []], - ["Remote Getaway", False, [], ['Progressive Resource Crafting']], - ["Remote Getaway", False, [], ['Flint and Steel']], - ["Remote Getaway", False, [], ['Progressive Tools']], - ["Remote Getaway", False, [], ['Progressive Weapons']], - ["Remote Getaway", False, [], ['Progressive Armor', 'Shield']], - ["Remote Getaway", False, [], ['Brewing']], - ["Remote Getaway", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Remote Getaway", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["Remote Getaway", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["Remote Getaway", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["Remote Getaway", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["Remote Getaway", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42033(self): - self.run_location_tests([ - ["Into Fire", False, []], - ["Into Fire", False, [], ['Progressive Resource Crafting']], - ["Into Fire", False, [], ['Flint and Steel']], - ["Into Fire", False, [], ['Progressive Tools']], - ["Into Fire", False, [], ['Progressive Weapons']], - ["Into Fire", False, [], ['Progressive Armor', 'Shield']], - ["Into Fire", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Into Fire", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Progressive Armor']], - ["Into Fire", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor']], - ["Into Fire", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield']], - ["Into Fire", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Shield']], - ]) - - def test_42034(self): - self.run_location_tests([ - ["War Pigs", False, []], - ["War Pigs", False, [], ['Progressive Resource Crafting']], - ["War Pigs", False, [], ['Flint and Steel']], - ["War Pigs", False, [], ['Progressive Tools']], - ["War Pigs", False, [], ['Progressive Weapons']], - ["War Pigs", False, [], ['Progressive Armor', 'Shield']], - ["War Pigs", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["War Pigs", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield']], - ["War Pigs", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Shield']], - ]) - - def test_42035(self): - self.run_location_tests([ - ["Take Aim", False, []], - ["Take Aim", False, [], ['Archery']], - ["Take Aim", True, ['Archery']], - ]) - - def test_42036(self): - self.run_location_tests([ - ["Total Beelocation", False, []], - ["Total Beelocation", False, [], ['Enchanting']], - ["Total Beelocation", False, [], ['Silk Touch Book']], - ["Total Beelocation", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["Total Beelocation", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Total Beelocation", True, ['Enchanting', 'Silk Touch Book', 'Progressive Resource Crafting', 'Progressive Resource Crafting', - 'Progressive Tools', 'Progressive Tools', 'Progressive Tools']], - ]) - - def test_42037(self): - self.run_location_tests([ - ["Arbalistic", False, []], - ["Arbalistic", False, [], ['Enchanting']], - ["Arbalistic", False, [], ['Piercing IV Book']], - ["Arbalistic", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["Arbalistic", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Arbalistic", False, [], ['Archery']], - ["Arbalistic", True, ['Enchanting', 'Piercing IV Book', 'Progressive Resource Crafting', 'Progressive Resource Crafting', - 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Archery']], - ]) - - def test_42038(self): - self.run_location_tests([ - ["The End... Again...", False, []], - ["The End... Again...", False, [], ['Progressive Resource Crafting']], - ["The End... Again...", False, [], ['Flint and Steel']], - ["The End... Again...", False, [], ['Progressive Tools']], - ["The End... Again...", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], - ["The End... Again...", False, [], ['Progressive Armor']], - ["The End... Again...", False, [], ['Brewing']], - ["The End... Again...", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["The End... Again...", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["The End... Again...", False, [], ['Archery']], - ["The End... Again...", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The End... Again...", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42039(self): - self.run_location_tests([ - ["Acquire Hardware", False, []], - ["Acquire Hardware", False, [], ["Progressive Tools"]], - ["Acquire Hardware", False, [], ["Progressive Resource Crafting"]], - ["Acquire Hardware", True, ["Progressive Tools", "Progressive Resource Crafting"]], - ]) - - def test_42040(self): - self.run_location_tests([ - ["Not Quite \"Nine\" Lives", False, []], - ["Not Quite \"Nine\" Lives", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["Not Quite \"Nine\" Lives", False, [], ['Flint and Steel']], - ["Not Quite \"Nine\" Lives", False, [], ['Progressive Tools']], - ["Not Quite \"Nine\" Lives", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Not Quite \"Nine\" Lives", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], - ["Not Quite \"Nine\" Lives", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], - ]) - - def test_42041(self): - self.run_location_tests([ - ["Cover Me With Diamonds", False, []], - ["Cover Me With Diamonds", False, ['Progressive Armor'], ['Progressive Armor']], - ["Cover Me With Diamonds", False, ['Progressive Tools'], ['Progressive Tools', 'Progressive Tools']], - ["Cover Me With Diamonds", False, [], ['Progressive Resource Crafting']], - ["Cover Me With Diamonds", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Armor', 'Progressive Armor']], - ]) - - def test_42042(self): - self.run_location_tests([ - ["Sky's the Limit", False, []], - ["Sky's the Limit", False, [], ['Progressive Resource Crafting']], - ["Sky's the Limit", False, [], ['Flint and Steel']], - ["Sky's the Limit", False, [], ['Progressive Tools']], - ["Sky's the Limit", False, [], ['Progressive Weapons']], - ["Sky's the Limit", False, [], ['Progressive Armor', 'Shield']], - ["Sky's the Limit", False, [], ['Brewing']], - ["Sky's the Limit", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Sky's the Limit", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["Sky's the Limit", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["Sky's the Limit", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["Sky's the Limit", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["Sky's the Limit", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42043(self): - self.run_location_tests([ - ["Hired Help", False, []], - ["Hired Help", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["Hired Help", False, [], ['Progressive Tools']], - ["Hired Help", True, ['Progressive Tools', 'Progressive Resource Crafting', 'Progressive Resource Crafting']], - ]) - - def test_42044(self): - self.run_location_tests([ - ["Return to Sender", False, []], - ["Return to Sender", False, [], ['Progressive Resource Crafting']], - ["Return to Sender", False, [], ['Flint and Steel']], - ["Return to Sender", False, [], ['Progressive Tools']], - ["Return to Sender", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Return to Sender", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], - ["Return to Sender", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], - ]) - - def test_42045(self): - self.run_location_tests([ - ["Sweet Dreams", False, []], - ["Sweet Dreams", True, ['Bed']], - ["Sweet Dreams", False, [], ['Bed', 'Progressive Weapons']], - ["Sweet Dreams", False, [], ['Bed', 'Progressive Resource Crafting', 'Campfire']], - ["Sweet Dreams", True, ['Progressive Weapons', 'Progressive Resource Crafting'], ['Bed', 'Campfire']], - ["Sweet Dreams", True, ['Progressive Weapons', 'Campfire'], ['Bed', 'Progressive Resource Crafting']], - ]) - - def test_42046(self): - self.run_location_tests([ - ["You Need a Mint", False, []], - ["You Need a Mint", False, [], ['Progressive Resource Crafting']], - ["You Need a Mint", False, [], ['Flint and Steel']], - ["You Need a Mint", False, [], ['Progressive Tools']], - ["You Need a Mint", False, [], ['Progressive Weapons']], - ["You Need a Mint", False, [], ['Progressive Armor', 'Shield']], - ["You Need a Mint", False, [], ['Brewing']], - ["You Need a Mint", False, [], ['Bottles']], - ["You Need a Mint", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["You Need a Mint", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["You Need a Mint", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', - '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Bottles']], - ["You Need a Mint", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', - '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Bottles']], - ["You Need a Mint", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', 'Brewing', - '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Bottles']], - ["You Need a Mint", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', 'Brewing', - '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Bottles']], - ]) - - def test_42047(self): - self.run_location_tests([ - ["Adventure", True, []], - ]) - - def test_42048(self): - self.run_location_tests([ - ["Monsters Hunted", False, []], - ["Monsters Hunted", False, [], ['Progressive Resource Crafting']], - ["Monsters Hunted", False, [], ['Flint and Steel']], - ["Monsters Hunted", False, [], ['Progressive Tools']], - ["Monsters Hunted", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], - ["Monsters Hunted", False, [], ['Progressive Armor']], - ["Monsters Hunted", False, [], ['Brewing']], - ["Monsters Hunted", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Monsters Hunted", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["Monsters Hunted", False, [], ['Archery']], - ["Monsters Hunted", False, [], ['Enchanting']], - ["Monsters Hunted", False, [], ['Fishing Rod']], - ["Monsters Hunted", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', 'Archery', - 'Progressive Armor', 'Progressive Armor', 'Enchanting', - 'Fishing Rod', 'Brewing', 'Bottles', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42049(self): - self.run_location_tests([ - ["Enchanter", False, []], - ["Enchanter", False, [], ['Enchanting']], - ["Enchanter", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Enchanter", False, [], ['Progressive Resource Crafting']], - ["Enchanter", True, ['Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Enchanting', 'Progressive Resource Crafting']], - ]) - - def test_42050(self): - self.run_location_tests([ - ["Voluntary Exile", False, []], - ["Voluntary Exile", False, [], ['Progressive Weapons']], - ["Voluntary Exile", False, [], ['Progressive Armor', 'Shield']], - ["Voluntary Exile", False, [], ['Progressive Tools']], - ["Voluntary Exile", False, [], ['Progressive Resource Crafting']], - ["Voluntary Exile", True, ['Progressive Tools', 'Progressive Armor', 'Progressive Weapons', 'Progressive Resource Crafting']], - ["Voluntary Exile", True, ['Progressive Tools', 'Shield', 'Progressive Weapons', 'Progressive Resource Crafting']], - ]) - - def test_42051(self): - self.run_location_tests([ - ["Eye Spy", False, []], - ["Eye Spy", False, [], ['Progressive Resource Crafting']], - ["Eye Spy", False, [], ['Flint and Steel']], - ["Eye Spy", False, [], ['Progressive Tools']], - ["Eye Spy", False, [], ['Progressive Weapons']], - ["Eye Spy", False, [], ['Progressive Armor', 'Shield']], - ["Eye Spy", False, [], ['Brewing']], - ["Eye Spy", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Eye Spy", False, [], ['3 Ender Pearls']], - ["Eye Spy", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', '3 Ender Pearls']], - ["Eye Spy", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', '3 Ender Pearls']], - ["Eye Spy", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', 'Brewing', '3 Ender Pearls']], - ["Eye Spy", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', 'Brewing', '3 Ender Pearls']], - ]) - - def test_42052(self): - self.run_location_tests([ - ["The End", False, []], - ["The End", False, [], ['Progressive Resource Crafting']], - ["The End", False, [], ['Flint and Steel']], - ["The End", False, [], ['Progressive Tools']], - ["The End", False, [], ['Progressive Weapons']], - ["The End", False, [], ['Progressive Armor', 'Shield']], - ["The End", False, [], ['Brewing']], - ["The End", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["The End", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["The End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42053(self): - self.run_location_tests([ - ["Serious Dedication", False, []], - ["Serious Dedication", False, [], ['Progressive Resource Crafting']], - ["Serious Dedication", False, [], ['Flint and Steel']], - ["Serious Dedication", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Serious Dedication", False, [], ['Progressive Weapons']], - ["Serious Dedication", False, [], ['Progressive Armor', 'Shield']], - ["Serious Dedication", False, [], ['Brewing']], - ["Serious Dedication", False, [], ['Bottles']], - ["Serious Dedication", False, [], ['Bed']], - ["Serious Dedication", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles', 'Bed']], - ["Serious Dedication", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles', 'Bed']], - ]) - - def test_42054(self): - self.run_location_tests([ - ["Postmortal", False, []], - ["Postmortal", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], - ["Postmortal", False, [], ['Progressive Armor']], - ["Postmortal", False, [], ['Shield']], - ["Postmortal", False, [], ['Progressive Resource Crafting']], - ["Postmortal", False, [], ['Progressive Tools']], - ["Postmortal", True, ['Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Shield', 'Progressive Resource Crafting', 'Progressive Tools']], - ]) - - def test_42055(self): - self.run_location_tests([ - ["Monster Hunter", True, []], - ]) - - def test_42056(self): - self.run_location_tests([ - ["Adventuring Time", False, []], - ["Adventuring Time", False, [], ['Progressive Weapons']], - ["Adventuring Time", False, [], ['Campfire', 'Progressive Resource Crafting']], - ["Adventuring Time", True, ['Progressive Weapons', 'Campfire']], - ["Adventuring Time", True, ['Progressive Weapons', 'Progressive Resource Crafting']], - ]) - - def test_42057(self): - self.run_location_tests([ - ["A Seedy Place", True, []], - ]) - - def test_42058(self): - self.run_location_tests([ - ["Those Were the Days", False, []], - ["Those Were the Days", False, [], ['Progressive Resource Crafting']], - ["Those Were the Days", False, [], ['Flint and Steel']], - ["Those Were the Days", False, [], ['Progressive Tools']], - ["Those Were the Days", False, [], ['Progressive Weapons']], - ["Those Were the Days", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Those Were the Days", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons']], - ["Those Were the Days", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons']], - ]) - - def test_42059(self): - self.run_location_tests([ - ["Hero of the Village", False, []], - ["Hero of the Village", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], - ["Hero of the Village", False, [], ['Progressive Armor']], - ["Hero of the Village", False, [], ['Shield']], - ["Hero of the Village", False, [], ['Progressive Resource Crafting']], - ["Hero of the Village", False, [], ['Progressive Tools']], - ["Hero of the Village", True, ['Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Shield', 'Progressive Resource Crafting', 'Progressive Tools']], - ]) - - def test_42060(self): - self.run_location_tests([ - ["Hidden in the Depths", False, []], - ["Hidden in the Depths", False, [], ['Progressive Resource Crafting']], - ["Hidden in the Depths", False, [], ['Flint and Steel']], - ["Hidden in the Depths", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Hidden in the Depths", False, [], ['Progressive Weapons']], - ["Hidden in the Depths", False, [], ['Progressive Armor', 'Shield']], - ["Hidden in the Depths", False, [], ['Brewing']], - ["Hidden in the Depths", False, [], ['Bottles']], - ["Hidden in the Depths", False, [], ['Bed']], - ["Hidden in the Depths", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles', 'Bed']], - ["Hidden in the Depths", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles', 'Bed']], - ]) - - def test_42061(self): - self.run_location_tests([ - ["Beaconator", False, []], - ["Beaconator", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["Beaconator", False, [], ['Flint and Steel']], - ["Beaconator", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Beaconator", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], - ["Beaconator", False, ['Progressive Armor'], ['Progressive Armor']], - ["Beaconator", False, [], ['Brewing']], - ["Beaconator", False, [], ['Bottles']], - ["Beaconator", False, [], ['Enchanting']], - ["Beaconator", True, [], ['Bucket']], - ["Beaconator", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', - 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Progressive Armor', - 'Brewing', 'Bottles', 'Enchanting']], - ]) - - def test_42062(self): - self.run_location_tests([ - ["Withering Heights", False, []], - ["Withering Heights", False, [], ['Progressive Resource Crafting']], - ["Withering Heights", False, [], ['Flint and Steel']], - ["Withering Heights", False, [], ['Progressive Tools']], - ["Withering Heights", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], - ["Withering Heights", False, ['Progressive Armor'], ['Progressive Armor']], - ["Withering Heights", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Withering Heights", False, [], ['Brewing']], - ["Withering Heights", False, [], ['Bottles']], - ["Withering Heights", False, [], ['Enchanting']], - ["Withering Heights", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Progressive Armor', - 'Brewing', 'Bottles', 'Enchanting']], - ]) - - def test_42063(self): - self.run_location_tests([ - ["A Balanced Diet", False, []], - ["A Balanced Diet", False, [], ['Bottles']], - ["A Balanced Diet", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["A Balanced Diet", False, [], ['Flint and Steel']], - ["A Balanced Diet", False, [], ['Progressive Tools']], - ["A Balanced Diet", False, [], ['Progressive Weapons']], - ["A Balanced Diet", False, [], ['Progressive Armor', 'Shield']], - ["A Balanced Diet", False, [], ['Brewing']], - ["A Balanced Diet", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["A Balanced Diet", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["A Balanced Diet", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', - 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', 'Bottles', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["A Balanced Diet", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', - 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Bottles', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["A Balanced Diet", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', - 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', 'Bottles', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["A Balanced Diet", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', - 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', 'Bottles', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42064(self): - self.run_location_tests([ - ["Subspace Bubble", False, []], - ["Subspace Bubble", False, [], ['Progressive Resource Crafting']], - ["Subspace Bubble", False, [], ['Flint and Steel']], - ["Subspace Bubble", False, [], ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Subspace Bubble", True, ['Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Progressive Resource Crafting']], - ]) - - def test_42065(self): - self.run_location_tests([ - ["Husbandry", True, []], - ]) - - def test_42066(self): - self.run_location_tests([ - ["Country Lode, Take Me Home", False, []], - ["Country Lode, Take Me Home", False, [], ['Progressive Resource Crafting']], - ["Country Lode, Take Me Home", False, [], ['Flint and Steel']], - ["Country Lode, Take Me Home", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Country Lode, Take Me Home", False, [], ['Progressive Weapons']], - ["Country Lode, Take Me Home", False, [], ['Progressive Armor', 'Shield']], - ["Country Lode, Take Me Home", False, [], ['Brewing']], - ["Country Lode, Take Me Home", False, [], ['Bottles']], - ["Country Lode, Take Me Home", False, [], ['Bed']], - ["Country Lode, Take Me Home", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles', 'Bed']], - ["Country Lode, Take Me Home", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles', 'Bed']], - ]) - - def test_42067(self): - self.run_location_tests([ - ["Bee Our Guest", False, []], - ["Bee Our Guest", False, [], ['Campfire']], - ["Bee Our Guest", False, [], ['Bottles']], - ["Bee Our Guest", False, [], ['Progressive Resource Crafting']], - ["Bee Our Guest", True, ['Campfire', 'Bottles', 'Progressive Resource Crafting']], - ]) - - def test_42068(self): - self.run_location_tests([ - ["What a Deal!", False, []], - ["What a Deal!", False, [], ['Progressive Weapons']], - ["What a Deal!", False, [], ['Campfire', 'Progressive Resource Crafting']], - ["What a Deal!", True, ['Progressive Weapons', 'Campfire']], - ["What a Deal!", True, ['Progressive Weapons', 'Progressive Resource Crafting']], - ]) - - def test_42069(self): - self.run_location_tests([ - ["Uneasy Alliance", False, []], - ["Uneasy Alliance", False, [], ['Progressive Resource Crafting']], - ["Uneasy Alliance", False, [], ['Flint and Steel']], - ["Uneasy Alliance", False, [], ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Uneasy Alliance", False, [], ['Fishing Rod']], - ["Uneasy Alliance", True, ['Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Progressive Resource Crafting', 'Fishing Rod']], - ]) - - def test_42070(self): - self.run_location_tests([ - ["Diamonds!", False, []], - ["Diamonds!", True, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools"]], - ["Diamonds!", False, [], ["Progressive Tools", "Progressive Tools"]], - ["Diamonds!", False, [], ["Progressive Resource Crafting"]], - ["Diamonds!", False, ["Progressive Tools", "Progressive Resource Crafting"]], - ["Diamonds!", True, ["Progressive Tools", "Progressive Tools", "Progressive Resource Crafting"]], - ]) - - def test_42071(self): - self.run_location_tests([ - ["A Terrible Fortress", False, []], - ["A Terrible Fortress", False, [], ['Progressive Resource Crafting']], - ["A Terrible Fortress", False, [], ['Flint and Steel']], - ["A Terrible Fortress", False, [], ['Progressive Tools']], - ["A Terrible Fortress", False, [], ['Progressive Weapons']], - ["A Terrible Fortress", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["A Terrible Fortress", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons']], - ["A Terrible Fortress", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons']], - ]) - - def test_42072(self): - self.run_location_tests([ - ["A Throwaway Joke", False, []], - ["A Throwaway Joke", False, [], ['Progressive Weapons']], - ["A Throwaway Joke", False, [], ['Campfire', 'Progressive Resource Crafting']], - ["A Throwaway Joke", True, ['Progressive Weapons', 'Campfire']], - ["A Throwaway Joke", True, ['Progressive Weapons', 'Progressive Resource Crafting']], - ]) - - def test_42073(self): - self.run_location_tests([ - ["Minecraft", True, []], - ]) - - def test_42074(self): - self.run_location_tests([ - ["Sticky Situation", False, []], - ["Sticky Situation", False, [], ['Bottles']], - ["Sticky Situation", False, [], ['Progressive Resource Crafting']], - ["Sticky Situation", False, [], ['Campfire']], - ["Sticky Situation", True, ['Bottles', 'Progressive Resource Crafting', 'Campfire']], - ]) - - def test_42075(self): - self.run_location_tests([ - ["Ol' Betsy", False, []], - ["Ol' Betsy", False, [], ['Archery']], - ["Ol' Betsy", False, [], ['Progressive Resource Crafting']], - ["Ol' Betsy", False, [], ['Progressive Tools']], - ["Ol' Betsy", True, ['Archery', 'Progressive Resource Crafting', 'Progressive Tools']], - ]) - - def test_42076(self): - self.run_location_tests([ - ["Cover Me in Debris", False, []], - ["Cover Me in Debris", False, [], ['Progressive Resource Crafting']], - ["Cover Me in Debris", False, [], ['Flint and Steel']], - ["Cover Me in Debris", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], - ["Cover Me in Debris", False, [], ['Progressive Weapons']], - ["Cover Me in Debris", False, ['Progressive Armor'], ['Progressive Armor']], - ["Cover Me in Debris", False, [], ['Brewing']], - ["Cover Me in Debris", False, [], ['Bottles']], - ["Cover Me in Debris", False, [], ['Bed']], - ["Cover Me in Debris", False, ['8 Netherite Scrap'], ['8 Netherite Scrap']], - ["Cover Me in Debris", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Progressive Armor', - 'Brewing', 'Bottles', 'Bed', '8 Netherite Scrap', '8 Netherite Scrap']], - ]) - - def test_42077(self): - self.run_location_tests([ - ["The End?", False, []], - ["The End?", False, [], ['Progressive Resource Crafting']], - ["The End?", False, [], ['Flint and Steel']], - ["The End?", False, [], ['Progressive Tools']], - ["The End?", False, [], ['Progressive Weapons']], - ["The End?", False, [], ['Progressive Armor', 'Shield']], - ["The End?", False, [], ['Brewing']], - ["The End?", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["The End?", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["The End?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The End?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The End?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ["The End?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def test_42078(self): - self.run_location_tests([ - ["The Parrots and the Bats", True, []], - ]) - - def test_42079(self): - self.run_location_tests([ - ["A Complete Catalogue", False, []], - ["A Complete Catalogue", False, [], ['Progressive Weapons']], - ["A Complete Catalogue", False, [], ['Campfire', 'Progressive Resource Crafting']], - ["A Complete Catalogue", True, ['Progressive Weapons', 'Campfire']], - ["A Complete Catalogue", True, ['Progressive Weapons', 'Progressive Resource Crafting']], - ]) - - def test_42080(self): - self.run_location_tests([ - ["Getting Wood", True, []], - ]) - - def test_42081(self): - self.run_location_tests([ - ["Time to Mine!", True, []], - ]) - - def test_42082(self): - self.run_location_tests([ - ["Hot Topic", False, []], - ["Hot Topic", True, ['Progressive Resource Crafting']], - ]) - - def test_42083(self): - self.run_location_tests([ - ["Bake Bread", True, []], - ]) - - def test_42084(self): - self.run_location_tests([ - ["The Lie", False, []], - ["The Lie", False, [], ['Progressive Resource Crafting']], - ["The Lie", False, [], ['Bucket']], - ["The Lie", False, [], ['Progressive Tools']], - ["The Lie", True, ['Bucket', 'Progressive Resource Crafting', 'Progressive Tools']], - ]) - - def test_42085(self): - self.run_location_tests([ - ["On a Rail", False, []], - ["On a Rail", False, [], ['Progressive Resource Crafting']], - ["On a Rail", False, ['Progressive Tools'], ['Progressive Tools', 'Progressive Tools']], - ["On a Rail", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools']], - ]) - - def test_42086(self): - self.run_location_tests([ - ["Time to Strike!", True, []], - ]) - - def test_42087(self): - self.run_location_tests([ - ["Cow Tipper", True, []], - ]) - - def test_42088(self): - self.run_location_tests([ - ["When Pigs Fly", False, []], - ["When Pigs Fly", False, [], ['Progressive Resource Crafting']], - ["When Pigs Fly", False, [], ['Progressive Tools']], - ["When Pigs Fly", False, [], ['Progressive Weapons']], - ["When Pigs Fly", False, [], ['Progressive Armor', 'Shield']], - ["When Pigs Fly", False, [], ['Fishing Rod']], - ["When Pigs Fly", False, [], ['Saddle']], - ["When Pigs Fly", False, ['Progressive Weapons'], ['Flint and Steel', 'Progressive Weapons', 'Progressive Weapons']], - ["When Pigs Fly", False, ['Progressive Tools', 'Progressive Tools', 'Progressive Weapons'], ['Bucket', 'Progressive Tools', 'Progressive Weapons', 'Progressive Weapons']], - ["When Pigs Fly", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Progressive Armor', 'Fishing Rod']], - ["When Pigs Fly", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor', 'Fishing Rod']], - ["When Pigs Fly", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield', 'Fishing Rod']], - ["When Pigs Fly", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Shield', 'Fishing Rod']], - ["When Pigs Fly", True, ['Saddle', 'Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Shield', 'Progressive Resource Crafting', 'Progressive Tools', 'Fishing Rod']], - ]) - - def test_42089(self): - self.run_location_tests([ - ["Overkill", False, []], - ["Overkill", False, [], ['Progressive Resource Crafting']], - ["Overkill", False, [], ['Flint and Steel']], - ["Overkill", False, [], ['Progressive Tools']], - ["Overkill", False, [], ['Progressive Weapons']], - ["Overkill", False, [], ['Progressive Armor', 'Shield']], - ["Overkill", False, [], ['Brewing']], - ["Overkill", False, [], ['Bottles']], - ["Overkill", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Overkill", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], - ["Overkill", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], - ["Overkill", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], - ["Overkill", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], - ]) - - def test_42090(self): - self.run_location_tests([ - ["Librarian", False, []], - ["Librarian", True, ['Enchanting']], - ]) - - def test_42091(self): - self.run_location_tests([ - ["Overpowered", False, []], - ["Overpowered", False, [], ['Progressive Resource Crafting']], - ["Overpowered", False, [], ['Flint and Steel']], - ["Overpowered", False, ['Progressive Tools', 'Progressive Tools', 'Bucket', 'Flint and Steel']], - ["Overpowered", False, [], ['Progressive Weapons']], - ["Overpowered", False, [], ['Progressive Armor', 'Shield']], - ["Overpowered", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor']], - ["Overpowered", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Progressive Armor']], - ["Overpowered", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Weapons', 'Shield']], - ["Overpowered", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield']], - ]) - - def test_42092(self): - self.run_location_tests([ - ["Wax On", False, []], - ["Wax On", False, [], ["Progressive Tools"]], - ["Wax On", False, [], ["Campfire"]], - ["Wax On", False, ["Progressive Resource Crafting"], ["Progressive Resource Crafting"]], - ["Wax On", True, ["Progressive Tools", "Progressive Resource Crafting", "Progressive Resource Crafting", "Campfire"]], - ]) - - def test_42093(self): - self.run_location_tests([ - ["Wax Off", False, []], - ["Wax Off", False, [], ["Progressive Tools"]], - ["Wax Off", False, [], ["Campfire"]], - ["Wax Off", False, ["Progressive Resource Crafting"], ["Progressive Resource Crafting"]], - ["Wax Off", True, ["Progressive Tools", "Progressive Resource Crafting", "Progressive Resource Crafting", "Campfire"]], - ]) - - def test_42094(self): - self.run_location_tests([ - ["The Cutest Predator", False, []], - ["The Cutest Predator", False, [], ["Progressive Tools"]], - ["The Cutest Predator", False, [], ["Progressive Resource Crafting"]], - ["The Cutest Predator", False, [], ["Bucket"]], - ["The Cutest Predator", True, ["Progressive Tools", "Progressive Resource Crafting", "Bucket"]], - ]) - - def test_42095(self): - self.run_location_tests([ - ["The Healing Power of Friendship", False, []], - ["The Healing Power of Friendship", False, [], ["Progressive Tools"]], - ["The Healing Power of Friendship", False, [], ["Progressive Resource Crafting"]], - ["The Healing Power of Friendship", False, [], ["Bucket"]], - ["The Healing Power of Friendship", True, ["Progressive Tools", "Progressive Resource Crafting", "Bucket"]], - ]) - - def test_42096(self): - self.run_location_tests([ - ["Is It a Bird?", False, []], - ["Is It a Bird?", False, [], ["Progressive Weapons"]], - ["Is It a Bird?", False, [], ["Progressive Tools"]], - ["Is It a Bird?", False, [], ["Progressive Resource Crafting"]], - ["Is It a Bird?", False, [], ["Spyglass"]], - ["Is It a Bird?", True, ["Progressive Weapons", "Progressive Tools", "Progressive Resource Crafting", "Spyglass"]], - ]) - - def test_42097(self): - self.run_location_tests([ - ["Is It a Balloon?", False, []], - ["Is It a Balloon?", False, [], ['Progressive Resource Crafting']], - ["Is It a Balloon?", False, [], ['Flint and Steel']], - ["Is It a Balloon?", False, [], ['Progressive Tools']], - ["Is It a Balloon?", False, [], ['Progressive Weapons']], - ["Is It a Balloon?", False, [], ['Spyglass']], - ["Is It a Balloon?", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Is It a Balloon?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Spyglass']], - ["Is It a Balloon?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Spyglass']], - ]) - - def test_42098(self): - self.run_location_tests([ - ["Is It a Plane?", False, []], - ["Is It a Plane?", False, [], ['Progressive Resource Crafting']], - ["Is It a Plane?", False, [], ['Flint and Steel']], - ["Is It a Plane?", False, [], ['Progressive Tools']], - ["Is It a Plane?", False, [], ['Progressive Weapons']], - ["Is It a Plane?", False, [], ['Progressive Armor', 'Shield']], - ["Is It a Plane?", False, [], ['Brewing']], - ["Is It a Plane?", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ["Is It a Plane?", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ["Is It a Plane?", False, [], ['Spyglass']], - ["Is It a Plane?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', - '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Spyglass']], - ["Is It a Plane?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', 'Brewing', - '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Spyglass']], - ["Is It a Plane?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', - 'Progressive Weapons', 'Shield', 'Brewing', - '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Spyglass']], - ["Is It a Plane?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', 'Brewing', - '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Spyglass']], - ]) - - def test_42099(self): - self.run_location_tests([ - ["Surge Protector", False, []], - ["Surge Protector", False, [], ['Channeling Book']], - ["Surge Protector", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], - ["Surge Protector", False, [], ['Enchanting']], - ["Surge Protector", False, [], ['Progressive Tools']], - ["Surge Protector", False, [], ['Progressive Weapons']], - ["Surge Protector", True, ['Progressive Weapons', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', - 'Enchanting', 'Progressive Resource Crafting', 'Progressive Resource Crafting', 'Channeling Book']], - ]) - - def test_42100(self): - self.run_location_tests([ - ["Light as a Rabbit", False, []], - ["Light as a Rabbit", False, [], ["Progressive Weapons"]], - ["Light as a Rabbit", False, [], ["Progressive Tools"]], - ["Light as a Rabbit", False, [], ["Progressive Resource Crafting"]], - ["Light as a Rabbit", False, [], ["Bucket"]], - ["Light as a Rabbit", True, ["Progressive Weapons", "Progressive Tools", "Progressive Resource Crafting", "Bucket"]], - ]) - - def test_42101(self): - self.run_location_tests([ - ["Glow and Behold!", False, []], - ["Glow and Behold!", False, [], ["Progressive Weapons"]], - ["Glow and Behold!", False, [], ["Progressive Resource Crafting", "Campfire"]], - ["Glow and Behold!", True, ["Progressive Weapons", "Progressive Resource Crafting"]], - ["Glow and Behold!", True, ["Progressive Weapons", "Campfire"]], - ]) - - def test_42102(self): - self.run_location_tests([ - ["Whatever Floats Your Goat!", False, []], - ["Whatever Floats Your Goat!", False, [], ["Progressive Weapons"]], - ["Whatever Floats Your Goat!", False, [], ["Progressive Resource Crafting", "Campfire"]], - ["Whatever Floats Your Goat!", True, ["Progressive Weapons", "Progressive Resource Crafting"]], - ["Whatever Floats Your Goat!", True, ["Progressive Weapons", "Campfire"]], - ]) - - # bucket, iron pick - def test_42103(self): - self.run_location_tests([ - ["Caves & Cliffs", False, []], - ["Caves & Cliffs", False, [], ["Bucket"]], - ["Caves & Cliffs", False, [], ["Progressive Tools"]], - ["Caves & Cliffs", False, [], ["Progressive Resource Crafting"]], - ["Caves & Cliffs", True, ["Progressive Resource Crafting", "Progressive Tools", "Progressive Tools", "Bucket"]], - ]) - - # bucket, fishing rod, saddle, combat - def test_42104(self): - self.run_location_tests([ - ["Feels like home", False, []], - ["Feels like home", False, [], ['Progressive Resource Crafting']], - ["Feels like home", False, [], ['Progressive Tools']], - ["Feels like home", False, [], ['Progressive Weapons']], - ["Feels like home", False, [], ['Progressive Armor', 'Shield']], - ["Feels like home", False, [], ['Fishing Rod']], - ["Feels like home", False, [], ['Saddle']], - ["Feels like home", False, [], ['Bucket']], - ["Feels like home", False, [], ['Flint and Steel']], - ["Feels like home", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Progressive Armor', 'Fishing Rod']], - ["Feels like home", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield', 'Fishing Rod']], - ]) - - # iron pick, combat - def test_42105(self): - self.run_location_tests([ - ["Sound of Music", False, []], - ["Sound of Music", False, [], ["Progressive Tools"]], - ["Sound of Music", False, [], ["Progressive Resource Crafting"]], - ["Sound of Music", False, [], ["Progressive Weapons"]], - ["Sound of Music", False, [], ["Progressive Armor", "Shield"]], - ["Sound of Music", True, ["Progressive Tools", "Progressive Tools", "Progressive Resource Crafting", "Progressive Weapons", "Progressive Armor"]], - ["Sound of Music", True, ["Progressive Tools", "Progressive Tools", "Progressive Resource Crafting", "Progressive Weapons", "Shield"]], - ]) - - # bucket, nether, villager - def test_42106(self): - self.run_location_tests([ - ["Star Trader", False, []], - ["Star Trader", False, [], ["Bucket"]], - ["Star Trader", False, [], ["Flint and Steel"]], - ["Star Trader", False, [], ["Progressive Tools"]], - ["Star Trader", False, [], ["Progressive Resource Crafting"]], - ["Star Trader", False, [], ["Progressive Weapons"]], - ["Star Trader", True, ["Bucket", "Flint and Steel", "Progressive Tools", "Progressive Resource Crafting", "Progressive Weapons"]], - ]) - - # bucket, redstone -> iron pick, pillager outpost -> adventure - def test_42107(self): - self.run_location_tests([ - ["Birthday Song", False, []], - ["Birthday Song", False, [], ["Bucket"]], - ["Birthday Song", False, [], ["Progressive Tools"]], - ["Birthday Song", False, [], ["Progressive Weapons"]], - ["Birthday Song", False, [], ["Progressive Resource Crafting"]], - ["Birthday Song", True, ["Progressive Resource Crafting", "Progressive Tools", "Progressive Tools", "Progressive Weapons", "Bucket"]], - ]) - - # bucket, adventure - def test_42108(self): - self.run_location_tests([ - ["Bukkit Bukkit", False, []], - ["Bukkit Bukkit", False, [], ["Bucket"]], - ["Bukkit Bukkit", False, [], ["Progressive Tools"]], - ["Bukkit Bukkit", False, [], ["Progressive Weapons"]], - ["Bukkit Bukkit", False, [], ["Progressive Resource Crafting"]], - ["Bukkit Bukkit", True, ["Bucket", "Progressive Tools", "Progressive Weapons", "Progressive Resource Crafting"]], - ]) - - # iron pick, adventure - def test_42109(self): - self.run_location_tests([ - ["It Spreads", False, []], - ["It Spreads", False, [], ["Progressive Tools"]], - ["It Spreads", False, [], ["Progressive Weapons"]], - ["It Spreads", False, [], ["Progressive Resource Crafting"]], - ["It Spreads", True, ["Progressive Tools", "Progressive Tools", "Progressive Weapons", "Progressive Resource Crafting"]], - ]) - - # iron pick, adventure - def test_42110(self): - self.run_location_tests([ - ["Sneak 100", False, []], - ["Sneak 100", False, [], ["Progressive Tools"]], - ["Sneak 100", False, [], ["Progressive Weapons"]], - ["Sneak 100", False, [], ["Progressive Resource Crafting"]], - ["Sneak 100", True, ["Progressive Tools", "Progressive Tools", "Progressive Weapons", "Progressive Resource Crafting"]], - ]) - - # adventure, lead - def test_42111(self): - self.run_location_tests([ - ["When the Squad Hops into Town", False, []], - ["When the Squad Hops into Town", False, [], ["Progressive Weapons"]], - ["When the Squad Hops into Town", False, [], ["Campfire", "Progressive Resource Crafting"]], - ["When the Squad Hops into Town", False, [], ["Lead"]], - ["When the Squad Hops into Town", True, ["Progressive Weapons", "Lead", "Campfire"]], - ["When the Squad Hops into Town", True, ["Progressive Weapons", "Lead", "Progressive Resource Crafting"]], - ]) - - # adventure, lead, nether - def test_42112(self): - self.run_location_tests([ - ["With Our Powers Combined!", False, []], - ["With Our Powers Combined!", False, [], ["Lead"]], - ["With Our Powers Combined!", False, [], ["Bucket", "Progressive Tools"]], - ["With Our Powers Combined!", False, [], ["Flint and Steel"]], - ["With Our Powers Combined!", False, [], ["Progressive Weapons"]], - ["With Our Powers Combined!", False, [], ["Progressive Resource Crafting"]], - ["With Our Powers Combined!", True, ["Lead", "Progressive Weapons", "Progressive Resource Crafting", "Flint and Steel", "Progressive Tools", "Bucket"]], - ["With Our Powers Combined!", True, ["Lead", "Progressive Weapons", "Progressive Resource Crafting", "Flint and Steel", "Progressive Tools", "Progressive Tools", "Progressive Tools"]], - ]) - - # pillager outpost -> adventure - def test_42113(self): - self.run_location_tests([ - ["You've Got a Friend in Me", False, []], - ["You've Got a Friend in Me", False, [], ["Progressive Weapons"]], - ["You've Got a Friend in Me", False, [], ["Campfire", "Progressive Resource Crafting"]], - ["You've Got a Friend in Me", True, ["Progressive Weapons", "Campfire"]], - ["You've Got a Friend in Me", True, ["Progressive Weapons", "Progressive Resource Crafting"]], - ]) diff --git a/worlds/minecraft/test/TestDataLoad.py b/worlds/minecraft/test/TestDataLoad.py deleted file mode 100644 index c14eef071bfc..000000000000 --- a/worlds/minecraft/test/TestDataLoad.py +++ /dev/null @@ -1,60 +0,0 @@ -import unittest - -from .. import Constants - -class TestDataLoad(unittest.TestCase): - - def test_item_data(self): - item_info = Constants.item_info - - # All items in sub-tables are in all_items - all_items: set = set(item_info['all_items']) - assert set(item_info['progression_items']) <= all_items - assert set(item_info['useful_items']) <= all_items - assert set(item_info['trap_items']) <= all_items - assert set(item_info['required_pool'].keys()) <= all_items - assert set(item_info['junk_weights'].keys()) <= all_items - - # No overlapping ids (because of bee trap stuff) - all_ids: set = set(Constants.item_name_to_id.values()) - assert len(all_items) == len(all_ids) - - def test_location_data(self): - location_info = Constants.location_info - exclusion_info = Constants.exclusion_info - - # Every location has a region and every region's locations are in all_locations - all_locations: set = set(location_info['all_locations']) - all_locs_2: set = set() - for v in location_info['locations_by_region'].values(): - all_locs_2.update(v) - assert all_locations == all_locs_2 - - # All exclusions are locations - for v in exclusion_info.values(): - assert set(v) <= all_locations - - def test_region_data(self): - region_info = Constants.region_info - - # Every entrance and region in mandatory/default/illegal connections is a real entrance and region - all_regions = set() - all_entrances = set() - for v in region_info['regions']: - assert isinstance(v[0], str) - assert isinstance(v[1], list) - all_regions.add(v[0]) - all_entrances.update(v[1]) - - for v in region_info['mandatory_connections']: - assert v[0] in all_entrances - assert v[1] in all_regions - - for v in region_info['default_connections']: - assert v[0] in all_entrances - assert v[1] in all_regions - - for k, v in region_info['illegal_connections'].items(): - assert k in all_regions - assert set(v) <= all_entrances - diff --git a/worlds/minecraft/test/TestEntrances.py b/worlds/minecraft/test/TestEntrances.py deleted file mode 100644 index 946eb23d6308..000000000000 --- a/worlds/minecraft/test/TestEntrances.py +++ /dev/null @@ -1,97 +0,0 @@ -from . import MCTestBase - - -class TestEntrances(MCTestBase): - options = { - "shuffle_structures": False, - "structure_compasses": False - } - - def testPortals(self): - self.run_entrance_tests([ - ['Nether Portal', False, []], - ['Nether Portal', False, [], ['Flint and Steel']], - ['Nether Portal', False, [], ['Progressive Resource Crafting']], - ['Nether Portal', False, [], ['Progressive Tools']], - ['Nether Portal', False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ['Nether Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket']], - ['Nether Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools']], - - ['End Portal', False, []], - ['End Portal', False, [], ['Brewing']], - ['End Portal', False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ['End Portal', False, [], ['Flint and Steel']], - ['End Portal', False, [], ['Progressive Resource Crafting']], - ['End Portal', False, [], ['Progressive Tools']], - ['End Portal', False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ['End Portal', False, [], ['Progressive Weapons']], - ['End Portal', False, [], ['Progressive Armor', 'Shield']], - ['End Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ['End Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ['End Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ['End Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ]) - - def testStructures(self): - self.run_entrance_tests([ # Structures 1 and 2 should be logically equivalent - ['Overworld Structure 1', False, []], - ['Overworld Structure 1', False, [], ['Progressive Weapons']], - ['Overworld Structure 1', False, [], ['Progressive Resource Crafting', 'Campfire']], - ['Overworld Structure 1', True, ['Progressive Weapons', 'Progressive Resource Crafting']], - ['Overworld Structure 1', True, ['Progressive Weapons', 'Campfire']], - - ['Overworld Structure 2', False, []], - ['Overworld Structure 2', False, [], ['Progressive Weapons']], - ['Overworld Structure 2', False, [], ['Progressive Resource Crafting', 'Campfire']], - ['Overworld Structure 2', True, ['Progressive Weapons', 'Progressive Resource Crafting']], - ['Overworld Structure 2', True, ['Progressive Weapons', 'Campfire']], - - ['Nether Structure 1', False, []], - ['Nether Structure 1', False, [], ['Flint and Steel']], - ['Nether Structure 1', False, [], ['Progressive Resource Crafting']], - ['Nether Structure 1', False, [], ['Progressive Tools']], - ['Nether Structure 1', False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ['Nether Structure 1', False, [], ['Progressive Weapons']], - ['Nether Structure 1', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', 'Progressive Weapons']], - ['Nether Structure 1', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons']], - - ['Nether Structure 2', False, []], - ['Nether Structure 2', False, [], ['Flint and Steel']], - ['Nether Structure 2', False, [], ['Progressive Resource Crafting']], - ['Nether Structure 2', False, [], ['Progressive Tools']], - ['Nether Structure 2', False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ['Nether Structure 2', False, [], ['Progressive Weapons']], - ['Nether Structure 2', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', 'Progressive Weapons']], - ['Nether Structure 2', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons']], - - ['The End Structure', False, []], - ['The End Structure', False, [], ['Brewing']], - ['The End Structure', False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], - ['The End Structure', False, [], ['Flint and Steel']], - ['The End Structure', False, [], ['Progressive Resource Crafting']], - ['The End Structure', False, [], ['Progressive Tools']], - ['The End Structure', False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], - ['The End Structure', False, [], ['Progressive Weapons']], - ['The End Structure', False, [], ['Progressive Armor', 'Shield']], - ['The End Structure', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ['The End Structure', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ['The End Structure', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Progressive Armor', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - ['The End Structure', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', - 'Progressive Weapons', 'Shield', - 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], - - ]) \ No newline at end of file diff --git a/worlds/minecraft/test/TestOptions.py b/worlds/minecraft/test/TestOptions.py deleted file mode 100644 index c04a07054c9c..000000000000 --- a/worlds/minecraft/test/TestOptions.py +++ /dev/null @@ -1,49 +0,0 @@ -from . import MCTestBase -from ..Constants import region_info -from .. import Options - -from BaseClasses import ItemClassification - -class AdvancementTestBase(MCTestBase): - options = { - "advancement_goal": Options.AdvancementGoal.range_end - } - # beatability test implicit - -class ShardTestBase(MCTestBase): - options = { - "egg_shards_required": Options.EggShardsRequired.range_end, - "egg_shards_available": Options.EggShardsAvailable.range_end - } - - # check that itempool is not overfilled with shards - def test_itempool(self): - assert len(self.multiworld.get_unfilled_locations()) == len(self.multiworld.itempool) - -class CompassTestBase(MCTestBase): - def test_compasses_in_pool(self): - structures = [x[1] for x in region_info["default_connections"]] - itempool_str = {item.name for item in self.multiworld.itempool} - for struct in structures: - assert f"Structure Compass ({struct})" in itempool_str - -class NoBeeTestBase(MCTestBase): - options = { - "bee_traps": Options.BeeTraps.range_start - } - - # With no bees, there are no traps in the pool - def test_bees(self): - for item in self.multiworld.itempool: - assert item.classification != ItemClassification.trap - - -class AllBeeTestBase(MCTestBase): - options = { - "bee_traps": Options.BeeTraps.range_end - } - - # With max bees, there are no filler items, only bee traps - def test_bees(self): - for item in self.multiworld.itempool: - assert item.classification != ItemClassification.filler diff --git a/worlds/minecraft/test/__init__.py b/worlds/minecraft/test/__init__.py deleted file mode 100644 index 3d936fe9cb6b..000000000000 --- a/worlds/minecraft/test/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -from test.bases import TestBase, WorldTestBase -from .. import MinecraftWorld, MinecraftOptions - - -class MCTestBase(WorldTestBase, TestBase): - game = "Minecraft" - player: int = 1 - - def _create_items(self, items, player): - singleton = False - if isinstance(items, str): - items = [items] - singleton = True - ret = [self.multiworld.worlds[player].create_item(item) for item in items] - if singleton: - return ret[0] - return ret - - def _get_items(self, item_pool, all_except): - if all_except and len(all_except) > 0: - items = self.multiworld.itempool[:] - items = [item for item in items if item.name not in all_except] - items.extend(self._create_items(item_pool[0], 1)) - else: - items = self._create_items(item_pool[0], 1) - return self.get_state(items) - - def _get_items_partial(self, item_pool, missing_item): - new_items = item_pool[0].copy() - new_items.remove(missing_item) - items = self._create_items(new_items, 1) - return self.get_state(items) - From 377cdb84b4114de86ef370103641b3f00a8ababa Mon Sep 17 00:00:00 2001 From: digiholic Date: Mon, 16 Jun 2025 05:47:55 -0600 Subject: [PATCH 0520/1218] MMBN3: Fixes Generation Errors and General UX Smoothing (#5077) Co-authored-by: qwint --- MMBN3Client.py | 9 +- data/lua/connector_mmbn3.lua | 2 +- worlds/mmbn3/Rom.py | 9 +- worlds/mmbn3/__init__.py | 217 ++++++++++++++------------ worlds/mmbn3/data/bn3-ap-patch.bsdiff | Bin 61276 -> 61371 bytes 5 files changed, 128 insertions(+), 109 deletions(-) diff --git a/MMBN3Client.py b/MMBN3Client.py index 4945d49221c4..bdf1427475af 100644 --- a/MMBN3Client.py +++ b/MMBN3Client.py @@ -290,12 +290,9 @@ async def gba_sync_task(ctx: MMBN3Context): async def run_game(romfile): - options = Utils.get_options().get("mmbn3_options", None) - if options is None: - auto_start = True - else: - auto_start = options.get("rom_start", True) - if auto_start: + from worlds.mmbn3 import MMBN3World + auto_start = MMBN3World.settings.rom_start + if auto_start is True: import webbrowser webbrowser.open(romfile) elif os.path.isfile(auto_start): diff --git a/data/lua/connector_mmbn3.lua b/data/lua/connector_mmbn3.lua index fce38a4c1102..c89f428fe511 100644 --- a/data/lua/connector_mmbn3.lua +++ b/data/lua/connector_mmbn3.lua @@ -477,7 +477,7 @@ function main() elseif (curstate == STATE_UNINITIALIZED) then -- If we're uninitialized, attempt to make the connection. if (frame % 120 == 0) then - server:settimeout(2) + server:settimeout(120) local client, timeout = server:accept() if timeout == nil then print('Initial Connection Made') diff --git a/worlds/mmbn3/Rom.py b/worlds/mmbn3/Rom.py index 79da50e534b4..347375c50356 100644 --- a/worlds/mmbn3/Rom.py +++ b/worlds/mmbn3/Rom.py @@ -185,7 +185,7 @@ def add_progression_scripts(self): # As far as I know, this should literally not be possible. # Every script I've looked at has dozens of unused indices, so finding 9 (8 plus one "ending" script) # should be no problem. We re-use these so we don't have to worry about an area getting tons of these - raise AssertionError("Error in generation -- not enough room for progressive undernet in archive "+self.startOffset) + raise AssertionError(f"Error in generation -- not enough room for progressive undernet in archive {self.startOffset} ({hex(self.startOffset)})") for i in range(9): # There are 8 progressive undernet ranks new_script_index = self.unused_indices[i] new_script = ArchiveScript(new_script_index, generate_progressive_undernet(i, self.unused_indices[i+1])) @@ -319,15 +319,16 @@ def get_source_data(cls) -> bytes: def get_base_rom_path(file_name: str = "") -> str: - options = Utils.get_options() if not file_name: - bn3_options = options.get("mmbn3_options", None) + from worlds.mmbn3 import MMBN3World + bn3_options = MMBN3World.settings + if bn3_options is None: file_name = "Mega Man Battle Network 3 - Blue Version (USA).gba" else: file_name = bn3_options["rom_file"] if not os.path.exists(file_name): - file_name = Utils.local_path(file_name) + file_name = Utils.user_path(file_name) return file_name diff --git a/worlds/mmbn3/__init__.py b/worlds/mmbn3/__init__.py index 507ddbc21f7e..80716977d3dd 100644 --- a/worlds/mmbn3/__init__.py +++ b/worlds/mmbn3/__init__.py @@ -1,7 +1,6 @@ import os import settings import typing -import threading from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification, Region, Entrance, \ LocationProgressType @@ -16,7 +15,7 @@ from .Regions import regions, RegionName from .Names.ItemName import ItemName from .Names.LocationName import LocationName -from worlds.generic.Rules import add_item_rule, add_rule +from worlds.generic.Rules import add_item_rule, add_rule, forbid_item class MMBN3Settings(settings.Group): @@ -26,8 +25,15 @@ class RomFile(settings.UserFilePath): description = "MMBN3 ROM File" md5s = [MMBN3DeltaPatch.hash] + class RomStart(str): + """ + Set this to false to never autostart a rom (such as after patching), + true for operating system default program + Alternatively, a path to a program to open the .gba file with + """ + rom_file: RomFile = RomFile(RomFile.copy_to) - rom_start: bool = True + rom_start: RomStart | bool = True class MMBN3Web(WebWorld): @@ -203,134 +209,134 @@ def set_rules(self) -> None: # Set WWW ID requirements def has_www_id(state): return state.has(ItemName.WWW_ID, self.player) - add_rule(self.multiworld.get_location(LocationName.ACDC_1_PMD, self.player), has_www_id) - add_rule(self.multiworld.get_location(LocationName.SciLab_1_WWW_BMD, self.player), has_www_id) - add_rule(self.multiworld.get_location(LocationName.Yoka_1_WWW_BMD, self.player), has_www_id) - add_rule(self.multiworld.get_location(LocationName.Undernet_1_WWW_BMD, self.player), has_www_id) + add_rule(self.get_location(LocationName.ACDC_1_PMD), has_www_id) + add_rule(self.get_location(LocationName.SciLab_1_WWW_BMD), has_www_id) + add_rule(self.get_location(LocationName.Yoka_1_WWW_BMD), has_www_id) + add_rule(self.get_location(LocationName.Undernet_1_WWW_BMD), has_www_id) # Set Press Program requirements def has_press(state): return state.has(ItemName.Press, self.player) - add_rule(self.multiworld.get_location(LocationName.Yoka_1_PMD, self.player), has_press) - add_rule(self.multiworld.get_location(LocationName.Yoka_2_Upper_BMD, self.player), has_press) - add_rule(self.multiworld.get_location(LocationName.Beach_2_East_BMD, self.player), has_press) - add_rule(self.multiworld.get_location(LocationName.Hades_South_BMD, self.player), has_press) - add_rule(self.multiworld.get_location(LocationName.Secret_3_BugFrag_BMD, self.player), has_press) - add_rule(self.multiworld.get_location(LocationName.Secret_3_Island_BMD, self.player), has_press) + add_rule(self.get_location(LocationName.Yoka_1_PMD), has_press) + add_rule(self.get_location(LocationName.Yoka_2_Upper_BMD), has_press) + add_rule(self.get_location(LocationName.Beach_2_East_BMD), has_press) + add_rule(self.get_location(LocationName.Hades_South_BMD), has_press) + add_rule(self.get_location(LocationName.Secret_3_BugFrag_BMD), has_press) + add_rule(self.get_location(LocationName.Secret_3_Island_BMD), has_press) # Set Purple Mystery Data Unlocker access def can_unlock(state): return state.can_reach_region(RegionName.SciLab_Overworld, self.player) or \ state.can_reach_region(RegionName.SciLab_Cyberworld, self.player) or \ state.can_reach_region(RegionName.Yoka_Cyberworld, self.player) or \ state.has(ItemName.Unlocker, self.player, 8) # There are 8 PMDs that aren't in one of the above areas - add_rule(self.multiworld.get_location(LocationName.ACDC_1_PMD, self.player), can_unlock) - add_rule(self.multiworld.get_location(LocationName.Yoka_1_PMD, self.player), can_unlock) - add_rule(self.multiworld.get_location(LocationName.Beach_1_PMD, self.player), can_unlock) - add_rule(self.multiworld.get_location(LocationName.Undernet_7_PMD, self.player), can_unlock) - add_rule(self.multiworld.get_location(LocationName.Mayls_HP_PMD, self.player), can_unlock) - add_rule(self.multiworld.get_location(LocationName.SciLab_Dads_Computer_PMD, self.player), can_unlock) - add_rule(self.multiworld.get_location(LocationName.Zoo_Panda_PMD, self.player), can_unlock) - add_rule(self.multiworld.get_location(LocationName.Beach_DNN_Security_Panel_PMD, self.player), can_unlock) - add_rule(self.multiworld.get_location(LocationName.Beach_DNN_Main_Console_PMD, self.player), can_unlock) - add_rule(self.multiworld.get_location(LocationName.Tamakos_HP_PMD, self.player), can_unlock) + add_rule(self.get_location(LocationName.ACDC_1_PMD), can_unlock) + add_rule(self.get_location(LocationName.Yoka_1_PMD), can_unlock) + add_rule(self.get_location(LocationName.Beach_1_PMD), can_unlock) + add_rule(self.get_location(LocationName.Undernet_7_PMD), can_unlock) + add_rule(self.get_location(LocationName.Mayls_HP_PMD), can_unlock) + add_rule(self.get_location(LocationName.SciLab_Dads_Computer_PMD), can_unlock) + add_rule(self.get_location(LocationName.Zoo_Panda_PMD), can_unlock) + add_rule(self.get_location(LocationName.Beach_DNN_Security_Panel_PMD), can_unlock) + add_rule(self.get_location(LocationName.Beach_DNN_Main_Console_PMD), can_unlock) + add_rule(self.get_location(LocationName.Tamakos_HP_PMD), can_unlock) # Set Job additional area access - self.multiworld.get_location(LocationName.Please_deliver_this, self.player).access_rule = \ + self.get_location(LocationName.Please_deliver_this).access_rule = \ lambda state: \ state.can_reach_region(RegionName.ACDC_Overworld, self.player) and \ state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) - self.multiworld.get_location(LocationName.My_Navi_is_sick, self.player).access_rule =\ + self.get_location(LocationName.My_Navi_is_sick).access_rule =\ lambda state: \ state.has(ItemName.Recov30_star, self.player) - self.multiworld.get_location(LocationName.Help_me_with_my_son, self.player).access_rule =\ + self.get_location(LocationName.Help_me_with_my_son).access_rule =\ lambda state:\ state.can_reach_region(RegionName.Yoka_Overworld, self.player) and \ state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) - self.multiworld.get_location(LocationName.Transmission_error, self.player).access_rule = \ + self.get_location(LocationName.Transmission_error).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Yoka_Overworld, self.player) - self.multiworld.get_location(LocationName.Chip_Prices, self.player).access_rule = \ + self.get_location(LocationName.Chip_Prices).access_rule = \ lambda state: \ state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) and \ state.can_reach_region(RegionName.SciLab_Cyberworld, self.player) - self.multiworld.get_location(LocationName.Im_broke, self.player).access_rule = \ + self.get_location(LocationName.Im_broke).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Yoka_Overworld, self.player) and \ state.can_reach_region(RegionName.Yoka_Cyberworld, self.player) - self.multiworld.get_location(LocationName.Rare_chips_for_cheap, self.player).access_rule = \ + self.get_location(LocationName.Rare_chips_for_cheap).access_rule = \ lambda state: \ state.can_reach_region(RegionName.ACDC_Overworld, self.player) - self.multiworld.get_location(LocationName.Be_my_boyfriend, self.player).access_rule =\ + self.get_location(LocationName.Be_my_boyfriend).access_rule =\ lambda state: \ state.can_reach_region(RegionName.Beach_Cyberworld, self.player) - self.multiworld.get_location(LocationName.Will_you_deliver, self.player).access_rule=\ + self.get_location(LocationName.Will_you_deliver).access_rule=\ lambda state: \ state.can_reach_region(RegionName.Yoka_Overworld, self.player) and \ state.can_reach_region(RegionName.Beach_Overworld, self.player) and \ state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) - self.multiworld.get_location(LocationName.Somebody_please_help, self.player).access_rule = \ + self.get_location(LocationName.Somebody_please_help).access_rule = \ lambda state: \ state.can_reach_region(RegionName.ACDC_Overworld, self.player) - self.multiworld.get_location(LocationName.Looking_for_condor, self.player).access_rule = \ + self.get_location(LocationName.Looking_for_condor).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Yoka_Overworld, self.player) and \ state.can_reach_region(RegionName.Beach_Overworld, self.player) and \ state.can_reach_region(RegionName.ACDC_Overworld, self.player) - self.multiworld.get_location(LocationName.Help_with_rehab, self.player).access_rule = \ + self.get_location(LocationName.Help_with_rehab).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Beach_Overworld, self.player) - self.multiworld.get_location(LocationName.Help_with_rehab_bonus, self.player).access_rule = \ + self.get_location(LocationName.Help_with_rehab_bonus).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Beach_Overworld, self.player) - self.multiworld.get_location(LocationName.Old_Master, self.player).access_rule = \ + self.get_location(LocationName.Old_Master).access_rule = \ lambda state: \ state.can_reach_region(RegionName.ACDC_Overworld, self.player) and \ state.can_reach_region(RegionName.Beach_Overworld, self.player) - self.multiworld.get_location(LocationName.Catching_gang_members, self.player).access_rule = \ + self.get_location(LocationName.Catching_gang_members).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Yoka_Cyberworld, self.player) and \ state.has(ItemName.Press, self.player) - self.multiworld.get_location(LocationName.Please_adopt_a_virus, self.player).access_rule = \ + self.get_location(LocationName.Please_adopt_a_virus).access_rule = \ lambda state: \ state.can_reach_region(RegionName.SciLab_Cyberworld, self.player) - self.multiworld.get_location(LocationName.Legendary_Tomes, self.player).access_rule = \ + self.get_location(LocationName.Legendary_Tomes).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Beach_Overworld, self.player) and \ state.can_reach_region(RegionName.Undernet, self.player) and \ state.can_reach_region(RegionName.Deep_Undernet, self.player) and \ state.has_all({ItemName.Press, ItemName.Magnum1_A}, self.player) - self.multiworld.get_location(LocationName.Legendary_Tomes_Treasure, self.player).access_rule = \ + self.get_location(LocationName.Legendary_Tomes_Treasure).access_rule = \ lambda state: \ state.can_reach_region(RegionName.ACDC_Overworld, self.player) and \ state.can_reach_location(LocationName.Legendary_Tomes, self.player) - self.multiworld.get_location(LocationName.Hide_and_seek_First_Child, self.player).access_rule = \ + self.get_location(LocationName.Hide_and_seek_First_Child).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Yoka_Overworld, self.player) - self.multiworld.get_location(LocationName.Hide_and_seek_Second_Child, self.player).access_rule = \ + self.get_location(LocationName.Hide_and_seek_Second_Child).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Yoka_Overworld, self.player) - self.multiworld.get_location(LocationName.Hide_and_seek_Third_Child, self.player).access_rule = \ + self.get_location(LocationName.Hide_and_seek_Third_Child).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Yoka_Overworld, self.player) - self.multiworld.get_location(LocationName.Hide_and_seek_Fourth_Child, self.player).access_rule = \ + self.get_location(LocationName.Hide_and_seek_Fourth_Child).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Yoka_Overworld, self.player) - self.multiworld.get_location(LocationName.Hide_and_seek_Completion, self.player).access_rule = \ + self.get_location(LocationName.Hide_and_seek_Completion).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Yoka_Overworld, self.player) - self.multiworld.get_location(LocationName.Finding_the_blue_Navi, self.player).access_rule = \ + self.get_location(LocationName.Finding_the_blue_Navi).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Undernet, self.player) - self.multiworld.get_location(LocationName.Give_your_support, self.player).access_rule = \ + self.get_location(LocationName.Give_your_support).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Beach_Overworld, self.player) - self.multiworld.get_location(LocationName.Stamp_collecting, self.player).access_rule = \ + self.get_location(LocationName.Stamp_collecting).access_rule = \ lambda state: \ state.can_reach_region(RegionName.Beach_Overworld, self.player) and \ state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) and \ state.can_reach_region(RegionName.SciLab_Cyberworld, self.player) and \ state.can_reach_region(RegionName.Yoka_Cyberworld, self.player) and \ state.can_reach_region(RegionName.Beach_Cyberworld, self.player) - self.multiworld.get_location(LocationName.Help_with_a_will, self.player).access_rule = \ + self.get_location(LocationName.Help_with_a_will).access_rule = \ lambda state: \ state.can_reach_region(RegionName.ACDC_Overworld, self.player) and \ state.can_reach_region(RegionName.ACDC_Cyberworld, self.player) and \ @@ -340,100 +346,115 @@ def can_unlock(state): return state.can_reach_region(RegionName.SciLab_Overworld state.can_reach_region(RegionName.Undernet, self.player) # Set Trade quests - self.multiworld.get_location(LocationName.ACDC_SonicWav_W_Trade, self.player).access_rule =\ + self.get_location(LocationName.ACDC_SonicWav_W_Trade).access_rule =\ lambda state: state.has(ItemName.SonicWav_W, self.player) - self.multiworld.get_location(LocationName.ACDC_Bubbler_C_Trade, self.player).access_rule =\ + self.get_location(LocationName.ACDC_Bubbler_C_Trade).access_rule =\ lambda state: state.has(ItemName.Bubbler_C, self.player) - self.multiworld.get_location(LocationName.ACDC_Recov120_S_Trade, self.player).access_rule =\ + self.get_location(LocationName.ACDC_Recov120_S_Trade).access_rule =\ lambda state: state.has(ItemName.Recov120_S, self.player) - self.multiworld.get_location(LocationName.SciLab_Shake1_S_Trade, self.player).access_rule =\ + self.get_location(LocationName.SciLab_Shake1_S_Trade).access_rule =\ lambda state: state.has(ItemName.Shake1_S, self.player) - self.multiworld.get_location(LocationName.Yoka_FireSwrd_P_Trade, self.player).access_rule =\ + self.get_location(LocationName.Yoka_FireSwrd_P_Trade).access_rule =\ lambda state: state.has(ItemName.FireSwrd_P, self.player) - self.multiworld.get_location(LocationName.Hospital_DynaWav_V_Trade, self.player).access_rule =\ + self.get_location(LocationName.Hospital_DynaWav_V_Trade).access_rule =\ lambda state: state.has(ItemName.DynaWave_V, self.player) - self.multiworld.get_location(LocationName.Beach_DNN_WideSwrd_C_Trade, self.player).access_rule =\ + self.get_location(LocationName.Beach_DNN_WideSwrd_C_Trade).access_rule =\ lambda state: state.has(ItemName.WideSwrd_C, self.player) - self.multiworld.get_location(LocationName.Beach_DNN_HoleMetr_H_Trade, self.player).access_rule =\ + self.get_location(LocationName.Beach_DNN_HoleMetr_H_Trade).access_rule =\ lambda state: state.has(ItemName.HoleMetr_H, self.player) - self.multiworld.get_location(LocationName.Beach_DNN_Shadow_J_Trade, self.player).access_rule =\ + self.get_location(LocationName.Beach_DNN_Shadow_J_Trade).access_rule =\ lambda state: state.has(ItemName.Shadow_J, self.player) - self.multiworld.get_location(LocationName.Hades_GrabBack_K_Trade, self.player).access_rule =\ + self.get_location(LocationName.Hades_GrabBack_K_Trade).access_rule =\ lambda state: state.has(ItemName.GrabBack_K, self.player) # Set Number Traders # The first 8 are considered cheap enough to grind for in ACDC. Protip: Try grinding in the tank - self.multiworld.get_location(LocationName.Numberman_Code_09, self.player).access_rule = \ + self.get_location(LocationName.Numberman_Code_09).access_rule = \ lambda state: self.explore_score(state) > 2 - self.multiworld.get_location(LocationName.Numberman_Code_10, self.player).access_rule = \ + self.get_location(LocationName.Numberman_Code_10).access_rule = \ lambda state: self.explore_score(state) > 2 - self.multiworld.get_location(LocationName.Numberman_Code_11, self.player).access_rule = \ + self.get_location(LocationName.Numberman_Code_11).access_rule = \ lambda state: self.explore_score(state) > 2 - self.multiworld.get_location(LocationName.Numberman_Code_12, self.player).access_rule = \ + self.get_location(LocationName.Numberman_Code_12).access_rule = \ lambda state: self.explore_score(state) > 2 - self.multiworld.get_location(LocationName.Numberman_Code_13, self.player).access_rule = \ + self.get_location(LocationName.Numberman_Code_13).access_rule = \ lambda state: self.explore_score(state) > 2 - self.multiworld.get_location(LocationName.Numberman_Code_14, self.player).access_rule = \ + self.get_location(LocationName.Numberman_Code_14).access_rule = \ lambda state: self.explore_score(state) > 2 - self.multiworld.get_location(LocationName.Numberman_Code_15, self.player).access_rule = \ + self.get_location(LocationName.Numberman_Code_15).access_rule = \ lambda state: self.explore_score(state) > 2 - self.multiworld.get_location(LocationName.Numberman_Code_16, self.player).access_rule = \ + self.get_location(LocationName.Numberman_Code_16).access_rule = \ lambda state: self.explore_score(state) > 2 - self.multiworld.get_location(LocationName.Numberman_Code_17, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_17).access_rule =\ lambda state: self.explore_score(state) > 4 - self.multiworld.get_location(LocationName.Numberman_Code_18, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_18).access_rule =\ lambda state: self.explore_score(state) > 4 - self.multiworld.get_location(LocationName.Numberman_Code_19, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_19).access_rule =\ lambda state: self.explore_score(state) > 4 - self.multiworld.get_location(LocationName.Numberman_Code_20, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_20).access_rule =\ lambda state: self.explore_score(state) > 4 - self.multiworld.get_location(LocationName.Numberman_Code_21, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_21).access_rule =\ lambda state: self.explore_score(state) > 4 - self.multiworld.get_location(LocationName.Numberman_Code_22, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_22).access_rule =\ lambda state: self.explore_score(state) > 4 - self.multiworld.get_location(LocationName.Numberman_Code_23, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_23).access_rule =\ lambda state: self.explore_score(state) > 4 - self.multiworld.get_location(LocationName.Numberman_Code_24, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_24).access_rule =\ lambda state: self.explore_score(state) > 4 - self.multiworld.get_location(LocationName.Numberman_Code_25, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_25).access_rule =\ lambda state: self.explore_score(state) > 8 - self.multiworld.get_location(LocationName.Numberman_Code_26, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_26).access_rule =\ lambda state: self.explore_score(state) > 8 - self.multiworld.get_location(LocationName.Numberman_Code_27, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_27).access_rule =\ lambda state: self.explore_score(state) > 8 - self.multiworld.get_location(LocationName.Numberman_Code_28, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_28).access_rule =\ lambda state: self.explore_score(state) > 8 - self.multiworld.get_location(LocationName.Numberman_Code_29, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_29).access_rule =\ lambda state: self.explore_score(state) > 10 - self.multiworld.get_location(LocationName.Numberman_Code_30, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_30).access_rule =\ lambda state: self.explore_score(state) > 10 - self.multiworld.get_location(LocationName.Numberman_Code_31, self.player).access_rule =\ + self.get_location(LocationName.Numberman_Code_31).access_rule =\ lambda state: self.explore_score(state) > 10 #miscellaneous locations with extra requirements - add_rule(self.multiworld.get_location(LocationName.Comedian, self.player), + add_rule(self.get_location(LocationName.Comedian), lambda state: state.has(ItemName.Humor, self.player)) - add_rule(self.multiworld.get_location(LocationName.Villain, self.player), + add_rule(self.get_location(LocationName.Villain), lambda state: state.has(ItemName.BlckMnd, self.player)) - def not_undernet(item): return item.code != item_table[ItemName.Progressive_Undernet_Rank].code or item.player != self.player - self.multiworld.get_location(LocationName.WWW_1_Central_BMD, self.player).item_rule = not_undernet - self.multiworld.get_location(LocationName.WWW_1_East_BMD, self.player).item_rule = not_undernet - self.multiworld.get_location(LocationName.WWW_2_East_BMD, self.player).item_rule = not_undernet - self.multiworld.get_location(LocationName.WWW_2_Northwest_BMD, self.player).item_rule = not_undernet - self.multiworld.get_location(LocationName.WWW_3_East_BMD, self.player).item_rule = not_undernet - self.multiworld.get_location(LocationName.WWW_3_North_BMD, self.player).item_rule = not_undernet - self.multiworld.get_location(LocationName.WWW_4_Northwest_BMD, self.player).item_rule = not_undernet - self.multiworld.get_location(LocationName.WWW_4_Central_BMD, self.player).item_rule = not_undernet - self.multiworld.get_location(LocationName.WWW_Wall_BMD, self.player).item_rule = not_undernet - self.multiworld.get_location(LocationName.WWW_Control_Room_1_Screen, self.player).item_rule = not_undernet - self.multiworld.get_location(LocationName.WWW_Wilys_Desk, self.player).item_rule = not_undernet + forbid_item(self.get_location(LocationName.WWW_1_Central_BMD), + ItemName.Progressive_Undernet_Rank, self.player) + forbid_item(self.get_location(LocationName.WWW_1_East_BMD), + ItemName.Progressive_Undernet_Rank, self.player) + forbid_item(self.get_location(LocationName.WWW_2_East_BMD), + ItemName.Progressive_Undernet_Rank, self.player) + forbid_item(self.get_location(LocationName.WWW_2_Northwest_BMD), + ItemName.Progressive_Undernet_Rank, self.player) + forbid_item(self.get_location(LocationName.WWW_3_East_BMD), + ItemName.Progressive_Undernet_Rank, self.player) + forbid_item(self.get_location(LocationName.WWW_3_North_BMD), + ItemName.Progressive_Undernet_Rank, self.player) + forbid_item(self.get_location(LocationName.WWW_4_Northwest_BMD), + ItemName.Progressive_Undernet_Rank, self.player) + forbid_item(self.get_location(LocationName.WWW_4_Central_BMD), + ItemName.Progressive_Undernet_Rank, self.player) + forbid_item(self.get_location(LocationName.WWW_Wall_BMD), + ItemName.Progressive_Undernet_Rank, self.player) + forbid_item(self.get_location(LocationName.WWW_Control_Room_1_Screen), + ItemName.Progressive_Undernet_Rank, self.player) + forbid_item(self.get_location(LocationName.WWW_Wilys_Desk), + ItemName.Progressive_Undernet_Rank, self.player) + + # I have no fuckin clue why this specific location shits the bed on a progressive undernet rank. + # If you ever figure it out I will buy you a pizza. + forbid_item(self.get_location(LocationName.Chocolate_Shop_07), + ItemName.Progressive_Undernet_Rank, self.player) # place "Victory" at "Final Boss" and set collection as win condition - self.multiworld.get_location(LocationName.Alpha_Defeated, self.player) \ + self.get_location(LocationName.Alpha_Defeated) \ .place_locked_item(self.create_event(ItemName.Victory)) self.multiworld.completion_condition[self.player] = \ lambda state: state.has(ItemName.Victory, self.player) diff --git a/worlds/mmbn3/data/bn3-ap-patch.bsdiff b/worlds/mmbn3/data/bn3-ap-patch.bsdiff index d55fecad80641b372bc7752600f335d6961f9185..43ace91bcd02b4d90be9cbcf1f4bba079bbbde52 100644 GIT binary patch literal 61371 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 literal 61276 zcmaHyV{9f)*zTViTif>5ed>0%wrxJO?cKIp+qP}nwr$(S`M>Y^aK4=@narJ;+{u;6 zOa}Rlkg|xRm>7^57aH)tN+&X0-g~L33DVfEHff?QC4XYIy+zh7e*{7T3IX-tmuEN zm?Hv!|5Y;pn1cT`1^_@u0svq!U^&bo=pq*RBw2ARCG!ijhltQ=$P}hIhyc$tpl2k% znD3phxu@?80DuTR2SEHU7i5tGfDl`NRPLiqm>-K)JSEBjK>M1{d@76iB0~GlK#&*# zpwj@L8H*4+upEFn05C8D0SlM`0`V+J(jr2D=KpC14-Wtw`5!|ghyX+c-~YS;|FbwR z@L$G%DL~*nDVKmE2GUCzfLRnw%v2=8RT4OsgTW<1ONhgqYA6+#VlD=yU>C+R*vlS` z&l^Gw%Ov|^j#UFD0ePbaEnvEbMJfQ9he}e#iGt>`nB_NSOTfqjUZ*rqt0-%#A%v3N zT$0M{w>LKl`;2mFW_u71>2Es-=$Ql<8X7Df&Vk=QJ@14?CM0UxjB(lL7yo8VC@+aL zu5eXyA-4@;T?-ckL!*K5!;ml{H#7z;h!LswH{JijDxRpKf?c!7cU3s#8e+ydGOP)5 z1;_1k_(>MTrMiR)zqZFBoyG#m#cIYk_-?v7xrnm^3Hvy6X@S*)gf)gEj4jjSbhNO) z=qu>H9q56DLO#z7W=xrbq`T1fU7IVAIuZ#rlL)x#WG_=QCA+#}eH0z_CB>+lMr59e zLSHhsZY4Nm<_`5LORqF9Uo=mP5#Vun4ilZ?A#2j*KI5sMBz5CcFXC$|V;ySd@p#e( zgKMS8W-)4I*AlLT9?x05Xo$vg&%eJM;Ek$GX@J9s83AWwNtgkXHu!!Ma;iwOVt#dL zZ7M44xxMfTz3m}Gj06JB*>6BbVL?8u3 z{wCsgT=NvRn{;!f3!BP{Ljp+Pbxw@a$uomoIv=FZUrgcSv z2<+=e79nT?YDHUzfM zXF*S~y+b$LkPtcLI-;;do2rU#MDO9Vcla5+)0_U!tyKgc3M_D>aO_L_aI_mazf_Jd z2<9@@1}z|0A;%1>RjrqU(@f$mb3kP)b3u z2Dt}CZxw#I6eQ}VH{OkbM@dNNmsaxLDBxVksCB=r`<^7}SqS$SFM@Ki4FNX43P~lv z11iW0EJo892>=7(Q`M-2{&E@G=(Sd9E~RKS_7l)bV-wt=kH527KQae5Q&`gS=>~M#K9Koo zX7Xfcuz94A;DP{vLavZB9K4?diLV5tZ`d9T%2nd`qBfa-LJ94$^;#J52DAuo5 z%3~6e`p4&E#=ZxrAsC+CK74PO`%po!We2`mw;5xzktAID<3B-hibav4k(d?0p)f-K z>Sy}5*rFQ>`nzC+Y^XnlIO00aTg;fhno(f%W`o_j=OhiG6yup<1}L;9Qi|WUg;z+lnSC7o)#<=aZHOC;nFQL?)4y zr=nN|W{DM-9>{VO%`ngLgQt@Qu!6Eu(1Ga^{IsY1=)HNMksz%EroyJ1OEh#qqQ39L4c84>MUp z7L7#t?0BA8IX0xHM9Q_q;!p+xZuL^Pwt1+c|=fHZk@0dOM-!Be`w`6~AU z6c01NMGg?{n`IWonz=llJe_B7L$SZSyp*T-S=K*G&*Fqnc`57sM|m;wg@s$$Fk_PW zN13A0Mge}|1rPB?;f49NNb-eS@iTcEQGRd$RlH1^MUI$XyevXQ8tqXeE;65NwDm7N1F!~md-gN~Yyu58Frq&((coKL%#m6k<;XF>+Y4;+=Z zOjkVRkd@_^S6(oUJ%bQ7^7XXz{P!r!&yEMZFfXq>3-k;wJ%w1nLsl%ZB+8keV+G4u zlc!+?vU-r7fshsE7l>jw6h>z7Jku3`aO|{#K;;K{Nk4fiS-dQ`c#1WPB3UYB>r~cs zN`8LWiQ;_8v+UB7)G|B8I=uY(x$L~`qO_uU8S_Qr0#9Yr(oWf;(z8FsrDqnW?EG*I zKpWbl(oWb%dC9ZiDtFn1{P>c@rKM-4$_p=rD&tZA?DKL)J?$Qjn|)^;f%=9?*11ji z-Zo?GxAcrMvdf;zte>AOl+W3Z*=AR-!u!b~CWF_YCZAyY$=c}1k&V~mnPJJ2%M4c1 z0Y&<9^UIY>L{Ewa181z`FYFru_r%1zt5BEJpDSKm|Lz1K{up6(oo_wXuj?rBkO6lp zY@Za_Rm9e`TBWNTHv8AJb~m;Iy?BlH?TY>mGf3@O;tpVw|A@wdBo5nX^?zaV+cS;1 zeCxwNF^yJ!sN`EdoVdEyaN56U_ZOVjeL=PiR+tp5GAp-AD4t&!I23KxsVt3^C#`+< zPB}q4W?Ik?q9|?4Z||AWobIUT=F*AK4wR< zo*6^tS@G*Ap)ucgh6d0d>=qBxJwa%Cckc4ZWfEi98yxbFNLA>`qB!cB5AL-wAbJ)D zGD&(pqwy?Yta-~%68aR_{v23bvxZ%D-?odSR#9Qwvvtc;k-zxXd4`?pVB?hbZmsFBXieh=+gT+rfY>z;rJ7iRoM+)3 z-mpWK1SGu5Ch%Xc>bII!rq3J&pOq{g_CGp)PH8;fKPh6Qz!x~Ft%4OfsT#W-Hk(E5 zYqx+qxnX47R%iJyeW6dypABsP1w~yPI%vlRD^57+tFM!|4%cLg-Lp_tb7m()GCtHd z5dIoir5BK}_c0x0x8A?B(w=iXDN>ob_}jsLz-)E1*HgPJz~W4k!Gy@qxcDyvGv{sw zj_w1SO=AelJ?e&gdNG48s(W^0fV#lM@aEECF{(%LS!cPXVB}hLO3Ll#AUfLNkkxY0 zE%Wbu^%FN8b<4*_@CI3`=qhO0=Vv}Q8$axMk?i5C2iV}fr~;4QS9ZS(x1^A<2DVG5 zCtu#$m?PaEd)Fjhqp5bcNe=BR?)KqyiBx-(+N=J!k7E77#6(m2iQ>e3O)ph}^|Lz8 zt!5u{IDDR&2ut^MB1|%#S=mBPWZiuwW%}qzVwIvIfZRXk+i83^vr3;#$P@cZ2G+rH z?Vnt&+nR3&RhI-g&0DijiFUVDXYy)SRT-Thpbi4n^f^jNgOy zE`uUOjZ$1&@BH5Pxtj^@@O16+ZcD{~U|vb}<~hrWA=DWMsZM!^k!g{5=YIThFJhQB zAKmf_*@E2*r?r6PntF9+;%e$`MpP7K&LWHZtDZry=}kuNw&2C2|0+%q#=2SpdzJ7{ ztg9eB$x$T~?yTl!pr*a0FOx}nR#y}uqWu>U8q*o&RZ}$>Dw+YYU%hH-M{41Tpf%jw zPAbyn5)J3*8TP_91to($y8RM8r)zMj+;xgVkkeD<4>jFm5w6SR1a4XDtPo!+UOyK~ z{|~_Tx?$k}9?$@mp4Di$Oqu03-TL?et3G#FE@ZRJ%hrYAtC>UY6r}oOnw)2d{TS`C z#e(-o-yi4N=`Q|5P^>tZf9dH^!9R}s#cZMl<^kseHE8lA@#r(bNM!?ShAvy=AkUc zGctAT%dny;PZ~GbV0l_fkO0wx#5ykrheI}fRQHF z9~89U60-Xg;5Ms(!8#Obr4fOcQw2D1tci?w0QI?qgk-xR1x1?y8USt4SCYg*CQb;Y zHU9*QDP0Klug0pK&mqmrFwf3Aq=u-l0clTA^+-N|9%|vP zH#JEru$vfWTFOs;Xd##(5c33FqTyx1F^)GdK2<`_W|BEzjg%23>4I@Y;2|CmlXd|3 z5`)Rid!&aoOnpibb_^K#wP(HRZ;0&w)?)e4o`%f+MP)w&wB7)PaZY`+D>Qi@iv`b_ zc9L?y?NL$QC>bgd3;KmhBEdt=LqOD&aE)>dKv(cM`3k&+JWpn;m#uZk8Pu!dIe`RP zxV53EI^F&n6&YT+E|L~Gp8ClbKi+ddoA4td;)o)fN|-_i)Ad92tpvD%bl`H{a*DD!4n_gguL{mRAo#~D z^RWHeR^^bQ2I6p`s-?pIr++oAdra_$sMD4BXmp&12`O~O>SsWD0p%m}X^=}Pk|07o z6(;GcY~0FMe43sWepTPPnDnsktGwvfdf zNCSPBBB(ZiTc23cKthKiTQ&yS5W$Hyd!}c(1A9UE_|F@~TCvs4az{_#CxYXjrPY&n zg3maolgtCxaGC^BQMTLjN4k>)Ue~x|p(0{+B zLBcnJF5gv&zpO`Z%NeJjrWo}QBF6O#5cr_6Ph~o>dEjtcig}m7TE`2HZnz8wEV4Sv zWb)D*E^vt%&U3w1q#m6jl_s3xSaD&%982a&-riw4Pt~(2S!ozmKOXQ&KibY0?6Ya( z%RaTc82(rf5VFz?lrNi*9@#xJs^ie?lFNQF_+yK-Fx&c}>Rvhy`f2^Lv4~DSt#V2r z9CcYjn|X%UC3bIsf6;l>vr&%K1VcMbJ00mwkUxbG%4cC2N00mth6YEOGF!1)@4=Q_ z_MxH>H5T@9df$Q-2M_=tUMGtUQFONb;_;X4HXs&_;aif=zNMiO{f28|og$!H04#oVtVjIb6!frBCri$TDNK3+72o~tu zB#kvgr58Y&+yMqK!I5B%Qn1KyT0oHXY*G!z$!_vA?@{egxewI3}3 zy|-BgoW);}&gSUh;0GTSZo?^A|L2jd;#kwMzt6yIzEJX)681n3TjiNK++vrM(*#_g z*N}Z2SiqG?e&=DK3&A+{fvg2BEl*7;em@E50_{$R7}w_2IT)a9!{l zpSJVpTl{v-wmU&%wua$ZD_zcwZW`7#P4J9-sFgA&j`K9cz_2EtHIz*MO2LDs%dE=V zX{Tu+vV3Zum-Y4L4~#w1a2KCRJP_~uQuxi9yde`(>i0s|yR$WJi$HJv799km`N;a2 z?WPt|&DjWgY&>)BdAu_ug0;mm*sGKlcY4=ex%tSSCfT3Cvj-LNd2){@?{rTcQb@aq z_y=DVmFb`*ZG~f1;i3)v=xSlEgYOkzIobq_$@96r4DerNLesx?uJ3+RgI3uZRu(wj z&Qcy2v&kpdR)5G%m7bmyVxl2_HC`qu9&74T22x%2YKpPYc=H#cfCB(JJX77>2)mjd z8@yByC=^MU3E?_gJ3~ON$Uufjn+U?L@uyW4^N7l#W^tNzyumGUh&ZME8-+RI0bFbUasI zMaZuTsSG)Mt=?s2(TA5je3cqDnHeLFYGW3E*-aR1A9Ik}VPrwYR&nj}0o-KsvYP47=}Tl8RBD8);eggG*b)v1^o9+pKPe~ChVo#=e|m|26G&l zHoMzI`)Auo4*7S=74+@;{#CW47n=%rY0xh%LTw*U@tnFyZ6=>0&(RNSD)t+1t;o3gx)zx*vo^d+b3U~+a z6TC-SdL?ZFuitgP-xSNa-wtd<9^Xw|Hd~2zLx%AJn-Ye;t~_`c4SK`%au=vU0+l$#X49ia|cCw`6L1X<#5HWvCFQMNgJYERno zcF$&is2gx11dhpig~}KSbM$;5r}PX{^pOtV19fB5YZx{SOZPhV<`1A(CySVhKze~9 zCjllB%*v*b2fEFfP#?V(LcF6o3)OM@RHYB=qmj8n?$<$J#&FCKxeRvIaR0ofWaE^X z5Dv<@CqSIP-nNrQH>=gdH5uZtLVxASk>L-cgxA%eBOr4&XL<41M{U{B?BYydVTk+~ z4WKtJ!Y{=ta${iMUX$a_h}r?b>sl?C>t zST^Z*5jMOUw+GDar^K*QB6lKbgR$3!`JiO!z|#vAq(y1`h2>-IcCBE13+<2lkxj&lcr7wmf+j>hxX^w9T?Q?MDejph7a$a80g@l3_W8 z*2s@j*>R4gRFWA6xUhL!3`epCZ*6>_z!}dTmA(&D61GXrB3p+YZ zFvtuap;oq~`y5kDGP1ushh1%$J!heQa?rbDgC267M$ASw^&iwS&fM#> z>=GNIDLabvIWk2+Ub-o)mkdJAilIrtD|=^A7Kh1Qwkfs-@v`Ld+Gf~Kj zXZZbj9y=dRo*q!zaFc`eG`-Em+odhn85@&ZG546<72^ZV364)!j=Dw@)pa`4NP7gz zf;M&w511Eq+)Xj5&aeQOjgB9qMm#9EalN94@Rs1xC$5fKfYWTUpMdnIW%jd07sk!uM3~<+ z`DHWPpYl3h`kK}?2Bbp-z(u3idz2CsnOeB_0^o9F&K9*acvbp(5U=u7swt{&Fxn0T zSh-kWD|zJf0{O#igX1`k01usa3X1(Sjw?>%d}`L`tDs-)~f2~qxY+MaRTRgeHWhyZ2iC?s;z|DX-?B{41gK%Omi@LfK7ouAQOz$- z%3gQTe%WKY!%AoWv4bpjlhj-xsMHdq5Y8>>zn!Twia}@@PmV@y93WOE4Akzanz)$zv*chop%kh4hBmYa(4e1q7%u=9o=0{|fgqu`hoNEd9hZ$<#hwHy~Fbmlp4 z#+ZeDKPNC6IE}^IU*%`QE54Kvos5$nYiaB3H@AA;Uw$sq?KGU@K(4zF>={-hvh;!y zne1vEFPLm4qZk@9|ETw@y=Y(V9%JPOxe$sDOAkGvm4OAoqs$#I0x8TcjxMYJG^jVkb8; zqgk?B-j+G%wP0Cy^|k5-^}-kb8`HH)gr)}-_5uHq5Tzmj+d?KX(6uO7O_tt3qxrmT z4~)Iv@*F!G5|w9P%#$I0BFA5rlOa$?rL|Km;DbVr@FO9W)zvB=zBpt|$_5b!Hq^Ln zGnM&GBv-k;cDTkDSFy*?y^Zq05_Qp&lD;i9Y^#kbfCT;_Ei1c}M(N-);(WAM?-#Ux zXN({cWc--{=4fU&WktDDwx0^vF8bApdd{uH$ql-L$?&zYV3=I>vXRBL?pGzD8~PTl1KJ zBa;Jo;75nJ0CN>GtIt{>-fu|!MYU@$|M_6 zp0BtPoM+*eR?8w$BayVfZ(p>=NX&lY(2g`AqHATN+t9t#q1|Pt2DhDR-Oet1Ce!e! z+?-r8UDxvDl^Yw*)Y4a?1iF9zwQp?#>KTslmF~3(0cgG!9T|4eATm^lH%|Y?!WF)( z#5U_i)f#Is`&FLaAo&A9-^;yKW|_R5{xP>>>rbOigX}->6Fll^{A&Cc{Q-xIEes+M z>%NRyy4vP!@*zF8@DOw-uX|71Vv?{rC47}?%pCZIga%|7R``MJS$Yu_w*CHyW8asy zcdaPDdNdejaD3WT>K9-qkF6JZNzf2zCx)G!Sd0g@-;oA z;v0$~ceKxPj&9nN;r<-u2;&R%CLszHSZEBJ#l6L>Yq~^PaNA45YFT}lwt zAfYY7B2oV)JH#dNAq7YsUcFN#sS4)bFn+A4-ssA?#my|5&QaHBNRnVP)DPxZ{JhO2 z)}>?z@mPObcrJAccQWO+gr#;n&6}f&p`WNfaI%p#D0}C@HOZF(Z=~fupzs0$q`ddY)V#49Z4<+KP za!^!GBU?J8ig{UuNVe6gumeUpE1S?}+6#4e&fISYORCFvtDSUs)v;7|cNU!*5k2)q zHi!@|A!Ql)m&KgKG--oNRN(4+6A+oAQ{?JOIey-jV-#>C43LaoNm%Z0^^@WUGRaD% zZORY3jIVj9KPQD3=K23TbJF4a)A03$6ve>mKbiDN>Q`5+4;!8xYm#haETikB=_(s< zsn7v+23i|fXBZRj+%?bO4%Bv*kwWpcbGRxmMh8cw4DcHA9*E+#I52cht&O1_z~^HP zgo1P@*AUPe$uyKSoc`j4=t}xn^Ea*RT4vZC{S_{M z_i%*c9p!jSME%81j#;wfS?-*fH=v;W2&yC1M#rto^6P~mQ zuMD#U!-U*)m3l(_-RDNmYASsq`42<);vflrc|=_zUY=et&V7DU;DGcgEr>3x4;hDM zI)6N8dRU5@C+!PYqaw8JO@2NFB)&D8yV@hHYKK5YaNj(HfrA`#lL1q3 zol;L8VRNa@`R`nJT0ChB_~mo|BU|-aoRfulXD%&h&rljv_+#oLL+x6}v)GKAqtJEbF%Jz+zHvhv-Br1Na(%4eD&8aRnhrOmWBwO2c z{EEv#I_;Y{;YTU5*$P^N%S-iwWHdhm%`%XA#+lyOIHdR#wKav^vV0yR-~{UExQWj4 z&6KK?ONC{wp1kt*GFDS!XqwL0sjxuS5!N#&%VPIdpj)tLAF7E1$ z8~#2wUCtabJKB9QxehtC3bCtywqMQ~7p%mRlO-ZpHd}vQ(JQE=W(ob6Dw_f^m@^#; zSUEIQ^EJsNn7!km(&aIhyq<;oIQR0jmxUnA?&$GV$`i`IjZan%%V&=@IzDT<7$L-J z?`+Ut6HZ-v>Fw8HHe>E_c1Ux(>u6--Ny+I)2L13hnQ_<)pDf7m$Sj0_@Ta6nF6rR! z2f2gRw{Z|zaXQ_sY@N!MA^6?(ATC5aIy^G0B_#hrtM8tU^S7mLJ!AyLMx&IUzKLg#nDygY9yi)o&gD!w5z7URt~8qm~=dPvQTr6$zci_4BRN_-u&1DnklNkB|?^Ev)ztU(MHMqh?JAZ%R$rJaW0**7}l}KNcei4YK zH1TUMx|gpMM1tQi+tQ4|3Tp5XTaRnNba`q_Xajoeab0TE^|&pioYUif5Mb&ig2 z)*j7ZWht}CT|f+8xArk^le$tF;pe8ndme;Oe{Mt{*`DaP$>T@I_|$& zfV7fCBphbbNbHB{aY%_$KvYt8MJ&`Tztk@CGj4S{h6Dz^Tks{_rvHZd*ryGfN#S>< zF^fCHtB!l#r_*P`S}Ocr#;P$?1TI9fngC5BT>R2w@`Br9xrK9<1v#Rl01>xNSJJGnS3I@Th&PpZx!gqCK zHfG(kmqSA|Ojpc8+3n|RCob}H0iEgzHQ*IrcR>jU$6jJr9=|= zI1~z0NBI*5DR##Ldw1YpvG81{uqso$l10;R0$kw|H)T=SiZ=Gy0tOMa)JFR^vaTxw z(g6)HB13SR;7MZpJsd39>mk4{ICBP93`uwtygL>$MT&cOGo;3Qx;m6XV0JGfoDBM3 zWQPpDp^RsT^aK9-E^FO3VA^*ZCpI)>n~EJ|J=L;I*1nWYiHIil{m#y-vyFx8d6-v7RvfrQaAc%9GmSpipv)Op!kpY0}~T{Y9&Bu-0r7--B>baupCO6 zr)b2E3FXGoZ?tqWij%C6zBwz}>7Lm|fk)PslWImIQ_Gbk$w!MC<|#FFf3j9SqIcsD zV+U6HLq(=z3sXpQ$$6S?7W@6mz1tDX(7&)vC>Hj@9(K5W>>~6Ljvd%&KDsfZZn&I= zPq(QwtapI*SPnOHD>+)*c*Z!Lj2S$E6a60Ch?T>jAd@2S^8J5kj^Nk@E5JPS@Bg36 z`LA~;fSAYPL7)BEYwOyl?IF6^ZGGFdaogK%{`@R+%g1KTbIaCeb*}Jy1NfsNx0-Y6 zxn8BK&DPGaYq(f_y?x%72HUViDpyr1TIRWPy4rg#PE}P!z8*5uhnRZ?4oY%%}J==wnaNEu0nfrVL|GK!dUNNJe^vSKg@p+wNy=rR; zs;RT~!LH+?y=l{>$=A)z)p$$uS>K+R{(ar|2Y;2``?=S(T3i44ddqyrd#1CA$JGhp zeS0PTwpYg};Wm@^W~%n)bLZBxXS>(d<0@xuqvyNFRpE2j`_+BNd*XzyI zd$t#o*|wdU=XC)NiQi)|m)8uL!mbpfdQc5kubDNhJ z7M}RjRh&rfWwo(-W7V_A_;r`f({sPE&*oOwJdEy>m)UUFwp%mHa_6>9al7r=yIwn2ua&&M5K#DAc0CZ3qTtimKqznL%W-RH4Be{ow zhN<$&f@cor3!oy0i$~>4p+e0q`X_^0ES7(k3#03IV3;H!Zt>*dVisDrKD_FRV;e z94Ui`s6v+I4-Nn~AV>Lc1i@L2fB@hOJH8-r)EAI~PKAzcE*1$5Zc!9^U=dHomx>6q zh%NggOhp1MFallb`&N4R#X1F723vh2%DX+v0}iVm2FA!E2nb+crij4m1A7h;!pg(S z1I&+9XQXq{-P}IFIFqjD_aqf*Jew0&zWuon+KFrb&g@^-$EeCrq$$yUcZ^n5gmmp{ zuS_Jdq~orc38&%ikI|mQi4mUG%jJreq@W_9fW&`TL~@^1anf7pUX-;-n-E$U&_j&~ zH$)3D#g`r;2RD&-nA~s{cIQFoOr7k9UhaGlOGa4KK}+5`MJIpn1zXvyj`t=y?kiK_ zw3@4UAq(7SbgV*CNXI7Rl$bKP!WH_2JpFg1V9J*sLy$d_7H6AFxENoLpNTQ{5(v%+!{m%)QW)}+1V@meN-69S$nRPYsY%Li0uKg~Y2VDZ@0hgtBea_TU| z+B?ke_zbitvXL!__8A(Nt4v?D_h3OWnstqa9Kd#k#8qstnr{$mcME@1P4i+OQao6V zYisCO)QCAb?Gm;wYSbDfX#ok;HIWlPsguc`f`{faxs%qfelZfTS|TVZIsWxd=JbvXuc1Bk!0 zgZv#kb#aypUYs>o_l}=B;_^#+MSFccO2mmWlZ3{4Suk5StbeVV%`g>+K(*r&H~p}w z3H=WY3ae%z3XUBjHhbCjxQmuq3>*ND}EnjAD& z+0j%zWO_VDe3@ODBW76NAq_j^EPLT9X)m3X!!t;f^+BDx8N*1hFD!F}3$|Lc(+-%8snY`D#8B=Pnk8w!C*3y?3_{A^+VSd+@Q8cOk4b$jK;w)VEksz_$Nz_<6^$ z2=dj}ff@H{^odJUYhXj{CSHECj2D8pU^kC~S~>@Y<)CsloQXjY;x%DMpi~B-ZBr|j zX-FPxGJx@xrT1c|X>~+LVLjCdo{<)?0#-p>_Q?W=XxbPHihQ@=;)Zso*a)jlA)QS7 z?TQR2Lg#LJ;Y$D_0A34)F$h!m1WVe+3W=D~!U#2Wu`(fC6EUq3e?+f*SmP^os3YXF zhPv72E5^Y@GC+k`*%<0w4m59!G<6K-9smi`^DdnFVW3$p1uq19klBPP`Wpm~-WsvlrQyJL zh$vH$g)#u*| zWVyQK%_Mb@xw&H&6P5>doN9yE`vE=&Mt*tCWExpH<G61^h-+ zbJL4n*%!s`i4y$Z$xTInEI=bzt^$^=-4e+X1HQO{2v}#?2U!*u5l~HwbM8i|9+{5E zA;{CcjK|E;lvcRYiWtg^W7F?v4WA%GHI6gpiP4`wJqy#zrz$!rDP1EoA-KJMl2c6A zosQ7K0PMxc`&hmbl|VB$Ze|<>5yOzXO2IFUaOwP5;P=ISw$^g>`sI4AOrgeC=BWdd zf{GPnWd;apw3ROd1pUAHxgly3muf`c;!_L3iknRHpN5)rDkqeE?bU&7?7mstI2$Is zmj#5hFa8D;9444{$XEy(zj_W6H&}&Pz@3-fZFtqZ`<)~jW9^q^hN4_$xV~Z;8U-N{ zZkTsL0pj|~8$>llL56Y-YtDt5aGsnl6R1AgZsVE*~Zf3g?UHpBCz!b*U}V zqO4^RRv!;51u$7Csaq^r#&%yUpMR}HKyquP23HpsGBnABooY?7)=mcykxS@qt%rG5 z1D2X)rv-$r>WX=|C?Q!)Jne;ghxcA$s@ZX0>buTG-n!an(-ex+FXs>4qM2ZLdN6bb z*l*DpS?V*pZvzqinrMj%ve{(d@`N~!T25h{aydrgky&EHH!DfACy@T4{pBsjL*RU7 zE+DRhpE#`xiJF2yVK@Q?t>w`QoBF`8o&A{X`w@TvrXuvCEg}c6j>HsQ0QFQATXN2# z;_{JupbZ0`#ifW%>RZ6!q-L{h0M42dG%lo{c!ORew%vjI4@a=DPf7@G0!K#&*PQLp zG*=6sI1fr)A<44#+HL9c=ByYTr`G;0b$C;dqG_C|P6RCAEcI{?4cmFii=~AROMjw| zKf3w091~-an>^P#I9JP(^|$L)-icukFkA5SyDZ(+Xrx&BDmA zG0t51QQMsd*-h#-O$lnCLtacNxmzWb~&X zwp{u5nTp;Vw)XTyLc%jY>#e#V{2}wCHUsIsV=k9+z@JiTG&WcFB60W%E*rJZ$%2arSnuzCL~pQp_{mO#1wu)Enapq}^~B<;Cf#-%ENv%mG>Ge$=(kumdn; zfnmj&gN90*#TUVX8#!CZR^Sq_@4REq0x;KkYto;Qy1r}ZLq}G~F`ej{Cp_ENT_UFD zjFnBF#M?=7lbnBR;zofDlRIuU_PxRYzc<$zu0)@xBZ=2V6hJScE-pDsQ6Y77ka>y8 z#&=~*pQBz=2X(b`is|5!spwV2?M5HT0x_GNyZ2qEReK}>`|Tg@O!zA|S#0mMF8CQ0 zXbesc8o%fv4vZYoOFP-1*%Y z<>mSVH@W>$yc+&fyuw~90Kh+|cplXbT4_m;mR<+53HsMyj?MK?Jwv5K!yqht*i085 z!iq@%$KA#o0k@Vsj%iyw6MGl<4y^tOU4aAMT$?UFk99UsF!yUYUuFVIRsuaKD*Q_G zHPIxCv1QxpJDh9H@X}vFc1=Dpty34)4T(s6CsBgscastdRsi>nQVVt3iG^i}=M=~a z{u8dJI^W?3+Atlg-GAq9jw)Wq-xy?C5I`C~>B?N|Ei=!9SoO;8i>1dkmfZ3xbR&$p z@#hKhw(b59PfVfnjp@5-l;0lX3kkvXX#~2T<0b-xvIQ&6U*TEn-*s_44zw%2nF*lr zR&jkYd^I&cg*?>!ZV6-t)aUSqDwYq1N4c1fC4YETQIbTQlrUvx5%_10oUNIx4C=x<<|%n~tKt~DI^jckJT zGvS0rQA8Np%FF#aFoD=yz{UgC7@`6pI5nl4f4cfg&Q@o3T>rlGon%LIh+_@7VSq6o z`Be6G1|-h$=hVW#b?oXIsQJZ&OQ^Vs!T!!&p8)CLZWAPP+$XJ+rlOEL7(YHen6t6! zg~YZ3?tt|vs5HuBtwD5sPx?N>y{3N{4w!Qkf$9g{RV+W|AtM5*eSRRUh7NgQj0E?6 zCG%-{ui4z*AJWGymt2k6TXd)j+vFrOUL;MkMm$TRdN0;#fV`l~nX1usGmY#IL_hCE z=S8x`#Vaex&&R1a?;%uEb6@VpOvUWwb@<{TaLVha(JIyWl)wU=CU5#c_ zH`(vfc;}wOmsV}3FS9p4ej&jk-}IwU9fNNv_NaVL^K)&KCHpdJJNxw4#$MI*vdc+a zhc`u7U^#-#0V- zMq*%r`8dCXUuSX871QXxYrlqwE%5;Rp@zOI>K{AT{Sgn$56r{1^i~TSG8&}erc?*h zH3l1Vqtf3&yC7>h(w5sY2MOKKFcy9|Edi)y@np)q+n|`zvR5CD;PySDAeQE7Xd{SE zOrfo}J60CsYv=3dG`hQbz8qANkcr`$FDI6bGQDgUaxG~H=%nYLCLVZ&Mjnc}w&R;B zQ83(p8QH}|$g9|gxL2>Wa~XSL2{OTK0bU%X;{%&3bYt za%K9YX{|)B`yX@|#9MPnq>9hm5nz3%btmPRU+_)8WukHCAv2UGMdS(~q9xhbxeM69 zav2R(mkL_U(#d}%Qs|d|?Sld6-)i1{DSs?f;!hmm?-^FcyHHWbLgu1jIX+hf+Z5ZnM8b5;$*5; z`Whu;sjcEB&YOlPVpbx0r|<(apj?B$ghj<`(zCcpNcK6T5n}iwxp6{VGMGgYs;G~Q zmA88t#&3I89QY+5bG}6O_u$`v(by(`d);G(nD4wzdyfS9v)X>Wd#J6ca}mDtu*s*{ zFQ%xX<;=Jf+F1M4i(l#!{bwO}OG9WH3tS$fvTY8V3vKtSVMr(aDl9&7cGK~*2YUFD z@99I0;wS_D&#sKD|1vIO;`qCZU@XuFn}9zV7s*Q`8HoEvQm;?q{bj z9KCyf5H4qDH2ZG>cZovbl>)NG#1*dI&+d51^hDLH;LjePOyHSru!_7F{Ua@Z0f;dR zxe0G^%w%zkC{7+Tt`sBE-Ix}Sd+KJePN19+od!tcawdQ1jlSaFGk#;)C0VCWNe{D0 z3L-NDOf5Lj2d{o$rV*;r>}-no6EnF5D(**l(<}gq;u8N5nw_}R;$}?thbb8#_uV0iMb40apYjIAb=B5>>i2cw6^3QHa#y3s-I)6 z-4UM7lyj`r{L>#kFA5N zBjsP8(BkPW@?CaoXG-9$P82-}*Eqh+d895&6cY!6VGwqqiS4km(<5Bh`u>F+`F9Z7 z8w{@gYi`=6bL_W!m+{NMRJqMtKZgfpsSSTZA0yF*3Eod5fTgG*+QSLXpNhZ-faGg7I6byEFDW^_Ezjx78+4XRavajx8$JP59{x(Zfj6;-d zum=9RK4iu8O!3tjwAH1R67l*5B`%Zp-voKfQaN@EB-Z!=SiHe(f zg(ek4mVtyml|vtP)1On^#IBq}GV30sxL5T*5zrivQu|M;=X)Wyr@OH-kWs4s=1TZ~ zA(P*zPP_3^_yL@=Bi9?CCk7IQBtx1U81arho%La8uqm=0|K*R@!{_yFGq99IvsR(4 z@T!Qm86fWLuul=)H&?)aQ8V^H#G`V)s|p8zva~p_pCJv^p$NQXR{ZGkt~5MQFXkz9 zlva$f7zqD+^{aj0BmT92{eJ){K-RyENk2EYPl1ferx?NhI|OvQx)FPBD?q|8P#W8N zu9ujIPRgOw z-+e_Nj*|LcjL(U-@3G8Ppf^E%7B;A)ji?d`( z_1{glxpdr!YP!U2=^DelCPB^B(?@Mdz_GY`G^9WW1=?ofx%AL^BGZlHt4Qq6b1BA4 zG^7TvhoD;Yt&VT!(r+CY*%&zScIAVFxd7l}T}&vpW?epfPgw_x(@}f&gL+k1+#e^y zT6N)3(Kcz?#nrhbb*)r?+lPb{jo4Cqt1B-EU;ymzDA+Gv-tb`d>RTO0zZfh>05RuK zQKt5P$WwiuFAiOnm)AoETp1aG=j~p&9^Iq-8Ft^U}edM!soBamzGR1X@|pYu;wCnWO11j zP1fQJk0^l$&eV;bA!TYkEt_wOhl3@H&#cz8oBV5h=8~e$#jmWDHnhfAAQ%8X9g7ZK zL@y73U1r<8c3W-nQyhOM9qHbF9Xv(c$O%ReimNxZ3F|8g= zl}7l-uWM|oGI5#ZyYt5c2B`Hn4|Xu7vYYi}+AwYprswv-)4j#9IF)!0MXA(7@}5No zT+exj6oy4YLh__%vPD%BQQTo*!%&&RBFA_+T%PXY?7t*HN?OK1C(s(sc2>KnxKxWg zYePS8`m!r-DghukAYyB^@PXWT;*kt?$ZAw13})dD$nfnr={tD?@r$S-2$DK_*sXZs z@%qM*Y|~ZnFIt8OLv$fe`#j&IbR8+mfBsVcmdS+ccM=xy-xC3S zFGtz)mkB5L(HyV?o`l8E9GI7d&Tj#rG;AQJl27lc>dUI)em$AZ8K`9~tUHf-(HZgn z%pxn|PNRcTEZ+vz51n?^chiZA=IchUB-i`}vOEHNW$j)1-^w;c++lAyYKON&wNG%N zx^Ylmhh7cEZeKQdv*c`RtucEOo4qHExn#@mdR84KGK^q^X2?+F^WBw@1L8+iad!+j zvbXdr*H77L;!g9>-XRmHiRP#Fc^ekVe5`}`GT#vH)0t_SzaiRN?rpJ!t-L?BOM802 z6Ea}(kd?P#QJ^AwUEG8*(m~Okp>N7>o+uk(KwWVb<(|L_CoHnCt+}<`im2!S?WkB>i7}I<9O4dKeWgCb@%-u7eQ}_29bFv4ed3es6uPQ=3PBx3zLR zOo9rjJdaLR;e&)Q*uGm`_<% zf9XIO%5}sV!T4NNsFK4g1&?Q#N5Re(#kYF-8Vbl(zAIi=lr7)%qp6q9()SuTHzO-A z216|#@(F*6wKZ?Urwbl^8HWW37LV_AZ=%h-57#; z@bxWSG{GO?v8QRbTX5)9dO;fP5a4>zEY9ch7T1tYF!DQ@u02!$E z#s|!D3e9+M<%7lOmNLRKa@_F~I4O!U5bs*AQ~gnCthHC`2@nBR4#hrGdw9mopZ3!D zj`YP=WG7=8WdmY&uUmLzs`Tf_=;?1pK$>??7W1X8w81Z!zTayOcq*ysac4qFkisd?jXO8Bc zwN9SMqdNmSUrc{qdwaqUw}4yd{)9tuI!aa~%vE#hlqYTEZF)&qBl`V(jkTk~rTBWZ zQSa00$KaVTC{T&=@-fu6iD#+elLBm`Fv*bIrL-$=aL4WLN9i@rzH8%>K}>5 z6{u$fc1rhqRoGdRd`NqJs+f3YhitLD<{&Tn3V$}!PgV$jtGJ!qg!G*HY=!y$+4Woe zfc)n4{tvM0VZJpy~ojxWk5W%m-GUGwzw`XDDd6rd)?4;M1ts$^g0L8L$FEL z{Ni&6_?N8r1>Wwflr&%UV3?`d(eF+7dI#1SWte)R-9*G=U!o#!c!j2&22>TwXDHfBKd>*N{bZCJw|@H+>5cb_`_}ZC z8Yfc{|>#oT%MD<*tH6Hi- zS2lwC*KfuH`$${{ym-!D7Gv&L`KKOFF0QWSPm8SRBG)@7rK@eW{U2Q=7HIY+-rL0P zB^t4XSqEnm|2rxD=tpP{e_+*pkNd8bd)n1wDbUU80MOUOZewk?(pKwrf0E>CiQUeN z1NgJhc)!_I1+)(qUQQg2XBavd8{UtO`hVrXnusE91k~aC3fYF^kp?@Kk0K#b!e|{2 zrm`g}F9i^>_8INQ(op+d*M*bUTU(O`F2ckJtbBnGmOH3kO}*!(`v1h&Eyf+uuN>cf z`L7oGm$KIvLQ#>1P+DtZ)6jQ%Wku?L4kZa5d+Vs|g*>Y~)vG5XQ!980s!)JNY;0#> zVOadjEOtr~Z>0_V8wrG!PHB);V^mvbL+M+bAO<$T`d!|}C~*n3>Fq!ZTc0-G;bF8n z^L@9?7IY9Oo^YTe6}=&%2H*0<{J4_AZFy&%px$>zIB~y(@mr8)T0=bkY`D)pEA3-E zcR4gtPB^ejQv`#3G!65r9ZbOttAtT{im$YWVA z-I7}hO@_$aO8<&_S(9hRB)I<(({A~_URRzE#DKB#IUvvPI=!^=YuxcsPz?jmMqHKV z|BrfZW|a(2=%$@odBqgOb6b_8kP6C!1EZx#dX*eIE|A`@c(Ckr(Tf00_lAZu=)y|% zjblk1sL?TLs%3-rx04-=xNJf``BpxquV-G>3as~AUjE{FdY3? zff+BD?teEUo&%Pz_u+|R{UuV9dd|@oEC78U1Gi&0f6$4cu5Cg-4k~ZxZ5WA>5!;L@ znfcHH%4B?qv0dzwGAHNT+A9{R@TccVuCLw1zd`j~RKTbPUC1v1`)^qpFibIw#3FSe z9X8nxoUxdQJqU?R2Cihb*pymlE^(X2+|qkT17@_k?y7uJGkw|9JVOba+Rb((7y7XS zK8t9vV!ay3Fe_j#f}bYAm))L$2S>x@_7a_8y62$%rbTu%Z5smP^{GdbC zCo~hK8Ro@3e?=E1^UcrtX!zwQe3tW{NKMC3<5pi3c}i#q}CqnU|~wEtO@6E&aL_o64%91i?PAd$+Xew z^mYqmC*B>H|4qzH2#fY^a$By>+dE_+F@rQhZe6q1NhI z(mZFo_EY<@r9U&vmipa<6HM2yttn`TpdruR zv((Xl6~T0H&}k4y_V`~lL<-!(XQO}Edi~{ISujiET z_(lo$QdMTNnUw|j-;6%X*|Xu}XP373z1=$Jl;)8;o>|i=qfFc6J#5D?(70>A5GCjm zxU8BkR58%Vzg%SwANnC{e*}hGT|A!l^$lP~3>!dH{k)Hd0tbYvS zUa2mm!TIT}3swIrkLs)7;e^<;{F-0WVEFUy+;}3FxM#}$A#?~l)C zQ5W|+q$S~@8MXJn)VIoWof%DB=zgJ5LtOhcak$--ZMf`^ncQX2Y_v`CEf3jo&5}=x z9&eGm0|Cj%Os0dymsz1eSENAgFcMkBfP5w3I?xN?9g$&R_jJRJ~-cs*-s;3d8+kwTA@&R=?Un@R*>AI-Q06u?E7D6 ze=G~A`9nxP+MXo`WQT8M0r9k}8Ix+g5}Mz^*F?GfRTSw(DCmfBz)H%pRPs%^Q0!<9 zgvRD~w!QnV{xoA+ooZyH_^;Ce&BZ8 zO}4tluNjXXnV_Y^GMVgOB!9{LVZYNvRp-MD2%KkIMv$!ms)XY6kw-3bm`h({v9mV2 z42`nWXkvR_w5oQih)~R?kt|JBE8kAhb2v#p+yHkk`B&7!Dnw-XutR72nH-QJR@RTH z(|JM%Uh+$xtG`&XI@4c&oMV0=XuVf(tpp&U0{z1qCeg!lwa#OQk{;j4 zhk9z^-IT7Ecan|}&YVx$tCHap&Bec3LrzUhu7|d*y(s2pM|Mzd`02G{VHFVDUgvdn zITWoFT-5|Vp5Cr z$&j{LTC~@)w$*|Jw0Xy-e8LY^{2IhnUM^d1$E1xZkX-|dApP5q=EJm4ym#?vjleS0 z1!9X6WA;y^W}W|Ki&a`Hw1VXSOG>i2n};cttBib}PFJ?-7Ho;Cm@1h+SHyo))M`#^ zMAs?U{kZ1b50;qv3X9(z!&g?^`pnzNXmI85rJ{%�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 From 92466595897a95c5ec984e4c530d0833fb8c8a72 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Mon, 16 Jun 2025 13:49:30 +0200 Subject: [PATCH 0521/1218] Make sure ladx removes the same copy of the starting item from the itempool that it's placing (#5110) --- worlds/ladx/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/worlds/ladx/__init__.py b/worlds/ladx/__init__.py index 78ae1ce8ad20..b1b033e01d23 100644 --- a/worlds/ladx/__init__.py +++ b/worlds/ladx/__init__.py @@ -335,7 +335,9 @@ def opens_new_regions(item): start_item = next((item for item in start_items if opens_new_regions(item)), None) if start_item: - itempool.remove(start_item) + # Make sure we're removing the same copy of the item that we're placing + # (.remove checks __eq__, which could be a different copy, so we find the first index and use .pop) + start_item = itempool.pop(itempool.index(start_item)) start_loc.place_locked_item(start_item) else: logging.getLogger("Link's Awakening Logger").warning(f"No {self.options.tarins_gift.current_option_name} available for Tarin's Gift.") From e0a63e0290270f117d1575896c0e9ab61eb05cae Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 16 Jun 2025 05:02:06 -0700 Subject: [PATCH 0522/1218] DS3: Link to the Appropriate .NET Runtime for Proton (#5093) --- worlds/dark_souls_3/docs/setup_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/docs/setup_en.md b/worlds/dark_souls_3/docs/setup_en.md index 4c3a6b2a7d60..4b11c8a498d9 100644 --- a/worlds/dark_souls_3/docs/setup_en.md +++ b/worlds/dark_souls_3/docs/setup_en.md @@ -73,7 +73,7 @@ things to keep in mind: * To run the game itself, just run `launchmod_darksouls3.bat` under Proton. -[.NET Runtime]: https://dotnet.microsoft.com/en-us/download/dotnet/8.0 +[.NET Runtime]: https://dotnet.microsoft.com/en-us/download/dotnet/6.0 [WINE]: https://www.winehq.org/ ## Troubleshooting From dda5a05cbb37fec368f811242c137817f85525a0 Mon Sep 17 00:00:00 2001 From: BlastSlimey <89539656+BlastSlimey@users.noreply.github.com> Date: Mon, 16 Jun 2025 14:07:27 +0200 Subject: [PATCH 0523/1218] shapez: Change Links to Shapesanity Cheat Sheet (#5047) --- worlds/shapez/docs/de_shapez.md | 2 +- worlds/shapez/docs/en_shapez.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/shapez/docs/de_shapez.md b/worlds/shapez/docs/de_shapez.md index 5ef8f13f7963..4a26ea821ce0 100644 --- a/worlds/shapez/docs/de_shapez.md +++ b/worlds/shapez/docs/de_shapez.md @@ -57,7 +57,7 @@ Ein Pop-Up erscheint, das das/die erhaltene(n) Item(s) und eventuell weitere Inf Hier ist ein Spicker für die Englischarbeit (bloß nicht dem Lehrer zeigen): -![image](https://raw.githubusercontent.com/BlastSlimey/Archipelago/refs/heads/main/worlds/shapez/docs/shapesanity_full.png) +![image](/static/generated/docs/shapez/shapesanity_full.png) ## Kann ich auch weitere Mods neben dem AP Client installieren? diff --git a/worlds/shapez/docs/en_shapez.md b/worlds/shapez/docs/en_shapez.md index 4af398c5f17e..dc41d73d7e13 100644 --- a/worlds/shapez/docs/en_shapez.md +++ b/worlds/shapez/docs/en_shapez.md @@ -56,7 +56,7 @@ A pop-up will show, which item(s) were received, with additional information on Here's a cheat sheet: -![image](https://raw.githubusercontent.com/BlastSlimey/Archipelago/refs/heads/main/worlds/shapez/docs/shapesanity_full.png) +![image](/static/generated/docs/shapez/shapesanity_full.png) ## Can I use other mods alongside the AP client? From 5c710ad032eedb6bd79ea2436490423c5a41aee0 Mon Sep 17 00:00:00 2001 From: Ixrec Date: Mon, 16 Jun 2025 13:36:12 +0100 Subject: [PATCH 0524/1218] Docs: Rework the "Events" Section of `world api.md` (#5012) Co-authored-by: Scipio Wright Co-authored-by: qwint Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- docs/world api.md | 86 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 27 deletions(-) diff --git a/docs/world api.md b/docs/world api.md index 013b02cc2076..833d379bb238 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -258,31 +258,6 @@ another flag like "progression", it means "an especially useful progression item * `progression_skip_balancing`: the combination of `progression` and `skip_balancing`, i.e., a progression item that will not be moved around by progression balancing; used, e.g., for currency or tokens, to not flood early spheres -### Events - -An Event is a special combination of a Location and an Item, with both having an `id` of `None`. These can be used to -track certain logic interactions, with the Event Item being required for access in other locations or regions, but not -being "real". Since the item and location have no ID, they get dropped at the end of generation and so the server is -never made aware of them and these locations can never be checked, nor can the items be received during play. -They may also be used for making the spoiler log look nicer, i.e. by having a `"Victory"` Event Item, that -is required to finish the game. This makes it very clear when the player finishes, rather than only seeing their last -relevant Item. Events function just like any other Location, and can still have their own access rules, etc. -By convention, the Event "pair" of Location and Item typically have the same name, though this is not a requirement. -They must not exist in the `name_to_id` lookups, as they have no ID. - -The most common way to create an Event pair is to create and place the Item on the Location as soon as it's created: - -```python -from worlds.AutoWorld import World -from BaseClasses import ItemClassification -from .subclasses import MyGameLocation, MyGameItem - - -class MyGameWorld(World): - victory_loc = MyGameLocation(self.player, "Victory", None) - victory_loc.place_locked_item(MyGameItem("Victory", ItemClassification.progression, None, self.player)) -``` - ### Regions Regions are logical containers that typically hold locations that share some common access rules. If location logic is @@ -339,6 +314,63 @@ avoiding the need for indirect conditions at the expense of performance. An item rule is a function that returns `True` or `False` for a `Location` based on a single item. It can be used to reject the placement of an item there. +### Events (or "generation-only items/locations") + +An event item or location is one that only exists during multiworld generation; the server is never made aware of them. +Event locations can never be checked by the player, and event items cannot be received during play. + +Events are used to represent in-game actions (that aren't regular Archipelago locations) when either: + +* We want to show in the spoiler log when the player is expected to perform the in-game action. +* It's the cleanest way to represent how that in-game action impacts logic. + +Typical examples include completing the goal, defeating a boss, or flipping a switch that affects multiple areas. + +To be precise: the term "event" on its own refers to the special combination of an "event item" placed on an "event +location". Event items and locations are created the same way as normal items and locations, except that they have an +`id` of `None`, and an event item must be placed on an event location +(and vice versa). Finally, although events are often described as "fake" items and locations, it's important to +understand that they are perfectly real during generation. + +The most common way to create an event is to create the event item and the event location, then immediately call +`Location.place_locked_item()`: + +```python +victory_loc = MyGameLocation(self.player, "Defeat the Final Boss", None, final_boss_arena_region) +victory_loc.place_locked_item(MyGameItem("Victory", ItemClassification.progression, None, self.player)) +self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) +set_rule(victory_loc, lambda state: state.has("Boss Defeating Sword", self.player)) +``` + +Requiring an event to finish the game will make the spoiler log display an additional +`Defeat the Final Boss: Victory` line when the player is expected to finish, rather than only showing their last +relevant item. But events aren't just about the spoiler log; a more substantial example of using events to structure +your logic might be: + +```python +water_loc = MyGameLocation(self.player, "Water Level Switch", None, pump_station_region) +water_loc.place_locked_item(MyGameItem("Lowered Water Level", ItemClassification.progression, None, self.player)) +pump_station_region.locations.append(water_loc) +set_rule(water_loc, lambda state: state.has("Double Jump", self.player)) # the switch is really high up +... +basement_loc = MyGameLocation(self.player, "Flooded House - Basement Chest", None, flooded_house_region) +flooded_house_region.locations += [upstairs_loc, ground_floor_loc, basement_loc] +... +set_rule(basement_loc, lambda state: state.has("Lowered Water Level", self.player)) +``` + +This creates a "Lowered Water Level" event and a regular location whose access rule depends on that +event being reachable. If you made several more locations the same way, this would ensure all of those locations can +only become reachable when the event location is reachable (i.e. when the water level can be lowered), without +copy-pasting the event location's access rule and then repeatedly re-evaluating it. Also, the spoiler log will show +`Water Level Switch: Lowered Water Level` when the player is expected to do this. + +To be clear, this example could also be modeled with a second Region (perhaps "Un-Flooded House"). Or you could modify +the game so flipping that switch checks a regular AP location in addition to lowering the water level. +Events are never required, but it may be cleaner to use an event if e.g. flipping that switch affects the logic in +dozens of half-flooded areas that would all otherwise need additional Regions, and you don't want it to be a regular +location. It depends on the game. + ## Implementation ### Your World @@ -488,8 +520,8 @@ In addition, the following methods can be implemented and are called in this ord If it's hard to separate, this can be done during `generate_early` or `create_items` as well. * `create_items(self)` called to place player's items into the MultiWorld's itempool. By the end of this step all regions, locations and - items have to be in the MultiWorld's regions and itempool. You cannot add or remove items, locations, or regions - after this step. Locations cannot be moved to different regions after this step. + items have to be in the MultiWorld's regions and itempool. You cannot add or remove items, locations, or regions after + this step. Locations cannot be moved to different regions after this step. This includes event items and locations. * `set_rules(self)` called to set access and item rules on locations and entrances. * `connect_entrances(self)` From 47bf6d724b20bb8455f360cc2ddecf82bfcf445c Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 16 Jun 2025 10:56:47 -0400 Subject: [PATCH 0525/1218] Minecraft Removal Cleanup (#5118) --- WebHostLib/static/assets/minecraftTracker.js | 49 -------------------- worlds/ladx/LADXR/patches/marin.txt | 2 - 2 files changed, 51 deletions(-) delete mode 100644 WebHostLib/static/assets/minecraftTracker.js diff --git a/WebHostLib/static/assets/minecraftTracker.js b/WebHostLib/static/assets/minecraftTracker.js deleted file mode 100644 index a698214b8dd6..000000000000 --- a/WebHostLib/static/assets/minecraftTracker.js +++ /dev/null @@ -1,49 +0,0 @@ -window.addEventListener('load', () => { - // Reload tracker every 15 seconds - const url = window.location; - setInterval(() => { - const ajax = new XMLHttpRequest(); - ajax.onreadystatechange = () => { - if (ajax.readyState !== 4) { return; } - - // Create a fake DOM using the returned HTML - const domParser = new DOMParser(); - const fakeDOM = domParser.parseFromString(ajax.responseText, 'text/html'); - - // Update item tracker - document.getElementById('inventory-table').innerHTML = fakeDOM.getElementById('inventory-table').innerHTML; - // Update only counters in the location-table - let counters = document.getElementsByClassName('counter'); - const fakeCounters = fakeDOM.getElementsByClassName('counter'); - for (let i = 0; i < counters.length; i++) { - counters[i].innerHTML = fakeCounters[i].innerHTML; - } - }; - ajax.open('GET', url); - ajax.send(); - }, 15000) - - // Collapsible advancement sections - const categories = document.getElementsByClassName("location-category"); - for (let i = 0; i < categories.length; i++) { - let hide_id = categories[i].id.split('-')[0]; - if (hide_id == 'Total') { - continue; - } - categories[i].addEventListener('click', function() { - // Toggle the advancement list - document.getElementById(hide_id).classList.toggle("hide"); - // Change text of the header - const tab_header = document.getElementById(hide_id+'-header').children[0]; - const orig_text = tab_header.innerHTML; - let new_text; - if (orig_text.includes("▼")) { - new_text = orig_text.replace("▼", "▲"); - } - else { - new_text = orig_text.replace("▲", "▼"); - } - tab_header.innerHTML = new_text; - }); - } -}); diff --git a/worlds/ladx/LADXR/patches/marin.txt b/worlds/ladx/LADXR/patches/marin.txt index 3634014afe23..a179e35fc6fb 100644 --- a/worlds/ladx/LADXR/patches/marin.txt +++ b/worlds/ladx/LADXR/patches/marin.txt @@ -220,7 +220,6 @@ To this day I still don't know if we inconvenienced the Mad Batter or not. Oh, hi ##### People forgot I was playable in Hyrule Warriors Join our Discord. Or else. -Also try Minecraft! I see you're finally awake... OwO This is Todd Howard, and today I'm pleased to announce... The Elder Scrolls V: Skyrim for the Nintendo Game Boy Color! @@ -281,7 +280,6 @@ Try Mario & Luigi Superstar Saga! Try MegaMan Battle Network 3! Try Meritous! Try The Messenger! -Try Minecraft! Try Muse Dash! Try Noita! Try Ocarina of Time! From 6f244c4661a7aee59f452f61a51e61adb3f856d5 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Mon, 16 Jun 2025 12:54:08 -0400 Subject: [PATCH 0526/1218] Docs: Update Plando Guide and Make it More User Friendly (#4858) * Make plando guide more user friendly. * Apply suggestions from code review Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Further updates for review. * Clear search box when filtering by type. * Forget previous commit name - more code review updates to doc. * Move link to yaml tutorial. * Replace STS example with Pokemon RB. * Use non-key item examples in RB. * Rooby's code review updates. * Update worlds/generic/docs/plando_en.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/generic/docs/plando_en.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Address some more feedback. * Make Factorio example more accurate. * Exempt's code review updates (round 4) * Exempt's code review updates (round 4 + 1) * Update worlds/generic/docs/plando_en.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/generic/docs/plando_en.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/generic/docs/plando_en.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/generic/docs/plando_en.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/generic/docs/plando_en.md | 250 +++++++++++++++++++------------ 1 file changed, 158 insertions(+), 92 deletions(-) diff --git a/worlds/generic/docs/plando_en.md b/worlds/generic/docs/plando_en.md index b383239d8d11..69f59c739eda 100644 --- a/worlds/generic/docs/plando_en.md +++ b/worlds/generic/docs/plando_en.md @@ -27,73 +27,176 @@ requires: plando: bosses, items, texts, connections ``` +For a basic understanding of YAML files, refer to +[YAML Formatting](/tutorial/Archipelago/advanced_settings/en#yaml-formatting) +in Advanced Settings. + ## Item Plando -Item plando allows a player to place an item in a specific location or specific locations, or place multiple items into a -list of specific locations both in their own game or in another player's game. - -* The options for item plando are `from_pool`, `world`, `percentage`, `force`, `count`, and either `item` and - `location`, or `items` and `locations`. - * `from_pool` determines if the item should be taken *from* the item pool or *added* to it. This can be true or - false and defaults to true if omitted. - * `world` is the target world to place the item in. - * It gets ignored if only one world is generated. - * Can be a number, name, true, false, null, or a list. False is the default. - * If a number is used, it targets that slot or player number in the multiworld. - * If a name is used, it will target the world with that player name. - * If set to true, it will be any player's world besides your own. - * If set to false, it will target your own world. - * If set to null, it will target a random world in the multiworld. - * If a list of names is used, it will target the games with the player names specified. - * `force` determines whether the generator will fail if the item can't be placed in the location. Can be true, false, - or silent. Silent is the default. - * If set to true, the item must be placed and the generator will throw an error if it is unable to do so. - * If set to false, the generator will log a warning if the placement can't be done but will still generate. - * If set to silent and the placement fails, it will be ignored entirely. - * `percentage` is the percentage chance for the relevant block to trigger. This can be any value from 0 to 100 and - if omitted will default to 100. - * Single Placement is when you use a plando block to place a single item at a single location. - * `item` is the item you would like to place and `location` is the location to place it. - * Multi Placement uses a plando block to place multiple items in multiple locations until either list is exhausted. - * `items` defines the items to use, each with a number for the amount. Using `true` instead of a number uses however many of that item are in your item pool. - * `locations` is a list of possible locations those items can be placed in. - * Some special location group names can be specified: - * `early_locations` will add all sphere 1 locations (locations logically reachable only with your starting inventory) - * `non_early_locations` will add all locations beyond sphere 1 (locations that require finding at least one item before they become logically reachable) - * Using the multi placement method, placements are picked randomly. - - * `count` can be used to set the maximum number of items placed from the block. The default is 1 if using `item` and False if using `items` - * If a number is used, it will try to place this number of items. - * If set to false, it will try to place as many items from the block as it can. - * If `min` and `max` are defined, it will try to place a number of items between these two numbers at random. +Item Plando allows a player to place an item in a specific location or locations, or place multiple items into a list +of specific locations in their own game and/or in another player's game. + +To add item plando to your player yaml, you add them under the `plando_items` block. You should start with `item` if you +want to do Single Placement, or `items` if you want to do Multi Placement. A list of items can still be defined under +`item` but only one of them will be chosen at random to be used. + +After you define `item/items`, you would define `location` or `locations`, depending on if you want to fill one +location or many. Note that both `location` and `locations` are optional. A list of locations can still be defined under +`location` but only one of them will be chosen at random to be used. + +You may do any combination of `item/items` and `location/locations` in a plando block, but the block only places items +in locations **until the shorter of the two lists is used up.** + +Once you are satisfied with your first block, you may continue to define ones under the same `plando_items` parent. +Each block can have several different options to tailor it the way you like. + +* The `items` section defines the items to use. Each item name can be followed by a colon and a value. + * A numerical value indicates the amount of that item. + * A `true` value uses all copies of that item that are in your item pool. + +* The `item` section defines a list of items to use, from which one will be chosen at random. Each item name can be + followed by a colon and a value. The value indicates the weight of that item being chosen. + +* The `locations` section defines possible locations those items can be placed in. Two special location groups exist: + * `early_locations` will add all sphere 1 locations (locations logically reachable only with your starting + inventory). + * `non_early_locations` will add all locations beyond sphere 1 (locations that require finding at least one item + before they become logically reachable). + +* `from_pool` determines if the item should be taken *from* the item pool or *created* from scratch. + * `false`: Create a new item with the same name (the world will determine its properties e.g. classification). + * `true`: Take the existing item, if it exists, from the item pool. If it does not exist, one will be created from + scratch. **(Default)** + +* `world` is the target world to place the item in. It gets ignored if only one world is generated. + * **A number:** Use this slot or player number in the multiworld. + * **A name:** Use the world with that player name. + * **A list of names:** Use the worlds with the player names specified. + * `true`: Locations will be in any player's world besides your own. + * `false`: Locations will be in your own world. **(Default)** + * `null`: Locations will be in a random world in the multiworld. + +* `force` determines whether the generator will fail if the plando block cannot be fulfilled. + * `true`: The generator will throw an error if it is unable to place an item. + * `false`: The generator will log a warning if it is unable to place an item, but it will still generate. + * `silent`: If the placement fails, it will be ignored entirely. **(Default)** + +* `percentage` is the percentage chance for the block to trigger. This can be any integer from 0 to 100. + **(Default: 100)** + +* `count` sets the number of items placed from the list. + * **Default: 1 if using `item` or `location`, and `false` otherwise.** + * **A number:** It will place this number of items. + * `false`: It will place as many items from the list as it can. + * **If `min` is defined,** it will place at least `min` many items (can be combined with `max`). + * **If `max` is defined,** it will place at most `max` many items (can be combined with `min`). ### Available Items and Locations -A list of all available items and locations can be found in the [website's datapackage](/datapackage). The items and locations will be in the `"item_name_to_id"` and `"location_name_to_id"` sections of the relevant game. You do not need the quotes but the name must be entered in the same as it appears on that page and is case-sensitive. +A list of all available items and locations can be found in the [website's datapackage](/datapackage). The items and +locations will be in the `"item_name_to_id"` and `"location_name_to_id"` sections of the relevant game. Names are +case-sensitive. You can also use item groups and location groups that are defined in the datapackage. -### Examples +## Item Plando Examples +```yaml + plando_items: + # Example block - Pokémon Red and Blue + - items: + Potion: 3 + locations: + - "Route 1 - Free Sample Man" + - "Mt Moon 1F - West Item" + - "Mt Moon 1F - South Item" +``` +This block will lock 3 Potion items on the Route 1 Pokémart employee and 2 Mt Moon items. Note these are all +Potions in the vanilla game. The world value has not been specified, so these locations must be in this player's own +world by default. + +```yaml + plando_items: + # Example block - A Link to the Past + - items: + Progressive Sword: 4 + world: + - BobsWitness + - BobsRogueLegacy + count: + min: 1 + max: 4 +``` +This block will attempt to place a random number, between 1 and 4, of Progressive Swords into any locations within the +game slots named "BobsWitness" and "BobsRogueLegacy." ```yaml plando_items: - # example block 1 - Timespinner + # Example block - Secret of Evermore + - items: + Levitate: 1 + Revealer: 1 + Energize: 1 + locations: + - Master Sword Pedestal + - Desert Discard + world: true + count: 2 +``` +This block will choose 2 from the Levitate, Revealer, and Energize items at random and attempt to put them into the +locations named "Master Sword Pedestal" and "Desert Discard". Because the world value is `true`, these locations +must be in other players' worlds. + +```yaml + plando_items: + # Example block - Timespinner - item: Empire Orb: 1 - Radiant Orb: 1 + Radiant Orb: 3 location: Starter Chest 1 - from_pool: true + from_pool: false world: true percentage: 50 - - # example block 2 - Ocarina of Time +``` +This block will place a single item, either the Empire Orb or Radiant Orb, on the location "Starter Chest 1". There is +a 25% chance it is Empire Orb, and 75% chance it is Radiant Orb (1 to 3 odds). The world value is `true`, so this +location must be in another player's world. Because the from_pool value is `false`, a copy of these items is added to +these locations, while the originals remain in the item pool to be shuffled. Unlike the previous examples, which will +always trigger, this block only has a 50% chance to trigger. + +```yaml + plando_items: + # Example block - Factorio + - items: + progressive-electric-energy-distribution: 2 + electric-energy-accumulators: 1 + progressive-turret: 2 + locations: + - AP-1-001 + - AP-1-002 + - AP-1-003 + - AP-1-004 + percentage: 80 + force: true + from_pool: true + world: false +``` +This block lists 5 items but only 4 locations, so it will place all but 1 of the items randomly among the locations +chosen here. This block has an 80% chance of occurring. Because force is `true`, the Generator will fail if it cannot +place one of the selected items (not including the fifth item). From_pool and World have been set to their default +values here, but they can be omitted and have the same result: items will be removed from the pool, and the locations +are in this player's own world. + +**NOTE:** Factorio's locations are dynamically generated, so the locations listed above may not exist in your game, +they are here for demonstration only. + +```yaml + plando_items: + # Example block - Ocarina of Time - items: - Kokiri Sword: 1 Biggoron Sword: 1 Bow: 1 Magic Meter: 1 Progressive Strength Upgrade: 3 Progressive Hookshot: 2 locations: - - Deku Tree Slingshot Chest - Dodongos Cavern Bomb Bag Chest - Jabu Jabus Belly Boomerang Chest - Bottom of the Well Lens of Truth Chest @@ -102,53 +205,16 @@ A list of all available items and locations can be found in the [website's datap - Water Temple Longshot Chest - Shadow Temple Hover Boots Chest - Spirit Temple Silver Gauntlets Chest - world: false - - # example block 3 - Factorio - - items: - progressive-electric-energy-distribution: 2 - electric-energy-accumulators: 1 - progressive-turret: 2 - locations: - - military - - gun-turret - - logistic-science-pack - - steel-processing - percentage: 80 - force: true - - # example block 4 - Secret of Evermore - - items: - Levitate: 1 - Revealer: 1 - Energize: 1 - locations: - - Master Sword Pedestal - - Boss Relic 1 - world: true - count: 2 - - # example block 5 - A Link to the Past - - items: - Progressive Sword: 4 - world: - - BobsSlaytheSpire - - BobsRogueLegacy - count: - min: 1 - max: 4 + from_pool: false + + - item: Kokiri Sword + location: Deku Tree Slingshot Chest + from_pool: false ``` -1. This block has a 50% chance to occur, and if it does, it will place either the Empire Orb or Radiant Orb on another -player's Starter Chest 1 and removes the chosen item from the item pool. -2. This block will always trigger and will place the player's swords, bow, magic meter, strength upgrades, and hookshots -in their own dungeon major item chests. -3. This block has an 80% chance of occurring, and when it does, it will place all but 1 of the items randomly among the -four locations chosen here. -4. This block will always trigger and will attempt to place a random 2 of Levitate, Revealer and Energize into -other players' Master Sword Pedestals or Boss Relic 1 locations. -5. This block will always trigger and will attempt to place a random number, between 1 and 4, of progressive swords -into any locations within the game slots named BobsSlaytheSpire and BobsRogueLegacy. - +The first block will place the player's Biggoron Sword, Bow, Magic Meter, strength upgrades, and hookshots in the +dungeon major item chests. Because the from_pool value is `false`, a copy of these items is added to these locations, +while the originals remain in the item pool to be shuffled. The second block will place the Kokiri Sword in the Deku +Tree Slingshot Chest, again not from the pool. ## Boss Plando From 211456242e0e018bd3356ecca5325862fb654f2d Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Mon, 16 Jun 2025 12:00:47 -0500 Subject: [PATCH 0527/1218] KDL3: update to gifting protocol 3 and update settings usage (#4814) * gift version 3 * update settings usage * that really has just been broken this entire time * remove unnecessary print * Update client.py * fix random flavor handling * fix incorrect sender/receiver --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/kdl3/client.py | 45 +++---- worlds/kdl3/gifting.py | 275 +++++++++++++++++++++-------------------- worlds/kdl3/options.py | 8 +- worlds/kdl3/rom.py | 8 +- 4 files changed, 168 insertions(+), 168 deletions(-) diff --git a/worlds/kdl3/client.py b/worlds/kdl3/client.py index 97bf68cbd99a..78a43239b4d6 100644 --- a/worlds/kdl3/client.py +++ b/worlds/kdl3/client.py @@ -90,7 +90,7 @@ def cmd_gift(self: "SNIClientCommandProcessor") -> None: async_start(update_object(self.ctx, f"Giftboxes;{self.ctx.team}", { f"{self.ctx.slot}": { - "IsOpen": handler.gifting, + "is_open": handler.gifting, **kdl3_gifting_options } })) @@ -175,11 +175,11 @@ async def pop_gift(self, ctx: "SNIContext") -> None: key, gift = ctx.stored_data[self.giftbox_key].popitem() await pop_object(ctx, self.giftbox_key, key) # first, special cases - traits = [trait["Trait"] for trait in gift["Traits"]] + traits = [trait["trait"] for trait in gift["traits"]] if "Candy" in traits or "Invincible" in traits: # apply invincibility candy self.item_queue.append(0x43) - elif "Tomato" in traits or "tomato" in gift["ItemName"].lower(): + elif "Tomato" in traits or "tomato" in gift["item_name"].lower(): # apply maxim tomato # only want tomatos here, no other vegetable is that good self.item_queue.append(0x42) @@ -187,7 +187,7 @@ async def pop_gift(self, ctx: "SNIContext") -> None: # Apply 1-Up self.item_queue.append(0x41) elif "Currency" in traits or "Star" in traits: - value = gift["ItemValue"] + value = gift.get("item_value", 1) if value >= 50000: self.item_queue.append(0x46) elif value >= 30000: @@ -210,8 +210,8 @@ async def pop_gift(self, ctx: "SNIContext") -> None: # check if it's tasty if any(x in traits for x in ["Consumable", "Food", "Drink", "Heal", "Health"]): # it's tasty!, use quality to decide how much to heal - quality = max((trait["Quality"] for trait in gift["Traits"] - if trait["Trait"] in ["Consumable", "Food", "Drink", "Heal", "Health"])) + quality = max((trait.get("quality", 1.0) for trait in gift["traits"] + if trait["trait"] in ["Consumable", "Food", "Drink", "Heal", "Health"])) quality = min(10, quality * 2) else: # it's not really edible, but he'll eat it anyway @@ -236,23 +236,23 @@ async def pick_gift_recipient(self, ctx: "SNIContext", gift: int) -> None: for slot, info in ctx.stored_data[self.motherbox_key].items(): if int(slot) == ctx.slot and len(ctx.stored_data[self.motherbox_key]) > 1: continue - desire = len(set(info["DesiredTraits"]).intersection([trait["Trait"] for trait in gift_base["Traits"]])) + desire = len(set(info["desired_traits"]).intersection([trait["trait"] for trait in gift_base["traits"]])) if desire > most_applicable: most_applicable = desire most_applicable_slot = int(slot) - elif most_applicable_slot != ctx.slot and most_applicable == -1 and info["AcceptsAnyGift"]: + elif most_applicable_slot == ctx.slot and most_applicable == -1 and info["accepts_any_gift"]: # only send to ourselves if no one else will take it most_applicable_slot = int(slot) # print(most_applicable, most_applicable_slot) item_uuid = uuid.uuid4().hex item = { **gift_base, - "ID": item_uuid, - "Sender": ctx.player_names[ctx.slot], - "Receiver": ctx.player_names[most_applicable_slot], - "SenderTeam": ctx.team, - "ReceiverTeam": ctx.team, # for the moment - "IsRefund": False + "id": item_uuid, + "sender_slot": ctx.slot, + "receiver_slot": most_applicable_slot, + "sender_team": ctx.team, + "receiver_team": ctx.team, # for the moment + "is_refund": False } # print(item) await update_object(ctx, f"Giftbox;{ctx.team};{most_applicable_slot}", { @@ -276,8 +276,9 @@ async def game_watcher(self, ctx: "SNIContext") -> None: if not self.initialize_gifting: self.giftbox_key = f"Giftbox;{ctx.team};{ctx.slot}" self.motherbox_key = f"Giftboxes;{ctx.team}" - enable_gifting = await snes_read(ctx, KDL3_GIFTING_FLAG, 0x01) - await initialize_giftboxes(ctx, self.giftbox_key, self.motherbox_key, bool(enable_gifting[0])) + enable_gifting = await snes_read(ctx, KDL3_GIFTING_FLAG, 0x02) + await initialize_giftboxes(ctx, self.giftbox_key, self.motherbox_key, + bool(int.from_bytes(enable_gifting, "little"))) self.initialize_gifting = True # can't check debug anymore, without going and copying the value. might be important later. if not self.levels: @@ -350,19 +351,19 @@ async def game_watcher(self, ctx: "SNIContext") -> None: self.item_queue.append(item_idx | 0x80) # handle gifts here - gifting_status = await snes_read(ctx, KDL3_GIFTING_FLAG, 0x01) - if hasattr(ctx, "gifting") and ctx.gifting: - if gifting_status[0]: + gifting_status = int.from_bytes(await snes_read(ctx, KDL3_GIFTING_FLAG, 0x02), "little") + if hasattr(self, "gifting") and self.gifting: + if gifting_status: gift = await snes_read(ctx, KDL3_GIFTING_SEND, 0x01) if gift[0]: # we have a gift to send await self.pick_gift_recipient(ctx, gift[0]) snes_buffered_write(ctx, KDL3_GIFTING_SEND, bytes([0x00])) else: - snes_buffered_write(ctx, KDL3_GIFTING_FLAG, bytes([0x01])) + snes_buffered_write(ctx, KDL3_GIFTING_FLAG, bytes([0x01, 0x00])) else: - if gifting_status[0]: - snes_buffered_write(ctx, KDL3_GIFTING_FLAG, bytes([0x00])) + if gifting_status: + snes_buffered_write(ctx, KDL3_GIFTING_FLAG, bytes([0x00, 0x00])) await snes_flush_writes(ctx) diff --git a/worlds/kdl3/gifting.py b/worlds/kdl3/gifting.py index e1626091000e..de1551487404 100644 --- a/worlds/kdl3/gifting.py +++ b/worlds/kdl3/gifting.py @@ -37,157 +37,158 @@ async def initialize_giftboxes(ctx: "SNIContext", giftbox_key: str, motherbox_ke ctx.set_notify(motherbox_key, giftbox_key) await update_object(ctx, f"Giftboxes;{ctx.team}", {f"{ctx.slot}": { - "IsOpen": is_open, + "is_open": is_open, **kdl3_gifting_options }}) + await update_object(ctx, f"Giftbox;{ctx.team};{ctx.slot}", {}) ctx.client_handler.gifting = is_open kdl3_gifting_options = { - "AcceptsAnyGift": True, - "DesiredTraits": [ + "accepts_any_gift": True, + "desired_traits": [ "Consumable", "Food", "Drink", "Candy", "Tomato", "Invincible", "Life", "Heal", "Health", "Trap", "Goo", "Gel", "Slow", "Slowness", "Eject", "Removal" ], - "MinimumGiftVersion": 2, + "minimum_gift_version": 3, } kdl3_gifts = { 1: { - "ItemName": "1-Up", - "Amount": 1, - "ItemValue": 400000, - "Traits": [ + "item_name": "1-Up", + "amount": 1, + "item_value": 400000, + "traits": [ { - "Trait": "Consumable", - "Quality": 1, - "Duration": 1, + "trait": "Consumable", + "quality": 1, + "duration": 1, }, { - "Trait": "Life", - "Quality": 1, - "Duration": 1 + "trait": "Life", + "quality": 1, + "duration": 1 } ] }, 2: { - "ItemName": "Maxim Tomato", - "Amount": 1, - "ItemValue": 500000, - "Traits": [ + "item_name": "Maxim Tomato", + "amount": 1, + "item_value": 500000, + "traits": [ { - "Trait": "Consumable", - "Quality": 5, - "Duration": 1, + "trait": "Consumable", + "quality": 5, + "duration": 1, }, { - "Trait": "Heal", - "Quality": 5, - "Duration": 1, + "trait": "Heal", + "quality": 5, + "duration": 1, }, { - "Trait": "Food", - "Quality": 5, - "Duration": 1, + "trait": "Food", + "quality": 5, + "duration": 1, }, { - "Trait": "Tomato", - "Quality": 5, - "Duration": 1, + "trait": "Tomato", + "quality": 5, + "duration": 1, }, { - "Trait": "Vegetable", - "Quality": 5, - "Duration": 1, + "trait": "Vegetable", + "quality": 5, + "duration": 1, } ] }, 3: { - "ItemName": "Energy Drink", - "Amount": 1, - "ItemValue": 100000, - "Traits": [ + "item_name": "Energy Drink", + "amount": 1, + "item_value": 100000, + "traits": [ { - "Trait": "Consumable", - "Quality": 1, - "Duration": 1, + "trait": "Consumable", + "quality": 1, + "duration": 1, }, { - "Trait": "Heal", - "Quality": 1, - "Duration": 1, + "trait": "Heal", + "quality": 1, + "duration": 1, }, { - "Trait": "Drink", - "Quality": 1, - "Duration": 1, + "trait": "Drink", + "quality": 1, + "duration": 1, }, ] }, 5: { - "ItemName": "Small Star Piece", - "Amount": 1, - "ItemValue": 10000, - "Traits": [ + "item_name": "Small Star Piece", + "amount": 1, + "item_value": 10000, + "traits": [ { - "Trait": "Currency", - "Quality": 1, - "Duration": 1, + "trait": "Currency", + "quality": 1, + "duration": 1, }, { - "Trait": "Money", - "Quality": 1, - "Duration": 1, + "trait": "Money", + "quality": 1, + "duration": 1, }, { - "Trait": "Star", - "Quality": 1, - "Duration": 1 + "trait": "Star", + "quality": 1, + "duration": 1 } ] }, 6: { - "ItemName": "Medium Star Piece", - "Amount": 1, - "ItemValue": 30000, - "Traits": [ + "item_name": "Medium Star Piece", + "amount": 1, + "item_value": 30000, + "traits": [ { - "Trait": "Currency", - "Quality": 3, - "Duration": 1, + "trait": "Currency", + "quality": 3, + "duration": 1, }, { - "Trait": "Money", - "Quality": 3, - "Duration": 1, + "trait": "Money", + "quality": 3, + "duration": 1, }, { - "Trait": "Star", - "Quality": 3, - "Duration": 1 + "trait": "Star", + "quality": 3, + "duration": 1 } ] }, 7: { - "ItemName": "Large Star Piece", - "Amount": 1, - "ItemValue": 50000, - "Traits": [ + "item_name": "Large Star Piece", + "amount": 1, + "item_value": 50000, + "traits": [ { - "Trait": "Currency", - "Quality": 5, - "Duration": 1, + "trait": "Currency", + "quality": 5, + "duration": 1, }, { - "Trait": "Money", - "Quality": 5, - "Duration": 1, + "trait": "Money", + "quality": 5, + "duration": 1, }, { - "Trait": "Star", - "Quality": 5, - "Duration": 1 + "trait": "Star", + "quality": 5, + "duration": 1 } ] }, @@ -195,90 +196,90 @@ async def initialize_giftboxes(ctx: "SNIContext", giftbox_key: str, motherbox_ke kdl3_trap_gifts = { 0: { - "ItemName": "Gooey Bag", - "Amount": 1, - "ItemValue": 10000, - "Traits": [ + "item_name": "Gooey Bag", + "amount": 1, + "item_value": 10000, + "traits": [ { - "Trait": "Trap", - "Quality": 1, - "Duration": 1, + "trait": "Trap", + "quality": 1, + "duration": 1, }, { - "Trait": "Goo", - "Quality": 1, - "Duration": 1, + "trait": "Goo", + "quality": 1, + "duration": 1, }, { - "Trait": "Gel", - "Quality": 1, - "Duration": 1 + "trait": "Gel", + "quality": 1, + "duration": 1 } ] }, 1: { - "ItemName": "Slowness", - "Amount": 1, - "ItemValue": 10000, - "Traits": [ + "item_name": "Slowness", + "amount": 1, + "item_value": 10000, + "traits": [ { - "Trait": "Trap", - "Quality": 1, - "Duration": 1, + "trait": "Trap", + "quality": 1, + "duration": 1, }, { - "Trait": "Slow", - "Quality": 1, - "Duration": 1, + "trait": "Slow", + "quality": 1, + "duration": 1, }, { - "Trait": "Slowness", - "Quality": 1, - "Duration": 1 + "trait": "Slowness", + "quality": 1, + "duration": 1 } ] }, 2: { - "ItemName": "Eject Ability", - "Amount": 1, - "ItemValue": 10000, - "Traits": [ + "item_name": "Eject Ability", + "amount": 1, + "item_value": 10000, + "traits": [ { - "Trait": "Trap", - "Quality": 1, - "Duration": 1, + "trait": "Trap", + "quality": 1, + "duration": 1, }, { - "Trait": "Eject", - "Quality": 1, - "Duration": 1, + "trait": "Eject", + "quality": 1, + "duration": 1, }, { - "Trait": "Removal", - "Quality": 1, - "Duration": 1 + "trait": "Removal", + "quality": 1, + "duration": 1 } ] }, 3: { - "ItemName": "Bad Meal", - "Amount": 1, - "ItemValue": 10000, - "Traits": [ + "item_name": "Bad Meal", + "amount": 1, + "item_value": 10000, + "traits": [ { - "Trait": "Trap", - "Quality": 1, - "Duration": 1, + "trait": "Trap", + "quality": 1, + "duration": 1, }, { - "Trait": "Damage", - "Quality": 1, - "Duration": 1, + "trait": "Damage", + "quality": 1, + "duration": 1, }, { - "Trait": "Food", - "Quality": 1, - "Duration": 1 + "trait": "Food", + "quality": 1, + "duration": 1 } ] }, diff --git a/worlds/kdl3/options.py b/worlds/kdl3/options.py index b9163794ad19..77095bfec68b 100644 --- a/worlds/kdl3/options.py +++ b/worlds/kdl3/options.py @@ -289,7 +289,7 @@ class KirbyFlavorPreset(Choice): option_lime = 12 option_lavender = 13 option_miku = 14 - option_custom = 15 + option_custom = -1 default = 0 @classmethod @@ -297,7 +297,7 @@ def from_text(cls, text: str) -> Choice: text = text.lower() if text == "random": choice_list = list(cls.name_lookup) - choice_list.remove(14) + choice_list.remove(-1) return cls(random.choice(choice_list)) return super().from_text(text) @@ -347,7 +347,7 @@ class GooeyFlavorPreset(Choice): option_orange = 11 option_lime = 12 option_lavender = 13 - option_custom = 14 + option_custom = -1 default = 0 @classmethod @@ -355,7 +355,7 @@ def from_text(cls, text: str) -> Choice: text = text.lower() if text == "random": choice_list = list(cls.name_lookup) - choice_list.remove(14) + choice_list.remove(-1) return cls(random.choice(choice_list)) return super().from_text(text) diff --git a/worlds/kdl3/rom.py b/worlds/kdl3/rom.py index 741ea0083027..5f986bc4be0c 100644 --- a/worlds/kdl3/rom.py +++ b/worlds/kdl3/rom.py @@ -7,7 +7,6 @@ import os import struct -import settings from worlds.Files import APProcedurePatch, APTokenMixin, APTokenTypes, APPatchExtension from .aesthetics import get_palette_bytes, kirby_target_palettes, get_kirby_palette, gooey_target_palettes, \ get_gooey_palette @@ -475,8 +474,7 @@ def patch_rom(world: "KDL3World", patch: KDL3ProcedurePatch) -> None: patch.write_token(APTokenTypes.WRITE, 0x3D016, world.options.ow_boss_requirement.value.to_bytes(2, "little")) patch.write_token(APTokenTypes.WRITE, 0x3D018, world.options.consumables.value.to_bytes(2, "little")) patch.write_token(APTokenTypes.WRITE, 0x3D01A, world.options.starsanity.value.to_bytes(2, "little")) - patch.write_token(APTokenTypes.WRITE, 0x3D01C, world.options.gifting.value.to_bytes(2, "little") - if world.multiworld.players > 1 else bytes([0, 0])) + patch.write_token(APTokenTypes.WRITE, 0x3D01C, world.options.gifting.value.to_bytes(2, "little")) patch.write_token(APTokenTypes.WRITE, 0x3D01E, world.options.strict_bosses.value.to_bytes(2, "little")) # don't write gifting for solo game, since there's no one to send anything to @@ -594,9 +592,9 @@ def get_base_rom_bytes() -> bytes: def get_base_rom_path(file_name: str = "") -> str: - options: settings.Settings = settings.get_settings() + from . import KDL3World if not file_name: - file_name = options["kdl3_options"]["rom_file"] + file_name = KDL3World.settings.rom_file if not os.path.exists(file_name): file_name = Utils.user_path(file_name) return file_name From 4eefd9c3ceff76d35091895308f3097c16c0c6ca Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 19 Jun 2025 06:39:26 -0500 Subject: [PATCH 0528/1218] Kivy: swap from the tab carousel to navigation bar (#4930) * implement tabs as NavigationBar * update the underline bar with the screen manager * remove some unneeded kv * remove the underline in favor of a full tab highlight * fix insert transitions * use on_release instead of on_press * minor cleanup * add remove_client_tab and add a caller to the NavigationBar for back compat * unused imports * Update kvui.py --------- Co-authored-by: Silvris <58583688+Silvris@users.noreply.github.com> Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- data/client.kv | 17 ++++- kvui.py | 176 +++++++++++++++++++++++++++---------------------- 2 files changed, 113 insertions(+), 80 deletions(-) diff --git a/data/client.kv b/data/client.kv index 53000dfe41f2..ed63df135d24 100644 --- a/data/client.kv +++ b/data/client.kv @@ -24,9 +24,20 @@ : ripple_color: app.theme_cls.primaryColor ripple_duration_in_fast: 0.2 -: - ripple_color: app.theme_cls.primaryColor - ripple_duration_in_fast: 0.2 +: + on_release: app.screens.switch_screens(self) + + MDNavigationItemLabel: + text: root.text + theme_text_color: "Custom" + text_color_active: self.theme_cls.primaryColor + text_color_normal: 1, 1, 1, 1 + # indicator is on icon only for some reason + canvas.before: + Color: + rgba: self.theme_cls.secondaryContainerColor if root.active else self.theme_cls.transparentColor + Rectangle: + size: root.size : adaptive_height: True theme_font_size: "Custom" diff --git a/kvui.py b/kvui.py index 172b7e554394..2f45831200bc 100644 --- a/kvui.py +++ b/kvui.py @@ -60,7 +60,10 @@ from kivymd.uix.gridlayout import MDGridLayout from kivymd.uix.floatlayout import MDFloatLayout from kivymd.uix.boxlayout import MDBoxLayout -from kivymd.uix.tab.tab import MDTabsSecondary, MDTabsItem, MDTabsItemText, MDTabsCarousel +from kivymd.uix.navigationbar import MDNavigationBar, MDNavigationItem +from kivymd.uix.screen import MDScreen +from kivymd.uix.screenmanager import MDScreenManager + from kivymd.uix.menu import MDDropdownMenu from kivymd.uix.menu.menu import MDDropdownTextItem from kivymd.uix.dropdownitem import MDDropDownItem, MDDropDownItemText @@ -726,6 +729,10 @@ def __init__(self, title, text, error=False, **kwargs): self.height += max(0, label.height - 18) +class MDNavigationItemBase(MDNavigationItem): + text = StringProperty(None) + + class ButtonsPrompt(MDDialog): def __init__(self, title: str, text: str, response: typing.Callable[[str], None], *prompts: str, **kwargs) -> None: @@ -766,58 +773,34 @@ def on_release(button: MDButton, *args) -> None: ) -class ClientTabs(MDTabsSecondary): - carousel: MDTabsCarousel - lock_swiping = True - - def __init__(self, *args, **kwargs): - self.carousel = MDTabsCarousel(lock_swiping=True, anim_move_duration=0.2) - super().__init__(*args, MDDivider(size_hint_y=None, height=dp(1)), self.carousel, **kwargs) - self.size_hint_y = 1 - - def _check_panel_height(self, *args): - self.ids.tab_scroll.height = dp(38) - - def update_indicator( - self, x: float = 0.0, w: float = 0.0, instance: MDTabsItem = None - ) -> None: - def update_indicator(*args): - indicator_pos = (0, 0) - indicator_size = (0, 0) - - item_text_object = self._get_tab_item_text_icon_object() - - if item_text_object: - indicator_pos = ( - instance.x + dp(12), - self.indicator.pos[1] - if not self._tabs_carousel - else self._tabs_carousel.height, - ) - indicator_size = ( - instance.width - dp(24), - self.indicator_height, - ) +class MDScreenManagerBase(MDScreenManager): + current_tab: MDNavigationItemBase + local_screen_names: list[str] - Animation( - pos=indicator_pos, - size=indicator_size, - d=0 if not self.indicator_anim else self.indicator_duration, - t=self.indicator_transition, - ).start(self.indicator) + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.local_screen_names = [] - if not instance: - self.indicator.pos = (x, self.indicator.pos[1]) - self.indicator.size = (w, self.indicator_height) + def add_widget(self, widget: Widget, *args, **kwargs) -> None: + super().add_widget(widget, *args, **kwargs) + if "index" in kwargs: + self.local_screen_names.insert(kwargs["index"], widget.name) else: - Clock.schedule_once(update_indicator) + self.local_screen_names.append(widget.name) + + def switch_screens(self, new_tab: MDNavigationItemBase) -> None: + """ + Called whenever the user clicks a tab to switch to a different screen. - def remove_tab(self, tab, content=None): - if content is None: - content = tab.content - self.ids.container.remove_widget(tab) - self.carousel.remove_widget(content) - self.on_size(self, self.size) + :param new_tab: The new screen to switch to's tab. + """ + name = new_tab.text + if self.local_screen_names.index(name) > self.local_screen_names.index(self.current_screen.name): + self.transition.direction = "left" + else: + self.transition.direction = "right" + self.current = name + self.current_tab = new_tab class CommandButton(MDButton, MDTooltip): @@ -845,6 +828,9 @@ class GameManager(ThemedApp): main_area_container: MDGridLayout """ subclasses can add more columns beside the tabs """ + tabs: MDNavigationBar + screens: MDScreenManagerBase + def __init__(self, ctx: context_type): self.title = self.base_title self.ctx = ctx @@ -874,7 +860,7 @@ def intercept_say(text): @property def tab_count(self): if hasattr(self, "tabs"): - return max(1, len(self.tabs.tab_list)) + return max(1, len(self.tabs.children)) return 1 def on_start(self): @@ -914,30 +900,30 @@ def connect_bar_validate(sender): self.grid.add_widget(self.progressbar) # middle part - self.tabs = ClientTabs(pos_hint={"center_x": 0.5, "center_y": 0.5}) - self.tabs.add_widget(MDTabsItem(MDTabsItemText(text="All" if len(self.logging_pairs) > 1 else "Archipelago"))) - self.log_panels["All"] = self.tabs.default_tab_content = UILog(*(logging.getLogger(logger_name) - for logger_name, name in - self.logging_pairs)) - self.tabs.carousel.add_widget(self.tabs.default_tab_content) + self.screens = MDScreenManagerBase(pos_hint={"center_x": 0.5}) + self.tabs = MDNavigationBar(orientation="horizontal", size_hint_y=None, height=dp(40), set_bars_color=True) + # bind the method to the bar for back compatibility + self.tabs.remove_tab = self.remove_client_tab + self.screens.current_tab = self.add_client_tab( + "All" if len(self.logging_pairs) > 1 else "Archipelago", + UILog(*(logging.getLogger(logger_name) for logger_name, name in self.logging_pairs)), + ) + self.log_panels["All"] = self.screens.current_tab.content + self.screens.current_tab.active = True for logger_name, display_name in self.logging_pairs: bridge_logger = logging.getLogger(logger_name) self.log_panels[display_name] = UILog(bridge_logger) if len(self.logging_pairs) > 1: - panel = MDTabsItem(MDTabsItemText(text=display_name)) - panel.content = self.log_panels[display_name] - # show Archipelago tab if other logging is present - self.tabs.carousel.add_widget(panel.content) - self.tabs.add_widget(panel) + self.add_client_tab(display_name, self.log_panels[display_name]) - hint_panel = self.add_client_tab("Hints", HintLayout()) self.hint_log = HintLog(self.json_to_kivy_parser) + hint_panel = self.add_client_tab("Hints", HintLayout(self.hint_log)) self.log_panels["Hints"] = hint_panel.content - hint_panel.content.add_widget(self.hint_log) - self.main_area_container = MDGridLayout(size_hint_y=1, rows=1) + self.main_area_container = MDGridLayout(size_hint_y=1, cols=1) self.main_area_container.add_widget(self.tabs) + self.main_area_container.add_widget(self.screens) self.grid.add_widget(self.main_area_container) @@ -974,25 +960,61 @@ def connect_bar_validate(sender): return self.container - def add_client_tab(self, title: str, content: Widget, index: int = -1) -> Widget: - """Adds a new tab to the client window with a given title, and provides a given Widget as its content. - Returns the new tab widget, with the provided content being placed on the tab as content.""" - new_tab = MDTabsItem(MDTabsItemText(text=title)) + def add_client_tab(self, title: str, content: Widget, index: int = -1) -> MDNavigationItemBase: + """ + Adds a new tab to the client window with a given title, and provides a given Widget as its content. + Returns the new tab widget, with the provided content being placed on the tab as content. + + :param title: The title of the tab. + :param content: The Widget to be added as content for this tab's new MDScreen. Will also be added to the + returned tab as tab.content. + :param index: The index to insert the tab at. Defaults to -1, meaning the tab will be appended to the end. + + :return: The new tab. + """ + if self.tabs.children: + self.tabs.add_widget(MDDivider(orientation="vertical")) + new_tab = MDNavigationItemBase(text=title) new_tab.content = content - if -1 < index <= len(self.tabs.carousel.slides): - new_tab.bind(on_release=self.tabs.set_active_item) - new_tab._tabs = self.tabs - self.tabs.ids.container.add_widget(new_tab, index=index) - self.tabs.carousel.add_widget(new_tab.content, index=len(self.tabs.carousel.slides) - index) + new_screen = MDScreen(name=title) + new_screen.add_widget(content) + if -1 < index <= len(self.tabs.children): + remapped_index = len(self.tabs.children) - index + self.tabs.add_widget(new_tab, index=remapped_index) + self.screens.add_widget(new_screen, index=index) else: self.tabs.add_widget(new_tab) - self.tabs.carousel.add_widget(new_tab.content) + self.screens.add_widget(new_screen) return new_tab + def remove_client_tab(self, tab: MDNavigationItemBase) -> None: + """ + Called to remove a tab and its screen. + + :param tab: The tab to remove. + """ + tab_index = self.tabs.children.index(tab) + # if the tab is currently active we need to swap before removing it + if tab == self.screens.current_tab: + if not tab_index: + # account for the divider + swap_index = tab_index + 2 + else: + swap_index = tab_index - 2 + self.tabs.children[swap_index].on_release() + # self.screens.switch_screens(self.tabs.children[swap_index]) + # get the divider to the left if we can + if not tab_index: + divider_index = tab_index + 1 + else: + divider_index = tab_index - 1 + self.tabs.remove_widget(self.tabs.children[divider_index]) + self.tabs.remove_widget(tab) + self.screens.remove_widget(self.screens.get_screen(tab.text)) + def update_texts(self, dt): - for slide in self.tabs.carousel.slides: - if hasattr(slide, "fix_heights"): - slide.fix_heights() # TODO: remove this when Kivy fixes this upstream + if hasattr(self.screens.current_tab.content, "fix_heights"): + getattr(self.screens.current_tab.content, "fix_heights")() if self.ctx.server: self.title = self.base_title + " " + Utils.__version__ + \ f" | Connected to: {self.ctx.server_address} " \ From c2666bacd791e70a555e7d7fe1a35818b54c0905 Mon Sep 17 00:00:00 2001 From: Katelyn Gigante Date: Fri, 20 Jun 2025 02:05:52 +1000 Subject: [PATCH 0529/1218] core: Don't attempt to write to the inside of an OSX App Bundle (#4380) * core: Frozen OSX should also use Home Directory * Use Application Support instead of homedir * Suggested changes --- Utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Utils.py b/Utils.py index f20389055008..84d3a33dc76f 100644 --- a/Utils.py +++ b/Utils.py @@ -166,6 +166,10 @@ def home_path(*path: str) -> str: os.symlink(home_path.cached_path, legacy_home_path) else: os.makedirs(home_path.cached_path, 0o700, exist_ok=True) + elif sys.platform == 'darwin': + import platformdirs + home_path.cached_path = platformdirs.user_data_dir("Archipelago", False) + os.makedirs(home_path.cached_path, 0o700, exist_ok=True) else: # not implemented home_path.cached_path = local_path() # this will generate the same exceptions we got previously @@ -177,7 +181,7 @@ def user_path(*path: str) -> str: """Returns either local_path or home_path based on write permissions.""" if hasattr(user_path, "cached_path"): pass - elif os.access(local_path(), os.W_OK): + elif os.access(local_path(), os.W_OK) and not (is_macos and is_frozen()): user_path.cached_path = local_path() else: user_path.cached_path = home_path() From e0ae3359f130e85f8c3a0d22dcdd315635d7cb5c Mon Sep 17 00:00:00 2001 From: palex00 <32203971+palex00@users.noreply.github.com> Date: Fri, 20 Jun 2025 20:55:49 +0200 Subject: [PATCH 0530/1218] =?UTF-8?q?Pok=C3=A9mon=20RB:=20Use=20new=20link?= =?UTF-8?q?=20for=20a=20new=20tracker=20(#5122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update setup_en.md * Update setup_es.md --- worlds/pokemon_rb/docs/setup_en.md | 4 ++-- worlds/pokemon_rb/docs/setup_es.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/worlds/pokemon_rb/docs/setup_en.md b/worlds/pokemon_rb/docs/setup_en.md index 773fb14da9e7..7e05c8c782d0 100644 --- a/worlds/pokemon_rb/docs/setup_en.md +++ b/worlds/pokemon_rb/docs/setup_en.md @@ -15,7 +15,7 @@ As we are using BizHawk, this guide is only applicable to Windows and Linux syst ## Optional Software -- [Pokémon Red and Blue Archipelago Map Tracker](https://github.com/coveleski/rb_tracker/releases/latest), for use with [PopTracker](https://github.com/black-sliver/PopTracker/releases) +- [Pokémon Red and Blue Archipelago Map Tracker](https://github.com/palex00/rb_tracker/releases/latest), for use with [PopTracker](https://github.com/black-sliver/PopTracker/releases) ## Configuring BizHawk @@ -109,7 +109,7 @@ server uses password, type in the bottom textfield `/connect
    : [p Pokémon Red and Blue has a fully functional map tracker that supports auto-tracking. -1. Download [Pokémon Red and Blue Archipelago Map Tracker](https://github.com/coveleski/rb_tracker/releases/latest) and [PopTracker](https://github.com/black-sliver/PopTracker/releases). +1. Download [Pokémon Red and Blue Archipelago Map Tracker](https://github.com/palex00/rb_tracker/releases/latest) and [PopTracker](https://github.com/black-sliver/PopTracker/releases). 2. Open PopTracker, and load the Pokémon Red and Blue pack. 3. Click on the "AP" symbol at the top. 4. Enter the AP address, slot name and password. diff --git a/worlds/pokemon_rb/docs/setup_es.md b/worlds/pokemon_rb/docs/setup_es.md index 67024c5b52ec..5c735bfe992a 100644 --- a/worlds/pokemon_rb/docs/setup_es.md +++ b/worlds/pokemon_rb/docs/setup_es.md @@ -16,7 +16,7 @@ Al usar BizHawk, esta guía solo es aplicable en los sistemas de Windows y Linux ## Software Opcional -- [Tracker de mapa para Pokémon Red and Blue Archipelago](https://github.com/coveleski/rb_tracker/releases/latest), para usar con [PopTracker](https://github.com/black-sliver/PopTracker/releases) +- [Tracker de mapa para Pokémon Red and Blue Archipelago](https://github.com/palex00/rb_tracker/releases/latest), para usar con [PopTracker](https://github.com/black-sliver/PopTracker/releases) ## Configurando BizHawk @@ -114,7 +114,7 @@ presiona enter (si el servidor usa contraseña, escribe en el campo de texto inf Pokémon Red and Blue tiene un mapa completamente funcional que soporta seguimiento automático. -1. Descarga el [Tracker de mapa para Pokémon Red and Blue Archipelago](https://github.com/coveleski/rb_tracker/releases/latest) y [PopTracker](https://github.com/black-sliver/PopTracker/releases). +1. Descarga el [Tracker de mapa para Pokémon Red and Blue Archipelago](https://github.com/palex00/rb_tracker/releases/latest) y [PopTracker](https://github.com/black-sliver/PopTracker/releases). 2. Abre PopTracker, y carga el pack de Pokémon Red and Blue. 3. Haz clic en el símbolo "AP" en la parte superior. 4. Ingresa la dirección de AP, nombre del slot y contraseña (si es que hay). From c34e29c7124a1b66d9e68f0a747780cd8254d61a Mon Sep 17 00:00:00 2001 From: James White Date: Fri, 20 Jun 2025 21:52:54 +0100 Subject: [PATCH 0531/1218] Pokemon RB: Client: Send bounce messages with current map ID (#5121) --- worlds/pokemon_rb/client.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/worlds/pokemon_rb/client.py b/worlds/pokemon_rb/client.py index 97ca126476fd..2eb56f539840 100644 --- a/worlds/pokemon_rb/client.py +++ b/worlds/pokemon_rb/client.py @@ -23,6 +23,7 @@ "DexSanityFlag": (0x1A71, 19), "GameStatus": (0x1A84, 0x01), "Money": (0x141F, 3), + "CurrentMap": (0x1436, 1), "ResetCheck": (0x0100, 4), # First and second Vermilion Gym trash can selection. Second is not used, so should always be 0. # First should never be above 0x0F. This is just before Event Flags. @@ -65,6 +66,7 @@ def __init__(self): self.banking_command = None self.game_state = False self.last_death_link = 0 + self.current_map = 0 async def validate_rom(self, ctx): game_name = await read(ctx.bizhawk_ctx, [(0x134, 12, "ROM")]) @@ -230,6 +232,10 @@ async def game_watcher(self, ctx): }]) self.banking_command = None + if data["CurrentMap"][0] != self.current_map: + await ctx.send_msgs([{"cmd": "Bounce", "slots": [ctx.slot], "data": {"currentMap": data["CurrentMap"][0]}}]) + self.current_map = data["CurrentMap"][0] + # VICTORY if data["EventFlag"][280] & 1 and not ctx.finished_game: From 00f862528083fec98af71a1c8b94120c99469ff1 Mon Sep 17 00:00:00 2001 From: DJ-lennart Date: Sat, 21 Jun 2025 16:31:12 +0200 Subject: [PATCH 0532/1218] Civilization VI: Updated setup and info pages (#5123) * Update setup_en.md Updated setup instructions for Civilization VI in Archipelago * Update en_Civilization VI.md Updated info page for Civilization VI in Archipelago * Update setup_en.md --- worlds/civ_6/docs/en_Civilization VI.md | 13 ++++----- worlds/civ_6/docs/setup_en.md | 35 +++++++++++++++---------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/worlds/civ_6/docs/en_Civilization VI.md b/worlds/civ_6/docs/en_Civilization VI.md index 215da00aa4fb..2a5f5fbd7399 100644 --- a/worlds/civ_6/docs/en_Civilization VI.md +++ b/worlds/civ_6/docs/en_Civilization VI.md @@ -20,16 +20,17 @@ A short period after receiving an item, you will get a notification indicating y ## FAQs - Do I need the DLC to play this? - - Yes, you need both Rise & Fall and Gathering Storm. + - You need both expansions, Rise & Fall and Gathering Storm. You do not need the other DLCs but they fully work with this. - Does this work with Multiplayer? - It does not and, despite my best efforts, probably won't until there's a new way for external programs to be able to interact with the game. -- Does my mod that reskins Barbarians as various Pro Wrestlers work with this? - - Only one way to find out! Any mods that modify techs/civics will most likely cause issues, though. +- Does this work with other mods? + - A lot of mods seem to work without issues combined with this, but you should avoid any mods that change things in the tech or civic tree, as even if they would work it could cause issues with the logic. - "Help! I can't see any of the items that have been sent to me!" - Both trees by default will show you the researchable Archipelago locations. To view the normal tree, you can click "Toggle Archipelago Tree" in the top-left corner of the tree view. - "Oh no! I received the Machinery tech and now instead of getting an Archer next turn, I have to wait an additional 10 turns to get a Crossbowman!" - Vanilla prevents you from building units of the same class from an earlier tech level after you have researched a later variant. For example, this could be problematic if someone unlocks Crossbowmen for you right out the gate since you won't be able to make Archers (which have a much lower production cost). -Solution: You can now go in to the tech tree, click "Toggle Archipelago Tree" to view your unlocked techs, and then can click any tech you have unlocked to toggle whether it is currently active or not. + - Solution: You can now go in to the tech tree, click "Toggle Archipelago Tree" to view your unlocked techs, and then can click any tech you have unlocked to toggle whether it is currently active or not. + - If you think you should be able to make Field Cannons but seemingly can't try disabling `Telecommunications` - "How does DeathLink work? Am I going to have to start a new game every time one of my friends dies?" - Heavens no, my fellow Archipelago appreciator. When configuring your Archipelago options for Civilization on the options page, there are several choices available for you to fine tune the way you'd like to be punished for the follies of your friends. These include: Having a random unit destroyed, losing a percentage of gold or faith, or even losing a point on your era score. If you can't make up your mind, you can elect to have any of them be selected every time a death link is sent your way. In the event you lose one of your units in combat (this means captured units don't count), then you will send a death link event to the rest of your friends. @@ -39,7 +40,8 @@ Solution: You can now go in to the tech tree, click "Toggle Archipelago Tree" to 1. `TECH_WRITING` 2. `TECH_EDUCATION` 3. `TECH_CHEMISTRY` - - If you want to see the details around each item, you can review [this file](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/civ_6/data/progressive_districts.json). + - An important thing to note is that the seaport is part of progressive industrial zones, due to electricity having both an industrial zone building and the seaport. + - If you want to see the details around each item, you can review [this file](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/civ_6/data/progressive_districts.py). ## Boostsanity Boostsanity takes all of the Eureka & Inspiration events and makes them location checks. This feature is the one to change up the way Civilization is played in an AP multiworld/randomizer. What normally are mundane tasks that are passively collected now become a novel and interesting bucket list that you need to pay attention to in order to unlock items for yourself and others! @@ -56,4 +58,3 @@ Boosts have logic associated with them in order to verify you can always reach t - The unpredictable timing of boosts and unlocking them can occasionally lead to scenarios where you'll have to first encounter a locked era defeat and then load a previous save. To help reduce the frequency of this, local `PROGRESSIVE_ERA` items will never be located at a boost check. - There's too many boosts, how will I know which one's I should focus on?! - In order to give a little more focus to all the boosts rather than just arbitrarily picking them at random, items in both of the vanilla trees will now have an advisor icon on them if its associated boost contains a progression item. - diff --git a/worlds/civ_6/docs/setup_en.md b/worlds/civ_6/docs/setup_en.md index 9cf4744b6596..fb8404190ff1 100644 --- a/worlds/civ_6/docs/setup_en.md +++ b/worlds/civ_6/docs/setup_en.md @@ -6,12 +6,14 @@ This guide is meant to help you get up and running with Civilization VI in Archi The following are required in order to play Civ VI in Archipelago: -- Windows OS (Firaxis does not support the necessary tooling for Mac, or Linux) +- Windows OS (Firaxis does not support the necessary tooling for Mac, or Linux). -- Installed [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) v0.4.5 or higher. +- Installed [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases). - The latest version of the [Civ VI AP Mod](https://github.com/hesto2/civilization_archipelago_mod/releases/latest). +- A copy of the game `Civilization VI` including the two expansions `Rise & Fall` and `Gathering Storm` (both the Steam and Epic version should work). + ## Enabling the tuner In the main menu, navigate to the "Game Options" page. On the "Game" menu, make sure that "Tuner (disables achievements)" is enabled. @@ -20,27 +22,32 @@ In the main menu, navigate to the "Game Options" page. On the "Game" menu, make 1. Download and unzip the latest release of the mod from [GitHub](https://github.com/hesto2/civilization_archipelago_mod/releases/latest). -2. Copy the folder containing the mod files to your Civ VI mods folder. On Windows, this is usually located at `C:\Users\YOUR_USER\Documents\My Games\Sid Meier's Civilization VI\Mods`. If you use OneDrive, check if the folder is instead located in your OneDrive file structure. +2. Copy the folder containing the mod files to your Civ VI mods folder. On Windows, this is usually located at `C:\Users\YOUR_USER\Documents\My Games\Sid Meier's Civilization VI\Mods`. If you use OneDrive, check if the folder is instead located in your OneDrive file structure, and use that path when relevant in future steps. 3. After the Archipelago host generates a game, you should be given a `.apcivvi` file. Associate the file with the Archipelago Launcher and double click it. -4. Copy the contents of the new folder it generates (it will have the same name as the `.apcivvi` file) into your Civilization VI Archipelago Mod folder. If double clicking the `.apcivvi` file doesn't generate a folder, you can just rename it to a file ending with `.zip` and extract its contents to a new folder. To do this, right click the `.apcivvi` file and click "Rename", make sure it ends in `.zip`, then right click it again and select "Extract All". - -5. Your finished mod folder should look something like this: +4. Copy the contents of the new folder it generates (it will have the same name as the `.apcivvi` file) into your Civilization VI Archipelago Mod folder. If double clicking the `.apcivvi` file doesn't generate a folder, you can instead open it as a zip file. You can do this by either right clicking it and opening it with a program that handles zip files, or by right clicking and renaming the file extension from `apcivvi` to `zip`. -- Civ VI Mods Directory - - civilization_archipelago_mod - - NewItems.xml - - InitOptions.lua - - Archipelago.modinfo - - All the other mod files, etc. +5. Place the files generated from the `.apcivvi` in your archipelago mod folder (there should be five files placed there from the apcivvi file, overwrite if asked). Your mod path should look something like `C:\Users\YOUR_USER\Documents\My Games\Sid Meier's Civilization VI\Mods\civilization_archipelago_mod`. ## Configuring your game -When configuring your game, make sure to start the game in the Ancient Era and leave all settings related to starting technologies and civics as the defaults. Other than that, configure difficulty, AI, etc. as you normally would. +Make sure you enable the mod in the main title under Additional Content > Mods. When configuring your game, make sure to start the game in the Ancient Era and leave all settings related to starting technologies and civics as the defaults. Other than that, configure difficulty, AI, etc. as you normally would. ## Troubleshooting +- If you have troubles with file extension related stuff, make sure Windows shows file extensions as they are turned off by default. If you don't know how to turn them on it is just a quick google search away. + - If you are getting an error: "The remote computer refused the network connection", or something else related to the client (or tuner) not being able to connect, it likely indicates the tuner is not actually enabled. One simple way to verify that it is enabled is, after completing the setup steps, go to Main Menu → Options → Look for an option named "Tuner" and verify it is set to "Enabled" -- If your game gets in a state where someone has sent you items or you have sent locations but these are not correctly sent to the multiworld, you can run `/resync` from the Civ 6 client. This may take up to a minute depending on how many items there are. +- If your game gets in a state where someone has sent you items or you have sent locations but these are not correctly sent to the multiworld, you can run `/resync` from the Civ 6 client. This may take up to a minute depending on how many items there are. This can resend certain items to you, like one time bonuses. + +- If the archipelago mod does not appear in the mod selector in the game, make sure the mod is correctly placed as a folder in the `Sid Meier's Civilization VI\Mods` folder, there should not be any loose files in there only folders. As in the path should look something like `C:\Users\YOUR_USER\Documents\My Games\Sid Meier's Civilization VI\Mods\civilization_archipelago_mod`. + +- If it still does not appear make sure you have the right folder, one way to verify you are in the right place is to find the general folder area where your Civ VI save files are located. + +- If you get an error when trying to start a game saying `Error - One or more Mods failed to load content`, make sure the files from the `.apcivvi` are placed into the `civilization_archipelago_mod` as loose files and not as a folder. + +- If you still have any errors make sure the two expansions Rise & Fall and Gathering Storm are active in the mod selector (all the official DLC works without issues but Rise & Fall and Gathering Storm are required for the mod). + +- If boostsanity is enabled and those items are not being sent out but regular techs are, make sure you placed the files from your new room in the mod folder. From 21864f6f950d752b3fb8c0411517f5b442708ac4 Mon Sep 17 00:00:00 2001 From: LiquidCat64 <74896918+LiquidCat64@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:25:45 -0600 Subject: [PATCH 0533/1218] CVCotM: Fix Advance Collection ROM (#5132) --- worlds/cvcotm/aesthetics.py | 4 ++-- worlds/cvcotm/data/patches.py | 24 ++++++++++++------------ worlds/cvcotm/rom.py | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/worlds/cvcotm/aesthetics.py b/worlds/cvcotm/aesthetics.py index d52165d076a1..86134f8e0954 100644 --- a/worlds/cvcotm/aesthetics.py +++ b/worlds/cvcotm/aesthetics.py @@ -734,8 +734,8 @@ def get_start_inventory_data(world: "CVCotMWorld") -> Tuple[Dict[int, bytes], bo magic_items_array[array_offset] += 1 # Add the start inventory arrays to the offset data in bytes form. - start_inventory_data[0x680080] = bytes(magic_items_array) - start_inventory_data[0x6800A0] = bytes(cards_array) + start_inventory_data[0x690080] = bytes(magic_items_array) + start_inventory_data[0x6900A0] = bytes(cards_array) # Add the extra max HP/MP/Hearts to all classes' base stats. Doing it this way makes us less likely to hit the max # possible Max Ups. diff --git a/worlds/cvcotm/data/patches.py b/worlds/cvcotm/data/patches.py index c2a9aa791f91..37fba3bd40e3 100644 --- a/worlds/cvcotm/data/patches.py +++ b/worlds/cvcotm/data/patches.py @@ -132,40 +132,40 @@ # Magic Items 0x13, 0x48, # ldr r0, =0x202572F - 0x14, 0x49, # ldr r1, =0x8680080 + 0x14, 0x49, # ldr r1, =0x8690080 0x00, 0x22, # mov r2, #0 0x8B, 0x5C, # ldrb r3, [r1, r2] 0x83, 0x54, # strb r3, [r0, r2] 0x01, 0x32, # adds r2, #1 0x08, 0x2A, # cmp r2, #8 - 0xFA, 0xDB, # blt 0x8680006 + 0xFA, 0xDB, # blt 0x8690006 # Max Ups 0x11, 0x48, # ldr r0, =0x202572C - 0x12, 0x49, # ldr r1, =0x8680090 + 0x12, 0x49, # ldr r1, =0x8690090 0x00, 0x22, # mov r2, #0 0x8B, 0x5C, # ldrb r3, [r1, r2] 0x83, 0x54, # strb r3, [r0, r2] 0x01, 0x32, # adds r2, #1 0x03, 0x2A, # cmp r2, #3 - 0xFA, 0xDB, # blt 0x8680016 + 0xFA, 0xDB, # blt 0x8690016 # Cards 0x0F, 0x48, # ldr r0, =0x2025674 - 0x10, 0x49, # ldr r1, =0x86800A0 + 0x10, 0x49, # ldr r1, =0x86900A0 0x00, 0x22, # mov r2, #0 0x8B, 0x5C, # ldrb r3, [r1, r2] 0x83, 0x54, # strb r3, [r0, r2] 0x01, 0x32, # adds r2, #1 0x14, 0x2A, # cmp r2, #0x14 - 0xFA, 0xDB, # blt 0x8680026 + 0xFA, 0xDB, # blt 0x8690026 # Inventory Items (not currently supported) 0x0D, 0x48, # ldr r0, =0x20256ED - 0x0E, 0x49, # ldr r1, =0x86800C0 + 0x0E, 0x49, # ldr r1, =0x86900C0 0x00, 0x22, # mov r2, #0 0x8B, 0x5C, # ldrb r3, [r1, r2] 0x83, 0x54, # strb r3, [r0, r2] 0x01, 0x32, # adds r2, #1 0x36, 0x2A, # cmp r2, #36 - 0xFA, 0xDB, # blt 0x8680036 + 0xFA, 0xDB, # blt 0x8690036 # Return to the function that checks for Magician Mode. 0xBA, 0x21, # movs r1, #0xBA 0x89, 0x00, # lsls r1, r1, #2 @@ -176,13 +176,13 @@ # LDR number pool 0x78, 0x7F, 0x00, 0x08, 0x2F, 0x57, 0x02, 0x02, - 0x80, 0x00, 0x68, 0x08, + 0x80, 0x00, 0x69, 0x08, 0x2C, 0x57, 0x02, 0x02, - 0x90, 0x00, 0x68, 0x08, + 0x90, 0x00, 0x69, 0x08, 0x74, 0x56, 0x02, 0x02, - 0xA0, 0x00, 0x68, 0x08, + 0xA0, 0x00, 0x69, 0x08, 0xED, 0x56, 0x02, 0x02, - 0xC0, 0x00, 0x68, 0x08, + 0xC0, 0x00, 0x69, 0x08, ] max_max_up_checker = [ diff --git a/worlds/cvcotm/rom.py b/worlds/cvcotm/rom.py index 6ae0b6e43863..350829292b34 100644 --- a/worlds/cvcotm/rom.py +++ b/worlds/cvcotm/rom.py @@ -335,8 +335,8 @@ def apply_patches(caller: APProcedurePatch, rom: bytes, options_file: str) -> by rom_data.write_bytes(0x679A60, patches.kickless_roc_height_shortener) # Give the player their Start Inventory upon entering their name on a new file. - rom_data.write_bytes(0x7F70, [0x00, 0x48, 0x87, 0x46, 0x00, 0x00, 0x68, 0x08]) - rom_data.write_bytes(0x680000, patches.start_inventory_giver) + rom_data.write_bytes(0x7F70, [0x00, 0x48, 0x87, 0x46, 0x00, 0x00, 0x69, 0x08]) + rom_data.write_bytes(0x690000, patches.start_inventory_giver) # Prevent Max Ups from exceeding 255. rom_data.write_bytes(0x5E170, [0x00, 0x4A, 0x97, 0x46, 0x00, 0x00, 0x6A, 0x08]) From 52389731ebef8e0b516059c2597657690d99eeee Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Fri, 27 Jun 2025 18:46:00 -0400 Subject: [PATCH 0534/1218] TWW: Update Preset S7 to S8 (#5138) --- worlds/tww/Presets.py | 89 +++++++++++++++++++++++----- worlds/tww/docs/en_The Wind Waker.md | 9 +-- 2 files changed, 80 insertions(+), 18 deletions(-) diff --git a/worlds/tww/Presets.py b/worlds/tww/Presets.py index 286494262fdf..bc1477cb5384 100644 --- a/worlds/tww/Presets.py +++ b/worlds/tww/Presets.py @@ -1,61 +1,122 @@ from typing import Any tww_options_presets: dict[str, dict[str, Any]] = { - "Tournament S7": { + "Tournament S8": { "progression_dungeon_secrets": True, "progression_combat_secret_caves": True, "progression_short_sidequests": True, + "progression_long_sidequests": True, "progression_spoils_trading": True, "progression_big_octos_gunboats": True, "progression_mail": True, + "progression_platforms_rafts": True, + "progression_submarines": True, + "progression_big_octos_gunboats": True, + "progression_expensive_purchases": True, "progression_island_puzzles": True, "progression_misc": True, "randomize_mapcompass": "startwith", + "randomize_bigkeys": "startwith", "required_bosses": True, - "num_required_bosses": 3, + "num_required_bosses": 4, + "included_dungeons": ["Forsaken Fortress"], "chest_type_matches_contents": True, "logic_obscurity": "hard", + "randomize_dungeon_entrances": True, "randomize_starting_island": True, "add_shortcut_warps_between_dungeons": True, "start_inventory_from_pool": { "Telescope": 1, "Wind Waker": 1, - "Goddess Tingle Statue": 1, - "Earth Tingle Statue": 1, - "Wind Tingle Statue": 1, "Wind's Requiem": 1, "Ballad of Gales": 1, + "Command Melody": 1, "Earth God's Lyric": 1, "Wind God's Aria": 1, "Song of Passing": 1, - "Progressive Magic Meter": 2, + "Triforce Shard 1": 1, + "Triforce Shard 2": 1, + "Triforce Shard 3": 1, + "Skull Necklace": 20, + "Golden Feather": 20, + "Knight's Crest": 10, + "Green Chu Jelly": 15, + "Nayru's Pearl": 1, + "Din's Pearl": 1, }, - "start_location_hints": ["Ganon's Tower - Maze Chest"], + "start_location_hints": [ + "Windfall Island - Chu Jelly Juice Shop - Give 15 Blue Chu Jelly", + "Ganon's Tower - Maze Chest", + ], "exclude_locations": [ - "Outset Island - Orca - Give 10 Knight's Crests", "Outset Island - Great Fairy", - "Windfall Island - Chu Jelly Juice Shop - Give 15 Green Chu Jelly", + "Windfall Island - Mrs. Marie - Give 1 Joy Pendant", "Windfall Island - Mrs. Marie - Give 21 Joy Pendants", "Windfall Island - Mrs. Marie - Give 40 Joy Pendants", - "Windfall Island - Maggie's Father - Give 20 Skull Necklaces", - "Dragon Roost Island - Rito Aerie - Give Hoskit 20 Golden Feathers", + "Windfall Island - Lenzo's House - Become Lenzo's Assistant", + "Windfall Island - Lenzo's House - Bring Forest Firefly", + "Windfall Island - Sam - Decorate the Town", + "Windfall Island - Kamo - Full Moon Photo", + "Windfall Island - Linda and Anton", + "Dragon Roost Island - Secret Cave", + "Greatfish Isle - Hidden Chest", + "Mother and Child Isles - Inside Mother Isle", + "Fire Mountain - Cave - Chest", + "Fire Mountain - Lookout Platform Chest", + "Fire Mountain - Lookout Platform - Destroy the Cannons", "Fire Mountain - Big Octo", - "Mailbox - Letter from Hoskit's Girlfriend", + "Headstone Island - Top of the Island", + "Headstone Island - Submarine", + "Earth Temple - Behind Curtain Next to Hammer Button", + "The Great Sea - Goron Trading Reward", + "The Great Sea - Withered Trees", "Private Oasis - Big Octo", + "Boating Course - Raft", + "Boating Course - Cave", "Stone Watcher Island - Cave", + "Stone Watcher Island - Lookout Platform Chest", + "Stone Watcher Island - Lookout Platform - Destroy the Cannons", "Overlook Island - Cave", + "Bird's Peak Rock - Cave", + "Pawprint Isle - Wizzrobe Cave", "Thorned Fairy Island - Great Fairy", + "Thorned Fairy Island - Northeastern Lookout Platform - Destroy the Cannons", + "Thorned Fairy Island - Southwestern Lookout Platform - Defeat the Enemies", "Eastern Fairy Island - Great Fairy", + "Eastern Fairy Island - Lookout Platform - Defeat the Cannons and Enemies", "Western Fairy Island - Great Fairy", - "Southern Fairy Island - Great Fairy", - "Northern Fairy Island - Great Fairy", + "Western Fairy Island - Lookout Platform", + "Tingle Island - Ankle - Reward for All Tingle Statues", "Tingle Island - Big Octo", "Diamond Steppe Island - Big Octo", + "Rock Spire Isle - Cave", "Rock Spire Isle - Beedle's Special Shop Ship - 500 Rupee Item", "Rock Spire Isle - Beedle's Special Shop Ship - 950 Rupee Item", "Rock Spire Isle - Beedle's Special Shop Ship - 900 Rupee Item", + "Rock Spire Isle - Western Lookout Platform - Destroy the Cannons", + "Rock Spire Isle - Eastern Lookout Platform - Destroy the Cannons", + "Rock Spire Isle - Center Lookout Platform", + "Rock Spire Isle - Southeast Gunboat", "Shark Island - Cave", + "Horseshoe Island - Northwestern Lookout Platform", + "Horseshoe Island - Southeastern Lookout Platform", + "Flight Control Platform - Submarine", + "Star Island - Cave", + "Star Island - Lookout Platform", + "Star Belt Archipelago - Lookout Platform", + "Five-Star Isles - Lookout Platform - Destroy the Cannons", + "Five-Star Isles - Raft", + "Five-Star Isles - Submarine", + "Seven-Star Isles - Center Lookout Platform", + "Seven-Star Isles - Northern Lookout Platform", + "Seven-Star Isles - Southern Lookout Platform", "Seven-Star Isles - Big Octo", + "Cyclops Reef - Lookout Platform - Defeat the Enemies", + "Two-Eye Reef - Lookout Platform", + "Two-Eye Reef - Big Octo Great Fairy", + "Five-Eye Reef - Lookout Platform", + "Six-Eye Reef - Lookout Platform - Destroy the Cannons", + "Six-Eye Reef - Submarine", ], }, "Miniblins 2025": { diff --git a/worlds/tww/docs/en_The Wind Waker.md b/worlds/tww/docs/en_The Wind Waker.md index 0158366b3f08..a49c8d6697ae 100644 --- a/worlds/tww/docs/en_The Wind Waker.md +++ b/worlds/tww/docs/en_The Wind Waker.md @@ -76,10 +76,11 @@ at least normal. A few presets are available on the [player options page](../player-options) for your convenience. -- **Tournament S7**: These are (as close to as possible) the settings used in the WWR Racing Server's - [Season 7 Tournament](https://docs.google.com/document/d/1mJj7an-DvpYilwNt-DdlFOy1fz5_NMZaPZvHeIekplc). - The preset features 3 required bosses and hard obscurity difficulty, and while the list of enabled progression options - may seem intimidating, the preset also excludes several locations. +- **Tournament S8**: These are (as close to as possible) the settings used in the WWR Racing Server's + [Season 8 Tournament](https://docs.google.com/document/d/1b8F5DL3P5fgsQC_URiwhpMfqTpsGh2M-KmtTdXVigh4). + The preset features 4 required bosses (with Helmaroc King guaranteed required), dungeon entrance rando, hard obscurity + difficulty, and a variety of overworld checks. While the list of enabled progression options may seem intimidating, + the preset also excludes several locations and starts you with a handful of items. - **Miniblins 2025**: These are (as close to as possible) the settings used in the WWR Racing Server's [2025 Season of Miniblins](https://docs.google.com/document/d/19vT68eU6PepD2BD2ZjR9ikElfqs8pXfqQucZ-TcscV8). This preset is great if you're new to Wind Waker! There aren't too many locations in the world, and you only need to From da52598c0843922d02912a933aeb6aa23833587c Mon Sep 17 00:00:00 2001 From: Fly Hyping Date: Fri, 27 Jun 2025 19:42:35 -0400 Subject: [PATCH 0535/1218] Wargroove: Fix Communication Thread (#5125) --- worlds/wargroove/Client.py | 130 +++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 63 deletions(-) diff --git a/worlds/wargroove/Client.py b/worlds/wargroove/Client.py index 3dc5d6eb0ca9..0627c7e9f2df 100644 --- a/worlds/wargroove/Client.py +++ b/worlds/wargroove/Client.py @@ -496,70 +496,74 @@ def get_commanders(self) -> List[Tuple[CommanderData, bool]]: async def game_watcher(ctx: WargrooveContext): while not ctx.exit_event.is_set(): - if ctx.syncing == True: - sync_msg = [{'cmd': 'Sync'}] - if ctx.locations_checked: - sync_msg.append({"cmd": "LocationChecks", "locations": list(ctx.locations_checked)}) - await ctx.send_msgs(sync_msg) - ctx.syncing = False - sending = [] - victory = False - for root, dirs, files in os.walk(ctx.game_communication_path): - for file in files: - if file == "deathLinkSend" and ctx.has_death_link: - with open(os.path.join(ctx.game_communication_path, file), 'r') as f: - failed_mission = f.read() - if ctx.slot is not None: - await ctx.send_death(f"{ctx.player_names[ctx.slot]} failed {failed_mission}") - os.remove(os.path.join(ctx.game_communication_path, file)) - if file.find("send") > -1: - st = file.split("send", -1)[1] - sending = sending+[(int(st))] - os.remove(os.path.join(ctx.game_communication_path, file)) - if file.find("victory") > -1: - victory = True - os.remove(os.path.join(ctx.game_communication_path, file)) - if file == "unitSacrifice" or file == "unitSacrificeAI": - if ctx.has_sacrifice_summon: - stored_units_key = ctx.player_stored_units_key - if file == "unitSacrificeAI": - stored_units_key = ctx.ai_stored_units_key + try: + if ctx.syncing == True: + sync_msg = [{'cmd': 'Sync'}] + if ctx.locations_checked: + sync_msg.append({"cmd": "LocationChecks", "locations": list(ctx.locations_checked)}) + await ctx.send_msgs(sync_msg) + ctx.syncing = False + sending = [] + victory = False + for root, dirs, files in os.walk(ctx.game_communication_path): + for file in files: + if file == "deathLinkSend" and ctx.has_death_link: with open(os.path.join(ctx.game_communication_path, file), 'r') as f: - unit_class = f.read() - message = [{"cmd": 'Set', "key": stored_units_key, - "default": [], - "want_reply": True, - "operations": [{"operation": "add", "value": [unit_class[:64]]}]}] - await ctx.send_msgs(message) - os.remove(os.path.join(ctx.game_communication_path, file)) - if file == "unitSummonRequestAI" or file == "unitSummonRequest": - if ctx.has_sacrifice_summon: - stored_units_key = ctx.player_stored_units_key - if file == "unitSummonRequestAI": - stored_units_key = ctx.ai_stored_units_key - with open(os.path.join(ctx.game_communication_path, "unitSummonResponse"), 'w') as f: - if stored_units_key in ctx.stored_data: - stored_units = ctx.stored_data[stored_units_key] - if stored_units is None: - stored_units = [] - wg1_stored_units = [unit for unit in stored_units if unit in ctx.unit_classes] - if len(wg1_stored_units) != 0: - summoned_unit = random.choice(wg1_stored_units) - message = [{"cmd": 'Set', "key": stored_units_key, - "default": [], - "want_reply": True, - "operations": [{"operation": "remove", "value": summoned_unit[:64]}]}] - await ctx.send_msgs(message) - f.write(summoned_unit) - os.remove(os.path.join(ctx.game_communication_path, file)) - - ctx.locations_checked = sending - message = [{"cmd": 'LocationChecks', "locations": sending}] - await ctx.send_msgs(message) - if not ctx.finished_game and victory: - await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) - ctx.finished_game = True - await asyncio.sleep(0.1) + failed_mission = f.read() + if ctx.slot is not None: + await ctx.send_death(f"{ctx.player_names[ctx.slot]} failed {failed_mission}") + os.remove(os.path.join(ctx.game_communication_path, file)) + if file.find("send") > -1: + st = file.split("send", -1)[1] + sending = sending+[(int(st))] + os.remove(os.path.join(ctx.game_communication_path, file)) + if file.find("victory") > -1: + victory = True + os.remove(os.path.join(ctx.game_communication_path, file)) + if file == "unitSacrifice" or file == "unitSacrificeAI": + if ctx.has_sacrifice_summon: + stored_units_key = ctx.player_stored_units_key + if file == "unitSacrificeAI": + stored_units_key = ctx.ai_stored_units_key + with open(os.path.join(ctx.game_communication_path, file), 'r') as f: + unit_class = f.read() + message = [{"cmd": 'Set', "key": stored_units_key, + "default": [], + "want_reply": True, + "operations": [{"operation": "add", "value": [unit_class[:64]]}]}] + await ctx.send_msgs(message) + os.remove(os.path.join(ctx.game_communication_path, file)) + if file == "unitSummonRequestAI" or file == "unitSummonRequest": + if ctx.has_sacrifice_summon: + stored_units_key = ctx.player_stored_units_key + if file == "unitSummonRequestAI": + stored_units_key = ctx.ai_stored_units_key + with open(os.path.join(ctx.game_communication_path, "unitSummonResponse"), 'w') as f: + if stored_units_key in ctx.stored_data: + stored_units = ctx.stored_data[stored_units_key] + if stored_units is None: + stored_units = [] + wg1_stored_units = [unit for unit in stored_units if unit in ctx.unit_classes] + if len(wg1_stored_units) != 0: + summoned_unit = random.choice(wg1_stored_units) + message = [{"cmd": 'Set', "key": stored_units_key, + "default": [], + "want_reply": True, + "operations": [{"operation": "remove", "value": summoned_unit[:64]}]}] + await ctx.send_msgs(message) + f.write(summoned_unit) + os.remove(os.path.join(ctx.game_communication_path, file)) + + ctx.locations_checked = sending + message = [{"cmd": 'LocationChecks', "locations": sending}] + await ctx.send_msgs(message) + if not ctx.finished_game and victory: + await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) + ctx.finished_game = True + await asyncio.sleep(0.1) + + except Exception as err: + logger.warn("Exception in communication thread, a check may not have been sent: " + str(err)) def print_error_and_close(msg): From 03e5fd3dae5a27cddd9fd4d3134d2d19f8d7562b Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Sat, 28 Jun 2025 10:46:37 -0400 Subject: [PATCH 0536/1218] TWW: Fix Swords in Swordless Mode (#5137) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/tww/randomizers/ItemPool.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/worlds/tww/randomizers/ItemPool.py b/worlds/tww/randomizers/ItemPool.py index 679d1939dffe..e3d62fa97390 100644 --- a/worlds/tww/randomizers/ItemPool.py +++ b/worlds/tww/randomizers/ItemPool.py @@ -110,6 +110,14 @@ def get_pool_core(world: "TWWWorld") -> tuple[list[str], list[str]]: else: filler_pool.extend([item] * data.quantity) + # If the player starts with a sword, add one to the precollected items list and remove one from the item pool. + if world.options.sword_mode == "start_with_sword": + precollected_items.append("Progressive Sword") + progression_pool.remove("Progressive Sword") + # Or, if it's swordless mode, remove all swords from the item pool. + elif world.options.sword_mode == "swordless": + useful_pool = [item for item in useful_pool if item != "Progressive Sword"] + # Assign useful and filler items to item pools in the world. world.random.shuffle(useful_pool) world.random.shuffle(filler_pool) @@ -141,17 +149,6 @@ def get_pool_core(world: "TWWWorld") -> tuple[list[str], list[str]]: pool.extend(progression_pool) num_items_left_to_place -= len(progression_pool) - # If the player starts with a sword, add one to the precollected items list and remove one from the item pool. - if world.options.sword_mode == "start_with_sword": - precollected_items.append("Progressive Sword") - num_items_left_to_place += 1 - pool.remove("Progressive Sword") - # Or, if it's swordless mode, remove all swords from the item pool. - elif world.options.sword_mode == "swordless": - while "Progressive Sword" in pool: - num_items_left_to_place += 1 - pool.remove("Progressive Sword") - # Place useful items, then filler items to fill out the remaining locations. pool.extend([world.get_filler_item_name(strict=False) for _ in range(num_items_left_to_place)]) From 8aacc23882c25a276dc03d766c9c3d6d11d65c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sat, 28 Jun 2025 11:36:09 -0400 Subject: [PATCH 0537/1218] SDV: Add "Desert Transportation" and "Island Transportation" Item Groups (#5143) --- worlds/stardew_valley/data/items.csv | 8 ++++---- worlds/stardew_valley/items/item_data.py | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/worlds/stardew_valley/data/items.csv b/worlds/stardew_valley/data/items.csv index 11a22e952d07..f7dac9c5794e 100644 --- a/worlds/stardew_valley/data/items.csv +++ b/worlds/stardew_valley/data/items.csv @@ -6,7 +6,7 @@ id,name,classification,groups,mod_name 18,Greenhouse,progression,COMMUNITY_REWARD, 19,Glittering Boulder Removed,progression,COMMUNITY_REWARD, 20,Minecarts Repair,useful,COMMUNITY_REWARD, -21,Bus Repair,progression,COMMUNITY_REWARD, +21,Bus Repair,progression,"COMMUNITY_REWARD,DESERT_TRANSPORTATION", 22,Progressive Movie Theater,"progression,trap",COMMUNITY_REWARD, 23,Stardrop,progression,, 24,Progressive Backpack,progression,, @@ -63,8 +63,8 @@ id,name,classification,groups,mod_name 77,Combat Level,progression,SKILL_LEVEL_UP, 78,Earth Obelisk,progression,WIZARD_BUILDING, 79,Water Obelisk,progression,WIZARD_BUILDING, -80,Desert Obelisk,progression,WIZARD_BUILDING, -81,Island Obelisk,progression,"WIZARD_BUILDING,GINGER_ISLAND", +80,Desert Obelisk,progression,"WIZARD_BUILDING,DESERT_TRANSPORTATION", +81,Island Obelisk,progression,"WIZARD_BUILDING,GINGER_ISLAND,ISLAND_TRANSPORTATION", 82,Junimo Hut,useful,WIZARD_BUILDING, 83,Gold Clock,progression,WIZARD_BUILDING, 84,Progressive Coop,progression,BUILDING, @@ -242,7 +242,7 @@ id,name,classification,groups,mod_name 257,Peach Sapling,progression,"RESOURCE_PACK,RESOURCE_PACK_USEFUL,CROPSANITY", 258,Banana Sapling,progression,"GINGER_ISLAND,RESOURCE_PACK,RESOURCE_PACK_USEFUL,CROPSANITY", 259,Mango Sapling,progression,"GINGER_ISLAND,RESOURCE_PACK,RESOURCE_PACK_USEFUL,CROPSANITY", -260,Boat Repair,progression,GINGER_ISLAND, +260,Boat Repair,progression,"GINGER_ISLAND,ISLAND_TRANSPORTATION", 261,Open Professor Snail Cave,progression,GINGER_ISLAND, 262,Island North Turtle,progression,"GINGER_ISLAND,WALNUT_PURCHASE", 263,Island West Turtle,progression,"GINGER_ISLAND,WALNUT_PURCHASE", diff --git a/worlds/stardew_valley/items/item_data.py b/worlds/stardew_valley/items/item_data.py index e7c3779e275d..6abc96f4e626 100644 --- a/worlds/stardew_valley/items/item_data.py +++ b/worlds/stardew_valley/items/item_data.py @@ -33,6 +33,8 @@ class Group(enum.Enum): SKILL_MASTERY = enum.auto() BUILDING = enum.auto() WIZARD_BUILDING = enum.auto() + DESERT_TRANSPORTATION = enum.auto() + ISLAND_TRANSPORTATION = enum.auto() ARCADE_MACHINE_BUFFS = enum.auto() BASE_RESOURCE = enum.auto() WARP_TOTEM = enum.auto() From ba66ef14ccdac88b486d357f9e5dbefb0aced610 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Wed, 2 Jul 2025 08:14:35 -0400 Subject: [PATCH 0538/1218] Update world api.md (#5149) --- docs/world api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/world api.md b/docs/world api.md index 833d379bb238..2f3dd0e429f8 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -266,7 +266,7 @@ like entrance randomization in logic. Regions have a list called `exits`, containing `Entrance` objects representing transitions to other regions. -There must be one special region (Called "Menu" by default, but configurable using [origin_region_name](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/AutoWorld.py#L298-L299)), +There must be one special region (Called "Menu" by default, but configurable using [origin_region_name](https://github.com/ArchipelagoMW/Archipelago/blob/main/worlds/AutoWorld.py#L310-L311)), from which the logic unfolds. AP assumes that a player will always be able to return to this starting region by resetting the game ("Save and quit"). ### Entrances From 11130037fe9a88d8be70a1624c35aea17daab680 Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Thu, 3 Jul 2025 15:08:36 -0400 Subject: [PATCH 0539/1218] Stardew Valley: Fixed luck level requirements for slot machines #5160 # Conflicts: # worlds/stardew_valley/data/craftable_data.py --- worlds/stardew_valley/data/craftable_data.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/stardew_valley/data/craftable_data.py b/worlds/stardew_valley/data/craftable_data.py index 66466d89b189..3dae67c2602c 100644 --- a/worlds/stardew_valley/data/craftable_data.py +++ b/worlds/stardew_valley/data/craftable_data.py @@ -386,7 +386,7 @@ def create_recipe(name: str, ingredients: Dict[str, int], source: RecipeSource, Forageable.salmonberry: 1, Material.clay: 1, Trash.joja_cola: 1}, ModNames.luck_skill) gold_slot_machine = skill_recipe(ModMachine.gold_slot_machine, ModSkill.luck, 4, {MetalBar.gold: 15, ModMachine.copper_slot_machine: 1}, ModNames.luck_skill) -iridium_slot_machine = skill_recipe(ModMachine.iridium_slot_machine, ModSkill.luck, 4, {MetalBar.iridium: 15, ModMachine.gold_slot_machine: 1}, ModNames.luck_skill) -radioactive_slot_machine = skill_recipe(ModMachine.radioactive_slot_machine, ModSkill.luck, 4, {MetalBar.radioactive: 15, ModMachine.iridium_slot_machine: 1}, ModNames.luck_skill) +iridium_slot_machine = skill_recipe(ModMachine.iridium_slot_machine, ModSkill.luck, 6, {MetalBar.iridium: 15, ModMachine.gold_slot_machine: 1}, ModNames.luck_skill) +radioactive_slot_machine = skill_recipe(ModMachine.radioactive_slot_machine, ModSkill.luck, 8, {MetalBar.radioactive: 15, ModMachine.iridium_slot_machine: 1}, ModNames.luck_skill) all_crafting_recipes_by_name = {recipe.item: recipe for recipe in all_crafting_recipes} From 072e2ece15429a49dda18898d266c9fa63905205 Mon Sep 17 00:00:00 2001 From: Ixrec Date: Sat, 5 Jul 2025 22:01:08 +0100 Subject: [PATCH 0540/1218] Docs: 'get_prefill_items' -> 'get_pre_fill_items' (#5167) --- docs/world api.md | 2 +- worlds/AutoWorld.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/world api.md b/docs/world api.md index 2f3dd0e429f8..677b1636e6be 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -533,7 +533,7 @@ In addition, the following methods can be implemented and are called in this ord called to modify item placement before, during, and after the regular fill process; all finishing before `generate_output`. Any items that need to be placed during `pre_fill` should not exist in the itempool, and if there are any items that need to be filled this way, but need to be in state while you fill other items, they can be - returned from `get_prefill_items`. + returned from `get_pre_fill_items`. * `generate_output(self, output_directory: str)` creates the output files if there is output to be generated. When this is called, `self.multiworld.get_locations(self.player)` has all locations for the player, with attribute `item` pointing to the diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 6ea6c237d970..6c1683e3d55e 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -382,7 +382,7 @@ def create_regions(self) -> None: def create_items(self) -> None: """ Method for creating and submitting items to the itempool. Items and Regions must *not* be created and submitted - to the MultiWorld after this step. If items need to be placed during pre_fill use `get_prefill_items`. + to the MultiWorld after this step. If items need to be placed during pre_fill use `get_pre_fill_items`. """ pass From e68b1ad42896ce5ec4c0ef0e46a21f0a21ab5cbb Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Sun, 6 Jul 2025 10:22:02 -0700 Subject: [PATCH 0541/1218] CommonClient: fix extra panels added to `main_area_container` (#5151) --- kvui.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kvui.py b/kvui.py index 2f45831200bc..e11e366d72d8 100644 --- a/kvui.py +++ b/kvui.py @@ -921,9 +921,11 @@ def connect_bar_validate(sender): hint_panel = self.add_client_tab("Hints", HintLayout(self.hint_log)) self.log_panels["Hints"] = hint_panel.content - self.main_area_container = MDGridLayout(size_hint_y=1, cols=1) - self.main_area_container.add_widget(self.tabs) - self.main_area_container.add_widget(self.screens) + self.main_area_container = MDGridLayout(size_hint_y=1, rows=1) + tab_container = MDGridLayout(size_hint_y=1, cols=1) + tab_container.add_widget(self.tabs) + tab_container.add_widget(self.screens) + self.main_area_container.add_widget(tab_container) self.grid.add_widget(self.main_area_container) From 4623d59206e88132432b6db74945a717057b2f8a Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 7 Jul 2025 15:51:39 +0200 Subject: [PATCH 0542/1218] Core: ensure slot_data and er_hint_info are only base data types (#5144) --------- Co-authored-by: Doug Hoskisson --- Main.py | 4 ++++ NetUtils.py | 21 +++++++++++++++++++++ test/general/test_implemented.py | 4 ++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Main.py b/Main.py index 442c2ff40441..456820a461f7 100644 --- a/Main.py +++ b/Main.py @@ -12,6 +12,7 @@ from BaseClasses import CollectionState, Item, Location, LocationProgressType, MultiWorld from Fill import FillError, balance_multiworld_progression, distribute_items_restrictive, flood_items, \ parse_planned_blocks, distribute_planned_blocks, resolve_early_locations_for_planned +from NetUtils import convert_to_base_types from Options import StartInventoryPool from Utils import __version__, output_path, version_tuple from settings import get_settings @@ -334,6 +335,9 @@ def precollect_hint(location: Location, auto_status: HintStatus): } AutoWorld.call_all(multiworld, "modify_multidata", multidata) + for key in ("slot_data", "er_hint_data"): + multidata[key] = convert_to_base_types(multidata[key]) + multidata = zlib.compress(pickle.dumps(multidata), 9) with open(os.path.join(temp_dir, f'{outfilebase}.archipelago'), 'wb') as f: diff --git a/NetUtils.py b/NetUtils.py index f2ae2a63a056..cc6e917c8800 100644 --- a/NetUtils.py +++ b/NetUtils.py @@ -106,6 +106,27 @@ def _scan_for_TypedTuples(obj: typing.Any) -> typing.Any: return obj +_base_types = str | int | bool | float | None | tuple["_base_types", ...] | dict["_base_types", "base_types"] + + +def convert_to_base_types(obj: typing.Any) -> _base_types: + if isinstance(obj, (tuple, list, set, frozenset)): + return tuple(convert_to_base_types(o) for o in obj) + elif isinstance(obj, dict): + return {convert_to_base_types(key): convert_to_base_types(value) for key, value in obj.items()} + elif obj is None or type(obj) in (str, int, float, bool): + return obj + # unwrap simple types to their base, such as StrEnum + elif isinstance(obj, str): + return str(obj) + elif isinstance(obj, int): + return int(obj) + elif isinstance(obj, float): + return float(obj) + else: + raise Exception(f"Cannot handle {type(obj)}") + + _encode = JSONEncoder( ensure_ascii=False, check_circular=False, diff --git a/test/general/test_implemented.py b/test/general/test_implemented.py index b74f82b738b5..cf0624a28837 100644 --- a/test/general/test_implemented.py +++ b/test/general/test_implemented.py @@ -1,7 +1,7 @@ import unittest from Fill import distribute_items_restrictive -from NetUtils import encode +from NetUtils import convert_to_base_types from worlds.AutoWorld import AutoWorldRegister, call_all from worlds import failed_world_loads from . import setup_solo_multiworld @@ -47,7 +47,7 @@ def test_slot_data(self): call_all(multiworld, "post_fill") for key, data in multiworld.worlds[1].fill_slot_data().items(): self.assertIsInstance(key, str, "keys in slot data must be a string") - self.assertIsInstance(encode(data), str, f"object {type(data).__name__} not serializable.") + convert_to_base_types(data) # only put base data types into slot data def test_no_failed_world_loads(self): if failed_world_loads: From 95e09c8e2a681ecd5666822b04fe7fed3ed9dec1 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Mon, 7 Jul 2025 16:24:35 +0200 Subject: [PATCH 0543/1218] Core: Take Counter back out of RestrictedUnpickler #5169 --- Utils.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Utils.py b/Utils.py index 84d3a33dc76f..6212b9328830 100644 --- a/Utils.py +++ b/Utils.py @@ -441,9 +441,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: def find_class(self, module: str, name: str) -> type: if module == "builtins" and name in safe_builtins: return getattr(builtins, name) - # used by OptionCounter - if module == "collections" and name == "Counter": - return collections.Counter # used by MultiServer -> savegame/multidata if module == "NetUtils" and name in {"NetworkItem", "ClientStatus", "Hint", "SlotType", "NetworkSlot", "HintStatus"}: From d4ebace99f17299c0fa861a1ccad42bdf4e332fe Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Mon, 7 Jul 2025 13:15:37 -0400 Subject: [PATCH 0544/1218] =?UTF-8?q?[Jak=20and=20Daxter]=20Auto=20Detect?= =?UTF-8?q?=20Install=20Path=20after=20Game=20Launcher=20Update=C2=A0#5152?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worlds/jakanddaxter/client.py | 36 ++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/worlds/jakanddaxter/client.py b/worlds/jakanddaxter/client.py index 2b669d384714..90e6a42aa7e3 100644 --- a/worlds/jakanddaxter/client.py +++ b/worlds/jakanddaxter/client.py @@ -367,7 +367,7 @@ def find_root_directory(ctx: JakAndDaxterContext): f" Close all launchers, games, clients, and console windows, then restart Archipelago.") if not os.path.exists(settings_path): - msg = (f"{err_title}: the OpenGOAL settings file does not exist.\n" + msg = (f"{err_title}: The OpenGOAL settings file does not exist.\n" f"{alt_instructions}") ctx.on_log_error(logger, msg) return @@ -375,14 +375,44 @@ def find_root_directory(ctx: JakAndDaxterContext): with open(settings_path, "r") as f: load = json.load(f) - jak1_installed = load["games"]["Jak 1"]["isInstalled"] + # This settings file has changed format once before, and may do so again in the future. + # Guard against future incompatibilities by checking the file version first, and use that to determine + # what JSON keys to look for next. + try: + settings_version = load["version"] + logger.debug(f"OpenGOAL settings file version: {settings_version}") + except KeyError: + msg = (f"{err_title}: The OpenGOAL settings file has no version number!\n" + f"{alt_instructions}") + ctx.on_log_error(logger, msg) + return + + try: + if settings_version == "2.0": + jak1_installed = load["games"]["Jak 1"]["isInstalled"] + mod_sources = load["games"]["Jak 1"]["modsInstalledVersion"] + + elif settings_version == "3.0": + jak1_installed = load["games"]["jak1"]["isInstalled"] + mod_sources = load["games"]["jak1"]["mods"] + + else: + msg = (f"{err_title}: The OpenGOAL settings file has an unknown version number ({settings_version}).\n" + f"{alt_instructions}") + ctx.on_log_error(logger, msg) + return + except KeyError as e: + msg = (f"{err_title}: The OpenGOAL settings file does not contain key entry {e}!\n" + f"{alt_instructions}") + ctx.on_log_error(logger, msg) + return + if not jak1_installed: msg = (f"{err_title}: The OpenGOAL Launcher is missing a normal install of Jak 1!\n" f"{alt_instructions}") ctx.on_log_error(logger, msg) return - mod_sources = load["games"]["Jak 1"]["modsInstalledVersion"] if mod_sources is None: msg = (f"{err_title}: No mod sources have been configured in the OpenGOAL Launcher!\n" f"{alt_instructions}") From f4b5422f66c0f5332cb05998ad0f7731d4a436f3 Mon Sep 17 00:00:00 2001 From: Remy Jette Date: Mon, 7 Jul 2025 13:57:55 -0700 Subject: [PATCH 0545/1218] Factorio: Fix link to world_gen documentation (#5171) --- worlds/factorio/Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/factorio/Options.py b/worlds/factorio/Options.py index 12fc90c1fd15..0a789669d5d6 100644 --- a/worlds/factorio/Options.py +++ b/worlds/factorio/Options.py @@ -321,7 +321,7 @@ class InventorySpillTrapCount(TrapCount): class FactorioWorldGen(OptionDict): """World Generation settings. Overview of options at https://wiki.factorio.com/Map_generator, - with in-depth documentation at https://lua-api.factorio.com/latest/Concepts.html#MapGenSettings""" + with in-depth documentation at https://lua-api.factorio.com/latest/concepts/MapGenSettings.html""" display_name = "World Generation" # FIXME: do we want default be a rando-optimized default or in-game DS? value: dict[str, dict[str, typing.Any]] From b1ff55dd061af9158c1747a57472d157e42ded92 Mon Sep 17 00:00:00 2001 From: axe-y <58866768+axe-y@users.noreply.github.com> Date: Thu, 10 Jul 2025 08:33:52 -0400 Subject: [PATCH 0546/1218] DLCQ: Fix/Refactor LFoD Start Inventory (#5176) --- worlds/dlcquest/Items.py | 40 +++++++++++----------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/worlds/dlcquest/Items.py b/worlds/dlcquest/Items.py index 550d92419ba9..5496885a74f7 100644 --- a/worlds/dlcquest/Items.py +++ b/worlds/dlcquest/Items.py @@ -30,7 +30,6 @@ class Group(enum.Enum): Deprecated = enum.auto() - @dataclass(frozen=True) class ItemData: code_without_offset: offset @@ -98,14 +97,15 @@ def create_trap_items(world, world_options: Options.DLCQuestOptions, trap_needed return traps -def create_items(world, world_options: Options.DLCQuestOptions, locations_count: int, excluded_items: list[str], random: Random): +def create_items(world, world_options: Options.DLCQuestOptions, locations_count: int, excluded_items: list[str], + random: Random): created_items = [] if world_options.campaign == Options.Campaign.option_basic or world_options.campaign == Options.Campaign.option_both: - create_items_basic(world_options, created_items, world, excluded_items) + create_items_campaign(world_options, created_items, world, excluded_items, Group.DLCQuest, 825, 250) if (world_options.campaign == Options.Campaign.option_live_freemium_or_die or world_options.campaign == Options.Campaign.option_both): - create_items_lfod(world_options, created_items, world, excluded_items) + create_items_campaign(world_options, created_items, world, excluded_items, Group.Freemium, 889, 200) trap_items = create_trap_items(world, world_options, locations_count - len(created_items), random) created_items += trap_items @@ -113,27 +113,8 @@ def create_items(world, world_options: Options.DLCQuestOptions, locations_count: return created_items -def create_items_lfod(world_options, created_items, world, excluded_items): - for item in items_by_group[Group.Freemium]: - if item.name in excluded_items: - excluded_items.remove(item) - continue - - if item.has_any_group(Group.DLC): - created_items.append(world.create_item(item)) - if item.has_any_group(Group.Item) and world_options.item_shuffle == Options.ItemShuffle.option_shuffled: - created_items.append(world.create_item(item)) - if item.has_any_group(Group.Twice): - created_items.append(world.create_item(item)) - if world_options.coinsanity == Options.CoinSanity.option_coin: - if world_options.coinbundlequantity == -1: - create_coin_piece(created_items, world, 889, 200, Group.Freemium) - return - create_coin(world_options, created_items, world, 889, 200, Group.Freemium) - - -def create_items_basic(world_options, created_items, world, excluded_items): - for item in items_by_group[Group.DLCQuest]: +def create_items_campaign(world_options: Options.DLCQuestOptions, created_items: list[DLCQuestItem], world, excluded_items: list[str], group: Group, total_coins: int, required_coins: int): + for item in items_by_group[group]: if item.name in excluded_items: excluded_items.remove(item.name) continue @@ -146,14 +127,15 @@ def create_items_basic(world_options, created_items, world, excluded_items): created_items.append(world.create_item(item)) if world_options.coinsanity == Options.CoinSanity.option_coin: if world_options.coinbundlequantity == -1: - create_coin_piece(created_items, world, 825, 250, Group.DLCQuest) + create_coin_piece(created_items, world, total_coins, required_coins, group) return - create_coin(world_options, created_items, world, 825, 250, Group.DLCQuest) + create_coin(world_options, created_items, world, total_coins, required_coins, group) def create_coin(world_options, created_items, world, total_coins, required_coins, group): coin_bundle_required = math.ceil(required_coins / world_options.coinbundlequantity) - coin_bundle_useful = math.ceil((total_coins - coin_bundle_required * world_options.coinbundlequantity) / world_options.coinbundlequantity) + coin_bundle_useful = math.ceil( + (total_coins - coin_bundle_required * world_options.coinbundlequantity) / world_options.coinbundlequantity) for item in items_by_group[group]: if item.has_any_group(Group.Coin): for i in range(coin_bundle_required): @@ -165,7 +147,7 @@ def create_coin(world_options, created_items, world, total_coins, required_coins def create_coin_piece(created_items, world, total_coins, required_coins, group): for item in items_by_group[group]: if item.has_any_group(Group.Piece): - for i in range(required_coins*10): + for i in range(required_coins * 10): created_items.append(world.create_item(item)) for i in range((total_coins - required_coins) * 10): created_items.append(world.create_item(item, ItemClassification.useful)) From edc0c89753b6e5283d7289d6e60c5e050e5d8303 Mon Sep 17 00:00:00 2001 From: Carter Hesterman Date: Thu, 10 Jul 2025 07:10:56 -0600 Subject: [PATCH 0547/1218] CIV 6: Remove Erroneous Boost Prereqs for Computers Boost (#5134) --- worlds/civ_6/data/boosts.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/worlds/civ_6/data/boosts.py b/worlds/civ_6/data/boosts.py index a3977208154e..49cedfdfd991 100644 --- a/worlds/civ_6/data/boosts.py +++ b/worlds/civ_6/data/boosts.py @@ -78,8 +78,8 @@ CivVIBoostData( "BOOST_TECH_IRON_WORKING", "ERA_CLASSICAL", - ["TECH_MINING"], - 1, + ["TECH_MINING", "TECH_BRONZE_WORKING"], + 2, "DEFAULT", ), CivVIBoostData( @@ -165,15 +165,9 @@ "BOOST_TECH_CASTLES", "ERA_MEDIEVAL", [ - "CIVIC_DIVINE_RIGHT", - "CIVIC_EXPLORATION", - "CIVIC_REFORMED_CHURCH", "CIVIC_SUFFRAGE", "CIVIC_TOTALITARIANISM", "CIVIC_CLASS_STRUGGLE", - "CIVIC_DIGITAL_DEMOCRACY", - "CIVIC_CORPORATE_LIBERTARIANISM", - "CIVIC_SYNTHETIC_TECHNOCRACY", ], 1, "DEFAULT", @@ -393,9 +387,6 @@ "CIVIC_SUFFRAGE", "CIVIC_TOTALITARIANISM", "CIVIC_CLASS_STRUGGLE", - "CIVIC_DIGITAL_DEMOCRACY", - "CIVIC_CORPORATE_LIBERTARIANISM", - "CIVIC_SYNTHETIC_TECHNOCRACY", ], 1, "DEFAULT", From 2974f7d11f57e97da00a568b1c03a670fd8938d0 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Fri, 11 Jul 2025 19:27:28 +0200 Subject: [PATCH 0548/1218] Core: Replace Clique with V6 in unit tests (#5181) * replace Clique with V6 in unit tests * no hard mode in V6 * modify regex in copy_world to allow : str * oops * I see now * work around all typing * there actually needs to be something --- .github/workflows/build.yml | 4 ++-- test/hosting/__main__.py | 8 ++++---- test/hosting/generate.py | 2 +- test/hosting/world.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d6b80965f0ac..07ae1136fc01 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -98,7 +98,7 @@ jobs: shell: bash run: | cd build/exe* - cp Players/Templates/Clique.yaml Players/ + cp Players/Templates/VVVVVV.yaml Players/ timeout 30 ./ArchipelagoGenerate - name: Store 7z uses: actions/upload-artifact@v4 @@ -189,7 +189,7 @@ jobs: shell: bash run: | cd build/exe* - cp Players/Templates/Clique.yaml Players/ + cp Players/Templates/VVVVVV.yaml Players/ timeout 30 ./ArchipelagoGenerate - name: Store AppImage uses: actions/upload-artifact@v4 diff --git a/test/hosting/__main__.py b/test/hosting/__main__.py index 6640c637b5bd..e235d7bb7218 100644 --- a/test/hosting/__main__.py +++ b/test/hosting/__main__.py @@ -63,12 +63,12 @@ def expect_equal(first: Any, second: Any, msg: str = "") -> None: spacer = '=' * 80 with TemporaryDirectory() as tempdir: - multis = [["Clique"], ["Temp World"], ["Clique", "Temp World"]] + multis = [["VVVVVV"], ["Temp World"], ["VVVVVV", "Temp World"]] p1_games = [] data_paths = [] rooms = [] - copy_world("Clique", "Temp World") + copy_world("VVVVVV", "Temp World") try: for n, games in enumerate(multis, 1): print(f"Generating [{n}] {', '.join(games)}") @@ -101,7 +101,7 @@ def expect_equal(first: Any, second: Any, msg: str = "") -> None: with Client(host.address, game, "Player1") as client: local_data_packages = client.games_packages local_collected_items = len(client.checked_locations) - if collected_items < 2: # Clique only has 2 Locations + if collected_items < 2: # Don't collect anything on the last iteration client.collect_any() # TODO: Ctrl+C test here as well @@ -125,7 +125,7 @@ def expect_equal(first: Any, second: Any, msg: str = "") -> None: with Client(host.address, game, "Player1") as client: web_data_packages = client.games_packages web_collected_items = len(client.checked_locations) - if collected_items < 2: # Clique only has 2 Locations + if collected_items < 2: # Don't collect anything on the last iteration client.collect_any() if collected_items == 1: sleep(1) # wait for the server to collect the item diff --git a/test/hosting/generate.py b/test/hosting/generate.py index d5d39dc95ee0..e90868eb6f9f 100644 --- a/test/hosting/generate.py +++ b/test/hosting/generate.py @@ -34,7 +34,7 @@ def _generate_local_inner(games: Iterable[str], f.write(json.dumps({ "name": f"Player{n}", "game": game, - game: {"hard_mode": "true"}, + game: {}, "description": f"generate_local slot {n} ('Player{n}'): {game}", })) diff --git a/test/hosting/world.py b/test/hosting/world.py index 74126412017e..cd53453c10c2 100644 --- a/test/hosting/world.py +++ b/test/hosting/world.py @@ -30,7 +30,7 @@ def copy(src: str, dst: str) -> None: _new_worlds[dst] = str(dst_folder) with open(dst_folder / "__init__.py", "r", encoding="utf-8-sig") as f: contents = f.read() - contents = re.sub(r'game\s*=\s*[\'"]' + re.escape(src) + r'[\'"]', f'game = "{dst}"', contents) + contents = re.sub(r'game\s*(:\s*[a-zA-Z\[\]]+)?\s*=\s*[\'"]' + re.escape(src) + r'[\'"]', f'game = "{dst}"', contents) with open(dst_folder / "__init__.py", "w", encoding="utf-8") as f: f.write(contents) From 6af34b66fb166af42f73879152c1a030ff2423f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zach=20=E2=80=9CPhar=E2=80=9D=20Parks?= <11338376+ThePhar@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:34:46 -0500 Subject: [PATCH 0549/1218] Various: Remove Rogue Legacy and Clique (#5177) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Various: Remove Rogue Legacy and Clique * Remove Clique from setup.py and revert network diagram.md change. * Try again. * Update network diagram.md --------- Co-authored-by: Zach “Phar” Parks Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- README.md | 2 - docs/CODEOWNERS | 6 - docs/network diagram/network diagram.md | 4 +- setup.py | 1 - worlds/clique/Items.py | 38 -- worlds/clique/Locations.py | 37 -- worlds/clique/Options.py | 34 -- worlds/clique/Regions.py | 11 - worlds/clique/Rules.py | 13 - worlds/clique/__init__.py | 102 ------ worlds/clique/docs/de_Clique.md | 18 - worlds/clique/docs/en_Clique.md | 16 - worlds/clique/docs/guide_de.md | 25 -- worlds/clique/docs/guide_en.md | 22 -- worlds/rogue_legacy/Items.py | 111 ------ worlds/rogue_legacy/Locations.py | 94 ----- worlds/rogue_legacy/Options.py | 387 -------------------- worlds/rogue_legacy/Presets.py | 61 --- worlds/rogue_legacy/Regions.py | 114 ------ worlds/rogue_legacy/Rules.py | 117 ------ worlds/rogue_legacy/__init__.py | 243 ------------ worlds/rogue_legacy/docs/en_Rogue Legacy.md | 34 -- worlds/rogue_legacy/docs/rogue-legacy_en.md | 35 -- worlds/rogue_legacy/test/TestUnique.py | 23 -- worlds/rogue_legacy/test/__init__.py | 5 - 25 files changed, 1 insertion(+), 1552 deletions(-) delete mode 100644 worlds/clique/Items.py delete mode 100644 worlds/clique/Locations.py delete mode 100644 worlds/clique/Options.py delete mode 100644 worlds/clique/Regions.py delete mode 100644 worlds/clique/Rules.py delete mode 100644 worlds/clique/__init__.py delete mode 100644 worlds/clique/docs/de_Clique.md delete mode 100644 worlds/clique/docs/en_Clique.md delete mode 100644 worlds/clique/docs/guide_de.md delete mode 100644 worlds/clique/docs/guide_en.md delete mode 100644 worlds/rogue_legacy/Items.py delete mode 100644 worlds/rogue_legacy/Locations.py delete mode 100644 worlds/rogue_legacy/Options.py delete mode 100644 worlds/rogue_legacy/Presets.py delete mode 100644 worlds/rogue_legacy/Regions.py delete mode 100644 worlds/rogue_legacy/Rules.py delete mode 100644 worlds/rogue_legacy/__init__.py delete mode 100644 worlds/rogue_legacy/docs/en_Rogue Legacy.md delete mode 100644 worlds/rogue_legacy/docs/rogue-legacy_en.md delete mode 100644 worlds/rogue_legacy/test/TestUnique.py delete mode 100644 worlds/rogue_legacy/test/__init__.py diff --git a/README.md b/README.md index afad4b15f0b7..29b6206a00d8 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,6 @@ Currently, the following games are supported: * Super Metroid * Secret of Evermore * Final Fantasy -* Rogue Legacy * VVVVVV * Raft * Super Mario 64 @@ -41,7 +40,6 @@ Currently, the following games are supported: * The Messenger * Kingdom Hearts 2 * The Legend of Zelda: Link's Awakening DX -* Clique * Adventure * DLC Quest * Noita diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 4bdd49b62958..3104200a6c9d 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -48,9 +48,6 @@ # Civilization VI /worlds/civ6/ @hesto2 -# Clique -/worlds/clique/ @ThePhar - # Dark Souls III /worlds/dark_souls_3/ @Marechal-L @nex3 @@ -148,9 +145,6 @@ # Raft /worlds/raft/ @SunnyBat -# Rogue Legacy -/worlds/rogue_legacy/ @ThePhar - # Risk of Rain 2 /worlds/ror2/ @kindasneaki diff --git a/docs/network diagram/network diagram.md b/docs/network diagram/network diagram.md index 0e31eaa3e4ca..2d0a1174f545 100644 --- a/docs/network diagram/network diagram.md +++ b/docs/network diagram/network diagram.md @@ -125,10 +125,8 @@ flowchart LR NM[Mod with Archipelago.MultiClient.Net] subgraph FNA/XNA TS[Timespinner] - RL[Rogue Legacy] end NM <-- TsRandomizer --> TS - NM <-- RogueLegacyRandomizer --> RL subgraph Unity ROR[Risk of Rain 2] SN[Subnautica] @@ -177,4 +175,4 @@ flowchart LR FMOD <--> FMAPI end CC <-- Integrated --> FC -``` \ No newline at end of file +``` diff --git a/setup.py b/setup.py index 959746717a17..cd1b1e87107d 100644 --- a/setup.py +++ b/setup.py @@ -63,7 +63,6 @@ "Adventure", "ArchipIDLE", "Archipelago", - "Clique", "Lufia II Ancient Cave", "Meritous", "Ocarina of Time", diff --git a/worlds/clique/Items.py b/worlds/clique/Items.py deleted file mode 100644 index 81e2540bacc0..000000000000 --- a/worlds/clique/Items.py +++ /dev/null @@ -1,38 +0,0 @@ -from typing import Callable, Dict, NamedTuple, Optional, TYPE_CHECKING - -from BaseClasses import Item, ItemClassification - -if TYPE_CHECKING: - from . import CliqueWorld - - -class CliqueItem(Item): - game = "Clique" - - -class CliqueItemData(NamedTuple): - code: Optional[int] = None - type: ItemClassification = ItemClassification.filler - can_create: Callable[["CliqueWorld"], bool] = lambda world: True - - -item_data_table: Dict[str, CliqueItemData] = { - "Feeling of Satisfaction": CliqueItemData( - code=69696969, - type=ItemClassification.progression, - ), - "Button Activation": CliqueItemData( - code=69696968, - type=ItemClassification.progression, - can_create=lambda world: world.options.hard_mode, - ), - "A Cool Filler Item (No Satisfaction Guaranteed)": CliqueItemData( - code=69696967, - can_create=lambda world: False # Only created from `get_filler_item_name`. - ), - "The Urge to Push": CliqueItemData( - type=ItemClassification.progression, - ), -} - -item_table = {name: data.code for name, data in item_data_table.items() if data.code is not None} diff --git a/worlds/clique/Locations.py b/worlds/clique/Locations.py deleted file mode 100644 index 900b497eb4eb..000000000000 --- a/worlds/clique/Locations.py +++ /dev/null @@ -1,37 +0,0 @@ -from typing import Callable, Dict, NamedTuple, Optional, TYPE_CHECKING - -from BaseClasses import Location - -if TYPE_CHECKING: - from . import CliqueWorld - - -class CliqueLocation(Location): - game = "Clique" - - -class CliqueLocationData(NamedTuple): - region: str - address: Optional[int] = None - can_create: Callable[["CliqueWorld"], bool] = lambda world: True - locked_item: Optional[str] = None - - -location_data_table: Dict[str, CliqueLocationData] = { - "The Big Red Button": CliqueLocationData( - region="The Button Realm", - address=69696969, - ), - "The Item on the Desk": CliqueLocationData( - region="The Button Realm", - address=69696968, - can_create=lambda world: world.options.hard_mode, - ), - "In the Player's Mind": CliqueLocationData( - region="The Button Realm", - locked_item="The Urge to Push", - ), -} - -location_table = {name: data.address for name, data in location_data_table.items() if data.address is not None} -locked_locations = {name: data for name, data in location_data_table.items() if data.locked_item} diff --git a/worlds/clique/Options.py b/worlds/clique/Options.py deleted file mode 100644 index d88a1289903c..000000000000 --- a/worlds/clique/Options.py +++ /dev/null @@ -1,34 +0,0 @@ -from dataclasses import dataclass -from Options import Choice, Toggle, PerGameCommonOptions, StartInventoryPool - - -class HardMode(Toggle): - """Only for the most masochistically inclined... Requires button activation!""" - display_name = "Hard Mode" - - -class ButtonColor(Choice): - """Customize your button! Now available in 12 unique colors.""" - display_name = "Button Color" - option_red = 0 - option_orange = 1 - option_yellow = 2 - option_green = 3 - option_cyan = 4 - option_blue = 5 - option_magenta = 6 - option_purple = 7 - option_pink = 8 - option_brown = 9 - option_white = 10 - option_black = 11 - - -@dataclass -class CliqueOptions(PerGameCommonOptions): - color: ButtonColor - hard_mode: HardMode - start_inventory_from_pool: StartInventoryPool - - # DeathLink is always on. Always. - # death_link: DeathLink diff --git a/worlds/clique/Regions.py b/worlds/clique/Regions.py deleted file mode 100644 index 04e317067fa1..000000000000 --- a/worlds/clique/Regions.py +++ /dev/null @@ -1,11 +0,0 @@ -from typing import Dict, List, NamedTuple - - -class CliqueRegionData(NamedTuple): - connecting_regions: List[str] = [] - - -region_data_table: Dict[str, CliqueRegionData] = { - "Menu": CliqueRegionData(["The Button Realm"]), - "The Button Realm": CliqueRegionData(), -} diff --git a/worlds/clique/Rules.py b/worlds/clique/Rules.py deleted file mode 100644 index 63ecd4e9e17c..000000000000 --- a/worlds/clique/Rules.py +++ /dev/null @@ -1,13 +0,0 @@ -from typing import Callable, TYPE_CHECKING - -from BaseClasses import CollectionState - -if TYPE_CHECKING: - from . import CliqueWorld - - -def get_button_rule(world: "CliqueWorld") -> Callable[[CollectionState], bool]: - if world.options.hard_mode: - return lambda state: state.has("Button Activation", world.player) - - return lambda state: True diff --git a/worlds/clique/__init__.py b/worlds/clique/__init__.py deleted file mode 100644 index 70777c51b00c..000000000000 --- a/worlds/clique/__init__.py +++ /dev/null @@ -1,102 +0,0 @@ -from typing import List, Dict, Any - -from BaseClasses import Region, Tutorial -from worlds.AutoWorld import WebWorld, World -from .Items import CliqueItem, item_data_table, item_table -from .Locations import CliqueLocation, location_data_table, location_table, locked_locations -from .Options import CliqueOptions -from .Regions import region_data_table -from .Rules import get_button_rule - - -class CliqueWebWorld(WebWorld): - theme = "partyTime" - - setup_en = Tutorial( - tutorial_name="Start Guide", - description="A guide to playing Clique.", - language="English", - file_name="guide_en.md", - link="guide/en", - authors=["Phar"] - ) - - setup_de = Tutorial( - tutorial_name="Anleitung zum Anfangen", - description="Eine Anleitung um Clique zu spielen.", - language="Deutsch", - file_name="guide_de.md", - link="guide/de", - authors=["Held_der_Zeit"] - ) - - tutorials = [setup_en, setup_de] - game_info_languages = ["en", "de"] - - -class CliqueWorld(World): - """The greatest game of all time.""" - - game = "Clique" - web = CliqueWebWorld() - options: CliqueOptions - options_dataclass = CliqueOptions - location_name_to_id = location_table - item_name_to_id = item_table - - def create_item(self, name: str) -> CliqueItem: - return CliqueItem(name, item_data_table[name].type, item_data_table[name].code, self.player) - - def create_items(self) -> None: - item_pool: List[CliqueItem] = [] - for name, item in item_data_table.items(): - if item.code and item.can_create(self): - item_pool.append(self.create_item(name)) - - self.multiworld.itempool += item_pool - - def create_regions(self) -> None: - # Create regions. - for region_name in region_data_table.keys(): - region = Region(region_name, self.player, self.multiworld) - self.multiworld.regions.append(region) - - # Create locations. - for region_name, region_data in region_data_table.items(): - region = self.get_region(region_name) - region.add_locations({ - location_name: location_data.address for location_name, location_data in location_data_table.items() - if location_data.region == region_name and location_data.can_create(self) - }, CliqueLocation) - region.add_exits(region_data_table[region_name].connecting_regions) - - # Place locked locations. - for location_name, location_data in locked_locations.items(): - # Ignore locations we never created. - if not location_data.can_create(self): - continue - - locked_item = self.create_item(location_data_table[location_name].locked_item) - self.get_location(location_name).place_locked_item(locked_item) - - # Set priority location for the Big Red Button! - self.options.priority_locations.value.add("The Big Red Button") - - def get_filler_item_name(self) -> str: - return "A Cool Filler Item (No Satisfaction Guaranteed)" - - def set_rules(self) -> None: - button_rule = get_button_rule(self) - self.get_location("The Big Red Button").access_rule = button_rule - self.get_location("In the Player's Mind").access_rule = button_rule - - # Do not allow button activations on buttons. - self.get_location("The Big Red Button").item_rule = lambda item: item.name != "Button Activation" - - # Completion condition. - self.multiworld.completion_condition[self.player] = lambda state: state.has("The Urge to Push", self.player) - - def fill_slot_data(self) -> Dict[str, Any]: - return { - "color": self.options.color.current_key - } diff --git a/worlds/clique/docs/de_Clique.md b/worlds/clique/docs/de_Clique.md deleted file mode 100644 index cde0a23cf6fe..000000000000 --- a/worlds/clique/docs/de_Clique.md +++ /dev/null @@ -1,18 +0,0 @@ -# Clique - -## Was ist das für ein Spiel? - -~~Clique ist ein psychologisches Überlebens-Horror Spiel, in dem der Spieler der Versuchung wiederstehen muss große~~ -~~(rote) Knöpfe zu drücken.~~ - -Clique ist ein scherzhaftes Spiel, welches für Archipelago im März 2023 entwickelt wurde, um zu zeigen, wie einfach -es sein kann eine Welt für Archipelago zu entwicklen. Das Ziel des Spiels ist es den großen (standardmäßig) roten -Knopf zu drücken. Wenn ein Spieler auf dem `hard_mode` (schwieriger Modus) spielt, muss dieser warten bis jemand -anderes in der Multiworld den Knopf aktiviert, damit er gedrückt werden kann. - -Clique kann auf den meisten modernen, HTML5-fähigen Browsern gespielt werden. - -## Wo ist die Seite für die Einstellungen? - -Die [Seite für die Spielereinstellungen dieses Spiels](../player-options) enthält alle Optionen die man benötigt um -eine YAML-Datei zu konfigurieren und zu exportieren. diff --git a/worlds/clique/docs/en_Clique.md b/worlds/clique/docs/en_Clique.md deleted file mode 100644 index e9cb164fecbf..000000000000 --- a/worlds/clique/docs/en_Clique.md +++ /dev/null @@ -1,16 +0,0 @@ -# Clique - -## What is this game? - -~~Clique is a psychological survival horror game where a player must survive the temptation to press red buttons.~~ - -Clique is a joke game developed for Archipelago in March 2023 to showcase how easy it can be to develop a world for -Archipelago. The objective of the game is to press the big red button. If a player is playing on `hard_mode`, they must -wait for someone else in the multiworld to "activate" their button before they can press it. - -Clique can be played on most modern HTML5-capable browsers. - -## Where is the options page? - -The [player options page for this game](../player-options) contains all the options you need to configure -and export a config file. diff --git a/worlds/clique/docs/guide_de.md b/worlds/clique/docs/guide_de.md deleted file mode 100644 index 26e08dbbdd7e..000000000000 --- a/worlds/clique/docs/guide_de.md +++ /dev/null @@ -1,25 +0,0 @@ -# Clique Anleitung - -Nachdem dein Seed generiert wurde, gehe auf die Website von [Clique dem Spiel](http://clique.pharware.com/) und gib -Server-Daten, deinen Slot-Namen und ein Passwort (falls vorhanden) ein. Klicke dann auf "Connect" (Verbinden). - -Wenn du auf "Einfach" spielst, kannst du unbedenklich den Knopf drücken und deine "Befriedigung" erhalten. - -Wenn du auf "Schwer" spielst, ist es sehr wahrscheinlich, dass du warten musst bevor du dein Ziel erreichen kannst. -Glücklicherweise läuft Click auf den meißten großen Browsern, die HTML5 unterstützen. Das heißt du kannst Clique auf -deinem Handy starten und produktiv sein während du wartest! - -Falls du einige Ideen brauchst was du tun kannst, während du wartest bis der Knopf aktiviert wurde, versuche -(mindestens) eins der Folgenden: - -- Dein Zimmer aufräumen. -- Die Wäsche machen. -- Etwas Essen von einem X-Belieben Fast Food Restaruant holen. -- Das tägliche Wordle machen. -- ~~Deine Seele an **Phar** verkaufen.~~ -- Deine Hausaufgaben erledigen. -- Deine Post abholen. - - -~~Solltest du auf irgendwelche Probleme in diesem Spiel stoßen, solltest du keinesfalls nicht **thephar** auf~~ -~~Discord kontaktieren. *zwinker* *zwinker*~~ diff --git a/worlds/clique/docs/guide_en.md b/worlds/clique/docs/guide_en.md deleted file mode 100644 index c3c113fe9056..000000000000 --- a/worlds/clique/docs/guide_en.md +++ /dev/null @@ -1,22 +0,0 @@ -# Clique Start Guide - -After rolling your seed, go to the [Clique Game](http://clique.pharware.com/) site and enter the server details, your -slot name, and a room password if one is required. Then click "Connect". - -If you're playing on "easy mode", just click the button and receive "Satisfaction". - -If you're playing on "hard mode", you may need to wait for activation before you can complete your objective. Luckily, -Clique runs in most major browsers that support HTML5, so you can load Clique on your phone and be productive while -you wait! - -If you need some ideas for what to do while waiting for button activation, give the following a try: - -- Clean your room. -- Wash the dishes. -- Get some food from a non-descript fast food restaurant. -- Do the daily Wordle. -- ~~Sell your soul to Phar.~~ -- Do your school work. - - -~~If you run into any issues with this game, definitely do not contact **thephar** on discord. *wink* *wink*~~ diff --git a/worlds/rogue_legacy/Items.py b/worlds/rogue_legacy/Items.py deleted file mode 100644 index efa24df05ac2..000000000000 --- a/worlds/rogue_legacy/Items.py +++ /dev/null @@ -1,111 +0,0 @@ -from typing import Dict, NamedTuple, Optional - -from BaseClasses import Item, ItemClassification - - -class RLItem(Item): - game: str = "Rogue Legacy" - - -class RLItemData(NamedTuple): - category: str - code: Optional[int] = None - classification: ItemClassification = ItemClassification.filler - max_quantity: int = 1 - weight: int = 1 - - -def get_items_by_category(category: str) -> Dict[str, RLItemData]: - item_dict: Dict[str, RLItemData] = {} - for name, data in item_table.items(): - if data.category == category: - item_dict.setdefault(name, data) - - return item_dict - - -item_table: Dict[str, RLItemData] = { - # Vendors - "Blacksmith": RLItemData("Vendors", 90_000, ItemClassification.progression), - "Enchantress": RLItemData("Vendors", 90_001, ItemClassification.progression), - "Architect": RLItemData("Vendors", 90_002, ItemClassification.useful), - - # Classes - "Progressive Knights": RLItemData("Classes", 90_003, ItemClassification.useful, 2), - "Progressive Mages": RLItemData("Classes", 90_004, ItemClassification.useful, 2), - "Progressive Barbarians": RLItemData("Classes", 90_005, ItemClassification.useful, 2), - "Progressive Knaves": RLItemData("Classes", 90_006, ItemClassification.useful, 2), - "Progressive Shinobis": RLItemData("Classes", 90_007, ItemClassification.useful, 2), - "Progressive Miners": RLItemData("Classes", 90_008, ItemClassification.useful, 2), - "Progressive Liches": RLItemData("Classes", 90_009, ItemClassification.useful, 2), - "Progressive Spellthieves": RLItemData("Classes", 90_010, ItemClassification.useful, 2), - "Dragons": RLItemData("Classes", 90_096, ItemClassification.progression), - "Traitors": RLItemData("Classes", 90_097, ItemClassification.useful), - - # Skills - "Health Up": RLItemData("Skills", 90_013, ItemClassification.progression_skip_balancing, 15), - "Mana Up": RLItemData("Skills", 90_014, ItemClassification.progression_skip_balancing, 15), - "Attack Up": RLItemData("Skills", 90_015, ItemClassification.progression_skip_balancing, 15), - "Magic Damage Up": RLItemData("Skills", 90_016, ItemClassification.progression_skip_balancing, 15), - "Armor Up": RLItemData("Skills", 90_017, ItemClassification.useful, 15), - "Equip Up": RLItemData("Skills", 90_018, ItemClassification.useful, 5), - "Crit Chance Up": RLItemData("Skills", 90_019, ItemClassification.useful, 5), - "Crit Damage Up": RLItemData("Skills", 90_020, ItemClassification.useful, 5), - "Down Strike Up": RLItemData("Skills", 90_021), - "Gold Gain Up": RLItemData("Skills", 90_022), - "Potion Efficiency Up": RLItemData("Skills", 90_023), - "Invulnerability Time Up": RLItemData("Skills", 90_024), - "Mana Cost Down": RLItemData("Skills", 90_025), - "Death Defiance": RLItemData("Skills", 90_026, ItemClassification.useful), - "Haggling": RLItemData("Skills", 90_027, ItemClassification.useful), - "Randomize Children": RLItemData("Skills", 90_028, ItemClassification.useful), - - # Blueprints - "Progressive Blueprints": RLItemData("Blueprints", 90_055, ItemClassification.useful, 15), - "Squire Blueprints": RLItemData("Blueprints", 90_040, ItemClassification.useful), - "Silver Blueprints": RLItemData("Blueprints", 90_041, ItemClassification.useful), - "Guardian Blueprints": RLItemData("Blueprints", 90_042, ItemClassification.useful), - "Imperial Blueprints": RLItemData("Blueprints", 90_043, ItemClassification.useful), - "Royal Blueprints": RLItemData("Blueprints", 90_044, ItemClassification.useful), - "Knight Blueprints": RLItemData("Blueprints", 90_045, ItemClassification.useful), - "Ranger Blueprints": RLItemData("Blueprints", 90_046, ItemClassification.useful), - "Sky Blueprints": RLItemData("Blueprints", 90_047, ItemClassification.useful), - "Dragon Blueprints": RLItemData("Blueprints", 90_048, ItemClassification.useful), - "Slayer Blueprints": RLItemData("Blueprints", 90_049, ItemClassification.useful), - "Blood Blueprints": RLItemData("Blueprints", 90_050, ItemClassification.useful), - "Sage Blueprints": RLItemData("Blueprints", 90_051, ItemClassification.useful), - "Retribution Blueprints": RLItemData("Blueprints", 90_052, ItemClassification.useful), - "Holy Blueprints": RLItemData("Blueprints", 90_053, ItemClassification.useful), - "Dark Blueprints": RLItemData("Blueprints", 90_054, ItemClassification.useful), - - # Runes - "Vault Runes": RLItemData("Runes", 90_060, ItemClassification.progression), - "Sprint Runes": RLItemData("Runes", 90_061, ItemClassification.progression), - "Vampire Runes": RLItemData("Runes", 90_062, ItemClassification.useful), - "Sky Runes": RLItemData("Runes", 90_063, ItemClassification.progression), - "Siphon Runes": RLItemData("Runes", 90_064, ItemClassification.useful), - "Retaliation Runes": RLItemData("Runes", 90_065), - "Bounty Runes": RLItemData("Runes", 90_066), - "Haste Runes": RLItemData("Runes", 90_067), - "Curse Runes": RLItemData("Runes", 90_068), - "Grace Runes": RLItemData("Runes", 90_069), - "Balance Runes": RLItemData("Runes", 90_070, ItemClassification.useful), - - # Junk - "Triple Stat Increase": RLItemData("Filler", 90_030, weight=6), - "1000 Gold": RLItemData("Filler", 90_031, weight=3), - "3000 Gold": RLItemData("Filler", 90_032, weight=2), - "5000 Gold": RLItemData("Filler", 90_033, weight=1), -} - -event_item_table: Dict[str, RLItemData] = { - "Defeat Khidr": RLItemData("Event", classification=ItemClassification.progression), - "Defeat Alexander": RLItemData("Event", classification=ItemClassification.progression), - "Defeat Ponce de Leon": RLItemData("Event", classification=ItemClassification.progression), - "Defeat Herodotus": RLItemData("Event", classification=ItemClassification.progression), - "Defeat Neo Khidr": RLItemData("Event", classification=ItemClassification.progression), - "Defeat Alexander IV": RLItemData("Event", classification=ItemClassification.progression), - "Defeat Ponce de Freon": RLItemData("Event", classification=ItemClassification.progression), - "Defeat Astrodotus": RLItemData("Event", classification=ItemClassification.progression), - "Defeat The Fountain": RLItemData("Event", classification=ItemClassification.progression), -} diff --git a/worlds/rogue_legacy/Locations.py b/worlds/rogue_legacy/Locations.py deleted file mode 100644 index db9e1db3b09a..000000000000 --- a/worlds/rogue_legacy/Locations.py +++ /dev/null @@ -1,94 +0,0 @@ -from typing import Dict, NamedTuple, Optional - -from BaseClasses import Location - - -class RLLocation(Location): - game: str = "Rogue Legacy" - - -class RLLocationData(NamedTuple): - category: str - code: Optional[int] = None - - -def get_locations_by_category(category: str) -> Dict[str, RLLocationData]: - location_dict: Dict[str, RLLocationData] = {} - for name, data in location_table.items(): - if data.category == category: - location_dict.setdefault(name, data) - - return location_dict - - -location_table: Dict[str, RLLocationData] = { - # Manor Renovation - "Manor - Ground Road": RLLocationData("Manor", 91_000), - "Manor - Main Base": RLLocationData("Manor", 91_001), - "Manor - Main Bottom Window": RLLocationData("Manor", 91_002), - "Manor - Main Top Window": RLLocationData("Manor", 91_003), - "Manor - Main Rooftop": RLLocationData("Manor", 91_004), - "Manor - Left Wing Base": RLLocationData("Manor", 91_005), - "Manor - Left Wing Window": RLLocationData("Manor", 91_006), - "Manor - Left Wing Rooftop": RLLocationData("Manor", 91_007), - "Manor - Left Big Base": RLLocationData("Manor", 91_008), - "Manor - Left Big Upper 1": RLLocationData("Manor", 91_009), - "Manor - Left Big Upper 2": RLLocationData("Manor", 91_010), - "Manor - Left Big Windows": RLLocationData("Manor", 91_011), - "Manor - Left Big Rooftop": RLLocationData("Manor", 91_012), - "Manor - Left Far Base": RLLocationData("Manor", 91_013), - "Manor - Left Far Roof": RLLocationData("Manor", 91_014), - "Manor - Left Extension": RLLocationData("Manor", 91_015), - "Manor - Left Tree 1": RLLocationData("Manor", 91_016), - "Manor - Left Tree 2": RLLocationData("Manor", 91_017), - "Manor - Right Wing Base": RLLocationData("Manor", 91_018), - "Manor - Right Wing Window": RLLocationData("Manor", 91_019), - "Manor - Right Wing Rooftop": RLLocationData("Manor", 91_020), - "Manor - Right Big Base": RLLocationData("Manor", 91_021), - "Manor - Right Big Upper": RLLocationData("Manor", 91_022), - "Manor - Right Big Rooftop": RLLocationData("Manor", 91_023), - "Manor - Right High Base": RLLocationData("Manor", 91_024), - "Manor - Right High Upper": RLLocationData("Manor", 91_025), - "Manor - Right High Tower": RLLocationData("Manor", 91_026), - "Manor - Right Extension": RLLocationData("Manor", 91_027), - "Manor - Right Tree": RLLocationData("Manor", 91_028), - "Manor - Observatory Base": RLLocationData("Manor", 91_029), - "Manor - Observatory Telescope": RLLocationData("Manor", 91_030), - - # Boss Rewards - "Castle Hamson Boss Reward": RLLocationData("Boss", 91_100), - "Forest Abkhazia Boss Reward": RLLocationData("Boss", 91_102), - "The Maya Boss Reward": RLLocationData("Boss", 91_104), - "Land of Darkness Boss Reward": RLLocationData("Boss", 91_106), - - # Special Locations - "Jukebox": RLLocationData("Special", 91_200), - "Painting": RLLocationData("Special", 91_201), - "Cheapskate Elf's Game": RLLocationData("Special", 91_202), - "Carnival": RLLocationData("Special", 91_203), - - # Diaries - **{f"Diary {i+1}": RLLocationData("Diary", 91_300 + i) for i in range(0, 25)}, - - # Chests - **{f"Castle Hamson - Chest {i+1}": RLLocationData("Chests", 91_600 + i) for i in range(0, 50)}, - **{f"Forest Abkhazia - Chest {i+1}": RLLocationData("Chests", 91_700 + i) for i in range(0, 50)}, - **{f"The Maya - Chest {i+1}": RLLocationData("Chests", 91_800 + i) for i in range(0, 50)}, - **{f"Land of Darkness - Chest {i+1}": RLLocationData("Chests", 91_900 + i) for i in range(0, 50)}, - **{f"Chest {i+1}": RLLocationData("Chests", 92_000 + i) for i in range(0, 200)}, - - # Fairy Chests - **{f"Castle Hamson - Fairy Chest {i+1}": RLLocationData("Fairies", 91_400 + i) for i in range(0, 15)}, - **{f"Forest Abkhazia - Fairy Chest {i+1}": RLLocationData("Fairies", 91_450 + i) for i in range(0, 15)}, - **{f"The Maya - Fairy Chest {i+1}": RLLocationData("Fairies", 91_500 + i) for i in range(0, 15)}, - **{f"Land of Darkness - Fairy Chest {i+1}": RLLocationData("Fairies", 91_550 + i) for i in range(0, 15)}, - **{f"Fairy Chest {i+1}": RLLocationData("Fairies", 92_200 + i) for i in range(0, 60)}, -} - -event_location_table: Dict[str, RLLocationData] = { - "Castle Hamson Boss Room": RLLocationData("Event"), - "Forest Abkhazia Boss Room": RLLocationData("Event"), - "The Maya Boss Room": RLLocationData("Event"), - "Land of Darkness Boss Room": RLLocationData("Event"), - "Fountain Room": RLLocationData("Event"), -} diff --git a/worlds/rogue_legacy/Options.py b/worlds/rogue_legacy/Options.py deleted file mode 100644 index 139ff6094427..000000000000 --- a/worlds/rogue_legacy/Options.py +++ /dev/null @@ -1,387 +0,0 @@ -from Options import Choice, Range, Toggle, DeathLink, DefaultOnToggle, OptionSet, PerGameCommonOptions - -from dataclasses import dataclass - - -class StartingGender(Choice): - """ - Determines the gender of your initial 'Sir Lee' character. - """ - display_name = "Starting Gender" - option_sir = 0 - option_lady = 1 - alias_male = 0 - alias_female = 1 - default = "random" - - -class StartingClass(Choice): - """ - Determines the starting class of your initial 'Sir Lee' character. - """ - display_name = "Starting Class" - option_knight = 0 - option_mage = 1 - option_barbarian = 2 - option_knave = 3 - option_shinobi = 4 - option_miner = 5 - option_spellthief = 6 - option_lich = 7 - default = 0 - - -class NewGamePlus(Choice): - """ - Puts the castle in new game plus mode which vastly increases enemy level, but increases gold gain by 50%. Not - recommended for those inexperienced to Rogue Legacy! - """ - display_name = "New Game Plus" - option_normal = 0 - option_new_game_plus = 1 - option_new_game_plus_2 = 2 - alias_hard = 1 - alias_brutal = 2 - default = 0 - - -class LevelScaling(Range): - """ - A percentage modifier for scaling enemy level as you continue throughout the castle. 100 means enemies will have - 100% level scaling (normal). Setting this too high will result in enemies with absurdly high levels, you have been - warned. - """ - display_name = "Enemy Level Scaling Percentage" - range_start = 1 - range_end = 300 - default = 100 - - -class FairyChestsPerZone(Range): - """ - Determines the number of Fairy Chests in a given zone that contain items. After these have been checked, only stat - bonuses can be found in Fairy Chests. - """ - display_name = "Fairy Chests Per Zone" - range_start = 0 - range_end = 15 - default = 1 - - -class ChestsPerZone(Range): - """ - Determines the number of Non-Fairy Chests in a given zone that contain items. After these have been checked, only - gold or stat bonuses can be found in Chests. - """ - display_name = "Chests Per Zone" - range_start = 20 - range_end = 50 - default = 20 - - -class UniversalFairyChests(Toggle): - """ - Determines if fairy chests should be combined into one pool instead of per zone, similar to Risk of Rain 2. - """ - display_name = "Universal Fairy Chests" - - -class UniversalChests(Toggle): - """ - Determines if non-fairy chests should be combined into one pool instead of per zone, similar to Risk of Rain 2. - """ - display_name = "Universal Non-Fairy Chests" - - -class Vendors(Choice): - """ - Determines where to place the Blacksmith and Enchantress unlocks in logic (or start with them unlocked). - """ - display_name = "Vendors" - option_start_unlocked = 0 - option_early = 1 - option_normal = 2 - option_anywhere = 3 - default = 1 - - -class Architect(Choice): - """ - Determines where the Architect sits in the item pool. - """ - display_name = "Architect" - option_start_unlocked = 0 - option_early = 1 - option_anywhere = 2 - option_disabled = 3 - alias_normal = 2 - default = 2 - - -class ArchitectFee(Range): - """ - Determines how large of a percentage the architect takes from the player when utilizing his services. 100 means he - takes all your gold. 0 means his services are free. - """ - display_name = "Architect Fee Percentage" - range_start = 0 - range_end = 100 - default = 40 - - -class DisableCharon(Toggle): - """ - Prevents Charon from taking your money when you re-enter the castle. Also removes Haggling from the Item Pool. - """ - display_name = "Disable Charon" - - -class RequirePurchasing(DefaultOnToggle): - """ - Determines where you will be required to purchase equipment and runes from the Blacksmith and Enchantress before - equipping them. If you disable require purchasing, Manor Renovations are scaled to take this into account. - """ - display_name = "Require Purchasing" - - -class ProgressiveBlueprints(Toggle): - """ - Instead of shuffling blueprints randomly into the pool, blueprint unlocks are progressively unlocked. You would get - Squire first, then Knight, etc., until finally Dark. - """ - display_name = "Progressive Blueprints" - - -class GoldGainMultiplier(Choice): - """ - Adjusts the multiplier for gaining gold from all sources. - """ - display_name = "Gold Gain Multiplier" - option_normal = 0 - option_quarter = 1 - option_half = 2 - option_double = 3 - option_quadruple = 4 - default = 0 - - -class NumberOfChildren(Range): - """ - Determines the number of offspring you can choose from on the lineage screen after a death. - """ - display_name = "Number of Children" - range_start = 1 - range_end = 5 - default = 3 - - -class AdditionalLadyNames(OptionSet): - """ - Set of additional names your potential offspring can have. If Allow Default Names is disabled, this is the only list - of names your children can have. The first value will also be your initial character's name depending on Starting - Gender. - """ - display_name = "Additional Lady Names" - -class AdditionalSirNames(OptionSet): - """ - Set of additional names your potential offspring can have. If Allow Default Names is disabled, this is the only list - of names your children can have. The first value will also be your initial character's name depending on Starting - Gender. - """ - display_name = "Additional Sir Names" - - -class AllowDefaultNames(DefaultOnToggle): - """ - Determines if the default names defined in the vanilla game are allowed to be used. Warning: Your world will not - generate if the number of Additional Names defined is less than the Number of Children value. - """ - display_name = "Allow Default Names" - - -class CastleScaling(Range): - """ - Adjusts the scaling factor for how big a castle can be. Larger castles scale enemies quicker and also take longer - to generate. 100 means normal castle size. - """ - display_name = "Castle Size Scaling Percentage" - range_start = 50 - range_end = 300 - default = 100 - - -class ChallengeBossKhidr(Choice): - """ - Determines if Neo Khidr replaces Khidr in their boss room. - """ - display_name = "Khidr" - option_vanilla = 0 - option_challenge = 1 - default = 0 - - -class ChallengeBossAlexander(Choice): - """ - Determines if Alexander the IV replaces Alexander in their boss room. - """ - display_name = "Alexander" - option_vanilla = 0 - option_challenge = 1 - default = 0 - - -class ChallengeBossLeon(Choice): - """ - Determines if Ponce de Freon replaces Ponce de Leon in their boss room. - """ - display_name = "Ponce de Leon" - option_vanilla = 0 - option_challenge = 1 - default = 0 - - -class ChallengeBossHerodotus(Choice): - """ - Determines if Astrodotus replaces Herodotus in their boss room. - """ - display_name = "Herodotus" - option_vanilla = 0 - option_challenge = 1 - default = 0 - - -class HealthUpPool(Range): - """ - Determines the number of Health Ups in the item pool. - """ - display_name = "Health Up Pool" - range_start = 0 - range_end = 15 - default = 15 - - -class ManaUpPool(Range): - """ - Determines the number of Mana Ups in the item pool. - """ - display_name = "Mana Up Pool" - range_start = 0 - range_end = 15 - default = 15 - - -class AttackUpPool(Range): - """ - Determines the number of Attack Ups in the item pool. - """ - display_name = "Attack Up Pool" - range_start = 0 - range_end = 15 - default = 15 - - -class MagicDamageUpPool(Range): - """ - Determines the number of Magic Damage Ups in the item pool. - """ - display_name = "Magic Damage Up Pool" - range_start = 0 - range_end = 15 - default = 15 - - -class ArmorUpPool(Range): - """ - Determines the number of Armor Ups in the item pool. - """ - display_name = "Armor Up Pool" - range_start = 0 - range_end = 10 - default = 10 - - -class EquipUpPool(Range): - """ - Determines the number of Equip Ups in the item pool. - """ - display_name = "Equip Up Pool" - range_start = 0 - range_end = 10 - default = 10 - - -class CritChanceUpPool(Range): - """ - Determines the number of Crit Chance Ups in the item pool. - """ - display_name = "Crit Chance Up Pool" - range_start = 0 - range_end = 5 - default = 5 - - -class CritDamageUpPool(Range): - """ - Determines the number of Crit Damage Ups in the item pool. - """ - display_name = "Crit Damage Up Pool" - range_start = 0 - range_end = 5 - default = 5 - - -class FreeDiaryOnGeneration(DefaultOnToggle): - """ - Allows the player to get a free diary check every time they regenerate the castle in the starting room. - """ - display_name = "Free Diary On Generation" - - -class AvailableClasses(OptionSet): - """ - List of classes that will be in the item pool to find. The upgraded form of the class will be added with it. - The upgraded form of your starting class will be available regardless. - """ - display_name = "Available Classes" - default = frozenset( - {"Knight", "Mage", "Barbarian", "Knave", "Shinobi", "Miner", "Spellthief", "Lich", "Dragon", "Traitor"} - ) - valid_keys = {"Knight", "Mage", "Barbarian", "Knave", "Shinobi", "Miner", "Spellthief", "Lich", "Dragon", "Traitor"} - - -@dataclass -class RLOptions(PerGameCommonOptions): - starting_gender: StartingGender - starting_class: StartingClass - available_classes: AvailableClasses - new_game_plus: NewGamePlus - fairy_chests_per_zone: FairyChestsPerZone - chests_per_zone: ChestsPerZone - universal_fairy_chests: UniversalFairyChests - universal_chests: UniversalChests - vendors: Vendors - architect: Architect - architect_fee: ArchitectFee - disable_charon: DisableCharon - require_purchasing: RequirePurchasing - progressive_blueprints: ProgressiveBlueprints - gold_gain_multiplier: GoldGainMultiplier - number_of_children: NumberOfChildren - free_diary_on_generation: FreeDiaryOnGeneration - khidr: ChallengeBossKhidr - alexander: ChallengeBossAlexander - leon: ChallengeBossLeon - herodotus: ChallengeBossHerodotus - health_pool: HealthUpPool - mana_pool: ManaUpPool - attack_pool: AttackUpPool - magic_damage_pool: MagicDamageUpPool - armor_pool: ArmorUpPool - equip_pool: EquipUpPool - crit_chance_pool: CritChanceUpPool - crit_damage_pool: CritDamageUpPool - allow_default_names: AllowDefaultNames - additional_lady_names: AdditionalLadyNames - additional_sir_names: AdditionalSirNames - death_link: DeathLink diff --git a/worlds/rogue_legacy/Presets.py b/worlds/rogue_legacy/Presets.py deleted file mode 100644 index 2dfeee64d8ca..000000000000 --- a/worlds/rogue_legacy/Presets.py +++ /dev/null @@ -1,61 +0,0 @@ -from typing import Any, Dict - -from .Options import Architect, GoldGainMultiplier, Vendors - -rl_options_presets: Dict[str, Dict[str, Any]] = { - # Example preset using only literal values. - "Unknown Fate": { - "progression_balancing": "random", - "accessibility": "random", - "starting_gender": "random", - "starting_class": "random", - "new_game_plus": "random", - "fairy_chests_per_zone": "random", - "chests_per_zone": "random", - "universal_fairy_chests": "random", - "universal_chests": "random", - "vendors": "random", - "architect": "random", - "architect_fee": "random", - "disable_charon": "random", - "require_purchasing": "random", - "progressive_blueprints": "random", - "gold_gain_multiplier": "random", - "number_of_children": "random", - "free_diary_on_generation": "random", - "khidr": "random", - "alexander": "random", - "leon": "random", - "herodotus": "random", - "health_pool": "random", - "mana_pool": "random", - "attack_pool": "random", - "magic_damage_pool": "random", - "armor_pool": "random", - "equip_pool": "random", - "crit_chance_pool": "random", - "crit_damage_pool": "random", - "allow_default_names": True, - "death_link": "random", - }, - # A preset I actually use, using some literal values and some from the option itself. - "Limited Potential": { - "progression_balancing": "disabled", - "fairy_chests_per_zone": 2, - "starting_class": "random", - "chests_per_zone": 30, - "vendors": Vendors.option_normal, - "architect": Architect.option_disabled, - "gold_gain_multiplier": GoldGainMultiplier.option_half, - "number_of_children": 2, - "free_diary_on_generation": False, - "health_pool": 10, - "mana_pool": 10, - "attack_pool": 10, - "magic_damage_pool": 10, - "armor_pool": 5, - "equip_pool": 10, - "crit_chance_pool": 5, - "crit_damage_pool": 5, - } -} diff --git a/worlds/rogue_legacy/Regions.py b/worlds/rogue_legacy/Regions.py deleted file mode 100644 index 61b0ef73ec78..000000000000 --- a/worlds/rogue_legacy/Regions.py +++ /dev/null @@ -1,114 +0,0 @@ -from typing import Dict, List, NamedTuple, Optional, TYPE_CHECKING - -from BaseClasses import MultiWorld, Region, Entrance -from .Locations import RLLocation, location_table, get_locations_by_category - -if TYPE_CHECKING: - from . import RLWorld - - -class RLRegionData(NamedTuple): - locations: Optional[List[str]] - region_exits: Optional[List[str]] - - -def create_regions(world: "RLWorld"): - regions: Dict[str, RLRegionData] = { - "Menu": RLRegionData(None, ["Castle Hamson"]), - "The Manor": RLRegionData([], []), - "Castle Hamson": RLRegionData([], ["Forest Abkhazia", "The Maya", "Land of Darkness", - "The Fountain Room", "The Manor"]), - "Forest Abkhazia": RLRegionData([], []), - "The Maya": RLRegionData([], []), - "Land of Darkness": RLRegionData([], []), - "The Fountain Room": RLRegionData([], None), - } - - # Artificially stagger diary spheres for progression. - for diary in range(0, 25): - region: str - if 0 <= diary < 6: - region = "Castle Hamson" - elif 6 <= diary < 12: - region = "Forest Abkhazia" - elif 12 <= diary < 18: - region = "The Maya" - elif 18 <= diary < 24: - region = "Land of Darkness" - else: - region = "The Fountain Room" - regions[region].locations.append(f"Diary {diary + 1}") - - # Manor & Special - for manor in get_locations_by_category("Manor").keys(): - regions["The Manor"].locations.append(manor) - for special in get_locations_by_category("Special").keys(): - regions["Castle Hamson"].locations.append(special) - - # Boss Rewards - regions["Castle Hamson"].locations.append("Castle Hamson Boss Reward") - regions["Forest Abkhazia"].locations.append("Forest Abkhazia Boss Reward") - regions["The Maya"].locations.append("The Maya Boss Reward") - regions["Land of Darkness"].locations.append("Land of Darkness Boss Reward") - - # Events - regions["Castle Hamson"].locations.append("Castle Hamson Boss Room") - regions["Forest Abkhazia"].locations.append("Forest Abkhazia Boss Room") - regions["The Maya"].locations.append("The Maya Boss Room") - regions["Land of Darkness"].locations.append("Land of Darkness Boss Room") - regions["The Fountain Room"].locations.append("Fountain Room") - - # Chests - chests = int(world.options.chests_per_zone) - for i in range(0, chests): - if world.options.universal_chests: - regions["Castle Hamson"].locations.append(f"Chest {i + 1}") - regions["Forest Abkhazia"].locations.append(f"Chest {i + 1 + chests}") - regions["The Maya"].locations.append(f"Chest {i + 1 + (chests * 2)}") - regions["Land of Darkness"].locations.append(f"Chest {i + 1 + (chests * 3)}") - else: - regions["Castle Hamson"].locations.append(f"Castle Hamson - Chest {i + 1}") - regions["Forest Abkhazia"].locations.append(f"Forest Abkhazia - Chest {i + 1}") - regions["The Maya"].locations.append(f"The Maya - Chest {i + 1}") - regions["Land of Darkness"].locations.append(f"Land of Darkness - Chest {i + 1}") - - # Fairy Chests - chests = int(world.options.fairy_chests_per_zone) - for i in range(0, chests): - if world.options.universal_fairy_chests: - regions["Castle Hamson"].locations.append(f"Fairy Chest {i + 1}") - regions["Forest Abkhazia"].locations.append(f"Fairy Chest {i + 1 + chests}") - regions["The Maya"].locations.append(f"Fairy Chest {i + 1 + (chests * 2)}") - regions["Land of Darkness"].locations.append(f"Fairy Chest {i + 1 + (chests * 3)}") - else: - regions["Castle Hamson"].locations.append(f"Castle Hamson - Fairy Chest {i + 1}") - regions["Forest Abkhazia"].locations.append(f"Forest Abkhazia - Fairy Chest {i + 1}") - regions["The Maya"].locations.append(f"The Maya - Fairy Chest {i + 1}") - regions["Land of Darkness"].locations.append(f"Land of Darkness - Fairy Chest {i + 1}") - - # Set up the regions correctly. - for name, data in regions.items(): - world.multiworld.regions.append(create_region(world.multiworld, world.player, name, data)) - - world.get_entrance("Castle Hamson").connect(world.get_region("Castle Hamson")) - world.get_entrance("The Manor").connect(world.get_region("The Manor")) - world.get_entrance("Forest Abkhazia").connect(world.get_region("Forest Abkhazia")) - world.get_entrance("The Maya").connect(world.get_region("The Maya")) - world.get_entrance("Land of Darkness").connect(world.get_region("Land of Darkness")) - world.get_entrance("The Fountain Room").connect(world.get_region("The Fountain Room")) - - -def create_region(multiworld: MultiWorld, player: int, name: str, data: RLRegionData): - region = Region(name, player, multiworld) - if data.locations: - for loc_name in data.locations: - loc_data = location_table.get(loc_name) - location = RLLocation(player, loc_name, loc_data.code if loc_data else None, region) - region.locations.append(location) - - if data.region_exits: - for exit in data.region_exits: - entrance = Entrance(player, exit, region) - region.exits.append(entrance) - - return region diff --git a/worlds/rogue_legacy/Rules.py b/worlds/rogue_legacy/Rules.py deleted file mode 100644 index 505bbdd63541..000000000000 --- a/worlds/rogue_legacy/Rules.py +++ /dev/null @@ -1,117 +0,0 @@ -from BaseClasses import CollectionState -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from . import RLWorld - - -def get_upgrade_total(world: "RLWorld") -> int: - return int(world.options.health_pool) + int(world.options.mana_pool) + \ - int(world.options.attack_pool) + int(world.options.magic_damage_pool) - - -def get_upgrade_count(state: CollectionState, player: int) -> int: - return state.count("Health Up", player) + state.count("Mana Up", player) + \ - state.count("Attack Up", player) + state.count("Magic Damage Up", player) - - -def has_vendors(state: CollectionState, player: int) -> bool: - return state.has_all({"Blacksmith", "Enchantress"}, player) - - -def has_upgrade_amount(state: CollectionState, player: int, amount: int) -> bool: - return get_upgrade_count(state, player) >= amount - - -def has_upgrades_percentage(state: CollectionState, world: "RLWorld", percentage: float) -> bool: - return has_upgrade_amount(state, world.player, round(get_upgrade_total(world) * (percentage / 100))) - - -def has_movement_rune(state: CollectionState, player: int) -> bool: - return state.has("Vault Runes", player) or state.has("Sprint Runes", player) or state.has("Sky Runes", player) - - -def has_fairy_progression(state: CollectionState, player: int) -> bool: - return state.has("Dragons", player) or (state.has("Enchantress", player) and has_movement_rune(state, player)) - - -def has_defeated_castle(state: CollectionState, player: int) -> bool: - return state.has("Defeat Khidr", player) or state.has("Defeat Neo Khidr", player) - - -def has_defeated_forest(state: CollectionState, player: int) -> bool: - return state.has("Defeat Alexander", player) or state.has("Defeat Alexander IV", player) - - -def has_defeated_tower(state: CollectionState, player: int) -> bool: - return state.has("Defeat Ponce de Leon", player) or state.has("Defeat Ponce de Freon", player) - - -def has_defeated_dungeon(state: CollectionState, player: int) -> bool: - return state.has("Defeat Herodotus", player) or state.has("Defeat Astrodotus", player) - - -def set_rules(world: "RLWorld", player: int): - # If 'vendors' are 'normal', then expect it to show up in the first half(ish) of the spheres. - if world.options.vendors == "normal": - world.get_location("Forest Abkhazia Boss Reward").access_rule = \ - lambda state: has_vendors(state, player) - - # Gate each manor location so everything isn't dumped into sphere 1. - manor_rules = { - "Defeat Khidr" if world.options.khidr == "vanilla" else "Defeat Neo Khidr": [ - "Manor - Left Wing Window", - "Manor - Left Wing Rooftop", - "Manor - Right Wing Window", - "Manor - Right Wing Rooftop", - "Manor - Left Big Base", - "Manor - Right Big Base", - "Manor - Left Tree 1", - "Manor - Left Tree 2", - "Manor - Right Tree", - ], - "Defeat Alexander" if world.options.alexander == "vanilla" else "Defeat Alexander IV": [ - "Manor - Left Big Upper 1", - "Manor - Left Big Upper 2", - "Manor - Left Big Windows", - "Manor - Left Big Rooftop", - "Manor - Left Far Base", - "Manor - Left Far Roof", - "Manor - Left Extension", - "Manor - Right Big Upper", - "Manor - Right Big Rooftop", - "Manor - Right Extension", - ], - "Defeat Ponce de Leon" if world.options.leon == "vanilla" else "Defeat Ponce de Freon": [ - "Manor - Right High Base", - "Manor - Right High Upper", - "Manor - Right High Tower", - "Manor - Observatory Base", - "Manor - Observatory Telescope", - ] - } - - # Set rules for manor locations. - for event, locations in manor_rules.items(): - for location in locations: - world.get_location(location).access_rule = lambda state: state.has(event, player) - - # Set rules for fairy chests to decrease headache of expectation to find non-movement fairy chests. - for fairy_location in [location for location in world.multiworld.get_locations(player) if "Fairy" in location.name]: - fairy_location.access_rule = lambda state: has_fairy_progression(state, player) - - # Region rules. - world.get_entrance("Forest Abkhazia").access_rule = \ - lambda state: has_upgrades_percentage(state, world, 12.5) and has_defeated_castle(state, player) - - world.get_entrance("The Maya").access_rule = \ - lambda state: has_upgrades_percentage(state, world, 25) and has_defeated_forest(state, player) - - world.get_entrance("Land of Darkness").access_rule = \ - lambda state: has_upgrades_percentage(state, world, 37.5) and has_defeated_tower(state, player) - - world.get_entrance("The Fountain Room").access_rule = \ - lambda state: has_upgrades_percentage(state, world, 50) and has_defeated_dungeon(state, player) - - # Win condition. - world.multiworld.completion_condition[player] = lambda state: state.has("Defeat The Fountain", player) diff --git a/worlds/rogue_legacy/__init__.py b/worlds/rogue_legacy/__init__.py deleted file mode 100644 index 7ffdd459db48..000000000000 --- a/worlds/rogue_legacy/__init__.py +++ /dev/null @@ -1,243 +0,0 @@ -from typing import List - -from BaseClasses import Tutorial -from worlds.AutoWorld import WebWorld, World -from .Items import RLItem, RLItemData, event_item_table, get_items_by_category, item_table -from .Locations import RLLocation, location_table -from .Options import RLOptions -from .Presets import rl_options_presets -from .Regions import create_regions -from .Rules import set_rules - - -class RLWeb(WebWorld): - theme = "stone" - tutorials = [Tutorial( - "Multiworld Setup Guide", - "A guide to setting up the Rogue Legacy Randomizer software on your computer. This guide covers single-player, " - "multiworld, and related software.", - "English", - "rogue-legacy_en.md", - "rogue-legacy/en", - ["Phar"] - )] - bug_report_page = "https://github.com/ThePhar/RogueLegacyRandomizer/issues/new?assignees=&labels=bug&template=" \ - "report-an-issue---.md&title=%5BIssue%5D" - options_presets = rl_options_presets - - -class RLWorld(World): - """ - Rogue Legacy is a genealogical rogue-"LITE" where anyone can be a hero. Each time you die, your child will succeed - you. Every child is unique. One child might be colorblind, another might have vertigo-- they could even be a dwarf. - But that's OK, because no one is perfect, and you don't have to be to succeed. - """ - game = "Rogue Legacy" - options_dataclass = RLOptions - options: RLOptions - topology_present = True - required_client_version = (0, 3, 5) - web = RLWeb() - - item_name_to_id = {name: data.code for name, data in item_table.items() if data.code is not None} - location_name_to_id = {name: data.code for name, data in location_table.items() if data.code is not None} - - def fill_slot_data(self) -> dict: - return self.options.as_dict(*[name for name in self.options_dataclass.type_hints.keys()]) - - def generate_early(self): - # Check validation of names. - additional_lady_names = len(self.options.additional_lady_names.value) - additional_sir_names = len(self.options.additional_sir_names.value) - if not self.options.allow_default_names: - if additional_lady_names < int(self.options.number_of_children): - raise Exception( - f"allow_default_names is off, but not enough names are defined in additional_lady_names. " - f"Expected {int(self.options.number_of_children)}, Got {additional_lady_names}") - - if additional_sir_names < int(self.options.number_of_children): - raise Exception( - f"allow_default_names is off, but not enough names are defined in additional_sir_names. " - f"Expected {int(self.options.number_of_children)}, Got {additional_sir_names}") - - def create_items(self): - item_pool: List[RLItem] = [] - total_locations = len(self.multiworld.get_unfilled_locations(self.player)) - for name, data in item_table.items(): - quantity = data.max_quantity - - # Architect - if name == "Architect": - if self.options.architect == "disabled": - continue - if self.options.architect == "start_unlocked": - self.multiworld.push_precollected(self.create_item(name)) - continue - if self.options.architect == "early": - self.multiworld.local_early_items[self.player]["Architect"] = 1 - - # Blacksmith and Enchantress - if name == "Blacksmith" or name == "Enchantress": - if self.options.vendors == "start_unlocked": - self.multiworld.push_precollected(self.create_item(name)) - continue - if self.options.vendors == "early": - self.multiworld.local_early_items[self.player]["Blacksmith"] = 1 - self.multiworld.local_early_items[self.player]["Enchantress"] = 1 - - # Haggling - if name == "Haggling" and self.options.disable_charon: - continue - - # Blueprints - if data.category == "Blueprints": - # No progressive blueprints if progressive_blueprints are disabled. - if name == "Progressive Blueprints" and not self.options.progressive_blueprints: - continue - # No distinct blueprints if progressive_blueprints are enabled. - elif name != "Progressive Blueprints" and self.options.progressive_blueprints: - continue - - # Classes - if data.category == "Classes": - if name == "Progressive Knights": - if "Knight" not in self.options.available_classes: - continue - - if self.options.starting_class == "knight": - quantity = 1 - if name == "Progressive Mages": - if "Mage" not in self.options.available_classes: - continue - - if self.options.starting_class == "mage": - quantity = 1 - if name == "Progressive Barbarians": - if "Barbarian" not in self.options.available_classes: - continue - - if self.options.starting_class == "barbarian": - quantity = 1 - if name == "Progressive Knaves": - if "Knave" not in self.options.available_classes: - continue - - if self.options.starting_class == "knave": - quantity = 1 - if name == "Progressive Miners": - if "Miner" not in self.options.available_classes: - continue - - if self.options.starting_class == "miner": - quantity = 1 - if name == "Progressive Shinobis": - if "Shinobi" not in self.options.available_classes: - continue - - if self.options.starting_class == "shinobi": - quantity = 1 - if name == "Progressive Liches": - if "Lich" not in self.options.available_classes: - continue - - if self.options.starting_class == "lich": - quantity = 1 - if name == "Progressive Spellthieves": - if "Spellthief" not in self.options.available_classes: - continue - - if self.options.starting_class == "spellthief": - quantity = 1 - if name == "Dragons": - if "Dragon" not in self.options.available_classes: - continue - if name == "Traitors": - if "Traitor" not in self.options.available_classes: - continue - - # Skills - if name == "Health Up": - quantity = self.options.health_pool.value - elif name == "Mana Up": - quantity = self.options.mana_pool.value - elif name == "Attack Up": - quantity = self.options.attack_pool.value - elif name == "Magic Damage Up": - quantity = self.options.magic_damage_pool.value - elif name == "Armor Up": - quantity = self.options.armor_pool.value - elif name == "Equip Up": - quantity = self.options.equip_pool.value - elif name == "Crit Chance Up": - quantity = self.options.crit_chance_pool.value - elif name == "Crit Damage Up": - quantity = self.options.crit_damage_pool.value - - # Ignore filler, it will be added in a later stage. - if data.category == "Filler": - continue - - item_pool += [self.create_item(name) for _ in range(0, quantity)] - - # Fill any empty locations with filler items. - while len(item_pool) < total_locations: - item_pool.append(self.create_item(self.get_filler_item_name())) - - self.multiworld.itempool += item_pool - - def get_filler_item_name(self) -> str: - fillers = get_items_by_category("Filler") - weights = [data.weight for data in fillers.values()] - return self.random.choices([filler for filler in fillers.keys()], weights, k=1)[0] - - def create_item(self, name: str) -> RLItem: - data = item_table[name] - return RLItem(name, data.classification, data.code, self.player) - - def create_event(self, name: str) -> RLItem: - data = event_item_table[name] - return RLItem(name, data.classification, data.code, self.player) - - def set_rules(self): - set_rules(self, self.player) - - def create_regions(self): - create_regions(self) - self._place_events() - - def _place_events(self): - # Fountain - self.multiworld.get_location("Fountain Room", self.player).place_locked_item( - self.create_event("Defeat The Fountain")) - - # Khidr / Neo Khidr - if self.options.khidr == "vanilla": - self.multiworld.get_location("Castle Hamson Boss Room", self.player).place_locked_item( - self.create_event("Defeat Khidr")) - else: - self.multiworld.get_location("Castle Hamson Boss Room", self.player).place_locked_item( - self.create_event("Defeat Neo Khidr")) - - # Alexander / Alexander IV - if self.options.alexander == "vanilla": - self.multiworld.get_location("Forest Abkhazia Boss Room", self.player).place_locked_item( - self.create_event("Defeat Alexander")) - else: - self.multiworld.get_location("Forest Abkhazia Boss Room", self.player).place_locked_item( - self.create_event("Defeat Alexander IV")) - - # Ponce de Leon / Ponce de Freon - if self.options.leon == "vanilla": - self.multiworld.get_location("The Maya Boss Room", self.player).place_locked_item( - self.create_event("Defeat Ponce de Leon")) - else: - self.multiworld.get_location("The Maya Boss Room", self.player).place_locked_item( - self.create_event("Defeat Ponce de Freon")) - - # Herodotus / Astrodotus - if self.options.herodotus == "vanilla": - self.multiworld.get_location("Land of Darkness Boss Room", self.player).place_locked_item( - self.create_event("Defeat Herodotus")) - else: - self.multiworld.get_location("Land of Darkness Boss Room", self.player).place_locked_item( - self.create_event("Defeat Astrodotus")) diff --git a/worlds/rogue_legacy/docs/en_Rogue Legacy.md b/worlds/rogue_legacy/docs/en_Rogue Legacy.md deleted file mode 100644 index dd203c73ac26..000000000000 --- a/worlds/rogue_legacy/docs/en_Rogue Legacy.md +++ /dev/null @@ -1,34 +0,0 @@ -# Rogue Legacy (PC) - -## Where is the options page? - -The [player options page for this game](../player-options) contains most of the options you need to -configure and export a config file. Some options can only be made in YAML, but an explanation can be found in the -[template yaml here](../../../static/generated/configs/Rogue%20Legacy.yaml). - -## What does randomization do to this game? - -Rogue Legacy Randomizer takes all the classes, skills, runes, and blueprints and spreads them out into chests, the manor -upgrade screen, bosses, and some special individual locations. The goal is to become powerful enough to defeat the four -zone bosses and then defeat The Fountain. - -## What items and locations get shuffled? -All the skill upgrades, class upgrades, runes packs, and equipment packs are shuffled in the manor upgrade screen, diary -checks, chests and fairy chests, and boss rewards. Skill upgrades are also grouped in packs of 5 to make the finding of -stats less of a chore. Runes and Equipment are also grouped together. - -Some additional locations that can contain items are the Jukebox, the Portraits, and the mini-game rewards. - -## Which items can be in another player's world? - -Any of the items which can be shuffled may also be placed into another player's world. It is possible to choose to limit -certain items to your own world. -## When the player receives an item, what happens? - -When the player receives an item, your character will hold the item above their head and display it to the world. It's -good for business! - -## What do I do if I encounter a bug with the game? - -Please reach out to Phar#4444 on Discord or you can drop a bug report on the -[GitHub page for Rogue Legacy Randomizer](https://github.com/ThePhar/RogueLegacyRandomizer/issues/new?assignees=&labels=bug&template=report-an-issue---.md&title=%5BIssue%5D). diff --git a/worlds/rogue_legacy/docs/rogue-legacy_en.md b/worlds/rogue_legacy/docs/rogue-legacy_en.md deleted file mode 100644 index fc9f6920178d..000000000000 --- a/worlds/rogue_legacy/docs/rogue-legacy_en.md +++ /dev/null @@ -1,35 +0,0 @@ -# Rogue Legacy Randomizer Setup Guide - -## Required Software - -- Rogue Legacy Randomizer from the - [Rogue Legacy Randomizer Releases Page](https://github.com/ThePhar/RogueLegacyRandomizer/releases) - -## Recommended Installation Instructions - -Please read the README file on the -[Rogue Legacy Randomizer GitHub](https://github.com/ThePhar/RogueLegacyRandomizer/blob/master/README.md) page for -up-to-date installation instructions. - -## Configuring your YAML file - -### What is a YAML file and why do I need one? - -Your YAML file contains a set of configuration options which provide the generator with information about how it should -generate your game. Each player of a multiworld will provide their own YAML file. This setup allows each player to enjoy -an experience customized for their taste, and different players in the same multiworld can all have different options. - -### Where do I get a YAML file? - -you can customize your options by visiting the [Rogue Legacy Options Page](/games/Rogue%20Legacy/player-options). - -### Connect to the MultiServer - -Once in game, press the start button and the AP connection screen should appear. You will fill out the hostname, port, -slot name, and password (if applicable). You should only need to fill out hostname, port, and password if the server -provides an alternative one to the default values. - -### Play the game - -Once you have entered the required values, you go to Connect and then select Confirm on the "Ready to Start" screen. Now -you're off to start your legacy! diff --git a/worlds/rogue_legacy/test/TestUnique.py b/worlds/rogue_legacy/test/TestUnique.py deleted file mode 100644 index 1ae9968d5519..000000000000 --- a/worlds/rogue_legacy/test/TestUnique.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Dict - -from . import RLTestBase -from ..Items import item_table -from ..Locations import location_table - - -class UniqueTest(RLTestBase): - @staticmethod - def test_item_ids_are_all_unique(): - item_ids: Dict[int, str] = {} - for name, data in item_table.items(): - assert data.code not in item_ids.keys(), f"'{name}': {data.code}, is not unique. " \ - f"'{item_ids[data.code]}' also has this identifier." - item_ids[data.code] = name - - @staticmethod - def test_location_ids_are_all_unique(): - location_ids: Dict[int, str] = {} - for name, data in location_table.items(): - assert data.code not in location_ids.keys(), f"'{name}': {data.code}, is not unique. " \ - f"'{location_ids[data.code]}' also has this identifier." - location_ids[data.code] = name diff --git a/worlds/rogue_legacy/test/__init__.py b/worlds/rogue_legacy/test/__init__.py deleted file mode 100644 index 3346476ba644..000000000000 --- a/worlds/rogue_legacy/test/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from test.bases import WorldTestBase - - -class RLTestBase(WorldTestBase): - game = "Rogue Legacy" From 7a6fb5e35b471ef196437dd97d23fd26402d903e Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:28:18 +0200 Subject: [PATCH 0550/1218] Revert "Core: Take Counter back out of RestrictedUnpickler" (#5184) * Revert "Core: Take Counter back out of RestrictedUnpickler #5169" This reverts commit 95e09c8e2a681ecd5666822b04fe7fed3ed9dec1. * Update Utils.py --- Utils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Utils.py b/Utils.py index 6212b9328830..5697bb162ace 100644 --- a/Utils.py +++ b/Utils.py @@ -441,6 +441,10 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: def find_class(self, module: str, name: str) -> type: if module == "builtins" and name in safe_builtins: return getattr(builtins, name) + # used by OptionCounter + # necessary because the actual Options class instances are pickled when transfered to WebHost generation pool + if module == "collections" and name == "Counter": + return collections.Counter # used by MultiServer -> savegame/multidata if module == "NetUtils" and name in {"NetworkItem", "ClientStatus", "Hint", "SlotType", "NetworkSlot", "HintStatus"}: From a79423534c30de502a71944a5ec1d95ff32847fe Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Fri, 11 Jul 2025 18:44:26 -0400 Subject: [PATCH 0551/1218] LADX: Update marin.txt (#5178) --- worlds/ladx/LADXR/patches/marin.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/worlds/ladx/LADXR/patches/marin.txt b/worlds/ladx/LADXR/patches/marin.txt index a179e35fc6fb..782f4129ce6e 100644 --- a/worlds/ladx/LADXR/patches/marin.txt +++ b/worlds/ladx/LADXR/patches/marin.txt @@ -255,7 +255,6 @@ Try Bumper Stickers! Try Castlevania 64! Try Celeste 64! Try ChecksFinder! -Try Clique! Try Dark Souls III! Try DLCQuest! Try Donkey Kong Country 3! @@ -268,6 +267,7 @@ Try A Hat in Time! Try Heretic! Try Hollow Knight! Try Hylics 2! +Try Jak and Daxter: The Precursor Legacy! Try Kingdom Hearts 2! Try Kirby's Dream Land 3! Try Landstalker - The Treasures of King Nole! @@ -288,11 +288,10 @@ Try Pokemon Emerald! Try Pokemon Red and Blue! Try Raft! Try Risk of Rain 2! -Try Rogue Legacy! Try Secret of Evermore! +Try shapez! Try Shivers! Try A Short Hike! -Try Slay the Spire! Try SMZ3! Try Sonic Adventure 2 Battle! Try Starcraft 2! @@ -300,6 +299,7 @@ Try Stardew Valley! Try Subnautica! Try Sudoku! Try Super Mario 64! +Try Super Mario Land 2: 6 Golden Coins! Try Super Mario World! Try Super Metroid! Try Terraria! @@ -312,7 +312,6 @@ Try The Witness! Try Yoshi's Island! Try Yu-Gi-Oh! 2006! Try Zillion! -Try Zork Grand Inquisitor! Try Old School Runescape! Try Kingdom Hearts! Try Mega Man 2! @@ -369,7 +368,6 @@ Have they added Among Us to AP yet? Every copy of LADX is personalized, David. Looks like you're going on A Short Hike. Bring back feathers please? Functioning Brain is at...\nWait. This isn't Witness. Wrong game, sorry. -Don't forget to check your Clique!\nIf, y'know, you have one. No pressure... :3 Sorry ######, but your progression item is in another world. &newgames\n&oldgames From 909565e5d958459093014e134ea21b18767cd1fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sat, 12 Jul 2025 07:12:04 -0400 Subject: [PATCH 0552/1218] Stardew Valley: Remove Rarecrow Locations from Night Market when Museumsanity is Disabled (#5146) --- worlds/stardew_valley/locations.py | 3 ++ worlds/stardew_valley/logic/museum_logic.py | 8 --- .../stardew_valley/test/rules/TestMuseum.py | 50 ++++++++++++++++++- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/worlds/stardew_valley/locations.py b/worlds/stardew_valley/locations.py index 0d621fda49ee..fa4d50ce792a 100644 --- a/worlds/stardew_valley/locations.py +++ b/worlds/stardew_valley/locations.py @@ -279,6 +279,9 @@ def extend_festival_locations(randomized_locations: List[LocationData], options: return festival_locations = locations_by_tag[LocationTags.FESTIVAL] + if not options.museumsanity: + festival_locations = [location for location in festival_locations if location.name not in ("Rarecrow #7 (Tanuki)", "Rarecrow #8 (Tribal Mask)")] + randomized_locations.extend(festival_locations) extend_hard_festival_locations(randomized_locations, options) extend_desert_festival_chef_locations(randomized_locations, options, random) diff --git a/worlds/stardew_valley/logic/museum_logic.py b/worlds/stardew_valley/logic/museum_logic.py index 2237cd89ea65..21718db27c9f 100644 --- a/worlds/stardew_valley/logic/museum_logic.py +++ b/worlds/stardew_valley/logic/museum_logic.py @@ -1,13 +1,5 @@ -from typing import Union - from Utils import cache_self1 -from .action_logic import ActionLogicMixin from .base_logic import BaseLogic, BaseLogicMixin -from .has_logic import HasLogicMixin -from .received_logic import ReceivedLogicMixin -from .region_logic import RegionLogicMixin -from .time_logic import TimeLogicMixin -from .tool_logic import ToolLogicMixin from .. import options from ..data.museum_data import MuseumItem, all_museum_items, all_museum_artifacts, all_museum_minerals from ..stardew_rule import StardewRule, False_ diff --git a/worlds/stardew_valley/test/rules/TestMuseum.py b/worlds/stardew_valley/test/rules/TestMuseum.py index 231bbafe2290..1a22e8800c5d 100644 --- a/worlds/stardew_valley/test/rules/TestMuseum.py +++ b/worlds/stardew_valley/test/rules/TestMuseum.py @@ -1,12 +1,16 @@ from collections import Counter +from unittest.mock import patch from ..bases import SVTestBase -from ...options import Museumsanity +from ..options import presets +from ... import options, StardewLogic, StardewRule +from ...logic.museum_logic import MuseumLogic +from ...stardew_rule import true_, LiteralStardewRule class TestMuseumMilestones(SVTestBase): options = { - Museumsanity.internal_name: Museumsanity.option_milestones + options.Museumsanity: options.Museumsanity.option_milestones } def test_50_milestone(self): @@ -14,3 +18,45 @@ def test_50_milestone(self): milestone_rule = self.world.logic.museum.can_find_museum_items(50) self.assert_rule_false(milestone_rule, self.multiworld.state) + + +class DisabledMuseumRule(LiteralStardewRule): + value = False + + def __or__(self, other) -> StardewRule: + return other + + def __and__(self, other) -> StardewRule: + return self + + def __repr__(self): + return "Disabled Museum Rule" + + +class TestMuseumsanityDisabledExcludesMuseumDonationsFromOtherLocations(SVTestBase): + options = { + **presets.allsanity_mods_6_x_x(), + options.Museumsanity.internal_name: options.Museumsanity.option_none + } + + def test_museum_donations_are_never_required_in_any_locations(self): + with patch("worlds.stardew_valley.logic.museum_logic.MuseumLogic") as MockMuseumLogic: + museum_logic: MuseumLogic = MockMuseumLogic.return_value + museum_logic.can_donate_museum_items.return_value = DisabledMuseumRule() + museum_logic.can_donate_museum_artifacts.return_value = DisabledMuseumRule() + museum_logic.can_find_museum_artifacts.return_value = DisabledMuseumRule() + museum_logic.can_find_museum_minerals.return_value = DisabledMuseumRule() + museum_logic.can_find_museum_items.return_value = DisabledMuseumRule() + museum_logic.can_complete_museum.return_value = DisabledMuseumRule() + museum_logic.can_donate.return_value = DisabledMuseumRule() + # Allowing calls to museum rules since a lot of other logic depends on it, for minerals for instance. + museum_logic.can_find_museum_item.return_value = true_ + + regions = {region.name for region in self.multiworld.regions} + self.world.logic = StardewLogic(self.player, self.world.options, self.world.content, regions) + self.world.set_rules() + + self.collect_everything() + for location in self.get_real_locations(): + with self.subTest(location.name): + self.assert_can_reach_location(location) From 585cbf95a6d1b65facd1f0058ba49c6174b24a00 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sat, 12 Jul 2025 07:14:34 -0400 Subject: [PATCH 0553/1218] TUNIC: Add UT Support for Breakables (#5182) --- worlds/tunic/ut_stuff.py | 492 +++++++++++++++++++++++++++++++-------- 1 file changed, 399 insertions(+), 93 deletions(-) diff --git a/worlds/tunic/ut_stuff.py b/worlds/tunic/ut_stuff.py index 8296452c73ec..82d58eaeb8dc 100644 --- a/worlds/tunic/ut_stuff.py +++ b/worlds/tunic/ut_stuff.py @@ -67,99 +67,6 @@ def map_page_index(data: Any) -> int: # mapping of everything after the second to last slash and the location id # lua used for the name: string.match(full_name, "[^/]*/[^/]*$") poptracker_data: dict[str, int] = { - "[Powered Secret Room] Chest/Follow the Purple Energy Road": 509342400, - "[Entryway] Chest/Mind the Slorms": 509342401, - "[Third Room] Beneath Platform Chest/Run from the tentacles!": 509342402, - "[Third Room] Tentacle Chest/Water Sucks": 509342403, - "[Entryway] Obscured Behind Waterfall/You can just go in there": 509342404, - "[Save Room] Upper Floor Chest 1/Through the Power of Prayer": 509342405, - "[Save Room] Upper Floor Chest 2/Above the Fox Shrine": 509342406, - "[Second Room] Underwater Chest/Hidden Passage": 509342407, - "[Back Corridor] Right Secret/Hidden Path": 509342408, - "[Back Corridor] Left Secret/Behind the Slorms": 509342409, - "[Second Room] Obscured Behind Waterfall/Just go in there": 509342410, - "[Side Room] Chest By Pots/Just Climb up There": 509342411, - "[Side Room] Chest By Phrends/So Many Phrends!": 509342412, - "[Second Room] Page/Ruined Atoll Map": 509342413, - "[Passage To Dark Tomb] Page Pickup/Siege Engine": 509342414, - "[1F] Guarded By Lasers/Beside 3 Miasma Seekers": 509342415, - "[1F] Near Spikes/Mind the Miasma Seeker": 509342416, - "Birdcage Room/[2F] Bird Room": 509342417, - "[2F] Entryway Upper Walkway/Overlooking Miasma": 509342418, - "[1F] Library/By the Books": 509342419, - "[2F] Library/Behind the Ladder": 509342420, - "[2F] Guarded By Lasers/Before the big reveal...": 509342421, - "Birdcage Room/[2F] Bird Room Secret": 509342422, - "[1F] Library Secret/Pray to the Wallman": 509342423, - "Spike Maze Near Exit/Watch out!": 509342424, - "2nd Laser Room/Can you roll?": 509342425, - "1st Laser Room/Use a bomb?": 509342426, - "Spike Maze Upper Walkway/Just walk right!": 509342427, - "Skulls Chest/Move the Grave": 509342428, - "Spike Maze Near Stairs/In the Corner": 509342429, - "1st Laser Room Obscured/Follow the red laser of death": 509342430, - "Guardhouse 2 - Upper Floor/In the Mound": 509342431, - "Guardhouse 2 - Bottom Floor Secret/Hidden Hallway": 509342432, - "Guardhouse 1 Obscured/Upper Floor Obscured": 509342433, - "Guardhouse 1/Upper Floor": 509342434, - "Guardhouse 1 Ledge HC/Dancing Fox Spirit Holy Cross": 509342435, - "Golden Obelisk Holy Cross/Use the Holy Cross": 509342436, - "Ice Rod Grapple Chest/Freeze the Blob and ascend With Orb": 509342437, - "Above Save Point/Chest": 509342438, - "Above Save Point Obscured/Hidden Path": 509342439, - "Guardhouse 1 Ledge/From Guardhouse 1 Chest": 509342440, - "Near Save Point/Chest": 509342441, - "Ambushed by Spiders/Beneath Spider Chest": 509342442, - "Near Telescope/Up on the Wall": 509342443, - "Ambushed by Spiders/Spider Chest": 509342444, - "Lower Dash Chest/Dash Across": 509342445, - "Lower Grapple Chest/Grapple Across": 509342446, - "Bombable Wall/Follow the Flowers": 509342447, - "Page On Teleporter/Page": 509342448, - "Forest Belltower Save Point/Near Save Point": 509342449, - "Forest Belltower - After Guard Captain/Chest": 509342450, - "East Bell/Forest Belltower - Obscured Near Bell Top Floor": 509342451, - "Forest Belltower Obscured/Obscured Beneath Bell Bottom Floor": 509342452, - "Forest Belltower Page/Page Pickup": 509342453, - "Forest Grave Path - Holy Cross Code by Grave/Single Money Chest": 509342454, - "Forest Grave Path - Above Gate/Chest": 509342455, - "Forest Grave Path - Obscured Chest/Behind the Trees": 509342456, - "Forest Grave Path - Upper Walkway/From the top of the Guardhouse": 509342457, - "The Hero's Sword/Forest Grave Path - Sword Pickup": 509342458, - "The Hero's Sword/Hero's Grave - Tooth Relic": 509342459, - "Fortress Courtyard - From East Belltower/Crack in the Wall": 509342460, - "Fortress Leaf Piles - Secret Chest/Dusty": 509342461, - "Fortress Arena/Hexagon Red": 509342462, - "Fortress Arena/Siege Engine|Vault Key Pickup": 509342463, - "Fortress East Shortcut - Chest Near Slimes/Mind the Custodians": 509342464, - "[West Wing] Candles Holy Cross/Use the Holy Cross": 509342465, - "Westmost Upper Room/[West Wing] Dark Room Chest 1": 509342466, - "Westmost Upper Room/[West Wing] Dark Room Chest 2": 509342467, - "[East Wing] Bombable Wall/Bomb the Wall": 509342468, - "[West Wing] Page Pickup/He will never visit the Far Shore": 509342469, - "Fortress Grave Path - Upper Walkway/Go Around the East Wing": 509342470, - "Vault Hero's Grave/Fortress Grave Path - Chest Right of Grave": 509342471, - "Vault Hero's Grave/Fortress Grave Path - Obscured Chest Left of Grave": 509342472, - "Vault Hero's Grave/Hero's Grave - Flowers Relic": 509342473, - "Bridge/Chest": 509342474, - "Cell Chest 1/Drop the Shortcut Rope": 509342475, - "Obscured Behind Waterfall/Muffling Bell": 509342476, - "Back Room Chest/Lose the Lure or take 2 Damage": 509342477, - "Cell Chest 2/Mind the Custodian": 509342478, - "Near Vault/Already Stolen": 509342479, - "Slorm Room/Tobias was Trapped Here Once...": 509342480, - "Escape Chest/Don't Kick Fimbleton!": 509342481, - "Grapple Above Hot Tub/Look Up": 509342482, - "Above Vault/Obscured Doorway Ledge": 509342483, - "Main Room Top Floor/Mind the Adult Frog": 509342484, - "Main Room Bottom Floor/Altar Chest": 509342485, - "Side Room Secret Passage/Upper Right Corner": 509342486, - "Side Room Chest/Oh No! Our Frogs! They're Dead!": 509342487, - "Side Room Grapple Secret/Grapple on Over": 509342488, - "Magic Orb Pickup/Frult Meeting": 509342489, - "The Librarian/Hexagon Green": 509342490, - "Library Hall/Holy Cross Chest": 509342491, - "Library Lab Chest by Shrine 2/Chest": 509342492, "Library Lab Chest by Shrine 1/Chest": 509342493, "Library Lab Chest by Shrine 3/Chest": 509342494, "Library Lab by Fuse/Behind Chalkboard": 509342495, @@ -369,6 +276,405 @@ def map_page_index(data: Any) -> int: "[North] Page Pickup/Survival Tips": 509342699, "[Southeast Lowlands] Ice Dagger Pickup/Ice Dagger Cave": 509342700, "Hero's Grave/Effigy Relic": 509342701, + "[East] Bombable Wall/Break Bombable Wall": 509350705, + "[West] Upper Area Bombable Wall/Break Bombable Wall": 509350704, + "[East Wing] Bombable Wall/Break Bombable Wall": 509350703, + "Bombable Wall/Break Bombable Wall": 509350702, + "[Northwest] Bombable Wall/Break Bombable Wall": 509350701, + "[Southwest] Bombable Wall Near Fountain/Break Bombable Wall": 509350700, + "Cube Cave/Break Bombable Wall": 509350699, + "[Central] Bombable Wall/Break Bombable Wall": 509350698, + "Purgatory Pots/Pot 33": 509350697, + "Purgatory Pots/Pot 32": 509350696, + "Purgatory Pots/Pot 31": 509350695, + "Purgatory Pots/Pot 30": 509350694, + "Purgatory Pots/Pot 29": 509350693, + "Purgatory Pots/Pot 28": 509350692, + "Purgatory Pots/Pot 27": 509350691, + "Purgatory Pots/Pot 26": 509350690, + "Purgatory Pots/Pot 25": 509350689, + "Purgatory Pots/Pot 24": 509350688, + "Purgatory Pots/Pot 23": 509350687, + "Purgatory Pots/Pot 22": 509350686, + "Purgatory Pots/Pot 21": 509350685, + "Purgatory Pots/Pot 20": 509350684, + "Purgatory Pots/Pot 19": 509350683, + "Purgatory Pots/Pot 18": 509350682, + "Purgatory Pots/Pot 17": 509350681, + "Purgatory Pots/Pot 16": 509350680, + "Purgatory Pots/Pot 15": 509350679, + "Purgatory Pots/Pot 14": 509350678, + "Purgatory Pots/Pot 13": 509350677, + "Purgatory Pots/Pot 12": 509350676, + "Purgatory Pots/Pot 11": 509350675, + "Purgatory Pots/Pot 10": 509350674, + "Purgatory Pots/Pot 9": 509350673, + "Purgatory Pots/Pot 8": 509350672, + "Purgatory Pots/Pot 7": 509350671, + "Purgatory Pots/Pot 6": 509350670, + "Purgatory Pots/Pot 5": 509350669, + "Purgatory Pots/Pot 4": 509350668, + "Purgatory Pots/Pot 3": 509350667, + "Purgatory Pots/Pot 2": 509350666, + "Purgatory Pots/Pot 1": 509350665, + "[1F] Pots by Stairs/Pot 2": 509350664, + "[1F] Pots by Stairs/Pot 1": 509350663, + "Crates/Crate 9": 509350662, + "Crates/Crate 8": 509350661, + "Crates/Crate 7": 509350660, + "Crates/Crate 6": 509350659, + "Crates/Crate 5": 509350658, + "Crates/Crate 4": 509350657, + "Crates/Crate 3": 509350656, + "Crates/Crate 2": 509350655, + "Crates/Crate 1": 509350654, + "[Lowlands] Crates/Crate 2": 509350653, + "[Lowlands] Crates/Crate 1": 509350652, + "[West] Near Isolated Chest/Crate 5": 509350651, + "[West] Near Isolated Chest/Crate 4": 509350650, + "[West] Near Isolated Chest/Crate 3": 509350649, + "[West] Near Isolated Chest/Crate 2": 509350648, + "[West] Near Isolated Chest/Crate 1": 509350647, + "[West] Crates by Shooting Range/Crate 5": 509350646, + "[West] Crates by Shooting Range/Crate 4": 509350645, + "[West] Crates by Shooting Range/Crate 3": 509350644, + "[West] Crates by Shooting Range/Crate 2": 509350643, + "[West] Crates by Shooting Range/Crate 1": 509350642, + "[West] Near Isolated Chest/Explosive Pot 2": 509350641, + "[West] Near Isolated Chest/Explosive Pot 1": 509350640, + "[West] Explosive Pot above Shooting Range/Explosive Pot": 509350639, + "[West] Explosive Pots near Bombable Wall/Explosive Pot 2": 509350638, + "[West] Explosive Pots near Bombable Wall/Explosive Pot 1": 509350637, + "[Central] Crates near Shortcut Ladder/Crate 5": 509350636, + "[Central] Crates near Shortcut Ladder/Crate 4": 509350635, + "[Central] Crates near Shortcut Ladder/Crate 3": 509350634, + "[Central] Crates near Shortcut Ladder/Crate 2": 509350633, + "[Central] Crates near Shortcut Ladder/Crate 1": 509350632, + "[Central] Explosive Pots near Shortcut Ladder/Explosive Pot 2": 509350631, + "[Central] Explosive Pots near Shortcut Ladder/Explosive Pot 1": 509350630, + "[Back Entrance] Pots/Pot 5": 509350629, + "[Back Entrance] Pots/Pot 4": 509350628, + "[Back Entrance] Pots/Pot 3": 509350627, + "[Back Entrance] Pots/Pot 2": 509350626, + "[Back Entrance] Pots/Pot 1": 509350625, + "[Central] Explosive Pots near Monastery/Explosive Pot 2": 509350624, + "[Central] Explosive Pots near Monastery/Explosive Pot 1": 509350623, + "[East] Explosive Pot beneath Scaffolding/Explosive Pot": 509350622, + "[East] Explosive Pots/Explosive Pot 3": 509350621, + "[East] Explosive Pots/Explosive Pot 2": 509350620, + "[East] Explosive Pots/Explosive Pot 1": 509350619, + "Display Cases/Display Case 3": 509350618, + "Display Cases/Display Case 2": 509350617, + "Display Cases/Display Case 1": 509350616, + "Orb Room Explosive Pots/Explosive Pot 2": 509350615, + "Orb Room Explosive Pots/Explosive Pot 1": 509350614, + "Pots after Gate/Pot 2": 509350613, + "Pots after Gate/Pot 1": 509350612, + "Slorm Room/Pot": 509350611, + "Main Room Pots/Pot 2": 509350610, + "Main Room Pots/Pot 1": 509350609, + "Side Room Pots/Pot 3": 509350608, + "Side Room Pots/Pot 2": 509350607, + "Side Room Pots/Pot 1": 509350606, + "Pots above Orb Altar/Pot 2": 509350605, + "Pots above Orb Altar/Pot 1": 509350604, + "[Upper] Pots/Pot 6": 509350603, + "[Upper] Pots/Pot 5": 509350602, + "[Upper] Pots/Pot 4": 509350601, + "[Upper] Pots/Pot 3": 509350600, + "[Upper] Pots/Pot 2": 509350599, + "[Upper] Pots/Pot 1": 509350598, + "[South] Explosive Pot near Birds/Explosive Pot": 509350597, + "[West] Broken House/Table": 509350596, + "[West] Broken House/Pot 2": 509350595, + "[West] Broken House/Pot 1": 509350594, + "Fortress Arena/Pot 2": 509350593, + "Fortress Arena/Pot 1": 509350592, + "Fortress Leaf Piles - Secret Chest/Leaf Pile 4": 509350591, + "Fortress Leaf Piles - Secret Chest/Leaf Pile 3": 509350590, + "Fortress Leaf Piles - Secret Chest/Leaf Pile 2": 509350589, + "Fortress Leaf Piles - Secret Chest/Leaf Pile 1": 509350588, + "Barrels/Back Room Barrel 7": 509350587, + "Barrels/Back Room Barrel 6": 509350586, + "Barrels/Back Room Barrel 5": 509350585, + "[Northwest] Sign by Quarry Gate/Sign": 509350400, + "[Central] Sign South of Checkpoint/Sign": 509350401, + "[Central] Sign by Ruined Passage/Sign": 509350402, + "[East] Pots near Slimes/Pot 1": 509350403, + "[East] Pots near Slimes/Pot 2": 509350404, + "[East] Pots near Slimes/Pot 3": 509350405, + "[East] Pots near Slimes/Pot 4": 509350406, + "[East] Pots near Slimes/Pot 5": 509350407, + "[East] Forest Sign/Sign": 509350408, + "[East] Fortress Sign/Sign": 509350409, + "[North] Pots/Pot 1": 509350410, + "[North] Pots/Pot 2": 509350411, + "[North] Pots/Pot 3": 509350412, + "[North] Pots/Pot 4": 509350413, + "[West] Sign Near West Garden Entrance/Sign": 509350414, + "Stick House/Pot 1": 509350415, + "Stick House/Pot 2": 509350416, + "Stick House/Pot 3": 509350417, + "Stick House/Pot 4": 509350418, + "Stick House/Pot 5": 509350419, + "Stick House/Pot 6": 509350420, + "Stick House/Pot 7": 509350421, + "Ruined Shop/Pot 1": 509350422, + "Ruined Shop/Pot 2": 509350423, + "Ruined Shop/Pot 3": 509350424, + "Ruined Shop/Pot 4": 509350425, + "Ruined Shop/Pot 5": 509350426, + "Inside Hourglass Cave/Sign": 509350427, + "Pots by Slimes/Pot 1": 509350428, + "Pots by Slimes/Pot 2": 509350429, + "Pots by Slimes/Pot 3": 509350430, + "Pots by Slimes/Pot 4": 509350431, + "Pots by Slimes/Pot 5": 509350432, + "Pots by Slimes/Pot 6": 509350433, + "[Upper] Barrels/Barrel 1": 509350434, + "[Upper] Barrels/Barrel 2": 509350435, + "[Upper] Barrels/Barrel 3": 509350436, + "Pots after Guard Captain/Pot 1": 509350437, + "Pots after Guard Captain/Pot 2": 509350438, + "Pots after Guard Captain/Pot 3": 509350439, + "Pots after Guard Captain/Pot 4": 509350440, + "Pots after Guard Captain/Pot 5": 509350441, + "Pots after Guard Captain/Pot 6": 509350442, + "Pots after Guard Captain/Pot 7": 509350443, + "Pots after Guard Captain/Pot 8": 509350444, + "Pots after Guard Captain/Pot 9": 509350445, + "Pots/Pot 1": 509350446, + "Pots/Pot 2": 509350447, + "Pots/Pot 3": 509350448, + "Pots/Pot 4": 509350449, + "Pots/Pot 5": 509350450, + "Sign by Grave Path/Sign": 509350451, + "Sign by Guardhouse 1/Sign": 509350452, + "Pots by Grave Path/Pot 1": 509350453, + "Pots by Grave Path/Pot 2": 509350454, + "Pots by Grave Path/Pot 3": 509350455, + "Pots by Envoy/Pot 1": 509350456, + "Pots by Envoy/Pot 2": 509350457, + "Pots by Envoy/Pot 3": 509350458, + "Bottom Floor Pots/Pot 1": 509350459, + "Bottom Floor Pots/Pot 2": 509350460, + "Bottom Floor Pots/Pot 3": 509350461, + "Bottom Floor Pots/Pot 4": 509350462, + "Bottom Floor Pots/Pot 5": 509350463, + "[Side Room] Pots by Chest/Pot 1": 509350464, + "[Side Room] Pots by Chest/Pot 2": 509350465, + "[Side Room] Pots by Chest/Pot 3": 509350466, + "[Third Room] Barrels by Bridge/Barrel 1": 509350467, + "[Third Room] Barrels by Bridge/Barrel 2": 509350468, + "[Third Room] Barrels by Bridge/Barrel 3": 509350469, + "[Third Room] Barrels after Back Corridor/Barrel 1": 509350470, + "[Third Room] Barrels after Back Corridor/Barrel 2": 509350471, + "[Third Room] Barrels after Back Corridor/Barrel 3": 509350472, + "[Third Room] Barrels after Back Corridor/Barrel 4": 509350473, + "[Third Room] Barrels after Back Corridor/Barrel 5": 509350474, + "[Third Room] Barrels by West Turret/Barrel 1": 509350475, + "[Third Room] Barrels by West Turret/Barrel 2": 509350476, + "[Third Room] Barrels by West Turret/Barrel 3": 509350477, + "[Third Room] Pots by East Turret/Pot 1": 509350478, + "[Third Room] Pots by East Turret/Pot 2": 509350479, + "[Third Room] Pots by East Turret/Pot 3": 509350480, + "[Third Room] Pots by East Turret/Pot 4": 509350481, + "[Third Room] Pots by East Turret/Pot 5": 509350482, + "[Third Room] Pots by East Turret/Pot 6": 509350483, + "[Third Room] Pots by East Turret/Pot 7": 509350484, + "Barrels/Barrel 1": 509350485, + "Barrels/Barrel 2": 509350486, + "Pot Hallway Pots/Pot 1": 509350487, + "Pot Hallway Pots/Pot 2": 509350488, + "Pot Hallway Pots/Pot 3": 509350489, + "Pot Hallway Pots/Pot 4": 509350490, + "Pot Hallway Pots/Pot 5": 509350491, + "Pot Hallway Pots/Pot 6": 509350492, + "Pot Hallway Pots/Pot 7": 509350493, + "Pot Hallway Pots/Pot 8": 509350494, + "Pot Hallway Pots/Pot 9": 509350495, + "Pot Hallway Pots/Pot 10": 509350496, + "Pot Hallway Pots/Pot 11": 509350497, + "Pot Hallway Pots/Pot 12": 509350498, + "Pot Hallway Pots/Pot 13": 509350499, + "Pot Hallway Pots/Pot 14": 509350500, + "2nd Laser Room Pots/Pot 1": 509350501, + "2nd Laser Room Pots/Pot 2": 509350502, + "2nd Laser Room Pots/Pot 3": 509350503, + "2nd Laser Room Pots/Pot 4": 509350504, + "2nd Laser Room Pots/Pot 5": 509350505, + "[Southeast Lowlands] Ice Dagger Pickup/Pot 1": 509350506, + "[Southeast Lowlands] Ice Dagger Pickup/Pot 2": 509350507, + "[Southeast Lowlands] Ice Dagger Pickup/Pot 3": 509350508, + "Fire Pots/Fire Pot 1": 509350509, + "Fire Pots/Fire Pot 2": 509350510, + "Fire Pots/Fire Pot 3": 509350511, + "Fire Pots/Fire Pot 4": 509350512, + "Fire Pots/Fire Pot 5": 509350513, + "Fire Pots/Fire Pot 6": 509350514, + "Fire Pots/Fire Pot 7": 509350515, + "Fire Pots/Fire Pot 8": 509350516, + "Upper Fire Pot/Fire Pot": 509350517, + "[Entry] Pots/Pot 1": 509350518, + "[Entry] Pots/Pot 2": 509350519, + "[By Grave] Pots/Pot 1": 509350520, + "[By Grave] Pots/Pot 2": 509350521, + "[By Grave] Pots/Pot 3": 509350522, + "[By Grave] Pots/Pot 4": 509350523, + "[By Grave] Pots/Pot 5": 509350524, + "[By Grave] Pots/Pot 6": 509350525, + "[Central] Fire Pots/Fire Pot 1": 509350526, + "[Central] Fire Pots/Fire Pot 2": 509350527, + "[Central] Pots by Door/Pot 1": 509350528, + "[Central] Pots by Door/Pot 2": 509350529, + "[Central] Pots by Door/Pot 3": 509350530, + "[Central] Pots by Door/Pot 4": 509350531, + "[Central] Pots by Door/Pot 5": 509350532, + "[Central] Pots by Door/Pot 6": 509350533, + "[Central] Pots by Door/Pot 7": 509350534, + "[Central] Pots by Door/Pot 8": 509350535, + "[Central] Pots by Door/Pot 9": 509350536, + "[Central] Pots by Door/Pot 10": 509350537, + "[Central] Pots by Door/Pot 11": 509350538, + "[East Wing] Pots by Broken Checkpoint/Pot 1": 509350539, + "[East Wing] Pots by Broken Checkpoint/Pot 2": 509350540, + "[East Wing] Pots by Broken Checkpoint/Pot 3": 509350541, + "[West Wing] Pots by Checkpoint/Pot 1": 509350542, + "[West Wing] Pots by Checkpoint/Pot 2": 509350543, + "[West Wing] Pots by Checkpoint/Pot 3": 509350544, + "[West Wing] Pots by Overlook/Pot 1": 509350545, + "[West Wing] Pots by Overlook/Pot 2": 509350546, + "[West Wing] Slorm Room Pots/Pot 1": 509350547, + "[West Wing] Slorm Room Pots/Pot 2": 509350548, + "[West Wing] Slorm Room Pots/Pot 3": 509350549, + "[West Wing] Chest Room Pots/Pot 1": 509350550, + "[West Wing] Chest Room Pots/Pot 2": 509350551, + "[West Wing] Pots by Stairs to Basement/Pot 1": 509350552, + "[West Wing] Pots by Stairs to Basement/Pot 2": 509350553, + "[West Wing] Pots by Stairs to Basement/Pot 3": 509350554, + "Entry Spot/Pot 1": 509350555, + "Entry Spot/Pot 2": 509350556, + "Entry Spot/Crate 1": 509350557, + "Entry Spot/Crate 2": 509350558, + "Entry Spot/Crate 3": 509350559, + "Entry Spot/Crate 4": 509350560, + "Entry Spot/Crate 5": 509350561, + "Entry Spot/Crate 6": 509350562, + "Entry Spot/Crate 7": 509350563, + "Slorm Room Crates/Crate 1": 509350564, + "Slorm Room Crates/Crate 2": 509350565, + "Crates under Rope/Crate 1": 509350566, + "Crates under Rope/Crate 2": 509350567, + "Crates under Rope/Crate 3": 509350568, + "Crates under Rope/Crate 4": 509350569, + "Crates under Rope/Crate 5": 509350570, + "Crates under Rope/Crate 6": 509350571, + "Fuse Room Fire Pots/Fire Pot 1": 509350572, + "Fuse Room Fire Pots/Fire Pot 2": 509350573, + "Fuse Room Fire Pots/Fire Pot 3": 509350574, + "Barrels/Barrel by Back Room 1": 509350575, + "Barrels/Barrel by Back Room 2": 509350576, + "Barrels/Barrel by Back Room 3": 509350577, + "Barrels/Barrel by Back Room 4": 509350578, + "Barrels/Barrel by Back Room 5": 509350579, + "Barrels/Barrel by Back Room 6": 509350580, + "Barrels/Back Room Barrel 1": 509350581, + "Barrels/Back Room Barrel 2": 509350582, + "Barrels/Back Room Barrel 3": 509350583, + "[Powered Secret Room] Chest/Follow the Purple Energy Road": 509342400, + "[Entryway] Chest/Mind the Slorms": 509342401, + "[Third Room] Beneath Platform Chest/Run from the tentacles!": 509342402, + "[Third Room] Tentacle Chest/Water Sucks": 509342403, + "[Entryway] Obscured Behind Waterfall/You can just go in there": 509342404, + "[Save Room] Upper Floor Chest 1/Through the Power of Prayer": 509342405, + "[Save Room] Upper Floor Chest 2/Above the Fox Shrine": 509342406, + "[Second Room] Underwater Chest/Hidden Passage": 509342407, + "[Back Corridor] Right Secret/Hidden Path": 509342408, + "[Back Corridor] Left Secret/Behind the Slorms": 509342409, + "[Second Room] Obscured Behind Waterfall/Just go in there": 509342410, + "[Side Room] Chest By Pots/Just Climb up There": 509342411, + "[Side Room] Chest By Phrends/So Many Phrends!": 509342412, + "[Second Room] Page/Ruined Atoll Map": 509342413, + "[Passage To Dark Tomb] Page Pickup/Siege Engine": 509342414, + "[1F] Guarded By Lasers/Beside 3 Miasma Seekers": 509342415, + "[1F] Near Spikes/Mind the Miasma Seeker": 509342416, + "Birdcage Room/[2F] Bird Room": 509342417, + "[2F] Entryway Upper Walkway/Overlooking Miasma": 509342418, + "[1F] Library/By the Books": 509342419, + "[2F] Library/Behind the Ladder": 509342420, + "[2F] Guarded By Lasers/Before the big reveal...": 509342421, + "Birdcage Room/[2F] Bird Room Secret": 509342422, + "[1F] Library Secret/Pray to the Wallman": 509342423, + "Spike Maze Near Exit/Watch out!": 509342424, + "2nd Laser Room/Can you roll?": 509342425, + "1st Laser Room/Use a bomb?": 509342426, + "Spike Maze Upper Walkway/Just walk right!": 509342427, + "Skulls Chest/Move the Grave": 509342428, + "Spike Maze Near Stairs/In the Corner": 509342429, + "1st Laser Room Obscured/Follow the red laser of death": 509342430, + "Guardhouse 2 - Upper Floor/In the Mound": 509342431, + "Guardhouse 2 - Bottom Floor Secret/Hidden Hallway": 509342432, + "Guardhouse 1 Obscured/Upper Floor Obscured": 509342433, + "Guardhouse 1/Upper Floor": 509342434, + "Guardhouse 1 Ledge HC/Dancing Fox Spirit Holy Cross": 509342435, + "Golden Obelisk Holy Cross/Use the Holy Cross": 509342436, + "Ice Rod Grapple Chest/Freeze the Blob and ascend With Orb": 509342437, + "Above Save Point/Chest": 509342438, + "Above Save Point Obscured/Hidden Path": 509342439, + "Guardhouse 1 Ledge/From Guardhouse 1 Chest": 509342440, + "Near Save Point/Chest": 509342441, + "Ambushed by Spiders/Beneath Spider Chest": 509342442, + "Near Telescope/Up on the Wall": 509342443, + "Ambushed by Spiders/Spider Chest": 509342444, + "Lower Dash Chest/Dash Across": 509342445, + "Lower Grapple Chest/Grapple Across": 509342446, + "Bombable Wall/Follow the Flowers": 509342447, + "Page On Teleporter/Page": 509342448, + "Forest Belltower Save Point/Near Save Point": 509342449, + "Forest Belltower - After Guard Captain/Chest": 509342450, + "East Bell/Forest Belltower - Obscured Near Bell Top Floor": 509342451, + "Forest Belltower Obscured/Obscured Beneath Bell Bottom Floor": 509342452, + "Forest Belltower Page/Page Pickup": 509342453, + "Forest Grave Path - Holy Cross Code by Grave/Single Money Chest": 509342454, + "Forest Grave Path - Above Gate/Chest": 509342455, + "Forest Grave Path - Obscured Chest/Behind the Trees": 509342456, + "Forest Grave Path - Upper Walkway/From the top of the Guardhouse": 509342457, + "The Hero's Sword/Forest Grave Path - Sword Pickup": 509342458, + "The Hero's Sword/Hero's Grave - Tooth Relic": 509342459, + "Fortress Courtyard - From East Belltower/Crack in the Wall": 509342460, + "Fortress Leaf Piles - Secret Chest/Dusty": 509342461, + "Fortress Arena/Hexagon Red": 509342462, + "Fortress Arena/Siege Engine|Vault Key Pickup": 509342463, + "Fortress East Shortcut - Chest Near Slimes/Mind the Custodians": 509342464, + "[West Wing] Candles Holy Cross/Use the Holy Cross": 509342465, + "Westmost Upper Room/[West Wing] Dark Room Chest 1": 509342466, + "Westmost Upper Room/[West Wing] Dark Room Chest 2": 509342467, + "[East Wing] Bombable Wall/Bomb the Wall": 509342468, + "[West Wing] Page Pickup/He will never visit the Far Shore": 509342469, + "Fortress Grave Path - Upper Walkway/Go Around the East Wing": 509342470, + "Vault Hero's Grave/Fortress Grave Path - Chest Right of Grave": 509342471, + "Vault Hero's Grave/Fortress Grave Path - Obscured Chest Left of Grave": 509342472, + "Vault Hero's Grave/Hero's Grave - Flowers Relic": 509342473, + "Bridge/Chest": 509342474, + "Cell Chest 1/Drop the Shortcut Rope": 509342475, + "Obscured Behind Waterfall/Muffling Bell": 509342476, + "Back Room Chest/Lose the Lure or take 2 Damage": 509342477, + "Cell Chest 2/Mind the Custodian": 509342478, + "Near Vault/Already Stolen": 509342479, + "Slorm Room/Tobias was Trapped Here Once...": 509342480, + "Escape Chest/Don't Kick Fimbleton!": 509342481, + "Grapple Above Hot Tub/Look Up": 509342482, + "Above Vault/Obscured Doorway Ledge": 509342483, + "Main Room Top Floor/Mind the Adult Frog": 509342484, + "Main Room Bottom Floor/Altar Chest": 509342485, + "Side Room Secret Passage/Upper Right Corner": 509342486, + "Side Room Chest/Oh No! Our Frogs! They're Dead!": 509342487, + "Side Room Grapple Secret/Grapple on Over": 509342488, + "Magic Orb Pickup/Frult Meeting": 509342489, + "The Librarian/Hexagon Green": 509342490, + "Library Hall/Holy Cross Chest": 509342491, + "Library Lab Chest by Shrine 2/Chest": 509342492, + "Barrels/Back Room Barrel 4": 509350584, } From 125d053b61733031d0ebe8559f6edd006e1c4e94 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sat, 12 Jul 2025 07:52:02 -0400 Subject: [PATCH 0554/1218] TUNIC: Fix missing line for UT stuff #5185 --- worlds/tunic/ut_stuff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/tunic/ut_stuff.py b/worlds/tunic/ut_stuff.py index 82d58eaeb8dc..2cf2f96a4ff2 100644 --- a/worlds/tunic/ut_stuff.py +++ b/worlds/tunic/ut_stuff.py @@ -681,7 +681,7 @@ def map_page_index(data: Any) -> int: # for setting up the poptracker integration tracker_world = { "map_page_maps": ["maps/maps_pop.json"], - "map_page_locations": ["locations/locations_pop_er.json"], + "map_page_locations": ["locations/locations_pop_er.json", "locations/locations_breakables.json"], "map_page_setting_key": "Slot:{player}:Current Map", "map_page_index": map_page_index, "external_pack_key": "ut_poptracker_path", From a9b35de7ee9d02d320aaae4b28259ae0ec3139ad Mon Sep 17 00:00:00 2001 From: Justus Lind Date: Sat, 12 Jul 2025 23:02:49 +1000 Subject: [PATCH 0555/1218] Muse Dash: Update song list to Rotaeno Update/7th Anniversary (#5066) --- worlds/musedash/MuseDashData.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/worlds/musedash/MuseDashData.py b/worlds/musedash/MuseDashData.py index f2bcf1220fa1..bcb4ab8e2a78 100644 --- a/worlds/musedash/MuseDashData.py +++ b/worlds/musedash/MuseDashData.py @@ -641,4 +641,17 @@ "Save Yourself": SongData(2900765, "85-3", "Happy Otaku Pack Vol.20", True, 5, 7, 10), "Menace": SongData(2900766, "85-4", "Happy Otaku Pack Vol.20", True, 7, 9, 11), "Dangling": SongData(2900767, "85-5", "Happy Otaku Pack Vol.20", True, 6, 8, 10), + "Inverted World": SongData(2900768, "86-0", "Aquaria Cruising Guide", True, 4, 6, 8), + "Suito": SongData(2900769, "86-1", "Aquaria Cruising Guide", True, 6, 8, 11), + "The Promised Land": SongData(2900770, "86-2", "Aquaria Cruising Guide", True, 4, 6, 9), + "Alfheim's faith": SongData(2900771, "86-3", "Aquaria Cruising Guide", True, 6, 8, 11), + "Heaven's Cage": SongData(2900772, "86-4", "Aquaria Cruising Guide", True, 5, 7, 10), + "Broomstick adventure!": SongData(2900773, "86-5", "Aquaria Cruising Guide", True, 7, 9, 11), + "Strong Nurse Buro-chan!": SongData(2900774, "43-61", "MD Plus Project", True, 5, 7, 9), + "Cubism": SongData(2900775, "43-62", "MD Plus Project", False, 5, 7, 9), + "Cubibibibism": SongData(2900776, "43-63", "MD Plus Project", False, 6, 8, 10), + "LET'S TOAST!!": SongData(2900777, "43-64", "MD Plus Project", False, 6, 8, 10), + "#YamiKawa": SongData(2900778, "43-65", "MD Plus Project", False, 5, 7, 10), + "Rainy Step": SongData(2900779, "43-66", "MD Plus Project", False, 2, 5, 8), + "OHOSHIKATSU": SongData(2900780, "43-67", "MD Plus Project", False, 5, 7, 10), } From ec3f168a09b54d8ee41e44f8fca70a582f9f0ddf Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Mon, 14 Jul 2025 07:22:10 +0000 Subject: [PATCH 0556/1218] Doc: match statement in style guide (#5187) * Test: add micro benchmark for match * Doc: add 'match' to python style guide --- docs/style.md | 4 +++ test/benchmark/match.py | 66 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 test/benchmark/match.py diff --git a/docs/style.md b/docs/style.md index 81853f41725b..5333155db96a 100644 --- a/docs/style.md +++ b/docs/style.md @@ -29,6 +29,10 @@ * New classes, attributes, and methods in core code should have docstrings that follow [reST style](https://peps.python.org/pep-0287/). * Worlds that do not follow PEP8 should still have a consistent style across its files to make reading easier. +* [Match statements](https://docs.python.org/3/tutorial/controlflow.html#tut-match) + may be used instead of `if`-`elif` if they result in nicer code, or they actually use pattern matching. + Beware of the performance: they are not `goto`s, but `if`-`elif` under the hood, and you may have less control. When + in doubt, just don't use it. ## Markdown diff --git a/test/benchmark/match.py b/test/benchmark/match.py new file mode 100644 index 000000000000..ccb600c0ba99 --- /dev/null +++ b/test/benchmark/match.py @@ -0,0 +1,66 @@ +"""Micro benchmark comparing match as "switch" with if-elif and dict access""" + +from timeit import timeit + + +def make_match(count: int) -> str: + code = f"for val in range({count}):\n match val:\n" + for n in range(count): + m = n + 1 + code += f" case {n}:\n" + code += f" res = {m}\n" + return code + + +def make_elif(count: int) -> str: + code = f"for val in range({count}):\n" + for n in range(count): + m = n + 1 + code += f" {'' if n == 0 else 'el'}if val == {n}:\n" + code += f" res = {m}\n" + return code + + +def make_dict(count: int, mode: str) -> str: + if mode == "value": + code = "dct = {\n" + for n in range(count): + m = n + 1 + code += f" {n}: {m},\n" + code += "}\n" + code += f"for val in range({count}):\n res = dct[val]" + return code + elif mode == "call": + code = "" + for n in range(count): + m = n + 1 + code += f"def func{n}():\n val = {m}\n\n" + code += "dct = {\n" + for n in range(count): + code += f" {n}: func{n},\n" + code += "}\n" + code += f"for val in range({count}):\n dct[val]()" + return code + return "" + + +def timeit_best_of_5(stmt: str, setup: str = "pass") -> float: + """ + Benchmark some code, returning the best of 5 runs. + :param stmt: Code to benchmark + :param setup: Optional code to set up environment + :return: Time taken in microseconds + """ + return min(timeit(stmt, setup, number=10000, globals={}) for _ in range(5)) * 100 + + +def main() -> None: + for count in (3, 5, 8, 10, 20, 30): + print(f"value of {count:-2} with match: {timeit_best_of_5(make_match(count)) / count:.3f} us") + print(f"value of {count:-2} with elif: {timeit_best_of_5(make_elif(count)) / count:.3f} us") + print(f"value of {count:-2} with dict: {timeit_best_of_5(make_dict(count, 'value')) / count:.3f} us") + print(f"call of {count:-2} with dict: {timeit_best_of_5(make_dict(count, 'call')) / count:.3f} us") + + +if __name__ == "__main__": + main() From f45410c917c4e0e69f0e769e83b5b7df7cd5853c Mon Sep 17 00:00:00 2001 From: qwint Date: Tue, 15 Jul 2025 00:10:40 -0500 Subject: [PATCH 0557/1218] Core: Update UUID handling to be more easily sharable between libraries (#5088) moves uuid caching to appdata and uuid generation to be a random uuid instead of getnode's hardware address driven identifier and updates docs to point to the shared cache --- Utils.py | 18 ++++++++++++++---- docs/network protocol.md | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Utils.py b/Utils.py index 5697bb162ace..d1c1dd5b5e70 100644 --- a/Utils.py +++ b/Utils.py @@ -413,13 +413,23 @@ def get_adjuster_settings(game_name: str) -> Namespace: @cache_argsless def get_unique_identifier(): - uuid = persistent_load().get("client", {}).get("uuid", None) + common_path = cache_path("common.json") + if os.path.exists(common_path): + with open(common_path) as f: + common_file = json.load(f) + uuid = common_file.get("uuid", None) + else: + common_file = {} + uuid = None + if uuid: return uuid - import uuid - uuid = uuid.getnode() - persistent_store("client", "uuid", uuid) + from uuid import uuid4 + uuid = str(uuid4()) + common_file["uuid"] = uuid + with open(common_path, "w") as f: + json.dump(common_file, f, separators=(",", ":")) return uuid diff --git a/docs/network protocol.md b/docs/network protocol.md index 8c07ff10fdf6..27238e6b7487 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -294,7 +294,7 @@ Sent by the client to initiate a connection to an Archipelago game session. | password | str | If the game session requires a password, it should be passed here. | | game | str | The name of the game the client is playing. Example: `A Link to the Past` | | name | str | The player name for this client. | -| uuid | str | Unique identifier for player client. | +| uuid | str | Unique identifier for player. Cached in the user cache \Archipelago\Cache\common.json | | version | [NetworkVersion](#NetworkVersion) | An object representing the Archipelago version this client supports. | | items_handling | int | Flags configuring which items should be sent by the server. Read below for individual flags. | | tags | list\[str\] | Denotes special features or capabilities that the sender is capable of. [Tags](#Tags) | From 9a648efa70e3bf6b3130ad4400b039238954882a Mon Sep 17 00:00:00 2001 From: lordlou <87331798+lordlou@users.noreply.github.com> Date: Tue, 15 Jul 2025 11:48:28 -0400 Subject: [PATCH 0558/1218] Super Metroid: Only Put Relevant Options in `slot_data` (#5192) * first working single-world randomized SM rom patches * - SM now displays message when getting an item outside for someone else (fills ROM item table) This is dependant on modifications done to sm_randomizer_rom project * First working MultiWorld SM * some missing things: - player name inject in ROM and get in client - end game get from ROM in client - send self item to server - add player names table in ROM * replaced CollectionState inheritance from SMBoolManager with a composition of an array of it (required to generation more than one SM world, which is still fails but is better) * - reenabled balancing * post rebase fixes * updated SmClient.py * + added VariaRandomizer LICENSE * + added sm_randomizer_rom project (which builds sm.ips) * Moved VariaRandomizer and sm_randomizer_rom projects inside worlds/sm and done some cleaning * properly revert change made to CollectionState and more cleaning * Fixed multiworld support patch not working with VariaRandomizer's * missing file commit * Fixed syntax error in unused code to satisfy Linter * Revert "Fixed multiworld support patch not working with VariaRandomizer's" This reverts commit fb3ca18528bb331995e3d3051648c8f84d04c08b. * many fixes and improovement - fixed seeded generation - fixed broken logic when more than one SM world - added missing rules for inter-area transitions - added basic patch presence for logic - added DoorManager init call to reflect present patches for logic - moved CollectionState addition out of BaseClasses into SM world - added condition to apply progitempool presorting only if SM world is present - set Bosses item id to None to prevent them going into multidata - now use get_game_players * first working (most of the time) progression generation for SM using VariaRandomizer's rules, items, locations and accessPoint (as regions) * first working single-world randomized SM rom patches * - SM now displays message when getting an item outside for someone else (fills ROM item table) This is dependant on modifications done to sm_randomizer_rom project * First working MultiWorld SM * some missing things: - player name inject in ROM and get in client - end game get from ROM in client - send self item to server - add player names table in ROM * replaced CollectionState inheritance from SMBoolManager with a composition of an array of it (required to generation more than one SM world, which is still fails but is better) * - reenabled balancing * post rebase fixes * updated SmClient.py * + added VariaRandomizer LICENSE * + added sm_randomizer_rom project (which builds sm.ips) * Moved VariaRandomizer and sm_randomizer_rom projects inside worlds/sm and done some cleaning * properly revert change made to CollectionState and more cleaning * Fixed multiworld support patch not working with VariaRandomizer's * missing file commit * Fixed syntax error in unused code to satisfy Linter * Revert "Fixed multiworld support patch not working with VariaRandomizer's" This reverts commit fb3ca18528bb331995e3d3051648c8f84d04c08b. * many fixes and improovement - fixed seeded generation - fixed broken logic when more than one SM world - added missing rules for inter-area transitions - added basic patch presence for logic - added DoorManager init call to reflect present patches for logic - moved CollectionState addition out of BaseClasses into SM world - added condition to apply progitempool presorting only if SM world is present - set Bosses item id to None to prevent them going into multidata - now use get_game_players * Fixed multiworld support patch not working with VariaRandomizer's Added stage_fill_hook to set morph first in progitempool Added back VariaRandomizer's standard patches * + added missing files from variaRandomizer project * + added missing variaRandomizer files (custom sprites) + started integrating VariaRandomizer options (WIP) * Some fixes for player and server name display - fixed player name of 16 characters reading too far in SM client - fixed 12 bytes SM player name limit (now 16) - fixed server name not being displayed in SM when using server cheat ( now displays RECEIVED FROM ARCHIPELAGO) - request: temporarly changed default seed names displayed in SM main menu to OWTCH * Fixed Goal completion not triggering in smClient * integrated VariaRandomizer's options into AP (WIP) - startAP is working - door rando is working - skillset is working * - fixed itemsounds.ips crash by always including nofanfare.ips into multiworld.ips (itemsounds is now always applied and "itemsounds" preset must always be "off") * skillset are now instanced per player instead of being a singleton class * RomPatches are now instanced per player instead of being a singleton class * DoorManager is now instanced per player instead of being a singleton class * - fixed the last bugs that prevented generation of >1 SM world * fixed crash when no skillset preset is specified in randoPreset (default to "casual") * maxDifficulty support and itemsounds removal - added support for maxDifficulty - removed itemsounds patch as its always applied from multiworld patch for now * Fixed bad merge * Post merge adaptation * fixed player name length fix that got lost with the merge * fixed generation with other game type than SM * added default randoPreset json for SM in playerSettings.yaml * fixed broken SM client following merge * beautified json skillset presets * Fixed ArchipelagoSmClient not building * Fixed conflict between mutliworld patch and beam_doors_plms patch - doorsColorsRando now working * SM generation now outputs APBP - Fixed paths for patches and presets when frozen * added missing file and fixed multithreading issue * temporarily set data_version = 0 * more work - added support for AP starting items - fixed client crash with gamemode being None - patch.py "compatible_version" is now 3 * commited missing asm files fixed start item reserve breaking game (was using bad write offset when patching) * Nothing item are now handled game-side. the game will now skip displaying a message box for received Nothing item (but the client will still receive it). fixed crash in SMClient when loosing connection to SNI * fixed No Energy Item missing its ID fixed Plando * merge post fixes * fixed start item Grapple, XRay and Reserve HUD, as well as graphic beams (except ice palette color) * fixed freeze in blue brinstar caused by Varia's custom PLM not being filled with proper Multiworld PLM address (altLocsAddresses) * fixed start item x-ray HUD display * Fixed start items being sent by the server (is all handled in ROM) Start items are now not removed from itempool anymore Nothing Item is now local_items so no player will ever pickup Nothing. Doing so reduces contribution of this world to the Multiworld the more Nothing there is though. Fixed crash (and possibly passing but broken) at generation where the static list of IPSPatches used by all SM worlds was being modified * fixed settings that could be applied to any SM players * fixed auth to server only using player name (now does as ALTTP to authenticate) * - fixed End Credits broken text * added non SM item name display * added all supported SM options in playerSettings.yaml * fixed locations needing a list of parent regions (now generate a region for each location with one-way exits to each (previously) parent region did some cleaning (mainly reverts on unnecessary core classes * minor setting fixes and tweaks - merged Area and lightArea settings - made missileQty, superQty and powerBombQty use value from 10 to 90 and divide value by float(10) when generating - fixed inverted layoutPatch setting * added option start_inventory_removes_from_pool fixed option names formatting fixed lint errors small code and repo cleanup * Hopefully fixed ROR2 that could not send any items * - fixed missing required change to ROR2 * fixed 0 hp when respawning without having ever saved (start items were not updating the save checksum) * fixed typo with doors_colors_rando * fixed checksum * added custom sprites for off-world items (progression or not) the original AP sprite was made with PierRoulette's SM Item Sprite Utility by ijwu * - added missing change following upstream merge - changed patch filename extension from apbp to apm3 so patch can be used with the new client * added morph placement options: early means local and sphere 1 * fixed failing unit tests * - fixed broken custom_preset options * - big cleanup to remove unnecessary or unsupported features * - more cleanup * - moved sm_randomizer_rom and all always applied patches into an external project that outputs basepatch.ips - small cleanup * - added comment to refer to project for generating basepatch.ips (https://github.com/lordlou/SMBasepatch) * fixed g4_skip patch that can be not applied if hud is enabled * - fixed off world sprite that can have broken graphics (restricted to use only first 2 palette) * - updated basepatch to reflect g4_skip removal - moved more asm files to SMBasepatch project * - tourian grey doors at baby metroid are now always flashing (allowing to go back if needed) * fixed wrong path if using built as exe * - cleaned exposed maxDifficulty options - removed always enabled Knows * Merged LttPClient and SMClient into SNIClient * added varia_custom Preset Option that fetch a preset (read from a new varia_custom_preset Option) from varia's web service * small doc precision * - added death_link support - fixed broken Goal Completion - post merge fix * - removed now useless presets * - fixed bad internal mapping with maxDiff - increases maxDiff if only Bosses is preventing beating the game * - added support for lowercase custom preset sections (knows, settings and controller) - fixed controller settings not applying to ROM * - fixed death loop when dying with Door rando, bomb or speed booster as starting items - varia's backup save should now be usable (automatically enabled when doing door rando) * -added docstring for generated yaml * fixed bad merge * fixed broken infinity max difficulty * commented debug prints * adjusted credits to mark progression speed and difficulty as Non Available * added support for more than 255 players (will print Archipelago for higher player number) * fixed missing cleanup * added support for 65535 different player names in ROM * fixed generations failing when only bosses are unreachable * - replaced setting maxDiff to infinity with a bool only affecting boss logics if only bosses are left to finish * fixed failling generations when using 'fun' settings Accessibility checks are forced to 'items' if restricted locations are used by VARIA following usage of 'fun' settings * fixed debug logger * removed unsupported "suits_restriction" option * fixed generations failing when only bosses are unreachable (using a less intrusive approach for AP) * - fixed deathlink emptying reserves - added death_link_survive option that lets player survive when receiving a deathlink if the have non-empty reserves * - merged death_link and death_link_survive options * fixed death_link * added a fallback default starting location instead of failing generation if an invalid one was chosen * added Nothing and NoEnergy as hint blacklist added missing NoEnergy as local items and removed it from progression * reduced slot_data to only what should be needed by PopTracker (for https://github.com/ArchipelagoMW/Archipelago/pull/5039) --- worlds/sm/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/sm/__init__.py b/worlds/sm/__init__.py index bc8dcd6114bc..3272f40c9b5d 100644 --- a/worlds/sm/__init__.py +++ b/worlds/sm/__init__.py @@ -852,7 +852,7 @@ def modify_multidata(self, multidata: dict): def fill_slot_data(self): slot_data = {} if not self.multiworld.is_race: - slot_data = self.options.as_dict(*self.options_dataclass.type_hints) + slot_data = self.options.as_dict("start_location", "max_difficulty", "area_randomization", "doors_colors_rando", "boss_randomization") slot_data["Preset"] = { "Knows": {}, "Settings": {"hardRooms": Settings.SettingsDict[self.player].hardRooms, "bossesDifficulty": Settings.SettingsDict[self.player].bossesDifficulty, From c8ca3e643d7b9f502a31edbadf9ad4ab2d8cec69 Mon Sep 17 00:00:00 2001 From: qwint Date: Tue, 15 Jul 2025 13:19:50 -0500 Subject: [PATCH 0559/1218] Core: Adds Visual Formatting to Option Group Headers in Template Yamls (#5092) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- data/options.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/options.yaml b/data/options.yaml index 3fbe25a9211f..f2621124c890 100644 --- a/data/options.yaml +++ b/data/options.yaml @@ -46,7 +46,9 @@ requires: {{ yaml_dump(game) }}: {%- for group_name, group_options in option_groups.items() %} - # {{ group_name }} + ##{% for _ in group_name %}#{% endfor %}## + # {{ group_name }} # + ##{% for _ in group_name %}#{% endfor %}## {%- for option_key, option in group_options.items() %} {{ option_key }}: From c879307b8e1cffa75afb3b1b14ae7f6e3b593f5c Mon Sep 17 00:00:00 2001 From: qwint Date: Tue, 15 Jul 2025 13:30:13 -0500 Subject: [PATCH 0560/1218] CC: Add Assert to Catch Old Datapackage Lookup API (#5131) --- CommonClient.py | 1 + 1 file changed, 1 insertion(+) diff --git a/CommonClient.py b/CommonClient.py index 3a5f51aeee33..35ed541fadb2 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -201,6 +201,7 @@ def __init__(self, ctx: CommonContext, lookup_type: typing.Literal["item", "loca # noinspection PyTypeChecker def __getitem__(self, key: str) -> typing.Mapping[int, str]: + assert isinstance(key, str), f"ctx.{self.lookup_type}_names used with an id, use the lookup_in_ helpers instead" return self._game_store[key] def __len__(self) -> int: From f967444ac2d7cb35dec6cb71da2e7189e42bb41e Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:32:22 +0200 Subject: [PATCH 0561/1218] Core: Assert that all the items in the multiworld itempool are actually unplaced at the start of distribute_items_restrictive (#5109) * Assert at the beginning of distribute items restrictive that no items in the itempool already have locations associated with them * actual message * placement * oops * Update Fill.py --- Fill.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Fill.py b/Fill.py index abdad4407097..d4df9fdd476a 100644 --- a/Fill.py +++ b/Fill.py @@ -450,6 +450,12 @@ def distribute_early_items(multiworld: MultiWorld, def distribute_items_restrictive(multiworld: MultiWorld, panic_method: typing.Literal["swap", "raise", "start_inventory"] = "swap") -> None: + assert all(item.location is None for item in multiworld.itempool), ( + "At the start of distribute_items_restrictive, " + "there are items in the multiworld itempool that are already placed on locations:\n" + f"{[(item.location, item) for item in multiworld.itempool if item.location is not None]}" + ) + fill_locations = sorted(multiworld.get_unfilled_locations()) multiworld.random.shuffle(fill_locations) # get items to distribute From c1ae637fa7d6d152a4a52fadb8055b3ec59f4606 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:32:53 +0200 Subject: [PATCH 0562/1218] Core: Crash on full accessibility if there are unreachable locations (Yes, you read that right) #3787 --- BaseClasses.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/BaseClasses.py b/BaseClasses.py index dbcd65ab55fa..ef0fa10e2170 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -706,6 +706,12 @@ def all_done() -> bool: sphere.append(locations.pop(n)) if not sphere: + if __debug__: + from Fill import FillError + raise FillError( + f"Could not access required locations for accessibility check. Missing: {locations}", + multiworld=self, + ) # ran out of places and did not finish yet, quit logging.warning(f"Could not access required locations for accessibility check." f" Missing: {locations}") From 507a9a53ef363e77b4dfdecb6612e8b335e6199d Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Tue, 15 Jul 2025 19:33:11 +0100 Subject: [PATCH 0563/1218] Core: Cleanup: Replace direct calling of dunder methods on objects (#4584) Calling the dunder method has to: 1. Look up the dunder method for that object/class 2. Bind a new method instance to the object instance 3. Call the method with its arguments 4. Run the appropriate operation on the object Whereas running the appropriate operation on the object from the start skips straight to step 4. Region.Register.__getitem__ is called a lot without #4583. In that case, generation of 10 template Blasphemous yamls with `--skip_output --seed 1` and progression balancing disabled went from 19.0s to 18.8s (1.3% reduction in generation duration). From profiling with `timeit` ```py def __getitem__(self, index: int) -> Location: return self._list[index] ``` appears to be about twice as fast as the old code: ```py def __getitem__(self, index: int) -> Location: return self._list.__getitem__(index) ``` Besides this, there is not expected to be any noticeable difference in performance, and there is not expected to be any difference in semantics with these changes. Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- BaseClasses.py | 12 ++++++------ CommonClient.py | 2 +- Options.py | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index ef0fa10e2170..c4fff017b74e 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1156,13 +1156,13 @@ def __init__(self, region_manager: MultiWorld.RegionManager): self.region_manager = region_manager def __getitem__(self, index: int) -> Location: - return self._list.__getitem__(index) + return self._list[index] def __setitem__(self, index: int, value: Location) -> None: raise NotImplementedError() def __len__(self) -> int: - return self._list.__len__() + return len(self._list) def __iter__(self): return iter(self._list) @@ -1176,8 +1176,8 @@ def copy(self): class LocationRegister(Register): def __delitem__(self, index: int) -> None: - location: Location = self._list.__getitem__(index) - self._list.__delitem__(index) + location: Location = self._list[index] + del self._list[index] del(self.region_manager.location_cache[location.player][location.name]) def insert(self, index: int, value: Location) -> None: @@ -1188,8 +1188,8 @@ def insert(self, index: int, value: Location) -> None: class EntranceRegister(Register): def __delitem__(self, index: int) -> None: - entrance: Entrance = self._list.__getitem__(index) - self._list.__delitem__(index) + entrance: Entrance = self._list[index] + del self._list[index] del(self.region_manager.entrance_cache[entrance.player][entrance.name]) def insert(self, index: int, value: Entrance) -> None: diff --git a/CommonClient.py b/CommonClient.py index 35ed541fadb2..454150acbf8b 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -211,7 +211,7 @@ def __iter__(self) -> typing.Iterator[str]: return iter(self._game_store) def __repr__(self) -> str: - return self._game_store.__repr__() + return repr(self._game_store) def lookup_in_game(self, code: int, game_name: typing.Optional[str] = None) -> str: """Returns the name for an item/location id in the context of a specific game or own game if `game` is diff --git a/Options.py b/Options.py index 26e145926edc..b910d21665af 100644 --- a/Options.py +++ b/Options.py @@ -865,13 +865,13 @@ def get_option_name(self, value): return ", ".join(f"{key}: {v}" for key, v in value.items()) def __getitem__(self, item: str) -> typing.Any: - return self.value.__getitem__(item) + return self.value[item] def __iter__(self) -> typing.Iterator[str]: - return self.value.__iter__() + return iter(self.value) def __len__(self) -> int: - return self.value.__len__() + return len(self.value) # __getitem__ fallback fails for Counters, so we define this explicitly def __contains__(self, item) -> bool: @@ -1067,10 +1067,10 @@ def __iter__(self) -> typing.Iterator[PlandoText]: yield from self.value def __getitem__(self, index: typing.SupportsIndex) -> PlandoText: - return self.value.__getitem__(index) + return self.value[index] def __len__(self) -> int: - return self.value.__len__() + return len(self.value) class ConnectionsMeta(AssembleOptions): @@ -1217,7 +1217,7 @@ def get_option_name(cls, value: typing.List[PlandoConnection]) -> str: connection.exit) for connection in value]) def __getitem__(self, index: typing.SupportsIndex) -> PlandoConnection: - return self.value.__getitem__(index) + return self.value[index] def __iter__(self) -> typing.Iterator[PlandoConnection]: yield from self.value From f9f386fa1948f0cb7348df2690d61792caceaa18 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Tue, 15 Jul 2025 19:33:24 +0100 Subject: [PATCH 0564/1218] Core: Cache previous swap states to use as the base state to sweep from (#3859) The previous swap_state can often be used as the base state to create the next swap_state. This previous swap_state will already have collected all items in item_pool and is likely to have checked many locations, meaning that creating the next swap_state from it instead of from base_state is faster. From generating with extra code to raise an exception if more than 2 previous swap states were used, and using A Hat in Time and Pokemon Red/Blue yamls that often result in lots of swapping in progression fill, I could not get a single seed go through more than 2 previous swap states. A few worlds' pre-fills do often use more than 2 previous swap states, notably LADX which sometimes goes through over 20. Given a 20 player Pokemon Red/Blue multiworld that usually generates in around 16 or 17 seconds, but on a specific seed that results in 56 swaps, generation went from about 260 seconds before this patch to about 104 seconds after this patch (generated with a meta.yaml to disable progression balancing and `python -O Generate.py --skip_output`). Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- Fill.py | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/Fill.py b/Fill.py index d4df9fdd476a..94904f4f392a 100644 --- a/Fill.py +++ b/Fill.py @@ -116,6 +116,13 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati else: # we filled all reachable spots. if swap: + # Keep a cache of previous safe swap states that might be usable to sweep from to produce the next + # swap state, instead of sweeping from `base_state` each time. + previous_safe_swap_state_cache: typing.Deque[CollectionState] = deque() + # Almost never are more than 2 states needed. The rare cases that do are usually highly restrictive + # single_player_placement=True pre-fills which can go through more than 10 states in some seeds. + max_swap_base_state_cache_length = 3 + # try swapping this item with previously placed items in a safe way then in an unsafe way swap_attempts = ((i, location, unsafe) for unsafe in (False, True) @@ -130,9 +137,30 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati location.item = None placed_item.location = None - swap_state = sweep_from_pool(base_state, [placed_item, *item_pool] if unsafe else item_pool, - multiworld.get_filled_locations(item.player) - if single_player_placement else None) + + for previous_safe_swap_state in previous_safe_swap_state_cache: + # If a state has already checked the location of the swap, then it cannot be used. + if location not in previous_safe_swap_state.advancements: + # Previous swap states will have collected all items in `item_pool`, so the new + # `swap_state` can skip having to collect them again. + # Previous swap states will also have already checked many locations, making the sweep + # faster. + swap_state = sweep_from_pool(previous_safe_swap_state, (placed_item,) if unsafe else (), + multiworld.get_filled_locations(item.player) + if single_player_placement else None) + break + else: + # No previous swap_state was usable as a base state to sweep from, so create a new one. + swap_state = sweep_from_pool(base_state, [placed_item, *item_pool] if unsafe else item_pool, + multiworld.get_filled_locations(item.player) + if single_player_placement else None) + # Unsafe states should not be added to the cache because they have collected `placed_item`. + if not unsafe: + if len(previous_safe_swap_state_cache) >= max_swap_base_state_cache_length: + # Remove the oldest cached state. + previous_safe_swap_state_cache.pop() + # Add the new state to the start of the cache. + previous_safe_swap_state_cache.appendleft(swap_state) # unsafe means swap_state assumes we can somehow collect placed_item before item_to_place # by continuing to swap, which is not guaranteed. This is unsafe because there is no mechanic # to clean that up later, so there is a chance generation fails. From 2aada8f683e57e70878680d1a98b2c05a6f30a16 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:35:27 +0200 Subject: [PATCH 0565/1218] Core: Add new ItemClassification "deprioritized" which will not be placed on priority locations (if possible) (#4610) * Add new deprioritized item flag * 4 retries * indent * . * style * I think this is nicer * Nicer * remove two lines again that I added unnecessarily * I think this test makes a bit more sense like this * Idk how to word this lol * Add progression_deprioritized_skip_balancing bc why not ig * More text * Update Fill.py * Update Fill.py * I am the big stupid * Actually collect the other half of progression items into state when filling without them * More clarity on the descriptions (hopefully) * visually separate technical description and use cases * Actually make the call do what the comments say it does --- BaseClasses.py | 36 +++++++++++++++++++++++++------- Fill.py | 44 ++++++++++++++++++++++++++++++++------- test/general/test_fill.py | 22 ++++++++++++++++++++ 3 files changed, 87 insertions(+), 15 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index c4fff017b74e..6deb878097a0 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1436,27 +1436,43 @@ def hint_text(self) -> str: class ItemClassification(IntFlag): - filler = 0b0000 + filler = 0b00000 """ aka trash, as in filler items like ammo, currency etc """ - progression = 0b0001 + progression = 0b00001 """ Item that is logically relevant. Protects this item from being placed on excluded or unreachable locations. """ - useful = 0b0010 + useful = 0b00010 """ Item that is especially useful. Protects this item from being placed on excluded or unreachable locations. When combined with another flag like "progression", it means "an especially useful progression item". """ - trap = 0b0100 + trap = 0b00100 """ Item that is detrimental in some way. """ - skip_balancing = 0b1000 + skip_balancing = 0b01000 """ should technically never occur on its own Item that is logically relevant, but progression balancing should not touch. - Typically currency or other counted items. """ - - progression_skip_balancing = 0b1001 # only progression gets balanced + + Possible reasons for why an item should not be pulled ahead by progression balancing: + 1. This item is quite insignificant, so pulling it earlier doesn't help (currency/etc.) + 2. It is important for the player experience that this item is evenly distributed in the seed (e.g. goal items) """ + + deprioritized = 0b10000 + """ Should technically never occur on its own. + Will not be considered for priority locations, + unless Priority Locations Fill runs out of regular progression items before filling all priority locations. + + Should be used for items that would feel bad for the player to find on a priority location. + Usually, these are items that are plentiful or insignificant. """ + + progression_deprioritized_skip_balancing = 0b11001 + """ Since a common case of both skip_balancing and deprioritized is "insignificant progression", + these items often want both flags. """ + + progression_skip_balancing = 0b01001 # only progression gets balanced + progression_deprioritized = 0b10001 # only progression can be placed during priority fill def as_flag(self) -> int: """As Network API flag int.""" @@ -1504,6 +1520,10 @@ def useful(self) -> bool: def trap(self) -> bool: return ItemClassification.trap in self.classification + @property + def deprioritized(self) -> bool: + return ItemClassification.deprioritized in self.classification + @property def filler(self) -> bool: return not (self.advancement or self.useful or self.trap) diff --git a/Fill.py b/Fill.py index 94904f4f392a..29a9a530a4cd 100644 --- a/Fill.py +++ b/Fill.py @@ -526,18 +526,48 @@ def mark_for_locking(location: Location): single_player = multiworld.players == 1 and not multiworld.groups if prioritylocations: + regular_progression = [] + deprioritized_progression = [] + for item in progitempool: + if item.deprioritized: + deprioritized_progression.append(item) + else: + regular_progression.append(item) + # "priority fill" - maximum_exploration_state = sweep_from_pool(multiworld.state) - fill_restrictive(multiworld, maximum_exploration_state, prioritylocations, progitempool, + # try without deprioritized items in the mix at all. This means they need to be collected into state first. + priority_fill_state = sweep_from_pool(multiworld.state, deprioritized_progression) + fill_restrictive(multiworld, priority_fill_state, prioritylocations, regular_progression, single_player_placement=single_player, swap=False, on_place=mark_for_locking, name="Priority", one_item_per_player=True, allow_partial=True) - if prioritylocations: + if prioritylocations and regular_progression: # retry with one_item_per_player off because some priority fills can fail to fill with that optimization - maximum_exploration_state = sweep_from_pool(multiworld.state) - fill_restrictive(multiworld, maximum_exploration_state, prioritylocations, progitempool, - single_player_placement=single_player, swap=False, on_place=mark_for_locking, - name="Priority Retry", one_item_per_player=False) + # deprioritized items are still not in the mix, so they need to be collected into state first. + priority_retry_state = sweep_from_pool(multiworld.state, deprioritized_progression) + fill_restrictive(multiworld, priority_retry_state, prioritylocations, regular_progression, + single_player_placement=single_player, swap=False, on_place=mark_for_locking, + name="Priority Retry", one_item_per_player=False, allow_partial=True) + + if prioritylocations and deprioritized_progression: + # There are no more regular progression items that can be placed on any priority locations. + # We'd still prefer to place deprioritized progression items on priority locations over filler items. + # Since we're leaving out the remaining regular progression now, we need to collect it into state first. + priority_retry_2_state = sweep_from_pool(multiworld.state, regular_progression) + fill_restrictive(multiworld, priority_retry_2_state, prioritylocations, deprioritized_progression, + single_player_placement=single_player, swap=False, on_place=mark_for_locking, + name="Priority Retry 2", one_item_per_player=True, allow_partial=True) + + if prioritylocations and deprioritized_progression: + # retry with deprioritized items AND without one_item_per_player optimisation + # Since we're leaving out the remaining regular progression now, we need to collect it into state first. + priority_retry_3_state = sweep_from_pool(multiworld.state, regular_progression) + fill_restrictive(multiworld, priority_retry_3_state, prioritylocations, deprioritized_progression, + single_player_placement=single_player, swap=False, on_place=mark_for_locking, + name="Priority Retry 3", one_item_per_player=False) + + # restore original order of progitempool + progitempool[:] = [item for item in progitempool if not item.location] accessibility_corrections(multiworld, multiworld.state, prioritylocations, progitempool) defaultlocations = prioritylocations + defaultlocations diff --git a/test/general/test_fill.py b/test/general/test_fill.py index c8bcec9581ac..bdc38d791316 100644 --- a/test/general/test_fill.py +++ b/test/general/test_fill.py @@ -603,6 +603,28 @@ def test_multiple_world_priority_distribute(self): self.assertTrue(player3.locations[2].item.advancement) self.assertTrue(player3.locations[3].item.advancement) + def test_deprioritized_does_not_land_on_priority(self): + multiworld = generate_test_multiworld(1) + player1 = generate_player_data(multiworld, 1, 2, prog_item_count=2) + + player1.prog_items[0].classification |= ItemClassification.deprioritized + player1.locations[0].progress_type = LocationProgressType.PRIORITY + + distribute_items_restrictive(multiworld) + + self.assertFalse(player1.locations[0].item.deprioritized) + + def test_deprioritized_still_goes_on_priority_ahead_of_filler(self): + multiworld = generate_test_multiworld(1) + player1 = generate_player_data(multiworld, 1, 2, prog_item_count=1, basic_item_count=1) + + player1.prog_items[0].classification |= ItemClassification.deprioritized + player1.locations[0].progress_type = LocationProgressType.PRIORITY + + distribute_items_restrictive(multiworld) + + self.assertTrue(player1.locations[0].item.advancement) + def test_can_remove_locations_in_fill_hook(self): """Test that distribute_items_restrictive calls the fill hook and allows for item and location removal""" multiworld = generate_test_multiworld() From e1b26bc76f7b69e2ec532d3ac4d9e60ba05824bc Mon Sep 17 00:00:00 2001 From: Eindall Date: Tue, 15 Jul 2025 21:02:17 +0200 Subject: [PATCH 0566/1218] Stardew Valley: Add French Guide (#4697) Co-authored-by: tmarquis --- worlds/stardew_valley/__init__.py | 28 ++++++--- worlds/stardew_valley/docs/setup_fr.md | 87 ++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 worlds/stardew_valley/docs/setup_fr.md diff --git a/worlds/stardew_valley/__init__.py b/worlds/stardew_valley/__init__.py index ea0ce9e1232d..ec96a9949e3c 100644 --- a/worlds/stardew_valley/__init__.py +++ b/worlds/stardew_valley/__init__.py @@ -50,15 +50,25 @@ class StardewWebWorld(WebWorld): options_presets = sv_options_presets option_groups = sv_option_groups - tutorials = [ - Tutorial( - "Multiworld Setup Guide", - "A guide to playing Stardew Valley with Archipelago.", - "English", - "setup_en.md", - "setup/en", - ["KaitoKid", "Jouramie", "Witchybun (Mod Support)", "Exempt-Medic (Proofreading)"] - )] + setup_en = Tutorial( + "Multiworld Setup Guide", + "A guide to playing Stardew Valley with Archipelago.", + "English", + "setup_en.md", + "setup/en", + ["KaitoKid", "Jouramie", "Witchybun (Mod Support)", "Exempt-Medic (Proofreading)"] + ) + + setup_fr = Tutorial( + "Guide de configuration MultiWorld", + "Un guide pour configurer Stardew Valley sur Archipelago", + "Français", + "setup_fr.md", + "setup/fr", + ["Eindall"] + ) + + tutorials = [setup_en, setup_fr] class StardewValleyWorld(World): diff --git a/worlds/stardew_valley/docs/setup_fr.md b/worlds/stardew_valley/docs/setup_fr.md new file mode 100644 index 000000000000..d7866c0b162c --- /dev/null +++ b/worlds/stardew_valley/docs/setup_fr.md @@ -0,0 +1,87 @@ +# Guide de configuration du Randomizer Stardew Valley + +## Logiciels nécessaires + +- Stardew Valley 1.6 sur PC (Recommandé: [Steam](https://store.steampowered.com/app/413150/Stardew_Valley/)) +- SMAPI ([Mod loader pour Stardew Valley](https://www.nexusmods.com/stardewvalley/mods/2400?tab=files)) +- [StardewArchipelago Version 6.x.x](https://github.com/agilbert1412/StardewArchipelago/releases) + - Il est important d'utiliser une release en 6.x.x pour jouer sur des seeds générées ici. Les versions ultérieures peuvent uniquement être utilisées pour des release ultérieures du générateur de mondes, qui ne sont pas encore hébergées sur archipelago.gg + +## Logiciels optionnels + +- Launcher Archipelago à partir de la [page des versions d'Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) + - (Uniquement pour le client textuel) +- Autres [mods supportés](https://github.com/agilbert1412/StardewArchipelago/blob/6.x.x/Documentation/Supported%20Mods.md) que vous pouvez ajouter au yaml pour les inclure dans la randomization d'Archipelago + + - Il n'est **pas** recommandé de modder Stardew Valley avec des mods non supportés, même s'il est possible de le faire. + Les interactions entre mods peuvent être imprévisibles, et aucune aide ne sera fournie pour les bugs qui y sont liés. + - Plus vous avez de mods non supportés, et plus ils sont gros, plus vous avez de chances de casser des choses. + +## Configuration du fichier YAML + +### Qu'est qu'un fichier YAML et pourquoi en ai-je besoin ? + +Voir le guide pour paramètrer un fichier YAML dans le guide de configuration d'Archipelago (en anglais): [Guide de configuration d'un MultiWorld basique](/tutorial/Archipelago/setup/en) + +### Où puis-je récupèrer un fichier YAML + +Vous pouvez personnaliser vos options en visitant la [Page d'options de joueur pour Stardew Valley](/games/Stardew%20Valley/player-options) + +## Rejoindre une partie en MultiWorld + +### Installation du mod + +- Installer [SMAPI](https://www.nexusmods.com/stardewvalley/mods/2400?tab=files) en suivant les instructions sur la page du mod. +- Télécharger et extraire le mod [StardewArchipelago](https://github.com/agilbert1412/StardewArchipelago/releases) dans le dossier "Mods" de Stardew Valley. +- *Optionnel*: Si vous voulez lancer le jeu depuis Steam, ajouter l'option de lancement suivante à Stardew Valley : `"[PATH TO STARDEW VALLEY]\Stardew Valley\StardewModdingAPI.exe" %command%` +- Sinon, exécutez juste "StardewModdingAPI.exe" dans le dossier d'installation de Stardew Valley. +- Stardew Valley devrait se lancer avec une console qui liste les informations des mods installés, et intéragit avec certains d'entre eux. + +### Se connecter au MultiServer + +Lancer Stardew Valley avec SMAPI. Une fois que vous avez atteint l'écran titre du jeu, créez une nouvelle ferme. + +Dans la fenêtre de création de personnage, vous verrez 3 nouveaux champs, qui permettent de relier votre personnage à un MultiWorld Archipelago. + +![image](https://i.imgur.com/b8KZy2F.png) + +Vous pouvez personnaliser votre personnage comme vous le souhaitez. + +Le champ "Server" nécessite l'adresse **et** le port, et le "Slotname" est le nom que vous avez spécifié dans votre YAML. + +`archipelago.gg:12345` + +`StardewPlayer` + +Le mot de passe est optionnel. + +Votre jeu se connectera automatiquement à Archipelago, et se reconnectera automatiquement également quand vous chargerez votre sauvegarde, plus tard. + +Vous n'aurez plus besoin d'entrer ces informations à nouveau pour ce personnage, à moins que votre session ne change d'ip ou de port. +Si l'ip ou le port de la session **change**, vous pouvez suivre ces instructions pour modifier les informations de connexion liées à votre sauvegarde : + +- Lancer Stardew Valley moddé +- Dans le **menu principal** du jeu, entrer la commande suivante **dans la console de SMAPI** : +- `connect_override ip:port slot password` +- Par exemple : `connect_override archipelago.gg:54321 StardewPlayer` +- Chargez votre partie. Les nouvelles informations de connexion seront utilisées à la place de celles enregistrées initialement. +- Jouez une journée, dormez et sauvegarder la partie. Les nouvelles informations de connexion iront écraser les précédentes, et deviendront permanentes. + +### Intéragir avec le MultiWorld depuis le jeu + +Quand vous vous connectez, vous devriez voir un message dans le chat vous informant de l'existence de la commande `!!help`. Cette commande liste les autres commandes exclusives à Stardew Valley que vous pouvez utiliser. + +De plus, vous pouvez utiliser le chat en jeu pour parler aux autres joueurs du MultiWorld, pour peu qu'ils aient un jeu qui supporte le chat. + +Enfin, vous pouvez également utiliser les commandes Archipelago (`!help` pour les lister) depuis le chat du jeu, permettant de demander des indices (via la commande `!hint`) sur certains objets. + +Il est important de préciser que le chat de Stardew Valley est assez limité. Par exemple, il ne permet pas de remonter l'historique de conversation. La console SMAPI qui tourne à côté aura quant à elle l'historique complet et sera plus pratique pour consulter des messages moins récents. +Pour une meilleure expérience avec le chat, vous pouvez aussi utiliser le client textuel d'Archipelago, bien qu'il ne permettra pas de lancer les commandes exclusives à Stardew Valley. + +### Jouer avec des mods supportés + +Voir la [documentation des mods supportés](https://github.com/agilbert1412/StardewArchipelago/blob/6.x.x/Documentation/Supported%20Mods.md) (en Anglais). + +### Multijoueur + +Vous ne pouvez pas jouer à Stardew Valley en mode multijoueur pour le moment. Il n'y a aucun plan d'action pour ajouter cette fonctionalité à court terme. \ No newline at end of file From f18f9e2dce6cbc59265d48b221c82a8c2d842bfc Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 15 Jul 2025 21:04:06 +0200 Subject: [PATCH 0567/1218] Core: increment version (#5194) --- Utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utils.py b/Utils.py index d1c1dd5b5e70..9c1171096e80 100644 --- a/Utils.py +++ b/Utils.py @@ -47,7 +47,7 @@ def as_simple_string(self) -> str: return ".".join(str(item) for item in self) -__version__ = "0.6.2" +__version__ = "0.6.3" version_tuple = tuplize_version(__version__) is_linux = sys.platform.startswith("linux") From fed60ca61a5a6874744b131af9f578e5b3a33c02 Mon Sep 17 00:00:00 2001 From: qwint Date: Tue, 15 Jul 2025 14:09:56 -0500 Subject: [PATCH 0568/1218] Hollow Knight: Explicitly Exclude Palace Items as Filler (#5119) --- worlds/hk/__init__.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/worlds/hk/__init__.py b/worlds/hk/__init__.py index 4a0da109fa18..31770637aa9a 100644 --- a/worlds/hk/__init__.py +++ b/worlds/hk/__init__.py @@ -218,6 +218,11 @@ def white_palace_exclusions(self): wp = self.options.WhitePalace if wp <= WhitePalace.option_nopathofpain: exclusions.update(path_of_pain_locations) + exclusions.update(( + "Soul_Totem-Path_of_Pain", + "Lore_Tablet-Path_of_Pain_Entrance", + "Journal_Entry-Seal_of_Binding", + )) if wp <= WhitePalace.option_kingfragment: exclusions.update(white_palace_checks) if wp == WhitePalace.option_exclude: @@ -226,6 +231,9 @@ def white_palace_exclusions(self): # If charms are randomized, this will be junk-filled -- so transitions and events are not progression exclusions.update(white_palace_transitions) exclusions.update(white_palace_events) + exclusions.update(item_name_groups["PalaceJournal"]) + exclusions.update(item_name_groups["PalaceLore"]) + exclusions.update(item_name_groups["PalaceTotem"]) return exclusions def create_regions(self): From 6360609980bf2c02e4c18fdecd91ae258b7dbf30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dana=C3=ABl=20V=2E?= <104455676+ReverM@users.noreply.github.com> Date: Tue, 15 Jul 2025 15:43:20 -0400 Subject: [PATCH 0569/1218] Witness: Add French and German Setup Documentation (#2527) Co-authored-by: Lolo Co-authored-by: Scipio Wright Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/witness/__init__.py | 22 +++++++++++++-- worlds/witness/docs/setup_de.md | 46 ++++++++++++++++++++++++++++++++ worlds/witness/docs/setup_fr.md | 47 +++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 worlds/witness/docs/setup_de.md create mode 100644 worlds/witness/docs/setup_fr.md diff --git a/worlds/witness/__init__.py b/worlds/witness/__init__.py index b2e91c7cf0f4..0f96ee94e8c9 100644 --- a/worlds/witness/__init__.py +++ b/worlds/witness/__init__.py @@ -27,14 +27,32 @@ class WitnessWebWorld(WebWorld): theme = "jungle" - tutorials = [Tutorial( + setup_en = Tutorial( "Multiworld Setup Guide", "A guide to playing The Witness with Archipelago.", "English", "setup_en.md", "setup/en", ["NewSoupVi", "Jarno"] - )] + ) + setup_de = Tutorial( + setup_en.tutorial_name, + setup_en.description, + "German", + "setup_de.md", + "setup/de", + ["NewSoupVi"] + ) + setup_fr = Tutorial( + setup_en.tutorial_name, + setup_en.description, + "Français", + "setup_fr.md", + "setup/fr", + ["Rever"] + ) + + tutorials = [setup_en, setup_de, setup_fr] options_presets = witness_option_presets option_groups = witness_option_groups diff --git a/worlds/witness/docs/setup_de.md b/worlds/witness/docs/setup_de.md new file mode 100644 index 000000000000..82865bb13422 --- /dev/null +++ b/worlds/witness/docs/setup_de.md @@ -0,0 +1,46 @@ +# The Witness Randomizer Setup + +## Benötigte Software + +- [The Witness für ein 64-bit-Windows-Betriebssystem (z.B. Steam-Version)](https://store.steampowered.com/app/210970/The_Witness/) +- [The Witness Archipelago Randomizer](https://github.com/NewSoupVi/The-Witness-Randomizer-for-Archipelago/releases/latest) + +## Optionale Software + +- [ArchipelagoTextClient](https://github.com/ArchipelagoMW/Archipelago/releases) +- [The Witness Auto-Tracker mit Kartenansicht](https://github.com/NewSoupVi/witness_archipelago_tracker/releases), benutzbar mit [PopTracker](https://github.com/black-sliver/PopTracker/releases) + +## Verbindung mit einem Multiworld-Spiel + +1. Öffne The Witness. +2. Erstelle einen neuen Speicherstand. +3. Öffne [The Witness Archipelago Randomizer](https://github.com/NewSoupVi/The-Witness-Randomizer-for-Archipelago/releases/latest). +4. Gib die Archipelago-Adresse, deinen Namen und evtl. das Passwort ein. +5. Drücke "Connect". +6. Viel Spaß! + +Wenn du ein vorheriges Spiel fortsetzen willst, ist das auch möüglich: + +1. Öffne The Witness. +2. Lade den Speicherstand für das Multiworld-Spiel, das du weiterspielen willst - Wenn das nicht sowieso schon der ist, den das Spiel automatisch geladen hat. +3. Öffne [The Witness Archipelago Randomizer](https://github.com/NewSoupVi/The-Witness-Randomizer-for-Archipelago/releases/latest). +4. Drücke "Load Credentials", um Adresse, Namen und Passwort automatisch zu laden (oder tippe diese manuell ein). +5. Drücke "Connect". + +## Archipelago Text Client + +Es ist empfehlenswert, den "Archipelago Text Client", der eine Textansicht für gesendete und erhaltene Items liefert, beim Spielen nebenbei sichtbar zu haben. +
    Diese Nachrichten werden zwar auch im Spiel angezeigt, jedoch nur für ein paar Sekunden. Es ist leicht, eine dieser Nachrichten zu übersehen. + +

    Alternativ gibt es den visuellen Auto-Tracker mit Kartenansicht, der im nächsten Kapitel beschrieben wird. + +## Auto-Tracking + +The Witness hat einen voll funktionsfähigen Tracker mit Kartenansicht und Autotracking. + +1. Installiere [PopTracker](https://github.com/black-sliver/PopTracker/releases) und lade den [The Witness Auto-Tracker mit Kartenansicht](https://github.com/NewSoupVi/witness_archipelago_tracker/releases) herunter. +2. Öffne PopTracker, und lade das "The Witness"-Packet. +3. Klicke auf das "AP"-Symbol am oberen Fensterrand. +4. Gib die Archipelago-Adresse, deinen Namen und evtl. das Passwort ein. + +Der Rest sollte vollautomatisch ohne weitere Eingabe funktionieren. Der Tracker wird deine momentanen Items anzeigen und lösbare Rätsel grün auf der Karte anzeigen. Sobald du eine Rätselsequenz abschließt, wird sie grau markiert. \ No newline at end of file diff --git a/worlds/witness/docs/setup_fr.md b/worlds/witness/docs/setup_fr.md new file mode 100644 index 000000000000..db88911b9291 --- /dev/null +++ b/worlds/witness/docs/setup_fr.md @@ -0,0 +1,47 @@ +# Guide d'installation du Witness randomizer + +## Logiciels Requis + +- [The Witness pour Windows 64-bit (par exemple, la version Steam)](https://store.steampowered.com/app/210970/The_Witness/) +- [The Witness Archipelago Randomizer](https://github.com/NewSoupVi/The-Witness-Randomizer-for-Archipelago/releases/latest) + +## Logiciels Facultatifs + +- [ArchipelagoTextClient](https://github.com/ArchipelagoMW/Archipelago/releases) +- [The Witness Map- et Auto-Tracker](https://github.com/NewSoupVi/witness_archipelago_tracker/releases), pour usage avec [PopTracker](https://github.com/black-sliver/PopTracker/releases) + +## Rejoindre un jeu multimonde + +1. Lancez The Witness +2. Commencez une nouvelle partie +3. Lancez [The Witness Archipelago Randomizer](https://github.com/NewSoupVi/The-Witness-Randomizer-for-Archipelago/releases/latest) +4. Inscrivez l'adresse Archipelago, votre nom de joueur et le mot de passe du jeu multimonde +5. Cliquez sur "Connect" +6. Jouez! + +Pour continuer un jeu multimonde précedemment commencé: + +1. Lancez The Witness +2. Chargez la sauvegarde sur laquelle vous avez dernièrement joué ce monde, si ce n'est pas celle qui a été chargée automatiquement +3. Lancez [The Witness Archipelago Randomizer](https://github.com/NewSoupVi/The-Witness-Randomizer-for-Archipelago/releases/latest) +4. Cliquez sur "Load Credentials" (ou tapez les manuellement) +5. Cliquez sur "Connect" + +## Archipelago Text Client + +Il est recommandé d'utiliser le "Archipelago Text Client" en parallèle afin de suivre quels items vous envoyez et recevez. +
    The Witness affiche également ces informations en jeu, mais seulement pour une courte période et donc il est facile de manquer ces messages. + +

    Bien sûr, vous pouvez également utiliser l'auto-tracker! + +## Auto-Tracking + +The Witness a un tracker fonctionnel qui supporte l'auto-tracking. + +1. Téléchargez [The Witness Map- and Auto-Tracker](https://github.com/NewSoupVi/witness_archipelago_tracker/releases) et [PopTracker](https://github.com/black-sliver/PopTracker/releases). +2. Ouvrez Poptracker, puis chargez le pack Witness. +3. Cliquez sur l'icone "AP" qui se situe au dessus de la carte. +4. Inscrivez l'adresse Archipelago, votre nom de joueur et le mot de passe du jeu multimonde. + +Le reste devrait être pris en charge par Poptracker - les items que vous recevrez et les puzzles que vous résolverez seront automatiquement indiqués. De plus, Poptracker est en mesure de détecter +vos paramètres de jeu - les puzzles accessibles seront alors masqués ou affichés en fonction de vos paramètres de randomization et de logique. Veuillez noter que le tracker peut être obsolète. \ No newline at end of file From 749c2435ed4270d2f8e81dd427cda878d0544c1b Mon Sep 17 00:00:00 2001 From: GreenMarco <71452195+GreenMarco@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:43:54 -0600 Subject: [PATCH 0570/1218] Hollow Knight: Add Spanish Language Docs (#5156) Co-authored-by: qwint --- worlds/hk/__init__.py | 12 +++++- worlds/hk/docs/es_Hollow Knight.md | 25 ++++++++++++ worlds/hk/docs/setup_es.md | 64 ++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 worlds/hk/docs/es_Hollow Knight.md create mode 100644 worlds/hk/docs/setup_es.md diff --git a/worlds/hk/__init__.py b/worlds/hk/__init__.py index 31770637aa9a..317d29334b35 100644 --- a/worlds/hk/__init__.py +++ b/worlds/hk/__init__.py @@ -154,7 +154,17 @@ class HKWeb(WebWorld): ["JoaoVictor-FA"] ) - tutorials = [setup_en, setup_pt_br] + setup_es = Tutorial( + setup_en.tutorial_name, + setup_en.description, + "Español", + "setup_es.md", + "setup/es", + ["GreenMarco", "Panto UwUr"] + ) + + tutorials = [setup_en, setup_pt_br, setup_es] + game_info_languages = ["en", "es"] bug_report_page = "https://github.com/Ijwu/Archipelago.HollowKnight/issues/new?assignees=&labels=bug%2C+needs+investigation&template=bug_report.md&title=" diff --git a/worlds/hk/docs/es_Hollow Knight.md b/worlds/hk/docs/es_Hollow Knight.md new file mode 100644 index 000000000000..1a086086adff --- /dev/null +++ b/worlds/hk/docs/es_Hollow Knight.md @@ -0,0 +1,25 @@ +# Hollow Knight + +## ¿Dónde está la página de opciones? + +La [página de opciones de jugador para este juego](../player-options) contiene todas las opciones que necesitas para +configurar y exportar un archivo de configuración. + +## ¿Qué se randomiza en este juego? + +El randomizer cambia la ubicación de los objetos. Los objetos que se intercambian se eligen dentro de tu YAML. +Los costes de las tiendas son aleatorios. Los objetos que podrían ser aleatorios, pero no lo son, permanecerán sin +modificar en sus ubicaciones habituales. En particular, cuando los ítems con el PadreLarva y la Vidente están +parcialmente randomizados, los ítems randomizados se obtendrán de un cofre en la habitación, mientras que los ítems no +randomizados serán dados por el NPC de forma normal. + +## ¿Qué objetos de Hollow Knight pueden aparecer en los mundos de otros jugadores? + +Esto depende enteramente de tus opciones YAML. Algunos ejemplos son: amuletos, larvas, capullos de saviavida, geo, etc. + +## ¿Qué aspecto tienen los objetos de otro mundo en Hollow Knight? + +Cuando el jugador de Hollow Knight recoja un objeto de un lugar y sea un objeto para otro juego, aparecerá en la +pantalla de objetos recientes de ese jugador como un objeto enviado a otro jugador. Si el objeto es para otro jugador +de Hollow Knight entonces el sprite será el del sprite original del objeto. Si el objeto pertenece a un jugador que no +está jugando a Hollow Knight, el sprite será el logo del Archipiélago. \ No newline at end of file diff --git a/worlds/hk/docs/setup_es.md b/worlds/hk/docs/setup_es.md new file mode 100644 index 000000000000..13628c401905 --- /dev/null +++ b/worlds/hk/docs/setup_es.md @@ -0,0 +1,64 @@ +# Hollow Knight Archipelago + +## Software requerido +* Descarga y descomprime Lumafly Mod manager desde el [sitio web de Lumafly](https://themulhima.github.io/Lumafly/) +* Tener una copia legal de Hollow Knight. + * Las versiones de Steam, GOG y Xbox Game Pass son compatibles + * Las versiones de Windows, Mac y Linux (Incluyendo Steam Deck) son compatibles + +## Instalación del mod de Archipelago con Lumafly +1. Ejecuta Lumafly y asegurate de localizar la carpeta de instalación de Hollow Knight +2. Instala el mod de Archipiélago haciendo click en cualquiera de los siguientes: + * Haz clic en uno de los enlaces de abajo para permitir Lumafly para instalar los mods. Lumafly pedirá + confirmación. + * [Archipiélago y dependencias solamente](https://themulhima.github.io/Lumafly/commands/download/?mods=Archipelago) + * [Archipelago con rando essentials](https://themulhima.github.io/Lumafly/commands/download/?mods=Archipelago/Archipelago%20Map%20Mod/RecentItemsDisplay/DebugMod/RandoStats/Additional%20Timelines/CompassAlwaysOn/AdditionalMaps/) + (incluye Archipelago Map Mod, RecentItemsDisplay, DebugMod, RandoStats, AdditionalTimelines, CompassAlwaysOn, + y AdditionalMaps). + * Haz clic en el botón "Instalar" situado junto a la entrada del mod "Archipiélago". Si lo deseas, instala también + "Archipelago Map Mod" para utilizarlo como rastreador en el juego. + Si lo requieres (Y recomiendo hacerlo) busca e instala Archipelago Map Mod para usar un tracker in-game +3. Ejecuta el juego desde el apartado de inicio haciendo click en el botón Launch with Mods + +## Que hago si Lumafly no encontro la ruta de instalación de mi juego? +1. Busca el directorio manualmente + * En Xbox Game pass: + 1. Entra a la Xbox App y dirigete sobre el icono de Hollow Knight que esta a la izquierda. + 2. Haz click en los 3 puntitos y elige el apartado Administrar + 3. Dirigete al apartado Archivos Locales y haz click en Buscar + 4. Abre en Hollow Knight, luego Content y copia la ruta de archivos que esta en la barra de navegación. + * En Steam: + 1. Si instalaste Hollow Knight en algún otro disco que no sea el predeterminado, ya sabrás donde se encuentra + el juego, ve a esa carpeta, abrela y copia la ruta de archivos que se encuentra en la barra de navegación. + * En Windows, la ruta predeterminada suele ser:`C:\Program Files (x86)\Steam\steamapps\common\Hollow Knight` + * En linux/Steam Deck suele ser: ~/.local/share/Steam/steamapps/common/Hollow Knight + * En Mac suele ser: ~/Library/Application Support/Steam/steamapps/common/Hollow Knight/hollow_knight.app +2. Ejecuta Lumafly como administrador y, cuando te pregunte por la ruta de instalación, pega la ruta que copeaste + anteriormente. + +## Configuración de tu fichero YAML +### ¿Qué es un YAML y por qué necesito uno? +Un archivo YAML es la forma en la que proporcionas tus opciones de jugador a Archipelago. +Mira la [guía básica de configuración multiworld](/tutorial/Archipelago/setup/en) aquí en la web de Archipelago para +aprender más, (solo se encuentra en Inglés). + +### ¿Dónde consigo un YAML? +Puedes usar la [página de opciones de juego para Hollow Knight](/games/Hollow%20Knight/player-options) aquí en la web +de Archipelago para generar un YAML usando una interfaz gráfica. + +## Unete a una partida de Archipelago en Hollow Knight +1. Inicia el juego con los mods necesarios indicados anteriormente. +2. Crea una **nueva partida.** +3. Elige el modo **Archipelago** en la selección de modos de partida. +4. Introduce la configuración correcta para tu servidor de Archipelago. +5. Pulsa **Iniciar** para iniciar la partida. El juego se quedará con la pantalla en negro unos segundos mientras + coloca todos los objetos. +6. El juego debera comenzar y ya estaras dentro del servidor. + * Si estas esperando a que termine un contador/timer, procura presionar el boton Start cuando el contador/timer + termine. + * Otra manera es pausar el juego y esperar a que el contador/timer termine cuando ingreses a la partida. + +## Consejos y otros comandos +Mientras juegas en un multiworld, puedes interactuar con el servidor usando varios comandos listados en la +[guía de comandos](/tutorial/Archipelago/commands/en). Puedes usar el Cliente de Texto Archipelago para hacer esto, +que está incluido en la última versión del [software de Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases/latest). \ No newline at end of file From 9e748332dcd1f66a697306c13db70c391373bccd Mon Sep 17 00:00:00 2001 From: SunCat Date: Tue, 15 Jul 2025 23:01:53 +0300 Subject: [PATCH 0571/1218] Various Games: Improve Custom Death Link Option Description (#4171) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: Scipio Wright Co-authored-by: LiquidCat64 <74896918+LiquidCat64@users.noreply.github.com> --- worlds/blasphemous/Options.py | 6 +----- worlds/bomb_rush_cyberfunk/Options.py | 6 +----- worlds/cv64/options.py | 17 ++++++++--------- worlds/cv64/rom.py | 6 +++--- worlds/hylics2/Options.py | 9 ++------- worlds/kh1/Options.py | 4 ++-- worlds/noita/options.py | 6 ++---- 7 files changed, 19 insertions(+), 35 deletions(-) diff --git a/worlds/blasphemous/Options.py b/worlds/blasphemous/Options.py index 2cb2d8a1d34d..74eb1139cef8 100644 --- a/worlds/blasphemous/Options.py +++ b/worlds/blasphemous/Options.py @@ -207,11 +207,7 @@ class EnemyScaling(DefaultOnToggle): class BlasphemousDeathLink(DeathLink): - """ - When you die, everyone dies. The reverse is also true. - - Note that Guilt Fragments will not appear when killed by Death Link. - """ + __doc__ = DeathLink.__doc__ + "\n\n Note that Guilt Fragments will not appear when killed by death link." @dataclass diff --git a/worlds/bomb_rush_cyberfunk/Options.py b/worlds/bomb_rush_cyberfunk/Options.py index 80831d064526..fd327d48ecd6 100644 --- a/worlds/bomb_rush_cyberfunk/Options.py +++ b/worlds/bomb_rush_cyberfunk/Options.py @@ -175,11 +175,7 @@ class DamageMultiplier(Range): class BRCDeathLink(DeathLink): - """ - When you die, everyone dies. The reverse is also true. - - This can be changed later in the options menu inside the Archipelago phone app. - """ + __doc__ = DeathLink.__doc__ + "\n\n This can be changed later in the options menu inside the Archipelago phone app." @dataclass diff --git a/worlds/cv64/options.py b/worlds/cv64/options.py index da1e1aba9440..62d7ec336912 100644 --- a/worlds/cv64/options.py +++ b/worlds/cv64/options.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from Options import (OptionGroup, Choice, DefaultOnToggle, ItemsAccessibility, PerGameCommonOptions, Range, Toggle, - StartInventoryPool) + StartInventoryPool, DeathLink) class CharacterStages(Choice): @@ -507,12 +507,11 @@ class WindowColorA(Range): default = 8 -class DeathLink(Choice): - """ - When you die, everyone dies. Of course the reverse is true too. - Explosive: Makes received DeathLinks kill you via the Magical Nitro explosion instead of the normal death animation. - """ - display_name = "DeathLink" +class CV64DeathLink(Choice): + __doc__ = (DeathLink.__doc__ + "\n\n Explosive: Makes received death links kill you via the Magical Nitro " + + "explosion instead of the normal death animation.") + + display_name = "Death Link" option_off = 0 alias_no = 0 alias_true = 1 @@ -575,7 +574,7 @@ class CV64Options(PerGameCommonOptions): map_lighting: MapLighting fall_guard: FallGuard cinematic_experience: CinematicExperience - death_link: DeathLink + death_link: CV64DeathLink cv64_option_groups = [ @@ -584,7 +583,7 @@ class CV64Options(PerGameCommonOptions): RenonFightCondition, VincentFightCondition, BadEndingCondition, IncreaseItemLimit, NerfHealingItems, LoadingZoneHeals, InvisibleItems, DropPreviousSubWeapon, PermanentPowerUps, IceTrapPercentage, IceTrapAppearance, DisableTimeRestrictions, SkipGondolas, SkipWaterwayBlocks, Countdown, BigToss, PantherDash, - IncreaseShimmySpeed, FallGuard, DeathLink + IncreaseShimmySpeed, FallGuard, CV64DeathLink ]), OptionGroup("cosmetics", [ WindowColorR, WindowColorG, WindowColorB, WindowColorA, BackgroundMusic, MapLighting, CinematicExperience diff --git a/worlds/cv64/rom.py b/worlds/cv64/rom.py index 830bed27796e..a40d3ab30034 100644 --- a/worlds/cv64/rom.py +++ b/worlds/cv64/rom.py @@ -16,7 +16,7 @@ from .aesthetics import renon_item_dialogue, get_item_text_color from .locations import get_location_info from .options import CharacterStages, VincentFightCondition, RenonFightCondition, PostBehemothBoss, RoomOfClocksBoss, \ - BadEndingCondition, DeathLink, DraculasCondition, InvisibleItems, Countdown, PantherDash + BadEndingCondition, CV64DeathLink, DraculasCondition, InvisibleItems, Countdown, PantherDash from settings import get_settings if TYPE_CHECKING: @@ -356,7 +356,7 @@ def apply_patches(caller: APProcedurePatch, rom: bytes, options_file: str) -> by rom_data.write_int32s(0xBFE190, patches.subweapon_surface_checker) # Make received DeathLinks blow you to smithereens instead of kill you normally. - if options["death_link"] == DeathLink.option_explosive: + if options["death_link"] == CV64DeathLink.option_explosive: rom_data.write_int32s(0xBFC0D0, patches.deathlink_nitro_edition) rom_data.write_int32(0x27A70, 0x10000008) # B [forward 0x08] rom_data.write_int32(0x27AA0, 0x0C0FFA78) # JAL 0x803FE9E0 @@ -365,7 +365,7 @@ def apply_patches(caller: APProcedurePatch, rom: bytes, options_file: str) -> by rom_data.write_int32(0x32DBC, 0x00000000) # Set the DeathLink ROM flag if it's on at all. - if options["death_link"] != DeathLink.option_off: + if options["death_link"] != CV64DeathLink.option_off: rom_data.write_byte(0xBFBFDE, 0x01) # DeathLink counter decrementer code diff --git a/worlds/hylics2/Options.py b/worlds/hylics2/Options.py index db9c316a7b1b..51072edcbd87 100644 --- a/worlds/hylics2/Options.py +++ b/worlds/hylics2/Options.py @@ -57,13 +57,8 @@ class ExtraLogic(DefaultOnToggle): class Hylics2DeathLink(DeathLink): - """ - When you die, everyone dies. The reverse is also true. - - Note that this also includes death by using the PERISH gesture. - - Can be toggled via in-game console command "/deathlink". - """ + __doc__ = (DeathLink.__doc__ + "\n\n Note that this also includes death by using the PERISH gesture." + + "\n\n Can be toggled via in-game console command \"/deathlink\".") @dataclass diff --git a/worlds/kh1/Options.py b/worlds/kh1/Options.py index 63732f61b2d0..7a79d5c1ea92 100644 --- a/worlds/kh1/Options.py +++ b/worlds/kh1/Options.py @@ -287,13 +287,13 @@ class BadStartingWeapons(Toggle): class DonaldDeathLink(Toggle): """ - If Donald is KO'ed, so is Sora. If Death Link is toggled on in your client, this will send a death to everyone. + If Donald is KO'ed, so is Sora. If Death Link is toggled on in your client, this will send a death to everyone who enabled death link. """ display_name = "Donald Death Link" class GoofyDeathLink(Toggle): """ - If Goofy is KO'ed, so is Sora. If Death Link is toggled on in your client, this will send a death to everyone. + If Goofy is KO'ed, so is Sora. If Death Link is toggled on in your client, this will send a death to everyone who enabled death link. """ display_name = "Goofy Death Link" diff --git a/worlds/noita/options.py b/worlds/noita/options.py index 8a973a0d7229..6798cc8ccd4c 100644 --- a/worlds/noita/options.py +++ b/worlds/noita/options.py @@ -121,10 +121,8 @@ class ShopPrice(Choice): class NoitaDeathLink(DeathLink): - """ - When you die, everyone dies. Of course, the reverse is true too. - You can disable this in the in-game mod options. - """ + __doc__ = (DeathLink.__doc__ + "\n\n You can disable this or set it to give yourself a trap effect when " + + "another player dies in the in-game mod options.") @dataclass From deed9de3e768e9da16b23f3f3e758d6b4c05ad09 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Tue, 15 Jul 2025 15:40:58 -0500 Subject: [PATCH 0572/1218] Core: Don't Cache the `get_all_state` Result (#4795) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- BaseClasses.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 6deb878097a0..ba07868655f8 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -5,6 +5,7 @@ import logging import random import secrets +import warnings from argparse import Namespace from collections import Counter, deque from collections.abc import Collection, MutableSequence @@ -438,12 +439,27 @@ def get_entrance(self, entrance_name: str, player: int) -> Entrance: def get_location(self, location_name: str, player: int) -> Location: return self.regions.location_cache[player][location_name] - def get_all_state(self, use_cache: bool, allow_partial_entrances: bool = False, + def get_all_state(self, use_cache: bool | None = None, allow_partial_entrances: bool = False, collect_pre_fill_items: bool = True, perform_sweep: bool = True) -> CollectionState: - cached = getattr(self, "_all_state", None) - if use_cache and cached: - return cached.copy() - + """ + Creates a new CollectionState, and collects all precollected items, all items in the multiworld itempool, those + specified in each worlds' `get_pre_fill_items()`, and then sweeps the multiworld collecting any other items + it is able to reach, building as complete of a completed game state as possible. + + :param use_cache: Deprecated and unused. + :param allow_partial_entrances: Whether the CollectionState should allow for disconnected entrances while + sweeping, such as before entrance randomization is complete. + :param collect_pre_fill_items: Whether the items in each worlds' `get_pre_fill_items()` should be added to this + state. + :param perform_sweep: Whether this state should perform a sweep for reachable locations, collecting any placed + items it can. + + :return: The completed CollectionState. + """ + if __debug__ and use_cache is not None: + # TODO swap to Utils.deprecate when we want this to crash on source and warn on frozen + warnings.warn("multiworld.get_all_state no longer caches all_state and this argument will be removed.", + DeprecationWarning) ret = CollectionState(self, allow_partial_entrances) for item in self.itempool: @@ -456,8 +472,6 @@ def get_all_state(self, use_cache: bool, allow_partial_entrances: bool = False, if perform_sweep: ret.sweep_for_advancements() - if use_cache: - self._all_state = ret return ret def get_items(self) -> List[Item]: From 1790a389c7e85630a0ba9197f04e56d67205a793 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Tue, 15 Jul 2025 17:04:27 -0400 Subject: [PATCH 0573/1218] TUNIC: Update Tests Per #4982 (#5191) --- worlds/tunic/test/__init__.py | 6 ------ worlds/tunic/test/bases.py | 5 +++++ worlds/tunic/test/test_access.py | 2 +- worlds/tunic/test/test_combat.py | 6 ++---- 4 files changed, 8 insertions(+), 11 deletions(-) create mode 100644 worlds/tunic/test/bases.py diff --git a/worlds/tunic/test/__init__.py b/worlds/tunic/test/__init__.py index d0b68955c538..e69de29bb2d1 100644 --- a/worlds/tunic/test/__init__.py +++ b/worlds/tunic/test/__init__.py @@ -1,6 +0,0 @@ -from test.bases import WorldTestBase - - -class TunicTestBase(WorldTestBase): - game = "TUNIC" - player = 1 diff --git a/worlds/tunic/test/bases.py b/worlds/tunic/test/bases.py new file mode 100644 index 000000000000..0e51bcd0139c --- /dev/null +++ b/worlds/tunic/test/bases.py @@ -0,0 +1,5 @@ +from test.bases import WorldTestBase + + +class TunicTestBase(WorldTestBase): + game = "TUNIC" diff --git a/worlds/tunic/test/test_access.py b/worlds/tunic/test/test_access.py index 6a26180cf026..1896db5d132a 100644 --- a/worlds/tunic/test/test_access.py +++ b/worlds/tunic/test/test_access.py @@ -1,5 +1,5 @@ -from . import TunicTestBase from .. import options +from .bases import TunicTestBase class TestAccess(TunicTestBase): diff --git a/worlds/tunic/test/test_combat.py b/worlds/tunic/test/test_combat.py index c0e76ef92bca..70324247dff8 100644 --- a/worlds/tunic/test/test_combat.py +++ b/worlds/tunic/test/test_combat.py @@ -1,17 +1,15 @@ from BaseClasses import ItemClassification from collections import Counter -from . import TunicTestBase -from .. import options +from .. import options, TunicWorld +from .bases import TunicTestBase from ..combat_logic import (check_combat_reqs, area_data, get_money_count, calc_effective_hp, get_potion_level, get_hp_level, get_def_level, get_sp_level, has_combat_reqs) from ..items import item_table -from .. import TunicWorld class TestCombat(TunicTestBase): options = {options.CombatLogic.internal_name: options.CombatLogic.option_on} - player = 1 world: TunicWorld combat_items = [] # these are items that are progression that do not contribute to combat logic From b90dcfb04135eb3661ab107ef1d741e52e4abdb3 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Wed, 16 Jul 2025 10:31:12 +0200 Subject: [PATCH 0574/1218] =?UTF-8?q?The=20Witness:=20Add=20Glass=20Factor?= =?UTF-8?q?y=20Entry=20Panel=20as=20a=20location=20in=20all=20options?= =?UTF-8?q?=C2=A0#4695?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worlds/witness/data/static_locations.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/witness/data/static_locations.py b/worlds/witness/data/static_locations.py index a5cfc3b49f59..029dcd5dcb35 100644 --- a/worlds/witness/data/static_locations.py +++ b/worlds/witness/data/static_locations.py @@ -18,6 +18,7 @@ "Outside Tutorial Outpost Entry Panel", "Outside Tutorial Outpost Exit Panel", + "Glass Factory Entry Panel", "Glass Factory Discard", "Glass Factory Back Wall 5", "Glass Factory Front 3", From 477028a025b2803c443ef0a4629170beb4deb58d Mon Sep 17 00:00:00 2001 From: Jacob Lewis Date: Wed, 16 Jul 2025 10:11:07 -0500 Subject: [PATCH 0575/1218] Dics: Add Webhost API Documententation (#4887) * capitialization changes * ditto * Revert "ditto" This reverts commit 17cf596735888e91850954c7306ce0b80d7e453d. * Revert "capitialization changes" This reverts commit 6fb86c6568da2c08b5f8e691d4fc810e3ab09a44. * full revert and full commit * Update docs/webhost api.md Co-authored-by: qwint * Update docs/webhost api.md Co-authored-by: Aaron Wagener * Update docs/webhost api.md Co-authored-by: Aaron Wagener * Update webhost api.md * Removed in-devolopment API * Apply standard capitilization and grammar flow Co-authored-by: Scipio Wright * declarative language * Apply suggestions from code review Co-authored-by: qwint * datapackage_checksum clarification, and /datapackage clairfication * /dp/checksum clarification * Detailed responces and /generation breakdown * Update webhost api.md * Made output anonomous * Update docs/webhost api.md Co-authored-by: qwint * Swapped IDs to UUID, and added language around UUID vs SUUID * Apply suggestions from code review formatting and grammar Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Condensed paragraphs and waterfalled headders --------- Co-authored-by: qwint Co-authored-by: Aaron Wagener Co-authored-by: Scipio Wright Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- docs/webhost api.md | 351 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) create mode 100644 docs/webhost api.md diff --git a/docs/webhost api.md b/docs/webhost api.md new file mode 100644 index 000000000000..dba57e554cfb --- /dev/null +++ b/docs/webhost api.md @@ -0,0 +1,351 @@ +# API Guide + +Archipelago has a rudimentary API that can be queried by endpoints. The API is a work-in-progress and should be improved over time. + +The following API requests are formatted as: `https:///api/` + +The returned data will be formated in a combination of JSON lists or dicts, with their keys or values being notated in `blocks` (if applicable) + +Current endpoints: +- Datapackage API + - [`/datapackage`](#datapackage) + - [`/datapackage/`](#datapackagestringchecksum) + - [`/datapackage_checksum`](#datapackagechecksum) +- Generation API + - [`/generate`](#generate) + - [`/status/`](#status) +- Room API + - [`/room_status/`](#roomstatus) +- User API + - [`/get_rooms`](#getrooms) + - [`/get_seeds`](#getseeds) + + +## UUID vs SUUID +Currently, the server reports back the item's `UUID` (Universally Unique Identifier). The item's `UUID` needs to be converted to a `base64 UUID` (nicknamed a `ShortUUID` and refered to as `SUUID` in the remainder of this document) that are URL safe in order to be queried via API endpoints. +- [PR 4944](https://github.com/ArchipelagoMW/Archipelago/pull/4944) is in progress to convert API returns into SUUIDs + +## Datapackage Endpoints +These endpoints are used by applications to acquire a room's datapackage, and validate that they have the correct datapackage for use. Datapackages normally include, item IDs, location IDs, and name groupings, for a given room, and are essential for mapping IDs received from Archipelago to their correct items or locations. + +### `/datapackage` + +Fetches the current datapackage from the WebHost. +You'll receive a dict named `games` that contains a named dict of every game and its data currently supported by Archipelago. +Each game will have: +- A checksum `checksum` +- A dict of item groups `item_name_groups` +- Item name to AP ID dict `item_name_to_id` +- A dict of location groups `location_name_groups` +- Location name to AP ID dict `location_name_to_id` + +Example: +``` +{ + "games": { + ... + "Clique": { + "checksum": "0271f7a80b44ba72187f92815c2bc8669cb464c7", + "item_name_groups": { + "Everything": [ + "A Cool Filler Item (No Satisfaction Guaranteed)", + "Button Activation", + "Feeling of Satisfaction" + ] + }, + "item_name_to_id": { + "A Cool Filler Item (No Satisfaction Guaranteed)": 69696967, + "Button Activation": 69696968, + "Feeling of Satisfaction": 69696969 + }, + "location_name_groups": { + "Everywhere": [ + "The Big Red Button", + "The Item on the Desk" + ] + }, + "location_name_to_id": { + "The Big Red Button": 69696969, + "The Item on the Desk": 69696968 + } + }, + ... + } +} +``` + +### `/datapackage/` + +Fetches a single datapackage by checksum. +Returns a dict of the game's data with: +- A checksum `checksum` +- A dict of item groups `item_name_groups` +- Item name to AP ID dict `item_name_to_id` +- A dict of location groups `location_name_groups` +- Location name to AP ID dict `location_name_to_id` + +Its format will be identical to the whole-datapackage endpoint (`/datapackage`), except you'll only be returned the single game's data in a dict. + +### `/datapackage_checksum` + +Fetches the checksums of the current static datapackages on the WebHost. +You'll receive a dict with `game:checksum` key-value pairs for all the current officially supported games. +Example: +``` +{ +... +"Donkey Kong Country 3":"f90acedcd958213f483a6a4c238e2a3faf92165e", +"Factorio":"a699194a9589db3ebc0d821915864b422c782f44", +... +} +``` + + +## Generation Endpoint +These endpoints are used internally for the WebHost to generate games and validate their generation. They are also used by external applications to generate games automatically. + +### `/generate` + +Submits a game to the WebHost for generation. +**This endpoint only accepts a POST HTTP request.** + +There are two ways to submit data for generation: With a file and with JSON. + +#### With a file: +Have your ZIP of yaml(s) or a single yaml, and submit a POST request to the `/generate` endpoint. +If the options are valid, you'll be returned a successful generation response. (see [Generation Response](#generation-response)) + +Example using the python requests library: +``` +file = {'file': open('Games.zip', 'rb')} +req = requests.post("https://archipelago.gg/api/generate", files=file) +``` + +#### With JSON: +Compile your weights/yaml data into a dict. Then insert that into a dict with the key `"weights"`. +Finally, submit a POST request to the `/generate` endpoint. +If the weighted options are valid, you'll be returned a successful generation response (see [Generation Response](#generation-response)) + +Example using the python requests library: +``` +data = {"Test":{"game": "Factorio","name": "Test","Factorio": {}},} +weights={"weights": data} +req = requests.post("https://archipelago.gg/api/generate", json=weights) +``` + +#### Generation Response: +##### Successful Generation: +Upon successful generation, you'll be sent a JSON dict response detailing the generation: +- The UUID of the generation `detail` +- The SUUID of the generation `encoded` +- The response text `text` +- The page that will resolve to the seed/room generation page once generation has completed `url` +- The API status page of the generation `wait_api_url` (see [Status Endpoint](#status)) + +Example: +``` +{ + "detail": "19878f16-5a58-4b76-aab7-d6bf38be9463", + "encoded": "GYePFlpYS3aqt9a_OL6UYw", + "text": "Generation of seed 19878f16-5a58-4b76-aab7-d6bf38be9463 started successfully.", + "url": "http://archipelago.gg/wait/GYePFlpYS3aqt9a_OL6UYw", + "wait_api_url": "http://archipelago.gg/api/status/GYePFlpYS3aqt9a_OL6UYw" +} +``` + +##### Failed Generation: + +Upon failed generation, you'll be returned a single key-value pair. The key will always be `text` +The value will give you a hint as to what may have gone wrong. +- Options without tags, and a 400 status code +- Options in a string, and a 400 status code +- Invalid file/weight string, `No options found. Expected file attachment or json weights.` with a 400 status code +- Too many slots for the server to process, `Max size of multiworld exceeded` with a 409 status code + +If the generation detects a issue in generation, you'll be sent a dict with two key-value pairs (`text` and `detail`) and a 400 status code. The values will be: +- Summary of issue in `text` +- Detailed issue in `detail` + +In the event of an unhandled server exception, you'll be provided a dict with a single key `text`: +- Exception, `Uncought Exception: ` with a 500 status code + +### `/status/` + +Retrieves the status of the seed's generation. +This endpoint will return a dict with a single key-vlaue pair. The key will always be `text` +The value will tell you the status of the generation: +- Generation was completed: `Generation done` with a 201 status code +- Generation request was not found: `Generation not found` with a 404 status code +- Generation of the seed failed: `Generation failed` with a 500 status code +- Generation is in progress still: `Generation running` with a 202 status code + +## Room Endpoints +Endpoints to fetch information of the active WebHost room with the supplied room_ID. + +### `/room_status/` + +Will provide a dict of room data with the following keys: +- Tracker UUID (`tracker`) +- A list of players (`players`) + - Each item containing a list with the Slot name and Game +- Last known hosted port (`last_port`) +- Last activity timestamp (`last_activity`) +- The room timeout counter (`timeout`) +- A list of downloads for files required for gameplay (`downloads`) + - Each item is a dict containings the download URL and slot (`slot`, `download`) + +Example: +``` +{ + "downloads": [ + { + "download": "/slot_file/kK5fmxd8TfisU5Yp_eg/1", + "slot": 1 + }, + { + "download": "/slot_file/kK5fmxd8TfisU5Yp_eg/2", + "slot": 2 + }, + { + "download": "/slot_file/kK5fmxd8TfisU5Yp_eg/3", + "slot": 3 + }, + { + "download": "/slot_file/kK5fmxd8TfisU5Yp_eg/4", + "slot": 4 + }, + { + "download": "/slot_file/kK5fmxd8TfisU5Yp_eg/5", + "slot": 5 + } + ], + "last_activity": "Fri, 18 Apr 2025 20:35:45 GMT", + "last_port": 52122, + "players": [ + [ + "Slot_Name_1", + "Ocarina of Time" + ], + [ + "Slot_Name_2", + "Ocarina of Time" + ], + [ + "Slot_Name_3", + "Ocarina of Time" + ], + [ + "Slot_Name_4", + "Ocarina of Time" + ], + [ + "Slot_Name_5", + "Ocarina of Time" + ] + ], + "timeout": 7200, + "tracker": "cf6989c0-4703-45d7-a317-2e5158431171" +} +``` + +## User Endpoints +User endpoints can get room and seed details from the current session tokens (cookies) + +### `/get_rooms` + +Retreives a list of all rooms currently owned by the session token. +Each list item will contain a dict with the room's details: +- Room UUID (`room_id`) +- Seed UUID (`seed_id`) +- Creation timestamp (`creation_time`) +- Last activity timestamp (`last_activity`) +- Last known AP port (`last_port`) +- Room timeout counter in seconds (`timeout`) +- Room tracker UUID (`tracker`) + +Example: +``` +[ + { + "creation_time": "Fri, 18 Apr 2025 19:46:53 GMT", + "last_activity": "Fri, 18 Apr 2025 21:16:02 GMT", + "last_port": 52122, + "room_id": "90ae5f9b-177c-4df8-ac53-9629fc3bff7a", + "seed_id": "efbd62c2-aaeb-4dda-88c3-f461c029cef6", + "timeout": 7200, + "tracker": "cf6989c0-4703-45d7-a317-2e5158431171" + }, + { + "creation_time": "Fri, 18 Apr 2025 20:36:42 GMT", + "last_activity": "Fri, 18 Apr 2025 20:36:46 GMT", + "last_port": 56884, + "room_id": "14465c05-d08e-4d28-96bd-916f994609d8", + "seed_id": "a528e34c-3b4f-42a9-9f8f-00a4fd40bacb", + "timeout": 7200, + "tracker": "4e624bd8-32b6-42e4-9178-aa407f72751c" + } +] +``` + +### `/get_seeds` + +Retreives a list of all seeds currently owned by the session token. +Each item in the list will contain a dict with the seed's details: +- Seed UUID (`seed_id`) +- Creation timestamp (`creation_time`) +- A list of player slots (`players`) + - Each item in the list will contain a list of the slot name and game + +Example: +``` +[ + { + "creation_time": "Fri, 18 Apr 2025 19:46:52 GMT", + "players": [ + [ + "Slot_Name_1", + "Ocarina of Time" + ], + [ + "Slot_Name_2", + "Ocarina of Time" + ], + [ + "Slot_Name_3", + "Ocarina of Time" + ], + [ + "Slot_Name_4", + "Ocarina of Time" + ], + [ + "Slot_Name_5", + "Ocarina of Time" + ] + ], + "seed_id": "efbd62c2-aaeb-4dda-88c3-f461c029cef6" + }, + { + "creation_time": "Fri, 18 Apr 2025 20:36:39 GMT", + "players": [ + [ + "Slot_Name_1", + "Clique" + ], + [ + "Slot_Name_2", + "Clique" + ], + [ + "Slot_Name_3", + "Clique" + ], + [ + "Slot_Name_4", + "Archipelago" + ] + ], + "seed_id": "a528e34c-3b4f-42a9-9f8f-00a4fd40bacb" + } +] +``` From e9e0861eb751996c2e65808ec62ffd9c5b55ec33 Mon Sep 17 00:00:00 2001 From: qwint Date: Wed, 16 Jul 2025 10:34:28 -0500 Subject: [PATCH 0576/1218] WebHostLib: Properly Format IDs in API Responses (#4944) * update the id formatter to use staticmethods to not fake the unused self arg, and then use the formatter for the user session endpoints * missed an id (ty treble) * clean up duplicate code * Update WebHostLib/__init__.py Co-authored-by: Aaron Wagener * keep the BaseConverter format * lol, change all the instances * revert this --------- Co-authored-by: Aaron Wagener --- WebHostLib/__init__.py | 14 +++++++++++--- WebHostLib/api/room.py | 3 ++- WebHostLib/api/user.py | 9 +++++---- test/hosting/webhost.py | 10 ++++++---- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/WebHostLib/__init__.py b/WebHostLib/__init__.py index 934cc2498d03..e928b8f3b1b5 100644 --- a/WebHostLib/__init__.py +++ b/WebHostLib/__init__.py @@ -61,18 +61,26 @@ Compress(app) +def to_python(value): + return uuid.UUID(bytes=base64.urlsafe_b64decode(value + '==')) + + +def to_url(value): + return base64.urlsafe_b64encode(value.bytes).rstrip(b'=').decode('ascii') + + class B64UUIDConverter(BaseConverter): def to_python(self, value): - return uuid.UUID(bytes=base64.urlsafe_b64decode(value + '==')) + return to_python(value) def to_url(self, value): - return base64.urlsafe_b64encode(value.bytes).rstrip(b'=').decode('ascii') + return to_url(value) # short UUID app.url_map.converters["suuid"] = B64UUIDConverter -app.jinja_env.filters['suuid'] = lambda value: base64.urlsafe_b64encode(value.bytes).rstrip(b'=').decode('ascii') +app.jinja_env.filters["suuid"] = to_url app.jinja_env.filters["title_sorted"] = title_sorted diff --git a/WebHostLib/api/room.py b/WebHostLib/api/room.py index 9337975695b2..78623bbe3eb3 100644 --- a/WebHostLib/api/room.py +++ b/WebHostLib/api/room.py @@ -3,6 +3,7 @@ from flask import abort, url_for +from WebHostLib import to_url import worlds.Files from . import api_endpoints, get_players from ..models import Room @@ -33,7 +34,7 @@ def supports_apdeltapatch(game: str) -> bool: downloads.append(slot_download) return { - "tracker": room.tracker, + "tracker": to_url(room.tracker), "players": get_players(room.seed), "last_port": room.last_port, "last_activity": room.last_activity, diff --git a/WebHostLib/api/user.py b/WebHostLib/api/user.py index 2524cc40a628..59c8e5728332 100644 --- a/WebHostLib/api/user.py +++ b/WebHostLib/api/user.py @@ -1,6 +1,7 @@ from flask import session, jsonify from pony.orm import select +from WebHostLib import to_url from WebHostLib.models import Room, Seed from . import api_endpoints, get_players @@ -10,13 +11,13 @@ def get_rooms(): response = [] for room in select(room for room in Room if room.owner == session["_id"]): response.append({ - "room_id": room.id, - "seed_id": room.seed.id, + "room_id": to_url(room.id), + "seed_id": to_url(room.seed.id), "creation_time": room.creation_time, "last_activity": room.last_activity, "last_port": room.last_port, "timeout": room.timeout, - "tracker": room.tracker, + "tracker": to_url(room.tracker), }) return jsonify(response) @@ -26,7 +27,7 @@ def get_seeds(): response = [] for seed in select(seed for seed in Seed if seed.owner == session["_id"]): response.append({ - "seed_id": seed.id, + "seed_id": to_url(seed.id), "creation_time": seed.creation_time, "players": get_players(seed), }) diff --git a/test/hosting/webhost.py b/test/hosting/webhost.py index 4db605e8c1ea..8888c3fb87fc 100644 --- a/test/hosting/webhost.py +++ b/test/hosting/webhost.py @@ -2,6 +2,8 @@ from pathlib import Path from typing import TYPE_CHECKING, Optional, cast +from WebHostLib import to_python + if TYPE_CHECKING: from flask import Flask from werkzeug.test import Client as FlaskClient @@ -103,7 +105,7 @@ def stop_room(app_client: "FlaskClient", poll_interval = 2 print(f"Stopping room {room_id}") - room_uuid = app.url_map.converters["suuid"].to_python(None, room_id) # type: ignore[arg-type] + room_uuid = to_python(room_id) if timeout is not None: sleep(.1) # should not be required, but other things might use threading @@ -156,7 +158,7 @@ def set_room_timeout(room_id: str, timeout: float) -> None: from WebHostLib.models import Room from WebHostLib import app - room_uuid = app.url_map.converters["suuid"].to_python(None, room_id) # type: ignore[arg-type] + room_uuid = to_python(room_id) with db_session: room: Room = Room.get(id=room_uuid) room.timeout = timeout @@ -168,7 +170,7 @@ def get_multidata_for_room(webhost_client: "FlaskClient", room_id: str) -> bytes from WebHostLib.models import Room from WebHostLib import app - room_uuid = app.url_map.converters["suuid"].to_python(None, room_id) # type: ignore[arg-type] + room_uuid = to_python(room_id) with db_session: room: Room = Room.get(id=room_uuid) return cast(bytes, room.seed.multidata) @@ -180,7 +182,7 @@ def set_multidata_for_room(webhost_client: "FlaskClient", room_id: str, data: by from WebHostLib.models import Room from WebHostLib import app - room_uuid = app.url_map.converters["suuid"].to_python(None, room_id) # type: ignore[arg-type] + room_uuid = to_python(room_id) with db_session: room: Room = Room.get(id=room_uuid) room.seed.multidata = data From 4a43a6ae138b9dc64afa7919c82d62eee05a18f2 Mon Sep 17 00:00:00 2001 From: qwint Date: Wed, 16 Jul 2025 10:51:34 -0500 Subject: [PATCH 0577/1218] Docs: Clean up SUUID Post #4944 (#5196) --- docs/webhost api.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/webhost api.md b/docs/webhost api.md index dba57e554cfb..c8936205ecb9 100644 --- a/docs/webhost api.md +++ b/docs/webhost api.md @@ -21,10 +21,6 @@ Current endpoints: - [`/get_seeds`](#getseeds) -## UUID vs SUUID -Currently, the server reports back the item's `UUID` (Universally Unique Identifier). The item's `UUID` needs to be converted to a `base64 UUID` (nicknamed a `ShortUUID` and refered to as `SUUID` in the remainder of this document) that are URL safe in order to be queried via API endpoints. -- [PR 4944](https://github.com/ArchipelagoMW/Archipelago/pull/4944) is in progress to convert API returns into SUUIDs - ## Datapackage Endpoints These endpoints are used by applications to acquire a room's datapackage, and validate that they have the correct datapackage for use. Datapackages normally include, item IDs, location IDs, and name groupings, for a given room, and are essential for mapping IDs received from Archipelago to their correct items or locations. @@ -185,7 +181,7 @@ Endpoints to fetch information of the active WebHost room with the supplied room ### `/room_status/` Will provide a dict of room data with the following keys: -- Tracker UUID (`tracker`) +- Tracker SUUID (`tracker`) - A list of players (`players`) - Each item containing a list with the Slot name and Game - Last known hosted port (`last_port`) @@ -255,13 +251,13 @@ User endpoints can get room and seed details from the current session tokens (co Retreives a list of all rooms currently owned by the session token. Each list item will contain a dict with the room's details: -- Room UUID (`room_id`) -- Seed UUID (`seed_id`) +- Room SUUID (`room_id`) +- Seed SUUID (`seed_id`) - Creation timestamp (`creation_time`) - Last activity timestamp (`last_activity`) - Last known AP port (`last_port`) - Room timeout counter in seconds (`timeout`) -- Room tracker UUID (`tracker`) +- Room tracker SUUID (`tracker`) Example: ``` @@ -291,7 +287,7 @@ Example: Retreives a list of all seeds currently owned by the session token. Each item in the list will contain a dict with the seed's details: -- Seed UUID (`seed_id`) +- Seed SUUID (`seed_id`) - Creation timestamp (`creation_time`) - A list of player slots (`players`) - Each item in the list will contain a list of the slot name and game From 604ab79af9f5432ed957775a15677b3dcc6d5d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Wed, 16 Jul 2025 11:57:06 -0400 Subject: [PATCH 0578/1218] Stardew Valley: Add walnutsanity prefix to locations (#4934) --- worlds/stardew_valley/data/locations.csv | 188 ++++++++--------- worlds/stardew_valley/rules.py | 52 ++--- .../stardew_valley/test/TestWalnutsanity.py | 197 ++++++++++-------- 3 files changed, 231 insertions(+), 206 deletions(-) diff --git a/worlds/stardew_valley/data/locations.csv b/worlds/stardew_valley/data/locations.csv index 2829a1252240..14554a3bcda2 100644 --- a/worlds/stardew_valley/data/locations.csv +++ b/worlds/stardew_valley/data/locations.csv @@ -2316,100 +2316,100 @@ id,region,name,tags,mod_name 4069,Museum,Read Note From Gunther,"BOOKSANITY,BOOKSANITY_LOST", 4070,Museum,Read Goblins by M. Jasper,"BOOKSANITY,BOOKSANITY_LOST", 4071,Museum,Read Secret Statues Acrostics,"BOOKSANITY,BOOKSANITY_LOST", -4101,Clint's Blacksmith,Open Golden Coconut,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4102,Island West,Fishing Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4103,Island West,Fishing Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4104,Island North,Fishing Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4105,Island North,Fishing Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4106,Island Southeast,Fishing Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4107,Island East,Jungle Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4108,Island East,Banana Altar,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4109,Leo's Hut,Leo's Tree,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4110,Island Shrine,Gem Birds Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4111,Island Shrine,Gem Birds Shrine,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4112,Island West,Harvesting Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4113,Island West,Harvesting Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4114,Island West,Harvesting Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4115,Island West,Harvesting Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4116,Island West,Harvesting Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4117,Gourmand Frog Cave,Gourmand Frog Melon,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4118,Gourmand Frog Cave,Gourmand Frog Wheat,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4119,Gourmand Frog Cave,Gourmand Frog Garlic,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4120,Island West,Journal Scrap #6,"WALNUTSANITY,WALNUTSANITY_DIG", -4121,Island West,Mussel Node Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4122,Island West,Mussel Node Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4123,Island West,Mussel Node Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4124,Island West,Mussel Node Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4125,Island West,Mussel Node Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4126,Shipwreck,Shipwreck Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4127,Island West,Whack A Mole,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4128,Island West,Starfish Triangle,"WALNUTSANITY,WALNUTSANITY_DIG", -4129,Island West,Starfish Diamond,"WALNUTSANITY,WALNUTSANITY_DIG", -4130,Island West,X in the sand,"WALNUTSANITY,WALNUTSANITY_DIG", -4131,Island West,Diamond Of Indents,"WALNUTSANITY,WALNUTSANITY_DIG", -4132,Island West,Bush Behind Coconut Tree,"WALNUTSANITY,WALNUTSANITY_BUSH", -4133,Island West,Journal Scrap #4,"WALNUTSANITY,WALNUTSANITY_DIG", -4134,Island West,Walnut Room Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4135,Island West,Coast Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4136,Island West,Tiger Slime Walnut,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4137,Island West,Bush Behind Mahogany Tree,"WALNUTSANITY,WALNUTSANITY_BUSH", -4138,Island West,Circle Of Grass,"WALNUTSANITY,WALNUTSANITY_DIG", -4139,Island West,Below Colored Crystals Cave Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4140,Colored Crystals Cave,Colored Crystals,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4141,Island West,Cliff Edge Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4142,Island West,Diamond Of Pebbles,"WALNUTSANITY,WALNUTSANITY_DIG", -4143,Island West,Farm Parrot Express Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4144,Island West,Farmhouse Cliff Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4145,Island North,Big Circle Of Stones,"WALNUTSANITY,WALNUTSANITY_DIG", -4146,Island North,Grove Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4147,Island North,Diamond Of Grass,"WALNUTSANITY,WALNUTSANITY_DIG", -4148,Island North,Small Circle Of Stones,"WALNUTSANITY,WALNUTSANITY_DIG", -4149,Island North,Patch Of Sand,"WALNUTSANITY,WALNUTSANITY_DIG", -4150,Dig Site,Crooked Circle Of Stones,"WALNUTSANITY,WALNUTSANITY_DIG", -4151,Dig Site,Above Dig Site Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4152,Dig Site,Above Field Office Bush 1,"WALNUTSANITY,WALNUTSANITY_BUSH", -4153,Dig Site,Above Field Office Bush 2,"WALNUTSANITY,WALNUTSANITY_BUSH", -4154,Field Office,Complete Large Animal Collection,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4155,Field Office,Complete Snake Collection,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4156,Field Office,Complete Mummified Frog Collection,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4157,Field Office,Complete Mummified Bat Collection,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4158,Field Office,Purple Flowers Island Survey,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4159,Field Office,Purple Starfish Island Survey,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4160,Island North,Bush Behind Volcano Tree,"WALNUTSANITY,WALNUTSANITY_BUSH", -4161,Island North,Arc Of Stones,"WALNUTSANITY,WALNUTSANITY_DIG", -4162,Island North,Protruding Tree Walnut,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4163,Island North,Journal Scrap #10,"WALNUTSANITY,WALNUTSANITY_DIG", -4164,Island North,Northmost Point Circle Of Stones,"WALNUTSANITY,WALNUTSANITY_DIG", -4165,Island North,Hidden Passage Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4166,Volcano Secret Beach,Secret Beach Bush 1,"WALNUTSANITY,WALNUTSANITY_BUSH", -4167,Volcano Secret Beach,Secret Beach Bush 2,"WALNUTSANITY,WALNUTSANITY_BUSH", -4168,Volcano - Floor 5,Volcano Rocks Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4169,Volcano - Floor 5,Volcano Rocks Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4170,Volcano - Floor 10,Volcano Rocks Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4171,Volcano - Floor 10,Volcano Rocks Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4172,Volcano - Floor 10,Volcano Rocks Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4173,Volcano - Floor 5,Volcano Monsters Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4174,Volcano - Floor 5,Volcano Monsters Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4175,Volcano - Floor 10,Volcano Monsters Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4176,Volcano - Floor 10,Volcano Monsters Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4177,Volcano - Floor 10,Volcano Monsters Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4178,Volcano - Floor 5,Volcano Crates Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4179,Volcano - Floor 5,Volcano Crates Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4180,Volcano - Floor 10,Volcano Crates Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4181,Volcano - Floor 10,Volcano Crates Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4182,Volcano - Floor 10,Volcano Crates Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4183,Volcano - Floor 5,Volcano Common Chest Walnut,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4184,Volcano - Floor 10,Volcano Rare Chest Walnut,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", -4185,Volcano - Floor 10,Forge Entrance Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4186,Volcano - Floor 10,Forge Exit Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4187,Island North,Cliff Over Island South Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", -4188,Island Southeast,Starfish Tide Pool,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4189,Island Southeast,Diamond Of Yellow Starfish,"WALNUTSANITY,WALNUTSANITY_DIG", -4190,Island Southeast,Mermaid Song,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4191,Pirate Cove,Pirate Darts 1,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4192,Pirate Cove,Pirate Darts 2,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4193,Pirate Cove,Pirate Darts 3,"WALNUTSANITY,WALNUTSANITY_PUZZLE", -4194,Pirate Cove,Pirate Cove Patch Of Sand,"WALNUTSANITY,WALNUTSANITY_DIG", +4101,Clint's Blacksmith,Walnutsanity: Open Golden Coconut,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4102,Island West,Walnutsanity: Fishing Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4103,Island West,Walnutsanity: Fishing Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4104,Island North,Walnutsanity: Fishing Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4105,Island North,Walnutsanity: Fishing Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4106,Island Southeast,Walnutsanity: Fishing Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4107,Island East,Walnutsanity: Jungle Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4108,Island East,Walnutsanity: Banana Altar,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4109,Leo's Hut,Walnutsanity: Leo's Tree,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4110,Island Shrine,Walnutsanity: Gem Birds Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4111,Island Shrine,Walnutsanity: Gem Birds Shrine,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4112,Island West,Walnutsanity: Harvesting Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4113,Island West,Walnutsanity: Harvesting Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4114,Island West,Walnutsanity: Harvesting Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4115,Island West,Walnutsanity: Harvesting Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4116,Island West,Walnutsanity: Harvesting Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4117,Gourmand Frog Cave,Walnutsanity: Gourmand Frog Melon,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4118,Gourmand Frog Cave,Walnutsanity: Gourmand Frog Wheat,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4119,Gourmand Frog Cave,Walnutsanity: Gourmand Frog Garlic,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4120,Island West,Walnutsanity: Journal Scrap #6,"WALNUTSANITY,WALNUTSANITY_DIG", +4121,Island West,Walnutsanity: Mussel Node Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4122,Island West,Walnutsanity: Mussel Node Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4123,Island West,Walnutsanity: Mussel Node Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4124,Island West,Walnutsanity: Mussel Node Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4125,Island West,Walnutsanity: Mussel Node Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4126,Shipwreck,Walnutsanity: Shipwreck Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4127,Island West,Walnutsanity: Whack A Mole,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4128,Island West,Walnutsanity: Starfish Triangle,"WALNUTSANITY,WALNUTSANITY_DIG", +4129,Island West,Walnutsanity: Starfish Diamond,"WALNUTSANITY,WALNUTSANITY_DIG", +4130,Island West,Walnutsanity: X in the sand,"WALNUTSANITY,WALNUTSANITY_DIG", +4131,Island West,Walnutsanity: Diamond Of Indents,"WALNUTSANITY,WALNUTSANITY_DIG", +4132,Island West,Walnutsanity: Bush Behind Coconut Tree,"WALNUTSANITY,WALNUTSANITY_BUSH", +4133,Island West,Walnutsanity: Journal Scrap #4,"WALNUTSANITY,WALNUTSANITY_DIG", +4134,Island West,Walnutsanity: Walnut Room Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4135,Island West,Walnutsanity: Coast Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4136,Island West,Walnutsanity: Tiger Slime Walnut,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4137,Island West,Walnutsanity: Bush Behind Mahogany Tree,"WALNUTSANITY,WALNUTSANITY_BUSH", +4138,Island West,Walnutsanity: Circle Of Grass,"WALNUTSANITY,WALNUTSANITY_DIG", +4139,Island West,Walnutsanity: Below Colored Crystals Cave Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4140,Colored Crystals Cave,Walnutsanity: Colored Crystals,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4141,Island West,Walnutsanity: Cliff Edge Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4142,Island West,Walnutsanity: Diamond Of Pebbles,"WALNUTSANITY,WALNUTSANITY_DIG", +4143,Island West,Walnutsanity: Farm Parrot Express Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4144,Island West,Walnutsanity: Farmhouse Cliff Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4145,Island North,Walnutsanity: Big Circle Of Stones,"WALNUTSANITY,WALNUTSANITY_DIG", +4146,Island North,Walnutsanity: Grove Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4147,Island North,Walnutsanity: Diamond Of Grass,"WALNUTSANITY,WALNUTSANITY_DIG", +4148,Island North,Walnutsanity: Small Circle Of Stones,"WALNUTSANITY,WALNUTSANITY_DIG", +4149,Island North,Walnutsanity: Patch Of Sand,"WALNUTSANITY,WALNUTSANITY_DIG", +4150,Dig Site,Walnutsanity: Crooked Circle Of Stones,"WALNUTSANITY,WALNUTSANITY_DIG", +4151,Dig Site,Walnutsanity: Above Dig Site Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4152,Dig Site,Walnutsanity: Above Field Office Bush 1,"WALNUTSANITY,WALNUTSANITY_BUSH", +4153,Dig Site,Walnutsanity: Above Field Office Bush 2,"WALNUTSANITY,WALNUTSANITY_BUSH", +4154,Field Office,Walnutsanity: Complete Large Animal Collection,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4155,Field Office,Walnutsanity: Complete Snake Collection,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4156,Field Office,Walnutsanity: Complete Mummified Frog Collection,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4157,Field Office,Walnutsanity: Complete Mummified Bat Collection,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4158,Field Office,Walnutsanity: Purple Flowers Island Survey,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4159,Field Office,Walnutsanity: Purple Starfish Island Survey,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4160,Island North,Walnutsanity: Bush Behind Volcano Tree,"WALNUTSANITY,WALNUTSANITY_BUSH", +4161,Island North,Walnutsanity: Arc Of Stones,"WALNUTSANITY,WALNUTSANITY_DIG", +4162,Island North,Walnutsanity: Protruding Tree Walnut,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4163,Island North,Walnutsanity: Journal Scrap #10,"WALNUTSANITY,WALNUTSANITY_DIG", +4164,Island North,Walnutsanity: Northmost Point Circle Of Stones,"WALNUTSANITY,WALNUTSANITY_DIG", +4165,Island North,Walnutsanity: Hidden Passage Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4166,Volcano Secret Beach,Walnutsanity: Secret Beach Bush 1,"WALNUTSANITY,WALNUTSANITY_BUSH", +4167,Volcano Secret Beach,Walnutsanity: Secret Beach Bush 2,"WALNUTSANITY,WALNUTSANITY_BUSH", +4168,Volcano - Floor 5,Walnutsanity: Volcano Rocks Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4169,Volcano - Floor 5,Walnutsanity: Volcano Rocks Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4170,Volcano - Floor 10,Walnutsanity: Volcano Rocks Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4171,Volcano - Floor 10,Walnutsanity: Volcano Rocks Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4172,Volcano - Floor 10,Walnutsanity: Volcano Rocks Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4173,Volcano - Floor 5,Walnutsanity: Volcano Monsters Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4174,Volcano - Floor 5,Walnutsanity: Volcano Monsters Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4175,Volcano - Floor 10,Walnutsanity: Volcano Monsters Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4176,Volcano - Floor 10,Walnutsanity: Volcano Monsters Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4177,Volcano - Floor 10,Walnutsanity: Volcano Monsters Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4178,Volcano - Floor 5,Walnutsanity: Volcano Crates Walnut 1,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4179,Volcano - Floor 5,Walnutsanity: Volcano Crates Walnut 2,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4180,Volcano - Floor 10,Walnutsanity: Volcano Crates Walnut 3,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4181,Volcano - Floor 10,Walnutsanity: Volcano Crates Walnut 4,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4182,Volcano - Floor 10,Walnutsanity: Volcano Crates Walnut 5,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4183,Volcano - Floor 5,Walnutsanity: Volcano Common Chest Walnut,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4184,Volcano - Floor 10,Walnutsanity: Volcano Rare Chest Walnut,"WALNUTSANITY,WALNUTSANITY_REPEATABLE", +4185,Volcano - Floor 10,Walnutsanity: Forge Entrance Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4186,Volcano - Floor 10,Walnutsanity: Forge Exit Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4187,Island North,Walnutsanity: Cliff Over Island South Bush,"WALNUTSANITY,WALNUTSANITY_BUSH", +4188,Island Southeast,Walnutsanity: Starfish Tide Pool,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4189,Island Southeast,Walnutsanity: Diamond Of Yellow Starfish,"WALNUTSANITY,WALNUTSANITY_DIG", +4190,Island Southeast,Walnutsanity: Mermaid Song,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4191,Pirate Cove,Walnutsanity: Pirate Darts 1,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4192,Pirate Cove,Walnutsanity: Pirate Darts 2,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4193,Pirate Cove,Walnutsanity: Pirate Darts 3,"WALNUTSANITY,WALNUTSANITY_PUZZLE", +4194,Pirate Cove,Walnutsanity: Pirate Cove Patch Of Sand,"WALNUTSANITY,WALNUTSANITY_DIG", 5001,Stardew Valley,Level 1 Luck,"LUCK_LEVEL,SKILL_LEVEL",Luck Skill 5002,Stardew Valley,Level 2 Luck,"LUCK_LEVEL,SKILL_LEVEL",Luck Skill 5003,Stardew Valley,Level 3 Luck,"LUCK_LEVEL,SKILL_LEVEL",Luck Skill diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index 350da064a103..2b7eec99607c 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -443,27 +443,27 @@ def set_walnut_puzzle_rules(logic: StardewLogic, multiworld, player, world_optio if WalnutsanityOptionName.puzzles not in world_options.walnutsanity: return - set_rule(multiworld.get_location("Open Golden Coconut", player), logic.has(Geode.golden_coconut)) - set_rule(multiworld.get_location("Banana Altar", player), logic.has(Fruit.banana)) - set_rule(multiworld.get_location("Leo's Tree", player), logic.tool.has_tool(Tool.axe)) - set_rule(multiworld.get_location("Gem Birds Shrine", player), logic.has(Mineral.amethyst) & logic.has(Mineral.aquamarine) & + set_rule(multiworld.get_location("Walnutsanity: Open Golden Coconut", player), logic.has(Geode.golden_coconut)) + set_rule(multiworld.get_location("Walnutsanity: Banana Altar", player), logic.has(Fruit.banana)) + set_rule(multiworld.get_location("Walnutsanity: Leo's Tree", player), logic.tool.has_tool(Tool.axe)) + set_rule(multiworld.get_location("Walnutsanity: Gem Birds Shrine", player), logic.has(Mineral.amethyst) & logic.has(Mineral.aquamarine) & logic.has(Mineral.emerald) & logic.has(Mineral.ruby) & logic.has(Mineral.topaz) & logic.region.can_reach_all((Region.island_north, Region.island_west, Region.island_east, Region.island_south))) - set_rule(multiworld.get_location("Gourmand Frog Melon", player), logic.has(Fruit.melon) & logic.region.can_reach(Region.island_west)) - set_rule(multiworld.get_location("Gourmand Frog Wheat", player), logic.has(Vegetable.wheat) & - logic.region.can_reach(Region.island_west) & logic.region.can_reach_location("Gourmand Frog Melon")) - set_rule(multiworld.get_location("Gourmand Frog Garlic", player), logic.has(Vegetable.garlic) & - logic.region.can_reach(Region.island_west) & logic.region.can_reach_location("Gourmand Frog Wheat")) - set_rule(multiworld.get_location("Whack A Mole", player), logic.tool.has_tool(Tool.watering_can, ToolMaterial.iridium)) - set_rule(multiworld.get_location("Complete Large Animal Collection", player), logic.walnut.can_complete_large_animal_collection()) - set_rule(multiworld.get_location("Complete Snake Collection", player), logic.walnut.can_complete_snake_collection()) - set_rule(multiworld.get_location("Complete Mummified Frog Collection", player), logic.walnut.can_complete_frog_collection()) - set_rule(multiworld.get_location("Complete Mummified Bat Collection", player), logic.walnut.can_complete_bat_collection()) - set_rule(multiworld.get_location("Purple Flowers Island Survey", player), logic.walnut.can_start_field_office) - set_rule(multiworld.get_location("Purple Starfish Island Survey", player), logic.walnut.can_start_field_office) - set_rule(multiworld.get_location("Protruding Tree Walnut", player), logic.combat.has_slingshot) - set_rule(multiworld.get_location("Starfish Tide Pool", player), logic.tool.has_fishing_rod(1)) - set_rule(multiworld.get_location("Mermaid Song", player), logic.has(Furniture.flute_block)) + set_rule(multiworld.get_location("Walnutsanity: Gourmand Frog Melon", player), logic.has(Fruit.melon) & logic.region.can_reach(Region.island_west)) + set_rule(multiworld.get_location("Walnutsanity: Gourmand Frog Wheat", player), logic.has(Vegetable.wheat) & + logic.region.can_reach(Region.island_west) & logic.region.can_reach_location("Walnutsanity: Gourmand Frog Melon")) + set_rule(multiworld.get_location("Walnutsanity: Gourmand Frog Garlic", player), logic.has(Vegetable.garlic) & + logic.region.can_reach(Region.island_west) & logic.region.can_reach_location("Walnutsanity: Gourmand Frog Wheat")) + set_rule(multiworld.get_location("Walnutsanity: Whack A Mole", player), logic.tool.has_tool(Tool.watering_can, ToolMaterial.iridium)) + set_rule(multiworld.get_location("Walnutsanity: Complete Large Animal Collection", player), logic.walnut.can_complete_large_animal_collection()) + set_rule(multiworld.get_location("Walnutsanity: Complete Snake Collection", player), logic.walnut.can_complete_snake_collection()) + set_rule(multiworld.get_location("Walnutsanity: Complete Mummified Frog Collection", player), logic.walnut.can_complete_frog_collection()) + set_rule(multiworld.get_location("Walnutsanity: Complete Mummified Bat Collection", player), logic.walnut.can_complete_bat_collection()) + set_rule(multiworld.get_location("Walnutsanity: Purple Flowers Island Survey", player), logic.walnut.can_start_field_office) + set_rule(multiworld.get_location("Walnutsanity: Purple Starfish Island Survey", player), logic.walnut.can_start_field_office) + set_rule(multiworld.get_location("Walnutsanity: Protruding Tree Walnut", player), logic.combat.has_slingshot) + set_rule(multiworld.get_location("Walnutsanity: Starfish Tide Pool", player), logic.tool.has_fishing_rod(1)) + set_rule(multiworld.get_location("Walnutsanity: Mermaid Song", player), logic.has(Furniture.flute_block)) def set_walnut_bushes_rules(logic, multiworld, player, world_options): @@ -490,13 +490,13 @@ def set_walnut_repeatable_rules(logic, multiworld, player, world_options): if WalnutsanityOptionName.repeatables not in world_options.walnutsanity: return for i in range(1, 6): - set_rule(multiworld.get_location(f"Fishing Walnut {i}", player), logic.tool.has_fishing_rod(1)) - set_rule(multiworld.get_location(f"Harvesting Walnut {i}", player), logic.skill.can_get_farming_xp) - set_rule(multiworld.get_location(f"Mussel Node Walnut {i}", player), logic.tool.has_tool(Tool.pickaxe)) - set_rule(multiworld.get_location(f"Volcano Rocks Walnut {i}", player), logic.tool.has_tool(Tool.pickaxe)) - set_rule(multiworld.get_location(f"Volcano Monsters Walnut {i}", player), logic.combat.has_galaxy_weapon) - set_rule(multiworld.get_location(f"Volcano Crates Walnut {i}", player), logic.combat.has_any_weapon) - set_rule(multiworld.get_location(f"Tiger Slime Walnut", player), logic.monster.can_kill(Monster.tiger_slime)) + set_rule(multiworld.get_location(f"Walnutsanity: Fishing Walnut {i}", player), logic.tool.has_fishing_rod(1)) + set_rule(multiworld.get_location(f"Walnutsanity: Harvesting Walnut {i}", player), logic.skill.can_get_farming_xp) + set_rule(multiworld.get_location(f"Walnutsanity: Mussel Node Walnut {i}", player), logic.tool.has_tool(Tool.pickaxe)) + set_rule(multiworld.get_location(f"Walnutsanity: Volcano Rocks Walnut {i}", player), logic.tool.has_tool(Tool.pickaxe)) + set_rule(multiworld.get_location(f"Walnutsanity: Volcano Monsters Walnut {i}", player), logic.combat.has_galaxy_weapon) + set_rule(multiworld.get_location(f"Walnutsanity: Volcano Crates Walnut {i}", player), logic.combat.has_any_weapon) + set_rule(multiworld.get_location(f"Walnutsanity: Tiger Slime Walnut", player), logic.monster.can_kill(Monster.tiger_slime)) def set_cropsanity_rules(logic: StardewLogic, multiworld, player, world_content: StardewContent): diff --git a/worlds/stardew_valley/test/TestWalnutsanity.py b/worlds/stardew_valley/test/TestWalnutsanity.py index e3411edd0224..418eaa87c70f 100644 --- a/worlds/stardew_valley/test/TestWalnutsanity.py +++ b/worlds/stardew_valley/test/TestWalnutsanity.py @@ -1,26 +1,46 @@ +import unittest + from .bases import SVTestBase from ..options import ExcludeGingerIsland, Walnutsanity, ToolProgression, SkillProgression from ..strings.ap_names.ap_option_names import WalnutsanityOptionName -class TestWalnutsanityNone(SVTestBase): +class SVWalnutsanityTestBase(SVTestBase): + expected_walnut_locations: set[str] = set() + unexpected_walnut_locations: set[str] = set() + + @classmethod + def setUpClass(cls) -> None: + if cls is SVWalnutsanityTestBase: + raise unittest.SkipTest("Base tests disabled") + + super().setUpClass() + + def test_walnut_locations(self): + location_names = {location.name for location in self.multiworld.get_locations()} + for location in self.expected_walnut_locations: + self.assertIn(location, location_names, f"{location} should be in the location names") + for location in self.unexpected_walnut_locations: + self.assertNotIn(location, location_names, f"{location} should not be in the location names") + + +class TestWalnutsanityNone(SVWalnutsanityTestBase): options = { ExcludeGingerIsland: ExcludeGingerIsland.option_false, Walnutsanity: Walnutsanity.preset_none, SkillProgression: ToolProgression.option_progressive, ToolProgression: ToolProgression.option_progressive, } - - def test_no_walnut_locations(self): - location_names = {location.name for location in self.multiworld.get_locations()} - self.assertNotIn("Open Golden Coconut", location_names) - self.assertNotIn("Fishing Walnut 4", location_names) - self.assertNotIn("Journal Scrap #6", location_names) - self.assertNotIn("Starfish Triangle", location_names) - self.assertNotIn("Bush Behind Coconut Tree", location_names) - self.assertNotIn("Purple Starfish Island Survey", location_names) - self.assertNotIn("Volcano Monsters Walnut 3", location_names) - self.assertNotIn("Cliff Over Island South Bush", location_names) + unexpected_walnut_locations = { + "Walnutsanity: Open Golden Coconut", + "Walnutsanity: Fishing Walnut 4", + "Walnutsanity: Journal Scrap #6", + "Walnutsanity: Starfish Triangle", + "Walnutsanity: Bush Behind Coconut Tree", + "Walnutsanity: Purple Starfish Island Survey", + "Walnutsanity: Volcano Monsters Walnut 3", + "Walnutsanity: Cliff Over Island South Bush", + } def test_logic_received_walnuts(self): # You need to receive 0, and collect 40 @@ -48,28 +68,30 @@ def test_logic_received_walnuts(self): self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) -class TestWalnutsanityPuzzles(SVTestBase): +class TestWalnutsanityPuzzles(SVWalnutsanityTestBase): options = { ExcludeGingerIsland: ExcludeGingerIsland.option_false, Walnutsanity: frozenset({WalnutsanityOptionName.puzzles}), SkillProgression: ToolProgression.option_progressive, ToolProgression: ToolProgression.option_progressive, } - - def test_only_puzzle_walnut_locations(self): - location_names = {location.name for location in self.multiworld.get_locations()} - self.assertIn("Open Golden Coconut", location_names) - self.assertNotIn("Fishing Walnut 4", location_names) - self.assertNotIn("Journal Scrap #6", location_names) - self.assertNotIn("Starfish Triangle", location_names) - self.assertNotIn("Bush Behind Coconut Tree", location_names) - self.assertIn("Purple Starfish Island Survey", location_names) - self.assertNotIn("Volcano Monsters Walnut 3", location_names) - self.assertNotIn("Cliff Over Island South Bush", location_names) + expected_walnut_locations = { + "Walnutsanity: Open Golden Coconut", + "Walnutsanity: Purple Starfish Island Survey", + } + unexpected_walnut_locations = { + "Walnutsanity: Fishing Walnut 4", + "Walnutsanity: Journal Scrap #6", + "Walnutsanity: Starfish Triangle", + "Walnutsanity: Bush Behind Coconut Tree", + "Walnutsanity: Volcano Monsters Walnut 3", + "Walnutsanity: Cliff Over Island South Bush", + } def test_field_office_locations_require_professor_snail(self): - location_names = ["Complete Large Animal Collection", "Complete Snake Collection", "Complete Mummified Frog Collection", - "Complete Mummified Bat Collection", "Purple Flowers Island Survey", "Purple Starfish Island Survey", ] + location_names = ["Walnutsanity: Complete Large Animal Collection", "Walnutsanity: Complete Snake Collection", + "Walnutsanity: Complete Mummified Frog Collection", "Walnutsanity: Complete Mummified Bat Collection", + "Walnutsanity: Purple Flowers Island Survey", "Walnutsanity: Purple Starfish Island Survey", ] self.collect("Island Obelisk") self.collect("Island North Turtle") self.collect("Island West Turtle") @@ -90,40 +112,42 @@ def test_field_office_locations_require_professor_snail(self): self.assert_can_reach_location(location) -class TestWalnutsanityBushes(SVTestBase): +class TestWalnutsanityBushes(SVWalnutsanityTestBase): options = { ExcludeGingerIsland: ExcludeGingerIsland.option_false, Walnutsanity: frozenset({WalnutsanityOptionName.bushes}), } - - def test_only_bush_walnut_locations(self): - location_names = {location.name for location in self.multiworld.get_locations()} - self.assertNotIn("Open Golden Coconut", location_names) - self.assertNotIn("Fishing Walnut 4", location_names) - self.assertNotIn("Journal Scrap #6", location_names) - self.assertNotIn("Starfish Triangle", location_names) - self.assertIn("Bush Behind Coconut Tree", location_names) - self.assertNotIn("Purple Starfish Island Survey", location_names) - self.assertNotIn("Volcano Monsters Walnut 3", location_names) - self.assertIn("Cliff Over Island South Bush", location_names) + expected_walnut_locations = { + "Walnutsanity: Bush Behind Coconut Tree", + "Walnutsanity: Cliff Over Island South Bush", + } + unexpected_walnut_locations = { + "Walnutsanity: Open Golden Coconut", + "Walnutsanity: Fishing Walnut 4", + "Walnutsanity: Journal Scrap #6", + "Walnutsanity: Starfish Triangle", + "Walnutsanity: Purple Starfish Island Survey", + "Walnutsanity: Volcano Monsters Walnut 3", + } -class TestWalnutsanityPuzzlesAndBushes(SVTestBase): +class TestWalnutsanityPuzzlesAndBushes(SVWalnutsanityTestBase): options = { ExcludeGingerIsland: ExcludeGingerIsland.option_false, Walnutsanity: frozenset({WalnutsanityOptionName.puzzles, WalnutsanityOptionName.bushes}), } - - def test_only_bush_walnut_locations(self): - location_names = {location.name for location in self.multiworld.get_locations()} - self.assertIn("Open Golden Coconut", location_names) - self.assertNotIn("Fishing Walnut 4", location_names) - self.assertNotIn("Journal Scrap #6", location_names) - self.assertNotIn("Starfish Triangle", location_names) - self.assertIn("Bush Behind Coconut Tree", location_names) - self.assertIn("Purple Starfish Island Survey", location_names) - self.assertNotIn("Volcano Monsters Walnut 3", location_names) - self.assertIn("Cliff Over Island South Bush", location_names) + expected_walnut_locations = { + "Walnutsanity: Open Golden Coconut", + "Walnutsanity: Bush Behind Coconut Tree", + "Walnutsanity: Purple Starfish Island Survey", + "Walnutsanity: Cliff Over Island South Bush", + } + unexpected_walnut_locations = { + "Walnutsanity: Fishing Walnut 4", + "Walnutsanity: Journal Scrap #6", + "Walnutsanity: Starfish Triangle", + "Walnutsanity: Volcano Monsters Walnut 3", + } def test_logic_received_walnuts(self): # You need to receive 25, and collect 15 @@ -136,58 +160,59 @@ def test_logic_received_walnuts(self): self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) -class TestWalnutsanityDigSpots(SVTestBase): +class TestWalnutsanityDigSpots(SVWalnutsanityTestBase): options = { ExcludeGingerIsland: ExcludeGingerIsland.option_false, Walnutsanity: frozenset({WalnutsanityOptionName.dig_spots}), } - - def test_only_dig_spots_walnut_locations(self): - location_names = {location.name for location in self.multiworld.get_locations()} - self.assertNotIn("Open Golden Coconut", location_names) - self.assertNotIn("Fishing Walnut 4", location_names) - self.assertIn("Journal Scrap #6", location_names) - self.assertIn("Starfish Triangle", location_names) - self.assertNotIn("Bush Behind Coconut Tree", location_names) - self.assertNotIn("Purple Starfish Island Survey", location_names) - self.assertNotIn("Volcano Monsters Walnut 3", location_names) - self.assertNotIn("Cliff Over Island South Bush", location_names) + expected_walnut_locations = { + "Walnutsanity: Journal Scrap #6", + "Walnutsanity: Starfish Triangle", + } + unexpected_walnut_locations = { + "Walnutsanity: Open Golden Coconut", + "Walnutsanity: Fishing Walnut 4", + "Walnutsanity: Bush Behind Coconut Tree", + "Walnutsanity: Purple Starfish Island Survey", + "Walnutsanity: Volcano Monsters Walnut 3", + "Walnutsanity: Cliff Over Island South Bush", + } -class TestWalnutsanityRepeatables(SVTestBase): +class TestWalnutsanityRepeatables(SVWalnutsanityTestBase): options = { ExcludeGingerIsland: ExcludeGingerIsland.option_false, Walnutsanity: frozenset({WalnutsanityOptionName.repeatables}), } - - def test_only_repeatable_walnut_locations(self): - location_names = {location.name for location in self.multiworld.get_locations()} - self.assertNotIn("Open Golden Coconut", location_names) - self.assertIn("Fishing Walnut 4", location_names) - self.assertNotIn("Journal Scrap #6", location_names) - self.assertNotIn("Starfish Triangle", location_names) - self.assertNotIn("Bush Behind Coconut Tree", location_names) - self.assertNotIn("Purple Starfish Island Survey", location_names) - self.assertIn("Volcano Monsters Walnut 3", location_names) - self.assertNotIn("Cliff Over Island South Bush", location_names) + expected_walnut_locations = { + "Walnutsanity: Fishing Walnut 4", + "Walnutsanity: Volcano Monsters Walnut 3", + } + unexpected_walnut_locations = { + "Walnutsanity: Open Golden Coconut", + "Walnutsanity: Journal Scrap #6", + "Walnutsanity: Starfish Triangle", + "Walnutsanity: Bush Behind Coconut Tree", + "Walnutsanity: Purple Starfish Island Survey", + "Walnutsanity: Cliff Over Island South Bush", + } -class TestWalnutsanityAll(SVTestBase): +class TestWalnutsanityAll(SVWalnutsanityTestBase): options = { ExcludeGingerIsland: ExcludeGingerIsland.option_false, Walnutsanity: Walnutsanity.preset_all, } - - def test_all_walnut_locations(self): - location_names = {location.name for location in self.multiworld.get_locations()} - self.assertIn("Open Golden Coconut", location_names) - self.assertIn("Fishing Walnut 4", location_names) - self.assertIn("Journal Scrap #6", location_names) - self.assertIn("Starfish Triangle", location_names) - self.assertIn("Bush Behind Coconut Tree", location_names) - self.assertIn("Purple Starfish Island Survey", location_names) - self.assertIn("Volcano Monsters Walnut 3", location_names) - self.assertIn("Cliff Over Island South Bush", location_names) + expected_walnut_locations = { + "Walnutsanity: Open Golden Coconut", + "Walnutsanity: Fishing Walnut 4", + "Walnutsanity: Journal Scrap #6", + "Walnutsanity: Starfish Triangle", + "Walnutsanity: Bush Behind Coconut Tree", + "Walnutsanity: Purple Starfish Island Survey", + "Walnutsanity: Volcano Monsters Walnut 3", + "Walnutsanity: Cliff Over Island South Bush", + } def test_logic_received_walnuts(self): # You need to receive 40, and collect 4 From 608a38f873eaa9d7cc4ca454774c771bb816d660 Mon Sep 17 00:00:00 2001 From: CookieCat <81494827+CookieCat45@users.noreply.github.com> Date: Wed, 16 Jul 2025 12:19:35 -0400 Subject: [PATCH 0579/1218] AHIT: Fix Test Fail for assert_not_all_options (#5197) --- worlds/ahit/__init__.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/worlds/ahit/__init__.py b/worlds/ahit/__init__.py index 1bcc840ae6cb..d258f8050d8d 100644 --- a/worlds/ahit/__init__.py +++ b/worlds/ahit/__init__.py @@ -260,11 +260,7 @@ def fill_slot_data(self) -> dict: f"{item_name} ({self.multiworld.get_player_name(loc.item.player)})") slot_data["ShopItemNames"] = shop_item_names - - for name, value in self.options.as_dict(*self.options_dataclass.type_hints).items(): - if name in slot_data_options: - slot_data[name] = value - + slot_data.update(self.options.as_dict(*slot_data_options)) return slot_data def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]): From 1923d6b1bcaf35d0ffb26ede6eae1d17b8c09a3d Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Wed, 16 Jul 2025 11:57:11 -0500 Subject: [PATCH 0580/1218] Options: Assert Not All Option in `Options.as_dict` (#5039) * Options: forbid worlds just dumping every single option they don't need * make the equal proper --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- Options.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Options.py b/Options.py index b910d21665af..e87280ca14e8 100644 --- a/Options.py +++ b/Options.py @@ -1315,6 +1315,7 @@ def as_dict( will be returned as a sorted list. """ assert option_names, "options.as_dict() was used without any option names." + assert len(option_names) < len(self.__class__.type_hints), "Specify only options you need." option_results = {} for option_name in option_names: if option_name not in type(self).type_hints: From e38d04c655258c7c7c70c485cf9a03697d21dbee Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Wed, 16 Jul 2025 23:49:01 -0400 Subject: [PATCH 0581/1218] Lingo: Fix Painting Gen Failures on Panels Mode Door Shuffle (#5199) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/lingo/player_logic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/lingo/player_logic.py b/worlds/lingo/player_logic.py index 9363dfedb67f..b76f12a916da 100644 --- a/worlds/lingo/player_logic.py +++ b/worlds/lingo/player_logic.py @@ -394,7 +394,7 @@ def is_req_enterable(painting: Painting) -> bool: or painting.room in required_painting_rooms: return False - if world.options.shuffle_doors == ShuffleDoors.option_none: + if world.options.shuffle_doors != ShuffleDoors.option_doors: if painting.req_blocked_when_no_doors: return False From ffab3a43fc17f4d06d241179ae9e2e26fdea47df Mon Sep 17 00:00:00 2001 From: Adrian Priestley <47989725+a-priestley@users.noreply.github.com> Date: Thu, 17 Jul 2025 05:30:57 -0230 Subject: [PATCH 0582/1218] Docker: Add initial configuration for project (#4419) * feat(docker): Add initial Docker configuration for project - Add .dockerignore file to ignore unnecessary files - Create Dockerfile with basic build and deployment configuration * feat(docker): Updated Docker configuration for improved security and build efficiency - Removed sensitive files from .dockerignore - Moved WORKDIR to /app in Dockerfile - Added gunicorn==23.0.0 dependency in RUN command - Created new docker-compose.yml file for service definition * feat(deployment): Implement containerized deployment configuration - Add additional environment variables for Python optimization - Update Dockerfile with new dependencies: eventlet, gevent, tornado - Create docker-compose.yml and configure services for web and nginx - Implement example configurations for web host settings and gunicorn - Establish nginx configuration for reverse proxy - Remove outdated docker-compose.yml from root directory * feat(deploy): Introduce Docker Compose configuration for multi-world deployment - Separate web service into two containers, one for main process and one for gunicorn - Update container configurations for improved security and maintainability - Remove unused volumes and network configurations * docs: Add new documentation for deploying Archipelago using containers - Document standalone image build and run process - Include example Docker Compose file for container orchestration - Provide information on services defined in the `docker-compose.yaml` file - Mention optional Enemizer feature and Git requirements * fixup! feat(docker): Updated Docker configuration for improved security and build efficiency - Removed sensitive files from .dockerignore - Moved WORKDIR to /app in Dockerfile - Added gunicorn==23.0.0 dependency in RUN command - Created new docker-compose.yml file for service definition * feat(deploy): Updated gunicorn configuration example - Adjusted worker and thread counts - Switched worker class from sync to gthread - Changed log level to info - Added example code snippet for customizing worker count * fix(deploy): Adjust concurrency settings for self-launch configuration - Reduce the number of world generators from 8 to 3 - Decrease the number of hosters from 5 to 4 * docs(deploy using containers): Improve readability, fix broken links - Update links to other documentation pages - Improve formatting for better readability - Remove unnecessary sections and files - Add note about building the image requiring a local copy of ArchipelagoMW source code * Update deploy/example_config.yaml Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> * Update deploy/example_selflaunch.yaml Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> * Update Dockerfile Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> * Update deploy/example_selflaunch.yaml Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> * fixup! Update Dockerfile * fix(Dockerfile): Update package installations to use latest versions - Remove specific version pins for git and libc6-dev - Ensure compatibility with newer package updates * feat(ci): Add GitHub Actions workflow for building and publishing Docker images - Create a new workflow for Docker image build and publish - Configure triggers for push and pull_request on main branch - Set up QEMU and Docker Buildx for multi-platform builds - Implement Docker login for GitHub Container Registry - Include Docker image metadata extraction and tagging * feat(healthcheck): Update Dockerfile and docker-compose for health checks - Add health check for the Webhost service in Dockerfile - Modify docker-compose to include a placeholder health check for multiworld service - Standardize comments and remove unnecessary lines * Revert "feat(ci): Add GitHub Actions workflow for building and publishing Docker images" This reverts commit 32a51b272627d99ca9796cbfda2e821bfdd95c70. * feat(docker): Enhance Dockerfile with Cython build stage - Add Cython builder stage for compiling speedups - Update package installation and organization for efficiency - Improve caching by copying requirements before installing - Add documentation for rootless Podman * fixup! feat(docker): Enhance Dockerfile with Cython build stage - Add Cython builder stage for compiling speedups - Update package installation and organization for efficiency - Improve caching by copying requirements before installing - Add documentation for rootless Podman --------- Co-authored-by: Adrian Priestley Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> Co-authored-by: Adrian Priestley --- .dockerignore | 210 ++++++++++++++++++++++++++++++++ Dockerfile | 97 +++++++++++++++ deploy/docker-compose.yml | 61 ++++++++++ deploy/example_config.yaml | 10 ++ deploy/example_gunicorn.conf.py | 19 +++ deploy/example_nginx.conf | 64 ++++++++++ deploy/example_selflaunch.yaml | 13 ++ docs/deploy using containers.md | 91 ++++++++++++++ 8 files changed, 565 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 deploy/docker-compose.yml create mode 100644 deploy/example_config.yaml create mode 100644 deploy/example_gunicorn.conf.py create mode 100644 deploy/example_nginx.conf create mode 100644 deploy/example_selflaunch.yaml create mode 100644 docs/deploy using containers.md diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000000..982e411032c6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,210 @@ +.git +.github +.run +docs +test +typings +*Client.py + +.idea +.vscode + +*_Spoiler.txt +*.bmbp +*.apbp +*.apl2ac +*.apm3 +*.apmc +*.apz5 +*.aptloz +*.apemerald +*.pyc +*.pyd +*.sfc +*.z64 +*.n64 +*.nes +*.smc +*.sms +*.gb +*.gbc +*.gba +*.wixobj +*.lck +*.db3 +*multidata +*multisave +*.archipelago +*.apsave +*.BIN +*.puml + +setups +build +bundle/components.wxs +dist +/prof/ +README.html +.vs/ +EnemizerCLI/ +/Players/ +/SNI/ +/sni-*/ +/appimagetool* +/host.yaml +/options.yaml +/config.yaml +/logs/ +_persistent_storage.yaml +mystery_result_*.yaml +*-errors.txt +success.txt +output/ +Output Logs/ +/factorio/ +/Minecraft Forge Server/ +/WebHostLib/static/generated +/freeze_requirements.txt +/Archipelago.zip +/setup.ini +/installdelete.iss +/data/user.kv +/datapackage +/custom_worlds + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so +*.dll + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt +installer.log + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# vim editor +*.swp + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv* +env/ +venv/ +/venv*/ +ENV/ +env.bak/ +venv.bak/ +*.code-workspace +shell.nix + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# Cython intermediates +_speedups.c +_speedups.cpp +_speedups.html + +# minecraft server stuff +jdk*/ +minecraft*/ +minecraft_versions.json +!worlds/minecraft/ + +# pyenv +.python-version + +#undertale stuff +/Undertale/ + +# OS General Files +.DS_Store +.AppleDouble +.LSOverride +Thumbs.db +[Dd]esktop.ini diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000000..0ed61c030172 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,97 @@ +# hadolint global ignore=SC1090,SC1091 + +# Source +FROM scratch AS release +WORKDIR /release +ADD https://github.com/Ijwu/Enemizer/releases/latest/download/ubuntu.16.04-x64.zip Enemizer.zip + +# Enemizer +FROM alpine:3.21 AS enemizer +ARG TARGETARCH +WORKDIR /release +COPY --from=release /release/Enemizer.zip . + +# No release for arm architecture. Skip. +RUN if [ "$TARGETARCH" = "amd64" ]; then \ + apk add unzip=6.0-r15 --no-cache && \ + unzip -u Enemizer.zip -d EnemizerCLI && \ + chmod -R 777 EnemizerCLI; \ + else touch EnemizerCLI; fi + +# Cython builder stage +FROM python:3.12 AS cython-builder + +WORKDIR /build + +# Copy and install requirements first (better caching) +COPY requirements.txt WebHostLib/requirements.txt + +RUN pip install --no-cache-dir -r \ + WebHostLib/requirements.txt \ + setuptools + +COPY _speedups.pyx . +COPY intset.h . + +RUN cythonize -b -i _speedups.pyx + +# Archipelago +FROM python:3.12-slim AS archipelago +ARG TARGETARCH +ENV VIRTUAL_ENV=/opt/venv +ENV PYTHONUNBUFFERED=1 +WORKDIR /app + +# Install requirements +# hadolint ignore=DL3008 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + git \ + gcc=4:12.2.0-3 \ + libc6-dev \ + libtk8.6=8.6.13-2 \ + g++=4:12.2.0-3 \ + curl && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Create and activate venv +RUN python -m venv $VIRTUAL_ENV; \ + . $VIRTUAL_ENV/bin/activate + +# Copy and install requirements first (better caching) +COPY WebHostLib/requirements.txt WebHostLib/requirements.txt + +RUN pip install --no-cache-dir -r \ + WebHostLib/requirements.txt \ + gunicorn==23.0.0 + +COPY . . + +COPY --from=cython-builder /build/*.so ./ + +# Run ModuleUpdate +RUN python ModuleUpdate.py -y + +# Purge unneeded packages +RUN apt-get purge -y \ + git \ + gcc \ + libc6-dev \ + g++ && \ + apt-get autoremove -y + +# Copy necessary components +COPY --from=enemizer /release/EnemizerCLI /tmp/EnemizerCLI + +# No release for arm architecture. Skip. +RUN if [ "$TARGETARCH" = "amd64" ]; then \ + cp /tmp/EnemizerCLI EnemizerCLI; \ + fi; \ + rm -rf /tmp/EnemizerCLI + +# Define health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ + CMD curl -f http://localhost:${PORT:-80} || exit 1 + +ENTRYPOINT [ "python", "WebHost.py" ] diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml new file mode 100644 index 000000000000..1472667442be --- /dev/null +++ b/deploy/docker-compose.yml @@ -0,0 +1,61 @@ +services: + multiworld: + # Build only once. Web service uses the same image build + build: + context: .. + # Name image for use in web service + image: archipelago-base + # Use locally-built image + pull_policy: never + # Launch main process without website hosting (config override) + entrypoint: python WebHost.py --config_override selflaunch.yaml + volumes: + # Mount application volume + - app_volume:/app + + # Mount configs + - ./example_config.yaml:/app/config.yaml + - ./example_selflaunch.yaml:/app/selflaunch.yaml + + # Expose on host network for access to dynamically mapped ports + network_mode: host + + # No Healthcheck in place yet for multiworld + healthcheck: + test: ["NONE"] + web: + # Use image build by multiworld service + image: archipelago-base + # Use locally-built image + pull_policy: never + # Launch gunicorn targeting WebHost application + entrypoint: gunicorn -c gunicorn.conf.py + volumes: + # Mount application volume + - app_volume:/app + + # Mount configs + - ./example_config.yaml:/app/config.yaml + - ./example_gunicorn.conf.py:/app/gunicorn.conf.py + environment: + # Bind gunicorn on 8000 + - PORT=8000 + + nginx: + image: nginx:stable-alpine + volumes: + # Mount application volume + - app_volume:/app + + # Mount config + - ./example_nginx.conf:/etc/nginx/nginx.conf + ports: + # Nginx listening internally on port 80 -- mapped to 8080 on host + - 8080:80 + depends_on: + - web + +volumes: + # Share application directory amongst multiworld and web services + # (for access to log files and the like), and nginx (for static files) + app_volume: diff --git a/deploy/example_config.yaml b/deploy/example_config.yaml new file mode 100644 index 000000000000..d74f7f238fcf --- /dev/null +++ b/deploy/example_config.yaml @@ -0,0 +1,10 @@ +# Refer to ../docs/webhost configuration sample.yaml + +# We'll be hosting VIA gunicorn +SELFHOST: false +# We'll start a separate process for rooms and generators +SELFLAUNCH: false + +# Host Address. This is the address encoded into the patch that will be used for client auto-connect. +# Set as your local IP (192.168.x.x) to serve over LAN. +HOST_ADDRESS: localhost diff --git a/deploy/example_gunicorn.conf.py b/deploy/example_gunicorn.conf.py new file mode 100644 index 000000000000..49f153df6738 --- /dev/null +++ b/deploy/example_gunicorn.conf.py @@ -0,0 +1,19 @@ +workers = 2 +threads = 2 +wsgi_app = "WebHost:get_app()" +accesslog = "-" +access_log_format = ( + '%({x-forwarded-for}i)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' +) +worker_class = "gthread" # "sync" | "gthread" +forwarded_allow_ips = "*" +loglevel = "info" + +""" +You can programatically set values. +For example, set number of workers to half of the cpu count: + +import multiprocessing + +workers = multiprocessing.cpu_count() / 2 +""" diff --git a/deploy/example_nginx.conf b/deploy/example_nginx.conf new file mode 100644 index 000000000000..b0c0e8e5a043 --- /dev/null +++ b/deploy/example_nginx.conf @@ -0,0 +1,64 @@ +worker_processes 1; + +user nobody nogroup; +# 'user nobody nobody;' for systems with 'nobody' as a group instead +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; # increase if you have lots of clients + accept_mutex off; # set to 'on' if nginx worker_processes > 1 + # 'use epoll;' to enable for Linux 2.6+ + # 'use kqueue;' to enable for FreeBSD, OSX + use epoll; +} + +http { + include mime.types; + # fallback in case we can't determine a type + default_type application/octet-stream; + access_log /var/log/nginx/access.log combined; + sendfile on; + + upstream app_server { + # fail_timeout=0 means we always retry an upstream even if it failed + # to return a good HTTP response + + # for UNIX domain socket setups + # server unix:/tmp/gunicorn.sock fail_timeout=0; + + # for a TCP configuration + server web:8000 fail_timeout=0; + } + + server { + # use 'listen 80 deferred;' for Linux + # use 'listen 80 accept_filter=httpready;' for FreeBSD + listen 80 deferred; + client_max_body_size 4G; + + # set the correct host(s) for your site + # server_name example.com www.example.com; + + keepalive_timeout 5; + + # path for static files + root /app/WebHostLib; + + location / { + # checks for static file, if not found proxy to app + try_files $uri @proxy_to_app; + } + + location @proxy_to_app { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + # we don't want nginx trying to do something clever with + # redirects, we set the Host: header above already. + proxy_redirect off; + + proxy_pass http://app_server; + } + } +} diff --git a/deploy/example_selflaunch.yaml b/deploy/example_selflaunch.yaml new file mode 100644 index 000000000000..41149dc18a44 --- /dev/null +++ b/deploy/example_selflaunch.yaml @@ -0,0 +1,13 @@ +# Refer to ../docs/webhost configuration sample.yaml + +# We'll be hosting VIA gunicorn +SELFHOST: false +# Start room and generator processes +SELFLAUNCH: true +JOB_THRESHOLD: 0 + +# Maximum concurrent world gens +GENERATORS: 3 + +# Rooms will be spread across multiple processes +HOSTERS: 4 diff --git a/docs/deploy using containers.md b/docs/deploy using containers.md new file mode 100644 index 000000000000..bb77900174c8 --- /dev/null +++ b/docs/deploy using containers.md @@ -0,0 +1,91 @@ +# Deploy Using Containers + +If you just want to play and there is a compiled version available on the [Archipelago releases page](https://github.com/ArchipelagoMW/Archipelago/releases), use that version. +To build the full Archipelago software stack, refer to [Running From Source](running%20from%20source.md). +Follow these steps to build and deploy a containerized instance of the web host software, optionally integrating [Gunicorn](https://gunicorn.org/) WSGI HTTP Server running behind the [nginx](https://nginx.org/) reverse proxy. + + +## Building the Container Image + +What you'll need: + * A container runtime engine such as: + * [Docker](https://www.docker.com/) + * [Podman](https://podman.io/) + * For running with rootless podman, you need to ensure all ports used are usable rootless, by default ports less than 1024 are root only. See [the official tutorial](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md) for details. + +Starting from the root repository directory, the standalone Archipelago image can be built and run with the command: +`docker build -t archipelago .` +Or: +`podman build -t archipelago .` + +It is recommended to tag the image using `-t` to more easily identify the image and run it. + + +## Running the Container + +Running the container can be performed using: +`docker run --network host archipelago` +Or: +`podman run --network host archipelago` + +The Archipelago web host requires access to multiple ports in order to host game servers simultaneously. To simplify configuration for this purpose, specify `--network host`. + +Given the default configuration, the website will be accessible at the hostname/IP address (localhost if run locally) of the machine being deployed to, at port 80. It can be configured by creating a YAML file and mapping a volume to the container when running initially: +`docker run archipelago --network host -v /path/to/config.yaml:/app/config.yaml` +See `docs/webhost configuration sample.yaml` for example. + + +## Using Docker Compose + +An example [docker compose](../deploy/docker-compose.yml) file can be found in [deploy](../deploy), along with example configuration files used by the services it orchestrates. Using these files as-is will spin up two separate archipelago containers with special modifications to their runtime arguments, in addition to deploying an `nginx` reverse proxy container. + +To deploy in this manner, from the ["deploy"](../deploy) directory, run: +`docker compose up -d` + +### Services + +The `docker-compose.yaml` file defines three services: + * multiworld: + * Executes the main `WebHost` process, using the [example config](../deploy/example_config.yaml), and overriding with a secondary [selflaunch example config](../deploy/example_selflaunch.yaml). This is because we do not want to launch the website through this service. + * web: + * Executes `gunicorn` using its [example config](../deploy/example_gunicorn.conf.py), which will bind it to the `WebHost` application, in effect launching it. + * We mount the main [config](../deploy/example_config.yaml) without an override to specify that we are launching the website through this service. + * No ports are exposed through to the host. + * nginx: + * Serves as a reverse proxy with `web` as its upstream. + * Directs all HTTP traffic from port 80 to the upstream service. + * Exposed to the host on port 8080. This is where we can reach the website. + +### Configuration + +As these are examples, they can be copied and modified. For instance setting the value of `HOST_ADDRESS` in [example config](../deploy/example_config.yaml) to host machines local IP address, will expose the service to its local area network. + +The configuration files may be modified to handle for machine-specific optimizations, such as: + * Web pages responding too slowly + * Edit [the gunicorn config](../deploy/example_gunicorn.conf.py) to increase thread and/or worker count. + * Game generation stalls + * Increase the generator count in [selflaunch config](../deploy/example_selflaunch.yaml) + * Gameplay lags + * Increase the hoster count in [selflaunch config](../deploy/example_selflaunch.yaml) + +Changes made to `docker-compose.yaml` can be applied by running `docker compose up -d`, while those made to other files are applied by running `docker compose restart`. + + +## Windows + +It is possible to carry out these deployment steps on Windows under [Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/install). + + +## Optional: A Link to the Past Enemizer + +Only required to generate seeds that include A Link to the Past with certain options enabled. You will receive an +error if it is required. +Enemizer can be enabled on `x86_64` platform architecture, and is included in the image build process. Enemizer requires a version 1.0 Japanese "Zelda no Densetsu" `.sfc` rom file to be placed in the application directory: +`docker run archipelago -v "/path/to/zelda.sfc:/app/Zelda no Densetsu - Kamigami no Triforce (Japan).sfc"`. +Enemizer is not currently available for `aarch64`. + + +## Optional: Git + +Building the image requires a local copy of the ArchipelagoMW source code. +Refer to [Running From Source](running%20from%20source.md#optional-git). From 4ae36ac727e690f1de0eba233b6683f2e1ad738c Mon Sep 17 00:00:00 2001 From: NoiseCrush <168460988+NoiseCrush@users.noreply.github.com> Date: Thu, 17 Jul 2025 07:46:31 -0400 Subject: [PATCH 0583/1218] Super Metroid: Improve Option Descriptions and Add Option Groups (#5100) --- worlds/sm/Options.py | 132 ++++++++++++++++++++++++++++++++++-------- worlds/sm/__init__.py | 3 +- 2 files changed, 110 insertions(+), 25 deletions(-) diff --git a/worlds/sm/Options.py b/worlds/sm/Options.py index 3dad16ad3afd..7bce35299429 100644 --- a/worlds/sm/Options.py +++ b/worlds/sm/Options.py @@ -1,5 +1,5 @@ import typing -from Options import Choice, PerGameCommonOptions, Range, OptionDict, OptionList, OptionSet, Option, Toggle, DefaultOnToggle +from Options import Choice, PerGameCommonOptions, Range, OptionDict, OptionList, OptionSet, OptionGroup, Toggle, DefaultOnToggle from .variaRandomizer.utils.objectives import _goals from dataclasses import dataclass @@ -8,8 +8,15 @@ class StartItemsRemovesFromPool(Toggle): display_name = "StartItems Removes From Item Pool" class Preset(Choice): - """Choose one of the presets or specify "varia_custom" to use varia_custom_preset option or specify "custom" to use - custom_preset option.""" + """Determines the general difficulty of the item placements by adjusting the list of tricks that logic allows. + - Newbie: New to randomizers, but completed Super Metroid 100% and knows basic techniques (Wall Jump, Shinespark, Mid-air Morph) + - Casual: Occasional rando player. No hell runs or suitless Maridia, some easy to learn tricks in logic. + - Regular: Plays rando regularly. Knows many tricks that open up the game. + - Veteran: Experienced rando player. Harder everything, some tougher tricks in logic. + - Expert: Knows almost all tricks: full suitless Maridia, Lower Norfair hell runs, etc. + - Master: Everything on hardest, all tricks known. + In-depth details on each preset can be found on the VARIA website: https://varia.run/presets + You may also specify "varia_custom" to use varia_custom_preset option, or specify "custom" to use custom_preset option.""" display_name = "Preset" option_newbie = 0 option_casual = 1 @@ -46,7 +53,8 @@ class StartLocation(Choice): default = 1 class DeathLink(Choice): - """When DeathLink is enabled and someone dies, you will die. With survive reserve tanks can save you.""" + """When DeathLink is enabled and someone else with DeathLink dies, you will die. + If "Enable Survive" is selected, reserve tanks can save you.""" display_name = "Death Link" option_disable = 0 option_enable = 1 @@ -56,11 +64,13 @@ class DeathLink(Choice): default = 0 class RemoteItems(Toggle): - """Indicates you get items sent from your own world. This allows coop play of a world.""" - display_name = "Remote Items" + """Items from your own world are sent via the Archipelago server. This allows co-op play of a world and means that + you will not lose items on death or save file loss.""" + display_name = "Remote Items" class MaxDifficulty(Choice): - """Depending on the perceived difficulties of the techniques, bosses, hell runs etc. from the preset, it will + """Maximum difficulty of tricks that are allowed from the seed's Preset. + Depending on the perceived difficulties of the techniques, bosses, hell runs etc. from the preset, it will prevent the Randomizer from placing an item in a location too difficult to reach with the current items.""" display_name = "Maximum Difficulty" option_easy = 0 @@ -73,7 +83,7 @@ class MaxDifficulty(Choice): default = 4 class MorphPlacement(Choice): - """Influences where the Morphing Ball with be placed.""" + """Influences where the Morphing Ball will be placed.""" display_name = "Morph Placement" option_early = 0 option_normal = 1 @@ -85,21 +95,21 @@ class StrictMinors(Toggle): display_name = "Strict Minors" class MissileQty(Range): - """The higher the number the higher the probability of choosing missles when placing a minor.""" + """The higher the number, the higher the probability of choosing Missiles when placing a minor.""" display_name = "Missile Quantity" range_start = 10 range_end = 90 default = 30 class SuperQty(Range): - """The higher the number the higher the probability of choosing super missles when placing a minor.""" + """The higher the number, the higher the probability of choosing Super Missiles when placing a minor.""" display_name = "Super Quantity" range_start = 10 range_end = 90 default = 20 class PowerBombQty(Range): - """The higher the number the higher the probability of choosing power bombs when placing a minor.""" + """The higher the number, the higher the probability of choosing Power Bombs when placing a minor.""" display_name = "Power Bomb Quantity" range_start = 10 range_end = 90 @@ -123,7 +133,13 @@ class EnergyQty(Choice): default = 3 class AreaRandomization(Choice): - """Randomize areas together using bidirectional access portals.""" + """Randomize areas together using bidirectional access portals. + - Off: No change. All rooms are connected the same as in the original game. + - Full: All doors connecting areas will be randomized. "Areas" are roughly determined, but generally are regions + with different tilesets or music. For example, red Brinstar and green/pink Brinstar are different areas, Crocomire + and upper Norfair are different areas, etc. + - Light: Keep the same number of transitions between areas as in vanilla. So Crocomire area will always be connected + to upper Norfair, there'll always be two transitions between Crateria/blue Brinstar and green/pink Brinstar, etc.""" display_name = "Area Randomization" option_off = 0 option_light = 1 @@ -136,13 +152,13 @@ class AreaLayout(Toggle): display_name = "Area Layout" class DoorsColorsRando(Toggle): - """Randomize the color of Red/Green/Yellow doors. Add four new type of doors which require Ice/Wave/Spazer/Plasma - beams to open them.""" + """Randomize the color of Red/Green/Yellow doors. Add four new types of doors which require Ice/Wave/Spazer/Plasma + Beams to open them.""" display_name = "Doors Colors Rando" class AllowGreyDoors(Toggle): """When randomizing the color of Red/Green/Yellow doors, some doors can be randomized to Grey. Grey doors will never - open, you will have to go around them.""" + open; you will have to go around them.""" display_name = "Allow Grey Doors" class BossRandomization(Toggle): @@ -169,7 +185,10 @@ class LayoutPatches(DefaultOnToggle): display_name = "Layout Patches" class VariaTweaks(Toggle): - """Include minor tweaks for the game to behave 'as it should' in a randomizer context""" + """Include minor tweaks for the game to behave 'as it should' in a randomizer context: + - Bomb Torizo always activates after picking up its item and does not require Bomb to activate + - Wrecked Ship item on the Energy Tank Chozo statue is present before defeating Phantoon + - Lower Norfair Chozo statue that lowers the acid toward Gold Torizo does not require Space Jump to activate""" display_name = "Varia Tweaks" class NerfedCharge(Toggle): @@ -179,7 +198,12 @@ class NerfedCharge(Toggle): display_name = "Nerfed Charge" class GravityBehaviour(Choice): - """Modify the heat damage and enemy damage reduction qualities of the Gravity and Varia Suits.""" + """Modify the heat damage and enemy damage reduction qualities of the Gravity and Varia Suits. + - Vanilla: Gravity provides full protection against all environmental damage (heat, spikes, etc.) + - Balanced: Removes Gravity environmental protection. Doubles Varia environmental protection. Enemy damage protection + is vanilla (50% Varia, 75% Gravity). + - Progressive: Gravity provides 50% heat reduction, Varia provides full heat reduction. Each suit adds 50% enemy + and environmental reduction, stacking to 75% reduction if you have both.""" display_name = "Gravity Behaviour" option_Vanilla = 0 option_Balanced = 1 @@ -233,7 +257,7 @@ class RandomMusic(Toggle): class CustomPreset(OptionDict): """ - see https://randommetroidsolver.pythonanywhere.com/presets for detailed info on each preset settings + see https://varia.run/presets for detailed info on each preset settings knows: each skill (know) has a pair [can use, perceived difficulty using one of 1, 5, 10, 25, 50 or 100 each one matching a max_difficulty] settings: hard rooms, hellruns and bosses settings @@ -246,7 +270,7 @@ class CustomPreset(OptionDict): } class VariaCustomPreset(OptionList): - """use an entry from the preset list on https://randommetroidsolver.pythonanywhere.com/presets""" + """use an entry from the preset list on https://varia.run/presets""" display_name = "Varia Custom Preset" default = {} @@ -259,7 +283,7 @@ class EscapeRando(Toggle): During the escape sequence: - All doors are opened - Maridia tube is opened - - The Hyper Beam can destroy Bomb , Power Bomb and Super Missile blocks and open blue/green gates from both sides + - The Hyper Beam can destroy Bomb, Power Bomb and Super Missile blocks and open blue/green gates from both sides - All mini bosses are defeated - All minor enemies are removed to allow you to move faster and remove lag @@ -281,9 +305,9 @@ class RemoveEscapeEnemies(Toggle): class Tourian(Choice): """ Choose endgame Tourian behaviour: - Vanilla: regular vanilla Tourian - Fast: speed up Tourian to skip Metroids, Zebetites, and all cutscenes (including Mother Brain 3 fight). Golden Four statues are replaced by an invincible Gadora until all objectives are completed. - Disabled: skip Tourian entirely, ie. escape sequence is triggered as soon as all objectives are completed. + - Vanilla: regular vanilla Tourian + - Fast: speed up Tourian to skip Metroids, Zebetites, and all cutscenes (including Mother Brain 3 fight). Golden Four statues are replaced by an invincible Gadora until all objectives are completed. + - Disabled: skip Tourian entirely; the escape sequence is triggered as soon as all objectives are completed. """ display_name = "Endgame behavior with Tourian" option_Vanilla = 0 @@ -373,10 +397,71 @@ class RelaxedRoundRobinCF(Toggle): """ display_name = "Relaxed round robin Crystal Flash" +sm_option_groups = [ + OptionGroup("Logic", [ + Preset, + MaxDifficulty, + StartLocation, + VariaCustomPreset, + CustomPreset, + ]), + OptionGroup("Objectives and Endgame", [ + Objective, + CustomObjective, + CustomObjectiveCount, + CustomObjectiveList, + Tourian, + EscapeRando, + RemoveEscapeEnemies, + Animals, + ]), + OptionGroup("Areas and Layout", [ + AreaRandomization, + AreaLayout, + DoorsColorsRando, + AllowGreyDoors, + BossRandomization, + LayoutPatches, + ]), + OptionGroup("Item Pool", [ + MorphPlacement, + StrictMinors, + MissileQty, + SuperQty, + PowerBombQty, + MinorQty, + EnergyQty, + FunCombat, + FunMovement, + FunSuits, + ]), + OptionGroup("Misc Tweaks", [ + VariaTweaks, + GravityBehaviour, + NerfedCharge, + SpinJumpRestart, + SpeedKeep, + InfiniteSpaceJump, + RelaxedRoundRobinCF, + ]), + OptionGroup("Quality of Life", [ + ElevatorsSpeed, + DoorsSpeed, + RefillBeforeSave, + ]), + OptionGroup("Cosmetic", [ + Hud, + HideItems, + NoMusic, + RandomMusic, + ]), +] + @dataclass class SMOptions(PerGameCommonOptions): start_inventory_removes_from_pool: StartItemsRemovesFromPool preset: Preset + max_difficulty: MaxDifficulty start_location: StartLocation remote_items: RemoteItems death_link: DeathLink @@ -384,7 +469,6 @@ class SMOptions(PerGameCommonOptions): #scav_num_locs: "10" #scav_randomized: "off" #scav_escape: "off" - max_difficulty: MaxDifficulty #progression_speed": "medium" #progression_difficulty": "normal" morph_placement: MorphPlacement diff --git a/worlds/sm/__init__.py b/worlds/sm/__init__.py index 3272f40c9b5d..cdb58b72fbd9 100644 --- a/worlds/sm/__init__.py +++ b/worlds/sm/__init__.py @@ -15,7 +15,7 @@ logger = logging.getLogger("Super Metroid") -from .Options import SMOptions +from .Options import SMOptions, sm_option_groups from .Client import SMSNIClient from .Rom import SM_ROM_MAX_PLAYERID, SM_ROM_PLAYERDATA_COUNT, SMProcedurePatch, get_sm_symbols import Utils @@ -78,6 +78,7 @@ class SMWeb(WebWorld): "multiworld/en", ["Farrak Kilhn"] )] + option_groups = sm_option_groups class ByteEdit(TypedDict): From fb9026d12da47ebbf24a487daf9ffaee93a361de Mon Sep 17 00:00:00 2001 From: David Carroll Date: Thu, 17 Jul 2025 06:48:55 -0500 Subject: [PATCH 0584/1218] SMZ3: Add Yaml Options to Slot Data (#5111) --- worlds/smz3/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/worlds/smz3/__init__.py b/worlds/smz3/__init__.py index dca105b16283..a98ae11df355 100644 --- a/worlds/smz3/__init__.py +++ b/worlds/smz3/__init__.py @@ -500,7 +500,14 @@ def modify_multidata(self, multidata: dict): multidata["connect_names"][new_name] = payload def fill_slot_data(self): - slot_data = {} + slot_data = { + "goal": self.options.goal.value, + "open_tower": self.options.open_tower.value, + "ganon_vulnerable": self.options.ganon_vulnerable.value, + "open_tourian": self.options.open_tourian.value, + "sm_logic": self.options.sm_logic.value, + "key_shuffle": self.options.key_shuffle.value, + } return slot_data def collect(self, state: CollectionState, item: Item) -> bool: From da0bb80fb4763a24cbf6c5cf00f01bf0dcaa3b1e Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Fri, 18 Jul 2025 07:28:05 -0400 Subject: [PATCH 0585/1218] Raft: Fix filler_item_types TypeError introduced in #4782 (#5203) --- worlds/raft/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/raft/__init__.py b/worlds/raft/__init__.py index 74ab9291b26e..374d952d4601 100644 --- a/worlds/raft/__init__.py +++ b/worlds/raft/__init__.py @@ -93,7 +93,7 @@ def create_items(self): dupeItemPool = list(dupeItemPool) # Finally, add items as necessary for item in dupeItemPool: - self.extraItemNamePool.append(self.replace_item_name_as_necessary(item)) + self.extraItemNamePool.append(self.replace_item_name_as_necessary(item["name"])) assert self.extraItemNamePool, f"Don't know what extra items to create for {self.player_name}." From a535ca31a8ae99e9c2bda8f09346ef062afe27ab Mon Sep 17 00:00:00 2001 From: Adrian Priestley <47989725+a-priestley@users.noreply.github.com> Date: Sat, 19 Jul 2025 11:18:30 -0230 Subject: [PATCH 0586/1218] Dockerfile/Core: Prevent module update during container runtime (#5205) * fix(env): Prevent module update during requirements processing - Add environment variable SKIP_REQUIREMENTS_UPDATE check - Ensure update is skipped if SKIP_REQUIREMENTS_UPDATE is set to true * squash! fix(env): Prevent module update during requirements processing - Add environment variable SKIP_REQUIREMENTS_UPDATE check - Ensure update is skipped if SKIP_REQUIREMENTS_UPDATE is set to true --- Dockerfile | 1 + ModuleUpdate.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0ed61c030172..c6d22a4fb836 100644 --- a/Dockerfile +++ b/Dockerfile @@ -94,4 +94,5 @@ RUN if [ "$TARGETARCH" = "amd64" ]; then \ HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:${PORT:-80} || exit 1 +ENV SKIP_REQUIREMENTS_UPDATE=true ENTRYPOINT [ "python", "WebHost.py" ] diff --git a/ModuleUpdate.py b/ModuleUpdate.py index 04cf25ea5594..e6ac570e5813 100644 --- a/ModuleUpdate.py +++ b/ModuleUpdate.py @@ -16,7 +16,11 @@ raise RuntimeError(f"Incompatible Python Version found: {sys.version_info}. 3.10.1+ is supported.") # don't run update if environment is frozen/compiled or if not the parent process (skip in subprocess) -_skip_update = bool(getattr(sys, "frozen", False) or multiprocessing.parent_process()) +_skip_update = bool( + getattr(sys, "frozen", False) or + multiprocessing.parent_process() or + os.environ.get("SKIP_REQUIREMENTS_UPDATE", "").lower() in ("1", "true", "yes") +) update_ran = _skip_update From d313a742663e68a57548826250dcec1c580f241d Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:53:34 -0400 Subject: [PATCH 0587/1218] ALttP: Fix `pre_fill` State Sweeping Too Early (#5215) --- worlds/alttp/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index 7f8d6ddf68ac..773fd7050cf2 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -505,10 +505,11 @@ def collect_item(self, state: CollectionState, item: Item, remove=False): def pre_fill(self): from Fill import fill_restrictive, FillError attempts = 5 - all_state = self.multiworld.get_all_state(use_cache=False) + all_state = self.multiworld.get_all_state(perform_sweep=False) crystals = [self.create_item(name) for name in ['Red Pendant', 'Blue Pendant', 'Green Pendant', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 7', 'Crystal 5', 'Crystal 6']] for crystal in crystals: all_state.remove(crystal) + all_state.sweep_for_advancements() crystal_locations = [self.get_location('Turtle Rock - Prize'), self.get_location('Eastern Palace - Prize'), self.get_location('Desert Palace - Prize'), From 76760e1bf3ba2d2d961657dbd03c2acc41a80f98 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Wed, 23 Jul 2025 03:01:47 +0100 Subject: [PATCH 0588/1218] OoT: Fix remove not invalidating cached reachability (#5222) Collecting an item into a CollectionState without sweeping, finding all reachable locations, removing that item from the state, and then finding all reachable locations again could result in more locations being reachable than before the item was initially collected into the CollectionState. This issue was present because OoT was not invalidating its reachable region caches for the different ages when items were removed from the CollectionState. To fix the issue, this PR has updated `OOTWorld.remove()` to invalid its caches, like how `CollectionState.remove()` invalidates the core Archipelago caches. --- worlds/oot/__init__.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/worlds/oot/__init__.py b/worlds/oot/__init__.py index ed025f49719c..d9465f1761b1 100644 --- a/worlds/oot/__init__.py +++ b/worlds/oot/__init__.py @@ -1324,10 +1324,20 @@ def remove(self, state: CollectionState, item: OOTItem) -> bool: state.prog_items[self.player][alt_item_name] -= count if state.prog_items[self.player][alt_item_name] < 1: del (state.prog_items[self.player][alt_item_name]) + # invalidate caches, nothing can be trusted anymore now + state.child_reachable_regions[self.player] = set() + state.child_blocked_connections[self.player] = set() + state.adult_reachable_regions[self.player] = set() + state.adult_blocked_connections[self.player] = set() state._oot_stale[self.player] = True return True changed = super().remove(state, item) if changed: + # invalidate caches, nothing can be trusted anymore now + state.child_reachable_regions[self.player] = set() + state.child_blocked_connections[self.player] = set() + state.adult_reachable_regions[self.player] = set() + state.adult_blocked_connections[self.player] = set() state._oot_stale[self.player] = True return changed From 6b44f217a35489f520698d25dbb8cabeebb3e348 Mon Sep 17 00:00:00 2001 From: Flore Date: Wed, 23 Jul 2025 05:39:07 +0200 Subject: [PATCH 0589/1218] DS3: Edit the setup docs to be more clear (#4618) * UPDATE: Dark Souls 3 setup docs to be more clear * UPDATE: DS3 Setup docs to make offline mode more explicit * UPDATE: Dark Souls 3 setup docs to be more clear * UPDATE: DS3 Setup docs to make offline mode more explicit * EDIT: DS3 setup docs to be up to date --- worlds/dark_souls_3/docs/setup_en.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/worlds/dark_souls_3/docs/setup_en.md b/worlds/dark_souls_3/docs/setup_en.md index 4b11c8a498d9..7edf0d54e101 100644 --- a/worlds/dark_souls_3/docs/setup_en.md +++ b/worlds/dark_souls_3/docs/setup_en.md @@ -39,15 +39,13 @@ randomized item and (optionally) enemy locations. You only need to do this once To run _Dark Souls III_ in Archipelago mode: -1. Start Steam. **Do not run in offline mode.** Running Steam in offline mode will make certain - scripted invaders fail to spawn. Instead, change the game itself to offline mode on the menu - screen. +1. Start Steam. **Do not run Steam in offline mode.** Running Steam in offline mode will make certain + scripted invaders fail to spawn. -2. Run `launchmod_darksouls3.bat`. This will start _Dark Souls III_ as well as a command prompt that - you can use to interact with the Archipelago server. +2. To prevent you from getting penalized, **make sure to set _Dark Souls III_ to offline mode in the game options.** -3. Type `/connect {SERVER_IP}:{SERVER_PORT} {SLOT_NAME}` into the command prompt, with the - appropriate values filled in. For example: `/connect archipelago.gg:24242 PlayerName`. +3. Run `launchmod_darksouls3.bat`. This will start _Dark Souls III_ as well as a command prompt that + you can use to interact with the Archipelago server. 4. Start playing as normal. An "Archipelago connected" message will appear onscreen once you have control of your character and the connection is established. From 0e4314ad1e840481d12252ae41358b14217aa3f6 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Wed, 23 Jul 2025 13:04:07 +0200 Subject: [PATCH 0590/1218] MultiServer: CreateHints command (Allows clients to hint own items in other worlds) (#4317) * CreateHint command * Docs * oops * forgot an arg * Update MultiServer.py * Add documentation on what happens when the hint already exists but with a different status (nothing) * Early exit if no locations provided * Add a clarifying comment to the code as well * change wording a bit --- MultiServer.py | 42 ++++++++++++++++++++++++++++++++++++++++ docs/network protocol.md | 16 +++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/MultiServer.py b/MultiServer.py index f12f327c3f62..108795d84f5d 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1950,6 +1950,48 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): if locs and create_as_hint: ctx.save() await ctx.send_msgs(client, [{'cmd': 'LocationInfo', 'locations': locs}]) + + elif cmd == 'CreateHints': + location_player = args.get("player", client.slot) + locations = args["locations"] + status = args.get("status", HintStatus.HINT_UNSPECIFIED) + + if not locations: + await ctx.send_msgs(client, [{"cmd": "InvalidPacket", "type": "arguments", + "text": "CreateHints: No locations specified.", "original_cmd": cmd}]) + + hints = [] + + for location in locations: + if location_player != client.slot and location not in ctx.locations[location_player]: + error_text = ( + "CreateHints: One or more of the locations do not exist for the specified off-world player. " + "Please refrain from hinting other slot's locations that you don't know contain your items." + ) + await ctx.send_msgs(client, [{"cmd": "InvalidPacket", "type": "arguments", + "text": error_text, "original_cmd": cmd}]) + return + + target_item, item_player, flags = ctx.locations[location_player][location] + + if client.slot not in ctx.slot_set(item_player): + if status != HintStatus.HINT_UNSPECIFIED: + error_text = 'CreateHints: Must use "unspecified"/None status for items from other players.' + await ctx.send_msgs(client, [{"cmd": "InvalidPacket", "type": "arguments", + "text": error_text, "original_cmd": cmd}]) + return + + if client.slot != location_player: + error_text = "CreateHints: Can only create hints for own items or own locations." + await ctx.send_msgs(client, [{"cmd": "InvalidPacket", "type": "arguments", + "text": error_text, "original_cmd": cmd}]) + return + + hints += collect_hint_location_id(ctx, client.team, location_player, location, status) + + # As of writing this code, only_new=True does not update status for existing hints + ctx.notify_hints(client.team, hints, only_new=True) + ctx.save() elif cmd == 'UpdateHint': location = args["location"] diff --git a/docs/network protocol.md b/docs/network protocol.md index 27238e6b7487..4b66b7b1d349 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -276,6 +276,7 @@ These packets are sent purely from client to server. They are not accepted by cl * [Sync](#Sync) * [LocationChecks](#LocationChecks) * [LocationScouts](#LocationScouts) +* [CreateHints](#CreateHints) * [UpdateHint](#UpdateHint) * [StatusUpdate](#StatusUpdate) * [Say](#Say) @@ -347,6 +348,21 @@ This is useful in cases where an item appears in the game world, such as 'ledge | locations | list\[int\] | The ids of the locations seen by the client. May contain any number of locations, even ones sent before; duplicates do not cause issues with the Archipelago server. | | create_as_hint | int | If non-zero, the scouted locations get created and broadcasted as a player-visible hint.
    If 2 only new hints are broadcast, however this does not remove them from the LocationInfo reply. | +### CreateHints + +Sent to the server to create hints for a specified list of locations. +Hints that already exist will be silently skipped and their status will not be updated. + +When creating hints for another slot's locations, the packet will fail if any of those locations don't contain items for the requesting slot. +When creating hints for your own slot's locations, non-existing locations will silently be skipped. + +#### Arguments +| Name | Type | Notes | +| ---- | ---- | ----- | +| locations | list\[int\] | The ids of the locations to create hints for. | +| player | int | The ID of the player whose locations are being hinted for. Defaults to the requesting slot. | +| status | [HintStatus](#HintStatus) | If included, sets the status of the hint to this status. Defaults to `HINT_UNSPECIFIED`. Cannot set `HINT_FOUND`. | + ### UpdateHint Sent to the server to update the status of a Hint. The client must be the 'receiving_player' of the Hint, or the update fails. From 8541c87c9785cce98820002bec4ca4b8ad1c00b6 Mon Sep 17 00:00:00 2001 From: MarioManTAW Date: Wed, 23 Jul 2025 16:27:50 -0500 Subject: [PATCH 0591/1218] Paint: Implement New Game (#4955) * Paint: Implement New Game * Add docstring * Remove unnecessary self.multiworld references * Implement start_inventory_from_pool * Convert logic to use LogicMixin * Add location_exists_with_options function to deduplicate code * Simplify starting tool creation * Add Paint to supported games list * Increment version to 0.4.1 * Update docs to include color selection features * Fix world attribute definitions * Fix linting errors * De-duplicate lists of traps * Move LogicMixin to __init__.py * 0.5.0 features - adjustable canvas size increment, updated similarity metric * Fix OptionError formatting * Create OptionError when generating single-player game with error-prone settings * Increment version to 0.5.1 * Update CODEOWNERS * Update documentation for 0.5.2 client changes * Simplify region creation * Add comments describing logic * Remove unnecessary f-strings * Remove unused import * Refactor rules to location class * Remove unnecessary self.multiworld references * Update logic to correctly match client-side item caps --------- Co-authored-by: Fabian Dill --- README.md | 1 + docs/CODEOWNERS | 3 + worlds/paint/__init__.py | 128 ++++++++++++++++++++++++++++++++++ worlds/paint/docs/en_Paint.md | 35 ++++++++++ worlds/paint/docs/guide_en.md | 8 +++ worlds/paint/items.py | 48 +++++++++++++ worlds/paint/locations.py | 24 +++++++ worlds/paint/options.py | 107 ++++++++++++++++++++++++++++ worlds/paint/rules.py | 40 +++++++++++ 9 files changed, 394 insertions(+) create mode 100644 worlds/paint/__init__.py create mode 100644 worlds/paint/docs/en_Paint.md create mode 100644 worlds/paint/docs/guide_en.md create mode 100644 worlds/paint/items.py create mode 100644 worlds/paint/locations.py create mode 100644 worlds/paint/options.py create mode 100644 worlds/paint/rules.py diff --git a/README.md b/README.md index 29b6206a00d8..44c44d72b4e9 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ Currently, the following games are supported: * Jak and Daxter: The Precursor Legacy * Super Mario Land 2: 6 Golden Coins * shapez +* Paint For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 3104200a6c9d..85b31683aa3a 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -136,6 +136,9 @@ # Overcooked! 2 /worlds/overcooked2/ @toasterparty +# Paint +/worlds/paint/ @MarioManTAW + # Pokemon Emerald /worlds/pokemon_emerald/ @Zunawe diff --git a/worlds/paint/__init__.py b/worlds/paint/__init__.py new file mode 100644 index 000000000000..8e501ff3dcff --- /dev/null +++ b/worlds/paint/__init__.py @@ -0,0 +1,128 @@ +from typing import Dict, Any + +from BaseClasses import CollectionState, Item, MultiWorld, Tutorial, Region +from Options import OptionError +from worlds.AutoWorld import LogicMixin, World, WebWorld +from .items import item_table, PaintItem, item_data_table, traps, deathlink_traps +from .locations import location_table, PaintLocation, location_data_table +from .options import PaintOptions + + +class PaintWebWorld(WebWorld): + theme = "partyTime" + + setup_en = Tutorial( + tutorial_name="Start Guide", + description="A guide to playing Paint in Archipelago.", + language="English", + file_name="guide_en.md", + link="guide/en", + authors=["MarioManTAW"] + ) + + tutorials = [setup_en] + + +class PaintWorld(World): + """ + The classic Microsoft app, reimagined as an Archipelago game! Find your tools, expand your canvas, and paint the + greatest image the world has ever seen. + """ + game = "Paint" + options_dataclass = PaintOptions + options: PaintOptions + web = PaintWebWorld() + location_name_to_id = location_table + item_name_to_id = item_table + origin_region_name = "Canvas" + + def generate_early(self) -> None: + if self.options.canvas_size_increment < 50 and self.options.logic_percent <= 55: + if self.multiworld.players == 1: + raise OptionError("Logic Percent must be greater than 55 when generating a single-player world with " + "Canvas Size Increment below 50.") + + def get_filler_item_name(self) -> str: + if self.random.randint(0, 99) >= self.options.trap_count: + return "Additional Palette Color" + elif self.options.death_link: + return self.random.choice(deathlink_traps) + else: + return self.random.choice(traps) + + def create_item(self, name: str) -> PaintItem: + item = PaintItem(name, item_data_table[name].type, item_data_table[name].code, self.player) + return item + + def create_items(self) -> None: + starting_tools = ["Brush", "Pencil", "Eraser/Color Eraser", "Airbrush", "Line", "Rectangle", "Ellipse", + "Rounded Rectangle"] + self.push_precollected(self.create_item("Magnifier")) + self.push_precollected(self.create_item(starting_tools.pop(self.options.starting_tool))) + items_to_create = ["Free-Form Select", "Select", "Fill With Color", "Pick Color", "Text", "Curve", "Polygon"] + items_to_create += starting_tools + items_to_create += ["Progressive Canvas Width"] * (400 // self.options.canvas_size_increment) + items_to_create += ["Progressive Canvas Height"] * (300 // self.options.canvas_size_increment) + depth_items = ["Progressive Color Depth (Red)", "Progressive Color Depth (Green)", + "Progressive Color Depth (Blue)"] + for item in depth_items: + self.push_precollected(self.create_item(item)) + items_to_create += depth_items * 6 + pre_filled = len(items_to_create) + to_fill = len(self.get_region("Canvas").locations) + if pre_filled > to_fill: + raise OptionError(f"{self.player_name}'s Paint world has too few locations for its required items. " + "Consider adding more locations by raising logic percent or adding fractional checks. " + "Alternatively, increasing the canvas size increment will require fewer items.") + while len(items_to_create) < (to_fill - pre_filled) * (self.options.trap_count / 100) + pre_filled: + if self.options.death_link: + items_to_create += [self.random.choice(deathlink_traps)] + else: + items_to_create += [self.random.choice(traps)] + while len(items_to_create) < to_fill: + items_to_create += ["Additional Palette Color"] + self.multiworld.itempool += [self.create_item(item) for item in items_to_create] + + def create_regions(self) -> None: + canvas = Region("Canvas", self.player, self.multiworld) + canvas.locations += [PaintLocation(self.player, loc_name, loc_data.address, canvas) + for loc_name, loc_data in location_data_table.items() + if location_exists_with_options(self, loc_data.address)] + + self.multiworld.regions += [canvas] + + def set_rules(self) -> None: + from .rules import set_completion_rules + set_completion_rules(self, self.player) + + def fill_slot_data(self) -> Dict[str, Any]: + return dict(self.options.as_dict("logic_percent", "goal_percent", "goal_image", "death_link", + "canvas_size_increment"), version="0.5.2") + + def collect(self, state: CollectionState, item: Item) -> bool: + change = super().collect(state, item) + if change: + state.paint_percent_stale[self.player] = True + return change + + def remove(self, state: CollectionState, item: Item) -> bool: + change = super().remove(state, item) + if change: + state.paint_percent_stale[self.player] = True + return change + + +def location_exists_with_options(world: PaintWorld, location: int): + l = location % 198600 + return l <= world.options.logic_percent * 4 and (l % 4 == 0 or + (l > world.options.half_percent_checks * 4 and l % 2 == 0) or + l > world.options.quarter_percent_checks * 4) + + +class PaintState(LogicMixin): + paint_percent_available: dict[int, float] # per player + paint_percent_stale: dict[int, bool] + + def init_mixin(self, multiworld: MultiWorld) -> None: + self.paint_percent_available = {player: 0 for player in multiworld.get_game_players("Paint")} + self.paint_percent_stale = {player: True for player in multiworld.get_game_players("Paint")} diff --git a/worlds/paint/docs/en_Paint.md b/worlds/paint/docs/en_Paint.md new file mode 100644 index 000000000000..845c7268485d --- /dev/null +++ b/worlds/paint/docs/en_Paint.md @@ -0,0 +1,35 @@ +# Paint + +## Where is the options page? + +You can read through all the options and generate a YAML [here](../player-options). + +## What does randomization do to this game? + +Most tools are locked from the start, leaving only the Magnifier and one drawing tool, specified in the game options. +Canvas size is locked and will only expand when the Progressive Canvas Width and Progressive Canvas Height items are +obtained. Additionally, color selection is limited, starting with only a few possible colors but gaining more options +when Progressive Color Depth items are obtained in each of the red, green, and blue components. + +Location checks are sent out based on similarity to a target image, measured as a percentage. Every percentage point up +to a maximum set in the game options will send a new check, and the game will be considered done when a certain target +percentage (also set in the game options) is reached. + +## What other changes are made to the game? + +This project is based on [JS Paint](https://jspaint.app), an open-source remake of Microsoft Paint. Most features will +work similarly to this version but some features have also been removed. Most notably, pasting functionality has been +completely removed to prevent cheating. + +With the addition of a second canvas to display the target image, there are some additional features that may not be +intuitive. There are two special functions in the Extras menu to help visualize how to improve your score. Similarity +Mode (shortcut Ctrl+Shift+M) shows the similarity of each portion of the image in grayscale, with white representing +perfect similarity and black representing no similarity. Conversely, Difference Mode (shortcut Ctrl+M) visualizes the +differences between what has been drawn and the target image in full color, showing the direction both hue and +lightness need to shift to match the target. Additionally, once unlocked, the Pick Color tool can be used on both the +main and target canvases. + +Custom colors have been streamlined for Archipelago play. The only starting palette options are black and white, but +additional palette slots can be unlocked as Archipelago items. Double-clicking on any palette slot will allow you to +edit the color in that slot directly and shift-clicking a palette slot will allow you to override the slot with your +currently selected color. diff --git a/worlds/paint/docs/guide_en.md b/worlds/paint/docs/guide_en.md new file mode 100644 index 000000000000..8571ad3d4dd3 --- /dev/null +++ b/worlds/paint/docs/guide_en.md @@ -0,0 +1,8 @@ +# Paint Randomizer Start Guide + +After rolling your seed, go to the [Archipelago Paint](https://mariomantaw.github.io/jspaint/) site and enter the +server details, your slot name, and a room password if one is required. Then click "Connect". If desired, you may then +load a custom target image with File->Open Goal Image. If playing asynchronously, note that progress is saved using the +hash that will appear at the end of the URL so it is recommended to leave the tab open or save the URL with the hash to +avoid losing progress. + diff --git a/worlds/paint/items.py b/worlds/paint/items.py new file mode 100644 index 000000000000..c2ea2001b66a --- /dev/null +++ b/worlds/paint/items.py @@ -0,0 +1,48 @@ +from typing import NamedTuple, Dict + +from BaseClasses import Item, ItemClassification + + +class PaintItem(Item): + game = "Paint" + + +class PaintItemData(NamedTuple): + code: int + type: ItemClassification + + +item_data_table: Dict[str, PaintItemData] = { + "Progressive Canvas Width": PaintItemData(198501, ItemClassification.progression), + "Progressive Canvas Height": PaintItemData(198502, ItemClassification.progression), + "Progressive Color Depth (Red)": PaintItemData(198503, ItemClassification.progression), + "Progressive Color Depth (Green)": PaintItemData(198504, ItemClassification.progression), + "Progressive Color Depth (Blue)": PaintItemData(198505, ItemClassification.progression), + "Free-Form Select": PaintItemData(198506, ItemClassification.useful), + "Select": PaintItemData(198507, ItemClassification.useful), + "Eraser/Color Eraser": PaintItemData(198508, ItemClassification.useful), + "Fill With Color": PaintItemData(198509, ItemClassification.useful), + "Pick Color": PaintItemData(198510, ItemClassification.progression), + "Magnifier": PaintItemData(198511, ItemClassification.useful), + "Pencil": PaintItemData(198512, ItemClassification.useful), + "Brush": PaintItemData(198513, ItemClassification.useful), + "Airbrush": PaintItemData(198514, ItemClassification.useful), + "Text": PaintItemData(198515, ItemClassification.useful), + "Line": PaintItemData(198516, ItemClassification.useful), + "Curve": PaintItemData(198517, ItemClassification.useful), + "Rectangle": PaintItemData(198518, ItemClassification.useful), + "Polygon": PaintItemData(198519, ItemClassification.useful), + "Ellipse": PaintItemData(198520, ItemClassification.useful), + "Rounded Rectangle": PaintItemData(198521, ItemClassification.useful), + # "Change Background Color": PaintItemData(198522, ItemClassification.useful), + "Additional Palette Color": PaintItemData(198523, ItemClassification.filler), + "Undo Trap": PaintItemData(198524, ItemClassification.trap), + "Clear Image Trap": PaintItemData(198525, ItemClassification.trap), + "Invert Colors Trap": PaintItemData(198526, ItemClassification.trap), + "Flip Horizontal Trap": PaintItemData(198527, ItemClassification.trap), + "Flip Vertical Trap": PaintItemData(198528, ItemClassification.trap), +} + +item_table = {name: data.code for name, data in item_data_table.items()} +traps = ["Undo Trap", "Clear Image Trap", "Invert Colors Trap", "Flip Horizontal Trap", "Flip Vertical Trap"] +deathlink_traps = ["Invert Colors Trap", "Flip Horizontal Trap", "Flip Vertical Trap"] diff --git a/worlds/paint/locations.py b/worlds/paint/locations.py new file mode 100644 index 000000000000..ce227991efd9 --- /dev/null +++ b/worlds/paint/locations.py @@ -0,0 +1,24 @@ +from typing import NamedTuple, Dict + +from BaseClasses import CollectionState, Location + + +class PaintLocation(Location): + game = "Paint" + def access_rule(self, state: CollectionState): + from .rules import paint_percent_available + return paint_percent_available(state, state.multiworld.worlds[self.player], self.player) >=\ + (self.address % 198600) / 4 + + +class PaintLocationData(NamedTuple): + region: str + address: int + + +location_data_table: Dict[str, PaintLocationData] = { + # f"Similarity: {i}%": PaintLocationData("Canvas", 198500 + i) for i in range(1, 96) + f"Similarity: {i/4}%": PaintLocationData("Canvas", 198600 + i) for i in range(1, 381) +} + +location_table = {name: data.address for name, data in location_data_table.items()} diff --git a/worlds/paint/options.py b/worlds/paint/options.py new file mode 100644 index 000000000000..95dee7d8fd9f --- /dev/null +++ b/worlds/paint/options.py @@ -0,0 +1,107 @@ +from dataclasses import dataclass + +from Options import Range, PerGameCommonOptions, StartInventoryPool, Toggle, Choice, Visibility + + +class LogicPercent(Range): + """Sets the maximum percent similarity required for a check to be in logic. + Higher values are more difficult and items/locations will not be generated beyond this number.""" + display_name = "Logic Percent" + range_start = 50 + range_end = 95 + default = 80 + + +class GoalPercent(Range): + """Sets the percent similarity required to achieve your goal. + If this number is higher than the value for logic percent, + reaching goal will be in logic upon obtaining all progression items.""" + display_name = "Goal Percent" + range_start = 50 + range_end = 95 + default = 80 + + +class HalfPercentChecks(Range): + """Sets the lowest percent at which locations will be created for each 0.5% of similarity. + Below this number, there will be a check every 1%. + Above this number, there will be a check every 0.5%.""" + display_name = "Half Percent Checks" + range_start = 0 + range_end = 95 + default = 50 + + +class QuarterPercentChecks(Range): + """Sets the lowest percent at which locations will be created for each 0.25% of similarity. + This number will override Half Percent Checks if it is lower.""" + display_name = "Quarter Percent Checks" + range_start = 0 + range_end = 95 + default = 70 + + +class CanvasSizeIncrement(Choice): + """Sets the number of pixels the canvas will expand for each width/height item received. + Ensure an adequate number of locations are generated if setting this below 50.""" + display_name = "Canvas Size Increment" + # option_10 = 10 + # option_20 = 20 + option_25 = 25 + option_50 = 50 + option_100 = 100 + default = 100 + + +class GoalImage(Range): + """Sets the numbered image you will be required to match. + See https://github.com/MarioManTAW/jspaint/tree/master/images/archipelago + for a list of possible images or choose random. + This can also be overwritten client-side by using File->Open.""" + display_name = "Goal Image" + range_start = 1 + range_end = 1 + default = 1 + visibility = Visibility.none + + +class StartingTool(Choice): + """Sets which tool (other than Magnifier) you will be able to use from the start.""" + option_brush = 0 + option_pencil = 1 + option_eraser = 2 + option_airbrush = 3 + option_line = 4 + option_rectangle = 5 + option_ellipse = 6 + option_rounded_rectangle = 7 + default = 0 + + +class TrapCount(Range): + """Sets the percentage of filler items to be replaced by random traps.""" + display_name = "Trap Fill Percent" + range_start = 0 + range_end = 100 + default = 0 + + +class DeathLink(Toggle): + """If on, using the Undo or Clear Image functions will send a death to all other players with death link on. + Receiving a death will clear the image and reset the history. + This option also prevents Undo and Clear Image traps from being generated in the item pool.""" + display_name = "Death Link" + + +@dataclass +class PaintOptions(PerGameCommonOptions): + logic_percent: LogicPercent + goal_percent: GoalPercent + half_percent_checks: HalfPercentChecks + quarter_percent_checks: QuarterPercentChecks + canvas_size_increment: CanvasSizeIncrement + goal_image: GoalImage + starting_tool: StartingTool + trap_count: TrapCount + death_link: DeathLink + start_inventory_from_pool: StartInventoryPool diff --git a/worlds/paint/rules.py b/worlds/paint/rules.py new file mode 100644 index 000000000000..1c7844c12931 --- /dev/null +++ b/worlds/paint/rules.py @@ -0,0 +1,40 @@ +from math import sqrt + +from BaseClasses import CollectionState +from . import PaintWorld + + +def paint_percent_available(state: CollectionState, world: PaintWorld, player: int) -> bool: + if state.paint_percent_stale[player]: + state.paint_percent_available[player] = calculate_paint_percent_available(state, world, player) + state.paint_percent_stale[player] = False + return state.paint_percent_available[player] + + +def calculate_paint_percent_available(state: CollectionState, world: PaintWorld, player: int) -> float: + p = state.has("Pick Color", player) + r = min(state.count("Progressive Color Depth (Red)", player), 7) + g = min(state.count("Progressive Color Depth (Green)", player), 7) + b = min(state.count("Progressive Color Depth (Blue)", player), 7) + if not p: + r = min(r, 2) + g = min(g, 2) + b = min(b, 2) + w = state.count("Progressive Canvas Width", player) + h = state.count("Progressive Canvas Height", player) + # This code looks a little messy but it's a mathematical formula derived from the similarity calculations in the + # client. The first line calculates the maximum score achievable for a single pixel with the current items in the + # worst possible case. This per-pixel score is then multiplied by the number of pixels currently available (the + # starting canvas is 400x300) over the total number of pixels with everything unlocked (800x600) to get the + # total score achievable assuming the worst possible target image. Finally, this is multiplied by the logic percent + # option which restricts the logic so as to not require pixel perfection. + return ((1 - ((sqrt(((2 ** (7 - r) - 1) ** 2 + (2 ** (7 - g) - 1) ** 2 + (2 ** (7 - b) - 1) ** 2) * 12)) / 765)) * + min(400 + w * world.options.canvas_size_increment, 800) * + min(300 + h * world.options.canvas_size_increment, 600) * + world.options.logic_percent / 480000) + + +def set_completion_rules(world: PaintWorld, player: int) -> None: + world.multiworld.completion_condition[player] = \ + lambda state: (paint_percent_available(state, world, player) >= + min(world.options.logic_percent, world.options.goal_percent)) From 81b8f3fc0ef1b562b190875d2d68b3bb971e5c98 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Thu, 24 Jul 2025 00:01:27 +0200 Subject: [PATCH 0592/1218] Factorio: fix rename of mod file leading to incompatibility with base game (#5219) --- WebHostLib/templates/macros.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WebHostLib/templates/macros.html b/WebHostLib/templates/macros.html index be664274e621..9a16bce1d392 100644 --- a/WebHostLib/templates/macros.html +++ b/WebHostLib/templates/macros.html @@ -32,6 +32,9 @@ {% elif patch.game == "Super Mario 64" and room.seed.slots|length == 1 %} Download APSM64EX File... + {% elif patch.game == "Factorio" %} + + Download Factorio Mod... {% elif patch.game | is_applayercontainer(patch.data, patch.player_id) %} Download Patch File... From 4ac1d91c16378fa9fed86ece314c3f55788468d4 Mon Sep 17 00:00:00 2001 From: Adrian Priestley <47989725+a-priestley@users.noreply.github.com> Date: Thu, 24 Jul 2025 04:05:13 -0230 Subject: [PATCH 0593/1218] chore(ci): exclude deployment and Docker files from unit test workflow triggers (#5214) * chore(ci): exclude deployment and Docker files from unit test workflow triggers - Modify unittests workflow to ignore changes in deploy directory and Docker-related files --- .github/workflows/unittests.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index 88b5d12987ad..2d83c649e852 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -8,18 +8,24 @@ on: paths: - '**' - '!docs/**' + - '!deploy/**' - '!setup.py' + - '!Dockerfile' - '!*.iss' - '!.gitignore' + - '!.dockerignore' - '!.github/workflows/**' - '.github/workflows/unittests.yml' pull_request: paths: - '**' - '!docs/**' + - '!deploy/**' - '!setup.py' + - '!Dockerfile' - '!*.iss' - '!.gitignore' + - '!.dockerignore' - '!.github/workflows/**' - '.github/workflows/unittests.yml' From bae1259abad74369313632703e0b43c94cbac387 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 25 Jul 2025 07:06:22 +0000 Subject: [PATCH 0594/1218] CI: switch to new appimagetool (#5233) Since this does not have versions anymore, we check the sha256 and require manual intervention if it changed. TODO: look for a way to do reproducible appimages again. --- .github/workflows/build.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 07ae1136fc01..721d63b1dc9d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,12 @@ on: env: ENEMIZER_VERSION: 7.1 - APPIMAGETOOL_VERSION: 13 + # NOTE: since appimage/appimagetool and appimage/type2-runtime does not have tags anymore, + # we check the sha256 and require manual intervention if it was updated. + APPIMAGETOOL_VERSION: continuous + APPIMAGETOOL_X86_64_HASH: '363dafac070b65cc36ca024b74db1f043c6f5cd7be8fca760e190dce0d18d684' + APPIMAGE_RUNTIME_VERSION: continuous + APPIMAGE_RUNTIME_X86_64_HASH: 'e3c4dfb70eddf42e7e5a1d28dff396d30563aa9a901970aebe6f01f3fecf9f8e' permissions: # permissions required for attestation id-token: 'write' @@ -134,10 +139,13 @@ jobs: - name: Install build-time dependencies run: | echo "PYTHON=python3.12" >> $GITHUB_ENV - wget -nv https://github.com/AppImage/AppImageKit/releases/download/$APPIMAGETOOL_VERSION/appimagetool-x86_64.AppImage + wget -nv https://github.com/AppImage/appimagetool/releases/download/$APPIMAGETOOL_VERSION/appimagetool-x86_64.AppImage + echo "$APPIMAGETOOL_X86_64_HASH appimagetool-x86_64.AppImage" | sha256sum -c + wget -nv https://github.com/AppImage/type2-runtime/releases/download/$APPIMAGE_RUNTIME_VERSION/runtime-x86_64 + echo "$APPIMAGE_RUNTIME_X86_64_HASH runtime-x86_64" | sha256sum -c chmod a+rx appimagetool-x86_64.AppImage ./appimagetool-x86_64.AppImage --appimage-extract - echo -e '#/bin/sh\n./squashfs-root/AppRun "$@"' > appimagetool + echo -e '#/bin/sh\n./squashfs-root/AppRun --runtime-file runtime-x86_64 "$@"' > appimagetool chmod a+rx appimagetool - name: Download run-time dependencies run: | From 387f79ceae1b8fbf93a152700e3e0960a45a6102 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 25 Jul 2025 07:15:34 +0000 Subject: [PATCH 0595/1218] setup: Downgrade bundled SNI to 0.0.100 (#5228) --- setup.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index cd1b1e87107d..704325d70cbb 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,10 @@ from hashlib import sha3_512 from pathlib import Path + +SNI_VERSION = "v0.0.100" # change back to "latest" once tray icon issues are fixed + + # This is a bit jank. We need cx-Freeze to be able to run anything from this script, so install it requirement = 'cx-Freeze==8.0.0' try: @@ -89,7 +93,8 @@ def download_SNI() -> None: machine_name = platform.machine().lower() # force amd64 on macos until we have universal2 sni, otherwise resolve to GOARCH machine_name = "universal" if platform_name == "darwin" else machine_to_go.get(machine_name, machine_name) - with urllib.request.urlopen("https://api.github.com/repos/alttpo/sni/releases/latest") as request: + sni_version_ref = "latest" if SNI_VERSION == "latest" else f"tags/{SNI_VERSION}" + with urllib.request.urlopen(f"https://api.github.com/repos/alttpo/SNI/releases/{sni_version_ref}") as request: data = json.load(request) files = data["assets"] From e5815ae5a2eeca81aad7d8c862fb498fa8760341 Mon Sep 17 00:00:00 2001 From: Justus Lind Date: Sat, 26 Jul 2025 04:47:59 +1000 Subject: [PATCH 0596/1218] Muse Dash: Update to Rhythm Master Collab (#5235) * Rhythm Master Collab * Deprioritze Music Sheets. * Oops missed this definition. --- worlds/musedash/MuseDashData.py | 7 +++++++ worlds/musedash/__init__.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/worlds/musedash/MuseDashData.py b/worlds/musedash/MuseDashData.py index bcb4ab8e2a78..32849eec9b17 100644 --- a/worlds/musedash/MuseDashData.py +++ b/worlds/musedash/MuseDashData.py @@ -654,4 +654,11 @@ "#YamiKawa": SongData(2900778, "43-65", "MD Plus Project", False, 5, 7, 10), "Rainy Step": SongData(2900779, "43-66", "MD Plus Project", False, 2, 5, 8), "OHOSHIKATSU": SongData(2900780, "43-67", "MD Plus Project", False, 5, 7, 10), + "Dreamy Day": SongData(2900781, "87-0", "Aim to Be a Rhythm Master!", False, 2, 5, 7), + "Futropolis": SongData(2900782, "87-1", "Aim to Be a Rhythm Master!", False, 4, 7, 9), + "Quo Vadis": SongData(2900783, "87-2", "Aim to Be a Rhythm Master!", False, 5, 7, 10), + "REANIMATE": SongData(2900784, "87-3", "Aim to Be a Rhythm Master!", False, 5, 7, 10), + "Ineffabilis": SongData(2900785, "87-4", "Aim to Be a Rhythm Master!", False, 3, 7, 10), + "DaJiaHao": SongData(2900786, "87-5", "Aim to Be a Rhythm Master!", False, 5, 7, 10), + "Echoes of SeraphiM": SongData(2900787, "87-6", "Aim to Be a Rhythm Master!", False, 5, 8, 10), } diff --git a/worlds/musedash/__init__.py b/worlds/musedash/__init__.py index d793308a7c0e..87eb70175202 100644 --- a/worlds/musedash/__init__.py +++ b/worlds/musedash/__init__.py @@ -173,7 +173,7 @@ def create_song_pool(self, available_song_keys: List[str]): def create_item(self, name: str) -> Item: if name == self.md_collection.MUSIC_SHEET_NAME: - return MuseDashFixedItem(name, ItemClassification.progression_skip_balancing, + return MuseDashFixedItem(name, ItemClassification.progression_deprioritized_skip_balancing, self.md_collection.MUSIC_SHEET_CODE, self.player) filler = self.md_collection.filler_items.get(name) From 88e8e2408b3770b4f6e9d1b69f69d2fb1078202f Mon Sep 17 00:00:00 2001 From: BadMagic100 Date: Fri, 25 Jul 2025 11:55:22 -0700 Subject: [PATCH 0597/1218] GER: Move EntranceLookup onto ERPlacementState. Improve usefulness of on_connect. (#4904) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- entrance_rando.py | 82 +++++++++++++++++++++-------- test/general/test_entrance_rando.py | 78 +++++++++++++++++++++------ 2 files changed, 122 insertions(+), 38 deletions(-) diff --git a/entrance_rando.py b/entrance_rando.py index 5ed2cd764596..492fff32e32d 100644 --- a/entrance_rando.py +++ b/entrance_rando.py @@ -52,13 +52,15 @@ def remove(self, entrance: Entrance) -> None: _coupled: bool _usable_exits: set[Entrance] - def __init__(self, rng: random.Random, coupled: bool, usable_exits: set[Entrance]): + def __init__(self, rng: random.Random, coupled: bool, usable_exits: set[Entrance], targets: Iterable[Entrance]): self.dead_ends = EntranceLookup.GroupLookup() self.others = EntranceLookup.GroupLookup() self._random = rng self._expands_graph_cache = {} self._coupled = coupled self._usable_exits = usable_exits + for target in targets: + self.add(target) def _can_expand_graph(self, entrance: Entrance) -> bool: """ @@ -121,7 +123,14 @@ def get_targets( dead_end: bool, preserve_group_order: bool ) -> Iterable[Entrance]: + """ + Gets available targets for the requested groups + :param groups: The groups to find targets for + :param dead_end: Whether to find dead ends. If false, finds non-dead-ends + :param preserve_group_order: Whether to preserve the group order in the returned iterable. If true, a sequence + like AAABBB is guaranteed. If false, groups can be interleaved, e.g. BAABAB. + """ lookup = self.dead_ends if dead_end else self.others if preserve_group_order: for group in groups: @@ -132,6 +141,27 @@ def get_targets( self._random.shuffle(ret) return ret + def find_target(self, name: str, group: int | None = None, dead_end: bool | None = None) -> Entrance | None: + """ + Finds a specific target in the lookup, if it is present. + + :param name: The name of the target + :param group: The target's group. Providing this will make the lookup faster, but can be omitted if it is not + known ahead of time for some reason. + :param dead_end: Whether the target is a dead end. Providing this will make the lookup faster, but can be + omitted if this is not known ahead of time (much more likely) + """ + if dead_end is None: + return (found + if (found := self.find_target(name, group, True)) + else self.find_target(name, group, False)) + lookup = self.dead_ends if dead_end else self.others + targets_to_check = lookup if group is None else lookup[group] + for target in targets_to_check: + if target.name == name: + return target + return None + def __len__(self): return len(self.dead_ends) + len(self.others) @@ -146,15 +176,18 @@ class ERPlacementState: """The world which is having its entrances randomized""" collection_state: CollectionState """The CollectionState backing the entrance randomization logic""" + entrance_lookup: EntranceLookup + """A lookup table of all unconnected ER targets""" coupled: bool """Whether entrance randomization is operating in coupled mode""" - def __init__(self, world: World, coupled: bool): + def __init__(self, world: World, entrance_lookup: EntranceLookup, coupled: bool): self.placements = [] self.pairings = [] self.world = world self.coupled = coupled self.collection_state = world.multiworld.get_all_state(False, True) + self.entrance_lookup = entrance_lookup @property def placed_regions(self) -> set[Region]: @@ -182,6 +215,7 @@ def _connect_one_way(self, source_exit: Entrance, target_entrance: Entrance) -> self.collection_state.stale[self.world.player] = True self.placements.append(source_exit) self.pairings.append((source_exit.name, target_entrance.name)) + self.entrance_lookup.remove(target_entrance) def test_speculative_connection(self, source_exit: Entrance, target_entrance: Entrance, usable_exits: set[Entrance]) -> bool: @@ -311,7 +345,7 @@ def randomize_entrances( preserve_group_order: bool = False, er_targets: list[Entrance] | None = None, exits: list[Entrance] | None = None, - on_connect: Callable[[ERPlacementState, list[Entrance]], None] | None = None + on_connect: Callable[[ERPlacementState, list[Entrance], list[Entrance]], bool | None] | None = None ) -> ERPlacementState: """ Randomizes Entrances for a single world in the multiworld. @@ -328,14 +362,18 @@ def randomize_entrances( :param exits: The list of exits (Entrance objects with no target region) to use for randomization. Remember to be deterministic! If not provided, automatically discovers all valid exits in your world. :param on_connect: A callback function which allows specifying side effects after a placement is completed - successfully and the underlying collection state has been updated. + successfully and the underlying collection state has been updated. The arguments are + 1. The ER state + 2. The exits placed in this placement pass + 3. The entrances they were connected to. + If you use on_connect to make additional placements, you are expected to return True to inform + GER that an additional sweep is needed. """ if not world.explicit_indirect_conditions: raise EntranceRandomizationError("Entrance randomization requires explicit indirect conditions in order " + "to correctly analyze whether dead end regions can be required in logic.") start_time = time.perf_counter() - er_state = ERPlacementState(world, coupled) # similar to fill, skip validity checks on entrances if the game is beatable on minimal accessibility perform_validity_check = True @@ -351,23 +389,25 @@ def randomize_entrances( # used when membership checks are needed on the exit list, e.g. speculative sweep exits_set = set(exits) - entrance_lookup = EntranceLookup(world.random, coupled, exits_set) - for entrance in er_targets: - entrance_lookup.add(entrance) + er_state = ERPlacementState( + world, + EntranceLookup(world.random, coupled, exits_set, er_targets), + coupled + ) # place the menu region and connected start region(s) er_state.collection_state.update_reachable_regions(world.player) def do_placement(source_exit: Entrance, target_entrance: Entrance) -> None: - placed_exits, removed_entrances = er_state.connect(source_exit, target_entrance) - # remove the placed targets from consideration - for entrance in removed_entrances: - entrance_lookup.remove(entrance) + placed_exits, paired_entrances = er_state.connect(source_exit, target_entrance) # propagate new connections er_state.collection_state.update_reachable_regions(world.player) er_state.collection_state.sweep_for_advancements() if on_connect: - on_connect(er_state, placed_exits) + change = on_connect(er_state, placed_exits, paired_entrances) + if change: + er_state.collection_state.update_reachable_regions(world.player) + er_state.collection_state.sweep_for_advancements() def needs_speculative_sweep(dead_end: bool, require_new_exits: bool, placeable_exits: list[Entrance]) -> bool: # speculative sweep is expensive. We currently only do it as a last resort, if we might cap off the graph @@ -388,12 +428,12 @@ def needs_speculative_sweep(dead_end: bool, require_new_exits: bool, placeable_e # check to see if we are proposing the last placement if not coupled: # in uncoupled, this check is easy as there will only be one target. - is_last_placement = len(entrance_lookup) == 1 + is_last_placement = len(er_state.entrance_lookup) == 1 else: # a bit harder, there may be 1 or 2 targets depending on if the exit to place is one way or two way. # if it is two way, we can safely assume that one of the targets is the logical pair of the exit. desired_target_count = 2 if placeable_exits[0].randomization_type == EntranceType.TWO_WAY else 1 - is_last_placement = len(entrance_lookup) == desired_target_count + is_last_placement = len(er_state.entrance_lookup) == desired_target_count # if it's not the last placement, we need a sweep return not is_last_placement @@ -402,7 +442,7 @@ def find_pairing(dead_end: bool, require_new_exits: bool) -> bool: placeable_exits = er_state.find_placeable_exits(perform_validity_check, exits) for source_exit in placeable_exits: target_groups = target_group_lookup[source_exit.randomization_group] - for target_entrance in entrance_lookup.get_targets(target_groups, dead_end, preserve_group_order): + for target_entrance in er_state.entrance_lookup.get_targets(target_groups, dead_end, preserve_group_order): # when requiring new exits, ideally we would like to make it so that every placement increases # (or keeps the same number of) reachable exits. The goal is to continue to expand the search space # so that we do not crash. In the interest of performance and bias reduction, generally, just checking @@ -420,7 +460,7 @@ def find_pairing(dead_end: bool, require_new_exits: bool) -> bool: else: # no source exits had any valid target so this stage is deadlocked. retries may be implemented if early # deadlocking is a frequent issue. - lookup = entrance_lookup.dead_ends if dead_end else entrance_lookup.others + lookup = er_state.entrance_lookup.dead_ends if dead_end else er_state.entrance_lookup.others # if we're in a stage where we're trying to get to new regions, we could also enter this # branch in a success state (when all regions of the preferred type have been placed, but there are still @@ -466,21 +506,21 @@ def find_pairing(dead_end: bool, require_new_exits: bool) -> bool: f"All unplaced exits: {unplaced_exits}") # stage 1 - try to place all the non-dead-end entrances - while entrance_lookup.others: + while er_state.entrance_lookup.others: if not find_pairing(dead_end=False, require_new_exits=True): break # stage 2 - try to place all the dead-end entrances - while entrance_lookup.dead_ends: + while er_state.entrance_lookup.dead_ends: if not find_pairing(dead_end=True, require_new_exits=True): break # stage 3 - all the regions should be placed at this point. We now need to connect dangling edges # stage 3a - get the rest of the dead ends (e.g. second entrances into already-visited regions) # doing this before the non-dead-ends is important to ensure there are enough connections to # go around - while entrance_lookup.dead_ends: + while er_state.entrance_lookup.dead_ends: find_pairing(dead_end=True, require_new_exits=False) # stage 3b - tie all the other loose ends connecting visited regions to each other - while entrance_lookup.others: + while er_state.entrance_lookup.others: find_pairing(dead_end=False, require_new_exits=False) running_time = time.perf_counter() - start_time diff --git a/test/general/test_entrance_rando.py b/test/general/test_entrance_rando.py index 65853dfc8b8e..8a697030e813 100644 --- a/test/general/test_entrance_rando.py +++ b/test/general/test_entrance_rando.py @@ -69,11 +69,9 @@ def test_shuffled_targets(self): exits_set = set([ex for region in multiworld.get_regions(1) for ex in region.exits if not ex.connected_region]) - lookup = EntranceLookup(multiworld.worlds[1].random, coupled=True, usable_exits=exits_set) er_targets = [entrance for region in multiworld.get_regions(1) for entrance in region.entrances if not entrance.parent_region] - for entrance in er_targets: - lookup.add(entrance) + lookup = EntranceLookup(multiworld.worlds[1].random, coupled=True, usable_exits=exits_set, targets=er_targets) retrieved_targets = lookup.get_targets([ERTestGroups.TOP, ERTestGroups.BOTTOM], False, False) @@ -92,11 +90,9 @@ def test_ordered_targets(self): exits_set = set([ex for region in multiworld.get_regions(1) for ex in region.exits if not ex.connected_region]) - lookup = EntranceLookup(multiworld.worlds[1].random, coupled=True, usable_exits=exits_set) er_targets = [entrance for region in multiworld.get_regions(1) for entrance in region.entrances if not entrance.parent_region] - for entrance in er_targets: - lookup.add(entrance) + lookup = EntranceLookup(multiworld.worlds[1].random, coupled=True, usable_exits=exits_set, targets=er_targets) retrieved_targets = lookup.get_targets([ERTestGroups.TOP, ERTestGroups.BOTTOM], False, True) @@ -112,12 +108,10 @@ def test_selective_dead_ends(self): for ex in region.exits if not ex.connected_region and ex.name != "region20_right" and ex.name != "region21_left"]) - lookup = EntranceLookup(multiworld.worlds[1].random, coupled=True, usable_exits=exits_set) er_targets = [entrance for region in multiworld.get_regions(1) for entrance in region.entrances if not entrance.parent_region and entrance.name != "region20_right" and entrance.name != "region21_left"] - for entrance in er_targets: - lookup.add(entrance) + lookup = EntranceLookup(multiworld.worlds[1].random, coupled=True, usable_exits=exits_set, targets=er_targets) # region 20 is the bottom left corner of the grid, and therefore only has a right entrance from region 21 # and a top entrance from region 15; since we've told lookup to ignore the right entrance from region 21, # the top entrance from region 15 should be considered a dead-end @@ -129,6 +123,56 @@ def test_selective_dead_ends(self): self.assertTrue(dead_end in lookup.dead_ends) self.assertEqual(len(lookup.dead_ends), 1) + def test_find_target_by_name(self): + """Tests that find_target can find the correct target by name only""" + multiworld = generate_test_multiworld() + generate_disconnected_region_grid(multiworld, 5) + exits_set = set([ex for region in multiworld.get_regions(1) + for ex in region.exits if not ex.connected_region]) + + er_targets = [entrance for region in multiworld.get_regions(1) + for entrance in region.entrances if not entrance.parent_region] + lookup = EntranceLookup(multiworld.worlds[1].random, coupled=True, usable_exits=exits_set, targets=er_targets) + + target = lookup.find_target("region0_right") + self.assertEqual(target.name, "region0_right") + self.assertEqual(target.randomization_group, ERTestGroups.RIGHT) + self.assertIsNone(lookup.find_target("nonexistant")) + + def test_find_target_by_name_and_group(self): + """Tests that find_target can find the correct target by name and group""" + multiworld = generate_test_multiworld() + generate_disconnected_region_grid(multiworld, 5) + exits_set = set([ex for region in multiworld.get_regions(1) + for ex in region.exits if not ex.connected_region]) + + er_targets = [entrance for region in multiworld.get_regions(1) + for entrance in region.entrances if not entrance.parent_region] + lookup = EntranceLookup(multiworld.worlds[1].random, coupled=True, usable_exits=exits_set, targets=er_targets) + + target = lookup.find_target("region0_right", ERTestGroups.RIGHT) + self.assertEqual(target.name, "region0_right") + self.assertEqual(target.randomization_group, ERTestGroups.RIGHT) + # wrong group + self.assertIsNone(lookup.find_target("region0_right", ERTestGroups.LEFT)) + + def test_find_target_by_name_and_group_and_category(self): + """Tests that find_target can find the correct target by name, group, and dead-endedness""" + multiworld = generate_test_multiworld() + generate_disconnected_region_grid(multiworld, 5) + exits_set = set([ex for region in multiworld.get_regions(1) + for ex in region.exits if not ex.connected_region]) + + er_targets = [entrance for region in multiworld.get_regions(1) + for entrance in region.entrances if not entrance.parent_region] + lookup = EntranceLookup(multiworld.worlds[1].random, coupled=True, usable_exits=exits_set, targets=er_targets) + + target = lookup.find_target("region0_right", ERTestGroups.RIGHT, False) + self.assertEqual(target.name, "region0_right") + self.assertEqual(target.randomization_group, ERTestGroups.RIGHT) + # wrong deadendedness + self.assertIsNone(lookup.find_target("region0_right", ERTestGroups.RIGHT, True)) + class TestBakeTargetGroupLookup(unittest.TestCase): def test_lookup_generation(self): multiworld = generate_test_multiworld() @@ -265,12 +309,12 @@ def test_coupled(self): generate_disconnected_region_grid(multiworld, 5) seen_placement_count = 0 - def verify_coupled(_: ERPlacementState, placed_entrances: list[Entrance]): + def verify_coupled(_: ERPlacementState, placed_exits: list[Entrance], placed_targets: list[Entrance]): nonlocal seen_placement_count - seen_placement_count += len(placed_entrances) - self.assertEqual(2, len(placed_entrances)) - self.assertEqual(placed_entrances[0].parent_region, placed_entrances[1].connected_region) - self.assertEqual(placed_entrances[1].parent_region, placed_entrances[0].connected_region) + seen_placement_count += len(placed_exits) + self.assertEqual(2, len(placed_exits)) + self.assertEqual(placed_exits[0].parent_region, placed_exits[1].connected_region) + self.assertEqual(placed_exits[1].parent_region, placed_exits[0].connected_region) result = randomize_entrances(multiworld.worlds[1], True, directionally_matched_group_lookup, on_connect=verify_coupled) @@ -313,10 +357,10 @@ def test_uncoupled(self): generate_disconnected_region_grid(multiworld, 5) seen_placement_count = 0 - def verify_uncoupled(state: ERPlacementState, placed_entrances: list[Entrance]): + def verify_uncoupled(state: ERPlacementState, placed_exits: list[Entrance], placed_targets: list[Entrance]): nonlocal seen_placement_count - seen_placement_count += len(placed_entrances) - self.assertEqual(1, len(placed_entrances)) + seen_placement_count += len(placed_exits) + self.assertEqual(1, len(placed_exits)) result = randomize_entrances(multiworld.worlds[1], False, directionally_matched_group_lookup, on_connect=verify_uncoupled) From ea4c4dcc0c431067ac11a000c54f55692ee04188 Mon Sep 17 00:00:00 2001 From: mobby45 <68152858+mobby45@users.noreply.github.com> Date: Fri, 25 Jul 2025 21:08:51 +0200 Subject: [PATCH 0598/1218] The Wind Waker: Adding French Translation for Guides (#5174) * Add files via upload * Delete fr_The Wind Waker.md * Delete setup_fr.md * Add files via upload * Update fr_The Wind Waker.md * Update fr_The Wind Waker.md * Update fr_The Wind Waker.md * Update worlds/tww/docs/fr_The Wind Waker.md I agree with that okat! Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md Agreed Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md agreed! Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md agreed! Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md agreed! Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md forgot to remove that, ok Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md agreed! Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md Okay! Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md Agreed Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md agreed Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md agreed Co-authored-by: Jonathan Tan * Update fr_The Wind Waker.md * Update worlds/tww/docs/fr_The Wind Waker.md okay! Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/setup_fr.md Co-authored-by: Jonathan Tan * Update setup_fr.md * Update setup_fr.md * Update fr_The Wind Waker.md Modifying lines * Update setup_fr.md Character Limits Update * Update worlds/tww/docs/setup_fr.md ok Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md Co-authored-by: Jonathan Tan * Update worlds/tww/docs/fr_The Wind Waker.md Co-authored-by: Jonathan Tan * Update en_The Wind Waker.md * Update worlds/tww/docs/setup_fr.md Co-authored-by: Jonathan Tan * Update __init__.py * Update __init__.py * Update worlds/tww/__init__.py Co-authored-by: Jonathan Tan * Update __init__.py --------- Co-authored-by: Jonathan Tan --- worlds/tww/__init__.py | 8 ++ worlds/tww/docs/en_The Wind Waker.md | 1 + worlds/tww/docs/fr_The Wind Waker.md | 142 +++++++++++++++++++++++++++ worlds/tww/docs/setup_fr.md | 95 ++++++++++++++++++ 4 files changed, 246 insertions(+) create mode 100644 worlds/tww/docs/fr_The Wind Waker.md create mode 100644 worlds/tww/docs/setup_fr.md diff --git a/worlds/tww/__init__.py b/worlds/tww/__init__.py index 5432d200ae3f..58e752b5c9ad 100644 --- a/worlds/tww/__init__.py +++ b/worlds/tww/__init__.py @@ -91,6 +91,14 @@ class TWWWeb(WebWorld): "setup_en.md", "setup/en", ["tanjo3", "Lunix"], + ), + Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Archipelago The Wind Waker software on your computer.", + "Français", + "setup_fr.md", + "setup/fr", + ["mobby45"] ) ] theme = "ocean" diff --git a/worlds/tww/docs/en_The Wind Waker.md b/worlds/tww/docs/en_The Wind Waker.md index a49c8d6697ae..77669ce7dd7e 100644 --- a/worlds/tww/docs/en_The Wind Waker.md +++ b/worlds/tww/docs/en_The Wind Waker.md @@ -116,6 +116,7 @@ This randomizer would not be possible without the help from: - Gamma / SageOfMirrors: (additional programming) - LagoLunatic: (base randomizer, additional assistance) - Lunix: (Linux support, additional programming) +- mobby45: (French Translation of Guides) - Mysteryem: (tracker support, additional programming) - Necrofitz: (additional documentation) - Ouro: (tracker support) diff --git a/worlds/tww/docs/fr_The Wind Waker.md b/worlds/tww/docs/fr_The Wind Waker.md new file mode 100644 index 000000000000..2c89ae53fe1f --- /dev/null +++ b/worlds/tww/docs/fr_The Wind Waker.md @@ -0,0 +1,142 @@ +# The Wind Waker + +## Où est la page d'options ? + +La [page d'option pour ce jeu](../player-options) contient toutes les options que vous avez besoin de configurer et +exporter afin d'obtenir un fichier de configuration. + +## Que fait la randomisation à ce jeu ? + +Les objets sont mélangés entre les différentes localisations du jeu, donc chaque expérience est unique. +Les localisations randomisés incluent les coffres, les objets reçu des PNJ, ainsi que les trésors submergés sous l'eau. +Le randomiseur inclue également des qualités de vie tel qu'un monde entièrement ouvert, +des cinématiques retirées ainsi qu'une vitesse de navigation améliorée, et plus. + +## Quelles localisations sont mélangés ? + +Seulement les localisations mises en logiques dans les paramètres du monde seront randomisés. +Les localisations restantes dans le jeu auront un rubis jaune. +Celles-ci incluant un message indiquant que la localisation n'est pas randomisé. + +## Quel est l'objectif de The Wind Waker ? + +Atteindre et battre Ganondorf en haut de la tour de Ganon. +Pour cela, vous aurez besoin des huit morceaux de la Triforce du Courage, l'Excalibur entièrerement ranimée (sauf si ce +sont des épées optionnelles ou en mode sans épée), les flèches de lumières, ainsi que tous les objets nécessaires pour +atteindre Ganondorf. + +## A quoi ressemble un objet venant d'un autre monde dans TWW ? + +Les objets appartenant aux autres mondes qui ne sont pas TWW sont représentés +par la Lettre de Père (la lettre que Médolie vous donne pour la donner à Komali), +un objet inutilisé dans le randomiseur. + +## Que se passe-t-il quand un joueur reçoit un objet ? + +Quand le joueur reçoit n'importe quel objet, il sera automatiquement ajouté à l'inventaire de Link. +Link **ne tiendra pas** l'objet au dessus de sa tête comme dans d'autres randomizer de Zelda. + +## J'ai besoin d'aide ! Que dois-je faire ? + +Référez vous à la [FAQ](https://lagolunatic.github.io/wwrando/faq/) premièrement. Ensuite, +essayez les étapes de résolutions de problèmes dans le [guide de mise en place](/tutorial/The%20Wind%20Waker/setup/en). +Si vous êtes encore bloqué, s'il vous plait poser votre question dans le salon textuel Wind Waker +dans le serveur discord d'Archipelago. + +## J'ai ouvert mon jeu dans Dolphin, mais je n'ai aucun de mes items de démarrage ! + +Vous devez vous connecter à la salle du multiworld pour recevoir vos objets. Cela inclut votre inventaire de départ. + +## Problèmes Connus + +- Les rubis randomisés freestanding, butins, et appâts seront aussi données au joueur qui récupère l'objet. + L'objet sera bien envoyé mais le joueur qui le collecte recevra une copie supplémentaire. +- Les objets que tiens Link au dessus de sa tête **ne sont pas** randomisés, + comme les rubis allant des trésors venant des cercles lumineux + jusqu'aux récompenses venant des mini-jeux, ne fonctionneront pas. +- Un objet qui reçoit des messages pour des objets progressifs reçu à des localisations + qui s'envoient plus tôt que prévu seront incorrect. Cela n'affecte pas le gameplay. +- Le compteur de quart de cœur dans les messages lorsqu'on reçoit un objet seront faux d'un. + Cela n'affecte pas le gameplay. +- Il a été signalé que l'itemlink peut être buggé. + Ça ne casse en rien le jeu, mais soyez en conscient. + +N'hésitez pas à signaler n'importe quel autre problème ou suggestion d'amélioration dans le salon textuel Wind Waker +dans le serveur discord d'Archipelago ! + +## Astuces et conseils + +### Où sont les secrets de donjons trouvés à trouver dans les donjons ? + +[Ce document](https://docs.google.com/document/d/1LrjGr6W9970XEA-pzl8OhwnqMqTbQaxCX--M-kdsLos/edit?usp=sharing) +contient des images montrant les différents secrets des donjons. + +### Que font exactement les options obscures et de précisions des options de difficultés ? + +Les options `logic_obscurity` et `logic_precision` modifient la logique du randomizer +pour mettre différentes astuces et techniques en logique. +[Ce document](https://docs.google.com/spreadsheets/d/14ToE1SvNr9yRRqU4GK2qxIsuDUs9Edegik3wUbLtzH8/edit?usp=sharing) +liste parfaitement les changements qui sont fait. Les options sont progressives donc par exemple, +la difficulté obscure dur inclue les astuces normales et durs. +Certains changements ont besoin de la combinaison des deux options. +Par exemple, pour mettre les canons qui détruisent la porte de la Forteresse Maudite pour vous en logique, +les paramètres obscure et précision doivent tout les deux être mis au moins à normal. + +### Quels sont les différents préréglages d'options ? + +Quelques préréglages (presets) sont disponibles sur la [page d'options](../player-options) pour votre confort. + +- **Tournoi Saison 8**: Ce sont (aussi proche que possible) les paramètres utilisés dans le [Tournoi + Saison 8](https://docs.google.com/document/d/1b8F5DL3P5fgsQC_URiwhpMfqTpsGh2M-KmtTdXVigh4) du serveur WWR Racing. + Ce préréglage contient 4 boss requis (avec le Roi Cuirassé garanti d'être requis), + entrée des donjons randomisées, difficulté obscure dur, et une variété de checks dans l'overworld, + même si la liste d'options progressive peut sembler intimidante. + Ce préréglage exclut également plusieurs localisations et vous fait commencez avec plusieurs objets. +- **Miniblins 2025**: Ce sont (aussi proche que possible) les paramètres utilisés dans la + [Saison 2025 de Miniblins](https://docs.google.com/document/d/19vT68eU6PepD2BD2ZjR9ikElfqs8pXfqQucZ-TcscV8) + du serveur WWR Racing. Ce préréglage est bien si vous êtes nouveau à The Wind Waker ! + Il n'y a pas beaucoup de localisation dans ce monde, et tu as seulement besoin de compléter deux donjons. + Tu commences aussi avec plusieurs objets utiles comme la double magie, + une amélioration de capacité pour votre arc et vos bombes ainsi que six coeurs. +- **Mixed Pools**: Ce sont (aussi proche que possible) les paramètres utilisés dans le + [Tournoi Mixed Pools Co-op](https://docs.google.com/document/d/1YGPTtEgP978TIi0PUAD792OtZbE2jBQpI8XCAy63qpg) + du serveur WWR Racing. + Ce préréglage contient toutes les entrées randomisés et inclue la plupart des localisations + derrière une entrée randomisé. Il y a aussi plusieurs locations de l'overworld, + étant donnée que ces paramètres sont censés être joué dans une équipe de deux joueurs. + Ce préréglage a aussi six boss requis, mais vu que les pools d'entrées sont randomisés, + les boss peuvent être trouvés n'importe où ! Regarder votre carte de l'océan pour + déterminer quels îles les boss sont. + +## Fonctionnalités planifiées + +- Type des coffres Dynamique assorties au contenu en fonction des options activés +- Implémentation des indices venant du randomiseur de base (options de placement des indices et des types d'indices) +- Intégration avec le système d'indice d'Archipelago (ex: indices des enchères) +- Support de l'EnergyLink +- Logique de la voile rapide en tant qu'option +- Continuer la correction de bug + +## Crédits + +Ce randomiseur ne pouvait pas être possible sans l'aide de : + +- BigSharkZ: (Dessinateur de l'îcone) +- Celeste (Maëlle): (correction de logique et de fautes d'orthographe, programmation additionnelle) +- Chavu: (document sur les difficultés de logique) +- CrainWWR: (multiworld et assitance sur la mémoire de Dolphin, programmation additionnelle) +- Cyb3R: (référence pour `TWWClient`) +- DeamonHunter: (programmation additionnelle) +- Dev5ter: (Implémentation initiale de l'AP de TWW) +- Gamma / SageOfMirrors: (programmation additionnelle) +- LagoLunatic: (randomiseur de base, assistance additionelle) +- Lunix: (Support Linux, programmation additionnelle) +- mobby45 (Traduction du guide français) +- Mysteryem: (Support du tracker, programmation additionnelle) +- Necrofitz: (documentation additionelle) +- Ouro: (Support du tracker) +- tal (matzahTalSoup): (guide pour les dungeon secrets) +- Tubamann: (programmation additionnelle) + +Le logo archipelago © 2022 par Krista Corkos et Christopher Wilson, sous licence +[CC BY-NC 4.0](http://creativecommons.org/licenses/by-nc/4.0/). diff --git a/worlds/tww/docs/setup_fr.md b/worlds/tww/docs/setup_fr.md new file mode 100644 index 000000000000..8457c8ef5bf5 --- /dev/null +++ b/worlds/tww/docs/setup_fr.md @@ -0,0 +1,95 @@ +# Guide de mise en place de l'Archipelago de The Wind Waker + +Bienvenue dans l'Archipelago The Wind Waker ! +Ce guide vous aidera à mettre en place le randomiser et à jouer à votre premier multiworld. +Si vous jouez à The Wind Waker, vous devez suivre quelques étapes simple pour commencer. + +## Requis + +Vous aurez besoin des choses suivantes pour être capable de jouer à The Wind Waker: +* L'[émulateur Dolphin](https://dolphin-emu.org/download/). **Nous recommendons d'utiliser la dernière version + sortie.** + * Les utilisateurs Linux peuvent utiliser le paquet flatpak + [disponible sur Flathub](https://flathub.org/apps/org.DolphinEmu.dolphin-emu). +* La dernière version du [Randomiser The Wind Waker pour + Archipelago](https://github.com/tanjo3/wwrando/releases?q=tag%3Aap_2). + * Veuillez noter que cette version est **différente** de celui utilisé pour le randomiser standard. Cette version + est spécifique à Archipelago. +* Une ISO du jeu Zelda The Wind Waker (version Nord Américaine), probablement nommé "Legend of Zelda, The - The Wind + Waker (USA).iso". + +De manière optionnelle, vous pouvez également télécharger: +* Le [tracker pour Wind Waker](https://github.com/Mysteryem/ww-poptracker/releases/latest) avec + [PopTracker](https://github.com/black-sliver/PopTracker/releases), qui en est la dépendance. +* Des [modèles de personnages personnalisés pour Wind + Waker](https://github.com/Sage-of-Mirrors/Custom-Wind-Waker-Player-Models) afin de personnaliser votre personnage en + jeu. + + +## Mise en place d'un YAML + +Tous les joueurs jouant à The Wind Waker doivent donner un YAML comportant les paramètres de leur monde +à l'hôte de la salle. +Vous pouvez aller sur la [page d'options The Wind Waker](/games/The%20Wind%20Waker/player-options) +pour générer un YAML avec vos options désirés. +Seulement les localisations catégorisées sous les options activés +sous "Progression Locations" seront randomisés dans votre monde. +Une fois que vous êtes heureux avec vos paramètres, +donnez votre fichier YAML à l'hôte de la salle et procéder à la prochaine étape. + +## Connexion à une salle + +L'hôte du multiworld vous donnera un lien pour télécharger votre fichier APTWW +ou un zip contenant les fichiers de tout le monde. +Le fichier APTWW doit être nommé `P#__XXXXX.aptww`, où `#` est l'identifiant du joueur, +`` est votre nom de joueur, et `XXXXX` est l'identifiant de la salle. +L'hôte doit également vous donner le nom de la salle du serveur avec le numéro de port. + +Une fois que vous êtes prêt, suivez ces étapes pour vous connecter à la salle: +1. Lancer le build AP du Randomiser. Si c'est la première fois que vous ouvrez le randomiser, + vous aurez besoin d'indiquer le chemin vers votre ISO de The Wind Waker et le dossier de sortie pour l'ISO randomisé. + Ceux-ci seront sauvegardé pour la prochaine fois que vous ouvrez le programme. +2. Modifier n'importe quel cosmétique comme vous le voulez avec les ajustements désirés + ainsi que la personnalisation de votre personnage desiré. +3. Pour le fichier APTWW, naviguer et localiser le chemin du fichier. +4. Appuyer sur `Randomize` en bas à droite. + Cela va randomiser et mettre l'ISO dans le dossier de sortie que vous avez renseigné. + Le fichier sera nommé `TWW AP_YYYYY_P# ().iso`, où `YYYYY` est le numéro de votre seed, + `#` est l'identifiant de votre joueur, et `` est le nom de votre joueur (nom de slot). + Veuillez vérifier que ces valeurs sont correctes pour votre multiworld. +5. Ouvrez Dolphin et utilisez le pour ouvrir l'iso randomisé. +6. Lancer `ArchipelagoLauncher.exe` (sans le `.exe` sur Linux) et choisissez `The Wind Waker Client`, + Cela va lancer le client texte. +7. Si Dolphin n'est pas encore ouvert, ou que vous n'avez pas encore commencé de nouveau fichier, + vous serez demandé à le faire. + * Une fois que vous avez ouvert votre ISO dans Dolphin, le client doit dire "Dolphin connected successfully.". +8. Connectez-vous à la salle entrant le nom du serveur et son numéro de port en haut et cliquer sur `Connect`. + Pour ceux qui hébergent sur le site web, cela sera `archipelago.gg:`, où `` est le numéro de port. + Si un jeu est hébergé à partir de `ArchipelagoServer.exe` (sans le `.exe` sur Linux), + le numéro de port par défaut est `38281` mais il peut être changé dans le `host.yaml`. +9. Si tu as ouvert ton ISO correspondant au multiworld auquel tu es connecté, + ça doit authentifier ton nom de slot automatiquement quand tu commences une nouveau fichier de sauvegarde. + +## Résolutions de problèmes +* Vérifier que vous utilisez la même version d'Archipelago que celui qui a généré le multiworld. +* Vérifier que `tww.apworld` n'est pas dans votre dossier d'installation Archipelago dans le dossier `custom_worlds`. +* Vérifier que vous utiliser la bonne version du build du randomiser que vous utilisez pour la version d'Archipelago. + * Le build doit donner un message d'erreur vous dirigeant vers la bonne version. + Vous pouvez aussi consulter les notes de version des builds AP de TWW + [ici](https://github.com/tanjo3/wwrando/releases?q=tag%3Aap_2), + afin de voir avec quelles versions d'Archipelago chaque build est compatible avec. +* Ne pas lancer le Launcher d'Archipelago ou Dolphin en tant qu'Administrateur sur Windows. +* Si vous rencontrez des problèmes avec l'authentification, + vérifier que la ROM randomisé est ouverte dans Dolphin et correspond au multiworld auquel vous vous connectez. +* Vérifier que vous n'utilisez aucune triche Dolphin ou que des codes de triches sont activés. + Certains codes peut interférer de manière imprévue avec l'émulation et + rendre la résolution des problèmes compliquées. +* Vérifier que `Modifier la taille de la mémoire émulée` dans Dolphin + (situé sous `Options` > `Configuration` > `Avancé`) est **désactivé**. +* Si le client ne peut pas se connecter à Dolphin, Vérifier que Dolphin est situé sur le même disque qu'Archipelago. + D'après certaines informations, avoir Dolphin sur un disque dur externe cause des problèmes de connexion. +* Vérifier que la `Région de remplacement` dans Dolphin (situé sous `Options` > `Configuration` > `Général`) + est mise à `NTSC-U`. +* Si vous lancez un menu de démarrage de Gamecube personnalisé, + vous aurez besoin de le passer en allant dans `Options` > `Configuration` > `GameCube` + et cocher `Passer le Menu Principal`. From 8499c2fd248428dcb8e30ab524e5d1c4b3f57565 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Fri, 25 Jul 2025 15:10:31 -0400 Subject: [PATCH 0599/1218] Options: Add PlandoItems to Item&Loc Option Group (#5201) --- Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Options.py b/Options.py index e87280ca14e8..c948e7e95f1b 100644 --- a/Options.py +++ b/Options.py @@ -1644,7 +1644,7 @@ class OptionGroup(typing.NamedTuple): item_and_loc_options = [LocalItems, NonLocalItems, StartInventory, StartInventoryPool, StartHints, - StartLocationHints, ExcludeLocations, PriorityLocations, ItemLinks] + StartLocationHints, ExcludeLocations, PriorityLocations, ItemLinks, PlandoItems] """ Options that are always populated in "Item & Location Options" Option Group. Cannot be moved to another group. If desired, a custom "Item & Location Options" Option Group can be defined, but only for adding additional options to From f66d8e9a61806b888d1c02f616669101c636bd7c Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Fri, 25 Jul 2025 17:23:39 -0600 Subject: [PATCH 0600/1218] WebHost: Update some typing in WebHostLib (#5069) --- WebHostLib/autolauncher.py | 3 --- WebHostLib/check.py | 12 ++++++------ WebHostLib/generate.py | 14 +++++++------- WebHostLib/stats.py | 15 ++++++--------- 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/WebHostLib/autolauncher.py b/WebHostLib/autolauncher.py index b3301462776a..719963e37508 100644 --- a/WebHostLib/autolauncher.py +++ b/WebHostLib/autolauncher.py @@ -164,9 +164,6 @@ def keep_running(): Thread(target=keep_running, name="AP_Autogen").start() -multiworlds: typing.Dict[type(Room.id), MultiworldInstance] = {} - - class MultiworldInstance(): def __init__(self, config: dict, id: int): self.room_ids = set() diff --git a/WebHostLib/check.py b/WebHostLib/check.py index 4e0cf1178f4b..b8e1fd875519 100644 --- a/WebHostLib/check.py +++ b/WebHostLib/check.py @@ -1,7 +1,7 @@ import os import zipfile import base64 -from typing import Union, Dict, Set, Tuple +from collections.abc import Set from flask import request, flash, redirect, url_for, render_template from markupsafe import Markup @@ -43,7 +43,7 @@ def mysterycheck(): return redirect(url_for("check"), 301) -def get_yaml_data(files) -> Union[Dict[str, str], str, Markup]: +def get_yaml_data(files) -> dict[str, str] | str | Markup: options = {} for uploaded_file in files: if banned_file(uploaded_file.filename): @@ -84,12 +84,12 @@ def get_yaml_data(files) -> Union[Dict[str, str], str, Markup]: return options -def roll_options(options: Dict[str, Union[dict, str]], +def roll_options(options: dict[str, dict | str], plando_options: Set[str] = frozenset({"bosses", "items", "connections", "texts"})) -> \ - Tuple[Dict[str, Union[str, bool]], Dict[str, dict]]: + tuple[dict[str, str | bool], dict[str, dict]]: plando_options = PlandoOptions.from_set(set(plando_options)) - results = {} - rolled_results = {} + results: dict[str, str | bool] = {} + rolled_results: dict[str, dict] = {} for filename, text in options.items(): try: if type(text) is dict: diff --git a/WebHostLib/generate.py b/WebHostLib/generate.py index 34033a085488..a84b17a88460 100644 --- a/WebHostLib/generate.py +++ b/WebHostLib/generate.py @@ -6,7 +6,7 @@ import tempfile import zipfile from collections import Counter -from typing import Any, Dict, List, Optional, Union, Set +from typing import Any from flask import flash, redirect, render_template, request, session, url_for from pony.orm import commit, db_session @@ -23,8 +23,8 @@ from .upload import upload_zip_to_db -def get_meta(options_source: dict, race: bool = False) -> Dict[str, Union[List[str], Dict[str, Any]]]: - plando_options: Set[str] = set() +def get_meta(options_source: dict, race: bool = False) -> dict[str, list[str] | dict[str, Any]]: + plando_options: set[str] = set() for substr in ("bosses", "items", "connections", "texts"): if options_source.get(f"plando_{substr}", substr in GeneratorOptions.plando_options): plando_options.add(substr) @@ -73,7 +73,7 @@ def generate(race=False): return render_template("generate.html", race=race, version=__version__) -def start_generation(options: Dict[str, Union[dict, str]], meta: Dict[str, Any]): +def start_generation(options: dict[str, dict | str], meta: dict[str, Any]): results, gen_options = roll_options(options, set(meta["plando_options"])) if any(type(result) == str for result in results.values()): @@ -104,9 +104,9 @@ def start_generation(options: Dict[str, Union[dict, str]], meta: Dict[str, Any]) return redirect(url_for("view_seed", seed=seed_id)) -def gen_game(gen_options: dict, meta: Optional[Dict[str, Any]] = None, owner=None, sid=None): - if not meta: - meta: Dict[str, Any] = {} +def gen_game(gen_options: dict, meta: dict[str, Any] | None = None, owner=None, sid=None): + if meta is None: + meta = {} meta.setdefault("server_options", {}).setdefault("hint_cost", 10) race = meta.setdefault("generator_options", {}).setdefault("race", False) diff --git a/WebHostLib/stats.py b/WebHostLib/stats.py index 36545ac96f1f..6fd73caf6cb5 100644 --- a/WebHostLib/stats.py +++ b/WebHostLib/stats.py @@ -1,4 +1,3 @@ -import typing from collections import Counter, defaultdict from colorsys import hsv_to_rgb from datetime import datetime, timedelta, date @@ -18,10 +17,9 @@ PLOT_WIDTH = 600 -def get_db_data(known_games: typing.Set[str]) -> typing.Tuple[typing.Counter[str], - typing.DefaultDict[datetime.date, typing.Dict[str, int]]]: - games_played = defaultdict(Counter) - total_games = Counter() +def get_db_data(known_games: set[str]) -> tuple[Counter[str], defaultdict[date, dict[str, int]]]: + games_played: defaultdict[date, dict[str, int]] = defaultdict(Counter) + total_games: Counter[str] = Counter() cutoff = date.today() - timedelta(days=30) room: Room for room in select(room for room in Room if room.creation_time >= cutoff): @@ -32,7 +30,7 @@ def get_db_data(known_games: typing.Set[str]) -> typing.Tuple[typing.Counter[str return total_games, games_played -def get_color_palette(colors_needed: int) -> typing.List[RGB]: +def get_color_palette(colors_needed: int) -> list[RGB]: colors = [] # colors_needed +1 to prevent first and last color being too close to each other colors_needed += 1 @@ -47,8 +45,7 @@ def get_color_palette(colors_needed: int) -> typing.List[RGB]: return colors -def create_game_played_figure(all_games_data: typing.Dict[datetime.date, typing.Dict[str, int]], - game: str, color: RGB) -> figure: +def create_game_played_figure(all_games_data: dict[date, dict[str, int]], game: str, color: RGB) -> figure: occurences = [] days = [day for day, game_data in all_games_data.items() if game_data[game]] for day in days: @@ -84,7 +81,7 @@ def stats(): days = sorted(games_played) color_palette = get_color_palette(len(total_games)) - game_to_color: typing.Dict[str, RGB] = {game: color for game, color in zip(total_games, color_palette)} + game_to_color: dict[str, RGB] = {game: color for game, color in zip(total_games, color_palette)} for game in sorted(total_games): occurences = [] From 23f0b720de2337af5114446ee3bc93b03bd9c649 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 25 Jul 2025 21:18:36 -0500 Subject: [PATCH 0601/1218] CommonClient: update commands to function without local apworld (#3045) --- CommonClient.py | 154 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 125 insertions(+), 29 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index 454150acbf8b..bd7113cb6f75 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -21,7 +21,7 @@ if __name__ == "__main__": Utils.init_logging("TextClient", exception_logger="Client") -from MultiServer import CommandProcessor +from MultiServer import CommandProcessor, mark_raw from NetUtils import (Endpoint, decode, NetworkItem, encode, JSONtoTextParser, ClientStatus, Permission, NetworkSlot, RawJSONtoTextParser, add_json_text, add_json_location, add_json_item, JSONTypes, HintStatus, SlotType) from Utils import Version, stream_input, async_start @@ -99,6 +99,17 @@ def _cmd_received(self) -> bool: self.ctx.on_print_json({"data": parts, "cmd": "PrintJSON"}) return True + def get_current_datapackage(self) -> dict[str, typing.Any]: + """ + Return datapackage for current game if known. + + :return: The datapackage for the currently registered game. If not found, an empty dictionary will be returned. + """ + if not self.ctx.game: + return {} + checksum = self.ctx.checksums[self.ctx.game] + return Utils.load_data_package_for_checksum(self.ctx.game, checksum) + def _cmd_missing(self, filter_text = "") -> bool: """List all missing location checks, from your local game state. Can be given text, which will be used as filter.""" @@ -107,7 +118,9 @@ def _cmd_missing(self, filter_text = "") -> bool: return False count = 0 checked_count = 0 - for location, location_id in AutoWorldRegister.world_types[self.ctx.game].location_name_to_id.items(): + + lookup = self.get_current_datapackage().get("location_name_to_id", {}) + for location, location_id in lookup.items(): if filter_text and filter_text not in location: continue if location_id < 0: @@ -128,43 +141,91 @@ def _cmd_missing(self, filter_text = "") -> bool: self.output("No missing location checks found.") return True - def _cmd_items(self): - """List all item names for the currently running game.""" + def output_datapackage_part(self, key: str, name: str) -> bool: + """ + Helper to digest a specific section of this game's datapackage. + + :param key: The dictionary key in the datapackage. + :param name: Printed to the user as context for the part. + + :return: Whether the process was successful. + """ if not self.ctx.game: - self.output("No game set, cannot determine existing items.") + self.output(f"No game set, cannot determine {name}.") return False - self.output(f"Item Names for {self.ctx.game}") - for item_name in AutoWorldRegister.world_types[self.ctx.game].item_name_to_id: - self.output(item_name) - def _cmd_item_groups(self): - """List all item group names for the currently running game.""" - if not self.ctx.game: - self.output("No game set, cannot determine existing item groups.") + lookup = self.get_current_datapackage().get(key) + if lookup is None: + self.output("datapackage not yet loaded, try again") return False - self.output(f"Item Group Names for {self.ctx.game}") - for group_name in AutoWorldRegister.world_types[self.ctx.game].item_name_groups: - self.output(group_name) - def _cmd_locations(self): + self.output(f"{name} for {self.ctx.game}") + for key in lookup: + self.output(key) + return True + + def _cmd_items(self) -> bool: + """List all item names for the currently running game.""" + return self.output_datapackage_part("item_name_to_id", "Item Names") + + def _cmd_locations(self) -> bool: """List all location names for the currently running game.""" - if not self.ctx.game: - self.output("No game set, cannot determine existing locations.") - return False - self.output(f"Location Names for {self.ctx.game}") - for location_name in AutoWorldRegister.world_types[self.ctx.game].location_name_to_id: - self.output(location_name) + return self.output_datapackage_part("location_name_to_id", "Location Names") + + def output_group_part(self, group_key: typing.Literal["item_name_groups", "location_name_groups"], + filter_key: str, + name: str) -> bool: + """ + Logs an item or location group from the player's game's datapackage. - def _cmd_location_groups(self): - """List all location group names for the currently running game.""" + :param group_key: Either Item or Location group to be processed. + :param filter_key: Which group key to filter to. If an empty string is passed will log all item/location groups. + :param name: Printed to the user as context for the part. + + :return: Whether the process was successful. + """ if not self.ctx.game: - self.output("No game set, cannot determine existing location groups.") + self.output(f"No game set, cannot determine existing {name} Groups.") + return False + lookup = Utils.persistent_load().get("groups_by_checksum", {}).get(self.ctx.checksums[self.ctx.game], {})\ + .get(self.ctx.game, {}).get(group_key, {}) + if lookup is None: + self.output("datapackage not yet loaded, try again") return False - self.output(f"Location Group Names for {self.ctx.game}") - for group_name in AutoWorldRegister.world_types[self.ctx.game].location_name_groups: - self.output(group_name) - def _cmd_ready(self): + if filter_key: + if filter_key not in lookup: + self.output(f"Unknown {name} Group {filter_key}") + return False + + self.output(f"{name}s for {name} Group \"{filter_key}\"") + for entry in lookup[filter_key]: + self.output(entry) + else: + self.output(f"{name} Groups for {self.ctx.game}") + for group in lookup: + self.output(group) + return True + + @mark_raw + def _cmd_item_groups(self, key: str = "") -> bool: + """ + List all item group names for the currently running game. + + :param key: Which item group to filter to. Will log all groups if empty. + """ + return self.output_group_part("item_name_groups", key, "Item") + + @mark_raw + def _cmd_location_groups(self, key: str = "") -> bool: + """ + List all location group names for the currently running game. + + :param key: Which item group to filter to. Will log all groups if empty. + """ + return self.output_group_part("location_name_groups", key, "Location") + + def _cmd_ready(self) -> bool: """Send ready status to server.""" self.ctx.ready = not self.ctx.ready if self.ctx.ready: @@ -174,6 +235,7 @@ def _cmd_ready(self): state = ClientStatus.CLIENT_CONNECTED self.output("Unreadied.") async_start(self.ctx.send_msgs([{"cmd": "StatusUpdate", "status": state}]), name="send StatusUpdate") + return True def default(self, raw: str): """The default message parser to be used when parsing any messages that do not match a command""" @@ -379,6 +441,8 @@ def __init__(self, server_address: typing.Optional[str] = None, password: typing self.jsontotextparser = JSONtoTextParser(self) self.rawjsontotextparser = RawJSONtoTextParser(self) + if self.game: + self.checksums[self.game] = network_data_package["games"][self.game]["checksum"] self.update_data_package(network_data_package) # execution @@ -638,6 +702,24 @@ def consume_network_data_package(self, data_package: dict): for game, game_data in data_package["games"].items(): Utils.store_data_package_for_checksum(game, game_data) + def consume_network_item_groups(self): + data = {"item_name_groups": self.stored_data[f"_read_item_name_groups_{self.game}"]} + current_cache = Utils.persistent_load().get("groups_by_checksum", {}).get(self.checksums[self.game], {}) + if self.game in current_cache: + current_cache[self.game].update(data) + else: + current_cache[self.game] = data + Utils.persistent_store("groups_by_checksum", self.checksums[self.game], current_cache) + + def consume_network_location_groups(self): + data = {"location_name_groups": self.stored_data[f"_read_location_name_groups_{self.game}"]} + current_cache = Utils.persistent_load().get("groups_by_checksum", {}).get(self.checksums[self.game], {}) + if self.game in current_cache: + current_cache[self.game].update(data) + else: + current_cache[self.game] = data + Utils.persistent_store("groups_by_checksum", self.checksums[self.game], current_cache) + # data storage def set_notify(self, *keys: str) -> None: @@ -938,6 +1020,12 @@ async def process_server_cmd(ctx: CommonContext, args: dict): ctx.hint_points = args.get("hint_points", 0) ctx.consume_players_package(args["players"]) ctx.stored_data_notification_keys.add(f"_read_hints_{ctx.team}_{ctx.slot}") + if ctx.game: + game = ctx.game + else: + game = ctx.slot_info[ctx.slot][1] + ctx.stored_data_notification_keys.add(f"_read_item_name_groups_{game}") + ctx.stored_data_notification_keys.add(f"_read_location_name_groups_{game}") msgs = [] if ctx.locations_checked: msgs.append({"cmd": "LocationChecks", @@ -1018,11 +1106,19 @@ async def process_server_cmd(ctx: CommonContext, args: dict): ctx.stored_data.update(args["keys"]) if ctx.ui and f"_read_hints_{ctx.team}_{ctx.slot}" in args["keys"]: ctx.ui.update_hints() + if f"_read_item_name_groups_{ctx.game}" in args["keys"]: + ctx.consume_network_item_groups() + if f"_read_location_name_groups_{ctx.game}" in args["keys"]: + ctx.consume_network_location_groups() elif cmd == "SetReply": ctx.stored_data[args["key"]] = args["value"] if ctx.ui and f"_read_hints_{ctx.team}_{ctx.slot}" == args["key"]: ctx.ui.update_hints() + elif f"_read_item_name_groups_{ctx.game}" == args["key"]: + ctx.consume_network_item_groups() + elif f"_read_location_name_groups_{ctx.game}" == args["key"]: + ctx.consume_network_location_groups() elif args["key"].startswith("EnergyLink"): ctx.current_energy_link_value = args["value"] if ctx.ui: From f27da5cc78ce29dd2aff4290041ff5d153047c3b Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sat, 26 Jul 2025 03:42:55 -0700 Subject: [PATCH 0602/1218] BizHawkClient: Add command to pass server messages to emulator (#3039) --- worlds/_bizhawk/context.py | 115 ++++++++++++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 8 deletions(-) diff --git a/worlds/_bizhawk/context.py b/worlds/_bizhawk/context.py index c9b107664463..250e4a882642 100644 --- a/worlds/_bizhawk/context.py +++ b/worlds/_bizhawk/context.py @@ -4,6 +4,7 @@ """ import asyncio +import copy import enum import subprocess from typing import Any @@ -13,7 +14,7 @@ import Utils from . import BizHawkContext, ConnectionStatus, NotConnectedError, RequestFailedError, connect, disconnect, get_hash, \ - get_script_version, get_system, ping + get_script_version, get_system, ping, display_message from .client import BizHawkClient, AutoBizHawkClientRegister @@ -27,20 +28,97 @@ class AuthStatus(enum.IntEnum): AUTHENTICATED = 3 +class TextCategory(str, enum.Enum): + ALL = "all" + INCOMING = "incoming" + OUTGOING = "outgoing" + OTHER = "other" + HINT = "hint" + CHAT = "chat" + SERVER = "server" + + class BizHawkClientCommandProcessor(ClientCommandProcessor): def _cmd_bh(self): """Shows the current status of the client's connection to BizHawk""" - if isinstance(self.ctx, BizHawkClientContext): - if self.ctx.bizhawk_ctx.connection_status == ConnectionStatus.NOT_CONNECTED: - logger.info("BizHawk Connection Status: Not Connected") - elif self.ctx.bizhawk_ctx.connection_status == ConnectionStatus.TENTATIVE: - logger.info("BizHawk Connection Status: Tentatively Connected") - elif self.ctx.bizhawk_ctx.connection_status == ConnectionStatus.CONNECTED: - logger.info("BizHawk Connection Status: Connected") + assert isinstance(self.ctx, BizHawkClientContext) + + if self.ctx.bizhawk_ctx.connection_status == ConnectionStatus.NOT_CONNECTED: + logger.info("BizHawk Connection Status: Not Connected") + elif self.ctx.bizhawk_ctx.connection_status == ConnectionStatus.TENTATIVE: + logger.info("BizHawk Connection Status: Tentatively Connected") + elif self.ctx.bizhawk_ctx.connection_status == ConnectionStatus.CONNECTED: + logger.info("BizHawk Connection Status: Connected") + + def _cmd_toggle_text(self, category: str | None = None, toggle: str | None = None): + """Sets types of incoming messages to forward to the emulator""" + assert isinstance(self.ctx, BizHawkClientContext) + + if category is None: + logger.info("Usage: /toggle_text category [toggle]\n\n" + "category: incoming, outgoing, other, hint, chat, and server\n" + "Or \"all\" to toggle all categories at once\n\n" + "toggle: on, off, true, or false\n" + "Or omit to set it to the opposite of its current state\n\n" + "Example: /toggle_text outgoing on") + return + + category = category.lower() + value: bool | None + if toggle is None: + value = None + elif toggle.lower() in ("on", "true"): + value = True + elif toggle.lower() in ("off", "false"): + value = False + else: + logger.info(f'Unknown value "{toggle}", should be on|off|true|false') + return + + valid_categories = ( + TextCategory.ALL, + TextCategory.OTHER, + TextCategory.INCOMING, + TextCategory.OUTGOING, + TextCategory.HINT, + TextCategory.CHAT, + TextCategory.SERVER, + ) + if category not in valid_categories: + logger.info(f'Unknown value "{category}", should be {"|".join(valid_categories)}') + return + + if category == TextCategory.ALL: + if value is None: + logger.info('Must specify "on" or "off" for category "all"') + return + + if value: + self.ctx.text_passthrough_categories.update(( + TextCategory.OTHER, + TextCategory.INCOMING, + TextCategory.OUTGOING, + TextCategory.HINT, + TextCategory.CHAT, + TextCategory.SERVER, + )) + else: + self.ctx.text_passthrough_categories.clear() + else: + if value is None: + value = category not in self.ctx.text_passthrough_categories + + if value: + self.ctx.text_passthrough_categories.add(category) + else: + self.ctx.text_passthrough_categories.remove(category) + + logger.info(f"Currently Showing Categories: {', '.join(self.ctx.text_passthrough_categories)}") class BizHawkClientContext(CommonContext): command_processor = BizHawkClientCommandProcessor + text_passthrough_categories: set[str] server_seed_name: str | None = None auth_status: AuthStatus password_requested: bool @@ -54,12 +132,33 @@ class BizHawkClientContext(CommonContext): def __init__(self, server_address: str | None, password: str | None): super().__init__(server_address, password) + self.text_passthrough_categories = set() self.auth_status = AuthStatus.NOT_AUTHENTICATED self.password_requested = False self.client_handler = None self.bizhawk_ctx = BizHawkContext() self.watcher_timeout = 0.5 + def _categorize_text(self, args: dict) -> TextCategory: + if "type" not in args or args["type"] in {"Hint", "Join", "Part", "TagsChanged", "Goal", "Release", "Collect", + "Countdown", "ServerChat", "ItemCheat"}: + return TextCategory.SERVER + elif args["type"] == "Chat": + return TextCategory.CHAT + elif args["type"] == "ItemSend": + if args["item"].player == self.slot: + return TextCategory.OUTGOING + elif args["receiving"] == self.slot: + return TextCategory.INCOMING + else: + return TextCategory.OTHER + + def on_print_json(self, args: dict): + super().on_print_json(args) + if self.bizhawk_ctx.connection_status == ConnectionStatus.CONNECTED: + if self._categorize_text(args) in self.text_passthrough_categories: + Utils.async_start(display_message(self.bizhawk_ctx, self.rawjsontotextparser(copy.deepcopy(args["data"])))) + def make_gui(self): ui = super().make_gui() ui.base_title = "Archipelago BizHawk Client" From a3af953683fc60a36956d883df39087ce2c8dab3 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 26 Jul 2025 14:12:45 +0200 Subject: [PATCH 0603/1218] WebHost: list unrecognized games as Other in stats (#5236) --- WebHostLib/stats.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/WebHostLib/stats.py b/WebHostLib/stats.py index 6fd73caf6cb5..2ce25c2cc7a2 100644 --- a/WebHostLib/stats.py +++ b/WebHostLib/stats.py @@ -25,8 +25,11 @@ def get_db_data(known_games: set[str]) -> tuple[Counter[str], defaultdict[date, for room in select(room for room in Room if room.creation_time >= cutoff): for slot in room.seed.slots: if slot.game in known_games: - total_games[slot.game] += 1 - games_played[room.creation_time.date()][slot.game] += 1 + current_game = slot.game + else: + current_game = "Other" + total_games[current_game] += 1 + games_played[room.creation_time.date()][current_game] += 1 return total_games, games_played From 8fd021e75724061e5cd73e9f7814c56e0ab5d844 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Sat, 26 Jul 2025 13:59:35 +0100 Subject: [PATCH 0604/1218] Core: Speed up CollectionState sweeping (#3812) * Sweep events per-player to reduce sweep iterations By finding all accessible locations per player and then collecting the items from those locations, if any collected items belong to a different player, then that player may be able to access more locations the next time all of their accessible locations are found. This reduces the number of iterations necessary to sweep through and collect from all accessible locations. * Also sweep per-player in MultiWorld.can_beat_game * Deduplicate code by using sweep_for_events in can_beat_game sweep_for_events has been modified to be able to return a generator and to be able to change the set of locations that are filtered out. This way, the same code can be used by both functions. * Skip checking locations by assuming each world only logically depends on itself While this assumption almost always holds true, worlds are allowed to logically depend on other worlds, so the sweep always double checks at the end by checking the locations of every world before finishing. * Fix missed update to CollectionState.collect implementation Collecting items with prevent_sweep=True (previously event=True) no longer always returns True, so the return value should now be checked. * Comment and variable name consistency/clarity accessible/inaccessible -> reachable/unreachable final sweep iteration -> extra sweep iteration maybe_final_sweep -> checking_if_finished * Apply suggestions from code review Use Iterator in return type hint instead of Iterable to help indicate that the returned value can only be iterated once. Be consistent in return statements. Because sweep_for_events can return a value now, the conditional branch that has no intended return value should explicitly return None. Co-authored-by: Doug Hoskisson * Update terminology from 'event' to 'advancement' * Add typing overloads for sweep_for_advancements This makes it so type-checkers and IDEs can see which calls return `None` and which calls return `Iterator` so that it doesn't complain about returning an `Iterator` from `sweep_for_events` or about iterating through `None` in `can_beat_game`. Co-authored-by: Doug Hoskisson * Update comment for why discard the player after finding their locations A lack of clarity was brought up in review. * Update for removed typing import --------- Co-authored-by: Doug Hoskisson --- BaseClasses.py | 166 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 131 insertions(+), 35 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index ba07868655f8..10d054063392 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -7,11 +7,11 @@ import secrets import warnings from argparse import Namespace -from collections import Counter, deque +from collections import Counter, deque, defaultdict from collections.abc import Collection, MutableSequence from enum import IntEnum, IntFlag from typing import (AbstractSet, Any, Callable, ClassVar, Dict, Iterable, Iterator, List, Literal, Mapping, NamedTuple, - Optional, Protocol, Set, Tuple, Union, TYPE_CHECKING) + Optional, Protocol, Set, Tuple, Union, TYPE_CHECKING, Literal, overload) import dataclasses from typing_extensions import NotRequired, TypedDict @@ -585,26 +585,9 @@ def can_beat_game(self, if self.has_beaten_game(state): return True - base_locations = self.get_locations() if locations is None else locations - prog_locations = {location for location in base_locations if location.item - and location.item.advancement and location not in state.locations_checked} - - while prog_locations: - sphere: Set[Location] = set() - # build up spheres of collection radius. - # Everything in each sphere is independent from each other in dependencies and only depends on lower spheres - for location in prog_locations: - if location.can_reach(state): - sphere.add(location) - - if not sphere: - # ran out of places and did not finish yet, quit - return False - - for location in sphere: - state.collect(location.item, True, location) - prog_locations -= sphere - + for _ in state.sweep_for_advancements(locations, + yield_each_sweep=True, + checked_locations=state.locations_checked): if self.has_beaten_game(state): return True @@ -889,20 +872,133 @@ def sweep_for_events(self, locations: Optional[Iterable[Location]] = None) -> No "Please switch over to sweep_for_advancements.") return self.sweep_for_advancements(locations) - def sweep_for_advancements(self, locations: Optional[Iterable[Location]] = None) -> None: + def _sweep_for_advancements_impl(self, advancements_per_player: List[Tuple[int, List[Location]]], + yield_each_sweep: bool) -> Iterator[None]: + """ + The implementation for sweep_for_advancements is separated here because it returns a generator due to the use + of a yield statement. + """ + all_players = {player for player, _ in advancements_per_player} + players_to_check = all_players + # As an optimization, it is assumed that each player's world only logically depends on itself. However, worlds + # are allowed to logically depend on other worlds, so once there are no more players that should be checked + # under this assumption, an extra sweep iteration is performed that checks every player, to confirm that the + # sweep is finished. + checking_if_finished = False + while players_to_check: + next_advancements_per_player: List[Tuple[int, List[Location]]] = [] + next_players_to_check = set() + + for player, locations in advancements_per_player: + if player not in players_to_check: + next_advancements_per_player.append((player, locations)) + continue + + # Accessibility of each location is checked first because a player's region accessibility cache becomes + # stale whenever one of their own items is collected into the state. + reachable_locations: List[Location] = [] + unreachable_locations: List[Location] = [] + for location in locations: + if location.can_reach(self): + # Locations containing items that do not belong to `player` could be collected immediately + # because they won't stale `player`'s region accessibility cache, but, for simplicity, all the + # items at reachable locations are collected in a single loop. + reachable_locations.append(location) + else: + unreachable_locations.append(location) + if unreachable_locations: + next_advancements_per_player.append((player, unreachable_locations)) + + # A previous player's locations processed in the current `while players_to_check` iteration could have + # collected items belonging to `player`, but now that all of `player`'s reachable locations have been + # found, it can be assumed that `player` will not gain any more reachable locations until another one of + # their items is collected. + # It would be clearer to not add players to `next_players_to_check` in the first place if they have yet + # to be processed in the current `while players_to_check` iteration, but checking if a player should be + # added to `next_players_to_check` would need to be run once for every item that is collected, so it is + # more performant to instead discard `player` from `next_players_to_check` once their locations have + # been processed. + next_players_to_check.discard(player) + + # Collect the items from the reachable locations. + for advancement in reachable_locations: + self.advancements.add(advancement) + item = advancement.item + assert isinstance(item, Item), "tried to collect advancement Location with no Item" + if self.collect(item, True, advancement): + # The player the item belongs to may be able to reach additional locations in the next sweep + # iteration. + next_players_to_check.add(item.player) + + if not next_players_to_check: + if not checking_if_finished: + # It is assumed that each player's world only logically depends on itself, which may not be the + # case, so confirm that the sweep is finished by doing an extra iteration that checks every player. + checking_if_finished = True + next_players_to_check = all_players + else: + checking_if_finished = False + + players_to_check = next_players_to_check + advancements_per_player = next_advancements_per_player + + if yield_each_sweep: + yield + + @overload + def sweep_for_advancements(self, locations: Optional[Iterable[Location]] = None, *, + yield_each_sweep: Literal[True], + checked_locations: Optional[Set[Location]] = None) -> Iterator[None]: ... + + @overload + def sweep_for_advancements(self, locations: Optional[Iterable[Location]] = None, + yield_each_sweep: Literal[False] = False, + checked_locations: Optional[Set[Location]] = None) -> None: ... + + def sweep_for_advancements(self, locations: Optional[Iterable[Location]] = None, yield_each_sweep: bool = False, + checked_locations: Optional[Set[Location]] = None) -> Optional[Iterator[None]]: + """ + Sweep through the locations that contain uncollected advancement items, collecting the items into the state + until there are no more reachable locations that contain uncollected advancement items. + + :param locations: The locations to sweep through, defaulting to all locations in the multiworld. + :param yield_each_sweep: When True, return a generator that yields at the end of each sweep iteration. + :param checked_locations: Optional override of locations to filter out from the locations argument, defaults to + self.advancements when None. + """ + if checked_locations is None: + checked_locations = self.advancements + + # Since the sweep loop usually performs many iterations, the locations are filtered in advance. + # A list of tuples is used, instead of a dictionary, because it is faster to iterate. + advancements_per_player: List[Tuple[int, List[Location]]] if locations is None: - locations = self.multiworld.get_filled_locations() - reachable_advancements = True - # since the loop has a good chance to run more than once, only filter the advancements once - locations = {location for location in locations if location.advancement and location not in self.advancements} - - while reachable_advancements: - reachable_advancements = {location for location in locations if location.can_reach(self)} - locations -= reachable_advancements - for advancement in reachable_advancements: - self.advancements.add(advancement) - assert isinstance(advancement.item, Item), "tried to collect Event with no Item" - self.collect(advancement.item, True, advancement) + # `location.advancement` can only be True for filled locations, so unfilled locations are filtered out. + advancements_per_player = [] + for player, locations_dict in self.multiworld.regions.location_cache.items(): + filtered_locations = [location for location in locations_dict.values() + if location.advancement and location not in checked_locations] + if filtered_locations: + advancements_per_player.append((player, filtered_locations)) + else: + # Filter and separate the locations into a list for each player. + advancements_per_player_dict: Dict[int, List[Location]] = defaultdict(list) + for location in locations: + if location.advancement and location not in checked_locations: + advancements_per_player_dict[location.player].append(location) + # Convert to a list of tuples. + advancements_per_player = list(advancements_per_player_dict.items()) + del advancements_per_player_dict + + if yield_each_sweep: + # Return a generator that will yield at the end of each sweep iteration. + return self._sweep_for_advancements_impl(advancements_per_player, True) + else: + # Create the generator, but tell it not to yield anything, so it will run to completion in zero iterations + # once started, then start and exhaust the generator by attempting to iterate it. + for _ in self._sweep_for_advancements_impl(advancements_per_player, False): + assert False, "Generator yielded when it should have run to completion without yielding" + return None # item name related def has(self, item: str, player: int, count: int = 1) -> bool: From 46829487d666f528218e146b1bb9dd1e351d7f65 Mon Sep 17 00:00:00 2001 From: Adrian Priestley <47989725+a-priestley@users.noreply.github.com> Date: Sat, 26 Jul 2025 12:18:39 -0230 Subject: [PATCH 0605/1218] fix(docker): Correct copy command to use recursive flag for EnemizerCLI (#5211) * fix(docker): Correct copy command to use recursive flag for EnemizerCLI - Changed 'cp' to 'cp -r' to properly copy EnemizerCLI directory * docs(deployment): Update container deployment documentation - Specify minimum versions for Docker and Podman - Add requirement for Docker Buildx plugin --- Dockerfile | 4 +++- docs/deploy using containers.md | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index c6d22a4fb836..46393aab9eaa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -86,7 +86,7 @@ COPY --from=enemizer /release/EnemizerCLI /tmp/EnemizerCLI # No release for arm architecture. Skip. RUN if [ "$TARGETARCH" = "amd64" ]; then \ - cp /tmp/EnemizerCLI EnemizerCLI; \ + cp -r /tmp/EnemizerCLI EnemizerCLI; \ fi; \ rm -rf /tmp/EnemizerCLI @@ -94,5 +94,7 @@ RUN if [ "$TARGETARCH" = "amd64" ]; then \ HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:${PORT:-80} || exit 1 +# Ensure no runtime ModuleUpdate. ENV SKIP_REQUIREMENTS_UPDATE=true + ENTRYPOINT [ "python", "WebHost.py" ] diff --git a/docs/deploy using containers.md b/docs/deploy using containers.md index bb77900174c8..6db38d443ffb 100644 --- a/docs/deploy using containers.md +++ b/docs/deploy using containers.md @@ -9,9 +9,10 @@ Follow these steps to build and deploy a containerized instance of the web host What you'll need: * A container runtime engine such as: - * [Docker](https://www.docker.com/) - * [Podman](https://podman.io/) + * [Docker](https://www.docker.com/) (Version 23.0 or later) + * [Podman](https://podman.io/) (version 4.0 or later) * For running with rootless podman, you need to ensure all ports used are usable rootless, by default ports less than 1024 are root only. See [the official tutorial](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md) for details. + * The Docker Buildx plugin (for Docker), as the Dockerfile uses `$TARGETARCH` for architecture detection. Follow [Docker's guide](https://docs.docker.com/build/buildx/install/). Verify with `docker buildx version`. Starting from the root repository directory, the standalone Archipelago image can be built and run with the command: `docker build -t archipelago .` From 4e1eb78163f9008f0812b8da3a0478c9a61dbfd7 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 26 Jul 2025 19:30:38 +0200 Subject: [PATCH 0606/1218] MultiServer: Fix LocationScouts with "only_new" broadcasting hints for found locations over and over (#4482) * Hints PR number 42069 * Make it explicit * clarify * oops * Port the change to CreateHints --- MultiServer.py | 11 ++++++----- docs/network protocol.md | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 108795d84f5d..1f421aaa8f54 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -752,7 +752,7 @@ def get_aliased_name(self, team: int, slot: int): return self.player_names[team, slot] def notify_hints(self, team: int, hints: typing.List[Hint], only_new: bool = False, - recipients: typing.Sequence[int] = None): + persist_even_if_found: bool = False, recipients: typing.Sequence[int] = None): """Send and remember hints.""" if only_new: hints = [hint for hint in hints if hint not in self.hints[team, hint.finding_player]] @@ -767,8 +767,9 @@ def notify_hints(self, team: int, hints: typing.List[Hint], only_new: bool = Fal if not hint.local and data not in concerns[hint.finding_player]: concerns[hint.finding_player].append(data) - # only remember hints that were not already found at the time of creation - if not hint.found: + # For !hint use cases, only hints that were not already found at the time of creation should be remembered + # For LocationScouts use-cases, all hints should be remembered + if not hint.found or persist_even_if_found: # since hints are bidirectional, finding player and receiving player, # we can check once if hint already exists if hint not in self.hints[team, hint.finding_player]: @@ -1946,7 +1947,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): hints.extend(collect_hint_location_id(ctx, client.team, client.slot, location, HintStatus.HINT_UNSPECIFIED)) locs.append(NetworkItem(target_item, location, target_player, flags)) - ctx.notify_hints(client.team, hints, only_new=create_as_hint == 2) + ctx.notify_hints(client.team, hints, only_new=create_as_hint == 2, persist_even_if_found=True) if locs and create_as_hint: ctx.save() await ctx.send_msgs(client, [{'cmd': 'LocationInfo', 'locations': locs}]) @@ -1990,7 +1991,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): hints += collect_hint_location_id(ctx, client.team, location_player, location, status) # As of writing this code, only_new=True does not update status for existing hints - ctx.notify_hints(client.team, hints, only_new=True) + ctx.notify_hints(client.team, hints, only_new=True, persist_even_if_found=True) ctx.save() elif cmd == 'UpdateHint': diff --git a/docs/network protocol.md b/docs/network protocol.md index 4b66b7b1d349..b40cf31b8568 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -340,7 +340,8 @@ Sent to the server to retrieve the items that are on a specified list of locatio Fully remote clients without a patch file may use this to "place" items onto their in-game locations, most commonly to display their names or item classifications before/upon pickup. LocationScouts can also be used to inform the server of locations the client has seen, but not checked. This creates a hint as if the player had run `!hint_location` on a location, but without deducting hint points. -This is useful in cases where an item appears in the game world, such as 'ledge items' in _A Link to the Past_. To do this, set the `create_as_hint` parameter to a non-zero value. +This is useful in cases where an item appears in the game world, such as 'ledge items' in _A Link to the Past_. To do this, set the `create_as_hint` parameter to a non-zero value. +Note that LocationScouts with a non-zero `create_as_hint` value will _always_ create a **persistent** hint (listed in the Hints tab of concerning players' TextClients), even if the location was already found. If this is not desired behavior, you need to prevent sending LocationScouts with `create_as_hint` for already found locations in your client-side code. #### Arguments | Name | Type | Notes | From faac2540bf5089fadd205258c5c61d8112cde5e1 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Sat, 26 Jul 2025 13:32:59 -0400 Subject: [PATCH 0607/1218] LADX: fix marin text splitting #5225 --- worlds/ladx/LADXR/patches/aesthetics.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/worlds/ladx/LADXR/patches/aesthetics.py b/worlds/ladx/LADXR/patches/aesthetics.py index 6ca7d3d973fd..2c9c8186870a 100644 --- a/worlds/ladx/LADXR/patches/aesthetics.py +++ b/worlds/ladx/LADXR/patches/aesthetics.py @@ -180,9 +180,10 @@ def noText(rom): def reduceMessageLengths(rom, rnd): # Into text from Marin. Got to go fast, so less text. (This intro text is very long) - lines = pkgutil.get_data(__name__, "marin.txt").decode("unicode_escape").splitlines() - lines = [l for l in lines if l.strip()] - rom.texts[0x01] = formatText(rnd.choice(lines).strip()) + lines = pkgutil.get_data(__name__, "marin.txt").splitlines(keepends=True) + while lines and lines[-1].strip() == b'': + lines.pop(-1) + rom.texts[0x01] = formatText(rnd.choice(lines).strip().decode("unicode_escape")) # Reduce length of a bunch of common texts rom.texts[0xEA] = formatText("You've got a Guardian Acorn!") From fa49fef6958f04557f5f7c55ba5ab4f8b3511a59 Mon Sep 17 00:00:00 2001 From: qwint Date: Sat, 26 Jul 2025 15:13:15 -0500 Subject: [PATCH 0608/1218] Core: use patch extension register directly (#4375) Co-authored-by: Aaron Wagener --- worlds/Files.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/worlds/Files.py b/worlds/Files.py index fa3739a5a919..27c0e9c42e35 100644 --- a/worlds/Files.py +++ b/worlds/Files.py @@ -15,7 +15,6 @@ semaphore = threading.Semaphore(os.cpu_count() or 4) del threading -del os class AutoPatchRegister(abc.ABCMeta): @@ -34,10 +33,8 @@ def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> Aut @staticmethod def get_handler(file: str) -> Optional[AutoPatchRegister]: - for file_ending, handler in AutoPatchRegister.file_endings.items(): - if file.endswith(file_ending): - return handler - return None + _, suffix = os.path.splitext(file) + return AutoPatchRegister.file_endings.get(suffix, None) class AutoPatchExtensionRegister(abc.ABCMeta): From 7a8048a8fddbb016de0f9e73bff7067e9a786d43 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Sat, 26 Jul 2025 16:16:00 -0400 Subject: [PATCH 0609/1218] LADX: generate without rom (#4278) --- worlds/ladx/LADXR/generator.py | 279 +++++++++------------ worlds/ladx/LADXR/hints.py | 56 ++++- worlds/ladx/LADXR/patches/core.py | 4 +- worlds/ladx/LADXR/patches/enemies.py | 2 +- worlds/ladx/LADXR/patches/titleScreen.py | 22 +- worlds/ladx/LADXR/patches/tradeSequence.py | 2 +- worlds/ladx/LADXR/rom.py | 16 +- worlds/ladx/LADXR/romTables.py | 8 +- worlds/ladx/Options.py | 39 +-- worlds/ladx/Rom.py | 99 +++++++- worlds/ladx/__init__.py | 80 +++--- 11 files changed, 317 insertions(+), 290 deletions(-) diff --git a/worlds/ladx/LADXR/generator.py b/worlds/ladx/LADXR/generator.py index 413bf89c063c..81ca66601049 100644 --- a/worlds/ladx/LADXR/generator.py +++ b/worlds/ladx/LADXR/generator.py @@ -2,13 +2,15 @@ import importlib.util import importlib.machinery import os -import pkgutil +import random +import pickle +import Utils +import settings from collections import defaultdict -from typing import TYPE_CHECKING +from typing import Dict from .romTables import ROMWithTables from . import assembler -from . import mapgen from . import patches from .patches import overworld as _ from .patches import dungeon as _ @@ -57,27 +59,20 @@ from . import hints from .patches import bank34 -from .utils import formatText from .roomEditor import RoomEditor, Object from .patches.aesthetics import rgb_to_bin, bin_to_rgb -from .locations.keyLocation import KeyLocation - -from BaseClasses import ItemClassification -from ..Locations import LinksAwakeningLocation -from ..Options import TrendyGame, Palette, MusicChangeCondition, Warps - -if TYPE_CHECKING: - from .. import LinksAwakeningWorld - +from .. import Options # Function to generate a final rom, this patches the rom with all required patches -def generateRom(args, world: "LinksAwakeningWorld"): +def generateRom(base_rom: bytes, args, patch_data: Dict): + random.seed(patch_data["seed"] + patch_data["player"]) + multi_key = binascii.unhexlify(patch_data["multi_key"].encode()) + item_list = pickle.loads(binascii.unhexlify(patch_data["item_list"].encode())) + options = patch_data["options"] rom_patches = [] - player_names = list(world.multiworld.player_name.values()) - - rom = ROMWithTables(args.input_filename, rom_patches) - rom.player_names = player_names + rom = ROMWithTables(base_rom, rom_patches) + rom.player_names = patch_data["other_player_names"] pymods = [] if args.pymod: for pymod in args.pymod: @@ -88,10 +83,13 @@ def generateRom(args, world: "LinksAwakeningWorld"): for pymod in pymods: pymod.prePatch(rom) - if world.ladxr_settings.gfxmod: - patches.aesthetics.gfxMod(rom, os.path.join("data", "sprites", "ladx", world.ladxr_settings.gfxmod)) - - item_list = [item for item in world.ladxr_logic.iteminfo_list if not isinstance(item, KeyLocation)] + if options["gfxmod"]: + user_settings = settings.get_settings() + try: + gfx_mod_file = user_settings["ladx_options"]["gfx_mod_file"] + patches.aesthetics.gfxMod(rom, gfx_mod_file) + except FileNotFoundError: + pass # if user just doesnt provide gfxmod file, let patching continue assembler.resetConsts() assembler.const("INV_SIZE", 16) @@ -121,7 +119,7 @@ def generateRom(args, world: "LinksAwakeningWorld"): assembler.const("wLinkSpawnDelay", 0xDE13) #assembler.const("HARDWARE_LINK", 1) - assembler.const("HARD_MODE", 1 if world.ladxr_settings.hardmode != "none" else 0) + assembler.const("HARD_MODE", 1 if options["hard_mode"] else 0) patches.core.cleanup(rom) patches.save.singleSaveSlot(rom) @@ -135,7 +133,7 @@ def generateRom(args, world: "LinksAwakeningWorld"): patches.core.easyColorDungeonAccess(rom) patches.owl.removeOwlEvents(rom) patches.enemies.fixArmosKnightAsMiniboss(rom) - patches.bank3e.addBank3E(rom, world.multi_key, world.player, player_names) + patches.bank3e.addBank3E(rom, multi_key, patch_data["player"], patch_data["other_player_names"]) patches.bank3f.addBank3F(rom) patches.bank34.addBank34(rom, item_list) patches.core.removeGhost(rom) @@ -144,19 +142,17 @@ def generateRom(args, world: "LinksAwakeningWorld"): patches.core.alwaysAllowSecretBook(rom) patches.core.injectMainLoop(rom) - from ..Options import ShuffleSmallKeys, ShuffleNightmareKeys - - if world.options.shuffle_small_keys != ShuffleSmallKeys.option_original_dungeon or\ - world.options.shuffle_nightmare_keys != ShuffleNightmareKeys.option_original_dungeon: + if options["shuffle_small_keys"] != Options.ShuffleSmallKeys.option_original_dungeon or\ + options["shuffle_nightmare_keys"] != Options.ShuffleNightmareKeys.option_original_dungeon: patches.inventory.advancedInventorySubscreen(rom) patches.inventory.moreSlots(rom) - if world.ladxr_settings.witch: - patches.witch.updateWitch(rom) + # if ladxr_settings["witch"]: + patches.witch.updateWitch(rom) patches.softlock.fixAll(rom) - if not world.ladxr_settings.rooster: + if not options["rooster"]: patches.maptweaks.tweakMap(rom) patches.maptweaks.tweakBirdKeyRoom(rom) - if world.ladxr_settings.overworld == "openmabe": + if options["overworld"] == Options.Overworld.option_open_mabe: patches.maptweaks.openMabe(rom) patches.chest.fixChests(rom) patches.shop.fixShop(rom) @@ -168,10 +164,10 @@ def generateRom(args, world: "LinksAwakeningWorld"): patches.tarin.updateTarin(rom) patches.fishingMinigame.updateFinishingMinigame(rom) patches.health.upgradeHealthContainers(rom) - if world.ladxr_settings.owlstatues in ("dungeon", "both"): - patches.owl.upgradeDungeonOwlStatues(rom) - if world.ladxr_settings.owlstatues in ("overworld", "both"): - patches.owl.upgradeOverworldOwlStatues(rom) + # if ladxr_settings["owlstatues"] in ("dungeon", "both"): + # patches.owl.upgradeDungeonOwlStatues(rom) + # if ladxr_settings["owlstatues"] in ("overworld", "both"): + # patches.owl.upgradeOverworldOwlStatues(rom) patches.goldenLeaf.fixGoldenLeaf(rom) patches.heartPiece.fixHeartPiece(rom) patches.seashell.fixSeashell(rom) @@ -180,143 +176,95 @@ def generateRom(args, world: "LinksAwakeningWorld"): patches.songs.upgradeMarin(rom) patches.songs.upgradeManbo(rom) patches.songs.upgradeMamu(rom) - patches.tradeSequence.patchTradeSequence(rom, world.ladxr_settings) - patches.bowwow.fixBowwow(rom, everywhere=world.ladxr_settings.bowwow != 'normal') - if world.ladxr_settings.bowwow != 'normal': - patches.bowwow.bowwowMapPatches(rom) + + patches.tradeSequence.patchTradeSequence(rom, options) + patches.bowwow.fixBowwow(rom, everywhere=False) + # if ladxr_settings["bowwow"] != 'normal': + # patches.bowwow.bowwowMapPatches(rom) patches.desert.desertAccess(rom) - if world.ladxr_settings.overworld == 'dungeondive': - patches.overworld.patchOverworldTilesets(rom) - patches.overworld.createDungeonOnlyOverworld(rom) - elif world.ladxr_settings.overworld == 'nodungeons': - patches.dungeon.patchNoDungeons(rom) - elif world.ladxr_settings.overworld == 'random': - patches.overworld.patchOverworldTilesets(rom) - mapgen.store_map(rom, world.ladxr_logic.world.map) + # if ladxr_settings["overworld"] == 'dungeondive': + # patches.overworld.patchOverworldTilesets(rom) + # patches.overworld.createDungeonOnlyOverworld(rom) + # elif ladxr_settings["overworld"] == 'nodungeons': + # patches.dungeon.patchNoDungeons(rom) + #elif world.ladxr_settings["overworld"] == 'random': + # patches.overworld.patchOverworldTilesets(rom) + # mapgen.store_map(rom, world.ladxr_logic.world.map) #if settings.dungeon_items == 'keysy': # patches.dungeon.removeKeyDoors(rom) # patches.reduceRNG.slowdownThreeOfAKind(rom) patches.reduceRNG.fixHorseHeads(rom) patches.bomb.onlyDropBombsWhenHaveBombs(rom) - if world.options.music_change_condition == MusicChangeCondition.option_always: + if options["music_change_condition"] == Options.MusicChangeCondition.option_always: patches.aesthetics.noSwordMusic(rom) - patches.aesthetics.reduceMessageLengths(rom, world.random) + patches.aesthetics.reduceMessageLengths(rom, random) patches.aesthetics.allowColorDungeonSpritesEverywhere(rom) - if world.ladxr_settings.music == 'random': - patches.music.randomizeMusic(rom, world.random) - elif world.ladxr_settings.music == 'off': + if options["music"] == Options.Music.option_shuffled: + patches.music.randomizeMusic(rom, random) + elif options["music"] == Options.Music.option_off: patches.music.noMusic(rom) - if world.ladxr_settings.noflash: + if options["no_flash"]: patches.aesthetics.removeFlashingLights(rom) - if world.ladxr_settings.hardmode == "oracle": + if options["hard_mode"] == Options.HardMode.option_oracle: patches.hardMode.oracleMode(rom) - elif world.ladxr_settings.hardmode == "hero": + elif options["hard_mode"] == Options.HardMode.option_hero: patches.hardMode.heroMode(rom) - elif world.ladxr_settings.hardmode == "ohko": + elif options["hard_mode"] == Options.HardMode.option_ohko: patches.hardMode.oneHitKO(rom) - if world.ladxr_settings.superweapons: - patches.weapons.patchSuperWeapons(rom) - if world.ladxr_settings.textmode == 'fast': + #if ladxr_settings["superweapons"]: + # patches.weapons.patchSuperWeapons(rom) + if options["text_mode"] == Options.TextMode.option_fast: patches.aesthetics.fastText(rom) - if world.ladxr_settings.textmode == 'none': - patches.aesthetics.fastText(rom) - patches.aesthetics.noText(rom) - if not world.ladxr_settings.nagmessages: + #if ladxr_settings["textmode"] == 'none': + # patches.aesthetics.fastText(rom) + # patches.aesthetics.noText(rom) + if not options["nag_messages"]: patches.aesthetics.removeNagMessages(rom) - if world.ladxr_settings.lowhpbeep == 'slow': + if options["low_hp_beep"] == Options.LowHpBeep.option_slow: patches.aesthetics.slowLowHPBeep(rom) - if world.ladxr_settings.lowhpbeep == 'none': + if options["low_hp_beep"] == Options.LowHpBeep.option_none: patches.aesthetics.removeLowHPBeep(rom) - if 0 <= int(world.ladxr_settings.linkspalette): - patches.aesthetics.forceLinksPalette(rom, int(world.ladxr_settings.linkspalette)) + if 0 <= options["link_palette"]: + patches.aesthetics.forceLinksPalette(rom, options["link_palette"]) if args.romdebugmode: # The default rom has this build in, just need to set a flag and we get this save. rom.patch(0, 0x0003, "00", "01") # Patch the sword check on the shopkeeper turning around. - if world.ladxr_settings.steal == 'never': - rom.patch(4, 0x36F9, "FA4EDB", "3E0000") - elif world.ladxr_settings.steal == 'always': - rom.patch(4, 0x36F9, "FA4EDB", "3E0100") + #if ladxr_settings["steal"] == 'never': + # rom.patch(4, 0x36F9, "FA4EDB", "3E0000") + #elif ladxr_settings["steal"] == 'always': + # rom.patch(4, 0x36F9, "FA4EDB", "3E0100") - if world.ladxr_settings.hpmode == 'inverted': - patches.health.setStartHealth(rom, 9) - elif world.ladxr_settings.hpmode == '1': - patches.health.setStartHealth(rom, 1) + #if ladxr_settings["hpmode"] == 'inverted': + # patches.health.setStartHealth(rom, 9) + #elif ladxr_settings["hpmode"] == '1': + # patches.health.setStartHealth(rom, 1) patches.inventory.songSelectAfterOcarinaSelect(rom) - if world.ladxr_settings.quickswap == 'a': + if options["quickswap"] == 'a': patches.core.quickswap(rom, 1) - elif world.ladxr_settings.quickswap == 'b': + elif options["quickswap"] == 'b': patches.core.quickswap(rom, 0) - patches.core.addBootsControls(rom, world.options.boots_controls) - - - world_setup = world.ladxr_logic.world_setup - - JUNK_HINT = 0.33 - RANDOM_HINT= 0.66 - # USEFUL_HINT = 1.0 - # TODO: filter events, filter unshuffled keys - all_items = world.multiworld.get_items() - our_items = [item for item in all_items - if item.player == world.player - and item.location - and item.code is not None - and item.location.show_in_spoiler] - our_useful_items = [item for item in our_items if ItemClassification.progression in item.classification] - - def gen_hint(): - if not world.options.in_game_hints: - return 'Hints are disabled!' - chance = world.random.uniform(0, 1) - if chance < JUNK_HINT: - return None - elif chance < RANDOM_HINT: - location = world.random.choice(our_items).location - else: # USEFUL_HINT - location = world.random.choice(our_useful_items).location - - if location.item.player == world.player: - name = "Your" - else: - name = f"{world.multiworld.player_name[location.item.player]}'s" - # filter out { and } since they cause issues with string.format later on - name = name.replace("{", "").replace("}", "") - - if isinstance(location, LinksAwakeningLocation): - location_name = location.ladxr_item.metadata.name - else: - location_name = location.name - - hint = f"{name} {location.item.name} is at {location_name}" - if location.player != world.player: - # filter out { and } since they cause issues with string.format later on - player_name = world.multiworld.player_name[location.player].replace("{", "").replace("}", "") - hint += f" in {player_name}'s world" - - # Cap hint size at 85 - # Realistically we could go bigger but let's be safe instead - hint = hint[:85] - - return hint + patches.core.addBootsControls(rom, options["boots_controls"]) - hints.addHints(rom, world.random, gen_hint) + random.seed(patch_data["seed"] + patch_data["player"]) + hints.addHints(rom, random, patch_data["hint_texts"]) - if world_setup.goal == "raft": + if patch_data["world_setup"]["goal"] == "raft": patches.goal.setRaftGoal(rom) - elif world_setup.goal in ("bingo", "bingo-full"): - patches.bingo.setBingoGoal(rom, world_setup.bingo_goals, world_setup.goal) - elif world_setup.goal == "seashells": + elif patch_data["world_setup"]["goal"] in ("bingo", "bingo-full"): + patches.bingo.setBingoGoal(rom, patch_data["world_setup"]["bingo_goals"], patch_data["world_setup"]["goal"]) + elif patch_data["world_setup"]["goal"] == "seashells": patches.goal.setSeashellGoal(rom, 20) else: - patches.goal.setRequiredInstrumentCount(rom, world_setup.goal) + patches.goal.setRequiredInstrumentCount(rom, patch_data["world_setup"]["goal"]) # Patch the generated logic into the rom - patches.chest.setMultiChest(rom, world_setup.multichest) - if world.ladxr_settings.overworld not in {"dungeondive", "random"}: - patches.entrances.changeEntrances(rom, world_setup.entrance_mapping) + patches.chest.setMultiChest(rom, patch_data["world_setup"]["multichest"]) + #if ladxr_settings["overworld"] not in {"dungeondive", "random"}: + patches.entrances.changeEntrances(rom, patch_data["world_setup"]["entrance_mapping"]) for spot in item_list: if spot.item and spot.item.startswith("*"): spot.item = spot.item[1:] @@ -327,23 +275,22 @@ def gen_hint(): # There are only 101 player name slots (99 + "The Server" + "another world"), so don't use more than that mw = 100 spot.patch(rom, spot.item, multiworld=mw) - patches.enemies.changeBosses(rom, world_setup.boss_mapping) - patches.enemies.changeMiniBosses(rom, world_setup.miniboss_mapping) + patches.enemies.changeBosses(rom, patch_data["world_setup"]["boss_mapping"]) + patches.enemies.changeMiniBosses(rom, patch_data["world_setup"]["miniboss_mapping"]) if not args.romdebugmode: patches.core.addFrameCounter(rom, len(item_list)) patches.core.warpHome(rom) # Needs to be done after setting the start location. - patches.titleScreen.setRomInfo(rom, world.multi_key, world.multiworld.seed_name, world.ladxr_settings, - world.player_name, world.player) - if world.options.ap_title_screen: + patches.titleScreen.setRomInfo(rom, patch_data) + if options["ap_title_screen"]: patches.titleScreen.setTitleGraphics(rom) patches.endscreen.updateEndScreen(rom) patches.aesthetics.updateSpriteData(rom) if args.doubletrouble: patches.enemies.doubleTrouble(rom) - if world.options.text_shuffle: + if options["text_shuffle"]: excluded_ids = [ # Overworld owl statues 0x1B6, 0x1B7, 0x1B8, 0x1B9, 0x1BA, 0x1BB, 0x1BC, 0x1BD, 0x1BE, 0x22D, @@ -388,6 +335,7 @@ def gen_hint(): excluded_texts = [ rom.texts[excluded_id] for excluded_id in excluded_ids] buckets = defaultdict(list) # For each ROM bank, shuffle text within the bank + random.seed(patch_data["seed"] + patch_data["player"]) for n, data in enumerate(rom.texts._PointerTable__data): # Don't muck up which text boxes are questions and which are statements if type(data) != int and data and data != b'\xFF' and data not in excluded_texts: @@ -395,20 +343,20 @@ def gen_hint(): for bucket in buckets.values(): # For each bucket, make a copy and shuffle shuffled = bucket.copy() - world.random.shuffle(shuffled) + random.shuffle(shuffled) # Then put new text in for bucket_idx, (orig_idx, data) in enumerate(bucket): rom.texts[shuffled[bucket_idx][0]] = data - if world.options.trendy_game != TrendyGame.option_normal: + if options["trendy_game"] != Options.TrendyGame.option_normal: # TODO: if 0 or 4, 5, remove inaccurate conveyor tiles room_editor = RoomEditor(rom, 0x2A0) - if world.options.trendy_game == TrendyGame.option_easy: + if options["trendy_game"] == Options.TrendyGame.option_easy: # Set physics flag on all objects for i in range(0, 6): rom.banks[0x4][0x6F1E + i -0x4000] = 0x4 @@ -419,7 +367,7 @@ def gen_hint(): # Add new conveyor to "push" yoshi (it's only a visual) room_editor.objects.append(Object(5, 3, 0xD0)) - if world.options.trendy_game >= TrendyGame.option_harder: + if options["trendy_game"] >= Options.TrendyGame.option_harder: """ Data_004_76A0:: db $FC, $00, $04, $00, $00 @@ -428,17 +376,18 @@ def gen_hint(): db $00, $04, $00, $FC, $00 """ speeds = { - TrendyGame.option_harder: (3, 8), - TrendyGame.option_hardest: (3, 8), - TrendyGame.option_impossible: (3, 16), + Options.TrendyGame.option_harder: (3, 8), + Options.TrendyGame.option_hardest: (3, 8), + Options.TrendyGame.option_impossible: (3, 16), } def speed(): - return world.random.randint(*speeds[world.options.trendy_game]) + random.seed(patch_data["seed"] + patch_data["player"]) + return random.randint(*speeds[options["trendy_game"]]) rom.banks[0x4][0x76A0-0x4000] = 0xFF - speed() rom.banks[0x4][0x76A2-0x4000] = speed() rom.banks[0x4][0x76A6-0x4000] = speed() rom.banks[0x4][0x76A8-0x4000] = 0xFF - speed() - if world.options.trendy_game >= TrendyGame.option_hardest: + if options["trendy_game"] >= Options.TrendyGame.option_hardest: rom.banks[0x4][0x76A1-0x4000] = 0xFF - speed() rom.banks[0x4][0x76A3-0x4000] = speed() rom.banks[0x4][0x76A5-0x4000] = speed() @@ -462,11 +411,11 @@ def speed(): for channel in range(3): color[channel] = color[channel] * 31 // 0xbc - if world.options.warps != Warps.option_vanilla: - patches.core.addWarpImprovements(rom, world.options.warps == Warps.option_improved_additional) + if options["warps"] != Options.Warps.option_vanilla: + patches.core.addWarpImprovements(rom, options["warps"] == Options.Warps.option_improved_additional) - palette = world.options.palette - if palette != Palette.option_normal: + palette = options["palette"] + if palette != Options.Palette.option_normal: ranges = { # Object palettes # Overworld palettes @@ -496,22 +445,22 @@ def clamp(x, min, max): r,g,b = bin_to_rgb(packed) # 1 bit - if palette == Palette.option_1bit: + if palette == Options.Palette.option_1bit: r &= 0b10000 g &= 0b10000 b &= 0b10000 # 2 bit - elif palette == Palette.option_1bit: + elif palette == Options.Palette.option_1bit: r &= 0b11000 g &= 0b11000 b &= 0b11000 # Invert - elif palette == Palette.option_inverted: + elif palette == Options.Palette.option_inverted: r = 31 - r g = 31 - g b = 31 - b # Pink - elif palette == Palette.option_pink: + elif palette == Options.Palette.option_pink: r = r // 2 r += 16 r = int(r) @@ -520,7 +469,7 @@ def clamp(x, min, max): b += 16 b = int(b) b = clamp(b, 0, 0x1F) - elif palette == Palette.option_greyscale: + elif palette == Options.Palette.option_greyscale: # gray=int(0.299*r+0.587*g+0.114*b) gray = (r + g + b) // 3 r = g = b = gray @@ -531,10 +480,10 @@ def clamp(x, min, max): SEED_LOCATION = 0x0134 # Patch over the title - assert(len(world.multi_key) == 12) - rom.patch(0x00, SEED_LOCATION, None, binascii.hexlify(world.multi_key)) + assert(len(multi_key) == 12) + rom.patch(0x00, SEED_LOCATION, None, binascii.hexlify(multi_key)) for pymod in pymods: pymod.postPatch(rom) - return rom + return rom.save() diff --git a/worlds/ladx/LADXR/hints.py b/worlds/ladx/LADXR/hints.py index aa7854889bb6..6f9f3e60f4a9 100644 --- a/worlds/ladx/LADXR/hints.py +++ b/worlds/ladx/LADXR/hints.py @@ -1,5 +1,7 @@ from .locations.items import * from .utils import formatText +from BaseClasses import ItemClassification +from ..Locations import LinksAwakeningLocation hint_text_ids = [ @@ -49,14 +51,64 @@ ] -def addHints(rom, rnd, hint_generator): +def addHints(rom, rnd, hint_texts): + hint_texts_copy = hint_texts.copy() text_ids = hint_text_ids.copy() rnd.shuffle(text_ids) for text_id in text_ids: - hint = hint_generator() + hint = hint_texts_copy.pop() if not hint: hint = rnd.choice(hints).format(*rnd.choice(useless_hint)) rom.texts[text_id] = formatText(hint) for text_id in range(0x200, 0x20C, 2): rom.texts[text_id] = formatText("Read this book?", ask="YES NO") + + +def generate_hint_texts(world): + JUNK_HINT = 0.33 + RANDOM_HINT= 0.66 + # USEFUL_HINT = 1.0 + # TODO: filter events, filter unshuffled keys + all_items = world.multiworld.get_items() + our_items = [item for item in all_items + if item.player == world.player + and item.location + and item.code is not None + and item.location.show_in_spoiler] + our_useful_items = [item for item in our_items if ItemClassification.progression in item.classification] + hint_texts = [] + def gen_hint(): + chance = world.random.uniform(0, 1) + if chance < JUNK_HINT: + return None + elif chance < RANDOM_HINT: + location = world.random.choice(our_items).location + else: # USEFUL_HINT + location = world.random.choice(our_useful_items).location + + if location.item.player == world.player: + name = "Your" + else: + name = f"{world.multiworld.player_name[location.item.player]}'s" + # filter out { and } since they cause issues with string.format later on + name = name.replace("{", "").replace("}", "") + + if isinstance(location, LinksAwakeningLocation): + location_name = location.ladxr_item.metadata.name + else: + location_name = location.name + + hint = f"{name} {location.item} is at {location_name}" + if location.player != world.player: + # filter out { and } since they cause issues with string.format later on + player_name = world.multiworld.player_name[location.player].replace("{", "").replace("}", "") + hint += f" in {player_name}'s world" + + # Cap hint size at 85 + # Realistically we could go bigger but let's be safe instead + hint = hint[:85] + return hint + for _ in hint_text_ids: + hint_texts.append(gen_hint()) + return hint_texts diff --git a/worlds/ladx/LADXR/patches/core.py b/worlds/ladx/LADXR/patches/core.py index d9fcd62e3060..10e85f9dc506 100644 --- a/worlds/ladx/LADXR/patches/core.py +++ b/worlds/ladx/LADXR/patches/core.py @@ -541,7 +541,7 @@ def addFrameCounter(rom, check_count): rom.banks[0x38][0x1400+n*0x20:0x1410+n*0x20] = utils.createTileData(gfx_high) rom.banks[0x38][0x1410+n*0x20:0x1420+n*0x20] = utils.createTileData(gfx_low) -def addBootsControls(rom, boots_controls: BootsControls): +def addBootsControls(rom, boots_controls: int): if boots_controls == BootsControls.option_vanilla: return consts = { @@ -578,7 +578,7 @@ def addBootsControls(rom, boots_controls: BootsControls): jr z, .yesBoots ld a, [hl] """ - }[boots_controls.value] + }[boots_controls] # The new code fits exactly within Nintendo's poorly space optimzied code while having more features boots_code = assembler.ASM(""" diff --git a/worlds/ladx/LADXR/patches/enemies.py b/worlds/ladx/LADXR/patches/enemies.py index f5e1df131356..29322918f262 100644 --- a/worlds/ladx/LADXR/patches/enemies.py +++ b/worlds/ladx/LADXR/patches/enemies.py @@ -42,7 +42,7 @@ "ARMOS_KNIGHT": [(4, 3, 0x88)], } MINIBOSS_ROOMS = { - 0: 0x111, 1: 0x128, 2: 0x145, 3: 0x164, 4: 0x193, 5: 0x1C5, 6: 0x228, 7: 0x23F, + "0": 0x111, "1": 0x128, "2": 0x145, "3": 0x164, "4": 0x193, "5": 0x1C5, "6": 0x228, "7": 0x23F, "c1": 0x30C, "c2": 0x303, "moblin_cave": 0x2E1, "armos_temple": 0x27F, diff --git a/worlds/ladx/LADXR/patches/titleScreen.py b/worlds/ladx/LADXR/patches/titleScreen.py index 3a4dade2185d..d986a570ef88 100644 --- a/worlds/ladx/LADXR/patches/titleScreen.py +++ b/worlds/ladx/LADXR/patches/titleScreen.py @@ -1,7 +1,6 @@ from ..backgroundEditor import BackgroundEditor from .aesthetics import rgb_to_bin, bin_to_rgb, prepatch import copy -import pkgutil CHAR_MAP = {'z': 0x3E, '-': 0x3F, '.': 0x39, ':': 0x42, '?': 0x3C, '!': 0x3D} def _encode(s): @@ -18,17 +17,18 @@ def _encode(s): return result -def setRomInfo(rom, seed, seed_name, settings, player_name, player_id): +def setRomInfo(rom, patch_data): + seed_name = patch_data["seed_name"] try: - seednr = int(seed, 16) + seednr = int(patch_data["seed"], 16) except: import hashlib - seednr = int(hashlib.md5(seed).hexdigest(), 16) + seednr = int(hashlib.md5(str(patch_data["seed"]).encode()).hexdigest(), 16) - if settings.race: + if patch_data["is_race"]: seed_name = "Race" - if isinstance(settings.race, str): - seed_name += " " + settings.race + if isinstance(patch_data["is_race"], str): + seed_name += " " + patch_data["is_race"] rom.patch(0x00, 0x07, "00", "01") else: rom.patch(0x00, 0x07, "00", "52") @@ -37,7 +37,7 @@ def setRomInfo(rom, seed, seed_name, settings, player_name, player_id): #line_2_hex = _encode(seed[16:]) BASE_DRAWING_AREA = 0x98a0 LINE_WIDTH = 0x20 - player_id_text = f"Player {player_id}:" + player_id_text = f"Player {patch_data['player']}:" for n in (3, 4): be = BackgroundEditor(rom, n) ba = BackgroundEditor(rom, n, attributes=True) @@ -45,9 +45,9 @@ def setRomInfo(rom, seed, seed_name, settings, player_name, player_id): for n, v in enumerate(_encode(player_id_text)): be.tiles[BASE_DRAWING_AREA + LINE_WIDTH * 5 + 2 + n] = v ba.tiles[BASE_DRAWING_AREA + LINE_WIDTH * 5 + 2 + n] = 0x00 - for n, v in enumerate(_encode(player_name)): - be.tiles[BASE_DRAWING_AREA + LINE_WIDTH * 6 + 0x13 - len(player_name) + n] = v - ba.tiles[BASE_DRAWING_AREA + LINE_WIDTH * 6 + 0x13 - len(player_name) + n] = 0x00 + for n, v in enumerate(_encode(patch_data['player_name'])): + be.tiles[BASE_DRAWING_AREA + LINE_WIDTH * 6 + 0x13 - len(patch_data['player_name']) + n] = v + ba.tiles[BASE_DRAWING_AREA + LINE_WIDTH * 6 + 0x13 - len(patch_data['player_name']) + n] = 0x00 for n, v in enumerate(line_1_hex): be.tiles[0x9a20 + n] = v ba.tiles[0x9a20 + n] = 0x00 diff --git a/worlds/ladx/LADXR/patches/tradeSequence.py b/worlds/ladx/LADXR/patches/tradeSequence.py index 0eb46ae23ae2..ef6f635d4509 100644 --- a/worlds/ladx/LADXR/patches/tradeSequence.py +++ b/worlds/ladx/LADXR/patches/tradeSequence.py @@ -387,7 +387,7 @@ def patchVarious(rom, settings): # Boomerang trade guy # if settings.boomerang not in {'trade', 'gift'} or settings.overworld in {'normal', 'nodungeons'}: - if settings.tradequest: + if settings["tradequest"]: # Update magnifier checks rom.patch(0x19, 0x05EC, ASM("ld a, [wTradeSequenceItem]\ncp $0E\njp nz, $7E61"), ASM("ld a, [wTradeSequenceItem2]\nand $20\njp z, $7E61")) # show the guy rom.patch(0x00, 0x3199, ASM("ld a, [wTradeSequenceItem]\ncp $0E\njr nz, $06"), ASM("ld a, [wTradeSequenceItem2]\nand $20\njr z, $06")) # load the proper room layout diff --git a/worlds/ladx/LADXR/rom.py b/worlds/ladx/LADXR/rom.py index 21969f4ab4ed..54d8f029160e 100644 --- a/worlds/ladx/LADXR/rom.py +++ b/worlds/ladx/LADXR/rom.py @@ -7,9 +7,7 @@ class ROM: - def __init__(self, filename, patches=None): - data = open(Utils.user_path(filename), "rb").read() - + def __init__(self, data, patches=None): if patches: for patch in patches: data = bsdiff4.patch(data, patch) @@ -64,18 +62,10 @@ def fixHeader(self, *, name=None): self.banks[0][0x14E] = checksum >> 8 self.banks[0][0x14F] = checksum & 0xFF - def save(self, file, *, name=None): + def save(self): # don't pass the name to fixHeader self.fixHeader() - if isinstance(file, str): - f = open(file, "wb") - for bank in self.banks: - f.write(bank) - f.close() - print("Saved:", file) - else: - for bank in self.banks: - file.write(bank) + return b"".join(self.banks) def readHexSeed(self): return self.banks[0x3E][0x2F00:0x2F10].hex().upper() diff --git a/worlds/ladx/LADXR/romTables.py b/worlds/ladx/LADXR/romTables.py index 3192443685d7..51acacc31c56 100644 --- a/worlds/ladx/LADXR/romTables.py +++ b/worlds/ladx/LADXR/romTables.py @@ -181,8 +181,8 @@ def __init__(self, rom): class ROMWithTables(ROM): - def __init__(self, filename, patches=None): - super().__init__(filename, patches) + def __init__(self, data, patches=None): + super().__init__(data, patches) # Ability to patch any text in the game with different text self.texts = Texts(self) @@ -203,7 +203,7 @@ def __init__(self, filename, patches=None): self.itemNames = {} - def save(self, filename, *, name=None): + def save(self): # Assert special handling of bank 9 expansion is fine for i in range(0x3d42, 0x4000): assert self.banks[9][i] == 0, self.banks[9][i] @@ -221,4 +221,4 @@ def save(self, filename, *, name=None): self.room_sprite_data_indoor.store(self) self.background_tiles.store(self) self.background_attributes.store(self) - super().save(filename, name=name) + return super().save() diff --git a/worlds/ladx/Options.py b/worlds/ladx/Options.py index 7ea7df36597c..8abfb0fbc958 100644 --- a/worlds/ladx/Options.py +++ b/worlds/ladx/Options.py @@ -425,46 +425,11 @@ class TrendyGame(Choice): default = option_normal -class GfxMod(FreeText, LADXROption): +class GfxMod(DefaultOffToggle): """ - Sets the sprite for link, among other things - The option should be the same name as a with sprite (and optional name) file in data/sprites/ladx + If enabled, the patcher will prompt the user for a modification file to change sprites in the game and optionally some text. """ display_name = "GFX Modification" - ladxr_name = "gfxmod" - normal = '' - default = 'Link' - - __spriteDir: str = Utils.local_path(os.path.join('data', 'sprites', 'ladx')) - __spriteFiles: typing.DefaultDict[str, typing.List[str]] = defaultdict(list) - - extensions = [".bin", ".bdiff", ".png", ".bmp"] - - for file in os.listdir(__spriteDir): - name, extension = os.path.splitext(file) - if extension in extensions: - __spriteFiles[name].append(file) - - def __init__(self, value: str): - super().__init__(value) - - def verify(self, world, player_name: str, plando_options) -> None: - if self.value == "Link" or self.value in GfxMod.__spriteFiles: - return - raise Exception( - f"LADX Sprite '{self.value}' not found. Possible sprites are: {['Link'] + list(GfxMod.__spriteFiles.keys())}") - - def to_ladxr_option(self, all_options): - if self.value == -1 or self.value == "Link": - return None, None - - assert self.value in GfxMod.__spriteFiles - - if len(GfxMod.__spriteFiles[self.value]) > 1: - logger.warning( - f"{self.value} does not uniquely identify a file. Possible matches: {GfxMod.__spriteFiles[self.value]}. Using {GfxMod.__spriteFiles[self.value][0]}") - - return self.ladxr_name, self.__spriteDir + "/" + GfxMod.__spriteFiles[self.value][0] class Palette(Choice): diff --git a/worlds/ladx/Rom.py b/worlds/ladx/Rom.py index 8ae1fac0fa31..969215a5e486 100644 --- a/worlds/ladx/Rom.py +++ b/worlds/ladx/Rom.py @@ -3,19 +3,112 @@ import hashlib import Utils import os +import json +import pkgutil +import bsdiff4 +import binascii +import pickle +from typing import TYPE_CHECKING +from .Common import * +from .LADXR import generator +from .LADXR.main import get_parser +from .LADXR.hints import generate_hint_texts +from .LADXR.locations.keyLocation import KeyLocation LADX_HASH = "07c211479386825042efb4ad31bb525f" -class LADXDeltaPatch(worlds.Files.APDeltaPatch): +if TYPE_CHECKING: + from . import LinksAwakeningWorld + + +class LADXPatchExtensions(worlds.Files.APPatchExtension): + game = LINKS_AWAKENING + + @staticmethod + def generate_rom(caller: worlds.Files.APProcedurePatch, rom: bytes, data_file: str) -> bytes: + patch_data = json.loads(caller.get_file(data_file).decode("utf-8")) + # TODO local option overrides + rom_name = get_base_rom_path() + out_name = f"{patch_data['out_base']}{caller.result_file_ending}" + parser = get_parser() + args = parser.parse_args([rom_name, "-o", out_name, "--dump"]) + return generator.generateRom(rom, args, patch_data) + + @staticmethod + def patch_title_screen(caller: worlds.Files.APProcedurePatch, rom: bytes, data_file: str) -> bytes: + patch_data = json.loads(caller.get_file(data_file).decode("utf-8")) + if patch_data["options"]["ap_title_screen"]: + return bsdiff4.patch(rom, pkgutil.get_data(__name__, "LADXR/patches/title_screen.bdiff4")) + return rom + +class LADXProcedurePatch(worlds.Files.APProcedurePatch): hash = LADX_HASH - game = "Links Awakening DX" - patch_file_ending = ".apladx" + game = LINKS_AWAKENING + patch_file_ending: str = ".apladx" result_file_ending: str = ".gbc" + procedure = [ + ("generate_rom", ["data.json"]), + ("patch_title_screen", ["data.json"]) + ] + @classmethod def get_source_data(cls) -> bytes: return get_base_rom_bytes() +def write_patch_data(world: "LinksAwakeningWorld", patch: LADXProcedurePatch): + item_list = pickle.dumps([item for item in world.ladxr_logic.iteminfo_list if not isinstance(item, KeyLocation)]) + data_dict = { + "out_base": world.multiworld.get_out_file_name_base(patch.player), + "is_race": world.multiworld.is_race, + "seed": world.multiworld.seed, + "seed_name": world.multiworld.seed_name, + "multi_key": binascii.hexlify(world.multi_key).decode(), + "player": patch.player, + "player_name": patch.player_name, + "other_player_names": list(world.multiworld.player_name.values()), + "item_list": binascii.hexlify(item_list).decode(), + "hint_texts": generate_hint_texts(world), + "world_setup": { + "goal": world.ladxr_logic.world_setup.goal, + "bingo_goals": world.ladxr_logic.world_setup.bingo_goals, + "multichest": world.ladxr_logic.world_setup.multichest, + "entrance_mapping": world.ladxr_logic.world_setup.entrance_mapping, + "boss_mapping": world.ladxr_logic.world_setup.boss_mapping, + "miniboss_mapping": world.ladxr_logic.world_setup.miniboss_mapping, + }, + "options": world.options.as_dict( + "tradequest", + "rooster", + "experimental_dungeon_shuffle", + "experimental_entrance_shuffle", + "goal", + "instrument_count", + "link_palette", + "warps", + "trendy_game", + "gfxmod", + "palette", + "text_shuffle", + "shuffle_nightmare_keys", + "shuffle_small_keys", + "music", + "music_change_condition", + "nag_messages", + "ap_title_screen", + "boots_controls", + # "stealing", + "quickswap", + "hard_mode", + "low_hp_beep", + "text_mode", + "no_flash", + "overworld", + ), + } + patch.write_file("data.json", json.dumps(data_dict).encode('utf-8')) + + def get_base_rom_bytes(file_name: str = "") -> bytes: base_rom_bytes = getattr(get_base_rom_bytes, "base_rom_bytes", None) if not base_rom_bytes: diff --git a/worlds/ladx/__init__.py b/worlds/ladx/__init__.py index b1b033e01d23..f17b602ed13d 100644 --- a/worlds/ladx/__init__.py +++ b/worlds/ladx/__init__.py @@ -1,16 +1,12 @@ import binascii import dataclasses import os -import pkgutil -import tempfile import typing import logging import re -import bsdiff4 - import settings -from BaseClasses import CollectionState, Entrance, Item, ItemClassification, Location, Tutorial, MultiWorld +from BaseClasses import CollectionState, Entrance, Item, ItemClassification, Location, Tutorial from Fill import fill_restrictive from worlds.AutoWorld import WebWorld, World from .Common import * @@ -18,19 +14,17 @@ from .Items import (DungeonItemData, DungeonItemType, ItemName, LinksAwakeningItem, TradeItemData, ladxr_item_to_la_item_name, links_awakening_items, links_awakening_items_by_name, links_awakening_item_name_groups) -from .LADXR import generator from .LADXR.itempool import ItemPool as LADXRItemPool from .LADXR.locations.constants import CHEST_ITEMS from .LADXR.locations.instrument import Instrument from .LADXR.logic import Logic as LADXRLogic -from .LADXR.main import get_parser from .LADXR.settings import Settings as LADXRSettings from .LADXR.worldSetup import WorldSetup as LADXRWorldSetup from .Locations import (LinksAwakeningLocation, LinksAwakeningRegion, create_regions_from_ladxr, get_locations_to_id, links_awakening_location_name_groups) from .Options import DungeonItemShuffle, ShuffleInstruments, LinksAwakeningOptions, ladx_option_groups -from .Rom import LADXDeltaPatch, get_base_rom_path +from .Rom import LADXProcedurePatch, write_patch_data DEVELOPER_MODE = False @@ -40,7 +34,7 @@ class RomFile(settings.UserFilePath): """File name of the Link's Awakening DX rom""" copy_to = "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (SGB Enhanced).gbc" description = "LADX ROM File" - md5s = [LADXDeltaPatch.hash] + md5s = [LADXProcedurePatch.hash] class RomStart(str): """ @@ -57,8 +51,16 @@ class RomStart(str): class DisplayMsgs(settings.Bool): """Display message inside of Bizhawk""" + class GfxModFile(settings.FilePath): + """ + Gfxmod file, get it from upstream: https://github.com/daid/LADXR/tree/master/gfx + Only .bin or .bdiff files + The same directory will be checked for a matching text modification file + """ + rom_file: RomFile = RomFile(RomFile.copy_to) rom_start: typing.Union[RomStart, bool] = True + gfx_mod_file: GfxModFile = GfxModFile() class LinksAwakeningWebWorld(WebWorld): tutorials = [Tutorial( @@ -179,10 +181,10 @@ def create_regions(self) -> None: assert(start) - menu_region = LinksAwakeningRegion("Menu", None, "Menu", self.player, self.multiworld) + menu_region = LinksAwakeningRegion("Menu", None, "Menu", self.player, self.multiworld) menu_region.exits = [Entrance(self.player, "Start Game", menu_region)] menu_region.exits[0].connect(start) - + self.multiworld.regions.append(menu_region) # Place RAFT, other access events @@ -190,14 +192,14 @@ def create_regions(self) -> None: for loc in region.locations: if loc.address is None: loc.place_locked_item(self.create_event(loc.ladxr_item.event)) - + # Connect Windfish -> Victory windfish = self.multiworld.get_region("Windfish", self.player) l = Location(self.player, "Windfish", parent=windfish) windfish.locations = [l] - + l.place_locked_item(self.create_event("An Alarm Clock")) - + self.multiworld.completion_condition[self.player] = lambda state: state.has("An Alarm Clock", player=self.player) def create_item(self, item_name: str): @@ -279,8 +281,8 @@ def create_items(self) -> None: event_location = Location(self.player, "Can Play Trendy Game", parent=trendy_region) trendy_region.locations.insert(0, event_location) event_location.place_locked_item(self.create_event("Can Play Trendy Game")) - - self.dungeon_locations_by_dungeon = [[], [], [], [], [], [], [], [], []] + + self.dungeon_locations_by_dungeon = [[], [], [], [], [], [], [], [], []] for r in self.multiworld.get_regions(self.player): # Set aside dungeon locations if r.dungeon_index: @@ -354,7 +356,7 @@ def pre_fill(self) -> None: # set containing the list of all possible dungeon locations for the player all_dungeon_locs = set() - + # Do dungeon specific things for dungeon_index in range(0, 9): # set up allow-list for dungeon specific items @@ -367,7 +369,7 @@ def pre_fill(self) -> None: # ...also set the rules for the dungeon for location in locs: orig_rule = location.item_rule - # If an item is about to be placed on a dungeon location, it can go there iff + # If an item is about to be placed on a dungeon location, it can go there iff # 1. it fits the general rules for that location (probably 'return True' for most places) # 2. Either # 2a. it's not a restricted dungeon item @@ -421,7 +423,7 @@ def priority(item): partial_all_state.sweep_for_advancements() fill_restrictive(self.multiworld, partial_all_state, all_dungeon_locs_to_fill, all_dungeon_items_to_fill, lock=True, single_player_placement=True, allow_partial=False) - + name_cache = {} # Tries to associate an icon from another game with an icon we have @@ -458,22 +460,16 @@ def guess_icon_for_other_world(self, foreign_item): for name in possibles: if name in self.name_cache: return self.name_cache[name] - + return "TRADING_ITEM_LETTER" - @classmethod - def stage_assert_generate(cls, multiworld: MultiWorld): - rom_file = get_base_rom_path() - if not os.path.exists(rom_file): - raise FileNotFoundError(rom_file) - def generate_output(self, output_directory: str): # copy items back to locations for r in self.multiworld.get_regions(self.player): for loc in r.locations: if isinstance(loc, LinksAwakeningLocation): assert(loc.item) - + # If we're a links awakening item, just use the item if isinstance(loc.item, LinksAwakeningItem): loc.ladxr_item.item = loc.item.item_data.ladxr_id @@ -499,31 +495,13 @@ def generate_output(self, output_directory: str): # Kind of kludge, make it possible for the location to differentiate between local and remote items loc.ladxr_item.location_owner = self.player - rom_name = Rom.get_base_rom_path() - out_name = f"AP-{self.multiworld.seed_name}-P{self.player}-{self.player_name}.gbc" - out_path = os.path.join(output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}.gbc") - - parser = get_parser() - args = parser.parse_args([rom_name, "-o", out_name, "--dump"]) - - rom = generator.generateRom(args, self) - - with open(out_path, "wb") as handle: - rom.save(handle, name="LADXR") - - # Write title screen after everything else is done - full gfxmods may stomp over the egg tiles - if self.options.ap_title_screen: - with tempfile.NamedTemporaryFile(delete=False) as title_patch: - title_patch.write(pkgutil.get_data(__name__, "LADXR/patches/title_screen.bdiff4")) - - bsdiff4.file_patch_inplace(out_path, title_patch.name) - os.unlink(title_patch.name) + + patch = LADXProcedurePatch(player=self.player, player_name=self.player_name) + write_patch_data(self, patch) + out_path = os.path.join(output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}" + f"{patch.patch_file_ending}") - patch = LADXDeltaPatch(os.path.splitext(out_path)[0]+LADXDeltaPatch.patch_file_ending, player=self.player, - player_name=self.player_name, patched_path=out_path) - patch.write() - if not DEVELOPER_MODE: - os.unlink(out_path) + patch.write(out_path) def generate_multi_key(self): return bytearray(self.random.getrandbits(8) for _ in range(10)) + self.player.to_bytes(2, 'big') From 774457b362d4497b3dba07231db7e3b39c147f0c Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Sat, 26 Jul 2025 16:25:06 -0400 Subject: [PATCH 0610/1218] LTTP: Add Missing Crystal Switch Logic (#4638) --- worlds/alttp/Rules.py | 17 +++++++++++------ worlds/alttp/test/dungeons/TestMiseryMire.py | 4 ++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index 2d11d537fbe8..b79170dac2cf 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -463,12 +463,15 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_location('Misery Mire - Big Chest', player), lambda state: state.has('Big Key (Misery Mire)', player)) set_rule(multiworld.get_location('Misery Mire - Spike Chest', player), lambda state: (world.can_take_damage and has_hearts(state, player, 4)) or state.has('Cane of Byrna', player) or state.has('Cape', player)) set_rule(multiworld.get_entrance('Misery Mire Big Key Door', player), lambda state: state.has('Big Key (Misery Mire)', player)) - # How to access crystal switch: - # If have big key: then you will need 2 small keys to be able to hit switch and return to main area, as you can burn key in dark room - # If not big key: cannot burn key in dark room, hence need only 1 key. all doors immediately available lead to a crystal switch. - # The listed chests are those which can be reached if you can reach a crystal switch. - set_rule(multiworld.get_location('Misery Mire - Map Chest', player), lambda state: state._lttp_has_key('Small Key (Misery Mire)', player, 2)) - set_rule(multiworld.get_location('Misery Mire - Main Lobby', player), lambda state: state._lttp_has_key('Small Key (Misery Mire)', player, 2)) + + # The most number of keys you can burn without opening the map chest and without reaching a crystal switch is 1, + # but if you cannot activate a crystal switch except by throwing a pot, you could burn another two going through + # the conveyor crystal room. + set_rule(multiworld.get_location('Misery Mire - Map Chest', player), lambda state: (state._lttp_has_key('Small Key (Misery Mire)', player, 2) and can_activate_crystal_switch(state, player)) or state._lttp_has_key('Small Key (Misery Mire)', player, 4)) + # Using a key on the map door chest will get you the map chest but not a crystal switch. Main Lobby should require + # one more key. + set_rule(multiworld.get_location('Misery Mire - Main Lobby', player), lambda state: (state._lttp_has_key('Small Key (Misery Mire)', player, 3) and can_activate_crystal_switch(state, player)) or state._lttp_has_key('Small Key (Misery Mire)', player, 5)) + # we can place a small key in the West wing iff it also contains/blocks the Big Key, as we cannot reach and softlock with the basement key door yet set_rule(multiworld.get_location('Misery Mire - Conveyor Crystal Key Drop', player), lambda state: state._lttp_has_key('Small Key (Misery Mire)', player, 4) @@ -542,6 +545,8 @@ def global_rules(multiworld: MultiWorld, player: int): set_rule(multiworld.get_location('Ganons Tower - Bob\'s Torch', player), lambda state: state.has('Pegasus Boots', player)) set_rule(multiworld.get_entrance('Ganons Tower (Tile Room)', player), lambda state: state.has('Cane of Somaria', player)) set_rule(multiworld.get_entrance('Ganons Tower (Hookshot Room)', player), lambda state: state.has('Hammer', player) and (state.has('Hookshot', player) or state.has('Pegasus Boots', player))) + set_rule(multiworld.get_location('Ganons Tower - Double Switch Pot Key', player), lambda state: state.has('Cane of Somaria', player) or can_use_bombs(state, player)) + set_rule(multiworld.get_entrance('Ganons Tower (Double Switch Room)', player), lambda state: state.has('Cane of Somaria', player) or can_use_bombs(state, player)) if world.options.pot_shuffle: set_rule(multiworld.get_location('Ganons Tower - Conveyor Cross Pot Key', player), lambda state: state.has('Hammer', player) and (state.has('Hookshot', player) or state.has('Pegasus Boots', player))) set_rule(multiworld.get_entrance('Ganons Tower (Map Room)', player), lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 8) or ( diff --git a/worlds/alttp/test/dungeons/TestMiseryMire.py b/worlds/alttp/test/dungeons/TestMiseryMire.py index 90b7055b764a..b44d7d1bee95 100644 --- a/worlds/alttp/test/dungeons/TestMiseryMire.py +++ b/worlds/alttp/test/dungeons/TestMiseryMire.py @@ -32,8 +32,8 @@ def testMiseryMire(self): ["Misery Mire - Main Lobby", False, []], ["Misery Mire - Main Lobby", False, [], ['Pegasus Boots', 'Hookshot']], ["Misery Mire - Main Lobby", False, [], ['Small Key (Misery Mire)', 'Big Key (Misery Mire)']], - ["Misery Mire - Main Lobby", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Hookshot', 'Progressive Sword']], - ["Misery Mire - Main Lobby", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Pegasus Boots', 'Progressive Sword']], + ["Misery Mire - Main Lobby", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Hookshot', 'Progressive Sword']], + ["Misery Mire - Main Lobby", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Pegasus Boots', 'Progressive Sword']], ["Misery Mire - Big Key Chest", False, []], ["Misery Mire - Big Key Chest", False, [], ['Fire Rod', 'Lamp']], From de4014f02c3cbf199b35e046ea3b65da57670b89 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 26 Jul 2025 16:30:55 -0400 Subject: [PATCH 0611/1218] Core/Tests: No Locality Changes After `generate_early` (#4481) * Change timing of locality option locking * Update world api.md * Remove whitespace --- Main.py | 19 ++++++++++--------- docs/world api.md | 1 + test/general/test_items.py | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Main.py b/Main.py index 456820a461f7..8bbbd74b10bb 100644 --- a/Main.py +++ b/Main.py @@ -93,6 +93,15 @@ def main(args, seed=None, baked_server_options: dict[str, object] | None = None) del local_early del early + # items can't be both local and non-local, prefer local + multiworld.worlds[player].options.non_local_items.value -= multiworld.worlds[player].options.local_items.value + multiworld.worlds[player].options.non_local_items.value -= set(multiworld.local_early_items[player]) + + # Clear non-applicable local and non-local items. + if multiworld.players == 1: + multiworld.worlds[1].options.non_local_items.value = set() + multiworld.worlds[1].options.local_items.value = set() + logger.info('Creating MultiWorld.') AutoWorld.call_all(multiworld, "create_regions") @@ -100,12 +109,6 @@ def main(args, seed=None, baked_server_options: dict[str, object] | None = None) AutoWorld.call_all(multiworld, "create_items") logger.info('Calculating Access Rules.') - - for player in multiworld.player_ids: - # items can't be both local and non-local, prefer local - multiworld.worlds[player].options.non_local_items.value -= multiworld.worlds[player].options.local_items.value - multiworld.worlds[player].options.non_local_items.value -= set(multiworld.local_early_items[player]) - AutoWorld.call_all(multiworld, "set_rules") for player in multiworld.player_ids: @@ -126,11 +129,9 @@ def main(args, seed=None, baked_server_options: dict[str, object] | None = None) multiworld.worlds[player].options.priority_locations.value -= world_excluded_locations # Set local and non-local item rules. + # This function is called so late because worlds might otherwise overwrite item_rules which are how locality works if multiworld.players > 1: locality_rules(multiworld) - else: - multiworld.worlds[1].options.non_local_items.value = set() - multiworld.worlds[1].options.local_items.value = set() multiworld.plando_item_blocks = parse_planned_blocks(multiworld) diff --git a/docs/world api.md b/docs/world api.md index 677b1636e6be..3bf4821924e0 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -515,6 +515,7 @@ In addition, the following methods can be implemented and are called in this ord called per player before any items or locations are created. You can set properties on your world here. Already has access to player options and RNG. This is the earliest step where the world should start setting up for the current multiworld, as the multiworld itself is still setting up before this point. + You cannot modify `local_items`, or `non_local_items` after this step. * `create_regions(self)` called to place player's regions and their locations into the MultiWorld's regions list. If it's hard to separate, this can be done during `generate_early` or `create_items` as well. diff --git a/test/general/test_items.py b/test/general/test_items.py index 1b376b28385c..dbaca1c91c74 100644 --- a/test/general/test_items.py +++ b/test/general/test_items.py @@ -148,8 +148,8 @@ def test_itempool_not_modified(self): def test_locality_not_modified(self): """Test that worlds don't modify the locality of items after duplicates are resolved""" - gen_steps = ("generate_early", "create_regions", "create_items") - additional_steps = ("set_rules", "connect_entrances", "generate_basic", "pre_fill") + gen_steps = ("generate_early",) + additional_steps = ("create_regions", "create_items", "set_rules", "connect_entrances", "generate_basic", "pre_fill") worlds_to_test = {game: world for game, world in AutoWorldRegister.world_types.items()} for game_name, world_type in worlds_to_test.items(): with self.subTest("Game", game=game_name): From a36e6259f1cb6d11a5fa79637778ad70e754860c Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Sat, 26 Jul 2025 15:01:40 -0600 Subject: [PATCH 0612/1218] Core: Add `restricted_dumps` helper (#5117) * Add pickling helper that check unpicklability * Add test condition and generation error handling * Fix incorrect call and make imports consistent * Fix newline padding * Change PicklingError to directly caused by UnpicklingError Co-authored-by: Doug Hoskisson * Revert to `pickle.dumps` for decompressed multidata * Fix import order * Restore pickle import in main * Re-add for multidata in Main * Remove multisave checks * Update MultiServer.py * Update customserver.py --------- Co-authored-by: Doug Hoskisson Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- Main.py | 5 ++--- MultiServer.py | 1 + Utils.py | 12 ++++++++++++ WebHostLib/api/generate.py | 4 ++-- WebHostLib/customserver.py | 3 ++- WebHostLib/generate.py | 22 ++++++++++++++-------- WebHostLib/upload.py | 1 - test/general/test_options.py | 10 ++++++---- 8 files changed, 39 insertions(+), 19 deletions(-) diff --git a/Main.py b/Main.py index 8bbbd74b10bb..fd7d8d9ab72d 100644 --- a/Main.py +++ b/Main.py @@ -2,7 +2,6 @@ import concurrent.futures import logging import os -import pickle import tempfile import time import zipfile @@ -14,7 +13,7 @@ parse_planned_blocks, distribute_planned_blocks, resolve_early_locations_for_planned from NetUtils import convert_to_base_types from Options import StartInventoryPool -from Utils import __version__, output_path, version_tuple +from Utils import __version__, output_path, restricted_dumps, version_tuple from settings import get_settings from worlds import AutoWorld from worlds.generic.Rules import exclusion_rules, locality_rules @@ -339,7 +338,7 @@ def precollect_hint(location: Location, auto_status: HintStatus): for key in ("slot_data", "er_hint_data"): multidata[key] = convert_to_base_types(multidata[key]) - multidata = zlib.compress(pickle.dumps(multidata), 9) + multidata = zlib.compress(restricted_dumps(multidata), 9) with open(os.path.join(temp_dir, f'{outfilebase}.archipelago'), 'wb') as f: f.write(bytes([3])) # version of format diff --git a/MultiServer.py b/MultiServer.py index 1f421aaa8f54..59960a2a500b 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -546,6 +546,7 @@ def save(self, now=False) -> bool: def _save(self, exit_save: bool = False) -> bool: try: + # Does not use Utils.restricted_dumps because we'd rather make a save than not make one encoded_save = pickle.dumps(self.get_save()) with open(self.save_filename, "wb") as f: f.write(zlib.compress(encoded_save)) diff --git a/Utils.py b/Utils.py index 9c1171096e80..abf359f43e07 100644 --- a/Utils.py +++ b/Utils.py @@ -483,6 +483,18 @@ def restricted_loads(s: bytes) -> Any: return RestrictedUnpickler(io.BytesIO(s)).load() +def restricted_dumps(obj: Any) -> bytes: + """Helper function analogous to pickle.dumps().""" + s = pickle.dumps(obj) + # Assert that the string can be successfully loaded by restricted_loads + try: + restricted_loads(s) + except pickle.UnpicklingError as e: + raise pickle.PicklingError(e) from e + + return s + + class ByValue: """ Mixin for enums to pickle value instead of name (restores pre-3.11 behavior). Use as left-most parent. diff --git a/WebHostLib/api/generate.py b/WebHostLib/api/generate.py index 5a66d1e69331..7bcbdbcf19d7 100644 --- a/WebHostLib/api/generate.py +++ b/WebHostLib/api/generate.py @@ -1,11 +1,11 @@ import json -import pickle from uuid import UUID from flask import request, session, url_for from markupsafe import Markup from pony.orm import commit +from Utils import restricted_dumps from WebHostLib import app from WebHostLib.check import get_yaml_data, roll_options from WebHostLib.generate import get_meta @@ -56,7 +56,7 @@ def generate_api(): "detail": results}, 400 else: gen = Generation( - options=pickle.dumps({name: vars(options) for name, options in gen_options.items()}), + options=restricted_dumps({name: vars(options) for name, options in gen_options.items()}), # convert to json compatible meta=json.dumps(meta), state=STATE_QUEUED, owner=session["_id"]) diff --git a/WebHostLib/customserver.py b/WebHostLib/customserver.py index 2ebb40d673bd..156c12523d9e 100644 --- a/WebHostLib/customserver.py +++ b/WebHostLib/customserver.py @@ -129,7 +129,7 @@ def load(self, room_id: int): else: row = GameDataPackage.get(checksum=game_data["checksum"]) if row: # None if rolled on >= 0.3.9 but uploaded to <= 0.3.8. multidata should be complete - game_data_packages[game] = Utils.restricted_loads(row.data) + game_data_packages[game] = restricted_loads(row.data) continue else: self.logger.warning(f"Did not find game_data_package for {game}: {game_data['checksum']}") @@ -159,6 +159,7 @@ def init_save(self, enabled: bool = True): @db_session def _save(self, exit_save: bool = False) -> bool: room = Room.get(id=self.room_id) + # Does not use Utils.restricted_dumps because we'd rather make a save than not make one room.multisave = pickle.dumps(self.get_save()) # saving only occurs on activity, so we can "abuse" this information to mark this as last_activity if not exit_save: # we don't want to count a shutdown as activity, which would restart the server again diff --git a/WebHostLib/generate.py b/WebHostLib/generate.py index a84b17a88460..02f5a0379aa2 100644 --- a/WebHostLib/generate.py +++ b/WebHostLib/generate.py @@ -1,11 +1,11 @@ import concurrent.futures import json import os -import pickle import random import tempfile import zipfile from collections import Counter +from pickle import PicklingError from typing import Any from flask import flash, redirect, render_template, request, session, url_for @@ -14,7 +14,7 @@ from BaseClasses import get_seed, seeddigits from Generate import PlandoOptions, handle_name from Main import main as ERmain -from Utils import __version__ +from Utils import __version__, restricted_dumps from WebHostLib import app from settings import ServerOptions, GeneratorOptions from worlds.alttp.EntranceRandomizer import parse_arguments @@ -83,12 +83,18 @@ def start_generation(options: dict[str, dict | str], meta: dict[str, Any]): f"If you have a larger group, please generate it yourself and upload it.") return redirect(url_for(request.endpoint, **(request.view_args or {}))) elif len(gen_options) >= app.config["JOB_THRESHOLD"]: - gen = Generation( - options=pickle.dumps({name: vars(options) for name, options in gen_options.items()}), - # convert to json compatible - meta=json.dumps(meta), - state=STATE_QUEUED, - owner=session["_id"]) + try: + gen = Generation( + options=restricted_dumps({name: vars(options) for name, options in gen_options.items()}), + # convert to json compatible + meta=json.dumps(meta), + state=STATE_QUEUED, + owner=session["_id"]) + except PicklingError as e: + from .autolauncher import handle_generation_failure + handle_generation_failure(e) + return render_template("seedError.html", seed_error=("PicklingError: " + str(e))) + commit() return redirect(url_for("wait_seed", seed=gen.id)) diff --git a/WebHostLib/upload.py b/WebHostLib/upload.py index ee4ba6a53e71..4c5d411df25b 100644 --- a/WebHostLib/upload.py +++ b/WebHostLib/upload.py @@ -1,4 +1,3 @@ -import base64 import json import pickle import typing diff --git a/test/general/test_options.py b/test/general/test_options.py index 7a3743e5a4e7..d8ce7017f27b 100644 --- a/test/general/test_options.py +++ b/test/general/test_options.py @@ -1,7 +1,8 @@ import unittest -from BaseClasses import MultiWorld, PlandoOptions -from Options import ItemLinks +from BaseClasses import PlandoOptions +from Options import ItemLinks, Choice +from Utils import restricted_dumps from worlds.AutoWorld import AutoWorldRegister @@ -73,9 +74,10 @@ def test_item_links_resolve(self): def test_pickle_dumps(self): """Test options can be pickled into database for WebHost generation""" - import pickle for gamename, world_type in AutoWorldRegister.world_types.items(): if not world_type.hidden: for option_key, option in world_type.options_dataclass.type_hints.items(): with self.subTest(game=gamename, option=option_key): - pickle.dumps(option.from_any(option.default)) + restricted_dumps(option.from_any(option.default)) + if issubclass(option, Choice) and option.default in option.name_lookup: + restricted_dumps(option.from_text(option.name_lookup[option.default])) From c9ebf69e0d8a0fbde02bba0ecf638c67e65665e4 Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Sat, 26 Jul 2025 16:27:29 -0700 Subject: [PATCH 0613/1218] Core: MultiData typing (#5071) --- Main.py | 23 +++++++++++++++-------- MultiServer.py | 4 ++-- NetUtils.py | 39 ++++++++++++++++++++++++++++++++++++++- WebHostLib/upload.py | 3 +-- docs/world api.md | 2 +- worlds/AutoWorld.py | 4 ++-- worlds/__init__.py | 17 ++--------------- 7 files changed, 61 insertions(+), 31 deletions(-) diff --git a/Main.py b/Main.py index fd7d8d9ab72d..67c861c0f49b 100644 --- a/Main.py +++ b/Main.py @@ -1,9 +1,11 @@ import collections +from collections.abc import Mapping import concurrent.futures import logging import os import tempfile import time +from typing import Any import zipfile import zlib @@ -239,11 +241,13 @@ def main(args, seed=None, baked_server_options: dict[str, object] | None = None) def write_multidata(): import NetUtils from NetUtils import HintStatus - slot_data = {} - client_versions = {} - games = {} - minimum_versions = {"server": AutoWorld.World.required_server_version, "clients": client_versions} - slot_info = {} + slot_data: dict[int, Mapping[str, Any]] = {} + client_versions: dict[int, tuple[int, int, int]] = {} + games: dict[int, str] = {} + minimum_versions: NetUtils.MinimumVersions = { + "server": AutoWorld.World.required_server_version, "clients": client_versions + } + slot_info: dict[int, NetUtils.NetworkSlot] = {} names = [[name for player, name in sorted(multiworld.player_name.items())]] for slot in multiworld.player_ids: player_world: AutoWorld.World = multiworld.worlds[slot] @@ -258,7 +262,9 @@ def write_multidata(): group_members=sorted(group["players"])) precollected_items = {player: [item.code for item in world_precollected if type(item.code) == int] for player, world_precollected in multiworld.precollected_items.items()} - precollected_hints = {player: set() for player in range(1, multiworld.players + 1 + len(multiworld.groups))} + precollected_hints: dict[int, set[NetUtils.Hint]] = { + player: set() for player in range(1, multiworld.players + 1 + len(multiworld.groups)) + } for slot in multiworld.player_ids: slot_data[slot] = multiworld.worlds[slot].fill_slot_data() @@ -315,7 +321,7 @@ def precollect_hint(location: Location, auto_status: HintStatus): if current_sphere: spheres.append(dict(current_sphere)) - multidata = { + multidata: NetUtils.MultiData | bytes = { "slot_data": slot_data, "slot_info": slot_info, "connect_names": {name: (0, player) for player, name in multiworld.player_name.items()}, @@ -325,7 +331,7 @@ def precollect_hint(location: Location, auto_status: HintStatus): "er_hint_data": er_hint_data, "precollected_items": precollected_items, "precollected_hints": precollected_hints, - "version": tuple(version_tuple), + "version": (version_tuple.major, version_tuple.minor, version_tuple.build), "tags": ["AP"], "minimum_versions": minimum_versions, "seed_name": multiworld.seed_name, @@ -333,6 +339,7 @@ def precollect_hint(location: Location, auto_status: HintStatus): "datapackage": data_package, "race_mode": int(multiworld.is_race), } + # TODO: change to `"version": version_tuple` after getting better serialization AutoWorld.call_all(multiworld, "modify_multidata", multidata) for key in ("slot_data", "er_hint_data"): diff --git a/MultiServer.py b/MultiServer.py index 59960a2a500b..11a9e394c6b6 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -43,7 +43,7 @@ import Utils from Utils import version_tuple, restricted_loads, Version, async_start, get_intended_text from NetUtils import Endpoint, ClientStatus, NetworkItem, decode, encode, NetworkPlayer, Permission, NetworkSlot, \ - SlotType, LocationStore, Hint, HintStatus + SlotType, LocationStore, MultiData, Hint, HintStatus from BaseClasses import ItemClassification @@ -445,7 +445,7 @@ def decompress(data: bytes) -> dict: raise Utils.VersionException("Incompatible multidata.") return restricted_loads(zlib.decompress(data[1:])) - def _load(self, decoded_obj: dict, game_data_packages: typing.Dict[str, typing.Any], + def _load(self, decoded_obj: MultiData, game_data_packages: typing.Dict[str, typing.Any], use_embedded_server_options: bool): self.read_data = {} diff --git a/NetUtils.py b/NetUtils.py index cc6e917c8800..45279183f631 100644 --- a/NetUtils.py +++ b/NetUtils.py @@ -1,5 +1,6 @@ from __future__ import annotations +from collections.abc import Mapping, Sequence import typing import enum import warnings @@ -83,7 +84,7 @@ class NetworkSlot(typing.NamedTuple): name: str game: str type: SlotType - group_members: typing.Union[typing.List[int], typing.Tuple] = () # only populated if type == group + group_members: Sequence[int] = () # only populated if type == group class NetworkItem(typing.NamedTuple): @@ -471,6 +472,42 @@ def get_remaining(self, state: typing.Dict[typing.Tuple[int, int], typing.Set[in location_id not in checked]) +class MinimumVersions(typing.TypedDict): + server: tuple[int, int, int] + clients: dict[int, tuple[int, int, int]] + + +class GamesPackage(typing.TypedDict, total=False): + item_name_groups: dict[str, list[str]] + item_name_to_id: dict[str, int] + location_name_groups: dict[str, list[str]] + location_name_to_id: dict[str, int] + checksum: str + + +class DataPackage(typing.TypedDict): + games: dict[str, GamesPackage] + + +class MultiData(typing.TypedDict): + slot_data: dict[int, Mapping[str, typing.Any]] + slot_info: dict[int, NetworkSlot] + connect_names: dict[str, tuple[int, int]] + locations: dict[int, dict[int, tuple[int, int, int]]] + checks_in_area: dict[int, dict[str, int | list[int]]] + server_options: dict[str, object] + er_hint_data: dict[int, dict[int, str]] + precollected_items: dict[int, list[int]] + precollected_hints: dict[int, set[Hint]] + version: tuple[int, int, int] + tags: list[str] + minimum_versions: MinimumVersions + seed_name: str + spheres: list[dict[int, set[int]]] + datapackage: dict[str, GamesPackage] + race_mode: int + + if typing.TYPE_CHECKING: # type-check with pure python implementation until we have a typing stub LocationStore = _LocationStore else: diff --git a/WebHostLib/upload.py b/WebHostLib/upload.py index 4c5d411df25b..48885e9cc6fb 100644 --- a/WebHostLib/upload.py +++ b/WebHostLib/upload.py @@ -13,9 +13,8 @@ import schema import MultiServer -from NetUtils import SlotType +from NetUtils import GamesPackage, SlotType from Utils import VersionException, __version__ -from worlds import GamesPackage from worlds.Files import AutoPatchRegister from worlds.AutoWorld import data_package_checksum from . import app diff --git a/docs/world api.md b/docs/world api.md index 3bf4821924e0..17cf81fe92ec 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -539,7 +539,7 @@ In addition, the following methods can be implemented and are called in this ord creates the output files if there is output to be generated. When this is called, `self.multiworld.get_locations(self.player)` has all locations for the player, with attribute `item` pointing to the item. `location.item.player` can be used to see if it's a local item. -* `fill_slot_data(self)` and `modify_multidata(self, multidata: Dict[str, Any])` can be used to modify the data that +* `fill_slot_data(self)` and `modify_multidata(self, multidata: MultiData)` can be used to modify the data that will be used by the server to host the MultiWorld. All instance methods can, optionally, have a class method defined which will be called after all instance methods are diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 6c1683e3d55e..568bdcf9a433 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -16,7 +16,7 @@ if TYPE_CHECKING: from BaseClasses import MultiWorld, Item, Location, Tutorial, Region, Entrance - from . import GamesPackage + from NetUtils import GamesPackage, MultiData from settings import Group perf_logger = logging.getLogger("performance") @@ -450,7 +450,7 @@ def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]): """ pass - def modify_multidata(self, multidata: Dict[str, Any]) -> None: # TODO: TypedDict for multidata? + def modify_multidata(self, multidata: "MultiData") -> None: """For deeper modification of server multidata.""" pass diff --git a/worlds/__init__.py b/worlds/__init__.py index 7db651bdd9e3..80240275b02f 100644 --- a/worlds/__init__.py +++ b/worlds/__init__.py @@ -7,8 +7,9 @@ import zipimport import time import dataclasses -from typing import Dict, List, TypedDict +from typing import List +from NetUtils import DataPackage from Utils import local_path, user_path local_folder = os.path.dirname(__file__) @@ -24,8 +25,6 @@ "world_sources", "local_folder", "user_folder", - "GamesPackage", - "DataPackage", "failed_world_loads", } @@ -33,18 +32,6 @@ failed_world_loads: List[str] = [] -class GamesPackage(TypedDict, total=False): - item_name_groups: Dict[str, List[str]] - item_name_to_id: Dict[str, int] - location_name_groups: Dict[str, List[str]] - location_name_to_id: Dict[str, int] - checksum: str - - -class DataPackage(TypedDict): - games: Dict[str, GamesPackage] - - @dataclasses.dataclass(order=True) class WorldSource: path: str # typically relative path from this module From 199a6df65e512ea19b6701e8678bb2155e53fdea Mon Sep 17 00:00:00 2001 From: Widowmaker-61 <121366307+Turky6192@users.noreply.github.com> Date: Sun, 27 Jul 2025 01:25:59 -0400 Subject: [PATCH 0614/1218] Muse Dash: Adding Option to select Goal Song (#4820) Co-authored-by: Justus Lind Co-authored-by: Aaron Wagener --- worlds/musedash/Options.py | 9 +++++++++ worlds/musedash/__init__.py | 19 +++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/worlds/musedash/Options.py b/worlds/musedash/Options.py index 9f729c2d03e2..83e58274f086 100644 --- a/worlds/musedash/Options.py +++ b/worlds/musedash/Options.py @@ -175,6 +175,13 @@ class ExcludeSongs(SongSet): """ display_name = "Exclude Songs" +class GoalSong(SongSet): + """ + One of the selected songs will be guaranteed to show up as the final Goal Song. + - You must have the DLC enabled to play these songs. + - If no songs are chosen, then the song will be randomly chosen from the available songs. + """ + display_name = "Goal Song" md_option_groups = [ OptionGroup("Song Choice", [ @@ -182,6 +189,7 @@ class ExcludeSongs(SongSet): StreamerModeEnabled, IncludeSongs, ExcludeSongs, + GoalSong, ]), OptionGroup("Difficulty", [ GradeNeeded, @@ -214,6 +222,7 @@ class MuseDashOptions(PerGameCommonOptions): death_link: DeathLink include_songs: IncludeSongs exclude_songs: ExcludeSongs + goal_song: GoalSong # Removed allow_just_as_planned_dlc_songs: Removed diff --git a/worlds/musedash/__init__.py b/worlds/musedash/__init__.py index 87eb70175202..eb82148c1bb9 100644 --- a/worlds/musedash/__init__.py +++ b/worlds/musedash/__init__.py @@ -119,12 +119,24 @@ def handle_plando(self, available_song_keys: List[str], dlc_songs: Set[str]) -> start_items = self.options.start_inventory.value.keys() include_songs = self.options.include_songs.value exclude_songs = self.options.exclude_songs.value + chosen_goal_songs = sorted(self.options.goal_song) self.starting_songs = [s for s in start_items if s in song_items] self.starting_songs = self.md_collection.filter_songs_to_dlc(self.starting_songs, dlc_songs) self.included_songs = [s for s in include_songs if s in song_items and s not in self.starting_songs] self.included_songs = self.md_collection.filter_songs_to_dlc(self.included_songs, dlc_songs) + # Making sure songs chosen for goal are allowed by DLC and remove the chosen from being added to the pool. + if chosen_goal_songs: + chosen_goal_songs = self.md_collection.filter_songs_to_dlc(chosen_goal_songs, dlc_songs) + if chosen_goal_songs: + self.random.shuffle(chosen_goal_songs) + self.victory_song_name = chosen_goal_songs.pop() + if self.victory_song_name in self.starting_songs: + self.starting_songs.remove(self.victory_song_name) + if self.victory_song_name in self.included_songs: + self.included_songs.remove(self.victory_song_name) + return [s for s in available_song_keys if s not in start_items and s not in include_songs and s not in exclude_songs] @@ -139,12 +151,13 @@ def create_song_pool(self, available_song_keys: List[str]): if included_song_count > additional_song_count: # If so, we want to thin the list, thus let's get the goal song and starter songs while we are at it. self.random.shuffle(self.included_songs) - self.victory_song_name = self.included_songs.pop() + if not self.victory_song_name: + self.victory_song_name = self.included_songs.pop() while len(self.included_songs) > additional_song_count: next_song = self.included_songs.pop() if len(self.starting_songs) < starting_song_count: self.starting_songs.append(next_song) - else: + elif not self.victory_song_name: # If not, choose a random victory song from the available songs chosen_song = self.random.randrange(0, len(available_song_keys) + included_song_count) if chosen_song < included_song_count: @@ -153,6 +166,8 @@ def create_song_pool(self, available_song_keys: List[str]): else: self.victory_song_name = available_song_keys[chosen_song - included_song_count] del available_song_keys[chosen_song - included_song_count] + elif self.victory_song_name in available_song_keys: + available_song_keys.remove(self.victory_song_name) # Next, make sure the starting songs are fulfilled if len(self.starting_songs) < starting_song_count: From ea1e07408368774a497759e7ae14a15b4ee145a7 Mon Sep 17 00:00:00 2001 From: Yussur Mustafa Oraji Date: Sun, 27 Jul 2025 16:45:48 +0200 Subject: [PATCH 0615/1218] V6: Allow Secret Lab Music to be Randomized (#4643) --- worlds/v6/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/v6/__init__.py b/worlds/v6/__init__.py index b74f335189cf..3ed8b7044c86 100644 --- a/worlds/v6/__init__.py +++ b/worlds/v6/__init__.py @@ -59,7 +59,7 @@ def create_items(self): self.multiworld.itempool += filltrinkets def generate_basic(self): - musiclist_o = [1,2,3,4,9,12] + musiclist_o = [1,2,3,4,9,11,12] musiclist_s = musiclist_o.copy() if self.options.music_rando: self.multiworld.random.shuffle(musiclist_s) From 04a3f78605fa55e9f8fd3177d0229d48b8d7890d Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sun, 27 Jul 2025 23:29:21 +0200 Subject: [PATCH 0616/1218] Core: Support inequality operators ("less than") for Choice option string comparisons (#3769) * add some unit tests to it * fix * Update Options.py Co-authored-by: qwint * Update Options.py --------- Co-authored-by: qwint --- Options.py | 24 ++++++++++++++++++++++++ test/options/test_option_classes.py | 9 +++++++++ worlds/witness/__init__.py | 2 +- worlds/witness/hints.py | 2 +- worlds/witness/player_logic.py | 4 ++-- 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Options.py b/Options.py index c948e7e95f1b..3e67d68569e9 100644 --- a/Options.py +++ b/Options.py @@ -494,6 +494,30 @@ def __ne__(self, other): else: raise TypeError(f"Can't compare {self.__class__.__name__} with {other.__class__.__name__}") + def __lt__(self, other: typing.Union[Choice, int, str]): + if isinstance(other, str): + assert other in self.options, f"compared against an unknown string. {self} < {other}" + other = self.options[other] + return super(Choice, self).__lt__(other) + + def __gt__(self, other: typing.Union[Choice, int, str]): + if isinstance(other, str): + assert other in self.options, f"compared against an unknown string. {self} > {other}" + other = self.options[other] + return super(Choice, self).__gt__(other) + + def __le__(self, other: typing.Union[Choice, int, str]): + if isinstance(other, str): + assert other in self.options, f"compared against an unknown string. {self} <= {other}" + other = self.options[other] + return super(Choice, self).__le__(other) + + def __ge__(self, other: typing.Union[Choice, int, str]): + if isinstance(other, str): + assert other in self.options, f"compared against an unknown string. {self} >= {other}" + other = self.options[other] + return super(Choice, self).__ge__(other) + __hash__ = Option.__hash__ # see https://docs.python.org/3/reference/datamodel.html#object.__hash__ diff --git a/test/options/test_option_classes.py b/test/options/test_option_classes.py index 8e2c4702c380..ca90db88708c 100644 --- a/test/options/test_option_classes.py +++ b/test/options/test_option_classes.py @@ -33,6 +33,15 @@ class TestDefaultOnToggle(DefaultOnToggle): self.assertEqual(choice_option_alias, TestChoice.alias_three) self.assertEqual(choice_option_attr, TestChoice.non_option_attr) + self.assertLess(choice_option_string, "two") + self.assertGreater(choice_option_string, "zero") + self.assertLessEqual(choice_option_string, "one") + self.assertLessEqual(choice_option_string, "two") + self.assertGreaterEqual(choice_option_string, "one") + self.assertGreaterEqual(choice_option_string, "zero") + + self.assertGreaterEqual(choice_option_alias, "three") + self.assertRaises(KeyError, TestChoice.from_any, "four") self.assertIn(choice_option_int, [1, 2, 3]) diff --git a/worlds/witness/__init__.py b/worlds/witness/__init__.py index 0f96ee94e8c9..bce9bb515146 100644 --- a/worlds/witness/__init__.py +++ b/worlds/witness/__init__.py @@ -257,7 +257,7 @@ def create_regions(self) -> None: needed_size = 2 needed_size += self.options.puzzle_randomization == "sigma_expert" needed_size += self.options.shuffle_symbols - needed_size += self.options.shuffle_doors > 0 + needed_size += self.options.shuffle_doors != "off" # Then, add checks in order until the required amount of sphere 1 checks is met. diff --git a/worlds/witness/hints.py b/worlds/witness/hints.py index c82024cc1217..ac5572257fc3 100644 --- a/worlds/witness/hints.py +++ b/worlds/witness/hints.py @@ -129,7 +129,7 @@ def get_priority_hint_items(world: "WitnessWorld") -> List[str]: "Shadows Laser", ] - if world.options.shuffle_doors >= 2: + if world.options.shuffle_doors >= "doors": priority.add("Desert Laser") priority.update(world.random.sample(lasers, 5)) diff --git a/worlds/witness/player_logic.py b/worlds/witness/player_logic.py index 52bddde17ee4..aed6d3da66bb 100644 --- a/worlds/witness/player_logic.py +++ b/worlds/witness/player_logic.py @@ -435,7 +435,7 @@ def handle_regular_postgame(self, world: "WitnessWorld") -> List[List[str]]: postgame_adjustments = [] # Make some quick references to some options - remote_doors = world.options.shuffle_doors >= 2 # "Panels" mode has no region accessibility implications. + remote_doors = world.options.shuffle_doors >= "doors" # "Panels" mode has no region accessibility implications. early_caves = world.options.early_caves victory = world.options.victory_condition mnt_lasers = world.options.mountain_lasers @@ -592,7 +592,7 @@ def make_options_adjustments(self, world: "WitnessWorld") -> None: # Make condensed references to some options - remote_doors = world.options.shuffle_doors >= 2 # "Panels" mode has no overarching region access implications. + remote_doors = world.options.shuffle_doors >= "doors" # "Panels" mode has no region access implications. lasers = world.options.shuffle_lasers victory = world.options.victory_condition mnt_lasers = world.options.mountain_lasers From f8d1e4edf362b2c3579e1613e318ccc761513a4a Mon Sep 17 00:00:00 2001 From: JKLeckr <11635283+JKLeckr@users.noreply.github.com> Date: Sun, 27 Jul 2025 19:57:19 -0500 Subject: [PATCH 0617/1218] Ignore .github dir in package test (#5098) Added comments for ignore code --- test/general/test_packages.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/general/test_packages.py b/test/general/test_packages.py index 32c7bdf47e49..1df6187ee00d 100644 --- a/test/general/test_packages.py +++ b/test/general/test_packages.py @@ -8,7 +8,12 @@ def test_packages_have_init(self): to indicate full package rather than namespace package.""" import Utils + # Ignore directories with these names. + ignore_dirs = {".github"} + worlds_path = Utils.local_path("worlds") for dirpath, dirnames, filenames in os.walk(worlds_path): + # Drop ignored directories from dirnames, excluding them from walking. + dirnames[:] = [d for d in dirnames if d not in ignore_dirs] with self.subTest(directory=dirpath): self.assertEqual("__init__.py" in filenames, any(file.endswith(".py") for file in filenames)) From 5e2702090c96959fc963aa72170fb861aaf656b1 Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Sun, 27 Jul 2025 18:10:06 -0700 Subject: [PATCH 0618/1218] Tests: only get `__init__.py` tests from test directories (#5135) --- pytest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index 4469a7c30d64..f050d58b70b1 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,5 +1,5 @@ [pytest] -python_files = test_*.py Test*.py __init__.py # TODO: remove Test* once all worlds have been ported +python_files = test_*.py Test*.py **/test*/**/__init__.py # TODO: remove Test* once all worlds have been ported python_classes = Test python_functions = test testpaths = From 4d1736666269b9be61890f8cd0d3fe4b9633d38d Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Mon, 28 Jul 2025 06:41:43 -0700 Subject: [PATCH 0619/1218] Core: fix dangerous mutable default in Fill (#5247) discussed here https://discord.com/channels/731205301247803413/731214280439103580/1327712564213448775 --- Fill.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Fill.py b/Fill.py index 29a9a530a4cd..1cc1278f4b50 100644 --- a/Fill.py +++ b/Fill.py @@ -358,7 +358,12 @@ def fast_fill(multiworld: MultiWorld, return item_pool[placing:], fill_locations[placing:] -def accessibility_corrections(multiworld: MultiWorld, state: CollectionState, locations, pool=[]): +def accessibility_corrections(multiworld: MultiWorld, + state: CollectionState, + locations: list[Location], + pool: list[Item] | None = None) -> None: + if pool is None: + pool = [] maximum_exploration_state = sweep_from_pool(state, pool) minimal_players = {player for player in multiworld.player_ids if multiworld.worlds[player].options.accessibility == "minimal"} From ad17c7fd216b9b06fcb86182f9057f7fea2b7a44 Mon Sep 17 00:00:00 2001 From: BlastSlimey <89539656+BlastSlimey@users.noreply.github.com> Date: Mon, 28 Jul 2025 17:01:57 +0200 Subject: [PATCH 0620/1218] shapez: Typing Cleanup + Small Docs Rewordings (#5189) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/shapez/__init__.py | 22 ++++---- worlds/shapez/common/options.py | 48 +++++++++--------- worlds/shapez/data/generate.py | 13 +++-- worlds/shapez/docs/datapackage_settings_de.md | 9 ++-- worlds/shapez/docs/datapackage_settings_en.md | 28 +++++------ worlds/shapez/docs/de_shapez.md | 20 ++++---- worlds/shapez/docs/en_shapez.md | 34 ++++++------- worlds/shapez/docs/setup_de.md | 7 +-- worlds/shapez/docs/setup_en.md | 6 +-- worlds/shapez/items.py | 36 ++++++------- worlds/shapez/locations.py | 50 +++++++++---------- worlds/shapez/regions.py | 12 ++--- worlds/shapez/test/__init__.py | 2 +- 13 files changed, 144 insertions(+), 143 deletions(-) diff --git a/worlds/shapez/__init__.py b/worlds/shapez/__init__.py index 2a77ed8c9c96..5557e2a96a6e 100644 --- a/worlds/shapez/__init__.py +++ b/worlds/shapez/__init__.py @@ -1,5 +1,5 @@ import math -from typing import Any, List, Dict, Tuple, Mapping +from typing import Mapping, Any from Options import OptionError from .data.strings import OTHER, ITEMS, CATEGORY, LOCATIONS, SLOTDATA, GOALS, OPTIONS @@ -123,23 +123,23 @@ def __init__(self, multiworld: MultiWorld, player: int): # Defining instance attributes for each shapez world # These are set to default values that should fail unit tests if not replaced with correct values self.location_count: int = 0 - self.level_logic: List[str] = [] - self.upgrade_logic: List[str] = [] + self.level_logic: list[str] = [] + self.upgrade_logic: list[str] = [] self.level_logic_type: str = "" self.upgrade_logic_type: str = "" - self.random_logic_phase_length: List[int] = [] - self.category_random_logic_amounts: Dict[str, int] = {} + self.random_logic_phase_length: list[int] = [] + self.category_random_logic_amounts: dict[str, int] = {} self.maxlevel: int = 0 self.finaltier: int = 0 - self.included_locations: Dict[str, Tuple[str, LocationProgressType]] = {} + self.included_locations: dict[str, tuple[str, LocationProgressType]] = {} self.client_seed: int = 0 - self.shapesanity_names: List[str] = [] + self.shapesanity_names: list[str] = [] self.upgrade_traps_allowed: bool = False # Universal Tracker support self.ut_active: bool = False - self.passthrough: Dict[str, any] = {} - self.location_id_to_alias: Dict[int, str] = {} + self.passthrough: dict[str, Any] = {} + self.location_id_to_alias: dict[int, str] = {} @classmethod def stage_generate_early(cls, multiworld: MultiWorld) -> None: @@ -315,7 +315,7 @@ def create_regions(self) -> None: def create_items(self) -> None: # Include guaranteed items (game mechanic unlocks and 7x4 big upgrades) - included_items: List[Item] = ([self.create_item(name) for name in buildings_processing.keys()] + included_items: list[Item] = ([self.create_item(name) for name in buildings_processing.keys()] + [self.create_item(name) for name in buildings_routing.keys()] + [self.create_item(name) for name in buildings_other.keys()] + [self.create_item(name) for name in buildings_top_row.keys()] @@ -412,6 +412,6 @@ def fill_slot_data(self) -> Mapping[str, Any]: **logic_type_cat_random_data, SLOTDATA.seed: self.client_seed, SLOTDATA.shapesanity: self.shapesanity_names} - def interpret_slot_data(self, slot_data: Dict[str, Any]) -> Dict[str, Any]: + def interpret_slot_data(self, slot_data: dict[str, Any]) -> dict[str, Any]: """Helper function for Universal Tracker""" return slot_data diff --git a/worlds/shapez/common/options.py b/worlds/shapez/common/options.py index aa66ced03294..8a55448cd491 100644 --- a/worlds/shapez/common/options.py +++ b/worlds/shapez/common/options.py @@ -1,5 +1,5 @@ import random -import typing +from typing import cast, Any from Options import FreeText, NumericOption @@ -47,7 +47,7 @@ def __init__(self, value: str): raise Exception(f"{value} is higher than maximum {self.range_end} for option {self.__class__.__name__}") @classmethod - def from_text(cls, text: str) -> typing.Any: + def from_text(cls, text: str) -> Any: return cls(text) @classmethod @@ -99,31 +99,31 @@ def current_key(self) -> str: def get_option_name(cls, value: float) -> str: return str(value) - def __eq__(self, other: typing.Any): + def __eq__(self, other: Any): if isinstance(other, NumericOption): return self.value == other.value else: - return typing.cast(bool, self.value == other) + return cast(bool, self.value == other) - def __lt__(self, other: typing.Union[int, float, NumericOption]) -> bool: + def __lt__(self, other: int | float | NumericOption) -> bool: if isinstance(other, NumericOption): return self.value < other.value else: return self.value < other - def __le__(self, other: typing.Union[int, float, NumericOption]) -> bool: + def __le__(self, other: int | float | NumericOption) -> bool: if isinstance(other, NumericOption): return self.value <= other.value else: return self.value <= other - def __gt__(self, other: typing.Union[int, float, NumericOption]) -> bool: + def __gt__(self, other: int | float | NumericOption) -> bool: if isinstance(other, NumericOption): return self.value > other.value else: return self.value > other - def __ge__(self, other: typing.Union[int, float, NumericOption]) -> bool: + def __ge__(self, other: int | float | NumericOption) -> bool: if isinstance(other, NumericOption): return self.value >= other.value else: @@ -132,59 +132,59 @@ def __ge__(self, other: typing.Union[int, float, NumericOption]) -> bool: def __int__(self) -> int: return int(self.value) - def __and__(self, other: typing.Any) -> int: + def __and__(self, other: Any) -> int: raise TypeError("& operator not supported for float values") - def __floordiv__(self, other: typing.Any) -> int: + def __floordiv__(self, other: Any) -> int: return int(self.value // float(other)) def __invert__(self) -> int: raise TypeError("~ operator not supported for float values") - def __lshift__(self, other: typing.Any) -> int: + def __lshift__(self, other: Any) -> int: raise TypeError("<< operator not supported for float values") - def __mod__(self, other: typing.Any) -> float: + def __mod__(self, other: Any) -> float: return self.value % float(other) def __neg__(self) -> float: return -self.value - def __or__(self, other: typing.Any) -> int: + def __or__(self, other: Any) -> int: raise TypeError("| operator not supported for float values") def __pos__(self) -> float: return +self.value - def __rand__(self, other: typing.Any) -> int: + def __rand__(self, other: Any) -> int: raise TypeError("& operator not supported for float values") - def __rfloordiv__(self, other: typing.Any) -> int: + def __rfloordiv__(self, other: Any) -> int: return int(float(other) // self.value) - def __rlshift__(self, other: typing.Any) -> int: + def __rlshift__(self, other: Any) -> int: raise TypeError("<< operator not supported for float values") - def __rmod__(self, other: typing.Any) -> float: + def __rmod__(self, other: Any) -> float: return float(other) % self.value - def __ror__(self, other: typing.Any) -> int: + def __ror__(self, other: Any) -> int: raise TypeError("| operator not supported for float values") - def __round__(self, ndigits: typing.Optional[int] = None) -> float: + def __round__(self, ndigits: int | None = None) -> float: return round(self.value, ndigits) - def __rpow__(self, base: typing.Any) -> typing.Any: + def __rpow__(self, base: Any) -> Any: return base ** self.value - def __rrshift__(self, other: typing.Any) -> int: + def __rrshift__(self, other: Any) -> int: raise TypeError(">> operator not supported for float values") - def __rshift__(self, other: typing.Any) -> int: + def __rshift__(self, other: Any) -> int: raise TypeError(">> operator not supported for float values") - def __rxor__(self, other: typing.Any) -> int: + def __rxor__(self, other: Any) -> int: raise TypeError("^ operator not supported for float values") - def __xor__(self, other: typing.Any) -> int: + def __xor__(self, other: Any) -> int: raise TypeError("^ operator not supported for float values") diff --git a/worlds/shapez/data/generate.py b/worlds/shapez/data/generate.py index 27d74e865d08..86b660ef5b0a 100644 --- a/worlds/shapez/data/generate.py +++ b/worlds/shapez/data/generate.py @@ -1,14 +1,13 @@ import itertools import time -from typing import Dict, List from worlds.shapez.data.strings import SHAPESANITY, REGIONS -shapesanity_simple: Dict[str, str] = {} -shapesanity_1_4: Dict[str, str] = {} -shapesanity_two_sided: Dict[str, str] = {} -shapesanity_three_parts: Dict[str, str] = {} -shapesanity_four_parts: Dict[str, str] = {} +shapesanity_simple: dict[str, str] = {} +shapesanity_1_4: dict[str, str] = {} +shapesanity_two_sided: dict[str, str] = {} +shapesanity_three_parts: dict[str, str] = {} +shapesanity_four_parts: dict[str, str] = {} subshape_names = [SHAPESANITY.circle, SHAPESANITY.square, SHAPESANITY.star, SHAPESANITY.windmill] color_names = [SHAPESANITY.red, SHAPESANITY.blue, SHAPESANITY.green, SHAPESANITY.yellow, SHAPESANITY.purple, SHAPESANITY.cyan, SHAPESANITY.white, SHAPESANITY.uncolored] @@ -16,7 +15,7 @@ short_colors = ["b", "c", "g", "p", "r", "u", "w", "y"] -def color_to_needed_building(color_list: List[str]) -> str: +def color_to_needed_building(color_list: list[str]) -> str: for next_color in color_list: if next_color in [SHAPESANITY.yellow, SHAPESANITY.purple, SHAPESANITY.cyan, SHAPESANITY.white, "y", "p", "c", "w"]: diff --git a/worlds/shapez/docs/datapackage_settings_de.md b/worlds/shapez/docs/datapackage_settings_de.md index ae375f3e3c66..a6c1b35cb8b0 100644 --- a/worlds/shapez/docs/datapackage_settings_de.md +++ b/worlds/shapez/docs/datapackage_settings_de.md @@ -4,7 +4,7 @@ Die Maximalwerte von `goal_amount` und `shapesanity_amount` sind fest eingebaute Einstellungen, die das Datenpaket des Spiels beeinflussen. Sie sind in einer Datei names `options.json` innerhalb der APWorld festgelegt. Durch das Ändern -dieser Werte erschaffst du eine custom APWorld, die nur auf deinem PC existiert. +dieser Werte erschaffst du eine custom Version der APWorld, die nur auf deinem PC existiert. ## Wie du die Datenpaket-Einstellungen änderst @@ -18,17 +18,18 @@ ordnungsgemäß befolgt wird. Anwendung auf eigene Gefahr. - `max_shapesanity` kann nicht weniger als `4` sein, da dies die benötigte Mindestanzahl zum Verhindern von FillErrors ist. - `max_shapesanity` kann auch nicht mehr als `75800` sein, da dies die maximale Anzahl an möglichen Shapesanity-Namen - ist. Ansonsten könnte die Generierung der Multiworld fehlschlagen. + ist. Das Generieren der Multiworld wird fehlschlagen, falls die `shapesanity_amount`-Option auf einen höheren Wert + gesetzt wird. - `max_levels_and_upgrades` kann nicht weniger als `27` sein, da dies die Mindestanzahl für das `mam`-Ziel ist. 5. Schließe die Zip-Datei und benenne sie zurück zu `shapez.apworld`. ## Warum muss ich das ganze selbst machen? Alle Spiele in Archipelago müssen eine Liste aller möglichen Locations **unabhängig der Spieler-Optionen** -bereitstellen. Diese Listen aller in einer Multiworld inkludierten Spiele werden in den Daten der Multiworld gespeichert +bereitstellen. Diese Listen aller in einer Multiworld inkludierten Spiele werden in den Daten der Multiworld gespeichert und an alle verbundenen Clients gesendet. Je mehr mögliche Locations, desto größer das Datenpaket. Und mit ~80000 möglichen Locations hatte shapez zu einem gewissen Zeitpunkt ein (von der Datenmenge her) größeres Datenpaket als alle -supporteten Spiele zusammen. Um also diese Datenmenge zu reduzieren wurden die ausgeschriebenen +Core-verifizierten Spiele zusammen. Um also diese Datenmenge zu reduzieren, wurden die ausgeschriebenen Shapesanity-Locations-Namen (`Shapesanity Uncolored Circle`, `Shapesanity Blue Rectangle`, ...) durch standardisierte Namen (`Shapesanity 1`, `Shapesanity 2`, ...) ersetzt. Durch das Ändern dieser Maximalwerte, und damit das Erstellen einer custom APWorld, kannst du die Anzahl der möglichen Locations erhöhen, wirst aber auch gleichzeitig das Datenpaket diff --git a/worlds/shapez/docs/datapackage_settings_en.md b/worlds/shapez/docs/datapackage_settings_en.md index fd0ed1673d9e..64f39abf2e55 100644 --- a/worlds/shapez/docs/datapackage_settings_en.md +++ b/worlds/shapez/docs/datapackage_settings_en.md @@ -1,14 +1,14 @@ -# Guide to change maximum locations in shapez +# Guide to change the maximum amount of locations in shapez ## Where do I find the settings to increase/decrease the amount of possible locations? -The maximum values of the `goal_amount` and `shapesanity_amount` are hardcoded settings that affect the datapackage. -They are stored in a file called `options.json` inside the apworld. By changing them, you will create a custom apworld -on your local machine. +The maximum values of the `goal_amount` and `shapesanity_amount` options are hardcoded settings that affect the +datapackage. They are stored in a file called `options.json` inside the apworld. By changing them, you will create a +custom version on your local machine. -## How to change datapackage options +## How to change datapackage settings -This tutorial is for advanced users and can result in the software not working properly, if not read carefully. +This tutorial is intended for advanced users and can result in the software not working properly, if not read carefully. Proceed at your own risk. 1. Go to `/lib/worlds`. @@ -17,17 +17,17 @@ Proceed at your own risk. 4. Edit the values in this file to your desire and save the file. - `max_shapesanity` cannot be lower than `4`, as this is the minimum amount to prevent FillErrors. - `max_shapesanity` also cannot be higher than `75800`, as this is the maximum amount of possible shapesanity names. - Else the multiworld generation might fail. + Multiworld generation will fail if the `shapesanity_amount` options is set to a higher value. - `max_levels_and_upgrades` cannot be lower than `27`, as this is the minimum amount for the `mam` goal to properly work. -5. Close the zip and rename it back to `shapez.apworld`. +5. Close the zip file and rename it back to `shapez.apworld`. ## Why do I have to do this manually? For every game in Archipelago, there must be a list of all possible locations, **regardless of player options**. When -generating a multiworld, a list of all locations of all included games will be saved in the multiworld data and sent to -all clients. The higher the amount of possible locations, the bigger the datapackage. And having ~80000 possible -locations at one point made the datapackage for shapez bigger than all other supported games combined. So to reduce the -datapackage of shapez, the locations for shapesanity are named `Shapesanity 1`, `Shapesanity 2` etc. instead of their -actual names. By creating a custom apworld, you can increase the amount of possible locations, but you will also -increase the size of the datapackage at the same time. +generating a multiworld, a list of all locations of all included games will be saved in the multiworld's data and sent +to all clients. The higher the amount of possible locations, the bigger the datapackage. And having ~80000 possible +locations at one point made the datapackage for shapez bigger than all other core-verified games combined. So, to reduce +the datapackage size of shapez, the locations for shapesanity are named `Shapesanity 1`, `Shapesanity 2` etc. instead of +their actual names. By creating a custom version of the apworld, you can increase the amount of possible locations, but +you will also increase the size of the datapackage at the same time. diff --git a/worlds/shapez/docs/de_shapez.md b/worlds/shapez/docs/de_shapez.md index 4a26ea821ce0..494edca210a1 100644 --- a/worlds/shapez/docs/de_shapez.md +++ b/worlds/shapez/docs/de_shapez.md @@ -19,25 +19,27 @@ Zusätzlich gibt es zu diesem Spiel "Datenpaket-Einstellungen", die du nach Alle Belohnungen aus den Tutorial-Level (das Freischalten von Gebäuden und Spielmechaniken) und Verbesserungen durch Upgrades werden dem Itempool der Multiworld hinzugefügt. Außerdem werden, wenn so in den Spieler-Optionen festgelegt, -die Bedingungen zum Abschließen eines Levels und zum Kaufen der Upgrades randomisiert. +die Bedingungen zum Abschließen eines Levels und zum Kaufen der Upgrades randomisiert und die Reihenfolge der Gebäude +in deinen Toolbars (Haupt- und Kabelebene) gemischt. ## Was ist das Ziel von shapez in Archipelago? -Da das Spiel eigentlich kein konkretes Ziel (nach dem Tutorial) hat, kann man sich zwischen (momentan) 4 verschiedenen -Zielen entscheiden: +Da das Spiel eigentlich kein konkretes Ziel, welches das Ende des Spiels bedeuten würde, hat, kann man sich zwischen +(aktuell) 4 verschiedenen Zielen entscheiden: 1. Vanilla: Schließe Level 26 ab (eigentlich das Ende des Tutorials). 2. MAM: Schließe ein bestimmtes Level nach Level 26 ab, das zuvor in den Spieler-Optionen festgelegt wurde. Es ist empfohlen, eine Maschine zu bauen, die alles automatisch herstellt ("Make-Anything-Machine", kurz MAM). -3. Even Fasterer: Kaufe alle Upgrades bis zu einer in den Spieler-Optionen festgelegten Stufe (nach Stufe 8). +3. Even Fasterer: Kaufe alle Upgrades bis zu einer in den Spieler-Optionen festgelegten Stufe (nach Stufe VIII (8)). 4. Efficiency III: Liefere 256 Blaupausen-Formen pro Sekunde ins Zentrum. ## Welche Items können in den Welten anderer Spieler erscheinen? -- Freischalten verschiedener Gebäude +- Gebäude - Blaupausen freischalten -- Große Upgrades (addiert 1 zum Geschwindigkeitsmultiplikator) -- Kleine Upgrades (addiert 0.1 zum Geschwindigkeitsmultiplikator) -- Andere ungewöhnliche Upgrades (optional) +- Upgrades + - Große Upgrades (addiert 1 zum Geschwindigkeitsmultiplikator) + - Kleine Upgrades (addiert 0.1 zum Geschwindigkeitsmultiplikator) + - Andere ungewöhnliche (auch negative) Upgrades (optional) - Verschiedene Bündel, die bestimmte Formen enthalten - Fallen, die bestimmte Formen aus dem Zentrum dränieren (ja, das Wort gibt es) - Fallen, die zufällige Gebäude oder andere Spielmechaniken betreffen @@ -45,7 +47,7 @@ empfohlen, eine Maschine zu bauen, die alles automatisch herstellt ("Make-Anythi ## Was ist eine Location / ein Check? - Level (minimum 1-25, bis zu 499 je nach Spieler-Optionen, mit zusätzlichen Checks für Level 1 und 20) -- Upgrades (minimum Stufen II-VIII (2-8), bis zu D (500) je nach Spieler-Optionen) +- Upgrades (minimum Stufen II-VIII (2-8), bis zu D (500), je nach Spieler-Optionen) - Bestimmte Formen mindestens einmal ins Zentrum liefern ("Shapesanity", bis zu 1000 zufällig gewählte Definitionen) - Errungenschaften (bis zu 45) diff --git a/worlds/shapez/docs/en_shapez.md b/worlds/shapez/docs/en_shapez.md index dc41d73d7e13..56c03872589c 100644 --- a/worlds/shapez/docs/en_shapez.md +++ b/worlds/shapez/docs/en_shapez.md @@ -4,9 +4,9 @@ shapez is an automation game about cutting, rotating, stacking, and painting shapes, that you extract from randomly generated patches on an infinite canvas, and sending them to the hub to complete levels. The "tutorial", where you -unlock a new building or game mechanic (almost) each level, lasts until level 26, where you unlock freeplay with -infinitely more levels, that require a new, randomly generated shape. Alongside the levels, you can unlock upgrades, -that make your buildings work faster. +unlock a new building or game mechanic (almost) each level, lasts until level 26, which unlocks freeplay with +infinitely more levels, that each require a new, randomly generated shape. Alongside the levels, you can unlock +upgrades, that make your buildings work faster. ## Where is the options page? @@ -17,29 +17,30 @@ There are also some advanced "datapackage settings" that can be changed by follo ## What does randomization do to this game? -Buildings and gameplay mechanics, that you normally unlock by completing a level, and upgrade improvements are put -into the item pool of the multiworld. Also, if enabled, the requirements for completing a level or buying an upgrade are -randomized. +Buildings and gameplay mechanics, which you normally unlock by completing a level, and upgrade improvements are put +into the item pool of the multiworld. You can also randomize the requirements for completing a level or buying an +upgrade and shuffle the order of building in your toolbars (main and wires layer). ## What is the goal of shapez in Archipelago? -As the game has no actual goal where the game ends, there are (currently) 4 different goals you can choose from in the -player options: +As the game has no actual goal that would represent the end of the game, there are (currently) 4 different goals you +can choose from in the player options: 1. Vanilla: Complete level 26 (the end of the tutorial). 2. MAM: Complete a player-specified level after level 26. It's recommended to build a Make-Anything-Machine (MAM). -3. Even Fasterer: Upgrade everything to a player-specified tier after tier 8. +3. Even Fasterer: Upgrade everything to a player-specified tier after tier VIII (8). 4. Efficiency III: Deliver 256 blueprint shapes per second to the hub. ## Which items can be in another player's world? -- Unlock different buildings -- Unlock blueprints -- Big upgrade improvements (adds 1 to the multiplier) -- Small upgrade improvements (adds .1 to the multiplier) -- Other unusual upgrade improvements (optional) +- Buildings +- Unlocking blueprints +- Upgrade improvements + - Big improvements, adding 1 to the multiplier + - Small improvements, adding 0.1 to the multiplier + - Optional: Other, rather unusual and even bad, improvements - Different shapes bundles - Inventory draining traps -- Different traps afflicting random buildings and game mechanics +- Different traps affecting random buildings and game mechanics ## What is considered a location check? @@ -61,5 +62,4 @@ Here's a cheat sheet: ## Can I use other mods alongside the AP client? At the moment, compatibility with other mods is not supported, but not forbidden. Gameplay altering mods will most -likely crash the game or disable loading the afflicted mods, while QoL mods might work without problems. Try at your own -risk. +likely break the game in some way, while small QoL mods might work without problems. Try at your own risk. diff --git a/worlds/shapez/docs/setup_de.md b/worlds/shapez/docs/setup_de.md index 1b927f379056..a2eb92dfa1f6 100644 --- a/worlds/shapez/docs/setup_de.md +++ b/worlds/shapez/docs/setup_de.md @@ -16,9 +16,10 @@ - Archipelago von der [Archipelago-Release-Seite](https://github.com/ArchipelagoMW/Archipelago/releases) * (Für den Text-Client) - * (Alternativ kannst du auch die eingebaute Konsole (nur lesbar) nutzen, indem du beim Starten des Spiels den - `-dev`-Parameter verwendest) -- Universal Tracker (schau im `#future-game-design`-Thread für UT auf dem Discord-Server nach der aktuellen Anleitung) + * (Alternativ kannst du auch die eingebaute Konsole nutzen, indem du das Spiel mit dem `-dev`-Parameter + startest und jede Nachricht als `AP.sendAPMessage(""")` schreibst) +- Universal Tracker (schau im Kanal von UT auf dem Discord-Server nach der aktuellen Anleitung und für weitere + Informationen) ## Installation diff --git a/worlds/shapez/docs/setup_en.md b/worlds/shapez/docs/setup_en.md index 4c91c16a0b5b..2036f75d6c51 100644 --- a/worlds/shapez/docs/setup_en.md +++ b/worlds/shapez/docs/setup_en.md @@ -16,9 +16,9 @@ - Archipelago from the [Archipelago Releases Page](https://github.com/ArchipelagoMW/Archipelago/releases) * (Only for the TextClient) - * (If you want, you can use the built-in console as a read-only text client by launching the game - with the `-dev` parameter) -- Universal Tracker (check UT's `#future-game-design` thread in the discord server for instructions) + * (You can alternatively use the built-in console by launching the game with the `-dev` parameter and typing + `AP.sendAPMessage(""")`) +- Universal Tracker (check UT's channel in the discord server for more information and instructions) ## Installation diff --git a/worlds/shapez/items.py b/worlds/shapez/items.py index aef4c03317ea..2e5816b9fccc 100644 --- a/worlds/shapez/items.py +++ b/worlds/shapez/items.py @@ -1,4 +1,4 @@ -from typing import Dict, Callable, Any, List +from typing import Callable, Any from BaseClasses import Item, ItemClassification as IClass from .options import ShapezOptions @@ -37,7 +37,7 @@ def always_trap(options: ShapezOptions) -> IClass: # would be unreasonably complicated and time-consuming. # Some buildings are not needed to complete the game, but are "logically needed" for the "MAM" achievement. -buildings_processing: Dict[str, Callable[[ShapezOptions], IClass]] = { +buildings_processing: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.cutter: always_progression, ITEMS.cutter_quad: always_progression, ITEMS.rotator: always_progression, @@ -50,7 +50,7 @@ def always_trap(options: ShapezOptions) -> IClass: ITEMS.color_mixer: always_progression, } -buildings_routing: Dict[str, Callable[[ShapezOptions], IClass]] = { +buildings_routing: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.balancer: always_progression, ITEMS.comp_merger: always_progression, ITEMS.comp_splitter: always_progression, @@ -58,12 +58,12 @@ def always_trap(options: ShapezOptions) -> IClass: ITEMS.tunnel_tier_ii: is_mam_achievement_included, } -buildings_other: Dict[str, Callable[[ShapezOptions], IClass]] = { +buildings_other: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.trash: always_progression, ITEMS.extractor_chain: always_useful } -buildings_top_row: Dict[str, Callable[[ShapezOptions], IClass]] = { +buildings_top_row: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.belt_reader: is_mam_achievement_included, ITEMS.storage: is_achievements_included, ITEMS.switch: always_progression, @@ -71,18 +71,18 @@ def always_trap(options: ShapezOptions) -> IClass: ITEMS.display: always_useful } -buildings_wires: Dict[str, Callable[[ShapezOptions], IClass]] = { +buildings_wires: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.wires: always_progression, ITEMS.const_signal: always_progression, ITEMS.logic_gates: is_mam_achievement_included, ITEMS.virtual_proc: is_mam_achievement_included } -gameplay_unlocks: Dict[str, Callable[[ShapezOptions], IClass]] = { +gameplay_unlocks: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.blueprints: is_achievements_included } -upgrades: Dict[str, Callable[[ShapezOptions], IClass]] = { +upgrades: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.upgrade_big_belt: always_progression, ITEMS.upgrade_big_miner: always_useful, ITEMS.upgrade_big_proc: always_useful, @@ -93,7 +93,7 @@ def always_trap(options: ShapezOptions) -> IClass: ITEMS.upgrade_small_paint: always_filler } -whacky_upgrades: Dict[str, Callable[[ShapezOptions], IClass]] = { +whacky_upgrades: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.upgrade_gigantic_belt: always_progression, ITEMS.upgrade_gigantic_miner: always_useful, ITEMS.upgrade_gigantic_proc: always_useful, @@ -106,7 +106,7 @@ def always_trap(options: ShapezOptions) -> IClass: ITEMS.upgrade_small_random: always_filler, } -whacky_upgrade_traps: Dict[str, Callable[[ShapezOptions], IClass]] = { +whacky_upgrade_traps: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.trap_upgrade_belt: always_trap, ITEMS.trap_upgrade_miner: always_trap, ITEMS.trap_upgrade_proc: always_trap, @@ -117,13 +117,13 @@ def always_trap(options: ShapezOptions) -> IClass: ITEMS.trap_upgrade_demonic_paint: always_trap, } -bundles: Dict[str, Callable[[ShapezOptions], IClass]] = { +bundles: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.bundle_blueprint: always_filler, ITEMS.bundle_level: always_filler, ITEMS.bundle_upgrade: always_filler } -standard_traps: Dict[str, Callable[[ShapezOptions], IClass]] = { +standard_traps: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.trap_locked: always_trap, ITEMS.trap_throttled: always_trap, ITEMS.trap_malfunction: always_trap, @@ -131,22 +131,22 @@ def always_trap(options: ShapezOptions) -> IClass: ITEMS.trap_clear_belts: always_trap, } -random_draining_trap: Dict[str, Callable[[ShapezOptions], IClass]] = { +random_draining_trap: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.trap_draining_inv: always_trap } -split_draining_traps: Dict[str, Callable[[ShapezOptions], IClass]] = { +split_draining_traps: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.trap_draining_blueprint: always_trap, ITEMS.trap_draining_level: always_trap, ITEMS.trap_draining_upgrade: always_trap } -belt_and_extractor: Dict[str, Callable[[ShapezOptions], IClass]] = { +belt_and_extractor: dict[str, Callable[[ShapezOptions], IClass]] = { ITEMS.belt: always_progression, ITEMS.extractor: always_progression } -item_table: Dict[str, Callable[[ShapezOptions], IClass]] = { +item_table: dict[str, Callable[[ShapezOptions], IClass]] = { **buildings_processing, **buildings_routing, **buildings_other, @@ -205,10 +205,10 @@ def trap(random: float, split_draining: bool, whacky_allowed: bool) -> str: return random_choice_nested(random, pool) -def random_choice_nested(random: float, nested: List[Any]) -> Any: +def random_choice_nested(random: float, nested: list[Any]) -> Any: """Helper function for getting a random element from a nested list.""" current: Any = nested - while isinstance(current, List): + while isinstance(current, list): index_float = random*len(current) current = current[int(index_float)] random = index_float-int(index_float) diff --git a/worlds/shapez/locations.py b/worlds/shapez/locations.py index 6d069afaa899..f68ca1ebf5b8 100644 --- a/worlds/shapez/locations.py +++ b/worlds/shapez/locations.py @@ -1,5 +1,5 @@ from random import Random -from typing import List, Tuple, Dict, Optional, Callable +from typing import Callable from BaseClasses import Location, LocationProgressType, Region from .data.strings import CATEGORY, LOCATIONS, REGIONS, OPTIONS, GOALS, OTHER, SHAPESANITY @@ -7,7 +7,7 @@ categories = [CATEGORY.belt, CATEGORY.miner, CATEGORY.processors, CATEGORY.painting] -translate: List[Tuple[int, str]] = [ +translate: list[tuple[int, str]] = [ (1000, "M"), (900, "CM"), (500, "D"), @@ -148,17 +148,17 @@ def roman(num: int) -> str: "windmill.", } -shapesanity_simple: Dict[str, str] = {} -shapesanity_1_4: Dict[str, str] = {} -shapesanity_two_sided: Dict[str, str] = {} -shapesanity_three_parts: Dict[str, str] = {} -shapesanity_four_parts: Dict[str, str] = {} +shapesanity_simple: dict[str, str] = {} +shapesanity_1_4: dict[str, str] = {} +shapesanity_two_sided: dict[str, str] = {} +shapesanity_three_parts: dict[str, str] = {} +shapesanity_four_parts: dict[str, str] = {} -level_locations: List[str] = ([LOCATIONS.level(1, 1), LOCATIONS.level(20, 1), LOCATIONS.level(20, 2)] +level_locations: list[str] = ([LOCATIONS.level(1, 1), LOCATIONS.level(20, 1), LOCATIONS.level(20, 2)] + [LOCATIONS.level(x) for x in range(1, max_levels_and_upgrades)]) -upgrade_locations: List[str] = [LOCATIONS.upgrade(cat, roman(x)) +upgrade_locations: list[str] = [LOCATIONS.upgrade(cat, roman(x)) for cat in categories for x in range(2, max_levels_and_upgrades+1)] -achievement_locations: List[str] = [LOCATIONS.my_eyes, LOCATIONS.painter, LOCATIONS.cutter, LOCATIONS.rotater, +achievement_locations: list[str] = [LOCATIONS.my_eyes, LOCATIONS.painter, LOCATIONS.cutter, LOCATIONS.rotater, LOCATIONS.wait_they_stack, LOCATIONS.wires, LOCATIONS.storage, LOCATIONS.freedom, LOCATIONS.the_logo, LOCATIONS.to_the_moon, LOCATIONS.its_piling_up, LOCATIONS.use_it_later, LOCATIONS.efficiency_1, LOCATIONS.preparing_to_launch, @@ -172,7 +172,7 @@ def roman(num: int) -> str: LOCATIONS.mam, LOCATIONS.perfectionist, LOCATIONS.next_dimension, LOCATIONS.oops, LOCATIONS.copy_pasta, LOCATIONS.ive_seen_that_before, LOCATIONS.memories, LOCATIONS.i_need_trains, LOCATIONS.a_bit_early, LOCATIONS.gps] -shapesanity_locations: List[str] = [LOCATIONS.shapesanity(x) for x in range(1, max_shapesanity+1)] +shapesanity_locations: list[str] = [LOCATIONS.shapesanity(x) for x in range(1, max_shapesanity+1)] def init_shapesanity_pool() -> None: @@ -186,12 +186,12 @@ def init_shapesanity_pool() -> None: def addlevels(maxlevel: int, logictype: str, - random_logic_phase_length: List[int]) -> Dict[str, Tuple[str, LocationProgressType]]: + random_logic_phase_length: list[int]) -> dict[str, tuple[str, LocationProgressType]]: """Returns a dictionary with all level locations based on player options (maxlevel INCLUDED). If shape requirements are not randomized, the logic type is expected to be vanilla.""" # Level 1 is always directly accessible - locations: Dict[str, Tuple[str, LocationProgressType]] \ + locations: dict[str, tuple[str, LocationProgressType]] \ = {LOCATIONS.level(1): (REGIONS.main, LocationProgressType.PRIORITY), LOCATIONS.level(1, 1): (REGIONS.main, LocationProgressType.PRIORITY)} level_regions = [REGIONS.main, REGIONS.levels_1, REGIONS.levels_2, REGIONS.levels_3, @@ -282,11 +282,11 @@ def f(name: str, region: str, progress: LocationProgressType = LocationProgressT def addupgrades(finaltier: int, logictype: str, - category_random_logic_amounts: Dict[str, int]) -> Dict[str, Tuple[str, LocationProgressType]]: + category_random_logic_amounts: dict[str, int]) -> dict[str, tuple[str, LocationProgressType]]: """Returns a dictionary with all upgrade locations based on player options (finaltier INCLUDED). If shape requirements are not randomized, give logic type 0.""" - locations: Dict[str, Tuple[str, LocationProgressType]] = {} + locations: dict[str, tuple[str, LocationProgressType]] = {} upgrade_regions = [REGIONS.main, REGIONS.upgrades_1, REGIONS.upgrades_2, REGIONS.upgrades_3, REGIONS.upgrades_4, REGIONS.upgrades_5] @@ -366,13 +366,13 @@ def f(name: str, region: str, progress: LocationProgressType = LocationProgressT def addachievements(excludesoftlock: bool, excludelong: bool, excludeprogressive: bool, - maxlevel: int, upgradelogictype: str, category_random_logic_amounts: Dict[str, int], - goal: str, presentlocations: Dict[str, Tuple[str, LocationProgressType]], + maxlevel: int, upgradelogictype: str, category_random_logic_amounts: dict[str, int], + goal: str, presentlocations: dict[str, tuple[str, LocationProgressType]], add_alias: Callable[[str, str], None], has_upgrade_traps: bool - ) -> Dict[str, Tuple[str, LocationProgressType]]: + ) -> dict[str, tuple[str, LocationProgressType]]: """Returns a dictionary with all achievement locations based on player options.""" - locations: Dict[str, Tuple[str, LocationProgressType]] = dict() + locations: dict[str, tuple[str, LocationProgressType]] = dict() upgrade_regions = [REGIONS.main, REGIONS.upgrades_1, REGIONS.upgrades_2, REGIONS.upgrades_3, REGIONS.upgrades_4, REGIONS.upgrades_5] @@ -472,10 +472,10 @@ def f(name: str, region: str, alias: str, progress: LocationProgressType = Locat def addshapesanity(amount: int, random: Random, append_shapesanity: Callable[[str], None], - add_alias: Callable[[str, str], None]) -> Dict[str, Tuple[str, LocationProgressType]]: + add_alias: Callable[[str, str], None]) -> dict[str, tuple[str, LocationProgressType]]: """Returns a dictionary with a given number of random shapesanity locations.""" - included_shapes: Dict[str, Tuple[str, LocationProgressType]] = {} + included_shapes: dict[str, tuple[str, LocationProgressType]] = {} def f(name: str, region: str, alias: str, progress: LocationProgressType = LocationProgressType.DEFAULT) -> None: included_shapes[name] = (region, progress) @@ -518,11 +518,11 @@ def f(name: str, region: str, alias: str, progress: LocationProgressType = Locat return included_shapes -def addshapesanity_ut(shapesanity_names: List[str], add_alias: Callable[[str, str], None] - ) -> Dict[str, Tuple[str, LocationProgressType]]: +def addshapesanity_ut(shapesanity_names: list[str], add_alias: Callable[[str, str], None] + ) -> dict[str, tuple[str, LocationProgressType]]: """Returns the same information as addshapesanity but will add specific values based on a UT rebuild.""" - included_shapes: Dict[str, Tuple[str, LocationProgressType]] = {} + included_shapes: dict[str, tuple[str, LocationProgressType]] = {} for name in shapesanity_names: for options in [shapesanity_simple, shapesanity_1_4, shapesanity_two_sided, shapesanity_three_parts, @@ -540,7 +540,7 @@ def addshapesanity_ut(shapesanity_names: List[str], add_alias: Callable[[str, st class ShapezLocation(Location): game = OTHER.game_name - def __init__(self, player: int, name: str, address: Optional[int], region: Region, + def __init__(self, player: int, name: str, address: int | None, region: Region, progress_type: LocationProgressType): super(ShapezLocation, self).__init__(player, name, address, region) self.progress_type = progress_type diff --git a/worlds/shapez/regions.py b/worlds/shapez/regions.py index c4ca1d0c816e..b5835461d875 100644 --- a/worlds/shapez/regions.py +++ b/worlds/shapez/regions.py @@ -1,5 +1,3 @@ -from typing import Dict, Tuple, List - from BaseClasses import Region, MultiWorld, LocationProgressType, ItemClassification, CollectionState from .items import ShapezItem from .locations import ShapezLocation @@ -102,7 +100,7 @@ def has_x_belt_multiplier(state: CollectionState, player: int, needed: float) -> return multiplier >= needed -def has_logic_list_building(state: CollectionState, player: int, buildings: List[str], index: int, +def has_logic_list_building(state: CollectionState, player: int, buildings: list[str], index: int, includeuseful: bool) -> bool: # Includes balancer, tunnel, and trash in logic in order to make them appear in earlier spheres @@ -126,11 +124,11 @@ def has_logic_list_building(state: CollectionState, player: int, buildings: List def create_shapez_regions(player: int, multiworld: MultiWorld, floating: bool, - included_locations: Dict[str, Tuple[str, LocationProgressType]], - location_name_to_id: Dict[str, int], level_logic_buildings: List[str], - upgrade_logic_buildings: List[str], early_useful: str, goal: str) -> List[Region]: + included_locations: dict[str, tuple[str, LocationProgressType]], + location_name_to_id: dict[str, int], level_logic_buildings: list[str], + upgrade_logic_buildings: list[str], early_useful: str, goal: str) -> list[Region]: """Creates and returns a list of all regions with entrances and all locations placed correctly.""" - regions: Dict[str, Region] = {name: Region(name, player, multiworld) for name in all_regions} + regions: dict[str, Region] = {name: Region(name, player, multiworld) for name in all_regions} # Creates ShapezLocations for every included location and puts them into the correct region for name, data in included_locations.items(): diff --git a/worlds/shapez/test/__init__.py b/worlds/shapez/test/__init__.py index d2dfad97da6f..c8855be9604d 100644 --- a/worlds/shapez/test/__init__.py +++ b/worlds/shapez/test/__init__.py @@ -1,7 +1,7 @@ from unittest import TestCase from test.bases import WorldTestBase -from .. import options_presets, ShapezWorld +from .. import ShapezWorld from ..data.strings import GOALS, OTHER, ITEMS, LOCATIONS, CATEGORY, OPTIONS, SHAPESANITY from ..options import max_levels_and_upgrades, max_shapesanity From 2a0ed7faa2c38e47db9d04be4d56835cd9c355cb Mon Sep 17 00:00:00 2001 From: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> Date: Tue, 29 Jul 2025 19:18:34 -0400 Subject: [PATCH 0621/1218] LttP: Remove per_slot_randoms in LttPAdjuster.py (#4898) --- LttPAdjuster.py | 1 - 1 file changed, 1 deletion(-) diff --git a/LttPAdjuster.py b/LttPAdjuster.py index 963557e8da81..d44f413499f1 100644 --- a/LttPAdjuster.py +++ b/LttPAdjuster.py @@ -40,7 +40,6 @@ def __init__(self, random): def __init__(self, sprite_pool): import random self.sprite_pool = {1: sprite_pool} - self.per_slot_randoms = {1: random} self.worlds = {1: self.AdjusterSubWorld(random)} From 1d8a0b294055d991ba28c4a29055d44d302ab5cf Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Wed, 30 Jul 2025 03:10:36 +0100 Subject: [PATCH 0622/1218] SM: Speed up deepcopy in copy_mixin (#4228) --- worlds/sm/variaRandomizer/logic/smbool.py | 8 ++++ .../sm/variaRandomizer/logic/smboolmanager.py | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/worlds/sm/variaRandomizer/logic/smbool.py b/worlds/sm/variaRandomizer/logic/smbool.py index b7f596cbbb08..25f20b550a0f 100644 --- a/worlds/sm/variaRandomizer/logic/smbool.py +++ b/worlds/sm/variaRandomizer/logic/smbool.py @@ -66,6 +66,14 @@ def __lt__(self, other): def __copy__(self): return SMBool(self.bool, self.difficulty, self._knows, self._items) + def __deepcopy__(self, memodict): + # `bool` and `difficulty` are a `bool` and `int`, so do not need to be copied. + # The `_knows` list is never mutated, so does not need to be copied. + # The `_items` list is a `list[str | list[str]]` (copied to a flat `list[str]` when accessed through the `items` + # property) that is mutated by code in helpers.py, so needs to be copied. Because there could be lists within + # the list, it is copied using the `flatten()` helper function. + return SMBool(self.bool, self.difficulty, self._knows, flatten(self._items)) + def json(self): # as we have slots instead of dict return {'bool': self.bool, 'difficulty': self.difficulty, 'knows': self.knows, 'items': self.items} diff --git a/worlds/sm/variaRandomizer/logic/smboolmanager.py b/worlds/sm/variaRandomizer/logic/smboolmanager.py index 16f903074e09..27abb0d31d9f 100644 --- a/worlds/sm/variaRandomizer/logic/smboolmanager.py +++ b/worlds/sm/variaRandomizer/logic/smboolmanager.py @@ -8,6 +8,7 @@ from ..utils.objectives import Objectives from ..utils.parameters import Knows, isKnows import logging +from copy import deepcopy import sys class SMBoolManager(object): @@ -34,6 +35,46 @@ def __init__(self, player=0, maxDiff=sys.maxsize, onlyBossLeft = False): self.createFacadeFunctions() self.createKnowsFunctions(player) self.resetItems() + self.itemsPositions = {} + + def __deepcopy__(self, memodict): + # Use __new__ to avoid calling __init__ like copy.deepcopy without __deepcopy__ implemented. + new = object.__new__(type(self)) + + # Copy everything over in the same order as __init__, ensuring that mutable attributes are deeply copied. + + # SMBool instances contain mutable lists, so must be deep-copied. + new._items = {i: deepcopy(v, memodict) for i, v in self._items.items()} + # `_counts` is a dict[str, int], so the dict can be copied because its keys and values are immutable. + new._counts = self._counts.copy() + # `player` is an int. + new.player = self.player + # `maxDiff` is an int. + new.maxDiff = self.maxDiff + # `onlyBossLeft` is a bool. + new.onlyBossLeft = self.onlyBossLeft + # The HelpersGraph keeps reference to the instance, so a new HelpersGraph is required. + new.helpers = Logic.HelpersGraph(new) + # DoorsManager is stateless, so the same instance can be used. + new.doorsManager = self.doorsManager + # Objectives are cached by self.player, so will be the same instance for the copy. + new.objectives = self.objectives + # Copy the facade functions from new.helpers into new.__dict__. + new.createFacadeFunctions() + # Copying the existing 'knows' functions from `self` to `new` is faster than re-creating all the lambdas with + # `new.createKnowsFunctions(player)`. + for key in Knows.__dict__.keys(): + if isKnows(key): + attribute_name = "knows"+key + knows_func = getattr(self, attribute_name) + setattr(new, attribute_name, knows_func) + # There is no need to call `new.resetItems()` because `_items` and `_counts` have been copied over. + # new.resetItems() + # itemsPositions is a `dict[str, tuple[int, int]]`, so the dict can be copied because the keys and values are + # immutable. + new.itemsPositions = self.itemsPositions.copy() + + return new def computeItemsPositions(self): # compute index in cache key for each items @@ -245,6 +286,9 @@ class SMBoolManagerPlando(SMBoolManager): def __init__(self): super(SMBoolManagerPlando, self).__init__() + def __deepcopy__(self, memodict): + return super().__deepcopy__(memodict) + def addItem(self, item): # a new item is available already = self.haveItem(item) From 6125e59ce3360d7c4a9aa97157489c180e12c16a Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 29 Jul 2025 22:33:33 -0400 Subject: [PATCH 0623/1218] Docs: Don't Suggest exclude in create_items (#5256) --- docs/world api.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/docs/world api.md b/docs/world api.md index 17cf81fe92ec..e8932cfd83f3 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -612,17 +612,10 @@ def create_items(self) -> None: # If there are two of the same item, the item has to be twice in the pool. # Which items are added to the pool may depend on player options, e.g. custom win condition like triforce hunt. # Having an item in the start inventory won't remove it from the pool. - # If an item can't have duplicates it has to be excluded manually. - - # List of items to exclude, as a copy since it will be destroyed below - exclude = [item for item in self.multiworld.precollected_items[self.player]] + # If you want to do that, use start_inventory_from_pool for item in map(self.create_item, mygame_items): - if item in exclude: - exclude.remove(item) # this is destructive. create unique list above - self.multiworld.itempool.append(self.create_item("nothing")) - else: - self.multiworld.itempool.append(item) + self.multiworld.itempool.append(item) # itempool and number of locations should match up. # If this is not the case we want to fill the itempool with junk. From 743501addc8e7c4f5b93b46ec9555cc787de5487 Mon Sep 17 00:00:00 2001 From: qwint Date: Tue, 29 Jul 2025 21:42:55 -0500 Subject: [PATCH 0624/1218] Docs: Remove Settings API Back Compat Section (#5255) --- docs/settings api.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/settings api.md b/docs/settings api.md index ef1f20d09815..d701c0175801 100644 --- a/docs/settings api.md +++ b/docs/settings api.md @@ -181,10 +181,3 @@ circular / partial imports. Instead, the code should fetch from settings on dema "Global" settings are populated immediately, while worlds settings are lazy loaded, so if really necessary, "global" settings could be used in global scope of worlds. - - -### APWorld Backwards Compatibility - -APWorlds that want to be compatible with both stable and dev versions, have two options: -1. use the old Utils.get_options() API until Archipelago 0.4.2 is out -2. add some sort of compatibility code to your world that mimics the new API From 8a552e36392166980f949e9a0c37e74ead2b6453 Mon Sep 17 00:00:00 2001 From: Solidus Snake <63137482+TheRealSolidusSnake@users.noreply.github.com> Date: Wed, 30 Jul 2025 07:40:01 -0400 Subject: [PATCH 0625/1218] SMZ3: Fix Junk Item Overflow (#5162) Removed `self.junkItemsNames = [item.Type.name for item in junkItems]` from `create_items` as that was pulling massive amounts of HeartPieces (because they're in junkItems in upstream) to be added if the start_inventory_from_pool was extensive. Getting more than 20 Heart Containers can lead to OHKO situations. ETank was also removed as a junk item that can be used as filler in the earlier defined list of junk items that AP allows since you should only have 14 in the pool. It's not a problem to have more per se, but you really shouldn't have 27 of them in the pool, either. Ammo and such is much less of a problem to have crazy amounts of. --- worlds/smz3/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/worlds/smz3/__init__.py b/worlds/smz3/__init__.py index a98ae11df355..4d0b63f33c36 100644 --- a/worlds/smz3/__init__.py +++ b/worlds/smz3/__init__.py @@ -97,7 +97,6 @@ def __init__(self, world: MultiWorld, player: int): ItemType.TwentyRupees, ItemType.FiftyRupees, ItemType.ThreeHundredRupees, - ItemType.ETank, ItemType.Missile, ItemType.Super, ItemType.PowerBomb @@ -231,7 +230,6 @@ def create_items(self): niceItems = TotalSMZ3Item.Item.CreateNicePool(self.smz3World) junkItems = TotalSMZ3Item.Item.CreateJunkPool(self.smz3World) - self.junkItemsNames = [item.Type.name for item in junkItems] if (self.smz3World.Config.Keysanity): progressionItems = self.progression + self.dungeon + self.keyCardsItems + self.SmMapsItems From 7abe7fe304d6895d92c50436dcf7e2c99f18b6fd Mon Sep 17 00:00:00 2001 From: josephwhite <22449090+josephwhite@users.noreply.github.com> Date: Thu, 31 Jul 2025 15:09:00 -0400 Subject: [PATCH 0626/1218] ALTTP/SNIC/BHC: Stop using Utils.get_settings() (#5239) * LTTP/SNIC/BHC: Stop using Utils.get_settings() * SNIClient: use Settings.sni_options --- SNIClient.py | 6 +++--- worlds/_bizhawk/context.py | 5 +++-- worlds/alttp/Rom.py | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/SNIClient.py b/SNIClient.py index 1156bf6040fb..d8bc05841f77 100644 --- a/SNIClient.py +++ b/SNIClient.py @@ -18,6 +18,7 @@ from CommonClient import CommonContext, server_loop, ClientCommandProcessor, gui_enabled, get_base_parser import Utils +from settings import Settings from Utils import async_start from MultiServer import mark_raw if typing.TYPE_CHECKING: @@ -285,7 +286,7 @@ class SNESState(enum.IntEnum): def launch_sni() -> None: - sni_path = Utils.get_settings()["sni_options"]["sni_path"] + sni_path = Settings.sni_options.sni_path if not os.path.isdir(sni_path): sni_path = Utils.local_path(sni_path) @@ -668,8 +669,7 @@ async def game_watcher(ctx: SNIContext) -> None: async def run_game(romfile: str) -> None: - auto_start = typing.cast(typing.Union[bool, str], - Utils.get_settings()["sni_options"].get("snes_rom_start", True)) + auto_start = Settings.sni_options.snes_rom_start if auto_start is True: import webbrowser webbrowser.open(romfile) diff --git a/worlds/_bizhawk/context.py b/worlds/_bizhawk/context.py index 250e4a882642..142c2964009c 100644 --- a/worlds/_bizhawk/context.py +++ b/worlds/_bizhawk/context.py @@ -9,6 +9,7 @@ import subprocess from typing import Any +import settings from CommonClient import CommonContext, ClientCommandProcessor, get_base_parser, server_loop, logger, gui_enabled import Patch import Utils @@ -304,10 +305,10 @@ async def _game_watcher(ctx: BizHawkClientContext): async def _run_game(rom: str): import os - auto_start = Utils.get_settings().bizhawkclient_options.rom_start + auto_start = settings.get_settings().bizhawkclient_options.rom_start if auto_start is True: - emuhawk_path = Utils.get_settings().bizhawkclient_options.emuhawk_path + emuhawk_path = settings.get_settings().bizhawkclient_options.emuhawk_path subprocess.Popen( [ emuhawk_path, diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index 99cc78e2d97d..399d64d433fd 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -1,6 +1,7 @@ from __future__ import annotations import Utils +import settings import worlds.Files LTTPJPN10HASH: str = "03a63945398191337e896e5771f77173" @@ -3023,7 +3024,7 @@ def get_base_rom_bytes(file_name: str = "") -> bytes: def get_base_rom_path(file_name: str = "") -> str: - options = Utils.get_settings() + options = settings.get_settings() if not file_name: file_name = options["lttp_options"]["rom_file"] if not os.path.exists(file_name): From 754e0a0de47d564840c9949fb5e1b6214afcff05 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Thu, 31 Jul 2025 14:42:42 -0500 Subject: [PATCH 0627/1218] Core: hard deprecate per_slot_randoms (#3382) Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- BaseClasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index 10d054063392..4b2c66434f0a 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -183,7 +183,7 @@ def set_player_attr(attr: str, val) -> None: set_player_attr('completion_condition', lambda state: True) self.worlds = {} self.per_slot_randoms = Utils.DeprecateDict("Using per_slot_randoms is now deprecated. Please use the " - "world's random object instead (usually self.random)") + "world's random object instead (usually self.random)", True) self.plando_options = PlandoOptions.none def get_all_ids(self) -> Tuple[int, ...]: From b1f729a9704c8de297cf253bb50930bb99b54c1f Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Thu, 31 Jul 2025 14:33:56 -0600 Subject: [PATCH 0628/1218] Core: Remove Checks for Unsupported Versions (#5067) * Remove redundant version checks/compatibility * Change windows7 check * Edit comments Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --------- Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- Options.py | 2 +- Utils.py | 3 +-- setup.py | 10 +++------- test/benchmark/locations.py | 11 +++-------- worlds/__init__.py | 4 +--- 5 files changed, 9 insertions(+), 21 deletions(-) diff --git a/Options.py b/Options.py index 3e67d68569e9..47d6c2d38708 100644 --- a/Options.py +++ b/Options.py @@ -1118,7 +1118,7 @@ class Direction: entrance: str exit: str - direction: typing.Literal["entrance", "exit", "both"] # TODO: convert Direction to StrEnum once 3.8 is dropped + direction: typing.Literal["entrance", "exit", "both"] # TODO: convert Direction to StrEnum once 3.10 is dropped percentage: int = 100 diff --git a/Utils.py b/Utils.py index abf359f43e07..b7616b57b125 100644 --- a/Utils.py +++ b/Utils.py @@ -953,8 +953,7 @@ def _freeze_support() -> None: # Handle the first process that MP will create if ( len(sys.argv) >= 2 and sys.argv[-2] == '-c' and sys.argv[-1].startswith(( - 'from multiprocessing.semaphore_tracker import main', # Py<3.8 - 'from multiprocessing.resource_tracker import main', # Py>=3.8 + 'from multiprocessing.resource_tracker import main', 'from multiprocessing.forkserver import main' )) and set(sys.argv[1:-2]) == set(_args_from_interpreter_flags()) ): diff --git a/setup.py b/setup.py index 704325d70cbb..c24a44352699 100644 --- a/setup.py +++ b/setup.py @@ -61,7 +61,6 @@ from Cython.Build import cythonize -# On Python < 3.10 LogicMixin is not currently supported. non_apworlds: set[str] = { "A Link to the Past", "Adventure", @@ -78,9 +77,6 @@ "Wargroove", } -# LogicMixin is broken before 3.10 import revamp -if sys.version_info < (3,10): - non_apworlds.add("Hollow Knight") def download_SNI() -> None: print("Updating SNI") @@ -108,8 +104,8 @@ def download_SNI() -> None: # prefer "many" builds if "many" in download_url: break - # prefer the correct windows or windows7 build - if platform_name == "windows" and ("windows7" in download_url) == (sys.version_info < (3, 9)): + # prefer non-windows7 builds to get up-to-date dependencies + if platform_name == "windows" and "windows7" not in download_url: break if source_url and source_url.endswith(".zip"): @@ -418,7 +414,7 @@ def run(self) -> None: if is_windows: # Inno setup stuff with open("setup.ini", "w") as f: - min_supported_windows = "6.2.9200" if sys.version_info > (3, 9) else "6.0.6000" + min_supported_windows = "6.2.9200" f.write(f"[Data]\nsource_path={self.buildfolder}\nmin_windows={min_supported_windows}\n") with open("installdelete.iss", "w") as f: f.writelines("Type: filesandordirs; Name: \"{app}\\lib\\worlds\\"+world_directory+"\"\n" diff --git a/test/benchmark/locations.py b/test/benchmark/locations.py index 16667a17b9af..0e496cd3eefb 100644 --- a/test/benchmark/locations.py +++ b/test/benchmark/locations.py @@ -29,14 +29,9 @@ class BenchmarkRunner: rule_iterations: int = 100_000 - if sys.version_info >= (3, 9): - @staticmethod - def format_times_from_counter(counter: collections.Counter[str], top: int = 5) -> str: - return "\n".join(f" {time:.4f} in {name}" for name, time in counter.most_common(top)) - else: - @staticmethod - def format_times_from_counter(counter: collections.Counter, top: int = 5) -> str: - return "\n".join(f" {time:.4f} in {name}" for name, time in counter.most_common(top)) + @staticmethod + def format_times_from_counter(counter: collections.Counter[str], top: int = 5) -> str: + return "\n".join(f" {time:.4f} in {name}" for name, time in counter.most_common(top)) def location_test(self, test_location: Location, state: CollectionState, state_name: str) -> float: with TimeIt(f"{test_location.game} {self.rule_iterations} " diff --git a/worlds/__init__.py b/worlds/__init__.py index 80240275b02f..89f7bcd063f0 100644 --- a/worlds/__init__.py +++ b/worlds/__init__.py @@ -63,9 +63,7 @@ def load(self) -> bool: sys.modules[mod.__name__] = mod with warnings.catch_warnings(): warnings.filterwarnings("ignore", message="__package__ != __spec__.parent") - # Found no equivalent for < 3.10 - if hasattr(importer, "exec_module"): - importer.exec_module(mod) + importer.exec_module(mod) else: importlib.import_module(f".{self.path}", "worlds") self.time_taken = time.perf_counter()-start From 2fe51d087f97ff718ad2421a630335fff6ca4a56 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Thu, 31 Jul 2025 22:43:34 +0200 Subject: [PATCH 0629/1218] CI: also use new appimage tool in release action --- .github/workflows/release.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a500f9a23b3f..1462560052cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,12 @@ on: env: ENEMIZER_VERSION: 7.1 - APPIMAGETOOL_VERSION: 13 + # NOTE: since appimage/appimagetool and appimage/type2-runtime does not have tags anymore, + # we check the sha256 and require manual intervention if it was updated. + APPIMAGETOOL_VERSION: continuous + APPIMAGETOOL_X86_64_HASH: '363dafac070b65cc36ca024b74db1f043c6f5cd7be8fca760e190dce0d18d684' + APPIMAGE_RUNTIME_VERSION: continuous + APPIMAGE_RUNTIME_X86_64_HASH: 'e3c4dfb70eddf42e7e5a1d28dff396d30563aa9a901970aebe6f01f3fecf9f8e' permissions: # permissions required for attestation id-token: 'write' @@ -122,10 +127,13 @@ jobs: - name: Install build-time dependencies run: | echo "PYTHON=python3.12" >> $GITHUB_ENV - wget -nv https://github.com/AppImage/AppImageKit/releases/download/$APPIMAGETOOL_VERSION/appimagetool-x86_64.AppImage + wget -nv https://github.com/AppImage/appimagetool/releases/download/$APPIMAGETOOL_VERSION/appimagetool-x86_64.AppImage + echo "$APPIMAGETOOL_X86_64_HASH appimagetool-x86_64.AppImage" | sha256sum -c + wget -nv https://github.com/AppImage/type2-runtime/releases/download/$APPIMAGE_RUNTIME_VERSION/runtime-x86_64 + echo "$APPIMAGE_RUNTIME_X86_64_HASH runtime-x86_64" | sha256sum -c chmod a+rx appimagetool-x86_64.AppImage ./appimagetool-x86_64.AppImage --appimage-extract - echo -e '#/bin/sh\n./squashfs-root/AppRun "$@"' > appimagetool + echo -e '#/bin/sh\n./squashfs-root/AppRun --runtime-file runtime-x86_64 "$@"' > appimagetool chmod a+rx appimagetool - name: Download run-time dependencies run: | From 8c07a2c930538dc45f5be2db0b883673c85320e3 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 1 Aug 2025 00:43:08 +0200 Subject: [PATCH 0630/1218] WebHost: turn module discovery dynamic (#5218) --- WebHostLib/__init__.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/WebHostLib/__init__.py b/WebHostLib/__init__.py index e928b8f3b1b5..74086cb8842b 100644 --- a/WebHostLib/__init__.py +++ b/WebHostLib/__init__.py @@ -87,12 +87,17 @@ def to_url(self, value): def register(): """Import submodules, triggering their registering on flask routing. Note: initializes worlds subsystem.""" + import importlib + + from werkzeug.utils import find_modules # has automatic patch integration import worlds.Files app.jinja_env.filters['is_applayercontainer'] = worlds.Files.is_ap_player_container from WebHostLib.customserver import run_server_process - # to trigger app routing picking up on it - from . import tracker, upload, landing, check, generate, downloads, api, stats, misc, robots, options, session + for module in find_modules("WebHostLib", include_packages=True): + importlib.import_module(module) + + from . import api app.register_blueprint(api.api_endpoints) From e7131eddc286dd252c91c391b8ecb796431a7e6d Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 1 Aug 2025 00:43:43 +0200 Subject: [PATCH 0631/1218] Setup: update cert signing process (#5161) --- setup.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/setup.py b/setup.py index c24a44352699..593a45f83085 100644 --- a/setup.py +++ b/setup.py @@ -9,6 +9,7 @@ import sys import sysconfig import threading +import urllib.error import urllib.request import warnings import zipfile @@ -144,15 +145,16 @@ def download_SNI() -> None: print(f"No SNI found for system spec {platform_name} {machine_name}") -signtool: str | None -if os.path.exists("X:/pw.txt"): - print("Using signtool") - with open("X:/pw.txt", encoding="utf-8-sig") as f: - pw = f.read() - signtool = r'signtool sign /f X:/_SITS_Zertifikat_.pfx /p "' + pw + \ - r'" /fd sha256 /td sha256 /tr http://timestamp.digicert.com/ ' -else: - signtool = None +signtool: str | None = None +try: + with urllib.request.urlopen('http://192.168.206.4:12345/connector/status') as response: + html = response.read() + if b"status=OK\n" in html: + signtool = (r'signtool sign /sha1 6df76fe776b82869a5693ddcb1b04589cffa6faf /fd sha256 /td sha256 ' + r'/tr http://timestamp.digicert.com/ ') + print("Using signtool") +except (ConnectionError, TimeoutError, urllib.error.URLError) as e: + pass build_platform = sysconfig.get_platform() From 332f955159bb6817be427be4b2b6d930ba0aba6d Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Fri, 1 Aug 2025 01:16:54 +0200 Subject: [PATCH 0632/1218] =?UTF-8?q?The=20Witness:=20Comply=20with=20new?= =?UTF-8?q?=20test=20base=20structure=C2=A0#5265?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worlds/witness/test/__init__.py | 196 ------------------ worlds/witness/test/bases.py | 196 ++++++++++++++++++ worlds/witness/test/test_auto_elevators.py | 2 +- .../test/test_disable_non_randomized.py | 2 +- worlds/witness/test/test_door_shuffle.py | 2 +- .../witness/test/test_easter_egg_shuffle.py | 2 +- worlds/witness/test/test_ep_shuffle.py | 2 +- worlds/witness/test/test_lasers.py | 2 +- worlds/witness/test/test_panel_hunt.py | 2 +- .../witness/test/test_roll_other_options.py | 2 +- worlds/witness/test/test_symbol_shuffle.py | 2 +- worlds/witness/test/test_weird_traversals.py | 2 +- 12 files changed, 206 insertions(+), 206 deletions(-) create mode 100644 worlds/witness/test/bases.py diff --git a/worlds/witness/test/__init__.py b/worlds/witness/test/__init__.py index c3b427851af0..e69de29bb2d1 100644 --- a/worlds/witness/test/__init__.py +++ b/worlds/witness/test/__init__.py @@ -1,196 +0,0 @@ -from typing import Any, ClassVar, Dict, Iterable, List, Mapping, Union - -from BaseClasses import CollectionState, Entrance, Item, Location, Region - -from test.bases import WorldTestBase -from test.general import gen_steps, setup_multiworld -from test.multiworld.test_multiworlds import MultiworldTestBase - -from .. import WitnessWorld -from ..data.utils import cast_not_none - - -class WitnessTestBase(WorldTestBase): - game = "The Witness" - player: ClassVar[int] = 1 - - world: WitnessWorld - - def can_beat_game_with_items(self, items: Iterable[Item]) -> bool: - """ - Check that the items listed are enough to beat the game. - """ - - state = CollectionState(self.multiworld) - for item in items: - state.collect(item) - return state.multiworld.can_beat_game(state) - - def assert_dependency_on_event_item(self, spot: Union[Location, Region, Entrance], item_name: str) -> None: - """ - WorldTestBase.assertAccessDependency, but modified & simplified to work with event items - """ - event_items = [item for item in self.multiworld.get_items() if item.name == item_name] - self.assertTrue(event_items, f"Event item {item_name} does not exist.") - - event_locations = [cast_not_none(event_item.location) for event_item in event_items] - - # Checking for an access dependency on an event item requires a bit of extra work, - # as state.remove forces a sweep, which will pick up the event item again right after we tried to remove it. - # So, we temporarily set the access rules of the event locations to be impossible. - original_rules = {event_location.name: event_location.access_rule for event_location in event_locations} - for event_location in event_locations: - event_location.access_rule = lambda _: False - - # We can't use self.assertAccessDependency here, it doesn't work for event items. (As of 2024-06-30) - test_state = self.multiworld.get_all_state(False) - - self.assertFalse(spot.can_reach(test_state), f"{spot.name} is reachable without {item_name}") - - test_state.collect(event_items[0]) - - self.assertTrue(spot.can_reach(test_state), f"{spot.name} is not reachable despite having {item_name}") - - # Restore original access rules. - for event_location in event_locations: - event_location.access_rule = original_rules[event_location.name] - - def assert_location_exists(self, location_name: str, strict_check: bool = True) -> None: - """ - Assert that a location exists in this world. - If strict_check, also make sure that this (non-event) location COULD exist. - """ - - if strict_check: - self.assertIn(location_name, self.world.location_name_to_id, f"Location {location_name} can never exist") - - try: - self.world.get_location(location_name) - except KeyError: - self.fail(f"Location {location_name} does not exist.") - - def assert_location_does_not_exist(self, location_name: str, strict_check: bool = True) -> None: - """ - Assert that a location exists in this world. - If strict_check, be explicit about whether the location could exist in the first place. - """ - - if strict_check: - self.assertIn(location_name, self.world.location_name_to_id, f"Location {location_name} can never exist") - - self.assertRaises( - KeyError, - lambda _: self.world.get_location(location_name), - f"Location {location_name} exists, but is not supposed to.", - ) - - def assert_can_beat_with_minimally(self, required_item_counts: Mapping[str, int]) -> None: - """ - Assert that the specified mapping of items is enough to beat the game, - and that having one less of any item would result in the game being unbeatable. - """ - # Find the actual items - found_items = [item for item in self.multiworld.get_items() if item.name in required_item_counts] - actual_items: Dict[str, List[Item]] = {item_name: [] for item_name in required_item_counts} - for item in found_items: - if len(actual_items[item.name]) < required_item_counts[item.name]: - actual_items[item.name].append(item) - - # Assert that enough items exist in the item pool to satisfy the specified required counts - for item_name, item_objects in actual_items.items(): - self.assertEqual( - len(item_objects), - required_item_counts[item_name], - f"Couldn't find {required_item_counts[item_name]} copies of item {item_name} available in the pool, " - f"only found {len(item_objects)}", - ) - - # assert that multiworld is beatable with the items specified - self.assertTrue( - self.can_beat_game_with_items(item for items in actual_items.values() for item in items), - f"Could not beat game with items: {required_item_counts}", - ) - - # assert that one less copy of any item would result in the multiworld being unbeatable - for item_name, item_objects in actual_items.items(): - with self.subTest(f"Verify cannot beat game with one less copy of {item_name}"): - removed_item = item_objects.pop() - self.assertFalse( - self.can_beat_game_with_items(item for items in actual_items.values() for item in items), - f"Game was beatable despite having {len(item_objects)} copies of {item_name} " - f"instead of the specified {required_item_counts[item_name]}", - ) - item_objects.append(removed_item) - - -class WitnessMultiworldTestBase(MultiworldTestBase): - options_per_world: List[Dict[str, Any]] - common_options: Dict[str, Any] = {} - - def setUp(self) -> None: - """ - Set up a multiworld with multiple players, each using different options. - """ - - self.multiworld = setup_multiworld([WitnessWorld] * len(self.options_per_world), ()) - - for world, options in zip(self.multiworld.worlds.values(), self.options_per_world): - for option_name, option_value in {**self.common_options, **options}.items(): - option = getattr(world.options, option_name) - self.assertIsNotNone(option) - - option.value = option.from_any(option_value).value - - self.assertSteps(gen_steps) - - def collect_by_name(self, item_names: Union[str, Iterable[str]], player: int) -> List[Item]: - """ - Collect all copies of a specified item name (or list of item names) for a player in the multiworld item pool. - """ - - items = self.get_items_by_name(item_names, player) - for item in items: - self.multiworld.state.collect(item) - return items - - def get_items_by_name(self, item_names: Union[str, Iterable[str]], player: int) -> List[Item]: - """ - Return all copies of a specified item name (or list of item names) for a player in the multiworld item pool. - """ - - if isinstance(item_names, str): - item_names = (item_names,) - return [item for item in self.multiworld.itempool if item.name in item_names and item.player == player] - - def assert_location_exists(self, location_name: str, player: int, strict_check: bool = True) -> None: - """ - Assert that a location exists in this world. - If strict_check, also make sure that this (non-event) location COULD exist. - """ - - world = self.multiworld.worlds[player] - - if strict_check: - self.assertIn(location_name, world.location_name_to_id, f"Location {location_name} can never exist") - - try: - world.get_location(location_name) - except KeyError: - self.fail(f"Location {location_name} does not exist.") - - def assert_location_does_not_exist(self, location_name: str, player: int, strict_check: bool = True) -> None: - """ - Assert that a location exists in this world. - If strict_check, be explicit about whether the location could exist in the first place. - """ - - world = self.multiworld.worlds[player] - - if strict_check: - self.assertIn(location_name, world.location_name_to_id, f"Location {location_name} can never exist") - - self.assertRaises( - KeyError, - lambda _: world.get_location(location_name), - f"Location {location_name} exists, but is not supposed to.", - ) diff --git a/worlds/witness/test/bases.py b/worlds/witness/test/bases.py new file mode 100644 index 000000000000..c3b427851af0 --- /dev/null +++ b/worlds/witness/test/bases.py @@ -0,0 +1,196 @@ +from typing import Any, ClassVar, Dict, Iterable, List, Mapping, Union + +from BaseClasses import CollectionState, Entrance, Item, Location, Region + +from test.bases import WorldTestBase +from test.general import gen_steps, setup_multiworld +from test.multiworld.test_multiworlds import MultiworldTestBase + +from .. import WitnessWorld +from ..data.utils import cast_not_none + + +class WitnessTestBase(WorldTestBase): + game = "The Witness" + player: ClassVar[int] = 1 + + world: WitnessWorld + + def can_beat_game_with_items(self, items: Iterable[Item]) -> bool: + """ + Check that the items listed are enough to beat the game. + """ + + state = CollectionState(self.multiworld) + for item in items: + state.collect(item) + return state.multiworld.can_beat_game(state) + + def assert_dependency_on_event_item(self, spot: Union[Location, Region, Entrance], item_name: str) -> None: + """ + WorldTestBase.assertAccessDependency, but modified & simplified to work with event items + """ + event_items = [item for item in self.multiworld.get_items() if item.name == item_name] + self.assertTrue(event_items, f"Event item {item_name} does not exist.") + + event_locations = [cast_not_none(event_item.location) for event_item in event_items] + + # Checking for an access dependency on an event item requires a bit of extra work, + # as state.remove forces a sweep, which will pick up the event item again right after we tried to remove it. + # So, we temporarily set the access rules of the event locations to be impossible. + original_rules = {event_location.name: event_location.access_rule for event_location in event_locations} + for event_location in event_locations: + event_location.access_rule = lambda _: False + + # We can't use self.assertAccessDependency here, it doesn't work for event items. (As of 2024-06-30) + test_state = self.multiworld.get_all_state(False) + + self.assertFalse(spot.can_reach(test_state), f"{spot.name} is reachable without {item_name}") + + test_state.collect(event_items[0]) + + self.assertTrue(spot.can_reach(test_state), f"{spot.name} is not reachable despite having {item_name}") + + # Restore original access rules. + for event_location in event_locations: + event_location.access_rule = original_rules[event_location.name] + + def assert_location_exists(self, location_name: str, strict_check: bool = True) -> None: + """ + Assert that a location exists in this world. + If strict_check, also make sure that this (non-event) location COULD exist. + """ + + if strict_check: + self.assertIn(location_name, self.world.location_name_to_id, f"Location {location_name} can never exist") + + try: + self.world.get_location(location_name) + except KeyError: + self.fail(f"Location {location_name} does not exist.") + + def assert_location_does_not_exist(self, location_name: str, strict_check: bool = True) -> None: + """ + Assert that a location exists in this world. + If strict_check, be explicit about whether the location could exist in the first place. + """ + + if strict_check: + self.assertIn(location_name, self.world.location_name_to_id, f"Location {location_name} can never exist") + + self.assertRaises( + KeyError, + lambda _: self.world.get_location(location_name), + f"Location {location_name} exists, but is not supposed to.", + ) + + def assert_can_beat_with_minimally(self, required_item_counts: Mapping[str, int]) -> None: + """ + Assert that the specified mapping of items is enough to beat the game, + and that having one less of any item would result in the game being unbeatable. + """ + # Find the actual items + found_items = [item for item in self.multiworld.get_items() if item.name in required_item_counts] + actual_items: Dict[str, List[Item]] = {item_name: [] for item_name in required_item_counts} + for item in found_items: + if len(actual_items[item.name]) < required_item_counts[item.name]: + actual_items[item.name].append(item) + + # Assert that enough items exist in the item pool to satisfy the specified required counts + for item_name, item_objects in actual_items.items(): + self.assertEqual( + len(item_objects), + required_item_counts[item_name], + f"Couldn't find {required_item_counts[item_name]} copies of item {item_name} available in the pool, " + f"only found {len(item_objects)}", + ) + + # assert that multiworld is beatable with the items specified + self.assertTrue( + self.can_beat_game_with_items(item for items in actual_items.values() for item in items), + f"Could not beat game with items: {required_item_counts}", + ) + + # assert that one less copy of any item would result in the multiworld being unbeatable + for item_name, item_objects in actual_items.items(): + with self.subTest(f"Verify cannot beat game with one less copy of {item_name}"): + removed_item = item_objects.pop() + self.assertFalse( + self.can_beat_game_with_items(item for items in actual_items.values() for item in items), + f"Game was beatable despite having {len(item_objects)} copies of {item_name} " + f"instead of the specified {required_item_counts[item_name]}", + ) + item_objects.append(removed_item) + + +class WitnessMultiworldTestBase(MultiworldTestBase): + options_per_world: List[Dict[str, Any]] + common_options: Dict[str, Any] = {} + + def setUp(self) -> None: + """ + Set up a multiworld with multiple players, each using different options. + """ + + self.multiworld = setup_multiworld([WitnessWorld] * len(self.options_per_world), ()) + + for world, options in zip(self.multiworld.worlds.values(), self.options_per_world): + for option_name, option_value in {**self.common_options, **options}.items(): + option = getattr(world.options, option_name) + self.assertIsNotNone(option) + + option.value = option.from_any(option_value).value + + self.assertSteps(gen_steps) + + def collect_by_name(self, item_names: Union[str, Iterable[str]], player: int) -> List[Item]: + """ + Collect all copies of a specified item name (or list of item names) for a player in the multiworld item pool. + """ + + items = self.get_items_by_name(item_names, player) + for item in items: + self.multiworld.state.collect(item) + return items + + def get_items_by_name(self, item_names: Union[str, Iterable[str]], player: int) -> List[Item]: + """ + Return all copies of a specified item name (or list of item names) for a player in the multiworld item pool. + """ + + if isinstance(item_names, str): + item_names = (item_names,) + return [item for item in self.multiworld.itempool if item.name in item_names and item.player == player] + + def assert_location_exists(self, location_name: str, player: int, strict_check: bool = True) -> None: + """ + Assert that a location exists in this world. + If strict_check, also make sure that this (non-event) location COULD exist. + """ + + world = self.multiworld.worlds[player] + + if strict_check: + self.assertIn(location_name, world.location_name_to_id, f"Location {location_name} can never exist") + + try: + world.get_location(location_name) + except KeyError: + self.fail(f"Location {location_name} does not exist.") + + def assert_location_does_not_exist(self, location_name: str, player: int, strict_check: bool = True) -> None: + """ + Assert that a location exists in this world. + If strict_check, be explicit about whether the location could exist in the first place. + """ + + world = self.multiworld.worlds[player] + + if strict_check: + self.assertIn(location_name, world.location_name_to_id, f"Location {location_name} can never exist") + + self.assertRaises( + KeyError, + lambda _: world.get_location(location_name), + f"Location {location_name} exists, but is not supposed to.", + ) diff --git a/worlds/witness/test/test_auto_elevators.py b/worlds/witness/test/test_auto_elevators.py index f91943e85577..6762657b8e46 100644 --- a/worlds/witness/test/test_auto_elevators.py +++ b/worlds/witness/test/test_auto_elevators.py @@ -1,4 +1,4 @@ -from ..test import WitnessMultiworldTestBase +from ..test.bases import WitnessMultiworldTestBase class TestElevatorsComeToYouBleed(WitnessMultiworldTestBase): diff --git a/worlds/witness/test/test_disable_non_randomized.py b/worlds/witness/test/test_disable_non_randomized.py index bf285f035d5b..00071ec5f6f0 100644 --- a/worlds/witness/test/test_disable_non_randomized.py +++ b/worlds/witness/test/test_disable_non_randomized.py @@ -1,5 +1,5 @@ from ..rules import _has_lasers -from ..test import WitnessTestBase +from ..test.bases import WitnessTestBase class TestDisableNonRandomized(WitnessTestBase): diff --git a/worlds/witness/test/test_door_shuffle.py b/worlds/witness/test/test_door_shuffle.py index ca4d6e0aa83e..be0a3332f32d 100644 --- a/worlds/witness/test/test_door_shuffle.py +++ b/worlds/witness/test/test_door_shuffle.py @@ -1,7 +1,7 @@ from typing import cast from .. import WitnessWorld -from ..test import WitnessMultiworldTestBase, WitnessTestBase +from ..test.bases import WitnessMultiworldTestBase, WitnessTestBase class TestIndividualDoors(WitnessTestBase): diff --git a/worlds/witness/test/test_easter_egg_shuffle.py b/worlds/witness/test/test_easter_egg_shuffle.py index 300d32f97fc6..a95357c6e12e 100644 --- a/worlds/witness/test/test_easter_egg_shuffle.py +++ b/worlds/witness/test/test_easter_egg_shuffle.py @@ -3,7 +3,7 @@ from BaseClasses import LocationProgressType from .. import WitnessWorld -from ..test import WitnessMultiworldTestBase +from ..test.bases import WitnessMultiworldTestBase class TestEasterEggShuffle(WitnessMultiworldTestBase): diff --git a/worlds/witness/test/test_ep_shuffle.py b/worlds/witness/test/test_ep_shuffle.py index 342390916675..17297fbcf38e 100644 --- a/worlds/witness/test/test_ep_shuffle.py +++ b/worlds/witness/test/test_ep_shuffle.py @@ -1,4 +1,4 @@ -from ..test import WitnessTestBase +from ..test.bases import WitnessTestBase class TestIndividualEPs(WitnessTestBase): diff --git a/worlds/witness/test/test_lasers.py b/worlds/witness/test/test_lasers.py index 5e60dfc52172..5681757161e7 100644 --- a/worlds/witness/test/test_lasers.py +++ b/worlds/witness/test/test_lasers.py @@ -1,4 +1,4 @@ -from ..test import WitnessTestBase +from ..test.bases import WitnessTestBase class TestSymbolsRequiredToWinElevatorNormal(WitnessTestBase): diff --git a/worlds/witness/test/test_panel_hunt.py b/worlds/witness/test/test_panel_hunt.py index 2f8434802b75..6dea65507098 100644 --- a/worlds/witness/test/test_panel_hunt.py +++ b/worlds/witness/test/test_panel_hunt.py @@ -1,6 +1,6 @@ from BaseClasses import CollectionState -from worlds.witness.test import WitnessMultiworldTestBase, WitnessTestBase +from ..test.bases import WitnessMultiworldTestBase, WitnessTestBase class TestMaxPanelHuntMinChecks(WitnessTestBase): diff --git a/worlds/witness/test/test_roll_other_options.py b/worlds/witness/test/test_roll_other_options.py index 05f3235a1f4d..72313034e495 100644 --- a/worlds/witness/test/test_roll_other_options.py +++ b/worlds/witness/test/test_roll_other_options.py @@ -1,5 +1,5 @@ from ..options import ElevatorsComeToYou -from ..test import WitnessTestBase +from ..test.bases import WitnessTestBase # These are just some random options combinations, just to catch whether I broke anything obvious diff --git a/worlds/witness/test/test_symbol_shuffle.py b/worlds/witness/test/test_symbol_shuffle.py index 3be874f3c0eb..fb1d82081594 100644 --- a/worlds/witness/test/test_symbol_shuffle.py +++ b/worlds/witness/test/test_symbol_shuffle.py @@ -1,4 +1,4 @@ -from ..test import WitnessMultiworldTestBase, WitnessTestBase +from ..test.bases import WitnessMultiworldTestBase, WitnessTestBase class TestSymbols(WitnessTestBase): diff --git a/worlds/witness/test/test_weird_traversals.py b/worlds/witness/test/test_weird_traversals.py index 47b69b01fb4a..9447a1392217 100644 --- a/worlds/witness/test/test_weird_traversals.py +++ b/worlds/witness/test/test_weird_traversals.py @@ -1,4 +1,4 @@ -from ..test import WitnessTestBase +from ..test.bases import WitnessTestBase class TestWeirdTraversalRequirements(WitnessTestBase): From 8bb236411d09604b5fe50f689ba0815587bed1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wilhelm=20Sch=C3=BCrmann?= Date: Fri, 1 Aug 2025 20:01:18 +0200 Subject: [PATCH 0633/1218] Various: Make clients wait a second between connects (#5061) --- AdventureClient.py | 1 + MMBN3Client.py | 1 + OoTClient.py | 1 + Zelda1Client.py | 1 + 4 files changed, 4 insertions(+) diff --git a/AdventureClient.py b/AdventureClient.py index a4839c902dd0..b89b8f060009 100644 --- a/AdventureClient.py +++ b/AdventureClient.py @@ -407,6 +407,7 @@ async def atari_sync_task(ctx: AdventureContext): except ConnectionRefusedError: logger.debug("Connection Refused, Trying Again") ctx.atari_status = CONNECTION_REFUSED_STATUS + await asyncio.sleep(1) continue except CancelledError: pass diff --git a/MMBN3Client.py b/MMBN3Client.py index bdf1427475af..31c6b309b8d7 100644 --- a/MMBN3Client.py +++ b/MMBN3Client.py @@ -286,6 +286,7 @@ async def gba_sync_task(ctx: MMBN3Context): except ConnectionRefusedError: logger.debug("Connection Refused, Trying Again") ctx.gba_status = CONNECTION_REFUSED_STATUS + await asyncio.sleep(1) continue diff --git a/OoTClient.py b/OoTClient.py index 571300ed36f5..2b0c7e4966f0 100644 --- a/OoTClient.py +++ b/OoTClient.py @@ -277,6 +277,7 @@ async def n64_sync_task(ctx: OoTContext): except ConnectionRefusedError: logger.debug("Connection Refused, Trying Again") ctx.n64_status = CONNECTION_REFUSED_STATUS + await asyncio.sleep(1) continue diff --git a/Zelda1Client.py b/Zelda1Client.py index 4473b3f3c7a3..9753621ef013 100644 --- a/Zelda1Client.py +++ b/Zelda1Client.py @@ -333,6 +333,7 @@ async def nes_sync_task(ctx: ZeldaContext): except ConnectionRefusedError: logger.debug("Connection Refused, Trying Again") ctx.nes_status = CONNECTION_REFUSED_STATUS + await asyncio.sleep(1) continue From e8f5bc1c9677d4146c8c9dcb2f3321916a6992f6 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Fri, 1 Aug 2025 14:39:57 -0400 Subject: [PATCH 0634/1218] TWW: Fix Death Link (#5270) --- worlds/tww/Options.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/tww/Options.py b/worlds/tww/Options.py index d02c606f9fb9..b6f2c1511b9c 100644 --- a/worlds/tww/Options.py +++ b/worlds/tww/Options.py @@ -800,6 +800,7 @@ def get_slot_data_dict(self) -> dict[str, Any]: "swift_sail", "skip_rematch_bosses", "remove_music", + "death_link", ) def get_output_dict(self) -> dict[str, Any]: From 37a9d9486544873783a75db3db493dabb999502c Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 1 Aug 2025 15:06:35 -0500 Subject: [PATCH 0635/1218] Core: Purge Multiworld.option_name (#5050) --- BaseClasses.py | 9 --------- Main.py | 2 +- worlds/AutoWorld.py | 12 ------------ worlds/alttp/Dungeons.py | 9 +++++---- 4 files changed, 6 insertions(+), 26 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 4b2c66434f0a..77cad22deb92 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -228,17 +228,8 @@ def set_seed(self, seed: Optional[int] = None, secure: bool = False, name: Optio self.seed_name = name if name else str(self.seed) def set_options(self, args: Namespace) -> None: - # TODO - remove this section once all worlds use options dataclasses from worlds import AutoWorld - all_keys: Set[str] = {key for player in self.player_ids for key in - AutoWorld.AutoWorldRegister.world_types[self.game[player]].options_dataclass.type_hints} - for option_key in all_keys: - option = Utils.DeprecateDict(f"Getting options from multiworld is now deprecated. " - f"Please use `self.options.{option_key}` instead.", True) - option.update(getattr(args, option_key, {})) - setattr(self, option_key, option) - for player in self.player_ids: world_type = AutoWorld.AutoWorldRegister.world_types[self.game[player]] self.worlds[player] = world_type(self, player) diff --git a/Main.py b/Main.py index 67c861c0f49b..bc2787579fac 100644 --- a/Main.py +++ b/Main.py @@ -176,7 +176,7 @@ def main(args, seed=None, baked_server_options: dict[str, object] | None = None) multiworld.link_items() - if any(multiworld.item_links.values()): + if any(world.options.item_links for world in multiworld.worlds.values()): multiworld._all_state = None logger.info("Running Item Plando.") diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 568bdcf9a433..9233f3d21755 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -72,15 +72,6 @@ def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> Aut dct["required_client_version"] = max(dct["required_client_version"], base.__dict__["required_client_version"]) - # create missing options_dataclass from legacy option_definitions - # TODO - remove this once all worlds use options dataclasses - if "options_dataclass" not in dct and "option_definitions" in dct: - # TODO - switch to deprecate after a version - deprecate(f"{name} Assigned options through option_definitions which is now deprecated. " - "Please use options_dataclass instead.") - dct["options_dataclass"] = make_dataclass(f"{name}Options", dct["option_definitions"].items(), - bases=(PerGameCommonOptions,)) - # construct class new_class = super().__new__(mcs, name, bases, dct) new_class.__file__ = sys.modules[new_class.__module__].__file__ @@ -493,9 +484,6 @@ def create_group(cls, multiworld: "MultiWorld", new_player_id: int, players: Set Creates a group, which is an instance of World that is responsible for multiple others. An example case is ItemLinks creating these. """ - # TODO remove loop when worlds use options dataclass - for option_key, option in cls.options_dataclass.type_hints.items(): - getattr(multiworld, option_key)[new_player_id] = option.from_any(option.default) group = cls(multiworld, new_player_id) group.options = cls.options_dataclass(**{option_key: option.from_any(option.default) for option_key, option in cls.options_dataclass.type_hints.items()}) diff --git a/worlds/alttp/Dungeons.py b/worlds/alttp/Dungeons.py index 39e8d7072bb5..6b7da695934f 100644 --- a/worlds/alttp/Dungeons.py +++ b/worlds/alttp/Dungeons.py @@ -209,8 +209,8 @@ def fill_dungeons_restrictive(multiworld: MultiWorld): if localized: in_dungeon_items = [item for item in get_dungeon_item_pool(multiworld) if (item.player, item.name) in localized] if in_dungeon_items: - restricted_players = {player for player, restricted in multiworld.restrict_dungeon_item_on_boss.items() if - restricted} + restricted_players = {world.player for world in multiworld.get_game_worlds("A Link to the Past") if + world.options.restrict_dungeon_item_on_boss} locations: typing.List["ALttPLocation"] = [ location for location in get_unfilled_dungeon_locations(multiworld) # filter boss @@ -255,8 +255,9 @@ def fill_dungeons_restrictive(multiworld: MultiWorld): if all_state_base.has("Triforce", player): all_state_base.remove(multiworld.worlds[player].create_item("Triforce")) - for (player, key_drop_shuffle) in multiworld.key_drop_shuffle.items(): - if not key_drop_shuffle and player not in multiworld.groups: + for lttp_world in multiworld.get_game_worlds("A Link to the Past"): + if not lttp_world.options.key_drop_shuffle and lttp_world.player not in multiworld.groups: + player = lttp_world.player for key_loc in key_drop_data: key_data = key_drop_data[key_loc] all_state_base.remove(item_factory(key_data[3], multiworld.worlds[player])) From 9ad6959559f8926e15b2a5c7e869125c76878159 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 1 Aug 2025 22:30:30 +0200 Subject: [PATCH 0636/1218] LttP: move more stuff out of core (#5049) Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- BaseClasses.py | 6 ---- worlds/alttp/ItemPool.py | 11 +++---- worlds/alttp/Rom.py | 22 ++++++------- worlds/alttp/Rules.py | 24 +++++++------- worlds/alttp/Shops.py | 61 ++++++++++++++++++------------------ worlds/alttp/StateHelpers.py | 8 ++--- worlds/alttp/__init__.py | 9 +++++- 7 files changed, 70 insertions(+), 71 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 77cad22deb92..a9477a03129a 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -154,17 +154,11 @@ def __init__(self, players: int): self.algorithm = 'balanced' self.groups = {} self.regions = self.RegionManager(players) - self.shops = [] self.itempool = [] self.seed = None self.seed_name: str = "Unavailable" self.precollected_items = {player: [] for player in self.player_ids} self.required_locations = [] - self.light_world_light_cone = False - self.dark_world_light_cone = False - self.rupoor_cost = 10 - self.aga_randomness = True - self.save_and_quit_from_boss = True self.custom = False self.customitemarray = [] self.shuffle_ganon = True diff --git a/worlds/alttp/ItemPool.py b/worlds/alttp/ItemPool.py index 9f1a58e5466d..53059c64bc00 100644 --- a/worlds/alttp/ItemPool.py +++ b/worlds/alttp/ItemPool.py @@ -223,7 +223,7 @@ def generate_itempool(world): - player = world.player + player: int = world.player multiworld = world.multiworld if world.options.item_pool.current_key not in difficulties: @@ -280,7 +280,6 @@ def generate_itempool(world): if multiworld.custom: pool, placed_items, precollected_items, clock_mode, treasure_hunt_required = ( make_custom_item_pool(multiworld, player)) - multiworld.rupoor_cost = min(multiworld.customitemarray[67], 9999) else: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_required, treasure_hunt_total, additional_triforce_pieces) = get_pool_core(multiworld, player) @@ -386,8 +385,8 @@ def generate_itempool(world): if world.options.retro_bow: shop_items = 0 - shop_locations = [location for shop_locations in (shop.region.locations for shop in multiworld.shops if - shop.type == ShopType.Shop and shop.region.player == player) for location in shop_locations if + shop_locations = [location for shop_locations in (shop.region.locations for shop in world.shops if + shop.type == ShopType.Shop) for location in shop_locations if location.shop_slot is not None] for location in shop_locations: if location.shop.inventory[location.shop_slot]["item"] == "Single Arrow": @@ -546,7 +545,7 @@ def set_up_take_anys(multiworld, world, player): connect_entrance(multiworld, entrance.name, old_man_take_any.name, player) entrance.target = 0x58 old_man_take_any.shop = TakeAny(old_man_take_any, 0x0112, 0xE2, True, True, total_shop_slots) - multiworld.shops.append(old_man_take_any.shop) + world.shops.append(old_man_take_any.shop) sword_indices = [ index for index, item in enumerate(multiworld.itempool) if item.player == player and item.type == 'Sword' @@ -574,7 +573,7 @@ def set_up_take_anys(multiworld, world, player): connect_entrance(multiworld, entrance.name, take_any.name, player) entrance.target = target take_any.shop = TakeAny(take_any, room_id, 0xE3, True, True, total_shop_slots + num + 1) - multiworld.shops.append(take_any.shop) + world.shops.append(take_any.shop) take_any.shop.add_inventory(0, 'Blue Potion', 0, 0) take_any.shop.add_inventory(1, 'Boss Heart Container', 0, 0) location = ALttPLocation(player, take_any.name, shop_table_by_location[take_any.name], parent=take_any) diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index 399d64d433fd..88b9485aafd9 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -1002,14 +1002,19 @@ def credits_digit(num): # set light cones rom.write_byte(0x180038, 0x01 if local_world.options.mode == "standard" else 0x00) - rom.write_byte(0x180039, 0x01 if world.light_world_light_cone else 0x00) - rom.write_byte(0x18003A, 0x01 if world.dark_world_light_cone else 0x00) + # light world light cone + rom.write_byte(0x180039, local_world.light_world_light_cone) + # dark world light cone + rom.write_byte(0x18003A, local_world.dark_world_light_cone) GREEN_TWENTY_RUPEES = 0x47 GREEN_CLOCK = item_table["Green Clock"].item_code rom.write_byte(0x18004F, 0x01) # Byrna Invulnerability: on + # Rupoor negative value + rom.write_int16(0x180036, local_world.rupoor_cost) + # handle item_functionality if local_world.options.item_functionality == 'hard': rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon @@ -1027,8 +1032,6 @@ def credits_digit(num): # Disable catching fairies rom.write_byte(0x34FD6, 0x80) overflow_replacement = GREEN_TWENTY_RUPEES - # Rupoor negative value - rom.write_int16(0x180036, world.rupoor_cost) # Set stun items rom.write_byte(0x180180, 0x02) # Hookshot only elif local_world.options.item_functionality == 'expert': @@ -1047,8 +1050,6 @@ def credits_digit(num): # Disable catching fairies rom.write_byte(0x34FD6, 0x80) overflow_replacement = GREEN_TWENTY_RUPEES - # Rupoor negative value - rom.write_int16(0x180036, world.rupoor_cost) # Set stun items rom.write_byte(0x180180, 0x00) # Nothing else: @@ -1066,8 +1067,6 @@ def credits_digit(num): rom.write_byte(0x18004F, 0x01) # Enable catching fairies rom.write_byte(0x34FD6, 0xF0) - # Rupoor negative value - rom.write_int16(0x180036, world.rupoor_cost) # Set stun items rom.write_byte(0x180180, 0x03) # All standard items # Set overflow items for progressive equipment @@ -1313,7 +1312,7 @@ def chunk(l, n): rom.write_byte(0x18008C, 0x01 if local_world.options.crystals_needed_for_gt == 0 else 0x00) # GT pre-opened if crystal requirement is 0 rom.write_byte(0xF5D73, 0xF0) # bees are catchable rom.write_byte(0xF5F10, 0xF0) # bees are catchable - rom.write_byte(0x180086, 0x00 if world.aga_randomness else 0x01) # set blue ball and ganon warp randomness + rom.write_byte(0x180086, 0x00) # set blue ball and ganon warp randomness rom.write_byte(0x1800A0, 0x01) # return to light world on s+q without mirror rom.write_byte(0x1800A1, 0x01) # enable overworld screen transition draining for water level inside swamp rom.write_byte(0x180174, 0x01 if local_world.fix_fake_world else 0x00) @@ -1618,7 +1617,7 @@ def get_reveal_bytes(itemName): rom.write_byte(0x1800A3, 0x01) # enable correct world setting behaviour after agahnim kills rom.write_byte(0x1800A4, 0x01 if local_world.options.glitches_required != 'no_logic' else 0x00) # enable POD EG fix rom.write_byte(0x186383, 0x01 if local_world.options.glitches_required == 'no_logic' else 0x00) # disable glitching to Triforce from Ganons Room - rom.write_byte(0x180042, 0x01 if world.save_and_quit_from_boss else 0x00) # Allow Save and Quit after boss kill + rom.write_byte(0x180042, 0x01 if local_world.save_and_quit_from_boss else 0x00) # Allow Save and Quit after boss kill # remove shield from uncle rom.write_bytes(0x6D253, [0x00, 0x00, 0xf6, 0xff, 0x00, 0x0E]) @@ -1739,8 +1738,7 @@ def get_price_data(price: int, price_type: int) -> List[int]: def write_custom_shops(rom, world, player): - shops = sorted([shop for shop in world.shops if shop.custom and shop.region.player == player], - key=lambda shop: shop.sram_offset) + shops = sorted([shop for shop in world.worlds[player].shops if shop.custom], key=lambda shop: shop.sram_offset) shop_data = bytearray() items_data = bytearray() diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index b79170dac2cf..a5b14e0c2da6 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -147,7 +147,6 @@ def set_defeat_dungeon_boss_rule(location): add_rule(location, lambda state: location.parent_region.dungeon.boss.can_defeat(state)) - def set_always_allow(spot, rule): spot.always_allow = rule @@ -980,18 +979,19 @@ def check_is_dark_world(region): return False -def add_conditional_lamps(world, player): +def add_conditional_lamps(multiworld, player): # Light cones in standard depend on which world we actually are in, not which one the location would normally be # We add Lamp requirements only to those locations which lie in the dark world (or everything if open + local_world = multiworld.worlds[player] def add_conditional_lamp(spot, region, spottype='Location', accessible_torch=False): - if (not world.dark_world_light_cone and check_is_dark_world(world.get_region(region, player))) or ( - not world.light_world_light_cone and not check_is_dark_world(world.get_region(region, player))): + if (not local_world.dark_world_light_cone and check_is_dark_world(local_world.get_region(region))) or ( + not local_world.light_world_light_cone and not check_is_dark_world(local_world.get_region(region))): if spottype == 'Location': - spot = world.get_location(spot, player) + spot = local_world.get_location(spot) else: - spot = world.get_entrance(spot, player) - add_lamp_requirement(world, spot, player, accessible_torch) + spot = local_world.get_entrance(spot) + add_lamp_requirement(multiworld, spot, player, accessible_torch) add_conditional_lamp('Misery Mire (Vitreous)', 'Misery Mire (Entrance)', 'Entrance') add_conditional_lamp('Turtle Rock (Dark Room) (North)', 'Turtle Rock (Entrance)', 'Entrance') @@ -1002,7 +1002,7 @@ def add_conditional_lamp(spot, region, spottype='Location', accessible_torch=Fal 'Location', True) add_conditional_lamp('Palace of Darkness - Dark Basement - Right', 'Palace of Darkness (Entrance)', 'Location', True) - if world.worlds[player].options.mode != 'inverted': + if multiworld.worlds[player].options.mode != 'inverted': add_conditional_lamp('Agahnim 1', 'Agahnims Tower', 'Entrance') add_conditional_lamp('Castle Tower - Dark Maze', 'Agahnims Tower') add_conditional_lamp('Castle Tower - Dark Archer Key Drop', 'Agahnims Tower') @@ -1024,10 +1024,10 @@ def add_conditional_lamp(spot, region, spottype='Location', accessible_torch=Fal add_conditional_lamp('Eastern Palace - Boss', 'Eastern Palace', 'Location', True) add_conditional_lamp('Eastern Palace - Prize', 'Eastern Palace', 'Location', True) - if not world.worlds[player].options.mode == "standard": - add_lamp_requirement(world, world.get_location('Sewers - Dark Cross', player), player) - add_lamp_requirement(world, world.get_entrance('Sewers Back Door', player), player) - add_lamp_requirement(world, world.get_entrance('Throne Room', player), player) + if not multiworld.worlds[player].options.mode == "standard": + add_lamp_requirement(multiworld, local_world.get_location("Sewers - Dark Cross"), player) + add_lamp_requirement(multiworld, local_world.get_entrance("Sewers Back Door"), player) + add_lamp_requirement(multiworld, local_world.get_entrance("Throne Room"), player) def open_rules(world, player): diff --git a/worlds/alttp/Shops.py b/worlds/alttp/Shops.py index bb3945f5b05a..89e43a1a041a 100644 --- a/worlds/alttp/Shops.py +++ b/worlds/alttp/Shops.py @@ -14,8 +14,6 @@ from .StateHelpers import has_hearts, can_use_bombs, can_hold_arrows -logger = logging.getLogger("Shops") - @unique class ShopType(IntEnum): @@ -162,7 +160,10 @@ class UpgradeShop(Shop): def push_shop_inventories(multiworld): - shop_slots = [location for shop_locations in (shop.region.locations for shop in multiworld.shops if shop.type + all_shops = [] + for world in multiworld.get_game_worlds(ALttPLocation.game): + all_shops.extend(world.shops) + shop_slots = [location for shop_locations in (shop.region.locations for shop in all_shops if shop.type != ShopType.TakeAny) for location in shop_locations if location.shop_slot is not None] for location in shop_slots: @@ -178,7 +179,7 @@ def push_shop_inventories(multiworld): get_price(multiworld, location.shop.inventory[location.shop_slot], location.player, location.shop_price_type)[1]) - for world in multiworld.get_game_worlds("A Link to the Past"): + for world in multiworld.get_game_worlds(ALttPLocation.game): world.pushed_shop_inventories.set() @@ -225,7 +226,7 @@ def create_shops(multiworld, player: int): if locked is None: shop.locked = True region.shop = shop - multiworld.shops.append(shop) + multiworld.worlds[player].shops.append(shop) for index, item in enumerate(inventory): shop.add_inventory(index, *item) if not locked and (num_slots or type == ShopType.UpgradeShop): @@ -309,50 +310,50 @@ def set_up_shops(multiworld, player: int): from .Options import small_key_shuffle # TODO: move hard+ mode changes for shields here, utilizing the new shops - if multiworld.worlds[player].options.retro_bow: + local_world = multiworld.worlds[player] + + if local_world.options.retro_bow: rss = multiworld.get_region('Red Shield Shop', player).shop + # Can't just replace the single arrow with 10 arrows as retro doesn't need them. replacement_items = [['Red Potion', 150], ['Green Potion', 75], ['Blue Potion', 200], ['Bombs (10)', 50], - ['Blue Shield', 50], ['Small Heart', - 10]] # Can't just replace the single arrow with 10 arrows as retro doesn't need them. - if multiworld.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: + ['Blue Shield', 50], ['Small Heart', 10]] + if local_world.options.small_key_shuffle == small_key_shuffle.option_universal: replacement_items.append(['Small Key (Universal)', 100]) replacement_item = multiworld.random.choice(replacement_items) rss.add_inventory(2, 'Single Arrow', 80, 1, replacement_item[0], replacement_item[1]) rss.locked = True - if multiworld.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal or multiworld.worlds[player].options.retro_bow: - for shop in multiworld.random.sample([s for s in multiworld.shops if - s.custom and not s.locked and s.type == ShopType.Shop - and s.region.player == player], 5): + if local_world.options.small_key_shuffle == small_key_shuffle.option_universal or local_world.options.retro_bow: + for shop in multiworld.random.sample([s for s in local_world.shops if + s.custom and not s.locked and s.type == ShopType.Shop], 5): shop.locked = True slots = [0, 1, 2] multiworld.random.shuffle(slots) slots = iter(slots) - if multiworld.worlds[player].options.small_key_shuffle == small_key_shuffle.option_universal: + if local_world.options.small_key_shuffle == small_key_shuffle.option_universal: shop.add_inventory(next(slots), 'Small Key (Universal)', 100) - if multiworld.worlds[player].options.retro_bow: + if local_world.options.retro_bow: shop.push_inventory(next(slots), 'Single Arrow', 80) - if multiworld.worlds[player].options.shuffle_capacity_upgrades: - for shop in multiworld.shops: - if shop.type == ShopType.UpgradeShop and shop.region.player == player and \ + if local_world.options.shuffle_capacity_upgrades: + for shop in local_world.shops: + if shop.type == ShopType.UpgradeShop and \ shop.region.name == "Capacity Upgrade": shop.clear_inventory() - if (multiworld.worlds[player].options.shuffle_shop_inventories or multiworld.worlds[player].options.randomize_shop_prices - or multiworld.worlds[player].options.randomize_cost_types): + if (local_world.options.shuffle_shop_inventories or local_world.options.randomize_shop_prices + or local_world.options.randomize_cost_types): shops = [] total_inventory = [] - for shop in multiworld.shops: - if shop.region.player == player: - if shop.type == ShopType.Shop and not shop.locked: - shops.append(shop) - total_inventory.extend(shop.inventory) + for shop in local_world.shops: + if shop.type == ShopType.Shop and not shop.locked: + shops.append(shop) + total_inventory.extend(shop.inventory) for item in total_inventory: item["price_type"], item["price"] = get_price(multiworld, item, player) - if multiworld.worlds[player].options.shuffle_shop_inventories: + if local_world.options.shuffle_shop_inventories: multiworld.random.shuffle(total_inventory) i = 0 @@ -407,7 +408,7 @@ def set_up_shops(multiworld, player: int): } -def get_price_modifier(item): +def get_price_modifier(item) -> float: if item.game == "A Link to the Past": if any(x in item.name for x in ['Compass', 'Map', 'Single Bomb', 'Single Arrow', 'Piece of Heart']): @@ -418,9 +419,9 @@ def get_price_modifier(item): elif any(x in item.name for x in ['Small Key', 'Heart']): return 0.5 else: - return 1 + return 1.0 if item.advancement: - return 1 + return 1.0 elif item.useful: return 0.5 else: @@ -471,7 +472,7 @@ def get_price(multiworld, item, player: int, price_type=None): def shop_price_rules(state: CollectionState, player: int, location: ALttPLocation): if location.shop_price_type == ShopPriceType.Hearts: - return has_hearts(state, player, (location.shop_price / 8) + 1) + return has_hearts(state, player, (location.shop_price // 8) + 1) elif location.shop_price_type == ShopPriceType.Bombs: return can_use_bombs(state, player, location.shop_price) elif location.shop_price_type == ShopPriceType.Arrows: diff --git a/worlds/alttp/StateHelpers.py b/worlds/alttp/StateHelpers.py index 6ac3c4b8f8a1..98409c8a8d3c 100644 --- a/worlds/alttp/StateHelpers.py +++ b/worlds/alttp/StateHelpers.py @@ -14,13 +14,13 @@ def can_bomb_clip(state: CollectionState, region: LTTPRegion, player: int) -> bo def can_buy_unlimited(state: CollectionState, item: str, player: int) -> bool: - return any(shop.region.player == player and shop.has_unlimited(item) and shop.region.can_reach(state) for - shop in state.multiworld.shops) + return any(shop.has_unlimited(item) and shop.region.can_reach(state) for + shop in state.multiworld.worlds[player].shops) def can_buy(state: CollectionState, item: str, player: int) -> bool: - return any(shop.region.player == player and shop.has(item) and shop.region.can_reach(state) for - shop in state.multiworld.shops) + return any(shop.has(item) and shop.region.can_reach(state) for + shop in state.multiworld.worlds[player].shops) def can_shoot_arrows(state: CollectionState, player: int, count: int = 0) -> bool: diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index 773fd7050cf2..4ee5b9d26640 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -236,6 +236,8 @@ class ALTTPWorld(World): required_client_version = (0, 4, 1) web = ALTTPWeb() + shops: list[Shop] + pedestal_credit_texts: typing.Dict[int, str] = \ {data.item_code: data.pedestal_credit for data in item_table.values() if data.pedestal_credit} sickkid_credit_texts: typing.Dict[int, str] = \ @@ -282,6 +284,10 @@ def enemizer_path(self) -> str: clock_mode: str = "" treasure_hunt_required: int = 0 treasure_hunt_total: int = 0 + light_world_light_cone: bool = False + dark_world_light_cone: bool = False + save_and_quit_from_boss: bool = True + rupoor_cost: int = 10 def __init__(self, *args, **kwargs): self.dungeon_local_item_names = set() @@ -298,6 +304,7 @@ def __init__(self, *args, **kwargs): self.fix_trock_exit = None self.required_medallions = ["Ether", "Quake"] self.escape_assist = [] + self.shops = [] super(ALTTPWorld, self).__init__(*args, **kwargs) @classmethod @@ -800,7 +807,7 @@ def build_shop_info(shop: Shop) -> typing.Dict[str, str]: return shop_data - if shop_info := [build_shop_info(shop) for shop in self.multiworld.shops if shop.custom]: + if shop_info := [build_shop_info(shop) for shop in self.shops if shop.custom]: spoiler_handle.write('\n\nShops:\n\n') for shop_data in shop_info: spoiler_handle.write("{} [{}]\n {}\n".format(shop_data['location'], shop_data['type'], "\n ".join( From 9edd55961f8918face11d0a0e22ce9b24467147c Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 2 Aug 2025 01:26:50 +0200 Subject: [PATCH 0637/1218] LttP: remove sprite download from setup flow & make sprite repo dynamic (#4830) --- LttPAdjuster.py | 51 +++++++++++++--------- WebHostLib/lttpsprites.py | 2 +- data/sprites/{alttpr => remote}/.gitignore | 0 inno_setup.iss | 5 --- setup.py | 8 ++-- worlds/alttp/Rom.py | 3 +- 6 files changed, 39 insertions(+), 30 deletions(-) rename data/sprites/{alttpr => remote}/.gitignore (100%) diff --git a/LttPAdjuster.py b/LttPAdjuster.py index d44f413499f1..4816210ff5be 100644 --- a/LttPAdjuster.py +++ b/LttPAdjuster.py @@ -32,6 +32,7 @@ WINDOW_MIN_HEIGHT = 525 WINDOW_MIN_WIDTH = 425 + class AdjusterWorld(object): class AdjusterSubWorld(object): def __init__(self, random): @@ -48,6 +49,7 @@ class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter): def _get_help_string(self, action): return textwrap.dedent(action.help) + # See argparse.BooleanOptionalAction class BooleanOptionalActionWithDisable(argparse.Action): def __init__(self, @@ -363,10 +365,10 @@ def run_sprite_update(): logging.info("Done updating sprites") -def update_sprites(task, on_finish=None): +def update_sprites(task, on_finish=None, repository_url: str = "https://alttpr.com/sprites"): resultmessage = "" successful = True - sprite_dir = user_path("data", "sprites", "alttpr") + sprite_dir = user_path("data", "sprites", "alttp", "remote") os.makedirs(sprite_dir, exist_ok=True) ctx = get_cert_none_ssl_context() @@ -376,11 +378,11 @@ def finished(): on_finish(successful, resultmessage) try: - task.update_status("Downloading alttpr sprites list") - with urlopen('https://alttpr.com/sprites', context=ctx) as response: + task.update_status("Downloading remote sprites list") + with urlopen(repository_url, context=ctx) as response: sprites_arr = json.loads(response.read().decode("utf-8")) except Exception as e: - resultmessage = "Error getting list of alttpr sprites. Sprites not updated.\n\n%s: %s" % (type(e).__name__, e) + resultmessage = "Error getting list of remote sprites. Sprites not updated.\n\n%s: %s" % (type(e).__name__, e) successful = False task.queue_event(finished) return @@ -388,13 +390,13 @@ def finished(): try: task.update_status("Determining needed sprites") current_sprites = [os.path.basename(file) for file in glob(sprite_dir + '/*')] - alttpr_sprites = [(sprite['file'], os.path.basename(urlparse(sprite['file']).path)) + remote_sprites = [(sprite['file'], os.path.basename(urlparse(sprite['file']).path)) for sprite in sprites_arr if sprite["author"] != "Nintendo"] - needed_sprites = [(sprite_url, filename) for (sprite_url, filename) in alttpr_sprites if + needed_sprites = [(sprite_url, filename) for (sprite_url, filename) in remote_sprites if filename not in current_sprites] - alttpr_filenames = [filename for (_, filename) in alttpr_sprites] - obsolete_sprites = [sprite for sprite in current_sprites if sprite not in alttpr_filenames] + remote_filenames = [filename for (_, filename) in remote_sprites] + obsolete_sprites = [sprite for sprite in current_sprites if sprite not in remote_filenames] except Exception as e: resultmessage = "Error Determining which sprites to update. Sprites not updated.\n\n%s: %s" % ( type(e).__name__, e) @@ -446,7 +448,7 @@ def rem(sprite): successful = False if successful: - resultmessage = "alttpr sprites updated successfully" + resultmessage = "Remote sprites updated successfully" task.queue_event(finished) @@ -867,7 +869,7 @@ def __init__(self, parent, callback, adjuster=False, randomOnEvent=True, spriteP def open_custom_sprite_dir(_evt): open_file(self.custom_sprite_dir) - alttpr_frametitle = Label(self.window, text='ALTTPR Sprites') + remote_frametitle = Label(self.window, text='Remote Sprites') custom_frametitle = Frame(self.window) title_text = Label(custom_frametitle, text="Custom Sprites") @@ -876,8 +878,8 @@ def open_custom_sprite_dir(_evt): title_link.pack(side=LEFT) title_link.bind("", open_custom_sprite_dir) - self.icon_section(alttpr_frametitle, self.alttpr_sprite_dir, - 'ALTTPR sprites not found. Click "Update alttpr sprites" to download them.') + self.icon_section(remote_frametitle, self.remote_sprite_dir, + 'Remote sprites not found. Click "Update remote sprites" to download them.') self.icon_section(custom_frametitle, self.custom_sprite_dir, 'Put sprites in the custom sprites folder (see open link above) to have them appear here.') if not randomOnEvent: @@ -890,11 +892,18 @@ def open_custom_sprite_dir(_evt): button = Button(frame, text="Browse for file...", command=self.browse_for_sprite) button.pack(side=RIGHT, padx=(5, 0)) - button = Button(frame, text="Update alttpr sprites", command=self.update_alttpr_sprites) + button = Button(frame, text="Update remote sprites", command=self.update_remote_sprites) button.pack(side=RIGHT, padx=(5, 0)) + + repository_label = Label(frame, text='Sprite Repository:') + self.repository_url = StringVar(frame, "https://alttpr.com/sprites") + repository_entry = Entry(frame, textvariable=self.repository_url) + repository_entry.pack(side=RIGHT, expand=True, fill=BOTH, pady=1) + repository_label.pack(side=RIGHT, expand=False, padx=(0, 5)) + button = Button(frame, text="Do not adjust sprite",command=self.use_default_sprite) - button.pack(side=LEFT,padx=(0,5)) + button.pack(side=LEFT, padx=(0, 5)) button = Button(frame, text="Default Link sprite", command=self.use_default_link_sprite) button.pack(side=LEFT, padx=(0, 5)) @@ -1054,7 +1063,7 @@ def grid_fill_sprites(self, frame): for i, button in enumerate(frame.buttons): button.grid(row=i // self.spritesPerRow, column=i % self.spritesPerRow) - def update_alttpr_sprites(self): + def update_remote_sprites(self): # need to wrap in try catch. We don't want errors getting the json or downloading the files to break us. self.window.destroy() self.parent.update() @@ -1067,7 +1076,8 @@ def on_finish(successful, resultmessage): messagebox.showerror("Sprite Updater", resultmessage) SpriteSelector(self.parent, self.callback, self.adjuster) - BackgroundTaskProgress(self.parent, update_sprites, "Updating Sprites", on_finish) + BackgroundTaskProgress(self.parent, update_sprites, "Updating Sprites", + on_finish, self.repository_url.get()) def browse_for_sprite(self): sprite = filedialog.askopenfilename( @@ -1157,12 +1167,13 @@ def deploy_icons(self): os.makedirs(self.custom_sprite_dir) @property - def alttpr_sprite_dir(self): - return user_path("data", "sprites", "alttpr") + def remote_sprite_dir(self): + return user_path("data", "sprites", "alttp", "remote") @property def custom_sprite_dir(self): - return user_path("data", "sprites", "custom") + return user_path("data", "sprites", "alttp", "custom") + def get_image_for_sprite(sprite, gif_only: bool = False): if not sprite.valid: diff --git a/WebHostLib/lttpsprites.py b/WebHostLib/lttpsprites.py index 1b8ee4cf487c..9d780b13e12a 100644 --- a/WebHostLib/lttpsprites.py +++ b/WebHostLib/lttpsprites.py @@ -14,7 +14,7 @@ def update_sprites_lttp(): from LttPAdjuster import update_sprites # Target directories - input_dir = user_path("data", "sprites", "alttpr") + input_dir = user_path("data", "sprites", "alttp", "remote") output_dir = local_path("WebHostLib", "static", "generated") # TODO: move to user_path os.makedirs(os.path.join(output_dir, "sprites"), exist_ok=True) diff --git a/data/sprites/alttpr/.gitignore b/data/sprites/remote/.gitignore similarity index 100% rename from data/sprites/alttpr/.gitignore rename to data/sprites/remote/.gitignore diff --git a/inno_setup.iss b/inno_setup.iss index 6f41b20496a1..8611c849fb4d 100644 --- a/inno_setup.iss +++ b/inno_setup.iss @@ -53,10 +53,6 @@ Name: "full"; Description: "Full installation" Name: "minimal"; Description: "Minimal installation" Name: "custom"; Description: "Custom installation"; Flags: iscustom -[Components] -Name: "core"; Description: "Archipelago"; Types: full minimal custom; Flags: fixed -Name: "lttp_sprites"; Description: "Download ""A Link to the Past"" player sprites"; Types: full; - [Dirs] NAME: "{app}"; Flags: setntfscompression; Permissions: everyone-modify users-modify authusers-modify; @@ -76,7 +72,6 @@ Name: "{commondesktop}\{#MyAppName} Launcher"; Filename: "{app}\ArchipelagoLaunc [Run] Filename: "{tmp}\vc_redist.x64.exe"; Parameters: "/passive /norestart"; Check: IsVCRedist64BitNeeded; StatusMsg: "Installing VC++ redistributable..." -Filename: "{app}\ArchipelagoLttPAdjuster"; Parameters: "--update_sprites"; StatusMsg: "Updating Sprite Library..."; Components: lttp_sprites Filename: "{app}\ArchipelagoLauncher"; Parameters: "--update_settings"; StatusMsg: "Updating host.yaml..."; Flags: runasoriginaluser runhidden Filename: "{app}\ArchipelagoLauncher"; Description: "{cm:LaunchProgram,{#StringChange('Launcher', '&', '&&')}}"; Flags: nowait postinstall skipifsilent diff --git a/setup.py b/setup.py index 593a45f83085..1808b22c62d0 100644 --- a/setup.py +++ b/setup.py @@ -199,9 +199,10 @@ def resolve_icon(icon_name: str): def remove_sprites_from_folder(folder: Path) -> None: - for file in os.listdir(folder): - if file != ".gitignore": - os.remove(folder / file) + if os.path.isdir(folder): + for file in os.listdir(folder): + if file != ".gitignore": + os.remove(folder / file) def _threaded_hash(filepath: str | Path) -> str: @@ -410,6 +411,7 @@ def run(self) -> None: os.system(signtool + os.path.join(self.buildfolder, "lib", "worlds", "oot", "data", *exe_path)) remove_sprites_from_folder(self.buildfolder / "data" / "sprites" / "alttpr") + remove_sprites_from_folder(self.buildfolder / "data" / "sprites" / "alttp" / "remote") self.create_manifest() diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index 88b9485aafd9..6a5792d21a3f 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -515,7 +515,8 @@ def load_sprite_from_file(file): logging.debug(f"Spritefile {file} could not be loaded as a valid sprite.") with concurrent.futures.ThreadPoolExecutor() as pool: - sprite_paths = [user_path('data', 'sprites', 'alttpr'), user_path('data', 'sprites', 'custom')] + sprite_paths = [user_path("data", "sprites", "alttp", "remote"), + user_path("data", "sprites", "alttp", "custom")] for dir in [dir for dir in sprite_paths if os.path.isdir(dir)]: for file in os.listdir(dir): pool.submit(load_sprite_from_file, os.path.join(dir, file)) From 277f21db7af0ca171f9faf4980ddc6db64a7e100 Mon Sep 17 00:00:00 2001 From: t3hf1gm3nt <59876300+t3hf1gm3nt@users.noreply.github.com> Date: Sat, 2 Aug 2025 13:14:24 -0400 Subject: [PATCH 0638/1218] The Legend of Zelda: Stepping Down as Maintainer (#5277) --- docs/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 85b31683aa3a..889d51415c25 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -200,7 +200,7 @@ /worlds/timespinner/ @Jarno458 # The Legend of Zelda (1) -/worlds/tloz/ @Rosalie-A @t3hf1gm3nt +/worlds/tloz/ @Rosalie-A # TUNIC /worlds/tunic/ @silent-destroyer @ScipioWright From 72ae076ce7800d93caefbd905759bfa6c54f97d7 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 2 Aug 2025 21:12:58 +0200 Subject: [PATCH 0639/1218] WebHost: server render remaining markdown using mistune (#5276) --------- Co-authored-by: Aaron Wagener Co-authored-by: qwint Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- BaseClasses.py | 2 +- WebHost.py | 48 ++----- WebHostLib/misc.py | 149 ++++++++++++++------ WebHostLib/requirements.txt | 3 +- WebHostLib/static/assets/gameInfo.js | 45 ------ WebHostLib/static/assets/tutorial.js | 52 ------- WebHostLib/static/assets/tutorialLanding.js | 81 ----------- WebHostLib/templates/gameInfo.html | 17 --- WebHostLib/templates/markdown_document.html | 3 +- WebHostLib/templates/tutorial.html | 17 --- WebHostLib/templates/tutorialLanding.html | 32 ++++- test/webhost/test_docs.py | 32 ++--- test/webhost/test_file_generation.py | 5 - worlds/ahit/__init__.py | 2 +- worlds/osrs/__init__.py | 2 +- worlds/yugioh06/__init__.py | 2 +- 16 files changed, 157 insertions(+), 335 deletions(-) delete mode 100644 WebHostLib/static/assets/gameInfo.js delete mode 100644 WebHostLib/static/assets/tutorial.js delete mode 100644 WebHostLib/static/assets/tutorialLanding.js delete mode 100644 WebHostLib/templates/gameInfo.html delete mode 100644 WebHostLib/templates/tutorial.html diff --git a/BaseClasses.py b/BaseClasses.py index a9477a03129a..d00c6007e172 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1926,7 +1926,7 @@ class Tutorial(NamedTuple): description: str language: str file_name: str - link: str + link: str # unused authors: List[str] diff --git a/WebHost.py b/WebHost.py index 768eeb512289..946eaa116f01 100644 --- a/WebHost.py +++ b/WebHost.py @@ -54,16 +54,15 @@ def get_app() -> "Flask": return app -def create_ordered_tutorials_file() -> typing.List[typing.Dict[str, typing.Any]]: - import json +def copy_tutorials_files_to_static() -> None: import shutil import zipfile + from werkzeug.utils import secure_filename zfile: zipfile.ZipInfo from worlds.AutoWorld import AutoWorldRegister worlds = {} - data = [] for game, world in AutoWorldRegister.world_types.items(): if hasattr(world.web, 'tutorials') and (not world.hidden or game == 'Archipelago'): worlds[game] = world @@ -72,7 +71,7 @@ def create_ordered_tutorials_file() -> typing.List[typing.Dict[str, typing.Any]] shutil.rmtree(base_target_path, ignore_errors=True) for game, world in worlds.items(): # copy files from world's docs folder to the generated folder - target_path = os.path.join(base_target_path, get_file_safe_name(game)) + target_path = os.path.join(base_target_path, secure_filename(game)) os.makedirs(target_path, exist_ok=True) if world.zip_path: @@ -85,45 +84,14 @@ def create_ordered_tutorials_file() -> typing.List[typing.Dict[str, typing.Any]] for zfile in zf.infolist(): if not zfile.is_dir() and "/docs/" in zfile.filename: zfile.filename = os.path.basename(zfile.filename) - zf.extract(zfile, target_path) + with open(os.path.join(target_path, secure_filename(zfile.filename)), "wb") as f: + f.write(zf.read(zfile)) else: source_path = Utils.local_path(os.path.dirname(world.__file__), "docs") files = os.listdir(source_path) for file in files: - shutil.copyfile(Utils.local_path(source_path, file), Utils.local_path(target_path, file)) - - # build a json tutorial dict per game - game_data = {'gameTitle': game, 'tutorials': []} - for tutorial in world.web.tutorials: - # build dict for the json file - current_tutorial = { - 'name': tutorial.tutorial_name, - 'description': tutorial.description, - 'files': [{ - 'language': tutorial.language, - 'filename': game + '/' + tutorial.file_name, - 'link': f'{game}/{tutorial.link}', - 'authors': tutorial.authors - }] - } - - # check if the name of the current guide exists already - for guide in game_data['tutorials']: - if guide and tutorial.tutorial_name == guide['name']: - guide['files'].append(current_tutorial['files'][0]) - break - else: - game_data['tutorials'].append(current_tutorial) - - data.append(game_data) - with open(Utils.local_path("WebHostLib", "static", "generated", "tutorials.json"), 'w', encoding='utf-8-sig') as json_target: - generic_data = {} - for games in data: - if 'Archipelago' in games['gameTitle']: - generic_data = data.pop(data.index(games)) - sorted_data = [generic_data] + Utils.title_sorted(data, key=lambda entry: entry["gameTitle"]) - json.dump(sorted_data, json_target, indent=2, ensure_ascii=False) - return sorted_data + shutil.copyfile(Utils.local_path(source_path, file), + Utils.local_path(target_path, secure_filename(file))) if __name__ == "__main__": @@ -142,7 +110,7 @@ def create_ordered_tutorials_file() -> typing.List[typing.Dict[str, typing.Any]] logging.warning("Could not update LttP sprites.") app = get_app() create_options_files() - create_ordered_tutorials_file() + copy_tutorials_files_to_static() if app.config["SELFLAUNCH"]: autohost(app.config) if app.config["SELFGEN"]: diff --git a/WebHostLib/misc.py b/WebHostLib/misc.py index 98731b65bdd6..d7ac950817b1 100644 --- a/WebHostLib/misc.py +++ b/WebHostLib/misc.py @@ -7,17 +7,69 @@ from pony.orm import count, commit, db_session from werkzeug.utils import secure_filename -from worlds.AutoWorld import AutoWorldRegister +from worlds.AutoWorld import AutoWorldRegister, World from . import app, cache from .models import Seed, Room, Command, UUID, uuid4 +from Utils import title_sorted -def get_world_theme(game_name: str): +def get_world_theme(game_name: str) -> str: if game_name in AutoWorldRegister.world_types: return AutoWorldRegister.world_types[game_name].web.theme return 'grass' +def get_visible_worlds() -> dict[str, type(World)]: + worlds = {} + for game, world in AutoWorldRegister.world_types.items(): + if not world.hidden: + worlds[game] = world + return worlds + + +def render_markdown(path: str) -> str: + import mistune + from collections import Counter + + markdown = mistune.create_markdown( + escape=False, + plugins=[ + "strikethrough", + "footnotes", + "table", + "speedup", + ], + ) + + heading_id_count: Counter[str] = Counter() + + def heading_id(text: str) -> str: + nonlocal heading_id_count + import re # there is no good way to do this without regex + + s = re.sub(r"[^\w\- ]", "", text.lower()).replace(" ", "-").strip("-") + n = heading_id_count[s] + heading_id_count[s] += 1 + if n > 0: + s += f"-{n}" + return s + + def id_hook(_: mistune.Markdown, state: mistune.BlockState) -> None: + for tok in state.tokens: + if tok["type"] == "heading" and tok["attrs"]["level"] < 4: + text = tok["text"] + assert isinstance(text, str) + unique_id = heading_id(text) + tok["attrs"]["id"] = unique_id + tok["text"] = f"{text}" # make header link to itself + + markdown.before_render_hooks.append(id_hook) + + with open(path, encoding="utf-8-sig") as f: + document = f.read() + return markdown(document) + + @app.errorhandler(404) @app.errorhandler(jinja2.exceptions.TemplateNotFound) def page_not_found(err): @@ -31,83 +83,88 @@ def start_playing(): return render_template(f"startPlaying.html") -# Game Info Pages @app.route('/games//info/') @cache.cached() def game_info(game, lang): - try: - world = AutoWorldRegister.world_types[game] - if lang not in world.web.game_info_languages: - raise KeyError("Sorry, this game's info page is not available in that language yet.") - except KeyError: - return abort(404) - return render_template('gameInfo.html', game=game, lang=lang, theme=get_world_theme(game)) + """Game Info Pages""" + theme = get_world_theme(game) + secure_game_name = secure_filename(game) + lang = secure_filename(lang) + document = render_markdown(os.path.join( + app.static_folder, "generated", "docs", + secure_game_name, f"{lang}_{secure_game_name}.md" + )) + return render_template( + "markdown_document.html", + title=f"{game} Guide", + html_from_markdown=document, + theme=theme, + ) -# List of supported games @app.route('/games') @cache.cached() def games(): - worlds = {} - for game, world in AutoWorldRegister.world_types.items(): - if not world.hidden: - worlds[game] = world - return render_template("supportedGames.html", worlds=worlds) + """List of supported games""" + return render_template("supportedGames.html", worlds=get_visible_worlds()) -@app.route('/tutorial///') +@app.route('/tutorial//') @cache.cached() -def tutorial(game, file, lang): - try: - world = AutoWorldRegister.world_types[game] - if lang not in [tut.link.split("/")[1] for tut in world.web.tutorials]: - raise KeyError("Sorry, the tutorial is not available in that language yet.") - except KeyError: - return abort(404) - return render_template("tutorial.html", game=game, file=file, lang=lang, theme=get_world_theme(game)) +def tutorial(game: str, file: str): + theme = get_world_theme(game) + secure_game_name = secure_filename(game) + file = secure_filename(file) + document = render_markdown(os.path.join( + app.static_folder, "generated", "docs", + secure_game_name, file+".md" + )) + return render_template( + "markdown_document.html", + title=f"{game} Guide", + html_from_markdown=document, + theme=theme, + ) @app.route('/tutorial/') @cache.cached() def tutorial_landing(): - return render_template("tutorialLanding.html") + tutorials = {} + worlds = AutoWorldRegister.world_types + for world_name, world_type in worlds.items(): + current_world = tutorials[world_name] = {} + for tutorial in world_type.web.tutorials: + current_tutorial = current_world.setdefault(tutorial.tutorial_name, { + "description": tutorial.description, "files": {}}) + current_tutorial["files"][secure_filename(tutorial.file_name).rsplit(".", 1)[0]] = { + "authors": tutorial.authors, + "language": tutorial.language + } + tutorials = {world_name: tutorials for world_name, tutorials in title_sorted( + tutorials.items(), key=lambda element: "\x00" if element[0] == "Archipelago" else worlds[element[0]].game)} + return render_template("tutorialLanding.html", worlds=worlds, tutorials=tutorials) @app.route('/faq//') @cache.cached() def faq(lang: str): - import markdown - with open(os.path.join(app.static_folder, "assets", "faq", secure_filename(lang)+".md")) as f: - document = f.read() + document = render_markdown(os.path.join(app.static_folder, "assets", "faq", secure_filename(lang)+".md")) return render_template( "markdown_document.html", title="Frequently Asked Questions", - html_from_markdown=markdown.markdown( - document, - extensions=["toc", "mdx_breakless_lists"], - extension_configs={ - "toc": {"anchorlink": True} - } - ), + html_from_markdown=document, ) @app.route('/glossary//') @cache.cached() def glossary(lang: str): - import markdown - with open(os.path.join(app.static_folder, "assets", "glossary", secure_filename(lang)+".md")) as f: - document = f.read() + document = render_markdown(os.path.join(app.static_folder, "assets", "glossary", secure_filename(lang)+".md")) return render_template( "markdown_document.html", title="Glossary", - html_from_markdown=markdown.markdown( - document, - extensions=["toc", "mdx_breakless_lists"], - extension_configs={ - "toc": {"anchorlink": True} - } - ), + html_from_markdown=document, ) diff --git a/WebHostLib/requirements.txt b/WebHostLib/requirements.txt index 4e6bf25df038..8fd6dc630428 100644 --- a/WebHostLib/requirements.txt +++ b/WebHostLib/requirements.txt @@ -7,6 +7,5 @@ Flask-Compress>=1.17 Flask-Limiter>=3.12 bokeh>=3.6.3 markupsafe>=3.0.2 -Markdown>=3.7 -mdx-breakless-lists>=1.0.1 setproctitle>=1.3.5 +mistune>=3.1.3 diff --git a/WebHostLib/static/assets/gameInfo.js b/WebHostLib/static/assets/gameInfo.js deleted file mode 100644 index 797c9f644847..000000000000 --- a/WebHostLib/static/assets/gameInfo.js +++ /dev/null @@ -1,45 +0,0 @@ -window.addEventListener('load', () => { - const gameInfo = document.getElementById('game-info'); - new Promise((resolve, reject) => { - const ajax = new XMLHttpRequest(); - ajax.onreadystatechange = () => { - if (ajax.readyState !== 4) { return; } - if (ajax.status === 404) { - reject("Sorry, this game's info page is not available in that language yet."); - return; - } - if (ajax.status !== 200) { - reject("Something went wrong while loading the info page."); - return; - } - resolve(ajax.responseText); - }; - ajax.open('GET', `${window.location.origin}/static/generated/docs/${gameInfo.getAttribute('data-game')}/` + - `${gameInfo.getAttribute('data-lang')}_${gameInfo.getAttribute('data-game')}.md`, true); - ajax.send(); - }).then((results) => { - // Populate page with HTML generated from markdown - showdown.setOption('tables', true); - showdown.setOption('strikethrough', true); - showdown.setOption('literalMidWordUnderscores', true); - gameInfo.innerHTML += (new showdown.Converter()).makeHtml(results); - - // Reset the id of all header divs to something nicer - for (const header of document.querySelectorAll('h1, h2, h3, h4, h5, h6')) { - const headerId = header.innerText.replace(/\s+/g, '-').toLowerCase(); - header.setAttribute('id', headerId); - header.addEventListener('click', () => { - window.location.hash = `#${headerId}`; - header.scrollIntoView(); - }); - } - - // Manually scroll the user to the appropriate header if anchor navigation is used - document.fonts.ready.finally(() => { - if (window.location.hash) { - const scrollTarget = document.getElementById(window.location.hash.substring(1)); - scrollTarget?.scrollIntoView(); - } - }); - }); -}); diff --git a/WebHostLib/static/assets/tutorial.js b/WebHostLib/static/assets/tutorial.js deleted file mode 100644 index c9022719fbb7..000000000000 --- a/WebHostLib/static/assets/tutorial.js +++ /dev/null @@ -1,52 +0,0 @@ -window.addEventListener('load', () => { - const tutorialWrapper = document.getElementById('tutorial-wrapper'); - new Promise((resolve, reject) => { - const ajax = new XMLHttpRequest(); - ajax.onreadystatechange = () => { - if (ajax.readyState !== 4) { return; } - if (ajax.status === 404) { - reject("Sorry, the tutorial is not available in that language yet."); - return; - } - if (ajax.status !== 200) { - reject("Something went wrong while loading the tutorial."); - return; - } - resolve(ajax.responseText); - }; - ajax.open('GET', `${window.location.origin}/static/generated/docs/` + - `${tutorialWrapper.getAttribute('data-game')}/${tutorialWrapper.getAttribute('data-file')}_` + - `${tutorialWrapper.getAttribute('data-lang')}.md`, true); - ajax.send(); - }).then((results) => { - // Populate page with HTML generated from markdown - showdown.setOption('tables', true); - showdown.setOption('strikethrough', true); - showdown.setOption('literalMidWordUnderscores', true); - showdown.setOption('disableForced4SpacesIndentedSublists', true); - tutorialWrapper.innerHTML += (new showdown.Converter()).makeHtml(results); - - const title = document.querySelector('h1') - if (title) { - document.title = title.textContent; - } - - // Reset the id of all header divs to something nicer - for (const header of document.querySelectorAll('h1, h2, h3, h4, h5, h6')) { - const headerId = header.innerText.replace(/\s+/g, '-').toLowerCase(); - header.setAttribute('id', headerId); - header.addEventListener('click', () => { - window.location.hash = `#${headerId}`; - header.scrollIntoView(); - }); - } - - // Manually scroll the user to the appropriate header if anchor navigation is used - document.fonts.ready.finally(() => { - if (window.location.hash) { - const scrollTarget = document.getElementById(window.location.hash.substring(1)); - scrollTarget?.scrollIntoView(); - } - }); - }); -}); diff --git a/WebHostLib/static/assets/tutorialLanding.js b/WebHostLib/static/assets/tutorialLanding.js deleted file mode 100644 index b820cc34653a..000000000000 --- a/WebHostLib/static/assets/tutorialLanding.js +++ /dev/null @@ -1,81 +0,0 @@ -const showError = () => { - const tutorial = document.getElementById('tutorial-landing'); - document.getElementById('page-title').innerText = 'This page is out of logic!'; - tutorial.removeChild(document.getElementById('loading')); - const userMessage = document.createElement('h3'); - const homepageLink = document.createElement('a'); - homepageLink.innerText = 'Click here'; - homepageLink.setAttribute('href', '/'); - userMessage.append(homepageLink); - userMessage.append(' to go back to safety!'); - tutorial.append(userMessage); -}; - -window.addEventListener('load', () => { - const ajax = new XMLHttpRequest(); - ajax.onreadystatechange = () => { - if (ajax.readyState !== 4) { return; } - const tutorialDiv = document.getElementById('tutorial-landing'); - if (ajax.status !== 200) { return showError(); } - - try { - const games = JSON.parse(ajax.responseText); - games.forEach((game) => { - const gameTitle = document.createElement('h2'); - gameTitle.innerText = game.gameTitle; - gameTitle.id = `${encodeURIComponent(game.gameTitle)}`; - tutorialDiv.appendChild(gameTitle); - - game.tutorials.forEach((tutorial) => { - const tutorialName = document.createElement('h3'); - tutorialName.innerText = tutorial.name; - tutorialDiv.appendChild(tutorialName); - - const tutorialDescription = document.createElement('p'); - tutorialDescription.innerText = tutorial.description; - tutorialDiv.appendChild(tutorialDescription); - - const intro = document.createElement('p'); - intro.innerText = 'This guide is available in the following languages:'; - tutorialDiv.appendChild(intro); - - const fileList = document.createElement('ul'); - tutorial.files.forEach((file) => { - const listItem = document.createElement('li'); - const anchor = document.createElement('a'); - anchor.innerText = file.language; - anchor.setAttribute('href', `${window.location.origin}/tutorial/${file.link}`); - listItem.appendChild(anchor); - - listItem.append(' by '); - for (let author of file.authors) { - listItem.append(author); - if (file.authors.indexOf(author) !== (file.authors.length -1)) { - listItem.append(', '); - } - } - - fileList.appendChild(listItem); - }); - tutorialDiv.appendChild(fileList); - }); - }); - - tutorialDiv.removeChild(document.getElementById('loading')); - } catch (error) { - showError(); - console.error(error); - } - - // Check if we are on an anchor when coming in, and scroll to it. - const hash = window.location.hash; - if (hash) { - const offset = 128; // To account for navbar banner at top of page. - window.scrollTo(0, 0); - const rect = document.getElementById(hash.slice(1)).getBoundingClientRect(); - window.scrollTo(rect.left, rect.top - offset); - } - }; - ajax.open('GET', `${window.location.origin}/static/generated/tutorials.json`, true); - ajax.send(); -}); diff --git a/WebHostLib/templates/gameInfo.html b/WebHostLib/templates/gameInfo.html deleted file mode 100644 index 3b908004b1be..000000000000 --- a/WebHostLib/templates/gameInfo.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends 'pageWrapper.html' %} - -{% block head %} - {{ game }} Info - - - -{% endblock %} - -{% block body %} - {% include 'header/'+theme+'Header.html' %} -
    - -
    -{% endblock %} diff --git a/WebHostLib/templates/markdown_document.html b/WebHostLib/templates/markdown_document.html index 07b3c8354d0d..a56ea244c724 100644 --- a/WebHostLib/templates/markdown_document.html +++ b/WebHostLib/templates/markdown_document.html @@ -1,7 +1,8 @@ {% extends 'pageWrapper.html' %} {% block head %} - {% include 'header/grassHeader.html' %} + {% set theme_name = theme|default("grass", true) %} + {% include "header/"+theme_name+"Header.html" %} {{ title }} {% endblock %} diff --git a/WebHostLib/templates/tutorial.html b/WebHostLib/templates/tutorial.html deleted file mode 100644 index 4b6622c31336..000000000000 --- a/WebHostLib/templates/tutorial.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends 'pageWrapper.html' %} - -{% block head %} - {% include 'header/'+theme+'Header.html' %} - Archipelago - - - -{% endblock %} - -{% block body %} -
    - -
    -{% endblock %} diff --git a/WebHostLib/templates/tutorialLanding.html b/WebHostLib/templates/tutorialLanding.html index 14db577e77d9..a96da883b624 100644 --- a/WebHostLib/templates/tutorialLanding.html +++ b/WebHostLib/templates/tutorialLanding.html @@ -3,14 +3,32 @@ {% block head %} {% include 'header/grassHeader.html' %} Archipelago Guides - - - + + {% endblock %} {% block body %} -
    -

    Archipelago Guides

    -

    Loading...

    +
    +

    Archipelago Guides

    + {% for world_name, world_type in worlds.items() %} +

    {{ world_type.game }}

    + {% for tutorial_name, tutorial_data in tutorials[world_name].items() %} +

    {{ tutorial_name }}

    +

    {{ tutorial_data.description }}

    +

    This guide is available in the following languages:

    +
      + {% for file_name, file_data in tutorial_data.files.items() %} +
    • + {{ file_data.language }} + by + {% for author in file_data.authors %} + {{ author }} + {% if not loop.last %}, {% endif %} + {% endfor %} +
    • + {% endfor %} +
    + {% endfor %} + {% endfor %}
    -{% endblock %} +{% endblock %} diff --git a/test/webhost/test_docs.py b/test/webhost/test_docs.py index 1e6c1b88f42c..a178a7cbf0bc 100644 --- a/test/webhost/test_docs.py +++ b/test/webhost/test_docs.py @@ -2,6 +2,8 @@ import Utils import os +from werkzeug.utils import secure_filename + import WebHost from worlds.AutoWorld import AutoWorldRegister @@ -9,36 +11,30 @@ class TestDocs(unittest.TestCase): @classmethod def setUpClass(cls) -> None: - cls.tutorials_data = WebHost.create_ordered_tutorials_file() + WebHost.copy_tutorials_files_to_static() def test_has_tutorial(self): - games_with_tutorial = set(entry["gameTitle"] for entry in self.tutorials_data) for game_name, world_type in AutoWorldRegister.world_types.items(): if not world_type.hidden: with self.subTest(game_name): - try: - self.assertIn(game_name, games_with_tutorial) - except AssertionError: - # look for partial name in the tutorial name - for game in games_with_tutorial: - if game_name in game: - break - else: - self.fail(f"{game_name} has no setup tutorial. " - f"Games with Tutorial: {games_with_tutorial}") + tutorials = world_type.web.tutorials + self.assertGreater(len(tutorials), 0, msg=f"{game_name} has no setup tutorial.") + + safe_name = secure_filename(game_name) + target_path = Utils.local_path("WebHostLib", "static", "generated", "docs", safe_name) + for tutorial in tutorials: + self.assertTrue( + os.path.isfile(Utils.local_path(target_path, secure_filename(tutorial.file_name))), + f'{game_name} missing tutorial file {tutorial.file_name}.' + ) def test_has_game_info(self): for game_name, world_type in AutoWorldRegister.world_types.items(): if not world_type.hidden: - safe_name = Utils.get_file_safe_name(game_name) + safe_name = secure_filename(game_name) target_path = Utils.local_path("WebHostLib", "static", "generated", "docs", safe_name) for game_info_lang in world_type.web.game_info_languages: with self.subTest(game_name): - self.assertTrue( - safe_name == game_name or - not os.path.isfile(Utils.local_path(target_path, f'{game_info_lang}_{game_name}.md')), - f'Info docs have be named _{safe_name}.md for {game_name}.' - ) self.assertTrue( os.path.isfile(Utils.local_path(target_path, f'{game_info_lang}_{safe_name}.md')), f'{game_name} missing game info file for "{game_info_lang}" language.' diff --git a/test/webhost/test_file_generation.py b/test/webhost/test_file_generation.py index 059f6b49a1fd..7b14ac871b95 100644 --- a/test/webhost/test_file_generation.py +++ b/test/webhost/test_file_generation.py @@ -29,8 +29,3 @@ def test_options(self): with open(file, encoding="utf-8-sig") as f: for value in roll_options({file.name: f.read()})[0].values(): self.assertTrue(value is True, f"Default Options for template {file.name} cannot be run.") - - def test_tutorial(self): - WebHost.create_ordered_tutorials_file() - self.assertTrue(os.path.exists(os.path.join(self.correct_path, "static", "generated", "tutorials.json"))) - self.assertFalse(os.path.exists(os.path.join(self.incorrect_path, "static", "generated", "tutorials.json"))) diff --git a/worlds/ahit/__init__.py b/worlds/ahit/__init__.py index d258f8050d8d..ff117283723c 100644 --- a/worlds/ahit/__init__.py +++ b/worlds/ahit/__init__.py @@ -34,7 +34,7 @@ class AWebInTime(WebWorld): "Multiworld Setup Guide", "A guide for setting up A Hat in Time to be played in Archipelago.", "English", - "ahit_en.md", + "setup_en.md", "setup/en", ["CookieCat"] )] diff --git a/worlds/osrs/__init__.py b/worlds/osrs/__init__.py index 9e439fe52ce3..a54e272d05fb 100644 --- a/worlds/osrs/__init__.py +++ b/worlds/osrs/__init__.py @@ -25,7 +25,7 @@ class OSRSWeb(WebWorld): "Multiworld Setup Guide", "A guide to setting up the Old School Runescape Randomizer connected to an Archipelago Multiworld", "English", - "docs/setup_en.md", + "setup_en.md", "setup/en", ["digiholic"] ) diff --git a/worlds/yugioh06/__init__.py b/worlds/yugioh06/__init__.py index 9070683f33d5..5d4cddd95c68 100644 --- a/worlds/yugioh06/__init__.py +++ b/worlds/yugioh06/__init__.py @@ -56,7 +56,7 @@ class Yugioh06Web(WebWorld): "A guide to setting up Yu-Gi-Oh! - Ultimate Masters Edition - World Championship Tournament 2006 " "for Archipelago on your computer.", "English", - "docs/setup_en.md", + "setup_en.md", "setup/en", ["Rensen"], ) From d408f7cabcf17301d722779fe83fe8b84ae07089 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 2 Aug 2025 21:19:23 +0200 Subject: [PATCH 0640/1218] Subnautica: add empty tanks option (#5271) --- worlds/subnautica/__init__.py | 3 ++- worlds/subnautica/options.py | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/worlds/subnautica/__init__.py b/worlds/subnautica/__init__.py index 850c23c7dd24..bfedf0c90a6a 100644 --- a/worlds/subnautica/__init__.py +++ b/worlds/subnautica/__init__.py @@ -41,7 +41,7 @@ class SubnauticaWorld(World): location_name_to_id = all_locations options_dataclass = options.SubnauticaOptions options: options.SubnauticaOptions - required_client_version = (0, 5, 0) + required_client_version = (0, 6, 2) origin_region_name = "Planet 4546B" creatures_to_scan: List[str] @@ -155,6 +155,7 @@ def fill_slot_data(self) -> Dict[str, Any]: "creatures_to_scan": self.creatures_to_scan, "death_link": self.options.death_link.value, "free_samples": self.options.free_samples.value, + "empty_tanks": self.options.empty_tanks.value, } return slot_data diff --git a/worlds/subnautica/options.py b/worlds/subnautica/options.py index 6cdcb33d8954..0aa869de0bf6 100644 --- a/worlds/subnautica/options.py +++ b/worlds/subnautica/options.py @@ -129,6 +129,10 @@ def weights_pair(self) -> typing.Tuple[typing.List[str], typing.List[int]]: return list(self.value.keys()), list(accumulate(self.value.values())) +class EmptyTanks(DefaultOnToggle): + """Oxygen Tanks stored in inventory are empty if enabled.""" + + @dataclass class SubnauticaOptions(PerGameCommonOptions): swim_rule: SwimRule @@ -140,3 +144,4 @@ class SubnauticaOptions(PerGameCommonOptions): death_link: SubnauticaDeathLink start_inventory_from_pool: StartInventoryPool filler_items_distribution: FillerItemsDistribution + empty_tanks: EmptyTanks From 84c2d70d9ada50d212d0662e07e0660c0e78b63d Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Sat, 2 Aug 2025 22:50:59 -0400 Subject: [PATCH 0641/1218] Fix regression on 404 redirects --- WebHostLib/misc.py | 58 +++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/WebHostLib/misc.py b/WebHostLib/misc.py index d7ac950817b1..ee85d3defbe3 100644 --- a/WebHostLib/misc.py +++ b/WebHostLib/misc.py @@ -87,19 +87,22 @@ def start_playing(): @cache.cached() def game_info(game, lang): """Game Info Pages""" - theme = get_world_theme(game) - secure_game_name = secure_filename(game) - lang = secure_filename(lang) - document = render_markdown(os.path.join( - app.static_folder, "generated", "docs", - secure_game_name, f"{lang}_{secure_game_name}.md" - )) - return render_template( - "markdown_document.html", - title=f"{game} Guide", - html_from_markdown=document, - theme=theme, - ) + try: + theme = get_world_theme(game) + secure_game_name = secure_filename(game) + lang = secure_filename(lang) + document = render_markdown(os.path.join( + app.static_folder, "generated", "docs", + secure_game_name, f"{lang}_{secure_game_name}.md" + )) + return render_template( + "markdown_document.html", + title=f"{game} Guide", + html_from_markdown=document, + theme=theme, + ) + except FileNotFoundError: + return abort(404) @app.route('/games') @@ -112,19 +115,22 @@ def games(): @app.route('/tutorial//') @cache.cached() def tutorial(game: str, file: str): - theme = get_world_theme(game) - secure_game_name = secure_filename(game) - file = secure_filename(file) - document = render_markdown(os.path.join( - app.static_folder, "generated", "docs", - secure_game_name, file+".md" - )) - return render_template( - "markdown_document.html", - title=f"{game} Guide", - html_from_markdown=document, - theme=theme, - ) + try: + theme = get_world_theme(game) + secure_game_name = secure_filename(game) + file = secure_filename(file) + document = render_markdown(os.path.join( + app.static_folder, "generated", "docs", + secure_game_name, file+".md" + )) + return render_template( + "markdown_document.html", + title=f"{game} Guide", + html_from_markdown=document, + theme=theme, + ) + except FileNotFoundError: + return abort(404) @app.route('/tutorial/') From e6d2d8f4557b382676ca038e264d5d1a69b2682a Mon Sep 17 00:00:00 2001 From: Ishigh1 Date: Mon, 4 Aug 2025 14:19:51 +0200 Subject: [PATCH 0642/1218] Core: Added a leading 0 to classification.as_flag #5291 --- BaseClasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index d00c6007e172..93264d909c9e 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1571,7 +1571,7 @@ class ItemClassification(IntFlag): def as_flag(self) -> int: """As Network API flag int.""" - return int(self & 0b0111) + return int(self & 0b00111) class Item: From 3b88630b0d8a58aeb3f58a2cb3957efc7b1ace97 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 4 Aug 2025 08:21:58 -0400 Subject: [PATCH 0643/1218] TUNIC: Fix zig skip showing up in decoupled + fixed shop #5289 --- worlds/tunic/er_scripts.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index ae1b5fcb454d..9fc44d842cc4 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -255,8 +255,10 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: else: dead_ends.append(portal) dead_end_direction_tracker[portal.direction] += 1 - if portal.region == "Zig Skip Exit" and entrance_layout == EntranceLayout.option_fixed_shop: + if (portal.region == "Zig Skip Exit" and entrance_layout == EntranceLayout.option_fixed_shop + and not decoupled): # direction isn't meaningful here since zig skip cannot be in direction pairs mode + # don't add it in decoupled two_plus.append(portal) # now we generate the shops and add them to the dead ends list From 4e92cac171e3c35688cae74f65a812aa17b0035a Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Mon, 4 Aug 2025 11:46:05 -0400 Subject: [PATCH 0644/1218] LADX: Update Docs (#5290) * convert ladxr section to markdown, other adjustments make links clickable crow icon -> open tracker adjust for removed sprite sheets some adjustments in ladxr section for differences in the ap version: we don't have a casual logic we don't have stealing options * fix link, and another correction --- worlds/ladx/docs/en_Links Awakening DX.md | 103 ++++++++++++---------- 1 file changed, 58 insertions(+), 45 deletions(-) diff --git a/worlds/ladx/docs/en_Links Awakening DX.md b/worlds/ladx/docs/en_Links Awakening DX.md index 91a34107c169..ad691008ec61 100644 --- a/worlds/ladx/docs/en_Links Awakening DX.md +++ b/worlds/ladx/docs/en_Links Awakening DX.md @@ -34,62 +34,75 @@ business! ## I don't know what to do! -That's not a question - but I'd suggest clicking the crow icon on your client, which will load an AP compatible autotracker for LADXR. +That's not a question - but I'd suggest clicking the **Open Tracker** button in your client, which will load an AP compatible autotracker for LADXR. ## What is this randomizer based on? -This randomizer is based on (forked from) the wonderful work daid did on LADXR - https://github.com/daid/LADXR +This randomizer is based on (forked from) the wonderful work daid did on [LADXR](https://github.com/daid/LADXR) -The autotracker code for communication with magpie tracker is directly copied from kbranch's repo - https://github.com/kbranch/Magpie/tree/master/autotracking +The autotracker code for communication with magpie tracker is directly copied from [kbranch's repo](https://github.com/kbranch/Magpie) ### Graphics The following sprite sheets have been included with permission of their respective authors: -* by Madam Materia (https://www.twitch.tv/isabelle_zephyr) +* by [Madam Materia](https://www.twitch.tv/isabelle_zephyr) * Matty_LA -* by Linker (https://twitter.com/BenjaminMaksym) - * Bowwow - * Bunny - * Luigi - * Mario - * Richard - * Tarin -Title screen graphics by toomanyteeth✨ (https://instagram.com/toomanyyyteeth) +Title screen graphics by [toomanyteeth✨](https://instagram.com/toomanyyyteeth) ## Some tips from LADXR... -

    Locations

    -

    All chests and dungeon keys are always randomized. Also, the 3 songs (Marin, Mambo, and Manu) give a you an item if you present them the Ocarina. The seashell mansion 20 shells reward is also shuffled, but the 5 and 10 shell reward is not, as those can be missed.

    -

    The moblin cave with Bowwow contains a chest instead. The color dungeon gives 2 items at the end instead of a choice of tunic. Other item locations are: The toadstool, the reward for delivering the toadstool, hidden seashells, heart pieces, heart containers, golden leaves, the Mad Batters (capacity upgrades), the shovel/bow in the shop, the rooster's grave, and all of the keys' (tail,slime,angler,face,bird) locations.

    -

    Finally, new players often forget the following locations: the heart piece hidden in the water at the castle, the heart piece hidden in the bomb cave (screen before the honey), bonk seashells (run with pegasus boots against the tree in at the Tail Cave, and the tree right of Mabe Village, next to the phone booth), and the hookshop drop from Master Stalfos in D5.

    - -

    Color Dungeon

    -

    The Color Dungeon is part of the item shuffle, and the red/blue tunics are shuffled in the item pool. Which means the fairy at the end of the color dungeon gives out two random items.

    -

    To access the color dungeon, you need the power bracelet, and you need to push the gravestones in the right order: "down, left, up, right, up", going from the lower right gravestone, to the one left of it, above it, and then to the right.

    - -

    Bowwow

    -

    Bowwow is in a chest, somewhere. After you find him, he will always be in the swamp with you, but not anywhere else.

    - -

    Added things

    -

    In your save and quit menu, there is a 3rd option to return to your home. This has two main uses: it speeds up the game, and prevents softlocks (common in entrance rando).

    -

    If you have weapons that require ammunition (bombs, powder, arrows), a ghost will show up inside Marin's house. He will refill you up to 10 ammunition, so you do not run out.

    -

    The flying rooster is (optionally) available as an item.

    -

    You can access the Bird Key cave item with the L2 Power Bracelet.

    -

    Boomerang cave is now a random item gift by default (available post-bombs), and boomerang is in the item pool.

    -

    Your inventory has been increased by four, to accommodate these items now coexisting with eachother.

    - -

    Removed things

    -

    The ghost mini-quest after D4 never shows up, his seashell reward is always available.

    -

    The walrus is moved a bit, so that you can access the desert without taking Marin on a date.

    - -

    Logic

    -

    Depending on your options, you can only steal after you find the sword, always, or never.

    -

    Do not forget that there are two items in the rafting ride. You can access this with just Hookshot or Flippers.

    -

    Killing enemies with bombs is in normal logic. You can switch to casual logic if you do not want this.

    -

    D7 confuses some people, but by dropping down pits on the 2nd floor you can access almost all of this dungeon, even without feather and power bracelet.

    - -

    Tech

    -

    The toadstool and magic powder used to be the same type of item. LADXR turns this into two items that you can have a the same time. 4 extra item slots in your inventory were added to support this extra item, and have the ability to own the boomerang.

    -

    The glitch where the slime key is effectively a 6th golden leaf is fixed, and golden leaves can be collected fine next to the slime key.

    +### Locations + +All chests and dungeon keys are always randomized. Also, the 3 songs (Marin, Mambo, and Manu) give a you an item if you present them the Ocarina. The seashell mansion 20 shells reward is also shuffled, but the 5 and 10 shell reward is not, as those can be missed. + +The moblin cave with Bowwow contains a chest instead. The color dungeon gives 2 items at the end instead of a choice of tunic. Other item locations are: The toadstool, the reward for delivering the toadstool, hidden seashells, heart pieces, heart containers, golden leaves, the Mad Batters (capacity upgrades), the shovel/bow in the shop, the rooster's grave, and all of the keys' (tail,slime,angler,face,bird) locations. + +Finally, new players often forget the following locations: the heart piece hidden in the water at the castle, the heart piece hidden in the bomb cave (screen before the honey), bonk seashells (run with pegasus boots against the tree in at the Tail Cave, and the tree right of Mabe Village, next to the phone booth), and the hookshop drop from Master Stalfos in D5. + +### Color Dungeon + +The Color Dungeon is part of the item shuffle, and the red/blue tunics are shuffled in the item pool. Which means the fairy at the end of the color dungeon gives out two random items. + +To access the color dungeon, you need the power bracelet, and you need to push the gravestones in the right order: "down, left, up, right, up", going from the lower right gravestone, to the one left of it, above it, and then to the right. + +### Bowwow + +Bowwow is in a chest, somewhere. After you find him, he will always be in the swamp with you, but not anywhere else. + +### Added things + +In your save and quit menu, there is a 3rd option to return to your home. This has two main uses: it speeds up the game, and prevents softlocks (common in entrance rando). + +If you have weapons that require ammunition (bombs, powder, arrows), a ghost will show up inside Marin's house. He will refill you up to 10 ammunition, so you do not run out. + +The flying rooster is (optionally) available as an item. + +If the rooster is disabled, you can access the Bird Key cave item with the L2 Power Bracelet. + +Boomerang cave is now a random item gift by default (available post-bombs), and boomerang is in the item pool. + +Your inventory has been increased by four, to accommodate these items now coexisting with eachother. + +### Removed things + +The ghost mini-quest after D4 never shows up, his seashell reward is always available. + +The walrus is moved a bit, so that you can access the desert without taking Marin on a date. + +### Logic + +You can only steal after you find the sword. + +Do not forget that there are two items in the rafting ride. You can access this with just Hookshot or Flippers. + +Killing enemies with bombs is in logic. + +D7 confuses some people, but by dropping down pits on the 2nd floor you can access almost all of this dungeon, even without feather and power bracelet. + +### Tech + +The toadstool and magic powder used to be the same type of item. LADXR turns this into two items that you can have a the same time. 4 extra item slots in your inventory were added to support this extra item, and have the ability to own the boomerang. + +The glitch where the slime key is effectively a 6th golden leaf is fixed, and golden leaves can be collected fine next to the slime key. From 1f6c99635e7f7e55c49a1c3ab41d2444716f8f98 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Tue, 5 Aug 2025 15:25:11 -0500 Subject: [PATCH 0645/1218] FF1: fix client breaking other NES games (#5293) --- worlds/ff1/Client.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/worlds/ff1/Client.py b/worlds/ff1/Client.py index f7315f69f0ad..a4279afd3a4a 100644 --- a/worlds/ff1/Client.py +++ b/worlds/ff1/Client.py @@ -89,11 +89,15 @@ def __init__(self) -> None: async def validate_rom(self, ctx: "BizHawkClientContext") -> bool: try: + if (await bizhawk.get_memory_size(ctx.bizhawk_ctx, self.rom)) < rom_name_location + 0x0D: + return False # ROM is not large enough to be a Final Fantasy 1 ROM # Check ROM name/patch version rom_name = ((await bizhawk.read(ctx.bizhawk_ctx, [(rom_name_location, 0x0D, self.rom)]))[0]) rom_name = rom_name.decode("ascii") if rom_name != "FINAL FANTASY": return False # Not a Final Fantasy 1 ROM + except UnicodeDecodeError: + return False # rom_name returned invalid text except bizhawk.RequestFailedError: return False # Not able to get a response, say no for now From 4633f129729853fcf77aa075ed6296fddacb41e4 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Thu, 7 Aug 2025 14:14:09 -0400 Subject: [PATCH 0646/1218] Docs: Use / instead of . for the reference to lttp's options.py (#5300) * Update options api.md * o -> O --- docs/options api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/options api.md b/docs/options api.md index c9b7c422fec8..193d3953426a 100644 --- a/docs/options api.md +++ b/docs/options api.md @@ -344,7 +344,7 @@ names, and `def can_place_boss`, which passes a boss and location, allowing you your game. When this function is called, `bosses`, `locations`, and the passed strings will all be lowercase. There is also a `duplicate_bosses` attribute allowing you to define if a boss can be placed multiple times in your world. False by default, and will reject duplicate boss names from the user. For an example of using this class, refer to -`worlds.alttp.options.py` +`worlds/alttp/Options.py` ### OptionDict This option returns a dictionary. Setting a default here is recommended as it will output the dictionary to the From 17ccfdc266d382ec38b7f1811d8ea430367cdc3b Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Fri, 8 Aug 2025 15:07:36 -0400 Subject: [PATCH 0647/1218] DS3: Don't Create Disabled Locations (#5292) --- worlds/dark_souls_3/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 6584ccec8778..a1ad2f6a7066 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -267,6 +267,10 @@ def create_region(self, region_name, location_table) -> Region: # Don't allow missable duplicates of progression items to be expected progression. if location.name in self.missable_dupe_prog_locs: continue + # Don't create DLC and NGP locations if those are disabled + if location.dlc and not self.options.enable_dlc: continue + if location.ngp and not self.options.enable_ngp: continue + # Replace non-randomized items with events that give the default item event_item = ( self.create_item(location.default_item_name) if location.default_item_name From ecb22642af291e05bdc6ae729bb14d4d1ae83792 Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Fri, 8 Aug 2025 16:24:19 -0600 Subject: [PATCH 0648/1218] Tests: Handle optional args for `get_all_state` patch (#5297) * Make `use_cache` optional * Pass all kwargs --- test/general/test_entrances.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/general/test_entrances.py b/test/general/test_entrances.py index 88362c8fa6d4..79025534ac68 100644 --- a/test/general/test_entrances.py +++ b/test/general/test_entrances.py @@ -48,13 +48,14 @@ def test_all_state_before_connect_entrances(self): original_get_all_state = multiworld.get_all_state - def patched_get_all_state(use_cache: bool, allow_partial_entrances: bool = False): + def patched_get_all_state(use_cache: bool | None = None, allow_partial_entrances: bool = False, + **kwargs): self.assertTrue(allow_partial_entrances, ( "Before the connect_entrances step finishes, other worlds might still have partial entrances. " "As such, any call to get_all_state must use allow_partial_entrances = True." )) - return original_get_all_state(use_cache, allow_partial_entrances) + return original_get_all_state(use_cache, allow_partial_entrances, **kwargs) multiworld.get_all_state = patched_get_all_state From 9bd535752e5bcde56ac12515217216c18cab57aa Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Sun, 10 Aug 2025 16:03:12 +0100 Subject: [PATCH 0649/1218] Core: Sort Unreachable Locations Written to the Spoiler (#5269) --- BaseClasses.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index 93264d909c9e..ca717b60f25f 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1899,7 +1899,8 @@ def write_option(option_key: str, option_obj: Options.AssembleOptions) -> None: if self.unreachables: outfile.write('\n\nUnreachable Progression Items:\n\n') outfile.write( - '\n'.join(['%s: %s' % (unreachable.item, unreachable) for unreachable in self.unreachables])) + '\n'.join(['%s: %s' % (unreachable.item, unreachable) + for unreachable in sorted(self.unreachables)])) if self.paths: outfile.write('\n\nPaths:\n\n') From c34c00baa433cfb8cb01fa8308b73ecb9dd1cec9 Mon Sep 17 00:00:00 2001 From: Adrian Priestley <47989725+a-priestley@users.noreply.github.com> Date: Sun, 10 Aug 2025 12:39:31 -0230 Subject: [PATCH 0650/1218] fix(deps): Lock setuptools version to <81 (#5284) - Update Dockerfile to specify "setuptools<81" - Modify ModuleUpdate.py to install setuptools with version constraint --- Dockerfile | 2 +- ModuleUpdate.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 46393aab9eaa..9e3c5f0d712a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,7 +28,7 @@ COPY requirements.txt WebHostLib/requirements.txt RUN pip install --no-cache-dir -r \ WebHostLib/requirements.txt \ - setuptools + "setuptools<81" COPY _speedups.pyx . COPY intset.h . diff --git a/ModuleUpdate.py b/ModuleUpdate.py index e6ac570e5813..2e58c4f7f93b 100644 --- a/ModuleUpdate.py +++ b/ModuleUpdate.py @@ -78,7 +78,7 @@ def install_pkg_resources(yes=False): check_pip() if not yes: confirm("pkg_resources not found, press enter to install it") - subprocess.call([sys.executable, "-m", "pip", "install", "--upgrade", "setuptools"]) + subprocess.call([sys.executable, "-m", "pip", "install", "--upgrade", "setuptools<81"]) def update(yes: bool = False, force: bool = False) -> None: From cdde38fdc9e5f1440249ab8da2cdf8a7edf44ff1 Mon Sep 17 00:00:00 2001 From: qwint Date: Sun, 10 Aug 2025 10:23:39 -0500 Subject: [PATCH 0651/1218] Settings: warn for broken worlds instead of crashing (#4438) note: i swear the issue was an importerror but i could only get attributeerrors on the getattr() call, maybe we want to check for both? --- settings.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/settings.py b/settings.py index ef1ea9adf741..48bc57f04467 100644 --- a/settings.py +++ b/settings.py @@ -754,7 +754,12 @@ def __getattribute__(self, key: str) -> Any: return super().__getattribute__(key) # directly import world and grab settings class world_mod, world_cls_name = _world_settings_name_cache[key].rsplit(".", 1) - world = cast(type, getattr(__import__(world_mod, fromlist=[world_cls_name]), world_cls_name)) + try: + world = cast(type, getattr(__import__(world_mod, fromlist=[world_cls_name]), world_cls_name)) + except AttributeError: + import warnings + warnings.warn(f"World {world_cls_name} failed to initialize properly.") + return super().__getattribute__(key) assert getattr(world, "settings_key") == key try: cls_or_name = world.__annotations__["settings"] From 378cc91a4d5204b9e370c95b17551f2f88a77431 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Tue, 12 Aug 2025 00:41:43 +0000 Subject: [PATCH 0652/1218] CI: update appimage runtime (#5315) --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 721d63b1dc9d..e886ae8230f9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ env: APPIMAGETOOL_VERSION: continuous APPIMAGETOOL_X86_64_HASH: '363dafac070b65cc36ca024b74db1f043c6f5cd7be8fca760e190dce0d18d684' APPIMAGE_RUNTIME_VERSION: continuous - APPIMAGE_RUNTIME_X86_64_HASH: 'e3c4dfb70eddf42e7e5a1d28dff396d30563aa9a901970aebe6f01f3fecf9f8e' + APPIMAGE_RUNTIME_X86_64_HASH: 'e70ffa9b69b211574d0917adc482dd66f25a0083427b5945783965d55b0b0a8b' permissions: # permissions required for attestation id-token: 'write' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1462560052cb..9b7fdd1bcf6b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ env: APPIMAGETOOL_VERSION: continuous APPIMAGETOOL_X86_64_HASH: '363dafac070b65cc36ca024b74db1f043c6f5cd7be8fca760e190dce0d18d684' APPIMAGE_RUNTIME_VERSION: continuous - APPIMAGE_RUNTIME_X86_64_HASH: 'e3c4dfb70eddf42e7e5a1d28dff396d30563aa9a901970aebe6f01f3fecf9f8e' + APPIMAGE_RUNTIME_X86_64_HASH: 'e70ffa9b69b211574d0917adc482dd66f25a0083427b5945783965d55b0b0a8b' permissions: # permissions required for attestation id-token: 'write' From 9057ce0ce3998b5f2ed54748d32f521052e887fe Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 12 Aug 2025 16:52:34 +0200 Subject: [PATCH 0653/1218] WebHost: fix links on sitemap, switch to url_for and add test to prevent future breakage (#5318) --- WebHostLib/templates/siteMap.html | 44 ++++++++++----------- test/general/__init__.py | 9 ++++- test/webhost/test_sitemap.py | 63 +++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 24 deletions(-) create mode 100644 test/webhost/test_sitemap.py diff --git a/WebHostLib/templates/siteMap.html b/WebHostLib/templates/siteMap.html index b7db8227dc50..4b764c341a87 100644 --- a/WebHostLib/templates/siteMap.html +++ b/WebHostLib/templates/siteMap.html @@ -11,32 +11,32 @@

    Site Map

    Base Pages

    Tutorials

    Game Info Pages

    diff --git a/test/general/__init__.py b/test/general/__init__.py index 34df741a8ca6..92ffc77ee6d9 100644 --- a/test/general/__init__.py +++ b/test/general/__init__.py @@ -3,7 +3,7 @@ from BaseClasses import CollectionState, Item, ItemClassification, Location, MultiWorld, Region from worlds import network_data_package -from worlds.AutoWorld import World, call_all +from worlds.AutoWorld import World, WebWorld, call_all gen_steps = ( "generate_early", @@ -17,7 +17,7 @@ def setup_solo_multiworld( - world_type: Type[World], steps: Tuple[str, ...] = gen_steps, seed: Optional[int] = None + world_type: Type[World], steps: Tuple[str, ...] = gen_steps, seed: Optional[int] = None ) -> MultiWorld: """ Creates a multiworld with a single player of `world_type`, sets default options, and calls provided gen steps. @@ -62,11 +62,16 @@ def setup_multiworld(worlds: Union[List[Type[World]], Type[World]], steps: Tuple return multiworld +class TestWebWorld(WebWorld): + tutorials = [] + + class TestWorld(World): game = f"Test Game" item_name_to_id = {} location_name_to_id = {} hidden = True + web = TestWebWorld() # add our test world to the data package, so we can test it later diff --git a/test/webhost/test_sitemap.py b/test/webhost/test_sitemap.py new file mode 100644 index 000000000000..930aa3241558 --- /dev/null +++ b/test/webhost/test_sitemap.py @@ -0,0 +1,63 @@ +import urllib.parse +import html +import re +from flask import url_for + +import WebHost +from . import TestBase + + +class TestSitemap(TestBase): + + # Codes for OK and some redirects that we use + valid_status_codes = [200, 302, 308] + + @classmethod + def setUpClass(cls) -> None: + super().setUpClass() + WebHost.copy_tutorials_files_to_static() + + def test_sitemap_route(self) -> None: + """Verify that the sitemap route works correctly and renders the template without errors.""" + with self.app.test_request_context(): + # Test the /sitemap route + with self.client.open("/sitemap") as response: + self.assertEqual(response.status_code, 200) + self.assertIn(b"Site Map", response.data) + + # Test the /index route which should also serve the sitemap + with self.client.open("/index") as response: + self.assertEqual(response.status_code, 200) + self.assertIn(b"Site Map", response.data) + + # Test using url_for with the function name + with self.client.open(url_for('get_sitemap')) as response: + self.assertEqual(response.status_code, 200) + self.assertIn(b'Site Map', response.data) + + def test_sitemap_links(self) -> None: + """ + Verify that all links in the sitemap are valid by making a request to each one. + """ + with self.app.test_request_context(): + with self.client.open(url_for("get_sitemap")) as response: + self.assertEqual(response.status_code, 200) + html_content = response.data.decode() + + # Extract all href links using regex + href_pattern = re.compile(r'href=["\'](.*?)["\']') + links = href_pattern.findall(html_content) + + self.assertTrue(len(links) > 0, "No links found in sitemap") + + # Test each link + for link in links: + # Skip external links + if link.startswith(("http://", "https://")): + continue + + link = urllib.parse.unquote(html.unescape(link)) + + with self.client.open(link) as response, self.subTest(link=link): + self.assertIn(response.status_code, self.valid_status_codes, + f"Link {link} returned invalid status code {response.status_code}") From 85c26f97400a6caaa7a690b9a299e7373c8ace80 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Tue, 12 Aug 2025 15:38:22 +0000 Subject: [PATCH 0654/1218] WebHost: redirect old tutorials to new URL (#5319) * WebHost: redirect old tutorials to new URL * WebHost: make comment in tutorial_redirect more accurate --- WebHostLib/misc.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/WebHostLib/misc.py b/WebHostLib/misc.py index ee85d3defbe3..c57a6386127f 100644 --- a/WebHostLib/misc.py +++ b/WebHostLib/misc.py @@ -133,6 +133,15 @@ def tutorial(game: str, file: str): return abort(404) +@app.route('/tutorial///') +def tutorial_redirect(game: str, file: str, lang: str): + """ + Permanent redirect old tutorial URLs to new ones to keep search engines happy. + e.g. /tutorial/Archipelago/setup/en -> /tutorial/Archipelago/setup_en + """ + return redirect(url_for("tutorial", game=game, file=f"{file}_{lang}"), code=301) + + @app.route('/tutorial/') @cache.cached() def tutorial_landing(): From 6e6fd0e9bcc40c7524fe5520a4382e43deb70a14 Mon Sep 17 00:00:00 2001 From: LiquidCat64 <74896918+LiquidCat64@users.noreply.github.com> Date: Tue, 12 Aug 2025 14:01:29 -0600 Subject: [PATCH 0655/1218] CV64 and CotM: Correct Archipleago (#5323) --- worlds/cv64/__init__.py | 2 +- worlds/cvcotm/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/cv64/__init__.py b/worlds/cv64/__init__.py index 1bd069a2cea8..117fd44ea06f 100644 --- a/worlds/cv64/__init__.py +++ b/worlds/cv64/__init__.py @@ -37,7 +37,7 @@ class CV64Web(WebWorld): tutorials = [Tutorial( "Multiworld Setup Guide", - "A guide to setting up the Archipleago Castlevania 64 randomizer on your computer and connecting it to a " + "A guide to setting up the Archipelago Castlevania 64 randomizer on your computer and connecting it to a " "multiworld.", "English", "setup_en.md", diff --git a/worlds/cvcotm/__init__.py b/worlds/cvcotm/__init__.py index a2d52b3ecc41..829c73ae8860 100644 --- a/worlds/cvcotm/__init__.py +++ b/worlds/cvcotm/__init__.py @@ -41,7 +41,7 @@ class CVCotMWeb(WebWorld): tutorials = [Tutorial( "Multiworld Setup Guide", - "A guide to setting up the Archipleago Castlevania: Circle of the Moon randomizer on your computer and " + "A guide to setting up the Archipelago Castlevania: Circle of the Moon randomizer on your computer and " "connecting it to a multiworld.", "English", "setup_en.md", From 0020e6c3d324ec1b74ba5a2db92bb2b464efce39 Mon Sep 17 00:00:00 2001 From: JaredWeakStrike <96694163+JaredWeakStrike@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:35:25 -0400 Subject: [PATCH 0656/1218] KH2: Fix html headers to be markdown (#5305) * update setup guide * Update worlds/kh2/docs/setup_en.md Co-authored-by: Fabian Dill * Update worlds/kh2/docs/setup_en.md Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> * Update en_Kingdom Hearts 2.md --------- Co-authored-by: Fabian Dill Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- worlds/kh2/docs/en_Kingdom Hearts 2.md | 24 +++++++++---------- worlds/kh2/docs/setup_en.md | 32 +++++++++++++------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/worlds/kh2/docs/en_Kingdom Hearts 2.md b/worlds/kh2/docs/en_Kingdom Hearts 2.md index 5aae7ad3a70e..6924800e6c6c 100644 --- a/worlds/kh2/docs/en_Kingdom Hearts 2.md +++ b/worlds/kh2/docs/en_Kingdom Hearts 2.md @@ -1,15 +1,15 @@ # Kingdom Hearts 2 -

    Changes from the vanilla game

    +## Changes from the vanilla game This randomizer creates a more dynamic play experience by randomizing the locations of most items in Kingdom Hearts 2. Currently all items within Chests, Popups, Get Bonuses, Form Levels, and Sora's Levels are randomized. This allows abilities that Sora would normally have to be placed on Keyblades with random stats. Additionally, there are several options for ways to finish the game, allowing for different goals beyond beating the final boss. -

    Where is the options page

    +## Where is the options page The [player options page for this game](../player-options) contains all the options you need to configure and export a config file. -

    What is randomized in this game?

    +## What is randomized in this game? - Chests @@ -21,27 +21,27 @@ The [player options page for this game](../player-options) contains all the opti - Keyblade Stats - Keyblade Abilities -

    What Kingdom Hearts 2 items can appear in other players' worlds?

    +## What Kingdom Hearts 2 items can appear in other players' worlds? Every item in the game except for abilities on weapons. -

    What is The Garden of Assemblage "GoA"?

    +## What is The Garden of Assemblage "GoA"? The Garden of Assemblage Mod made by Sonicshadowsilver2 and Num turns the Garden of Assemblage into a “World Hub” where each portal takes you to one of the game worlds (as opposed to having a world map). This allows you to enter worlds at any time, and world progression is maintained for each world individually. -

    What does another world's item look like in Kingdom Hearts 2?

    +## What does another world's item look like in Kingdom Hearts 2? In Kingdom Hearts 2, items which need to be sent to other worlds appear in any location that has a item in the vanilla game. They are represented by the Archipelago icon, and must be "picked up" as if it were a normal item. Upon obtaining the item, it will be sent to its home world. -

    When the player receives an item, what happens?

    +## When the player receives an item, what happens? It is added to your inventory. If you obtain magic, you will need to pause your game to have it show up in your inventory, then enter a new room for it to become properly usable. -

    What Happens if I die before Room Saving?

    +## What Happens if I die before Room Saving? When you die in vanilla Kingdom Hearts 2, you are reverted to the last non-boss room you entered and your status is reverted to what it was at that time. However, in archipelago, any item that you have sent/received will not be taken away from the player, any chest you have opened will remain open, and you will keep your level, but lose the experience. @@ -49,7 +49,7 @@ When you die in vanilla Kingdom Hearts 2, you are reverted to the last non-boss For example, if you are fighting Roxas, receive Reflect Element, then die mid-fight, you will keep that Reflect Element. You will still need to pause your game to have it show up in your inventory, then enter a new room for it to become properly usable. -

    Customization options:

    +## Customization options: - Choose a goal from the list below (with an additional option to Kill Final Xemnas alongside your goal). @@ -64,11 +64,11 @@ For example, if you are fighting Roxas, receive Reflect Element, then die mid-fi - Customize the amount and level of progressive movement (Growth Abilities) you start with. - Customize start inventory, i.e., begin every run with certain items or spells of your choice. -

    What are Lucky Emblems?

    +## What are Lucky Emblems? Lucky Emblems are items that are required to beat the game if your goal is "Lucky Emblem Hunt".
    You can think of these as requiring X number of Proofs of Nonexistence to open the final door. -

    What is Hitlist/Bounties?

    +## What is Hitlist/Bounties? The Hitlist goal adds "bounty" items to select late-game fights and locations, and you need to collect X number of them to win.
    The list of possible locations that can contain a bounty: @@ -82,7 +82,7 @@ The list of possible locations that can contain a bounty: - Transport to Remembrance - Godess of Fate cup and Hades Paradox cup -

    Quality of life:

    +## Quality of life: With the help of Shananas, Num, and ZakTheRobot we have many QoL features such are: diff --git a/worlds/kh2/docs/setup_en.md b/worlds/kh2/docs/setup_en.md index a1248d109584..db0f6c86b920 100644 --- a/worlds/kh2/docs/setup_en.md +++ b/worlds/kh2/docs/setup_en.md @@ -1,11 +1,11 @@ # Kingdom Hearts 2 Archipelago Setup Guide -

    Quick Links

    +## Quick Links - [Game Info Page](../../../../games/Kingdom%20Hearts%202/info/en) - [Player Options Page](../../../../games/Kingdom%20Hearts%202/player-options) -

    Required Software:

    +## Required Software: Kingdom Hearts II Final Mix from the [Epic Games Store](https://store.epicgames.com/en-US/discover/kingdom-hearts) or [Steam](https://store.steampowered.com/app/2552430/KINGDOM_HEARTS_HD_1525_ReMIX/) @@ -23,39 +23,39 @@ Kingdom Hearts II Final Mix from the [Epic Games Store](https://store.epicgames. 1. Optionally Install the Archipelago Quality Of Life mod from `JaredWeakStrike/AP_QOL` using OpenKH Mod Manager 2. Optionally Install the Quality Of Life mod from `shananas/BearSkip` using OpenKH Mod Manager -

    Required: Archipelago Companion Mod

    +### Required: Archipelago Companion Mod Load this mod just like the GoA ROM you did during the KH2 Rando setup. `JaredWeakStrike/APCompanion`
    Have this mod second-highest priority below the .zip seed.
    This mod is based upon Num's Garden of Assemblage Mod and requires it to work. Without Num this could not be possible. -

    Required: Auto Save Mod and KH2 Lua Library

    +### Required: Auto Save Mod and KH2 Lua Library -Load these mods just like you loaded the GoA ROM mod during the KH2 Rando setup. `KH2FM-Mods-equations19/auto-save` and `KH2FM-Mods-equations19/KH2-Lua-Library` Location doesn't matter, required in case of crashes. See [Best Practices](en#best-practices) on how to load the auto save +Load these mods just like you loaded the GoA ROM mod during the KH2 Rando setup. `KH2FM-Mods-equations19/auto-save` and `KH2FM-Mods-equations19/KH2-Lua-Library` Location doesn't matter, required in case of crashes. See [Best Practices](#best-practices) on how to load the auto save -

    Optional QoL Mods: AP QoL and Bear Skip

    +### Optional QoL Mods: AP QoL and Bear Skip `JaredWeakStrike/AP_QOL` Makes the urns minigames much faster, makes Cavern of Remembrance orbs drop significantly more drive orbs for refilling drive/leveling master form, skips the animation when using the bulky vendor RC, skips carpet escape auto-scroller in Agrabah 2, and prevents the wardrobe in the Beasts Castle wardrobe push minigame from waking up while being pushed. `shananas/BearSkip` Skips all minigames in 100 Acre Woods except the Spooky Cave minigame since there are chests in Spooky Cave you can only get during the minigame. For Spooky Cave, Pooh is moved to the other side of the invisible wall that prevents you from using his RC to finish the minigame. -

    Installing A Seed

    +### Installing A Seed When you generate a game you will see a download link for a KH2 .zip seed on the room page. Download the seed then open OpenKH Mod Manager and click the green plus and "Select and install Mod Archive".
    Make sure the seed is on the top of the list (Highest Priority)
    After Installing the seed click "Mod Loader -> Build/Build and Run". Every slot is a unique mod to install and will be needed be repatched for different slots/rooms. -

    Optional Software:

    +## Optional Software: - [Kingdom Hearts 2 AP Tracker](https://github.com/palex00/kh2-ap-tracker/releases/latest/), for use with [PopTracker](https://github.com/black-sliver/PopTracker/releases) -

    What the Mod Manager Should Look Like.

    +## What the Mod Manager Should Look Like. ![image](https://i.imgur.com/N0WJ8Qn.png) -

    Using the KH2 Client

    +## Using the KH2 Client Start the game through OpenKH Mod Manager. If starting a new run, enter the Garden of Assemblage from a new save. If returning to a run, load the save and enter the Garden of Assemblage. Then run the [ArchipelagoKH2Client.exe](https://github.com/ArchipelagoMW/Archipelago/releases).
    When you successfully connect to the server the client will automatically hook into the game to send/receive checks.
    @@ -67,13 +67,13 @@ Most checks will be sent to you anywhere outside a load or cutscene.
    If you obtain magic, you will need to pause your game to have it show up in your inventory, then enter a new room for it to become properly usable. -

    KH2 Client should look like this:

    +## KH2 Client should look like this: ![image](https://i.imgur.com/qP6CmV8.png) Enter The room's port number into the top box where the x's are and press "Connect". Follow the prompts there and you should be connected -

    Common Pitfalls

    +## Common Pitfalls - Having an old GOA Lua Script in your `C:\Users\*YourName*\Documents\KINGDOM HEARTS HD 1.5+2.5 ReMIX\scripts\kh2` folder. - Pressing F2 while in game should look like this. ![image](https://i.imgur.com/ABSdtPC.png) @@ -86,7 +86,7 @@ Enter The room's port number into the top box where the x's are and pres - Using a seed from the standalone KH2 Randomizer Seed Generator. - The Archipelago version of the KH2 Randomizer does not use this Seed Generator; refer to the [Archipelago Setup](https://archipelago.gg/tutorial/Archipelago/setup/en) to learn how to generate and play a seed through Archipelago. -

    Best Practices

    +## Best Practices - Make a save at the start of the GoA before opening anything. This will be the file to select when loading an autosave if/when your game crashes. - If you don't want to have a save in the GoA. Disconnect the client, load the auto save, and then reconnect the client after it loads the auto save. @@ -94,13 +94,13 @@ Enter The room's port number into the top box where the x's are and pres - Run the game in windows/borderless windowed mode. Fullscreen is stable but the game can crash if you alt-tab out. - Make sure to save in a different save slot when playing in an async or disconnecting from the server to play a different seed -

    Logic Sheet & PopTracker Autotracking

    +## Logic Sheet & PopTracker Autotracking Have any questions on what's in logic? This spreadsheet made by Bulcon has the answer [Requirements/logic sheet](https://docs.google.com/spreadsheets/d/1nNi8ohEs1fv-sDQQRaP45o6NoRcMlLJsGckBonweDMY/edit?usp=sharing) Alternatively you can use the Kingdom Hearts 2 PopTracker Pack that is based off of the logic sheet above and does all the work for you. -

    PopTracker Pack

    +### PopTracker Pack 1. Download [Kingdom Hearts 2 AP Tracker](https://github.com/palex00/kh2-ap-tracker/releases/latest/) and [PopTracker](https://github.com/black-sliver/PopTracker/releases). @@ -112,7 +112,7 @@ Alternatively you can use the Kingdom Hearts 2 PopTracker Pack that is based off This pack will handle logic, received items, checked locations and autotabbing for you! -

    F.A.Q.

    +## F.A.Q. - Why is my Client giving me a "Cannot Open Process: " error? - Due to how the client reads kingdom hearts 2 memory some people's computer flags it as a virus. Run the client as admin. From 5110676c76277b3bfddb1dde27c8635d853b2172 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 15 Aug 2025 11:44:24 +0200 Subject: [PATCH 0657/1218] Core: 0.6.4 (#5314) --- Utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utils.py b/Utils.py index b7616b57b125..04c4ac57e921 100644 --- a/Utils.py +++ b/Utils.py @@ -47,7 +47,7 @@ def as_simple_string(self) -> str: return ".".join(str(item) for item in self) -__version__ = "0.6.3" +__version__ = "0.6.4" version_tuple = tuplize_version(__version__) is_linux = sys.platform.startswith("linux") From b85887241f96ccef74a836c494ff24b9bf64cbff Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 15 Aug 2025 10:36:13 +0000 Subject: [PATCH 0658/1218] CI: update appimagetool hash (#5333) --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e886ae8230f9..7151ff00c88e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ env: # NOTE: since appimage/appimagetool and appimage/type2-runtime does not have tags anymore, # we check the sha256 and require manual intervention if it was updated. APPIMAGETOOL_VERSION: continuous - APPIMAGETOOL_X86_64_HASH: '363dafac070b65cc36ca024b74db1f043c6f5cd7be8fca760e190dce0d18d684' + APPIMAGETOOL_X86_64_HASH: '29348a20b80827cd261c28e95172ff828b69d43d4e4e18e3fd069e2c8693c94e' APPIMAGE_RUNTIME_VERSION: continuous APPIMAGE_RUNTIME_X86_64_HASH: 'e70ffa9b69b211574d0917adc482dd66f25a0083427b5945783965d55b0b0a8b' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b7fdd1bcf6b..8c5d87b0ba44 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ env: # NOTE: since appimage/appimagetool and appimage/type2-runtime does not have tags anymore, # we check the sha256 and require manual intervention if it was updated. APPIMAGETOOL_VERSION: continuous - APPIMAGETOOL_X86_64_HASH: '363dafac070b65cc36ca024b74db1f043c6f5cd7be8fca760e190dce0d18d684' + APPIMAGETOOL_X86_64_HASH: '29348a20b80827cd261c28e95172ff828b69d43d4e4e18e3fd069e2c8693c94e' APPIMAGE_RUNTIME_VERSION: continuous APPIMAGE_RUNTIME_X86_64_HASH: 'e70ffa9b69b211574d0917adc482dd66f25a0083427b5945783965d55b0b0a8b' From 8f7fcd4889002b89f0e0d07364a1faaf269a80b6 Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Fri, 15 Aug 2025 05:55:11 -0700 Subject: [PATCH 0659/1218] Zillion: Move `completion_condition` Definition Earlier (#5279) --- worlds/zillion/__init__.py | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/worlds/zillion/__init__.py b/worlds/zillion/__init__.py index 588654d25978..02ef920d8f6c 100644 --- a/worlds/zillion/__init__.py +++ b/worlds/zillion/__init__.py @@ -168,8 +168,8 @@ def generate_early(self) -> None: def create_regions(self) -> None: assert self.zz_system.randomizer, "generate_early hasn't been called" assert self.id_to_zz_item, "generate_early hasn't been called" - p = self.player - logic_cache = ZillionLogicCache(p, self.zz_system.randomizer, self.id_to_zz_item) + player = self.player + logic_cache = ZillionLogicCache(player, self.zz_system.randomizer, self.id_to_zz_item) self.logic_cache = logic_cache w = self.multiworld self.my_locations = [] @@ -192,7 +192,7 @@ def create_regions(self) -> None: all_regions: dict[str, ZillionRegion] = {} for here_zz_name, zz_r in self.zz_system.randomizer.regions.items(): here_name = "Menu" if here_zz_name == "start" else zz_reg_name_to_reg_name(here_zz_name) - all_regions[here_name] = ZillionRegion(zz_r, here_name, here_name, p, w) + all_regions[here_name] = ZillionRegion(zz_r, here_name, here_name, player, w) self.multiworld.regions.append(all_regions[here_name]) limited_skill = Req(gun=3, jump=3, skill=self.zz_system.randomizer.options.skill, hp=940, red=1, floppy=126) @@ -239,7 +239,7 @@ def access_rule_wrapped(zz_loc_local: ZzLocation, for zz_dest in zz_here.connections.keys(): dest_name = "Menu" if zz_dest.name == "start" else zz_reg_name_to_reg_name(zz_dest.name) dest = all_regions[dest_name] - exit_ = Entrance(p, f"{here_name} to {dest_name}", here) + exit_ = Entrance(player, f"{here_name} to {dest_name}", here) here.exits.append(exit_) exit_.connect(dest) @@ -248,6 +248,11 @@ def access_rule_wrapped(zz_loc_local: ZzLocation, if self.options.priority_dead_ends.value: self.options.priority_locations.value |= {loc.name for loc in dead_end_locations} + # main location name is an alias + main_loc_name = self.zz_system.randomizer.loc_name_2_pretty[self.zz_system.randomizer.locations["main"].name] + self.multiworld.get_location(main_loc_name, player).place_locked_item(self.create_item("Win")) + self.multiworld.completion_condition[player] = lambda state: state.has("Win", player) + @override def create_items(self) -> None: if not self.id_to_zz_item: @@ -272,17 +277,6 @@ def create_items(self) -> None: self.logger.debug(f"Zillion Items: {item_name} 1") self.multiworld.itempool.append(self.create_item(item_name)) - @override - def generate_basic(self) -> None: - assert self.zz_system.randomizer, "generate_early hasn't been called" - # main location name is an alias - main_loc_name = self.zz_system.randomizer.loc_name_2_pretty[self.zz_system.randomizer.locations["main"].name] - - self.multiworld.get_location(main_loc_name, self.player)\ - .place_locked_item(self.create_item("Win")) - self.multiworld.completion_condition[self.player] = \ - lambda state: state.has("Win", self.player) - @staticmethod def stage_generate_basic(multiworld: MultiWorld, *args: Any) -> None: # noqa: ANN401 # item link pools are about to be created in main From 9d654b7e3b489d5f1b854dfe24518beb24ba1b8d Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 15 Aug 2025 18:45:40 +0200 Subject: [PATCH 0660/1218] Core: drop Python 3.10 (#5324) Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- .github/pyright-config.json | 2 +- .github/workflows/analyze-modified-files.yml | 2 +- .github/workflows/unittests.yml | 5 ++--- ModuleUpdate.py | 10 +++++----- Utils.py | 2 +- docs/contributing.md | 2 +- docs/running from source.md | 2 +- worlds/generic/docs/mac_en.md | 2 +- 8 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/pyright-config.json b/.github/pyright-config.json index b6561afa4662..64a46d80cceb 100644 --- a/.github/pyright-config.json +++ b/.github/pyright-config.json @@ -29,7 +29,7 @@ "reportMissingImports": true, "reportMissingTypeStubs": true, - "pythonVersion": "3.10", + "pythonVersion": "3.11", "pythonPlatform": "Windows", "executionEnvironments": [ diff --git a/.github/workflows/analyze-modified-files.yml b/.github/workflows/analyze-modified-files.yml index 6788abd30a1c..862a050c517e 100644 --- a/.github/workflows/analyze-modified-files.yml +++ b/.github/workflows/analyze-modified-files.yml @@ -53,7 +53,7 @@ jobs: - uses: actions/setup-python@v5 if: env.diff != '' with: - python-version: '3.10' + python-version: '3.11' - name: "Install dependencies" if: env.diff != '' diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index 2d83c649e852..96219daa1973 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -39,11 +39,10 @@ jobs: matrix: os: [ubuntu-latest] python: - - {version: '3.10'} - - {version: '3.11'} + - {version: '3.11.2'} # Change to '3.11' around 2026-06-10 - {version: '3.12'} include: - - python: {version: '3.10'} # old compat + - python: {version: '3.11'} # old compat os: windows-latest - python: {version: '3.12'} # current os: windows-latest diff --git a/ModuleUpdate.py b/ModuleUpdate.py index 2e58c4f7f93b..46064d3f9215 100644 --- a/ModuleUpdate.py +++ b/ModuleUpdate.py @@ -5,15 +5,15 @@ import warnings -if sys.platform in ("win32", "darwin") and sys.version_info < (3, 10, 11): +if sys.platform in ("win32", "darwin") and sys.version_info < (3, 11, 9): # Official micro version updates. This should match the number in docs/running from source.md. - raise RuntimeError(f"Incompatible Python Version found: {sys.version_info}. Official 3.10.15+ is supported.") -elif sys.platform in ("win32", "darwin") and sys.version_info < (3, 10, 15): + raise RuntimeError(f"Incompatible Python Version found: {sys.version_info}. Official 3.11.9+ is supported.") +elif sys.platform in ("win32", "darwin") and sys.version_info < (3, 11, 13): # There are known security issues, but no easy way to install fixed versions on Windows for testing. warnings.warn(f"Python Version {sys.version_info} has security issues. Don't use in production.") -elif sys.version_info < (3, 10, 1): +elif sys.version_info < (3, 11, 0): # Other platforms may get security backports instead of micro updates, so the number is unreliable. - raise RuntimeError(f"Incompatible Python Version found: {sys.version_info}. 3.10.1+ is supported.") + raise RuntimeError(f"Incompatible Python Version found: {sys.version_info}. 3.11.0+ is supported.") # don't run update if environment is frozen/compiled or if not the parent process (skip in subprocess) _skip_update = bool( diff --git a/Utils.py b/Utils.py index 04c4ac57e921..fc8dd7264c75 100644 --- a/Utils.py +++ b/Utils.py @@ -900,7 +900,7 @@ def async_start(co: Coroutine[None, None, typing.Any], name: Optional[str] = Non Use this to start a task when you don't keep a reference to it or immediately await it, to prevent early garbage collection. "fire-and-forget" """ - # https://docs.python.org/3.10/library/asyncio-task.html#asyncio.create_task + # https://docs.python.org/3.11/library/asyncio-task.html#asyncio.create_task # Python docs: # ``` # Important: Save a reference to the result of [asyncio.create_task], diff --git a/docs/contributing.md b/docs/contributing.md index 96fc316be82c..06d83bebbc5a 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -16,7 +16,7 @@ game contributions: * **Do not introduce unit test failures/regressions.** Archipelago supports multiple versions of Python. You may need to download older Python versions to fully test your changes. Currently, the oldest supported version - is [Python 3.10](https://www.python.org/downloads/release/python-31015/). + is [Python 3.11](https://www.python.org/downloads/release/python-31113/). It is recommended that automated github actions are turned on in your fork to have github run unit tests after pushing. You can turn them on here: diff --git a/docs/running from source.md b/docs/running from source.md index 8e8b4f4b61c3..36bff8c8faba 100644 --- a/docs/running from source.md +++ b/docs/running from source.md @@ -7,7 +7,7 @@ use that version. These steps are for developers or platforms without compiled r ## General What you'll need: - * [Python 3.10.11 or newer](https://www.python.org/downloads/), not the Windows Store version + * [Python 3.11.9 or newer](https://www.python.org/downloads/), not the Windows Store version * On Windows, please consider only using the latest supported version in production environments since security updates for older versions are not easily available. * Python 3.12.x is currently the newest supported version diff --git a/worlds/generic/docs/mac_en.md b/worlds/generic/docs/mac_en.md index 38fd3cd9404a..72f7d1a8b58b 100644 --- a/worlds/generic/docs/mac_en.md +++ b/worlds/generic/docs/mac_en.md @@ -2,7 +2,7 @@ Archipelago does not have a compiled release on macOS. However, it is possible to run from source code on macOS. This guide expects you to have some experience with running software from the terminal. ## Prerequisite Software Here is a list of software to install and source code to download. -1. Python 3.10 "universal2" or newer from the [macOS Python downloads page](https://www.python.org/downloads/macos/). +1. Python 3.11 "universal2" or newer from the [macOS Python downloads page](https://www.python.org/downloads/macos/). **Python 3.13 is not supported yet.** 2. Xcode from the [macOS App Store](https://apps.apple.com/us/app/xcode/id497799835). 3. The source code from the [Archipelago releases page](https://github.com/ArchipelagoMW/Archipelago/releases). From eb09be35947002edf3c83d5b02736fa652cc7eef Mon Sep 17 00:00:00 2001 From: Faris <162540354+FarisTheAncient@users.noreply.github.com> Date: Sat, 16 Aug 2025 16:08:44 -0500 Subject: [PATCH 0661/1218] OSRS: Fix UT Integration and Various Gen Failures (#5331) --- worlds/osrs/Locations.py | 2 + worlds/osrs/LogicCSV/LogicCSVToPython.py | 2 +- worlds/osrs/LogicCSV/locations_generated.py | 2 +- worlds/osrs/Options.py | 2 +- worlds/osrs/Rules.py | 2 + worlds/osrs/__init__.py | 94 ++++++++++++++------- 6 files changed, 69 insertions(+), 35 deletions(-) diff --git a/worlds/osrs/Locations.py b/worlds/osrs/Locations.py index b5827d60f2fe..324da86be48f 100644 --- a/worlds/osrs/Locations.py +++ b/worlds/osrs/Locations.py @@ -3,6 +3,8 @@ from BaseClasses import Location +task_types = ["prayer", "magic", "runecraft", "mining", "crafting", "smithing", "fishing", "cooking", "firemaking", "woodcutting", "combat"] + class SkillRequirement(typing.NamedTuple): skill: str level: int diff --git a/worlds/osrs/LogicCSV/LogicCSVToPython.py b/worlds/osrs/LogicCSV/LogicCSVToPython.py index b66f53cc9db5..082bda7a0875 100644 --- a/worlds/osrs/LogicCSV/LogicCSVToPython.py +++ b/worlds/osrs/LogicCSV/LogicCSVToPython.py @@ -8,7 +8,7 @@ # The CSVs are updated at this repository to be shared between generator and client. data_repository_address = "https://raw.githubusercontent.com/digiholic/osrs-archipelago-logic/" # The Github tag of the CSVs this was generated with -data_csv_tag = "v2.0.4" +data_csv_tag = "v2.0.5" # If true, generate using file names in the repository debug = False diff --git a/worlds/osrs/LogicCSV/locations_generated.py b/worlds/osrs/LogicCSV/locations_generated.py index 4c1cd0bdd893..03156b1c71e8 100644 --- a/worlds/osrs/LogicCSV/locations_generated.py +++ b/worlds/osrs/LogicCSV/locations_generated.py @@ -77,7 +77,7 @@ LocationRow('Bake a Redberry Pie', 'cooking', ['Redberry Bush', 'Wheat', 'Windmill', 'Pie Dish', ], [SkillRequirement('Cooking', 10), ], [], 0), LocationRow('Cook some Stew', 'cooking', ['Bowl', 'Meat', 'Potato', ], [SkillRequirement('Cooking', 25), ], [], 0), LocationRow('Bake an Apple Pie', 'cooking', ['Cooking Apple', 'Wheat', 'Windmill', 'Pie Dish', ], [SkillRequirement('Cooking', 32), ], [], 2), - LocationRow('Enter the Cook\'s Guild', 'cooking', ['Cook\'s Guild', ], [], [], 0), + LocationRow('Enter the Cook\'s Guild', 'cooking', ['Cook\'s Guild', ], [SkillRequirement('Cooking', 32), ], [], 0), LocationRow('Bake a Cake', 'cooking', ['Wheat', 'Windmill', 'Egg', 'Milk', 'Cake Tin', ], [SkillRequirement('Cooking', 40), ], [], 6), LocationRow('Bake a Meat Pizza', 'cooking', ['Wheat', 'Windmill', 'Cheese', 'Tomato', 'Meat', ], [SkillRequirement('Cooking', 45), ], [], 8), LocationRow('Burn a Log', 'firemaking', [], [SkillRequirement('Firemaking', 1), SkillRequirement('Woodcutting', 1), ], [], 0), diff --git a/worlds/osrs/Options.py b/worlds/osrs/Options.py index 55a040b0950e..cf0754a3c2aa 100644 --- a/worlds/osrs/Options.py +++ b/worlds/osrs/Options.py @@ -2,7 +2,7 @@ from Options import Choice, Toggle, Range, PerGameCommonOptions -MAX_COMBAT_TASKS = 16 +MAX_COMBAT_TASKS = 17 MAX_PRAYER_TASKS = 5 MAX_MAGIC_TASKS = 7 diff --git a/worlds/osrs/Rules.py b/worlds/osrs/Rules.py index 7fd770f0f7a7..1cdaabe3e2dd 100644 --- a/worlds/osrs/Rules.py +++ b/worlds/osrs/Rules.py @@ -190,6 +190,8 @@ def get_firemaking_skill_rule(level, player, options) -> CollectionRule: def get_skill_rule(skill, level, player, options) -> CollectionRule: + if level <= 1: + return lambda state: True if skill.lower() == "fishing": return get_fishing_skill_rule(level, player, options) if skill.lower() == "mining": diff --git a/worlds/osrs/__init__.py b/worlds/osrs/__init__.py index a54e272d05fb..e0587daff35e 100644 --- a/worlds/osrs/__init__.py +++ b/worlds/osrs/__init__.py @@ -1,11 +1,11 @@ import typing -from BaseClasses import Item, Tutorial, ItemClassification, Region, MultiWorld, CollectionState -from Fill import fill_restrictive, FillError +from BaseClasses import Item, Tutorial, ItemClassification, Region, MultiWorld from worlds.AutoWorld import WebWorld, World +from Options import OptionError from .Items import OSRSItem, starting_area_dict, chunksanity_starting_chunks, QP_Items, ItemRow, \ chunksanity_special_region_names -from .Locations import OSRSLocation, LocationRow +from .Locations import OSRSLocation, LocationRow, task_types from .Rules import * from .Options import OSRSOptions, StartingArea from .Names import LocationNames, ItemNames, RegionNames @@ -47,6 +47,7 @@ class OSRSWorld(World): base_id = 0x070000 data_version = 1 explicit_indirect_conditions = False + ut_can_gen_without_yaml = True item_name_to_id = {item_rows[i].name: 0x070000 + i for i in range(len(item_rows))} location_name_to_id = {location_rows[i].name: 0x070000 + i for i in range(len(location_rows))} @@ -105,6 +106,18 @@ def generate_early(self) -> None: # Set Starting Chunk self.multiworld.push_precollected(self.create_item(self.starting_area_item)) + elif hasattr(self.multiworld,"re_gen_passthrough") and self.game in self.multiworld.re_gen_passthrough: + re_gen_passthrough = self.multiworld.re_gen_passthrough[self.game] # UT passthrough + if "starting_area" in re_gen_passthrough: + self.starting_area_item = re_gen_passthrough["starting_area"] + for task_type in task_types: + if f"max_{task_type}_level" in re_gen_passthrough: + getattr(self.options,f"max_{task_type}_level").value = re_gen_passthrough[f"max_{task_type}_level"] + max_count = getattr(self.options,f"max_{task_type}_tasks") + max_count.value = max_count.range_end + self.options.brutal_grinds.value = re_gen_passthrough["brutal_grinds"] + + """ This function pulls from LogicCSVToPython so that it sends the correct tag of the repository to the client. @@ -115,20 +128,13 @@ def fill_slot_data(self): data = self.options.as_dict("brutal_grinds") data["data_csv_tag"] = data_csv_tag data["starting_area"] = str(self.starting_area_item) #these aren't actually strings, they just play them on tv + for task_type in task_types: + data[f"max_{task_type}_level"] = getattr(self.options,f"max_{task_type}_level").value return data - def interpret_slot_data(self, slot_data: typing.Dict[str, typing.Any]) -> None: - if "starting_area" in slot_data: - self.starting_area_item = slot_data["starting_area"] - menu_region = self.multiworld.get_region("Menu",self.player) - menu_region.exits.clear() #prevent making extra exits if players just reconnect to a differnet slot - if self.starting_area_item in chunksanity_special_region_names: - starting_area_region = chunksanity_special_region_names[self.starting_area_item] - else: - starting_area_region = self.starting_area_item[6:] # len("Area: ") - starting_entrance = menu_region.create_exit(f"Start->{starting_area_region}") - starting_entrance.access_rule = lambda state: state.has(self.starting_area_item, self.player) - starting_entrance.connect(self.region_name_to_data[starting_area_region]) + @staticmethod + def interpret_slot_data(slot_data: typing.Dict[str, typing.Any]) -> typing.Dict[str, typing.Any]: + return slot_data def create_regions(self) -> None: """ @@ -195,6 +201,8 @@ def roll_locations(self): generation_is_fake = hasattr(self.multiworld, "generation_is_fake") # UT specific override locations_required = 0 for item_row in item_rows: + if item_row.name == self.starting_area_item: + continue #skip starting area # If it's a filler item, set it aside for later if item_row.progression == ItemClassification.filler: continue @@ -206,15 +214,18 @@ def roll_locations(self): locations_required += item_row.amount if self.options.enable_duds: locations_required += self.options.dud_count - locations_added = 1 # At this point we've already added the starting area, so we start at 1 instead of 0 - + locations_added = 0 # Keep track of the number of locations we add so we don't add more the number of items we're going to make # Quests are always added first, before anything else is rolled for i, location_row in enumerate(location_rows): - if location_row.category in {"quest", "points", "goal"}: + if location_row.category in {"quest"}: if self.task_within_skill_levels(location_row.skills): self.create_and_add_location(i) - if location_row.category == "quest": - locations_added += 1 + locations_added += 1 + elif location_row.category in {"goal"}: + if not self.task_within_skill_levels(location_row.skills): + raise OptionError(f"Goal location for {self.player_name} not allowed in skill levels") #it doesn't actually have any, but just in case for future + self.create_and_add_location(i) + # Build up the weighted Task Pool rnd = self.random @@ -225,18 +236,28 @@ def roll_locations(self): rnd.shuffle(general_tasks) else: general_tasks.reverse() - for i in range(self.options.minimum_general_tasks): + general_tasks_added = 0 + while general_tasks_added0: task = general_tasks.pop() - self.add_location(task) - locations_added += 1 + if self.task_within_skill_levels(task.skills): + self.add_location(task) + locations_added += 1 + general_tasks_added += 1 + if general_tasks_added < self.options.minimum_general_tasks: + raise OptionError(f"{self.plyaer_name} doesn't have enough general tasks to create required minimum count"+ + f", raise maximum skill levels or lower minimum general tasks") - general_weight = self.options.general_task_weight if len(general_tasks) > 0 else 0 + general_weight = self.options.general_task_weight.value if len(general_tasks) > 0 else 0 tasks_per_task_type: typing.Dict[str, typing.List[LocationRow]] = {} weights_per_task_type: typing.Dict[str, int] = {} - - task_types = ["prayer", "magic", "runecraft", "mining", "crafting", - "smithing", "fishing", "cooking", "firemaking", "woodcutting", "combat"] + for task_type in task_types: max_amount_for_task_type = getattr(self.options, f"max_{task_type}_tasks") tasks_for_this_type = [task for task in self.locations_by_category[task_type] @@ -263,10 +284,13 @@ def roll_locations(self): all_weights.append(weights_per_task_type[task_type]) # Even after the initial forced generals, they can still be rolled randomly - if general_weight > 0: + if general_weight > 0 and len(general_tasks)>0: all_tasks.append(general_tasks) all_weights.append(general_weight) + if not generation_is_fake and locations_added > locations_required: #due to minimum general tasks we already have more than needed + raise OptionError(f"Too many locations created for {self.player_name}, lower the minimum general tasks") + while locations_added < locations_required or (generation_is_fake and len(all_tasks) > 0): if all_tasks: chosen_task = rnd.choices(all_tasks, all_weights)[0] @@ -282,9 +306,9 @@ def roll_locations(self): del all_tasks[index] del all_weights[index] - else: + else: # We can ignore general tasks in UT because they will have been cleared already if len(general_tasks) == 0: - raise Exception(f"There are not enough available tasks to fill the remaining pool for OSRS " + + raise OptionError(f"There are not enough available tasks to fill the remaining pool for OSRS " + f"Please adjust {self.player_name}'s settings to be less restrictive of tasks.") task = general_tasks.pop() self.add_location(task) @@ -296,7 +320,7 @@ def add_location(self, location): self.create_and_add_location(index) def create_items(self) -> None: - filler_items = [] + filler_items:list[ItemRow] = [] for item_row in item_rows: if item_row.name != self.starting_area_item: # If it's a filler item, set it aside for later @@ -321,7 +345,7 @@ def create_items(self) -> None: def get_filler_item_name(self) -> str: if self.options.enable_duds: - return self.random.choice([item for item in item_rows if item.progression == ItemClassification.filler]) + return self.random.choice([item.name for item in item_rows if item.progression == ItemClassification.filler]) else: return self.random.choice([ItemNames.Progressive_Weapons, ItemNames.Progressive_Magic, ItemNames.Progressive_Range_Weapon, ItemNames.Progressive_Armor, @@ -388,6 +412,12 @@ def set_rules(self) -> None: # Set the access rule for the QP Location add_rule(qp_loc, lambda state, loc=q_loc: (loc.can_reach(state))) + qp = 0 + for qp_event in self.available_QP_locations: + qp += int(qp_event[0]) + if qp < self.location_rows_by_name[LocationNames.Q_Dragon_Slayer].qp: + raise OptionError(f"{self.player_name} doesn't have enough quests for reach goal, increase maximum skill levels") + # place "Victory" at "Dragon Slayer" and set collection as win condition self.multiworld.get_location(LocationNames.Q_Dragon_Slayer, self.player) \ .place_locked_item(self.create_event("Victory")) From 6f7ca082f22b350c9fc7dfea3e6357635c2da60b Mon Sep 17 00:00:00 2001 From: Flit <8645405+FlitPix@users.noreply.github.com> Date: Sun, 17 Aug 2025 14:47:01 -0400 Subject: [PATCH 0662/1218] Docker: use python:3.12-slim-bookworm (#5343) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 9e3c5f0d712a..294767beb24b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,7 @@ COPY intset.h . RUN cythonize -b -i _speedups.pyx # Archipelago -FROM python:3.12-slim AS archipelago +FROM python:3.12-slim-bookworm AS archipelago ARG TARGETARCH ENV VIRTUAL_ENV=/opt/venv ENV PYTHONUNBUFFERED=1 From 6ba2b7f8c36e3f2945223183d99c043f0069a8c9 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Sun, 17 Aug 2025 19:46:48 -0500 Subject: [PATCH 0663/1218] Tests: implement pattern for filtering unittests locally (#5080) --- test/worlds/__init__.py | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/test/worlds/__init__.py b/test/worlds/__init__.py index 4bc017511c66..4a4e3e07c15c 100644 --- a/test/worlds/__init__.py +++ b/test/worlds/__init__.py @@ -1,17 +1,46 @@ -def load_tests(loader, standard_tests, pattern): +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from unittest import TestLoader, TestSuite + + +def load_tests(loader: "TestLoader", standard_tests: "TestSuite", pattern: str): import os import unittest + import fnmatch from .. import file_path from worlds.AutoWorld import AutoWorldRegister suite = unittest.TestSuite() suite.addTests(standard_tests) + + # pattern hack + # all tests from within __init__ are always imported, so we need to filter out the folder earlier + # if the pattern isn't matching a specific world, we don't have much of a solution + + if pattern.startswith("worlds."): + if pattern.endswith(".py"): + pattern = pattern[:-3] + components = pattern.split(".") + world_glob = f"worlds.{components[1]}" + pattern = components[-1] + + elif pattern.startswith(f"worlds{os.path.sep}") or pattern.startswith(f"worlds{os.path.altsep}"): + components = pattern.split(os.path.sep) + if len(components) == 1: + components = pattern.split(os.path.altsep) + world_glob = f"worlds.{components[1]}" + pattern = components[-1] + else: + world_glob = "*" + + folders = [os.path.join(os.path.split(world.__file__)[0], "test") - for world in AutoWorldRegister.world_types.values()] + for world in AutoWorldRegister.world_types.values() + if fnmatch.fnmatch(world.__module__, world_glob)] all_tests = [ test_case for folder in folders if os.path.exists(folder) - for test_collection in loader.discover(folder, top_level_dir=file_path) + for test_collection in loader.discover(folder, top_level_dir=file_path, pattern=pattern) for test_suite in test_collection if isinstance(test_suite, unittest.suite.TestSuite) for test_case in test_suite ] From 9a64b8c5cecc91efbbda7cb300bfad0cca296552 Mon Sep 17 00:00:00 2001 From: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> Date: Sun, 17 Aug 2025 20:48:56 -0400 Subject: [PATCH 0664/1218] Webhost: Remove showdown.js Remnants (#4984) --- WebHostLib/static/styles/markdown.css | 6 ------ 1 file changed, 6 deletions(-) diff --git a/WebHostLib/static/styles/markdown.css b/WebHostLib/static/styles/markdown.css index 5ead2c60f791..ac06dea59d13 100644 --- a/WebHostLib/static/styles/markdown.css +++ b/WebHostLib/static/styles/markdown.css @@ -28,7 +28,6 @@ font-weight: normal; font-family: LondrinaSolid-Regular, sans-serif; text-transform: uppercase; - cursor: pointer; /* TODO: remove once we drop showdown.js */ width: 100%; text-shadow: 1px 1px 4px #000000; } @@ -37,7 +36,6 @@ font-size: 38px; font-weight: normal; font-family: LondrinaSolid-Light, sans-serif; - cursor: pointer; /* TODO: remove once we drop showdown.js */ width: 100%; margin-top: 20px; margin-bottom: 0.5rem; @@ -50,7 +48,6 @@ font-family: LexendDeca-Regular, sans-serif; text-transform: none; text-align: left; - cursor: pointer; /* TODO: remove once we drop showdown.js */ width: 100%; margin-bottom: 0.5rem; } @@ -59,7 +56,6 @@ font-family: LexendDeca-Regular, sans-serif; text-transform: none; font-size: 24px; - cursor: pointer; /* TODO: remove once we drop showdown.js */ margin-bottom: 24px; } @@ -67,14 +63,12 @@ font-family: LexendDeca-Regular, sans-serif; text-transform: none; font-size: 22px; - cursor: pointer; /* TODO: remove once we drop showdown.js */ } .markdown h6, .markdown details summary.h6{ font-family: LexendDeca-Regular, sans-serif; text-transform: none; font-size: 20px; - cursor: pointer; /* TODO: remove once we drop showdown.js */ } .markdown h4, .markdown h5, .markdown h6{ From 48906de8733d9a498484810c89a38f0865ec28d7 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Tue, 19 Aug 2025 12:08:39 -0400 Subject: [PATCH 0665/1218] Jak and Daxter: fix checks getting lost if player disconnects. (#5280) --- worlds/jakanddaxter/client.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/worlds/jakanddaxter/client.py b/worlds/jakanddaxter/client.py index 90e6a42aa7e3..fa2aea5495ef 100644 --- a/worlds/jakanddaxter/client.py +++ b/worlds/jakanddaxter/client.py @@ -135,6 +135,10 @@ async def server_auth(self, password_requested: bool = False): self.tags = set() await self.send_connect() + async def disconnect(self, allow_autoreconnect: bool = False): + self.locations_checked = set() # Clear this set to gracefully handle server disconnects. + await super(JakAndDaxterContext, self).disconnect(allow_autoreconnect) + def on_package(self, cmd: str, args: dict): if cmd == "RoomInfo": @@ -177,6 +181,10 @@ async def get_orb_balance(): create_task_log_exception(get_orb_balance()) + # If there were any locations checked while the client wasn't connected, we want to make sure the server + # knows about them. To do that, replay the whole location_outbox (no duplicates will be sent). + self.memr.outbox_index = 0 + # Tell the server if Deathlink is enabled or disabled in the in-game options. # This allows us to "remember" the user's choice. self.on_deathlink_toggle() @@ -254,6 +262,7 @@ def on_deathlink(self, data: dict): # We don't need an ap_inform function because check_locations solves that need. def on_location_check(self, location_ids: list[int]): + self.locations_checked.update(location_ids) # Populate this set to gracefully handle server disconnects. create_task_log_exception(self.check_locations(location_ids)) # CommonClient has no finished_game function, so we will have to craft our own. TODO - Update if that changes. From 16d5b453a79c7ef869e20c1e27b3cf4192b037b3 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Tue, 19 Aug 2025 17:35:50 +0000 Subject: [PATCH 0666/1218] Core: require setuptools>=75 (#5346) Setuptools 70.3.0 seems to not work for us. --- Dockerfile | 2 +- ModuleUpdate.py | 4 ++-- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 294767beb24b..363478988c96 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,7 +28,7 @@ COPY requirements.txt WebHostLib/requirements.txt RUN pip install --no-cache-dir -r \ WebHostLib/requirements.txt \ - "setuptools<81" + "setuptools>=75,<81" COPY _speedups.pyx . COPY intset.h . diff --git a/ModuleUpdate.py b/ModuleUpdate.py index 46064d3f9215..db42f8e5abcb 100644 --- a/ModuleUpdate.py +++ b/ModuleUpdate.py @@ -74,11 +74,11 @@ def update_command(): def install_pkg_resources(yes=False): try: import pkg_resources # noqa: F401 - except ImportError: + except (AttributeError, ImportError): check_pip() if not yes: confirm("pkg_resources not found, press enter to install it") - subprocess.call([sys.executable, "-m", "pip", "install", "--upgrade", "setuptools<81"]) + subprocess.call([sys.executable, "-m", "pip", "install", "--upgrade", "setuptools>=75,<81"]) def update(yes: bool = False, force: bool = False) -> None: diff --git a/setup.py b/setup.py index 1808b22c62d0..01342e4ece61 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,7 @@ install_cx_freeze = False except pkg_resources.ResolutionError: install_cx_freeze = True -except ImportError: +except (AttributeError, ImportError): install_cx_freeze = True pkg_resources = None # type: ignore[assignment] From bead81b64b067c03489c135b326cba1aa5772443 Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Wed, 20 Aug 2025 23:46:06 -0600 Subject: [PATCH 0667/1218] Core: Fix get_unique_identifier failing on missing cache folder (#5322) --- Utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Utils.py b/Utils.py index fc8dd7264c75..5a24bc157eca 100644 --- a/Utils.py +++ b/Utils.py @@ -414,11 +414,11 @@ def get_adjuster_settings(game_name: str) -> Namespace: @cache_argsless def get_unique_identifier(): common_path = cache_path("common.json") - if os.path.exists(common_path): + try: with open(common_path) as f: common_file = json.load(f) uuid = common_file.get("uuid", None) - else: + except FileNotFoundError: common_file = {} uuid = None @@ -428,6 +428,9 @@ def get_unique_identifier(): from uuid import uuid4 uuid = str(uuid4()) common_file["uuid"] = uuid + + cache_folder = os.path.dirname(common_path) + os.makedirs(cache_folder, exist_ok=True) with open(common_path, "w") as f: json.dump(common_file, f, separators=(",", ":")) return uuid From 88a4a589a0ae4f3f38e6de35772d7bdc3c61a761 Mon Sep 17 00:00:00 2001 From: Aaron Wagener Date: Sat, 23 Aug 2025 01:33:46 -0500 Subject: [PATCH 0668/1218] WebHost: add a tracker api endpoint (#1052) An endpoint from the tracker page. --- WebHostLib/api/__init__.py | 4 +- WebHostLib/api/tracker.py | 230 +++++++++++++++++++++++++++++++++++++ docs/webhost api.md | 210 +++++++++++++++++++++++++++++++++ 3 files changed, 442 insertions(+), 2 deletions(-) create mode 100644 WebHostLib/api/tracker.py diff --git a/WebHostLib/api/__init__.py b/WebHostLib/api/__init__.py index d0b9d05c16b8..54eb5c1de151 100644 --- a/WebHostLib/api/__init__.py +++ b/WebHostLib/api/__init__.py @@ -11,5 +11,5 @@ def get_players(seed: Seed) -> List[Tuple[str, str]]: return [(slot.player_name, slot.game) for slot in seed.slots.order_by(Slot.player_id)] - -from . import datapackage, generate, room, user # trigger registration +# trigger endpoint registration +from . import datapackage, generate, room, tracker, user diff --git a/WebHostLib/api/tracker.py b/WebHostLib/api/tracker.py new file mode 100644 index 000000000000..abf4cdbe1ba5 --- /dev/null +++ b/WebHostLib/api/tracker.py @@ -0,0 +1,230 @@ +from datetime import datetime, timezone +from typing import Any, TypedDict +from uuid import UUID + +from flask import abort + +from NetUtils import ClientStatus, Hint, NetworkItem, SlotType +from WebHostLib import cache +from WebHostLib.api import api_endpoints +from WebHostLib.models import Room +from WebHostLib.tracker import TrackerData + + +@api_endpoints.route("/tracker/") +@cache.memoize(timeout=60) +def tracker_data(tracker: UUID) -> dict[str, Any]: + """ + Outputs json data to /api/tracker/. + + :param tracker: UUID of current session tracker. + + :return: Tracking data for all players in the room. Typing and docstrings describe the format of each value. + """ + room: Room | None = Room.get(tracker=tracker) + if not room: + abort(404) + + tracker_data = TrackerData(room) + + all_players: dict[int, list[int]] = tracker_data.get_all_players() + + class PlayerAlias(TypedDict): + player: int + name: str | None + + player_aliases: list[dict[str, int | list[PlayerAlias]]] = [] + """Slot aliases of all players.""" + for team, players in all_players.items(): + team_player_aliases: list[PlayerAlias] = [] + team_aliases = {"team": team, "players": team_player_aliases} + player_aliases.append(team_aliases) + for player in players: + team_player_aliases.append({"player": player, "alias": tracker_data.get_player_alias(team, player)}) + + class PlayerItemsReceived(TypedDict): + player: int + items: list[NetworkItem] + + player_items_received: list[dict[str, int | list[PlayerItemsReceived]]] = [] + """Items received by each player.""" + for team, players in all_players.items(): + player_received_items: list[PlayerItemsReceived] = [] + team_items_received = {"team": team, "players": player_received_items} + player_items_received.append(team_items_received) + for player in players: + player_received_items.append( + {"player": player, "items": tracker_data.get_player_received_items(team, player)}) + + class PlayerChecksDone(TypedDict): + player: int + locations: list[int] + + player_checks_done: list[dict[str, int | list[PlayerChecksDone]]] = [] + """ID of all locations checked by each player.""" + for team, players in all_players.items(): + per_player_checks: list[PlayerChecksDone] = [] + team_checks_done = {"team": team, "players": per_player_checks} + player_checks_done.append(team_checks_done) + for player in players: + per_player_checks.append( + {"player": player, "locations": sorted(tracker_data.get_player_checked_locations(team, player))}) + + total_checks_done: list[dict[str, int]] = [ + {"team": team, "checks_done": checks_done} + for team, checks_done in tracker_data.get_team_locations_checked_count().items() + ] + """Total number of locations checked for the entire multiworld per team.""" + + class PlayerHints(TypedDict): + player: int + hints: list[Hint] + + hints: list[dict[str, int | list[PlayerHints]]] = [] + """Hints that all players have used or received.""" + for team, players in tracker_data.get_all_slots().items(): + per_player_hints: list[PlayerHints] = [] + team_hints = {"team": team, "players": per_player_hints} + hints.append(team_hints) + for player in players: + player_hints = sorted(tracker_data.get_player_hints(team, player)) + per_player_hints.append({"player": player, "hints": player_hints}) + slot_info = tracker_data.get_slot_info(team, player) + # this assumes groups are always after players + if slot_info.type != SlotType.group: + continue + for member in slot_info.group_members: + team_hints[member]["hints"] += player_hints + + class PlayerTimer(TypedDict): + player: int + time: datetime | None + + activity_timers: list[dict[str, int | list[PlayerTimer]]] = [] + """Time of last activity per player. Returned as RFC 1123 format and null if no connection has been made.""" + for team, players in all_players.items(): + player_timers: list[PlayerTimer] = [] + team_timers = {"team": team, "players": player_timers} + activity_timers.append(team_timers) + for player in players: + player_timers.append({"player": player, "time": None}) + + client_activity_timers: tuple[tuple[int, int], float] = tracker_data._multisave.get("client_activity_timers", ()) + for (team, player), timestamp in client_activity_timers: + # use index since we can rely on order + activity_timers[team]["player_timers"][player - 1]["time"] = datetime.fromtimestamp(timestamp, timezone.utc) + + connection_timers: list[dict[str, int | list[PlayerTimer]]] = [] + """Time of last connection per player. Returned as RFC 1123 format and null if no connection has been made.""" + for team, players in all_players.items(): + player_timers: list[PlayerTimer] = [] + team_connection_timers = {"team": team, "players": player_timers} + connection_timers.append(team_connection_timers) + for player in players: + player_timers.append({"player": player, "time": None}) + + client_connection_timers: tuple[tuple[int, int], float] = tracker_data._multisave.get( + "client_connection_timers", ()) + for (team, player), timestamp in client_connection_timers: + connection_timers[team]["players"][player - 1]["time"] = datetime.fromtimestamp(timestamp, timezone.utc) + + class PlayerStatus(TypedDict): + player: int + status: ClientStatus + + player_status: list[dict[str, int | list[PlayerStatus]]] = [] + """The current client status for each player.""" + for team, players in all_players.items(): + player_statuses: list[PlayerStatus] = [] + team_status = {"team": team, "players": player_statuses} + player_status.append(team_status) + for player in players: + player_statuses.append({"player": player, "status": tracker_data.get_player_client_status(team, player)}) + + return { + **get_static_tracker_data(room), + "aliases": player_aliases, + "player_items_received": player_items_received, + "player_checks_done": player_checks_done, + "total_checks_done": total_checks_done, + "hints": hints, + "activity_timers": activity_timers, + "connection_timers": connection_timers, + "player_status": player_status, + "datapackage": tracker_data._multidata["datapackage"], + } + +@cache.memoize() +def get_static_tracker_data(room: Room) -> dict[str, Any]: + """ + Builds and caches the static data for this active session tracker, so that it doesn't need to be recalculated. + """ + + tracker_data = TrackerData(room) + + all_players: dict[int, list[int]] = tracker_data.get_all_players() + + class PlayerGroups(TypedDict): + slot: int + name: str + members: list[int] + + groups: list[dict[str, int | list[PlayerGroups]]] = [] + """The Slot ID of groups and the IDs of the group's members.""" + for team, players in tracker_data.get_all_slots().items(): + groups_in_team: list[PlayerGroups] = [] + team_groups = {"team": team, "groups": groups_in_team} + groups.append(team_groups) + for player in players: + slot_info = tracker_data.get_slot_info(team, player) + if slot_info.type != SlotType.group or not slot_info.group_members: + continue + groups_in_team.append( + { + "slot": player, + "name": slot_info.name, + "members": list(slot_info.group_members), + }) + class PlayerName(TypedDict): + player: int + name: str + + player_names: list[dict[str, str | list[PlayerName]]] = [] + """Slot names of all players.""" + for team, players in all_players.items(): + per_team_player_names: list[PlayerName] = [] + team_names = {"team": team, "players": per_team_player_names} + player_names.append(team_names) + for player in players: + per_team_player_names.append({"player": player, "name": tracker_data.get_player_name(team, player)}) + + class PlayerGame(TypedDict): + player: int + game: str + + games: list[dict[str, int | list[PlayerGame]]] = [] + """The game each player is playing.""" + for team, players in all_players.items(): + player_games: list[PlayerGame] = [] + team_games = {"team": team, "players": player_games} + games.append(team_games) + for player in players: + player_games.append({"player": player, "game": tracker_data.get_player_game(team, player)}) + + class PlayerSlotData(TypedDict): + player: int + slot_data: dict[str, Any] + + slot_data: list[dict[str, int | list[PlayerSlotData]]] = [] + """Slot data for each player.""" + for team, players in all_players.items(): + player_slot_data: list[PlayerSlotData] = [] + team_slot_data = {"team": team, "players": player_slot_data} + slot_data.append(team_slot_data) + for player in players: + player_slot_data.append({"player": player, "slot_data": tracker_data.get_slot_data(team, player)}) + + return { + "groups": groups, + "slot_data": slot_data, + } diff --git a/docs/webhost api.md b/docs/webhost api.md index c8936205ecb9..ca4b1ce71597 100644 --- a/docs/webhost api.md +++ b/docs/webhost api.md @@ -16,6 +16,8 @@ Current endpoints: - [`/status/`](#status) - Room API - [`/room_status/`](#roomstatus) +- Tracker API + - [`/tracker/`](#tracker) - User API - [`/get_rooms`](#getrooms) - [`/get_seeds`](#getseeds) @@ -244,6 +246,214 @@ Example: } ``` +## Tracker Endpoints +Endpoints to fetch information regarding players of an active WebHost room with the supplied tracker_ID. The tracker ID +can either be viewed while on a room tracker page, or from the [room's endpoint](#room-endpoints). + +### `/tracker/` + +Will provide a dict of tracker data with the following keys: + +- item_link groups and their players (`groups`) +- Each player's slot_data (`slot_data`) +- Each player's current alias (`aliases`) + - Will return the name if there is none +- A list of items each player has received as a NetworkItem (`player_items_received`) +- A list of checks done by each player as a list of the location id's (`player_checks_done`) +- The total number of checks done by all players (`total_checks_done`) +- Hints that players have used or received (`hints`) +- The time of last activity of each player in RFC 1123 format (`activity_timers`) +- The time of last active connection of each player in RFC 1123 format (`connection_timers`) +- The current client status of each player (`player_status`) +- The datapackage hash for each player (`datapackage`) + - This hash can then be sent to the datapackage API to receive the appropriate datapackage as necessary + + +Example: +```json +{ + "groups": [ + { + "team": 0, + "groups": [ + { + "slot": 5, + "name": "testGroup", + "members": [ + 1, + 2 + ] + }, + { + "slot": 6, + "name": "myCoolLink", + "members": [ + 3, + 4 + ] + } + ] + } + ], + "slot_data": [ + { + "team": 0, + "players": [ + { + "player": 1, + "slot_data": { + "example_option": 1, + "other_option": 3 + } + }, + { + "player": 2, + "slot_data": { + "example_option": 1, + "other_option": 2 + } + } + ] + } + ], + "aliases": [ + { + "team": 0, + "players": [ + { + "player": 1, + "alias": "Incompetence" + }, + { + "player": 2, + "alias": "Slot_Name_2" + } + ] + } + ], + "player_items_received": [ + { + "team": 0, + "players": [ + { + "player": 1, + "items": [ + [1, 1, 1, 0], + [2, 2, 2, 1] + ] + }, + { + "player": 2, + "items": [ + [1, 1, 1, 2], + [2, 2, 2, 0] + ] + } + ] + } + ], + "player_checks_done": [ + { + "team": 0, + "players": [ + { + "player": 1, + "locations": [ + 1, + 2 + ] + }, + { + "player": 2, + "locations": [ + 1, + 2 + ] + } + ] + } + ], + "total_checks_done": [ + { + "team": 0, + "checks_done": 4 + } + ], + "hints": [ + { + "team": 0, + "players": [ + { + "player": 1, + "hints": [ + [1, 2, 4, 6, 0, "", 4, 0] + ] + }, + { + "player": 2, + "hints": [] + } + ] + } + ], + "activity_timers": [ + { + "team": 0, + "players": [ + { + "player": 1, + "time": "Fri, 18 Apr 2025 20:35:45 GMT" + }, + { + "player": 2, + "time": "Fri, 18 Apr 2025 20:42:46 GMT" + } + ] + } + ], + "connection_timers": [ + { + "team": 0, + "players": [ + { + "player": 1, + "time": "Fri, 18 Apr 2025 20:38:25 GMT" + }, + { + "player": 2, + "time": "Fri, 18 Apr 2025 21:03:00 GMT" + } + ] + } + ], + "player_status": [ + { + "team": 0, + "players": [ + { + "player": 1, + "status": 0 + }, + { + "player": 2, + "status": 0 + } + ] + } + ], + "datapackage": { + "Archipelago": { + "checksum": "ac9141e9ad0318df2fa27da5f20c50a842afeecb", + "version": 0 + }, + "The Messenger": { + "checksum": "6991cbcda7316b65bcb072667f3ee4c4cae71c0b", + "version": 0 + } + } +} +``` + ## User Endpoints User endpoints can get room and seed details from the current session tokens (cookies) From dfd7cbf0c5c11bb2ff126349395b9cbf1f81f297 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 23 Aug 2025 18:36:25 -0400 Subject: [PATCH 0669/1218] Tests: Standardize World Exclusions, Strengthen LCS Test (#4423) --- test/general/test_implemented.py | 9 +++++---- test/general/test_items.py | 3 +-- test/general/test_locations.py | 9 ++++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/test/general/test_implemented.py b/test/general/test_implemented.py index cf0624a28837..de432e369099 100644 --- a/test/general/test_implemented.py +++ b/test/general/test_implemented.py @@ -37,10 +37,11 @@ def test_stage_methods(self): def test_slot_data(self): """Tests that if a world creates slot data, it's json serializable.""" - for game_name, world_type in AutoWorldRegister.world_types.items(): - # has an await for generate_output which isn't being called - if game_name in {"Ocarina of Time"}: - continue + # has an await for generate_output which isn't being called + excluded_games = ("Ocarina of Time",) + worlds_to_test = {game: world + for game, world in AutoWorldRegister.world_types.items() if game not in excluded_games} + for game_name, world_type in worlds_to_test.items(): multiworld = setup_solo_multiworld(world_type) with self.subTest(game=game_name, seed=multiworld.seed): distribute_items_restrictive(multiworld) diff --git a/test/general/test_items.py b/test/general/test_items.py index dbaca1c91c74..a48576da5220 100644 --- a/test/general/test_items.py +++ b/test/general/test_items.py @@ -150,8 +150,7 @@ def test_locality_not_modified(self): """Test that worlds don't modify the locality of items after duplicates are resolved""" gen_steps = ("generate_early",) additional_steps = ("create_regions", "create_items", "set_rules", "connect_entrances", "generate_basic", "pre_fill") - worlds_to_test = {game: world for game, world in AutoWorldRegister.world_types.items()} - for game_name, world_type in worlds_to_test.items(): + for game_name, world_type in AutoWorldRegister.world_types.items(): with self.subTest("Game", game=game_name): multiworld = setup_solo_multiworld(world_type, gen_steps) local_items = multiworld.worlds[1].options.local_items.value.copy() diff --git a/test/general/test_locations.py b/test/general/test_locations.py index 37ae94e00328..77ae2602e528 100644 --- a/test/general/test_locations.py +++ b/test/general/test_locations.py @@ -33,7 +33,10 @@ def test_locations_in_datapackage(self): def test_location_creation_steps(self): """Tests that Regions and Locations aren't created after `create_items`.""" gen_steps = ("generate_early", "create_regions", "create_items") - for game_name, world_type in AutoWorldRegister.world_types.items(): + excluded_games = ("Ocarina of Time", "Pokemon Red and Blue") + worlds_to_test = {game: world + for game, world in AutoWorldRegister.world_types.items() if game not in excluded_games} + for game_name, world_type in worlds_to_test.items(): with self.subTest("Game", game_name=game_name): multiworld = setup_solo_multiworld(world_type, gen_steps) region_count = len(multiworld.get_regions()) @@ -54,13 +57,13 @@ def test_location_creation_steps(self): call_all(multiworld, "generate_basic") self.assertEqual(region_count, len(multiworld.get_regions()), f"{game_name} modified region count during generate_basic") - self.assertGreaterEqual(location_count, len(multiworld.get_locations()), + self.assertEqual(location_count, len(multiworld.get_locations()), f"{game_name} modified locations count during generate_basic") call_all(multiworld, "pre_fill") self.assertEqual(region_count, len(multiworld.get_regions()), f"{game_name} modified region count during pre_fill") - self.assertGreaterEqual(location_count, len(multiworld.get_locations()), + self.assertEqual(location_count, len(multiworld.get_locations()), f"{game_name} modified locations count during pre_fill") def test_location_group(self): From d5bdac02b76e4d579f7f6cada09132fd6eb833e6 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sun, 24 Aug 2025 02:54:49 +0200 Subject: [PATCH 0670/1218] Docs: Add deprioritized to AP API doc (#5355) Did this on my phone while in the bathroom :) --- docs/world api.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/world api.md b/docs/world api.md index e8932cfd83f3..832ad05d4f66 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -257,6 +257,14 @@ another flag like "progression", it means "an especially useful progression item combined with `progression`; see below) * `progression_skip_balancing`: the combination of `progression` and `skip_balancing`, i.e., a progression item that will not be moved around by progression balancing; used, e.g., for currency or tokens, to not flood early spheres +* `deprioritized`: denotes that an item should not be placed on priority locations + (to be combined with `progression`; see below) +* `progression_deprioritized`: the combination of `progression` and `deprioritized`, i.e. a progression item that + should not be placed on priority locations, despite being progression; + like skip_balancing, this is commonly used for currency or tokens. +* `progression_deprioritized_skip_balancing`: the combination of `progression`, `deprioritized` and `skip_balancing`. + Since there is overlap between the kind of items that want `skip_balancing` and `deprioritized`, + this combined classification exists for convenience ### Regions From d146d90131a5087698cbf67a9fc085ce3da2f362 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Mon, 25 Aug 2025 17:52:04 +0200 Subject: [PATCH 0671/1218] Core: Fix Priority Fill *not* crashing when it should, in cases where there is no deprioritized progression #5363 --- Fill.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Fill.py b/Fill.py index 1cc1278f4b50..7a079fbc82db 100644 --- a/Fill.py +++ b/Fill.py @@ -549,10 +549,12 @@ def mark_for_locking(location: Location): if prioritylocations and regular_progression: # retry with one_item_per_player off because some priority fills can fail to fill with that optimization # deprioritized items are still not in the mix, so they need to be collected into state first. + # allow_partial should only be set if there is deprioritized progression to fall back on. priority_retry_state = sweep_from_pool(multiworld.state, deprioritized_progression) fill_restrictive(multiworld, priority_retry_state, prioritylocations, regular_progression, single_player_placement=single_player, swap=False, on_place=mark_for_locking, - name="Priority Retry", one_item_per_player=False, allow_partial=True) + name="Priority Retry", one_item_per_player=False, + allow_partial=bool(deprioritized_progression)) if prioritylocations and deprioritized_progression: # There are no more regular progression items that can be placed on any priority locations. From 1fa342b0859439ed671ad43f1c29ad5fa8468e12 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Mon, 25 Aug 2025 17:36:39 +0000 Subject: [PATCH 0672/1218] Core: add python 3.13 support (#5357) * Core: fix freeze support for py3.13+ Loading Utils now patches multiprocessing.freeze_support() Utils.freeze_support() is now deprecated * WebHost: use pony fork on py3.13 * CI: test with py3.13 --- .github/workflows/unittests.yml | 7 ++++--- Launcher.py | 2 +- Utils.py | 20 +++++++++++++------- WebHostLib/requirements.txt | 3 ++- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index 96219daa1973..90a5d70b8e0c 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -41,12 +41,13 @@ jobs: python: - {version: '3.11.2'} # Change to '3.11' around 2026-06-10 - {version: '3.12'} + - {version: '3.13'} include: - python: {version: '3.11'} # old compat os: windows-latest - - python: {version: '3.12'} # current + - python: {version: '3.13'} # current os: windows-latest - - python: {version: '3.12'} # current + - python: {version: '3.13'} # current os: macos-latest steps: @@ -74,7 +75,7 @@ jobs: os: - ubuntu-latest python: - - {version: '3.12'} # current + - {version: '3.13'} # current steps: - uses: actions/checkout@v4 diff --git a/Launcher.py b/Launcher.py index 5720012cf9a7..adc3cb96ef24 100644 --- a/Launcher.py +++ b/Launcher.py @@ -484,7 +484,7 @@ def main(args: argparse.Namespace | dict | None = None): if __name__ == '__main__': init_logging('Launcher') - Utils.freeze_support() + multiprocessing.freeze_support() multiprocessing.set_start_method("spawn") # if launched process uses kivy, fork won't work parser = argparse.ArgumentParser( description='Archipelago Launcher', diff --git a/Utils.py b/Utils.py index 5a24bc157eca..e73edd7137f2 100644 --- a/Utils.py +++ b/Utils.py @@ -940,15 +940,15 @@ def __getitem__(self, item: Any) -> Any: def _extend_freeze_support() -> None: - """Extend multiprocessing.freeze_support() to also work on Non-Windows for spawn.""" - # upstream issue: https://github.com/python/cpython/issues/76327 + """Extend multiprocessing.freeze_support() to also work on Non-Windows and without setting spawn method first.""" + # original upstream issue: https://github.com/python/cpython/issues/76327 # code based on https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/rthooks/pyi_rth_multiprocessing.py#L26 import multiprocessing import multiprocessing.spawn def _freeze_support() -> None: """Minimal freeze_support. Only apply this if frozen.""" - from subprocess import _args_from_interpreter_flags + from subprocess import _args_from_interpreter_flags # noqa # Prevent `spawn` from trying to read `__main__` in from the main script multiprocessing.process.ORIGINAL_DIR = None @@ -975,17 +975,23 @@ def _freeze_support() -> None: multiprocessing.spawn.spawn_main(**kwargs) sys.exit() - if not is_windows and is_frozen(): - multiprocessing.freeze_support = multiprocessing.spawn.freeze_support = _freeze_support + def _noop() -> None: + pass + + multiprocessing.freeze_support = multiprocessing.spawn.freeze_support = _freeze_support if is_frozen() else _noop def freeze_support() -> None: - """This behaves like multiprocessing.freeze_support but also works on Non-Windows.""" + """This now only calls multiprocessing.freeze_support since we are patching freeze_support on module load.""" import multiprocessing - _extend_freeze_support() + + deprecate("Use multiprocessing.freeze_support() instead") multiprocessing.freeze_support() +_extend_freeze_support() + + def visualize_regions(root_region: Region, file_name: str, *, show_entrance_names: bool = False, show_locations: bool = True, show_other_regions: bool = True, linetype_ortho: bool = True, regions_to_highlight: set[Region] | None = None) -> None: diff --git a/WebHostLib/requirements.txt b/WebHostLib/requirements.txt index 8fd6dc630428..f64ed085c982 100644 --- a/WebHostLib/requirements.txt +++ b/WebHostLib/requirements.txt @@ -1,6 +1,7 @@ flask>=3.1.1 werkzeug>=3.1.3 -pony>=0.7.19 +pony>=0.7.19; python_version <= '3.12' +pony @ git+https://github.com/black-sliver/pony@7feb1221953b7fa4a6735466bf21a8b4d35e33ba#0.7.19; python_version >= '3.13' waitress>=3.0.2 Flask-Caching>=2.3.0 Flask-Compress>=1.17 From e1fca86cf82f0616e292dd5b0375d43fa2e61a48 Mon Sep 17 00:00:00 2001 From: Ishigh1 Date: Wed, 27 Aug 2025 02:36:47 +0200 Subject: [PATCH 0673/1218] Core: Improved GER's caching of visited nodes during initialization (#5366) * Moved the visited update * Renamed visited to seen --- entrance_rando.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/entrance_rando.py b/entrance_rando.py index 492fff32e32d..578059ae6f5b 100644 --- a/entrance_rando.py +++ b/entrance_rando.py @@ -74,13 +74,12 @@ def _can_expand_graph(self, entrance: Entrance) -> bool: if entrance in self._expands_graph_cache: return self._expands_graph_cache[entrance] - visited = set() + seen = {entrance.connected_region} q: deque[Region] = deque() q.append(entrance.connected_region) while q: region = q.popleft() - visited.add(region) # check if the region itself is progression if region in region.multiworld.indirect_connections: @@ -103,7 +102,8 @@ def _can_expand_graph(self, entrance: Entrance) -> bool: and exit_ in self._usable_exits): self._expands_graph_cache[entrance] = True return True - elif exit_.connected_region and exit_.connected_region not in visited: + elif exit_.connected_region and exit_.connected_region not in seen: + seen.add(exit_.connected_region) q.append(exit_.connected_region) self._expands_graph_cache[entrance] = False From be51fb9ba9309bd0dcd20c8da7420af7b7959295 Mon Sep 17 00:00:00 2001 From: Rosalie <61372066+Rosalie-A@users.noreply.github.com> Date: Wed, 27 Aug 2025 09:20:51 -0400 Subject: [PATCH 0674/1218] [TLOZ] Updated to remove deprecated call. (#5266) * Updated to remove deprecated call. * Removed unused argument. --- worlds/tloz/Rom.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/worlds/tloz/Rom.py b/worlds/tloz/Rom.py index 58aa38805f73..e7b60b90fe6b 100644 --- a/worlds/tloz/Rom.py +++ b/worlds/tloz/Rom.py @@ -70,10 +70,6 @@ def get_base_rom_bytes(file_name: str = "") -> bytes: return base_rom_bytes -def get_base_rom_path(file_name: str = "") -> str: - options = Utils.get_options() - if not file_name: - file_name = options["tloz_options"]["rom_file"] - if not os.path.exists(file_name): - file_name = Utils.user_path(file_name) - return file_name +def get_base_rom_path() -> str: + from . import TLoZWorld + return TLoZWorld.settings.rom_file From e11b40c94b0b570b1ccb01245b6638a01e709658 Mon Sep 17 00:00:00 2001 From: lordlou <87331798+lordlou@users.noreply.github.com> Date: Wed, 27 Aug 2025 09:21:28 -0400 Subject: [PATCH 0675/1218] [SM, SMZ3] get options deprecation (#5257) * - SM now displays message when getting an item outside for someone else (fills ROM item table) This is dependant on modifications done to sm_randomizer_rom project * First working MultiWorld SM * some missing things: - player name inject in ROM and get in client - end game get from ROM in client - send self item to server - add player names table in ROM * replaced CollectionState inheritance from SMBoolManager with a composition of an array of it (required to generation more than one SM world, which is still fails but is better) * - reenabled balancing * post rebase fixes * updated SmClient.py * + added VariaRandomizer LICENSE * + added sm_randomizer_rom project (which builds sm.ips) * Moved VariaRandomizer and sm_randomizer_rom projects inside worlds/sm and done some cleaning * properly revert change made to CollectionState and more cleaning * Fixed multiworld support patch not working with VariaRandomizer's * missing file commit * Fixed syntax error in unused code to satisfy Linter * Revert "Fixed multiworld support patch not working with VariaRandomizer's" This reverts commit fb3ca18528bb331995e3d3051648c8f84d04c08b. * many fixes and improovement - fixed seeded generation - fixed broken logic when more than one SM world - added missing rules for inter-area transitions - added basic patch presence for logic - added DoorManager init call to reflect present patches for logic - moved CollectionState addition out of BaseClasses into SM world - added condition to apply progitempool presorting only if SM world is present - set Bosses item id to None to prevent them going into multidata - now use get_game_players * first working (most of the time) progression generation for SM using VariaRandomizer's rules, items, locations and accessPoint (as regions) * first working single-world randomized SM rom patches * - SM now displays message when getting an item outside for someone else (fills ROM item table) This is dependant on modifications done to sm_randomizer_rom project * First working MultiWorld SM * some missing things: - player name inject in ROM and get in client - end game get from ROM in client - send self item to server - add player names table in ROM * replaced CollectionState inheritance from SMBoolManager with a composition of an array of it (required to generation more than one SM world, which is still fails but is better) * - reenabled balancing * post rebase fixes * updated SmClient.py * + added VariaRandomizer LICENSE * + added sm_randomizer_rom project (which builds sm.ips) * Moved VariaRandomizer and sm_randomizer_rom projects inside worlds/sm and done some cleaning * properly revert change made to CollectionState and more cleaning * Fixed multiworld support patch not working with VariaRandomizer's * missing file commit * Fixed syntax error in unused code to satisfy Linter * Revert "Fixed multiworld support patch not working with VariaRandomizer's" This reverts commit fb3ca18528bb331995e3d3051648c8f84d04c08b. * many fixes and improovement - fixed seeded generation - fixed broken logic when more than one SM world - added missing rules for inter-area transitions - added basic patch presence for logic - added DoorManager init call to reflect present patches for logic - moved CollectionState addition out of BaseClasses into SM world - added condition to apply progitempool presorting only if SM world is present - set Bosses item id to None to prevent them going into multidata - now use get_game_players * Fixed multiworld support patch not working with VariaRandomizer's Added stage_fill_hook to set morph first in progitempool Added back VariaRandomizer's standard patches * + added missing files from variaRandomizer project * + added missing variaRandomizer files (custom sprites) + started integrating VariaRandomizer options (WIP) * Some fixes for player and server name display - fixed player name of 16 characters reading too far in SM client - fixed 12 bytes SM player name limit (now 16) - fixed server name not being displayed in SM when using server cheat ( now displays RECEIVED FROM ARCHIPELAGO) - request: temporarly changed default seed names displayed in SM main menu to OWTCH * Fixed Goal completion not triggering in smClient * integrated VariaRandomizer's options into AP (WIP) - startAP is working - door rando is working - skillset is working * - fixed itemsounds.ips crash by always including nofanfare.ips into multiworld.ips (itemsounds is now always applied and "itemsounds" preset must always be "off") * skillset are now instanced per player instead of being a singleton class * RomPatches are now instanced per player instead of being a singleton class * DoorManager is now instanced per player instead of being a singleton class * - fixed the last bugs that prevented generation of >1 SM world * fixed crash when no skillset preset is specified in randoPreset (default to "casual") * maxDifficulty support and itemsounds removal - added support for maxDifficulty - removed itemsounds patch as its always applied from multiworld patch for now * Fixed bad merge * Post merge adaptation * fixed player name length fix that got lost with the merge * fixed generation with other game type than SM * added default randoPreset json for SM in playerSettings.yaml * fixed broken SM client following merge * beautified json skillset presets * Fixed ArchipelagoSmClient not building * Fixed conflict between mutliworld patch and beam_doors_plms patch - doorsColorsRando now working * SM generation now outputs APBP - Fixed paths for patches and presets when frozen * added missing file and fixed multithreading issue * temporarily set data_version = 0 * more work - added support for AP starting items - fixed client crash with gamemode being None - patch.py "compatible_version" is now 3 * commited missing asm files fixed start item reserve breaking game (was using bad write offset when patching) * Nothing item are now handled game-side. the game will now skip displaying a message box for received Nothing item (but the client will still receive it). fixed crash in SMClient when loosing connection to SNI * fixed No Energy Item missing its ID fixed Plando * merge post fixes * fixed start item Grapple, XRay and Reserve HUD, as well as graphic beams (except ice palette color) * fixed freeze in blue brinstar caused by Varia's custom PLM not being filled with proper Multiworld PLM address (altLocsAddresses) * fixed start item x-ray HUD display * Fixed start items being sent by the server (is all handled in ROM) Start items are now not removed from itempool anymore Nothing Item is now local_items so no player will ever pickup Nothing. Doing so reduces contribution of this world to the Multiworld the more Nothing there is though. Fixed crash (and possibly passing but broken) at generation where the static list of IPSPatches used by all SM worlds was being modified * fixed settings that could be applied to any SM players * fixed auth to server only using player name (now does as ALTTP to authenticate) * - fixed End Credits broken text * added non SM item name display * added all supported SM options in playerSettings.yaml * fixed locations needing a list of parent regions (now generate a region for each location with one-way exits to each (previously) parent region did some cleaning (mainly reverts on unnecessary core classes * minor setting fixes and tweaks - merged Area and lightArea settings - made missileQty, superQty and powerBombQty use value from 10 to 90 and divide value by float(10) when generating - fixed inverted layoutPatch setting * added option start_inventory_removes_from_pool fixed option names formatting fixed lint errors small code and repo cleanup * Hopefully fixed ROR2 that could not send any items * - fixed missing required change to ROR2 * fixed 0 hp when respawning without having ever saved (start items were not updating the save checksum) * fixed typo with doors_colors_rando * fixed checksum * added custom sprites for off-world items (progression or not) the original AP sprite was made with PierRoulette's SM Item Sprite Utility by ijwu * - added missing change following upstream merge - changed patch filename extension from apbp to apm3 so patch can be used with the new client * added morph placement options: early means local and sphere 1 * fixed failing unit tests * - fixed broken custom_preset options * - big cleanup to remove unnecessary or unsupported features * - more cleanup * - moved sm_randomizer_rom and all always applied patches into an external project that outputs basepatch.ips - small cleanup * - added comment to refer to project for generating basepatch.ips (https://github.com/lordlou/SMBasepatch) * fixed g4_skip patch that can be not applied if hud is enabled * - fixed off world sprite that can have broken graphics (restricted to use only first 2 palette) * - updated basepatch to reflect g4_skip removal - moved more asm files to SMBasepatch project * - tourian grey doors at baby metroid are now always flashing (allowing to go back if needed) * fixed wrong path if using built as exe * - cleaned exposed maxDifficulty options - removed always enabled Knows * Merged LttPClient and SMClient into SNIClient * added varia_custom Preset Option that fetch a preset (read from a new varia_custom_preset Option) from varia's web service * small doc precision * - added death_link support - fixed broken Goal Completion - post merge fix * - removed now useless presets * - fixed bad internal mapping with maxDiff - increases maxDiff if only Bosses is preventing beating the game * - added support for lowercase custom preset sections (knows, settings and controller) - fixed controller settings not applying to ROM * - fixed death loop when dying with Door rando, bomb or speed booster as starting items - varia's backup save should now be usable (automatically enabled when doing door rando) * -added docstring for generated yaml * fixed bad merge * fixed broken infinity max difficulty * commented debug prints * adjusted credits to mark progression speed and difficulty as Non Available * added support for more than 255 players (will print Archipelago for higher player number) * fixed missing cleanup * added support for 65535 different player names in ROM * fixed generations failing when only bosses are unreachable * - replaced setting maxDiff to infinity with a bool only affecting boss logics if only bosses are left to finish * fixed failling generations when using 'fun' settings Accessibility checks are forced to 'items' if restricted locations are used by VARIA following usage of 'fun' settings * fixed debug logger * removed unsupported "suits_restriction" option * fixed generations failing when only bosses are unreachable (using a less intrusive approach for AP) * - fixed deathlink emptying reserves - added death_link_survive option that lets player survive when receiving a deathlink if the have non-empty reserves * - merged death_link and death_link_survive options * fixed death_link * added a fallback default starting location instead of failing generation if an invalid one was chosen * added Nothing and NoEnergy as hint blacklist added missing NoEnergy as local items and removed it from progression * replaced deprecated usage of Utils.get_options with settings.get_settings in SM and SMZ3 --- worlds/sm/Rom.py | 3 ++- worlds/smz3/Rom.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/worlds/sm/Rom.py b/worlds/sm/Rom.py index c5b6645ed8ef..9d567aa4825f 100644 --- a/worlds/sm/Rom.py +++ b/worlds/sm/Rom.py @@ -1,6 +1,7 @@ import hashlib import os +import settings import json import Utils from Utils import read_snes_rom @@ -77,7 +78,7 @@ def get_base_rom_bytes(file_name: str = "") -> bytes: def get_base_rom_path(file_name: str = "") -> str: - options = Utils.get_options() + options: settings.Settings = settings.get_settings() if not file_name: file_name = options["sm_options"]["rom_file"] if not os.path.exists(file_name): diff --git a/worlds/smz3/Rom.py b/worlds/smz3/Rom.py index d66d9239792d..4c66b0d450fe 100644 --- a/worlds/smz3/Rom.py +++ b/worlds/smz3/Rom.py @@ -1,6 +1,7 @@ import hashlib import os +import settings import Utils from Utils import read_snes_rom from worlds.Files import APProcedurePatch, APPatchExtension, APTokenMixin, APTokenTypes @@ -65,7 +66,7 @@ def get_base_rom_bytes() -> bytes: def get_sm_base_rom_path(file_name: str = "") -> str: - options = Utils.get_options() + options: settings.Settings = settings.get_settings() if not file_name: file_name = options["sm_options"]["rom_file"] if not os.path.exists(file_name): @@ -74,7 +75,7 @@ def get_sm_base_rom_path(file_name: str = "") -> str: def get_lttp_base_rom_path(file_name: str = "") -> str: - options = Utils.get_options() + options: settings.Settings = settings.get_settings() if not file_name: file_name = options["lttp_options"]["rom_file"] if not os.path.exists(file_name): From 750c8a98100ceaea01871255f6da813d0fd839e7 Mon Sep 17 00:00:00 2001 From: PoryGone <98504756+PoryGone@users.noreply.github.com> Date: Wed, 27 Aug 2025 09:21:53 -0400 Subject: [PATCH 0676/1218] Stop using get_options (#5341) --- worlds/dkc3/Rom.py | 5 +++-- worlds/smw/Regions.py | 2 +- worlds/smw/Rom.py | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/worlds/dkc3/Rom.py b/worlds/dkc3/Rom.py index fb8bc2b122a4..cde4d8c76496 100644 --- a/worlds/dkc3/Rom.py +++ b/worlds/dkc3/Rom.py @@ -1,3 +1,4 @@ + import Utils from Utils import read_snes_rom from worlds.AutoWorld import World @@ -735,9 +736,9 @@ def get_base_rom_bytes(file_name: str = "") -> bytes: return base_rom_bytes def get_base_rom_path(file_name: str = "") -> str: - options = Utils.get_options() if not file_name: - file_name = options["dkc3_options"]["rom_file"] + from settings import get_settings + file_name = get_settings()["dkc3_options"]["rom_file"] if not os.path.exists(file_name): file_name = Utils.user_path(file_name) return file_name diff --git a/worlds/smw/Regions.py b/worlds/smw/Regions.py index 249604987401..d7950ffb3563 100644 --- a/worlds/smw/Regions.py +++ b/worlds/smw/Regions.py @@ -808,7 +808,7 @@ def create_regions(world: World, active_locations): lambda state: (state.has(ItemName.blue_switch_palace, player) and (state.has(ItemName.p_switch, player) or state.has(ItemName.green_switch_palace, player) or - (state.has(ItemName.yellow_switch_palace, player) or state.has(ItemName.red_switch_palace, player))))) + (state.has(ItemName.yellow_switch_palace, player) and state.has(ItemName.red_switch_palace, player))))) add_location_to_region(multiworld, player, active_locations, LocationName.chocolate_island_3_region, LocationName.chocolate_island_3_dragon) add_location_to_region(multiworld, player, active_locations, LocationName.chocolate_island_4_region, LocationName.chocolate_island_4_dragon, lambda state: (state.has(ItemName.p_switch, player) and diff --git a/worlds/smw/Rom.py b/worlds/smw/Rom.py index 9016e14def91..081d6b4a504d 100644 --- a/worlds/smw/Rom.py +++ b/worlds/smw/Rom.py @@ -3185,9 +3185,9 @@ def get_base_rom_bytes(file_name: str = "") -> bytes: def get_base_rom_path(file_name: str = "") -> str: - options = Utils.get_options() if not file_name: - file_name = options["smw_options"]["rom_file"] + from settings import get_settings + file_name = get_settings()["smw_options"]["rom_file"] if not os.path.exists(file_name): file_name = Utils.user_path(file_name) return file_name From 439be48f36a2ed26bedede7e620d441cc3478b4f Mon Sep 17 00:00:00 2001 From: Rosalie <61372066+Rosalie-A@users.noreply.github.com> Date: Wed, 27 Aug 2025 13:28:42 -0400 Subject: [PATCH 0677/1218] [TLOZ] Remove deprecated Utils.get_options call, part 2 (#5371) * Updated to remove deprecated call. * Removed unused argument. * Removed errant client calls to Utils.get_options, and fixed call in Rom.py that was passing an argument. --- Zelda1Client.py | 7 ++++--- worlds/tloz/Rom.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Zelda1Client.py b/Zelda1Client.py index 9753621ef013..6dd7a361658c 100644 --- a/Zelda1Client.py +++ b/Zelda1Client.py @@ -20,6 +20,8 @@ from worlds.tloz.Locations import location_ids from worlds.tloz import Items, Locations, Rom +from settings import get_settings + SYSTEM_MESSAGE_ID = 0 CONNECTION_TIMING_OUT_STATUS = "Connection timing out. Please restart your emulator, then restart connector_tloz.lua" @@ -341,13 +343,12 @@ async def nes_sync_task(ctx: ZeldaContext): # Text Mode to use !hint and such with games that have no text entry Utils.init_logging("ZeldaClient") - options = Utils.get_options() - DISPLAY_MSGS = options["tloz_options"]["display_msgs"] + DISPLAY_MSGS = get_settings()["tloz_options"]["display_msgs"] async def run_game(romfile: str) -> None: auto_start = typing.cast(typing.Union[bool, str], - Utils.get_options()["tloz_options"].get("rom_start", True)) + get_settings()["tloz_options"].get("rom_start", True)) if auto_start is True: import webbrowser webbrowser.open(romfile) diff --git a/worlds/tloz/Rom.py b/worlds/tloz/Rom.py index e7b60b90fe6b..5b618bb688e4 100644 --- a/worlds/tloz/Rom.py +++ b/worlds/tloz/Rom.py @@ -58,7 +58,7 @@ def get_source_data(cls) -> bytes: def get_base_rom_bytes(file_name: str = "") -> bytes: base_rom_bytes = getattr(get_base_rom_bytes, "base_rom_bytes", None) if not base_rom_bytes: - file_name = get_base_rom_path(file_name) + file_name = get_base_rom_path() base_rom_bytes = bytes(Utils.read_snes_rom(open(file_name, "rb"))) basemd5 = hashlib.md5() From bb2ecb8a97913399c64ea1594dadeaadc83c7b9d Mon Sep 17 00:00:00 2001 From: Justus Lind Date: Sat, 30 Aug 2025 01:41:29 +1000 Subject: [PATCH 0678/1218] Muse Dash: Change Exception to Option Error and Update to Muse Radio FM106 (#5374) * Change Exception to OptionError * Update to Muse Radio FM106. * Add Scipio's suggestion. Co-authored-by: Scipio Wright --------- Co-authored-by: Scipio Wright --- worlds/musedash/MuseDashData.py | 4 ++++ worlds/musedash/__init__.py | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/worlds/musedash/MuseDashData.py b/worlds/musedash/MuseDashData.py index 32849eec9b17..6943b281f1cc 100644 --- a/worlds/musedash/MuseDashData.py +++ b/worlds/musedash/MuseDashData.py @@ -661,4 +661,8 @@ "Ineffabilis": SongData(2900785, "87-4", "Aim to Be a Rhythm Master!", False, 3, 7, 10), "DaJiaHao": SongData(2900786, "87-5", "Aim to Be a Rhythm Master!", False, 5, 7, 10), "Echoes of SeraphiM": SongData(2900787, "87-6", "Aim to Be a Rhythm Master!", False, 5, 8, 10), + "Othello feat.Uiro": SongData(2900788, "88-0", "MUSE RADIO FM106", True, 3, 5, 7), + "Midnight Blue": SongData(2900789, "88-1", "MUSE RADIO FM106", True, 2, 5, 7), + "overwork feat.Woonoo": SongData(2900790, "88-2", "MUSE RADIO FM106", True, 2, 6, 8), + "SUPER CITYLIGHTS": SongData(2900791, "88-3", "MUSE RADIO FM106", True, 5, 7, 10), } diff --git a/worlds/musedash/__init__.py b/worlds/musedash/__init__.py index eb82148c1bb9..239d640e6882 100644 --- a/worlds/musedash/__init__.py +++ b/worlds/musedash/__init__.py @@ -2,7 +2,7 @@ from BaseClasses import Region, Item, ItemClassification, Tutorial from typing import List, ClassVar, Type, Set from math import floor -from Options import PerGameCommonOptions +from Options import PerGameCommonOptions, OptionError from .Options import MuseDashOptions, md_option_groups from .Items import MuseDashSongItem, MuseDashFixedItem @@ -102,7 +102,8 @@ def generate_early(self): # If the above fails, we want to adjust the difficulty thresholds. # Easier first, then harder if lower_diff_threshold <= 1 and higher_diff_threshold >= 11: - raise Exception("Failed to find enough songs, even with maximum difficulty thresholds.") + raise OptionError("Failed to find enough songs, even with maximum difficulty thresholds. " + "Too many songs have been excluded or set to be starter songs.") elif lower_diff_threshold <= 1: higher_diff_threshold += 1 else: From f2461a2fea9f9d8a8fca6ef411fb8531a8c0c364 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 30 Aug 2025 22:33:43 +0200 Subject: [PATCH 0679/1218] WebHost: Ensure that OptionSets and OptionLists get exported to yaml, even when nothing is selected (#5240) * Ensure that OptionSets and OptionLists get exported to yaml, even if nothing is selected * forgot ItemSet and LocationSet * Make it even less likely for there to be overlap --- WebHostLib/options.py | 9 +++++++-- WebHostLib/templates/playerOptions/macros.html | 4 ++++ WebHostLib/templates/weightedOptions/macros.html | 4 ++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/WebHostLib/options.py b/WebHostLib/options.py index 38489cee3c49..3c63fa8c7fb9 100644 --- a/WebHostLib/options.py +++ b/WebHostLib/options.py @@ -155,7 +155,9 @@ def generate_weighted_yaml(game: str): options = {} for key, val in request.form.items(): - if "||" not in key: + if val == "_ensure-empty-list": + options[key] = {} + elif "||" not in key: if len(str(val)) == 0: continue @@ -212,8 +214,11 @@ def generate_yaml(game: str): if request.method == "POST": options = {} intent_generate = False + for key, val in request.form.items(multi=True): - if key in options: + if val == "_ensure-empty-list": + options[key] = [] + elif options.get(key): if not isinstance(options[key], list): options[key] = [options[key]] options[key].append(val) diff --git a/WebHostLib/templates/playerOptions/macros.html b/WebHostLib/templates/playerOptions/macros.html index bbb3c75d12a3..a4cc3aa5acf3 100644 --- a/WebHostLib/templates/playerOptions/macros.html +++ b/WebHostLib/templates/playerOptions/macros.html @@ -134,6 +134,7 @@ {% macro OptionList(option_name, option) %} {{ OptionTitle(option_name, option) }} +
    {% for key in (option.valid_keys if option.valid_keys is ordered else option.valid_keys|sort) %}
    @@ -146,6 +147,7 @@ {% macro LocationSet(option_name, option) %} {{ OptionTitle(option_name, option) }} +
    {% for group_name in world.location_name_groups.keys()|sort %} {% if group_name != "Everywhere" %} @@ -169,6 +171,7 @@ {% macro ItemSet(option_name, option) %} {{ OptionTitle(option_name, option) }} +
    {% for group_name in world.item_name_groups.keys()|sort %} {% if group_name != "Everything" %} @@ -192,6 +195,7 @@ {% macro OptionSet(option_name, option) %} {{ OptionTitle(option_name, option) }} +
    {% for key in (option.valid_keys if option.valid_keys is ordered else option.valid_keys|sort) %}
    diff --git a/WebHostLib/templates/weightedOptions/macros.html b/WebHostLib/templates/weightedOptions/macros.html index 89ba0a0e6e7a..1d485a24def8 100644 --- a/WebHostLib/templates/weightedOptions/macros.html +++ b/WebHostLib/templates/weightedOptions/macros.html @@ -139,6 +139,7 @@ {% endmacro %} {% macro OptionList(option_name, option) %} +
    {% for key in (option.valid_keys if option.valid_keys is ordered else option.valid_keys|sort) %}
    @@ -158,6 +159,7 @@ {% endmacro %} {% macro LocationSet(option_name, option, world) %} +
    {% for group_name in world.location_name_groups.keys()|sort %} {% if group_name != "Everywhere" %} @@ -180,6 +182,7 @@ {% endmacro %} {% macro ItemSet(option_name, option, world) %} +
    {% for group_name in world.item_name_groups.keys()|sort %} {% if group_name != "Everything" %} @@ -202,6 +205,7 @@ {% endmacro %} {% macro OptionSet(option_name, option) %} +
    {% for key in (option.valid_keys if option.valid_keys is ordered else option.valid_keys|sort) %}
    From 34aaa44b1f426239a3789229ed3a69107d4e3a1b Mon Sep 17 00:00:00 2001 From: sgrunt Date: Sat, 30 Aug 2025 17:09:22 -0600 Subject: [PATCH 0680/1218] Timespinner: add support for spider traps from new client release (#4848) Co-authored-by: sgrunt --- worlds/timespinner/Items.py | 4 +++- worlds/timespinner/Options.py | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/worlds/timespinner/Items.py b/worlds/timespinner/Items.py index a00fca7ee5f4..4cfcc289fdc9 100644 --- a/worlds/timespinner/Items.py +++ b/worlds/timespinner/Items.py @@ -208,7 +208,9 @@ class ItemData(NamedTuple): 'Lab Access Research': ItemData('Lab Access', 1337196, progression=True), 'Lab Access Dynamo': ItemData('Lab Access', 1337197, progression=True), 'Drawbridge Key': ItemData('Key', 1337198, progression=True), - # 1337199 - 1337248 Reserved + # 1337199 Reserved + 'Spider Trap': ItemData('Trap', 1337200, 0, trap=True), + # 1337201 - 1337248 Reserved 'Max Sand': ItemData('Stat', 1337249, 14) } diff --git a/worlds/timespinner/Options.py b/worlds/timespinner/Options.py index 4cb7fbbce14b..0b735ea3913a 100644 --- a/worlds/timespinner/Options.py +++ b/worlds/timespinner/Options.py @@ -367,8 +367,8 @@ class TrapChance(Range): class Traps(OptionList): """List of traps that may be in the item pool to find""" display_name = "Traps Types" - valid_keys = { "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap", "Throw Stun Trap" } - default = [ "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap", "Throw Stun Trap" ] + valid_keys = { "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap", "Throw Stun Trap", "Spider Trap" } + default = [ "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap", "Throw Stun Trap", "Spider Trap" ] class PresentAccessWithWheelAndSpindle(Toggle): """When inverted, allows using the refugee camp warp when both the Timespinner Wheel and Spindle is acquired.""" From 893acd2f027e910402839930e2cd886f889747c2 Mon Sep 17 00:00:00 2001 From: Etsuna <47378314+Etsuna@users.noreply.github.com> Date: Sun, 31 Aug 2025 14:12:32 +0200 Subject: [PATCH 0681/1218] Webserver: fix activity_timers for api tracker.py (#5385) --- WebHostLib/api/tracker.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WebHostLib/api/tracker.py b/WebHostLib/api/tracker.py index abf4cdbe1ba5..4ea3a2339233 100644 --- a/WebHostLib/api/tracker.py +++ b/WebHostLib/api/tracker.py @@ -112,7 +112,9 @@ class PlayerTimer(TypedDict): client_activity_timers: tuple[tuple[int, int], float] = tracker_data._multisave.get("client_activity_timers", ()) for (team, player), timestamp in client_activity_timers: # use index since we can rely on order - activity_timers[team]["player_timers"][player - 1]["time"] = datetime.fromtimestamp(timestamp, timezone.utc) + # FIX: key is "players" (not "player_timers") + activity_timers[team]["players"][player - 1]["time"] = datetime.fromtimestamp(timestamp, timezone.utc) + connection_timers: list[dict[str, int | list[PlayerTimer]]] = [] """Time of last connection per player. Returned as RFC 1123 format and null if no connection has been made.""" From cdf7165ab4d01f22a3f9a2b4cb603c1e8852db4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sun, 31 Aug 2025 10:21:23 -0400 Subject: [PATCH 0682/1218] Stardew Valley: Use new asserts in tests (#4621) * changes * cherry pick stuff * use newly create methods more * use new assets to ease readability * remove unneeded assert * add assert region adapters * use new asserts yay * self review * self review * review * replace parrot express with transportation constant * bullshit commit again * revert a bunch of off topic changes * these changes seems to be on topic * revert some undesired merge changes * review imports * use type instead of instance in some options * properly return super * review * change one str to use a constnat --- worlds/stardew_valley/test/TestGeneration.py | 29 +++++------ .../stardew_valley/test/TestWalnutsanity.py | 34 ++++++------ worlds/stardew_valley/test/bases.py | 52 +++++++++++-------- worlds/stardew_valley/test/options/utils.py | 4 +- .../stardew_valley/test/rules/TestArcades.py | 36 ++++++------- 5 files changed, 81 insertions(+), 74 deletions(-) diff --git a/worlds/stardew_valley/test/TestGeneration.py b/worlds/stardew_valley/test/TestGeneration.py index 5e60f8e80abb..7b1535676d27 100644 --- a/worlds/stardew_valley/test/TestGeneration.py +++ b/worlds/stardew_valley/test/TestGeneration.py @@ -131,15 +131,13 @@ def test_given_elevator_to_floor_105_when_find_another_elevator_then_has_access_ items_for_115 = self.generate_items_for_mine_115() last_elevator = self.get_item_by_name("Progressive Mine Elevator") self.collect(items_for_115) - floor_115 = self.multiworld.get_region("The Mines - Floor 115", self.player) - floor_120 = self.multiworld.get_region("The Mines - Floor 120", self.player) - self.assertTrue(floor_115.can_reach(self.multiworld.state)) - self.assertFalse(floor_120.can_reach(self.multiworld.state)) + self.assert_can_reach_region(Region.mines_floor_115) + self.assert_cannot_reach_region(Region.mines_floor_120) self.collect(last_elevator) - self.assertTrue(floor_120.can_reach(self.multiworld.state)) + self.assert_can_reach_region(Region.mines_floor_120) def generate_items_for_mine_115(self) -> List[Item]: pickaxes = [self.get_item_by_name("Progressive Pickaxe")] * 2 @@ -171,27 +169,24 @@ def test_given_access_to_floor_115_when_find_more_tools_then_has_access_to_skull items_for_skull_50 = self.generate_items_for_skull_50() items_for_skull_100 = self.generate_items_for_skull_100() self.collect(items_for_115) - floor_115 = self.multiworld.get_region(Region.mines_floor_115, self.player) - skull_25 = self.multiworld.get_region(Region.skull_cavern_25, self.player) - skull_75 = self.multiworld.get_region(Region.skull_cavern_75, self.player) - self.assertTrue(floor_115.can_reach(self.multiworld.state)) - self.assertFalse(skull_25.can_reach(self.multiworld.state)) - self.assertFalse(skull_75.can_reach(self.multiworld.state)) + self.assert_can_reach_region(Region.mines_floor_115) + self.assert_cannot_reach_region(Region.skull_cavern_25) + self.assert_cannot_reach_region(Region.skull_cavern_75) self.remove(items_for_115) self.collect(items_for_skull_50) - self.assertTrue(floor_115.can_reach(self.multiworld.state)) - self.assertTrue(skull_25.can_reach(self.multiworld.state)) - self.assertFalse(skull_75.can_reach(self.multiworld.state)) + self.assert_can_reach_region(Region.mines_floor_115) + self.assert_can_reach_region(Region.skull_cavern_25) + self.assert_cannot_reach_region(Region.skull_cavern_75) self.remove(items_for_skull_50) self.collect(items_for_skull_100) - self.assertTrue(floor_115.can_reach(self.multiworld.state)) - self.assertTrue(skull_25.can_reach(self.multiworld.state)) - self.assertTrue(skull_75.can_reach(self.multiworld.state)) + self.assert_can_reach_region(Region.mines_floor_115) + self.assert_can_reach_region(Region.skull_cavern_25) + self.assert_can_reach_region(Region.skull_cavern_75) def generate_items_for_mine_115(self) -> List[Item]: pickaxes = [self.get_item_by_name("Progressive Pickaxe")] * 2 diff --git a/worlds/stardew_valley/test/TestWalnutsanity.py b/worlds/stardew_valley/test/TestWalnutsanity.py index 418eaa87c70f..7111174d2630 100644 --- a/worlds/stardew_valley/test/TestWalnutsanity.py +++ b/worlds/stardew_valley/test/TestWalnutsanity.py @@ -3,6 +3,7 @@ from .bases import SVTestBase from ..options import ExcludeGingerIsland, Walnutsanity, ToolProgression, SkillProgression from ..strings.ap_names.ap_option_names import WalnutsanityOptionName +from ..strings.ap_names.transport_names import Transportation class SVWalnutsanityTestBase(SVTestBase): @@ -48,24 +49,27 @@ def test_logic_received_walnuts(self): self.collect("Island West Turtle") self.collect("Progressive House") self.collect("5 Golden Walnuts", 10) + self.assert_cannot_reach_location(Transportation.parrot_express) - self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) self.collect("Island North Turtle") self.collect("Island Resort") self.collect("Open Professor Snail Cave") - self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_cannot_reach_location(Transportation.parrot_express) + self.collect("Dig Site Bridge") self.collect("Island Farmhouse") self.collect("Qi Walnut Room") - self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_cannot_reach_location(Transportation.parrot_express) + self.collect("Combat Level", 10) self.collect("Mining Level", 10) - self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_cannot_reach_location(Transportation.parrot_express) + self.collect("Progressive Slingshot") self.collect("Progressive Weapon", 5) self.collect("Progressive Pickaxe", 4) self.collect("Progressive Watering Can", 4) - self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_can_reach_location(Transportation.parrot_express) class TestWalnutsanityPuzzles(SVWalnutsanityTestBase): @@ -155,9 +159,9 @@ def test_logic_received_walnuts(self): self.collect("Island West Turtle") self.collect("5 Golden Walnuts", 5) - self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_cannot_reach_location(Transportation.parrot_express) self.collect("Island North Turtle") - self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_can_reach_location(Transportation.parrot_express) class TestWalnutsanityDigSpots(SVWalnutsanityTestBase): @@ -218,20 +222,20 @@ def test_logic_received_walnuts(self): # You need to receive 40, and collect 4 self.collect("Island Obelisk") self.collect("Island West Turtle") - self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_cannot_reach_location(Transportation.parrot_express) items = self.collect("5 Golden Walnuts", 8) - self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_can_reach_location(Transportation.parrot_express) self.remove(items) - self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_cannot_reach_location(Transportation.parrot_express) items = self.collect("3 Golden Walnuts", 14) - self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_can_reach_location(Transportation.parrot_express) self.remove(items) - self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_cannot_reach_location(Transportation.parrot_express) items = self.collect("Golden Walnut", 40) - self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_can_reach_location(Transportation.parrot_express) self.remove(items) - self.assertFalse(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_cannot_reach_location(Transportation.parrot_express) self.collect("5 Golden Walnuts", 4) self.collect("3 Golden Walnuts", 6) self.collect("Golden Walnut", 2) - self.assertTrue(self.multiworld.state.can_reach_location("Parrot Express", self.player)) + self.assert_can_reach_location(Transportation.parrot_express) diff --git a/worlds/stardew_valley/test/bases.py b/worlds/stardew_valley/test/bases.py index a2852183996d..4370c05d7b2c 100644 --- a/worlds/stardew_valley/test/bases.py +++ b/worlds/stardew_valley/test/bases.py @@ -4,10 +4,10 @@ import threading import typing import unittest +from collections.abc import Iterable from contextlib import contextmanager -from typing import Optional, Dict, Union, Any, List, Iterable -from BaseClasses import get_seed, MultiWorld, Location, Item, CollectionState, Entrance +from BaseClasses import get_seed, MultiWorld, Location, Item, Region, CollectionState, Entrance from test.bases import WorldTestBase from test.general import gen_steps, setup_solo_multiworld as setup_base_solo_multiworld from worlds.AutoWorld import call_all @@ -18,6 +18,7 @@ from ..options import StardewValleyOption, options logger = logging.getLogger(__name__) + DEFAULT_TEST_SEED = get_seed() logger.info(f"Default Test Seed: {DEFAULT_TEST_SEED}") @@ -39,7 +40,7 @@ class SVTestCase(unittest.TestCase): @contextmanager def solo_world_sub_test(self, msg: str | None = None, /, - world_options: dict[str | type[StardewValleyOption], Any] | None = None, + world_options: dict[str | type[StardewValleyOption], typing.Any] | None = None, *, seed=DEFAULT_TEST_SEED, world_caching=True, @@ -121,18 +122,17 @@ def collect_all_except(self, item_to_not_collect: str): if item.name != item_to_not_collect: self.multiworld.state.collect(item) - def get_real_locations(self) -> List[Location]: + def get_real_locations(self) -> list[Location]: return [location for location in self.multiworld.get_locations(self.player) if location.address is not None] - def get_real_location_names(self) -> List[str]: + def get_real_location_names(self) -> list[str]: return [location.name for location in self.get_real_locations()] - def collect(self, item: Union[str, Item, Iterable[Item]], count: int = 1) -> Union[None, Item, List[Item]]: + def collect(self, item: str | Item | Iterable[Item], count: int = 1) -> Item | list[Item] | None: assert count > 0 if not isinstance(item, str): - super().collect(item) - return + return super().collect(item) if count == 1: item = self.create_item(item) @@ -162,34 +162,44 @@ def reset_collection_state(self) -> None: def assert_rule_true(self, rule: StardewRule, state: CollectionState | None = None) -> None: if state is None: state = self.multiworld.state - super().assert_rule_true(rule, state) + return super().assert_rule_true(rule, state) def assert_rule_false(self, rule: StardewRule, state: CollectionState | None = None) -> None: if state is None: state = self.multiworld.state - super().assert_rule_false(rule, state) + return super().assert_rule_false(rule, state) def assert_can_reach_location(self, location: Location | str, state: CollectionState | None = None) -> None: if state is None: state = self.multiworld.state - super().assert_can_reach_location(location, state) + return super().assert_can_reach_location(location, state) def assert_cannot_reach_location(self, location: Location | str, state: CollectionState | None = None) -> None: if state is None: state = self.multiworld.state - super().assert_cannot_reach_location(location, state) + return super().assert_cannot_reach_location(location, state) + + def assert_can_reach_region(self, region: Region | str, state: CollectionState | None = None) -> None: + if state is None: + state = self.multiworld.state + return super().assert_can_reach_region(region, state) + + def assert_cannot_reach_region(self, region: Region | str, state: CollectionState | None = None) -> None: + if state is None: + state = self.multiworld.state + return super().assert_cannot_reach_region(region, state) def assert_can_reach_entrance(self, entrance: Entrance | str, state: CollectionState | None = None) -> None: if state is None: state = self.multiworld.state - super().assert_can_reach_entrance(entrance, state) + return super().assert_can_reach_entrance(entrance, state) pre_generated_worlds = {} @contextmanager -def solo_multiworld(world_options: dict[str | type[StardewValleyOption], Any] | None = None, +def solo_multiworld(world_options: dict[str | type[StardewValleyOption], typing.Any] | None = None, *, seed=DEFAULT_TEST_SEED, world_caching=True) -> Iterable[tuple[MultiWorld, StardewValleyWorld]]: @@ -200,13 +210,11 @@ def solo_multiworld(world_options: dict[str | type[StardewValleyOption], Any] | multiworld = setup_solo_multiworld(world_options, seed) try: multiworld.lock.acquire() - world = multiworld.worlds[1] - original_state = multiworld.state.copy() original_itempool = multiworld.itempool.copy() unfilled_locations = multiworld.get_unfilled_locations(1) - yield multiworld, typing.cast(StardewValleyWorld, world) + yield multiworld, typing.cast(StardewValleyWorld, multiworld.worlds[1]) multiworld.state = original_state multiworld.itempool = original_itempool @@ -217,9 +225,9 @@ def solo_multiworld(world_options: dict[str | type[StardewValleyOption], Any] | # Mostly a copy of test.general.setup_solo_multiworld, I just don't want to change the core. -def setup_solo_multiworld(test_options: Optional[Dict[Union[str, StardewValleyOption], str]] = None, +def setup_solo_multiworld(test_options: dict[str | type[StardewValleyOption], str] | None = None, seed=DEFAULT_TEST_SEED, - _cache: Dict[frozenset, MultiWorld] = {}, # noqa + _cache: dict[frozenset, MultiWorld] = {}, # noqa _steps=gen_steps) -> MultiWorld: test_options = parse_class_option_keys(test_options) @@ -276,7 +284,7 @@ def make_hashable(test_options, seed): return frozenset(test_options.items()).union({("seed", seed)}) -def search_world_cache(cache: Dict[frozenset, MultiWorld], frozen_options: frozenset) -> Optional[MultiWorld]: +def search_world_cache(cache: dict[frozenset, MultiWorld], frozen_options: frozenset) -> MultiWorld | None: try: return cache[frozen_options] except KeyError: @@ -286,12 +294,12 @@ def search_world_cache(cache: Dict[frozenset, MultiWorld], frozen_options: froze return None -def add_to_world_cache(cache: Dict[frozenset, MultiWorld], frozen_options: frozenset, multi_world: MultiWorld) -> None: +def add_to_world_cache(cache: dict[frozenset, MultiWorld], frozen_options: frozenset, multi_world: MultiWorld) -> None: # We could complete the key with all the default options, but that does not seem to improve performances. cache[frozen_options] = multi_world -def setup_multiworld(test_options: Iterable[Dict[str, int]] = None, seed=None) -> MultiWorld: # noqa +def setup_multiworld(test_options: Iterable[dict[str, int]] | None = None, seed=None) -> MultiWorld: # noqa if test_options is None: test_options = [] diff --git a/worlds/stardew_valley/test/options/utils.py b/worlds/stardew_valley/test/options/utils.py index 9f02105da84f..1ed88974ec05 100644 --- a/worlds/stardew_valley/test/options/utils.py +++ b/worlds/stardew_valley/test/options/utils.py @@ -7,7 +7,7 @@ from ...options import StardewValleyOptions, StardewValleyOption -def parse_class_option_keys(test_options: dict[str | StardewValleyOption, Any] | None) -> dict: +def parse_class_option_keys(test_options: dict[str | type[StardewValleyOption], Any] | None) -> dict: """ Now the option class is allowed as key. """ if test_options is None: return {} @@ -25,7 +25,7 @@ def parse_class_option_keys(test_options: dict[str | StardewValleyOption, Any] | return parsed_options -def fill_dataclass_with_default(test_options: dict[str | StardewValleyOption, Any] | None) -> StardewValleyOptions: +def fill_dataclass_with_default(test_options: dict[str | type[StardewValleyOption], Any] | None) -> StardewValleyOptions: test_options = parse_class_option_keys(test_options) filled_options = {} diff --git a/worlds/stardew_valley/test/rules/TestArcades.py b/worlds/stardew_valley/test/rules/TestArcades.py index 407f299992c3..b820fda79777 100644 --- a/worlds/stardew_valley/test/rules/TestArcades.py +++ b/worlds/stardew_valley/test/rules/TestArcades.py @@ -8,9 +8,9 @@ class TestArcadeMachinesLogic(SVTestBase): } def test_prairie_king(self): - self.assertFalse(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) - self.assertFalse(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) - self.assertFalse(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) + self.assert_cannot_reach_region("JotPK World 1") + self.assert_cannot_reach_region("JotPK World 2") + self.assert_cannot_reach_region("JotPK World 3") self.assert_cannot_reach_location("Journey of the Prairie King Victory") boots = self.create_item("JotPK: Progressive Boots") @@ -21,18 +21,18 @@ def test_prairie_king(self): self.multiworld.state.collect(boots) self.multiworld.state.collect(gun) - self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) - self.assertFalse(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) - self.assertFalse(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) + self.assert_can_reach_region("JotPK World 1") + self.assert_cannot_reach_region("JotPK World 2") + self.assert_cannot_reach_region("JotPK World 3") self.assert_cannot_reach_location("Journey of the Prairie King Victory") self.remove(boots) self.remove(gun) self.multiworld.state.collect(boots) self.multiworld.state.collect(boots) - self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) - self.assertFalse(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) - self.assertFalse(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) + self.assert_can_reach_region("JotPK World 1") + self.assert_cannot_reach_region("JotPK World 2") + self.assert_cannot_reach_region("JotPK World 3") self.assert_cannot_reach_location("Journey of the Prairie King Victory") self.remove(boots) self.remove(boots) @@ -41,9 +41,9 @@ def test_prairie_king(self): self.multiworld.state.collect(gun) self.multiworld.state.collect(ammo) self.multiworld.state.collect(life) - self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) - self.assertTrue(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) - self.assertFalse(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) + self.assert_can_reach_region("JotPK World 1") + self.assert_can_reach_region("JotPK World 2") + self.assert_cannot_reach_region("JotPK World 3") self.assert_cannot_reach_location("Journey of the Prairie King Victory") self.remove(boots) self.remove(gun) @@ -57,9 +57,9 @@ def test_prairie_king(self): self.multiworld.state.collect(ammo) self.multiworld.state.collect(life) self.multiworld.state.collect(drop) - self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) - self.assertTrue(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) - self.assertTrue(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) + self.assert_can_reach_region("JotPK World 1") + self.assert_can_reach_region("JotPK World 2") + self.assert_can_reach_region("JotPK World 3") self.assert_cannot_reach_location("Journey of the Prairie King Victory") self.remove(boots) self.remove(gun) @@ -80,9 +80,9 @@ def test_prairie_king(self): self.multiworld.state.collect(ammo) self.multiworld.state.collect(life) self.multiworld.state.collect(drop) - self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) - self.assertTrue(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) - self.assertTrue(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) + self.assert_can_reach_region("JotPK World 1") + self.assert_can_reach_region("JotPK World 2") + self.assert_can_reach_region("JotPK World 3") self.assert_can_reach_location("Journey of the Prairie King Victory") self.remove(boots) self.remove(boots) From c753fbff2de1c2a327dcb83b2b170900902476af Mon Sep 17 00:00:00 2001 From: PoryGone <98504756+PoryGone@users.noreply.github.com> Date: Sun, 31 Aug 2025 17:31:09 -0400 Subject: [PATCH 0683/1218] Celeste (Open World): Implement New Game (#4937) * APWorld Skeleton * Hair Color Rando and first items * All interactable items * Checkpoint Items and Locations * First pass sample intermediate data * Bulk of Region/location code * JSON Data Parser * New items and Level Item mapping * Data Parsing fixes and most of 1a data * 1a complete data and region/location/item creation fixes * Add Key Location type and ID output * Add options to slot data * 1B Level Data * Added Location logging * Add Goal Area Options * 1c Level Data * Old Site A B C level data * Key/Binosanity and Hair Length options * Key Item/Location and Clutter Event handling * Remove generic 'keys' item * 3a level data * 3b and 3c level data * Chapter 4 level data * Chapter 5 Logic Data * Chapter 5 level data * Trap Support * Add TrapLink Support * Chapter 6 A/B/C Level Data * Add active_levels to slot_data * Item and Location Name Groups + style cleanups * Chapter 7 Level Data and Items, Gemsanity option * Goal Area and victory handling * Fix slot_data * Add Core Level Data * Carsanity * Farewell Level Data and ID Range Update * Farewell level data and handling * Music Shuffle * Require Cassettes * Change default trap expiration action to Deaths * Handle Poetry * Mod versioning * Rename folder, general cleanup * Additional Cleanup * Handle Farewell Golden Goal when Include Goldens is off * Better handling of Farewell Golden * Update Docs * Beta test bug fixes * Bump to v1.0.0 * Update Changelog * Several Logic tweaks * Update APWorld Version * Add Celeste (Open World) to README * Peer review changes * Logic Fixes: * Adjust Mirror Temple B Key logic * Increment APWorld version * Fix several logic bugs * Add missing link * Add Item Name Groups for common alternative item names * Account for Madeline's post-Celeste hair-dying activities * Account for ignored member variable and hardcoded color in Celeste codebase * Add Blue Clouds to the logic of reaching Farewell - intro-02-launch * Type checking workaround * Bump version number * Adjust Setup Guide * Minor typing fixes * Logic and PR fixes * Increment APWorld Version * Use more world helpers * Core review * CODEOWNERS --- README.md | 1 + docs/CODEOWNERS | 3 + worlds/celeste_open_world/CHANGELOG.md | 47 + worlds/celeste_open_world/Items.py | 264 + worlds/celeste_open_world/Levels.py | 208 + worlds/celeste_open_world/Locations.py | 281 + worlds/celeste_open_world/Names/ItemName.py | 210 + worlds/celeste_open_world/Names/__init__.py | 0 worlds/celeste_open_world/Options.py | 528 + worlds/celeste_open_world/__init__.py | 351 + .../data/CelesteLevelData.json | 41232 ++++++++++++++++ .../data/CelesteLevelData.py | 9792 ++++ worlds/celeste_open_world/data/ParseData.py | 190 + worlds/celeste_open_world/data/__init__.py | 0 .../docs/en_Celeste (Open World).md | 98 + worlds/celeste_open_world/docs/guide_en.md | 20 + 16 files changed, 53225 insertions(+) create mode 100644 worlds/celeste_open_world/CHANGELOG.md create mode 100644 worlds/celeste_open_world/Items.py create mode 100644 worlds/celeste_open_world/Levels.py create mode 100644 worlds/celeste_open_world/Locations.py create mode 100644 worlds/celeste_open_world/Names/ItemName.py create mode 100644 worlds/celeste_open_world/Names/__init__.py create mode 100644 worlds/celeste_open_world/Options.py create mode 100644 worlds/celeste_open_world/__init__.py create mode 100644 worlds/celeste_open_world/data/CelesteLevelData.json create mode 100644 worlds/celeste_open_world/data/CelesteLevelData.py create mode 100644 worlds/celeste_open_world/data/ParseData.py create mode 100644 worlds/celeste_open_world/data/__init__.py create mode 100644 worlds/celeste_open_world/docs/en_Celeste (Open World).md create mode 100644 worlds/celeste_open_world/docs/guide_en.md diff --git a/README.md b/README.md index 44c44d72b4e9..4a0aa614ffec 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ Currently, the following games are supported: * Super Mario Land 2: 6 Golden Coins * shapez * Paint +* Celeste (Open World) For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 889d51415c25..44eb830b3a9f 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -42,6 +42,9 @@ # Celeste 64 /worlds/celeste64/ @PoryGone +# Celeste (Open World) +/worlds/celeste_open_world/ @PoryGone + # ChecksFinder /worlds/checksfinder/ @SunCatMC diff --git a/worlds/celeste_open_world/CHANGELOG.md b/worlds/celeste_open_world/CHANGELOG.md new file mode 100644 index 000000000000..dbc3d7173b09 --- /dev/null +++ b/worlds/celeste_open_world/CHANGELOG.md @@ -0,0 +1,47 @@ +# Celeste - Changelog + + +## v1.0 - First Stable Release + +### Features: + +- Goal is to collect a certain number of Strawberries, finish your chosen Goal Area, and reach the credits in the Epilogue +- Locations included: + - Level Clears + - Strawberries + - Crystal Hearts + - Cassettes + - Golden Strawberries + - Keys + - Checkpoints + - Summit Gems + - Cars + - Binoculars + - Rooms +- Items included: + - 34 different interactable objects + - Keys + - Checkpoints + - Summit Gems + - Crystal Hearts + - Cassettes + - Traps + - Bald Trap + - Literature Trap + - Stun Trap + - Invisible Trap + - Fast Trap + - Slow Trap + - Ice Trap + - Reverse Trap + - Screen Flip Trap + - Laughter Trap + - Hiccup Trap + - Zoom Trap +- Aesthetic Options: + - Music Shuffle + - Require Cassette items to hear music + - Hair Length/Color options +- Death Link + - Amnesty option to select how many deaths must occur to send a DeathLink +- Trap Link diff --git a/worlds/celeste_open_world/Items.py b/worlds/celeste_open_world/Items.py new file mode 100644 index 000000000000..51df6e91f17d --- /dev/null +++ b/worlds/celeste_open_world/Items.py @@ -0,0 +1,264 @@ +from typing import NamedTuple, Optional + +from BaseClasses import Item, ItemClassification +from .Names import ItemName + + +level_item_lists: dict[str, set[str]] = { + "0a": set(), + + "1a": {ItemName.springs, ItemName.traffic_blocks, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "1b": {ItemName.springs, ItemName.traffic_blocks, ItemName.dash_refills, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "1c": {ItemName.traffic_blocks, ItemName.dash_refills, ItemName.coins}, + + "2a": {ItemName.springs, ItemName.dream_blocks, ItemName.traffic_blocks, ItemName.strawberry_seeds, ItemName.dash_refills, ItemName.coins}, + "2b": {ItemName.springs, ItemName.dream_blocks, ItemName.dash_refills, ItemName.coins, ItemName.blue_cassette_blocks}, + "2c": {ItemName.springs, ItemName.dream_blocks, ItemName.dash_refills, ItemName.coins}, + + "3a": {ItemName.springs, ItemName.moving_platforms, ItemName.sinking_platforms, ItemName.dash_refills, ItemName.coins, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "3b": {ItemName.springs, ItemName.dash_refills, ItemName.sinking_platforms, ItemName.coins, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "3c": {ItemName.dash_refills, ItemName.sinking_platforms, ItemName.coins}, + + "4a": {ItemName.blue_clouds, ItemName.blue_boosters, ItemName.moving_platforms, ItemName.coins, ItemName.strawberry_seeds, ItemName.springs, ItemName.move_blocks, ItemName.pink_clouds, ItemName.white_block, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "4b": {ItemName.blue_boosters, ItemName.moving_platforms, ItemName.move_blocks, ItemName.springs, ItemName.coins, ItemName.blue_clouds, ItemName.pink_clouds, ItemName.dash_refills, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "4c": {ItemName.blue_boosters, ItemName.move_blocks, ItemName.dash_refills, ItemName.pink_clouds}, + + "5a": {ItemName.swap_blocks, ItemName.red_boosters, ItemName.dash_switches, ItemName.dash_refills, ItemName.coins, ItemName.springs, ItemName.torches, ItemName.seekers, ItemName.theo_crystal, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "5b": {ItemName.swap_blocks, ItemName.red_boosters, ItemName.dash_switches, ItemName.dash_refills, ItemName.coins, ItemName.springs, ItemName.torches, ItemName.seekers, ItemName.theo_crystal, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "5c": {ItemName.swap_blocks, ItemName.red_boosters, ItemName.dash_switches, ItemName.dash_refills}, + + "6a": {ItemName.feathers, ItemName.kevin_blocks, ItemName.dash_refills, ItemName.bumpers, ItemName.springs, ItemName.coins, ItemName.badeline_boosters, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "6b": {ItemName.feathers, ItemName.kevin_blocks, ItemName.dash_refills, ItemName.bumpers, ItemName.coins, ItemName.springs, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "6c": {ItemName.feathers, ItemName.kevin_blocks, ItemName.dash_refills, ItemName.bumpers}, + + "7a": {ItemName.springs, ItemName.dash_refills, ItemName.badeline_boosters, ItemName.traffic_blocks, ItemName.coins, ItemName.dream_blocks, ItemName.sinking_platforms, ItemName.blue_boosters, ItemName.blue_clouds, ItemName.pink_clouds, ItemName.move_blocks, ItemName.moving_platforms, ItemName.swap_blocks, ItemName.red_boosters, ItemName.dash_switches, ItemName.feathers, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "7b": {ItemName.springs, ItemName.dash_refills, ItemName.badeline_boosters, ItemName.traffic_blocks, ItemName.coins, ItemName.dream_blocks, ItemName.moving_platforms, ItemName.blue_boosters, ItemName.blue_clouds, ItemName.pink_clouds, ItemName.move_blocks, ItemName.swap_blocks, ItemName.red_boosters, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "7c": {ItemName.springs, ItemName.dash_refills, ItemName.badeline_boosters, ItemName.coins, ItemName.pink_clouds}, + + # Epilogue + "8a": set(), + + # Core + "9a": {ItemName.springs, ItemName.dash_refills, ItemName.fire_ice_balls, ItemName.bumpers, ItemName.core_toggles, ItemName.core_blocks, ItemName.coins, ItemName.badeline_boosters, ItemName.feathers, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "9b": {ItemName.springs, ItemName.dash_refills, ItemName.fire_ice_balls, ItemName.bumpers, ItemName.core_toggles, ItemName.core_blocks, ItemName.coins, ItemName.badeline_boosters, ItemName.dream_blocks, ItemName.moving_platforms, ItemName.blue_clouds, ItemName.swap_blocks, ItemName.kevin_blocks, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks}, + "9c": {ItemName.dash_refills, ItemName.bumpers, ItemName.core_toggles, ItemName.core_blocks, ItemName.traffic_blocks, ItemName.dream_blocks, ItemName.pink_clouds, ItemName.swap_blocks, ItemName.kevin_blocks}, + + # Farewell Pre/Post Empty Space + "10a": {ItemName.blue_clouds, ItemName.badeline_boosters, ItemName.dash_refills, ItemName.double_dash_refills, ItemName.swap_blocks, ItemName.springs, ItemName.pufferfish, ItemName.coins, ItemName.dream_blocks, ItemName.jellyfish, ItemName.red_boosters, ItemName.dash_switches, ItemName.move_blocks, ItemName.breaker_boxes, ItemName.traffic_blocks}, + "10b": {ItemName.dream_blocks, ItemName.badeline_boosters, ItemName.bird, ItemName.dash_refills, ItemName.double_dash_refills, ItemName.kevin_blocks, ItemName.coins, ItemName.traffic_blocks, ItemName.move_blocks, ItemName.blue_boosters, ItemName.springs, ItemName.feathers, ItemName.swap_blocks, ItemName.red_boosters, ItemName.core_blocks, ItemName.fire_ice_balls, ItemName.kevin_blocks, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.yellow_cassette_blocks, ItemName.green_cassette_blocks, ItemName.breaker_boxes, ItemName.pufferfish, ItemName.jellyfish}, + "10c": {ItemName.badeline_boosters, ItemName.double_dash_refills, ItemName.springs, ItemName.pufferfish, ItemName.jellyfish}, +} + +level_cassette_items: dict[str, str] = { + "0a": ItemName.prologue_cassette, + "1a": ItemName.fc_a_cassette, + "1b": ItemName.fc_b_cassette, + "1c": ItemName.fc_c_cassette, + "2a": ItemName.os_a_cassette, + "2b": ItemName.os_b_cassette, + "2c": ItemName.os_c_cassette, + "3a": ItemName.cr_a_cassette, + "3b": ItemName.cr_b_cassette, + "3c": ItemName.cr_c_cassette, + "4a": ItemName.gr_a_cassette, + "4b": ItemName.gr_b_cassette, + "4c": ItemName.gr_c_cassette, + "5a": ItemName.mt_a_cassette, + "5b": ItemName.mt_b_cassette, + "5c": ItemName.mt_c_cassette, + "6a": ItemName.ref_a_cassette, + "6b": ItemName.ref_b_cassette, + "6c": ItemName.ref_c_cassette, + "7a": ItemName.sum_a_cassette, + "7b": ItemName.sum_b_cassette, + "7c": ItemName.sum_c_cassette, + "8a": ItemName.epilogue_cassette, + "9a": ItemName.core_a_cassette, + "9b": ItemName.core_b_cassette, + "9c": ItemName.core_c_cassette, + "10a":ItemName.farewell_cassette, +} + + +celeste_base_id: int = 0xCA10000 + + +class CelesteItem(Item): + game = "Celeste" + + +class CelesteItemData(NamedTuple): + code: Optional[int] = None + type: ItemClassification = ItemClassification.filler + + +collectable_item_data_table: dict[str, CelesteItemData] = { + ItemName.strawberry: CelesteItemData(celeste_base_id + 0x0, ItemClassification.progression_skip_balancing), + ItemName.raspberry: CelesteItemData(celeste_base_id + 0x1, ItemClassification.filler), +} + +goal_item_data_table: dict[str, CelesteItemData] = { + ItemName.house_keys: CelesteItemData(celeste_base_id + 0x10, ItemClassification.progression_skip_balancing), +} + +trap_item_data_table: dict[str, CelesteItemData] = { + ItemName.bald_trap: CelesteItemData(celeste_base_id + 0x20, ItemClassification.trap), + ItemName.literature_trap: CelesteItemData(celeste_base_id + 0x21, ItemClassification.trap), + ItemName.stun_trap: CelesteItemData(celeste_base_id + 0x22, ItemClassification.trap), + ItemName.invisible_trap: CelesteItemData(celeste_base_id + 0x23, ItemClassification.trap), + ItemName.fast_trap: CelesteItemData(celeste_base_id + 0x24, ItemClassification.trap), + ItemName.slow_trap: CelesteItemData(celeste_base_id + 0x25, ItemClassification.trap), + ItemName.ice_trap: CelesteItemData(celeste_base_id + 0x26, ItemClassification.trap), + ItemName.reverse_trap: CelesteItemData(celeste_base_id + 0x28, ItemClassification.trap), + ItemName.screen_flip_trap: CelesteItemData(celeste_base_id + 0x29, ItemClassification.trap), + ItemName.laughter_trap: CelesteItemData(celeste_base_id + 0x2A, ItemClassification.trap), + ItemName.hiccup_trap: CelesteItemData(celeste_base_id + 0x2B, ItemClassification.trap), + ItemName.zoom_trap: CelesteItemData(celeste_base_id + 0x2C, ItemClassification.trap), +} + +checkpoint_item_data_table: dict[str, CelesteItemData] = {} + +key_item_data_table: dict[str, CelesteItemData] = {} +gem_item_data_table: dict[str, CelesteItemData] = {} + +interactable_item_data_table: dict[str, CelesteItemData] = { + ItemName.springs: CelesteItemData(celeste_base_id + 0x2000 + 0x00, ItemClassification.progression), + ItemName.traffic_blocks: CelesteItemData(celeste_base_id + 0x2000 + 0x01, ItemClassification.progression), + ItemName.pink_cassette_blocks: CelesteItemData(celeste_base_id + 0x2000 + 0x02, ItemClassification.progression), + ItemName.blue_cassette_blocks: CelesteItemData(celeste_base_id + 0x2000 + 0x03, ItemClassification.progression), + + ItemName.dream_blocks: CelesteItemData(celeste_base_id + 0x2000 + 0x04, ItemClassification.progression), + ItemName.coins: CelesteItemData(celeste_base_id + 0x2000 + 0x05, ItemClassification.progression), + ItemName.strawberry_seeds: CelesteItemData(celeste_base_id + 0x2000 + 0x1F, ItemClassification.progression), + + ItemName.sinking_platforms: CelesteItemData(celeste_base_id + 0x2000 + 0x20, ItemClassification.progression), + + ItemName.moving_platforms: CelesteItemData(celeste_base_id + 0x2000 + 0x06, ItemClassification.progression), + ItemName.blue_boosters: CelesteItemData(celeste_base_id + 0x2000 + 0x07, ItemClassification.progression), + ItemName.blue_clouds: CelesteItemData(celeste_base_id + 0x2000 + 0x08, ItemClassification.progression), + ItemName.move_blocks: CelesteItemData(celeste_base_id + 0x2000 + 0x09, ItemClassification.progression), + ItemName.white_block: CelesteItemData(celeste_base_id + 0x2000 + 0x21, ItemClassification.progression), + + ItemName.swap_blocks: CelesteItemData(celeste_base_id + 0x2000 + 0x0A, ItemClassification.progression), + ItemName.red_boosters: CelesteItemData(celeste_base_id + 0x2000 + 0x0B, ItemClassification.progression), + ItemName.torches: CelesteItemData(celeste_base_id + 0x2000 + 0x22, ItemClassification.useful), + ItemName.theo_crystal: CelesteItemData(celeste_base_id + 0x2000 + 0x0C, ItemClassification.progression), + + ItemName.feathers: CelesteItemData(celeste_base_id + 0x2000 + 0x0D, ItemClassification.progression), + ItemName.bumpers: CelesteItemData(celeste_base_id + 0x2000 + 0x0E, ItemClassification.progression), + ItemName.kevin_blocks: CelesteItemData(celeste_base_id + 0x2000 + 0x0F, ItemClassification.progression), + + ItemName.pink_clouds: CelesteItemData(celeste_base_id + 0x2000 + 0x10, ItemClassification.progression), + ItemName.badeline_boosters: CelesteItemData(celeste_base_id + 0x2000 + 0x11, ItemClassification.progression), + + ItemName.fire_ice_balls: CelesteItemData(celeste_base_id + 0x2000 + 0x12, ItemClassification.progression), + ItemName.core_toggles: CelesteItemData(celeste_base_id + 0x2000 + 0x13, ItemClassification.progression), + ItemName.core_blocks: CelesteItemData(celeste_base_id + 0x2000 + 0x14, ItemClassification.progression), + + ItemName.pufferfish: CelesteItemData(celeste_base_id + 0x2000 + 0x15, ItemClassification.progression), + ItemName.jellyfish: CelesteItemData(celeste_base_id + 0x2000 + 0x16, ItemClassification.progression), + ItemName.breaker_boxes: CelesteItemData(celeste_base_id + 0x2000 + 0x17, ItemClassification.progression), + ItemName.dash_refills: CelesteItemData(celeste_base_id + 0x2000 + 0x18, ItemClassification.progression), + ItemName.double_dash_refills: CelesteItemData(celeste_base_id + 0x2000 + 0x19, ItemClassification.progression), + ItemName.yellow_cassette_blocks: CelesteItemData(celeste_base_id + 0x2000 + 0x1A, ItemClassification.progression), + ItemName.green_cassette_blocks: CelesteItemData(celeste_base_id + 0x2000 + 0x1B, ItemClassification.progression), + ItemName.bird: CelesteItemData(celeste_base_id + 0x2000 + 0x23, ItemClassification.progression), + + ItemName.dash_switches: CelesteItemData(celeste_base_id + 0x2000 + 0x1C, ItemClassification.progression), + ItemName.seekers: CelesteItemData(celeste_base_id + 0x2000 + 0x1D, ItemClassification.progression), +} + +cassette_item_data_table: dict[str, CelesteItemData] = { + ItemName.prologue_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x00, ItemClassification.filler), + ItemName.fc_a_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x01, ItemClassification.filler), + ItemName.fc_b_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x02, ItemClassification.filler), + ItemName.fc_c_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x03, ItemClassification.filler), + ItemName.os_a_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x04, ItemClassification.filler), + ItemName.os_b_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x05, ItemClassification.filler), + ItemName.os_c_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x06, ItemClassification.filler), + ItemName.cr_a_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x07, ItemClassification.filler), + ItemName.cr_b_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x08, ItemClassification.filler), + ItemName.cr_c_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x09, ItemClassification.filler), + ItemName.gr_a_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x0A, ItemClassification.filler), + ItemName.gr_b_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x0B, ItemClassification.filler), + ItemName.gr_c_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x0C, ItemClassification.filler), + ItemName.mt_a_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x0D, ItemClassification.filler), + ItemName.mt_b_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x0E, ItemClassification.filler), + ItemName.mt_c_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x0F, ItemClassification.filler), + ItemName.ref_a_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x10, ItemClassification.filler), + ItemName.ref_b_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x11, ItemClassification.filler), + ItemName.ref_c_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x12, ItemClassification.filler), + ItemName.sum_a_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x13, ItemClassification.filler), + ItemName.sum_b_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x14, ItemClassification.filler), + ItemName.sum_c_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x15, ItemClassification.filler), + ItemName.epilogue_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x16, ItemClassification.filler), + ItemName.core_a_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x17, ItemClassification.filler), + ItemName.core_b_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x18, ItemClassification.filler), + ItemName.core_c_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x19, ItemClassification.filler), + ItemName.farewell_cassette: CelesteItemData(celeste_base_id + 0x1000 + 0x1A, ItemClassification.filler), +} + +crystal_heart_item_data_table: dict[str, CelesteItemData] = { + ItemName.crystal_heart_1: CelesteItemData(celeste_base_id + 0x3000 + 0x00, ItemClassification.filler), + ItemName.crystal_heart_2: CelesteItemData(celeste_base_id + 0x3000 + 0x01, ItemClassification.filler), + ItemName.crystal_heart_3: CelesteItemData(celeste_base_id + 0x3000 + 0x02, ItemClassification.filler), + ItemName.crystal_heart_4: CelesteItemData(celeste_base_id + 0x3000 + 0x03, ItemClassification.filler), + ItemName.crystal_heart_5: CelesteItemData(celeste_base_id + 0x3000 + 0x04, ItemClassification.filler), + ItemName.crystal_heart_6: CelesteItemData(celeste_base_id + 0x3000 + 0x05, ItemClassification.filler), + ItemName.crystal_heart_7: CelesteItemData(celeste_base_id + 0x3000 + 0x06, ItemClassification.filler), + ItemName.crystal_heart_8: CelesteItemData(celeste_base_id + 0x3000 + 0x07, ItemClassification.filler), + ItemName.crystal_heart_9: CelesteItemData(celeste_base_id + 0x3000 + 0x08, ItemClassification.filler), + ItemName.crystal_heart_10: CelesteItemData(celeste_base_id + 0x3000 + 0x09, ItemClassification.filler), + ItemName.crystal_heart_11: CelesteItemData(celeste_base_id + 0x3000 + 0x0A, ItemClassification.filler), + ItemName.crystal_heart_12: CelesteItemData(celeste_base_id + 0x3000 + 0x0B, ItemClassification.filler), + ItemName.crystal_heart_13: CelesteItemData(celeste_base_id + 0x3000 + 0x0C, ItemClassification.filler), + ItemName.crystal_heart_14: CelesteItemData(celeste_base_id + 0x3000 + 0x0D, ItemClassification.filler), + ItemName.crystal_heart_15: CelesteItemData(celeste_base_id + 0x3000 + 0x0E, ItemClassification.filler), + ItemName.crystal_heart_16: CelesteItemData(celeste_base_id + 0x3000 + 0x0F, ItemClassification.filler), +} + +def add_checkpoint_to_table(id: int, name: str): + checkpoint_item_data_table[name] = CelesteItemData(id, ItemClassification.progression) + +def add_key_to_table(id: int, name: str): + key_item_data_table[name] = CelesteItemData(id, ItemClassification.progression) + +def add_gem_to_table(id: int, name: str): + gem_item_data_table[name] = CelesteItemData(id, ItemClassification.progression) + +def generate_item_data_table() -> dict[str, CelesteItemData]: + return {**collectable_item_data_table, + **goal_item_data_table, + **trap_item_data_table, + **checkpoint_item_data_table, + **key_item_data_table, + **gem_item_data_table, + **cassette_item_data_table, + **crystal_heart_item_data_table, + **interactable_item_data_table} + + +def generate_item_table() -> dict[str, int]: + return {name: data.code for name, data in generate_item_data_table().items() if data.code is not None} + + +def generate_item_groups() -> dict[str, list[str]]: + item_groups: dict[str, list[str]] = { + "Collectables": list(collectable_item_data_table.keys()), + "Traps": list(trap_item_data_table.keys()), + "Checkpoints": list(checkpoint_item_data_table.keys()), + "Keys": list(key_item_data_table.keys()), + "Gems": list(gem_item_data_table.keys()), + "Cassettes": list(cassette_item_data_table.keys()), + "Crystal Hearts": list(crystal_heart_item_data_table.keys()), + "Interactables": list(interactable_item_data_table.keys()), + + # Commonly mistaken names + "Green Boosters": [ItemName.blue_boosters], + "Green Bubbles": [ItemName.blue_boosters], + "Blue Bubbles": [ItemName.blue_boosters], + "Red Bubbles": [ItemName.red_boosters], + "Touch Switches": [ItemName.coins], + } + + return item_groups diff --git a/worlds/celeste_open_world/Levels.py b/worlds/celeste_open_world/Levels.py new file mode 100644 index 000000000000..1f846bbe57a2 --- /dev/null +++ b/worlds/celeste_open_world/Levels.py @@ -0,0 +1,208 @@ +from __future__ import annotations +from enum import IntEnum + +from BaseClasses import CollectionState + + +goal_area_option_to_name: dict[int, str] = { + 0: "7a", + 1: "7b", + 2: "7c", + 3: "9a", + 4: "9b", + 5: "9c", + 6: "10a", + 7: "10b", + 8: "10c", +} + + +goal_area_option_to_display_name: dict[int, str] = { + 0: "The Summit A", + 1: "The Summit B", + 2: "The Summit C", + 3: "Core A", + 4: "Core B", + 5: "Core C", + 6: "Farewell", + 7: "Farewell", + 8: "Farewell", +} + +goal_area_to_location_name: dict[str, str] = { + "7a": "The Summit A - Level Clear", + "7b": "The Summit B - Level Clear", + "7c": "The Summit C - Level Clear", + "9a": "Core A - Level Clear", + "9b": "Core B - Level Clear", + "9c": "Core C - Level Clear", + "10a": "Farewell - Crystal Heart?", + "10b": "Farewell - Level Clear", + "10c": "Farewell - Golden Strawberry", +} + + +class LocationType(IntEnum): + strawberry = 0 + golden_strawberry = 1 + cassette = 2 + crystal_heart = 3 + checkpoint = 4 + level_clear = 5 + key = 6 + binoculars = 7 + room_enter = 8 + clutter = 9 + gem = 10 + car = 11 + +class DoorDirection(IntEnum): + up = 0 + right = 1 + down = 2 + left = 3 + special = 4 + + +class Door: + name: str + room_name: str + room: Room + dir: DoorDirection + blocked: bool + closes_behind: bool + region: PreRegion + + def __init__(self, name: str, room_name: str, dir: DoorDirection, blocked: bool, closes_behind: bool): + self.name = name + self.room_name = room_name + self.dir = dir + self.blocked = blocked + self.closes_behind = closes_behind + # Find PreRegion later using our name once we know it exists + + +class PreRegion: + name: str + room_name: str + room: Room + connections: list[RegionConnection] + locations: list[LevelLocation] + + def __init__(self, name: str, room_name: str, connections: list[RegionConnection], locations: list[LevelLocation]): + self.name = name + self.room_name = room_name + self.connections = connections.copy() + self.locations = locations.copy() + + for loc in self.locations: + loc.region = self + + +class RegionConnection: + source_name: str + source: PreRegion + destination_name: str + destination: PreRegion + possible_access: list[list[str]] + + def __init__(self, source_name: str, destination_name: str, possible_access: list[list[str]] = []): + self.source_name = source_name + self.destination_name = destination_name + self.possible_access = possible_access.copy() + + +class LevelLocation: + name: str + display_name: str + region_name: str + region: PreRegion + loc_type: LocationType + possible_access: list[list[str]] + + def __init__(self, name: str, display_name: str, region_name: str, loc_type: LocationType, possible_access: list[list[str]] = []): + self.name = name + self.display_name = display_name + self.region_name = region_name + self.loc_type = loc_type + self.possible_access = possible_access.copy() + +class Room: + level_name: str + name: str + display_name: str + regions: list[PreRegion] + doors: list[Door] + checkpoint: str + checkpoint_region: str + + def __init__(self, level_name: str, name: str, display_name: str, regions: list[PreRegion], doors: list[Door], checkpoint: str = None, checkpoint_region: str = None): + self.level_name = level_name + self.name = name + self.display_name = display_name + self.regions = regions.copy() + self.doors = doors.copy() + self.checkpoint = checkpoint + self.checkpoint_region = checkpoint_region + + from .data.CelesteLevelData import all_regions + + for reg in self.regions: + reg.room = self + + for reg_con in reg.connections: + reg_con.source = reg + reg_con.destination = all_regions[reg_con.destination_name] + + for door in self.doors: + door.room = self + + +class RoomConnection: + level_name: str + source: Door + dest: Door + two_way: bool + + def __init__(self, level_name: str, source: Door, dest: Door): + self.level_name = level_name + self.source = source + self.dest = dest + self.two_way = not self.dest.closes_behind + + if (self.source.dir == DoorDirection.left and self.dest.dir != DoorDirection.right or + self.source.dir == DoorDirection.right and self.dest.dir != DoorDirection.left or + self.source.dir == DoorDirection.up and self.dest.dir != DoorDirection.down or + self.source.dir == DoorDirection.down and self.dest.dir != DoorDirection.up): + raise Exception(f"Door {source.name} ({self.source.dir}) and Door {dest.name} ({self.dest.dir}) have mismatched directions.") + + +class Level: + name: str + display_name: str + rooms: list[Room] + room_connections: list[RoomConnection] + + def __init__(self, name: str, display_name: str, rooms: list[Room], room_connections: list[RoomConnection]): + self.name = name + self.display_name = display_name + self.rooms = rooms.copy() + self.room_connections = room_connections.copy() + + +def load_logic_data() -> dict[str, Level]: + from .data.CelesteLevelData import all_levels + + #for _, level in all_levels.items(): + # print(level.display_name) + # + # for room in level.rooms: + # print(" " + room.display_name) + # + # for region in room.regions: + # print(" " + region.name) + # + # for location in region.locations: + # print(" " + location.display_name) + + return all_levels diff --git a/worlds/celeste_open_world/Locations.py b/worlds/celeste_open_world/Locations.py new file mode 100644 index 000000000000..01ce53366680 --- /dev/null +++ b/worlds/celeste_open_world/Locations.py @@ -0,0 +1,281 @@ +from typing import NamedTuple, Optional, TYPE_CHECKING + +from BaseClasses import Location, Region +from worlds.generic.Rules import set_rule + +from .Levels import Level, LocationType +from .Names import ItemName + +if TYPE_CHECKING: + from . import CelesteOpenWorld +else: + CelesteOpenWorld = object + + +celeste_base_id: int = 0xCA10000 + + +class CelesteLocation(Location): + game = "Celeste" + + +class CelesteLocationData(NamedTuple): + region: str + address: Optional[int] = None + + +checkpoint_location_data_table: dict[str, CelesteLocationData] = {} +key_location_data_table: dict[str, CelesteLocationData] = {} + +location_id_offsets: dict[LocationType, int | None] = { + LocationType.strawberry: celeste_base_id, + LocationType.golden_strawberry: celeste_base_id + 0x1000, + LocationType.cassette: celeste_base_id + 0x2000, + LocationType.car: celeste_base_id + 0x2A00, + LocationType.crystal_heart: celeste_base_id + 0x3000, + LocationType.checkpoint: celeste_base_id + 0x4000, + LocationType.level_clear: celeste_base_id + 0x5000, + LocationType.key: celeste_base_id + 0x6000, + LocationType.gem: celeste_base_id + 0x6A00, + LocationType.binoculars: celeste_base_id + 0x7000, + LocationType.room_enter: celeste_base_id + 0x8000, + LocationType.clutter: None, +} + + +def generate_location_table() -> dict[str, int]: + from .Levels import Level, LocationType, load_logic_data + level_data: dict[str, Level] = load_logic_data() + location_table = {} + + location_counts: dict[LocationType, int] = { + LocationType.strawberry: 0, + LocationType.golden_strawberry: 0, + LocationType.cassette: 0, + LocationType.car: 0, + LocationType.crystal_heart: 0, + LocationType.checkpoint: 0, + LocationType.level_clear: 0, + LocationType.key: 0, + LocationType.gem: 0, + LocationType.binoculars: 0, + LocationType.room_enter: 0, + } + + for _, level in level_data.items(): + for room in level.rooms: + if room.name != "10b_GOAL": + location_table[room.display_name] = location_id_offsets[LocationType.room_enter] + location_counts[LocationType.room_enter] + location_counts[LocationType.room_enter] += 1 + + if room.checkpoint is not None and room.checkpoint != "Start": + checkpoint_id: int = location_id_offsets[LocationType.checkpoint] + location_counts[LocationType.checkpoint] + checkpoint_name: str = level.display_name + " - " + room.checkpoint + location_table[checkpoint_name] = checkpoint_id + location_counts[LocationType.checkpoint] += 1 + checkpoint_location_data_table[checkpoint_name] = CelesteLocationData(level.display_name, checkpoint_id) + + from .Items import add_checkpoint_to_table + add_checkpoint_to_table(checkpoint_id, checkpoint_name) + + for region in room.regions: + for location in region.locations: + if location_id_offsets[location.loc_type] is not None: + location_id = location_id_offsets[location.loc_type] + location_counts[location.loc_type] + location_table[location.display_name] = location_id + location_counts[location.loc_type] += 1 + + if location.loc_type == LocationType.key: + from .Items import add_key_to_table + add_key_to_table(location_id, location.display_name) + + if location.loc_type == LocationType.gem: + from .Items import add_gem_to_table + add_gem_to_table(location_id, location.display_name) + + return location_table + + +def create_regions_and_locations(world: CelesteOpenWorld): + menu_region = Region("Menu", world.player, world.multiworld) + world.multiworld.regions.append(menu_region) + + world.active_checkpoint_names: list[str] = [] + world.goal_checkpoint_names: dict[str, str] = dict() + world.active_key_names: list[str] = [] + world.active_gem_names: list[str] = [] + world.active_clutter_names: list[str] = [] + + for _, level in world.level_data.items(): + if level.name not in world.active_levels: + continue + + for room in level.rooms: + room_region = Region(room.name + "_room", world.player, world.multiworld) + world.multiworld.regions.append(room_region) + + for pre_region in room.regions: + region = Region(pre_region.name, world.player, world.multiworld) + world.multiworld.regions.append(region) + + for level_location in pre_region.locations: + if level_location.loc_type == LocationType.golden_strawberry: + if level_location.display_name == "Farewell - Golden Strawberry": + if not world.options.goal_area == "farewell_golden": + continue + elif not world.options.include_goldens: + continue + + if level_location.loc_type == LocationType.car and not world.options.carsanity: + continue + + if level_location.loc_type == LocationType.binoculars and not world.options.binosanity: + continue + + if level_location.loc_type == LocationType.key: + world.active_key_names.append(level_location.display_name) + + if level_location.loc_type == LocationType.gem: + world.active_gem_names.append(level_location.display_name) + + location_rule = None + if len(level_location.possible_access) == 1: + only_access = level_location.possible_access[0] + if len(only_access) == 1: + only_item = level_location.possible_access[0][0] + def location_rule_func(state, only_item=only_item): + return state.has(only_item, world.player) + location_rule = location_rule_func + else: + def location_rule_func(state, only_access=only_access): + return state.has_all(only_access, world.player) + location_rule = location_rule_func + elif len(level_location.possible_access) > 0: + def location_rule_func(state, level_location=level_location): + for sublist in level_location.possible_access: + if state.has_all(sublist, world.player): + return True + return False + location_rule = location_rule_func + + if level_location.loc_type == LocationType.clutter: + world.active_clutter_names.append(level_location.display_name) + location = CelesteLocation(world.player, level_location.display_name, None, region) + if location_rule is not None: + set_rule(location, location_rule) + region.locations.append(location) + continue + + location = CelesteLocation(world.player, level_location.display_name, world.location_name_to_id[level_location.display_name], region) + if location_rule is not None: + set_rule(location, location_rule) + region.locations.append(location) + + for pre_region in room.regions: + region = world.get_region(pre_region.name) + for connection in pre_region.connections: + connection_rule = None + if len(connection.possible_access) == 1: + only_access = connection.possible_access[0] + if len(only_access) == 1: + only_item = connection.possible_access[0][0] + def connection_rule_func(state, only_item=only_item): + return state.has(only_item, world.player) + connection_rule = connection_rule_func + else: + def connection_rule_func(state, only_access=only_access): + return state.has_all(only_access, world.player) + connection_rule = connection_rule_func + elif len(connection.possible_access) > 0: + def connection_rule_func(state, connection=connection): + for sublist in connection.possible_access: + if state.has_all(sublist, world.player): + return True + return False + + connection_rule = connection_rule_func + + if connection_rule is None: + region.add_exits([connection.destination_name]) + else: + region.add_exits([connection.destination_name], {connection.destination_name: connection_rule}) + region.add_exits([room_region.name]) + + if room.checkpoint != None: + if room.checkpoint == "Start": + if world.options.lock_goal_area and (level.name == world.goal_area or (level.name[:2] == world.goal_area[:2] == "10")): + world.goal_start_region: str = room.checkpoint_region + elif level.name == "8a": + world.epilogue_start_region: str = room.checkpoint_region + else: + menu_region.add_exits([room.checkpoint_region]) + else: + checkpoint_location_name = level.display_name + " - " + room.checkpoint + world.active_checkpoint_names.append(checkpoint_location_name) + checkpoint_rule = lambda state, checkpoint_location_name=checkpoint_location_name: state.has(checkpoint_location_name, world.player) + room_region.add_locations({ + checkpoint_location_name: world.location_name_to_id[checkpoint_location_name] + }, CelesteLocation) + + if world.options.lock_goal_area and (level.name == world.goal_area or (level.name[:2] == world.goal_area[:2] == "10")): + world.goal_checkpoint_names[room.checkpoint_region] = checkpoint_location_name + else: + menu_region.add_exits([room.checkpoint_region], {room.checkpoint_region: checkpoint_rule}) + + if world.options.roomsanity: + if room.name != "10b_GOAL": + room_location_name = room.display_name + room_region.add_locations({ + room_location_name: world.location_name_to_id[room_location_name] + }, CelesteLocation) + + for room_connection in level.room_connections: + source_region = world.get_region(room_connection.source.name) + source_region.add_exits([room_connection.dest.name]) + if room_connection.two_way: + dest_region = world.get_region(room_connection.dest.name) + dest_region.add_exits([room_connection.source.name]) + + if level.name == "10b": + # Manually connect the two parts of Farewell + source_region = world.get_region("10a_e-08_east") + source_region.add_exits(["10b_f-door_west"]) + + if level.name == "10c": + # Manually connect the Golden room of Farewell + golden_items: list[str] = [ItemName.traffic_blocks, ItemName.dash_refills, ItemName.double_dash_refills, ItemName.dream_blocks, ItemName.swap_blocks, ItemName.move_blocks, ItemName.blue_boosters, ItemName.springs, ItemName.feathers, ItemName.coins, ItemName.red_boosters, ItemName.kevin_blocks, ItemName.core_blocks, ItemName.fire_ice_balls, ItemName.badeline_boosters, ItemName.bird, ItemName.breaker_boxes, ItemName.pufferfish, ItemName.jellyfish, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.yellow_cassette_blocks, ItemName.green_cassette_blocks] + golden_rule = lambda state: state.has_all(golden_items, world.player) + + source_region_end = world.get_region("10b_j-19_top") + source_region_end.add_exits(["10c_end-golden_bottom"], {"10c_end-golden_bottom": golden_rule}) + source_region_moon = world.get_region("10b_j-16_east") + source_region_moon.add_exits(["10c_end-golden_bottom"], {"10c_end-golden_bottom": golden_rule}) + source_region_golden = world.get_region("10c_end-golden_top") + source_region_golden.add_exits(["10b_GOAL_main"]) + + +location_data_table: dict[str, int] = generate_location_table() + + +def generate_location_groups() -> dict[str, list[str]]: + from .Levels import Level, LocationType, load_logic_data + level_data: dict[str, Level] = load_logic_data() + + location_groups: dict[str, list[str]] = { + "Strawberries": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.strawberry] and id < location_id_offsets[LocationType.golden_strawberry]], + "Golden Strawberries": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.golden_strawberry] and id < location_id_offsets[LocationType.cassette]], + "Cassettes": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.cassette] and id < location_id_offsets[LocationType.car]], + "Cars": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.car] and id < location_id_offsets[LocationType.crystal_heart]], + "Crystal Hearts": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.crystal_heart] and id < location_id_offsets[LocationType.checkpoint]], + "Checkpoints": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.checkpoint] and id < location_id_offsets[LocationType.level_clear]], + "Level Clears": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.level_clear] and id < location_id_offsets[LocationType.key]], + "Keys": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.key] and id < location_id_offsets[LocationType.gem]], + "Gems": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.gem] and id < location_id_offsets[LocationType.binoculars]], + "Binoculars": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.binoculars] and id < location_id_offsets[LocationType.room_enter]], + "Rooms": [name for name, id in location_data_table.items() if id >= location_id_offsets[LocationType.room_enter]], + } + + for level in level_data.values(): + location_groups.update({level.display_name: [loc_name for loc_name, id in location_data_table.items() if level.display_name in loc_name]}) + + return location_groups diff --git a/worlds/celeste_open_world/Names/ItemName.py b/worlds/celeste_open_world/Names/ItemName.py new file mode 100644 index 000000000000..93b57dde9da8 --- /dev/null +++ b/worlds/celeste_open_world/Names/ItemName.py @@ -0,0 +1,210 @@ +# Collectables +strawberry = "Strawberry" +raspberry = "Raspberry" + +# Goal Items +house_keys = "Granny's House Keys" +victory = "Victory" + +# Traps +bald_trap = "Bald Trap" +literature_trap = "Literature Trap" +stun_trap = "Stun Trap" +invisible_trap = "Invisible Trap" +fast_trap = "Fast Trap" +slow_trap = "Slow Trap" +ice_trap = "Ice Trap" +reverse_trap = "Reverse Trap" +screen_flip_trap = "Screen Flip Trap" +laughter_trap = "Laughter Trap" +hiccup_trap = "Hiccup Trap" +zoom_trap = "Zoom Trap" + +# Movement +dash = "Dash" +u_dash = "Up Dash" +r_dash = "Right Dash" +d_dash = "Down Dash" +l_dash = "Left Dash" +ur_dash = "Up-Right Dash" +dr_dash = "Down-Right Dash" +dl_dash = "Down-Left Dash" +ul_dash = "Up-Left Dash" + +# Interactables +springs = "Springs" +traffic_blocks = "Traffic Blocks" +pink_cassette_blocks = "Pink Cassette Blocks" +blue_cassette_blocks = "Blue Cassette Blocks" + +dream_blocks = "Dream Blocks" +coins = "Coins" +strawberry_seeds = "Strawberry Seeds" + +sinking_platforms = "Sinking Platforms" + +moving_platforms = "Moving Platforms" +blue_boosters = "Blue Boosters" +blue_clouds = "Blue Clouds" +move_blocks = "Move Blocks" +white_block = "White Block" + +swap_blocks = "Swap Blocks" +red_boosters = "Red Boosters" +torches = "Torches" +theo_crystal = "Theo Crystal" + +feathers = "Feathers" +bumpers = "Bumpers" +kevin_blocks = "Kevins" + +pink_clouds = "Pink Clouds" +badeline_boosters = "Badeline Boosters" + +fire_ice_balls = "Fire and Ice Balls" +core_toggles = "Core Toggles" +core_blocks = "Core Blocks" + +pufferfish = "Pufferfish" +jellyfish = "Jellyfish" +breaker_boxes = "Breaker Boxes" +dash_refills = "Dash Refills" +double_dash_refills = "Double Dash Refills" +yellow_cassette_blocks = "Yellow Cassette Blocks" +green_cassette_blocks = "Green Cassette Blocks" + +dash_switches = "Dash Switches" +seekers = "Seekers" +bird = "Bird" + +brown_clutter = "Celestial Resort A - Brown Clutter" +green_clutter = "Celestial Resort A - Green Clutter" +pink_clutter = "Celestial Resort A - Pink Clutter" + +cannot_access = "Cannot Access" + +# Checkpoints +fc_a_checkpoint_1 = "Forsaken City A - Crossing" +fc_a_checkpoint_2 = "Forsaken City A - Chasm" + +fc_b_checkpoint_1 = "Forsaken City B - Contraption" +fc_b_checkpoint_2 = "Forsaken City B - Scrap Pit" + +os_a_checkpoint_1 = "Old Site A - Intervention" +os_a_checkpoint_2 = "Old Site A - Awake" + +os_b_checkpoint_1 = "Old Site B - Combination Lock" +os_b_checkpoint_2 = "Old Site B - Dream Altar" + +cr_a_checkpoint_1 = "Celestial Resort A - Huge Mess" +cr_a_checkpoint_2 = "Celestial Resort A - Elevator Shaft" +cr_a_checkpoint_3 = "Celestial Resort A - Presidential Suite" + +cr_b_checkpoint_1 = "Celestial Resort B - Staff Quarters" +cr_b_checkpoint_2 = "Celestial Resort B - Library" +cr_b_checkpoint_3 = "Celestial Resort B - Rooftop" + +gr_a_checkpoint_1 = "Golden Ridge A - Shrine" +gr_a_checkpoint_2 = "Golden Ridge A - Old Trail" +gr_a_checkpoint_3 = "Golden Ridge A - Cliff Face" + +gr_b_checkpoint_1 = "Golden Ridge B - Stepping Stones" +gr_b_checkpoint_2 = "Golden Ridge B - Gusty Canyon" +gr_b_checkpoint_3 = "Golden Ridge B - Eye of the Storm" + +mt_a_checkpoint_1 = "Mirror Temple A - Depths" +mt_a_checkpoint_2 = "Mirror Temple A - Unravelling" +mt_a_checkpoint_3 = "Mirror Temple A - Search" +mt_a_checkpoint_4 = "Mirror Temple A - Rescue" + +mt_b_checkpoint_1 = "Mirror Temple B - Central Chamber" +mt_b_checkpoint_2 = "Mirror Temple B - Through the Mirror" +mt_b_checkpoint_3 = "Mirror Temple B - Mix Master" + +ref_a_checkpoint_1 = "Reflection A - Lake" +ref_a_checkpoint_2 = "Reflection A - Hollows" +ref_a_checkpoint_3 = "Reflection A - Reflection" +ref_a_checkpoint_4 = "Reflection A - Rock Bottom" +ref_a_checkpoint_5 = "Reflection A - Resolution" + +ref_b_checkpoint_1 = "Reflection B - Reflection" +ref_b_checkpoint_2 = "Reflection B - Rock Bottom" +ref_b_checkpoint_3 = "Reflection B - Reprieve" + +sum_a_checkpoint_1 = "The Summit A - 500 M" +sum_a_checkpoint_2 = "The Summit A - 1000 M" +sum_a_checkpoint_3 = "The Summit A - 1500 M" +sum_a_checkpoint_4 = "The Summit A - 2000 M" +sum_a_checkpoint_5 = "The Summit A - 2500 M" +sum_a_checkpoint_6 = "The Summit A - 3000 M" + +sum_b_checkpoint_1 = "The Summit B - 500 M" +sum_b_checkpoint_2 = "The Summit B - 1000 M" +sum_b_checkpoint_3 = "The Summit B - 1500 M" +sum_b_checkpoint_4 = "The Summit B - 2000 M" +sum_b_checkpoint_5 = "The Summit B - 2500 M" +sum_b_checkpoint_6 = "The Summit B - 3000 M" + +core_a_checkpoint_1 = "Core A - Into the Core" +core_a_checkpoint_2 = "Core A - Hot and Cold" +core_a_checkpoint_3 = "Core A - Heart of the Mountain" + +core_b_checkpoint_1 = "Core B - Into the Core" +core_b_checkpoint_2 = "Core B - Burning or Freezing" +core_b_checkpoint_3 = "Core B - Heartbeat" + +farewell_checkpoint_1 = "Farewell - Singular" +farewell_checkpoint_2 = "Farewell - Power Source" +farewell_checkpoint_3 = "Farewell - Remembered" +farewell_checkpoint_4 = "Farewell - Event Horizon" +farewell_checkpoint_5 = "Farewell - Determination" +farewell_checkpoint_6 = "Farewell - Stubbornness" +farewell_checkpoint_7 = "Farewell - Reconcilliation" +farewell_checkpoint_8 = "Farewell - Farewell" + +# Cassettes +prologue_cassette = "Prologue Cassette" +fc_a_cassette = "Forsaken City Cassette - A Side" +fc_b_cassette = "Forsaken City Cassette - B Side" +fc_c_cassette = "Forsaken City Cassette - C Side" +os_a_cassette = "Old Site Cassette - A Side" +os_b_cassette = "Old Site Cassette - B Side" +os_c_cassette = "Old Site Cassette - C Side" +cr_a_cassette = "Celestial Resort Cassette - A Side" +cr_b_cassette = "Celestial Resort Cassette - B Side" +cr_c_cassette = "Celestial Resort Cassette - C Side" +gr_a_cassette = "Golden Ridge Cassette - A Side" +gr_b_cassette = "Golden Ridge Cassette - B Side" +gr_c_cassette = "Golden Ridge Cassette - C Side" +mt_a_cassette = "Mirror Temple Cassette - A Side" +mt_b_cassette = "Mirror Temple Cassette - B Side" +mt_c_cassette = "Mirror Temple Cassette - C Side" +ref_a_cassette = "Reflection Cassette - A Side" +ref_b_cassette = "Reflection Cassette - B Side" +ref_c_cassette = "Reflection Cassette - C Side" +sum_a_cassette = "The Summit Cassette - A Side" +sum_b_cassette = "The Summit Cassette - B Side" +sum_c_cassette = "The Summit Cassette - C Side" +epilogue_cassette = "Epilogue Cassette" +core_a_cassette = "Core Cassette - A Side" +core_b_cassette = "Core Cassette - B Side" +core_c_cassette = "Core Cassette - C Side" +farewell_cassette = "Farewell Cassette" + +# Crystal Hearts +crystal_heart_1 = "Crystal Heart 1" +crystal_heart_2 = "Crystal Heart 2" +crystal_heart_3 = "Crystal Heart 3" +crystal_heart_4 = "Crystal Heart 4" +crystal_heart_5 = "Crystal Heart 5" +crystal_heart_6 = "Crystal Heart 6" +crystal_heart_7 = "Crystal Heart 7" +crystal_heart_8 = "Crystal Heart 8" +crystal_heart_9 = "Crystal Heart 9" +crystal_heart_10 = "Crystal Heart 10" +crystal_heart_11 = "Crystal Heart 11" +crystal_heart_12 = "Crystal Heart 12" +crystal_heart_13 = "Crystal Heart 13" +crystal_heart_14 = "Crystal Heart 14" +crystal_heart_15 = "Crystal Heart 15" +crystal_heart_16 = "Crystal Heart 16" diff --git a/worlds/celeste_open_world/Names/__init__.py b/worlds/celeste_open_world/Names/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/worlds/celeste_open_world/Options.py b/worlds/celeste_open_world/Options.py new file mode 100644 index 000000000000..75e8928a294f --- /dev/null +++ b/worlds/celeste_open_world/Options.py @@ -0,0 +1,528 @@ +from dataclasses import dataclass +import random + +from Options import Choice, Range, DefaultOnToggle, Toggle, TextChoice, DeathLink, OptionGroup, PerGameCommonOptions, OptionError +from worlds.AutoWorld import World + + +class DeathLinkAmnesty(Range): + """ + How many deaths it takes to send a DeathLink + """ + display_name = "Death Link Amnesty" + range_start = 1 + range_end = 30 + default = 10 + +class TrapLink(Toggle): + """ + Whether your received traps are linked to other players + + You will also receive any linked traps from other players with Trap Link enabled, + if you have a weight above "none" set for that trap + """ + display_name = "Trap Link" + + +class GoalArea(Choice): + """ + What Area must be cleared to gain access to the Epilogue and complete the game + """ + display_name = "Goal Area" + option_the_summit_a = 0 + option_the_summit_b = 1 + option_the_summit_c = 2 + option_core_a = 3 + option_core_b = 4 + option_core_c = 5 + option_empty_space = 6 + option_farewell = 7 + option_farewell_golden = 8 + default = 0 + +class LockGoalArea(DefaultOnToggle): + """ + Determines whether your Goal Area will be locked until you receive your required Strawberries, or only the Epilogue + """ + display_name = "Lock Goal Area" + +class GoalAreaCheckpointsanity(Toggle): + """ + Determines whether the Checkpoints in your Goal Area will be shuffled into the item pool (if Checkpointsanity is active) + """ + display_name = "Goal Area Checkpointsanity" + +class TotalStrawberries(Range): + """ + Maximum number of how many Strawberries can exist + """ + display_name = "Total Strawberries" + range_start = 0 + range_end = 202 + default = 50 + +class StrawberriesRequiredPercentage(Range): + """ + Percentage of existing Strawberries you must receive to access your Goal Area (if Lock Goal Area is active) and the Epilogue + """ + display_name = "Strawberries Required Percentage" + range_start = 0 + range_end = 100 + default = 80 + + +class Checkpointsanity(Toggle): + """ + Determines whether Checkpoints will be shuffled into the item pool + """ + display_name = "Checkpointsanity" + +class Binosanity(Toggle): + """ + Determines whether using Binoculars sends location checks + """ + display_name = "Binosanity" + +class Keysanity(Toggle): + """ + Determines whether individual Keys are shuffled into the item pool + """ + display_name = "Keysanity" + +class Gemsanity(Toggle): + """ + Determines whether Summit Gems are shuffled into the item pool + """ + display_name = "Gemsanity" + +class Carsanity(Toggle): + """ + Determines whether riding on cars grants location checks + """ + display_name = "Carsanity" + +class Roomsanity(Toggle): + """ + Determines whether entering individual rooms sends location checks + """ + display_name = "Roomsanity" + +class IncludeGoldens(Toggle): + """ + Determines whether collecting Golden Strawberries sends location checks + """ + display_name = "Include Goldens" + + +class IncludeCore(Toggle): + """ + Determines whether Chapter 8 - Core Levels will be included + """ + display_name = "Include Core" + +class IncludeFarewell(Choice): + """ + Determines how much of Chapter 9 - Farewell Level will be included + """ + display_name = "Include Farewell" + option_none = 0 + option_empty_space = 1 + option_farewell = 2 + default = 0 + +class IncludeBSides(Toggle): + """ + Determines whether the B-Side Levels will be included + """ + display_name = "Include B-Sides" + +class IncludeCSides(Toggle): + """ + Determines whether the C-Side Levels will be included + """ + display_name = "Include C-Sides" + + +class JunkFillPercentage(Range): + """ + Replace a percentage of non-required Strawberries in the item pool with junk items + """ + display_name = "Junk Fill Percentage" + range_start = 0 + range_end = 100 + default = 50 + +class TrapFillPercentage(Range): + """ + Replace a percentage of junk items in the item pool with random traps + """ + display_name = "Trap Fill Percentage" + range_start = 0 + range_end = 100 + default = 0 + +class TrapExpirationAction(Choice): + """ + The type of action which causes traps to wear off + """ + display_name = "Trap Expiration Action" + option_return_to_menu = 0 + option_deaths = 1 + option_new_screens = 2 + default = 1 + +class TrapExpirationAmount(Range): + """ + The amount of the selected Trap Expiration Action that must occur for the trap to wear off + """ + display_name = "Trap Expiration Amount" + range_start = 1 + range_end = 10 + default = 5 + +class BaseTrapWeight(Choice): + """ + Base Class for Trap Weights + """ + option_none = 0 + option_low = 1 + option_medium = 2 + option_high = 4 + default = 2 + +class BaldTrapWeight(BaseTrapWeight): + """ + Likelihood of receiving a trap which makes Maddy bald + """ + display_name = "Bald Trap Weight" + +class LiteratureTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which causes the player to read literature + """ + display_name = "Literature Trap Weight" + +class StunTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which briefly stuns Maddy + """ + display_name = "Stun Trap Weight" + +class InvisibleTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which turns Maddy invisible + """ + display_name = "Invisible Trap Weight" + +class FastTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which increases the game speed + """ + display_name = "Fast Trap Weight" + +class SlowTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which decreases the game speed + """ + display_name = "Slow Trap Weight" + +class IceTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which causes the level to become slippery + """ + display_name = "Ice Trap Weight" + +class ReverseTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which causes the controls to be reversed + """ + display_name = "Reverse Trap Weight" + +class ScreenFlipTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which causes the screen to be flipped + """ + display_name = "Screen Flip Trap Weight" + +class LaughterTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which causes Maddy to laugh uncontrollably + """ + display_name = "Laughter Trap Weight" + +class HiccupTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which causes Maddy to hiccup uncontrollably + """ + display_name = "Hiccup Trap Weight" + +class ZoomTrapWeight(BaseTrapWeight): + """ + Likelihood of a receiving a trap which causes the camera to focus on Maddy + """ + display_name = "Zoom Trap Weight" + + +class MusicShuffle(Choice): + """ + Music shuffle type + + None: No Music is shuffled + + Consistent: Each music track is consistently shuffled throughout the game + + Singularity: The entire game uses one song for levels + """ + display_name = "Music Shuffle" + option_none = 0 + option_consistent = 1 + option_singularity = 2 + default = 0 + +class RequireCassettes(Toggle): + """ + Determines whether you must receive a level's Cassette Item to hear that level's music + """ + display_name = "Require Cassettes" + + +class MadelineHairLength(Choice): + """ + How long Madeline's hair is + """ + display_name = "Madeline Hair Length" + option_very_short = 1 + option_short = 2 + option_default = 4 + option_long = 7 + option_very_long = 10 + option_absurd = 20 + default = 4 + + +class ColorChoice(TextChoice): + option_strawberry = 0xAC3232 + option_empty = 0x44B7FF + option_double = 0xFF6DEF + option_golden = 0xFFD65C + option_baddy = 0x9B3FB5 + option_fire_red = 0xFF0000 + option_maroon = 0x800000 + option_salmon = 0xFF3A65 + option_orange = 0xD86E0A + option_lime_green = 0x8DF920 + option_bright_green = 0x0DAF05 + option_forest_green = 0x132818 + option_royal_blue = 0x0036BF + option_brown = 0xB78726 + option_black = 0x000000 + option_white = 0xFFFFFF + option_grey = 0x808080 + option_any_color = -1 + + @classmethod + def from_text(cls, text: str) -> Choice: + text = text.lower() + if text == "random": + choice_list = list(cls.name_lookup) + choice_list.remove(cls.option_any_color) + return cls(random.choice(choice_list)) + return super().from_text(text) + + +class MadelineOneDashHairColor(ColorChoice): + """ + What color Madeline's hair is when she has one dash + The `any_color` option will choose a fully random color + A custom color entry may be supplied as a 6-character RGB hex color code + e.g. F542C8 + """ + display_name = "Madeline One Dash Hair Color" + default = ColorChoice.option_strawberry + +class MadelineTwoDashHairColor(ColorChoice): + """ + What color Madeline's hair is when she has two dashes + The `any_color` option will choose a fully random color + A custom color entry may be supplied as a 6-character RGB hex color code + e.g. F542C8 + """ + display_name = "Madeline Two Dash Hair Color" + default = ColorChoice.option_double + +class MadelineNoDashHairColor(ColorChoice): + """ + What color Madeline's hair is when she has no dashes + The `any_color` option will choose a fully random color + A custom color entry may be supplied as a 6-character RGB hex color code + e.g. F542C8 + """ + display_name = "Madeline No Dash Hair Color" + default = ColorChoice.option_empty + +class MadelineFeatherHairColor(ColorChoice): + """ + What color Madeline's hair is when she has a feather + The `any_color` option will choose a fully random color + A custom color entry may be supplied as a 6-character RGB hex color code + e.g. F542C8 + """ + display_name = "Madeline Feather Hair Color" + default = ColorChoice.option_golden + + + +celeste_option_groups = [ + OptionGroup("Goal Options", [ + GoalArea, + LockGoalArea, + GoalAreaCheckpointsanity, + TotalStrawberries, + StrawberriesRequiredPercentage, + ]), + OptionGroup("Location Options", [ + Checkpointsanity, + Binosanity, + Keysanity, + Gemsanity, + Carsanity, + Roomsanity, + IncludeGoldens, + IncludeCore, + IncludeFarewell, + IncludeBSides, + IncludeCSides, + ]), + OptionGroup("Junk and Traps", [ + JunkFillPercentage, + TrapFillPercentage, + TrapExpirationAction, + TrapExpirationAmount, + BaldTrapWeight, + LiteratureTrapWeight, + StunTrapWeight, + InvisibleTrapWeight, + FastTrapWeight, + SlowTrapWeight, + IceTrapWeight, + ReverseTrapWeight, + ScreenFlipTrapWeight, + LaughterTrapWeight, + HiccupTrapWeight, + ZoomTrapWeight, + ]), + OptionGroup("Aesthetic Options", [ + MusicShuffle, + RequireCassettes, + MadelineHairLength, + MadelineOneDashHairColor, + MadelineTwoDashHairColor, + MadelineNoDashHairColor, + MadelineFeatherHairColor, + ]), +] + + +def resolve_options(world: World): + # One Dash Hair + if isinstance(world.options.madeline_one_dash_hair_color.value, str): + try: + world.madeline_one_dash_hair_color = int(world.options.madeline_one_dash_hair_color.value.strip("#")[:6], 16) + except ValueError: + raise OptionError(f"Invalid input for option `madeline_one_dash_hair_color`:" + f"{world.options.madeline_one_dash_hair_color.value} for " + f"{world.player_name}") + elif world.options.madeline_one_dash_hair_color.value == ColorChoice.option_any_color: + world.madeline_one_dash_hair_color = world.random.randint(0, 0xFFFFFF) + else: + world.madeline_one_dash_hair_color = world.options.madeline_one_dash_hair_color.value + + # Two Dash Hair + if isinstance(world.options.madeline_two_dash_hair_color.value, str): + try: + world.madeline_two_dash_hair_color = int(world.options.madeline_two_dash_hair_color.value.strip("#")[:6], 16) + except ValueError: + raise OptionError(f"Invalid input for option `madeline_two_dash_hair_color`:" + f"{world.options.madeline_two_dash_hair_color.value} for " + f"{world.player_name}") + elif world.options.madeline_two_dash_hair_color.value == ColorChoice.option_any_color: + world.madeline_two_dash_hair_color = world.random.randint(0, 0xFFFFFF) + else: + world.madeline_two_dash_hair_color = world.options.madeline_two_dash_hair_color.value + + # No Dash Hair + if isinstance(world.options.madeline_no_dash_hair_color.value, str): + try: + world.madeline_no_dash_hair_color = int(world.options.madeline_no_dash_hair_color.value.strip("#")[:6], 16) + except ValueError: + raise OptionError(f"Invalid input for option `madeline_no_dash_hair_color`:" + f"{world.options.madeline_no_dash_hair_color.value} for " + f"{world.player_name}") + elif world.options.madeline_no_dash_hair_color.value == ColorChoice.option_any_color: + world.madeline_no_dash_hair_color = world.random.randint(0, 0xFFFFFF) + else: + world.madeline_no_dash_hair_color = world.options.madeline_no_dash_hair_color.value + + # Feather Hair + if isinstance(world.options.madeline_feather_hair_color.value, str): + try: + world.madeline_feather_hair_color = int(world.options.madeline_feather_hair_color.value.strip("#")[:6], 16) + except ValueError: + raise OptionError(f"Invalid input for option `madeline_feather_hair_color`:" + f"{world.options.madeline_feather_hair_color.value} for " + f"{world.player_name}") + elif world.options.madeline_feather_hair_color.value == ColorChoice.option_any_color: + world.madeline_feather_hair_color = world.random.randint(0, 0xFFFFFF) + else: + world.madeline_feather_hair_color = world.options.madeline_feather_hair_color.value + + +@dataclass +class CelesteOptions(PerGameCommonOptions): + death_link: DeathLink + death_link_amnesty: DeathLinkAmnesty + trap_link: TrapLink + + goal_area: GoalArea + lock_goal_area: LockGoalArea + goal_area_checkpointsanity: GoalAreaCheckpointsanity + total_strawberries: TotalStrawberries + strawberries_required_percentage: StrawberriesRequiredPercentage + + junk_fill_percentage: JunkFillPercentage + trap_fill_percentage: TrapFillPercentage + trap_expiration_action: TrapExpirationAction + trap_expiration_amount: TrapExpirationAmount + bald_trap_weight: BaldTrapWeight + literature_trap_weight: LiteratureTrapWeight + stun_trap_weight: StunTrapWeight + invisible_trap_weight: InvisibleTrapWeight + fast_trap_weight: FastTrapWeight + slow_trap_weight: SlowTrapWeight + ice_trap_weight: IceTrapWeight + reverse_trap_weight: ReverseTrapWeight + screen_flip_trap_weight: ScreenFlipTrapWeight + laughter_trap_weight: LaughterTrapWeight + hiccup_trap_weight: HiccupTrapWeight + zoom_trap_weight: ZoomTrapWeight + + checkpointsanity: Checkpointsanity + binosanity: Binosanity + keysanity: Keysanity + gemsanity: Gemsanity + carsanity: Carsanity + roomsanity: Roomsanity + include_goldens: IncludeGoldens + include_core: IncludeCore + include_farewell: IncludeFarewell + include_b_sides: IncludeBSides + include_c_sides: IncludeCSides + + music_shuffle: MusicShuffle + require_cassettes: RequireCassettes + + madeline_hair_length: MadelineHairLength + madeline_one_dash_hair_color: MadelineOneDashHairColor + madeline_two_dash_hair_color: MadelineTwoDashHairColor + madeline_no_dash_hair_color: MadelineNoDashHairColor + madeline_feather_hair_color: MadelineFeatherHairColor diff --git a/worlds/celeste_open_world/__init__.py b/worlds/celeste_open_world/__init__.py new file mode 100644 index 000000000000..38c3778e831c --- /dev/null +++ b/worlds/celeste_open_world/__init__.py @@ -0,0 +1,351 @@ +from copy import deepcopy +import math + +from BaseClasses import ItemClassification, Location, MultiWorld, Region, Tutorial +from Utils import visualize_regions +from worlds.AutoWorld import WebWorld, World + +from .Items import CelesteItem, generate_item_table, generate_item_data_table, generate_item_groups, level_item_lists, level_cassette_items,\ + cassette_item_data_table, crystal_heart_item_data_table, trap_item_data_table +from .Locations import CelesteLocation, location_data_table, generate_location_groups, checkpoint_location_data_table, location_id_offsets +from .Names import ItemName +from .Options import CelesteOptions, celeste_option_groups, resolve_options +from .Levels import Level, LocationType, load_logic_data, goal_area_option_to_name, goal_area_option_to_display_name, goal_area_to_location_name + + +class CelesteOpenWebWorld(WebWorld): + theme = "ice" + + setup_en = Tutorial( + tutorial_name="Start Guide", + description="A guide to playing Celeste (Open World) in Archipelago.", + language="English", + file_name="guide_en.md", + link="guide/en", + authors=["PoryGone"] + ) + + tutorials = [setup_en] + + option_groups = celeste_option_groups + + +class CelesteOpenWorld(World): + """ + Celeste (Open World) is a randomizer for the original Celeste. In this acclaimed platformer created by ExOK Games, you control Madeline as she attempts to climb the titular mountain, meeting friends and obstacles along the way. Progression is found in unlocking the ability to interact with various objects in the areas, such as springs, traffic blocks, feathers, and many more. Please be safe on the climb. + """ + + # Class Data + game = "Celeste (Open World)" + web = CelesteOpenWebWorld() + options_dataclass = CelesteOptions + options: CelesteOptions + + level_data: dict[str, Level] = load_logic_data() + + location_name_to_id: dict[str, int] = location_data_table + location_name_groups: dict[str, list[str]] = generate_location_groups() + item_name_to_id: dict[str, int] = generate_item_table() + item_name_groups: dict[str, list[str]] = generate_item_groups() + + + # Instance Data + madeline_one_dash_hair_color: int + madeline_two_dash_hair_color: int + madeline_no_dash_hair_color: int + madeline_feather_hair_color: int + + active_levels: set[str] + active_items: set[str] + + + def generate_early(self) -> None: + if not self.player_name.isascii(): + raise RuntimeError(f"Invalid player_name {self.player_name} for game {self.game}. Name must be ascii.") + + resolve_options(self) + + self.goal_area: str = goal_area_option_to_name[self.options.goal_area.value] + + self.active_levels = {"0a", "1a", "2a", "3a", "4a", "5a", "6a", "7a", "8a"} + if self.options.include_core: + self.active_levels.add("9a") + if self.options.include_farewell >= 1: + self.active_levels.add("10a") + if self.options.include_farewell == 2: + self.active_levels.add("10b") + if self.options.include_b_sides: + self.active_levels.update({"1b", "2b", "3b", "4b", "5b", "6b", "7b"}) + if self.options.include_core: + self.active_levels.add("9b") + if self.options.include_c_sides: + self.active_levels.update({"1c", "2c", "3c", "4c", "5c", "6c", "7c"}) + if self.options.include_core: + self.active_levels.add("9c") + + self.active_levels.add(self.goal_area) + if self.goal_area == "10c": + self.active_levels.add("10a") + self.active_levels.add("10b") + elif self.goal_area == "10b": + self.active_levels.add("10a") + + self.active_items = set() + for level in self.active_levels: + self.active_items.update(level_item_lists[level]) + + + def create_regions(self) -> None: + from .Locations import create_regions_and_locations + + create_regions_and_locations(self) + + + def create_item(self, name: str, force_useful: bool = False) -> CelesteItem: + item_data_table = generate_item_data_table() + + if name == ItemName.strawberry and force_useful: + return CelesteItem(name, ItemClassification.useful, item_data_table[name].code, self.player) + elif name in item_data_table: + return CelesteItem(name, item_data_table[name].type, item_data_table[name].code, self.player) + else: + return CelesteItem(name, ItemClassification.progression, None, self.player) + + def create_items(self) -> None: + item_pool: list[CelesteItem] = [] + + location_count: int = len(self.get_locations()) + goal_area_location_count: int = sum(goal_area_option_to_display_name[self.options.goal_area] in loc.name for loc in self.get_locations()) + + # Goal Items + goal_item_loc: Location = self.get_location(goal_area_to_location_name[self.goal_area]) + goal_item_loc.place_locked_item(self.create_item(ItemName.house_keys)) + location_count -= 1 + + epilogue_region: Region = self.get_region(self.epilogue_start_region) + epilogue_region.add_locations({ItemName.victory: None }, CelesteLocation) + victory_loc: Location = self.get_location(ItemName.victory) + victory_loc.place_locked_item(self.create_item(ItemName.victory)) + + # Checkpoints + for item_name in self.active_checkpoint_names: + if self.options.checkpointsanity: + if not self.options.goal_area_checkpointsanity and goal_area_option_to_display_name[self.options.goal_area] in item_name: + checkpoint_loc: Location = self.get_location(item_name) + checkpoint_loc.place_locked_item(self.create_item(item_name)) + location_count -= 1 + else: + item_pool.append(self.create_item(item_name)) + else: + checkpoint_loc: Location = self.get_location(item_name) + checkpoint_loc.place_locked_item(self.create_item(item_name)) + location_count -= 1 + + # Keys + if self.options.keysanity: + item_pool += [self.create_item(item_name) for item_name in self.active_key_names] + else: + for item_name in self.active_key_names: + key_loc: Location = self.get_location(item_name) + key_loc.place_locked_item(self.create_item(item_name)) + location_count -= 1 + + # Summit Gems + if self.options.gemsanity: + item_pool += [self.create_item(item_name) for item_name in self.active_gem_names] + else: + for item_name in self.active_gem_names: + gem_loc: Location = self.get_location(item_name) + gem_loc.place_locked_item(self.create_item(item_name)) + location_count -= 1 + + # Clutter Events + for item_name in self.active_clutter_names: + clutter_loc: Location = self.get_location(item_name) + clutter_loc.place_locked_item(self.create_item(item_name)) + location_count -= 1 + + # Interactables + item_pool += [self.create_item(item_name) for item_name in sorted(self.active_items)] + + # Strawberries + real_total_strawberries: int = min(self.options.total_strawberries.value, location_count - goal_area_location_count - len(item_pool)) + self.strawberries_required = int(real_total_strawberries * (self.options.strawberries_required_percentage / 100)) + + menu_region = self.get_region("Menu") + if getattr(self, "goal_start_region", None): + menu_region.add_exits([self.goal_start_region], {self.goal_start_region: lambda state: state.has(ItemName.strawberry, self.player, self.strawberries_required)}) + if getattr(self, "goal_checkpoint_names", None): + for region_name, location_name in self.goal_checkpoint_names.items(): + checkpoint_rule = lambda state, location_name=location_name: state.has(location_name, self.player) and state.has(ItemName.strawberry, self.player, self.strawberries_required) + menu_region.add_exits([region_name], {region_name: checkpoint_rule}) + + menu_region.add_exits([self.epilogue_start_region], {self.epilogue_start_region: lambda state: (state.has(ItemName.strawberry, self.player, self.strawberries_required) and state.has(ItemName.house_keys, self.player))}) + + item_pool += [self.create_item(ItemName.strawberry) for _ in range(self.strawberries_required)] + + # Filler and Traps + non_required_strawberries = (real_total_strawberries - self.strawberries_required) + replacement_filler_count = math.floor(non_required_strawberries * (self.options.junk_fill_percentage.value / 100.0)) + remaining_extra_strawberries = non_required_strawberries - replacement_filler_count + item_pool += [self.create_item(ItemName.strawberry, True) for _ in range(remaining_extra_strawberries)] + + trap_weights = [] + trap_weights += ([ItemName.bald_trap] * self.options.bald_trap_weight.value) + trap_weights += ([ItemName.literature_trap] * self.options.literature_trap_weight.value) + trap_weights += ([ItemName.stun_trap] * self.options.stun_trap_weight.value) + trap_weights += ([ItemName.invisible_trap] * self.options.invisible_trap_weight.value) + trap_weights += ([ItemName.fast_trap] * self.options.fast_trap_weight.value) + trap_weights += ([ItemName.slow_trap] * self.options.slow_trap_weight.value) + trap_weights += ([ItemName.ice_trap] * self.options.ice_trap_weight.value) + trap_weights += ([ItemName.reverse_trap] * self.options.reverse_trap_weight.value) + trap_weights += ([ItemName.screen_flip_trap] * self.options.screen_flip_trap_weight.value) + trap_weights += ([ItemName.laughter_trap] * self.options.laughter_trap_weight.value) + trap_weights += ([ItemName.hiccup_trap] * self.options.hiccup_trap_weight.value) + trap_weights += ([ItemName.zoom_trap] * self.options.zoom_trap_weight.value) + + total_filler_count: int = (location_count - len(item_pool)) + + # Cassettes + if self.options.require_cassettes: + shuffled_active_levels = sorted(self.active_levels) + self.random.shuffle(shuffled_active_levels) + for level_name in shuffled_active_levels: + if level_name == "10b" or level_name == "10c": + continue + if level_name not in self.multiworld.precollected_items[self.player]: + if total_filler_count > 0: + item_pool.append(self.create_item(level_cassette_items[level_name])) + total_filler_count -= 1 + else: + self.multiworld.push_precollected(self.create_item(level_cassette_items[level_name])) + + # Crystal Hearts + for name in crystal_heart_item_data_table.keys(): + if total_filler_count > 0: + if name not in self.multiworld.precollected_items[self.player]: + item_pool.append(self.create_item(name)) + total_filler_count -= 1 + + trap_count = 0 if (len(trap_weights) == 0) else math.ceil(total_filler_count * (self.options.trap_fill_percentage.value / 100.0)) + total_filler_count -= trap_count + + item_pool += [self.create_item(ItemName.raspberry) for _ in range(total_filler_count)] + + trap_pool = [] + for i in range(trap_count): + trap_item = self.random.choice(trap_weights) + trap_pool.append(self.create_item(trap_item)) + + item_pool += trap_pool + + self.multiworld.itempool += item_pool + + def get_filler_item_name(self) -> str: + return ItemName.raspberry + + + def set_rules(self) -> None: + self.multiworld.completion_condition[self.player] = lambda state: state.has(ItemName.victory, self.player) + + + def fill_slot_data(self): + return { + "apworld_version": 10004, + "min_mod_version": 10000, + + "death_link": self.options.death_link.value, + "death_link_amnesty": self.options.death_link_amnesty.value, + "trap_link": self.options.trap_link.value, + + "active_levels": self.active_levels, + "goal_area": self.goal_area, + "lock_goal_area": self.options.lock_goal_area.value, + "strawberries_required": self.strawberries_required, + + "checkpointsanity": self.options.checkpointsanity.value, + "binosanity": self.options.binosanity.value, + "keysanity": self.options.keysanity.value, + "gemsanity": self.options.gemsanity.value, + "carsanity": self.options.carsanity.value, + "roomsanity": self.options.roomsanity.value, + "include_goldens": self.options.include_goldens.value, + + "include_core": self.options.include_core.value, + "include_farewell": self.options.include_farewell.value, + "include_b_sides": self.options.include_b_sides.value, + "include_c_sides": self.options.include_c_sides.value, + + "trap_expiration_action": self.options.trap_expiration_action.value, + "trap_expiration_amount": self.options.trap_expiration_amount.value, + "active_traps": self.output_active_traps(), + + "madeline_hair_length": self.options.madeline_hair_length.value, + "madeline_one_dash_hair_color": self.madeline_one_dash_hair_color, + "madeline_two_dash_hair_color": self.madeline_two_dash_hair_color, + "madeline_no_dash_hair_color": self.madeline_no_dash_hair_color, + "madeline_feather_hair_color": self.madeline_feather_hair_color, + + "music_shuffle": self.options.music_shuffle.value, + "music_map": self.generate_music_data(), + "require_cassettes": self.options.require_cassettes.value, + "chosen_poem": self.random.randint(0, 119), + } + + def output_active_traps(self) -> dict[int, int]: + trap_data = {} + + trap_data[0x20] = self.options.bald_trap_weight.value + trap_data[0x21] = self.options.literature_trap_weight.value + trap_data[0x22] = self.options.stun_trap_weight.value + trap_data[0x23] = self.options.invisible_trap_weight.value + trap_data[0x24] = self.options.fast_trap_weight.value + trap_data[0x25] = self.options.slow_trap_weight.value + trap_data[0x26] = self.options.ice_trap_weight.value + trap_data[0x28] = self.options.reverse_trap_weight.value + trap_data[0x29] = self.options.screen_flip_trap_weight.value + trap_data[0x2A] = self.options.laughter_trap_weight.value + trap_data[0x2B] = self.options.hiccup_trap_weight.value + trap_data[0x2C] = self.options.zoom_trap_weight.value + + return trap_data + + def generate_music_data(self) -> dict[int, int]: + if self.options.music_shuffle == "consistent": + musiclist_o = list(range(0, 48)) + musiclist_s = musiclist_o.copy() + self.random.shuffle(musiclist_s) + + return dict(zip(musiclist_o, musiclist_s)) + elif self.options.music_shuffle == "singularity": + musiclist_o = list(range(0, 48)) + musiclist_s = [self.random.choice(musiclist_o)] * len(musiclist_o) + + return dict(zip(musiclist_o, musiclist_s)) + else: + musiclist_o = list(range(0, 48)) + musiclist_s = musiclist_o.copy() + + return dict(zip(musiclist_o, musiclist_s)) + + + # Useful Debugging tools, kept around for later. + #@classmethod + #def stage_assert_generate(cls, _multiworld: MultiWorld) -> None: + # with open("./worlds/celeste_open_world/data/IDs.txt", "w") as f: + # print("Items:", file=f) + # for name in sorted(CelesteOpenWorld.item_name_to_id, key=CelesteOpenWorld.item_name_to_id.get): + # id = CelesteOpenWorld.item_name_to_id[name] + # print(f"{{ 0x{id:X}, \"{name}\" }},", file=f) + # print("\nLocations:", file=f) + # for name in sorted(CelesteOpenWorld.location_name_to_id, key=CelesteOpenWorld.location_name_to_id.get): + # id = CelesteOpenWorld.location_name_to_id[name] + # print(f"{{ 0x{id:X}, \"{name}\" }},", file=f) + # print("\nLocations 2:", file=f) + # for name in sorted(CelesteOpenWorld.location_name_to_id, key=CelesteOpenWorld.location_name_to_id.get): + # id = CelesteOpenWorld.location_name_to_id[name] + # print(f"{{ \"{name}\", 0x{id:X} }},", file=f) + # + #def generate_output(self, output_directory: str): + # visualize_regions(self.get_region("Menu"), f"Player{self.player}.puml", show_entrance_names=False, + # regions_to_highlight=self.multiworld.get_all_state(self.player).reachable_regions[self.player]) diff --git a/worlds/celeste_open_world/data/CelesteLevelData.json b/worlds/celeste_open_world/data/CelesteLevelData.json new file mode 100644 index 000000000000..5b4edd9b88b4 --- /dev/null +++ b/worlds/celeste_open_world/data/CelesteLevelData.json @@ -0,0 +1,41232 @@ +{ + "levels": [ + { + "name": "0a", + "display_name": "Prologue", + "rooms": [ + { + "name": "-1", + "regions": [ + { + "name": "main", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "car", + "display_name": "Car", + "type": "car", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "0", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "main", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + }, + { + "dest": "north", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "0b", + "regions": [ + { + "name": "south", + "connections": [] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "1", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "main", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "2", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "main", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "3", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "main", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + } + ], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "-1", + "source_door": "east", + "dest_room": "0", + "dest_door": "west" + }, + { + "source_room": "0", + "source_door": "north", + "dest_room": "0b", + "dest_door": "south" + }, + { + "source_room": "0", + "source_door": "east", + "dest_room": "1", + "dest_door": "west" + }, + { + "source_room": "1", + "source_door": "east", + "dest_room": "2", + "dest_door": "west" + }, + { + "source_room": "2", + "source_door": "east", + "dest_room": "3", + "dest_door": "west" + } + ] + }, + { + "name": "1a", + "display_name": "Forsaken City A", + "rooms": [ + { + "name": "1", + "regions": [ + { + "name": "main", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "main" + }, + { + "name": "2", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "3", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "4", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "3b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "5", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north-west", + "rule": [ [ "traffic_blocks" ] ] + }, + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "center", + "rule": [] + }, + { + "dest": "bottom", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "center", + "connections": [ + { + "dest": "north-east", + "rule": [] + }, + { + "dest": "bottom", + "rule": [] + }, + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "north-east", + "rule": [] + }, + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "center", + "rule": [] + }, + { + "dest": "top", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": true, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "5z", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "5a", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "traffic_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "6", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Crossing", + "checkpoint_region": "south-west" + }, + { + "name": "6z", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "6zb", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "main", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "7zb", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "springs", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "6a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "6b", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "traffic_blocks" ] ] + }, + { + "dest": "north-east", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "s0", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "traffic_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "s1", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + }, + { + "name": "crystal_heart", + "display_name": "Crystal Heart", + "type": "crystal_heart", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "6c", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "springs" ] ] + }, + { + "dest": "north-east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": true, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "7", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "7z", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": true, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "8z", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "8zb", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "8", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "north", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "north", + "rule": [] + }, + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "north-east", + "rule": [] + }, + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "7a", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "9z", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "traffic_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "8b", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "9", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "traffic_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "9b", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + }, + { + "dest": "north-west", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Chasm", + "checkpoint_region": "west" + }, + { + "name": "9c", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "traffic_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10", + "regions": [ + { + "name": "south-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "north-west", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10z", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10zb", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11", + "regions": [ + { + "name": "south-east", + "connections": [ + { + "dest": "north", + "rule": [ [ "traffic_blocks", "springs" ] ] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "south", + "rule": [ [ "traffic_blocks" ] ] + }, + { + "dest": "west", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "south-west", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11z", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "cassette", + "display_name": "Cassette", + "type": "cassette", + "rule": [ [ "pink_cassette_blocks", "blue_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10a", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12z", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12a", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "main", + "connections": [ + { + "dest": "south", + "rule": [] + } + ], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "springs", "traffic_blocks", "dash_refills" ] ] + }, + { + "name": "winged_golden", + "display_name": "Winged Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "springs", "traffic_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "1", + "source_door": "east", + "dest_room": "2", + "dest_door": "west" + }, + { + "source_room": "2", + "source_door": "east", + "dest_room": "3", + "dest_door": "west" + }, + { + "source_room": "3", + "source_door": "east", + "dest_room": "4", + "dest_door": "west" + }, + { + "source_room": "4", + "source_door": "east", + "dest_room": "3b", + "dest_door": "west" + }, + { + "source_room": "3b", + "source_door": "top", + "dest_room": "5", + "dest_door": "bottom" + }, + { + "source_room": "5", + "source_door": "west", + "dest_room": "5z", + "dest_door": "east" + }, + { + "source_room": "5", + "source_door": "south-east", + "dest_room": "5a", + "dest_door": "west" + }, + { + "source_room": "5", + "source_door": "top", + "dest_room": "6", + "dest_door": "south-west" + }, + { + "source_room": "6", + "source_door": "west", + "dest_room": "6z", + "dest_door": "east" + }, + { + "source_room": "6", + "source_door": "east", + "dest_room": "6a", + "dest_door": "west" + }, + { + "source_room": "6z", + "source_door": "north-west", + "dest_room": "7zb", + "dest_door": "east" + }, + { + "source_room": "6z", + "source_door": "west", + "dest_room": "6zb", + "dest_door": "east" + }, + { + "source_room": "7zb", + "source_door": "west", + "dest_room": "6zb", + "dest_door": "north-west" + }, + { + "source_room": "6a", + "source_door": "east", + "dest_room": "6b", + "dest_door": "south-west" + }, + { + "source_room": "6b", + "source_door": "north-west", + "dest_room": "s0", + "dest_door": "east" + }, + { + "source_room": "6b", + "source_door": "north-east", + "dest_room": "6c", + "dest_door": "south-west" + }, + { + "source_room": "s0", + "source_door": "west", + "dest_room": "s1", + "dest_door": "east" + }, + { + "source_room": "6c", + "source_door": "north-west", + "dest_room": "7z", + "dest_door": "bottom" + }, + { + "source_room": "6c", + "source_door": "north-east", + "dest_room": "7", + "dest_door": "west" + }, + { + "source_room": "7", + "source_door": "east", + "dest_room": "8", + "dest_door": "south-west" + }, + { + "source_room": "7z", + "source_door": "top", + "dest_room": "8z", + "dest_door": "bottom" + }, + { + "source_room": "8z", + "source_door": "top", + "dest_room": "8zb", + "dest_door": "west" + }, + { + "source_room": "8zb", + "source_door": "east", + "dest_room": "8", + "dest_door": "west" + }, + { + "source_room": "8", + "source_door": "south", + "dest_room": "7a", + "dest_door": "west" + }, + { + "source_room": "8", + "source_door": "north", + "dest_room": "9z", + "dest_door": "east" + }, + { + "source_room": "8", + "source_door": "north-east", + "dest_room": "8b", + "dest_door": "west" + }, + { + "source_room": "7a", + "source_door": "east", + "dest_room": "8", + "dest_door": "south-east" + }, + { + "source_room": "8b", + "source_door": "east", + "dest_room": "9", + "dest_door": "west" + }, + { + "source_room": "9", + "source_door": "east", + "dest_room": "9b", + "dest_door": "west" + }, + { + "source_room": "9b", + "source_door": "north-west", + "dest_room": "10", + "dest_door": "south-east" + }, + { + "source_room": "9b", + "source_door": "north-east", + "dest_room": "10a", + "dest_door": "bottom" + }, + { + "source_room": "9b", + "source_door": "east", + "dest_room": "9c", + "dest_door": "west" + }, + { + "source_room": "10", + "source_door": "south-west", + "dest_room": "10z", + "dest_door": "east" + }, + { + "source_room": "10", + "source_door": "north-west", + "dest_room": "11", + "dest_door": "south-west" + }, + { + "source_room": "10z", + "source_door": "west", + "dest_room": "10zb", + "dest_door": "east" + }, + { + "source_room": "11", + "source_door": "south", + "dest_room": "10", + "dest_door": "north-east" + }, + { + "source_room": "11", + "source_door": "west", + "dest_room": "11z", + "dest_door": "east" + }, + { + "source_room": "10a", + "source_door": "top", + "dest_room": "11", + "dest_door": "south-east" + }, + { + "source_room": "11", + "source_door": "north", + "dest_room": "12", + "dest_door": "south-west" + }, + { + "source_room": "12", + "source_door": "north-west", + "dest_room": "12z", + "dest_door": "east" + }, + { + "source_room": "12", + "source_door": "east", + "dest_room": "12a", + "dest_door": "bottom" + }, + { + "source_room": "12a", + "source_door": "top", + "dest_room": "end", + "dest_door": "south" + } + ] + }, + { + "name": "1b", + "display_name": "Forsaken City B", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Contraption", + "checkpoint_region": "west" + }, + { + "name": "05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "05b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "07", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Scrap Pit", + "checkpoint_region": "west" + }, + { + "name": "08b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "pink_cassette_blocks", "blue_cassette_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "springs", "traffic_blocks", "dash_refills", "pink_cassette_blocks", "blue_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + }, + { + "source_room": "02", + "source_door": "east", + "dest_room": "02b", + "dest_door": "west" + }, + { + "source_room": "02b", + "source_door": "east", + "dest_room": "03", + "dest_door": "west" + }, + { + "source_room": "03", + "source_door": "east", + "dest_room": "04", + "dest_door": "west" + }, + { + "source_room": "04", + "source_door": "east", + "dest_room": "05", + "dest_door": "west" + }, + { + "source_room": "05", + "source_door": "east", + "dest_room": "05b", + "dest_door": "west" + }, + { + "source_room": "05b", + "source_door": "east", + "dest_room": "06", + "dest_door": "west" + }, + { + "source_room": "06", + "source_door": "east", + "dest_room": "07", + "dest_door": "bottom" + }, + { + "source_room": "07", + "source_door": "top", + "dest_room": "08", + "dest_door": "west" + }, + { + "source_room": "08", + "source_door": "east", + "dest_room": "08b", + "dest_door": "west" + }, + { + "source_room": "08b", + "source_door": "east", + "dest_room": "09", + "dest_door": "west" + }, + { + "source_room": "09", + "source_door": "east", + "dest_room": "10", + "dest_door": "west" + }, + { + "source_room": "10", + "source_door": "east", + "dest_room": "11", + "dest_door": "bottom" + }, + { + "source_room": "11", + "source_door": "top", + "dest_room": "end", + "dest_door": "west" + } + ] + }, + { + "name": "1c", + "display_name": "Forsaken City C", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "coins", "traffic_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "traffic_blocks", "dash_refills", "coins" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + } + ] + }, + { + "name": "2a", + "display_name": "Old Site A", + "rooms": [ + { + "name": "start", + "regions": [ + { + "name": "main", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + }, + { + "dest": "top", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "main" + }, + { + "name": "s0", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "s1", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "s2", + "regions": [ + { + "name": "bottom", + "connections": [], + "locations": [ + { + "name": "crystal_heart", + "display_name": "Crystal Heart", + "type": "crystal_heart", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "0", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "north-east", + "rule": [ [ "dream_blocks" ] ] + }, + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "north-west", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south-east", + "rule": [ [ "dream_blocks" ] ] + }, + { + "dest": "north-west", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "1", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d0", + "regions": [ + { + "name": "north", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "north", + "rule": [] + }, + { + "dest": "west", + "rule": [] + }, + { + "dest": "north-east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "south", + "rule": [ [ "dream_blocks" ] ] + }, + { + "dest": "south-east", + "rule": [] + }, + { + "dest": "south-east", + "rule": [ [ "cannot_access" ] ] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "south-west", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dream_blocks" ] ] + }, + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": true, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d7", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d8", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south-east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d3", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "west", + "rule": [ [ "dream_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d2", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d9", + "regions": [ + { + "name": "north-west", + "connections": [], + "locations": [ + { + "name": "cassette", + "display_name": "Cassette", + "type": "cassette", + "rule": [ [ "dream_blocks", "pink_cassette_blocks", "blue_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d1", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "south-east", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks", "strawberry_seeds" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "south-east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": true, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d6", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d4", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "south", + "rule": [ [ "dream_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "traffic_blocks", "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d5", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "3x", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "3", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Intervention", + "checkpoint_region": "bottom" + }, + { + "name": "4", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "5", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "6", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks", "coins" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "7", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks", "coins" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "8", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "9", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [ [ "dream_blocks" ] ] + }, + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "south-east", + "rule": [ [ "coins" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "9b", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dream_blocks", "dash_refills", "coins" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "2", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "west", + "rule": [ [ "dream_blocks" ] ] + }, + { + "dest": "south", + "rule": [ [ "dream_blocks" ] ] + }, + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "north", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12c", + "regions": [ + { + "name": "south", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12d", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "north", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "13", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "phone", + "rule": [] + } + ] + }, + { + "name": "phone", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "phone", + "direction": "special", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_0", + "regions": [ + { + "name": "main", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + }, + { + "dest": "top", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "main", + "direction": "special", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_s0", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_s1", + "regions": [ + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_1", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_2", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_3", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Awake", + "checkpoint_region": "west" + }, + { + "name": "end_4", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_3b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north", + "rule": [ [ "springs" ] ] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_3cb", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_3c", + "regions": [ + { + "name": "bottom", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_5", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end_6", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "main", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "dream_blocks", "coins", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "start", + "source_door": "top", + "dest_room": "s0", + "dest_door": "bottom" + }, + { + "source_room": "start", + "source_door": "east", + "dest_room": "0", + "dest_door": "south-west" + }, + { + "source_room": "s0", + "source_door": "top", + "dest_room": "s1", + "dest_door": "bottom" + }, + { + "source_room": "s1", + "source_door": "top", + "dest_room": "s2", + "dest_door": "bottom" + }, + { + "source_room": "0", + "source_door": "north-west", + "dest_room": "3x", + "dest_door": "bottom" + }, + { + "source_room": "0", + "source_door": "north-east", + "dest_room": "1", + "dest_door": "north-west" + }, + { + "source_room": "0", + "source_door": "south-east", + "dest_room": "1", + "dest_door": "south-west" + }, + { + "source_room": "1", + "source_door": "south", + "dest_room": "d0", + "dest_door": "north" + }, + { + "source_room": "1", + "source_door": "south-east", + "dest_room": "2", + "dest_door": "south-west" + }, + { + "source_room": "d0", + "source_door": "north-west", + "dest_room": "d1", + "dest_door": "north-east" + }, + { + "source_room": "d0", + "source_door": "west", + "dest_room": "d1", + "dest_door": "south-east" + }, + { + "source_room": "d0", + "source_door": "south-west", + "dest_room": "d6", + "dest_door": "east" + }, + { + "source_room": "d0", + "source_door": "south", + "dest_room": "d9", + "dest_door": "north-west" + }, + { + "source_room": "d0", + "source_door": "south-east", + "dest_room": "d7", + "dest_door": "west" + }, + { + "source_room": "d0", + "source_door": "east", + "dest_room": "d2", + "dest_door": "west" + }, + { + "source_room": "d0", + "source_door": "north-east", + "dest_room": "d4", + "dest_door": "west" + }, + { + "source_room": "d1", + "source_door": "south-west", + "dest_room": "d6", + "dest_door": "west" + }, + { + "source_room": "d7", + "source_door": "east", + "dest_room": "d8", + "dest_door": "west" + }, + { + "source_room": "d2", + "source_door": "east", + "dest_room": "d3", + "dest_door": "north" + }, + { + "source_room": "d4", + "source_door": "east", + "dest_room": "d5", + "dest_door": "west" + }, + { + "source_room": "d4", + "source_door": "south", + "dest_room": "d2", + "dest_door": "north-west" + }, + { + "source_room": "d8", + "source_door": "north-east", + "dest_room": "d3", + "dest_door": "west" + }, + { + "source_room": "d8", + "source_door": "south-east", + "dest_room": "d3", + "dest_door": "south" + }, + { + "source_room": "3x", + "source_door": "top", + "dest_room": "3", + "dest_door": "bottom" + }, + { + "source_room": "3", + "source_door": "top", + "dest_room": "4", + "dest_door": "bottom" + }, + { + "source_room": "4", + "source_door": "top", + "dest_room": "5", + "dest_door": "bottom" + }, + { + "source_room": "5", + "source_door": "top", + "dest_room": "6", + "dest_door": "bottom" + }, + { + "source_room": "6", + "source_door": "top", + "dest_room": "7", + "dest_door": "bottom" + }, + { + "source_room": "7", + "source_door": "top", + "dest_room": "8", + "dest_door": "bottom" + }, + { + "source_room": "8", + "source_door": "top", + "dest_room": "9", + "dest_door": "west" + }, + { + "source_room": "9", + "source_door": "north", + "dest_room": "9b", + "dest_door": "east" + }, + { + "source_room": "9", + "source_door": "south-east", + "dest_room": "10", + "dest_door": "top" + }, + { + "source_room": "9b", + "source_door": "west", + "dest_room": "9", + "dest_door": "north-west" + }, + { + "source_room": "10", + "source_door": "bottom", + "dest_room": "2", + "dest_door": "north-west" + }, + { + "source_room": "2", + "source_door": "south-east", + "dest_room": "11", + "dest_door": "west" + }, + { + "source_room": "11", + "source_door": "east", + "dest_room": "12b", + "dest_door": "west" + }, + { + "source_room": "12b", + "source_door": "north", + "dest_room": "12c", + "dest_door": "south" + }, + { + "source_room": "12b", + "source_door": "south", + "dest_room": "12d", + "dest_door": "north-west" + }, + { + "source_room": "12b", + "source_door": "east", + "dest_room": "12", + "dest_door": "west" + }, + { + "source_room": "12d", + "source_door": "north", + "dest_room": "12b", + "dest_door": "south-east" + }, + { + "source_room": "12", + "source_door": "east", + "dest_room": "13", + "dest_door": "west" + }, + { + "source_room": "13", + "source_door": "phone", + "dest_room": "end_0", + "dest_door": "main" + }, + { + "source_room": "end_0", + "source_door": "top", + "dest_room": "end_s0", + "dest_door": "bottom" + }, + { + "source_room": "end_0", + "source_door": "east", + "dest_room": "end_1", + "dest_door": "west" + }, + { + "source_room": "end_s0", + "source_door": "top", + "dest_room": "end_s1", + "dest_door": "bottom" + }, + { + "source_room": "end_1", + "source_door": "east", + "dest_room": "end_2", + "dest_door": "west" + }, + { + "source_room": "end_1", + "source_door": "north-east", + "dest_room": "end_2", + "dest_door": "north-west" + }, + { + "source_room": "end_2", + "source_door": "east", + "dest_room": "end_3", + "dest_door": "west" + }, + { + "source_room": "end_2", + "source_door": "north-east", + "dest_room": "end_3", + "dest_door": "north-west" + }, + { + "source_room": "end_3", + "source_door": "east", + "dest_room": "end_4", + "dest_door": "west" + }, + { + "source_room": "end_4", + "source_door": "east", + "dest_room": "end_3b", + "dest_door": "west" + }, + { + "source_room": "end_3b", + "source_door": "north", + "dest_room": "end_3cb", + "dest_door": "bottom" + }, + { + "source_room": "end_3b", + "source_door": "east", + "dest_room": "end_5", + "dest_door": "west" + }, + { + "source_room": "end_3cb", + "source_door": "top", + "dest_room": "end_3c", + "dest_door": "bottom" + }, + { + "source_room": "end_5", + "source_door": "east", + "dest_room": "end_6", + "dest_door": "west" + } + ] + }, + { + "name": "2b", + "display_name": "Old Site B", + "rooms": [ + { + "name": "start", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "01b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Combination Lock", + "checkpoint_region": "west" + }, + { + "name": "04", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "05", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "07", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks", "coins" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "08b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Dream Altar", + "checkpoint_region": "west" + }, + { + "name": "08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "springs", "dream_blocks", "dash_refills", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "blue_cassette_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "springs", "dream_blocks", "dash_refills", "coins", "blue_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "start", + "source_door": "east", + "dest_room": "00", + "dest_door": "west" + }, + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "01b", + "dest_door": "west" + }, + { + "source_room": "01b", + "source_door": "east", + "dest_room": "02b", + "dest_door": "west" + }, + { + "source_room": "02b", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + }, + { + "source_room": "02", + "source_door": "east", + "dest_room": "03", + "dest_door": "west" + }, + { + "source_room": "03", + "source_door": "east", + "dest_room": "04", + "dest_door": "bottom" + }, + { + "source_room": "04", + "source_door": "top", + "dest_room": "05", + "dest_door": "bottom" + }, + { + "source_room": "05", + "source_door": "top", + "dest_room": "06", + "dest_door": "west" + }, + { + "source_room": "06", + "source_door": "east", + "dest_room": "07", + "dest_door": "bottom" + }, + { + "source_room": "07", + "source_door": "top", + "dest_room": "08b", + "dest_door": "west" + }, + { + "source_room": "08b", + "source_door": "east", + "dest_room": "08", + "dest_door": "west" + }, + { + "source_room": "08", + "source_door": "east", + "dest_room": "09", + "dest_door": "west" + }, + { + "source_room": "09", + "source_door": "east", + "dest_room": "10", + "dest_door": "west" + }, + { + "source_room": "10", + "source_door": "east", + "dest_room": "11", + "dest_door": "bottom" + }, + { + "source_room": "11", + "source_door": "top", + "dest_room": "end", + "dest_door": "west" + } + ] + }, + { + "name": "2c", + "display_name": "Old Site C", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "coins", "dream_blocks", "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "dream_blocks", "dash_refills", "coins" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + } + ] + }, + { + "name": "3a", + "display_name": "Celestial Resort A", + "rooms": [ + { + "name": "s0", + "regions": [ + { + "name": "main", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "main" + }, + { + "name": "s1", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "s2", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north-west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "s3", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "Front Door Key" ] ] + } + ], + "locations": [ + { + "name": "key_1", + "display_name": "Front Door Key", + "type": "key", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "0x-a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "00-a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02-a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "main", + "rule": [ + [ "sinking_platforms" ], + [ "dash_refills" ] + ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + }, + { + "dest": "main", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "main", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills" ] ] + }, + { + "dest": "east", + "rule": [ [ "Hallway Key 1" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": true, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02-b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "hallway_key_1", + "display_name": "Hallway Key 1", + "type": "key", + "rule": [] + } + ] + }, + { + "name": "far-east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "far-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "01-b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north-west", + "rule": [ [ "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "00-b", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": true, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "00-c", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "south-east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south-west", + "rule": [ [ "dash_refills" ] ] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "0x-b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "03-a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "sinking_platforms" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "04-b", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "05-a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "moving_platforms" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills", "moving_platforms" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "06-a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "07-a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "Hallway Key 2", "dash_refills" ] ] + }, + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "Hallway Key 2", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "07-b", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ], + "locations": [ + { + "name": "key_2", + "display_name": "Hallway Key 2", + "type": "key", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "06-b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "06-c", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "south-east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": true, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "05-c", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "08-c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins", "moving_platforms", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "08-b", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "sinking_platforms", "coins" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "08-a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "bottom", + "rule": [ + [ "brown_clutter" ], + [ "green_clutter" ], + [ "pink_clutter" ] + ] + } + ] + }, + { + "name": "bottom", + "connections": [] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Huge Mess", + "checkpoint_region": "west" + }, + { + "name": "09-b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "center", + "rule": [ [ "Huge Mess Key" ] ] + } + ] + }, + { + "name": "center", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north-west", + "rule": [ [ "Huge Mess Key" ] ] + }, + { + "dest": "south-west", + "rule": [ + [ "brown_clutter" ], + [ "green_clutter" ], + [ "pink_clutter" ] + ] + }, + { + "dest": "south", + "rule": [] + }, + { + "dest": "south-east", + "rule": [] + }, + { + "dest": "east", + "rule": [] + }, + { + "dest": "north-east-right", + "rule": [] + }, + { + "dest": "north-east-top", + "rule": [] + }, + { + "dest": "north", + "rule": [] + } + ], + "locations": [ + { + "name": "key_4", + "display_name": "Huge Mess Key", + "type": "key", + "rule": [ [ "brown_clutter", "green_clutter", "pink_clutter" ] ] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "center", + "rule": [ + [ "brown_clutter" ], + [ "green_clutter" ], + [ "pink_clutter" ] + ] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north-east-right", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north-east-top", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east-right", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east-top", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10-x", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "west", + "rule": [ [ "brown_clutter" ] ] + } + ], + "locations": [ + { + "name": "brown_clutter", + "display_name": "Brown Clutter", + "type": "clutter", + "rule": [] + } + ] + }, + { + "name": "north-east-top", + "connections": [ + { + "dest": "north-east-right", + "rule": [] + } + ] + }, + { + "name": "north-east-right", + "connections": [ + { + "dest": "north-east-top", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-east-top", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-east-right", + "direction": "right", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11-x", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [ [ "coins" ] ] + } + ] + }, + { + "name": "south", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11-y", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12-y", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11-z", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10-z", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "sinking_platforms" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10-y", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10-c", + "regions": [ + { + "name": "south-east", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11-c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ], + "locations": [ + { + "name": "crystal_heart", + "display_name": "Crystal Heart", + "type": "crystal_heart", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12-c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "top", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12-d", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11-d", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "cannot_access" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10-d", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "main", + "rule": [ [ "green_clutter" ] ] + } + ] + }, + { + "name": "main", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "green_clutter", + "display_name": "Green Clutter", + "type": "clutter", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11-b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north-east", + "rule": [ [ "pink_clutter" ] ] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [ [ "pink_clutter" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12-b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "13-b", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "13-a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "south-west", + "rule": [ [ "pink_clutter" ] ] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "west", + "rule": [ [ "pink_clutter" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "13-x", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12-x", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "pink_clutter", + "display_name": "Pink Clutter", + "type": "clutter", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11-a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "south-east-bottom", + "connections": [ + { + "dest": "south-east-right", + "rule": [ [ "pink_clutter" ] ] + } + ] + }, + { + "name": "south-east-right", + "connections": [ + { + "dest": "south-east-bottom", + "rule": [ [ "pink_clutter" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-east-bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east-right", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "08-x", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "09-d", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Elevator Shaft", + "checkpoint_region": "bottom" + }, + { + "name": "08-d", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills", "coins" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "06-d", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "04-d", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "south-west", + "rule": [ [ "cannot_access" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "04-c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "Presidential Suite Key" ] ] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [ [ "Presidential Suite Key" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02-c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "key_5", + "display_name": "Presidential Suite Key", + "type": "key", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "sinking_platforms" ] ] + }, + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "03-b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [] + }, + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "01-c", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "cassette", + "display_name": "Cassette", + "type": "cassette", + "rule": [ [ "pink_cassette_blocks", "blue_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02-d", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "cannot_access" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "00-d", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "Presidential Suite", + "checkpoint_region": "east" + }, + { + "name": "roof00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "roof01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "roof02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "roof03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "coins", "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "roof04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "roof05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "roof06b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "roof06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [] + }, + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "roof07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + }, + { + "name": "main", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "Front Door Key", "Hallway Key 1", "Hallway Key 2", "Huge Mess Key", "Presidential Suite Key", "sinking_platforms", "dash_refills", "brown_clutter", "green_clutter", "pink_clutter", "coins", "moving_platforms", "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "s0", + "source_door": "east", + "dest_room": "s1", + "dest_door": "west" + }, + { + "source_room": "s1", + "source_door": "east", + "dest_room": "s2", + "dest_door": "west" + }, + { + "source_room": "s1", + "source_door": "north-east", + "dest_room": "s2", + "dest_door": "north-west" + }, + { + "source_room": "s2", + "source_door": "east", + "dest_room": "s3", + "dest_door": "west" + }, + { + "source_room": "s3", + "source_door": "east", + "dest_room": "0x-a", + "dest_door": "west" + }, + { + "source_room": "0x-a", + "source_door": "east", + "dest_room": "00-a", + "dest_door": "west" + }, + { + "source_room": "00-a", + "source_door": "east", + "dest_room": "02-a", + "dest_door": "west" + }, + { + "source_room": "02-a", + "source_door": "east", + "dest_room": "03-a", + "dest_door": "west" + }, + { + "source_room": "02-a", + "source_door": "top", + "dest_room": "02-b", + "dest_door": "east" + }, + { + "source_room": "02-b", + "source_door": "west", + "dest_room": "01-b", + "dest_door": "east" + }, + { + "source_room": "01-b", + "source_door": "north-west", + "dest_room": "00-b", + "dest_door": "east" + }, + { + "source_room": "01-b", + "source_door": "west", + "dest_room": "00-b", + "dest_door": "south-east" + }, + { + "source_room": "00-b", + "source_door": "south-west", + "dest_room": "0x-b", + "dest_door": "south-east" + }, + { + "source_room": "00-b", + "source_door": "north", + "dest_room": "00-c", + "dest_door": "south-east" + }, + { + "source_room": "00-b", + "source_door": "west", + "dest_room": "0x-b", + "dest_door": "north-east" + }, + { + "source_room": "00-c", + "source_door": "south-west", + "dest_room": "00-b", + "dest_door": "north-west" + }, + { + "source_room": "00-c", + "source_door": "north-east", + "dest_room": "01-c", + "dest_door": "west" + }, + { + "source_room": "0x-b", + "source_door": "west", + "dest_room": "s3", + "dest_door": "north" + }, + { + "source_room": "03-a", + "source_door": "top", + "dest_room": "04-b", + "dest_door": "east" + }, + { + "source_room": "03-a", + "source_door": "east", + "dest_room": "05-a", + "dest_door": "west" + }, + { + "source_room": "05-a", + "source_door": "east", + "dest_room": "06-a", + "dest_door": "west" + }, + { + "source_room": "06-a", + "source_door": "east", + "dest_room": "07-a", + "dest_door": "west" + }, + { + "source_room": "07-a", + "source_door": "top", + "dest_room": "07-b", + "dest_door": "bottom" + }, + { + "source_room": "07-a", + "source_door": "east", + "dest_room": "08-a", + "dest_door": "west" + }, + { + "source_room": "07-b", + "source_door": "west", + "dest_room": "06-b", + "dest_door": "east" + }, + { + "source_room": "06-b", + "source_door": "west", + "dest_room": "06-c", + "dest_door": "south-west" + }, + { + "source_room": "06-c", + "source_door": "north-west", + "dest_room": "05-c", + "dest_door": "east" + }, + { + "source_room": "06-c", + "source_door": "east", + "dest_room": "08-c", + "dest_door": "west" + }, + { + "source_room": "06-c", + "source_door": "south-east", + "dest_room": "07-b", + "dest_door": "top" + }, + { + "source_room": "08-c", + "source_door": "east", + "dest_room": "08-b", + "dest_door": "east" + }, + { + "source_room": "08-b", + "source_door": "west", + "dest_room": "07-b", + "dest_door": "east" + }, + { + "source_room": "08-a", + "source_door": "bottom", + "dest_room": "08-x", + "dest_door": "west" + }, + { + "source_room": "08-a", + "source_door": "east", + "dest_room": "09-b", + "dest_door": "west" + }, + { + "source_room": "09-b", + "source_door": "south-east", + "dest_room": "10-x", + "dest_door": "north-east-top" + }, + { + "source_room": "09-b", + "source_door": "north-west", + "dest_room": "09-d", + "dest_door": "bottom" + }, + { + "source_room": "09-b", + "source_door": "north-east-top", + "dest_room": "10-c", + "dest_door": "south-east" + }, + { + "source_room": "09-b", + "source_door": "east", + "dest_room": "11-a", + "dest_door": "west" + }, + { + "source_room": "09-b", + "source_door": "north-east-right", + "dest_room": "11-b", + "dest_door": "west" + }, + { + "source_room": "10-x", + "source_door": "north-east-right", + "dest_room": "11-x", + "dest_door": "west" + }, + { + "source_room": "11-x", + "source_door": "south", + "dest_room": "11-y", + "dest_door": "west" + }, + { + "source_room": "11-y", + "source_door": "east", + "dest_room": "12-y", + "dest_door": "west" + }, + { + "source_room": "11-y", + "source_door": "south", + "dest_room": "11-z", + "dest_door": "east" + }, + { + "source_room": "11-z", + "source_door": "west", + "dest_room": "10-z", + "dest_door": "bottom" + }, + { + "source_room": "10-z", + "source_door": "top", + "dest_room": "10-y", + "dest_door": "bottom" + }, + { + "source_room": "10-y", + "source_door": "top", + "dest_room": "10-x", + "dest_door": "south-east" + }, + { + "source_room": "10-x", + "source_door": "west", + "dest_room": "09-b", + "dest_door": "south" + }, + { + "source_room": "10-c", + "source_door": "north-east", + "dest_room": "11-c", + "dest_door": "west" + }, + { + "source_room": "10-c", + "source_door": "south-west", + "dest_room": "09-b", + "dest_door": "north" + }, + { + "source_room": "11-c", + "source_door": "east", + "dest_room": "12-c", + "dest_door": "west" + }, + { + "source_room": "11-c", + "source_door": "south-west", + "dest_room": "11-b", + "dest_door": "north-west" + }, + { + "source_room": "12-c", + "source_door": "top", + "dest_room": "12-d", + "dest_door": "bottom" + }, + { + "source_room": "12-d", + "source_door": "top", + "dest_room": "11-d", + "dest_door": "east" + }, + { + "source_room": "11-d", + "source_door": "west", + "dest_room": "10-d", + "dest_door": "east" + }, + { + "source_room": "10-d", + "source_door": "west", + "dest_room": "10-c", + "dest_door": "north-west" + }, + { + "source_room": "11-b", + "source_door": "north-east", + "dest_room": "11-c", + "dest_door": "south-east" + }, + { + "source_room": "11-b", + "source_door": "east", + "dest_room": "12-b", + "dest_door": "west" + }, + { + "source_room": "12-b", + "source_door": "east", + "dest_room": "13-b", + "dest_door": "top" + }, + { + "source_room": "13-b", + "source_door": "bottom", + "dest_room": "13-a", + "dest_door": "west" + }, + { + "source_room": "13-a", + "source_door": "east", + "dest_room": "13-x", + "dest_door": "east" + }, + { + "source_room": "13-x", + "source_door": "west", + "dest_room": "12-x", + "dest_door": "east" + }, + { + "source_room": "12-x", + "source_door": "north-east", + "dest_room": "11-a", + "dest_door": "south-east-bottom" + }, + { + "source_room": "12-x", + "source_door": "west", + "dest_room": "11-a", + "dest_door": "south" + }, + { + "source_room": "11-a", + "source_door": "south-east-right", + "dest_room": "13-a", + "dest_door": "south-west" + }, + { + "source_room": "08-x", + "source_door": "east", + "dest_room": "09-b", + "dest_door": "south-west" + }, + { + "source_room": "09-d", + "source_door": "top", + "dest_room": "08-d", + "dest_door": "east" + }, + { + "source_room": "08-d", + "source_door": "west", + "dest_room": "06-d", + "dest_door": "east" + }, + { + "source_room": "06-d", + "source_door": "west", + "dest_room": "04-d", + "dest_door": "east" + }, + { + "source_room": "04-d", + "source_door": "west", + "dest_room": "02-d", + "dest_door": "east" + }, + { + "source_room": "04-d", + "source_door": "south", + "dest_room": "04-c", + "dest_door": "east" + }, + { + "source_room": "04-c", + "source_door": "west", + "dest_room": "02-c", + "dest_door": "east" + }, + { + "source_room": "04-c", + "source_door": "north-west", + "dest_room": "04-d", + "dest_door": "south-west" + }, + { + "source_room": "02-c", + "source_door": "west", + "dest_room": "01-c", + "dest_door": "east" + }, + { + "source_room": "02-c", + "source_door": "south-east", + "dest_room": "03-b", + "dest_door": "north" + }, + { + "source_room": "03-b", + "source_door": "east", + "dest_room": "04-b", + "dest_door": "west" + }, + { + "source_room": "03-b", + "source_door": "west", + "dest_room": "02-b", + "dest_door": "far-east" + }, + { + "source_room": "02-d", + "source_door": "west", + "dest_room": "00-d", + "dest_door": "east" + }, + { + "source_room": "00-d", + "source_door": "west", + "dest_room": "roof00", + "dest_door": "west" + }, + { + "source_room": "roof00", + "source_door": "east", + "dest_room": "roof01", + "dest_door": "west" + }, + { + "source_room": "roof01", + "source_door": "east", + "dest_room": "roof02", + "dest_door": "west" + }, + { + "source_room": "roof02", + "source_door": "east", + "dest_room": "roof03", + "dest_door": "west" + }, + { + "source_room": "roof03", + "source_door": "east", + "dest_room": "roof04", + "dest_door": "west" + }, + { + "source_room": "roof04", + "source_door": "east", + "dest_room": "roof05", + "dest_door": "west" + }, + { + "source_room": "roof05", + "source_door": "east", + "dest_room": "roof06b", + "dest_door": "west" + }, + { + "source_room": "roof06b", + "source_door": "east", + "dest_room": "roof06", + "dest_door": "west" + }, + { + "source_room": "roof06", + "source_door": "east", + "dest_room": "roof07", + "dest_door": "west" + } + ] + }, + { + "name": "3b", + "display_name": "Celestial Resort B", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "back", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "moving_platforms", "coins", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "sinking_platforms" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "sinking_platforms" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Staff Quarters", + "checkpoint_region": "west" + }, + { + "name": "07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "08", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Library", + "checkpoint_region": "west" + }, + { + "name": "13", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "14", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "15", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "16", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": true, + "closes_behind": false + } + ], + "checkpoint": "Rooftop", + "checkpoint_region": "west" + }, + { + "name": "17", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills", "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "18", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "19", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "springs", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "21", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "20", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "pink_cassette_blocks", "blue_cassette_blocks", "dash_refills", "springs", "coins" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "pink_cassette_blocks", "blue_cassette_blocks", "dash_refills", "springs", "coins", "moving_platforms", "sinking_platforms" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "00", + "source_door": "west", + "dest_room": "back", + "dest_door": "east" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + }, + { + "source_room": "02", + "source_door": "east", + "dest_room": "03", + "dest_door": "west" + }, + { + "source_room": "03", + "source_door": "east", + "dest_room": "04", + "dest_door": "west" + }, + { + "source_room": "04", + "source_door": "east", + "dest_room": "05", + "dest_door": "west" + }, + { + "source_room": "05", + "source_door": "east", + "dest_room": "06", + "dest_door": "west" + }, + { + "source_room": "06", + "source_door": "east", + "dest_room": "07", + "dest_door": "west" + }, + { + "source_room": "07", + "source_door": "east", + "dest_room": "08", + "dest_door": "bottom" + }, + { + "source_room": "08", + "source_door": "top", + "dest_room": "09", + "dest_door": "west" + }, + { + "source_room": "09", + "source_door": "east", + "dest_room": "10", + "dest_door": "west" + }, + { + "source_room": "10", + "source_door": "east", + "dest_room": "11", + "dest_door": "west" + }, + { + "source_room": "11", + "source_door": "east", + "dest_room": "13", + "dest_door": "west" + }, + { + "source_room": "13", + "source_door": "east", + "dest_room": "14", + "dest_door": "west" + }, + { + "source_room": "14", + "source_door": "east", + "dest_room": "15", + "dest_door": "west" + }, + { + "source_room": "15", + "source_door": "east", + "dest_room": "12", + "dest_door": "west" + }, + { + "source_room": "12", + "source_door": "east", + "dest_room": "16", + "dest_door": "west" + }, + { + "source_room": "16", + "source_door": "top", + "dest_room": "17", + "dest_door": "west" + }, + { + "source_room": "17", + "source_door": "east", + "dest_room": "18", + "dest_door": "west" + }, + { + "source_room": "18", + "source_door": "east", + "dest_room": "19", + "dest_door": "west" + }, + { + "source_room": "19", + "source_door": "east", + "dest_room": "21", + "dest_door": "west" + }, + { + "source_room": "21", + "source_door": "east", + "dest_room": "20", + "dest_door": "west" + }, + { + "source_room": "20", + "source_door": "east", + "dest_room": "end", + "dest_door": "west" + } + ] + }, + { + "name": "3c", + "display_name": "Celestial Resort C", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "sinking_platforms" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "coins", "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "sinking_platforms", "dash_refills", "coins" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + } + ] + }, + { + "name": "4a", + "display_name": "Golden Ridge A", + "rooms": [ + { + "name": "a-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_clouds" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "a-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-01x", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_clouds", "pink_clouds" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_clouds" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "blue_clouds" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "moving_platforms" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "moving_platforms" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "blue_clouds", "blue_boosters" ] ] + }, + { + "dest": "east", + "rule": [ [ "blue_clouds" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_clouds" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "strawberry_seeds", "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-11", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "cassette", + "display_name": "Cassette", + "type": "cassette", + "rule": [ [ "pink_cassette_blocks", "blue_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-09", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "south-east", + "rule": [] + }, + { + "dest": "west", + "rule": [ [ "move_blocks" ] ] + }, + { + "dest": "east", + "rule": [ [ "move_blocks" ] ] + }, + { + "dest": "north-east", + "rule": [ [ "move_blocks" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "north", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Shrine", + "checkpoint_region": "south" + }, + { + "name": "b-01", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [ [ "move_blocks" ] ] + }, + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [ [ "move_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-04", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "move_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "cannot_access" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "move_blocks", "blue_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks", "blue_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "move_blocks", "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "move_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "south-west", + "connections": [], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [ [ "move_blocks" ] ] + }, + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "north-east", + "rule": [] + }, + { + "dest": "north", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": true, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-sec", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "crystal_heart", + "display_name": "Crystal Heart", + "type": "crystal_heart", + "rule": [ [ "white_block" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": true, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-secb", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "move_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-05", + "regions": [ + { + "name": "center", + "connections": [ + { + "dest": "west", + "rule": [ [ "pink_clouds", "move_blocks" ] ] + } + ] + }, + { + "name": "west", + "connections": [] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north-east", + "rule": [ [ "move_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "center", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-08b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks", "blue_clouds" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "move_blocks", "blue_clouds" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + }, + { + "dest": "north-west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Old Trail", + "checkpoint_region": "west" + }, + { + "name": "c-01", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pink_clouds" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters", "move_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "blue_boosters", "move_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-06", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_boosters", "blue_clouds", "move_blocks" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "bottom", + "rule": [] + }, + { + "dest": "top", + "rule": [ [ "move_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "coins", "move_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-06b", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills", "blue_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins", "move_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-08", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "bottom", + "rule": [] + }, + { + "dest": "top", + "rule": [ [ "blue_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-10", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "blue_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "south", + "rule": [] + }, + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Cliff Face", + "checkpoint_region": "west" + }, + { + "name": "d-00b", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "move_blocks", "blue_boosters" ] ] + }, + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks", "coins", "pink_clouds", "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_clouds", "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "blue_clouds", "pink_clouds", "blue_boosters", "move_blocks", "dash_refills", "springs", "coins" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "a-00", + "source_door": "east", + "dest_room": "a-01", + "dest_door": "west" + }, + { + "source_room": "a-01", + "source_door": "east", + "dest_room": "a-01x", + "dest_door": "west" + }, + { + "source_room": "a-01x", + "source_door": "east", + "dest_room": "a-02", + "dest_door": "west" + }, + { + "source_room": "a-02", + "source_door": "east", + "dest_room": "a-03", + "dest_door": "west" + }, + { + "source_room": "a-03", + "source_door": "east", + "dest_room": "a-04", + "dest_door": "west" + }, + { + "source_room": "a-04", + "source_door": "east", + "dest_room": "a-05", + "dest_door": "west" + }, + { + "source_room": "a-05", + "source_door": "east", + "dest_room": "a-06", + "dest_door": "west" + }, + { + "source_room": "a-06", + "source_door": "east", + "dest_room": "a-07", + "dest_door": "west" + }, + { + "source_room": "a-07", + "source_door": "east", + "dest_room": "a-08", + "dest_door": "west" + }, + { + "source_room": "a-08", + "source_door": "north-west", + "dest_room": "a-10", + "dest_door": "east" + }, + { + "source_room": "a-08", + "source_door": "east", + "dest_room": "a-09", + "dest_door": "bottom" + }, + { + "source_room": "a-10", + "source_door": "west", + "dest_room": "a-11", + "dest_door": "east" + }, + { + "source_room": "a-09", + "source_door": "top", + "dest_room": "b-00", + "dest_door": "south" + }, + { + "source_room": "b-00", + "source_door": "south-east", + "dest_room": "b-01", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "north-west", + "dest_room": "b-04", + "dest_door": "east" + }, + { + "source_room": "b-04", + "source_door": "west", + "dest_room": "b-06", + "dest_door": "east" + }, + { + "source_room": "b-06", + "source_door": "west", + "dest_room": "b-07", + "dest_door": "west" + }, + { + "source_room": "b-07", + "source_door": "east", + "dest_room": "b-03", + "dest_door": "west" + }, + { + "source_room": "b-03", + "source_door": "east", + "dest_room": "b-00", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "east", + "dest_room": "b-02", + "dest_door": "south-west" + }, + { + "source_room": "b-00", + "source_door": "north-east", + "dest_room": "b-02", + "dest_door": "north-west" + }, + { + "source_room": "b-02", + "source_door": "north-east", + "dest_room": "b-sec", + "dest_door": "west" + }, + { + "source_room": "b-sec", + "source_door": "east", + "dest_room": "b-secb", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "north", + "dest_room": "b-05", + "dest_door": "center" + }, + { + "source_room": "b-05", + "source_door": "west", + "dest_room": "b-04", + "dest_door": "north-west" + }, + { + "source_room": "b-02", + "source_door": "north", + "dest_room": "b-05", + "dest_door": "east" + }, + { + "source_room": "b-05", + "source_door": "north-east", + "dest_room": "b-08b", + "dest_door": "west" + }, + { + "source_room": "b-08b", + "source_door": "east", + "dest_room": "b-08", + "dest_door": "west" + }, + { + "source_room": "b-08", + "source_door": "east", + "dest_room": "c-00", + "dest_door": "west" + }, + { + "source_room": "c-00", + "source_door": "north-west", + "dest_room": "c-01", + "dest_door": "east" + }, + { + "source_room": "c-00", + "source_door": "east", + "dest_room": "c-02", + "dest_door": "west" + }, + { + "source_room": "c-02", + "source_door": "east", + "dest_room": "c-04", + "dest_door": "west" + }, + { + "source_room": "c-04", + "source_door": "east", + "dest_room": "c-05", + "dest_door": "west" + }, + { + "source_room": "c-05", + "source_door": "east", + "dest_room": "c-06", + "dest_door": "bottom" + }, + { + "source_room": "c-06", + "source_door": "west", + "dest_room": "c-06b", + "dest_door": "east" + }, + { + "source_room": "c-06", + "source_door": "top", + "dest_room": "c-09", + "dest_door": "west" + }, + { + "source_room": "c-09", + "source_door": "east", + "dest_room": "c-07", + "dest_door": "west" + }, + { + "source_room": "c-07", + "source_door": "east", + "dest_room": "c-08", + "dest_door": "bottom" + }, + { + "source_room": "c-08", + "source_door": "east", + "dest_room": "c-10", + "dest_door": "bottom" + }, + { + "source_room": "c-08", + "source_door": "top", + "dest_room": "d-00", + "dest_door": "west" + }, + { + "source_room": "c-10", + "source_door": "top", + "dest_room": "d-00", + "dest_door": "south" + }, + { + "source_room": "d-00", + "source_door": "north-west", + "dest_room": "d-00b", + "dest_door": "east" + }, + { + "source_room": "d-00", + "source_door": "east", + "dest_room": "d-01", + "dest_door": "west" + }, + { + "source_room": "d-01", + "source_door": "east", + "dest_room": "d-02", + "dest_door": "west" + }, + { + "source_room": "d-02", + "source_door": "east", + "dest_room": "d-03", + "dest_door": "west" + }, + { + "source_room": "d-03", + "source_door": "east", + "dest_room": "d-04", + "dest_door": "west" + }, + { + "source_room": "d-04", + "source_door": "east", + "dest_room": "d-05", + "dest_door": "west" + }, + { + "source_room": "d-05", + "source_door": "east", + "dest_room": "d-06", + "dest_door": "west" + }, + { + "source_room": "d-06", + "source_door": "east", + "dest_room": "d-07", + "dest_door": "west" + }, + { + "source_room": "d-07", + "source_door": "east", + "dest_room": "d-08", + "dest_door": "west" + }, + { + "source_room": "d-08", + "source_door": "east", + "dest_room": "d-09", + "dest_door": "west" + }, + { + "source_room": "d-09", + "source_door": "east", + "dest_room": "d-10", + "dest_door": "west" + } + ] + }, + { + "name": "4b", + "display_name": "Golden Ridge B", + "rooms": [ + { + "name": "a-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "a-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "moving_platforms" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "moving_platforms" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "move_blocks", "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks", "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Stepping Stones", + "checkpoint_region": "west" + }, + { + "name": "b-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "move_blocks", "springs", "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins", "moving_platforms", "springs", "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Gusty Canyon", + "checkpoint_region": "west" + }, + { + "name": "c-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "moving_platforms" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "move_blocks", "blue_clouds" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "blue_clouds" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_clouds" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_clouds" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Eye of the Storm", + "checkpoint_region": "west" + }, + { + "name": "d-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pink_clouds", "blue_boosters" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "blue_boosters", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "end", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "pink_cassette_blocks", "blue_cassette_blocks", "dash_refills", "blue_boosters" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "pink_cassette_blocks", "blue_cassette_blocks", "dash_refills", "springs", "coins", "moving_platforms", "blue_boosters", "blue_clouds", "pink_clouds", "move_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "a-00", + "source_door": "east", + "dest_room": "a-01", + "dest_door": "west" + }, + { + "source_room": "a-01", + "source_door": "east", + "dest_room": "a-02", + "dest_door": "west" + }, + { + "source_room": "a-02", + "source_door": "east", + "dest_room": "a-03", + "dest_door": "west" + }, + { + "source_room": "a-03", + "source_door": "east", + "dest_room": "a-04", + "dest_door": "west" + }, + { + "source_room": "a-04", + "source_door": "east", + "dest_room": "b-00", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "east", + "dest_room": "b-01", + "dest_door": "west" + }, + { + "source_room": "b-01", + "source_door": "east", + "dest_room": "b-02", + "dest_door": "bottom" + }, + { + "source_room": "b-02", + "source_door": "top", + "dest_room": "b-03", + "dest_door": "west" + }, + { + "source_room": "b-03", + "source_door": "east", + "dest_room": "b-04", + "dest_door": "west" + }, + { + "source_room": "b-04", + "source_door": "east", + "dest_room": "c-00", + "dest_door": "west" + }, + { + "source_room": "c-00", + "source_door": "east", + "dest_room": "c-01", + "dest_door": "west" + }, + { + "source_room": "c-01", + "source_door": "east", + "dest_room": "c-02", + "dest_door": "west" + }, + { + "source_room": "c-02", + "source_door": "east", + "dest_room": "c-03", + "dest_door": "bottom" + }, + { + "source_room": "c-03", + "source_door": "top", + "dest_room": "c-04", + "dest_door": "west" + }, + { + "source_room": "c-04", + "source_door": "east", + "dest_room": "d-00", + "dest_door": "west" + }, + { + "source_room": "d-00", + "source_door": "east", + "dest_room": "d-01", + "dest_door": "west" + }, + { + "source_room": "d-01", + "source_door": "east", + "dest_room": "d-02", + "dest_door": "west" + }, + { + "source_room": "d-02", + "source_door": "east", + "dest_room": "d-03", + "dest_door": "west" + }, + { + "source_room": "d-03", + "source_door": "east", + "dest_room": "end", + "dest_door": "west" + } + ] + }, + { + "name": "4c", + "display_name": "Golden Ridge C", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks", "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "pink_clouds", "blue_boosters", "move_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "pink_clouds", "blue_boosters", "move_blocks", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + } + ] + }, + { + "name": "5a", + "display_name": "Mirror Temple A", + "rooms": [ + { + "name": "a-00b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "a-00x", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-00d", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-00c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "red_boosters", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "center", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + }, + { + "dest": "south-west", + "rule": [ [ "swap_blocks" ] ] + }, + { + "dest": "south-east", + "rule": [ [ "swap_blocks" ] ] + }, + { + "dest": "north", + "rule": [ [ "red_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [ [ "red_boosters" ] ] + }, + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north", + "rule": [] + }, + { + "dest": "south", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-04", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "north", + "rule": [] + }, + { + "dest": "south", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "swap_blocks", "springs" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-05", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "center", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + }, + { + "dest": "south-west", + "rule": [ [ "swap_blocks" ] ] + }, + { + "dest": "south-east", + "rule": [ [ "swap_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "center", + "rule": [ [ "dash_switches" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "center", + "rule": [ [ "dash_switches" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-06", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters", "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-07", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills", "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "center", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north-east", + "rule": [ [ "red_boosters", "swap_blocks" ] ] + }, + { + "dest": "south", + "rule": [] + }, + { + "dest": "north", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ], + "locations": [ + { + "name": "key_1", + "display_name": "Entrance Key", + "type": "key", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "center", + "rule": [ [ "dash_switches" ] ] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "red_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-11", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills", "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-12", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "west", + "connections": [] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "east", + "rule": [ [ "red_boosters", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-15", + "regions": [ + { + "name": "south", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "coins", "red_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-14", + "regions": [ + { + "name": "south", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "swap_blocks", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-13", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "Entrance Key" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "Entrance Key" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_switches" ] ] + }, + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Depths", + "checkpoint_region": "west" + }, + { + "name": "b-18", + "regions": [ + { + "name": "south", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-01", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "center", + "connections": [ + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "west", + "rule": [ [ "swap_blocks" ] ] + }, + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "north", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "swap_blocks" ] ] + }, + { + "dest": "south-east", + "rule": [] + }, + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "center", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-01c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-20", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [ [ "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-21", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-01b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "center", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north-west", + "rule": [ [ "red_boosters" ] ] + }, + { + "dest": "north", + "rule": [ [ "red_boosters" ] ] + }, + { + "dest": "north-east", + "rule": [ [ "red_boosters" ] ] + }, + { + "dest": "east-upper", + "rule": [] + }, + { + "dest": "east-lower", + "rule": [ [ "red_boosters" ] ] + }, + { + "dest": "south-east", + "rule": [] + }, + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "east-upper", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "east-lower", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "east-upper", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "east-lower", + "direction": "right", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": true + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-05", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ], + "locations": [ + { + "name": "key_2", + "display_name": "Depths Key", + "type": "key", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-07", + "regions": [ + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-09", + "regions": [ + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [ [ "red_boosters", "dash_switches" ] ] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-10", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-11", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "dash_switches" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-12", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-13", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-east", + "rule": [ [ "swap_blocks" ] ] + }, + { + "dest": "east", + "rule": [ [ "dash_switches", "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-17", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [ [ "strawberry_seeds", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-22", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "cassette", + "display_name": "Cassette", + "type": "cassette", + "rule": [ [ "red_boosters", "pink_cassette_blocks", "blue_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-east", + "rule": [ [ "red_boosters" ] ] + }, + { + "dest": "east", + "rule": [ [ "red_boosters", "Depths Key" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "red_boosters", "Depths Key" ] ] + } + ] + }, + { + "name": "north-east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-19", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "red_boosters", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-14", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north", + "rule": [] + }, + { + "dest": "south", + "rule": [ [ "Depths Key" ] ] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [ [ "Depths Key" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "south", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-15", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "crystal_heart", + "display_name": "Crystal Heart", + "type": "crystal_heart", + "rule": [ [ "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-16", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "mirror", + "rule": [ [ "red_boosters", "dash_switches" ] ] + } + ] + }, + { + "name": "mirror", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "mirror", + "direction": "special", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "void", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "special", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "special", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-00", + "regions": [ + { + "name": "bottom", + "connections": [] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "special", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "Unravelling", + "checkpoint_region": "top" + }, + { + "name": "c-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-01b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks", "red_boosters", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-01c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks", "red_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-08b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "seekers" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-12", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-11", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-13", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-00", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "north", + "connections": [] + }, + { + "name": "west", + "connections": [] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "red_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Search", + "checkpoint_region": "south" + }, + { + "name": "d-01", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "center", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "south-east-down", + "rule": [] + }, + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + }, + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "south-west-left", + "connections": [ + { + "dest": "south-west-down", + "rule": [] + } + ] + }, + { + "name": "south-west-down", + "connections": [ + { + "dest": "center", + "rule": [] + }, + { + "dest": "south-west-left", + "rule": [] + } + ] + }, + { + "name": "south-east-right", + "connections": [ + { + "dest": "south-east-down", + "rule": [] + } + ] + }, + { + "name": "south-east-down", + "connections": [ + { + "dest": "center", + "rule": [] + }, + { + "dest": "south-east-right", + "rule": [ [ "seekers" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-west-left", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west-down", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east-right", + "direction": "right", + "blocked": true, + "closes_behind": false + }, + { + "name": "south-east-down", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-09", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "red_boosters", "dash_refills", "swap_blocks" ] ] + } + ] + }, + { + "name": "west", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-04", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "red_boosters", "Search Key 1", "Search Key 2" ] ] + }, + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [] + }, + { + "name": "south-west-left", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "key_3", + "display_name": "Search Key 1", + "type": "key", + "rule": [] + } + ] + }, + { + "name": "south-west-right", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "key_4", + "display_name": "Search Key 2", + "type": "key", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [], + "locations": [ + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [ [ "red_boosters", "swap_blocks" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west-left", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west-right", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-05", + "regions": [ + { + "name": "north", + "connections": [ + { + "dest": "west", + "rule": [ [ "red_boosters", "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-06", + "regions": [ + { + "name": "north-east", + "connections": [] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "north-east", + "rule": [ [ "red_boosters", "swap_blocks" ] ] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-07", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "north", + "connections": [ + { + "dest": "west", + "rule": [ [ "coins" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-02", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ + [ "springs" ], + [ "seekers" ] + ] + } + ] + }, + { + "name": "west", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-03", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "coins", "seekers" ] ] + } + ] + }, + { + "name": "west", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-15", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "center", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "south-east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [ [ "swap_blocks", "dash_refills" ] ] + }, + { + "name": "key_5", + "display_name": "Search Key 3", + "type": "key", + "rule": [ [ "swap_blocks", "seekers" ] ] + } + ] + }, + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-13", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-19b", + "regions": [ + { + "name": "south-east-right", + "connections": [ + { + "dest": "south-east-down", + "rule": [] + } + ] + }, + { + "name": "south-east-down", + "connections": [ + { + "dest": "south-east-right", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-east-right", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east-down", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-19", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "swap_blocks", "springs" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "Search Key 3" ] ] + } + ] + }, + { + "name": "west", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-20", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "seekers", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + + { + "name": "e-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "Rescue", + "checkpoint_region": "west" + }, + { + "name": "e-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "dash_switches", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_switches" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "swap_blocks", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "swap_blocks", "springs", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-11", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "theo_crystal" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "red_boosters", "swap_blocks", "dash_switches", "Entrance Key", "Depths Key", "Search Key 1", "Search Key 2", "seekers", "coins", "theo_crystal" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "a-00b", + "source_door": "west", + "dest_room": "a-00x", + "dest_door": "east" + }, + { + "source_room": "a-00b", + "source_door": "east", + "dest_room": "a-00d", + "dest_door": "west" + }, + { + "source_room": "a-00d", + "source_door": "east", + "dest_room": "a-00c", + "dest_door": "west" + }, + { + "source_room": "a-00c", + "source_door": "east", + "dest_room": "a-00", + "dest_door": "west" + }, + { + "source_room": "a-00", + "source_door": "east", + "dest_room": "a-01", + "dest_door": "west" + }, + { + "source_room": "a-01", + "source_door": "east", + "dest_room": "a-13", + "dest_door": "west" + }, + { + "source_room": "a-01", + "source_door": "south-west", + "dest_room": "a-04", + "dest_door": "north" + }, + { + "source_room": "a-01", + "source_door": "south-east", + "dest_room": "a-02", + "dest_door": "north" + }, + { + "source_room": "a-01", + "source_door": "north", + "dest_room": "a-08", + "dest_door": "south" + }, + { + "source_room": "a-02", + "source_door": "west", + "dest_room": "a-03", + "dest_door": "east" + }, + { + "source_room": "a-02", + "source_door": "south", + "dest_room": "a-05", + "dest_door": "north-east" + }, + { + "source_room": "a-04", + "source_door": "east", + "dest_room": "a-03", + "dest_door": "west" + }, + { + "source_room": "a-04", + "source_door": "south", + "dest_room": "a-05", + "dest_door": "north-west" + }, + { + "source_room": "a-05", + "source_door": "south-west", + "dest_room": "a-07", + "dest_door": "east" + }, + { + "source_room": "a-05", + "source_door": "south-east", + "dest_room": "a-06", + "dest_door": "west" + }, + { + "source_room": "a-08", + "source_door": "west", + "dest_room": "a-10", + "dest_door": "east" + }, + { + "source_room": "a-08", + "source_door": "north", + "dest_room": "a-14", + "dest_door": "south" + }, + { + "source_room": "a-08", + "source_door": "north-east", + "dest_room": "a-12", + "dest_door": "north-west" + }, + { + "source_room": "a-08", + "source_door": "south-east", + "dest_room": "a-12", + "dest_door": "south-west" + }, + { + "source_room": "a-10", + "source_door": "west", + "dest_room": "a-09", + "dest_door": "east" + }, + { + "source_room": "a-09", + "source_door": "west", + "dest_room": "a-11", + "dest_door": "east" + }, + { + "source_room": "a-12", + "source_door": "west", + "dest_room": "a-08", + "dest_door": "east" + }, + { + "source_room": "a-12", + "source_door": "east", + "dest_room": "a-15", + "dest_door": "south" + }, + { + "source_room": "a-13", + "source_door": "east", + "dest_room": "b-00", + "dest_door": "west" + }, + + { + "source_room": "b-00", + "source_door": "north-west", + "dest_room": "b-18", + "dest_door": "south" + }, + { + "source_room": "b-00", + "source_door": "east", + "dest_room": "b-01", + "dest_door": "south-west" + }, + { + "source_room": "b-01", + "source_door": "west", + "dest_room": "b-20", + "dest_door": "west" + }, + { + "source_room": "b-01", + "source_door": "north", + "dest_room": "b-20", + "dest_door": "south" + }, + { + "source_room": "b-01", + "source_door": "north-east", + "dest_room": "b-20", + "dest_door": "east" + }, + { + "source_room": "b-01", + "source_door": "east", + "dest_room": "b-01b", + "dest_door": "west" + }, + { + "source_room": "b-01", + "source_door": "south", + "dest_room": "b-01c", + "dest_door": "west" + }, + { + "source_room": "b-01c", + "source_door": "east", + "dest_room": "b-01", + "dest_door": "south-east" + }, + { + "source_room": "b-20", + "source_door": "south-west", + "dest_room": "b-01", + "dest_door": "north-west" + }, + { + "source_room": "b-20", + "source_door": "north-west", + "dest_room": "b-21", + "dest_door": "east" + }, + { + "source_room": "b-01b", + "source_door": "east", + "dest_room": "b-02", + "dest_door": "west" + }, + { + "source_room": "b-02", + "source_door": "north-west", + "dest_room": "b-03", + "dest_door": "east" + }, + { + "source_room": "b-02", + "source_door": "north", + "dest_room": "b-04", + "dest_door": "south" + }, + { + "source_room": "b-02", + "source_door": "north-east", + "dest_room": "b-05", + "dest_door": "west" + }, + { + "source_room": "b-02", + "source_door": "east-upper", + "dest_room": "b-06", + "dest_door": "west" + }, + { + "source_room": "b-02", + "source_door": "east-lower", + "dest_room": "b-11", + "dest_door": "north-west" + }, + { + "source_room": "b-02", + "source_door": "south-east", + "dest_room": "b-11", + "dest_door": "west" + }, + { + "source_room": "b-02", + "source_door": "south", + "dest_room": "b-10", + "dest_door": "east" + }, + { + "source_room": "b-04", + "source_door": "west", + "dest_room": "b-07", + "dest_door": "south" + }, + { + "source_room": "b-07", + "source_door": "north", + "dest_room": "b-08", + "dest_door": "west" + }, + { + "source_room": "b-08", + "source_door": "east", + "dest_room": "b-09", + "dest_door": "north" + }, + { + "source_room": "b-09", + "source_door": "south", + "dest_room": "b-04", + "dest_door": "east" + }, + { + "source_room": "b-11", + "source_door": "south-west", + "dest_room": "b-12", + "dest_door": "west" + }, + { + "source_room": "b-11", + "source_door": "south-east", + "dest_room": "b-12", + "dest_door": "east" + }, + { + "source_room": "b-11", + "source_door": "east", + "dest_room": "b-13", + "dest_door": "west" + }, + { + "source_room": "b-13", + "source_door": "east", + "dest_room": "b-17", + "dest_door": "west" + }, + { + "source_room": "b-13", + "source_door": "north-east", + "dest_room": "b-17", + "dest_door": "north-west" + }, + { + "source_room": "b-17", + "source_door": "east", + "dest_room": "b-22", + "dest_door": "west" + }, + { + "source_room": "b-06", + "source_door": "east", + "dest_room": "b-19", + "dest_door": "west" + }, + { + "source_room": "b-06", + "source_door": "north-east", + "dest_room": "b-19", + "dest_door": "north-west" + }, + { + "source_room": "b-19", + "source_door": "east", + "dest_room": "b-14", + "dest_door": "west" + }, + { + "source_room": "b-14", + "source_door": "south", + "dest_room": "b-15", + "dest_door": "west" + }, + { + "source_room": "b-14", + "source_door": "north", + "dest_room": "b-16", + "dest_door": "bottom" + }, + { + "source_room": "b-16", + "source_door": "mirror", + "dest_room": "void", + "dest_door": "east" + }, + { + "source_room": "void", + "source_door": "west", + "dest_room": "c-00", + "dest_door": "top" + }, + { + "source_room": "c-00", + "source_door": "bottom", + "dest_room": "c-01", + "dest_door": "west" + }, + { + "source_room": "c-01", + "source_door": "east", + "dest_room": "c-01b", + "dest_door": "west" + }, + { + "source_room": "c-01b", + "source_door": "east", + "dest_room": "c-01c", + "dest_door": "west" + }, + { + "source_room": "c-01c", + "source_door": "east", + "dest_room": "c-08b", + "dest_door": "west" + }, + { + "source_room": "c-08b", + "source_door": "east", + "dest_room": "c-08", + "dest_door": "west" + }, + { + "source_room": "c-08", + "source_door": "east", + "dest_room": "c-10", + "dest_door": "west" + }, + { + "source_room": "c-10", + "source_door": "east", + "dest_room": "c-12", + "dest_door": "west" + }, + { + "source_room": "c-12", + "source_door": "east", + "dest_room": "c-07", + "dest_door": "west" + }, + { + "source_room": "c-07", + "source_door": "east", + "dest_room": "c-11", + "dest_door": "west" + }, + { + "source_room": "c-11", + "source_door": "east", + "dest_room": "c-09", + "dest_door": "west" + }, + { + "source_room": "c-09", + "source_door": "east", + "dest_room": "c-13", + "dest_door": "west" + }, + { + "source_room": "c-13", + "source_door": "east", + "dest_room": "d-00", + "dest_door": "south" + }, + + { + "source_room": "d-00", + "source_door": "north", + "dest_room": "d-01", + "dest_door": "south" + }, + { + "source_room": "d-00", + "source_door": "west", + "dest_room": "d-05", + "dest_door": "east" + }, + { + "source_room": "d-05", + "source_door": "south", + "dest_room": "d-02", + "dest_door": "east" + }, + { + "source_room": "d-01", + "source_door": "north-west", + "dest_room": "d-09", + "dest_door": "east" + }, + { + "source_room": "d-01", + "source_door": "west", + "dest_room": "d-09", + "dest_door": "east" + }, + { + "source_room": "d-01", + "source_door": "south-west-down", + "dest_room": "d-05", + "dest_door": "north" + }, + { + "source_room": "d-01", + "source_door": "south-east-down", + "dest_room": "d-07", + "dest_door": "north" + }, + { + "source_room": "d-01", + "source_door": "south-east-right", + "dest_room": "d-15", + "dest_door": "south-west" + }, + { + "source_room": "d-01", + "source_door": "east", + "dest_room": "d-15", + "dest_door": "west" + }, + { + "source_room": "d-01", + "source_door": "north-east", + "dest_room": "d-15", + "dest_door": "north-west" + }, + { + "source_room": "d-09", + "source_door": "west", + "dest_room": "d-04", + "dest_door": "north" + }, + { + "source_room": "d-04", + "source_door": "west", + "dest_room": "d-19b", + "dest_door": "south-east-right" + }, + { + "source_room": "d-04", + "source_door": "south-east", + "dest_room": "d-01", + "dest_door": "south-west-left" + }, + { + "source_room": "d-05", + "source_door": "west", + "dest_room": "d-06", + "dest_door": "south-east" + }, + { + "source_room": "d-05", + "source_door": "south", + "dest_room": "d-02", + "dest_door": "east" + }, + { + "source_room": "d-06", + "source_door": "north-east", + "dest_room": "d-04", + "dest_door": "south-west-right" + }, + { + "source_room": "d-06", + "source_door": "north-west", + "dest_room": "d-04", + "dest_door": "south-west-left" + }, + { + "source_room": "d-07", + "source_door": "west", + "dest_room": "d-00", + "dest_door": "east" + }, + { + "source_room": "d-02", + "source_door": "west", + "dest_room": "d-03", + "dest_door": "east" + }, + { + "source_room": "d-03", + "source_door": "west", + "dest_room": "d-06", + "dest_door": "south-west" + }, + { + "source_room": "d-15", + "source_door": "south-east", + "dest_room": "d-13", + "dest_door": "east" + }, + { + "source_room": "d-13", + "source_door": "west", + "dest_room": "d-15", + "dest_door": "south" + }, + { + "source_room": "d-19b", + "source_door": "south-east-down", + "dest_room": "d-19", + "dest_door": "east" + }, + { + "source_room": "d-19b", + "source_door": "north-east", + "dest_room": "d-10", + "dest_door": "west" + }, + { + "source_room": "d-19", + "source_door": "west", + "dest_room": "d-19b", + "dest_door": "south-west" + }, + { + "source_room": "d-10", + "source_door": "east", + "dest_room": "d-20", + "dest_door": "west" + }, + { + "source_room": "d-20", + "source_door": "east", + "dest_room": "e-00", + "dest_door": "west" + }, + { + "source_room": "e-00", + "source_door": "east", + "dest_room": "e-01", + "dest_door": "west" + }, + { + "source_room": "e-01", + "source_door": "east", + "dest_room": "e-02", + "dest_door": "west" + }, + { + "source_room": "e-02", + "source_door": "east", + "dest_room": "e-03", + "dest_door": "west" + }, + { + "source_room": "e-03", + "source_door": "east", + "dest_room": "e-04", + "dest_door": "west" + }, + { + "source_room": "e-04", + "source_door": "east", + "dest_room": "e-06", + "dest_door": "west" + }, + { + "source_room": "e-06", + "source_door": "east", + "dest_room": "e-05", + "dest_door": "west" + }, + { + "source_room": "e-05", + "source_door": "east", + "dest_room": "e-07", + "dest_door": "west" + }, + { + "source_room": "e-07", + "source_door": "east", + "dest_room": "e-08", + "dest_door": "west" + }, + { + "source_room": "e-08", + "source_door": "east", + "dest_room": "e-09", + "dest_door": "west" + }, + { + "source_room": "e-09", + "source_door": "east", + "dest_room": "e-10", + "dest_door": "west" + }, + { + "source_room": "e-10", + "source_door": "east", + "dest_room": "e-11", + "dest_door": "west" + } + ] + }, + { + "name": "5b", + "display_name": "Mirror Temple B", + "rooms": [ + { + "name": "start", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "a-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "red_boosters", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [ [ "Central Chamber Key 2" ] ] + }, + { + "dest": "north", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Central Chamber", + "checkpoint_region": "south" + }, + { + "name": "b-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north", + "rule": [ [ "swap_blocks", "dash_refills" ] ] + }, + { + "dest": "east", + "rule": [ [ "red_boosters", "Central Chamber Key 2" ] ] + } + ] + }, + { + "name": "north", + "connections": [] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-04", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "swap_blocks", "dash_refills", "red_boosters" ] ] + } + ] + }, + { + "name": "west", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "center", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "north", + "rule": [ [ "red_boosters", "Central Chamber Key 1" ] ] + }, + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "center", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "center", + "rule": [] + } + ], + "locations": [ + { + "name": "key_1", + "display_name": "Central Chamber Key 1", + "type": "key", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "center", + "rule": [] + } + ], + "locations": [ + { + "name": "key_2", + "display_name": "Central Chamber Key 2", + "type": "key", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-05", + "regions": [ + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [ [ "swap_blocks", "dash_refills", "coins" ] ] + } + ] + }, + { + "name": "south", + "connections": [] + } + ], + "doors": [ + { + "name": "north", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-06", + "regions": [ + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-07", + "regions": [ + { + "name": "north", + "connections": [] + }, + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "main", + "connections": [ + { + "dest": "north", + "rule": [ [ "red_boosters", "dash_switches", "Central Chamber Key 1" ] ] + }, + { + "dest": "west", + "rule": [ [ "dash_switches" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "main", + "rule": [ [ "red_boosters", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "main", + "rule": [ [ "red_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-08", + "regions": [ + { + "name": "south", + "connections": [] + }, + { + "name": "north", + "connections": [] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [ [ "swap_blocks", "springs" ] ] + }, + { + "dest": "north", + "rule": [ [ "dash_switches", "swap_blocks", "springs", "Central Chamber Key 1" ] ] + } + ] + } + ], + "doors": [ + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-09", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "mirror", + "rule": [ [ "swap_blocks", "red_boosters", "dash_switches" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "mirror", + "connections": [] + } + ], + "doors": [ + { + "name": "mirror", + "direction": "special", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-00", + "regions": [ + { + "name": "bottom", + "connections": [] + }, + { + "name": "mirror", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dash_refills", "dash_switches" ] ] + } + ] + } + ], + "doors": [ + { + "name": "mirror", + "direction": "special", + "blocked": false, + "closes_behind": true + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Through the Mirror", + "checkpoint_region": "mirror" + }, + { + "name": "c-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "seekers", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "seekers", "dash_switches", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "seekers", "red_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "seekers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Mix Master", + "checkpoint_region": "west" + }, + { + "name": "d-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "springs", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "springs", "dash_switches", "seekers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "springs", "swap_blocks", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "theo_crystal", "springs", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "pink_cassette_blocks", "blue_cassette_blocks", "springs", "swap_blocks" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "Central Chamber Key 1", "Central Chamber Key 2", "pink_cassette_blocks", "blue_cassette_blocks", "theo_crystal", "dash_refills", "springs", "coins", "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "start", + "source_door": "east", + "dest_room": "a-00", + "dest_door": "west" + }, + { + "source_room": "a-00", + "source_door": "east", + "dest_room": "a-01", + "dest_door": "west" + }, + { + "source_room": "a-01", + "source_door": "east", + "dest_room": "a-02", + "dest_door": "west" + }, + { + "source_room": "a-02", + "source_door": "east", + "dest_room": "b-00", + "dest_door": "south" + }, + { + "source_room": "b-00", + "source_door": "east", + "dest_room": "b-01", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "north", + "dest_room": "b-02", + "dest_door": "south" + }, + { + "source_room": "b-00", + "source_door": "west", + "dest_room": "b-06", + "dest_door": "east" + }, + { + "source_room": "b-01", + "source_door": "north", + "dest_room": "b-04", + "dest_door": "east" + }, + { + "source_room": "b-01", + "source_door": "east", + "dest_room": "b-07", + "dest_door": "south" + }, + { + "source_room": "b-04", + "source_door": "west", + "dest_room": "b-02", + "dest_door": "south-east" + }, + { + "source_room": "b-02", + "source_door": "north-west", + "dest_room": "b-05", + "dest_door": "north" + }, + { + "source_room": "b-02", + "source_door": "north-east", + "dest_room": "b-03", + "dest_door": "west" + }, + { + "source_room": "b-02", + "source_door": "north", + "dest_room": "b-08", + "dest_door": "south" + }, + { + "source_room": "b-05", + "source_door": "south", + "dest_room": "b-02", + "dest_door": "south-west" + }, + { + "source_room": "b-07", + "source_door": "north", + "dest_room": "b-03", + "dest_door": "east" + }, + { + "source_room": "b-03", + "source_door": "north", + "dest_room": "b-08", + "dest_door": "east" + }, + { + "source_room": "b-08", + "source_door": "north", + "dest_room": "b-09", + "dest_door": "bottom" + }, + { + "source_room": "b-09", + "source_door": "mirror", + "dest_room": "c-00", + "dest_door": "mirror" + }, + { + "source_room": "c-00", + "source_door": "bottom", + "dest_room": "c-01", + "dest_door": "west" + }, + { + "source_room": "c-01", + "source_door": "east", + "dest_room": "c-02", + "dest_door": "west" + }, + { + "source_room": "c-02", + "source_door": "east", + "dest_room": "c-03", + "dest_door": "west" + }, + { + "source_room": "c-03", + "source_door": "east", + "dest_room": "c-04", + "dest_door": "west" + }, + { + "source_room": "c-04", + "source_door": "east", + "dest_room": "d-00", + "dest_door": "west" + }, + { + "source_room": "d-00", + "source_door": "east", + "dest_room": "d-01", + "dest_door": "west" + }, + { + "source_room": "d-00", + "source_door": "east", + "dest_room": "d-01", + "dest_door": "west" + }, + { + "source_room": "d-01", + "source_door": "east", + "dest_room": "d-02", + "dest_door": "west" + }, + { + "source_room": "d-02", + "source_door": "east", + "dest_room": "d-03", + "dest_door": "west" + }, + { + "source_room": "d-03", + "source_door": "east", + "dest_room": "d-04", + "dest_door": "west" + }, + { + "source_room": "d-04", + "source_door": "east", + "dest_room": "d-05", + "dest_door": "west" + } + ] + }, + { + "name": "5c", + "display_name": "Mirror Temple C", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "swap_blocks", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "red_boosters", "dash_refills", "dash_switches" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "red_boosters", "dash_refills", "dash_switches", "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + } + ] + }, + { + "name": "6a", + "display_name": "Reflection A", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "kevin_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "east" + }, + { + "name": "01", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "bottom-west", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "bottom-west", + "connections": [] + }, + { + "name": "top-west", + "connections": [ + { + "dest": "top", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "top-west", + "rule": [ [ "feathers" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "bottom-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02b", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "kevin_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "04", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "south-west", + "rule": [ [ "kevin_blocks" ] ] + }, + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "north-west", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-west", + "direction": "left", + "blocked": true, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Hollows", + "checkpoint_region": "south" + }, + { + "name": "04b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "04c", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "crystal_heart", + "display_name": "Crystal Heart", + "type": "crystal_heart", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "04d", + "regions": [ + { + "name": "west", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "04e", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "cassette", + "display_name": "Cassette", + "type": "cassette", + "rule": [ [ "pink_cassette_blocks", "blue_cassette_blocks", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "kevin_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "kevin_blocks", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "08a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "kevin_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "08b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "kevin_blocks", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "east", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "10b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "bumpers" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "11", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "north-east", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "12b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "kevin_blocks", "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "bumpers" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "13", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "14a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "14b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "coins", "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "15", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "16a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "16b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "17", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "north-east", + "rule": [ [ "kevin_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "cannot_access" ] ] + }, + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "18a", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "18b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "19", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [ [ "feathers" ] ] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "20", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Reflection", + "checkpoint_region": "west" + }, + { + "name": "b-00b", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00c", + "regions": [ + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "kevin_blocks" ] ] + } + ] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02b", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "kevin_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Rock Bottom", + "checkpoint_region": "west" + }, + { + "name": "boss-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "feathers" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "bumpers" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-11", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-12", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-13", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-14", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-15", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-16", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-17", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-18", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "feathers", "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-19", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "feathers", "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "boss-20", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "feathers", "dash_refills", "kevin_blocks", "bumpers", "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "after-00", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Resolution", + "checkpoint_region": "bottom" + }, + { + "name": "after-01", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "goal", + "rule": [ [ "badeline_boosters" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "west", + "dest_room": "01", + "dest_door": "bottom" + }, + { + "source_room": "01", + "source_door": "top", + "dest_room": "02", + "dest_door": "bottom" + }, + { + "source_room": "02", + "source_door": "bottom-west", + "dest_room": "03", + "dest_door": "bottom" + }, + { + "source_room": "02", + "source_door": "top", + "dest_room": "02b", + "dest_door": "bottom" + }, + { + "source_room": "03", + "source_door": "top", + "dest_room": "02", + "dest_door": "top-west" + }, + { + "source_room": "02b", + "source_door": "top", + "dest_room": "04", + "dest_door": "south" + }, + + { + "source_room": "04", + "source_door": "north-west", + "dest_room": "04b", + "dest_door": "east" + }, + { + "source_room": "04", + "source_door": "south-east", + "dest_room": "04d", + "dest_door": "west" + }, + { + "source_room": "04", + "source_door": "east", + "dest_room": "05", + "dest_door": "west" + }, + { + "source_room": "04", + "source_door": "south-west", + "dest_room": "04e", + "dest_door": "east" + }, + { + "source_room": "04b", + "source_door": "west", + "dest_room": "04c", + "dest_door": "east" + }, + { + "source_room": "05", + "source_door": "east", + "dest_room": "06", + "dest_door": "west" + }, + { + "source_room": "06", + "source_door": "east", + "dest_room": "07", + "dest_door": "west" + }, + { + "source_room": "07", + "source_door": "east", + "dest_room": "08a", + "dest_door": "west" + }, + { + "source_room": "07", + "source_door": "north-east", + "dest_room": "08b", + "dest_door": "west" + }, + { + "source_room": "08a", + "source_door": "east", + "dest_room": "09", + "dest_door": "west" + }, + { + "source_room": "08b", + "source_door": "east", + "dest_room": "09", + "dest_door": "north-west" + }, + { + "source_room": "09", + "source_door": "east", + "dest_room": "10a", + "dest_door": "west" + }, + { + "source_room": "09", + "source_door": "north-east", + "dest_room": "10b", + "dest_door": "west" + }, + { + "source_room": "10a", + "source_door": "east", + "dest_room": "11", + "dest_door": "west" + }, + { + "source_room": "10b", + "source_door": "east", + "dest_room": "11", + "dest_door": "north-west" + }, + { + "source_room": "11", + "source_door": "east", + "dest_room": "12a", + "dest_door": "west" + }, + { + "source_room": "11", + "source_door": "north-east", + "dest_room": "12b", + "dest_door": "west" + }, + { + "source_room": "12a", + "source_door": "east", + "dest_room": "13", + "dest_door": "west" + }, + { + "source_room": "12b", + "source_door": "east", + "dest_room": "13", + "dest_door": "north-west" + }, + { + "source_room": "13", + "source_door": "east", + "dest_room": "14a", + "dest_door": "west" + }, + { + "source_room": "13", + "source_door": "north-east", + "dest_room": "14b", + "dest_door": "west" + }, + { + "source_room": "14a", + "source_door": "east", + "dest_room": "15", + "dest_door": "west" + }, + { + "source_room": "14b", + "source_door": "east", + "dest_room": "15", + "dest_door": "north-west" + }, + { + "source_room": "15", + "source_door": "east", + "dest_room": "16a", + "dest_door": "west" + }, + { + "source_room": "15", + "source_door": "north-east", + "dest_room": "16b", + "dest_door": "west" + }, + { + "source_room": "16a", + "source_door": "east", + "dest_room": "17", + "dest_door": "west" + }, + { + "source_room": "16b", + "source_door": "east", + "dest_room": "17", + "dest_door": "north-west" + }, + { + "source_room": "17", + "source_door": "east", + "dest_room": "18a", + "dest_door": "west" + }, + { + "source_room": "17", + "source_door": "north-east", + "dest_room": "18b", + "dest_door": "west" + }, + { + "source_room": "18a", + "source_door": "east", + "dest_room": "19", + "dest_door": "west" + }, + { + "source_room": "18b", + "source_door": "east", + "dest_room": "19", + "dest_door": "north-west" + }, + { + "source_room": "19", + "source_door": "east", + "dest_room": "20", + "dest_door": "west" + }, + { + "source_room": "20", + "source_door": "east", + "dest_room": "b-00", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "east", + "dest_room": "b-01", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "top", + "dest_room": "b-00b", + "dest_door": "bottom" + }, + { + "source_room": "b-00b", + "source_door": "top", + "dest_room": "b-00c", + "dest_door": "east" + }, + { + "source_room": "b-01", + "source_door": "east", + "dest_room": "b-02", + "dest_door": "top" + }, + { + "source_room": "b-02", + "source_door": "bottom", + "dest_room": "b-02b", + "dest_door": "top" + }, + { + "source_room": "b-02b", + "source_door": "bottom", + "dest_room": "b-03", + "dest_door": "west" + }, + { + "source_room": "b-03", + "source_door": "east", + "dest_room": "boss-00", + "dest_door": "west" + }, + { + "source_room": "boss-00", + "source_door": "east", + "dest_room": "boss-01", + "dest_door": "west" + }, + { + "source_room": "boss-01", + "source_door": "east", + "dest_room": "boss-02", + "dest_door": "west" + }, + { + "source_room": "boss-02", + "source_door": "east", + "dest_room": "boss-03", + "dest_door": "west" + }, + { + "source_room": "boss-03", + "source_door": "east", + "dest_room": "boss-04", + "dest_door": "west" + }, + { + "source_room": "boss-04", + "source_door": "east", + "dest_room": "boss-05", + "dest_door": "west" + }, + { + "source_room": "boss-05", + "source_door": "east", + "dest_room": "boss-06", + "dest_door": "west" + }, + { + "source_room": "boss-06", + "source_door": "east", + "dest_room": "boss-07", + "dest_door": "west" + }, + { + "source_room": "boss-07", + "source_door": "east", + "dest_room": "boss-08", + "dest_door": "west" + }, + { + "source_room": "boss-08", + "source_door": "east", + "dest_room": "boss-09", + "dest_door": "west" + }, + { + "source_room": "boss-09", + "source_door": "east", + "dest_room": "boss-10", + "dest_door": "west" + }, + { + "source_room": "boss-10", + "source_door": "east", + "dest_room": "boss-11", + "dest_door": "west" + }, + { + "source_room": "boss-11", + "source_door": "east", + "dest_room": "boss-12", + "dest_door": "west" + }, + { + "source_room": "boss-12", + "source_door": "east", + "dest_room": "boss-13", + "dest_door": "west" + }, + { + "source_room": "boss-13", + "source_door": "east", + "dest_room": "boss-14", + "dest_door": "west" + }, + { + "source_room": "boss-14", + "source_door": "east", + "dest_room": "boss-15", + "dest_door": "west" + }, + { + "source_room": "boss-15", + "source_door": "east", + "dest_room": "boss-16", + "dest_door": "west" + }, + { + "source_room": "boss-16", + "source_door": "east", + "dest_room": "boss-17", + "dest_door": "west" + }, + { + "source_room": "boss-17", + "source_door": "east", + "dest_room": "boss-18", + "dest_door": "west" + }, + { + "source_room": "boss-18", + "source_door": "east", + "dest_room": "boss-19", + "dest_door": "west" + }, + { + "source_room": "boss-19", + "source_door": "east", + "dest_room": "boss-20", + "dest_door": "west" + }, + { + "source_room": "boss-20", + "source_door": "east", + "dest_room": "after-00", + "dest_door": "bottom" + }, + { + "source_room": "after-00", + "source_door": "top", + "dest_room": "after-01", + "dest_door": "bottom" + } + ] + }, + { + "name": "6b", + "display_name": "Reflection B", + "rooms": [ + { + "name": "a-00", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "kevin_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "bottom" + }, + { + "name": "a-01", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "feathers", "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "bumpers", "feathers" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "kevin_blocks", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers", "kevin_blocks", "dash_refills", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Reflection", + "checkpoint_region": "west" + }, + { + "name": "b-01", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dash_refills", "kevin_blocks" ] ] + } + ] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-04", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-05", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dash_refills", "kevin_blocks" ] ] + } + ] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-06", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-07", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dash_refills", "feathers" ] ] + } + ] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-08", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Rock Bottom", + "checkpoint_region": "west" + }, + { + "name": "c-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "feathers", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "feathers", "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "kevin_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Reprieve", + "checkpoint_region": "west" + }, + { + "name": "d-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers", "feathers", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers", "kevin_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers", "kevin_blocks", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "blue_cassette_blocks", "bumpers" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "blue_cassette_blocks", "bumpers", "dash_refills", "springs", "coins", "kevin_blocks", "feathers" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "a-00", + "source_door": "top", + "dest_room": "a-01", + "dest_door": "bottom" + }, + { + "source_room": "a-01", + "source_door": "top", + "dest_room": "a-02", + "dest_door": "bottom" + }, + { + "source_room": "a-02", + "source_door": "top", + "dest_room": "a-03", + "dest_door": "west" + }, + { + "source_room": "a-03", + "source_door": "east", + "dest_room": "a-04", + "dest_door": "west" + }, + { + "source_room": "a-04", + "source_door": "east", + "dest_room": "a-05", + "dest_door": "west" + }, + { + "source_room": "a-05", + "source_door": "east", + "dest_room": "a-06", + "dest_door": "west" + }, + { + "source_room": "a-06", + "source_door": "east", + "dest_room": "b-00", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "east", + "dest_room": "b-01", + "dest_door": "top" + }, + { + "source_room": "b-01", + "source_door": "bottom", + "dest_room": "b-02", + "dest_door": "top" + }, + { + "source_room": "b-02", + "source_door": "bottom", + "dest_room": "b-03", + "dest_door": "top" + }, + { + "source_room": "b-03", + "source_door": "bottom", + "dest_room": "b-04", + "dest_door": "top" + }, + { + "source_room": "b-04", + "source_door": "bottom", + "dest_room": "b-05", + "dest_door": "top" + }, + { + "source_room": "b-05", + "source_door": "bottom", + "dest_room": "b-06", + "dest_door": "top" + }, + { + "source_room": "b-06", + "source_door": "bottom", + "dest_room": "b-07", + "dest_door": "top" + }, + { + "source_room": "b-07", + "source_door": "bottom", + "dest_room": "b-08", + "dest_door": "top" + }, + { + "source_room": "b-08", + "source_door": "bottom", + "dest_room": "b-10", + "dest_door": "west" + }, + { + "source_room": "b-10", + "source_door": "east", + "dest_room": "c-00", + "dest_door": "west" + }, + { + "source_room": "c-00", + "source_door": "east", + "dest_room": "c-01", + "dest_door": "west" + }, + { + "source_room": "c-01", + "source_door": "east", + "dest_room": "c-02", + "dest_door": "west" + }, + { + "source_room": "c-02", + "source_door": "east", + "dest_room": "c-03", + "dest_door": "west" + }, + { + "source_room": "c-03", + "source_door": "east", + "dest_room": "c-04", + "dest_door": "west" + }, + { + "source_room": "c-04", + "source_door": "east", + "dest_room": "d-00", + "dest_door": "west" + }, + { + "source_room": "d-00", + "source_door": "east", + "dest_room": "d-01", + "dest_door": "west" + }, + { + "source_room": "d-01", + "source_door": "east", + "dest_room": "d-02", + "dest_door": "west" + }, + { + "source_room": "d-02", + "source_door": "east", + "dest_room": "d-03", + "dest_door": "west" + }, + { + "source_room": "d-03", + "source_door": "east", + "dest_room": "d-04", + "dest_door": "west" + }, + { + "source_room": "d-04", + "source_door": "east", + "dest_room": "d-05", + "dest_door": "west" + } + ] + }, + { + "name": "6c", + "display_name": "Reflection C", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "kevin_blocks", "dash_refills", "bumpers" ] ] + } + ], + "locations": [ + { + "name": "binoculars_1", + "display_name": "Binoculars 1", + "type": "binoculars", + "rule": [] + }, + { + "name": "binoculars_2", + "display_name": "Binoculars 2", + "type": "binoculars", + "rule": [ [ "kevin_blocks", "dash_refills", "bumpers" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "kevin_blocks", "dash_refills", "bumpers", "feathers" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + } + ] + }, + { + "name": "7a", + "display_name": "The Summit A", + "rooms": [ + { + "name": "a-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "a-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north", + "rule": [ [ "springs" ] ] + }, + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02b", + "regions": [ + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "springs" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": true, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-04b", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [ [ "springs", "dash_refills" ] ] + }, + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-06", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "badeline_boosters", "springs" ] ] + }, + { + "dest": "top-side", + "rule": [ [ "badeline_boosters", "springs" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + }, + { + "name": "top-side", + "connections": [ + { + "dest": "top", + "rule": [ [ "badeline_boosters" ] ] + } + ], + "locations": [ + { + "name": "gem_1", + "display_name": "Gem 1", + "type": "gem", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "500 M", + "checkpoint_region": "bottom" + }, + { + "name": "b-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks", "springs" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + }, + { + "dest": "north-east", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "north", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "north", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02b", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + }, + { + "dest": "north-east", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "north-west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02e", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "traffic_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + }, + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02d", + "regions": [ + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "gem_2", + "display_name": "Gem 2", + "type": "gem", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north", + "rule": [ [ "traffic_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-04", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "coins", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-09", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "traffic_blocks", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "traffic_blocks" ] ] + }, + { + "dest": "top-side", + "rule": [] + } + ] + }, + { + "name": "top-side", + "connections": [ + { + "dest": "top", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "1000 M", + "checkpoint_region": "west" + }, + { + "name": "c-01", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-02", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks", "springs", "coins" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-03", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-03b", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "dream_blocks" ] ] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north-east", + "rule": [ [ "dream_blocks" ] ] + }, + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-05", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-06", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "dream_blocks" ] ] + }, + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-06b", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "dream_blocks" ] ] + } + ] + }, + { + "name": "north", + "connections": [] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": true, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-06c", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "gem_3", + "display_name": "Gem 3", + "type": "gem", + "rule": [ [ "dream_blocks", "coins" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south-east", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-07b", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dream_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-09", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "dream_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-00", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "1500 M", + "checkpoint_region": "bottom" + }, + { + "name": "d-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "sinking_platforms" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "sinking_platforms" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-01b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-01c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "south", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "sinking_platforms" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-01d", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "coins", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "cannot_access" ] ] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-03b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "cassette", + "display_name": "Cassette", + "type": "cassette", + "rule": [ [ "blue_cassette_blocks", "pink_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ + [ "coins" ], + [ "dash_refills" ] + ] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + }, + { + "dest": "north-east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-05b", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "gem_4", + "display_name": "Gem 4", + "type": "gem", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south-east", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": true, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-07", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "north-east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north", + "rule": [ [ "dash_refills" ] ] + }, + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north-east", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-10b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "springs" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-11", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-00b", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [ [ "blue_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "2000 M", + "checkpoint_region": "bottom" + }, + { + "name": "e-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "north-west", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters", "blue_clouds" ] ] + }, + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south-west", + "rule": [ [ "blue_boosters", "blue_clouds" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-01", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "north", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-01b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-01c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks" ] ] + } + ], + "locations": [ + { + "name": "gem_5", + "display_name": "Gem 5", + "type": "gem", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pink_clouds" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "pink_clouds" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-03", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters", "moving_platforms" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-07", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "move_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "move_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-08", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_clouds" ] ] + }, + { + "dest": "east", + "rule": [ [ "blue_clouds" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-09", + "regions": [ + { + "name": "north", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north", + "direction": "up", + "blocked": true, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-11", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "move_blocks" ] ] + }, + { + "dest": "east", + "rule": [ [ "move_blocks", "blue_boosters" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-12", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "strawberry_seeds", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-10", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "south", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-10b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks", "dash_refills", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-13", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "badeline_boosters", "dash_refills", "move_blocks", "blue_boosters", "springs" ] ] + } + ] + }, + { + "name": "top", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-00", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "north-east", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "north-east", + "connections": [] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "left", + "blocked": true, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "2500 M", + "checkpoint_region": "south" + }, + { + "name": "f-01", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "right", + "blocked": true, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "north-east", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": true, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-02b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "red_boosters", "dash_refills", "swap_blocks", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "gem_6", + "display_name": "Gem 6", + "type": "gem", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "swap_blocks", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "south-west", + "rule": [] + }, + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "north", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + }, + { + "dest": "south-east", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "2500 M Key" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-06", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "north", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "north-west", + "rule": [] + }, + { + "dest": "north-east", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south-west", + "rule": [] + } + ] + }, + { + "name": "south-west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "south", + "connections": [] + }, + { + "name": "south-east", + "connections": [], + "locations": [ + { + "name": "key", + "display_name": "2500 M Key", + "type": "key", + "rule": [ [ "red_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "south-west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north-west", + "rule": [ [ "red_boosters" ] ] + }, + { + "dest": "east", + "rule": [ [ "swap_blocks", "red_boosters", "dash_refills" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": true, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-08b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "springs" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "swap_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-08d", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_switches", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-08c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "swap_blocks" ] ] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-10b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "dash_refills", "dash_switches" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-11", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "badeline_boosters", "swap_blocks", "springs", "red_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [] + }, + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [] + }, + { + "name": "strawberry_3", + "display_name": "Strawberry 3", + "type": "strawberry", + "rule": [ [ "dash_switches" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-00", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "3000 M", + "checkpoint_region": "bottom" + }, + { + "name": "g-00b", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "c26", + "rule": [] + } + ], + "locations": [ + { + "name": "crystal_heart", + "display_name": "Crystal Heart", + "type": "crystal_heart", + "rule": [ [ "Gem 1", "Gem 2", "Gem 3", "Gem 4", "Gem 5", "Gem 6" ] ] + } + ] + }, + { + "name": "c26", + "connections": [ + { + "dest": "c24", + "rule": [ [ "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "c24", + "connections": [ + { + "dest": "c21", + "rule": [ [ "springs" ] ] + } + ], + "locations": [ + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "c21", + "connections": [ + { + "dest": "top", + "rule": [ [ "springs", "dash_refills", "badeline_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry_3", + "display_name": "Strawberry 3", + "type": "strawberry", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-01", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "c18", + "rule": [ [ "blue_clouds" ] ] + } + ] + }, + { + "name": "c18", + "connections": [ + { + "dest": "c16", + "rule": [ [ "dash_refills", "blue_clouds" ] ] + } + ], + "locations": [ + { + "name": "strawberry_1", + "display_name": "Strawberry 1", + "type": "strawberry", + "rule": [ [ "dash_refills", "blue_clouds" ] ] + } + ] + }, + { + "name": "c16", + "connections": [ + { + "dest": "top", + "rule": [ [ "springs", "coins", "dash_refills", "pink_clouds", "badeline_boosters" ] ] + } + ], + "locations": [ + { + "name": "strawberry_2", + "display_name": "Strawberry 2", + "type": "strawberry", + "rule": [] + }, + { + "name": "strawberry_3", + "display_name": "Strawberry 3", + "type": "strawberry", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-02", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "blue_clouds", "feathers" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "goal", + "rule": [ [ "springs", "dash_refills", "feathers" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [ [ "springs" ] ] + }, + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "springs", "dash_refills", "feathers" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "springs", "dash_refills", "feathers", "blue_clouds", "pink_clouds", "coins", "badeline_boosters", "red_boosters", "swap_blocks", "dash_switches", "2500 M Key", "move_blocks", "blue_boosters", "dream_blocks", "traffic_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "a-00", + "source_door": "east", + "dest_room": "a-01", + "dest_door": "west" + }, + { + "source_room": "a-01", + "source_door": "east", + "dest_room": "a-02", + "dest_door": "west" + }, + { + "source_room": "a-02", + "source_door": "north", + "dest_room": "a-02b", + "dest_door": "east" + }, + { + "source_room": "a-02b", + "source_door": "west", + "dest_room": "a-02", + "dest_door": "north-west" + }, + { + "source_room": "a-02", + "source_door": "east", + "dest_room": "a-03", + "dest_door": "west" + }, + { + "source_room": "a-03", + "source_door": "east", + "dest_room": "a-04", + "dest_door": "west" + }, + { + "source_room": "a-04", + "source_door": "north", + "dest_room": "a-04b", + "dest_door": "east" + }, + { + "source_room": "a-04", + "source_door": "east", + "dest_room": "a-05", + "dest_door": "west" + }, + { + "source_room": "a-05", + "source_door": "east", + "dest_room": "a-06", + "dest_door": "bottom" + }, + { + "source_room": "a-06", + "source_door": "top", + "dest_room": "b-00", + "dest_door": "bottom" + }, + { + "source_room": "b-00", + "source_door": "top", + "dest_room": "b-01", + "dest_door": "west" + }, + { + "source_room": "b-01", + "source_door": "east", + "dest_room": "b-02", + "dest_door": "south" + }, + { + "source_room": "b-02", + "source_door": "north-west", + "dest_room": "b-02b", + "dest_door": "south" + }, + { + "source_room": "b-02", + "source_door": "north", + "dest_room": "b-02d", + "dest_door": "south" + }, + { + "source_room": "b-02", + "source_door": "north-east", + "dest_room": "b-03", + "dest_door": "west" + }, + { + "source_room": "b-02b", + "source_door": "north-west", + "dest_room": "b-02e", + "dest_door": "east" + }, + { + "source_room": "b-02b", + "source_door": "north-east", + "dest_room": "b-02c", + "dest_door": "west" + }, + { + "source_room": "b-02c", + "source_door": "east", + "dest_room": "b-05", + "dest_door": "north-west" + }, + { + "source_room": "b-02c", + "source_door": "south-east", + "dest_room": "b-02d", + "dest_door": "north" + }, + { + "source_room": "b-03", + "source_door": "east", + "dest_room": "b-04", + "dest_door": "west" + }, + { + "source_room": "b-03", + "source_door": "north", + "dest_room": "b-05", + "dest_door": "west" + }, + { + "source_room": "b-05", + "source_door": "east", + "dest_room": "b-06", + "dest_door": "west" + }, + { + "source_room": "b-06", + "source_door": "east", + "dest_room": "b-07", + "dest_door": "west" + }, + { + "source_room": "b-07", + "source_door": "east", + "dest_room": "b-08", + "dest_door": "west" + }, + { + "source_room": "b-08", + "source_door": "east", + "dest_room": "b-09", + "dest_door": "bottom" + }, + { + "source_room": "b-09", + "source_door": "top", + "dest_room": "c-00", + "dest_door": "west" + }, + { + "source_room": "c-00", + "source_door": "east", + "dest_room": "c-01", + "dest_door": "bottom" + }, + { + "source_room": "c-01", + "source_door": "top", + "dest_room": "c-02", + "dest_door": "bottom" + }, + { + "source_room": "c-02", + "source_door": "top", + "dest_room": "c-03", + "dest_door": "south" + }, + { + "source_room": "c-03", + "source_door": "west", + "dest_room": "c-03b", + "dest_door": "east" + }, + { + "source_room": "c-03", + "source_door": "east", + "dest_room": "c-04", + "dest_door": "west" + }, + { + "source_room": "c-04", + "source_door": "north-west", + "dest_room": "c-06", + "dest_door": "south" + }, + { + "source_room": "c-04", + "source_door": "north-east", + "dest_room": "c-06b", + "dest_door": "south" + }, + { + "source_room": "c-04", + "source_door": "east", + "dest_room": "c-05", + "dest_door": "west" + }, + { + "source_room": "c-06", + "source_door": "east", + "dest_room": "c-06b", + "dest_door": "west" + }, + { + "source_room": "c-06", + "source_door": "north", + "dest_room": "c-07", + "dest_door": "south-west" + }, + { + "source_room": "c-06b", + "source_door": "east", + "dest_room": "c-06c", + "dest_door": "west" + }, + { + "source_room": "c-06b", + "source_door": "north", + "dest_room": "c-07", + "dest_door": "south-east" + }, + { + "source_room": "c-07", + "source_door": "west", + "dest_room": "c-07b", + "dest_door": "east" + }, + { + "source_room": "c-07", + "source_door": "east", + "dest_room": "c-08", + "dest_door": "west" + }, + { + "source_room": "c-08", + "source_door": "east", + "dest_room": "c-09", + "dest_door": "bottom" + }, + { + "source_room": "c-09", + "source_door": "top", + "dest_room": "d-00", + "dest_door": "bottom" + }, + { + "source_room": "d-00", + "source_door": "top", + "dest_room": "d-01", + "dest_door": "west" + }, + { + "source_room": "d-01", + "source_door": "east", + "dest_room": "d-01b", + "dest_door": "west" + }, + { + "source_room": "d-01b", + "source_door": "east", + "dest_room": "d-02", + "dest_door": "west" + }, + { + "source_room": "d-01b", + "source_door": "south-west", + "dest_room": "d-01c", + "dest_door": "west" + }, + { + "source_room": "d-01c", + "source_door": "south", + "dest_room": "d-01d", + "dest_door": "west" + }, + { + "source_room": "d-01c", + "source_door": "east", + "dest_room": "d-01b", + "dest_door": "south-east" + }, + { + "source_room": "d-01d", + "source_door": "east", + "dest_room": "d-01c", + "dest_door": "south-east" + }, + { + "source_room": "d-02", + "source_door": "east", + "dest_room": "d-03", + "dest_door": "west" + }, + { + "source_room": "d-03", + "source_door": "east", + "dest_room": "d-04", + "dest_door": "west" + }, + { + "source_room": "d-03", + "source_door": "north-east", + "dest_room": "d-03b", + "dest_door": "east" + }, + { + "source_room": "d-03b", + "source_door": "west", + "dest_room": "d-03", + "dest_door": "north-west" + }, + { + "source_room": "d-04", + "source_door": "east", + "dest_room": "d-05", + "dest_door": "west" + }, + { + "source_room": "d-05", + "source_door": "east", + "dest_room": "d-05b", + "dest_door": "west" + }, + { + "source_room": "d-05", + "source_door": "north-east", + "dest_room": "d-06", + "dest_door": "south-west" + }, + { + "source_room": "d-06", + "source_door": "west", + "dest_room": "d-07", + "dest_door": "east" + }, + { + "source_room": "d-06", + "source_door": "south-east", + "dest_room": "d-08", + "dest_door": "west" + }, + { + "source_room": "d-06", + "source_door": "east", + "dest_room": "d-09", + "dest_door": "west" + }, + { + "source_room": "d-08", + "source_door": "east", + "dest_room": "d-10", + "dest_door": "west" + }, + { + "source_room": "d-09", + "source_door": "east", + "dest_room": "d-10", + "dest_door": "north-west" + }, + { + "source_room": "d-10", + "source_door": "north-east", + "dest_room": "d-10b", + "dest_door": "east" + }, + { + "source_room": "d-10", + "source_door": "east", + "dest_room": "d-11", + "dest_door": "bottom" + }, + { + "source_room": "d-10b", + "source_door": "west", + "dest_room": "d-10", + "dest_door": "north" + }, + { + "source_room": "d-11", + "source_door": "top", + "dest_room": "e-00b", + "dest_door": "bottom" + }, + { + "source_room": "e-00b", + "source_door": "top", + "dest_room": "e-00", + "dest_door": "south-west" + }, + { + "source_room": "e-00", + "source_door": "west", + "dest_room": "e-01", + "dest_door": "east" + }, + { + "source_room": "e-00", + "source_door": "north-west", + "dest_room": "e-02", + "dest_door": "west" + }, + { + "source_room": "e-00", + "source_door": "east", + "dest_room": "e-03", + "dest_door": "south-west" + }, + { + "source_room": "e-01", + "source_door": "west", + "dest_room": "e-01b", + "dest_door": "east" + }, + { + "source_room": "e-01b", + "source_door": "west", + "dest_room": "e-01c", + "dest_door": "west" + }, + { + "source_room": "e-01c", + "source_door": "east", + "dest_room": "e-01", + "dest_door": "north" + }, + { + "source_room": "e-02", + "source_door": "east", + "dest_room": "e-03", + "dest_door": "west" + }, + { + "source_room": "e-03", + "source_door": "east", + "dest_room": "e-04", + "dest_door": "west" + }, + { + "source_room": "e-04", + "source_door": "east", + "dest_room": "e-05", + "dest_door": "west" + }, + { + "source_room": "e-05", + "source_door": "east", + "dest_room": "e-06", + "dest_door": "west" + }, + { + "source_room": "e-06", + "source_door": "east", + "dest_room": "e-07", + "dest_door": "bottom" + }, + { + "source_room": "e-07", + "source_door": "top", + "dest_room": "e-08", + "dest_door": "south" + }, + { + "source_room": "e-08", + "source_door": "west", + "dest_room": "e-09", + "dest_door": "east" + }, + { + "source_room": "e-08", + "source_door": "east", + "dest_room": "e-10", + "dest_door": "south" + }, + { + "source_room": "e-09", + "source_door": "north", + "dest_room": "e-11", + "dest_door": "south" + }, + { + "source_room": "e-11", + "source_door": "north", + "dest_room": "e-12", + "dest_door": "west" + }, + { + "source_room": "e-11", + "source_door": "east", + "dest_room": "e-10", + "dest_door": "north" + }, + { + "source_room": "e-10", + "source_door": "east", + "dest_room": "e-10b", + "dest_door": "west" + }, + { + "source_room": "e-10b", + "source_door": "east", + "dest_room": "e-13", + "dest_door": "bottom" + }, + { + "source_room": "e-13", + "source_door": "top", + "dest_room": "f-00", + "dest_door": "south" + }, + { + "source_room": "f-00", + "source_door": "west", + "dest_room": "f-01", + "dest_door": "south" + }, + { + "source_room": "f-00", + "source_door": "east", + "dest_room": "f-02", + "dest_door": "west" + }, + { + "source_room": "f-00", + "source_door": "north-east", + "dest_room": "f-02", + "dest_door": "north-west" + }, + { + "source_room": "f-01", + "source_door": "north", + "dest_room": "f-00", + "dest_door": "north-west" + }, + { + "source_room": "f-02", + "source_door": "north-east", + "dest_room": "f-02b", + "dest_door": "west" + }, + { + "source_room": "f-02", + "source_door": "east", + "dest_room": "f-04", + "dest_door": "west" + }, + { + "source_room": "f-02b", + "source_door": "east", + "dest_room": "f-07", + "dest_door": "west" + }, + { + "source_room": "f-04", + "source_door": "east", + "dest_room": "f-03", + "dest_door": "west" + }, + { + "source_room": "f-03", + "source_door": "east", + "dest_room": "f-05", + "dest_door": "west" + }, + { + "source_room": "f-05", + "source_door": "east", + "dest_room": "f-08", + "dest_door": "west" + }, + { + "source_room": "f-05", + "source_door": "south-west", + "dest_room": "f-06", + "dest_door": "north-west" + }, + { + "source_room": "f-05", + "source_door": "south", + "dest_room": "f-06", + "dest_door": "north" + }, + { + "source_room": "f-05", + "source_door": "south-east", + "dest_room": "f-06", + "dest_door": "north-east" + }, + { + "source_room": "f-05", + "source_door": "north-west", + "dest_room": "f-07", + "dest_door": "south-west" + }, + { + "source_room": "f-05", + "source_door": "north", + "dest_room": "f-07", + "dest_door": "south" + }, + { + "source_room": "f-05", + "source_door": "north-east", + "dest_room": "f-07", + "dest_door": "south-east" + }, + { + "source_room": "f-08", + "source_door": "north-west", + "dest_room": "f-08b", + "dest_door": "west" + }, + { + "source_room": "f-08", + "source_door": "east", + "dest_room": "f-09", + "dest_door": "west" + }, + { + "source_room": "f-09", + "source_door": "east", + "dest_room": "f-10", + "dest_door": "west" + }, + { + "source_room": "f-08b", + "source_door": "east", + "dest_room": "f-08d", + "dest_door": "west" + }, + { + "source_room": "f-08d", + "source_door": "east", + "dest_room": "f-08c", + "dest_door": "west" + }, + { + "source_room": "f-08c", + "source_door": "east", + "dest_room": "f-10", + "dest_door": "north-east" + }, + { + "source_room": "f-10", + "source_door": "east", + "dest_room": "f-10b", + "dest_door": "west" + }, + { + "source_room": "f-10b", + "source_door": "east", + "dest_room": "f-11", + "dest_door": "bottom" + }, + { + "source_room": "f-11", + "source_door": "top", + "dest_room": "g-00", + "dest_door": "bottom" + }, + { + "source_room": "g-00", + "source_door": "top", + "dest_room": "g-00b", + "dest_door": "bottom" + }, + { + "source_room": "g-00b", + "source_door": "top", + "dest_room": "g-01", + "dest_door": "bottom" + }, + { + "source_room": "g-01", + "source_door": "top", + "dest_room": "g-02", + "dest_door": "bottom" + }, + { + "source_room": "g-02", + "source_door": "top", + "dest_room": "g-03", + "dest_door": "bottom" + } + ] + }, + { + "name": "7b", + "display_name": "The Summit B", + "rooms": [ + { + "name": "a-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "a-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "springs", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "traffic_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "500 M", + "checkpoint_region": "bottom" + }, + { + "name": "b-01", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "traffic_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "traffic_blocks", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "1000 M", + "checkpoint_region": "west" + }, + { + "name": "c-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "1500 M", + "checkpoint_region": "west" + }, + { + "name": "d-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "moving_platforms", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "springs", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters", "blue_clouds" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "2000 M", + "checkpoint_region": "west" + }, + { + "name": "e-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "blue_clouds", "pink_clouds", "coins", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "2500 M", + "checkpoint_region": "west" + }, + { + "name": "f-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "swap_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "swap_blocks", "dash_refills", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-00", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "springs", "dash_refills", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "3000 M", + "checkpoint_region": "bottom" + }, + { + "name": "g-01", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "springs", "dash_refills", "pink_clouds", "blue_clouds", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-02", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "springs", "dash_refills", "pink_clouds", "blue_clouds", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "goal", + "rule": [ [ "blue_cassette_blocks", "pink_cassette_blocks", "blue_clouds" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "springs", "dash_refills", "blue_clouds", "pink_clouds", "coins", "badeline_boosters", "red_boosters", "swap_blocks", "move_blocks", "blue_boosters", "dream_blocks", "traffic_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "a-00", + "source_door": "east", + "dest_room": "a-01", + "dest_door": "west" + }, + { + "source_room": "a-01", + "source_door": "east", + "dest_room": "a-02", + "dest_door": "west" + }, + { + "source_room": "a-02", + "source_door": "east", + "dest_room": "a-03", + "dest_door": "bottom" + }, + { + "source_room": "a-03", + "source_door": "top", + "dest_room": "b-00", + "dest_door": "bottom" + }, + { + "source_room": "b-00", + "source_door": "top", + "dest_room": "b-01", + "dest_door": "bottom" + }, + { + "source_room": "b-01", + "source_door": "top", + "dest_room": "b-02", + "dest_door": "west" + }, + { + "source_room": "b-02", + "source_door": "east", + "dest_room": "b-03", + "dest_door": "bottom" + }, + { + "source_room": "b-03", + "source_door": "top", + "dest_room": "c-01", + "dest_door": "west" + }, + { + "source_room": "c-01", + "source_door": "east", + "dest_room": "c-00", + "dest_door": "west" + }, + { + "source_room": "c-00", + "source_door": "east", + "dest_room": "c-02", + "dest_door": "west" + }, + { + "source_room": "c-02", + "source_door": "east", + "dest_room": "c-03", + "dest_door": "bottom" + }, + { + "source_room": "c-03", + "source_door": "top", + "dest_room": "d-00", + "dest_door": "west" + }, + { + "source_room": "d-00", + "source_door": "east", + "dest_room": "d-01", + "dest_door": "west" + }, + { + "source_room": "d-01", + "source_door": "east", + "dest_room": "d-02", + "dest_door": "west" + }, + { + "source_room": "d-02", + "source_door": "east", + "dest_room": "d-03", + "dest_door": "bottom" + }, + { + "source_room": "d-03", + "source_door": "top", + "dest_room": "e-00", + "dest_door": "west" + }, + { + "source_room": "e-00", + "source_door": "east", + "dest_room": "e-01", + "dest_door": "west" + }, + { + "source_room": "e-01", + "source_door": "east", + "dest_room": "e-02", + "dest_door": "west" + }, + { + "source_room": "e-02", + "source_door": "east", + "dest_room": "e-03", + "dest_door": "bottom" + }, + { + "source_room": "e-03", + "source_door": "top", + "dest_room": "f-00", + "dest_door": "west" + }, + { + "source_room": "f-00", + "source_door": "east", + "dest_room": "f-01", + "dest_door": "west" + }, + { + "source_room": "f-01", + "source_door": "east", + "dest_room": "f-02", + "dest_door": "west" + }, + { + "source_room": "f-02", + "source_door": "east", + "dest_room": "f-03", + "dest_door": "bottom" + }, + { + "source_room": "f-03", + "source_door": "top", + "dest_room": "g-00", + "dest_door": "bottom" + }, + { + "source_room": "g-00", + "source_door": "top", + "dest_room": "g-01", + "dest_door": "bottom" + }, + { + "source_room": "g-01", + "source_door": "top", + "dest_room": "g-02", + "dest_door": "bottom" + }, + { + "source_room": "g-02", + "source_door": "top", + "dest_room": "g-03", + "dest_door": "bottom" + } + ] + }, + { + "name": "7c", + "display_name": "The Summit C", + "rooms": [ + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "badeline_boosters" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "coins", "badeline_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "pink_clouds", "dash_refills", "springs" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "pink_clouds", "dash_refills", "springs", "coins", "badeline_boosters" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + }, + { + "source_room": "02", + "source_door": "east", + "dest_room": "03", + "dest_door": "west" + } + ] + }, + { + "name": "8a", + "display_name": "Epilogue", + "rooms": [ + { + "name": "outside", + "regions": [ + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "east" + }, + { + "name": "bridge", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "secret", + "regions": [ + { + "name": "west", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "outside", + "source_door": "east", + "dest_room": "bridge", + "dest_door": "west" + }, + { + "source_room": "bridge", + "source_door": "east", + "dest_room": "secret", + "dest_door": "west" + } + ] + }, + { + "name": "9a", + "display_name": "Core A", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "0x", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "car", + "display_name": "Car", + "type": "car", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Into the Core", + "checkpoint_region": "west" + }, + { + "name": "a-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "core_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [] + }, + { + "dest": "north", + "rule": [ [ "fire_ice_balls", "core_toggles", "core_blocks", "dash_refills", "coins" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "core_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "core_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "core_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-04", + "regions": [ + { + "name": "north-west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_toggles" ] ] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks", "core_toggles" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-05", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "fire_ice_balls", "core_toggles", "dash_refills", "coins" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-06", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "fire_ice_balls", "core_toggles", "core_blocks", "dash_refills", "bumpers", "coins" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-07b", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "core_toggles" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-07", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "core_toggles", "core_blocks", "bumpers" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_toggles", "core_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_toggles" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "north-east", + "rule": [ [ "core_toggles", "fire_ice_balls", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Hot and Cold", + "checkpoint_region": "west" + }, + { + "name": "c-00b", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "fire_ice_balls", "core_toggles", "dash_refills", "bumpers" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks", "core_toggles", "fire_ice_balls", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "core_blocks", "core_toggles", "fire_ice_balls", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks", "core_toggles", "dash_refills", "bumpers" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "core_blocks", "core_toggles", "dash_refills", "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "north", + "rule": [ [ "core_toggles", "fire_ice_balls", "dash_refills" ] ] + }, + { + "dest": "east", + "rule": [ [ "core_blocks", "core_toggles", "fire_ice_balls", "dash_refills" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-03b", + "regions": [ + { + "name": "west", + "connections": [] + }, + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [] + }, + { + "dest": "east", + "rule": [ [ "core_toggles" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "core_toggles" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "south", + "rule": [ [ "core_toggles" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-00", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Heart of the Mountain", + "checkpoint_region": "bottom" + }, + { + "name": "d-01", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-02", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "core_toggles" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "core_blocks", "core_toggles" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-04", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-05", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "core_toggles", "fire_ice_balls" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-06", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "core_blocks" ] ] + } + ], + "locations": [ + { + "name": "strawberry", + "display_name": "Strawberry", + "type": "strawberry", + "rule": [ [ "dash_refills", "core_blocks" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-07", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "core_blocks", "core_toggles", "fire_ice_balls", "springs", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "core_blocks", "core_toggles", "fire_ice_balls", "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "core_toggles" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bumpers", "core_toggles" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-10b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "bumpers", "core_toggles", "core_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-10c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "feathers", "core_toggles" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-11", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "center", + "rule": [ [ "core_blocks", "core_toggles", "blue_cassette_blocks", "pink_cassette_blocks" ] ] + } + ] + }, + { + "name": "center", + "connections": [ + { + "dest": "east", + "rule": [] + } + ], + "locations": [ + { + "name": "cassette", + "display_name": "Cassette", + "type": "cassette", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "space", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "dash_refills", "springs", "coins", "bumpers", "feathers", "badeline_boosters", "core_blocks", "core_toggles", "fire_ice_balls", "blue_cassette_blocks", "pink_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "00", + "source_door": "west", + "dest_room": "0x", + "dest_door": "east" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + }, + { + "source_room": "02", + "source_door": "east", + "dest_room": "a-00", + "dest_door": "west" + }, + { + "source_room": "a-00", + "source_door": "east", + "dest_room": "a-01", + "dest_door": "west" + }, + { + "source_room": "a-01", + "source_door": "east", + "dest_room": "a-02", + "dest_door": "west" + }, + { + "source_room": "a-02", + "source_door": "east", + "dest_room": "a-03", + "dest_door": "bottom" + }, + { + "source_room": "a-03", + "source_door": "top", + "dest_room": "b-00", + "dest_door": "south" + }, + { + "source_room": "b-00", + "source_door": "west", + "dest_room": "b-06", + "dest_door": "east" + }, + { + "source_room": "b-00", + "source_door": "east", + "dest_room": "b-01", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "north", + "dest_room": "b-07b", + "dest_door": "bottom" + }, + { + "source_room": "b-01", + "source_door": "east", + "dest_room": "b-02", + "dest_door": "west" + }, + { + "source_room": "b-02", + "source_door": "east", + "dest_room": "b-03", + "dest_door": "west" + }, + { + "source_room": "b-03", + "source_door": "east", + "dest_room": "b-04", + "dest_door": "west" + }, + { + "source_room": "b-04", + "source_door": "east", + "dest_room": "b-05", + "dest_door": "east" + }, + { + "source_room": "b-05", + "source_door": "west", + "dest_room": "b-04", + "dest_door": "north-west" + }, + { + "source_room": "b-07b", + "source_door": "top", + "dest_room": "b-07", + "dest_door": "bottom" + }, + { + "source_room": "b-07", + "source_door": "top", + "dest_room": "c-00", + "dest_door": "west" + }, + { + "source_room": "c-00", + "source_door": "north-east", + "dest_room": "c-00b", + "dest_door": "west" + }, + { + "source_room": "c-00", + "source_door": "east", + "dest_room": "c-01", + "dest_door": "west" + }, + { + "source_room": "c-01", + "source_door": "east", + "dest_room": "c-02", + "dest_door": "west" + }, + { + "source_room": "c-02", + "source_door": "east", + "dest_room": "c-03", + "dest_door": "west" + }, + { + "source_room": "c-03", + "source_door": "east", + "dest_room": "c-04", + "dest_door": "west" + }, + { + "source_room": "c-03", + "source_door": "north", + "dest_room": "c-03b", + "dest_door": "south" + }, + { + "source_room": "c-03b", + "source_door": "west", + "dest_room": "c-03", + "dest_door": "north-west" + }, + { + "source_room": "c-03b", + "source_door": "east", + "dest_room": "c-03", + "dest_door": "north-east" + }, + { + "source_room": "c-04", + "source_door": "east", + "dest_room": "d-00", + "dest_door": "bottom" + }, + { + "source_room": "d-00", + "source_door": "top", + "dest_room": "d-01", + "dest_door": "bottom" + }, + { + "source_room": "d-01", + "source_door": "top", + "dest_room": "d-02", + "dest_door": "bottom" + }, + { + "source_room": "d-02", + "source_door": "top", + "dest_room": "d-03", + "dest_door": "bottom" + }, + { + "source_room": "d-03", + "source_door": "top", + "dest_room": "d-04", + "dest_door": "bottom" + }, + { + "source_room": "d-04", + "source_door": "top", + "dest_room": "d-05", + "dest_door": "bottom" + }, + { + "source_room": "d-05", + "source_door": "top", + "dest_room": "d-06", + "dest_door": "bottom" + }, + { + "source_room": "d-06", + "source_door": "top", + "dest_room": "d-07", + "dest_door": "bottom" + }, + { + "source_room": "d-07", + "source_door": "top", + "dest_room": "d-08", + "dest_door": "west" + }, + { + "source_room": "d-08", + "source_door": "east", + "dest_room": "d-09", + "dest_door": "west" + }, + { + "source_room": "d-09", + "source_door": "east", + "dest_room": "d-10", + "dest_door": "west" + }, + { + "source_room": "d-10", + "source_door": "east", + "dest_room": "d-10b", + "dest_door": "west" + }, + { + "source_room": "d-10b", + "source_door": "east", + "dest_room": "d-10c", + "dest_door": "west" + }, + { + "source_room": "d-10c", + "source_door": "east", + "dest_room": "d-11", + "dest_door": "west" + }, + { + "source_room": "d-11", + "source_door": "east", + "dest_room": "space", + "dest_door": "west" + } + ] + }, + { + "name": "9b", + "display_name": "Core B", + "rooms": [ + { + "name": "00", + "regions": [ + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "east" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Into the Core", + "checkpoint_region": "west" + }, + { + "name": "a-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks", "core_toggles", "fire_ice_balls", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "fire_ice_balls" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "fire_ice_balls" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks", "core_toggles", "dash_refills", "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Burning or Freezing", + "checkpoint_region": "west" + }, + { + "name": "b-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks", "core_toggles", "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_toggles", "fire_ice_balls", "bumpers", "dash_refills", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "core_toggles" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "core_toggles", "fire_ice_balls" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-01", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "core_blocks", "core_toggles", "springs" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Heartbeat", + "checkpoint_region": "bottom" + }, + { + "name": "c-02", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "core_toggles", "bumpers", "fire_ice_balls" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "springs" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-04", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "springs", "traffic_blocks", "dream_blocks", "moving_platforms", "blue_clouds", "swap_blocks", "kevin_blocks", "core_blocks", "badeline_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "core_toggles", "core_blocks", "bumpers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "fire_ice_balls", "core_toggles", "core_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "fire_ice_balls", "core_toggles", "core_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "core_toggles" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "core_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "space", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "dash_refills", "blue_cassette_blocks", "pink_cassette_blocks" ] ] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "dash_refills", "bumpers", "coins", "springs", "traffic_blocks", "dream_blocks", "moving_platforms", "blue_clouds", "swap_blocks", "kevin_blocks", "core_blocks", "badeline_boosters", "core_toggles", "fire_ice_balls", "blue_cassette_blocks", "pink_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "a-00", + "dest_door": "west" + }, + { + "source_room": "a-00", + "source_door": "east", + "dest_room": "a-01", + "dest_door": "west" + }, + { + "source_room": "a-01", + "source_door": "east", + "dest_room": "a-02", + "dest_door": "west" + }, + { + "source_room": "a-02", + "source_door": "east", + "dest_room": "a-03", + "dest_door": "west" + }, + { + "source_room": "a-03", + "source_door": "east", + "dest_room": "a-04", + "dest_door": "west" + }, + { + "source_room": "a-04", + "source_door": "east", + "dest_room": "a-05", + "dest_door": "west" + }, + { + "source_room": "a-05", + "source_door": "east", + "dest_room": "b-00", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "east", + "dest_room": "b-01", + "dest_door": "west" + }, + { + "source_room": "b-01", + "source_door": "east", + "dest_room": "b-02", + "dest_door": "west" + }, + { + "source_room": "b-02", + "source_door": "east", + "dest_room": "b-03", + "dest_door": "west" + }, + { + "source_room": "b-03", + "source_door": "east", + "dest_room": "b-04", + "dest_door": "west" + }, + { + "source_room": "b-04", + "source_door": "east", + "dest_room": "b-05", + "dest_door": "west" + }, + { + "source_room": "b-05", + "source_door": "east", + "dest_room": "c-01", + "dest_door": "bottom" + }, + { + "source_room": "c-01", + "source_door": "top", + "dest_room": "c-02", + "dest_door": "bottom" + }, + { + "source_room": "c-02", + "source_door": "top", + "dest_room": "c-03", + "dest_door": "bottom" + }, + { + "source_room": "c-03", + "source_door": "top", + "dest_room": "c-04", + "dest_door": "bottom" + }, + { + "source_room": "c-04", + "source_door": "top", + "dest_room": "c-05", + "dest_door": "west" + }, + { + "source_room": "c-05", + "source_door": "east", + "dest_room": "c-06", + "dest_door": "west" + }, + { + "source_room": "c-06", + "source_door": "east", + "dest_room": "c-08", + "dest_door": "west" + }, + { + "source_room": "c-08", + "source_door": "east", + "dest_room": "c-07", + "dest_door": "west" + }, + { + "source_room": "c-07", + "source_door": "east", + "dest_room": "space", + "dest_door": "west" + } + ] + }, + { + "name": "9c", + "display_name": "Core C", + "rooms": [ + { + "name": "intro", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "core_blocks", "dash_refills", "core_toggles", "bumpers" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "goal", + "rule": [ [ "springs", "traffic_blocks", "dash_refills", "core_toggles", "dream_blocks", "bumpers", "pink_clouds", "swap_blocks", "kevin_blocks", "core_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "goal", + "connections": [], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + }, + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "springs", "traffic_blocks", "dash_refills", "core_toggles", "dream_blocks", "bumpers", "pink_clouds", "swap_blocks", "kevin_blocks", "core_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "intro", + "source_door": "east", + "dest_room": "00", + "dest_door": "west" + }, + { + "source_room": "00", + "source_door": "east", + "dest_room": "01", + "dest_door": "west" + }, + { + "source_room": "01", + "source_door": "east", + "dest_room": "02", + "dest_door": "west" + } + ] + }, + { + "name": "10a", + "display_name": "Farewell", + "rooms": [ + { + "name": "intro-00-past", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "special", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Start", + "checkpoint_region": "west" + }, + { + "name": "intro-01-future", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "badeline_boosters", "blue_clouds" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "special", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "intro-02-launch", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "badeline_boosters", "blue_clouds" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "intro-03-space", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Singular", + "checkpoint_region": "west" + }, + { + "name": "a-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "double_dash_refills", "dash_refills" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "springs" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "a-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "coins", "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "coins", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "springs", "dream_blocks", "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "b-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish" ] ] + }, + { + "dest": "north-east", + "rule": [ [ "jellyfish", "dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + }, + { + "name": "north-east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Power Source", + "checkpoint_region": "west" + }, + { + "name": "c-00b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-alt-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish", "double_dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-alt-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "c-03", + "regions": [ + { + "name": "south-west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "jellyfish", "springs" ] ] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south-west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-00", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "south-east", + "rule": [ [ "red_boosters" ] ] + }, + { + "dest": "north", + "rule": [ [ "red_boosters", "Power Source Key 1", "Power Source Key 2", "Power Source Key 3", "Power Source Key 4", "Power Source Key 5" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [ [ "Power Source Key 5" ] ] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south", + "rule": [ [ "double_dash_refills", "dash_switches" ] ] + }, + { + "dest": "north-west", + "rule": [ [ "double_dash_refills", "springs", "dash_switches" ] ] + } + ] + }, + { + "name": "north-west", + "connections": [ + { + "dest": "south", + "rule": [ [ "jellyfish", "dash_switches" ] ] + }, + { + "dest": "breaker", + "rule": [ [ "jellyfish", "springs", "dash_switches", "breaker_boxes" ] ] + } + ] + }, + { + "name": "breaker", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "north-east-door", + "rule": [] + }, + { + "dest": "south-east-door", + "rule": [] + }, + { + "dest": "south-west-door", + "rule": [] + }, + { + "dest": "west-door", + "rule": [] + }, + { + "dest": "north-west-door", + "rule": [] + } + ] + }, + { + "name": "north-east-door", + "connections": [ + { + "dest": "south", + "rule": [ [ "breaker_boxes" ] ] + } + ] + }, + { + "name": "south-east-door", + "connections": [ + { + "dest": "south", + "rule": [ [ "breaker_boxes" ] ] + } + ] + }, + { + "name": "south-west-door", + "connections": [ + { + "dest": "south", + "rule": [ [ "breaker_boxes" ] ] + } + ] + }, + { + "name": "west-door", + "connections": [ + { + "dest": "south", + "rule": [ [ "breaker_boxes" ] ] + } + ] + }, + { + "name": "north-west-door", + "connections": [ + { + "dest": "south", + "rule": [ [ "breaker_boxes" ] ] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east-door", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east-door", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-west-door", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "west-door", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-west-door", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-04", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "key_1", + "display_name": "Power Source Key 1", + "type": "key", + "rule": [ [ "double_dash_refills", "jellyfish" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-03", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [ [ "breaker_boxes" ] ] + }, + { + "name": "key_2", + "display_name": "Power Source Key 2", + "type": "key", + "rule": [ [ "breaker_boxes", "double_dash_refills", "jellyfish" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-01", + "regions": [ + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "key_3", + "display_name": "Power Source Key 3", + "type": "key", + "rule": [ [ "dash_refills", "dash_switches", "jellyfish" ] ] + } + ] + } + ], + "doors": [ + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-02", + "regions": [ + { + "name": "bottom", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [ [ "breaker_boxes" ] ] + }, + { + "name": "key_4", + "display_name": "Power Source Key 4", + "type": "key", + "rule": [ [ "breaker_boxes", "double_dash_refills", "springs", "move_blocks", "jellyfish" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "d-05", + "regions": [ + { + "name": "west", + "connections": [], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "key_5", + "display_name": "Power Source Key 5", + "type": "key", + "rule": [ [ "double_dash_refills", "coins", "red_boosters", "jellyfish" ] ] + } + ] + }, + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "north", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-00y", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "red_boosters" ] ] + }, + { + "dest": "south-east", + "rule": [] + } + ] + }, + { + "name": "south-east", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "north-east", + "connections": [ + { + "dest": "north", + "rule": [ [ "red_boosters" ] ] + } + ] + }, + { + "name": "north", + "connections": [] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": false + }, + { + "name": "south-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north-east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-00yb", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "red_boosters", "dash_refills", "double_dash_refills" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [] + } + ], + "doors": [ + { + "name": "south", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "left", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-00z", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Remembered", + "checkpoint_region": "south" + }, + { + "name": "e-00", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "blue_clouds", "pufferfish", "coins", "double_dash_refills" ] ] + } + ] + }, + { + "name": "north", + "connections": [] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-00b", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "jellyfish", "springs" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-01", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "north", + "rule": [ [ "jellyfish", "springs", "dash_refills" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + }, + { + "name": "car", + "display_name": "Secret Car", + "type": "car", + "rule": [ [ "jellyfish", "springs", "dash_refills" ] ] + } + ] + }, + { + "name": "north", + "connections": [] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish", "springs", "dash_refills", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "springs", "double_dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish", "springs", "dash_switches" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "springs", "coins", "traffic_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-05b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-05c", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "swap_blocks", "double_dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish", "springs", "dash_refills", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "springs", "double_dash_refills", "move_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "e-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish", "springs", "double_dash_refills", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [], + "locations": [ + { + "name": "crystal_heart", + "display_name": "Crystal Heart?", + "type": "crystal_heart", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "intro-00-past", + "source_door": "east", + "dest_room": "intro-01-future", + "dest_door": "west" + }, + { + "source_room": "intro-01-future", + "source_door": "east", + "dest_room": "intro-02-launch", + "dest_door": "bottom" + }, + { + "source_room": "intro-02-launch", + "source_door": "top", + "dest_room": "intro-03-space", + "dest_door": "west" + }, + { + "source_room": "intro-03-space", + "source_door": "east", + "dest_room": "a-00", + "dest_door": "west" + }, + { + "source_room": "a-00", + "source_door": "east", + "dest_room": "a-01", + "dest_door": "west" + }, + { + "source_room": "a-01", + "source_door": "east", + "dest_room": "a-02", + "dest_door": "west" + }, + { + "source_room": "a-02", + "source_door": "east", + "dest_room": "a-03", + "dest_door": "west" + }, + { + "source_room": "a-03", + "source_door": "east", + "dest_room": "a-04", + "dest_door": "west" + }, + { + "source_room": "a-04", + "source_door": "east", + "dest_room": "a-05", + "dest_door": "west" + }, + { + "source_room": "a-05", + "source_door": "east", + "dest_room": "b-00", + "dest_door": "west" + }, + { + "source_room": "b-00", + "source_door": "east", + "dest_room": "b-01", + "dest_door": "west" + }, + { + "source_room": "b-01", + "source_door": "east", + "dest_room": "b-02", + "dest_door": "west" + }, + { + "source_room": "b-02", + "source_door": "east", + "dest_room": "b-03", + "dest_door": "west" + }, + { + "source_room": "b-03", + "source_door": "east", + "dest_room": "b-04", + "dest_door": "west" + }, + { + "source_room": "b-04", + "source_door": "east", + "dest_room": "b-05", + "dest_door": "west" + }, + { + "source_room": "b-05", + "source_door": "east", + "dest_room": "b-06", + "dest_door": "west" + }, + { + "source_room": "b-06", + "source_door": "east", + "dest_room": "b-07", + "dest_door": "west" + }, + { + "source_room": "b-07", + "source_door": "east", + "dest_room": "c-00", + "dest_door": "west" + }, + { + "source_room": "c-00", + "source_door": "east", + "dest_room": "c-00b", + "dest_door": "west" + }, + { + "source_room": "c-00", + "source_door": "north-east", + "dest_room": "c-alt-00", + "dest_door": "west" + }, + { + "source_room": "c-00b", + "source_door": "east", + "dest_room": "c-01", + "dest_door": "west" + }, + { + "source_room": "c-01", + "source_door": "east", + "dest_room": "c-02", + "dest_door": "west" + }, + { + "source_room": "c-02", + "source_door": "east", + "dest_room": "c-03", + "dest_door": "south" + }, + { + "source_room": "c-alt-00", + "source_door": "east", + "dest_room": "c-alt-01", + "dest_door": "west" + }, + { + "source_room": "c-alt-01", + "source_door": "east", + "dest_room": "c-03", + "dest_door": "south-west" + }, + { + "source_room": "c-03", + "source_door": "north", + "dest_room": "d-00", + "dest_door": "south" + }, + { + "source_room": "d-00", + "source_door": "north-east-door", + "dest_room": "d-04", + "dest_door": "west" + }, + { + "source_room": "d-00", + "source_door": "south-east-door", + "dest_room": "d-03", + "dest_door": "west" + }, + { + "source_room": "d-00", + "source_door": "south-west-door", + "dest_room": "d-01", + "dest_door": "east" + }, + { + "source_room": "d-00", + "source_door": "west-door", + "dest_room": "d-02", + "dest_door": "bottom" + }, + { + "source_room": "d-00", + "source_door": "north-west-door", + "dest_room": "d-05", + "dest_door": "west" + }, + { + "source_room": "d-00", + "source_door": "north", + "dest_room": "d-05", + "dest_door": "south" + }, + { + "source_room": "d-05", + "source_door": "north", + "dest_room": "e-00y", + "dest_door": "south" + }, + { + "source_room": "e-00y", + "source_door": "north", + "dest_room": "e-00z", + "dest_door": "south" + }, + { + "source_room": "e-00y", + "source_door": "south-east", + "dest_room": "e-00yb", + "dest_door": "south" + }, + { + "source_room": "e-00yb", + "source_door": "north", + "dest_room": "e-00y", + "dest_door": "north-east" + }, + { + "source_room": "e-00z", + "source_door": "north", + "dest_room": "e-00", + "dest_door": "south" + }, + { + "source_room": "e-00", + "source_door": "north", + "dest_room": "e-00b", + "dest_door": "south" + }, + { + "source_room": "e-00b", + "source_door": "north", + "dest_room": "e-01", + "dest_door": "south" + }, + { + "source_room": "e-01", + "source_door": "north", + "dest_room": "e-02", + "dest_door": "west" + }, + { + "source_room": "e-02", + "source_door": "east", + "dest_room": "e-03", + "dest_door": "west" + }, + { + "source_room": "e-03", + "source_door": "east", + "dest_room": "e-04", + "dest_door": "west" + }, + { + "source_room": "e-04", + "source_door": "east", + "dest_room": "e-05", + "dest_door": "west" + }, + { + "source_room": "e-05", + "source_door": "east", + "dest_room": "e-05b", + "dest_door": "west" + }, + { + "source_room": "e-05b", + "source_door": "east", + "dest_room": "e-05c", + "dest_door": "west" + }, + { + "source_room": "e-05c", + "source_door": "east", + "dest_room": "e-06", + "dest_door": "west" + }, + { + "source_room": "e-06", + "source_door": "east", + "dest_room": "e-07", + "dest_door": "west" + }, + { + "source_room": "e-07", + "source_door": "east", + "dest_room": "e-08", + "dest_door": "west" + } + ] + }, + { + "name": "10b", + "display_name": "Farewell", + "rooms": [ + { + "name": "f-door", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Event Horizon", + "checkpoint_region": "west" + }, + { + "name": "f-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "dream_blocks" ] ] + } + ], + "locations": [ + { + "name": "car", + "display_name": "Internet Car", + "type": "car", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "kevin_blocks", "dream_blocks", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "traffic_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "double_dash_refills", "coins", "move_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "f-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "double_dash_refills", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-00", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dash_refills", "traffic_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-01", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "blue_boosters" ] ] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-03", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "dream_blocks", "coins" ] ] + } + ] + }, + { + "name": "top", + "connections": [] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "move_blocks", "springs" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "g-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "feathers" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [ [ "double_dash_refills", "dash_refills", "springs", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-00b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Determination", + "checkpoint_region": "west" + }, + { + "name": "h-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "swap_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "double_dash_refills", "springs", "move_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "red_boosters" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins", "double_dash_refills", "springs" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-03b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins", "double_dash_refills", "core_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-04", + "regions": [ + { + "name": "top", + "connections": [ + { + "dest": "east", + "rule": [] + }, + { + "dest": "bottom", + "rule": [ [ "red_boosters" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + }, + { + "name": "bottom", + "connections": [] + } + ], + "doors": [ + { + "name": "top", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + }, + { + "name": "bottom", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-04b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "top", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "springs", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-06b", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "fire_ice_balls", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [ + { + "dest": "bottom", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_boosters", "springs", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars_1", + "display_name": "Binoculars 1", + "type": "binoculars", + "rule": [] + }, + { + "name": "binoculars_2", + "display_name": "Binoculars 2", + "type": "binoculars", + "rule": [ [ "blue_boosters", "springs", "coins" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "double_dash_refills", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "double_dash_refills", "coins", "feathers", "kevin_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "h-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "feathers", "springs", "badeline_boosters" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "i-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "blue_cassette_blocks", "pink_cassette_blocks", "yellow_cassette_blocks", "green_cassette_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [ + { + "dest": "west", + "rule": [ [ "blue_cassette_blocks", "pink_cassette_blocks", "yellow_cassette_blocks", "green_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Stubbornness", + "checkpoint_region": "west" + }, + { + "name": "i-00b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "double_dash_refills", "springs", "blue_cassette_blocks", "pink_cassette_blocks", "yellow_cassette_blocks", "green_cassette_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "i-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "coins", "springs", "blue_cassette_blocks", "pink_cassette_blocks", "yellow_cassette_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "i-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "blue_cassette_blocks", "pink_cassette_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "i-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "blue_cassette_blocks", "pink_cassette_blocks", "yellow_cassette_blocks" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "i-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "red_boosters", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "i-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "blue_cassette_blocks", "pink_cassette_blocks", "yellow_cassette_blocks" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-00", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Reconciliation", + "checkpoint_region": "west" + }, + { + "name": "j-00b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "double_dash_refills", "springs", "jellyfish", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-01", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "springs", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-02", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish", "springs", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-03", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "springs", "double_dash_refills", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-04", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish", "bird" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-05", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "bird", "badeline_boosters", "feathers" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-06", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dash_refills", "double_dash_refills", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-07", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "feathers", "springs", "bird" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-08", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "dream_blocks", "double_dash_refills", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-09", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish", "springs", "double_dash_refills", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-10", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "pufferfish", "swap_blocks", "dash_refills", "double_dash_refills", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-11", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "move_blocks", "double_dash_refills", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-12", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "dash_refills", "double_dash_refills", "bird" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-13", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "feathers", "double_dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-14", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "traffic_blocks", "pufferfish", "double_dash_refills", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-14b", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "springs", "jellyfish", "double_dash_refills" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-15", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "kevin_blocks", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-16", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [ [ "jellyfish", "pufferfish", "springs", "dash_refills", "double_dash_refills", "coins", "feathers", "bird", "badeline_boosters", "breaker_boxes" ] ] + }, + { + "dest": "top", + "rule": [ [ "jellyfish", "pufferfish", "springs", "dash_refills", "double_dash_refills", "coins", "feathers", "bird", "badeline_boosters", "breaker_boxes" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "left", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "Farewell", + "checkpoint_region": "west" + }, + { + "name": "j-17", + "regions": [ + { + "name": "south", + "connections": [ + { + "dest": "west", + "rule": [] + } + ] + }, + { + "name": "west", + "connections": [ + { + "dest": "south", + "rule": [] + } + ] + }, + { + "name": "north", + "connections": [ + { + "dest": "south", + "rule": [] + }, + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "south", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "west", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "north", + "direction": "up", + "blocked": false, + "closes_behind": false + }, + { + "name": "east", + "direction": "right", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-18", + "regions": [ + { + "name": "west", + "connections": [ + { + "dest": "east", + "rule": [] + } + ] + }, + { + "name": "east", + "connections": [] + } + ], + "doors": [ + { + "name": "west", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "east", + "direction": "down", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "j-19", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "jellyfish", "springs", "dash_refills", "double_dash_refills", "coins" ] ] + } + ], + "locations": [ + { + "name": "binoculars", + "display_name": "Binoculars", + "type": "binoculars", + "rule": [] + } + ] + }, + { + "name": "top", + "connections": [], + "locations": [ + { + "name": "moon_berry", + "display_name": "Moon Berry", + "type": "strawberry", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "left", + "blocked": false, + "closes_behind": false + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": false + } + ], + "checkpoint": "", + "checkpoint_region": "" + }, + { + "name": "GOAL", + "regions": [ + { + "name": "main", + "connections": [ + { + "dest": "moon", + "rule": [] + } + ], + "locations": [ + { + "name": "clear", + "display_name": "Level Clear", + "type": "level_clear", + "rule": [] + } + ] + }, + { + "name": "moon", + "connections": [ + { + "dest": "main", + "rule": [] + } + ] + } + ], + "doors": [ + { + "name": "main", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "moon", + "direction": "down", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [ + { + "source_room": "f-door", + "source_door": "east", + "dest_room": "f-00", + "dest_door": "west" + }, + { + "source_room": "f-00", + "source_door": "east", + "dest_room": "f-01", + "dest_door": "west" + }, + { + "source_room": "f-01", + "source_door": "east", + "dest_room": "f-02", + "dest_door": "west" + }, + { + "source_room": "f-02", + "source_door": "east", + "dest_room": "f-03", + "dest_door": "west" + }, + { + "source_room": "f-03", + "source_door": "east", + "dest_room": "f-04", + "dest_door": "west" + }, + { + "source_room": "f-04", + "source_door": "east", + "dest_room": "f-05", + "dest_door": "west" + }, + { + "source_room": "f-05", + "source_door": "east", + "dest_room": "f-06", + "dest_door": "west" + }, + { + "source_room": "f-06", + "source_door": "east", + "dest_room": "f-07", + "dest_door": "west" + }, + { + "source_room": "f-07", + "source_door": "east", + "dest_room": "f-08", + "dest_door": "west" + }, + { + "source_room": "f-08", + "source_door": "east", + "dest_room": "f-09", + "dest_door": "west" + }, + { + "source_room": "f-09", + "source_door": "east", + "dest_room": "g-00", + "dest_door": "bottom" + }, + { + "source_room": "g-00", + "source_door": "top", + "dest_room": "g-01", + "dest_door": "bottom" + }, + { + "source_room": "g-01", + "source_door": "top", + "dest_room": "g-03", + "dest_door": "bottom" + }, + { + "source_room": "g-03", + "source_door": "top", + "dest_room": "g-02", + "dest_door": "west" + }, + { + "source_room": "g-02", + "source_door": "east", + "dest_room": "g-04", + "dest_door": "west" + }, + { + "source_room": "g-04", + "source_door": "east", + "dest_room": "g-05", + "dest_door": "west" + }, + { + "source_room": "g-05", + "source_door": "east", + "dest_room": "g-06", + "dest_door": "west" + }, + { + "source_room": "g-06", + "source_door": "east", + "dest_room": "h-00b", + "dest_door": "west" + }, + { + "source_room": "h-00b", + "source_door": "east", + "dest_room": "h-00", + "dest_door": "west" + }, + { + "source_room": "h-00", + "source_door": "east", + "dest_room": "h-01", + "dest_door": "west" + }, + { + "source_room": "h-01", + "source_door": "east", + "dest_room": "h-02", + "dest_door": "west" + }, + { + "source_room": "h-02", + "source_door": "east", + "dest_room": "h-03", + "dest_door": "west" + }, + { + "source_room": "h-03", + "source_door": "east", + "dest_room": "h-03b", + "dest_door": "west" + }, + { + "source_room": "h-03b", + "source_door": "east", + "dest_room": "h-04", + "dest_door": "top" + }, + { + "source_room": "h-04", + "source_door": "east", + "dest_room": "h-04b", + "dest_door": "west" + }, + { + "source_room": "h-04", + "source_door": "bottom", + "dest_room": "h-05", + "dest_door": "west" + }, + { + "source_room": "h-04b", + "source_door": "east", + "dest_room": "h-05", + "dest_door": "top" + }, + { + "source_room": "h-05", + "source_door": "east", + "dest_room": "h-06", + "dest_door": "west" + }, + { + "source_room": "h-06", + "source_door": "east", + "dest_room": "h-06b", + "dest_door": "bottom" + }, + { + "source_room": "h-06b", + "source_door": "top", + "dest_room": "h-07", + "dest_door": "west" + }, + { + "source_room": "h-07", + "source_door": "east", + "dest_room": "h-08", + "dest_door": "west" + }, + { + "source_room": "h-08", + "source_door": "east", + "dest_room": "h-09", + "dest_door": "west" + }, + { + "source_room": "h-09", + "source_door": "east", + "dest_room": "h-10", + "dest_door": "west" + }, + { + "source_room": "h-10", + "source_door": "east", + "dest_room": "i-00", + "dest_door": "west" + }, + { + "source_room": "i-00", + "source_door": "east", + "dest_room": "i-00b", + "dest_door": "west" + }, + { + "source_room": "i-00b", + "source_door": "east", + "dest_room": "i-01", + "dest_door": "west" + }, + { + "source_room": "i-01", + "source_door": "east", + "dest_room": "i-02", + "dest_door": "west" + }, + { + "source_room": "i-02", + "source_door": "east", + "dest_room": "i-03", + "dest_door": "west" + }, + { + "source_room": "i-03", + "source_door": "east", + "dest_room": "i-04", + "dest_door": "west" + }, + { + "source_room": "i-04", + "source_door": "east", + "dest_room": "i-05", + "dest_door": "west" + }, + { + "source_room": "i-05", + "source_door": "east", + "dest_room": "j-00", + "dest_door": "west" + }, + { + "source_room": "j-00", + "source_door": "east", + "dest_room": "j-00b", + "dest_door": "west" + }, + { + "source_room": "j-00b", + "source_door": "east", + "dest_room": "j-01", + "dest_door": "west" + }, + { + "source_room": "j-01", + "source_door": "east", + "dest_room": "j-02", + "dest_door": "west" + }, + { + "source_room": "j-02", + "source_door": "east", + "dest_room": "j-03", + "dest_door": "west" + }, + { + "source_room": "j-03", + "source_door": "east", + "dest_room": "j-04", + "dest_door": "west" + }, + { + "source_room": "j-04", + "source_door": "east", + "dest_room": "j-05", + "dest_door": "west" + }, + { + "source_room": "j-05", + "source_door": "east", + "dest_room": "j-06", + "dest_door": "west" + }, + { + "source_room": "j-06", + "source_door": "east", + "dest_room": "j-07", + "dest_door": "west" + }, + { + "source_room": "j-07", + "source_door": "east", + "dest_room": "j-08", + "dest_door": "west" + }, + { + "source_room": "j-08", + "source_door": "east", + "dest_room": "j-09", + "dest_door": "west" + }, + { + "source_room": "j-09", + "source_door": "east", + "dest_room": "j-10", + "dest_door": "west" + }, + { + "source_room": "j-10", + "source_door": "east", + "dest_room": "j-11", + "dest_door": "west" + }, + { + "source_room": "j-11", + "source_door": "east", + "dest_room": "j-12", + "dest_door": "west" + }, + { + "source_room": "j-12", + "source_door": "east", + "dest_room": "j-13", + "dest_door": "west" + }, + { + "source_room": "j-13", + "source_door": "east", + "dest_room": "j-14", + "dest_door": "west" + }, + { + "source_room": "j-14", + "source_door": "east", + "dest_room": "j-14b", + "dest_door": "west" + }, + { + "source_room": "j-14b", + "source_door": "east", + "dest_room": "j-15", + "dest_door": "west" + }, + { + "source_room": "j-15", + "source_door": "east", + "dest_room": "j-16", + "dest_door": "west" + }, + { + "source_room": "j-16", + "source_door": "east", + "dest_room": "GOAL", + "dest_door": "main" + }, + { + "source_room": "j-16", + "source_door": "top", + "dest_room": "j-17", + "dest_door": "south" + }, + { + "source_room": "j-17", + "source_door": "west", + "dest_room": "j-18", + "dest_door": "west" + }, + { + "source_room": "j-17", + "source_door": "east", + "dest_room": "j-19", + "dest_door": "bottom" + }, + { + "source_room": "j-18", + "source_door": "east", + "dest_room": "j-17", + "dest_door": "north" + }, + { + "source_room": "j-19", + "source_door": "top", + "dest_room": "GOAL", + "dest_door": "moon" + } + ] + }, + { + "name": "10c", + "display_name": "Farewell", + "rooms": [ + { + "name": "end-golden", + "regions": [ + { + "name": "bottom", + "connections": [ + { + "dest": "top", + "rule": [ [ "double_dash_refills", "jellyfish", "springs", "pufferfish", "badeline_boosters" ] ] + } + ], + "locations": [ + { + "name": "binoculars_1", + "display_name": "Binoculars 1", + "type": "binoculars", + "rule": [] + }, + { + "name": "binoculars_2", + "display_name": "Binoculars 2", + "type": "binoculars", + "rule": [] + }, + { + "name": "binoculars_3", + "display_name": "Binoculars 3", + "type": "binoculars", + "rule": [ [ "double_dash_refills", "jellyfish", "springs", "pufferfish" ] ] + } + ] + }, + { + "name": "top", + "connections": [], + "locations": [ + { + "name": "golden", + "display_name": "Golden Strawberry", + "type": "golden_strawberry", + "rule": [ [ "traffic_blocks", "dash_refills", "double_dash_refills", "dream_blocks", "swap_blocks", "move_blocks", "blue_boosters", "springs", "feathers", "coins", "red_boosters", "kevin_blocks", "core_blocks", "fire_ice_balls", "badeline_boosters", "bird", "breaker_boxes", "pufferfish", "jellyfish", "pink_cassette_blocks", "blue_cassette_blocks", "yellow_cassette_blocks", "green_cassette_blocks" ] ] + } + ] + } + ], + "doors": [ + { + "name": "bottom", + "direction": "down", + "blocked": false, + "closes_behind": true + }, + { + "name": "top", + "direction": "up", + "blocked": false, + "closes_behind": true + } + ], + "checkpoint": "", + "checkpoint_region": "" + } + ], + "room_connections": [] + } + ] +} \ No newline at end of file diff --git a/worlds/celeste_open_world/data/CelesteLevelData.py b/worlds/celeste_open_world/data/CelesteLevelData.py new file mode 100644 index 000000000000..f4c492dd4f8e --- /dev/null +++ b/worlds/celeste_open_world/data/CelesteLevelData.py @@ -0,0 +1,9792 @@ +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MANUALLY EDIT. + +from ..Levels import Level, Room, PreRegion, LevelLocation, RegionConnection, RoomConnection, Door, DoorDirection, LocationType +from ..Names import ItemName + +all_doors: dict[str, Door] = { + "0a_-1_east": Door("0a_-1_east", "0a_-1", DoorDirection.right, False, False), + + "0a_0_west": Door("0a_0_west", "0a_0", DoorDirection.left, False, False), + "0a_0_east": Door("0a_0_east", "0a_0", DoorDirection.right, False, False), + "0a_0_north": Door("0a_0_north", "0a_0", DoorDirection.up, False, False), + + "0a_0b_south": Door("0a_0b_south", "0a_0b", DoorDirection.down, False, False), + + "0a_1_west": Door("0a_1_west", "0a_1", DoorDirection.left, False, False), + "0a_1_east": Door("0a_1_east", "0a_1", DoorDirection.right, False, False), + + "0a_2_west": Door("0a_2_west", "0a_2", DoorDirection.left, False, False), + "0a_2_east": Door("0a_2_east", "0a_2", DoorDirection.right, False, False), + + "0a_3_west": Door("0a_3_west", "0a_3", DoorDirection.left, False, False), + + "1a_1_east": Door("1a_1_east", "1a_1", DoorDirection.up, False, False), + + "1a_2_west": Door("1a_2_west", "1a_2", DoorDirection.down, False, True), + "1a_2_east": Door("1a_2_east", "1a_2", DoorDirection.up, False, False), + + "1a_3_west": Door("1a_3_west", "1a_3", DoorDirection.down, False, True), + "1a_3_east": Door("1a_3_east", "1a_3", DoorDirection.up, False, False), + + "1a_4_west": Door("1a_4_west", "1a_4", DoorDirection.down, False, True), + "1a_4_east": Door("1a_4_east", "1a_4", DoorDirection.up, False, False), + + "1a_3b_west": Door("1a_3b_west", "1a_3b", DoorDirection.down, False, True), + "1a_3b_top": Door("1a_3b_top", "1a_3b", DoorDirection.up, False, False), + + "1a_5_bottom": Door("1a_5_bottom", "1a_5", DoorDirection.down, False, True), + "1a_5_west": Door("1a_5_west", "1a_5", DoorDirection.left, False, False), + "1a_5_south-east": Door("1a_5_south-east", "1a_5", DoorDirection.right, True, False), + "1a_5_top": Door("1a_5_top", "1a_5", DoorDirection.up, False, False), + + "1a_5z_east": Door("1a_5z_east", "1a_5z", DoorDirection.right, False, False), + + "1a_5a_west": Door("1a_5a_west", "1a_5a", DoorDirection.left, False, False), + + "1a_6_south-west": Door("1a_6_south-west", "1a_6", DoorDirection.down, False, True), + "1a_6_west": Door("1a_6_west", "1a_6", DoorDirection.left, False, False), + "1a_6_east": Door("1a_6_east", "1a_6", DoorDirection.right, False, False), + + "1a_6z_north-west": Door("1a_6z_north-west", "1a_6z", DoorDirection.up, False, False), + "1a_6z_west": Door("1a_6z_west", "1a_6z", DoorDirection.left, False, False), + "1a_6z_east": Door("1a_6z_east", "1a_6z", DoorDirection.right, False, False), + + "1a_6zb_north-west": Door("1a_6zb_north-west", "1a_6zb", DoorDirection.up, False, True), + "1a_6zb_east": Door("1a_6zb_east", "1a_6zb", DoorDirection.right, False, False), + + "1a_7zb_west": Door("1a_7zb_west", "1a_7zb", DoorDirection.down, False, False), + "1a_7zb_east": Door("1a_7zb_east", "1a_7zb", DoorDirection.down, False, False), + + "1a_6a_west": Door("1a_6a_west", "1a_6a", DoorDirection.left, False, False), + "1a_6a_east": Door("1a_6a_east", "1a_6a", DoorDirection.right, False, False), + + "1a_6b_north-west": Door("1a_6b_north-west", "1a_6b", DoorDirection.left, False, False), + "1a_6b_south-west": Door("1a_6b_south-west", "1a_6b", DoorDirection.left, False, False), + "1a_6b_north-east": Door("1a_6b_north-east", "1a_6b", DoorDirection.right, False, False), + + "1a_s0_west": Door("1a_s0_west", "1a_s0", DoorDirection.left, False, False), + "1a_s0_east": Door("1a_s0_east", "1a_s0", DoorDirection.right, False, False), + + "1a_s1_east": Door("1a_s1_east", "1a_s1", DoorDirection.right, False, False), + + "1a_6c_south-west": Door("1a_6c_south-west", "1a_6c", DoorDirection.left, False, False), + "1a_6c_north-west": Door("1a_6c_north-west", "1a_6c", DoorDirection.left, True, False), + "1a_6c_north-east": Door("1a_6c_north-east", "1a_6c", DoorDirection.up, False, False), + + "1a_7_west": Door("1a_7_west", "1a_7", DoorDirection.down, False, True), + "1a_7_east": Door("1a_7_east", "1a_7", DoorDirection.up, False, False), + + "1a_7z_bottom": Door("1a_7z_bottom", "1a_7z", DoorDirection.right, False, False), + "1a_7z_top": Door("1a_7z_top", "1a_7z", DoorDirection.up, True, False), + + "1a_8z_bottom": Door("1a_8z_bottom", "1a_8z", DoorDirection.down, False, False), + "1a_8z_top": Door("1a_8z_top", "1a_8z", DoorDirection.right, False, False), + + "1a_8zb_west": Door("1a_8zb_west", "1a_8zb", DoorDirection.left, False, False), + "1a_8zb_east": Door("1a_8zb_east", "1a_8zb", DoorDirection.right, False, False), + + "1a_8_south-west": Door("1a_8_south-west", "1a_8", DoorDirection.down, False, True), + "1a_8_west": Door("1a_8_west", "1a_8", DoorDirection.left, False, True), + "1a_8_south": Door("1a_8_south", "1a_8", DoorDirection.down, False, False), + "1a_8_south-east": Door("1a_8_south-east", "1a_8", DoorDirection.down, False, True), + "1a_8_north": Door("1a_8_north", "1a_8", DoorDirection.up, False, False), + "1a_8_north-east": Door("1a_8_north-east", "1a_8", DoorDirection.right, False, False), + + "1a_7a_west": Door("1a_7a_west", "1a_7a", DoorDirection.up, False, False), + "1a_7a_east": Door("1a_7a_east", "1a_7a", DoorDirection.up, False, False), + + "1a_9z_east": Door("1a_9z_east", "1a_9z", DoorDirection.down, False, False), + + "1a_8b_west": Door("1a_8b_west", "1a_8b", DoorDirection.left, False, False), + "1a_8b_east": Door("1a_8b_east", "1a_8b", DoorDirection.up, False, False), + + "1a_9_west": Door("1a_9_west", "1a_9", DoorDirection.down, False, True), + "1a_9_east": Door("1a_9_east", "1a_9", DoorDirection.right, False, False), + + "1a_9b_west": Door("1a_9b_west", "1a_9b", DoorDirection.left, False, False), + "1a_9b_north-west": Door("1a_9b_north-west", "1a_9b", DoorDirection.up, False, False), + "1a_9b_east": Door("1a_9b_east", "1a_9b", DoorDirection.right, False, False), + "1a_9b_north-east": Door("1a_9b_north-east", "1a_9b", DoorDirection.up, False, False), + + "1a_9c_west": Door("1a_9c_west", "1a_9c", DoorDirection.left, False, True), + + "1a_10_south-east": Door("1a_10_south-east", "1a_10", DoorDirection.down, False, False), + "1a_10_south-west": Door("1a_10_south-west", "1a_10", DoorDirection.left, False, False), + "1a_10_north-west": Door("1a_10_north-west", "1a_10", DoorDirection.up, False, False), + "1a_10_north-east": Door("1a_10_north-east", "1a_10", DoorDirection.up, False, True), + + "1a_10z_west": Door("1a_10z_west", "1a_10z", DoorDirection.left, False, False), + "1a_10z_east": Door("1a_10z_east", "1a_10z", DoorDirection.right, False, False), + + "1a_10zb_east": Door("1a_10zb_east", "1a_10zb", DoorDirection.right, False, False), + + "1a_11_south": Door("1a_11_south", "1a_11", DoorDirection.down, False, False), + "1a_11_south-west": Door("1a_11_south-west", "1a_11", DoorDirection.down, False, False), + "1a_11_west": Door("1a_11_west", "1a_11", DoorDirection.left, False, False), + "1a_11_south-east": Door("1a_11_south-east", "1a_11", DoorDirection.down, False, True), + "1a_11_north": Door("1a_11_north", "1a_11", DoorDirection.up, False, False), + + "1a_11z_east": Door("1a_11z_east", "1a_11z", DoorDirection.right, False, False), + + "1a_10a_bottom": Door("1a_10a_bottom", "1a_10a", DoorDirection.down, False, False), + "1a_10a_top": Door("1a_10a_top", "1a_10a", DoorDirection.up, False, False), + + "1a_12_south-west": Door("1a_12_south-west", "1a_12", DoorDirection.down, False, True), + "1a_12_north-west": Door("1a_12_north-west", "1a_12", DoorDirection.left, False, False), + "1a_12_east": Door("1a_12_east", "1a_12", DoorDirection.right, False, True), + + "1a_12z_east": Door("1a_12z_east", "1a_12z", DoorDirection.right, False, False), + + "1a_12a_bottom": Door("1a_12a_bottom", "1a_12a", DoorDirection.left, False, False), + "1a_12a_top": Door("1a_12a_top", "1a_12a", DoorDirection.up, False, False), + + "1a_end_south": Door("1a_end_south", "1a_end", DoorDirection.down, False, True), + + "1b_00_east": Door("1b_00_east", "1b_00", DoorDirection.up, False, False), + + "1b_01_west": Door("1b_01_west", "1b_01", DoorDirection.down, False, True), + "1b_01_east": Door("1b_01_east", "1b_01", DoorDirection.up, False, False), + + "1b_02_west": Door("1b_02_west", "1b_02", DoorDirection.down, False, True), + "1b_02_east": Door("1b_02_east", "1b_02", DoorDirection.up, False, False), + + "1b_02b_west": Door("1b_02b_west", "1b_02b", DoorDirection.down, False, True), + "1b_02b_east": Door("1b_02b_east", "1b_02b", DoorDirection.up, False, False), + + "1b_03_west": Door("1b_03_west", "1b_03", DoorDirection.down, False, True), + "1b_03_east": Door("1b_03_east", "1b_03", DoorDirection.right, False, False), + + "1b_04_west": Door("1b_04_west", "1b_04", DoorDirection.left, False, True), + "1b_04_east": Door("1b_04_east", "1b_04", DoorDirection.up, False, False), + + "1b_05_west": Door("1b_05_west", "1b_05", DoorDirection.down, False, True), + "1b_05_east": Door("1b_05_east", "1b_05", DoorDirection.up, False, False), + + "1b_05b_west": Door("1b_05b_west", "1b_05b", DoorDirection.down, False, True), + "1b_05b_east": Door("1b_05b_east", "1b_05b", DoorDirection.up, False, False), + + "1b_06_west": Door("1b_06_west", "1b_06", DoorDirection.down, False, True), + "1b_06_east": Door("1b_06_east", "1b_06", DoorDirection.right, False, False), + + "1b_07_bottom": Door("1b_07_bottom", "1b_07", DoorDirection.left, False, False), + "1b_07_top": Door("1b_07_top", "1b_07", DoorDirection.up, False, False), + + "1b_08_west": Door("1b_08_west", "1b_08", DoorDirection.down, False, True), + "1b_08_east": Door("1b_08_east", "1b_08", DoorDirection.up, False, False), + + "1b_08b_west": Door("1b_08b_west", "1b_08b", DoorDirection.down, False, True), + "1b_08b_east": Door("1b_08b_east", "1b_08b", DoorDirection.up, False, False), + + "1b_09_west": Door("1b_09_west", "1b_09", DoorDirection.down, False, True), + "1b_09_east": Door("1b_09_east", "1b_09", DoorDirection.right, False, False), + + "1b_10_west": Door("1b_10_west", "1b_10", DoorDirection.left, False, False), + "1b_10_east": Door("1b_10_east", "1b_10", DoorDirection.right, False, False), + + "1b_11_bottom": Door("1b_11_bottom", "1b_11", DoorDirection.left, False, False), + "1b_11_top": Door("1b_11_top", "1b_11", DoorDirection.up, False, False), + + "1b_end_west": Door("1b_end_west", "1b_end", DoorDirection.down, False, True), + + "1c_00_east": Door("1c_00_east", "1c_00", DoorDirection.right, False, False), + + "1c_01_west": Door("1c_01_west", "1c_01", DoorDirection.left, False, True), + "1c_01_east": Door("1c_01_east", "1c_01", DoorDirection.right, False, False), + + "1c_02_west": Door("1c_02_west", "1c_02", DoorDirection.left, False, True), + + "2a_start_east": Door("2a_start_east", "2a_start", DoorDirection.right, False, False), + "2a_start_top": Door("2a_start_top", "2a_start", DoorDirection.up, False, False), + + "2a_s0_bottom": Door("2a_s0_bottom", "2a_s0", DoorDirection.down, False, False), + "2a_s0_top": Door("2a_s0_top", "2a_s0", DoorDirection.up, False, False), + + "2a_s1_bottom": Door("2a_s1_bottom", "2a_s1", DoorDirection.down, False, False), + "2a_s1_top": Door("2a_s1_top", "2a_s1", DoorDirection.up, False, False), + + "2a_s2_bottom": Door("2a_s2_bottom", "2a_s2", DoorDirection.down, False, False), + + "2a_0_south-west": Door("2a_0_south-west", "2a_0", DoorDirection.left, False, False), + "2a_0_south-east": Door("2a_0_south-east", "2a_0", DoorDirection.right, False, False), + "2a_0_north-west": Door("2a_0_north-west", "2a_0", DoorDirection.up, False, False), + "2a_0_north-east": Door("2a_0_north-east", "2a_0", DoorDirection.right, False, False), + + "2a_1_south-west": Door("2a_1_south-west", "2a_1", DoorDirection.left, False, False), + "2a_1_south-east": Door("2a_1_south-east", "2a_1", DoorDirection.right, False, False), + "2a_1_north-west": Door("2a_1_north-west", "2a_1", DoorDirection.left, False, False), + "2a_1_south": Door("2a_1_south", "2a_1", DoorDirection.down, False, False), + + "2a_d0_north": Door("2a_d0_north", "2a_d0", DoorDirection.up, False, False), + "2a_d0_north-west": Door("2a_d0_north-west", "2a_d0", DoorDirection.left, False, False), + "2a_d0_west": Door("2a_d0_west", "2a_d0", DoorDirection.left, False, False), + "2a_d0_south-west": Door("2a_d0_south-west", "2a_d0", DoorDirection.left, False, False), + "2a_d0_south": Door("2a_d0_south", "2a_d0", DoorDirection.down, False, False), + "2a_d0_south-east": Door("2a_d0_south-east", "2a_d0", DoorDirection.right, True, False), + "2a_d0_east": Door("2a_d0_east", "2a_d0", DoorDirection.right, False, False), + "2a_d0_north-east": Door("2a_d0_north-east", "2a_d0", DoorDirection.right, False, False), + + "2a_d7_west": Door("2a_d7_west", "2a_d7", DoorDirection.left, False, False), + "2a_d7_east": Door("2a_d7_east", "2a_d7", DoorDirection.right, False, False), + + "2a_d8_west": Door("2a_d8_west", "2a_d8", DoorDirection.left, False, False), + "2a_d8_south-east": Door("2a_d8_south-east", "2a_d8", DoorDirection.right, False, False), + "2a_d8_north-east": Door("2a_d8_north-east", "2a_d8", DoorDirection.right, False, False), + + "2a_d3_west": Door("2a_d3_west", "2a_d3", DoorDirection.left, False, False), + "2a_d3_south": Door("2a_d3_south", "2a_d3", DoorDirection.left, False, False), + "2a_d3_north": Door("2a_d3_north", "2a_d3", DoorDirection.left, False, False), + + "2a_d2_west": Door("2a_d2_west", "2a_d2", DoorDirection.left, False, False), + "2a_d2_north-west": Door("2a_d2_north-west", "2a_d2", DoorDirection.up, False, True), + "2a_d2_east": Door("2a_d2_east", "2a_d2", DoorDirection.right, False, False), + + "2a_d9_north-west": Door("2a_d9_north-west", "2a_d9", DoorDirection.up, False, False), + + "2a_d1_north-east": Door("2a_d1_north-east", "2a_d1", DoorDirection.right, False, False), + "2a_d1_south-east": Door("2a_d1_south-east", "2a_d1", DoorDirection.right, False, False), + "2a_d1_south-west": Door("2a_d1_south-west", "2a_d1", DoorDirection.down, True, False), + + "2a_d6_west": Door("2a_d6_west", "2a_d6", DoorDirection.up, False, False), + "2a_d6_east": Door("2a_d6_east", "2a_d6", DoorDirection.right, False, False), + + "2a_d4_west": Door("2a_d4_west", "2a_d4", DoorDirection.left, False, False), + "2a_d4_east": Door("2a_d4_east", "2a_d4", DoorDirection.right, False, False), + "2a_d4_south": Door("2a_d4_south", "2a_d4", DoorDirection.down, False, False), + + "2a_d5_west": Door("2a_d5_west", "2a_d5", DoorDirection.left, False, False), + + "2a_3x_bottom": Door("2a_3x_bottom", "2a_3x", DoorDirection.down, False, False), + "2a_3x_top": Door("2a_3x_top", "2a_3x", DoorDirection.up, False, False), + + "2a_3_bottom": Door("2a_3_bottom", "2a_3", DoorDirection.down, False, True), + "2a_3_top": Door("2a_3_top", "2a_3", DoorDirection.up, False, False), + + "2a_4_bottom": Door("2a_4_bottom", "2a_4", DoorDirection.down, False, True), + "2a_4_top": Door("2a_4_top", "2a_4", DoorDirection.up, False, False), + + "2a_5_bottom": Door("2a_5_bottom", "2a_5", DoorDirection.down, False, True), + "2a_5_top": Door("2a_5_top", "2a_5", DoorDirection.up, False, False), + + "2a_6_bottom": Door("2a_6_bottom", "2a_6", DoorDirection.down, False, True), + "2a_6_top": Door("2a_6_top", "2a_6", DoorDirection.up, False, False), + + "2a_7_bottom": Door("2a_7_bottom", "2a_7", DoorDirection.down, False, True), + "2a_7_top": Door("2a_7_top", "2a_7", DoorDirection.up, False, False), + + "2a_8_bottom": Door("2a_8_bottom", "2a_8", DoorDirection.down, False, True), + "2a_8_top": Door("2a_8_top", "2a_8", DoorDirection.right, False, False), + + "2a_9_west": Door("2a_9_west", "2a_9", DoorDirection.left, False, False), + "2a_9_north": Door("2a_9_north", "2a_9", DoorDirection.up, False, False), + "2a_9_north-west": Door("2a_9_north-west", "2a_9", DoorDirection.up, False, False), + "2a_9_south-east": Door("2a_9_south-east", "2a_9", DoorDirection.down, False, False), + + "2a_9b_east": Door("2a_9b_east", "2a_9b", DoorDirection.down, False, True), + "2a_9b_west": Door("2a_9b_west", "2a_9b", DoorDirection.down, False, False), + + "2a_10_bottom": Door("2a_10_bottom", "2a_10", DoorDirection.down, False, True), + "2a_10_top": Door("2a_10_top", "2a_10", DoorDirection.up, False, False), + + "2a_2_north-west": Door("2a_2_north-west", "2a_2", DoorDirection.up, False, False), + "2a_2_south-west": Door("2a_2_south-west", "2a_2", DoorDirection.left, False, False), + "2a_2_south-east": Door("2a_2_south-east", "2a_2", DoorDirection.right, False, False), + + "2a_11_west": Door("2a_11_west", "2a_11", DoorDirection.left, False, False), + "2a_11_east": Door("2a_11_east", "2a_11", DoorDirection.right, False, False), + + "2a_12b_west": Door("2a_12b_west", "2a_12b", DoorDirection.left, False, False), + "2a_12b_north": Door("2a_12b_north", "2a_12b", DoorDirection.up, False, False), + "2a_12b_south": Door("2a_12b_south", "2a_12b", DoorDirection.down, False, False), + "2a_12b_south-east": Door("2a_12b_south-east", "2a_12b", DoorDirection.down, False, True), + "2a_12b_east": Door("2a_12b_east", "2a_12b", DoorDirection.right, False, True), + + "2a_12c_south": Door("2a_12c_south", "2a_12c", DoorDirection.down, False, False), + + "2a_12d_north-west": Door("2a_12d_north-west", "2a_12d", DoorDirection.up, False, False), + "2a_12d_north": Door("2a_12d_north", "2a_12d", DoorDirection.up, False, False), + + "2a_12_west": Door("2a_12_west", "2a_12", DoorDirection.left, False, False), + "2a_12_east": Door("2a_12_east", "2a_12", DoorDirection.right, False, False), + + "2a_13_west": Door("2a_13_west", "2a_13", DoorDirection.left, False, False), + "2a_13_phone": Door("2a_13_phone", "2a_13", DoorDirection.special, False, True), + + "2a_end_0_main": Door("2a_end_0_main", "2a_end_0", DoorDirection.special, False, True), + "2a_end_0_east": Door("2a_end_0_east", "2a_end_0", DoorDirection.right, False, False), + "2a_end_0_top": Door("2a_end_0_top", "2a_end_0", DoorDirection.up, False, False), + + "2a_end_s0_bottom": Door("2a_end_s0_bottom", "2a_end_s0", DoorDirection.down, False, False), + "2a_end_s0_top": Door("2a_end_s0_top", "2a_end_s0", DoorDirection.up, False, False), + + "2a_end_s1_bottom": Door("2a_end_s1_bottom", "2a_end_s1", DoorDirection.down, False, False), + + "2a_end_1_west": Door("2a_end_1_west", "2a_end_1", DoorDirection.left, False, False), + "2a_end_1_north-east": Door("2a_end_1_north-east", "2a_end_1", DoorDirection.right, False, False), + "2a_end_1_east": Door("2a_end_1_east", "2a_end_1", DoorDirection.right, False, False), + + "2a_end_2_north-west": Door("2a_end_2_north-west", "2a_end_2", DoorDirection.left, False, False), + "2a_end_2_west": Door("2a_end_2_west", "2a_end_2", DoorDirection.left, False, False), + "2a_end_2_north-east": Door("2a_end_2_north-east", "2a_end_2", DoorDirection.right, False, False), + "2a_end_2_east": Door("2a_end_2_east", "2a_end_2", DoorDirection.right, False, False), + + "2a_end_3_north-west": Door("2a_end_3_north-west", "2a_end_3", DoorDirection.left, False, True), + "2a_end_3_west": Door("2a_end_3_west", "2a_end_3", DoorDirection.left, False, True), + "2a_end_3_east": Door("2a_end_3_east", "2a_end_3", DoorDirection.right, False, False), + + "2a_end_4_west": Door("2a_end_4_west", "2a_end_4", DoorDirection.left, False, False), + "2a_end_4_east": Door("2a_end_4_east", "2a_end_4", DoorDirection.right, False, False), + + "2a_end_3b_west": Door("2a_end_3b_west", "2a_end_3b", DoorDirection.left, False, False), + "2a_end_3b_north": Door("2a_end_3b_north", "2a_end_3b", DoorDirection.up, False, False), + "2a_end_3b_east": Door("2a_end_3b_east", "2a_end_3b", DoorDirection.right, False, False), + + "2a_end_3cb_bottom": Door("2a_end_3cb_bottom", "2a_end_3cb", DoorDirection.down, False, False), + "2a_end_3cb_top": Door("2a_end_3cb_top", "2a_end_3cb", DoorDirection.up, False, False), + + "2a_end_3c_bottom": Door("2a_end_3c_bottom", "2a_end_3c", DoorDirection.down, False, False), + + "2a_end_5_west": Door("2a_end_5_west", "2a_end_5", DoorDirection.left, False, False), + "2a_end_5_east": Door("2a_end_5_east", "2a_end_5", DoorDirection.right, False, False), + + "2a_end_6_west": Door("2a_end_6_west", "2a_end_6", DoorDirection.left, False, False), + + "2b_start_east": Door("2b_start_east", "2b_start", DoorDirection.right, False, False), + + "2b_00_west": Door("2b_00_west", "2b_00", DoorDirection.left, False, False), + "2b_00_east": Door("2b_00_east", "2b_00", DoorDirection.right, False, False), + + "2b_01_west": Door("2b_01_west", "2b_01", DoorDirection.left, False, False), + "2b_01_east": Door("2b_01_east", "2b_01", DoorDirection.up, False, False), + + "2b_01b_west": Door("2b_01b_west", "2b_01b", DoorDirection.down, False, True), + "2b_01b_east": Door("2b_01b_east", "2b_01b", DoorDirection.up, False, False), + + "2b_02b_west": Door("2b_02b_west", "2b_02b", DoorDirection.down, False, True), + "2b_02b_east": Door("2b_02b_east", "2b_02b", DoorDirection.up, False, False), + + "2b_02_west": Door("2b_02_west", "2b_02", DoorDirection.down, False, True), + "2b_02_east": Door("2b_02_east", "2b_02", DoorDirection.up, False, False), + + "2b_03_west": Door("2b_03_west", "2b_03", DoorDirection.down, False, True), + "2b_03_east": Door("2b_03_east", "2b_03", DoorDirection.up, False, False), + + "2b_04_bottom": Door("2b_04_bottom", "2b_04", DoorDirection.down, False, True), + "2b_04_top": Door("2b_04_top", "2b_04", DoorDirection.up, False, False), + + "2b_05_bottom": Door("2b_05_bottom", "2b_05", DoorDirection.down, False, True), + "2b_05_top": Door("2b_05_top", "2b_05", DoorDirection.up, False, False), + + "2b_06_west": Door("2b_06_west", "2b_06", DoorDirection.down, False, True), + "2b_06_east": Door("2b_06_east", "2b_06", DoorDirection.right, False, False), + + "2b_07_bottom": Door("2b_07_bottom", "2b_07", DoorDirection.left, False, False), + "2b_07_top": Door("2b_07_top", "2b_07", DoorDirection.up, False, False), + + "2b_08b_west": Door("2b_08b_west", "2b_08b", DoorDirection.down, False, True), + "2b_08b_east": Door("2b_08b_east", "2b_08b", DoorDirection.up, False, False), + + "2b_08_west": Door("2b_08_west", "2b_08", DoorDirection.down, False, True), + "2b_08_east": Door("2b_08_east", "2b_08", DoorDirection.up, False, False), + + "2b_09_west": Door("2b_09_west", "2b_09", DoorDirection.down, False, True), + "2b_09_east": Door("2b_09_east", "2b_09", DoorDirection.right, False, False), + + "2b_10_west": Door("2b_10_west", "2b_10", DoorDirection.left, False, False), + "2b_10_east": Door("2b_10_east", "2b_10", DoorDirection.up, False, False), + + "2b_11_bottom": Door("2b_11_bottom", "2b_11", DoorDirection.down, False, True), + "2b_11_top": Door("2b_11_top", "2b_11", DoorDirection.up, False, False), + + "2b_end_west": Door("2b_end_west", "2b_end", DoorDirection.down, False, True), + + "2c_00_east": Door("2c_00_east", "2c_00", DoorDirection.right, False, False), + + "2c_01_west": Door("2c_01_west", "2c_01", DoorDirection.left, False, False), + "2c_01_east": Door("2c_01_east", "2c_01", DoorDirection.right, False, False), + + "2c_02_west": Door("2c_02_west", "2c_02", DoorDirection.left, False, True), + + "3a_s0_east": Door("3a_s0_east", "3a_s0", DoorDirection.right, False, False), + + "3a_s1_west": Door("3a_s1_west", "3a_s1", DoorDirection.left, False, False), + "3a_s1_east": Door("3a_s1_east", "3a_s1", DoorDirection.right, False, False), + "3a_s1_north-east": Door("3a_s1_north-east", "3a_s1", DoorDirection.right, False, False), + + "3a_s2_west": Door("3a_s2_west", "3a_s2", DoorDirection.left, False, False), + "3a_s2_north-west": Door("3a_s2_north-west", "3a_s2", DoorDirection.left, False, False), + "3a_s2_east": Door("3a_s2_east", "3a_s2", DoorDirection.right, False, False), + + "3a_s3_west": Door("3a_s3_west", "3a_s3", DoorDirection.left, False, False), + "3a_s3_north": Door("3a_s3_north", "3a_s3", DoorDirection.right, False, False), + "3a_s3_east": Door("3a_s3_east", "3a_s3", DoorDirection.right, False, False), + + "3a_0x-a_west": Door("3a_0x-a_west", "3a_0x-a", DoorDirection.left, False, True), + "3a_0x-a_east": Door("3a_0x-a_east", "3a_0x-a", DoorDirection.right, False, False), + + "3a_00-a_west": Door("3a_00-a_west", "3a_00-a", DoorDirection.left, False, False), + "3a_00-a_east": Door("3a_00-a_east", "3a_00-a", DoorDirection.right, False, False), + + "3a_02-a_west": Door("3a_02-a_west", "3a_02-a", DoorDirection.left, False, True), + "3a_02-a_top": Door("3a_02-a_top", "3a_02-a", DoorDirection.up, False, False), + "3a_02-a_east": Door("3a_02-a_east", "3a_02-a", DoorDirection.right, True, False), + + "3a_02-b_west": Door("3a_02-b_west", "3a_02-b", DoorDirection.left, False, False), + "3a_02-b_east": Door("3a_02-b_east", "3a_02-b", DoorDirection.down, False, False), + "3a_02-b_far-east": Door("3a_02-b_far-east", "3a_02-b", DoorDirection.right, False, False), + + "3a_01-b_west": Door("3a_01-b_west", "3a_01-b", DoorDirection.left, False, False), + "3a_01-b_north-west": Door("3a_01-b_north-west", "3a_01-b", DoorDirection.left, False, False), + "3a_01-b_east": Door("3a_01-b_east", "3a_01-b", DoorDirection.right, False, False), + + "3a_00-b_south-west": Door("3a_00-b_south-west", "3a_00-b", DoorDirection.left, False, False), + "3a_00-b_south-east": Door("3a_00-b_south-east", "3a_00-b", DoorDirection.right, False, False), + "3a_00-b_west": Door("3a_00-b_west", "3a_00-b", DoorDirection.left, False, False), + "3a_00-b_north-west": Door("3a_00-b_north-west", "3a_00-b", DoorDirection.up, False, False), + "3a_00-b_east": Door("3a_00-b_east", "3a_00-b", DoorDirection.right, False, False), + "3a_00-b_north": Door("3a_00-b_north", "3a_00-b", DoorDirection.up, True, False), + + "3a_00-c_south-west": Door("3a_00-c_south-west", "3a_00-c", DoorDirection.down, False, False), + "3a_00-c_south-east": Door("3a_00-c_south-east", "3a_00-c", DoorDirection.down, False, False), + "3a_00-c_north-east": Door("3a_00-c_north-east", "3a_00-c", DoorDirection.right, False, False), + + "3a_0x-b_west": Door("3a_0x-b_west", "3a_0x-b", DoorDirection.left, False, False), + "3a_0x-b_south-east": Door("3a_0x-b_south-east", "3a_0x-b", DoorDirection.right, False, False), + "3a_0x-b_north-east": Door("3a_0x-b_north-east", "3a_0x-b", DoorDirection.right, False, False), + + "3a_03-a_west": Door("3a_03-a_west", "3a_03-a", DoorDirection.left, False, False), + "3a_03-a_top": Door("3a_03-a_top", "3a_03-a", DoorDirection.up, False, False), + "3a_03-a_east": Door("3a_03-a_east", "3a_03-a", DoorDirection.right, False, False), + + "3a_04-b_west": Door("3a_04-b_west", "3a_04-b", DoorDirection.left, False, False), + "3a_04-b_east": Door("3a_04-b_east", "3a_04-b", DoorDirection.down, False, False), + + "3a_05-a_west": Door("3a_05-a_west", "3a_05-a", DoorDirection.left, False, False), + "3a_05-a_east": Door("3a_05-a_east", "3a_05-a", DoorDirection.right, False, False), + + "3a_06-a_west": Door("3a_06-a_west", "3a_06-a", DoorDirection.left, False, False), + "3a_06-a_east": Door("3a_06-a_east", "3a_06-a", DoorDirection.right, False, False), + + "3a_07-a_west": Door("3a_07-a_west", "3a_07-a", DoorDirection.left, False, False), + "3a_07-a_top": Door("3a_07-a_top", "3a_07-a", DoorDirection.up, False, False), + "3a_07-a_east": Door("3a_07-a_east", "3a_07-a", DoorDirection.right, False, False), + + "3a_07-b_bottom": Door("3a_07-b_bottom", "3a_07-b", DoorDirection.down, False, False), + "3a_07-b_west": Door("3a_07-b_west", "3a_07-b", DoorDirection.left, False, False), + "3a_07-b_top": Door("3a_07-b_top", "3a_07-b", DoorDirection.up, False, False), + "3a_07-b_east": Door("3a_07-b_east", "3a_07-b", DoorDirection.right, False, False), + + "3a_06-b_west": Door("3a_06-b_west", "3a_06-b", DoorDirection.up, False, False), + "3a_06-b_east": Door("3a_06-b_east", "3a_06-b", DoorDirection.right, False, False), + + "3a_06-c_south-west": Door("3a_06-c_south-west", "3a_06-c", DoorDirection.down, False, True), + "3a_06-c_north-west": Door("3a_06-c_north-west", "3a_06-c", DoorDirection.left, False, False), + "3a_06-c_south-east": Door("3a_06-c_south-east", "3a_06-c", DoorDirection.down, True, False), + "3a_06-c_east": Door("3a_06-c_east", "3a_06-c", DoorDirection.right, False, False), + + "3a_05-c_east": Door("3a_05-c_east", "3a_05-c", DoorDirection.right, False, False), + + "3a_08-c_west": Door("3a_08-c_west", "3a_08-c", DoorDirection.left, False, False), + "3a_08-c_east": Door("3a_08-c_east", "3a_08-c", DoorDirection.down, False, False), + + "3a_08-b_west": Door("3a_08-b_west", "3a_08-b", DoorDirection.left, False, False), + "3a_08-b_east": Door("3a_08-b_east", "3a_08-b", DoorDirection.up, False, False), + + "3a_08-a_west": Door("3a_08-a_west", "3a_08-a", DoorDirection.left, False, True), + "3a_08-a_bottom": Door("3a_08-a_bottom", "3a_08-a", DoorDirection.down, False, False), + "3a_08-a_east": Door("3a_08-a_east", "3a_08-a", DoorDirection.right, False, False), + + "3a_09-b_west": Door("3a_09-b_west", "3a_09-b", DoorDirection.left, False, False), + "3a_09-b_north-west": Door("3a_09-b_north-west", "3a_09-b", DoorDirection.up, False, False), + "3a_09-b_south-west": Door("3a_09-b_south-west", "3a_09-b", DoorDirection.down, False, True), + "3a_09-b_south": Door("3a_09-b_south", "3a_09-b", DoorDirection.down, False, True), + "3a_09-b_south-east": Door("3a_09-b_south-east", "3a_09-b", DoorDirection.down, False, False), + "3a_09-b_east": Door("3a_09-b_east", "3a_09-b", DoorDirection.right, False, False), + "3a_09-b_north-east-right": Door("3a_09-b_north-east-right", "3a_09-b", DoorDirection.right, False, False), + "3a_09-b_north-east-top": Door("3a_09-b_north-east-top", "3a_09-b", DoorDirection.up, False, False), + "3a_09-b_north": Door("3a_09-b_north", "3a_09-b", DoorDirection.up, False, True), + + "3a_10-x_west": Door("3a_10-x_west", "3a_10-x", DoorDirection.up, False, False), + "3a_10-x_south-east": Door("3a_10-x_south-east", "3a_10-x", DoorDirection.down, False, True), + "3a_10-x_north-east-top": Door("3a_10-x_north-east-top", "3a_10-x", DoorDirection.up, False, True), + "3a_10-x_north-east-right": Door("3a_10-x_north-east-right", "3a_10-x", DoorDirection.right, False, True), + + "3a_11-x_west": Door("3a_11-x_west", "3a_11-x", DoorDirection.left, False, False), + "3a_11-x_south": Door("3a_11-x_south", "3a_11-x", DoorDirection.down, False, False), + + "3a_11-y_west": Door("3a_11-y_west", "3a_11-y", DoorDirection.up, False, False), + "3a_11-y_east": Door("3a_11-y_east", "3a_11-y", DoorDirection.right, False, False), + "3a_11-y_south": Door("3a_11-y_south", "3a_11-y", DoorDirection.down, False, False), + + "3a_12-y_west": Door("3a_12-y_west", "3a_12-y", DoorDirection.left, False, False), + + "3a_11-z_west": Door("3a_11-z_west", "3a_11-z", DoorDirection.left, False, False), + "3a_11-z_east": Door("3a_11-z_east", "3a_11-z", DoorDirection.up, False, False), + + "3a_10-z_bottom": Door("3a_10-z_bottom", "3a_10-z", DoorDirection.right, False, False), + "3a_10-z_top": Door("3a_10-z_top", "3a_10-z", DoorDirection.up, False, False), + + "3a_10-y_bottom": Door("3a_10-y_bottom", "3a_10-y", DoorDirection.down, False, True), + "3a_10-y_top": Door("3a_10-y_top", "3a_10-y", DoorDirection.up, False, False), + + "3a_10-c_south-east": Door("3a_10-c_south-east", "3a_10-c", DoorDirection.down, False, False), + "3a_10-c_north-east": Door("3a_10-c_north-east", "3a_10-c", DoorDirection.right, False, False), + "3a_10-c_north-west": Door("3a_10-c_north-west", "3a_10-c", DoorDirection.up, False, False), + "3a_10-c_south-west": Door("3a_10-c_south-west", "3a_10-c", DoorDirection.down, False, False), + + "3a_11-c_south-east": Door("3a_11-c_south-east", "3a_11-c", DoorDirection.down, False, True), + "3a_11-c_east": Door("3a_11-c_east", "3a_11-c", DoorDirection.right, False, False), + "3a_11-c_west": Door("3a_11-c_west", "3a_11-c", DoorDirection.left, False, False), + "3a_11-c_south-west": Door("3a_11-c_south-west", "3a_11-c", DoorDirection.down, False, False), + + "3a_12-c_west": Door("3a_12-c_west", "3a_12-c", DoorDirection.left, False, False), + "3a_12-c_top": Door("3a_12-c_top", "3a_12-c", DoorDirection.up, False, False), + + "3a_12-d_bottom": Door("3a_12-d_bottom", "3a_12-d", DoorDirection.down, False, True), + "3a_12-d_top": Door("3a_12-d_top", "3a_12-d", DoorDirection.left, False, False), + + "3a_11-d_west": Door("3a_11-d_west", "3a_11-d", DoorDirection.left, False, False), + "3a_11-d_east": Door("3a_11-d_east", "3a_11-d", DoorDirection.right, False, False), + + "3a_10-d_west": Door("3a_10-d_west", "3a_10-d", DoorDirection.down, False, False), + "3a_10-d_east": Door("3a_10-d_east", "3a_10-d", DoorDirection.right, False, False), + + "3a_11-b_west": Door("3a_11-b_west", "3a_11-b", DoorDirection.left, False, False), + "3a_11-b_north-west": Door("3a_11-b_north-west", "3a_11-b", DoorDirection.up, False, False), + "3a_11-b_east": Door("3a_11-b_east", "3a_11-b", DoorDirection.right, False, False), + "3a_11-b_north-east": Door("3a_11-b_north-east", "3a_11-b", DoorDirection.up, False, False), + + "3a_12-b_west": Door("3a_12-b_west", "3a_12-b", DoorDirection.left, False, False), + "3a_12-b_east": Door("3a_12-b_east", "3a_12-b", DoorDirection.right, False, False), + + "3a_13-b_top": Door("3a_13-b_top", "3a_13-b", DoorDirection.left, False, False), + "3a_13-b_bottom": Door("3a_13-b_bottom", "3a_13-b", DoorDirection.down, False, False), + + "3a_13-a_west": Door("3a_13-a_west", "3a_13-a", DoorDirection.up, False, False), + "3a_13-a_south-west": Door("3a_13-a_south-west", "3a_13-a", DoorDirection.left, False, False), + "3a_13-a_east": Door("3a_13-a_east", "3a_13-a", DoorDirection.down, False, False), + + "3a_13-x_west": Door("3a_13-x_west", "3a_13-x", DoorDirection.left, False, False), + "3a_13-x_east": Door("3a_13-x_east", "3a_13-x", DoorDirection.up, False, False), + + "3a_12-x_west": Door("3a_12-x_west", "3a_12-x", DoorDirection.up, False, False), + "3a_12-x_north-east": Door("3a_12-x_north-east", "3a_12-x", DoorDirection.up, False, False), + "3a_12-x_east": Door("3a_12-x_east", "3a_12-x", DoorDirection.right, False, False), + + "3a_11-a_west": Door("3a_11-a_west", "3a_11-a", DoorDirection.left, False, False), + "3a_11-a_south": Door("3a_11-a_south", "3a_11-a", DoorDirection.down, False, True), + "3a_11-a_south-east-bottom": Door("3a_11-a_south-east-bottom", "3a_11-a", DoorDirection.down, False, False), + "3a_11-a_south-east-right": Door("3a_11-a_south-east-right", "3a_11-a", DoorDirection.right, False, False), + + "3a_08-x_west": Door("3a_08-x_west", "3a_08-x", DoorDirection.up, False, False), + "3a_08-x_east": Door("3a_08-x_east", "3a_08-x", DoorDirection.up, False, False), + + "3a_09-d_bottom": Door("3a_09-d_bottom", "3a_09-d", DoorDirection.down, False, True), + "3a_09-d_top": Door("3a_09-d_top", "3a_09-d", DoorDirection.left, False, False), + + "3a_08-d_west": Door("3a_08-d_west", "3a_08-d", DoorDirection.left, False, False), + "3a_08-d_east": Door("3a_08-d_east", "3a_08-d", DoorDirection.right, False, False), + + "3a_06-d_west": Door("3a_06-d_west", "3a_06-d", DoorDirection.left, False, False), + "3a_06-d_east": Door("3a_06-d_east", "3a_06-d", DoorDirection.right, False, False), + + "3a_04-d_west": Door("3a_04-d_west", "3a_04-d", DoorDirection.left, False, False), + "3a_04-d_south-west": Door("3a_04-d_south-west", "3a_04-d", DoorDirection.down, False, False), + "3a_04-d_south": Door("3a_04-d_south", "3a_04-d", DoorDirection.down, False, False), + "3a_04-d_east": Door("3a_04-d_east", "3a_04-d", DoorDirection.right, False, False), + + "3a_04-c_west": Door("3a_04-c_west", "3a_04-c", DoorDirection.left, False, False), + "3a_04-c_north-west": Door("3a_04-c_north-west", "3a_04-c", DoorDirection.up, False, False), + "3a_04-c_east": Door("3a_04-c_east", "3a_04-c", DoorDirection.up, False, False), + + "3a_02-c_west": Door("3a_02-c_west", "3a_02-c", DoorDirection.left, False, False), + "3a_02-c_east": Door("3a_02-c_east", "3a_02-c", DoorDirection.right, False, False), + "3a_02-c_south-east": Door("3a_02-c_south-east", "3a_02-c", DoorDirection.down, False, False), + + "3a_03-b_west": Door("3a_03-b_west", "3a_03-b", DoorDirection.left, False, False), + "3a_03-b_east": Door("3a_03-b_east", "3a_03-b", DoorDirection.right, False, False), + "3a_03-b_north": Door("3a_03-b_north", "3a_03-b", DoorDirection.up, False, False), + + "3a_01-c_west": Door("3a_01-c_west", "3a_01-c", DoorDirection.left, False, False), + "3a_01-c_east": Door("3a_01-c_east", "3a_01-c", DoorDirection.right, False, False), + + "3a_02-d_west": Door("3a_02-d_west", "3a_02-d", DoorDirection.left, False, False), + "3a_02-d_east": Door("3a_02-d_east", "3a_02-d", DoorDirection.right, False, False), + + "3a_00-d_west": Door("3a_00-d_west", "3a_00-d", DoorDirection.up, False, False), + "3a_00-d_east": Door("3a_00-d_east", "3a_00-d", DoorDirection.right, False, True), + + "3a_roof00_west": Door("3a_roof00_west", "3a_roof00", DoorDirection.down, False, True), + "3a_roof00_east": Door("3a_roof00_east", "3a_roof00", DoorDirection.right, False, False), + + "3a_roof01_west": Door("3a_roof01_west", "3a_roof01", DoorDirection.left, False, False), + "3a_roof01_east": Door("3a_roof01_east", "3a_roof01", DoorDirection.right, False, False), + + "3a_roof02_west": Door("3a_roof02_west", "3a_roof02", DoorDirection.left, False, False), + "3a_roof02_east": Door("3a_roof02_east", "3a_roof02", DoorDirection.right, False, False), + + "3a_roof03_west": Door("3a_roof03_west", "3a_roof03", DoorDirection.left, False, False), + "3a_roof03_east": Door("3a_roof03_east", "3a_roof03", DoorDirection.right, False, False), + + "3a_roof04_west": Door("3a_roof04_west", "3a_roof04", DoorDirection.left, False, False), + "3a_roof04_east": Door("3a_roof04_east", "3a_roof04", DoorDirection.right, False, False), + + "3a_roof05_west": Door("3a_roof05_west", "3a_roof05", DoorDirection.left, False, False), + "3a_roof05_east": Door("3a_roof05_east", "3a_roof05", DoorDirection.right, False, False), + + "3a_roof06b_west": Door("3a_roof06b_west", "3a_roof06b", DoorDirection.left, False, False), + "3a_roof06b_east": Door("3a_roof06b_east", "3a_roof06b", DoorDirection.right, False, False), + + "3a_roof06_west": Door("3a_roof06_west", "3a_roof06", DoorDirection.left, False, False), + "3a_roof06_east": Door("3a_roof06_east", "3a_roof06", DoorDirection.right, False, False), + + "3a_roof07_west": Door("3a_roof07_west", "3a_roof07", DoorDirection.left, False, False), + + "3b_00_west": Door("3b_00_west", "3b_00", DoorDirection.left, False, False), + "3b_00_east": Door("3b_00_east", "3b_00", DoorDirection.right, False, False), + + "3b_back_east": Door("3b_back_east", "3b_back", DoorDirection.right, False, False), + + "3b_01_west": Door("3b_01_west", "3b_01", DoorDirection.left, False, False), + "3b_01_east": Door("3b_01_east", "3b_01", DoorDirection.right, False, False), + + "3b_02_west": Door("3b_02_west", "3b_02", DoorDirection.left, False, True), + "3b_02_east": Door("3b_02_east", "3b_02", DoorDirection.right, False, False), + + "3b_03_west": Door("3b_03_west", "3b_03", DoorDirection.left, False, False), + "3b_03_east": Door("3b_03_east", "3b_03", DoorDirection.right, False, False), + + "3b_04_west": Door("3b_04_west", "3b_04", DoorDirection.left, False, False), + "3b_04_east": Door("3b_04_east", "3b_04", DoorDirection.right, False, False), + + "3b_05_west": Door("3b_05_west", "3b_05", DoorDirection.left, False, False), + "3b_05_east": Door("3b_05_east", "3b_05", DoorDirection.right, False, False), + + "3b_06_west": Door("3b_06_west", "3b_06", DoorDirection.left, False, True), + "3b_06_east": Door("3b_06_east", "3b_06", DoorDirection.right, False, False), + + "3b_07_west": Door("3b_07_west", "3b_07", DoorDirection.left, False, False), + "3b_07_east": Door("3b_07_east", "3b_07", DoorDirection.right, False, False), + + "3b_08_bottom": Door("3b_08_bottom", "3b_08", DoorDirection.left, False, False), + "3b_08_top": Door("3b_08_top", "3b_08", DoorDirection.up, False, False), + + "3b_09_west": Door("3b_09_west", "3b_09", DoorDirection.down, False, True), + "3b_09_east": Door("3b_09_east", "3b_09", DoorDirection.right, False, False), + + "3b_10_west": Door("3b_10_west", "3b_10", DoorDirection.left, False, False), + "3b_10_east": Door("3b_10_east", "3b_10", DoorDirection.right, False, False), + + "3b_11_west": Door("3b_11_west", "3b_11", DoorDirection.left, False, True), + "3b_11_east": Door("3b_11_east", "3b_11", DoorDirection.right, False, False), + + "3b_13_west": Door("3b_13_west", "3b_13", DoorDirection.left, False, False), + "3b_13_east": Door("3b_13_east", "3b_13", DoorDirection.right, False, False), + + "3b_14_west": Door("3b_14_west", "3b_14", DoorDirection.left, False, False), + "3b_14_east": Door("3b_14_east", "3b_14", DoorDirection.right, False, False), + + "3b_15_west": Door("3b_15_west", "3b_15", DoorDirection.left, False, False), + "3b_15_east": Door("3b_15_east", "3b_15", DoorDirection.right, False, False), + + "3b_12_west": Door("3b_12_west", "3b_12", DoorDirection.left, False, False), + "3b_12_east": Door("3b_12_east", "3b_12", DoorDirection.right, False, False), + + "3b_16_west": Door("3b_16_west", "3b_16", DoorDirection.left, False, True), + "3b_16_top": Door("3b_16_top", "3b_16", DoorDirection.up, True, False), + + "3b_17_west": Door("3b_17_west", "3b_17", DoorDirection.down, False, True), + "3b_17_east": Door("3b_17_east", "3b_17", DoorDirection.right, False, False), + + "3b_18_west": Door("3b_18_west", "3b_18", DoorDirection.left, False, False), + "3b_18_east": Door("3b_18_east", "3b_18", DoorDirection.right, False, False), + + "3b_19_west": Door("3b_19_west", "3b_19", DoorDirection.left, False, False), + "3b_19_east": Door("3b_19_east", "3b_19", DoorDirection.right, False, False), + + "3b_21_west": Door("3b_21_west", "3b_21", DoorDirection.left, False, False), + "3b_21_east": Door("3b_21_east", "3b_21", DoorDirection.right, False, False), + + "3b_20_west": Door("3b_20_west", "3b_20", DoorDirection.left, False, False), + "3b_20_east": Door("3b_20_east", "3b_20", DoorDirection.down, False, False), + + "3b_end_west": Door("3b_end_west", "3b_end", DoorDirection.up, False, True), + + "3c_00_east": Door("3c_00_east", "3c_00", DoorDirection.up, False, False), + + "3c_01_west": Door("3c_01_west", "3c_01", DoorDirection.down, False, False), + "3c_01_east": Door("3c_01_east", "3c_01", DoorDirection.right, False, False), + + "3c_02_west": Door("3c_02_west", "3c_02", DoorDirection.left, False, True), + + "4a_a-00_east": Door("4a_a-00_east", "4a_a-00", DoorDirection.right, False, False), + + "4a_a-01_west": Door("4a_a-01_west", "4a_a-01", DoorDirection.left, False, False), + "4a_a-01_east": Door("4a_a-01_east", "4a_a-01", DoorDirection.right, False, False), + + "4a_a-01x_west": Door("4a_a-01x_west", "4a_a-01x", DoorDirection.left, False, False), + "4a_a-01x_east": Door("4a_a-01x_east", "4a_a-01x", DoorDirection.right, False, False), + + "4a_a-02_west": Door("4a_a-02_west", "4a_a-02", DoorDirection.left, False, False), + "4a_a-02_east": Door("4a_a-02_east", "4a_a-02", DoorDirection.right, False, False), + + "4a_a-03_west": Door("4a_a-03_west", "4a_a-03", DoorDirection.left, False, False), + "4a_a-03_east": Door("4a_a-03_east", "4a_a-03", DoorDirection.right, False, False), + + "4a_a-04_west": Door("4a_a-04_west", "4a_a-04", DoorDirection.left, False, False), + "4a_a-04_east": Door("4a_a-04_east", "4a_a-04", DoorDirection.right, False, False), + + "4a_a-05_west": Door("4a_a-05_west", "4a_a-05", DoorDirection.left, False, False), + "4a_a-05_east": Door("4a_a-05_east", "4a_a-05", DoorDirection.right, False, False), + + "4a_a-06_west": Door("4a_a-06_west", "4a_a-06", DoorDirection.left, False, False), + "4a_a-06_east": Door("4a_a-06_east", "4a_a-06", DoorDirection.right, False, False), + + "4a_a-07_west": Door("4a_a-07_west", "4a_a-07", DoorDirection.left, False, False), + "4a_a-07_east": Door("4a_a-07_east", "4a_a-07", DoorDirection.right, False, False), + + "4a_a-08_west": Door("4a_a-08_west", "4a_a-08", DoorDirection.left, False, False), + "4a_a-08_north-west": Door("4a_a-08_north-west", "4a_a-08", DoorDirection.left, False, False), + "4a_a-08_east": Door("4a_a-08_east", "4a_a-08", DoorDirection.up, False, False), + + "4a_a-10_west": Door("4a_a-10_west", "4a_a-10", DoorDirection.left, False, False), + "4a_a-10_east": Door("4a_a-10_east", "4a_a-10", DoorDirection.right, False, False), + + "4a_a-11_east": Door("4a_a-11_east", "4a_a-11", DoorDirection.right, False, False), + + "4a_a-09_bottom": Door("4a_a-09_bottom", "4a_a-09", DoorDirection.down, False, True), + "4a_a-09_top": Door("4a_a-09_top", "4a_a-09", DoorDirection.up, False, False), + + "4a_b-00_south": Door("4a_b-00_south", "4a_b-00", DoorDirection.down, False, True), + "4a_b-00_south-east": Door("4a_b-00_south-east", "4a_b-00", DoorDirection.right, False, False), + "4a_b-00_east": Door("4a_b-00_east", "4a_b-00", DoorDirection.right, False, False), + "4a_b-00_north-east": Door("4a_b-00_north-east", "4a_b-00", DoorDirection.right, False, False), + "4a_b-00_west": Door("4a_b-00_west", "4a_b-00", DoorDirection.left, False, False), + "4a_b-00_north-west": Door("4a_b-00_north-west", "4a_b-00", DoorDirection.left, False, False), + "4a_b-00_north": Door("4a_b-00_north", "4a_b-00", DoorDirection.up, False, False), + + "4a_b-01_west": Door("4a_b-01_west", "4a_b-01", DoorDirection.left, False, False), + + "4a_b-04_west": Door("4a_b-04_west", "4a_b-04", DoorDirection.left, False, False), + "4a_b-04_north-west": Door("4a_b-04_north-west", "4a_b-04", DoorDirection.up, False, False), + "4a_b-04_east": Door("4a_b-04_east", "4a_b-04", DoorDirection.right, False, False), + + "4a_b-06_west": Door("4a_b-06_west", "4a_b-06", DoorDirection.down, False, False), + "4a_b-06_east": Door("4a_b-06_east", "4a_b-06", DoorDirection.right, False, False), + + "4a_b-07_west": Door("4a_b-07_west", "4a_b-07", DoorDirection.up, False, False), + "4a_b-07_east": Door("4a_b-07_east", "4a_b-07", DoorDirection.right, False, False), + + "4a_b-03_west": Door("4a_b-03_west", "4a_b-03", DoorDirection.left, False, False), + "4a_b-03_east": Door("4a_b-03_east", "4a_b-03", DoorDirection.right, False, False), + + "4a_b-02_south-west": Door("4a_b-02_south-west", "4a_b-02", DoorDirection.left, False, False), + "4a_b-02_north-west": Door("4a_b-02_north-west", "4a_b-02", DoorDirection.left, False, False), + "4a_b-02_north-east": Door("4a_b-02_north-east", "4a_b-02", DoorDirection.right, True, False), + "4a_b-02_north": Door("4a_b-02_north", "4a_b-02", DoorDirection.up, False, False), + + "4a_b-sec_west": Door("4a_b-sec_west", "4a_b-sec", DoorDirection.left, False, False), + "4a_b-sec_east": Door("4a_b-sec_east", "4a_b-sec", DoorDirection.right, True, False), + + "4a_b-secb_west": Door("4a_b-secb_west", "4a_b-secb", DoorDirection.left, False, False), + + "4a_b-05_west": Door("4a_b-05_west", "4a_b-05", DoorDirection.down, False, False), + "4a_b-05_center": Door("4a_b-05_center", "4a_b-05", DoorDirection.down, False, True), + "4a_b-05_north-east": Door("4a_b-05_north-east", "4a_b-05", DoorDirection.up, False, False), + "4a_b-05_east": Door("4a_b-05_east", "4a_b-05", DoorDirection.down, False, False), + + "4a_b-08b_west": Door("4a_b-08b_west", "4a_b-08b", DoorDirection.down, False, False), + "4a_b-08b_east": Door("4a_b-08b_east", "4a_b-08b", DoorDirection.up, False, False), + + "4a_b-08_west": Door("4a_b-08_west", "4a_b-08", DoorDirection.down, False, False), + "4a_b-08_east": Door("4a_b-08_east", "4a_b-08", DoorDirection.up, False, False), + + "4a_c-00_west": Door("4a_c-00_west", "4a_c-00", DoorDirection.down, False, True), + "4a_c-00_north-west": Door("4a_c-00_north-west", "4a_c-00", DoorDirection.left, False, False), + "4a_c-00_east": Door("4a_c-00_east", "4a_c-00", DoorDirection.right, False, False), + + "4a_c-01_east": Door("4a_c-01_east", "4a_c-01", DoorDirection.right, False, False), + + "4a_c-02_west": Door("4a_c-02_west", "4a_c-02", DoorDirection.left, False, False), + "4a_c-02_east": Door("4a_c-02_east", "4a_c-02", DoorDirection.up, False, False), + + "4a_c-04_west": Door("4a_c-04_west", "4a_c-04", DoorDirection.down, False, True), + "4a_c-04_east": Door("4a_c-04_east", "4a_c-04", DoorDirection.right, False, False), + + "4a_c-05_west": Door("4a_c-05_west", "4a_c-05", DoorDirection.left, False, False), + "4a_c-05_east": Door("4a_c-05_east", "4a_c-05", DoorDirection.up, False, False), + + "4a_c-06_bottom": Door("4a_c-06_bottom", "4a_c-06", DoorDirection.down, False, False), + "4a_c-06_west": Door("4a_c-06_west", "4a_c-06", DoorDirection.left, False, False), + "4a_c-06_top": Door("4a_c-06_top", "4a_c-06", DoorDirection.up, False, False), + + "4a_c-06b_east": Door("4a_c-06b_east", "4a_c-06b", DoorDirection.right, False, False), + + "4a_c-09_west": Door("4a_c-09_west", "4a_c-09", DoorDirection.down, False, True), + "4a_c-09_east": Door("4a_c-09_east", "4a_c-09", DoorDirection.up, False, False), + + "4a_c-07_west": Door("4a_c-07_west", "4a_c-07", DoorDirection.down, False, True), + "4a_c-07_east": Door("4a_c-07_east", "4a_c-07", DoorDirection.right, False, False), + + "4a_c-08_bottom": Door("4a_c-08_bottom", "4a_c-08", DoorDirection.left, False, False), + "4a_c-08_east": Door("4a_c-08_east", "4a_c-08", DoorDirection.right, False, False), + "4a_c-08_top": Door("4a_c-08_top", "4a_c-08", DoorDirection.up, False, False), + + "4a_c-10_bottom": Door("4a_c-10_bottom", "4a_c-10", DoorDirection.left, False, False), + "4a_c-10_top": Door("4a_c-10_top", "4a_c-10", DoorDirection.up, False, False), + + "4a_d-00_west": Door("4a_d-00_west", "4a_d-00", DoorDirection.down, False, True), + "4a_d-00_south": Door("4a_d-00_south", "4a_d-00", DoorDirection.down, False, True), + "4a_d-00_north-west": Door("4a_d-00_north-west", "4a_d-00", DoorDirection.left, False, False), + "4a_d-00_east": Door("4a_d-00_east", "4a_d-00", DoorDirection.right, False, False), + + "4a_d-00b_east": Door("4a_d-00b_east", "4a_d-00b", DoorDirection.right, False, False), + + "4a_d-01_west": Door("4a_d-01_west", "4a_d-01", DoorDirection.left, False, False), + "4a_d-01_east": Door("4a_d-01_east", "4a_d-01", DoorDirection.right, False, False), + + "4a_d-02_west": Door("4a_d-02_west", "4a_d-02", DoorDirection.left, False, False), + "4a_d-02_east": Door("4a_d-02_east", "4a_d-02", DoorDirection.right, False, False), + + "4a_d-03_west": Door("4a_d-03_west", "4a_d-03", DoorDirection.left, False, False), + "4a_d-03_east": Door("4a_d-03_east", "4a_d-03", DoorDirection.right, False, False), + + "4a_d-04_west": Door("4a_d-04_west", "4a_d-04", DoorDirection.left, False, False), + "4a_d-04_east": Door("4a_d-04_east", "4a_d-04", DoorDirection.right, False, False), + + "4a_d-05_west": Door("4a_d-05_west", "4a_d-05", DoorDirection.left, False, False), + "4a_d-05_east": Door("4a_d-05_east", "4a_d-05", DoorDirection.right, False, False), + + "4a_d-06_west": Door("4a_d-06_west", "4a_d-06", DoorDirection.left, False, False), + "4a_d-06_east": Door("4a_d-06_east", "4a_d-06", DoorDirection.right, False, False), + + "4a_d-07_west": Door("4a_d-07_west", "4a_d-07", DoorDirection.left, False, False), + "4a_d-07_east": Door("4a_d-07_east", "4a_d-07", DoorDirection.right, False, False), + + "4a_d-08_west": Door("4a_d-08_west", "4a_d-08", DoorDirection.left, False, False), + "4a_d-08_east": Door("4a_d-08_east", "4a_d-08", DoorDirection.right, False, False), + + "4a_d-09_west": Door("4a_d-09_west", "4a_d-09", DoorDirection.left, False, False), + "4a_d-09_east": Door("4a_d-09_east", "4a_d-09", DoorDirection.right, False, False), + + "4a_d-10_west": Door("4a_d-10_west", "4a_d-10", DoorDirection.left, False, True), + + "4b_a-00_east": Door("4b_a-00_east", "4b_a-00", DoorDirection.right, False, False), + + "4b_a-01_west": Door("4b_a-01_west", "4b_a-01", DoorDirection.left, False, False), + "4b_a-01_east": Door("4b_a-01_east", "4b_a-01", DoorDirection.right, False, False), + + "4b_a-02_west": Door("4b_a-02_west", "4b_a-02", DoorDirection.left, False, False), + "4b_a-02_east": Door("4b_a-02_east", "4b_a-02", DoorDirection.right, False, False), + + "4b_a-03_west": Door("4b_a-03_west", "4b_a-03", DoorDirection.left, False, False), + "4b_a-03_east": Door("4b_a-03_east", "4b_a-03", DoorDirection.right, False, False), + + "4b_a-04_west": Door("4b_a-04_west", "4b_a-04", DoorDirection.left, False, False), + "4b_a-04_east": Door("4b_a-04_east", "4b_a-04", DoorDirection.right, False, False), + + "4b_b-00_west": Door("4b_b-00_west", "4b_b-00", DoorDirection.left, False, False), + "4b_b-00_east": Door("4b_b-00_east", "4b_b-00", DoorDirection.right, False, False), + + "4b_b-01_west": Door("4b_b-01_west", "4b_b-01", DoorDirection.left, False, False), + "4b_b-01_east": Door("4b_b-01_east", "4b_b-01", DoorDirection.up, False, False), + + "4b_b-02_bottom": Door("4b_b-02_bottom", "4b_b-02", DoorDirection.down, False, True), + "4b_b-02_top": Door("4b_b-02_top", "4b_b-02", DoorDirection.up, False, False), + + "4b_b-03_west": Door("4b_b-03_west", "4b_b-03", DoorDirection.down, False, True), + "4b_b-03_east": Door("4b_b-03_east", "4b_b-03", DoorDirection.up, False, False), + + "4b_b-04_west": Door("4b_b-04_west", "4b_b-04", DoorDirection.down, False, True), + "4b_b-04_east": Door("4b_b-04_east", "4b_b-04", DoorDirection.right, False, False), + + "4b_c-00_west": Door("4b_c-00_west", "4b_c-00", DoorDirection.left, False, True), + "4b_c-00_east": Door("4b_c-00_east", "4b_c-00", DoorDirection.right, False, False), + + "4b_c-01_west": Door("4b_c-01_west", "4b_c-01", DoorDirection.left, False, False), + "4b_c-01_east": Door("4b_c-01_east", "4b_c-01", DoorDirection.right, False, False), + + "4b_c-02_west": Door("4b_c-02_west", "4b_c-02", DoorDirection.left, False, False), + "4b_c-02_east": Door("4b_c-02_east", "4b_c-02", DoorDirection.right, False, False), + + "4b_c-03_bottom": Door("4b_c-03_bottom", "4b_c-03", DoorDirection.left, False, False), + "4b_c-03_top": Door("4b_c-03_top", "4b_c-03", DoorDirection.up, False, False), + + "4b_c-04_west": Door("4b_c-04_west", "4b_c-04", DoorDirection.down, False, True), + "4b_c-04_east": Door("4b_c-04_east", "4b_c-04", DoorDirection.right, False, False), + + "4b_d-00_west": Door("4b_d-00_west", "4b_d-00", DoorDirection.left, False, False), + "4b_d-00_east": Door("4b_d-00_east", "4b_d-00", DoorDirection.right, False, False), + + "4b_d-01_west": Door("4b_d-01_west", "4b_d-01", DoorDirection.left, False, False), + "4b_d-01_east": Door("4b_d-01_east", "4b_d-01", DoorDirection.right, False, False), + + "4b_d-02_west": Door("4b_d-02_west", "4b_d-02", DoorDirection.left, False, False), + "4b_d-02_east": Door("4b_d-02_east", "4b_d-02", DoorDirection.right, False, False), + + "4b_d-03_west": Door("4b_d-03_west", "4b_d-03", DoorDirection.left, False, False), + "4b_d-03_east": Door("4b_d-03_east", "4b_d-03", DoorDirection.right, False, False), + + "4b_end_west": Door("4b_end_west", "4b_end", DoorDirection.left, False, False), + + "4c_00_east": Door("4c_00_east", "4c_00", DoorDirection.right, False, False), + + "4c_01_west": Door("4c_01_west", "4c_01", DoorDirection.left, False, False), + "4c_01_east": Door("4c_01_east", "4c_01", DoorDirection.right, False, False), + + "4c_02_west": Door("4c_02_west", "4c_02", DoorDirection.left, False, False), + + "5a_a-00b_west": Door("5a_a-00b_west", "5a_a-00b", DoorDirection.left, False, False), + "5a_a-00b_east": Door("5a_a-00b_east", "5a_a-00b", DoorDirection.right, False, False), + + "5a_a-00x_east": Door("5a_a-00x_east", "5a_a-00x", DoorDirection.right, False, False), + + "5a_a-00d_west": Door("5a_a-00d_west", "5a_a-00d", DoorDirection.left, False, False), + "5a_a-00d_east": Door("5a_a-00d_east", "5a_a-00d", DoorDirection.right, False, False), + + "5a_a-00c_west": Door("5a_a-00c_west", "5a_a-00c", DoorDirection.left, False, False), + "5a_a-00c_east": Door("5a_a-00c_east", "5a_a-00c", DoorDirection.right, False, False), + + "5a_a-00_west": Door("5a_a-00_west", "5a_a-00", DoorDirection.left, False, False), + "5a_a-00_east": Door("5a_a-00_east", "5a_a-00", DoorDirection.right, False, False), + + "5a_a-01_west": Door("5a_a-01_west", "5a_a-01", DoorDirection.left, False, True), + "5a_a-01_south-west": Door("5a_a-01_south-west", "5a_a-01", DoorDirection.down, False, False), + "5a_a-01_south-east": Door("5a_a-01_south-east", "5a_a-01", DoorDirection.down, False, False), + "5a_a-01_east": Door("5a_a-01_east", "5a_a-01", DoorDirection.right, False, False), + "5a_a-01_north": Door("5a_a-01_north", "5a_a-01", DoorDirection.up, False, False), + + "5a_a-02_west": Door("5a_a-02_west", "5a_a-02", DoorDirection.left, False, False), + "5a_a-02_north": Door("5a_a-02_north", "5a_a-02", DoorDirection.up, False, False), + "5a_a-02_south": Door("5a_a-02_south", "5a_a-02", DoorDirection.down, False, False), + + "5a_a-03_west": Door("5a_a-03_west", "5a_a-03", DoorDirection.left, False, False), + "5a_a-03_east": Door("5a_a-03_east", "5a_a-03", DoorDirection.right, False, False), + + "5a_a-04_east": Door("5a_a-04_east", "5a_a-04", DoorDirection.right, False, False), + "5a_a-04_north": Door("5a_a-04_north", "5a_a-04", DoorDirection.up, False, False), + "5a_a-04_south": Door("5a_a-04_south", "5a_a-04", DoorDirection.down, False, False), + + "5a_a-05_north-west": Door("5a_a-05_north-west", "5a_a-05", DoorDirection.up, False, False), + "5a_a-05_south-west": Door("5a_a-05_south-west", "5a_a-05", DoorDirection.left, False, False), + "5a_a-05_south-east": Door("5a_a-05_south-east", "5a_a-05", DoorDirection.right, False, False), + "5a_a-05_north-east": Door("5a_a-05_north-east", "5a_a-05", DoorDirection.up, False, False), + + "5a_a-06_west": Door("5a_a-06_west", "5a_a-06", DoorDirection.left, False, False), + + "5a_a-07_east": Door("5a_a-07_east", "5a_a-07", DoorDirection.right, False, False), + + "5a_a-08_west": Door("5a_a-08_west", "5a_a-08", DoorDirection.left, False, False), + "5a_a-08_south": Door("5a_a-08_south", "5a_a-08", DoorDirection.down, False, False), + "5a_a-08_south-east": Door("5a_a-08_south-east", "5a_a-08", DoorDirection.right, False, False), + "5a_a-08_east": Door("5a_a-08_east", "5a_a-08", DoorDirection.right, False, False), + "5a_a-08_north-east": Door("5a_a-08_north-east", "5a_a-08", DoorDirection.right, False, False), + "5a_a-08_north": Door("5a_a-08_north", "5a_a-08", DoorDirection.up, False, False), + + "5a_a-10_west": Door("5a_a-10_west", "5a_a-10", DoorDirection.left, False, False), + "5a_a-10_east": Door("5a_a-10_east", "5a_a-10", DoorDirection.right, False, False), + + "5a_a-09_west": Door("5a_a-09_west", "5a_a-09", DoorDirection.left, False, False), + "5a_a-09_east": Door("5a_a-09_east", "5a_a-09", DoorDirection.right, False, False), + + "5a_a-11_east": Door("5a_a-11_east", "5a_a-11", DoorDirection.right, False, False), + + "5a_a-12_north-west": Door("5a_a-12_north-west", "5a_a-12", DoorDirection.left, False, False), + "5a_a-12_west": Door("5a_a-12_west", "5a_a-12", DoorDirection.left, False, False), + "5a_a-12_south-west": Door("5a_a-12_south-west", "5a_a-12", DoorDirection.left, False, False), + "5a_a-12_east": Door("5a_a-12_east", "5a_a-12", DoorDirection.up, False, False), + + "5a_a-15_south": Door("5a_a-15_south", "5a_a-15", DoorDirection.down, False, False), + + "5a_a-14_south": Door("5a_a-14_south", "5a_a-14", DoorDirection.down, False, False), + + "5a_a-13_west": Door("5a_a-13_west", "5a_a-13", DoorDirection.left, False, False), + "5a_a-13_east": Door("5a_a-13_east", "5a_a-13", DoorDirection.right, False, False), + + "5a_b-00_west": Door("5a_b-00_west", "5a_b-00", DoorDirection.left, False, True), + "5a_b-00_north-west": Door("5a_b-00_north-west", "5a_b-00", DoorDirection.up, False, False), + "5a_b-00_east": Door("5a_b-00_east", "5a_b-00", DoorDirection.right, False, False), + + "5a_b-18_south": Door("5a_b-18_south", "5a_b-18", DoorDirection.down, False, False), + + "5a_b-01_south-west": Door("5a_b-01_south-west", "5a_b-01", DoorDirection.left, False, True), + "5a_b-01_west": Door("5a_b-01_west", "5a_b-01", DoorDirection.up, False, False), + "5a_b-01_north-west": Door("5a_b-01_north-west", "5a_b-01", DoorDirection.up, False, True), + "5a_b-01_north": Door("5a_b-01_north", "5a_b-01", DoorDirection.up, False, False), + "5a_b-01_north-east": Door("5a_b-01_north-east", "5a_b-01", DoorDirection.up, False, False), + "5a_b-01_east": Door("5a_b-01_east", "5a_b-01", DoorDirection.right, False, False), + "5a_b-01_south-east": Door("5a_b-01_south-east", "5a_b-01", DoorDirection.down, False, True), + "5a_b-01_south": Door("5a_b-01_south", "5a_b-01", DoorDirection.down, False, False), + + "5a_b-01c_west": Door("5a_b-01c_west", "5a_b-01c", DoorDirection.up, False, False), + "5a_b-01c_east": Door("5a_b-01c_east", "5a_b-01c", DoorDirection.up, False, False), + + "5a_b-20_north-west": Door("5a_b-20_north-west", "5a_b-20", DoorDirection.left, False, False), + "5a_b-20_west": Door("5a_b-20_west", "5a_b-20", DoorDirection.down, False, True), + "5a_b-20_south-west": Door("5a_b-20_south-west", "5a_b-20", DoorDirection.down, False, False), + "5a_b-20_south": Door("5a_b-20_south", "5a_b-20", DoorDirection.down, False, False), + "5a_b-20_east": Door("5a_b-20_east", "5a_b-20", DoorDirection.down, False, False), + + "5a_b-21_east": Door("5a_b-21_east", "5a_b-21", DoorDirection.right, False, False), + + "5a_b-01b_west": Door("5a_b-01b_west", "5a_b-01b", DoorDirection.left, False, False), + "5a_b-01b_east": Door("5a_b-01b_east", "5a_b-01b", DoorDirection.right, False, False), + + "5a_b-02_west": Door("5a_b-02_west", "5a_b-02", DoorDirection.left, False, True), + "5a_b-02_north-west": Door("5a_b-02_north-west", "5a_b-02", DoorDirection.left, False, True), + "5a_b-02_north": Door("5a_b-02_north", "5a_b-02", DoorDirection.up, False, False), + "5a_b-02_north-east": Door("5a_b-02_north-east", "5a_b-02", DoorDirection.right, False, False), + "5a_b-02_east-upper": Door("5a_b-02_east-upper", "5a_b-02", DoorDirection.right, False, False), + "5a_b-02_east-lower": Door("5a_b-02_east-lower", "5a_b-02", DoorDirection.right, False, True), + "5a_b-02_south-east": Door("5a_b-02_south-east", "5a_b-02", DoorDirection.right, False, True), + "5a_b-02_south": Door("5a_b-02_south", "5a_b-02", DoorDirection.down, False, False), + + "5a_b-03_east": Door("5a_b-03_east", "5a_b-03", DoorDirection.right, False, False), + + "5a_b-05_west": Door("5a_b-05_west", "5a_b-05", DoorDirection.left, False, False), + + "5a_b-04_west": Door("5a_b-04_west", "5a_b-04", DoorDirection.left, False, False), + "5a_b-04_east": Door("5a_b-04_east", "5a_b-04", DoorDirection.right, False, False), + "5a_b-04_south": Door("5a_b-04_south", "5a_b-04", DoorDirection.down, False, False), + + "5a_b-07_north": Door("5a_b-07_north", "5a_b-07", DoorDirection.right, False, False), + "5a_b-07_south": Door("5a_b-07_south", "5a_b-07", DoorDirection.right, False, False), + + "5a_b-08_west": Door("5a_b-08_west", "5a_b-08", DoorDirection.left, False, False), + "5a_b-08_east": Door("5a_b-08_east", "5a_b-08", DoorDirection.right, False, False), + + "5a_b-09_north": Door("5a_b-09_north", "5a_b-09", DoorDirection.left, False, False), + "5a_b-09_south": Door("5a_b-09_south", "5a_b-09", DoorDirection.left, False, False), + + "5a_b-10_east": Door("5a_b-10_east", "5a_b-10", DoorDirection.up, False, False), + + "5a_b-11_north-west": Door("5a_b-11_north-west", "5a_b-11", DoorDirection.left, False, False), + "5a_b-11_west": Door("5a_b-11_west", "5a_b-11", DoorDirection.left, False, False), + "5a_b-11_south-west": Door("5a_b-11_south-west", "5a_b-11", DoorDirection.down, False, False), + "5a_b-11_south-east": Door("5a_b-11_south-east", "5a_b-11", DoorDirection.down, False, False), + "5a_b-11_east": Door("5a_b-11_east", "5a_b-11", DoorDirection.right, False, False), + + "5a_b-12_west": Door("5a_b-12_west", "5a_b-12", DoorDirection.up, False, False), + "5a_b-12_east": Door("5a_b-12_east", "5a_b-12", DoorDirection.up, False, False), + + "5a_b-13_west": Door("5a_b-13_west", "5a_b-13", DoorDirection.left, False, False), + "5a_b-13_east": Door("5a_b-13_east", "5a_b-13", DoorDirection.right, False, False), + "5a_b-13_north-east": Door("5a_b-13_north-east", "5a_b-13", DoorDirection.right, False, False), + + "5a_b-17_west": Door("5a_b-17_west", "5a_b-17", DoorDirection.left, False, False), + "5a_b-17_east": Door("5a_b-17_east", "5a_b-17", DoorDirection.right, False, False), + "5a_b-17_north-west": Door("5a_b-17_north-west", "5a_b-17", DoorDirection.left, False, False), + + "5a_b-22_west": Door("5a_b-22_west", "5a_b-22", DoorDirection.left, False, False), + + "5a_b-06_west": Door("5a_b-06_west", "5a_b-06", DoorDirection.left, False, False), + "5a_b-06_east": Door("5a_b-06_east", "5a_b-06", DoorDirection.right, False, False), + "5a_b-06_north-east": Door("5a_b-06_north-east", "5a_b-06", DoorDirection.right, False, False), + + "5a_b-19_west": Door("5a_b-19_west", "5a_b-19", DoorDirection.left, False, True), + "5a_b-19_east": Door("5a_b-19_east", "5a_b-19", DoorDirection.right, False, False), + "5a_b-19_north-west": Door("5a_b-19_north-west", "5a_b-19", DoorDirection.left, False, False), + + "5a_b-14_west": Door("5a_b-14_west", "5a_b-14", DoorDirection.left, False, True), + "5a_b-14_south": Door("5a_b-14_south", "5a_b-14", DoorDirection.right, False, False), + "5a_b-14_north": Door("5a_b-14_north", "5a_b-14", DoorDirection.up, False, False), + + "5a_b-15_west": Door("5a_b-15_west", "5a_b-15", DoorDirection.left, False, False), + + "5a_b-16_bottom": Door("5a_b-16_bottom", "5a_b-16", DoorDirection.down, False, False), + "5a_b-16_mirror": Door("5a_b-16_mirror", "5a_b-16", DoorDirection.special, False, False), + + "5a_void_east": Door("5a_void_east", "5a_void", DoorDirection.special, False, True), + "5a_void_west": Door("5a_void_west", "5a_void", DoorDirection.special, False, False), + + "5a_c-00_bottom": Door("5a_c-00_bottom", "5a_c-00", DoorDirection.right, False, False), + "5a_c-00_top": Door("5a_c-00_top", "5a_c-00", DoorDirection.special, False, True), + + "5a_c-01_west": Door("5a_c-01_west", "5a_c-01", DoorDirection.left, False, False), + "5a_c-01_east": Door("5a_c-01_east", "5a_c-01", DoorDirection.right, False, False), + + "5a_c-01b_west": Door("5a_c-01b_west", "5a_c-01b", DoorDirection.left, False, True), + "5a_c-01b_east": Door("5a_c-01b_east", "5a_c-01b", DoorDirection.right, False, False), + + "5a_c-01c_west": Door("5a_c-01c_west", "5a_c-01c", DoorDirection.left, False, True), + "5a_c-01c_east": Door("5a_c-01c_east", "5a_c-01c", DoorDirection.right, False, False), + + "5a_c-08b_west": Door("5a_c-08b_west", "5a_c-08b", DoorDirection.left, False, True), + "5a_c-08b_east": Door("5a_c-08b_east", "5a_c-08b", DoorDirection.right, False, False), + + "5a_c-08_west": Door("5a_c-08_west", "5a_c-08", DoorDirection.left, False, True), + "5a_c-08_east": Door("5a_c-08_east", "5a_c-08", DoorDirection.right, False, False), + + "5a_c-10_west": Door("5a_c-10_west", "5a_c-10", DoorDirection.left, False, False), + "5a_c-10_east": Door("5a_c-10_east", "5a_c-10", DoorDirection.right, False, False), + + "5a_c-12_west": Door("5a_c-12_west", "5a_c-12", DoorDirection.left, False, True), + "5a_c-12_east": Door("5a_c-12_east", "5a_c-12", DoorDirection.right, False, False), + + "5a_c-07_west": Door("5a_c-07_west", "5a_c-07", DoorDirection.left, False, True), + "5a_c-07_east": Door("5a_c-07_east", "5a_c-07", DoorDirection.right, False, False), + + "5a_c-11_west": Door("5a_c-11_west", "5a_c-11", DoorDirection.left, False, True), + "5a_c-11_east": Door("5a_c-11_east", "5a_c-11", DoorDirection.right, False, False), + + "5a_c-09_west": Door("5a_c-09_west", "5a_c-09", DoorDirection.left, False, False), + "5a_c-09_east": Door("5a_c-09_east", "5a_c-09", DoorDirection.right, False, False), + + "5a_c-13_west": Door("5a_c-13_west", "5a_c-13", DoorDirection.left, False, False), + "5a_c-13_east": Door("5a_c-13_east", "5a_c-13", DoorDirection.up, False, False), + + "5a_d-00_south": Door("5a_d-00_south", "5a_d-00", DoorDirection.down, False, True), + "5a_d-00_north": Door("5a_d-00_north", "5a_d-00", DoorDirection.up, False, False), + "5a_d-00_west": Door("5a_d-00_west", "5a_d-00", DoorDirection.left, False, False), + "5a_d-00_east": Door("5a_d-00_east", "5a_d-00", DoorDirection.right, False, False), + + "5a_d-01_south": Door("5a_d-01_south", "5a_d-01", DoorDirection.down, False, True), + "5a_d-01_south-west-left": Door("5a_d-01_south-west-left", "5a_d-01", DoorDirection.left, False, False), + "5a_d-01_south-west-down": Door("5a_d-01_south-west-down", "5a_d-01", DoorDirection.down, False, False), + "5a_d-01_south-east-right": Door("5a_d-01_south-east-right", "5a_d-01", DoorDirection.right, True, False), + "5a_d-01_south-east-down": Door("5a_d-01_south-east-down", "5a_d-01", DoorDirection.down, False, False), + "5a_d-01_west": Door("5a_d-01_west", "5a_d-01", DoorDirection.left, False, False), + "5a_d-01_east": Door("5a_d-01_east", "5a_d-01", DoorDirection.right, False, False), + "5a_d-01_north-west": Door("5a_d-01_north-west", "5a_d-01", DoorDirection.left, False, False), + "5a_d-01_north-east": Door("5a_d-01_north-east", "5a_d-01", DoorDirection.right, False, False), + + "5a_d-09_west": Door("5a_d-09_west", "5a_d-09", DoorDirection.down, False, False), + "5a_d-09_east": Door("5a_d-09_east", "5a_d-09", DoorDirection.right, False, False), + + "5a_d-04_west": Door("5a_d-04_west", "5a_d-04", DoorDirection.left, False, False), + "5a_d-04_east": Door("5a_d-04_east", "5a_d-04", DoorDirection.right, False, False), + "5a_d-04_south-west-left": Door("5a_d-04_south-west-left", "5a_d-04", DoorDirection.down, False, False), + "5a_d-04_south-west-right": Door("5a_d-04_south-west-right", "5a_d-04", DoorDirection.down, False, False), + "5a_d-04_south-east": Door("5a_d-04_south-east", "5a_d-04", DoorDirection.right, False, False), + "5a_d-04_north": Door("5a_d-04_north", "5a_d-04", DoorDirection.up, False, False), + + "5a_d-05_west": Door("5a_d-05_west", "5a_d-05", DoorDirection.left, False, False), + "5a_d-05_north": Door("5a_d-05_north", "5a_d-05", DoorDirection.up, False, False), + "5a_d-05_east": Door("5a_d-05_east", "5a_d-05", DoorDirection.right, False, False), + "5a_d-05_south": Door("5a_d-05_south", "5a_d-05", DoorDirection.down, False, False), + + "5a_d-06_north-east": Door("5a_d-06_north-east", "5a_d-06", DoorDirection.up, False, False), + "5a_d-06_south-east": Door("5a_d-06_south-east", "5a_d-06", DoorDirection.right, False, True), + "5a_d-06_south-west": Door("5a_d-06_south-west", "5a_d-06", DoorDirection.down, False, False), + "5a_d-06_north-west": Door("5a_d-06_north-west", "5a_d-06", DoorDirection.up, False, False), + + "5a_d-07_north": Door("5a_d-07_north", "5a_d-07", DoorDirection.up, False, False), + "5a_d-07_west": Door("5a_d-07_west", "5a_d-07", DoorDirection.left, False, False), + + "5a_d-02_west": Door("5a_d-02_west", "5a_d-02", DoorDirection.left, False, False), + "5a_d-02_east": Door("5a_d-02_east", "5a_d-02", DoorDirection.up, False, False), + + "5a_d-03_west": Door("5a_d-03_west", "5a_d-03", DoorDirection.up, False, False), + "5a_d-03_east": Door("5a_d-03_east", "5a_d-03", DoorDirection.right, False, False), + + "5a_d-15_north-west": Door("5a_d-15_north-west", "5a_d-15", DoorDirection.left, False, False), + "5a_d-15_west": Door("5a_d-15_west", "5a_d-15", DoorDirection.left, False, False), + "5a_d-15_south-west": Door("5a_d-15_south-west", "5a_d-15", DoorDirection.left, False, False), + "5a_d-15_south": Door("5a_d-15_south", "5a_d-15", DoorDirection.down, False, False), + "5a_d-15_south-east": Door("5a_d-15_south-east", "5a_d-15", DoorDirection.down, False, False), + + "5a_d-13_west": Door("5a_d-13_west", "5a_d-13", DoorDirection.up, False, False), + "5a_d-13_east": Door("5a_d-13_east", "5a_d-13", DoorDirection.up, False, True), + + "5a_d-19b_south-east-right": Door("5a_d-19b_south-east-right", "5a_d-19b", DoorDirection.right, False, False), + "5a_d-19b_south-east-down": Door("5a_d-19b_south-east-down", "5a_d-19b", DoorDirection.down, False, False), + "5a_d-19b_south-west": Door("5a_d-19b_south-west", "5a_d-19b", DoorDirection.down, False, False), + "5a_d-19b_north-east": Door("5a_d-19b_north-east", "5a_d-19b", DoorDirection.right, False, False), + + "5a_d-19_east": Door("5a_d-19_east", "5a_d-19", DoorDirection.up, False, False), + "5a_d-19_west": Door("5a_d-19_west", "5a_d-19", DoorDirection.up, False, False), + + "5a_d-10_east": Door("5a_d-10_east", "5a_d-10", DoorDirection.up, False, False), + "5a_d-10_west": Door("5a_d-10_west", "5a_d-10", DoorDirection.left, False, False), + + "5a_d-20_east": Door("5a_d-20_east", "5a_d-20", DoorDirection.right, False, False), + "5a_d-20_west": Door("5a_d-20_west", "5a_d-20", DoorDirection.down, False, True), + + "5a_e-00_east": Door("5a_e-00_east", "5a_e-00", DoorDirection.right, False, False), + "5a_e-00_west": Door("5a_e-00_west", "5a_e-00", DoorDirection.left, False, True), + + "5a_e-01_east": Door("5a_e-01_east", "5a_e-01", DoorDirection.right, False, False), + "5a_e-01_west": Door("5a_e-01_west", "5a_e-01", DoorDirection.left, False, True), + + "5a_e-02_east": Door("5a_e-02_east", "5a_e-02", DoorDirection.right, False, False), + "5a_e-02_west": Door("5a_e-02_west", "5a_e-02", DoorDirection.left, False, True), + + "5a_e-03_east": Door("5a_e-03_east", "5a_e-03", DoorDirection.right, False, False), + "5a_e-03_west": Door("5a_e-03_west", "5a_e-03", DoorDirection.left, False, True), + + "5a_e-04_east": Door("5a_e-04_east", "5a_e-04", DoorDirection.right, False, False), + "5a_e-04_west": Door("5a_e-04_west", "5a_e-04", DoorDirection.left, False, True), + + "5a_e-06_east": Door("5a_e-06_east", "5a_e-06", DoorDirection.right, False, False), + "5a_e-06_west": Door("5a_e-06_west", "5a_e-06", DoorDirection.left, False, True), + + "5a_e-05_east": Door("5a_e-05_east", "5a_e-05", DoorDirection.right, False, False), + "5a_e-05_west": Door("5a_e-05_west", "5a_e-05", DoorDirection.left, False, True), + + "5a_e-07_east": Door("5a_e-07_east", "5a_e-07", DoorDirection.right, False, False), + "5a_e-07_west": Door("5a_e-07_west", "5a_e-07", DoorDirection.left, False, True), + + "5a_e-08_east": Door("5a_e-08_east", "5a_e-08", DoorDirection.right, False, False), + "5a_e-08_west": Door("5a_e-08_west", "5a_e-08", DoorDirection.left, False, True), + + "5a_e-09_east": Door("5a_e-09_east", "5a_e-09", DoorDirection.right, False, False), + "5a_e-09_west": Door("5a_e-09_west", "5a_e-09", DoorDirection.left, False, True), + + "5a_e-10_east": Door("5a_e-10_east", "5a_e-10", DoorDirection.right, False, False), + "5a_e-10_west": Door("5a_e-10_west", "5a_e-10", DoorDirection.left, False, True), + + "5a_e-11_west": Door("5a_e-11_west", "5a_e-11", DoorDirection.left, False, True), + + "5b_start_east": Door("5b_start_east", "5b_start", DoorDirection.right, False, False), + + "5b_a-00_west": Door("5b_a-00_west", "5b_a-00", DoorDirection.left, False, False), + "5b_a-00_east": Door("5b_a-00_east", "5b_a-00", DoorDirection.right, False, False), + + "5b_a-01_west": Door("5b_a-01_west", "5b_a-01", DoorDirection.left, False, False), + "5b_a-01_east": Door("5b_a-01_east", "5b_a-01", DoorDirection.right, False, False), + + "5b_a-02_west": Door("5b_a-02_west", "5b_a-02", DoorDirection.left, False, False), + "5b_a-02_east": Door("5b_a-02_east", "5b_a-02", DoorDirection.up, False, False), + + "5b_b-00_south": Door("5b_b-00_south", "5b_b-00", DoorDirection.down, False, True), + "5b_b-00_west": Door("5b_b-00_west", "5b_b-00", DoorDirection.left, False, False), + "5b_b-00_north": Door("5b_b-00_north", "5b_b-00", DoorDirection.up, False, False), + "5b_b-00_east": Door("5b_b-00_east", "5b_b-00", DoorDirection.right, False, False), + + "5b_b-01_west": Door("5b_b-01_west", "5b_b-01", DoorDirection.left, False, False), + "5b_b-01_north": Door("5b_b-01_north", "5b_b-01", DoorDirection.up, False, False), + "5b_b-01_east": Door("5b_b-01_east", "5b_b-01", DoorDirection.right, False, False), + + "5b_b-04_west": Door("5b_b-04_west", "5b_b-04", DoorDirection.left, False, False), + "5b_b-04_east": Door("5b_b-04_east", "5b_b-04", DoorDirection.down, False, False), + + "5b_b-02_south": Door("5b_b-02_south", "5b_b-02", DoorDirection.down, False, True), + "5b_b-02_north-west": Door("5b_b-02_north-west", "5b_b-02", DoorDirection.left, False, False), + "5b_b-02_south-west": Door("5b_b-02_south-west", "5b_b-02", DoorDirection.left, False, False), + "5b_b-02_north": Door("5b_b-02_north", "5b_b-02", DoorDirection.up, False, False), + "5b_b-02_north-east": Door("5b_b-02_north-east", "5b_b-02", DoorDirection.right, False, False), + "5b_b-02_south-east": Door("5b_b-02_south-east", "5b_b-02", DoorDirection.right, False, False), + + "5b_b-05_north": Door("5b_b-05_north", "5b_b-05", DoorDirection.right, False, False), + "5b_b-05_south": Door("5b_b-05_south", "5b_b-05", DoorDirection.right, False, False), + + "5b_b-06_east": Door("5b_b-06_east", "5b_b-06", DoorDirection.right, False, False), + + "5b_b-07_north": Door("5b_b-07_north", "5b_b-07", DoorDirection.up, False, False), + "5b_b-07_south": Door("5b_b-07_south", "5b_b-07", DoorDirection.left, False, False), + + "5b_b-03_north": Door("5b_b-03_north", "5b_b-03", DoorDirection.up, False, False), + "5b_b-03_west": Door("5b_b-03_west", "5b_b-03", DoorDirection.left, False, False), + "5b_b-03_east": Door("5b_b-03_east", "5b_b-03", DoorDirection.down, False, True), + + "5b_b-08_north": Door("5b_b-08_north", "5b_b-08", DoorDirection.up, False, False), + "5b_b-08_south": Door("5b_b-08_south", "5b_b-08", DoorDirection.down, False, False), + "5b_b-08_east": Door("5b_b-08_east", "5b_b-08", DoorDirection.down, False, True), + + "5b_b-09_mirror": Door("5b_b-09_mirror", "5b_b-09", DoorDirection.special, False, False), + "5b_b-09_bottom": Door("5b_b-09_bottom", "5b_b-09", DoorDirection.down, False, True), + + "5b_c-00_mirror": Door("5b_c-00_mirror", "5b_c-00", DoorDirection.special, False, True), + "5b_c-00_bottom": Door("5b_c-00_bottom", "5b_c-00", DoorDirection.right, False, False), + + "5b_c-01_west": Door("5b_c-01_west", "5b_c-01", DoorDirection.left, False, True), + "5b_c-01_east": Door("5b_c-01_east", "5b_c-01", DoorDirection.right, False, False), + + "5b_c-02_west": Door("5b_c-02_west", "5b_c-02", DoorDirection.left, False, True), + "5b_c-02_east": Door("5b_c-02_east", "5b_c-02", DoorDirection.right, False, False), + + "5b_c-03_west": Door("5b_c-03_west", "5b_c-03", DoorDirection.left, False, True), + "5b_c-03_east": Door("5b_c-03_east", "5b_c-03", DoorDirection.right, False, False), + + "5b_c-04_west": Door("5b_c-04_west", "5b_c-04", DoorDirection.left, False, True), + "5b_c-04_east": Door("5b_c-04_east", "5b_c-04", DoorDirection.up, False, False), + + "5b_d-00_west": Door("5b_d-00_west", "5b_d-00", DoorDirection.down, False, True), + "5b_d-00_east": Door("5b_d-00_east", "5b_d-00", DoorDirection.right, False, False), + + "5b_d-01_west": Door("5b_d-01_west", "5b_d-01", DoorDirection.left, False, True), + "5b_d-01_east": Door("5b_d-01_east", "5b_d-01", DoorDirection.right, False, False), + + "5b_d-02_west": Door("5b_d-02_west", "5b_d-02", DoorDirection.left, False, True), + "5b_d-02_east": Door("5b_d-02_east", "5b_d-02", DoorDirection.right, False, False), + + "5b_d-03_west": Door("5b_d-03_west", "5b_d-03", DoorDirection.left, False, True), + "5b_d-03_east": Door("5b_d-03_east", "5b_d-03", DoorDirection.right, False, False), + + "5b_d-04_west": Door("5b_d-04_west", "5b_d-04", DoorDirection.left, False, True), + "5b_d-04_east": Door("5b_d-04_east", "5b_d-04", DoorDirection.right, False, False), + + "5b_d-05_west": Door("5b_d-05_west", "5b_d-05", DoorDirection.left, False, False), + + "5c_00_east": Door("5c_00_east", "5c_00", DoorDirection.right, False, False), + + "5c_01_west": Door("5c_01_west", "5c_01", DoorDirection.left, False, False), + "5c_01_east": Door("5c_01_east", "5c_01", DoorDirection.right, False, False), + + "5c_02_west": Door("5c_02_west", "5c_02", DoorDirection.left, False, False), + + "6a_00_west": Door("6a_00_west", "6a_00", DoorDirection.up, False, False), + + "6a_01_bottom": Door("6a_01_bottom", "6a_01", DoorDirection.down, False, True), + "6a_01_top": Door("6a_01_top", "6a_01", DoorDirection.up, False, False), + + "6a_02_bottom": Door("6a_02_bottom", "6a_02", DoorDirection.down, False, True), + "6a_02_bottom-west": Door("6a_02_bottom-west", "6a_02", DoorDirection.left, False, False), + "6a_02_top-west": Door("6a_02_top-west", "6a_02", DoorDirection.left, False, False), + "6a_02_top": Door("6a_02_top", "6a_02", DoorDirection.up, False, False), + + "6a_03_bottom": Door("6a_03_bottom", "6a_03", DoorDirection.right, False, False), + "6a_03_top": Door("6a_03_top", "6a_03", DoorDirection.right, False, False), + + "6a_02b_bottom": Door("6a_02b_bottom", "6a_02b", DoorDirection.down, False, True), + "6a_02b_top": Door("6a_02b_top", "6a_02b", DoorDirection.up, False, False), + + "6a_04_south": Door("6a_04_south", "6a_04", DoorDirection.down, False, True), + "6a_04_south-west": Door("6a_04_south-west", "6a_04", DoorDirection.left, True, False), + "6a_04_south-east": Door("6a_04_south-east", "6a_04", DoorDirection.right, False, False), + "6a_04_east": Door("6a_04_east", "6a_04", DoorDirection.right, False, False), + "6a_04_north-west": Door("6a_04_north-west", "6a_04", DoorDirection.left, False, False), + + "6a_04b_west": Door("6a_04b_west", "6a_04b", DoorDirection.left, False, False), + "6a_04b_east": Door("6a_04b_east", "6a_04b", DoorDirection.right, False, False), + + "6a_04c_east": Door("6a_04c_east", "6a_04c", DoorDirection.right, False, False), + + "6a_04d_west": Door("6a_04d_west", "6a_04d", DoorDirection.left, False, False), + + "6a_04e_east": Door("6a_04e_east", "6a_04e", DoorDirection.right, False, False), + + "6a_05_west": Door("6a_05_west", "6a_05", DoorDirection.left, False, False), + "6a_05_east": Door("6a_05_east", "6a_05", DoorDirection.right, False, False), + + "6a_06_west": Door("6a_06_west", "6a_06", DoorDirection.left, False, False), + "6a_06_east": Door("6a_06_east", "6a_06", DoorDirection.right, False, False), + + "6a_07_west": Door("6a_07_west", "6a_07", DoorDirection.left, False, False), + "6a_07_east": Door("6a_07_east", "6a_07", DoorDirection.right, False, False), + "6a_07_north-east": Door("6a_07_north-east", "6a_07", DoorDirection.right, False, False), + + "6a_08a_west": Door("6a_08a_west", "6a_08a", DoorDirection.left, False, False), + "6a_08a_east": Door("6a_08a_east", "6a_08a", DoorDirection.right, False, False), + + "6a_08b_west": Door("6a_08b_west", "6a_08b", DoorDirection.left, False, False), + "6a_08b_east": Door("6a_08b_east", "6a_08b", DoorDirection.right, False, False), + + "6a_09_west": Door("6a_09_west", "6a_09", DoorDirection.left, False, True), + "6a_09_north-west": Door("6a_09_north-west", "6a_09", DoorDirection.left, False, True), + "6a_09_east": Door("6a_09_east", "6a_09", DoorDirection.right, False, False), + "6a_09_north-east": Door("6a_09_north-east", "6a_09", DoorDirection.right, False, False), + + "6a_10a_west": Door("6a_10a_west", "6a_10a", DoorDirection.left, False, False), + "6a_10a_east": Door("6a_10a_east", "6a_10a", DoorDirection.right, False, False), + + "6a_10b_west": Door("6a_10b_west", "6a_10b", DoorDirection.left, False, False), + "6a_10b_east": Door("6a_10b_east", "6a_10b", DoorDirection.right, False, False), + + "6a_11_west": Door("6a_11_west", "6a_11", DoorDirection.left, False, True), + "6a_11_north-west": Door("6a_11_north-west", "6a_11", DoorDirection.left, False, True), + "6a_11_east": Door("6a_11_east", "6a_11", DoorDirection.right, False, False), + "6a_11_north-east": Door("6a_11_north-east", "6a_11", DoorDirection.right, False, False), + + "6a_12a_west": Door("6a_12a_west", "6a_12a", DoorDirection.left, False, False), + "6a_12a_east": Door("6a_12a_east", "6a_12a", DoorDirection.right, False, False), + + "6a_12b_west": Door("6a_12b_west", "6a_12b", DoorDirection.left, False, False), + "6a_12b_east": Door("6a_12b_east", "6a_12b", DoorDirection.right, False, False), + + "6a_13_west": Door("6a_13_west", "6a_13", DoorDirection.left, False, True), + "6a_13_north-west": Door("6a_13_north-west", "6a_13", DoorDirection.left, False, True), + "6a_13_east": Door("6a_13_east", "6a_13", DoorDirection.right, False, False), + "6a_13_north-east": Door("6a_13_north-east", "6a_13", DoorDirection.right, False, False), + + "6a_14a_west": Door("6a_14a_west", "6a_14a", DoorDirection.left, False, False), + "6a_14a_east": Door("6a_14a_east", "6a_14a", DoorDirection.right, False, False), + + "6a_14b_west": Door("6a_14b_west", "6a_14b", DoorDirection.left, False, False), + "6a_14b_east": Door("6a_14b_east", "6a_14b", DoorDirection.right, False, False), + + "6a_15_west": Door("6a_15_west", "6a_15", DoorDirection.left, False, True), + "6a_15_north-west": Door("6a_15_north-west", "6a_15", DoorDirection.left, False, True), + "6a_15_east": Door("6a_15_east", "6a_15", DoorDirection.right, False, False), + "6a_15_north-east": Door("6a_15_north-east", "6a_15", DoorDirection.right, False, False), + + "6a_16a_west": Door("6a_16a_west", "6a_16a", DoorDirection.left, False, False), + "6a_16a_east": Door("6a_16a_east", "6a_16a", DoorDirection.right, False, False), + + "6a_16b_west": Door("6a_16b_west", "6a_16b", DoorDirection.left, False, False), + "6a_16b_east": Door("6a_16b_east", "6a_16b", DoorDirection.right, False, False), + + "6a_17_west": Door("6a_17_west", "6a_17", DoorDirection.left, False, True), + "6a_17_north-west": Door("6a_17_north-west", "6a_17", DoorDirection.left, False, True), + "6a_17_east": Door("6a_17_east", "6a_17", DoorDirection.right, False, False), + "6a_17_north-east": Door("6a_17_north-east", "6a_17", DoorDirection.right, False, False), + + "6a_18a_west": Door("6a_18a_west", "6a_18a", DoorDirection.left, False, False), + "6a_18a_east": Door("6a_18a_east", "6a_18a", DoorDirection.right, False, False), + + "6a_18b_west": Door("6a_18b_west", "6a_18b", DoorDirection.left, False, False), + "6a_18b_east": Door("6a_18b_east", "6a_18b", DoorDirection.right, False, False), + + "6a_19_west": Door("6a_19_west", "6a_19", DoorDirection.left, False, True), + "6a_19_north-west": Door("6a_19_north-west", "6a_19", DoorDirection.left, False, True), + "6a_19_east": Door("6a_19_east", "6a_19", DoorDirection.right, False, False), + + "6a_20_west": Door("6a_20_west", "6a_20", DoorDirection.left, False, False), + "6a_20_east": Door("6a_20_east", "6a_20", DoorDirection.right, False, False), + + "6a_b-00_west": Door("6a_b-00_west", "6a_b-00", DoorDirection.left, False, True), + "6a_b-00_top": Door("6a_b-00_top", "6a_b-00", DoorDirection.up, False, False), + "6a_b-00_east": Door("6a_b-00_east", "6a_b-00", DoorDirection.right, False, False), + + "6a_b-00b_bottom": Door("6a_b-00b_bottom", "6a_b-00b", DoorDirection.down, False, False), + "6a_b-00b_top": Door("6a_b-00b_top", "6a_b-00b", DoorDirection.left, False, False), + + "6a_b-00c_east": Door("6a_b-00c_east", "6a_b-00c", DoorDirection.right, False, False), + + "6a_b-01_west": Door("6a_b-01_west", "6a_b-01", DoorDirection.left, False, False), + "6a_b-01_east": Door("6a_b-01_east", "6a_b-01", DoorDirection.down, False, False), + + "6a_b-02_top": Door("6a_b-02_top", "6a_b-02", DoorDirection.up, False, False), + "6a_b-02_bottom": Door("6a_b-02_bottom", "6a_b-02", DoorDirection.right, False, False), + + "6a_b-02b_top": Door("6a_b-02b_top", "6a_b-02b", DoorDirection.left, False, False), + "6a_b-02b_bottom": Door("6a_b-02b_bottom", "6a_b-02b", DoorDirection.right, False, False), + + "6a_b-03_west": Door("6a_b-03_west", "6a_b-03", DoorDirection.left, False, False), + "6a_b-03_east": Door("6a_b-03_east", "6a_b-03", DoorDirection.right, False, False), + + "6a_boss-00_west": Door("6a_boss-00_west", "6a_boss-00", DoorDirection.left, False, True), + "6a_boss-00_east": Door("6a_boss-00_east", "6a_boss-00", DoorDirection.down, False, False), + + "6a_boss-01_west": Door("6a_boss-01_west", "6a_boss-01", DoorDirection.up, False, False), + "6a_boss-01_east": Door("6a_boss-01_east", "6a_boss-01", DoorDirection.down, False, False), + + "6a_boss-02_west": Door("6a_boss-02_west", "6a_boss-02", DoorDirection.up, False, False), + "6a_boss-02_east": Door("6a_boss-02_east", "6a_boss-02", DoorDirection.down, False, False), + + "6a_boss-03_west": Door("6a_boss-03_west", "6a_boss-03", DoorDirection.up, False, False), + "6a_boss-03_east": Door("6a_boss-03_east", "6a_boss-03", DoorDirection.down, False, False), + + "6a_boss-04_west": Door("6a_boss-04_west", "6a_boss-04", DoorDirection.up, False, False), + "6a_boss-04_east": Door("6a_boss-04_east", "6a_boss-04", DoorDirection.right, False, False), + + "6a_boss-05_west": Door("6a_boss-05_west", "6a_boss-05", DoorDirection.left, False, False), + "6a_boss-05_east": Door("6a_boss-05_east", "6a_boss-05", DoorDirection.down, False, False), + + "6a_boss-06_west": Door("6a_boss-06_west", "6a_boss-06", DoorDirection.up, False, False), + "6a_boss-06_east": Door("6a_boss-06_east", "6a_boss-06", DoorDirection.down, False, False), + + "6a_boss-07_west": Door("6a_boss-07_west", "6a_boss-07", DoorDirection.up, False, False), + "6a_boss-07_east": Door("6a_boss-07_east", "6a_boss-07", DoorDirection.down, False, False), + + "6a_boss-08_west": Door("6a_boss-08_west", "6a_boss-08", DoorDirection.up, False, False), + "6a_boss-08_east": Door("6a_boss-08_east", "6a_boss-08", DoorDirection.down, False, False), + + "6a_boss-09_west": Door("6a_boss-09_west", "6a_boss-09", DoorDirection.up, False, False), + "6a_boss-09_east": Door("6a_boss-09_east", "6a_boss-09", DoorDirection.right, False, False), + + "6a_boss-10_west": Door("6a_boss-10_west", "6a_boss-10", DoorDirection.left, False, False), + "6a_boss-10_east": Door("6a_boss-10_east", "6a_boss-10", DoorDirection.right, False, False), + + "6a_boss-11_west": Door("6a_boss-11_west", "6a_boss-11", DoorDirection.left, False, False), + "6a_boss-11_east": Door("6a_boss-11_east", "6a_boss-11", DoorDirection.down, False, False), + + "6a_boss-12_west": Door("6a_boss-12_west", "6a_boss-12", DoorDirection.up, False, False), + "6a_boss-12_east": Door("6a_boss-12_east", "6a_boss-12", DoorDirection.down, False, False), + + "6a_boss-13_west": Door("6a_boss-13_west", "6a_boss-13", DoorDirection.up, False, False), + "6a_boss-13_east": Door("6a_boss-13_east", "6a_boss-13", DoorDirection.right, False, False), + + "6a_boss-14_west": Door("6a_boss-14_west", "6a_boss-14", DoorDirection.left, False, False), + "6a_boss-14_east": Door("6a_boss-14_east", "6a_boss-14", DoorDirection.right, False, False), + + "6a_boss-15_west": Door("6a_boss-15_west", "6a_boss-15", DoorDirection.left, False, False), + "6a_boss-15_east": Door("6a_boss-15_east", "6a_boss-15", DoorDirection.down, False, False), + + "6a_boss-16_west": Door("6a_boss-16_west", "6a_boss-16", DoorDirection.up, False, False), + "6a_boss-16_east": Door("6a_boss-16_east", "6a_boss-16", DoorDirection.right, False, False), + + "6a_boss-17_west": Door("6a_boss-17_west", "6a_boss-17", DoorDirection.left, False, False), + "6a_boss-17_east": Door("6a_boss-17_east", "6a_boss-17", DoorDirection.down, False, False), + + "6a_boss-18_west": Door("6a_boss-18_west", "6a_boss-18", DoorDirection.up, False, False), + "6a_boss-18_east": Door("6a_boss-18_east", "6a_boss-18", DoorDirection.right, False, False), + + "6a_boss-19_west": Door("6a_boss-19_west", "6a_boss-19", DoorDirection.left, False, False), + "6a_boss-19_east": Door("6a_boss-19_east", "6a_boss-19", DoorDirection.right, False, False), + + "6a_boss-20_west": Door("6a_boss-20_west", "6a_boss-20", DoorDirection.left, False, False), + "6a_boss-20_east": Door("6a_boss-20_east", "6a_boss-20", DoorDirection.up, False, False), + + "6a_after-00_bottom": Door("6a_after-00_bottom", "6a_after-00", DoorDirection.down, False, True), + "6a_after-00_top": Door("6a_after-00_top", "6a_after-00", DoorDirection.up, False, False), + + "6a_after-01_bottom": Door("6a_after-01_bottom", "6a_after-01", DoorDirection.down, False, True), + + "6b_a-00_top": Door("6b_a-00_top", "6b_a-00", DoorDirection.up, False, False), + + "6b_a-01_bottom": Door("6b_a-01_bottom", "6b_a-01", DoorDirection.down, False, True), + "6b_a-01_top": Door("6b_a-01_top", "6b_a-01", DoorDirection.up, False, False), + + "6b_a-02_bottom": Door("6b_a-02_bottom", "6b_a-02", DoorDirection.down, False, True), + "6b_a-02_top": Door("6b_a-02_top", "6b_a-02", DoorDirection.up, False, False), + + "6b_a-03_west": Door("6b_a-03_west", "6b_a-03", DoorDirection.down, False, True), + "6b_a-03_east": Door("6b_a-03_east", "6b_a-03", DoorDirection.right, False, False), + + "6b_a-04_west": Door("6b_a-04_west", "6b_a-04", DoorDirection.left, False, False), + "6b_a-04_east": Door("6b_a-04_east", "6b_a-04", DoorDirection.right, False, False), + + "6b_a-05_west": Door("6b_a-05_west", "6b_a-05", DoorDirection.left, False, False), + "6b_a-05_east": Door("6b_a-05_east", "6b_a-05", DoorDirection.right, False, False), + + "6b_a-06_west": Door("6b_a-06_west", "6b_a-06", DoorDirection.left, False, False), + "6b_a-06_east": Door("6b_a-06_east", "6b_a-06", DoorDirection.right, False, False), + + "6b_b-00_west": Door("6b_b-00_west", "6b_b-00", DoorDirection.left, False, True), + "6b_b-00_east": Door("6b_b-00_east", "6b_b-00", DoorDirection.down, False, False), + + "6b_b-01_top": Door("6b_b-01_top", "6b_b-01", DoorDirection.up, False, False), + "6b_b-01_bottom": Door("6b_b-01_bottom", "6b_b-01", DoorDirection.right, False, False), + + "6b_b-02_top": Door("6b_b-02_top", "6b_b-02", DoorDirection.left, False, False), + "6b_b-02_bottom": Door("6b_b-02_bottom", "6b_b-02", DoorDirection.right, False, False), + + "6b_b-03_top": Door("6b_b-03_top", "6b_b-03", DoorDirection.left, False, False), + "6b_b-03_bottom": Door("6b_b-03_bottom", "6b_b-03", DoorDirection.right, False, False), + + "6b_b-04_top": Door("6b_b-04_top", "6b_b-04", DoorDirection.left, False, False), + "6b_b-04_bottom": Door("6b_b-04_bottom", "6b_b-04", DoorDirection.right, False, False), + + "6b_b-05_top": Door("6b_b-05_top", "6b_b-05", DoorDirection.left, False, False), + "6b_b-05_bottom": Door("6b_b-05_bottom", "6b_b-05", DoorDirection.right, False, False), + + "6b_b-06_top": Door("6b_b-06_top", "6b_b-06", DoorDirection.left, False, False), + "6b_b-06_bottom": Door("6b_b-06_bottom", "6b_b-06", DoorDirection.right, False, False), + + "6b_b-07_top": Door("6b_b-07_top", "6b_b-07", DoorDirection.left, False, False), + "6b_b-07_bottom": Door("6b_b-07_bottom", "6b_b-07", DoorDirection.right, False, False), + + "6b_b-08_top": Door("6b_b-08_top", "6b_b-08", DoorDirection.left, False, False), + "6b_b-08_bottom": Door("6b_b-08_bottom", "6b_b-08", DoorDirection.right, False, False), + + "6b_b-10_west": Door("6b_b-10_west", "6b_b-10", DoorDirection.left, False, False), + "6b_b-10_east": Door("6b_b-10_east", "6b_b-10", DoorDirection.right, False, False), + + "6b_c-00_west": Door("6b_c-00_west", "6b_c-00", DoorDirection.left, False, True), + "6b_c-00_east": Door("6b_c-00_east", "6b_c-00", DoorDirection.right, False, False), + + "6b_c-01_west": Door("6b_c-01_west", "6b_c-01", DoorDirection.left, False, True), + "6b_c-01_east": Door("6b_c-01_east", "6b_c-01", DoorDirection.right, False, False), + + "6b_c-02_west": Door("6b_c-02_west", "6b_c-02", DoorDirection.left, False, True), + "6b_c-02_east": Door("6b_c-02_east", "6b_c-02", DoorDirection.right, False, False), + + "6b_c-03_west": Door("6b_c-03_west", "6b_c-03", DoorDirection.left, False, True), + "6b_c-03_east": Door("6b_c-03_east", "6b_c-03", DoorDirection.right, False, False), + + "6b_c-04_west": Door("6b_c-04_west", "6b_c-04", DoorDirection.left, False, True), + "6b_c-04_east": Door("6b_c-04_east", "6b_c-04", DoorDirection.right, False, False), + + "6b_d-00_west": Door("6b_d-00_west", "6b_d-00", DoorDirection.left, False, True), + "6b_d-00_east": Door("6b_d-00_east", "6b_d-00", DoorDirection.up, False, False), + + "6b_d-01_west": Door("6b_d-01_west", "6b_d-01", DoorDirection.down, False, True), + "6b_d-01_east": Door("6b_d-01_east", "6b_d-01", DoorDirection.right, False, False), + + "6b_d-02_west": Door("6b_d-02_west", "6b_d-02", DoorDirection.left, False, False), + "6b_d-02_east": Door("6b_d-02_east", "6b_d-02", DoorDirection.right, False, False), + + "6b_d-03_west": Door("6b_d-03_west", "6b_d-03", DoorDirection.left, False, False), + "6b_d-03_east": Door("6b_d-03_east", "6b_d-03", DoorDirection.right, False, False), + + "6b_d-04_west": Door("6b_d-04_west", "6b_d-04", DoorDirection.left, False, False), + "6b_d-04_east": Door("6b_d-04_east", "6b_d-04", DoorDirection.right, False, False), + + "6b_d-05_west": Door("6b_d-05_west", "6b_d-05", DoorDirection.left, False, False), + + "6c_00_east": Door("6c_00_east", "6c_00", DoorDirection.right, False, False), + + "6c_01_west": Door("6c_01_west", "6c_01", DoorDirection.left, False, False), + "6c_01_east": Door("6c_01_east", "6c_01", DoorDirection.right, False, False), + + "6c_02_west": Door("6c_02_west", "6c_02", DoorDirection.left, False, False), + + "7a_a-00_east": Door("7a_a-00_east", "7a_a-00", DoorDirection.right, False, False), + + "7a_a-01_west": Door("7a_a-01_west", "7a_a-01", DoorDirection.left, False, True), + "7a_a-01_east": Door("7a_a-01_east", "7a_a-01", DoorDirection.right, False, False), + + "7a_a-02_west": Door("7a_a-02_west", "7a_a-02", DoorDirection.left, False, True), + "7a_a-02_north": Door("7a_a-02_north", "7a_a-02", DoorDirection.up, False, False), + "7a_a-02_north-west": Door("7a_a-02_north-west", "7a_a-02", DoorDirection.up, False, True), + "7a_a-02_east": Door("7a_a-02_east", "7a_a-02", DoorDirection.right, False, False), + + "7a_a-02b_east": Door("7a_a-02b_east", "7a_a-02b", DoorDirection.down, False, True), + "7a_a-02b_west": Door("7a_a-02b_west", "7a_a-02b", DoorDirection.down, False, False), + + "7a_a-03_west": Door("7a_a-03_west", "7a_a-03", DoorDirection.left, False, False), + "7a_a-03_east": Door("7a_a-03_east", "7a_a-03", DoorDirection.right, False, False), + + "7a_a-04_west": Door("7a_a-04_west", "7a_a-04", DoorDirection.left, False, False), + "7a_a-04_north": Door("7a_a-04_north", "7a_a-04", DoorDirection.up, True, False), + "7a_a-04_east": Door("7a_a-04_east", "7a_a-04", DoorDirection.right, False, False), + + "7a_a-04b_east": Door("7a_a-04b_east", "7a_a-04b", DoorDirection.down, False, False), + + "7a_a-05_west": Door("7a_a-05_west", "7a_a-05", DoorDirection.left, False, False), + "7a_a-05_east": Door("7a_a-05_east", "7a_a-05", DoorDirection.right, False, False), + + "7a_a-06_bottom": Door("7a_a-06_bottom", "7a_a-06", DoorDirection.left, False, False), + "7a_a-06_top": Door("7a_a-06_top", "7a_a-06", DoorDirection.up, False, False), + + "7a_b-00_bottom": Door("7a_b-00_bottom", "7a_b-00", DoorDirection.down, False, True), + "7a_b-00_top": Door("7a_b-00_top", "7a_b-00", DoorDirection.up, False, False), + + "7a_b-01_west": Door("7a_b-01_west", "7a_b-01", DoorDirection.down, False, True), + "7a_b-01_east": Door("7a_b-01_east", "7a_b-01", DoorDirection.right, False, False), + + "7a_b-02_south": Door("7a_b-02_south", "7a_b-02", DoorDirection.left, False, False), + "7a_b-02_north-west": Door("7a_b-02_north-west", "7a_b-02", DoorDirection.left, False, False), + "7a_b-02_north": Door("7a_b-02_north", "7a_b-02", DoorDirection.up, False, False), + "7a_b-02_north-east": Door("7a_b-02_north-east", "7a_b-02", DoorDirection.right, False, False), + + "7a_b-02b_south": Door("7a_b-02b_south", "7a_b-02b", DoorDirection.right, False, False), + "7a_b-02b_north-west": Door("7a_b-02b_north-west", "7a_b-02b", DoorDirection.left, False, False), + "7a_b-02b_north-east": Door("7a_b-02b_north-east", "7a_b-02b", DoorDirection.right, False, False), + + "7a_b-02e_east": Door("7a_b-02e_east", "7a_b-02e", DoorDirection.right, False, False), + + "7a_b-02c_west": Door("7a_b-02c_west", "7a_b-02c", DoorDirection.left, False, False), + "7a_b-02c_south-east": Door("7a_b-02c_south-east", "7a_b-02c", DoorDirection.down, False, False), + "7a_b-02c_east": Door("7a_b-02c_east", "7a_b-02c", DoorDirection.right, False, False), + + "7a_b-02d_north": Door("7a_b-02d_north", "7a_b-02d", DoorDirection.up, False, False), + "7a_b-02d_south": Door("7a_b-02d_south", "7a_b-02d", DoorDirection.down, False, False), + + "7a_b-03_west": Door("7a_b-03_west", "7a_b-03", DoorDirection.left, False, False), + "7a_b-03_north": Door("7a_b-03_north", "7a_b-03", DoorDirection.up, False, False), + "7a_b-03_east": Door("7a_b-03_east", "7a_b-03", DoorDirection.right, False, False), + + "7a_b-04_west": Door("7a_b-04_west", "7a_b-04", DoorDirection.left, False, False), + + "7a_b-05_west": Door("7a_b-05_west", "7a_b-05", DoorDirection.down, False, True), + "7a_b-05_north-west": Door("7a_b-05_north-west", "7a_b-05", DoorDirection.left, False, True), + "7a_b-05_east": Door("7a_b-05_east", "7a_b-05", DoorDirection.right, False, False), + + "7a_b-06_west": Door("7a_b-06_west", "7a_b-06", DoorDirection.left, False, False), + "7a_b-06_east": Door("7a_b-06_east", "7a_b-06", DoorDirection.right, False, False), + + "7a_b-07_west": Door("7a_b-07_west", "7a_b-07", DoorDirection.left, False, False), + "7a_b-07_east": Door("7a_b-07_east", "7a_b-07", DoorDirection.right, False, False), + + "7a_b-08_west": Door("7a_b-08_west", "7a_b-08", DoorDirection.left, False, False), + "7a_b-08_east": Door("7a_b-08_east", "7a_b-08", DoorDirection.right, False, False), + + "7a_b-09_bottom": Door("7a_b-09_bottom", "7a_b-09", DoorDirection.left, False, False), + "7a_b-09_top": Door("7a_b-09_top", "7a_b-09", DoorDirection.up, False, False), + + "7a_c-00_west": Door("7a_c-00_west", "7a_c-00", DoorDirection.down, False, True), + "7a_c-00_east": Door("7a_c-00_east", "7a_c-00", DoorDirection.up, False, False), + + "7a_c-01_bottom": Door("7a_c-01_bottom", "7a_c-01", DoorDirection.down, False, True), + "7a_c-01_top": Door("7a_c-01_top", "7a_c-01", DoorDirection.up, False, False), + + "7a_c-02_bottom": Door("7a_c-02_bottom", "7a_c-02", DoorDirection.down, False, True), + "7a_c-02_top": Door("7a_c-02_top", "7a_c-02", DoorDirection.up, False, False), + + "7a_c-03_south": Door("7a_c-03_south", "7a_c-03", DoorDirection.down, False, True), + "7a_c-03_west": Door("7a_c-03_west", "7a_c-03", DoorDirection.left, False, False), + "7a_c-03_east": Door("7a_c-03_east", "7a_c-03", DoorDirection.right, False, False), + + "7a_c-03b_east": Door("7a_c-03b_east", "7a_c-03b", DoorDirection.right, False, False), + + "7a_c-04_west": Door("7a_c-04_west", "7a_c-04", DoorDirection.left, False, True), + "7a_c-04_north-west": Door("7a_c-04_north-west", "7a_c-04", DoorDirection.up, False, False), + "7a_c-04_north-east": Door("7a_c-04_north-east", "7a_c-04", DoorDirection.up, False, False), + "7a_c-04_east": Door("7a_c-04_east", "7a_c-04", DoorDirection.right, False, False), + + "7a_c-05_west": Door("7a_c-05_west", "7a_c-05", DoorDirection.left, False, False), + + "7a_c-06_south": Door("7a_c-06_south", "7a_c-06", DoorDirection.down, False, False), + "7a_c-06_north": Door("7a_c-06_north", "7a_c-06", DoorDirection.up, False, False), + "7a_c-06_east": Door("7a_c-06_east", "7a_c-06", DoorDirection.right, False, False), + + "7a_c-06b_south": Door("7a_c-06b_south", "7a_c-06b", DoorDirection.down, False, False), + "7a_c-06b_north": Door("7a_c-06b_north", "7a_c-06b", DoorDirection.up, False, False), + "7a_c-06b_west": Door("7a_c-06b_west", "7a_c-06b", DoorDirection.left, False, False), + "7a_c-06b_east": Door("7a_c-06b_east", "7a_c-06b", DoorDirection.right, True, False), + + "7a_c-06c_west": Door("7a_c-06c_west", "7a_c-06c", DoorDirection.left, False, False), + + "7a_c-07_west": Door("7a_c-07_west", "7a_c-07", DoorDirection.left, False, False), + "7a_c-07_south-west": Door("7a_c-07_south-west", "7a_c-07", DoorDirection.down, False, True), + "7a_c-07_south-east": Door("7a_c-07_south-east", "7a_c-07", DoorDirection.down, False, True), + "7a_c-07_east": Door("7a_c-07_east", "7a_c-07", DoorDirection.right, False, False), + + "7a_c-07b_east": Door("7a_c-07b_east", "7a_c-07b", DoorDirection.right, False, False), + + "7a_c-08_west": Door("7a_c-08_west", "7a_c-08", DoorDirection.left, False, False), + "7a_c-08_east": Door("7a_c-08_east", "7a_c-08", DoorDirection.right, False, False), + + "7a_c-09_bottom": Door("7a_c-09_bottom", "7a_c-09", DoorDirection.left, False, False), + "7a_c-09_top": Door("7a_c-09_top", "7a_c-09", DoorDirection.up, False, False), + + "7a_d-00_bottom": Door("7a_d-00_bottom", "7a_d-00", DoorDirection.down, False, True), + "7a_d-00_top": Door("7a_d-00_top", "7a_d-00", DoorDirection.up, False, False), + + "7a_d-01_west": Door("7a_d-01_west", "7a_d-01", DoorDirection.down, False, True), + "7a_d-01_east": Door("7a_d-01_east", "7a_d-01", DoorDirection.right, False, False), + + "7a_d-01b_west": Door("7a_d-01b_west", "7a_d-01b", DoorDirection.left, False, False), + "7a_d-01b_south-west": Door("7a_d-01b_south-west", "7a_d-01b", DoorDirection.down, False, False), + "7a_d-01b_east": Door("7a_d-01b_east", "7a_d-01b", DoorDirection.right, False, False), + "7a_d-01b_south-east": Door("7a_d-01b_south-east", "7a_d-01b", DoorDirection.down, False, False), + + "7a_d-01c_west": Door("7a_d-01c_west", "7a_d-01c", DoorDirection.up, False, False), + "7a_d-01c_south": Door("7a_d-01c_south", "7a_d-01c", DoorDirection.down, False, False), + "7a_d-01c_east": Door("7a_d-01c_east", "7a_d-01c", DoorDirection.up, False, False), + "7a_d-01c_south-east": Door("7a_d-01c_south-east", "7a_d-01c", DoorDirection.down, False, False), + + "7a_d-01d_west": Door("7a_d-01d_west", "7a_d-01d", DoorDirection.up, False, False), + "7a_d-01d_east": Door("7a_d-01d_east", "7a_d-01d", DoorDirection.up, False, False), + + "7a_d-02_west": Door("7a_d-02_west", "7a_d-02", DoorDirection.left, False, False), + "7a_d-02_east": Door("7a_d-02_east", "7a_d-02", DoorDirection.right, False, False), + + "7a_d-03_west": Door("7a_d-03_west", "7a_d-03", DoorDirection.left, False, False), + "7a_d-03_north-west": Door("7a_d-03_north-west", "7a_d-03", DoorDirection.up, False, True), + "7a_d-03_east": Door("7a_d-03_east", "7a_d-03", DoorDirection.right, False, False), + "7a_d-03_north-east": Door("7a_d-03_north-east", "7a_d-03", DoorDirection.up, False, False), + + "7a_d-03b_west": Door("7a_d-03b_west", "7a_d-03b", DoorDirection.down, False, False), + "7a_d-03b_east": Door("7a_d-03b_east", "7a_d-03b", DoorDirection.down, False, True), + + "7a_d-04_west": Door("7a_d-04_west", "7a_d-04", DoorDirection.left, False, False), + "7a_d-04_east": Door("7a_d-04_east", "7a_d-04", DoorDirection.right, False, False), + + "7a_d-05_west": Door("7a_d-05_west", "7a_d-05", DoorDirection.left, False, False), + "7a_d-05_north-east": Door("7a_d-05_north-east", "7a_d-05", DoorDirection.up, False, False), + "7a_d-05_east": Door("7a_d-05_east", "7a_d-05", DoorDirection.right, False, False), + + "7a_d-05b_west": Door("7a_d-05b_west", "7a_d-05b", DoorDirection.left, False, False), + + "7a_d-06_west": Door("7a_d-06_west", "7a_d-06", DoorDirection.left, False, False), + "7a_d-06_south-west": Door("7a_d-06_south-west", "7a_d-06", DoorDirection.down, False, False), + "7a_d-06_south-east": Door("7a_d-06_south-east", "7a_d-06", DoorDirection.down, True, False), + "7a_d-06_east": Door("7a_d-06_east", "7a_d-06", DoorDirection.right, False, False), + + "7a_d-07_east": Door("7a_d-07_east", "7a_d-07", DoorDirection.right, False, False), + + "7a_d-08_west": Door("7a_d-08_west", "7a_d-08", DoorDirection.up, False, False), + "7a_d-08_east": Door("7a_d-08_east", "7a_d-08", DoorDirection.right, False, False), + + "7a_d-09_west": Door("7a_d-09_west", "7a_d-09", DoorDirection.left, False, False), + "7a_d-09_east": Door("7a_d-09_east", "7a_d-09", DoorDirection.down, False, False), + + "7a_d-10_west": Door("7a_d-10_west", "7a_d-10", DoorDirection.left, False, True), + "7a_d-10_north-west": Door("7a_d-10_north-west", "7a_d-10", DoorDirection.up, False, True), + "7a_d-10_north": Door("7a_d-10_north", "7a_d-10", DoorDirection.up, False, True), + "7a_d-10_north-east": Door("7a_d-10_north-east", "7a_d-10", DoorDirection.up, False, False), + "7a_d-10_east": Door("7a_d-10_east", "7a_d-10", DoorDirection.right, False, False), + + "7a_d-10b_west": Door("7a_d-10b_west", "7a_d-10b", DoorDirection.down, False, False), + "7a_d-10b_east": Door("7a_d-10b_east", "7a_d-10b", DoorDirection.down, False, True), + + "7a_d-11_bottom": Door("7a_d-11_bottom", "7a_d-11", DoorDirection.left, False, False), + "7a_d-11_top": Door("7a_d-11_top", "7a_d-11", DoorDirection.up, False, False), + + "7a_e-00b_bottom": Door("7a_e-00b_bottom", "7a_e-00b", DoorDirection.down, False, True), + "7a_e-00b_top": Door("7a_e-00b_top", "7a_e-00b", DoorDirection.up, False, False), + + "7a_e-00_west": Door("7a_e-00_west", "7a_e-00", DoorDirection.left, False, False), + "7a_e-00_south-west": Door("7a_e-00_south-west", "7a_e-00", DoorDirection.down, False, True), + "7a_e-00_north-west": Door("7a_e-00_north-west", "7a_e-00", DoorDirection.up, False, False), + "7a_e-00_east": Door("7a_e-00_east", "7a_e-00", DoorDirection.right, False, False), + + "7a_e-01_west": Door("7a_e-01_west", "7a_e-01", DoorDirection.left, False, False), + "7a_e-01_north": Door("7a_e-01_north", "7a_e-01", DoorDirection.up, False, True), + "7a_e-01_east": Door("7a_e-01_east", "7a_e-01", DoorDirection.right, False, True), + + "7a_e-01b_west": Door("7a_e-01b_west", "7a_e-01b", DoorDirection.up, False, False), + "7a_e-01b_east": Door("7a_e-01b_east", "7a_e-01b", DoorDirection.right, False, False), + + "7a_e-01c_west": Door("7a_e-01c_west", "7a_e-01c", DoorDirection.down, False, True), + "7a_e-01c_east": Door("7a_e-01c_east", "7a_e-01c", DoorDirection.down, False, False), + + "7a_e-02_west": Door("7a_e-02_west", "7a_e-02", DoorDirection.down, False, True), + "7a_e-02_east": Door("7a_e-02_east", "7a_e-02", DoorDirection.right, False, False), + + "7a_e-03_south-west": Door("7a_e-03_south-west", "7a_e-03", DoorDirection.left, False, False), + "7a_e-03_west": Door("7a_e-03_west", "7a_e-03", DoorDirection.left, False, False), + "7a_e-03_east": Door("7a_e-03_east", "7a_e-03", DoorDirection.right, False, False), + + "7a_e-04_west": Door("7a_e-04_west", "7a_e-04", DoorDirection.left, False, False), + "7a_e-04_east": Door("7a_e-04_east", "7a_e-04", DoorDirection.right, False, False), + + "7a_e-05_west": Door("7a_e-05_west", "7a_e-05", DoorDirection.left, False, False), + "7a_e-05_east": Door("7a_e-05_east", "7a_e-05", DoorDirection.right, False, False), + + "7a_e-06_west": Door("7a_e-06_west", "7a_e-06", DoorDirection.left, False, False), + "7a_e-06_east": Door("7a_e-06_east", "7a_e-06", DoorDirection.right, False, False), + + "7a_e-07_bottom": Door("7a_e-07_bottom", "7a_e-07", DoorDirection.left, False, False), + "7a_e-07_top": Door("7a_e-07_top", "7a_e-07", DoorDirection.up, False, False), + + "7a_e-08_south": Door("7a_e-08_south", "7a_e-08", DoorDirection.down, False, True), + "7a_e-08_west": Door("7a_e-08_west", "7a_e-08", DoorDirection.left, False, False), + "7a_e-08_east": Door("7a_e-08_east", "7a_e-08", DoorDirection.right, False, False), + + "7a_e-09_north": Door("7a_e-09_north", "7a_e-09", DoorDirection.up, True, False), + "7a_e-09_east": Door("7a_e-09_east", "7a_e-09", DoorDirection.right, False, False), + + "7a_e-11_south": Door("7a_e-11_south", "7a_e-11", DoorDirection.down, False, False), + "7a_e-11_north": Door("7a_e-11_north", "7a_e-11", DoorDirection.up, False, False), + "7a_e-11_east": Door("7a_e-11_east", "7a_e-11", DoorDirection.down, False, False), + + "7a_e-12_west": Door("7a_e-12_west", "7a_e-12", DoorDirection.down, False, False), + + "7a_e-10_south": Door("7a_e-10_south", "7a_e-10", DoorDirection.left, False, False), + "7a_e-10_north": Door("7a_e-10_north", "7a_e-10", DoorDirection.up, False, True), + "7a_e-10_east": Door("7a_e-10_east", "7a_e-10", DoorDirection.right, False, False), + + "7a_e-10b_west": Door("7a_e-10b_west", "7a_e-10b", DoorDirection.left, False, False), + "7a_e-10b_east": Door("7a_e-10b_east", "7a_e-10b", DoorDirection.right, False, False), + + "7a_e-13_bottom": Door("7a_e-13_bottom", "7a_e-13", DoorDirection.left, False, False), + "7a_e-13_top": Door("7a_e-13_top", "7a_e-13", DoorDirection.up, False, False), + + "7a_f-00_south": Door("7a_f-00_south", "7a_f-00", DoorDirection.down, False, True), + "7a_f-00_west": Door("7a_f-00_west", "7a_f-00", DoorDirection.left, True, False), + "7a_f-00_north-west": Door("7a_f-00_north-west", "7a_f-00", DoorDirection.left, False, True), + "7a_f-00_east": Door("7a_f-00_east", "7a_f-00", DoorDirection.right, False, False), + "7a_f-00_north-east": Door("7a_f-00_north-east", "7a_f-00", DoorDirection.right, False, False), + + "7a_f-01_south": Door("7a_f-01_south", "7a_f-01", DoorDirection.right, False, False), + "7a_f-01_north": Door("7a_f-01_north", "7a_f-01", DoorDirection.right, True, False), + + "7a_f-02_west": Door("7a_f-02_west", "7a_f-02", DoorDirection.left, True, False), + "7a_f-02_north-west": Door("7a_f-02_north-west", "7a_f-02", DoorDirection.left, False, True), + "7a_f-02_east": Door("7a_f-02_east", "7a_f-02", DoorDirection.right, False, False), + "7a_f-02_north-east": Door("7a_f-02_north-east", "7a_f-02", DoorDirection.up, False, False), + + "7a_f-02b_west": Door("7a_f-02b_west", "7a_f-02b", DoorDirection.down, False, False), + "7a_f-02b_east": Door("7a_f-02b_east", "7a_f-02b", DoorDirection.right, False, False), + + "7a_f-04_west": Door("7a_f-04_west", "7a_f-04", DoorDirection.left, False, False), + "7a_f-04_east": Door("7a_f-04_east", "7a_f-04", DoorDirection.right, False, False), + + "7a_f-03_west": Door("7a_f-03_west", "7a_f-03", DoorDirection.left, False, False), + "7a_f-03_east": Door("7a_f-03_east", "7a_f-03", DoorDirection.right, False, False), + + "7a_f-05_west": Door("7a_f-05_west", "7a_f-05", DoorDirection.left, False, False), + "7a_f-05_south-west": Door("7a_f-05_south-west", "7a_f-05", DoorDirection.down, False, True), + "7a_f-05_north-west": Door("7a_f-05_north-west", "7a_f-05", DoorDirection.up, False, False), + "7a_f-05_south": Door("7a_f-05_south", "7a_f-05", DoorDirection.down, False, False), + "7a_f-05_north": Door("7a_f-05_north", "7a_f-05", DoorDirection.up, False, False), + "7a_f-05_south-east": Door("7a_f-05_south-east", "7a_f-05", DoorDirection.down, False, True), + "7a_f-05_east": Door("7a_f-05_east", "7a_f-05", DoorDirection.right, False, False), + "7a_f-05_north-east": Door("7a_f-05_north-east", "7a_f-05", DoorDirection.up, False, False), + + "7a_f-06_north-west": Door("7a_f-06_north-west", "7a_f-06", DoorDirection.up, False, False), + "7a_f-06_north": Door("7a_f-06_north", "7a_f-06", DoorDirection.up, False, False), + "7a_f-06_north-east": Door("7a_f-06_north-east", "7a_f-06", DoorDirection.up, False, False), + + "7a_f-07_west": Door("7a_f-07_west", "7a_f-07", DoorDirection.left, False, True), + "7a_f-07_south-west": Door("7a_f-07_south-west", "7a_f-07", DoorDirection.down, False, True), + "7a_f-07_south": Door("7a_f-07_south", "7a_f-07", DoorDirection.down, False, False), + "7a_f-07_south-east": Door("7a_f-07_south-east", "7a_f-07", DoorDirection.down, False, True), + + "7a_f-08_west": Door("7a_f-08_west", "7a_f-08", DoorDirection.left, False, False), + "7a_f-08_north-west": Door("7a_f-08_north-west", "7a_f-08", DoorDirection.up, True, False), + "7a_f-08_east": Door("7a_f-08_east", "7a_f-08", DoorDirection.right, False, False), + + "7a_f-08b_west": Door("7a_f-08b_west", "7a_f-08b", DoorDirection.down, False, False), + "7a_f-08b_east": Door("7a_f-08b_east", "7a_f-08b", DoorDirection.right, False, False), + + "7a_f-08d_west": Door("7a_f-08d_west", "7a_f-08d", DoorDirection.left, False, False), + "7a_f-08d_east": Door("7a_f-08d_east", "7a_f-08d", DoorDirection.right, False, False), + + "7a_f-08c_west": Door("7a_f-08c_west", "7a_f-08c", DoorDirection.left, False, False), + "7a_f-08c_east": Door("7a_f-08c_east", "7a_f-08c", DoorDirection.down, False, False), + + "7a_f-09_west": Door("7a_f-09_west", "7a_f-09", DoorDirection.left, False, False), + "7a_f-09_east": Door("7a_f-09_east", "7a_f-09", DoorDirection.right, False, False), + + "7a_f-10_west": Door("7a_f-10_west", "7a_f-10", DoorDirection.left, False, False), + "7a_f-10_north-east": Door("7a_f-10_north-east", "7a_f-10", DoorDirection.up, False, True), + "7a_f-10_east": Door("7a_f-10_east", "7a_f-10", DoorDirection.right, False, False), + + "7a_f-10b_west": Door("7a_f-10b_west", "7a_f-10b", DoorDirection.left, False, False), + "7a_f-10b_east": Door("7a_f-10b_east", "7a_f-10b", DoorDirection.right, False, False), + + "7a_f-11_bottom": Door("7a_f-11_bottom", "7a_f-11", DoorDirection.left, False, False), + "7a_f-11_top": Door("7a_f-11_top", "7a_f-11", DoorDirection.up, False, False), + + "7a_g-00_bottom": Door("7a_g-00_bottom", "7a_g-00", DoorDirection.down, False, True), + "7a_g-00_top": Door("7a_g-00_top", "7a_g-00", DoorDirection.up, False, False), + + "7a_g-00b_bottom": Door("7a_g-00b_bottom", "7a_g-00b", DoorDirection.down, False, True), + "7a_g-00b_top": Door("7a_g-00b_top", "7a_g-00b", DoorDirection.up, False, False), + + "7a_g-01_bottom": Door("7a_g-01_bottom", "7a_g-01", DoorDirection.down, False, True), + "7a_g-01_top": Door("7a_g-01_top", "7a_g-01", DoorDirection.up, False, False), + + "7a_g-02_bottom": Door("7a_g-02_bottom", "7a_g-02", DoorDirection.down, False, True), + "7a_g-02_top": Door("7a_g-02_top", "7a_g-02", DoorDirection.up, False, False), + + "7a_g-03_bottom": Door("7a_g-03_bottom", "7a_g-03", DoorDirection.down, False, True), + + "7b_a-00_east": Door("7b_a-00_east", "7b_a-00", DoorDirection.right, False, False), + + "7b_a-01_west": Door("7b_a-01_west", "7b_a-01", DoorDirection.left, False, False), + "7b_a-01_east": Door("7b_a-01_east", "7b_a-01", DoorDirection.right, False, False), + + "7b_a-02_west": Door("7b_a-02_west", "7b_a-02", DoorDirection.left, False, False), + "7b_a-02_east": Door("7b_a-02_east", "7b_a-02", DoorDirection.right, False, False), + + "7b_a-03_bottom": Door("7b_a-03_bottom", "7b_a-03", DoorDirection.left, False, True), + "7b_a-03_top": Door("7b_a-03_top", "7b_a-03", DoorDirection.up, False, False), + + "7b_b-00_bottom": Door("7b_b-00_bottom", "7b_b-00", DoorDirection.down, False, True), + "7b_b-00_top": Door("7b_b-00_top", "7b_b-00", DoorDirection.up, False, False), + + "7b_b-01_bottom": Door("7b_b-01_bottom", "7b_b-01", DoorDirection.down, False, True), + "7b_b-01_top": Door("7b_b-01_top", "7b_b-01", DoorDirection.up, False, False), + + "7b_b-02_west": Door("7b_b-02_west", "7b_b-02", DoorDirection.down, False, True), + "7b_b-02_east": Door("7b_b-02_east", "7b_b-02", DoorDirection.right, False, False), + + "7b_b-03_bottom": Door("7b_b-03_bottom", "7b_b-03", DoorDirection.left, False, False), + "7b_b-03_top": Door("7b_b-03_top", "7b_b-03", DoorDirection.up, False, False), + + "7b_c-01_west": Door("7b_c-01_west", "7b_c-01", DoorDirection.down, False, True), + "7b_c-01_east": Door("7b_c-01_east", "7b_c-01", DoorDirection.up, False, False), + + "7b_c-00_west": Door("7b_c-00_west", "7b_c-00", DoorDirection.down, False, True), + "7b_c-00_east": Door("7b_c-00_east", "7b_c-00", DoorDirection.up, False, False), + + "7b_c-02_west": Door("7b_c-02_west", "7b_c-02", DoorDirection.down, False, True), + "7b_c-02_east": Door("7b_c-02_east", "7b_c-02", DoorDirection.right, False, False), + + "7b_c-03_bottom": Door("7b_c-03_bottom", "7b_c-03", DoorDirection.left, False, True), + "7b_c-03_top": Door("7b_c-03_top", "7b_c-03", DoorDirection.up, False, False), + + "7b_d-00_west": Door("7b_d-00_west", "7b_d-00", DoorDirection.down, False, True), + "7b_d-00_east": Door("7b_d-00_east", "7b_d-00", DoorDirection.right, False, False), + + "7b_d-01_west": Door("7b_d-01_west", "7b_d-01", DoorDirection.left, False, False), + "7b_d-01_east": Door("7b_d-01_east", "7b_d-01", DoorDirection.right, False, False), + + "7b_d-02_west": Door("7b_d-02_west", "7b_d-02", DoorDirection.left, False, False), + "7b_d-02_east": Door("7b_d-02_east", "7b_d-02", DoorDirection.right, False, False), + + "7b_d-03_bottom": Door("7b_d-03_bottom", "7b_d-03", DoorDirection.left, False, False), + "7b_d-03_top": Door("7b_d-03_top", "7b_d-03", DoorDirection.up, False, False), + + "7b_e-00_west": Door("7b_e-00_west", "7b_e-00", DoorDirection.down, False, True), + "7b_e-00_east": Door("7b_e-00_east", "7b_e-00", DoorDirection.up, False, False), + + "7b_e-01_west": Door("7b_e-01_west", "7b_e-01", DoorDirection.down, False, True), + "7b_e-01_east": Door("7b_e-01_east", "7b_e-01", DoorDirection.up, False, False), + + "7b_e-02_west": Door("7b_e-02_west", "7b_e-02", DoorDirection.down, False, True), + "7b_e-02_east": Door("7b_e-02_east", "7b_e-02", DoorDirection.right, False, False), + + "7b_e-03_bottom": Door("7b_e-03_bottom", "7b_e-03", DoorDirection.left, False, False), + "7b_e-03_top": Door("7b_e-03_top", "7b_e-03", DoorDirection.up, False, False), + + "7b_f-00_west": Door("7b_f-00_west", "7b_f-00", DoorDirection.down, False, True), + "7b_f-00_east": Door("7b_f-00_east", "7b_f-00", DoorDirection.right, False, False), + + "7b_f-01_west": Door("7b_f-01_west", "7b_f-01", DoorDirection.left, False, False), + "7b_f-01_east": Door("7b_f-01_east", "7b_f-01", DoorDirection.right, False, False), + + "7b_f-02_west": Door("7b_f-02_west", "7b_f-02", DoorDirection.left, False, False), + "7b_f-02_east": Door("7b_f-02_east", "7b_f-02", DoorDirection.right, False, False), + + "7b_f-03_bottom": Door("7b_f-03_bottom", "7b_f-03", DoorDirection.left, False, False), + "7b_f-03_top": Door("7b_f-03_top", "7b_f-03", DoorDirection.up, False, False), + + "7b_g-00_bottom": Door("7b_g-00_bottom", "7b_g-00", DoorDirection.down, False, True), + "7b_g-00_top": Door("7b_g-00_top", "7b_g-00", DoorDirection.up, False, False), + + "7b_g-01_bottom": Door("7b_g-01_bottom", "7b_g-01", DoorDirection.down, False, True), + "7b_g-01_top": Door("7b_g-01_top", "7b_g-01", DoorDirection.up, False, False), + + "7b_g-02_bottom": Door("7b_g-02_bottom", "7b_g-02", DoorDirection.down, False, True), + "7b_g-02_top": Door("7b_g-02_top", "7b_g-02", DoorDirection.up, False, False), + + "7b_g-03_bottom": Door("7b_g-03_bottom", "7b_g-03", DoorDirection.down, False, True), + + "7c_01_east": Door("7c_01_east", "7c_01", DoorDirection.up, False, False), + + "7c_02_west": Door("7c_02_west", "7c_02", DoorDirection.down, False, True), + "7c_02_east": Door("7c_02_east", "7c_02", DoorDirection.up, False, False), + + "7c_03_west": Door("7c_03_west", "7c_03", DoorDirection.down, False, True), + + "8a_outside_east": Door("8a_outside_east", "8a_outside", DoorDirection.right, False, False), + + "8a_bridge_west": Door("8a_bridge_west", "8a_bridge", DoorDirection.left, False, False), + "8a_bridge_east": Door("8a_bridge_east", "8a_bridge", DoorDirection.right, False, False), + + "8a_secret_west": Door("8a_secret_west", "8a_secret", DoorDirection.left, False, False), + + "9a_00_east": Door("9a_00_east", "9a_00", DoorDirection.right, False, False), + "9a_00_west": Door("9a_00_west", "9a_00", DoorDirection.left, False, False), + + "9a_0x_east": Door("9a_0x_east", "9a_0x", DoorDirection.right, False, False), + + "9a_01_west": Door("9a_01_west", "9a_01", DoorDirection.left, False, False), + "9a_01_east": Door("9a_01_east", "9a_01", DoorDirection.right, False, False), + + "9a_02_west": Door("9a_02_west", "9a_02", DoorDirection.left, False, False), + "9a_02_east": Door("9a_02_east", "9a_02", DoorDirection.right, False, False), + + "9a_a-00_west": Door("9a_a-00_west", "9a_a-00", DoorDirection.left, False, True), + "9a_a-00_east": Door("9a_a-00_east", "9a_a-00", DoorDirection.right, False, False), + + "9a_a-01_west": Door("9a_a-01_west", "9a_a-01", DoorDirection.left, False, False), + "9a_a-01_east": Door("9a_a-01_east", "9a_a-01", DoorDirection.right, False, False), + + "9a_a-02_west": Door("9a_a-02_west", "9a_a-02", DoorDirection.left, False, False), + "9a_a-02_east": Door("9a_a-02_east", "9a_a-02", DoorDirection.up, False, False), + + "9a_a-03_bottom": Door("9a_a-03_bottom", "9a_a-03", DoorDirection.down, False, True), + "9a_a-03_top": Door("9a_a-03_top", "9a_a-03", DoorDirection.up, False, False), + + "9a_b-00_west": Door("9a_b-00_west", "9a_b-00", DoorDirection.left, False, False), + "9a_b-00_south": Door("9a_b-00_south", "9a_b-00", DoorDirection.down, False, True), + "9a_b-00_north": Door("9a_b-00_north", "9a_b-00", DoorDirection.up, False, False), + "9a_b-00_east": Door("9a_b-00_east", "9a_b-00", DoorDirection.right, False, False), + + "9a_b-01_west": Door("9a_b-01_west", "9a_b-01", DoorDirection.left, False, False), + "9a_b-01_east": Door("9a_b-01_east", "9a_b-01", DoorDirection.right, False, False), + + "9a_b-02_west": Door("9a_b-02_west", "9a_b-02", DoorDirection.left, False, False), + "9a_b-02_east": Door("9a_b-02_east", "9a_b-02", DoorDirection.right, False, False), + + "9a_b-03_west": Door("9a_b-03_west", "9a_b-03", DoorDirection.left, False, False), + "9a_b-03_east": Door("9a_b-03_east", "9a_b-03", DoorDirection.right, False, False), + + "9a_b-04_north-west": Door("9a_b-04_north-west", "9a_b-04", DoorDirection.up, False, False), + "9a_b-04_west": Door("9a_b-04_west", "9a_b-04", DoorDirection.left, False, False), + "9a_b-04_east": Door("9a_b-04_east", "9a_b-04", DoorDirection.up, False, False), + + "9a_b-05_west": Door("9a_b-05_west", "9a_b-05", DoorDirection.down, False, False), + "9a_b-05_east": Door("9a_b-05_east", "9a_b-05", DoorDirection.down, False, True), + + "9a_b-06_east": Door("9a_b-06_east", "9a_b-06", DoorDirection.right, False, False), + + "9a_b-07b_bottom": Door("9a_b-07b_bottom", "9a_b-07b", DoorDirection.down, False, True), + "9a_b-07b_top": Door("9a_b-07b_top", "9a_b-07b", DoorDirection.up, False, False), + + "9a_b-07_bottom": Door("9a_b-07_bottom", "9a_b-07", DoorDirection.down, False, True), + "9a_b-07_top": Door("9a_b-07_top", "9a_b-07", DoorDirection.up, False, False), + + "9a_c-00_west": Door("9a_c-00_west", "9a_c-00", DoorDirection.down, False, True), + "9a_c-00_north-east": Door("9a_c-00_north-east", "9a_c-00", DoorDirection.up, False, False), + "9a_c-00_east": Door("9a_c-00_east", "9a_c-00", DoorDirection.right, False, False), + + "9a_c-00b_west": Door("9a_c-00b_west", "9a_c-00b", DoorDirection.down, False, False), + + "9a_c-01_west": Door("9a_c-01_west", "9a_c-01", DoorDirection.left, False, False), + "9a_c-01_east": Door("9a_c-01_east", "9a_c-01", DoorDirection.right, False, False), + + "9a_c-02_west": Door("9a_c-02_west", "9a_c-02", DoorDirection.left, False, False), + "9a_c-02_east": Door("9a_c-02_east", "9a_c-02", DoorDirection.right, False, False), + + "9a_c-03_west": Door("9a_c-03_west", "9a_c-03", DoorDirection.left, False, False), + "9a_c-03_north-west": Door("9a_c-03_north-west", "9a_c-03", DoorDirection.up, False, True), + "9a_c-03_north": Door("9a_c-03_north", "9a_c-03", DoorDirection.up, False, False), + "9a_c-03_north-east": Door("9a_c-03_north-east", "9a_c-03", DoorDirection.up, False, True), + "9a_c-03_east": Door("9a_c-03_east", "9a_c-03", DoorDirection.right, False, False), + + "9a_c-03b_west": Door("9a_c-03b_west", "9a_c-03b", DoorDirection.down, False, False), + "9a_c-03b_south": Door("9a_c-03b_south", "9a_c-03b", DoorDirection.down, False, False), + "9a_c-03b_east": Door("9a_c-03b_east", "9a_c-03b", DoorDirection.down, False, False), + + "9a_c-04_west": Door("9a_c-04_west", "9a_c-04", DoorDirection.left, False, False), + "9a_c-04_east": Door("9a_c-04_east", "9a_c-04", DoorDirection.right, False, False), + + "9a_d-00_bottom": Door("9a_d-00_bottom", "9a_d-00", DoorDirection.left, False, True), + "9a_d-00_top": Door("9a_d-00_top", "9a_d-00", DoorDirection.up, False, False), + + "9a_d-01_bottom": Door("9a_d-01_bottom", "9a_d-01", DoorDirection.down, False, True), + "9a_d-01_top": Door("9a_d-01_top", "9a_d-01", DoorDirection.up, False, False), + + "9a_d-02_bottom": Door("9a_d-02_bottom", "9a_d-02", DoorDirection.down, False, True), + "9a_d-02_top": Door("9a_d-02_top", "9a_d-02", DoorDirection.up, False, False), + + "9a_d-03_bottom": Door("9a_d-03_bottom", "9a_d-03", DoorDirection.down, False, True), + "9a_d-03_top": Door("9a_d-03_top", "9a_d-03", DoorDirection.up, False, False), + + "9a_d-04_bottom": Door("9a_d-04_bottom", "9a_d-04", DoorDirection.down, False, True), + "9a_d-04_top": Door("9a_d-04_top", "9a_d-04", DoorDirection.up, False, False), + + "9a_d-05_bottom": Door("9a_d-05_bottom", "9a_d-05", DoorDirection.down, False, True), + "9a_d-05_top": Door("9a_d-05_top", "9a_d-05", DoorDirection.up, False, False), + + "9a_d-06_bottom": Door("9a_d-06_bottom", "9a_d-06", DoorDirection.down, False, True), + "9a_d-06_top": Door("9a_d-06_top", "9a_d-06", DoorDirection.up, False, False), + + "9a_d-07_bottom": Door("9a_d-07_bottom", "9a_d-07", DoorDirection.down, False, True), + "9a_d-07_top": Door("9a_d-07_top", "9a_d-07", DoorDirection.up, False, False), + + "9a_d-08_west": Door("9a_d-08_west", "9a_d-08", DoorDirection.down, False, True), + "9a_d-08_east": Door("9a_d-08_east", "9a_d-08", DoorDirection.right, False, False), + + "9a_d-09_west": Door("9a_d-09_west", "9a_d-09", DoorDirection.left, False, True), + "9a_d-09_east": Door("9a_d-09_east", "9a_d-09", DoorDirection.right, False, False), + + "9a_d-10_west": Door("9a_d-10_west", "9a_d-10", DoorDirection.left, False, True), + "9a_d-10_east": Door("9a_d-10_east", "9a_d-10", DoorDirection.right, False, False), + + "9a_d-10b_west": Door("9a_d-10b_west", "9a_d-10b", DoorDirection.left, False, True), + "9a_d-10b_east": Door("9a_d-10b_east", "9a_d-10b", DoorDirection.right, False, False), + + "9a_d-10c_west": Door("9a_d-10c_west", "9a_d-10c", DoorDirection.left, False, True), + "9a_d-10c_east": Door("9a_d-10c_east", "9a_d-10c", DoorDirection.right, False, False), + + "9a_d-11_west": Door("9a_d-11_west", "9a_d-11", DoorDirection.left, False, True), + "9a_d-11_east": Door("9a_d-11_east", "9a_d-11", DoorDirection.right, False, False), + + "9a_space_west": Door("9a_space_west", "9a_space", DoorDirection.left, False, True), + + "9b_00_east": Door("9b_00_east", "9b_00", DoorDirection.right, False, False), + + "9b_01_west": Door("9b_01_west", "9b_01", DoorDirection.left, False, False), + "9b_01_east": Door("9b_01_east", "9b_01", DoorDirection.right, False, False), + + "9b_a-00_west": Door("9b_a-00_west", "9b_a-00", DoorDirection.left, False, True), + "9b_a-00_east": Door("9b_a-00_east", "9b_a-00", DoorDirection.right, False, False), + + "9b_a-01_west": Door("9b_a-01_west", "9b_a-01", DoorDirection.left, False, False), + "9b_a-01_east": Door("9b_a-01_east", "9b_a-01", DoorDirection.right, False, False), + + "9b_a-02_west": Door("9b_a-02_west", "9b_a-02", DoorDirection.left, False, False), + "9b_a-02_east": Door("9b_a-02_east", "9b_a-02", DoorDirection.up, False, False), + + "9b_a-03_west": Door("9b_a-03_west", "9b_a-03", DoorDirection.down, False, True), + "9b_a-03_east": Door("9b_a-03_east", "9b_a-03", DoorDirection.right, False, False), + + "9b_a-04_west": Door("9b_a-04_west", "9b_a-04", DoorDirection.left, False, False), + "9b_a-04_east": Door("9b_a-04_east", "9b_a-04", DoorDirection.right, False, False), + + "9b_a-05_west": Door("9b_a-05_west", "9b_a-05", DoorDirection.left, False, False), + "9b_a-05_east": Door("9b_a-05_east", "9b_a-05", DoorDirection.up, False, False), + + "9b_b-00_west": Door("9b_b-00_west", "9b_b-00", DoorDirection.down, False, True), + "9b_b-00_east": Door("9b_b-00_east", "9b_b-00", DoorDirection.right, False, False), + + "9b_b-01_west": Door("9b_b-01_west", "9b_b-01", DoorDirection.left, False, False), + "9b_b-01_east": Door("9b_b-01_east", "9b_b-01", DoorDirection.right, False, False), + + "9b_b-02_west": Door("9b_b-02_west", "9b_b-02", DoorDirection.left, False, False), + "9b_b-02_east": Door("9b_b-02_east", "9b_b-02", DoorDirection.right, False, False), + + "9b_b-03_west": Door("9b_b-03_west", "9b_b-03", DoorDirection.left, False, False), + "9b_b-03_east": Door("9b_b-03_east", "9b_b-03", DoorDirection.right, False, False), + + "9b_b-04_west": Door("9b_b-04_west", "9b_b-04", DoorDirection.left, False, False), + "9b_b-04_east": Door("9b_b-04_east", "9b_b-04", DoorDirection.right, False, False), + + "9b_b-05_west": Door("9b_b-05_west", "9b_b-05", DoorDirection.left, False, False), + "9b_b-05_east": Door("9b_b-05_east", "9b_b-05", DoorDirection.right, False, False), + + "9b_c-01_bottom": Door("9b_c-01_bottom", "9b_c-01", DoorDirection.left, False, True), + "9b_c-01_top": Door("9b_c-01_top", "9b_c-01", DoorDirection.up, False, False), + + "9b_c-02_bottom": Door("9b_c-02_bottom", "9b_c-02", DoorDirection.down, False, True), + "9b_c-02_top": Door("9b_c-02_top", "9b_c-02", DoorDirection.up, False, False), + + "9b_c-03_bottom": Door("9b_c-03_bottom", "9b_c-03", DoorDirection.down, False, True), + "9b_c-03_top": Door("9b_c-03_top", "9b_c-03", DoorDirection.up, False, False), + + "9b_c-04_bottom": Door("9b_c-04_bottom", "9b_c-04", DoorDirection.down, False, True), + "9b_c-04_top": Door("9b_c-04_top", "9b_c-04", DoorDirection.up, False, False), + + "9b_c-05_west": Door("9b_c-05_west", "9b_c-05", DoorDirection.down, False, True), + "9b_c-05_east": Door("9b_c-05_east", "9b_c-05", DoorDirection.right, False, False), + + "9b_c-06_west": Door("9b_c-06_west", "9b_c-06", DoorDirection.left, False, False), + "9b_c-06_east": Door("9b_c-06_east", "9b_c-06", DoorDirection.right, False, False), + + "9b_c-08_west": Door("9b_c-08_west", "9b_c-08", DoorDirection.left, False, False), + "9b_c-08_east": Door("9b_c-08_east", "9b_c-08", DoorDirection.right, False, False), + + "9b_c-07_west": Door("9b_c-07_west", "9b_c-07", DoorDirection.left, False, False), + "9b_c-07_east": Door("9b_c-07_east", "9b_c-07", DoorDirection.right, False, False), + + "9b_space_west": Door("9b_space_west", "9b_space", DoorDirection.left, False, True), + + "9c_intro_east": Door("9c_intro_east", "9c_intro", DoorDirection.right, False, False), + + "9c_00_west": Door("9c_00_west", "9c_00", DoorDirection.left, False, False), + "9c_00_east": Door("9c_00_east", "9c_00", DoorDirection.right, False, False), + + "9c_01_west": Door("9c_01_west", "9c_01", DoorDirection.left, False, True), + "9c_01_east": Door("9c_01_east", "9c_01", DoorDirection.right, False, False), + + "9c_02_west": Door("9c_02_west", "9c_02", DoorDirection.left, False, True), + + "10a_intro-00-past_east": Door("10a_intro-00-past_east", "10a_intro-00-past", DoorDirection.special, False, False), + + "10a_intro-01-future_west": Door("10a_intro-01-future_west", "10a_intro-01-future", DoorDirection.special, False, True), + "10a_intro-01-future_east": Door("10a_intro-01-future_east", "10a_intro-01-future", DoorDirection.up, False, False), + + "10a_intro-02-launch_bottom": Door("10a_intro-02-launch_bottom", "10a_intro-02-launch", DoorDirection.down, False, True), + "10a_intro-02-launch_top": Door("10a_intro-02-launch_top", "10a_intro-02-launch", DoorDirection.up, False, False), + + "10a_intro-03-space_west": Door("10a_intro-03-space_west", "10a_intro-03-space", DoorDirection.down, False, True), + "10a_intro-03-space_east": Door("10a_intro-03-space_east", "10a_intro-03-space", DoorDirection.right, False, False), + + "10a_a-00_west": Door("10a_a-00_west", "10a_a-00", DoorDirection.left, False, False), + "10a_a-00_east": Door("10a_a-00_east", "10a_a-00", DoorDirection.right, False, False), + + "10a_a-01_west": Door("10a_a-01_west", "10a_a-01", DoorDirection.left, False, False), + "10a_a-01_east": Door("10a_a-01_east", "10a_a-01", DoorDirection.right, False, False), + + "10a_a-02_west": Door("10a_a-02_west", "10a_a-02", DoorDirection.left, False, False), + "10a_a-02_east": Door("10a_a-02_east", "10a_a-02", DoorDirection.right, False, False), + + "10a_a-03_west": Door("10a_a-03_west", "10a_a-03", DoorDirection.left, False, False), + "10a_a-03_east": Door("10a_a-03_east", "10a_a-03", DoorDirection.right, False, False), + + "10a_a-04_west": Door("10a_a-04_west", "10a_a-04", DoorDirection.left, False, False), + "10a_a-04_east": Door("10a_a-04_east", "10a_a-04", DoorDirection.right, False, False), + + "10a_a-05_west": Door("10a_a-05_west", "10a_a-05", DoorDirection.left, False, False), + "10a_a-05_east": Door("10a_a-05_east", "10a_a-05", DoorDirection.right, False, False), + + "10a_b-00_west": Door("10a_b-00_west", "10a_b-00", DoorDirection.left, False, False), + "10a_b-00_east": Door("10a_b-00_east", "10a_b-00", DoorDirection.right, False, False), + + "10a_b-01_west": Door("10a_b-01_west", "10a_b-01", DoorDirection.left, False, False), + "10a_b-01_east": Door("10a_b-01_east", "10a_b-01", DoorDirection.right, False, False), + + "10a_b-02_west": Door("10a_b-02_west", "10a_b-02", DoorDirection.left, False, False), + "10a_b-02_east": Door("10a_b-02_east", "10a_b-02", DoorDirection.right, False, False), + + "10a_b-03_west": Door("10a_b-03_west", "10a_b-03", DoorDirection.left, False, False), + "10a_b-03_east": Door("10a_b-03_east", "10a_b-03", DoorDirection.right, False, False), + + "10a_b-04_west": Door("10a_b-04_west", "10a_b-04", DoorDirection.left, False, False), + "10a_b-04_east": Door("10a_b-04_east", "10a_b-04", DoorDirection.right, False, False), + + "10a_b-05_west": Door("10a_b-05_west", "10a_b-05", DoorDirection.left, False, False), + "10a_b-05_east": Door("10a_b-05_east", "10a_b-05", DoorDirection.right, False, False), + + "10a_b-06_west": Door("10a_b-06_west", "10a_b-06", DoorDirection.left, False, False), + "10a_b-06_east": Door("10a_b-06_east", "10a_b-06", DoorDirection.right, False, False), + + "10a_b-07_west": Door("10a_b-07_west", "10a_b-07", DoorDirection.left, False, False), + "10a_b-07_east": Door("10a_b-07_east", "10a_b-07", DoorDirection.right, False, False), + + "10a_c-00_west": Door("10a_c-00_west", "10a_c-00", DoorDirection.left, False, False), + "10a_c-00_east": Door("10a_c-00_east", "10a_c-00", DoorDirection.right, False, False), + "10a_c-00_north-east": Door("10a_c-00_north-east", "10a_c-00", DoorDirection.right, False, False), + + "10a_c-00b_west": Door("10a_c-00b_west", "10a_c-00b", DoorDirection.left, False, False), + "10a_c-00b_east": Door("10a_c-00b_east", "10a_c-00b", DoorDirection.right, False, False), + + "10a_c-01_west": Door("10a_c-01_west", "10a_c-01", DoorDirection.left, False, False), + "10a_c-01_east": Door("10a_c-01_east", "10a_c-01", DoorDirection.right, False, False), + + "10a_c-02_west": Door("10a_c-02_west", "10a_c-02", DoorDirection.left, False, False), + "10a_c-02_east": Door("10a_c-02_east", "10a_c-02", DoorDirection.up, False, False), + + "10a_c-alt-00_west": Door("10a_c-alt-00_west", "10a_c-alt-00", DoorDirection.left, False, False), + "10a_c-alt-00_east": Door("10a_c-alt-00_east", "10a_c-alt-00", DoorDirection.right, False, False), + + "10a_c-alt-01_west": Door("10a_c-alt-01_west", "10a_c-alt-01", DoorDirection.left, False, False), + "10a_c-alt-01_east": Door("10a_c-alt-01_east", "10a_c-alt-01", DoorDirection.right, False, False), + + "10a_c-03_south-west": Door("10a_c-03_south-west", "10a_c-03", DoorDirection.left, False, False), + "10a_c-03_south": Door("10a_c-03_south", "10a_c-03", DoorDirection.down, False, True), + "10a_c-03_north": Door("10a_c-03_north", "10a_c-03", DoorDirection.up, False, False), + + "10a_d-00_south": Door("10a_d-00_south", "10a_d-00", DoorDirection.down, False, True), + "10a_d-00_north": Door("10a_d-00_north", "10a_d-00", DoorDirection.up, False, False), + "10a_d-00_north-east-door": Door("10a_d-00_north-east-door", "10a_d-00", DoorDirection.right, False, False), + "10a_d-00_south-east-door": Door("10a_d-00_south-east-door", "10a_d-00", DoorDirection.right, False, False), + "10a_d-00_south-west-door": Door("10a_d-00_south-west-door", "10a_d-00", DoorDirection.left, False, False), + "10a_d-00_west-door": Door("10a_d-00_west-door", "10a_d-00", DoorDirection.up, False, False), + "10a_d-00_north-west-door": Door("10a_d-00_north-west-door", "10a_d-00", DoorDirection.up, False, False), + + "10a_d-04_west": Door("10a_d-04_west", "10a_d-04", DoorDirection.left, False, False), + + "10a_d-03_west": Door("10a_d-03_west", "10a_d-03", DoorDirection.left, False, False), + + "10a_d-01_east": Door("10a_d-01_east", "10a_d-01", DoorDirection.right, False, False), + + "10a_d-02_bottom": Door("10a_d-02_bottom", "10a_d-02", DoorDirection.down, False, False), + + "10a_d-05_west": Door("10a_d-05_west", "10a_d-05", DoorDirection.down, False, False), + "10a_d-05_south": Door("10a_d-05_south", "10a_d-05", DoorDirection.down, False, True), + "10a_d-05_north": Door("10a_d-05_north", "10a_d-05", DoorDirection.up, False, False), + + "10a_e-00y_south": Door("10a_e-00y_south", "10a_e-00y", DoorDirection.down, False, False), + "10a_e-00y_south-east": Door("10a_e-00y_south-east", "10a_e-00y", DoorDirection.right, False, False), + "10a_e-00y_north-east": Door("10a_e-00y_north-east", "10a_e-00y", DoorDirection.right, False, False), + "10a_e-00y_north": Door("10a_e-00y_north", "10a_e-00y", DoorDirection.up, False, False), + + "10a_e-00yb_south": Door("10a_e-00yb_south", "10a_e-00yb", DoorDirection.left, False, False), + "10a_e-00yb_north": Door("10a_e-00yb_north", "10a_e-00yb", DoorDirection.left, False, False), + + "10a_e-00z_south": Door("10a_e-00z_south", "10a_e-00z", DoorDirection.down, False, True), + "10a_e-00z_north": Door("10a_e-00z_north", "10a_e-00z", DoorDirection.up, False, False), + + "10a_e-00_south": Door("10a_e-00_south", "10a_e-00", DoorDirection.down, False, True), + "10a_e-00_north": Door("10a_e-00_north", "10a_e-00", DoorDirection.up, False, False), + + "10a_e-00b_south": Door("10a_e-00b_south", "10a_e-00b", DoorDirection.down, False, True), + "10a_e-00b_north": Door("10a_e-00b_north", "10a_e-00b", DoorDirection.up, False, False), + + "10a_e-01_south": Door("10a_e-01_south", "10a_e-01", DoorDirection.down, False, True), + "10a_e-01_north": Door("10a_e-01_north", "10a_e-01", DoorDirection.up, False, False), + + "10a_e-02_west": Door("10a_e-02_west", "10a_e-02", DoorDirection.down, False, True), + "10a_e-02_east": Door("10a_e-02_east", "10a_e-02", DoorDirection.right, False, False), + + "10a_e-03_west": Door("10a_e-03_west", "10a_e-03", DoorDirection.left, False, False), + "10a_e-03_east": Door("10a_e-03_east", "10a_e-03", DoorDirection.right, False, False), + + "10a_e-04_west": Door("10a_e-04_west", "10a_e-04", DoorDirection.left, False, False), + "10a_e-04_east": Door("10a_e-04_east", "10a_e-04", DoorDirection.right, False, False), + + "10a_e-05_west": Door("10a_e-05_west", "10a_e-05", DoorDirection.left, False, False), + "10a_e-05_east": Door("10a_e-05_east", "10a_e-05", DoorDirection.right, False, False), + + "10a_e-05b_west": Door("10a_e-05b_west", "10a_e-05b", DoorDirection.left, False, False), + "10a_e-05b_east": Door("10a_e-05b_east", "10a_e-05b", DoorDirection.right, False, False), + + "10a_e-05c_west": Door("10a_e-05c_west", "10a_e-05c", DoorDirection.left, False, False), + "10a_e-05c_east": Door("10a_e-05c_east", "10a_e-05c", DoorDirection.right, False, False), + + "10a_e-06_west": Door("10a_e-06_west", "10a_e-06", DoorDirection.left, False, False), + "10a_e-06_east": Door("10a_e-06_east", "10a_e-06", DoorDirection.right, False, False), + + "10a_e-07_west": Door("10a_e-07_west", "10a_e-07", DoorDirection.left, False, False), + "10a_e-07_east": Door("10a_e-07_east", "10a_e-07", DoorDirection.right, False, False), + + "10a_e-08_west": Door("10a_e-08_west", "10a_e-08", DoorDirection.left, False, False), + "10a_e-08_east": Door("10a_e-08_east", "10a_e-08", DoorDirection.right, False, False), + + "10b_f-door_west": Door("10b_f-door_west", "10b_f-door", DoorDirection.left, False, True), + "10b_f-door_east": Door("10b_f-door_east", "10b_f-door", DoorDirection.right, False, False), + + "10b_f-00_west": Door("10b_f-00_west", "10b_f-00", DoorDirection.left, False, False), + "10b_f-00_east": Door("10b_f-00_east", "10b_f-00", DoorDirection.right, False, False), + + "10b_f-01_west": Door("10b_f-01_west", "10b_f-01", DoorDirection.left, False, False), + "10b_f-01_east": Door("10b_f-01_east", "10b_f-01", DoorDirection.right, False, False), + + "10b_f-02_west": Door("10b_f-02_west", "10b_f-02", DoorDirection.left, False, False), + "10b_f-02_east": Door("10b_f-02_east", "10b_f-02", DoorDirection.right, False, False), + + "10b_f-03_west": Door("10b_f-03_west", "10b_f-03", DoorDirection.left, False, False), + "10b_f-03_east": Door("10b_f-03_east", "10b_f-03", DoorDirection.right, False, False), + + "10b_f-04_west": Door("10b_f-04_west", "10b_f-04", DoorDirection.left, False, False), + "10b_f-04_east": Door("10b_f-04_east", "10b_f-04", DoorDirection.right, False, False), + + "10b_f-05_west": Door("10b_f-05_west", "10b_f-05", DoorDirection.left, False, False), + "10b_f-05_east": Door("10b_f-05_east", "10b_f-05", DoorDirection.right, False, False), + + "10b_f-06_west": Door("10b_f-06_west", "10b_f-06", DoorDirection.left, False, False), + "10b_f-06_east": Door("10b_f-06_east", "10b_f-06", DoorDirection.right, False, False), + + "10b_f-07_west": Door("10b_f-07_west", "10b_f-07", DoorDirection.left, False, False), + "10b_f-07_east": Door("10b_f-07_east", "10b_f-07", DoorDirection.right, False, False), + + "10b_f-08_west": Door("10b_f-08_west", "10b_f-08", DoorDirection.left, False, False), + "10b_f-08_east": Door("10b_f-08_east", "10b_f-08", DoorDirection.right, False, False), + + "10b_f-09_west": Door("10b_f-09_west", "10b_f-09", DoorDirection.left, False, False), + "10b_f-09_east": Door("10b_f-09_east", "10b_f-09", DoorDirection.up, False, False), + + "10b_g-00_bottom": Door("10b_g-00_bottom", "10b_g-00", DoorDirection.down, False, True), + "10b_g-00_top": Door("10b_g-00_top", "10b_g-00", DoorDirection.up, False, False), + + "10b_g-01_bottom": Door("10b_g-01_bottom", "10b_g-01", DoorDirection.down, False, True), + "10b_g-01_top": Door("10b_g-01_top", "10b_g-01", DoorDirection.up, False, False), + + "10b_g-03_bottom": Door("10b_g-03_bottom", "10b_g-03", DoorDirection.down, False, True), + "10b_g-03_top": Door("10b_g-03_top", "10b_g-03", DoorDirection.up, False, False), + + "10b_g-02_west": Door("10b_g-02_west", "10b_g-02", DoorDirection.down, False, True), + "10b_g-02_east": Door("10b_g-02_east", "10b_g-02", DoorDirection.up, False, False), + + "10b_g-04_west": Door("10b_g-04_west", "10b_g-04", DoorDirection.down, False, True), + "10b_g-04_east": Door("10b_g-04_east", "10b_g-04", DoorDirection.right, False, False), + + "10b_g-05_west": Door("10b_g-05_west", "10b_g-05", DoorDirection.left, False, False), + "10b_g-05_east": Door("10b_g-05_east", "10b_g-05", DoorDirection.right, False, False), + + "10b_g-06_west": Door("10b_g-06_west", "10b_g-06", DoorDirection.left, False, False), + "10b_g-06_east": Door("10b_g-06_east", "10b_g-06", DoorDirection.right, False, False), + + "10b_h-00b_west": Door("10b_h-00b_west", "10b_h-00b", DoorDirection.left, False, False), + "10b_h-00b_east": Door("10b_h-00b_east", "10b_h-00b", DoorDirection.down, False, False), + + "10b_h-00_west": Door("10b_h-00_west", "10b_h-00", DoorDirection.up, False, False), + "10b_h-00_east": Door("10b_h-00_east", "10b_h-00", DoorDirection.right, False, False), + + "10b_h-01_west": Door("10b_h-01_west", "10b_h-01", DoorDirection.left, False, False), + "10b_h-01_east": Door("10b_h-01_east", "10b_h-01", DoorDirection.up, False, False), + + "10b_h-02_west": Door("10b_h-02_west", "10b_h-02", DoorDirection.down, False, True), + "10b_h-02_east": Door("10b_h-02_east", "10b_h-02", DoorDirection.right, False, False), + + "10b_h-03_west": Door("10b_h-03_west", "10b_h-03", DoorDirection.left, False, False), + "10b_h-03_east": Door("10b_h-03_east", "10b_h-03", DoorDirection.right, False, False), + + "10b_h-03b_west": Door("10b_h-03b_west", "10b_h-03b", DoorDirection.left, False, False), + "10b_h-03b_east": Door("10b_h-03b_east", "10b_h-03b", DoorDirection.right, False, False), + + "10b_h-04_top": Door("10b_h-04_top", "10b_h-04", DoorDirection.left, False, False), + "10b_h-04_east": Door("10b_h-04_east", "10b_h-04", DoorDirection.right, False, False), + "10b_h-04_bottom": Door("10b_h-04_bottom", "10b_h-04", DoorDirection.right, False, False), + + "10b_h-04b_west": Door("10b_h-04b_west", "10b_h-04b", DoorDirection.left, False, False), + "10b_h-04b_east": Door("10b_h-04b_east", "10b_h-04b", DoorDirection.down, False, False), + + "10b_h-05_west": Door("10b_h-05_west", "10b_h-05", DoorDirection.left, False, False), + "10b_h-05_top": Door("10b_h-05_top", "10b_h-05", DoorDirection.up, False, True), + "10b_h-05_east": Door("10b_h-05_east", "10b_h-05", DoorDirection.right, False, False), + + "10b_h-06_west": Door("10b_h-06_west", "10b_h-06", DoorDirection.left, False, False), + "10b_h-06_east": Door("10b_h-06_east", "10b_h-06", DoorDirection.up, False, False), + + "10b_h-06b_bottom": Door("10b_h-06b_bottom", "10b_h-06b", DoorDirection.down, False, True), + "10b_h-06b_top": Door("10b_h-06b_top", "10b_h-06b", DoorDirection.up, False, False), + + "10b_h-07_west": Door("10b_h-07_west", "10b_h-07", DoorDirection.down, False, True), + "10b_h-07_east": Door("10b_h-07_east", "10b_h-07", DoorDirection.right, False, False), + + "10b_h-08_west": Door("10b_h-08_west", "10b_h-08", DoorDirection.left, False, True), + "10b_h-08_east": Door("10b_h-08_east", "10b_h-08", DoorDirection.right, False, False), + + "10b_h-09_west": Door("10b_h-09_west", "10b_h-09", DoorDirection.left, False, False), + "10b_h-09_east": Door("10b_h-09_east", "10b_h-09", DoorDirection.right, False, False), + + "10b_h-10_west": Door("10b_h-10_west", "10b_h-10", DoorDirection.left, False, False), + "10b_h-10_east": Door("10b_h-10_east", "10b_h-10", DoorDirection.up, False, False), + + "10b_i-00_west": Door("10b_i-00_west", "10b_i-00", DoorDirection.down, False, True), + "10b_i-00_east": Door("10b_i-00_east", "10b_i-00", DoorDirection.right, False, False), + + "10b_i-00b_west": Door("10b_i-00b_west", "10b_i-00b", DoorDirection.left, False, False), + "10b_i-00b_east": Door("10b_i-00b_east", "10b_i-00b", DoorDirection.right, False, False), + + "10b_i-01_west": Door("10b_i-01_west", "10b_i-01", DoorDirection.left, False, False), + "10b_i-01_east": Door("10b_i-01_east", "10b_i-01", DoorDirection.right, False, False), + + "10b_i-02_west": Door("10b_i-02_west", "10b_i-02", DoorDirection.left, False, False), + "10b_i-02_east": Door("10b_i-02_east", "10b_i-02", DoorDirection.right, False, False), + + "10b_i-03_west": Door("10b_i-03_west", "10b_i-03", DoorDirection.left, False, False), + "10b_i-03_east": Door("10b_i-03_east", "10b_i-03", DoorDirection.right, False, False), + + "10b_i-04_west": Door("10b_i-04_west", "10b_i-04", DoorDirection.left, False, False), + "10b_i-04_east": Door("10b_i-04_east", "10b_i-04", DoorDirection.right, False, False), + + "10b_i-05_west": Door("10b_i-05_west", "10b_i-05", DoorDirection.left, False, False), + "10b_i-05_east": Door("10b_i-05_east", "10b_i-05", DoorDirection.right, False, False), + + "10b_j-00_west": Door("10b_j-00_west", "10b_j-00", DoorDirection.left, False, True), + "10b_j-00_east": Door("10b_j-00_east", "10b_j-00", DoorDirection.right, False, False), + + "10b_j-00b_west": Door("10b_j-00b_west", "10b_j-00b", DoorDirection.left, False, False), + "10b_j-00b_east": Door("10b_j-00b_east", "10b_j-00b", DoorDirection.right, False, False), + + "10b_j-01_west": Door("10b_j-01_west", "10b_j-01", DoorDirection.left, False, False), + "10b_j-01_east": Door("10b_j-01_east", "10b_j-01", DoorDirection.right, False, False), + + "10b_j-02_west": Door("10b_j-02_west", "10b_j-02", DoorDirection.left, False, False), + "10b_j-02_east": Door("10b_j-02_east", "10b_j-02", DoorDirection.right, False, False), + + "10b_j-03_west": Door("10b_j-03_west", "10b_j-03", DoorDirection.left, False, False), + "10b_j-03_east": Door("10b_j-03_east", "10b_j-03", DoorDirection.right, False, False), + + "10b_j-04_west": Door("10b_j-04_west", "10b_j-04", DoorDirection.left, False, False), + "10b_j-04_east": Door("10b_j-04_east", "10b_j-04", DoorDirection.right, False, False), + + "10b_j-05_west": Door("10b_j-05_west", "10b_j-05", DoorDirection.left, False, False), + "10b_j-05_east": Door("10b_j-05_east", "10b_j-05", DoorDirection.right, False, False), + + "10b_j-06_west": Door("10b_j-06_west", "10b_j-06", DoorDirection.left, False, False), + "10b_j-06_east": Door("10b_j-06_east", "10b_j-06", DoorDirection.right, False, False), + + "10b_j-07_west": Door("10b_j-07_west", "10b_j-07", DoorDirection.left, False, False), + "10b_j-07_east": Door("10b_j-07_east", "10b_j-07", DoorDirection.right, False, False), + + "10b_j-08_west": Door("10b_j-08_west", "10b_j-08", DoorDirection.left, False, False), + "10b_j-08_east": Door("10b_j-08_east", "10b_j-08", DoorDirection.right, False, False), + + "10b_j-09_west": Door("10b_j-09_west", "10b_j-09", DoorDirection.left, False, False), + "10b_j-09_east": Door("10b_j-09_east", "10b_j-09", DoorDirection.right, False, False), + + "10b_j-10_west": Door("10b_j-10_west", "10b_j-10", DoorDirection.left, False, False), + "10b_j-10_east": Door("10b_j-10_east", "10b_j-10", DoorDirection.right, False, False), + + "10b_j-11_west": Door("10b_j-11_west", "10b_j-11", DoorDirection.left, False, False), + "10b_j-11_east": Door("10b_j-11_east", "10b_j-11", DoorDirection.right, False, False), + + "10b_j-12_west": Door("10b_j-12_west", "10b_j-12", DoorDirection.left, False, False), + "10b_j-12_east": Door("10b_j-12_east", "10b_j-12", DoorDirection.right, False, False), + + "10b_j-13_west": Door("10b_j-13_west", "10b_j-13", DoorDirection.left, False, False), + "10b_j-13_east": Door("10b_j-13_east", "10b_j-13", DoorDirection.right, False, False), + + "10b_j-14_west": Door("10b_j-14_west", "10b_j-14", DoorDirection.left, False, False), + "10b_j-14_east": Door("10b_j-14_east", "10b_j-14", DoorDirection.right, False, False), + + "10b_j-14b_west": Door("10b_j-14b_west", "10b_j-14b", DoorDirection.left, False, False), + "10b_j-14b_east": Door("10b_j-14b_east", "10b_j-14b", DoorDirection.right, False, False), + + "10b_j-15_west": Door("10b_j-15_west", "10b_j-15", DoorDirection.left, False, False), + "10b_j-15_east": Door("10b_j-15_east", "10b_j-15", DoorDirection.right, False, False), + + "10b_j-16_west": Door("10b_j-16_west", "10b_j-16", DoorDirection.left, False, True), + "10b_j-16_top": Door("10b_j-16_top", "10b_j-16", DoorDirection.up, False, False), + "10b_j-16_east": Door("10b_j-16_east", "10b_j-16", DoorDirection.up, False, False), + + "10b_j-17_south": Door("10b_j-17_south", "10b_j-17", DoorDirection.down, False, True), + "10b_j-17_west": Door("10b_j-17_west", "10b_j-17", DoorDirection.up, False, False), + "10b_j-17_north": Door("10b_j-17_north", "10b_j-17", DoorDirection.up, False, False), + "10b_j-17_east": Door("10b_j-17_east", "10b_j-17", DoorDirection.right, False, False), + + "10b_j-18_west": Door("10b_j-18_west", "10b_j-18", DoorDirection.down, False, True), + "10b_j-18_east": Door("10b_j-18_east", "10b_j-18", DoorDirection.down, False, False), + + "10b_j-19_bottom": Door("10b_j-19_bottom", "10b_j-19", DoorDirection.left, False, False), + "10b_j-19_top": Door("10b_j-19_top", "10b_j-19", DoorDirection.up, False, False), + + "10b_GOAL_main": Door("10b_GOAL_main", "10b_GOAL", DoorDirection.down, False, True), + "10b_GOAL_moon": Door("10b_GOAL_moon", "10b_GOAL", DoorDirection.down, False, True), + + "10c_end-golden_bottom": Door("10c_end-golden_bottom", "10c_end-golden", DoorDirection.down, False, True), + "10c_end-golden_top": Door("10c_end-golden_top", "10c_end-golden", DoorDirection.up, False, True), + +} + +all_region_connections: dict[str, RegionConnection] = { + "0a_-1_main---0a_-1_east": RegionConnection("0a_-1_main", "0a_-1_east", []), + "0a_-1_east---0a_-1_main": RegionConnection("0a_-1_east", "0a_-1_main", []), + + "0a_0_west---0a_0_main": RegionConnection("0a_0_west", "0a_0_main", []), + "0a_0_main---0a_0_west": RegionConnection("0a_0_main", "0a_0_west", []), + "0a_0_main---0a_0_east": RegionConnection("0a_0_main", "0a_0_east", []), + "0a_0_main---0a_0_north": RegionConnection("0a_0_main", "0a_0_north", []), + "0a_0_north---0a_0_main": RegionConnection("0a_0_north", "0a_0_main", []), + "0a_0_east---0a_0_main": RegionConnection("0a_0_east", "0a_0_main", []), + + + "0a_1_west---0a_1_main": RegionConnection("0a_1_west", "0a_1_main", []), + "0a_1_main---0a_1_west": RegionConnection("0a_1_main", "0a_1_west", []), + "0a_1_main---0a_1_east": RegionConnection("0a_1_main", "0a_1_east", []), + "0a_1_east---0a_1_main": RegionConnection("0a_1_east", "0a_1_main", []), + + "0a_2_west---0a_2_main": RegionConnection("0a_2_west", "0a_2_main", []), + "0a_2_main---0a_2_west": RegionConnection("0a_2_main", "0a_2_west", []), + "0a_2_main---0a_2_east": RegionConnection("0a_2_main", "0a_2_east", []), + "0a_2_east---0a_2_main": RegionConnection("0a_2_east", "0a_2_main", []), + + "0a_3_west---0a_3_main": RegionConnection("0a_3_west", "0a_3_main", []), + "0a_3_main---0a_3_west": RegionConnection("0a_3_main", "0a_3_west", []), + "0a_3_main---0a_3_east": RegionConnection("0a_3_main", "0a_3_east", []), + "0a_3_east---0a_3_main": RegionConnection("0a_3_east", "0a_3_main", []), + + "1a_1_main---1a_1_east": RegionConnection("1a_1_main", "1a_1_east", []), + "1a_1_east---1a_1_main": RegionConnection("1a_1_east", "1a_1_main", []), + + "1a_2_west---1a_2_east": RegionConnection("1a_2_west", "1a_2_east", []), + "1a_2_east---1a_2_west": RegionConnection("1a_2_east", "1a_2_west", []), + + "1a_3_west---1a_3_east": RegionConnection("1a_3_west", "1a_3_east", []), + "1a_3_east---1a_3_west": RegionConnection("1a_3_east", "1a_3_west", []), + + "1a_4_west---1a_4_east": RegionConnection("1a_4_west", "1a_4_east", [[ItemName.traffic_blocks, ], ]), + "1a_4_east---1a_4_west": RegionConnection("1a_4_east", "1a_4_west", []), + + "1a_3b_west---1a_3b_east": RegionConnection("1a_3b_west", "1a_3b_east", []), + "1a_3b_east---1a_3b_west": RegionConnection("1a_3b_east", "1a_3b_west", []), + "1a_3b_east---1a_3b_top": RegionConnection("1a_3b_east", "1a_3b_top", []), + "1a_3b_top---1a_3b_west": RegionConnection("1a_3b_top", "1a_3b_west", []), + "1a_3b_top---1a_3b_east": RegionConnection("1a_3b_top", "1a_3b_east", []), + + "1a_5_bottom---1a_5_west": RegionConnection("1a_5_bottom", "1a_5_west", []), + "1a_5_bottom---1a_5_north-west": RegionConnection("1a_5_bottom", "1a_5_north-west", [[ItemName.traffic_blocks, ], ]), + "1a_5_bottom---1a_5_center": RegionConnection("1a_5_bottom", "1a_5_center", []), + "1a_5_west---1a_5_bottom": RegionConnection("1a_5_west", "1a_5_bottom", []), + "1a_5_north-west---1a_5_center": RegionConnection("1a_5_north-west", "1a_5_center", []), + "1a_5_north-west---1a_5_bottom": RegionConnection("1a_5_north-west", "1a_5_bottom", []), + "1a_5_center---1a_5_north-east": RegionConnection("1a_5_center", "1a_5_north-east", []), + "1a_5_center---1a_5_bottom": RegionConnection("1a_5_center", "1a_5_bottom", []), + "1a_5_center---1a_5_south-east": RegionConnection("1a_5_center", "1a_5_south-east", []), + "1a_5_south-east---1a_5_north-east": RegionConnection("1a_5_south-east", "1a_5_north-east", []), + "1a_5_south-east---1a_5_center": RegionConnection("1a_5_south-east", "1a_5_center", []), + "1a_5_north-east---1a_5_center": RegionConnection("1a_5_north-east", "1a_5_center", []), + "1a_5_north-east---1a_5_top": RegionConnection("1a_5_north-east", "1a_5_top", [[ItemName.springs, ], ]), + "1a_5_top---1a_5_north-east": RegionConnection("1a_5_top", "1a_5_north-east", []), + + + + "1a_6_south-west---1a_6_west": RegionConnection("1a_6_south-west", "1a_6_west", []), + "1a_6_west---1a_6_south-west": RegionConnection("1a_6_west", "1a_6_south-west", []), + "1a_6_west---1a_6_east": RegionConnection("1a_6_west", "1a_6_east", [[ItemName.dash_refills, ], ]), + "1a_6_east---1a_6_west": RegionConnection("1a_6_east", "1a_6_west", [[ItemName.cannot_access, ], ]), + + "1a_6z_north-west---1a_6z_west": RegionConnection("1a_6z_north-west", "1a_6z_west", []), + "1a_6z_west---1a_6z_north-west": RegionConnection("1a_6z_west", "1a_6z_north-west", []), + "1a_6z_west---1a_6z_east": RegionConnection("1a_6z_west", "1a_6z_east", []), + "1a_6z_east---1a_6z_west": RegionConnection("1a_6z_east", "1a_6z_west", [[ItemName.dash_refills, ], ]), + + "1a_6zb_north-west---1a_6zb_main": RegionConnection("1a_6zb_north-west", "1a_6zb_main", []), + "1a_6zb_main---1a_6zb_north-west": RegionConnection("1a_6zb_main", "1a_6zb_north-west", []), + "1a_6zb_main---1a_6zb_east": RegionConnection("1a_6zb_main", "1a_6zb_east", []), + "1a_6zb_east---1a_6zb_main": RegionConnection("1a_6zb_east", "1a_6zb_main", []), + + "1a_7zb_west---1a_7zb_east": RegionConnection("1a_7zb_west", "1a_7zb_east", [[ItemName.dash_refills, ], ]), + "1a_7zb_east---1a_7zb_west": RegionConnection("1a_7zb_east", "1a_7zb_west", [[ItemName.springs, ItemName.dash_refills, ], ]), + + "1a_6a_west---1a_6a_east": RegionConnection("1a_6a_west", "1a_6a_east", [[ItemName.dash_refills, ], ]), + "1a_6a_east---1a_6a_west": RegionConnection("1a_6a_east", "1a_6a_west", []), + + "1a_6b_south-west---1a_6b_north-west": RegionConnection("1a_6b_south-west", "1a_6b_north-west", [[ItemName.traffic_blocks, ], ]), + "1a_6b_south-west---1a_6b_north-east": RegionConnection("1a_6b_south-west", "1a_6b_north-east", [[ItemName.traffic_blocks, ], ]), + "1a_6b_north-west---1a_6b_south-west": RegionConnection("1a_6b_north-west", "1a_6b_south-west", []), + "1a_6b_north-east---1a_6b_south-west": RegionConnection("1a_6b_north-east", "1a_6b_south-west", []), + + "1a_s0_west---1a_s0_east": RegionConnection("1a_s0_west", "1a_s0_east", []), + "1a_s0_east---1a_s0_west": RegionConnection("1a_s0_east", "1a_s0_west", [[ItemName.traffic_blocks, ], ]), + + + "1a_6c_south-west---1a_6c_north-west": RegionConnection("1a_6c_south-west", "1a_6c_north-west", [[ItemName.springs, ], ]), + "1a_6c_south-west---1a_6c_north-east": RegionConnection("1a_6c_south-west", "1a_6c_north-east", [[ItemName.springs, ], ]), + "1a_6c_north-west---1a_6c_south-west": RegionConnection("1a_6c_north-west", "1a_6c_south-west", []), + "1a_6c_north-east---1a_6c_south-west": RegionConnection("1a_6c_north-east", "1a_6c_south-west", []), + + "1a_7_west---1a_7_east": RegionConnection("1a_7_west", "1a_7_east", []), + "1a_7_east---1a_7_west": RegionConnection("1a_7_east", "1a_7_west", []), + + "1a_7z_bottom---1a_7z_top": RegionConnection("1a_7z_bottom", "1a_7z_top", []), + "1a_7z_top---1a_7z_bottom": RegionConnection("1a_7z_top", "1a_7z_bottom", []), + + "1a_8z_bottom---1a_8z_top": RegionConnection("1a_8z_bottom", "1a_8z_top", [[ItemName.traffic_blocks, ], ]), + "1a_8z_top---1a_8z_bottom": RegionConnection("1a_8z_top", "1a_8z_bottom", []), + + "1a_8zb_west---1a_8zb_east": RegionConnection("1a_8zb_west", "1a_8zb_east", [[ItemName.dash_refills, ], ]), + "1a_8zb_east---1a_8zb_west": RegionConnection("1a_8zb_east", "1a_8zb_west", [[ItemName.cannot_access, ], ]), + + "1a_8_south-west---1a_8_south": RegionConnection("1a_8_south-west", "1a_8_south", []), + "1a_8_south-west---1a_8_north": RegionConnection("1a_8_south-west", "1a_8_north", []), + "1a_8_west---1a_8_south-west": RegionConnection("1a_8_west", "1a_8_south-west", []), + "1a_8_south-east---1a_8_north": RegionConnection("1a_8_south-east", "1a_8_north", []), + "1a_8_south-east---1a_8_south": RegionConnection("1a_8_south-east", "1a_8_south", []), + "1a_8_north---1a_8_north-east": RegionConnection("1a_8_north", "1a_8_north-east", []), + "1a_8_north---1a_8_south": RegionConnection("1a_8_north", "1a_8_south", []), + "1a_8_north-east---1a_8_north": RegionConnection("1a_8_north-east", "1a_8_north", []), + + "1a_7a_east---1a_7a_west": RegionConnection("1a_7a_east", "1a_7a_west", []), + "1a_7a_west---1a_7a_east": RegionConnection("1a_7a_west", "1a_7a_east", []), + + + "1a_8b_east---1a_8b_west": RegionConnection("1a_8b_east", "1a_8b_west", []), + "1a_8b_west---1a_8b_east": RegionConnection("1a_8b_west", "1a_8b_east", [[ItemName.traffic_blocks, ], ]), + + "1a_9_east---1a_9_west": RegionConnection("1a_9_east", "1a_9_west", [[ItemName.cannot_access, ], ]), + "1a_9_west---1a_9_east": RegionConnection("1a_9_west", "1a_9_east", [[ItemName.traffic_blocks, ], ]), + + "1a_9b_east---1a_9b_north-east": RegionConnection("1a_9b_east", "1a_9b_north-east", []), + "1a_9b_north-east---1a_9b_east": RegionConnection("1a_9b_north-east", "1a_9b_east", []), + "1a_9b_north-east---1a_9b_west": RegionConnection("1a_9b_north-east", "1a_9b_west", []), + "1a_9b_west---1a_9b_east": RegionConnection("1a_9b_west", "1a_9b_east", [[ItemName.traffic_blocks, ], ]), + "1a_9b_west---1a_9b_north-west": RegionConnection("1a_9b_west", "1a_9b_north-west", [[ItemName.traffic_blocks, ], ]), + "1a_9b_north-west---1a_9b_west": RegionConnection("1a_9b_north-west", "1a_9b_west", []), + + + "1a_10_south-east---1a_10_south-west": RegionConnection("1a_10_south-east", "1a_10_south-west", []), + "1a_10_south-east---1a_10_north-west": RegionConnection("1a_10_south-east", "1a_10_north-west", [[ItemName.traffic_blocks, ], ]), + "1a_10_south-west---1a_10_south-east": RegionConnection("1a_10_south-west", "1a_10_south-east", []), + "1a_10_north-west---1a_10_south-east": RegionConnection("1a_10_north-west", "1a_10_south-east", []), + "1a_10_north-east---1a_10_south-east": RegionConnection("1a_10_north-east", "1a_10_south-east", []), + + "1a_10z_west---1a_10z_east": RegionConnection("1a_10z_west", "1a_10z_east", []), + "1a_10z_east---1a_10z_west": RegionConnection("1a_10z_east", "1a_10z_west", [[ItemName.springs, ], ]), + + + "1a_11_south-east---1a_11_north": RegionConnection("1a_11_south-east", "1a_11_north", [[ItemName.traffic_blocks, ItemName.springs, ], ]), + "1a_11_south-west---1a_11_south": RegionConnection("1a_11_south-west", "1a_11_south", [[ItemName.traffic_blocks, ], ]), + "1a_11_south-west---1a_11_west": RegionConnection("1a_11_south-west", "1a_11_west", [[ItemName.traffic_blocks, ], ]), + "1a_11_north---1a_11_south-east": RegionConnection("1a_11_north", "1a_11_south-east", []), + "1a_11_west---1a_11_south-west": RegionConnection("1a_11_west", "1a_11_south-west", [[ItemName.traffic_blocks, ], ]), + "1a_11_south---1a_11_south-west": RegionConnection("1a_11_south", "1a_11_south-west", []), + + + "1a_10a_bottom---1a_10a_top": RegionConnection("1a_10a_bottom", "1a_10a_top", [[ItemName.dash_refills, ], ]), + "1a_10a_top---1a_10a_bottom": RegionConnection("1a_10a_top", "1a_10a_bottom", [[ItemName.cannot_access, ], ]), + + "1a_12_south-west---1a_12_north-west": RegionConnection("1a_12_south-west", "1a_12_north-west", []), + "1a_12_south-west---1a_12_east": RegionConnection("1a_12_south-west", "1a_12_east", []), + "1a_12_north-west---1a_12_south-west": RegionConnection("1a_12_north-west", "1a_12_south-west", []), + + + "1a_12a_bottom---1a_12a_top": RegionConnection("1a_12a_bottom", "1a_12a_top", [[ItemName.traffic_blocks, ], ]), + "1a_12a_top---1a_12a_bottom": RegionConnection("1a_12a_top", "1a_12a_bottom", []), + + "1a_end_south---1a_end_main": RegionConnection("1a_end_south", "1a_end_main", []), + "1a_end_main---1a_end_south": RegionConnection("1a_end_main", "1a_end_south", []), + + "1b_00_west---1b_00_east": RegionConnection("1b_00_west", "1b_00_east", []), + "1b_00_east---1b_00_west": RegionConnection("1b_00_east", "1b_00_west", []), + + "1b_01_west---1b_01_east": RegionConnection("1b_01_west", "1b_01_east", [[ItemName.traffic_blocks, ], ]), + "1b_01_east---1b_01_west": RegionConnection("1b_01_east", "1b_01_west", [[ItemName.cannot_access, ], ]), + + "1b_02_west---1b_02_east": RegionConnection("1b_02_west", "1b_02_east", [[ItemName.traffic_blocks, ], ]), + "1b_02_east---1b_02_west": RegionConnection("1b_02_east", "1b_02_west", [[ItemName.cannot_access, ], ]), + + "1b_02b_west---1b_02b_east": RegionConnection("1b_02b_west", "1b_02b_east", [[ItemName.traffic_blocks, ], ]), + "1b_02b_east---1b_02b_west": RegionConnection("1b_02b_east", "1b_02b_west", [[ItemName.cannot_access, ], ]), + + "1b_03_west---1b_03_east": RegionConnection("1b_03_west", "1b_03_east", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "1b_03_east---1b_03_west": RegionConnection("1b_03_east", "1b_03_west", [[ItemName.cannot_access, ], ]), + + "1b_04_west---1b_04_east": RegionConnection("1b_04_west", "1b_04_east", [[ItemName.traffic_blocks, ItemName.springs, ], ]), + "1b_04_east---1b_04_west": RegionConnection("1b_04_east", "1b_04_west", [[ItemName.cannot_access, ], ]), + + "1b_05_west---1b_05_east": RegionConnection("1b_05_west", "1b_05_east", [[ItemName.traffic_blocks, ], ]), + "1b_05_east---1b_05_west": RegionConnection("1b_05_east", "1b_05_west", [[ItemName.cannot_access, ], ]), + + "1b_05b_west---1b_05b_east": RegionConnection("1b_05b_west", "1b_05b_east", [[ItemName.springs, ItemName.dash_refills, ], ]), + "1b_05b_east---1b_05b_west": RegionConnection("1b_05b_east", "1b_05b_west", [[ItemName.cannot_access, ], ]), + + "1b_06_west---1b_06_east": RegionConnection("1b_06_west", "1b_06_east", [[ItemName.springs, ItemName.dash_refills, ], ]), + "1b_06_east---1b_06_west": RegionConnection("1b_06_east", "1b_06_west", [[ItemName.cannot_access, ], ]), + + "1b_07_bottom---1b_07_top": RegionConnection("1b_07_bottom", "1b_07_top", [[ItemName.traffic_blocks, ], ]), + "1b_07_top---1b_07_bottom": RegionConnection("1b_07_top", "1b_07_bottom", []), + + "1b_08_west---1b_08_east": RegionConnection("1b_08_west", "1b_08_east", [[ItemName.traffic_blocks, ], ]), + + "1b_08b_west---1b_08b_east": RegionConnection("1b_08b_west", "1b_08b_east", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "1b_08b_east---1b_08b_west": RegionConnection("1b_08b_east", "1b_08b_west", [[ItemName.cannot_access, ], ]), + + "1b_09_west---1b_09_east": RegionConnection("1b_09_west", "1b_09_east", [[ItemName.traffic_blocks, ], ]), + "1b_09_east---1b_09_west": RegionConnection("1b_09_east", "1b_09_west", []), + + "1b_10_west---1b_10_east": RegionConnection("1b_10_west", "1b_10_east", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + + "1b_11_bottom---1b_11_top": RegionConnection("1b_11_bottom", "1b_11_top", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "1b_11_top---1b_11_bottom": RegionConnection("1b_11_top", "1b_11_bottom", []), + + "1b_end_west---1b_end_goal": RegionConnection("1b_end_west", "1b_end_goal", [[ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.dash_refills, ], ]), + + "1c_00_west---1c_00_east": RegionConnection("1c_00_west", "1c_00_east", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "1c_00_east---1c_00_west": RegionConnection("1c_00_east", "1c_00_west", [[ItemName.cannot_access, ], ]), + + "1c_01_west---1c_01_east": RegionConnection("1c_01_west", "1c_01_east", [[ItemName.traffic_blocks, ], ]), + "1c_01_east---1c_01_west": RegionConnection("1c_01_east", "1c_01_west", []), + + "1c_02_west---1c_02_goal": RegionConnection("1c_02_west", "1c_02_goal", [[ItemName.coins, ItemName.traffic_blocks, ], ]), + + "2a_start_main---2a_start_east": RegionConnection("2a_start_main", "2a_start_east", []), + "2a_start_top---2a_start_east": RegionConnection("2a_start_top", "2a_start_east", []), + "2a_start_top---2a_start_main": RegionConnection("2a_start_top", "2a_start_main", []), + "2a_start_east---2a_start_main": RegionConnection("2a_start_east", "2a_start_main", []), + "2a_start_east---2a_start_top": RegionConnection("2a_start_east", "2a_start_top", []), + + "2a_s0_bottom---2a_s0_top": RegionConnection("2a_s0_bottom", "2a_s0_top", []), + "2a_s0_top---2a_s0_bottom": RegionConnection("2a_s0_top", "2a_s0_bottom", []), + + "2a_s1_bottom---2a_s1_top": RegionConnection("2a_s1_bottom", "2a_s1_top", []), + "2a_s1_top---2a_s1_bottom": RegionConnection("2a_s1_top", "2a_s1_bottom", []), + + + "2a_0_south-west---2a_0_south-east": RegionConnection("2a_0_south-west", "2a_0_south-east", []), + "2a_0_south-east---2a_0_north-east": RegionConnection("2a_0_south-east", "2a_0_north-east", [[ItemName.dream_blocks, ], ]), + "2a_0_south-east---2a_0_south-west": RegionConnection("2a_0_south-east", "2a_0_south-west", []), + "2a_0_south-east---2a_0_north-west": RegionConnection("2a_0_south-east", "2a_0_north-west", [[ItemName.dream_blocks, ], ]), + "2a_0_north-west---2a_0_south-west": RegionConnection("2a_0_north-west", "2a_0_south-west", []), + "2a_0_north-east---2a_0_south-east": RegionConnection("2a_0_north-east", "2a_0_south-east", [[ItemName.dream_blocks, ], ]), + "2a_0_north-east---2a_0_north-west": RegionConnection("2a_0_north-east", "2a_0_north-west", [[ItemName.dream_blocks, ], ]), + + "2a_1_south-west---2a_1_south": RegionConnection("2a_1_south-west", "2a_1_south", []), + "2a_1_south---2a_1_south-west": RegionConnection("2a_1_south", "2a_1_south-west", []), + "2a_1_south---2a_1_south-east": RegionConnection("2a_1_south", "2a_1_south-east", []), + "2a_1_south-east---2a_1_south": RegionConnection("2a_1_south-east", "2a_1_south", []), + + "2a_d0_north---2a_d0_north-west": RegionConnection("2a_d0_north", "2a_d0_north-west", []), + "2a_d0_north-west---2a_d0_north": RegionConnection("2a_d0_north-west", "2a_d0_north", []), + "2a_d0_north-west---2a_d0_west": RegionConnection("2a_d0_north-west", "2a_d0_west", []), + "2a_d0_north-west---2a_d0_north-east": RegionConnection("2a_d0_north-west", "2a_d0_north-east", [[ItemName.dream_blocks, ], ]), + "2a_d0_west---2a_d0_north-west": RegionConnection("2a_d0_west", "2a_d0_north-west", []), + "2a_d0_west---2a_d0_south-west": RegionConnection("2a_d0_west", "2a_d0_south-west", []), + "2a_d0_west---2a_d0_east": RegionConnection("2a_d0_west", "2a_d0_east", []), + "2a_d0_south-west---2a_d0_south": RegionConnection("2a_d0_south-west", "2a_d0_south", [[ItemName.dream_blocks, ], ]), + "2a_d0_south-west---2a_d0_south-east": RegionConnection("2a_d0_south-west", "2a_d0_south-east", []), + "2a_d0_south-west---2a_d0_south-east": RegionConnection("2a_d0_south-west", "2a_d0_south-east", [[ItemName.cannot_access, ], ]), + "2a_d0_south---2a_d0_south-west": RegionConnection("2a_d0_south", "2a_d0_south-west", [[ItemName.dream_blocks, ], ]), + "2a_d0_south-east---2a_d0_south-west": RegionConnection("2a_d0_south-east", "2a_d0_south-west", []), + "2a_d0_south-east---2a_d0_east": RegionConnection("2a_d0_south-east", "2a_d0_east", []), + "2a_d0_east---2a_d0_west": RegionConnection("2a_d0_east", "2a_d0_west", [[ItemName.dream_blocks, ], ]), + "2a_d0_east---2a_d0_south-east": RegionConnection("2a_d0_east", "2a_d0_south-east", []), + "2a_d0_north-east---2a_d0_north-west": RegionConnection("2a_d0_north-east", "2a_d0_north-west", [[ItemName.dream_blocks, ], ]), + + "2a_d7_west---2a_d7_east": RegionConnection("2a_d7_west", "2a_d7_east", [[ItemName.dash_refills, ], ]), + "2a_d7_east---2a_d7_west": RegionConnection("2a_d7_east", "2a_d7_west", [[ItemName.cannot_access, ], ]), + + "2a_d8_west---2a_d8_south-east": RegionConnection("2a_d8_west", "2a_d8_south-east", [[ItemName.dash_refills, ], ]), + "2a_d8_south-east---2a_d8_west": RegionConnection("2a_d8_south-east", "2a_d8_west", [[ItemName.cannot_access, ], ]), + "2a_d8_south-east---2a_d8_north-east": RegionConnection("2a_d8_south-east", "2a_d8_north-east", []), + + "2a_d3_west---2a_d3_north": RegionConnection("2a_d3_west", "2a_d3_north", [[ItemName.dream_blocks, ], ]), + "2a_d3_north---2a_d3_west": RegionConnection("2a_d3_north", "2a_d3_west", [[ItemName.dream_blocks, ], ]), + + "2a_d2_west---2a_d2_east": RegionConnection("2a_d2_west", "2a_d2_east", []), + "2a_d2_north-west---2a_d2_west": RegionConnection("2a_d2_north-west", "2a_d2_west", []), + "2a_d2_east---2a_d2_west": RegionConnection("2a_d2_east", "2a_d2_west", []), + + + "2a_d1_south-west---2a_d1_south-east": RegionConnection("2a_d1_south-west", "2a_d1_south-east", []), + "2a_d1_south-west---2a_d1_north-east": RegionConnection("2a_d1_south-west", "2a_d1_north-east", []), + "2a_d1_south-east---2a_d1_south-west": RegionConnection("2a_d1_south-east", "2a_d1_south-west", []), + "2a_d1_south-east---2a_d1_north-east": RegionConnection("2a_d1_south-east", "2a_d1_north-east", []), + "2a_d1_north-east---2a_d1_south-west": RegionConnection("2a_d1_north-east", "2a_d1_south-west", []), + "2a_d1_north-east---2a_d1_south-east": RegionConnection("2a_d1_north-east", "2a_d1_south-east", []), + + "2a_d6_west---2a_d6_east": RegionConnection("2a_d6_west", "2a_d6_east", []), + "2a_d6_east---2a_d6_west": RegionConnection("2a_d6_east", "2a_d6_west", [[ItemName.cannot_access, ], ]), + + "2a_d4_west---2a_d4_east": RegionConnection("2a_d4_west", "2a_d4_east", []), + "2a_d4_west---2a_d4_south": RegionConnection("2a_d4_west", "2a_d4_south", [[ItemName.dream_blocks, ], ]), + "2a_d4_east---2a_d4_west": RegionConnection("2a_d4_east", "2a_d4_west", []), + "2a_d4_south---2a_d4_west": RegionConnection("2a_d4_south", "2a_d4_west", [[ItemName.dream_blocks, ], ]), + + + "2a_3x_bottom---2a_3x_top": RegionConnection("2a_3x_bottom", "2a_3x_top", [[ItemName.dream_blocks, ], ]), + "2a_3x_top---2a_3x_bottom": RegionConnection("2a_3x_top", "2a_3x_bottom", [[ItemName.dream_blocks, ], ]), + + "2a_3_bottom---2a_3_top": RegionConnection("2a_3_bottom", "2a_3_top", [[ItemName.dream_blocks, ], ]), + "2a_3_top---2a_3_bottom": RegionConnection("2a_3_top", "2a_3_bottom", [[ItemName.dream_blocks, ], ]), + + "2a_4_bottom---2a_4_top": RegionConnection("2a_4_bottom", "2a_4_top", [[ItemName.dream_blocks, ], ]), + "2a_4_top---2a_4_bottom": RegionConnection("2a_4_top", "2a_4_bottom", [[ItemName.dream_blocks, ], ]), + + "2a_5_bottom---2a_5_top": RegionConnection("2a_5_bottom", "2a_5_top", [[ItemName.dream_blocks, ], ]), + "2a_5_top---2a_5_bottom": RegionConnection("2a_5_top", "2a_5_bottom", [[ItemName.dream_blocks, ], ]), + + "2a_6_bottom---2a_6_top": RegionConnection("2a_6_bottom", "2a_6_top", [[ItemName.dream_blocks, ItemName.coins, ], ]), + "2a_6_top---2a_6_bottom": RegionConnection("2a_6_top", "2a_6_bottom", [[ItemName.cannot_access, ], ]), + + "2a_7_bottom---2a_7_top": RegionConnection("2a_7_bottom", "2a_7_top", [[ItemName.dream_blocks, ItemName.coins, ], ]), + "2a_7_top---2a_7_bottom": RegionConnection("2a_7_top", "2a_7_bottom", [[ItemName.cannot_access, ], ]), + + "2a_8_bottom---2a_8_top": RegionConnection("2a_8_bottom", "2a_8_top", [[ItemName.dream_blocks, ], ]), + "2a_8_top---2a_8_bottom": RegionConnection("2a_8_top", "2a_8_bottom", [[ItemName.cannot_access, ], ]), + + "2a_9_west---2a_9_north": RegionConnection("2a_9_west", "2a_9_north", [[ItemName.dream_blocks, ], ]), + "2a_9_north---2a_9_south": RegionConnection("2a_9_north", "2a_9_south", [[ItemName.dream_blocks, ], ]), + "2a_9_north---2a_9_west": RegionConnection("2a_9_north", "2a_9_west", [[ItemName.cannot_access, ], ]), + "2a_9_north-west---2a_9_west": RegionConnection("2a_9_north-west", "2a_9_west", []), + "2a_9_south---2a_9_south-east": RegionConnection("2a_9_south", "2a_9_south-east", [[ItemName.coins, ], ]), + + "2a_9b_east---2a_9b_west": RegionConnection("2a_9b_east", "2a_9b_west", []), + "2a_9b_west---2a_9b_east": RegionConnection("2a_9b_west", "2a_9b_east", []), + + "2a_10_top---2a_10_bottom": RegionConnection("2a_10_top", "2a_10_bottom", [[ItemName.dream_blocks, ItemName.dash_refills, ItemName.coins, ], ]), + "2a_10_bottom---2a_10_top": RegionConnection("2a_10_bottom", "2a_10_top", [[ItemName.cannot_access, ], ]), + + "2a_2_north-west---2a_2_south-east": RegionConnection("2a_2_north-west", "2a_2_south-east", []), + "2a_2_south-east---2a_2_north-west": RegionConnection("2a_2_south-east", "2a_2_north-west", []), + + "2a_11_west---2a_11_east": RegionConnection("2a_11_west", "2a_11_east", []), + "2a_11_east---2a_11_west": RegionConnection("2a_11_east", "2a_11_west", []), + + "2a_12b_west---2a_12b_north": RegionConnection("2a_12b_west", "2a_12b_north", [[ItemName.dream_blocks, ], ]), + "2a_12b_north---2a_12b_west": RegionConnection("2a_12b_north", "2a_12b_west", [[ItemName.dream_blocks, ], ]), + "2a_12b_north---2a_12b_south": RegionConnection("2a_12b_north", "2a_12b_south", [[ItemName.dream_blocks, ], ]), + "2a_12b_north---2a_12b_east": RegionConnection("2a_12b_north", "2a_12b_east", [[ItemName.dream_blocks, ], ]), + "2a_12b_south---2a_12b_north": RegionConnection("2a_12b_south", "2a_12b_north", [[ItemName.dream_blocks, ], ]), + "2a_12b_east---2a_12b_north": RegionConnection("2a_12b_east", "2a_12b_north", [[ItemName.dream_blocks, ], ]), + "2a_12b_south-east---2a_12b_north": RegionConnection("2a_12b_south-east", "2a_12b_north", []), + + + "2a_12d_north-west---2a_12d_north": RegionConnection("2a_12d_north-west", "2a_12d_north", []), + "2a_12d_north---2a_12d_north-west": RegionConnection("2a_12d_north", "2a_12d_north-west", []), + + "2a_12_west---2a_12_east": RegionConnection("2a_12_west", "2a_12_east", []), + "2a_12_east---2a_12_west": RegionConnection("2a_12_east", "2a_12_west", []), + + "2a_13_west---2a_13_phone": RegionConnection("2a_13_west", "2a_13_phone", []), + "2a_13_phone---2a_13_west": RegionConnection("2a_13_phone", "2a_13_west", []), + + "2a_end_0_main---2a_end_0_east": RegionConnection("2a_end_0_main", "2a_end_0_east", []), + "2a_end_0_top---2a_end_0_east": RegionConnection("2a_end_0_top", "2a_end_0_east", []), + "2a_end_0_top---2a_end_0_main": RegionConnection("2a_end_0_top", "2a_end_0_main", []), + "2a_end_0_east---2a_end_0_main": RegionConnection("2a_end_0_east", "2a_end_0_main", []), + "2a_end_0_east---2a_end_0_top": RegionConnection("2a_end_0_east", "2a_end_0_top", []), + + "2a_end_s0_bottom---2a_end_s0_top": RegionConnection("2a_end_s0_bottom", "2a_end_s0_top", []), + "2a_end_s0_top---2a_end_s0_bottom": RegionConnection("2a_end_s0_top", "2a_end_s0_bottom", []), + + + "2a_end_1_west---2a_end_1_east": RegionConnection("2a_end_1_west", "2a_end_1_east", []), + "2a_end_1_west---2a_end_1_north-east": RegionConnection("2a_end_1_west", "2a_end_1_north-east", []), + "2a_end_1_north-east---2a_end_1_west": RegionConnection("2a_end_1_north-east", "2a_end_1_west", []), + "2a_end_1_east---2a_end_1_west": RegionConnection("2a_end_1_east", "2a_end_1_west", []), + + "2a_end_2_north-west---2a_end_2_north-east": RegionConnection("2a_end_2_north-west", "2a_end_2_north-east", []), + "2a_end_2_west---2a_end_2_east": RegionConnection("2a_end_2_west", "2a_end_2_east", []), + "2a_end_2_north-east---2a_end_2_north-west": RegionConnection("2a_end_2_north-east", "2a_end_2_north-west", []), + "2a_end_2_east---2a_end_2_west": RegionConnection("2a_end_2_east", "2a_end_2_west", []), + + "2a_end_3_north-west---2a_end_3_west": RegionConnection("2a_end_3_north-west", "2a_end_3_west", []), + "2a_end_3_west---2a_end_3_east": RegionConnection("2a_end_3_west", "2a_end_3_east", []), + "2a_end_3_west---2a_end_3_north-west": RegionConnection("2a_end_3_west", "2a_end_3_north-west", []), + "2a_end_3_east---2a_end_3_west": RegionConnection("2a_end_3_east", "2a_end_3_west", []), + + "2a_end_4_west---2a_end_4_east": RegionConnection("2a_end_4_west", "2a_end_4_east", []), + "2a_end_4_east---2a_end_4_west": RegionConnection("2a_end_4_east", "2a_end_4_west", []), + + "2a_end_3b_west---2a_end_3b_north": RegionConnection("2a_end_3b_west", "2a_end_3b_north", [[ItemName.springs, ], ]), + "2a_end_3b_west---2a_end_3b_east": RegionConnection("2a_end_3b_west", "2a_end_3b_east", []), + "2a_end_3b_north---2a_end_3b_west": RegionConnection("2a_end_3b_north", "2a_end_3b_west", []), + "2a_end_3b_east---2a_end_3b_west": RegionConnection("2a_end_3b_east", "2a_end_3b_west", []), + + "2a_end_3cb_bottom---2a_end_3cb_top": RegionConnection("2a_end_3cb_bottom", "2a_end_3cb_top", []), + "2a_end_3cb_top---2a_end_3cb_bottom": RegionConnection("2a_end_3cb_top", "2a_end_3cb_bottom", []), + + + "2a_end_5_west---2a_end_5_east": RegionConnection("2a_end_5_west", "2a_end_5_east", []), + "2a_end_5_east---2a_end_5_west": RegionConnection("2a_end_5_east", "2a_end_5_west", []), + + "2a_end_6_west---2a_end_6_main": RegionConnection("2a_end_6_west", "2a_end_6_main", []), + "2a_end_6_main---2a_end_6_west": RegionConnection("2a_end_6_main", "2a_end_6_west", []), + + "2b_start_west---2b_start_east": RegionConnection("2b_start_west", "2b_start_east", []), + "2b_start_east---2b_start_west": RegionConnection("2b_start_east", "2b_start_west", []), + + "2b_00_west---2b_00_east": RegionConnection("2b_00_west", "2b_00_east", [[ItemName.dream_blocks, ], ]), + "2b_00_east---2b_00_west": RegionConnection("2b_00_east", "2b_00_west", [[ItemName.dream_blocks, ], ]), + + "2b_01_west---2b_01_east": RegionConnection("2b_01_west", "2b_01_east", [[ItemName.dream_blocks, ], ]), + "2b_01_east---2b_01_west": RegionConnection("2b_01_east", "2b_01_west", [[ItemName.dream_blocks, ], ]), + + "2b_01b_west---2b_01b_east": RegionConnection("2b_01b_west", "2b_01b_east", [[ItemName.dream_blocks, ], ]), + "2b_01b_east---2b_01b_west": RegionConnection("2b_01b_east", "2b_01b_west", [[ItemName.cannot_access, ], ]), + + "2b_02b_west---2b_02b_east": RegionConnection("2b_02b_west", "2b_02b_east", [[ItemName.dream_blocks, ItemName.dash_refills, ], ]), + "2b_02b_east---2b_02b_west": RegionConnection("2b_02b_east", "2b_02b_west", [[ItemName.cannot_access, ], ]), + + "2b_02_west---2b_02_east": RegionConnection("2b_02_west", "2b_02_east", [[ItemName.dream_blocks, ItemName.dash_refills, ], ]), + "2b_02_east---2b_02_west": RegionConnection("2b_02_east", "2b_02_west", [[ItemName.cannot_access, ], ]), + + "2b_03_west---2b_03_east": RegionConnection("2b_03_west", "2b_03_east", [[ItemName.dream_blocks, ItemName.coins, ], ]), + "2b_03_east---2b_03_west": RegionConnection("2b_03_east", "2b_03_west", [[ItemName.cannot_access, ], ]), + + "2b_04_bottom---2b_04_top": RegionConnection("2b_04_bottom", "2b_04_top", [[ItemName.dream_blocks, ItemName.dash_refills, ], ]), + "2b_04_top---2b_04_bottom": RegionConnection("2b_04_top", "2b_04_bottom", [[ItemName.cannot_access, ], ]), + + "2b_05_bottom---2b_05_top": RegionConnection("2b_05_bottom", "2b_05_top", [[ItemName.dream_blocks, ItemName.dash_refills, ], ]), + "2b_05_top---2b_05_bottom": RegionConnection("2b_05_top", "2b_05_bottom", [[ItemName.cannot_access, ], ]), + + "2b_06_west---2b_06_east": RegionConnection("2b_06_west", "2b_06_east", [[ItemName.dream_blocks, ItemName.coins, ], ]), + "2b_06_east---2b_06_west": RegionConnection("2b_06_east", "2b_06_west", [[ItemName.cannot_access, ], ]), + + "2b_07_bottom---2b_07_top": RegionConnection("2b_07_bottom", "2b_07_top", [[ItemName.dream_blocks, ItemName.coins, ], ]), + "2b_07_top---2b_07_bottom": RegionConnection("2b_07_top", "2b_07_bottom", [[ItemName.cannot_access, ], ]), + + "2b_08b_west---2b_08b_east": RegionConnection("2b_08b_west", "2b_08b_east", [[ItemName.dream_blocks, ItemName.springs, ], ]), + "2b_08b_east---2b_08b_west": RegionConnection("2b_08b_east", "2b_08b_west", [[ItemName.cannot_access, ], ]), + + "2b_08_west---2b_08_east": RegionConnection("2b_08_west", "2b_08_east", [[ItemName.dream_blocks, ItemName.dash_refills, ], ]), + + "2b_09_west---2b_09_east": RegionConnection("2b_09_west", "2b_09_east", [[ItemName.dream_blocks, ], ]), + + "2b_10_west---2b_10_east": RegionConnection("2b_10_west", "2b_10_east", [[ItemName.dream_blocks, ItemName.coins, ], ]), + + "2b_11_bottom---2b_11_top": RegionConnection("2b_11_bottom", "2b_11_top", [[ItemName.springs, ItemName.dream_blocks, ItemName.dash_refills, ItemName.coins, ], ]), + + "2b_end_west---2b_end_goal": RegionConnection("2b_end_west", "2b_end_goal", [[ItemName.blue_cassette_blocks, ItemName.dash_refills, ], ]), + + "2c_00_west---2c_00_east": RegionConnection("2c_00_west", "2c_00_east", [[ItemName.dream_blocks, ], ]), + "2c_00_east---2c_00_west": RegionConnection("2c_00_east", "2c_00_west", [[ItemName.dream_blocks, ], ]), + + "2c_01_west---2c_01_east": RegionConnection("2c_01_west", "2c_01_east", [[ItemName.dream_blocks, ItemName.coins, ], ]), + + "2c_02_west---2c_02_goal": RegionConnection("2c_02_west", "2c_02_goal", [[ItemName.coins, ItemName.dream_blocks, ItemName.dash_refills, ], ]), + + "3a_s0_main---3a_s0_east": RegionConnection("3a_s0_main", "3a_s0_east", []), + "3a_s0_east---3a_s0_main": RegionConnection("3a_s0_east", "3a_s0_main", []), + + "3a_s1_west---3a_s1_east": RegionConnection("3a_s1_west", "3a_s1_east", []), + "3a_s1_west---3a_s1_north-east": RegionConnection("3a_s1_west", "3a_s1_north-east", []), + "3a_s1_east---3a_s1_west": RegionConnection("3a_s1_east", "3a_s1_west", []), + "3a_s1_north-east---3a_s1_west": RegionConnection("3a_s1_north-east", "3a_s1_west", []), + + "3a_s2_west---3a_s2_east": RegionConnection("3a_s2_west", "3a_s2_east", []), + "3a_s2_north-west---3a_s2_east": RegionConnection("3a_s2_north-west", "3a_s2_east", []), + "3a_s2_east---3a_s2_west": RegionConnection("3a_s2_east", "3a_s2_west", []), + "3a_s2_east---3a_s2_north-west": RegionConnection("3a_s2_east", "3a_s2_north-west", []), + + "3a_s3_west---3a_s3_east": RegionConnection("3a_s3_west", "3a_s3_east", [["Celestial Resort A - Front Door Key", ], ]), + "3a_s3_east---3a_s3_west": RegionConnection("3a_s3_east", "3a_s3_west", []), + + "3a_0x-a_west---3a_0x-a_east": RegionConnection("3a_0x-a_west", "3a_0x-a_east", []), + "3a_0x-a_east---3a_0x-a_west": RegionConnection("3a_0x-a_east", "3a_0x-a_west", []), + + "3a_00-a_west---3a_00-a_east": RegionConnection("3a_00-a_west", "3a_00-a_east", []), + "3a_00-a_east---3a_00-a_west": RegionConnection("3a_00-a_east", "3a_00-a_west", []), + + "3a_02-a_west---3a_02-a_main": RegionConnection("3a_02-a_west", "3a_02-a_main", [[ItemName.sinking_platforms, ], [ItemName.dash_refills, ], ]), + "3a_02-a_top---3a_02-a_west": RegionConnection("3a_02-a_top", "3a_02-a_west", [[ItemName.dash_refills, ], ]), + "3a_02-a_top---3a_02-a_main": RegionConnection("3a_02-a_top", "3a_02-a_main", [[ItemName.dash_refills, ], ]), + "3a_02-a_main---3a_02-a_top": RegionConnection("3a_02-a_main", "3a_02-a_top", [[ItemName.dash_refills, ], ]), + "3a_02-a_main---3a_02-a_east": RegionConnection("3a_02-a_main", "3a_02-a_east", [["Celestial Resort A - Hallway Key 1", ], ]), + "3a_02-a_east---3a_02-a_main": RegionConnection("3a_02-a_east", "3a_02-a_main", []), + + "3a_02-b_west---3a_02-b_east": RegionConnection("3a_02-b_west", "3a_02-b_east", []), + "3a_02-b_east---3a_02-b_west": RegionConnection("3a_02-b_east", "3a_02-b_west", []), + + "3a_01-b_west---3a_01-b_east": RegionConnection("3a_01-b_west", "3a_01-b_east", []), + "3a_01-b_north-west---3a_01-b_west": RegionConnection("3a_01-b_north-west", "3a_01-b_west", []), + "3a_01-b_east---3a_01-b_west": RegionConnection("3a_01-b_east", "3a_01-b_west", []), + "3a_01-b_east---3a_01-b_north-west": RegionConnection("3a_01-b_east", "3a_01-b_north-west", [[ItemName.springs, ], ]), + + "3a_00-b_south-west---3a_00-b_south-east": RegionConnection("3a_00-b_south-west", "3a_00-b_south-east", []), + "3a_00-b_south-east---3a_00-b_south-west": RegionConnection("3a_00-b_south-east", "3a_00-b_south-west", []), + "3a_00-b_west---3a_00-b_north-west": RegionConnection("3a_00-b_west", "3a_00-b_north-west", []), + "3a_00-b_north-west---3a_00-b_west": RegionConnection("3a_00-b_north-west", "3a_00-b_west", []), + "3a_00-b_east---3a_00-b_north": RegionConnection("3a_00-b_east", "3a_00-b_north", []), + "3a_00-b_north---3a_00-b_east": RegionConnection("3a_00-b_north", "3a_00-b_east", []), + + "3a_00-c_south-west---3a_00-c_south-east": RegionConnection("3a_00-c_south-west", "3a_00-c_south-east", [[ItemName.dash_refills, ], ]), + "3a_00-c_south-east---3a_00-c_south-west": RegionConnection("3a_00-c_south-east", "3a_00-c_south-west", [[ItemName.dash_refills, ], ]), + "3a_00-c_south-east---3a_00-c_north-east": RegionConnection("3a_00-c_south-east", "3a_00-c_north-east", []), + "3a_00-c_north-east---3a_00-c_south-east": RegionConnection("3a_00-c_north-east", "3a_00-c_south-east", []), + + "3a_0x-b_west---3a_0x-b_south-east": RegionConnection("3a_0x-b_west", "3a_0x-b_south-east", []), + "3a_0x-b_north-east---3a_0x-b_west": RegionConnection("3a_0x-b_north-east", "3a_0x-b_west", [[ItemName.dash_refills, ], ]), + + "3a_03-a_west---3a_03-a_east": RegionConnection("3a_03-a_west", "3a_03-a_east", [[ItemName.sinking_platforms, ], ]), + "3a_03-a_top---3a_03-a_east": RegionConnection("3a_03-a_top", "3a_03-a_east", []), + "3a_03-a_east---3a_03-a_top": RegionConnection("3a_03-a_east", "3a_03-a_top", []), + + + "3a_05-a_west---3a_05-a_east": RegionConnection("3a_05-a_west", "3a_05-a_east", [[ItemName.dash_refills, ItemName.moving_platforms, ], ]), + "3a_05-a_east---3a_05-a_west": RegionConnection("3a_05-a_east", "3a_05-a_west", [[ItemName.dash_refills, ItemName.moving_platforms, ], ]), + + "3a_06-a_west---3a_06-a_east": RegionConnection("3a_06-a_west", "3a_06-a_east", []), + + "3a_07-a_west---3a_07-a_east": RegionConnection("3a_07-a_west", "3a_07-a_east", [["Celestial Resort A - Hallway Key 2", ItemName.dash_refills, ], ]), + "3a_07-a_west---3a_07-a_top": RegionConnection("3a_07-a_west", "3a_07-a_top", []), + "3a_07-a_top---3a_07-a_west": RegionConnection("3a_07-a_top", "3a_07-a_west", []), + "3a_07-a_east---3a_07-a_west": RegionConnection("3a_07-a_east", "3a_07-a_west", [["Celestial Resort A - Hallway Key 2", ItemName.dash_refills, ], ]), + + "3a_07-b_bottom---3a_07-b_west": RegionConnection("3a_07-b_bottom", "3a_07-b_west", []), + "3a_07-b_west---3a_07-b_bottom": RegionConnection("3a_07-b_west", "3a_07-b_bottom", []), + "3a_07-b_east---3a_07-b_bottom": RegionConnection("3a_07-b_east", "3a_07-b_bottom", []), + + "3a_06-b_west---3a_06-b_east": RegionConnection("3a_06-b_west", "3a_06-b_east", []), + "3a_06-b_east---3a_06-b_west": RegionConnection("3a_06-b_east", "3a_06-b_west", []), + + "3a_06-c_south-west---3a_06-c_north-west": RegionConnection("3a_06-c_south-west", "3a_06-c_north-west", []), + "3a_06-c_south-west---3a_06-c_south-east": RegionConnection("3a_06-c_south-west", "3a_06-c_south-east", []), + "3a_06-c_north-west---3a_06-c_south-west": RegionConnection("3a_06-c_north-west", "3a_06-c_south-west", []), + "3a_06-c_south-east---3a_06-c_south-west": RegionConnection("3a_06-c_south-east", "3a_06-c_south-west", []), + "3a_06-c_south-east---3a_06-c_east": RegionConnection("3a_06-c_south-east", "3a_06-c_east", []), + "3a_06-c_east---3a_06-c_south-east": RegionConnection("3a_06-c_east", "3a_06-c_south-east", []), + + + "3a_08-c_west---3a_08-c_east": RegionConnection("3a_08-c_west", "3a_08-c_east", [[ItemName.coins, ItemName.moving_platforms, ItemName.springs, ], ]), + + "3a_08-b_east---3a_08-b_west": RegionConnection("3a_08-b_east", "3a_08-b_west", [[ItemName.sinking_platforms, ItemName.coins, ], ]), + + "3a_08-a_west---3a_08-a_east": RegionConnection("3a_08-a_west", "3a_08-a_east", []), + "3a_08-a_west---3a_08-a_bottom": RegionConnection("3a_08-a_west", "3a_08-a_bottom", [[ItemName.brown_clutter, ], [ItemName.green_clutter, ], [ItemName.pink_clutter, ], ]), + "3a_08-a_east---3a_08-a_west": RegionConnection("3a_08-a_east", "3a_08-a_west", []), + + "3a_09-b_west---3a_09-b_center": RegionConnection("3a_09-b_west", "3a_09-b_center", []), + "3a_09-b_north-west---3a_09-b_center": RegionConnection("3a_09-b_north-west", "3a_09-b_center", [["Celestial Resort A - Huge Mess Key", ], ]), + "3a_09-b_center---3a_09-b_west": RegionConnection("3a_09-b_center", "3a_09-b_west", []), + "3a_09-b_center---3a_09-b_north-west": RegionConnection("3a_09-b_center", "3a_09-b_north-west", [["Celestial Resort A - Huge Mess Key", ], ]), + "3a_09-b_center---3a_09-b_south-west": RegionConnection("3a_09-b_center", "3a_09-b_south-west", [[ItemName.brown_clutter, ], [ItemName.green_clutter, ], [ItemName.pink_clutter, ], ]), + "3a_09-b_center---3a_09-b_south": RegionConnection("3a_09-b_center", "3a_09-b_south", []), + "3a_09-b_center---3a_09-b_south-east": RegionConnection("3a_09-b_center", "3a_09-b_south-east", []), + "3a_09-b_center---3a_09-b_east": RegionConnection("3a_09-b_center", "3a_09-b_east", []), + "3a_09-b_center---3a_09-b_north-east-right": RegionConnection("3a_09-b_center", "3a_09-b_north-east-right", []), + "3a_09-b_center---3a_09-b_north-east-top": RegionConnection("3a_09-b_center", "3a_09-b_north-east-top", []), + "3a_09-b_center---3a_09-b_north": RegionConnection("3a_09-b_center", "3a_09-b_north", []), + "3a_09-b_south-west---3a_09-b_center": RegionConnection("3a_09-b_south-west", "3a_09-b_center", [[ItemName.brown_clutter, ], [ItemName.green_clutter, ], [ItemName.pink_clutter, ], ]), + "3a_09-b_south---3a_09-b_center": RegionConnection("3a_09-b_south", "3a_09-b_center", []), + "3a_09-b_south-east---3a_09-b_center": RegionConnection("3a_09-b_south-east", "3a_09-b_center", []), + "3a_09-b_east---3a_09-b_center": RegionConnection("3a_09-b_east", "3a_09-b_center", []), + "3a_09-b_north-east-right---3a_09-b_center": RegionConnection("3a_09-b_north-east-right", "3a_09-b_center", []), + "3a_09-b_north-east-top---3a_09-b_center": RegionConnection("3a_09-b_north-east-top", "3a_09-b_center", []), + "3a_09-b_north---3a_09-b_center": RegionConnection("3a_09-b_north", "3a_09-b_center", []), + + "3a_10-x_west---3a_10-x_south-east": RegionConnection("3a_10-x_west", "3a_10-x_south-east", []), + "3a_10-x_south-east---3a_10-x_west": RegionConnection("3a_10-x_south-east", "3a_10-x_west", [[ItemName.brown_clutter, ], ]), + "3a_10-x_north-east-top---3a_10-x_north-east-right": RegionConnection("3a_10-x_north-east-top", "3a_10-x_north-east-right", []), + "3a_10-x_north-east-right---3a_10-x_north-east-top": RegionConnection("3a_10-x_north-east-right", "3a_10-x_north-east-top", []), + + "3a_11-x_west---3a_11-x_south": RegionConnection("3a_11-x_west", "3a_11-x_south", [[ItemName.coins, ], ]), + + "3a_11-y_west---3a_11-y_east": RegionConnection("3a_11-y_west", "3a_11-y_east", []), + "3a_11-y_east---3a_11-y_east": RegionConnection("3a_11-y_east", "3a_11-y_east", []), + "3a_11-y_east---3a_11-y_south": RegionConnection("3a_11-y_east", "3a_11-y_south", []), + "3a_11-y_south---3a_11-y_east": RegionConnection("3a_11-y_south", "3a_11-y_east", []), + + + "3a_11-z_west---3a_11-z_east": RegionConnection("3a_11-z_west", "3a_11-z_east", [[ItemName.dash_refills, ], ]), + "3a_11-z_east---3a_11-z_west": RegionConnection("3a_11-z_east", "3a_11-z_west", [[ItemName.dash_refills, ], ]), + + "3a_10-z_bottom---3a_10-z_top": RegionConnection("3a_10-z_bottom", "3a_10-z_top", [[ItemName.sinking_platforms, ], ]), + "3a_10-z_top---3a_10-z_bottom": RegionConnection("3a_10-z_top", "3a_10-z_bottom", []), + + "3a_10-y_bottom---3a_10-y_top": RegionConnection("3a_10-y_bottom", "3a_10-y_top", []), + "3a_10-y_top---3a_10-y_bottom": RegionConnection("3a_10-y_top", "3a_10-y_bottom", []), + + "3a_10-c_south-east---3a_10-c_north-east": RegionConnection("3a_10-c_south-east", "3a_10-c_north-east", []), + "3a_10-c_north-east---3a_10-c_south-east": RegionConnection("3a_10-c_north-east", "3a_10-c_south-east", []), + "3a_10-c_north-west---3a_10-c_south-west": RegionConnection("3a_10-c_north-west", "3a_10-c_south-west", []), + "3a_10-c_south-west---3a_10-c_north-west": RegionConnection("3a_10-c_south-west", "3a_10-c_north-west", []), + + "3a_11-c_west---3a_11-c_east": RegionConnection("3a_11-c_west", "3a_11-c_east", []), + "3a_11-c_east---3a_11-c_west": RegionConnection("3a_11-c_east", "3a_11-c_west", []), + "3a_11-c_south-east---3a_11-c_south-west": RegionConnection("3a_11-c_south-east", "3a_11-c_south-west", []), + "3a_11-c_south-west---3a_11-c_south-east": RegionConnection("3a_11-c_south-west", "3a_11-c_south-east", []), + + "3a_12-c_west---3a_12-c_top": RegionConnection("3a_12-c_west", "3a_12-c_top", []), + "3a_12-c_top---3a_12-c_west": RegionConnection("3a_12-c_top", "3a_12-c_west", []), + + "3a_12-d_bottom---3a_12-d_top": RegionConnection("3a_12-d_bottom", "3a_12-d_top", []), + + "3a_11-d_west---3a_11-d_east": RegionConnection("3a_11-d_west", "3a_11-d_east", [[ItemName.cannot_access, ], ]), + "3a_11-d_east---3a_11-d_west": RegionConnection("3a_11-d_east", "3a_11-d_west", [[ItemName.dash_refills, ], ]), + + "3a_10-d_west---3a_10-d_main": RegionConnection("3a_10-d_west", "3a_10-d_main", [[ItemName.green_clutter, ], ]), + "3a_10-d_main---3a_10-d_west": RegionConnection("3a_10-d_main", "3a_10-d_west", []), + "3a_10-d_east---3a_10-d_main": RegionConnection("3a_10-d_east", "3a_10-d_main", []), + + "3a_11-b_west---3a_11-b_east": RegionConnection("3a_11-b_west", "3a_11-b_east", []), + "3a_11-b_north-west---3a_11-b_west": RegionConnection("3a_11-b_north-west", "3a_11-b_west", []), + "3a_11-b_east---3a_11-b_west": RegionConnection("3a_11-b_east", "3a_11-b_west", []), + "3a_11-b_east---3a_11-b_north-east": RegionConnection("3a_11-b_east", "3a_11-b_north-east", [[ItemName.pink_clutter, ], ]), + "3a_11-b_north-east---3a_11-b_east": RegionConnection("3a_11-b_north-east", "3a_11-b_east", [[ItemName.pink_clutter, ], ]), + + "3a_12-b_west---3a_12-b_east": RegionConnection("3a_12-b_west", "3a_12-b_east", []), + "3a_12-b_east---3a_12-b_west": RegionConnection("3a_12-b_east", "3a_12-b_west", []), + + "3a_13-b_top---3a_13-b_bottom": RegionConnection("3a_13-b_top", "3a_13-b_bottom", []), + "3a_13-b_bottom---3a_13-b_top": RegionConnection("3a_13-b_bottom", "3a_13-b_top", []), + + "3a_13-a_west---3a_13-a_east": RegionConnection("3a_13-a_west", "3a_13-a_east", []), + "3a_13-a_west---3a_13-a_south-west": RegionConnection("3a_13-a_west", "3a_13-a_south-west", [[ItemName.pink_clutter, ], ]), + "3a_13-a_south-west---3a_13-a_west": RegionConnection("3a_13-a_south-west", "3a_13-a_west", [[ItemName.pink_clutter, ], ]), + + "3a_13-x_west---3a_13-x_east": RegionConnection("3a_13-x_west", "3a_13-x_east", []), + "3a_13-x_east---3a_13-x_west": RegionConnection("3a_13-x_east", "3a_13-x_west", []), + + "3a_12-x_west---3a_12-x_east": RegionConnection("3a_12-x_west", "3a_12-x_east", []), + "3a_12-x_north-east---3a_12-x_east": RegionConnection("3a_12-x_north-east", "3a_12-x_east", []), + "3a_12-x_east---3a_12-x_west": RegionConnection("3a_12-x_east", "3a_12-x_west", []), + + "3a_11-a_west---3a_11-a_south": RegionConnection("3a_11-a_west", "3a_11-a_south", []), + "3a_11-a_south---3a_11-a_west": RegionConnection("3a_11-a_south", "3a_11-a_west", []), + "3a_11-a_south-east-bottom---3a_11-a_south-east-right": RegionConnection("3a_11-a_south-east-bottom", "3a_11-a_south-east-right", [[ItemName.pink_clutter, ], ]), + "3a_11-a_south-east-right---3a_11-a_south-east-bottom": RegionConnection("3a_11-a_south-east-right", "3a_11-a_south-east-bottom", [[ItemName.pink_clutter, ], ]), + + "3a_08-x_west---3a_08-x_east": RegionConnection("3a_08-x_west", "3a_08-x_east", []), + "3a_08-x_east---3a_08-x_west": RegionConnection("3a_08-x_east", "3a_08-x_west", []), + + "3a_09-d_bottom---3a_09-d_top": RegionConnection("3a_09-d_bottom", "3a_09-d_top", []), + + "3a_08-d_east---3a_08-d_west": RegionConnection("3a_08-d_east", "3a_08-d_west", [[ItemName.dash_refills, ItemName.coins, ], ]), + + "3a_06-d_east---3a_06-d_west": RegionConnection("3a_06-d_east", "3a_06-d_west", [[ItemName.dash_refills, ], ]), + + "3a_04-d_west---3a_04-d_west": RegionConnection("3a_04-d_west", "3a_04-d_west", []), + "3a_04-d_south-west---3a_04-d_west": RegionConnection("3a_04-d_south-west", "3a_04-d_west", []), + "3a_04-d_south---3a_04-d_south-west": RegionConnection("3a_04-d_south", "3a_04-d_south-west", [[ItemName.cannot_access, ], ]), + "3a_04-d_east---3a_04-d_south": RegionConnection("3a_04-d_east", "3a_04-d_south", [[ItemName.dash_refills, ], ]), + + "3a_04-c_west---3a_04-c_north-west": RegionConnection("3a_04-c_west", "3a_04-c_north-west", [["Celestial Resort A - Presidential Suite Key", ], ]), + "3a_04-c_west---3a_04-c_east": RegionConnection("3a_04-c_west", "3a_04-c_east", []), + "3a_04-c_north-west---3a_04-c_west": RegionConnection("3a_04-c_north-west", "3a_04-c_west", [["Celestial Resort A - Presidential Suite Key", ], ]), + "3a_04-c_east---3a_04-c_west": RegionConnection("3a_04-c_east", "3a_04-c_west", []), + + "3a_02-c_west---3a_02-c_east": RegionConnection("3a_02-c_west", "3a_02-c_east", []), + "3a_02-c_east---3a_02-c_west": RegionConnection("3a_02-c_east", "3a_02-c_west", [[ItemName.sinking_platforms, ], ]), + "3a_02-c_east---3a_02-c_south-east": RegionConnection("3a_02-c_east", "3a_02-c_south-east", []), + "3a_02-c_south-east---3a_02-c_east": RegionConnection("3a_02-c_south-east", "3a_02-c_east", []), + + "3a_03-b_west---3a_03-b_east": RegionConnection("3a_03-b_west", "3a_03-b_east", []), + "3a_03-b_east---3a_03-b_west": RegionConnection("3a_03-b_east", "3a_03-b_west", []), + "3a_03-b_east---3a_03-b_north": RegionConnection("3a_03-b_east", "3a_03-b_north", []), + "3a_03-b_north---3a_03-b_east": RegionConnection("3a_03-b_north", "3a_03-b_east", []), + + + "3a_02-d_west---3a_02-d_east": RegionConnection("3a_02-d_west", "3a_02-d_east", [[ItemName.cannot_access, ], ]), + "3a_02-d_east---3a_02-d_west": RegionConnection("3a_02-d_east", "3a_02-d_west", [[ItemName.dash_refills, ], ]), + + "3a_00-d_west---3a_00-d_east": RegionConnection("3a_00-d_west", "3a_00-d_east", []), + "3a_00-d_east---3a_00-d_west": RegionConnection("3a_00-d_east", "3a_00-d_west", []), + + "3a_roof00_west---3a_roof00_east": RegionConnection("3a_roof00_west", "3a_roof00_east", []), + "3a_roof00_east---3a_roof00_west": RegionConnection("3a_roof00_east", "3a_roof00_west", []), + + "3a_roof01_west---3a_roof01_east": RegionConnection("3a_roof01_west", "3a_roof01_east", [[ItemName.springs, ], ]), + + "3a_roof02_west---3a_roof02_east": RegionConnection("3a_roof02_west", "3a_roof02_east", []), + "3a_roof02_east---3a_roof02_west": RegionConnection("3a_roof02_east", "3a_roof02_west", []), + + "3a_roof03_west---3a_roof03_east": RegionConnection("3a_roof03_west", "3a_roof03_east", [[ItemName.springs, ItemName.coins, ItemName.dash_refills, ], ]), + + "3a_roof04_west---3a_roof04_east": RegionConnection("3a_roof04_west", "3a_roof04_east", []), + "3a_roof04_east---3a_roof04_west": RegionConnection("3a_roof04_east", "3a_roof04_west", []), + + "3a_roof05_west---3a_roof05_east": RegionConnection("3a_roof05_west", "3a_roof05_east", [[ItemName.springs, ], ]), + + "3a_roof06b_west---3a_roof06b_east": RegionConnection("3a_roof06b_west", "3a_roof06b_east", [[ItemName.dash_refills, ], ]), + "3a_roof06b_east---3a_roof06b_west": RegionConnection("3a_roof06b_east", "3a_roof06b_west", [[ItemName.dash_refills, ], ]), + + "3a_roof06_west---3a_roof06_east": RegionConnection("3a_roof06_west", "3a_roof06_east", []), + "3a_roof06_east---3a_roof06_west": RegionConnection("3a_roof06_east", "3a_roof06_west", []), + + "3a_roof07_west---3a_roof07_main": RegionConnection("3a_roof07_west", "3a_roof07_main", []), + "3a_roof07_main---3a_roof07_west": RegionConnection("3a_roof07_main", "3a_roof07_west", []), + + "3b_00_west---3b_00_east": RegionConnection("3b_00_west", "3b_00_east", []), + "3b_00_east---3b_00_west": RegionConnection("3b_00_east", "3b_00_west", []), + + + "3b_01_west---3b_01_east": RegionConnection("3b_01_west", "3b_01_east", [[ItemName.dash_refills, ], ]), + "3b_01_east---3b_01_west": RegionConnection("3b_01_east", "3b_01_west", [[ItemName.dash_refills, ], ]), + + "3b_02_west---3b_02_east": RegionConnection("3b_02_west", "3b_02_east", []), + "3b_02_east---3b_02_west": RegionConnection("3b_02_east", "3b_02_west", []), + + "3b_03_west---3b_03_east": RegionConnection("3b_03_west", "3b_03_east", [[ItemName.dash_refills, ], ]), + "3b_03_east---3b_03_west": RegionConnection("3b_03_east", "3b_03_west", [[ItemName.dash_refills, ], ]), + + "3b_04_west---3b_04_east": RegionConnection("3b_04_west", "3b_04_east", [[ItemName.dash_refills, ], ]), + "3b_04_east---3b_04_west": RegionConnection("3b_04_east", "3b_04_west", [[ItemName.dash_refills, ], ]), + + "3b_05_west---3b_05_east": RegionConnection("3b_05_west", "3b_05_east", [[ItemName.moving_platforms, ItemName.coins, ItemName.springs, ], ]), + + "3b_06_west---3b_06_east": RegionConnection("3b_06_west", "3b_06_east", [[ItemName.sinking_platforms, ], ]), + "3b_06_east---3b_06_west": RegionConnection("3b_06_east", "3b_06_west", [[ItemName.sinking_platforms, ], ]), + + "3b_07_west---3b_07_east": RegionConnection("3b_07_west", "3b_07_east", []), + "3b_07_east---3b_07_west": RegionConnection("3b_07_east", "3b_07_west", []), + + "3b_08_bottom---3b_08_top": RegionConnection("3b_08_bottom", "3b_08_top", [[ItemName.dash_refills, ], ]), + "3b_08_top---3b_08_bottom": RegionConnection("3b_08_top", "3b_08_bottom", []), + + "3b_09_west---3b_09_east": RegionConnection("3b_09_west", "3b_09_east", []), + "3b_09_east---3b_09_east": RegionConnection("3b_09_east", "3b_09_east", []), + + "3b_10_west---3b_10_east": RegionConnection("3b_10_west", "3b_10_east", [[ItemName.dash_refills, ], ]), + + "3b_11_west---3b_11_east": RegionConnection("3b_11_west", "3b_11_east", [[ItemName.dash_refills, ], ]), + "3b_11_east---3b_11_west": RegionConnection("3b_11_east", "3b_11_west", [[ItemName.dash_refills, ], ]), + + "3b_13_west---3b_13_east": RegionConnection("3b_13_west", "3b_13_east", [[ItemName.springs, ], ]), + "3b_13_east---3b_13_west": RegionConnection("3b_13_east", "3b_13_west", [[ItemName.springs, ], ]), + + "3b_14_west---3b_14_east": RegionConnection("3b_14_west", "3b_14_east", [[ItemName.dash_refills, ], ]), + "3b_14_east---3b_14_west": RegionConnection("3b_14_east", "3b_14_west", [[ItemName.dash_refills, ], ]), + + "3b_15_west---3b_15_east": RegionConnection("3b_15_west", "3b_15_east", []), + "3b_15_east---3b_15_west": RegionConnection("3b_15_east", "3b_15_west", []), + + "3b_12_west---3b_12_east": RegionConnection("3b_12_west", "3b_12_east", [[ItemName.springs, ], ]), + "3b_12_east---3b_12_west": RegionConnection("3b_12_east", "3b_12_west", [[ItemName.springs, ], ]), + + "3b_16_west---3b_16_top": RegionConnection("3b_16_west", "3b_16_top", []), + "3b_16_top---3b_16_west": RegionConnection("3b_16_top", "3b_16_west", []), + + "3b_17_west---3b_17_east": RegionConnection("3b_17_west", "3b_17_east", [[ItemName.dash_refills, ItemName.springs, ], ]), + "3b_17_east---3b_17_west": RegionConnection("3b_17_east", "3b_17_west", [[ItemName.dash_refills, ItemName.springs, ], ]), + + "3b_18_west---3b_18_east": RegionConnection("3b_18_west", "3b_18_east", []), + "3b_18_east---3b_18_west": RegionConnection("3b_18_east", "3b_18_west", []), + + "3b_19_west---3b_19_east": RegionConnection("3b_19_west", "3b_19_east", [[ItemName.springs, ItemName.dash_refills, ], ]), + "3b_19_east---3b_19_west": RegionConnection("3b_19_east", "3b_19_west", [[ItemName.springs, ItemName.dash_refills, ], ]), + + "3b_21_west---3b_21_east": RegionConnection("3b_21_west", "3b_21_east", [[ItemName.dash_refills, ], ]), + "3b_21_east---3b_21_west": RegionConnection("3b_21_east", "3b_21_west", [[ItemName.dash_refills, ], ]), + + "3b_20_west---3b_20_east": RegionConnection("3b_20_west", "3b_20_east", [[ItemName.dash_refills, ItemName.coins, ], ]), + + "3b_end_west---3b_end_goal": RegionConnection("3b_end_west", "3b_end_goal", [[ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.dash_refills, ItemName.springs, ItemName.coins, ], ]), + + "3c_00_west---3c_00_east": RegionConnection("3c_00_west", "3c_00_east", [[ItemName.dash_refills, ], ]), + "3c_00_east---3c_00_west": RegionConnection("3c_00_east", "3c_00_west", [[ItemName.dash_refills, ], ]), + + "3c_01_west---3c_01_east": RegionConnection("3c_01_west", "3c_01_east", [[ItemName.sinking_platforms, ], ]), + + "3c_02_west---3c_02_goal": RegionConnection("3c_02_west", "3c_02_goal", [[ItemName.coins, ItemName.dash_refills, ], ]), + + "4a_a-00_west---4a_a-00_east": RegionConnection("4a_a-00_west", "4a_a-00_east", [[ItemName.blue_clouds, ], ]), + "4a_a-00_east---4a_a-00_west": RegionConnection("4a_a-00_east", "4a_a-00_west", []), + + "4a_a-01_west---4a_a-01_east": RegionConnection("4a_a-01_west", "4a_a-01_east", [[ItemName.blue_boosters, ], ]), + "4a_a-01_east---4a_a-01_west": RegionConnection("4a_a-01_east", "4a_a-01_west", [[ItemName.blue_boosters, ], ]), + + "4a_a-01x_west---4a_a-01x_east": RegionConnection("4a_a-01x_west", "4a_a-01x_east", [[ItemName.blue_boosters, ], ]), + "4a_a-01x_east---4a_a-01x_west": RegionConnection("4a_a-01x_east", "4a_a-01x_west", [[ItemName.blue_boosters, ], ]), + + "4a_a-02_west---4a_a-02_east": RegionConnection("4a_a-02_west", "4a_a-02_east", []), + "4a_a-02_east---4a_a-02_west": RegionConnection("4a_a-02_east", "4a_a-02_west", []), + + "4a_a-03_west---4a_a-03_east": RegionConnection("4a_a-03_west", "4a_a-03_east", [[ItemName.blue_boosters, ], ]), + "4a_a-03_east---4a_a-03_west": RegionConnection("4a_a-03_east", "4a_a-03_west", [[ItemName.blue_boosters, ], ]), + + "4a_a-04_west---4a_a-04_east": RegionConnection("4a_a-04_west", "4a_a-04_east", [[ItemName.blue_clouds, ItemName.pink_clouds, ], ]), + "4a_a-04_east---4a_a-04_west": RegionConnection("4a_a-04_east", "4a_a-04_west", [[ItemName.blue_clouds, ], ]), + + "4a_a-05_west---4a_a-05_east": RegionConnection("4a_a-05_west", "4a_a-05_east", [[ItemName.moving_platforms, ], ]), + "4a_a-05_east---4a_a-05_west": RegionConnection("4a_a-05_east", "4a_a-05_west", [[ItemName.moving_platforms, ], ]), + + "4a_a-06_west---4a_a-06_east": RegionConnection("4a_a-06_west", "4a_a-06_east", []), + "4a_a-06_east---4a_a-06_west": RegionConnection("4a_a-06_east", "4a_a-06_west", []), + + "4a_a-07_west---4a_a-07_east": RegionConnection("4a_a-07_west", "4a_a-07_east", [[ItemName.blue_boosters, ItemName.coins, ], ]), + + "4a_a-08_west---4a_a-08_north-west": RegionConnection("4a_a-08_west", "4a_a-08_north-west", [[ItemName.blue_clouds, ItemName.blue_boosters, ], ]), + "4a_a-08_west---4a_a-08_east": RegionConnection("4a_a-08_west", "4a_a-08_east", [[ItemName.blue_clouds, ], ]), + "4a_a-08_north-west---4a_a-08_west": RegionConnection("4a_a-08_north-west", "4a_a-08_west", []), + "4a_a-08_east---4a_a-08_west": RegionConnection("4a_a-08_east", "4a_a-08_west", [[ItemName.blue_clouds, ], ]), + + "4a_a-10_west---4a_a-10_east": RegionConnection("4a_a-10_west", "4a_a-10_east", []), + "4a_a-10_east---4a_a-10_west": RegionConnection("4a_a-10_east", "4a_a-10_west", []), + + + "4a_a-09_bottom---4a_a-09_top": RegionConnection("4a_a-09_bottom", "4a_a-09_top", []), + "4a_a-09_top---4a_a-09_bottom": RegionConnection("4a_a-09_top", "4a_a-09_bottom", []), + + "4a_b-00_south---4a_b-00_south-east": RegionConnection("4a_b-00_south", "4a_b-00_south-east", []), + "4a_b-00_south---4a_b-00_west": RegionConnection("4a_b-00_south", "4a_b-00_west", [[ItemName.move_blocks, ], ]), + "4a_b-00_south---4a_b-00_east": RegionConnection("4a_b-00_south", "4a_b-00_east", [[ItemName.move_blocks, ], ]), + "4a_b-00_south---4a_b-00_north-east": RegionConnection("4a_b-00_south", "4a_b-00_north-east", [[ItemName.move_blocks, ], ]), + "4a_b-00_south-east---4a_b-00_south": RegionConnection("4a_b-00_south-east", "4a_b-00_south", []), + "4a_b-00_east---4a_b-00_south": RegionConnection("4a_b-00_east", "4a_b-00_south", []), + "4a_b-00_east---4a_b-00_north-west": RegionConnection("4a_b-00_east", "4a_b-00_north-west", []), + "4a_b-00_west---4a_b-00_south": RegionConnection("4a_b-00_west", "4a_b-00_south", []), + "4a_b-00_west---4a_b-00_north-west": RegionConnection("4a_b-00_west", "4a_b-00_north-west", []), + "4a_b-00_north-west---4a_b-00_south": RegionConnection("4a_b-00_north-west", "4a_b-00_south", []), + "4a_b-00_north-west---4a_b-00_north": RegionConnection("4a_b-00_north-west", "4a_b-00_north", []), + "4a_b-00_north---4a_b-00_north-west": RegionConnection("4a_b-00_north", "4a_b-00_north-west", []), + + + "4a_b-04_north-west---4a_b-04_east": RegionConnection("4a_b-04_north-west", "4a_b-04_east", []), + "4a_b-04_east---4a_b-04_west": RegionConnection("4a_b-04_east", "4a_b-04_west", [[ItemName.move_blocks, ], ]), + + "4a_b-06_west---4a_b-06_east": RegionConnection("4a_b-06_west", "4a_b-06_east", [[ItemName.cannot_access, ], ]), + "4a_b-06_east---4a_b-06_west": RegionConnection("4a_b-06_east", "4a_b-06_west", [[ItemName.move_blocks, ItemName.blue_boosters, ], ]), + + "4a_b-07_west---4a_b-07_east": RegionConnection("4a_b-07_west", "4a_b-07_east", [[ItemName.move_blocks, ItemName.blue_boosters, ], ]), + + "4a_b-03_west---4a_b-03_east": RegionConnection("4a_b-03_west", "4a_b-03_east", []), + "4a_b-03_east---4a_b-03_west": RegionConnection("4a_b-03_east", "4a_b-03_west", []), + + "4a_b-02_north-west---4a_b-02_north-east": RegionConnection("4a_b-02_north-west", "4a_b-02_north-east", []), + "4a_b-02_north-west---4a_b-02_north": RegionConnection("4a_b-02_north-west", "4a_b-02_north", []), + "4a_b-02_north-east---4a_b-02_north-west": RegionConnection("4a_b-02_north-east", "4a_b-02_north-west", []), + "4a_b-02_north---4a_b-02_north-west": RegionConnection("4a_b-02_north", "4a_b-02_north-west", []), + + "4a_b-sec_west---4a_b-sec_east": RegionConnection("4a_b-sec_west", "4a_b-sec_east", []), + "4a_b-sec_east---4a_b-sec_west": RegionConnection("4a_b-sec_east", "4a_b-sec_west", []), + + + "4a_b-05_center---4a_b-05_west": RegionConnection("4a_b-05_center", "4a_b-05_west", [[ItemName.pink_clouds, ItemName.move_blocks, ], ]), + "4a_b-05_north-east---4a_b-05_east": RegionConnection("4a_b-05_north-east", "4a_b-05_east", []), + "4a_b-05_east---4a_b-05_north-east": RegionConnection("4a_b-05_east", "4a_b-05_north-east", [[ItemName.move_blocks, ], ]), + + "4a_b-08b_west---4a_b-08b_east": RegionConnection("4a_b-08b_west", "4a_b-08b_east", [[ItemName.move_blocks, ItemName.dash_refills, ], ]), + "4a_b-08b_east---4a_b-08b_west": RegionConnection("4a_b-08b_east", "4a_b-08b_west", [[ItemName.dash_refills, ], ]), + + "4a_b-08_west---4a_b-08_east": RegionConnection("4a_b-08_west", "4a_b-08_east", [[ItemName.move_blocks, ItemName.blue_clouds, ], ]), + + "4a_c-00_west---4a_c-00_east": RegionConnection("4a_c-00_west", "4a_c-00_east", [[ItemName.blue_boosters, ], ]), + "4a_c-00_west---4a_c-00_north-west": RegionConnection("4a_c-00_west", "4a_c-00_north-west", []), + "4a_c-00_east---4a_c-00_west": RegionConnection("4a_c-00_east", "4a_c-00_west", [[ItemName.blue_boosters, ], ]), + "4a_c-00_north-west---4a_c-00_west": RegionConnection("4a_c-00_north-west", "4a_c-00_west", []), + + + "4a_c-02_west---4a_c-02_east": RegionConnection("4a_c-02_west", "4a_c-02_east", [[ItemName.blue_boosters, ], ]), + "4a_c-02_east---4a_c-02_west": RegionConnection("4a_c-02_east", "4a_c-02_west", [[ItemName.blue_boosters, ], ]), + + "4a_c-04_west---4a_c-04_east": RegionConnection("4a_c-04_west", "4a_c-04_east", [[ItemName.pink_clouds, ], ]), + + "4a_c-05_west---4a_c-05_east": RegionConnection("4a_c-05_west", "4a_c-05_east", [[ItemName.blue_boosters, ItemName.move_blocks, ], ]), + "4a_c-05_east---4a_c-05_west": RegionConnection("4a_c-05_east", "4a_c-05_west", [[ItemName.cannot_access, ], ]), + + "4a_c-06_bottom---4a_c-06_west": RegionConnection("4a_c-06_bottom", "4a_c-06_west", [[ItemName.blue_boosters, ItemName.blue_clouds, ItemName.move_blocks, ], ]), + "4a_c-06_west---4a_c-06_bottom": RegionConnection("4a_c-06_west", "4a_c-06_bottom", []), + "4a_c-06_west---4a_c-06_top": RegionConnection("4a_c-06_west", "4a_c-06_top", [[ItemName.move_blocks, ], ]), + + + "4a_c-09_west---4a_c-09_east": RegionConnection("4a_c-09_west", "4a_c-09_east", [[ItemName.coins, ItemName.move_blocks, ], ]), + + "4a_c-07_west---4a_c-07_east": RegionConnection("4a_c-07_west", "4a_c-07_east", []), + + "4a_c-08_bottom---4a_c-08_east": RegionConnection("4a_c-08_bottom", "4a_c-08_east", [[ItemName.springs, ], ]), + "4a_c-08_east---4a_c-08_bottom": RegionConnection("4a_c-08_east", "4a_c-08_bottom", []), + "4a_c-08_east---4a_c-08_top": RegionConnection("4a_c-08_east", "4a_c-08_top", [[ItemName.blue_boosters, ], ]), + "4a_c-08_top---4a_c-08_east": RegionConnection("4a_c-08_top", "4a_c-08_east", []), + + "4a_c-10_bottom---4a_c-10_top": RegionConnection("4a_c-10_bottom", "4a_c-10_top", [[ItemName.blue_boosters, ], ]), + "4a_c-10_top---4a_c-10_bottom": RegionConnection("4a_c-10_top", "4a_c-10_bottom", [[ItemName.blue_boosters, ], ]), + + "4a_d-00_west---4a_d-00_east": RegionConnection("4a_d-00_west", "4a_d-00_east", []), + "4a_d-00_west---4a_d-00_south": RegionConnection("4a_d-00_west", "4a_d-00_south", []), + "4a_d-00_west---4a_d-00_north-west": RegionConnection("4a_d-00_west", "4a_d-00_north-west", []), + "4a_d-00_south---4a_d-00_west": RegionConnection("4a_d-00_south", "4a_d-00_west", []), + "4a_d-00_east---4a_d-00_west": RegionConnection("4a_d-00_east", "4a_d-00_west", []), + "4a_d-00_north-west---4a_d-00_west": RegionConnection("4a_d-00_north-west", "4a_d-00_west", []), + + + "4a_d-01_west---4a_d-01_east": RegionConnection("4a_d-01_west", "4a_d-01_east", []), + "4a_d-01_east---4a_d-01_west": RegionConnection("4a_d-01_east", "4a_d-01_west", []), + + "4a_d-02_west---4a_d-02_east": RegionConnection("4a_d-02_west", "4a_d-02_east", [[ItemName.move_blocks, ItemName.coins, ItemName.pink_clouds, ItemName.blue_boosters, ], ]), + + "4a_d-03_west---4a_d-03_east": RegionConnection("4a_d-03_west", "4a_d-03_east", []), + "4a_d-03_east---4a_d-03_west": RegionConnection("4a_d-03_east", "4a_d-03_west", []), + + "4a_d-04_west---4a_d-04_east": RegionConnection("4a_d-04_west", "4a_d-04_east", []), + "4a_d-04_east---4a_d-04_west": RegionConnection("4a_d-04_east", "4a_d-04_west", []), + + "4a_d-05_west---4a_d-05_east": RegionConnection("4a_d-05_west", "4a_d-05_east", []), + "4a_d-05_east---4a_d-05_west": RegionConnection("4a_d-05_east", "4a_d-05_west", []), + + "4a_d-06_west---4a_d-06_east": RegionConnection("4a_d-06_west", "4a_d-06_east", [[ItemName.blue_boosters, ], ]), + "4a_d-06_east---4a_d-06_west": RegionConnection("4a_d-06_east", "4a_d-06_west", []), + + "4a_d-07_west---4a_d-07_east": RegionConnection("4a_d-07_west", "4a_d-07_east", [[ItemName.blue_boosters, ], ]), + "4a_d-07_east---4a_d-07_west": RegionConnection("4a_d-07_east", "4a_d-07_west", [[ItemName.blue_boosters, ], ]), + + "4a_d-08_west---4a_d-08_east": RegionConnection("4a_d-08_west", "4a_d-08_east", [[ItemName.blue_clouds, ItemName.blue_boosters, ], ]), + + "4a_d-09_west---4a_d-09_east": RegionConnection("4a_d-09_west", "4a_d-09_east", [[ItemName.blue_boosters, ], ]), + "4a_d-09_east---4a_d-09_west": RegionConnection("4a_d-09_east", "4a_d-09_west", [[ItemName.blue_boosters, ], ]), + + "4a_d-10_west---4a_d-10_goal": RegionConnection("4a_d-10_west", "4a_d-10_goal", []), + + "4b_a-00_west---4b_a-00_east": RegionConnection("4b_a-00_west", "4b_a-00_east", [[ItemName.blue_boosters, ], ]), + "4b_a-00_east---4b_a-00_west": RegionConnection("4b_a-00_east", "4b_a-00_west", [[ItemName.blue_boosters, ], ]), + + "4b_a-01_west---4b_a-01_east": RegionConnection("4b_a-01_west", "4b_a-01_east", [[ItemName.moving_platforms, ], ]), + "4b_a-01_east---4b_a-01_west": RegionConnection("4b_a-01_east", "4b_a-01_west", [[ItemName.moving_platforms, ], ]), + + "4b_a-02_west---4b_a-02_east": RegionConnection("4b_a-02_west", "4b_a-02_east", [[ItemName.blue_boosters, ], ]), + + "4b_a-03_west---4b_a-03_east": RegionConnection("4b_a-03_west", "4b_a-03_east", [[ItemName.springs, ItemName.move_blocks, ItemName.blue_boosters, ], ]), + + "4b_a-04_west---4b_a-04_east": RegionConnection("4b_a-04_west", "4b_a-04_east", [[ItemName.move_blocks, ItemName.blue_boosters, ], ]), + + "4b_b-00_west---4b_b-00_east": RegionConnection("4b_b-00_west", "4b_b-00_east", [[ItemName.blue_boosters, ], ]), + + "4b_b-01_west---4b_b-01_east": RegionConnection("4b_b-01_west", "4b_b-01_east", [[ItemName.blue_boosters, ], ]), + "4b_b-01_east---4b_b-01_west": RegionConnection("4b_b-01_east", "4b_b-01_west", [[ItemName.cannot_access, ], ]), + + "4b_b-02_bottom---4b_b-02_top": RegionConnection("4b_b-02_bottom", "4b_b-02_top", [[ItemName.move_blocks, ItemName.springs, ItemName.dash_refills, ], ]), + "4b_b-02_top---4b_b-02_bottom": RegionConnection("4b_b-02_top", "4b_b-02_bottom", []), + + "4b_b-03_west---4b_b-03_east": RegionConnection("4b_b-03_west", "4b_b-03_east", [[ItemName.coins, ItemName.moving_platforms, ItemName.springs, ItemName.blue_boosters, ], ]), + + "4b_b-04_west---4b_b-04_east": RegionConnection("4b_b-04_west", "4b_b-04_east", [[ItemName.blue_boosters, ], ]), + + "4b_c-00_west---4b_c-00_east": RegionConnection("4b_c-00_west", "4b_c-00_east", [[ItemName.blue_boosters, ], ]), + + "4b_c-01_west---4b_c-01_east": RegionConnection("4b_c-01_west", "4b_c-01_east", [[ItemName.moving_platforms, ], ]), + "4b_c-01_east---4b_c-01_west": RegionConnection("4b_c-01_east", "4b_c-01_west", [[ItemName.cannot_access, ], ]), + + "4b_c-02_west---4b_c-02_east": RegionConnection("4b_c-02_west", "4b_c-02_east", [[ItemName.move_blocks, ], ]), + + "4b_c-03_bottom---4b_c-03_top": RegionConnection("4b_c-03_bottom", "4b_c-03_top", [[ItemName.move_blocks, ItemName.blue_clouds, ], ]), + "4b_c-03_top---4b_c-03_bottom": RegionConnection("4b_c-03_top", "4b_c-03_bottom", [[ItemName.blue_clouds, ], ]), + + "4b_c-04_west---4b_c-04_east": RegionConnection("4b_c-04_west", "4b_c-04_east", [[ItemName.blue_boosters, ], ]), + "4b_c-04_east---4b_c-04_west": RegionConnection("4b_c-04_east", "4b_c-04_west", []), + + "4b_d-00_west---4b_d-00_east": RegionConnection("4b_d-00_west", "4b_d-00_east", [[ItemName.blue_clouds, ], ]), + "4b_d-00_east---4b_d-00_west": RegionConnection("4b_d-00_east", "4b_d-00_west", [[ItemName.blue_clouds, ], ]), + + "4b_d-01_west---4b_d-01_east": RegionConnection("4b_d-01_west", "4b_d-01_east", [[ItemName.pink_clouds, ItemName.blue_boosters, ], ]), + "4b_d-01_east---4b_d-01_west": RegionConnection("4b_d-01_east", "4b_d-01_west", [[ItemName.cannot_access, ], ]), + + "4b_d-02_west---4b_d-02_east": RegionConnection("4b_d-02_west", "4b_d-02_east", [[ItemName.dash_refills, ItemName.blue_boosters, ItemName.coins, ], ]), + "4b_d-02_east---4b_d-02_west": RegionConnection("4b_d-02_east", "4b_d-02_west", [[ItemName.cannot_access, ], ]), + + "4b_d-03_west---4b_d-03_east": RegionConnection("4b_d-03_west", "4b_d-03_east", [[ItemName.blue_boosters, ], ]), + + "4b_end_west---4b_end_goal": RegionConnection("4b_end_west", "4b_end_goal", [[ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.dash_refills, ItemName.blue_boosters, ], ]), + + "4c_00_west---4c_00_east": RegionConnection("4c_00_west", "4c_00_east", [[ItemName.blue_boosters, ], ]), + + "4c_01_west---4c_01_east": RegionConnection("4c_01_west", "4c_01_east", [[ItemName.move_blocks, ItemName.dash_refills, ], ]), + "4c_01_east---4c_01_west": RegionConnection("4c_01_east", "4c_01_west", [[ItemName.cannot_access, ], ]), + + "4c_02_west---4c_02_goal": RegionConnection("4c_02_west", "4c_02_goal", [[ItemName.pink_clouds, ItemName.blue_boosters, ItemName.move_blocks, ], ]), + + "5a_a-00b_west---5a_a-00b_east": RegionConnection("5a_a-00b_west", "5a_a-00b_east", []), + "5a_a-00b_east---5a_a-00b_west": RegionConnection("5a_a-00b_east", "5a_a-00b_west", []), + + + "5a_a-00d_west---5a_a-00d_east": RegionConnection("5a_a-00d_west", "5a_a-00d_east", []), + "5a_a-00d_east---5a_a-00d_west": RegionConnection("5a_a-00d_east", "5a_a-00d_west", []), + + "5a_a-00c_west---5a_a-00c_east": RegionConnection("5a_a-00c_west", "5a_a-00c_east", []), + "5a_a-00c_east---5a_a-00c_west": RegionConnection("5a_a-00c_east", "5a_a-00c_west", []), + + "5a_a-00_west---5a_a-00_east": RegionConnection("5a_a-00_west", "5a_a-00_east", [[ItemName.red_boosters, ItemName.dash_switches, ], ]), + + "5a_a-01_west---5a_a-01_center": RegionConnection("5a_a-01_west", "5a_a-01_center", []), + "5a_a-01_center---5a_a-01_west": RegionConnection("5a_a-01_center", "5a_a-01_west", []), + "5a_a-01_center---5a_a-01_east": RegionConnection("5a_a-01_center", "5a_a-01_east", []), + "5a_a-01_center---5a_a-01_south-west": RegionConnection("5a_a-01_center", "5a_a-01_south-west", [[ItemName.swap_blocks, ], ]), + "5a_a-01_center---5a_a-01_south-east": RegionConnection("5a_a-01_center", "5a_a-01_south-east", [[ItemName.swap_blocks, ], ]), + "5a_a-01_center---5a_a-01_north": RegionConnection("5a_a-01_center", "5a_a-01_north", [[ItemName.red_boosters, ], ]), + "5a_a-01_east---5a_a-01_center": RegionConnection("5a_a-01_east", "5a_a-01_center", []), + "5a_a-01_south-west---5a_a-01_center": RegionConnection("5a_a-01_south-west", "5a_a-01_center", []), + "5a_a-01_south-east---5a_a-01_center": RegionConnection("5a_a-01_south-east", "5a_a-01_center", []), + "5a_a-01_north---5a_a-01_center": RegionConnection("5a_a-01_north", "5a_a-01_center", []), + + "5a_a-02_west---5a_a-02_north": RegionConnection("5a_a-02_west", "5a_a-02_north", []), + "5a_a-02_west---5a_a-02_south": RegionConnection("5a_a-02_west", "5a_a-02_south", []), + "5a_a-02_north---5a_a-02_west": RegionConnection("5a_a-02_north", "5a_a-02_west", []), + "5a_a-02_south---5a_a-02_west": RegionConnection("5a_a-02_south", "5a_a-02_west", []), + + "5a_a-03_west---5a_a-03_east": RegionConnection("5a_a-03_west", "5a_a-03_east", []), + "5a_a-03_east---5a_a-03_west": RegionConnection("5a_a-03_east", "5a_a-03_west", []), + + "5a_a-04_east---5a_a-04_north": RegionConnection("5a_a-04_east", "5a_a-04_north", []), + "5a_a-04_east---5a_a-04_south": RegionConnection("5a_a-04_east", "5a_a-04_south", []), + "5a_a-04_north---5a_a-04_east": RegionConnection("5a_a-04_north", "5a_a-04_east", []), + "5a_a-04_south---5a_a-04_east": RegionConnection("5a_a-04_south", "5a_a-04_east", []), + + "5a_a-05_north-west---5a_a-05_center": RegionConnection("5a_a-05_north-west", "5a_a-05_center", []), + "5a_a-05_center---5a_a-05_north-west": RegionConnection("5a_a-05_center", "5a_a-05_north-west", []), + "5a_a-05_center---5a_a-05_north-east": RegionConnection("5a_a-05_center", "5a_a-05_north-east", []), + "5a_a-05_center---5a_a-05_south-west": RegionConnection("5a_a-05_center", "5a_a-05_south-west", [[ItemName.swap_blocks, ], ]), + "5a_a-05_center---5a_a-05_south-east": RegionConnection("5a_a-05_center", "5a_a-05_south-east", [[ItemName.swap_blocks, ], ]), + "5a_a-05_north-east---5a_a-05_center": RegionConnection("5a_a-05_north-east", "5a_a-05_center", []), + "5a_a-05_south-west---5a_a-05_center": RegionConnection("5a_a-05_south-west", "5a_a-05_center", [[ItemName.dash_switches, ], ]), + "5a_a-05_south-east---5a_a-05_center": RegionConnection("5a_a-05_south-east", "5a_a-05_center", [[ItemName.dash_switches, ], ]), + + + + "5a_a-08_west---5a_a-08_center": RegionConnection("5a_a-08_west", "5a_a-08_center", []), + "5a_a-08_center---5a_a-08_west": RegionConnection("5a_a-08_center", "5a_a-08_west", []), + "5a_a-08_center---5a_a-08_north-east": RegionConnection("5a_a-08_center", "5a_a-08_north-east", [[ItemName.red_boosters, ItemName.swap_blocks, ], ]), + "5a_a-08_center---5a_a-08_south": RegionConnection("5a_a-08_center", "5a_a-08_south", []), + "5a_a-08_center---5a_a-08_north": RegionConnection("5a_a-08_center", "5a_a-08_north", [[ItemName.swap_blocks, ], ]), + "5a_a-08_east---5a_a-08_south-east": RegionConnection("5a_a-08_east", "5a_a-08_south-east", []), + "5a_a-08_south---5a_a-08_center": RegionConnection("5a_a-08_south", "5a_a-08_center", []), + "5a_a-08_south-east---5a_a-08_center": RegionConnection("5a_a-08_south-east", "5a_a-08_center", [[ItemName.dash_switches, ], ]), + "5a_a-08_south-east---5a_a-08_east": RegionConnection("5a_a-08_south-east", "5a_a-08_east", []), + "5a_a-08_north-east---5a_a-08_center": RegionConnection("5a_a-08_north-east", "5a_a-08_center", []), + "5a_a-08_north---5a_a-08_center": RegionConnection("5a_a-08_north", "5a_a-08_center", []), + + "5a_a-10_west---5a_a-10_east": RegionConnection("5a_a-10_west", "5a_a-10_east", [[ItemName.swap_blocks, ], ]), + "5a_a-10_east---5a_a-10_west": RegionConnection("5a_a-10_east", "5a_a-10_west", [[ItemName.swap_blocks, ], ]), + + "5a_a-09_west---5a_a-09_east": RegionConnection("5a_a-09_west", "5a_a-09_east", [[ItemName.red_boosters, ], ]), + "5a_a-09_east---5a_a-09_west": RegionConnection("5a_a-09_east", "5a_a-09_west", [[ItemName.red_boosters, ], ]), + + + "5a_a-12_north-west---5a_a-12_west": RegionConnection("5a_a-12_north-west", "5a_a-12_west", [[ItemName.red_boosters, ], ]), + "5a_a-12_south-west---5a_a-12_east": RegionConnection("5a_a-12_south-west", "5a_a-12_east", [[ItemName.red_boosters, ItemName.dash_switches, ], ]), + + + + "5a_a-13_west---5a_a-13_east": RegionConnection("5a_a-13_west", "5a_a-13_east", [["Mirror Temple A - Entrance Key", ], ]), + "5a_a-13_east---5a_a-13_west": RegionConnection("5a_a-13_east", "5a_a-13_west", [["Mirror Temple A - Entrance Key", ], ]), + + "5a_b-00_west---5a_b-00_east": RegionConnection("5a_b-00_west", "5a_b-00_east", [[ItemName.dash_switches, ], ]), + "5a_b-00_west---5a_b-00_north-west": RegionConnection("5a_b-00_west", "5a_b-00_north-west", []), + "5a_b-00_north-west---5a_b-00_west": RegionConnection("5a_b-00_north-west", "5a_b-00_west", []), + + + "5a_b-01_south-west---5a_b-01_center": RegionConnection("5a_b-01_south-west", "5a_b-01_center", []), + "5a_b-01_center---5a_b-01_south-west": RegionConnection("5a_b-01_center", "5a_b-01_south-west", []), + "5a_b-01_center---5a_b-01_west": RegionConnection("5a_b-01_center", "5a_b-01_west", [[ItemName.swap_blocks, ], ]), + "5a_b-01_center---5a_b-01_north-west": RegionConnection("5a_b-01_center", "5a_b-01_north-west", []), + "5a_b-01_center---5a_b-01_north": RegionConnection("5a_b-01_center", "5a_b-01_north", []), + "5a_b-01_center---5a_b-01_north-east": RegionConnection("5a_b-01_center", "5a_b-01_north-east", []), + "5a_b-01_center---5a_b-01_east": RegionConnection("5a_b-01_center", "5a_b-01_east", [[ItemName.swap_blocks, ], ]), + "5a_b-01_center---5a_b-01_south-east": RegionConnection("5a_b-01_center", "5a_b-01_south-east", []), + "5a_b-01_center---5a_b-01_south": RegionConnection("5a_b-01_center", "5a_b-01_south", []), + "5a_b-01_west---5a_b-01_center": RegionConnection("5a_b-01_west", "5a_b-01_center", [[ItemName.swap_blocks, ], ]), + "5a_b-01_north-west---5a_b-01_center": RegionConnection("5a_b-01_north-west", "5a_b-01_center", []), + "5a_b-01_north---5a_b-01_center": RegionConnection("5a_b-01_north", "5a_b-01_center", []), + "5a_b-01_north-east---5a_b-01_center": RegionConnection("5a_b-01_north-east", "5a_b-01_center", []), + "5a_b-01_east---5a_b-01_center": RegionConnection("5a_b-01_east", "5a_b-01_center", []), + "5a_b-01_south-east---5a_b-01_center": RegionConnection("5a_b-01_south-east", "5a_b-01_center", []), + "5a_b-01_south---5a_b-01_center": RegionConnection("5a_b-01_south", "5a_b-01_center", []), + + "5a_b-01c_west---5a_b-01c_east": RegionConnection("5a_b-01c_west", "5a_b-01c_east", [[ItemName.swap_blocks, ], ]), + "5a_b-01c_east---5a_b-01c_west": RegionConnection("5a_b-01c_east", "5a_b-01c_west", [[ItemName.cannot_access, ], ]), + + "5a_b-20_north-west---5a_b-20_west": RegionConnection("5a_b-20_north-west", "5a_b-20_west", []), + "5a_b-20_west---5a_b-20_north-west": RegionConnection("5a_b-20_west", "5a_b-20_north-west", []), + "5a_b-20_west---5a_b-20_south-west": RegionConnection("5a_b-20_west", "5a_b-20_south-west", []), + "5a_b-20_south-west---5a_b-20_west": RegionConnection("5a_b-20_south-west", "5a_b-20_west", []), + + + "5a_b-01b_west---5a_b-01b_east": RegionConnection("5a_b-01b_west", "5a_b-01b_east", [[ItemName.swap_blocks, ], ]), + "5a_b-01b_east---5a_b-01b_west": RegionConnection("5a_b-01b_east", "5a_b-01b_west", [[ItemName.swap_blocks, ], ]), + + "5a_b-02_center---5a_b-02_west": RegionConnection("5a_b-02_center", "5a_b-02_west", []), + "5a_b-02_center---5a_b-02_north-west": RegionConnection("5a_b-02_center", "5a_b-02_north-west", [[ItemName.red_boosters, ], ]), + "5a_b-02_center---5a_b-02_north": RegionConnection("5a_b-02_center", "5a_b-02_north", [[ItemName.red_boosters, ], ]), + "5a_b-02_center---5a_b-02_north-east": RegionConnection("5a_b-02_center", "5a_b-02_north-east", [[ItemName.red_boosters, ], ]), + "5a_b-02_center---5a_b-02_east-upper": RegionConnection("5a_b-02_center", "5a_b-02_east-upper", []), + "5a_b-02_center---5a_b-02_east-lower": RegionConnection("5a_b-02_center", "5a_b-02_east-lower", [[ItemName.red_boosters, ], ]), + "5a_b-02_center---5a_b-02_south-east": RegionConnection("5a_b-02_center", "5a_b-02_south-east", []), + "5a_b-02_center---5a_b-02_south": RegionConnection("5a_b-02_center", "5a_b-02_south", []), + "5a_b-02_west---5a_b-02_center": RegionConnection("5a_b-02_west", "5a_b-02_center", []), + "5a_b-02_north-west---5a_b-02_center": RegionConnection("5a_b-02_north-west", "5a_b-02_center", []), + "5a_b-02_north---5a_b-02_center": RegionConnection("5a_b-02_north", "5a_b-02_center", []), + "5a_b-02_north-east---5a_b-02_center": RegionConnection("5a_b-02_north-east", "5a_b-02_center", []), + "5a_b-02_east-upper---5a_b-02_center": RegionConnection("5a_b-02_east-upper", "5a_b-02_center", []), + "5a_b-02_east-lower---5a_b-02_center": RegionConnection("5a_b-02_east-lower", "5a_b-02_center", []), + "5a_b-02_south-east---5a_b-02_center": RegionConnection("5a_b-02_south-east", "5a_b-02_center", []), + "5a_b-02_south---5a_b-02_center": RegionConnection("5a_b-02_south", "5a_b-02_center", []), + + + + "5a_b-04_west---5a_b-04_south": RegionConnection("5a_b-04_west", "5a_b-04_south", []), + "5a_b-04_east---5a_b-04_south": RegionConnection("5a_b-04_east", "5a_b-04_south", []), + "5a_b-04_south---5a_b-04_west": RegionConnection("5a_b-04_south", "5a_b-04_west", []), + + "5a_b-07_north---5a_b-07_south": RegionConnection("5a_b-07_north", "5a_b-07_south", []), + "5a_b-07_south---5a_b-07_north": RegionConnection("5a_b-07_south", "5a_b-07_north", [[ItemName.dash_refills, ], ]), + + "5a_b-08_west---5a_b-08_east": RegionConnection("5a_b-08_west", "5a_b-08_east", [[ItemName.dash_refills, ], ]), + "5a_b-08_east---5a_b-08_west": RegionConnection("5a_b-08_east", "5a_b-08_west", [[ItemName.cannot_access, ], ]), + + "5a_b-09_north---5a_b-09_south": RegionConnection("5a_b-09_north", "5a_b-09_south", [[ItemName.red_boosters, ItemName.dash_switches, ], ]), + "5a_b-09_south---5a_b-09_north": RegionConnection("5a_b-09_south", "5a_b-09_north", [[ItemName.cannot_access, ], ]), + + + "5a_b-11_north-west---5a_b-11_west": RegionConnection("5a_b-11_north-west", "5a_b-11_west", []), + "5a_b-11_north-west---5a_b-11_east": RegionConnection("5a_b-11_north-west", "5a_b-11_east", [[ItemName.dash_switches, ], ]), + "5a_b-11_west---5a_b-11_south-west": RegionConnection("5a_b-11_west", "5a_b-11_south-west", []), + "5a_b-11_south-west---5a_b-11_west": RegionConnection("5a_b-11_south-west", "5a_b-11_west", []), + "5a_b-11_south-west---5a_b-11_south-east": RegionConnection("5a_b-11_south-west", "5a_b-11_south-east", []), + "5a_b-11_south-east---5a_b-11_south-west": RegionConnection("5a_b-11_south-east", "5a_b-11_south-west", []), + "5a_b-11_east---5a_b-11_west": RegionConnection("5a_b-11_east", "5a_b-11_west", [[ItemName.cannot_access, ], ]), + + "5a_b-12_west---5a_b-12_east": RegionConnection("5a_b-12_west", "5a_b-12_east", []), + "5a_b-12_east---5a_b-12_west": RegionConnection("5a_b-12_east", "5a_b-12_west", []), + + "5a_b-13_west---5a_b-13_north-east": RegionConnection("5a_b-13_west", "5a_b-13_north-east", [[ItemName.swap_blocks, ], ]), + "5a_b-13_west---5a_b-13_east": RegionConnection("5a_b-13_west", "5a_b-13_east", [[ItemName.dash_switches, ItemName.swap_blocks, ], ]), + "5a_b-13_north-east---5a_b-13_west": RegionConnection("5a_b-13_north-east", "5a_b-13_west", []), + + "5a_b-17_west---5a_b-17_east": RegionConnection("5a_b-17_west", "5a_b-17_east", []), + "5a_b-17_east---5a_b-17_west": RegionConnection("5a_b-17_east", "5a_b-17_west", []), + + + "5a_b-06_west---5a_b-06_north-east": RegionConnection("5a_b-06_west", "5a_b-06_north-east", [[ItemName.red_boosters, ], ]), + "5a_b-06_west---5a_b-06_east": RegionConnection("5a_b-06_west", "5a_b-06_east", [[ItemName.red_boosters, "Mirror Temple A - Depths Key", ], ]), + "5a_b-06_east---5a_b-06_west": RegionConnection("5a_b-06_east", "5a_b-06_west", [[ItemName.red_boosters, "Mirror Temple A - Depths Key", ], ]), + + "5a_b-19_west---5a_b-19_north-west": RegionConnection("5a_b-19_west", "5a_b-19_north-west", []), + "5a_b-19_west---5a_b-19_east": RegionConnection("5a_b-19_west", "5a_b-19_east", [[ItemName.red_boosters, ItemName.dash_refills, ], ]), + "5a_b-19_north-west---5a_b-19_west": RegionConnection("5a_b-19_north-west", "5a_b-19_west", []), + + "5a_b-14_west---5a_b-14_north": RegionConnection("5a_b-14_west", "5a_b-14_north", []), + "5a_b-14_west---5a_b-14_south": RegionConnection("5a_b-14_west", "5a_b-14_south", [["Mirror Temple A - Depths Key", ], ]), + "5a_b-14_south---5a_b-14_west": RegionConnection("5a_b-14_south", "5a_b-14_west", [["Mirror Temple A - Depths Key", ], ]), + "5a_b-14_north---5a_b-14_west": RegionConnection("5a_b-14_north", "5a_b-14_west", []), + + + "5a_b-16_bottom---5a_b-16_mirror": RegionConnection("5a_b-16_bottom", "5a_b-16_mirror", [[ItemName.red_boosters, ItemName.dash_switches, ], ]), + + "5a_void_east---5a_void_west": RegionConnection("5a_void_east", "5a_void_west", []), + "5a_void_west---5a_void_east": RegionConnection("5a_void_west", "5a_void_east", []), + + "5a_c-00_top---5a_c-00_bottom": RegionConnection("5a_c-00_top", "5a_c-00_bottom", []), + + "5a_c-01_west---5a_c-01_east": RegionConnection("5a_c-01_west", "5a_c-01_east", []), + "5a_c-01_east---5a_c-01_west": RegionConnection("5a_c-01_east", "5a_c-01_west", []), + + "5a_c-01b_west---5a_c-01b_east": RegionConnection("5a_c-01b_west", "5a_c-01b_east", [[ItemName.swap_blocks, ItemName.red_boosters, ItemName.dash_switches, ], ]), + + "5a_c-01c_west---5a_c-01c_east": RegionConnection("5a_c-01c_west", "5a_c-01c_east", [[ItemName.swap_blocks, ItemName.red_boosters, ], ]), + + "5a_c-08b_west---5a_c-08b_east": RegionConnection("5a_c-08b_west", "5a_c-08b_east", [[ItemName.dash_switches, ], ]), + + "5a_c-08_west---5a_c-08_east": RegionConnection("5a_c-08_west", "5a_c-08_east", []), + + "5a_c-10_west---5a_c-10_east": RegionConnection("5a_c-10_west", "5a_c-10_east", [[ItemName.coins, ], ]), + + "5a_c-12_west---5a_c-12_east": RegionConnection("5a_c-12_west", "5a_c-12_east", [[ItemName.coins, ], ]), + + "5a_c-07_west---5a_c-07_east": RegionConnection("5a_c-07_west", "5a_c-07_east", [[ItemName.coins, ], ]), + + "5a_c-11_west---5a_c-11_east": RegionConnection("5a_c-11_west", "5a_c-11_east", []), + "5a_c-11_east---5a_c-11_east": RegionConnection("5a_c-11_east", "5a_c-11_east", []), + + "5a_c-09_west---5a_c-09_east": RegionConnection("5a_c-09_west", "5a_c-09_east", [[ItemName.coins, ], ]), + + "5a_c-13_west---5a_c-13_east": RegionConnection("5a_c-13_west", "5a_c-13_east", [[ItemName.coins, ], ]), + + "5a_d-00_south---5a_d-00_north": RegionConnection("5a_d-00_south", "5a_d-00_north", [[ItemName.red_boosters, ], ]), + "5a_d-00_east---5a_d-00_west": RegionConnection("5a_d-00_east", "5a_d-00_west", [[ItemName.red_boosters, ], ]), + + "5a_d-01_south---5a_d-01_center": RegionConnection("5a_d-01_south", "5a_d-01_center", []), + "5a_d-01_center---5a_d-01_south": RegionConnection("5a_d-01_center", "5a_d-01_south", []), + "5a_d-01_center---5a_d-01_south-east-down": RegionConnection("5a_d-01_center", "5a_d-01_south-east-down", []), + "5a_d-01_center---5a_d-01_west": RegionConnection("5a_d-01_center", "5a_d-01_west", []), + "5a_d-01_center---5a_d-01_east": RegionConnection("5a_d-01_center", "5a_d-01_east", []), + "5a_d-01_center---5a_d-01_north-west": RegionConnection("5a_d-01_center", "5a_d-01_north-west", []), + "5a_d-01_center---5a_d-01_north-east": RegionConnection("5a_d-01_center", "5a_d-01_north-east", []), + "5a_d-01_south-west-left---5a_d-01_south-west-down": RegionConnection("5a_d-01_south-west-left", "5a_d-01_south-west-down", []), + "5a_d-01_south-west-down---5a_d-01_center": RegionConnection("5a_d-01_south-west-down", "5a_d-01_center", []), + "5a_d-01_south-west-down---5a_d-01_south-west-left": RegionConnection("5a_d-01_south-west-down", "5a_d-01_south-west-left", []), + "5a_d-01_south-east-right---5a_d-01_south-east-down": RegionConnection("5a_d-01_south-east-right", "5a_d-01_south-east-down", []), + "5a_d-01_south-east-down---5a_d-01_center": RegionConnection("5a_d-01_south-east-down", "5a_d-01_center", []), + "5a_d-01_south-east-down---5a_d-01_south-east-right": RegionConnection("5a_d-01_south-east-down", "5a_d-01_south-east-right", [[ItemName.seekers, ], ]), + "5a_d-01_west---5a_d-01_center": RegionConnection("5a_d-01_west", "5a_d-01_center", []), + "5a_d-01_east---5a_d-01_center": RegionConnection("5a_d-01_east", "5a_d-01_center", []), + "5a_d-01_north-west---5a_d-01_center": RegionConnection("5a_d-01_north-west", "5a_d-01_center", []), + "5a_d-01_north-east---5a_d-01_center": RegionConnection("5a_d-01_north-east", "5a_d-01_center", []), + + "5a_d-09_east---5a_d-09_west": RegionConnection("5a_d-09_east", "5a_d-09_west", [[ItemName.red_boosters, ItemName.dash_refills, ItemName.swap_blocks, ], ]), + + "5a_d-04_east---5a_d-04_west": RegionConnection("5a_d-04_east", "5a_d-04_west", [[ItemName.red_boosters, "Mirror Temple A - Search Key 1", "Mirror Temple A - Search Key 2", ], ]), + "5a_d-04_east---5a_d-04_south-east": RegionConnection("5a_d-04_east", "5a_d-04_south-east", []), + "5a_d-04_south-west-left---5a_d-04_east": RegionConnection("5a_d-04_south-west-left", "5a_d-04_east", []), + "5a_d-04_south-west-right---5a_d-04_east": RegionConnection("5a_d-04_south-west-right", "5a_d-04_east", []), + "5a_d-04_north---5a_d-04_east": RegionConnection("5a_d-04_north", "5a_d-04_east", []), + + "5a_d-05_north---5a_d-05_west": RegionConnection("5a_d-05_north", "5a_d-05_west", [[ItemName.red_boosters, ItemName.swap_blocks, ], ]), + "5a_d-05_east---5a_d-05_south": RegionConnection("5a_d-05_east", "5a_d-05_south", []), + "5a_d-05_south---5a_d-05_east": RegionConnection("5a_d-05_south", "5a_d-05_east", []), + + "5a_d-06_south-east---5a_d-06_north-east": RegionConnection("5a_d-06_south-east", "5a_d-06_north-east", [[ItemName.red_boosters, ItemName.swap_blocks, ], ]), + "5a_d-06_south-west---5a_d-06_north-west": RegionConnection("5a_d-06_south-west", "5a_d-06_north-west", [[ItemName.springs, ], ]), + "5a_d-06_north-west---5a_d-06_south-west": RegionConnection("5a_d-06_north-west", "5a_d-06_south-west", []), + + "5a_d-07_north---5a_d-07_west": RegionConnection("5a_d-07_north", "5a_d-07_west", [[ItemName.coins, ], ]), + + "5a_d-02_east---5a_d-02_west": RegionConnection("5a_d-02_east", "5a_d-02_west", [[ItemName.springs, ], [ItemName.seekers, ], ]), + + "5a_d-03_east---5a_d-03_west": RegionConnection("5a_d-03_east", "5a_d-03_west", [[ItemName.coins, ItemName.seekers, ], ]), + + "5a_d-15_north-west---5a_d-15_center": RegionConnection("5a_d-15_north-west", "5a_d-15_center", []), + "5a_d-15_center---5a_d-15_north-west": RegionConnection("5a_d-15_center", "5a_d-15_north-west", []), + "5a_d-15_center---5a_d-15_south-west": RegionConnection("5a_d-15_center", "5a_d-15_south-west", []), + "5a_d-15_center---5a_d-15_south-east": RegionConnection("5a_d-15_center", "5a_d-15_south-east", []), + "5a_d-15_south-west---5a_d-15_center": RegionConnection("5a_d-15_south-west", "5a_d-15_center", []), + "5a_d-15_south---5a_d-15_center": RegionConnection("5a_d-15_south", "5a_d-15_center", []), + + "5a_d-13_east---5a_d-13_west": RegionConnection("5a_d-13_east", "5a_d-13_west", []), + "5a_d-13_west---5a_d-13_west": RegionConnection("5a_d-13_west", "5a_d-13_west", []), + + "5a_d-19b_south-east-right---5a_d-19b_south-east-down": RegionConnection("5a_d-19b_south-east-right", "5a_d-19b_south-east-down", []), + "5a_d-19b_south-east-down---5a_d-19b_south-east-right": RegionConnection("5a_d-19b_south-east-down", "5a_d-19b_south-east-right", []), + "5a_d-19b_south-west---5a_d-19b_north-east": RegionConnection("5a_d-19b_south-west", "5a_d-19b_north-east", []), + "5a_d-19b_north-east---5a_d-19b_south-west": RegionConnection("5a_d-19b_north-east", "5a_d-19b_south-west", []), + + "5a_d-19_east---5a_d-19_west": RegionConnection("5a_d-19_east", "5a_d-19_west", [[ItemName.swap_blocks, ItemName.springs, ], ]), + + "5a_d-10_west---5a_d-10_east": RegionConnection("5a_d-10_west", "5a_d-10_east", [[ItemName.dash_refills, ], ]), + + "5a_d-20_west---5a_d-20_east": RegionConnection("5a_d-20_west", "5a_d-20_east", [[ItemName.seekers, ItemName.coins, ], ]), + + "5a_e-00_west---5a_e-00_east": RegionConnection("5a_e-00_west", "5a_e-00_east", [[ItemName.theo_crystal, ], ]), + + "5a_e-01_west---5a_e-01_east": RegionConnection("5a_e-01_west", "5a_e-01_east", [[ItemName.theo_crystal, ItemName.dash_switches, ], ]), + + "5a_e-02_west---5a_e-02_east": RegionConnection("5a_e-02_west", "5a_e-02_east", [[ItemName.theo_crystal, ItemName.dash_switches, ], ]), + + "5a_e-03_west---5a_e-03_east": RegionConnection("5a_e-03_west", "5a_e-03_east", [[ItemName.theo_crystal, ItemName.dash_switches, ], ]), + + "5a_e-04_west---5a_e-04_east": RegionConnection("5a_e-04_west", "5a_e-04_east", [[ItemName.theo_crystal, ItemName.coins, ], ]), + + "5a_e-06_west---5a_e-06_east": RegionConnection("5a_e-06_west", "5a_e-06_east", [[ItemName.theo_crystal, ItemName.dash_switches, ItemName.springs, ], ]), + + "5a_e-05_west---5a_e-05_east": RegionConnection("5a_e-05_west", "5a_e-05_east", [[ItemName.theo_crystal, ItemName.swap_blocks, ItemName.coins, ], ]), + + "5a_e-07_west---5a_e-07_east": RegionConnection("5a_e-07_west", "5a_e-07_east", [[ItemName.theo_crystal, ], ]), + + "5a_e-08_west---5a_e-08_east": RegionConnection("5a_e-08_west", "5a_e-08_east", [[ItemName.theo_crystal, ItemName.swap_blocks, ], ]), + + "5a_e-09_west---5a_e-09_east": RegionConnection("5a_e-09_west", "5a_e-09_east", [[ItemName.theo_crystal, ItemName.swap_blocks, ], ]), + + "5a_e-10_west---5a_e-10_east": RegionConnection("5a_e-10_west", "5a_e-10_east", [[ItemName.theo_crystal, ItemName.swap_blocks, ItemName.springs, ItemName.dash_switches, ], ]), + + "5a_e-11_west---5a_e-11_goal": RegionConnection("5a_e-11_west", "5a_e-11_goal", [[ItemName.theo_crystal, ], ]), + + "5b_start_west---5b_start_east": RegionConnection("5b_start_west", "5b_start_east", []), + "5b_start_east---5b_start_west": RegionConnection("5b_start_east", "5b_start_west", []), + + "5b_a-00_west---5b_a-00_east": RegionConnection("5b_a-00_west", "5b_a-00_east", [[ItemName.red_boosters, ItemName.dash_switches, ], ]), + + "5b_a-01_west---5b_a-01_east": RegionConnection("5b_a-01_west", "5b_a-01_east", [[ItemName.red_boosters, ], ]), + + "5b_a-02_west---5b_a-02_east": RegionConnection("5b_a-02_west", "5b_a-02_east", [[ItemName.swap_blocks, ], ]), + + "5b_b-00_south---5b_b-00_west": RegionConnection("5b_b-00_south", "5b_b-00_west", [["Mirror Temple B - Central Chamber Key 2", ], ]), + "5b_b-00_south---5b_b-00_north": RegionConnection("5b_b-00_south", "5b_b-00_north", []), + "5b_b-00_south---5b_b-00_east": RegionConnection("5b_b-00_south", "5b_b-00_east", []), + "5b_b-00_west---5b_b-00_south": RegionConnection("5b_b-00_west", "5b_b-00_south", []), + "5b_b-00_north---5b_b-00_south": RegionConnection("5b_b-00_north", "5b_b-00_south", []), + "5b_b-00_east---5b_b-00_south": RegionConnection("5b_b-00_east", "5b_b-00_south", []), + + "5b_b-01_west---5b_b-01_north": RegionConnection("5b_b-01_west", "5b_b-01_north", [[ItemName.swap_blocks, ItemName.dash_refills, ], ]), + "5b_b-01_west---5b_b-01_east": RegionConnection("5b_b-01_west", "5b_b-01_east", [[ItemName.red_boosters, "Mirror Temple B - Central Chamber Key 2", ], ]), + + "5b_b-04_east---5b_b-04_west": RegionConnection("5b_b-04_east", "5b_b-04_west", [[ItemName.swap_blocks, ItemName.dash_refills, ItemName.red_boosters, ], ]), + + "5b_b-02_south---5b_b-02_center": RegionConnection("5b_b-02_south", "5b_b-02_center", []), + "5b_b-02_center---5b_b-02_south": RegionConnection("5b_b-02_center", "5b_b-02_south", []), + "5b_b-02_center---5b_b-02_north": RegionConnection("5b_b-02_center", "5b_b-02_north", [[ItemName.red_boosters, "Mirror Temple B - Central Chamber Key 1", ], ]), + "5b_b-02_center---5b_b-02_north-west": RegionConnection("5b_b-02_center", "5b_b-02_north-west", []), + "5b_b-02_center---5b_b-02_north-east": RegionConnection("5b_b-02_center", "5b_b-02_north-east", []), + "5b_b-02_north-west---5b_b-02_center": RegionConnection("5b_b-02_north-west", "5b_b-02_center", []), + "5b_b-02_north-east---5b_b-02_center": RegionConnection("5b_b-02_north-east", "5b_b-02_center", []), + "5b_b-02_north---5b_b-02_center": RegionConnection("5b_b-02_north", "5b_b-02_center", []), + "5b_b-02_south-west---5b_b-02_center": RegionConnection("5b_b-02_south-west", "5b_b-02_center", []), + "5b_b-02_south-east---5b_b-02_center": RegionConnection("5b_b-02_south-east", "5b_b-02_center", []), + + "5b_b-05_north---5b_b-05_south": RegionConnection("5b_b-05_north", "5b_b-05_south", [[ItemName.swap_blocks, ItemName.dash_refills, ItemName.coins, ], ]), + + + "5b_b-07_south---5b_b-07_north": RegionConnection("5b_b-07_south", "5b_b-07_north", [[ItemName.swap_blocks, ], ]), + + "5b_b-03_main---5b_b-03_north": RegionConnection("5b_b-03_main", "5b_b-03_north", [[ItemName.red_boosters, ItemName.dash_switches, "Mirror Temple B - Central Chamber Key 1", ], ]), + "5b_b-03_main---5b_b-03_west": RegionConnection("5b_b-03_main", "5b_b-03_west", [[ItemName.dash_switches, ], ]), + "5b_b-03_north---5b_b-03_main": RegionConnection("5b_b-03_north", "5b_b-03_main", [[ItemName.red_boosters, ItemName.dash_switches, ], ]), + "5b_b-03_east---5b_b-03_main": RegionConnection("5b_b-03_east", "5b_b-03_main", [[ItemName.red_boosters, ], ]), + + "5b_b-08_east---5b_b-08_south": RegionConnection("5b_b-08_east", "5b_b-08_south", [[ItemName.swap_blocks, ItemName.springs, ], ]), + "5b_b-08_east---5b_b-08_north": RegionConnection("5b_b-08_east", "5b_b-08_north", [[ItemName.dash_switches, ItemName.swap_blocks, ItemName.springs, "Mirror Temple B - Central Chamber Key 1", ], ]), + + "5b_b-09_bottom---5b_b-09_mirror": RegionConnection("5b_b-09_bottom", "5b_b-09_mirror", [[ItemName.swap_blocks, ItemName.red_boosters, ItemName.dash_switches, ], ]), + + "5b_c-00_mirror---5b_c-00_bottom": RegionConnection("5b_c-00_mirror", "5b_c-00_bottom", [[ItemName.dash_refills, ItemName.dash_switches, ], ]), + + "5b_c-01_west---5b_c-01_east": RegionConnection("5b_c-01_west", "5b_c-01_east", [[ItemName.seekers, ItemName.coins, ], ]), + + "5b_c-02_west---5b_c-02_east": RegionConnection("5b_c-02_west", "5b_c-02_east", [[ItemName.seekers, ItemName.dash_switches, ItemName.dash_refills, ], ]), + + "5b_c-03_west---5b_c-03_east": RegionConnection("5b_c-03_west", "5b_c-03_east", [[ItemName.seekers, ItemName.red_boosters, ], ]), + + "5b_c-04_west---5b_c-04_east": RegionConnection("5b_c-04_west", "5b_c-04_east", [[ItemName.seekers, ], ]), + + "5b_d-00_west---5b_d-00_east": RegionConnection("5b_d-00_west", "5b_d-00_east", [[ItemName.theo_crystal, ], ]), + + "5b_d-01_west---5b_d-01_east": RegionConnection("5b_d-01_west", "5b_d-01_east", [[ItemName.theo_crystal, ItemName.springs, ItemName.dash_switches, ], ]), + + "5b_d-02_west---5b_d-02_east": RegionConnection("5b_d-02_west", "5b_d-02_east", [[ItemName.theo_crystal, ItemName.springs, ItemName.dash_switches, ItemName.seekers, ], ]), + + "5b_d-03_west---5b_d-03_east": RegionConnection("5b_d-03_west", "5b_d-03_east", [[ItemName.theo_crystal, ItemName.springs, ItemName.swap_blocks, ItemName.coins, ], ]), + + "5b_d-04_west---5b_d-04_east": RegionConnection("5b_d-04_west", "5b_d-04_east", [[ItemName.theo_crystal, ItemName.springs, ItemName.dash_refills, ], ]), + + "5b_d-05_west---5b_d-05_goal": RegionConnection("5b_d-05_west", "5b_d-05_goal", [[ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.springs, ItemName.swap_blocks, ], ]), + + "5c_00_west---5c_00_east": RegionConnection("5c_00_west", "5c_00_east", [[ItemName.swap_blocks, ItemName.dash_refills, ], ]), + "5c_00_east---5c_00_west": RegionConnection("5c_00_east", "5c_00_west", [[ItemName.swap_blocks, ItemName.dash_refills, ], ]), + + "5c_01_west---5c_01_east": RegionConnection("5c_01_west", "5c_01_east", [[ItemName.swap_blocks, ], ]), + "5c_01_east---5c_01_west": RegionConnection("5c_01_east", "5c_01_west", [[ItemName.cannot_access, ], ]), + + "5c_02_west---5c_02_goal": RegionConnection("5c_02_west", "5c_02_goal", [[ItemName.red_boosters, ItemName.dash_refills, ItemName.dash_switches, ], ]), + + "6a_00_west---6a_00_east": RegionConnection("6a_00_west", "6a_00_east", []), + "6a_00_east---6a_00_west": RegionConnection("6a_00_east", "6a_00_west", [[ItemName.kevin_blocks, ], ]), + + "6a_01_bottom---6a_01_top": RegionConnection("6a_01_bottom", "6a_01_top", [[ItemName.feathers, ], ]), + "6a_01_top---6a_01_bottom": RegionConnection("6a_01_top", "6a_01_bottom", []), + + "6a_02_bottom---6a_02_bottom-west": RegionConnection("6a_02_bottom", "6a_02_bottom-west", [[ItemName.feathers, ], ]), + "6a_02_top-west---6a_02_top": RegionConnection("6a_02_top-west", "6a_02_top", [[ItemName.feathers, ], ]), + "6a_02_top---6a_02_top-west": RegionConnection("6a_02_top", "6a_02_top-west", [[ItemName.feathers, ], ]), + + "6a_03_bottom---6a_03_top": RegionConnection("6a_03_bottom", "6a_03_top", [[ItemName.feathers, ], ]), + + "6a_02b_bottom---6a_02b_top": RegionConnection("6a_02b_bottom", "6a_02b_top", [[ItemName.kevin_blocks, ], ]), + + "6a_04_south---6a_04_south-west": RegionConnection("6a_04_south", "6a_04_south-west", [[ItemName.kevin_blocks, ], ]), + "6a_04_south---6a_04_south-east": RegionConnection("6a_04_south", "6a_04_south-east", []), + "6a_04_south-west---6a_04_south": RegionConnection("6a_04_south-west", "6a_04_south", []), + "6a_04_south-west---6a_04_east": RegionConnection("6a_04_south-west", "6a_04_east", [[ItemName.feathers, ], ]), + "6a_04_south-east---6a_04_south": RegionConnection("6a_04_south-east", "6a_04_south", []), + "6a_04_east---6a_04_south": RegionConnection("6a_04_east", "6a_04_south", []), + "6a_04_east---6a_04_north-west": RegionConnection("6a_04_east", "6a_04_north-west", [[ItemName.feathers, ], ]), + "6a_04_north-west---6a_04_south": RegionConnection("6a_04_north-west", "6a_04_south", []), + + "6a_04b_west---6a_04b_east": RegionConnection("6a_04b_west", "6a_04b_east", []), + "6a_04b_east---6a_04b_west": RegionConnection("6a_04b_east", "6a_04b_west", []), + + + + + "6a_05_west---6a_05_east": RegionConnection("6a_05_west", "6a_05_east", [[ItemName.kevin_blocks, ], ]), + + "6a_06_west---6a_06_east": RegionConnection("6a_06_west", "6a_06_east", [[ItemName.kevin_blocks, ItemName.feathers, ], ]), + + "6a_07_west---6a_07_east": RegionConnection("6a_07_west", "6a_07_east", []), + "6a_07_west---6a_07_north-east": RegionConnection("6a_07_west", "6a_07_north-east", []), + "6a_07_east---6a_07_west": RegionConnection("6a_07_east", "6a_07_west", []), + "6a_07_north-east---6a_07_west": RegionConnection("6a_07_north-east", "6a_07_west", []), + + "6a_08a_west---6a_08a_east": RegionConnection("6a_08a_west", "6a_08a_east", [[ItemName.kevin_blocks, ItemName.dash_refills, ], ]), + + "6a_08b_west---6a_08b_east": RegionConnection("6a_08b_west", "6a_08b_east", [[ItemName.kevin_blocks, ItemName.feathers, ], ]), + + "6a_09_west---6a_09_north-west": RegionConnection("6a_09_west", "6a_09_north-west", []), + "6a_09_north-west---6a_09_north-east": RegionConnection("6a_09_north-west", "6a_09_north-east", []), + "6a_09_east---6a_09_west": RegionConnection("6a_09_east", "6a_09_west", []), + "6a_09_north-east---6a_09_east": RegionConnection("6a_09_north-east", "6a_09_east", []), + + "6a_10a_west---6a_10a_east": RegionConnection("6a_10a_west", "6a_10a_east", [[ItemName.dash_refills, ], ]), + "6a_10a_east---6a_10a_east": RegionConnection("6a_10a_east", "6a_10a_east", [[ItemName.cannot_access, ], ]), + + "6a_10b_west---6a_10b_east": RegionConnection("6a_10b_west", "6a_10b_east", [[ItemName.bumpers, ], ]), + "6a_10b_east---6a_10b_west": RegionConnection("6a_10b_east", "6a_10b_west", [[ItemName.bumpers, ], ]), + + "6a_11_west---6a_11_north-west": RegionConnection("6a_11_west", "6a_11_north-west", [[ItemName.bumpers, ], ]), + "6a_11_north-west---6a_11_north-east": RegionConnection("6a_11_north-west", "6a_11_north-east", [[ItemName.bumpers, ], ]), + "6a_11_east---6a_11_north-east": RegionConnection("6a_11_east", "6a_11_north-east", []), + "6a_11_north-east---6a_11_north-west": RegionConnection("6a_11_north-east", "6a_11_north-west", []), + "6a_11_north-east---6a_11_east": RegionConnection("6a_11_north-east", "6a_11_east", []), + + "6a_12a_west---6a_12a_east": RegionConnection("6a_12a_west", "6a_12a_east", [[ItemName.feathers, ], ]), + + "6a_12b_west---6a_12b_east": RegionConnection("6a_12b_west", "6a_12b_east", [[ItemName.kevin_blocks, ItemName.bumpers, ], ]), + "6a_12b_east---6a_12b_west": RegionConnection("6a_12b_east", "6a_12b_west", [[ItemName.bumpers, ], ]), + + "6a_13_west---6a_13_north-west": RegionConnection("6a_13_west", "6a_13_north-west", []), + "6a_13_north-west---6a_13_east": RegionConnection("6a_13_north-west", "6a_13_east", []), + "6a_13_north-west---6a_13_north-east": RegionConnection("6a_13_north-west", "6a_13_north-east", []), + "6a_13_east---6a_13_north-east": RegionConnection("6a_13_east", "6a_13_north-east", []), + "6a_13_north-east---6a_13_north-west": RegionConnection("6a_13_north-east", "6a_13_north-west", []), + "6a_13_north-east---6a_13_east": RegionConnection("6a_13_north-east", "6a_13_east", []), + + "6a_14a_west---6a_14a_east": RegionConnection("6a_14a_west", "6a_14a_east", [[ItemName.bumpers, ItemName.dash_refills, ], ]), + + "6a_14b_west---6a_14b_east": RegionConnection("6a_14b_west", "6a_14b_east", [[ItemName.springs, ItemName.coins, ItemName.bumpers, ], ]), + + "6a_15_west---6a_15_north-west": RegionConnection("6a_15_west", "6a_15_north-west", []), + "6a_15_north-west---6a_15_east": RegionConnection("6a_15_north-west", "6a_15_east", []), + "6a_15_north-west---6a_15_north-east": RegionConnection("6a_15_north-west", "6a_15_north-east", []), + "6a_15_east---6a_15_north-east": RegionConnection("6a_15_east", "6a_15_north-east", []), + "6a_15_north-east---6a_15_north-west": RegionConnection("6a_15_north-east", "6a_15_north-west", []), + "6a_15_north-east---6a_15_east": RegionConnection("6a_15_north-east", "6a_15_east", []), + + "6a_16a_west---6a_16a_east": RegionConnection("6a_16a_west", "6a_16a_east", [[ItemName.feathers, ], ]), + + "6a_16b_west---6a_16b_east": RegionConnection("6a_16b_west", "6a_16b_east", [[ItemName.dash_refills, ItemName.feathers, ], ]), + + "6a_17_west---6a_17_north-west": RegionConnection("6a_17_west", "6a_17_north-west", []), + "6a_17_north-west---6a_17_east": RegionConnection("6a_17_north-west", "6a_17_east", []), + "6a_17_north-west---6a_17_north-east": RegionConnection("6a_17_north-west", "6a_17_north-east", [[ItemName.kevin_blocks, ], ]), + "6a_17_east---6a_17_north-east": RegionConnection("6a_17_east", "6a_17_north-east", []), + "6a_17_north-east---6a_17_north-west": RegionConnection("6a_17_north-east", "6a_17_north-west", [[ItemName.cannot_access, ], ]), + "6a_17_north-east---6a_17_east": RegionConnection("6a_17_north-east", "6a_17_east", []), + + "6a_18a_west---6a_18a_east": RegionConnection("6a_18a_west", "6a_18a_east", [[ItemName.bumpers, ItemName.feathers, ], ]), + + "6a_18b_west---6a_18b_east": RegionConnection("6a_18b_west", "6a_18b_east", [[ItemName.bumpers, ], ]), + + "6a_19_west---6a_19_north-west": RegionConnection("6a_19_west", "6a_19_north-west", []), + "6a_19_west---6a_19_east": RegionConnection("6a_19_west", "6a_19_east", [[ItemName.feathers, ], ]), + "6a_19_north-west---6a_19_west": RegionConnection("6a_19_north-west", "6a_19_west", [[ItemName.feathers, ], ]), + "6a_19_north-west---6a_19_east": RegionConnection("6a_19_north-west", "6a_19_east", []), + + "6a_20_west---6a_20_east": RegionConnection("6a_20_west", "6a_20_east", [[ItemName.feathers, ], ]), + + "6a_b-00_west---6a_b-00_east": RegionConnection("6a_b-00_west", "6a_b-00_east", []), + "6a_b-00_west---6a_b-00_top": RegionConnection("6a_b-00_west", "6a_b-00_top", []), + "6a_b-00_east---6a_b-00_west": RegionConnection("6a_b-00_east", "6a_b-00_west", []), + "6a_b-00_top---6a_b-00_west": RegionConnection("6a_b-00_top", "6a_b-00_west", []), + + "6a_b-00b_bottom---6a_b-00b_top": RegionConnection("6a_b-00b_bottom", "6a_b-00b_top", []), + "6a_b-00b_top---6a_b-00b_bottom": RegionConnection("6a_b-00b_top", "6a_b-00b_bottom", []), + + + "6a_b-01_west---6a_b-01_east": RegionConnection("6a_b-01_west", "6a_b-01_east", []), + "6a_b-01_east---6a_b-01_west": RegionConnection("6a_b-01_east", "6a_b-01_west", []), + + "6a_b-02_top---6a_b-02_bottom": RegionConnection("6a_b-02_top", "6a_b-02_bottom", [[ItemName.kevin_blocks, ], ]), + + "6a_b-02b_top---6a_b-02b_bottom": RegionConnection("6a_b-02b_top", "6a_b-02b_bottom", []), + + "6a_b-03_west---6a_b-03_east": RegionConnection("6a_b-03_west", "6a_b-03_east", [[ItemName.kevin_blocks, ], ]), + + "6a_boss-00_west---6a_boss-00_east": RegionConnection("6a_boss-00_west", "6a_boss-00_east", []), + "6a_boss-00_east---6a_boss-00_west": RegionConnection("6a_boss-00_east", "6a_boss-00_west", []), + + "6a_boss-01_west---6a_boss-01_east": RegionConnection("6a_boss-01_west", "6a_boss-01_east", []), + "6a_boss-01_east---6a_boss-01_west": RegionConnection("6a_boss-01_east", "6a_boss-01_west", []), + + "6a_boss-02_west---6a_boss-02_east": RegionConnection("6a_boss-02_west", "6a_boss-02_east", [[ItemName.springs, ], ]), + "6a_boss-02_east---6a_boss-02_west": RegionConnection("6a_boss-02_east", "6a_boss-02_west", []), + + "6a_boss-03_west---6a_boss-03_east": RegionConnection("6a_boss-03_west", "6a_boss-03_east", []), + "6a_boss-03_east---6a_boss-03_west": RegionConnection("6a_boss-03_east", "6a_boss-03_west", []), + + "6a_boss-04_west---6a_boss-04_east": RegionConnection("6a_boss-04_west", "6a_boss-04_east", []), + "6a_boss-04_east---6a_boss-04_west": RegionConnection("6a_boss-04_east", "6a_boss-04_west", []), + + "6a_boss-05_west---6a_boss-05_east": RegionConnection("6a_boss-05_west", "6a_boss-05_east", [[ItemName.dash_refills, ], ]), + "6a_boss-05_east---6a_boss-05_west": RegionConnection("6a_boss-05_east", "6a_boss-05_west", [[ItemName.dash_refills, ], ]), + + "6a_boss-06_west---6a_boss-06_east": RegionConnection("6a_boss-06_west", "6a_boss-06_east", []), + "6a_boss-06_east---6a_boss-06_west": RegionConnection("6a_boss-06_east", "6a_boss-06_west", []), + + "6a_boss-07_west---6a_boss-07_east": RegionConnection("6a_boss-07_west", "6a_boss-07_east", [[ItemName.feathers, ], ]), + "6a_boss-07_east---6a_boss-07_west": RegionConnection("6a_boss-07_east", "6a_boss-07_west", [[ItemName.feathers, ], ]), + + "6a_boss-08_west---6a_boss-08_east": RegionConnection("6a_boss-08_west", "6a_boss-08_east", [[ItemName.dash_refills, ], ]), + + "6a_boss-09_west---6a_boss-09_east": RegionConnection("6a_boss-09_west", "6a_boss-09_east", [[ItemName.feathers, ], ]), + + "6a_boss-10_west---6a_boss-10_east": RegionConnection("6a_boss-10_west", "6a_boss-10_east", [[ItemName.bumpers, ], ]), + "6a_boss-10_east---6a_boss-10_west": RegionConnection("6a_boss-10_east", "6a_boss-10_west", [[ItemName.bumpers, ], ]), + + "6a_boss-11_west---6a_boss-11_east": RegionConnection("6a_boss-11_west", "6a_boss-11_east", [[ItemName.bumpers, ], ]), + + "6a_boss-12_west---6a_boss-12_east": RegionConnection("6a_boss-12_west", "6a_boss-12_east", [[ItemName.dash_refills, ], ]), + + "6a_boss-13_west---6a_boss-13_east": RegionConnection("6a_boss-13_west", "6a_boss-13_east", []), + "6a_boss-13_east---6a_boss-13_west": RegionConnection("6a_boss-13_east", "6a_boss-13_west", []), + + "6a_boss-14_west---6a_boss-14_east": RegionConnection("6a_boss-14_west", "6a_boss-14_east", []), + "6a_boss-14_east---6a_boss-14_west": RegionConnection("6a_boss-14_east", "6a_boss-14_west", []), + + "6a_boss-15_west---6a_boss-15_east": RegionConnection("6a_boss-15_west", "6a_boss-15_east", []), + + "6a_boss-16_west---6a_boss-16_east": RegionConnection("6a_boss-16_west", "6a_boss-16_east", []), + "6a_boss-16_east---6a_boss-16_west": RegionConnection("6a_boss-16_east", "6a_boss-16_west", []), + + "6a_boss-17_west---6a_boss-17_east": RegionConnection("6a_boss-17_west", "6a_boss-17_east", []), + "6a_boss-17_east---6a_boss-17_west": RegionConnection("6a_boss-17_east", "6a_boss-17_west", [[ItemName.cannot_access, ], ]), + + "6a_boss-18_west---6a_boss-18_east": RegionConnection("6a_boss-18_west", "6a_boss-18_east", [[ItemName.feathers, ItemName.bumpers, ], ]), + + "6a_boss-19_west---6a_boss-19_east": RegionConnection("6a_boss-19_west", "6a_boss-19_east", [[ItemName.feathers, ItemName.bumpers, ], ]), + + "6a_boss-20_west---6a_boss-20_east": RegionConnection("6a_boss-20_west", "6a_boss-20_east", []), + "6a_boss-20_east---6a_boss-20_west": RegionConnection("6a_boss-20_east", "6a_boss-20_west", []), + + "6a_after-00_bottom---6a_after-00_top": RegionConnection("6a_after-00_bottom", "6a_after-00_top", []), + "6a_after-00_top---6a_after-00_bottom": RegionConnection("6a_after-00_top", "6a_after-00_bottom", []), + + "6a_after-01_bottom---6a_after-01_goal": RegionConnection("6a_after-01_bottom", "6a_after-01_goal", [[ItemName.badeline_boosters, ], ]), + + "6b_a-00_bottom---6b_a-00_top": RegionConnection("6b_a-00_bottom", "6b_a-00_top", [[ItemName.kevin_blocks, ], ]), + + "6b_a-01_bottom---6b_a-01_top": RegionConnection("6b_a-01_bottom", "6b_a-01_top", [[ItemName.feathers, ItemName.dash_refills, ], ]), + + "6b_a-02_bottom---6b_a-02_top": RegionConnection("6b_a-02_bottom", "6b_a-02_top", [[ItemName.bumpers, ItemName.feathers, ], ]), + + "6b_a-03_west---6b_a-03_east": RegionConnection("6b_a-03_west", "6b_a-03_east", [[ItemName.kevin_blocks, ItemName.coins, ], ]), + + "6b_a-04_west---6b_a-04_east": RegionConnection("6b_a-04_west", "6b_a-04_east", [[ItemName.bumpers, ], ]), + + "6b_a-05_west---6b_a-05_east": RegionConnection("6b_a-05_west", "6b_a-05_east", [[ItemName.bumpers, ], ]), + + "6b_a-06_west---6b_a-06_east": RegionConnection("6b_a-06_west", "6b_a-06_east", [[ItemName.bumpers, ItemName.kevin_blocks, ItemName.dash_refills, ItemName.coins, ], ]), + + "6b_b-00_west---6b_b-00_east": RegionConnection("6b_b-00_west", "6b_b-00_east", []), + + "6b_b-01_top---6b_b-01_bottom": RegionConnection("6b_b-01_top", "6b_b-01_bottom", [[ItemName.dash_refills, ], ]), + + "6b_b-02_top---6b_b-02_bottom": RegionConnection("6b_b-02_top", "6b_b-02_bottom", [[ItemName.dash_refills, ItemName.kevin_blocks, ], ]), + + "6b_b-03_top---6b_b-03_bottom": RegionConnection("6b_b-03_top", "6b_b-03_bottom", [[ItemName.bumpers, ], ]), + + "6b_b-04_top---6b_b-04_bottom": RegionConnection("6b_b-04_top", "6b_b-04_bottom", [[ItemName.dash_refills, ], ]), + + "6b_b-05_top---6b_b-05_bottom": RegionConnection("6b_b-05_top", "6b_b-05_bottom", [[ItemName.dash_refills, ItemName.kevin_blocks, ], ]), + + "6b_b-06_top---6b_b-06_bottom": RegionConnection("6b_b-06_top", "6b_b-06_bottom", []), + + "6b_b-07_top---6b_b-07_bottom": RegionConnection("6b_b-07_top", "6b_b-07_bottom", [[ItemName.dash_refills, ItemName.feathers, ], ]), + + "6b_b-08_top---6b_b-08_bottom": RegionConnection("6b_b-08_top", "6b_b-08_bottom", [[ItemName.dash_refills, ], ]), + + "6b_b-10_west---6b_b-10_east": RegionConnection("6b_b-10_west", "6b_b-10_east", [[ItemName.dash_refills, ItemName.feathers, ], ]), + + "6b_c-00_west---6b_c-00_east": RegionConnection("6b_c-00_west", "6b_c-00_east", [[ItemName.springs, ], ]), + + "6b_c-01_west---6b_c-01_east": RegionConnection("6b_c-01_west", "6b_c-01_east", [[ItemName.dash_refills, ItemName.feathers, ], ]), + + "6b_c-02_west---6b_c-02_east": RegionConnection("6b_c-02_west", "6b_c-02_east", [[ItemName.dash_refills, ItemName.feathers, ], ]), + + "6b_c-03_west---6b_c-03_east": RegionConnection("6b_c-03_west", "6b_c-03_east", [[ItemName.dash_refills, ItemName.feathers, ItemName.coins, ], ]), + + "6b_c-04_west---6b_c-04_east": RegionConnection("6b_c-04_west", "6b_c-04_east", [[ItemName.dash_refills, ItemName.feathers, ItemName.bumpers, ], ]), + + "6b_d-00_west---6b_d-00_east": RegionConnection("6b_d-00_west", "6b_d-00_east", [[ItemName.dash_refills, ItemName.kevin_blocks, ], ]), + + "6b_d-01_west---6b_d-01_east": RegionConnection("6b_d-01_west", "6b_d-01_east", [[ItemName.bumpers, ], ]), + + "6b_d-02_west---6b_d-02_east": RegionConnection("6b_d-02_west", "6b_d-02_east", [[ItemName.bumpers, ItemName.feathers, ItemName.coins, ], ]), + + "6b_d-03_west---6b_d-03_east": RegionConnection("6b_d-03_west", "6b_d-03_east", [[ItemName.bumpers, ItemName.kevin_blocks, ], ]), + + "6b_d-04_west---6b_d-04_east": RegionConnection("6b_d-04_west", "6b_d-04_east", [[ItemName.bumpers, ItemName.kevin_blocks, ItemName.feathers, ], ]), + + "6b_d-05_west---6b_d-05_goal": RegionConnection("6b_d-05_west", "6b_d-05_goal", [[ItemName.blue_cassette_blocks, ItemName.bumpers, ], ]), + + "6c_00_west---6c_00_east": RegionConnection("6c_00_west", "6c_00_east", [[ItemName.bumpers, ], ]), + + "6c_01_west---6c_01_east": RegionConnection("6c_01_west", "6c_01_east", [[ItemName.dash_refills, ItemName.feathers, ], ]), + + "6c_02_west---6c_02_goal": RegionConnection("6c_02_west", "6c_02_goal", [[ItemName.kevin_blocks, ItemName.dash_refills, ItemName.bumpers, ], ]), + + "7a_a-00_west---7a_a-00_east": RegionConnection("7a_a-00_west", "7a_a-00_east", []), + "7a_a-00_east---7a_a-00_west": RegionConnection("7a_a-00_east", "7a_a-00_west", []), + + "7a_a-01_west---7a_a-01_east": RegionConnection("7a_a-01_west", "7a_a-01_east", [[ItemName.dash_refills, ], ]), + "7a_a-01_east---7a_a-01_east": RegionConnection("7a_a-01_east", "7a_a-01_east", [[ItemName.dash_refills, ], ]), + + "7a_a-02_west---7a_a-02_north": RegionConnection("7a_a-02_west", "7a_a-02_north", [[ItemName.springs, ], ]), + "7a_a-02_west---7a_a-02_east": RegionConnection("7a_a-02_west", "7a_a-02_east", [[ItemName.springs, ], ]), + "7a_a-02_east---7a_a-02_west": RegionConnection("7a_a-02_east", "7a_a-02_west", []), + "7a_a-02_north---7a_a-02_west": RegionConnection("7a_a-02_north", "7a_a-02_west", []), + "7a_a-02_north-west---7a_a-02_west": RegionConnection("7a_a-02_north-west", "7a_a-02_west", []), + + "7a_a-02b_east---7a_a-02b_west": RegionConnection("7a_a-02b_east", "7a_a-02b_west", []), + "7a_a-02b_west---7a_a-02b_east": RegionConnection("7a_a-02b_west", "7a_a-02b_east", []), + + "7a_a-03_west---7a_a-03_east": RegionConnection("7a_a-03_west", "7a_a-03_east", [[ItemName.springs, ], ]), + "7a_a-03_east---7a_a-03_west": RegionConnection("7a_a-03_east", "7a_a-03_west", [[ItemName.springs, ], ]), + + "7a_a-04_west---7a_a-04_east": RegionConnection("7a_a-04_west", "7a_a-04_east", [[ItemName.dash_refills, ItemName.springs, ], ]), + "7a_a-04_north---7a_a-04_east": RegionConnection("7a_a-04_north", "7a_a-04_east", []), + "7a_a-04_east---7a_a-04_west": RegionConnection("7a_a-04_east", "7a_a-04_west", []), + "7a_a-04_east---7a_a-04_north": RegionConnection("7a_a-04_east", "7a_a-04_north", []), + + + "7a_a-05_west---7a_a-05_east": RegionConnection("7a_a-05_west", "7a_a-05_east", [[ItemName.dash_refills, ], ]), + "7a_a-05_east---7a_a-05_west": RegionConnection("7a_a-05_east", "7a_a-05_west", [[ItemName.dash_refills, ], ]), + + "7a_a-06_bottom---7a_a-06_top": RegionConnection("7a_a-06_bottom", "7a_a-06_top", [[ItemName.badeline_boosters, ItemName.springs, ], ]), + "7a_a-06_bottom---7a_a-06_top-side": RegionConnection("7a_a-06_bottom", "7a_a-06_top-side", [[ItemName.badeline_boosters, ItemName.springs, ], ]), + "7a_a-06_top---7a_a-06_bottom": RegionConnection("7a_a-06_top", "7a_a-06_bottom", []), + "7a_a-06_top-side---7a_a-06_top": RegionConnection("7a_a-06_top-side", "7a_a-06_top", [[ItemName.badeline_boosters, ], ]), + + "7a_b-00_bottom---7a_b-00_top": RegionConnection("7a_b-00_bottom", "7a_b-00_top", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "7a_b-00_top---7a_b-00_bottom": RegionConnection("7a_b-00_top", "7a_b-00_bottom", []), + + "7a_b-01_west---7a_b-01_east": RegionConnection("7a_b-01_west", "7a_b-01_east", [[ItemName.traffic_blocks, ItemName.springs, ], ]), + + "7a_b-02_south---7a_b-02_north-west": RegionConnection("7a_b-02_south", "7a_b-02_north-west", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "7a_b-02_south---7a_b-02_north-east": RegionConnection("7a_b-02_south", "7a_b-02_north-east", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "7a_b-02_north-west---7a_b-02_north": RegionConnection("7a_b-02_north-west", "7a_b-02_north", []), + "7a_b-02_north---7a_b-02_north-east": RegionConnection("7a_b-02_north", "7a_b-02_north-east", []), + "7a_b-02_north-east---7a_b-02_south": RegionConnection("7a_b-02_north-east", "7a_b-02_south", []), + "7a_b-02_north-east---7a_b-02_north": RegionConnection("7a_b-02_north-east", "7a_b-02_north", []), + + "7a_b-02b_south---7a_b-02b_north-west": RegionConnection("7a_b-02b_south", "7a_b-02b_north-west", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "7a_b-02b_south---7a_b-02b_north-east": RegionConnection("7a_b-02b_south", "7a_b-02b_north-east", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "7a_b-02b_north-west---7a_b-02b_north-east": RegionConnection("7a_b-02b_north-west", "7a_b-02b_north-east", []), + "7a_b-02b_north-east---7a_b-02b_south": RegionConnection("7a_b-02b_north-east", "7a_b-02b_south", []), + "7a_b-02b_north-east---7a_b-02b_north-west": RegionConnection("7a_b-02b_north-east", "7a_b-02b_north-west", []), + + + "7a_b-02c_west---7a_b-02c_east": RegionConnection("7a_b-02c_west", "7a_b-02c_east", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "7a_b-02c_east---7a_b-02c_west": RegionConnection("7a_b-02c_east", "7a_b-02c_west", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "7a_b-02c_east---7a_b-02c_south-east": RegionConnection("7a_b-02c_east", "7a_b-02c_south-east", []), + "7a_b-02c_south-east---7a_b-02c_east": RegionConnection("7a_b-02c_south-east", "7a_b-02c_east", []), + + "7a_b-02d_north---7a_b-02d_south": RegionConnection("7a_b-02d_north", "7a_b-02d_south", [[ItemName.dash_refills, ], ]), + "7a_b-02d_south---7a_b-02d_north": RegionConnection("7a_b-02d_south", "7a_b-02d_north", [[ItemName.dash_refills, ], ]), + + "7a_b-03_west---7a_b-03_east": RegionConnection("7a_b-03_west", "7a_b-03_east", []), + "7a_b-03_east---7a_b-03_west": RegionConnection("7a_b-03_east", "7a_b-03_west", []), + "7a_b-03_east---7a_b-03_north": RegionConnection("7a_b-03_east", "7a_b-03_north", [[ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "7a_b-03_north---7a_b-03_east": RegionConnection("7a_b-03_north", "7a_b-03_east", []), + + + "7a_b-05_west---7a_b-05_east": RegionConnection("7a_b-05_west", "7a_b-05_east", [[ItemName.springs, ItemName.coins, ItemName.dash_refills, ], ]), + "7a_b-05_north-west---7a_b-05_west": RegionConnection("7a_b-05_north-west", "7a_b-05_west", []), + + "7a_b-06_west---7a_b-06_east": RegionConnection("7a_b-06_west", "7a_b-06_east", [[ItemName.traffic_blocks, ], ]), + "7a_b-06_east---7a_b-06_west": RegionConnection("7a_b-06_east", "7a_b-06_west", []), + + "7a_b-07_west---7a_b-07_east": RegionConnection("7a_b-07_west", "7a_b-07_east", [[ItemName.traffic_blocks, ], ]), + "7a_b-07_east---7a_b-07_west": RegionConnection("7a_b-07_east", "7a_b-07_west", []), + + "7a_b-08_west---7a_b-08_east": RegionConnection("7a_b-08_west", "7a_b-08_east", [[ItemName.springs, ], ]), + + "7a_b-09_bottom---7a_b-09_top": RegionConnection("7a_b-09_bottom", "7a_b-09_top", [[ItemName.traffic_blocks, ItemName.badeline_boosters, ], ]), + "7a_b-09_top---7a_b-09_bottom": RegionConnection("7a_b-09_top", "7a_b-09_bottom", [[ItemName.traffic_blocks, ], ]), + "7a_b-09_top---7a_b-09_top-side": RegionConnection("7a_b-09_top", "7a_b-09_top-side", []), + "7a_b-09_top-side---7a_b-09_top": RegionConnection("7a_b-09_top-side", "7a_b-09_top", []), + + "7a_c-00_west---7a_c-00_east": RegionConnection("7a_c-00_west", "7a_c-00_east", [[ItemName.dream_blocks, ], ]), + "7a_c-00_east---7a_c-00_west": RegionConnection("7a_c-00_east", "7a_c-00_west", [[ItemName.dream_blocks, ], ]), + + "7a_c-01_bottom---7a_c-01_top": RegionConnection("7a_c-01_bottom", "7a_c-01_top", [[ItemName.dream_blocks, ], ]), + "7a_c-01_top---7a_c-01_bottom": RegionConnection("7a_c-01_top", "7a_c-01_bottom", [[ItemName.dream_blocks, ], ]), + + "7a_c-02_bottom---7a_c-02_top": RegionConnection("7a_c-02_bottom", "7a_c-02_top", [[ItemName.dream_blocks, ItemName.springs, ItemName.coins, ], ]), + + "7a_c-03_south---7a_c-03_west": RegionConnection("7a_c-03_south", "7a_c-03_west", []), + "7a_c-03_south---7a_c-03_east": RegionConnection("7a_c-03_south", "7a_c-03_east", [[ItemName.dream_blocks, ], ]), + "7a_c-03_west---7a_c-03_south": RegionConnection("7a_c-03_west", "7a_c-03_south", []), + "7a_c-03_east---7a_c-03_south": RegionConnection("7a_c-03_east", "7a_c-03_south", [[ItemName.dream_blocks, ], ]), + + + "7a_c-04_west---7a_c-04_north-west": RegionConnection("7a_c-04_west", "7a_c-04_north-west", [[ItemName.dream_blocks, ], ]), + "7a_c-04_west---7a_c-04_east": RegionConnection("7a_c-04_west", "7a_c-04_east", []), + "7a_c-04_north-west---7a_c-04_west": RegionConnection("7a_c-04_north-west", "7a_c-04_west", [[ItemName.dream_blocks, ], ]), + "7a_c-04_north-east---7a_c-04_east": RegionConnection("7a_c-04_north-east", "7a_c-04_east", [[ItemName.dream_blocks, ], ]), + "7a_c-04_east---7a_c-04_north-east": RegionConnection("7a_c-04_east", "7a_c-04_north-east", [[ItemName.dream_blocks, ], ]), + "7a_c-04_east---7a_c-04_west": RegionConnection("7a_c-04_east", "7a_c-04_west", []), + + + "7a_c-06_south---7a_c-06_north": RegionConnection("7a_c-06_south", "7a_c-06_north", [[ItemName.dream_blocks, ], ]), + "7a_c-06_south---7a_c-06_east": RegionConnection("7a_c-06_south", "7a_c-06_east", [[ItemName.dream_blocks, ], ]), + "7a_c-06_north---7a_c-06_south": RegionConnection("7a_c-06_north", "7a_c-06_south", []), + "7a_c-06_east---7a_c-06_south": RegionConnection("7a_c-06_east", "7a_c-06_south", [[ItemName.dream_blocks, ], ]), + + "7a_c-06b_south---7a_c-06b_east": RegionConnection("7a_c-06b_south", "7a_c-06b_east", [[ItemName.dream_blocks, ItemName.dream_blocks, ], ]), + "7a_c-06b_west---7a_c-06b_east": RegionConnection("7a_c-06b_west", "7a_c-06b_east", [[ItemName.dream_blocks, ], ]), + "7a_c-06b_east---7a_c-06b_north": RegionConnection("7a_c-06b_east", "7a_c-06b_north", [[ItemName.dream_blocks, ], ]), + + + "7a_c-07_west---7a_c-07_south-west": RegionConnection("7a_c-07_west", "7a_c-07_south-west", []), + "7a_c-07_south-west---7a_c-07_west": RegionConnection("7a_c-07_south-west", "7a_c-07_west", []), + "7a_c-07_south-west---7a_c-07_south-east": RegionConnection("7a_c-07_south-west", "7a_c-07_south-east", []), + "7a_c-07_south-east---7a_c-07_south-west": RegionConnection("7a_c-07_south-east", "7a_c-07_south-west", []), + "7a_c-07_south-east---7a_c-07_east": RegionConnection("7a_c-07_south-east", "7a_c-07_east", [[ItemName.dream_blocks, ], ]), + "7a_c-07_east---7a_c-07_south-east": RegionConnection("7a_c-07_east", "7a_c-07_south-east", [[ItemName.dream_blocks, ], ]), + + + "7a_c-08_west---7a_c-08_east": RegionConnection("7a_c-08_west", "7a_c-08_east", [[ItemName.dream_blocks, ], ]), + "7a_c-08_east---7a_c-08_west": RegionConnection("7a_c-08_east", "7a_c-08_west", [[ItemName.dream_blocks, ], ]), + + "7a_c-09_bottom---7a_c-09_top": RegionConnection("7a_c-09_bottom", "7a_c-09_top", [[ItemName.dream_blocks, ItemName.badeline_boosters, ], ]), + "7a_c-09_top---7a_c-09_bottom": RegionConnection("7a_c-09_top", "7a_c-09_bottom", [[ItemName.dream_blocks, ], ]), + + "7a_d-00_bottom---7a_d-00_top": RegionConnection("7a_d-00_bottom", "7a_d-00_top", [[ItemName.dash_refills, ], ]), + "7a_d-00_top---7a_d-00_bottom": RegionConnection("7a_d-00_top", "7a_d-00_bottom", []), + + "7a_d-01_west---7a_d-01_east": RegionConnection("7a_d-01_west", "7a_d-01_east", [[ItemName.sinking_platforms, ], ]), + "7a_d-01_east---7a_d-01_west": RegionConnection("7a_d-01_east", "7a_d-01_west", [[ItemName.sinking_platforms, ], ]), + + "7a_d-01b_west---7a_d-01b_east": RegionConnection("7a_d-01b_west", "7a_d-01b_east", []), + "7a_d-01b_west---7a_d-01b_south-west": RegionConnection("7a_d-01b_west", "7a_d-01b_south-west", []), + "7a_d-01b_south-west---7a_d-01b_west": RegionConnection("7a_d-01b_south-west", "7a_d-01b_west", []), + "7a_d-01b_east---7a_d-01b_west": RegionConnection("7a_d-01b_east", "7a_d-01b_west", []), + "7a_d-01b_south-east---7a_d-01b_east": RegionConnection("7a_d-01b_south-east", "7a_d-01b_east", []), + + "7a_d-01c_west---7a_d-01c_east": RegionConnection("7a_d-01c_west", "7a_d-01c_east", []), + "7a_d-01c_south---7a_d-01c_east": RegionConnection("7a_d-01c_south", "7a_d-01c_east", []), + "7a_d-01c_east---7a_d-01c_west": RegionConnection("7a_d-01c_east", "7a_d-01c_west", []), + "7a_d-01c_east---7a_d-01c_south": RegionConnection("7a_d-01c_east", "7a_d-01c_south", []), + "7a_d-01c_south-east---7a_d-01c_east": RegionConnection("7a_d-01c_south-east", "7a_d-01c_east", []), + + "7a_d-01d_west---7a_d-01d_east": RegionConnection("7a_d-01d_west", "7a_d-01d_east", []), + "7a_d-01d_east---7a_d-01d_west": RegionConnection("7a_d-01d_east", "7a_d-01d_west", []), + + "7a_d-02_west---7a_d-02_east": RegionConnection("7a_d-02_west", "7a_d-02_east", [[ItemName.coins, ], ]), + + "7a_d-03_west---7a_d-03_east": RegionConnection("7a_d-03_west", "7a_d-03_east", []), + "7a_d-03_west---7a_d-03_north-east": RegionConnection("7a_d-03_west", "7a_d-03_north-east", []), + "7a_d-03_north-west---7a_d-03_west": RegionConnection("7a_d-03_north-west", "7a_d-03_west", []), + "7a_d-03_east---7a_d-03_west": RegionConnection("7a_d-03_east", "7a_d-03_west", [[ItemName.cannot_access, ], ]), + "7a_d-03_north-east---7a_d-03_west": RegionConnection("7a_d-03_north-east", "7a_d-03_west", []), + + "7a_d-03b_west---7a_d-03b_east": RegionConnection("7a_d-03b_west", "7a_d-03b_east", []), + "7a_d-03b_east---7a_d-03b_west": RegionConnection("7a_d-03b_east", "7a_d-03b_west", []), + + "7a_d-04_west---7a_d-04_east": RegionConnection("7a_d-04_west", "7a_d-04_east", []), + "7a_d-04_east---7a_d-04_west": RegionConnection("7a_d-04_east", "7a_d-04_west", []), + + "7a_d-05_west---7a_d-05_east": RegionConnection("7a_d-05_west", "7a_d-05_east", [[ItemName.coins, ], [ItemName.dash_refills, ], ]), + "7a_d-05_north-east---7a_d-05_east": RegionConnection("7a_d-05_north-east", "7a_d-05_east", []), + "7a_d-05_east---7a_d-05_west": RegionConnection("7a_d-05_east", "7a_d-05_west", [[ItemName.dash_refills, ], ]), + "7a_d-05_east---7a_d-05_north-east": RegionConnection("7a_d-05_east", "7a_d-05_north-east", []), + + + "7a_d-06_west---7a_d-06_south-west": RegionConnection("7a_d-06_west", "7a_d-06_south-west", []), + "7a_d-06_south-west---7a_d-06_west": RegionConnection("7a_d-06_south-west", "7a_d-06_west", []), + "7a_d-06_south-west---7a_d-06_east": RegionConnection("7a_d-06_south-west", "7a_d-06_east", []), + "7a_d-06_south-east---7a_d-06_west": RegionConnection("7a_d-06_south-east", "7a_d-06_west", []), + "7a_d-06_south-east---7a_d-06_east": RegionConnection("7a_d-06_south-east", "7a_d-06_east", []), + "7a_d-06_east---7a_d-06_south-east": RegionConnection("7a_d-06_east", "7a_d-06_south-east", []), + + + "7a_d-08_west---7a_d-08_east": RegionConnection("7a_d-08_west", "7a_d-08_east", [[ItemName.dash_refills, ], ]), + "7a_d-08_east---7a_d-08_west": RegionConnection("7a_d-08_east", "7a_d-08_west", [[ItemName.dash_refills, ], ]), + + "7a_d-09_west---7a_d-09_east": RegionConnection("7a_d-09_west", "7a_d-09_east", [[ItemName.springs, ], ]), + + "7a_d-10_west---7a_d-10_north-west": RegionConnection("7a_d-10_west", "7a_d-10_north-west", []), + "7a_d-10_north-west---7a_d-10_west": RegionConnection("7a_d-10_north-west", "7a_d-10_west", []), + "7a_d-10_north-west---7a_d-10_east": RegionConnection("7a_d-10_north-west", "7a_d-10_east", []), + "7a_d-10_north---7a_d-10_north-west": RegionConnection("7a_d-10_north", "7a_d-10_north-west", []), + "7a_d-10_north---7a_d-10_north-east": RegionConnection("7a_d-10_north", "7a_d-10_north-east", [[ItemName.dash_refills, ], ]), + "7a_d-10_north-east---7a_d-10_north": RegionConnection("7a_d-10_north-east", "7a_d-10_north", [[ItemName.dash_refills, ], ]), + "7a_d-10_north-east---7a_d-10_east": RegionConnection("7a_d-10_north-east", "7a_d-10_east", [[ItemName.dash_refills, ], ]), + "7a_d-10_east---7a_d-10_north-east": RegionConnection("7a_d-10_east", "7a_d-10_north-east", [[ItemName.dash_refills, ], ]), + + "7a_d-10b_west---7a_d-10b_east": RegionConnection("7a_d-10b_west", "7a_d-10b_east", []), + "7a_d-10b_east---7a_d-10b_west": RegionConnection("7a_d-10b_east", "7a_d-10b_west", []), + + "7a_d-11_bottom---7a_d-11_top": RegionConnection("7a_d-11_bottom", "7a_d-11_top", [[ItemName.badeline_boosters, ], ]), + "7a_d-11_top---7a_d-11_bottom": RegionConnection("7a_d-11_top", "7a_d-11_bottom", []), + + "7a_e-00b_bottom---7a_e-00b_top": RegionConnection("7a_e-00b_bottom", "7a_e-00b_top", [[ItemName.blue_boosters, ], ]), + "7a_e-00b_top---7a_e-00b_bottom": RegionConnection("7a_e-00b_top", "7a_e-00b_bottom", [[ItemName.blue_boosters, ], ]), + + "7a_e-00_west---7a_e-00_south-west": RegionConnection("7a_e-00_west", "7a_e-00_south-west", []), + "7a_e-00_west---7a_e-00_north-west": RegionConnection("7a_e-00_west", "7a_e-00_north-west", []), + "7a_e-00_south-west---7a_e-00_east": RegionConnection("7a_e-00_south-west", "7a_e-00_east", [[ItemName.blue_boosters, ItemName.blue_clouds, ], ]), + "7a_e-00_south-west---7a_e-00_west": RegionConnection("7a_e-00_south-west", "7a_e-00_west", []), + "7a_e-00_north-west---7a_e-00_south-west": RegionConnection("7a_e-00_north-west", "7a_e-00_south-west", []), + "7a_e-00_east---7a_e-00_south-west": RegionConnection("7a_e-00_east", "7a_e-00_south-west", [[ItemName.blue_boosters, ItemName.blue_clouds, ], ]), + + "7a_e-01_north---7a_e-01_east": RegionConnection("7a_e-01_north", "7a_e-01_east", []), + "7a_e-01_east---7a_e-01_west": RegionConnection("7a_e-01_east", "7a_e-01_west", []), + + "7a_e-01b_west---7a_e-01b_east": RegionConnection("7a_e-01b_west", "7a_e-01b_east", []), + "7a_e-01b_east---7a_e-01b_west": RegionConnection("7a_e-01b_east", "7a_e-01b_west", []), + + "7a_e-01c_west---7a_e-01c_east": RegionConnection("7a_e-01c_west", "7a_e-01c_east", [[ItemName.move_blocks, ], ]), + + "7a_e-02_west---7a_e-02_east": RegionConnection("7a_e-02_west", "7a_e-02_east", [[ItemName.pink_clouds, ], ]), + + "7a_e-03_south-west---7a_e-03_east": RegionConnection("7a_e-03_south-west", "7a_e-03_east", [[ItemName.blue_boosters, ItemName.moving_platforms, ], ]), + "7a_e-03_west---7a_e-03_east": RegionConnection("7a_e-03_west", "7a_e-03_east", []), + "7a_e-03_east---7a_e-03_west": RegionConnection("7a_e-03_east", "7a_e-03_west", []), + + "7a_e-04_west---7a_e-04_east": RegionConnection("7a_e-04_west", "7a_e-04_east", [[ItemName.blue_boosters, ItemName.springs, ], ]), + + "7a_e-05_west---7a_e-05_east": RegionConnection("7a_e-05_west", "7a_e-05_east", []), + "7a_e-05_east---7a_e-05_west": RegionConnection("7a_e-05_east", "7a_e-05_west", []), + + "7a_e-06_west---7a_e-06_east": RegionConnection("7a_e-06_west", "7a_e-06_east", [[ItemName.move_blocks, ], ]), + + "7a_e-07_bottom---7a_e-07_top": RegionConnection("7a_e-07_bottom", "7a_e-07_top", [[ItemName.move_blocks, ], ]), + + "7a_e-08_south---7a_e-08_west": RegionConnection("7a_e-08_south", "7a_e-08_west", [[ItemName.blue_clouds, ], ]), + "7a_e-08_south---7a_e-08_east": RegionConnection("7a_e-08_south", "7a_e-08_east", [[ItemName.blue_clouds, ], ]), + "7a_e-08_west---7a_e-08_south": RegionConnection("7a_e-08_west", "7a_e-08_south", []), + "7a_e-08_east---7a_e-08_south": RegionConnection("7a_e-08_east", "7a_e-08_south", []), + + "7a_e-09_north---7a_e-09_east": RegionConnection("7a_e-09_north", "7a_e-09_east", []), + "7a_e-09_east---7a_e-09_north": RegionConnection("7a_e-09_east", "7a_e-09_north", []), + + "7a_e-11_south---7a_e-11_north": RegionConnection("7a_e-11_south", "7a_e-11_north", [[ItemName.move_blocks, ], ]), + "7a_e-11_south---7a_e-11_east": RegionConnection("7a_e-11_south", "7a_e-11_east", [[ItemName.move_blocks, ItemName.blue_boosters, ], ]), + "7a_e-11_north---7a_e-11_south": RegionConnection("7a_e-11_north", "7a_e-11_south", []), + + + "7a_e-10_south---7a_e-10_east": RegionConnection("7a_e-10_south", "7a_e-10_east", [[ItemName.blue_boosters, ], ]), + "7a_e-10_north---7a_e-10_south": RegionConnection("7a_e-10_north", "7a_e-10_south", []), + + "7a_e-10b_west---7a_e-10b_east": RegionConnection("7a_e-10b_west", "7a_e-10b_east", [[ItemName.move_blocks, ItemName.dash_refills, ItemName.springs, ], ]), + + "7a_e-13_bottom---7a_e-13_top": RegionConnection("7a_e-13_bottom", "7a_e-13_top", [[ItemName.badeline_boosters, ItemName.dash_refills, ItemName.move_blocks, ItemName.blue_boosters, ItemName.springs, ], ]), + + "7a_f-00_south---7a_f-00_west": RegionConnection("7a_f-00_south", "7a_f-00_west", []), + "7a_f-00_south---7a_f-00_east": RegionConnection("7a_f-00_south", "7a_f-00_east", [[ItemName.red_boosters, ], ]), + "7a_f-00_west---7a_f-00_south": RegionConnection("7a_f-00_west", "7a_f-00_south", []), + "7a_f-00_north-west---7a_f-00_west": RegionConnection("7a_f-00_north-west", "7a_f-00_west", []), + "7a_f-00_north-west---7a_f-00_north-east": RegionConnection("7a_f-00_north-west", "7a_f-00_north-east", [[ItemName.red_boosters, ], ]), + + "7a_f-01_south---7a_f-01_north": RegionConnection("7a_f-01_south", "7a_f-01_north", []), + "7a_f-01_north---7a_f-01_south": RegionConnection("7a_f-01_north", "7a_f-01_south", []), + + "7a_f-02_west---7a_f-02_east": RegionConnection("7a_f-02_west", "7a_f-02_east", [[ItemName.swap_blocks, ], ]), + "7a_f-02_north-west---7a_f-02_north-east": RegionConnection("7a_f-02_north-west", "7a_f-02_north-east", [[ItemName.red_boosters, ], ]), + "7a_f-02_north-east---7a_f-02_east": RegionConnection("7a_f-02_north-east", "7a_f-02_east", []), + + "7a_f-02b_west---7a_f-02b_east": RegionConnection("7a_f-02b_west", "7a_f-02b_east", [[ItemName.red_boosters, ItemName.dash_refills, ItemName.swap_blocks, ItemName.dash_switches, ], ]), + + "7a_f-04_west---7a_f-04_east": RegionConnection("7a_f-04_west", "7a_f-04_east", [[ItemName.swap_blocks, ], ]), + + "7a_f-03_west---7a_f-03_east": RegionConnection("7a_f-03_west", "7a_f-03_east", [[ItemName.swap_blocks, ItemName.dash_refills, ], ]), + "7a_f-03_east---7a_f-03_west": RegionConnection("7a_f-03_east", "7a_f-03_west", [[ItemName.swap_blocks, ItemName.dash_refills, ], ]), + + "7a_f-05_west---7a_f-05_south": RegionConnection("7a_f-05_west", "7a_f-05_south", []), + "7a_f-05_south-west---7a_f-05_south": RegionConnection("7a_f-05_south-west", "7a_f-05_south", []), + "7a_f-05_north-west---7a_f-05_south": RegionConnection("7a_f-05_north-west", "7a_f-05_south", []), + "7a_f-05_south---7a_f-05_west": RegionConnection("7a_f-05_south", "7a_f-05_west", []), + "7a_f-05_south---7a_f-05_south-west": RegionConnection("7a_f-05_south", "7a_f-05_south-west", []), + "7a_f-05_south---7a_f-05_north-west": RegionConnection("7a_f-05_south", "7a_f-05_north-west", []), + "7a_f-05_south---7a_f-05_north": RegionConnection("7a_f-05_south", "7a_f-05_north", []), + "7a_f-05_south---7a_f-05_north-east": RegionConnection("7a_f-05_south", "7a_f-05_north-east", []), + "7a_f-05_south---7a_f-05_south-east": RegionConnection("7a_f-05_south", "7a_f-05_south-east", []), + "7a_f-05_south---7a_f-05_east": RegionConnection("7a_f-05_south", "7a_f-05_east", [["The Summit A - 2500 M Key", ], ]), + "7a_f-05_north---7a_f-05_south": RegionConnection("7a_f-05_north", "7a_f-05_south", []), + "7a_f-05_north-east---7a_f-05_south": RegionConnection("7a_f-05_north-east", "7a_f-05_south", []), + "7a_f-05_south-east---7a_f-05_south": RegionConnection("7a_f-05_south-east", "7a_f-05_south", []), + + "7a_f-06_north-west---7a_f-06_north": RegionConnection("7a_f-06_north-west", "7a_f-06_north", []), + "7a_f-06_north---7a_f-06_north-west": RegionConnection("7a_f-06_north", "7a_f-06_north-west", []), + "7a_f-06_north---7a_f-06_north-east": RegionConnection("7a_f-06_north", "7a_f-06_north-east", []), + "7a_f-06_north-east---7a_f-06_north": RegionConnection("7a_f-06_north-east", "7a_f-06_north", []), + + "7a_f-07_west---7a_f-07_south-west": RegionConnection("7a_f-07_west", "7a_f-07_south-west", []), + + "7a_f-08_west---7a_f-08_north-west": RegionConnection("7a_f-08_west", "7a_f-08_north-west", [[ItemName.red_boosters, ], ]), + "7a_f-08_west---7a_f-08_east": RegionConnection("7a_f-08_west", "7a_f-08_east", [[ItemName.swap_blocks, ItemName.red_boosters, ItemName.dash_refills, ], ]), + "7a_f-08_north-west---7a_f-08_west": RegionConnection("7a_f-08_north-west", "7a_f-08_west", []), + + "7a_f-08b_west---7a_f-08b_east": RegionConnection("7a_f-08b_west", "7a_f-08b_east", [[ItemName.springs, ], ]), + "7a_f-08b_east---7a_f-08b_west": RegionConnection("7a_f-08b_east", "7a_f-08b_west", [[ItemName.springs, ], ]), + + "7a_f-08d_west---7a_f-08d_east": RegionConnection("7a_f-08d_west", "7a_f-08d_east", [[ItemName.dash_switches, ItemName.springs, ], ]), + + "7a_f-08c_west---7a_f-08c_east": RegionConnection("7a_f-08c_west", "7a_f-08c_east", [[ItemName.swap_blocks, ItemName.dash_refills, ], ]), + + "7a_f-09_west---7a_f-09_east": RegionConnection("7a_f-09_west", "7a_f-09_east", [[ItemName.red_boosters, ], ]), + + "7a_f-10_west---7a_f-10_east": RegionConnection("7a_f-10_west", "7a_f-10_east", [[ItemName.swap_blocks, ], ]), + "7a_f-10_north-east---7a_f-10_east": RegionConnection("7a_f-10_north-east", "7a_f-10_east", []), + + "7a_f-10b_west---7a_f-10b_east": RegionConnection("7a_f-10b_west", "7a_f-10b_east", [[ItemName.springs, ItemName.dash_refills, ItemName.dash_switches, ], ]), + + "7a_f-11_bottom---7a_f-11_top": RegionConnection("7a_f-11_bottom", "7a_f-11_top", [[ItemName.badeline_boosters, ItemName.swap_blocks, ItemName.springs, ItemName.red_boosters, ], ]), + "7a_f-11_top---7a_f-11_bottom": RegionConnection("7a_f-11_top", "7a_f-11_bottom", []), + + "7a_g-00_bottom---7a_g-00_top": RegionConnection("7a_g-00_bottom", "7a_g-00_top", [[ItemName.dash_refills, ItemName.badeline_boosters, ], ]), + + "7a_g-00b_bottom---7a_g-00b_c26": RegionConnection("7a_g-00b_bottom", "7a_g-00b_c26", []), + "7a_g-00b_c26---7a_g-00b_c24": RegionConnection("7a_g-00b_c26", "7a_g-00b_c24", [[ItemName.dash_refills, ], ]), + "7a_g-00b_c24---7a_g-00b_c21": RegionConnection("7a_g-00b_c24", "7a_g-00b_c21", [[ItemName.springs, ], ]), + "7a_g-00b_c21---7a_g-00b_top": RegionConnection("7a_g-00b_c21", "7a_g-00b_top", [[ItemName.springs, ItemName.dash_refills, ItemName.badeline_boosters, ], ]), + + "7a_g-01_bottom---7a_g-01_c18": RegionConnection("7a_g-01_bottom", "7a_g-01_c18", [[ItemName.blue_clouds, ], ]), + "7a_g-01_c18---7a_g-01_c16": RegionConnection("7a_g-01_c18", "7a_g-01_c16", [[ItemName.dash_refills, ItemName.blue_clouds, ], ]), + "7a_g-01_c16---7a_g-01_top": RegionConnection("7a_g-01_c16", "7a_g-01_top", [[ItemName.springs, ItemName.coins, ItemName.dash_refills, ItemName.pink_clouds, ItemName.badeline_boosters, ], ]), + + "7a_g-02_bottom---7a_g-02_top": RegionConnection("7a_g-02_bottom", "7a_g-02_top", [[ItemName.blue_clouds, ItemName.feathers, ], ]), + + "7a_g-03_bottom---7a_g-03_goal": RegionConnection("7a_g-03_bottom", "7a_g-03_goal", [[ItemName.springs, ItemName.dash_refills, ItemName.feathers, ], ]), + + "7b_a-00_west---7b_a-00_east": RegionConnection("7b_a-00_west", "7b_a-00_east", [[ItemName.springs, ], ]), + + "7b_a-01_west---7b_a-01_east": RegionConnection("7b_a-01_west", "7b_a-01_east", [[ItemName.springs, ], ]), + + "7b_a-02_west---7b_a-02_east": RegionConnection("7b_a-02_west", "7b_a-02_east", [[ItemName.springs, ], ]), + + "7b_a-03_bottom---7b_a-03_top": RegionConnection("7b_a-03_bottom", "7b_a-03_top", [[ItemName.springs, ItemName.badeline_boosters, ], ]), + + "7b_b-00_bottom---7b_b-00_top": RegionConnection("7b_b-00_bottom", "7b_b-00_top", [[ItemName.dash_refills, ItemName.traffic_blocks, ], ]), + "7b_b-00_top---7b_b-00_bottom": RegionConnection("7b_b-00_top", "7b_b-00_bottom", []), + + "7b_b-01_bottom---7b_b-01_top": RegionConnection("7b_b-01_bottom", "7b_b-01_top", [[ItemName.traffic_blocks, ], ]), + "7b_b-01_top---7b_b-01_bottom": RegionConnection("7b_b-01_top", "7b_b-01_bottom", []), + + "7b_b-02_west---7b_b-02_east": RegionConnection("7b_b-02_west", "7b_b-02_east", [[ItemName.springs, ], ]), + + "7b_b-03_bottom---7b_b-03_top": RegionConnection("7b_b-03_bottom", "7b_b-03_top", [[ItemName.traffic_blocks, ItemName.badeline_boosters, ], ]), + + "7b_c-01_west---7b_c-01_east": RegionConnection("7b_c-01_west", "7b_c-01_east", [[ItemName.dream_blocks, ItemName.springs, ], ]), + + "7b_c-00_west---7b_c-00_east": RegionConnection("7b_c-00_west", "7b_c-00_east", [[ItemName.dream_blocks, ], ]), + + "7b_c-02_west---7b_c-02_east": RegionConnection("7b_c-02_west", "7b_c-02_east", [[ItemName.dream_blocks, ItemName.springs, ], ]), + + "7b_c-03_bottom---7b_c-03_top": RegionConnection("7b_c-03_bottom", "7b_c-03_top", [[ItemName.dream_blocks, ItemName.badeline_boosters, ], ]), + + "7b_d-00_west---7b_d-00_east": RegionConnection("7b_d-00_west", "7b_d-00_east", [[ItemName.springs, ], ]), + + "7b_d-01_west---7b_d-01_east": RegionConnection("7b_d-01_west", "7b_d-01_east", [[ItemName.dash_refills, ], ]), + + "7b_d-02_west---7b_d-02_east": RegionConnection("7b_d-02_west", "7b_d-02_east", [[ItemName.springs, ItemName.moving_platforms, ItemName.coins, ], ]), + + "7b_d-03_bottom---7b_d-03_top": RegionConnection("7b_d-03_bottom", "7b_d-03_top", [[ItemName.springs, ItemName.badeline_boosters, ], ]), + + "7b_e-00_west---7b_e-00_east": RegionConnection("7b_e-00_west", "7b_e-00_east", [[ItemName.blue_boosters, ItemName.blue_clouds, ], ]), + + "7b_e-01_west---7b_e-01_east": RegionConnection("7b_e-01_west", "7b_e-01_east", [[ItemName.move_blocks, ItemName.springs, ], ]), + + "7b_e-02_west---7b_e-02_east": RegionConnection("7b_e-02_west", "7b_e-02_east", []), + + "7b_e-03_bottom---7b_e-03_top": RegionConnection("7b_e-03_bottom", "7b_e-03_top", [[ItemName.blue_clouds, ItemName.pink_clouds, ItemName.coins, ItemName.badeline_boosters, ], ]), + + "7b_f-00_west---7b_f-00_east": RegionConnection("7b_f-00_west", "7b_f-00_east", [[ItemName.springs, ItemName.swap_blocks, ], ]), + + "7b_f-01_west---7b_f-01_east": RegionConnection("7b_f-01_west", "7b_f-01_east", [[ItemName.red_boosters, ], ]), + + "7b_f-02_west---7b_f-02_east": RegionConnection("7b_f-02_west", "7b_f-02_east", [[ItemName.springs, ItemName.swap_blocks, ItemName.dash_refills, ], ]), + + "7b_f-03_bottom---7b_f-03_top": RegionConnection("7b_f-03_bottom", "7b_f-03_top", [[ItemName.dash_refills, ItemName.swap_blocks, ItemName.dash_refills, ItemName.badeline_boosters, ], ]), + + "7b_g-00_bottom---7b_g-00_top": RegionConnection("7b_g-00_bottom", "7b_g-00_top", [[ItemName.springs, ItemName.dash_refills, ItemName.badeline_boosters, ], ]), + + "7b_g-01_bottom---7b_g-01_top": RegionConnection("7b_g-01_bottom", "7b_g-01_top", [[ItemName.springs, ItemName.dash_refills, ItemName.pink_clouds, ItemName.blue_clouds, ItemName.badeline_boosters, ], ]), + + "7b_g-02_bottom---7b_g-02_top": RegionConnection("7b_g-02_bottom", "7b_g-02_top", [[ItemName.springs, ItemName.dash_refills, ItemName.pink_clouds, ItemName.blue_clouds, ItemName.badeline_boosters, ], ]), + + "7b_g-03_bottom---7b_g-03_goal": RegionConnection("7b_g-03_bottom", "7b_g-03_goal", [[ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ItemName.blue_clouds, ], ]), + + "7c_01_west---7c_01_east": RegionConnection("7c_01_west", "7c_01_east", [[ItemName.dash_refills, ItemName.badeline_boosters, ], ]), + + "7c_02_west---7c_02_east": RegionConnection("7c_02_west", "7c_02_east", [[ItemName.springs, ItemName.coins, ItemName.badeline_boosters, ], ]), + + "7c_03_west---7c_03_goal": RegionConnection("7c_03_west", "7c_03_goal", [[ItemName.pink_clouds, ItemName.dash_refills, ItemName.springs, ], ]), + + + "8a_bridge_west---8a_bridge_east": RegionConnection("8a_bridge_west", "8a_bridge_east", []), + "8a_bridge_east---8a_bridge_west": RegionConnection("8a_bridge_east", "8a_bridge_west", []), + + + "9a_00_west---9a_00_east": RegionConnection("9a_00_west", "9a_00_east", []), + "9a_00_east---9a_00_west": RegionConnection("9a_00_east", "9a_00_west", []), + + + "9a_01_west---9a_01_east": RegionConnection("9a_01_west", "9a_01_east", [[ItemName.dash_refills, ], ]), + "9a_01_east---9a_01_west": RegionConnection("9a_01_east", "9a_01_west", []), + + "9a_02_west---9a_02_east": RegionConnection("9a_02_west", "9a_02_east", []), + "9a_02_east---9a_02_west": RegionConnection("9a_02_east", "9a_02_west", []), + + "9a_a-00_west---9a_a-00_east": RegionConnection("9a_a-00_west", "9a_a-00_east", [[ItemName.dash_refills, ], ]), + "9a_a-00_east---9a_a-00_west": RegionConnection("9a_a-00_east", "9a_a-00_west", []), + + "9a_a-01_west---9a_a-01_east": RegionConnection("9a_a-01_west", "9a_a-01_east", [[ItemName.dash_refills, ItemName.springs, ], ]), + "9a_a-01_east---9a_a-01_west": RegionConnection("9a_a-01_east", "9a_a-01_west", []), + + "9a_a-02_west---9a_a-02_east": RegionConnection("9a_a-02_west", "9a_a-02_east", [[ItemName.core_blocks, ], ]), + "9a_a-02_east---9a_a-02_west": RegionConnection("9a_a-02_east", "9a_a-02_west", [[ItemName.core_blocks, ], ]), + + "9a_a-03_bottom---9a_a-03_top": RegionConnection("9a_a-03_bottom", "9a_a-03_top", []), + "9a_a-03_top---9a_a-03_bottom": RegionConnection("9a_a-03_top", "9a_a-03_bottom", []), + + "9a_b-00_west---9a_b-00_south": RegionConnection("9a_b-00_west", "9a_b-00_south", []), + "9a_b-00_south---9a_b-00_west": RegionConnection("9a_b-00_south", "9a_b-00_west", []), + "9a_b-00_south---9a_b-00_east": RegionConnection("9a_b-00_south", "9a_b-00_east", []), + "9a_b-00_south---9a_b-00_north": RegionConnection("9a_b-00_south", "9a_b-00_north", [[ItemName.fire_ice_balls, ItemName.core_toggles, ItemName.core_blocks, ItemName.dash_refills, ItemName.coins, ], ]), + "9a_b-00_north---9a_b-00_south": RegionConnection("9a_b-00_north", "9a_b-00_south", []), + "9a_b-00_east---9a_b-00_south": RegionConnection("9a_b-00_east", "9a_b-00_south", []), + + "9a_b-01_west---9a_b-01_east": RegionConnection("9a_b-01_west", "9a_b-01_east", [[ItemName.core_blocks, ], ]), + "9a_b-01_east---9a_b-01_west": RegionConnection("9a_b-01_east", "9a_b-01_west", [[ItemName.core_blocks, ], ]), + + "9a_b-02_west---9a_b-02_east": RegionConnection("9a_b-02_west", "9a_b-02_east", [[ItemName.core_blocks, ], ]), + "9a_b-02_east---9a_b-02_west": RegionConnection("9a_b-02_east", "9a_b-02_west", [[ItemName.core_blocks, ], ]), + + "9a_b-03_west---9a_b-03_east": RegionConnection("9a_b-03_west", "9a_b-03_east", [[ItemName.core_blocks, ], ]), + "9a_b-03_east---9a_b-03_west": RegionConnection("9a_b-03_east", "9a_b-03_west", [[ItemName.core_blocks, ], ]), + + "9a_b-04_north-west---9a_b-04_east": RegionConnection("9a_b-04_north-west", "9a_b-04_east", [[ItemName.core_toggles, ], ]), + "9a_b-04_west---9a_b-04_east": RegionConnection("9a_b-04_west", "9a_b-04_east", [[ItemName.core_blocks, ItemName.core_toggles, ], ]), + + "9a_b-05_east---9a_b-05_west": RegionConnection("9a_b-05_east", "9a_b-05_west", [[ItemName.fire_ice_balls, ItemName.core_toggles, ItemName.dash_refills, ItemName.coins, ], ]), + + + "9a_b-07b_bottom---9a_b-07b_top": RegionConnection("9a_b-07b_bottom", "9a_b-07b_top", [[ItemName.dash_refills, ItemName.core_toggles, ], ]), + "9a_b-07b_top---9a_b-07b_bottom": RegionConnection("9a_b-07b_top", "9a_b-07b_bottom", []), + + "9a_b-07_bottom---9a_b-07_top": RegionConnection("9a_b-07_bottom", "9a_b-07_top", [[ItemName.core_toggles, ItemName.core_blocks, ItemName.bumpers, ], ]), + + "9a_c-00_west---9a_c-00_east": RegionConnection("9a_c-00_west", "9a_c-00_east", [[ItemName.core_toggles, ItemName.core_blocks, ItemName.dash_refills, ], ]), + "9a_c-00_north-east---9a_c-00_east": RegionConnection("9a_c-00_north-east", "9a_c-00_east", [[ItemName.core_toggles, ], ]), + "9a_c-00_east---9a_c-00_north-east": RegionConnection("9a_c-00_east", "9a_c-00_north-east", [[ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.dash_refills, ], ]), + + + "9a_c-01_west---9a_c-01_east": RegionConnection("9a_c-01_west", "9a_c-01_east", [[ItemName.core_blocks, ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.dash_refills, ], ]), + "9a_c-01_east---9a_c-01_west": RegionConnection("9a_c-01_east", "9a_c-01_west", [[ItemName.core_blocks, ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.dash_refills, ], ]), + + "9a_c-02_west---9a_c-02_east": RegionConnection("9a_c-02_west", "9a_c-02_east", [[ItemName.core_blocks, ItemName.core_toggles, ItemName.dash_refills, ItemName.bumpers, ], ]), + + "9a_c-03_west---9a_c-03_north": RegionConnection("9a_c-03_west", "9a_c-03_north", [[ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.dash_refills, ], ]), + "9a_c-03_west---9a_c-03_east": RegionConnection("9a_c-03_west", "9a_c-03_east", [[ItemName.core_blocks, ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.dash_refills, ], ]), + "9a_c-03_north-west---9a_c-03_west": RegionConnection("9a_c-03_north-west", "9a_c-03_west", []), + "9a_c-03_north-east---9a_c-03_east": RegionConnection("9a_c-03_north-east", "9a_c-03_east", []), + + "9a_c-03b_south---9a_c-03b_west": RegionConnection("9a_c-03b_south", "9a_c-03b_west", []), + "9a_c-03b_south---9a_c-03b_east": RegionConnection("9a_c-03b_south", "9a_c-03b_east", [[ItemName.core_toggles, ], ]), + "9a_c-03b_east---9a_c-03b_south": RegionConnection("9a_c-03b_east", "9a_c-03b_south", [[ItemName.core_toggles, ], ]), + + "9a_c-04_west---9a_c-04_east": RegionConnection("9a_c-04_west", "9a_c-04_east", [[ItemName.dash_refills, ], ]), + "9a_c-04_east---9a_c-04_west": RegionConnection("9a_c-04_east", "9a_c-04_west", [[ItemName.dash_refills, ], ]), + + "9a_d-00_bottom---9a_d-00_top": RegionConnection("9a_d-00_bottom", "9a_d-00_top", [[ItemName.dash_refills, ], ]), + + "9a_d-01_bottom---9a_d-01_top": RegionConnection("9a_d-01_bottom", "9a_d-01_top", [[ItemName.dash_refills, ], ]), + + "9a_d-02_bottom---9a_d-02_top": RegionConnection("9a_d-02_bottom", "9a_d-02_top", [[ItemName.dash_refills, ItemName.core_toggles, ], ]), + + "9a_d-03_bottom---9a_d-03_top": RegionConnection("9a_d-03_bottom", "9a_d-03_top", [[ItemName.dash_refills, ItemName.core_blocks, ItemName.core_toggles, ], ]), + + "9a_d-04_bottom---9a_d-04_top": RegionConnection("9a_d-04_bottom", "9a_d-04_top", [[ItemName.dash_refills, ], ]), + + "9a_d-05_bottom---9a_d-05_top": RegionConnection("9a_d-05_bottom", "9a_d-05_top", [[ItemName.dash_refills, ItemName.core_toggles, ItemName.fire_ice_balls, ], ]), + + "9a_d-06_bottom---9a_d-06_top": RegionConnection("9a_d-06_bottom", "9a_d-06_top", [[ItemName.dash_refills, ItemName.core_blocks, ], ]), + + "9a_d-07_bottom---9a_d-07_top": RegionConnection("9a_d-07_bottom", "9a_d-07_top", [[ItemName.dash_refills, ItemName.core_blocks, ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.springs, ItemName.badeline_boosters, ], ]), + + "9a_d-08_west---9a_d-08_east": RegionConnection("9a_d-08_west", "9a_d-08_east", [[ItemName.dash_refills, ItemName.core_blocks, ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.bumpers, ], ]), + + "9a_d-09_west---9a_d-09_east": RegionConnection("9a_d-09_west", "9a_d-09_east", [[ItemName.dash_refills, ItemName.core_toggles, ], ]), + + "9a_d-10_west---9a_d-10_east": RegionConnection("9a_d-10_west", "9a_d-10_east", [[ItemName.bumpers, ItemName.core_toggles, ], ]), + + "9a_d-10b_west---9a_d-10b_east": RegionConnection("9a_d-10b_west", "9a_d-10b_east", [[ItemName.dash_refills, ItemName.bumpers, ItemName.core_toggles, ItemName.core_blocks, ], ]), + + "9a_d-10c_west---9a_d-10c_east": RegionConnection("9a_d-10c_west", "9a_d-10c_east", [[ItemName.feathers, ItemName.core_toggles, ], ]), + + "9a_d-11_west---9a_d-11_center": RegionConnection("9a_d-11_west", "9a_d-11_center", [[ItemName.core_blocks, ItemName.core_toggles, ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ], ]), + "9a_d-11_center---9a_d-11_east": RegionConnection("9a_d-11_center", "9a_d-11_east", []), + + "9a_space_west---9a_space_goal": RegionConnection("9a_space_west", "9a_space_goal", []), + + + "9b_01_west---9b_01_east": RegionConnection("9b_01_west", "9b_01_east", []), + "9b_01_east---9b_01_west": RegionConnection("9b_01_east", "9b_01_west", []), + + "9b_a-00_west---9b_a-00_east": RegionConnection("9b_a-00_west", "9b_a-00_east", [[ItemName.dash_refills, ], ]), + "9b_a-00_east---9b_a-00_west": RegionConnection("9b_a-00_east", "9b_a-00_west", [[ItemName.dash_refills, ], ]), + + "9b_a-01_west---9b_a-01_east": RegionConnection("9b_a-01_west", "9b_a-01_east", [[ItemName.core_blocks, ], ]), + + "9b_a-02_west---9b_a-02_east": RegionConnection("9b_a-02_west", "9b_a-02_east", [[ItemName.core_blocks, ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.dash_refills, ], ]), + + "9b_a-03_west---9b_a-03_east": RegionConnection("9b_a-03_west", "9b_a-03_east", [[ItemName.fire_ice_balls, ], ]), + "9b_a-03_east---9b_a-03_west": RegionConnection("9b_a-03_east", "9b_a-03_west", [[ItemName.fire_ice_balls, ], ]), + + "9b_a-04_west---9b_a-04_east": RegionConnection("9b_a-04_west", "9b_a-04_east", [[ItemName.core_blocks, ItemName.dash_refills, ], ]), + + "9b_a-05_west---9b_a-05_east": RegionConnection("9b_a-05_west", "9b_a-05_east", [[ItemName.core_blocks, ItemName.core_toggles, ItemName.dash_refills, ItemName.bumpers, ], ]), + + "9b_b-00_west---9b_b-00_east": RegionConnection("9b_b-00_west", "9b_b-00_east", [[ItemName.core_blocks, ], ]), + + "9b_b-01_west---9b_b-01_east": RegionConnection("9b_b-01_west", "9b_b-01_east", [[ItemName.core_blocks, ItemName.core_toggles, ItemName.bumpers, ], ]), + + "9b_b-02_west---9b_b-02_east": RegionConnection("9b_b-02_west", "9b_b-02_east", [[ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.bumpers, ItemName.dash_refills, ItemName.coins, ], ]), + + "9b_b-03_west---9b_b-03_east": RegionConnection("9b_b-03_west", "9b_b-03_east", [[ItemName.dash_refills, ItemName.core_toggles, ], ]), + + "9b_b-04_west---9b_b-04_east": RegionConnection("9b_b-04_west", "9b_b-04_east", [[ItemName.dash_refills, ], ]), + + "9b_b-05_west---9b_b-05_east": RegionConnection("9b_b-05_west", "9b_b-05_east", [[ItemName.dash_refills, ItemName.core_toggles, ItemName.fire_ice_balls, ], ]), + + "9b_c-01_bottom---9b_c-01_top": RegionConnection("9b_c-01_bottom", "9b_c-01_top", [[ItemName.dash_refills, ItemName.core_blocks, ItemName.core_toggles, ItemName.springs, ], ]), + + "9b_c-02_bottom---9b_c-02_top": RegionConnection("9b_c-02_bottom", "9b_c-02_top", [[ItemName.dash_refills, ItemName.core_toggles, ItemName.bumpers, ItemName.fire_ice_balls, ], ]), + + "9b_c-03_bottom---9b_c-03_top": RegionConnection("9b_c-03_bottom", "9b_c-03_top", [[ItemName.dash_refills, ItemName.springs, ], ]), + + "9b_c-04_bottom---9b_c-04_top": RegionConnection("9b_c-04_bottom", "9b_c-04_top", [[ItemName.dash_refills, ItemName.springs, ItemName.traffic_blocks, ItemName.dream_blocks, ItemName.moving_platforms, ItemName.blue_clouds, ItemName.swap_blocks, ItemName.kevin_blocks, ItemName.core_blocks, ItemName.badeline_boosters, ], ]), + + "9b_c-05_west---9b_c-05_east": RegionConnection("9b_c-05_west", "9b_c-05_east", [[ItemName.dash_refills, ItemName.core_toggles, ItemName.core_blocks, ItemName.bumpers, ], ]), + + "9b_c-06_west---9b_c-06_east": RegionConnection("9b_c-06_west", "9b_c-06_east", [[ItemName.fire_ice_balls, ItemName.core_toggles, ItemName.core_blocks, ], ]), + "9b_c-06_east---9b_c-06_west": RegionConnection("9b_c-06_east", "9b_c-06_west", [[ItemName.fire_ice_balls, ItemName.core_toggles, ItemName.core_blocks, ], ]), + + "9b_c-08_west---9b_c-08_east": RegionConnection("9b_c-08_west", "9b_c-08_east", [[ItemName.dash_refills, ItemName.core_toggles, ], ]), + + "9b_c-07_west---9b_c-07_east": RegionConnection("9b_c-07_west", "9b_c-07_east", [[ItemName.dash_refills, ItemName.core_blocks, ], ]), + + "9b_space_west---9b_space_goal": RegionConnection("9b_space_west", "9b_space_goal", [[ItemName.dash_refills, ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ], ]), + + "9c_intro_west---9c_intro_east": RegionConnection("9c_intro_west", "9c_intro_east", []), + "9c_intro_east---9c_intro_west": RegionConnection("9c_intro_east", "9c_intro_west", []), + + "9c_00_west---9c_00_east": RegionConnection("9c_00_west", "9c_00_east", [[ItemName.dash_refills, ], ]), + + "9c_01_west---9c_01_east": RegionConnection("9c_01_west", "9c_01_east", [[ItemName.core_blocks, ItemName.dash_refills, ItemName.core_toggles, ItemName.bumpers, ], ]), + + "9c_02_west---9c_02_goal": RegionConnection("9c_02_west", "9c_02_goal", [[ItemName.springs, ItemName.traffic_blocks, ItemName.dash_refills, ItemName.core_toggles, ItemName.dream_blocks, ItemName.bumpers, ItemName.pink_clouds, ItemName.swap_blocks, ItemName.kevin_blocks, ItemName.core_blocks, ], ]), + + "10a_intro-00-past_west---10a_intro-00-past_east": RegionConnection("10a_intro-00-past_west", "10a_intro-00-past_east", []), + "10a_intro-00-past_east---10a_intro-00-past_west": RegionConnection("10a_intro-00-past_east", "10a_intro-00-past_west", []), + + "10a_intro-01-future_west---10a_intro-01-future_east": RegionConnection("10a_intro-01-future_west", "10a_intro-01-future_east", [[ItemName.badeline_boosters, ItemName.blue_clouds, ], ]), + + "10a_intro-02-launch_bottom---10a_intro-02-launch_top": RegionConnection("10a_intro-02-launch_bottom", "10a_intro-02-launch_top", [[ItemName.badeline_boosters, ItemName.blue_clouds, ], ]), + "10a_intro-02-launch_top---10a_intro-02-launch_bottom": RegionConnection("10a_intro-02-launch_top", "10a_intro-02-launch_bottom", []), + + "10a_intro-03-space_west---10a_intro-03-space_east": RegionConnection("10a_intro-03-space_west", "10a_intro-03-space_east", []), + "10a_intro-03-space_east---10a_intro-03-space_west": RegionConnection("10a_intro-03-space_east", "10a_intro-03-space_west", []), + + "10a_a-00_west---10a_a-00_east": RegionConnection("10a_a-00_west", "10a_a-00_east", [[ItemName.double_dash_refills, ], ]), + "10a_a-00_east---10a_a-00_west": RegionConnection("10a_a-00_east", "10a_a-00_west", []), + + "10a_a-01_west---10a_a-01_east": RegionConnection("10a_a-01_west", "10a_a-01_east", [[ItemName.double_dash_refills, ItemName.dash_refills, ], ]), + "10a_a-01_east---10a_a-01_west": RegionConnection("10a_a-01_east", "10a_a-01_west", [[ItemName.double_dash_refills, ItemName.dash_refills, ], ]), + + "10a_a-02_west---10a_a-02_east": RegionConnection("10a_a-02_west", "10a_a-02_east", [[ItemName.double_dash_refills, ItemName.swap_blocks, ], ]), + + "10a_a-03_west---10a_a-03_east": RegionConnection("10a_a-03_west", "10a_a-03_east", [[ItemName.double_dash_refills, ItemName.swap_blocks, ], ]), + + "10a_a-04_west---10a_a-04_east": RegionConnection("10a_a-04_west", "10a_a-04_east", [[ItemName.double_dash_refills, ItemName.springs, ], ]), + + "10a_a-05_west---10a_a-05_east": RegionConnection("10a_a-05_west", "10a_a-05_east", [[ItemName.coins, ItemName.springs, ], ]), + + "10a_b-00_west---10a_b-00_east": RegionConnection("10a_b-00_west", "10a_b-00_east", [[ItemName.pufferfish, ], ]), + + "10a_b-01_west---10a_b-01_east": RegionConnection("10a_b-01_west", "10a_b-01_east", [[ItemName.pufferfish, ], ]), + + "10a_b-02_west---10a_b-02_east": RegionConnection("10a_b-02_west", "10a_b-02_east", [[ItemName.pufferfish, ItemName.coins, ], ]), + + "10a_b-03_west---10a_b-03_east": RegionConnection("10a_b-03_west", "10a_b-03_east", [[ItemName.pufferfish, ItemName.coins, ItemName.dream_blocks, ], ]), + + "10a_b-04_west---10a_b-04_east": RegionConnection("10a_b-04_west", "10a_b-04_east", [[ItemName.pufferfish, ItemName.coins, ItemName.springs, ], ]), + + "10a_b-05_west---10a_b-05_east": RegionConnection("10a_b-05_west", "10a_b-05_east", [[ItemName.pufferfish, ItemName.springs, ], ]), + + "10a_b-06_west---10a_b-06_east": RegionConnection("10a_b-06_west", "10a_b-06_east", [[ItemName.pufferfish, ItemName.springs, ItemName.dream_blocks, ItemName.dash_refills, ], ]), + + "10a_b-07_west---10a_b-07_east": RegionConnection("10a_b-07_west", "10a_b-07_east", [[ItemName.double_dash_refills, ItemName.dash_refills, ], ]), + + "10a_c-00_west---10a_c-00_east": RegionConnection("10a_c-00_west", "10a_c-00_east", [[ItemName.jellyfish, ], ]), + "10a_c-00_west---10a_c-00_north-east": RegionConnection("10a_c-00_west", "10a_c-00_north-east", [[ItemName.jellyfish, ItemName.dash_refills, ], ]), + + "10a_c-00b_west---10a_c-00b_east": RegionConnection("10a_c-00b_west", "10a_c-00b_east", [[ItemName.jellyfish, ItemName.springs, ], ]), + + "10a_c-01_west---10a_c-01_east": RegionConnection("10a_c-01_west", "10a_c-01_east", [[ItemName.jellyfish, ], ]), + + "10a_c-02_west---10a_c-02_east": RegionConnection("10a_c-02_west", "10a_c-02_east", [[ItemName.jellyfish, ], ]), + + "10a_c-alt-00_west---10a_c-alt-00_east": RegionConnection("10a_c-alt-00_west", "10a_c-alt-00_east", [[ItemName.jellyfish, ItemName.double_dash_refills, ], ]), + + "10a_c-alt-01_west---10a_c-alt-01_east": RegionConnection("10a_c-alt-01_west", "10a_c-alt-01_east", []), + + "10a_c-03_south-west---10a_c-03_south": RegionConnection("10a_c-03_south-west", "10a_c-03_south", []), + "10a_c-03_south---10a_c-03_north": RegionConnection("10a_c-03_south", "10a_c-03_north", [[ItemName.jellyfish, ItemName.springs, ], ]), + "10a_c-03_north---10a_c-03_south": RegionConnection("10a_c-03_north", "10a_c-03_south", []), + + "10a_d-00_south---10a_d-00_south-east": RegionConnection("10a_d-00_south", "10a_d-00_south-east", [[ItemName.red_boosters, ], ]), + "10a_d-00_south---10a_d-00_north": RegionConnection("10a_d-00_south", "10a_d-00_north", [[ItemName.red_boosters, "Farewell - Power Source Key 1", "Farewell - Power Source Key 2", "Farewell - Power Source Key 3", "Farewell - Power Source Key 4", "Farewell - Power Source Key 5", ], ]), + "10a_d-00_north---10a_d-00_south": RegionConnection("10a_d-00_north", "10a_d-00_south", [["Farewell - Power Source Key 5", ], ]), + "10a_d-00_south-east---10a_d-00_south": RegionConnection("10a_d-00_south-east", "10a_d-00_south", [[ItemName.double_dash_refills, ItemName.dash_switches, ], ]), + "10a_d-00_south-east---10a_d-00_north-west": RegionConnection("10a_d-00_south-east", "10a_d-00_north-west", [[ItemName.double_dash_refills, ItemName.springs, ItemName.dash_switches, ], ]), + "10a_d-00_north-west---10a_d-00_south": RegionConnection("10a_d-00_north-west", "10a_d-00_south", [[ItemName.jellyfish, ItemName.dash_switches, ], ]), + "10a_d-00_north-west---10a_d-00_breaker": RegionConnection("10a_d-00_north-west", "10a_d-00_breaker", [[ItemName.jellyfish, ItemName.springs, ItemName.dash_switches, ItemName.breaker_boxes, ], ]), + "10a_d-00_breaker---10a_d-00_south": RegionConnection("10a_d-00_breaker", "10a_d-00_south", []), + "10a_d-00_breaker---10a_d-00_north-east-door": RegionConnection("10a_d-00_breaker", "10a_d-00_north-east-door", []), + "10a_d-00_breaker---10a_d-00_south-east-door": RegionConnection("10a_d-00_breaker", "10a_d-00_south-east-door", []), + "10a_d-00_breaker---10a_d-00_south-west-door": RegionConnection("10a_d-00_breaker", "10a_d-00_south-west-door", []), + "10a_d-00_breaker---10a_d-00_west-door": RegionConnection("10a_d-00_breaker", "10a_d-00_west-door", []), + "10a_d-00_breaker---10a_d-00_north-west-door": RegionConnection("10a_d-00_breaker", "10a_d-00_north-west-door", []), + "10a_d-00_north-east-door---10a_d-00_south": RegionConnection("10a_d-00_north-east-door", "10a_d-00_south", [[ItemName.breaker_boxes, ], ]), + "10a_d-00_south-east-door---10a_d-00_south": RegionConnection("10a_d-00_south-east-door", "10a_d-00_south", [[ItemName.breaker_boxes, ], ]), + "10a_d-00_south-west-door---10a_d-00_south": RegionConnection("10a_d-00_south-west-door", "10a_d-00_south", [[ItemName.breaker_boxes, ], ]), + "10a_d-00_west-door---10a_d-00_south": RegionConnection("10a_d-00_west-door", "10a_d-00_south", [[ItemName.breaker_boxes, ], ]), + "10a_d-00_north-west-door---10a_d-00_south": RegionConnection("10a_d-00_north-west-door", "10a_d-00_south", [[ItemName.breaker_boxes, ], ]), + + + + + + "10a_d-05_south---10a_d-05_north": RegionConnection("10a_d-05_south", "10a_d-05_north", [[ItemName.red_boosters, ], ]), + + "10a_e-00y_south---10a_e-00y_north": RegionConnection("10a_e-00y_south", "10a_e-00y_north", [[ItemName.red_boosters, ], ]), + "10a_e-00y_south---10a_e-00y_south-east": RegionConnection("10a_e-00y_south", "10a_e-00y_south-east", []), + "10a_e-00y_south-east---10a_e-00y_south": RegionConnection("10a_e-00y_south-east", "10a_e-00y_south", []), + "10a_e-00y_north-east---10a_e-00y_north": RegionConnection("10a_e-00y_north-east", "10a_e-00y_north", [[ItemName.red_boosters, ], ]), + + "10a_e-00yb_south---10a_e-00yb_north": RegionConnection("10a_e-00yb_south", "10a_e-00yb_north", [[ItemName.red_boosters, ItemName.dash_refills, ItemName.double_dash_refills, ], ]), + + "10a_e-00z_south---10a_e-00z_north": RegionConnection("10a_e-00z_south", "10a_e-00z_north", []), + "10a_e-00z_north---10a_e-00z_south": RegionConnection("10a_e-00z_north", "10a_e-00z_south", []), + + "10a_e-00_south---10a_e-00_north": RegionConnection("10a_e-00_south", "10a_e-00_north", [[ItemName.blue_clouds, ItemName.pufferfish, ItemName.coins, ItemName.double_dash_refills, ], ]), + + "10a_e-00b_south---10a_e-00b_north": RegionConnection("10a_e-00b_south", "10a_e-00b_north", [[ItemName.jellyfish, ItemName.springs, ], ]), + "10a_e-00b_north---10a_e-00b_south": RegionConnection("10a_e-00b_north", "10a_e-00b_south", []), + + "10a_e-01_south---10a_e-01_north": RegionConnection("10a_e-01_south", "10a_e-01_north", [[ItemName.jellyfish, ItemName.springs, ItemName.dash_refills, ], ]), + + "10a_e-02_west---10a_e-02_east": RegionConnection("10a_e-02_west", "10a_e-02_east", [[ItemName.jellyfish, ItemName.springs, ItemName.dash_refills, ItemName.coins, ], ]), + + "10a_e-03_west---10a_e-03_east": RegionConnection("10a_e-03_west", "10a_e-03_east", [[ItemName.pufferfish, ItemName.springs, ItemName.double_dash_refills, ], ]), + "10a_e-03_east---10a_e-03_east": RegionConnection("10a_e-03_east", "10a_e-03_east", [[ItemName.pufferfish, ], ]), + + "10a_e-04_west---10a_e-04_east": RegionConnection("10a_e-04_west", "10a_e-04_east", [[ItemName.jellyfish, ItemName.springs, ItemName.dash_switches, ], ]), + + "10a_e-05_west---10a_e-05_east": RegionConnection("10a_e-05_west", "10a_e-05_east", [[ItemName.pufferfish, ItemName.springs, ItemName.coins, ItemName.traffic_blocks, ], ]), + + "10a_e-05b_west---10a_e-05b_east": RegionConnection("10a_e-05b_west", "10a_e-05b_east", [[ItemName.pufferfish, ItemName.swap_blocks, ], ]), + + "10a_e-05c_west---10a_e-05c_east": RegionConnection("10a_e-05c_west", "10a_e-05c_east", [[ItemName.pufferfish, ItemName.swap_blocks, ItemName.double_dash_refills, ], ]), + + "10a_e-06_west---10a_e-06_east": RegionConnection("10a_e-06_west", "10a_e-06_east", [[ItemName.jellyfish, ItemName.springs, ItemName.dash_refills, ItemName.coins, ], ]), + + "10a_e-07_west---10a_e-07_east": RegionConnection("10a_e-07_west", "10a_e-07_east", [[ItemName.pufferfish, ItemName.springs, ItemName.double_dash_refills, ItemName.move_blocks, ], ]), + + "10a_e-08_west---10a_e-08_east": RegionConnection("10a_e-08_west", "10a_e-08_east", [[ItemName.jellyfish, ItemName.springs, ItemName.double_dash_refills, ItemName.coins, ], ]), + + "10b_f-door_west---10b_f-door_east": RegionConnection("10b_f-door_west", "10b_f-door_east", [[ItemName.double_dash_refills, ], ]), + "10b_f-door_east---10b_f-door_west": RegionConnection("10b_f-door_east", "10b_f-door_west", []), + + "10b_f-00_west---10b_f-00_east": RegionConnection("10b_f-00_west", "10b_f-00_east", [[ItemName.springs, ItemName.dream_blocks, ], ]), + + "10b_f-01_west---10b_f-01_east": RegionConnection("10b_f-01_west", "10b_f-01_east", []), + "10b_f-01_east---10b_f-01_west": RegionConnection("10b_f-01_east", "10b_f-01_west", []), + + "10b_f-02_west---10b_f-02_east": RegionConnection("10b_f-02_west", "10b_f-02_east", []), + + "10b_f-03_west---10b_f-03_east": RegionConnection("10b_f-03_west", "10b_f-03_east", [[ItemName.double_dash_refills, ], ]), + + "10b_f-04_west---10b_f-04_east": RegionConnection("10b_f-04_west", "10b_f-04_east", []), + "10b_f-04_east---10b_f-04_west": RegionConnection("10b_f-04_east", "10b_f-04_west", []), + + "10b_f-05_west---10b_f-05_east": RegionConnection("10b_f-05_west", "10b_f-05_east", [[ItemName.double_dash_refills, ], ]), + + "10b_f-06_west---10b_f-06_east": RegionConnection("10b_f-06_west", "10b_f-06_east", [[ItemName.double_dash_refills, ItemName.kevin_blocks, ItemName.dream_blocks, ItemName.coins, ], ]), + + "10b_f-07_west---10b_f-07_east": RegionConnection("10b_f-07_west", "10b_f-07_east", [[ItemName.dash_refills, ItemName.traffic_blocks, ], ]), + + "10b_f-08_west---10b_f-08_east": RegionConnection("10b_f-08_west", "10b_f-08_east", [[ItemName.dash_refills, ItemName.double_dash_refills, ItemName.coins, ItemName.move_blocks, ], ]), + + "10b_f-09_west---10b_f-09_east": RegionConnection("10b_f-09_west", "10b_f-09_east", [[ItemName.dash_refills, ItemName.double_dash_refills, ItemName.coins, ], ]), + + "10b_g-00_bottom---10b_g-00_top": RegionConnection("10b_g-00_bottom", "10b_g-00_top", [[ItemName.dash_refills, ItemName.traffic_blocks, ], ]), + "10b_g-00_top---10b_g-00_bottom": RegionConnection("10b_g-00_top", "10b_g-00_bottom", []), + + "10b_g-01_bottom---10b_g-01_top": RegionConnection("10b_g-01_bottom", "10b_g-01_top", [[ItemName.blue_boosters, ], ]), + "10b_g-01_top---10b_g-01_bottom": RegionConnection("10b_g-01_top", "10b_g-01_bottom", []), + + "10b_g-03_bottom---10b_g-03_top": RegionConnection("10b_g-03_bottom", "10b_g-03_top", [[ItemName.dream_blocks, ItemName.coins, ], ]), + + "10b_g-02_west---10b_g-02_east": RegionConnection("10b_g-02_west", "10b_g-02_east", [[ItemName.dream_blocks, ], ]), + + "10b_g-04_west---10b_g-04_east": RegionConnection("10b_g-04_west", "10b_g-04_east", [[ItemName.move_blocks, ItemName.springs, ], ]), + + "10b_g-05_west---10b_g-05_east": RegionConnection("10b_g-05_west", "10b_g-05_east", []), + + "10b_g-06_west---10b_g-06_east": RegionConnection("10b_g-06_west", "10b_g-06_east", [[ItemName.double_dash_refills, ItemName.feathers, ], ]), + + "10b_h-00b_west---10b_h-00b_east": RegionConnection("10b_h-00b_west", "10b_h-00b_east", [[ItemName.double_dash_refills, ItemName.feathers, ], ]), + + "10b_h-00_west---10b_h-00_east": RegionConnection("10b_h-00_west", "10b_h-00_east", [[ItemName.dash_refills, ItemName.swap_blocks, ], ]), + + "10b_h-01_west---10b_h-01_east": RegionConnection("10b_h-01_west", "10b_h-01_east", [[ItemName.dash_refills, ItemName.double_dash_refills, ItemName.springs, ItemName.move_blocks, ], ]), + + "10b_h-02_west---10b_h-02_east": RegionConnection("10b_h-02_west", "10b_h-02_east", [[ItemName.red_boosters, ], ]), + + "10b_h-03_west---10b_h-03_east": RegionConnection("10b_h-03_west", "10b_h-03_east", [[ItemName.coins, ItemName.double_dash_refills, ItemName.springs, ], ]), + + "10b_h-03b_west---10b_h-03b_east": RegionConnection("10b_h-03b_west", "10b_h-03b_east", [[ItemName.coins, ItemName.double_dash_refills, ItemName.core_blocks, ], ]), + + "10b_h-04_top---10b_h-04_east": RegionConnection("10b_h-04_top", "10b_h-04_east", []), + "10b_h-04_top---10b_h-04_bottom": RegionConnection("10b_h-04_top", "10b_h-04_bottom", [[ItemName.red_boosters, ], ]), + + "10b_h-04b_west---10b_h-04b_east": RegionConnection("10b_h-04b_west", "10b_h-04b_east", [[ItemName.double_dash_refills, ], ]), + + "10b_h-05_west---10b_h-05_top": RegionConnection("10b_h-05_west", "10b_h-05_top", []), + "10b_h-05_top---10b_h-05_east": RegionConnection("10b_h-05_top", "10b_h-05_east", [[ItemName.double_dash_refills, ItemName.coins, ], ]), + + "10b_h-06_west---10b_h-06_east": RegionConnection("10b_h-06_west", "10b_h-06_east", [[ItemName.dash_refills, ItemName.springs, ItemName.feathers, ], ]), + + "10b_h-06b_bottom---10b_h-06b_top": RegionConnection("10b_h-06b_bottom", "10b_h-06b_top", [[ItemName.fire_ice_balls, ItemName.coins, ], ]), + "10b_h-06b_top---10b_h-06b_bottom": RegionConnection("10b_h-06b_top", "10b_h-06b_bottom", []), + + "10b_h-07_west---10b_h-07_east": RegionConnection("10b_h-07_west", "10b_h-07_east", [[ItemName.blue_boosters, ItemName.springs, ItemName.coins, ], ]), + + "10b_h-08_west---10b_h-08_east": RegionConnection("10b_h-08_west", "10b_h-08_east", [[ItemName.dash_refills, ItemName.double_dash_refills, ItemName.coins, ], ]), + + "10b_h-09_west---10b_h-09_east": RegionConnection("10b_h-09_west", "10b_h-09_east", [[ItemName.dash_refills, ItemName.double_dash_refills, ItemName.coins, ItemName.feathers, ItemName.kevin_blocks, ], ]), + + "10b_h-10_west---10b_h-10_east": RegionConnection("10b_h-10_west", "10b_h-10_east", [[ItemName.feathers, ItemName.springs, ItemName.badeline_boosters, ], ]), + + "10b_i-00_west---10b_i-00_east": RegionConnection("10b_i-00_west", "10b_i-00_east", [[ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ItemName.yellow_cassette_blocks, ItemName.green_cassette_blocks, ], ]), + "10b_i-00_east---10b_i-00_west": RegionConnection("10b_i-00_east", "10b_i-00_west", [[ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ItemName.yellow_cassette_blocks, ItemName.green_cassette_blocks, ], ]), + + "10b_i-00b_west---10b_i-00b_east": RegionConnection("10b_i-00b_west", "10b_i-00b_east", [[ItemName.dash_refills, ItemName.double_dash_refills, ItemName.springs, ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ItemName.yellow_cassette_blocks, ItemName.green_cassette_blocks, ], ]), + + "10b_i-01_west---10b_i-01_east": RegionConnection("10b_i-01_west", "10b_i-01_east", [[ItemName.coins, ItemName.springs, ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ItemName.yellow_cassette_blocks, ], ]), + + "10b_i-02_west---10b_i-02_east": RegionConnection("10b_i-02_west", "10b_i-02_east", [[ItemName.double_dash_refills, ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ], ]), + + "10b_i-03_west---10b_i-03_east": RegionConnection("10b_i-03_west", "10b_i-03_east", [[ItemName.double_dash_refills, ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ItemName.yellow_cassette_blocks, ], ]), + + "10b_i-04_west---10b_i-04_east": RegionConnection("10b_i-04_west", "10b_i-04_east", [[ItemName.red_boosters, ItemName.coins, ], ]), + + "10b_i-05_west---10b_i-05_east": RegionConnection("10b_i-05_west", "10b_i-05_east", [[ItemName.double_dash_refills, ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ItemName.yellow_cassette_blocks, ], ]), + + "10b_j-00_west---10b_j-00_east": RegionConnection("10b_j-00_west", "10b_j-00_east", [[ItemName.dash_refills, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-00b_west---10b_j-00b_east": RegionConnection("10b_j-00b_west", "10b_j-00b_east", [[ItemName.double_dash_refills, ItemName.springs, ItemName.jellyfish, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-01_west---10b_j-01_east": RegionConnection("10b_j-01_west", "10b_j-01_east", [[ItemName.dash_refills, ItemName.springs, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-02_west---10b_j-02_east": RegionConnection("10b_j-02_west", "10b_j-02_east", [[ItemName.jellyfish, ItemName.springs, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-03_west---10b_j-03_east": RegionConnection("10b_j-03_west", "10b_j-03_east", [[ItemName.pufferfish, ItemName.springs, ItemName.double_dash_refills, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-04_west---10b_j-04_east": RegionConnection("10b_j-04_west", "10b_j-04_east", [[ItemName.jellyfish, ItemName.bird, ], ]), + + "10b_j-05_west---10b_j-05_east": RegionConnection("10b_j-05_west", "10b_j-05_east", [[ItemName.bird, ItemName.badeline_boosters, ItemName.feathers, ], ]), + + "10b_j-06_west---10b_j-06_east": RegionConnection("10b_j-06_west", "10b_j-06_east", [[ItemName.dash_refills, ItemName.double_dash_refills, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-07_west---10b_j-07_east": RegionConnection("10b_j-07_west", "10b_j-07_east", [[ItemName.pufferfish, ItemName.feathers, ItemName.springs, ItemName.bird, ], ]), + + "10b_j-08_west---10b_j-08_east": RegionConnection("10b_j-08_west", "10b_j-08_east", [[ItemName.dream_blocks, ItemName.double_dash_refills, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-09_west---10b_j-09_east": RegionConnection("10b_j-09_west", "10b_j-09_east", [[ItemName.jellyfish, ItemName.springs, ItemName.double_dash_refills, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-10_west---10b_j-10_east": RegionConnection("10b_j-10_west", "10b_j-10_east", [[ItemName.pufferfish, ItemName.swap_blocks, ItemName.dash_refills, ItemName.double_dash_refills, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-11_west---10b_j-11_east": RegionConnection("10b_j-11_west", "10b_j-11_east", [[ItemName.springs, ItemName.move_blocks, ItemName.double_dash_refills, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-12_west---10b_j-12_east": RegionConnection("10b_j-12_west", "10b_j-12_east", [[ItemName.springs, ItemName.dash_refills, ItemName.double_dash_refills, ItemName.bird, ], ]), + + "10b_j-13_west---10b_j-13_east": RegionConnection("10b_j-13_west", "10b_j-13_east", [[ItemName.springs, ItemName.feathers, ItemName.double_dash_refills, ], ]), + + "10b_j-14_west---10b_j-14_east": RegionConnection("10b_j-14_west", "10b_j-14_east", [[ItemName.traffic_blocks, ItemName.pufferfish, ItemName.double_dash_refills, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-14b_west---10b_j-14b_east": RegionConnection("10b_j-14b_west", "10b_j-14b_east", [[ItemName.springs, ItemName.jellyfish, ItemName.double_dash_refills, ], ]), + + "10b_j-15_west---10b_j-15_east": RegionConnection("10b_j-15_west", "10b_j-15_east", [[ItemName.kevin_blocks, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-16_west---10b_j-16_east": RegionConnection("10b_j-16_west", "10b_j-16_east", [[ItemName.jellyfish, ItemName.pufferfish, ItemName.springs, ItemName.dash_refills, ItemName.double_dash_refills, ItemName.coins, ItemName.feathers, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + "10b_j-16_west---10b_j-16_top": RegionConnection("10b_j-16_west", "10b_j-16_top", [[ItemName.jellyfish, ItemName.pufferfish, ItemName.springs, ItemName.dash_refills, ItemName.double_dash_refills, ItemName.coins, ItemName.feathers, ItemName.bird, ItemName.badeline_boosters, ItemName.breaker_boxes, ], ]), + + "10b_j-17_south---10b_j-17_west": RegionConnection("10b_j-17_south", "10b_j-17_west", []), + "10b_j-17_west---10b_j-17_south": RegionConnection("10b_j-17_west", "10b_j-17_south", []), + "10b_j-17_north---10b_j-17_south": RegionConnection("10b_j-17_north", "10b_j-17_south", []), + "10b_j-17_north---10b_j-17_east": RegionConnection("10b_j-17_north", "10b_j-17_east", []), + + "10b_j-18_west---10b_j-18_east": RegionConnection("10b_j-18_west", "10b_j-18_east", []), + + "10b_j-19_bottom---10b_j-19_top": RegionConnection("10b_j-19_bottom", "10b_j-19_top", [[ItemName.jellyfish, ItemName.springs, ItemName.dash_refills, ItemName.double_dash_refills, ItemName.coins, ], ]), + + "10b_GOAL_main---10b_GOAL_moon": RegionConnection("10b_GOAL_main", "10b_GOAL_moon", []), + "10b_GOAL_moon---10b_GOAL_main": RegionConnection("10b_GOAL_moon", "10b_GOAL_main", []), + + "10c_end-golden_bottom---10c_end-golden_top": RegionConnection("10c_end-golden_bottom", "10c_end-golden_top", [[ItemName.double_dash_refills, ItemName.jellyfish, ItemName.springs, ItemName.pufferfish, ItemName.badeline_boosters, ], ]), + +} + +all_locations: dict[str, LevelLocation] = { + "0a_-1_car": LevelLocation("0a_-1_car", "Prologue - Car", "0a_-1_main", LocationType.car, []), + "0a_3_clear": LevelLocation("0a_3_clear", "Prologue - Level Clear", "0a_3_east", LocationType.level_clear, []), + + "1a_2_strawberry": LevelLocation("1a_2_strawberry", "Forsaken City A - Room 2 Strawberry", "1a_2_west", LocationType.strawberry, [[ItemName.springs, ], ]), + "1a_3_strawberry": LevelLocation("1a_3_strawberry", "Forsaken City A - Room 3 Strawberry", "1a_3_east", LocationType.strawberry, []), + "1a_3b_strawberry": LevelLocation("1a_3b_strawberry", "Forsaken City A - Room 3b Strawberry", "1a_3b_top", LocationType.strawberry, []), + "1a_5_strawberry": LevelLocation("1a_5_strawberry", "Forsaken City A - Room 5 Strawberry", "1a_5_north-west", LocationType.strawberry, []), + "1a_5z_strawberry": LevelLocation("1a_5z_strawberry", "Forsaken City A - Room 5z Strawberry", "1a_5z_east", LocationType.strawberry, [[ItemName.springs, ], ]), + "1a_5a_strawberry": LevelLocation("1a_5a_strawberry", "Forsaken City A - Room 5a Strawberry", "1a_5a_west", LocationType.strawberry, [[ItemName.traffic_blocks, ], ]), + "1a_6_strawberry": LevelLocation("1a_6_strawberry", "Forsaken City A - Room 6 Strawberry", "1a_6_east", LocationType.strawberry, []), + "1a_7zb_strawberry": LevelLocation("1a_7zb_strawberry", "Forsaken City A - Room 7zb Strawberry", "1a_7zb_west", LocationType.strawberry, []), + "1a_s1_strawberry": LevelLocation("1a_s1_strawberry", "Forsaken City A - Room s1 Strawberry", "1a_s1_east", LocationType.strawberry, []), + "1a_s1_crystal_heart": LevelLocation("1a_s1_crystal_heart", "Forsaken City A - Crystal Heart", "1a_s1_east", LocationType.crystal_heart, []), + "1a_7z_strawberry": LevelLocation("1a_7z_strawberry", "Forsaken City A - Room 7z Strawberry", "1a_7z_bottom", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "1a_8zb_strawberry": LevelLocation("1a_8zb_strawberry", "Forsaken City A - Room 8zb Strawberry", "1a_8zb_west", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "1a_7a_strawberry": LevelLocation("1a_7a_strawberry", "Forsaken City A - Room 7a Strawberry", "1a_7a_east", LocationType.strawberry, [[ItemName.traffic_blocks, ], ]), + "1a_9z_strawberry": LevelLocation("1a_9z_strawberry", "Forsaken City A - Room 9z Strawberry", "1a_9z_east", LocationType.strawberry, [[ItemName.traffic_blocks, ], ]), + "1a_8b_strawberry": LevelLocation("1a_8b_strawberry", "Forsaken City A - Room 8b Strawberry", "1a_8b_east", LocationType.strawberry, [[ItemName.traffic_blocks, ], ]), + "1a_9_strawberry": LevelLocation("1a_9_strawberry", "Forsaken City A - Room 9 Strawberry", "1a_9_west", LocationType.strawberry, [[ItemName.traffic_blocks, ], ]), + "1a_9b_strawberry": LevelLocation("1a_9b_strawberry", "Forsaken City A - Room 9b Strawberry", "1a_9b_east", LocationType.strawberry, []), + "1a_9c_strawberry": LevelLocation("1a_9c_strawberry", "Forsaken City A - Room 9c Strawberry", "1a_9c_west", LocationType.strawberry, [[ItemName.traffic_blocks, ], ]), + "1a_10zb_strawberry": LevelLocation("1a_10zb_strawberry", "Forsaken City A - Room 10zb Strawberry", "1a_10zb_east", LocationType.strawberry, []), + "1a_11_strawberry": LevelLocation("1a_11_strawberry", "Forsaken City A - Room 11 Strawberry", "1a_11_south", LocationType.strawberry, []), + "1a_11z_cassette": LevelLocation("1a_11z_cassette", "Forsaken City A - Cassette", "1a_11z_east", LocationType.cassette, [[ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ], ]), + "1a_12z_strawberry": LevelLocation("1a_12z_strawberry", "Forsaken City A - Room 12z Strawberry", "1a_12z_east", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "1a_end_clear": LevelLocation("1a_end_clear", "Forsaken City A - Level Clear", "1a_end_main", LocationType.level_clear, []), + "1a_end_golden": LevelLocation("1a_end_golden", "Forsaken City A - Golden Strawberry", "1a_end_main", LocationType.golden_strawberry, [[ItemName.springs, ItemName.traffic_blocks, ItemName.dash_refills, ], ]), + "1a_end_winged_golden": LevelLocation("1a_end_winged_golden", "Forsaken City A - Winged Golden Strawberry", "1a_end_main", LocationType.golden_strawberry, [[ItemName.springs, ItemName.traffic_blocks, ], ]), + + "1b_03_binoculars": LevelLocation("1b_03_binoculars", "Forsaken City B - Room 03 Binoculars", "1b_03_west", LocationType.binoculars, []), + "1b_09_binoculars": LevelLocation("1b_09_binoculars", "Forsaken City B - Room 09 Binoculars", "1b_09_west", LocationType.binoculars, []), + "1b_end_clear": LevelLocation("1b_end_clear", "Forsaken City B - Level Clear", "1b_end_goal", LocationType.level_clear, []), + "1b_end_golden": LevelLocation("1b_end_golden", "Forsaken City B - Golden Strawberry", "1b_end_goal", LocationType.golden_strawberry, [[ItemName.springs, ItemName.traffic_blocks, ItemName.dash_refills, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ], ]), + + "1c_01_binoculars": LevelLocation("1c_01_binoculars", "Forsaken City C - Room 01 Binoculars", "1c_01_west", LocationType.binoculars, []), + "1c_02_binoculars": LevelLocation("1c_02_binoculars", "Forsaken City C - Room 02 Binoculars", "1c_02_west", LocationType.binoculars, []), + "1c_02_clear": LevelLocation("1c_02_clear", "Forsaken City C - Level Clear", "1c_02_goal", LocationType.level_clear, []), + "1c_02_golden": LevelLocation("1c_02_golden", "Forsaken City C - Golden Strawberry", "1c_02_goal", LocationType.golden_strawberry, [[ItemName.traffic_blocks, ItemName.dash_refills, ItemName.coins, ], ]), + + "2a_s2_crystal_heart": LevelLocation("2a_s2_crystal_heart", "Old Site A - Crystal Heart", "2a_s2_bottom", LocationType.crystal_heart, []), + "2a_1_strawberry": LevelLocation("2a_1_strawberry", "Old Site A - Room 1 Strawberry", "2a_1_north-west", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_d0_strawberry": LevelLocation("2a_d0_strawberry", "Old Site A - Room d0 Strawberry", "2a_d0_north", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_d3_binoculars": LevelLocation("2a_d3_binoculars", "Old Site A - Room d3 Binoculars", "2a_d3_north", LocationType.binoculars, []), + "2a_d3_strawberry": LevelLocation("2a_d3_strawberry", "Old Site A - Room d3 Strawberry", "2a_d3_south", LocationType.strawberry, []), + "2a_d2_strawberry_1": LevelLocation("2a_d2_strawberry_1", "Old Site A - Room d2 Strawberry 1", "2a_d2_north-west", LocationType.strawberry, []), + "2a_d2_strawberry_2": LevelLocation("2a_d2_strawberry_2", "Old Site A - Room d2 Strawberry 2", "2a_d2_east", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_d9_cassette": LevelLocation("2a_d9_cassette", "Old Site A - Cassette", "2a_d9_north-west", LocationType.cassette, [[ItemName.dream_blocks, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ], ]), + "2a_d1_strawberry": LevelLocation("2a_d1_strawberry", "Old Site A - Room d1 Strawberry", "2a_d1_south-west", LocationType.strawberry, [[ItemName.dream_blocks, ItemName.strawberry_seeds, ], ]), + "2a_d6_strawberry": LevelLocation("2a_d6_strawberry", "Old Site A - Room d6 Strawberry", "2a_d6_west", LocationType.strawberry, []), + "2a_d4_strawberry": LevelLocation("2a_d4_strawberry", "Old Site A - Room d4 Strawberry", "2a_d4_west", LocationType.strawberry, [[ItemName.traffic_blocks, ItemName.dream_blocks, ], ]), + "2a_d5_strawberry": LevelLocation("2a_d5_strawberry", "Old Site A - Room d5 Strawberry", "2a_d5_west", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_4_strawberry": LevelLocation("2a_4_strawberry", "Old Site A - Room 4 Strawberry", "2a_4_bottom", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_5_strawberry": LevelLocation("2a_5_strawberry", "Old Site A - Room 5 Strawberry", "2a_5_bottom", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_8_strawberry": LevelLocation("2a_8_strawberry", "Old Site A - Room 8 Strawberry", "2a_8_bottom", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_9_strawberry": LevelLocation("2a_9_strawberry", "Old Site A - Room 9 Strawberry", "2a_9_south", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_9b_strawberry": LevelLocation("2a_9b_strawberry", "Old Site A - Room 9b Strawberry", "2a_9b_east", LocationType.strawberry, []), + "2a_10_strawberry": LevelLocation("2a_10_strawberry", "Old Site A - Room 10 Strawberry", "2a_10_top", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_12c_strawberry": LevelLocation("2a_12c_strawberry", "Old Site A - Room 12c Strawberry", "2a_12c_south", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_12d_strawberry": LevelLocation("2a_12d_strawberry", "Old Site A - Room 12d Strawberry", "2a_12d_north-west", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "2a_end_3c_strawberry": LevelLocation("2a_end_3c_strawberry", "Old Site A - Room end_3c Strawberry", "2a_end_3c_bottom", LocationType.strawberry, [[ItemName.springs, ], ]), + "2a_end_6_clear": LevelLocation("2a_end_6_clear", "Old Site A - Level Clear", "2a_end_6_main", LocationType.level_clear, []), + "2a_end_6_golden": LevelLocation("2a_end_6_golden", "Old Site A - Golden Strawberry", "2a_end_6_main", LocationType.golden_strawberry, [[ItemName.dream_blocks, ItemName.coins, ItemName.dash_refills, ], ]), + + "2b_10_binoculars": LevelLocation("2b_10_binoculars", "Old Site B - Room 10 Binoculars", "2b_10_west", LocationType.binoculars, []), + "2b_11_binoculars": LevelLocation("2b_11_binoculars", "Old Site B - Room 11 Binoculars", "2b_11_bottom", LocationType.binoculars, []), + "2b_end_clear": LevelLocation("2b_end_clear", "Old Site B - Level Clear", "2b_end_goal", LocationType.level_clear, []), + "2b_end_golden": LevelLocation("2b_end_golden", "Old Site B - Golden Strawberry", "2b_end_goal", LocationType.golden_strawberry, [[ItemName.springs, ItemName.dream_blocks, ItemName.dash_refills, ItemName.coins, ItemName.blue_cassette_blocks, ], ]), + + "2c_02_binoculars": LevelLocation("2c_02_binoculars", "Old Site C - Room 02 Binoculars", "2c_02_west", LocationType.binoculars, []), + "2c_02_clear": LevelLocation("2c_02_clear", "Old Site C - Level Clear", "2c_02_goal", LocationType.level_clear, []), + "2c_02_golden": LevelLocation("2c_02_golden", "Old Site C - Golden Strawberry", "2c_02_goal", LocationType.golden_strawberry, [[ItemName.dream_blocks, ItemName.dash_refills, ItemName.coins, ], ]), + + "3a_s2_strawberry_1": LevelLocation("3a_s2_strawberry_1", "Celestial Resort A - Room s2 Strawberry 1", "3a_s2_west", LocationType.strawberry, []), + "3a_s2_strawberry_2": LevelLocation("3a_s2_strawberry_2", "Celestial Resort A - Room s2 Strawberry 2", "3a_s2_north-west", LocationType.strawberry, []), + "3a_s3_key_1": LevelLocation("3a_s3_key_1", "Celestial Resort A - Front Door Key", "3a_s3_west", LocationType.key, []), + "3a_s3_strawberry": LevelLocation("3a_s3_strawberry", "Celestial Resort A - Room s3 Strawberry", "3a_s3_north", LocationType.strawberry, []), + "3a_00-a_strawberry": LevelLocation("3a_00-a_strawberry", "Celestial Resort A - Room 00-a Strawberry", "3a_00-a_east", LocationType.strawberry, []), + "3a_02-b_hallway_key_1": LevelLocation("3a_02-b_hallway_key_1", "Celestial Resort A - Hallway Key 1", "3a_02-b_east", LocationType.key, []), + "3a_00-b_strawberry": LevelLocation("3a_00-b_strawberry", "Celestial Resort A - Room 00-b Strawberry", "3a_00-b_east", LocationType.strawberry, []), + "3a_04-b_strawberry": LevelLocation("3a_04-b_strawberry", "Celestial Resort A - Room 04-b Strawberry", "3a_04-b_east", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "3a_06-a_strawberry": LevelLocation("3a_06-a_strawberry", "Celestial Resort A - Room 06-a Strawberry", "3a_06-a_west", LocationType.strawberry, []), + "3a_07-b_strawberry": LevelLocation("3a_07-b_strawberry", "Celestial Resort A - Room 07-b Strawberry", "3a_07-b_top", LocationType.strawberry, []), + "3a_07-b_key_2": LevelLocation("3a_07-b_key_2", "Celestial Resort A - Hallway Key 2", "3a_07-b_east", LocationType.key, []), + "3a_06-b_strawberry": LevelLocation("3a_06-b_strawberry", "Celestial Resort A - Room 06-b Strawberry", "3a_06-b_east", LocationType.strawberry, []), + "3a_06-c_strawberry": LevelLocation("3a_06-c_strawberry", "Celestial Resort A - Room 06-c Strawberry", "3a_06-c_south-west", LocationType.strawberry, []), + "3a_05-c_strawberry": LevelLocation("3a_05-c_strawberry", "Celestial Resort A - Room 05-c Strawberry", "3a_05-c_east", LocationType.strawberry, []), + "3a_09-b_key_4": LevelLocation("3a_09-b_key_4", "Celestial Resort A - Huge Mess Key", "3a_09-b_center", LocationType.key, [[ItemName.brown_clutter, ItemName.green_clutter, ItemName.pink_clutter, ], ]), + "3a_10-x_brown_clutter": LevelLocation("3a_10-x_brown_clutter", "Celestial Resort A - Brown Clutter", "3a_10-x_south-east", LocationType.clutter, []), + "3a_12-y_strawberry": LevelLocation("3a_12-y_strawberry", "Celestial Resort A - Room 12-y Strawberry", "3a_12-y_west", LocationType.strawberry, []), + "3a_10-y_strawberry": LevelLocation("3a_10-y_strawberry", "Celestial Resort A - Room 10-y Strawberry", "3a_10-y_bottom", LocationType.strawberry, []), + "3a_11-c_crystal_heart": LevelLocation("3a_11-c_crystal_heart", "Celestial Resort A - Crystal Heart", "3a_11-c_south-east", LocationType.crystal_heart, []), + "3a_12-c_strawberry": LevelLocation("3a_12-c_strawberry", "Celestial Resort A - Room 12-c Strawberry", "3a_12-c_west", LocationType.strawberry, []), + "3a_11-d_strawberry": LevelLocation("3a_11-d_strawberry", "Celestial Resort A - Room 11-d Strawberry", "3a_11-d_east", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "3a_10-d_green_clutter": LevelLocation("3a_10-d_green_clutter", "Celestial Resort A - Green Clutter", "3a_10-d_main", LocationType.clutter, []), + "3a_13-b_strawberry": LevelLocation("3a_13-b_strawberry", "Celestial Resort A - Room 13-b Strawberry", "3a_13-b_top", LocationType.strawberry, []), + "3a_13-x_strawberry": LevelLocation("3a_13-x_strawberry", "Celestial Resort A - Room 13-x Strawberry", "3a_13-x_west", LocationType.strawberry, []), + "3a_12-x_pink_clutter": LevelLocation("3a_12-x_pink_clutter", "Celestial Resort A - Pink Clutter", "3a_12-x_east", LocationType.clutter, []), + "3a_08-x_strawberry": LevelLocation("3a_08-x_strawberry", "Celestial Resort A - Room 08-x Strawberry", "3a_08-x_west", LocationType.strawberry, []), + "3a_06-d_strawberry": LevelLocation("3a_06-d_strawberry", "Celestial Resort A - Room 06-d Strawberry", "3a_06-d_east", LocationType.strawberry, []), + "3a_04-c_strawberry": LevelLocation("3a_04-c_strawberry", "Celestial Resort A - Room 04-c Strawberry", "3a_04-c_east", LocationType.strawberry, []), + "3a_02-c_key_5": LevelLocation("3a_02-c_key_5", "Celestial Resort A - Presidential Suite Key", "3a_02-c_west", LocationType.key, []), + "3a_03-b_strawberry_1": LevelLocation("3a_03-b_strawberry_1", "Celestial Resort A - Room 03-b Strawberry 1", "3a_03-b_west", LocationType.strawberry, []), + "3a_03-b_strawberry_2": LevelLocation("3a_03-b_strawberry_2", "Celestial Resort A - Room 03-b Strawberry 2", "3a_03-b_west", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "3a_01-c_cassette": LevelLocation("3a_01-c_cassette", "Celestial Resort A - Cassette", "3a_01-c_east", LocationType.cassette, [[ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ], ]), + "3a_roof03_strawberry": LevelLocation("3a_roof03_strawberry", "Celestial Resort A - Room roof03 Strawberry", "3a_roof03_west", LocationType.strawberry, []), + "3a_roof06_strawberry_1": LevelLocation("3a_roof06_strawberry_1", "Celestial Resort A - Room roof06 Strawberry 1", "3a_roof06_west", LocationType.strawberry, []), + "3a_roof06_strawberry_2": LevelLocation("3a_roof06_strawberry_2", "Celestial Resort A - Room roof06 Strawberry 2", "3a_roof06_west", LocationType.strawberry, []), + "3a_roof07_clear": LevelLocation("3a_roof07_clear", "Celestial Resort A - Level Clear", "3a_roof07_main", LocationType.level_clear, []), + "3a_roof07_golden": LevelLocation("3a_roof07_golden", "Celestial Resort A - Golden Strawberry", "3a_roof07_main", LocationType.golden_strawberry, [["Celestial Resort A - Front Door Key", "Celestial Resort A - Hallway Key 1", "Celestial Resort A - Hallway Key 2", "Celestial Resort A - Huge Mess Key", "Celestial Resort A - Presidential Suite Key", ItemName.sinking_platforms, ItemName.dash_refills, ItemName.brown_clutter, ItemName.green_clutter, ItemName.pink_clutter, ItemName.coins, ItemName.moving_platforms, ItemName.springs, ], ]), + + "3b_back_binoculars": LevelLocation("3b_back_binoculars", "Celestial Resort B - Room back Binoculars", "3b_back_east", LocationType.binoculars, []), + "3b_12_binoculars": LevelLocation("3b_12_binoculars", "Celestial Resort B - Room 12 Binoculars", "3b_12_west", LocationType.binoculars, []), + "3b_end_clear": LevelLocation("3b_end_clear", "Celestial Resort B - Level Clear", "3b_end_goal", LocationType.level_clear, []), + "3b_end_golden": LevelLocation("3b_end_golden", "Celestial Resort B - Golden Strawberry", "3b_end_goal", LocationType.golden_strawberry, [[ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.dash_refills, ItemName.springs, ItemName.coins, ItemName.moving_platforms, ItemName.sinking_platforms, ], ]), + + "3c_02_binoculars": LevelLocation("3c_02_binoculars", "Celestial Resort C - Room 02 Binoculars", "3c_02_west", LocationType.binoculars, []), + "3c_02_clear": LevelLocation("3c_02_clear", "Celestial Resort C - Level Clear", "3c_02_goal", LocationType.level_clear, []), + "3c_02_golden": LevelLocation("3c_02_golden", "Celestial Resort C - Golden Strawberry", "3c_02_goal", LocationType.golden_strawberry, [[ItemName.sinking_platforms, ItemName.dash_refills, ItemName.coins, ], ]), + + "4a_a-01x_strawberry": LevelLocation("4a_a-01x_strawberry", "Golden Ridge A - Room a-01x Strawberry", "4a_a-01x_west", LocationType.strawberry, []), + "4a_a-02_strawberry": LevelLocation("4a_a-02_strawberry", "Golden Ridge A - Room a-02 Strawberry", "4a_a-02_west", LocationType.strawberry, []), + "4a_a-03_strawberry": LevelLocation("4a_a-03_strawberry", "Golden Ridge A - Room a-03 Strawberry", "4a_a-03_west", LocationType.strawberry, [[ItemName.blue_boosters, ], ]), + "4a_a-04_strawberry": LevelLocation("4a_a-04_strawberry", "Golden Ridge A - Room a-04 Strawberry", "4a_a-04_east", LocationType.strawberry, [[ItemName.blue_clouds, ], ]), + "4a_a-06_strawberry": LevelLocation("4a_a-06_strawberry", "Golden Ridge A - Room a-06 Strawberry", "4a_a-06_west", LocationType.strawberry, []), + "4a_a-07_strawberry": LevelLocation("4a_a-07_strawberry", "Golden Ridge A - Room a-07 Strawberry", "4a_a-07_east", LocationType.strawberry, []), + "4a_a-10_strawberry": LevelLocation("4a_a-10_strawberry", "Golden Ridge A - Room a-10 Strawberry", "4a_a-10_east", LocationType.strawberry, [[ItemName.strawberry_seeds, ItemName.springs, ], ]), + "4a_a-11_binoculars": LevelLocation("4a_a-11_binoculars", "Golden Ridge A - Room a-11 Binoculars", "4a_a-11_east", LocationType.binoculars, []), + "4a_a-11_cassette": LevelLocation("4a_a-11_cassette", "Golden Ridge A - Cassette", "4a_a-11_east", LocationType.cassette, [[ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ], ]), + "4a_a-09_strawberry": LevelLocation("4a_a-09_strawberry", "Golden Ridge A - Room a-09 Strawberry", "4a_a-09_top", LocationType.strawberry, []), + "4a_b-01_strawberry_1": LevelLocation("4a_b-01_strawberry_1", "Golden Ridge A - Room b-01 Strawberry 1", "4a_b-01_west", LocationType.strawberry, [[ItemName.move_blocks, ], ]), + "4a_b-01_strawberry_2": LevelLocation("4a_b-01_strawberry_2", "Golden Ridge A - Room b-01 Strawberry 2", "4a_b-01_west", LocationType.strawberry, [[ItemName.move_blocks, ], ]), + "4a_b-04_strawberry": LevelLocation("4a_b-04_strawberry", "Golden Ridge A - Room b-04 Strawberry", "4a_b-04_north-west", LocationType.strawberry, []), + "4a_b-07_strawberry": LevelLocation("4a_b-07_strawberry", "Golden Ridge A - Room b-07 Strawberry", "4a_b-07_west", LocationType.strawberry, [[ItemName.move_blocks, ItemName.blue_boosters, ], ]), + "4a_b-03_strawberry": LevelLocation("4a_b-03_strawberry", "Golden Ridge A - Room b-03 Strawberry", "4a_b-03_west", LocationType.strawberry, [[ItemName.move_blocks, ], ]), + "4a_b-02_strawberry_1": LevelLocation("4a_b-02_strawberry_1", "Golden Ridge A - Room b-02 Strawberry 1", "4a_b-02_south-west", LocationType.strawberry, [[ItemName.move_blocks, ], ]), + "4a_b-02_binoculars": LevelLocation("4a_b-02_binoculars", "Golden Ridge A - Room b-02 Binoculars", "4a_b-02_south-west", LocationType.binoculars, []), + "4a_b-02_strawberry_2": LevelLocation("4a_b-02_strawberry_2", "Golden Ridge A - Room b-02 Strawberry 2", "4a_b-02_north-east", LocationType.strawberry, []), + "4a_b-sec_crystal_heart": LevelLocation("4a_b-sec_crystal_heart", "Golden Ridge A - Crystal Heart", "4a_b-sec_west", LocationType.crystal_heart, [[ItemName.white_block, ], ]), + "4a_b-secb_strawberry": LevelLocation("4a_b-secb_strawberry", "Golden Ridge A - Room b-secb Strawberry", "4a_b-secb_west", LocationType.strawberry, [[ItemName.move_blocks, ], ]), + "4a_b-08_strawberry": LevelLocation("4a_b-08_strawberry", "Golden Ridge A - Room b-08 Strawberry", "4a_b-08_west", LocationType.strawberry, [[ItemName.move_blocks, ItemName.blue_clouds, ], ]), + "4a_c-00_strawberry": LevelLocation("4a_c-00_strawberry", "Golden Ridge A - Room c-00 Strawberry", "4a_c-00_west", LocationType.strawberry, []), + "4a_c-01_strawberry": LevelLocation("4a_c-01_strawberry", "Golden Ridge A - Room c-01 Strawberry", "4a_c-01_east", LocationType.strawberry, []), + "4a_c-05_strawberry": LevelLocation("4a_c-05_strawberry", "Golden Ridge A - Room c-05 Strawberry", "4a_c-05_east", LocationType.strawberry, [[ItemName.blue_boosters, ItemName.move_blocks, ], ]), + "4a_c-06_strawberry": LevelLocation("4a_c-06_strawberry", "Golden Ridge A - Room c-06 Strawberry", "4a_c-06_west", LocationType.strawberry, [[ItemName.coins, ItemName.move_blocks, ], ]), + "4a_c-06b_strawberry": LevelLocation("4a_c-06b_strawberry", "Golden Ridge A - Room c-06b Strawberry", "4a_c-06b_east", LocationType.strawberry, [[ItemName.dash_refills, ItemName.blue_boosters, ], ]), + "4a_c-08_strawberry": LevelLocation("4a_c-08_strawberry", "Golden Ridge A - Room c-08 Strawberry", "4a_c-08_east", LocationType.strawberry, [[ItemName.blue_boosters, ], ]), + "4a_c-10_strawberry": LevelLocation("4a_c-10_strawberry", "Golden Ridge A - Room c-10 Strawberry", "4a_c-10_top", LocationType.strawberry, []), + "4a_d-00b_strawberry": LevelLocation("4a_d-00b_strawberry", "Golden Ridge A - Room d-00b Strawberry", "4a_d-00b_east", LocationType.strawberry, [[ItemName.move_blocks, ItemName.blue_boosters, ], ]), + "4a_d-00b_binoculars": LevelLocation("4a_d-00b_binoculars", "Golden Ridge A - Room d-00b Binoculars", "4a_d-00b_east", LocationType.binoculars, []), + "4a_d-01_strawberry": LevelLocation("4a_d-01_strawberry", "Golden Ridge A - Room d-01 Strawberry", "4a_d-01_east", LocationType.strawberry, []), + "4a_d-04_strawberry": LevelLocation("4a_d-04_strawberry", "Golden Ridge A - Room d-04 Strawberry", "4a_d-04_east", LocationType.strawberry, []), + "4a_d-07_strawberry": LevelLocation("4a_d-07_strawberry", "Golden Ridge A - Room d-07 Strawberry", "4a_d-07_west", LocationType.strawberry, [[ItemName.blue_boosters, ], ]), + "4a_d-09_strawberry": LevelLocation("4a_d-09_strawberry", "Golden Ridge A - Room d-09 Strawberry", "4a_d-09_west", LocationType.strawberry, [[ItemName.blue_boosters, ], ]), + "4a_d-10_clear": LevelLocation("4a_d-10_clear", "Golden Ridge A - Level Clear", "4a_d-10_goal", LocationType.level_clear, []), + "4a_d-10_golden": LevelLocation("4a_d-10_golden", "Golden Ridge A - Golden Strawberry", "4a_d-10_goal", LocationType.golden_strawberry, [[ItemName.blue_clouds, ItemName.pink_clouds, ItemName.blue_boosters, ItemName.move_blocks, ItemName.dash_refills, ItemName.springs, ItemName.coins, ], ]), + + "4b_b-02_binoculars": LevelLocation("4b_b-02_binoculars", "Golden Ridge B - Room b-02 Binoculars", "4b_b-02_bottom", LocationType.binoculars, []), + "4b_c-03_binoculars": LevelLocation("4b_c-03_binoculars", "Golden Ridge B - Room c-03 Binoculars", "4b_c-03_bottom", LocationType.binoculars, []), + "4b_d-01_binoculars": LevelLocation("4b_d-01_binoculars", "Golden Ridge B - Room d-01 Binoculars", "4b_d-01_west", LocationType.binoculars, []), + "4b_end_binoculars": LevelLocation("4b_end_binoculars", "Golden Ridge B - Room end Binoculars", "4b_end_west", LocationType.binoculars, []), + "4b_end_clear": LevelLocation("4b_end_clear", "Golden Ridge B - Level Clear", "4b_end_goal", LocationType.level_clear, []), + "4b_end_golden": LevelLocation("4b_end_golden", "Golden Ridge B - Golden Strawberry", "4b_end_goal", LocationType.golden_strawberry, [[ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.dash_refills, ItemName.springs, ItemName.coins, ItemName.moving_platforms, ItemName.blue_boosters, ItemName.blue_clouds, ItemName.pink_clouds, ItemName.move_blocks, ], ]), + + "4c_01_binoculars": LevelLocation("4c_01_binoculars", "Golden Ridge C - Room 01 Binoculars", "4c_01_west", LocationType.binoculars, []), + "4c_02_binoculars": LevelLocation("4c_02_binoculars", "Golden Ridge C - Room 02 Binoculars", "4c_02_west", LocationType.binoculars, []), + "4c_02_clear": LevelLocation("4c_02_clear", "Golden Ridge C - Level Clear", "4c_02_goal", LocationType.level_clear, []), + "4c_02_golden": LevelLocation("4c_02_golden", "Golden Ridge C - Golden Strawberry", "4c_02_goal", LocationType.golden_strawberry, [[ItemName.pink_clouds, ItemName.blue_boosters, ItemName.move_blocks, ItemName.dash_refills, ], ]), + + "5a_a-00x_strawberry": LevelLocation("5a_a-00x_strawberry", "Mirror Temple A - Room a-00x Strawberry", "5a_a-00x_east", LocationType.strawberry, []), + "5a_a-01_strawberry_1": LevelLocation("5a_a-01_strawberry_1", "Mirror Temple A - Room a-01 Strawberry 1", "5a_a-01_center", LocationType.strawberry, [[ItemName.red_boosters, ], ]), + "5a_a-01_strawberry_2": LevelLocation("5a_a-01_strawberry_2", "Mirror Temple A - Room a-01 Strawberry 2", "5a_a-01_center", LocationType.strawberry, []), + "5a_a-02_strawberry": LevelLocation("5a_a-02_strawberry", "Mirror Temple A - Room a-02 Strawberry", "5a_a-02_west", LocationType.strawberry, [[ItemName.swap_blocks, ], ]), + "5a_a-03_strawberry": LevelLocation("5a_a-03_strawberry", "Mirror Temple A - Room a-03 Strawberry", "5a_a-03_west", LocationType.strawberry, [[ItemName.red_boosters, ], ]), + "5a_a-04_strawberry": LevelLocation("5a_a-04_strawberry", "Mirror Temple A - Room a-04 Strawberry", "5a_a-04_east", LocationType.strawberry, [[ItemName.swap_blocks, ItemName.springs, ], ]), + "5a_a-05_strawberry": LevelLocation("5a_a-05_strawberry", "Mirror Temple A - Room a-05 Strawberry", "5a_a-05_center", LocationType.strawberry, [[ItemName.swap_blocks, ], ]), + "5a_a-06_strawberry": LevelLocation("5a_a-06_strawberry", "Mirror Temple A - Room a-06 Strawberry", "5a_a-06_west", LocationType.strawberry, [[ItemName.red_boosters, ItemName.swap_blocks, ], ]), + "5a_a-07_strawberry": LevelLocation("5a_a-07_strawberry", "Mirror Temple A - Room a-07 Strawberry", "5a_a-07_east", LocationType.strawberry, [[ItemName.dash_refills, ItemName.swap_blocks, ], ]), + "5a_a-08_key_1": LevelLocation("5a_a-08_key_1", "Mirror Temple A - Entrance Key", "5a_a-08_east", LocationType.key, []), + "5a_a-11_strawberry": LevelLocation("5a_a-11_strawberry", "Mirror Temple A - Room a-11 Strawberry", "5a_a-11_east", LocationType.strawberry, [[ItemName.dash_refills, ItemName.swap_blocks, ], ]), + "5a_a-15_strawberry": LevelLocation("5a_a-15_strawberry", "Mirror Temple A - Room a-15 Strawberry", "5a_a-15_south", LocationType.strawberry, [[ItemName.coins, ItemName.red_boosters, ], ]), + "5a_a-14_strawberry": LevelLocation("5a_a-14_strawberry", "Mirror Temple A - Room a-14 Strawberry", "5a_a-14_south", LocationType.strawberry, [[ItemName.swap_blocks, ItemName.dash_refills, ], ]), + "5a_b-18_strawberry": LevelLocation("5a_b-18_strawberry", "Mirror Temple A - Room b-18 Strawberry", "5a_b-18_south", LocationType.strawberry, [[ItemName.red_boosters, ], ]), + "5a_b-01c_strawberry": LevelLocation("5a_b-01c_strawberry", "Mirror Temple A - Room b-01c Strawberry", "5a_b-01c_east", LocationType.strawberry, [[ItemName.red_boosters, ], ]), + "5a_b-20_strawberry_1": LevelLocation("5a_b-20_strawberry_1", "Mirror Temple A - Room b-20 Strawberry 1", "5a_b-20_south", LocationType.strawberry, []), + "5a_b-20_strawberry_2": LevelLocation("5a_b-20_strawberry_2", "Mirror Temple A - Room b-20 Strawberry 2", "5a_b-20_east", LocationType.strawberry, [[ItemName.swap_blocks, ], ]), + "5a_b-21_strawberry": LevelLocation("5a_b-21_strawberry", "Mirror Temple A - Room b-21 Strawberry", "5a_b-21_east", LocationType.strawberry, [[ItemName.red_boosters, ItemName.dash_refills, ], ]), + "5a_b-03_strawberry": LevelLocation("5a_b-03_strawberry", "Mirror Temple A - Room b-03 Strawberry", "5a_b-03_east", LocationType.strawberry, [[ItemName.red_boosters, ], ]), + "5a_b-05_strawberry": LevelLocation("5a_b-05_strawberry", "Mirror Temple A - Room b-05 Strawberry", "5a_b-05_west", LocationType.strawberry, [[ItemName.red_boosters, ItemName.dash_refills, ], ]), + "5a_b-04_key_2": LevelLocation("5a_b-04_key_2", "Mirror Temple A - Depths Key", "5a_b-04_east", LocationType.key, []), + "5a_b-10_strawberry": LevelLocation("5a_b-10_strawberry", "Mirror Temple A - Room b-10 Strawberry", "5a_b-10_east", LocationType.strawberry, [[ItemName.red_boosters, ], ]), + "5a_b-12_strawberry": LevelLocation("5a_b-12_strawberry", "Mirror Temple A - Room b-12 Strawberry", "5a_b-12_east", LocationType.strawberry, [[ItemName.red_boosters, ], ]), + "5a_b-17_strawberry_2": LevelLocation("5a_b-17_strawberry_2", "Mirror Temple A - Room b-17 Strawberry 2", "5a_b-17_west", LocationType.strawberry, [[ItemName.strawberry_seeds, ItemName.springs, ], ]), + "5a_b-17_strawberry_1": LevelLocation("5a_b-17_strawberry_1", "Mirror Temple A - Room b-17 Strawberry 1", "5a_b-17_north-west", LocationType.strawberry, []), + "5a_b-22_binoculars": LevelLocation("5a_b-22_binoculars", "Mirror Temple A - Room b-22 Binoculars", "5a_b-22_west", LocationType.binoculars, []), + "5a_b-22_cassette": LevelLocation("5a_b-22_cassette", "Mirror Temple A - Cassette", "5a_b-22_west", LocationType.cassette, [[ItemName.red_boosters, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ], ]), + "5a_b-15_crystal_heart": LevelLocation("5a_b-15_crystal_heart", "Mirror Temple A - Crystal Heart", "5a_b-15_west", LocationType.crystal_heart, [[ItemName.swap_blocks, ], ]), + "5a_c-08_strawberry": LevelLocation("5a_c-08_strawberry", "Mirror Temple A - Room c-08 Strawberry", "5a_c-08_east", LocationType.strawberry, [[ItemName.seekers, ], ]), + "5a_d-04_key_3": LevelLocation("5a_d-04_key_3", "Mirror Temple A - Search Key 1", "5a_d-04_south-west-left", LocationType.key, []), + "5a_d-04_key_4": LevelLocation("5a_d-04_key_4", "Mirror Temple A - Search Key 2", "5a_d-04_south-west-right", LocationType.key, []), + "5a_d-04_strawberry_2": LevelLocation("5a_d-04_strawberry_2", "Mirror Temple A - Room d-04 Strawberry 2", "5a_d-04_south-east", LocationType.strawberry, [[ItemName.red_boosters, ItemName.swap_blocks, ], ]), + "5a_d-04_strawberry_1": LevelLocation("5a_d-04_strawberry_1", "Mirror Temple A - Room d-04 Strawberry 1", "5a_d-04_north", LocationType.strawberry, []), + "5a_d-15_strawberry_2": LevelLocation("5a_d-15_strawberry_2", "Mirror Temple A - Room d-15 Strawberry 2", "5a_d-15_center", LocationType.strawberry, [[ItemName.swap_blocks, ItemName.dash_refills, ], ]), + "5a_d-15_key_5": LevelLocation("5a_d-15_key_5", "Mirror Temple A - Search Key 3", "5a_d-15_center", LocationType.key, [[ItemName.swap_blocks, ItemName.seekers, ], ]), + "5a_d-15_strawberry_1": LevelLocation("5a_d-15_strawberry_1", "Mirror Temple A - Room d-15 Strawberry 1", "5a_d-15_west", LocationType.strawberry, [[ItemName.red_boosters, ], ]), + "5a_d-13_strawberry": LevelLocation("5a_d-13_strawberry", "Mirror Temple A - Room d-13 Strawberry", "5a_d-13_west", LocationType.strawberry, []), + "5a_d-19_strawberry": LevelLocation("5a_d-19_strawberry", "Mirror Temple A - Room d-19 Strawberry", "5a_d-19_east", LocationType.strawberry, [["Mirror Temple A - Search Key 3", ], ]), + "5a_e-06_strawberry": LevelLocation("5a_e-06_strawberry", "Mirror Temple A - Room e-06 Strawberry", "5a_e-06_east", LocationType.strawberry, [[ItemName.dash_switches, ], ]), + "5a_e-11_clear": LevelLocation("5a_e-11_clear", "Mirror Temple A - Level Clear", "5a_e-11_goal", LocationType.level_clear, []), + "5a_e-11_golden": LevelLocation("5a_e-11_golden", "Mirror Temple A - Golden Strawberry", "5a_e-11_goal", LocationType.golden_strawberry, [[ItemName.red_boosters, ItemName.swap_blocks, ItemName.dash_switches, "Mirror Temple A - Entrance Key", "Mirror Temple A - Depths Key", "Mirror Temple A - Search Key 1", "Mirror Temple A - Search Key 2", ItemName.seekers, ItemName.coins, ItemName.theo_crystal, ], ]), + + "5b_b-02_key_1": LevelLocation("5b_b-02_key_1", "Mirror Temple B - Central Chamber Key 1", "5b_b-02_south-west", LocationType.key, []), + "5b_b-02_key_2": LevelLocation("5b_b-02_key_2", "Mirror Temple B - Central Chamber Key 2", "5b_b-02_south-east", LocationType.key, []), + "5b_b-09_binoculars": LevelLocation("5b_b-09_binoculars", "Mirror Temple B - Room b-09 Binoculars", "5b_b-09_bottom", LocationType.binoculars, []), + "5b_d-05_clear": LevelLocation("5b_d-05_clear", "Mirror Temple B - Level Clear", "5b_d-05_goal", LocationType.level_clear, []), + "5b_d-05_golden": LevelLocation("5b_d-05_golden", "Mirror Temple B - Golden Strawberry", "5b_d-05_goal", LocationType.golden_strawberry, [["Mirror Temple B - Central Chamber Key 1", "Mirror Temple B - Central Chamber Key 2", ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.theo_crystal, ItemName.dash_refills, ItemName.springs, ItemName.coins, ItemName.swap_blocks, ], ]), + + "5c_02_binoculars": LevelLocation("5c_02_binoculars", "Mirror Temple C - Room 02 Binoculars", "5c_02_west", LocationType.binoculars, []), + "5c_02_clear": LevelLocation("5c_02_clear", "Mirror Temple C - Level Clear", "5c_02_goal", LocationType.level_clear, []), + "5c_02_golden": LevelLocation("5c_02_golden", "Mirror Temple C - Golden Strawberry", "5c_02_goal", LocationType.golden_strawberry, [[ItemName.red_boosters, ItemName.dash_refills, ItemName.dash_switches, ItemName.swap_blocks, ], ]), + + "6a_04c_crystal_heart": LevelLocation("6a_04c_crystal_heart", "Reflection A - Crystal Heart", "6a_04c_east", LocationType.crystal_heart, []), + "6a_04e_binoculars": LevelLocation("6a_04e_binoculars", "Reflection A - Room 04e Binoculars", "6a_04e_east", LocationType.binoculars, []), + "6a_04e_cassette": LevelLocation("6a_04e_cassette", "Reflection A - Cassette", "6a_04e_east", LocationType.cassette, [[ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.dash_refills, ], ]), + "6a_boss-20_golden": LevelLocation("6a_boss-20_golden", "Reflection A - Golden Strawberry", "6a_boss-20_east", LocationType.golden_strawberry, [[ItemName.feathers, ItemName.dash_refills, ItemName.kevin_blocks, ItemName.bumpers, ItemName.springs, ], ]), + "6a_after-01_clear": LevelLocation("6a_after-01_clear", "Reflection A - Level Clear", "6a_after-01_goal", LocationType.level_clear, []), + + "6b_a-02_binoculars": LevelLocation("6b_a-02_binoculars", "Reflection B - Room a-02 Binoculars", "6b_a-02_bottom", LocationType.binoculars, []), + "6b_a-06_binoculars": LevelLocation("6b_a-06_binoculars", "Reflection B - Room a-06 Binoculars", "6b_a-06_west", LocationType.binoculars, []), + "6b_d-05_clear": LevelLocation("6b_d-05_clear", "Reflection B - Level Clear", "6b_d-05_goal", LocationType.level_clear, []), + "6b_d-05_golden": LevelLocation("6b_d-05_golden", "Reflection B - Golden Strawberry", "6b_d-05_goal", LocationType.golden_strawberry, [[ItemName.blue_cassette_blocks, ItemName.bumpers, ItemName.dash_refills, ItemName.springs, ItemName.coins, ItemName.kevin_blocks, ItemName.feathers, ], ]), + + "6c_02_binoculars_1": LevelLocation("6c_02_binoculars_1", "Reflection C - Room 02 Binoculars 1", "6c_02_west", LocationType.binoculars, []), + "6c_02_binoculars_2": LevelLocation("6c_02_binoculars_2", "Reflection C - Room 02 Binoculars 2", "6c_02_west", LocationType.binoculars, [[ItemName.kevin_blocks, ItemName.dash_refills, ItemName.bumpers, ], ]), + "6c_02_clear": LevelLocation("6c_02_clear", "Reflection C - Level Clear", "6c_02_goal", LocationType.level_clear, []), + "6c_02_golden": LevelLocation("6c_02_golden", "Reflection C - Golden Strawberry", "6c_02_goal", LocationType.golden_strawberry, [[ItemName.kevin_blocks, ItemName.dash_refills, ItemName.bumpers, ItemName.feathers, ], ]), + + "7a_a-02b_strawberry": LevelLocation("7a_a-02b_strawberry", "The Summit A - Room a-02b Strawberry", "7a_a-02b_east", LocationType.strawberry, []), + "7a_a-04b_strawberry_1": LevelLocation("7a_a-04b_strawberry_1", "The Summit A - Room a-04b Strawberry 1", "7a_a-04b_east", LocationType.strawberry, [[ItemName.springs, ItemName.dash_refills, ], ]), + "7a_a-04b_strawberry_2": LevelLocation("7a_a-04b_strawberry_2", "The Summit A - Room a-04b Strawberry 2", "7a_a-04b_east", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "7a_a-05_strawberry": LevelLocation("7a_a-05_strawberry", "The Summit A - Room a-05 Strawberry", "7a_a-05_west", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "7a_a-06_gem_1": LevelLocation("7a_a-06_gem_1", "The Summit A - Gem 1", "7a_a-06_top-side", LocationType.gem, []), + "7a_b-01_binoculars": LevelLocation("7a_b-01_binoculars", "The Summit A - Room b-01 Binoculars", "7a_b-01_west", LocationType.binoculars, []), + "7a_b-02_binoculars": LevelLocation("7a_b-02_binoculars", "The Summit A - Room b-02 Binoculars", "7a_b-02_south", LocationType.binoculars, []), + "7a_b-02_strawberry": LevelLocation("7a_b-02_strawberry", "The Summit A - Room b-02 Strawberry", "7a_b-02_south", LocationType.strawberry, [[ItemName.traffic_blocks, ], ]), + "7a_b-02b_binoculars": LevelLocation("7a_b-02b_binoculars", "The Summit A - Room b-02b Binoculars", "7a_b-02b_south", LocationType.binoculars, []), + "7a_b-02b_strawberry": LevelLocation("7a_b-02b_strawberry", "The Summit A - Room b-02b Strawberry", "7a_b-02b_north-east", LocationType.strawberry, []), + "7a_b-02e_strawberry": LevelLocation("7a_b-02e_strawberry", "The Summit A - Room b-02e Strawberry", "7a_b-02e_east", LocationType.strawberry, [[ItemName.traffic_blocks, ], ]), + "7a_b-02d_gem_2": LevelLocation("7a_b-02d_gem_2", "The Summit A - Gem 2", "7a_b-02d_south", LocationType.gem, []), + "7a_b-04_strawberry": LevelLocation("7a_b-04_strawberry", "The Summit A - Room b-04 Strawberry", "7a_b-04_west", LocationType.strawberry, [[ItemName.springs, ], ]), + "7a_b-08_strawberry": LevelLocation("7a_b-08_strawberry", "The Summit A - Room b-08 Strawberry", "7a_b-08_east", LocationType.strawberry, []), + "7a_b-09_strawberry": LevelLocation("7a_b-09_strawberry", "The Summit A - Room b-09 Strawberry", "7a_b-09_top-side", LocationType.strawberry, []), + "7a_c-03b_binoculars": LevelLocation("7a_c-03b_binoculars", "The Summit A - Room c-03b Binoculars", "7a_c-03b_east", LocationType.binoculars, []), + "7a_c-03b_strawberry": LevelLocation("7a_c-03b_strawberry", "The Summit A - Room c-03b Strawberry", "7a_c-03b_east", LocationType.strawberry, [[ItemName.dream_blocks, ItemName.dash_refills, ], ]), + "7a_c-05_binoculars": LevelLocation("7a_c-05_binoculars", "The Summit A - Room c-05 Binoculars", "7a_c-05_west", LocationType.binoculars, []), + "7a_c-05_strawberry": LevelLocation("7a_c-05_strawberry", "The Summit A - Room c-05 Strawberry", "7a_c-05_west", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "7a_c-06b_strawberry": LevelLocation("7a_c-06b_strawberry", "The Summit A - Room c-06b Strawberry", "7a_c-06b_west", LocationType.strawberry, []), + "7a_c-06c_binoculars": LevelLocation("7a_c-06c_binoculars", "The Summit A - Room c-06c Binoculars", "7a_c-06c_west", LocationType.binoculars, []), + "7a_c-06c_gem_3": LevelLocation("7a_c-06c_gem_3", "The Summit A - Gem 3", "7a_c-06c_west", LocationType.gem, [[ItemName.dream_blocks, ItemName.coins, ], ]), + "7a_c-07b_binoculars": LevelLocation("7a_c-07b_binoculars", "The Summit A - Room c-07b Binoculars", "7a_c-07b_east", LocationType.binoculars, []), + "7a_c-07b_strawberry": LevelLocation("7a_c-07b_strawberry", "The Summit A - Room c-07b Strawberry", "7a_c-07b_east", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "7a_c-08_strawberry": LevelLocation("7a_c-08_strawberry", "The Summit A - Room c-08 Strawberry", "7a_c-08_west", LocationType.strawberry, [[ItemName.dream_blocks, ], ]), + "7a_c-09_strawberry": LevelLocation("7a_c-09_strawberry", "The Summit A - Room c-09 Strawberry", "7a_c-09_top", LocationType.strawberry, []), + "7a_d-00_strawberry": LevelLocation("7a_d-00_strawberry", "The Summit A - Room d-00 Strawberry", "7a_d-00_bottom", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "7a_d-01c_strawberry": LevelLocation("7a_d-01c_strawberry", "The Summit A - Room d-01c Strawberry", "7a_d-01c_east", LocationType.strawberry, [[ItemName.sinking_platforms, ], ]), + "7a_d-01d_strawberry": LevelLocation("7a_d-01d_strawberry", "The Summit A - Room d-01d Strawberry", "7a_d-01d_west", LocationType.strawberry, [[ItemName.coins, ItemName.dash_refills, ], ]), + "7a_d-03_strawberry": LevelLocation("7a_d-03_strawberry", "The Summit A - Room d-03 Strawberry", "7a_d-03_west", LocationType.strawberry, []), + "7a_d-03b_cassette": LevelLocation("7a_d-03b_cassette", "The Summit A - Cassette", "7a_d-03b_east", LocationType.cassette, [[ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ], ]), + "7a_d-04_strawberry": LevelLocation("7a_d-04_strawberry", "The Summit A - Room d-04 Strawberry", "7a_d-04_west", LocationType.strawberry, []), + "7a_d-05b_gem_4": LevelLocation("7a_d-05b_gem_4", "The Summit A - Gem 4", "7a_d-05b_west", LocationType.gem, [[ItemName.dash_refills, ], ]), + "7a_d-07_strawberry": LevelLocation("7a_d-07_strawberry", "The Summit A - Room d-07 Strawberry", "7a_d-07_east", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "7a_d-08_strawberry": LevelLocation("7a_d-08_strawberry", "The Summit A - Room d-08 Strawberry", "7a_d-08_east", LocationType.strawberry, []), + "7a_d-10b_strawberry": LevelLocation("7a_d-10b_strawberry", "The Summit A - Room d-10b Strawberry", "7a_d-10b_east", LocationType.strawberry, [[ItemName.springs, ], ]), + "7a_e-01c_gem_5": LevelLocation("7a_e-01c_gem_5", "The Summit A - Gem 5", "7a_e-01c_west", LocationType.gem, []), + "7a_e-02_strawberry": LevelLocation("7a_e-02_strawberry", "The Summit A - Room e-02 Strawberry", "7a_e-02_west", LocationType.strawberry, [[ItemName.pink_clouds, ], ]), + "7a_e-05_strawberry": LevelLocation("7a_e-05_strawberry", "The Summit A - Room e-05 Strawberry", "7a_e-05_east", LocationType.strawberry, []), + "7a_e-07_strawberry": LevelLocation("7a_e-07_strawberry", "The Summit A - Room e-07 Strawberry", "7a_e-07_bottom", LocationType.strawberry, [[ItemName.move_blocks, ItemName.dash_refills, ], ]), + "7a_e-09_strawberry": LevelLocation("7a_e-09_strawberry", "The Summit A - Room e-09 Strawberry", "7a_e-09_east", LocationType.strawberry, []), + "7a_e-11_strawberry": LevelLocation("7a_e-11_strawberry", "The Summit A - Room e-11 Strawberry", "7a_e-11_east", LocationType.strawberry, []), + "7a_e-12_strawberry": LevelLocation("7a_e-12_strawberry", "The Summit A - Room e-12 Strawberry", "7a_e-12_west", LocationType.strawberry, [[ItemName.strawberry_seeds, ItemName.dash_refills, ], ]), + "7a_e-10_strawberry": LevelLocation("7a_e-10_strawberry", "The Summit A - Room e-10 Strawberry", "7a_e-10_south", LocationType.strawberry, [[ItemName.blue_boosters, ], ]), + "7a_e-13_strawberry": LevelLocation("7a_e-13_strawberry", "The Summit A - Room e-13 Strawberry", "7a_e-13_top", LocationType.strawberry, []), + "7a_f-00_strawberry": LevelLocation("7a_f-00_strawberry", "The Summit A - Room f-00 Strawberry", "7a_f-00_west", LocationType.strawberry, [[ItemName.red_boosters, ], ]), + "7a_f-01_strawberry": LevelLocation("7a_f-01_strawberry", "The Summit A - Room f-01 Strawberry", "7a_f-01_south", LocationType.strawberry, [[ItemName.swap_blocks, ], ]), + "7a_f-02b_gem_6": LevelLocation("7a_f-02b_gem_6", "The Summit A - Gem 6", "7a_f-02b_east", LocationType.gem, []), + "7a_f-07_strawberry": LevelLocation("7a_f-07_strawberry", "The Summit A - Room f-07 Strawberry", "7a_f-07_south-west", LocationType.strawberry, [[ItemName.red_boosters, ], ]), + "7a_f-07_key": LevelLocation("7a_f-07_key", "The Summit A - 2500 M Key", "7a_f-07_south-east", LocationType.key, [[ItemName.red_boosters, ], ]), + "7a_f-08b_strawberry": LevelLocation("7a_f-08b_strawberry", "The Summit A - Room f-08b Strawberry", "7a_f-08b_east", LocationType.strawberry, [[ItemName.swap_blocks, ], ]), + "7a_f-08c_strawberry": LevelLocation("7a_f-08c_strawberry", "The Summit A - Room f-08c Strawberry", "7a_f-08c_east", LocationType.strawberry, []), + "7a_f-11_strawberry_1": LevelLocation("7a_f-11_strawberry_1", "The Summit A - Room f-11 Strawberry 1", "7a_f-11_top", LocationType.strawberry, []), + "7a_f-11_strawberry_2": LevelLocation("7a_f-11_strawberry_2", "The Summit A - Room f-11 Strawberry 2", "7a_f-11_top", LocationType.strawberry, []), + "7a_f-11_strawberry_3": LevelLocation("7a_f-11_strawberry_3", "The Summit A - Room f-11 Strawberry 3", "7a_f-11_top", LocationType.strawberry, [[ItemName.dash_switches, ], ]), + "7a_g-00b_crystal_heart": LevelLocation("7a_g-00b_crystal_heart", "The Summit A - Crystal Heart", "7a_g-00b_bottom", LocationType.crystal_heart, [["The Summit A - Gem 1", "The Summit A - Gem 2", "The Summit A - Gem 3", "The Summit A - Gem 4", "The Summit A - Gem 5", "The Summit A - Gem 6", ], ]), + "7a_g-00b_strawberry_1": LevelLocation("7a_g-00b_strawberry_1", "The Summit A - Room g-00b Strawberry 1", "7a_g-00b_c26", LocationType.strawberry, [[ItemName.dash_refills, ], ]), + "7a_g-00b_strawberry_2": LevelLocation("7a_g-00b_strawberry_2", "The Summit A - Room g-00b Strawberry 2", "7a_g-00b_c24", LocationType.strawberry, [[ItemName.springs, ], ]), + "7a_g-00b_strawberry_3": LevelLocation("7a_g-00b_strawberry_3", "The Summit A - Room g-00b Strawberry 3", "7a_g-00b_c21", LocationType.strawberry, [[ItemName.springs, ], ]), + "7a_g-01_strawberry_1": LevelLocation("7a_g-01_strawberry_1", "The Summit A - Room g-01 Strawberry 1", "7a_g-01_c18", LocationType.strawberry, [[ItemName.dash_refills, ItemName.blue_clouds, ], ]), + "7a_g-01_strawberry_2": LevelLocation("7a_g-01_strawberry_2", "The Summit A - Room g-01 Strawberry 2", "7a_g-01_c16", LocationType.strawberry, []), + "7a_g-01_strawberry_3": LevelLocation("7a_g-01_strawberry_3", "The Summit A - Room g-01 Strawberry 3", "7a_g-01_c16", LocationType.strawberry, []), + "7a_g-03_binoculars": LevelLocation("7a_g-03_binoculars", "The Summit A - Room g-03 Binoculars", "7a_g-03_bottom", LocationType.binoculars, [[ItemName.springs, ], ]), + "7a_g-03_strawberry": LevelLocation("7a_g-03_strawberry", "The Summit A - Room g-03 Strawberry", "7a_g-03_bottom", LocationType.strawberry, [[ItemName.springs, ItemName.dash_refills, ItemName.feathers, ], ]), + "7a_g-03_clear": LevelLocation("7a_g-03_clear", "The Summit A - Level Clear", "7a_g-03_goal", LocationType.level_clear, []), + "7a_g-03_golden": LevelLocation("7a_g-03_golden", "The Summit A - Golden Strawberry", "7a_g-03_goal", LocationType.golden_strawberry, [[ItemName.springs, ItemName.dash_refills, ItemName.feathers, ItemName.blue_clouds, ItemName.pink_clouds, ItemName.coins, ItemName.badeline_boosters, ItemName.red_boosters, ItemName.swap_blocks, ItemName.dash_switches, "The Summit A - 2500 M Key", ItemName.move_blocks, ItemName.blue_boosters, ItemName.dream_blocks, ItemName.traffic_blocks, ], ]), + + "7b_b-01_binoculars": LevelLocation("7b_b-01_binoculars", "The Summit B - Room b-01 Binoculars", "7b_b-01_bottom", LocationType.binoculars, []), + "7b_b-02_binoculars": LevelLocation("7b_b-02_binoculars", "The Summit B - Room b-02 Binoculars", "7b_b-02_west", LocationType.binoculars, [[ItemName.springs, ], ]), + "7b_g-03_clear": LevelLocation("7b_g-03_clear", "The Summit B - Level Clear", "7b_g-03_goal", LocationType.level_clear, []), + "7b_g-03_golden": LevelLocation("7b_g-03_golden", "The Summit B - Golden Strawberry", "7b_g-03_goal", LocationType.golden_strawberry, [[ItemName.springs, ItemName.dash_refills, ItemName.blue_clouds, ItemName.pink_clouds, ItemName.coins, ItemName.badeline_boosters, ItemName.red_boosters, ItemName.swap_blocks, ItemName.move_blocks, ItemName.blue_boosters, ItemName.dream_blocks, ItemName.traffic_blocks, ], ]), + + "7c_01_binoculars": LevelLocation("7c_01_binoculars", "The Summit C - Room 01 Binoculars", "7c_01_west", LocationType.binoculars, []), + "7c_03_binoculars": LevelLocation("7c_03_binoculars", "The Summit C - Room 03 Binoculars", "7c_03_west", LocationType.binoculars, []), + "7c_03_clear": LevelLocation("7c_03_clear", "The Summit C - Level Clear", "7c_03_goal", LocationType.level_clear, []), + "7c_03_golden": LevelLocation("7c_03_golden", "The Summit C - Golden Strawberry", "7c_03_goal", LocationType.golden_strawberry, [[ItemName.pink_clouds, ItemName.dash_refills, ItemName.springs, ItemName.coins, ItemName.badeline_boosters, ], ]), + + + "9a_0x_car": LevelLocation("9a_0x_car", "Core A - Car", "9a_0x_east", LocationType.car, []), + "9a_b-06_strawberry": LevelLocation("9a_b-06_strawberry", "Core A - Room b-06 Strawberry", "9a_b-06_east", LocationType.strawberry, [[ItemName.fire_ice_balls, ItemName.core_toggles, ItemName.core_blocks, ItemName.dash_refills, ItemName.bumpers, ItemName.coins, ], ]), + "9a_c-00b_strawberry": LevelLocation("9a_c-00b_strawberry", "Core A - Room c-00b Strawberry", "9a_c-00b_west", LocationType.strawberry, [[ItemName.fire_ice_balls, ItemName.core_toggles, ItemName.dash_refills, ItemName.bumpers, ], ]), + "9a_c-02_strawberry": LevelLocation("9a_c-02_strawberry", "Core A - Room c-02 Strawberry", "9a_c-02_west", LocationType.strawberry, [[ItemName.core_blocks, ItemName.core_toggles, ItemName.dash_refills, ItemName.bumpers, ], ]), + "9a_c-03b_strawberry": LevelLocation("9a_c-03b_strawberry", "Core A - Room c-03b Strawberry", "9a_c-03b_south", LocationType.strawberry, [[ItemName.core_toggles, ], ]), + "9a_d-06_strawberry": LevelLocation("9a_d-06_strawberry", "Core A - Room d-06 Strawberry", "9a_d-06_bottom", LocationType.strawberry, [[ItemName.dash_refills, ItemName.core_blocks, ], ]), + "9a_d-11_cassette": LevelLocation("9a_d-11_cassette", "Core A - Cassette", "9a_d-11_center", LocationType.cassette, []), + "9a_space_clear": LevelLocation("9a_space_clear", "Core A - Level Clear", "9a_space_goal", LocationType.level_clear, []), + "9a_space_golden": LevelLocation("9a_space_golden", "Core A - Golden Strawberry", "9a_space_goal", LocationType.golden_strawberry, [[ItemName.dash_refills, ItemName.springs, ItemName.coins, ItemName.bumpers, ItemName.feathers, ItemName.badeline_boosters, ItemName.core_blocks, ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ], ]), + + "9b_space_clear": LevelLocation("9b_space_clear", "Core B - Level Clear", "9b_space_goal", LocationType.level_clear, []), + "9b_space_golden": LevelLocation("9b_space_golden", "Core B - Golden Strawberry", "9b_space_goal", LocationType.golden_strawberry, [[ItemName.dash_refills, ItemName.bumpers, ItemName.coins, ItemName.springs, ItemName.traffic_blocks, ItemName.dream_blocks, ItemName.moving_platforms, ItemName.blue_clouds, ItemName.swap_blocks, ItemName.kevin_blocks, ItemName.core_blocks, ItemName.badeline_boosters, ItemName.core_toggles, ItemName.fire_ice_balls, ItemName.blue_cassette_blocks, ItemName.pink_cassette_blocks, ], ]), + + "9c_01_binoculars": LevelLocation("9c_01_binoculars", "Core C - Room 01 Binoculars", "9c_01_west", LocationType.binoculars, []), + "9c_02_binoculars": LevelLocation("9c_02_binoculars", "Core C - Room 02 Binoculars", "9c_02_west", LocationType.binoculars, []), + "9c_02_clear": LevelLocation("9c_02_clear", "Core C - Level Clear", "9c_02_goal", LocationType.level_clear, []), + "9c_02_golden": LevelLocation("9c_02_golden", "Core C - Golden Strawberry", "9c_02_goal", LocationType.golden_strawberry, [[ItemName.springs, ItemName.traffic_blocks, ItemName.dash_refills, ItemName.core_toggles, ItemName.dream_blocks, ItemName.bumpers, ItemName.pink_clouds, ItemName.swap_blocks, ItemName.kevin_blocks, ItemName.core_blocks, ], ]), + + "10a_a-04_binoculars": LevelLocation("10a_a-04_binoculars", "Farewell - Room a-04 Binoculars", "10a_a-04_west", LocationType.binoculars, []), + "10a_b-06_binoculars": LevelLocation("10a_b-06_binoculars", "Farewell - Room b-06 Binoculars", "10a_b-06_west", LocationType.binoculars, []), + "10a_d-00_binoculars": LevelLocation("10a_d-00_binoculars", "Farewell - Room d-00 Binoculars", "10a_d-00_south", LocationType.binoculars, []), + "10a_d-04_binoculars": LevelLocation("10a_d-04_binoculars", "Farewell - Room d-04 Binoculars", "10a_d-04_west", LocationType.binoculars, []), + "10a_d-04_key_1": LevelLocation("10a_d-04_key_1", "Farewell - Power Source Key 1", "10a_d-04_west", LocationType.key, [[ItemName.double_dash_refills, ItemName.jellyfish, ], ]), + "10a_d-03_binoculars": LevelLocation("10a_d-03_binoculars", "Farewell - Room d-03 Binoculars", "10a_d-03_west", LocationType.binoculars, [[ItemName.breaker_boxes, ], ]), + "10a_d-03_key_2": LevelLocation("10a_d-03_key_2", "Farewell - Power Source Key 2", "10a_d-03_west", LocationType.key, [[ItemName.breaker_boxes, ItemName.double_dash_refills, ItemName.jellyfish, ], ]), + "10a_d-01_binoculars": LevelLocation("10a_d-01_binoculars", "Farewell - Room d-01 Binoculars", "10a_d-01_east", LocationType.binoculars, []), + "10a_d-01_key_3": LevelLocation("10a_d-01_key_3", "Farewell - Power Source Key 3", "10a_d-01_east", LocationType.key, [[ItemName.dash_refills, ItemName.dash_switches, ItemName.jellyfish, ], ]), + "10a_d-02_binoculars": LevelLocation("10a_d-02_binoculars", "Farewell - Room d-02 Binoculars", "10a_d-02_bottom", LocationType.binoculars, [[ItemName.breaker_boxes, ], ]), + "10a_d-02_key_4": LevelLocation("10a_d-02_key_4", "Farewell - Power Source Key 4", "10a_d-02_bottom", LocationType.key, [[ItemName.breaker_boxes, ItemName.double_dash_refills, ItemName.springs, ItemName.move_blocks, ItemName.jellyfish, ], ]), + "10a_d-05_binoculars": LevelLocation("10a_d-05_binoculars", "Farewell - Room d-05 Binoculars", "10a_d-05_west", LocationType.binoculars, []), + "10a_d-05_key_5": LevelLocation("10a_d-05_key_5", "Farewell - Power Source Key 5", "10a_d-05_west", LocationType.key, [[ItemName.double_dash_refills, ItemName.coins, ItemName.red_boosters, ItemName.jellyfish, ], ]), + "10a_e-00yb_binoculars": LevelLocation("10a_e-00yb_binoculars", "Farewell - Room e-00yb Binoculars", "10a_e-00yb_south", LocationType.binoculars, []), + "10a_e-00b_binoculars": LevelLocation("10a_e-00b_binoculars", "Farewell - Room e-00b Binoculars", "10a_e-00b_south", LocationType.binoculars, []), + "10a_e-01_binoculars": LevelLocation("10a_e-01_binoculars", "Farewell - Room e-01 Binoculars", "10a_e-01_south", LocationType.binoculars, []), + "10a_e-01_car": LevelLocation("10a_e-01_car", "Farewell - Secret Car", "10a_e-01_south", LocationType.car, [[ItemName.jellyfish, ItemName.springs, ItemName.dash_refills, ], ]), + "10a_e-02_binoculars": LevelLocation("10a_e-02_binoculars", "Farewell - Room e-02 Binoculars", "10a_e-02_west", LocationType.binoculars, []), + "10a_e-04_binoculars": LevelLocation("10a_e-04_binoculars", "Farewell - Room e-04 Binoculars", "10a_e-04_west", LocationType.binoculars, []), + "10a_e-08_binoculars": LevelLocation("10a_e-08_binoculars", "Farewell - Room e-08 Binoculars", "10a_e-08_west", LocationType.binoculars, []), + "10a_e-08_crystal_heart": LevelLocation("10a_e-08_crystal_heart", "Farewell - Crystal Heart?", "10a_e-08_east", LocationType.crystal_heart, []), + + "10b_f-00_car": LevelLocation("10b_f-00_car", "Farewell - Internet Car", "10b_f-00_west", LocationType.car, []), + "10b_f-06_binoculars": LevelLocation("10b_f-06_binoculars", "Farewell - Room f-06 Binoculars", "10b_f-06_west", LocationType.binoculars, []), + "10b_f-07_binoculars": LevelLocation("10b_f-07_binoculars", "Farewell - Room f-07 Binoculars", "10b_f-07_west", LocationType.binoculars, []), + "10b_f-08_binoculars": LevelLocation("10b_f-08_binoculars", "Farewell - Room f-08 Binoculars", "10b_f-08_west", LocationType.binoculars, []), + "10b_f-09_binoculars": LevelLocation("10b_f-09_binoculars", "Farewell - Room f-09 Binoculars", "10b_f-09_west", LocationType.binoculars, []), + "10b_g-00_binoculars": LevelLocation("10b_g-00_binoculars", "Farewell - Room g-00 Binoculars", "10b_g-00_bottom", LocationType.binoculars, []), + "10b_g-04_binoculars": LevelLocation("10b_g-04_binoculars", "Farewell - Room g-04 Binoculars", "10b_g-04_west", LocationType.binoculars, []), + "10b_g-06_binoculars": LevelLocation("10b_g-06_binoculars", "Farewell - Room g-06 Binoculars", "10b_g-06_west", LocationType.binoculars, [[ItemName.double_dash_refills, ItemName.dash_refills, ItemName.springs, ItemName.feathers, ], ]), + "10b_h-01_binoculars": LevelLocation("10b_h-01_binoculars", "Farewell - Room h-01 Binoculars", "10b_h-01_west", LocationType.binoculars, []), + "10b_h-02_binoculars": LevelLocation("10b_h-02_binoculars", "Farewell - Room h-02 Binoculars", "10b_h-02_west", LocationType.binoculars, []), + "10b_h-03b_binoculars": LevelLocation("10b_h-03b_binoculars", "Farewell - Room h-03b Binoculars", "10b_h-03b_west", LocationType.binoculars, []), + "10b_h-04_binoculars": LevelLocation("10b_h-04_binoculars", "Farewell - Room h-04 Binoculars", "10b_h-04_top", LocationType.binoculars, []), + "10b_h-05_binoculars": LevelLocation("10b_h-05_binoculars", "Farewell - Room h-05 Binoculars", "10b_h-05_top", LocationType.binoculars, []), + "10b_h-06b_binoculars": LevelLocation("10b_h-06b_binoculars", "Farewell - Room h-06b Binoculars", "10b_h-06b_bottom", LocationType.binoculars, []), + "10b_h-07_binoculars_1": LevelLocation("10b_h-07_binoculars_1", "Farewell - Room h-07 Binoculars 1", "10b_h-07_west", LocationType.binoculars, []), + "10b_h-07_binoculars_2": LevelLocation("10b_h-07_binoculars_2", "Farewell - Room h-07 Binoculars 2", "10b_h-07_west", LocationType.binoculars, [[ItemName.blue_boosters, ItemName.springs, ItemName.coins, ], ]), + "10b_h-08_binoculars": LevelLocation("10b_h-08_binoculars", "Farewell - Room h-08 Binoculars", "10b_h-08_west", LocationType.binoculars, []), + "10b_h-09_binoculars": LevelLocation("10b_h-09_binoculars", "Farewell - Room h-09 Binoculars", "10b_h-09_west", LocationType.binoculars, []), + "10b_i-00b_binoculars": LevelLocation("10b_i-00b_binoculars", "Farewell - Room i-00b Binoculars", "10b_i-00b_west", LocationType.binoculars, []), + "10b_i-02_binoculars": LevelLocation("10b_i-02_binoculars", "Farewell - Room i-02 Binoculars", "10b_i-02_west", LocationType.binoculars, []), + "10b_i-04_binoculars": LevelLocation("10b_i-04_binoculars", "Farewell - Room i-04 Binoculars", "10b_i-04_west", LocationType.binoculars, []), + "10b_i-05_binoculars": LevelLocation("10b_i-05_binoculars", "Farewell - Room i-05 Binoculars", "10b_i-05_west", LocationType.binoculars, []), + "10b_j-16_binoculars": LevelLocation("10b_j-16_binoculars", "Farewell - Room j-16 Binoculars", "10b_j-16_west", LocationType.binoculars, []), + "10b_j-19_binoculars": LevelLocation("10b_j-19_binoculars", "Farewell - Room j-19 Binoculars", "10b_j-19_bottom", LocationType.binoculars, []), + "10b_j-19_moon_berry": LevelLocation("10b_j-19_moon_berry", "Farewell - Moon Berry", "10b_j-19_top", LocationType.strawberry, []), + "10b_GOAL_clear": LevelLocation("10b_GOAL_clear", "Farewell - Level Clear", "10b_GOAL_main", LocationType.level_clear, []), + + "10c_end-golden_binoculars_1": LevelLocation("10c_end-golden_binoculars_1", "Farewell - Room end-golden Binoculars 1", "10c_end-golden_bottom", LocationType.binoculars, []), + "10c_end-golden_binoculars_2": LevelLocation("10c_end-golden_binoculars_2", "Farewell - Room end-golden Binoculars 2", "10c_end-golden_bottom", LocationType.binoculars, []), + "10c_end-golden_binoculars_3": LevelLocation("10c_end-golden_binoculars_3", "Farewell - Room end-golden Binoculars 3", "10c_end-golden_bottom", LocationType.binoculars, [[ItemName.double_dash_refills, ItemName.jellyfish, ItemName.springs, ItemName.pufferfish, ], ]), + "10c_end-golden_golden": LevelLocation("10c_end-golden_golden", "Farewell - Golden Strawberry", "10c_end-golden_top", LocationType.golden_strawberry, [[ItemName.traffic_blocks, ItemName.dash_refills, ItemName.double_dash_refills, ItemName.dream_blocks, ItemName.swap_blocks, ItemName.move_blocks, ItemName.blue_boosters, ItemName.springs, ItemName.feathers, ItemName.coins, ItemName.red_boosters, ItemName.kevin_blocks, ItemName.core_blocks, ItemName.fire_ice_balls, ItemName.badeline_boosters, ItemName.bird, ItemName.breaker_boxes, ItemName.pufferfish, ItemName.jellyfish, ItemName.pink_cassette_blocks, ItemName.blue_cassette_blocks, ItemName.yellow_cassette_blocks, ItemName.green_cassette_blocks, ], ]), + +} + +all_regions: dict[str, PreRegion] = { + "0a_-1_main": PreRegion("0a_-1_main", "0a_-1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_-1_main"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_-1_main"]), + "0a_-1_east": PreRegion("0a_-1_east", "0a_-1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_-1_east"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_-1_east"]), + + "0a_0_west": PreRegion("0a_0_west", "0a_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_0_west"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_0_west"]), + "0a_0_main": PreRegion("0a_0_main", "0a_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_0_main"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_0_main"]), + "0a_0_north": PreRegion("0a_0_north", "0a_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_0_north"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_0_north"]), + "0a_0_east": PreRegion("0a_0_east", "0a_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_0_east"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_0_east"]), + + "0a_0b_south": PreRegion("0a_0b_south", "0a_0b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_0b_south"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_0b_south"]), + + "0a_1_west": PreRegion("0a_1_west", "0a_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_1_west"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_1_west"]), + "0a_1_main": PreRegion("0a_1_main", "0a_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_1_main"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_1_main"]), + "0a_1_east": PreRegion("0a_1_east", "0a_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_1_east"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_1_east"]), + + "0a_2_west": PreRegion("0a_2_west", "0a_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_2_west"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_2_west"]), + "0a_2_main": PreRegion("0a_2_main", "0a_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_2_main"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_2_main"]), + "0a_2_east": PreRegion("0a_2_east", "0a_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_2_east"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_2_east"]), + + "0a_3_west": PreRegion("0a_3_west", "0a_3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_3_west"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_3_west"]), + "0a_3_main": PreRegion("0a_3_main", "0a_3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_3_main"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_3_main"]), + "0a_3_east": PreRegion("0a_3_east", "0a_3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "0a_3_east"], [loc for _, loc in all_locations.items() if loc.region_name == "0a_3_east"]), + + "1a_1_main": PreRegion("1a_1_main", "1a_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_1_main"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_1_main"]), + "1a_1_east": PreRegion("1a_1_east", "1a_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_1_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_1_east"]), + + "1a_2_west": PreRegion("1a_2_west", "1a_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_2_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_2_west"]), + "1a_2_east": PreRegion("1a_2_east", "1a_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_2_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_2_east"]), + + "1a_3_west": PreRegion("1a_3_west", "1a_3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_3_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_3_west"]), + "1a_3_east": PreRegion("1a_3_east", "1a_3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_3_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_3_east"]), + + "1a_4_west": PreRegion("1a_4_west", "1a_4", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_4_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_4_west"]), + "1a_4_east": PreRegion("1a_4_east", "1a_4", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_4_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_4_east"]), + + "1a_3b_west": PreRegion("1a_3b_west", "1a_3b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_3b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_3b_west"]), + "1a_3b_east": PreRegion("1a_3b_east", "1a_3b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_3b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_3b_east"]), + "1a_3b_top": PreRegion("1a_3b_top", "1a_3b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_3b_top"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_3b_top"]), + + "1a_5_bottom": PreRegion("1a_5_bottom", "1a_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_5_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_5_bottom"]), + "1a_5_west": PreRegion("1a_5_west", "1a_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_5_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_5_west"]), + "1a_5_north-west": PreRegion("1a_5_north-west", "1a_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_5_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_5_north-west"]), + "1a_5_center": PreRegion("1a_5_center", "1a_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_5_center"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_5_center"]), + "1a_5_south-east": PreRegion("1a_5_south-east", "1a_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_5_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_5_south-east"]), + "1a_5_north-east": PreRegion("1a_5_north-east", "1a_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_5_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_5_north-east"]), + "1a_5_top": PreRegion("1a_5_top", "1a_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_5_top"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_5_top"]), + + "1a_5z_east": PreRegion("1a_5z_east", "1a_5z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_5z_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_5z_east"]), + + "1a_5a_west": PreRegion("1a_5a_west", "1a_5a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_5a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_5a_west"]), + + "1a_6_south-west": PreRegion("1a_6_south-west", "1a_6", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6_south-west"]), + "1a_6_west": PreRegion("1a_6_west", "1a_6", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6_west"]), + "1a_6_east": PreRegion("1a_6_east", "1a_6", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6_east"]), + + "1a_6z_north-west": PreRegion("1a_6z_north-west", "1a_6z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6z_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6z_north-west"]), + "1a_6z_west": PreRegion("1a_6z_west", "1a_6z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6z_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6z_west"]), + "1a_6z_east": PreRegion("1a_6z_east", "1a_6z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6z_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6z_east"]), + + "1a_6zb_north-west": PreRegion("1a_6zb_north-west", "1a_6zb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6zb_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6zb_north-west"]), + "1a_6zb_main": PreRegion("1a_6zb_main", "1a_6zb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6zb_main"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6zb_main"]), + "1a_6zb_east": PreRegion("1a_6zb_east", "1a_6zb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6zb_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6zb_east"]), + + "1a_7zb_west": PreRegion("1a_7zb_west", "1a_7zb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_7zb_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_7zb_west"]), + "1a_7zb_east": PreRegion("1a_7zb_east", "1a_7zb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_7zb_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_7zb_east"]), + + "1a_6a_west": PreRegion("1a_6a_west", "1a_6a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6a_west"]), + "1a_6a_east": PreRegion("1a_6a_east", "1a_6a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6a_east"]), + + "1a_6b_south-west": PreRegion("1a_6b_south-west", "1a_6b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6b_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6b_south-west"]), + "1a_6b_north-west": PreRegion("1a_6b_north-west", "1a_6b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6b_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6b_north-west"]), + "1a_6b_north-east": PreRegion("1a_6b_north-east", "1a_6b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6b_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6b_north-east"]), + + "1a_s0_west": PreRegion("1a_s0_west", "1a_s0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_s0_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_s0_west"]), + "1a_s0_east": PreRegion("1a_s0_east", "1a_s0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_s0_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_s0_east"]), + + "1a_s1_east": PreRegion("1a_s1_east", "1a_s1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_s1_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_s1_east"]), + + "1a_6c_south-west": PreRegion("1a_6c_south-west", "1a_6c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6c_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6c_south-west"]), + "1a_6c_north-west": PreRegion("1a_6c_north-west", "1a_6c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6c_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6c_north-west"]), + "1a_6c_north-east": PreRegion("1a_6c_north-east", "1a_6c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_6c_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_6c_north-east"]), + + "1a_7_west": PreRegion("1a_7_west", "1a_7", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_7_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_7_west"]), + "1a_7_east": PreRegion("1a_7_east", "1a_7", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_7_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_7_east"]), + + "1a_7z_bottom": PreRegion("1a_7z_bottom", "1a_7z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_7z_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_7z_bottom"]), + "1a_7z_top": PreRegion("1a_7z_top", "1a_7z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_7z_top"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_7z_top"]), + + "1a_8z_bottom": PreRegion("1a_8z_bottom", "1a_8z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8z_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8z_bottom"]), + "1a_8z_top": PreRegion("1a_8z_top", "1a_8z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8z_top"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8z_top"]), + + "1a_8zb_west": PreRegion("1a_8zb_west", "1a_8zb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8zb_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8zb_west"]), + "1a_8zb_east": PreRegion("1a_8zb_east", "1a_8zb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8zb_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8zb_east"]), + + "1a_8_south-west": PreRegion("1a_8_south-west", "1a_8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8_south-west"]), + "1a_8_west": PreRegion("1a_8_west", "1a_8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8_west"]), + "1a_8_south": PreRegion("1a_8_south", "1a_8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8_south"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8_south"]), + "1a_8_south-east": PreRegion("1a_8_south-east", "1a_8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8_south-east"]), + "1a_8_north": PreRegion("1a_8_north", "1a_8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8_north"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8_north"]), + "1a_8_north-east": PreRegion("1a_8_north-east", "1a_8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8_north-east"]), + + "1a_7a_east": PreRegion("1a_7a_east", "1a_7a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_7a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_7a_east"]), + "1a_7a_west": PreRegion("1a_7a_west", "1a_7a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_7a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_7a_west"]), + + "1a_9z_east": PreRegion("1a_9z_east", "1a_9z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_9z_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_9z_east"]), + + "1a_8b_east": PreRegion("1a_8b_east", "1a_8b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8b_east"]), + "1a_8b_west": PreRegion("1a_8b_west", "1a_8b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_8b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_8b_west"]), + + "1a_9_east": PreRegion("1a_9_east", "1a_9", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_9_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_9_east"]), + "1a_9_west": PreRegion("1a_9_west", "1a_9", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_9_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_9_west"]), + + "1a_9b_east": PreRegion("1a_9b_east", "1a_9b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_9b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_9b_east"]), + "1a_9b_north-east": PreRegion("1a_9b_north-east", "1a_9b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_9b_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_9b_north-east"]), + "1a_9b_west": PreRegion("1a_9b_west", "1a_9b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_9b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_9b_west"]), + "1a_9b_north-west": PreRegion("1a_9b_north-west", "1a_9b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_9b_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_9b_north-west"]), + + "1a_9c_west": PreRegion("1a_9c_west", "1a_9c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_9c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_9c_west"]), + + "1a_10_south-east": PreRegion("1a_10_south-east", "1a_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_10_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_10_south-east"]), + "1a_10_south-west": PreRegion("1a_10_south-west", "1a_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_10_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_10_south-west"]), + "1a_10_north-west": PreRegion("1a_10_north-west", "1a_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_10_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_10_north-west"]), + "1a_10_north-east": PreRegion("1a_10_north-east", "1a_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_10_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_10_north-east"]), + + "1a_10z_west": PreRegion("1a_10z_west", "1a_10z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_10z_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_10z_west"]), + "1a_10z_east": PreRegion("1a_10z_east", "1a_10z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_10z_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_10z_east"]), + + "1a_10zb_east": PreRegion("1a_10zb_east", "1a_10zb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_10zb_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_10zb_east"]), + + "1a_11_south-east": PreRegion("1a_11_south-east", "1a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_11_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_11_south-east"]), + "1a_11_south-west": PreRegion("1a_11_south-west", "1a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_11_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_11_south-west"]), + "1a_11_north": PreRegion("1a_11_north", "1a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_11_north"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_11_north"]), + "1a_11_west": PreRegion("1a_11_west", "1a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_11_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_11_west"]), + "1a_11_south": PreRegion("1a_11_south", "1a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_11_south"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_11_south"]), + + "1a_11z_east": PreRegion("1a_11z_east", "1a_11z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_11z_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_11z_east"]), + + "1a_10a_bottom": PreRegion("1a_10a_bottom", "1a_10a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_10a_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_10a_bottom"]), + "1a_10a_top": PreRegion("1a_10a_top", "1a_10a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_10a_top"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_10a_top"]), + + "1a_12_south-west": PreRegion("1a_12_south-west", "1a_12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_12_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_12_south-west"]), + "1a_12_north-west": PreRegion("1a_12_north-west", "1a_12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_12_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_12_north-west"]), + "1a_12_east": PreRegion("1a_12_east", "1a_12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_12_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_12_east"]), + + "1a_12z_east": PreRegion("1a_12z_east", "1a_12z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_12z_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_12z_east"]), + + "1a_12a_bottom": PreRegion("1a_12a_bottom", "1a_12a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_12a_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_12a_bottom"]), + "1a_12a_top": PreRegion("1a_12a_top", "1a_12a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_12a_top"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_12a_top"]), + + "1a_end_south": PreRegion("1a_end_south", "1a_end", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_end_south"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_end_south"]), + "1a_end_main": PreRegion("1a_end_main", "1a_end", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1a_end_main"], [loc for _, loc in all_locations.items() if loc.region_name == "1a_end_main"]), + + "1b_00_west": PreRegion("1b_00_west", "1b_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_00_west"]), + "1b_00_east": PreRegion("1b_00_east", "1b_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_00_east"]), + + "1b_01_west": PreRegion("1b_01_west", "1b_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_01_west"]), + "1b_01_east": PreRegion("1b_01_east", "1b_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_01_east"]), + + "1b_02_west": PreRegion("1b_02_west", "1b_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_02_west"]), + "1b_02_east": PreRegion("1b_02_east", "1b_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_02_east"]), + + "1b_02b_west": PreRegion("1b_02b_west", "1b_02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_02b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_02b_west"]), + "1b_02b_east": PreRegion("1b_02b_east", "1b_02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_02b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_02b_east"]), + + "1b_03_west": PreRegion("1b_03_west", "1b_03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_03_west"]), + "1b_03_east": PreRegion("1b_03_east", "1b_03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_03_east"]), + + "1b_04_west": PreRegion("1b_04_west", "1b_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_04_west"]), + "1b_04_east": PreRegion("1b_04_east", "1b_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_04_east"]), + + "1b_05_west": PreRegion("1b_05_west", "1b_05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_05_west"]), + "1b_05_east": PreRegion("1b_05_east", "1b_05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_05_east"]), + + "1b_05b_west": PreRegion("1b_05b_west", "1b_05b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_05b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_05b_west"]), + "1b_05b_east": PreRegion("1b_05b_east", "1b_05b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_05b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_05b_east"]), + + "1b_06_west": PreRegion("1b_06_west", "1b_06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_06_west"]), + "1b_06_east": PreRegion("1b_06_east", "1b_06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_06_east"]), + + "1b_07_bottom": PreRegion("1b_07_bottom", "1b_07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_07_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_07_bottom"]), + "1b_07_top": PreRegion("1b_07_top", "1b_07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_07_top"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_07_top"]), + + "1b_08_west": PreRegion("1b_08_west", "1b_08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_08_west"]), + "1b_08_east": PreRegion("1b_08_east", "1b_08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_08_east"]), + + "1b_08b_west": PreRegion("1b_08b_west", "1b_08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_08b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_08b_west"]), + "1b_08b_east": PreRegion("1b_08b_east", "1b_08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_08b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_08b_east"]), + + "1b_09_west": PreRegion("1b_09_west", "1b_09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_09_west"]), + "1b_09_east": PreRegion("1b_09_east", "1b_09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_09_east"]), + + "1b_10_west": PreRegion("1b_10_west", "1b_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_10_west"]), + "1b_10_east": PreRegion("1b_10_east", "1b_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_10_east"]), + + "1b_11_bottom": PreRegion("1b_11_bottom", "1b_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_11_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_11_bottom"]), + "1b_11_top": PreRegion("1b_11_top", "1b_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_11_top"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_11_top"]), + + "1b_end_west": PreRegion("1b_end_west", "1b_end", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_end_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_end_west"]), + "1b_end_goal": PreRegion("1b_end_goal", "1b_end", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1b_end_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "1b_end_goal"]), + + "1c_00_west": PreRegion("1c_00_west", "1c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1c_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1c_00_west"]), + "1c_00_east": PreRegion("1c_00_east", "1c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1c_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1c_00_east"]), + + "1c_01_west": PreRegion("1c_01_west", "1c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1c_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1c_01_west"]), + "1c_01_east": PreRegion("1c_01_east", "1c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1c_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "1c_01_east"]), + + "1c_02_west": PreRegion("1c_02_west", "1c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1c_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "1c_02_west"]), + "1c_02_goal": PreRegion("1c_02_goal", "1c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "1c_02_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "1c_02_goal"]), + + "2a_start_main": PreRegion("2a_start_main", "2a_start", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_start_main"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_start_main"]), + "2a_start_top": PreRegion("2a_start_top", "2a_start", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_start_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_start_top"]), + "2a_start_east": PreRegion("2a_start_east", "2a_start", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_start_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_start_east"]), + + "2a_s0_bottom": PreRegion("2a_s0_bottom", "2a_s0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_s0_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_s0_bottom"]), + "2a_s0_top": PreRegion("2a_s0_top", "2a_s0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_s0_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_s0_top"]), + + "2a_s1_bottom": PreRegion("2a_s1_bottom", "2a_s1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_s1_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_s1_bottom"]), + "2a_s1_top": PreRegion("2a_s1_top", "2a_s1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_s1_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_s1_top"]), + + "2a_s2_bottom": PreRegion("2a_s2_bottom", "2a_s2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_s2_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_s2_bottom"]), + + "2a_0_south-west": PreRegion("2a_0_south-west", "2a_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_0_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_0_south-west"]), + "2a_0_south-east": PreRegion("2a_0_south-east", "2a_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_0_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_0_south-east"]), + "2a_0_north-west": PreRegion("2a_0_north-west", "2a_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_0_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_0_north-west"]), + "2a_0_north-east": PreRegion("2a_0_north-east", "2a_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_0_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_0_north-east"]), + + "2a_1_south-west": PreRegion("2a_1_south-west", "2a_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_1_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_1_south-west"]), + "2a_1_south": PreRegion("2a_1_south", "2a_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_1_south"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_1_south"]), + "2a_1_south-east": PreRegion("2a_1_south-east", "2a_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_1_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_1_south-east"]), + "2a_1_north-west": PreRegion("2a_1_north-west", "2a_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_1_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_1_north-west"]), + + "2a_d0_north": PreRegion("2a_d0_north", "2a_d0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d0_north"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d0_north"]), + "2a_d0_north-west": PreRegion("2a_d0_north-west", "2a_d0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d0_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d0_north-west"]), + "2a_d0_west": PreRegion("2a_d0_west", "2a_d0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d0_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d0_west"]), + "2a_d0_south-west": PreRegion("2a_d0_south-west", "2a_d0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d0_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d0_south-west"]), + "2a_d0_south": PreRegion("2a_d0_south", "2a_d0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d0_south"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d0_south"]), + "2a_d0_south-east": PreRegion("2a_d0_south-east", "2a_d0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d0_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d0_south-east"]), + "2a_d0_east": PreRegion("2a_d0_east", "2a_d0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d0_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d0_east"]), + "2a_d0_north-east": PreRegion("2a_d0_north-east", "2a_d0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d0_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d0_north-east"]), + + "2a_d7_west": PreRegion("2a_d7_west", "2a_d7", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d7_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d7_west"]), + "2a_d7_east": PreRegion("2a_d7_east", "2a_d7", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d7_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d7_east"]), + + "2a_d8_west": PreRegion("2a_d8_west", "2a_d8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d8_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d8_west"]), + "2a_d8_south-east": PreRegion("2a_d8_south-east", "2a_d8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d8_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d8_south-east"]), + "2a_d8_north-east": PreRegion("2a_d8_north-east", "2a_d8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d8_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d8_north-east"]), + + "2a_d3_west": PreRegion("2a_d3_west", "2a_d3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d3_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d3_west"]), + "2a_d3_north": PreRegion("2a_d3_north", "2a_d3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d3_north"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d3_north"]), + "2a_d3_south": PreRegion("2a_d3_south", "2a_d3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d3_south"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d3_south"]), + + "2a_d2_west": PreRegion("2a_d2_west", "2a_d2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d2_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d2_west"]), + "2a_d2_north-west": PreRegion("2a_d2_north-west", "2a_d2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d2_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d2_north-west"]), + "2a_d2_east": PreRegion("2a_d2_east", "2a_d2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d2_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d2_east"]), + + "2a_d9_north-west": PreRegion("2a_d9_north-west", "2a_d9", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d9_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d9_north-west"]), + + "2a_d1_south-west": PreRegion("2a_d1_south-west", "2a_d1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d1_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d1_south-west"]), + "2a_d1_south-east": PreRegion("2a_d1_south-east", "2a_d1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d1_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d1_south-east"]), + "2a_d1_north-east": PreRegion("2a_d1_north-east", "2a_d1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d1_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d1_north-east"]), + + "2a_d6_west": PreRegion("2a_d6_west", "2a_d6", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d6_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d6_west"]), + "2a_d6_east": PreRegion("2a_d6_east", "2a_d6", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d6_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d6_east"]), + + "2a_d4_west": PreRegion("2a_d4_west", "2a_d4", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d4_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d4_west"]), + "2a_d4_east": PreRegion("2a_d4_east", "2a_d4", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d4_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d4_east"]), + "2a_d4_south": PreRegion("2a_d4_south", "2a_d4", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d4_south"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d4_south"]), + + "2a_d5_west": PreRegion("2a_d5_west", "2a_d5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_d5_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_d5_west"]), + + "2a_3x_bottom": PreRegion("2a_3x_bottom", "2a_3x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_3x_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_3x_bottom"]), + "2a_3x_top": PreRegion("2a_3x_top", "2a_3x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_3x_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_3x_top"]), + + "2a_3_bottom": PreRegion("2a_3_bottom", "2a_3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_3_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_3_bottom"]), + "2a_3_top": PreRegion("2a_3_top", "2a_3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_3_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_3_top"]), + + "2a_4_bottom": PreRegion("2a_4_bottom", "2a_4", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_4_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_4_bottom"]), + "2a_4_top": PreRegion("2a_4_top", "2a_4", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_4_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_4_top"]), + + "2a_5_bottom": PreRegion("2a_5_bottom", "2a_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_5_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_5_bottom"]), + "2a_5_top": PreRegion("2a_5_top", "2a_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_5_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_5_top"]), + + "2a_6_bottom": PreRegion("2a_6_bottom", "2a_6", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_6_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_6_bottom"]), + "2a_6_top": PreRegion("2a_6_top", "2a_6", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_6_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_6_top"]), + + "2a_7_bottom": PreRegion("2a_7_bottom", "2a_7", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_7_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_7_bottom"]), + "2a_7_top": PreRegion("2a_7_top", "2a_7", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_7_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_7_top"]), + + "2a_8_bottom": PreRegion("2a_8_bottom", "2a_8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_8_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_8_bottom"]), + "2a_8_top": PreRegion("2a_8_top", "2a_8", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_8_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_8_top"]), + + "2a_9_west": PreRegion("2a_9_west", "2a_9", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_9_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_9_west"]), + "2a_9_north": PreRegion("2a_9_north", "2a_9", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_9_north"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_9_north"]), + "2a_9_north-west": PreRegion("2a_9_north-west", "2a_9", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_9_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_9_north-west"]), + "2a_9_south": PreRegion("2a_9_south", "2a_9", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_9_south"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_9_south"]), + "2a_9_south-east": PreRegion("2a_9_south-east", "2a_9", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_9_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_9_south-east"]), + + "2a_9b_east": PreRegion("2a_9b_east", "2a_9b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_9b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_9b_east"]), + "2a_9b_west": PreRegion("2a_9b_west", "2a_9b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_9b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_9b_west"]), + + "2a_10_top": PreRegion("2a_10_top", "2a_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_10_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_10_top"]), + "2a_10_bottom": PreRegion("2a_10_bottom", "2a_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_10_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_10_bottom"]), + + "2a_2_north-west": PreRegion("2a_2_north-west", "2a_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_2_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_2_north-west"]), + "2a_2_south-west": PreRegion("2a_2_south-west", "2a_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_2_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_2_south-west"]), + "2a_2_south-east": PreRegion("2a_2_south-east", "2a_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_2_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_2_south-east"]), + + "2a_11_west": PreRegion("2a_11_west", "2a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_11_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_11_west"]), + "2a_11_east": PreRegion("2a_11_east", "2a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_11_east"]), + + "2a_12b_west": PreRegion("2a_12b_west", "2a_12b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_12b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_12b_west"]), + "2a_12b_north": PreRegion("2a_12b_north", "2a_12b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_12b_north"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_12b_north"]), + "2a_12b_south": PreRegion("2a_12b_south", "2a_12b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_12b_south"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_12b_south"]), + "2a_12b_east": PreRegion("2a_12b_east", "2a_12b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_12b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_12b_east"]), + "2a_12b_south-east": PreRegion("2a_12b_south-east", "2a_12b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_12b_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_12b_south-east"]), + + "2a_12c_south": PreRegion("2a_12c_south", "2a_12c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_12c_south"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_12c_south"]), + + "2a_12d_north-west": PreRegion("2a_12d_north-west", "2a_12d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_12d_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_12d_north-west"]), + "2a_12d_north": PreRegion("2a_12d_north", "2a_12d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_12d_north"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_12d_north"]), + + "2a_12_west": PreRegion("2a_12_west", "2a_12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_12_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_12_west"]), + "2a_12_east": PreRegion("2a_12_east", "2a_12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_12_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_12_east"]), + + "2a_13_west": PreRegion("2a_13_west", "2a_13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_13_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_13_west"]), + "2a_13_phone": PreRegion("2a_13_phone", "2a_13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_13_phone"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_13_phone"]), + + "2a_end_0_main": PreRegion("2a_end_0_main", "2a_end_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_0_main"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_0_main"]), + "2a_end_0_top": PreRegion("2a_end_0_top", "2a_end_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_0_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_0_top"]), + "2a_end_0_east": PreRegion("2a_end_0_east", "2a_end_0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_0_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_0_east"]), + + "2a_end_s0_bottom": PreRegion("2a_end_s0_bottom", "2a_end_s0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_s0_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_s0_bottom"]), + "2a_end_s0_top": PreRegion("2a_end_s0_top", "2a_end_s0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_s0_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_s0_top"]), + + "2a_end_s1_bottom": PreRegion("2a_end_s1_bottom", "2a_end_s1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_s1_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_s1_bottom"]), + + "2a_end_1_west": PreRegion("2a_end_1_west", "2a_end_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_1_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_1_west"]), + "2a_end_1_north-east": PreRegion("2a_end_1_north-east", "2a_end_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_1_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_1_north-east"]), + "2a_end_1_east": PreRegion("2a_end_1_east", "2a_end_1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_1_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_1_east"]), + + "2a_end_2_north-west": PreRegion("2a_end_2_north-west", "2a_end_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_2_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_2_north-west"]), + "2a_end_2_west": PreRegion("2a_end_2_west", "2a_end_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_2_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_2_west"]), + "2a_end_2_north-east": PreRegion("2a_end_2_north-east", "2a_end_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_2_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_2_north-east"]), + "2a_end_2_east": PreRegion("2a_end_2_east", "2a_end_2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_2_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_2_east"]), + + "2a_end_3_north-west": PreRegion("2a_end_3_north-west", "2a_end_3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_3_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_3_north-west"]), + "2a_end_3_west": PreRegion("2a_end_3_west", "2a_end_3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_3_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_3_west"]), + "2a_end_3_east": PreRegion("2a_end_3_east", "2a_end_3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_3_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_3_east"]), + + "2a_end_4_west": PreRegion("2a_end_4_west", "2a_end_4", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_4_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_4_west"]), + "2a_end_4_east": PreRegion("2a_end_4_east", "2a_end_4", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_4_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_4_east"]), + + "2a_end_3b_west": PreRegion("2a_end_3b_west", "2a_end_3b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_3b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_3b_west"]), + "2a_end_3b_north": PreRegion("2a_end_3b_north", "2a_end_3b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_3b_north"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_3b_north"]), + "2a_end_3b_east": PreRegion("2a_end_3b_east", "2a_end_3b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_3b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_3b_east"]), + + "2a_end_3cb_bottom": PreRegion("2a_end_3cb_bottom", "2a_end_3cb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_3cb_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_3cb_bottom"]), + "2a_end_3cb_top": PreRegion("2a_end_3cb_top", "2a_end_3cb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_3cb_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_3cb_top"]), + + "2a_end_3c_bottom": PreRegion("2a_end_3c_bottom", "2a_end_3c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_3c_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_3c_bottom"]), + + "2a_end_5_west": PreRegion("2a_end_5_west", "2a_end_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_5_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_5_west"]), + "2a_end_5_east": PreRegion("2a_end_5_east", "2a_end_5", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_5_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_5_east"]), + + "2a_end_6_west": PreRegion("2a_end_6_west", "2a_end_6", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_6_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_6_west"]), + "2a_end_6_main": PreRegion("2a_end_6_main", "2a_end_6", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2a_end_6_main"], [loc for _, loc in all_locations.items() if loc.region_name == "2a_end_6_main"]), + + "2b_start_west": PreRegion("2b_start_west", "2b_start", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_start_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_start_west"]), + "2b_start_east": PreRegion("2b_start_east", "2b_start", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_start_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_start_east"]), + + "2b_00_west": PreRegion("2b_00_west", "2b_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_00_west"]), + "2b_00_east": PreRegion("2b_00_east", "2b_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_00_east"]), + + "2b_01_west": PreRegion("2b_01_west", "2b_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_01_west"]), + "2b_01_east": PreRegion("2b_01_east", "2b_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_01_east"]), + + "2b_01b_west": PreRegion("2b_01b_west", "2b_01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_01b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_01b_west"]), + "2b_01b_east": PreRegion("2b_01b_east", "2b_01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_01b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_01b_east"]), + + "2b_02b_west": PreRegion("2b_02b_west", "2b_02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_02b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_02b_west"]), + "2b_02b_east": PreRegion("2b_02b_east", "2b_02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_02b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_02b_east"]), + + "2b_02_west": PreRegion("2b_02_west", "2b_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_02_west"]), + "2b_02_east": PreRegion("2b_02_east", "2b_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_02_east"]), + + "2b_03_west": PreRegion("2b_03_west", "2b_03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_03_west"]), + "2b_03_east": PreRegion("2b_03_east", "2b_03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_03_east"]), + + "2b_04_bottom": PreRegion("2b_04_bottom", "2b_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_04_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_04_bottom"]), + "2b_04_top": PreRegion("2b_04_top", "2b_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_04_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_04_top"]), + + "2b_05_bottom": PreRegion("2b_05_bottom", "2b_05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_05_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_05_bottom"]), + "2b_05_top": PreRegion("2b_05_top", "2b_05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_05_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_05_top"]), + + "2b_06_west": PreRegion("2b_06_west", "2b_06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_06_west"]), + "2b_06_east": PreRegion("2b_06_east", "2b_06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_06_east"]), + + "2b_07_bottom": PreRegion("2b_07_bottom", "2b_07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_07_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_07_bottom"]), + "2b_07_top": PreRegion("2b_07_top", "2b_07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_07_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_07_top"]), + + "2b_08b_west": PreRegion("2b_08b_west", "2b_08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_08b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_08b_west"]), + "2b_08b_east": PreRegion("2b_08b_east", "2b_08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_08b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_08b_east"]), + + "2b_08_west": PreRegion("2b_08_west", "2b_08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_08_west"]), + "2b_08_east": PreRegion("2b_08_east", "2b_08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_08_east"]), + + "2b_09_west": PreRegion("2b_09_west", "2b_09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_09_west"]), + "2b_09_east": PreRegion("2b_09_east", "2b_09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_09_east"]), + + "2b_10_west": PreRegion("2b_10_west", "2b_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_10_west"]), + "2b_10_east": PreRegion("2b_10_east", "2b_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_10_east"]), + + "2b_11_bottom": PreRegion("2b_11_bottom", "2b_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_11_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_11_bottom"]), + "2b_11_top": PreRegion("2b_11_top", "2b_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_11_top"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_11_top"]), + + "2b_end_west": PreRegion("2b_end_west", "2b_end", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_end_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_end_west"]), + "2b_end_goal": PreRegion("2b_end_goal", "2b_end", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2b_end_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "2b_end_goal"]), + + "2c_00_west": PreRegion("2c_00_west", "2c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2c_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2c_00_west"]), + "2c_00_east": PreRegion("2c_00_east", "2c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2c_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2c_00_east"]), + + "2c_01_west": PreRegion("2c_01_west", "2c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2c_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2c_01_west"]), + "2c_01_east": PreRegion("2c_01_east", "2c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2c_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "2c_01_east"]), + + "2c_02_west": PreRegion("2c_02_west", "2c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2c_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "2c_02_west"]), + "2c_02_goal": PreRegion("2c_02_goal", "2c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "2c_02_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "2c_02_goal"]), + + "3a_s0_main": PreRegion("3a_s0_main", "3a_s0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s0_main"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s0_main"]), + "3a_s0_east": PreRegion("3a_s0_east", "3a_s0", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s0_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s0_east"]), + + "3a_s1_west": PreRegion("3a_s1_west", "3a_s1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s1_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s1_west"]), + "3a_s1_east": PreRegion("3a_s1_east", "3a_s1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s1_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s1_east"]), + "3a_s1_north-east": PreRegion("3a_s1_north-east", "3a_s1", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s1_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s1_north-east"]), + + "3a_s2_west": PreRegion("3a_s2_west", "3a_s2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s2_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s2_west"]), + "3a_s2_north-west": PreRegion("3a_s2_north-west", "3a_s2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s2_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s2_north-west"]), + "3a_s2_east": PreRegion("3a_s2_east", "3a_s2", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s2_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s2_east"]), + + "3a_s3_west": PreRegion("3a_s3_west", "3a_s3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s3_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s3_west"]), + "3a_s3_north": PreRegion("3a_s3_north", "3a_s3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s3_north"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s3_north"]), + "3a_s3_east": PreRegion("3a_s3_east", "3a_s3", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_s3_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_s3_east"]), + + "3a_0x-a_west": PreRegion("3a_0x-a_west", "3a_0x-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_0x-a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_0x-a_west"]), + "3a_0x-a_east": PreRegion("3a_0x-a_east", "3a_0x-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_0x-a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_0x-a_east"]), + + "3a_00-a_west": PreRegion("3a_00-a_west", "3a_00-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-a_west"]), + "3a_00-a_east": PreRegion("3a_00-a_east", "3a_00-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-a_east"]), + + "3a_02-a_west": PreRegion("3a_02-a_west", "3a_02-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-a_west"]), + "3a_02-a_top": PreRegion("3a_02-a_top", "3a_02-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-a_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-a_top"]), + "3a_02-a_main": PreRegion("3a_02-a_main", "3a_02-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-a_main"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-a_main"]), + "3a_02-a_east": PreRegion("3a_02-a_east", "3a_02-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-a_east"]), + + "3a_02-b_west": PreRegion("3a_02-b_west", "3a_02-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-b_west"]), + "3a_02-b_east": PreRegion("3a_02-b_east", "3a_02-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-b_east"]), + "3a_02-b_far-east": PreRegion("3a_02-b_far-east", "3a_02-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-b_far-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-b_far-east"]), + + "3a_01-b_west": PreRegion("3a_01-b_west", "3a_01-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_01-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_01-b_west"]), + "3a_01-b_north-west": PreRegion("3a_01-b_north-west", "3a_01-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_01-b_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_01-b_north-west"]), + "3a_01-b_east": PreRegion("3a_01-b_east", "3a_01-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_01-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_01-b_east"]), + + "3a_00-b_south-west": PreRegion("3a_00-b_south-west", "3a_00-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-b_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-b_south-west"]), + "3a_00-b_south-east": PreRegion("3a_00-b_south-east", "3a_00-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-b_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-b_south-east"]), + "3a_00-b_west": PreRegion("3a_00-b_west", "3a_00-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-b_west"]), + "3a_00-b_north-west": PreRegion("3a_00-b_north-west", "3a_00-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-b_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-b_north-west"]), + "3a_00-b_east": PreRegion("3a_00-b_east", "3a_00-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-b_east"]), + "3a_00-b_north": PreRegion("3a_00-b_north", "3a_00-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-b_north"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-b_north"]), + + "3a_00-c_south-west": PreRegion("3a_00-c_south-west", "3a_00-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-c_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-c_south-west"]), + "3a_00-c_south-east": PreRegion("3a_00-c_south-east", "3a_00-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-c_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-c_south-east"]), + "3a_00-c_north-east": PreRegion("3a_00-c_north-east", "3a_00-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-c_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-c_north-east"]), + + "3a_0x-b_west": PreRegion("3a_0x-b_west", "3a_0x-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_0x-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_0x-b_west"]), + "3a_0x-b_south-east": PreRegion("3a_0x-b_south-east", "3a_0x-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_0x-b_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_0x-b_south-east"]), + "3a_0x-b_north-east": PreRegion("3a_0x-b_north-east", "3a_0x-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_0x-b_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_0x-b_north-east"]), + + "3a_03-a_west": PreRegion("3a_03-a_west", "3a_03-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_03-a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_03-a_west"]), + "3a_03-a_top": PreRegion("3a_03-a_top", "3a_03-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_03-a_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_03-a_top"]), + "3a_03-a_east": PreRegion("3a_03-a_east", "3a_03-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_03-a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_03-a_east"]), + + "3a_04-b_west": PreRegion("3a_04-b_west", "3a_04-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_04-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_04-b_west"]), + "3a_04-b_east": PreRegion("3a_04-b_east", "3a_04-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_04-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_04-b_east"]), + + "3a_05-a_west": PreRegion("3a_05-a_west", "3a_05-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_05-a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_05-a_west"]), + "3a_05-a_east": PreRegion("3a_05-a_east", "3a_05-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_05-a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_05-a_east"]), + + "3a_06-a_west": PreRegion("3a_06-a_west", "3a_06-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_06-a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_06-a_west"]), + "3a_06-a_east": PreRegion("3a_06-a_east", "3a_06-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_06-a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_06-a_east"]), + + "3a_07-a_west": PreRegion("3a_07-a_west", "3a_07-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_07-a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_07-a_west"]), + "3a_07-a_top": PreRegion("3a_07-a_top", "3a_07-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_07-a_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_07-a_top"]), + "3a_07-a_east": PreRegion("3a_07-a_east", "3a_07-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_07-a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_07-a_east"]), + + "3a_07-b_bottom": PreRegion("3a_07-b_bottom", "3a_07-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_07-b_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_07-b_bottom"]), + "3a_07-b_west": PreRegion("3a_07-b_west", "3a_07-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_07-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_07-b_west"]), + "3a_07-b_top": PreRegion("3a_07-b_top", "3a_07-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_07-b_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_07-b_top"]), + "3a_07-b_east": PreRegion("3a_07-b_east", "3a_07-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_07-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_07-b_east"]), + + "3a_06-b_west": PreRegion("3a_06-b_west", "3a_06-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_06-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_06-b_west"]), + "3a_06-b_east": PreRegion("3a_06-b_east", "3a_06-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_06-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_06-b_east"]), + + "3a_06-c_south-west": PreRegion("3a_06-c_south-west", "3a_06-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_06-c_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_06-c_south-west"]), + "3a_06-c_north-west": PreRegion("3a_06-c_north-west", "3a_06-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_06-c_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_06-c_north-west"]), + "3a_06-c_south-east": PreRegion("3a_06-c_south-east", "3a_06-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_06-c_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_06-c_south-east"]), + "3a_06-c_east": PreRegion("3a_06-c_east", "3a_06-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_06-c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_06-c_east"]), + + "3a_05-c_east": PreRegion("3a_05-c_east", "3a_05-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_05-c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_05-c_east"]), + + "3a_08-c_west": PreRegion("3a_08-c_west", "3a_08-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-c_west"]), + "3a_08-c_east": PreRegion("3a_08-c_east", "3a_08-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-c_east"]), + + "3a_08-b_west": PreRegion("3a_08-b_west", "3a_08-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-b_west"]), + "3a_08-b_east": PreRegion("3a_08-b_east", "3a_08-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-b_east"]), + + "3a_08-a_west": PreRegion("3a_08-a_west", "3a_08-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-a_west"]), + "3a_08-a_bottom": PreRegion("3a_08-a_bottom", "3a_08-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-a_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-a_bottom"]), + "3a_08-a_east": PreRegion("3a_08-a_east", "3a_08-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-a_east"]), + + "3a_09-b_west": PreRegion("3a_09-b_west", "3a_09-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-b_west"]), + "3a_09-b_north-west": PreRegion("3a_09-b_north-west", "3a_09-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-b_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-b_north-west"]), + "3a_09-b_center": PreRegion("3a_09-b_center", "3a_09-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-b_center"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-b_center"]), + "3a_09-b_south-west": PreRegion("3a_09-b_south-west", "3a_09-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-b_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-b_south-west"]), + "3a_09-b_south": PreRegion("3a_09-b_south", "3a_09-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-b_south"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-b_south"]), + "3a_09-b_south-east": PreRegion("3a_09-b_south-east", "3a_09-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-b_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-b_south-east"]), + "3a_09-b_east": PreRegion("3a_09-b_east", "3a_09-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-b_east"]), + "3a_09-b_north-east-right": PreRegion("3a_09-b_north-east-right", "3a_09-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-b_north-east-right"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-b_north-east-right"]), + "3a_09-b_north-east-top": PreRegion("3a_09-b_north-east-top", "3a_09-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-b_north-east-top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-b_north-east-top"]), + "3a_09-b_north": PreRegion("3a_09-b_north", "3a_09-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-b_north"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-b_north"]), + + "3a_10-x_west": PreRegion("3a_10-x_west", "3a_10-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-x_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-x_west"]), + "3a_10-x_south-east": PreRegion("3a_10-x_south-east", "3a_10-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-x_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-x_south-east"]), + "3a_10-x_north-east-top": PreRegion("3a_10-x_north-east-top", "3a_10-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-x_north-east-top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-x_north-east-top"]), + "3a_10-x_north-east-right": PreRegion("3a_10-x_north-east-right", "3a_10-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-x_north-east-right"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-x_north-east-right"]), + + "3a_11-x_west": PreRegion("3a_11-x_west", "3a_11-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-x_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-x_west"]), + "3a_11-x_south": PreRegion("3a_11-x_south", "3a_11-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-x_south"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-x_south"]), + + "3a_11-y_west": PreRegion("3a_11-y_west", "3a_11-y", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-y_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-y_west"]), + "3a_11-y_east": PreRegion("3a_11-y_east", "3a_11-y", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-y_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-y_east"]), + "3a_11-y_south": PreRegion("3a_11-y_south", "3a_11-y", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-y_south"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-y_south"]), + + "3a_12-y_west": PreRegion("3a_12-y_west", "3a_12-y", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_12-y_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_12-y_west"]), + + "3a_11-z_west": PreRegion("3a_11-z_west", "3a_11-z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-z_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-z_west"]), + "3a_11-z_east": PreRegion("3a_11-z_east", "3a_11-z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-z_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-z_east"]), + + "3a_10-z_bottom": PreRegion("3a_10-z_bottom", "3a_10-z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-z_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-z_bottom"]), + "3a_10-z_top": PreRegion("3a_10-z_top", "3a_10-z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-z_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-z_top"]), + + "3a_10-y_bottom": PreRegion("3a_10-y_bottom", "3a_10-y", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-y_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-y_bottom"]), + "3a_10-y_top": PreRegion("3a_10-y_top", "3a_10-y", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-y_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-y_top"]), + + "3a_10-c_south-east": PreRegion("3a_10-c_south-east", "3a_10-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-c_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-c_south-east"]), + "3a_10-c_north-east": PreRegion("3a_10-c_north-east", "3a_10-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-c_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-c_north-east"]), + "3a_10-c_north-west": PreRegion("3a_10-c_north-west", "3a_10-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-c_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-c_north-west"]), + "3a_10-c_south-west": PreRegion("3a_10-c_south-west", "3a_10-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-c_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-c_south-west"]), + + "3a_11-c_west": PreRegion("3a_11-c_west", "3a_11-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-c_west"]), + "3a_11-c_east": PreRegion("3a_11-c_east", "3a_11-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-c_east"]), + "3a_11-c_south-east": PreRegion("3a_11-c_south-east", "3a_11-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-c_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-c_south-east"]), + "3a_11-c_south-west": PreRegion("3a_11-c_south-west", "3a_11-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-c_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-c_south-west"]), + + "3a_12-c_west": PreRegion("3a_12-c_west", "3a_12-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_12-c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_12-c_west"]), + "3a_12-c_top": PreRegion("3a_12-c_top", "3a_12-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_12-c_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_12-c_top"]), + + "3a_12-d_bottom": PreRegion("3a_12-d_bottom", "3a_12-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_12-d_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_12-d_bottom"]), + "3a_12-d_top": PreRegion("3a_12-d_top", "3a_12-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_12-d_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_12-d_top"]), + + "3a_11-d_west": PreRegion("3a_11-d_west", "3a_11-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-d_west"]), + "3a_11-d_east": PreRegion("3a_11-d_east", "3a_11-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-d_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-d_east"]), + + "3a_10-d_west": PreRegion("3a_10-d_west", "3a_10-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-d_west"]), + "3a_10-d_main": PreRegion("3a_10-d_main", "3a_10-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-d_main"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-d_main"]), + "3a_10-d_east": PreRegion("3a_10-d_east", "3a_10-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_10-d_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_10-d_east"]), + + "3a_11-b_west": PreRegion("3a_11-b_west", "3a_11-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-b_west"]), + "3a_11-b_north-west": PreRegion("3a_11-b_north-west", "3a_11-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-b_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-b_north-west"]), + "3a_11-b_east": PreRegion("3a_11-b_east", "3a_11-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-b_east"]), + "3a_11-b_north-east": PreRegion("3a_11-b_north-east", "3a_11-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-b_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-b_north-east"]), + + "3a_12-b_west": PreRegion("3a_12-b_west", "3a_12-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_12-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_12-b_west"]), + "3a_12-b_east": PreRegion("3a_12-b_east", "3a_12-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_12-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_12-b_east"]), + + "3a_13-b_top": PreRegion("3a_13-b_top", "3a_13-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_13-b_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_13-b_top"]), + "3a_13-b_bottom": PreRegion("3a_13-b_bottom", "3a_13-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_13-b_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_13-b_bottom"]), + + "3a_13-a_west": PreRegion("3a_13-a_west", "3a_13-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_13-a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_13-a_west"]), + "3a_13-a_south-west": PreRegion("3a_13-a_south-west", "3a_13-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_13-a_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_13-a_south-west"]), + "3a_13-a_east": PreRegion("3a_13-a_east", "3a_13-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_13-a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_13-a_east"]), + + "3a_13-x_west": PreRegion("3a_13-x_west", "3a_13-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_13-x_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_13-x_west"]), + "3a_13-x_east": PreRegion("3a_13-x_east", "3a_13-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_13-x_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_13-x_east"]), + + "3a_12-x_west": PreRegion("3a_12-x_west", "3a_12-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_12-x_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_12-x_west"]), + "3a_12-x_north-east": PreRegion("3a_12-x_north-east", "3a_12-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_12-x_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_12-x_north-east"]), + "3a_12-x_east": PreRegion("3a_12-x_east", "3a_12-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_12-x_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_12-x_east"]), + + "3a_11-a_west": PreRegion("3a_11-a_west", "3a_11-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-a_west"]), + "3a_11-a_south": PreRegion("3a_11-a_south", "3a_11-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-a_south"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-a_south"]), + "3a_11-a_south-east-bottom": PreRegion("3a_11-a_south-east-bottom", "3a_11-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-a_south-east-bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-a_south-east-bottom"]), + "3a_11-a_south-east-right": PreRegion("3a_11-a_south-east-right", "3a_11-a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_11-a_south-east-right"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_11-a_south-east-right"]), + + "3a_08-x_west": PreRegion("3a_08-x_west", "3a_08-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-x_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-x_west"]), + "3a_08-x_east": PreRegion("3a_08-x_east", "3a_08-x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-x_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-x_east"]), + + "3a_09-d_bottom": PreRegion("3a_09-d_bottom", "3a_09-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-d_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-d_bottom"]), + "3a_09-d_top": PreRegion("3a_09-d_top", "3a_09-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_09-d_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_09-d_top"]), + + "3a_08-d_west": PreRegion("3a_08-d_west", "3a_08-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-d_west"]), + "3a_08-d_east": PreRegion("3a_08-d_east", "3a_08-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_08-d_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_08-d_east"]), + + "3a_06-d_west": PreRegion("3a_06-d_west", "3a_06-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_06-d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_06-d_west"]), + "3a_06-d_east": PreRegion("3a_06-d_east", "3a_06-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_06-d_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_06-d_east"]), + + "3a_04-d_west": PreRegion("3a_04-d_west", "3a_04-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_04-d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_04-d_west"]), + "3a_04-d_south-west": PreRegion("3a_04-d_south-west", "3a_04-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_04-d_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_04-d_south-west"]), + "3a_04-d_south": PreRegion("3a_04-d_south", "3a_04-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_04-d_south"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_04-d_south"]), + "3a_04-d_east": PreRegion("3a_04-d_east", "3a_04-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_04-d_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_04-d_east"]), + + "3a_04-c_west": PreRegion("3a_04-c_west", "3a_04-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_04-c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_04-c_west"]), + "3a_04-c_north-west": PreRegion("3a_04-c_north-west", "3a_04-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_04-c_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_04-c_north-west"]), + "3a_04-c_east": PreRegion("3a_04-c_east", "3a_04-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_04-c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_04-c_east"]), + + "3a_02-c_west": PreRegion("3a_02-c_west", "3a_02-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-c_west"]), + "3a_02-c_east": PreRegion("3a_02-c_east", "3a_02-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-c_east"]), + "3a_02-c_south-east": PreRegion("3a_02-c_south-east", "3a_02-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-c_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-c_south-east"]), + + "3a_03-b_west": PreRegion("3a_03-b_west", "3a_03-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_03-b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_03-b_west"]), + "3a_03-b_east": PreRegion("3a_03-b_east", "3a_03-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_03-b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_03-b_east"]), + "3a_03-b_north": PreRegion("3a_03-b_north", "3a_03-b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_03-b_north"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_03-b_north"]), + + "3a_01-c_west": PreRegion("3a_01-c_west", "3a_01-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_01-c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_01-c_west"]), + "3a_01-c_east": PreRegion("3a_01-c_east", "3a_01-c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_01-c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_01-c_east"]), + + "3a_02-d_west": PreRegion("3a_02-d_west", "3a_02-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-d_west"]), + "3a_02-d_east": PreRegion("3a_02-d_east", "3a_02-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_02-d_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_02-d_east"]), + + "3a_00-d_west": PreRegion("3a_00-d_west", "3a_00-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-d_west"]), + "3a_00-d_east": PreRegion("3a_00-d_east", "3a_00-d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_00-d_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_00-d_east"]), + + "3a_roof00_west": PreRegion("3a_roof00_west", "3a_roof00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof00_west"]), + "3a_roof00_east": PreRegion("3a_roof00_east", "3a_roof00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof00_east"]), + + "3a_roof01_west": PreRegion("3a_roof01_west", "3a_roof01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof01_west"]), + "3a_roof01_east": PreRegion("3a_roof01_east", "3a_roof01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof01_east"]), + + "3a_roof02_west": PreRegion("3a_roof02_west", "3a_roof02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof02_west"]), + "3a_roof02_east": PreRegion("3a_roof02_east", "3a_roof02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof02_east"]), + + "3a_roof03_west": PreRegion("3a_roof03_west", "3a_roof03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof03_west"]), + "3a_roof03_east": PreRegion("3a_roof03_east", "3a_roof03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof03_east"]), + + "3a_roof04_west": PreRegion("3a_roof04_west", "3a_roof04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof04_west"]), + "3a_roof04_east": PreRegion("3a_roof04_east", "3a_roof04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof04_east"]), + + "3a_roof05_west": PreRegion("3a_roof05_west", "3a_roof05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof05_west"]), + "3a_roof05_east": PreRegion("3a_roof05_east", "3a_roof05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof05_east"]), + + "3a_roof06b_west": PreRegion("3a_roof06b_west", "3a_roof06b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof06b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof06b_west"]), + "3a_roof06b_east": PreRegion("3a_roof06b_east", "3a_roof06b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof06b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof06b_east"]), + + "3a_roof06_west": PreRegion("3a_roof06_west", "3a_roof06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof06_west"]), + "3a_roof06_east": PreRegion("3a_roof06_east", "3a_roof06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof06_east"]), + + "3a_roof07_west": PreRegion("3a_roof07_west", "3a_roof07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof07_west"]), + "3a_roof07_main": PreRegion("3a_roof07_main", "3a_roof07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3a_roof07_main"], [loc for _, loc in all_locations.items() if loc.region_name == "3a_roof07_main"]), + + "3b_00_west": PreRegion("3b_00_west", "3b_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_00_west"]), + "3b_00_east": PreRegion("3b_00_east", "3b_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_00_east"]), + + "3b_back_east": PreRegion("3b_back_east", "3b_back", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_back_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_back_east"]), + + "3b_01_west": PreRegion("3b_01_west", "3b_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_01_west"]), + "3b_01_east": PreRegion("3b_01_east", "3b_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_01_east"]), + + "3b_02_west": PreRegion("3b_02_west", "3b_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_02_west"]), + "3b_02_east": PreRegion("3b_02_east", "3b_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_02_east"]), + + "3b_03_west": PreRegion("3b_03_west", "3b_03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_03_west"]), + "3b_03_east": PreRegion("3b_03_east", "3b_03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_03_east"]), + + "3b_04_west": PreRegion("3b_04_west", "3b_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_04_west"]), + "3b_04_east": PreRegion("3b_04_east", "3b_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_04_east"]), + + "3b_05_west": PreRegion("3b_05_west", "3b_05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_05_west"]), + "3b_05_east": PreRegion("3b_05_east", "3b_05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_05_east"]), + + "3b_06_west": PreRegion("3b_06_west", "3b_06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_06_west"]), + "3b_06_east": PreRegion("3b_06_east", "3b_06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_06_east"]), + + "3b_07_west": PreRegion("3b_07_west", "3b_07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_07_west"]), + "3b_07_east": PreRegion("3b_07_east", "3b_07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_07_east"]), + + "3b_08_bottom": PreRegion("3b_08_bottom", "3b_08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_08_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_08_bottom"]), + "3b_08_top": PreRegion("3b_08_top", "3b_08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_08_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_08_top"]), + + "3b_09_west": PreRegion("3b_09_west", "3b_09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_09_west"]), + "3b_09_east": PreRegion("3b_09_east", "3b_09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_09_east"]), + + "3b_10_west": PreRegion("3b_10_west", "3b_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_10_west"]), + "3b_10_east": PreRegion("3b_10_east", "3b_10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_10_east"]), + + "3b_11_west": PreRegion("3b_11_west", "3b_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_11_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_11_west"]), + "3b_11_east": PreRegion("3b_11_east", "3b_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_11_east"]), + + "3b_13_west": PreRegion("3b_13_west", "3b_13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_13_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_13_west"]), + "3b_13_east": PreRegion("3b_13_east", "3b_13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_13_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_13_east"]), + + "3b_14_west": PreRegion("3b_14_west", "3b_14", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_14_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_14_west"]), + "3b_14_east": PreRegion("3b_14_east", "3b_14", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_14_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_14_east"]), + + "3b_15_west": PreRegion("3b_15_west", "3b_15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_15_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_15_west"]), + "3b_15_east": PreRegion("3b_15_east", "3b_15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_15_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_15_east"]), + + "3b_12_west": PreRegion("3b_12_west", "3b_12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_12_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_12_west"]), + "3b_12_east": PreRegion("3b_12_east", "3b_12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_12_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_12_east"]), + + "3b_16_west": PreRegion("3b_16_west", "3b_16", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_16_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_16_west"]), + "3b_16_top": PreRegion("3b_16_top", "3b_16", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_16_top"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_16_top"]), + + "3b_17_west": PreRegion("3b_17_west", "3b_17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_17_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_17_west"]), + "3b_17_east": PreRegion("3b_17_east", "3b_17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_17_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_17_east"]), + + "3b_18_west": PreRegion("3b_18_west", "3b_18", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_18_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_18_west"]), + "3b_18_east": PreRegion("3b_18_east", "3b_18", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_18_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_18_east"]), + + "3b_19_west": PreRegion("3b_19_west", "3b_19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_19_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_19_west"]), + "3b_19_east": PreRegion("3b_19_east", "3b_19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_19_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_19_east"]), + + "3b_21_west": PreRegion("3b_21_west", "3b_21", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_21_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_21_west"]), + "3b_21_east": PreRegion("3b_21_east", "3b_21", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_21_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_21_east"]), + + "3b_20_west": PreRegion("3b_20_west", "3b_20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_20_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_20_west"]), + "3b_20_east": PreRegion("3b_20_east", "3b_20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_20_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_20_east"]), + + "3b_end_west": PreRegion("3b_end_west", "3b_end", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_end_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_end_west"]), + "3b_end_goal": PreRegion("3b_end_goal", "3b_end", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3b_end_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "3b_end_goal"]), + + "3c_00_west": PreRegion("3c_00_west", "3c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3c_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3c_00_west"]), + "3c_00_east": PreRegion("3c_00_east", "3c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3c_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3c_00_east"]), + + "3c_01_west": PreRegion("3c_01_west", "3c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3c_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3c_01_west"]), + "3c_01_east": PreRegion("3c_01_east", "3c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3c_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "3c_01_east"]), + + "3c_02_west": PreRegion("3c_02_west", "3c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3c_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "3c_02_west"]), + "3c_02_goal": PreRegion("3c_02_goal", "3c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "3c_02_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "3c_02_goal"]), + + "4a_a-00_west": PreRegion("4a_a-00_west", "4a_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-00_west"]), + "4a_a-00_east": PreRegion("4a_a-00_east", "4a_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-00_east"]), + + "4a_a-01_west": PreRegion("4a_a-01_west", "4a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-01_west"]), + "4a_a-01_east": PreRegion("4a_a-01_east", "4a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-01_east"]), + + "4a_a-01x_west": PreRegion("4a_a-01x_west", "4a_a-01x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-01x_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-01x_west"]), + "4a_a-01x_east": PreRegion("4a_a-01x_east", "4a_a-01x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-01x_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-01x_east"]), + + "4a_a-02_west": PreRegion("4a_a-02_west", "4a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-02_west"]), + "4a_a-02_east": PreRegion("4a_a-02_east", "4a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-02_east"]), + + "4a_a-03_west": PreRegion("4a_a-03_west", "4a_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-03_west"]), + "4a_a-03_east": PreRegion("4a_a-03_east", "4a_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-03_east"]), + + "4a_a-04_west": PreRegion("4a_a-04_west", "4a_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-04_west"]), + "4a_a-04_east": PreRegion("4a_a-04_east", "4a_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-04_east"]), + + "4a_a-05_west": PreRegion("4a_a-05_west", "4a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-05_west"]), + "4a_a-05_east": PreRegion("4a_a-05_east", "4a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-05_east"]), + + "4a_a-06_west": PreRegion("4a_a-06_west", "4a_a-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-06_west"]), + "4a_a-06_east": PreRegion("4a_a-06_east", "4a_a-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-06_east"]), + + "4a_a-07_west": PreRegion("4a_a-07_west", "4a_a-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-07_west"]), + "4a_a-07_east": PreRegion("4a_a-07_east", "4a_a-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-07_east"]), + + "4a_a-08_west": PreRegion("4a_a-08_west", "4a_a-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-08_west"]), + "4a_a-08_north-west": PreRegion("4a_a-08_north-west", "4a_a-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-08_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-08_north-west"]), + "4a_a-08_east": PreRegion("4a_a-08_east", "4a_a-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-08_east"]), + + "4a_a-10_west": PreRegion("4a_a-10_west", "4a_a-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-10_west"]), + "4a_a-10_east": PreRegion("4a_a-10_east", "4a_a-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-10_east"]), + + "4a_a-11_east": PreRegion("4a_a-11_east", "4a_a-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-11_east"]), + + "4a_a-09_bottom": PreRegion("4a_a-09_bottom", "4a_a-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-09_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-09_bottom"]), + "4a_a-09_top": PreRegion("4a_a-09_top", "4a_a-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_a-09_top"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_a-09_top"]), + + "4a_b-00_south": PreRegion("4a_b-00_south", "4a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-00_south"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-00_south"]), + "4a_b-00_south-east": PreRegion("4a_b-00_south-east", "4a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-00_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-00_south-east"]), + "4a_b-00_east": PreRegion("4a_b-00_east", "4a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-00_east"]), + "4a_b-00_west": PreRegion("4a_b-00_west", "4a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-00_west"]), + "4a_b-00_north-east": PreRegion("4a_b-00_north-east", "4a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-00_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-00_north-east"]), + "4a_b-00_north-west": PreRegion("4a_b-00_north-west", "4a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-00_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-00_north-west"]), + "4a_b-00_north": PreRegion("4a_b-00_north", "4a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-00_north"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-00_north"]), + + "4a_b-01_west": PreRegion("4a_b-01_west", "4a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-01_west"]), + + "4a_b-04_west": PreRegion("4a_b-04_west", "4a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-04_west"]), + "4a_b-04_north-west": PreRegion("4a_b-04_north-west", "4a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-04_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-04_north-west"]), + "4a_b-04_east": PreRegion("4a_b-04_east", "4a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-04_east"]), + + "4a_b-06_west": PreRegion("4a_b-06_west", "4a_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-06_west"]), + "4a_b-06_east": PreRegion("4a_b-06_east", "4a_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-06_east"]), + + "4a_b-07_west": PreRegion("4a_b-07_west", "4a_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-07_west"]), + "4a_b-07_east": PreRegion("4a_b-07_east", "4a_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-07_east"]), + + "4a_b-03_west": PreRegion("4a_b-03_west", "4a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-03_west"]), + "4a_b-03_east": PreRegion("4a_b-03_east", "4a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-03_east"]), + + "4a_b-02_south-west": PreRegion("4a_b-02_south-west", "4a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-02_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-02_south-west"]), + "4a_b-02_north-west": PreRegion("4a_b-02_north-west", "4a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-02_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-02_north-west"]), + "4a_b-02_north-east": PreRegion("4a_b-02_north-east", "4a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-02_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-02_north-east"]), + "4a_b-02_north": PreRegion("4a_b-02_north", "4a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-02_north"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-02_north"]), + + "4a_b-sec_west": PreRegion("4a_b-sec_west", "4a_b-sec", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-sec_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-sec_west"]), + "4a_b-sec_east": PreRegion("4a_b-sec_east", "4a_b-sec", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-sec_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-sec_east"]), + + "4a_b-secb_west": PreRegion("4a_b-secb_west", "4a_b-secb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-secb_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-secb_west"]), + + "4a_b-05_center": PreRegion("4a_b-05_center", "4a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-05_center"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-05_center"]), + "4a_b-05_west": PreRegion("4a_b-05_west", "4a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-05_west"]), + "4a_b-05_north-east": PreRegion("4a_b-05_north-east", "4a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-05_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-05_north-east"]), + "4a_b-05_east": PreRegion("4a_b-05_east", "4a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-05_east"]), + + "4a_b-08b_west": PreRegion("4a_b-08b_west", "4a_b-08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-08b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-08b_west"]), + "4a_b-08b_east": PreRegion("4a_b-08b_east", "4a_b-08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-08b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-08b_east"]), + + "4a_b-08_west": PreRegion("4a_b-08_west", "4a_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-08_west"]), + "4a_b-08_east": PreRegion("4a_b-08_east", "4a_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_b-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_b-08_east"]), + + "4a_c-00_west": PreRegion("4a_c-00_west", "4a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-00_west"]), + "4a_c-00_east": PreRegion("4a_c-00_east", "4a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-00_east"]), + "4a_c-00_north-west": PreRegion("4a_c-00_north-west", "4a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-00_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-00_north-west"]), + + "4a_c-01_east": PreRegion("4a_c-01_east", "4a_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-01_east"]), + + "4a_c-02_west": PreRegion("4a_c-02_west", "4a_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-02_west"]), + "4a_c-02_east": PreRegion("4a_c-02_east", "4a_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-02_east"]), + + "4a_c-04_west": PreRegion("4a_c-04_west", "4a_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-04_west"]), + "4a_c-04_east": PreRegion("4a_c-04_east", "4a_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-04_east"]), + + "4a_c-05_west": PreRegion("4a_c-05_west", "4a_c-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-05_west"]), + "4a_c-05_east": PreRegion("4a_c-05_east", "4a_c-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-05_east"]), + + "4a_c-06_bottom": PreRegion("4a_c-06_bottom", "4a_c-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-06_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-06_bottom"]), + "4a_c-06_west": PreRegion("4a_c-06_west", "4a_c-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-06_west"]), + "4a_c-06_top": PreRegion("4a_c-06_top", "4a_c-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-06_top"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-06_top"]), + + "4a_c-06b_east": PreRegion("4a_c-06b_east", "4a_c-06b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-06b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-06b_east"]), + + "4a_c-09_west": PreRegion("4a_c-09_west", "4a_c-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-09_west"]), + "4a_c-09_east": PreRegion("4a_c-09_east", "4a_c-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-09_east"]), + + "4a_c-07_west": PreRegion("4a_c-07_west", "4a_c-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-07_west"]), + "4a_c-07_east": PreRegion("4a_c-07_east", "4a_c-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-07_east"]), + + "4a_c-08_bottom": PreRegion("4a_c-08_bottom", "4a_c-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-08_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-08_bottom"]), + "4a_c-08_east": PreRegion("4a_c-08_east", "4a_c-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-08_east"]), + "4a_c-08_top": PreRegion("4a_c-08_top", "4a_c-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-08_top"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-08_top"]), + + "4a_c-10_bottom": PreRegion("4a_c-10_bottom", "4a_c-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-10_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-10_bottom"]), + "4a_c-10_top": PreRegion("4a_c-10_top", "4a_c-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_c-10_top"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_c-10_top"]), + + "4a_d-00_west": PreRegion("4a_d-00_west", "4a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-00_west"]), + "4a_d-00_south": PreRegion("4a_d-00_south", "4a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-00_south"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-00_south"]), + "4a_d-00_east": PreRegion("4a_d-00_east", "4a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-00_east"]), + "4a_d-00_north-west": PreRegion("4a_d-00_north-west", "4a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-00_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-00_north-west"]), + + "4a_d-00b_east": PreRegion("4a_d-00b_east", "4a_d-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-00b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-00b_east"]), + + "4a_d-01_west": PreRegion("4a_d-01_west", "4a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-01_west"]), + "4a_d-01_east": PreRegion("4a_d-01_east", "4a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-01_east"]), + + "4a_d-02_west": PreRegion("4a_d-02_west", "4a_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-02_west"]), + "4a_d-02_east": PreRegion("4a_d-02_east", "4a_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-02_east"]), + + "4a_d-03_west": PreRegion("4a_d-03_west", "4a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-03_west"]), + "4a_d-03_east": PreRegion("4a_d-03_east", "4a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-03_east"]), + + "4a_d-04_west": PreRegion("4a_d-04_west", "4a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-04_west"]), + "4a_d-04_east": PreRegion("4a_d-04_east", "4a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-04_east"]), + + "4a_d-05_west": PreRegion("4a_d-05_west", "4a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-05_west"]), + "4a_d-05_east": PreRegion("4a_d-05_east", "4a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-05_east"]), + + "4a_d-06_west": PreRegion("4a_d-06_west", "4a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-06_west"]), + "4a_d-06_east": PreRegion("4a_d-06_east", "4a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-06_east"]), + + "4a_d-07_west": PreRegion("4a_d-07_west", "4a_d-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-07_west"]), + "4a_d-07_east": PreRegion("4a_d-07_east", "4a_d-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-07_east"]), + + "4a_d-08_west": PreRegion("4a_d-08_west", "4a_d-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-08_west"]), + "4a_d-08_east": PreRegion("4a_d-08_east", "4a_d-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-08_east"]), + + "4a_d-09_west": PreRegion("4a_d-09_west", "4a_d-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-09_west"]), + "4a_d-09_east": PreRegion("4a_d-09_east", "4a_d-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-09_east"]), + + "4a_d-10_west": PreRegion("4a_d-10_west", "4a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-10_west"]), + "4a_d-10_goal": PreRegion("4a_d-10_goal", "4a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4a_d-10_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "4a_d-10_goal"]), + + "4b_a-00_west": PreRegion("4b_a-00_west", "4b_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_a-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_a-00_west"]), + "4b_a-00_east": PreRegion("4b_a-00_east", "4b_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_a-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_a-00_east"]), + + "4b_a-01_west": PreRegion("4b_a-01_west", "4b_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_a-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_a-01_west"]), + "4b_a-01_east": PreRegion("4b_a-01_east", "4b_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_a-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_a-01_east"]), + + "4b_a-02_west": PreRegion("4b_a-02_west", "4b_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_a-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_a-02_west"]), + "4b_a-02_east": PreRegion("4b_a-02_east", "4b_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_a-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_a-02_east"]), + + "4b_a-03_west": PreRegion("4b_a-03_west", "4b_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_a-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_a-03_west"]), + "4b_a-03_east": PreRegion("4b_a-03_east", "4b_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_a-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_a-03_east"]), + + "4b_a-04_west": PreRegion("4b_a-04_west", "4b_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_a-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_a-04_west"]), + "4b_a-04_east": PreRegion("4b_a-04_east", "4b_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_a-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_a-04_east"]), + + "4b_b-00_west": PreRegion("4b_b-00_west", "4b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_b-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_b-00_west"]), + "4b_b-00_east": PreRegion("4b_b-00_east", "4b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_b-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_b-00_east"]), + + "4b_b-01_west": PreRegion("4b_b-01_west", "4b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_b-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_b-01_west"]), + "4b_b-01_east": PreRegion("4b_b-01_east", "4b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_b-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_b-01_east"]), + + "4b_b-02_bottom": PreRegion("4b_b-02_bottom", "4b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_b-02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_b-02_bottom"]), + "4b_b-02_top": PreRegion("4b_b-02_top", "4b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_b-02_top"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_b-02_top"]), + + "4b_b-03_west": PreRegion("4b_b-03_west", "4b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_b-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_b-03_west"]), + "4b_b-03_east": PreRegion("4b_b-03_east", "4b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_b-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_b-03_east"]), + + "4b_b-04_west": PreRegion("4b_b-04_west", "4b_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_b-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_b-04_west"]), + "4b_b-04_east": PreRegion("4b_b-04_east", "4b_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_b-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_b-04_east"]), + + "4b_c-00_west": PreRegion("4b_c-00_west", "4b_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_c-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_c-00_west"]), + "4b_c-00_east": PreRegion("4b_c-00_east", "4b_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_c-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_c-00_east"]), + + "4b_c-01_west": PreRegion("4b_c-01_west", "4b_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_c-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_c-01_west"]), + "4b_c-01_east": PreRegion("4b_c-01_east", "4b_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_c-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_c-01_east"]), + + "4b_c-02_west": PreRegion("4b_c-02_west", "4b_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_c-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_c-02_west"]), + "4b_c-02_east": PreRegion("4b_c-02_east", "4b_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_c-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_c-02_east"]), + + "4b_c-03_bottom": PreRegion("4b_c-03_bottom", "4b_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_c-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_c-03_bottom"]), + "4b_c-03_top": PreRegion("4b_c-03_top", "4b_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_c-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_c-03_top"]), + + "4b_c-04_west": PreRegion("4b_c-04_west", "4b_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_c-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_c-04_west"]), + "4b_c-04_east": PreRegion("4b_c-04_east", "4b_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_c-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_c-04_east"]), + + "4b_d-00_west": PreRegion("4b_d-00_west", "4b_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_d-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_d-00_west"]), + "4b_d-00_east": PreRegion("4b_d-00_east", "4b_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_d-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_d-00_east"]), + + "4b_d-01_west": PreRegion("4b_d-01_west", "4b_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_d-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_d-01_west"]), + "4b_d-01_east": PreRegion("4b_d-01_east", "4b_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_d-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_d-01_east"]), + + "4b_d-02_west": PreRegion("4b_d-02_west", "4b_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_d-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_d-02_west"]), + "4b_d-02_east": PreRegion("4b_d-02_east", "4b_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_d-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_d-02_east"]), + + "4b_d-03_west": PreRegion("4b_d-03_west", "4b_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_d-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_d-03_west"]), + "4b_d-03_east": PreRegion("4b_d-03_east", "4b_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_d-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_d-03_east"]), + + "4b_end_west": PreRegion("4b_end_west", "4b_end", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_end_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_end_west"]), + "4b_end_goal": PreRegion("4b_end_goal", "4b_end", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4b_end_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "4b_end_goal"]), + + "4c_00_west": PreRegion("4c_00_west", "4c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4c_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4c_00_west"]), + "4c_00_east": PreRegion("4c_00_east", "4c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4c_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4c_00_east"]), + + "4c_01_west": PreRegion("4c_01_west", "4c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4c_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4c_01_west"]), + "4c_01_east": PreRegion("4c_01_east", "4c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4c_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "4c_01_east"]), + + "4c_02_west": PreRegion("4c_02_west", "4c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4c_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "4c_02_west"]), + "4c_02_goal": PreRegion("4c_02_goal", "4c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "4c_02_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "4c_02_goal"]), + + "5a_a-00b_west": PreRegion("5a_a-00b_west", "5a_a-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-00b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-00b_west"]), + "5a_a-00b_east": PreRegion("5a_a-00b_east", "5a_a-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-00b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-00b_east"]), + + "5a_a-00x_east": PreRegion("5a_a-00x_east", "5a_a-00x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-00x_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-00x_east"]), + + "5a_a-00d_west": PreRegion("5a_a-00d_west", "5a_a-00d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-00d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-00d_west"]), + "5a_a-00d_east": PreRegion("5a_a-00d_east", "5a_a-00d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-00d_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-00d_east"]), + + "5a_a-00c_west": PreRegion("5a_a-00c_west", "5a_a-00c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-00c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-00c_west"]), + "5a_a-00c_east": PreRegion("5a_a-00c_east", "5a_a-00c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-00c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-00c_east"]), + + "5a_a-00_west": PreRegion("5a_a-00_west", "5a_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-00_west"]), + "5a_a-00_east": PreRegion("5a_a-00_east", "5a_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-00_east"]), + + "5a_a-01_west": PreRegion("5a_a-01_west", "5a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-01_west"]), + "5a_a-01_center": PreRegion("5a_a-01_center", "5a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-01_center"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-01_center"]), + "5a_a-01_east": PreRegion("5a_a-01_east", "5a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-01_east"]), + "5a_a-01_south-west": PreRegion("5a_a-01_south-west", "5a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-01_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-01_south-west"]), + "5a_a-01_south-east": PreRegion("5a_a-01_south-east", "5a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-01_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-01_south-east"]), + "5a_a-01_north": PreRegion("5a_a-01_north", "5a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-01_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-01_north"]), + + "5a_a-02_west": PreRegion("5a_a-02_west", "5a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-02_west"]), + "5a_a-02_north": PreRegion("5a_a-02_north", "5a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-02_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-02_north"]), + "5a_a-02_south": PreRegion("5a_a-02_south", "5a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-02_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-02_south"]), + + "5a_a-03_west": PreRegion("5a_a-03_west", "5a_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-03_west"]), + "5a_a-03_east": PreRegion("5a_a-03_east", "5a_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-03_east"]), + + "5a_a-04_east": PreRegion("5a_a-04_east", "5a_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-04_east"]), + "5a_a-04_north": PreRegion("5a_a-04_north", "5a_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-04_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-04_north"]), + "5a_a-04_south": PreRegion("5a_a-04_south", "5a_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-04_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-04_south"]), + + "5a_a-05_north-west": PreRegion("5a_a-05_north-west", "5a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-05_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-05_north-west"]), + "5a_a-05_center": PreRegion("5a_a-05_center", "5a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-05_center"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-05_center"]), + "5a_a-05_north-east": PreRegion("5a_a-05_north-east", "5a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-05_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-05_north-east"]), + "5a_a-05_south-west": PreRegion("5a_a-05_south-west", "5a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-05_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-05_south-west"]), + "5a_a-05_south-east": PreRegion("5a_a-05_south-east", "5a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-05_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-05_south-east"]), + + "5a_a-06_west": PreRegion("5a_a-06_west", "5a_a-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-06_west"]), + + "5a_a-07_east": PreRegion("5a_a-07_east", "5a_a-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-07_east"]), + + "5a_a-08_west": PreRegion("5a_a-08_west", "5a_a-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-08_west"]), + "5a_a-08_center": PreRegion("5a_a-08_center", "5a_a-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-08_center"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-08_center"]), + "5a_a-08_east": PreRegion("5a_a-08_east", "5a_a-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-08_east"]), + "5a_a-08_south": PreRegion("5a_a-08_south", "5a_a-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-08_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-08_south"]), + "5a_a-08_south-east": PreRegion("5a_a-08_south-east", "5a_a-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-08_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-08_south-east"]), + "5a_a-08_north-east": PreRegion("5a_a-08_north-east", "5a_a-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-08_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-08_north-east"]), + "5a_a-08_north": PreRegion("5a_a-08_north", "5a_a-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-08_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-08_north"]), + + "5a_a-10_west": PreRegion("5a_a-10_west", "5a_a-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-10_west"]), + "5a_a-10_east": PreRegion("5a_a-10_east", "5a_a-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-10_east"]), + + "5a_a-09_west": PreRegion("5a_a-09_west", "5a_a-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-09_west"]), + "5a_a-09_east": PreRegion("5a_a-09_east", "5a_a-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-09_east"]), + + "5a_a-11_east": PreRegion("5a_a-11_east", "5a_a-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-11_east"]), + + "5a_a-12_north-west": PreRegion("5a_a-12_north-west", "5a_a-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-12_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-12_north-west"]), + "5a_a-12_west": PreRegion("5a_a-12_west", "5a_a-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-12_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-12_west"]), + "5a_a-12_south-west": PreRegion("5a_a-12_south-west", "5a_a-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-12_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-12_south-west"]), + "5a_a-12_east": PreRegion("5a_a-12_east", "5a_a-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-12_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-12_east"]), + + "5a_a-15_south": PreRegion("5a_a-15_south", "5a_a-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-15_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-15_south"]), + + "5a_a-14_south": PreRegion("5a_a-14_south", "5a_a-14", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-14_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-14_south"]), + + "5a_a-13_west": PreRegion("5a_a-13_west", "5a_a-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-13_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-13_west"]), + "5a_a-13_east": PreRegion("5a_a-13_east", "5a_a-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_a-13_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_a-13_east"]), + + "5a_b-00_west": PreRegion("5a_b-00_west", "5a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-00_west"]), + "5a_b-00_north-west": PreRegion("5a_b-00_north-west", "5a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-00_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-00_north-west"]), + "5a_b-00_east": PreRegion("5a_b-00_east", "5a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-00_east"]), + + "5a_b-18_south": PreRegion("5a_b-18_south", "5a_b-18", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-18_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-18_south"]), + + "5a_b-01_south-west": PreRegion("5a_b-01_south-west", "5a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01_south-west"]), + "5a_b-01_center": PreRegion("5a_b-01_center", "5a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01_center"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01_center"]), + "5a_b-01_west": PreRegion("5a_b-01_west", "5a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01_west"]), + "5a_b-01_north-west": PreRegion("5a_b-01_north-west", "5a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01_north-west"]), + "5a_b-01_north": PreRegion("5a_b-01_north", "5a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01_north"]), + "5a_b-01_north-east": PreRegion("5a_b-01_north-east", "5a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01_north-east"]), + "5a_b-01_east": PreRegion("5a_b-01_east", "5a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01_east"]), + "5a_b-01_south-east": PreRegion("5a_b-01_south-east", "5a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01_south-east"]), + "5a_b-01_south": PreRegion("5a_b-01_south", "5a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01_south"]), + + "5a_b-01c_west": PreRegion("5a_b-01c_west", "5a_b-01c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01c_west"]), + "5a_b-01c_east": PreRegion("5a_b-01c_east", "5a_b-01c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01c_east"]), + + "5a_b-20_north-west": PreRegion("5a_b-20_north-west", "5a_b-20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-20_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-20_north-west"]), + "5a_b-20_west": PreRegion("5a_b-20_west", "5a_b-20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-20_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-20_west"]), + "5a_b-20_south-west": PreRegion("5a_b-20_south-west", "5a_b-20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-20_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-20_south-west"]), + "5a_b-20_south": PreRegion("5a_b-20_south", "5a_b-20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-20_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-20_south"]), + "5a_b-20_east": PreRegion("5a_b-20_east", "5a_b-20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-20_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-20_east"]), + + "5a_b-21_east": PreRegion("5a_b-21_east", "5a_b-21", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-21_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-21_east"]), + + "5a_b-01b_west": PreRegion("5a_b-01b_west", "5a_b-01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01b_west"]), + "5a_b-01b_east": PreRegion("5a_b-01b_east", "5a_b-01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-01b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-01b_east"]), + + "5a_b-02_center": PreRegion("5a_b-02_center", "5a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-02_center"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-02_center"]), + "5a_b-02_west": PreRegion("5a_b-02_west", "5a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-02_west"]), + "5a_b-02_north-west": PreRegion("5a_b-02_north-west", "5a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-02_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-02_north-west"]), + "5a_b-02_north": PreRegion("5a_b-02_north", "5a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-02_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-02_north"]), + "5a_b-02_north-east": PreRegion("5a_b-02_north-east", "5a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-02_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-02_north-east"]), + "5a_b-02_east-upper": PreRegion("5a_b-02_east-upper", "5a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-02_east-upper"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-02_east-upper"]), + "5a_b-02_east-lower": PreRegion("5a_b-02_east-lower", "5a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-02_east-lower"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-02_east-lower"]), + "5a_b-02_south-east": PreRegion("5a_b-02_south-east", "5a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-02_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-02_south-east"]), + "5a_b-02_south": PreRegion("5a_b-02_south", "5a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-02_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-02_south"]), + + "5a_b-03_east": PreRegion("5a_b-03_east", "5a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-03_east"]), + + "5a_b-05_west": PreRegion("5a_b-05_west", "5a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-05_west"]), + + "5a_b-04_west": PreRegion("5a_b-04_west", "5a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-04_west"]), + "5a_b-04_east": PreRegion("5a_b-04_east", "5a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-04_east"]), + "5a_b-04_south": PreRegion("5a_b-04_south", "5a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-04_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-04_south"]), + + "5a_b-07_north": PreRegion("5a_b-07_north", "5a_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-07_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-07_north"]), + "5a_b-07_south": PreRegion("5a_b-07_south", "5a_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-07_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-07_south"]), + + "5a_b-08_west": PreRegion("5a_b-08_west", "5a_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-08_west"]), + "5a_b-08_east": PreRegion("5a_b-08_east", "5a_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-08_east"]), + + "5a_b-09_north": PreRegion("5a_b-09_north", "5a_b-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-09_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-09_north"]), + "5a_b-09_south": PreRegion("5a_b-09_south", "5a_b-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-09_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-09_south"]), + + "5a_b-10_east": PreRegion("5a_b-10_east", "5a_b-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-10_east"]), + + "5a_b-11_north-west": PreRegion("5a_b-11_north-west", "5a_b-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-11_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-11_north-west"]), + "5a_b-11_west": PreRegion("5a_b-11_west", "5a_b-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-11_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-11_west"]), + "5a_b-11_south-west": PreRegion("5a_b-11_south-west", "5a_b-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-11_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-11_south-west"]), + "5a_b-11_south-east": PreRegion("5a_b-11_south-east", "5a_b-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-11_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-11_south-east"]), + "5a_b-11_east": PreRegion("5a_b-11_east", "5a_b-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-11_east"]), + + "5a_b-12_west": PreRegion("5a_b-12_west", "5a_b-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-12_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-12_west"]), + "5a_b-12_east": PreRegion("5a_b-12_east", "5a_b-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-12_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-12_east"]), + + "5a_b-13_west": PreRegion("5a_b-13_west", "5a_b-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-13_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-13_west"]), + "5a_b-13_east": PreRegion("5a_b-13_east", "5a_b-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-13_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-13_east"]), + "5a_b-13_north-east": PreRegion("5a_b-13_north-east", "5a_b-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-13_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-13_north-east"]), + + "5a_b-17_west": PreRegion("5a_b-17_west", "5a_b-17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-17_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-17_west"]), + "5a_b-17_east": PreRegion("5a_b-17_east", "5a_b-17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-17_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-17_east"]), + "5a_b-17_north-west": PreRegion("5a_b-17_north-west", "5a_b-17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-17_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-17_north-west"]), + + "5a_b-22_west": PreRegion("5a_b-22_west", "5a_b-22", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-22_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-22_west"]), + + "5a_b-06_west": PreRegion("5a_b-06_west", "5a_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-06_west"]), + "5a_b-06_east": PreRegion("5a_b-06_east", "5a_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-06_east"]), + "5a_b-06_north-east": PreRegion("5a_b-06_north-east", "5a_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-06_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-06_north-east"]), + + "5a_b-19_west": PreRegion("5a_b-19_west", "5a_b-19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-19_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-19_west"]), + "5a_b-19_east": PreRegion("5a_b-19_east", "5a_b-19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-19_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-19_east"]), + "5a_b-19_north-west": PreRegion("5a_b-19_north-west", "5a_b-19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-19_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-19_north-west"]), + + "5a_b-14_west": PreRegion("5a_b-14_west", "5a_b-14", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-14_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-14_west"]), + "5a_b-14_south": PreRegion("5a_b-14_south", "5a_b-14", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-14_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-14_south"]), + "5a_b-14_north": PreRegion("5a_b-14_north", "5a_b-14", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-14_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-14_north"]), + + "5a_b-15_west": PreRegion("5a_b-15_west", "5a_b-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-15_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-15_west"]), + + "5a_b-16_bottom": PreRegion("5a_b-16_bottom", "5a_b-16", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-16_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-16_bottom"]), + "5a_b-16_mirror": PreRegion("5a_b-16_mirror", "5a_b-16", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_b-16_mirror"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_b-16_mirror"]), + + "5a_void_east": PreRegion("5a_void_east", "5a_void", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_void_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_void_east"]), + "5a_void_west": PreRegion("5a_void_west", "5a_void", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_void_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_void_west"]), + + "5a_c-00_bottom": PreRegion("5a_c-00_bottom", "5a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-00_bottom"]), + "5a_c-00_top": PreRegion("5a_c-00_top", "5a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-00_top"]), + + "5a_c-01_west": PreRegion("5a_c-01_west", "5a_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-01_west"]), + "5a_c-01_east": PreRegion("5a_c-01_east", "5a_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-01_east"]), + + "5a_c-01b_west": PreRegion("5a_c-01b_west", "5a_c-01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-01b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-01b_west"]), + "5a_c-01b_east": PreRegion("5a_c-01b_east", "5a_c-01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-01b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-01b_east"]), + + "5a_c-01c_west": PreRegion("5a_c-01c_west", "5a_c-01c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-01c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-01c_west"]), + "5a_c-01c_east": PreRegion("5a_c-01c_east", "5a_c-01c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-01c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-01c_east"]), + + "5a_c-08b_west": PreRegion("5a_c-08b_west", "5a_c-08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-08b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-08b_west"]), + "5a_c-08b_east": PreRegion("5a_c-08b_east", "5a_c-08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-08b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-08b_east"]), + + "5a_c-08_west": PreRegion("5a_c-08_west", "5a_c-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-08_west"]), + "5a_c-08_east": PreRegion("5a_c-08_east", "5a_c-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-08_east"]), + + "5a_c-10_west": PreRegion("5a_c-10_west", "5a_c-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-10_west"]), + "5a_c-10_east": PreRegion("5a_c-10_east", "5a_c-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-10_east"]), + + "5a_c-12_west": PreRegion("5a_c-12_west", "5a_c-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-12_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-12_west"]), + "5a_c-12_east": PreRegion("5a_c-12_east", "5a_c-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-12_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-12_east"]), + + "5a_c-07_west": PreRegion("5a_c-07_west", "5a_c-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-07_west"]), + "5a_c-07_east": PreRegion("5a_c-07_east", "5a_c-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-07_east"]), + + "5a_c-11_west": PreRegion("5a_c-11_west", "5a_c-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-11_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-11_west"]), + "5a_c-11_east": PreRegion("5a_c-11_east", "5a_c-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-11_east"]), + + "5a_c-09_west": PreRegion("5a_c-09_west", "5a_c-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-09_west"]), + "5a_c-09_east": PreRegion("5a_c-09_east", "5a_c-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-09_east"]), + + "5a_c-13_west": PreRegion("5a_c-13_west", "5a_c-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-13_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-13_west"]), + "5a_c-13_east": PreRegion("5a_c-13_east", "5a_c-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_c-13_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_c-13_east"]), + + "5a_d-00_south": PreRegion("5a_d-00_south", "5a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-00_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-00_south"]), + "5a_d-00_north": PreRegion("5a_d-00_north", "5a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-00_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-00_north"]), + "5a_d-00_west": PreRegion("5a_d-00_west", "5a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-00_west"]), + "5a_d-00_east": PreRegion("5a_d-00_east", "5a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-00_east"]), + + "5a_d-01_south": PreRegion("5a_d-01_south", "5a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-01_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-01_south"]), + "5a_d-01_center": PreRegion("5a_d-01_center", "5a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-01_center"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-01_center"]), + "5a_d-01_south-west-left": PreRegion("5a_d-01_south-west-left", "5a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-01_south-west-left"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-01_south-west-left"]), + "5a_d-01_south-west-down": PreRegion("5a_d-01_south-west-down", "5a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-01_south-west-down"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-01_south-west-down"]), + "5a_d-01_south-east-right": PreRegion("5a_d-01_south-east-right", "5a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-01_south-east-right"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-01_south-east-right"]), + "5a_d-01_south-east-down": PreRegion("5a_d-01_south-east-down", "5a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-01_south-east-down"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-01_south-east-down"]), + "5a_d-01_west": PreRegion("5a_d-01_west", "5a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-01_west"]), + "5a_d-01_east": PreRegion("5a_d-01_east", "5a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-01_east"]), + "5a_d-01_north-west": PreRegion("5a_d-01_north-west", "5a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-01_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-01_north-west"]), + "5a_d-01_north-east": PreRegion("5a_d-01_north-east", "5a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-01_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-01_north-east"]), + + "5a_d-09_east": PreRegion("5a_d-09_east", "5a_d-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-09_east"]), + "5a_d-09_west": PreRegion("5a_d-09_west", "5a_d-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-09_west"]), + + "5a_d-04_east": PreRegion("5a_d-04_east", "5a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-04_east"]), + "5a_d-04_west": PreRegion("5a_d-04_west", "5a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-04_west"]), + "5a_d-04_south-west-left": PreRegion("5a_d-04_south-west-left", "5a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-04_south-west-left"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-04_south-west-left"]), + "5a_d-04_south-west-right": PreRegion("5a_d-04_south-west-right", "5a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-04_south-west-right"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-04_south-west-right"]), + "5a_d-04_south-east": PreRegion("5a_d-04_south-east", "5a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-04_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-04_south-east"]), + "5a_d-04_north": PreRegion("5a_d-04_north", "5a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-04_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-04_north"]), + + "5a_d-05_north": PreRegion("5a_d-05_north", "5a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-05_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-05_north"]), + "5a_d-05_east": PreRegion("5a_d-05_east", "5a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-05_east"]), + "5a_d-05_south": PreRegion("5a_d-05_south", "5a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-05_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-05_south"]), + "5a_d-05_west": PreRegion("5a_d-05_west", "5a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-05_west"]), + + "5a_d-06_north-east": PreRegion("5a_d-06_north-east", "5a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-06_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-06_north-east"]), + "5a_d-06_south-east": PreRegion("5a_d-06_south-east", "5a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-06_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-06_south-east"]), + "5a_d-06_south-west": PreRegion("5a_d-06_south-west", "5a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-06_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-06_south-west"]), + "5a_d-06_north-west": PreRegion("5a_d-06_north-west", "5a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-06_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-06_north-west"]), + + "5a_d-07_west": PreRegion("5a_d-07_west", "5a_d-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-07_west"]), + "5a_d-07_north": PreRegion("5a_d-07_north", "5a_d-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-07_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-07_north"]), + + "5a_d-02_east": PreRegion("5a_d-02_east", "5a_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-02_east"]), + "5a_d-02_west": PreRegion("5a_d-02_west", "5a_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-02_west"]), + + "5a_d-03_east": PreRegion("5a_d-03_east", "5a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-03_east"]), + "5a_d-03_west": PreRegion("5a_d-03_west", "5a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-03_west"]), + + "5a_d-15_north-west": PreRegion("5a_d-15_north-west", "5a_d-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-15_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-15_north-west"]), + "5a_d-15_center": PreRegion("5a_d-15_center", "5a_d-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-15_center"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-15_center"]), + "5a_d-15_west": PreRegion("5a_d-15_west", "5a_d-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-15_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-15_west"]), + "5a_d-15_south-west": PreRegion("5a_d-15_south-west", "5a_d-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-15_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-15_south-west"]), + "5a_d-15_south": PreRegion("5a_d-15_south", "5a_d-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-15_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-15_south"]), + "5a_d-15_south-east": PreRegion("5a_d-15_south-east", "5a_d-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-15_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-15_south-east"]), + + "5a_d-13_east": PreRegion("5a_d-13_east", "5a_d-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-13_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-13_east"]), + "5a_d-13_west": PreRegion("5a_d-13_west", "5a_d-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-13_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-13_west"]), + + "5a_d-19b_south-east-right": PreRegion("5a_d-19b_south-east-right", "5a_d-19b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-19b_south-east-right"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-19b_south-east-right"]), + "5a_d-19b_south-east-down": PreRegion("5a_d-19b_south-east-down", "5a_d-19b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-19b_south-east-down"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-19b_south-east-down"]), + "5a_d-19b_south-west": PreRegion("5a_d-19b_south-west", "5a_d-19b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-19b_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-19b_south-west"]), + "5a_d-19b_north-east": PreRegion("5a_d-19b_north-east", "5a_d-19b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-19b_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-19b_north-east"]), + + "5a_d-19_east": PreRegion("5a_d-19_east", "5a_d-19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-19_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-19_east"]), + "5a_d-19_west": PreRegion("5a_d-19_west", "5a_d-19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-19_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-19_west"]), + + "5a_d-10_west": PreRegion("5a_d-10_west", "5a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-10_west"]), + "5a_d-10_east": PreRegion("5a_d-10_east", "5a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-10_east"]), + + "5a_d-20_west": PreRegion("5a_d-20_west", "5a_d-20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-20_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-20_west"]), + "5a_d-20_east": PreRegion("5a_d-20_east", "5a_d-20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_d-20_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_d-20_east"]), + + "5a_e-00_west": PreRegion("5a_e-00_west", "5a_e-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-00_west"]), + "5a_e-00_east": PreRegion("5a_e-00_east", "5a_e-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-00_east"]), + + "5a_e-01_west": PreRegion("5a_e-01_west", "5a_e-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-01_west"]), + "5a_e-01_east": PreRegion("5a_e-01_east", "5a_e-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-01_east"]), + + "5a_e-02_west": PreRegion("5a_e-02_west", "5a_e-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-02_west"]), + "5a_e-02_east": PreRegion("5a_e-02_east", "5a_e-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-02_east"]), + + "5a_e-03_west": PreRegion("5a_e-03_west", "5a_e-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-03_west"]), + "5a_e-03_east": PreRegion("5a_e-03_east", "5a_e-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-03_east"]), + + "5a_e-04_west": PreRegion("5a_e-04_west", "5a_e-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-04_west"]), + "5a_e-04_east": PreRegion("5a_e-04_east", "5a_e-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-04_east"]), + + "5a_e-06_west": PreRegion("5a_e-06_west", "5a_e-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-06_west"]), + "5a_e-06_east": PreRegion("5a_e-06_east", "5a_e-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-06_east"]), + + "5a_e-05_west": PreRegion("5a_e-05_west", "5a_e-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-05_west"]), + "5a_e-05_east": PreRegion("5a_e-05_east", "5a_e-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-05_east"]), + + "5a_e-07_west": PreRegion("5a_e-07_west", "5a_e-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-07_west"]), + "5a_e-07_east": PreRegion("5a_e-07_east", "5a_e-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-07_east"]), + + "5a_e-08_west": PreRegion("5a_e-08_west", "5a_e-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-08_west"]), + "5a_e-08_east": PreRegion("5a_e-08_east", "5a_e-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-08_east"]), + + "5a_e-09_west": PreRegion("5a_e-09_west", "5a_e-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-09_west"]), + "5a_e-09_east": PreRegion("5a_e-09_east", "5a_e-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-09_east"]), + + "5a_e-10_west": PreRegion("5a_e-10_west", "5a_e-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-10_west"]), + "5a_e-10_east": PreRegion("5a_e-10_east", "5a_e-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-10_east"]), + + "5a_e-11_west": PreRegion("5a_e-11_west", "5a_e-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-11_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-11_west"]), + "5a_e-11_goal": PreRegion("5a_e-11_goal", "5a_e-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5a_e-11_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "5a_e-11_goal"]), + + "5b_start_west": PreRegion("5b_start_west", "5b_start", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_start_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_start_west"]), + "5b_start_east": PreRegion("5b_start_east", "5b_start", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_start_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_start_east"]), + + "5b_a-00_west": PreRegion("5b_a-00_west", "5b_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_a-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_a-00_west"]), + "5b_a-00_east": PreRegion("5b_a-00_east", "5b_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_a-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_a-00_east"]), + + "5b_a-01_west": PreRegion("5b_a-01_west", "5b_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_a-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_a-01_west"]), + "5b_a-01_east": PreRegion("5b_a-01_east", "5b_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_a-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_a-01_east"]), + + "5b_a-02_west": PreRegion("5b_a-02_west", "5b_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_a-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_a-02_west"]), + "5b_a-02_east": PreRegion("5b_a-02_east", "5b_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_a-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_a-02_east"]), + + "5b_b-00_south": PreRegion("5b_b-00_south", "5b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-00_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-00_south"]), + "5b_b-00_west": PreRegion("5b_b-00_west", "5b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-00_west"]), + "5b_b-00_north": PreRegion("5b_b-00_north", "5b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-00_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-00_north"]), + "5b_b-00_east": PreRegion("5b_b-00_east", "5b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-00_east"]), + + "5b_b-01_west": PreRegion("5b_b-01_west", "5b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-01_west"]), + "5b_b-01_north": PreRegion("5b_b-01_north", "5b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-01_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-01_north"]), + "5b_b-01_east": PreRegion("5b_b-01_east", "5b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-01_east"]), + + "5b_b-04_east": PreRegion("5b_b-04_east", "5b_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-04_east"]), + "5b_b-04_west": PreRegion("5b_b-04_west", "5b_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-04_west"]), + + "5b_b-02_south": PreRegion("5b_b-02_south", "5b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-02_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-02_south"]), + "5b_b-02_center": PreRegion("5b_b-02_center", "5b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-02_center"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-02_center"]), + "5b_b-02_north-west": PreRegion("5b_b-02_north-west", "5b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-02_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-02_north-west"]), + "5b_b-02_north-east": PreRegion("5b_b-02_north-east", "5b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-02_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-02_north-east"]), + "5b_b-02_north": PreRegion("5b_b-02_north", "5b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-02_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-02_north"]), + "5b_b-02_south-west": PreRegion("5b_b-02_south-west", "5b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-02_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-02_south-west"]), + "5b_b-02_south-east": PreRegion("5b_b-02_south-east", "5b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-02_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-02_south-east"]), + + "5b_b-05_north": PreRegion("5b_b-05_north", "5b_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-05_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-05_north"]), + "5b_b-05_south": PreRegion("5b_b-05_south", "5b_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-05_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-05_south"]), + + "5b_b-06_east": PreRegion("5b_b-06_east", "5b_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-06_east"]), + + "5b_b-07_north": PreRegion("5b_b-07_north", "5b_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-07_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-07_north"]), + "5b_b-07_south": PreRegion("5b_b-07_south", "5b_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-07_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-07_south"]), + + "5b_b-03_west": PreRegion("5b_b-03_west", "5b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-03_west"]), + "5b_b-03_main": PreRegion("5b_b-03_main", "5b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-03_main"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-03_main"]), + "5b_b-03_north": PreRegion("5b_b-03_north", "5b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-03_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-03_north"]), + "5b_b-03_east": PreRegion("5b_b-03_east", "5b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-03_east"]), + + "5b_b-08_south": PreRegion("5b_b-08_south", "5b_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-08_south"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-08_south"]), + "5b_b-08_north": PreRegion("5b_b-08_north", "5b_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-08_north"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-08_north"]), + "5b_b-08_east": PreRegion("5b_b-08_east", "5b_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-08_east"]), + + "5b_b-09_bottom": PreRegion("5b_b-09_bottom", "5b_b-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-09_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-09_bottom"]), + "5b_b-09_mirror": PreRegion("5b_b-09_mirror", "5b_b-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_b-09_mirror"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_b-09_mirror"]), + + "5b_c-00_bottom": PreRegion("5b_c-00_bottom", "5b_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_c-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_c-00_bottom"]), + "5b_c-00_mirror": PreRegion("5b_c-00_mirror", "5b_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_c-00_mirror"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_c-00_mirror"]), + + "5b_c-01_west": PreRegion("5b_c-01_west", "5b_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_c-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_c-01_west"]), + "5b_c-01_east": PreRegion("5b_c-01_east", "5b_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_c-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_c-01_east"]), + + "5b_c-02_west": PreRegion("5b_c-02_west", "5b_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_c-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_c-02_west"]), + "5b_c-02_east": PreRegion("5b_c-02_east", "5b_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_c-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_c-02_east"]), + + "5b_c-03_west": PreRegion("5b_c-03_west", "5b_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_c-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_c-03_west"]), + "5b_c-03_east": PreRegion("5b_c-03_east", "5b_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_c-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_c-03_east"]), + + "5b_c-04_west": PreRegion("5b_c-04_west", "5b_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_c-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_c-04_west"]), + "5b_c-04_east": PreRegion("5b_c-04_east", "5b_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_c-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_c-04_east"]), + + "5b_d-00_west": PreRegion("5b_d-00_west", "5b_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-00_west"]), + "5b_d-00_east": PreRegion("5b_d-00_east", "5b_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-00_east"]), + + "5b_d-01_west": PreRegion("5b_d-01_west", "5b_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-01_west"]), + "5b_d-01_east": PreRegion("5b_d-01_east", "5b_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-01_east"]), + + "5b_d-02_west": PreRegion("5b_d-02_west", "5b_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-02_west"]), + "5b_d-02_east": PreRegion("5b_d-02_east", "5b_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-02_east"]), + + "5b_d-03_west": PreRegion("5b_d-03_west", "5b_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-03_west"]), + "5b_d-03_east": PreRegion("5b_d-03_east", "5b_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-03_east"]), + + "5b_d-04_west": PreRegion("5b_d-04_west", "5b_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-04_west"]), + "5b_d-04_east": PreRegion("5b_d-04_east", "5b_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-04_east"]), + + "5b_d-05_west": PreRegion("5b_d-05_west", "5b_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-05_west"]), + "5b_d-05_goal": PreRegion("5b_d-05_goal", "5b_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5b_d-05_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "5b_d-05_goal"]), + + "5c_00_west": PreRegion("5c_00_west", "5c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5c_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5c_00_west"]), + "5c_00_east": PreRegion("5c_00_east", "5c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5c_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5c_00_east"]), + + "5c_01_west": PreRegion("5c_01_west", "5c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5c_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5c_01_west"]), + "5c_01_east": PreRegion("5c_01_east", "5c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5c_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "5c_01_east"]), + + "5c_02_west": PreRegion("5c_02_west", "5c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5c_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "5c_02_west"]), + "5c_02_goal": PreRegion("5c_02_goal", "5c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "5c_02_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "5c_02_goal"]), + + "6a_00_west": PreRegion("6a_00_west", "6a_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_00_west"]), + "6a_00_east": PreRegion("6a_00_east", "6a_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_00_east"]), + + "6a_01_bottom": PreRegion("6a_01_bottom", "6a_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_01_bottom"]), + "6a_01_top": PreRegion("6a_01_top", "6a_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_01_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_01_top"]), + + "6a_02_bottom": PreRegion("6a_02_bottom", "6a_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_02_bottom"]), + "6a_02_bottom-west": PreRegion("6a_02_bottom-west", "6a_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_02_bottom-west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_02_bottom-west"]), + "6a_02_top-west": PreRegion("6a_02_top-west", "6a_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_02_top-west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_02_top-west"]), + "6a_02_top": PreRegion("6a_02_top", "6a_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_02_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_02_top"]), + + "6a_03_bottom": PreRegion("6a_03_bottom", "6a_03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_03_bottom"]), + "6a_03_top": PreRegion("6a_03_top", "6a_03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_03_top"]), + + "6a_02b_bottom": PreRegion("6a_02b_bottom", "6a_02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_02b_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_02b_bottom"]), + "6a_02b_top": PreRegion("6a_02b_top", "6a_02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_02b_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_02b_top"]), + + "6a_04_south": PreRegion("6a_04_south", "6a_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_04_south"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_04_south"]), + "6a_04_south-west": PreRegion("6a_04_south-west", "6a_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_04_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_04_south-west"]), + "6a_04_south-east": PreRegion("6a_04_south-east", "6a_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_04_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_04_south-east"]), + "6a_04_east": PreRegion("6a_04_east", "6a_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_04_east"]), + "6a_04_north-west": PreRegion("6a_04_north-west", "6a_04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_04_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_04_north-west"]), + + "6a_04b_west": PreRegion("6a_04b_west", "6a_04b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_04b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_04b_west"]), + "6a_04b_east": PreRegion("6a_04b_east", "6a_04b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_04b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_04b_east"]), + + "6a_04c_east": PreRegion("6a_04c_east", "6a_04c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_04c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_04c_east"]), + + "6a_04d_west": PreRegion("6a_04d_west", "6a_04d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_04d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_04d_west"]), + + "6a_04e_east": PreRegion("6a_04e_east", "6a_04e", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_04e_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_04e_east"]), + + "6a_05_west": PreRegion("6a_05_west", "6a_05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_05_west"]), + "6a_05_east": PreRegion("6a_05_east", "6a_05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_05_east"]), + + "6a_06_west": PreRegion("6a_06_west", "6a_06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_06_west"]), + "6a_06_east": PreRegion("6a_06_east", "6a_06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_06_east"]), + + "6a_07_west": PreRegion("6a_07_west", "6a_07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_07_west"]), + "6a_07_east": PreRegion("6a_07_east", "6a_07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_07_east"]), + "6a_07_north-east": PreRegion("6a_07_north-east", "6a_07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_07_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_07_north-east"]), + + "6a_08a_west": PreRegion("6a_08a_west", "6a_08a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_08a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_08a_west"]), + "6a_08a_east": PreRegion("6a_08a_east", "6a_08a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_08a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_08a_east"]), + + "6a_08b_west": PreRegion("6a_08b_west", "6a_08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_08b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_08b_west"]), + "6a_08b_east": PreRegion("6a_08b_east", "6a_08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_08b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_08b_east"]), + + "6a_09_west": PreRegion("6a_09_west", "6a_09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_09_west"]), + "6a_09_north-west": PreRegion("6a_09_north-west", "6a_09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_09_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_09_north-west"]), + "6a_09_east": PreRegion("6a_09_east", "6a_09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_09_east"]), + "6a_09_north-east": PreRegion("6a_09_north-east", "6a_09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_09_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_09_north-east"]), + + "6a_10a_west": PreRegion("6a_10a_west", "6a_10a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_10a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_10a_west"]), + "6a_10a_east": PreRegion("6a_10a_east", "6a_10a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_10a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_10a_east"]), + + "6a_10b_west": PreRegion("6a_10b_west", "6a_10b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_10b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_10b_west"]), + "6a_10b_east": PreRegion("6a_10b_east", "6a_10b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_10b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_10b_east"]), + + "6a_11_west": PreRegion("6a_11_west", "6a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_11_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_11_west"]), + "6a_11_north-west": PreRegion("6a_11_north-west", "6a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_11_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_11_north-west"]), + "6a_11_east": PreRegion("6a_11_east", "6a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_11_east"]), + "6a_11_north-east": PreRegion("6a_11_north-east", "6a_11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_11_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_11_north-east"]), + + "6a_12a_west": PreRegion("6a_12a_west", "6a_12a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_12a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_12a_west"]), + "6a_12a_east": PreRegion("6a_12a_east", "6a_12a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_12a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_12a_east"]), + + "6a_12b_west": PreRegion("6a_12b_west", "6a_12b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_12b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_12b_west"]), + "6a_12b_east": PreRegion("6a_12b_east", "6a_12b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_12b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_12b_east"]), + + "6a_13_west": PreRegion("6a_13_west", "6a_13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_13_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_13_west"]), + "6a_13_north-west": PreRegion("6a_13_north-west", "6a_13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_13_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_13_north-west"]), + "6a_13_east": PreRegion("6a_13_east", "6a_13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_13_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_13_east"]), + "6a_13_north-east": PreRegion("6a_13_north-east", "6a_13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_13_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_13_north-east"]), + + "6a_14a_west": PreRegion("6a_14a_west", "6a_14a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_14a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_14a_west"]), + "6a_14a_east": PreRegion("6a_14a_east", "6a_14a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_14a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_14a_east"]), + + "6a_14b_west": PreRegion("6a_14b_west", "6a_14b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_14b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_14b_west"]), + "6a_14b_east": PreRegion("6a_14b_east", "6a_14b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_14b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_14b_east"]), + + "6a_15_west": PreRegion("6a_15_west", "6a_15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_15_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_15_west"]), + "6a_15_north-west": PreRegion("6a_15_north-west", "6a_15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_15_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_15_north-west"]), + "6a_15_east": PreRegion("6a_15_east", "6a_15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_15_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_15_east"]), + "6a_15_north-east": PreRegion("6a_15_north-east", "6a_15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_15_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_15_north-east"]), + + "6a_16a_west": PreRegion("6a_16a_west", "6a_16a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_16a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_16a_west"]), + "6a_16a_east": PreRegion("6a_16a_east", "6a_16a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_16a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_16a_east"]), + + "6a_16b_west": PreRegion("6a_16b_west", "6a_16b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_16b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_16b_west"]), + "6a_16b_east": PreRegion("6a_16b_east", "6a_16b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_16b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_16b_east"]), + + "6a_17_west": PreRegion("6a_17_west", "6a_17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_17_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_17_west"]), + "6a_17_north-west": PreRegion("6a_17_north-west", "6a_17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_17_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_17_north-west"]), + "6a_17_east": PreRegion("6a_17_east", "6a_17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_17_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_17_east"]), + "6a_17_north-east": PreRegion("6a_17_north-east", "6a_17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_17_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_17_north-east"]), + + "6a_18a_west": PreRegion("6a_18a_west", "6a_18a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_18a_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_18a_west"]), + "6a_18a_east": PreRegion("6a_18a_east", "6a_18a", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_18a_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_18a_east"]), + + "6a_18b_west": PreRegion("6a_18b_west", "6a_18b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_18b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_18b_west"]), + "6a_18b_east": PreRegion("6a_18b_east", "6a_18b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_18b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_18b_east"]), + + "6a_19_west": PreRegion("6a_19_west", "6a_19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_19_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_19_west"]), + "6a_19_north-west": PreRegion("6a_19_north-west", "6a_19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_19_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_19_north-west"]), + "6a_19_east": PreRegion("6a_19_east", "6a_19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_19_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_19_east"]), + + "6a_20_west": PreRegion("6a_20_west", "6a_20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_20_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_20_west"]), + "6a_20_east": PreRegion("6a_20_east", "6a_20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_20_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_20_east"]), + + "6a_b-00_west": PreRegion("6a_b-00_west", "6a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-00_west"]), + "6a_b-00_east": PreRegion("6a_b-00_east", "6a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-00_east"]), + "6a_b-00_top": PreRegion("6a_b-00_top", "6a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-00_top"]), + + "6a_b-00b_bottom": PreRegion("6a_b-00b_bottom", "6a_b-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-00b_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-00b_bottom"]), + "6a_b-00b_top": PreRegion("6a_b-00b_top", "6a_b-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-00b_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-00b_top"]), + + "6a_b-00c_east": PreRegion("6a_b-00c_east", "6a_b-00c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-00c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-00c_east"]), + + "6a_b-01_west": PreRegion("6a_b-01_west", "6a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-01_west"]), + "6a_b-01_east": PreRegion("6a_b-01_east", "6a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-01_east"]), + + "6a_b-02_top": PreRegion("6a_b-02_top", "6a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-02_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-02_top"]), + "6a_b-02_bottom": PreRegion("6a_b-02_bottom", "6a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-02_bottom"]), + + "6a_b-02b_top": PreRegion("6a_b-02b_top", "6a_b-02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-02b_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-02b_top"]), + "6a_b-02b_bottom": PreRegion("6a_b-02b_bottom", "6a_b-02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-02b_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-02b_bottom"]), + + "6a_b-03_west": PreRegion("6a_b-03_west", "6a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-03_west"]), + "6a_b-03_east": PreRegion("6a_b-03_east", "6a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_b-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_b-03_east"]), + + "6a_boss-00_west": PreRegion("6a_boss-00_west", "6a_boss-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-00_west"]), + "6a_boss-00_east": PreRegion("6a_boss-00_east", "6a_boss-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-00_east"]), + + "6a_boss-01_west": PreRegion("6a_boss-01_west", "6a_boss-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-01_west"]), + "6a_boss-01_east": PreRegion("6a_boss-01_east", "6a_boss-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-01_east"]), + + "6a_boss-02_west": PreRegion("6a_boss-02_west", "6a_boss-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-02_west"]), + "6a_boss-02_east": PreRegion("6a_boss-02_east", "6a_boss-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-02_east"]), + + "6a_boss-03_west": PreRegion("6a_boss-03_west", "6a_boss-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-03_west"]), + "6a_boss-03_east": PreRegion("6a_boss-03_east", "6a_boss-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-03_east"]), + + "6a_boss-04_west": PreRegion("6a_boss-04_west", "6a_boss-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-04_west"]), + "6a_boss-04_east": PreRegion("6a_boss-04_east", "6a_boss-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-04_east"]), + + "6a_boss-05_west": PreRegion("6a_boss-05_west", "6a_boss-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-05_west"]), + "6a_boss-05_east": PreRegion("6a_boss-05_east", "6a_boss-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-05_east"]), + + "6a_boss-06_west": PreRegion("6a_boss-06_west", "6a_boss-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-06_west"]), + "6a_boss-06_east": PreRegion("6a_boss-06_east", "6a_boss-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-06_east"]), + + "6a_boss-07_west": PreRegion("6a_boss-07_west", "6a_boss-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-07_west"]), + "6a_boss-07_east": PreRegion("6a_boss-07_east", "6a_boss-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-07_east"]), + + "6a_boss-08_west": PreRegion("6a_boss-08_west", "6a_boss-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-08_west"]), + "6a_boss-08_east": PreRegion("6a_boss-08_east", "6a_boss-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-08_east"]), + + "6a_boss-09_west": PreRegion("6a_boss-09_west", "6a_boss-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-09_west"]), + "6a_boss-09_east": PreRegion("6a_boss-09_east", "6a_boss-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-09_east"]), + + "6a_boss-10_west": PreRegion("6a_boss-10_west", "6a_boss-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-10_west"]), + "6a_boss-10_east": PreRegion("6a_boss-10_east", "6a_boss-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-10_east"]), + + "6a_boss-11_west": PreRegion("6a_boss-11_west", "6a_boss-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-11_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-11_west"]), + "6a_boss-11_east": PreRegion("6a_boss-11_east", "6a_boss-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-11_east"]), + + "6a_boss-12_west": PreRegion("6a_boss-12_west", "6a_boss-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-12_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-12_west"]), + "6a_boss-12_east": PreRegion("6a_boss-12_east", "6a_boss-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-12_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-12_east"]), + + "6a_boss-13_west": PreRegion("6a_boss-13_west", "6a_boss-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-13_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-13_west"]), + "6a_boss-13_east": PreRegion("6a_boss-13_east", "6a_boss-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-13_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-13_east"]), + + "6a_boss-14_west": PreRegion("6a_boss-14_west", "6a_boss-14", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-14_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-14_west"]), + "6a_boss-14_east": PreRegion("6a_boss-14_east", "6a_boss-14", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-14_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-14_east"]), + + "6a_boss-15_west": PreRegion("6a_boss-15_west", "6a_boss-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-15_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-15_west"]), + "6a_boss-15_east": PreRegion("6a_boss-15_east", "6a_boss-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-15_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-15_east"]), + + "6a_boss-16_west": PreRegion("6a_boss-16_west", "6a_boss-16", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-16_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-16_west"]), + "6a_boss-16_east": PreRegion("6a_boss-16_east", "6a_boss-16", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-16_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-16_east"]), + + "6a_boss-17_west": PreRegion("6a_boss-17_west", "6a_boss-17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-17_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-17_west"]), + "6a_boss-17_east": PreRegion("6a_boss-17_east", "6a_boss-17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-17_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-17_east"]), + + "6a_boss-18_west": PreRegion("6a_boss-18_west", "6a_boss-18", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-18_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-18_west"]), + "6a_boss-18_east": PreRegion("6a_boss-18_east", "6a_boss-18", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-18_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-18_east"]), + + "6a_boss-19_west": PreRegion("6a_boss-19_west", "6a_boss-19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-19_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-19_west"]), + "6a_boss-19_east": PreRegion("6a_boss-19_east", "6a_boss-19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-19_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-19_east"]), + + "6a_boss-20_west": PreRegion("6a_boss-20_west", "6a_boss-20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-20_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-20_west"]), + "6a_boss-20_east": PreRegion("6a_boss-20_east", "6a_boss-20", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_boss-20_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_boss-20_east"]), + + "6a_after-00_bottom": PreRegion("6a_after-00_bottom", "6a_after-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_after-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_after-00_bottom"]), + "6a_after-00_top": PreRegion("6a_after-00_top", "6a_after-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_after-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_after-00_top"]), + + "6a_after-01_bottom": PreRegion("6a_after-01_bottom", "6a_after-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_after-01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_after-01_bottom"]), + "6a_after-01_goal": PreRegion("6a_after-01_goal", "6a_after-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6a_after-01_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "6a_after-01_goal"]), + + "6b_a-00_bottom": PreRegion("6b_a-00_bottom", "6b_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-00_bottom"]), + "6b_a-00_top": PreRegion("6b_a-00_top", "6b_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-00_top"]), + + "6b_a-01_bottom": PreRegion("6b_a-01_bottom", "6b_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-01_bottom"]), + "6b_a-01_top": PreRegion("6b_a-01_top", "6b_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-01_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-01_top"]), + + "6b_a-02_bottom": PreRegion("6b_a-02_bottom", "6b_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-02_bottom"]), + "6b_a-02_top": PreRegion("6b_a-02_top", "6b_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-02_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-02_top"]), + + "6b_a-03_west": PreRegion("6b_a-03_west", "6b_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-03_west"]), + "6b_a-03_east": PreRegion("6b_a-03_east", "6b_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-03_east"]), + + "6b_a-04_west": PreRegion("6b_a-04_west", "6b_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-04_west"]), + "6b_a-04_east": PreRegion("6b_a-04_east", "6b_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-04_east"]), + + "6b_a-05_west": PreRegion("6b_a-05_west", "6b_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-05_west"]), + "6b_a-05_east": PreRegion("6b_a-05_east", "6b_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-05_east"]), + + "6b_a-06_west": PreRegion("6b_a-06_west", "6b_a-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-06_west"]), + "6b_a-06_east": PreRegion("6b_a-06_east", "6b_a-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_a-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_a-06_east"]), + + "6b_b-00_west": PreRegion("6b_b-00_west", "6b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-00_west"]), + "6b_b-00_east": PreRegion("6b_b-00_east", "6b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-00_east"]), + + "6b_b-01_top": PreRegion("6b_b-01_top", "6b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-01_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-01_top"]), + "6b_b-01_bottom": PreRegion("6b_b-01_bottom", "6b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-01_bottom"]), + + "6b_b-02_top": PreRegion("6b_b-02_top", "6b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-02_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-02_top"]), + "6b_b-02_bottom": PreRegion("6b_b-02_bottom", "6b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-02_bottom"]), + + "6b_b-03_top": PreRegion("6b_b-03_top", "6b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-03_top"]), + "6b_b-03_bottom": PreRegion("6b_b-03_bottom", "6b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-03_bottom"]), + + "6b_b-04_top": PreRegion("6b_b-04_top", "6b_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-04_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-04_top"]), + "6b_b-04_bottom": PreRegion("6b_b-04_bottom", "6b_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-04_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-04_bottom"]), + + "6b_b-05_top": PreRegion("6b_b-05_top", "6b_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-05_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-05_top"]), + "6b_b-05_bottom": PreRegion("6b_b-05_bottom", "6b_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-05_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-05_bottom"]), + + "6b_b-06_top": PreRegion("6b_b-06_top", "6b_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-06_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-06_top"]), + "6b_b-06_bottom": PreRegion("6b_b-06_bottom", "6b_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-06_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-06_bottom"]), + + "6b_b-07_top": PreRegion("6b_b-07_top", "6b_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-07_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-07_top"]), + "6b_b-07_bottom": PreRegion("6b_b-07_bottom", "6b_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-07_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-07_bottom"]), + + "6b_b-08_top": PreRegion("6b_b-08_top", "6b_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-08_top"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-08_top"]), + "6b_b-08_bottom": PreRegion("6b_b-08_bottom", "6b_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-08_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-08_bottom"]), + + "6b_b-10_west": PreRegion("6b_b-10_west", "6b_b-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-10_west"]), + "6b_b-10_east": PreRegion("6b_b-10_east", "6b_b-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_b-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_b-10_east"]), + + "6b_c-00_west": PreRegion("6b_c-00_west", "6b_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_c-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_c-00_west"]), + "6b_c-00_east": PreRegion("6b_c-00_east", "6b_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_c-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_c-00_east"]), + + "6b_c-01_west": PreRegion("6b_c-01_west", "6b_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_c-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_c-01_west"]), + "6b_c-01_east": PreRegion("6b_c-01_east", "6b_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_c-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_c-01_east"]), + + "6b_c-02_west": PreRegion("6b_c-02_west", "6b_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_c-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_c-02_west"]), + "6b_c-02_east": PreRegion("6b_c-02_east", "6b_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_c-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_c-02_east"]), + + "6b_c-03_west": PreRegion("6b_c-03_west", "6b_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_c-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_c-03_west"]), + "6b_c-03_east": PreRegion("6b_c-03_east", "6b_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_c-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_c-03_east"]), + + "6b_c-04_west": PreRegion("6b_c-04_west", "6b_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_c-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_c-04_west"]), + "6b_c-04_east": PreRegion("6b_c-04_east", "6b_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_c-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_c-04_east"]), + + "6b_d-00_west": PreRegion("6b_d-00_west", "6b_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-00_west"]), + "6b_d-00_east": PreRegion("6b_d-00_east", "6b_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-00_east"]), + + "6b_d-01_west": PreRegion("6b_d-01_west", "6b_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-01_west"]), + "6b_d-01_east": PreRegion("6b_d-01_east", "6b_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-01_east"]), + + "6b_d-02_west": PreRegion("6b_d-02_west", "6b_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-02_west"]), + "6b_d-02_east": PreRegion("6b_d-02_east", "6b_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-02_east"]), + + "6b_d-03_west": PreRegion("6b_d-03_west", "6b_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-03_west"]), + "6b_d-03_east": PreRegion("6b_d-03_east", "6b_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-03_east"]), + + "6b_d-04_west": PreRegion("6b_d-04_west", "6b_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-04_west"]), + "6b_d-04_east": PreRegion("6b_d-04_east", "6b_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-04_east"]), + + "6b_d-05_west": PreRegion("6b_d-05_west", "6b_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-05_west"]), + "6b_d-05_goal": PreRegion("6b_d-05_goal", "6b_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6b_d-05_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "6b_d-05_goal"]), + + "6c_00_west": PreRegion("6c_00_west", "6c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6c_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6c_00_west"]), + "6c_00_east": PreRegion("6c_00_east", "6c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6c_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6c_00_east"]), + + "6c_01_west": PreRegion("6c_01_west", "6c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6c_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6c_01_west"]), + "6c_01_east": PreRegion("6c_01_east", "6c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6c_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "6c_01_east"]), + + "6c_02_west": PreRegion("6c_02_west", "6c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6c_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "6c_02_west"]), + "6c_02_goal": PreRegion("6c_02_goal", "6c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "6c_02_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "6c_02_goal"]), + + "7a_a-00_west": PreRegion("7a_a-00_west", "7a_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-00_west"]), + "7a_a-00_east": PreRegion("7a_a-00_east", "7a_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-00_east"]), + + "7a_a-01_west": PreRegion("7a_a-01_west", "7a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-01_west"]), + "7a_a-01_east": PreRegion("7a_a-01_east", "7a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-01_east"]), + + "7a_a-02_west": PreRegion("7a_a-02_west", "7a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-02_west"]), + "7a_a-02_east": PreRegion("7a_a-02_east", "7a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-02_east"]), + "7a_a-02_north": PreRegion("7a_a-02_north", "7a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-02_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-02_north"]), + "7a_a-02_north-west": PreRegion("7a_a-02_north-west", "7a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-02_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-02_north-west"]), + + "7a_a-02b_east": PreRegion("7a_a-02b_east", "7a_a-02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-02b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-02b_east"]), + "7a_a-02b_west": PreRegion("7a_a-02b_west", "7a_a-02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-02b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-02b_west"]), + + "7a_a-03_west": PreRegion("7a_a-03_west", "7a_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-03_west"]), + "7a_a-03_east": PreRegion("7a_a-03_east", "7a_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-03_east"]), + + "7a_a-04_west": PreRegion("7a_a-04_west", "7a_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-04_west"]), + "7a_a-04_north": PreRegion("7a_a-04_north", "7a_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-04_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-04_north"]), + "7a_a-04_east": PreRegion("7a_a-04_east", "7a_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-04_east"]), + + "7a_a-04b_east": PreRegion("7a_a-04b_east", "7a_a-04b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-04b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-04b_east"]), + + "7a_a-05_west": PreRegion("7a_a-05_west", "7a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-05_west"]), + "7a_a-05_east": PreRegion("7a_a-05_east", "7a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-05_east"]), + + "7a_a-06_bottom": PreRegion("7a_a-06_bottom", "7a_a-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-06_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-06_bottom"]), + "7a_a-06_top": PreRegion("7a_a-06_top", "7a_a-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-06_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-06_top"]), + "7a_a-06_top-side": PreRegion("7a_a-06_top-side", "7a_a-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_a-06_top-side"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_a-06_top-side"]), + + "7a_b-00_bottom": PreRegion("7a_b-00_bottom", "7a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-00_bottom"]), + "7a_b-00_top": PreRegion("7a_b-00_top", "7a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-00_top"]), + + "7a_b-01_west": PreRegion("7a_b-01_west", "7a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-01_west"]), + "7a_b-01_east": PreRegion("7a_b-01_east", "7a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-01_east"]), + + "7a_b-02_south": PreRegion("7a_b-02_south", "7a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02_south"]), + "7a_b-02_north-west": PreRegion("7a_b-02_north-west", "7a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02_north-west"]), + "7a_b-02_north": PreRegion("7a_b-02_north", "7a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02_north"]), + "7a_b-02_north-east": PreRegion("7a_b-02_north-east", "7a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02_north-east"]), + + "7a_b-02b_south": PreRegion("7a_b-02b_south", "7a_b-02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02b_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02b_south"]), + "7a_b-02b_north-west": PreRegion("7a_b-02b_north-west", "7a_b-02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02b_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02b_north-west"]), + "7a_b-02b_north-east": PreRegion("7a_b-02b_north-east", "7a_b-02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02b_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02b_north-east"]), + + "7a_b-02e_east": PreRegion("7a_b-02e_east", "7a_b-02e", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02e_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02e_east"]), + + "7a_b-02c_west": PreRegion("7a_b-02c_west", "7a_b-02c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02c_west"]), + "7a_b-02c_east": PreRegion("7a_b-02c_east", "7a_b-02c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02c_east"]), + "7a_b-02c_south-east": PreRegion("7a_b-02c_south-east", "7a_b-02c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02c_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02c_south-east"]), + + "7a_b-02d_north": PreRegion("7a_b-02d_north", "7a_b-02d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02d_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02d_north"]), + "7a_b-02d_south": PreRegion("7a_b-02d_south", "7a_b-02d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-02d_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-02d_south"]), + + "7a_b-03_west": PreRegion("7a_b-03_west", "7a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-03_west"]), + "7a_b-03_east": PreRegion("7a_b-03_east", "7a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-03_east"]), + "7a_b-03_north": PreRegion("7a_b-03_north", "7a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-03_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-03_north"]), + + "7a_b-04_west": PreRegion("7a_b-04_west", "7a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-04_west"]), + + "7a_b-05_west": PreRegion("7a_b-05_west", "7a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-05_west"]), + "7a_b-05_east": PreRegion("7a_b-05_east", "7a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-05_east"]), + "7a_b-05_north-west": PreRegion("7a_b-05_north-west", "7a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-05_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-05_north-west"]), + + "7a_b-06_west": PreRegion("7a_b-06_west", "7a_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-06_west"]), + "7a_b-06_east": PreRegion("7a_b-06_east", "7a_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-06_east"]), + + "7a_b-07_west": PreRegion("7a_b-07_west", "7a_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-07_west"]), + "7a_b-07_east": PreRegion("7a_b-07_east", "7a_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-07_east"]), + + "7a_b-08_west": PreRegion("7a_b-08_west", "7a_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-08_west"]), + "7a_b-08_east": PreRegion("7a_b-08_east", "7a_b-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-08_east"]), + + "7a_b-09_bottom": PreRegion("7a_b-09_bottom", "7a_b-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-09_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-09_bottom"]), + "7a_b-09_top": PreRegion("7a_b-09_top", "7a_b-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-09_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-09_top"]), + "7a_b-09_top-side": PreRegion("7a_b-09_top-side", "7a_b-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_b-09_top-side"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_b-09_top-side"]), + + "7a_c-00_west": PreRegion("7a_c-00_west", "7a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-00_west"]), + "7a_c-00_east": PreRegion("7a_c-00_east", "7a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-00_east"]), + + "7a_c-01_bottom": PreRegion("7a_c-01_bottom", "7a_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-01_bottom"]), + "7a_c-01_top": PreRegion("7a_c-01_top", "7a_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-01_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-01_top"]), + + "7a_c-02_bottom": PreRegion("7a_c-02_bottom", "7a_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-02_bottom"]), + "7a_c-02_top": PreRegion("7a_c-02_top", "7a_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-02_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-02_top"]), + + "7a_c-03_south": PreRegion("7a_c-03_south", "7a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-03_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-03_south"]), + "7a_c-03_west": PreRegion("7a_c-03_west", "7a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-03_west"]), + "7a_c-03_east": PreRegion("7a_c-03_east", "7a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-03_east"]), + + "7a_c-03b_east": PreRegion("7a_c-03b_east", "7a_c-03b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-03b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-03b_east"]), + + "7a_c-04_west": PreRegion("7a_c-04_west", "7a_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-04_west"]), + "7a_c-04_north-west": PreRegion("7a_c-04_north-west", "7a_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-04_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-04_north-west"]), + "7a_c-04_north-east": PreRegion("7a_c-04_north-east", "7a_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-04_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-04_north-east"]), + "7a_c-04_east": PreRegion("7a_c-04_east", "7a_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-04_east"]), + + "7a_c-05_west": PreRegion("7a_c-05_west", "7a_c-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-05_west"]), + + "7a_c-06_south": PreRegion("7a_c-06_south", "7a_c-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-06_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-06_south"]), + "7a_c-06_north": PreRegion("7a_c-06_north", "7a_c-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-06_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-06_north"]), + "7a_c-06_east": PreRegion("7a_c-06_east", "7a_c-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-06_east"]), + + "7a_c-06b_south": PreRegion("7a_c-06b_south", "7a_c-06b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-06b_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-06b_south"]), + "7a_c-06b_north": PreRegion("7a_c-06b_north", "7a_c-06b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-06b_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-06b_north"]), + "7a_c-06b_west": PreRegion("7a_c-06b_west", "7a_c-06b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-06b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-06b_west"]), + "7a_c-06b_east": PreRegion("7a_c-06b_east", "7a_c-06b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-06b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-06b_east"]), + + "7a_c-06c_west": PreRegion("7a_c-06c_west", "7a_c-06c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-06c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-06c_west"]), + + "7a_c-07_west": PreRegion("7a_c-07_west", "7a_c-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-07_west"]), + "7a_c-07_south-west": PreRegion("7a_c-07_south-west", "7a_c-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-07_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-07_south-west"]), + "7a_c-07_south-east": PreRegion("7a_c-07_south-east", "7a_c-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-07_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-07_south-east"]), + "7a_c-07_east": PreRegion("7a_c-07_east", "7a_c-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-07_east"]), + + "7a_c-07b_east": PreRegion("7a_c-07b_east", "7a_c-07b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-07b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-07b_east"]), + + "7a_c-08_west": PreRegion("7a_c-08_west", "7a_c-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-08_west"]), + "7a_c-08_east": PreRegion("7a_c-08_east", "7a_c-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-08_east"]), + + "7a_c-09_bottom": PreRegion("7a_c-09_bottom", "7a_c-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-09_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-09_bottom"]), + "7a_c-09_top": PreRegion("7a_c-09_top", "7a_c-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_c-09_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_c-09_top"]), + + "7a_d-00_bottom": PreRegion("7a_d-00_bottom", "7a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-00_bottom"]), + "7a_d-00_top": PreRegion("7a_d-00_top", "7a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-00_top"]), + + "7a_d-01_west": PreRegion("7a_d-01_west", "7a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01_west"]), + "7a_d-01_east": PreRegion("7a_d-01_east", "7a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01_east"]), + + "7a_d-01b_west": PreRegion("7a_d-01b_west", "7a_d-01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01b_west"]), + "7a_d-01b_south-west": PreRegion("7a_d-01b_south-west", "7a_d-01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01b_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01b_south-west"]), + "7a_d-01b_east": PreRegion("7a_d-01b_east", "7a_d-01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01b_east"]), + "7a_d-01b_south-east": PreRegion("7a_d-01b_south-east", "7a_d-01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01b_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01b_south-east"]), + + "7a_d-01c_west": PreRegion("7a_d-01c_west", "7a_d-01c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01c_west"]), + "7a_d-01c_south": PreRegion("7a_d-01c_south", "7a_d-01c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01c_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01c_south"]), + "7a_d-01c_east": PreRegion("7a_d-01c_east", "7a_d-01c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01c_east"]), + "7a_d-01c_south-east": PreRegion("7a_d-01c_south-east", "7a_d-01c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01c_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01c_south-east"]), + + "7a_d-01d_west": PreRegion("7a_d-01d_west", "7a_d-01d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01d_west"]), + "7a_d-01d_east": PreRegion("7a_d-01d_east", "7a_d-01d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-01d_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-01d_east"]), + + "7a_d-02_west": PreRegion("7a_d-02_west", "7a_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-02_west"]), + "7a_d-02_east": PreRegion("7a_d-02_east", "7a_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-02_east"]), + + "7a_d-03_west": PreRegion("7a_d-03_west", "7a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-03_west"]), + "7a_d-03_north-west": PreRegion("7a_d-03_north-west", "7a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-03_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-03_north-west"]), + "7a_d-03_east": PreRegion("7a_d-03_east", "7a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-03_east"]), + "7a_d-03_north-east": PreRegion("7a_d-03_north-east", "7a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-03_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-03_north-east"]), + + "7a_d-03b_west": PreRegion("7a_d-03b_west", "7a_d-03b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-03b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-03b_west"]), + "7a_d-03b_east": PreRegion("7a_d-03b_east", "7a_d-03b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-03b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-03b_east"]), + + "7a_d-04_west": PreRegion("7a_d-04_west", "7a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-04_west"]), + "7a_d-04_east": PreRegion("7a_d-04_east", "7a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-04_east"]), + + "7a_d-05_west": PreRegion("7a_d-05_west", "7a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-05_west"]), + "7a_d-05_north-east": PreRegion("7a_d-05_north-east", "7a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-05_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-05_north-east"]), + "7a_d-05_east": PreRegion("7a_d-05_east", "7a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-05_east"]), + + "7a_d-05b_west": PreRegion("7a_d-05b_west", "7a_d-05b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-05b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-05b_west"]), + + "7a_d-06_west": PreRegion("7a_d-06_west", "7a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-06_west"]), + "7a_d-06_south-west": PreRegion("7a_d-06_south-west", "7a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-06_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-06_south-west"]), + "7a_d-06_south-east": PreRegion("7a_d-06_south-east", "7a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-06_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-06_south-east"]), + "7a_d-06_east": PreRegion("7a_d-06_east", "7a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-06_east"]), + + "7a_d-07_east": PreRegion("7a_d-07_east", "7a_d-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-07_east"]), + + "7a_d-08_west": PreRegion("7a_d-08_west", "7a_d-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-08_west"]), + "7a_d-08_east": PreRegion("7a_d-08_east", "7a_d-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-08_east"]), + + "7a_d-09_west": PreRegion("7a_d-09_west", "7a_d-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-09_west"]), + "7a_d-09_east": PreRegion("7a_d-09_east", "7a_d-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-09_east"]), + + "7a_d-10_west": PreRegion("7a_d-10_west", "7a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-10_west"]), + "7a_d-10_north-west": PreRegion("7a_d-10_north-west", "7a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-10_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-10_north-west"]), + "7a_d-10_north": PreRegion("7a_d-10_north", "7a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-10_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-10_north"]), + "7a_d-10_north-east": PreRegion("7a_d-10_north-east", "7a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-10_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-10_north-east"]), + "7a_d-10_east": PreRegion("7a_d-10_east", "7a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-10_east"]), + + "7a_d-10b_west": PreRegion("7a_d-10b_west", "7a_d-10b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-10b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-10b_west"]), + "7a_d-10b_east": PreRegion("7a_d-10b_east", "7a_d-10b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-10b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-10b_east"]), + + "7a_d-11_bottom": PreRegion("7a_d-11_bottom", "7a_d-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-11_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-11_bottom"]), + "7a_d-11_top": PreRegion("7a_d-11_top", "7a_d-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_d-11_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_d-11_top"]), + + "7a_e-00b_bottom": PreRegion("7a_e-00b_bottom", "7a_e-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-00b_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-00b_bottom"]), + "7a_e-00b_top": PreRegion("7a_e-00b_top", "7a_e-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-00b_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-00b_top"]), + + "7a_e-00_west": PreRegion("7a_e-00_west", "7a_e-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-00_west"]), + "7a_e-00_south-west": PreRegion("7a_e-00_south-west", "7a_e-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-00_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-00_south-west"]), + "7a_e-00_north-west": PreRegion("7a_e-00_north-west", "7a_e-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-00_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-00_north-west"]), + "7a_e-00_east": PreRegion("7a_e-00_east", "7a_e-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-00_east"]), + + "7a_e-01_west": PreRegion("7a_e-01_west", "7a_e-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-01_west"]), + "7a_e-01_north": PreRegion("7a_e-01_north", "7a_e-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-01_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-01_north"]), + "7a_e-01_east": PreRegion("7a_e-01_east", "7a_e-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-01_east"]), + + "7a_e-01b_west": PreRegion("7a_e-01b_west", "7a_e-01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-01b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-01b_west"]), + "7a_e-01b_east": PreRegion("7a_e-01b_east", "7a_e-01b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-01b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-01b_east"]), + + "7a_e-01c_west": PreRegion("7a_e-01c_west", "7a_e-01c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-01c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-01c_west"]), + "7a_e-01c_east": PreRegion("7a_e-01c_east", "7a_e-01c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-01c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-01c_east"]), + + "7a_e-02_west": PreRegion("7a_e-02_west", "7a_e-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-02_west"]), + "7a_e-02_east": PreRegion("7a_e-02_east", "7a_e-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-02_east"]), + + "7a_e-03_south-west": PreRegion("7a_e-03_south-west", "7a_e-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-03_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-03_south-west"]), + "7a_e-03_west": PreRegion("7a_e-03_west", "7a_e-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-03_west"]), + "7a_e-03_east": PreRegion("7a_e-03_east", "7a_e-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-03_east"]), + + "7a_e-04_west": PreRegion("7a_e-04_west", "7a_e-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-04_west"]), + "7a_e-04_east": PreRegion("7a_e-04_east", "7a_e-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-04_east"]), + + "7a_e-05_west": PreRegion("7a_e-05_west", "7a_e-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-05_west"]), + "7a_e-05_east": PreRegion("7a_e-05_east", "7a_e-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-05_east"]), + + "7a_e-06_west": PreRegion("7a_e-06_west", "7a_e-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-06_west"]), + "7a_e-06_east": PreRegion("7a_e-06_east", "7a_e-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-06_east"]), + + "7a_e-07_bottom": PreRegion("7a_e-07_bottom", "7a_e-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-07_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-07_bottom"]), + "7a_e-07_top": PreRegion("7a_e-07_top", "7a_e-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-07_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-07_top"]), + + "7a_e-08_south": PreRegion("7a_e-08_south", "7a_e-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-08_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-08_south"]), + "7a_e-08_west": PreRegion("7a_e-08_west", "7a_e-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-08_west"]), + "7a_e-08_east": PreRegion("7a_e-08_east", "7a_e-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-08_east"]), + + "7a_e-09_north": PreRegion("7a_e-09_north", "7a_e-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-09_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-09_north"]), + "7a_e-09_east": PreRegion("7a_e-09_east", "7a_e-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-09_east"]), + + "7a_e-11_south": PreRegion("7a_e-11_south", "7a_e-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-11_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-11_south"]), + "7a_e-11_north": PreRegion("7a_e-11_north", "7a_e-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-11_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-11_north"]), + "7a_e-11_east": PreRegion("7a_e-11_east", "7a_e-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-11_east"]), + + "7a_e-12_west": PreRegion("7a_e-12_west", "7a_e-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-12_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-12_west"]), + + "7a_e-10_south": PreRegion("7a_e-10_south", "7a_e-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-10_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-10_south"]), + "7a_e-10_north": PreRegion("7a_e-10_north", "7a_e-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-10_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-10_north"]), + "7a_e-10_east": PreRegion("7a_e-10_east", "7a_e-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-10_east"]), + + "7a_e-10b_west": PreRegion("7a_e-10b_west", "7a_e-10b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-10b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-10b_west"]), + "7a_e-10b_east": PreRegion("7a_e-10b_east", "7a_e-10b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-10b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-10b_east"]), + + "7a_e-13_bottom": PreRegion("7a_e-13_bottom", "7a_e-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-13_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-13_bottom"]), + "7a_e-13_top": PreRegion("7a_e-13_top", "7a_e-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_e-13_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_e-13_top"]), + + "7a_f-00_south": PreRegion("7a_f-00_south", "7a_f-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-00_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-00_south"]), + "7a_f-00_west": PreRegion("7a_f-00_west", "7a_f-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-00_west"]), + "7a_f-00_north-west": PreRegion("7a_f-00_north-west", "7a_f-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-00_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-00_north-west"]), + "7a_f-00_north-east": PreRegion("7a_f-00_north-east", "7a_f-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-00_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-00_north-east"]), + "7a_f-00_east": PreRegion("7a_f-00_east", "7a_f-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-00_east"]), + + "7a_f-01_south": PreRegion("7a_f-01_south", "7a_f-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-01_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-01_south"]), + "7a_f-01_north": PreRegion("7a_f-01_north", "7a_f-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-01_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-01_north"]), + + "7a_f-02_west": PreRegion("7a_f-02_west", "7a_f-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-02_west"]), + "7a_f-02_north-west": PreRegion("7a_f-02_north-west", "7a_f-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-02_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-02_north-west"]), + "7a_f-02_north-east": PreRegion("7a_f-02_north-east", "7a_f-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-02_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-02_north-east"]), + "7a_f-02_east": PreRegion("7a_f-02_east", "7a_f-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-02_east"]), + + "7a_f-02b_west": PreRegion("7a_f-02b_west", "7a_f-02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-02b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-02b_west"]), + "7a_f-02b_east": PreRegion("7a_f-02b_east", "7a_f-02b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-02b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-02b_east"]), + + "7a_f-04_west": PreRegion("7a_f-04_west", "7a_f-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-04_west"]), + "7a_f-04_east": PreRegion("7a_f-04_east", "7a_f-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-04_east"]), + + "7a_f-03_west": PreRegion("7a_f-03_west", "7a_f-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-03_west"]), + "7a_f-03_east": PreRegion("7a_f-03_east", "7a_f-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-03_east"]), + + "7a_f-05_west": PreRegion("7a_f-05_west", "7a_f-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-05_west"]), + "7a_f-05_south-west": PreRegion("7a_f-05_south-west", "7a_f-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-05_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-05_south-west"]), + "7a_f-05_north-west": PreRegion("7a_f-05_north-west", "7a_f-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-05_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-05_north-west"]), + "7a_f-05_south": PreRegion("7a_f-05_south", "7a_f-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-05_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-05_south"]), + "7a_f-05_north": PreRegion("7a_f-05_north", "7a_f-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-05_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-05_north"]), + "7a_f-05_north-east": PreRegion("7a_f-05_north-east", "7a_f-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-05_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-05_north-east"]), + "7a_f-05_south-east": PreRegion("7a_f-05_south-east", "7a_f-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-05_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-05_south-east"]), + "7a_f-05_east": PreRegion("7a_f-05_east", "7a_f-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-05_east"]), + + "7a_f-06_north-west": PreRegion("7a_f-06_north-west", "7a_f-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-06_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-06_north-west"]), + "7a_f-06_north": PreRegion("7a_f-06_north", "7a_f-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-06_north"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-06_north"]), + "7a_f-06_north-east": PreRegion("7a_f-06_north-east", "7a_f-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-06_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-06_north-east"]), + + "7a_f-07_west": PreRegion("7a_f-07_west", "7a_f-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-07_west"]), + "7a_f-07_south-west": PreRegion("7a_f-07_south-west", "7a_f-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-07_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-07_south-west"]), + "7a_f-07_south": PreRegion("7a_f-07_south", "7a_f-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-07_south"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-07_south"]), + "7a_f-07_south-east": PreRegion("7a_f-07_south-east", "7a_f-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-07_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-07_south-east"]), + + "7a_f-08_west": PreRegion("7a_f-08_west", "7a_f-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-08_west"]), + "7a_f-08_north-west": PreRegion("7a_f-08_north-west", "7a_f-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-08_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-08_north-west"]), + "7a_f-08_east": PreRegion("7a_f-08_east", "7a_f-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-08_east"]), + + "7a_f-08b_west": PreRegion("7a_f-08b_west", "7a_f-08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-08b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-08b_west"]), + "7a_f-08b_east": PreRegion("7a_f-08b_east", "7a_f-08b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-08b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-08b_east"]), + + "7a_f-08d_west": PreRegion("7a_f-08d_west", "7a_f-08d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-08d_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-08d_west"]), + "7a_f-08d_east": PreRegion("7a_f-08d_east", "7a_f-08d", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-08d_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-08d_east"]), + + "7a_f-08c_west": PreRegion("7a_f-08c_west", "7a_f-08c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-08c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-08c_west"]), + "7a_f-08c_east": PreRegion("7a_f-08c_east", "7a_f-08c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-08c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-08c_east"]), + + "7a_f-09_west": PreRegion("7a_f-09_west", "7a_f-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-09_west"]), + "7a_f-09_east": PreRegion("7a_f-09_east", "7a_f-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-09_east"]), + + "7a_f-10_west": PreRegion("7a_f-10_west", "7a_f-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-10_west"]), + "7a_f-10_north-east": PreRegion("7a_f-10_north-east", "7a_f-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-10_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-10_north-east"]), + "7a_f-10_east": PreRegion("7a_f-10_east", "7a_f-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-10_east"]), + + "7a_f-10b_west": PreRegion("7a_f-10b_west", "7a_f-10b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-10b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-10b_west"]), + "7a_f-10b_east": PreRegion("7a_f-10b_east", "7a_f-10b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-10b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-10b_east"]), + + "7a_f-11_bottom": PreRegion("7a_f-11_bottom", "7a_f-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-11_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-11_bottom"]), + "7a_f-11_top": PreRegion("7a_f-11_top", "7a_f-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_f-11_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_f-11_top"]), + + "7a_g-00_bottom": PreRegion("7a_g-00_bottom", "7a_g-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-00_bottom"]), + "7a_g-00_top": PreRegion("7a_g-00_top", "7a_g-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-00_top"]), + + "7a_g-00b_bottom": PreRegion("7a_g-00b_bottom", "7a_g-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-00b_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-00b_bottom"]), + "7a_g-00b_c26": PreRegion("7a_g-00b_c26", "7a_g-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-00b_c26"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-00b_c26"]), + "7a_g-00b_c24": PreRegion("7a_g-00b_c24", "7a_g-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-00b_c24"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-00b_c24"]), + "7a_g-00b_c21": PreRegion("7a_g-00b_c21", "7a_g-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-00b_c21"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-00b_c21"]), + "7a_g-00b_top": PreRegion("7a_g-00b_top", "7a_g-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-00b_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-00b_top"]), + + "7a_g-01_bottom": PreRegion("7a_g-01_bottom", "7a_g-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-01_bottom"]), + "7a_g-01_c18": PreRegion("7a_g-01_c18", "7a_g-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-01_c18"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-01_c18"]), + "7a_g-01_c16": PreRegion("7a_g-01_c16", "7a_g-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-01_c16"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-01_c16"]), + "7a_g-01_top": PreRegion("7a_g-01_top", "7a_g-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-01_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-01_top"]), + + "7a_g-02_bottom": PreRegion("7a_g-02_bottom", "7a_g-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-02_bottom"]), + "7a_g-02_top": PreRegion("7a_g-02_top", "7a_g-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-02_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-02_top"]), + + "7a_g-03_bottom": PreRegion("7a_g-03_bottom", "7a_g-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-03_bottom"]), + "7a_g-03_goal": PreRegion("7a_g-03_goal", "7a_g-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7a_g-03_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "7a_g-03_goal"]), + + "7b_a-00_west": PreRegion("7b_a-00_west", "7b_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_a-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_a-00_west"]), + "7b_a-00_east": PreRegion("7b_a-00_east", "7b_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_a-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_a-00_east"]), + + "7b_a-01_west": PreRegion("7b_a-01_west", "7b_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_a-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_a-01_west"]), + "7b_a-01_east": PreRegion("7b_a-01_east", "7b_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_a-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_a-01_east"]), + + "7b_a-02_west": PreRegion("7b_a-02_west", "7b_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_a-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_a-02_west"]), + "7b_a-02_east": PreRegion("7b_a-02_east", "7b_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_a-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_a-02_east"]), + + "7b_a-03_bottom": PreRegion("7b_a-03_bottom", "7b_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_a-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_a-03_bottom"]), + "7b_a-03_top": PreRegion("7b_a-03_top", "7b_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_a-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_a-03_top"]), + + "7b_b-00_bottom": PreRegion("7b_b-00_bottom", "7b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_b-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_b-00_bottom"]), + "7b_b-00_top": PreRegion("7b_b-00_top", "7b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_b-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_b-00_top"]), + + "7b_b-01_bottom": PreRegion("7b_b-01_bottom", "7b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_b-01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_b-01_bottom"]), + "7b_b-01_top": PreRegion("7b_b-01_top", "7b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_b-01_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_b-01_top"]), + + "7b_b-02_west": PreRegion("7b_b-02_west", "7b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_b-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_b-02_west"]), + "7b_b-02_east": PreRegion("7b_b-02_east", "7b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_b-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_b-02_east"]), + + "7b_b-03_bottom": PreRegion("7b_b-03_bottom", "7b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_b-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_b-03_bottom"]), + "7b_b-03_top": PreRegion("7b_b-03_top", "7b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_b-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_b-03_top"]), + + "7b_c-01_west": PreRegion("7b_c-01_west", "7b_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_c-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_c-01_west"]), + "7b_c-01_east": PreRegion("7b_c-01_east", "7b_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_c-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_c-01_east"]), + + "7b_c-00_west": PreRegion("7b_c-00_west", "7b_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_c-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_c-00_west"]), + "7b_c-00_east": PreRegion("7b_c-00_east", "7b_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_c-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_c-00_east"]), + + "7b_c-02_west": PreRegion("7b_c-02_west", "7b_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_c-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_c-02_west"]), + "7b_c-02_east": PreRegion("7b_c-02_east", "7b_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_c-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_c-02_east"]), + + "7b_c-03_bottom": PreRegion("7b_c-03_bottom", "7b_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_c-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_c-03_bottom"]), + "7b_c-03_top": PreRegion("7b_c-03_top", "7b_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_c-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_c-03_top"]), + + "7b_d-00_west": PreRegion("7b_d-00_west", "7b_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_d-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_d-00_west"]), + "7b_d-00_east": PreRegion("7b_d-00_east", "7b_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_d-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_d-00_east"]), + + "7b_d-01_west": PreRegion("7b_d-01_west", "7b_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_d-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_d-01_west"]), + "7b_d-01_east": PreRegion("7b_d-01_east", "7b_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_d-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_d-01_east"]), + + "7b_d-02_west": PreRegion("7b_d-02_west", "7b_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_d-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_d-02_west"]), + "7b_d-02_east": PreRegion("7b_d-02_east", "7b_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_d-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_d-02_east"]), + + "7b_d-03_bottom": PreRegion("7b_d-03_bottom", "7b_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_d-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_d-03_bottom"]), + "7b_d-03_top": PreRegion("7b_d-03_top", "7b_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_d-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_d-03_top"]), + + "7b_e-00_west": PreRegion("7b_e-00_west", "7b_e-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_e-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_e-00_west"]), + "7b_e-00_east": PreRegion("7b_e-00_east", "7b_e-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_e-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_e-00_east"]), + + "7b_e-01_west": PreRegion("7b_e-01_west", "7b_e-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_e-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_e-01_west"]), + "7b_e-01_east": PreRegion("7b_e-01_east", "7b_e-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_e-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_e-01_east"]), + + "7b_e-02_west": PreRegion("7b_e-02_west", "7b_e-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_e-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_e-02_west"]), + "7b_e-02_east": PreRegion("7b_e-02_east", "7b_e-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_e-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_e-02_east"]), + + "7b_e-03_bottom": PreRegion("7b_e-03_bottom", "7b_e-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_e-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_e-03_bottom"]), + "7b_e-03_top": PreRegion("7b_e-03_top", "7b_e-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_e-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_e-03_top"]), + + "7b_f-00_west": PreRegion("7b_f-00_west", "7b_f-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_f-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_f-00_west"]), + "7b_f-00_east": PreRegion("7b_f-00_east", "7b_f-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_f-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_f-00_east"]), + + "7b_f-01_west": PreRegion("7b_f-01_west", "7b_f-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_f-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_f-01_west"]), + "7b_f-01_east": PreRegion("7b_f-01_east", "7b_f-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_f-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_f-01_east"]), + + "7b_f-02_west": PreRegion("7b_f-02_west", "7b_f-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_f-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_f-02_west"]), + "7b_f-02_east": PreRegion("7b_f-02_east", "7b_f-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_f-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_f-02_east"]), + + "7b_f-03_bottom": PreRegion("7b_f-03_bottom", "7b_f-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_f-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_f-03_bottom"]), + "7b_f-03_top": PreRegion("7b_f-03_top", "7b_f-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_f-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_f-03_top"]), + + "7b_g-00_bottom": PreRegion("7b_g-00_bottom", "7b_g-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_g-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_g-00_bottom"]), + "7b_g-00_top": PreRegion("7b_g-00_top", "7b_g-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_g-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_g-00_top"]), + + "7b_g-01_bottom": PreRegion("7b_g-01_bottom", "7b_g-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_g-01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_g-01_bottom"]), + "7b_g-01_top": PreRegion("7b_g-01_top", "7b_g-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_g-01_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_g-01_top"]), + + "7b_g-02_bottom": PreRegion("7b_g-02_bottom", "7b_g-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_g-02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_g-02_bottom"]), + "7b_g-02_top": PreRegion("7b_g-02_top", "7b_g-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_g-02_top"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_g-02_top"]), + + "7b_g-03_bottom": PreRegion("7b_g-03_bottom", "7b_g-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_g-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_g-03_bottom"]), + "7b_g-03_goal": PreRegion("7b_g-03_goal", "7b_g-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7b_g-03_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "7b_g-03_goal"]), + + "7c_01_west": PreRegion("7c_01_west", "7c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7c_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7c_01_west"]), + "7c_01_east": PreRegion("7c_01_east", "7c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7c_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7c_01_east"]), + + "7c_02_west": PreRegion("7c_02_west", "7c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7c_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7c_02_west"]), + "7c_02_east": PreRegion("7c_02_east", "7c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7c_02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "7c_02_east"]), + + "7c_03_west": PreRegion("7c_03_west", "7c_03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7c_03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "7c_03_west"]), + "7c_03_goal": PreRegion("7c_03_goal", "7c_03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "7c_03_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "7c_03_goal"]), + + "8a_outside_east": PreRegion("8a_outside_east", "8a_outside", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "8a_outside_east"], [loc for _, loc in all_locations.items() if loc.region_name == "8a_outside_east"]), + + "8a_bridge_west": PreRegion("8a_bridge_west", "8a_bridge", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "8a_bridge_west"], [loc for _, loc in all_locations.items() if loc.region_name == "8a_bridge_west"]), + "8a_bridge_east": PreRegion("8a_bridge_east", "8a_bridge", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "8a_bridge_east"], [loc for _, loc in all_locations.items() if loc.region_name == "8a_bridge_east"]), + + "8a_secret_west": PreRegion("8a_secret_west", "8a_secret", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "8a_secret_west"], [loc for _, loc in all_locations.items() if loc.region_name == "8a_secret_west"]), + + "9a_00_west": PreRegion("9a_00_west", "9a_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_00_west"]), + "9a_00_east": PreRegion("9a_00_east", "9a_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_00_east"]), + + "9a_0x_east": PreRegion("9a_0x_east", "9a_0x", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_0x_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_0x_east"]), + + "9a_01_west": PreRegion("9a_01_west", "9a_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_01_west"]), + "9a_01_east": PreRegion("9a_01_east", "9a_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_01_east"]), + + "9a_02_west": PreRegion("9a_02_west", "9a_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_02_west"]), + "9a_02_east": PreRegion("9a_02_east", "9a_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_02_east"]), + + "9a_a-00_west": PreRegion("9a_a-00_west", "9a_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_a-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_a-00_west"]), + "9a_a-00_east": PreRegion("9a_a-00_east", "9a_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_a-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_a-00_east"]), + + "9a_a-01_west": PreRegion("9a_a-01_west", "9a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_a-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_a-01_west"]), + "9a_a-01_east": PreRegion("9a_a-01_east", "9a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_a-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_a-01_east"]), + + "9a_a-02_west": PreRegion("9a_a-02_west", "9a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_a-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_a-02_west"]), + "9a_a-02_east": PreRegion("9a_a-02_east", "9a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_a-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_a-02_east"]), + + "9a_a-03_bottom": PreRegion("9a_a-03_bottom", "9a_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_a-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_a-03_bottom"]), + "9a_a-03_top": PreRegion("9a_a-03_top", "9a_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_a-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_a-03_top"]), + + "9a_b-00_west": PreRegion("9a_b-00_west", "9a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-00_west"]), + "9a_b-00_south": PreRegion("9a_b-00_south", "9a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-00_south"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-00_south"]), + "9a_b-00_north": PreRegion("9a_b-00_north", "9a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-00_north"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-00_north"]), + "9a_b-00_east": PreRegion("9a_b-00_east", "9a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-00_east"]), + + "9a_b-01_west": PreRegion("9a_b-01_west", "9a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-01_west"]), + "9a_b-01_east": PreRegion("9a_b-01_east", "9a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-01_east"]), + + "9a_b-02_west": PreRegion("9a_b-02_west", "9a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-02_west"]), + "9a_b-02_east": PreRegion("9a_b-02_east", "9a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-02_east"]), + + "9a_b-03_west": PreRegion("9a_b-03_west", "9a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-03_west"]), + "9a_b-03_east": PreRegion("9a_b-03_east", "9a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-03_east"]), + + "9a_b-04_north-west": PreRegion("9a_b-04_north-west", "9a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-04_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-04_north-west"]), + "9a_b-04_west": PreRegion("9a_b-04_west", "9a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-04_west"]), + "9a_b-04_east": PreRegion("9a_b-04_east", "9a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-04_east"]), + + "9a_b-05_west": PreRegion("9a_b-05_west", "9a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-05_west"]), + "9a_b-05_east": PreRegion("9a_b-05_east", "9a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-05_east"]), + + "9a_b-06_east": PreRegion("9a_b-06_east", "9a_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-06_east"]), + + "9a_b-07b_bottom": PreRegion("9a_b-07b_bottom", "9a_b-07b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-07b_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-07b_bottom"]), + "9a_b-07b_top": PreRegion("9a_b-07b_top", "9a_b-07b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-07b_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-07b_top"]), + + "9a_b-07_bottom": PreRegion("9a_b-07_bottom", "9a_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-07_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-07_bottom"]), + "9a_b-07_top": PreRegion("9a_b-07_top", "9a_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_b-07_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_b-07_top"]), + + "9a_c-00_west": PreRegion("9a_c-00_west", "9a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-00_west"]), + "9a_c-00_north-east": PreRegion("9a_c-00_north-east", "9a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-00_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-00_north-east"]), + "9a_c-00_east": PreRegion("9a_c-00_east", "9a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-00_east"]), + + "9a_c-00b_west": PreRegion("9a_c-00b_west", "9a_c-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-00b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-00b_west"]), + + "9a_c-01_west": PreRegion("9a_c-01_west", "9a_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-01_west"]), + "9a_c-01_east": PreRegion("9a_c-01_east", "9a_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-01_east"]), + + "9a_c-02_west": PreRegion("9a_c-02_west", "9a_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-02_west"]), + "9a_c-02_east": PreRegion("9a_c-02_east", "9a_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-02_east"]), + + "9a_c-03_west": PreRegion("9a_c-03_west", "9a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-03_west"]), + "9a_c-03_north-west": PreRegion("9a_c-03_north-west", "9a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-03_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-03_north-west"]), + "9a_c-03_north": PreRegion("9a_c-03_north", "9a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-03_north"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-03_north"]), + "9a_c-03_north-east": PreRegion("9a_c-03_north-east", "9a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-03_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-03_north-east"]), + "9a_c-03_east": PreRegion("9a_c-03_east", "9a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-03_east"]), + + "9a_c-03b_west": PreRegion("9a_c-03b_west", "9a_c-03b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-03b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-03b_west"]), + "9a_c-03b_south": PreRegion("9a_c-03b_south", "9a_c-03b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-03b_south"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-03b_south"]), + "9a_c-03b_east": PreRegion("9a_c-03b_east", "9a_c-03b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-03b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-03b_east"]), + + "9a_c-04_west": PreRegion("9a_c-04_west", "9a_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-04_west"]), + "9a_c-04_east": PreRegion("9a_c-04_east", "9a_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_c-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_c-04_east"]), + + "9a_d-00_bottom": PreRegion("9a_d-00_bottom", "9a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-00_bottom"]), + "9a_d-00_top": PreRegion("9a_d-00_top", "9a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-00_top"]), + + "9a_d-01_bottom": PreRegion("9a_d-01_bottom", "9a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-01_bottom"]), + "9a_d-01_top": PreRegion("9a_d-01_top", "9a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-01_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-01_top"]), + + "9a_d-02_bottom": PreRegion("9a_d-02_bottom", "9a_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-02_bottom"]), + "9a_d-02_top": PreRegion("9a_d-02_top", "9a_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-02_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-02_top"]), + + "9a_d-03_bottom": PreRegion("9a_d-03_bottom", "9a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-03_bottom"]), + "9a_d-03_top": PreRegion("9a_d-03_top", "9a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-03_top"]), + + "9a_d-04_bottom": PreRegion("9a_d-04_bottom", "9a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-04_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-04_bottom"]), + "9a_d-04_top": PreRegion("9a_d-04_top", "9a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-04_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-04_top"]), + + "9a_d-05_bottom": PreRegion("9a_d-05_bottom", "9a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-05_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-05_bottom"]), + "9a_d-05_top": PreRegion("9a_d-05_top", "9a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-05_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-05_top"]), + + "9a_d-06_bottom": PreRegion("9a_d-06_bottom", "9a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-06_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-06_bottom"]), + "9a_d-06_top": PreRegion("9a_d-06_top", "9a_d-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-06_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-06_top"]), + + "9a_d-07_bottom": PreRegion("9a_d-07_bottom", "9a_d-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-07_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-07_bottom"]), + "9a_d-07_top": PreRegion("9a_d-07_top", "9a_d-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-07_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-07_top"]), + + "9a_d-08_west": PreRegion("9a_d-08_west", "9a_d-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-08_west"]), + "9a_d-08_east": PreRegion("9a_d-08_east", "9a_d-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-08_east"]), + + "9a_d-09_west": PreRegion("9a_d-09_west", "9a_d-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-09_west"]), + "9a_d-09_east": PreRegion("9a_d-09_east", "9a_d-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-09_east"]), + + "9a_d-10_west": PreRegion("9a_d-10_west", "9a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-10_west"]), + "9a_d-10_east": PreRegion("9a_d-10_east", "9a_d-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-10_east"]), + + "9a_d-10b_west": PreRegion("9a_d-10b_west", "9a_d-10b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-10b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-10b_west"]), + "9a_d-10b_east": PreRegion("9a_d-10b_east", "9a_d-10b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-10b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-10b_east"]), + + "9a_d-10c_west": PreRegion("9a_d-10c_west", "9a_d-10c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-10c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-10c_west"]), + "9a_d-10c_east": PreRegion("9a_d-10c_east", "9a_d-10c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-10c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-10c_east"]), + + "9a_d-11_west": PreRegion("9a_d-11_west", "9a_d-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-11_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-11_west"]), + "9a_d-11_center": PreRegion("9a_d-11_center", "9a_d-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-11_center"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-11_center"]), + "9a_d-11_east": PreRegion("9a_d-11_east", "9a_d-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_d-11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_d-11_east"]), + + "9a_space_west": PreRegion("9a_space_west", "9a_space", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_space_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_space_west"]), + "9a_space_goal": PreRegion("9a_space_goal", "9a_space", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9a_space_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "9a_space_goal"]), + + "9b_00_east": PreRegion("9b_00_east", "9b_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_00_east"]), + + "9b_01_west": PreRegion("9b_01_west", "9b_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_01_west"]), + "9b_01_east": PreRegion("9b_01_east", "9b_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_01_east"]), + + "9b_a-00_west": PreRegion("9b_a-00_west", "9b_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-00_west"]), + "9b_a-00_east": PreRegion("9b_a-00_east", "9b_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-00_east"]), + + "9b_a-01_west": PreRegion("9b_a-01_west", "9b_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-01_west"]), + "9b_a-01_east": PreRegion("9b_a-01_east", "9b_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-01_east"]), + + "9b_a-02_west": PreRegion("9b_a-02_west", "9b_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-02_west"]), + "9b_a-02_east": PreRegion("9b_a-02_east", "9b_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-02_east"]), + + "9b_a-03_west": PreRegion("9b_a-03_west", "9b_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-03_west"]), + "9b_a-03_east": PreRegion("9b_a-03_east", "9b_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-03_east"]), + + "9b_a-04_west": PreRegion("9b_a-04_west", "9b_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-04_west"]), + "9b_a-04_east": PreRegion("9b_a-04_east", "9b_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-04_east"]), + + "9b_a-05_west": PreRegion("9b_a-05_west", "9b_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-05_west"]), + "9b_a-05_east": PreRegion("9b_a-05_east", "9b_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_a-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_a-05_east"]), + + "9b_b-00_west": PreRegion("9b_b-00_west", "9b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-00_west"]), + "9b_b-00_east": PreRegion("9b_b-00_east", "9b_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-00_east"]), + + "9b_b-01_west": PreRegion("9b_b-01_west", "9b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-01_west"]), + "9b_b-01_east": PreRegion("9b_b-01_east", "9b_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-01_east"]), + + "9b_b-02_west": PreRegion("9b_b-02_west", "9b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-02_west"]), + "9b_b-02_east": PreRegion("9b_b-02_east", "9b_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-02_east"]), + + "9b_b-03_west": PreRegion("9b_b-03_west", "9b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-03_west"]), + "9b_b-03_east": PreRegion("9b_b-03_east", "9b_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-03_east"]), + + "9b_b-04_west": PreRegion("9b_b-04_west", "9b_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-04_west"]), + "9b_b-04_east": PreRegion("9b_b-04_east", "9b_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-04_east"]), + + "9b_b-05_west": PreRegion("9b_b-05_west", "9b_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-05_west"]), + "9b_b-05_east": PreRegion("9b_b-05_east", "9b_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_b-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_b-05_east"]), + + "9b_c-01_bottom": PreRegion("9b_c-01_bottom", "9b_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-01_bottom"]), + "9b_c-01_top": PreRegion("9b_c-01_top", "9b_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-01_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-01_top"]), + + "9b_c-02_bottom": PreRegion("9b_c-02_bottom", "9b_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-02_bottom"]), + "9b_c-02_top": PreRegion("9b_c-02_top", "9b_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-02_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-02_top"]), + + "9b_c-03_bottom": PreRegion("9b_c-03_bottom", "9b_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-03_bottom"]), + "9b_c-03_top": PreRegion("9b_c-03_top", "9b_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-03_top"]), + + "9b_c-04_bottom": PreRegion("9b_c-04_bottom", "9b_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-04_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-04_bottom"]), + "9b_c-04_top": PreRegion("9b_c-04_top", "9b_c-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-04_top"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-04_top"]), + + "9b_c-05_west": PreRegion("9b_c-05_west", "9b_c-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-05_west"]), + "9b_c-05_east": PreRegion("9b_c-05_east", "9b_c-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-05_east"]), + + "9b_c-06_west": PreRegion("9b_c-06_west", "9b_c-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-06_west"]), + "9b_c-06_east": PreRegion("9b_c-06_east", "9b_c-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-06_east"]), + + "9b_c-08_west": PreRegion("9b_c-08_west", "9b_c-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-08_west"]), + "9b_c-08_east": PreRegion("9b_c-08_east", "9b_c-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-08_east"]), + + "9b_c-07_west": PreRegion("9b_c-07_west", "9b_c-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-07_west"]), + "9b_c-07_east": PreRegion("9b_c-07_east", "9b_c-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_c-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_c-07_east"]), + + "9b_space_west": PreRegion("9b_space_west", "9b_space", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_space_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_space_west"]), + "9b_space_goal": PreRegion("9b_space_goal", "9b_space", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9b_space_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "9b_space_goal"]), + + "9c_intro_west": PreRegion("9c_intro_west", "9c_intro", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9c_intro_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9c_intro_west"]), + "9c_intro_east": PreRegion("9c_intro_east", "9c_intro", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9c_intro_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9c_intro_east"]), + + "9c_00_west": PreRegion("9c_00_west", "9c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9c_00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9c_00_west"]), + "9c_00_east": PreRegion("9c_00_east", "9c_00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9c_00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9c_00_east"]), + + "9c_01_west": PreRegion("9c_01_west", "9c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9c_01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9c_01_west"]), + "9c_01_east": PreRegion("9c_01_east", "9c_01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9c_01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "9c_01_east"]), + + "9c_02_west": PreRegion("9c_02_west", "9c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9c_02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "9c_02_west"]), + "9c_02_goal": PreRegion("9c_02_goal", "9c_02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "9c_02_goal"], [loc for _, loc in all_locations.items() if loc.region_name == "9c_02_goal"]), + + "10a_intro-00-past_west": PreRegion("10a_intro-00-past_west", "10a_intro-00-past", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_intro-00-past_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_intro-00-past_west"]), + "10a_intro-00-past_east": PreRegion("10a_intro-00-past_east", "10a_intro-00-past", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_intro-00-past_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_intro-00-past_east"]), + + "10a_intro-01-future_west": PreRegion("10a_intro-01-future_west", "10a_intro-01-future", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_intro-01-future_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_intro-01-future_west"]), + "10a_intro-01-future_east": PreRegion("10a_intro-01-future_east", "10a_intro-01-future", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_intro-01-future_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_intro-01-future_east"]), + + "10a_intro-02-launch_bottom": PreRegion("10a_intro-02-launch_bottom", "10a_intro-02-launch", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_intro-02-launch_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_intro-02-launch_bottom"]), + "10a_intro-02-launch_top": PreRegion("10a_intro-02-launch_top", "10a_intro-02-launch", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_intro-02-launch_top"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_intro-02-launch_top"]), + + "10a_intro-03-space_west": PreRegion("10a_intro-03-space_west", "10a_intro-03-space", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_intro-03-space_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_intro-03-space_west"]), + "10a_intro-03-space_east": PreRegion("10a_intro-03-space_east", "10a_intro-03-space", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_intro-03-space_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_intro-03-space_east"]), + + "10a_a-00_west": PreRegion("10a_a-00_west", "10a_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-00_west"]), + "10a_a-00_east": PreRegion("10a_a-00_east", "10a_a-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-00_east"]), + + "10a_a-01_west": PreRegion("10a_a-01_west", "10a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-01_west"]), + "10a_a-01_east": PreRegion("10a_a-01_east", "10a_a-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-01_east"]), + + "10a_a-02_west": PreRegion("10a_a-02_west", "10a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-02_west"]), + "10a_a-02_east": PreRegion("10a_a-02_east", "10a_a-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-02_east"]), + + "10a_a-03_west": PreRegion("10a_a-03_west", "10a_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-03_west"]), + "10a_a-03_east": PreRegion("10a_a-03_east", "10a_a-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-03_east"]), + + "10a_a-04_west": PreRegion("10a_a-04_west", "10a_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-04_west"]), + "10a_a-04_east": PreRegion("10a_a-04_east", "10a_a-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-04_east"]), + + "10a_a-05_west": PreRegion("10a_a-05_west", "10a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-05_west"]), + "10a_a-05_east": PreRegion("10a_a-05_east", "10a_a-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_a-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_a-05_east"]), + + "10a_b-00_west": PreRegion("10a_b-00_west", "10a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-00_west"]), + "10a_b-00_east": PreRegion("10a_b-00_east", "10a_b-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-00_east"]), + + "10a_b-01_west": PreRegion("10a_b-01_west", "10a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-01_west"]), + "10a_b-01_east": PreRegion("10a_b-01_east", "10a_b-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-01_east"]), + + "10a_b-02_west": PreRegion("10a_b-02_west", "10a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-02_west"]), + "10a_b-02_east": PreRegion("10a_b-02_east", "10a_b-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-02_east"]), + + "10a_b-03_west": PreRegion("10a_b-03_west", "10a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-03_west"]), + "10a_b-03_east": PreRegion("10a_b-03_east", "10a_b-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-03_east"]), + + "10a_b-04_west": PreRegion("10a_b-04_west", "10a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-04_west"]), + "10a_b-04_east": PreRegion("10a_b-04_east", "10a_b-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-04_east"]), + + "10a_b-05_west": PreRegion("10a_b-05_west", "10a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-05_west"]), + "10a_b-05_east": PreRegion("10a_b-05_east", "10a_b-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-05_east"]), + + "10a_b-06_west": PreRegion("10a_b-06_west", "10a_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-06_west"]), + "10a_b-06_east": PreRegion("10a_b-06_east", "10a_b-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-06_east"]), + + "10a_b-07_west": PreRegion("10a_b-07_west", "10a_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-07_west"]), + "10a_b-07_east": PreRegion("10a_b-07_east", "10a_b-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_b-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_b-07_east"]), + + "10a_c-00_west": PreRegion("10a_c-00_west", "10a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-00_west"]), + "10a_c-00_east": PreRegion("10a_c-00_east", "10a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-00_east"]), + "10a_c-00_north-east": PreRegion("10a_c-00_north-east", "10a_c-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-00_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-00_north-east"]), + + "10a_c-00b_west": PreRegion("10a_c-00b_west", "10a_c-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-00b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-00b_west"]), + "10a_c-00b_east": PreRegion("10a_c-00b_east", "10a_c-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-00b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-00b_east"]), + + "10a_c-01_west": PreRegion("10a_c-01_west", "10a_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-01_west"]), + "10a_c-01_east": PreRegion("10a_c-01_east", "10a_c-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-01_east"]), + + "10a_c-02_west": PreRegion("10a_c-02_west", "10a_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-02_west"]), + "10a_c-02_east": PreRegion("10a_c-02_east", "10a_c-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-02_east"]), + + "10a_c-alt-00_west": PreRegion("10a_c-alt-00_west", "10a_c-alt-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-alt-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-alt-00_west"]), + "10a_c-alt-00_east": PreRegion("10a_c-alt-00_east", "10a_c-alt-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-alt-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-alt-00_east"]), + + "10a_c-alt-01_west": PreRegion("10a_c-alt-01_west", "10a_c-alt-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-alt-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-alt-01_west"]), + "10a_c-alt-01_east": PreRegion("10a_c-alt-01_east", "10a_c-alt-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-alt-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-alt-01_east"]), + + "10a_c-03_south-west": PreRegion("10a_c-03_south-west", "10a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-03_south-west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-03_south-west"]), + "10a_c-03_south": PreRegion("10a_c-03_south", "10a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-03_south"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-03_south"]), + "10a_c-03_north": PreRegion("10a_c-03_north", "10a_c-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_c-03_north"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_c-03_north"]), + + "10a_d-00_south": PreRegion("10a_d-00_south", "10a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-00_south"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-00_south"]), + "10a_d-00_north": PreRegion("10a_d-00_north", "10a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-00_north"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-00_north"]), + "10a_d-00_south-east": PreRegion("10a_d-00_south-east", "10a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-00_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-00_south-east"]), + "10a_d-00_north-west": PreRegion("10a_d-00_north-west", "10a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-00_north-west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-00_north-west"]), + "10a_d-00_breaker": PreRegion("10a_d-00_breaker", "10a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-00_breaker"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-00_breaker"]), + "10a_d-00_north-east-door": PreRegion("10a_d-00_north-east-door", "10a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-00_north-east-door"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-00_north-east-door"]), + "10a_d-00_south-east-door": PreRegion("10a_d-00_south-east-door", "10a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-00_south-east-door"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-00_south-east-door"]), + "10a_d-00_south-west-door": PreRegion("10a_d-00_south-west-door", "10a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-00_south-west-door"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-00_south-west-door"]), + "10a_d-00_west-door": PreRegion("10a_d-00_west-door", "10a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-00_west-door"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-00_west-door"]), + "10a_d-00_north-west-door": PreRegion("10a_d-00_north-west-door", "10a_d-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-00_north-west-door"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-00_north-west-door"]), + + "10a_d-04_west": PreRegion("10a_d-04_west", "10a_d-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-04_west"]), + + "10a_d-03_west": PreRegion("10a_d-03_west", "10a_d-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-03_west"]), + + "10a_d-01_east": PreRegion("10a_d-01_east", "10a_d-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-01_east"]), + + "10a_d-02_bottom": PreRegion("10a_d-02_bottom", "10a_d-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-02_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-02_bottom"]), + + "10a_d-05_west": PreRegion("10a_d-05_west", "10a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-05_west"]), + "10a_d-05_south": PreRegion("10a_d-05_south", "10a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-05_south"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-05_south"]), + "10a_d-05_north": PreRegion("10a_d-05_north", "10a_d-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_d-05_north"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_d-05_north"]), + + "10a_e-00y_south": PreRegion("10a_e-00y_south", "10a_e-00y", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00y_south"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00y_south"]), + "10a_e-00y_south-east": PreRegion("10a_e-00y_south-east", "10a_e-00y", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00y_south-east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00y_south-east"]), + "10a_e-00y_north-east": PreRegion("10a_e-00y_north-east", "10a_e-00y", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00y_north-east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00y_north-east"]), + "10a_e-00y_north": PreRegion("10a_e-00y_north", "10a_e-00y", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00y_north"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00y_north"]), + + "10a_e-00yb_south": PreRegion("10a_e-00yb_south", "10a_e-00yb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00yb_south"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00yb_south"]), + "10a_e-00yb_north": PreRegion("10a_e-00yb_north", "10a_e-00yb", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00yb_north"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00yb_north"]), + + "10a_e-00z_south": PreRegion("10a_e-00z_south", "10a_e-00z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00z_south"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00z_south"]), + "10a_e-00z_north": PreRegion("10a_e-00z_north", "10a_e-00z", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00z_north"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00z_north"]), + + "10a_e-00_south": PreRegion("10a_e-00_south", "10a_e-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00_south"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00_south"]), + "10a_e-00_north": PreRegion("10a_e-00_north", "10a_e-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00_north"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00_north"]), + + "10a_e-00b_south": PreRegion("10a_e-00b_south", "10a_e-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00b_south"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00b_south"]), + "10a_e-00b_north": PreRegion("10a_e-00b_north", "10a_e-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-00b_north"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-00b_north"]), + + "10a_e-01_south": PreRegion("10a_e-01_south", "10a_e-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-01_south"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-01_south"]), + "10a_e-01_north": PreRegion("10a_e-01_north", "10a_e-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-01_north"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-01_north"]), + + "10a_e-02_west": PreRegion("10a_e-02_west", "10a_e-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-02_west"]), + "10a_e-02_east": PreRegion("10a_e-02_east", "10a_e-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-02_east"]), + + "10a_e-03_west": PreRegion("10a_e-03_west", "10a_e-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-03_west"]), + "10a_e-03_east": PreRegion("10a_e-03_east", "10a_e-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-03_east"]), + + "10a_e-04_west": PreRegion("10a_e-04_west", "10a_e-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-04_west"]), + "10a_e-04_east": PreRegion("10a_e-04_east", "10a_e-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-04_east"]), + + "10a_e-05_west": PreRegion("10a_e-05_west", "10a_e-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-05_west"]), + "10a_e-05_east": PreRegion("10a_e-05_east", "10a_e-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-05_east"]), + + "10a_e-05b_west": PreRegion("10a_e-05b_west", "10a_e-05b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-05b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-05b_west"]), + "10a_e-05b_east": PreRegion("10a_e-05b_east", "10a_e-05b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-05b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-05b_east"]), + + "10a_e-05c_west": PreRegion("10a_e-05c_west", "10a_e-05c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-05c_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-05c_west"]), + "10a_e-05c_east": PreRegion("10a_e-05c_east", "10a_e-05c", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-05c_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-05c_east"]), + + "10a_e-06_west": PreRegion("10a_e-06_west", "10a_e-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-06_west"]), + "10a_e-06_east": PreRegion("10a_e-06_east", "10a_e-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-06_east"]), + + "10a_e-07_west": PreRegion("10a_e-07_west", "10a_e-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-07_west"]), + "10a_e-07_east": PreRegion("10a_e-07_east", "10a_e-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-07_east"]), + + "10a_e-08_west": PreRegion("10a_e-08_west", "10a_e-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-08_west"]), + "10a_e-08_east": PreRegion("10a_e-08_east", "10a_e-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10a_e-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10a_e-08_east"]), + + "10b_f-door_west": PreRegion("10b_f-door_west", "10b_f-door", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-door_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-door_west"]), + "10b_f-door_east": PreRegion("10b_f-door_east", "10b_f-door", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-door_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-door_east"]), + + "10b_f-00_west": PreRegion("10b_f-00_west", "10b_f-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-00_west"]), + "10b_f-00_east": PreRegion("10b_f-00_east", "10b_f-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-00_east"]), + + "10b_f-01_west": PreRegion("10b_f-01_west", "10b_f-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-01_west"]), + "10b_f-01_east": PreRegion("10b_f-01_east", "10b_f-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-01_east"]), + + "10b_f-02_west": PreRegion("10b_f-02_west", "10b_f-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-02_west"]), + "10b_f-02_east": PreRegion("10b_f-02_east", "10b_f-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-02_east"]), + + "10b_f-03_west": PreRegion("10b_f-03_west", "10b_f-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-03_west"]), + "10b_f-03_east": PreRegion("10b_f-03_east", "10b_f-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-03_east"]), + + "10b_f-04_west": PreRegion("10b_f-04_west", "10b_f-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-04_west"]), + "10b_f-04_east": PreRegion("10b_f-04_east", "10b_f-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-04_east"]), + + "10b_f-05_west": PreRegion("10b_f-05_west", "10b_f-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-05_west"]), + "10b_f-05_east": PreRegion("10b_f-05_east", "10b_f-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-05_east"]), + + "10b_f-06_west": PreRegion("10b_f-06_west", "10b_f-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-06_west"]), + "10b_f-06_east": PreRegion("10b_f-06_east", "10b_f-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-06_east"]), + + "10b_f-07_west": PreRegion("10b_f-07_west", "10b_f-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-07_west"]), + "10b_f-07_east": PreRegion("10b_f-07_east", "10b_f-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-07_east"]), + + "10b_f-08_west": PreRegion("10b_f-08_west", "10b_f-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-08_west"]), + "10b_f-08_east": PreRegion("10b_f-08_east", "10b_f-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-08_east"]), + + "10b_f-09_west": PreRegion("10b_f-09_west", "10b_f-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-09_west"]), + "10b_f-09_east": PreRegion("10b_f-09_east", "10b_f-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_f-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_f-09_east"]), + + "10b_g-00_bottom": PreRegion("10b_g-00_bottom", "10b_g-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-00_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-00_bottom"]), + "10b_g-00_top": PreRegion("10b_g-00_top", "10b_g-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-00_top"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-00_top"]), + + "10b_g-01_bottom": PreRegion("10b_g-01_bottom", "10b_g-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-01_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-01_bottom"]), + "10b_g-01_top": PreRegion("10b_g-01_top", "10b_g-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-01_top"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-01_top"]), + + "10b_g-03_bottom": PreRegion("10b_g-03_bottom", "10b_g-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-03_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-03_bottom"]), + "10b_g-03_top": PreRegion("10b_g-03_top", "10b_g-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-03_top"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-03_top"]), + + "10b_g-02_west": PreRegion("10b_g-02_west", "10b_g-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-02_west"]), + "10b_g-02_east": PreRegion("10b_g-02_east", "10b_g-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-02_east"]), + + "10b_g-04_west": PreRegion("10b_g-04_west", "10b_g-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-04_west"]), + "10b_g-04_east": PreRegion("10b_g-04_east", "10b_g-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-04_east"]), + + "10b_g-05_west": PreRegion("10b_g-05_west", "10b_g-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-05_west"]), + "10b_g-05_east": PreRegion("10b_g-05_east", "10b_g-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-05_east"]), + + "10b_g-06_west": PreRegion("10b_g-06_west", "10b_g-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-06_west"]), + "10b_g-06_east": PreRegion("10b_g-06_east", "10b_g-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_g-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_g-06_east"]), + + "10b_h-00b_west": PreRegion("10b_h-00b_west", "10b_h-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-00b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-00b_west"]), + "10b_h-00b_east": PreRegion("10b_h-00b_east", "10b_h-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-00b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-00b_east"]), + + "10b_h-00_west": PreRegion("10b_h-00_west", "10b_h-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-00_west"]), + "10b_h-00_east": PreRegion("10b_h-00_east", "10b_h-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-00_east"]), + + "10b_h-01_west": PreRegion("10b_h-01_west", "10b_h-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-01_west"]), + "10b_h-01_east": PreRegion("10b_h-01_east", "10b_h-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-01_east"]), + + "10b_h-02_west": PreRegion("10b_h-02_west", "10b_h-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-02_west"]), + "10b_h-02_east": PreRegion("10b_h-02_east", "10b_h-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-02_east"]), + + "10b_h-03_west": PreRegion("10b_h-03_west", "10b_h-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-03_west"]), + "10b_h-03_east": PreRegion("10b_h-03_east", "10b_h-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-03_east"]), + + "10b_h-03b_west": PreRegion("10b_h-03b_west", "10b_h-03b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-03b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-03b_west"]), + "10b_h-03b_east": PreRegion("10b_h-03b_east", "10b_h-03b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-03b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-03b_east"]), + + "10b_h-04_top": PreRegion("10b_h-04_top", "10b_h-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-04_top"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-04_top"]), + "10b_h-04_east": PreRegion("10b_h-04_east", "10b_h-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-04_east"]), + "10b_h-04_bottom": PreRegion("10b_h-04_bottom", "10b_h-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-04_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-04_bottom"]), + + "10b_h-04b_west": PreRegion("10b_h-04b_west", "10b_h-04b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-04b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-04b_west"]), + "10b_h-04b_east": PreRegion("10b_h-04b_east", "10b_h-04b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-04b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-04b_east"]), + + "10b_h-05_west": PreRegion("10b_h-05_west", "10b_h-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-05_west"]), + "10b_h-05_top": PreRegion("10b_h-05_top", "10b_h-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-05_top"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-05_top"]), + "10b_h-05_east": PreRegion("10b_h-05_east", "10b_h-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-05_east"]), + + "10b_h-06_west": PreRegion("10b_h-06_west", "10b_h-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-06_west"]), + "10b_h-06_east": PreRegion("10b_h-06_east", "10b_h-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-06_east"]), + + "10b_h-06b_bottom": PreRegion("10b_h-06b_bottom", "10b_h-06b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-06b_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-06b_bottom"]), + "10b_h-06b_top": PreRegion("10b_h-06b_top", "10b_h-06b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-06b_top"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-06b_top"]), + + "10b_h-07_west": PreRegion("10b_h-07_west", "10b_h-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-07_west"]), + "10b_h-07_east": PreRegion("10b_h-07_east", "10b_h-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-07_east"]), + + "10b_h-08_west": PreRegion("10b_h-08_west", "10b_h-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-08_west"]), + "10b_h-08_east": PreRegion("10b_h-08_east", "10b_h-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-08_east"]), + + "10b_h-09_west": PreRegion("10b_h-09_west", "10b_h-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-09_west"]), + "10b_h-09_east": PreRegion("10b_h-09_east", "10b_h-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-09_east"]), + + "10b_h-10_west": PreRegion("10b_h-10_west", "10b_h-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-10_west"]), + "10b_h-10_east": PreRegion("10b_h-10_east", "10b_h-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_h-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_h-10_east"]), + + "10b_i-00_west": PreRegion("10b_i-00_west", "10b_i-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-00_west"]), + "10b_i-00_east": PreRegion("10b_i-00_east", "10b_i-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-00_east"]), + + "10b_i-00b_west": PreRegion("10b_i-00b_west", "10b_i-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-00b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-00b_west"]), + "10b_i-00b_east": PreRegion("10b_i-00b_east", "10b_i-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-00b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-00b_east"]), + + "10b_i-01_west": PreRegion("10b_i-01_west", "10b_i-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-01_west"]), + "10b_i-01_east": PreRegion("10b_i-01_east", "10b_i-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-01_east"]), + + "10b_i-02_west": PreRegion("10b_i-02_west", "10b_i-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-02_west"]), + "10b_i-02_east": PreRegion("10b_i-02_east", "10b_i-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-02_east"]), + + "10b_i-03_west": PreRegion("10b_i-03_west", "10b_i-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-03_west"]), + "10b_i-03_east": PreRegion("10b_i-03_east", "10b_i-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-03_east"]), + + "10b_i-04_west": PreRegion("10b_i-04_west", "10b_i-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-04_west"]), + "10b_i-04_east": PreRegion("10b_i-04_east", "10b_i-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-04_east"]), + + "10b_i-05_west": PreRegion("10b_i-05_west", "10b_i-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-05_west"]), + "10b_i-05_east": PreRegion("10b_i-05_east", "10b_i-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_i-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_i-05_east"]), + + "10b_j-00_west": PreRegion("10b_j-00_west", "10b_j-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-00_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-00_west"]), + "10b_j-00_east": PreRegion("10b_j-00_east", "10b_j-00", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-00_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-00_east"]), + + "10b_j-00b_west": PreRegion("10b_j-00b_west", "10b_j-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-00b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-00b_west"]), + "10b_j-00b_east": PreRegion("10b_j-00b_east", "10b_j-00b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-00b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-00b_east"]), + + "10b_j-01_west": PreRegion("10b_j-01_west", "10b_j-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-01_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-01_west"]), + "10b_j-01_east": PreRegion("10b_j-01_east", "10b_j-01", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-01_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-01_east"]), + + "10b_j-02_west": PreRegion("10b_j-02_west", "10b_j-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-02_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-02_west"]), + "10b_j-02_east": PreRegion("10b_j-02_east", "10b_j-02", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-02_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-02_east"]), + + "10b_j-03_west": PreRegion("10b_j-03_west", "10b_j-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-03_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-03_west"]), + "10b_j-03_east": PreRegion("10b_j-03_east", "10b_j-03", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-03_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-03_east"]), + + "10b_j-04_west": PreRegion("10b_j-04_west", "10b_j-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-04_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-04_west"]), + "10b_j-04_east": PreRegion("10b_j-04_east", "10b_j-04", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-04_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-04_east"]), + + "10b_j-05_west": PreRegion("10b_j-05_west", "10b_j-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-05_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-05_west"]), + "10b_j-05_east": PreRegion("10b_j-05_east", "10b_j-05", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-05_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-05_east"]), + + "10b_j-06_west": PreRegion("10b_j-06_west", "10b_j-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-06_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-06_west"]), + "10b_j-06_east": PreRegion("10b_j-06_east", "10b_j-06", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-06_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-06_east"]), + + "10b_j-07_west": PreRegion("10b_j-07_west", "10b_j-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-07_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-07_west"]), + "10b_j-07_east": PreRegion("10b_j-07_east", "10b_j-07", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-07_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-07_east"]), + + "10b_j-08_west": PreRegion("10b_j-08_west", "10b_j-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-08_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-08_west"]), + "10b_j-08_east": PreRegion("10b_j-08_east", "10b_j-08", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-08_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-08_east"]), + + "10b_j-09_west": PreRegion("10b_j-09_west", "10b_j-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-09_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-09_west"]), + "10b_j-09_east": PreRegion("10b_j-09_east", "10b_j-09", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-09_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-09_east"]), + + "10b_j-10_west": PreRegion("10b_j-10_west", "10b_j-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-10_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-10_west"]), + "10b_j-10_east": PreRegion("10b_j-10_east", "10b_j-10", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-10_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-10_east"]), + + "10b_j-11_west": PreRegion("10b_j-11_west", "10b_j-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-11_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-11_west"]), + "10b_j-11_east": PreRegion("10b_j-11_east", "10b_j-11", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-11_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-11_east"]), + + "10b_j-12_west": PreRegion("10b_j-12_west", "10b_j-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-12_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-12_west"]), + "10b_j-12_east": PreRegion("10b_j-12_east", "10b_j-12", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-12_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-12_east"]), + + "10b_j-13_west": PreRegion("10b_j-13_west", "10b_j-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-13_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-13_west"]), + "10b_j-13_east": PreRegion("10b_j-13_east", "10b_j-13", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-13_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-13_east"]), + + "10b_j-14_west": PreRegion("10b_j-14_west", "10b_j-14", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-14_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-14_west"]), + "10b_j-14_east": PreRegion("10b_j-14_east", "10b_j-14", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-14_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-14_east"]), + + "10b_j-14b_west": PreRegion("10b_j-14b_west", "10b_j-14b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-14b_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-14b_west"]), + "10b_j-14b_east": PreRegion("10b_j-14b_east", "10b_j-14b", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-14b_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-14b_east"]), + + "10b_j-15_west": PreRegion("10b_j-15_west", "10b_j-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-15_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-15_west"]), + "10b_j-15_east": PreRegion("10b_j-15_east", "10b_j-15", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-15_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-15_east"]), + + "10b_j-16_west": PreRegion("10b_j-16_west", "10b_j-16", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-16_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-16_west"]), + "10b_j-16_top": PreRegion("10b_j-16_top", "10b_j-16", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-16_top"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-16_top"]), + "10b_j-16_east": PreRegion("10b_j-16_east", "10b_j-16", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-16_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-16_east"]), + + "10b_j-17_south": PreRegion("10b_j-17_south", "10b_j-17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-17_south"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-17_south"]), + "10b_j-17_west": PreRegion("10b_j-17_west", "10b_j-17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-17_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-17_west"]), + "10b_j-17_north": PreRegion("10b_j-17_north", "10b_j-17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-17_north"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-17_north"]), + "10b_j-17_east": PreRegion("10b_j-17_east", "10b_j-17", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-17_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-17_east"]), + + "10b_j-18_west": PreRegion("10b_j-18_west", "10b_j-18", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-18_west"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-18_west"]), + "10b_j-18_east": PreRegion("10b_j-18_east", "10b_j-18", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-18_east"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-18_east"]), + + "10b_j-19_bottom": PreRegion("10b_j-19_bottom", "10b_j-19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-19_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-19_bottom"]), + "10b_j-19_top": PreRegion("10b_j-19_top", "10b_j-19", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_j-19_top"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_j-19_top"]), + + "10b_GOAL_main": PreRegion("10b_GOAL_main", "10b_GOAL", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_GOAL_main"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_GOAL_main"]), + "10b_GOAL_moon": PreRegion("10b_GOAL_moon", "10b_GOAL", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10b_GOAL_moon"], [loc for _, loc in all_locations.items() if loc.region_name == "10b_GOAL_moon"]), + + "10c_end-golden_bottom": PreRegion("10c_end-golden_bottom", "10c_end-golden", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10c_end-golden_bottom"], [loc for _, loc in all_locations.items() if loc.region_name == "10c_end-golden_bottom"]), + "10c_end-golden_top": PreRegion("10c_end-golden_top", "10c_end-golden", [reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == "10c_end-golden_top"], [loc for _, loc in all_locations.items() if loc.region_name == "10c_end-golden_top"]), + +} + +all_room_connections: dict[str, RoomConnection] = { + "0a_-1_east---0a_0_west": RoomConnection("0a", all_doors["0a_-1_east"], all_doors["0a_0_west"]), + "0a_0_north---0a_0b_south": RoomConnection("0a", all_doors["0a_0_north"], all_doors["0a_0b_south"]), + "0a_0_east---0a_1_west": RoomConnection("0a", all_doors["0a_0_east"], all_doors["0a_1_west"]), + "0a_1_east---0a_2_west": RoomConnection("0a", all_doors["0a_1_east"], all_doors["0a_2_west"]), + "0a_2_east---0a_3_west": RoomConnection("0a", all_doors["0a_2_east"], all_doors["0a_3_west"]), + + "1a_1_east---1a_2_west": RoomConnection("1a", all_doors["1a_1_east"], all_doors["1a_2_west"]), + "1a_2_east---1a_3_west": RoomConnection("1a", all_doors["1a_2_east"], all_doors["1a_3_west"]), + "1a_3_east---1a_4_west": RoomConnection("1a", all_doors["1a_3_east"], all_doors["1a_4_west"]), + "1a_4_east---1a_3b_west": RoomConnection("1a", all_doors["1a_4_east"], all_doors["1a_3b_west"]), + "1a_3b_top---1a_5_bottom": RoomConnection("1a", all_doors["1a_3b_top"], all_doors["1a_5_bottom"]), + "1a_5_west---1a_5z_east": RoomConnection("1a", all_doors["1a_5_west"], all_doors["1a_5z_east"]), + "1a_5_south-east---1a_5a_west": RoomConnection("1a", all_doors["1a_5_south-east"], all_doors["1a_5a_west"]), + "1a_5_top---1a_6_south-west": RoomConnection("1a", all_doors["1a_5_top"], all_doors["1a_6_south-west"]), + "1a_6_west---1a_6z_east": RoomConnection("1a", all_doors["1a_6_west"], all_doors["1a_6z_east"]), + "1a_6_east---1a_6a_west": RoomConnection("1a", all_doors["1a_6_east"], all_doors["1a_6a_west"]), + "1a_6z_north-west---1a_7zb_east": RoomConnection("1a", all_doors["1a_6z_north-west"], all_doors["1a_7zb_east"]), + "1a_6z_west---1a_6zb_east": RoomConnection("1a", all_doors["1a_6z_west"], all_doors["1a_6zb_east"]), + "1a_7zb_west---1a_6zb_north-west": RoomConnection("1a", all_doors["1a_7zb_west"], all_doors["1a_6zb_north-west"]), + "1a_6a_east---1a_6b_south-west": RoomConnection("1a", all_doors["1a_6a_east"], all_doors["1a_6b_south-west"]), + "1a_6b_north-west---1a_s0_east": RoomConnection("1a", all_doors["1a_6b_north-west"], all_doors["1a_s0_east"]), + "1a_6b_north-east---1a_6c_south-west": RoomConnection("1a", all_doors["1a_6b_north-east"], all_doors["1a_6c_south-west"]), + "1a_s0_west---1a_s1_east": RoomConnection("1a", all_doors["1a_s0_west"], all_doors["1a_s1_east"]), + "1a_6c_north-west---1a_7z_bottom": RoomConnection("1a", all_doors["1a_6c_north-west"], all_doors["1a_7z_bottom"]), + "1a_6c_north-east---1a_7_west": RoomConnection("1a", all_doors["1a_6c_north-east"], all_doors["1a_7_west"]), + "1a_7_east---1a_8_south-west": RoomConnection("1a", all_doors["1a_7_east"], all_doors["1a_8_south-west"]), + "1a_7z_top---1a_8z_bottom": RoomConnection("1a", all_doors["1a_7z_top"], all_doors["1a_8z_bottom"]), + "1a_8z_top---1a_8zb_west": RoomConnection("1a", all_doors["1a_8z_top"], all_doors["1a_8zb_west"]), + "1a_8zb_east---1a_8_west": RoomConnection("1a", all_doors["1a_8zb_east"], all_doors["1a_8_west"]), + "1a_8_south---1a_7a_west": RoomConnection("1a", all_doors["1a_8_south"], all_doors["1a_7a_west"]), + "1a_8_north---1a_9z_east": RoomConnection("1a", all_doors["1a_8_north"], all_doors["1a_9z_east"]), + "1a_8_north-east---1a_8b_west": RoomConnection("1a", all_doors["1a_8_north-east"], all_doors["1a_8b_west"]), + "1a_7a_east---1a_8_south-east": RoomConnection("1a", all_doors["1a_7a_east"], all_doors["1a_8_south-east"]), + "1a_8b_east---1a_9_west": RoomConnection("1a", all_doors["1a_8b_east"], all_doors["1a_9_west"]), + "1a_9_east---1a_9b_west": RoomConnection("1a", all_doors["1a_9_east"], all_doors["1a_9b_west"]), + "1a_9b_north-west---1a_10_south-east": RoomConnection("1a", all_doors["1a_9b_north-west"], all_doors["1a_10_south-east"]), + "1a_9b_north-east---1a_10a_bottom": RoomConnection("1a", all_doors["1a_9b_north-east"], all_doors["1a_10a_bottom"]), + "1a_9b_east---1a_9c_west": RoomConnection("1a", all_doors["1a_9b_east"], all_doors["1a_9c_west"]), + "1a_10_south-west---1a_10z_east": RoomConnection("1a", all_doors["1a_10_south-west"], all_doors["1a_10z_east"]), + "1a_10_north-west---1a_11_south-west": RoomConnection("1a", all_doors["1a_10_north-west"], all_doors["1a_11_south-west"]), + "1a_10z_west---1a_10zb_east": RoomConnection("1a", all_doors["1a_10z_west"], all_doors["1a_10zb_east"]), + "1a_11_south---1a_10_north-east": RoomConnection("1a", all_doors["1a_11_south"], all_doors["1a_10_north-east"]), + "1a_11_west---1a_11z_east": RoomConnection("1a", all_doors["1a_11_west"], all_doors["1a_11z_east"]), + "1a_10a_top---1a_11_south-east": RoomConnection("1a", all_doors["1a_10a_top"], all_doors["1a_11_south-east"]), + "1a_11_north---1a_12_south-west": RoomConnection("1a", all_doors["1a_11_north"], all_doors["1a_12_south-west"]), + "1a_12_north-west---1a_12z_east": RoomConnection("1a", all_doors["1a_12_north-west"], all_doors["1a_12z_east"]), + "1a_12_east---1a_12a_bottom": RoomConnection("1a", all_doors["1a_12_east"], all_doors["1a_12a_bottom"]), + "1a_12a_top---1a_end_south": RoomConnection("1a", all_doors["1a_12a_top"], all_doors["1a_end_south"]), + + "1b_00_east---1b_01_west": RoomConnection("1b", all_doors["1b_00_east"], all_doors["1b_01_west"]), + "1b_01_east---1b_02_west": RoomConnection("1b", all_doors["1b_01_east"], all_doors["1b_02_west"]), + "1b_02_east---1b_02b_west": RoomConnection("1b", all_doors["1b_02_east"], all_doors["1b_02b_west"]), + "1b_02b_east---1b_03_west": RoomConnection("1b", all_doors["1b_02b_east"], all_doors["1b_03_west"]), + "1b_03_east---1b_04_west": RoomConnection("1b", all_doors["1b_03_east"], all_doors["1b_04_west"]), + "1b_04_east---1b_05_west": RoomConnection("1b", all_doors["1b_04_east"], all_doors["1b_05_west"]), + "1b_05_east---1b_05b_west": RoomConnection("1b", all_doors["1b_05_east"], all_doors["1b_05b_west"]), + "1b_05b_east---1b_06_west": RoomConnection("1b", all_doors["1b_05b_east"], all_doors["1b_06_west"]), + "1b_06_east---1b_07_bottom": RoomConnection("1b", all_doors["1b_06_east"], all_doors["1b_07_bottom"]), + "1b_07_top---1b_08_west": RoomConnection("1b", all_doors["1b_07_top"], all_doors["1b_08_west"]), + "1b_08_east---1b_08b_west": RoomConnection("1b", all_doors["1b_08_east"], all_doors["1b_08b_west"]), + "1b_08b_east---1b_09_west": RoomConnection("1b", all_doors["1b_08b_east"], all_doors["1b_09_west"]), + "1b_09_east---1b_10_west": RoomConnection("1b", all_doors["1b_09_east"], all_doors["1b_10_west"]), + "1b_10_east---1b_11_bottom": RoomConnection("1b", all_doors["1b_10_east"], all_doors["1b_11_bottom"]), + "1b_11_top---1b_end_west": RoomConnection("1b", all_doors["1b_11_top"], all_doors["1b_end_west"]), + + "1c_00_east---1c_01_west": RoomConnection("1c", all_doors["1c_00_east"], all_doors["1c_01_west"]), + "1c_01_east---1c_02_west": RoomConnection("1c", all_doors["1c_01_east"], all_doors["1c_02_west"]), + + "2a_start_top---2a_s0_bottom": RoomConnection("2a", all_doors["2a_start_top"], all_doors["2a_s0_bottom"]), + "2a_start_east---2a_0_south-west": RoomConnection("2a", all_doors["2a_start_east"], all_doors["2a_0_south-west"]), + "2a_s0_top---2a_s1_bottom": RoomConnection("2a", all_doors["2a_s0_top"], all_doors["2a_s1_bottom"]), + "2a_s1_top---2a_s2_bottom": RoomConnection("2a", all_doors["2a_s1_top"], all_doors["2a_s2_bottom"]), + "2a_0_north-west---2a_3x_bottom": RoomConnection("2a", all_doors["2a_0_north-west"], all_doors["2a_3x_bottom"]), + "2a_0_north-east---2a_1_north-west": RoomConnection("2a", all_doors["2a_0_north-east"], all_doors["2a_1_north-west"]), + "2a_0_south-east---2a_1_south-west": RoomConnection("2a", all_doors["2a_0_south-east"], all_doors["2a_1_south-west"]), + "2a_1_south---2a_d0_north": RoomConnection("2a", all_doors["2a_1_south"], all_doors["2a_d0_north"]), + "2a_1_south-east---2a_2_south-west": RoomConnection("2a", all_doors["2a_1_south-east"], all_doors["2a_2_south-west"]), + "2a_d0_north-west---2a_d1_north-east": RoomConnection("2a", all_doors["2a_d0_north-west"], all_doors["2a_d1_north-east"]), + "2a_d0_west---2a_d1_south-east": RoomConnection("2a", all_doors["2a_d0_west"], all_doors["2a_d1_south-east"]), + "2a_d0_south-west---2a_d6_east": RoomConnection("2a", all_doors["2a_d0_south-west"], all_doors["2a_d6_east"]), + "2a_d0_south---2a_d9_north-west": RoomConnection("2a", all_doors["2a_d0_south"], all_doors["2a_d9_north-west"]), + "2a_d0_south-east---2a_d7_west": RoomConnection("2a", all_doors["2a_d0_south-east"], all_doors["2a_d7_west"]), + "2a_d0_east---2a_d2_west": RoomConnection("2a", all_doors["2a_d0_east"], all_doors["2a_d2_west"]), + "2a_d0_north-east---2a_d4_west": RoomConnection("2a", all_doors["2a_d0_north-east"], all_doors["2a_d4_west"]), + "2a_d1_south-west---2a_d6_west": RoomConnection("2a", all_doors["2a_d1_south-west"], all_doors["2a_d6_west"]), + "2a_d7_east---2a_d8_west": RoomConnection("2a", all_doors["2a_d7_east"], all_doors["2a_d8_west"]), + "2a_d2_east---2a_d3_north": RoomConnection("2a", all_doors["2a_d2_east"], all_doors["2a_d3_north"]), + "2a_d4_east---2a_d5_west": RoomConnection("2a", all_doors["2a_d4_east"], all_doors["2a_d5_west"]), + "2a_d4_south---2a_d2_north-west": RoomConnection("2a", all_doors["2a_d4_south"], all_doors["2a_d2_north-west"]), + "2a_d8_north-east---2a_d3_west": RoomConnection("2a", all_doors["2a_d8_north-east"], all_doors["2a_d3_west"]), + "2a_d8_south-east---2a_d3_south": RoomConnection("2a", all_doors["2a_d8_south-east"], all_doors["2a_d3_south"]), + "2a_3x_top---2a_3_bottom": RoomConnection("2a", all_doors["2a_3x_top"], all_doors["2a_3_bottom"]), + "2a_3_top---2a_4_bottom": RoomConnection("2a", all_doors["2a_3_top"], all_doors["2a_4_bottom"]), + "2a_4_top---2a_5_bottom": RoomConnection("2a", all_doors["2a_4_top"], all_doors["2a_5_bottom"]), + "2a_5_top---2a_6_bottom": RoomConnection("2a", all_doors["2a_5_top"], all_doors["2a_6_bottom"]), + "2a_6_top---2a_7_bottom": RoomConnection("2a", all_doors["2a_6_top"], all_doors["2a_7_bottom"]), + "2a_7_top---2a_8_bottom": RoomConnection("2a", all_doors["2a_7_top"], all_doors["2a_8_bottom"]), + "2a_8_top---2a_9_west": RoomConnection("2a", all_doors["2a_8_top"], all_doors["2a_9_west"]), + "2a_9_north---2a_9b_east": RoomConnection("2a", all_doors["2a_9_north"], all_doors["2a_9b_east"]), + "2a_9_south-east---2a_10_top": RoomConnection("2a", all_doors["2a_9_south-east"], all_doors["2a_10_top"]), + "2a_9b_west---2a_9_north-west": RoomConnection("2a", all_doors["2a_9b_west"], all_doors["2a_9_north-west"]), + "2a_10_bottom---2a_2_north-west": RoomConnection("2a", all_doors["2a_10_bottom"], all_doors["2a_2_north-west"]), + "2a_2_south-east---2a_11_west": RoomConnection("2a", all_doors["2a_2_south-east"], all_doors["2a_11_west"]), + "2a_11_east---2a_12b_west": RoomConnection("2a", all_doors["2a_11_east"], all_doors["2a_12b_west"]), + "2a_12b_north---2a_12c_south": RoomConnection("2a", all_doors["2a_12b_north"], all_doors["2a_12c_south"]), + "2a_12b_south---2a_12d_north-west": RoomConnection("2a", all_doors["2a_12b_south"], all_doors["2a_12d_north-west"]), + "2a_12b_east---2a_12_west": RoomConnection("2a", all_doors["2a_12b_east"], all_doors["2a_12_west"]), + "2a_12d_north---2a_12b_south-east": RoomConnection("2a", all_doors["2a_12d_north"], all_doors["2a_12b_south-east"]), + "2a_12_east---2a_13_west": RoomConnection("2a", all_doors["2a_12_east"], all_doors["2a_13_west"]), + "2a_13_phone---2a_end_0_main": RoomConnection("2a", all_doors["2a_13_phone"], all_doors["2a_end_0_main"]), + "2a_end_0_top---2a_end_s0_bottom": RoomConnection("2a", all_doors["2a_end_0_top"], all_doors["2a_end_s0_bottom"]), + "2a_end_0_east---2a_end_1_west": RoomConnection("2a", all_doors["2a_end_0_east"], all_doors["2a_end_1_west"]), + "2a_end_s0_top---2a_end_s1_bottom": RoomConnection("2a", all_doors["2a_end_s0_top"], all_doors["2a_end_s1_bottom"]), + "2a_end_1_east---2a_end_2_west": RoomConnection("2a", all_doors["2a_end_1_east"], all_doors["2a_end_2_west"]), + "2a_end_1_north-east---2a_end_2_north-west": RoomConnection("2a", all_doors["2a_end_1_north-east"], all_doors["2a_end_2_north-west"]), + "2a_end_2_east---2a_end_3_west": RoomConnection("2a", all_doors["2a_end_2_east"], all_doors["2a_end_3_west"]), + "2a_end_2_north-east---2a_end_3_north-west": RoomConnection("2a", all_doors["2a_end_2_north-east"], all_doors["2a_end_3_north-west"]), + "2a_end_3_east---2a_end_4_west": RoomConnection("2a", all_doors["2a_end_3_east"], all_doors["2a_end_4_west"]), + "2a_end_4_east---2a_end_3b_west": RoomConnection("2a", all_doors["2a_end_4_east"], all_doors["2a_end_3b_west"]), + "2a_end_3b_north---2a_end_3cb_bottom": RoomConnection("2a", all_doors["2a_end_3b_north"], all_doors["2a_end_3cb_bottom"]), + "2a_end_3b_east---2a_end_5_west": RoomConnection("2a", all_doors["2a_end_3b_east"], all_doors["2a_end_5_west"]), + "2a_end_3cb_top---2a_end_3c_bottom": RoomConnection("2a", all_doors["2a_end_3cb_top"], all_doors["2a_end_3c_bottom"]), + "2a_end_5_east---2a_end_6_west": RoomConnection("2a", all_doors["2a_end_5_east"], all_doors["2a_end_6_west"]), + + "2b_start_east---2b_00_west": RoomConnection("2b", all_doors["2b_start_east"], all_doors["2b_00_west"]), + "2b_00_east---2b_01_west": RoomConnection("2b", all_doors["2b_00_east"], all_doors["2b_01_west"]), + "2b_01_east---2b_01b_west": RoomConnection("2b", all_doors["2b_01_east"], all_doors["2b_01b_west"]), + "2b_01b_east---2b_02b_west": RoomConnection("2b", all_doors["2b_01b_east"], all_doors["2b_02b_west"]), + "2b_02b_east---2b_02_west": RoomConnection("2b", all_doors["2b_02b_east"], all_doors["2b_02_west"]), + "2b_02_east---2b_03_west": RoomConnection("2b", all_doors["2b_02_east"], all_doors["2b_03_west"]), + "2b_03_east---2b_04_bottom": RoomConnection("2b", all_doors["2b_03_east"], all_doors["2b_04_bottom"]), + "2b_04_top---2b_05_bottom": RoomConnection("2b", all_doors["2b_04_top"], all_doors["2b_05_bottom"]), + "2b_05_top---2b_06_west": RoomConnection("2b", all_doors["2b_05_top"], all_doors["2b_06_west"]), + "2b_06_east---2b_07_bottom": RoomConnection("2b", all_doors["2b_06_east"], all_doors["2b_07_bottom"]), + "2b_07_top---2b_08b_west": RoomConnection("2b", all_doors["2b_07_top"], all_doors["2b_08b_west"]), + "2b_08b_east---2b_08_west": RoomConnection("2b", all_doors["2b_08b_east"], all_doors["2b_08_west"]), + "2b_08_east---2b_09_west": RoomConnection("2b", all_doors["2b_08_east"], all_doors["2b_09_west"]), + "2b_09_east---2b_10_west": RoomConnection("2b", all_doors["2b_09_east"], all_doors["2b_10_west"]), + "2b_10_east---2b_11_bottom": RoomConnection("2b", all_doors["2b_10_east"], all_doors["2b_11_bottom"]), + "2b_11_top---2b_end_west": RoomConnection("2b", all_doors["2b_11_top"], all_doors["2b_end_west"]), + + "2c_00_east---2c_01_west": RoomConnection("2c", all_doors["2c_00_east"], all_doors["2c_01_west"]), + "2c_01_east---2c_02_west": RoomConnection("2c", all_doors["2c_01_east"], all_doors["2c_02_west"]), + + "3a_s0_east---3a_s1_west": RoomConnection("3a", all_doors["3a_s0_east"], all_doors["3a_s1_west"]), + "3a_s1_east---3a_s2_west": RoomConnection("3a", all_doors["3a_s1_east"], all_doors["3a_s2_west"]), + "3a_s1_north-east---3a_s2_north-west": RoomConnection("3a", all_doors["3a_s1_north-east"], all_doors["3a_s2_north-west"]), + "3a_s2_east---3a_s3_west": RoomConnection("3a", all_doors["3a_s2_east"], all_doors["3a_s3_west"]), + "3a_s3_east---3a_0x-a_west": RoomConnection("3a", all_doors["3a_s3_east"], all_doors["3a_0x-a_west"]), + "3a_0x-a_east---3a_00-a_west": RoomConnection("3a", all_doors["3a_0x-a_east"], all_doors["3a_00-a_west"]), + "3a_00-a_east---3a_02-a_west": RoomConnection("3a", all_doors["3a_00-a_east"], all_doors["3a_02-a_west"]), + "3a_02-a_east---3a_03-a_west": RoomConnection("3a", all_doors["3a_02-a_east"], all_doors["3a_03-a_west"]), + "3a_02-a_top---3a_02-b_east": RoomConnection("3a", all_doors["3a_02-a_top"], all_doors["3a_02-b_east"]), + "3a_02-b_west---3a_01-b_east": RoomConnection("3a", all_doors["3a_02-b_west"], all_doors["3a_01-b_east"]), + "3a_01-b_north-west---3a_00-b_east": RoomConnection("3a", all_doors["3a_01-b_north-west"], all_doors["3a_00-b_east"]), + "3a_01-b_west---3a_00-b_south-east": RoomConnection("3a", all_doors["3a_01-b_west"], all_doors["3a_00-b_south-east"]), + "3a_00-b_south-west---3a_0x-b_south-east": RoomConnection("3a", all_doors["3a_00-b_south-west"], all_doors["3a_0x-b_south-east"]), + "3a_00-b_north---3a_00-c_south-east": RoomConnection("3a", all_doors["3a_00-b_north"], all_doors["3a_00-c_south-east"]), + "3a_00-b_west---3a_0x-b_north-east": RoomConnection("3a", all_doors["3a_00-b_west"], all_doors["3a_0x-b_north-east"]), + "3a_00-c_south-west---3a_00-b_north-west": RoomConnection("3a", all_doors["3a_00-c_south-west"], all_doors["3a_00-b_north-west"]), + "3a_00-c_north-east---3a_01-c_west": RoomConnection("3a", all_doors["3a_00-c_north-east"], all_doors["3a_01-c_west"]), + "3a_0x-b_west---3a_s3_north": RoomConnection("3a", all_doors["3a_0x-b_west"], all_doors["3a_s3_north"]), + "3a_03-a_top---3a_04-b_east": RoomConnection("3a", all_doors["3a_03-a_top"], all_doors["3a_04-b_east"]), + "3a_03-a_east---3a_05-a_west": RoomConnection("3a", all_doors["3a_03-a_east"], all_doors["3a_05-a_west"]), + "3a_05-a_east---3a_06-a_west": RoomConnection("3a", all_doors["3a_05-a_east"], all_doors["3a_06-a_west"]), + "3a_06-a_east---3a_07-a_west": RoomConnection("3a", all_doors["3a_06-a_east"], all_doors["3a_07-a_west"]), + "3a_07-a_top---3a_07-b_bottom": RoomConnection("3a", all_doors["3a_07-a_top"], all_doors["3a_07-b_bottom"]), + "3a_07-a_east---3a_08-a_west": RoomConnection("3a", all_doors["3a_07-a_east"], all_doors["3a_08-a_west"]), + "3a_07-b_west---3a_06-b_east": RoomConnection("3a", all_doors["3a_07-b_west"], all_doors["3a_06-b_east"]), + "3a_06-b_west---3a_06-c_south-west": RoomConnection("3a", all_doors["3a_06-b_west"], all_doors["3a_06-c_south-west"]), + "3a_06-c_north-west---3a_05-c_east": RoomConnection("3a", all_doors["3a_06-c_north-west"], all_doors["3a_05-c_east"]), + "3a_06-c_east---3a_08-c_west": RoomConnection("3a", all_doors["3a_06-c_east"], all_doors["3a_08-c_west"]), + "3a_06-c_south-east---3a_07-b_top": RoomConnection("3a", all_doors["3a_06-c_south-east"], all_doors["3a_07-b_top"]), + "3a_08-c_east---3a_08-b_east": RoomConnection("3a", all_doors["3a_08-c_east"], all_doors["3a_08-b_east"]), + "3a_08-b_west---3a_07-b_east": RoomConnection("3a", all_doors["3a_08-b_west"], all_doors["3a_07-b_east"]), + "3a_08-a_bottom---3a_08-x_west": RoomConnection("3a", all_doors["3a_08-a_bottom"], all_doors["3a_08-x_west"]), + "3a_08-a_east---3a_09-b_west": RoomConnection("3a", all_doors["3a_08-a_east"], all_doors["3a_09-b_west"]), + "3a_09-b_south-east---3a_10-x_north-east-top": RoomConnection("3a", all_doors["3a_09-b_south-east"], all_doors["3a_10-x_north-east-top"]), + "3a_09-b_north-west---3a_09-d_bottom": RoomConnection("3a", all_doors["3a_09-b_north-west"], all_doors["3a_09-d_bottom"]), + "3a_09-b_north-east-top---3a_10-c_south-east": RoomConnection("3a", all_doors["3a_09-b_north-east-top"], all_doors["3a_10-c_south-east"]), + "3a_09-b_east---3a_11-a_west": RoomConnection("3a", all_doors["3a_09-b_east"], all_doors["3a_11-a_west"]), + "3a_09-b_north-east-right---3a_11-b_west": RoomConnection("3a", all_doors["3a_09-b_north-east-right"], all_doors["3a_11-b_west"]), + "3a_10-x_north-east-right---3a_11-x_west": RoomConnection("3a", all_doors["3a_10-x_north-east-right"], all_doors["3a_11-x_west"]), + "3a_11-x_south---3a_11-y_west": RoomConnection("3a", all_doors["3a_11-x_south"], all_doors["3a_11-y_west"]), + "3a_11-y_east---3a_12-y_west": RoomConnection("3a", all_doors["3a_11-y_east"], all_doors["3a_12-y_west"]), + "3a_11-y_south---3a_11-z_east": RoomConnection("3a", all_doors["3a_11-y_south"], all_doors["3a_11-z_east"]), + "3a_11-z_west---3a_10-z_bottom": RoomConnection("3a", all_doors["3a_11-z_west"], all_doors["3a_10-z_bottom"]), + "3a_10-z_top---3a_10-y_bottom": RoomConnection("3a", all_doors["3a_10-z_top"], all_doors["3a_10-y_bottom"]), + "3a_10-y_top---3a_10-x_south-east": RoomConnection("3a", all_doors["3a_10-y_top"], all_doors["3a_10-x_south-east"]), + "3a_10-x_west---3a_09-b_south": RoomConnection("3a", all_doors["3a_10-x_west"], all_doors["3a_09-b_south"]), + "3a_10-c_north-east---3a_11-c_west": RoomConnection("3a", all_doors["3a_10-c_north-east"], all_doors["3a_11-c_west"]), + "3a_10-c_south-west---3a_09-b_north": RoomConnection("3a", all_doors["3a_10-c_south-west"], all_doors["3a_09-b_north"]), + "3a_11-c_east---3a_12-c_west": RoomConnection("3a", all_doors["3a_11-c_east"], all_doors["3a_12-c_west"]), + "3a_11-c_south-west---3a_11-b_north-west": RoomConnection("3a", all_doors["3a_11-c_south-west"], all_doors["3a_11-b_north-west"]), + "3a_12-c_top---3a_12-d_bottom": RoomConnection("3a", all_doors["3a_12-c_top"], all_doors["3a_12-d_bottom"]), + "3a_12-d_top---3a_11-d_east": RoomConnection("3a", all_doors["3a_12-d_top"], all_doors["3a_11-d_east"]), + "3a_11-d_west---3a_10-d_east": RoomConnection("3a", all_doors["3a_11-d_west"], all_doors["3a_10-d_east"]), + "3a_10-d_west---3a_10-c_north-west": RoomConnection("3a", all_doors["3a_10-d_west"], all_doors["3a_10-c_north-west"]), + "3a_11-b_north-east---3a_11-c_south-east": RoomConnection("3a", all_doors["3a_11-b_north-east"], all_doors["3a_11-c_south-east"]), + "3a_11-b_east---3a_12-b_west": RoomConnection("3a", all_doors["3a_11-b_east"], all_doors["3a_12-b_west"]), + "3a_12-b_east---3a_13-b_top": RoomConnection("3a", all_doors["3a_12-b_east"], all_doors["3a_13-b_top"]), + "3a_13-b_bottom---3a_13-a_west": RoomConnection("3a", all_doors["3a_13-b_bottom"], all_doors["3a_13-a_west"]), + "3a_13-a_east---3a_13-x_east": RoomConnection("3a", all_doors["3a_13-a_east"], all_doors["3a_13-x_east"]), + "3a_13-x_west---3a_12-x_east": RoomConnection("3a", all_doors["3a_13-x_west"], all_doors["3a_12-x_east"]), + "3a_12-x_north-east---3a_11-a_south-east-bottom": RoomConnection("3a", all_doors["3a_12-x_north-east"], all_doors["3a_11-a_south-east-bottom"]), + "3a_12-x_west---3a_11-a_south": RoomConnection("3a", all_doors["3a_12-x_west"], all_doors["3a_11-a_south"]), + "3a_11-a_south-east-right---3a_13-a_south-west": RoomConnection("3a", all_doors["3a_11-a_south-east-right"], all_doors["3a_13-a_south-west"]), + "3a_08-x_east---3a_09-b_south-west": RoomConnection("3a", all_doors["3a_08-x_east"], all_doors["3a_09-b_south-west"]), + "3a_09-d_top---3a_08-d_east": RoomConnection("3a", all_doors["3a_09-d_top"], all_doors["3a_08-d_east"]), + "3a_08-d_west---3a_06-d_east": RoomConnection("3a", all_doors["3a_08-d_west"], all_doors["3a_06-d_east"]), + "3a_06-d_west---3a_04-d_east": RoomConnection("3a", all_doors["3a_06-d_west"], all_doors["3a_04-d_east"]), + "3a_04-d_west---3a_02-d_east": RoomConnection("3a", all_doors["3a_04-d_west"], all_doors["3a_02-d_east"]), + "3a_04-d_south---3a_04-c_east": RoomConnection("3a", all_doors["3a_04-d_south"], all_doors["3a_04-c_east"]), + "3a_04-c_west---3a_02-c_east": RoomConnection("3a", all_doors["3a_04-c_west"], all_doors["3a_02-c_east"]), + "3a_04-c_north-west---3a_04-d_south-west": RoomConnection("3a", all_doors["3a_04-c_north-west"], all_doors["3a_04-d_south-west"]), + "3a_02-c_west---3a_01-c_east": RoomConnection("3a", all_doors["3a_02-c_west"], all_doors["3a_01-c_east"]), + "3a_02-c_south-east---3a_03-b_north": RoomConnection("3a", all_doors["3a_02-c_south-east"], all_doors["3a_03-b_north"]), + "3a_03-b_east---3a_04-b_west": RoomConnection("3a", all_doors["3a_03-b_east"], all_doors["3a_04-b_west"]), + "3a_03-b_west---3a_02-b_far-east": RoomConnection("3a", all_doors["3a_03-b_west"], all_doors["3a_02-b_far-east"]), + "3a_02-d_west---3a_00-d_east": RoomConnection("3a", all_doors["3a_02-d_west"], all_doors["3a_00-d_east"]), + "3a_00-d_west---3a_roof00_west": RoomConnection("3a", all_doors["3a_00-d_west"], all_doors["3a_roof00_west"]), + "3a_roof00_east---3a_roof01_west": RoomConnection("3a", all_doors["3a_roof00_east"], all_doors["3a_roof01_west"]), + "3a_roof01_east---3a_roof02_west": RoomConnection("3a", all_doors["3a_roof01_east"], all_doors["3a_roof02_west"]), + "3a_roof02_east---3a_roof03_west": RoomConnection("3a", all_doors["3a_roof02_east"], all_doors["3a_roof03_west"]), + "3a_roof03_east---3a_roof04_west": RoomConnection("3a", all_doors["3a_roof03_east"], all_doors["3a_roof04_west"]), + "3a_roof04_east---3a_roof05_west": RoomConnection("3a", all_doors["3a_roof04_east"], all_doors["3a_roof05_west"]), + "3a_roof05_east---3a_roof06b_west": RoomConnection("3a", all_doors["3a_roof05_east"], all_doors["3a_roof06b_west"]), + "3a_roof06b_east---3a_roof06_west": RoomConnection("3a", all_doors["3a_roof06b_east"], all_doors["3a_roof06_west"]), + "3a_roof06_east---3a_roof07_west": RoomConnection("3a", all_doors["3a_roof06_east"], all_doors["3a_roof07_west"]), + + "3b_00_east---3b_01_west": RoomConnection("3b", all_doors["3b_00_east"], all_doors["3b_01_west"]), + "3b_00_west---3b_back_east": RoomConnection("3b", all_doors["3b_00_west"], all_doors["3b_back_east"]), + "3b_01_east---3b_02_west": RoomConnection("3b", all_doors["3b_01_east"], all_doors["3b_02_west"]), + "3b_02_east---3b_03_west": RoomConnection("3b", all_doors["3b_02_east"], all_doors["3b_03_west"]), + "3b_03_east---3b_04_west": RoomConnection("3b", all_doors["3b_03_east"], all_doors["3b_04_west"]), + "3b_04_east---3b_05_west": RoomConnection("3b", all_doors["3b_04_east"], all_doors["3b_05_west"]), + "3b_05_east---3b_06_west": RoomConnection("3b", all_doors["3b_05_east"], all_doors["3b_06_west"]), + "3b_06_east---3b_07_west": RoomConnection("3b", all_doors["3b_06_east"], all_doors["3b_07_west"]), + "3b_07_east---3b_08_bottom": RoomConnection("3b", all_doors["3b_07_east"], all_doors["3b_08_bottom"]), + "3b_08_top---3b_09_west": RoomConnection("3b", all_doors["3b_08_top"], all_doors["3b_09_west"]), + "3b_09_east---3b_10_west": RoomConnection("3b", all_doors["3b_09_east"], all_doors["3b_10_west"]), + "3b_10_east---3b_11_west": RoomConnection("3b", all_doors["3b_10_east"], all_doors["3b_11_west"]), + "3b_11_east---3b_13_west": RoomConnection("3b", all_doors["3b_11_east"], all_doors["3b_13_west"]), + "3b_13_east---3b_14_west": RoomConnection("3b", all_doors["3b_13_east"], all_doors["3b_14_west"]), + "3b_14_east---3b_15_west": RoomConnection("3b", all_doors["3b_14_east"], all_doors["3b_15_west"]), + "3b_15_east---3b_12_west": RoomConnection("3b", all_doors["3b_15_east"], all_doors["3b_12_west"]), + "3b_12_east---3b_16_west": RoomConnection("3b", all_doors["3b_12_east"], all_doors["3b_16_west"]), + "3b_16_top---3b_17_west": RoomConnection("3b", all_doors["3b_16_top"], all_doors["3b_17_west"]), + "3b_17_east---3b_18_west": RoomConnection("3b", all_doors["3b_17_east"], all_doors["3b_18_west"]), + "3b_18_east---3b_19_west": RoomConnection("3b", all_doors["3b_18_east"], all_doors["3b_19_west"]), + "3b_19_east---3b_21_west": RoomConnection("3b", all_doors["3b_19_east"], all_doors["3b_21_west"]), + "3b_21_east---3b_20_west": RoomConnection("3b", all_doors["3b_21_east"], all_doors["3b_20_west"]), + "3b_20_east---3b_end_west": RoomConnection("3b", all_doors["3b_20_east"], all_doors["3b_end_west"]), + + "3c_00_east---3c_01_west": RoomConnection("3c", all_doors["3c_00_east"], all_doors["3c_01_west"]), + "3c_01_east---3c_02_west": RoomConnection("3c", all_doors["3c_01_east"], all_doors["3c_02_west"]), + + "4a_a-00_east---4a_a-01_west": RoomConnection("4a", all_doors["4a_a-00_east"], all_doors["4a_a-01_west"]), + "4a_a-01_east---4a_a-01x_west": RoomConnection("4a", all_doors["4a_a-01_east"], all_doors["4a_a-01x_west"]), + "4a_a-01x_east---4a_a-02_west": RoomConnection("4a", all_doors["4a_a-01x_east"], all_doors["4a_a-02_west"]), + "4a_a-02_east---4a_a-03_west": RoomConnection("4a", all_doors["4a_a-02_east"], all_doors["4a_a-03_west"]), + "4a_a-03_east---4a_a-04_west": RoomConnection("4a", all_doors["4a_a-03_east"], all_doors["4a_a-04_west"]), + "4a_a-04_east---4a_a-05_west": RoomConnection("4a", all_doors["4a_a-04_east"], all_doors["4a_a-05_west"]), + "4a_a-05_east---4a_a-06_west": RoomConnection("4a", all_doors["4a_a-05_east"], all_doors["4a_a-06_west"]), + "4a_a-06_east---4a_a-07_west": RoomConnection("4a", all_doors["4a_a-06_east"], all_doors["4a_a-07_west"]), + "4a_a-07_east---4a_a-08_west": RoomConnection("4a", all_doors["4a_a-07_east"], all_doors["4a_a-08_west"]), + "4a_a-08_north-west---4a_a-10_east": RoomConnection("4a", all_doors["4a_a-08_north-west"], all_doors["4a_a-10_east"]), + "4a_a-08_east---4a_a-09_bottom": RoomConnection("4a", all_doors["4a_a-08_east"], all_doors["4a_a-09_bottom"]), + "4a_a-10_west---4a_a-11_east": RoomConnection("4a", all_doors["4a_a-10_west"], all_doors["4a_a-11_east"]), + "4a_a-09_top---4a_b-00_south": RoomConnection("4a", all_doors["4a_a-09_top"], all_doors["4a_b-00_south"]), + "4a_b-00_south-east---4a_b-01_west": RoomConnection("4a", all_doors["4a_b-00_south-east"], all_doors["4a_b-01_west"]), + "4a_b-00_north-west---4a_b-04_east": RoomConnection("4a", all_doors["4a_b-00_north-west"], all_doors["4a_b-04_east"]), + "4a_b-04_west---4a_b-06_east": RoomConnection("4a", all_doors["4a_b-04_west"], all_doors["4a_b-06_east"]), + "4a_b-06_west---4a_b-07_west": RoomConnection("4a", all_doors["4a_b-06_west"], all_doors["4a_b-07_west"]), + "4a_b-07_east---4a_b-03_west": RoomConnection("4a", all_doors["4a_b-07_east"], all_doors["4a_b-03_west"]), + "4a_b-03_east---4a_b-00_west": RoomConnection("4a", all_doors["4a_b-03_east"], all_doors["4a_b-00_west"]), + "4a_b-00_east---4a_b-02_south-west": RoomConnection("4a", all_doors["4a_b-00_east"], all_doors["4a_b-02_south-west"]), + "4a_b-00_north-east---4a_b-02_north-west": RoomConnection("4a", all_doors["4a_b-00_north-east"], all_doors["4a_b-02_north-west"]), + "4a_b-02_north-east---4a_b-sec_west": RoomConnection("4a", all_doors["4a_b-02_north-east"], all_doors["4a_b-sec_west"]), + "4a_b-sec_east---4a_b-secb_west": RoomConnection("4a", all_doors["4a_b-sec_east"], all_doors["4a_b-secb_west"]), + "4a_b-00_north---4a_b-05_center": RoomConnection("4a", all_doors["4a_b-00_north"], all_doors["4a_b-05_center"]), + "4a_b-05_west---4a_b-04_north-west": RoomConnection("4a", all_doors["4a_b-05_west"], all_doors["4a_b-04_north-west"]), + "4a_b-02_north---4a_b-05_east": RoomConnection("4a", all_doors["4a_b-02_north"], all_doors["4a_b-05_east"]), + "4a_b-05_north-east---4a_b-08b_west": RoomConnection("4a", all_doors["4a_b-05_north-east"], all_doors["4a_b-08b_west"]), + "4a_b-08b_east---4a_b-08_west": RoomConnection("4a", all_doors["4a_b-08b_east"], all_doors["4a_b-08_west"]), + "4a_b-08_east---4a_c-00_west": RoomConnection("4a", all_doors["4a_b-08_east"], all_doors["4a_c-00_west"]), + "4a_c-00_north-west---4a_c-01_east": RoomConnection("4a", all_doors["4a_c-00_north-west"], all_doors["4a_c-01_east"]), + "4a_c-00_east---4a_c-02_west": RoomConnection("4a", all_doors["4a_c-00_east"], all_doors["4a_c-02_west"]), + "4a_c-02_east---4a_c-04_west": RoomConnection("4a", all_doors["4a_c-02_east"], all_doors["4a_c-04_west"]), + "4a_c-04_east---4a_c-05_west": RoomConnection("4a", all_doors["4a_c-04_east"], all_doors["4a_c-05_west"]), + "4a_c-05_east---4a_c-06_bottom": RoomConnection("4a", all_doors["4a_c-05_east"], all_doors["4a_c-06_bottom"]), + "4a_c-06_west---4a_c-06b_east": RoomConnection("4a", all_doors["4a_c-06_west"], all_doors["4a_c-06b_east"]), + "4a_c-06_top---4a_c-09_west": RoomConnection("4a", all_doors["4a_c-06_top"], all_doors["4a_c-09_west"]), + "4a_c-09_east---4a_c-07_west": RoomConnection("4a", all_doors["4a_c-09_east"], all_doors["4a_c-07_west"]), + "4a_c-07_east---4a_c-08_bottom": RoomConnection("4a", all_doors["4a_c-07_east"], all_doors["4a_c-08_bottom"]), + "4a_c-08_east---4a_c-10_bottom": RoomConnection("4a", all_doors["4a_c-08_east"], all_doors["4a_c-10_bottom"]), + "4a_c-08_top---4a_d-00_west": RoomConnection("4a", all_doors["4a_c-08_top"], all_doors["4a_d-00_west"]), + "4a_c-10_top---4a_d-00_south": RoomConnection("4a", all_doors["4a_c-10_top"], all_doors["4a_d-00_south"]), + "4a_d-00_north-west---4a_d-00b_east": RoomConnection("4a", all_doors["4a_d-00_north-west"], all_doors["4a_d-00b_east"]), + "4a_d-00_east---4a_d-01_west": RoomConnection("4a", all_doors["4a_d-00_east"], all_doors["4a_d-01_west"]), + "4a_d-01_east---4a_d-02_west": RoomConnection("4a", all_doors["4a_d-01_east"], all_doors["4a_d-02_west"]), + "4a_d-02_east---4a_d-03_west": RoomConnection("4a", all_doors["4a_d-02_east"], all_doors["4a_d-03_west"]), + "4a_d-03_east---4a_d-04_west": RoomConnection("4a", all_doors["4a_d-03_east"], all_doors["4a_d-04_west"]), + "4a_d-04_east---4a_d-05_west": RoomConnection("4a", all_doors["4a_d-04_east"], all_doors["4a_d-05_west"]), + "4a_d-05_east---4a_d-06_west": RoomConnection("4a", all_doors["4a_d-05_east"], all_doors["4a_d-06_west"]), + "4a_d-06_east---4a_d-07_west": RoomConnection("4a", all_doors["4a_d-06_east"], all_doors["4a_d-07_west"]), + "4a_d-07_east---4a_d-08_west": RoomConnection("4a", all_doors["4a_d-07_east"], all_doors["4a_d-08_west"]), + "4a_d-08_east---4a_d-09_west": RoomConnection("4a", all_doors["4a_d-08_east"], all_doors["4a_d-09_west"]), + "4a_d-09_east---4a_d-10_west": RoomConnection("4a", all_doors["4a_d-09_east"], all_doors["4a_d-10_west"]), + + "4b_a-00_east---4b_a-01_west": RoomConnection("4b", all_doors["4b_a-00_east"], all_doors["4b_a-01_west"]), + "4b_a-01_east---4b_a-02_west": RoomConnection("4b", all_doors["4b_a-01_east"], all_doors["4b_a-02_west"]), + "4b_a-02_east---4b_a-03_west": RoomConnection("4b", all_doors["4b_a-02_east"], all_doors["4b_a-03_west"]), + "4b_a-03_east---4b_a-04_west": RoomConnection("4b", all_doors["4b_a-03_east"], all_doors["4b_a-04_west"]), + "4b_a-04_east---4b_b-00_west": RoomConnection("4b", all_doors["4b_a-04_east"], all_doors["4b_b-00_west"]), + "4b_b-00_east---4b_b-01_west": RoomConnection("4b", all_doors["4b_b-00_east"], all_doors["4b_b-01_west"]), + "4b_b-01_east---4b_b-02_bottom": RoomConnection("4b", all_doors["4b_b-01_east"], all_doors["4b_b-02_bottom"]), + "4b_b-02_top---4b_b-03_west": RoomConnection("4b", all_doors["4b_b-02_top"], all_doors["4b_b-03_west"]), + "4b_b-03_east---4b_b-04_west": RoomConnection("4b", all_doors["4b_b-03_east"], all_doors["4b_b-04_west"]), + "4b_b-04_east---4b_c-00_west": RoomConnection("4b", all_doors["4b_b-04_east"], all_doors["4b_c-00_west"]), + "4b_c-00_east---4b_c-01_west": RoomConnection("4b", all_doors["4b_c-00_east"], all_doors["4b_c-01_west"]), + "4b_c-01_east---4b_c-02_west": RoomConnection("4b", all_doors["4b_c-01_east"], all_doors["4b_c-02_west"]), + "4b_c-02_east---4b_c-03_bottom": RoomConnection("4b", all_doors["4b_c-02_east"], all_doors["4b_c-03_bottom"]), + "4b_c-03_top---4b_c-04_west": RoomConnection("4b", all_doors["4b_c-03_top"], all_doors["4b_c-04_west"]), + "4b_c-04_east---4b_d-00_west": RoomConnection("4b", all_doors["4b_c-04_east"], all_doors["4b_d-00_west"]), + "4b_d-00_east---4b_d-01_west": RoomConnection("4b", all_doors["4b_d-00_east"], all_doors["4b_d-01_west"]), + "4b_d-01_east---4b_d-02_west": RoomConnection("4b", all_doors["4b_d-01_east"], all_doors["4b_d-02_west"]), + "4b_d-02_east---4b_d-03_west": RoomConnection("4b", all_doors["4b_d-02_east"], all_doors["4b_d-03_west"]), + "4b_d-03_east---4b_end_west": RoomConnection("4b", all_doors["4b_d-03_east"], all_doors["4b_end_west"]), + + "4c_00_east---4c_01_west": RoomConnection("4c", all_doors["4c_00_east"], all_doors["4c_01_west"]), + "4c_01_east---4c_02_west": RoomConnection("4c", all_doors["4c_01_east"], all_doors["4c_02_west"]), + + "5a_a-00b_west---5a_a-00x_east": RoomConnection("5a", all_doors["5a_a-00b_west"], all_doors["5a_a-00x_east"]), + "5a_a-00b_east---5a_a-00d_west": RoomConnection("5a", all_doors["5a_a-00b_east"], all_doors["5a_a-00d_west"]), + "5a_a-00d_east---5a_a-00c_west": RoomConnection("5a", all_doors["5a_a-00d_east"], all_doors["5a_a-00c_west"]), + "5a_a-00c_east---5a_a-00_west": RoomConnection("5a", all_doors["5a_a-00c_east"], all_doors["5a_a-00_west"]), + "5a_a-00_east---5a_a-01_west": RoomConnection("5a", all_doors["5a_a-00_east"], all_doors["5a_a-01_west"]), + "5a_a-01_east---5a_a-13_west": RoomConnection("5a", all_doors["5a_a-01_east"], all_doors["5a_a-13_west"]), + "5a_a-01_south-west---5a_a-04_north": RoomConnection("5a", all_doors["5a_a-01_south-west"], all_doors["5a_a-04_north"]), + "5a_a-01_south-east---5a_a-02_north": RoomConnection("5a", all_doors["5a_a-01_south-east"], all_doors["5a_a-02_north"]), + "5a_a-01_north---5a_a-08_south": RoomConnection("5a", all_doors["5a_a-01_north"], all_doors["5a_a-08_south"]), + "5a_a-02_west---5a_a-03_east": RoomConnection("5a", all_doors["5a_a-02_west"], all_doors["5a_a-03_east"]), + "5a_a-02_south---5a_a-05_north-east": RoomConnection("5a", all_doors["5a_a-02_south"], all_doors["5a_a-05_north-east"]), + "5a_a-04_east---5a_a-03_west": RoomConnection("5a", all_doors["5a_a-04_east"], all_doors["5a_a-03_west"]), + "5a_a-04_south---5a_a-05_north-west": RoomConnection("5a", all_doors["5a_a-04_south"], all_doors["5a_a-05_north-west"]), + "5a_a-05_south-west---5a_a-07_east": RoomConnection("5a", all_doors["5a_a-05_south-west"], all_doors["5a_a-07_east"]), + "5a_a-05_south-east---5a_a-06_west": RoomConnection("5a", all_doors["5a_a-05_south-east"], all_doors["5a_a-06_west"]), + "5a_a-08_west---5a_a-10_east": RoomConnection("5a", all_doors["5a_a-08_west"], all_doors["5a_a-10_east"]), + "5a_a-08_north---5a_a-14_south": RoomConnection("5a", all_doors["5a_a-08_north"], all_doors["5a_a-14_south"]), + "5a_a-08_north-east---5a_a-12_north-west": RoomConnection("5a", all_doors["5a_a-08_north-east"], all_doors["5a_a-12_north-west"]), + "5a_a-08_south-east---5a_a-12_south-west": RoomConnection("5a", all_doors["5a_a-08_south-east"], all_doors["5a_a-12_south-west"]), + "5a_a-10_west---5a_a-09_east": RoomConnection("5a", all_doors["5a_a-10_west"], all_doors["5a_a-09_east"]), + "5a_a-09_west---5a_a-11_east": RoomConnection("5a", all_doors["5a_a-09_west"], all_doors["5a_a-11_east"]), + "5a_a-12_west---5a_a-08_east": RoomConnection("5a", all_doors["5a_a-12_west"], all_doors["5a_a-08_east"]), + "5a_a-12_east---5a_a-15_south": RoomConnection("5a", all_doors["5a_a-12_east"], all_doors["5a_a-15_south"]), + "5a_a-13_east---5a_b-00_west": RoomConnection("5a", all_doors["5a_a-13_east"], all_doors["5a_b-00_west"]), + "5a_b-00_north-west---5a_b-18_south": RoomConnection("5a", all_doors["5a_b-00_north-west"], all_doors["5a_b-18_south"]), + "5a_b-00_east---5a_b-01_south-west": RoomConnection("5a", all_doors["5a_b-00_east"], all_doors["5a_b-01_south-west"]), + "5a_b-01_west---5a_b-20_west": RoomConnection("5a", all_doors["5a_b-01_west"], all_doors["5a_b-20_west"]), + "5a_b-01_north---5a_b-20_south": RoomConnection("5a", all_doors["5a_b-01_north"], all_doors["5a_b-20_south"]), + "5a_b-01_north-east---5a_b-20_east": RoomConnection("5a", all_doors["5a_b-01_north-east"], all_doors["5a_b-20_east"]), + "5a_b-01_east---5a_b-01b_west": RoomConnection("5a", all_doors["5a_b-01_east"], all_doors["5a_b-01b_west"]), + "5a_b-01_south---5a_b-01c_west": RoomConnection("5a", all_doors["5a_b-01_south"], all_doors["5a_b-01c_west"]), + "5a_b-01c_east---5a_b-01_south-east": RoomConnection("5a", all_doors["5a_b-01c_east"], all_doors["5a_b-01_south-east"]), + "5a_b-20_south-west---5a_b-01_north-west": RoomConnection("5a", all_doors["5a_b-20_south-west"], all_doors["5a_b-01_north-west"]), + "5a_b-20_north-west---5a_b-21_east": RoomConnection("5a", all_doors["5a_b-20_north-west"], all_doors["5a_b-21_east"]), + "5a_b-01b_east---5a_b-02_west": RoomConnection("5a", all_doors["5a_b-01b_east"], all_doors["5a_b-02_west"]), + "5a_b-02_north-west---5a_b-03_east": RoomConnection("5a", all_doors["5a_b-02_north-west"], all_doors["5a_b-03_east"]), + "5a_b-02_north---5a_b-04_south": RoomConnection("5a", all_doors["5a_b-02_north"], all_doors["5a_b-04_south"]), + "5a_b-02_north-east---5a_b-05_west": RoomConnection("5a", all_doors["5a_b-02_north-east"], all_doors["5a_b-05_west"]), + "5a_b-02_east-upper---5a_b-06_west": RoomConnection("5a", all_doors["5a_b-02_east-upper"], all_doors["5a_b-06_west"]), + "5a_b-02_east-lower---5a_b-11_north-west": RoomConnection("5a", all_doors["5a_b-02_east-lower"], all_doors["5a_b-11_north-west"]), + "5a_b-02_south-east---5a_b-11_west": RoomConnection("5a", all_doors["5a_b-02_south-east"], all_doors["5a_b-11_west"]), + "5a_b-02_south---5a_b-10_east": RoomConnection("5a", all_doors["5a_b-02_south"], all_doors["5a_b-10_east"]), + "5a_b-04_west---5a_b-07_south": RoomConnection("5a", all_doors["5a_b-04_west"], all_doors["5a_b-07_south"]), + "5a_b-07_north---5a_b-08_west": RoomConnection("5a", all_doors["5a_b-07_north"], all_doors["5a_b-08_west"]), + "5a_b-08_east---5a_b-09_north": RoomConnection("5a", all_doors["5a_b-08_east"], all_doors["5a_b-09_north"]), + "5a_b-09_south---5a_b-04_east": RoomConnection("5a", all_doors["5a_b-09_south"], all_doors["5a_b-04_east"]), + "5a_b-11_south-west---5a_b-12_west": RoomConnection("5a", all_doors["5a_b-11_south-west"], all_doors["5a_b-12_west"]), + "5a_b-11_south-east---5a_b-12_east": RoomConnection("5a", all_doors["5a_b-11_south-east"], all_doors["5a_b-12_east"]), + "5a_b-11_east---5a_b-13_west": RoomConnection("5a", all_doors["5a_b-11_east"], all_doors["5a_b-13_west"]), + "5a_b-13_east---5a_b-17_west": RoomConnection("5a", all_doors["5a_b-13_east"], all_doors["5a_b-17_west"]), + "5a_b-13_north-east---5a_b-17_north-west": RoomConnection("5a", all_doors["5a_b-13_north-east"], all_doors["5a_b-17_north-west"]), + "5a_b-17_east---5a_b-22_west": RoomConnection("5a", all_doors["5a_b-17_east"], all_doors["5a_b-22_west"]), + "5a_b-06_east---5a_b-19_west": RoomConnection("5a", all_doors["5a_b-06_east"], all_doors["5a_b-19_west"]), + "5a_b-06_north-east---5a_b-19_north-west": RoomConnection("5a", all_doors["5a_b-06_north-east"], all_doors["5a_b-19_north-west"]), + "5a_b-19_east---5a_b-14_west": RoomConnection("5a", all_doors["5a_b-19_east"], all_doors["5a_b-14_west"]), + "5a_b-14_south---5a_b-15_west": RoomConnection("5a", all_doors["5a_b-14_south"], all_doors["5a_b-15_west"]), + "5a_b-14_north---5a_b-16_bottom": RoomConnection("5a", all_doors["5a_b-14_north"], all_doors["5a_b-16_bottom"]), + "5a_b-16_mirror---5a_void_east": RoomConnection("5a", all_doors["5a_b-16_mirror"], all_doors["5a_void_east"]), + "5a_void_west---5a_c-00_top": RoomConnection("5a", all_doors["5a_void_west"], all_doors["5a_c-00_top"]), + "5a_c-00_bottom---5a_c-01_west": RoomConnection("5a", all_doors["5a_c-00_bottom"], all_doors["5a_c-01_west"]), + "5a_c-01_east---5a_c-01b_west": RoomConnection("5a", all_doors["5a_c-01_east"], all_doors["5a_c-01b_west"]), + "5a_c-01b_east---5a_c-01c_west": RoomConnection("5a", all_doors["5a_c-01b_east"], all_doors["5a_c-01c_west"]), + "5a_c-01c_east---5a_c-08b_west": RoomConnection("5a", all_doors["5a_c-01c_east"], all_doors["5a_c-08b_west"]), + "5a_c-08b_east---5a_c-08_west": RoomConnection("5a", all_doors["5a_c-08b_east"], all_doors["5a_c-08_west"]), + "5a_c-08_east---5a_c-10_west": RoomConnection("5a", all_doors["5a_c-08_east"], all_doors["5a_c-10_west"]), + "5a_c-10_east---5a_c-12_west": RoomConnection("5a", all_doors["5a_c-10_east"], all_doors["5a_c-12_west"]), + "5a_c-12_east---5a_c-07_west": RoomConnection("5a", all_doors["5a_c-12_east"], all_doors["5a_c-07_west"]), + "5a_c-07_east---5a_c-11_west": RoomConnection("5a", all_doors["5a_c-07_east"], all_doors["5a_c-11_west"]), + "5a_c-11_east---5a_c-09_west": RoomConnection("5a", all_doors["5a_c-11_east"], all_doors["5a_c-09_west"]), + "5a_c-09_east---5a_c-13_west": RoomConnection("5a", all_doors["5a_c-09_east"], all_doors["5a_c-13_west"]), + "5a_c-13_east---5a_d-00_south": RoomConnection("5a", all_doors["5a_c-13_east"], all_doors["5a_d-00_south"]), + "5a_d-00_north---5a_d-01_south": RoomConnection("5a", all_doors["5a_d-00_north"], all_doors["5a_d-01_south"]), + "5a_d-00_west---5a_d-05_east": RoomConnection("5a", all_doors["5a_d-00_west"], all_doors["5a_d-05_east"]), + "5a_d-05_south---5a_d-02_east": RoomConnection("5a", all_doors["5a_d-05_south"], all_doors["5a_d-02_east"]), + "5a_d-01_north-west---5a_d-09_east": RoomConnection("5a", all_doors["5a_d-01_north-west"], all_doors["5a_d-09_east"]), + "5a_d-01_west---5a_d-09_east": RoomConnection("5a", all_doors["5a_d-01_west"], all_doors["5a_d-09_east"]), + "5a_d-01_south-west-down---5a_d-05_north": RoomConnection("5a", all_doors["5a_d-01_south-west-down"], all_doors["5a_d-05_north"]), + "5a_d-01_south-east-down---5a_d-07_north": RoomConnection("5a", all_doors["5a_d-01_south-east-down"], all_doors["5a_d-07_north"]), + "5a_d-01_south-east-right---5a_d-15_south-west": RoomConnection("5a", all_doors["5a_d-01_south-east-right"], all_doors["5a_d-15_south-west"]), + "5a_d-01_east---5a_d-15_west": RoomConnection("5a", all_doors["5a_d-01_east"], all_doors["5a_d-15_west"]), + "5a_d-01_north-east---5a_d-15_north-west": RoomConnection("5a", all_doors["5a_d-01_north-east"], all_doors["5a_d-15_north-west"]), + "5a_d-09_west---5a_d-04_north": RoomConnection("5a", all_doors["5a_d-09_west"], all_doors["5a_d-04_north"]), + "5a_d-04_west---5a_d-19b_south-east-right": RoomConnection("5a", all_doors["5a_d-04_west"], all_doors["5a_d-19b_south-east-right"]), + "5a_d-04_south-east---5a_d-01_south-west-left": RoomConnection("5a", all_doors["5a_d-04_south-east"], all_doors["5a_d-01_south-west-left"]), + "5a_d-05_west---5a_d-06_south-east": RoomConnection("5a", all_doors["5a_d-05_west"], all_doors["5a_d-06_south-east"]), + "5a_d-05_south---5a_d-02_east": RoomConnection("5a", all_doors["5a_d-05_south"], all_doors["5a_d-02_east"]), + "5a_d-06_north-east---5a_d-04_south-west-right": RoomConnection("5a", all_doors["5a_d-06_north-east"], all_doors["5a_d-04_south-west-right"]), + "5a_d-06_north-west---5a_d-04_south-west-left": RoomConnection("5a", all_doors["5a_d-06_north-west"], all_doors["5a_d-04_south-west-left"]), + "5a_d-07_west---5a_d-00_east": RoomConnection("5a", all_doors["5a_d-07_west"], all_doors["5a_d-00_east"]), + "5a_d-02_west---5a_d-03_east": RoomConnection("5a", all_doors["5a_d-02_west"], all_doors["5a_d-03_east"]), + "5a_d-03_west---5a_d-06_south-west": RoomConnection("5a", all_doors["5a_d-03_west"], all_doors["5a_d-06_south-west"]), + "5a_d-15_south-east---5a_d-13_east": RoomConnection("5a", all_doors["5a_d-15_south-east"], all_doors["5a_d-13_east"]), + "5a_d-13_west---5a_d-15_south": RoomConnection("5a", all_doors["5a_d-13_west"], all_doors["5a_d-15_south"]), + "5a_d-19b_south-east-down---5a_d-19_east": RoomConnection("5a", all_doors["5a_d-19b_south-east-down"], all_doors["5a_d-19_east"]), + "5a_d-19b_north-east---5a_d-10_west": RoomConnection("5a", all_doors["5a_d-19b_north-east"], all_doors["5a_d-10_west"]), + "5a_d-19_west---5a_d-19b_south-west": RoomConnection("5a", all_doors["5a_d-19_west"], all_doors["5a_d-19b_south-west"]), + "5a_d-10_east---5a_d-20_west": RoomConnection("5a", all_doors["5a_d-10_east"], all_doors["5a_d-20_west"]), + "5a_d-20_east---5a_e-00_west": RoomConnection("5a", all_doors["5a_d-20_east"], all_doors["5a_e-00_west"]), + "5a_e-00_east---5a_e-01_west": RoomConnection("5a", all_doors["5a_e-00_east"], all_doors["5a_e-01_west"]), + "5a_e-01_east---5a_e-02_west": RoomConnection("5a", all_doors["5a_e-01_east"], all_doors["5a_e-02_west"]), + "5a_e-02_east---5a_e-03_west": RoomConnection("5a", all_doors["5a_e-02_east"], all_doors["5a_e-03_west"]), + "5a_e-03_east---5a_e-04_west": RoomConnection("5a", all_doors["5a_e-03_east"], all_doors["5a_e-04_west"]), + "5a_e-04_east---5a_e-06_west": RoomConnection("5a", all_doors["5a_e-04_east"], all_doors["5a_e-06_west"]), + "5a_e-06_east---5a_e-05_west": RoomConnection("5a", all_doors["5a_e-06_east"], all_doors["5a_e-05_west"]), + "5a_e-05_east---5a_e-07_west": RoomConnection("5a", all_doors["5a_e-05_east"], all_doors["5a_e-07_west"]), + "5a_e-07_east---5a_e-08_west": RoomConnection("5a", all_doors["5a_e-07_east"], all_doors["5a_e-08_west"]), + "5a_e-08_east---5a_e-09_west": RoomConnection("5a", all_doors["5a_e-08_east"], all_doors["5a_e-09_west"]), + "5a_e-09_east---5a_e-10_west": RoomConnection("5a", all_doors["5a_e-09_east"], all_doors["5a_e-10_west"]), + "5a_e-10_east---5a_e-11_west": RoomConnection("5a", all_doors["5a_e-10_east"], all_doors["5a_e-11_west"]), + + "5b_start_east---5b_a-00_west": RoomConnection("5b", all_doors["5b_start_east"], all_doors["5b_a-00_west"]), + "5b_a-00_east---5b_a-01_west": RoomConnection("5b", all_doors["5b_a-00_east"], all_doors["5b_a-01_west"]), + "5b_a-01_east---5b_a-02_west": RoomConnection("5b", all_doors["5b_a-01_east"], all_doors["5b_a-02_west"]), + "5b_a-02_east---5b_b-00_south": RoomConnection("5b", all_doors["5b_a-02_east"], all_doors["5b_b-00_south"]), + "5b_b-00_east---5b_b-01_west": RoomConnection("5b", all_doors["5b_b-00_east"], all_doors["5b_b-01_west"]), + "5b_b-00_north---5b_b-02_south": RoomConnection("5b", all_doors["5b_b-00_north"], all_doors["5b_b-02_south"]), + "5b_b-00_west---5b_b-06_east": RoomConnection("5b", all_doors["5b_b-00_west"], all_doors["5b_b-06_east"]), + "5b_b-01_north---5b_b-04_east": RoomConnection("5b", all_doors["5b_b-01_north"], all_doors["5b_b-04_east"]), + "5b_b-01_east---5b_b-07_south": RoomConnection("5b", all_doors["5b_b-01_east"], all_doors["5b_b-07_south"]), + "5b_b-04_west---5b_b-02_south-east": RoomConnection("5b", all_doors["5b_b-04_west"], all_doors["5b_b-02_south-east"]), + "5b_b-02_north-west---5b_b-05_north": RoomConnection("5b", all_doors["5b_b-02_north-west"], all_doors["5b_b-05_north"]), + "5b_b-02_north-east---5b_b-03_west": RoomConnection("5b", all_doors["5b_b-02_north-east"], all_doors["5b_b-03_west"]), + "5b_b-02_north---5b_b-08_south": RoomConnection("5b", all_doors["5b_b-02_north"], all_doors["5b_b-08_south"]), + "5b_b-05_south---5b_b-02_south-west": RoomConnection("5b", all_doors["5b_b-05_south"], all_doors["5b_b-02_south-west"]), + "5b_b-07_north---5b_b-03_east": RoomConnection("5b", all_doors["5b_b-07_north"], all_doors["5b_b-03_east"]), + "5b_b-03_north---5b_b-08_east": RoomConnection("5b", all_doors["5b_b-03_north"], all_doors["5b_b-08_east"]), + "5b_b-08_north---5b_b-09_bottom": RoomConnection("5b", all_doors["5b_b-08_north"], all_doors["5b_b-09_bottom"]), + "5b_b-09_mirror---5b_c-00_mirror": RoomConnection("5b", all_doors["5b_b-09_mirror"], all_doors["5b_c-00_mirror"]), + "5b_c-00_bottom---5b_c-01_west": RoomConnection("5b", all_doors["5b_c-00_bottom"], all_doors["5b_c-01_west"]), + "5b_c-01_east---5b_c-02_west": RoomConnection("5b", all_doors["5b_c-01_east"], all_doors["5b_c-02_west"]), + "5b_c-02_east---5b_c-03_west": RoomConnection("5b", all_doors["5b_c-02_east"], all_doors["5b_c-03_west"]), + "5b_c-03_east---5b_c-04_west": RoomConnection("5b", all_doors["5b_c-03_east"], all_doors["5b_c-04_west"]), + "5b_c-04_east---5b_d-00_west": RoomConnection("5b", all_doors["5b_c-04_east"], all_doors["5b_d-00_west"]), + "5b_d-00_east---5b_d-01_west": RoomConnection("5b", all_doors["5b_d-00_east"], all_doors["5b_d-01_west"]), + "5b_d-00_east---5b_d-01_west": RoomConnection("5b", all_doors["5b_d-00_east"], all_doors["5b_d-01_west"]), + "5b_d-01_east---5b_d-02_west": RoomConnection("5b", all_doors["5b_d-01_east"], all_doors["5b_d-02_west"]), + "5b_d-02_east---5b_d-03_west": RoomConnection("5b", all_doors["5b_d-02_east"], all_doors["5b_d-03_west"]), + "5b_d-03_east---5b_d-04_west": RoomConnection("5b", all_doors["5b_d-03_east"], all_doors["5b_d-04_west"]), + "5b_d-04_east---5b_d-05_west": RoomConnection("5b", all_doors["5b_d-04_east"], all_doors["5b_d-05_west"]), + + "5c_00_east---5c_01_west": RoomConnection("5c", all_doors["5c_00_east"], all_doors["5c_01_west"]), + "5c_01_east---5c_02_west": RoomConnection("5c", all_doors["5c_01_east"], all_doors["5c_02_west"]), + + "6a_00_west---6a_01_bottom": RoomConnection("6a", all_doors["6a_00_west"], all_doors["6a_01_bottom"]), + "6a_01_top---6a_02_bottom": RoomConnection("6a", all_doors["6a_01_top"], all_doors["6a_02_bottom"]), + "6a_02_bottom-west---6a_03_bottom": RoomConnection("6a", all_doors["6a_02_bottom-west"], all_doors["6a_03_bottom"]), + "6a_02_top---6a_02b_bottom": RoomConnection("6a", all_doors["6a_02_top"], all_doors["6a_02b_bottom"]), + "6a_03_top---6a_02_top-west": RoomConnection("6a", all_doors["6a_03_top"], all_doors["6a_02_top-west"]), + "6a_02b_top---6a_04_south": RoomConnection("6a", all_doors["6a_02b_top"], all_doors["6a_04_south"]), + "6a_04_north-west---6a_04b_east": RoomConnection("6a", all_doors["6a_04_north-west"], all_doors["6a_04b_east"]), + "6a_04_south-east---6a_04d_west": RoomConnection("6a", all_doors["6a_04_south-east"], all_doors["6a_04d_west"]), + "6a_04_east---6a_05_west": RoomConnection("6a", all_doors["6a_04_east"], all_doors["6a_05_west"]), + "6a_04_south-west---6a_04e_east": RoomConnection("6a", all_doors["6a_04_south-west"], all_doors["6a_04e_east"]), + "6a_04b_west---6a_04c_east": RoomConnection("6a", all_doors["6a_04b_west"], all_doors["6a_04c_east"]), + "6a_05_east---6a_06_west": RoomConnection("6a", all_doors["6a_05_east"], all_doors["6a_06_west"]), + "6a_06_east---6a_07_west": RoomConnection("6a", all_doors["6a_06_east"], all_doors["6a_07_west"]), + "6a_07_east---6a_08a_west": RoomConnection("6a", all_doors["6a_07_east"], all_doors["6a_08a_west"]), + "6a_07_north-east---6a_08b_west": RoomConnection("6a", all_doors["6a_07_north-east"], all_doors["6a_08b_west"]), + "6a_08a_east---6a_09_west": RoomConnection("6a", all_doors["6a_08a_east"], all_doors["6a_09_west"]), + "6a_08b_east---6a_09_north-west": RoomConnection("6a", all_doors["6a_08b_east"], all_doors["6a_09_north-west"]), + "6a_09_east---6a_10a_west": RoomConnection("6a", all_doors["6a_09_east"], all_doors["6a_10a_west"]), + "6a_09_north-east---6a_10b_west": RoomConnection("6a", all_doors["6a_09_north-east"], all_doors["6a_10b_west"]), + "6a_10a_east---6a_11_west": RoomConnection("6a", all_doors["6a_10a_east"], all_doors["6a_11_west"]), + "6a_10b_east---6a_11_north-west": RoomConnection("6a", all_doors["6a_10b_east"], all_doors["6a_11_north-west"]), + "6a_11_east---6a_12a_west": RoomConnection("6a", all_doors["6a_11_east"], all_doors["6a_12a_west"]), + "6a_11_north-east---6a_12b_west": RoomConnection("6a", all_doors["6a_11_north-east"], all_doors["6a_12b_west"]), + "6a_12a_east---6a_13_west": RoomConnection("6a", all_doors["6a_12a_east"], all_doors["6a_13_west"]), + "6a_12b_east---6a_13_north-west": RoomConnection("6a", all_doors["6a_12b_east"], all_doors["6a_13_north-west"]), + "6a_13_east---6a_14a_west": RoomConnection("6a", all_doors["6a_13_east"], all_doors["6a_14a_west"]), + "6a_13_north-east---6a_14b_west": RoomConnection("6a", all_doors["6a_13_north-east"], all_doors["6a_14b_west"]), + "6a_14a_east---6a_15_west": RoomConnection("6a", all_doors["6a_14a_east"], all_doors["6a_15_west"]), + "6a_14b_east---6a_15_north-west": RoomConnection("6a", all_doors["6a_14b_east"], all_doors["6a_15_north-west"]), + "6a_15_east---6a_16a_west": RoomConnection("6a", all_doors["6a_15_east"], all_doors["6a_16a_west"]), + "6a_15_north-east---6a_16b_west": RoomConnection("6a", all_doors["6a_15_north-east"], all_doors["6a_16b_west"]), + "6a_16a_east---6a_17_west": RoomConnection("6a", all_doors["6a_16a_east"], all_doors["6a_17_west"]), + "6a_16b_east---6a_17_north-west": RoomConnection("6a", all_doors["6a_16b_east"], all_doors["6a_17_north-west"]), + "6a_17_east---6a_18a_west": RoomConnection("6a", all_doors["6a_17_east"], all_doors["6a_18a_west"]), + "6a_17_north-east---6a_18b_west": RoomConnection("6a", all_doors["6a_17_north-east"], all_doors["6a_18b_west"]), + "6a_18a_east---6a_19_west": RoomConnection("6a", all_doors["6a_18a_east"], all_doors["6a_19_west"]), + "6a_18b_east---6a_19_north-west": RoomConnection("6a", all_doors["6a_18b_east"], all_doors["6a_19_north-west"]), + "6a_19_east---6a_20_west": RoomConnection("6a", all_doors["6a_19_east"], all_doors["6a_20_west"]), + "6a_20_east---6a_b-00_west": RoomConnection("6a", all_doors["6a_20_east"], all_doors["6a_b-00_west"]), + "6a_b-00_east---6a_b-01_west": RoomConnection("6a", all_doors["6a_b-00_east"], all_doors["6a_b-01_west"]), + "6a_b-00_top---6a_b-00b_bottom": RoomConnection("6a", all_doors["6a_b-00_top"], all_doors["6a_b-00b_bottom"]), + "6a_b-00b_top---6a_b-00c_east": RoomConnection("6a", all_doors["6a_b-00b_top"], all_doors["6a_b-00c_east"]), + "6a_b-01_east---6a_b-02_top": RoomConnection("6a", all_doors["6a_b-01_east"], all_doors["6a_b-02_top"]), + "6a_b-02_bottom---6a_b-02b_top": RoomConnection("6a", all_doors["6a_b-02_bottom"], all_doors["6a_b-02b_top"]), + "6a_b-02b_bottom---6a_b-03_west": RoomConnection("6a", all_doors["6a_b-02b_bottom"], all_doors["6a_b-03_west"]), + "6a_b-03_east---6a_boss-00_west": RoomConnection("6a", all_doors["6a_b-03_east"], all_doors["6a_boss-00_west"]), + "6a_boss-00_east---6a_boss-01_west": RoomConnection("6a", all_doors["6a_boss-00_east"], all_doors["6a_boss-01_west"]), + "6a_boss-01_east---6a_boss-02_west": RoomConnection("6a", all_doors["6a_boss-01_east"], all_doors["6a_boss-02_west"]), + "6a_boss-02_east---6a_boss-03_west": RoomConnection("6a", all_doors["6a_boss-02_east"], all_doors["6a_boss-03_west"]), + "6a_boss-03_east---6a_boss-04_west": RoomConnection("6a", all_doors["6a_boss-03_east"], all_doors["6a_boss-04_west"]), + "6a_boss-04_east---6a_boss-05_west": RoomConnection("6a", all_doors["6a_boss-04_east"], all_doors["6a_boss-05_west"]), + "6a_boss-05_east---6a_boss-06_west": RoomConnection("6a", all_doors["6a_boss-05_east"], all_doors["6a_boss-06_west"]), + "6a_boss-06_east---6a_boss-07_west": RoomConnection("6a", all_doors["6a_boss-06_east"], all_doors["6a_boss-07_west"]), + "6a_boss-07_east---6a_boss-08_west": RoomConnection("6a", all_doors["6a_boss-07_east"], all_doors["6a_boss-08_west"]), + "6a_boss-08_east---6a_boss-09_west": RoomConnection("6a", all_doors["6a_boss-08_east"], all_doors["6a_boss-09_west"]), + "6a_boss-09_east---6a_boss-10_west": RoomConnection("6a", all_doors["6a_boss-09_east"], all_doors["6a_boss-10_west"]), + "6a_boss-10_east---6a_boss-11_west": RoomConnection("6a", all_doors["6a_boss-10_east"], all_doors["6a_boss-11_west"]), + "6a_boss-11_east---6a_boss-12_west": RoomConnection("6a", all_doors["6a_boss-11_east"], all_doors["6a_boss-12_west"]), + "6a_boss-12_east---6a_boss-13_west": RoomConnection("6a", all_doors["6a_boss-12_east"], all_doors["6a_boss-13_west"]), + "6a_boss-13_east---6a_boss-14_west": RoomConnection("6a", all_doors["6a_boss-13_east"], all_doors["6a_boss-14_west"]), + "6a_boss-14_east---6a_boss-15_west": RoomConnection("6a", all_doors["6a_boss-14_east"], all_doors["6a_boss-15_west"]), + "6a_boss-15_east---6a_boss-16_west": RoomConnection("6a", all_doors["6a_boss-15_east"], all_doors["6a_boss-16_west"]), + "6a_boss-16_east---6a_boss-17_west": RoomConnection("6a", all_doors["6a_boss-16_east"], all_doors["6a_boss-17_west"]), + "6a_boss-17_east---6a_boss-18_west": RoomConnection("6a", all_doors["6a_boss-17_east"], all_doors["6a_boss-18_west"]), + "6a_boss-18_east---6a_boss-19_west": RoomConnection("6a", all_doors["6a_boss-18_east"], all_doors["6a_boss-19_west"]), + "6a_boss-19_east---6a_boss-20_west": RoomConnection("6a", all_doors["6a_boss-19_east"], all_doors["6a_boss-20_west"]), + "6a_boss-20_east---6a_after-00_bottom": RoomConnection("6a", all_doors["6a_boss-20_east"], all_doors["6a_after-00_bottom"]), + "6a_after-00_top---6a_after-01_bottom": RoomConnection("6a", all_doors["6a_after-00_top"], all_doors["6a_after-01_bottom"]), + + "6b_a-00_top---6b_a-01_bottom": RoomConnection("6b", all_doors["6b_a-00_top"], all_doors["6b_a-01_bottom"]), + "6b_a-01_top---6b_a-02_bottom": RoomConnection("6b", all_doors["6b_a-01_top"], all_doors["6b_a-02_bottom"]), + "6b_a-02_top---6b_a-03_west": RoomConnection("6b", all_doors["6b_a-02_top"], all_doors["6b_a-03_west"]), + "6b_a-03_east---6b_a-04_west": RoomConnection("6b", all_doors["6b_a-03_east"], all_doors["6b_a-04_west"]), + "6b_a-04_east---6b_a-05_west": RoomConnection("6b", all_doors["6b_a-04_east"], all_doors["6b_a-05_west"]), + "6b_a-05_east---6b_a-06_west": RoomConnection("6b", all_doors["6b_a-05_east"], all_doors["6b_a-06_west"]), + "6b_a-06_east---6b_b-00_west": RoomConnection("6b", all_doors["6b_a-06_east"], all_doors["6b_b-00_west"]), + "6b_b-00_east---6b_b-01_top": RoomConnection("6b", all_doors["6b_b-00_east"], all_doors["6b_b-01_top"]), + "6b_b-01_bottom---6b_b-02_top": RoomConnection("6b", all_doors["6b_b-01_bottom"], all_doors["6b_b-02_top"]), + "6b_b-02_bottom---6b_b-03_top": RoomConnection("6b", all_doors["6b_b-02_bottom"], all_doors["6b_b-03_top"]), + "6b_b-03_bottom---6b_b-04_top": RoomConnection("6b", all_doors["6b_b-03_bottom"], all_doors["6b_b-04_top"]), + "6b_b-04_bottom---6b_b-05_top": RoomConnection("6b", all_doors["6b_b-04_bottom"], all_doors["6b_b-05_top"]), + "6b_b-05_bottom---6b_b-06_top": RoomConnection("6b", all_doors["6b_b-05_bottom"], all_doors["6b_b-06_top"]), + "6b_b-06_bottom---6b_b-07_top": RoomConnection("6b", all_doors["6b_b-06_bottom"], all_doors["6b_b-07_top"]), + "6b_b-07_bottom---6b_b-08_top": RoomConnection("6b", all_doors["6b_b-07_bottom"], all_doors["6b_b-08_top"]), + "6b_b-08_bottom---6b_b-10_west": RoomConnection("6b", all_doors["6b_b-08_bottom"], all_doors["6b_b-10_west"]), + "6b_b-10_east---6b_c-00_west": RoomConnection("6b", all_doors["6b_b-10_east"], all_doors["6b_c-00_west"]), + "6b_c-00_east---6b_c-01_west": RoomConnection("6b", all_doors["6b_c-00_east"], all_doors["6b_c-01_west"]), + "6b_c-01_east---6b_c-02_west": RoomConnection("6b", all_doors["6b_c-01_east"], all_doors["6b_c-02_west"]), + "6b_c-02_east---6b_c-03_west": RoomConnection("6b", all_doors["6b_c-02_east"], all_doors["6b_c-03_west"]), + "6b_c-03_east---6b_c-04_west": RoomConnection("6b", all_doors["6b_c-03_east"], all_doors["6b_c-04_west"]), + "6b_c-04_east---6b_d-00_west": RoomConnection("6b", all_doors["6b_c-04_east"], all_doors["6b_d-00_west"]), + "6b_d-00_east---6b_d-01_west": RoomConnection("6b", all_doors["6b_d-00_east"], all_doors["6b_d-01_west"]), + "6b_d-01_east---6b_d-02_west": RoomConnection("6b", all_doors["6b_d-01_east"], all_doors["6b_d-02_west"]), + "6b_d-02_east---6b_d-03_west": RoomConnection("6b", all_doors["6b_d-02_east"], all_doors["6b_d-03_west"]), + "6b_d-03_east---6b_d-04_west": RoomConnection("6b", all_doors["6b_d-03_east"], all_doors["6b_d-04_west"]), + "6b_d-04_east---6b_d-05_west": RoomConnection("6b", all_doors["6b_d-04_east"], all_doors["6b_d-05_west"]), + + "6c_00_east---6c_01_west": RoomConnection("6c", all_doors["6c_00_east"], all_doors["6c_01_west"]), + "6c_01_east---6c_02_west": RoomConnection("6c", all_doors["6c_01_east"], all_doors["6c_02_west"]), + + "7a_a-00_east---7a_a-01_west": RoomConnection("7a", all_doors["7a_a-00_east"], all_doors["7a_a-01_west"]), + "7a_a-01_east---7a_a-02_west": RoomConnection("7a", all_doors["7a_a-01_east"], all_doors["7a_a-02_west"]), + "7a_a-02_north---7a_a-02b_east": RoomConnection("7a", all_doors["7a_a-02_north"], all_doors["7a_a-02b_east"]), + "7a_a-02b_west---7a_a-02_north-west": RoomConnection("7a", all_doors["7a_a-02b_west"], all_doors["7a_a-02_north-west"]), + "7a_a-02_east---7a_a-03_west": RoomConnection("7a", all_doors["7a_a-02_east"], all_doors["7a_a-03_west"]), + "7a_a-03_east---7a_a-04_west": RoomConnection("7a", all_doors["7a_a-03_east"], all_doors["7a_a-04_west"]), + "7a_a-04_north---7a_a-04b_east": RoomConnection("7a", all_doors["7a_a-04_north"], all_doors["7a_a-04b_east"]), + "7a_a-04_east---7a_a-05_west": RoomConnection("7a", all_doors["7a_a-04_east"], all_doors["7a_a-05_west"]), + "7a_a-05_east---7a_a-06_bottom": RoomConnection("7a", all_doors["7a_a-05_east"], all_doors["7a_a-06_bottom"]), + "7a_a-06_top---7a_b-00_bottom": RoomConnection("7a", all_doors["7a_a-06_top"], all_doors["7a_b-00_bottom"]), + "7a_b-00_top---7a_b-01_west": RoomConnection("7a", all_doors["7a_b-00_top"], all_doors["7a_b-01_west"]), + "7a_b-01_east---7a_b-02_south": RoomConnection("7a", all_doors["7a_b-01_east"], all_doors["7a_b-02_south"]), + "7a_b-02_north-west---7a_b-02b_south": RoomConnection("7a", all_doors["7a_b-02_north-west"], all_doors["7a_b-02b_south"]), + "7a_b-02_north---7a_b-02d_south": RoomConnection("7a", all_doors["7a_b-02_north"], all_doors["7a_b-02d_south"]), + "7a_b-02_north-east---7a_b-03_west": RoomConnection("7a", all_doors["7a_b-02_north-east"], all_doors["7a_b-03_west"]), + "7a_b-02b_north-west---7a_b-02e_east": RoomConnection("7a", all_doors["7a_b-02b_north-west"], all_doors["7a_b-02e_east"]), + "7a_b-02b_north-east---7a_b-02c_west": RoomConnection("7a", all_doors["7a_b-02b_north-east"], all_doors["7a_b-02c_west"]), + "7a_b-02c_east---7a_b-05_north-west": RoomConnection("7a", all_doors["7a_b-02c_east"], all_doors["7a_b-05_north-west"]), + "7a_b-02c_south-east---7a_b-02d_north": RoomConnection("7a", all_doors["7a_b-02c_south-east"], all_doors["7a_b-02d_north"]), + "7a_b-03_east---7a_b-04_west": RoomConnection("7a", all_doors["7a_b-03_east"], all_doors["7a_b-04_west"]), + "7a_b-03_north---7a_b-05_west": RoomConnection("7a", all_doors["7a_b-03_north"], all_doors["7a_b-05_west"]), + "7a_b-05_east---7a_b-06_west": RoomConnection("7a", all_doors["7a_b-05_east"], all_doors["7a_b-06_west"]), + "7a_b-06_east---7a_b-07_west": RoomConnection("7a", all_doors["7a_b-06_east"], all_doors["7a_b-07_west"]), + "7a_b-07_east---7a_b-08_west": RoomConnection("7a", all_doors["7a_b-07_east"], all_doors["7a_b-08_west"]), + "7a_b-08_east---7a_b-09_bottom": RoomConnection("7a", all_doors["7a_b-08_east"], all_doors["7a_b-09_bottom"]), + "7a_b-09_top---7a_c-00_west": RoomConnection("7a", all_doors["7a_b-09_top"], all_doors["7a_c-00_west"]), + "7a_c-00_east---7a_c-01_bottom": RoomConnection("7a", all_doors["7a_c-00_east"], all_doors["7a_c-01_bottom"]), + "7a_c-01_top---7a_c-02_bottom": RoomConnection("7a", all_doors["7a_c-01_top"], all_doors["7a_c-02_bottom"]), + "7a_c-02_top---7a_c-03_south": RoomConnection("7a", all_doors["7a_c-02_top"], all_doors["7a_c-03_south"]), + "7a_c-03_west---7a_c-03b_east": RoomConnection("7a", all_doors["7a_c-03_west"], all_doors["7a_c-03b_east"]), + "7a_c-03_east---7a_c-04_west": RoomConnection("7a", all_doors["7a_c-03_east"], all_doors["7a_c-04_west"]), + "7a_c-04_north-west---7a_c-06_south": RoomConnection("7a", all_doors["7a_c-04_north-west"], all_doors["7a_c-06_south"]), + "7a_c-04_north-east---7a_c-06b_south": RoomConnection("7a", all_doors["7a_c-04_north-east"], all_doors["7a_c-06b_south"]), + "7a_c-04_east---7a_c-05_west": RoomConnection("7a", all_doors["7a_c-04_east"], all_doors["7a_c-05_west"]), + "7a_c-06_east---7a_c-06b_west": RoomConnection("7a", all_doors["7a_c-06_east"], all_doors["7a_c-06b_west"]), + "7a_c-06_north---7a_c-07_south-west": RoomConnection("7a", all_doors["7a_c-06_north"], all_doors["7a_c-07_south-west"]), + "7a_c-06b_east---7a_c-06c_west": RoomConnection("7a", all_doors["7a_c-06b_east"], all_doors["7a_c-06c_west"]), + "7a_c-06b_north---7a_c-07_south-east": RoomConnection("7a", all_doors["7a_c-06b_north"], all_doors["7a_c-07_south-east"]), + "7a_c-07_west---7a_c-07b_east": RoomConnection("7a", all_doors["7a_c-07_west"], all_doors["7a_c-07b_east"]), + "7a_c-07_east---7a_c-08_west": RoomConnection("7a", all_doors["7a_c-07_east"], all_doors["7a_c-08_west"]), + "7a_c-08_east---7a_c-09_bottom": RoomConnection("7a", all_doors["7a_c-08_east"], all_doors["7a_c-09_bottom"]), + "7a_c-09_top---7a_d-00_bottom": RoomConnection("7a", all_doors["7a_c-09_top"], all_doors["7a_d-00_bottom"]), + "7a_d-00_top---7a_d-01_west": RoomConnection("7a", all_doors["7a_d-00_top"], all_doors["7a_d-01_west"]), + "7a_d-01_east---7a_d-01b_west": RoomConnection("7a", all_doors["7a_d-01_east"], all_doors["7a_d-01b_west"]), + "7a_d-01b_east---7a_d-02_west": RoomConnection("7a", all_doors["7a_d-01b_east"], all_doors["7a_d-02_west"]), + "7a_d-01b_south-west---7a_d-01c_west": RoomConnection("7a", all_doors["7a_d-01b_south-west"], all_doors["7a_d-01c_west"]), + "7a_d-01c_south---7a_d-01d_west": RoomConnection("7a", all_doors["7a_d-01c_south"], all_doors["7a_d-01d_west"]), + "7a_d-01c_east---7a_d-01b_south-east": RoomConnection("7a", all_doors["7a_d-01c_east"], all_doors["7a_d-01b_south-east"]), + "7a_d-01d_east---7a_d-01c_south-east": RoomConnection("7a", all_doors["7a_d-01d_east"], all_doors["7a_d-01c_south-east"]), + "7a_d-02_east---7a_d-03_west": RoomConnection("7a", all_doors["7a_d-02_east"], all_doors["7a_d-03_west"]), + "7a_d-03_east---7a_d-04_west": RoomConnection("7a", all_doors["7a_d-03_east"], all_doors["7a_d-04_west"]), + "7a_d-03_north-east---7a_d-03b_east": RoomConnection("7a", all_doors["7a_d-03_north-east"], all_doors["7a_d-03b_east"]), + "7a_d-03b_west---7a_d-03_north-west": RoomConnection("7a", all_doors["7a_d-03b_west"], all_doors["7a_d-03_north-west"]), + "7a_d-04_east---7a_d-05_west": RoomConnection("7a", all_doors["7a_d-04_east"], all_doors["7a_d-05_west"]), + "7a_d-05_east---7a_d-05b_west": RoomConnection("7a", all_doors["7a_d-05_east"], all_doors["7a_d-05b_west"]), + "7a_d-05_north-east---7a_d-06_south-west": RoomConnection("7a", all_doors["7a_d-05_north-east"], all_doors["7a_d-06_south-west"]), + "7a_d-06_west---7a_d-07_east": RoomConnection("7a", all_doors["7a_d-06_west"], all_doors["7a_d-07_east"]), + "7a_d-06_south-east---7a_d-08_west": RoomConnection("7a", all_doors["7a_d-06_south-east"], all_doors["7a_d-08_west"]), + "7a_d-06_east---7a_d-09_west": RoomConnection("7a", all_doors["7a_d-06_east"], all_doors["7a_d-09_west"]), + "7a_d-08_east---7a_d-10_west": RoomConnection("7a", all_doors["7a_d-08_east"], all_doors["7a_d-10_west"]), + "7a_d-09_east---7a_d-10_north-west": RoomConnection("7a", all_doors["7a_d-09_east"], all_doors["7a_d-10_north-west"]), + "7a_d-10_north-east---7a_d-10b_east": RoomConnection("7a", all_doors["7a_d-10_north-east"], all_doors["7a_d-10b_east"]), + "7a_d-10_east---7a_d-11_bottom": RoomConnection("7a", all_doors["7a_d-10_east"], all_doors["7a_d-11_bottom"]), + "7a_d-10b_west---7a_d-10_north": RoomConnection("7a", all_doors["7a_d-10b_west"], all_doors["7a_d-10_north"]), + "7a_d-11_top---7a_e-00b_bottom": RoomConnection("7a", all_doors["7a_d-11_top"], all_doors["7a_e-00b_bottom"]), + "7a_e-00b_top---7a_e-00_south-west": RoomConnection("7a", all_doors["7a_e-00b_top"], all_doors["7a_e-00_south-west"]), + "7a_e-00_west---7a_e-01_east": RoomConnection("7a", all_doors["7a_e-00_west"], all_doors["7a_e-01_east"]), + "7a_e-00_north-west---7a_e-02_west": RoomConnection("7a", all_doors["7a_e-00_north-west"], all_doors["7a_e-02_west"]), + "7a_e-00_east---7a_e-03_south-west": RoomConnection("7a", all_doors["7a_e-00_east"], all_doors["7a_e-03_south-west"]), + "7a_e-01_west---7a_e-01b_east": RoomConnection("7a", all_doors["7a_e-01_west"], all_doors["7a_e-01b_east"]), + "7a_e-01b_west---7a_e-01c_west": RoomConnection("7a", all_doors["7a_e-01b_west"], all_doors["7a_e-01c_west"]), + "7a_e-01c_east---7a_e-01_north": RoomConnection("7a", all_doors["7a_e-01c_east"], all_doors["7a_e-01_north"]), + "7a_e-02_east---7a_e-03_west": RoomConnection("7a", all_doors["7a_e-02_east"], all_doors["7a_e-03_west"]), + "7a_e-03_east---7a_e-04_west": RoomConnection("7a", all_doors["7a_e-03_east"], all_doors["7a_e-04_west"]), + "7a_e-04_east---7a_e-05_west": RoomConnection("7a", all_doors["7a_e-04_east"], all_doors["7a_e-05_west"]), + "7a_e-05_east---7a_e-06_west": RoomConnection("7a", all_doors["7a_e-05_east"], all_doors["7a_e-06_west"]), + "7a_e-06_east---7a_e-07_bottom": RoomConnection("7a", all_doors["7a_e-06_east"], all_doors["7a_e-07_bottom"]), + "7a_e-07_top---7a_e-08_south": RoomConnection("7a", all_doors["7a_e-07_top"], all_doors["7a_e-08_south"]), + "7a_e-08_west---7a_e-09_east": RoomConnection("7a", all_doors["7a_e-08_west"], all_doors["7a_e-09_east"]), + "7a_e-08_east---7a_e-10_south": RoomConnection("7a", all_doors["7a_e-08_east"], all_doors["7a_e-10_south"]), + "7a_e-09_north---7a_e-11_south": RoomConnection("7a", all_doors["7a_e-09_north"], all_doors["7a_e-11_south"]), + "7a_e-11_north---7a_e-12_west": RoomConnection("7a", all_doors["7a_e-11_north"], all_doors["7a_e-12_west"]), + "7a_e-11_east---7a_e-10_north": RoomConnection("7a", all_doors["7a_e-11_east"], all_doors["7a_e-10_north"]), + "7a_e-10_east---7a_e-10b_west": RoomConnection("7a", all_doors["7a_e-10_east"], all_doors["7a_e-10b_west"]), + "7a_e-10b_east---7a_e-13_bottom": RoomConnection("7a", all_doors["7a_e-10b_east"], all_doors["7a_e-13_bottom"]), + "7a_e-13_top---7a_f-00_south": RoomConnection("7a", all_doors["7a_e-13_top"], all_doors["7a_f-00_south"]), + "7a_f-00_west---7a_f-01_south": RoomConnection("7a", all_doors["7a_f-00_west"], all_doors["7a_f-01_south"]), + "7a_f-00_east---7a_f-02_west": RoomConnection("7a", all_doors["7a_f-00_east"], all_doors["7a_f-02_west"]), + "7a_f-00_north-east---7a_f-02_north-west": RoomConnection("7a", all_doors["7a_f-00_north-east"], all_doors["7a_f-02_north-west"]), + "7a_f-01_north---7a_f-00_north-west": RoomConnection("7a", all_doors["7a_f-01_north"], all_doors["7a_f-00_north-west"]), + "7a_f-02_north-east---7a_f-02b_west": RoomConnection("7a", all_doors["7a_f-02_north-east"], all_doors["7a_f-02b_west"]), + "7a_f-02_east---7a_f-04_west": RoomConnection("7a", all_doors["7a_f-02_east"], all_doors["7a_f-04_west"]), + "7a_f-02b_east---7a_f-07_west": RoomConnection("7a", all_doors["7a_f-02b_east"], all_doors["7a_f-07_west"]), + "7a_f-04_east---7a_f-03_west": RoomConnection("7a", all_doors["7a_f-04_east"], all_doors["7a_f-03_west"]), + "7a_f-03_east---7a_f-05_west": RoomConnection("7a", all_doors["7a_f-03_east"], all_doors["7a_f-05_west"]), + "7a_f-05_east---7a_f-08_west": RoomConnection("7a", all_doors["7a_f-05_east"], all_doors["7a_f-08_west"]), + "7a_f-05_south-west---7a_f-06_north-west": RoomConnection("7a", all_doors["7a_f-05_south-west"], all_doors["7a_f-06_north-west"]), + "7a_f-05_south---7a_f-06_north": RoomConnection("7a", all_doors["7a_f-05_south"], all_doors["7a_f-06_north"]), + "7a_f-05_south-east---7a_f-06_north-east": RoomConnection("7a", all_doors["7a_f-05_south-east"], all_doors["7a_f-06_north-east"]), + "7a_f-05_north-west---7a_f-07_south-west": RoomConnection("7a", all_doors["7a_f-05_north-west"], all_doors["7a_f-07_south-west"]), + "7a_f-05_north---7a_f-07_south": RoomConnection("7a", all_doors["7a_f-05_north"], all_doors["7a_f-07_south"]), + "7a_f-05_north-east---7a_f-07_south-east": RoomConnection("7a", all_doors["7a_f-05_north-east"], all_doors["7a_f-07_south-east"]), + "7a_f-08_north-west---7a_f-08b_west": RoomConnection("7a", all_doors["7a_f-08_north-west"], all_doors["7a_f-08b_west"]), + "7a_f-08_east---7a_f-09_west": RoomConnection("7a", all_doors["7a_f-08_east"], all_doors["7a_f-09_west"]), + "7a_f-09_east---7a_f-10_west": RoomConnection("7a", all_doors["7a_f-09_east"], all_doors["7a_f-10_west"]), + "7a_f-08b_east---7a_f-08d_west": RoomConnection("7a", all_doors["7a_f-08b_east"], all_doors["7a_f-08d_west"]), + "7a_f-08d_east---7a_f-08c_west": RoomConnection("7a", all_doors["7a_f-08d_east"], all_doors["7a_f-08c_west"]), + "7a_f-08c_east---7a_f-10_north-east": RoomConnection("7a", all_doors["7a_f-08c_east"], all_doors["7a_f-10_north-east"]), + "7a_f-10_east---7a_f-10b_west": RoomConnection("7a", all_doors["7a_f-10_east"], all_doors["7a_f-10b_west"]), + "7a_f-10b_east---7a_f-11_bottom": RoomConnection("7a", all_doors["7a_f-10b_east"], all_doors["7a_f-11_bottom"]), + "7a_f-11_top---7a_g-00_bottom": RoomConnection("7a", all_doors["7a_f-11_top"], all_doors["7a_g-00_bottom"]), + "7a_g-00_top---7a_g-00b_bottom": RoomConnection("7a", all_doors["7a_g-00_top"], all_doors["7a_g-00b_bottom"]), + "7a_g-00b_top---7a_g-01_bottom": RoomConnection("7a", all_doors["7a_g-00b_top"], all_doors["7a_g-01_bottom"]), + "7a_g-01_top---7a_g-02_bottom": RoomConnection("7a", all_doors["7a_g-01_top"], all_doors["7a_g-02_bottom"]), + "7a_g-02_top---7a_g-03_bottom": RoomConnection("7a", all_doors["7a_g-02_top"], all_doors["7a_g-03_bottom"]), + + "7b_a-00_east---7b_a-01_west": RoomConnection("7b", all_doors["7b_a-00_east"], all_doors["7b_a-01_west"]), + "7b_a-01_east---7b_a-02_west": RoomConnection("7b", all_doors["7b_a-01_east"], all_doors["7b_a-02_west"]), + "7b_a-02_east---7b_a-03_bottom": RoomConnection("7b", all_doors["7b_a-02_east"], all_doors["7b_a-03_bottom"]), + "7b_a-03_top---7b_b-00_bottom": RoomConnection("7b", all_doors["7b_a-03_top"], all_doors["7b_b-00_bottom"]), + "7b_b-00_top---7b_b-01_bottom": RoomConnection("7b", all_doors["7b_b-00_top"], all_doors["7b_b-01_bottom"]), + "7b_b-01_top---7b_b-02_west": RoomConnection("7b", all_doors["7b_b-01_top"], all_doors["7b_b-02_west"]), + "7b_b-02_east---7b_b-03_bottom": RoomConnection("7b", all_doors["7b_b-02_east"], all_doors["7b_b-03_bottom"]), + "7b_b-03_top---7b_c-01_west": RoomConnection("7b", all_doors["7b_b-03_top"], all_doors["7b_c-01_west"]), + "7b_c-01_east---7b_c-00_west": RoomConnection("7b", all_doors["7b_c-01_east"], all_doors["7b_c-00_west"]), + "7b_c-00_east---7b_c-02_west": RoomConnection("7b", all_doors["7b_c-00_east"], all_doors["7b_c-02_west"]), + "7b_c-02_east---7b_c-03_bottom": RoomConnection("7b", all_doors["7b_c-02_east"], all_doors["7b_c-03_bottom"]), + "7b_c-03_top---7b_d-00_west": RoomConnection("7b", all_doors["7b_c-03_top"], all_doors["7b_d-00_west"]), + "7b_d-00_east---7b_d-01_west": RoomConnection("7b", all_doors["7b_d-00_east"], all_doors["7b_d-01_west"]), + "7b_d-01_east---7b_d-02_west": RoomConnection("7b", all_doors["7b_d-01_east"], all_doors["7b_d-02_west"]), + "7b_d-02_east---7b_d-03_bottom": RoomConnection("7b", all_doors["7b_d-02_east"], all_doors["7b_d-03_bottom"]), + "7b_d-03_top---7b_e-00_west": RoomConnection("7b", all_doors["7b_d-03_top"], all_doors["7b_e-00_west"]), + "7b_e-00_east---7b_e-01_west": RoomConnection("7b", all_doors["7b_e-00_east"], all_doors["7b_e-01_west"]), + "7b_e-01_east---7b_e-02_west": RoomConnection("7b", all_doors["7b_e-01_east"], all_doors["7b_e-02_west"]), + "7b_e-02_east---7b_e-03_bottom": RoomConnection("7b", all_doors["7b_e-02_east"], all_doors["7b_e-03_bottom"]), + "7b_e-03_top---7b_f-00_west": RoomConnection("7b", all_doors["7b_e-03_top"], all_doors["7b_f-00_west"]), + "7b_f-00_east---7b_f-01_west": RoomConnection("7b", all_doors["7b_f-00_east"], all_doors["7b_f-01_west"]), + "7b_f-01_east---7b_f-02_west": RoomConnection("7b", all_doors["7b_f-01_east"], all_doors["7b_f-02_west"]), + "7b_f-02_east---7b_f-03_bottom": RoomConnection("7b", all_doors["7b_f-02_east"], all_doors["7b_f-03_bottom"]), + "7b_f-03_top---7b_g-00_bottom": RoomConnection("7b", all_doors["7b_f-03_top"], all_doors["7b_g-00_bottom"]), + "7b_g-00_top---7b_g-01_bottom": RoomConnection("7b", all_doors["7b_g-00_top"], all_doors["7b_g-01_bottom"]), + "7b_g-01_top---7b_g-02_bottom": RoomConnection("7b", all_doors["7b_g-01_top"], all_doors["7b_g-02_bottom"]), + "7b_g-02_top---7b_g-03_bottom": RoomConnection("7b", all_doors["7b_g-02_top"], all_doors["7b_g-03_bottom"]), + + "7c_01_east---7c_02_west": RoomConnection("7c", all_doors["7c_01_east"], all_doors["7c_02_west"]), + "7c_02_east---7c_03_west": RoomConnection("7c", all_doors["7c_02_east"], all_doors["7c_03_west"]), + + "8a_outside_east---8a_bridge_west": RoomConnection("8a", all_doors["8a_outside_east"], all_doors["8a_bridge_west"]), + "8a_bridge_east---8a_secret_west": RoomConnection("8a", all_doors["8a_bridge_east"], all_doors["8a_secret_west"]), + + "9a_00_east---9a_01_west": RoomConnection("9a", all_doors["9a_00_east"], all_doors["9a_01_west"]), + "9a_00_west---9a_0x_east": RoomConnection("9a", all_doors["9a_00_west"], all_doors["9a_0x_east"]), + "9a_01_east---9a_02_west": RoomConnection("9a", all_doors["9a_01_east"], all_doors["9a_02_west"]), + "9a_02_east---9a_a-00_west": RoomConnection("9a", all_doors["9a_02_east"], all_doors["9a_a-00_west"]), + "9a_a-00_east---9a_a-01_west": RoomConnection("9a", all_doors["9a_a-00_east"], all_doors["9a_a-01_west"]), + "9a_a-01_east---9a_a-02_west": RoomConnection("9a", all_doors["9a_a-01_east"], all_doors["9a_a-02_west"]), + "9a_a-02_east---9a_a-03_bottom": RoomConnection("9a", all_doors["9a_a-02_east"], all_doors["9a_a-03_bottom"]), + "9a_a-03_top---9a_b-00_south": RoomConnection("9a", all_doors["9a_a-03_top"], all_doors["9a_b-00_south"]), + "9a_b-00_west---9a_b-06_east": RoomConnection("9a", all_doors["9a_b-00_west"], all_doors["9a_b-06_east"]), + "9a_b-00_east---9a_b-01_west": RoomConnection("9a", all_doors["9a_b-00_east"], all_doors["9a_b-01_west"]), + "9a_b-00_north---9a_b-07b_bottom": RoomConnection("9a", all_doors["9a_b-00_north"], all_doors["9a_b-07b_bottom"]), + "9a_b-01_east---9a_b-02_west": RoomConnection("9a", all_doors["9a_b-01_east"], all_doors["9a_b-02_west"]), + "9a_b-02_east---9a_b-03_west": RoomConnection("9a", all_doors["9a_b-02_east"], all_doors["9a_b-03_west"]), + "9a_b-03_east---9a_b-04_west": RoomConnection("9a", all_doors["9a_b-03_east"], all_doors["9a_b-04_west"]), + "9a_b-04_east---9a_b-05_east": RoomConnection("9a", all_doors["9a_b-04_east"], all_doors["9a_b-05_east"]), + "9a_b-05_west---9a_b-04_north-west": RoomConnection("9a", all_doors["9a_b-05_west"], all_doors["9a_b-04_north-west"]), + "9a_b-07b_top---9a_b-07_bottom": RoomConnection("9a", all_doors["9a_b-07b_top"], all_doors["9a_b-07_bottom"]), + "9a_b-07_top---9a_c-00_west": RoomConnection("9a", all_doors["9a_b-07_top"], all_doors["9a_c-00_west"]), + "9a_c-00_north-east---9a_c-00b_west": RoomConnection("9a", all_doors["9a_c-00_north-east"], all_doors["9a_c-00b_west"]), + "9a_c-00_east---9a_c-01_west": RoomConnection("9a", all_doors["9a_c-00_east"], all_doors["9a_c-01_west"]), + "9a_c-01_east---9a_c-02_west": RoomConnection("9a", all_doors["9a_c-01_east"], all_doors["9a_c-02_west"]), + "9a_c-02_east---9a_c-03_west": RoomConnection("9a", all_doors["9a_c-02_east"], all_doors["9a_c-03_west"]), + "9a_c-03_east---9a_c-04_west": RoomConnection("9a", all_doors["9a_c-03_east"], all_doors["9a_c-04_west"]), + "9a_c-03_north---9a_c-03b_south": RoomConnection("9a", all_doors["9a_c-03_north"], all_doors["9a_c-03b_south"]), + "9a_c-03b_west---9a_c-03_north-west": RoomConnection("9a", all_doors["9a_c-03b_west"], all_doors["9a_c-03_north-west"]), + "9a_c-03b_east---9a_c-03_north-east": RoomConnection("9a", all_doors["9a_c-03b_east"], all_doors["9a_c-03_north-east"]), + "9a_c-04_east---9a_d-00_bottom": RoomConnection("9a", all_doors["9a_c-04_east"], all_doors["9a_d-00_bottom"]), + "9a_d-00_top---9a_d-01_bottom": RoomConnection("9a", all_doors["9a_d-00_top"], all_doors["9a_d-01_bottom"]), + "9a_d-01_top---9a_d-02_bottom": RoomConnection("9a", all_doors["9a_d-01_top"], all_doors["9a_d-02_bottom"]), + "9a_d-02_top---9a_d-03_bottom": RoomConnection("9a", all_doors["9a_d-02_top"], all_doors["9a_d-03_bottom"]), + "9a_d-03_top---9a_d-04_bottom": RoomConnection("9a", all_doors["9a_d-03_top"], all_doors["9a_d-04_bottom"]), + "9a_d-04_top---9a_d-05_bottom": RoomConnection("9a", all_doors["9a_d-04_top"], all_doors["9a_d-05_bottom"]), + "9a_d-05_top---9a_d-06_bottom": RoomConnection("9a", all_doors["9a_d-05_top"], all_doors["9a_d-06_bottom"]), + "9a_d-06_top---9a_d-07_bottom": RoomConnection("9a", all_doors["9a_d-06_top"], all_doors["9a_d-07_bottom"]), + "9a_d-07_top---9a_d-08_west": RoomConnection("9a", all_doors["9a_d-07_top"], all_doors["9a_d-08_west"]), + "9a_d-08_east---9a_d-09_west": RoomConnection("9a", all_doors["9a_d-08_east"], all_doors["9a_d-09_west"]), + "9a_d-09_east---9a_d-10_west": RoomConnection("9a", all_doors["9a_d-09_east"], all_doors["9a_d-10_west"]), + "9a_d-10_east---9a_d-10b_west": RoomConnection("9a", all_doors["9a_d-10_east"], all_doors["9a_d-10b_west"]), + "9a_d-10b_east---9a_d-10c_west": RoomConnection("9a", all_doors["9a_d-10b_east"], all_doors["9a_d-10c_west"]), + "9a_d-10c_east---9a_d-11_west": RoomConnection("9a", all_doors["9a_d-10c_east"], all_doors["9a_d-11_west"]), + "9a_d-11_east---9a_space_west": RoomConnection("9a", all_doors["9a_d-11_east"], all_doors["9a_space_west"]), + + "9b_00_east---9b_01_west": RoomConnection("9b", all_doors["9b_00_east"], all_doors["9b_01_west"]), + "9b_01_east---9b_a-00_west": RoomConnection("9b", all_doors["9b_01_east"], all_doors["9b_a-00_west"]), + "9b_a-00_east---9b_a-01_west": RoomConnection("9b", all_doors["9b_a-00_east"], all_doors["9b_a-01_west"]), + "9b_a-01_east---9b_a-02_west": RoomConnection("9b", all_doors["9b_a-01_east"], all_doors["9b_a-02_west"]), + "9b_a-02_east---9b_a-03_west": RoomConnection("9b", all_doors["9b_a-02_east"], all_doors["9b_a-03_west"]), + "9b_a-03_east---9b_a-04_west": RoomConnection("9b", all_doors["9b_a-03_east"], all_doors["9b_a-04_west"]), + "9b_a-04_east---9b_a-05_west": RoomConnection("9b", all_doors["9b_a-04_east"], all_doors["9b_a-05_west"]), + "9b_a-05_east---9b_b-00_west": RoomConnection("9b", all_doors["9b_a-05_east"], all_doors["9b_b-00_west"]), + "9b_b-00_east---9b_b-01_west": RoomConnection("9b", all_doors["9b_b-00_east"], all_doors["9b_b-01_west"]), + "9b_b-01_east---9b_b-02_west": RoomConnection("9b", all_doors["9b_b-01_east"], all_doors["9b_b-02_west"]), + "9b_b-02_east---9b_b-03_west": RoomConnection("9b", all_doors["9b_b-02_east"], all_doors["9b_b-03_west"]), + "9b_b-03_east---9b_b-04_west": RoomConnection("9b", all_doors["9b_b-03_east"], all_doors["9b_b-04_west"]), + "9b_b-04_east---9b_b-05_west": RoomConnection("9b", all_doors["9b_b-04_east"], all_doors["9b_b-05_west"]), + "9b_b-05_east---9b_c-01_bottom": RoomConnection("9b", all_doors["9b_b-05_east"], all_doors["9b_c-01_bottom"]), + "9b_c-01_top---9b_c-02_bottom": RoomConnection("9b", all_doors["9b_c-01_top"], all_doors["9b_c-02_bottom"]), + "9b_c-02_top---9b_c-03_bottom": RoomConnection("9b", all_doors["9b_c-02_top"], all_doors["9b_c-03_bottom"]), + "9b_c-03_top---9b_c-04_bottom": RoomConnection("9b", all_doors["9b_c-03_top"], all_doors["9b_c-04_bottom"]), + "9b_c-04_top---9b_c-05_west": RoomConnection("9b", all_doors["9b_c-04_top"], all_doors["9b_c-05_west"]), + "9b_c-05_east---9b_c-06_west": RoomConnection("9b", all_doors["9b_c-05_east"], all_doors["9b_c-06_west"]), + "9b_c-06_east---9b_c-08_west": RoomConnection("9b", all_doors["9b_c-06_east"], all_doors["9b_c-08_west"]), + "9b_c-08_east---9b_c-07_west": RoomConnection("9b", all_doors["9b_c-08_east"], all_doors["9b_c-07_west"]), + "9b_c-07_east---9b_space_west": RoomConnection("9b", all_doors["9b_c-07_east"], all_doors["9b_space_west"]), + + "9c_intro_east---9c_00_west": RoomConnection("9c", all_doors["9c_intro_east"], all_doors["9c_00_west"]), + "9c_00_east---9c_01_west": RoomConnection("9c", all_doors["9c_00_east"], all_doors["9c_01_west"]), + "9c_01_east---9c_02_west": RoomConnection("9c", all_doors["9c_01_east"], all_doors["9c_02_west"]), + + "10a_intro-00-past_east---10a_intro-01-future_west": RoomConnection("10a", all_doors["10a_intro-00-past_east"], all_doors["10a_intro-01-future_west"]), + "10a_intro-01-future_east---10a_intro-02-launch_bottom": RoomConnection("10a", all_doors["10a_intro-01-future_east"], all_doors["10a_intro-02-launch_bottom"]), + "10a_intro-02-launch_top---10a_intro-03-space_west": RoomConnection("10a", all_doors["10a_intro-02-launch_top"], all_doors["10a_intro-03-space_west"]), + "10a_intro-03-space_east---10a_a-00_west": RoomConnection("10a", all_doors["10a_intro-03-space_east"], all_doors["10a_a-00_west"]), + "10a_a-00_east---10a_a-01_west": RoomConnection("10a", all_doors["10a_a-00_east"], all_doors["10a_a-01_west"]), + "10a_a-01_east---10a_a-02_west": RoomConnection("10a", all_doors["10a_a-01_east"], all_doors["10a_a-02_west"]), + "10a_a-02_east---10a_a-03_west": RoomConnection("10a", all_doors["10a_a-02_east"], all_doors["10a_a-03_west"]), + "10a_a-03_east---10a_a-04_west": RoomConnection("10a", all_doors["10a_a-03_east"], all_doors["10a_a-04_west"]), + "10a_a-04_east---10a_a-05_west": RoomConnection("10a", all_doors["10a_a-04_east"], all_doors["10a_a-05_west"]), + "10a_a-05_east---10a_b-00_west": RoomConnection("10a", all_doors["10a_a-05_east"], all_doors["10a_b-00_west"]), + "10a_b-00_east---10a_b-01_west": RoomConnection("10a", all_doors["10a_b-00_east"], all_doors["10a_b-01_west"]), + "10a_b-01_east---10a_b-02_west": RoomConnection("10a", all_doors["10a_b-01_east"], all_doors["10a_b-02_west"]), + "10a_b-02_east---10a_b-03_west": RoomConnection("10a", all_doors["10a_b-02_east"], all_doors["10a_b-03_west"]), + "10a_b-03_east---10a_b-04_west": RoomConnection("10a", all_doors["10a_b-03_east"], all_doors["10a_b-04_west"]), + "10a_b-04_east---10a_b-05_west": RoomConnection("10a", all_doors["10a_b-04_east"], all_doors["10a_b-05_west"]), + "10a_b-05_east---10a_b-06_west": RoomConnection("10a", all_doors["10a_b-05_east"], all_doors["10a_b-06_west"]), + "10a_b-06_east---10a_b-07_west": RoomConnection("10a", all_doors["10a_b-06_east"], all_doors["10a_b-07_west"]), + "10a_b-07_east---10a_c-00_west": RoomConnection("10a", all_doors["10a_b-07_east"], all_doors["10a_c-00_west"]), + "10a_c-00_east---10a_c-00b_west": RoomConnection("10a", all_doors["10a_c-00_east"], all_doors["10a_c-00b_west"]), + "10a_c-00_north-east---10a_c-alt-00_west": RoomConnection("10a", all_doors["10a_c-00_north-east"], all_doors["10a_c-alt-00_west"]), + "10a_c-00b_east---10a_c-01_west": RoomConnection("10a", all_doors["10a_c-00b_east"], all_doors["10a_c-01_west"]), + "10a_c-01_east---10a_c-02_west": RoomConnection("10a", all_doors["10a_c-01_east"], all_doors["10a_c-02_west"]), + "10a_c-02_east---10a_c-03_south": RoomConnection("10a", all_doors["10a_c-02_east"], all_doors["10a_c-03_south"]), + "10a_c-alt-00_east---10a_c-alt-01_west": RoomConnection("10a", all_doors["10a_c-alt-00_east"], all_doors["10a_c-alt-01_west"]), + "10a_c-alt-01_east---10a_c-03_south-west": RoomConnection("10a", all_doors["10a_c-alt-01_east"], all_doors["10a_c-03_south-west"]), + "10a_c-03_north---10a_d-00_south": RoomConnection("10a", all_doors["10a_c-03_north"], all_doors["10a_d-00_south"]), + "10a_d-00_north-east-door---10a_d-04_west": RoomConnection("10a", all_doors["10a_d-00_north-east-door"], all_doors["10a_d-04_west"]), + "10a_d-00_south-east-door---10a_d-03_west": RoomConnection("10a", all_doors["10a_d-00_south-east-door"], all_doors["10a_d-03_west"]), + "10a_d-00_south-west-door---10a_d-01_east": RoomConnection("10a", all_doors["10a_d-00_south-west-door"], all_doors["10a_d-01_east"]), + "10a_d-00_west-door---10a_d-02_bottom": RoomConnection("10a", all_doors["10a_d-00_west-door"], all_doors["10a_d-02_bottom"]), + "10a_d-00_north-west-door---10a_d-05_west": RoomConnection("10a", all_doors["10a_d-00_north-west-door"], all_doors["10a_d-05_west"]), + "10a_d-00_north---10a_d-05_south": RoomConnection("10a", all_doors["10a_d-00_north"], all_doors["10a_d-05_south"]), + "10a_d-05_north---10a_e-00y_south": RoomConnection("10a", all_doors["10a_d-05_north"], all_doors["10a_e-00y_south"]), + "10a_e-00y_north---10a_e-00z_south": RoomConnection("10a", all_doors["10a_e-00y_north"], all_doors["10a_e-00z_south"]), + "10a_e-00y_south-east---10a_e-00yb_south": RoomConnection("10a", all_doors["10a_e-00y_south-east"], all_doors["10a_e-00yb_south"]), + "10a_e-00yb_north---10a_e-00y_north-east": RoomConnection("10a", all_doors["10a_e-00yb_north"], all_doors["10a_e-00y_north-east"]), + "10a_e-00z_north---10a_e-00_south": RoomConnection("10a", all_doors["10a_e-00z_north"], all_doors["10a_e-00_south"]), + "10a_e-00_north---10a_e-00b_south": RoomConnection("10a", all_doors["10a_e-00_north"], all_doors["10a_e-00b_south"]), + "10a_e-00b_north---10a_e-01_south": RoomConnection("10a", all_doors["10a_e-00b_north"], all_doors["10a_e-01_south"]), + "10a_e-01_north---10a_e-02_west": RoomConnection("10a", all_doors["10a_e-01_north"], all_doors["10a_e-02_west"]), + "10a_e-02_east---10a_e-03_west": RoomConnection("10a", all_doors["10a_e-02_east"], all_doors["10a_e-03_west"]), + "10a_e-03_east---10a_e-04_west": RoomConnection("10a", all_doors["10a_e-03_east"], all_doors["10a_e-04_west"]), + "10a_e-04_east---10a_e-05_west": RoomConnection("10a", all_doors["10a_e-04_east"], all_doors["10a_e-05_west"]), + "10a_e-05_east---10a_e-05b_west": RoomConnection("10a", all_doors["10a_e-05_east"], all_doors["10a_e-05b_west"]), + "10a_e-05b_east---10a_e-05c_west": RoomConnection("10a", all_doors["10a_e-05b_east"], all_doors["10a_e-05c_west"]), + "10a_e-05c_east---10a_e-06_west": RoomConnection("10a", all_doors["10a_e-05c_east"], all_doors["10a_e-06_west"]), + "10a_e-06_east---10a_e-07_west": RoomConnection("10a", all_doors["10a_e-06_east"], all_doors["10a_e-07_west"]), + "10a_e-07_east---10a_e-08_west": RoomConnection("10a", all_doors["10a_e-07_east"], all_doors["10a_e-08_west"]), + + "10b_f-door_east---10b_f-00_west": RoomConnection("10b", all_doors["10b_f-door_east"], all_doors["10b_f-00_west"]), + "10b_f-00_east---10b_f-01_west": RoomConnection("10b", all_doors["10b_f-00_east"], all_doors["10b_f-01_west"]), + "10b_f-01_east---10b_f-02_west": RoomConnection("10b", all_doors["10b_f-01_east"], all_doors["10b_f-02_west"]), + "10b_f-02_east---10b_f-03_west": RoomConnection("10b", all_doors["10b_f-02_east"], all_doors["10b_f-03_west"]), + "10b_f-03_east---10b_f-04_west": RoomConnection("10b", all_doors["10b_f-03_east"], all_doors["10b_f-04_west"]), + "10b_f-04_east---10b_f-05_west": RoomConnection("10b", all_doors["10b_f-04_east"], all_doors["10b_f-05_west"]), + "10b_f-05_east---10b_f-06_west": RoomConnection("10b", all_doors["10b_f-05_east"], all_doors["10b_f-06_west"]), + "10b_f-06_east---10b_f-07_west": RoomConnection("10b", all_doors["10b_f-06_east"], all_doors["10b_f-07_west"]), + "10b_f-07_east---10b_f-08_west": RoomConnection("10b", all_doors["10b_f-07_east"], all_doors["10b_f-08_west"]), + "10b_f-08_east---10b_f-09_west": RoomConnection("10b", all_doors["10b_f-08_east"], all_doors["10b_f-09_west"]), + "10b_f-09_east---10b_g-00_bottom": RoomConnection("10b", all_doors["10b_f-09_east"], all_doors["10b_g-00_bottom"]), + "10b_g-00_top---10b_g-01_bottom": RoomConnection("10b", all_doors["10b_g-00_top"], all_doors["10b_g-01_bottom"]), + "10b_g-01_top---10b_g-03_bottom": RoomConnection("10b", all_doors["10b_g-01_top"], all_doors["10b_g-03_bottom"]), + "10b_g-03_top---10b_g-02_west": RoomConnection("10b", all_doors["10b_g-03_top"], all_doors["10b_g-02_west"]), + "10b_g-02_east---10b_g-04_west": RoomConnection("10b", all_doors["10b_g-02_east"], all_doors["10b_g-04_west"]), + "10b_g-04_east---10b_g-05_west": RoomConnection("10b", all_doors["10b_g-04_east"], all_doors["10b_g-05_west"]), + "10b_g-05_east---10b_g-06_west": RoomConnection("10b", all_doors["10b_g-05_east"], all_doors["10b_g-06_west"]), + "10b_g-06_east---10b_h-00b_west": RoomConnection("10b", all_doors["10b_g-06_east"], all_doors["10b_h-00b_west"]), + "10b_h-00b_east---10b_h-00_west": RoomConnection("10b", all_doors["10b_h-00b_east"], all_doors["10b_h-00_west"]), + "10b_h-00_east---10b_h-01_west": RoomConnection("10b", all_doors["10b_h-00_east"], all_doors["10b_h-01_west"]), + "10b_h-01_east---10b_h-02_west": RoomConnection("10b", all_doors["10b_h-01_east"], all_doors["10b_h-02_west"]), + "10b_h-02_east---10b_h-03_west": RoomConnection("10b", all_doors["10b_h-02_east"], all_doors["10b_h-03_west"]), + "10b_h-03_east---10b_h-03b_west": RoomConnection("10b", all_doors["10b_h-03_east"], all_doors["10b_h-03b_west"]), + "10b_h-03b_east---10b_h-04_top": RoomConnection("10b", all_doors["10b_h-03b_east"], all_doors["10b_h-04_top"]), + "10b_h-04_east---10b_h-04b_west": RoomConnection("10b", all_doors["10b_h-04_east"], all_doors["10b_h-04b_west"]), + "10b_h-04_bottom---10b_h-05_west": RoomConnection("10b", all_doors["10b_h-04_bottom"], all_doors["10b_h-05_west"]), + "10b_h-04b_east---10b_h-05_top": RoomConnection("10b", all_doors["10b_h-04b_east"], all_doors["10b_h-05_top"]), + "10b_h-05_east---10b_h-06_west": RoomConnection("10b", all_doors["10b_h-05_east"], all_doors["10b_h-06_west"]), + "10b_h-06_east---10b_h-06b_bottom": RoomConnection("10b", all_doors["10b_h-06_east"], all_doors["10b_h-06b_bottom"]), + "10b_h-06b_top---10b_h-07_west": RoomConnection("10b", all_doors["10b_h-06b_top"], all_doors["10b_h-07_west"]), + "10b_h-07_east---10b_h-08_west": RoomConnection("10b", all_doors["10b_h-07_east"], all_doors["10b_h-08_west"]), + "10b_h-08_east---10b_h-09_west": RoomConnection("10b", all_doors["10b_h-08_east"], all_doors["10b_h-09_west"]), + "10b_h-09_east---10b_h-10_west": RoomConnection("10b", all_doors["10b_h-09_east"], all_doors["10b_h-10_west"]), + "10b_h-10_east---10b_i-00_west": RoomConnection("10b", all_doors["10b_h-10_east"], all_doors["10b_i-00_west"]), + "10b_i-00_east---10b_i-00b_west": RoomConnection("10b", all_doors["10b_i-00_east"], all_doors["10b_i-00b_west"]), + "10b_i-00b_east---10b_i-01_west": RoomConnection("10b", all_doors["10b_i-00b_east"], all_doors["10b_i-01_west"]), + "10b_i-01_east---10b_i-02_west": RoomConnection("10b", all_doors["10b_i-01_east"], all_doors["10b_i-02_west"]), + "10b_i-02_east---10b_i-03_west": RoomConnection("10b", all_doors["10b_i-02_east"], all_doors["10b_i-03_west"]), + "10b_i-03_east---10b_i-04_west": RoomConnection("10b", all_doors["10b_i-03_east"], all_doors["10b_i-04_west"]), + "10b_i-04_east---10b_i-05_west": RoomConnection("10b", all_doors["10b_i-04_east"], all_doors["10b_i-05_west"]), + "10b_i-05_east---10b_j-00_west": RoomConnection("10b", all_doors["10b_i-05_east"], all_doors["10b_j-00_west"]), + "10b_j-00_east---10b_j-00b_west": RoomConnection("10b", all_doors["10b_j-00_east"], all_doors["10b_j-00b_west"]), + "10b_j-00b_east---10b_j-01_west": RoomConnection("10b", all_doors["10b_j-00b_east"], all_doors["10b_j-01_west"]), + "10b_j-01_east---10b_j-02_west": RoomConnection("10b", all_doors["10b_j-01_east"], all_doors["10b_j-02_west"]), + "10b_j-02_east---10b_j-03_west": RoomConnection("10b", all_doors["10b_j-02_east"], all_doors["10b_j-03_west"]), + "10b_j-03_east---10b_j-04_west": RoomConnection("10b", all_doors["10b_j-03_east"], all_doors["10b_j-04_west"]), + "10b_j-04_east---10b_j-05_west": RoomConnection("10b", all_doors["10b_j-04_east"], all_doors["10b_j-05_west"]), + "10b_j-05_east---10b_j-06_west": RoomConnection("10b", all_doors["10b_j-05_east"], all_doors["10b_j-06_west"]), + "10b_j-06_east---10b_j-07_west": RoomConnection("10b", all_doors["10b_j-06_east"], all_doors["10b_j-07_west"]), + "10b_j-07_east---10b_j-08_west": RoomConnection("10b", all_doors["10b_j-07_east"], all_doors["10b_j-08_west"]), + "10b_j-08_east---10b_j-09_west": RoomConnection("10b", all_doors["10b_j-08_east"], all_doors["10b_j-09_west"]), + "10b_j-09_east---10b_j-10_west": RoomConnection("10b", all_doors["10b_j-09_east"], all_doors["10b_j-10_west"]), + "10b_j-10_east---10b_j-11_west": RoomConnection("10b", all_doors["10b_j-10_east"], all_doors["10b_j-11_west"]), + "10b_j-11_east---10b_j-12_west": RoomConnection("10b", all_doors["10b_j-11_east"], all_doors["10b_j-12_west"]), + "10b_j-12_east---10b_j-13_west": RoomConnection("10b", all_doors["10b_j-12_east"], all_doors["10b_j-13_west"]), + "10b_j-13_east---10b_j-14_west": RoomConnection("10b", all_doors["10b_j-13_east"], all_doors["10b_j-14_west"]), + "10b_j-14_east---10b_j-14b_west": RoomConnection("10b", all_doors["10b_j-14_east"], all_doors["10b_j-14b_west"]), + "10b_j-14b_east---10b_j-15_west": RoomConnection("10b", all_doors["10b_j-14b_east"], all_doors["10b_j-15_west"]), + "10b_j-15_east---10b_j-16_west": RoomConnection("10b", all_doors["10b_j-15_east"], all_doors["10b_j-16_west"]), + "10b_j-16_east---10b_GOAL_main": RoomConnection("10b", all_doors["10b_j-16_east"], all_doors["10b_GOAL_main"]), + "10b_j-16_top---10b_j-17_south": RoomConnection("10b", all_doors["10b_j-16_top"], all_doors["10b_j-17_south"]), + "10b_j-17_west---10b_j-18_west": RoomConnection("10b", all_doors["10b_j-17_west"], all_doors["10b_j-18_west"]), + "10b_j-17_east---10b_j-19_bottom": RoomConnection("10b", all_doors["10b_j-17_east"], all_doors["10b_j-19_bottom"]), + "10b_j-18_east---10b_j-17_north": RoomConnection("10b", all_doors["10b_j-18_east"], all_doors["10b_j-17_north"]), + "10b_j-19_top---10b_GOAL_moon": RoomConnection("10b", all_doors["10b_j-19_top"], all_doors["10b_GOAL_moon"]), + + +} + +all_rooms: dict[str, Room] = { + "0a_-1": Room("0a", "0a_-1", "Prologue - Room -1", [reg for _, reg in all_regions.items() if reg.room_name == "0a_-1"], [door for _, door in all_doors.items() if door.room_name == "0a_-1"]), + "0a_0": Room("0a", "0a_0", "Prologue - Room 0", [reg for _, reg in all_regions.items() if reg.room_name == "0a_0"], [door for _, door in all_doors.items() if door.room_name == "0a_0"], "Start", "0a_0_west"), + "0a_0b": Room("0a", "0a_0b", "Prologue - Room 0b", [reg for _, reg in all_regions.items() if reg.room_name == "0a_0b"], [door for _, door in all_doors.items() if door.room_name == "0a_0b"]), + "0a_1": Room("0a", "0a_1", "Prologue - Room 1", [reg for _, reg in all_regions.items() if reg.room_name == "0a_1"], [door for _, door in all_doors.items() if door.room_name == "0a_1"]), + "0a_2": Room("0a", "0a_2", "Prologue - Room 2", [reg for _, reg in all_regions.items() if reg.room_name == "0a_2"], [door for _, door in all_doors.items() if door.room_name == "0a_2"]), + "0a_3": Room("0a", "0a_3", "Prologue - Room 3", [reg for _, reg in all_regions.items() if reg.room_name == "0a_3"], [door for _, door in all_doors.items() if door.room_name == "0a_3"]), + + "1a_1": Room("1a", "1a_1", "Forsaken City A - Room 1", [reg for _, reg in all_regions.items() if reg.room_name == "1a_1"], [door for _, door in all_doors.items() if door.room_name == "1a_1"], "Start", "1a_1_main"), + "1a_2": Room("1a", "1a_2", "Forsaken City A - Room 2", [reg for _, reg in all_regions.items() if reg.room_name == "1a_2"], [door for _, door in all_doors.items() if door.room_name == "1a_2"]), + "1a_3": Room("1a", "1a_3", "Forsaken City A - Room 3", [reg for _, reg in all_regions.items() if reg.room_name == "1a_3"], [door for _, door in all_doors.items() if door.room_name == "1a_3"]), + "1a_4": Room("1a", "1a_4", "Forsaken City A - Room 4", [reg for _, reg in all_regions.items() if reg.room_name == "1a_4"], [door for _, door in all_doors.items() if door.room_name == "1a_4"]), + "1a_3b": Room("1a", "1a_3b", "Forsaken City A - Room 3b", [reg for _, reg in all_regions.items() if reg.room_name == "1a_3b"], [door for _, door in all_doors.items() if door.room_name == "1a_3b"]), + "1a_5": Room("1a", "1a_5", "Forsaken City A - Room 5", [reg for _, reg in all_regions.items() if reg.room_name == "1a_5"], [door for _, door in all_doors.items() if door.room_name == "1a_5"]), + "1a_5z": Room("1a", "1a_5z", "Forsaken City A - Room 5z", [reg for _, reg in all_regions.items() if reg.room_name == "1a_5z"], [door for _, door in all_doors.items() if door.room_name == "1a_5z"]), + "1a_5a": Room("1a", "1a_5a", "Forsaken City A - Room 5a", [reg for _, reg in all_regions.items() if reg.room_name == "1a_5a"], [door for _, door in all_doors.items() if door.room_name == "1a_5a"]), + "1a_6": Room("1a", "1a_6", "Forsaken City A - Room 6", [reg for _, reg in all_regions.items() if reg.room_name == "1a_6"], [door for _, door in all_doors.items() if door.room_name == "1a_6"], "Crossing", "1a_6_south-west"), + "1a_6z": Room("1a", "1a_6z", "Forsaken City A - Room 6z", [reg for _, reg in all_regions.items() if reg.room_name == "1a_6z"], [door for _, door in all_doors.items() if door.room_name == "1a_6z"]), + "1a_6zb": Room("1a", "1a_6zb", "Forsaken City A - Room 6zb", [reg for _, reg in all_regions.items() if reg.room_name == "1a_6zb"], [door for _, door in all_doors.items() if door.room_name == "1a_6zb"]), + "1a_7zb": Room("1a", "1a_7zb", "Forsaken City A - Room 7zb", [reg for _, reg in all_regions.items() if reg.room_name == "1a_7zb"], [door for _, door in all_doors.items() if door.room_name == "1a_7zb"]), + "1a_6a": Room("1a", "1a_6a", "Forsaken City A - Room 6a", [reg for _, reg in all_regions.items() if reg.room_name == "1a_6a"], [door for _, door in all_doors.items() if door.room_name == "1a_6a"]), + "1a_6b": Room("1a", "1a_6b", "Forsaken City A - Room 6b", [reg for _, reg in all_regions.items() if reg.room_name == "1a_6b"], [door for _, door in all_doors.items() if door.room_name == "1a_6b"]), + "1a_s0": Room("1a", "1a_s0", "Forsaken City A - Room s0", [reg for _, reg in all_regions.items() if reg.room_name == "1a_s0"], [door for _, door in all_doors.items() if door.room_name == "1a_s0"]), + "1a_s1": Room("1a", "1a_s1", "Forsaken City A - Room s1", [reg for _, reg in all_regions.items() if reg.room_name == "1a_s1"], [door for _, door in all_doors.items() if door.room_name == "1a_s1"]), + "1a_6c": Room("1a", "1a_6c", "Forsaken City A - Room 6c", [reg for _, reg in all_regions.items() if reg.room_name == "1a_6c"], [door for _, door in all_doors.items() if door.room_name == "1a_6c"]), + "1a_7": Room("1a", "1a_7", "Forsaken City A - Room 7", [reg for _, reg in all_regions.items() if reg.room_name == "1a_7"], [door for _, door in all_doors.items() if door.room_name == "1a_7"]), + "1a_7z": Room("1a", "1a_7z", "Forsaken City A - Room 7z", [reg for _, reg in all_regions.items() if reg.room_name == "1a_7z"], [door for _, door in all_doors.items() if door.room_name == "1a_7z"]), + "1a_8z": Room("1a", "1a_8z", "Forsaken City A - Room 8z", [reg for _, reg in all_regions.items() if reg.room_name == "1a_8z"], [door for _, door in all_doors.items() if door.room_name == "1a_8z"]), + "1a_8zb": Room("1a", "1a_8zb", "Forsaken City A - Room 8zb", [reg for _, reg in all_regions.items() if reg.room_name == "1a_8zb"], [door for _, door in all_doors.items() if door.room_name == "1a_8zb"]), + "1a_8": Room("1a", "1a_8", "Forsaken City A - Room 8", [reg for _, reg in all_regions.items() if reg.room_name == "1a_8"], [door for _, door in all_doors.items() if door.room_name == "1a_8"]), + "1a_7a": Room("1a", "1a_7a", "Forsaken City A - Room 7a", [reg for _, reg in all_regions.items() if reg.room_name == "1a_7a"], [door for _, door in all_doors.items() if door.room_name == "1a_7a"]), + "1a_9z": Room("1a", "1a_9z", "Forsaken City A - Room 9z", [reg for _, reg in all_regions.items() if reg.room_name == "1a_9z"], [door for _, door in all_doors.items() if door.room_name == "1a_9z"]), + "1a_8b": Room("1a", "1a_8b", "Forsaken City A - Room 8b", [reg for _, reg in all_regions.items() if reg.room_name == "1a_8b"], [door for _, door in all_doors.items() if door.room_name == "1a_8b"]), + "1a_9": Room("1a", "1a_9", "Forsaken City A - Room 9", [reg for _, reg in all_regions.items() if reg.room_name == "1a_9"], [door for _, door in all_doors.items() if door.room_name == "1a_9"]), + "1a_9b": Room("1a", "1a_9b", "Forsaken City A - Room 9b", [reg for _, reg in all_regions.items() if reg.room_name == "1a_9b"], [door for _, door in all_doors.items() if door.room_name == "1a_9b"], "Chasm", "1a_9b_west"), + "1a_9c": Room("1a", "1a_9c", "Forsaken City A - Room 9c", [reg for _, reg in all_regions.items() if reg.room_name == "1a_9c"], [door for _, door in all_doors.items() if door.room_name == "1a_9c"]), + "1a_10": Room("1a", "1a_10", "Forsaken City A - Room 10", [reg for _, reg in all_regions.items() if reg.room_name == "1a_10"], [door for _, door in all_doors.items() if door.room_name == "1a_10"]), + "1a_10z": Room("1a", "1a_10z", "Forsaken City A - Room 10z", [reg for _, reg in all_regions.items() if reg.room_name == "1a_10z"], [door for _, door in all_doors.items() if door.room_name == "1a_10z"]), + "1a_10zb": Room("1a", "1a_10zb", "Forsaken City A - Room 10zb", [reg for _, reg in all_regions.items() if reg.room_name == "1a_10zb"], [door for _, door in all_doors.items() if door.room_name == "1a_10zb"]), + "1a_11": Room("1a", "1a_11", "Forsaken City A - Room 11", [reg for _, reg in all_regions.items() if reg.room_name == "1a_11"], [door for _, door in all_doors.items() if door.room_name == "1a_11"]), + "1a_11z": Room("1a", "1a_11z", "Forsaken City A - Room 11z", [reg for _, reg in all_regions.items() if reg.room_name == "1a_11z"], [door for _, door in all_doors.items() if door.room_name == "1a_11z"]), + "1a_10a": Room("1a", "1a_10a", "Forsaken City A - Room 10a", [reg for _, reg in all_regions.items() if reg.room_name == "1a_10a"], [door for _, door in all_doors.items() if door.room_name == "1a_10a"]), + "1a_12": Room("1a", "1a_12", "Forsaken City A - Room 12", [reg for _, reg in all_regions.items() if reg.room_name == "1a_12"], [door for _, door in all_doors.items() if door.room_name == "1a_12"]), + "1a_12z": Room("1a", "1a_12z", "Forsaken City A - Room 12z", [reg for _, reg in all_regions.items() if reg.room_name == "1a_12z"], [door for _, door in all_doors.items() if door.room_name == "1a_12z"]), + "1a_12a": Room("1a", "1a_12a", "Forsaken City A - Room 12a", [reg for _, reg in all_regions.items() if reg.room_name == "1a_12a"], [door for _, door in all_doors.items() if door.room_name == "1a_12a"]), + "1a_end": Room("1a", "1a_end", "Forsaken City A - Room end", [reg for _, reg in all_regions.items() if reg.room_name == "1a_end"], [door for _, door in all_doors.items() if door.room_name == "1a_end"]), + + "1b_00": Room("1b", "1b_00", "Forsaken City B - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "1b_00"], [door for _, door in all_doors.items() if door.room_name == "1b_00"], "Start", "1b_00_west"), + "1b_01": Room("1b", "1b_01", "Forsaken City B - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "1b_01"], [door for _, door in all_doors.items() if door.room_name == "1b_01"]), + "1b_02": Room("1b", "1b_02", "Forsaken City B - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "1b_02"], [door for _, door in all_doors.items() if door.room_name == "1b_02"]), + "1b_02b": Room("1b", "1b_02b", "Forsaken City B - Room 02b", [reg for _, reg in all_regions.items() if reg.room_name == "1b_02b"], [door for _, door in all_doors.items() if door.room_name == "1b_02b"]), + "1b_03": Room("1b", "1b_03", "Forsaken City B - Room 03", [reg for _, reg in all_regions.items() if reg.room_name == "1b_03"], [door for _, door in all_doors.items() if door.room_name == "1b_03"]), + "1b_04": Room("1b", "1b_04", "Forsaken City B - Room 04", [reg for _, reg in all_regions.items() if reg.room_name == "1b_04"], [door for _, door in all_doors.items() if door.room_name == "1b_04"], "Contraption", "1b_04_west"), + "1b_05": Room("1b", "1b_05", "Forsaken City B - Room 05", [reg for _, reg in all_regions.items() if reg.room_name == "1b_05"], [door for _, door in all_doors.items() if door.room_name == "1b_05"]), + "1b_05b": Room("1b", "1b_05b", "Forsaken City B - Room 05b", [reg for _, reg in all_regions.items() if reg.room_name == "1b_05b"], [door for _, door in all_doors.items() if door.room_name == "1b_05b"]), + "1b_06": Room("1b", "1b_06", "Forsaken City B - Room 06", [reg for _, reg in all_regions.items() if reg.room_name == "1b_06"], [door for _, door in all_doors.items() if door.room_name == "1b_06"]), + "1b_07": Room("1b", "1b_07", "Forsaken City B - Room 07", [reg for _, reg in all_regions.items() if reg.room_name == "1b_07"], [door for _, door in all_doors.items() if door.room_name == "1b_07"]), + "1b_08": Room("1b", "1b_08", "Forsaken City B - Room 08", [reg for _, reg in all_regions.items() if reg.room_name == "1b_08"], [door for _, door in all_doors.items() if door.room_name == "1b_08"], "Scrap Pit", "1b_08_west"), + "1b_08b": Room("1b", "1b_08b", "Forsaken City B - Room 08b", [reg for _, reg in all_regions.items() if reg.room_name == "1b_08b"], [door for _, door in all_doors.items() if door.room_name == "1b_08b"]), + "1b_09": Room("1b", "1b_09", "Forsaken City B - Room 09", [reg for _, reg in all_regions.items() if reg.room_name == "1b_09"], [door for _, door in all_doors.items() if door.room_name == "1b_09"]), + "1b_10": Room("1b", "1b_10", "Forsaken City B - Room 10", [reg for _, reg in all_regions.items() if reg.room_name == "1b_10"], [door for _, door in all_doors.items() if door.room_name == "1b_10"]), + "1b_11": Room("1b", "1b_11", "Forsaken City B - Room 11", [reg for _, reg in all_regions.items() if reg.room_name == "1b_11"], [door for _, door in all_doors.items() if door.room_name == "1b_11"]), + "1b_end": Room("1b", "1b_end", "Forsaken City B - Room end", [reg for _, reg in all_regions.items() if reg.room_name == "1b_end"], [door for _, door in all_doors.items() if door.room_name == "1b_end"]), + + "1c_00": Room("1c", "1c_00", "Forsaken City C - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "1c_00"], [door for _, door in all_doors.items() if door.room_name == "1c_00"], "Start", "1c_00_west"), + "1c_01": Room("1c", "1c_01", "Forsaken City C - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "1c_01"], [door for _, door in all_doors.items() if door.room_name == "1c_01"]), + "1c_02": Room("1c", "1c_02", "Forsaken City C - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "1c_02"], [door for _, door in all_doors.items() if door.room_name == "1c_02"]), + + "2a_start": Room("2a", "2a_start", "Old Site A - Room start", [reg for _, reg in all_regions.items() if reg.room_name == "2a_start"], [door for _, door in all_doors.items() if door.room_name == "2a_start"], "Start", "2a_start_main"), + "2a_s0": Room("2a", "2a_s0", "Old Site A - Room s0", [reg for _, reg in all_regions.items() if reg.room_name == "2a_s0"], [door for _, door in all_doors.items() if door.room_name == "2a_s0"]), + "2a_s1": Room("2a", "2a_s1", "Old Site A - Room s1", [reg for _, reg in all_regions.items() if reg.room_name == "2a_s1"], [door for _, door in all_doors.items() if door.room_name == "2a_s1"]), + "2a_s2": Room("2a", "2a_s2", "Old Site A - Room s2", [reg for _, reg in all_regions.items() if reg.room_name == "2a_s2"], [door for _, door in all_doors.items() if door.room_name == "2a_s2"]), + "2a_0": Room("2a", "2a_0", "Old Site A - Room 0", [reg for _, reg in all_regions.items() if reg.room_name == "2a_0"], [door for _, door in all_doors.items() if door.room_name == "2a_0"]), + "2a_1": Room("2a", "2a_1", "Old Site A - Room 1", [reg for _, reg in all_regions.items() if reg.room_name == "2a_1"], [door for _, door in all_doors.items() if door.room_name == "2a_1"]), + "2a_d0": Room("2a", "2a_d0", "Old Site A - Room d0", [reg for _, reg in all_regions.items() if reg.room_name == "2a_d0"], [door for _, door in all_doors.items() if door.room_name == "2a_d0"]), + "2a_d7": Room("2a", "2a_d7", "Old Site A - Room d7", [reg for _, reg in all_regions.items() if reg.room_name == "2a_d7"], [door for _, door in all_doors.items() if door.room_name == "2a_d7"]), + "2a_d8": Room("2a", "2a_d8", "Old Site A - Room d8", [reg for _, reg in all_regions.items() if reg.room_name == "2a_d8"], [door for _, door in all_doors.items() if door.room_name == "2a_d8"]), + "2a_d3": Room("2a", "2a_d3", "Old Site A - Room d3", [reg for _, reg in all_regions.items() if reg.room_name == "2a_d3"], [door for _, door in all_doors.items() if door.room_name == "2a_d3"]), + "2a_d2": Room("2a", "2a_d2", "Old Site A - Room d2", [reg for _, reg in all_regions.items() if reg.room_name == "2a_d2"], [door for _, door in all_doors.items() if door.room_name == "2a_d2"]), + "2a_d9": Room("2a", "2a_d9", "Old Site A - Room d9", [reg for _, reg in all_regions.items() if reg.room_name == "2a_d9"], [door for _, door in all_doors.items() if door.room_name == "2a_d9"]), + "2a_d1": Room("2a", "2a_d1", "Old Site A - Room d1", [reg for _, reg in all_regions.items() if reg.room_name == "2a_d1"], [door for _, door in all_doors.items() if door.room_name == "2a_d1"]), + "2a_d6": Room("2a", "2a_d6", "Old Site A - Room d6", [reg for _, reg in all_regions.items() if reg.room_name == "2a_d6"], [door for _, door in all_doors.items() if door.room_name == "2a_d6"]), + "2a_d4": Room("2a", "2a_d4", "Old Site A - Room d4", [reg for _, reg in all_regions.items() if reg.room_name == "2a_d4"], [door for _, door in all_doors.items() if door.room_name == "2a_d4"]), + "2a_d5": Room("2a", "2a_d5", "Old Site A - Room d5", [reg for _, reg in all_regions.items() if reg.room_name == "2a_d5"], [door for _, door in all_doors.items() if door.room_name == "2a_d5"]), + "2a_3x": Room("2a", "2a_3x", "Old Site A - Room 3x", [reg for _, reg in all_regions.items() if reg.room_name == "2a_3x"], [door for _, door in all_doors.items() if door.room_name == "2a_3x"]), + "2a_3": Room("2a", "2a_3", "Old Site A - Room 3", [reg for _, reg in all_regions.items() if reg.room_name == "2a_3"], [door for _, door in all_doors.items() if door.room_name == "2a_3"], "Intervention", "2a_3_bottom"), + "2a_4": Room("2a", "2a_4", "Old Site A - Room 4", [reg for _, reg in all_regions.items() if reg.room_name == "2a_4"], [door for _, door in all_doors.items() if door.room_name == "2a_4"]), + "2a_5": Room("2a", "2a_5", "Old Site A - Room 5", [reg for _, reg in all_regions.items() if reg.room_name == "2a_5"], [door for _, door in all_doors.items() if door.room_name == "2a_5"]), + "2a_6": Room("2a", "2a_6", "Old Site A - Room 6", [reg for _, reg in all_regions.items() if reg.room_name == "2a_6"], [door for _, door in all_doors.items() if door.room_name == "2a_6"]), + "2a_7": Room("2a", "2a_7", "Old Site A - Room 7", [reg for _, reg in all_regions.items() if reg.room_name == "2a_7"], [door for _, door in all_doors.items() if door.room_name == "2a_7"]), + "2a_8": Room("2a", "2a_8", "Old Site A - Room 8", [reg for _, reg in all_regions.items() if reg.room_name == "2a_8"], [door for _, door in all_doors.items() if door.room_name == "2a_8"]), + "2a_9": Room("2a", "2a_9", "Old Site A - Room 9", [reg for _, reg in all_regions.items() if reg.room_name == "2a_9"], [door for _, door in all_doors.items() if door.room_name == "2a_9"]), + "2a_9b": Room("2a", "2a_9b", "Old Site A - Room 9b", [reg for _, reg in all_regions.items() if reg.room_name == "2a_9b"], [door for _, door in all_doors.items() if door.room_name == "2a_9b"]), + "2a_10": Room("2a", "2a_10", "Old Site A - Room 10", [reg for _, reg in all_regions.items() if reg.room_name == "2a_10"], [door for _, door in all_doors.items() if door.room_name == "2a_10"]), + "2a_2": Room("2a", "2a_2", "Old Site A - Room 2", [reg for _, reg in all_regions.items() if reg.room_name == "2a_2"], [door for _, door in all_doors.items() if door.room_name == "2a_2"]), + "2a_11": Room("2a", "2a_11", "Old Site A - Room 11", [reg for _, reg in all_regions.items() if reg.room_name == "2a_11"], [door for _, door in all_doors.items() if door.room_name == "2a_11"]), + "2a_12b": Room("2a", "2a_12b", "Old Site A - Room 12b", [reg for _, reg in all_regions.items() if reg.room_name == "2a_12b"], [door for _, door in all_doors.items() if door.room_name == "2a_12b"]), + "2a_12c": Room("2a", "2a_12c", "Old Site A - Room 12c", [reg for _, reg in all_regions.items() if reg.room_name == "2a_12c"], [door for _, door in all_doors.items() if door.room_name == "2a_12c"]), + "2a_12d": Room("2a", "2a_12d", "Old Site A - Room 12d", [reg for _, reg in all_regions.items() if reg.room_name == "2a_12d"], [door for _, door in all_doors.items() if door.room_name == "2a_12d"]), + "2a_12": Room("2a", "2a_12", "Old Site A - Room 12", [reg for _, reg in all_regions.items() if reg.room_name == "2a_12"], [door for _, door in all_doors.items() if door.room_name == "2a_12"]), + "2a_13": Room("2a", "2a_13", "Old Site A - Room 13", [reg for _, reg in all_regions.items() if reg.room_name == "2a_13"], [door for _, door in all_doors.items() if door.room_name == "2a_13"]), + "2a_end_0": Room("2a", "2a_end_0", "Old Site A - Room end_0", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_0"], [door for _, door in all_doors.items() if door.room_name == "2a_end_0"]), + "2a_end_s0": Room("2a", "2a_end_s0", "Old Site A - Room end_s0", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_s0"], [door for _, door in all_doors.items() if door.room_name == "2a_end_s0"]), + "2a_end_s1": Room("2a", "2a_end_s1", "Old Site A - Room end_s1", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_s1"], [door for _, door in all_doors.items() if door.room_name == "2a_end_s1"]), + "2a_end_1": Room("2a", "2a_end_1", "Old Site A - Room end_1", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_1"], [door for _, door in all_doors.items() if door.room_name == "2a_end_1"]), + "2a_end_2": Room("2a", "2a_end_2", "Old Site A - Room end_2", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_2"], [door for _, door in all_doors.items() if door.room_name == "2a_end_2"]), + "2a_end_3": Room("2a", "2a_end_3", "Old Site A - Room end_3", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_3"], [door for _, door in all_doors.items() if door.room_name == "2a_end_3"], "Awake", "2a_end_3_west"), + "2a_end_4": Room("2a", "2a_end_4", "Old Site A - Room end_4", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_4"], [door for _, door in all_doors.items() if door.room_name == "2a_end_4"]), + "2a_end_3b": Room("2a", "2a_end_3b", "Old Site A - Room end_3b", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_3b"], [door for _, door in all_doors.items() if door.room_name == "2a_end_3b"]), + "2a_end_3cb": Room("2a", "2a_end_3cb", "Old Site A - Room end_3cb", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_3cb"], [door for _, door in all_doors.items() if door.room_name == "2a_end_3cb"]), + "2a_end_3c": Room("2a", "2a_end_3c", "Old Site A - Room end_3c", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_3c"], [door for _, door in all_doors.items() if door.room_name == "2a_end_3c"]), + "2a_end_5": Room("2a", "2a_end_5", "Old Site A - Room end_5", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_5"], [door for _, door in all_doors.items() if door.room_name == "2a_end_5"]), + "2a_end_6": Room("2a", "2a_end_6", "Old Site A - Room end_6", [reg for _, reg in all_regions.items() if reg.room_name == "2a_end_6"], [door for _, door in all_doors.items() if door.room_name == "2a_end_6"]), + + "2b_start": Room("2b", "2b_start", "Old Site B - Room start", [reg for _, reg in all_regions.items() if reg.room_name == "2b_start"], [door for _, door in all_doors.items() if door.room_name == "2b_start"], "Start", "2b_start_west"), + "2b_00": Room("2b", "2b_00", "Old Site B - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "2b_00"], [door for _, door in all_doors.items() if door.room_name == "2b_00"]), + "2b_01": Room("2b", "2b_01", "Old Site B - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "2b_01"], [door for _, door in all_doors.items() if door.room_name == "2b_01"]), + "2b_01b": Room("2b", "2b_01b", "Old Site B - Room 01b", [reg for _, reg in all_regions.items() if reg.room_name == "2b_01b"], [door for _, door in all_doors.items() if door.room_name == "2b_01b"]), + "2b_02b": Room("2b", "2b_02b", "Old Site B - Room 02b", [reg for _, reg in all_regions.items() if reg.room_name == "2b_02b"], [door for _, door in all_doors.items() if door.room_name == "2b_02b"]), + "2b_02": Room("2b", "2b_02", "Old Site B - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "2b_02"], [door for _, door in all_doors.items() if door.room_name == "2b_02"]), + "2b_03": Room("2b", "2b_03", "Old Site B - Room 03", [reg for _, reg in all_regions.items() if reg.room_name == "2b_03"], [door for _, door in all_doors.items() if door.room_name == "2b_03"], "Combination Lock", "2b_03_west"), + "2b_04": Room("2b", "2b_04", "Old Site B - Room 04", [reg for _, reg in all_regions.items() if reg.room_name == "2b_04"], [door for _, door in all_doors.items() if door.room_name == "2b_04"]), + "2b_05": Room("2b", "2b_05", "Old Site B - Room 05", [reg for _, reg in all_regions.items() if reg.room_name == "2b_05"], [door for _, door in all_doors.items() if door.room_name == "2b_05"]), + "2b_06": Room("2b", "2b_06", "Old Site B - Room 06", [reg for _, reg in all_regions.items() if reg.room_name == "2b_06"], [door for _, door in all_doors.items() if door.room_name == "2b_06"]), + "2b_07": Room("2b", "2b_07", "Old Site B - Room 07", [reg for _, reg in all_regions.items() if reg.room_name == "2b_07"], [door for _, door in all_doors.items() if door.room_name == "2b_07"]), + "2b_08b": Room("2b", "2b_08b", "Old Site B - Room 08b", [reg for _, reg in all_regions.items() if reg.room_name == "2b_08b"], [door for _, door in all_doors.items() if door.room_name == "2b_08b"], "Dream Altar", "2b_08b_west"), + "2b_08": Room("2b", "2b_08", "Old Site B - Room 08", [reg for _, reg in all_regions.items() if reg.room_name == "2b_08"], [door for _, door in all_doors.items() if door.room_name == "2b_08"]), + "2b_09": Room("2b", "2b_09", "Old Site B - Room 09", [reg for _, reg in all_regions.items() if reg.room_name == "2b_09"], [door for _, door in all_doors.items() if door.room_name == "2b_09"]), + "2b_10": Room("2b", "2b_10", "Old Site B - Room 10", [reg for _, reg in all_regions.items() if reg.room_name == "2b_10"], [door for _, door in all_doors.items() if door.room_name == "2b_10"]), + "2b_11": Room("2b", "2b_11", "Old Site B - Room 11", [reg for _, reg in all_regions.items() if reg.room_name == "2b_11"], [door for _, door in all_doors.items() if door.room_name == "2b_11"]), + "2b_end": Room("2b", "2b_end", "Old Site B - Room end", [reg for _, reg in all_regions.items() if reg.room_name == "2b_end"], [door for _, door in all_doors.items() if door.room_name == "2b_end"]), + + "2c_00": Room("2c", "2c_00", "Old Site C - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "2c_00"], [door for _, door in all_doors.items() if door.room_name == "2c_00"], "Start", "2c_00_west"), + "2c_01": Room("2c", "2c_01", "Old Site C - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "2c_01"], [door for _, door in all_doors.items() if door.room_name == "2c_01"]), + "2c_02": Room("2c", "2c_02", "Old Site C - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "2c_02"], [door for _, door in all_doors.items() if door.room_name == "2c_02"]), + + "3a_s0": Room("3a", "3a_s0", "Celestial Resort A - Room s0", [reg for _, reg in all_regions.items() if reg.room_name == "3a_s0"], [door for _, door in all_doors.items() if door.room_name == "3a_s0"], "Start", "3a_s0_main"), + "3a_s1": Room("3a", "3a_s1", "Celestial Resort A - Room s1", [reg for _, reg in all_regions.items() if reg.room_name == "3a_s1"], [door for _, door in all_doors.items() if door.room_name == "3a_s1"]), + "3a_s2": Room("3a", "3a_s2", "Celestial Resort A - Room s2", [reg for _, reg in all_regions.items() if reg.room_name == "3a_s2"], [door for _, door in all_doors.items() if door.room_name == "3a_s2"]), + "3a_s3": Room("3a", "3a_s3", "Celestial Resort A - Room s3", [reg for _, reg in all_regions.items() if reg.room_name == "3a_s3"], [door for _, door in all_doors.items() if door.room_name == "3a_s3"]), + "3a_0x-a": Room("3a", "3a_0x-a", "Celestial Resort A - Room 0x-a", [reg for _, reg in all_regions.items() if reg.room_name == "3a_0x-a"], [door for _, door in all_doors.items() if door.room_name == "3a_0x-a"]), + "3a_00-a": Room("3a", "3a_00-a", "Celestial Resort A - Room 00-a", [reg for _, reg in all_regions.items() if reg.room_name == "3a_00-a"], [door for _, door in all_doors.items() if door.room_name == "3a_00-a"]), + "3a_02-a": Room("3a", "3a_02-a", "Celestial Resort A - Room 02-a", [reg for _, reg in all_regions.items() if reg.room_name == "3a_02-a"], [door for _, door in all_doors.items() if door.room_name == "3a_02-a"]), + "3a_02-b": Room("3a", "3a_02-b", "Celestial Resort A - Room 02-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_02-b"], [door for _, door in all_doors.items() if door.room_name == "3a_02-b"]), + "3a_01-b": Room("3a", "3a_01-b", "Celestial Resort A - Room 01-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_01-b"], [door for _, door in all_doors.items() if door.room_name == "3a_01-b"]), + "3a_00-b": Room("3a", "3a_00-b", "Celestial Resort A - Room 00-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_00-b"], [door for _, door in all_doors.items() if door.room_name == "3a_00-b"]), + "3a_00-c": Room("3a", "3a_00-c", "Celestial Resort A - Room 00-c", [reg for _, reg in all_regions.items() if reg.room_name == "3a_00-c"], [door for _, door in all_doors.items() if door.room_name == "3a_00-c"]), + "3a_0x-b": Room("3a", "3a_0x-b", "Celestial Resort A - Room 0x-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_0x-b"], [door for _, door in all_doors.items() if door.room_name == "3a_0x-b"]), + "3a_03-a": Room("3a", "3a_03-a", "Celestial Resort A - Room 03-a", [reg for _, reg in all_regions.items() if reg.room_name == "3a_03-a"], [door for _, door in all_doors.items() if door.room_name == "3a_03-a"]), + "3a_04-b": Room("3a", "3a_04-b", "Celestial Resort A - Room 04-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_04-b"], [door for _, door in all_doors.items() if door.room_name == "3a_04-b"]), + "3a_05-a": Room("3a", "3a_05-a", "Celestial Resort A - Room 05-a", [reg for _, reg in all_regions.items() if reg.room_name == "3a_05-a"], [door for _, door in all_doors.items() if door.room_name == "3a_05-a"]), + "3a_06-a": Room("3a", "3a_06-a", "Celestial Resort A - Room 06-a", [reg for _, reg in all_regions.items() if reg.room_name == "3a_06-a"], [door for _, door in all_doors.items() if door.room_name == "3a_06-a"]), + "3a_07-a": Room("3a", "3a_07-a", "Celestial Resort A - Room 07-a", [reg for _, reg in all_regions.items() if reg.room_name == "3a_07-a"], [door for _, door in all_doors.items() if door.room_name == "3a_07-a"]), + "3a_07-b": Room("3a", "3a_07-b", "Celestial Resort A - Room 07-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_07-b"], [door for _, door in all_doors.items() if door.room_name == "3a_07-b"]), + "3a_06-b": Room("3a", "3a_06-b", "Celestial Resort A - Room 06-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_06-b"], [door for _, door in all_doors.items() if door.room_name == "3a_06-b"]), + "3a_06-c": Room("3a", "3a_06-c", "Celestial Resort A - Room 06-c", [reg for _, reg in all_regions.items() if reg.room_name == "3a_06-c"], [door for _, door in all_doors.items() if door.room_name == "3a_06-c"]), + "3a_05-c": Room("3a", "3a_05-c", "Celestial Resort A - Room 05-c", [reg for _, reg in all_regions.items() if reg.room_name == "3a_05-c"], [door for _, door in all_doors.items() if door.room_name == "3a_05-c"]), + "3a_08-c": Room("3a", "3a_08-c", "Celestial Resort A - Room 08-c", [reg for _, reg in all_regions.items() if reg.room_name == "3a_08-c"], [door for _, door in all_doors.items() if door.room_name == "3a_08-c"]), + "3a_08-b": Room("3a", "3a_08-b", "Celestial Resort A - Room 08-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_08-b"], [door for _, door in all_doors.items() if door.room_name == "3a_08-b"]), + "3a_08-a": Room("3a", "3a_08-a", "Celestial Resort A - Room 08-a", [reg for _, reg in all_regions.items() if reg.room_name == "3a_08-a"], [door for _, door in all_doors.items() if door.room_name == "3a_08-a"], "Huge Mess", "3a_08-a_west"), + "3a_09-b": Room("3a", "3a_09-b", "Celestial Resort A - Room 09-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_09-b"], [door for _, door in all_doors.items() if door.room_name == "3a_09-b"]), + "3a_10-x": Room("3a", "3a_10-x", "Celestial Resort A - Room 10-x", [reg for _, reg in all_regions.items() if reg.room_name == "3a_10-x"], [door for _, door in all_doors.items() if door.room_name == "3a_10-x"]), + "3a_11-x": Room("3a", "3a_11-x", "Celestial Resort A - Room 11-x", [reg for _, reg in all_regions.items() if reg.room_name == "3a_11-x"], [door for _, door in all_doors.items() if door.room_name == "3a_11-x"]), + "3a_11-y": Room("3a", "3a_11-y", "Celestial Resort A - Room 11-y", [reg for _, reg in all_regions.items() if reg.room_name == "3a_11-y"], [door for _, door in all_doors.items() if door.room_name == "3a_11-y"]), + "3a_12-y": Room("3a", "3a_12-y", "Celestial Resort A - Room 12-y", [reg for _, reg in all_regions.items() if reg.room_name == "3a_12-y"], [door for _, door in all_doors.items() if door.room_name == "3a_12-y"]), + "3a_11-z": Room("3a", "3a_11-z", "Celestial Resort A - Room 11-z", [reg for _, reg in all_regions.items() if reg.room_name == "3a_11-z"], [door for _, door in all_doors.items() if door.room_name == "3a_11-z"]), + "3a_10-z": Room("3a", "3a_10-z", "Celestial Resort A - Room 10-z", [reg for _, reg in all_regions.items() if reg.room_name == "3a_10-z"], [door for _, door in all_doors.items() if door.room_name == "3a_10-z"]), + "3a_10-y": Room("3a", "3a_10-y", "Celestial Resort A - Room 10-y", [reg for _, reg in all_regions.items() if reg.room_name == "3a_10-y"], [door for _, door in all_doors.items() if door.room_name == "3a_10-y"]), + "3a_10-c": Room("3a", "3a_10-c", "Celestial Resort A - Room 10-c", [reg for _, reg in all_regions.items() if reg.room_name == "3a_10-c"], [door for _, door in all_doors.items() if door.room_name == "3a_10-c"]), + "3a_11-c": Room("3a", "3a_11-c", "Celestial Resort A - Room 11-c", [reg for _, reg in all_regions.items() if reg.room_name == "3a_11-c"], [door for _, door in all_doors.items() if door.room_name == "3a_11-c"]), + "3a_12-c": Room("3a", "3a_12-c", "Celestial Resort A - Room 12-c", [reg for _, reg in all_regions.items() if reg.room_name == "3a_12-c"], [door for _, door in all_doors.items() if door.room_name == "3a_12-c"]), + "3a_12-d": Room("3a", "3a_12-d", "Celestial Resort A - Room 12-d", [reg for _, reg in all_regions.items() if reg.room_name == "3a_12-d"], [door for _, door in all_doors.items() if door.room_name == "3a_12-d"]), + "3a_11-d": Room("3a", "3a_11-d", "Celestial Resort A - Room 11-d", [reg for _, reg in all_regions.items() if reg.room_name == "3a_11-d"], [door for _, door in all_doors.items() if door.room_name == "3a_11-d"]), + "3a_10-d": Room("3a", "3a_10-d", "Celestial Resort A - Room 10-d", [reg for _, reg in all_regions.items() if reg.room_name == "3a_10-d"], [door for _, door in all_doors.items() if door.room_name == "3a_10-d"]), + "3a_11-b": Room("3a", "3a_11-b", "Celestial Resort A - Room 11-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_11-b"], [door for _, door in all_doors.items() if door.room_name == "3a_11-b"]), + "3a_12-b": Room("3a", "3a_12-b", "Celestial Resort A - Room 12-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_12-b"], [door for _, door in all_doors.items() if door.room_name == "3a_12-b"]), + "3a_13-b": Room("3a", "3a_13-b", "Celestial Resort A - Room 13-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_13-b"], [door for _, door in all_doors.items() if door.room_name == "3a_13-b"]), + "3a_13-a": Room("3a", "3a_13-a", "Celestial Resort A - Room 13-a", [reg for _, reg in all_regions.items() if reg.room_name == "3a_13-a"], [door for _, door in all_doors.items() if door.room_name == "3a_13-a"]), + "3a_13-x": Room("3a", "3a_13-x", "Celestial Resort A - Room 13-x", [reg for _, reg in all_regions.items() if reg.room_name == "3a_13-x"], [door for _, door in all_doors.items() if door.room_name == "3a_13-x"]), + "3a_12-x": Room("3a", "3a_12-x", "Celestial Resort A - Room 12-x", [reg for _, reg in all_regions.items() if reg.room_name == "3a_12-x"], [door for _, door in all_doors.items() if door.room_name == "3a_12-x"]), + "3a_11-a": Room("3a", "3a_11-a", "Celestial Resort A - Room 11-a", [reg for _, reg in all_regions.items() if reg.room_name == "3a_11-a"], [door for _, door in all_doors.items() if door.room_name == "3a_11-a"]), + "3a_08-x": Room("3a", "3a_08-x", "Celestial Resort A - Room 08-x", [reg for _, reg in all_regions.items() if reg.room_name == "3a_08-x"], [door for _, door in all_doors.items() if door.room_name == "3a_08-x"]), + "3a_09-d": Room("3a", "3a_09-d", "Celestial Resort A - Room 09-d", [reg for _, reg in all_regions.items() if reg.room_name == "3a_09-d"], [door for _, door in all_doors.items() if door.room_name == "3a_09-d"], "Elevator Shaft", "3a_09-d_bottom"), + "3a_08-d": Room("3a", "3a_08-d", "Celestial Resort A - Room 08-d", [reg for _, reg in all_regions.items() if reg.room_name == "3a_08-d"], [door for _, door in all_doors.items() if door.room_name == "3a_08-d"]), + "3a_06-d": Room("3a", "3a_06-d", "Celestial Resort A - Room 06-d", [reg for _, reg in all_regions.items() if reg.room_name == "3a_06-d"], [door for _, door in all_doors.items() if door.room_name == "3a_06-d"]), + "3a_04-d": Room("3a", "3a_04-d", "Celestial Resort A - Room 04-d", [reg for _, reg in all_regions.items() if reg.room_name == "3a_04-d"], [door for _, door in all_doors.items() if door.room_name == "3a_04-d"]), + "3a_04-c": Room("3a", "3a_04-c", "Celestial Resort A - Room 04-c", [reg for _, reg in all_regions.items() if reg.room_name == "3a_04-c"], [door for _, door in all_doors.items() if door.room_name == "3a_04-c"]), + "3a_02-c": Room("3a", "3a_02-c", "Celestial Resort A - Room 02-c", [reg for _, reg in all_regions.items() if reg.room_name == "3a_02-c"], [door for _, door in all_doors.items() if door.room_name == "3a_02-c"]), + "3a_03-b": Room("3a", "3a_03-b", "Celestial Resort A - Room 03-b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_03-b"], [door for _, door in all_doors.items() if door.room_name == "3a_03-b"]), + "3a_01-c": Room("3a", "3a_01-c", "Celestial Resort A - Room 01-c", [reg for _, reg in all_regions.items() if reg.room_name == "3a_01-c"], [door for _, door in all_doors.items() if door.room_name == "3a_01-c"]), + "3a_02-d": Room("3a", "3a_02-d", "Celestial Resort A - Room 02-d", [reg for _, reg in all_regions.items() if reg.room_name == "3a_02-d"], [door for _, door in all_doors.items() if door.room_name == "3a_02-d"]), + "3a_00-d": Room("3a", "3a_00-d", "Celestial Resort A - Room 00-d", [reg for _, reg in all_regions.items() if reg.room_name == "3a_00-d"], [door for _, door in all_doors.items() if door.room_name == "3a_00-d"], "Presidential Suite", "3a_00-d_east"), + "3a_roof00": Room("3a", "3a_roof00", "Celestial Resort A - Room roof00", [reg for _, reg in all_regions.items() if reg.room_name == "3a_roof00"], [door for _, door in all_doors.items() if door.room_name == "3a_roof00"]), + "3a_roof01": Room("3a", "3a_roof01", "Celestial Resort A - Room roof01", [reg for _, reg in all_regions.items() if reg.room_name == "3a_roof01"], [door for _, door in all_doors.items() if door.room_name == "3a_roof01"]), + "3a_roof02": Room("3a", "3a_roof02", "Celestial Resort A - Room roof02", [reg for _, reg in all_regions.items() if reg.room_name == "3a_roof02"], [door for _, door in all_doors.items() if door.room_name == "3a_roof02"]), + "3a_roof03": Room("3a", "3a_roof03", "Celestial Resort A - Room roof03", [reg for _, reg in all_regions.items() if reg.room_name == "3a_roof03"], [door for _, door in all_doors.items() if door.room_name == "3a_roof03"]), + "3a_roof04": Room("3a", "3a_roof04", "Celestial Resort A - Room roof04", [reg for _, reg in all_regions.items() if reg.room_name == "3a_roof04"], [door for _, door in all_doors.items() if door.room_name == "3a_roof04"]), + "3a_roof05": Room("3a", "3a_roof05", "Celestial Resort A - Room roof05", [reg for _, reg in all_regions.items() if reg.room_name == "3a_roof05"], [door for _, door in all_doors.items() if door.room_name == "3a_roof05"]), + "3a_roof06b": Room("3a", "3a_roof06b", "Celestial Resort A - Room roof06b", [reg for _, reg in all_regions.items() if reg.room_name == "3a_roof06b"], [door for _, door in all_doors.items() if door.room_name == "3a_roof06b"]), + "3a_roof06": Room("3a", "3a_roof06", "Celestial Resort A - Room roof06", [reg for _, reg in all_regions.items() if reg.room_name == "3a_roof06"], [door for _, door in all_doors.items() if door.room_name == "3a_roof06"]), + "3a_roof07": Room("3a", "3a_roof07", "Celestial Resort A - Room roof07", [reg for _, reg in all_regions.items() if reg.room_name == "3a_roof07"], [door for _, door in all_doors.items() if door.room_name == "3a_roof07"]), + + "3b_00": Room("3b", "3b_00", "Celestial Resort B - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "3b_00"], [door for _, door in all_doors.items() if door.room_name == "3b_00"], "Start", "3b_00_west"), + "3b_back": Room("3b", "3b_back", "Celestial Resort B - Room back", [reg for _, reg in all_regions.items() if reg.room_name == "3b_back"], [door for _, door in all_doors.items() if door.room_name == "3b_back"]), + "3b_01": Room("3b", "3b_01", "Celestial Resort B - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "3b_01"], [door for _, door in all_doors.items() if door.room_name == "3b_01"]), + "3b_02": Room("3b", "3b_02", "Celestial Resort B - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "3b_02"], [door for _, door in all_doors.items() if door.room_name == "3b_02"]), + "3b_03": Room("3b", "3b_03", "Celestial Resort B - Room 03", [reg for _, reg in all_regions.items() if reg.room_name == "3b_03"], [door for _, door in all_doors.items() if door.room_name == "3b_03"]), + "3b_04": Room("3b", "3b_04", "Celestial Resort B - Room 04", [reg for _, reg in all_regions.items() if reg.room_name == "3b_04"], [door for _, door in all_doors.items() if door.room_name == "3b_04"]), + "3b_05": Room("3b", "3b_05", "Celestial Resort B - Room 05", [reg for _, reg in all_regions.items() if reg.room_name == "3b_05"], [door for _, door in all_doors.items() if door.room_name == "3b_05"]), + "3b_06": Room("3b", "3b_06", "Celestial Resort B - Room 06", [reg for _, reg in all_regions.items() if reg.room_name == "3b_06"], [door for _, door in all_doors.items() if door.room_name == "3b_06"], "Staff Quarters", "3b_06_west"), + "3b_07": Room("3b", "3b_07", "Celestial Resort B - Room 07", [reg for _, reg in all_regions.items() if reg.room_name == "3b_07"], [door for _, door in all_doors.items() if door.room_name == "3b_07"]), + "3b_08": Room("3b", "3b_08", "Celestial Resort B - Room 08", [reg for _, reg in all_regions.items() if reg.room_name == "3b_08"], [door for _, door in all_doors.items() if door.room_name == "3b_08"]), + "3b_09": Room("3b", "3b_09", "Celestial Resort B - Room 09", [reg for _, reg in all_regions.items() if reg.room_name == "3b_09"], [door for _, door in all_doors.items() if door.room_name == "3b_09"]), + "3b_10": Room("3b", "3b_10", "Celestial Resort B - Room 10", [reg for _, reg in all_regions.items() if reg.room_name == "3b_10"], [door for _, door in all_doors.items() if door.room_name == "3b_10"]), + "3b_11": Room("3b", "3b_11", "Celestial Resort B - Room 11", [reg for _, reg in all_regions.items() if reg.room_name == "3b_11"], [door for _, door in all_doors.items() if door.room_name == "3b_11"], "Library", "3b_11_west"), + "3b_13": Room("3b", "3b_13", "Celestial Resort B - Room 13", [reg for _, reg in all_regions.items() if reg.room_name == "3b_13"], [door for _, door in all_doors.items() if door.room_name == "3b_13"]), + "3b_14": Room("3b", "3b_14", "Celestial Resort B - Room 14", [reg for _, reg in all_regions.items() if reg.room_name == "3b_14"], [door for _, door in all_doors.items() if door.room_name == "3b_14"]), + "3b_15": Room("3b", "3b_15", "Celestial Resort B - Room 15", [reg for _, reg in all_regions.items() if reg.room_name == "3b_15"], [door for _, door in all_doors.items() if door.room_name == "3b_15"]), + "3b_12": Room("3b", "3b_12", "Celestial Resort B - Room 12", [reg for _, reg in all_regions.items() if reg.room_name == "3b_12"], [door for _, door in all_doors.items() if door.room_name == "3b_12"]), + "3b_16": Room("3b", "3b_16", "Celestial Resort B - Room 16", [reg for _, reg in all_regions.items() if reg.room_name == "3b_16"], [door for _, door in all_doors.items() if door.room_name == "3b_16"], "Rooftop", "3b_16_west"), + "3b_17": Room("3b", "3b_17", "Celestial Resort B - Room 17", [reg for _, reg in all_regions.items() if reg.room_name == "3b_17"], [door for _, door in all_doors.items() if door.room_name == "3b_17"]), + "3b_18": Room("3b", "3b_18", "Celestial Resort B - Room 18", [reg for _, reg in all_regions.items() if reg.room_name == "3b_18"], [door for _, door in all_doors.items() if door.room_name == "3b_18"]), + "3b_19": Room("3b", "3b_19", "Celestial Resort B - Room 19", [reg for _, reg in all_regions.items() if reg.room_name == "3b_19"], [door for _, door in all_doors.items() if door.room_name == "3b_19"]), + "3b_21": Room("3b", "3b_21", "Celestial Resort B - Room 21", [reg for _, reg in all_regions.items() if reg.room_name == "3b_21"], [door for _, door in all_doors.items() if door.room_name == "3b_21"]), + "3b_20": Room("3b", "3b_20", "Celestial Resort B - Room 20", [reg for _, reg in all_regions.items() if reg.room_name == "3b_20"], [door for _, door in all_doors.items() if door.room_name == "3b_20"]), + "3b_end": Room("3b", "3b_end", "Celestial Resort B - Room end", [reg for _, reg in all_regions.items() if reg.room_name == "3b_end"], [door for _, door in all_doors.items() if door.room_name == "3b_end"]), + + "3c_00": Room("3c", "3c_00", "Celestial Resort C - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "3c_00"], [door for _, door in all_doors.items() if door.room_name == "3c_00"], "Start", "3c_00_west"), + "3c_01": Room("3c", "3c_01", "Celestial Resort C - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "3c_01"], [door for _, door in all_doors.items() if door.room_name == "3c_01"]), + "3c_02": Room("3c", "3c_02", "Celestial Resort C - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "3c_02"], [door for _, door in all_doors.items() if door.room_name == "3c_02"]), + + "4a_a-00": Room("4a", "4a_a-00", "Golden Ridge A - Room a-00", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-00"], [door for _, door in all_doors.items() if door.room_name == "4a_a-00"], "Start", "4a_a-00_west"), + "4a_a-01": Room("4a", "4a_a-01", "Golden Ridge A - Room a-01", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-01"], [door for _, door in all_doors.items() if door.room_name == "4a_a-01"]), + "4a_a-01x": Room("4a", "4a_a-01x", "Golden Ridge A - Room a-01x", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-01x"], [door for _, door in all_doors.items() if door.room_name == "4a_a-01x"]), + "4a_a-02": Room("4a", "4a_a-02", "Golden Ridge A - Room a-02", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-02"], [door for _, door in all_doors.items() if door.room_name == "4a_a-02"]), + "4a_a-03": Room("4a", "4a_a-03", "Golden Ridge A - Room a-03", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-03"], [door for _, door in all_doors.items() if door.room_name == "4a_a-03"]), + "4a_a-04": Room("4a", "4a_a-04", "Golden Ridge A - Room a-04", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-04"], [door for _, door in all_doors.items() if door.room_name == "4a_a-04"]), + "4a_a-05": Room("4a", "4a_a-05", "Golden Ridge A - Room a-05", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-05"], [door for _, door in all_doors.items() if door.room_name == "4a_a-05"]), + "4a_a-06": Room("4a", "4a_a-06", "Golden Ridge A - Room a-06", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-06"], [door for _, door in all_doors.items() if door.room_name == "4a_a-06"]), + "4a_a-07": Room("4a", "4a_a-07", "Golden Ridge A - Room a-07", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-07"], [door for _, door in all_doors.items() if door.room_name == "4a_a-07"]), + "4a_a-08": Room("4a", "4a_a-08", "Golden Ridge A - Room a-08", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-08"], [door for _, door in all_doors.items() if door.room_name == "4a_a-08"]), + "4a_a-10": Room("4a", "4a_a-10", "Golden Ridge A - Room a-10", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-10"], [door for _, door in all_doors.items() if door.room_name == "4a_a-10"]), + "4a_a-11": Room("4a", "4a_a-11", "Golden Ridge A - Room a-11", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-11"], [door for _, door in all_doors.items() if door.room_name == "4a_a-11"]), + "4a_a-09": Room("4a", "4a_a-09", "Golden Ridge A - Room a-09", [reg for _, reg in all_regions.items() if reg.room_name == "4a_a-09"], [door for _, door in all_doors.items() if door.room_name == "4a_a-09"]), + "4a_b-00": Room("4a", "4a_b-00", "Golden Ridge A - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-00"], [door for _, door in all_doors.items() if door.room_name == "4a_b-00"], "Shrine", "4a_b-00_south"), + "4a_b-01": Room("4a", "4a_b-01", "Golden Ridge A - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-01"], [door for _, door in all_doors.items() if door.room_name == "4a_b-01"]), + "4a_b-04": Room("4a", "4a_b-04", "Golden Ridge A - Room b-04", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-04"], [door for _, door in all_doors.items() if door.room_name == "4a_b-04"]), + "4a_b-06": Room("4a", "4a_b-06", "Golden Ridge A - Room b-06", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-06"], [door for _, door in all_doors.items() if door.room_name == "4a_b-06"]), + "4a_b-07": Room("4a", "4a_b-07", "Golden Ridge A - Room b-07", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-07"], [door for _, door in all_doors.items() if door.room_name == "4a_b-07"]), + "4a_b-03": Room("4a", "4a_b-03", "Golden Ridge A - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-03"], [door for _, door in all_doors.items() if door.room_name == "4a_b-03"]), + "4a_b-02": Room("4a", "4a_b-02", "Golden Ridge A - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-02"], [door for _, door in all_doors.items() if door.room_name == "4a_b-02"]), + "4a_b-sec": Room("4a", "4a_b-sec", "Golden Ridge A - Room b-sec", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-sec"], [door for _, door in all_doors.items() if door.room_name == "4a_b-sec"]), + "4a_b-secb": Room("4a", "4a_b-secb", "Golden Ridge A - Room b-secb", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-secb"], [door for _, door in all_doors.items() if door.room_name == "4a_b-secb"]), + "4a_b-05": Room("4a", "4a_b-05", "Golden Ridge A - Room b-05", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-05"], [door for _, door in all_doors.items() if door.room_name == "4a_b-05"]), + "4a_b-08b": Room("4a", "4a_b-08b", "Golden Ridge A - Room b-08b", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-08b"], [door for _, door in all_doors.items() if door.room_name == "4a_b-08b"]), + "4a_b-08": Room("4a", "4a_b-08", "Golden Ridge A - Room b-08", [reg for _, reg in all_regions.items() if reg.room_name == "4a_b-08"], [door for _, door in all_doors.items() if door.room_name == "4a_b-08"]), + "4a_c-00": Room("4a", "4a_c-00", "Golden Ridge A - Room c-00", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-00"], [door for _, door in all_doors.items() if door.room_name == "4a_c-00"], "Old Trail", "4a_c-00_west"), + "4a_c-01": Room("4a", "4a_c-01", "Golden Ridge A - Room c-01", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-01"], [door for _, door in all_doors.items() if door.room_name == "4a_c-01"]), + "4a_c-02": Room("4a", "4a_c-02", "Golden Ridge A - Room c-02", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-02"], [door for _, door in all_doors.items() if door.room_name == "4a_c-02"]), + "4a_c-04": Room("4a", "4a_c-04", "Golden Ridge A - Room c-04", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-04"], [door for _, door in all_doors.items() if door.room_name == "4a_c-04"]), + "4a_c-05": Room("4a", "4a_c-05", "Golden Ridge A - Room c-05", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-05"], [door for _, door in all_doors.items() if door.room_name == "4a_c-05"]), + "4a_c-06": Room("4a", "4a_c-06", "Golden Ridge A - Room c-06", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-06"], [door for _, door in all_doors.items() if door.room_name == "4a_c-06"]), + "4a_c-06b": Room("4a", "4a_c-06b", "Golden Ridge A - Room c-06b", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-06b"], [door for _, door in all_doors.items() if door.room_name == "4a_c-06b"]), + "4a_c-09": Room("4a", "4a_c-09", "Golden Ridge A - Room c-09", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-09"], [door for _, door in all_doors.items() if door.room_name == "4a_c-09"]), + "4a_c-07": Room("4a", "4a_c-07", "Golden Ridge A - Room c-07", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-07"], [door for _, door in all_doors.items() if door.room_name == "4a_c-07"]), + "4a_c-08": Room("4a", "4a_c-08", "Golden Ridge A - Room c-08", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-08"], [door for _, door in all_doors.items() if door.room_name == "4a_c-08"]), + "4a_c-10": Room("4a", "4a_c-10", "Golden Ridge A - Room c-10", [reg for _, reg in all_regions.items() if reg.room_name == "4a_c-10"], [door for _, door in all_doors.items() if door.room_name == "4a_c-10"]), + "4a_d-00": Room("4a", "4a_d-00", "Golden Ridge A - Room d-00", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-00"], [door for _, door in all_doors.items() if door.room_name == "4a_d-00"], "Cliff Face", "4a_d-00_west"), + "4a_d-00b": Room("4a", "4a_d-00b", "Golden Ridge A - Room d-00b", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-00b"], [door for _, door in all_doors.items() if door.room_name == "4a_d-00b"]), + "4a_d-01": Room("4a", "4a_d-01", "Golden Ridge A - Room d-01", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-01"], [door for _, door in all_doors.items() if door.room_name == "4a_d-01"]), + "4a_d-02": Room("4a", "4a_d-02", "Golden Ridge A - Room d-02", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-02"], [door for _, door in all_doors.items() if door.room_name == "4a_d-02"]), + "4a_d-03": Room("4a", "4a_d-03", "Golden Ridge A - Room d-03", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-03"], [door for _, door in all_doors.items() if door.room_name == "4a_d-03"]), + "4a_d-04": Room("4a", "4a_d-04", "Golden Ridge A - Room d-04", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-04"], [door for _, door in all_doors.items() if door.room_name == "4a_d-04"]), + "4a_d-05": Room("4a", "4a_d-05", "Golden Ridge A - Room d-05", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-05"], [door for _, door in all_doors.items() if door.room_name == "4a_d-05"]), + "4a_d-06": Room("4a", "4a_d-06", "Golden Ridge A - Room d-06", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-06"], [door for _, door in all_doors.items() if door.room_name == "4a_d-06"]), + "4a_d-07": Room("4a", "4a_d-07", "Golden Ridge A - Room d-07", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-07"], [door for _, door in all_doors.items() if door.room_name == "4a_d-07"]), + "4a_d-08": Room("4a", "4a_d-08", "Golden Ridge A - Room d-08", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-08"], [door for _, door in all_doors.items() if door.room_name == "4a_d-08"]), + "4a_d-09": Room("4a", "4a_d-09", "Golden Ridge A - Room d-09", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-09"], [door for _, door in all_doors.items() if door.room_name == "4a_d-09"]), + "4a_d-10": Room("4a", "4a_d-10", "Golden Ridge A - Room d-10", [reg for _, reg in all_regions.items() if reg.room_name == "4a_d-10"], [door for _, door in all_doors.items() if door.room_name == "4a_d-10"]), + + "4b_a-00": Room("4b", "4b_a-00", "Golden Ridge B - Room a-00", [reg for _, reg in all_regions.items() if reg.room_name == "4b_a-00"], [door for _, door in all_doors.items() if door.room_name == "4b_a-00"], "Start", "4b_a-00_west"), + "4b_a-01": Room("4b", "4b_a-01", "Golden Ridge B - Room a-01", [reg for _, reg in all_regions.items() if reg.room_name == "4b_a-01"], [door for _, door in all_doors.items() if door.room_name == "4b_a-01"]), + "4b_a-02": Room("4b", "4b_a-02", "Golden Ridge B - Room a-02", [reg for _, reg in all_regions.items() if reg.room_name == "4b_a-02"], [door for _, door in all_doors.items() if door.room_name == "4b_a-02"]), + "4b_a-03": Room("4b", "4b_a-03", "Golden Ridge B - Room a-03", [reg for _, reg in all_regions.items() if reg.room_name == "4b_a-03"], [door for _, door in all_doors.items() if door.room_name == "4b_a-03"]), + "4b_a-04": Room("4b", "4b_a-04", "Golden Ridge B - Room a-04", [reg for _, reg in all_regions.items() if reg.room_name == "4b_a-04"], [door for _, door in all_doors.items() if door.room_name == "4b_a-04"]), + "4b_b-00": Room("4b", "4b_b-00", "Golden Ridge B - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "4b_b-00"], [door for _, door in all_doors.items() if door.room_name == "4b_b-00"], "Stepping Stones", "4b_b-00_west"), + "4b_b-01": Room("4b", "4b_b-01", "Golden Ridge B - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "4b_b-01"], [door for _, door in all_doors.items() if door.room_name == "4b_b-01"]), + "4b_b-02": Room("4b", "4b_b-02", "Golden Ridge B - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "4b_b-02"], [door for _, door in all_doors.items() if door.room_name == "4b_b-02"]), + "4b_b-03": Room("4b", "4b_b-03", "Golden Ridge B - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "4b_b-03"], [door for _, door in all_doors.items() if door.room_name == "4b_b-03"]), + "4b_b-04": Room("4b", "4b_b-04", "Golden Ridge B - Room b-04", [reg for _, reg in all_regions.items() if reg.room_name == "4b_b-04"], [door for _, door in all_doors.items() if door.room_name == "4b_b-04"]), + "4b_c-00": Room("4b", "4b_c-00", "Golden Ridge B - Room c-00", [reg for _, reg in all_regions.items() if reg.room_name == "4b_c-00"], [door for _, door in all_doors.items() if door.room_name == "4b_c-00"], "Gusty Canyon", "4b_c-00_west"), + "4b_c-01": Room("4b", "4b_c-01", "Golden Ridge B - Room c-01", [reg for _, reg in all_regions.items() if reg.room_name == "4b_c-01"], [door for _, door in all_doors.items() if door.room_name == "4b_c-01"]), + "4b_c-02": Room("4b", "4b_c-02", "Golden Ridge B - Room c-02", [reg for _, reg in all_regions.items() if reg.room_name == "4b_c-02"], [door for _, door in all_doors.items() if door.room_name == "4b_c-02"]), + "4b_c-03": Room("4b", "4b_c-03", "Golden Ridge B - Room c-03", [reg for _, reg in all_regions.items() if reg.room_name == "4b_c-03"], [door for _, door in all_doors.items() if door.room_name == "4b_c-03"]), + "4b_c-04": Room("4b", "4b_c-04", "Golden Ridge B - Room c-04", [reg for _, reg in all_regions.items() if reg.room_name == "4b_c-04"], [door for _, door in all_doors.items() if door.room_name == "4b_c-04"]), + "4b_d-00": Room("4b", "4b_d-00", "Golden Ridge B - Room d-00", [reg for _, reg in all_regions.items() if reg.room_name == "4b_d-00"], [door for _, door in all_doors.items() if door.room_name == "4b_d-00"], "Eye of the Storm", "4b_d-00_west"), + "4b_d-01": Room("4b", "4b_d-01", "Golden Ridge B - Room d-01", [reg for _, reg in all_regions.items() if reg.room_name == "4b_d-01"], [door for _, door in all_doors.items() if door.room_name == "4b_d-01"]), + "4b_d-02": Room("4b", "4b_d-02", "Golden Ridge B - Room d-02", [reg for _, reg in all_regions.items() if reg.room_name == "4b_d-02"], [door for _, door in all_doors.items() if door.room_name == "4b_d-02"]), + "4b_d-03": Room("4b", "4b_d-03", "Golden Ridge B - Room d-03", [reg for _, reg in all_regions.items() if reg.room_name == "4b_d-03"], [door for _, door in all_doors.items() if door.room_name == "4b_d-03"]), + "4b_end": Room("4b", "4b_end", "Golden Ridge B - Room end", [reg for _, reg in all_regions.items() if reg.room_name == "4b_end"], [door for _, door in all_doors.items() if door.room_name == "4b_end"]), + + "4c_00": Room("4c", "4c_00", "Golden Ridge C - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "4c_00"], [door for _, door in all_doors.items() if door.room_name == "4c_00"], "Start", "4c_00_west"), + "4c_01": Room("4c", "4c_01", "Golden Ridge C - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "4c_01"], [door for _, door in all_doors.items() if door.room_name == "4c_01"]), + "4c_02": Room("4c", "4c_02", "Golden Ridge C - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "4c_02"], [door for _, door in all_doors.items() if door.room_name == "4c_02"]), + + "5a_a-00b": Room("5a", "5a_a-00b", "Mirror Temple A - Room a-00b", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-00b"], [door for _, door in all_doors.items() if door.room_name == "5a_a-00b"], "Start", "5a_a-00b_west"), + "5a_a-00x": Room("5a", "5a_a-00x", "Mirror Temple A - Room a-00x", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-00x"], [door for _, door in all_doors.items() if door.room_name == "5a_a-00x"]), + "5a_a-00d": Room("5a", "5a_a-00d", "Mirror Temple A - Room a-00d", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-00d"], [door for _, door in all_doors.items() if door.room_name == "5a_a-00d"]), + "5a_a-00c": Room("5a", "5a_a-00c", "Mirror Temple A - Room a-00c", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-00c"], [door for _, door in all_doors.items() if door.room_name == "5a_a-00c"]), + "5a_a-00": Room("5a", "5a_a-00", "Mirror Temple A - Room a-00", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-00"], [door for _, door in all_doors.items() if door.room_name == "5a_a-00"]), + "5a_a-01": Room("5a", "5a_a-01", "Mirror Temple A - Room a-01", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-01"], [door for _, door in all_doors.items() if door.room_name == "5a_a-01"]), + "5a_a-02": Room("5a", "5a_a-02", "Mirror Temple A - Room a-02", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-02"], [door for _, door in all_doors.items() if door.room_name == "5a_a-02"]), + "5a_a-03": Room("5a", "5a_a-03", "Mirror Temple A - Room a-03", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-03"], [door for _, door in all_doors.items() if door.room_name == "5a_a-03"]), + "5a_a-04": Room("5a", "5a_a-04", "Mirror Temple A - Room a-04", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-04"], [door for _, door in all_doors.items() if door.room_name == "5a_a-04"]), + "5a_a-05": Room("5a", "5a_a-05", "Mirror Temple A - Room a-05", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-05"], [door for _, door in all_doors.items() if door.room_name == "5a_a-05"]), + "5a_a-06": Room("5a", "5a_a-06", "Mirror Temple A - Room a-06", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-06"], [door for _, door in all_doors.items() if door.room_name == "5a_a-06"]), + "5a_a-07": Room("5a", "5a_a-07", "Mirror Temple A - Room a-07", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-07"], [door for _, door in all_doors.items() if door.room_name == "5a_a-07"]), + "5a_a-08": Room("5a", "5a_a-08", "Mirror Temple A - Room a-08", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-08"], [door for _, door in all_doors.items() if door.room_name == "5a_a-08"]), + "5a_a-10": Room("5a", "5a_a-10", "Mirror Temple A - Room a-10", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-10"], [door for _, door in all_doors.items() if door.room_name == "5a_a-10"]), + "5a_a-09": Room("5a", "5a_a-09", "Mirror Temple A - Room a-09", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-09"], [door for _, door in all_doors.items() if door.room_name == "5a_a-09"]), + "5a_a-11": Room("5a", "5a_a-11", "Mirror Temple A - Room a-11", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-11"], [door for _, door in all_doors.items() if door.room_name == "5a_a-11"]), + "5a_a-12": Room("5a", "5a_a-12", "Mirror Temple A - Room a-12", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-12"], [door for _, door in all_doors.items() if door.room_name == "5a_a-12"]), + "5a_a-15": Room("5a", "5a_a-15", "Mirror Temple A - Room a-15", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-15"], [door for _, door in all_doors.items() if door.room_name == "5a_a-15"]), + "5a_a-14": Room("5a", "5a_a-14", "Mirror Temple A - Room a-14", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-14"], [door for _, door in all_doors.items() if door.room_name == "5a_a-14"]), + "5a_a-13": Room("5a", "5a_a-13", "Mirror Temple A - Room a-13", [reg for _, reg in all_regions.items() if reg.room_name == "5a_a-13"], [door for _, door in all_doors.items() if door.room_name == "5a_a-13"]), + "5a_b-00": Room("5a", "5a_b-00", "Mirror Temple A - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-00"], [door for _, door in all_doors.items() if door.room_name == "5a_b-00"], "Depths", "5a_b-00_west"), + "5a_b-18": Room("5a", "5a_b-18", "Mirror Temple A - Room b-18", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-18"], [door for _, door in all_doors.items() if door.room_name == "5a_b-18"]), + "5a_b-01": Room("5a", "5a_b-01", "Mirror Temple A - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-01"], [door for _, door in all_doors.items() if door.room_name == "5a_b-01"]), + "5a_b-01c": Room("5a", "5a_b-01c", "Mirror Temple A - Room b-01c", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-01c"], [door for _, door in all_doors.items() if door.room_name == "5a_b-01c"]), + "5a_b-20": Room("5a", "5a_b-20", "Mirror Temple A - Room b-20", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-20"], [door for _, door in all_doors.items() if door.room_name == "5a_b-20"]), + "5a_b-21": Room("5a", "5a_b-21", "Mirror Temple A - Room b-21", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-21"], [door for _, door in all_doors.items() if door.room_name == "5a_b-21"]), + "5a_b-01b": Room("5a", "5a_b-01b", "Mirror Temple A - Room b-01b", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-01b"], [door for _, door in all_doors.items() if door.room_name == "5a_b-01b"]), + "5a_b-02": Room("5a", "5a_b-02", "Mirror Temple A - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-02"], [door for _, door in all_doors.items() if door.room_name == "5a_b-02"]), + "5a_b-03": Room("5a", "5a_b-03", "Mirror Temple A - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-03"], [door for _, door in all_doors.items() if door.room_name == "5a_b-03"]), + "5a_b-05": Room("5a", "5a_b-05", "Mirror Temple A - Room b-05", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-05"], [door for _, door in all_doors.items() if door.room_name == "5a_b-05"]), + "5a_b-04": Room("5a", "5a_b-04", "Mirror Temple A - Room b-04", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-04"], [door for _, door in all_doors.items() if door.room_name == "5a_b-04"]), + "5a_b-07": Room("5a", "5a_b-07", "Mirror Temple A - Room b-07", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-07"], [door for _, door in all_doors.items() if door.room_name == "5a_b-07"]), + "5a_b-08": Room("5a", "5a_b-08", "Mirror Temple A - Room b-08", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-08"], [door for _, door in all_doors.items() if door.room_name == "5a_b-08"]), + "5a_b-09": Room("5a", "5a_b-09", "Mirror Temple A - Room b-09", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-09"], [door for _, door in all_doors.items() if door.room_name == "5a_b-09"]), + "5a_b-10": Room("5a", "5a_b-10", "Mirror Temple A - Room b-10", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-10"], [door for _, door in all_doors.items() if door.room_name == "5a_b-10"]), + "5a_b-11": Room("5a", "5a_b-11", "Mirror Temple A - Room b-11", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-11"], [door for _, door in all_doors.items() if door.room_name == "5a_b-11"]), + "5a_b-12": Room("5a", "5a_b-12", "Mirror Temple A - Room b-12", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-12"], [door for _, door in all_doors.items() if door.room_name == "5a_b-12"]), + "5a_b-13": Room("5a", "5a_b-13", "Mirror Temple A - Room b-13", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-13"], [door for _, door in all_doors.items() if door.room_name == "5a_b-13"]), + "5a_b-17": Room("5a", "5a_b-17", "Mirror Temple A - Room b-17", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-17"], [door for _, door in all_doors.items() if door.room_name == "5a_b-17"]), + "5a_b-22": Room("5a", "5a_b-22", "Mirror Temple A - Room b-22", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-22"], [door for _, door in all_doors.items() if door.room_name == "5a_b-22"]), + "5a_b-06": Room("5a", "5a_b-06", "Mirror Temple A - Room b-06", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-06"], [door for _, door in all_doors.items() if door.room_name == "5a_b-06"]), + "5a_b-19": Room("5a", "5a_b-19", "Mirror Temple A - Room b-19", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-19"], [door for _, door in all_doors.items() if door.room_name == "5a_b-19"]), + "5a_b-14": Room("5a", "5a_b-14", "Mirror Temple A - Room b-14", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-14"], [door for _, door in all_doors.items() if door.room_name == "5a_b-14"]), + "5a_b-15": Room("5a", "5a_b-15", "Mirror Temple A - Room b-15", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-15"], [door for _, door in all_doors.items() if door.room_name == "5a_b-15"]), + "5a_b-16": Room("5a", "5a_b-16", "Mirror Temple A - Room b-16", [reg for _, reg in all_regions.items() if reg.room_name == "5a_b-16"], [door for _, door in all_doors.items() if door.room_name == "5a_b-16"]), + "5a_void": Room("5a", "5a_void", "Mirror Temple A - Room void", [reg for _, reg in all_regions.items() if reg.room_name == "5a_void"], [door for _, door in all_doors.items() if door.room_name == "5a_void"]), + "5a_c-00": Room("5a", "5a_c-00", "Mirror Temple A - Room c-00", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-00"], [door for _, door in all_doors.items() if door.room_name == "5a_c-00"], "Unravelling", "5a_c-00_top"), + "5a_c-01": Room("5a", "5a_c-01", "Mirror Temple A - Room c-01", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-01"], [door for _, door in all_doors.items() if door.room_name == "5a_c-01"]), + "5a_c-01b": Room("5a", "5a_c-01b", "Mirror Temple A - Room c-01b", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-01b"], [door for _, door in all_doors.items() if door.room_name == "5a_c-01b"]), + "5a_c-01c": Room("5a", "5a_c-01c", "Mirror Temple A - Room c-01c", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-01c"], [door for _, door in all_doors.items() if door.room_name == "5a_c-01c"]), + "5a_c-08b": Room("5a", "5a_c-08b", "Mirror Temple A - Room c-08b", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-08b"], [door for _, door in all_doors.items() if door.room_name == "5a_c-08b"]), + "5a_c-08": Room("5a", "5a_c-08", "Mirror Temple A - Room c-08", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-08"], [door for _, door in all_doors.items() if door.room_name == "5a_c-08"]), + "5a_c-10": Room("5a", "5a_c-10", "Mirror Temple A - Room c-10", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-10"], [door for _, door in all_doors.items() if door.room_name == "5a_c-10"]), + "5a_c-12": Room("5a", "5a_c-12", "Mirror Temple A - Room c-12", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-12"], [door for _, door in all_doors.items() if door.room_name == "5a_c-12"]), + "5a_c-07": Room("5a", "5a_c-07", "Mirror Temple A - Room c-07", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-07"], [door for _, door in all_doors.items() if door.room_name == "5a_c-07"]), + "5a_c-11": Room("5a", "5a_c-11", "Mirror Temple A - Room c-11", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-11"], [door for _, door in all_doors.items() if door.room_name == "5a_c-11"]), + "5a_c-09": Room("5a", "5a_c-09", "Mirror Temple A - Room c-09", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-09"], [door for _, door in all_doors.items() if door.room_name == "5a_c-09"]), + "5a_c-13": Room("5a", "5a_c-13", "Mirror Temple A - Room c-13", [reg for _, reg in all_regions.items() if reg.room_name == "5a_c-13"], [door for _, door in all_doors.items() if door.room_name == "5a_c-13"]), + "5a_d-00": Room("5a", "5a_d-00", "Mirror Temple A - Room d-00", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-00"], [door for _, door in all_doors.items() if door.room_name == "5a_d-00"], "Search", "5a_d-00_south"), + "5a_d-01": Room("5a", "5a_d-01", "Mirror Temple A - Room d-01", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-01"], [door for _, door in all_doors.items() if door.room_name == "5a_d-01"]), + "5a_d-09": Room("5a", "5a_d-09", "Mirror Temple A - Room d-09", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-09"], [door for _, door in all_doors.items() if door.room_name == "5a_d-09"]), + "5a_d-04": Room("5a", "5a_d-04", "Mirror Temple A - Room d-04", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-04"], [door for _, door in all_doors.items() if door.room_name == "5a_d-04"]), + "5a_d-05": Room("5a", "5a_d-05", "Mirror Temple A - Room d-05", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-05"], [door for _, door in all_doors.items() if door.room_name == "5a_d-05"]), + "5a_d-06": Room("5a", "5a_d-06", "Mirror Temple A - Room d-06", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-06"], [door for _, door in all_doors.items() if door.room_name == "5a_d-06"]), + "5a_d-07": Room("5a", "5a_d-07", "Mirror Temple A - Room d-07", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-07"], [door for _, door in all_doors.items() if door.room_name == "5a_d-07"]), + "5a_d-02": Room("5a", "5a_d-02", "Mirror Temple A - Room d-02", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-02"], [door for _, door in all_doors.items() if door.room_name == "5a_d-02"]), + "5a_d-03": Room("5a", "5a_d-03", "Mirror Temple A - Room d-03", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-03"], [door for _, door in all_doors.items() if door.room_name == "5a_d-03"]), + "5a_d-15": Room("5a", "5a_d-15", "Mirror Temple A - Room d-15", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-15"], [door for _, door in all_doors.items() if door.room_name == "5a_d-15"]), + "5a_d-13": Room("5a", "5a_d-13", "Mirror Temple A - Room d-13", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-13"], [door for _, door in all_doors.items() if door.room_name == "5a_d-13"]), + "5a_d-19b": Room("5a", "5a_d-19b", "Mirror Temple A - Room d-19b", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-19b"], [door for _, door in all_doors.items() if door.room_name == "5a_d-19b"]), + "5a_d-19": Room("5a", "5a_d-19", "Mirror Temple A - Room d-19", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-19"], [door for _, door in all_doors.items() if door.room_name == "5a_d-19"]), + "5a_d-10": Room("5a", "5a_d-10", "Mirror Temple A - Room d-10", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-10"], [door for _, door in all_doors.items() if door.room_name == "5a_d-10"]), + "5a_d-20": Room("5a", "5a_d-20", "Mirror Temple A - Room d-20", [reg for _, reg in all_regions.items() if reg.room_name == "5a_d-20"], [door for _, door in all_doors.items() if door.room_name == "5a_d-20"]), + "5a_e-00": Room("5a", "5a_e-00", "Mirror Temple A - Room e-00", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-00"], [door for _, door in all_doors.items() if door.room_name == "5a_e-00"], "Rescue", "5a_e-00_west"), + "5a_e-01": Room("5a", "5a_e-01", "Mirror Temple A - Room e-01", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-01"], [door for _, door in all_doors.items() if door.room_name == "5a_e-01"]), + "5a_e-02": Room("5a", "5a_e-02", "Mirror Temple A - Room e-02", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-02"], [door for _, door in all_doors.items() if door.room_name == "5a_e-02"]), + "5a_e-03": Room("5a", "5a_e-03", "Mirror Temple A - Room e-03", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-03"], [door for _, door in all_doors.items() if door.room_name == "5a_e-03"]), + "5a_e-04": Room("5a", "5a_e-04", "Mirror Temple A - Room e-04", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-04"], [door for _, door in all_doors.items() if door.room_name == "5a_e-04"]), + "5a_e-06": Room("5a", "5a_e-06", "Mirror Temple A - Room e-06", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-06"], [door for _, door in all_doors.items() if door.room_name == "5a_e-06"]), + "5a_e-05": Room("5a", "5a_e-05", "Mirror Temple A - Room e-05", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-05"], [door for _, door in all_doors.items() if door.room_name == "5a_e-05"]), + "5a_e-07": Room("5a", "5a_e-07", "Mirror Temple A - Room e-07", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-07"], [door for _, door in all_doors.items() if door.room_name == "5a_e-07"]), + "5a_e-08": Room("5a", "5a_e-08", "Mirror Temple A - Room e-08", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-08"], [door for _, door in all_doors.items() if door.room_name == "5a_e-08"]), + "5a_e-09": Room("5a", "5a_e-09", "Mirror Temple A - Room e-09", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-09"], [door for _, door in all_doors.items() if door.room_name == "5a_e-09"]), + "5a_e-10": Room("5a", "5a_e-10", "Mirror Temple A - Room e-10", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-10"], [door for _, door in all_doors.items() if door.room_name == "5a_e-10"]), + "5a_e-11": Room("5a", "5a_e-11", "Mirror Temple A - Room e-11", [reg for _, reg in all_regions.items() if reg.room_name == "5a_e-11"], [door for _, door in all_doors.items() if door.room_name == "5a_e-11"]), + + "5b_start": Room("5b", "5b_start", "Mirror Temple B - Room start", [reg for _, reg in all_regions.items() if reg.room_name == "5b_start"], [door for _, door in all_doors.items() if door.room_name == "5b_start"], "Start", "5b_start_west"), + "5b_a-00": Room("5b", "5b_a-00", "Mirror Temple B - Room a-00", [reg for _, reg in all_regions.items() if reg.room_name == "5b_a-00"], [door for _, door in all_doors.items() if door.room_name == "5b_a-00"]), + "5b_a-01": Room("5b", "5b_a-01", "Mirror Temple B - Room a-01", [reg for _, reg in all_regions.items() if reg.room_name == "5b_a-01"], [door for _, door in all_doors.items() if door.room_name == "5b_a-01"]), + "5b_a-02": Room("5b", "5b_a-02", "Mirror Temple B - Room a-02", [reg for _, reg in all_regions.items() if reg.room_name == "5b_a-02"], [door for _, door in all_doors.items() if door.room_name == "5b_a-02"]), + "5b_b-00": Room("5b", "5b_b-00", "Mirror Temple B - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "5b_b-00"], [door for _, door in all_doors.items() if door.room_name == "5b_b-00"], "Central Chamber", "5b_b-00_south"), + "5b_b-01": Room("5b", "5b_b-01", "Mirror Temple B - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "5b_b-01"], [door for _, door in all_doors.items() if door.room_name == "5b_b-01"]), + "5b_b-04": Room("5b", "5b_b-04", "Mirror Temple B - Room b-04", [reg for _, reg in all_regions.items() if reg.room_name == "5b_b-04"], [door for _, door in all_doors.items() if door.room_name == "5b_b-04"]), + "5b_b-02": Room("5b", "5b_b-02", "Mirror Temple B - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "5b_b-02"], [door for _, door in all_doors.items() if door.room_name == "5b_b-02"]), + "5b_b-05": Room("5b", "5b_b-05", "Mirror Temple B - Room b-05", [reg for _, reg in all_regions.items() if reg.room_name == "5b_b-05"], [door for _, door in all_doors.items() if door.room_name == "5b_b-05"]), + "5b_b-06": Room("5b", "5b_b-06", "Mirror Temple B - Room b-06", [reg for _, reg in all_regions.items() if reg.room_name == "5b_b-06"], [door for _, door in all_doors.items() if door.room_name == "5b_b-06"]), + "5b_b-07": Room("5b", "5b_b-07", "Mirror Temple B - Room b-07", [reg for _, reg in all_regions.items() if reg.room_name == "5b_b-07"], [door for _, door in all_doors.items() if door.room_name == "5b_b-07"]), + "5b_b-03": Room("5b", "5b_b-03", "Mirror Temple B - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "5b_b-03"], [door for _, door in all_doors.items() if door.room_name == "5b_b-03"]), + "5b_b-08": Room("5b", "5b_b-08", "Mirror Temple B - Room b-08", [reg for _, reg in all_regions.items() if reg.room_name == "5b_b-08"], [door for _, door in all_doors.items() if door.room_name == "5b_b-08"]), + "5b_b-09": Room("5b", "5b_b-09", "Mirror Temple B - Room b-09", [reg for _, reg in all_regions.items() if reg.room_name == "5b_b-09"], [door for _, door in all_doors.items() if door.room_name == "5b_b-09"]), + "5b_c-00": Room("5b", "5b_c-00", "Mirror Temple B - Room c-00", [reg for _, reg in all_regions.items() if reg.room_name == "5b_c-00"], [door for _, door in all_doors.items() if door.room_name == "5b_c-00"], "Through the Mirror", "5b_c-00_mirror"), + "5b_c-01": Room("5b", "5b_c-01", "Mirror Temple B - Room c-01", [reg for _, reg in all_regions.items() if reg.room_name == "5b_c-01"], [door for _, door in all_doors.items() if door.room_name == "5b_c-01"]), + "5b_c-02": Room("5b", "5b_c-02", "Mirror Temple B - Room c-02", [reg for _, reg in all_regions.items() if reg.room_name == "5b_c-02"], [door for _, door in all_doors.items() if door.room_name == "5b_c-02"]), + "5b_c-03": Room("5b", "5b_c-03", "Mirror Temple B - Room c-03", [reg for _, reg in all_regions.items() if reg.room_name == "5b_c-03"], [door for _, door in all_doors.items() if door.room_name == "5b_c-03"]), + "5b_c-04": Room("5b", "5b_c-04", "Mirror Temple B - Room c-04", [reg for _, reg in all_regions.items() if reg.room_name == "5b_c-04"], [door for _, door in all_doors.items() if door.room_name == "5b_c-04"]), + "5b_d-00": Room("5b", "5b_d-00", "Mirror Temple B - Room d-00", [reg for _, reg in all_regions.items() if reg.room_name == "5b_d-00"], [door for _, door in all_doors.items() if door.room_name == "5b_d-00"], "Mix Master", "5b_d-00_west"), + "5b_d-01": Room("5b", "5b_d-01", "Mirror Temple B - Room d-01", [reg for _, reg in all_regions.items() if reg.room_name == "5b_d-01"], [door for _, door in all_doors.items() if door.room_name == "5b_d-01"]), + "5b_d-02": Room("5b", "5b_d-02", "Mirror Temple B - Room d-02", [reg for _, reg in all_regions.items() if reg.room_name == "5b_d-02"], [door for _, door in all_doors.items() if door.room_name == "5b_d-02"]), + "5b_d-03": Room("5b", "5b_d-03", "Mirror Temple B - Room d-03", [reg for _, reg in all_regions.items() if reg.room_name == "5b_d-03"], [door for _, door in all_doors.items() if door.room_name == "5b_d-03"]), + "5b_d-04": Room("5b", "5b_d-04", "Mirror Temple B - Room d-04", [reg for _, reg in all_regions.items() if reg.room_name == "5b_d-04"], [door for _, door in all_doors.items() if door.room_name == "5b_d-04"]), + "5b_d-05": Room("5b", "5b_d-05", "Mirror Temple B - Room d-05", [reg for _, reg in all_regions.items() if reg.room_name == "5b_d-05"], [door for _, door in all_doors.items() if door.room_name == "5b_d-05"]), + + "5c_00": Room("5c", "5c_00", "Mirror Temple C - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "5c_00"], [door for _, door in all_doors.items() if door.room_name == "5c_00"], "Start", "5c_00_west"), + "5c_01": Room("5c", "5c_01", "Mirror Temple C - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "5c_01"], [door for _, door in all_doors.items() if door.room_name == "5c_01"]), + "5c_02": Room("5c", "5c_02", "Mirror Temple C - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "5c_02"], [door for _, door in all_doors.items() if door.room_name == "5c_02"]), + + "6a_00": Room("6a", "6a_00", "Reflection A - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "6a_00"], [door for _, door in all_doors.items() if door.room_name == "6a_00"], "Start", "6a_00_east"), + "6a_01": Room("6a", "6a_01", "Reflection A - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "6a_01"], [door for _, door in all_doors.items() if door.room_name == "6a_01"]), + "6a_02": Room("6a", "6a_02", "Reflection A - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "6a_02"], [door for _, door in all_doors.items() if door.room_name == "6a_02"]), + "6a_03": Room("6a", "6a_03", "Reflection A - Room 03", [reg for _, reg in all_regions.items() if reg.room_name == "6a_03"], [door for _, door in all_doors.items() if door.room_name == "6a_03"]), + "6a_02b": Room("6a", "6a_02b", "Reflection A - Room 02b", [reg for _, reg in all_regions.items() if reg.room_name == "6a_02b"], [door for _, door in all_doors.items() if door.room_name == "6a_02b"]), + "6a_04": Room("6a", "6a_04", "Reflection A - Room 04", [reg for _, reg in all_regions.items() if reg.room_name == "6a_04"], [door for _, door in all_doors.items() if door.room_name == "6a_04"], "Hollows", "6a_04_south"), + "6a_04b": Room("6a", "6a_04b", "Reflection A - Room 04b", [reg for _, reg in all_regions.items() if reg.room_name == "6a_04b"], [door for _, door in all_doors.items() if door.room_name == "6a_04b"]), + "6a_04c": Room("6a", "6a_04c", "Reflection A - Room 04c", [reg for _, reg in all_regions.items() if reg.room_name == "6a_04c"], [door for _, door in all_doors.items() if door.room_name == "6a_04c"]), + "6a_04d": Room("6a", "6a_04d", "Reflection A - Room 04d", [reg for _, reg in all_regions.items() if reg.room_name == "6a_04d"], [door for _, door in all_doors.items() if door.room_name == "6a_04d"]), + "6a_04e": Room("6a", "6a_04e", "Reflection A - Room 04e", [reg for _, reg in all_regions.items() if reg.room_name == "6a_04e"], [door for _, door in all_doors.items() if door.room_name == "6a_04e"]), + "6a_05": Room("6a", "6a_05", "Reflection A - Room 05", [reg for _, reg in all_regions.items() if reg.room_name == "6a_05"], [door for _, door in all_doors.items() if door.room_name == "6a_05"]), + "6a_06": Room("6a", "6a_06", "Reflection A - Room 06", [reg for _, reg in all_regions.items() if reg.room_name == "6a_06"], [door for _, door in all_doors.items() if door.room_name == "6a_06"]), + "6a_07": Room("6a", "6a_07", "Reflection A - Room 07", [reg for _, reg in all_regions.items() if reg.room_name == "6a_07"], [door for _, door in all_doors.items() if door.room_name == "6a_07"]), + "6a_08a": Room("6a", "6a_08a", "Reflection A - Room 08a", [reg for _, reg in all_regions.items() if reg.room_name == "6a_08a"], [door for _, door in all_doors.items() if door.room_name == "6a_08a"]), + "6a_08b": Room("6a", "6a_08b", "Reflection A - Room 08b", [reg for _, reg in all_regions.items() if reg.room_name == "6a_08b"], [door for _, door in all_doors.items() if door.room_name == "6a_08b"]), + "6a_09": Room("6a", "6a_09", "Reflection A - Room 09", [reg for _, reg in all_regions.items() if reg.room_name == "6a_09"], [door for _, door in all_doors.items() if door.room_name == "6a_09"]), + "6a_10a": Room("6a", "6a_10a", "Reflection A - Room 10a", [reg for _, reg in all_regions.items() if reg.room_name == "6a_10a"], [door for _, door in all_doors.items() if door.room_name == "6a_10a"]), + "6a_10b": Room("6a", "6a_10b", "Reflection A - Room 10b", [reg for _, reg in all_regions.items() if reg.room_name == "6a_10b"], [door for _, door in all_doors.items() if door.room_name == "6a_10b"]), + "6a_11": Room("6a", "6a_11", "Reflection A - Room 11", [reg for _, reg in all_regions.items() if reg.room_name == "6a_11"], [door for _, door in all_doors.items() if door.room_name == "6a_11"]), + "6a_12a": Room("6a", "6a_12a", "Reflection A - Room 12a", [reg for _, reg in all_regions.items() if reg.room_name == "6a_12a"], [door for _, door in all_doors.items() if door.room_name == "6a_12a"]), + "6a_12b": Room("6a", "6a_12b", "Reflection A - Room 12b", [reg for _, reg in all_regions.items() if reg.room_name == "6a_12b"], [door for _, door in all_doors.items() if door.room_name == "6a_12b"]), + "6a_13": Room("6a", "6a_13", "Reflection A - Room 13", [reg for _, reg in all_regions.items() if reg.room_name == "6a_13"], [door for _, door in all_doors.items() if door.room_name == "6a_13"]), + "6a_14a": Room("6a", "6a_14a", "Reflection A - Room 14a", [reg for _, reg in all_regions.items() if reg.room_name == "6a_14a"], [door for _, door in all_doors.items() if door.room_name == "6a_14a"]), + "6a_14b": Room("6a", "6a_14b", "Reflection A - Room 14b", [reg for _, reg in all_regions.items() if reg.room_name == "6a_14b"], [door for _, door in all_doors.items() if door.room_name == "6a_14b"]), + "6a_15": Room("6a", "6a_15", "Reflection A - Room 15", [reg for _, reg in all_regions.items() if reg.room_name == "6a_15"], [door for _, door in all_doors.items() if door.room_name == "6a_15"]), + "6a_16a": Room("6a", "6a_16a", "Reflection A - Room 16a", [reg for _, reg in all_regions.items() if reg.room_name == "6a_16a"], [door for _, door in all_doors.items() if door.room_name == "6a_16a"]), + "6a_16b": Room("6a", "6a_16b", "Reflection A - Room 16b", [reg for _, reg in all_regions.items() if reg.room_name == "6a_16b"], [door for _, door in all_doors.items() if door.room_name == "6a_16b"]), + "6a_17": Room("6a", "6a_17", "Reflection A - Room 17", [reg for _, reg in all_regions.items() if reg.room_name == "6a_17"], [door for _, door in all_doors.items() if door.room_name == "6a_17"]), + "6a_18a": Room("6a", "6a_18a", "Reflection A - Room 18a", [reg for _, reg in all_regions.items() if reg.room_name == "6a_18a"], [door for _, door in all_doors.items() if door.room_name == "6a_18a"]), + "6a_18b": Room("6a", "6a_18b", "Reflection A - Room 18b", [reg for _, reg in all_regions.items() if reg.room_name == "6a_18b"], [door for _, door in all_doors.items() if door.room_name == "6a_18b"]), + "6a_19": Room("6a", "6a_19", "Reflection A - Room 19", [reg for _, reg in all_regions.items() if reg.room_name == "6a_19"], [door for _, door in all_doors.items() if door.room_name == "6a_19"]), + "6a_20": Room("6a", "6a_20", "Reflection A - Room 20", [reg for _, reg in all_regions.items() if reg.room_name == "6a_20"], [door for _, door in all_doors.items() if door.room_name == "6a_20"]), + "6a_b-00": Room("6a", "6a_b-00", "Reflection A - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "6a_b-00"], [door for _, door in all_doors.items() if door.room_name == "6a_b-00"], "Reflection", "6a_b-00_west"), + "6a_b-00b": Room("6a", "6a_b-00b", "Reflection A - Room b-00b", [reg for _, reg in all_regions.items() if reg.room_name == "6a_b-00b"], [door for _, door in all_doors.items() if door.room_name == "6a_b-00b"]), + "6a_b-00c": Room("6a", "6a_b-00c", "Reflection A - Room b-00c", [reg for _, reg in all_regions.items() if reg.room_name == "6a_b-00c"], [door for _, door in all_doors.items() if door.room_name == "6a_b-00c"]), + "6a_b-01": Room("6a", "6a_b-01", "Reflection A - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "6a_b-01"], [door for _, door in all_doors.items() if door.room_name == "6a_b-01"]), + "6a_b-02": Room("6a", "6a_b-02", "Reflection A - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "6a_b-02"], [door for _, door in all_doors.items() if door.room_name == "6a_b-02"]), + "6a_b-02b": Room("6a", "6a_b-02b", "Reflection A - Room b-02b", [reg for _, reg in all_regions.items() if reg.room_name == "6a_b-02b"], [door for _, door in all_doors.items() if door.room_name == "6a_b-02b"]), + "6a_b-03": Room("6a", "6a_b-03", "Reflection A - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "6a_b-03"], [door for _, door in all_doors.items() if door.room_name == "6a_b-03"]), + "6a_boss-00": Room("6a", "6a_boss-00", "Reflection A - Room boss-00", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-00"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-00"], "Rock Bottom", "6a_boss-00_west"), + "6a_boss-01": Room("6a", "6a_boss-01", "Reflection A - Room boss-01", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-01"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-01"]), + "6a_boss-02": Room("6a", "6a_boss-02", "Reflection A - Room boss-02", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-02"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-02"]), + "6a_boss-03": Room("6a", "6a_boss-03", "Reflection A - Room boss-03", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-03"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-03"]), + "6a_boss-04": Room("6a", "6a_boss-04", "Reflection A - Room boss-04", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-04"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-04"]), + "6a_boss-05": Room("6a", "6a_boss-05", "Reflection A - Room boss-05", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-05"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-05"]), + "6a_boss-06": Room("6a", "6a_boss-06", "Reflection A - Room boss-06", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-06"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-06"]), + "6a_boss-07": Room("6a", "6a_boss-07", "Reflection A - Room boss-07", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-07"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-07"]), + "6a_boss-08": Room("6a", "6a_boss-08", "Reflection A - Room boss-08", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-08"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-08"]), + "6a_boss-09": Room("6a", "6a_boss-09", "Reflection A - Room boss-09", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-09"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-09"]), + "6a_boss-10": Room("6a", "6a_boss-10", "Reflection A - Room boss-10", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-10"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-10"]), + "6a_boss-11": Room("6a", "6a_boss-11", "Reflection A - Room boss-11", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-11"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-11"]), + "6a_boss-12": Room("6a", "6a_boss-12", "Reflection A - Room boss-12", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-12"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-12"]), + "6a_boss-13": Room("6a", "6a_boss-13", "Reflection A - Room boss-13", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-13"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-13"]), + "6a_boss-14": Room("6a", "6a_boss-14", "Reflection A - Room boss-14", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-14"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-14"]), + "6a_boss-15": Room("6a", "6a_boss-15", "Reflection A - Room boss-15", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-15"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-15"]), + "6a_boss-16": Room("6a", "6a_boss-16", "Reflection A - Room boss-16", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-16"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-16"]), + "6a_boss-17": Room("6a", "6a_boss-17", "Reflection A - Room boss-17", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-17"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-17"]), + "6a_boss-18": Room("6a", "6a_boss-18", "Reflection A - Room boss-18", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-18"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-18"]), + "6a_boss-19": Room("6a", "6a_boss-19", "Reflection A - Room boss-19", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-19"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-19"]), + "6a_boss-20": Room("6a", "6a_boss-20", "Reflection A - Room boss-20", [reg for _, reg in all_regions.items() if reg.room_name == "6a_boss-20"], [door for _, door in all_doors.items() if door.room_name == "6a_boss-20"]), + "6a_after-00": Room("6a", "6a_after-00", "Reflection A - Room after-00", [reg for _, reg in all_regions.items() if reg.room_name == "6a_after-00"], [door for _, door in all_doors.items() if door.room_name == "6a_after-00"], "Resolution", "6a_after-00_bottom"), + "6a_after-01": Room("6a", "6a_after-01", "Reflection A - Room after-01", [reg for _, reg in all_regions.items() if reg.room_name == "6a_after-01"], [door for _, door in all_doors.items() if door.room_name == "6a_after-01"]), + + "6b_a-00": Room("6b", "6b_a-00", "Reflection B - Room a-00", [reg for _, reg in all_regions.items() if reg.room_name == "6b_a-00"], [door for _, door in all_doors.items() if door.room_name == "6b_a-00"], "Start", "6b_a-00_bottom"), + "6b_a-01": Room("6b", "6b_a-01", "Reflection B - Room a-01", [reg for _, reg in all_regions.items() if reg.room_name == "6b_a-01"], [door for _, door in all_doors.items() if door.room_name == "6b_a-01"]), + "6b_a-02": Room("6b", "6b_a-02", "Reflection B - Room a-02", [reg for _, reg in all_regions.items() if reg.room_name == "6b_a-02"], [door for _, door in all_doors.items() if door.room_name == "6b_a-02"]), + "6b_a-03": Room("6b", "6b_a-03", "Reflection B - Room a-03", [reg for _, reg in all_regions.items() if reg.room_name == "6b_a-03"], [door for _, door in all_doors.items() if door.room_name == "6b_a-03"]), + "6b_a-04": Room("6b", "6b_a-04", "Reflection B - Room a-04", [reg for _, reg in all_regions.items() if reg.room_name == "6b_a-04"], [door for _, door in all_doors.items() if door.room_name == "6b_a-04"]), + "6b_a-05": Room("6b", "6b_a-05", "Reflection B - Room a-05", [reg for _, reg in all_regions.items() if reg.room_name == "6b_a-05"], [door for _, door in all_doors.items() if door.room_name == "6b_a-05"]), + "6b_a-06": Room("6b", "6b_a-06", "Reflection B - Room a-06", [reg for _, reg in all_regions.items() if reg.room_name == "6b_a-06"], [door for _, door in all_doors.items() if door.room_name == "6b_a-06"]), + "6b_b-00": Room("6b", "6b_b-00", "Reflection B - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "6b_b-00"], [door for _, door in all_doors.items() if door.room_name == "6b_b-00"], "Reflection", "6b_b-00_west"), + "6b_b-01": Room("6b", "6b_b-01", "Reflection B - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "6b_b-01"], [door for _, door in all_doors.items() if door.room_name == "6b_b-01"]), + "6b_b-02": Room("6b", "6b_b-02", "Reflection B - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "6b_b-02"], [door for _, door in all_doors.items() if door.room_name == "6b_b-02"]), + "6b_b-03": Room("6b", "6b_b-03", "Reflection B - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "6b_b-03"], [door for _, door in all_doors.items() if door.room_name == "6b_b-03"]), + "6b_b-04": Room("6b", "6b_b-04", "Reflection B - Room b-04", [reg for _, reg in all_regions.items() if reg.room_name == "6b_b-04"], [door for _, door in all_doors.items() if door.room_name == "6b_b-04"]), + "6b_b-05": Room("6b", "6b_b-05", "Reflection B - Room b-05", [reg for _, reg in all_regions.items() if reg.room_name == "6b_b-05"], [door for _, door in all_doors.items() if door.room_name == "6b_b-05"]), + "6b_b-06": Room("6b", "6b_b-06", "Reflection B - Room b-06", [reg for _, reg in all_regions.items() if reg.room_name == "6b_b-06"], [door for _, door in all_doors.items() if door.room_name == "6b_b-06"]), + "6b_b-07": Room("6b", "6b_b-07", "Reflection B - Room b-07", [reg for _, reg in all_regions.items() if reg.room_name == "6b_b-07"], [door for _, door in all_doors.items() if door.room_name == "6b_b-07"]), + "6b_b-08": Room("6b", "6b_b-08", "Reflection B - Room b-08", [reg for _, reg in all_regions.items() if reg.room_name == "6b_b-08"], [door for _, door in all_doors.items() if door.room_name == "6b_b-08"]), + "6b_b-10": Room("6b", "6b_b-10", "Reflection B - Room b-10", [reg for _, reg in all_regions.items() if reg.room_name == "6b_b-10"], [door for _, door in all_doors.items() if door.room_name == "6b_b-10"]), + "6b_c-00": Room("6b", "6b_c-00", "Reflection B - Room c-00", [reg for _, reg in all_regions.items() if reg.room_name == "6b_c-00"], [door for _, door in all_doors.items() if door.room_name == "6b_c-00"], "Rock Bottom", "6b_c-00_west"), + "6b_c-01": Room("6b", "6b_c-01", "Reflection B - Room c-01", [reg for _, reg in all_regions.items() if reg.room_name == "6b_c-01"], [door for _, door in all_doors.items() if door.room_name == "6b_c-01"]), + "6b_c-02": Room("6b", "6b_c-02", "Reflection B - Room c-02", [reg for _, reg in all_regions.items() if reg.room_name == "6b_c-02"], [door for _, door in all_doors.items() if door.room_name == "6b_c-02"]), + "6b_c-03": Room("6b", "6b_c-03", "Reflection B - Room c-03", [reg for _, reg in all_regions.items() if reg.room_name == "6b_c-03"], [door for _, door in all_doors.items() if door.room_name == "6b_c-03"]), + "6b_c-04": Room("6b", "6b_c-04", "Reflection B - Room c-04", [reg for _, reg in all_regions.items() if reg.room_name == "6b_c-04"], [door for _, door in all_doors.items() if door.room_name == "6b_c-04"]), + "6b_d-00": Room("6b", "6b_d-00", "Reflection B - Room d-00", [reg for _, reg in all_regions.items() if reg.room_name == "6b_d-00"], [door for _, door in all_doors.items() if door.room_name == "6b_d-00"], "Reprieve", "6b_d-00_west"), + "6b_d-01": Room("6b", "6b_d-01", "Reflection B - Room d-01", [reg for _, reg in all_regions.items() if reg.room_name == "6b_d-01"], [door for _, door in all_doors.items() if door.room_name == "6b_d-01"]), + "6b_d-02": Room("6b", "6b_d-02", "Reflection B - Room d-02", [reg for _, reg in all_regions.items() if reg.room_name == "6b_d-02"], [door for _, door in all_doors.items() if door.room_name == "6b_d-02"]), + "6b_d-03": Room("6b", "6b_d-03", "Reflection B - Room d-03", [reg for _, reg in all_regions.items() if reg.room_name == "6b_d-03"], [door for _, door in all_doors.items() if door.room_name == "6b_d-03"]), + "6b_d-04": Room("6b", "6b_d-04", "Reflection B - Room d-04", [reg for _, reg in all_regions.items() if reg.room_name == "6b_d-04"], [door for _, door in all_doors.items() if door.room_name == "6b_d-04"]), + "6b_d-05": Room("6b", "6b_d-05", "Reflection B - Room d-05", [reg for _, reg in all_regions.items() if reg.room_name == "6b_d-05"], [door for _, door in all_doors.items() if door.room_name == "6b_d-05"]), + + "6c_00": Room("6c", "6c_00", "Reflection C - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "6c_00"], [door for _, door in all_doors.items() if door.room_name == "6c_00"], "Start", "6c_00_west"), + "6c_01": Room("6c", "6c_01", "Reflection C - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "6c_01"], [door for _, door in all_doors.items() if door.room_name == "6c_01"]), + "6c_02": Room("6c", "6c_02", "Reflection C - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "6c_02"], [door for _, door in all_doors.items() if door.room_name == "6c_02"]), + + "7a_a-00": Room("7a", "7a_a-00", "The Summit A - Room a-00", [reg for _, reg in all_regions.items() if reg.room_name == "7a_a-00"], [door for _, door in all_doors.items() if door.room_name == "7a_a-00"], "Start", "7a_a-00_west"), + "7a_a-01": Room("7a", "7a_a-01", "The Summit A - Room a-01", [reg for _, reg in all_regions.items() if reg.room_name == "7a_a-01"], [door for _, door in all_doors.items() if door.room_name == "7a_a-01"]), + "7a_a-02": Room("7a", "7a_a-02", "The Summit A - Room a-02", [reg for _, reg in all_regions.items() if reg.room_name == "7a_a-02"], [door for _, door in all_doors.items() if door.room_name == "7a_a-02"]), + "7a_a-02b": Room("7a", "7a_a-02b", "The Summit A - Room a-02b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_a-02b"], [door for _, door in all_doors.items() if door.room_name == "7a_a-02b"]), + "7a_a-03": Room("7a", "7a_a-03", "The Summit A - Room a-03", [reg for _, reg in all_regions.items() if reg.room_name == "7a_a-03"], [door for _, door in all_doors.items() if door.room_name == "7a_a-03"]), + "7a_a-04": Room("7a", "7a_a-04", "The Summit A - Room a-04", [reg for _, reg in all_regions.items() if reg.room_name == "7a_a-04"], [door for _, door in all_doors.items() if door.room_name == "7a_a-04"]), + "7a_a-04b": Room("7a", "7a_a-04b", "The Summit A - Room a-04b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_a-04b"], [door for _, door in all_doors.items() if door.room_name == "7a_a-04b"]), + "7a_a-05": Room("7a", "7a_a-05", "The Summit A - Room a-05", [reg for _, reg in all_regions.items() if reg.room_name == "7a_a-05"], [door for _, door in all_doors.items() if door.room_name == "7a_a-05"]), + "7a_a-06": Room("7a", "7a_a-06", "The Summit A - Room a-06", [reg for _, reg in all_regions.items() if reg.room_name == "7a_a-06"], [door for _, door in all_doors.items() if door.room_name == "7a_a-06"]), + "7a_b-00": Room("7a", "7a_b-00", "The Summit A - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-00"], [door for _, door in all_doors.items() if door.room_name == "7a_b-00"], "500 M", "7a_b-00_bottom"), + "7a_b-01": Room("7a", "7a_b-01", "The Summit A - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-01"], [door for _, door in all_doors.items() if door.room_name == "7a_b-01"]), + "7a_b-02": Room("7a", "7a_b-02", "The Summit A - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-02"], [door for _, door in all_doors.items() if door.room_name == "7a_b-02"]), + "7a_b-02b": Room("7a", "7a_b-02b", "The Summit A - Room b-02b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-02b"], [door for _, door in all_doors.items() if door.room_name == "7a_b-02b"]), + "7a_b-02e": Room("7a", "7a_b-02e", "The Summit A - Room b-02e", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-02e"], [door for _, door in all_doors.items() if door.room_name == "7a_b-02e"]), + "7a_b-02c": Room("7a", "7a_b-02c", "The Summit A - Room b-02c", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-02c"], [door for _, door in all_doors.items() if door.room_name == "7a_b-02c"]), + "7a_b-02d": Room("7a", "7a_b-02d", "The Summit A - Room b-02d", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-02d"], [door for _, door in all_doors.items() if door.room_name == "7a_b-02d"]), + "7a_b-03": Room("7a", "7a_b-03", "The Summit A - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-03"], [door for _, door in all_doors.items() if door.room_name == "7a_b-03"]), + "7a_b-04": Room("7a", "7a_b-04", "The Summit A - Room b-04", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-04"], [door for _, door in all_doors.items() if door.room_name == "7a_b-04"]), + "7a_b-05": Room("7a", "7a_b-05", "The Summit A - Room b-05", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-05"], [door for _, door in all_doors.items() if door.room_name == "7a_b-05"]), + "7a_b-06": Room("7a", "7a_b-06", "The Summit A - Room b-06", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-06"], [door for _, door in all_doors.items() if door.room_name == "7a_b-06"]), + "7a_b-07": Room("7a", "7a_b-07", "The Summit A - Room b-07", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-07"], [door for _, door in all_doors.items() if door.room_name == "7a_b-07"]), + "7a_b-08": Room("7a", "7a_b-08", "The Summit A - Room b-08", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-08"], [door for _, door in all_doors.items() if door.room_name == "7a_b-08"]), + "7a_b-09": Room("7a", "7a_b-09", "The Summit A - Room b-09", [reg for _, reg in all_regions.items() if reg.room_name == "7a_b-09"], [door for _, door in all_doors.items() if door.room_name == "7a_b-09"]), + "7a_c-00": Room("7a", "7a_c-00", "The Summit A - Room c-00", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-00"], [door for _, door in all_doors.items() if door.room_name == "7a_c-00"], "1000 M", "7a_c-00_west"), + "7a_c-01": Room("7a", "7a_c-01", "The Summit A - Room c-01", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-01"], [door for _, door in all_doors.items() if door.room_name == "7a_c-01"]), + "7a_c-02": Room("7a", "7a_c-02", "The Summit A - Room c-02", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-02"], [door for _, door in all_doors.items() if door.room_name == "7a_c-02"]), + "7a_c-03": Room("7a", "7a_c-03", "The Summit A - Room c-03", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-03"], [door for _, door in all_doors.items() if door.room_name == "7a_c-03"]), + "7a_c-03b": Room("7a", "7a_c-03b", "The Summit A - Room c-03b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-03b"], [door for _, door in all_doors.items() if door.room_name == "7a_c-03b"]), + "7a_c-04": Room("7a", "7a_c-04", "The Summit A - Room c-04", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-04"], [door for _, door in all_doors.items() if door.room_name == "7a_c-04"]), + "7a_c-05": Room("7a", "7a_c-05", "The Summit A - Room c-05", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-05"], [door for _, door in all_doors.items() if door.room_name == "7a_c-05"]), + "7a_c-06": Room("7a", "7a_c-06", "The Summit A - Room c-06", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-06"], [door for _, door in all_doors.items() if door.room_name == "7a_c-06"]), + "7a_c-06b": Room("7a", "7a_c-06b", "The Summit A - Room c-06b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-06b"], [door for _, door in all_doors.items() if door.room_name == "7a_c-06b"]), + "7a_c-06c": Room("7a", "7a_c-06c", "The Summit A - Room c-06c", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-06c"], [door for _, door in all_doors.items() if door.room_name == "7a_c-06c"]), + "7a_c-07": Room("7a", "7a_c-07", "The Summit A - Room c-07", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-07"], [door for _, door in all_doors.items() if door.room_name == "7a_c-07"]), + "7a_c-07b": Room("7a", "7a_c-07b", "The Summit A - Room c-07b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-07b"], [door for _, door in all_doors.items() if door.room_name == "7a_c-07b"]), + "7a_c-08": Room("7a", "7a_c-08", "The Summit A - Room c-08", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-08"], [door for _, door in all_doors.items() if door.room_name == "7a_c-08"]), + "7a_c-09": Room("7a", "7a_c-09", "The Summit A - Room c-09", [reg for _, reg in all_regions.items() if reg.room_name == "7a_c-09"], [door for _, door in all_doors.items() if door.room_name == "7a_c-09"]), + "7a_d-00": Room("7a", "7a_d-00", "The Summit A - Room d-00", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-00"], [door for _, door in all_doors.items() if door.room_name == "7a_d-00"], "1500 M", "7a_d-00_bottom"), + "7a_d-01": Room("7a", "7a_d-01", "The Summit A - Room d-01", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-01"], [door for _, door in all_doors.items() if door.room_name == "7a_d-01"]), + "7a_d-01b": Room("7a", "7a_d-01b", "The Summit A - Room d-01b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-01b"], [door for _, door in all_doors.items() if door.room_name == "7a_d-01b"]), + "7a_d-01c": Room("7a", "7a_d-01c", "The Summit A - Room d-01c", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-01c"], [door for _, door in all_doors.items() if door.room_name == "7a_d-01c"]), + "7a_d-01d": Room("7a", "7a_d-01d", "The Summit A - Room d-01d", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-01d"], [door for _, door in all_doors.items() if door.room_name == "7a_d-01d"]), + "7a_d-02": Room("7a", "7a_d-02", "The Summit A - Room d-02", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-02"], [door for _, door in all_doors.items() if door.room_name == "7a_d-02"]), + "7a_d-03": Room("7a", "7a_d-03", "The Summit A - Room d-03", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-03"], [door for _, door in all_doors.items() if door.room_name == "7a_d-03"]), + "7a_d-03b": Room("7a", "7a_d-03b", "The Summit A - Room d-03b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-03b"], [door for _, door in all_doors.items() if door.room_name == "7a_d-03b"]), + "7a_d-04": Room("7a", "7a_d-04", "The Summit A - Room d-04", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-04"], [door for _, door in all_doors.items() if door.room_name == "7a_d-04"]), + "7a_d-05": Room("7a", "7a_d-05", "The Summit A - Room d-05", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-05"], [door for _, door in all_doors.items() if door.room_name == "7a_d-05"]), + "7a_d-05b": Room("7a", "7a_d-05b", "The Summit A - Room d-05b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-05b"], [door for _, door in all_doors.items() if door.room_name == "7a_d-05b"]), + "7a_d-06": Room("7a", "7a_d-06", "The Summit A - Room d-06", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-06"], [door for _, door in all_doors.items() if door.room_name == "7a_d-06"]), + "7a_d-07": Room("7a", "7a_d-07", "The Summit A - Room d-07", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-07"], [door for _, door in all_doors.items() if door.room_name == "7a_d-07"]), + "7a_d-08": Room("7a", "7a_d-08", "The Summit A - Room d-08", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-08"], [door for _, door in all_doors.items() if door.room_name == "7a_d-08"]), + "7a_d-09": Room("7a", "7a_d-09", "The Summit A - Room d-09", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-09"], [door for _, door in all_doors.items() if door.room_name == "7a_d-09"]), + "7a_d-10": Room("7a", "7a_d-10", "The Summit A - Room d-10", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-10"], [door for _, door in all_doors.items() if door.room_name == "7a_d-10"]), + "7a_d-10b": Room("7a", "7a_d-10b", "The Summit A - Room d-10b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-10b"], [door for _, door in all_doors.items() if door.room_name == "7a_d-10b"]), + "7a_d-11": Room("7a", "7a_d-11", "The Summit A - Room d-11", [reg for _, reg in all_regions.items() if reg.room_name == "7a_d-11"], [door for _, door in all_doors.items() if door.room_name == "7a_d-11"]), + "7a_e-00b": Room("7a", "7a_e-00b", "The Summit A - Room e-00b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-00b"], [door for _, door in all_doors.items() if door.room_name == "7a_e-00b"], "2000 M", "7a_e-00b_bottom"), + "7a_e-00": Room("7a", "7a_e-00", "The Summit A - Room e-00", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-00"], [door for _, door in all_doors.items() if door.room_name == "7a_e-00"]), + "7a_e-01": Room("7a", "7a_e-01", "The Summit A - Room e-01", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-01"], [door for _, door in all_doors.items() if door.room_name == "7a_e-01"]), + "7a_e-01b": Room("7a", "7a_e-01b", "The Summit A - Room e-01b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-01b"], [door for _, door in all_doors.items() if door.room_name == "7a_e-01b"]), + "7a_e-01c": Room("7a", "7a_e-01c", "The Summit A - Room e-01c", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-01c"], [door for _, door in all_doors.items() if door.room_name == "7a_e-01c"]), + "7a_e-02": Room("7a", "7a_e-02", "The Summit A - Room e-02", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-02"], [door for _, door in all_doors.items() if door.room_name == "7a_e-02"]), + "7a_e-03": Room("7a", "7a_e-03", "The Summit A - Room e-03", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-03"], [door for _, door in all_doors.items() if door.room_name == "7a_e-03"]), + "7a_e-04": Room("7a", "7a_e-04", "The Summit A - Room e-04", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-04"], [door for _, door in all_doors.items() if door.room_name == "7a_e-04"]), + "7a_e-05": Room("7a", "7a_e-05", "The Summit A - Room e-05", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-05"], [door for _, door in all_doors.items() if door.room_name == "7a_e-05"]), + "7a_e-06": Room("7a", "7a_e-06", "The Summit A - Room e-06", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-06"], [door for _, door in all_doors.items() if door.room_name == "7a_e-06"]), + "7a_e-07": Room("7a", "7a_e-07", "The Summit A - Room e-07", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-07"], [door for _, door in all_doors.items() if door.room_name == "7a_e-07"]), + "7a_e-08": Room("7a", "7a_e-08", "The Summit A - Room e-08", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-08"], [door for _, door in all_doors.items() if door.room_name == "7a_e-08"]), + "7a_e-09": Room("7a", "7a_e-09", "The Summit A - Room e-09", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-09"], [door for _, door in all_doors.items() if door.room_name == "7a_e-09"]), + "7a_e-11": Room("7a", "7a_e-11", "The Summit A - Room e-11", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-11"], [door for _, door in all_doors.items() if door.room_name == "7a_e-11"]), + "7a_e-12": Room("7a", "7a_e-12", "The Summit A - Room e-12", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-12"], [door for _, door in all_doors.items() if door.room_name == "7a_e-12"]), + "7a_e-10": Room("7a", "7a_e-10", "The Summit A - Room e-10", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-10"], [door for _, door in all_doors.items() if door.room_name == "7a_e-10"]), + "7a_e-10b": Room("7a", "7a_e-10b", "The Summit A - Room e-10b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-10b"], [door for _, door in all_doors.items() if door.room_name == "7a_e-10b"]), + "7a_e-13": Room("7a", "7a_e-13", "The Summit A - Room e-13", [reg for _, reg in all_regions.items() if reg.room_name == "7a_e-13"], [door for _, door in all_doors.items() if door.room_name == "7a_e-13"]), + "7a_f-00": Room("7a", "7a_f-00", "The Summit A - Room f-00", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-00"], [door for _, door in all_doors.items() if door.room_name == "7a_f-00"], "2500 M", "7a_f-00_south"), + "7a_f-01": Room("7a", "7a_f-01", "The Summit A - Room f-01", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-01"], [door for _, door in all_doors.items() if door.room_name == "7a_f-01"]), + "7a_f-02": Room("7a", "7a_f-02", "The Summit A - Room f-02", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-02"], [door for _, door in all_doors.items() if door.room_name == "7a_f-02"]), + "7a_f-02b": Room("7a", "7a_f-02b", "The Summit A - Room f-02b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-02b"], [door for _, door in all_doors.items() if door.room_name == "7a_f-02b"]), + "7a_f-04": Room("7a", "7a_f-04", "The Summit A - Room f-04", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-04"], [door for _, door in all_doors.items() if door.room_name == "7a_f-04"]), + "7a_f-03": Room("7a", "7a_f-03", "The Summit A - Room f-03", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-03"], [door for _, door in all_doors.items() if door.room_name == "7a_f-03"]), + "7a_f-05": Room("7a", "7a_f-05", "The Summit A - Room f-05", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-05"], [door for _, door in all_doors.items() if door.room_name == "7a_f-05"]), + "7a_f-06": Room("7a", "7a_f-06", "The Summit A - Room f-06", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-06"], [door for _, door in all_doors.items() if door.room_name == "7a_f-06"]), + "7a_f-07": Room("7a", "7a_f-07", "The Summit A - Room f-07", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-07"], [door for _, door in all_doors.items() if door.room_name == "7a_f-07"]), + "7a_f-08": Room("7a", "7a_f-08", "The Summit A - Room f-08", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-08"], [door for _, door in all_doors.items() if door.room_name == "7a_f-08"]), + "7a_f-08b": Room("7a", "7a_f-08b", "The Summit A - Room f-08b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-08b"], [door for _, door in all_doors.items() if door.room_name == "7a_f-08b"]), + "7a_f-08d": Room("7a", "7a_f-08d", "The Summit A - Room f-08d", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-08d"], [door for _, door in all_doors.items() if door.room_name == "7a_f-08d"]), + "7a_f-08c": Room("7a", "7a_f-08c", "The Summit A - Room f-08c", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-08c"], [door for _, door in all_doors.items() if door.room_name == "7a_f-08c"]), + "7a_f-09": Room("7a", "7a_f-09", "The Summit A - Room f-09", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-09"], [door for _, door in all_doors.items() if door.room_name == "7a_f-09"]), + "7a_f-10": Room("7a", "7a_f-10", "The Summit A - Room f-10", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-10"], [door for _, door in all_doors.items() if door.room_name == "7a_f-10"]), + "7a_f-10b": Room("7a", "7a_f-10b", "The Summit A - Room f-10b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-10b"], [door for _, door in all_doors.items() if door.room_name == "7a_f-10b"]), + "7a_f-11": Room("7a", "7a_f-11", "The Summit A - Room f-11", [reg for _, reg in all_regions.items() if reg.room_name == "7a_f-11"], [door for _, door in all_doors.items() if door.room_name == "7a_f-11"]), + "7a_g-00": Room("7a", "7a_g-00", "The Summit A - Room g-00", [reg for _, reg in all_regions.items() if reg.room_name == "7a_g-00"], [door for _, door in all_doors.items() if door.room_name == "7a_g-00"], "3000 M", "7a_g-00_bottom"), + "7a_g-00b": Room("7a", "7a_g-00b", "The Summit A - Room g-00b", [reg for _, reg in all_regions.items() if reg.room_name == "7a_g-00b"], [door for _, door in all_doors.items() if door.room_name == "7a_g-00b"]), + "7a_g-01": Room("7a", "7a_g-01", "The Summit A - Room g-01", [reg for _, reg in all_regions.items() if reg.room_name == "7a_g-01"], [door for _, door in all_doors.items() if door.room_name == "7a_g-01"]), + "7a_g-02": Room("7a", "7a_g-02", "The Summit A - Room g-02", [reg for _, reg in all_regions.items() if reg.room_name == "7a_g-02"], [door for _, door in all_doors.items() if door.room_name == "7a_g-02"]), + "7a_g-03": Room("7a", "7a_g-03", "The Summit A - Room g-03", [reg for _, reg in all_regions.items() if reg.room_name == "7a_g-03"], [door for _, door in all_doors.items() if door.room_name == "7a_g-03"]), + + "7b_a-00": Room("7b", "7b_a-00", "The Summit B - Room a-00", [reg for _, reg in all_regions.items() if reg.room_name == "7b_a-00"], [door for _, door in all_doors.items() if door.room_name == "7b_a-00"], "Start", "7b_a-00_west"), + "7b_a-01": Room("7b", "7b_a-01", "The Summit B - Room a-01", [reg for _, reg in all_regions.items() if reg.room_name == "7b_a-01"], [door for _, door in all_doors.items() if door.room_name == "7b_a-01"]), + "7b_a-02": Room("7b", "7b_a-02", "The Summit B - Room a-02", [reg for _, reg in all_regions.items() if reg.room_name == "7b_a-02"], [door for _, door in all_doors.items() if door.room_name == "7b_a-02"]), + "7b_a-03": Room("7b", "7b_a-03", "The Summit B - Room a-03", [reg for _, reg in all_regions.items() if reg.room_name == "7b_a-03"], [door for _, door in all_doors.items() if door.room_name == "7b_a-03"]), + "7b_b-00": Room("7b", "7b_b-00", "The Summit B - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "7b_b-00"], [door for _, door in all_doors.items() if door.room_name == "7b_b-00"], "500 M", "7b_b-00_bottom"), + "7b_b-01": Room("7b", "7b_b-01", "The Summit B - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "7b_b-01"], [door for _, door in all_doors.items() if door.room_name == "7b_b-01"]), + "7b_b-02": Room("7b", "7b_b-02", "The Summit B - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "7b_b-02"], [door for _, door in all_doors.items() if door.room_name == "7b_b-02"]), + "7b_b-03": Room("7b", "7b_b-03", "The Summit B - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "7b_b-03"], [door for _, door in all_doors.items() if door.room_name == "7b_b-03"]), + "7b_c-01": Room("7b", "7b_c-01", "The Summit B - Room c-01", [reg for _, reg in all_regions.items() if reg.room_name == "7b_c-01"], [door for _, door in all_doors.items() if door.room_name == "7b_c-01"], "1000 M", "7b_c-01_west"), + "7b_c-00": Room("7b", "7b_c-00", "The Summit B - Room c-00", [reg for _, reg in all_regions.items() if reg.room_name == "7b_c-00"], [door for _, door in all_doors.items() if door.room_name == "7b_c-00"]), + "7b_c-02": Room("7b", "7b_c-02", "The Summit B - Room c-02", [reg for _, reg in all_regions.items() if reg.room_name == "7b_c-02"], [door for _, door in all_doors.items() if door.room_name == "7b_c-02"]), + "7b_c-03": Room("7b", "7b_c-03", "The Summit B - Room c-03", [reg for _, reg in all_regions.items() if reg.room_name == "7b_c-03"], [door for _, door in all_doors.items() if door.room_name == "7b_c-03"]), + "7b_d-00": Room("7b", "7b_d-00", "The Summit B - Room d-00", [reg for _, reg in all_regions.items() if reg.room_name == "7b_d-00"], [door for _, door in all_doors.items() if door.room_name == "7b_d-00"], "1500 M", "7b_d-00_west"), + "7b_d-01": Room("7b", "7b_d-01", "The Summit B - Room d-01", [reg for _, reg in all_regions.items() if reg.room_name == "7b_d-01"], [door for _, door in all_doors.items() if door.room_name == "7b_d-01"]), + "7b_d-02": Room("7b", "7b_d-02", "The Summit B - Room d-02", [reg for _, reg in all_regions.items() if reg.room_name == "7b_d-02"], [door for _, door in all_doors.items() if door.room_name == "7b_d-02"]), + "7b_d-03": Room("7b", "7b_d-03", "The Summit B - Room d-03", [reg for _, reg in all_regions.items() if reg.room_name == "7b_d-03"], [door for _, door in all_doors.items() if door.room_name == "7b_d-03"]), + "7b_e-00": Room("7b", "7b_e-00", "The Summit B - Room e-00", [reg for _, reg in all_regions.items() if reg.room_name == "7b_e-00"], [door for _, door in all_doors.items() if door.room_name == "7b_e-00"], "2000 M", "7b_e-00_west"), + "7b_e-01": Room("7b", "7b_e-01", "The Summit B - Room e-01", [reg for _, reg in all_regions.items() if reg.room_name == "7b_e-01"], [door for _, door in all_doors.items() if door.room_name == "7b_e-01"]), + "7b_e-02": Room("7b", "7b_e-02", "The Summit B - Room e-02", [reg for _, reg in all_regions.items() if reg.room_name == "7b_e-02"], [door for _, door in all_doors.items() if door.room_name == "7b_e-02"]), + "7b_e-03": Room("7b", "7b_e-03", "The Summit B - Room e-03", [reg for _, reg in all_regions.items() if reg.room_name == "7b_e-03"], [door for _, door in all_doors.items() if door.room_name == "7b_e-03"]), + "7b_f-00": Room("7b", "7b_f-00", "The Summit B - Room f-00", [reg for _, reg in all_regions.items() if reg.room_name == "7b_f-00"], [door for _, door in all_doors.items() if door.room_name == "7b_f-00"], "2500 M", "7b_f-00_west"), + "7b_f-01": Room("7b", "7b_f-01", "The Summit B - Room f-01", [reg for _, reg in all_regions.items() if reg.room_name == "7b_f-01"], [door for _, door in all_doors.items() if door.room_name == "7b_f-01"]), + "7b_f-02": Room("7b", "7b_f-02", "The Summit B - Room f-02", [reg for _, reg in all_regions.items() if reg.room_name == "7b_f-02"], [door for _, door in all_doors.items() if door.room_name == "7b_f-02"]), + "7b_f-03": Room("7b", "7b_f-03", "The Summit B - Room f-03", [reg for _, reg in all_regions.items() if reg.room_name == "7b_f-03"], [door for _, door in all_doors.items() if door.room_name == "7b_f-03"]), + "7b_g-00": Room("7b", "7b_g-00", "The Summit B - Room g-00", [reg for _, reg in all_regions.items() if reg.room_name == "7b_g-00"], [door for _, door in all_doors.items() if door.room_name == "7b_g-00"], "3000 M", "7b_g-00_bottom"), + "7b_g-01": Room("7b", "7b_g-01", "The Summit B - Room g-01", [reg for _, reg in all_regions.items() if reg.room_name == "7b_g-01"], [door for _, door in all_doors.items() if door.room_name == "7b_g-01"]), + "7b_g-02": Room("7b", "7b_g-02", "The Summit B - Room g-02", [reg for _, reg in all_regions.items() if reg.room_name == "7b_g-02"], [door for _, door in all_doors.items() if door.room_name == "7b_g-02"]), + "7b_g-03": Room("7b", "7b_g-03", "The Summit B - Room g-03", [reg for _, reg in all_regions.items() if reg.room_name == "7b_g-03"], [door for _, door in all_doors.items() if door.room_name == "7b_g-03"]), + + "7c_01": Room("7c", "7c_01", "The Summit C - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "7c_01"], [door for _, door in all_doors.items() if door.room_name == "7c_01"], "Start", "7c_01_west"), + "7c_02": Room("7c", "7c_02", "The Summit C - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "7c_02"], [door for _, door in all_doors.items() if door.room_name == "7c_02"]), + "7c_03": Room("7c", "7c_03", "The Summit C - Room 03", [reg for _, reg in all_regions.items() if reg.room_name == "7c_03"], [door for _, door in all_doors.items() if door.room_name == "7c_03"]), + + "8a_outside": Room("8a", "8a_outside", "Epilogue - Room outside", [reg for _, reg in all_regions.items() if reg.room_name == "8a_outside"], [door for _, door in all_doors.items() if door.room_name == "8a_outside"], "Start", "8a_outside_east"), + "8a_bridge": Room("8a", "8a_bridge", "Epilogue - Room bridge", [reg for _, reg in all_regions.items() if reg.room_name == "8a_bridge"], [door for _, door in all_doors.items() if door.room_name == "8a_bridge"]), + "8a_secret": Room("8a", "8a_secret", "Epilogue - Room secret", [reg for _, reg in all_regions.items() if reg.room_name == "8a_secret"], [door for _, door in all_doors.items() if door.room_name == "8a_secret"]), + + "9a_00": Room("9a", "9a_00", "Core A - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "9a_00"], [door for _, door in all_doors.items() if door.room_name == "9a_00"], "Start", "9a_00_west"), + "9a_0x": Room("9a", "9a_0x", "Core A - Room 0x", [reg for _, reg in all_regions.items() if reg.room_name == "9a_0x"], [door for _, door in all_doors.items() if door.room_name == "9a_0x"]), + "9a_01": Room("9a", "9a_01", "Core A - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "9a_01"], [door for _, door in all_doors.items() if door.room_name == "9a_01"]), + "9a_02": Room("9a", "9a_02", "Core A - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "9a_02"], [door for _, door in all_doors.items() if door.room_name == "9a_02"]), + "9a_a-00": Room("9a", "9a_a-00", "Core A - Room a-00", [reg for _, reg in all_regions.items() if reg.room_name == "9a_a-00"], [door for _, door in all_doors.items() if door.room_name == "9a_a-00"], "Into the Core", "9a_a-00_west"), + "9a_a-01": Room("9a", "9a_a-01", "Core A - Room a-01", [reg for _, reg in all_regions.items() if reg.room_name == "9a_a-01"], [door for _, door in all_doors.items() if door.room_name == "9a_a-01"]), + "9a_a-02": Room("9a", "9a_a-02", "Core A - Room a-02", [reg for _, reg in all_regions.items() if reg.room_name == "9a_a-02"], [door for _, door in all_doors.items() if door.room_name == "9a_a-02"]), + "9a_a-03": Room("9a", "9a_a-03", "Core A - Room a-03", [reg for _, reg in all_regions.items() if reg.room_name == "9a_a-03"], [door for _, door in all_doors.items() if door.room_name == "9a_a-03"]), + "9a_b-00": Room("9a", "9a_b-00", "Core A - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "9a_b-00"], [door for _, door in all_doors.items() if door.room_name == "9a_b-00"]), + "9a_b-01": Room("9a", "9a_b-01", "Core A - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "9a_b-01"], [door for _, door in all_doors.items() if door.room_name == "9a_b-01"]), + "9a_b-02": Room("9a", "9a_b-02", "Core A - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "9a_b-02"], [door for _, door in all_doors.items() if door.room_name == "9a_b-02"]), + "9a_b-03": Room("9a", "9a_b-03", "Core A - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "9a_b-03"], [door for _, door in all_doors.items() if door.room_name == "9a_b-03"]), + "9a_b-04": Room("9a", "9a_b-04", "Core A - Room b-04", [reg for _, reg in all_regions.items() if reg.room_name == "9a_b-04"], [door for _, door in all_doors.items() if door.room_name == "9a_b-04"]), + "9a_b-05": Room("9a", "9a_b-05", "Core A - Room b-05", [reg for _, reg in all_regions.items() if reg.room_name == "9a_b-05"], [door for _, door in all_doors.items() if door.room_name == "9a_b-05"]), + "9a_b-06": Room("9a", "9a_b-06", "Core A - Room b-06", [reg for _, reg in all_regions.items() if reg.room_name == "9a_b-06"], [door for _, door in all_doors.items() if door.room_name == "9a_b-06"]), + "9a_b-07b": Room("9a", "9a_b-07b", "Core A - Room b-07b", [reg for _, reg in all_regions.items() if reg.room_name == "9a_b-07b"], [door for _, door in all_doors.items() if door.room_name == "9a_b-07b"]), + "9a_b-07": Room("9a", "9a_b-07", "Core A - Room b-07", [reg for _, reg in all_regions.items() if reg.room_name == "9a_b-07"], [door for _, door in all_doors.items() if door.room_name == "9a_b-07"]), + "9a_c-00": Room("9a", "9a_c-00", "Core A - Room c-00", [reg for _, reg in all_regions.items() if reg.room_name == "9a_c-00"], [door for _, door in all_doors.items() if door.room_name == "9a_c-00"], "Hot and Cold", "9a_c-00_west"), + "9a_c-00b": Room("9a", "9a_c-00b", "Core A - Room c-00b", [reg for _, reg in all_regions.items() if reg.room_name == "9a_c-00b"], [door for _, door in all_doors.items() if door.room_name == "9a_c-00b"]), + "9a_c-01": Room("9a", "9a_c-01", "Core A - Room c-01", [reg for _, reg in all_regions.items() if reg.room_name == "9a_c-01"], [door for _, door in all_doors.items() if door.room_name == "9a_c-01"]), + "9a_c-02": Room("9a", "9a_c-02", "Core A - Room c-02", [reg for _, reg in all_regions.items() if reg.room_name == "9a_c-02"], [door for _, door in all_doors.items() if door.room_name == "9a_c-02"]), + "9a_c-03": Room("9a", "9a_c-03", "Core A - Room c-03", [reg for _, reg in all_regions.items() if reg.room_name == "9a_c-03"], [door for _, door in all_doors.items() if door.room_name == "9a_c-03"]), + "9a_c-03b": Room("9a", "9a_c-03b", "Core A - Room c-03b", [reg for _, reg in all_regions.items() if reg.room_name == "9a_c-03b"], [door for _, door in all_doors.items() if door.room_name == "9a_c-03b"]), + "9a_c-04": Room("9a", "9a_c-04", "Core A - Room c-04", [reg for _, reg in all_regions.items() if reg.room_name == "9a_c-04"], [door for _, door in all_doors.items() if door.room_name == "9a_c-04"]), + "9a_d-00": Room("9a", "9a_d-00", "Core A - Room d-00", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-00"], [door for _, door in all_doors.items() if door.room_name == "9a_d-00"], "Heart of the Mountain", "9a_d-00_bottom"), + "9a_d-01": Room("9a", "9a_d-01", "Core A - Room d-01", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-01"], [door for _, door in all_doors.items() if door.room_name == "9a_d-01"]), + "9a_d-02": Room("9a", "9a_d-02", "Core A - Room d-02", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-02"], [door for _, door in all_doors.items() if door.room_name == "9a_d-02"]), + "9a_d-03": Room("9a", "9a_d-03", "Core A - Room d-03", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-03"], [door for _, door in all_doors.items() if door.room_name == "9a_d-03"]), + "9a_d-04": Room("9a", "9a_d-04", "Core A - Room d-04", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-04"], [door for _, door in all_doors.items() if door.room_name == "9a_d-04"]), + "9a_d-05": Room("9a", "9a_d-05", "Core A - Room d-05", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-05"], [door for _, door in all_doors.items() if door.room_name == "9a_d-05"]), + "9a_d-06": Room("9a", "9a_d-06", "Core A - Room d-06", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-06"], [door for _, door in all_doors.items() if door.room_name == "9a_d-06"]), + "9a_d-07": Room("9a", "9a_d-07", "Core A - Room d-07", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-07"], [door for _, door in all_doors.items() if door.room_name == "9a_d-07"]), + "9a_d-08": Room("9a", "9a_d-08", "Core A - Room d-08", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-08"], [door for _, door in all_doors.items() if door.room_name == "9a_d-08"]), + "9a_d-09": Room("9a", "9a_d-09", "Core A - Room d-09", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-09"], [door for _, door in all_doors.items() if door.room_name == "9a_d-09"]), + "9a_d-10": Room("9a", "9a_d-10", "Core A - Room d-10", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-10"], [door for _, door in all_doors.items() if door.room_name == "9a_d-10"]), + "9a_d-10b": Room("9a", "9a_d-10b", "Core A - Room d-10b", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-10b"], [door for _, door in all_doors.items() if door.room_name == "9a_d-10b"]), + "9a_d-10c": Room("9a", "9a_d-10c", "Core A - Room d-10c", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-10c"], [door for _, door in all_doors.items() if door.room_name == "9a_d-10c"]), + "9a_d-11": Room("9a", "9a_d-11", "Core A - Room d-11", [reg for _, reg in all_regions.items() if reg.room_name == "9a_d-11"], [door for _, door in all_doors.items() if door.room_name == "9a_d-11"]), + "9a_space": Room("9a", "9a_space", "Core A - Room space", [reg for _, reg in all_regions.items() if reg.room_name == "9a_space"], [door for _, door in all_doors.items() if door.room_name == "9a_space"]), + + "9b_00": Room("9b", "9b_00", "Core B - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "9b_00"], [door for _, door in all_doors.items() if door.room_name == "9b_00"], "Start", "9b_00_east"), + "9b_01": Room("9b", "9b_01", "Core B - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "9b_01"], [door for _, door in all_doors.items() if door.room_name == "9b_01"]), + "9b_a-00": Room("9b", "9b_a-00", "Core B - Room a-00", [reg for _, reg in all_regions.items() if reg.room_name == "9b_a-00"], [door for _, door in all_doors.items() if door.room_name == "9b_a-00"], "Into the Core", "9b_a-00_west"), + "9b_a-01": Room("9b", "9b_a-01", "Core B - Room a-01", [reg for _, reg in all_regions.items() if reg.room_name == "9b_a-01"], [door for _, door in all_doors.items() if door.room_name == "9b_a-01"]), + "9b_a-02": Room("9b", "9b_a-02", "Core B - Room a-02", [reg for _, reg in all_regions.items() if reg.room_name == "9b_a-02"], [door for _, door in all_doors.items() if door.room_name == "9b_a-02"]), + "9b_a-03": Room("9b", "9b_a-03", "Core B - Room a-03", [reg for _, reg in all_regions.items() if reg.room_name == "9b_a-03"], [door for _, door in all_doors.items() if door.room_name == "9b_a-03"]), + "9b_a-04": Room("9b", "9b_a-04", "Core B - Room a-04", [reg for _, reg in all_regions.items() if reg.room_name == "9b_a-04"], [door for _, door in all_doors.items() if door.room_name == "9b_a-04"]), + "9b_a-05": Room("9b", "9b_a-05", "Core B - Room a-05", [reg for _, reg in all_regions.items() if reg.room_name == "9b_a-05"], [door for _, door in all_doors.items() if door.room_name == "9b_a-05"]), + "9b_b-00": Room("9b", "9b_b-00", "Core B - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "9b_b-00"], [door for _, door in all_doors.items() if door.room_name == "9b_b-00"], "Burning or Freezing", "9b_b-00_west"), + "9b_b-01": Room("9b", "9b_b-01", "Core B - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "9b_b-01"], [door for _, door in all_doors.items() if door.room_name == "9b_b-01"]), + "9b_b-02": Room("9b", "9b_b-02", "Core B - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "9b_b-02"], [door for _, door in all_doors.items() if door.room_name == "9b_b-02"]), + "9b_b-03": Room("9b", "9b_b-03", "Core B - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "9b_b-03"], [door for _, door in all_doors.items() if door.room_name == "9b_b-03"]), + "9b_b-04": Room("9b", "9b_b-04", "Core B - Room b-04", [reg for _, reg in all_regions.items() if reg.room_name == "9b_b-04"], [door for _, door in all_doors.items() if door.room_name == "9b_b-04"]), + "9b_b-05": Room("9b", "9b_b-05", "Core B - Room b-05", [reg for _, reg in all_regions.items() if reg.room_name == "9b_b-05"], [door for _, door in all_doors.items() if door.room_name == "9b_b-05"]), + "9b_c-01": Room("9b", "9b_c-01", "Core B - Room c-01", [reg for _, reg in all_regions.items() if reg.room_name == "9b_c-01"], [door for _, door in all_doors.items() if door.room_name == "9b_c-01"], "Heartbeat", "9b_c-01_bottom"), + "9b_c-02": Room("9b", "9b_c-02", "Core B - Room c-02", [reg for _, reg in all_regions.items() if reg.room_name == "9b_c-02"], [door for _, door in all_doors.items() if door.room_name == "9b_c-02"]), + "9b_c-03": Room("9b", "9b_c-03", "Core B - Room c-03", [reg for _, reg in all_regions.items() if reg.room_name == "9b_c-03"], [door for _, door in all_doors.items() if door.room_name == "9b_c-03"]), + "9b_c-04": Room("9b", "9b_c-04", "Core B - Room c-04", [reg for _, reg in all_regions.items() if reg.room_name == "9b_c-04"], [door for _, door in all_doors.items() if door.room_name == "9b_c-04"]), + "9b_c-05": Room("9b", "9b_c-05", "Core B - Room c-05", [reg for _, reg in all_regions.items() if reg.room_name == "9b_c-05"], [door for _, door in all_doors.items() if door.room_name == "9b_c-05"]), + "9b_c-06": Room("9b", "9b_c-06", "Core B - Room c-06", [reg for _, reg in all_regions.items() if reg.room_name == "9b_c-06"], [door for _, door in all_doors.items() if door.room_name == "9b_c-06"]), + "9b_c-08": Room("9b", "9b_c-08", "Core B - Room c-08", [reg for _, reg in all_regions.items() if reg.room_name == "9b_c-08"], [door for _, door in all_doors.items() if door.room_name == "9b_c-08"]), + "9b_c-07": Room("9b", "9b_c-07", "Core B - Room c-07", [reg for _, reg in all_regions.items() if reg.room_name == "9b_c-07"], [door for _, door in all_doors.items() if door.room_name == "9b_c-07"]), + "9b_space": Room("9b", "9b_space", "Core B - Room space", [reg for _, reg in all_regions.items() if reg.room_name == "9b_space"], [door for _, door in all_doors.items() if door.room_name == "9b_space"]), + + "9c_intro": Room("9c", "9c_intro", "Core C - Room intro", [reg for _, reg in all_regions.items() if reg.room_name == "9c_intro"], [door for _, door in all_doors.items() if door.room_name == "9c_intro"], "Start", "9c_intro_west"), + "9c_00": Room("9c", "9c_00", "Core C - Room 00", [reg for _, reg in all_regions.items() if reg.room_name == "9c_00"], [door for _, door in all_doors.items() if door.room_name == "9c_00"]), + "9c_01": Room("9c", "9c_01", "Core C - Room 01", [reg for _, reg in all_regions.items() if reg.room_name == "9c_01"], [door for _, door in all_doors.items() if door.room_name == "9c_01"]), + "9c_02": Room("9c", "9c_02", "Core C - Room 02", [reg for _, reg in all_regions.items() if reg.room_name == "9c_02"], [door for _, door in all_doors.items() if door.room_name == "9c_02"]), + + "10a_intro-00-past": Room("10a", "10a_intro-00-past", "Farewell - Room intro-00-past", [reg for _, reg in all_regions.items() if reg.room_name == "10a_intro-00-past"], [door for _, door in all_doors.items() if door.room_name == "10a_intro-00-past"], "Start", "10a_intro-00-past_west"), + "10a_intro-01-future": Room("10a", "10a_intro-01-future", "Farewell - Room intro-01-future", [reg for _, reg in all_regions.items() if reg.room_name == "10a_intro-01-future"], [door for _, door in all_doors.items() if door.room_name == "10a_intro-01-future"]), + "10a_intro-02-launch": Room("10a", "10a_intro-02-launch", "Farewell - Room intro-02-launch", [reg for _, reg in all_regions.items() if reg.room_name == "10a_intro-02-launch"], [door for _, door in all_doors.items() if door.room_name == "10a_intro-02-launch"]), + "10a_intro-03-space": Room("10a", "10a_intro-03-space", "Farewell - Room intro-03-space", [reg for _, reg in all_regions.items() if reg.room_name == "10a_intro-03-space"], [door for _, door in all_doors.items() if door.room_name == "10a_intro-03-space"]), + "10a_a-00": Room("10a", "10a_a-00", "Farewell - Room a-00", [reg for _, reg in all_regions.items() if reg.room_name == "10a_a-00"], [door for _, door in all_doors.items() if door.room_name == "10a_a-00"], "Singular", "10a_a-00_west"), + "10a_a-01": Room("10a", "10a_a-01", "Farewell - Room a-01", [reg for _, reg in all_regions.items() if reg.room_name == "10a_a-01"], [door for _, door in all_doors.items() if door.room_name == "10a_a-01"]), + "10a_a-02": Room("10a", "10a_a-02", "Farewell - Room a-02", [reg for _, reg in all_regions.items() if reg.room_name == "10a_a-02"], [door for _, door in all_doors.items() if door.room_name == "10a_a-02"]), + "10a_a-03": Room("10a", "10a_a-03", "Farewell - Room a-03", [reg for _, reg in all_regions.items() if reg.room_name == "10a_a-03"], [door for _, door in all_doors.items() if door.room_name == "10a_a-03"]), + "10a_a-04": Room("10a", "10a_a-04", "Farewell - Room a-04", [reg for _, reg in all_regions.items() if reg.room_name == "10a_a-04"], [door for _, door in all_doors.items() if door.room_name == "10a_a-04"]), + "10a_a-05": Room("10a", "10a_a-05", "Farewell - Room a-05", [reg for _, reg in all_regions.items() if reg.room_name == "10a_a-05"], [door for _, door in all_doors.items() if door.room_name == "10a_a-05"]), + "10a_b-00": Room("10a", "10a_b-00", "Farewell - Room b-00", [reg for _, reg in all_regions.items() if reg.room_name == "10a_b-00"], [door for _, door in all_doors.items() if door.room_name == "10a_b-00"]), + "10a_b-01": Room("10a", "10a_b-01", "Farewell - Room b-01", [reg for _, reg in all_regions.items() if reg.room_name == "10a_b-01"], [door for _, door in all_doors.items() if door.room_name == "10a_b-01"]), + "10a_b-02": Room("10a", "10a_b-02", "Farewell - Room b-02", [reg for _, reg in all_regions.items() if reg.room_name == "10a_b-02"], [door for _, door in all_doors.items() if door.room_name == "10a_b-02"]), + "10a_b-03": Room("10a", "10a_b-03", "Farewell - Room b-03", [reg for _, reg in all_regions.items() if reg.room_name == "10a_b-03"], [door for _, door in all_doors.items() if door.room_name == "10a_b-03"]), + "10a_b-04": Room("10a", "10a_b-04", "Farewell - Room b-04", [reg for _, reg in all_regions.items() if reg.room_name == "10a_b-04"], [door for _, door in all_doors.items() if door.room_name == "10a_b-04"]), + "10a_b-05": Room("10a", "10a_b-05", "Farewell - Room b-05", [reg for _, reg in all_regions.items() if reg.room_name == "10a_b-05"], [door for _, door in all_doors.items() if door.room_name == "10a_b-05"]), + "10a_b-06": Room("10a", "10a_b-06", "Farewell - Room b-06", [reg for _, reg in all_regions.items() if reg.room_name == "10a_b-06"], [door for _, door in all_doors.items() if door.room_name == "10a_b-06"]), + "10a_b-07": Room("10a", "10a_b-07", "Farewell - Room b-07", [reg for _, reg in all_regions.items() if reg.room_name == "10a_b-07"], [door for _, door in all_doors.items() if door.room_name == "10a_b-07"]), + "10a_c-00": Room("10a", "10a_c-00", "Farewell - Room c-00", [reg for _, reg in all_regions.items() if reg.room_name == "10a_c-00"], [door for _, door in all_doors.items() if door.room_name == "10a_c-00"], "Power Source", "10a_c-00_west"), + "10a_c-00b": Room("10a", "10a_c-00b", "Farewell - Room c-00b", [reg for _, reg in all_regions.items() if reg.room_name == "10a_c-00b"], [door for _, door in all_doors.items() if door.room_name == "10a_c-00b"]), + "10a_c-01": Room("10a", "10a_c-01", "Farewell - Room c-01", [reg for _, reg in all_regions.items() if reg.room_name == "10a_c-01"], [door for _, door in all_doors.items() if door.room_name == "10a_c-01"]), + "10a_c-02": Room("10a", "10a_c-02", "Farewell - Room c-02", [reg for _, reg in all_regions.items() if reg.room_name == "10a_c-02"], [door for _, door in all_doors.items() if door.room_name == "10a_c-02"]), + "10a_c-alt-00": Room("10a", "10a_c-alt-00", "Farewell - Room c-alt-00", [reg for _, reg in all_regions.items() if reg.room_name == "10a_c-alt-00"], [door for _, door in all_doors.items() if door.room_name == "10a_c-alt-00"]), + "10a_c-alt-01": Room("10a", "10a_c-alt-01", "Farewell - Room c-alt-01", [reg for _, reg in all_regions.items() if reg.room_name == "10a_c-alt-01"], [door for _, door in all_doors.items() if door.room_name == "10a_c-alt-01"]), + "10a_c-03": Room("10a", "10a_c-03", "Farewell - Room c-03", [reg for _, reg in all_regions.items() if reg.room_name == "10a_c-03"], [door for _, door in all_doors.items() if door.room_name == "10a_c-03"]), + "10a_d-00": Room("10a", "10a_d-00", "Farewell - Room d-00", [reg for _, reg in all_regions.items() if reg.room_name == "10a_d-00"], [door for _, door in all_doors.items() if door.room_name == "10a_d-00"]), + "10a_d-04": Room("10a", "10a_d-04", "Farewell - Room d-04", [reg for _, reg in all_regions.items() if reg.room_name == "10a_d-04"], [door for _, door in all_doors.items() if door.room_name == "10a_d-04"]), + "10a_d-03": Room("10a", "10a_d-03", "Farewell - Room d-03", [reg for _, reg in all_regions.items() if reg.room_name == "10a_d-03"], [door for _, door in all_doors.items() if door.room_name == "10a_d-03"]), + "10a_d-01": Room("10a", "10a_d-01", "Farewell - Room d-01", [reg for _, reg in all_regions.items() if reg.room_name == "10a_d-01"], [door for _, door in all_doors.items() if door.room_name == "10a_d-01"]), + "10a_d-02": Room("10a", "10a_d-02", "Farewell - Room d-02", [reg for _, reg in all_regions.items() if reg.room_name == "10a_d-02"], [door for _, door in all_doors.items() if door.room_name == "10a_d-02"]), + "10a_d-05": Room("10a", "10a_d-05", "Farewell - Room d-05", [reg for _, reg in all_regions.items() if reg.room_name == "10a_d-05"], [door for _, door in all_doors.items() if door.room_name == "10a_d-05"]), + "10a_e-00y": Room("10a", "10a_e-00y", "Farewell - Room e-00y", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-00y"], [door for _, door in all_doors.items() if door.room_name == "10a_e-00y"]), + "10a_e-00yb": Room("10a", "10a_e-00yb", "Farewell - Room e-00yb", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-00yb"], [door for _, door in all_doors.items() if door.room_name == "10a_e-00yb"]), + "10a_e-00z": Room("10a", "10a_e-00z", "Farewell - Room e-00z", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-00z"], [door for _, door in all_doors.items() if door.room_name == "10a_e-00z"], "Remembered", "10a_e-00z_south"), + "10a_e-00": Room("10a", "10a_e-00", "Farewell - Room e-00", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-00"], [door for _, door in all_doors.items() if door.room_name == "10a_e-00"]), + "10a_e-00b": Room("10a", "10a_e-00b", "Farewell - Room e-00b", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-00b"], [door for _, door in all_doors.items() if door.room_name == "10a_e-00b"]), + "10a_e-01": Room("10a", "10a_e-01", "Farewell - Room e-01", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-01"], [door for _, door in all_doors.items() if door.room_name == "10a_e-01"]), + "10a_e-02": Room("10a", "10a_e-02", "Farewell - Room e-02", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-02"], [door for _, door in all_doors.items() if door.room_name == "10a_e-02"]), + "10a_e-03": Room("10a", "10a_e-03", "Farewell - Room e-03", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-03"], [door for _, door in all_doors.items() if door.room_name == "10a_e-03"]), + "10a_e-04": Room("10a", "10a_e-04", "Farewell - Room e-04", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-04"], [door for _, door in all_doors.items() if door.room_name == "10a_e-04"]), + "10a_e-05": Room("10a", "10a_e-05", "Farewell - Room e-05", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-05"], [door for _, door in all_doors.items() if door.room_name == "10a_e-05"]), + "10a_e-05b": Room("10a", "10a_e-05b", "Farewell - Room e-05b", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-05b"], [door for _, door in all_doors.items() if door.room_name == "10a_e-05b"]), + "10a_e-05c": Room("10a", "10a_e-05c", "Farewell - Room e-05c", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-05c"], [door for _, door in all_doors.items() if door.room_name == "10a_e-05c"]), + "10a_e-06": Room("10a", "10a_e-06", "Farewell - Room e-06", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-06"], [door for _, door in all_doors.items() if door.room_name == "10a_e-06"]), + "10a_e-07": Room("10a", "10a_e-07", "Farewell - Room e-07", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-07"], [door for _, door in all_doors.items() if door.room_name == "10a_e-07"]), + "10a_e-08": Room("10a", "10a_e-08", "Farewell - Room e-08", [reg for _, reg in all_regions.items() if reg.room_name == "10a_e-08"], [door for _, door in all_doors.items() if door.room_name == "10a_e-08"]), + + "10b_f-door": Room("10b", "10b_f-door", "Farewell - Room f-door", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-door"], [door for _, door in all_doors.items() if door.room_name == "10b_f-door"], "Event Horizon", "10b_f-door_west"), + "10b_f-00": Room("10b", "10b_f-00", "Farewell - Room f-00", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-00"], [door for _, door in all_doors.items() if door.room_name == "10b_f-00"]), + "10b_f-01": Room("10b", "10b_f-01", "Farewell - Room f-01", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-01"], [door for _, door in all_doors.items() if door.room_name == "10b_f-01"]), + "10b_f-02": Room("10b", "10b_f-02", "Farewell - Room f-02", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-02"], [door for _, door in all_doors.items() if door.room_name == "10b_f-02"]), + "10b_f-03": Room("10b", "10b_f-03", "Farewell - Room f-03", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-03"], [door for _, door in all_doors.items() if door.room_name == "10b_f-03"]), + "10b_f-04": Room("10b", "10b_f-04", "Farewell - Room f-04", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-04"], [door for _, door in all_doors.items() if door.room_name == "10b_f-04"]), + "10b_f-05": Room("10b", "10b_f-05", "Farewell - Room f-05", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-05"], [door for _, door in all_doors.items() if door.room_name == "10b_f-05"]), + "10b_f-06": Room("10b", "10b_f-06", "Farewell - Room f-06", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-06"], [door for _, door in all_doors.items() if door.room_name == "10b_f-06"]), + "10b_f-07": Room("10b", "10b_f-07", "Farewell - Room f-07", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-07"], [door for _, door in all_doors.items() if door.room_name == "10b_f-07"]), + "10b_f-08": Room("10b", "10b_f-08", "Farewell - Room f-08", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-08"], [door for _, door in all_doors.items() if door.room_name == "10b_f-08"]), + "10b_f-09": Room("10b", "10b_f-09", "Farewell - Room f-09", [reg for _, reg in all_regions.items() if reg.room_name == "10b_f-09"], [door for _, door in all_doors.items() if door.room_name == "10b_f-09"]), + "10b_g-00": Room("10b", "10b_g-00", "Farewell - Room g-00", [reg for _, reg in all_regions.items() if reg.room_name == "10b_g-00"], [door for _, door in all_doors.items() if door.room_name == "10b_g-00"]), + "10b_g-01": Room("10b", "10b_g-01", "Farewell - Room g-01", [reg for _, reg in all_regions.items() if reg.room_name == "10b_g-01"], [door for _, door in all_doors.items() if door.room_name == "10b_g-01"]), + "10b_g-03": Room("10b", "10b_g-03", "Farewell - Room g-03", [reg for _, reg in all_regions.items() if reg.room_name == "10b_g-03"], [door for _, door in all_doors.items() if door.room_name == "10b_g-03"]), + "10b_g-02": Room("10b", "10b_g-02", "Farewell - Room g-02", [reg for _, reg in all_regions.items() if reg.room_name == "10b_g-02"], [door for _, door in all_doors.items() if door.room_name == "10b_g-02"]), + "10b_g-04": Room("10b", "10b_g-04", "Farewell - Room g-04", [reg for _, reg in all_regions.items() if reg.room_name == "10b_g-04"], [door for _, door in all_doors.items() if door.room_name == "10b_g-04"]), + "10b_g-05": Room("10b", "10b_g-05", "Farewell - Room g-05", [reg for _, reg in all_regions.items() if reg.room_name == "10b_g-05"], [door for _, door in all_doors.items() if door.room_name == "10b_g-05"]), + "10b_g-06": Room("10b", "10b_g-06", "Farewell - Room g-06", [reg for _, reg in all_regions.items() if reg.room_name == "10b_g-06"], [door for _, door in all_doors.items() if door.room_name == "10b_g-06"]), + "10b_h-00b": Room("10b", "10b_h-00b", "Farewell - Room h-00b", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-00b"], [door for _, door in all_doors.items() if door.room_name == "10b_h-00b"], "Determination", "10b_h-00b_west"), + "10b_h-00": Room("10b", "10b_h-00", "Farewell - Room h-00", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-00"], [door for _, door in all_doors.items() if door.room_name == "10b_h-00"]), + "10b_h-01": Room("10b", "10b_h-01", "Farewell - Room h-01", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-01"], [door for _, door in all_doors.items() if door.room_name == "10b_h-01"]), + "10b_h-02": Room("10b", "10b_h-02", "Farewell - Room h-02", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-02"], [door for _, door in all_doors.items() if door.room_name == "10b_h-02"]), + "10b_h-03": Room("10b", "10b_h-03", "Farewell - Room h-03", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-03"], [door for _, door in all_doors.items() if door.room_name == "10b_h-03"]), + "10b_h-03b": Room("10b", "10b_h-03b", "Farewell - Room h-03b", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-03b"], [door for _, door in all_doors.items() if door.room_name == "10b_h-03b"]), + "10b_h-04": Room("10b", "10b_h-04", "Farewell - Room h-04", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-04"], [door for _, door in all_doors.items() if door.room_name == "10b_h-04"]), + "10b_h-04b": Room("10b", "10b_h-04b", "Farewell - Room h-04b", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-04b"], [door for _, door in all_doors.items() if door.room_name == "10b_h-04b"]), + "10b_h-05": Room("10b", "10b_h-05", "Farewell - Room h-05", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-05"], [door for _, door in all_doors.items() if door.room_name == "10b_h-05"]), + "10b_h-06": Room("10b", "10b_h-06", "Farewell - Room h-06", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-06"], [door for _, door in all_doors.items() if door.room_name == "10b_h-06"]), + "10b_h-06b": Room("10b", "10b_h-06b", "Farewell - Room h-06b", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-06b"], [door for _, door in all_doors.items() if door.room_name == "10b_h-06b"]), + "10b_h-07": Room("10b", "10b_h-07", "Farewell - Room h-07", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-07"], [door for _, door in all_doors.items() if door.room_name == "10b_h-07"]), + "10b_h-08": Room("10b", "10b_h-08", "Farewell - Room h-08", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-08"], [door for _, door in all_doors.items() if door.room_name == "10b_h-08"]), + "10b_h-09": Room("10b", "10b_h-09", "Farewell - Room h-09", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-09"], [door for _, door in all_doors.items() if door.room_name == "10b_h-09"]), + "10b_h-10": Room("10b", "10b_h-10", "Farewell - Room h-10", [reg for _, reg in all_regions.items() if reg.room_name == "10b_h-10"], [door for _, door in all_doors.items() if door.room_name == "10b_h-10"]), + "10b_i-00": Room("10b", "10b_i-00", "Farewell - Room i-00", [reg for _, reg in all_regions.items() if reg.room_name == "10b_i-00"], [door for _, door in all_doors.items() if door.room_name == "10b_i-00"], "Stubbornness", "10b_i-00_west"), + "10b_i-00b": Room("10b", "10b_i-00b", "Farewell - Room i-00b", [reg for _, reg in all_regions.items() if reg.room_name == "10b_i-00b"], [door for _, door in all_doors.items() if door.room_name == "10b_i-00b"]), + "10b_i-01": Room("10b", "10b_i-01", "Farewell - Room i-01", [reg for _, reg in all_regions.items() if reg.room_name == "10b_i-01"], [door for _, door in all_doors.items() if door.room_name == "10b_i-01"]), + "10b_i-02": Room("10b", "10b_i-02", "Farewell - Room i-02", [reg for _, reg in all_regions.items() if reg.room_name == "10b_i-02"], [door for _, door in all_doors.items() if door.room_name == "10b_i-02"]), + "10b_i-03": Room("10b", "10b_i-03", "Farewell - Room i-03", [reg for _, reg in all_regions.items() if reg.room_name == "10b_i-03"], [door for _, door in all_doors.items() if door.room_name == "10b_i-03"]), + "10b_i-04": Room("10b", "10b_i-04", "Farewell - Room i-04", [reg for _, reg in all_regions.items() if reg.room_name == "10b_i-04"], [door for _, door in all_doors.items() if door.room_name == "10b_i-04"]), + "10b_i-05": Room("10b", "10b_i-05", "Farewell - Room i-05", [reg for _, reg in all_regions.items() if reg.room_name == "10b_i-05"], [door for _, door in all_doors.items() if door.room_name == "10b_i-05"]), + "10b_j-00": Room("10b", "10b_j-00", "Farewell - Room j-00", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-00"], [door for _, door in all_doors.items() if door.room_name == "10b_j-00"], "Reconciliation", "10b_j-00_west"), + "10b_j-00b": Room("10b", "10b_j-00b", "Farewell - Room j-00b", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-00b"], [door for _, door in all_doors.items() if door.room_name == "10b_j-00b"]), + "10b_j-01": Room("10b", "10b_j-01", "Farewell - Room j-01", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-01"], [door for _, door in all_doors.items() if door.room_name == "10b_j-01"]), + "10b_j-02": Room("10b", "10b_j-02", "Farewell - Room j-02", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-02"], [door for _, door in all_doors.items() if door.room_name == "10b_j-02"]), + "10b_j-03": Room("10b", "10b_j-03", "Farewell - Room j-03", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-03"], [door for _, door in all_doors.items() if door.room_name == "10b_j-03"]), + "10b_j-04": Room("10b", "10b_j-04", "Farewell - Room j-04", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-04"], [door for _, door in all_doors.items() if door.room_name == "10b_j-04"]), + "10b_j-05": Room("10b", "10b_j-05", "Farewell - Room j-05", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-05"], [door for _, door in all_doors.items() if door.room_name == "10b_j-05"]), + "10b_j-06": Room("10b", "10b_j-06", "Farewell - Room j-06", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-06"], [door for _, door in all_doors.items() if door.room_name == "10b_j-06"]), + "10b_j-07": Room("10b", "10b_j-07", "Farewell - Room j-07", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-07"], [door for _, door in all_doors.items() if door.room_name == "10b_j-07"]), + "10b_j-08": Room("10b", "10b_j-08", "Farewell - Room j-08", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-08"], [door for _, door in all_doors.items() if door.room_name == "10b_j-08"]), + "10b_j-09": Room("10b", "10b_j-09", "Farewell - Room j-09", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-09"], [door for _, door in all_doors.items() if door.room_name == "10b_j-09"]), + "10b_j-10": Room("10b", "10b_j-10", "Farewell - Room j-10", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-10"], [door for _, door in all_doors.items() if door.room_name == "10b_j-10"]), + "10b_j-11": Room("10b", "10b_j-11", "Farewell - Room j-11", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-11"], [door for _, door in all_doors.items() if door.room_name == "10b_j-11"]), + "10b_j-12": Room("10b", "10b_j-12", "Farewell - Room j-12", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-12"], [door for _, door in all_doors.items() if door.room_name == "10b_j-12"]), + "10b_j-13": Room("10b", "10b_j-13", "Farewell - Room j-13", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-13"], [door for _, door in all_doors.items() if door.room_name == "10b_j-13"]), + "10b_j-14": Room("10b", "10b_j-14", "Farewell - Room j-14", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-14"], [door for _, door in all_doors.items() if door.room_name == "10b_j-14"]), + "10b_j-14b": Room("10b", "10b_j-14b", "Farewell - Room j-14b", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-14b"], [door for _, door in all_doors.items() if door.room_name == "10b_j-14b"]), + "10b_j-15": Room("10b", "10b_j-15", "Farewell - Room j-15", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-15"], [door for _, door in all_doors.items() if door.room_name == "10b_j-15"]), + "10b_j-16": Room("10b", "10b_j-16", "Farewell - Room j-16", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-16"], [door for _, door in all_doors.items() if door.room_name == "10b_j-16"], "Farewell", "10b_j-16_west"), + "10b_j-17": Room("10b", "10b_j-17", "Farewell - Room j-17", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-17"], [door for _, door in all_doors.items() if door.room_name == "10b_j-17"]), + "10b_j-18": Room("10b", "10b_j-18", "Farewell - Room j-18", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-18"], [door for _, door in all_doors.items() if door.room_name == "10b_j-18"]), + "10b_j-19": Room("10b", "10b_j-19", "Farewell - Room j-19", [reg for _, reg in all_regions.items() if reg.room_name == "10b_j-19"], [door for _, door in all_doors.items() if door.room_name == "10b_j-19"]), + "10b_GOAL": Room("10b", "10b_GOAL", "Farewell - Room GOAL", [reg for _, reg in all_regions.items() if reg.room_name == "10b_GOAL"], [door for _, door in all_doors.items() if door.room_name == "10b_GOAL"]), + + "10c_end-golden": Room("10c", "10c_end-golden", "Farewell - Room end-golden", [reg for _, reg in all_regions.items() if reg.room_name == "10c_end-golden"], [door for _, door in all_doors.items() if door.room_name == "10c_end-golden"]), + +} + +all_levels: dict[str, Level] = { + "0a": Level("0a", "Prologue", [room for _, room in all_rooms.items() if room.level_name == "0a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "0a"]), + "1a": Level("1a", "Forsaken City A", [room for _, room in all_rooms.items() if room.level_name == "1a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "1a"]), + "1b": Level("1b", "Forsaken City B", [room for _, room in all_rooms.items() if room.level_name == "1b"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "1b"]), + "1c": Level("1c", "Forsaken City C", [room for _, room in all_rooms.items() if room.level_name == "1c"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "1c"]), + "2a": Level("2a", "Old Site A", [room for _, room in all_rooms.items() if room.level_name == "2a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "2a"]), + "2b": Level("2b", "Old Site B", [room for _, room in all_rooms.items() if room.level_name == "2b"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "2b"]), + "2c": Level("2c", "Old Site C", [room for _, room in all_rooms.items() if room.level_name == "2c"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "2c"]), + "3a": Level("3a", "Celestial Resort A", [room for _, room in all_rooms.items() if room.level_name == "3a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "3a"]), + "3b": Level("3b", "Celestial Resort B", [room for _, room in all_rooms.items() if room.level_name == "3b"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "3b"]), + "3c": Level("3c", "Celestial Resort C", [room for _, room in all_rooms.items() if room.level_name == "3c"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "3c"]), + "4a": Level("4a", "Golden Ridge A", [room for _, room in all_rooms.items() if room.level_name == "4a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "4a"]), + "4b": Level("4b", "Golden Ridge B", [room for _, room in all_rooms.items() if room.level_name == "4b"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "4b"]), + "4c": Level("4c", "Golden Ridge C", [room for _, room in all_rooms.items() if room.level_name == "4c"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "4c"]), + "5a": Level("5a", "Mirror Temple A", [room for _, room in all_rooms.items() if room.level_name == "5a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "5a"]), + "5b": Level("5b", "Mirror Temple B", [room for _, room in all_rooms.items() if room.level_name == "5b"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "5b"]), + "5c": Level("5c", "Mirror Temple C", [room for _, room in all_rooms.items() if room.level_name == "5c"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "5c"]), + "6a": Level("6a", "Reflection A", [room for _, room in all_rooms.items() if room.level_name == "6a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "6a"]), + "6b": Level("6b", "Reflection B", [room for _, room in all_rooms.items() if room.level_name == "6b"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "6b"]), + "6c": Level("6c", "Reflection C", [room for _, room in all_rooms.items() if room.level_name == "6c"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "6c"]), + "7a": Level("7a", "The Summit A", [room for _, room in all_rooms.items() if room.level_name == "7a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "7a"]), + "7b": Level("7b", "The Summit B", [room for _, room in all_rooms.items() if room.level_name == "7b"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "7b"]), + "7c": Level("7c", "The Summit C", [room for _, room in all_rooms.items() if room.level_name == "7c"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "7c"]), + "8a": Level("8a", "Epilogue", [room for _, room in all_rooms.items() if room.level_name == "8a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "8a"]), + "9a": Level("9a", "Core A", [room for _, room in all_rooms.items() if room.level_name == "9a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "9a"]), + "9b": Level("9b", "Core B", [room for _, room in all_rooms.items() if room.level_name == "9b"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "9b"]), + "9c": Level("9c", "Core C", [room for _, room in all_rooms.items() if room.level_name == "9c"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "9c"]), + "10a": Level("10a", "Farewell", [room for _, room in all_rooms.items() if room.level_name == "10a"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "10a"]), + "10b": Level("10b", "Farewell", [room for _, room in all_rooms.items() if room.level_name == "10b"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "10b"]), + "10c": Level("10c", "Farewell", [room for _, room in all_rooms.items() if room.level_name == "10c"], [room_con for _, room_con in all_room_connections.items() if room_con.level_name == "10c"]), + +} + diff --git a/worlds/celeste_open_world/data/ParseData.py b/worlds/celeste_open_world/data/ParseData.py new file mode 100644 index 000000000000..b9f8f47267ef --- /dev/null +++ b/worlds/celeste_open_world/data/ParseData.py @@ -0,0 +1,190 @@ +if __name__ == "__main__": + import json + + all_doors: list[str] = [] + all_region_connections: list[str] = [] + all_locations: list[str] = [] + all_regions: list[str] = [] + all_room_connections: list[str] = [] + all_rooms: list[str] = [] + all_levels: list[str] = [] + + + data_file = open('CelesteLevelData.json') + level_data = json.load(data_file) + data_file.close() + + # Levels + for level in level_data["levels"]: + level_str = (f" \"{level['name']}\": Level(\"{level['name']}\", " + f"\"{level['display_name']}\", " + f"[room for _, room in all_rooms.items() if room.level_name == \"{level['name']}\"], " + f"[room_con for _, room_con in all_room_connections.items() if room_con.level_name == \"{level['name']}\"])," + ) + + all_levels.append(level_str) + + # Rooms + for room in level["rooms"]: + room_full_name = f"{level['name']}_{room['name']}" + room_full_display_name = f"{level['display_name']} - Room {room['name']}" + + room_str = (f" \"{room_full_name}\": Room(\"{level['name']}\", " + f"\"{room_full_name}\", \"{room_full_display_name}\", " + f"[reg for _, reg in all_regions.items() if reg.room_name == \"{room_full_name}\"], " + f"[door for _, door in all_doors.items() if door.room_name == \"{room_full_name}\"]" + ) + + if "checkpoint" in room and room["checkpoint"] != "": + room_str += f", \"{room['checkpoint']}\", \"{room_full_name}_{room['checkpoint_region']}\"" + room_str += ")," + + all_rooms.append(room_str) + + # Regions + for region in room["regions"]: + region_full_name = f"{room_full_name}_{region['name']}" + + region_str = (f" \"{region_full_name}\": PreRegion(\"{region_full_name}\", " + f"\"{room_full_name}\", " + f"[reg_con for _, reg_con in all_region_connections.items() if reg_con.source_name == \"{region_full_name}\"], " + f"[loc for _, loc in all_locations.items() if loc.region_name == \"{region_full_name}\"])," + ) + + all_regions.append(region_str) + + # Locations + if "locations" in region: + for location in region["locations"]: + location_full_name = f"{room_full_name}_{location['name']}" + + location_display_name = location['display_name'] + if (location['type'] == "strawberry" and location_display_name != "Moon Berry") or location['type'] == "binoculars" : + location_display_name = f"Room {room['name']} {location_display_name}" + location_full_display_name = f"{level['display_name']} - {location_display_name}" + + location_str = (f" \"{location_full_name}\": LevelLocation(\"{location_full_name}\", " + f"\"{location_full_display_name}\", \"{region_full_name}\", " + f"LocationType.{location['type']}, [" + ) + + if "rule" in location: + for possible_access in location['rule']: + location_str += f"[" + for item in possible_access: + if "Key" in item or "Gem" in item: + location_str += f"\"{level['display_name']} - {item}\", " + else: + location_str += f"ItemName.{item}, " + location_str += f"], " + elif "rules" in location: + raise Exception(f"Location {location_full_name} uses 'rules' instead of 'rule") + + location_str += "])," + + all_locations.append(location_str) + + # Region Connections + for reg_con in region["connections"]: + dest_region_full_name = f"{room_full_name}_{reg_con['dest']}" + reg_con_full_name = f"{region_full_name}---{dest_region_full_name}" + + reg_con_str = f" \"{reg_con_full_name}\": RegionConnection(\"{region_full_name}\", \"{dest_region_full_name}\", [" + + for possible_access in reg_con['rule']: + reg_con_str += f"[" + for item in possible_access: + if "Key" in item or "Gem" in item: + reg_con_str += f"\"{level['display_name']} - {item}\", " + else: + reg_con_str += f"ItemName.{item}, " + reg_con_str += f"], " + + reg_con_str += "])," + + all_region_connections.append(reg_con_str) + + for door in room["doors"]: + door_full_name = f"{room_full_name}_{door['name']}" + + door_str = (f" \"{door_full_name}\": Door(\"{door_full_name}\", " + f"\"{room_full_name}\", " + f"DoorDirection.{door['direction']}, " + ) + + door_str += "True, " if door["blocked"] else "False, " + door_str += "True)," if door["closes_behind"] else "False)," + + all_doors.append(door_str) + + all_regions.append("") + all_region_connections.append("") + all_doors.append("") + + all_locations.append("") + all_rooms.append("") + + # Room Connections + for room_con in level["room_connections"]: + source_door_full_name = f"{level['name']}_{room_con['source_room']}_{room_con['source_door']}" + dest_door_full_name = f"{level['name']}_{room_con['dest_room']}_{room_con['dest_door']}" + + room_con_str = (f" \"{source_door_full_name}---{dest_door_full_name}\": RoomConnection(\"{level['name']}\", " + f"all_doors[\"{source_door_full_name}\"], " + f"all_doors[\"{dest_door_full_name}\"])," + ) + + all_room_connections.append(room_con_str) + + all_room_connections.append("") + + + all_levels.append("") + + + import sys + out_file = open("CelesteLevelData.py", "w") + sys.stdout = out_file + + print("# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MANUALLY EDIT.") + print("") + print("from ..Levels import Level, Room, PreRegion, LevelLocation, RegionConnection, RoomConnection, Door, DoorDirection, LocationType") + print("from ..Names import ItemName") + print("") + print("all_doors: dict[str, Door] = {") + for line in all_doors: + print(line) + print("}") + print("") + print("all_region_connections: dict[str, RegionConnection] = {") + for line in all_region_connections: + print(line) + print("}") + print("") + print("all_locations: dict[str, LevelLocation] = {") + for line in all_locations: + print(line) + print("}") + print("") + print("all_regions: dict[str, PreRegion] = {") + for line in all_regions: + print(line) + print("}") + print("") + print("all_room_connections: dict[str, RoomConnection] = {") + for line in all_room_connections: + print(line) + print("}") + print("") + print("all_rooms: dict[str, Room] = {") + for line in all_rooms: + print(line) + print("}") + print("") + print("all_levels: dict[str, Level] = {") + for line in all_levels: + print(line) + print("}") + print("") + + out_file.close() diff --git a/worlds/celeste_open_world/data/__init__.py b/worlds/celeste_open_world/data/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/worlds/celeste_open_world/docs/en_Celeste (Open World).md b/worlds/celeste_open_world/docs/en_Celeste (Open World).md new file mode 100644 index 000000000000..c27c4d6480da --- /dev/null +++ b/worlds/celeste_open_world/docs/en_Celeste (Open World).md @@ -0,0 +1,98 @@ +# Celeste Open World + +## What is this game? + +**Celeste (Open World)** is a Randomizer for the original Celeste. In this acclaimed platformer created by ExOK Games, you control Madeline as she attempts to climb the titular mountain, meeting friends and obstacles along the way. +This randomizer takes an "Open World" approach. All of your active areas are open to you from the start. Progression is found in unlocking the ability to interact with various objects in the areas, such as springs, traffic blocks, feathers, and many more. One area can be selected as your "Goal Area", requiring you to clear that area before you can access the Epilogue and finish the game. Additionally, you can be required to receive a customizable amount of `Strawberry` items to access the Epilogue and optionally to access your Goal Area as well. +There are a variety of progression, location, and aesthetic options available. Please be safe on the climb. + +## Where is the options page? + +The [player options page for this game](../player-options) contains all the options you need to configure and export a config file. + +## What does randomization do to this game? + +By default, the Prologue, the A-Side levels for Chapters 1-7, and the Epilogue are included in the randomizer. Using options, B- and C-Sides can also be included, as can the Core and Farewell chapters. One level is chosen via an option to be the "Goal Area". Obtaining the required amount of Strawberry items from the multiworld and clearing this Goal Area will grant access to the Epilogue and the Credits, which is the goal of the randomizer. + +## What items get shuffled? + +The main collectable in this game is Strawberries, which you must collect to complete the game. + +16 Crystal Heart items are included as filler items (Heart Gates are disabled in this mod). Any additional space in the item pool is filled by Raspberries, which do nothing, and Traps. + +The following interactable items are included in the item pool, so long as any active level includes them: +- Springs +- Dash Refills +- Traffic Blocks +- Pink Cassette Blocks +- Blue Cassette Blocks +- Dream Blocks +- Coins +- Strawberry Seeds +- Sinking Platforms +- Moving Platforms +- Blue Clouds +- Pink Clouds +- Blue Boosters +- Red Boosters +- Move Blocks +- White Block +- Swap Blocks +- Dash Switches +- Torches +- Theo Crystal +- Feathers +- Bumpers +- Kevins +- Badeline Boosters +- Fire and Ice Balls +- Core Toggles +- Core Blocks +- Pufferfish +- Jellyfish +- Double Dash Refills +- Breaker Boxes +- Yellow Cassette Blocks +- Green Cassette Blocks +- Bird + +Additionally, the following items can optionally be included in the Item Pool: +- Keys +- Checkpoints +- Summit Gems +- One Cassette per active level + +Finally, the following Traps can be optionally included in the Item Pool: +- Bald Trap +- Literature Trap +- Stun Trap +- Invisible Trap +- Fast Trap +- Slow Trap +- Ice Trap +- Reverse Trap +- Screen Flip Trap +- Laughter Trap +- Hiccup Trap +- Zoom Trap + +## What locations get shuffled? + +By default, the locations in Celeste (Open World) which can contain items are: +- Level Clears +- Strawberries +- Crystal Hearts +- Cassettes + +Additionally, the following locations can optionally be included in the Location Pool: +- Golden Strawberries +- Keys +- Checkpoints +- Summit Gems +- Cars +- Binoculars +- Rooms + +## How can I get started? + +To get started playing Celeste (Open World) in Archipelago, [go to the setup guide for this game](../../../tutorial/Celeste%20(Open%20World)/guide/en) diff --git a/worlds/celeste_open_world/docs/guide_en.md b/worlds/celeste_open_world/docs/guide_en.md new file mode 100644 index 000000000000..eb96d6276261 --- /dev/null +++ b/worlds/celeste_open_world/docs/guide_en.md @@ -0,0 +1,20 @@ +# Celeste (Open World) Setup Guide + +## Required Software +- The latest version of Celeste (1.4) from any official PC game distributor +- Olympus (Celeste Mod Manager) from: [Olympus Download Page](https://everestapi.github.io/) +- The latest version of the Archipelago Open World mod for Celeste from: [GitHub Release](https://github.com/PoryGoneDev/Celeste-Archipelago-Open-World/releases) + +## Installation Procedures (Windows/Linux) + +1. Install the latest version of Celeste (v1.4) on PC +2. Install `Olympus` (mod manager/launcher) and `Everest` (mod loader) per its instructions: [Olympus Setup Instructions](https://everestapi.github.io/) +3. Place the `Archipelago_Open_World.zip` from the GitHub release into the `mods` folder in your Celeste install +4. (Recommended) From the main menu, enter `Mod Options` and set `Debug Mode` to `Everest` or `Always`. This will give you access to a rudimentary Text Client which can be toggled with the `~` key. + +## Joining a MultiWorld Game + +1. Load Everest from the Olympus Launcher with the Archipelago Open World mod enabled +2. Enter the Connection Menu via the `Connect` button on the main menu +3. Use the keyboard to enter your connection information, then press the Connect button +4. Once connected, you can use the Debug Menu (opened with `~`) as a Text Client, by typing "`!ap `" followed by what you would normally enter into a Text Client From 5fd9570368bb86acbd35c613cb526f24fb36e730 Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 1 Sep 2025 18:53:58 -0500 Subject: [PATCH 0684/1218] Docs: Add section about adding Components (#5097) * kinda driven by wanting to test the labeling change in prod but also components are a weird part of the ecosystem and could use more documentation. * additional text describing launch/launch_subprocess and their use * Update docs/adding games.md Co-authored-by: Duck <31627079+duckboycool@users.noreply.github.com> --------- Co-authored-by: Duck <31627079+duckboycool@users.noreply.github.com> --- docs/adding games.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/adding games.md b/docs/adding games.md index c3eb0d023eb3..762a908fc8e3 100644 --- a/docs/adding games.md +++ b/docs/adding games.md @@ -62,6 +62,24 @@ if possible. * If your client appears in the Archipelago Launcher, you may define an icon for it that differentiates it from other clients. The icon size is 48x48 pixels, but smaller or larger images will scale to that size. +### Launcher Integration + +If you have a python client or want to utilize the integration features of the Archipelago Launcher (ex. Slot links in +webhost) you can define a Component to be a part of the Launcher. `LauncherComponents.components` can be appended to +with additional Components in order to automatically add them to the Launcher. Most Components only need a +`display_name` and `func`, but `supports_uri` and `game_name` can be defined to support launching by webhost links, +`icon` and `description` can be used to customize display in the Launcher UI, and `file_identifier` can be used to +launch by file. + +Additionally, if you use `func` you have access to LauncherComponent.launch or launch_subprocess to run your +function as a subprocesses that can be utilized side by side other clients. +```py +def my_func(*args: str): + from .client import run_client + LauncherComponent.launch(run_client, name="My Client", args=args) +``` + + ## World The world is your game integration for the Archipelago generator, webhost, and multiworld server. It contains all the From 14d65fdf28cd8b03056dc2a967508d383cb29400 Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 1 Sep 2025 18:54:34 -0500 Subject: [PATCH 0685/1218] Docs: Add doc for shared cache (#5129) * adds doc file describing what the shared cache is, how to use it, and what you can currently expect in it * Update docs/shared_cache.md Co-authored-by: Duck <31627079+duckboycool@users.noreply.github.com> --------- Co-authored-by: Duck <31627079+duckboycool@users.noreply.github.com> --- docs/shared_cache.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 docs/shared_cache.md diff --git a/docs/shared_cache.md b/docs/shared_cache.md new file mode 100644 index 000000000000..0dd323926a58 --- /dev/null +++ b/docs/shared_cache.md @@ -0,0 +1,18 @@ +# Shared Cache + +Archipelago maintains a shared folder of information that can be persisted for a machine and reused across Libraries. +It can be found at the User Cache Directory for appname `Archipelago` in the `Cache` subfolder +(ex. `%LOCALAPPDATA%/Archipelago/Cache`). + +## Common Cache + +The Common Cache `common.json` can be used to store any generic data that is expected to be shared across programs +for the same User. + +* `uuid`: A UUID identifier used to identify clients as from the same user/machine, to be sent in the Connect packet + +## Data Package Cache + +The `datapackage` folder in the shared cache folder is used to store datapackages by game and checksum to be reused +in order to save network traffic. The expected structure is `datapackage/Game Name/checksum_value.json` with the +contents of each json file being the no-whitespace datapackage contents. From a0a1c5d4c0453ea367e12966d926c0bbb70eed67 Mon Sep 17 00:00:00 2001 From: Rhenaud Dubois Date: Tue, 2 Sep 2025 01:56:52 +0200 Subject: [PATCH 0686/1218] Pokemon Emerald: Added Pokemon Gen 3 Adjuster data (#5145) * Added Pokemon Gen 3 Adjuster data * Updated extracted data * Commented out adjuster docs for now * Replace in the docs markers with ** --- worlds/pokemon_emerald/__init__.py | 19 +- worlds/pokemon_emerald/adjuster_constants.py | 240 ++++++++++++++ .../pokemon_emerald/data/extracted_data.json | 2 +- worlds/pokemon_emerald/docs/adjuster_en.md | 293 ++++++++++++++++++ .../pokemon_emerald/docs/icon_palette_0.pal | 19 ++ .../pokemon_emerald/docs/icon_palette_1.pal | 19 ++ .../pokemon_emerald/docs/icon_palette_2.pal | 19 ++ 7 files changed, 608 insertions(+), 3 deletions(-) create mode 100644 worlds/pokemon_emerald/adjuster_constants.py create mode 100644 worlds/pokemon_emerald/docs/adjuster_en.md create mode 100644 worlds/pokemon_emerald/docs/icon_palette_0.pal create mode 100644 worlds/pokemon_emerald/docs/icon_palette_1.pal create mode 100644 worlds/pokemon_emerald/docs/icon_palette_2.pal diff --git a/worlds/pokemon_emerald/__init__.py b/worlds/pokemon_emerald/__init__.py index c1875710ef2c..4f2c2ef95cb4 100644 --- a/worlds/pokemon_emerald/__init__.py +++ b/worlds/pokemon_emerald/__init__.py @@ -26,9 +26,14 @@ from .pokemon import (get_random_move, get_species_id_by_label, randomize_abilities, randomize_learnsets, randomize_legendary_encounters, randomize_misc_pokemon, randomize_starters, randomize_tm_hm_compatibility,randomize_types, randomize_wild_encounters) -from .rom import PokemonEmeraldProcedurePatch, write_tokens +from .rom import PokemonEmeraldProcedurePatch, write_tokens from .util import get_encounter_type_label +# Try adding the Pokemon Gen 3 Adjuster +try: + from worlds._pokemon_gen3_adjuster import __init__ +except: + pass class PokemonEmeraldWebWorld(WebWorld): """ @@ -53,7 +58,7 @@ class PokemonEmeraldWebWorld(WebWorld): "setup/es", ["nachocua"] ) - + setup_sv = Tutorial( "Multivärld Installations Guide", "En guide för att kunna spela Pokémon Emerald med Archipelago.", @@ -63,6 +68,16 @@ class PokemonEmeraldWebWorld(WebWorld): ["Tsukino"] ) + # Add this doc file when the adjuster is merged + adjuster_en = Tutorial( + "Usage Guide", + "A guide to use the Pokemon Gen 3 Adjuster with Pokemon Emerald.", + "English", + "adjuster_en.md", + "adjuster/en", + ["RhenaudTheLukark"] + ) + tutorials = [setup_en, setup_es, setup_sv] option_groups = OPTION_GROUPS diff --git a/worlds/pokemon_emerald/adjuster_constants.py b/worlds/pokemon_emerald/adjuster_constants.py new file mode 100644 index 000000000000..db3eac179d8c --- /dev/null +++ b/worlds/pokemon_emerald/adjuster_constants.py @@ -0,0 +1,240 @@ +from worlds._pokemon_gen3_adjuster.adjuster_constants import * +from .data import data + +EMERALD_PATCH_EXTENSIONS = ".apemerald" + +EMERALD_POKEMON_SPRITES = ["front_anim", "back", "icon", "footprint"] +EMERALD_POKEMON_MAIN_PALETTE_EXTRACTION_PRIORITY = ["front_anim", "back"] +EMERALD_POKEMON_SHINY_PALETTE_EXTRACTION_PRIORITY = ["sfront_anim", "sback"] +EMERALD_POKEMON_PALETTES = { + "palette": EMERALD_POKEMON_MAIN_PALETTE_EXTRACTION_PRIORITY, + "palette_shiny": EMERALD_POKEMON_SHINY_PALETTE_EXTRACTION_PRIORITY +} + +EMERALD_EGG_SPRITES = [*EMERALD_POKEMON_SPRITES, "hatch_anim"] +EMERALD_EGG_PALETTES = {**EMERALD_POKEMON_PALETTES, "palette_hatch": POKEMON_HATCH_PALETTE_EXTRACTION_PRIORITY} + +EMERALD_TRAINER_FOLDERS = ["Brendan", "May"] +EMERALD_TRAINER_SPRITES = ["walking_running", "acro_bike", "mach_bike", "surfing", "field_move", "underwater", + "fishing", "watering", "decorating", "battle_front", "battle_back"] +EMERALD_TRAINER_MAIN_PALETTE_EXTRACTION_PRIORITY = ["walking_running", "acro_bike", "mach_bike", "surfing", + "field_move", "fishing", "watering", "decorating"] +EMERALD_TRAINER_PALETTES = { + "palette": EMERALD_TRAINER_MAIN_PALETTE_EXTRACTION_PRIORITY, + "palette_reflection": TRAINER_REFLECTION_PALETTE_EXTRACTION_PRIORITY, + "palette_underwater": TRAINER_UNDERWATER_PALETTE_EXTRACTION_PRIORITY, + "palette_battle_back": TRAINER_BATTLE_BACK_PALETTE_EXTRACTION_PRIORITY, + "palette_battle_front": TRAINER_BATTLE_FRONT_PALETTE_EXTRACTION_PRIORITY +} + +EMERALD_SIMPLE_TRAINER_FOLDERS: list[str] = [] + +EMERALD_FOLDER_OBJECT_INFOS: list[dict[str, str | list[str] | dict[str, list[str]]]] = [ + { + "name": "Egg", + "key": "pokemon", + "folders": POKEMON_FOLDERS, + "sprites": EMERALD_EGG_SPRITES, + "palettes": EMERALD_EGG_PALETTES + }, + { + "key": "pokemon", + "folders": POKEMON_FOLDERS, + "sprites": EMERALD_POKEMON_SPRITES, + "palettes": EMERALD_POKEMON_PALETTES + }, + { + "key": "players", + "folders": EMERALD_TRAINER_FOLDERS, + "sprites": EMERALD_TRAINER_SPRITES, + "palettes": EMERALD_TRAINER_PALETTES + }, + { + "key": "trainer", + "folders": EMERALD_SIMPLE_TRAINER_FOLDERS, + "sprites": SIMPLE_TRAINER_SPRITES, + "palettes": SIMPLE_TRAINER_PALETTES + } +] + +EMERALD_INTERNAL_ID_TO_OBJECT_ADDRESS = { + "pokemon_front_anim": ("gMonFrontPicTable", 8, False), + "pokemon_back": ("gMonBackPicTable", 8, False), + "pokemon_icon": ("gMonIconTable", 4, False), + "pokemon_icon_index": ("gMonIconPaletteIndices", 1, False), + "pokemon_footprint": ("gMonFootprintTable", 4, False), + "pokemon_hatch_anim": ("sEggHatchTiles", 0, True), + "pokemon_palette": ("gMonPaletteTable", 8, False), + "pokemon_palette_shiny": ("gMonShinyPaletteTable", 8, False), + "pokemon_palette_hatch": ("sEggPalette", 0, True), + "pokemon_stats": ("gSpeciesInfo", 28, False), + "pokemon_move_pool": ("gLevelUpLearnsets", 4, False), + + "brendan_walking_running": ("gObjectEventGraphicsInfoPointers", 400, False), + "brendan_mach_bike": ("gObjectEventGraphicsInfoPointers", 404, False), + "brendan_acro_bike": ("gObjectEventGraphicsInfoPointers", 408, False), + "brendan_surfing": ("gObjectEventGraphicsInfoPointers", 412, False), + "brendan_field_move": ("gObjectEventGraphicsInfoPointers", 416, False), + "brendan_underwater": ("gObjectEventGraphicsInfoPointers", 444, False), + "brendan_fishing": ("gObjectEventGraphicsInfoPointers", 548, False), + "brendan_watering": ("gObjectEventGraphicsInfoPointers", 764, False), + "brendan_decorating": ("gObjectEventGraphicsInfoPointers", 772, False), + "brendan_battle_front": ("gTrainerFrontPicTable", 568, False), + "brendan_battle_back": ("gTrainerBackPicTable", 0, False), + "brendan_battle_back_throw": ("sTrainerBackSpriteTemplates", 0, False), + "brendan_palette": ("sObjectEventSpritePalettes", 64, False), + "brendan_palette_reflection": ("sObjectEventSpritePalettes", 72, False), + "brendan_palette_underwater": ("sObjectEventSpritePalettes", 88, False), + "brendan_palette_battle_back": ("gTrainerBackPicPaletteTable", 0, False), + "brendan_palette_battle_front": ("gTrainerFrontPicPaletteTable", 568, False), + + "may_walking_running": ("gObjectEventGraphicsInfoPointers", 420, False), + "may_mach_bike": ("gObjectEventGraphicsInfoPointers", 424, False), + "may_acro_bike": ("gObjectEventGraphicsInfoPointers", 428, False), + "may_surfing": ("gObjectEventGraphicsInfoPointers", 432, False), + "may_field_move": ("gObjectEventGraphicsInfoPointers", 436, False), + "may_underwater": ("gObjectEventGraphicsInfoPointers", 448, False), + "may_fishing": ("gObjectEventGraphicsInfoPointers", 552, False), + "may_watering": ("gObjectEventGraphicsInfoPointers", 768, False), + "may_decorating": ("gObjectEventGraphicsInfoPointers", 776, False), + "may_battle_front": ("gTrainerFrontPicTable", 576, False), + "may_battle_back": ("gTrainerBackPicTable", 8, False), + "may_battle_back_throw": ("sTrainerBackSpriteTemplates", 24, False), + "may_palette": ("sObjectEventSpritePalettes", 136, False), + "may_palette_reflection": ("sObjectEventSpritePalettes", 144, False), + "may_palette_underwater": ("sObjectEventSpritePalettes", 88, False), + "may_palette_battle_back": ("gTrainerBackPicPaletteTable", 8, False), + "may_palette_battle_front": ("gTrainerFrontPicPaletteTable", 576, False), + + "brendan_battle_throw_anim": ("gTrainerBackAnimsPtrTable", 0, False), + "may_battle_throw_anim": ("gTrainerBackAnimsPtrTable", 4, False), + "emerald_battle_throw_anim": ("gTrainerBackAnimsPtrTable", 0, True), + "frlg_battle_throw_anim": ("gTrainerBackAnimsPtrTable", 8, True), +} + +EMERALD_OVERWORLD_SPRITE_ADDRESSES = { + "brendan_walking_running": [0, 400, 864], + "brendan_mach_bike": [4, 404], + "brendan_acro_bike": [252, 408], + "brendan_surfing": [8, 412], + "brendan_field_move": [12, 416], + "brendan_underwater": [444], + "brendan_fishing": [548], + "brendan_watering": [764], + "brendan_decorating": [772], + "may_walking_running": [356, 420, 868], + "may_mach_bike": [360, 424], + "may_acro_bike": [364, 428], + "may_surfing": [368, 432], + "may_field_move": [372, 436], + "may_underwater": [448], + "may_fishing": [552], + "may_watering": [768], + "may_decorating": [776], +} + +EMERALD_POINTER_REFERENCES = { + "overworld_palette_table": [("LoadObjectEventPalette", 40), ("PatchObjectPalette", 52), + ("FindObjectEventPaletteIndexByTag", 40)] +} + +EMERALD_OVERWORLD_PALETTE_IDS = { + "Brendan": 0x1100, + "May": 0x1110, + "Underwater": 0x1115 +} + +EMERALD_DATA_ADDRESSES_ORIGINAL = { + "LoadObjectEventPalette": 0x08e894, + "PatchObjectPalette": 0x08e91c, + "FindObjectEventPaletteIndexByTag": 0x08e980, + "gSpeciesInfo": 0x3203cc, + "gLevelUpLearnsets": 0x32937c, + "gMonFrontPicTable": 0x30a18c, + "gMonBackPicTable": 0x3028b8, + "gMonIconTable": 0x57bca8, + "gMonFootprintTable": 0x56e694, + "gMonPaletteTable": 0x303678, + "gMonShinyPaletteTable": 0x304438, + "gMonIconPaletteIndices": 0x57c388, + "sEggPalette": 0x32b70c, + "sEggHatchTiles": 0x32b72c, + "gObjectEventGraphicsInfoPointers": 0x505620, + "sObjectEventSpritePalettes": 0x50bbc8, + "gTrainerFrontPicTable": 0x305654, + "gTrainerFrontPicPaletteTable": 0x30593c, + "gTrainerBackPicTable": 0x305d4c, + "gTrainerBackPicPaletteTable": 0x305d8c, + "sTrainerBackSpriteTemplates": 0x329df8, + "gTrainerBackAnimsPtrTable": 0x305d0c, + "sBackAnims_Brendan": 0x305ccc, + "sBackAnims_Red": 0x305cdc, + "gObjectEventBaseOam_16x16": 0x5094fc, + "gObjectEventBaseOam_16x32": 0x509514, + "gObjectEventBaseOam_32x32": 0x50951c, + "sOamTables_16x16": 0x50954c, + "sOamTables_16x32": 0x5095a0, + "sOamTables_32x32": 0x5095f4, + "sEmpty6": 0xe3cf31 +} + +EMERALD_DATA_ADDRESS_BEGINNING = 0x00 +EMERALD_DATA_ADDRESS_END = 0xFFFFFF + +EMERALD_DATA_ADDRESS_INFOS: dict[str, int | dict[str, int]] = { + "Emerald": { + "crc32": 0x1f1c08fb, + "original_addresses": EMERALD_DATA_ADDRESSES_ORIGINAL, + "ap_addresses": data.rom_addresses, + "data_address_beginning": EMERALD_DATA_ADDRESS_BEGINNING, + "data_address_end": EMERALD_DATA_ADDRESS_END + } +} + +EMERALD_VALID_OVERWORLD_SPRITE_SIZES: list[dict[str, int | str]] = [ + {"width": 16, "height": 16, "data": "sOamTables_16x16", "distrib": "gObjectEventBaseOam_16x16"}, + {"width": 16, "height": 32, "data": "sOamTables_16x32", "distrib": "gObjectEventBaseOam_16x32"}, + {"width": 32, "height": 32, "data": "sOamTables_32x32", "distrib": "gObjectEventBaseOam_32x32"}, +] + +EMERALD_SPRITES_REQUIREMENTS: dict[str, dict[str, bool | int | list[int]]] = { + "pokemon_front_anim": {"frames": 2, "width": 64, "height": 64}, + "pokemon_back": {"frames": 1, "width": 64, "height": 64}, + "pokemon_icon": {"frames": 2, "width": 32, "height": 32, "palette": VALID_ICON_PALETTES}, + "pokemon_footprint": {"frames": 1, "width": 16, "height": 16, "palette_size": 2, + "palette": VALID_FOOTPRINT_PALETTE}, + "pokemon_hatch_anim": {"frames": 1, "width": 32, "height": 136}, + "players_walking_running": {"frames": 18, "width": 16, "height": 32, "palette": VALID_OVERWORLD_PALETTE}, + "players_reflection": {"frames": 18, "width": 16, "height": 32, "palette": []}, + "players_mach_bike": {"frames": 9, "width": 32, "height": 32, "palette": VALID_OVERWORLD_PALETTE}, + "players_acro_bike": {"frames": 27, "width": 32, "height": 32, "palette": VALID_OVERWORLD_PALETTE}, + "players_surfing": {"frames": 12, "width": 32, "height": 32, "palette": VALID_OVERWORLD_PALETTE}, + "players_field_move": {"frames": 5, "width": 32, "height": 32, "palette": VALID_OVERWORLD_PALETTE}, + "players_underwater": {"frames": 9, "width": 32, "height": 32, + "palette": VALID_OVERWORLD_UNDERWATER_PALETTE}, + "players_fishing": {"frames": 12, "width": 32, "height": 32, "palette": VALID_OVERWORLD_PALETTE}, + "players_watering": {"frames": 9, "width": 32, "height": 32, "palette": VALID_OVERWORLD_PALETTE}, + "players_decorating": {"frames": 1, "width": 16, "height": 32, "palette": VALID_OVERWORLD_PALETTE}, + "players_battle_front": {"frames": 1, "width": 64, "height": 64}, + "players_battle_back": {"frames": [4, 5], "width": 64, "height": 64}, + "players_battle_back_throw": {"frames": [4, 5], "width": 64, "height": 64}, + "trainer_walking": {"frames": 9, "width": 16, "height": 32, "palette": VALID_WEAK_OVERWORLD_PALETTE}, + "trainer_battle_front": {"frames": 1, "width": 64, "height": 64}, +} + +EMERALD_SPRITES_REQUIREMENTS_EXCEPTIONS: dict[str, dict[str, dict[str, bool | int | list[int]]]] = { + "Castform": { + "pokemon_front_anim": {"frames": 4, "palette_size": 16, "palettes": 4, "palette_per_frame": True}, + "pokemon_back": {"frames": 4, "palette_size": 16, "palettes": 4, "palette_per_frame": True}, + }, + "Deoxys": { + "pokemon_back": {"frames": 2}, + "pokemon_icon": {"frames": 4}, + }, + "Unown A": { + "pokemon_front_anim": {"palette": VALID_UNOWN_PALETTE}, + "pokemon_back": {"palette": VALID_UNOWN_PALETTE}, + "pokemon_sfront_anim": {"palette": VALID_UNOWN_SHINY_PALETTE}, + "pokemon_sback": {"palette": VALID_UNOWN_SHINY_PALETTE}, + } +} \ No newline at end of file diff --git a/worlds/pokemon_emerald/data/extracted_data.json b/worlds/pokemon_emerald/data/extracted_data.json index f270637481cb..d066e31bcdf0 100644 --- a/worlds/pokemon_emerald/data/extracted_data.json +++ b/worlds/pokemon_emerald/data/extracted_data.json @@ -1 +1 @@ -{"_comment":"DO NOT MODIFY. This file was auto-generated. Your changes will likely be overwritten.","_rom_name":"pokemon emerald version / AP 5","constants":{"ABILITIES_COUNT":78,"ABILITY_AIR_LOCK":77,"ABILITY_ARENA_TRAP":71,"ABILITY_BATTLE_ARMOR":4,"ABILITY_BLAZE":66,"ABILITY_CACOPHONY":76,"ABILITY_CHLOROPHYLL":34,"ABILITY_CLEAR_BODY":29,"ABILITY_CLOUD_NINE":13,"ABILITY_COLOR_CHANGE":16,"ABILITY_COMPOUND_EYES":14,"ABILITY_CUTE_CHARM":56,"ABILITY_DAMP":6,"ABILITY_DRIZZLE":2,"ABILITY_DROUGHT":70,"ABILITY_EARLY_BIRD":48,"ABILITY_EFFECT_SPORE":27,"ABILITY_FLAME_BODY":49,"ABILITY_FLASH_FIRE":18,"ABILITY_FORECAST":59,"ABILITY_GUTS":62,"ABILITY_HUGE_POWER":37,"ABILITY_HUSTLE":55,"ABILITY_HYPER_CUTTER":52,"ABILITY_ILLUMINATE":35,"ABILITY_IMMUNITY":17,"ABILITY_INNER_FOCUS":39,"ABILITY_INSOMNIA":15,"ABILITY_INTIMIDATE":22,"ABILITY_KEEN_EYE":51,"ABILITY_LEVITATE":26,"ABILITY_LIGHTNING_ROD":31,"ABILITY_LIMBER":7,"ABILITY_LIQUID_OOZE":64,"ABILITY_MAGMA_ARMOR":40,"ABILITY_MAGNET_PULL":42,"ABILITY_MARVEL_SCALE":63,"ABILITY_MINUS":58,"ABILITY_NATURAL_CURE":30,"ABILITY_NONE":0,"ABILITY_OBLIVIOUS":12,"ABILITY_OVERGROW":65,"ABILITY_OWN_TEMPO":20,"ABILITY_PICKUP":53,"ABILITY_PLUS":57,"ABILITY_POISON_POINT":38,"ABILITY_PRESSURE":46,"ABILITY_PURE_POWER":74,"ABILITY_RAIN_DISH":44,"ABILITY_ROCK_HEAD":69,"ABILITY_ROUGH_SKIN":24,"ABILITY_RUN_AWAY":50,"ABILITY_SAND_STREAM":45,"ABILITY_SAND_VEIL":8,"ABILITY_SERENE_GRACE":32,"ABILITY_SHADOW_TAG":23,"ABILITY_SHED_SKIN":61,"ABILITY_SHELL_ARMOR":75,"ABILITY_SHIELD_DUST":19,"ABILITY_SOUNDPROOF":43,"ABILITY_SPEED_BOOST":3,"ABILITY_STATIC":9,"ABILITY_STENCH":1,"ABILITY_STICKY_HOLD":60,"ABILITY_STURDY":5,"ABILITY_SUCTION_CUPS":21,"ABILITY_SWARM":68,"ABILITY_SWIFT_SWIM":33,"ABILITY_SYNCHRONIZE":28,"ABILITY_THICK_FAT":47,"ABILITY_TORRENT":67,"ABILITY_TRACE":36,"ABILITY_TRUANT":54,"ABILITY_VITAL_SPIRIT":72,"ABILITY_VOLT_ABSORB":10,"ABILITY_WATER_ABSORB":11,"ABILITY_WATER_VEIL":41,"ABILITY_WHITE_SMOKE":73,"ABILITY_WONDER_GUARD":25,"ACRO_BIKE":1,"BAG_ITEM_CAPACITY_DIGITS":2,"BERRY_CAPACITY_DIGITS":3,"BERRY_FIRMNESS_HARD":3,"BERRY_FIRMNESS_SOFT":2,"BERRY_FIRMNESS_SUPER_HARD":5,"BERRY_FIRMNESS_UNKNOWN":0,"BERRY_FIRMNESS_VERY_HARD":4,"BERRY_FIRMNESS_VERY_SOFT":1,"BERRY_NONE":0,"BERRY_STAGE_BERRIES":5,"BERRY_STAGE_FLOWERING":4,"BERRY_STAGE_NO_BERRY":0,"BERRY_STAGE_PLANTED":1,"BERRY_STAGE_SPARKLING":255,"BERRY_STAGE_SPROUTED":2,"BERRY_STAGE_TALLER":3,"BERRY_TREES_COUNT":128,"BERRY_TREE_ROUTE_102_ORAN":2,"BERRY_TREE_ROUTE_102_PECHA":1,"BERRY_TREE_ROUTE_103_CHERI_1":5,"BERRY_TREE_ROUTE_103_CHERI_2":7,"BERRY_TREE_ROUTE_103_LEPPA":6,"BERRY_TREE_ROUTE_104_CHERI_1":8,"BERRY_TREE_ROUTE_104_CHERI_2":76,"BERRY_TREE_ROUTE_104_LEPPA":10,"BERRY_TREE_ROUTE_104_ORAN_1":4,"BERRY_TREE_ROUTE_104_ORAN_2":11,"BERRY_TREE_ROUTE_104_PECHA":13,"BERRY_TREE_ROUTE_104_SOIL_1":3,"BERRY_TREE_ROUTE_104_SOIL_2":9,"BERRY_TREE_ROUTE_104_SOIL_3":12,"BERRY_TREE_ROUTE_104_SOIL_4":75,"BERRY_TREE_ROUTE_110_NANAB_1":16,"BERRY_TREE_ROUTE_110_NANAB_2":17,"BERRY_TREE_ROUTE_110_NANAB_3":18,"BERRY_TREE_ROUTE_111_ORAN_1":80,"BERRY_TREE_ROUTE_111_ORAN_2":81,"BERRY_TREE_ROUTE_111_RAZZ_1":19,"BERRY_TREE_ROUTE_111_RAZZ_2":20,"BERRY_TREE_ROUTE_112_PECHA_1":22,"BERRY_TREE_ROUTE_112_PECHA_2":23,"BERRY_TREE_ROUTE_112_RAWST_1":21,"BERRY_TREE_ROUTE_112_RAWST_2":24,"BERRY_TREE_ROUTE_114_PERSIM_1":68,"BERRY_TREE_ROUTE_114_PERSIM_2":77,"BERRY_TREE_ROUTE_114_PERSIM_3":78,"BERRY_TREE_ROUTE_115_BLUK_1":55,"BERRY_TREE_ROUTE_115_BLUK_2":56,"BERRY_TREE_ROUTE_115_KELPSY_1":69,"BERRY_TREE_ROUTE_115_KELPSY_2":70,"BERRY_TREE_ROUTE_115_KELPSY_3":71,"BERRY_TREE_ROUTE_116_CHESTO_1":26,"BERRY_TREE_ROUTE_116_CHESTO_2":66,"BERRY_TREE_ROUTE_116_PINAP_1":25,"BERRY_TREE_ROUTE_116_PINAP_2":67,"BERRY_TREE_ROUTE_117_WEPEAR_1":27,"BERRY_TREE_ROUTE_117_WEPEAR_2":28,"BERRY_TREE_ROUTE_117_WEPEAR_3":29,"BERRY_TREE_ROUTE_118_SITRUS_1":31,"BERRY_TREE_ROUTE_118_SITRUS_2":33,"BERRY_TREE_ROUTE_118_SOIL":32,"BERRY_TREE_ROUTE_119_HONDEW_1":83,"BERRY_TREE_ROUTE_119_HONDEW_2":84,"BERRY_TREE_ROUTE_119_LEPPA":86,"BERRY_TREE_ROUTE_119_POMEG_1":34,"BERRY_TREE_ROUTE_119_POMEG_2":35,"BERRY_TREE_ROUTE_119_POMEG_3":36,"BERRY_TREE_ROUTE_119_SITRUS":85,"BERRY_TREE_ROUTE_120_ASPEAR_1":37,"BERRY_TREE_ROUTE_120_ASPEAR_2":38,"BERRY_TREE_ROUTE_120_ASPEAR_3":39,"BERRY_TREE_ROUTE_120_NANAB":44,"BERRY_TREE_ROUTE_120_PECHA_1":40,"BERRY_TREE_ROUTE_120_PECHA_2":41,"BERRY_TREE_ROUTE_120_PECHA_3":42,"BERRY_TREE_ROUTE_120_PINAP":45,"BERRY_TREE_ROUTE_120_RAZZ":43,"BERRY_TREE_ROUTE_120_WEPEAR":46,"BERRY_TREE_ROUTE_121_ASPEAR":48,"BERRY_TREE_ROUTE_121_CHESTO":50,"BERRY_TREE_ROUTE_121_NANAB_1":52,"BERRY_TREE_ROUTE_121_NANAB_2":53,"BERRY_TREE_ROUTE_121_PERSIM":47,"BERRY_TREE_ROUTE_121_RAWST":49,"BERRY_TREE_ROUTE_121_SOIL_1":51,"BERRY_TREE_ROUTE_121_SOIL_2":54,"BERRY_TREE_ROUTE_123_GREPA_1":60,"BERRY_TREE_ROUTE_123_GREPA_2":61,"BERRY_TREE_ROUTE_123_GREPA_3":65,"BERRY_TREE_ROUTE_123_GREPA_4":72,"BERRY_TREE_ROUTE_123_LEPPA_1":62,"BERRY_TREE_ROUTE_123_LEPPA_2":64,"BERRY_TREE_ROUTE_123_PECHA":87,"BERRY_TREE_ROUTE_123_POMEG_1":15,"BERRY_TREE_ROUTE_123_POMEG_2":30,"BERRY_TREE_ROUTE_123_POMEG_3":58,"BERRY_TREE_ROUTE_123_POMEG_4":59,"BERRY_TREE_ROUTE_123_QUALOT_1":14,"BERRY_TREE_ROUTE_123_QUALOT_2":73,"BERRY_TREE_ROUTE_123_QUALOT_3":74,"BERRY_TREE_ROUTE_123_QUALOT_4":79,"BERRY_TREE_ROUTE_123_RAWST":57,"BERRY_TREE_ROUTE_123_SITRUS":88,"BERRY_TREE_ROUTE_123_SOIL":63,"BERRY_TREE_ROUTE_130_LIECHI":82,"DAILY_FLAGS_END":2399,"DAILY_FLAGS_START":2336,"FIRST_BALL":1,"FIRST_BERRY_INDEX":133,"FIRST_BERRY_MASTER_BERRY":153,"FIRST_BERRY_MASTER_WIFE_BERRY":133,"FIRST_KIRI_BERRY":153,"FIRST_MAIL_INDEX":121,"FIRST_ROUTE_114_MAN_BERRY":148,"FLAGS_COUNT":2400,"FLAG_ADDED_MATCH_CALL_TO_POKENAV":304,"FLAG_ADVENTURE_STARTED":116,"FLAG_ARRIVED_AT_MARINE_CAVE_EMERGE_SPOT":2265,"FLAG_ARRIVED_AT_NAVEL_ROCK":2273,"FLAG_ARRIVED_AT_TERRA_CAVE_ENTRANCE":2266,"FLAG_ARRIVED_ON_FARAWAY_ISLAND":2264,"FLAG_BADGE01_GET":2151,"FLAG_BADGE02_GET":2152,"FLAG_BADGE03_GET":2153,"FLAG_BADGE04_GET":2154,"FLAG_BADGE05_GET":2155,"FLAG_BADGE06_GET":2156,"FLAG_BADGE07_GET":2157,"FLAG_BADGE08_GET":2158,"FLAG_BATTLE_FRONTIER_TRADE_DONE":156,"FLAG_BEAT_MAGMA_GRUNT_JAGGED_PASS":313,"FLAG_BEAUTY_PAINTING_MADE":161,"FLAG_BERRY_MASTERS_WIFE":1197,"FLAG_BERRY_MASTER_RECEIVED_BERRY_1":1195,"FLAG_BERRY_MASTER_RECEIVED_BERRY_2":1196,"FLAG_BERRY_TREES_START":612,"FLAG_BERRY_TREE_01":612,"FLAG_BERRY_TREE_02":613,"FLAG_BERRY_TREE_03":614,"FLAG_BERRY_TREE_04":615,"FLAG_BERRY_TREE_05":616,"FLAG_BERRY_TREE_06":617,"FLAG_BERRY_TREE_07":618,"FLAG_BERRY_TREE_08":619,"FLAG_BERRY_TREE_09":620,"FLAG_BERRY_TREE_10":621,"FLAG_BERRY_TREE_11":622,"FLAG_BERRY_TREE_12":623,"FLAG_BERRY_TREE_13":624,"FLAG_BERRY_TREE_14":625,"FLAG_BERRY_TREE_15":626,"FLAG_BERRY_TREE_16":627,"FLAG_BERRY_TREE_17":628,"FLAG_BERRY_TREE_18":629,"FLAG_BERRY_TREE_19":630,"FLAG_BERRY_TREE_20":631,"FLAG_BERRY_TREE_21":632,"FLAG_BERRY_TREE_22":633,"FLAG_BERRY_TREE_23":634,"FLAG_BERRY_TREE_24":635,"FLAG_BERRY_TREE_25":636,"FLAG_BERRY_TREE_26":637,"FLAG_BERRY_TREE_27":638,"FLAG_BERRY_TREE_28":639,"FLAG_BERRY_TREE_29":640,"FLAG_BERRY_TREE_30":641,"FLAG_BERRY_TREE_31":642,"FLAG_BERRY_TREE_32":643,"FLAG_BERRY_TREE_33":644,"FLAG_BERRY_TREE_34":645,"FLAG_BERRY_TREE_35":646,"FLAG_BERRY_TREE_36":647,"FLAG_BERRY_TREE_37":648,"FLAG_BERRY_TREE_38":649,"FLAG_BERRY_TREE_39":650,"FLAG_BERRY_TREE_40":651,"FLAG_BERRY_TREE_41":652,"FLAG_BERRY_TREE_42":653,"FLAG_BERRY_TREE_43":654,"FLAG_BERRY_TREE_44":655,"FLAG_BERRY_TREE_45":656,"FLAG_BERRY_TREE_46":657,"FLAG_BERRY_TREE_47":658,"FLAG_BERRY_TREE_48":659,"FLAG_BERRY_TREE_49":660,"FLAG_BERRY_TREE_50":661,"FLAG_BERRY_TREE_51":662,"FLAG_BERRY_TREE_52":663,"FLAG_BERRY_TREE_53":664,"FLAG_BERRY_TREE_54":665,"FLAG_BERRY_TREE_55":666,"FLAG_BERRY_TREE_56":667,"FLAG_BERRY_TREE_57":668,"FLAG_BERRY_TREE_58":669,"FLAG_BERRY_TREE_59":670,"FLAG_BERRY_TREE_60":671,"FLAG_BERRY_TREE_61":672,"FLAG_BERRY_TREE_62":673,"FLAG_BERRY_TREE_63":674,"FLAG_BERRY_TREE_64":675,"FLAG_BERRY_TREE_65":676,"FLAG_BERRY_TREE_66":677,"FLAG_BERRY_TREE_67":678,"FLAG_BERRY_TREE_68":679,"FLAG_BERRY_TREE_69":680,"FLAG_BERRY_TREE_70":681,"FLAG_BERRY_TREE_71":682,"FLAG_BERRY_TREE_72":683,"FLAG_BERRY_TREE_73":684,"FLAG_BERRY_TREE_74":685,"FLAG_BERRY_TREE_75":686,"FLAG_BERRY_TREE_76":687,"FLAG_BERRY_TREE_77":688,"FLAG_BERRY_TREE_78":689,"FLAG_BERRY_TREE_79":690,"FLAG_BERRY_TREE_80":691,"FLAG_BERRY_TREE_81":692,"FLAG_BERRY_TREE_82":693,"FLAG_BERRY_TREE_83":694,"FLAG_BERRY_TREE_84":695,"FLAG_BERRY_TREE_85":696,"FLAG_BERRY_TREE_86":697,"FLAG_BERRY_TREE_87":698,"FLAG_BERRY_TREE_88":699,"FLAG_BETTER_SHOPS_ENABLED":206,"FLAG_BIRCH_AIDE_MET":88,"FLAG_CANCEL_BATTLE_ROOM_CHALLENGE":119,"FLAG_CAUGHT_DEOXYS":429,"FLAG_CAUGHT_GROUDON":480,"FLAG_CAUGHT_HO_OH":146,"FLAG_CAUGHT_KYOGRE":479,"FLAG_CAUGHT_LATIAS":457,"FLAG_CAUGHT_LATIOS":482,"FLAG_CAUGHT_LUGIA":145,"FLAG_CAUGHT_MEW":458,"FLAG_CAUGHT_RAYQUAZA":478,"FLAG_CAUGHT_REGICE":427,"FLAG_CAUGHT_REGIROCK":426,"FLAG_CAUGHT_REGISTEEL":483,"FLAG_CHOSEN_MULTI_BATTLE_NPC_PARTNER":338,"FLAG_CHOSE_CLAW_FOSSIL":336,"FLAG_CHOSE_ROOT_FOSSIL":335,"FLAG_COLLECTED_ALL_GOLD_SYMBOLS":466,"FLAG_COLLECTED_ALL_SILVER_SYMBOLS":92,"FLAG_CONTEST_SKETCH_CREATED":270,"FLAG_COOL_PAINTING_MADE":160,"FLAG_CUTE_PAINTING_MADE":162,"FLAG_DAILY_APPRENTICE_LEAVES":2356,"FLAG_DAILY_BERRY_MASTERS_WIFE":2353,"FLAG_DAILY_BERRY_MASTER_RECEIVED_BERRY":2349,"FLAG_DAILY_CONTEST_LOBBY_RECEIVED_BERRY":2337,"FLAG_DAILY_FLOWER_SHOP_RECEIVED_BERRY":2352,"FLAG_DAILY_LILYCOVE_RECEIVED_BERRY":2351,"FLAG_DAILY_PICKED_LOTO_TICKET":2346,"FLAG_DAILY_ROUTE_111_RECEIVED_BERRY":2348,"FLAG_DAILY_ROUTE_114_RECEIVED_BERRY":2347,"FLAG_DAILY_ROUTE_120_RECEIVED_BERRY":2350,"FLAG_DAILY_SECRET_BASE":2338,"FLAG_DAILY_SOOTOPOLIS_RECEIVED_BERRY":2354,"FLAG_DECLINED_BIKE":89,"FLAG_DECLINED_RIVAL_BATTLE_LILYCOVE":286,"FLAG_DECLINED_WALLY_BATTLE_MAUVILLE":284,"FLAG_DECORATION_1":174,"FLAG_DECORATION_10":183,"FLAG_DECORATION_11":184,"FLAG_DECORATION_12":185,"FLAG_DECORATION_13":186,"FLAG_DECORATION_14":187,"FLAG_DECORATION_2":175,"FLAG_DECORATION_3":176,"FLAG_DECORATION_4":177,"FLAG_DECORATION_5":178,"FLAG_DECORATION_6":179,"FLAG_DECORATION_7":180,"FLAG_DECORATION_8":181,"FLAG_DECORATION_9":182,"FLAG_DEFEATED_DEOXYS":428,"FLAG_DEFEATED_DEWFORD_GYM":1265,"FLAG_DEFEATED_ELECTRODE_1_AQUA_HIDEOUT":452,"FLAG_DEFEATED_ELECTRODE_2_AQUA_HIDEOUT":453,"FLAG_DEFEATED_ELITE_4_DRAKE":1278,"FLAG_DEFEATED_ELITE_4_GLACIA":1277,"FLAG_DEFEATED_ELITE_4_PHOEBE":1276,"FLAG_DEFEATED_ELITE_4_SIDNEY":1275,"FLAG_DEFEATED_EVIL_TEAM_MT_CHIMNEY":139,"FLAG_DEFEATED_FORTREE_GYM":1269,"FLAG_DEFEATED_GROUDON":447,"FLAG_DEFEATED_GRUNT_SPACE_CENTER_1F":191,"FLAG_DEFEATED_HO_OH":476,"FLAG_DEFEATED_KECLEON_1_ROUTE_119":989,"FLAG_DEFEATED_KECLEON_1_ROUTE_120":982,"FLAG_DEFEATED_KECLEON_2_ROUTE_119":990,"FLAG_DEFEATED_KECLEON_2_ROUTE_120":985,"FLAG_DEFEATED_KECLEON_3_ROUTE_120":986,"FLAG_DEFEATED_KECLEON_4_ROUTE_120":987,"FLAG_DEFEATED_KECLEON_5_ROUTE_120":988,"FLAG_DEFEATED_KEKLEON_ROUTE_120_BRIDGE":970,"FLAG_DEFEATED_KYOGRE":446,"FLAG_DEFEATED_LATIAS":456,"FLAG_DEFEATED_LATIOS":481,"FLAG_DEFEATED_LAVARIDGE_GYM":1267,"FLAG_DEFEATED_LUGIA":477,"FLAG_DEFEATED_MAGMA_SPACE_CENTER":117,"FLAG_DEFEATED_MAUVILLE_GYM":1266,"FLAG_DEFEATED_METEOR_FALLS_STEVEN":1272,"FLAG_DEFEATED_MEW":455,"FLAG_DEFEATED_MOSSDEEP_GYM":1270,"FLAG_DEFEATED_PETALBURG_GYM":1268,"FLAG_DEFEATED_RAYQUAZA":448,"FLAG_DEFEATED_REGICE":444,"FLAG_DEFEATED_REGIROCK":443,"FLAG_DEFEATED_REGISTEEL":445,"FLAG_DEFEATED_RIVAL_ROUTE103":130,"FLAG_DEFEATED_RIVAL_ROUTE_104":125,"FLAG_DEFEATED_RIVAL_RUSTBORO":211,"FLAG_DEFEATED_RUSTBORO_GYM":1264,"FLAG_DEFEATED_SEASHORE_HOUSE":141,"FLAG_DEFEATED_SOOTOPOLIS_GYM":1271,"FLAG_DEFEATED_SS_TIDAL_TRAINERS":247,"FLAG_DEFEATED_SUDOWOODO":454,"FLAG_DEFEATED_VOLTORB_1_NEW_MAUVILLE":449,"FLAG_DEFEATED_VOLTORB_2_NEW_MAUVILLE":450,"FLAG_DEFEATED_VOLTORB_3_NEW_MAUVILLE":451,"FLAG_DEFEATED_WALLY_MAUVILLE":190,"FLAG_DEFEATED_WALLY_VICTORY_ROAD":126,"FLAG_DELIVERED_DEVON_GOODS":149,"FLAG_DELIVERED_STEVEN_LETTER":189,"FLAG_DEOXYS_IS_RECOVERING":1258,"FLAG_DEOXYS_ROCK_COMPLETE":2260,"FLAG_DEVON_GOODS_STOLEN":142,"FLAG_DOCK_REJECTED_DEVON_GOODS":148,"FLAG_DONT_TRANSITION_MUSIC":16385,"FLAG_ENABLE_BRAWLY_MATCH_CALL":468,"FLAG_ENABLE_FIRST_WALLY_POKENAV_CALL":136,"FLAG_ENABLE_FLANNERY_MATCH_CALL":470,"FLAG_ENABLE_JUAN_MATCH_CALL":473,"FLAG_ENABLE_MOM_MATCH_CALL":216,"FLAG_ENABLE_MR_STONE_POKENAV":344,"FLAG_ENABLE_MULTI_CORRIDOR_DOOR":16386,"FLAG_ENABLE_NORMAN_MATCH_CALL":306,"FLAG_ENABLE_PROF_BIRCH_MATCH_CALL":281,"FLAG_ENABLE_RIVAL_MATCH_CALL":253,"FLAG_ENABLE_ROXANNE_FIRST_CALL":128,"FLAG_ENABLE_ROXANNE_MATCH_CALL":467,"FLAG_ENABLE_SCOTT_MATCH_CALL":215,"FLAG_ENABLE_SHIP_BIRTH_ISLAND":2261,"FLAG_ENABLE_SHIP_FARAWAY_ISLAND":2262,"FLAG_ENABLE_SHIP_NAVEL_ROCK":2272,"FLAG_ENABLE_SHIP_SOUTHERN_ISLAND":2227,"FLAG_ENABLE_TATE_AND_LIZA_MATCH_CALL":472,"FLAG_ENABLE_WALLY_MATCH_CALL":214,"FLAG_ENABLE_WATTSON_MATCH_CALL":469,"FLAG_ENABLE_WINONA_MATCH_CALL":471,"FLAG_ENTERED_CONTEST":341,"FLAG_ENTERED_ELITE_FOUR":263,"FLAG_ENTERED_MIRAGE_TOWER":2268,"FLAG_EVIL_LEADER_PLEASE_STOP":219,"FLAG_EVIL_TEAM_ESCAPED_STERN_SPOKE":271,"FLAG_EXCHANGED_SCANNER":294,"FLAG_FAN_CLUB_STRENGTH_SHARED":210,"FLAG_FLOWER_SHOP_RECEIVED_BERRY":1207,"FLAG_FORCE_MIRAGE_TOWER_VISIBLE":157,"FLAG_FORTREE_NPC_TRADE_COMPLETED":155,"FLAG_GOOD_LUCK_SAFARI_ZONE":93,"FLAG_GOT_BASEMENT_KEY_FROM_WATTSON":208,"FLAG_GOT_TM_THUNDERBOLT_FROM_WATTSON":209,"FLAG_GROUDON_AWAKENED_MAGMA_HIDEOUT":111,"FLAG_GROUDON_IS_RECOVERING":1274,"FLAG_HAS_MATCH_CALL":303,"FLAG_HIDDEN_ITEMS_START":500,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":531,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":532,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":533,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":534,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":601,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":604,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":603,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":602,"FLAG_HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":528,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":548,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":549,"FLAG_HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":577,"FLAG_HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":576,"FLAG_HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":500,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":527,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":575,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":543,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":578,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":529,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":580,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":579,"FLAG_HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":609,"FLAG_HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":595,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":561,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POTION":558,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":559,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":560,"FLAG_HIDDEN_ITEM_ROUTE_104_ANTIDOTE":585,"FLAG_HIDDEN_ITEM_ROUTE_104_HEART_SCALE":588,"FLAG_HIDDEN_ITEM_ROUTE_104_POKE_BALL":562,"FLAG_HIDDEN_ITEM_ROUTE_104_POTION":537,"FLAG_HIDDEN_ITEM_ROUTE_104_SUPER_POTION":544,"FLAG_HIDDEN_ITEM_ROUTE_105_BIG_PEARL":611,"FLAG_HIDDEN_ITEM_ROUTE_105_HEART_SCALE":589,"FLAG_HIDDEN_ITEM_ROUTE_106_HEART_SCALE":547,"FLAG_HIDDEN_ITEM_ROUTE_106_POKE_BALL":563,"FLAG_HIDDEN_ITEM_ROUTE_106_STARDUST":546,"FLAG_HIDDEN_ITEM_ROUTE_108_RARE_CANDY":586,"FLAG_HIDDEN_ITEM_ROUTE_109_ETHER":564,"FLAG_HIDDEN_ITEM_ROUTE_109_GREAT_BALL":551,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":552,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":590,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":591,"FLAG_HIDDEN_ITEM_ROUTE_109_REVIVE":550,"FLAG_HIDDEN_ITEM_ROUTE_110_FULL_HEAL":555,"FLAG_HIDDEN_ITEM_ROUTE_110_GREAT_BALL":553,"FLAG_HIDDEN_ITEM_ROUTE_110_POKE_BALL":565,"FLAG_HIDDEN_ITEM_ROUTE_110_REVIVE":554,"FLAG_HIDDEN_ITEM_ROUTE_111_PROTEIN":556,"FLAG_HIDDEN_ITEM_ROUTE_111_RARE_CANDY":557,"FLAG_HIDDEN_ITEM_ROUTE_111_STARDUST":502,"FLAG_HIDDEN_ITEM_ROUTE_113_ETHER":503,"FLAG_HIDDEN_ITEM_ROUTE_113_NUGGET":598,"FLAG_HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":530,"FLAG_HIDDEN_ITEM_ROUTE_114_CARBOS":504,"FLAG_HIDDEN_ITEM_ROUTE_114_REVIVE":542,"FLAG_HIDDEN_ITEM_ROUTE_115_HEART_SCALE":597,"FLAG_HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":596,"FLAG_HIDDEN_ITEM_ROUTE_116_SUPER_POTION":545,"FLAG_HIDDEN_ITEM_ROUTE_117_REPEL":572,"FLAG_HIDDEN_ITEM_ROUTE_118_HEART_SCALE":566,"FLAG_HIDDEN_ITEM_ROUTE_118_IRON":567,"FLAG_HIDDEN_ITEM_ROUTE_119_CALCIUM":505,"FLAG_HIDDEN_ITEM_ROUTE_119_FULL_HEAL":568,"FLAG_HIDDEN_ITEM_ROUTE_119_MAX_ETHER":587,"FLAG_HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":506,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":571,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":569,"FLAG_HIDDEN_ITEM_ROUTE_120_REVIVE":584,"FLAG_HIDDEN_ITEM_ROUTE_120_ZINC":570,"FLAG_HIDDEN_ITEM_ROUTE_121_FULL_HEAL":573,"FLAG_HIDDEN_ITEM_ROUTE_121_HP_UP":539,"FLAG_HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":600,"FLAG_HIDDEN_ITEM_ROUTE_121_NUGGET":540,"FLAG_HIDDEN_ITEM_ROUTE_123_HYPER_POTION":574,"FLAG_HIDDEN_ITEM_ROUTE_123_PP_UP":599,"FLAG_HIDDEN_ITEM_ROUTE_123_RARE_CANDY":610,"FLAG_HIDDEN_ITEM_ROUTE_123_REVIVE":541,"FLAG_HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":507,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":592,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":593,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":594,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":606,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":607,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":605,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":608,"FLAG_HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":535,"FLAG_HIDDEN_ITEM_TRICK_HOUSE_NUGGET":501,"FLAG_HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":511,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CALCIUM":536,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CARBOS":508,"FLAG_HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":509,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":513,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":538,"FLAG_HIDDEN_ITEM_UNDERWATER_124_PEARL":510,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":520,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":512,"FLAG_HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":514,"FLAG_HIDDEN_ITEM_UNDERWATER_126_IRON":519,"FLAG_HIDDEN_ITEM_UNDERWATER_126_PEARL":517,"FLAG_HIDDEN_ITEM_UNDERWATER_126_STARDUST":516,"FLAG_HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":515,"FLAG_HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":518,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":523,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HP_UP":522,"FLAG_HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":524,"FLAG_HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":521,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PEARL":526,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PROTEIN":525,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":581,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":582,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":583,"FLAG_HIDE_APPRENTICE":701,"FLAG_HIDE_AQUA_HIDEOUT_1F_GRUNTS_BLOCKING_ENTRANCE":821,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_1":977,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_2":978,"FLAG_HIDE_AQUA_HIDEOUT_B2F_SUBMARINE_SHADOW":943,"FLAG_HIDE_AQUA_HIDEOUT_GRUNTS":924,"FLAG_HIDE_BATTLE_FRONTIER_RECEPTION_GATE_SCOTT":836,"FLAG_HIDE_BATTLE_FRONTIER_SUDOWOODO":842,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_1":711,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_2":712,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_3":713,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_4":714,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_5":715,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_6":716,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_1":864,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_2":865,"FLAG_HIDE_BATTLE_TOWER_OPPONENT":888,"FLAG_HIDE_BATTLE_TOWER_REPORTER":918,"FLAG_HIDE_BIRTH_ISLAND_DEOXYS_TRIANGLE":764,"FLAG_HIDE_BRINEYS_HOUSE_MR_BRINEY":739,"FLAG_HIDE_BRINEYS_HOUSE_PEEKO":881,"FLAG_HIDE_CAVE_OF_ORIGIN_B1F_WALLACE":820,"FLAG_HIDE_CHAMPIONS_ROOM_BIRCH":921,"FLAG_HIDE_CHAMPIONS_ROOM_RIVAL":920,"FLAG_HIDE_CONTEST_POKE_BALL":86,"FLAG_HIDE_DEOXYS":763,"FLAG_HIDE_DESERT_UNDERPASS_FOSSIL":874,"FLAG_HIDE_DEWFORD_HALL_SLUDGE_BOMB_MAN":940,"FLAG_HIDE_EVER_GRANDE_POKEMON_CENTER_1F_SCOTT":793,"FLAG_HIDE_FALLARBOR_AZURILL":907,"FLAG_HIDE_FALLARBOR_HOUSE_PROF_COZMO":928,"FLAG_HIDE_FALLARBOR_TOWN_BATTLE_TENT_SCOTT":767,"FLAG_HIDE_FALLORBOR_POKEMON_CENTER_LANETTE":871,"FLAG_HIDE_FANCLUB_BOY":790,"FLAG_HIDE_FANCLUB_LADY":792,"FLAG_HIDE_FANCLUB_LITTLE_BOY":791,"FLAG_HIDE_FANCLUB_OLD_LADY":789,"FLAG_HIDE_FORTREE_CITY_HOUSE_4_WINGULL":933,"FLAG_HIDE_FORTREE_CITY_KECLEON":969,"FLAG_HIDE_GRANITE_CAVE_STEVEN":833,"FLAG_HIDE_HO_OH":801,"FLAG_HIDE_JAGGED_PASS_MAGMA_GUARD":847,"FLAG_HIDE_LANETTES_HOUSE_LANETTE":870,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL":929,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL_ON_BIKE":930,"FLAG_HIDE_LILYCOVE_CITY_AQUA_GRUNTS":852,"FLAG_HIDE_LILYCOVE_CITY_RIVAL":971,"FLAG_HIDE_LILYCOVE_CITY_WAILMER":729,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER":832,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER_REPLACEMENT":873,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_1":774,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_2":895,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_REPORTER":802,"FLAG_HIDE_LILYCOVE_DEPARTMENT_STORE_ROOFTOP_SALE_WOMAN":962,"FLAG_HIDE_LILYCOVE_FAN_CLUB_INTERVIEWER":730,"FLAG_HIDE_LILYCOVE_HARBOR_EVENT_TICKET_TAKER":748,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_ATTENDANT":908,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_SAILOR":909,"FLAG_HIDE_LILYCOVE_HARBOR_SSTIDAL":861,"FLAG_HIDE_LILYCOVE_MOTEL_GAME_DESIGNERS":925,"FLAG_HIDE_LILYCOVE_MOTEL_SCOTT":787,"FLAG_HIDE_LILYCOVE_MUSEUM_CURATOR":775,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_1":776,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_2":777,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_3":778,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_4":779,"FLAG_HIDE_LILYCOVE_MUSEUM_TOURISTS":780,"FLAG_HIDE_LILYCOVE_POKEMON_CENTER_CONTEST_LADY_MON":993,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCH":795,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_BIRCH":721,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CHIKORITA":838,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CYNDAQUIL":811,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_TOTODILE":812,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_RIVAL":889,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_UNKNOWN_0x380":896,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_POKE_BALL":817,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_SWABLU_DOLL":815,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_BRENDAN":745,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_MOM":758,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_BEDROOM":760,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_MOM":784,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_SIBLING":735,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_TRUCK":761,"FLAG_HIDE_LITTLEROOT_TOWN_FAT_MAN":868,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_PICHU_DOLL":849,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_POKE_BALL":818,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MAY":746,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MOM":759,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_BEDROOM":722,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_MOM":785,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_SIBLING":736,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_TRUCK":762,"FLAG_HIDE_LITTLEROOT_TOWN_MOM_OUTSIDE":752,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_BEDROOM_MOM":757,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_1":754,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_2":755,"FLAG_HIDE_LITTLEROOT_TOWN_RIVAL":794,"FLAG_HIDE_LUGIA":800,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON":853,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON_ASLEEP":850,"FLAG_HIDE_MAGMA_HIDEOUT_GRUNTS":857,"FLAG_HIDE_MAGMA_HIDEOUT_MAXIE":867,"FLAG_HIDE_MAP_NAME_POPUP":16384,"FLAG_HIDE_MARINE_CAVE_KYOGRE":782,"FLAG_HIDE_MAUVILLE_CITY_SCOTT":765,"FLAG_HIDE_MAUVILLE_CITY_WALLY":804,"FLAG_HIDE_MAUVILLE_CITY_WALLYS_UNCLE":805,"FLAG_HIDE_MAUVILLE_CITY_WATTSON":912,"FLAG_HIDE_MAUVILLE_GYM_WATTSON":913,"FLAG_HIDE_METEOR_FALLS_1F_1R_COZMO":942,"FLAG_HIDE_METEOR_FALLS_TEAM_AQUA":938,"FLAG_HIDE_METEOR_FALLS_TEAM_MAGMA":939,"FLAG_HIDE_MEW":718,"FLAG_HIDE_MIRAGE_TOWER_CLAW_FOSSIL":964,"FLAG_HIDE_MIRAGE_TOWER_ROOT_FOSSIL":963,"FLAG_HIDE_MOSSDEEP_CITY_HOUSE_2_WINGULL":934,"FLAG_HIDE_MOSSDEEP_CITY_SCOTT":788,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_STEVEN":753,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_TEAM_MAGMA":756,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_STEVEN":863,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_TEAM_MAGMA":862,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_MAGMA_NOTE":737,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_BELDUM_POKEBALL":968,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_INVISIBLE_NINJA_BOY":727,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_STEVEN":967,"FLAG_HIDE_MOSSDEEP_CITY_TEAM_MAGMA":823,"FLAG_HIDE_MR_BRINEY_BOAT_DEWFORD_TOWN":743,"FLAG_HIDE_MR_BRINEY_DEWFORD_TOWN":740,"FLAG_HIDE_MT_CHIMNEY_LAVA_COOKIE_LADY":994,"FLAG_HIDE_MT_CHIMNEY_TEAM_AQUA":926,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA":927,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA_BATTLEABLE":981,"FLAG_HIDE_MT_CHIMNEY_TRAINERS":877,"FLAG_HIDE_MT_PYRE_SUMMIT_ARCHIE":916,"FLAG_HIDE_MT_PYRE_SUMMIT_MAXIE":856,"FLAG_HIDE_MT_PYRE_SUMMIT_TEAM_AQUA":917,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_1":974,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_2":975,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_3":976,"FLAG_HIDE_OLDALE_TOWN_RIVAL":979,"FLAG_HIDE_PETALBURG_CITY_SCOTT":995,"FLAG_HIDE_PETALBURG_CITY_WALLY":726,"FLAG_HIDE_PETALBURG_CITY_WALLYS_DAD":830,"FLAG_HIDE_PETALBURG_CITY_WALLYS_MOM":728,"FLAG_HIDE_PETALBURG_GYM_GREETER":781,"FLAG_HIDE_PETALBURG_GYM_NORMAN":772,"FLAG_HIDE_PETALBURG_GYM_WALLY":866,"FLAG_HIDE_PETALBURG_GYM_WALLYS_DAD":824,"FLAG_HIDE_PETALBURG_WOODS_AQUA_GRUNT":725,"FLAG_HIDE_PETALBURG_WOODS_DEVON_EMPLOYEE":724,"FLAG_HIDE_PLAYERS_HOUSE_DAD":734,"FLAG_HIDE_POKEMON_CENTER_2F_MYSTERY_GIFT_MAN":702,"FLAG_HIDE_REGICE":936,"FLAG_HIDE_REGIROCK":935,"FLAG_HIDE_REGISTEEL":937,"FLAG_HIDE_ROUTE_101_BIRCH":897,"FLAG_HIDE_ROUTE_101_BIRCH_STARTERS_BAG":700,"FLAG_HIDE_ROUTE_101_BIRCH_ZIGZAGOON_BATTLE":720,"FLAG_HIDE_ROUTE_101_BOY":991,"FLAG_HIDE_ROUTE_101_ZIGZAGOON":750,"FLAG_HIDE_ROUTE_103_BIRCH":898,"FLAG_HIDE_ROUTE_103_RIVAL":723,"FLAG_HIDE_ROUTE_104_MR_BRINEY":738,"FLAG_HIDE_ROUTE_104_MR_BRINEY_BOAT":742,"FLAG_HIDE_ROUTE_104_RIVAL":719,"FLAG_HIDE_ROUTE_104_WHITE_HERB_FLORIST":906,"FLAG_HIDE_ROUTE_109_MR_BRINEY":741,"FLAG_HIDE_ROUTE_109_MR_BRINEY_BOAT":744,"FLAG_HIDE_ROUTE_110_BIRCH":837,"FLAG_HIDE_ROUTE_110_RIVAL":919,"FLAG_HIDE_ROUTE_110_RIVAL_ON_BIKE":922,"FLAG_HIDE_ROUTE_110_TEAM_AQUA":900,"FLAG_HIDE_ROUTE_111_DESERT_FOSSIL":876,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_1":796,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_2":903,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_3":799,"FLAG_HIDE_ROUTE_111_PLAYER_DESCENT":875,"FLAG_HIDE_ROUTE_111_ROCK_SMASH_TIP_GUY":843,"FLAG_HIDE_ROUTE_111_SECRET_POWER_MAN":960,"FLAG_HIDE_ROUTE_111_VICKY_WINSTRATE":771,"FLAG_HIDE_ROUTE_111_VICTORIA_WINSTRATE":769,"FLAG_HIDE_ROUTE_111_VICTOR_WINSTRATE":768,"FLAG_HIDE_ROUTE_111_VIVI_WINSTRATE":770,"FLAG_HIDE_ROUTE_112_TEAM_MAGMA":819,"FLAG_HIDE_ROUTE_115_BOULDERS":825,"FLAG_HIDE_ROUTE_116_DEVON_EMPLOYEE":947,"FLAG_HIDE_ROUTE_116_DROPPED_GLASSES_MAN":813,"FLAG_HIDE_ROUTE_116_MR_BRINEY":891,"FLAG_HIDE_ROUTE_116_WANDAS_BOYFRIEND":894,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_1":797,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_2":901,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_3":904,"FLAG_HIDE_ROUTE_118_STEVEN":966,"FLAG_HIDE_ROUTE_119_RIVAL":851,"FLAG_HIDE_ROUTE_119_RIVAL_ON_BIKE":923,"FLAG_HIDE_ROUTE_119_SCOTT":786,"FLAG_HIDE_ROUTE_119_TEAM_AQUA":890,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_BRIDGE":822,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_SHELLY":915,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_1":798,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_2":902,"FLAG_HIDE_ROUTE_120_STEVEN":972,"FLAG_HIDE_ROUTE_121_TEAM_AQUA_GRUNTS":914,"FLAG_HIDE_ROUTE_128_ARCHIE":944,"FLAG_HIDE_ROUTE_128_MAXIE":945,"FLAG_HIDE_ROUTE_128_STEVEN":834,"FLAG_HIDE_RUSTBORO_CITY_AQUA_GRUNT":731,"FLAG_HIDE_RUSTBORO_CITY_DEVON_CORP_3F_EMPLOYEE":949,"FLAG_HIDE_RUSTBORO_CITY_DEVON_EMPLOYEE_1":732,"FLAG_HIDE_RUSTBORO_CITY_POKEMON_SCHOOL_SCOTT":999,"FLAG_HIDE_RUSTBORO_CITY_RIVAL":814,"FLAG_HIDE_RUSTBORO_CITY_SCIENTIST":844,"FLAG_HIDE_RUSTURF_TUNNEL_AQUA_GRUNT":878,"FLAG_HIDE_RUSTURF_TUNNEL_BRINEY":879,"FLAG_HIDE_RUSTURF_TUNNEL_PEEKO":880,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_1":931,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_2":932,"FLAG_HIDE_RUSTURF_TUNNEL_WANDA":983,"FLAG_HIDE_RUSTURF_TUNNEL_WANDAS_BOYFRIEND":807,"FLAG_HIDE_SAFARI_ZONE_SOUTH_CONSTRUCTION_WORKERS":717,"FLAG_HIDE_SAFARI_ZONE_SOUTH_EAST_EXPANSION":747,"FLAG_HIDE_SEAFLOOR_CAVERN_AQUA_GRUNTS":946,"FLAG_HIDE_SEAFLOOR_CAVERN_ENTRANCE_AQUA_GRUNT":941,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_ARCHIE":828,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE":859,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE_ASLEEP":733,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAGMA_GRUNTS":831,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAXIE":829,"FLAG_HIDE_SECRET_BASE_TRAINER":173,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA":773,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA_STILL":80,"FLAG_HIDE_SKY_PILLAR_WALLACE":855,"FLAG_HIDE_SLATEPORT_CITY_CAPTAIN_STERN":840,"FLAG_HIDE_SLATEPORT_CITY_CONTEST_REPORTER":803,"FLAG_HIDE_SLATEPORT_CITY_GABBY_AND_TY":835,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_AQUA_GRUNT":845,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_ARCHIE":846,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_CAPTAIN_STERN":841,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_PATRONS":905,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SS_TIDAL":860,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SUBMARINE_SHADOW":848,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_1":884,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_2":885,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_ARCHIE":886,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_CAPTAIN_STERN":887,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_AQUA_GRUNTS":883,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_FAMILIAR_AQUA_GRUNT":965,"FLAG_HIDE_SLATEPORT_CITY_SCOTT":749,"FLAG_HIDE_SLATEPORT_CITY_STERNS_SHIPYARD_MR_BRINEY":869,"FLAG_HIDE_SLATEPORT_CITY_TEAM_AQUA":882,"FLAG_HIDE_SLATEPORT_CITY_TM_SALESMAN":948,"FLAG_HIDE_SLATEPORT_MUSEUM_POPULATION":961,"FLAG_HIDE_SOOTOPOLIS_CITY_ARCHIE":826,"FLAG_HIDE_SOOTOPOLIS_CITY_GROUDON":998,"FLAG_HIDE_SOOTOPOLIS_CITY_KYOGRE":997,"FLAG_HIDE_SOOTOPOLIS_CITY_MAN_1":839,"FLAG_HIDE_SOOTOPOLIS_CITY_MAXIE":827,"FLAG_HIDE_SOOTOPOLIS_CITY_RAYQUAZA":996,"FLAG_HIDE_SOOTOPOLIS_CITY_RESIDENTS":854,"FLAG_HIDE_SOOTOPOLIS_CITY_STEVEN":973,"FLAG_HIDE_SOOTOPOLIS_CITY_WALLACE":816,"FLAG_HIDE_SOUTHERN_ISLAND_EON_STONE":910,"FLAG_HIDE_SOUTHERN_ISLAND_UNCHOSEN_EON_DUO_MON":911,"FLAG_HIDE_SS_TIDAL_CORRIDOR_MR_BRINEY":950,"FLAG_HIDE_SS_TIDAL_CORRIDOR_SCOTT":810,"FLAG_HIDE_SS_TIDAL_ROOMS_SNATCH_GIVER":951,"FLAG_HIDE_TERRA_CAVE_GROUDON":783,"FLAG_HIDE_TRICK_HOUSE_END_MAN":899,"FLAG_HIDE_TRICK_HOUSE_ENTRANCE_MAN":872,"FLAG_HIDE_UNDERWATER_SEA_FLOOR_CAVERN_STOLEN_SUBMARINE":980,"FLAG_HIDE_UNION_ROOM_PLAYER_1":703,"FLAG_HIDE_UNION_ROOM_PLAYER_2":704,"FLAG_HIDE_UNION_ROOM_PLAYER_3":705,"FLAG_HIDE_UNION_ROOM_PLAYER_4":706,"FLAG_HIDE_UNION_ROOM_PLAYER_5":707,"FLAG_HIDE_UNION_ROOM_PLAYER_6":708,"FLAG_HIDE_UNION_ROOM_PLAYER_7":709,"FLAG_HIDE_UNION_ROOM_PLAYER_8":710,"FLAG_HIDE_VERDANTURF_TOWN_SCOTT":766,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLY":806,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLYS_UNCLE":809,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDA":984,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDAS_BOYFRIEND":808,"FLAG_HIDE_VICTORY_ROAD_ENTRANCE_WALLY":858,"FLAG_HIDE_VICTORY_ROAD_EXIT_WALLY":751,"FLAG_HIDE_WEATHER_INSTITUTE_1F_WORKERS":892,"FLAG_HIDE_WEATHER_INSTITUTE_2F_AQUA_GRUNT_M":992,"FLAG_HIDE_WEATHER_INSTITUTE_2F_WORKERS":893,"FLAG_HO_OH_IS_RECOVERING":1256,"FLAG_INTERACTED_WITH_DEVON_EMPLOYEE_GOODS_STOLEN":159,"FLAG_INTERACTED_WITH_STEVEN_SPACE_CENTER":205,"FLAG_IS_CHAMPION":2175,"FLAG_ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":1100,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":1102,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":1078,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":1101,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":1077,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":1095,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":1099,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":1097,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":1096,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":1098,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":1124,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":1071,"FLAG_ITEM_AQUA_HIDEOUT_B1F_NUGGET":1132,"FLAG_ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":1072,"FLAG_ITEM_ARTISAN_CAVE_1F_CARBOS":1163,"FLAG_ITEM_ARTISAN_CAVE_B1F_HP_UP":1162,"FLAG_ITEM_FIERY_PATH_FIRE_STONE":1111,"FLAG_ITEM_FIERY_PATH_TM_TOXIC":1091,"FLAG_ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":1050,"FLAG_ITEM_GRANITE_CAVE_B1F_POKE_BALL":1051,"FLAG_ITEM_GRANITE_CAVE_B2F_RARE_CANDY":1054,"FLAG_ITEM_GRANITE_CAVE_B2F_REPEL":1053,"FLAG_ITEM_JAGGED_PASS_BURN_HEAL":1070,"FLAG_ITEM_LILYCOVE_CITY_MAX_REPEL":1042,"FLAG_ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":1151,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":1165,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":1164,"FLAG_ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":1166,"FLAG_ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":1167,"FLAG_ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":1059,"FLAG_ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":1168,"FLAG_ITEM_MAUVILLE_CITY_X_SPEED":1116,"FLAG_ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":1045,"FLAG_ITEM_METEOR_FALLS_1F_1R_MOON_STONE":1046,"FLAG_ITEM_METEOR_FALLS_1F_1R_PP_UP":1047,"FLAG_ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":1044,"FLAG_ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":1080,"FLAG_ITEM_MOSSDEEP_CITY_NET_BALL":1043,"FLAG_ITEM_MOSSDEEP_STEVENS_HOUSE_HM08":1133,"FLAG_ITEM_MT_PYRE_2F_ULTRA_BALL":1129,"FLAG_ITEM_MT_PYRE_3F_SUPER_REPEL":1120,"FLAG_ITEM_MT_PYRE_4F_SEA_INCENSE":1130,"FLAG_ITEM_MT_PYRE_5F_LAX_INCENSE":1052,"FLAG_ITEM_MT_PYRE_6F_TM_SHADOW_BALL":1089,"FLAG_ITEM_MT_PYRE_EXTERIOR_MAX_POTION":1073,"FLAG_ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":1074,"FLAG_ITEM_NEW_MAUVILLE_ESCAPE_ROPE":1076,"FLAG_ITEM_NEW_MAUVILLE_FULL_HEAL":1122,"FLAG_ITEM_NEW_MAUVILLE_PARALYZE_HEAL":1123,"FLAG_ITEM_NEW_MAUVILLE_THUNDER_STONE":1110,"FLAG_ITEM_NEW_MAUVILLE_ULTRA_BALL":1075,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MASTER_BALL":1125,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MAX_ELIXIR":1126,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B2F_NEST_BALL":1127,"FLAG_ITEM_PETALBURG_CITY_ETHER":1040,"FLAG_ITEM_PETALBURG_CITY_MAX_REVIVE":1039,"FLAG_ITEM_PETALBURG_WOODS_ETHER":1058,"FLAG_ITEM_PETALBURG_WOODS_GREAT_BALL":1056,"FLAG_ITEM_PETALBURG_WOODS_PARALYZE_HEAL":1117,"FLAG_ITEM_PETALBURG_WOODS_X_ATTACK":1055,"FLAG_ITEM_ROUTE_102_POTION":1000,"FLAG_ITEM_ROUTE_103_GUARD_SPEC":1114,"FLAG_ITEM_ROUTE_103_PP_UP":1137,"FLAG_ITEM_ROUTE_104_POKE_BALL":1057,"FLAG_ITEM_ROUTE_104_POTION":1135,"FLAG_ITEM_ROUTE_104_PP_UP":1002,"FLAG_ITEM_ROUTE_104_X_ACCURACY":1115,"FLAG_ITEM_ROUTE_105_IRON":1003,"FLAG_ITEM_ROUTE_106_PROTEIN":1004,"FLAG_ITEM_ROUTE_108_STAR_PIECE":1139,"FLAG_ITEM_ROUTE_109_POTION":1140,"FLAG_ITEM_ROUTE_109_PP_UP":1005,"FLAG_ITEM_ROUTE_110_DIRE_HIT":1007,"FLAG_ITEM_ROUTE_110_ELIXIR":1141,"FLAG_ITEM_ROUTE_110_RARE_CANDY":1006,"FLAG_ITEM_ROUTE_111_ELIXIR":1142,"FLAG_ITEM_ROUTE_111_HP_UP":1010,"FLAG_ITEM_ROUTE_111_STARDUST":1009,"FLAG_ITEM_ROUTE_111_TM_SANDSTORM":1008,"FLAG_ITEM_ROUTE_112_NUGGET":1011,"FLAG_ITEM_ROUTE_113_HYPER_POTION":1143,"FLAG_ITEM_ROUTE_113_MAX_ETHER":1012,"FLAG_ITEM_ROUTE_113_SUPER_REPEL":1013,"FLAG_ITEM_ROUTE_114_ENERGY_POWDER":1160,"FLAG_ITEM_ROUTE_114_PROTEIN":1015,"FLAG_ITEM_ROUTE_114_RARE_CANDY":1014,"FLAG_ITEM_ROUTE_115_GREAT_BALL":1118,"FLAG_ITEM_ROUTE_115_HEAL_POWDER":1144,"FLAG_ITEM_ROUTE_115_IRON":1018,"FLAG_ITEM_ROUTE_115_PP_UP":1161,"FLAG_ITEM_ROUTE_115_SUPER_POTION":1016,"FLAG_ITEM_ROUTE_115_TM_FOCUS_PUNCH":1017,"FLAG_ITEM_ROUTE_116_ETHER":1019,"FLAG_ITEM_ROUTE_116_HP_UP":1021,"FLAG_ITEM_ROUTE_116_POTION":1146,"FLAG_ITEM_ROUTE_116_REPEL":1020,"FLAG_ITEM_ROUTE_116_X_SPECIAL":1001,"FLAG_ITEM_ROUTE_117_GREAT_BALL":1022,"FLAG_ITEM_ROUTE_117_REVIVE":1023,"FLAG_ITEM_ROUTE_118_HYPER_POTION":1121,"FLAG_ITEM_ROUTE_119_ELIXIR_1":1026,"FLAG_ITEM_ROUTE_119_ELIXIR_2":1147,"FLAG_ITEM_ROUTE_119_HYPER_POTION_1":1029,"FLAG_ITEM_ROUTE_119_HYPER_POTION_2":1106,"FLAG_ITEM_ROUTE_119_LEAF_STONE":1027,"FLAG_ITEM_ROUTE_119_NUGGET":1134,"FLAG_ITEM_ROUTE_119_RARE_CANDY":1028,"FLAG_ITEM_ROUTE_119_SUPER_REPEL":1024,"FLAG_ITEM_ROUTE_119_ZINC":1025,"FLAG_ITEM_ROUTE_120_FULL_HEAL":1031,"FLAG_ITEM_ROUTE_120_HYPER_POTION":1107,"FLAG_ITEM_ROUTE_120_NEST_BALL":1108,"FLAG_ITEM_ROUTE_120_NUGGET":1030,"FLAG_ITEM_ROUTE_120_REVIVE":1148,"FLAG_ITEM_ROUTE_121_CARBOS":1103,"FLAG_ITEM_ROUTE_121_REVIVE":1149,"FLAG_ITEM_ROUTE_121_ZINC":1150,"FLAG_ITEM_ROUTE_123_CALCIUM":1032,"FLAG_ITEM_ROUTE_123_ELIXIR":1109,"FLAG_ITEM_ROUTE_123_PP_UP":1152,"FLAG_ITEM_ROUTE_123_REVIVAL_HERB":1153,"FLAG_ITEM_ROUTE_123_ULTRA_BALL":1104,"FLAG_ITEM_ROUTE_124_BLUE_SHARD":1093,"FLAG_ITEM_ROUTE_124_RED_SHARD":1092,"FLAG_ITEM_ROUTE_124_YELLOW_SHARD":1066,"FLAG_ITEM_ROUTE_125_BIG_PEARL":1154,"FLAG_ITEM_ROUTE_126_GREEN_SHARD":1105,"FLAG_ITEM_ROUTE_127_CARBOS":1035,"FLAG_ITEM_ROUTE_127_RARE_CANDY":1155,"FLAG_ITEM_ROUTE_127_ZINC":1034,"FLAG_ITEM_ROUTE_132_PROTEIN":1156,"FLAG_ITEM_ROUTE_132_RARE_CANDY":1036,"FLAG_ITEM_ROUTE_133_BIG_PEARL":1037,"FLAG_ITEM_ROUTE_133_MAX_REVIVE":1157,"FLAG_ITEM_ROUTE_133_STAR_PIECE":1038,"FLAG_ITEM_ROUTE_134_CARBOS":1158,"FLAG_ITEM_ROUTE_134_STAR_PIECE":1159,"FLAG_ITEM_RUSTBORO_CITY_X_DEFEND":1041,"FLAG_ITEM_RUSTURF_TUNNEL_MAX_ETHER":1049,"FLAG_ITEM_RUSTURF_TUNNEL_POKE_BALL":1048,"FLAG_ITEM_SAFARI_ZONE_NORTH_CALCIUM":1119,"FLAG_ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":1169,"FLAG_ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":1094,"FLAG_ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":1170,"FLAG_ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":1131,"FLAG_ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":1079,"FLAG_ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":1090,"FLAG_ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":1081,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":1113,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":1112,"FLAG_ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":1082,"FLAG_ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":1083,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":1060,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":1061,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":1062,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":1063,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":1064,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":1065,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":1067,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":1068,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":1069,"FLAG_ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":1084,"FLAG_ITEM_VICTORY_ROAD_1F_PP_UP":1085,"FLAG_ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":1087,"FLAG_ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":1086,"FLAG_ITEM_VICTORY_ROAD_B2F_FULL_HEAL":1088,"FLAG_KECLEON_FLED_FORTREE":295,"FLAG_KYOGRE_ESCAPED_SEAFLOOR_CAVERN":129,"FLAG_KYOGRE_IS_RECOVERING":1273,"FLAG_LANDMARK_ABANDONED_SHIP":2206,"FLAG_LANDMARK_ALTERING_CAVE":2269,"FLAG_LANDMARK_ANCIENT_TOMB":2233,"FLAG_LANDMARK_ARTISAN_CAVE":2271,"FLAG_LANDMARK_BATTLE_FRONTIER":2216,"FLAG_LANDMARK_BERRY_MASTERS_HOUSE":2243,"FLAG_LANDMARK_DESERT_RUINS":2230,"FLAG_LANDMARK_DESERT_UNDERPASS":2270,"FLAG_LANDMARK_FIERY_PATH":2218,"FLAG_LANDMARK_FLOWER_SHOP":2204,"FLAG_LANDMARK_FOSSIL_MANIACS_HOUSE":2231,"FLAG_LANDMARK_GLASS_WORKSHOP":2212,"FLAG_LANDMARK_HUNTERS_HOUSE":2235,"FLAG_LANDMARK_ISLAND_CAVE":2229,"FLAG_LANDMARK_LANETTES_HOUSE":2213,"FLAG_LANDMARK_MIRAGE_TOWER":120,"FLAG_LANDMARK_MR_BRINEY_HOUSE":2205,"FLAG_LANDMARK_NEW_MAUVILLE":2208,"FLAG_LANDMARK_OLD_LADY_REST_SHOP":2209,"FLAG_LANDMARK_POKEMON_DAYCARE":2214,"FLAG_LANDMARK_POKEMON_LEAGUE":2228,"FLAG_LANDMARK_SCORCHED_SLAB":2232,"FLAG_LANDMARK_SEAFLOOR_CAVERN":2215,"FLAG_LANDMARK_SEALED_CHAMBER":2236,"FLAG_LANDMARK_SEASHORE_HOUSE":2207,"FLAG_LANDMARK_SKY_PILLAR":2238,"FLAG_LANDMARK_SOUTHERN_ISLAND":2217,"FLAG_LANDMARK_TRAINER_HILL":2274,"FLAG_LANDMARK_TRICK_HOUSE":2210,"FLAG_LANDMARK_TUNNELERS_REST_HOUSE":2234,"FLAG_LANDMARK_WINSTRATE_FAMILY":2211,"FLAG_LATIAS_IS_RECOVERING":1263,"FLAG_LATIOS_IS_RECOVERING":1255,"FLAG_LATIOS_OR_LATIAS_ROAMING":255,"FLAG_LEGENDARIES_IN_SOOTOPOLIS":83,"FLAG_LILYCOVE_RECEIVED_BERRY":1208,"FLAG_LUGIA_IS_RECOVERING":1257,"FLAG_MAP_SCRIPT_CHECKED_DEOXYS":2259,"FLAG_MATCH_CALL_REGISTERED":348,"FLAG_MAUVILLE_GYM_BARRIERS_STATE":99,"FLAG_MET_ARCHIE_METEOR_FALLS":207,"FLAG_MET_ARCHIE_SOOTOPOLIS":308,"FLAG_MET_BATTLE_FRONTIER_BREEDER":339,"FLAG_MET_BATTLE_FRONTIER_GAMBLER":343,"FLAG_MET_BATTLE_FRONTIER_MANIAC":340,"FLAG_MET_DEVON_EMPLOYEE":287,"FLAG_MET_DIVING_TREASURE_HUNTER":217,"FLAG_MET_FANCLUB_YOUNGER_BROTHER":300,"FLAG_MET_FRONTIER_BEAUTY_MOVE_TUTOR":346,"FLAG_MET_FRONTIER_SWIMMER_MOVE_TUTOR":347,"FLAG_MET_HIDDEN_POWER_GIVER":118,"FLAG_MET_MAXIE_SOOTOPOLIS":309,"FLAG_MET_PRETTY_PETAL_SHOP_OWNER":127,"FLAG_MET_PROF_COZMO":244,"FLAG_MET_RIVAL_IN_HOUSE_AFTER_LILYCOVE":293,"FLAG_MET_RIVAL_LILYCOVE":292,"FLAG_MET_RIVAL_MOM":87,"FLAG_MET_RIVAL_RUSTBORO":288,"FLAG_MET_SCOTT_AFTER_OBTAINING_STONE_BADGE":459,"FLAG_MET_SCOTT_IN_EVERGRANDE":463,"FLAG_MET_SCOTT_IN_FALLARBOR":461,"FLAG_MET_SCOTT_IN_LILYCOVE":462,"FLAG_MET_SCOTT_IN_VERDANTURF":460,"FLAG_MET_SCOTT_ON_SS_TIDAL":464,"FLAG_MET_SCOTT_RUSTBORO":310,"FLAG_MET_SLATEPORT_FANCLUB_CHAIRMAN":342,"FLAG_MET_TEAM_AQUA_HARBOR":97,"FLAG_MET_WAILMER_TRAINER":218,"FLAG_MEW_IS_RECOVERING":1259,"FLAG_MIRAGE_TOWER_VISIBLE":334,"FLAG_MOSSDEEP_GYM_SWITCH_1":100,"FLAG_MOSSDEEP_GYM_SWITCH_2":101,"FLAG_MOSSDEEP_GYM_SWITCH_3":102,"FLAG_MOSSDEEP_GYM_SWITCH_4":103,"FLAG_MOVE_TUTOR_TAUGHT_DOUBLE_EDGE":441,"FLAG_MOVE_TUTOR_TAUGHT_DYNAMICPUNCH":440,"FLAG_MOVE_TUTOR_TAUGHT_EXPLOSION":442,"FLAG_MOVE_TUTOR_TAUGHT_FURY_CUTTER":435,"FLAG_MOVE_TUTOR_TAUGHT_METRONOME":437,"FLAG_MOVE_TUTOR_TAUGHT_MIMIC":436,"FLAG_MOVE_TUTOR_TAUGHT_ROLLOUT":434,"FLAG_MOVE_TUTOR_TAUGHT_SLEEP_TALK":438,"FLAG_MOVE_TUTOR_TAUGHT_SUBSTITUTE":439,"FLAG_MOVE_TUTOR_TAUGHT_SWAGGER":433,"FLAG_MR_BRINEY_SAILING_INTRO":147,"FLAG_MYSTERY_GIFT_1":485,"FLAG_MYSTERY_GIFT_10":494,"FLAG_MYSTERY_GIFT_11":495,"FLAG_MYSTERY_GIFT_12":496,"FLAG_MYSTERY_GIFT_13":497,"FLAG_MYSTERY_GIFT_14":498,"FLAG_MYSTERY_GIFT_15":499,"FLAG_MYSTERY_GIFT_2":486,"FLAG_MYSTERY_GIFT_3":487,"FLAG_MYSTERY_GIFT_4":488,"FLAG_MYSTERY_GIFT_5":489,"FLAG_MYSTERY_GIFT_6":490,"FLAG_MYSTERY_GIFT_7":491,"FLAG_MYSTERY_GIFT_8":492,"FLAG_MYSTERY_GIFT_9":493,"FLAG_MYSTERY_GIFT_DONE":484,"FLAG_NEVER_SET_0x0DC":220,"FLAG_NOT_READY_FOR_BATTLE_ROUTE_120":290,"FLAG_NURSE_MENTIONS_GOLD_CARD":345,"FLAG_NURSE_UNION_ROOM_REMINDER":2176,"FLAG_OCEANIC_MUSEUM_MET_REPORTER":105,"FLAG_OMIT_DIVE_FROM_STEVEN_LETTER":302,"FLAG_PACIFIDLOG_NPC_TRADE_COMPLETED":154,"FLAG_PENDING_DAYCARE_EGG":134,"FLAG_PETALBURG_MART_EXPANDED_ITEMS":296,"FLAG_POKERUS_EXPLAINED":273,"FLAG_PURCHASED_HARBOR_MAIL":104,"FLAG_RAYQUAZA_IS_RECOVERING":1279,"FLAG_RECEIVED_20_COINS":225,"FLAG_RECEIVED_6_SODA_POP":140,"FLAG_RECEIVED_ACRO_BIKE":1181,"FLAG_RECEIVED_AMULET_COIN":133,"FLAG_RECEIVED_AURORA_TICKET":314,"FLAG_RECEIVED_BADGE_1":1182,"FLAG_RECEIVED_BADGE_2":1183,"FLAG_RECEIVED_BADGE_3":1184,"FLAG_RECEIVED_BADGE_4":1185,"FLAG_RECEIVED_BADGE_5":1186,"FLAG_RECEIVED_BADGE_6":1187,"FLAG_RECEIVED_BADGE_7":1188,"FLAG_RECEIVED_BADGE_8":1189,"FLAG_RECEIVED_BELDUM":298,"FLAG_RECEIVED_BELUE_BERRY":252,"FLAG_RECEIVED_BIKE":90,"FLAG_RECEIVED_BLUE_SCARF":201,"FLAG_RECEIVED_CASTFORM":151,"FLAG_RECEIVED_CHARCOAL":254,"FLAG_RECEIVED_CHESTO_BERRY_ROUTE_104":246,"FLAG_RECEIVED_CLEANSE_TAG":282,"FLAG_RECEIVED_COIN_CASE":258,"FLAG_RECEIVED_CONTEST_PASS":150,"FLAG_RECEIVED_DEEP_SEA_SCALE":1190,"FLAG_RECEIVED_DEEP_SEA_TOOTH":1191,"FLAG_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":1172,"FLAG_RECEIVED_DEVON_SCOPE":285,"FLAG_RECEIVED_DOLL_LANETTE":131,"FLAG_RECEIVED_DURIN_BERRY":251,"FLAG_RECEIVED_EON_TICKET":474,"FLAG_RECEIVED_EXP_SHARE":272,"FLAG_RECEIVED_FANCLUB_TM_THIS_WEEK":299,"FLAG_RECEIVED_FIRST_POKEBALLS":233,"FLAG_RECEIVED_FOCUS_BAND":283,"FLAG_RECEIVED_GLASS_ORNAMENT":236,"FLAG_RECEIVED_GOLD_SHIELD":238,"FLAG_RECEIVED_GOOD_ROD":227,"FLAG_RECEIVED_GO_GOGGLES":221,"FLAG_RECEIVED_GREAT_BALL_PETALBURG_WOODS":1171,"FLAG_RECEIVED_GREAT_BALL_RUSTBORO_CITY":1173,"FLAG_RECEIVED_GREEN_SCARF":203,"FLAG_RECEIVED_HM_CUT":137,"FLAG_RECEIVED_HM_DIVE":123,"FLAG_RECEIVED_HM_FLASH":109,"FLAG_RECEIVED_HM_FLY":110,"FLAG_RECEIVED_HM_ROCK_SMASH":107,"FLAG_RECEIVED_HM_STRENGTH":106,"FLAG_RECEIVED_HM_SURF":122,"FLAG_RECEIVED_HM_WATERFALL":312,"FLAG_RECEIVED_ITEMFINDER":1176,"FLAG_RECEIVED_KINGS_ROCK":276,"FLAG_RECEIVED_LAVARIDGE_EGG":266,"FLAG_RECEIVED_LETTER":1174,"FLAG_RECEIVED_MACHO_BRACE":277,"FLAG_RECEIVED_MACH_BIKE":1180,"FLAG_RECEIVED_MAGMA_EMBLEM":1177,"FLAG_RECEIVED_MENTAL_HERB":223,"FLAG_RECEIVED_METEORITE":115,"FLAG_RECEIVED_MIRACLE_SEED":297,"FLAG_RECEIVED_MYSTIC_TICKET":315,"FLAG_RECEIVED_OLD_ROD":257,"FLAG_RECEIVED_OLD_SEA_MAP":316,"FLAG_RECEIVED_PAMTRE_BERRY":249,"FLAG_RECEIVED_PINK_SCARF":202,"FLAG_RECEIVED_POKEBLOCK_CASE":95,"FLAG_RECEIVED_POKEDEX_FROM_BIRCH":2276,"FLAG_RECEIVED_POKENAV":188,"FLAG_RECEIVED_POTION_OLDALE":132,"FLAG_RECEIVED_POWDER_JAR":337,"FLAG_RECEIVED_PREMIER_BALL_RUSTBORO":213,"FLAG_RECEIVED_QUICK_CLAW":275,"FLAG_RECEIVED_RED_OR_BLUE_ORB":212,"FLAG_RECEIVED_RED_SCARF":200,"FLAG_RECEIVED_REPEAT_BALL":256,"FLAG_RECEIVED_REVIVED_FOSSIL_MON":267,"FLAG_RECEIVED_RUNNING_SHOES":274,"FLAG_RECEIVED_SECRET_POWER":96,"FLAG_RECEIVED_SHOAL_SALT_1":952,"FLAG_RECEIVED_SHOAL_SALT_2":953,"FLAG_RECEIVED_SHOAL_SALT_3":954,"FLAG_RECEIVED_SHOAL_SALT_4":955,"FLAG_RECEIVED_SHOAL_SHELL_1":956,"FLAG_RECEIVED_SHOAL_SHELL_2":957,"FLAG_RECEIVED_SHOAL_SHELL_3":958,"FLAG_RECEIVED_SHOAL_SHELL_4":959,"FLAG_RECEIVED_SILK_SCARF":289,"FLAG_RECEIVED_SILVER_SHIELD":237,"FLAG_RECEIVED_SOFT_SAND":280,"FLAG_RECEIVED_SOOTHE_BELL":278,"FLAG_RECEIVED_SOOT_SACK":1033,"FLAG_RECEIVED_SPECIAL_PHRASE_HINT":85,"FLAG_RECEIVED_SPELON_BERRY":248,"FLAG_RECEIVED_SS_TICKET":291,"FLAG_RECEIVED_STARTER_DOLL":226,"FLAG_RECEIVED_SUN_STONE_MOSSDEEP":192,"FLAG_RECEIVED_SUPER_ROD":152,"FLAG_RECEIVED_TM_AERIAL_ACE":170,"FLAG_RECEIVED_TM_ATTRACT":235,"FLAG_RECEIVED_TM_BRICK_BREAK":121,"FLAG_RECEIVED_TM_BULK_UP":166,"FLAG_RECEIVED_TM_BULLET_SEED":262,"FLAG_RECEIVED_TM_CALM_MIND":171,"FLAG_RECEIVED_TM_DIG":261,"FLAG_RECEIVED_TM_FACADE":169,"FLAG_RECEIVED_TM_FRUSTRATION":1179,"FLAG_RECEIVED_TM_GIGA_DRAIN":232,"FLAG_RECEIVED_TM_HIDDEN_POWER":264,"FLAG_RECEIVED_TM_OVERHEAT":168,"FLAG_RECEIVED_TM_REST":234,"FLAG_RECEIVED_TM_RETURN":229,"FLAG_RECEIVED_TM_RETURN_2":1178,"FLAG_RECEIVED_TM_ROAR":231,"FLAG_RECEIVED_TM_ROCK_TOMB":165,"FLAG_RECEIVED_TM_SHOCK_WAVE":167,"FLAG_RECEIVED_TM_SLUDGE_BOMB":230,"FLAG_RECEIVED_TM_SNATCH":260,"FLAG_RECEIVED_TM_STEEL_WING":1175,"FLAG_RECEIVED_TM_THIEF":269,"FLAG_RECEIVED_TM_TORMENT":265,"FLAG_RECEIVED_TM_WATER_PULSE":172,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_1":1200,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_2":1201,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_3":1202,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_4":1203,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_5":1204,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_6":1205,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_7":1206,"FLAG_RECEIVED_WAILMER_DOLL":245,"FLAG_RECEIVED_WAILMER_PAIL":94,"FLAG_RECEIVED_WATMEL_BERRY":250,"FLAG_RECEIVED_WHITE_HERB":279,"FLAG_RECEIVED_YELLOW_SCARF":204,"FLAG_RECOVERED_DEVON_GOODS":143,"FLAG_REGICE_IS_RECOVERING":1260,"FLAG_REGIROCK_IS_RECOVERING":1261,"FLAG_REGISTEEL_IS_RECOVERING":1262,"FLAG_REGISTERED_STEVEN_POKENAV":305,"FLAG_REGISTER_RIVAL_POKENAV":124,"FLAG_REGI_DOORS_OPENED":228,"FLAG_REMATCH_ABIGAIL":387,"FLAG_REMATCH_AMY_AND_LIV":399,"FLAG_REMATCH_ANDRES":350,"FLAG_REMATCH_ANNA_AND_MEG":378,"FLAG_REMATCH_BENJAMIN":390,"FLAG_REMATCH_BERNIE":369,"FLAG_REMATCH_BRAWLY":415,"FLAG_REMATCH_BROOKE":356,"FLAG_REMATCH_CALVIN":383,"FLAG_REMATCH_CAMERON":373,"FLAG_REMATCH_CATHERINE":406,"FLAG_REMATCH_CINDY":359,"FLAG_REMATCH_CORY":401,"FLAG_REMATCH_CRISTIN":355,"FLAG_REMATCH_CYNDY":395,"FLAG_REMATCH_DALTON":368,"FLAG_REMATCH_DIANA":398,"FLAG_REMATCH_DRAKE":424,"FLAG_REMATCH_DUSTY":351,"FLAG_REMATCH_DYLAN":388,"FLAG_REMATCH_EDWIN":402,"FLAG_REMATCH_ELLIOT":384,"FLAG_REMATCH_ERNEST":400,"FLAG_REMATCH_ETHAN":370,"FLAG_REMATCH_FERNANDO":367,"FLAG_REMATCH_FLANNERY":417,"FLAG_REMATCH_GABRIELLE":405,"FLAG_REMATCH_GLACIA":423,"FLAG_REMATCH_HALEY":408,"FLAG_REMATCH_ISAAC":404,"FLAG_REMATCH_ISABEL":379,"FLAG_REMATCH_ISAIAH":385,"FLAG_REMATCH_JACKI":374,"FLAG_REMATCH_JACKSON":407,"FLAG_REMATCH_JAMES":409,"FLAG_REMATCH_JEFFREY":372,"FLAG_REMATCH_JENNY":397,"FLAG_REMATCH_JERRY":377,"FLAG_REMATCH_JESSICA":361,"FLAG_REMATCH_JOHN_AND_JAY":371,"FLAG_REMATCH_KAREN":376,"FLAG_REMATCH_KATELYN":389,"FLAG_REMATCH_KIRA_AND_DAN":412,"FLAG_REMATCH_KOJI":366,"FLAG_REMATCH_LAO":394,"FLAG_REMATCH_LILA_AND_ROY":354,"FLAG_REMATCH_LOLA":352,"FLAG_REMATCH_LYDIA":403,"FLAG_REMATCH_MADELINE":396,"FLAG_REMATCH_MARIA":386,"FLAG_REMATCH_MIGUEL":380,"FLAG_REMATCH_NICOLAS":392,"FLAG_REMATCH_NOB":365,"FLAG_REMATCH_NORMAN":418,"FLAG_REMATCH_PABLO":391,"FLAG_REMATCH_PHOEBE":422,"FLAG_REMATCH_RICKY":353,"FLAG_REMATCH_ROBERT":393,"FLAG_REMATCH_ROSE":349,"FLAG_REMATCH_ROXANNE":414,"FLAG_REMATCH_SAWYER":411,"FLAG_REMATCH_SHELBY":382,"FLAG_REMATCH_SIDNEY":421,"FLAG_REMATCH_STEVE":363,"FLAG_REMATCH_TATE_AND_LIZA":420,"FLAG_REMATCH_THALIA":360,"FLAG_REMATCH_TIMOTHY":381,"FLAG_REMATCH_TONY":364,"FLAG_REMATCH_TRENT":410,"FLAG_REMATCH_VALERIE":358,"FLAG_REMATCH_WALLACE":425,"FLAG_REMATCH_WALLY":413,"FLAG_REMATCH_WALTER":375,"FLAG_REMATCH_WATTSON":416,"FLAG_REMATCH_WILTON":357,"FLAG_REMATCH_WINONA":419,"FLAG_REMATCH_WINSTON":362,"FLAG_RESCUED_BIRCH":82,"FLAG_RETURNED_DEVON_GOODS":144,"FLAG_RETURNED_RED_OR_BLUE_ORB":259,"FLAG_RIVAL_LEFT_FOR_ROUTE103":301,"FLAG_ROUTE_111_RECEIVED_BERRY":1192,"FLAG_ROUTE_114_RECEIVED_BERRY":1193,"FLAG_ROUTE_120_RECEIVED_BERRY":1194,"FLAG_RUSTBORO_NPC_TRADE_COMPLETED":153,"FLAG_RUSTURF_TUNNEL_OPENED":199,"FLAG_SCOTT_CALL_BATTLE_FRONTIER":114,"FLAG_SCOTT_CALL_FORTREE_GYM":138,"FLAG_SCOTT_GIVES_BATTLE_POINTS":465,"FLAG_SECRET_BASE_REGISTRY_ENABLED":268,"FLAG_SET_WALL_CLOCK":81,"FLAG_SHOWN_AURORA_TICKET":431,"FLAG_SHOWN_BOX_WAS_FULL_MESSAGE":2263,"FLAG_SHOWN_EON_TICKET":430,"FLAG_SHOWN_MYSTIC_TICKET":475,"FLAG_SHOWN_OLD_SEA_MAP":432,"FLAG_SMART_PAINTING_MADE":163,"FLAG_SOOTOPOLIS_ARCHIE_MAXIE_LEAVE":158,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_1":1198,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_2":1199,"FLAG_SPECIAL_FLAG_UNUSED_0x4003":16387,"FLAG_SS_TIDAL_DISABLED":84,"FLAG_STEVEN_GUIDES_TO_CAVE_OF_ORIGIN":307,"FLAG_STORING_ITEMS_IN_PYRAMID_BAG":16388,"FLAG_SYS_ARENA_GOLD":2251,"FLAG_SYS_ARENA_SILVER":2250,"FLAG_SYS_BRAILLE_DIG":2223,"FLAG_SYS_BRAILLE_REGICE_COMPLETED":2225,"FLAG_SYS_B_DASH":2240,"FLAG_SYS_CAVE_BATTLE":2201,"FLAG_SYS_CAVE_SHIP":2199,"FLAG_SYS_CAVE_WONDER":2200,"FLAG_SYS_CHANGED_DEWFORD_TREND":2195,"FLAG_SYS_CHAT_USED":2149,"FLAG_SYS_CLOCK_SET":2197,"FLAG_SYS_CRUISE_MODE":2189,"FLAG_SYS_CTRL_OBJ_DELETE":2241,"FLAG_SYS_CYCLING_ROAD":2187,"FLAG_SYS_DOME_GOLD":2247,"FLAG_SYS_DOME_SILVER":2246,"FLAG_SYS_ENC_DOWN_ITEM":2222,"FLAG_SYS_ENC_UP_ITEM":2221,"FLAG_SYS_FACTORY_GOLD":2253,"FLAG_SYS_FACTORY_SILVER":2252,"FLAG_SYS_FRONTIER_PASS":2258,"FLAG_SYS_GAME_CLEAR":2148,"FLAG_SYS_MIX_RECORD":2196,"FLAG_SYS_MYSTERY_EVENT_ENABLE":2220,"FLAG_SYS_MYSTERY_GIFT_ENABLE":2267,"FLAG_SYS_NATIONAL_DEX":2198,"FLAG_SYS_PALACE_GOLD":2249,"FLAG_SYS_PALACE_SILVER":2248,"FLAG_SYS_PC_LANETTE":2219,"FLAG_SYS_PIKE_GOLD":2255,"FLAG_SYS_PIKE_SILVER":2254,"FLAG_SYS_POKEDEX_GET":2145,"FLAG_SYS_POKEMON_GET":2144,"FLAG_SYS_POKENAV_GET":2146,"FLAG_SYS_PYRAMID_GOLD":2257,"FLAG_SYS_PYRAMID_SILVER":2256,"FLAG_SYS_REGIROCK_PUZZLE_COMPLETED":2224,"FLAG_SYS_REGISTEEL_PUZZLE_COMPLETED":2226,"FLAG_SYS_RESET_RTC_ENABLE":2242,"FLAG_SYS_RIBBON_GET":2203,"FLAG_SYS_SAFARI_MODE":2188,"FLAG_SYS_SHOAL_ITEM":2239,"FLAG_SYS_SHOAL_TIDE":2202,"FLAG_SYS_TOWER_GOLD":2245,"FLAG_SYS_TOWER_SILVER":2244,"FLAG_SYS_TV_HOME":2192,"FLAG_SYS_TV_LATIAS_LATIOS":2237,"FLAG_SYS_TV_START":2194,"FLAG_SYS_TV_WATCH":2193,"FLAG_SYS_USE_FLASH":2184,"FLAG_SYS_USE_STRENGTH":2185,"FLAG_SYS_WEATHER_CTRL":2186,"FLAG_TEAM_AQUA_ESCAPED_IN_SUBMARINE":112,"FLAG_TEMP_1":1,"FLAG_TEMP_10":16,"FLAG_TEMP_11":17,"FLAG_TEMP_12":18,"FLAG_TEMP_13":19,"FLAG_TEMP_14":20,"FLAG_TEMP_15":21,"FLAG_TEMP_16":22,"FLAG_TEMP_17":23,"FLAG_TEMP_18":24,"FLAG_TEMP_19":25,"FLAG_TEMP_1A":26,"FLAG_TEMP_1B":27,"FLAG_TEMP_1C":28,"FLAG_TEMP_1D":29,"FLAG_TEMP_1E":30,"FLAG_TEMP_1F":31,"FLAG_TEMP_2":2,"FLAG_TEMP_3":3,"FLAG_TEMP_4":4,"FLAG_TEMP_5":5,"FLAG_TEMP_6":6,"FLAG_TEMP_7":7,"FLAG_TEMP_8":8,"FLAG_TEMP_9":9,"FLAG_TEMP_A":10,"FLAG_TEMP_B":11,"FLAG_TEMP_C":12,"FLAG_TEMP_D":13,"FLAG_TEMP_E":14,"FLAG_TEMP_F":15,"FLAG_TEMP_HIDE_MIRAGE_ISLAND_BERRY_TREE":17,"FLAG_TEMP_REGICE_PUZZLE_FAILED":3,"FLAG_TEMP_REGICE_PUZZLE_STARTED":2,"FLAG_TEMP_SKIP_GABBY_INTERVIEW":1,"FLAG_THANKED_FOR_PLAYING_WITH_WALLY":135,"FLAG_TOUGH_PAINTING_MADE":164,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_1":194,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_2":195,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_3":196,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_4":197,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_5":198,"FLAG_TV_EXPLAINED":98,"FLAG_UNLOCKED_TRENDY_SAYINGS":2150,"FLAG_USED_ROOM_1_KEY":240,"FLAG_USED_ROOM_2_KEY":241,"FLAG_USED_ROOM_4_KEY":242,"FLAG_USED_ROOM_6_KEY":243,"FLAG_USED_STORAGE_KEY":239,"FLAG_VISITED_DEWFORD_TOWN":2161,"FLAG_VISITED_EVER_GRANDE_CITY":2174,"FLAG_VISITED_FALLARBOR_TOWN":2163,"FLAG_VISITED_FORTREE_CITY":2170,"FLAG_VISITED_LAVARIDGE_TOWN":2162,"FLAG_VISITED_LILYCOVE_CITY":2171,"FLAG_VISITED_LITTLEROOT_TOWN":2159,"FLAG_VISITED_MAUVILLE_CITY":2168,"FLAG_VISITED_MOSSDEEP_CITY":2172,"FLAG_VISITED_OLDALE_TOWN":2160,"FLAG_VISITED_PACIFIDLOG_TOWN":2165,"FLAG_VISITED_PETALBURG_CITY":2166,"FLAG_VISITED_RUSTBORO_CITY":2169,"FLAG_VISITED_SLATEPORT_CITY":2167,"FLAG_VISITED_SOOTOPOLIS_CITY":2173,"FLAG_VISITED_VERDANTURF_TOWN":2164,"FLAG_WALLACE_GOES_TO_SKY_PILLAR":311,"FLAG_WALLY_SPEECH":193,"FLAG_WATTSON_REMATCH_AVAILABLE":91,"FLAG_WHITEOUT_TO_LAVARIDGE":108,"FLAG_WINGULL_DELIVERED_MAIL":224,"FLAG_WINGULL_SENT_ON_ERRAND":222,"FLAG_WONDER_CARD_UNUSED_1":317,"FLAG_WONDER_CARD_UNUSED_10":326,"FLAG_WONDER_CARD_UNUSED_11":327,"FLAG_WONDER_CARD_UNUSED_12":328,"FLAG_WONDER_CARD_UNUSED_13":329,"FLAG_WONDER_CARD_UNUSED_14":330,"FLAG_WONDER_CARD_UNUSED_15":331,"FLAG_WONDER_CARD_UNUSED_16":332,"FLAG_WONDER_CARD_UNUSED_17":333,"FLAG_WONDER_CARD_UNUSED_2":318,"FLAG_WONDER_CARD_UNUSED_3":319,"FLAG_WONDER_CARD_UNUSED_4":320,"FLAG_WONDER_CARD_UNUSED_5":321,"FLAG_WONDER_CARD_UNUSED_6":322,"FLAG_WONDER_CARD_UNUSED_7":323,"FLAG_WONDER_CARD_UNUSED_8":324,"FLAG_WONDER_CARD_UNUSED_9":325,"FLAVOR_BITTER":3,"FLAVOR_COUNT":5,"FLAVOR_DRY":1,"FLAVOR_SOUR":4,"FLAVOR_SPICY":0,"FLAVOR_SWEET":2,"GOOD_ROD":1,"ITEMS_COUNT":377,"ITEM_034":52,"ITEM_035":53,"ITEM_036":54,"ITEM_037":55,"ITEM_038":56,"ITEM_039":57,"ITEM_03A":58,"ITEM_03B":59,"ITEM_03C":60,"ITEM_03D":61,"ITEM_03E":62,"ITEM_048":72,"ITEM_052":82,"ITEM_057":87,"ITEM_058":88,"ITEM_059":89,"ITEM_05A":90,"ITEM_05B":91,"ITEM_05C":92,"ITEM_063":99,"ITEM_064":100,"ITEM_065":101,"ITEM_066":102,"ITEM_069":105,"ITEM_071":113,"ITEM_072":114,"ITEM_073":115,"ITEM_074":116,"ITEM_075":117,"ITEM_076":118,"ITEM_077":119,"ITEM_078":120,"ITEM_0EA":234,"ITEM_0EB":235,"ITEM_0EC":236,"ITEM_0ED":237,"ITEM_0EE":238,"ITEM_0EF":239,"ITEM_0F0":240,"ITEM_0F1":241,"ITEM_0F2":242,"ITEM_0F3":243,"ITEM_0F4":244,"ITEM_0F5":245,"ITEM_0F6":246,"ITEM_0F7":247,"ITEM_0F8":248,"ITEM_0F9":249,"ITEM_0FA":250,"ITEM_0FB":251,"ITEM_0FC":252,"ITEM_0FD":253,"ITEM_10B":267,"ITEM_15B":347,"ITEM_15C":348,"ITEM_ACRO_BIKE":272,"ITEM_AGUAV_BERRY":146,"ITEM_AMULET_COIN":189,"ITEM_ANTIDOTE":14,"ITEM_APICOT_BERRY":172,"ITEM_ARCHIPELAGO_PROGRESSION":112,"ITEM_ASPEAR_BERRY":137,"ITEM_AURORA_TICKET":371,"ITEM_AWAKENING":17,"ITEM_BADGE_1":226,"ITEM_BADGE_2":227,"ITEM_BADGE_3":228,"ITEM_BADGE_4":229,"ITEM_BADGE_5":230,"ITEM_BADGE_6":231,"ITEM_BADGE_7":232,"ITEM_BADGE_8":233,"ITEM_BASEMENT_KEY":271,"ITEM_BEAD_MAIL":127,"ITEM_BELUE_BERRY":167,"ITEM_BERRY_JUICE":44,"ITEM_BERRY_POUCH":365,"ITEM_BICYCLE":360,"ITEM_BIG_MUSHROOM":104,"ITEM_BIG_PEARL":107,"ITEM_BIKE_VOUCHER":352,"ITEM_BLACK_BELT":207,"ITEM_BLACK_FLUTE":42,"ITEM_BLACK_GLASSES":206,"ITEM_BLUE_FLUTE":39,"ITEM_BLUE_ORB":277,"ITEM_BLUE_SCARF":255,"ITEM_BLUE_SHARD":49,"ITEM_BLUK_BERRY":149,"ITEM_BRIGHT_POWDER":179,"ITEM_BURN_HEAL":15,"ITEM_B_USE_MEDICINE":1,"ITEM_B_USE_OTHER":2,"ITEM_CALCIUM":67,"ITEM_CARBOS":66,"ITEM_CARD_KEY":355,"ITEM_CHARCOAL":215,"ITEM_CHERI_BERRY":133,"ITEM_CHESTO_BERRY":134,"ITEM_CHOICE_BAND":186,"ITEM_CLAW_FOSSIL":287,"ITEM_CLEANSE_TAG":190,"ITEM_COIN_CASE":260,"ITEM_CONTEST_PASS":266,"ITEM_CORNN_BERRY":159,"ITEM_DEEP_SEA_SCALE":193,"ITEM_DEEP_SEA_TOOTH":192,"ITEM_DEVON_GOODS":269,"ITEM_DEVON_SCOPE":288,"ITEM_DIRE_HIT":74,"ITEM_DIVE_BALL":7,"ITEM_DOME_FOSSIL":358,"ITEM_DRAGON_FANG":216,"ITEM_DRAGON_SCALE":201,"ITEM_DREAM_MAIL":130,"ITEM_DURIN_BERRY":166,"ITEM_ELIXIR":36,"ITEM_ENERGY_POWDER":30,"ITEM_ENERGY_ROOT":31,"ITEM_ENIGMA_BERRY":175,"ITEM_EON_TICKET":275,"ITEM_ESCAPE_ROPE":85,"ITEM_ETHER":34,"ITEM_EVERSTONE":195,"ITEM_EXP_SHARE":182,"ITEM_FAB_MAIL":131,"ITEM_FAME_CHECKER":363,"ITEM_FIGY_BERRY":143,"ITEM_FIRE_STONE":95,"ITEM_FLUFFY_TAIL":81,"ITEM_FOCUS_BAND":196,"ITEM_FRESH_WATER":26,"ITEM_FULL_HEAL":23,"ITEM_FULL_RESTORE":19,"ITEM_GANLON_BERRY":169,"ITEM_GLITTER_MAIL":123,"ITEM_GOLD_TEETH":353,"ITEM_GOOD_ROD":263,"ITEM_GO_GOGGLES":279,"ITEM_GREAT_BALL":3,"ITEM_GREEN_SCARF":257,"ITEM_GREEN_SHARD":51,"ITEM_GREPA_BERRY":157,"ITEM_GUARD_SPEC":73,"ITEM_HARBOR_MAIL":122,"ITEM_HARD_STONE":204,"ITEM_HEAL_POWDER":32,"ITEM_HEART_SCALE":111,"ITEM_HELIX_FOSSIL":357,"ITEM_HM01":339,"ITEM_HM02":340,"ITEM_HM03":341,"ITEM_HM04":342,"ITEM_HM05":343,"ITEM_HM06":344,"ITEM_HM07":345,"ITEM_HM08":346,"ITEM_HM_CUT":339,"ITEM_HM_DIVE":346,"ITEM_HM_FLASH":343,"ITEM_HM_FLY":340,"ITEM_HM_ROCK_SMASH":344,"ITEM_HM_STRENGTH":342,"ITEM_HM_SURF":341,"ITEM_HM_WATERFALL":345,"ITEM_HONDEW_BERRY":156,"ITEM_HP_UP":63,"ITEM_HYPER_POTION":21,"ITEM_IAPAPA_BERRY":147,"ITEM_ICE_HEAL":16,"ITEM_IRON":65,"ITEM_ITEMFINDER":261,"ITEM_KELPSY_BERRY":154,"ITEM_KINGS_ROCK":187,"ITEM_LANSAT_BERRY":173,"ITEM_LAVA_COOKIE":38,"ITEM_LAX_INCENSE":221,"ITEM_LEAF_STONE":98,"ITEM_LEFTOVERS":200,"ITEM_LEMONADE":28,"ITEM_LEPPA_BERRY":138,"ITEM_LETTER":274,"ITEM_LIECHI_BERRY":168,"ITEM_LIFT_KEY":356,"ITEM_LIGHT_BALL":202,"ITEM_LIST_END":65535,"ITEM_LUCKY_EGG":197,"ITEM_LUCKY_PUNCH":222,"ITEM_LUM_BERRY":141,"ITEM_LUXURY_BALL":11,"ITEM_MACHO_BRACE":181,"ITEM_MACH_BIKE":259,"ITEM_MAGMA_EMBLEM":375,"ITEM_MAGNET":208,"ITEM_MAGOST_BERRY":160,"ITEM_MAGO_BERRY":145,"ITEM_MASTER_BALL":1,"ITEM_MAX_ELIXIR":37,"ITEM_MAX_ETHER":35,"ITEM_MAX_POTION":20,"ITEM_MAX_REPEL":84,"ITEM_MAX_REVIVE":25,"ITEM_MECH_MAIL":124,"ITEM_MENTAL_HERB":185,"ITEM_METAL_COAT":199,"ITEM_METAL_POWDER":223,"ITEM_METEORITE":280,"ITEM_MIRACLE_SEED":205,"ITEM_MOOMOO_MILK":29,"ITEM_MOON_STONE":94,"ITEM_MYSTIC_TICKET":370,"ITEM_MYSTIC_WATER":209,"ITEM_NANAB_BERRY":150,"ITEM_NEST_BALL":8,"ITEM_NET_BALL":6,"ITEM_NEVER_MELT_ICE":212,"ITEM_NOMEL_BERRY":162,"ITEM_NONE":0,"ITEM_NUGGET":110,"ITEM_OAKS_PARCEL":349,"ITEM_OLD_AMBER":354,"ITEM_OLD_ROD":262,"ITEM_OLD_SEA_MAP":376,"ITEM_ORANGE_MAIL":121,"ITEM_ORAN_BERRY":139,"ITEM_PAMTRE_BERRY":164,"ITEM_PARALYZE_HEAL":18,"ITEM_PEARL":106,"ITEM_PECHA_BERRY":135,"ITEM_PERSIM_BERRY":140,"ITEM_PETAYA_BERRY":171,"ITEM_PINAP_BERRY":152,"ITEM_PINK_SCARF":256,"ITEM_POISON_BARB":211,"ITEM_POKEBLOCK_CASE":273,"ITEM_POKE_BALL":4,"ITEM_POKE_DOLL":80,"ITEM_POKE_FLUTE":350,"ITEM_POMEG_BERRY":153,"ITEM_POTION":13,"ITEM_POWDER_JAR":372,"ITEM_PP_MAX":71,"ITEM_PP_UP":69,"ITEM_PREMIER_BALL":12,"ITEM_PROTEIN":64,"ITEM_QUALOT_BERRY":155,"ITEM_QUICK_CLAW":183,"ITEM_RABUTA_BERRY":161,"ITEM_RAINBOW_PASS":368,"ITEM_RARE_CANDY":68,"ITEM_RAWST_BERRY":136,"ITEM_RAZZ_BERRY":148,"ITEM_RED_FLUTE":41,"ITEM_RED_ORB":276,"ITEM_RED_SCARF":254,"ITEM_RED_SHARD":48,"ITEM_REPEAT_BALL":9,"ITEM_REPEL":86,"ITEM_RETRO_MAIL":132,"ITEM_REVIVAL_HERB":33,"ITEM_REVIVE":24,"ITEM_ROOM_1_KEY":281,"ITEM_ROOM_2_KEY":282,"ITEM_ROOM_4_KEY":283,"ITEM_ROOM_6_KEY":284,"ITEM_ROOT_FOSSIL":286,"ITEM_RUBY":373,"ITEM_SACRED_ASH":45,"ITEM_SAFARI_BALL":5,"ITEM_SALAC_BERRY":170,"ITEM_SAPPHIRE":374,"ITEM_SCANNER":278,"ITEM_SCOPE_LENS":198,"ITEM_SEA_INCENSE":220,"ITEM_SECRET_KEY":351,"ITEM_SHADOW_MAIL":128,"ITEM_SHARP_BEAK":210,"ITEM_SHELL_BELL":219,"ITEM_SHOAL_SALT":46,"ITEM_SHOAL_SHELL":47,"ITEM_SILK_SCARF":217,"ITEM_SILPH_SCOPE":359,"ITEM_SILVER_POWDER":188,"ITEM_SITRUS_BERRY":142,"ITEM_SMOKE_BALL":194,"ITEM_SODA_POP":27,"ITEM_SOFT_SAND":203,"ITEM_SOOTHE_BELL":184,"ITEM_SOOT_SACK":270,"ITEM_SOUL_DEW":191,"ITEM_SPELL_TAG":213,"ITEM_SPELON_BERRY":163,"ITEM_SS_TICKET":265,"ITEM_STARDUST":108,"ITEM_STARF_BERRY":174,"ITEM_STAR_PIECE":109,"ITEM_STICK":225,"ITEM_STORAGE_KEY":285,"ITEM_SUN_STONE":93,"ITEM_SUPER_POTION":22,"ITEM_SUPER_REPEL":83,"ITEM_SUPER_ROD":264,"ITEM_TAMATO_BERRY":158,"ITEM_TEA":369,"ITEM_TEACHY_TV":366,"ITEM_THICK_CLUB":224,"ITEM_THUNDER_STONE":96,"ITEM_TIMER_BALL":10,"ITEM_TINY_MUSHROOM":103,"ITEM_TM01":289,"ITEM_TM02":290,"ITEM_TM03":291,"ITEM_TM04":292,"ITEM_TM05":293,"ITEM_TM06":294,"ITEM_TM07":295,"ITEM_TM08":296,"ITEM_TM09":297,"ITEM_TM10":298,"ITEM_TM11":299,"ITEM_TM12":300,"ITEM_TM13":301,"ITEM_TM14":302,"ITEM_TM15":303,"ITEM_TM16":304,"ITEM_TM17":305,"ITEM_TM18":306,"ITEM_TM19":307,"ITEM_TM20":308,"ITEM_TM21":309,"ITEM_TM22":310,"ITEM_TM23":311,"ITEM_TM24":312,"ITEM_TM25":313,"ITEM_TM26":314,"ITEM_TM27":315,"ITEM_TM28":316,"ITEM_TM29":317,"ITEM_TM30":318,"ITEM_TM31":319,"ITEM_TM32":320,"ITEM_TM33":321,"ITEM_TM34":322,"ITEM_TM35":323,"ITEM_TM36":324,"ITEM_TM37":325,"ITEM_TM38":326,"ITEM_TM39":327,"ITEM_TM40":328,"ITEM_TM41":329,"ITEM_TM42":330,"ITEM_TM43":331,"ITEM_TM44":332,"ITEM_TM45":333,"ITEM_TM46":334,"ITEM_TM47":335,"ITEM_TM48":336,"ITEM_TM49":337,"ITEM_TM50":338,"ITEM_TM_AERIAL_ACE":328,"ITEM_TM_ATTRACT":333,"ITEM_TM_BLIZZARD":302,"ITEM_TM_BRICK_BREAK":319,"ITEM_TM_BULK_UP":296,"ITEM_TM_BULLET_SEED":297,"ITEM_TM_CALM_MIND":292,"ITEM_TM_CASE":364,"ITEM_TM_DIG":316,"ITEM_TM_DOUBLE_TEAM":320,"ITEM_TM_DRAGON_CLAW":290,"ITEM_TM_EARTHQUAKE":314,"ITEM_TM_FACADE":330,"ITEM_TM_FIRE_BLAST":326,"ITEM_TM_FLAMETHROWER":323,"ITEM_TM_FOCUS_PUNCH":289,"ITEM_TM_FRUSTRATION":309,"ITEM_TM_GIGA_DRAIN":307,"ITEM_TM_HAIL":295,"ITEM_TM_HIDDEN_POWER":298,"ITEM_TM_HYPER_BEAM":303,"ITEM_TM_ICE_BEAM":301,"ITEM_TM_IRON_TAIL":311,"ITEM_TM_LIGHT_SCREEN":304,"ITEM_TM_OVERHEAT":338,"ITEM_TM_PROTECT":305,"ITEM_TM_PSYCHIC":317,"ITEM_TM_RAIN_DANCE":306,"ITEM_TM_REFLECT":321,"ITEM_TM_REST":332,"ITEM_TM_RETURN":315,"ITEM_TM_ROAR":293,"ITEM_TM_ROCK_TOMB":327,"ITEM_TM_SAFEGUARD":308,"ITEM_TM_SANDSTORM":325,"ITEM_TM_SECRET_POWER":331,"ITEM_TM_SHADOW_BALL":318,"ITEM_TM_SHOCK_WAVE":322,"ITEM_TM_SKILL_SWAP":336,"ITEM_TM_SLUDGE_BOMB":324,"ITEM_TM_SNATCH":337,"ITEM_TM_SOLAR_BEAM":310,"ITEM_TM_STEEL_WING":335,"ITEM_TM_SUNNY_DAY":299,"ITEM_TM_TAUNT":300,"ITEM_TM_THIEF":334,"ITEM_TM_THUNDER":313,"ITEM_TM_THUNDERBOLT":312,"ITEM_TM_TORMENT":329,"ITEM_TM_TOXIC":294,"ITEM_TM_WATER_PULSE":291,"ITEM_TOWN_MAP":361,"ITEM_TRI_PASS":367,"ITEM_TROPIC_MAIL":129,"ITEM_TWISTED_SPOON":214,"ITEM_ULTRA_BALL":2,"ITEM_UNUSED_BERRY_1":176,"ITEM_UNUSED_BERRY_2":177,"ITEM_UNUSED_BERRY_3":178,"ITEM_UP_GRADE":218,"ITEM_USE_BAG_MENU":4,"ITEM_USE_FIELD":2,"ITEM_USE_MAIL":0,"ITEM_USE_PARTY_MENU":1,"ITEM_USE_PBLOCK_CASE":3,"ITEM_VS_SEEKER":362,"ITEM_WAILMER_PAIL":268,"ITEM_WATER_STONE":97,"ITEM_WATMEL_BERRY":165,"ITEM_WAVE_MAIL":126,"ITEM_WEPEAR_BERRY":151,"ITEM_WHITE_FLUTE":43,"ITEM_WHITE_HERB":180,"ITEM_WIKI_BERRY":144,"ITEM_WOOD_MAIL":125,"ITEM_X_ACCURACY":78,"ITEM_X_ATTACK":75,"ITEM_X_DEFEND":76,"ITEM_X_SPECIAL":79,"ITEM_X_SPEED":77,"ITEM_YELLOW_FLUTE":40,"ITEM_YELLOW_SCARF":258,"ITEM_YELLOW_SHARD":50,"ITEM_ZINC":70,"LAST_BALL":12,"LAST_BERRY_INDEX":175,"LAST_BERRY_MASTER_BERRY":162,"LAST_BERRY_MASTER_WIFE_BERRY":142,"LAST_KIRI_BERRY":162,"LAST_ROUTE_114_MAN_BERRY":152,"MACH_BIKE":0,"MAIL_NONE":255,"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":6207,"MAP_ABANDONED_SHIP_CORRIDORS_1F":6199,"MAP_ABANDONED_SHIP_CORRIDORS_B1F":6201,"MAP_ABANDONED_SHIP_DECK":6198,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":6209,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":6210,"MAP_ABANDONED_SHIP_ROOMS2_1F":6206,"MAP_ABANDONED_SHIP_ROOMS2_B1F":6203,"MAP_ABANDONED_SHIP_ROOMS_1F":6200,"MAP_ABANDONED_SHIP_ROOMS_B1F":6202,"MAP_ABANDONED_SHIP_ROOM_B1F":6205,"MAP_ABANDONED_SHIP_UNDERWATER1":6204,"MAP_ABANDONED_SHIP_UNDERWATER2":6208,"MAP_ALTERING_CAVE":6250,"MAP_ANCIENT_TOMB":6212,"MAP_AQUA_HIDEOUT_1F":6167,"MAP_AQUA_HIDEOUT_B1F":6168,"MAP_AQUA_HIDEOUT_B2F":6169,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":6218,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":6219,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":6220,"MAP_ARTISAN_CAVE_1F":6244,"MAP_ARTISAN_CAVE_B1F":6243,"MAP_BATTLE_COLOSSEUM_2P":6424,"MAP_BATTLE_COLOSSEUM_4P":6427,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":6686,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":6685,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":6684,"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":6677,"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":6675,"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":6674,"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":6676,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":6689,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":6687,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":6688,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":6680,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":6679,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":6678,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":6691,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":6690,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":6694,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":6693,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":6695,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":6692,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":6682,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":6681,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":6683,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":6664,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":6663,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":6662,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":6661,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":6673,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":6672,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":6671,"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":6698,"MAP_BATTLE_FRONTIER_LOUNGE1":6697,"MAP_BATTLE_FRONTIER_LOUNGE2":6699,"MAP_BATTLE_FRONTIER_LOUNGE3":6700,"MAP_BATTLE_FRONTIER_LOUNGE4":6701,"MAP_BATTLE_FRONTIER_LOUNGE5":6703,"MAP_BATTLE_FRONTIER_LOUNGE6":6704,"MAP_BATTLE_FRONTIER_LOUNGE7":6705,"MAP_BATTLE_FRONTIER_LOUNGE8":6707,"MAP_BATTLE_FRONTIER_LOUNGE9":6708,"MAP_BATTLE_FRONTIER_MART":6711,"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":6670,"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":6660,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":6709,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":6710,"MAP_BATTLE_FRONTIER_RANKING_HALL":6696,"MAP_BATTLE_FRONTIER_RECEPTION_GATE":6706,"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":6702,"MAP_BATTLE_PYRAMID_SQUARE01":6444,"MAP_BATTLE_PYRAMID_SQUARE02":6445,"MAP_BATTLE_PYRAMID_SQUARE03":6446,"MAP_BATTLE_PYRAMID_SQUARE04":6447,"MAP_BATTLE_PYRAMID_SQUARE05":6448,"MAP_BATTLE_PYRAMID_SQUARE06":6449,"MAP_BATTLE_PYRAMID_SQUARE07":6450,"MAP_BATTLE_PYRAMID_SQUARE08":6451,"MAP_BATTLE_PYRAMID_SQUARE09":6452,"MAP_BATTLE_PYRAMID_SQUARE10":6453,"MAP_BATTLE_PYRAMID_SQUARE11":6454,"MAP_BATTLE_PYRAMID_SQUARE12":6455,"MAP_BATTLE_PYRAMID_SQUARE13":6456,"MAP_BATTLE_PYRAMID_SQUARE14":6457,"MAP_BATTLE_PYRAMID_SQUARE15":6458,"MAP_BATTLE_PYRAMID_SQUARE16":6459,"MAP_BIRTH_ISLAND_EXTERIOR":6714,"MAP_BIRTH_ISLAND_HARBOR":6715,"MAP_CAVE_OF_ORIGIN_1F":6182,"MAP_CAVE_OF_ORIGIN_B1F":6186,"MAP_CAVE_OF_ORIGIN_ENTRANCE":6181,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":6183,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":6184,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":6185,"MAP_CONTEST_HALL":6428,"MAP_CONTEST_HALL_BEAUTY":6435,"MAP_CONTEST_HALL_COOL":6437,"MAP_CONTEST_HALL_CUTE":6439,"MAP_CONTEST_HALL_SMART":6438,"MAP_CONTEST_HALL_TOUGH":6436,"MAP_DESERT_RUINS":6150,"MAP_DESERT_UNDERPASS":6242,"MAP_DEWFORD_TOWN":11,"MAP_DEWFORD_TOWN_GYM":771,"MAP_DEWFORD_TOWN_HALL":772,"MAP_DEWFORD_TOWN_HOUSE1":768,"MAP_DEWFORD_TOWN_HOUSE2":773,"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":769,"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":770,"MAP_EVER_GRANDE_CITY":8,"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":4100,"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":4099,"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":4098,"MAP_EVER_GRANDE_CITY_HALL1":4101,"MAP_EVER_GRANDE_CITY_HALL2":4102,"MAP_EVER_GRANDE_CITY_HALL3":4103,"MAP_EVER_GRANDE_CITY_HALL4":4104,"MAP_EVER_GRANDE_CITY_HALL5":4105,"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":4107,"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":4097,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":4108,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":4109,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":4106,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":4110,"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":4096,"MAP_FALLARBOR_TOWN":13,"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":1283,"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":1282,"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":1281,"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":1286,"MAP_FALLARBOR_TOWN_MART":1280,"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":1287,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":1284,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":1285,"MAP_FARAWAY_ISLAND_ENTRANCE":6712,"MAP_FARAWAY_ISLAND_INTERIOR":6713,"MAP_FIERY_PATH":6158,"MAP_FORTREE_CITY":4,"MAP_FORTREE_CITY_DECORATION_SHOP":3081,"MAP_FORTREE_CITY_GYM":3073,"MAP_FORTREE_CITY_HOUSE1":3072,"MAP_FORTREE_CITY_HOUSE2":3077,"MAP_FORTREE_CITY_HOUSE3":3078,"MAP_FORTREE_CITY_HOUSE4":3079,"MAP_FORTREE_CITY_HOUSE5":3080,"MAP_FORTREE_CITY_MART":3076,"MAP_FORTREE_CITY_POKEMON_CENTER_1F":3074,"MAP_FORTREE_CITY_POKEMON_CENTER_2F":3075,"MAP_GRANITE_CAVE_1F":6151,"MAP_GRANITE_CAVE_B1F":6152,"MAP_GRANITE_CAVE_B2F":6153,"MAP_GRANITE_CAVE_STEVENS_ROOM":6154,"MAP_GROUPS_COUNT":34,"MAP_INSIDE_OF_TRUCK":6440,"MAP_ISLAND_CAVE":6211,"MAP_JAGGED_PASS":6157,"MAP_LAVARIDGE_TOWN":12,"MAP_LAVARIDGE_TOWN_GYM_1F":1025,"MAP_LAVARIDGE_TOWN_GYM_B1F":1026,"MAP_LAVARIDGE_TOWN_HERB_SHOP":1024,"MAP_LAVARIDGE_TOWN_HOUSE":1027,"MAP_LAVARIDGE_TOWN_MART":1028,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":1029,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":1030,"MAP_LILYCOVE_CITY":5,"MAP_LILYCOVE_CITY_CONTEST_HALL":3333,"MAP_LILYCOVE_CITY_CONTEST_LOBBY":3332,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":3328,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":3329,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":3344,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":3345,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":3346,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":3347,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":3348,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":3350,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":3349,"MAP_LILYCOVE_CITY_HARBOR":3338,"MAP_LILYCOVE_CITY_HOUSE1":3340,"MAP_LILYCOVE_CITY_HOUSE2":3341,"MAP_LILYCOVE_CITY_HOUSE3":3342,"MAP_LILYCOVE_CITY_HOUSE4":3343,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":3330,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":3331,"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":3339,"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":3334,"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":3335,"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":3337,"MAP_LILYCOVE_CITY_UNUSED_MART":3336,"MAP_LITTLEROOT_TOWN":9,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":256,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":257,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":258,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":259,"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":260,"MAP_MAGMA_HIDEOUT_1F":6230,"MAP_MAGMA_HIDEOUT_2F_1R":6231,"MAP_MAGMA_HIDEOUT_2F_2R":6232,"MAP_MAGMA_HIDEOUT_2F_3R":6237,"MAP_MAGMA_HIDEOUT_3F_1R":6233,"MAP_MAGMA_HIDEOUT_3F_2R":6234,"MAP_MAGMA_HIDEOUT_3F_3R":6236,"MAP_MAGMA_HIDEOUT_4F":6235,"MAP_MARINE_CAVE_END":6247,"MAP_MARINE_CAVE_ENTRANCE":6246,"MAP_MAUVILLE_CITY":2,"MAP_MAUVILLE_CITY_BIKE_SHOP":2561,"MAP_MAUVILLE_CITY_GAME_CORNER":2563,"MAP_MAUVILLE_CITY_GYM":2560,"MAP_MAUVILLE_CITY_HOUSE1":2562,"MAP_MAUVILLE_CITY_HOUSE2":2564,"MAP_MAUVILLE_CITY_MART":2567,"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":2565,"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":2566,"MAP_METEOR_FALLS_1F_1R":6144,"MAP_METEOR_FALLS_1F_2R":6145,"MAP_METEOR_FALLS_B1F_1R":6146,"MAP_METEOR_FALLS_B1F_2R":6147,"MAP_METEOR_FALLS_STEVENS_CAVE":6251,"MAP_MIRAGE_TOWER_1F":6238,"MAP_MIRAGE_TOWER_2F":6239,"MAP_MIRAGE_TOWER_3F":6240,"MAP_MIRAGE_TOWER_4F":6241,"MAP_MOSSDEEP_CITY":6,"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":3595,"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":3596,"MAP_MOSSDEEP_CITY_GYM":3584,"MAP_MOSSDEEP_CITY_HOUSE1":3585,"MAP_MOSSDEEP_CITY_HOUSE2":3586,"MAP_MOSSDEEP_CITY_HOUSE3":3590,"MAP_MOSSDEEP_CITY_HOUSE4":3592,"MAP_MOSSDEEP_CITY_MART":3589,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":3587,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":3588,"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":3593,"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":3594,"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":3591,"MAP_MT_CHIMNEY":6156,"MAP_MT_CHIMNEY_CABLE_CAR_STATION":4865,"MAP_MT_PYRE_1F":6159,"MAP_MT_PYRE_2F":6160,"MAP_MT_PYRE_3F":6161,"MAP_MT_PYRE_4F":6162,"MAP_MT_PYRE_5F":6163,"MAP_MT_PYRE_6F":6164,"MAP_MT_PYRE_EXTERIOR":6165,"MAP_MT_PYRE_SUMMIT":6166,"MAP_NAVEL_ROCK_B1F":6725,"MAP_NAVEL_ROCK_BOTTOM":6743,"MAP_NAVEL_ROCK_DOWN01":6732,"MAP_NAVEL_ROCK_DOWN02":6733,"MAP_NAVEL_ROCK_DOWN03":6734,"MAP_NAVEL_ROCK_DOWN04":6735,"MAP_NAVEL_ROCK_DOWN05":6736,"MAP_NAVEL_ROCK_DOWN06":6737,"MAP_NAVEL_ROCK_DOWN07":6738,"MAP_NAVEL_ROCK_DOWN08":6739,"MAP_NAVEL_ROCK_DOWN09":6740,"MAP_NAVEL_ROCK_DOWN10":6741,"MAP_NAVEL_ROCK_DOWN11":6742,"MAP_NAVEL_ROCK_ENTRANCE":6724,"MAP_NAVEL_ROCK_EXTERIOR":6722,"MAP_NAVEL_ROCK_FORK":6726,"MAP_NAVEL_ROCK_HARBOR":6723,"MAP_NAVEL_ROCK_TOP":6731,"MAP_NAVEL_ROCK_UP1":6727,"MAP_NAVEL_ROCK_UP2":6728,"MAP_NAVEL_ROCK_UP3":6729,"MAP_NAVEL_ROCK_UP4":6730,"MAP_NEW_MAUVILLE_ENTRANCE":6196,"MAP_NEW_MAUVILLE_INSIDE":6197,"MAP_OLDALE_TOWN":10,"MAP_OLDALE_TOWN_HOUSE1":512,"MAP_OLDALE_TOWN_HOUSE2":513,"MAP_OLDALE_TOWN_MART":516,"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":514,"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":515,"MAP_PACIFIDLOG_TOWN":15,"MAP_PACIFIDLOG_TOWN_HOUSE1":1794,"MAP_PACIFIDLOG_TOWN_HOUSE2":1795,"MAP_PACIFIDLOG_TOWN_HOUSE3":1796,"MAP_PACIFIDLOG_TOWN_HOUSE4":1797,"MAP_PACIFIDLOG_TOWN_HOUSE5":1798,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":1792,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":1793,"MAP_PETALBURG_CITY":0,"MAP_PETALBURG_CITY_GYM":2049,"MAP_PETALBURG_CITY_HOUSE1":2050,"MAP_PETALBURG_CITY_HOUSE2":2051,"MAP_PETALBURG_CITY_MART":2054,"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":2052,"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":2053,"MAP_PETALBURG_CITY_WALLYS_HOUSE":2048,"MAP_PETALBURG_WOODS":6155,"MAP_RECORD_CORNER":6426,"MAP_ROUTE101":16,"MAP_ROUTE102":17,"MAP_ROUTE103":18,"MAP_ROUTE104":19,"MAP_ROUTE104_MR_BRINEYS_HOUSE":4352,"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":4353,"MAP_ROUTE104_PROTOTYPE":6912,"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":6913,"MAP_ROUTE105":20,"MAP_ROUTE106":21,"MAP_ROUTE107":22,"MAP_ROUTE108":23,"MAP_ROUTE109":24,"MAP_ROUTE109_SEASHORE_HOUSE":7168,"MAP_ROUTE110":25,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":7435,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":7436,"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":7426,"MAP_ROUTE110_TRICK_HOUSE_END":7425,"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":7424,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":7427,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":7428,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":7429,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":7430,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":7431,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":7432,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":7433,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":7434,"MAP_ROUTE111":26,"MAP_ROUTE111_OLD_LADYS_REST_STOP":4609,"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":4608,"MAP_ROUTE112":27,"MAP_ROUTE112_CABLE_CAR_STATION":4864,"MAP_ROUTE113":28,"MAP_ROUTE113_GLASS_WORKSHOP":7680,"MAP_ROUTE114":29,"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":5120,"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":5121,"MAP_ROUTE114_LANETTES_HOUSE":5122,"MAP_ROUTE115":30,"MAP_ROUTE116":31,"MAP_ROUTE116_TUNNELERS_REST_HOUSE":5376,"MAP_ROUTE117":32,"MAP_ROUTE117_POKEMON_DAY_CARE":5632,"MAP_ROUTE118":33,"MAP_ROUTE119":34,"MAP_ROUTE119_HOUSE":8194,"MAP_ROUTE119_WEATHER_INSTITUTE_1F":8192,"MAP_ROUTE119_WEATHER_INSTITUTE_2F":8193,"MAP_ROUTE120":35,"MAP_ROUTE121":36,"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":5888,"MAP_ROUTE122":37,"MAP_ROUTE123":38,"MAP_ROUTE123_BERRY_MASTERS_HOUSE":7936,"MAP_ROUTE124":39,"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":8448,"MAP_ROUTE125":40,"MAP_ROUTE126":41,"MAP_ROUTE127":42,"MAP_ROUTE128":43,"MAP_ROUTE129":44,"MAP_ROUTE130":45,"MAP_ROUTE131":46,"MAP_ROUTE132":47,"MAP_ROUTE133":48,"MAP_ROUTE134":49,"MAP_RUSTBORO_CITY":3,"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":2827,"MAP_RUSTBORO_CITY_DEVON_CORP_1F":2816,"MAP_RUSTBORO_CITY_DEVON_CORP_2F":2817,"MAP_RUSTBORO_CITY_DEVON_CORP_3F":2818,"MAP_RUSTBORO_CITY_FLAT1_1F":2824,"MAP_RUSTBORO_CITY_FLAT1_2F":2825,"MAP_RUSTBORO_CITY_FLAT2_1F":2829,"MAP_RUSTBORO_CITY_FLAT2_2F":2830,"MAP_RUSTBORO_CITY_FLAT2_3F":2831,"MAP_RUSTBORO_CITY_GYM":2819,"MAP_RUSTBORO_CITY_HOUSE1":2826,"MAP_RUSTBORO_CITY_HOUSE2":2828,"MAP_RUSTBORO_CITY_HOUSE3":2832,"MAP_RUSTBORO_CITY_MART":2823,"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":2821,"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":2822,"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":2820,"MAP_RUSTURF_TUNNEL":6148,"MAP_SAFARI_ZONE_NORTH":6657,"MAP_SAFARI_ZONE_NORTHEAST":6668,"MAP_SAFARI_ZONE_NORTHWEST":6656,"MAP_SAFARI_ZONE_REST_HOUSE":6667,"MAP_SAFARI_ZONE_SOUTH":6659,"MAP_SAFARI_ZONE_SOUTHEAST":6669,"MAP_SAFARI_ZONE_SOUTHWEST":6658,"MAP_SCORCHED_SLAB":6217,"MAP_SEAFLOOR_CAVERN_ENTRANCE":6171,"MAP_SEAFLOOR_CAVERN_ROOM1":6172,"MAP_SEAFLOOR_CAVERN_ROOM2":6173,"MAP_SEAFLOOR_CAVERN_ROOM3":6174,"MAP_SEAFLOOR_CAVERN_ROOM4":6175,"MAP_SEAFLOOR_CAVERN_ROOM5":6176,"MAP_SEAFLOOR_CAVERN_ROOM6":6177,"MAP_SEAFLOOR_CAVERN_ROOM7":6178,"MAP_SEAFLOOR_CAVERN_ROOM8":6179,"MAP_SEAFLOOR_CAVERN_ROOM9":6180,"MAP_SEALED_CHAMBER_INNER_ROOM":6216,"MAP_SEALED_CHAMBER_OUTER_ROOM":6215,"MAP_SECRET_BASE_BLUE_CAVE1":6402,"MAP_SECRET_BASE_BLUE_CAVE2":6408,"MAP_SECRET_BASE_BLUE_CAVE3":6414,"MAP_SECRET_BASE_BLUE_CAVE4":6420,"MAP_SECRET_BASE_BROWN_CAVE1":6401,"MAP_SECRET_BASE_BROWN_CAVE2":6407,"MAP_SECRET_BASE_BROWN_CAVE3":6413,"MAP_SECRET_BASE_BROWN_CAVE4":6419,"MAP_SECRET_BASE_RED_CAVE1":6400,"MAP_SECRET_BASE_RED_CAVE2":6406,"MAP_SECRET_BASE_RED_CAVE3":6412,"MAP_SECRET_BASE_RED_CAVE4":6418,"MAP_SECRET_BASE_SHRUB1":6405,"MAP_SECRET_BASE_SHRUB2":6411,"MAP_SECRET_BASE_SHRUB3":6417,"MAP_SECRET_BASE_SHRUB4":6423,"MAP_SECRET_BASE_TREE1":6404,"MAP_SECRET_BASE_TREE2":6410,"MAP_SECRET_BASE_TREE3":6416,"MAP_SECRET_BASE_TREE4":6422,"MAP_SECRET_BASE_YELLOW_CAVE1":6403,"MAP_SECRET_BASE_YELLOW_CAVE2":6409,"MAP_SECRET_BASE_YELLOW_CAVE3":6415,"MAP_SECRET_BASE_YELLOW_CAVE4":6421,"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":6194,"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":6195,"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":6190,"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":6227,"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":6191,"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":6193,"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":6192,"MAP_SKY_PILLAR_1F":6223,"MAP_SKY_PILLAR_2F":6224,"MAP_SKY_PILLAR_3F":6225,"MAP_SKY_PILLAR_4F":6226,"MAP_SKY_PILLAR_5F":6228,"MAP_SKY_PILLAR_ENTRANCE":6221,"MAP_SKY_PILLAR_OUTSIDE":6222,"MAP_SKY_PILLAR_TOP":6229,"MAP_SLATEPORT_CITY":1,"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":2308,"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":2307,"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":2306,"MAP_SLATEPORT_CITY_HARBOR":2313,"MAP_SLATEPORT_CITY_HOUSE":2314,"MAP_SLATEPORT_CITY_MART":2317,"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":2309,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":2311,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":2312,"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":2315,"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":2316,"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":2310,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":2304,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":2305,"MAP_SOOTOPOLIS_CITY":7,"MAP_SOOTOPOLIS_CITY_GYM_1F":3840,"MAP_SOOTOPOLIS_CITY_GYM_B1F":3841,"MAP_SOOTOPOLIS_CITY_HOUSE1":3845,"MAP_SOOTOPOLIS_CITY_HOUSE2":3846,"MAP_SOOTOPOLIS_CITY_HOUSE3":3847,"MAP_SOOTOPOLIS_CITY_HOUSE4":3848,"MAP_SOOTOPOLIS_CITY_HOUSE5":3849,"MAP_SOOTOPOLIS_CITY_HOUSE6":3850,"MAP_SOOTOPOLIS_CITY_HOUSE7":3851,"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":3852,"MAP_SOOTOPOLIS_CITY_MART":3844,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":3853,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":3854,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":3842,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":3843,"MAP_SOUTHERN_ISLAND_EXTERIOR":6665,"MAP_SOUTHERN_ISLAND_INTERIOR":6666,"MAP_SS_TIDAL_CORRIDOR":6441,"MAP_SS_TIDAL_LOWER_DECK":6442,"MAP_SS_TIDAL_ROOMS":6443,"MAP_TERRA_CAVE_END":6249,"MAP_TERRA_CAVE_ENTRANCE":6248,"MAP_TRADE_CENTER":6425,"MAP_TRAINER_HILL_1F":6717,"MAP_TRAINER_HILL_2F":6718,"MAP_TRAINER_HILL_3F":6719,"MAP_TRAINER_HILL_4F":6720,"MAP_TRAINER_HILL_ELEVATOR":6744,"MAP_TRAINER_HILL_ENTRANCE":6716,"MAP_TRAINER_HILL_ROOF":6721,"MAP_UNDERWATER_MARINE_CAVE":6245,"MAP_UNDERWATER_ROUTE105":55,"MAP_UNDERWATER_ROUTE124":50,"MAP_UNDERWATER_ROUTE125":56,"MAP_UNDERWATER_ROUTE126":51,"MAP_UNDERWATER_ROUTE127":52,"MAP_UNDERWATER_ROUTE128":53,"MAP_UNDERWATER_ROUTE129":54,"MAP_UNDERWATER_ROUTE134":6213,"MAP_UNDERWATER_SEAFLOOR_CAVERN":6170,"MAP_UNDERWATER_SEALED_CHAMBER":6214,"MAP_UNDERWATER_SOOTOPOLIS_CITY":6149,"MAP_UNION_ROOM":6460,"MAP_UNUSED_CONTEST_HALL1":6429,"MAP_UNUSED_CONTEST_HALL2":6430,"MAP_UNUSED_CONTEST_HALL3":6431,"MAP_UNUSED_CONTEST_HALL4":6432,"MAP_UNUSED_CONTEST_HALL5":6433,"MAP_UNUSED_CONTEST_HALL6":6434,"MAP_VERDANTURF_TOWN":14,"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":1538,"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":1537,"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":1536,"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":1543,"MAP_VERDANTURF_TOWN_HOUSE":1544,"MAP_VERDANTURF_TOWN_MART":1539,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":1540,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":1541,"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":1542,"MAP_VICTORY_ROAD_1F":6187,"MAP_VICTORY_ROAD_B1F":6188,"MAP_VICTORY_ROAD_B2F":6189,"MAX_BAG_ITEM_CAPACITY":99,"MAX_BERRY_CAPACITY":999,"MAX_BERRY_INDEX":178,"MAX_ITEM_DIGITS":3,"MAX_PC_ITEM_CAPACITY":999,"MAX_TRAINERS_COUNT":864,"MOVES_COUNT":355,"MOVE_ABSORB":71,"MOVE_ACID":51,"MOVE_ACID_ARMOR":151,"MOVE_AERIAL_ACE":332,"MOVE_AEROBLAST":177,"MOVE_AGILITY":97,"MOVE_AIR_CUTTER":314,"MOVE_AMNESIA":133,"MOVE_ANCIENT_POWER":246,"MOVE_ARM_THRUST":292,"MOVE_AROMATHERAPY":312,"MOVE_ASSIST":274,"MOVE_ASTONISH":310,"MOVE_ATTRACT":213,"MOVE_AURORA_BEAM":62,"MOVE_BARRAGE":140,"MOVE_BARRIER":112,"MOVE_BATON_PASS":226,"MOVE_BEAT_UP":251,"MOVE_BELLY_DRUM":187,"MOVE_BIDE":117,"MOVE_BIND":20,"MOVE_BITE":44,"MOVE_BLAST_BURN":307,"MOVE_BLAZE_KICK":299,"MOVE_BLIZZARD":59,"MOVE_BLOCK":335,"MOVE_BODY_SLAM":34,"MOVE_BONEMERANG":155,"MOVE_BONE_CLUB":125,"MOVE_BONE_RUSH":198,"MOVE_BOUNCE":340,"MOVE_BRICK_BREAK":280,"MOVE_BUBBLE":145,"MOVE_BUBBLE_BEAM":61,"MOVE_BULK_UP":339,"MOVE_BULLET_SEED":331,"MOVE_CALM_MIND":347,"MOVE_CAMOUFLAGE":293,"MOVE_CHARGE":268,"MOVE_CHARM":204,"MOVE_CLAMP":128,"MOVE_COMET_PUNCH":4,"MOVE_CONFUSE_RAY":109,"MOVE_CONFUSION":93,"MOVE_CONSTRICT":132,"MOVE_CONVERSION":160,"MOVE_CONVERSION_2":176,"MOVE_COSMIC_POWER":322,"MOVE_COTTON_SPORE":178,"MOVE_COUNTER":68,"MOVE_COVET":343,"MOVE_CRABHAMMER":152,"MOVE_CROSS_CHOP":238,"MOVE_CRUNCH":242,"MOVE_CRUSH_CLAW":306,"MOVE_CURSE":174,"MOVE_CUT":15,"MOVE_DEFENSE_CURL":111,"MOVE_DESTINY_BOND":194,"MOVE_DETECT":197,"MOVE_DIG":91,"MOVE_DISABLE":50,"MOVE_DIVE":291,"MOVE_DIZZY_PUNCH":146,"MOVE_DOOM_DESIRE":353,"MOVE_DOUBLE_EDGE":38,"MOVE_DOUBLE_KICK":24,"MOVE_DOUBLE_SLAP":3,"MOVE_DOUBLE_TEAM":104,"MOVE_DRAGON_BREATH":225,"MOVE_DRAGON_CLAW":337,"MOVE_DRAGON_DANCE":349,"MOVE_DRAGON_RAGE":82,"MOVE_DREAM_EATER":138,"MOVE_DRILL_PECK":65,"MOVE_DYNAMIC_PUNCH":223,"MOVE_EARTHQUAKE":89,"MOVE_EGG_BOMB":121,"MOVE_EMBER":52,"MOVE_ENCORE":227,"MOVE_ENDEAVOR":283,"MOVE_ENDURE":203,"MOVE_ERUPTION":284,"MOVE_EXPLOSION":153,"MOVE_EXTRASENSORY":326,"MOVE_EXTREME_SPEED":245,"MOVE_FACADE":263,"MOVE_FAINT_ATTACK":185,"MOVE_FAKE_OUT":252,"MOVE_FAKE_TEARS":313,"MOVE_FALSE_SWIPE":206,"MOVE_FEATHER_DANCE":297,"MOVE_FIRE_BLAST":126,"MOVE_FIRE_PUNCH":7,"MOVE_FIRE_SPIN":83,"MOVE_FISSURE":90,"MOVE_FLAIL":175,"MOVE_FLAMETHROWER":53,"MOVE_FLAME_WHEEL":172,"MOVE_FLASH":148,"MOVE_FLATTER":260,"MOVE_FLY":19,"MOVE_FOCUS_ENERGY":116,"MOVE_FOCUS_PUNCH":264,"MOVE_FOLLOW_ME":266,"MOVE_FORESIGHT":193,"MOVE_FRENZY_PLANT":338,"MOVE_FRUSTRATION":218,"MOVE_FURY_ATTACK":31,"MOVE_FURY_CUTTER":210,"MOVE_FURY_SWIPES":154,"MOVE_FUTURE_SIGHT":248,"MOVE_GIGA_DRAIN":202,"MOVE_GLARE":137,"MOVE_GRASS_WHISTLE":320,"MOVE_GROWL":45,"MOVE_GROWTH":74,"MOVE_GRUDGE":288,"MOVE_GUILLOTINE":12,"MOVE_GUST":16,"MOVE_HAIL":258,"MOVE_HARDEN":106,"MOVE_HAZE":114,"MOVE_HEADBUTT":29,"MOVE_HEAL_BELL":215,"MOVE_HEAT_WAVE":257,"MOVE_HELPING_HAND":270,"MOVE_HIDDEN_POWER":237,"MOVE_HI_JUMP_KICK":136,"MOVE_HORN_ATTACK":30,"MOVE_HORN_DRILL":32,"MOVE_HOWL":336,"MOVE_HYDRO_CANNON":308,"MOVE_HYDRO_PUMP":56,"MOVE_HYPER_BEAM":63,"MOVE_HYPER_FANG":158,"MOVE_HYPER_VOICE":304,"MOVE_HYPNOSIS":95,"MOVE_ICE_BALL":301,"MOVE_ICE_BEAM":58,"MOVE_ICE_PUNCH":8,"MOVE_ICICLE_SPEAR":333,"MOVE_ICY_WIND":196,"MOVE_IMPRISON":286,"MOVE_INGRAIN":275,"MOVE_IRON_DEFENSE":334,"MOVE_IRON_TAIL":231,"MOVE_JUMP_KICK":26,"MOVE_KARATE_CHOP":2,"MOVE_KINESIS":134,"MOVE_KNOCK_OFF":282,"MOVE_LEAF_BLADE":348,"MOVE_LEECH_LIFE":141,"MOVE_LEECH_SEED":73,"MOVE_LEER":43,"MOVE_LICK":122,"MOVE_LIGHT_SCREEN":113,"MOVE_LOCK_ON":199,"MOVE_LOVELY_KISS":142,"MOVE_LOW_KICK":67,"MOVE_LUSTER_PURGE":295,"MOVE_MACH_PUNCH":183,"MOVE_MAGICAL_LEAF":345,"MOVE_MAGIC_COAT":277,"MOVE_MAGNITUDE":222,"MOVE_MEAN_LOOK":212,"MOVE_MEDITATE":96,"MOVE_MEGAHORN":224,"MOVE_MEGA_DRAIN":72,"MOVE_MEGA_KICK":25,"MOVE_MEGA_PUNCH":5,"MOVE_MEMENTO":262,"MOVE_METAL_CLAW":232,"MOVE_METAL_SOUND":319,"MOVE_METEOR_MASH":309,"MOVE_METRONOME":118,"MOVE_MILK_DRINK":208,"MOVE_MIMIC":102,"MOVE_MIND_READER":170,"MOVE_MINIMIZE":107,"MOVE_MIRROR_COAT":243,"MOVE_MIRROR_MOVE":119,"MOVE_MIST":54,"MOVE_MIST_BALL":296,"MOVE_MOONLIGHT":236,"MOVE_MORNING_SUN":234,"MOVE_MUDDY_WATER":330,"MOVE_MUD_SHOT":341,"MOVE_MUD_SLAP":189,"MOVE_MUD_SPORT":300,"MOVE_NATURE_POWER":267,"MOVE_NEEDLE_ARM":302,"MOVE_NIGHTMARE":171,"MOVE_NIGHT_SHADE":101,"MOVE_NONE":0,"MOVE_OCTAZOOKA":190,"MOVE_ODOR_SLEUTH":316,"MOVE_OUTRAGE":200,"MOVE_OVERHEAT":315,"MOVE_PAIN_SPLIT":220,"MOVE_PAY_DAY":6,"MOVE_PECK":64,"MOVE_PERISH_SONG":195,"MOVE_PETAL_DANCE":80,"MOVE_PIN_MISSILE":42,"MOVE_POISON_FANG":305,"MOVE_POISON_GAS":139,"MOVE_POISON_POWDER":77,"MOVE_POISON_STING":40,"MOVE_POISON_TAIL":342,"MOVE_POUND":1,"MOVE_POWDER_SNOW":181,"MOVE_PRESENT":217,"MOVE_PROTECT":182,"MOVE_PSYBEAM":60,"MOVE_PSYCHIC":94,"MOVE_PSYCHO_BOOST":354,"MOVE_PSYCH_UP":244,"MOVE_PSYWAVE":149,"MOVE_PURSUIT":228,"MOVE_QUICK_ATTACK":98,"MOVE_RAGE":99,"MOVE_RAIN_DANCE":240,"MOVE_RAPID_SPIN":229,"MOVE_RAZOR_LEAF":75,"MOVE_RAZOR_WIND":13,"MOVE_RECOVER":105,"MOVE_RECYCLE":278,"MOVE_REFLECT":115,"MOVE_REFRESH":287,"MOVE_REST":156,"MOVE_RETURN":216,"MOVE_REVENGE":279,"MOVE_REVERSAL":179,"MOVE_ROAR":46,"MOVE_ROCK_BLAST":350,"MOVE_ROCK_SLIDE":157,"MOVE_ROCK_SMASH":249,"MOVE_ROCK_THROW":88,"MOVE_ROCK_TOMB":317,"MOVE_ROLE_PLAY":272,"MOVE_ROLLING_KICK":27,"MOVE_ROLLOUT":205,"MOVE_SACRED_FIRE":221,"MOVE_SAFEGUARD":219,"MOVE_SANDSTORM":201,"MOVE_SAND_ATTACK":28,"MOVE_SAND_TOMB":328,"MOVE_SCARY_FACE":184,"MOVE_SCRATCH":10,"MOVE_SCREECH":103,"MOVE_SECRET_POWER":290,"MOVE_SEISMIC_TOSS":69,"MOVE_SELF_DESTRUCT":120,"MOVE_SHADOW_BALL":247,"MOVE_SHADOW_PUNCH":325,"MOVE_SHARPEN":159,"MOVE_SHEER_COLD":329,"MOVE_SHOCK_WAVE":351,"MOVE_SIGNAL_BEAM":324,"MOVE_SILVER_WIND":318,"MOVE_SING":47,"MOVE_SKETCH":166,"MOVE_SKILL_SWAP":285,"MOVE_SKULL_BASH":130,"MOVE_SKY_ATTACK":143,"MOVE_SKY_UPPERCUT":327,"MOVE_SLACK_OFF":303,"MOVE_SLAM":21,"MOVE_SLASH":163,"MOVE_SLEEP_POWDER":79,"MOVE_SLEEP_TALK":214,"MOVE_SLUDGE":124,"MOVE_SLUDGE_BOMB":188,"MOVE_SMELLING_SALT":265,"MOVE_SMOG":123,"MOVE_SMOKESCREEN":108,"MOVE_SNATCH":289,"MOVE_SNORE":173,"MOVE_SOFT_BOILED":135,"MOVE_SOLAR_BEAM":76,"MOVE_SONIC_BOOM":49,"MOVE_SPARK":209,"MOVE_SPIDER_WEB":169,"MOVE_SPIKES":191,"MOVE_SPIKE_CANNON":131,"MOVE_SPITE":180,"MOVE_SPIT_UP":255,"MOVE_SPLASH":150,"MOVE_SPORE":147,"MOVE_STEEL_WING":211,"MOVE_STOCKPILE":254,"MOVE_STOMP":23,"MOVE_STRENGTH":70,"MOVE_STRING_SHOT":81,"MOVE_STRUGGLE":165,"MOVE_STUN_SPORE":78,"MOVE_SUBMISSION":66,"MOVE_SUBSTITUTE":164,"MOVE_SUNNY_DAY":241,"MOVE_SUPERPOWER":276,"MOVE_SUPERSONIC":48,"MOVE_SUPER_FANG":162,"MOVE_SURF":57,"MOVE_SWAGGER":207,"MOVE_SWALLOW":256,"MOVE_SWEET_KISS":186,"MOVE_SWEET_SCENT":230,"MOVE_SWIFT":129,"MOVE_SWORDS_DANCE":14,"MOVE_SYNTHESIS":235,"MOVE_TACKLE":33,"MOVE_TAIL_GLOW":294,"MOVE_TAIL_WHIP":39,"MOVE_TAKE_DOWN":36,"MOVE_TAUNT":269,"MOVE_TEETER_DANCE":298,"MOVE_TELEPORT":100,"MOVE_THIEF":168,"MOVE_THRASH":37,"MOVE_THUNDER":87,"MOVE_THUNDERBOLT":85,"MOVE_THUNDER_PUNCH":9,"MOVE_THUNDER_SHOCK":84,"MOVE_THUNDER_WAVE":86,"MOVE_TICKLE":321,"MOVE_TORMENT":259,"MOVE_TOXIC":92,"MOVE_TRANSFORM":144,"MOVE_TRICK":271,"MOVE_TRIPLE_KICK":167,"MOVE_TRI_ATTACK":161,"MOVE_TWINEEDLE":41,"MOVE_TWISTER":239,"MOVE_UNAVAILABLE":65535,"MOVE_UPROAR":253,"MOVE_VICE_GRIP":11,"MOVE_VINE_WHIP":22,"MOVE_VITAL_THROW":233,"MOVE_VOLT_TACKLE":344,"MOVE_WATERFALL":127,"MOVE_WATER_GUN":55,"MOVE_WATER_PULSE":352,"MOVE_WATER_SPORT":346,"MOVE_WATER_SPOUT":323,"MOVE_WEATHER_BALL":311,"MOVE_WHIRLPOOL":250,"MOVE_WHIRLWIND":18,"MOVE_WILL_O_WISP":261,"MOVE_WING_ATTACK":17,"MOVE_WISH":273,"MOVE_WITHDRAW":110,"MOVE_WRAP":35,"MOVE_YAWN":281,"MOVE_ZAP_CANNON":192,"MUS_ABANDONED_SHIP":381,"MUS_ABNORMAL_WEATHER":443,"MUS_AQUA_MAGMA_HIDEOUT":430,"MUS_AWAKEN_LEGEND":388,"MUS_BIRCH_LAB":383,"MUS_B_ARENA":458,"MUS_B_DOME":467,"MUS_B_DOME_LOBBY":473,"MUS_B_FACTORY":469,"MUS_B_FRONTIER":457,"MUS_B_PALACE":463,"MUS_B_PIKE":468,"MUS_B_PYRAMID":461,"MUS_B_PYRAMID_TOP":462,"MUS_B_TOWER":465,"MUS_B_TOWER_RS":384,"MUS_CABLE_CAR":425,"MUS_CAUGHT":352,"MUS_CAVE_OF_ORIGIN":386,"MUS_CONTEST":440,"MUS_CONTEST_LOBBY":452,"MUS_CONTEST_RESULTS":446,"MUS_CONTEST_WINNER":439,"MUS_CREDITS":455,"MUS_CYCLING":403,"MUS_C_COMM_CENTER":356,"MUS_C_VS_LEGEND_BEAST":358,"MUS_DESERT":409,"MUS_DEWFORD":427,"MUS_DUMMY":0,"MUS_ENCOUNTER_AQUA":419,"MUS_ENCOUNTER_BRENDAN":421,"MUS_ENCOUNTER_CHAMPION":454,"MUS_ENCOUNTER_COOL":417,"MUS_ENCOUNTER_ELITE_FOUR":450,"MUS_ENCOUNTER_FEMALE":407,"MUS_ENCOUNTER_GIRL":379,"MUS_ENCOUNTER_HIKER":451,"MUS_ENCOUNTER_INTENSE":416,"MUS_ENCOUNTER_INTERVIEWER":453,"MUS_ENCOUNTER_MAGMA":441,"MUS_ENCOUNTER_MALE":380,"MUS_ENCOUNTER_MAY":415,"MUS_ENCOUNTER_RICH":397,"MUS_ENCOUNTER_SUSPICIOUS":423,"MUS_ENCOUNTER_SWIMMER":385,"MUS_ENCOUNTER_TWINS":449,"MUS_END":456,"MUS_EVER_GRANDE":422,"MUS_EVOLUTION":377,"MUS_EVOLUTION_INTRO":376,"MUS_EVOLVED":371,"MUS_FALLARBOR":437,"MUS_FOLLOW_ME":420,"MUS_FORTREE":382,"MUS_GAME_CORNER":426,"MUS_GSC_PEWTER":357,"MUS_GSC_ROUTE38":351,"MUS_GYM":364,"MUS_HALL_OF_FAME":436,"MUS_HALL_OF_FAME_ROOM":447,"MUS_HEAL":368,"MUS_HELP":410,"MUS_INTRO":414,"MUS_INTRO_BATTLE":442,"MUS_LEVEL_UP":367,"MUS_LILYCOVE":408,"MUS_LILYCOVE_MUSEUM":373,"MUS_LINK_CONTEST_P1":393,"MUS_LINK_CONTEST_P2":394,"MUS_LINK_CONTEST_P3":395,"MUS_LINK_CONTEST_P4":396,"MUS_LITTLEROOT":405,"MUS_LITTLEROOT_TEST":350,"MUS_MOVE_DELETED":378,"MUS_MT_CHIMNEY":406,"MUS_MT_PYRE":432,"MUS_MT_PYRE_EXTERIOR":434,"MUS_NONE":65535,"MUS_OBTAIN_BADGE":369,"MUS_OBTAIN_BERRY":387,"MUS_OBTAIN_B_POINTS":459,"MUS_OBTAIN_ITEM":370,"MUS_OBTAIN_SYMBOL":466,"MUS_OBTAIN_TMHM":372,"MUS_OCEANIC_MUSEUM":375,"MUS_OLDALE":363,"MUS_PETALBURG":362,"MUS_PETALBURG_WOODS":366,"MUS_POKE_CENTER":400,"MUS_POKE_MART":404,"MUS_RAYQUAZA_APPEARS":464,"MUS_REGISTER_MATCH_CALL":460,"MUS_RG_BERRY_PICK":542,"MUS_RG_CAUGHT":534,"MUS_RG_CAUGHT_INTRO":531,"MUS_RG_CELADON":521,"MUS_RG_CINNABAR":491,"MUS_RG_CREDITS":502,"MUS_RG_CYCLING":494,"MUS_RG_DEX_RATING":529,"MUS_RG_ENCOUNTER_BOY":497,"MUS_RG_ENCOUNTER_DEOXYS":555,"MUS_RG_ENCOUNTER_GIRL":496,"MUS_RG_ENCOUNTER_GYM_LEADER":554,"MUS_RG_ENCOUNTER_RIVAL":527,"MUS_RG_ENCOUNTER_ROCKET":495,"MUS_RG_FOLLOW_ME":484,"MUS_RG_FUCHSIA":520,"MUS_RG_GAME_CORNER":485,"MUS_RG_GAME_FREAK":533,"MUS_RG_GYM":487,"MUS_RG_HALL_OF_FAME":498,"MUS_RG_HEAL":493,"MUS_RG_INTRO_FIGHT":489,"MUS_RG_JIGGLYPUFF":488,"MUS_RG_LAVENDER":492,"MUS_RG_MT_MOON":500,"MUS_RG_MYSTERY_GIFT":541,"MUS_RG_NET_CENTER":540,"MUS_RG_NEW_GAME_EXIT":537,"MUS_RG_NEW_GAME_INSTRUCT":535,"MUS_RG_NEW_GAME_INTRO":536,"MUS_RG_OAK":514,"MUS_RG_OAK_LAB":513,"MUS_RG_OBTAIN_KEY_ITEM":530,"MUS_RG_PALLET":512,"MUS_RG_PEWTER":526,"MUS_RG_PHOTO":532,"MUS_RG_POKE_CENTER":515,"MUS_RG_POKE_FLUTE":550,"MUS_RG_POKE_JUMP":538,"MUS_RG_POKE_MANSION":501,"MUS_RG_POKE_TOWER":518,"MUS_RG_RIVAL_EXIT":528,"MUS_RG_ROCKET_HIDEOUT":486,"MUS_RG_ROUTE1":503,"MUS_RG_ROUTE11":506,"MUS_RG_ROUTE24":504,"MUS_RG_ROUTE3":505,"MUS_RG_SEVII_123":547,"MUS_RG_SEVII_45":548,"MUS_RG_SEVII_67":549,"MUS_RG_SEVII_CAVE":543,"MUS_RG_SEVII_DUNGEON":546,"MUS_RG_SEVII_ROUTE":545,"MUS_RG_SILPH":519,"MUS_RG_SLOW_PALLET":557,"MUS_RG_SS_ANNE":516,"MUS_RG_SURF":517,"MUS_RG_TEACHY_TV_MENU":558,"MUS_RG_TEACHY_TV_SHOW":544,"MUS_RG_TITLE":490,"MUS_RG_TRAINER_TOWER":556,"MUS_RG_UNION_ROOM":539,"MUS_RG_VERMILLION":525,"MUS_RG_VICTORY_GYM_LEADER":524,"MUS_RG_VICTORY_ROAD":507,"MUS_RG_VICTORY_TRAINER":522,"MUS_RG_VICTORY_WILD":523,"MUS_RG_VIRIDIAN_FOREST":499,"MUS_RG_VS_CHAMPION":511,"MUS_RG_VS_DEOXYS":551,"MUS_RG_VS_GYM_LEADER":508,"MUS_RG_VS_LEGEND":553,"MUS_RG_VS_MEWTWO":552,"MUS_RG_VS_TRAINER":509,"MUS_RG_VS_WILD":510,"MUS_ROULETTE":392,"MUS_ROUTE101":359,"MUS_ROUTE104":401,"MUS_ROUTE110":360,"MUS_ROUTE113":418,"MUS_ROUTE118":32767,"MUS_ROUTE119":402,"MUS_ROUTE120":361,"MUS_ROUTE122":374,"MUS_RUSTBORO":399,"MUS_SAFARI_ZONE":428,"MUS_SAILING":431,"MUS_SCHOOL":435,"MUS_SEALED_CHAMBER":438,"MUS_SLATEPORT":433,"MUS_SLOTS_JACKPOT":389,"MUS_SLOTS_WIN":390,"MUS_SOOTOPOLIS":445,"MUS_SURF":365,"MUS_TITLE":413,"MUS_TOO_BAD":391,"MUS_TRICK_HOUSE":448,"MUS_UNDERWATER":411,"MUS_VERDANTURF":398,"MUS_VICTORY_AQUA_MAGMA":424,"MUS_VICTORY_GYM_LEADER":354,"MUS_VICTORY_LEAGUE":355,"MUS_VICTORY_ROAD":429,"MUS_VICTORY_TRAINER":412,"MUS_VICTORY_WILD":353,"MUS_VS_AQUA_MAGMA":475,"MUS_VS_AQUA_MAGMA_LEADER":483,"MUS_VS_CHAMPION":478,"MUS_VS_ELITE_FOUR":482,"MUS_VS_FRONTIER_BRAIN":471,"MUS_VS_GYM_LEADER":477,"MUS_VS_KYOGRE_GROUDON":480,"MUS_VS_MEW":472,"MUS_VS_RAYQUAZA":470,"MUS_VS_REGI":479,"MUS_VS_RIVAL":481,"MUS_VS_TRAINER":476,"MUS_VS_WILD":474,"MUS_WEATHER_GROUDON":444,"NUM_BADGES":8,"NUM_BERRY_MASTER_BERRIES":10,"NUM_BERRY_MASTER_BERRIES_SKIPPED":20,"NUM_BERRY_MASTER_WIFE_BERRIES":10,"NUM_DAILY_FLAGS":64,"NUM_HIDDEN_MACHINES":8,"NUM_KIRI_BERRIES":10,"NUM_KIRI_BERRIES_SKIPPED":20,"NUM_ROUTE_114_MAN_BERRIES":5,"NUM_ROUTE_114_MAN_BERRIES_SKIPPED":15,"NUM_SPECIAL_FLAGS":128,"NUM_SPECIES":412,"NUM_TECHNICAL_MACHINES":50,"NUM_TEMP_FLAGS":32,"NUM_WATER_STAGES":4,"NUM_WONDER_CARD_FLAGS":20,"OLD_ROD":0,"PH_CHOICE_BLEND":589,"PH_CHOICE_HELD":590,"PH_CHOICE_SOLO":591,"PH_CLOTH_BLEND":565,"PH_CLOTH_HELD":566,"PH_CLOTH_SOLO":567,"PH_CURE_BLEND":604,"PH_CURE_HELD":605,"PH_CURE_SOLO":606,"PH_DRESS_BLEND":568,"PH_DRESS_HELD":569,"PH_DRESS_SOLO":570,"PH_FACE_BLEND":562,"PH_FACE_HELD":563,"PH_FACE_SOLO":564,"PH_FLEECE_BLEND":571,"PH_FLEECE_HELD":572,"PH_FLEECE_SOLO":573,"PH_FOOT_BLEND":595,"PH_FOOT_HELD":596,"PH_FOOT_SOLO":597,"PH_GOAT_BLEND":583,"PH_GOAT_HELD":584,"PH_GOAT_SOLO":585,"PH_GOOSE_BLEND":598,"PH_GOOSE_HELD":599,"PH_GOOSE_SOLO":600,"PH_KIT_BLEND":574,"PH_KIT_HELD":575,"PH_KIT_SOLO":576,"PH_LOT_BLEND":580,"PH_LOT_HELD":581,"PH_LOT_SOLO":582,"PH_MOUTH_BLEND":592,"PH_MOUTH_HELD":593,"PH_MOUTH_SOLO":594,"PH_NURSE_BLEND":607,"PH_NURSE_HELD":608,"PH_NURSE_SOLO":609,"PH_PRICE_BLEND":577,"PH_PRICE_HELD":578,"PH_PRICE_SOLO":579,"PH_STRUT_BLEND":601,"PH_STRUT_HELD":602,"PH_STRUT_SOLO":603,"PH_THOUGHT_BLEND":586,"PH_THOUGHT_HELD":587,"PH_THOUGHT_SOLO":588,"PH_TRAP_BLEND":559,"PH_TRAP_HELD":560,"PH_TRAP_SOLO":561,"SE_A":25,"SE_APPLAUSE":105,"SE_ARENA_TIMEUP1":265,"SE_ARENA_TIMEUP2":266,"SE_BALL":23,"SE_BALLOON_BLUE":75,"SE_BALLOON_RED":74,"SE_BALLOON_YELLOW":76,"SE_BALL_BOUNCE_1":56,"SE_BALL_BOUNCE_2":57,"SE_BALL_BOUNCE_3":58,"SE_BALL_BOUNCE_4":59,"SE_BALL_OPEN":15,"SE_BALL_THROW":61,"SE_BALL_TRADE":60,"SE_BALL_TRAY_BALL":115,"SE_BALL_TRAY_ENTER":114,"SE_BALL_TRAY_EXIT":116,"SE_BANG":20,"SE_BERRY_BLENDER":53,"SE_BIKE_BELL":11,"SE_BIKE_HOP":34,"SE_BOO":22,"SE_BREAKABLE_DOOR":77,"SE_BRIDGE_WALK":71,"SE_CARD":54,"SE_CLICK":36,"SE_CONTEST_CONDITION_LOSE":38,"SE_CONTEST_CURTAIN_FALL":98,"SE_CONTEST_CURTAIN_RISE":97,"SE_CONTEST_HEART":96,"SE_CONTEST_ICON_CHANGE":99,"SE_CONTEST_ICON_CLEAR":100,"SE_CONTEST_MONS_TURN":101,"SE_CONTEST_PLACE":24,"SE_DEX_PAGE":109,"SE_DEX_SCROLL":108,"SE_DEX_SEARCH":112,"SE_DING_DONG":73,"SE_DOOR":8,"SE_DOWNPOUR":83,"SE_DOWNPOUR_STOP":84,"SE_E":28,"SE_EFFECTIVE":13,"SE_EGG_HATCH":113,"SE_ELEVATOR":89,"SE_ESCALATOR":80,"SE_EXIT":9,"SE_EXP":33,"SE_EXP_MAX":91,"SE_FAILURE":32,"SE_FAINT":16,"SE_FALL":43,"SE_FIELD_POISON":79,"SE_FLEE":17,"SE_FU_ZAKU":37,"SE_GLASS_FLUTE":117,"SE_I":26,"SE_ICE_BREAK":41,"SE_ICE_CRACK":42,"SE_ICE_STAIRS":40,"SE_INTRO_BLAST":103,"SE_ITEMFINDER":72,"SE_LAVARIDGE_FALL_WARP":39,"SE_LEDGE":10,"SE_LOW_HEALTH":90,"SE_MUD_BALL":78,"SE_MUGSHOT":104,"SE_M_ABSORB":180,"SE_M_ABSORB_2":179,"SE_M_ACID_ARMOR":218,"SE_M_ATTRACT":226,"SE_M_ATTRACT2":227,"SE_M_BARRIER":208,"SE_M_BATON_PASS":224,"SE_M_BELLY_DRUM":185,"SE_M_BIND":170,"SE_M_BITE":161,"SE_M_BLIZZARD":153,"SE_M_BLIZZARD2":154,"SE_M_BONEMERANG":187,"SE_M_BRICK_BREAK":198,"SE_M_BUBBLE":124,"SE_M_BUBBLE2":125,"SE_M_BUBBLE3":126,"SE_M_BUBBLE_BEAM":182,"SE_M_BUBBLE_BEAM2":183,"SE_M_CHARGE":213,"SE_M_CHARM":212,"SE_M_COMET_PUNCH":139,"SE_M_CONFUSE_RAY":196,"SE_M_COSMIC_POWER":243,"SE_M_CRABHAMMER":142,"SE_M_CUT":128,"SE_M_DETECT":209,"SE_M_DIG":175,"SE_M_DIVE":233,"SE_M_DIZZY_PUNCH":176,"SE_M_DOUBLE_SLAP":134,"SE_M_DOUBLE_TEAM":135,"SE_M_DRAGON_RAGE":171,"SE_M_EARTHQUAKE":234,"SE_M_EMBER":151,"SE_M_ENCORE":222,"SE_M_ENCORE2":223,"SE_M_EXPLOSION":178,"SE_M_FAINT_ATTACK":190,"SE_M_FIRE_PUNCH":147,"SE_M_FLAMETHROWER":146,"SE_M_FLAME_WHEEL":144,"SE_M_FLAME_WHEEL2":145,"SE_M_FLATTER":229,"SE_M_FLY":158,"SE_M_GIGA_DRAIN":199,"SE_M_GRASSWHISTLE":231,"SE_M_GUST":132,"SE_M_GUST2":133,"SE_M_HAIL":242,"SE_M_HARDEN":120,"SE_M_HAZE":246,"SE_M_HEADBUTT":162,"SE_M_HEAL_BELL":195,"SE_M_HEAT_WAVE":240,"SE_M_HORN_ATTACK":166,"SE_M_HYDRO_PUMP":164,"SE_M_HYPER_BEAM":215,"SE_M_HYPER_BEAM2":247,"SE_M_ICY_WIND":137,"SE_M_JUMP_KICK":143,"SE_M_LEER":192,"SE_M_LICK":188,"SE_M_LOCK_ON":210,"SE_M_MEGA_KICK":140,"SE_M_MEGA_KICK2":141,"SE_M_METRONOME":186,"SE_M_MILK_DRINK":225,"SE_M_MINIMIZE":204,"SE_M_MIST":168,"SE_M_MOONLIGHT":211,"SE_M_MORNING_SUN":228,"SE_M_NIGHTMARE":121,"SE_M_PAY_DAY":174,"SE_M_PERISH_SONG":173,"SE_M_PETAL_DANCE":202,"SE_M_POISON_POWDER":169,"SE_M_PSYBEAM":189,"SE_M_PSYBEAM2":200,"SE_M_RAIN_DANCE":127,"SE_M_RAZOR_WIND":136,"SE_M_RAZOR_WIND2":160,"SE_M_REFLECT":207,"SE_M_REVERSAL":217,"SE_M_ROCK_THROW":131,"SE_M_SACRED_FIRE":149,"SE_M_SACRED_FIRE2":150,"SE_M_SANDSTORM":219,"SE_M_SAND_ATTACK":159,"SE_M_SAND_TOMB":230,"SE_M_SCRATCH":155,"SE_M_SCREECH":181,"SE_M_SELF_DESTRUCT":177,"SE_M_SING":172,"SE_M_SKETCH":205,"SE_M_SKY_UPPERCUT":238,"SE_M_SNORE":197,"SE_M_SOLAR_BEAM":201,"SE_M_SPIT_UP":232,"SE_M_STAT_DECREASE":245,"SE_M_STAT_INCREASE":239,"SE_M_STRENGTH":214,"SE_M_STRING_SHOT":129,"SE_M_STRING_SHOT2":130,"SE_M_SUPERSONIC":184,"SE_M_SURF":163,"SE_M_SWAGGER":193,"SE_M_SWAGGER2":194,"SE_M_SWEET_SCENT":236,"SE_M_SWIFT":206,"SE_M_SWORDS_DANCE":191,"SE_M_TAIL_WHIP":167,"SE_M_TAKE_DOWN":152,"SE_M_TEETER_DANCE":244,"SE_M_TELEPORT":203,"SE_M_THUNDERBOLT":118,"SE_M_THUNDERBOLT2":119,"SE_M_THUNDER_WAVE":138,"SE_M_TOXIC":148,"SE_M_TRI_ATTACK":220,"SE_M_TRI_ATTACK2":221,"SE_M_TWISTER":235,"SE_M_UPROAR":241,"SE_M_VICEGRIP":156,"SE_M_VITAL_THROW":122,"SE_M_VITAL_THROW2":123,"SE_M_WATERFALL":216,"SE_M_WHIRLPOOL":165,"SE_M_WING_ATTACK":157,"SE_M_YAWN":237,"SE_N":30,"SE_NOTE_A":67,"SE_NOTE_B":68,"SE_NOTE_C":62,"SE_NOTE_C_HIGH":69,"SE_NOTE_D":63,"SE_NOTE_E":64,"SE_NOTE_F":65,"SE_NOTE_G":66,"SE_NOT_EFFECTIVE":12,"SE_O":29,"SE_ORB":107,"SE_PC_LOGIN":2,"SE_PC_OFF":3,"SE_PC_ON":4,"SE_PIKE_CURTAIN_CLOSE":267,"SE_PIKE_CURTAIN_OPEN":268,"SE_PIN":21,"SE_POKENAV_CALL":263,"SE_POKENAV_HANG_UP":264,"SE_POKENAV_OFF":111,"SE_POKENAV_ON":110,"SE_PUDDLE":70,"SE_RAIN":85,"SE_RAIN_STOP":86,"SE_REPEL":47,"SE_RG_BAG_CURSOR":252,"SE_RG_BAG_POCKET":253,"SE_RG_BALL_CLICK":254,"SE_RG_CARD_FLIP":249,"SE_RG_CARD_FLIPPING":250,"SE_RG_CARD_OPEN":251,"SE_RG_DEOXYS_MOVE":260,"SE_RG_DOOR":248,"SE_RG_HELP_CLOSE":258,"SE_RG_HELP_ERROR":259,"SE_RG_HELP_OPEN":257,"SE_RG_POKE_JUMP_FAILURE":262,"SE_RG_POKE_JUMP_SUCCESS":261,"SE_RG_SHOP":255,"SE_RG_SS_ANNE_HORN":256,"SE_ROTATING_GATE":48,"SE_ROULETTE_BALL":92,"SE_ROULETTE_BALL2":93,"SE_SAVE":55,"SE_SELECT":5,"SE_SHINY":102,"SE_SHIP":19,"SE_SHOP":95,"SE_SLIDING_DOOR":18,"SE_SUCCESS":31,"SE_SUDOWOODO_SHAKE":269,"SE_SUPER_EFFECTIVE":14,"SE_SWITCH":35,"SE_TAILLOW_WING_FLAP":94,"SE_THUNDER":87,"SE_THUNDER2":88,"SE_THUNDERSTORM":81,"SE_THUNDERSTORM_STOP":82,"SE_TRUCK_DOOR":52,"SE_TRUCK_MOVE":49,"SE_TRUCK_STOP":50,"SE_TRUCK_UNLOAD":51,"SE_U":27,"SE_UNLOCK":44,"SE_USE_ITEM":1,"SE_VEND":106,"SE_WALL_HIT":7,"SE_WARP_IN":45,"SE_WARP_OUT":46,"SE_WIN_OPEN":6,"SPECIAL_FLAGS_END":16511,"SPECIAL_FLAGS_START":16384,"SPECIES_ABRA":63,"SPECIES_ABSOL":376,"SPECIES_AERODACTYL":142,"SPECIES_AGGRON":384,"SPECIES_AIPOM":190,"SPECIES_ALAKAZAM":65,"SPECIES_ALTARIA":359,"SPECIES_AMPHAROS":181,"SPECIES_ANORITH":390,"SPECIES_ARBOK":24,"SPECIES_ARCANINE":59,"SPECIES_ARIADOS":168,"SPECIES_ARMALDO":391,"SPECIES_ARON":382,"SPECIES_ARTICUNO":144,"SPECIES_AZUMARILL":184,"SPECIES_AZURILL":350,"SPECIES_BAGON":395,"SPECIES_BALTOY":318,"SPECIES_BANETTE":378,"SPECIES_BARBOACH":323,"SPECIES_BAYLEEF":153,"SPECIES_BEAUTIFLY":292,"SPECIES_BEEDRILL":15,"SPECIES_BELDUM":398,"SPECIES_BELLOSSOM":182,"SPECIES_BELLSPROUT":69,"SPECIES_BLASTOISE":9,"SPECIES_BLAZIKEN":282,"SPECIES_BLISSEY":242,"SPECIES_BRELOOM":307,"SPECIES_BULBASAUR":1,"SPECIES_BUTTERFREE":12,"SPECIES_CACNEA":344,"SPECIES_CACTURNE":345,"SPECIES_CAMERUPT":340,"SPECIES_CARVANHA":330,"SPECIES_CASCOON":293,"SPECIES_CASTFORM":385,"SPECIES_CATERPIE":10,"SPECIES_CELEBI":251,"SPECIES_CHANSEY":113,"SPECIES_CHARIZARD":6,"SPECIES_CHARMANDER":4,"SPECIES_CHARMELEON":5,"SPECIES_CHIKORITA":152,"SPECIES_CHIMECHO":411,"SPECIES_CHINCHOU":170,"SPECIES_CLAMPERL":373,"SPECIES_CLAYDOL":319,"SPECIES_CLEFABLE":36,"SPECIES_CLEFAIRY":35,"SPECIES_CLEFFA":173,"SPECIES_CLOYSTER":91,"SPECIES_COMBUSKEN":281,"SPECIES_CORPHISH":326,"SPECIES_CORSOLA":222,"SPECIES_CRADILY":389,"SPECIES_CRAWDAUNT":327,"SPECIES_CROBAT":169,"SPECIES_CROCONAW":159,"SPECIES_CUBONE":104,"SPECIES_CYNDAQUIL":155,"SPECIES_DELCATTY":316,"SPECIES_DELIBIRD":225,"SPECIES_DEOXYS":410,"SPECIES_DEWGONG":87,"SPECIES_DIGLETT":50,"SPECIES_DITTO":132,"SPECIES_DODRIO":85,"SPECIES_DODUO":84,"SPECIES_DONPHAN":232,"SPECIES_DRAGONAIR":148,"SPECIES_DRAGONITE":149,"SPECIES_DRATINI":147,"SPECIES_DROWZEE":96,"SPECIES_DUGTRIO":51,"SPECIES_DUNSPARCE":206,"SPECIES_DUSCLOPS":362,"SPECIES_DUSKULL":361,"SPECIES_DUSTOX":294,"SPECIES_EEVEE":133,"SPECIES_EGG":412,"SPECIES_EKANS":23,"SPECIES_ELECTABUZZ":125,"SPECIES_ELECTRIKE":337,"SPECIES_ELECTRODE":101,"SPECIES_ELEKID":239,"SPECIES_ENTEI":244,"SPECIES_ESPEON":196,"SPECIES_EXEGGCUTE":102,"SPECIES_EXEGGUTOR":103,"SPECIES_EXPLOUD":372,"SPECIES_FARFETCHD":83,"SPECIES_FEAROW":22,"SPECIES_FEEBAS":328,"SPECIES_FERALIGATR":160,"SPECIES_FLAAFFY":180,"SPECIES_FLAREON":136,"SPECIES_FLYGON":334,"SPECIES_FORRETRESS":205,"SPECIES_FURRET":162,"SPECIES_GARDEVOIR":394,"SPECIES_GASTLY":92,"SPECIES_GENGAR":94,"SPECIES_GEODUDE":74,"SPECIES_GIRAFARIG":203,"SPECIES_GLALIE":347,"SPECIES_GLIGAR":207,"SPECIES_GLOOM":44,"SPECIES_GOLBAT":42,"SPECIES_GOLDEEN":118,"SPECIES_GOLDUCK":55,"SPECIES_GOLEM":76,"SPECIES_GOREBYSS":375,"SPECIES_GRANBULL":210,"SPECIES_GRAVELER":75,"SPECIES_GRIMER":88,"SPECIES_GROUDON":405,"SPECIES_GROVYLE":278,"SPECIES_GROWLITHE":58,"SPECIES_GRUMPIG":352,"SPECIES_GULPIN":367,"SPECIES_GYARADOS":130,"SPECIES_HARIYAMA":336,"SPECIES_HAUNTER":93,"SPECIES_HERACROSS":214,"SPECIES_HITMONCHAN":107,"SPECIES_HITMONLEE":106,"SPECIES_HITMONTOP":237,"SPECIES_HOOTHOOT":163,"SPECIES_HOPPIP":187,"SPECIES_HORSEA":116,"SPECIES_HOUNDOOM":229,"SPECIES_HOUNDOUR":228,"SPECIES_HO_OH":250,"SPECIES_HUNTAIL":374,"SPECIES_HYPNO":97,"SPECIES_IGGLYBUFF":174,"SPECIES_ILLUMISE":387,"SPECIES_IVYSAUR":2,"SPECIES_JIGGLYPUFF":39,"SPECIES_JIRACHI":409,"SPECIES_JOLTEON":135,"SPECIES_JUMPLUFF":189,"SPECIES_JYNX":124,"SPECIES_KABUTO":140,"SPECIES_KABUTOPS":141,"SPECIES_KADABRA":64,"SPECIES_KAKUNA":14,"SPECIES_KANGASKHAN":115,"SPECIES_KECLEON":317,"SPECIES_KINGDRA":230,"SPECIES_KINGLER":99,"SPECIES_KIRLIA":393,"SPECIES_KOFFING":109,"SPECIES_KRABBY":98,"SPECIES_KYOGRE":404,"SPECIES_LAIRON":383,"SPECIES_LANTURN":171,"SPECIES_LAPRAS":131,"SPECIES_LARVITAR":246,"SPECIES_LATIAS":407,"SPECIES_LATIOS":408,"SPECIES_LEDIAN":166,"SPECIES_LEDYBA":165,"SPECIES_LICKITUNG":108,"SPECIES_LILEEP":388,"SPECIES_LINOONE":289,"SPECIES_LOMBRE":296,"SPECIES_LOTAD":295,"SPECIES_LOUDRED":371,"SPECIES_LUDICOLO":297,"SPECIES_LUGIA":249,"SPECIES_LUNATONE":348,"SPECIES_LUVDISC":325,"SPECIES_MACHAMP":68,"SPECIES_MACHOKE":67,"SPECIES_MACHOP":66,"SPECIES_MAGBY":240,"SPECIES_MAGCARGO":219,"SPECIES_MAGIKARP":129,"SPECIES_MAGMAR":126,"SPECIES_MAGNEMITE":81,"SPECIES_MAGNETON":82,"SPECIES_MAKUHITA":335,"SPECIES_MANECTRIC":338,"SPECIES_MANKEY":56,"SPECIES_MANTINE":226,"SPECIES_MAREEP":179,"SPECIES_MARILL":183,"SPECIES_MAROWAK":105,"SPECIES_MARSHTOMP":284,"SPECIES_MASQUERAIN":312,"SPECIES_MAWILE":355,"SPECIES_MEDICHAM":357,"SPECIES_MEDITITE":356,"SPECIES_MEGANIUM":154,"SPECIES_MEOWTH":52,"SPECIES_METAGROSS":400,"SPECIES_METANG":399,"SPECIES_METAPOD":11,"SPECIES_MEW":151,"SPECIES_MEWTWO":150,"SPECIES_MIGHTYENA":287,"SPECIES_MILOTIC":329,"SPECIES_MILTANK":241,"SPECIES_MINUN":354,"SPECIES_MISDREAVUS":200,"SPECIES_MOLTRES":146,"SPECIES_MR_MIME":122,"SPECIES_MUDKIP":283,"SPECIES_MUK":89,"SPECIES_MURKROW":198,"SPECIES_NATU":177,"SPECIES_NIDOKING":34,"SPECIES_NIDOQUEEN":31,"SPECIES_NIDORAN_F":29,"SPECIES_NIDORAN_M":32,"SPECIES_NIDORINA":30,"SPECIES_NIDORINO":33,"SPECIES_NINCADA":301,"SPECIES_NINETALES":38,"SPECIES_NINJASK":302,"SPECIES_NOCTOWL":164,"SPECIES_NONE":0,"SPECIES_NOSEPASS":320,"SPECIES_NUMEL":339,"SPECIES_NUZLEAF":299,"SPECIES_OCTILLERY":224,"SPECIES_ODDISH":43,"SPECIES_OLD_UNOWN_B":252,"SPECIES_OLD_UNOWN_C":253,"SPECIES_OLD_UNOWN_D":254,"SPECIES_OLD_UNOWN_E":255,"SPECIES_OLD_UNOWN_F":256,"SPECIES_OLD_UNOWN_G":257,"SPECIES_OLD_UNOWN_H":258,"SPECIES_OLD_UNOWN_I":259,"SPECIES_OLD_UNOWN_J":260,"SPECIES_OLD_UNOWN_K":261,"SPECIES_OLD_UNOWN_L":262,"SPECIES_OLD_UNOWN_M":263,"SPECIES_OLD_UNOWN_N":264,"SPECIES_OLD_UNOWN_O":265,"SPECIES_OLD_UNOWN_P":266,"SPECIES_OLD_UNOWN_Q":267,"SPECIES_OLD_UNOWN_R":268,"SPECIES_OLD_UNOWN_S":269,"SPECIES_OLD_UNOWN_T":270,"SPECIES_OLD_UNOWN_U":271,"SPECIES_OLD_UNOWN_V":272,"SPECIES_OLD_UNOWN_W":273,"SPECIES_OLD_UNOWN_X":274,"SPECIES_OLD_UNOWN_Y":275,"SPECIES_OLD_UNOWN_Z":276,"SPECIES_OMANYTE":138,"SPECIES_OMASTAR":139,"SPECIES_ONIX":95,"SPECIES_PARAS":46,"SPECIES_PARASECT":47,"SPECIES_PELIPPER":310,"SPECIES_PERSIAN":53,"SPECIES_PHANPY":231,"SPECIES_PICHU":172,"SPECIES_PIDGEOT":18,"SPECIES_PIDGEOTTO":17,"SPECIES_PIDGEY":16,"SPECIES_PIKACHU":25,"SPECIES_PILOSWINE":221,"SPECIES_PINECO":204,"SPECIES_PINSIR":127,"SPECIES_PLUSLE":353,"SPECIES_POLITOED":186,"SPECIES_POLIWAG":60,"SPECIES_POLIWHIRL":61,"SPECIES_POLIWRATH":62,"SPECIES_PONYTA":77,"SPECIES_POOCHYENA":286,"SPECIES_PORYGON":137,"SPECIES_PORYGON2":233,"SPECIES_PRIMEAPE":57,"SPECIES_PSYDUCK":54,"SPECIES_PUPITAR":247,"SPECIES_QUAGSIRE":195,"SPECIES_QUILAVA":156,"SPECIES_QWILFISH":211,"SPECIES_RAICHU":26,"SPECIES_RAIKOU":243,"SPECIES_RALTS":392,"SPECIES_RAPIDASH":78,"SPECIES_RATICATE":20,"SPECIES_RATTATA":19,"SPECIES_RAYQUAZA":406,"SPECIES_REGICE":402,"SPECIES_REGIROCK":401,"SPECIES_REGISTEEL":403,"SPECIES_RELICANTH":381,"SPECIES_REMORAID":223,"SPECIES_RHYDON":112,"SPECIES_RHYHORN":111,"SPECIES_ROSELIA":363,"SPECIES_SABLEYE":322,"SPECIES_SALAMENCE":397,"SPECIES_SANDSHREW":27,"SPECIES_SANDSLASH":28,"SPECIES_SCEPTILE":279,"SPECIES_SCIZOR":212,"SPECIES_SCYTHER":123,"SPECIES_SEADRA":117,"SPECIES_SEAKING":119,"SPECIES_SEALEO":342,"SPECIES_SEEDOT":298,"SPECIES_SEEL":86,"SPECIES_SENTRET":161,"SPECIES_SEVIPER":379,"SPECIES_SHARPEDO":331,"SPECIES_SHEDINJA":303,"SPECIES_SHELGON":396,"SPECIES_SHELLDER":90,"SPECIES_SHIFTRY":300,"SPECIES_SHROOMISH":306,"SPECIES_SHUCKLE":213,"SPECIES_SHUPPET":377,"SPECIES_SILCOON":291,"SPECIES_SKARMORY":227,"SPECIES_SKIPLOOM":188,"SPECIES_SKITTY":315,"SPECIES_SLAKING":366,"SPECIES_SLAKOTH":364,"SPECIES_SLOWBRO":80,"SPECIES_SLOWKING":199,"SPECIES_SLOWPOKE":79,"SPECIES_SLUGMA":218,"SPECIES_SMEARGLE":235,"SPECIES_SMOOCHUM":238,"SPECIES_SNEASEL":215,"SPECIES_SNORLAX":143,"SPECIES_SNORUNT":346,"SPECIES_SNUBBULL":209,"SPECIES_SOLROCK":349,"SPECIES_SPEAROW":21,"SPECIES_SPHEAL":341,"SPECIES_SPINARAK":167,"SPECIES_SPINDA":308,"SPECIES_SPOINK":351,"SPECIES_SQUIRTLE":7,"SPECIES_STANTLER":234,"SPECIES_STARMIE":121,"SPECIES_STARYU":120,"SPECIES_STEELIX":208,"SPECIES_SUDOWOODO":185,"SPECIES_SUICUNE":245,"SPECIES_SUNFLORA":192,"SPECIES_SUNKERN":191,"SPECIES_SURSKIT":311,"SPECIES_SWABLU":358,"SPECIES_SWALOT":368,"SPECIES_SWAMPERT":285,"SPECIES_SWELLOW":305,"SPECIES_SWINUB":220,"SPECIES_TAILLOW":304,"SPECIES_TANGELA":114,"SPECIES_TAUROS":128,"SPECIES_TEDDIURSA":216,"SPECIES_TENTACOOL":72,"SPECIES_TENTACRUEL":73,"SPECIES_TOGEPI":175,"SPECIES_TOGETIC":176,"SPECIES_TORCHIC":280,"SPECIES_TORKOAL":321,"SPECIES_TOTODILE":158,"SPECIES_TRAPINCH":332,"SPECIES_TREECKO":277,"SPECIES_TROPIUS":369,"SPECIES_TYPHLOSION":157,"SPECIES_TYRANITAR":248,"SPECIES_TYROGUE":236,"SPECIES_UMBREON":197,"SPECIES_UNOWN":201,"SPECIES_UNOWN_B":413,"SPECIES_UNOWN_C":414,"SPECIES_UNOWN_D":415,"SPECIES_UNOWN_E":416,"SPECIES_UNOWN_EMARK":438,"SPECIES_UNOWN_F":417,"SPECIES_UNOWN_G":418,"SPECIES_UNOWN_H":419,"SPECIES_UNOWN_I":420,"SPECIES_UNOWN_J":421,"SPECIES_UNOWN_K":422,"SPECIES_UNOWN_L":423,"SPECIES_UNOWN_M":424,"SPECIES_UNOWN_N":425,"SPECIES_UNOWN_O":426,"SPECIES_UNOWN_P":427,"SPECIES_UNOWN_Q":428,"SPECIES_UNOWN_QMARK":439,"SPECIES_UNOWN_R":429,"SPECIES_UNOWN_S":430,"SPECIES_UNOWN_T":431,"SPECIES_UNOWN_U":432,"SPECIES_UNOWN_V":433,"SPECIES_UNOWN_W":434,"SPECIES_UNOWN_X":435,"SPECIES_UNOWN_Y":436,"SPECIES_UNOWN_Z":437,"SPECIES_URSARING":217,"SPECIES_VAPOREON":134,"SPECIES_VENOMOTH":49,"SPECIES_VENONAT":48,"SPECIES_VENUSAUR":3,"SPECIES_VIBRAVA":333,"SPECIES_VICTREEBEL":71,"SPECIES_VIGOROTH":365,"SPECIES_VILEPLUME":45,"SPECIES_VOLBEAT":386,"SPECIES_VOLTORB":100,"SPECIES_VULPIX":37,"SPECIES_WAILMER":313,"SPECIES_WAILORD":314,"SPECIES_WALREIN":343,"SPECIES_WARTORTLE":8,"SPECIES_WEEDLE":13,"SPECIES_WEEPINBELL":70,"SPECIES_WEEZING":110,"SPECIES_WHISCASH":324,"SPECIES_WHISMUR":370,"SPECIES_WIGGLYTUFF":40,"SPECIES_WINGULL":309,"SPECIES_WOBBUFFET":202,"SPECIES_WOOPER":194,"SPECIES_WURMPLE":290,"SPECIES_WYNAUT":360,"SPECIES_XATU":178,"SPECIES_YANMA":193,"SPECIES_ZANGOOSE":380,"SPECIES_ZAPDOS":145,"SPECIES_ZIGZAGOON":288,"SPECIES_ZUBAT":41,"SUPER_ROD":2,"SYSTEM_FLAGS":2144,"TEMP_FLAGS_END":31,"TEMP_FLAGS_START":0,"TRAINERS_COUNT":855,"TRAINER_AARON":397,"TRAINER_ABIGAIL_1":358,"TRAINER_ABIGAIL_2":360,"TRAINER_ABIGAIL_3":361,"TRAINER_ABIGAIL_4":362,"TRAINER_ABIGAIL_5":363,"TRAINER_AIDAN":674,"TRAINER_AISHA":757,"TRAINER_ALAN":630,"TRAINER_ALBERT":80,"TRAINER_ALBERTO":12,"TRAINER_ALEX":413,"TRAINER_ALEXA":670,"TRAINER_ALEXIA":90,"TRAINER_ALEXIS":248,"TRAINER_ALICE":448,"TRAINER_ALIX":750,"TRAINER_ALLEN":333,"TRAINER_ALLISON":387,"TRAINER_ALVARO":849,"TRAINER_ALYSSA":701,"TRAINER_AMY_AND_LIV_1":481,"TRAINER_AMY_AND_LIV_2":482,"TRAINER_AMY_AND_LIV_3":485,"TRAINER_AMY_AND_LIV_4":487,"TRAINER_AMY_AND_LIV_5":488,"TRAINER_AMY_AND_LIV_6":489,"TRAINER_ANABEL":805,"TRAINER_ANDREA":613,"TRAINER_ANDRES_1":737,"TRAINER_ANDRES_2":812,"TRAINER_ANDRES_3":813,"TRAINER_ANDRES_4":814,"TRAINER_ANDRES_5":815,"TRAINER_ANDREW":336,"TRAINER_ANGELICA":436,"TRAINER_ANGELINA":712,"TRAINER_ANGELO":802,"TRAINER_ANNA_AND_MEG_1":287,"TRAINER_ANNA_AND_MEG_2":288,"TRAINER_ANNA_AND_MEG_3":289,"TRAINER_ANNA_AND_MEG_4":290,"TRAINER_ANNA_AND_MEG_5":291,"TRAINER_ANNIKA":502,"TRAINER_ANTHONY":352,"TRAINER_ARCHIE":34,"TRAINER_ASHLEY":655,"TRAINER_ATHENA":577,"TRAINER_ATSUSHI":190,"TRAINER_AURON":506,"TRAINER_AUSTINA":58,"TRAINER_AUTUMN":217,"TRAINER_AXLE":203,"TRAINER_BARNY":343,"TRAINER_BARRY":163,"TRAINER_BEAU":212,"TRAINER_BECK":414,"TRAINER_BECKY":470,"TRAINER_BEN":323,"TRAINER_BENJAMIN_1":353,"TRAINER_BENJAMIN_2":354,"TRAINER_BENJAMIN_3":355,"TRAINER_BENJAMIN_4":356,"TRAINER_BENJAMIN_5":357,"TRAINER_BENNY":407,"TRAINER_BERKE":74,"TRAINER_BERNIE_1":206,"TRAINER_BERNIE_2":207,"TRAINER_BERNIE_3":208,"TRAINER_BERNIE_4":209,"TRAINER_BERNIE_5":210,"TRAINER_BETH":445,"TRAINER_BETHANY":301,"TRAINER_BEVERLY":441,"TRAINER_BIANCA":706,"TRAINER_BILLY":319,"TRAINER_BLAKE":235,"TRAINER_BRANDEN":745,"TRAINER_BRANDI":756,"TRAINER_BRANDON":811,"TRAINER_BRAWLY_1":266,"TRAINER_BRAWLY_2":774,"TRAINER_BRAWLY_3":775,"TRAINER_BRAWLY_4":776,"TRAINER_BRAWLY_5":777,"TRAINER_BRAXTON":75,"TRAINER_BRENDA":454,"TRAINER_BRENDAN_LILYCOVE_MUDKIP":661,"TRAINER_BRENDAN_LILYCOVE_TORCHIC":663,"TRAINER_BRENDAN_LILYCOVE_TREECKO":662,"TRAINER_BRENDAN_PLACEHOLDER":853,"TRAINER_BRENDAN_ROUTE_103_MUDKIP":520,"TRAINER_BRENDAN_ROUTE_103_TORCHIC":526,"TRAINER_BRENDAN_ROUTE_103_TREECKO":523,"TRAINER_BRENDAN_ROUTE_110_MUDKIP":521,"TRAINER_BRENDAN_ROUTE_110_TORCHIC":527,"TRAINER_BRENDAN_ROUTE_110_TREECKO":524,"TRAINER_BRENDAN_ROUTE_119_MUDKIP":522,"TRAINER_BRENDAN_ROUTE_119_TORCHIC":528,"TRAINER_BRENDAN_ROUTE_119_TREECKO":525,"TRAINER_BRENDAN_RUSTBORO_MUDKIP":593,"TRAINER_BRENDAN_RUSTBORO_TORCHIC":599,"TRAINER_BRENDAN_RUSTBORO_TREECKO":592,"TRAINER_BRENDEN":572,"TRAINER_BRENT":223,"TRAINER_BRIANNA":118,"TRAINER_BRICE":626,"TRAINER_BRIDGET":129,"TRAINER_BROOKE_1":94,"TRAINER_BROOKE_2":101,"TRAINER_BROOKE_3":102,"TRAINER_BROOKE_4":103,"TRAINER_BROOKE_5":104,"TRAINER_BRYAN":744,"TRAINER_BRYANT":746,"TRAINER_CALE":764,"TRAINER_CALLIE":763,"TRAINER_CALVIN_1":318,"TRAINER_CALVIN_2":328,"TRAINER_CALVIN_3":329,"TRAINER_CALVIN_4":330,"TRAINER_CALVIN_5":331,"TRAINER_CAMDEN":374,"TRAINER_CAMERON_1":238,"TRAINER_CAMERON_2":239,"TRAINER_CAMERON_3":240,"TRAINER_CAMERON_4":241,"TRAINER_CAMERON_5":242,"TRAINER_CAMRON":739,"TRAINER_CARLEE":464,"TRAINER_CAROL":471,"TRAINER_CAROLINA":741,"TRAINER_CAROLINE":99,"TRAINER_CARTER":345,"TRAINER_CATHERINE_1":559,"TRAINER_CATHERINE_2":562,"TRAINER_CATHERINE_3":563,"TRAINER_CATHERINE_4":564,"TRAINER_CATHERINE_5":565,"TRAINER_CEDRIC":475,"TRAINER_CELIA":743,"TRAINER_CELINA":705,"TRAINER_CHAD":174,"TRAINER_CHANDLER":698,"TRAINER_CHARLIE":66,"TRAINER_CHARLOTTE":714,"TRAINER_CHASE":378,"TRAINER_CHESTER":408,"TRAINER_CHIP":45,"TRAINER_CHRIS":693,"TRAINER_CINDY_1":114,"TRAINER_CINDY_2":117,"TRAINER_CINDY_3":120,"TRAINER_CINDY_4":121,"TRAINER_CINDY_5":122,"TRAINER_CINDY_6":123,"TRAINER_CLARENCE":580,"TRAINER_CLARISSA":435,"TRAINER_CLARK":631,"TRAINER_CLAUDE":338,"TRAINER_CLIFFORD":584,"TRAINER_COBY":709,"TRAINER_COLE":201,"TRAINER_COLIN":405,"TRAINER_COLTON":294,"TRAINER_CONNIE":128,"TRAINER_CONOR":511,"TRAINER_CORA":428,"TRAINER_CORY_1":740,"TRAINER_CORY_2":816,"TRAINER_CORY_3":817,"TRAINER_CORY_4":818,"TRAINER_CORY_5":819,"TRAINER_CRISSY":614,"TRAINER_CRISTIAN":574,"TRAINER_CRISTIN_1":767,"TRAINER_CRISTIN_2":828,"TRAINER_CRISTIN_3":829,"TRAINER_CRISTIN_4":830,"TRAINER_CRISTIN_5":831,"TRAINER_CYNDY_1":427,"TRAINER_CYNDY_2":430,"TRAINER_CYNDY_3":431,"TRAINER_CYNDY_4":432,"TRAINER_CYNDY_5":433,"TRAINER_DAISUKE":189,"TRAINER_DAISY":36,"TRAINER_DALE":341,"TRAINER_DALTON_1":196,"TRAINER_DALTON_2":197,"TRAINER_DALTON_3":198,"TRAINER_DALTON_4":199,"TRAINER_DALTON_5":200,"TRAINER_DANA":458,"TRAINER_DANIELLE":650,"TRAINER_DAPHNE":115,"TRAINER_DARCY":733,"TRAINER_DARIAN":696,"TRAINER_DARIUS":803,"TRAINER_DARRIN":154,"TRAINER_DAVID":158,"TRAINER_DAVIS":539,"TRAINER_DAWSON":694,"TRAINER_DAYTON":760,"TRAINER_DEAN":164,"TRAINER_DEANDRE":715,"TRAINER_DEBRA":460,"TRAINER_DECLAN":15,"TRAINER_DEMETRIUS":375,"TRAINER_DENISE":444,"TRAINER_DEREK":227,"TRAINER_DEVAN":753,"TRAINER_DEZ_AND_LUKE":640,"TRAINER_DIANA_1":474,"TRAINER_DIANA_2":477,"TRAINER_DIANA_3":478,"TRAINER_DIANA_4":479,"TRAINER_DIANA_5":480,"TRAINER_DIANNE":417,"TRAINER_DILLON":327,"TRAINER_DOMINIK":152,"TRAINER_DONALD":224,"TRAINER_DONNY":384,"TRAINER_DOUG":618,"TRAINER_DOUGLAS":153,"TRAINER_DRAKE":264,"TRAINER_DREW":211,"TRAINER_DUDLEY":173,"TRAINER_DUNCAN":496,"TRAINER_DUSTY_1":44,"TRAINER_DUSTY_2":47,"TRAINER_DUSTY_3":48,"TRAINER_DUSTY_4":49,"TRAINER_DUSTY_5":50,"TRAINER_DWAYNE":493,"TRAINER_DYLAN_1":364,"TRAINER_DYLAN_2":365,"TRAINER_DYLAN_3":366,"TRAINER_DYLAN_4":367,"TRAINER_DYLAN_5":368,"TRAINER_ED":13,"TRAINER_EDDIE":332,"TRAINER_EDGAR":79,"TRAINER_EDMOND":491,"TRAINER_EDWARD":232,"TRAINER_EDWARDO":404,"TRAINER_EDWIN_1":512,"TRAINER_EDWIN_2":515,"TRAINER_EDWIN_3":516,"TRAINER_EDWIN_4":517,"TRAINER_EDWIN_5":518,"TRAINER_ELI":501,"TRAINER_ELIJAH":742,"TRAINER_ELLIOT_1":339,"TRAINER_ELLIOT_2":346,"TRAINER_ELLIOT_3":347,"TRAINER_ELLIOT_4":348,"TRAINER_ELLIOT_5":349,"TRAINER_ERIC":632,"TRAINER_ERNEST_1":492,"TRAINER_ERNEST_2":497,"TRAINER_ERNEST_3":498,"TRAINER_ERNEST_4":499,"TRAINER_ERNEST_5":500,"TRAINER_ETHAN_1":216,"TRAINER_ETHAN_2":219,"TRAINER_ETHAN_3":220,"TRAINER_ETHAN_4":221,"TRAINER_ETHAN_5":222,"TRAINER_EVERETT":850,"TRAINER_FABIAN":759,"TRAINER_FELIX":38,"TRAINER_FERNANDO_1":195,"TRAINER_FERNANDO_2":832,"TRAINER_FERNANDO_3":833,"TRAINER_FERNANDO_4":834,"TRAINER_FERNANDO_5":835,"TRAINER_FLAGS_END":2143,"TRAINER_FLAGS_START":1280,"TRAINER_FLANNERY_1":268,"TRAINER_FLANNERY_2":782,"TRAINER_FLANNERY_3":783,"TRAINER_FLANNERY_4":784,"TRAINER_FLANNERY_5":785,"TRAINER_FLINT":654,"TRAINER_FOSTER":46,"TRAINER_FRANKLIN":170,"TRAINER_FREDRICK":29,"TRAINER_GABBY_AND_TY_1":51,"TRAINER_GABBY_AND_TY_2":52,"TRAINER_GABBY_AND_TY_3":53,"TRAINER_GABBY_AND_TY_4":54,"TRAINER_GABBY_AND_TY_5":55,"TRAINER_GABBY_AND_TY_6":56,"TRAINER_GABRIELLE_1":9,"TRAINER_GABRIELLE_2":840,"TRAINER_GABRIELLE_3":841,"TRAINER_GABRIELLE_4":842,"TRAINER_GABRIELLE_5":843,"TRAINER_GARRET":138,"TRAINER_GARRISON":547,"TRAINER_GEORGE":73,"TRAINER_GEORGIA":281,"TRAINER_GERALD":648,"TRAINER_GILBERT":169,"TRAINER_GINA_AND_MIA_1":483,"TRAINER_GINA_AND_MIA_2":486,"TRAINER_GLACIA":263,"TRAINER_GRACE":450,"TRAINER_GREG":619,"TRAINER_GRETA":808,"TRAINER_GRUNT_AQUA_HIDEOUT_1":2,"TRAINER_GRUNT_AQUA_HIDEOUT_2":3,"TRAINER_GRUNT_AQUA_HIDEOUT_3":4,"TRAINER_GRUNT_AQUA_HIDEOUT_4":5,"TRAINER_GRUNT_AQUA_HIDEOUT_5":27,"TRAINER_GRUNT_AQUA_HIDEOUT_6":28,"TRAINER_GRUNT_AQUA_HIDEOUT_7":192,"TRAINER_GRUNT_AQUA_HIDEOUT_8":193,"TRAINER_GRUNT_JAGGED_PASS":570,"TRAINER_GRUNT_MAGMA_HIDEOUT_1":716,"TRAINER_GRUNT_MAGMA_HIDEOUT_10":725,"TRAINER_GRUNT_MAGMA_HIDEOUT_11":726,"TRAINER_GRUNT_MAGMA_HIDEOUT_12":727,"TRAINER_GRUNT_MAGMA_HIDEOUT_13":728,"TRAINER_GRUNT_MAGMA_HIDEOUT_14":729,"TRAINER_GRUNT_MAGMA_HIDEOUT_15":730,"TRAINER_GRUNT_MAGMA_HIDEOUT_16":731,"TRAINER_GRUNT_MAGMA_HIDEOUT_2":717,"TRAINER_GRUNT_MAGMA_HIDEOUT_3":718,"TRAINER_GRUNT_MAGMA_HIDEOUT_4":719,"TRAINER_GRUNT_MAGMA_HIDEOUT_5":720,"TRAINER_GRUNT_MAGMA_HIDEOUT_6":721,"TRAINER_GRUNT_MAGMA_HIDEOUT_7":722,"TRAINER_GRUNT_MAGMA_HIDEOUT_8":723,"TRAINER_GRUNT_MAGMA_HIDEOUT_9":724,"TRAINER_GRUNT_MT_CHIMNEY_1":146,"TRAINER_GRUNT_MT_CHIMNEY_2":579,"TRAINER_GRUNT_MT_PYRE_1":23,"TRAINER_GRUNT_MT_PYRE_2":24,"TRAINER_GRUNT_MT_PYRE_3":25,"TRAINER_GRUNT_MT_PYRE_4":569,"TRAINER_GRUNT_MUSEUM_1":20,"TRAINER_GRUNT_MUSEUM_2":21,"TRAINER_GRUNT_PETALBURG_WOODS":10,"TRAINER_GRUNT_RUSTURF_TUNNEL":16,"TRAINER_GRUNT_SEAFLOOR_CAVERN_1":6,"TRAINER_GRUNT_SEAFLOOR_CAVERN_2":7,"TRAINER_GRUNT_SEAFLOOR_CAVERN_3":8,"TRAINER_GRUNT_SEAFLOOR_CAVERN_4":14,"TRAINER_GRUNT_SEAFLOOR_CAVERN_5":567,"TRAINER_GRUNT_SPACE_CENTER_1":22,"TRAINER_GRUNT_SPACE_CENTER_2":116,"TRAINER_GRUNT_SPACE_CENTER_3":586,"TRAINER_GRUNT_SPACE_CENTER_4":587,"TRAINER_GRUNT_SPACE_CENTER_5":588,"TRAINER_GRUNT_SPACE_CENTER_6":589,"TRAINER_GRUNT_SPACE_CENTER_7":590,"TRAINER_GRUNT_UNUSED":568,"TRAINER_GRUNT_WEATHER_INST_1":17,"TRAINER_GRUNT_WEATHER_INST_2":18,"TRAINER_GRUNT_WEATHER_INST_3":19,"TRAINER_GRUNT_WEATHER_INST_4":26,"TRAINER_GRUNT_WEATHER_INST_5":596,"TRAINER_GWEN":59,"TRAINER_HAILEY":697,"TRAINER_HALEY_1":604,"TRAINER_HALEY_2":607,"TRAINER_HALEY_3":608,"TRAINER_HALEY_4":609,"TRAINER_HALEY_5":610,"TRAINER_HALLE":546,"TRAINER_HANNAH":244,"TRAINER_HARRISON":578,"TRAINER_HAYDEN":707,"TRAINER_HECTOR":513,"TRAINER_HEIDI":469,"TRAINER_HELENE":751,"TRAINER_HENRY":668,"TRAINER_HERMAN":167,"TRAINER_HIDEO":651,"TRAINER_HITOSHI":180,"TRAINER_HOPE":96,"TRAINER_HUDSON":510,"TRAINER_HUEY":490,"TRAINER_HUGH":399,"TRAINER_HUMBERTO":402,"TRAINER_IMANI":442,"TRAINER_IRENE":476,"TRAINER_ISAAC_1":538,"TRAINER_ISAAC_2":541,"TRAINER_ISAAC_3":542,"TRAINER_ISAAC_4":543,"TRAINER_ISAAC_5":544,"TRAINER_ISABELLA":595,"TRAINER_ISABELLE":736,"TRAINER_ISABEL_1":302,"TRAINER_ISABEL_2":303,"TRAINER_ISABEL_3":304,"TRAINER_ISABEL_4":305,"TRAINER_ISABEL_5":306,"TRAINER_ISAIAH_1":376,"TRAINER_ISAIAH_2":379,"TRAINER_ISAIAH_3":380,"TRAINER_ISAIAH_4":381,"TRAINER_ISAIAH_5":382,"TRAINER_ISOBEL":383,"TRAINER_IVAN":337,"TRAINER_JACE":204,"TRAINER_JACK":172,"TRAINER_JACKI_1":249,"TRAINER_JACKI_2":250,"TRAINER_JACKI_3":251,"TRAINER_JACKI_4":252,"TRAINER_JACKI_5":253,"TRAINER_JACKSON_1":552,"TRAINER_JACKSON_2":555,"TRAINER_JACKSON_3":556,"TRAINER_JACKSON_4":557,"TRAINER_JACKSON_5":558,"TRAINER_JACLYN":243,"TRAINER_JACOB":351,"TRAINER_JAIDEN":749,"TRAINER_JAMES_1":621,"TRAINER_JAMES_2":622,"TRAINER_JAMES_3":623,"TRAINER_JAMES_4":624,"TRAINER_JAMES_5":625,"TRAINER_JANI":418,"TRAINER_JANICE":605,"TRAINER_JARED":401,"TRAINER_JASMINE":359,"TRAINER_JAYLEN":326,"TRAINER_JAZMYN":503,"TRAINER_JEFF":202,"TRAINER_JEFFREY_1":226,"TRAINER_JEFFREY_2":228,"TRAINER_JEFFREY_3":229,"TRAINER_JEFFREY_4":230,"TRAINER_JEFFREY_5":231,"TRAINER_JENNA":560,"TRAINER_JENNIFER":95,"TRAINER_JENNY_1":449,"TRAINER_JENNY_2":465,"TRAINER_JENNY_3":466,"TRAINER_JENNY_4":467,"TRAINER_JENNY_5":468,"TRAINER_JEROME":156,"TRAINER_JERRY_1":273,"TRAINER_JERRY_2":276,"TRAINER_JERRY_3":277,"TRAINER_JERRY_4":278,"TRAINER_JERRY_5":279,"TRAINER_JESSICA_1":127,"TRAINER_JESSICA_2":132,"TRAINER_JESSICA_3":133,"TRAINER_JESSICA_4":134,"TRAINER_JESSICA_5":135,"TRAINER_JOCELYN":425,"TRAINER_JODY":91,"TRAINER_JOEY":322,"TRAINER_JOHANNA":647,"TRAINER_JOHNSON":754,"TRAINER_JOHN_AND_JAY_1":681,"TRAINER_JOHN_AND_JAY_2":682,"TRAINER_JOHN_AND_JAY_3":683,"TRAINER_JOHN_AND_JAY_4":684,"TRAINER_JOHN_AND_JAY_5":685,"TRAINER_JONAH":667,"TRAINER_JONAS":504,"TRAINER_JONATHAN":598,"TRAINER_JOSE":617,"TRAINER_JOSEPH":700,"TRAINER_JOSH":320,"TRAINER_JOSHUA":237,"TRAINER_JOSUE":738,"TRAINER_JUAN_1":272,"TRAINER_JUAN_2":798,"TRAINER_JUAN_3":799,"TRAINER_JUAN_4":800,"TRAINER_JUAN_5":801,"TRAINER_JULIE":100,"TRAINER_JULIO":566,"TRAINER_JUSTIN":215,"TRAINER_KAI":713,"TRAINER_KALEB":699,"TRAINER_KARA":457,"TRAINER_KAREN_1":280,"TRAINER_KAREN_2":282,"TRAINER_KAREN_3":283,"TRAINER_KAREN_4":284,"TRAINER_KAREN_5":285,"TRAINER_KATELYNN":325,"TRAINER_KATELYN_1":386,"TRAINER_KATELYN_2":388,"TRAINER_KATELYN_3":389,"TRAINER_KATELYN_4":390,"TRAINER_KATELYN_5":391,"TRAINER_KATE_AND_JOY":286,"TRAINER_KATHLEEN":583,"TRAINER_KATIE":455,"TRAINER_KAYLA":247,"TRAINER_KAYLEE":462,"TRAINER_KAYLEY":505,"TRAINER_KEEGAN":205,"TRAINER_KEIGO":652,"TRAINER_KEIRA":93,"TRAINER_KELVIN":507,"TRAINER_KENT":620,"TRAINER_KEVIN":171,"TRAINER_KIM_AND_IRIS":678,"TRAINER_KINDRA":106,"TRAINER_KIRA_AND_DAN_1":642,"TRAINER_KIRA_AND_DAN_2":643,"TRAINER_KIRA_AND_DAN_3":644,"TRAINER_KIRA_AND_DAN_4":645,"TRAINER_KIRA_AND_DAN_5":646,"TRAINER_KIRK":191,"TRAINER_KIYO":181,"TRAINER_KOICHI":182,"TRAINER_KOJI_1":672,"TRAINER_KOJI_2":824,"TRAINER_KOJI_3":825,"TRAINER_KOJI_4":826,"TRAINER_KOJI_5":827,"TRAINER_KYLA":443,"TRAINER_KYRA":748,"TRAINER_LAO_1":419,"TRAINER_LAO_2":421,"TRAINER_LAO_3":422,"TRAINER_LAO_4":423,"TRAINER_LAO_5":424,"TRAINER_LARRY":213,"TRAINER_LAURA":426,"TRAINER_LAUREL":463,"TRAINER_LAWRENCE":710,"TRAINER_LEAF":852,"TRAINER_LEAH":35,"TRAINER_LEA_AND_JED":641,"TRAINER_LENNY":628,"TRAINER_LEONARD":495,"TRAINER_LEONARDO":576,"TRAINER_LEONEL":762,"TRAINER_LEROY":77,"TRAINER_LILA_AND_ROY_1":687,"TRAINER_LILA_AND_ROY_2":688,"TRAINER_LILA_AND_ROY_3":689,"TRAINER_LILA_AND_ROY_4":690,"TRAINER_LILA_AND_ROY_5":691,"TRAINER_LILITH":573,"TRAINER_LINDA":461,"TRAINER_LISA_AND_RAY":692,"TRAINER_LOLA_1":57,"TRAINER_LOLA_2":60,"TRAINER_LOLA_3":61,"TRAINER_LOLA_4":62,"TRAINER_LOLA_5":63,"TRAINER_LORENZO":553,"TRAINER_LUCAS_1":629,"TRAINER_LUCAS_2":633,"TRAINER_LUCY":810,"TRAINER_LUIS":151,"TRAINER_LUNG":420,"TRAINER_LYDIA_1":545,"TRAINER_LYDIA_2":548,"TRAINER_LYDIA_3":549,"TRAINER_LYDIA_4":550,"TRAINER_LYDIA_5":551,"TRAINER_LYLE":616,"TRAINER_MACEY":591,"TRAINER_MADELINE_1":434,"TRAINER_MADELINE_2":437,"TRAINER_MADELINE_3":438,"TRAINER_MADELINE_4":439,"TRAINER_MADELINE_5":440,"TRAINER_MAKAYLA":758,"TRAINER_MARC":571,"TRAINER_MARCEL":11,"TRAINER_MARCOS":702,"TRAINER_MARIA_1":369,"TRAINER_MARIA_2":370,"TRAINER_MARIA_3":371,"TRAINER_MARIA_4":372,"TRAINER_MARIA_5":373,"TRAINER_MARIELA":848,"TRAINER_MARK":145,"TRAINER_MARLENE":752,"TRAINER_MARLEY":508,"TRAINER_MARTHA":473,"TRAINER_MARY":89,"TRAINER_MATT":30,"TRAINER_MATTHEW":157,"TRAINER_MAURA":246,"TRAINER_MAXIE_MAGMA_HIDEOUT":601,"TRAINER_MAXIE_MOSSDEEP":734,"TRAINER_MAXIE_MT_CHIMNEY":602,"TRAINER_MAY_LILYCOVE_MUDKIP":664,"TRAINER_MAY_LILYCOVE_TORCHIC":666,"TRAINER_MAY_LILYCOVE_TREECKO":665,"TRAINER_MAY_PLACEHOLDER":854,"TRAINER_MAY_ROUTE_103_MUDKIP":529,"TRAINER_MAY_ROUTE_103_TORCHIC":535,"TRAINER_MAY_ROUTE_103_TREECKO":532,"TRAINER_MAY_ROUTE_110_MUDKIP":530,"TRAINER_MAY_ROUTE_110_TORCHIC":536,"TRAINER_MAY_ROUTE_110_TREECKO":533,"TRAINER_MAY_ROUTE_119_MUDKIP":531,"TRAINER_MAY_ROUTE_119_TORCHIC":537,"TRAINER_MAY_ROUTE_119_TREECKO":534,"TRAINER_MAY_RUSTBORO_MUDKIP":600,"TRAINER_MAY_RUSTBORO_TORCHIC":769,"TRAINER_MAY_RUSTBORO_TREECKO":768,"TRAINER_MELINA":755,"TRAINER_MELISSA":124,"TRAINER_MEL_AND_PAUL":680,"TRAINER_MICAH":255,"TRAINER_MICHELLE":98,"TRAINER_MIGUEL_1":293,"TRAINER_MIGUEL_2":295,"TRAINER_MIGUEL_3":296,"TRAINER_MIGUEL_4":297,"TRAINER_MIGUEL_5":298,"TRAINER_MIKE_1":634,"TRAINER_MIKE_2":635,"TRAINER_MISSY":447,"TRAINER_MITCHELL":540,"TRAINER_MIU_AND_YUKI":484,"TRAINER_MOLLIE":137,"TRAINER_MYLES":765,"TRAINER_NANCY":472,"TRAINER_NAOMI":119,"TRAINER_NATE":582,"TRAINER_NED":340,"TRAINER_NICHOLAS":585,"TRAINER_NICOLAS_1":392,"TRAINER_NICOLAS_2":393,"TRAINER_NICOLAS_3":394,"TRAINER_NICOLAS_4":395,"TRAINER_NICOLAS_5":396,"TRAINER_NIKKI":453,"TRAINER_NOB_1":183,"TRAINER_NOB_2":184,"TRAINER_NOB_3":185,"TRAINER_NOB_4":186,"TRAINER_NOB_5":187,"TRAINER_NOLAN":342,"TRAINER_NOLAND":809,"TRAINER_NOLEN":161,"TRAINER_NONE":0,"TRAINER_NORMAN_1":269,"TRAINER_NORMAN_2":786,"TRAINER_NORMAN_3":787,"TRAINER_NORMAN_4":788,"TRAINER_NORMAN_5":789,"TRAINER_OLIVIA":130,"TRAINER_OWEN":83,"TRAINER_PABLO_1":377,"TRAINER_PABLO_2":820,"TRAINER_PABLO_3":821,"TRAINER_PABLO_4":822,"TRAINER_PABLO_5":823,"TRAINER_PARKER":72,"TRAINER_PAT":766,"TRAINER_PATRICIA":105,"TRAINER_PAUL":275,"TRAINER_PAULA":429,"TRAINER_PAXTON":594,"TRAINER_PERRY":398,"TRAINER_PETE":735,"TRAINER_PHIL":400,"TRAINER_PHILLIP":494,"TRAINER_PHOEBE":262,"TRAINER_PRESLEY":403,"TRAINER_PRESTON":233,"TRAINER_QUINCY":324,"TRAINER_RACHEL":761,"TRAINER_RANDALL":71,"TRAINER_RED":851,"TRAINER_REED":675,"TRAINER_RELI_AND_IAN":686,"TRAINER_REYNA":509,"TRAINER_RHETT":703,"TRAINER_RICHARD":166,"TRAINER_RICK":615,"TRAINER_RICKY_1":64,"TRAINER_RICKY_2":67,"TRAINER_RICKY_3":68,"TRAINER_RICKY_4":69,"TRAINER_RICKY_5":70,"TRAINER_RILEY":653,"TRAINER_ROBERT_1":406,"TRAINER_ROBERT_2":409,"TRAINER_ROBERT_3":410,"TRAINER_ROBERT_4":411,"TRAINER_ROBERT_5":412,"TRAINER_ROBIN":612,"TRAINER_RODNEY":165,"TRAINER_ROGER":669,"TRAINER_ROLAND":160,"TRAINER_RONALD":350,"TRAINER_ROSE_1":37,"TRAINER_ROSE_2":40,"TRAINER_ROSE_3":41,"TRAINER_ROSE_4":42,"TRAINER_ROSE_5":43,"TRAINER_ROXANNE_1":265,"TRAINER_ROXANNE_2":770,"TRAINER_ROXANNE_3":771,"TRAINER_ROXANNE_4":772,"TRAINER_ROXANNE_5":773,"TRAINER_RUBEN":671,"TRAINER_SALLY":611,"TRAINER_SAMANTHA":245,"TRAINER_SAMUEL":81,"TRAINER_SANTIAGO":168,"TRAINER_SARAH":695,"TRAINER_SAWYER_1":1,"TRAINER_SAWYER_2":836,"TRAINER_SAWYER_3":837,"TRAINER_SAWYER_4":838,"TRAINER_SAWYER_5":839,"TRAINER_SEBASTIAN":554,"TRAINER_SHANE":214,"TRAINER_SHANNON":97,"TRAINER_SHARON":452,"TRAINER_SHAWN":194,"TRAINER_SHAYLA":747,"TRAINER_SHEILA":125,"TRAINER_SHELBY_1":313,"TRAINER_SHELBY_2":314,"TRAINER_SHELBY_3":315,"TRAINER_SHELBY_4":316,"TRAINER_SHELBY_5":317,"TRAINER_SHELLY_SEAFLOOR_CAVERN":33,"TRAINER_SHELLY_WEATHER_INSTITUTE":32,"TRAINER_SHIRLEY":126,"TRAINER_SIDNEY":261,"TRAINER_SIENNA":459,"TRAINER_SIMON":65,"TRAINER_SOPHIA":561,"TRAINER_SOPHIE":708,"TRAINER_SPENCER":159,"TRAINER_SPENSER":807,"TRAINER_STAN":162,"TRAINER_STEVEN":804,"TRAINER_STEVE_1":143,"TRAINER_STEVE_2":147,"TRAINER_STEVE_3":148,"TRAINER_STEVE_4":149,"TRAINER_STEVE_5":150,"TRAINER_SUSIE":456,"TRAINER_SYLVIA":575,"TRAINER_TABITHA_MAGMA_HIDEOUT":732,"TRAINER_TABITHA_MOSSDEEP":514,"TRAINER_TABITHA_MT_CHIMNEY":597,"TRAINER_TAKAO":179,"TRAINER_TAKASHI":416,"TRAINER_TALIA":385,"TRAINER_TAMMY":107,"TRAINER_TANYA":451,"TRAINER_TARA":446,"TRAINER_TASHA":109,"TRAINER_TATE_AND_LIZA_1":271,"TRAINER_TATE_AND_LIZA_2":794,"TRAINER_TATE_AND_LIZA_3":795,"TRAINER_TATE_AND_LIZA_4":796,"TRAINER_TATE_AND_LIZA_5":797,"TRAINER_TAYLOR":225,"TRAINER_TED":274,"TRAINER_TERRY":581,"TRAINER_THALIA_1":144,"TRAINER_THALIA_2":844,"TRAINER_THALIA_3":845,"TRAINER_THALIA_4":846,"TRAINER_THALIA_5":847,"TRAINER_THOMAS":256,"TRAINER_TIANA":603,"TRAINER_TIFFANY":131,"TRAINER_TIMMY":334,"TRAINER_TIMOTHY_1":307,"TRAINER_TIMOTHY_2":308,"TRAINER_TIMOTHY_3":309,"TRAINER_TIMOTHY_4":310,"TRAINER_TIMOTHY_5":311,"TRAINER_TISHA":676,"TRAINER_TOMMY":321,"TRAINER_TONY_1":155,"TRAINER_TONY_2":175,"TRAINER_TONY_3":176,"TRAINER_TONY_4":177,"TRAINER_TONY_5":178,"TRAINER_TORI_AND_TIA":677,"TRAINER_TRAVIS":218,"TRAINER_TRENT_1":627,"TRAINER_TRENT_2":636,"TRAINER_TRENT_3":637,"TRAINER_TRENT_4":638,"TRAINER_TRENT_5":639,"TRAINER_TUCKER":806,"TRAINER_TYRA_AND_IVY":679,"TRAINER_TYRON":704,"TRAINER_VALERIE_1":108,"TRAINER_VALERIE_2":110,"TRAINER_VALERIE_3":111,"TRAINER_VALERIE_4":112,"TRAINER_VALERIE_5":113,"TRAINER_VANESSA":300,"TRAINER_VICKY":312,"TRAINER_VICTOR":292,"TRAINER_VICTORIA":299,"TRAINER_VINCENT":76,"TRAINER_VIOLET":39,"TRAINER_VIRGIL":234,"TRAINER_VITO":82,"TRAINER_VIVI":606,"TRAINER_VIVIAN":649,"TRAINER_WADE":344,"TRAINER_WALLACE":335,"TRAINER_WALLY_MAUVILLE":656,"TRAINER_WALLY_VR_1":519,"TRAINER_WALLY_VR_2":657,"TRAINER_WALLY_VR_3":658,"TRAINER_WALLY_VR_4":659,"TRAINER_WALLY_VR_5":660,"TRAINER_WALTER_1":254,"TRAINER_WALTER_2":257,"TRAINER_WALTER_3":258,"TRAINER_WALTER_4":259,"TRAINER_WALTER_5":260,"TRAINER_WARREN":88,"TRAINER_WATTSON_1":267,"TRAINER_WATTSON_2":778,"TRAINER_WATTSON_3":779,"TRAINER_WATTSON_4":780,"TRAINER_WATTSON_5":781,"TRAINER_WAYNE":673,"TRAINER_WENDY":92,"TRAINER_WILLIAM":236,"TRAINER_WILTON_1":78,"TRAINER_WILTON_2":84,"TRAINER_WILTON_3":85,"TRAINER_WILTON_4":86,"TRAINER_WILTON_5":87,"TRAINER_WINONA_1":270,"TRAINER_WINONA_2":790,"TRAINER_WINONA_3":791,"TRAINER_WINONA_4":792,"TRAINER_WINONA_5":793,"TRAINER_WINSTON_1":136,"TRAINER_WINSTON_2":139,"TRAINER_WINSTON_3":140,"TRAINER_WINSTON_4":141,"TRAINER_WINSTON_5":142,"TRAINER_WYATT":711,"TRAINER_YASU":415,"TRAINER_YUJI":188,"TRAINER_ZANDER":31},"legendary_encounters":[{"address":2538600,"catch_flag":429,"defeat_flag":428,"level":30,"species":410},{"address":2354334,"catch_flag":480,"defeat_flag":447,"level":70,"species":405},{"address":2543160,"catch_flag":146,"defeat_flag":476,"level":70,"species":250},{"address":2354112,"catch_flag":479,"defeat_flag":446,"level":70,"species":404},{"address":2385623,"catch_flag":457,"defeat_flag":456,"level":50,"species":407},{"address":2385687,"catch_flag":482,"defeat_flag":481,"level":50,"species":408},{"address":2543443,"catch_flag":145,"defeat_flag":477,"level":70,"species":249},{"address":2538177,"catch_flag":458,"defeat_flag":455,"level":30,"species":151},{"address":2347488,"catch_flag":478,"defeat_flag":448,"level":70,"species":406},{"address":2345460,"catch_flag":427,"defeat_flag":444,"level":40,"species":402},{"address":2298183,"catch_flag":426,"defeat_flag":443,"level":40,"species":401},{"address":2345731,"catch_flag":483,"defeat_flag":445,"level":40,"species":403}],"locations":{"BADGE_1":{"address":2188036,"default_item":226,"flag":1182},"BADGE_2":{"address":2095131,"default_item":227,"flag":1183},"BADGE_3":{"address":2167252,"default_item":228,"flag":1184},"BADGE_4":{"address":2103246,"default_item":229,"flag":1185},"BADGE_5":{"address":2129781,"default_item":230,"flag":1186},"BADGE_6":{"address":2202122,"default_item":231,"flag":1187},"BADGE_7":{"address":2243964,"default_item":232,"flag":1188},"BADGE_8":{"address":2262314,"default_item":233,"flag":1189},"BERRY_TREE_01":{"address":5843562,"default_item":135,"flag":612},"BERRY_TREE_02":{"address":5843564,"default_item":139,"flag":613},"BERRY_TREE_03":{"address":5843566,"default_item":142,"flag":614},"BERRY_TREE_04":{"address":5843568,"default_item":139,"flag":615},"BERRY_TREE_05":{"address":5843570,"default_item":133,"flag":616},"BERRY_TREE_06":{"address":5843572,"default_item":138,"flag":617},"BERRY_TREE_07":{"address":5843574,"default_item":133,"flag":618},"BERRY_TREE_08":{"address":5843576,"default_item":133,"flag":619},"BERRY_TREE_09":{"address":5843578,"default_item":142,"flag":620},"BERRY_TREE_10":{"address":5843580,"default_item":138,"flag":621},"BERRY_TREE_11":{"address":5843582,"default_item":139,"flag":622},"BERRY_TREE_12":{"address":5843584,"default_item":142,"flag":623},"BERRY_TREE_13":{"address":5843586,"default_item":135,"flag":624},"BERRY_TREE_14":{"address":5843588,"default_item":155,"flag":625},"BERRY_TREE_15":{"address":5843590,"default_item":153,"flag":626},"BERRY_TREE_16":{"address":5843592,"default_item":150,"flag":627},"BERRY_TREE_17":{"address":5843594,"default_item":150,"flag":628},"BERRY_TREE_18":{"address":5843596,"default_item":150,"flag":629},"BERRY_TREE_19":{"address":5843598,"default_item":148,"flag":630},"BERRY_TREE_20":{"address":5843600,"default_item":148,"flag":631},"BERRY_TREE_21":{"address":5843602,"default_item":136,"flag":632},"BERRY_TREE_22":{"address":5843604,"default_item":135,"flag":633},"BERRY_TREE_23":{"address":5843606,"default_item":135,"flag":634},"BERRY_TREE_24":{"address":5843608,"default_item":136,"flag":635},"BERRY_TREE_25":{"address":5843610,"default_item":152,"flag":636},"BERRY_TREE_26":{"address":5843612,"default_item":134,"flag":637},"BERRY_TREE_27":{"address":5843614,"default_item":151,"flag":638},"BERRY_TREE_28":{"address":5843616,"default_item":151,"flag":639},"BERRY_TREE_29":{"address":5843618,"default_item":151,"flag":640},"BERRY_TREE_30":{"address":5843620,"default_item":153,"flag":641},"BERRY_TREE_31":{"address":5843622,"default_item":142,"flag":642},"BERRY_TREE_32":{"address":5843624,"default_item":142,"flag":643},"BERRY_TREE_33":{"address":5843626,"default_item":142,"flag":644},"BERRY_TREE_34":{"address":5843628,"default_item":153,"flag":645},"BERRY_TREE_35":{"address":5843630,"default_item":153,"flag":646},"BERRY_TREE_36":{"address":5843632,"default_item":153,"flag":647},"BERRY_TREE_37":{"address":5843634,"default_item":137,"flag":648},"BERRY_TREE_38":{"address":5843636,"default_item":137,"flag":649},"BERRY_TREE_39":{"address":5843638,"default_item":137,"flag":650},"BERRY_TREE_40":{"address":5843640,"default_item":135,"flag":651},"BERRY_TREE_41":{"address":5843642,"default_item":135,"flag":652},"BERRY_TREE_42":{"address":5843644,"default_item":135,"flag":653},"BERRY_TREE_43":{"address":5843646,"default_item":148,"flag":654},"BERRY_TREE_44":{"address":5843648,"default_item":150,"flag":655},"BERRY_TREE_45":{"address":5843650,"default_item":152,"flag":656},"BERRY_TREE_46":{"address":5843652,"default_item":151,"flag":657},"BERRY_TREE_47":{"address":5843654,"default_item":140,"flag":658},"BERRY_TREE_48":{"address":5843656,"default_item":137,"flag":659},"BERRY_TREE_49":{"address":5843658,"default_item":136,"flag":660},"BERRY_TREE_50":{"address":5843660,"default_item":134,"flag":661},"BERRY_TREE_51":{"address":5843662,"default_item":142,"flag":662},"BERRY_TREE_52":{"address":5843664,"default_item":150,"flag":663},"BERRY_TREE_53":{"address":5843666,"default_item":150,"flag":664},"BERRY_TREE_54":{"address":5843668,"default_item":142,"flag":665},"BERRY_TREE_55":{"address":5843670,"default_item":149,"flag":666},"BERRY_TREE_56":{"address":5843672,"default_item":149,"flag":667},"BERRY_TREE_57":{"address":5843674,"default_item":136,"flag":668},"BERRY_TREE_58":{"address":5843676,"default_item":153,"flag":669},"BERRY_TREE_59":{"address":5843678,"default_item":153,"flag":670},"BERRY_TREE_60":{"address":5843680,"default_item":157,"flag":671},"BERRY_TREE_61":{"address":5843682,"default_item":157,"flag":672},"BERRY_TREE_62":{"address":5843684,"default_item":138,"flag":673},"BERRY_TREE_63":{"address":5843686,"default_item":142,"flag":674},"BERRY_TREE_64":{"address":5843688,"default_item":138,"flag":675},"BERRY_TREE_65":{"address":5843690,"default_item":157,"flag":676},"BERRY_TREE_66":{"address":5843692,"default_item":134,"flag":677},"BERRY_TREE_67":{"address":5843694,"default_item":152,"flag":678},"BERRY_TREE_68":{"address":5843696,"default_item":140,"flag":679},"BERRY_TREE_69":{"address":5843698,"default_item":154,"flag":680},"BERRY_TREE_70":{"address":5843700,"default_item":154,"flag":681},"BERRY_TREE_71":{"address":5843702,"default_item":154,"flag":682},"BERRY_TREE_72":{"address":5843704,"default_item":157,"flag":683},"BERRY_TREE_73":{"address":5843706,"default_item":155,"flag":684},"BERRY_TREE_74":{"address":5843708,"default_item":155,"flag":685},"BERRY_TREE_75":{"address":5843710,"default_item":142,"flag":686},"BERRY_TREE_76":{"address":5843712,"default_item":133,"flag":687},"BERRY_TREE_77":{"address":5843714,"default_item":140,"flag":688},"BERRY_TREE_78":{"address":5843716,"default_item":140,"flag":689},"BERRY_TREE_79":{"address":5843718,"default_item":155,"flag":690},"BERRY_TREE_80":{"address":5843720,"default_item":139,"flag":691},"BERRY_TREE_81":{"address":5843722,"default_item":139,"flag":692},"BERRY_TREE_82":{"address":5843724,"default_item":168,"flag":693},"BERRY_TREE_83":{"address":5843726,"default_item":156,"flag":694},"BERRY_TREE_84":{"address":5843728,"default_item":156,"flag":695},"BERRY_TREE_85":{"address":5843730,"default_item":142,"flag":696},"BERRY_TREE_86":{"address":5843732,"default_item":138,"flag":697},"BERRY_TREE_87":{"address":5843734,"default_item":135,"flag":698},"BERRY_TREE_88":{"address":5843736,"default_item":142,"flag":699},"HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":{"address":5497200,"default_item":281,"flag":531},"HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":{"address":5497212,"default_item":282,"flag":532},"HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":{"address":5497224,"default_item":283,"flag":533},"HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":{"address":5497236,"default_item":284,"flag":534},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":{"address":5500100,"default_item":67,"flag":601},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":{"address":5500124,"default_item":65,"flag":604},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":{"address":5500112,"default_item":64,"flag":603},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":{"address":5500088,"default_item":70,"flag":602},"HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":{"address":5435924,"default_item":110,"flag":528},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":{"address":5487372,"default_item":195,"flag":548},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":{"address":5487384,"default_item":195,"flag":549},"HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":{"address":5489116,"default_item":23,"flag":577},"HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":{"address":5489128,"default_item":3,"flag":576},"HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":{"address":5435672,"default_item":16,"flag":500},"HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":{"address":5432608,"default_item":111,"flag":527},"HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":{"address":5432632,"default_item":4,"flag":575},"HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":{"address":5432620,"default_item":69,"flag":543},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":{"address":5490440,"default_item":35,"flag":578},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":{"address":5490428,"default_item":2,"flag":529},"HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":{"address":5490796,"default_item":68,"flag":580},"HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":{"address":5490784,"default_item":70,"flag":579},"HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":{"address":5525804,"default_item":45,"flag":609},"HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":{"address":5428972,"default_item":68,"flag":595},"HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":{"address":5487908,"default_item":4,"flag":561},"HIDDEN_ITEM_PETALBURG_WOODS_POTION":{"address":5487872,"default_item":13,"flag":558},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":{"address":5487884,"default_item":103,"flag":559},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":{"address":5487896,"default_item":103,"flag":560},"HIDDEN_ITEM_ROUTE_104_ANTIDOTE":{"address":5438492,"default_item":14,"flag":585},"HIDDEN_ITEM_ROUTE_104_HEART_SCALE":{"address":5438504,"default_item":111,"flag":588},"HIDDEN_ITEM_ROUTE_104_POKE_BALL":{"address":5438468,"default_item":4,"flag":562},"HIDDEN_ITEM_ROUTE_104_POTION":{"address":5438480,"default_item":13,"flag":537},"HIDDEN_ITEM_ROUTE_104_SUPER_POTION":{"address":5438456,"default_item":22,"flag":544},"HIDDEN_ITEM_ROUTE_105_BIG_PEARL":{"address":5438748,"default_item":107,"flag":611},"HIDDEN_ITEM_ROUTE_105_HEART_SCALE":{"address":5438736,"default_item":111,"flag":589},"HIDDEN_ITEM_ROUTE_106_HEART_SCALE":{"address":5438932,"default_item":111,"flag":547},"HIDDEN_ITEM_ROUTE_106_POKE_BALL":{"address":5438908,"default_item":4,"flag":563},"HIDDEN_ITEM_ROUTE_106_STARDUST":{"address":5438920,"default_item":108,"flag":546},"HIDDEN_ITEM_ROUTE_108_RARE_CANDY":{"address":5439340,"default_item":68,"flag":586},"HIDDEN_ITEM_ROUTE_109_ETHER":{"address":5440016,"default_item":34,"flag":564},"HIDDEN_ITEM_ROUTE_109_GREAT_BALL":{"address":5440004,"default_item":3,"flag":551},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":{"address":5439992,"default_item":111,"flag":552},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":{"address":5440028,"default_item":111,"flag":590},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":{"address":5440040,"default_item":111,"flag":591},"HIDDEN_ITEM_ROUTE_109_REVIVE":{"address":5439980,"default_item":24,"flag":550},"HIDDEN_ITEM_ROUTE_110_FULL_HEAL":{"address":5441308,"default_item":23,"flag":555},"HIDDEN_ITEM_ROUTE_110_GREAT_BALL":{"address":5441284,"default_item":3,"flag":553},"HIDDEN_ITEM_ROUTE_110_POKE_BALL":{"address":5441296,"default_item":4,"flag":565},"HIDDEN_ITEM_ROUTE_110_REVIVE":{"address":5441272,"default_item":24,"flag":554},"HIDDEN_ITEM_ROUTE_111_PROTEIN":{"address":5443220,"default_item":64,"flag":556},"HIDDEN_ITEM_ROUTE_111_RARE_CANDY":{"address":5443232,"default_item":68,"flag":557},"HIDDEN_ITEM_ROUTE_111_STARDUST":{"address":5443160,"default_item":108,"flag":502},"HIDDEN_ITEM_ROUTE_113_ETHER":{"address":5444488,"default_item":34,"flag":503},"HIDDEN_ITEM_ROUTE_113_NUGGET":{"address":5444512,"default_item":110,"flag":598},"HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":{"address":5444500,"default_item":320,"flag":530},"HIDDEN_ITEM_ROUTE_114_CARBOS":{"address":5445340,"default_item":66,"flag":504},"HIDDEN_ITEM_ROUTE_114_REVIVE":{"address":5445364,"default_item":24,"flag":542},"HIDDEN_ITEM_ROUTE_115_HEART_SCALE":{"address":5446176,"default_item":111,"flag":597},"HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":{"address":5447056,"default_item":206,"flag":596},"HIDDEN_ITEM_ROUTE_116_SUPER_POTION":{"address":5447044,"default_item":22,"flag":545},"HIDDEN_ITEM_ROUTE_117_REPEL":{"address":5447708,"default_item":86,"flag":572},"HIDDEN_ITEM_ROUTE_118_HEART_SCALE":{"address":5448404,"default_item":111,"flag":566},"HIDDEN_ITEM_ROUTE_118_IRON":{"address":5448392,"default_item":65,"flag":567},"HIDDEN_ITEM_ROUTE_119_CALCIUM":{"address":5449972,"default_item":67,"flag":505},"HIDDEN_ITEM_ROUTE_119_FULL_HEAL":{"address":5450056,"default_item":23,"flag":568},"HIDDEN_ITEM_ROUTE_119_MAX_ETHER":{"address":5450068,"default_item":35,"flag":587},"HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":{"address":5449984,"default_item":2,"flag":506},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":{"address":5451596,"default_item":68,"flag":571},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":{"address":5451620,"default_item":68,"flag":569},"HIDDEN_ITEM_ROUTE_120_REVIVE":{"address":5451608,"default_item":24,"flag":584},"HIDDEN_ITEM_ROUTE_120_ZINC":{"address":5451632,"default_item":70,"flag":570},"HIDDEN_ITEM_ROUTE_121_FULL_HEAL":{"address":5452540,"default_item":23,"flag":573},"HIDDEN_ITEM_ROUTE_121_HP_UP":{"address":5452516,"default_item":63,"flag":539},"HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":{"address":5452552,"default_item":25,"flag":600},"HIDDEN_ITEM_ROUTE_121_NUGGET":{"address":5452528,"default_item":110,"flag":540},"HIDDEN_ITEM_ROUTE_123_HYPER_POTION":{"address":5454100,"default_item":21,"flag":574},"HIDDEN_ITEM_ROUTE_123_PP_UP":{"address":5454112,"default_item":69,"flag":599},"HIDDEN_ITEM_ROUTE_123_RARE_CANDY":{"address":5454124,"default_item":68,"flag":610},"HIDDEN_ITEM_ROUTE_123_REVIVE":{"address":5454088,"default_item":24,"flag":541},"HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":{"address":5454052,"default_item":83,"flag":507},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":{"address":5455620,"default_item":111,"flag":592},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":{"address":5455632,"default_item":111,"flag":593},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":{"address":5455644,"default_item":111,"flag":594},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":{"address":5517256,"default_item":68,"flag":606},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":{"address":5517268,"default_item":70,"flag":607},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":{"address":5517432,"default_item":19,"flag":605},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":{"address":5517420,"default_item":69,"flag":608},"HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":{"address":5511292,"default_item":200,"flag":535},"HIDDEN_ITEM_TRICK_HOUSE_NUGGET":{"address":5526716,"default_item":110,"flag":501},"HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":{"address":5456992,"default_item":107,"flag":511},"HIDDEN_ITEM_UNDERWATER_124_CALCIUM":{"address":5457016,"default_item":67,"flag":536},"HIDDEN_ITEM_UNDERWATER_124_CARBOS":{"address":5456956,"default_item":66,"flag":508},"HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":{"address":5456968,"default_item":51,"flag":509},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":{"address":5457004,"default_item":111,"flag":513},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":{"address":5457028,"default_item":111,"flag":538},"HIDDEN_ITEM_UNDERWATER_124_PEARL":{"address":5456980,"default_item":106,"flag":510},"HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":{"address":5457140,"default_item":107,"flag":520},"HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":{"address":5457152,"default_item":49,"flag":512},"HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":{"address":5457068,"default_item":111,"flag":514},"HIDDEN_ITEM_UNDERWATER_126_IRON":{"address":5457116,"default_item":65,"flag":519},"HIDDEN_ITEM_UNDERWATER_126_PEARL":{"address":5457104,"default_item":106,"flag":517},"HIDDEN_ITEM_UNDERWATER_126_STARDUST":{"address":5457092,"default_item":108,"flag":516},"HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":{"address":5457080,"default_item":2,"flag":515},"HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":{"address":5457128,"default_item":50,"flag":518},"HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":{"address":5457224,"default_item":111,"flag":523},"HIDDEN_ITEM_UNDERWATER_127_HP_UP":{"address":5457212,"default_item":63,"flag":522},"HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":{"address":5457236,"default_item":48,"flag":524},"HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":{"address":5457200,"default_item":109,"flag":521},"HIDDEN_ITEM_UNDERWATER_128_PEARL":{"address":5457288,"default_item":106,"flag":526},"HIDDEN_ITEM_UNDERWATER_128_PROTEIN":{"address":5457276,"default_item":64,"flag":525},"HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":{"address":5493932,"default_item":2,"flag":581},"HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":{"address":5494744,"default_item":36,"flag":582},"HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":{"address":5494756,"default_item":84,"flag":583},"ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":{"address":2709805,"default_item":285,"flag":1100},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":{"address":2709857,"default_item":306,"flag":1102},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":{"address":2709831,"default_item":278,"flag":1078},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":{"address":2709844,"default_item":97,"flag":1101},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":{"address":2709818,"default_item":11,"flag":1077},"ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":{"address":2709740,"default_item":122,"flag":1095},"ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":{"address":2709792,"default_item":24,"flag":1099},"ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":{"address":2709766,"default_item":7,"flag":1097},"ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":{"address":2709753,"default_item":85,"flag":1096},"ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":{"address":2709779,"default_item":301,"flag":1098},"ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":{"address":2710039,"default_item":1,"flag":1124},"ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":{"address":2710065,"default_item":37,"flag":1071},"ITEM_AQUA_HIDEOUT_B1F_NUGGET":{"address":2710052,"default_item":110,"flag":1132},"ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":{"address":2710078,"default_item":8,"flag":1072},"ITEM_ARTISAN_CAVE_1F_CARBOS":{"address":2710416,"default_item":66,"flag":1163},"ITEM_ARTISAN_CAVE_B1F_HP_UP":{"address":2710403,"default_item":63,"flag":1162},"ITEM_FIERY_PATH_FIRE_STONE":{"address":2709584,"default_item":95,"flag":1111},"ITEM_FIERY_PATH_TM_TOXIC":{"address":2709597,"default_item":294,"flag":1091},"ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":{"address":2709519,"default_item":85,"flag":1050},"ITEM_GRANITE_CAVE_B1F_POKE_BALL":{"address":2709532,"default_item":4,"flag":1051},"ITEM_GRANITE_CAVE_B2F_RARE_CANDY":{"address":2709558,"default_item":68,"flag":1054},"ITEM_GRANITE_CAVE_B2F_REPEL":{"address":2709545,"default_item":86,"flag":1053},"ITEM_JAGGED_PASS_BURN_HEAL":{"address":2709571,"default_item":15,"flag":1070},"ITEM_LILYCOVE_CITY_MAX_REPEL":{"address":2709415,"default_item":84,"flag":1042},"ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":{"address":2710429,"default_item":68,"flag":1151},"ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":{"address":2710455,"default_item":19,"flag":1165},"ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":{"address":2710442,"default_item":37,"flag":1164},"ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":{"address":2710468,"default_item":110,"flag":1166},"ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":{"address":2710481,"default_item":71,"flag":1167},"ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":{"address":2710507,"default_item":85,"flag":1059},"ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":{"address":2710494,"default_item":25,"flag":1168},"ITEM_MAUVILLE_CITY_X_SPEED":{"address":2709389,"default_item":77,"flag":1116},"ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":{"address":2709623,"default_item":23,"flag":1045},"ITEM_METEOR_FALLS_1F_1R_MOON_STONE":{"address":2709636,"default_item":94,"flag":1046},"ITEM_METEOR_FALLS_1F_1R_PP_UP":{"address":2709649,"default_item":69,"flag":1047},"ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":{"address":2709610,"default_item":311,"flag":1044},"ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":{"address":2709662,"default_item":290,"flag":1080},"ITEM_MOSSDEEP_CITY_NET_BALL":{"address":2709428,"default_item":6,"flag":1043},"ITEM_MT_PYRE_2F_ULTRA_BALL":{"address":2709948,"default_item":2,"flag":1129},"ITEM_MT_PYRE_3F_SUPER_REPEL":{"address":2709961,"default_item":83,"flag":1120},"ITEM_MT_PYRE_4F_SEA_INCENSE":{"address":2709974,"default_item":220,"flag":1130},"ITEM_MT_PYRE_5F_LAX_INCENSE":{"address":2709987,"default_item":221,"flag":1052},"ITEM_MT_PYRE_6F_TM_SHADOW_BALL":{"address":2710000,"default_item":318,"flag":1089},"ITEM_MT_PYRE_EXTERIOR_MAX_POTION":{"address":2710013,"default_item":20,"flag":1073},"ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":{"address":2710026,"default_item":336,"flag":1074},"ITEM_NEW_MAUVILLE_ESCAPE_ROPE":{"address":2709688,"default_item":85,"flag":1076},"ITEM_NEW_MAUVILLE_FULL_HEAL":{"address":2709714,"default_item":23,"flag":1122},"ITEM_NEW_MAUVILLE_PARALYZE_HEAL":{"address":2709727,"default_item":18,"flag":1123},"ITEM_NEW_MAUVILLE_THUNDER_STONE":{"address":2709701,"default_item":96,"flag":1110},"ITEM_NEW_MAUVILLE_ULTRA_BALL":{"address":2709675,"default_item":2,"flag":1075},"ITEM_PETALBURG_CITY_ETHER":{"address":2709376,"default_item":34,"flag":1040},"ITEM_PETALBURG_CITY_MAX_REVIVE":{"address":2709363,"default_item":25,"flag":1039},"ITEM_PETALBURG_WOODS_ETHER":{"address":2709467,"default_item":34,"flag":1058},"ITEM_PETALBURG_WOODS_GREAT_BALL":{"address":2709454,"default_item":3,"flag":1056},"ITEM_PETALBURG_WOODS_PARALYZE_HEAL":{"address":2709480,"default_item":18,"flag":1117},"ITEM_PETALBURG_WOODS_X_ATTACK":{"address":2709441,"default_item":75,"flag":1055},"ITEM_ROUTE_102_POTION":{"address":2708375,"default_item":13,"flag":1000},"ITEM_ROUTE_103_GUARD_SPEC":{"address":2708388,"default_item":73,"flag":1114},"ITEM_ROUTE_103_PP_UP":{"address":2708401,"default_item":69,"flag":1137},"ITEM_ROUTE_104_POKE_BALL":{"address":2708427,"default_item":4,"flag":1057},"ITEM_ROUTE_104_POTION":{"address":2708453,"default_item":13,"flag":1135},"ITEM_ROUTE_104_PP_UP":{"address":2708414,"default_item":69,"flag":1002},"ITEM_ROUTE_104_X_ACCURACY":{"address":2708440,"default_item":78,"flag":1115},"ITEM_ROUTE_105_IRON":{"address":2708466,"default_item":65,"flag":1003},"ITEM_ROUTE_106_PROTEIN":{"address":2708479,"default_item":64,"flag":1004},"ITEM_ROUTE_108_STAR_PIECE":{"address":2708492,"default_item":109,"flag":1139},"ITEM_ROUTE_109_POTION":{"address":2708518,"default_item":13,"flag":1140},"ITEM_ROUTE_109_PP_UP":{"address":2708505,"default_item":69,"flag":1005},"ITEM_ROUTE_110_DIRE_HIT":{"address":2708544,"default_item":74,"flag":1007},"ITEM_ROUTE_110_ELIXIR":{"address":2708557,"default_item":36,"flag":1141},"ITEM_ROUTE_110_RARE_CANDY":{"address":2708531,"default_item":68,"flag":1006},"ITEM_ROUTE_111_ELIXIR":{"address":2708609,"default_item":36,"flag":1142},"ITEM_ROUTE_111_HP_UP":{"address":2708596,"default_item":63,"flag":1010},"ITEM_ROUTE_111_STARDUST":{"address":2708583,"default_item":108,"flag":1009},"ITEM_ROUTE_111_TM_SANDSTORM":{"address":2708570,"default_item":325,"flag":1008},"ITEM_ROUTE_112_NUGGET":{"address":2708622,"default_item":110,"flag":1011},"ITEM_ROUTE_113_HYPER_POTION":{"address":2708661,"default_item":21,"flag":1143},"ITEM_ROUTE_113_MAX_ETHER":{"address":2708635,"default_item":35,"flag":1012},"ITEM_ROUTE_113_SUPER_REPEL":{"address":2708648,"default_item":83,"flag":1013},"ITEM_ROUTE_114_ENERGY_POWDER":{"address":2708700,"default_item":30,"flag":1160},"ITEM_ROUTE_114_PROTEIN":{"address":2708687,"default_item":64,"flag":1015},"ITEM_ROUTE_114_RARE_CANDY":{"address":2708674,"default_item":68,"flag":1014},"ITEM_ROUTE_115_GREAT_BALL":{"address":2708752,"default_item":3,"flag":1118},"ITEM_ROUTE_115_HEAL_POWDER":{"address":2708765,"default_item":32,"flag":1144},"ITEM_ROUTE_115_IRON":{"address":2708739,"default_item":65,"flag":1018},"ITEM_ROUTE_115_PP_UP":{"address":2708778,"default_item":69,"flag":1161},"ITEM_ROUTE_115_SUPER_POTION":{"address":2708713,"default_item":22,"flag":1016},"ITEM_ROUTE_115_TM_FOCUS_PUNCH":{"address":2708726,"default_item":289,"flag":1017},"ITEM_ROUTE_116_ETHER":{"address":2708804,"default_item":34,"flag":1019},"ITEM_ROUTE_116_HP_UP":{"address":2708830,"default_item":63,"flag":1021},"ITEM_ROUTE_116_POTION":{"address":2708843,"default_item":13,"flag":1146},"ITEM_ROUTE_116_REPEL":{"address":2708817,"default_item":86,"flag":1020},"ITEM_ROUTE_116_X_SPECIAL":{"address":2708791,"default_item":79,"flag":1001},"ITEM_ROUTE_117_GREAT_BALL":{"address":2708856,"default_item":3,"flag":1022},"ITEM_ROUTE_117_REVIVE":{"address":2708869,"default_item":24,"flag":1023},"ITEM_ROUTE_118_HYPER_POTION":{"address":2708882,"default_item":21,"flag":1121},"ITEM_ROUTE_119_ELIXIR_1":{"address":2708921,"default_item":36,"flag":1026},"ITEM_ROUTE_119_ELIXIR_2":{"address":2708986,"default_item":36,"flag":1147},"ITEM_ROUTE_119_HYPER_POTION_1":{"address":2708960,"default_item":21,"flag":1029},"ITEM_ROUTE_119_HYPER_POTION_2":{"address":2708973,"default_item":21,"flag":1106},"ITEM_ROUTE_119_LEAF_STONE":{"address":2708934,"default_item":98,"flag":1027},"ITEM_ROUTE_119_NUGGET":{"address":2710104,"default_item":110,"flag":1134},"ITEM_ROUTE_119_RARE_CANDY":{"address":2708947,"default_item":68,"flag":1028},"ITEM_ROUTE_119_SUPER_REPEL":{"address":2708895,"default_item":83,"flag":1024},"ITEM_ROUTE_119_ZINC":{"address":2708908,"default_item":70,"flag":1025},"ITEM_ROUTE_120_FULL_HEAL":{"address":2709012,"default_item":23,"flag":1031},"ITEM_ROUTE_120_HYPER_POTION":{"address":2709025,"default_item":21,"flag":1107},"ITEM_ROUTE_120_NEST_BALL":{"address":2709038,"default_item":8,"flag":1108},"ITEM_ROUTE_120_NUGGET":{"address":2708999,"default_item":110,"flag":1030},"ITEM_ROUTE_120_REVIVE":{"address":2709051,"default_item":24,"flag":1148},"ITEM_ROUTE_121_CARBOS":{"address":2709064,"default_item":66,"flag":1103},"ITEM_ROUTE_121_REVIVE":{"address":2709077,"default_item":24,"flag":1149},"ITEM_ROUTE_121_ZINC":{"address":2709090,"default_item":70,"flag":1150},"ITEM_ROUTE_123_CALCIUM":{"address":2709103,"default_item":67,"flag":1032},"ITEM_ROUTE_123_ELIXIR":{"address":2709129,"default_item":36,"flag":1109},"ITEM_ROUTE_123_PP_UP":{"address":2709142,"default_item":69,"flag":1152},"ITEM_ROUTE_123_REVIVAL_HERB":{"address":2709155,"default_item":33,"flag":1153},"ITEM_ROUTE_123_ULTRA_BALL":{"address":2709116,"default_item":2,"flag":1104},"ITEM_ROUTE_124_BLUE_SHARD":{"address":2709181,"default_item":49,"flag":1093},"ITEM_ROUTE_124_RED_SHARD":{"address":2709168,"default_item":48,"flag":1092},"ITEM_ROUTE_124_YELLOW_SHARD":{"address":2709194,"default_item":50,"flag":1066},"ITEM_ROUTE_125_BIG_PEARL":{"address":2709207,"default_item":107,"flag":1154},"ITEM_ROUTE_126_GREEN_SHARD":{"address":2709220,"default_item":51,"flag":1105},"ITEM_ROUTE_127_CARBOS":{"address":2709246,"default_item":66,"flag":1035},"ITEM_ROUTE_127_RARE_CANDY":{"address":2709259,"default_item":68,"flag":1155},"ITEM_ROUTE_127_ZINC":{"address":2709233,"default_item":70,"flag":1034},"ITEM_ROUTE_132_PROTEIN":{"address":2709285,"default_item":64,"flag":1156},"ITEM_ROUTE_132_RARE_CANDY":{"address":2709272,"default_item":68,"flag":1036},"ITEM_ROUTE_133_BIG_PEARL":{"address":2709298,"default_item":107,"flag":1037},"ITEM_ROUTE_133_MAX_REVIVE":{"address":2709324,"default_item":25,"flag":1157},"ITEM_ROUTE_133_STAR_PIECE":{"address":2709311,"default_item":109,"flag":1038},"ITEM_ROUTE_134_CARBOS":{"address":2709337,"default_item":66,"flag":1158},"ITEM_ROUTE_134_STAR_PIECE":{"address":2709350,"default_item":109,"flag":1159},"ITEM_RUSTBORO_CITY_X_DEFEND":{"address":2709402,"default_item":76,"flag":1041},"ITEM_RUSTURF_TUNNEL_MAX_ETHER":{"address":2709506,"default_item":35,"flag":1049},"ITEM_RUSTURF_TUNNEL_POKE_BALL":{"address":2709493,"default_item":4,"flag":1048},"ITEM_SAFARI_ZONE_NORTH_CALCIUM":{"address":2709896,"default_item":67,"flag":1119},"ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":{"address":2709922,"default_item":110,"flag":1169},"ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":{"address":2709883,"default_item":310,"flag":1094},"ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":{"address":2709935,"default_item":107,"flag":1170},"ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":{"address":2709909,"default_item":25,"flag":1131},"ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":{"address":2709870,"default_item":299,"flag":1079},"ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":{"address":2710208,"default_item":314,"flag":1090},"ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":{"address":2710143,"default_item":107,"flag":1081},"ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":{"address":2710195,"default_item":212,"flag":1113},"ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":{"address":2710182,"default_item":295,"flag":1112},"ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":{"address":2710156,"default_item":68,"flag":1082},"ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":{"address":2710169,"default_item":16,"flag":1083},"ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":{"address":[2710221,2551006],"default_item":121,"flag":1060},"ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":{"address":[2710234,2551032],"default_item":122,"flag":1061},"ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":{"address":[2710247,2551058],"default_item":126,"flag":1062},"ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":{"address":[2710260,2551084],"default_item":128,"flag":1063},"ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":{"address":[2710273,2551110],"default_item":125,"flag":1064},"ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":{"address":[2710286,2551136],"default_item":124,"flag":1065},"ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":{"address":[2710299,2551162],"default_item":123,"flag":1067},"ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":{"address":[2710312,2551188],"default_item":129,"flag":1068},"ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":{"address":[2710325,2551214],"default_item":127,"flag":1069},"ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":{"address":2710338,"default_item":37,"flag":1084},"ITEM_VICTORY_ROAD_1F_PP_UP":{"address":2710351,"default_item":69,"flag":1085},"ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":{"address":2710377,"default_item":19,"flag":1087},"ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":{"address":2710364,"default_item":317,"flag":1086},"ITEM_VICTORY_ROAD_B2F_FULL_HEAL":{"address":2710390,"default_item":23,"flag":1088},"NPC_GIFT_BERRY_MASTERS_WIFE":{"address":2570453,"default_item":133,"flag":1197},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_1":{"address":2570263,"default_item":153,"flag":1195},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_2":{"address":2570315,"default_item":154,"flag":1196},"NPC_GIFT_FLOWER_SHOP_RECEIVED_BERRY":{"address":2284375,"default_item":133,"flag":1207},"NPC_GIFT_GOT_BASEMENT_KEY_FROM_WATTSON":{"address":1971718,"default_item":271,"flag":208},"NPC_GIFT_GOT_TM_THUNDERBOLT_FROM_WATTSON":{"address":1971754,"default_item":312,"flag":209},"NPC_GIFT_LILYCOVE_RECEIVED_BERRY":{"address":1985277,"default_item":141,"flag":1208},"NPC_GIFT_RECEIVED_6_SODA_POP":{"address":2543767,"default_item":27,"flag":140},"NPC_GIFT_RECEIVED_ACRO_BIKE":{"address":2170570,"default_item":272,"flag":1181},"NPC_GIFT_RECEIVED_AMULET_COIN":{"address":2716248,"default_item":189,"flag":133},"NPC_GIFT_RECEIVED_AURORA_TICKET":{"address":2716523,"default_item":371,"flag":314},"NPC_GIFT_RECEIVED_CHARCOAL":{"address":2102559,"default_item":215,"flag":254},"NPC_GIFT_RECEIVED_CHESTO_BERRY_ROUTE_104":{"address":2028703,"default_item":134,"flag":246},"NPC_GIFT_RECEIVED_CLEANSE_TAG":{"address":2312109,"default_item":190,"flag":282},"NPC_GIFT_RECEIVED_COIN_CASE":{"address":2179054,"default_item":260,"flag":258},"NPC_GIFT_RECEIVED_DEEP_SEA_SCALE":{"address":2162572,"default_item":193,"flag":1190},"NPC_GIFT_RECEIVED_DEEP_SEA_TOOTH":{"address":2162555,"default_item":192,"flag":1191},"NPC_GIFT_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":{"address":2295814,"default_item":269,"flag":1172},"NPC_GIFT_RECEIVED_DEVON_SCOPE":{"address":2065146,"default_item":288,"flag":285},"NPC_GIFT_RECEIVED_EON_TICKET":{"address":2716574,"default_item":275,"flag":474},"NPC_GIFT_RECEIVED_EXP_SHARE":{"address":2185525,"default_item":182,"flag":272},"NPC_GIFT_RECEIVED_FIRST_POKEBALLS":{"address":2085751,"default_item":4,"flag":233},"NPC_GIFT_RECEIVED_FOCUS_BAND":{"address":2337807,"default_item":196,"flag":283},"NPC_GIFT_RECEIVED_GOOD_ROD":{"address":2058408,"default_item":263,"flag":227},"NPC_GIFT_RECEIVED_GO_GOGGLES":{"address":2017746,"default_item":279,"flag":221},"NPC_GIFT_RECEIVED_GREAT_BALL_PETALBURG_WOODS":{"address":2300119,"default_item":3,"flag":1171},"NPC_GIFT_RECEIVED_GREAT_BALL_RUSTBORO_CITY":{"address":1977146,"default_item":3,"flag":1173},"NPC_GIFT_RECEIVED_HM_CUT":{"address":2199532,"default_item":339,"flag":137},"NPC_GIFT_RECEIVED_HM_DIVE":{"address":2252095,"default_item":346,"flag":123},"NPC_GIFT_RECEIVED_HM_FLASH":{"address":2298287,"default_item":343,"flag":109},"NPC_GIFT_RECEIVED_HM_FLY":{"address":2060636,"default_item":340,"flag":110},"NPC_GIFT_RECEIVED_HM_ROCK_SMASH":{"address":2174128,"default_item":344,"flag":107},"NPC_GIFT_RECEIVED_HM_STRENGTH":{"address":2295305,"default_item":342,"flag":106},"NPC_GIFT_RECEIVED_HM_SURF":{"address":2126671,"default_item":341,"flag":122},"NPC_GIFT_RECEIVED_HM_WATERFALL":{"address":1999854,"default_item":345,"flag":312},"NPC_GIFT_RECEIVED_ITEMFINDER":{"address":2039874,"default_item":261,"flag":1176},"NPC_GIFT_RECEIVED_KINGS_ROCK":{"address":1993670,"default_item":187,"flag":276},"NPC_GIFT_RECEIVED_LETTER":{"address":2185301,"default_item":274,"flag":1174},"NPC_GIFT_RECEIVED_MACHO_BRACE":{"address":2284472,"default_item":181,"flag":277},"NPC_GIFT_RECEIVED_MACH_BIKE":{"address":2170553,"default_item":259,"flag":1180},"NPC_GIFT_RECEIVED_MAGMA_EMBLEM":{"address":2316671,"default_item":375,"flag":1177},"NPC_GIFT_RECEIVED_MENTAL_HERB":{"address":2208103,"default_item":185,"flag":223},"NPC_GIFT_RECEIVED_METEORITE":{"address":2304222,"default_item":280,"flag":115},"NPC_GIFT_RECEIVED_MIRACLE_SEED":{"address":2300337,"default_item":205,"flag":297},"NPC_GIFT_RECEIVED_MYSTIC_TICKET":{"address":2716540,"default_item":370,"flag":315},"NPC_GIFT_RECEIVED_OLD_ROD":{"address":2012541,"default_item":262,"flag":257},"NPC_GIFT_RECEIVED_OLD_SEA_MAP":{"address":2716557,"default_item":376,"flag":316},"NPC_GIFT_RECEIVED_POKEBLOCK_CASE":{"address":2614193,"default_item":273,"flag":95},"NPC_GIFT_RECEIVED_POTION_OLDALE":{"address":2010888,"default_item":13,"flag":132},"NPC_GIFT_RECEIVED_POWDER_JAR":{"address":1962504,"default_item":372,"flag":337},"NPC_GIFT_RECEIVED_PREMIER_BALL_RUSTBORO":{"address":2200571,"default_item":12,"flag":213},"NPC_GIFT_RECEIVED_QUICK_CLAW":{"address":2192227,"default_item":183,"flag":275},"NPC_GIFT_RECEIVED_REPEAT_BALL":{"address":2053722,"default_item":9,"flag":256},"NPC_GIFT_RECEIVED_SECRET_POWER":{"address":2598914,"default_item":331,"flag":96},"NPC_GIFT_RECEIVED_SILK_SCARF":{"address":2101830,"default_item":217,"flag":289},"NPC_GIFT_RECEIVED_SOFT_SAND":{"address":2035664,"default_item":203,"flag":280},"NPC_GIFT_RECEIVED_SOOTHE_BELL":{"address":2151278,"default_item":184,"flag":278},"NPC_GIFT_RECEIVED_SOOT_SACK":{"address":2567245,"default_item":270,"flag":1033},"NPC_GIFT_RECEIVED_SS_TICKET":{"address":2716506,"default_item":265,"flag":291},"NPC_GIFT_RECEIVED_SUN_STONE_MOSSDEEP":{"address":2254406,"default_item":93,"flag":192},"NPC_GIFT_RECEIVED_SUPER_ROD":{"address":2251560,"default_item":264,"flag":152},"NPC_GIFT_RECEIVED_TM_AERIAL_ACE":{"address":2202201,"default_item":328,"flag":170},"NPC_GIFT_RECEIVED_TM_ATTRACT":{"address":2116413,"default_item":333,"flag":235},"NPC_GIFT_RECEIVED_TM_BRICK_BREAK":{"address":2269085,"default_item":319,"flag":121},"NPC_GIFT_RECEIVED_TM_BULK_UP":{"address":2095210,"default_item":296,"flag":166},"NPC_GIFT_RECEIVED_TM_BULLET_SEED":{"address":2028910,"default_item":297,"flag":262},"NPC_GIFT_RECEIVED_TM_CALM_MIND":{"address":2244066,"default_item":292,"flag":171},"NPC_GIFT_RECEIVED_TM_DIG":{"address":2286669,"default_item":316,"flag":261},"NPC_GIFT_RECEIVED_TM_FACADE":{"address":2129909,"default_item":330,"flag":169},"NPC_GIFT_RECEIVED_TM_FRUSTRATION":{"address":2124110,"default_item":309,"flag":1179},"NPC_GIFT_RECEIVED_TM_GIGA_DRAIN":{"address":2068012,"default_item":307,"flag":232},"NPC_GIFT_RECEIVED_TM_HIDDEN_POWER":{"address":2206905,"default_item":298,"flag":264},"NPC_GIFT_RECEIVED_TM_OVERHEAT":{"address":2103328,"default_item":338,"flag":168},"NPC_GIFT_RECEIVED_TM_REST":{"address":2236966,"default_item":332,"flag":234},"NPC_GIFT_RECEIVED_TM_RETURN":{"address":2113546,"default_item":315,"flag":229},"NPC_GIFT_RECEIVED_TM_RETURN_2":{"address":2124055,"default_item":315,"flag":1178},"NPC_GIFT_RECEIVED_TM_ROAR":{"address":2051750,"default_item":293,"flag":231},"NPC_GIFT_RECEIVED_TM_ROCK_TOMB":{"address":2188088,"default_item":327,"flag":165},"NPC_GIFT_RECEIVED_TM_SHOCK_WAVE":{"address":2167340,"default_item":322,"flag":167},"NPC_GIFT_RECEIVED_TM_SLUDGE_BOMB":{"address":2099189,"default_item":324,"flag":230},"NPC_GIFT_RECEIVED_TM_SNATCH":{"address":2360766,"default_item":337,"flag":260},"NPC_GIFT_RECEIVED_TM_STEEL_WING":{"address":2298866,"default_item":335,"flag":1175},"NPC_GIFT_RECEIVED_TM_THIEF":{"address":2154698,"default_item":334,"flag":269},"NPC_GIFT_RECEIVED_TM_TORMENT":{"address":2145260,"default_item":329,"flag":265},"NPC_GIFT_RECEIVED_TM_WATER_PULSE":{"address":2262402,"default_item":291,"flag":172},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_1":{"address":2550316,"default_item":68,"flag":1200},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_2":{"address":2550390,"default_item":10,"flag":1201},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_3":{"address":2550473,"default_item":204,"flag":1202},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_4":{"address":2550556,"default_item":194,"flag":1203},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_5":{"address":2550630,"default_item":300,"flag":1204},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_6":{"address":2550695,"default_item":208,"flag":1205},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_7":{"address":2550769,"default_item":71,"flag":1206},"NPC_GIFT_RECEIVED_WAILMER_PAIL":{"address":2284320,"default_item":268,"flag":94},"NPC_GIFT_RECEIVED_WHITE_HERB":{"address":2028770,"default_item":180,"flag":279},"NPC_GIFT_ROUTE_111_RECEIVED_BERRY":{"address":2045493,"default_item":148,"flag":1192},"NPC_GIFT_ROUTE_114_RECEIVED_BERRY":{"address":2051680,"default_item":149,"flag":1193},"NPC_GIFT_ROUTE_120_RECEIVED_BERRY":{"address":2064727,"default_item":143,"flag":1194},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_1":{"address":1998521,"default_item":153,"flag":1198},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_2":{"address":1998566,"default_item":143,"flag":1199},"POKEDEX_REWARD_001":{"address":5729368,"default_item":3,"flag":0},"POKEDEX_REWARD_002":{"address":5729370,"default_item":3,"flag":0},"POKEDEX_REWARD_003":{"address":5729372,"default_item":3,"flag":0},"POKEDEX_REWARD_004":{"address":5729374,"default_item":3,"flag":0},"POKEDEX_REWARD_005":{"address":5729376,"default_item":3,"flag":0},"POKEDEX_REWARD_006":{"address":5729378,"default_item":3,"flag":0},"POKEDEX_REWARD_007":{"address":5729380,"default_item":3,"flag":0},"POKEDEX_REWARD_008":{"address":5729382,"default_item":3,"flag":0},"POKEDEX_REWARD_009":{"address":5729384,"default_item":3,"flag":0},"POKEDEX_REWARD_010":{"address":5729386,"default_item":3,"flag":0},"POKEDEX_REWARD_011":{"address":5729388,"default_item":3,"flag":0},"POKEDEX_REWARD_012":{"address":5729390,"default_item":3,"flag":0},"POKEDEX_REWARD_013":{"address":5729392,"default_item":3,"flag":0},"POKEDEX_REWARD_014":{"address":5729394,"default_item":3,"flag":0},"POKEDEX_REWARD_015":{"address":5729396,"default_item":3,"flag":0},"POKEDEX_REWARD_016":{"address":5729398,"default_item":3,"flag":0},"POKEDEX_REWARD_017":{"address":5729400,"default_item":3,"flag":0},"POKEDEX_REWARD_018":{"address":5729402,"default_item":3,"flag":0},"POKEDEX_REWARD_019":{"address":5729404,"default_item":3,"flag":0},"POKEDEX_REWARD_020":{"address":5729406,"default_item":3,"flag":0},"POKEDEX_REWARD_021":{"address":5729408,"default_item":3,"flag":0},"POKEDEX_REWARD_022":{"address":5729410,"default_item":3,"flag":0},"POKEDEX_REWARD_023":{"address":5729412,"default_item":3,"flag":0},"POKEDEX_REWARD_024":{"address":5729414,"default_item":3,"flag":0},"POKEDEX_REWARD_025":{"address":5729416,"default_item":3,"flag":0},"POKEDEX_REWARD_026":{"address":5729418,"default_item":3,"flag":0},"POKEDEX_REWARD_027":{"address":5729420,"default_item":3,"flag":0},"POKEDEX_REWARD_028":{"address":5729422,"default_item":3,"flag":0},"POKEDEX_REWARD_029":{"address":5729424,"default_item":3,"flag":0},"POKEDEX_REWARD_030":{"address":5729426,"default_item":3,"flag":0},"POKEDEX_REWARD_031":{"address":5729428,"default_item":3,"flag":0},"POKEDEX_REWARD_032":{"address":5729430,"default_item":3,"flag":0},"POKEDEX_REWARD_033":{"address":5729432,"default_item":3,"flag":0},"POKEDEX_REWARD_034":{"address":5729434,"default_item":3,"flag":0},"POKEDEX_REWARD_035":{"address":5729436,"default_item":3,"flag":0},"POKEDEX_REWARD_036":{"address":5729438,"default_item":3,"flag":0},"POKEDEX_REWARD_037":{"address":5729440,"default_item":3,"flag":0},"POKEDEX_REWARD_038":{"address":5729442,"default_item":3,"flag":0},"POKEDEX_REWARD_039":{"address":5729444,"default_item":3,"flag":0},"POKEDEX_REWARD_040":{"address":5729446,"default_item":3,"flag":0},"POKEDEX_REWARD_041":{"address":5729448,"default_item":3,"flag":0},"POKEDEX_REWARD_042":{"address":5729450,"default_item":3,"flag":0},"POKEDEX_REWARD_043":{"address":5729452,"default_item":3,"flag":0},"POKEDEX_REWARD_044":{"address":5729454,"default_item":3,"flag":0},"POKEDEX_REWARD_045":{"address":5729456,"default_item":3,"flag":0},"POKEDEX_REWARD_046":{"address":5729458,"default_item":3,"flag":0},"POKEDEX_REWARD_047":{"address":5729460,"default_item":3,"flag":0},"POKEDEX_REWARD_048":{"address":5729462,"default_item":3,"flag":0},"POKEDEX_REWARD_049":{"address":5729464,"default_item":3,"flag":0},"POKEDEX_REWARD_050":{"address":5729466,"default_item":3,"flag":0},"POKEDEX_REWARD_051":{"address":5729468,"default_item":3,"flag":0},"POKEDEX_REWARD_052":{"address":5729470,"default_item":3,"flag":0},"POKEDEX_REWARD_053":{"address":5729472,"default_item":3,"flag":0},"POKEDEX_REWARD_054":{"address":5729474,"default_item":3,"flag":0},"POKEDEX_REWARD_055":{"address":5729476,"default_item":3,"flag":0},"POKEDEX_REWARD_056":{"address":5729478,"default_item":3,"flag":0},"POKEDEX_REWARD_057":{"address":5729480,"default_item":3,"flag":0},"POKEDEX_REWARD_058":{"address":5729482,"default_item":3,"flag":0},"POKEDEX_REWARD_059":{"address":5729484,"default_item":3,"flag":0},"POKEDEX_REWARD_060":{"address":5729486,"default_item":3,"flag":0},"POKEDEX_REWARD_061":{"address":5729488,"default_item":3,"flag":0},"POKEDEX_REWARD_062":{"address":5729490,"default_item":3,"flag":0},"POKEDEX_REWARD_063":{"address":5729492,"default_item":3,"flag":0},"POKEDEX_REWARD_064":{"address":5729494,"default_item":3,"flag":0},"POKEDEX_REWARD_065":{"address":5729496,"default_item":3,"flag":0},"POKEDEX_REWARD_066":{"address":5729498,"default_item":3,"flag":0},"POKEDEX_REWARD_067":{"address":5729500,"default_item":3,"flag":0},"POKEDEX_REWARD_068":{"address":5729502,"default_item":3,"flag":0},"POKEDEX_REWARD_069":{"address":5729504,"default_item":3,"flag":0},"POKEDEX_REWARD_070":{"address":5729506,"default_item":3,"flag":0},"POKEDEX_REWARD_071":{"address":5729508,"default_item":3,"flag":0},"POKEDEX_REWARD_072":{"address":5729510,"default_item":3,"flag":0},"POKEDEX_REWARD_073":{"address":5729512,"default_item":3,"flag":0},"POKEDEX_REWARD_074":{"address":5729514,"default_item":3,"flag":0},"POKEDEX_REWARD_075":{"address":5729516,"default_item":3,"flag":0},"POKEDEX_REWARD_076":{"address":5729518,"default_item":3,"flag":0},"POKEDEX_REWARD_077":{"address":5729520,"default_item":3,"flag":0},"POKEDEX_REWARD_078":{"address":5729522,"default_item":3,"flag":0},"POKEDEX_REWARD_079":{"address":5729524,"default_item":3,"flag":0},"POKEDEX_REWARD_080":{"address":5729526,"default_item":3,"flag":0},"POKEDEX_REWARD_081":{"address":5729528,"default_item":3,"flag":0},"POKEDEX_REWARD_082":{"address":5729530,"default_item":3,"flag":0},"POKEDEX_REWARD_083":{"address":5729532,"default_item":3,"flag":0},"POKEDEX_REWARD_084":{"address":5729534,"default_item":3,"flag":0},"POKEDEX_REWARD_085":{"address":5729536,"default_item":3,"flag":0},"POKEDEX_REWARD_086":{"address":5729538,"default_item":3,"flag":0},"POKEDEX_REWARD_087":{"address":5729540,"default_item":3,"flag":0},"POKEDEX_REWARD_088":{"address":5729542,"default_item":3,"flag":0},"POKEDEX_REWARD_089":{"address":5729544,"default_item":3,"flag":0},"POKEDEX_REWARD_090":{"address":5729546,"default_item":3,"flag":0},"POKEDEX_REWARD_091":{"address":5729548,"default_item":3,"flag":0},"POKEDEX_REWARD_092":{"address":5729550,"default_item":3,"flag":0},"POKEDEX_REWARD_093":{"address":5729552,"default_item":3,"flag":0},"POKEDEX_REWARD_094":{"address":5729554,"default_item":3,"flag":0},"POKEDEX_REWARD_095":{"address":5729556,"default_item":3,"flag":0},"POKEDEX_REWARD_096":{"address":5729558,"default_item":3,"flag":0},"POKEDEX_REWARD_097":{"address":5729560,"default_item":3,"flag":0},"POKEDEX_REWARD_098":{"address":5729562,"default_item":3,"flag":0},"POKEDEX_REWARD_099":{"address":5729564,"default_item":3,"flag":0},"POKEDEX_REWARD_100":{"address":5729566,"default_item":3,"flag":0},"POKEDEX_REWARD_101":{"address":5729568,"default_item":3,"flag":0},"POKEDEX_REWARD_102":{"address":5729570,"default_item":3,"flag":0},"POKEDEX_REWARD_103":{"address":5729572,"default_item":3,"flag":0},"POKEDEX_REWARD_104":{"address":5729574,"default_item":3,"flag":0},"POKEDEX_REWARD_105":{"address":5729576,"default_item":3,"flag":0},"POKEDEX_REWARD_106":{"address":5729578,"default_item":3,"flag":0},"POKEDEX_REWARD_107":{"address":5729580,"default_item":3,"flag":0},"POKEDEX_REWARD_108":{"address":5729582,"default_item":3,"flag":0},"POKEDEX_REWARD_109":{"address":5729584,"default_item":3,"flag":0},"POKEDEX_REWARD_110":{"address":5729586,"default_item":3,"flag":0},"POKEDEX_REWARD_111":{"address":5729588,"default_item":3,"flag":0},"POKEDEX_REWARD_112":{"address":5729590,"default_item":3,"flag":0},"POKEDEX_REWARD_113":{"address":5729592,"default_item":3,"flag":0},"POKEDEX_REWARD_114":{"address":5729594,"default_item":3,"flag":0},"POKEDEX_REWARD_115":{"address":5729596,"default_item":3,"flag":0},"POKEDEX_REWARD_116":{"address":5729598,"default_item":3,"flag":0},"POKEDEX_REWARD_117":{"address":5729600,"default_item":3,"flag":0},"POKEDEX_REWARD_118":{"address":5729602,"default_item":3,"flag":0},"POKEDEX_REWARD_119":{"address":5729604,"default_item":3,"flag":0},"POKEDEX_REWARD_120":{"address":5729606,"default_item":3,"flag":0},"POKEDEX_REWARD_121":{"address":5729608,"default_item":3,"flag":0},"POKEDEX_REWARD_122":{"address":5729610,"default_item":3,"flag":0},"POKEDEX_REWARD_123":{"address":5729612,"default_item":3,"flag":0},"POKEDEX_REWARD_124":{"address":5729614,"default_item":3,"flag":0},"POKEDEX_REWARD_125":{"address":5729616,"default_item":3,"flag":0},"POKEDEX_REWARD_126":{"address":5729618,"default_item":3,"flag":0},"POKEDEX_REWARD_127":{"address":5729620,"default_item":3,"flag":0},"POKEDEX_REWARD_128":{"address":5729622,"default_item":3,"flag":0},"POKEDEX_REWARD_129":{"address":5729624,"default_item":3,"flag":0},"POKEDEX_REWARD_130":{"address":5729626,"default_item":3,"flag":0},"POKEDEX_REWARD_131":{"address":5729628,"default_item":3,"flag":0},"POKEDEX_REWARD_132":{"address":5729630,"default_item":3,"flag":0},"POKEDEX_REWARD_133":{"address":5729632,"default_item":3,"flag":0},"POKEDEX_REWARD_134":{"address":5729634,"default_item":3,"flag":0},"POKEDEX_REWARD_135":{"address":5729636,"default_item":3,"flag":0},"POKEDEX_REWARD_136":{"address":5729638,"default_item":3,"flag":0},"POKEDEX_REWARD_137":{"address":5729640,"default_item":3,"flag":0},"POKEDEX_REWARD_138":{"address":5729642,"default_item":3,"flag":0},"POKEDEX_REWARD_139":{"address":5729644,"default_item":3,"flag":0},"POKEDEX_REWARD_140":{"address":5729646,"default_item":3,"flag":0},"POKEDEX_REWARD_141":{"address":5729648,"default_item":3,"flag":0},"POKEDEX_REWARD_142":{"address":5729650,"default_item":3,"flag":0},"POKEDEX_REWARD_143":{"address":5729652,"default_item":3,"flag":0},"POKEDEX_REWARD_144":{"address":5729654,"default_item":3,"flag":0},"POKEDEX_REWARD_145":{"address":5729656,"default_item":3,"flag":0},"POKEDEX_REWARD_146":{"address":5729658,"default_item":3,"flag":0},"POKEDEX_REWARD_147":{"address":5729660,"default_item":3,"flag":0},"POKEDEX_REWARD_148":{"address":5729662,"default_item":3,"flag":0},"POKEDEX_REWARD_149":{"address":5729664,"default_item":3,"flag":0},"POKEDEX_REWARD_150":{"address":5729666,"default_item":3,"flag":0},"POKEDEX_REWARD_151":{"address":5729668,"default_item":3,"flag":0},"POKEDEX_REWARD_152":{"address":5729670,"default_item":3,"flag":0},"POKEDEX_REWARD_153":{"address":5729672,"default_item":3,"flag":0},"POKEDEX_REWARD_154":{"address":5729674,"default_item":3,"flag":0},"POKEDEX_REWARD_155":{"address":5729676,"default_item":3,"flag":0},"POKEDEX_REWARD_156":{"address":5729678,"default_item":3,"flag":0},"POKEDEX_REWARD_157":{"address":5729680,"default_item":3,"flag":0},"POKEDEX_REWARD_158":{"address":5729682,"default_item":3,"flag":0},"POKEDEX_REWARD_159":{"address":5729684,"default_item":3,"flag":0},"POKEDEX_REWARD_160":{"address":5729686,"default_item":3,"flag":0},"POKEDEX_REWARD_161":{"address":5729688,"default_item":3,"flag":0},"POKEDEX_REWARD_162":{"address":5729690,"default_item":3,"flag":0},"POKEDEX_REWARD_163":{"address":5729692,"default_item":3,"flag":0},"POKEDEX_REWARD_164":{"address":5729694,"default_item":3,"flag":0},"POKEDEX_REWARD_165":{"address":5729696,"default_item":3,"flag":0},"POKEDEX_REWARD_166":{"address":5729698,"default_item":3,"flag":0},"POKEDEX_REWARD_167":{"address":5729700,"default_item":3,"flag":0},"POKEDEX_REWARD_168":{"address":5729702,"default_item":3,"flag":0},"POKEDEX_REWARD_169":{"address":5729704,"default_item":3,"flag":0},"POKEDEX_REWARD_170":{"address":5729706,"default_item":3,"flag":0},"POKEDEX_REWARD_171":{"address":5729708,"default_item":3,"flag":0},"POKEDEX_REWARD_172":{"address":5729710,"default_item":3,"flag":0},"POKEDEX_REWARD_173":{"address":5729712,"default_item":3,"flag":0},"POKEDEX_REWARD_174":{"address":5729714,"default_item":3,"flag":0},"POKEDEX_REWARD_175":{"address":5729716,"default_item":3,"flag":0},"POKEDEX_REWARD_176":{"address":5729718,"default_item":3,"flag":0},"POKEDEX_REWARD_177":{"address":5729720,"default_item":3,"flag":0},"POKEDEX_REWARD_178":{"address":5729722,"default_item":3,"flag":0},"POKEDEX_REWARD_179":{"address":5729724,"default_item":3,"flag":0},"POKEDEX_REWARD_180":{"address":5729726,"default_item":3,"flag":0},"POKEDEX_REWARD_181":{"address":5729728,"default_item":3,"flag":0},"POKEDEX_REWARD_182":{"address":5729730,"default_item":3,"flag":0},"POKEDEX_REWARD_183":{"address":5729732,"default_item":3,"flag":0},"POKEDEX_REWARD_184":{"address":5729734,"default_item":3,"flag":0},"POKEDEX_REWARD_185":{"address":5729736,"default_item":3,"flag":0},"POKEDEX_REWARD_186":{"address":5729738,"default_item":3,"flag":0},"POKEDEX_REWARD_187":{"address":5729740,"default_item":3,"flag":0},"POKEDEX_REWARD_188":{"address":5729742,"default_item":3,"flag":0},"POKEDEX_REWARD_189":{"address":5729744,"default_item":3,"flag":0},"POKEDEX_REWARD_190":{"address":5729746,"default_item":3,"flag":0},"POKEDEX_REWARD_191":{"address":5729748,"default_item":3,"flag":0},"POKEDEX_REWARD_192":{"address":5729750,"default_item":3,"flag":0},"POKEDEX_REWARD_193":{"address":5729752,"default_item":3,"flag":0},"POKEDEX_REWARD_194":{"address":5729754,"default_item":3,"flag":0},"POKEDEX_REWARD_195":{"address":5729756,"default_item":3,"flag":0},"POKEDEX_REWARD_196":{"address":5729758,"default_item":3,"flag":0},"POKEDEX_REWARD_197":{"address":5729760,"default_item":3,"flag":0},"POKEDEX_REWARD_198":{"address":5729762,"default_item":3,"flag":0},"POKEDEX_REWARD_199":{"address":5729764,"default_item":3,"flag":0},"POKEDEX_REWARD_200":{"address":5729766,"default_item":3,"flag":0},"POKEDEX_REWARD_201":{"address":5729768,"default_item":3,"flag":0},"POKEDEX_REWARD_202":{"address":5729770,"default_item":3,"flag":0},"POKEDEX_REWARD_203":{"address":5729772,"default_item":3,"flag":0},"POKEDEX_REWARD_204":{"address":5729774,"default_item":3,"flag":0},"POKEDEX_REWARD_205":{"address":5729776,"default_item":3,"flag":0},"POKEDEX_REWARD_206":{"address":5729778,"default_item":3,"flag":0},"POKEDEX_REWARD_207":{"address":5729780,"default_item":3,"flag":0},"POKEDEX_REWARD_208":{"address":5729782,"default_item":3,"flag":0},"POKEDEX_REWARD_209":{"address":5729784,"default_item":3,"flag":0},"POKEDEX_REWARD_210":{"address":5729786,"default_item":3,"flag":0},"POKEDEX_REWARD_211":{"address":5729788,"default_item":3,"flag":0},"POKEDEX_REWARD_212":{"address":5729790,"default_item":3,"flag":0},"POKEDEX_REWARD_213":{"address":5729792,"default_item":3,"flag":0},"POKEDEX_REWARD_214":{"address":5729794,"default_item":3,"flag":0},"POKEDEX_REWARD_215":{"address":5729796,"default_item":3,"flag":0},"POKEDEX_REWARD_216":{"address":5729798,"default_item":3,"flag":0},"POKEDEX_REWARD_217":{"address":5729800,"default_item":3,"flag":0},"POKEDEX_REWARD_218":{"address":5729802,"default_item":3,"flag":0},"POKEDEX_REWARD_219":{"address":5729804,"default_item":3,"flag":0},"POKEDEX_REWARD_220":{"address":5729806,"default_item":3,"flag":0},"POKEDEX_REWARD_221":{"address":5729808,"default_item":3,"flag":0},"POKEDEX_REWARD_222":{"address":5729810,"default_item":3,"flag":0},"POKEDEX_REWARD_223":{"address":5729812,"default_item":3,"flag":0},"POKEDEX_REWARD_224":{"address":5729814,"default_item":3,"flag":0},"POKEDEX_REWARD_225":{"address":5729816,"default_item":3,"flag":0},"POKEDEX_REWARD_226":{"address":5729818,"default_item":3,"flag":0},"POKEDEX_REWARD_227":{"address":5729820,"default_item":3,"flag":0},"POKEDEX_REWARD_228":{"address":5729822,"default_item":3,"flag":0},"POKEDEX_REWARD_229":{"address":5729824,"default_item":3,"flag":0},"POKEDEX_REWARD_230":{"address":5729826,"default_item":3,"flag":0},"POKEDEX_REWARD_231":{"address":5729828,"default_item":3,"flag":0},"POKEDEX_REWARD_232":{"address":5729830,"default_item":3,"flag":0},"POKEDEX_REWARD_233":{"address":5729832,"default_item":3,"flag":0},"POKEDEX_REWARD_234":{"address":5729834,"default_item":3,"flag":0},"POKEDEX_REWARD_235":{"address":5729836,"default_item":3,"flag":0},"POKEDEX_REWARD_236":{"address":5729838,"default_item":3,"flag":0},"POKEDEX_REWARD_237":{"address":5729840,"default_item":3,"flag":0},"POKEDEX_REWARD_238":{"address":5729842,"default_item":3,"flag":0},"POKEDEX_REWARD_239":{"address":5729844,"default_item":3,"flag":0},"POKEDEX_REWARD_240":{"address":5729846,"default_item":3,"flag":0},"POKEDEX_REWARD_241":{"address":5729848,"default_item":3,"flag":0},"POKEDEX_REWARD_242":{"address":5729850,"default_item":3,"flag":0},"POKEDEX_REWARD_243":{"address":5729852,"default_item":3,"flag":0},"POKEDEX_REWARD_244":{"address":5729854,"default_item":3,"flag":0},"POKEDEX_REWARD_245":{"address":5729856,"default_item":3,"flag":0},"POKEDEX_REWARD_246":{"address":5729858,"default_item":3,"flag":0},"POKEDEX_REWARD_247":{"address":5729860,"default_item":3,"flag":0},"POKEDEX_REWARD_248":{"address":5729862,"default_item":3,"flag":0},"POKEDEX_REWARD_249":{"address":5729864,"default_item":3,"flag":0},"POKEDEX_REWARD_250":{"address":5729866,"default_item":3,"flag":0},"POKEDEX_REWARD_251":{"address":5729868,"default_item":3,"flag":0},"POKEDEX_REWARD_252":{"address":5729870,"default_item":3,"flag":0},"POKEDEX_REWARD_253":{"address":5729872,"default_item":3,"flag":0},"POKEDEX_REWARD_254":{"address":5729874,"default_item":3,"flag":0},"POKEDEX_REWARD_255":{"address":5729876,"default_item":3,"flag":0},"POKEDEX_REWARD_256":{"address":5729878,"default_item":3,"flag":0},"POKEDEX_REWARD_257":{"address":5729880,"default_item":3,"flag":0},"POKEDEX_REWARD_258":{"address":5729882,"default_item":3,"flag":0},"POKEDEX_REWARD_259":{"address":5729884,"default_item":3,"flag":0},"POKEDEX_REWARD_260":{"address":5729886,"default_item":3,"flag":0},"POKEDEX_REWARD_261":{"address":5729888,"default_item":3,"flag":0},"POKEDEX_REWARD_262":{"address":5729890,"default_item":3,"flag":0},"POKEDEX_REWARD_263":{"address":5729892,"default_item":3,"flag":0},"POKEDEX_REWARD_264":{"address":5729894,"default_item":3,"flag":0},"POKEDEX_REWARD_265":{"address":5729896,"default_item":3,"flag":0},"POKEDEX_REWARD_266":{"address":5729898,"default_item":3,"flag":0},"POKEDEX_REWARD_267":{"address":5729900,"default_item":3,"flag":0},"POKEDEX_REWARD_268":{"address":5729902,"default_item":3,"flag":0},"POKEDEX_REWARD_269":{"address":5729904,"default_item":3,"flag":0},"POKEDEX_REWARD_270":{"address":5729906,"default_item":3,"flag":0},"POKEDEX_REWARD_271":{"address":5729908,"default_item":3,"flag":0},"POKEDEX_REWARD_272":{"address":5729910,"default_item":3,"flag":0},"POKEDEX_REWARD_273":{"address":5729912,"default_item":3,"flag":0},"POKEDEX_REWARD_274":{"address":5729914,"default_item":3,"flag":0},"POKEDEX_REWARD_275":{"address":5729916,"default_item":3,"flag":0},"POKEDEX_REWARD_276":{"address":5729918,"default_item":3,"flag":0},"POKEDEX_REWARD_277":{"address":5729920,"default_item":3,"flag":0},"POKEDEX_REWARD_278":{"address":5729922,"default_item":3,"flag":0},"POKEDEX_REWARD_279":{"address":5729924,"default_item":3,"flag":0},"POKEDEX_REWARD_280":{"address":5729926,"default_item":3,"flag":0},"POKEDEX_REWARD_281":{"address":5729928,"default_item":3,"flag":0},"POKEDEX_REWARD_282":{"address":5729930,"default_item":3,"flag":0},"POKEDEX_REWARD_283":{"address":5729932,"default_item":3,"flag":0},"POKEDEX_REWARD_284":{"address":5729934,"default_item":3,"flag":0},"POKEDEX_REWARD_285":{"address":5729936,"default_item":3,"flag":0},"POKEDEX_REWARD_286":{"address":5729938,"default_item":3,"flag":0},"POKEDEX_REWARD_287":{"address":5729940,"default_item":3,"flag":0},"POKEDEX_REWARD_288":{"address":5729942,"default_item":3,"flag":0},"POKEDEX_REWARD_289":{"address":5729944,"default_item":3,"flag":0},"POKEDEX_REWARD_290":{"address":5729946,"default_item":3,"flag":0},"POKEDEX_REWARD_291":{"address":5729948,"default_item":3,"flag":0},"POKEDEX_REWARD_292":{"address":5729950,"default_item":3,"flag":0},"POKEDEX_REWARD_293":{"address":5729952,"default_item":3,"flag":0},"POKEDEX_REWARD_294":{"address":5729954,"default_item":3,"flag":0},"POKEDEX_REWARD_295":{"address":5729956,"default_item":3,"flag":0},"POKEDEX_REWARD_296":{"address":5729958,"default_item":3,"flag":0},"POKEDEX_REWARD_297":{"address":5729960,"default_item":3,"flag":0},"POKEDEX_REWARD_298":{"address":5729962,"default_item":3,"flag":0},"POKEDEX_REWARD_299":{"address":5729964,"default_item":3,"flag":0},"POKEDEX_REWARD_300":{"address":5729966,"default_item":3,"flag":0},"POKEDEX_REWARD_301":{"address":5729968,"default_item":3,"flag":0},"POKEDEX_REWARD_302":{"address":5729970,"default_item":3,"flag":0},"POKEDEX_REWARD_303":{"address":5729972,"default_item":3,"flag":0},"POKEDEX_REWARD_304":{"address":5729974,"default_item":3,"flag":0},"POKEDEX_REWARD_305":{"address":5729976,"default_item":3,"flag":0},"POKEDEX_REWARD_306":{"address":5729978,"default_item":3,"flag":0},"POKEDEX_REWARD_307":{"address":5729980,"default_item":3,"flag":0},"POKEDEX_REWARD_308":{"address":5729982,"default_item":3,"flag":0},"POKEDEX_REWARD_309":{"address":5729984,"default_item":3,"flag":0},"POKEDEX_REWARD_310":{"address":5729986,"default_item":3,"flag":0},"POKEDEX_REWARD_311":{"address":5729988,"default_item":3,"flag":0},"POKEDEX_REWARD_312":{"address":5729990,"default_item":3,"flag":0},"POKEDEX_REWARD_313":{"address":5729992,"default_item":3,"flag":0},"POKEDEX_REWARD_314":{"address":5729994,"default_item":3,"flag":0},"POKEDEX_REWARD_315":{"address":5729996,"default_item":3,"flag":0},"POKEDEX_REWARD_316":{"address":5729998,"default_item":3,"flag":0},"POKEDEX_REWARD_317":{"address":5730000,"default_item":3,"flag":0},"POKEDEX_REWARD_318":{"address":5730002,"default_item":3,"flag":0},"POKEDEX_REWARD_319":{"address":5730004,"default_item":3,"flag":0},"POKEDEX_REWARD_320":{"address":5730006,"default_item":3,"flag":0},"POKEDEX_REWARD_321":{"address":5730008,"default_item":3,"flag":0},"POKEDEX_REWARD_322":{"address":5730010,"default_item":3,"flag":0},"POKEDEX_REWARD_323":{"address":5730012,"default_item":3,"flag":0},"POKEDEX_REWARD_324":{"address":5730014,"default_item":3,"flag":0},"POKEDEX_REWARD_325":{"address":5730016,"default_item":3,"flag":0},"POKEDEX_REWARD_326":{"address":5730018,"default_item":3,"flag":0},"POKEDEX_REWARD_327":{"address":5730020,"default_item":3,"flag":0},"POKEDEX_REWARD_328":{"address":5730022,"default_item":3,"flag":0},"POKEDEX_REWARD_329":{"address":5730024,"default_item":3,"flag":0},"POKEDEX_REWARD_330":{"address":5730026,"default_item":3,"flag":0},"POKEDEX_REWARD_331":{"address":5730028,"default_item":3,"flag":0},"POKEDEX_REWARD_332":{"address":5730030,"default_item":3,"flag":0},"POKEDEX_REWARD_333":{"address":5730032,"default_item":3,"flag":0},"POKEDEX_REWARD_334":{"address":5730034,"default_item":3,"flag":0},"POKEDEX_REWARD_335":{"address":5730036,"default_item":3,"flag":0},"POKEDEX_REWARD_336":{"address":5730038,"default_item":3,"flag":0},"POKEDEX_REWARD_337":{"address":5730040,"default_item":3,"flag":0},"POKEDEX_REWARD_338":{"address":5730042,"default_item":3,"flag":0},"POKEDEX_REWARD_339":{"address":5730044,"default_item":3,"flag":0},"POKEDEX_REWARD_340":{"address":5730046,"default_item":3,"flag":0},"POKEDEX_REWARD_341":{"address":5730048,"default_item":3,"flag":0},"POKEDEX_REWARD_342":{"address":5730050,"default_item":3,"flag":0},"POKEDEX_REWARD_343":{"address":5730052,"default_item":3,"flag":0},"POKEDEX_REWARD_344":{"address":5730054,"default_item":3,"flag":0},"POKEDEX_REWARD_345":{"address":5730056,"default_item":3,"flag":0},"POKEDEX_REWARD_346":{"address":5730058,"default_item":3,"flag":0},"POKEDEX_REWARD_347":{"address":5730060,"default_item":3,"flag":0},"POKEDEX_REWARD_348":{"address":5730062,"default_item":3,"flag":0},"POKEDEX_REWARD_349":{"address":5730064,"default_item":3,"flag":0},"POKEDEX_REWARD_350":{"address":5730066,"default_item":3,"flag":0},"POKEDEX_REWARD_351":{"address":5730068,"default_item":3,"flag":0},"POKEDEX_REWARD_352":{"address":5730070,"default_item":3,"flag":0},"POKEDEX_REWARD_353":{"address":5730072,"default_item":3,"flag":0},"POKEDEX_REWARD_354":{"address":5730074,"default_item":3,"flag":0},"POKEDEX_REWARD_355":{"address":5730076,"default_item":3,"flag":0},"POKEDEX_REWARD_356":{"address":5730078,"default_item":3,"flag":0},"POKEDEX_REWARD_357":{"address":5730080,"default_item":3,"flag":0},"POKEDEX_REWARD_358":{"address":5730082,"default_item":3,"flag":0},"POKEDEX_REWARD_359":{"address":5730084,"default_item":3,"flag":0},"POKEDEX_REWARD_360":{"address":5730086,"default_item":3,"flag":0},"POKEDEX_REWARD_361":{"address":5730088,"default_item":3,"flag":0},"POKEDEX_REWARD_362":{"address":5730090,"default_item":3,"flag":0},"POKEDEX_REWARD_363":{"address":5730092,"default_item":3,"flag":0},"POKEDEX_REWARD_364":{"address":5730094,"default_item":3,"flag":0},"POKEDEX_REWARD_365":{"address":5730096,"default_item":3,"flag":0},"POKEDEX_REWARD_366":{"address":5730098,"default_item":3,"flag":0},"POKEDEX_REWARD_367":{"address":5730100,"default_item":3,"flag":0},"POKEDEX_REWARD_368":{"address":5730102,"default_item":3,"flag":0},"POKEDEX_REWARD_369":{"address":5730104,"default_item":3,"flag":0},"POKEDEX_REWARD_370":{"address":5730106,"default_item":3,"flag":0},"POKEDEX_REWARD_371":{"address":5730108,"default_item":3,"flag":0},"POKEDEX_REWARD_372":{"address":5730110,"default_item":3,"flag":0},"POKEDEX_REWARD_373":{"address":5730112,"default_item":3,"flag":0},"POKEDEX_REWARD_374":{"address":5730114,"default_item":3,"flag":0},"POKEDEX_REWARD_375":{"address":5730116,"default_item":3,"flag":0},"POKEDEX_REWARD_376":{"address":5730118,"default_item":3,"flag":0},"POKEDEX_REWARD_377":{"address":5730120,"default_item":3,"flag":0},"POKEDEX_REWARD_378":{"address":5730122,"default_item":3,"flag":0},"POKEDEX_REWARD_379":{"address":5730124,"default_item":3,"flag":0},"POKEDEX_REWARD_380":{"address":5730126,"default_item":3,"flag":0},"POKEDEX_REWARD_381":{"address":5730128,"default_item":3,"flag":0},"POKEDEX_REWARD_382":{"address":5730130,"default_item":3,"flag":0},"POKEDEX_REWARD_383":{"address":5730132,"default_item":3,"flag":0},"POKEDEX_REWARD_384":{"address":5730134,"default_item":3,"flag":0},"POKEDEX_REWARD_385":{"address":5730136,"default_item":3,"flag":0},"POKEDEX_REWARD_386":{"address":5730138,"default_item":3,"flag":0},"TRAINER_AARON_REWARD":{"address":5602878,"default_item":104,"flag":1677},"TRAINER_ABIGAIL_1_REWARD":{"address":5602800,"default_item":106,"flag":1638},"TRAINER_AIDAN_REWARD":{"address":5603432,"default_item":104,"flag":1954},"TRAINER_AISHA_REWARD":{"address":5603598,"default_item":106,"flag":2037},"TRAINER_ALBERTO_REWARD":{"address":5602108,"default_item":108,"flag":1292},"TRAINER_ALBERT_REWARD":{"address":5602244,"default_item":104,"flag":1360},"TRAINER_ALEXA_REWARD":{"address":5603424,"default_item":104,"flag":1950},"TRAINER_ALEXIA_REWARD":{"address":5602264,"default_item":104,"flag":1370},"TRAINER_ALEX_REWARD":{"address":5602910,"default_item":104,"flag":1693},"TRAINER_ALICE_REWARD":{"address":5602980,"default_item":103,"flag":1728},"TRAINER_ALIX_REWARD":{"address":5603584,"default_item":106,"flag":2030},"TRAINER_ALLEN_REWARD":{"address":5602750,"default_item":103,"flag":1613},"TRAINER_ALLISON_REWARD":{"address":5602858,"default_item":104,"flag":1667},"TRAINER_ALYSSA_REWARD":{"address":5603486,"default_item":106,"flag":1981},"TRAINER_AMY_AND_LIV_1_REWARD":{"address":5603046,"default_item":103,"flag":1761},"TRAINER_ANDREA_REWARD":{"address":5603310,"default_item":106,"flag":1893},"TRAINER_ANDRES_1_REWARD":{"address":5603558,"default_item":104,"flag":2017},"TRAINER_ANDREW_REWARD":{"address":5602756,"default_item":106,"flag":1616},"TRAINER_ANGELICA_REWARD":{"address":5602956,"default_item":104,"flag":1716},"TRAINER_ANGELINA_REWARD":{"address":5603508,"default_item":106,"flag":1992},"TRAINER_ANGELO_REWARD":{"address":5603688,"default_item":104,"flag":2082},"TRAINER_ANNA_AND_MEG_1_REWARD":{"address":5602658,"default_item":106,"flag":1567},"TRAINER_ANNIKA_REWARD":{"address":5603088,"default_item":107,"flag":1782},"TRAINER_ANTHONY_REWARD":{"address":5602788,"default_item":106,"flag":1632},"TRAINER_ARCHIE_REWARD":{"address":5602152,"default_item":107,"flag":1314},"TRAINER_ASHLEY_REWARD":{"address":5603394,"default_item":106,"flag":1935},"TRAINER_ATHENA_REWARD":{"address":5603238,"default_item":104,"flag":1857},"TRAINER_ATSUSHI_REWARD":{"address":5602464,"default_item":104,"flag":1470},"TRAINER_AURON_REWARD":{"address":5603096,"default_item":104,"flag":1786},"TRAINER_AUSTINA_REWARD":{"address":5602200,"default_item":103,"flag":1338},"TRAINER_AUTUMN_REWARD":{"address":5602518,"default_item":106,"flag":1497},"TRAINER_AXLE_REWARD":{"address":5602490,"default_item":108,"flag":1483},"TRAINER_BARNY_REWARD":{"address":5602770,"default_item":104,"flag":1623},"TRAINER_BARRY_REWARD":{"address":5602410,"default_item":106,"flag":1443},"TRAINER_BEAU_REWARD":{"address":5602508,"default_item":106,"flag":1492},"TRAINER_BECKY_REWARD":{"address":5603024,"default_item":106,"flag":1750},"TRAINER_BECK_REWARD":{"address":5602912,"default_item":104,"flag":1694},"TRAINER_BENJAMIN_1_REWARD":{"address":5602790,"default_item":106,"flag":1633},"TRAINER_BEN_REWARD":{"address":5602730,"default_item":106,"flag":1603},"TRAINER_BERKE_REWARD":{"address":5602232,"default_item":104,"flag":1354},"TRAINER_BERNIE_1_REWARD":{"address":5602496,"default_item":106,"flag":1486},"TRAINER_BETHANY_REWARD":{"address":5602686,"default_item":107,"flag":1581},"TRAINER_BETH_REWARD":{"address":5602974,"default_item":103,"flag":1725},"TRAINER_BEVERLY_REWARD":{"address":5602966,"default_item":103,"flag":1721},"TRAINER_BIANCA_REWARD":{"address":5603496,"default_item":106,"flag":1986},"TRAINER_BILLY_REWARD":{"address":5602722,"default_item":103,"flag":1599},"TRAINER_BLAKE_REWARD":{"address":5602554,"default_item":108,"flag":1515},"TRAINER_BRANDEN_REWARD":{"address":5603574,"default_item":106,"flag":2025},"TRAINER_BRANDI_REWARD":{"address":5603596,"default_item":106,"flag":2036},"TRAINER_BRAWLY_1_REWARD":{"address":5602616,"default_item":104,"flag":1546},"TRAINER_BRAXTON_REWARD":{"address":5602234,"default_item":104,"flag":1355},"TRAINER_BRENDAN_LILYCOVE_MUDKIP_REWARD":{"address":5603406,"default_item":104,"flag":1941},"TRAINER_BRENDAN_LILYCOVE_TORCHIC_REWARD":{"address":5603410,"default_item":104,"flag":1943},"TRAINER_BRENDAN_LILYCOVE_TREECKO_REWARD":{"address":5603408,"default_item":104,"flag":1942},"TRAINER_BRENDAN_ROUTE_103_MUDKIP_REWARD":{"address":5603124,"default_item":106,"flag":1800},"TRAINER_BRENDAN_ROUTE_103_TORCHIC_REWARD":{"address":5603136,"default_item":106,"flag":1806},"TRAINER_BRENDAN_ROUTE_103_TREECKO_REWARD":{"address":5603130,"default_item":106,"flag":1803},"TRAINER_BRENDAN_ROUTE_110_MUDKIP_REWARD":{"address":5603126,"default_item":104,"flag":1801},"TRAINER_BRENDAN_ROUTE_110_TORCHIC_REWARD":{"address":5603138,"default_item":104,"flag":1807},"TRAINER_BRENDAN_ROUTE_110_TREECKO_REWARD":{"address":5603132,"default_item":104,"flag":1804},"TRAINER_BRENDAN_ROUTE_119_MUDKIP_REWARD":{"address":5603128,"default_item":104,"flag":1802},"TRAINER_BRENDAN_ROUTE_119_TORCHIC_REWARD":{"address":5603140,"default_item":104,"flag":1808},"TRAINER_BRENDAN_ROUTE_119_TREECKO_REWARD":{"address":5603134,"default_item":104,"flag":1805},"TRAINER_BRENDAN_RUSTBORO_MUDKIP_REWARD":{"address":5603270,"default_item":108,"flag":1873},"TRAINER_BRENDAN_RUSTBORO_TORCHIC_REWARD":{"address":5603282,"default_item":108,"flag":1879},"TRAINER_BRENDAN_RUSTBORO_TREECKO_REWARD":{"address":5603268,"default_item":108,"flag":1872},"TRAINER_BRENDA_REWARD":{"address":5602992,"default_item":106,"flag":1734},"TRAINER_BRENDEN_REWARD":{"address":5603228,"default_item":106,"flag":1852},"TRAINER_BRENT_REWARD":{"address":5602530,"default_item":104,"flag":1503},"TRAINER_BRIANNA_REWARD":{"address":5602320,"default_item":110,"flag":1398},"TRAINER_BRICE_REWARD":{"address":5603336,"default_item":106,"flag":1906},"TRAINER_BRIDGET_REWARD":{"address":5602342,"default_item":107,"flag":1409},"TRAINER_BROOKE_1_REWARD":{"address":5602272,"default_item":108,"flag":1374},"TRAINER_BRYANT_REWARD":{"address":5603576,"default_item":106,"flag":2026},"TRAINER_BRYAN_REWARD":{"address":5603572,"default_item":104,"flag":2024},"TRAINER_CALE_REWARD":{"address":5603612,"default_item":104,"flag":2044},"TRAINER_CALLIE_REWARD":{"address":5603610,"default_item":106,"flag":2043},"TRAINER_CALVIN_1_REWARD":{"address":5602720,"default_item":103,"flag":1598},"TRAINER_CAMDEN_REWARD":{"address":5602832,"default_item":104,"flag":1654},"TRAINER_CAMERON_1_REWARD":{"address":5602560,"default_item":108,"flag":1518},"TRAINER_CAMRON_REWARD":{"address":5603562,"default_item":104,"flag":2019},"TRAINER_CARLEE_REWARD":{"address":5603012,"default_item":106,"flag":1744},"TRAINER_CAROLINA_REWARD":{"address":5603566,"default_item":104,"flag":2021},"TRAINER_CAROLINE_REWARD":{"address":5602282,"default_item":104,"flag":1379},"TRAINER_CAROL_REWARD":{"address":5603026,"default_item":106,"flag":1751},"TRAINER_CARTER_REWARD":{"address":5602774,"default_item":104,"flag":1625},"TRAINER_CATHERINE_1_REWARD":{"address":5603202,"default_item":104,"flag":1839},"TRAINER_CEDRIC_REWARD":{"address":5603034,"default_item":108,"flag":1755},"TRAINER_CELIA_REWARD":{"address":5603570,"default_item":106,"flag":2023},"TRAINER_CELINA_REWARD":{"address":5603494,"default_item":108,"flag":1985},"TRAINER_CHAD_REWARD":{"address":5602432,"default_item":106,"flag":1454},"TRAINER_CHANDLER_REWARD":{"address":5603480,"default_item":103,"flag":1978},"TRAINER_CHARLIE_REWARD":{"address":5602216,"default_item":103,"flag":1346},"TRAINER_CHARLOTTE_REWARD":{"address":5603512,"default_item":106,"flag":1994},"TRAINER_CHASE_REWARD":{"address":5602840,"default_item":104,"flag":1658},"TRAINER_CHESTER_REWARD":{"address":5602900,"default_item":108,"flag":1688},"TRAINER_CHIP_REWARD":{"address":5602174,"default_item":104,"flag":1325},"TRAINER_CHRIS_REWARD":{"address":5603470,"default_item":108,"flag":1973},"TRAINER_CINDY_1_REWARD":{"address":5602312,"default_item":104,"flag":1394},"TRAINER_CLARENCE_REWARD":{"address":5603244,"default_item":106,"flag":1860},"TRAINER_CLARISSA_REWARD":{"address":5602954,"default_item":104,"flag":1715},"TRAINER_CLARK_REWARD":{"address":5603346,"default_item":106,"flag":1911},"TRAINER_CLAUDE_REWARD":{"address":5602760,"default_item":108,"flag":1618},"TRAINER_CLIFFORD_REWARD":{"address":5603252,"default_item":107,"flag":1864},"TRAINER_COBY_REWARD":{"address":5603502,"default_item":106,"flag":1989},"TRAINER_COLE_REWARD":{"address":5602486,"default_item":108,"flag":1481},"TRAINER_COLIN_REWARD":{"address":5602894,"default_item":108,"flag":1685},"TRAINER_COLTON_REWARD":{"address":5602672,"default_item":107,"flag":1574},"TRAINER_CONNIE_REWARD":{"address":5602340,"default_item":107,"flag":1408},"TRAINER_CONOR_REWARD":{"address":5603106,"default_item":104,"flag":1791},"TRAINER_CORY_1_REWARD":{"address":5603564,"default_item":108,"flag":2020},"TRAINER_CRISSY_REWARD":{"address":5603312,"default_item":106,"flag":1894},"TRAINER_CRISTIAN_REWARD":{"address":5603232,"default_item":106,"flag":1854},"TRAINER_CRISTIN_1_REWARD":{"address":5603618,"default_item":104,"flag":2047},"TRAINER_CYNDY_1_REWARD":{"address":5602938,"default_item":106,"flag":1707},"TRAINER_DAISUKE_REWARD":{"address":5602462,"default_item":106,"flag":1469},"TRAINER_DAISY_REWARD":{"address":5602156,"default_item":106,"flag":1316},"TRAINER_DALE_REWARD":{"address":5602766,"default_item":106,"flag":1621},"TRAINER_DALTON_1_REWARD":{"address":5602476,"default_item":106,"flag":1476},"TRAINER_DANA_REWARD":{"address":5603000,"default_item":106,"flag":1738},"TRAINER_DANIELLE_REWARD":{"address":5603384,"default_item":106,"flag":1930},"TRAINER_DAPHNE_REWARD":{"address":5602314,"default_item":110,"flag":1395},"TRAINER_DARCY_REWARD":{"address":5603550,"default_item":104,"flag":2013},"TRAINER_DARIAN_REWARD":{"address":5603476,"default_item":106,"flag":1976},"TRAINER_DARIUS_REWARD":{"address":5603690,"default_item":108,"flag":2083},"TRAINER_DARRIN_REWARD":{"address":5602392,"default_item":103,"flag":1434},"TRAINER_DAVID_REWARD":{"address":5602400,"default_item":103,"flag":1438},"TRAINER_DAVIS_REWARD":{"address":5603162,"default_item":106,"flag":1819},"TRAINER_DAWSON_REWARD":{"address":5603472,"default_item":104,"flag":1974},"TRAINER_DAYTON_REWARD":{"address":5603604,"default_item":108,"flag":2040},"TRAINER_DEANDRE_REWARD":{"address":5603514,"default_item":103,"flag":1995},"TRAINER_DEAN_REWARD":{"address":5602412,"default_item":103,"flag":1444},"TRAINER_DEBRA_REWARD":{"address":5603004,"default_item":106,"flag":1740},"TRAINER_DECLAN_REWARD":{"address":5602114,"default_item":106,"flag":1295},"TRAINER_DEMETRIUS_REWARD":{"address":5602834,"default_item":106,"flag":1655},"TRAINER_DENISE_REWARD":{"address":5602972,"default_item":103,"flag":1724},"TRAINER_DEREK_REWARD":{"address":5602538,"default_item":108,"flag":1507},"TRAINER_DEVAN_REWARD":{"address":5603590,"default_item":106,"flag":2033},"TRAINER_DEZ_AND_LUKE_REWARD":{"address":5603364,"default_item":108,"flag":1920},"TRAINER_DIANA_1_REWARD":{"address":5603032,"default_item":106,"flag":1754},"TRAINER_DIANNE_REWARD":{"address":5602918,"default_item":104,"flag":1697},"TRAINER_DILLON_REWARD":{"address":5602738,"default_item":106,"flag":1607},"TRAINER_DOMINIK_REWARD":{"address":5602388,"default_item":103,"flag":1432},"TRAINER_DONALD_REWARD":{"address":5602532,"default_item":104,"flag":1504},"TRAINER_DONNY_REWARD":{"address":5602852,"default_item":104,"flag":1664},"TRAINER_DOUGLAS_REWARD":{"address":5602390,"default_item":103,"flag":1433},"TRAINER_DOUG_REWARD":{"address":5603320,"default_item":106,"flag":1898},"TRAINER_DRAKE_REWARD":{"address":5602612,"default_item":110,"flag":1544},"TRAINER_DREW_REWARD":{"address":5602506,"default_item":106,"flag":1491},"TRAINER_DUNCAN_REWARD":{"address":5603076,"default_item":108,"flag":1776},"TRAINER_DUSTY_1_REWARD":{"address":5602172,"default_item":104,"flag":1324},"TRAINER_DWAYNE_REWARD":{"address":5603070,"default_item":106,"flag":1773},"TRAINER_DYLAN_1_REWARD":{"address":5602812,"default_item":106,"flag":1644},"TRAINER_EDGAR_REWARD":{"address":5602242,"default_item":104,"flag":1359},"TRAINER_EDMOND_REWARD":{"address":5603066,"default_item":106,"flag":1771},"TRAINER_EDWARDO_REWARD":{"address":5602892,"default_item":108,"flag":1684},"TRAINER_EDWARD_REWARD":{"address":5602548,"default_item":106,"flag":1512},"TRAINER_EDWIN_1_REWARD":{"address":5603108,"default_item":108,"flag":1792},"TRAINER_ED_REWARD":{"address":5602110,"default_item":104,"flag":1293},"TRAINER_ELIJAH_REWARD":{"address":5603568,"default_item":108,"flag":2022},"TRAINER_ELI_REWARD":{"address":5603086,"default_item":108,"flag":1781},"TRAINER_ELLIOT_1_REWARD":{"address":5602762,"default_item":106,"flag":1619},"TRAINER_ERIC_REWARD":{"address":5603348,"default_item":108,"flag":1912},"TRAINER_ERNEST_1_REWARD":{"address":5603068,"default_item":104,"flag":1772},"TRAINER_ETHAN_1_REWARD":{"address":5602516,"default_item":106,"flag":1496},"TRAINER_FABIAN_REWARD":{"address":5603602,"default_item":108,"flag":2039},"TRAINER_FELIX_REWARD":{"address":5602160,"default_item":104,"flag":1318},"TRAINER_FERNANDO_1_REWARD":{"address":5602474,"default_item":108,"flag":1475},"TRAINER_FLANNERY_1_REWARD":{"address":5602620,"default_item":107,"flag":1548},"TRAINER_FLINT_REWARD":{"address":5603392,"default_item":106,"flag":1934},"TRAINER_FOSTER_REWARD":{"address":5602176,"default_item":104,"flag":1326},"TRAINER_FRANKLIN_REWARD":{"address":5602424,"default_item":106,"flag":1450},"TRAINER_FREDRICK_REWARD":{"address":5602142,"default_item":104,"flag":1309},"TRAINER_GABRIELLE_1_REWARD":{"address":5602102,"default_item":104,"flag":1289},"TRAINER_GARRET_REWARD":{"address":5602360,"default_item":110,"flag":1418},"TRAINER_GARRISON_REWARD":{"address":5603178,"default_item":104,"flag":1827},"TRAINER_GEORGE_REWARD":{"address":5602230,"default_item":104,"flag":1353},"TRAINER_GERALD_REWARD":{"address":5603380,"default_item":104,"flag":1928},"TRAINER_GILBERT_REWARD":{"address":5602422,"default_item":106,"flag":1449},"TRAINER_GINA_AND_MIA_1_REWARD":{"address":5603050,"default_item":103,"flag":1763},"TRAINER_GLACIA_REWARD":{"address":5602610,"default_item":110,"flag":1543},"TRAINER_GRACE_REWARD":{"address":5602984,"default_item":106,"flag":1730},"TRAINER_GREG_REWARD":{"address":5603322,"default_item":106,"flag":1899},"TRAINER_GRUNT_AQUA_HIDEOUT_1_REWARD":{"address":5602088,"default_item":106,"flag":1282},"TRAINER_GRUNT_AQUA_HIDEOUT_2_REWARD":{"address":5602090,"default_item":106,"flag":1283},"TRAINER_GRUNT_AQUA_HIDEOUT_3_REWARD":{"address":5602092,"default_item":106,"flag":1284},"TRAINER_GRUNT_AQUA_HIDEOUT_4_REWARD":{"address":5602094,"default_item":106,"flag":1285},"TRAINER_GRUNT_AQUA_HIDEOUT_5_REWARD":{"address":5602138,"default_item":106,"flag":1307},"TRAINER_GRUNT_AQUA_HIDEOUT_6_REWARD":{"address":5602140,"default_item":106,"flag":1308},"TRAINER_GRUNT_AQUA_HIDEOUT_7_REWARD":{"address":5602468,"default_item":106,"flag":1472},"TRAINER_GRUNT_AQUA_HIDEOUT_8_REWARD":{"address":5602470,"default_item":106,"flag":1473},"TRAINER_GRUNT_MAGMA_HIDEOUT_10_REWARD":{"address":5603534,"default_item":106,"flag":2005},"TRAINER_GRUNT_MAGMA_HIDEOUT_11_REWARD":{"address":5603536,"default_item":106,"flag":2006},"TRAINER_GRUNT_MAGMA_HIDEOUT_12_REWARD":{"address":5603538,"default_item":106,"flag":2007},"TRAINER_GRUNT_MAGMA_HIDEOUT_13_REWARD":{"address":5603540,"default_item":106,"flag":2008},"TRAINER_GRUNT_MAGMA_HIDEOUT_14_REWARD":{"address":5603542,"default_item":106,"flag":2009},"TRAINER_GRUNT_MAGMA_HIDEOUT_15_REWARD":{"address":5603544,"default_item":106,"flag":2010},"TRAINER_GRUNT_MAGMA_HIDEOUT_16_REWARD":{"address":5603546,"default_item":106,"flag":2011},"TRAINER_GRUNT_MAGMA_HIDEOUT_1_REWARD":{"address":5603516,"default_item":106,"flag":1996},"TRAINER_GRUNT_MAGMA_HIDEOUT_2_REWARD":{"address":5603518,"default_item":106,"flag":1997},"TRAINER_GRUNT_MAGMA_HIDEOUT_3_REWARD":{"address":5603520,"default_item":106,"flag":1998},"TRAINER_GRUNT_MAGMA_HIDEOUT_4_REWARD":{"address":5603522,"default_item":106,"flag":1999},"TRAINER_GRUNT_MAGMA_HIDEOUT_5_REWARD":{"address":5603524,"default_item":106,"flag":2000},"TRAINER_GRUNT_MAGMA_HIDEOUT_6_REWARD":{"address":5603526,"default_item":106,"flag":2001},"TRAINER_GRUNT_MAGMA_HIDEOUT_7_REWARD":{"address":5603528,"default_item":106,"flag":2002},"TRAINER_GRUNT_MAGMA_HIDEOUT_8_REWARD":{"address":5603530,"default_item":106,"flag":2003},"TRAINER_GRUNT_MAGMA_HIDEOUT_9_REWARD":{"address":5603532,"default_item":106,"flag":2004},"TRAINER_GRUNT_MT_CHIMNEY_1_REWARD":{"address":5602376,"default_item":106,"flag":1426},"TRAINER_GRUNT_MT_CHIMNEY_2_REWARD":{"address":5603242,"default_item":106,"flag":1859},"TRAINER_GRUNT_MT_PYRE_1_REWARD":{"address":5602130,"default_item":106,"flag":1303},"TRAINER_GRUNT_MT_PYRE_2_REWARD":{"address":5602132,"default_item":106,"flag":1304},"TRAINER_GRUNT_MT_PYRE_3_REWARD":{"address":5602134,"default_item":106,"flag":1305},"TRAINER_GRUNT_MT_PYRE_4_REWARD":{"address":5603222,"default_item":106,"flag":1849},"TRAINER_GRUNT_MUSEUM_1_REWARD":{"address":5602124,"default_item":106,"flag":1300},"TRAINER_GRUNT_MUSEUM_2_REWARD":{"address":5602126,"default_item":106,"flag":1301},"TRAINER_GRUNT_PETALBURG_WOODS_REWARD":{"address":5602104,"default_item":103,"flag":1290},"TRAINER_GRUNT_RUSTURF_TUNNEL_REWARD":{"address":5602116,"default_item":103,"flag":1296},"TRAINER_GRUNT_SEAFLOOR_CAVERN_1_REWARD":{"address":5602096,"default_item":108,"flag":1286},"TRAINER_GRUNT_SEAFLOOR_CAVERN_2_REWARD":{"address":5602098,"default_item":108,"flag":1287},"TRAINER_GRUNT_SEAFLOOR_CAVERN_3_REWARD":{"address":5602100,"default_item":108,"flag":1288},"TRAINER_GRUNT_SEAFLOOR_CAVERN_4_REWARD":{"address":5602112,"default_item":108,"flag":1294},"TRAINER_GRUNT_SEAFLOOR_CAVERN_5_REWARD":{"address":5603218,"default_item":108,"flag":1847},"TRAINER_GRUNT_SPACE_CENTER_1_REWARD":{"address":5602128,"default_item":106,"flag":1302},"TRAINER_GRUNT_SPACE_CENTER_2_REWARD":{"address":5602316,"default_item":106,"flag":1396},"TRAINER_GRUNT_SPACE_CENTER_3_REWARD":{"address":5603256,"default_item":106,"flag":1866},"TRAINER_GRUNT_SPACE_CENTER_4_REWARD":{"address":5603258,"default_item":106,"flag":1867},"TRAINER_GRUNT_SPACE_CENTER_5_REWARD":{"address":5603260,"default_item":106,"flag":1868},"TRAINER_GRUNT_SPACE_CENTER_6_REWARD":{"address":5603262,"default_item":106,"flag":1869},"TRAINER_GRUNT_SPACE_CENTER_7_REWARD":{"address":5603264,"default_item":106,"flag":1870},"TRAINER_GRUNT_WEATHER_INST_1_REWARD":{"address":5602118,"default_item":106,"flag":1297},"TRAINER_GRUNT_WEATHER_INST_2_REWARD":{"address":5602120,"default_item":106,"flag":1298},"TRAINER_GRUNT_WEATHER_INST_3_REWARD":{"address":5602122,"default_item":106,"flag":1299},"TRAINER_GRUNT_WEATHER_INST_4_REWARD":{"address":5602136,"default_item":106,"flag":1306},"TRAINER_GRUNT_WEATHER_INST_5_REWARD":{"address":5603276,"default_item":106,"flag":1876},"TRAINER_GWEN_REWARD":{"address":5602202,"default_item":103,"flag":1339},"TRAINER_HAILEY_REWARD":{"address":5603478,"default_item":103,"flag":1977},"TRAINER_HALEY_1_REWARD":{"address":5603292,"default_item":103,"flag":1884},"TRAINER_HALLE_REWARD":{"address":5603176,"default_item":104,"flag":1826},"TRAINER_HANNAH_REWARD":{"address":5602572,"default_item":108,"flag":1524},"TRAINER_HARRISON_REWARD":{"address":5603240,"default_item":106,"flag":1858},"TRAINER_HAYDEN_REWARD":{"address":5603498,"default_item":106,"flag":1987},"TRAINER_HECTOR_REWARD":{"address":5603110,"default_item":104,"flag":1793},"TRAINER_HEIDI_REWARD":{"address":5603022,"default_item":106,"flag":1749},"TRAINER_HELENE_REWARD":{"address":5603586,"default_item":106,"flag":2031},"TRAINER_HENRY_REWARD":{"address":5603420,"default_item":104,"flag":1948},"TRAINER_HERMAN_REWARD":{"address":5602418,"default_item":106,"flag":1447},"TRAINER_HIDEO_REWARD":{"address":5603386,"default_item":106,"flag":1931},"TRAINER_HITOSHI_REWARD":{"address":5602444,"default_item":104,"flag":1460},"TRAINER_HOPE_REWARD":{"address":5602276,"default_item":104,"flag":1376},"TRAINER_HUDSON_REWARD":{"address":5603104,"default_item":104,"flag":1790},"TRAINER_HUEY_REWARD":{"address":5603064,"default_item":106,"flag":1770},"TRAINER_HUGH_REWARD":{"address":5602882,"default_item":108,"flag":1679},"TRAINER_HUMBERTO_REWARD":{"address":5602888,"default_item":108,"flag":1682},"TRAINER_IMANI_REWARD":{"address":5602968,"default_item":103,"flag":1722},"TRAINER_IRENE_REWARD":{"address":5603036,"default_item":106,"flag":1756},"TRAINER_ISAAC_1_REWARD":{"address":5603160,"default_item":106,"flag":1818},"TRAINER_ISABELLA_REWARD":{"address":5603274,"default_item":104,"flag":1875},"TRAINER_ISABELLE_REWARD":{"address":5603556,"default_item":103,"flag":2016},"TRAINER_ISABEL_1_REWARD":{"address":5602688,"default_item":104,"flag":1582},"TRAINER_ISAIAH_1_REWARD":{"address":5602836,"default_item":104,"flag":1656},"TRAINER_ISOBEL_REWARD":{"address":5602850,"default_item":104,"flag":1663},"TRAINER_IVAN_REWARD":{"address":5602758,"default_item":106,"flag":1617},"TRAINER_JACE_REWARD":{"address":5602492,"default_item":108,"flag":1484},"TRAINER_JACKI_1_REWARD":{"address":5602582,"default_item":108,"flag":1529},"TRAINER_JACKSON_1_REWARD":{"address":5603188,"default_item":104,"flag":1832},"TRAINER_JACK_REWARD":{"address":5602428,"default_item":106,"flag":1452},"TRAINER_JACLYN_REWARD":{"address":5602570,"default_item":106,"flag":1523},"TRAINER_JACOB_REWARD":{"address":5602786,"default_item":106,"flag":1631},"TRAINER_JAIDEN_REWARD":{"address":5603582,"default_item":106,"flag":2029},"TRAINER_JAMES_1_REWARD":{"address":5603326,"default_item":103,"flag":1901},"TRAINER_JANICE_REWARD":{"address":5603294,"default_item":103,"flag":1885},"TRAINER_JANI_REWARD":{"address":5602920,"default_item":103,"flag":1698},"TRAINER_JARED_REWARD":{"address":5602886,"default_item":108,"flag":1681},"TRAINER_JASMINE_REWARD":{"address":5602802,"default_item":103,"flag":1639},"TRAINER_JAYLEN_REWARD":{"address":5602736,"default_item":106,"flag":1606},"TRAINER_JAZMYN_REWARD":{"address":5603090,"default_item":106,"flag":1783},"TRAINER_JEFFREY_1_REWARD":{"address":5602536,"default_item":104,"flag":1506},"TRAINER_JEFF_REWARD":{"address":5602488,"default_item":108,"flag":1482},"TRAINER_JENNA_REWARD":{"address":5603204,"default_item":104,"flag":1840},"TRAINER_JENNIFER_REWARD":{"address":5602274,"default_item":104,"flag":1375},"TRAINER_JENNY_1_REWARD":{"address":5602982,"default_item":106,"flag":1729},"TRAINER_JEROME_REWARD":{"address":5602396,"default_item":103,"flag":1436},"TRAINER_JERRY_1_REWARD":{"address":5602630,"default_item":103,"flag":1553},"TRAINER_JESSICA_1_REWARD":{"address":5602338,"default_item":104,"flag":1407},"TRAINER_JOCELYN_REWARD":{"address":5602934,"default_item":106,"flag":1705},"TRAINER_JODY_REWARD":{"address":5602266,"default_item":104,"flag":1371},"TRAINER_JOEY_REWARD":{"address":5602728,"default_item":103,"flag":1602},"TRAINER_JOHANNA_REWARD":{"address":5603378,"default_item":104,"flag":1927},"TRAINER_JOHNSON_REWARD":{"address":5603592,"default_item":103,"flag":2034},"TRAINER_JOHN_AND_JAY_1_REWARD":{"address":5603446,"default_item":104,"flag":1961},"TRAINER_JONAH_REWARD":{"address":5603418,"default_item":104,"flag":1947},"TRAINER_JONAS_REWARD":{"address":5603092,"default_item":106,"flag":1784},"TRAINER_JONATHAN_REWARD":{"address":5603280,"default_item":104,"flag":1878},"TRAINER_JOSEPH_REWARD":{"address":5603484,"default_item":106,"flag":1980},"TRAINER_JOSE_REWARD":{"address":5603318,"default_item":103,"flag":1897},"TRAINER_JOSH_REWARD":{"address":5602724,"default_item":103,"flag":1600},"TRAINER_JOSUE_REWARD":{"address":5603560,"default_item":108,"flag":2018},"TRAINER_JUAN_1_REWARD":{"address":5602628,"default_item":109,"flag":1552},"TRAINER_JULIE_REWARD":{"address":5602284,"default_item":104,"flag":1380},"TRAINER_JULIO_REWARD":{"address":5603216,"default_item":108,"flag":1846},"TRAINER_KAI_REWARD":{"address":5603510,"default_item":108,"flag":1993},"TRAINER_KALEB_REWARD":{"address":5603482,"default_item":104,"flag":1979},"TRAINER_KARA_REWARD":{"address":5602998,"default_item":106,"flag":1737},"TRAINER_KAREN_1_REWARD":{"address":5602644,"default_item":103,"flag":1560},"TRAINER_KATELYNN_REWARD":{"address":5602734,"default_item":104,"flag":1605},"TRAINER_KATELYN_1_REWARD":{"address":5602856,"default_item":104,"flag":1666},"TRAINER_KATE_AND_JOY_REWARD":{"address":5602656,"default_item":106,"flag":1566},"TRAINER_KATHLEEN_REWARD":{"address":5603250,"default_item":108,"flag":1863},"TRAINER_KATIE_REWARD":{"address":5602994,"default_item":106,"flag":1735},"TRAINER_KAYLA_REWARD":{"address":5602578,"default_item":106,"flag":1527},"TRAINER_KAYLEY_REWARD":{"address":5603094,"default_item":104,"flag":1785},"TRAINER_KEEGAN_REWARD":{"address":5602494,"default_item":108,"flag":1485},"TRAINER_KEIGO_REWARD":{"address":5603388,"default_item":106,"flag":1932},"TRAINER_KELVIN_REWARD":{"address":5603098,"default_item":104,"flag":1787},"TRAINER_KENT_REWARD":{"address":5603324,"default_item":106,"flag":1900},"TRAINER_KEVIN_REWARD":{"address":5602426,"default_item":106,"flag":1451},"TRAINER_KIM_AND_IRIS_REWARD":{"address":5603440,"default_item":106,"flag":1958},"TRAINER_KINDRA_REWARD":{"address":5602296,"default_item":108,"flag":1386},"TRAINER_KIRA_AND_DAN_1_REWARD":{"address":5603368,"default_item":108,"flag":1922},"TRAINER_KIRK_REWARD":{"address":5602466,"default_item":106,"flag":1471},"TRAINER_KIYO_REWARD":{"address":5602446,"default_item":104,"flag":1461},"TRAINER_KOICHI_REWARD":{"address":5602448,"default_item":108,"flag":1462},"TRAINER_KOJI_1_REWARD":{"address":5603428,"default_item":104,"flag":1952},"TRAINER_KYLA_REWARD":{"address":5602970,"default_item":103,"flag":1723},"TRAINER_KYRA_REWARD":{"address":5603580,"default_item":104,"flag":2028},"TRAINER_LAO_1_REWARD":{"address":5602922,"default_item":103,"flag":1699},"TRAINER_LARRY_REWARD":{"address":5602510,"default_item":106,"flag":1493},"TRAINER_LAURA_REWARD":{"address":5602936,"default_item":106,"flag":1706},"TRAINER_LAUREL_REWARD":{"address":5603010,"default_item":106,"flag":1743},"TRAINER_LAWRENCE_REWARD":{"address":5603504,"default_item":106,"flag":1990},"TRAINER_LEAH_REWARD":{"address":5602154,"default_item":108,"flag":1315},"TRAINER_LEA_AND_JED_REWARD":{"address":5603366,"default_item":104,"flag":1921},"TRAINER_LENNY_REWARD":{"address":5603340,"default_item":108,"flag":1908},"TRAINER_LEONARDO_REWARD":{"address":5603236,"default_item":106,"flag":1856},"TRAINER_LEONARD_REWARD":{"address":5603074,"default_item":104,"flag":1775},"TRAINER_LEONEL_REWARD":{"address":5603608,"default_item":104,"flag":2042},"TRAINER_LILA_AND_ROY_1_REWARD":{"address":5603458,"default_item":106,"flag":1967},"TRAINER_LILITH_REWARD":{"address":5603230,"default_item":106,"flag":1853},"TRAINER_LINDA_REWARD":{"address":5603006,"default_item":106,"flag":1741},"TRAINER_LISA_AND_RAY_REWARD":{"address":5603468,"default_item":106,"flag":1972},"TRAINER_LOLA_1_REWARD":{"address":5602198,"default_item":103,"flag":1337},"TRAINER_LORENZO_REWARD":{"address":5603190,"default_item":104,"flag":1833},"TRAINER_LUCAS_1_REWARD":{"address":5603342,"default_item":108,"flag":1909},"TRAINER_LUIS_REWARD":{"address":5602386,"default_item":103,"flag":1431},"TRAINER_LUNG_REWARD":{"address":5602924,"default_item":103,"flag":1700},"TRAINER_LYDIA_1_REWARD":{"address":5603174,"default_item":106,"flag":1825},"TRAINER_LYLE_REWARD":{"address":5603316,"default_item":103,"flag":1896},"TRAINER_MACEY_REWARD":{"address":5603266,"default_item":108,"flag":1871},"TRAINER_MADELINE_1_REWARD":{"address":5602952,"default_item":108,"flag":1714},"TRAINER_MAKAYLA_REWARD":{"address":5603600,"default_item":104,"flag":2038},"TRAINER_MARCEL_REWARD":{"address":5602106,"default_item":104,"flag":1291},"TRAINER_MARCOS_REWARD":{"address":5603488,"default_item":106,"flag":1982},"TRAINER_MARC_REWARD":{"address":5603226,"default_item":106,"flag":1851},"TRAINER_MARIA_1_REWARD":{"address":5602822,"default_item":106,"flag":1649},"TRAINER_MARK_REWARD":{"address":5602374,"default_item":104,"flag":1425},"TRAINER_MARLENE_REWARD":{"address":5603588,"default_item":106,"flag":2032},"TRAINER_MARLEY_REWARD":{"address":5603100,"default_item":104,"flag":1788},"TRAINER_MARY_REWARD":{"address":5602262,"default_item":104,"flag":1369},"TRAINER_MATTHEW_REWARD":{"address":5602398,"default_item":103,"flag":1437},"TRAINER_MATT_REWARD":{"address":5602144,"default_item":104,"flag":1310},"TRAINER_MAURA_REWARD":{"address":5602576,"default_item":108,"flag":1526},"TRAINER_MAXIE_MAGMA_HIDEOUT_REWARD":{"address":5603286,"default_item":107,"flag":1881},"TRAINER_MAXIE_MT_CHIMNEY_REWARD":{"address":5603288,"default_item":104,"flag":1882},"TRAINER_MAY_LILYCOVE_MUDKIP_REWARD":{"address":5603412,"default_item":104,"flag":1944},"TRAINER_MAY_LILYCOVE_TORCHIC_REWARD":{"address":5603416,"default_item":104,"flag":1946},"TRAINER_MAY_LILYCOVE_TREECKO_REWARD":{"address":5603414,"default_item":104,"flag":1945},"TRAINER_MAY_ROUTE_103_MUDKIP_REWARD":{"address":5603142,"default_item":106,"flag":1809},"TRAINER_MAY_ROUTE_103_TORCHIC_REWARD":{"address":5603154,"default_item":106,"flag":1815},"TRAINER_MAY_ROUTE_103_TREECKO_REWARD":{"address":5603148,"default_item":106,"flag":1812},"TRAINER_MAY_ROUTE_110_MUDKIP_REWARD":{"address":5603144,"default_item":104,"flag":1810},"TRAINER_MAY_ROUTE_110_TORCHIC_REWARD":{"address":5603156,"default_item":104,"flag":1816},"TRAINER_MAY_ROUTE_110_TREECKO_REWARD":{"address":5603150,"default_item":104,"flag":1813},"TRAINER_MAY_ROUTE_119_MUDKIP_REWARD":{"address":5603146,"default_item":104,"flag":1811},"TRAINER_MAY_ROUTE_119_TORCHIC_REWARD":{"address":5603158,"default_item":104,"flag":1817},"TRAINER_MAY_ROUTE_119_TREECKO_REWARD":{"address":5603152,"default_item":104,"flag":1814},"TRAINER_MAY_RUSTBORO_MUDKIP_REWARD":{"address":5603284,"default_item":108,"flag":1880},"TRAINER_MAY_RUSTBORO_TORCHIC_REWARD":{"address":5603622,"default_item":108,"flag":2049},"TRAINER_MAY_RUSTBORO_TREECKO_REWARD":{"address":5603620,"default_item":108,"flag":2048},"TRAINER_MELINA_REWARD":{"address":5603594,"default_item":106,"flag":2035},"TRAINER_MELISSA_REWARD":{"address":5602332,"default_item":104,"flag":1404},"TRAINER_MEL_AND_PAUL_REWARD":{"address":5603444,"default_item":108,"flag":1960},"TRAINER_MICAH_REWARD":{"address":5602594,"default_item":107,"flag":1535},"TRAINER_MICHELLE_REWARD":{"address":5602280,"default_item":104,"flag":1378},"TRAINER_MIGUEL_1_REWARD":{"address":5602670,"default_item":104,"flag":1573},"TRAINER_MIKE_2_REWARD":{"address":5603354,"default_item":106,"flag":1915},"TRAINER_MISSY_REWARD":{"address":5602978,"default_item":103,"flag":1727},"TRAINER_MITCHELL_REWARD":{"address":5603164,"default_item":104,"flag":1820},"TRAINER_MIU_AND_YUKI_REWARD":{"address":5603052,"default_item":106,"flag":1764},"TRAINER_MOLLIE_REWARD":{"address":5602358,"default_item":104,"flag":1417},"TRAINER_MYLES_REWARD":{"address":5603614,"default_item":104,"flag":2045},"TRAINER_NANCY_REWARD":{"address":5603028,"default_item":106,"flag":1752},"TRAINER_NAOMI_REWARD":{"address":5602322,"default_item":110,"flag":1399},"TRAINER_NATE_REWARD":{"address":5603248,"default_item":107,"flag":1862},"TRAINER_NED_REWARD":{"address":5602764,"default_item":106,"flag":1620},"TRAINER_NICHOLAS_REWARD":{"address":5603254,"default_item":108,"flag":1865},"TRAINER_NICOLAS_1_REWARD":{"address":5602868,"default_item":104,"flag":1672},"TRAINER_NIKKI_REWARD":{"address":5602990,"default_item":106,"flag":1733},"TRAINER_NOB_1_REWARD":{"address":5602450,"default_item":106,"flag":1463},"TRAINER_NOLAN_REWARD":{"address":5602768,"default_item":108,"flag":1622},"TRAINER_NOLEN_REWARD":{"address":5602406,"default_item":106,"flag":1441},"TRAINER_NORMAN_1_REWARD":{"address":5602622,"default_item":107,"flag":1549},"TRAINER_OLIVIA_REWARD":{"address":5602344,"default_item":107,"flag":1410},"TRAINER_OWEN_REWARD":{"address":5602250,"default_item":104,"flag":1363},"TRAINER_PABLO_1_REWARD":{"address":5602838,"default_item":104,"flag":1657},"TRAINER_PARKER_REWARD":{"address":5602228,"default_item":104,"flag":1352},"TRAINER_PAT_REWARD":{"address":5603616,"default_item":104,"flag":2046},"TRAINER_PAXTON_REWARD":{"address":5603272,"default_item":104,"flag":1874},"TRAINER_PERRY_REWARD":{"address":5602880,"default_item":108,"flag":1678},"TRAINER_PETE_REWARD":{"address":5603554,"default_item":103,"flag":2015},"TRAINER_PHILLIP_REWARD":{"address":5603072,"default_item":104,"flag":1774},"TRAINER_PHIL_REWARD":{"address":5602884,"default_item":108,"flag":1680},"TRAINER_PHOEBE_REWARD":{"address":5602608,"default_item":110,"flag":1542},"TRAINER_PRESLEY_REWARD":{"address":5602890,"default_item":104,"flag":1683},"TRAINER_PRESTON_REWARD":{"address":5602550,"default_item":108,"flag":1513},"TRAINER_QUINCY_REWARD":{"address":5602732,"default_item":104,"flag":1604},"TRAINER_RACHEL_REWARD":{"address":5603606,"default_item":104,"flag":2041},"TRAINER_RANDALL_REWARD":{"address":5602226,"default_item":104,"flag":1351},"TRAINER_REED_REWARD":{"address":5603434,"default_item":106,"flag":1955},"TRAINER_RELI_AND_IAN_REWARD":{"address":5603456,"default_item":106,"flag":1966},"TRAINER_REYNA_REWARD":{"address":5603102,"default_item":108,"flag":1789},"TRAINER_RHETT_REWARD":{"address":5603490,"default_item":106,"flag":1983},"TRAINER_RICHARD_REWARD":{"address":5602416,"default_item":106,"flag":1446},"TRAINER_RICKY_1_REWARD":{"address":5602212,"default_item":103,"flag":1344},"TRAINER_RICK_REWARD":{"address":5603314,"default_item":103,"flag":1895},"TRAINER_RILEY_REWARD":{"address":5603390,"default_item":106,"flag":1933},"TRAINER_ROBERT_1_REWARD":{"address":5602896,"default_item":108,"flag":1686},"TRAINER_RODNEY_REWARD":{"address":5602414,"default_item":106,"flag":1445},"TRAINER_ROGER_REWARD":{"address":5603422,"default_item":104,"flag":1949},"TRAINER_ROLAND_REWARD":{"address":5602404,"default_item":106,"flag":1440},"TRAINER_RONALD_REWARD":{"address":5602784,"default_item":104,"flag":1630},"TRAINER_ROSE_1_REWARD":{"address":5602158,"default_item":106,"flag":1317},"TRAINER_ROXANNE_1_REWARD":{"address":5602614,"default_item":104,"flag":1545},"TRAINER_RUBEN_REWARD":{"address":5603426,"default_item":104,"flag":1951},"TRAINER_SAMANTHA_REWARD":{"address":5602574,"default_item":108,"flag":1525},"TRAINER_SAMUEL_REWARD":{"address":5602246,"default_item":104,"flag":1361},"TRAINER_SANTIAGO_REWARD":{"address":5602420,"default_item":106,"flag":1448},"TRAINER_SARAH_REWARD":{"address":5603474,"default_item":104,"flag":1975},"TRAINER_SAWYER_1_REWARD":{"address":5602086,"default_item":108,"flag":1281},"TRAINER_SHANE_REWARD":{"address":5602512,"default_item":106,"flag":1494},"TRAINER_SHANNON_REWARD":{"address":5602278,"default_item":104,"flag":1377},"TRAINER_SHARON_REWARD":{"address":5602988,"default_item":106,"flag":1732},"TRAINER_SHAWN_REWARD":{"address":5602472,"default_item":106,"flag":1474},"TRAINER_SHAYLA_REWARD":{"address":5603578,"default_item":108,"flag":2027},"TRAINER_SHEILA_REWARD":{"address":5602334,"default_item":104,"flag":1405},"TRAINER_SHELBY_1_REWARD":{"address":5602710,"default_item":108,"flag":1593},"TRAINER_SHELLY_SEAFLOOR_CAVERN_REWARD":{"address":5602150,"default_item":104,"flag":1313},"TRAINER_SHELLY_WEATHER_INSTITUTE_REWARD":{"address":5602148,"default_item":104,"flag":1312},"TRAINER_SHIRLEY_REWARD":{"address":5602336,"default_item":104,"flag":1406},"TRAINER_SIDNEY_REWARD":{"address":5602606,"default_item":110,"flag":1541},"TRAINER_SIENNA_REWARD":{"address":5603002,"default_item":106,"flag":1739},"TRAINER_SIMON_REWARD":{"address":5602214,"default_item":103,"flag":1345},"TRAINER_SOPHIE_REWARD":{"address":5603500,"default_item":106,"flag":1988},"TRAINER_SPENCER_REWARD":{"address":5602402,"default_item":106,"flag":1439},"TRAINER_STAN_REWARD":{"address":5602408,"default_item":106,"flag":1442},"TRAINER_STEVEN_REWARD":{"address":5603692,"default_item":109,"flag":2084},"TRAINER_STEVE_1_REWARD":{"address":5602370,"default_item":104,"flag":1423},"TRAINER_SUSIE_REWARD":{"address":5602996,"default_item":106,"flag":1736},"TRAINER_SYLVIA_REWARD":{"address":5603234,"default_item":108,"flag":1855},"TRAINER_TABITHA_MAGMA_HIDEOUT_REWARD":{"address":5603548,"default_item":104,"flag":2012},"TRAINER_TABITHA_MT_CHIMNEY_REWARD":{"address":5603278,"default_item":108,"flag":1877},"TRAINER_TAKAO_REWARD":{"address":5602442,"default_item":106,"flag":1459},"TRAINER_TAKASHI_REWARD":{"address":5602916,"default_item":106,"flag":1696},"TRAINER_TALIA_REWARD":{"address":5602854,"default_item":104,"flag":1665},"TRAINER_TAMMY_REWARD":{"address":5602298,"default_item":106,"flag":1387},"TRAINER_TANYA_REWARD":{"address":5602986,"default_item":106,"flag":1731},"TRAINER_TARA_REWARD":{"address":5602976,"default_item":103,"flag":1726},"TRAINER_TASHA_REWARD":{"address":5602302,"default_item":108,"flag":1389},"TRAINER_TATE_AND_LIZA_1_REWARD":{"address":5602626,"default_item":109,"flag":1551},"TRAINER_TAYLOR_REWARD":{"address":5602534,"default_item":104,"flag":1505},"TRAINER_THALIA_1_REWARD":{"address":5602372,"default_item":104,"flag":1424},"TRAINER_THOMAS_REWARD":{"address":5602596,"default_item":107,"flag":1536},"TRAINER_TIANA_REWARD":{"address":5603290,"default_item":103,"flag":1883},"TRAINER_TIFFANY_REWARD":{"address":5602346,"default_item":107,"flag":1411},"TRAINER_TIMMY_REWARD":{"address":5602752,"default_item":103,"flag":1614},"TRAINER_TIMOTHY_1_REWARD":{"address":5602698,"default_item":104,"flag":1587},"TRAINER_TISHA_REWARD":{"address":5603436,"default_item":106,"flag":1956},"TRAINER_TOMMY_REWARD":{"address":5602726,"default_item":103,"flag":1601},"TRAINER_TONY_1_REWARD":{"address":5602394,"default_item":103,"flag":1435},"TRAINER_TORI_AND_TIA_REWARD":{"address":5603438,"default_item":103,"flag":1957},"TRAINER_TRAVIS_REWARD":{"address":5602520,"default_item":106,"flag":1498},"TRAINER_TRENT_1_REWARD":{"address":5603338,"default_item":106,"flag":1907},"TRAINER_TYRA_AND_IVY_REWARD":{"address":5603442,"default_item":106,"flag":1959},"TRAINER_TYRON_REWARD":{"address":5603492,"default_item":106,"flag":1984},"TRAINER_VALERIE_1_REWARD":{"address":5602300,"default_item":108,"flag":1388},"TRAINER_VANESSA_REWARD":{"address":5602684,"default_item":104,"flag":1580},"TRAINER_VICKY_REWARD":{"address":5602708,"default_item":108,"flag":1592},"TRAINER_VICTORIA_REWARD":{"address":5602682,"default_item":106,"flag":1579},"TRAINER_VICTOR_REWARD":{"address":5602668,"default_item":106,"flag":1572},"TRAINER_VIOLET_REWARD":{"address":5602162,"default_item":104,"flag":1319},"TRAINER_VIRGIL_REWARD":{"address":5602552,"default_item":108,"flag":1514},"TRAINER_VITO_REWARD":{"address":5602248,"default_item":104,"flag":1362},"TRAINER_VIVIAN_REWARD":{"address":5603382,"default_item":106,"flag":1929},"TRAINER_VIVI_REWARD":{"address":5603296,"default_item":106,"flag":1886},"TRAINER_WADE_REWARD":{"address":5602772,"default_item":106,"flag":1624},"TRAINER_WALLACE_REWARD":{"address":5602754,"default_item":110,"flag":1615},"TRAINER_WALLY_MAUVILLE_REWARD":{"address":5603396,"default_item":108,"flag":1936},"TRAINER_WALLY_VR_1_REWARD":{"address":5603122,"default_item":107,"flag":1799},"TRAINER_WALTER_1_REWARD":{"address":5602592,"default_item":104,"flag":1534},"TRAINER_WARREN_REWARD":{"address":5602260,"default_item":104,"flag":1368},"TRAINER_WATTSON_1_REWARD":{"address":5602618,"default_item":104,"flag":1547},"TRAINER_WAYNE_REWARD":{"address":5603430,"default_item":104,"flag":1953},"TRAINER_WENDY_REWARD":{"address":5602268,"default_item":104,"flag":1372},"TRAINER_WILLIAM_REWARD":{"address":5602556,"default_item":106,"flag":1516},"TRAINER_WILTON_1_REWARD":{"address":5602240,"default_item":108,"flag":1358},"TRAINER_WINONA_1_REWARD":{"address":5602624,"default_item":107,"flag":1550},"TRAINER_WINSTON_1_REWARD":{"address":5602356,"default_item":104,"flag":1416},"TRAINER_WYATT_REWARD":{"address":5603506,"default_item":104,"flag":1991},"TRAINER_YASU_REWARD":{"address":5602914,"default_item":106,"flag":1695},"TRAINER_ZANDER_REWARD":{"address":5602146,"default_item":108,"flag":1311}},"maps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":{"header_address":4766420,"warp_table_address":5496844},"MAP_ABANDONED_SHIP_CORRIDORS_1F":{"header_address":4766196,"warp_table_address":5495920},"MAP_ABANDONED_SHIP_CORRIDORS_B1F":{"header_address":4766252,"warp_table_address":5496248},"MAP_ABANDONED_SHIP_DECK":{"header_address":4766168,"warp_table_address":5495812},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":{"fishing_encounters":{"address":5609088,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766476,"warp_table_address":5496908,"water_encounters":{"address":5609060,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":{"header_address":4766504,"warp_table_address":5497120},"MAP_ABANDONED_SHIP_ROOMS2_1F":{"header_address":4766392,"warp_table_address":5496752},"MAP_ABANDONED_SHIP_ROOMS2_B1F":{"header_address":4766308,"warp_table_address":5496484},"MAP_ABANDONED_SHIP_ROOMS_1F":{"header_address":4766224,"warp_table_address":5496132},"MAP_ABANDONED_SHIP_ROOMS_B1F":{"fishing_encounters":{"address":5606324,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766280,"warp_table_address":5496392,"water_encounters":{"address":5606296,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_ROOM_B1F":{"header_address":4766364,"warp_table_address":5496596},"MAP_ABANDONED_SHIP_UNDERWATER1":{"header_address":4766336,"warp_table_address":5496536},"MAP_ABANDONED_SHIP_UNDERWATER2":{"header_address":4766448,"warp_table_address":5496880},"MAP_ALTERING_CAVE":{"header_address":4767624,"land_encounters":{"address":5613400,"slots":[41,41,41,41,41,41,41,41,41,41,41,41]},"warp_table_address":5500436},"MAP_ANCIENT_TOMB":{"header_address":4766560,"warp_table_address":5497460},"MAP_AQUA_HIDEOUT_1F":{"header_address":4765300,"warp_table_address":5490892},"MAP_AQUA_HIDEOUT_B1F":{"header_address":4765328,"warp_table_address":5491152},"MAP_AQUA_HIDEOUT_B2F":{"header_address":4765356,"warp_table_address":5491516},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":{"header_address":4766728,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":{"header_address":4766756,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":{"header_address":4766784,"warp_table_address":4160749568},"MAP_ARTISAN_CAVE_1F":{"header_address":4767456,"land_encounters":{"address":5613344,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500172},"MAP_ARTISAN_CAVE_B1F":{"header_address":4767428,"land_encounters":{"address":5613288,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500064},"MAP_BATTLE_COLOSSEUM_2P":{"header_address":4768352,"warp_table_address":5509852},"MAP_BATTLE_COLOSSEUM_4P":{"header_address":4768436,"warp_table_address":5510152},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":{"header_address":4770228,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":{"header_address":4770200,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":{"header_address":4770172,"warp_table_address":5520908},"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":{"header_address":4769976,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":{"header_address":4769920,"warp_table_address":5519076},"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":{"header_address":4769892,"warp_table_address":5518968},"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":{"header_address":4769948,"warp_table_address":5519136},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":{"header_address":4770312,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":{"header_address":4770256,"warp_table_address":5521384},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":{"header_address":4770284,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":{"header_address":4770060,"warp_table_address":5520116},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":{"header_address":4770032,"warp_table_address":5519944},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":{"header_address":4770004,"warp_table_address":5519696},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":{"header_address":4770368,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":{"header_address":4770340,"warp_table_address":5521808},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":{"header_address":4770452,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":{"header_address":4770424,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":{"header_address":4770480,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":{"header_address":4770396,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":{"header_address":4770116,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":{"header_address":4770088,"warp_table_address":5520248},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":{"header_address":4770144,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":{"header_address":4769612,"warp_table_address":5516696},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":{"header_address":4769584,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":{"header_address":4769556,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":{"header_address":4769528,"warp_table_address":5516432},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":{"header_address":4769864,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":{"header_address":4769836,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":{"header_address":4769808,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":{"header_address":4770564,"warp_table_address":5523056},"MAP_BATTLE_FRONTIER_LOUNGE1":{"header_address":4770536,"warp_table_address":5522812},"MAP_BATTLE_FRONTIER_LOUNGE2":{"header_address":4770592,"warp_table_address":5523220},"MAP_BATTLE_FRONTIER_LOUNGE3":{"header_address":4770620,"warp_table_address":5523376},"MAP_BATTLE_FRONTIER_LOUNGE4":{"header_address":4770648,"warp_table_address":5523476},"MAP_BATTLE_FRONTIER_LOUNGE5":{"header_address":4770704,"warp_table_address":5523660},"MAP_BATTLE_FRONTIER_LOUNGE6":{"header_address":4770732,"warp_table_address":5523720},"MAP_BATTLE_FRONTIER_LOUNGE7":{"header_address":4770760,"warp_table_address":5523844},"MAP_BATTLE_FRONTIER_LOUNGE8":{"header_address":4770816,"warp_table_address":5524100},"MAP_BATTLE_FRONTIER_LOUNGE9":{"header_address":4770844,"warp_table_address":5524152},"MAP_BATTLE_FRONTIER_MART":{"header_address":4770928,"warp_table_address":5524588},"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":{"header_address":4769780,"warp_table_address":5518080},"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":{"header_address":4769500,"warp_table_address":5516048},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":{"header_address":4770872,"warp_table_address":5524308},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":{"header_address":4770900,"warp_table_address":5524448},"MAP_BATTLE_FRONTIER_RANKING_HALL":{"header_address":4770508,"warp_table_address":5522560},"MAP_BATTLE_FRONTIER_RECEPTION_GATE":{"header_address":4770788,"warp_table_address":5523992},"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":{"header_address":4770676,"warp_table_address":5523528},"MAP_BATTLE_PYRAMID_SQUARE01":{"header_address":4768912,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE02":{"header_address":4768940,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE03":{"header_address":4768968,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE04":{"header_address":4768996,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE05":{"header_address":4769024,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE06":{"header_address":4769052,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE07":{"header_address":4769080,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE08":{"header_address":4769108,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE09":{"header_address":4769136,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE10":{"header_address":4769164,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE11":{"header_address":4769192,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE12":{"header_address":4769220,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE13":{"header_address":4769248,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE14":{"header_address":4769276,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE15":{"header_address":4769304,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE16":{"header_address":4769332,"warp_table_address":4160749568},"MAP_BIRTH_ISLAND_EXTERIOR":{"header_address":4771012,"warp_table_address":5524876},"MAP_BIRTH_ISLAND_HARBOR":{"header_address":4771040,"warp_table_address":5524952},"MAP_CAVE_OF_ORIGIN_1F":{"header_address":4765720,"land_encounters":{"address":5609868,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493440},"MAP_CAVE_OF_ORIGIN_B1F":{"header_address":4765832,"warp_table_address":5493608},"MAP_CAVE_OF_ORIGIN_ENTRANCE":{"header_address":4765692,"land_encounters":{"address":5609812,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493404},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":{"header_address":4765748,"land_encounters":{"address":5609924,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493476},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":{"header_address":4765776,"land_encounters":{"address":5609980,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493512},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":{"header_address":4765804,"land_encounters":{"address":5610036,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493548},"MAP_CONTEST_HALL":{"header_address":4768464,"warp_table_address":4160749568},"MAP_CONTEST_HALL_BEAUTY":{"header_address":4768660,"warp_table_address":4160749568},"MAP_CONTEST_HALL_COOL":{"header_address":4768716,"warp_table_address":4160749568},"MAP_CONTEST_HALL_CUTE":{"header_address":4768772,"warp_table_address":4160749568},"MAP_CONTEST_HALL_SMART":{"header_address":4768744,"warp_table_address":4160749568},"MAP_CONTEST_HALL_TOUGH":{"header_address":4768688,"warp_table_address":4160749568},"MAP_DESERT_RUINS":{"header_address":4764824,"warp_table_address":5486828},"MAP_DESERT_UNDERPASS":{"header_address":4767400,"land_encounters":{"address":5613232,"slots":[132,370,132,371,132,370,371,132,370,132,371,132]},"warp_table_address":5500012},"MAP_DEWFORD_TOWN":{"fishing_encounters":{"address":5611588,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758300,"warp_table_address":5435180,"water_encounters":{"address":5611560,"slots":[72,309,309,310,310]}},"MAP_DEWFORD_TOWN_GYM":{"header_address":4759952,"warp_table_address":5460340},"MAP_DEWFORD_TOWN_HALL":{"header_address":4759980,"warp_table_address":5460640},"MAP_DEWFORD_TOWN_HOUSE1":{"header_address":4759868,"warp_table_address":5459856},"MAP_DEWFORD_TOWN_HOUSE2":{"header_address":4760008,"warp_table_address":5460748},"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":{"header_address":4759896,"warp_table_address":5459964},"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":{"header_address":4759924,"warp_table_address":5460104},"MAP_EVER_GRANDE_CITY":{"fishing_encounters":{"address":5611892,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4758216,"warp_table_address":5434048,"water_encounters":{"address":5611864,"slots":[72,309,309,310,310]}},"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":{"header_address":4764012,"warp_table_address":5483720},"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":{"header_address":4763984,"warp_table_address":5483612},"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":{"header_address":4763956,"warp_table_address":5483552},"MAP_EVER_GRANDE_CITY_HALL1":{"header_address":4764040,"warp_table_address":5483756},"MAP_EVER_GRANDE_CITY_HALL2":{"header_address":4764068,"warp_table_address":5483808},"MAP_EVER_GRANDE_CITY_HALL3":{"header_address":4764096,"warp_table_address":5483860},"MAP_EVER_GRANDE_CITY_HALL4":{"header_address":4764124,"warp_table_address":5483912},"MAP_EVER_GRANDE_CITY_HALL5":{"header_address":4764152,"warp_table_address":5483948},"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":{"header_address":4764208,"warp_table_address":5484180},"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":{"header_address":4763928,"warp_table_address":5483492},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":{"header_address":4764236,"warp_table_address":5484304},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":{"header_address":4764264,"warp_table_address":5484444},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":{"header_address":4764180,"warp_table_address":5484096},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":{"header_address":4764292,"warp_table_address":5484584},"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":{"header_address":4763900,"warp_table_address":5483432},"MAP_FALLARBOR_TOWN":{"header_address":4758356,"warp_table_address":5435792},"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760316,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760288,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760260,"warp_table_address":5462376},"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":{"header_address":4760400,"warp_table_address":5462888},"MAP_FALLARBOR_TOWN_MART":{"header_address":4760232,"warp_table_address":5462220},"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":{"header_address":4760428,"warp_table_address":5462948},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":{"header_address":4760344,"warp_table_address":5462656},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":{"header_address":4760372,"warp_table_address":5462796},"MAP_FARAWAY_ISLAND_ENTRANCE":{"header_address":4770956,"warp_table_address":5524672},"MAP_FARAWAY_ISLAND_INTERIOR":{"header_address":4770984,"warp_table_address":5524792},"MAP_FIERY_PATH":{"header_address":4765048,"land_encounters":{"address":5606456,"slots":[339,109,339,66,321,218,109,66,321,321,88,88]},"warp_table_address":5489344},"MAP_FORTREE_CITY":{"header_address":4758104,"warp_table_address":5431676},"MAP_FORTREE_CITY_DECORATION_SHOP":{"header_address":4762444,"warp_table_address":5473936},"MAP_FORTREE_CITY_GYM":{"header_address":4762220,"warp_table_address":5472984},"MAP_FORTREE_CITY_HOUSE1":{"header_address":4762192,"warp_table_address":5472756},"MAP_FORTREE_CITY_HOUSE2":{"header_address":4762332,"warp_table_address":5473504},"MAP_FORTREE_CITY_HOUSE3":{"header_address":4762360,"warp_table_address":5473588},"MAP_FORTREE_CITY_HOUSE4":{"header_address":4762388,"warp_table_address":5473696},"MAP_FORTREE_CITY_HOUSE5":{"header_address":4762416,"warp_table_address":5473804},"MAP_FORTREE_CITY_MART":{"header_address":4762304,"warp_table_address":5473420},"MAP_FORTREE_CITY_POKEMON_CENTER_1F":{"header_address":4762248,"warp_table_address":5473140},"MAP_FORTREE_CITY_POKEMON_CENTER_2F":{"header_address":4762276,"warp_table_address":5473280},"MAP_GRANITE_CAVE_1F":{"header_address":4764852,"land_encounters":{"address":5605988,"slots":[41,335,335,41,335,63,335,335,74,74,74,74]},"warp_table_address":5486956},"MAP_GRANITE_CAVE_B1F":{"header_address":4764880,"land_encounters":{"address":5606044,"slots":[41,382,382,382,41,63,335,335,322,322,322,322]},"warp_table_address":5487032},"MAP_GRANITE_CAVE_B2F":{"header_address":4764908,"land_encounters":{"address":5606372,"slots":[41,382,382,41,382,63,322,322,322,322,322,322]},"rock_smash_encounters":{"address":5606428,"slots":[74,320,74,74,74]},"warp_table_address":5487324},"MAP_GRANITE_CAVE_STEVENS_ROOM":{"header_address":4764936,"land_encounters":{"address":5608188,"slots":[41,335,335,41,335,63,335,335,382,382,382,382]},"warp_table_address":5487432},"MAP_INSIDE_OF_TRUCK":{"header_address":4768800,"warp_table_address":5510720},"MAP_ISLAND_CAVE":{"header_address":4766532,"warp_table_address":5497356},"MAP_JAGGED_PASS":{"header_address":4765020,"land_encounters":{"address":5606644,"slots":[339,339,66,339,351,66,351,66,339,351,339,351]},"warp_table_address":5488908},"MAP_LAVARIDGE_TOWN":{"header_address":4758328,"warp_table_address":5435516},"MAP_LAVARIDGE_TOWN_GYM_1F":{"header_address":4760064,"warp_table_address":5461036},"MAP_LAVARIDGE_TOWN_GYM_B1F":{"header_address":4760092,"warp_table_address":5461384},"MAP_LAVARIDGE_TOWN_HERB_SHOP":{"header_address":4760036,"warp_table_address":5460856},"MAP_LAVARIDGE_TOWN_HOUSE":{"header_address":4760120,"warp_table_address":5461668},"MAP_LAVARIDGE_TOWN_MART":{"header_address":4760148,"warp_table_address":5461776},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":{"header_address":4760176,"warp_table_address":5461908},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":{"header_address":4760204,"warp_table_address":5462056},"MAP_LILYCOVE_CITY":{"fishing_encounters":{"address":5611512,"slots":[129,72,129,72,313,313,313,120,313,313]},"header_address":4758132,"warp_table_address":5432368,"water_encounters":{"address":5611484,"slots":[72,309,309,310,310]}},"MAP_LILYCOVE_CITY_CONTEST_HALL":{"header_address":4762612,"warp_table_address":5476560},"MAP_LILYCOVE_CITY_CONTEST_LOBBY":{"header_address":4762584,"warp_table_address":5475596},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":{"header_address":4762472,"warp_table_address":5473996},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":{"header_address":4762500,"warp_table_address":5474224},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":{"header_address":4762920,"warp_table_address":5478044},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":{"header_address":4762948,"warp_table_address":5478228},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":{"header_address":4762976,"warp_table_address":5478392},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":{"header_address":4763004,"warp_table_address":5478556},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":{"header_address":4763032,"warp_table_address":5478768},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":{"header_address":4763088,"warp_table_address":5478984},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":{"header_address":4763060,"warp_table_address":5478908},"MAP_LILYCOVE_CITY_HARBOR":{"header_address":4762752,"warp_table_address":5477396},"MAP_LILYCOVE_CITY_HOUSE1":{"header_address":4762808,"warp_table_address":5477540},"MAP_LILYCOVE_CITY_HOUSE2":{"header_address":4762836,"warp_table_address":5477600},"MAP_LILYCOVE_CITY_HOUSE3":{"header_address":4762864,"warp_table_address":5477780},"MAP_LILYCOVE_CITY_HOUSE4":{"header_address":4762892,"warp_table_address":5477864},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":{"header_address":4762528,"warp_table_address":5474492},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":{"header_address":4762556,"warp_table_address":5474824},"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":{"header_address":4762780,"warp_table_address":5477456},"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":{"header_address":4762640,"warp_table_address":5476804},"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":{"header_address":4762668,"warp_table_address":5476944},"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":{"header_address":4762724,"warp_table_address":5477240},"MAP_LILYCOVE_CITY_UNUSED_MART":{"header_address":4762696,"warp_table_address":5476988},"MAP_LITTLEROOT_TOWN":{"header_address":4758244,"warp_table_address":5434528},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":{"header_address":4759588,"warp_table_address":5457588},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":{"header_address":4759616,"warp_table_address":5458080},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":{"header_address":4759644,"warp_table_address":5458324},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":{"header_address":4759672,"warp_table_address":5458816},"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":{"header_address":4759700,"warp_table_address":5459036},"MAP_MAGMA_HIDEOUT_1F":{"header_address":4767064,"land_encounters":{"address":5612560,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498844},"MAP_MAGMA_HIDEOUT_2F_1R":{"header_address":4767092,"land_encounters":{"address":5612616,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498992},"MAP_MAGMA_HIDEOUT_2F_2R":{"header_address":4767120,"land_encounters":{"address":5612672,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499180},"MAP_MAGMA_HIDEOUT_2F_3R":{"header_address":4767260,"land_encounters":{"address":5612952,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499696},"MAP_MAGMA_HIDEOUT_3F_1R":{"header_address":4767148,"land_encounters":{"address":5612728,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499288},"MAP_MAGMA_HIDEOUT_3F_2R":{"header_address":4767176,"land_encounters":{"address":5612784,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499380},"MAP_MAGMA_HIDEOUT_3F_3R":{"header_address":4767232,"land_encounters":{"address":5612896,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499660},"MAP_MAGMA_HIDEOUT_4F":{"header_address":4767204,"land_encounters":{"address":5612840,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499600},"MAP_MARINE_CAVE_END":{"header_address":4767540,"warp_table_address":5500288},"MAP_MARINE_CAVE_ENTRANCE":{"header_address":4767512,"warp_table_address":5500236},"MAP_MAUVILLE_CITY":{"header_address":4758048,"warp_table_address":5430380},"MAP_MAUVILLE_CITY_BIKE_SHOP":{"header_address":4761520,"warp_table_address":5469232},"MAP_MAUVILLE_CITY_GAME_CORNER":{"header_address":4761576,"warp_table_address":5469640},"MAP_MAUVILLE_CITY_GYM":{"header_address":4761492,"warp_table_address":5469060},"MAP_MAUVILLE_CITY_HOUSE1":{"header_address":4761548,"warp_table_address":5469316},"MAP_MAUVILLE_CITY_HOUSE2":{"header_address":4761604,"warp_table_address":5469988},"MAP_MAUVILLE_CITY_MART":{"header_address":4761688,"warp_table_address":5470424},"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":{"header_address":4761632,"warp_table_address":5470144},"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":{"header_address":4761660,"warp_table_address":5470308},"MAP_METEOR_FALLS_1F_1R":{"fishing_encounters":{"address":5610796,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4764656,"land_encounters":{"address":5610712,"slots":[41,41,41,41,41,349,349,349,41,41,41,41]},"warp_table_address":5486052,"water_encounters":{"address":5610768,"slots":[41,41,349,349,349]}},"MAP_METEOR_FALLS_1F_2R":{"fishing_encounters":{"address":5610928,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764684,"land_encounters":{"address":5610844,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486220,"water_encounters":{"address":5610900,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_1R":{"fishing_encounters":{"address":5611060,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764712,"land_encounters":{"address":5610976,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486284,"water_encounters":{"address":5611032,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_2R":{"fishing_encounters":{"address":5606596,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764740,"land_encounters":{"address":5606512,"slots":[42,42,395,349,395,349,395,349,42,42,42,42]},"warp_table_address":5486376,"water_encounters":{"address":5606568,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_STEVENS_CAVE":{"header_address":4767652,"land_encounters":{"address":5613904,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5500488},"MAP_MIRAGE_TOWER_1F":{"header_address":4767288,"land_encounters":{"address":5613008,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499732},"MAP_MIRAGE_TOWER_2F":{"header_address":4767316,"land_encounters":{"address":5613064,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499768},"MAP_MIRAGE_TOWER_3F":{"header_address":4767344,"land_encounters":{"address":5613120,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499852},"MAP_MIRAGE_TOWER_4F":{"header_address":4767372,"land_encounters":{"address":5613176,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499960},"MAP_MOSSDEEP_CITY":{"fishing_encounters":{"address":5611740,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758160,"warp_table_address":5433064,"water_encounters":{"address":5611712,"slots":[72,309,309,310,310]}},"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":{"header_address":4763424,"warp_table_address":5481712},"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":{"header_address":4763452,"warp_table_address":5481816},"MAP_MOSSDEEP_CITY_GYM":{"header_address":4763116,"warp_table_address":5479884},"MAP_MOSSDEEP_CITY_HOUSE1":{"header_address":4763144,"warp_table_address":5480232},"MAP_MOSSDEEP_CITY_HOUSE2":{"header_address":4763172,"warp_table_address":5480340},"MAP_MOSSDEEP_CITY_HOUSE3":{"header_address":4763284,"warp_table_address":5480812},"MAP_MOSSDEEP_CITY_HOUSE4":{"header_address":4763340,"warp_table_address":5481076},"MAP_MOSSDEEP_CITY_MART":{"header_address":4763256,"warp_table_address":5480752},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":{"header_address":4763200,"warp_table_address":5480448},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":{"header_address":4763228,"warp_table_address":5480612},"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":{"header_address":4763368,"warp_table_address":5481376},"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":{"header_address":4763396,"warp_table_address":5481636},"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":{"header_address":4763312,"warp_table_address":5480920},"MAP_MT_CHIMNEY":{"header_address":4764992,"warp_table_address":5488664},"MAP_MT_CHIMNEY_CABLE_CAR_STATION":{"header_address":4764460,"warp_table_address":5485144},"MAP_MT_PYRE_1F":{"header_address":4765076,"land_encounters":{"address":5606100,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489452},"MAP_MT_PYRE_2F":{"header_address":4765104,"land_encounters":{"address":5607796,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489712},"MAP_MT_PYRE_3F":{"header_address":4765132,"land_encounters":{"address":5607852,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489868},"MAP_MT_PYRE_4F":{"header_address":4765160,"land_encounters":{"address":5607908,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5489984},"MAP_MT_PYRE_5F":{"header_address":4765188,"land_encounters":{"address":5607964,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490100},"MAP_MT_PYRE_6F":{"header_address":4765216,"land_encounters":{"address":5608020,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490232},"MAP_MT_PYRE_EXTERIOR":{"header_address":4765244,"land_encounters":{"address":5608076,"slots":[377,377,377,377,37,37,37,37,309,309,309,309]},"warp_table_address":5490316},"MAP_MT_PYRE_SUMMIT":{"header_address":4765272,"land_encounters":{"address":5608132,"slots":[377,377,377,377,377,377,377,361,361,361,411,411]},"warp_table_address":5490656},"MAP_NAVEL_ROCK_B1F":{"header_address":4771320,"warp_table_address":5525524},"MAP_NAVEL_ROCK_BOTTOM":{"header_address":4771824,"warp_table_address":5526248},"MAP_NAVEL_ROCK_DOWN01":{"header_address":4771516,"warp_table_address":5525828},"MAP_NAVEL_ROCK_DOWN02":{"header_address":4771544,"warp_table_address":5525864},"MAP_NAVEL_ROCK_DOWN03":{"header_address":4771572,"warp_table_address":5525900},"MAP_NAVEL_ROCK_DOWN04":{"header_address":4771600,"warp_table_address":5525936},"MAP_NAVEL_ROCK_DOWN05":{"header_address":4771628,"warp_table_address":5525972},"MAP_NAVEL_ROCK_DOWN06":{"header_address":4771656,"warp_table_address":5526008},"MAP_NAVEL_ROCK_DOWN07":{"header_address":4771684,"warp_table_address":5526044},"MAP_NAVEL_ROCK_DOWN08":{"header_address":4771712,"warp_table_address":5526080},"MAP_NAVEL_ROCK_DOWN09":{"header_address":4771740,"warp_table_address":5526116},"MAP_NAVEL_ROCK_DOWN10":{"header_address":4771768,"warp_table_address":5526152},"MAP_NAVEL_ROCK_DOWN11":{"header_address":4771796,"warp_table_address":5526188},"MAP_NAVEL_ROCK_ENTRANCE":{"header_address":4771292,"warp_table_address":5525488},"MAP_NAVEL_ROCK_EXTERIOR":{"header_address":4771236,"warp_table_address":5525376},"MAP_NAVEL_ROCK_FORK":{"header_address":4771348,"warp_table_address":5525560},"MAP_NAVEL_ROCK_HARBOR":{"header_address":4771264,"warp_table_address":5525460},"MAP_NAVEL_ROCK_TOP":{"header_address":4771488,"warp_table_address":5525772},"MAP_NAVEL_ROCK_UP1":{"header_address":4771376,"warp_table_address":5525604},"MAP_NAVEL_ROCK_UP2":{"header_address":4771404,"warp_table_address":5525640},"MAP_NAVEL_ROCK_UP3":{"header_address":4771432,"warp_table_address":5525676},"MAP_NAVEL_ROCK_UP4":{"header_address":4771460,"warp_table_address":5525712},"MAP_NEW_MAUVILLE_ENTRANCE":{"header_address":4766112,"land_encounters":{"address":5610092,"slots":[100,81,100,81,100,81,100,81,100,81,100,81]},"warp_table_address":5495284},"MAP_NEW_MAUVILLE_INSIDE":{"header_address":4766140,"land_encounters":{"address":5607136,"slots":[100,81,100,81,100,81,100,81,100,81,101,82]},"warp_table_address":5495528},"MAP_OLDALE_TOWN":{"header_address":4758272,"warp_table_address":5434860},"MAP_OLDALE_TOWN_HOUSE1":{"header_address":4759728,"warp_table_address":5459276},"MAP_OLDALE_TOWN_HOUSE2":{"header_address":4759756,"warp_table_address":5459360},"MAP_OLDALE_TOWN_MART":{"header_address":4759840,"warp_table_address":5459748},"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":{"header_address":4759784,"warp_table_address":5459492},"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":{"header_address":4759812,"warp_table_address":5459632},"MAP_PACIFIDLOG_TOWN":{"fishing_encounters":{"address":5611816,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758412,"warp_table_address":5436288,"water_encounters":{"address":5611788,"slots":[72,309,309,310,310]}},"MAP_PACIFIDLOG_TOWN_HOUSE1":{"header_address":4760764,"warp_table_address":5464400},"MAP_PACIFIDLOG_TOWN_HOUSE2":{"header_address":4760792,"warp_table_address":5464508},"MAP_PACIFIDLOG_TOWN_HOUSE3":{"header_address":4760820,"warp_table_address":5464592},"MAP_PACIFIDLOG_TOWN_HOUSE4":{"header_address":4760848,"warp_table_address":5464700},"MAP_PACIFIDLOG_TOWN_HOUSE5":{"header_address":4760876,"warp_table_address":5464784},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":{"header_address":4760708,"warp_table_address":5464168},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":{"header_address":4760736,"warp_table_address":5464308},"MAP_PETALBURG_CITY":{"fishing_encounters":{"address":5611968,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4757992,"warp_table_address":5428704,"water_encounters":{"address":5611940,"slots":[183,183,183,183,183]}},"MAP_PETALBURG_CITY_GYM":{"header_address":4760932,"warp_table_address":5465168},"MAP_PETALBURG_CITY_HOUSE1":{"header_address":4760960,"warp_table_address":5465708},"MAP_PETALBURG_CITY_HOUSE2":{"header_address":4760988,"warp_table_address":5465792},"MAP_PETALBURG_CITY_MART":{"header_address":4761072,"warp_table_address":5466228},"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":{"header_address":4761016,"warp_table_address":5465948},"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":{"header_address":4761044,"warp_table_address":5466088},"MAP_PETALBURG_CITY_WALLYS_HOUSE":{"header_address":4760904,"warp_table_address":5464868},"MAP_PETALBURG_WOODS":{"header_address":4764964,"land_encounters":{"address":5605876,"slots":[286,290,306,286,291,293,290,306,304,364,304,364]},"warp_table_address":5487772},"MAP_RECORD_CORNER":{"header_address":4768408,"warp_table_address":5510036},"MAP_ROUTE101":{"header_address":4758440,"land_encounters":{"address":5604388,"slots":[290,286,290,290,286,286,290,286,288,288,288,288]},"warp_table_address":4160749568},"MAP_ROUTE102":{"fishing_encounters":{"address":5604528,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758468,"land_encounters":{"address":5604444,"slots":[286,290,286,290,295,295,288,288,288,392,288,298]},"warp_table_address":4160749568,"water_encounters":{"address":5604500,"slots":[183,183,183,183,118]}},"MAP_ROUTE103":{"fishing_encounters":{"address":5604660,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758496,"land_encounters":{"address":5604576,"slots":[286,286,286,286,309,288,288,288,309,309,309,309]},"warp_table_address":5437452,"water_encounters":{"address":5604632,"slots":[72,309,309,310,310]}},"MAP_ROUTE104":{"fishing_encounters":{"address":5604792,"slots":[129,129,129,129,129,129,129,129,129,129]},"header_address":4758524,"land_encounters":{"address":5604708,"slots":[286,290,286,183,183,286,304,304,309,309,309,309]},"warp_table_address":5438308,"water_encounters":{"address":5604764,"slots":[309,309,309,310,310]}},"MAP_ROUTE104_MR_BRINEYS_HOUSE":{"header_address":4764320,"warp_table_address":5484676},"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4764348,"warp_table_address":5484784},"MAP_ROUTE104_PROTOTYPE":{"header_address":4771880,"warp_table_address":4160749568},"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4771908,"warp_table_address":4160749568},"MAP_ROUTE105":{"fishing_encounters":{"address":5604868,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758552,"warp_table_address":5438720,"water_encounters":{"address":5604840,"slots":[72,309,309,310,310]}},"MAP_ROUTE106":{"fishing_encounters":{"address":5606728,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758580,"warp_table_address":5438892,"water_encounters":{"address":5606700,"slots":[72,309,309,310,310]}},"MAP_ROUTE107":{"fishing_encounters":{"address":5606804,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758608,"warp_table_address":4160749568,"water_encounters":{"address":5606776,"slots":[72,309,309,310,310]}},"MAP_ROUTE108":{"fishing_encounters":{"address":5606880,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758636,"warp_table_address":5439324,"water_encounters":{"address":5606852,"slots":[72,309,309,310,310]}},"MAP_ROUTE109":{"fishing_encounters":{"address":5606956,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758664,"warp_table_address":5439940,"water_encounters":{"address":5606928,"slots":[72,309,309,310,310]}},"MAP_ROUTE109_SEASHORE_HOUSE":{"header_address":4771936,"warp_table_address":5526472},"MAP_ROUTE110":{"fishing_encounters":{"address":5605000,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758692,"land_encounters":{"address":5604916,"slots":[286,337,367,337,354,43,354,367,309,309,353,353]},"warp_table_address":5440928,"water_encounters":{"address":5604972,"slots":[72,309,309,310,310]}},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":{"header_address":4772272,"warp_table_address":5529400},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":{"header_address":4772300,"warp_table_address":5529508},"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":{"header_address":4772020,"warp_table_address":5526740},"MAP_ROUTE110_TRICK_HOUSE_END":{"header_address":4771992,"warp_table_address":5526676},"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":{"header_address":4771964,"warp_table_address":5526532},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":{"header_address":4772048,"warp_table_address":5527152},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":{"header_address":4772076,"warp_table_address":5527328},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":{"header_address":4772104,"warp_table_address":5527616},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":{"header_address":4772132,"warp_table_address":5528072},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":{"header_address":4772160,"warp_table_address":5528248},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":{"header_address":4772188,"warp_table_address":5528752},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":{"header_address":4772216,"warp_table_address":5529024},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":{"header_address":4772244,"warp_table_address":5529320},"MAP_ROUTE111":{"fishing_encounters":{"address":5605160,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758720,"land_encounters":{"address":5605048,"slots":[27,332,27,332,318,318,27,332,318,344,344,344]},"rock_smash_encounters":{"address":5605132,"slots":[74,74,74,74,74]},"warp_table_address":5442448,"water_encounters":{"address":5605104,"slots":[183,183,183,183,118]}},"MAP_ROUTE111_OLD_LADYS_REST_STOP":{"header_address":4764404,"warp_table_address":5484976},"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":{"header_address":4764376,"warp_table_address":5484916},"MAP_ROUTE112":{"header_address":4758748,"land_encounters":{"address":5605208,"slots":[339,339,183,339,339,183,339,183,339,339,339,339]},"warp_table_address":5443604},"MAP_ROUTE112_CABLE_CAR_STATION":{"header_address":4764432,"warp_table_address":5485060},"MAP_ROUTE113":{"header_address":4758776,"land_encounters":{"address":5605264,"slots":[308,308,218,308,308,218,308,218,308,227,308,227]},"warp_table_address":5444092},"MAP_ROUTE113_GLASS_WORKSHOP":{"header_address":4772328,"warp_table_address":5529640},"MAP_ROUTE114":{"fishing_encounters":{"address":5605432,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758804,"land_encounters":{"address":5605320,"slots":[358,295,358,358,295,296,296,296,379,379,379,299]},"rock_smash_encounters":{"address":5605404,"slots":[74,74,74,74,74]},"warp_table_address":5445184,"water_encounters":{"address":5605376,"slots":[183,183,183,183,118]}},"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":{"header_address":4764488,"warp_table_address":5485204},"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":{"header_address":4764516,"warp_table_address":5485320},"MAP_ROUTE114_LANETTES_HOUSE":{"header_address":4764544,"warp_table_address":5485420},"MAP_ROUTE115":{"fishing_encounters":{"address":5607088,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758832,"land_encounters":{"address":5607004,"slots":[358,304,358,304,304,305,39,39,309,309,309,309]},"warp_table_address":5445988,"water_encounters":{"address":5607060,"slots":[72,309,309,310,310]}},"MAP_ROUTE116":{"header_address":4758860,"land_encounters":{"address":5605480,"slots":[286,370,301,63,301,304,304,304,286,286,315,315]},"warp_table_address":5446872},"MAP_ROUTE116_TUNNELERS_REST_HOUSE":{"header_address":4764572,"warp_table_address":5485564},"MAP_ROUTE117":{"fishing_encounters":{"address":5605620,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758888,"land_encounters":{"address":5605536,"slots":[286,43,286,43,183,43,387,387,387,387,386,298]},"warp_table_address":5447656,"water_encounters":{"address":5605592,"slots":[183,183,183,183,118]}},"MAP_ROUTE117_POKEMON_DAY_CARE":{"header_address":4764600,"warp_table_address":5485624},"MAP_ROUTE118":{"fishing_encounters":{"address":5605752,"slots":[129,72,129,72,330,331,330,330,330,330]},"header_address":4758916,"land_encounters":{"address":5605668,"slots":[288,337,288,337,289,338,309,309,309,309,309,317]},"warp_table_address":5448236,"water_encounters":{"address":5605724,"slots":[72,309,309,310,310]}},"MAP_ROUTE119":{"fishing_encounters":{"address":5607276,"slots":[129,72,129,72,330,330,330,330,330,330]},"header_address":4758944,"land_encounters":{"address":5607192,"slots":[288,289,288,43,289,43,43,43,369,369,369,317]},"warp_table_address":5449460,"water_encounters":{"address":5607248,"slots":[72,309,309,310,310]}},"MAP_ROUTE119_HOUSE":{"header_address":4772440,"warp_table_address":5530360},"MAP_ROUTE119_WEATHER_INSTITUTE_1F":{"header_address":4772384,"warp_table_address":5529880},"MAP_ROUTE119_WEATHER_INSTITUTE_2F":{"header_address":4772412,"warp_table_address":5530164},"MAP_ROUTE120":{"fishing_encounters":{"address":5607408,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758972,"land_encounters":{"address":5607324,"slots":[286,287,287,43,183,43,43,183,376,376,317,298]},"warp_table_address":5451160,"water_encounters":{"address":5607380,"slots":[183,183,183,183,118]}},"MAP_ROUTE121":{"fishing_encounters":{"address":5607540,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759000,"land_encounters":{"address":5607456,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5452364,"water_encounters":{"address":5607512,"slots":[72,309,309,310,310]}},"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":{"header_address":4764628,"warp_table_address":5485732},"MAP_ROUTE122":{"fishing_encounters":{"address":5607616,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759028,"warp_table_address":5452576,"water_encounters":{"address":5607588,"slots":[72,309,309,310,310]}},"MAP_ROUTE123":{"fishing_encounters":{"address":5607748,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759056,"land_encounters":{"address":5607664,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5453636,"water_encounters":{"address":5607720,"slots":[72,309,309,310,310]}},"MAP_ROUTE123_BERRY_MASTERS_HOUSE":{"header_address":4772356,"warp_table_address":5529724},"MAP_ROUTE124":{"fishing_encounters":{"address":5605828,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759084,"warp_table_address":5454436,"water_encounters":{"address":5605800,"slots":[72,309,309,310,310]}},"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":{"header_address":4772468,"warp_table_address":5530420},"MAP_ROUTE125":{"fishing_encounters":{"address":5608272,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759112,"warp_table_address":5454716,"water_encounters":{"address":5608244,"slots":[72,309,309,310,310]}},"MAP_ROUTE126":{"fishing_encounters":{"address":5608348,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759140,"warp_table_address":4160749568,"water_encounters":{"address":5608320,"slots":[72,309,309,310,310]}},"MAP_ROUTE127":{"fishing_encounters":{"address":5608424,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759168,"warp_table_address":4160749568,"water_encounters":{"address":5608396,"slots":[72,309,309,310,310]}},"MAP_ROUTE128":{"fishing_encounters":{"address":5608500,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4759196,"warp_table_address":4160749568,"water_encounters":{"address":5608472,"slots":[72,309,309,310,310]}},"MAP_ROUTE129":{"fishing_encounters":{"address":5608576,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759224,"warp_table_address":4160749568,"water_encounters":{"address":5608548,"slots":[72,309,309,310,314]}},"MAP_ROUTE130":{"fishing_encounters":{"address":5608708,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759252,"land_encounters":{"address":5608624,"slots":[360,360,360,360,360,360,360,360,360,360,360,360]},"warp_table_address":4160749568,"water_encounters":{"address":5608680,"slots":[72,309,309,310,310]}},"MAP_ROUTE131":{"fishing_encounters":{"address":5608784,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759280,"warp_table_address":5456116,"water_encounters":{"address":5608756,"slots":[72,309,309,310,310]}},"MAP_ROUTE132":{"fishing_encounters":{"address":5608860,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759308,"warp_table_address":4160749568,"water_encounters":{"address":5608832,"slots":[72,309,309,310,310]}},"MAP_ROUTE133":{"fishing_encounters":{"address":5608936,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759336,"warp_table_address":4160749568,"water_encounters":{"address":5608908,"slots":[72,309,309,310,310]}},"MAP_ROUTE134":{"fishing_encounters":{"address":5609012,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759364,"warp_table_address":4160749568,"water_encounters":{"address":5608984,"slots":[72,309,309,310,310]}},"MAP_RUSTBORO_CITY":{"header_address":4758076,"warp_table_address":5430936},"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":{"header_address":4762024,"warp_table_address":5472204},"MAP_RUSTBORO_CITY_DEVON_CORP_1F":{"header_address":4761716,"warp_table_address":5470532},"MAP_RUSTBORO_CITY_DEVON_CORP_2F":{"header_address":4761744,"warp_table_address":5470744},"MAP_RUSTBORO_CITY_DEVON_CORP_3F":{"header_address":4761772,"warp_table_address":5470852},"MAP_RUSTBORO_CITY_FLAT1_1F":{"header_address":4761940,"warp_table_address":5471808},"MAP_RUSTBORO_CITY_FLAT1_2F":{"header_address":4761968,"warp_table_address":5472044},"MAP_RUSTBORO_CITY_FLAT2_1F":{"header_address":4762080,"warp_table_address":5472372},"MAP_RUSTBORO_CITY_FLAT2_2F":{"header_address":4762108,"warp_table_address":5472464},"MAP_RUSTBORO_CITY_FLAT2_3F":{"header_address":4762136,"warp_table_address":5472548},"MAP_RUSTBORO_CITY_GYM":{"header_address":4761800,"warp_table_address":5471024},"MAP_RUSTBORO_CITY_HOUSE1":{"header_address":4761996,"warp_table_address":5472120},"MAP_RUSTBORO_CITY_HOUSE2":{"header_address":4762052,"warp_table_address":5472288},"MAP_RUSTBORO_CITY_HOUSE3":{"header_address":4762164,"warp_table_address":5472648},"MAP_RUSTBORO_CITY_MART":{"header_address":4761912,"warp_table_address":5471724},"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":{"header_address":4761856,"warp_table_address":5471444},"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":{"header_address":4761884,"warp_table_address":5471584},"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":{"header_address":4761828,"warp_table_address":5471252},"MAP_RUSTURF_TUNNEL":{"header_address":4764768,"land_encounters":{"address":5605932,"slots":[370,370,370,370,370,370,370,370,370,370,370,370]},"warp_table_address":5486644},"MAP_SAFARI_ZONE_NORTH":{"header_address":4769416,"land_encounters":{"address":5610280,"slots":[231,43,231,43,177,44,44,177,178,214,178,214]},"rock_smash_encounters":{"address":5610336,"slots":[74,74,74,74,74]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHEAST":{"header_address":4769724,"land_encounters":{"address":5612476,"slots":[190,216,190,216,191,165,163,204,228,241,228,241]},"rock_smash_encounters":{"address":5612532,"slots":[213,213,213,213,213]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHWEST":{"fishing_encounters":{"address":5610448,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769388,"land_encounters":{"address":5610364,"slots":[111,43,111,43,84,44,44,84,85,127,85,127]},"warp_table_address":4160749568,"water_encounters":{"address":5610420,"slots":[54,54,54,55,55]}},"MAP_SAFARI_ZONE_REST_HOUSE":{"header_address":4769696,"warp_table_address":5516996},"MAP_SAFARI_ZONE_SOUTH":{"header_address":4769472,"land_encounters":{"address":5606212,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515444},"MAP_SAFARI_ZONE_SOUTHEAST":{"fishing_encounters":{"address":5612428,"slots":[129,118,129,118,223,118,223,223,223,224]},"header_address":4769752,"land_encounters":{"address":5612344,"slots":[191,179,191,179,190,167,163,209,234,207,234,207]},"warp_table_address":4160749568,"water_encounters":{"address":5612400,"slots":[194,183,183,183,195]}},"MAP_SAFARI_ZONE_SOUTHWEST":{"fishing_encounters":{"address":5610232,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769444,"land_encounters":{"address":5610148,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515260,"water_encounters":{"address":5610204,"slots":[54,54,54,54,54]}},"MAP_SCORCHED_SLAB":{"header_address":4766700,"warp_table_address":5498144},"MAP_SEAFLOOR_CAVERN_ENTRANCE":{"fishing_encounters":{"address":5609764,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765412,"warp_table_address":5491796,"water_encounters":{"address":5609736,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM1":{"header_address":4765440,"land_encounters":{"address":5609136,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5491952},"MAP_SEAFLOOR_CAVERN_ROOM2":{"header_address":4765468,"land_encounters":{"address":5609192,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492188},"MAP_SEAFLOOR_CAVERN_ROOM3":{"header_address":4765496,"land_encounters":{"address":5609248,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492456},"MAP_SEAFLOOR_CAVERN_ROOM4":{"header_address":4765524,"land_encounters":{"address":5609304,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492548},"MAP_SEAFLOOR_CAVERN_ROOM5":{"header_address":4765552,"land_encounters":{"address":5609360,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492744},"MAP_SEAFLOOR_CAVERN_ROOM6":{"fishing_encounters":{"address":5609500,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765580,"land_encounters":{"address":5609416,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492788,"water_encounters":{"address":5609472,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM7":{"fishing_encounters":{"address":5609632,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765608,"land_encounters":{"address":5609548,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492832,"water_encounters":{"address":5609604,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM8":{"header_address":4765636,"land_encounters":{"address":5609680,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493156},"MAP_SEAFLOOR_CAVERN_ROOM9":{"header_address":4765664,"warp_table_address":5493360},"MAP_SEALED_CHAMBER_INNER_ROOM":{"header_address":4766672,"warp_table_address":5497984},"MAP_SEALED_CHAMBER_OUTER_ROOM":{"header_address":4766644,"warp_table_address":5497608},"MAP_SECRET_BASE_BLUE_CAVE1":{"header_address":4767736,"warp_table_address":5501652},"MAP_SECRET_BASE_BLUE_CAVE2":{"header_address":4767904,"warp_table_address":5503980},"MAP_SECRET_BASE_BLUE_CAVE3":{"header_address":4768072,"warp_table_address":5506308},"MAP_SECRET_BASE_BLUE_CAVE4":{"header_address":4768240,"warp_table_address":5508636},"MAP_SECRET_BASE_BROWN_CAVE1":{"header_address":4767708,"warp_table_address":5501264},"MAP_SECRET_BASE_BROWN_CAVE2":{"header_address":4767876,"warp_table_address":5503592},"MAP_SECRET_BASE_BROWN_CAVE3":{"header_address":4768044,"warp_table_address":5505920},"MAP_SECRET_BASE_BROWN_CAVE4":{"header_address":4768212,"warp_table_address":5508248},"MAP_SECRET_BASE_RED_CAVE1":{"header_address":4767680,"warp_table_address":5500876},"MAP_SECRET_BASE_RED_CAVE2":{"header_address":4767848,"warp_table_address":5503204},"MAP_SECRET_BASE_RED_CAVE3":{"header_address":4768016,"warp_table_address":5505532},"MAP_SECRET_BASE_RED_CAVE4":{"header_address":4768184,"warp_table_address":5507860},"MAP_SECRET_BASE_SHRUB1":{"header_address":4767820,"warp_table_address":5502816},"MAP_SECRET_BASE_SHRUB2":{"header_address":4767988,"warp_table_address":5505144},"MAP_SECRET_BASE_SHRUB3":{"header_address":4768156,"warp_table_address":5507472},"MAP_SECRET_BASE_SHRUB4":{"header_address":4768324,"warp_table_address":5509800},"MAP_SECRET_BASE_TREE1":{"header_address":4767792,"warp_table_address":5502428},"MAP_SECRET_BASE_TREE2":{"header_address":4767960,"warp_table_address":5504756},"MAP_SECRET_BASE_TREE3":{"header_address":4768128,"warp_table_address":5507084},"MAP_SECRET_BASE_TREE4":{"header_address":4768296,"warp_table_address":5509412},"MAP_SECRET_BASE_YELLOW_CAVE1":{"header_address":4767764,"warp_table_address":5502040},"MAP_SECRET_BASE_YELLOW_CAVE2":{"header_address":4767932,"warp_table_address":5504368},"MAP_SECRET_BASE_YELLOW_CAVE3":{"header_address":4768100,"warp_table_address":5506696},"MAP_SECRET_BASE_YELLOW_CAVE4":{"header_address":4768268,"warp_table_address":5509024},"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":{"header_address":4766056,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":{"header_address":4766084,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":{"fishing_encounters":{"address":5611436,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765944,"land_encounters":{"address":5611352,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494828,"water_encounters":{"address":5611408,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":{"header_address":4766980,"land_encounters":{"address":5612044,"slots":[41,341,41,341,41,341,346,341,42,346,42,346]},"warp_table_address":5498544},"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":{"fishing_encounters":{"address":5611304,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765972,"land_encounters":{"address":5611220,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494904,"water_encounters":{"address":5611276,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":{"header_address":4766028,"land_encounters":{"address":5611164,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495180},"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":{"header_address":4766000,"land_encounters":{"address":5611108,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495084},"MAP_SKY_PILLAR_1F":{"header_address":4766868,"land_encounters":{"address":5612100,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498328},"MAP_SKY_PILLAR_2F":{"header_address":4766896,"warp_table_address":5498372},"MAP_SKY_PILLAR_3F":{"header_address":4766924,"land_encounters":{"address":5612232,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498408},"MAP_SKY_PILLAR_4F":{"header_address":4766952,"warp_table_address":5498452},"MAP_SKY_PILLAR_5F":{"header_address":4767008,"land_encounters":{"address":5612288,"slots":[322,42,42,322,319,378,378,319,319,359,359,359]},"warp_table_address":5498572},"MAP_SKY_PILLAR_ENTRANCE":{"header_address":4766812,"warp_table_address":5498232},"MAP_SKY_PILLAR_OUTSIDE":{"header_address":4766840,"warp_table_address":5498292},"MAP_SKY_PILLAR_TOP":{"header_address":4767036,"warp_table_address":5498656},"MAP_SLATEPORT_CITY":{"fishing_encounters":{"address":5611664,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758020,"warp_table_address":5429836,"water_encounters":{"address":5611636,"slots":[72,309,309,310,310]}},"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":{"header_address":4761212,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":{"header_address":4761184,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":{"header_address":4761156,"warp_table_address":5466624},"MAP_SLATEPORT_CITY_HARBOR":{"header_address":4761352,"warp_table_address":5468328},"MAP_SLATEPORT_CITY_HOUSE":{"header_address":4761380,"warp_table_address":5468492},"MAP_SLATEPORT_CITY_MART":{"header_address":4761464,"warp_table_address":5468856},"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":{"header_address":4761240,"warp_table_address":5466832},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":{"header_address":4761296,"warp_table_address":5467456},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":{"header_address":4761324,"warp_table_address":5467856},"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":{"header_address":4761408,"warp_table_address":5468600},"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":{"header_address":4761436,"warp_table_address":5468740},"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":{"header_address":4761268,"warp_table_address":5467084},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":{"header_address":4761100,"warp_table_address":5466360},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":{"header_address":4761128,"warp_table_address":5466476},"MAP_SOOTOPOLIS_CITY":{"fishing_encounters":{"address":5612184,"slots":[129,72,129,129,129,129,129,130,130,130]},"header_address":4758188,"warp_table_address":5433852,"water_encounters":{"address":5612156,"slots":[129,129,129,129,129]}},"MAP_SOOTOPOLIS_CITY_GYM_1F":{"header_address":4763480,"warp_table_address":5481892},"MAP_SOOTOPOLIS_CITY_GYM_B1F":{"header_address":4763508,"warp_table_address":5482200},"MAP_SOOTOPOLIS_CITY_HOUSE1":{"header_address":4763620,"warp_table_address":5482664},"MAP_SOOTOPOLIS_CITY_HOUSE2":{"header_address":4763648,"warp_table_address":5482724},"MAP_SOOTOPOLIS_CITY_HOUSE3":{"header_address":4763676,"warp_table_address":5482808},"MAP_SOOTOPOLIS_CITY_HOUSE4":{"header_address":4763704,"warp_table_address":5482916},"MAP_SOOTOPOLIS_CITY_HOUSE5":{"header_address":4763732,"warp_table_address":5483000},"MAP_SOOTOPOLIS_CITY_HOUSE6":{"header_address":4763760,"warp_table_address":5483060},"MAP_SOOTOPOLIS_CITY_HOUSE7":{"header_address":4763788,"warp_table_address":5483144},"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":{"header_address":4763816,"warp_table_address":5483228},"MAP_SOOTOPOLIS_CITY_MART":{"header_address":4763592,"warp_table_address":5482580},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":{"header_address":4763844,"warp_table_address":5483312},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":{"header_address":4763872,"warp_table_address":5483380},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":{"header_address":4763536,"warp_table_address":5482324},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":{"header_address":4763564,"warp_table_address":5482464},"MAP_SOUTHERN_ISLAND_EXTERIOR":{"header_address":4769640,"warp_table_address":5516780},"MAP_SOUTHERN_ISLAND_INTERIOR":{"header_address":4769668,"warp_table_address":5516876},"MAP_SS_TIDAL_CORRIDOR":{"header_address":4768828,"warp_table_address":5510992},"MAP_SS_TIDAL_LOWER_DECK":{"header_address":4768856,"warp_table_address":5511276},"MAP_SS_TIDAL_ROOMS":{"header_address":4768884,"warp_table_address":5511508},"MAP_TERRA_CAVE_END":{"header_address":4767596,"warp_table_address":5500392},"MAP_TERRA_CAVE_ENTRANCE":{"header_address":4767568,"warp_table_address":5500332},"MAP_TRADE_CENTER":{"header_address":4768380,"warp_table_address":5509944},"MAP_TRAINER_HILL_1F":{"header_address":4771096,"warp_table_address":5525172},"MAP_TRAINER_HILL_2F":{"header_address":4771124,"warp_table_address":5525208},"MAP_TRAINER_HILL_3F":{"header_address":4771152,"warp_table_address":5525244},"MAP_TRAINER_HILL_4F":{"header_address":4771180,"warp_table_address":5525280},"MAP_TRAINER_HILL_ELEVATOR":{"header_address":4771852,"warp_table_address":5526300},"MAP_TRAINER_HILL_ENTRANCE":{"header_address":4771068,"warp_table_address":5525100},"MAP_TRAINER_HILL_ROOF":{"header_address":4771208,"warp_table_address":5525340},"MAP_UNDERWATER_MARINE_CAVE":{"header_address":4767484,"warp_table_address":5500208},"MAP_UNDERWATER_ROUTE105":{"header_address":4759532,"warp_table_address":5457348},"MAP_UNDERWATER_ROUTE124":{"header_address":4759392,"warp_table_address":4160749568,"water_encounters":{"address":5612016,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE125":{"header_address":4759560,"warp_table_address":5457384},"MAP_UNDERWATER_ROUTE126":{"header_address":4759420,"warp_table_address":5457052,"water_encounters":{"address":5606268,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE127":{"header_address":4759448,"warp_table_address":5457176},"MAP_UNDERWATER_ROUTE128":{"header_address":4759476,"warp_table_address":5457260},"MAP_UNDERWATER_ROUTE129":{"header_address":4759504,"warp_table_address":5457312},"MAP_UNDERWATER_ROUTE134":{"header_address":4766588,"warp_table_address":5497540},"MAP_UNDERWATER_SEAFLOOR_CAVERN":{"header_address":4765384,"warp_table_address":5491744},"MAP_UNDERWATER_SEALED_CHAMBER":{"header_address":4766616,"warp_table_address":5497568},"MAP_UNDERWATER_SOOTOPOLIS_CITY":{"header_address":4764796,"warp_table_address":5486768},"MAP_UNION_ROOM":{"header_address":4769360,"warp_table_address":5514872},"MAP_UNUSED_CONTEST_HALL1":{"header_address":4768492,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL2":{"header_address":4768520,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL3":{"header_address":4768548,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL4":{"header_address":4768576,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL5":{"header_address":4768604,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL6":{"header_address":4768632,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN":{"header_address":4758384,"warp_table_address":5436044},"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760512,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760484,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760456,"warp_table_address":5463128},"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":{"header_address":4760652,"warp_table_address":5463928},"MAP_VERDANTURF_TOWN_HOUSE":{"header_address":4760680,"warp_table_address":5464012},"MAP_VERDANTURF_TOWN_MART":{"header_address":4760540,"warp_table_address":5463408},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":{"header_address":4760568,"warp_table_address":5463540},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":{"header_address":4760596,"warp_table_address":5463680},"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":{"header_address":4760624,"warp_table_address":5463844},"MAP_VICTORY_ROAD_1F":{"header_address":4765860,"land_encounters":{"address":5606156,"slots":[42,336,383,371,41,335,42,336,382,370,382,370]},"warp_table_address":5493852},"MAP_VICTORY_ROAD_B1F":{"header_address":4765888,"land_encounters":{"address":5610496,"slots":[42,336,383,383,42,336,42,336,383,355,383,355]},"rock_smash_encounters":{"address":5610552,"slots":[75,74,75,75,75]},"warp_table_address":5494460},"MAP_VICTORY_ROAD_B2F":{"fishing_encounters":{"address":5610664,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4765916,"land_encounters":{"address":5610580,"slots":[42,322,383,383,42,322,42,322,383,355,383,355]},"warp_table_address":5494704,"water_encounters":{"address":5610636,"slots":[42,42,42,42,42]}}},"misc_pokemon":[{"address":2572358,"species":385},{"address":2018148,"species":360},{"address":2323175,"species":101},{"address":2323252,"species":101},{"address":2581669,"species":317},{"address":2581574,"species":317},{"address":2581688,"species":317},{"address":2581593,"species":317},{"address":2581612,"species":317},{"address":2581631,"species":317},{"address":2581650,"species":317},{"address":2065036,"species":317},{"address":2386223,"species":185},{"address":2339323,"species":100},{"address":2339400,"species":100},{"address":2339477,"species":100}],"misc_ram_addresses":{"CB2_Overworld":134768624,"gArchipelagoDeathLinkQueued":33804824,"gArchipelagoReceivedItem":33804776,"gMain":50340544,"gPlayerParty":33703196,"gSaveBlock1Ptr":50355596,"gSaveBlock2Ptr":50355600},"misc_rom_addresses":{"gArchipelagoInfo":5912960,"gArchipelagoItemNames":5896457,"gArchipelagoNameTable":5905457,"gArchipelagoOptions":5895556,"gArchipelagoPlayerNames":5895607,"gBattleMoves":3281380,"gEvolutionTable":3318404,"gLevelUpLearnsets":3334884,"gRandomizedBerryTreeItems":5843560,"gRandomizedSoundTable":10155508,"gSpeciesInfo":3296744,"gTMHMLearnsets":3289780,"gTrainers":3230072,"gTutorMoves":6428060,"sFanfares":5422580,"sNewGamePCItems":6210444,"sStarterMon":6021752,"sTMHMMoves":6432208,"sTutorLearnsets":6428120},"species":[{"abilities":[0,0],"address":3296744,"base_stats":[0,0,0,0,0,0],"catch_rate":0,"evolutions":[],"friendship":0,"id":0,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3296772,"base_stats":[45,49,49,45,65,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":2}],"friendship":70,"id":1,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296800,"base_stats":[60,62,63,60,80,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":3}],"friendship":70,"id":2,"learnset":{"address":3308308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":38,"move_id":74},{"level":47,"move_id":235},{"level":56,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296828,"base_stats":[80,82,83,80,100,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":3,"learnset":{"address":3308338,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":1,"move_id":22},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":41,"move_id":74},{"level":53,"move_id":235},{"level":65,"move_id":76}]},"tmhm_learnset":"00E41E0886354730","types":[12,3]},{"abilities":[66,0],"address":3296856,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":5}],"friendship":70,"id":4,"learnset":{"address":3308368,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":19,"move_id":99},{"level":25,"move_id":184},{"level":31,"move_id":53},{"level":37,"move_id":163},{"level":43,"move_id":82},{"level":49,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296884,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":6}],"friendship":70,"id":5,"learnset":{"address":3308394,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":41,"move_id":163},{"level":48,"move_id":82},{"level":55,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296912,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":6,"learnset":{"address":3308420,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":1,"move_id":108},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":36,"move_id":17},{"level":44,"move_id":163},{"level":54,"move_id":82},{"level":64,"move_id":83}]},"tmhm_learnset":"00AE5EA4CE514633","types":[10,2]},{"abilities":[67,0],"address":3296940,"base_stats":[44,48,65,43,50,64],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":8}],"friendship":70,"id":7,"learnset":{"address":3308448,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":18,"move_id":44},{"level":23,"move_id":229},{"level":28,"move_id":182},{"level":33,"move_id":240},{"level":40,"move_id":130},{"level":47,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296968,"base_stats":[59,63,80,58,65,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":9}],"friendship":70,"id":8,"learnset":{"address":3308478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":37,"move_id":240},{"level":45,"move_id":130},{"level":53,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296996,"base_stats":[79,83,100,78,85,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":9,"learnset":{"address":3308508,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":1,"move_id":110},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":42,"move_id":240},{"level":55,"move_id":130},{"level":68,"move_id":56}]},"tmhm_learnset":"03B01E00CE537275","types":[11,11]},{"abilities":[19,0],"address":3297024,"base_stats":[45,30,35,45,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":11}],"friendship":70,"id":10,"learnset":{"address":3308538,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3297052,"base_stats":[50,20,55,30,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":12}],"friendship":70,"id":11,"learnset":{"address":3308548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[14,0],"address":3297080,"base_stats":[60,45,50,70,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":12,"learnset":{"address":3308560,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":77},{"level":14,"move_id":78},{"level":15,"move_id":79},{"level":18,"move_id":48},{"level":23,"move_id":18},{"level":28,"move_id":16},{"level":34,"move_id":60},{"level":40,"move_id":219},{"level":47,"move_id":318}]},"tmhm_learnset":"0040BE80B43F4620","types":[6,2]},{"abilities":[19,0],"address":3297108,"base_stats":[40,35,30,50,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":14}],"friendship":70,"id":13,"learnset":{"address":3308590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[61,0],"address":3297136,"base_stats":[45,25,50,35,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":15}],"friendship":70,"id":14,"learnset":{"address":3308600,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[68,0],"address":3297164,"base_stats":[65,80,40,75,45,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":15,"learnset":{"address":3308612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":31},{"level":10,"move_id":31},{"level":15,"move_id":116},{"level":20,"move_id":41},{"level":25,"move_id":99},{"level":30,"move_id":228},{"level":35,"move_id":42},{"level":40,"move_id":97},{"level":45,"move_id":283}]},"tmhm_learnset":"00843E88C4354620","types":[6,3]},{"abilities":[51,0],"address":3297192,"base_stats":[40,45,40,56,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":17}],"friendship":70,"id":16,"learnset":{"address":3308638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":19,"move_id":18},{"level":25,"move_id":17},{"level":31,"move_id":297},{"level":39,"move_id":97},{"level":47,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297220,"base_stats":[63,60,55,71,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":18}],"friendship":70,"id":17,"learnset":{"address":3308664,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":43,"move_id":97},{"level":52,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297248,"base_stats":[83,80,75,91,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":18,"learnset":{"address":3308690,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":1,"move_id":98},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":48,"move_id":97},{"level":62,"move_id":119}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[50,62],"address":3297276,"base_stats":[30,56,35,72,25,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":20}],"friendship":70,"id":19,"learnset":{"address":3308716,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":116},{"level":27,"move_id":228},{"level":34,"move_id":162},{"level":41,"move_id":283}]},"tmhm_learnset":"00843E02ADD33E20","types":[0,0]},{"abilities":[50,62],"address":3297304,"base_stats":[55,81,60,97,50,70],"catch_rate":127,"evolutions":[],"friendship":70,"id":20,"learnset":{"address":3308738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":184},{"level":30,"move_id":228},{"level":40,"move_id":162},{"level":50,"move_id":283}]},"tmhm_learnset":"00A43E02ADD37E30","types":[0,0]},{"abilities":[51,0],"address":3297332,"base_stats":[40,60,30,70,31,31],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":22}],"friendship":70,"id":21,"learnset":{"address":3308760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":19,"move_id":228},{"level":25,"move_id":332},{"level":31,"move_id":119},{"level":37,"move_id":65},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297360,"base_stats":[65,90,65,100,61,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":22,"learnset":{"address":3308784,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":43},{"level":1,"move_id":31},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":26,"move_id":228},{"level":32,"move_id":119},{"level":40,"move_id":65},{"level":47,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[22,61],"address":3297388,"base_stats":[35,60,44,55,40,54],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":24}],"friendship":70,"id":23,"learnset":{"address":3308806,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":25,"move_id":103},{"level":32,"move_id":51},{"level":37,"move_id":254},{"level":37,"move_id":256},{"level":37,"move_id":255},{"level":44,"move_id":114}]},"tmhm_learnset":"00213F088E570620","types":[3,3]},{"abilities":[22,61],"address":3297416,"base_stats":[60,85,69,80,65,79],"catch_rate":90,"evolutions":[],"friendship":70,"id":24,"learnset":{"address":3308834,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":40},{"level":1,"move_id":44},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":28,"move_id":103},{"level":38,"move_id":51},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255},{"level":56,"move_id":114}]},"tmhm_learnset":"00213F088E574620","types":[3,3]},{"abilities":[9,0],"address":3297444,"base_stats":[35,55,30,90,50,40],"catch_rate":190,"evolutions":[{"method":"ITEM","param":96,"species":26}],"friendship":70,"id":25,"learnset":{"address":3308862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":45},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":98},{"level":15,"move_id":104},{"level":20,"move_id":21},{"level":26,"move_id":85},{"level":33,"move_id":97},{"level":41,"move_id":87},{"level":50,"move_id":113}]},"tmhm_learnset":"00E01E02CDD38221","types":[13,13]},{"abilities":[9,0],"address":3297472,"base_stats":[60,90,55,100,90,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":26,"learnset":{"address":3308890,"moves":[{"level":1,"move_id":84},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":1,"move_id":85}]},"tmhm_learnset":"00E03E02CDD3C221","types":[13,13]},{"abilities":[8,0],"address":3297500,"base_stats":[50,75,85,40,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":28}],"friendship":70,"id":27,"learnset":{"address":3308900,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":23,"move_id":163},{"level":30,"move_id":129},{"level":37,"move_id":154},{"level":45,"move_id":328},{"level":53,"move_id":201}]},"tmhm_learnset":"00A43ED0CE510621","types":[4,4]},{"abilities":[8,0],"address":3297528,"base_stats":[75,100,110,65,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":28,"learnset":{"address":3308926,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":28},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":24,"move_id":163},{"level":33,"move_id":129},{"level":42,"move_id":154},{"level":52,"move_id":328},{"level":62,"move_id":201}]},"tmhm_learnset":"00A43ED0CE514621","types":[4,4]},{"abilities":[38,0],"address":3297556,"base_stats":[55,47,52,41,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":30}],"friendship":70,"id":29,"learnset":{"address":3308952,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":44},{"level":23,"move_id":270},{"level":30,"move_id":154},{"level":38,"move_id":260},{"level":47,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297584,"base_stats":[70,62,67,56,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":31}],"friendship":70,"id":30,"learnset":{"address":3308978,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":44},{"level":26,"move_id":270},{"level":34,"move_id":154},{"level":43,"move_id":260},{"level":53,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297612,"base_stats":[90,82,87,76,75,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":31,"learnset":{"address":3309004,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":34}]},"tmhm_learnset":"00B43FFEEFD37E35","types":[3,4]},{"abilities":[38,0],"address":3297640,"base_stats":[46,57,40,50,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":33}],"friendship":70,"id":32,"learnset":{"address":3309016,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":30},{"level":23,"move_id":270},{"level":30,"move_id":31},{"level":38,"move_id":260},{"level":47,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297668,"base_stats":[61,72,57,65,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":34}],"friendship":70,"id":33,"learnset":{"address":3309042,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":30},{"level":26,"move_id":270},{"level":34,"move_id":31},{"level":43,"move_id":260},{"level":53,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297696,"base_stats":[81,92,77,85,85,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":34,"learnset":{"address":3309068,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":116},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":37}]},"tmhm_learnset":"00B43F7EEFD37E35","types":[3,4]},{"abilities":[56,0],"address":3297724,"base_stats":[70,45,48,35,60,65],"catch_rate":150,"evolutions":[{"method":"ITEM","param":94,"species":36}],"friendship":140,"id":35,"learnset":{"address":3309080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":227},{"level":9,"move_id":47},{"level":13,"move_id":3},{"level":17,"move_id":266},{"level":21,"move_id":107},{"level":25,"move_id":111},{"level":29,"move_id":118},{"level":33,"move_id":322},{"level":37,"move_id":236},{"level":41,"move_id":113},{"level":45,"move_id":309}]},"tmhm_learnset":"00611E27FDFBB62D","types":[0,0]},{"abilities":[56,0],"address":3297752,"base_stats":[95,70,73,60,85,90],"catch_rate":25,"evolutions":[],"friendship":140,"id":36,"learnset":{"address":3309112,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":3},{"level":1,"move_id":107},{"level":1,"move_id":118}]},"tmhm_learnset":"00611E27FDFBF62D","types":[0,0]},{"abilities":[18,0],"address":3297780,"base_stats":[38,41,40,65,50,65],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":38}],"friendship":70,"id":37,"learnset":{"address":3309122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":5,"move_id":39},{"level":9,"move_id":46},{"level":13,"move_id":98},{"level":17,"move_id":261},{"level":21,"move_id":109},{"level":25,"move_id":286},{"level":29,"move_id":53},{"level":33,"move_id":219},{"level":37,"move_id":288},{"level":41,"move_id":83}]},"tmhm_learnset":"00021E248C590630","types":[10,10]},{"abilities":[18,0],"address":3297808,"base_stats":[73,76,75,100,81,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":38,"learnset":{"address":3309152,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":98},{"level":1,"move_id":109},{"level":1,"move_id":219},{"level":45,"move_id":83}]},"tmhm_learnset":"00021E248C594630","types":[10,10]},{"abilities":[56,0],"address":3297836,"base_stats":[115,45,20,20,45,25],"catch_rate":170,"evolutions":[{"method":"ITEM","param":94,"species":40}],"friendship":70,"id":39,"learnset":{"address":3309164,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":50},{"level":19,"move_id":205},{"level":24,"move_id":3},{"level":29,"move_id":156},{"level":34,"move_id":34},{"level":39,"move_id":102},{"level":44,"move_id":304},{"level":49,"move_id":38}]},"tmhm_learnset":"00611E27FDBBB625","types":[0,0]},{"abilities":[56,0],"address":3297864,"base_stats":[140,70,45,45,75,50],"catch_rate":50,"evolutions":[],"friendship":70,"id":40,"learnset":{"address":3309194,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":50},{"level":1,"move_id":111},{"level":1,"move_id":3}]},"tmhm_learnset":"00611E27FDBBF625","types":[0,0]},{"abilities":[39,0],"address":3297892,"base_stats":[40,45,35,55,30,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":42}],"friendship":70,"id":41,"learnset":{"address":3309204,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":141},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":26,"move_id":109},{"level":31,"move_id":314},{"level":36,"move_id":212},{"level":41,"move_id":305},{"level":46,"move_id":114}]},"tmhm_learnset":"00017F88A4170E20","types":[3,2]},{"abilities":[39,0],"address":3297920,"base_stats":[75,80,70,90,65,75],"catch_rate":90,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":169}],"friendship":70,"id":42,"learnset":{"address":3309232,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00017F88A4174E20","types":[3,2]},{"abilities":[34,0],"address":3297948,"base_stats":[45,50,55,30,75,65],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":44}],"friendship":70,"id":43,"learnset":{"address":3309260,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":23,"move_id":51},{"level":32,"move_id":236},{"level":39,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3297976,"base_stats":[60,65,70,40,85,75],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":45},{"method":"ITEM","param":93,"species":182}],"friendship":70,"id":44,"learnset":{"address":3309284,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":77},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":24,"move_id":51},{"level":35,"move_id":236},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298004,"base_stats":[75,80,85,50,100,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":45,"learnset":{"address":3309308,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":312},{"level":1,"move_id":78},{"level":1,"move_id":72},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884354720","types":[12,3]},{"abilities":[27,0],"address":3298032,"base_stats":[35,70,55,25,45,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":24,"species":47}],"friendship":70,"id":46,"learnset":{"address":3309320,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":25,"move_id":147},{"level":31,"move_id":163},{"level":37,"move_id":74},{"level":43,"move_id":202},{"level":49,"move_id":312}]},"tmhm_learnset":"00C43E888C350720","types":[6,12]},{"abilities":[27,0],"address":3298060,"base_stats":[60,95,80,30,60,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":47,"learnset":{"address":3309346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":78},{"level":1,"move_id":77},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":27,"move_id":147},{"level":35,"move_id":163},{"level":43,"move_id":74},{"level":51,"move_id":202},{"level":59,"move_id":312}]},"tmhm_learnset":"00C43E888C354720","types":[6,12]},{"abilities":[14,0],"address":3298088,"base_stats":[60,55,50,45,40,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":49}],"friendship":70,"id":48,"learnset":{"address":3309372,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":33,"move_id":60},{"level":36,"move_id":79},{"level":41,"move_id":94}]},"tmhm_learnset":"0040BE0894350620","types":[6,3]},{"abilities":[19,0],"address":3298116,"base_stats":[70,65,60,90,90,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":49,"learnset":{"address":3309398,"moves":[{"level":1,"move_id":318},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":1,"move_id":48},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":31,"move_id":16},{"level":36,"move_id":60},{"level":42,"move_id":79},{"level":52,"move_id":94}]},"tmhm_learnset":"0040BE8894354620","types":[6,3]},{"abilities":[8,71],"address":3298144,"base_stats":[10,55,25,95,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":26,"species":51}],"friendship":70,"id":50,"learnset":{"address":3309428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":33,"move_id":163},{"level":41,"move_id":89},{"level":49,"move_id":90}]},"tmhm_learnset":"00843EC88E110620","types":[4,4]},{"abilities":[8,71],"address":3298172,"base_stats":[35,80,50,120,50,70],"catch_rate":50,"evolutions":[],"friendship":70,"id":51,"learnset":{"address":3309452,"moves":[{"level":1,"move_id":161},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":1,"move_id":45},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":26,"move_id":328},{"level":38,"move_id":163},{"level":51,"move_id":89},{"level":64,"move_id":90}]},"tmhm_learnset":"00843EC88E114620","types":[4,4]},{"abilities":[53,0],"address":3298200,"base_stats":[40,45,35,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":28,"species":53}],"friendship":70,"id":52,"learnset":{"address":3309478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":28,"move_id":185},{"level":35,"move_id":103},{"level":41,"move_id":154},{"level":46,"move_id":163},{"level":50,"move_id":252}]},"tmhm_learnset":"00453F82ADD30E24","types":[0,0]},{"abilities":[7,0],"address":3298228,"base_stats":[65,70,60,115,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":53,"learnset":{"address":3309502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":44},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":29,"move_id":185},{"level":38,"move_id":103},{"level":46,"move_id":154},{"level":53,"move_id":163},{"level":59,"move_id":252}]},"tmhm_learnset":"00453F82ADD34E34","types":[0,0]},{"abilities":[6,13],"address":3298256,"base_stats":[50,52,48,55,65,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":33,"species":55}],"friendship":70,"id":54,"learnset":{"address":3309526,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":40,"move_id":154},{"level":50,"move_id":56}]},"tmhm_learnset":"03F01E80CC53326D","types":[11,11]},{"abilities":[6,13],"address":3298284,"base_stats":[80,82,78,85,95,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":55,"learnset":{"address":3309550,"moves":[{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":50},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":44,"move_id":154},{"level":58,"move_id":56}]},"tmhm_learnset":"03F01E80CC53726D","types":[11,11]},{"abilities":[72,0],"address":3298312,"base_stats":[40,80,35,70,35,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":57}],"friendship":70,"id":56,"learnset":{"address":3309574,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":33,"move_id":69},{"level":39,"move_id":238},{"level":45,"move_id":103},{"level":51,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD30EA1","types":[1,1]},{"abilities":[72,0],"address":3298340,"base_stats":[65,105,60,95,60,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":57,"learnset":{"address":3309600,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":67},{"level":1,"move_id":99},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":28,"move_id":99},{"level":36,"move_id":69},{"level":45,"move_id":238},{"level":54,"move_id":103},{"level":63,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD34EA1","types":[1,1]},{"abilities":[22,18],"address":3298368,"base_stats":[55,70,45,60,70,50],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":59}],"friendship":70,"id":58,"learnset":{"address":3309628,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":7,"move_id":52},{"level":13,"move_id":43},{"level":19,"move_id":316},{"level":25,"move_id":36},{"level":31,"move_id":172},{"level":37,"move_id":270},{"level":43,"move_id":97},{"level":49,"move_id":53}]},"tmhm_learnset":"00A23EA48C510630","types":[10,10]},{"abilities":[22,18],"address":3298396,"base_stats":[90,110,80,95,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":59,"learnset":{"address":3309654,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":1,"move_id":52},{"level":1,"move_id":316},{"level":49,"move_id":245}]},"tmhm_learnset":"00A23EA48C514630","types":[10,10]},{"abilities":[11,6],"address":3298424,"base_stats":[40,50,40,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":61}],"friendship":70,"id":60,"learnset":{"address":3309666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":25,"move_id":240},{"level":31,"move_id":34},{"level":37,"move_id":187},{"level":43,"move_id":56}]},"tmhm_learnset":"03103E009C133264","types":[11,11]},{"abilities":[11,6],"address":3298452,"base_stats":[65,65,65,90,50,50],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":62},{"method":"ITEM","param":187,"species":186}],"friendship":70,"id":61,"learnset":{"address":3309690,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":95},{"level":1,"move_id":55},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":27,"move_id":240},{"level":35,"move_id":34},{"level":43,"move_id":187},{"level":51,"move_id":56}]},"tmhm_learnset":"03B03E00DE133265","types":[11,11]},{"abilities":[11,6],"address":3298480,"base_stats":[90,85,95,70,70,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":62,"learnset":{"address":3309714,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":66},{"level":35,"move_id":66},{"level":51,"move_id":170}]},"tmhm_learnset":"03B03E40DE1372E5","types":[11,1]},{"abilities":[28,39],"address":3298508,"base_stats":[25,20,15,90,105,55],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":16,"species":64}],"friendship":70,"id":63,"learnset":{"address":3309728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":100}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298536,"base_stats":[40,35,30,105,120,70],"catch_rate":100,"evolutions":[{"method":"LEVEL","param":37,"species":65}],"friendship":70,"id":64,"learnset":{"address":3309738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":272},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298564,"base_stats":[55,50,45,120,135,85],"catch_rate":50,"evolutions":[],"friendship":70,"id":65,"learnset":{"address":3309766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":347},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45BCE29","types":[14,14]},{"abilities":[62,0],"address":3298592,"base_stats":[70,80,50,35,35,35],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":28,"species":67}],"friendship":70,"id":66,"learnset":{"address":3309794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":31,"move_id":233},{"level":37,"move_id":66},{"level":40,"move_id":238},{"level":43,"move_id":184},{"level":49,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298620,"base_stats":[80,100,70,45,50,60],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":68}],"friendship":70,"id":67,"learnset":{"address":3309824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298648,"base_stats":[90,130,80,55,65,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":68,"learnset":{"address":3309854,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1346A1","types":[1,1]},{"abilities":[34,0],"address":3298676,"base_stats":[50,75,35,40,70,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":70}],"friendship":70,"id":69,"learnset":{"address":3309884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":23,"move_id":51},{"level":30,"move_id":230},{"level":37,"move_id":75},{"level":45,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298704,"base_stats":[65,90,50,55,85,45],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":71}],"friendship":70,"id":70,"learnset":{"address":3309912,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":1,"move_id":74},{"level":1,"move_id":35},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":24,"move_id":51},{"level":33,"move_id":230},{"level":42,"move_id":75},{"level":54,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298732,"base_stats":[80,105,65,70,100,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":71,"learnset":{"address":3309940,"moves":[{"level":1,"move_id":22},{"level":1,"move_id":79},{"level":1,"move_id":230},{"level":1,"move_id":75}]},"tmhm_learnset":"00443E0884354720","types":[12,3]},{"abilities":[29,64],"address":3298760,"base_stats":[40,40,35,70,50,100],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":73}],"friendship":70,"id":72,"learnset":{"address":3309950,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":36,"move_id":112},{"level":43,"move_id":103},{"level":49,"move_id":56}]},"tmhm_learnset":"03143E0884173264","types":[11,3]},{"abilities":[29,64],"address":3298788,"base_stats":[80,70,65,100,80,120],"catch_rate":60,"evolutions":[],"friendship":70,"id":73,"learnset":{"address":3309976,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":48},{"level":1,"move_id":132},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":38,"move_id":112},{"level":47,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03143E0884177264","types":[11,3]},{"abilities":[69,5],"address":3298816,"base_stats":[40,80,100,20,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":75}],"friendship":70,"id":74,"learnset":{"address":3310002,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":26,"move_id":205},{"level":31,"move_id":350},{"level":36,"move_id":89},{"level":41,"move_id":153},{"level":46,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298844,"base_stats":[55,95,115,35,45,45],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":37,"species":76}],"friendship":70,"id":75,"learnset":{"address":3310030,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298872,"base_stats":[80,110,130,45,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":76,"learnset":{"address":3310058,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE114631","types":[5,4]},{"abilities":[50,18],"address":3298900,"base_stats":[50,85,55,90,65,65],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":40,"species":78}],"friendship":70,"id":77,"learnset":{"address":3310086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":45,"move_id":340},{"level":53,"move_id":126}]},"tmhm_learnset":"00221E2484710620","types":[10,10]},{"abilities":[50,18],"address":3298928,"base_stats":[65,100,70,105,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":78,"learnset":{"address":3310114,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":52},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":40,"move_id":31},{"level":50,"move_id":340},{"level":63,"move_id":126}]},"tmhm_learnset":"00221E2484714620","types":[10,10]},{"abilities":[12,20],"address":3298956,"base_stats":[90,65,65,15,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":80},{"method":"ITEM","param":187,"species":199}],"friendship":70,"id":79,"learnset":{"address":3310144,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":133},{"level":48,"move_id":94}]},"tmhm_learnset":"02709E24BE5B366C","types":[11,14]},{"abilities":[12,20],"address":3298984,"base_stats":[95,75,110,30,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":80,"learnset":{"address":3310168,"moves":[{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":37,"move_id":110},{"level":46,"move_id":133},{"level":54,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[42,5],"address":3299012,"base_stats":[25,35,70,45,95,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":82}],"friendship":70,"id":81,"learnset":{"address":3310194,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":32,"move_id":199},{"level":38,"move_id":129},{"level":44,"move_id":103},{"level":50,"move_id":192}]},"tmhm_learnset":"00400E0385930620","types":[13,8]},{"abilities":[42,5],"address":3299040,"base_stats":[50,60,95,70,120,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":82,"learnset":{"address":3310222,"moves":[{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":1,"move_id":84},{"level":1,"move_id":48},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":35,"move_id":199},{"level":44,"move_id":161},{"level":53,"move_id":103},{"level":62,"move_id":192}]},"tmhm_learnset":"00400E0385934620","types":[13,8]},{"abilities":[51,39],"address":3299068,"base_stats":[52,65,55,60,58,62],"catch_rate":45,"evolutions":[],"friendship":70,"id":83,"learnset":{"address":3310250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":6,"move_id":28},{"level":11,"move_id":43},{"level":16,"move_id":31},{"level":21,"move_id":282},{"level":26,"move_id":210},{"level":31,"move_id":14},{"level":36,"move_id":97},{"level":41,"move_id":163},{"level":46,"move_id":206}]},"tmhm_learnset":"000C7E8084510620","types":[0,2]},{"abilities":[50,48],"address":3299096,"base_stats":[35,85,45,75,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":85}],"friendship":70,"id":84,"learnset":{"address":3310278,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":33,"move_id":253},{"level":37,"move_id":65},{"level":45,"move_id":97}]},"tmhm_learnset":"00087E8084110620","types":[0,2]},{"abilities":[50,48],"address":3299124,"base_stats":[60,110,70,100,60,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":85,"learnset":{"address":3310302,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":228},{"level":1,"move_id":31},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":38,"move_id":253},{"level":47,"move_id":65},{"level":60,"move_id":97}]},"tmhm_learnset":"00087F8084114E20","types":[0,2]},{"abilities":[47,0],"address":3299152,"base_stats":[65,45,55,45,45,70],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":34,"species":87}],"friendship":70,"id":86,"learnset":{"address":3310326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":29},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":37,"move_id":36},{"level":41,"move_id":58},{"level":49,"move_id":219}]},"tmhm_learnset":"03103E00841B3264","types":[11,11]},{"abilities":[47,0],"address":3299180,"base_stats":[90,70,80,70,70,95],"catch_rate":75,"evolutions":[],"friendship":70,"id":87,"learnset":{"address":3310350,"moves":[{"level":1,"move_id":29},{"level":1,"move_id":45},{"level":1,"move_id":196},{"level":1,"move_id":62},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":34,"move_id":329},{"level":42,"move_id":36},{"level":51,"move_id":58},{"level":64,"move_id":219}]},"tmhm_learnset":"03103E00841B7264","types":[11,15]},{"abilities":[1,60],"address":3299208,"base_stats":[80,80,50,25,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":89}],"friendship":70,"id":88,"learnset":{"address":3310376,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":43,"move_id":188},{"level":53,"move_id":262}]},"tmhm_learnset":"00003F6E8D970E20","types":[3,3]},{"abilities":[1,60],"address":3299236,"base_stats":[105,105,75,50,65,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":89,"learnset":{"address":3310402,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":47,"move_id":188},{"level":61,"move_id":262}]},"tmhm_learnset":"00A03F6ECD974E21","types":[3,3]},{"abilities":[75,0],"address":3299264,"base_stats":[30,65,100,40,45,25],"catch_rate":190,"evolutions":[{"method":"ITEM","param":97,"species":91}],"friendship":70,"id":90,"learnset":{"address":3310428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":110},{"level":9,"move_id":48},{"level":17,"move_id":62},{"level":25,"move_id":182},{"level":33,"move_id":43},{"level":41,"move_id":128},{"level":49,"move_id":58}]},"tmhm_learnset":"02101E0084133264","types":[11,11]},{"abilities":[75,0],"address":3299292,"base_stats":[50,95,180,70,85,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":91,"learnset":{"address":3310450,"moves":[{"level":1,"move_id":110},{"level":1,"move_id":48},{"level":1,"move_id":62},{"level":1,"move_id":182},{"level":33,"move_id":191},{"level":41,"move_id":131}]},"tmhm_learnset":"02101F0084137264","types":[11,15]},{"abilities":[26,0],"address":3299320,"base_stats":[30,35,30,80,100,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":93}],"friendship":70,"id":92,"learnset":{"address":3310464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":28,"move_id":109},{"level":33,"move_id":138},{"level":36,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299348,"base_stats":[45,50,45,95,115,55],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":94}],"friendship":70,"id":93,"learnset":{"address":3310488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299376,"base_stats":[60,65,60,110,130,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":94,"learnset":{"address":3310514,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"00A1BF08F5974E21","types":[7,3]},{"abilities":[69,5],"address":3299404,"base_stats":[35,45,160,70,30,45],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":208}],"friendship":70,"id":95,"learnset":{"address":3310540,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":328},{"level":57,"move_id":38}]},"tmhm_learnset":"00A01F508E510E30","types":[5,4]},{"abilities":[15,0],"address":3299432,"base_stats":[60,48,45,42,43,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":26,"species":97}],"friendship":70,"id":96,"learnset":{"address":3310568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":31,"move_id":139},{"level":36,"move_id":96},{"level":40,"move_id":94},{"level":43,"move_id":244},{"level":45,"move_id":248}]},"tmhm_learnset":"0041BF01F41B8E29","types":[14,14]},{"abilities":[15,0],"address":3299460,"base_stats":[85,73,70,67,73,115],"catch_rate":75,"evolutions":[],"friendship":70,"id":97,"learnset":{"address":3310594,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":1,"move_id":50},{"level":1,"move_id":93},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":33,"move_id":139},{"level":40,"move_id":96},{"level":49,"move_id":94},{"level":55,"move_id":244},{"level":60,"move_id":248}]},"tmhm_learnset":"0041BF01F41BCE29","types":[14,14]},{"abilities":[52,75],"address":3299488,"base_stats":[30,105,90,50,25,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":28,"species":99}],"friendship":70,"id":98,"learnset":{"address":3310620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":34,"move_id":12},{"level":41,"move_id":182},{"level":45,"move_id":152}]},"tmhm_learnset":"02B43E408C133264","types":[11,11]},{"abilities":[52,75],"address":3299516,"base_stats":[55,130,115,75,50,50],"catch_rate":60,"evolutions":[],"friendship":70,"id":99,"learnset":{"address":3310646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":43},{"level":1,"move_id":11},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":38,"move_id":12},{"level":49,"move_id":182},{"level":57,"move_id":152}]},"tmhm_learnset":"02B43E408C137264","types":[11,11]},{"abilities":[43,9],"address":3299544,"base_stats":[40,30,50,100,55,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":101}],"friendship":70,"id":100,"learnset":{"address":3310672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":32,"move_id":205},{"level":37,"move_id":113},{"level":42,"move_id":129},{"level":46,"move_id":153},{"level":49,"move_id":243}]},"tmhm_learnset":"00402F0285938A20","types":[13,13]},{"abilities":[43,9],"address":3299572,"base_stats":[60,50,70,140,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":101,"learnset":{"address":3310700,"moves":[{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":1,"move_id":49},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":34,"move_id":205},{"level":41,"move_id":113},{"level":48,"move_id":129},{"level":54,"move_id":153},{"level":59,"move_id":243}]},"tmhm_learnset":"00402F028593CA20","types":[13,13]},{"abilities":[34,0],"address":3299600,"base_stats":[60,40,80,40,60,45],"catch_rate":90,"evolutions":[{"method":"ITEM","param":98,"species":103}],"friendship":70,"id":102,"learnset":{"address":3310728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":253},{"level":1,"move_id":95},{"level":7,"move_id":115},{"level":13,"move_id":73},{"level":19,"move_id":93},{"level":25,"move_id":78},{"level":31,"move_id":77},{"level":37,"move_id":79},{"level":43,"move_id":76}]},"tmhm_learnset":"0060BE0994358720","types":[12,14]},{"abilities":[34,0],"address":3299628,"base_stats":[95,95,85,55,125,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":103,"learnset":{"address":3310752,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":95},{"level":1,"move_id":93},{"level":19,"move_id":23},{"level":31,"move_id":121}]},"tmhm_learnset":"0060BE099435C720","types":[12,14]},{"abilities":[69,31],"address":3299656,"base_stats":[50,50,95,35,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":105}],"friendship":70,"id":104,"learnset":{"address":3310766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":125},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":29,"move_id":99},{"level":33,"move_id":206},{"level":37,"move_id":37},{"level":41,"move_id":198},{"level":45,"move_id":38}]},"tmhm_learnset":"00A03EF4CE513621","types":[4,4]},{"abilities":[69,31],"address":3299684,"base_stats":[60,80,110,45,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":105,"learnset":{"address":3310798,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":125},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":32,"move_id":99},{"level":39,"move_id":206},{"level":46,"move_id":37},{"level":53,"move_id":198},{"level":61,"move_id":38}]},"tmhm_learnset":"00A03EF4CE517621","types":[4,4]},{"abilities":[7,0],"address":3299712,"base_stats":[50,120,53,87,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":106,"learnset":{"address":3310830,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":24},{"level":6,"move_id":96},{"level":11,"move_id":27},{"level":16,"move_id":26},{"level":20,"move_id":280},{"level":21,"move_id":116},{"level":26,"move_id":136},{"level":31,"move_id":170},{"level":36,"move_id":193},{"level":41,"move_id":203},{"level":46,"move_id":25},{"level":51,"move_id":179}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[51,0],"address":3299740,"base_stats":[50,105,79,76,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":107,"learnset":{"address":3310862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":4},{"level":7,"move_id":97},{"level":13,"move_id":228},{"level":20,"move_id":183},{"level":26,"move_id":9},{"level":26,"move_id":8},{"level":26,"move_id":7},{"level":32,"move_id":327},{"level":38,"move_id":5},{"level":44,"move_id":197},{"level":50,"move_id":68}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[20,12],"address":3299768,"base_stats":[90,55,75,30,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":108,"learnset":{"address":3310892,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":122},{"level":7,"move_id":48},{"level":12,"move_id":111},{"level":18,"move_id":282},{"level":23,"move_id":23},{"level":29,"move_id":35},{"level":34,"move_id":50},{"level":40,"move_id":21},{"level":45,"move_id":103},{"level":51,"move_id":287}]},"tmhm_learnset":"00B43E76EFF37625","types":[0,0]},{"abilities":[26,0],"address":3299796,"base_stats":[40,65,95,35,60,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":35,"species":110}],"friendship":70,"id":109,"learnset":{"address":3310920,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":41,"move_id":153},{"level":45,"move_id":194},{"level":49,"move_id":262}]},"tmhm_learnset":"00403F2EA5930E20","types":[3,3]},{"abilities":[26,0],"address":3299824,"base_stats":[65,90,120,60,85,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":110,"learnset":{"address":3310946,"moves":[{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":1,"move_id":123},{"level":1,"move_id":120},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":44,"move_id":153},{"level":51,"move_id":194},{"level":58,"move_id":262}]},"tmhm_learnset":"00403F2EA5934E20","types":[3,3]},{"abilities":[31,69],"address":3299852,"base_stats":[80,85,95,25,30,30],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":42,"species":112}],"friendship":70,"id":111,"learnset":{"address":3310972,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":43,"move_id":36},{"level":52,"move_id":89},{"level":57,"move_id":224}]},"tmhm_learnset":"00A03E768FD33630","types":[4,5]},{"abilities":[31,69],"address":3299880,"base_stats":[105,130,120,40,45,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":112,"learnset":{"address":3310998,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":1,"move_id":23},{"level":1,"move_id":31},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":46,"move_id":36},{"level":58,"move_id":89},{"level":66,"move_id":224}]},"tmhm_learnset":"00B43E76CFD37631","types":[4,5]},{"abilities":[30,32],"address":3299908,"base_stats":[250,5,5,50,35,105],"catch_rate":30,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":242}],"friendship":140,"id":113,"learnset":{"address":3311024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":287},{"level":13,"move_id":135},{"level":17,"move_id":3},{"level":23,"move_id":107},{"level":29,"move_id":47},{"level":35,"move_id":121},{"level":41,"move_id":111},{"level":49,"move_id":113},{"level":57,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[34,0],"address":3299936,"base_stats":[65,55,115,60,100,40],"catch_rate":45,"evolutions":[],"friendship":70,"id":114,"learnset":{"address":3311054,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":275},{"level":1,"move_id":132},{"level":4,"move_id":79},{"level":10,"move_id":71},{"level":13,"move_id":74},{"level":19,"move_id":77},{"level":22,"move_id":22},{"level":28,"move_id":20},{"level":31,"move_id":72},{"level":37,"move_id":78},{"level":40,"move_id":21},{"level":46,"move_id":321}]},"tmhm_learnset":"00C43E0884354720","types":[12,12]},{"abilities":[48,0],"address":3299964,"base_stats":[105,95,80,90,40,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":115,"learnset":{"address":3311084,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":4},{"level":1,"move_id":43},{"level":7,"move_id":44},{"level":13,"move_id":39},{"level":19,"move_id":252},{"level":25,"move_id":5},{"level":31,"move_id":99},{"level":37,"move_id":203},{"level":43,"move_id":146},{"level":49,"move_id":179}]},"tmhm_learnset":"00B43EF6EFF37675","types":[0,0]},{"abilities":[33,0],"address":3299992,"base_stats":[30,40,70,60,70,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":32,"species":117}],"friendship":70,"id":116,"learnset":{"address":3311110,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":36,"move_id":97},{"level":43,"move_id":56},{"level":50,"move_id":349}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[38,0],"address":3300020,"base_stats":[55,65,95,85,95,45],"catch_rate":75,"evolutions":[{"method":"ITEM","param":201,"species":230}],"friendship":70,"id":117,"learnset":{"address":3311134,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[33,41],"address":3300048,"base_stats":[45,67,60,63,35,50],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":119}],"friendship":70,"id":118,"learnset":{"address":3311158,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":38,"move_id":127},{"level":43,"move_id":32},{"level":52,"move_id":97}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,41],"address":3300076,"base_stats":[80,92,65,68,65,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":119,"learnset":{"address":3311182,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":1,"move_id":48},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":41,"move_id":127},{"level":49,"move_id":32},{"level":61,"move_id":97}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[35,30],"address":3300104,"base_stats":[30,45,55,85,70,55],"catch_rate":225,"evolutions":[{"method":"ITEM","param":97,"species":121}],"friendship":70,"id":120,"learnset":{"address":3311206,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":6,"move_id":55},{"level":10,"move_id":229},{"level":15,"move_id":105},{"level":19,"move_id":293},{"level":24,"move_id":129},{"level":28,"move_id":61},{"level":33,"move_id":107},{"level":37,"move_id":113},{"level":42,"move_id":322},{"level":46,"move_id":56}]},"tmhm_learnset":"03500E019593B264","types":[11,11]},{"abilities":[35,30],"address":3300132,"base_stats":[60,75,85,115,100,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":121,"learnset":{"address":3311236,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":229},{"level":1,"move_id":105},{"level":1,"move_id":129},{"level":33,"move_id":109}]},"tmhm_learnset":"03508E019593F264","types":[11,14]},{"abilities":[43,0],"address":3300160,"base_stats":[40,45,65,90,100,120],"catch_rate":45,"evolutions":[],"friendship":70,"id":122,"learnset":{"address":3311248,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":112},{"level":5,"move_id":93},{"level":9,"move_id":164},{"level":13,"move_id":96},{"level":17,"move_id":3},{"level":21,"move_id":113},{"level":21,"move_id":115},{"level":25,"move_id":227},{"level":29,"move_id":60},{"level":33,"move_id":278},{"level":37,"move_id":271},{"level":41,"move_id":272},{"level":45,"move_id":94},{"level":49,"move_id":226},{"level":53,"move_id":219}]},"tmhm_learnset":"0041BF03F5BBCE29","types":[14,14]},{"abilities":[68,0],"address":3300188,"base_stats":[70,110,80,105,55,80],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":212}],"friendship":70,"id":123,"learnset":{"address":3311286,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":17},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00847E8084134620","types":[6,2]},{"abilities":[12,0],"address":3300216,"base_stats":[65,50,35,95,115,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":124,"learnset":{"address":3311314,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":1,"move_id":142},{"level":1,"move_id":181},{"level":9,"move_id":142},{"level":13,"move_id":181},{"level":21,"move_id":3},{"level":25,"move_id":8},{"level":35,"move_id":212},{"level":41,"move_id":313},{"level":51,"move_id":34},{"level":57,"move_id":195},{"level":67,"move_id":59}]},"tmhm_learnset":"0040BF01F413FA6D","types":[15,14]},{"abilities":[9,0],"address":3300244,"base_stats":[65,83,57,105,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":125,"learnset":{"address":3311342,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":1,"move_id":9},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":36,"move_id":103},{"level":47,"move_id":85},{"level":58,"move_id":87}]},"tmhm_learnset":"00E03E02D5D3C221","types":[13,13]},{"abilities":[49,0],"address":3300272,"base_stats":[65,95,57,93,100,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":126,"learnset":{"address":3311364,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":43},{"level":1,"move_id":123},{"level":1,"move_id":7},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":33,"move_id":241},{"level":41,"move_id":53},{"level":49,"move_id":109},{"level":57,"move_id":126}]},"tmhm_learnset":"00A03E24D4514621","types":[10,10]},{"abilities":[52,0],"address":3300300,"base_stats":[65,125,100,85,55,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":127,"learnset":{"address":3311390,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":11},{"level":1,"move_id":116},{"level":7,"move_id":20},{"level":13,"move_id":69},{"level":19,"move_id":106},{"level":25,"move_id":279},{"level":31,"move_id":280},{"level":37,"move_id":12},{"level":43,"move_id":66},{"level":49,"move_id":14}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,6]},{"abilities":[22,0],"address":3300328,"base_stats":[75,100,95,110,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":128,"learnset":{"address":3311416,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":8,"move_id":99},{"level":13,"move_id":30},{"level":19,"move_id":184},{"level":26,"move_id":228},{"level":34,"move_id":156},{"level":43,"move_id":37},{"level":53,"move_id":36}]},"tmhm_learnset":"00B01E7687F37624","types":[0,0]},{"abilities":[33,0],"address":3300356,"base_stats":[20,10,55,80,15,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":130}],"friendship":70,"id":129,"learnset":{"address":3311442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"0000000000000000","types":[11,11]},{"abilities":[22,0],"address":3300384,"base_stats":[95,125,79,81,60,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":130,"learnset":{"address":3311456,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":37},{"level":20,"move_id":44},{"level":25,"move_id":82},{"level":30,"move_id":43},{"level":35,"move_id":239},{"level":40,"move_id":56},{"level":45,"move_id":240},{"level":50,"move_id":349},{"level":55,"move_id":63}]},"tmhm_learnset":"03B01F3487937A74","types":[11,2]},{"abilities":[11,75],"address":3300412,"base_stats":[130,85,80,60,85,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":131,"learnset":{"address":3311482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":45},{"level":1,"move_id":47},{"level":7,"move_id":54},{"level":13,"move_id":34},{"level":19,"move_id":109},{"level":25,"move_id":195},{"level":31,"move_id":58},{"level":37,"move_id":240},{"level":43,"move_id":219},{"level":49,"move_id":56},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E0295DB7274","types":[11,15]},{"abilities":[7,0],"address":3300440,"base_stats":[48,48,48,48,48,48],"catch_rate":35,"evolutions":[],"friendship":70,"id":132,"learnset":{"address":3311510,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":144}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[50,0],"address":3300468,"base_stats":[55,55,50,55,45,65],"catch_rate":45,"evolutions":[{"method":"ITEM","param":96,"species":135},{"method":"ITEM","param":97,"species":134},{"method":"ITEM","param":95,"species":136},{"method":"FRIENDSHIP_DAY","param":0,"species":196},{"method":"FRIENDSHIP_NIGHT","param":0,"species":197}],"friendship":70,"id":133,"learnset":{"address":3311520,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":45},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":226},{"level":42,"move_id":36}]},"tmhm_learnset":"00001E00AC530620","types":[0,0]},{"abilities":[11,0],"address":3300496,"base_stats":[130,65,60,65,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":134,"learnset":{"address":3311542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":55},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":62},{"level":42,"move_id":114},{"level":47,"move_id":151},{"level":52,"move_id":56}]},"tmhm_learnset":"03101E00AC537674","types":[11,11]},{"abilities":[10,0],"address":3300524,"base_stats":[65,65,60,130,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":135,"learnset":{"address":3311568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":84},{"level":23,"move_id":98},{"level":30,"move_id":24},{"level":36,"move_id":42},{"level":42,"move_id":86},{"level":47,"move_id":97},{"level":52,"move_id":87}]},"tmhm_learnset":"00401E02ADD34630","types":[13,13]},{"abilities":[18,0],"address":3300552,"base_stats":[65,130,60,65,95,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":136,"learnset":{"address":3311594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":52},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":83},{"level":42,"move_id":123},{"level":47,"move_id":43},{"level":52,"move_id":53}]},"tmhm_learnset":"00021E24AC534630","types":[10,10]},{"abilities":[36,0],"address":3300580,"base_stats":[65,60,70,40,85,75],"catch_rate":45,"evolutions":[{"method":"ITEM","param":218,"species":233}],"friendship":70,"id":137,"learnset":{"address":3311620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":159},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[33,75],"address":3300608,"base_stats":[35,40,100,35,90,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":139}],"friendship":70,"id":138,"learnset":{"address":3311646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":43,"move_id":321},{"level":49,"move_id":246},{"level":55,"move_id":56}]},"tmhm_learnset":"03903E5084133264","types":[5,11]},{"abilities":[33,75],"address":3300636,"base_stats":[70,60,125,55,115,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":139,"learnset":{"address":3311672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":1,"move_id":44},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":40,"move_id":131},{"level":46,"move_id":321},{"level":55,"move_id":246},{"level":65,"move_id":56}]},"tmhm_learnset":"03903E5084137264","types":[5,11]},{"abilities":[33,4],"address":3300664,"base_stats":[30,80,90,55,55,45],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":141}],"friendship":70,"id":140,"learnset":{"address":3311700,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":43,"move_id":319},{"level":49,"move_id":72},{"level":55,"move_id":246}]},"tmhm_learnset":"01903ED08C173264","types":[5,11]},{"abilities":[33,4],"address":3300692,"base_stats":[60,115,105,80,65,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":141,"learnset":{"address":3311726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":71},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":40,"move_id":163},{"level":46,"move_id":319},{"level":55,"move_id":72},{"level":65,"move_id":246}]},"tmhm_learnset":"03943ED0CC177264","types":[5,11]},{"abilities":[69,46],"address":3300720,"base_stats":[80,105,65,130,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":142,"learnset":{"address":3311754,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":8,"move_id":97},{"level":15,"move_id":44},{"level":22,"move_id":48},{"level":29,"move_id":246},{"level":36,"move_id":184},{"level":43,"move_id":36},{"level":50,"move_id":63}]},"tmhm_learnset":"00A87FF486534E32","types":[5,2]},{"abilities":[17,47],"address":3300748,"base_stats":[160,110,65,30,65,110],"catch_rate":25,"evolutions":[],"friendship":70,"id":143,"learnset":{"address":3311778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":133},{"level":10,"move_id":111},{"level":15,"move_id":187},{"level":19,"move_id":29},{"level":24,"move_id":281},{"level":28,"move_id":156},{"level":28,"move_id":173},{"level":33,"move_id":34},{"level":37,"move_id":335},{"level":42,"move_id":343},{"level":46,"move_id":205},{"level":51,"move_id":63}]},"tmhm_learnset":"00301E76F7B37625","types":[0,0]},{"abilities":[46,0],"address":3300776,"base_stats":[90,85,100,85,95,125],"catch_rate":3,"evolutions":[],"friendship":35,"id":144,"learnset":{"address":3311812,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":181},{"level":13,"move_id":54},{"level":25,"move_id":97},{"level":37,"move_id":170},{"level":49,"move_id":58},{"level":61,"move_id":115},{"level":73,"move_id":59},{"level":85,"move_id":329}]},"tmhm_learnset":"00884E9184137674","types":[15,2]},{"abilities":[46,0],"address":3300804,"base_stats":[90,90,85,100,125,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":145,"learnset":{"address":3311836,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":84},{"level":13,"move_id":86},{"level":25,"move_id":97},{"level":37,"move_id":197},{"level":49,"move_id":65},{"level":61,"move_id":268},{"level":73,"move_id":113},{"level":85,"move_id":87}]},"tmhm_learnset":"00C84E928593C630","types":[13,2]},{"abilities":[46,0],"address":3300832,"base_stats":[90,100,90,90,125,85],"catch_rate":3,"evolutions":[],"friendship":35,"id":146,"learnset":{"address":3311860,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":1,"move_id":52},{"level":13,"move_id":83},{"level":25,"move_id":97},{"level":37,"move_id":203},{"level":49,"move_id":53},{"level":61,"move_id":219},{"level":73,"move_id":257},{"level":85,"move_id":143}]},"tmhm_learnset":"008A4EB4841B4630","types":[10,2]},{"abilities":[61,0],"address":3300860,"base_stats":[41,64,45,50,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":148}],"friendship":35,"id":147,"learnset":{"address":3311884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":36,"move_id":97},{"level":43,"move_id":219},{"level":50,"move_id":200},{"level":57,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[61,0],"address":3300888,"base_stats":[61,84,65,70,70,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":149}],"friendship":35,"id":148,"learnset":{"address":3311910,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":56,"move_id":200},{"level":65,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[39,0],"address":3300916,"base_stats":[91,134,95,80,100,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":149,"learnset":{"address":3311936,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":55,"move_id":17},{"level":61,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BC5EF6C7DB7677","types":[16,2]},{"abilities":[46,0],"address":3300944,"base_stats":[106,110,90,130,154,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":150,"learnset":{"address":3311964,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":50},{"level":11,"move_id":112},{"level":22,"move_id":129},{"level":33,"move_id":244},{"level":44,"move_id":248},{"level":55,"move_id":54},{"level":66,"move_id":94},{"level":77,"move_id":133},{"level":88,"move_id":105},{"level":99,"move_id":219}]},"tmhm_learnset":"00E18FF7F7FBFEED","types":[14,14]},{"abilities":[28,0],"address":3300972,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":151,"learnset":{"address":3311992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":10,"move_id":144},{"level":20,"move_id":5},{"level":30,"move_id":118},{"level":40,"move_id":94},{"level":50,"move_id":246}]},"tmhm_learnset":"03FFFFFFFFFFFFFF","types":[14,14]},{"abilities":[65,0],"address":3301000,"base_stats":[45,49,65,45,49,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":153}],"friendship":70,"id":152,"learnset":{"address":3312012,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":22,"move_id":235},{"level":29,"move_id":34},{"level":36,"move_id":113},{"level":43,"move_id":219},{"level":50,"move_id":76}]},"tmhm_learnset":"00441E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301028,"base_stats":[60,62,80,60,63,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":154}],"friendship":70,"id":153,"learnset":{"address":3312038,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":39,"move_id":113},{"level":47,"move_id":219},{"level":55,"move_id":76}]},"tmhm_learnset":"00E41E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301056,"base_stats":[80,82,100,80,83,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":154,"learnset":{"address":3312064,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":41,"move_id":113},{"level":51,"move_id":219},{"level":61,"move_id":76}]},"tmhm_learnset":"00E41E01867DC720","types":[12,12]},{"abilities":[66,0],"address":3301084,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":14,"species":156}],"friendship":70,"id":155,"learnset":{"address":3312090,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":19,"move_id":98},{"level":27,"move_id":172},{"level":36,"move_id":129},{"level":46,"move_id":53}]},"tmhm_learnset":"00061EA48C110620","types":[10,10]},{"abilities":[66,0],"address":3301112,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":157}],"friendship":70,"id":156,"learnset":{"address":3312112,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":42,"move_id":129},{"level":54,"move_id":53}]},"tmhm_learnset":"00A61EA4CC110631","types":[10,10]},{"abilities":[66,0],"address":3301140,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":157,"learnset":{"address":3312134,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":1,"move_id":52},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":45,"move_id":129},{"level":60,"move_id":53}]},"tmhm_learnset":"00A61EA4CE114631","types":[10,10]},{"abilities":[67,0],"address":3301168,"base_stats":[50,65,64,43,44,48],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":18,"species":159}],"friendship":70,"id":158,"learnset":{"address":3312156,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":20,"move_id":44},{"level":27,"move_id":184},{"level":35,"move_id":163},{"level":43,"move_id":103},{"level":52,"move_id":56}]},"tmhm_learnset":"03141E80CC533265","types":[11,11]},{"abilities":[67,0],"address":3301196,"base_stats":[65,80,80,58,59,63],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":160}],"friendship":70,"id":159,"learnset":{"address":3312180,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":37,"move_id":163},{"level":45,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03B41E80CC533275","types":[11,11]},{"abilities":[67,0],"address":3301224,"base_stats":[85,105,100,78,79,83],"catch_rate":45,"evolutions":[],"friendship":70,"id":160,"learnset":{"address":3312204,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":1,"move_id":55},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":38,"move_id":163},{"level":47,"move_id":103},{"level":58,"move_id":56}]},"tmhm_learnset":"03B41E80CE537277","types":[11,11]},{"abilities":[50,51],"address":3301252,"base_stats":[35,46,34,20,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":15,"species":162}],"friendship":70,"id":161,"learnset":{"address":3312228,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":17,"move_id":270},{"level":24,"move_id":21},{"level":31,"move_id":266},{"level":40,"move_id":156},{"level":49,"move_id":133}]},"tmhm_learnset":"00143E06ECF31625","types":[0,0]},{"abilities":[50,51],"address":3301280,"base_stats":[85,76,64,90,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":162,"learnset":{"address":3312254,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":98},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":19,"move_id":270},{"level":28,"move_id":21},{"level":37,"move_id":266},{"level":48,"move_id":156},{"level":59,"move_id":133}]},"tmhm_learnset":"00B43E06EDF37625","types":[0,0]},{"abilities":[15,51],"address":3301308,"base_stats":[60,30,30,50,36,56],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":164}],"friendship":70,"id":163,"learnset":{"address":3312280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":22,"move_id":115},{"level":28,"move_id":36},{"level":34,"move_id":93},{"level":48,"move_id":138}]},"tmhm_learnset":"00487E81B4130620","types":[0,2]},{"abilities":[15,51],"address":3301336,"base_stats":[100,50,50,70,76,96],"catch_rate":90,"evolutions":[],"friendship":70,"id":164,"learnset":{"address":3312304,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":193},{"level":1,"move_id":64},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":25,"move_id":115},{"level":33,"move_id":36},{"level":41,"move_id":93},{"level":57,"move_id":138}]},"tmhm_learnset":"00487E81B4134620","types":[0,2]},{"abilities":[68,48],"address":3301364,"base_stats":[40,20,30,55,40,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":166}],"friendship":70,"id":165,"learnset":{"address":3312328,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":22,"move_id":113},{"level":22,"move_id":115},{"level":22,"move_id":219},{"level":29,"move_id":226},{"level":36,"move_id":129},{"level":43,"move_id":97},{"level":50,"move_id":38}]},"tmhm_learnset":"00403E81CC3D8621","types":[6,2]},{"abilities":[68,48],"address":3301392,"base_stats":[55,35,50,85,55,110],"catch_rate":90,"evolutions":[],"friendship":70,"id":166,"learnset":{"address":3312356,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":48},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":24,"move_id":113},{"level":24,"move_id":115},{"level":24,"move_id":219},{"level":33,"move_id":226},{"level":42,"move_id":129},{"level":51,"move_id":97},{"level":60,"move_id":38}]},"tmhm_learnset":"00403E81CC3DC621","types":[6,2]},{"abilities":[68,15],"address":3301420,"base_stats":[40,60,40,30,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":168}],"friendship":70,"id":167,"learnset":{"address":3312384,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":23,"move_id":141},{"level":30,"move_id":154},{"level":37,"move_id":169},{"level":45,"move_id":97},{"level":53,"move_id":94}]},"tmhm_learnset":"00403E089C350620","types":[6,3]},{"abilities":[68,15],"address":3301448,"base_stats":[70,90,70,40,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":168,"learnset":{"address":3312410,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":1,"move_id":184},{"level":1,"move_id":132},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":25,"move_id":141},{"level":34,"move_id":154},{"level":43,"move_id":169},{"level":53,"move_id":97},{"level":63,"move_id":94}]},"tmhm_learnset":"00403E089C354620","types":[6,3]},{"abilities":[39,0],"address":3301476,"base_stats":[85,90,80,130,70,80],"catch_rate":90,"evolutions":[],"friendship":70,"id":169,"learnset":{"address":3312436,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00097F88A4174E20","types":[3,2]},{"abilities":[10,35],"address":3301504,"base_stats":[75,38,38,67,56,56],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":27,"species":171}],"friendship":70,"id":170,"learnset":{"address":3312464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":29,"move_id":109},{"level":37,"move_id":36},{"level":41,"move_id":56},{"level":49,"move_id":268}]},"tmhm_learnset":"03501E0285933264","types":[11,13]},{"abilities":[10,35],"address":3301532,"base_stats":[125,58,58,67,76,76],"catch_rate":75,"evolutions":[],"friendship":70,"id":171,"learnset":{"address":3312490,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":1,"move_id":48},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":32,"move_id":109},{"level":43,"move_id":36},{"level":50,"move_id":56},{"level":61,"move_id":268}]},"tmhm_learnset":"03501E0285937264","types":[11,13]},{"abilities":[9,0],"address":3301560,"base_stats":[20,40,15,60,35,35],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":25}],"friendship":70,"id":172,"learnset":{"address":3312516,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":204},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":186}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[56,0],"address":3301588,"base_stats":[50,25,28,15,45,55],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":35}],"friendship":140,"id":173,"learnset":{"address":3312532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":204},{"level":4,"move_id":227},{"level":8,"move_id":47},{"level":13,"move_id":186}]},"tmhm_learnset":"00401E27BC7B8624","types":[0,0]},{"abilities":[56,0],"address":3301616,"base_stats":[90,30,15,15,40,20],"catch_rate":170,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":39}],"friendship":70,"id":174,"learnset":{"address":3312548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":1,"move_id":204},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":186}]},"tmhm_learnset":"00401E27BC3B8624","types":[0,0]},{"abilities":[55,32],"address":3301644,"base_stats":[35,20,65,20,40,65],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":176}],"friendship":70,"id":175,"learnset":{"address":3312564,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C01E27B43B8624","types":[0,0]},{"abilities":[55,32],"address":3301672,"base_stats":[55,40,85,40,80,105],"catch_rate":75,"evolutions":[],"friendship":70,"id":176,"learnset":{"address":3312590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C85EA7F43BC625","types":[0,2]},{"abilities":[28,48],"address":3301700,"base_stats":[40,50,45,70,70,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":178}],"friendship":70,"id":177,"learnset":{"address":3312616,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":30,"move_id":273},{"level":30,"move_id":248},{"level":40,"move_id":109},{"level":50,"move_id":94}]},"tmhm_learnset":"0040FE81B4378628","types":[14,2]},{"abilities":[28,48],"address":3301728,"base_stats":[65,75,70,95,95,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":178,"learnset":{"address":3312638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":35,"move_id":273},{"level":35,"move_id":248},{"level":50,"move_id":109},{"level":65,"move_id":94}]},"tmhm_learnset":"0048FE81B437C628","types":[14,2]},{"abilities":[9,0],"address":3301756,"base_stats":[55,40,40,35,65,45],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":15,"species":180}],"friendship":70,"id":179,"learnset":{"address":3312660,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":84},{"level":16,"move_id":86},{"level":23,"move_id":178},{"level":30,"move_id":113},{"level":37,"move_id":87}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[9,0],"address":3301784,"base_stats":[70,55,55,45,80,60],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":181}],"friendship":70,"id":180,"learnset":{"address":3312680,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":36,"move_id":113},{"level":45,"move_id":87}]},"tmhm_learnset":"00E01E02C5D38221","types":[13,13]},{"abilities":[9,0],"address":3301812,"base_stats":[90,75,75,55,115,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":181,"learnset":{"address":3312700,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":1,"move_id":86},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":30,"move_id":9},{"level":42,"move_id":113},{"level":57,"move_id":87}]},"tmhm_learnset":"00E01E02C5D3C221","types":[13,13]},{"abilities":[34,0],"address":3301840,"base_stats":[75,80,85,50,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":182,"learnset":{"address":3312722,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":78},{"level":1,"move_id":345},{"level":44,"move_id":80},{"level":55,"move_id":76}]},"tmhm_learnset":"00441E08843D4720","types":[12,12]},{"abilities":[47,37],"address":3301868,"base_stats":[70,20,50,40,20,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":18,"species":184}],"friendship":70,"id":183,"learnset":{"address":3312736,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":21,"move_id":61},{"level":28,"move_id":38},{"level":36,"move_id":240},{"level":45,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[47,37],"address":3301896,"base_stats":[100,50,80,50,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":184,"learnset":{"address":3312762,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":39},{"level":1,"move_id":55},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":24,"move_id":61},{"level":34,"move_id":38},{"level":45,"move_id":240},{"level":57,"move_id":56}]},"tmhm_learnset":"03B01E00CC537265","types":[11,11]},{"abilities":[5,69],"address":3301924,"base_stats":[70,100,115,30,30,65],"catch_rate":65,"evolutions":[],"friendship":70,"id":185,"learnset":{"address":3312788,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":102},{"level":9,"move_id":175},{"level":17,"move_id":67},{"level":25,"move_id":157},{"level":33,"move_id":335},{"level":41,"move_id":185},{"level":49,"move_id":21},{"level":57,"move_id":38}]},"tmhm_learnset":"00A03E50CE110E29","types":[5,5]},{"abilities":[11,6],"address":3301952,"base_stats":[90,75,75,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":186,"learnset":{"address":3312812,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":195},{"level":35,"move_id":195},{"level":51,"move_id":207}]},"tmhm_learnset":"03B03E00DE137265","types":[11,11]},{"abilities":[34,0],"address":3301980,"base_stats":[35,35,40,50,35,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":188}],"friendship":70,"id":187,"learnset":{"address":3312826,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":20,"move_id":73},{"level":25,"move_id":178},{"level":30,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302008,"base_stats":[55,45,50,80,45,65],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":27,"species":189}],"friendship":70,"id":188,"learnset":{"address":3312854,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":29,"move_id":178},{"level":36,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302036,"base_stats":[75,55,70,110,55,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":189,"learnset":{"address":3312882,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":33,"move_id":178},{"level":44,"move_id":72}]},"tmhm_learnset":"00401E8084354720","types":[12,2]},{"abilities":[50,53],"address":3302064,"base_stats":[55,70,55,85,40,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":190,"learnset":{"address":3312910,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":6,"move_id":28},{"level":13,"move_id":310},{"level":18,"move_id":226},{"level":25,"move_id":321},{"level":31,"move_id":154},{"level":38,"move_id":129},{"level":43,"move_id":103},{"level":50,"move_id":97}]},"tmhm_learnset":"00A53E82EDF30E25","types":[0,0]},{"abilities":[34,0],"address":3302092,"base_stats":[30,30,30,30,30,30],"catch_rate":235,"evolutions":[{"method":"ITEM","param":93,"species":192}],"friendship":70,"id":191,"learnset":{"address":3312936,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":6,"move_id":74},{"level":13,"move_id":72},{"level":18,"move_id":275},{"level":25,"move_id":283},{"level":30,"move_id":241},{"level":37,"move_id":235},{"level":42,"move_id":202}]},"tmhm_learnset":"00441E08843D8720","types":[12,12]},{"abilities":[34,0],"address":3302120,"base_stats":[75,75,55,30,105,85],"catch_rate":120,"evolutions":[],"friendship":70,"id":192,"learnset":{"address":3312960,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":1},{"level":6,"move_id":74},{"level":13,"move_id":75},{"level":18,"move_id":275},{"level":25,"move_id":331},{"level":30,"move_id":241},{"level":37,"move_id":80},{"level":42,"move_id":76}]},"tmhm_learnset":"00441E08843DC720","types":[12,12]},{"abilities":[3,14],"address":3302148,"base_stats":[65,65,45,95,75,45],"catch_rate":75,"evolutions":[],"friendship":70,"id":193,"learnset":{"address":3312984,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":193},{"level":7,"move_id":98},{"level":13,"move_id":104},{"level":19,"move_id":49},{"level":25,"move_id":197},{"level":31,"move_id":48},{"level":37,"move_id":253},{"level":43,"move_id":17},{"level":49,"move_id":103}]},"tmhm_learnset":"00407E80B4350620","types":[6,2]},{"abilities":[6,11],"address":3302176,"base_stats":[55,45,45,15,25,25],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":195}],"friendship":70,"id":194,"learnset":{"address":3313010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":21,"move_id":133},{"level":31,"move_id":281},{"level":36,"move_id":89},{"level":41,"move_id":240},{"level":51,"move_id":54},{"level":51,"move_id":114}]},"tmhm_learnset":"03D01E188E533264","types":[11,4]},{"abilities":[6,11],"address":3302204,"base_stats":[95,85,85,35,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":195,"learnset":{"address":3313036,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":23,"move_id":133},{"level":35,"move_id":281},{"level":42,"move_id":89},{"level":49,"move_id":240},{"level":61,"move_id":54},{"level":61,"move_id":114}]},"tmhm_learnset":"03F01E58CE537265","types":[11,4]},{"abilities":[28,0],"address":3302232,"base_stats":[65,65,60,110,130,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":196,"learnset":{"address":3313062,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":93},{"level":23,"move_id":98},{"level":30,"move_id":129},{"level":36,"move_id":60},{"level":42,"move_id":244},{"level":47,"move_id":94},{"level":52,"move_id":234}]},"tmhm_learnset":"00449E01BC53C628","types":[14,14]},{"abilities":[28,0],"address":3302260,"base_stats":[95,65,110,65,60,130],"catch_rate":45,"evolutions":[],"friendship":35,"id":197,"learnset":{"address":3313088,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":228},{"level":23,"move_id":98},{"level":30,"move_id":109},{"level":36,"move_id":185},{"level":42,"move_id":212},{"level":47,"move_id":103},{"level":52,"move_id":236}]},"tmhm_learnset":"00451F00BC534E20","types":[17,17]},{"abilities":[15,0],"address":3302288,"base_stats":[60,85,42,91,85,42],"catch_rate":30,"evolutions":[],"friendship":35,"id":198,"learnset":{"address":3313114,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":9,"move_id":310},{"level":14,"move_id":228},{"level":22,"move_id":114},{"level":27,"move_id":101},{"level":35,"move_id":185},{"level":40,"move_id":269},{"level":48,"move_id":212}]},"tmhm_learnset":"00097F80A4130E28","types":[17,2]},{"abilities":[12,20],"address":3302316,"base_stats":[95,75,80,30,100,110],"catch_rate":70,"evolutions":[],"friendship":70,"id":199,"learnset":{"address":3313138,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":207},{"level":48,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[26,0],"address":3302344,"base_stats":[60,60,60,85,85,85],"catch_rate":45,"evolutions":[],"friendship":35,"id":200,"learnset":{"address":3313162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":149},{"level":6,"move_id":180},{"level":11,"move_id":310},{"level":17,"move_id":109},{"level":23,"move_id":212},{"level":30,"move_id":60},{"level":37,"move_id":220},{"level":45,"move_id":195},{"level":53,"move_id":288}]},"tmhm_learnset":"0041BF82B5930E28","types":[7,7]},{"abilities":[26,0],"address":3302372,"base_stats":[48,72,48,48,72,48],"catch_rate":225,"evolutions":[],"friendship":70,"id":201,"learnset":{"address":3313188,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":237}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[23,0],"address":3302400,"base_stats":[190,33,58,33,33,58],"catch_rate":45,"evolutions":[],"friendship":70,"id":202,"learnset":{"address":3313198,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":243},{"level":1,"move_id":219},{"level":1,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[39,48],"address":3302428,"base_stats":[70,80,65,85,90,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":203,"learnset":{"address":3313208,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":7,"move_id":310},{"level":13,"move_id":93},{"level":19,"move_id":23},{"level":25,"move_id":316},{"level":31,"move_id":97},{"level":37,"move_id":226},{"level":43,"move_id":60},{"level":49,"move_id":242}]},"tmhm_learnset":"00E0BE03B7D38628","types":[0,14]},{"abilities":[5,0],"address":3302456,"base_stats":[50,65,90,15,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":205}],"friendship":70,"id":204,"learnset":{"address":3313234,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":36,"move_id":153},{"level":43,"move_id":191},{"level":50,"move_id":38}]},"tmhm_learnset":"00A01E118E358620","types":[6,6]},{"abilities":[5,0],"address":3302484,"base_stats":[75,90,140,40,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":205,"learnset":{"address":3313258,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":1,"move_id":120},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":39,"move_id":153},{"level":49,"move_id":191},{"level":59,"move_id":38}]},"tmhm_learnset":"00A01E118E35C620","types":[6,8]},{"abilities":[32,50],"address":3302512,"base_stats":[100,70,70,45,65,65],"catch_rate":190,"evolutions":[],"friendship":70,"id":206,"learnset":{"address":3313282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":4,"move_id":111},{"level":11,"move_id":281},{"level":14,"move_id":137},{"level":21,"move_id":180},{"level":24,"move_id":228},{"level":31,"move_id":103},{"level":34,"move_id":36},{"level":41,"move_id":283}]},"tmhm_learnset":"00A03E66AFF3362C","types":[0,0]},{"abilities":[52,8],"address":3302540,"base_stats":[65,75,105,85,35,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":207,"learnset":{"address":3313308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":28},{"level":13,"move_id":106},{"level":20,"move_id":98},{"level":28,"move_id":185},{"level":36,"move_id":163},{"level":44,"move_id":103},{"level":52,"move_id":12}]},"tmhm_learnset":"00A47ED88E530620","types":[4,2]},{"abilities":[69,5],"address":3302568,"base_stats":[75,85,200,30,55,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":208,"learnset":{"address":3313332,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":242},{"level":57,"move_id":38}]},"tmhm_learnset":"00A41F508E514E30","types":[8,4]},{"abilities":[22,50],"address":3302596,"base_stats":[60,80,50,30,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":23,"species":210}],"friendship":70,"id":209,"learnset":{"address":3313360,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":26,"move_id":46},{"level":34,"move_id":99},{"level":43,"move_id":36},{"level":53,"move_id":242}]},"tmhm_learnset":"00A23F2EEFB30EB5","types":[0,0]},{"abilities":[22,22],"address":3302624,"base_stats":[90,120,75,45,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":210,"learnset":{"address":3313386,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":28,"move_id":46},{"level":38,"move_id":99},{"level":49,"move_id":36},{"level":61,"move_id":242}]},"tmhm_learnset":"00A23F6EEFF34EB5","types":[0,0]},{"abilities":[38,33],"address":3302652,"base_stats":[65,95,75,85,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":211,"learnset":{"address":3313412,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":191},{"level":1,"move_id":33},{"level":1,"move_id":40},{"level":10,"move_id":106},{"level":10,"move_id":107},{"level":19,"move_id":55},{"level":28,"move_id":42},{"level":37,"move_id":36},{"level":46,"move_id":56}]},"tmhm_learnset":"03101E0AA4133264","types":[11,3]},{"abilities":[68,0],"address":3302680,"base_stats":[70,130,100,65,55,80],"catch_rate":25,"evolutions":[],"friendship":70,"id":212,"learnset":{"address":3313434,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":232},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00A47E9084134620","types":[6,8]},{"abilities":[5,0],"address":3302708,"base_stats":[20,10,230,5,10,230],"catch_rate":190,"evolutions":[],"friendship":70,"id":213,"learnset":{"address":3313462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":9,"move_id":35},{"level":14,"move_id":227},{"level":23,"move_id":219},{"level":28,"move_id":117},{"level":37,"move_id":156}]},"tmhm_learnset":"00E01E588E190620","types":[6,5]},{"abilities":[68,62],"address":3302736,"base_stats":[80,125,75,85,40,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":214,"learnset":{"address":3313482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":30},{"level":11,"move_id":203},{"level":17,"move_id":31},{"level":23,"move_id":280},{"level":30,"move_id":68},{"level":37,"move_id":36},{"level":45,"move_id":179},{"level":53,"move_id":224}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,1]},{"abilities":[39,51],"address":3302764,"base_stats":[55,95,55,115,35,75],"catch_rate":60,"evolutions":[],"friendship":35,"id":215,"learnset":{"address":3313508,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":269},{"level":8,"move_id":98},{"level":15,"move_id":103},{"level":22,"move_id":185},{"level":29,"move_id":154},{"level":36,"move_id":97},{"level":43,"move_id":196},{"level":50,"move_id":163},{"level":57,"move_id":251},{"level":64,"move_id":232}]},"tmhm_learnset":"00B53F80EC533E69","types":[17,15]},{"abilities":[53,0],"address":3302792,"base_stats":[60,80,50,40,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":217}],"friendship":70,"id":216,"learnset":{"address":3313536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43F80CE130EB1","types":[0,0]},{"abilities":[62,0],"address":3302820,"base_stats":[90,130,75,55,75,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":217,"learnset":{"address":3313562,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":122},{"level":1,"move_id":154},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43FC0CE134EB1","types":[0,0]},{"abilities":[40,49],"address":3302848,"base_stats":[40,40,40,20,70,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":219}],"friendship":70,"id":218,"learnset":{"address":3313588,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":43,"move_id":157},{"level":50,"move_id":34}]},"tmhm_learnset":"00821E2584118620","types":[10,10]},{"abilities":[40,49],"address":3302876,"base_stats":[50,50,120,30,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":219,"learnset":{"address":3313612,"moves":[{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":1,"move_id":52},{"level":1,"move_id":88},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":48,"move_id":157},{"level":60,"move_id":34}]},"tmhm_learnset":"00A21E758611C620","types":[10,5]},{"abilities":[12,0],"address":3302904,"base_stats":[50,50,40,50,30,30],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":221}],"friendship":70,"id":220,"learnset":{"address":3313636,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":316},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":37,"move_id":54},{"level":46,"move_id":59},{"level":55,"move_id":133}]},"tmhm_learnset":"00A01E518E13B270","types":[15,4]},{"abilities":[12,0],"address":3302932,"base_stats":[100,100,80,50,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":221,"learnset":{"address":3313658,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":316},{"level":1,"move_id":181},{"level":1,"move_id":203},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":33,"move_id":31},{"level":42,"move_id":54},{"level":56,"move_id":59},{"level":70,"move_id":133}]},"tmhm_learnset":"00A01E518E13F270","types":[15,4]},{"abilities":[55,30],"address":3302960,"base_stats":[55,55,85,35,65,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":222,"learnset":{"address":3313682,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":106},{"level":12,"move_id":145},{"level":17,"move_id":105},{"level":17,"move_id":287},{"level":23,"move_id":61},{"level":28,"move_id":131},{"level":34,"move_id":350},{"level":39,"move_id":243},{"level":45,"move_id":246}]},"tmhm_learnset":"00B01E51BE1BB66C","types":[11,5]},{"abilities":[55,0],"address":3302988,"base_stats":[35,65,35,65,65,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":224}],"friendship":70,"id":223,"learnset":{"address":3313710,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":199},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":33,"move_id":116},{"level":44,"move_id":58},{"level":55,"move_id":63}]},"tmhm_learnset":"03103E2494137624","types":[11,11]},{"abilities":[21,0],"address":3303016,"base_stats":[75,105,75,45,105,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":224,"learnset":{"address":3313734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":132},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":25,"move_id":190},{"level":38,"move_id":116},{"level":54,"move_id":58},{"level":70,"move_id":63}]},"tmhm_learnset":"03103E2C94137724","types":[11,11]},{"abilities":[72,55],"address":3303044,"base_stats":[45,55,45,75,65,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":225,"learnset":{"address":3313760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":217}]},"tmhm_learnset":"00083E8084133265","types":[15,2]},{"abilities":[33,11],"address":3303072,"base_stats":[65,40,70,70,80,140],"catch_rate":25,"evolutions":[],"friendship":70,"id":226,"learnset":{"address":3313770,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":145},{"level":8,"move_id":48},{"level":15,"move_id":61},{"level":22,"move_id":36},{"level":29,"move_id":97},{"level":36,"move_id":17},{"level":43,"move_id":352},{"level":50,"move_id":109}]},"tmhm_learnset":"03101E8086133264","types":[11,2]},{"abilities":[51,5],"address":3303100,"base_stats":[65,80,140,70,40,70],"catch_rate":25,"evolutions":[],"friendship":70,"id":227,"learnset":{"address":3313794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":10,"move_id":28},{"level":13,"move_id":129},{"level":16,"move_id":97},{"level":26,"move_id":31},{"level":29,"move_id":314},{"level":32,"move_id":211},{"level":42,"move_id":191},{"level":45,"move_id":319}]},"tmhm_learnset":"008C7F9084110E30","types":[8,2]},{"abilities":[48,18],"address":3303128,"base_stats":[45,60,30,65,80,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":24,"species":229}],"friendship":35,"id":228,"learnset":{"address":3313820,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":25,"move_id":44},{"level":31,"move_id":316},{"level":37,"move_id":185},{"level":43,"move_id":53},{"level":49,"move_id":242}]},"tmhm_learnset":"00833F2CA4710E30","types":[17,10]},{"abilities":[48,18],"address":3303156,"base_stats":[75,90,50,95,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":229,"learnset":{"address":3313846,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":1,"move_id":336},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":27,"move_id":44},{"level":35,"move_id":316},{"level":43,"move_id":185},{"level":51,"move_id":53},{"level":59,"move_id":242}]},"tmhm_learnset":"00A33F2CA4714E30","types":[17,10]},{"abilities":[33,0],"address":3303184,"base_stats":[75,95,95,85,95,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":230,"learnset":{"address":3313872,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,16]},{"abilities":[53,0],"address":3303212,"base_stats":[90,60,60,40,40,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":25,"species":232}],"friendship":70,"id":231,"learnset":{"address":3313896,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":36},{"level":33,"move_id":205},{"level":41,"move_id":203},{"level":49,"move_id":38}]},"tmhm_learnset":"00A01E5086510630","types":[4,4]},{"abilities":[5,0],"address":3303240,"base_stats":[90,120,120,50,60,60],"catch_rate":60,"evolutions":[],"friendship":70,"id":232,"learnset":{"address":3313918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":30},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":31},{"level":33,"move_id":205},{"level":41,"move_id":229},{"level":49,"move_id":89}]},"tmhm_learnset":"00A01E5086514630","types":[4,4]},{"abilities":[36,0],"address":3303268,"base_stats":[85,80,90,60,105,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":233,"learnset":{"address":3313940,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":111},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[22,0],"address":3303296,"base_stats":[73,95,62,85,85,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":234,"learnset":{"address":3313966,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":43},{"level":13,"move_id":310},{"level":19,"move_id":95},{"level":25,"move_id":23},{"level":31,"move_id":28},{"level":37,"move_id":36},{"level":43,"move_id":109},{"level":49,"move_id":347}]},"tmhm_learnset":"0040BE03B7F38638","types":[0,0]},{"abilities":[20,0],"address":3303324,"base_stats":[55,20,35,75,20,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":235,"learnset":{"address":3313992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":166},{"level":11,"move_id":166},{"level":21,"move_id":166},{"level":31,"move_id":166},{"level":41,"move_id":166},{"level":51,"move_id":166},{"level":61,"move_id":166},{"level":71,"move_id":166},{"level":81,"move_id":166},{"level":91,"move_id":166}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[62,0],"address":3303352,"base_stats":[35,35,35,35,35,35],"catch_rate":75,"evolutions":[{"method":"LEVEL_ATK_LT_DEF","param":20,"species":107},{"method":"LEVEL_ATK_GT_DEF","param":20,"species":106},{"method":"LEVEL_ATK_EQ_DEF","param":20,"species":237}],"friendship":70,"id":236,"learnset":{"address":3314020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"00A03E00C61306A0","types":[1,1]},{"abilities":[22,0],"address":3303380,"base_stats":[50,95,95,70,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":237,"learnset":{"address":3314030,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":27},{"level":7,"move_id":116},{"level":13,"move_id":228},{"level":19,"move_id":98},{"level":20,"move_id":167},{"level":25,"move_id":229},{"level":31,"move_id":68},{"level":37,"move_id":97},{"level":43,"move_id":197},{"level":49,"move_id":283}]},"tmhm_learnset":"00A03E10CE1306A0","types":[1,1]},{"abilities":[12,0],"address":3303408,"base_stats":[45,30,15,65,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":124}],"friendship":70,"id":238,"learnset":{"address":3314058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":9,"move_id":186},{"level":13,"move_id":181},{"level":21,"move_id":93},{"level":25,"move_id":47},{"level":33,"move_id":212},{"level":37,"move_id":313},{"level":45,"move_id":94},{"level":49,"move_id":195},{"level":57,"move_id":59}]},"tmhm_learnset":"0040BE01B413B26C","types":[15,14]},{"abilities":[9,0],"address":3303436,"base_stats":[45,63,37,95,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":125}],"friendship":70,"id":239,"learnset":{"address":3314086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":33,"move_id":103},{"level":41,"move_id":85},{"level":49,"move_id":87}]},"tmhm_learnset":"00C03E02D5938221","types":[13,13]},{"abilities":[49,0],"address":3303464,"base_stats":[45,75,37,83,70,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":126}],"friendship":70,"id":240,"learnset":{"address":3314108,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":31,"move_id":241},{"level":37,"move_id":53},{"level":43,"move_id":109},{"level":49,"move_id":126}]},"tmhm_learnset":"00803E24D4510621","types":[10,10]},{"abilities":[47,0],"address":3303492,"base_stats":[95,80,105,100,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":241,"learnset":{"address":3314134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":8,"move_id":111},{"level":13,"move_id":23},{"level":19,"move_id":208},{"level":26,"move_id":117},{"level":34,"move_id":205},{"level":43,"move_id":34},{"level":53,"move_id":215}]},"tmhm_learnset":"00B01E52E7F37625","types":[0,0]},{"abilities":[30,32],"address":3303520,"base_stats":[255,10,10,55,75,135],"catch_rate":30,"evolutions":[],"friendship":140,"id":242,"learnset":{"address":3314160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":4,"move_id":39},{"level":7,"move_id":287},{"level":10,"move_id":135},{"level":13,"move_id":3},{"level":18,"move_id":107},{"level":23,"move_id":47},{"level":28,"move_id":121},{"level":33,"move_id":111},{"level":40,"move_id":113},{"level":47,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[46,0],"address":3303548,"base_stats":[90,85,75,115,115,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":243,"learnset":{"address":3314190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":84},{"level":21,"move_id":46},{"level":31,"move_id":98},{"level":41,"move_id":209},{"level":51,"move_id":115},{"level":61,"move_id":242},{"level":71,"move_id":87},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E138DD34638","types":[13,13]},{"abilities":[46,0],"address":3303576,"base_stats":[115,115,85,100,90,75],"catch_rate":3,"evolutions":[],"friendship":35,"id":244,"learnset":{"address":3314216,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":52},{"level":21,"move_id":46},{"level":31,"move_id":83},{"level":41,"move_id":23},{"level":51,"move_id":53},{"level":61,"move_id":207},{"level":71,"move_id":126},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E358C734638","types":[10,10]},{"abilities":[46,0],"address":3303604,"base_stats":[100,75,115,85,90,115],"catch_rate":3,"evolutions":[],"friendship":35,"id":245,"learnset":{"address":3314242,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":61},{"level":21,"move_id":240},{"level":31,"move_id":16},{"level":41,"move_id":62},{"level":51,"move_id":54},{"level":61,"move_id":243},{"level":71,"move_id":56},{"level":81,"move_id":347}]},"tmhm_learnset":"03940E118C53767C","types":[11,11]},{"abilities":[62,0],"address":3303632,"base_stats":[50,64,50,41,45,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":247}],"friendship":35,"id":246,"learnset":{"address":3314268,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":36,"move_id":184},{"level":43,"move_id":242},{"level":50,"move_id":89},{"level":57,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[61,0],"address":3303660,"base_stats":[70,84,70,51,65,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":248}],"friendship":35,"id":247,"learnset":{"address":3314294,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":56,"move_id":89},{"level":65,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[45,0],"address":3303688,"base_stats":[100,134,110,61,95,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":248,"learnset":{"address":3314320,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":61,"move_id":89},{"level":75,"move_id":63}]},"tmhm_learnset":"00B41FF6CFD37E37","types":[5,17]},{"abilities":[46,0],"address":3303716,"base_stats":[106,90,130,110,90,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":249,"learnset":{"address":3314346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":56},{"level":55,"move_id":240},{"level":66,"move_id":129},{"level":77,"move_id":177},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"03B8CE93B7DFF67C","types":[14,2]},{"abilities":[46,0],"address":3303744,"base_stats":[106,130,90,90,110,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":250,"learnset":{"address":3314374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":126},{"level":55,"move_id":241},{"level":66,"move_id":129},{"level":77,"move_id":221},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"00EA4EB7B7BFC638","types":[10,2]},{"abilities":[30,0],"address":3303772,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":251,"learnset":{"address":3314402,"moves":[{"level":1,"move_id":73},{"level":1,"move_id":93},{"level":1,"move_id":105},{"level":1,"move_id":215},{"level":10,"move_id":219},{"level":20,"move_id":246},{"level":30,"move_id":248},{"level":40,"move_id":226},{"level":50,"move_id":195}]},"tmhm_learnset":"00448E93B43FC62C","types":[14,12]},{"abilities":[0,0],"address":3303800,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":252,"learnset":{"address":3314422,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303828,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":253,"learnset":{"address":3314432,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303856,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":254,"learnset":{"address":3314442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303884,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":255,"learnset":{"address":3314452,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303912,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":256,"learnset":{"address":3314462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303940,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":257,"learnset":{"address":3314472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303968,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":258,"learnset":{"address":3314482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303996,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":259,"learnset":{"address":3314492,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304024,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":260,"learnset":{"address":3314502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304052,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":261,"learnset":{"address":3314512,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304080,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":262,"learnset":{"address":3314522,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304108,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":263,"learnset":{"address":3314532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304136,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":264,"learnset":{"address":3314542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304164,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":265,"learnset":{"address":3314552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304192,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":266,"learnset":{"address":3314562,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304220,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":267,"learnset":{"address":3314572,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304248,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":268,"learnset":{"address":3314582,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304276,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":269,"learnset":{"address":3314592,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304304,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":270,"learnset":{"address":3314602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304332,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":271,"learnset":{"address":3314612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304360,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":272,"learnset":{"address":3314622,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304388,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":273,"learnset":{"address":3314632,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304416,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":274,"learnset":{"address":3314642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304444,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":275,"learnset":{"address":3314652,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304472,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":276,"learnset":{"address":3314662,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3304500,"base_stats":[40,45,35,70,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":278}],"friendship":70,"id":277,"learnset":{"address":3314672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":228},{"level":21,"move_id":103},{"level":26,"move_id":72},{"level":31,"move_id":97},{"level":36,"move_id":21},{"level":41,"move_id":197},{"level":46,"move_id":202}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304528,"base_stats":[50,65,45,95,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":279}],"friendship":70,"id":278,"learnset":{"address":3314700,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":41,"move_id":21},{"level":47,"move_id":197},{"level":53,"move_id":206}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304556,"base_stats":[70,85,65,120,105,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":279,"learnset":{"address":3314730,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":43,"move_id":21},{"level":51,"move_id":197},{"level":59,"move_id":206}]},"tmhm_learnset":"00E41EC0CE7D4733","types":[12,12]},{"abilities":[66,0],"address":3304584,"base_stats":[45,60,40,45,70,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":281}],"friendship":70,"id":280,"learnset":{"address":3314760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":116},{"level":10,"move_id":52},{"level":16,"move_id":64},{"level":19,"move_id":28},{"level":25,"move_id":83},{"level":28,"move_id":98},{"level":34,"move_id":163},{"level":37,"move_id":119},{"level":43,"move_id":53}]},"tmhm_learnset":"00A61EE48C110620","types":[10,10]},{"abilities":[66,0],"address":3304612,"base_stats":[60,85,60,55,85,60],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":282}],"friendship":70,"id":281,"learnset":{"address":3314788,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":39,"move_id":163},{"level":43,"move_id":119},{"level":50,"move_id":327}]},"tmhm_learnset":"00A61EE4CC1106A1","types":[10,1]},{"abilities":[66,0],"address":3304640,"base_stats":[80,120,70,80,110,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":282,"learnset":{"address":3314818,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":36,"move_id":299},{"level":42,"move_id":163},{"level":49,"move_id":119},{"level":59,"move_id":327}]},"tmhm_learnset":"00A61EE4CE1146B1","types":[10,1]},{"abilities":[67,0],"address":3304668,"base_stats":[50,70,50,40,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":284}],"friendship":70,"id":283,"learnset":{"address":3314852,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":19,"move_id":193},{"level":24,"move_id":300},{"level":28,"move_id":36},{"level":33,"move_id":250},{"level":37,"move_id":182},{"level":42,"move_id":56},{"level":46,"move_id":283}]},"tmhm_learnset":"03B01E408C533264","types":[11,11]},{"abilities":[67,0],"address":3304696,"base_stats":[70,85,70,50,60,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":285}],"friendship":70,"id":284,"learnset":{"address":3314882,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":37,"move_id":330},{"level":42,"move_id":182},{"level":46,"move_id":89},{"level":53,"move_id":283}]},"tmhm_learnset":"03B01E408E533264","types":[11,4]},{"abilities":[67,0],"address":3304724,"base_stats":[100,110,90,60,85,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":285,"learnset":{"address":3314914,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":39,"move_id":330},{"level":46,"move_id":182},{"level":52,"move_id":89},{"level":61,"move_id":283}]},"tmhm_learnset":"03B01E40CE537275","types":[11,4]},{"abilities":[50,0],"address":3304752,"base_stats":[35,55,35,35,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":287}],"friendship":70,"id":286,"learnset":{"address":3314946,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":21,"move_id":46},{"level":25,"move_id":207},{"level":29,"move_id":184},{"level":33,"move_id":36},{"level":37,"move_id":269},{"level":41,"move_id":242},{"level":45,"move_id":168}]},"tmhm_learnset":"00813F00AC530E30","types":[17,17]},{"abilities":[22,0],"address":3304780,"base_stats":[70,90,70,70,60,60],"catch_rate":127,"evolutions":[],"friendship":70,"id":287,"learnset":{"address":3314978,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":336},{"level":1,"move_id":28},{"level":1,"move_id":44},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":22,"move_id":46},{"level":27,"move_id":207},{"level":32,"move_id":184},{"level":37,"move_id":36},{"level":42,"move_id":269},{"level":47,"move_id":242},{"level":52,"move_id":168}]},"tmhm_learnset":"00A13F00AC534E30","types":[17,17]},{"abilities":[53,0],"address":3304808,"base_stats":[38,30,41,60,30,41],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":289}],"friendship":70,"id":288,"learnset":{"address":3315010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":21,"move_id":300},{"level":25,"move_id":42},{"level":29,"move_id":343},{"level":33,"move_id":175},{"level":37,"move_id":156},{"level":41,"move_id":187}]},"tmhm_learnset":"00943E02ADD33624","types":[0,0]},{"abilities":[53,0],"address":3304836,"base_stats":[78,70,61,100,50,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":289,"learnset":{"address":3315040,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":23,"move_id":300},{"level":29,"move_id":154},{"level":35,"move_id":343},{"level":41,"move_id":163},{"level":47,"move_id":156},{"level":53,"move_id":187}]},"tmhm_learnset":"00B43E02ADD37634","types":[0,0]},{"abilities":[19,0],"address":3304864,"base_stats":[45,45,35,20,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_SILCOON","param":7,"species":291},{"method":"LEVEL_CASCOON","param":7,"species":293}],"friendship":70,"id":290,"learnset":{"address":3315070,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81},{"level":5,"move_id":40}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3304892,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":292}],"friendship":70,"id":291,"learnset":{"address":3315082,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[68,0],"address":3304920,"base_stats":[60,70,50,65,90,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":292,"learnset":{"address":3315094,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":10,"move_id":71},{"level":13,"move_id":16},{"level":17,"move_id":78},{"level":20,"move_id":234},{"level":24,"move_id":72},{"level":27,"move_id":18},{"level":31,"move_id":213},{"level":34,"move_id":318},{"level":38,"move_id":202}]},"tmhm_learnset":"00403E80B43D4620","types":[6,2]},{"abilities":[61,0],"address":3304948,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":294}],"friendship":70,"id":293,"learnset":{"address":3315122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[19,0],"address":3304976,"base_stats":[60,50,70,65,50,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":294,"learnset":{"address":3315134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":16},{"level":17,"move_id":182},{"level":20,"move_id":236},{"level":24,"move_id":60},{"level":27,"move_id":18},{"level":31,"move_id":113},{"level":34,"move_id":318},{"level":38,"move_id":92}]},"tmhm_learnset":"00403E88B435C620","types":[6,3]},{"abilities":[33,44],"address":3305004,"base_stats":[40,30,30,30,40,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":296}],"friendship":70,"id":295,"learnset":{"address":3315162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":21,"move_id":54},{"level":31,"move_id":240},{"level":43,"move_id":72}]},"tmhm_learnset":"00503E0084373764","types":[11,12]},{"abilities":[33,44],"address":3305032,"base_stats":[60,50,50,50,60,70],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":297}],"friendship":70,"id":296,"learnset":{"address":3315184,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":154},{"level":31,"move_id":346},{"level":37,"move_id":168},{"level":43,"move_id":253},{"level":49,"move_id":56}]},"tmhm_learnset":"03F03E00C4373764","types":[11,12]},{"abilities":[33,44],"address":3305060,"base_stats":[80,70,70,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":297,"learnset":{"address":3315212,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":45},{"level":1,"move_id":71},{"level":1,"move_id":267}]},"tmhm_learnset":"03F03E00C4377765","types":[11,12]},{"abilities":[34,48],"address":3305088,"base_stats":[40,40,50,30,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":299}],"friendship":70,"id":298,"learnset":{"address":3315222,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":21,"move_id":235},{"level":31,"move_id":241},{"level":43,"move_id":153}]},"tmhm_learnset":"00C01E00AC350720","types":[12,12]},{"abilities":[34,48],"address":3305116,"base_stats":[70,70,40,60,60,40],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":300}],"friendship":70,"id":299,"learnset":{"address":3315244,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":259},{"level":31,"move_id":185},{"level":37,"move_id":13},{"level":43,"move_id":207},{"level":49,"move_id":326}]},"tmhm_learnset":"00E43F40EC354720","types":[12,17]},{"abilities":[34,48],"address":3305144,"base_stats":[90,100,60,80,90,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":300,"learnset":{"address":3315272,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":1,"move_id":74},{"level":1,"move_id":267}]},"tmhm_learnset":"00E43FC0EC354720","types":[12,17]},{"abilities":[14,0],"address":3305172,"base_stats":[31,45,90,40,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_NINJASK","param":20,"species":302},{"method":"LEVEL_SHEDINJA","param":20,"species":303}],"friendship":70,"id":301,"learnset":{"address":3315282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":206},{"level":31,"move_id":189},{"level":38,"move_id":232},{"level":45,"move_id":91}]},"tmhm_learnset":"00440E90AC350620","types":[6,4]},{"abilities":[3,0],"address":3305200,"base_stats":[61,90,45,160,50,50],"catch_rate":120,"evolutions":[],"friendship":70,"id":302,"learnset":{"address":3315308,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":141},{"level":1,"move_id":28},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":20,"move_id":104},{"level":20,"move_id":210},{"level":20,"move_id":103},{"level":25,"move_id":14},{"level":31,"move_id":163},{"level":38,"move_id":97},{"level":45,"move_id":226}]},"tmhm_learnset":"00443E90AC354620","types":[6,2]},{"abilities":[25,0],"address":3305228,"base_stats":[1,90,45,40,30,30],"catch_rate":45,"evolutions":[],"friendship":70,"id":303,"learnset":{"address":3315340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":180},{"level":31,"move_id":109},{"level":38,"move_id":247},{"level":45,"move_id":288}]},"tmhm_learnset":"00442E90AC354620","types":[6,7]},{"abilities":[62,0],"address":3305256,"base_stats":[40,55,30,85,30,30],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":305}],"friendship":70,"id":304,"learnset":{"address":3315366,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":26,"move_id":283},{"level":34,"move_id":332},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[62,0],"address":3305284,"base_stats":[60,85,60,125,50,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":305,"learnset":{"address":3315390,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":98},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":28,"move_id":283},{"level":38,"move_id":332},{"level":49,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[27,0],"address":3305312,"base_stats":[60,40,60,35,40,60],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":23,"species":307}],"friendship":70,"id":306,"learnset":{"address":3315414,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":28,"move_id":77},{"level":36,"move_id":74},{"level":45,"move_id":202},{"level":54,"move_id":147}]},"tmhm_learnset":"00411E08843D0720","types":[12,12]},{"abilities":[27,0],"address":3305340,"base_stats":[60,130,80,70,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":307,"learnset":{"address":3315442,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":33},{"level":1,"move_id":78},{"level":1,"move_id":73},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":23,"move_id":183},{"level":28,"move_id":68},{"level":36,"move_id":327},{"level":45,"move_id":170},{"level":54,"move_id":223}]},"tmhm_learnset":"00E51E08C47D47A1","types":[12,1]},{"abilities":[20,0],"address":3305368,"base_stats":[60,60,60,60,60,60],"catch_rate":255,"evolutions":[],"friendship":70,"id":308,"learnset":{"address":3315472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":253},{"level":12,"move_id":185},{"level":16,"move_id":60},{"level":23,"move_id":95},{"level":27,"move_id":146},{"level":34,"move_id":298},{"level":38,"move_id":244},{"level":45,"move_id":38},{"level":49,"move_id":175},{"level":56,"move_id":37}]},"tmhm_learnset":"00E1BE42FC1B062D","types":[0,0]},{"abilities":[51,0],"address":3305396,"base_stats":[40,30,30,85,55,30],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":310}],"friendship":70,"id":309,"learnset":{"address":3315502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":31,"move_id":98},{"level":43,"move_id":228},{"level":55,"move_id":97}]},"tmhm_learnset":"00087E8284133264","types":[11,2]},{"abilities":[51,0],"address":3305424,"base_stats":[60,50,100,65,85,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":310,"learnset":{"address":3315524,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":346},{"level":1,"move_id":17},{"level":3,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":25,"move_id":182},{"level":33,"move_id":254},{"level":33,"move_id":256},{"level":47,"move_id":255},{"level":61,"move_id":56}]},"tmhm_learnset":"00187E8284137264","types":[11,2]},{"abilities":[33,0],"address":3305452,"base_stats":[40,30,32,65,50,52],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":312}],"friendship":70,"id":311,"learnset":{"address":3315552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":25,"move_id":61},{"level":31,"move_id":97},{"level":37,"move_id":54},{"level":37,"move_id":114}]},"tmhm_learnset":"00403E00A4373624","types":[6,11]},{"abilities":[22,0],"address":3305480,"base_stats":[70,60,62,60,80,82],"catch_rate":75,"evolutions":[],"friendship":70,"id":312,"learnset":{"address":3315576,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":98},{"level":1,"move_id":230},{"level":1,"move_id":346},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":26,"move_id":16},{"level":33,"move_id":184},{"level":40,"move_id":78},{"level":47,"move_id":318},{"level":53,"move_id":18}]},"tmhm_learnset":"00403E80A4377624","types":[6,2]},{"abilities":[41,12],"address":3305508,"base_stats":[130,70,35,60,70,35],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":40,"species":314}],"friendship":70,"id":313,"learnset":{"address":3315602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":150},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":41,"move_id":323},{"level":46,"move_id":133},{"level":50,"move_id":56}]},"tmhm_learnset":"03B01E4086133274","types":[11,11]},{"abilities":[41,12],"address":3305536,"base_stats":[170,90,45,60,90,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":314,"learnset":{"address":3315634,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":205},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":44,"move_id":323},{"level":52,"move_id":133},{"level":59,"move_id":56}]},"tmhm_learnset":"03B01E4086137274","types":[11,11]},{"abilities":[56,0],"address":3305564,"base_stats":[50,45,45,50,35,35],"catch_rate":255,"evolutions":[{"method":"ITEM","param":94,"species":316}],"friendship":70,"id":315,"learnset":{"address":3315666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":3,"move_id":39},{"level":7,"move_id":213},{"level":13,"move_id":47},{"level":15,"move_id":3},{"level":19,"move_id":274},{"level":25,"move_id":204},{"level":27,"move_id":185},{"level":31,"move_id":343},{"level":37,"move_id":215},{"level":39,"move_id":38}]},"tmhm_learnset":"00401E02ADFB362C","types":[0,0]},{"abilities":[56,0],"address":3305592,"base_stats":[70,65,65,70,55,55],"catch_rate":60,"evolutions":[],"friendship":70,"id":316,"learnset":{"address":3315696,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":213},{"level":1,"move_id":47},{"level":1,"move_id":3}]},"tmhm_learnset":"00E01E02ADFB762C","types":[0,0]},{"abilities":[16,0],"address":3305620,"base_stats":[60,90,70,40,60,120],"catch_rate":200,"evolutions":[],"friendship":70,"id":317,"learnset":{"address":3315706,"moves":[{"level":1,"move_id":168},{"level":1,"move_id":39},{"level":1,"move_id":310},{"level":1,"move_id":122},{"level":1,"move_id":10},{"level":4,"move_id":20},{"level":7,"move_id":185},{"level":12,"move_id":154},{"level":17,"move_id":60},{"level":24,"move_id":103},{"level":31,"move_id":163},{"level":40,"move_id":164},{"level":49,"move_id":246}]},"tmhm_learnset":"00E5BEE6EDF33625","types":[0,0]},{"abilities":[26,0],"address":3305648,"base_stats":[40,40,55,55,40,70],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":36,"species":319}],"friendship":70,"id":318,"learnset":{"address":3315734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":37,"move_id":322},{"level":45,"move_id":153}]},"tmhm_learnset":"00408E51BE339620","types":[4,14]},{"abilities":[26,0],"address":3305676,"base_stats":[60,70,105,75,70,120],"catch_rate":90,"evolutions":[],"friendship":70,"id":319,"learnset":{"address":3315764,"moves":[{"level":1,"move_id":100},{"level":1,"move_id":93},{"level":1,"move_id":106},{"level":1,"move_id":229},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":36,"move_id":63},{"level":42,"move_id":322},{"level":55,"move_id":153}]},"tmhm_learnset":"00E08E51BE33D620","types":[4,14]},{"abilities":[5,42],"address":3305704,"base_stats":[30,45,135,30,45,90],"catch_rate":255,"evolutions":[],"friendship":70,"id":320,"learnset":{"address":3315796,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":106},{"level":13,"move_id":88},{"level":16,"move_id":335},{"level":22,"move_id":86},{"level":28,"move_id":157},{"level":31,"move_id":201},{"level":37,"move_id":156},{"level":43,"move_id":192},{"level":46,"move_id":199}]},"tmhm_learnset":"00A01F5287910E20","types":[5,5]},{"abilities":[73,0],"address":3305732,"base_stats":[70,85,140,20,85,70],"catch_rate":90,"evolutions":[],"friendship":70,"id":321,"learnset":{"address":3315824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":4,"move_id":123},{"level":7,"move_id":174},{"level":14,"move_id":108},{"level":17,"move_id":83},{"level":20,"move_id":34},{"level":27,"move_id":182},{"level":30,"move_id":53},{"level":33,"move_id":334},{"level":40,"move_id":133},{"level":43,"move_id":175},{"level":46,"move_id":257}]},"tmhm_learnset":"00A21E2C84510620","types":[10,10]},{"abilities":[51,0],"address":3305760,"base_stats":[50,75,75,50,65,65],"catch_rate":45,"evolutions":[],"friendship":35,"id":322,"learnset":{"address":3315856,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":10},{"level":5,"move_id":193},{"level":9,"move_id":101},{"level":13,"move_id":310},{"level":17,"move_id":154},{"level":21,"move_id":252},{"level":25,"move_id":197},{"level":29,"move_id":185},{"level":33,"move_id":282},{"level":37,"move_id":109},{"level":41,"move_id":247},{"level":45,"move_id":212}]},"tmhm_learnset":"00C53FC2FC130E2D","types":[17,7]},{"abilities":[12,0],"address":3305788,"base_stats":[50,48,43,60,46,41],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":324}],"friendship":70,"id":323,"learnset":{"address":3315888,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":189},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":31,"move_id":89},{"level":36,"move_id":248},{"level":41,"move_id":90}]},"tmhm_learnset":"03101E5086133264","types":[11,4]},{"abilities":[12,0],"address":3305816,"base_stats":[110,78,73,60,76,71],"catch_rate":75,"evolutions":[],"friendship":70,"id":324,"learnset":{"address":3315918,"moves":[{"level":1,"move_id":321},{"level":1,"move_id":189},{"level":1,"move_id":300},{"level":1,"move_id":346},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":36,"move_id":89},{"level":46,"move_id":248},{"level":56,"move_id":90}]},"tmhm_learnset":"03B01E5086137264","types":[11,4]},{"abilities":[33,0],"address":3305844,"base_stats":[43,30,55,97,40,65],"catch_rate":225,"evolutions":[],"friendship":70,"id":325,"learnset":{"address":3315948,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":204},{"level":12,"move_id":55},{"level":16,"move_id":97},{"level":24,"move_id":36},{"level":28,"move_id":213},{"level":36,"move_id":186},{"level":40,"move_id":175},{"level":48,"move_id":219}]},"tmhm_learnset":"03101E00841B3264","types":[11,11]},{"abilities":[52,75],"address":3305872,"base_stats":[43,80,65,35,50,35],"catch_rate":205,"evolutions":[{"method":"LEVEL","param":30,"species":327}],"friendship":70,"id":326,"learnset":{"address":3315974,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":32,"move_id":269},{"level":35,"move_id":152},{"level":38,"move_id":14},{"level":44,"move_id":12}]},"tmhm_learnset":"01B41EC8CC133A64","types":[11,11]},{"abilities":[52,75],"address":3305900,"base_stats":[63,120,85,55,90,55],"catch_rate":155,"evolutions":[],"friendship":70,"id":327,"learnset":{"address":3316004,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":106},{"level":1,"move_id":11},{"level":1,"move_id":43},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":34,"move_id":269},{"level":39,"move_id":152},{"level":44,"move_id":14},{"level":52,"move_id":12}]},"tmhm_learnset":"03B41EC8CC137A64","types":[11,17]},{"abilities":[33,0],"address":3305928,"base_stats":[20,15,20,80,10,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":30,"species":329}],"friendship":70,"id":328,"learnset":{"address":3316034,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[63,0],"address":3305956,"base_stats":[95,60,79,81,100,125],"catch_rate":60,"evolutions":[],"friendship":70,"id":329,"learnset":{"address":3316048,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":5,"move_id":35},{"level":10,"move_id":346},{"level":15,"move_id":287},{"level":20,"move_id":352},{"level":25,"move_id":239},{"level":30,"move_id":105},{"level":35,"move_id":240},{"level":40,"move_id":56},{"level":45,"move_id":213},{"level":50,"move_id":219}]},"tmhm_learnset":"03101E00845B7264","types":[11,11]},{"abilities":[24,0],"address":3305984,"base_stats":[45,90,20,65,65,20],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":30,"species":331}],"friendship":35,"id":330,"learnset":{"address":3316078,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":31,"move_id":36},{"level":37,"move_id":207},{"level":43,"move_id":97}]},"tmhm_learnset":"03103F0084133A64","types":[11,17]},{"abilities":[24,0],"address":3306012,"base_stats":[70,120,40,95,95,40],"catch_rate":60,"evolutions":[],"friendship":35,"id":331,"learnset":{"address":3316104,"moves":[{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":1,"move_id":99},{"level":1,"move_id":116},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":33,"move_id":163},{"level":38,"move_id":269},{"level":43,"move_id":207},{"level":48,"move_id":130},{"level":53,"move_id":97}]},"tmhm_learnset":"03B03F4086137A74","types":[11,17]},{"abilities":[52,71],"address":3306040,"base_stats":[45,100,45,10,45,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":333}],"friendship":70,"id":332,"learnset":{"address":3316134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":41,"move_id":91},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A01E508E354620","types":[4,4]},{"abilities":[26,26],"address":3306068,"base_stats":[50,70,50,70,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":45,"species":334}],"friendship":70,"id":333,"learnset":{"address":3316158,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A85E508E354620","types":[4,16]},{"abilities":[26,26],"address":3306096,"base_stats":[80,100,80,100,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":334,"learnset":{"address":3316184,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":53,"move_id":201},{"level":65,"move_id":63}]},"tmhm_learnset":"00A85E748E754622","types":[4,16]},{"abilities":[47,62],"address":3306124,"base_stats":[72,60,30,25,20,30],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":24,"species":336}],"friendship":70,"id":335,"learnset":{"address":3316210,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":28,"move_id":282},{"level":31,"move_id":265},{"level":37,"move_id":187},{"level":40,"move_id":203},{"level":46,"move_id":69},{"level":49,"move_id":179}]},"tmhm_learnset":"00B01E40CE1306A1","types":[1,1]},{"abilities":[47,62],"address":3306152,"base_stats":[144,120,60,50,40,60],"catch_rate":200,"evolutions":[],"friendship":70,"id":336,"learnset":{"address":3316242,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":1,"move_id":28},{"level":1,"move_id":292},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":29,"move_id":282},{"level":33,"move_id":265},{"level":40,"move_id":187},{"level":44,"move_id":203},{"level":51,"move_id":69},{"level":55,"move_id":179}]},"tmhm_learnset":"00B01E40CE1346A1","types":[1,1]},{"abilities":[9,31],"address":3306180,"base_stats":[40,45,40,65,65,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":26,"species":338}],"friendship":70,"id":337,"learnset":{"address":3316274,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":28,"move_id":46},{"level":33,"move_id":44},{"level":36,"move_id":87},{"level":41,"move_id":268}]},"tmhm_learnset":"00603E0285D30230","types":[13,13]},{"abilities":[9,31],"address":3306208,"base_stats":[70,75,60,105,105,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":338,"learnset":{"address":3316304,"moves":[{"level":1,"move_id":86},{"level":1,"move_id":43},{"level":1,"move_id":336},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":31,"move_id":46},{"level":39,"move_id":44},{"level":45,"move_id":87},{"level":53,"move_id":268}]},"tmhm_learnset":"00603E0285D34230","types":[13,13]},{"abilities":[12,0],"address":3306236,"base_stats":[60,60,40,35,65,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":33,"species":340}],"friendship":70,"id":339,"learnset":{"address":3316334,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":35,"move_id":89},{"level":41,"move_id":53},{"level":49,"move_id":38}]},"tmhm_learnset":"00A21E748E110620","types":[10,4]},{"abilities":[40,0],"address":3306264,"base_stats":[70,100,70,40,105,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":340,"learnset":{"address":3316360,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":1,"move_id":52},{"level":1,"move_id":222},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":33,"move_id":157},{"level":37,"move_id":89},{"level":45,"move_id":284},{"level":55,"move_id":90}]},"tmhm_learnset":"00A21E748E114630","types":[10,4]},{"abilities":[47,0],"address":3306292,"base_stats":[70,40,50,25,55,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":342}],"friendship":70,"id":341,"learnset":{"address":3316388,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":59},{"level":49,"move_id":329}]},"tmhm_learnset":"03B01E4086533264","types":[15,11]},{"abilities":[47,0],"address":3306320,"base_stats":[90,60,70,45,75,70],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":44,"species":343}],"friendship":70,"id":342,"learnset":{"address":3316416,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":47,"move_id":59},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E4086533274","types":[15,11]},{"abilities":[47,0],"address":3306348,"base_stats":[110,80,90,65,95,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":343,"learnset":{"address":3316444,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":50,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"03B01E4086537274","types":[15,11]},{"abilities":[8,0],"address":3306376,"base_stats":[50,85,40,35,85,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":32,"species":345}],"friendship":35,"id":344,"learnset":{"address":3316472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":33,"move_id":191},{"level":37,"move_id":302},{"level":41,"move_id":178},{"level":45,"move_id":201}]},"tmhm_learnset":"00441E1084350721","types":[12,12]},{"abilities":[8,0],"address":3306404,"base_stats":[70,115,60,55,115,60],"catch_rate":60,"evolutions":[],"friendship":35,"id":345,"learnset":{"address":3316504,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":74},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":35,"move_id":191},{"level":41,"move_id":302},{"level":47,"move_id":178},{"level":53,"move_id":201}]},"tmhm_learnset":"00641E1084354721","types":[12,17]},{"abilities":[39,0],"address":3306432,"base_stats":[50,50,50,50,50,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":42,"species":347}],"friendship":70,"id":346,"learnset":{"address":3316536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":37,"move_id":258},{"level":43,"move_id":59}]},"tmhm_learnset":"00401E00A41BB264","types":[15,15]},{"abilities":[39,0],"address":3306460,"base_stats":[80,80,80,80,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":347,"learnset":{"address":3316564,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":1,"move_id":104},{"level":1,"move_id":44},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":42,"move_id":258},{"level":53,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"00401F00A61BFA64","types":[15,15]},{"abilities":[26,0],"address":3306488,"base_stats":[70,55,65,70,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":348,"learnset":{"address":3316594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":95},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":94},{"level":43,"move_id":248},{"level":49,"move_id":153}]},"tmhm_learnset":"00408E51B61BD228","types":[5,14]},{"abilities":[26,0],"address":3306516,"base_stats":[70,95,85,70,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":349,"learnset":{"address":3316620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":83},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":157},{"level":43,"move_id":76},{"level":49,"move_id":153}]},"tmhm_learnset":"00428E75B639C628","types":[5,14]},{"abilities":[47,37],"address":3306544,"base_stats":[50,20,40,20,20,40],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":183}],"friendship":70,"id":350,"learnset":{"address":3316646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":150},{"level":3,"move_id":204},{"level":6,"move_id":39},{"level":10,"move_id":145},{"level":15,"move_id":21},{"level":21,"move_id":55}]},"tmhm_learnset":"01101E0084533264","types":[0,0]},{"abilities":[47,20],"address":3306572,"base_stats":[60,25,35,60,70,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":352}],"friendship":70,"id":351,"learnset":{"address":3316666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":1,"move_id":150},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":34,"move_id":94},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":340}]},"tmhm_learnset":"0041BF03B4538E28","types":[14,14]},{"abilities":[47,20],"address":3306600,"base_stats":[80,45,65,80,90,110],"catch_rate":60,"evolutions":[],"friendship":70,"id":352,"learnset":{"address":3316696,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":149},{"level":1,"move_id":316},{"level":1,"move_id":60},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":37,"move_id":94},{"level":43,"move_id":156},{"level":43,"move_id":173},{"level":55,"move_id":340}]},"tmhm_learnset":"0041BF03B453CE29","types":[14,14]},{"abilities":[57,0],"address":3306628,"base_stats":[60,50,40,95,85,75],"catch_rate":200,"evolutions":[],"friendship":70,"id":353,"learnset":{"address":3316726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":313},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[58,0],"address":3306656,"base_stats":[60,40,50,95,75,85],"catch_rate":200,"evolutions":[],"friendship":70,"id":354,"learnset":{"address":3316756,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":204},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[52,22],"address":3306684,"base_stats":[50,85,85,50,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":355,"learnset":{"address":3316786,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":6,"move_id":313},{"level":11,"move_id":44},{"level":16,"move_id":230},{"level":21,"move_id":11},{"level":26,"move_id":185},{"level":31,"move_id":226},{"level":36,"move_id":242},{"level":41,"move_id":334},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255}]},"tmhm_learnset":"00A01F7CC4335E21","types":[8,8]},{"abilities":[74,0],"address":3306712,"base_stats":[30,40,55,60,40,55],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":37,"species":357}],"friendship":70,"id":356,"learnset":{"address":3316818,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":38,"move_id":244},{"level":42,"move_id":179},{"level":48,"move_id":105}]},"tmhm_learnset":"00E01E41F41386A9","types":[1,14]},{"abilities":[74,0],"address":3306740,"base_stats":[60,60,75,80,60,75],"catch_rate":90,"evolutions":[],"friendship":70,"id":357,"learnset":{"address":3316848,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":9},{"level":1,"move_id":8},{"level":1,"move_id":117},{"level":1,"move_id":96},{"level":1,"move_id":93},{"level":1,"move_id":197},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":40,"move_id":244},{"level":46,"move_id":179},{"level":54,"move_id":105}]},"tmhm_learnset":"00E01E41F413C6A9","types":[1,14]},{"abilities":[30,0],"address":3306768,"base_stats":[45,40,60,50,40,75],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":359}],"friendship":70,"id":358,"learnset":{"address":3316884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":38,"move_id":119},{"level":41,"move_id":287},{"level":48,"move_id":195}]},"tmhm_learnset":"00087E80843B1620","types":[0,2]},{"abilities":[30,0],"address":3306796,"base_stats":[75,70,90,80,70,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":359,"learnset":{"address":3316912,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":310},{"level":1,"move_id":47},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":35,"move_id":225},{"level":40,"move_id":349},{"level":45,"move_id":287},{"level":54,"move_id":195},{"level":59,"move_id":143}]},"tmhm_learnset":"00887EA4867B5632","types":[16,2]},{"abilities":[23,0],"address":3306824,"base_stats":[95,23,48,23,23,48],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":15,"species":202}],"friendship":70,"id":360,"learnset":{"address":3316944,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":150},{"level":1,"move_id":204},{"level":1,"move_id":227},{"level":15,"move_id":68},{"level":15,"move_id":243},{"level":15,"move_id":219},{"level":15,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[26,0],"address":3306852,"base_stats":[20,40,90,25,30,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":362}],"friendship":35,"id":361,"learnset":{"address":3316962,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":38,"move_id":261},{"level":45,"move_id":212},{"level":49,"move_id":248}]},"tmhm_learnset":"0041BF00B4133E28","types":[7,7]},{"abilities":[46,0],"address":3306880,"base_stats":[40,70,130,25,60,130],"catch_rate":90,"evolutions":[],"friendship":35,"id":362,"learnset":{"address":3316990,"moves":[{"level":1,"move_id":20},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":1,"move_id":50},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":37,"move_id":325},{"level":41,"move_id":261},{"level":51,"move_id":212},{"level":58,"move_id":248}]},"tmhm_learnset":"00E1BF40B6137E29","types":[7,7]},{"abilities":[30,38],"address":3306908,"base_stats":[50,60,45,65,100,80],"catch_rate":150,"evolutions":[],"friendship":70,"id":363,"learnset":{"address":3317020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":5,"move_id":74},{"level":9,"move_id":40},{"level":13,"move_id":78},{"level":17,"move_id":72},{"level":21,"move_id":73},{"level":25,"move_id":345},{"level":29,"move_id":320},{"level":33,"move_id":202},{"level":37,"move_id":230},{"level":41,"move_id":275},{"level":45,"move_id":92},{"level":49,"move_id":80},{"level":53,"move_id":312},{"level":57,"move_id":235}]},"tmhm_learnset":"00441E08A4350720","types":[12,3]},{"abilities":[54,0],"address":3306936,"base_stats":[60,60,60,30,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":365}],"friendship":70,"id":364,"learnset":{"address":3317058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E5B336A5","types":[0,0]},{"abilities":[72,0],"address":3306964,"base_stats":[80,80,80,90,55,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":366}],"friendship":70,"id":365,"learnset":{"address":3317082,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":116},{"level":1,"move_id":227},{"level":1,"move_id":253},{"level":7,"move_id":227},{"level":13,"move_id":253},{"level":19,"move_id":154},{"level":25,"move_id":203},{"level":31,"move_id":163},{"level":37,"move_id":68},{"level":43,"move_id":264},{"level":49,"move_id":179}]},"tmhm_learnset":"00A41EA6E7B33EB5","types":[0,0]},{"abilities":[54,0],"address":3306992,"base_stats":[150,160,100,100,95,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":366,"learnset":{"address":3317108,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":1,"move_id":227},{"level":1,"move_id":303},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":36,"move_id":207},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E7B37EB5","types":[0,0]},{"abilities":[64,60],"address":3307020,"base_stats":[70,43,53,40,43,53],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":26,"species":368}],"friendship":70,"id":367,"learnset":{"address":3317134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":28,"move_id":92},{"level":34,"move_id":254},{"level":34,"move_id":255},{"level":34,"move_id":256},{"level":39,"move_id":188}]},"tmhm_learnset":"00A11E0AA4371724","types":[3,3]},{"abilities":[64,60],"address":3307048,"base_stats":[100,73,83,55,73,83],"catch_rate":75,"evolutions":[],"friendship":70,"id":368,"learnset":{"address":3317164,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":281},{"level":1,"move_id":139},{"level":1,"move_id":124},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":26,"move_id":34},{"level":31,"move_id":92},{"level":40,"move_id":254},{"level":40,"move_id":255},{"level":40,"move_id":256},{"level":48,"move_id":188}]},"tmhm_learnset":"00A11E0AA4375724","types":[3,3]},{"abilities":[34,0],"address":3307076,"base_stats":[99,68,83,51,72,87],"catch_rate":200,"evolutions":[],"friendship":70,"id":369,"learnset":{"address":3317196,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":16},{"level":7,"move_id":74},{"level":11,"move_id":75},{"level":17,"move_id":23},{"level":21,"move_id":230},{"level":27,"move_id":18},{"level":31,"move_id":345},{"level":37,"move_id":34},{"level":41,"move_id":76},{"level":47,"move_id":235}]},"tmhm_learnset":"00EC5E80863D4730","types":[12,2]},{"abilities":[43,0],"address":3307104,"base_stats":[64,51,23,28,51,23],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":20,"species":371}],"friendship":70,"id":370,"learnset":{"address":3317224,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":21,"move_id":48},{"level":25,"move_id":23},{"level":31,"move_id":103},{"level":35,"move_id":46},{"level":41,"move_id":156},{"level":41,"move_id":214},{"level":45,"move_id":304}]},"tmhm_learnset":"00001E26A4333634","types":[0,0]},{"abilities":[43,0],"address":3307132,"base_stats":[84,71,43,48,71,43],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":40,"species":372}],"friendship":70,"id":371,"learnset":{"address":3317254,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":43,"move_id":46},{"level":51,"move_id":156},{"level":51,"move_id":214},{"level":57,"move_id":304}]},"tmhm_learnset":"00A21F26E6333E34","types":[0,0]},{"abilities":[43,0],"address":3307160,"base_stats":[104,91,63,68,91,63],"catch_rate":45,"evolutions":[],"friendship":70,"id":372,"learnset":{"address":3317284,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":40,"move_id":63},{"level":45,"move_id":46},{"level":55,"move_id":156},{"level":55,"move_id":214},{"level":63,"move_id":304}]},"tmhm_learnset":"00A21F26E6337E34","types":[0,0]},{"abilities":[75,0],"address":3307188,"base_stats":[35,64,85,32,74,55],"catch_rate":255,"evolutions":[{"method":"ITEM","param":192,"species":374},{"method":"ITEM","param":193,"species":375}],"friendship":70,"id":373,"learnset":{"address":3317316,"moves":[{"level":1,"move_id":128},{"level":1,"move_id":55},{"level":1,"move_id":250},{"level":1,"move_id":334}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,0],"address":3307216,"base_stats":[55,104,105,52,94,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":374,"learnset":{"address":3317326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":44},{"level":15,"move_id":103},{"level":22,"move_id":352},{"level":29,"move_id":184},{"level":36,"move_id":242},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03111E4084137264","types":[11,11]},{"abilities":[33,0],"address":3307244,"base_stats":[55,84,105,52,114,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":375,"learnset":{"address":3317350,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":93},{"level":15,"move_id":97},{"level":22,"move_id":352},{"level":29,"move_id":133},{"level":36,"move_id":94},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03101E00B41B7264","types":[11,11]},{"abilities":[46,0],"address":3307272,"base_stats":[65,130,60,75,75,60],"catch_rate":30,"evolutions":[],"friendship":35,"id":376,"learnset":{"address":3317374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":5,"move_id":43},{"level":9,"move_id":269},{"level":13,"move_id":98},{"level":17,"move_id":13},{"level":21,"move_id":44},{"level":26,"move_id":14},{"level":31,"move_id":104},{"level":36,"move_id":163},{"level":41,"move_id":248},{"level":46,"move_id":195}]},"tmhm_learnset":"00E53FB6A5D37E6C","types":[17,17]},{"abilities":[15,0],"address":3307300,"base_stats":[44,75,35,45,63,33],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":37,"species":378}],"friendship":35,"id":377,"learnset":{"address":3317404,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":282},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":37,"move_id":185},{"level":44,"move_id":247},{"level":49,"move_id":289},{"level":56,"move_id":288}]},"tmhm_learnset":"0041BF02B5930E28","types":[7,7]},{"abilities":[15,0],"address":3307328,"base_stats":[64,115,65,65,83,63],"catch_rate":45,"evolutions":[],"friendship":35,"id":378,"learnset":{"address":3317432,"moves":[{"level":1,"move_id":282},{"level":1,"move_id":103},{"level":1,"move_id":101},{"level":1,"move_id":174},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":39,"move_id":185},{"level":48,"move_id":247},{"level":55,"move_id":289},{"level":64,"move_id":288}]},"tmhm_learnset":"0041BF02B5934E28","types":[7,7]},{"abilities":[61,0],"address":3307356,"base_stats":[73,100,60,65,100,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":379,"learnset":{"address":3317460,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":7,"move_id":122},{"level":10,"move_id":44},{"level":16,"move_id":342},{"level":19,"move_id":103},{"level":25,"move_id":137},{"level":28,"move_id":242},{"level":34,"move_id":305},{"level":37,"move_id":207},{"level":43,"move_id":114}]},"tmhm_learnset":"00A13E0C8E570E20","types":[3,3]},{"abilities":[17,0],"address":3307384,"base_stats":[73,115,60,90,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":380,"learnset":{"address":3317488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":43},{"level":7,"move_id":98},{"level":10,"move_id":14},{"level":13,"move_id":210},{"level":19,"move_id":163},{"level":25,"move_id":228},{"level":31,"move_id":306},{"level":37,"move_id":269},{"level":46,"move_id":197},{"level":55,"move_id":206}]},"tmhm_learnset":"00A03EA6EDF73E35","types":[0,0]},{"abilities":[33,69],"address":3307412,"base_stats":[100,90,130,55,45,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":381,"learnset":{"address":3317518,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":8,"move_id":55},{"level":15,"move_id":317},{"level":22,"move_id":281},{"level":29,"move_id":36},{"level":36,"move_id":300},{"level":43,"move_id":246},{"level":50,"move_id":156},{"level":57,"move_id":38},{"level":64,"move_id":56}]},"tmhm_learnset":"03901E50861B726C","types":[11,5]},{"abilities":[5,69],"address":3307440,"base_stats":[50,70,100,30,40,40],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":32,"species":383}],"friendship":35,"id":382,"learnset":{"address":3317546,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":34,"move_id":182},{"level":39,"move_id":319},{"level":44,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307468,"base_stats":[60,90,140,40,50,50],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":42,"species":384}],"friendship":35,"id":383,"learnset":{"address":3317578,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":45,"move_id":319},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307496,"base_stats":[70,110,180,50,60,60],"catch_rate":45,"evolutions":[],"friendship":35,"id":384,"learnset":{"address":3317610,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":50,"move_id":319},{"level":63,"move_id":38}]},"tmhm_learnset":"00B41EF6CFF37E37","types":[8,5]},{"abilities":[59,0],"address":3307524,"base_stats":[70,70,70,70,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":385,"learnset":{"address":3317642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":10,"move_id":55},{"level":10,"move_id":52},{"level":10,"move_id":181},{"level":20,"move_id":240},{"level":20,"move_id":241},{"level":20,"move_id":258},{"level":30,"move_id":311}]},"tmhm_learnset":"00403E36A5B33664","types":[0,0]},{"abilities":[35,68],"address":3307552,"base_stats":[65,73,55,85,47,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":386,"learnset":{"address":3317666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":109},{"level":9,"move_id":104},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":294},{"level":25,"move_id":324},{"level":29,"move_id":182},{"level":33,"move_id":270},{"level":37,"move_id":38}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[12,0],"address":3307580,"base_stats":[65,47,55,85,73,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":387,"learnset":{"address":3317694,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":230},{"level":9,"move_id":204},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":273},{"level":25,"move_id":227},{"level":29,"move_id":260},{"level":33,"move_id":270},{"level":37,"move_id":343}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[21,0],"address":3307608,"base_stats":[66,41,77,23,61,87],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":389}],"friendship":70,"id":388,"learnset":{"address":3317722,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":43,"move_id":246},{"level":50,"move_id":254},{"level":50,"move_id":255},{"level":50,"move_id":256}]},"tmhm_learnset":"00001E1884350720","types":[5,12]},{"abilities":[21,0],"address":3307636,"base_stats":[86,81,97,43,81,107],"catch_rate":45,"evolutions":[],"friendship":70,"id":389,"learnset":{"address":3317750,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":132},{"level":1,"move_id":51},{"level":1,"move_id":275},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":48,"move_id":246},{"level":60,"move_id":254},{"level":60,"move_id":255},{"level":60,"move_id":256}]},"tmhm_learnset":"00A01E5886354720","types":[5,12]},{"abilities":[4,0],"address":3307664,"base_stats":[45,95,50,75,40,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":391}],"friendship":70,"id":390,"learnset":{"address":3317778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":43,"move_id":210},{"level":49,"move_id":163},{"level":55,"move_id":350}]},"tmhm_learnset":"00841ED0CC110624","types":[5,6]},{"abilities":[4,0],"address":3307692,"base_stats":[75,125,100,45,70,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":391,"learnset":{"address":3317806,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":300},{"level":1,"move_id":55},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":46,"move_id":210},{"level":55,"move_id":163},{"level":64,"move_id":350}]},"tmhm_learnset":"00A41ED0CE514624","types":[5,6]},{"abilities":[28,36],"address":3307720,"base_stats":[28,25,25,40,45,35],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":20,"species":393}],"friendship":35,"id":392,"learnset":{"address":3317834,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":45},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":31,"move_id":286},{"level":36,"move_id":248},{"level":41,"move_id":95},{"level":46,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307748,"base_stats":[38,35,35,50,65,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":394}],"friendship":35,"id":393,"learnset":{"address":3317862,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":40,"move_id":248},{"level":47,"move_id":95},{"level":54,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307776,"base_stats":[68,65,65,80,125,115],"catch_rate":45,"evolutions":[],"friendship":35,"id":394,"learnset":{"address":3317890,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":42,"move_id":248},{"level":51,"move_id":95},{"level":60,"move_id":138}]},"tmhm_learnset":"0041BF03B49BCE28","types":[14,14]},{"abilities":[69,0],"address":3307804,"base_stats":[45,75,60,50,40,30],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":396}],"friendship":35,"id":395,"learnset":{"address":3317918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":33,"move_id":225},{"level":37,"move_id":184},{"level":41,"move_id":242},{"level":49,"move_id":337},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[69,0],"address":3307832,"base_stats":[65,95,100,50,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":50,"species":397}],"friendship":35,"id":396,"learnset":{"address":3317948,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":56,"move_id":242},{"level":69,"move_id":337},{"level":78,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[22,0],"address":3307860,"base_stats":[95,135,80,100,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":397,"learnset":{"address":3317980,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":50,"move_id":19},{"level":61,"move_id":242},{"level":79,"move_id":337},{"level":93,"move_id":38}]},"tmhm_learnset":"00AC5EE4C6534632","types":[16,2]},{"abilities":[29,0],"address":3307888,"base_stats":[40,55,80,30,35,60],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":20,"species":399}],"friendship":35,"id":398,"learnset":{"address":3318014,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36}]},"tmhm_learnset":"0000000000000000","types":[8,14]},{"abilities":[29,0],"address":3307916,"base_stats":[60,75,100,50,55,80],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":45,"species":400}],"friendship":35,"id":399,"learnset":{"address":3318024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":50,"move_id":309},{"level":56,"move_id":97},{"level":62,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307944,"base_stats":[80,135,130,70,95,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":400,"learnset":{"address":3318052,"moves":[{"level":1,"move_id":36},{"level":1,"move_id":93},{"level":1,"move_id":232},{"level":1,"move_id":184},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":55,"move_id":309},{"level":66,"move_id":97},{"level":77,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307972,"base_stats":[80,100,200,50,50,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":401,"learnset":{"address":3318080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":153},{"level":9,"move_id":88},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E52CF994621","types":[5,5]},{"abilities":[29,0],"address":3308000,"base_stats":[80,50,100,50,100,200],"catch_rate":3,"evolutions":[],"friendship":35,"id":402,"learnset":{"address":3318106,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":196},{"level":1,"move_id":153},{"level":9,"move_id":196},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E02C79B7261","types":[15,15]},{"abilities":[29,0],"address":3308028,"base_stats":[80,75,150,50,75,150],"catch_rate":3,"evolutions":[],"friendship":35,"id":403,"learnset":{"address":3318132,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":232},{"level":1,"move_id":153},{"level":9,"move_id":232},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00ED2C79B4621","types":[8,8]},{"abilities":[2,0],"address":3308056,"base_stats":[100,100,90,90,150,140],"catch_rate":5,"evolutions":[],"friendship":0,"id":404,"learnset":{"address":3318160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":352},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":34},{"level":30,"move_id":347},{"level":35,"move_id":58},{"level":45,"move_id":56},{"level":50,"move_id":156},{"level":60,"move_id":329},{"level":65,"move_id":38},{"level":75,"move_id":323}]},"tmhm_learnset":"03B00E42C79B727C","types":[11,11]},{"abilities":[70,0],"address":3308084,"base_stats":[100,150,140,90,100,90],"catch_rate":5,"evolutions":[],"friendship":0,"id":405,"learnset":{"address":3318190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":341},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":163},{"level":30,"move_id":339},{"level":35,"move_id":89},{"level":45,"move_id":126},{"level":50,"move_id":156},{"level":60,"move_id":90},{"level":65,"move_id":76},{"level":75,"move_id":284}]},"tmhm_learnset":"00A60EF6CFF946B2","types":[4,4]},{"abilities":[77,0],"address":3308112,"base_stats":[105,150,90,95,150,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":406,"learnset":{"address":3318220,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":239},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":337},{"level":30,"move_id":349},{"level":35,"move_id":242},{"level":45,"move_id":19},{"level":50,"move_id":156},{"level":60,"move_id":245},{"level":65,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BA0EB6C7F376B6","types":[16,2]},{"abilities":[26,0],"address":3308140,"base_stats":[80,80,90,110,110,130],"catch_rate":3,"evolutions":[],"friendship":90,"id":407,"learnset":{"address":3318250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":273},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":346},{"level":30,"move_id":287},{"level":35,"move_id":296},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":204}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[26,0],"address":3308168,"base_stats":[80,90,80,110,130,110],"catch_rate":3,"evolutions":[],"friendship":90,"id":408,"learnset":{"address":3318280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":262},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":182},{"level":30,"move_id":287},{"level":35,"move_id":295},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":349}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[32,0],"address":3308196,"base_stats":[100,100,100,100,100,100],"catch_rate":3,"evolutions":[],"friendship":100,"id":409,"learnset":{"address":3318310,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":273},{"level":1,"move_id":93},{"level":5,"move_id":156},{"level":10,"move_id":129},{"level":15,"move_id":270},{"level":20,"move_id":94},{"level":25,"move_id":287},{"level":30,"move_id":156},{"level":35,"move_id":38},{"level":40,"move_id":248},{"level":45,"move_id":322},{"level":50,"move_id":353}]},"tmhm_learnset":"00408E93B59BC62C","types":[8,14]},{"abilities":[46,0],"address":3308224,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":410,"learnset":{"address":3318340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":35},{"level":5,"move_id":101},{"level":10,"move_id":104},{"level":15,"move_id":282},{"level":20,"move_id":228},{"level":25,"move_id":94},{"level":30,"move_id":129},{"level":35,"move_id":97},{"level":40,"move_id":105},{"level":45,"move_id":354},{"level":50,"move_id":245}]},"tmhm_learnset":"00E58FC3F5BBDE2D","types":[14,14]},{"abilities":[26,0],"address":3308252,"base_stats":[65,50,70,65,95,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":411,"learnset":{"address":3318370,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":6,"move_id":45},{"level":9,"move_id":310},{"level":14,"move_id":93},{"level":17,"move_id":36},{"level":22,"move_id":253},{"level":25,"move_id":281},{"level":30,"move_id":149},{"level":33,"move_id":38},{"level":38,"move_id":215},{"level":41,"move_id":219},{"level":46,"move_id":94}]},"tmhm_learnset":"00419F03B41B8E28","types":[14,14]}],"tmhm_moves":[264,337,352,347,46,92,258,339,331,237,241,269,58,59,63,113,182,240,202,219,218,76,231,85,87,89,216,91,94,247,280,104,115,351,53,188,201,126,317,332,259,263,290,156,213,168,211,285,289,315,15,19,57,70,148,249,127,291],"trainers":[{"address":3230072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[],"party_address":4160749568,"script_address":0},{"address":3230112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":74}],"party_address":3211124,"script_address":2304511},{"address":3230152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":286}],"party_address":3211132,"script_address":2321901},{"address":3230192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":330}],"party_address":3211140,"script_address":2323326},{"address":3230232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211156,"script_address":2323373},{"address":3230272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211164,"script_address":2324386},{"address":3230312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":286}],"party_address":3211172,"script_address":2326808},{"address":3230352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211180,"script_address":2326839},{"address":3230392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":41}],"party_address":3211188,"script_address":2328040},{"address":3230432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":315},{"level":26,"species":286},{"level":26,"species":288},{"level":26,"species":295},{"level":26,"species":298},{"level":26,"species":304}],"party_address":3211196,"script_address":2314251},{"address":3230472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":286}],"party_address":3211244,"script_address":0},{"address":3230512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":300}],"party_address":3211252,"script_address":2067580},{"address":3230552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":310},{"level":30,"species":178}],"party_address":3211268,"script_address":2068523},{"address":3230592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":380},{"level":30,"species":379}],"party_address":3211284,"script_address":2068554},{"address":3230632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211300,"script_address":2328071},{"address":3230672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3211308,"script_address":2069620},{"address":3230712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":286}],"party_address":3211316,"script_address":0},{"address":3230752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3211324,"script_address":2570959},{"address":3230792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":286},{"level":27,"species":330}],"party_address":3211340,"script_address":2572093},{"address":3230832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":286},{"level":26,"species":41},{"level":26,"species":330}],"party_address":3211356,"script_address":2572124},{"address":3230872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":330}],"party_address":3211380,"script_address":2157889},{"address":3230912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":41},{"level":14,"species":330}],"party_address":3211388,"script_address":2157948},{"address":3230952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":339}],"party_address":3211404,"script_address":2254636},{"address":3230992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211412,"script_address":2317522},{"address":3231032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211420,"script_address":2317553},{"address":3231072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":286},{"level":30,"species":330}],"party_address":3211428,"script_address":2317584},{"address":3231112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330}],"party_address":3211444,"script_address":2570990},{"address":3231152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211452,"script_address":2323414},{"address":3231192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211460,"script_address":2324427},{"address":3231232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":335},{"level":30,"species":67}],"party_address":3211468,"script_address":2068492},{"address":3231272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":287},{"level":34,"species":42}],"party_address":3211484,"script_address":2324250},{"address":3231312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":336}],"party_address":3211500,"script_address":2312702},{"address":3231352,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330},{"level":28,"species":287}],"party_address":3211508,"script_address":2572155},{"address":3231392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":331},{"level":37,"species":287}],"party_address":3211524,"script_address":2327156},{"address":3231432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":287},{"level":41,"species":169},{"level":43,"species":331}],"party_address":3211540,"script_address":2328478},{"address":3231472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":351}],"party_address":3211564,"script_address":2312671},{"address":3231512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211572,"script_address":2026085},{"address":3231552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":363},{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211588,"script_address":2058784},{"address":3231592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,0,0,0],"species":357},{"level":43,"moves":[29,89,0,0],"species":319}],"party_address":3211612,"script_address":2335547},{"address":3231632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":363},{"level":26,"species":44}],"party_address":3211644,"script_address":2068148},{"address":3231672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":363}],"party_address":3211660,"script_address":0},{"address":3231712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":306},{"level":28,"species":44},{"level":28,"species":363}],"party_address":3211676,"script_address":0},{"address":3231752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":306},{"level":31,"species":44},{"level":31,"species":363}],"party_address":3211700,"script_address":0},{"address":3231792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307},{"level":34,"species":44},{"level":34,"species":363}],"party_address":3211724,"script_address":0},{"address":3231832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,163,28,40],"species":28}],"party_address":3211748,"script_address":2046490},{"address":3231872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[60,120,201,246],"species":318},{"level":27,"moves":[91,163,28,40],"species":27},{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211764,"script_address":2065682},{"address":3231912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[91,163,28,40],"species":27},{"level":25,"moves":[91,163,28,40],"species":28}],"party_address":3211812,"script_address":2033540},{"address":3231952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211844,"script_address":0},{"address":3231992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[91,163,28,40],"species":28}],"party_address":3211860,"script_address":0},{"address":3232032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[91,163,28,40],"species":28}],"party_address":3211876,"script_address":0},{"address":3232072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[91,163,28,40],"species":28}],"party_address":3211892,"script_address":0},{"address":3232112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":81},{"level":17,"species":370}],"party_address":3211908,"script_address":0},{"address":3232152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":81},{"level":27,"species":371}],"party_address":3211924,"script_address":0},{"address":3232192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":82},{"level":30,"species":371}],"party_address":3211940,"script_address":0},{"address":3232232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":82},{"level":33,"species":371}],"party_address":3211956,"script_address":0},{"address":3232272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82},{"level":36,"species":371}],"party_address":3211972,"script_address":0},{"address":3232312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[49,86,63,85],"species":82},{"level":39,"moves":[54,23,48,48],"species":372}],"party_address":3211988,"script_address":0},{"address":3232352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":350}],"party_address":3212020,"script_address":2036011},{"address":3232392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212036,"script_address":2036121},{"address":3232432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212044,"script_address":2036152},{"address":3232472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183},{"level":26,"species":183}],"party_address":3212052,"script_address":0},{"address":3232512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":183},{"level":29,"species":183}],"party_address":3212068,"script_address":0},{"address":3232552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":183},{"level":32,"species":183}],"party_address":3212084,"script_address":0},{"address":3232592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":35,"species":184}],"party_address":3212100,"script_address":0},{"address":3232632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":13,"moves":[28,29,39,57],"species":288}],"party_address":3212116,"script_address":2035901},{"address":3232672,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":183}],"party_address":3212132,"script_address":2544001},{"address":3232712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212148,"script_address":2339831},{"address":3232752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[28,42,39,57],"species":289}],"party_address":3212156,"script_address":0},{"address":3232792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[28,42,39,57],"species":289}],"party_address":3212172,"script_address":0},{"address":3232832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[28,42,39,57],"species":289}],"party_address":3212188,"script_address":0},{"address":3232872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[28,42,39,57],"species":289}],"party_address":3212204,"script_address":0},{"address":3232912,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[98,97,17,0],"species":305}],"party_address":3212220,"script_address":2131164},{"address":3232952,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[42,146,8,0],"species":308}],"party_address":3212236,"script_address":2131228},{"address":3232992,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[47,68,247,0],"species":364}],"party_address":3212252,"script_address":2131292},{"address":3233032,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[116,163,0,0],"species":365}],"party_address":3212268,"script_address":2131356},{"address":3233072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[116,98,17,27],"species":305},{"level":28,"moves":[44,91,185,72],"species":332},{"level":28,"moves":[205,250,54,96],"species":313},{"level":28,"moves":[85,48,86,49],"species":82},{"level":28,"moves":[202,185,104,207],"species":300}],"party_address":3212284,"script_address":2068117},{"address":3233112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":322},{"level":44,"species":357},{"level":44,"species":331}],"party_address":3212364,"script_address":2565920},{"address":3233152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":355},{"level":46,"species":121}],"party_address":3212388,"script_address":2565982},{"address":3233192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":337},{"level":17,"species":313},{"level":17,"species":335}],"party_address":3212404,"script_address":2046693},{"address":3233232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":345},{"level":43,"species":310}],"party_address":3212428,"script_address":2332685},{"address":3233272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":82},{"level":43,"species":89}],"party_address":3212444,"script_address":2332716},{"address":3233312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":305},{"level":42,"species":355},{"level":42,"species":64}],"party_address":3212460,"script_address":2334375},{"address":3233352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":85},{"level":42,"species":64},{"level":42,"species":101},{"level":42,"species":300}],"party_address":3212484,"script_address":2335423},{"address":3233392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":317},{"level":42,"species":75},{"level":42,"species":314}],"party_address":3212516,"script_address":2335454},{"address":3233432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":337},{"level":26,"species":313},{"level":26,"species":335}],"party_address":3212540,"script_address":0},{"address":3233472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":313},{"level":29,"species":335}],"party_address":3212564,"script_address":0},{"address":3233512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":338},{"level":32,"species":313},{"level":32,"species":335}],"party_address":3212588,"script_address":0},{"address":3233552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":338},{"level":35,"species":313},{"level":35,"species":336}],"party_address":3212612,"script_address":0},{"address":3233592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":297}],"party_address":3212636,"script_address":2073950},{"address":3233632,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[185,95,0,0],"species":316}],"party_address":3212652,"script_address":2131420},{"address":3233672,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[111,38,247,0],"species":40}],"party_address":3212668,"script_address":2131484},{"address":3233712,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[14,163,0,0],"species":380}],"party_address":3212684,"script_address":2131548},{"address":3233752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[226,185,57,44],"species":355},{"level":29,"moves":[72,89,64,73],"species":363},{"level":29,"moves":[19,55,54,182],"species":310}],"party_address":3212700,"script_address":2068086},{"address":3233792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":383},{"level":45,"species":338}],"party_address":3212748,"script_address":2565951},{"address":3233832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":309},{"level":17,"species":339},{"level":17,"species":363}],"party_address":3212764,"script_address":2046803},{"address":3233872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":322}],"party_address":3212788,"script_address":2065651},{"address":3233912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3212796,"script_address":2332747},{"address":3233952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":319}],"party_address":3212804,"script_address":2334406},{"address":3233992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":321},{"level":42,"species":357},{"level":42,"species":297}],"party_address":3212812,"script_address":2334437},{"address":3234032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":227},{"level":43,"species":322}],"party_address":3212836,"script_address":2335485},{"address":3234072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":28},{"level":42,"species":38},{"level":42,"species":369}],"party_address":3212852,"script_address":2335516},{"address":3234112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":26,"species":339},{"level":26,"species":363}],"party_address":3212876,"script_address":0},{"address":3234152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":339},{"level":29,"species":363}],"party_address":3212900,"script_address":0},{"address":3234192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":339},{"level":32,"species":363}],"party_address":3212924,"script_address":0},{"address":3234232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":340},{"level":34,"species":363}],"party_address":3212948,"script_address":0},{"address":3234272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":348}],"party_address":3212972,"script_address":2564729},{"address":3234312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":361},{"level":30,"species":377}],"party_address":3212988,"script_address":2068461},{"address":3234352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":361},{"level":29,"species":377}],"party_address":3213004,"script_address":2067284},{"address":3234392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":322}],"party_address":3213020,"script_address":2315745},{"address":3234432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":377}],"party_address":3213028,"script_address":2315532},{"address":3234472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":322},{"level":31,"species":351}],"party_address":3213036,"script_address":0},{"address":3234512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":351},{"level":35,"species":322}],"party_address":3213052,"script_address":0},{"address":3234552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":351},{"level":40,"species":322}],"party_address":3213068,"script_address":0},{"address":3234592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":361},{"level":42,"species":322},{"level":42,"species":352}],"party_address":3213084,"script_address":0},{"address":3234632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213108,"script_address":2030087},{"address":3234672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[213,186,175,96],"species":325},{"level":39,"moves":[213,219,36,96],"species":325}],"party_address":3213116,"script_address":2265894},{"address":3234712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":287},{"level":28,"species":287},{"level":30,"species":339}],"party_address":3213148,"script_address":2254717},{"address":3234752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":11,"moves":[33,39,0,0],"species":288}],"party_address":3213172,"script_address":0},{"address":3234792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":40,"species":119}],"party_address":3213188,"script_address":2265677},{"address":3234832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3213196,"script_address":2361019},{"address":3234872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213204,"script_address":0},{"address":3234912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213212,"script_address":0},{"address":3234952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213220,"script_address":0},{"address":3234992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213228,"script_address":0},{"address":3235032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":183}],"party_address":3213244,"script_address":2304387},{"address":3235072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3213252,"script_address":2304418},{"address":3235112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":339}],"party_address":3213260,"script_address":2304449},{"address":3235152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[20,122,154,185],"species":317},{"level":29,"moves":[86,103,137,242],"species":379}],"party_address":3213268,"script_address":2067377},{"address":3235192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":118}],"party_address":3213300,"script_address":2265708},{"address":3235232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":184}],"party_address":3213308,"script_address":2265739},{"address":3235272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[78,250,240,96],"species":373},{"level":37,"moves":[13,152,96,0],"species":326},{"level":39,"moves":[253,154,252,96],"species":296}],"party_address":3213316,"script_address":2265770},{"address":3235312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":330},{"level":39,"species":331}],"party_address":3213364,"script_address":2265801},{"address":3235352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[20,122,154,185],"species":317},{"level":35,"moves":[86,103,137,242],"species":379}],"party_address":3213380,"script_address":0},{"address":3235392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[20,122,154,185],"species":317},{"level":38,"moves":[86,103,137,242],"species":379}],"party_address":3213412,"script_address":0},{"address":3235432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[20,122,154,185],"species":317},{"level":41,"moves":[86,103,137,242],"species":379}],"party_address":3213444,"script_address":0},{"address":3235472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[20,122,154,185],"species":317},{"level":44,"moves":[86,103,137,242],"species":379}],"party_address":3213476,"script_address":0},{"address":3235512,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213508,"script_address":2029901},{"address":3235552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":324},{"level":33,"species":356}],"party_address":3213516,"script_address":2074012},{"address":3235592,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":184}],"party_address":3213532,"script_address":2360988},{"address":3235632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213540,"script_address":0},{"address":3235672,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213548,"script_address":0},{"address":3235712,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213556,"script_address":0},{"address":3235752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213564,"script_address":0},{"address":3235792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3213580,"script_address":2051965},{"address":3235832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":116}],"party_address":3213588,"script_address":2340108},{"address":3235872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":111}],"party_address":3213604,"script_address":2312578},{"address":3235912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":339}],"party_address":3213612,"script_address":2304480},{"address":3235952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":383}],"party_address":3213620,"script_address":0},{"address":3235992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":383},{"level":29,"species":111}],"party_address":3213628,"script_address":0},{"address":3236032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":383},{"level":32,"species":111}],"party_address":3213644,"script_address":0},{"address":3236072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":384},{"level":35,"species":112}],"party_address":3213660,"script_address":0},{"address":3236112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213676,"script_address":2033571},{"address":3236152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":72}],"party_address":3213684,"script_address":2033602},{"address":3236192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":72}],"party_address":3213692,"script_address":2034185},{"address":3236232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":309},{"level":24,"species":72}],"party_address":3213708,"script_address":2034479},{"address":3236272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213732,"script_address":2034510},{"address":3236312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":73}],"party_address":3213740,"script_address":2034776},{"address":3236352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213748,"script_address":2034807},{"address":3236392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3213756,"script_address":2035777},{"address":3236432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309}],"party_address":3213772,"script_address":2069178},{"address":3236472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3213788,"script_address":2069209},{"address":3236512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":73}],"party_address":3213796,"script_address":2069789},{"address":3236552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":116}],"party_address":3213804,"script_address":2069820},{"address":3236592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213812,"script_address":2070163},{"address":3236632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":31,"species":309},{"level":31,"species":330}],"party_address":3213820,"script_address":2070194},{"address":3236672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213844,"script_address":2073229},{"address":3236712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310}],"party_address":3213852,"script_address":2073359},{"address":3236752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213860,"script_address":2073390},{"address":3236792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":73},{"level":33,"species":313}],"party_address":3213876,"script_address":2073291},{"address":3236832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3213892,"script_address":2073608},{"address":3236872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":342}],"party_address":3213900,"script_address":2073857},{"address":3236912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":341}],"party_address":3213908,"script_address":2073576},{"address":3236952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213916,"script_address":2074089},{"address":3236992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213924,"script_address":0},{"address":3237032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":313}],"party_address":3213948,"script_address":2069381},{"address":3237072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":331}],"party_address":3213964,"script_address":0},{"address":3237112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":331}],"party_address":3213972,"script_address":0},{"address":3237152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120},{"level":36,"species":331}],"party_address":3213980,"script_address":0},{"address":3237192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":121},{"level":39,"species":331}],"party_address":3213996,"script_address":0},{"address":3237232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3214012,"script_address":2095275},{"address":3237272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":66},{"level":32,"species":67}],"party_address":3214020,"script_address":2074213},{"address":3237312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":336}],"party_address":3214036,"script_address":2073701},{"address":3237352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":66},{"level":28,"species":67}],"party_address":3214044,"script_address":2052921},{"address":3237392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214060,"script_address":2052952},{"address":3237432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":67}],"party_address":3214068,"script_address":0},{"address":3237472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":66},{"level":29,"species":67}],"party_address":3214076,"script_address":0},{"address":3237512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":66},{"level":31,"species":67},{"level":31,"species":67}],"party_address":3214092,"script_address":0},{"address":3237552,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":66},{"level":33,"species":67},{"level":33,"species":67},{"level":33,"species":68}],"party_address":3214116,"script_address":0},{"address":3237592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":335},{"level":26,"species":67}],"party_address":3214148,"script_address":2557758},{"address":3237632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214164,"script_address":2046662},{"address":3237672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":336}],"party_address":3214172,"script_address":2315359},{"address":3237712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[98,86,209,43],"species":337},{"level":17,"moves":[12,95,103,0],"species":100}],"party_address":3214180,"script_address":2167608},{"address":3237752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":286},{"level":31,"species":41}],"party_address":3214212,"script_address":2323445},{"address":3237792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3214228,"script_address":2324458},{"address":3237832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":100},{"level":17,"species":81}],"party_address":3214236,"script_address":2167639},{"address":3237872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":337},{"level":30,"species":371}],"party_address":3214252,"script_address":2068709},{"address":3237912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81},{"level":15,"species":370}],"party_address":3214268,"script_address":2058956},{"address":3237952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":81},{"level":25,"species":370},{"level":25,"species":81}],"party_address":3214284,"script_address":0},{"address":3237992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81},{"level":28,"species":371},{"level":28,"species":81}],"party_address":3214308,"script_address":0},{"address":3238032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":82},{"level":31,"species":371},{"level":31,"species":82}],"party_address":3214332,"script_address":0},{"address":3238072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82},{"level":34,"species":372},{"level":34,"species":82}],"party_address":3214356,"script_address":0},{"address":3238112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214380,"script_address":2103394},{"address":3238152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":218},{"level":22,"species":218}],"party_address":3214388,"script_address":2103601},{"address":3238192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214404,"script_address":2103446},{"address":3238232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214412,"script_address":2103570},{"address":3238272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214420,"script_address":2103477},{"address":3238312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309}],"party_address":3214428,"script_address":2052075},{"address":3238352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":218},{"level":26,"species":309}],"party_address":3214444,"script_address":0},{"address":3238392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310}],"party_address":3214460,"script_address":0},{"address":3238432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":218},{"level":32,"species":310}],"party_address":3214476,"script_address":0},{"address":3238472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":219},{"level":35,"species":310}],"party_address":3214492,"script_address":0},{"address":3238512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,28,40,163],"species":27}],"party_address":3214508,"script_address":2046366},{"address":3238552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":21,"moves":[229,189,60,61],"species":318},{"level":21,"moves":[40,28,10,91],"species":27},{"level":21,"moves":[229,189,60,61],"species":318}],"party_address":3214524,"script_address":2046428},{"address":3238592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":299}],"party_address":3214572,"script_address":2049829},{"address":3238632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27},{"level":18,"species":299}],"party_address":3214580,"script_address":2051903},{"address":3238672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":317}],"party_address":3214596,"script_address":2557005},{"address":3238712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":288},{"level":20,"species":304}],"party_address":3214604,"script_address":2310199},{"address":3238752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3214620,"script_address":2310337},{"address":3238792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27}],"party_address":3214628,"script_address":2046600},{"address":3238832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":288},{"level":26,"species":304}],"party_address":3214636,"script_address":0},{"address":3238872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":289},{"level":29,"species":305}],"party_address":3214652,"script_address":0},{"address":3238912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":305},{"level":31,"species":289}],"party_address":3214668,"script_address":0},{"address":3238952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":28},{"level":34,"species":289}],"party_address":3214692,"script_address":0},{"address":3238992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":311}],"party_address":3214716,"script_address":2061044},{"address":3239032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":290},{"level":24,"species":291},{"level":24,"species":292}],"party_address":3214724,"script_address":2061075},{"address":3239072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":290},{"level":27,"species":293},{"level":27,"species":294}],"party_address":3214748,"script_address":2061106},{"address":3239112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":311},{"level":27,"species":311},{"level":27,"species":311}],"party_address":3214772,"script_address":2065541},{"address":3239152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":294},{"level":16,"species":292}],"party_address":3214796,"script_address":2057595},{"address":3239192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":311},{"level":31,"species":311}],"party_address":3214812,"script_address":0},{"address":3239232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":311},{"level":34,"species":311},{"level":34,"species":312}],"party_address":3214836,"script_address":0},{"address":3239272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":311},{"level":36,"species":290},{"level":36,"species":311},{"level":36,"species":312}],"party_address":3214860,"script_address":0},{"address":3239312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":311},{"level":38,"species":294},{"level":38,"species":311},{"level":38,"species":312},{"level":38,"species":292}],"party_address":3214892,"script_address":0},{"address":3239352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[237,0,0,0],"species":63}],"party_address":3214932,"script_address":2038374},{"address":3239392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3214948,"script_address":2244488},{"address":3239432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":392}],"party_address":3214956,"script_address":2244519},{"address":3239472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3214964,"script_address":2244550},{"address":3239512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":392},{"level":26,"species":393}],"party_address":3214972,"script_address":2314189},{"address":3239552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3214996,"script_address":2564698},{"address":3239592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":349}],"party_address":3215012,"script_address":2068179},{"address":3239632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":64},{"level":33,"species":349}],"party_address":3215020,"script_address":0},{"address":3239672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":64},{"level":38,"species":349}],"party_address":3215036,"script_address":0},{"address":3239712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3215052,"script_address":0},{"address":3239752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":349},{"level":45,"species":65}],"party_address":3215068,"script_address":0},{"address":3239792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[237,0,0,0],"species":63}],"party_address":3215084,"script_address":2038405},{"address":3239832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3215100,"script_address":2244581},{"address":3239872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":178}],"party_address":3215108,"script_address":2244612},{"address":3239912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3215116,"script_address":2244643},{"address":3239952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":202},{"level":26,"species":177},{"level":26,"species":64}],"party_address":3215124,"script_address":2314220},{"address":3239992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":393},{"level":41,"species":178}],"party_address":3215148,"script_address":2564760},{"address":3240032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":64},{"level":30,"species":348}],"party_address":3215164,"script_address":2068289},{"address":3240072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":64},{"level":34,"species":348}],"party_address":3215180,"script_address":0},{"address":3240112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":64},{"level":37,"species":348}],"party_address":3215196,"script_address":0},{"address":3240152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":64},{"level":40,"species":348}],"party_address":3215212,"script_address":0},{"address":3240192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":348},{"level":43,"species":65}],"party_address":3215228,"script_address":0},{"address":3240232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338}],"party_address":3215244,"script_address":2067174},{"address":3240272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":338},{"level":44,"species":338}],"party_address":3215252,"script_address":2360864},{"address":3240312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":380}],"party_address":3215268,"script_address":2360895},{"address":3240352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":338}],"party_address":3215276,"script_address":0},{"address":3240392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[29,28,60,154],"species":289},{"level":36,"moves":[98,209,60,46],"species":338}],"party_address":3215284,"script_address":0},{"address":3240432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[29,28,60,154],"species":289},{"level":39,"moves":[98,209,60,0],"species":338}],"party_address":3215316,"script_address":0},{"address":3240472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[29,28,60,154],"species":289},{"level":41,"moves":[154,50,93,244],"species":55},{"level":41,"moves":[98,209,60,46],"species":338}],"party_address":3215348,"script_address":0},{"address":3240512,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,38,28,242],"species":287},{"level":48,"moves":[3,104,207,70],"species":300},{"level":46,"moves":[73,185,46,178],"species":345},{"level":48,"moves":[57,14,70,7],"species":327},{"level":49,"moves":[76,157,14,163],"species":376}],"party_address":3215396,"script_address":2274753},{"address":3240552,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[69,109,174,182],"species":362},{"level":49,"moves":[247,32,5,185],"species":378},{"level":50,"moves":[247,104,101,185],"species":322},{"level":49,"moves":[247,94,85,7],"species":378},{"level":51,"moves":[247,58,157,89],"species":362}],"party_address":3215476,"script_address":2275380},{"address":3240592,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[227,34,2,45],"species":342},{"level":50,"moves":[113,242,196,58],"species":347},{"level":52,"moves":[213,38,2,59],"species":342},{"level":52,"moves":[247,153,2,58],"species":347},{"level":53,"moves":[57,34,58,73],"species":343}],"party_address":3215556,"script_address":2276062},{"address":3240632,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[61,81,182,38],"species":396},{"level":54,"moves":[38,225,93,76],"species":359},{"level":53,"moves":[108,93,57,34],"species":230},{"level":53,"moves":[53,242,225,89],"species":334},{"level":55,"moves":[53,81,157,242],"species":397}],"party_address":3215636,"script_address":2276724},{"address":3240672,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":12,"moves":[33,111,88,61],"species":74},{"level":12,"moves":[33,111,88,61],"species":74},{"level":15,"moves":[79,106,33,61],"species":320}],"party_address":3215716,"script_address":2187976},{"address":3240712,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[2,67,69,83],"species":66},{"level":16,"moves":[8,113,115,83],"species":356},{"level":19,"moves":[36,233,179,83],"species":335}],"party_address":3215764,"script_address":2095066},{"address":3240752,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":20,"moves":[205,209,120,95],"species":100},{"level":20,"moves":[95,43,98,80],"species":337},{"level":22,"moves":[48,95,86,49],"species":82},{"level":24,"moves":[98,86,95,80],"species":338}],"party_address":3215812,"script_address":2167181},{"address":3240792,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[59,36,222,241],"species":339},{"level":24,"moves":[59,123,113,241],"species":218},{"level":26,"moves":[59,33,241,213],"species":340},{"level":29,"moves":[59,241,34,213],"species":321}],"party_address":3215876,"script_address":2103186},{"address":3240832,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[42,60,7,227],"species":308},{"level":27,"moves":[163,7,227,185],"species":365},{"level":29,"moves":[163,187,7,29],"species":289},{"level":31,"moves":[68,25,7,185],"species":366}],"party_address":3215940,"script_address":2129756},{"address":3240872,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[195,119,219,76],"species":358},{"level":29,"moves":[241,76,76,235],"species":369},{"level":30,"moves":[55,48,182,76],"species":310},{"level":31,"moves":[28,31,211,76],"species":227},{"level":33,"moves":[89,225,93,76],"species":359}],"party_address":3216004,"script_address":2202062},{"address":3240912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[89,246,94,113],"species":319},{"level":41,"moves":[94,241,109,91],"species":178},{"level":42,"moves":[113,94,95,91],"species":348},{"level":42,"moves":[241,76,94,53],"species":349}],"party_address":3216084,"script_address":0},{"address":3240952,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[96,213,186,175],"species":325},{"level":41,"moves":[240,96,133,89],"species":324},{"level":43,"moves":[227,34,62,96],"species":342},{"level":43,"moves":[96,152,13,43],"species":327},{"level":46,"moves":[96,104,58,156],"species":230}],"party_address":3216148,"script_address":2262245},{"address":3240992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":392}],"party_address":3216228,"script_address":2054242},{"address":3241032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3216236,"script_address":2554598},{"address":3241072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":339},{"level":15,"species":43},{"level":15,"species":309}],"party_address":3216244,"script_address":2554629},{"address":3241112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":356}],"party_address":3216268,"script_address":0},{"address":3241152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":393},{"level":29,"species":356}],"party_address":3216284,"script_address":0},{"address":3241192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":393},{"level":32,"species":357}],"party_address":3216300,"script_address":0},{"address":3241232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":393},{"level":34,"species":378},{"level":34,"species":357}],"party_address":3216316,"script_address":0},{"address":3241272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":306}],"party_address":3216340,"script_address":2054490},{"address":3241312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":306},{"level":16,"species":292}],"party_address":3216348,"script_address":2554660},{"address":3241352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":370}],"party_address":3216364,"script_address":0},{"address":3241392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":306},{"level":29,"species":371}],"party_address":3216380,"script_address":0},{"address":3241432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":307},{"level":32,"species":371}],"party_address":3216396,"script_address":0},{"address":3241472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":307},{"level":35,"species":372}],"party_address":3216412,"script_address":0},{"address":3241512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[95,60,146,42],"species":308},{"level":32,"moves":[8,25,47,185],"species":366}],"party_address":3216428,"script_address":0},{"address":3241552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[45,39,29,60],"species":288},{"level":17,"moves":[33,116,36,0],"species":335}],"party_address":3216460,"script_address":0},{"address":3241592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[45,39,29,60],"species":288},{"level":30,"moves":[33,116,36,0],"species":335}],"party_address":3216492,"script_address":0},{"address":3241632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[45,39,29,60],"species":288},{"level":33,"moves":[33,116,36,0],"species":335}],"party_address":3216524,"script_address":0},{"address":3241672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[45,39,29,60],"species":289},{"level":36,"moves":[33,116,36,0],"species":335}],"party_address":3216556,"script_address":0},{"address":3241712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[45,39,29,60],"species":289},{"level":38,"moves":[33,116,36,0],"species":336}],"party_address":3216588,"script_address":0},{"address":3241752,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":16,"species":304},{"level":16,"species":288}],"party_address":3216620,"script_address":2045785},{"address":3241792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":15,"species":315}],"party_address":3216636,"script_address":2026353},{"address":3241832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[18,204,185,215],"species":315},{"level":36,"moves":[18,204,185,215],"species":315},{"level":40,"moves":[18,204,185,215],"species":315},{"level":12,"moves":[18,204,185,215],"species":315},{"level":30,"moves":[18,204,185,215],"species":315},{"level":42,"moves":[18,204,185,215],"species":316}],"party_address":3216644,"script_address":2360833},{"address":3241872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":315}],"party_address":3216740,"script_address":0},{"address":3241912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":315}],"party_address":3216748,"script_address":0},{"address":3241952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316}],"party_address":3216756,"script_address":0},{"address":3241992,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":316}],"party_address":3216764,"script_address":0},{"address":3242032,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":17,"species":363}],"party_address":3216772,"script_address":2045890},{"address":3242072,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":25}],"party_address":3216780,"script_address":2067143},{"address":3242112,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":350},{"level":37,"species":183},{"level":39,"species":184}],"party_address":3216788,"script_address":2265832},{"address":3242152,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":353},{"level":14,"species":354}],"party_address":3216812,"script_address":2038890},{"address":3242192,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":26,"species":353},{"level":26,"species":354}],"party_address":3216828,"script_address":0},{"address":3242232,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":353},{"level":29,"species":354}],"party_address":3216844,"script_address":0},{"address":3242272,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":353},{"level":32,"species":354}],"party_address":3216860,"script_address":0},{"address":3242312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":353},{"level":35,"species":354}],"party_address":3216876,"script_address":0},{"address":3242352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":336}],"party_address":3216892,"script_address":2052811},{"address":3242392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[36,26,28,91],"species":336}],"party_address":3216900,"script_address":0},{"address":3242432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[36,26,28,91],"species":336}],"party_address":3216916,"script_address":0},{"address":3242472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[36,187,28,91],"species":336}],"party_address":3216932,"script_address":0},{"address":3242512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[36,187,28,91],"species":336}],"party_address":3216948,"script_address":0},{"address":3242552,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[136,96,93,197],"species":356}],"party_address":3216964,"script_address":2046100},{"address":3242592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":356},{"level":21,"species":335}],"party_address":3216980,"script_address":2304277},{"address":3242632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":356},{"level":30,"species":335}],"party_address":3216996,"script_address":0},{"address":3242672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":357},{"level":33,"species":336}],"party_address":3217012,"script_address":0},{"address":3242712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":357},{"level":36,"species":336}],"party_address":3217028,"script_address":0},{"address":3242752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":357},{"level":39,"species":336}],"party_address":3217044,"script_address":0},{"address":3242792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":286}],"party_address":3217060,"script_address":2024678},{"address":3242832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":288},{"level":7,"species":298}],"party_address":3217068,"script_address":2029684},{"address":3242872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[33,0,0,0],"species":74}],"party_address":3217084,"script_address":2188154},{"address":3242912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3217100,"script_address":2188185},{"address":3242952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":66}],"party_address":3217116,"script_address":2054180},{"address":3242992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[29,28,45,85],"species":288},{"level":17,"moves":[133,124,25,1],"species":367}],"party_address":3217124,"script_address":2167670},{"address":3243032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[213,58,85,53],"species":366},{"level":43,"moves":[29,182,5,92],"species":362}],"party_address":3217156,"script_address":2332778},{"address":3243072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,94,85,91],"species":394},{"level":43,"moves":[89,247,76,24],"species":366}],"party_address":3217188,"script_address":2332809},{"address":3243112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":332}],"party_address":3217220,"script_address":2050594},{"address":3243152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3217228,"script_address":2050625},{"address":3243192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":287}],"party_address":3217236,"script_address":0},{"address":3243232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":305},{"level":30,"species":287}],"party_address":3217244,"script_address":0},{"address":3243272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":305},{"level":29,"species":289},{"level":33,"species":287}],"party_address":3217260,"script_address":0},{"address":3243312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":32,"species":289},{"level":36,"species":287}],"party_address":3217284,"script_address":0},{"address":3243352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":16,"species":288}],"party_address":3217308,"script_address":2553792},{"address":3243392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":3,"species":304}],"party_address":3217324,"script_address":2024926},{"address":3243432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":382},{"level":13,"species":337}],"party_address":3217340,"script_address":2039000},{"address":3243472,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[240,67,38,59],"species":314},{"level":55,"moves":[92,56,188,58],"species":73},{"level":56,"moves":[202,57,73,104],"species":297},{"level":56,"moves":[89,57,133,63],"species":324},{"level":56,"moves":[93,89,63,57],"species":130},{"level":58,"moves":[105,57,58,92],"species":329}],"party_address":3217356,"script_address":2277575},{"address":3243512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":10,"species":72},{"level":15,"species":129}],"party_address":3217452,"script_address":2026322},{"address":3243552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":6,"species":129},{"level":7,"species":129}],"party_address":3217476,"script_address":2029653},{"address":3243592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":129},{"level":17,"species":118},{"level":18,"species":323}],"party_address":3217500,"script_address":2052185},{"address":3243632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":10,"species":129},{"level":7,"species":72},{"level":10,"species":129}],"party_address":3217524,"script_address":2034247},{"address":3243672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72}],"party_address":3217548,"script_address":2034357},{"address":3243712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72},{"level":14,"species":313},{"level":11,"species":72},{"level":14,"species":313}],"party_address":3217556,"script_address":2038546},{"address":3243752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3217588,"script_address":2052216},{"address":3243792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3217596,"script_address":2058894},{"address":3243832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":72}],"party_address":3217612,"script_address":2058925},{"address":3243872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":73}],"party_address":3217620,"script_address":2036183},{"address":3243912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":27,"species":130},{"level":27,"species":130}],"party_address":3217636,"script_address":0},{"address":3243952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":130},{"level":26,"species":330},{"level":26,"species":72},{"level":29,"species":130}],"party_address":3217660,"script_address":0},{"address":3243992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":130},{"level":30,"species":330},{"level":30,"species":73},{"level":31,"species":130}],"party_address":3217692,"script_address":0},{"address":3244032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":130},{"level":33,"species":331},{"level":33,"species":130},{"level":35,"species":73}],"party_address":3217724,"script_address":0},{"address":3244072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":129},{"level":21,"species":130},{"level":23,"species":130},{"level":26,"species":130},{"level":30,"species":130},{"level":35,"species":130}],"party_address":3217756,"script_address":2073670},{"address":3244112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":100},{"level":6,"species":100},{"level":14,"species":81}],"party_address":3217804,"script_address":2038577},{"address":3244152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81}],"party_address":3217828,"script_address":2038608},{"address":3244192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217844,"script_address":2038639},{"address":3244232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":81}],"party_address":3217852,"script_address":0},{"address":3244272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":81}],"party_address":3217860,"script_address":0},{"address":3244312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82}],"party_address":3217868,"script_address":0},{"address":3244352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":82}],"party_address":3217876,"script_address":0},{"address":3244392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217884,"script_address":2038780},{"address":3244432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81},{"level":6,"species":100}],"party_address":3217892,"script_address":2038749},{"address":3244472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81}],"party_address":3217916,"script_address":0},{"address":3244512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":81}],"party_address":3217924,"script_address":0},{"address":3244552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82}],"party_address":3217932,"script_address":0},{"address":3244592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":82}],"party_address":3217940,"script_address":0},{"address":3244632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217948,"script_address":2057375},{"address":3244672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217956,"script_address":0},{"address":3244712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3217964,"script_address":0},{"address":3244752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3217972,"script_address":0},{"address":3244792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3217980,"script_address":0},{"address":3244832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217988,"script_address":2057485},{"address":3244872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217996,"script_address":0},{"address":3244912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3218004,"script_address":0},{"address":3244952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3218012,"script_address":0},{"address":3244992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3218020,"script_address":0},{"address":3245032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218028,"script_address":2070582},{"address":3245072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":288},{"level":25,"species":337}],"party_address":3218044,"script_address":2340077},{"address":3245112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218060,"script_address":2071332},{"address":3245152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218068,"script_address":2070380},{"address":3245192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218084,"script_address":2072978},{"address":3245232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218100,"script_address":0},{"address":3245272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218108,"script_address":0},{"address":3245312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218116,"script_address":0},{"address":3245352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218124,"script_address":0},{"address":3245392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218132,"script_address":2070318},{"address":3245432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218140,"script_address":2070613},{"address":3245472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218156,"script_address":2073545},{"address":3245512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218164,"script_address":2071442},{"address":3245552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":309},{"level":33,"species":120}],"party_address":3218172,"script_address":2073009},{"address":3245592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218188,"script_address":0},{"address":3245632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218196,"script_address":0},{"address":3245672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218204,"script_address":0},{"address":3245712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218212,"script_address":0},{"address":3245752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":359},{"level":37,"species":359}],"party_address":3218220,"script_address":2292701},{"address":3245792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":359}],"party_address":3218236,"script_address":0},{"address":3245832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":359},{"level":44,"species":359}],"party_address":3218252,"script_address":0},{"address":3245872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":395},{"level":46,"species":359},{"level":46,"species":359}],"party_address":3218268,"script_address":0},{"address":3245912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":49,"species":359},{"level":49,"species":359},{"level":49,"species":396}],"party_address":3218292,"script_address":0},{"address":3245952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[225,29,116,52],"species":395}],"party_address":3218316,"script_address":2074182},{"address":3245992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309}],"party_address":3218332,"script_address":2059066},{"address":3246032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":369}],"party_address":3218340,"script_address":2061450},{"address":3246072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":305}],"party_address":3218356,"script_address":2061481},{"address":3246112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":84},{"level":27,"species":227},{"level":27,"species":369}],"party_address":3218364,"script_address":2202267},{"address":3246152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":227}],"party_address":3218388,"script_address":2202391},{"address":3246192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":369},{"level":33,"species":178}],"party_address":3218396,"script_address":2070085},{"address":3246232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":84},{"level":29,"species":310}],"party_address":3218412,"script_address":2202298},{"address":3246272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":309},{"level":28,"species":177}],"party_address":3218428,"script_address":2065338},{"address":3246312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":358}],"party_address":3218444,"script_address":2065369},{"address":3246352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":305},{"level":36,"species":310},{"level":36,"species":178}],"party_address":3218452,"script_address":2563257},{"address":3246392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":305}],"party_address":3218476,"script_address":2059097},{"address":3246432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":177},{"level":32,"species":358}],"party_address":3218492,"script_address":0},{"address":3246472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":177},{"level":35,"species":359}],"party_address":3218508,"script_address":0},{"address":3246512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":177},{"level":38,"species":359}],"party_address":3218524,"script_address":0},{"address":3246552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":178}],"party_address":3218540,"script_address":0},{"address":3246592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":177},{"level":33,"species":305}],"party_address":3218556,"script_address":2074151},{"address":3246632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":369}],"party_address":3218572,"script_address":2073981},{"address":3246672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302}],"party_address":3218580,"script_address":2061512},{"address":3246712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302},{"level":25,"species":109}],"party_address":3218588,"script_address":2061543},{"address":3246752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,89,0,0],"species":319},{"level":43,"moves":[85,89,0,0],"species":171}],"party_address":3218604,"script_address":2335578},{"address":3246792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3218636,"script_address":2341860},{"address":3246832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,124,120],"species":109}],"party_address":3218644,"script_address":2050766},{"address":3246872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":109},{"level":18,"species":302}],"party_address":3218692,"script_address":2050876},{"address":3246912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[139,33,124,120],"species":109},{"level":24,"moves":[139,33,124,0],"species":109},{"level":24,"moves":[139,33,124,120],"species":109},{"level":26,"moves":[33,124,0,0],"species":109}],"party_address":3218708,"script_address":0},{"address":3246952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,0],"species":109},{"level":29,"moves":[33,124,0,0],"species":109}],"party_address":3218772,"script_address":0},{"address":3246992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":32,"moves":[33,124,0,0],"species":109}],"party_address":3218836,"script_address":0},{"address":3247032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[139,33,124,0],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":35,"moves":[33,124,0,0],"species":110}],"party_address":3218900,"script_address":0},{"address":3247072,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218964,"script_address":2095313},{"address":3247112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218972,"script_address":2095351},{"address":3247152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":335}],"party_address":3218980,"script_address":2053062},{"address":3247192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":356}],"party_address":3218996,"script_address":2557727},{"address":3247232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3219004,"script_address":2557789},{"address":3247272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3219012,"script_address":0},{"address":3247312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":356},{"level":29,"species":335}],"party_address":3219028,"script_address":0},{"address":3247352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":357},{"level":32,"species":336}],"party_address":3219044,"script_address":0},{"address":3247392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":357},{"level":35,"species":336}],"party_address":3219060,"script_address":0},{"address":3247432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":19,"moves":[52,33,222,241],"species":339}],"party_address":3219076,"script_address":2050656},{"address":3247472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":363},{"level":28,"species":313}],"party_address":3219092,"script_address":2065713},{"address":3247512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[240,55,87,96],"species":385}],"party_address":3219108,"script_address":2065744},{"address":3247552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[52,33,222,241],"species":339}],"party_address":3219124,"script_address":0},{"address":3247592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[52,36,222,241],"species":339}],"party_address":3219140,"script_address":0},{"address":3247632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[73,72,64,241],"species":363},{"level":34,"moves":[53,36,222,241],"species":339}],"party_address":3219156,"script_address":0},{"address":3247672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[73,202,76,241],"species":363},{"level":37,"moves":[53,36,89,241],"species":340}],"party_address":3219188,"script_address":0},{"address":3247712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":313}],"party_address":3219220,"script_address":2033633},{"address":3247752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3219236,"script_address":2033664},{"address":3247792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":313}],"party_address":3219244,"script_address":2034216},{"address":3247832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":118}],"party_address":3219252,"script_address":2034620},{"address":3247872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219268,"script_address":2034651},{"address":3247912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":116},{"level":25,"species":183}],"party_address":3219276,"script_address":2034838},{"address":3247952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219292,"script_address":2034869},{"address":3247992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":118},{"level":24,"species":309},{"level":24,"species":118}],"party_address":3219300,"script_address":2035808},{"address":3248032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3219324,"script_address":2069240},{"address":3248072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":183}],"party_address":3219332,"script_address":2069350},{"address":3248112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219340,"script_address":2069851},{"address":3248152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219348,"script_address":2069882},{"address":3248192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":183},{"level":33,"species":341}],"party_address":3219356,"script_address":2070225},{"address":3248232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":118}],"party_address":3219372,"script_address":2070256},{"address":3248272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":118},{"level":33,"species":341}],"party_address":3219380,"script_address":2073260},{"address":3248312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219396,"script_address":2073421},{"address":3248352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219404,"script_address":2073452},{"address":3248392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":184}],"party_address":3219412,"script_address":2073639},{"address":3248432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219420,"script_address":2070349},{"address":3248472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219436,"script_address":2073888},{"address":3248512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":116},{"level":33,"species":117}],"party_address":3219444,"script_address":2073919},{"address":3248552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":171},{"level":34,"species":310}],"party_address":3219460,"script_address":0},{"address":3248592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219476,"script_address":2074120},{"address":3248632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":119}],"party_address":3219492,"script_address":2071676},{"address":3248672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":313}],"party_address":3219500,"script_address":0},{"address":3248712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":313}],"party_address":3219508,"script_address":0},{"address":3248752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":120},{"level":43,"species":313}],"party_address":3219516,"script_address":0},{"address":3248792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":313},{"level":45,"species":121}],"party_address":3219532,"script_address":0},{"address":3248832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[91,28,40,163],"species":27},{"level":22,"moves":[229,189,60,61],"species":318}],"party_address":3219556,"script_address":2046397},{"address":3248872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[28,40,163,91],"species":27},{"level":22,"moves":[205,61,39,111],"species":183}],"party_address":3219588,"script_address":2046459},{"address":3248912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":304},{"level":17,"species":296}],"party_address":3219620,"script_address":2049860},{"address":3248952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":183},{"level":18,"species":296}],"party_address":3219636,"script_address":2051934},{"address":3248992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":315},{"level":23,"species":358}],"party_address":3219652,"script_address":2557036},{"address":3249032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":306},{"level":19,"species":43},{"level":19,"species":358}],"party_address":3219668,"script_address":2310092},{"address":3249072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[194,219,68,243],"species":202}],"party_address":3219692,"script_address":2315855},{"address":3249112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":306},{"level":17,"species":183}],"party_address":3219708,"script_address":2046631},{"address":3249152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":306},{"level":25,"species":44},{"level":25,"species":358}],"party_address":3219724,"script_address":0},{"address":3249192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":307},{"level":28,"species":44},{"level":28,"species":358}],"party_address":3219748,"script_address":0},{"address":3249232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307},{"level":31,"species":44},{"level":31,"species":358}],"party_address":3219772,"script_address":0},{"address":3249272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":307},{"level":40,"species":45},{"level":40,"species":359}],"party_address":3219796,"script_address":0},{"address":3249312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":353},{"level":15,"species":354}],"party_address":3219820,"script_address":0},{"address":3249352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":353},{"level":27,"species":354}],"party_address":3219836,"script_address":0},{"address":3249392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":298},{"level":6,"species":295}],"party_address":3219852,"script_address":0},{"address":3249432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":292},{"level":26,"species":294}],"party_address":3219868,"script_address":0},{"address":3249472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":353},{"level":9,"species":354}],"party_address":3219884,"script_address":0},{"address":3249512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[101,50,0,0],"species":361},{"level":10,"moves":[71,73,0,0],"species":306}],"party_address":3219900,"script_address":0},{"address":3249552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":353},{"level":30,"species":354}],"party_address":3219932,"script_address":0},{"address":3249592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[209,12,57,14],"species":353},{"level":33,"moves":[209,12,204,14],"species":354}],"party_address":3219948,"script_address":0},{"address":3249632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,12,57,14],"species":353},{"level":36,"moves":[87,12,204,14],"species":354}],"party_address":3219980,"script_address":0},{"address":3249672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":309},{"level":12,"species":66}],"party_address":3220012,"script_address":2035839},{"address":3249712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309}],"party_address":3220028,"script_address":2035870},{"address":3249752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":67}],"party_address":3220036,"script_address":2069913},{"address":3249792,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":66},{"level":11,"species":72}],"party_address":3220052,"script_address":2543939},{"address":3249832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":73},{"level":44,"species":67}],"party_address":3220076,"script_address":2360255},{"address":3249872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":66},{"level":43,"species":310},{"level":43,"species":67}],"party_address":3220092,"script_address":2360286},{"address":3249912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":341},{"level":25,"species":67}],"party_address":3220116,"script_address":2340984},{"address":3249952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":309},{"level":36,"species":72},{"level":36,"species":67}],"party_address":3220132,"script_address":0},{"address":3249992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":310},{"level":39,"species":72},{"level":39,"species":67}],"party_address":3220156,"script_address":0},{"address":3250032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":310},{"level":42,"species":72},{"level":42,"species":67}],"party_address":3220180,"script_address":0},{"address":3250072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":310},{"level":45,"species":67},{"level":45,"species":73}],"party_address":3220204,"script_address":0},{"address":3250112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3220228,"script_address":2103632},{"address":3250152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[175,96,216,213],"species":328},{"level":39,"moves":[175,96,216,213],"species":328}],"party_address":3220236,"script_address":2265863},{"address":3250192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":376}],"party_address":3220268,"script_address":2068647},{"address":3250232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[92,87,120,188],"species":109}],"party_address":3220276,"script_address":2068616},{"address":3250272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[241,55,53,76],"species":385}],"party_address":3220292,"script_address":2068585},{"address":3250312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":338},{"level":33,"species":68}],"party_address":3220308,"script_address":2070116},{"address":3250352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":341}],"party_address":3220324,"script_address":2074337},{"address":3250392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[44,46,86,85],"species":338}],"party_address":3220340,"script_address":2074306},{"address":3250432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":356},{"level":33,"species":336}],"party_address":3220356,"script_address":2074275},{"address":3250472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3220372,"script_address":2074244},{"address":3250512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":170},{"level":33,"species":336}],"party_address":3220380,"script_address":2074043},{"address":3250552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":296},{"level":14,"species":299}],"party_address":3220396,"script_address":2038436},{"address":3250592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":380},{"level":18,"species":379}],"party_address":3220412,"script_address":2053172},{"address":3250632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":340},{"level":38,"species":287},{"level":40,"species":42}],"party_address":3220428,"script_address":0},{"address":3250672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":299}],"party_address":3220452,"script_address":0},{"address":3250712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":299}],"party_address":3220468,"script_address":0},{"address":3250752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":299}],"party_address":3220484,"script_address":0},{"address":3250792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":297},{"level":35,"species":300}],"party_address":3220500,"script_address":0},{"address":3250832,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[76,219,225,93],"species":359},{"level":43,"moves":[47,18,204,185],"species":316},{"level":44,"moves":[89,73,202,92],"species":363},{"level":41,"moves":[48,85,161,103],"species":82},{"level":45,"moves":[104,91,94,248],"species":394}],"party_address":3220516,"script_address":2332529},{"address":3250872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220596,"script_address":2025759},{"address":3250912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309},{"level":20,"species":278}],"party_address":3220604,"script_address":2039798},{"address":3250952,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310},{"level":31,"species":278}],"party_address":3220628,"script_address":2060578},{"address":3250992,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220652,"script_address":2025703},{"address":3251032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220660,"script_address":2039742},{"address":3251072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220684,"script_address":2060522},{"address":3251112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220708,"script_address":2025731},{"address":3251152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220716,"script_address":2039770},{"address":3251192,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220740,"script_address":2060550},{"address":3251232,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220764,"script_address":2025675},{"address":3251272,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":218},{"level":20,"species":278}],"party_address":3220772,"script_address":2039622},{"address":3251312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":296},{"level":31,"species":278}],"party_address":3220796,"script_address":2060420},{"address":3251352,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220820,"script_address":2025619},{"address":3251392,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220828,"script_address":2039566},{"address":3251432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220852,"script_address":2060364},{"address":3251472,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220876,"script_address":2025647},{"address":3251512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220884,"script_address":2039594},{"address":3251552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220908,"script_address":2060392},{"address":3251592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":370},{"level":11,"species":288},{"level":11,"species":382},{"level":11,"species":286},{"level":11,"species":304},{"level":11,"species":335}],"party_address":3220932,"script_address":2057155},{"address":3251632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":127}],"party_address":3220980,"script_address":2068678},{"address":3251672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[153,115,113,94],"species":348},{"level":43,"moves":[153,115,113,247],"species":349}],"party_address":3220988,"script_address":2334468},{"address":3251712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":371},{"level":22,"species":289},{"level":22,"species":382},{"level":22,"species":287},{"level":22,"species":305},{"level":22,"species":335}],"party_address":3221020,"script_address":0},{"address":3251752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":371},{"level":25,"species":289},{"level":25,"species":382},{"level":25,"species":287},{"level":25,"species":305},{"level":25,"species":336}],"party_address":3221068,"script_address":0},{"address":3251792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":371},{"level":28,"species":289},{"level":28,"species":382},{"level":28,"species":287},{"level":28,"species":305},{"level":28,"species":336}],"party_address":3221116,"script_address":0},{"address":3251832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":371},{"level":31,"species":289},{"level":31,"species":383},{"level":31,"species":287},{"level":31,"species":305},{"level":31,"species":336}],"party_address":3221164,"script_address":0},{"address":3251872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":306},{"level":11,"species":183},{"level":11,"species":363},{"level":11,"species":315},{"level":11,"species":118}],"party_address":3221212,"script_address":2057265},{"address":3251912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":322},{"level":43,"species":376}],"party_address":3221260,"script_address":2334499},{"address":3251952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":28}],"party_address":3221276,"script_address":2341891},{"address":3251992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":309},{"level":22,"species":306},{"level":22,"species":183},{"level":22,"species":363},{"level":22,"species":315},{"level":22,"species":118}],"party_address":3221284,"script_address":0},{"address":3252032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":310},{"level":25,"species":307},{"level":25,"species":183},{"level":25,"species":363},{"level":25,"species":316},{"level":25,"species":118}],"party_address":3221332,"script_address":0},{"address":3252072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":310},{"level":28,"species":307},{"level":28,"species":183},{"level":28,"species":363},{"level":28,"species":316},{"level":28,"species":118}],"party_address":3221380,"script_address":0},{"address":3252112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":310},{"level":31,"species":307},{"level":31,"species":184},{"level":31,"species":363},{"level":31,"species":316},{"level":31,"species":119}],"party_address":3221428,"script_address":0},{"address":3252152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3221476,"script_address":2061230},{"address":3252192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":298},{"level":28,"species":299},{"level":28,"species":296}],"party_address":3221484,"script_address":2065479},{"address":3252232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":345}],"party_address":3221508,"script_address":2563288},{"address":3252272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307}],"party_address":3221516,"script_address":0},{"address":3252312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307}],"party_address":3221524,"script_address":0},{"address":3252352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":307}],"party_address":3221532,"script_address":0},{"address":3252392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":317},{"level":39,"species":307}],"party_address":3221540,"script_address":0},{"address":3252432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":44},{"level":26,"species":363}],"party_address":3221556,"script_address":2061340},{"address":3252472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":295},{"level":28,"species":296},{"level":28,"species":299}],"party_address":3221572,"script_address":2065510},{"address":3252512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":358},{"level":38,"species":363}],"party_address":3221596,"script_address":2563226},{"address":3252552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":44},{"level":30,"species":363}],"party_address":3221612,"script_address":0},{"address":3252592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":44},{"level":33,"species":363}],"party_address":3221628,"script_address":0},{"address":3252632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":44},{"level":36,"species":363}],"party_address":3221644,"script_address":0},{"address":3252672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":182},{"level":39,"species":363}],"party_address":3221660,"script_address":0},{"address":3252712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":81}],"party_address":3221676,"script_address":2310306},{"address":3252752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":287},{"level":35,"species":42}],"party_address":3221684,"script_address":2327187},{"address":3252792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":313},{"level":31,"species":41}],"party_address":3221700,"script_address":0},{"address":3252832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":30,"species":41}],"party_address":3221716,"script_address":2317615},{"address":3252872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":286},{"level":22,"species":339}],"party_address":3221732,"script_address":2309993},{"address":3252912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3221748,"script_address":2188216},{"address":3252952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3221764,"script_address":2095389},{"address":3252992,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3221772,"script_address":2095465},{"address":3253032,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":335}],"party_address":3221780,"script_address":2095427},{"address":3253072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":356}],"party_address":3221788,"script_address":2244674},{"address":3253112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3221796,"script_address":2070287},{"address":3253152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[87,86,98,0],"species":338},{"level":32,"moves":[57,168,0,0],"species":289}],"party_address":3221804,"script_address":2070768},{"address":3253192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":73}],"party_address":3221836,"script_address":2071645},{"address":3253232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":41}],"party_address":3221844,"script_address":2304070},{"address":3253272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3221852,"script_address":2073102},{"address":3253312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":203}],"party_address":3221860,"script_address":0},{"address":3253352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":351}],"party_address":3221868,"script_address":2244705},{"address":3253392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3221876,"script_address":2244829},{"address":3253432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3221884,"script_address":2244767},{"address":3253472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":202}],"party_address":3221892,"script_address":2244798},{"address":3253512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":286}],"party_address":3221900,"script_address":2254605},{"address":3253552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221916,"script_address":2254667},{"address":3253592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3221924,"script_address":2257768},{"address":3253632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":287}],"party_address":3221932,"script_address":2257818},{"address":3253672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221940,"script_address":2257868},{"address":3253712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":177}],"party_address":3221948,"script_address":2244736},{"address":3253752,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3221956,"script_address":1978559},{"address":3253792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3221972,"script_address":1978621},{"address":3253832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":305},{"level":33,"species":307}],"party_address":3221988,"script_address":2073732},{"address":3253872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3222004,"script_address":2069651},{"address":3253912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3222012,"script_address":2572062},{"address":3253952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":20,"species":286},{"level":22,"species":339},{"level":22,"species":41}],"party_address":3222028,"script_address":2304039},{"address":3253992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":317},{"level":33,"species":371}],"party_address":3222060,"script_address":2073794},{"address":3254032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":218},{"level":15,"species":283}],"party_address":3222076,"script_address":1978590},{"address":3254072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3222092,"script_address":1978317},{"address":3254112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":287},{"level":38,"species":169},{"level":39,"species":340}],"party_address":3222108,"script_address":2351441},{"address":3254152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":287},{"level":24,"species":41},{"level":25,"species":340}],"party_address":3222132,"script_address":2303440},{"address":3254192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":4,"species":306}],"party_address":3222156,"script_address":2024895},{"address":3254232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":295},{"level":6,"species":306}],"party_address":3222172,"script_address":2029715},{"address":3254272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":183}],"party_address":3222188,"script_address":2054459},{"address":3254312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183},{"level":15,"species":306},{"level":15,"species":339}],"party_address":3222196,"script_address":2045995},{"address":3254352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":306}],"party_address":3222220,"script_address":0},{"address":3254392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":307}],"party_address":3222236,"script_address":0},{"address":3254432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":307}],"party_address":3222252,"script_address":0},{"address":3254472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":296},{"level":34,"species":307}],"party_address":3222268,"script_address":0},{"address":3254512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":43}],"party_address":3222292,"script_address":2553761},{"address":3254552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":315},{"level":14,"species":306},{"level":14,"species":183}],"party_address":3222300,"script_address":2553823},{"address":3254592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325}],"party_address":3222324,"script_address":2265615},{"address":3254632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":118},{"level":39,"species":313}],"party_address":3222332,"script_address":2265646},{"address":3254672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":290},{"level":4,"species":290}],"party_address":3222348,"script_address":2024864},{"address":3254712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290}],"party_address":3222364,"script_address":2300392},{"address":3254752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":290},{"level":8,"species":301}],"party_address":3222396,"script_address":2054211},{"address":3254792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":301},{"level":28,"species":302}],"party_address":3222412,"script_address":2061137},{"address":3254832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222428,"script_address":2061168},{"address":3254872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302}],"party_address":3222444,"script_address":2061199},{"address":3254912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":301},{"level":6,"species":301}],"party_address":3222452,"script_address":2300423},{"address":3254952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":302}],"party_address":3222468,"script_address":0},{"address":3254992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":302}],"party_address":3222476,"script_address":0},{"address":3255032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":294},{"level":31,"species":302}],"party_address":3222492,"script_address":0},{"address":3255072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":311},{"level":33,"species":302},{"level":33,"species":294},{"level":33,"species":302}],"party_address":3222516,"script_address":0},{"address":3255112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":339},{"level":17,"species":66}],"party_address":3222548,"script_address":2049688},{"address":3255152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":17,"species":74},{"level":16,"species":74}],"party_address":3222564,"script_address":2049719},{"address":3255192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":66}],"party_address":3222588,"script_address":2051841},{"address":3255232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":339}],"party_address":3222604,"script_address":2051872},{"address":3255272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":74},{"level":22,"species":320},{"level":22,"species":75}],"party_address":3222620,"script_address":2557067},{"address":3255312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74}],"party_address":3222644,"script_address":2054428},{"address":3255352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":74},{"level":20,"species":318}],"party_address":3222652,"script_address":2310061},{"address":3255392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":9,"moves":[150,55,0,0],"species":313}],"party_address":3222668,"script_address":0},{"address":3255432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[16,45,0,0],"species":310},{"level":10,"moves":[44,184,0,0],"species":286}],"party_address":3222684,"script_address":0},{"address":3255472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":16,"species":74},{"level":16,"species":66}],"party_address":3222716,"script_address":2296023},{"address":3255512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":75}],"party_address":3222740,"script_address":0},{"address":3255552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":74},{"level":27,"species":74},{"level":27,"species":75},{"level":27,"species":75}],"party_address":3222772,"script_address":0},{"address":3255592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":74},{"level":30,"species":75},{"level":30,"species":75},{"level":30,"species":75}],"party_address":3222804,"script_address":0},{"address":3255632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":76}],"party_address":3222836,"script_address":0},{"address":3255672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":316},{"level":31,"species":338}],"party_address":3222868,"script_address":0},{"address":3255712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":325}],"party_address":3222884,"script_address":0},{"address":3255752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222900,"script_address":0},{"address":3255792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":386},{"level":30,"species":387}],"party_address":3222916,"script_address":0},{"address":3255832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":386},{"level":33,"species":387}],"party_address":3222932,"script_address":0},{"address":3255872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":386},{"level":36,"species":387}],"party_address":3222948,"script_address":0},{"address":3255912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":386},{"level":39,"species":387}],"party_address":3222964,"script_address":0},{"address":3255952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":118}],"party_address":3222980,"script_address":2543970},{"address":3255992,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[53,154,185,20],"species":317}],"party_address":3222988,"script_address":2103539},{"address":3256032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[117,197,93,9],"species":356},{"level":17,"moves":[9,197,93,96],"species":356}],"party_address":3223004,"script_address":2167701},{"address":3256072,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[117,197,93,7],"species":356}],"party_address":3223036,"script_address":2103508},{"address":3256112,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[33,120,124,108],"species":109},{"level":25,"moves":[33,139,124,108],"species":109}],"party_address":3223052,"script_address":2061574},{"address":3256152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[139,120,124,108],"species":109},{"level":28,"moves":[28,104,210,14],"species":302}],"party_address":3223084,"script_address":2065775},{"address":3256192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[141,154,170,91],"species":301},{"level":28,"moves":[33,120,124,108],"species":109}],"party_address":3223116,"script_address":2065806},{"address":3256232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":305},{"level":29,"species":178}],"party_address":3223148,"script_address":2202329},{"address":3256272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":358},{"level":27,"species":358},{"level":27,"species":358}],"party_address":3223164,"script_address":2202360},{"address":3256312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":392}],"party_address":3223188,"script_address":1971405},{"address":3256352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[76,219,225,93],"species":359},{"level":46,"moves":[47,18,204,185],"species":316},{"level":47,"moves":[89,73,202,92],"species":363},{"level":44,"moves":[48,85,161,103],"species":82},{"level":48,"moves":[104,91,94,248],"species":394}],"party_address":3223196,"script_address":2332607},{"address":3256392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[76,219,225,93],"species":359},{"level":49,"moves":[47,18,204,185],"species":316},{"level":50,"moves":[89,73,202,92],"species":363},{"level":47,"moves":[48,85,161,103],"species":82},{"level":51,"moves":[104,91,94,248],"species":394}],"party_address":3223276,"script_address":0},{"address":3256432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[76,219,225,93],"species":359},{"level":52,"moves":[47,18,204,185],"species":316},{"level":53,"moves":[89,73,202,92],"species":363},{"level":50,"moves":[48,85,161,103],"species":82},{"level":54,"moves":[104,91,94,248],"species":394}],"party_address":3223356,"script_address":0},{"address":3256472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[76,219,225,93],"species":359},{"level":55,"moves":[47,18,204,185],"species":316},{"level":56,"moves":[89,73,202,92],"species":363},{"level":53,"moves":[48,85,161,103],"species":82},{"level":57,"moves":[104,91,94,248],"species":394}],"party_address":3223436,"script_address":0},{"address":3256512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223516,"script_address":1986165},{"address":3256552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223548,"script_address":1986109},{"address":3256592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223580,"script_address":1986137},{"address":3256632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223612,"script_address":1986081},{"address":3256672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223644,"script_address":1986025},{"address":3256712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223676,"script_address":1986053},{"address":3256752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":31,"species":72},{"level":32,"species":331}],"party_address":3223708,"script_address":2070644},{"address":3256792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":34,"species":73}],"party_address":3223732,"script_address":2070675},{"address":3256832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":129},{"level":25,"species":129},{"level":35,"species":130}],"party_address":3223748,"script_address":2070706},{"address":3256872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":44},{"level":34,"species":184}],"party_address":3223772,"script_address":2071552},{"address":3256912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":300},{"level":34,"species":320}],"party_address":3223788,"script_address":2071583},{"address":3256952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":67}],"party_address":3223804,"script_address":2070799},{"address":3256992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":72},{"level":31,"species":72},{"level":36,"species":313}],"party_address":3223812,"script_address":2071614},{"address":3257032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":305},{"level":32,"species":227}],"party_address":3223836,"script_address":2070737},{"address":3257072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":341},{"level":33,"species":331}],"party_address":3223852,"script_address":2073040},{"address":3257112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170}],"party_address":3223868,"script_address":2073071},{"address":3257152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":308},{"level":19,"species":308}],"party_address":3223876,"script_address":0},{"address":3257192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[47,31,219,76],"species":358},{"level":35,"moves":[53,36,156,89],"species":339}],"party_address":3223892,"script_address":0},{"address":3257232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[74,78,72,73],"species":363},{"level":20,"moves":[111,205,44,88],"species":75}],"party_address":3223924,"script_address":0},{"address":3257272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[16,60,92,182],"species":294},{"level":27,"moves":[16,72,213,78],"species":292}],"party_address":3223956,"script_address":0},{"address":3257312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[94,7,244,182],"species":357},{"level":39,"moves":[8,61,156,187],"species":336}],"party_address":3223988,"script_address":0},{"address":3257352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,7,244,182],"species":357},{"level":43,"moves":[8,61,156,187],"species":336}],"party_address":3224020,"script_address":0},{"address":3257392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[94,7,244,182],"species":357},{"level":46,"moves":[8,61,156,187],"species":336}],"party_address":3224052,"script_address":0},{"address":3257432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":49,"moves":[94,7,244,182],"species":357},{"level":49,"moves":[8,61,156,187],"species":336}],"party_address":3224084,"script_address":0},{"address":3257472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[94,7,244,182],"species":357},{"level":52,"moves":[8,61,156,187],"species":336}],"party_address":3224116,"script_address":0},{"address":3257512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":33,"species":309}],"party_address":3224148,"script_address":0},{"address":3257552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170},{"level":33,"species":330}],"party_address":3224164,"script_address":0},{"address":3257592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":170},{"level":40,"species":330}],"party_address":3224180,"script_address":0},{"address":3257632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":171},{"level":43,"species":330}],"party_address":3224196,"script_address":0},{"address":3257672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":171},{"level":46,"species":331}],"party_address":3224212,"script_address":0},{"address":3257712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":51,"species":171},{"level":49,"species":331}],"party_address":3224228,"script_address":0},{"address":3257752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":118},{"level":25,"species":72}],"party_address":3224244,"script_address":0},{"address":3257792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":129},{"level":20,"species":72},{"level":26,"species":328},{"level":23,"species":330}],"party_address":3224260,"script_address":2061605},{"address":3257832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":288},{"level":8,"species":286}],"party_address":3224292,"script_address":2054707},{"address":3257872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":295},{"level":8,"species":288}],"party_address":3224308,"script_address":2054676},{"address":3257912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":129}],"party_address":3224324,"script_address":2030343},{"address":3257952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":183}],"party_address":3224332,"script_address":2036307},{"address":3257992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":72},{"level":12,"species":72}],"party_address":3224340,"script_address":2036276},{"address":3258032,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":354},{"level":14,"species":353}],"party_address":3224356,"script_address":2039032},{"address":3258072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":337},{"level":14,"species":100}],"party_address":3224372,"script_address":2039063},{"address":3258112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81}],"party_address":3224388,"script_address":2039094},{"address":3258152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":100}],"party_address":3224396,"script_address":2026463},{"address":3258192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":335}],"party_address":3224404,"script_address":2026494},{"address":3258232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":27}],"party_address":3224412,"script_address":2046975},{"address":3258272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":363}],"party_address":3224420,"script_address":2047006},{"address":3258312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306}],"party_address":3224428,"script_address":2046944},{"address":3258352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339}],"party_address":3224436,"script_address":2046913},{"address":3258392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":183},{"level":19,"species":296}],"party_address":3224444,"script_address":2050969},{"address":3258432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":227},{"level":19,"species":305}],"party_address":3224460,"script_address":2051000},{"address":3258472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":318},{"level":18,"species":27}],"party_address":3224476,"script_address":2051031},{"address":3258512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":382},{"level":18,"species":382}],"party_address":3224492,"script_address":2051062},{"address":3258552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":183}],"party_address":3224508,"script_address":2052309},{"address":3258592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3224524,"script_address":2052371},{"address":3258632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":299}],"party_address":3224532,"script_address":2052340},{"address":3258672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":14,"species":382},{"level":14,"species":337}],"party_address":3224540,"script_address":2059128},{"address":3258712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224564,"script_address":2347841},{"address":3258752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224572,"script_address":2347872},{"address":3258792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224580,"script_address":2348597},{"address":3258832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":41}],"party_address":3224588,"script_address":2348628},{"address":3258872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":339}],"party_address":3224604,"script_address":2348659},{"address":3258912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224620,"script_address":2349324},{"address":3258952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224628,"script_address":2349355},{"address":3258992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224636,"script_address":2349386},{"address":3259032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224644,"script_address":2350264},{"address":3259072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224652,"script_address":2350826},{"address":3259112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224660,"script_address":2351566},{"address":3259152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224668,"script_address":2351597},{"address":3259192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224676,"script_address":2351628},{"address":3259232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224684,"script_address":2348566},{"address":3259272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224692,"script_address":2349293},{"address":3259312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224700,"script_address":2350295},{"address":3259352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":339},{"level":28,"species":287},{"level":30,"species":41},{"level":33,"species":340}],"party_address":3224708,"script_address":2351659},{"address":3259392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":310},{"level":33,"species":340}],"party_address":3224740,"script_address":2073763},{"address":3259432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":287},{"level":43,"species":169},{"level":44,"species":340}],"party_address":3224756,"script_address":0},{"address":3259472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":72}],"party_address":3224780,"script_address":2026525},{"address":3259512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183}],"party_address":3224788,"script_address":2026556},{"address":3259552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":27},{"level":25,"species":27}],"party_address":3224796,"script_address":2033726},{"address":3259592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":309}],"party_address":3224812,"script_address":2033695},{"address":3259632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":120}],"party_address":3224828,"script_address":2034744},{"address":3259672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":309},{"level":24,"species":66},{"level":24,"species":72}],"party_address":3224836,"script_address":2034931},{"address":3259712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":338},{"level":24,"species":305},{"level":24,"species":338}],"party_address":3224860,"script_address":2034900},{"address":3259752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":227},{"level":25,"species":227}],"party_address":3224884,"script_address":2036338},{"address":3259792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":183},{"level":22,"species":296}],"party_address":3224900,"script_address":2047037},{"address":3259832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":27},{"level":22,"species":28}],"party_address":3224916,"script_address":2047068},{"address":3259872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":304},{"level":22,"species":299}],"party_address":3224932,"script_address":2047099},{"address":3259912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":18,"species":218}],"party_address":3224948,"script_address":2049891},{"address":3259952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306},{"level":18,"species":363}],"party_address":3224964,"script_address":2049922},{"address":3259992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":84},{"level":26,"species":85}],"party_address":3224980,"script_address":2053203},{"address":3260032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302},{"level":26,"species":367}],"party_address":3224996,"script_address":2053234},{"address":3260072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":64},{"level":26,"species":393}],"party_address":3225012,"script_address":2053265},{"address":3260112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3225028,"script_address":2053296},{"address":3260152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":351}],"party_address":3225044,"script_address":2053327},{"address":3260192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3225060,"script_address":2054738},{"address":3260232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":306},{"level":8,"species":295}],"party_address":3225076,"script_address":2054769},{"address":3260272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3225092,"script_address":2057834},{"address":3260312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3225100,"script_address":2057865},{"address":3260352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":356}],"party_address":3225108,"script_address":2057896},{"address":3260392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":363},{"level":33,"species":357}],"party_address":3225116,"script_address":2073825},{"address":3260432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":338}],"party_address":3225132,"script_address":2061636},{"address":3260472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":218},{"level":25,"species":339}],"party_address":3225140,"script_address":2061667},{"address":3260512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3225156,"script_address":2061698},{"address":3260552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[87,98,86,0],"species":338}],"party_address":3225164,"script_address":2065837},{"address":3260592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":356},{"level":28,"species":335}],"party_address":3225180,"script_address":2065868},{"address":3260632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":292}],"party_address":3225196,"script_address":2067487},{"address":3260672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":335},{"level":25,"species":309},{"level":25,"species":369},{"level":25,"species":288},{"level":25,"species":337},{"level":25,"species":339}],"party_address":3225212,"script_address":2067518},{"address":3260712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":286},{"level":25,"species":306},{"level":25,"species":337},{"level":25,"species":183},{"level":25,"species":27},{"level":25,"species":367}],"party_address":3225260,"script_address":2067549},{"address":3260752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":371},{"level":29,"species":365}],"party_address":3225308,"script_address":2067611},{"address":3260792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3225324,"script_address":1978255},{"address":3260832,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":321},{"level":15,"species":283}],"party_address":3225340,"script_address":1978286},{"address":3260872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[182,205,222,153],"species":76},{"level":35,"moves":[14,58,57,157],"species":140},{"level":35,"moves":[231,153,46,157],"species":95},{"level":37,"moves":[104,153,182,157],"species":320}],"party_address":3225356,"script_address":0},{"address":3260912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[182,58,157,57],"species":138},{"level":37,"moves":[182,205,222,153],"species":76},{"level":40,"moves":[14,58,57,157],"species":141},{"level":40,"moves":[231,153,46,157],"species":95},{"level":42,"moves":[104,153,182,157],"species":320}],"party_address":3225420,"script_address":0},{"address":3260952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[182,58,157,57],"species":139},{"level":42,"moves":[182,205,89,153],"species":76},{"level":45,"moves":[14,58,57,157],"species":141},{"level":45,"moves":[231,153,46,157],"species":95},{"level":47,"moves":[104,153,182,157],"species":320}],"party_address":3225500,"script_address":0},{"address":3260992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[157,63,48,182],"species":142},{"level":47,"moves":[8,205,89,153],"species":76},{"level":47,"moves":[182,58,157,57],"species":139},{"level":50,"moves":[14,58,57,157],"species":141},{"level":50,"moves":[231,153,46,157],"species":208},{"level":52,"moves":[104,153,182,157],"species":320}],"party_address":3225580,"script_address":0},{"address":3261032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[2,157,8,83],"species":68},{"level":33,"moves":[94,113,115,8],"species":356},{"level":35,"moves":[228,68,182,167],"species":237},{"level":37,"moves":[252,8,187,89],"species":336}],"party_address":3225676,"script_address":0},{"address":3261072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[2,157,8,83],"species":68},{"level":38,"moves":[94,113,115,8],"species":357},{"level":40,"moves":[228,68,182,167],"species":237},{"level":42,"moves":[252,8,187,89],"species":336}],"party_address":3225740,"script_address":0},{"address":3261112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[71,182,7,8],"species":107},{"level":43,"moves":[2,157,8,83],"species":68},{"level":43,"moves":[8,113,115,94],"species":357},{"level":45,"moves":[228,68,182,167],"species":237},{"level":47,"moves":[252,8,187,89],"species":336}],"party_address":3225804,"script_address":0},{"address":3261152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[25,8,89,83],"species":106},{"level":46,"moves":[71,182,7,8],"species":107},{"level":48,"moves":[238,157,8,83],"species":68},{"level":48,"moves":[8,113,115,94],"species":357},{"level":50,"moves":[228,68,182,167],"species":237},{"level":52,"moves":[252,8,187,89],"species":336}],"party_address":3225884,"script_address":0},{"address":3261192,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,182,86,113],"species":179},{"level":36,"moves":[205,87,153,240],"species":101},{"level":38,"moves":[48,182,87,240],"species":82},{"level":40,"moves":[44,86,87,182],"species":338}],"party_address":3225980,"script_address":0},{"address":3261232,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[87,21,240,95],"species":25},{"level":41,"moves":[87,182,86,113],"species":180},{"level":41,"moves":[205,87,153,240],"species":101},{"level":43,"moves":[48,182,87,240],"species":82},{"level":45,"moves":[44,86,87,182],"species":338}],"party_address":3226044,"script_address":0},{"address":3261272,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[87,21,240,182],"species":26},{"level":46,"moves":[87,182,86,113],"species":181},{"level":46,"moves":[205,87,153,240],"species":101},{"level":48,"moves":[48,182,87,240],"species":82},{"level":50,"moves":[44,86,87,182],"species":338}],"party_address":3226124,"script_address":0},{"address":3261312,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[129,8,9,113],"species":125},{"level":51,"moves":[87,21,240,182],"species":26},{"level":51,"moves":[87,182,86,113],"species":181},{"level":53,"moves":[205,87,153,240],"species":101},{"level":53,"moves":[48,182,87,240],"species":82},{"level":55,"moves":[44,86,87,182],"species":338}],"party_address":3226204,"script_address":0},{"address":3261352,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[59,213,113,157],"species":219},{"level":36,"moves":[53,213,76,84],"species":77},{"level":38,"moves":[59,241,89,213],"species":340},{"level":40,"moves":[59,241,153,213],"species":321}],"party_address":3226300,"script_address":0},{"address":3261392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[14,53,46,241],"species":58},{"level":43,"moves":[59,213,113,157],"species":219},{"level":41,"moves":[53,213,76,84],"species":77},{"level":43,"moves":[59,241,89,213],"species":340},{"level":45,"moves":[59,241,153,213],"species":321}],"party_address":3226364,"script_address":0},{"address":3261432,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,76,13,241],"species":228},{"level":46,"moves":[14,53,241,46],"species":58},{"level":48,"moves":[59,213,113,157],"species":219},{"level":46,"moves":[53,213,76,84],"species":78},{"level":48,"moves":[59,241,89,213],"species":340},{"level":50,"moves":[59,241,153,213],"species":321}],"party_address":3226444,"script_address":0},{"address":3261472,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":51,"moves":[14,53,241,46],"species":59},{"level":53,"moves":[59,213,113,157],"species":219},{"level":51,"moves":[46,76,13,241],"species":229},{"level":51,"moves":[53,213,76,84],"species":78},{"level":53,"moves":[59,241,89,213],"species":340},{"level":55,"moves":[59,241,153,213],"species":321}],"party_address":3226540,"script_address":0},{"address":3261512,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[113,47,29,8],"species":113},{"level":42,"moves":[59,247,38,126],"species":366},{"level":43,"moves":[42,29,7,95],"species":308},{"level":45,"moves":[63,53,85,247],"species":366}],"party_address":3226636,"script_address":0},{"address":3261552,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[59,247,38,126],"species":366},{"level":47,"moves":[113,47,29,8],"species":113},{"level":45,"moves":[252,146,203,179],"species":115},{"level":48,"moves":[42,29,7,95],"species":308},{"level":50,"moves":[63,53,85,247],"species":366}],"party_address":3226700,"script_address":0},{"address":3261592,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[59,247,38,126],"species":366},{"level":52,"moves":[113,47,29,8],"species":242},{"level":50,"moves":[252,146,203,179],"species":115},{"level":53,"moves":[42,29,7,95],"species":308},{"level":55,"moves":[63,53,85,247],"species":366}],"party_address":3226780,"script_address":0},{"address":3261632,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[59,247,38,126],"species":366},{"level":57,"moves":[182,47,29,8],"species":242},{"level":55,"moves":[252,146,203,179],"species":115},{"level":57,"moves":[36,182,126,89],"species":128},{"level":58,"moves":[42,29,7,95],"species":308},{"level":60,"moves":[63,53,85,247],"species":366}],"party_address":3226860,"script_address":0},{"address":3261672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[86,85,182,58],"species":147},{"level":38,"moves":[241,76,76,89],"species":369},{"level":41,"moves":[57,48,182,76],"species":310},{"level":43,"moves":[18,191,211,76],"species":227},{"level":45,"moves":[76,156,93,89],"species":359}],"party_address":3226956,"script_address":0},{"address":3261712,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[95,94,115,138],"species":163},{"level":43,"moves":[241,76,76,89],"species":369},{"level":45,"moves":[86,85,182,58],"species":148},{"level":46,"moves":[57,48,182,76],"species":310},{"level":48,"moves":[18,191,211,76],"species":227},{"level":50,"moves":[76,156,93,89],"species":359}],"party_address":3227036,"script_address":0},{"address":3261752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[95,94,115,138],"species":164},{"level":49,"moves":[241,76,76,89],"species":369},{"level":50,"moves":[86,85,182,58],"species":148},{"level":51,"moves":[57,48,182,76],"species":310},{"level":53,"moves":[18,191,211,76],"species":227},{"level":55,"moves":[76,156,93,89],"species":359}],"party_address":3227132,"script_address":0},{"address":3261792,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,94,115,138],"species":164},{"level":54,"moves":[241,76,76,89],"species":369},{"level":55,"moves":[57,48,182,76],"species":310},{"level":55,"moves":[63,85,89,58],"species":149},{"level":58,"moves":[18,191,211,76],"species":227},{"level":60,"moves":[143,156,93,89],"species":359}],"party_address":3227228,"script_address":0},{"address":3261832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[25,94,91,182],"species":79},{"level":49,"moves":[89,246,94,113],"species":319},{"level":49,"moves":[94,156,109,91],"species":178},{"level":50,"moves":[89,94,156,91],"species":348},{"level":50,"moves":[241,76,94,53],"species":349}],"party_address":3227324,"script_address":0},{"address":3261872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,138,29,182],"species":96},{"level":53,"moves":[25,94,91,182],"species":79},{"level":54,"moves":[89,153,94,113],"species":319},{"level":54,"moves":[94,156,109,91],"species":178},{"level":55,"moves":[89,94,156,91],"species":348},{"level":55,"moves":[241,76,94,53],"species":349}],"party_address":3227404,"script_address":0},{"address":3261912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":58,"moves":[95,138,29,182],"species":97},{"level":59,"moves":[89,153,94,113],"species":319},{"level":58,"moves":[25,94,91,182],"species":79},{"level":59,"moves":[94,156,109,91],"species":178},{"level":60,"moves":[89,94,156,91],"species":348},{"level":60,"moves":[241,76,94,53],"species":349}],"party_address":3227500,"script_address":0},{"address":3261952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":63,"moves":[95,138,29,182],"species":97},{"level":64,"moves":[89,153,94,113],"species":319},{"level":63,"moves":[25,94,91,182],"species":199},{"level":64,"moves":[94,156,109,91],"species":178},{"level":65,"moves":[89,94,156,91],"species":348},{"level":65,"moves":[241,76,94,53],"species":349}],"party_address":3227596,"script_address":0},{"address":3261992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[95,240,182,56],"species":60},{"level":46,"moves":[240,96,104,90],"species":324},{"level":48,"moves":[96,34,182,58],"species":343},{"level":48,"moves":[156,152,13,104],"species":327},{"level":51,"moves":[96,104,58,156],"species":230}],"party_address":3227692,"script_address":0},{"address":3262032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[95,240,182,56],"species":61},{"level":51,"moves":[240,96,104,90],"species":324},{"level":53,"moves":[96,34,182,58],"species":343},{"level":53,"moves":[156,12,13,104],"species":327},{"level":56,"moves":[96,104,58,156],"species":230}],"party_address":3227772,"script_address":0},{"address":3262072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[56,195,58,109],"species":131},{"level":58,"moves":[240,96,104,90],"species":324},{"level":56,"moves":[95,240,182,56],"species":61},{"level":58,"moves":[96,34,182,58],"species":343},{"level":58,"moves":[156,12,13,104],"species":327},{"level":61,"moves":[96,104,58,156],"species":230}],"party_address":3227852,"script_address":0},{"address":3262112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":61,"moves":[56,195,58,109],"species":131},{"level":63,"moves":[240,96,104,90],"species":324},{"level":61,"moves":[95,240,56,195],"species":186},{"level":63,"moves":[96,34,182,73],"species":343},{"level":63,"moves":[156,12,13,104],"species":327},{"level":66,"moves":[96,104,58,156],"species":230}],"party_address":3227948,"script_address":0},{"address":3262152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[95,98,204,0],"species":387},{"level":17,"moves":[95,98,109,0],"species":386}],"party_address":3228044,"script_address":2167732},{"address":3262192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":369}],"party_address":3228076,"script_address":2202422},{"address":3262232,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":77,"moves":[92,76,191,211],"species":227},{"level":75,"moves":[115,113,246,89],"species":319},{"level":76,"moves":[87,89,76,81],"species":384},{"level":76,"moves":[202,246,19,109],"species":389},{"level":76,"moves":[96,246,76,163],"species":391},{"level":78,"moves":[89,94,53,247],"species":400}],"party_address":3228084,"script_address":2354502},{"address":3262272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228180,"script_address":0},{"address":3262312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228188,"script_address":0},{"address":3262352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228196,"script_address":0},{"address":3262392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228204,"script_address":0},{"address":3262432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228212,"script_address":0},{"address":3262472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228220,"script_address":0},{"address":3262512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228228,"script_address":0},{"address":3262552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":27}],"party_address":3228236,"script_address":0},{"address":3262592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":320},{"level":33,"species":27},{"level":33,"species":27}],"party_address":3228252,"script_address":0},{"address":3262632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":320},{"level":35,"species":27},{"level":35,"species":27}],"party_address":3228276,"script_address":0},{"address":3262672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":320},{"level":37,"species":28},{"level":37,"species":28}],"party_address":3228300,"script_address":0},{"address":3262712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":309},{"level":30,"species":66},{"level":30,"species":72}],"party_address":3228324,"script_address":0},{"address":3262752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":66},{"level":32,"species":72}],"party_address":3228348,"script_address":0},{"address":3262792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":66},{"level":34,"species":73}],"party_address":3228372,"script_address":0},{"address":3262832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":310},{"level":36,"species":67},{"level":36,"species":73}],"party_address":3228396,"script_address":0},{"address":3262872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":120},{"level":37,"species":120}],"party_address":3228420,"script_address":0},{"address":3262912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":309},{"level":39,"species":120},{"level":39,"species":120}],"party_address":3228436,"script_address":0},{"address":3262952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":310},{"level":41,"species":120},{"level":41,"species":120}],"party_address":3228460,"script_address":0},{"address":3262992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":310},{"level":43,"species":121},{"level":43,"species":121}],"party_address":3228484,"script_address":0},{"address":3263032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":67},{"level":37,"species":67}],"party_address":3228508,"script_address":0},{"address":3263072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":335},{"level":39,"species":67},{"level":39,"species":67}],"party_address":3228524,"script_address":0},{"address":3263112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":336},{"level":41,"species":67},{"level":41,"species":67}],"party_address":3228548,"script_address":0},{"address":3263152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":336},{"level":43,"species":68},{"level":43,"species":68}],"party_address":3228572,"script_address":0},{"address":3263192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":371},{"level":35,"species":365}],"party_address":3228596,"script_address":0},{"address":3263232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":308},{"level":37,"species":371},{"level":37,"species":365}],"party_address":3228612,"script_address":0},{"address":3263272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":308},{"level":39,"species":371},{"level":39,"species":365}],"party_address":3228636,"script_address":0},{"address":3263312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":308},{"level":41,"species":372},{"level":41,"species":366}],"party_address":3228660,"script_address":0},{"address":3263352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":337},{"level":35,"species":337},{"level":35,"species":371}],"party_address":3228684,"script_address":0},{"address":3263392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":337},{"level":37,"species":338},{"level":37,"species":371}],"party_address":3228708,"script_address":0},{"address":3263432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":338},{"level":39,"species":338},{"level":39,"species":371}],"party_address":3228732,"script_address":0},{"address":3263472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":338},{"level":41,"species":338},{"level":41,"species":372}],"party_address":3228756,"script_address":0},{"address":3263512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":74},{"level":26,"species":339}],"party_address":3228780,"script_address":0},{"address":3263552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":66},{"level":28,"species":339},{"level":28,"species":75}],"party_address":3228796,"script_address":0},{"address":3263592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":66},{"level":30,"species":339},{"level":30,"species":75}],"party_address":3228820,"script_address":0},{"address":3263632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":340},{"level":33,"species":76}],"party_address":3228844,"script_address":0},{"address":3263672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":315},{"level":31,"species":287},{"level":31,"species":288},{"level":31,"species":295},{"level":31,"species":298},{"level":31,"species":304}],"party_address":3228868,"script_address":0},{"address":3263712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":315},{"level":33,"species":287},{"level":33,"species":289},{"level":33,"species":296},{"level":33,"species":299},{"level":33,"species":304}],"party_address":3228916,"script_address":0},{"address":3263752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316},{"level":35,"species":287},{"level":35,"species":289},{"level":35,"species":296},{"level":35,"species":299},{"level":35,"species":305}],"party_address":3228964,"script_address":0},{"address":3263792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":316},{"level":37,"species":287},{"level":37,"species":289},{"level":37,"species":297},{"level":37,"species":300},{"level":37,"species":305}],"party_address":3229012,"script_address":0},{"address":3263832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313},{"level":34,"species":116}],"party_address":3229060,"script_address":0},{"address":3263872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":325},{"level":36,"species":313},{"level":36,"species":117}],"party_address":3229076,"script_address":0},{"address":3263912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":325},{"level":38,"species":313},{"level":38,"species":117}],"party_address":3229100,"script_address":0},{"address":3263952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325},{"level":40,"species":314},{"level":40,"species":230}],"party_address":3229124,"script_address":0},{"address":3263992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":411}],"party_address":3229148,"script_address":2564791},{"address":3264032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":64}],"party_address":3229156,"script_address":2564822},{"address":3264072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":202}],"party_address":3229172,"script_address":0},{"address":3264112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":4}],"party_address":3229180,"script_address":0},{"address":3264152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":1}],"party_address":3229188,"script_address":0},{"address":3264192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":405}],"party_address":3229196,"script_address":0},{"address":3264232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":404}],"party_address":3229204,"script_address":0}],"warps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4":"MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0","MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2":"MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1","MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10","MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2":"MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11","MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3":"MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2","MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0":"MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4","MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3":"MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5","MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2":"MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6","MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4":"MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7","MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0":"MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8","MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9","MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2":"MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0","MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0":"MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1","MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0":"MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2","MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1":"MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3","MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2":"MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4","MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0":"MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5","MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10":"MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6","MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9":"MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7","MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0":"MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0","MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2","MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3","MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0":"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8","MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8":"MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0","MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11":"MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2","MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0","MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0","MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3","MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4","MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0","MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1","MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2","MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0","MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0":"MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0","MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0":"MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0","MAP_ALTERING_CAVE:0/MAP_ROUTE103:0":"MAP_ROUTE103:0/MAP_ALTERING_CAVE:0","MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0":"MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0","MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2":"MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1","MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1":"MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2","MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6":"MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0","MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0":"MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2","MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2":"MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0","MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0":"MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1","MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6":"MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10","MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22":"MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11","MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9":"MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12","MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18":"MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13","MAP_AQUA_HIDEOUT_B1F:14/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16":"MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15","MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15":"MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16","MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20":"MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17","MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13":"MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18","MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24":"MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19","MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1":"MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2","MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:21/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11":"MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22","MAP_AQUA_HIDEOUT_B1F:23/MAP_AQUA_HIDEOUT_B1F:17!":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19":"MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24","MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2":"MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3","MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7":"MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4","MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8":"MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5","MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10":"MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6","MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5":"MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8","MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1":"MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0","MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2":"MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1","MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3":"MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2","MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5":"MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3","MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8":"MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4","MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3":"MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5","MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7":"MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6","MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6":"MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7","MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4":"MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8","MAP_AQUA_HIDEOUT_B2F:9/MAP_AQUA_HIDEOUT_B1F:4!":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0","MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1":"MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1","MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0","MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1":"MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1","MAP_BATTLE_COLOSSEUM_2P:0,1/MAP_DYNAMIC:-1!":"","MAP_BATTLE_COLOSSEUM_4P:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:3/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0!":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2","MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2","MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0","MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0","MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0","MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0","MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0","MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0","MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0","MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0","MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0","MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0","MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0":"MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0":"MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0":"MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0":"MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0":"MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0":"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0":"MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0":"MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0":"MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0":"MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0":"MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0":"MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0":"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0":"MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0":"MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1","MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0","MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0":"MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0","MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0":"MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0","MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1":"MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0","MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3":"MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0":"MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:0/MAP_CAVE_OF_ORIGIN_1F:1!":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:1/MAP_CAVE_OF_ORIGIN_B1F:0!":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_DESERT_RUINS:0/MAP_ROUTE111:1":"MAP_ROUTE111:1/MAP_DESERT_RUINS:0","MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2":"MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1","MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1":"MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2","MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0","MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0":"MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0","MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1","MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0":"MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2","MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0":"MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3","MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0":"MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4","MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2":"MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0","MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0":"MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0","MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3":"MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0","MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4":"MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1":"MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0","MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1","MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0":"MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2","MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1":"MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1":"MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0":"MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1":"MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0":"MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1":"MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0":"MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1","MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0","MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1","MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0","MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1","MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0","MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1","MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0","MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1","MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0","MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1","MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1":"MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0":"MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1":"MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0":"MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0":"MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1":"MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0":"MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1","MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0":"MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0","MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0":"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1","MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2","MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0":"MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3","MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0":"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4","MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1":"MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0","MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3":"MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0","MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0":"MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0","MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4":"MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2":"MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1":"MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1","MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1":"MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1","MAP_FIERY_PATH:0/MAP_ROUTE112:4":"MAP_ROUTE112:4/MAP_FIERY_PATH:0","MAP_FIERY_PATH:1/MAP_ROUTE112:5":"MAP_ROUTE112:5/MAP_FIERY_PATH:1","MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0","MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0":"MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1","MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0":"MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2","MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0":"MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3","MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0":"MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4","MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0":"MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5","MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0":"MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6","MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0":"MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7","MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0":"MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8","MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8":"MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0","MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2":"MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0","MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1":"MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0","MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4":"MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0","MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5":"MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0","MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6":"MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0","MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7":"MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0","MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3":"MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0":"MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2","MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0","MAP_FORTREE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FORTREE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0":"MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0","MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0":"MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1","MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1":"MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2","MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0":"MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3","MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1":"MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0","MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2":"MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1","MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0":"MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2","MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1":"MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3","MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2":"MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4","MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3":"MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5","MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4":"MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6","MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2":"MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0","MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3":"MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1","MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4":"MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2","MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5":"MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3","MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6":"MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4","MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3":"MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0","MAP_INSIDE_OF_TRUCK:0,1,2/MAP_DYNAMIC:-1!":"","MAP_ISLAND_CAVE:0/MAP_ROUTE105:0":"MAP_ROUTE105:0/MAP_ISLAND_CAVE:0","MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2":"MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1","MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1":"MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2","MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3":"MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1","MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3":"MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3","MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0":"MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4","MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0":"MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0","MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0":"MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1","MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0":"MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2","MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3","MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0":"MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4","MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5","MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1":"MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0","MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8":"MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10","MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9":"MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11","MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10":"MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12","MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11":"MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13","MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12":"MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14","MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13":"MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15","MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14":"MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16","MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15":"MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17","MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16":"MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18","MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17":"MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19","MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0":"MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2","MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18":"MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20","MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20":"MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21","MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19":"MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22","MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21":"MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23","MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22":"MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24","MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23":"MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25","MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2":"MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3","MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4":"MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4","MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3":"MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5","MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1":"MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6","MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5":"MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7","MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6":"MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8","MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7":"MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9","MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2":"MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0","MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6":"MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1","MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12":"MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10","MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13":"MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11","MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14":"MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12","MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15":"MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13","MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16":"MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14","MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17":"MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15","MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18":"MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16","MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19":"MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17","MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20":"MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18","MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22":"MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19","MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3":"MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2","MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21":"MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20","MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23":"MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21","MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24":"MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22","MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25":"MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23","MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5":"MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3","MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4":"MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4","MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7":"MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5","MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8":"MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6","MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9":"MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7","MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10":"MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8","MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11":"MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9","MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0":"MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0","MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4":"MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0","MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2":"MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3":"MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5":"MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0","MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1","MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0":"MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10","MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0":"MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11","MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0":"MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12","MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2","MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13","MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4","MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1":"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5","MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0":"MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6","MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0":"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7","MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0":"MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8","MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0":"MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9","MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0","MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1","MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4":"MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0","MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0":"MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2","MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1":"MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1":"MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:3/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!":"","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0","MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12":"MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0","MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8":"MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0","MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9":"MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0","MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10":"MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0","MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11":"MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13":"MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0","MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7":"MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2":"MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5":"MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1","MAP_LILYCOVE_CITY_UNUSED_MART:0,1/MAP_LILYCOVE_CITY:0!":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0","MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1","MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0":"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1":"MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0":"MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2":"MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0","MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4":"MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0","MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1":"MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1","MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1":"MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2","MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0":"MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3","MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0":"MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0","MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1":"MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1","MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2":"MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2","MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0":"MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0","MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2":"MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1","MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3":"MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0","MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0":"MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1","MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0":"MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0","MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0":"MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1","MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2":"MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2","MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1":"MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0","MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1":"MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0","MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1":"MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1","MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0":"MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0","MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1":"MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1","MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0":"MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0","MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0":"MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0","MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0":"MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0","MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1","MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0":"MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2","MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0":"MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3","MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0":"MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4","MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0":"MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5","MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0":"MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6","MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2":"MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0","MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5":"MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0","MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0":"MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0","MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4":"MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0","MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6":"MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0","MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3":"MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1":"MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0":"MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0","MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0":"MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1","MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0":"MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2","MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4":"MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3","MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5":"MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4","MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0":"MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5","MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2":"MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0","MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0":"MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1","MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1":"MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2","MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2":"MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3","MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1":"MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0","MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2":"MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1","MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3":"MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2","MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0":"MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3","MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3":"MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4","MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4":"MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5","MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3":"MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0","MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5":"MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0","MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3":"MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0","MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1":"MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1","MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0":"MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0","MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1":"MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1","MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0":"MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0","MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0":"MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1","MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1":"MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0","MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0":"MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0","MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0":"MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1","MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2","MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0":"MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3","MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0":"MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4","MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0":"MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5","MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0":"MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6","MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1":"MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7","MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8","MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9":"MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2","MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0","MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1":"MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0","MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11":"MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10","MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10":"MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11","MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13":"MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12","MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12":"MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13","MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3":"MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2","MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2":"MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3","MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5":"MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4","MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4":"MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5","MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7":"MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6","MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6":"MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7","MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9":"MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8","MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8":"MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9","MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0":"MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0","MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3":"MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0","MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5":"MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0","MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7":"MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1","MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4":"MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2":"MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8":"MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2","MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0","MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6":"MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0","MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1":"MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1","MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3":"MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3","MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1":"MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1","MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0":"MAP_ROUTE122:0/MAP_MT_PYRE_1F:0","MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0":"MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1","MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0":"MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4","MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4":"MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5","MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4":"MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0","MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0":"MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1","MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4":"MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2","MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5":"MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3","MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5":"MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4","MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1":"MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0","MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1":"MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1","MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4":"MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2","MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5":"MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3","MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2":"MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4","MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3":"MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5","MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1":"MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0","MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1":"MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1","MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3":"MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2","MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4":"MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3","MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2":"MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4","MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3":"MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5","MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0":"MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0","MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0":"MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1","MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1":"MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2","MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2":"MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3","MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3":"MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4","MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0":"MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0","MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2":"MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1","MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1":"MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0","MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1":"MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1","MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1":"MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1","MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0":"MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0","MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1":"MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1","MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0":"MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0","MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2":"MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0","MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0":"MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1","MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1":"MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0","MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0":"MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1","MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1":"MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0","MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0":"MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1","MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1":"MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0","MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0":"MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1","MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1":"MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0","MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0":"MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1","MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1":"MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0","MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0":"MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1","MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1":"MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0","MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0":"MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1","MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1":"MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0","MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0":"MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1","MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1":"MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0","MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0":"MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1","MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1":"MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0","MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1":"MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1","MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0":"MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0","MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1":"MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1","MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0":"MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0","MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1":"MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1","MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0":"MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0","MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1":"MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1","MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0":"MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0","MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1":"MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1","MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0":"MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2","MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0":"MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0","MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1":"MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0","MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0":"MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0","MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0":"MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1","MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1":"MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0","MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0":"MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1","MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1":"MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0","MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0":"MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1","MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1":"MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0","MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0":"MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1","MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0":"MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0","MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0":"MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1","MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1":"MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0","MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0":"MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0","MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0":"MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1","MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2","MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0":"MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3","MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0":"MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0","MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1":"MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0","MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3":"MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2":"MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0","MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0":"MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1","MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0":"MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2","MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0":"MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3","MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0":"MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4","MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0":"MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5","MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1":"MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0","MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2":"MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0","MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3":"MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0","MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4":"MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0","MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5":"MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0":"MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0":"MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0","MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0":"MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1","MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0":"MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2","MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3","MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0":"MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4","MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0":"MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5","MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2":"MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0","MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8":"MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10","MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9":"MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12","MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16":"MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14","MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18":"MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15","MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14":"MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16","MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15":"MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18","MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3":"MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2","MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24":"MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20","MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26":"MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21","MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28":"MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22","MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30":"MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23","MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20":"MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24","MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21":"MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26","MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22":"MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28","MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2":"MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3","MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23":"MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30","MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34":"MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32","MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36":"MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33","MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32":"MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34","MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33":"MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36","MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6":"MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5","MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5":"MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6","MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10":"MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8","MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12":"MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9","MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0":"MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0","MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4":"MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0","MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5":"MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3":"MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1":"MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0","MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3":"MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1","MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5":"MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3","MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7":"MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5","MAP_RECORD_CORNER:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_ROUTE103:0/MAP_ALTERING_CAVE:0":"MAP_ALTERING_CAVE:0/MAP_ROUTE103:0","MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0":"MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0","MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0":"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1","MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1":"MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3","MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3":"MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5","MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5":"MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7","MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0":"MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0","MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1":"MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0","MAP_ROUTE105:0/MAP_ISLAND_CAVE:0":"MAP_ISLAND_CAVE:0/MAP_ROUTE105:0","MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0":"MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0","MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0":"MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0","MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0":"MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0","MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0":"MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0","MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0":"MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0","MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1","MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2","MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3","MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4","MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4":"MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5":"MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2":"MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3":"MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1":"MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:2,3/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0","MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0":"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1":"MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0":"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0","MAP_ROUTE111:1/MAP_DESERT_RUINS:0":"MAP_DESERT_RUINS:0/MAP_ROUTE111:1","MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0":"MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2","MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0":"MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3","MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0":"MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4","MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2":"MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0","MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0":"MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0","MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1":"MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1","MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1":"MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3","MAP_ROUTE112:4/MAP_FIERY_PATH:0":"MAP_FIERY_PATH:0/MAP_ROUTE112:4","MAP_ROUTE112:5/MAP_FIERY_PATH:1":"MAP_FIERY_PATH:1/MAP_ROUTE112:5","MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1":"MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1","MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0":"MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0","MAP_ROUTE113:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0":"MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0","MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0":"MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0","MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1","MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0":"MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2","MAP_ROUTE114:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1":"MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0":"MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2","MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2":"MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0","MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1":"MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0","MAP_ROUTE115:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE115:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0":"MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0","MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0":"MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1","MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2":"MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2","MAP_ROUTE116:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1":"MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0","MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0":"MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0","MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0":"MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0","MAP_ROUTE118:0/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE118:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0","MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0":"MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1","MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1":"MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0":"MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2","MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0","MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0":"MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0","MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0":"MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1","MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0":"MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0":"MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2","MAP_ROUTE122:0/MAP_MT_PYRE_1F:0":"MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0","MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0":"MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0","MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0":"MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0","MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0":"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0","MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0":"MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0","MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0","MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0":"MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0","MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0":"MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0","MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0":"MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1","MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0":"MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10","MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0":"MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11","MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0":"MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2","MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3","MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0":"MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4","MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6","MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0":"MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7","MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0":"MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8","MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0":"MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9","MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8":"MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0","MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6":"MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1","MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2","MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0","MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1","MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0","MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1":"MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0","MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0":"MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2","MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2":"MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0","MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10":"MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0","MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0":"MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2","MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2":"MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0","MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0":"MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1","MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1":"MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0","MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0":"MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0","MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7":"MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0","MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9":"MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0","MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11":"MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0","MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2":"MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3":"MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4":"MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0","MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0":"MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0","MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4":"MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1","MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2":"MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2","MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0":"MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0","MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0","MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0":"MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0","MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1":"MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:0/MAP_UNDERWATER_ROUTE128:0!":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0":"MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1","MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0":"MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1","MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0":"MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2","MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2":"MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0","MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0":"MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1","MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0":"MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2","MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0":"MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3","MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1":"MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0","MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1":"MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1","MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1":"MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2","MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1":"MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0","MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1":"MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1","MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2":"MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2","MAP_SEAFLOOR_CAVERN_ROOM4:3/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1":"MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0","MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1":"MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1","MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2":"MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2","MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2":"MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0","MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2":"MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1","MAP_SEAFLOOR_CAVERN_ROOM6:2/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3":"MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0","MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1":"MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1","MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0":"MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0","MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0":"MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1","MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0":"MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0","MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0":"MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0","MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0":"MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0","MAP_SECRET_BASE_BLUE_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0":"MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1","MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1":"MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0","MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0":"MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2","MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2":"MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0","MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0":"MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1","MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1":"MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0","MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0":"MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1","MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1":"MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2","MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1":"MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0","MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2":"MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1","MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0":"MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2","MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2":"MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0","MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0":"MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1","MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0":"MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0","MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0":"MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1","MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1":"MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0","MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0":"MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1","MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1":"MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0","MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0","MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0":"MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1","MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0":"MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10","MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2","MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0":"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3","MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0":"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4","MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7","MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0":"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6","MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0":"MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8","MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2":"MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9","MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3":"MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0","MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8":"MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0","MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9":"MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2","MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10":"MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0","MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1":"MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0","MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6":"MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7":"MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0":"MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4":"MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2":"MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0","MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0","MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0":"MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1","MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0":"MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10","MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0":"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11","MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12","MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0":"MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2","MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0":"MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3","MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0":"MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4","MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0":"MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5","MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0":"MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6","MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0":"MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7","MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0":"MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8","MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0":"MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9","MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2":"MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0","MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0":"MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2","MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2":"MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0","MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4":"MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0","MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5":"MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0","MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6":"MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0","MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7":"MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0","MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8":"MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0","MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9":"MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0","MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10":"MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0","MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11":"MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0","MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1":"MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12":"MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0":"MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1":"MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1","MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1":"MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1","MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0":"MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0","MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2":"MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1","MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4":"MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2","MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6":"MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3","MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8":"MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4","MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9":"MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5","MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10":"MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6","MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11":"MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7","MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0":"MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8","MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8":"MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0","MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0":"MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0","MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6":"MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10","MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7":"MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11","MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1":"MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2","MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2":"MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4","MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3":"MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6","MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4":"MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8","MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5":"MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9","MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1":"MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0","MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!":"","MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0":"MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1","MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!":"","MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2":"MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0","MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0":"MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1","MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1":"MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0","MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0":"MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1","MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1":"MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0","MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0":"MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1","MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1":"MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0","MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0":"MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1","MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1":"MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1","MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4":"MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0","MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0":"MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2","MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1":"MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0","MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1":"MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1","MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!":"","MAP_UNDERWATER_ROUTE105:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE105:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0":"MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0","MAP_UNDERWATER_ROUTE127:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE127:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0":"MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0","MAP_UNDERWATER_ROUTE129:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE129:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0":"MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0","MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0":"MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0","MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0":"MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0","MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!":"","MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0":"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0","MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0":"MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1","MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2","MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0":"MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3","MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1":"MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4","MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0":"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5","MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0":"MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6","MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0":"MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0","MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5":"MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0","MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6":"MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0","MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1":"MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2":"MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3":"MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0","MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2":"MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0","MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3":"MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1","MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5":"MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2","MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2":"MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3","MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4":"MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4","MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0":"MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0","MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2":"MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1","MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3":"MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2","MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1":"MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3","MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4":"MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4","MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2":"MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5","MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3":"MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6","MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0":"MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0","MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3":"MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1","MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1":"MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2","MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6":"MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3"}} +{"_comment":"DO NOT MODIFY. This file was auto-generated. Your changes will likely be overwritten.","_rom_name":"pokemon emerald version / AP 5","constants":{"ABILITIES_COUNT":78,"ABILITY_AIR_LOCK":77,"ABILITY_ARENA_TRAP":71,"ABILITY_BATTLE_ARMOR":4,"ABILITY_BLAZE":66,"ABILITY_CACOPHONY":76,"ABILITY_CHLOROPHYLL":34,"ABILITY_CLEAR_BODY":29,"ABILITY_CLOUD_NINE":13,"ABILITY_COLOR_CHANGE":16,"ABILITY_COMPOUND_EYES":14,"ABILITY_CUTE_CHARM":56,"ABILITY_DAMP":6,"ABILITY_DRIZZLE":2,"ABILITY_DROUGHT":70,"ABILITY_EARLY_BIRD":48,"ABILITY_EFFECT_SPORE":27,"ABILITY_FLAME_BODY":49,"ABILITY_FLASH_FIRE":18,"ABILITY_FORECAST":59,"ABILITY_GUTS":62,"ABILITY_HUGE_POWER":37,"ABILITY_HUSTLE":55,"ABILITY_HYPER_CUTTER":52,"ABILITY_ILLUMINATE":35,"ABILITY_IMMUNITY":17,"ABILITY_INNER_FOCUS":39,"ABILITY_INSOMNIA":15,"ABILITY_INTIMIDATE":22,"ABILITY_KEEN_EYE":51,"ABILITY_LEVITATE":26,"ABILITY_LIGHTNING_ROD":31,"ABILITY_LIMBER":7,"ABILITY_LIQUID_OOZE":64,"ABILITY_MAGMA_ARMOR":40,"ABILITY_MAGNET_PULL":42,"ABILITY_MARVEL_SCALE":63,"ABILITY_MINUS":58,"ABILITY_NATURAL_CURE":30,"ABILITY_NONE":0,"ABILITY_OBLIVIOUS":12,"ABILITY_OVERGROW":65,"ABILITY_OWN_TEMPO":20,"ABILITY_PICKUP":53,"ABILITY_PLUS":57,"ABILITY_POISON_POINT":38,"ABILITY_PRESSURE":46,"ABILITY_PURE_POWER":74,"ABILITY_RAIN_DISH":44,"ABILITY_ROCK_HEAD":69,"ABILITY_ROUGH_SKIN":24,"ABILITY_RUN_AWAY":50,"ABILITY_SAND_STREAM":45,"ABILITY_SAND_VEIL":8,"ABILITY_SERENE_GRACE":32,"ABILITY_SHADOW_TAG":23,"ABILITY_SHED_SKIN":61,"ABILITY_SHELL_ARMOR":75,"ABILITY_SHIELD_DUST":19,"ABILITY_SOUNDPROOF":43,"ABILITY_SPEED_BOOST":3,"ABILITY_STATIC":9,"ABILITY_STENCH":1,"ABILITY_STICKY_HOLD":60,"ABILITY_STURDY":5,"ABILITY_SUCTION_CUPS":21,"ABILITY_SWARM":68,"ABILITY_SWIFT_SWIM":33,"ABILITY_SYNCHRONIZE":28,"ABILITY_THICK_FAT":47,"ABILITY_TORRENT":67,"ABILITY_TRACE":36,"ABILITY_TRUANT":54,"ABILITY_VITAL_SPIRIT":72,"ABILITY_VOLT_ABSORB":10,"ABILITY_WATER_ABSORB":11,"ABILITY_WATER_VEIL":41,"ABILITY_WHITE_SMOKE":73,"ABILITY_WONDER_GUARD":25,"ACRO_BIKE":1,"BAG_ITEM_CAPACITY_DIGITS":2,"BERRY_CAPACITY_DIGITS":3,"BERRY_FIRMNESS_HARD":3,"BERRY_FIRMNESS_SOFT":2,"BERRY_FIRMNESS_SUPER_HARD":5,"BERRY_FIRMNESS_UNKNOWN":0,"BERRY_FIRMNESS_VERY_HARD":4,"BERRY_FIRMNESS_VERY_SOFT":1,"BERRY_NONE":0,"BERRY_STAGE_BERRIES":5,"BERRY_STAGE_FLOWERING":4,"BERRY_STAGE_NO_BERRY":0,"BERRY_STAGE_PLANTED":1,"BERRY_STAGE_SPARKLING":255,"BERRY_STAGE_SPROUTED":2,"BERRY_STAGE_TALLER":3,"BERRY_TREES_COUNT":128,"BERRY_TREE_ROUTE_102_ORAN":2,"BERRY_TREE_ROUTE_102_PECHA":1,"BERRY_TREE_ROUTE_103_CHERI_1":5,"BERRY_TREE_ROUTE_103_CHERI_2":7,"BERRY_TREE_ROUTE_103_LEPPA":6,"BERRY_TREE_ROUTE_104_CHERI_1":8,"BERRY_TREE_ROUTE_104_CHERI_2":76,"BERRY_TREE_ROUTE_104_LEPPA":10,"BERRY_TREE_ROUTE_104_ORAN_1":4,"BERRY_TREE_ROUTE_104_ORAN_2":11,"BERRY_TREE_ROUTE_104_PECHA":13,"BERRY_TREE_ROUTE_104_SOIL_1":3,"BERRY_TREE_ROUTE_104_SOIL_2":9,"BERRY_TREE_ROUTE_104_SOIL_3":12,"BERRY_TREE_ROUTE_104_SOIL_4":75,"BERRY_TREE_ROUTE_110_NANAB_1":16,"BERRY_TREE_ROUTE_110_NANAB_2":17,"BERRY_TREE_ROUTE_110_NANAB_3":18,"BERRY_TREE_ROUTE_111_ORAN_1":80,"BERRY_TREE_ROUTE_111_ORAN_2":81,"BERRY_TREE_ROUTE_111_RAZZ_1":19,"BERRY_TREE_ROUTE_111_RAZZ_2":20,"BERRY_TREE_ROUTE_112_PECHA_1":22,"BERRY_TREE_ROUTE_112_PECHA_2":23,"BERRY_TREE_ROUTE_112_RAWST_1":21,"BERRY_TREE_ROUTE_112_RAWST_2":24,"BERRY_TREE_ROUTE_114_PERSIM_1":68,"BERRY_TREE_ROUTE_114_PERSIM_2":77,"BERRY_TREE_ROUTE_114_PERSIM_3":78,"BERRY_TREE_ROUTE_115_BLUK_1":55,"BERRY_TREE_ROUTE_115_BLUK_2":56,"BERRY_TREE_ROUTE_115_KELPSY_1":69,"BERRY_TREE_ROUTE_115_KELPSY_2":70,"BERRY_TREE_ROUTE_115_KELPSY_3":71,"BERRY_TREE_ROUTE_116_CHESTO_1":26,"BERRY_TREE_ROUTE_116_CHESTO_2":66,"BERRY_TREE_ROUTE_116_PINAP_1":25,"BERRY_TREE_ROUTE_116_PINAP_2":67,"BERRY_TREE_ROUTE_117_WEPEAR_1":27,"BERRY_TREE_ROUTE_117_WEPEAR_2":28,"BERRY_TREE_ROUTE_117_WEPEAR_3":29,"BERRY_TREE_ROUTE_118_SITRUS_1":31,"BERRY_TREE_ROUTE_118_SITRUS_2":33,"BERRY_TREE_ROUTE_118_SOIL":32,"BERRY_TREE_ROUTE_119_HONDEW_1":83,"BERRY_TREE_ROUTE_119_HONDEW_2":84,"BERRY_TREE_ROUTE_119_LEPPA":86,"BERRY_TREE_ROUTE_119_POMEG_1":34,"BERRY_TREE_ROUTE_119_POMEG_2":35,"BERRY_TREE_ROUTE_119_POMEG_3":36,"BERRY_TREE_ROUTE_119_SITRUS":85,"BERRY_TREE_ROUTE_120_ASPEAR_1":37,"BERRY_TREE_ROUTE_120_ASPEAR_2":38,"BERRY_TREE_ROUTE_120_ASPEAR_3":39,"BERRY_TREE_ROUTE_120_NANAB":44,"BERRY_TREE_ROUTE_120_PECHA_1":40,"BERRY_TREE_ROUTE_120_PECHA_2":41,"BERRY_TREE_ROUTE_120_PECHA_3":42,"BERRY_TREE_ROUTE_120_PINAP":45,"BERRY_TREE_ROUTE_120_RAZZ":43,"BERRY_TREE_ROUTE_120_WEPEAR":46,"BERRY_TREE_ROUTE_121_ASPEAR":48,"BERRY_TREE_ROUTE_121_CHESTO":50,"BERRY_TREE_ROUTE_121_NANAB_1":52,"BERRY_TREE_ROUTE_121_NANAB_2":53,"BERRY_TREE_ROUTE_121_PERSIM":47,"BERRY_TREE_ROUTE_121_RAWST":49,"BERRY_TREE_ROUTE_121_SOIL_1":51,"BERRY_TREE_ROUTE_121_SOIL_2":54,"BERRY_TREE_ROUTE_123_GREPA_1":60,"BERRY_TREE_ROUTE_123_GREPA_2":61,"BERRY_TREE_ROUTE_123_GREPA_3":65,"BERRY_TREE_ROUTE_123_GREPA_4":72,"BERRY_TREE_ROUTE_123_LEPPA_1":62,"BERRY_TREE_ROUTE_123_LEPPA_2":64,"BERRY_TREE_ROUTE_123_PECHA":87,"BERRY_TREE_ROUTE_123_POMEG_1":15,"BERRY_TREE_ROUTE_123_POMEG_2":30,"BERRY_TREE_ROUTE_123_POMEG_3":58,"BERRY_TREE_ROUTE_123_POMEG_4":59,"BERRY_TREE_ROUTE_123_QUALOT_1":14,"BERRY_TREE_ROUTE_123_QUALOT_2":73,"BERRY_TREE_ROUTE_123_QUALOT_3":74,"BERRY_TREE_ROUTE_123_QUALOT_4":79,"BERRY_TREE_ROUTE_123_RAWST":57,"BERRY_TREE_ROUTE_123_SITRUS":88,"BERRY_TREE_ROUTE_123_SOIL":63,"BERRY_TREE_ROUTE_130_LIECHI":82,"DAILY_FLAGS_END":2399,"DAILY_FLAGS_START":2336,"FIRST_BALL":1,"FIRST_BERRY_INDEX":133,"FIRST_BERRY_MASTER_BERRY":153,"FIRST_BERRY_MASTER_WIFE_BERRY":133,"FIRST_KIRI_BERRY":153,"FIRST_MAIL_INDEX":121,"FIRST_ROUTE_114_MAN_BERRY":148,"FLAGS_COUNT":2400,"FLAG_ADDED_MATCH_CALL_TO_POKENAV":304,"FLAG_ADVENTURE_STARTED":116,"FLAG_ARRIVED_AT_MARINE_CAVE_EMERGE_SPOT":2265,"FLAG_ARRIVED_AT_NAVEL_ROCK":2273,"FLAG_ARRIVED_AT_TERRA_CAVE_ENTRANCE":2266,"FLAG_ARRIVED_ON_FARAWAY_ISLAND":2264,"FLAG_BADGE01_GET":2151,"FLAG_BADGE02_GET":2152,"FLAG_BADGE03_GET":2153,"FLAG_BADGE04_GET":2154,"FLAG_BADGE05_GET":2155,"FLAG_BADGE06_GET":2156,"FLAG_BADGE07_GET":2157,"FLAG_BADGE08_GET":2158,"FLAG_BATTLE_FRONTIER_TRADE_DONE":156,"FLAG_BEAT_MAGMA_GRUNT_JAGGED_PASS":313,"FLAG_BEAUTY_PAINTING_MADE":161,"FLAG_BERRY_MASTERS_WIFE":1197,"FLAG_BERRY_MASTER_RECEIVED_BERRY_1":1195,"FLAG_BERRY_MASTER_RECEIVED_BERRY_2":1196,"FLAG_BERRY_TREES_START":612,"FLAG_BERRY_TREE_01":612,"FLAG_BERRY_TREE_02":613,"FLAG_BERRY_TREE_03":614,"FLAG_BERRY_TREE_04":615,"FLAG_BERRY_TREE_05":616,"FLAG_BERRY_TREE_06":617,"FLAG_BERRY_TREE_07":618,"FLAG_BERRY_TREE_08":619,"FLAG_BERRY_TREE_09":620,"FLAG_BERRY_TREE_10":621,"FLAG_BERRY_TREE_11":622,"FLAG_BERRY_TREE_12":623,"FLAG_BERRY_TREE_13":624,"FLAG_BERRY_TREE_14":625,"FLAG_BERRY_TREE_15":626,"FLAG_BERRY_TREE_16":627,"FLAG_BERRY_TREE_17":628,"FLAG_BERRY_TREE_18":629,"FLAG_BERRY_TREE_19":630,"FLAG_BERRY_TREE_20":631,"FLAG_BERRY_TREE_21":632,"FLAG_BERRY_TREE_22":633,"FLAG_BERRY_TREE_23":634,"FLAG_BERRY_TREE_24":635,"FLAG_BERRY_TREE_25":636,"FLAG_BERRY_TREE_26":637,"FLAG_BERRY_TREE_27":638,"FLAG_BERRY_TREE_28":639,"FLAG_BERRY_TREE_29":640,"FLAG_BERRY_TREE_30":641,"FLAG_BERRY_TREE_31":642,"FLAG_BERRY_TREE_32":643,"FLAG_BERRY_TREE_33":644,"FLAG_BERRY_TREE_34":645,"FLAG_BERRY_TREE_35":646,"FLAG_BERRY_TREE_36":647,"FLAG_BERRY_TREE_37":648,"FLAG_BERRY_TREE_38":649,"FLAG_BERRY_TREE_39":650,"FLAG_BERRY_TREE_40":651,"FLAG_BERRY_TREE_41":652,"FLAG_BERRY_TREE_42":653,"FLAG_BERRY_TREE_43":654,"FLAG_BERRY_TREE_44":655,"FLAG_BERRY_TREE_45":656,"FLAG_BERRY_TREE_46":657,"FLAG_BERRY_TREE_47":658,"FLAG_BERRY_TREE_48":659,"FLAG_BERRY_TREE_49":660,"FLAG_BERRY_TREE_50":661,"FLAG_BERRY_TREE_51":662,"FLAG_BERRY_TREE_52":663,"FLAG_BERRY_TREE_53":664,"FLAG_BERRY_TREE_54":665,"FLAG_BERRY_TREE_55":666,"FLAG_BERRY_TREE_56":667,"FLAG_BERRY_TREE_57":668,"FLAG_BERRY_TREE_58":669,"FLAG_BERRY_TREE_59":670,"FLAG_BERRY_TREE_60":671,"FLAG_BERRY_TREE_61":672,"FLAG_BERRY_TREE_62":673,"FLAG_BERRY_TREE_63":674,"FLAG_BERRY_TREE_64":675,"FLAG_BERRY_TREE_65":676,"FLAG_BERRY_TREE_66":677,"FLAG_BERRY_TREE_67":678,"FLAG_BERRY_TREE_68":679,"FLAG_BERRY_TREE_69":680,"FLAG_BERRY_TREE_70":681,"FLAG_BERRY_TREE_71":682,"FLAG_BERRY_TREE_72":683,"FLAG_BERRY_TREE_73":684,"FLAG_BERRY_TREE_74":685,"FLAG_BERRY_TREE_75":686,"FLAG_BERRY_TREE_76":687,"FLAG_BERRY_TREE_77":688,"FLAG_BERRY_TREE_78":689,"FLAG_BERRY_TREE_79":690,"FLAG_BERRY_TREE_80":691,"FLAG_BERRY_TREE_81":692,"FLAG_BERRY_TREE_82":693,"FLAG_BERRY_TREE_83":694,"FLAG_BERRY_TREE_84":695,"FLAG_BERRY_TREE_85":696,"FLAG_BERRY_TREE_86":697,"FLAG_BERRY_TREE_87":698,"FLAG_BERRY_TREE_88":699,"FLAG_BETTER_SHOPS_ENABLED":206,"FLAG_BIRCH_AIDE_MET":88,"FLAG_CANCEL_BATTLE_ROOM_CHALLENGE":119,"FLAG_CAUGHT_DEOXYS":429,"FLAG_CAUGHT_GROUDON":480,"FLAG_CAUGHT_HO_OH":146,"FLAG_CAUGHT_KYOGRE":479,"FLAG_CAUGHT_LATIAS":457,"FLAG_CAUGHT_LATIOS":482,"FLAG_CAUGHT_LUGIA":145,"FLAG_CAUGHT_MEW":458,"FLAG_CAUGHT_RAYQUAZA":478,"FLAG_CAUGHT_REGICE":427,"FLAG_CAUGHT_REGIROCK":426,"FLAG_CAUGHT_REGISTEEL":483,"FLAG_CHOSEN_MULTI_BATTLE_NPC_PARTNER":338,"FLAG_CHOSE_CLAW_FOSSIL":336,"FLAG_CHOSE_ROOT_FOSSIL":335,"FLAG_COLLECTED_ALL_GOLD_SYMBOLS":466,"FLAG_COLLECTED_ALL_SILVER_SYMBOLS":92,"FLAG_CONTEST_SKETCH_CREATED":270,"FLAG_COOL_PAINTING_MADE":160,"FLAG_CUTE_PAINTING_MADE":162,"FLAG_DAILY_APPRENTICE_LEAVES":2356,"FLAG_DAILY_BERRY_MASTERS_WIFE":2353,"FLAG_DAILY_BERRY_MASTER_RECEIVED_BERRY":2349,"FLAG_DAILY_CONTEST_LOBBY_RECEIVED_BERRY":2337,"FLAG_DAILY_FLOWER_SHOP_RECEIVED_BERRY":2352,"FLAG_DAILY_LILYCOVE_RECEIVED_BERRY":2351,"FLAG_DAILY_PICKED_LOTO_TICKET":2346,"FLAG_DAILY_ROUTE_111_RECEIVED_BERRY":2348,"FLAG_DAILY_ROUTE_114_RECEIVED_BERRY":2347,"FLAG_DAILY_ROUTE_120_RECEIVED_BERRY":2350,"FLAG_DAILY_SECRET_BASE":2338,"FLAG_DAILY_SOOTOPOLIS_RECEIVED_BERRY":2354,"FLAG_DECLINED_BIKE":89,"FLAG_DECLINED_RIVAL_BATTLE_LILYCOVE":286,"FLAG_DECLINED_WALLY_BATTLE_MAUVILLE":284,"FLAG_DECORATION_1":174,"FLAG_DECORATION_10":183,"FLAG_DECORATION_11":184,"FLAG_DECORATION_12":185,"FLAG_DECORATION_13":186,"FLAG_DECORATION_14":187,"FLAG_DECORATION_2":175,"FLAG_DECORATION_3":176,"FLAG_DECORATION_4":177,"FLAG_DECORATION_5":178,"FLAG_DECORATION_6":179,"FLAG_DECORATION_7":180,"FLAG_DECORATION_8":181,"FLAG_DECORATION_9":182,"FLAG_DEFEATED_DEOXYS":428,"FLAG_DEFEATED_DEWFORD_GYM":1265,"FLAG_DEFEATED_ELECTRODE_1_AQUA_HIDEOUT":452,"FLAG_DEFEATED_ELECTRODE_2_AQUA_HIDEOUT":453,"FLAG_DEFEATED_ELITE_4_DRAKE":1278,"FLAG_DEFEATED_ELITE_4_GLACIA":1277,"FLAG_DEFEATED_ELITE_4_PHOEBE":1276,"FLAG_DEFEATED_ELITE_4_SIDNEY":1275,"FLAG_DEFEATED_EVIL_TEAM_MT_CHIMNEY":139,"FLAG_DEFEATED_FORTREE_GYM":1269,"FLAG_DEFEATED_GROUDON":447,"FLAG_DEFEATED_GRUNT_SPACE_CENTER_1F":191,"FLAG_DEFEATED_HO_OH":476,"FLAG_DEFEATED_KECLEON_1_ROUTE_119":989,"FLAG_DEFEATED_KECLEON_1_ROUTE_120":982,"FLAG_DEFEATED_KECLEON_2_ROUTE_119":990,"FLAG_DEFEATED_KECLEON_2_ROUTE_120":985,"FLAG_DEFEATED_KECLEON_3_ROUTE_120":986,"FLAG_DEFEATED_KECLEON_4_ROUTE_120":987,"FLAG_DEFEATED_KECLEON_5_ROUTE_120":988,"FLAG_DEFEATED_KEKLEON_ROUTE_120_BRIDGE":970,"FLAG_DEFEATED_KYOGRE":446,"FLAG_DEFEATED_LATIAS":456,"FLAG_DEFEATED_LATIOS":481,"FLAG_DEFEATED_LAVARIDGE_GYM":1267,"FLAG_DEFEATED_LUGIA":477,"FLAG_DEFEATED_MAGMA_SPACE_CENTER":117,"FLAG_DEFEATED_MAUVILLE_GYM":1266,"FLAG_DEFEATED_METEOR_FALLS_STEVEN":1272,"FLAG_DEFEATED_MEW":455,"FLAG_DEFEATED_MOSSDEEP_GYM":1270,"FLAG_DEFEATED_PETALBURG_GYM":1268,"FLAG_DEFEATED_RAYQUAZA":448,"FLAG_DEFEATED_REGICE":444,"FLAG_DEFEATED_REGIROCK":443,"FLAG_DEFEATED_REGISTEEL":445,"FLAG_DEFEATED_RIVAL_ROUTE103":130,"FLAG_DEFEATED_RIVAL_ROUTE_104":125,"FLAG_DEFEATED_RIVAL_RUSTBORO":211,"FLAG_DEFEATED_RUSTBORO_GYM":1264,"FLAG_DEFEATED_SEASHORE_HOUSE":141,"FLAG_DEFEATED_SOOTOPOLIS_GYM":1271,"FLAG_DEFEATED_SS_TIDAL_TRAINERS":247,"FLAG_DEFEATED_SUDOWOODO":454,"FLAG_DEFEATED_VOLTORB_1_NEW_MAUVILLE":449,"FLAG_DEFEATED_VOLTORB_2_NEW_MAUVILLE":450,"FLAG_DEFEATED_VOLTORB_3_NEW_MAUVILLE":451,"FLAG_DEFEATED_WALLY_MAUVILLE":190,"FLAG_DEFEATED_WALLY_VICTORY_ROAD":126,"FLAG_DELIVERED_DEVON_GOODS":149,"FLAG_DELIVERED_STEVEN_LETTER":189,"FLAG_DEOXYS_IS_RECOVERING":1258,"FLAG_DEOXYS_ROCK_COMPLETE":2260,"FLAG_DEVON_GOODS_STOLEN":142,"FLAG_DOCK_REJECTED_DEVON_GOODS":148,"FLAG_DONT_TRANSITION_MUSIC":16385,"FLAG_ENABLE_BRAWLY_MATCH_CALL":468,"FLAG_ENABLE_FIRST_WALLY_POKENAV_CALL":136,"FLAG_ENABLE_FLANNERY_MATCH_CALL":470,"FLAG_ENABLE_JUAN_MATCH_CALL":473,"FLAG_ENABLE_MOM_MATCH_CALL":216,"FLAG_ENABLE_MR_STONE_POKENAV":344,"FLAG_ENABLE_MULTI_CORRIDOR_DOOR":16386,"FLAG_ENABLE_NORMAN_MATCH_CALL":306,"FLAG_ENABLE_PROF_BIRCH_MATCH_CALL":281,"FLAG_ENABLE_RIVAL_MATCH_CALL":253,"FLAG_ENABLE_ROXANNE_FIRST_CALL":128,"FLAG_ENABLE_ROXANNE_MATCH_CALL":467,"FLAG_ENABLE_SCOTT_MATCH_CALL":215,"FLAG_ENABLE_SHIP_BIRTH_ISLAND":2261,"FLAG_ENABLE_SHIP_FARAWAY_ISLAND":2262,"FLAG_ENABLE_SHIP_NAVEL_ROCK":2272,"FLAG_ENABLE_SHIP_SOUTHERN_ISLAND":2227,"FLAG_ENABLE_TATE_AND_LIZA_MATCH_CALL":472,"FLAG_ENABLE_WALLY_MATCH_CALL":214,"FLAG_ENABLE_WATTSON_MATCH_CALL":469,"FLAG_ENABLE_WINONA_MATCH_CALL":471,"FLAG_ENTERED_CONTEST":341,"FLAG_ENTERED_ELITE_FOUR":263,"FLAG_ENTERED_MIRAGE_TOWER":2268,"FLAG_EVIL_LEADER_PLEASE_STOP":219,"FLAG_EVIL_TEAM_ESCAPED_STERN_SPOKE":271,"FLAG_EXCHANGED_SCANNER":294,"FLAG_FAN_CLUB_STRENGTH_SHARED":210,"FLAG_FLOWER_SHOP_RECEIVED_BERRY":1207,"FLAG_FORCE_MIRAGE_TOWER_VISIBLE":157,"FLAG_FORTREE_NPC_TRADE_COMPLETED":155,"FLAG_GOOD_LUCK_SAFARI_ZONE":93,"FLAG_GOT_BASEMENT_KEY_FROM_WATTSON":208,"FLAG_GOT_TM_THUNDERBOLT_FROM_WATTSON":209,"FLAG_GROUDON_AWAKENED_MAGMA_HIDEOUT":111,"FLAG_GROUDON_IS_RECOVERING":1274,"FLAG_HAS_MATCH_CALL":303,"FLAG_HIDDEN_ITEMS_START":500,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":531,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":532,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":533,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":534,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":601,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":604,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":603,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":602,"FLAG_HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":528,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":548,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":549,"FLAG_HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":577,"FLAG_HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":576,"FLAG_HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":500,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":527,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":575,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":543,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":578,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":529,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":580,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":579,"FLAG_HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":609,"FLAG_HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":595,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":561,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POTION":558,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":559,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":560,"FLAG_HIDDEN_ITEM_ROUTE_104_ANTIDOTE":585,"FLAG_HIDDEN_ITEM_ROUTE_104_HEART_SCALE":588,"FLAG_HIDDEN_ITEM_ROUTE_104_POKE_BALL":562,"FLAG_HIDDEN_ITEM_ROUTE_104_POTION":537,"FLAG_HIDDEN_ITEM_ROUTE_104_SUPER_POTION":544,"FLAG_HIDDEN_ITEM_ROUTE_105_BIG_PEARL":611,"FLAG_HIDDEN_ITEM_ROUTE_105_HEART_SCALE":589,"FLAG_HIDDEN_ITEM_ROUTE_106_HEART_SCALE":547,"FLAG_HIDDEN_ITEM_ROUTE_106_POKE_BALL":563,"FLAG_HIDDEN_ITEM_ROUTE_106_STARDUST":546,"FLAG_HIDDEN_ITEM_ROUTE_108_RARE_CANDY":586,"FLAG_HIDDEN_ITEM_ROUTE_109_ETHER":564,"FLAG_HIDDEN_ITEM_ROUTE_109_GREAT_BALL":551,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":552,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":590,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":591,"FLAG_HIDDEN_ITEM_ROUTE_109_REVIVE":550,"FLAG_HIDDEN_ITEM_ROUTE_110_FULL_HEAL":555,"FLAG_HIDDEN_ITEM_ROUTE_110_GREAT_BALL":553,"FLAG_HIDDEN_ITEM_ROUTE_110_POKE_BALL":565,"FLAG_HIDDEN_ITEM_ROUTE_110_REVIVE":554,"FLAG_HIDDEN_ITEM_ROUTE_111_PROTEIN":556,"FLAG_HIDDEN_ITEM_ROUTE_111_RARE_CANDY":557,"FLAG_HIDDEN_ITEM_ROUTE_111_STARDUST":502,"FLAG_HIDDEN_ITEM_ROUTE_113_ETHER":503,"FLAG_HIDDEN_ITEM_ROUTE_113_NUGGET":598,"FLAG_HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":530,"FLAG_HIDDEN_ITEM_ROUTE_114_CARBOS":504,"FLAG_HIDDEN_ITEM_ROUTE_114_REVIVE":542,"FLAG_HIDDEN_ITEM_ROUTE_115_HEART_SCALE":597,"FLAG_HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":596,"FLAG_HIDDEN_ITEM_ROUTE_116_SUPER_POTION":545,"FLAG_HIDDEN_ITEM_ROUTE_117_REPEL":572,"FLAG_HIDDEN_ITEM_ROUTE_118_HEART_SCALE":566,"FLAG_HIDDEN_ITEM_ROUTE_118_IRON":567,"FLAG_HIDDEN_ITEM_ROUTE_119_CALCIUM":505,"FLAG_HIDDEN_ITEM_ROUTE_119_FULL_HEAL":568,"FLAG_HIDDEN_ITEM_ROUTE_119_MAX_ETHER":587,"FLAG_HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":506,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":571,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":569,"FLAG_HIDDEN_ITEM_ROUTE_120_REVIVE":584,"FLAG_HIDDEN_ITEM_ROUTE_120_ZINC":570,"FLAG_HIDDEN_ITEM_ROUTE_121_FULL_HEAL":573,"FLAG_HIDDEN_ITEM_ROUTE_121_HP_UP":539,"FLAG_HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":600,"FLAG_HIDDEN_ITEM_ROUTE_121_NUGGET":540,"FLAG_HIDDEN_ITEM_ROUTE_123_HYPER_POTION":574,"FLAG_HIDDEN_ITEM_ROUTE_123_PP_UP":599,"FLAG_HIDDEN_ITEM_ROUTE_123_RARE_CANDY":610,"FLAG_HIDDEN_ITEM_ROUTE_123_REVIVE":541,"FLAG_HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":507,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":592,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":593,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":594,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":606,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":607,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":605,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":608,"FLAG_HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":535,"FLAG_HIDDEN_ITEM_TRICK_HOUSE_NUGGET":501,"FLAG_HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":511,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CALCIUM":536,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CARBOS":508,"FLAG_HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":509,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":513,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":538,"FLAG_HIDDEN_ITEM_UNDERWATER_124_PEARL":510,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":520,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":512,"FLAG_HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":514,"FLAG_HIDDEN_ITEM_UNDERWATER_126_IRON":519,"FLAG_HIDDEN_ITEM_UNDERWATER_126_PEARL":517,"FLAG_HIDDEN_ITEM_UNDERWATER_126_STARDUST":516,"FLAG_HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":515,"FLAG_HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":518,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":523,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HP_UP":522,"FLAG_HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":524,"FLAG_HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":521,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PEARL":526,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PROTEIN":525,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":581,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":582,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":583,"FLAG_HIDE_APPRENTICE":701,"FLAG_HIDE_AQUA_HIDEOUT_1F_GRUNTS_BLOCKING_ENTRANCE":821,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_1":977,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_2":978,"FLAG_HIDE_AQUA_HIDEOUT_B2F_SUBMARINE_SHADOW":943,"FLAG_HIDE_AQUA_HIDEOUT_GRUNTS":924,"FLAG_HIDE_BATTLE_FRONTIER_RECEPTION_GATE_SCOTT":836,"FLAG_HIDE_BATTLE_FRONTIER_SUDOWOODO":842,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_1":711,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_2":712,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_3":713,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_4":714,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_5":715,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_6":716,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_1":864,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_2":865,"FLAG_HIDE_BATTLE_TOWER_OPPONENT":888,"FLAG_HIDE_BATTLE_TOWER_REPORTER":918,"FLAG_HIDE_BIRTH_ISLAND_DEOXYS_TRIANGLE":764,"FLAG_HIDE_BRINEYS_HOUSE_MR_BRINEY":739,"FLAG_HIDE_BRINEYS_HOUSE_PEEKO":881,"FLAG_HIDE_CAVE_OF_ORIGIN_B1F_WALLACE":820,"FLAG_HIDE_CHAMPIONS_ROOM_BIRCH":921,"FLAG_HIDE_CHAMPIONS_ROOM_RIVAL":920,"FLAG_HIDE_CONTEST_POKE_BALL":86,"FLAG_HIDE_DEOXYS":763,"FLAG_HIDE_DESERT_UNDERPASS_FOSSIL":874,"FLAG_HIDE_DEWFORD_HALL_SLUDGE_BOMB_MAN":940,"FLAG_HIDE_EVER_GRANDE_POKEMON_CENTER_1F_SCOTT":793,"FLAG_HIDE_FALLARBOR_AZURILL":907,"FLAG_HIDE_FALLARBOR_HOUSE_PROF_COZMO":928,"FLAG_HIDE_FALLARBOR_TOWN_BATTLE_TENT_SCOTT":767,"FLAG_HIDE_FALLORBOR_POKEMON_CENTER_LANETTE":871,"FLAG_HIDE_FANCLUB_BOY":790,"FLAG_HIDE_FANCLUB_LADY":792,"FLAG_HIDE_FANCLUB_LITTLE_BOY":791,"FLAG_HIDE_FANCLUB_OLD_LADY":789,"FLAG_HIDE_FORTREE_CITY_HOUSE_4_WINGULL":933,"FLAG_HIDE_FORTREE_CITY_KECLEON":969,"FLAG_HIDE_GRANITE_CAVE_STEVEN":833,"FLAG_HIDE_HO_OH":801,"FLAG_HIDE_JAGGED_PASS_MAGMA_GUARD":847,"FLAG_HIDE_LANETTES_HOUSE_LANETTE":870,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL":929,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL_ON_BIKE":930,"FLAG_HIDE_LILYCOVE_CITY_AQUA_GRUNTS":852,"FLAG_HIDE_LILYCOVE_CITY_RIVAL":971,"FLAG_HIDE_LILYCOVE_CITY_WAILMER":729,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER":832,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER_REPLACEMENT":873,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_1":774,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_2":895,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_REPORTER":802,"FLAG_HIDE_LILYCOVE_DEPARTMENT_STORE_ROOFTOP_SALE_WOMAN":962,"FLAG_HIDE_LILYCOVE_FAN_CLUB_INTERVIEWER":730,"FLAG_HIDE_LILYCOVE_HARBOR_EVENT_TICKET_TAKER":748,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_ATTENDANT":908,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_SAILOR":909,"FLAG_HIDE_LILYCOVE_HARBOR_SSTIDAL":861,"FLAG_HIDE_LILYCOVE_MOTEL_GAME_DESIGNERS":925,"FLAG_HIDE_LILYCOVE_MOTEL_SCOTT":787,"FLAG_HIDE_LILYCOVE_MUSEUM_CURATOR":775,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_1":776,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_2":777,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_3":778,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_4":779,"FLAG_HIDE_LILYCOVE_MUSEUM_TOURISTS":780,"FLAG_HIDE_LILYCOVE_POKEMON_CENTER_CONTEST_LADY_MON":993,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCH":795,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_BIRCH":721,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CHIKORITA":838,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CYNDAQUIL":811,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_TOTODILE":812,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_RIVAL":889,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_UNKNOWN_0x380":896,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_POKE_BALL":817,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_SWABLU_DOLL":815,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_BRENDAN":745,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_MOM":758,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_BEDROOM":760,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_MOM":784,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_SIBLING":735,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_TRUCK":761,"FLAG_HIDE_LITTLEROOT_TOWN_FAT_MAN":868,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_PICHU_DOLL":849,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_POKE_BALL":818,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MAY":746,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MOM":759,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_BEDROOM":722,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_MOM":785,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_SIBLING":736,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_TRUCK":762,"FLAG_HIDE_LITTLEROOT_TOWN_MOM_OUTSIDE":752,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_BEDROOM_MOM":757,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_1":754,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_2":755,"FLAG_HIDE_LITTLEROOT_TOWN_RIVAL":794,"FLAG_HIDE_LUGIA":800,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON":853,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON_ASLEEP":850,"FLAG_HIDE_MAGMA_HIDEOUT_GRUNTS":857,"FLAG_HIDE_MAGMA_HIDEOUT_MAXIE":867,"FLAG_HIDE_MAP_NAME_POPUP":16384,"FLAG_HIDE_MARINE_CAVE_KYOGRE":782,"FLAG_HIDE_MAUVILLE_CITY_SCOTT":765,"FLAG_HIDE_MAUVILLE_CITY_WALLY":804,"FLAG_HIDE_MAUVILLE_CITY_WALLYS_UNCLE":805,"FLAG_HIDE_MAUVILLE_CITY_WATTSON":912,"FLAG_HIDE_MAUVILLE_GYM_WATTSON":913,"FLAG_HIDE_METEOR_FALLS_1F_1R_COZMO":942,"FLAG_HIDE_METEOR_FALLS_TEAM_AQUA":938,"FLAG_HIDE_METEOR_FALLS_TEAM_MAGMA":939,"FLAG_HIDE_MEW":718,"FLAG_HIDE_MIRAGE_TOWER_CLAW_FOSSIL":964,"FLAG_HIDE_MIRAGE_TOWER_ROOT_FOSSIL":963,"FLAG_HIDE_MOSSDEEP_CITY_HOUSE_2_WINGULL":934,"FLAG_HIDE_MOSSDEEP_CITY_SCOTT":788,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_STEVEN":753,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_TEAM_MAGMA":756,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_STEVEN":863,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_TEAM_MAGMA":862,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_MAGMA_NOTE":737,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_BELDUM_POKEBALL":968,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_INVISIBLE_NINJA_BOY":727,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_STEVEN":967,"FLAG_HIDE_MOSSDEEP_CITY_TEAM_MAGMA":823,"FLAG_HIDE_MR_BRINEY_BOAT_DEWFORD_TOWN":743,"FLAG_HIDE_MR_BRINEY_DEWFORD_TOWN":740,"FLAG_HIDE_MT_CHIMNEY_LAVA_COOKIE_LADY":994,"FLAG_HIDE_MT_CHIMNEY_TEAM_AQUA":926,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA":927,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA_BATTLEABLE":981,"FLAG_HIDE_MT_CHIMNEY_TRAINERS":877,"FLAG_HIDE_MT_PYRE_SUMMIT_ARCHIE":916,"FLAG_HIDE_MT_PYRE_SUMMIT_MAXIE":856,"FLAG_HIDE_MT_PYRE_SUMMIT_TEAM_AQUA":917,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_1":974,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_2":975,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_3":976,"FLAG_HIDE_OLDALE_TOWN_RIVAL":979,"FLAG_HIDE_PETALBURG_CITY_SCOTT":995,"FLAG_HIDE_PETALBURG_CITY_WALLY":726,"FLAG_HIDE_PETALBURG_CITY_WALLYS_DAD":830,"FLAG_HIDE_PETALBURG_CITY_WALLYS_MOM":728,"FLAG_HIDE_PETALBURG_GYM_GREETER":781,"FLAG_HIDE_PETALBURG_GYM_NORMAN":772,"FLAG_HIDE_PETALBURG_GYM_WALLY":866,"FLAG_HIDE_PETALBURG_GYM_WALLYS_DAD":824,"FLAG_HIDE_PETALBURG_WOODS_AQUA_GRUNT":725,"FLAG_HIDE_PETALBURG_WOODS_DEVON_EMPLOYEE":724,"FLAG_HIDE_PLAYERS_HOUSE_DAD":734,"FLAG_HIDE_POKEMON_CENTER_2F_MYSTERY_GIFT_MAN":702,"FLAG_HIDE_REGICE":936,"FLAG_HIDE_REGIROCK":935,"FLAG_HIDE_REGISTEEL":937,"FLAG_HIDE_ROUTE_101_BIRCH":897,"FLAG_HIDE_ROUTE_101_BIRCH_STARTERS_BAG":700,"FLAG_HIDE_ROUTE_101_BIRCH_ZIGZAGOON_BATTLE":720,"FLAG_HIDE_ROUTE_101_BOY":991,"FLAG_HIDE_ROUTE_101_ZIGZAGOON":750,"FLAG_HIDE_ROUTE_103_BIRCH":898,"FLAG_HIDE_ROUTE_103_RIVAL":723,"FLAG_HIDE_ROUTE_104_MR_BRINEY":738,"FLAG_HIDE_ROUTE_104_MR_BRINEY_BOAT":742,"FLAG_HIDE_ROUTE_104_RIVAL":719,"FLAG_HIDE_ROUTE_104_WHITE_HERB_FLORIST":906,"FLAG_HIDE_ROUTE_109_MR_BRINEY":741,"FLAG_HIDE_ROUTE_109_MR_BRINEY_BOAT":744,"FLAG_HIDE_ROUTE_110_BIRCH":837,"FLAG_HIDE_ROUTE_110_RIVAL":919,"FLAG_HIDE_ROUTE_110_RIVAL_ON_BIKE":922,"FLAG_HIDE_ROUTE_110_TEAM_AQUA":900,"FLAG_HIDE_ROUTE_111_DESERT_FOSSIL":876,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_1":796,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_2":903,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_3":799,"FLAG_HIDE_ROUTE_111_PLAYER_DESCENT":875,"FLAG_HIDE_ROUTE_111_ROCK_SMASH_TIP_GUY":843,"FLAG_HIDE_ROUTE_111_SECRET_POWER_MAN":960,"FLAG_HIDE_ROUTE_111_VICKY_WINSTRATE":771,"FLAG_HIDE_ROUTE_111_VICTORIA_WINSTRATE":769,"FLAG_HIDE_ROUTE_111_VICTOR_WINSTRATE":768,"FLAG_HIDE_ROUTE_111_VIVI_WINSTRATE":770,"FLAG_HIDE_ROUTE_112_TEAM_MAGMA":819,"FLAG_HIDE_ROUTE_115_BOULDERS":825,"FLAG_HIDE_ROUTE_116_DEVON_EMPLOYEE":947,"FLAG_HIDE_ROUTE_116_DROPPED_GLASSES_MAN":813,"FLAG_HIDE_ROUTE_116_MR_BRINEY":891,"FLAG_HIDE_ROUTE_116_WANDAS_BOYFRIEND":894,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_1":797,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_2":901,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_3":904,"FLAG_HIDE_ROUTE_118_STEVEN":966,"FLAG_HIDE_ROUTE_119_RIVAL":851,"FLAG_HIDE_ROUTE_119_RIVAL_ON_BIKE":923,"FLAG_HIDE_ROUTE_119_SCOTT":786,"FLAG_HIDE_ROUTE_119_TEAM_AQUA":890,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_BRIDGE":822,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_SHELLY":915,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_1":798,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_2":902,"FLAG_HIDE_ROUTE_120_STEVEN":972,"FLAG_HIDE_ROUTE_121_TEAM_AQUA_GRUNTS":914,"FLAG_HIDE_ROUTE_128_ARCHIE":944,"FLAG_HIDE_ROUTE_128_MAXIE":945,"FLAG_HIDE_ROUTE_128_STEVEN":834,"FLAG_HIDE_RUSTBORO_CITY_AQUA_GRUNT":731,"FLAG_HIDE_RUSTBORO_CITY_DEVON_CORP_3F_EMPLOYEE":949,"FLAG_HIDE_RUSTBORO_CITY_DEVON_EMPLOYEE_1":732,"FLAG_HIDE_RUSTBORO_CITY_POKEMON_SCHOOL_SCOTT":999,"FLAG_HIDE_RUSTBORO_CITY_RIVAL":814,"FLAG_HIDE_RUSTBORO_CITY_SCIENTIST":844,"FLAG_HIDE_RUSTURF_TUNNEL_AQUA_GRUNT":878,"FLAG_HIDE_RUSTURF_TUNNEL_BRINEY":879,"FLAG_HIDE_RUSTURF_TUNNEL_PEEKO":880,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_1":931,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_2":932,"FLAG_HIDE_RUSTURF_TUNNEL_WANDA":983,"FLAG_HIDE_RUSTURF_TUNNEL_WANDAS_BOYFRIEND":807,"FLAG_HIDE_SAFARI_ZONE_SOUTH_CONSTRUCTION_WORKERS":717,"FLAG_HIDE_SAFARI_ZONE_SOUTH_EAST_EXPANSION":747,"FLAG_HIDE_SEAFLOOR_CAVERN_AQUA_GRUNTS":946,"FLAG_HIDE_SEAFLOOR_CAVERN_ENTRANCE_AQUA_GRUNT":941,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_ARCHIE":828,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE":859,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE_ASLEEP":733,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAGMA_GRUNTS":831,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAXIE":829,"FLAG_HIDE_SECRET_BASE_TRAINER":173,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA":773,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA_STILL":80,"FLAG_HIDE_SKY_PILLAR_WALLACE":855,"FLAG_HIDE_SLATEPORT_CITY_CAPTAIN_STERN":840,"FLAG_HIDE_SLATEPORT_CITY_CONTEST_REPORTER":803,"FLAG_HIDE_SLATEPORT_CITY_GABBY_AND_TY":835,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_AQUA_GRUNT":845,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_ARCHIE":846,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_CAPTAIN_STERN":841,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_PATRONS":905,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SS_TIDAL":860,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SUBMARINE_SHADOW":848,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_1":884,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_2":885,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_ARCHIE":886,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_CAPTAIN_STERN":887,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_AQUA_GRUNTS":883,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_FAMILIAR_AQUA_GRUNT":965,"FLAG_HIDE_SLATEPORT_CITY_SCOTT":749,"FLAG_HIDE_SLATEPORT_CITY_STERNS_SHIPYARD_MR_BRINEY":869,"FLAG_HIDE_SLATEPORT_CITY_TEAM_AQUA":882,"FLAG_HIDE_SLATEPORT_CITY_TM_SALESMAN":948,"FLAG_HIDE_SLATEPORT_MUSEUM_POPULATION":961,"FLAG_HIDE_SOOTOPOLIS_CITY_ARCHIE":826,"FLAG_HIDE_SOOTOPOLIS_CITY_GROUDON":998,"FLAG_HIDE_SOOTOPOLIS_CITY_KYOGRE":997,"FLAG_HIDE_SOOTOPOLIS_CITY_MAN_1":839,"FLAG_HIDE_SOOTOPOLIS_CITY_MAXIE":827,"FLAG_HIDE_SOOTOPOLIS_CITY_RAYQUAZA":996,"FLAG_HIDE_SOOTOPOLIS_CITY_RESIDENTS":854,"FLAG_HIDE_SOOTOPOLIS_CITY_STEVEN":973,"FLAG_HIDE_SOOTOPOLIS_CITY_WALLACE":816,"FLAG_HIDE_SOUTHERN_ISLAND_EON_STONE":910,"FLAG_HIDE_SOUTHERN_ISLAND_UNCHOSEN_EON_DUO_MON":911,"FLAG_HIDE_SS_TIDAL_CORRIDOR_MR_BRINEY":950,"FLAG_HIDE_SS_TIDAL_CORRIDOR_SCOTT":810,"FLAG_HIDE_SS_TIDAL_ROOMS_SNATCH_GIVER":951,"FLAG_HIDE_TERRA_CAVE_GROUDON":783,"FLAG_HIDE_TRICK_HOUSE_END_MAN":899,"FLAG_HIDE_TRICK_HOUSE_ENTRANCE_MAN":872,"FLAG_HIDE_UNDERWATER_SEA_FLOOR_CAVERN_STOLEN_SUBMARINE":980,"FLAG_HIDE_UNION_ROOM_PLAYER_1":703,"FLAG_HIDE_UNION_ROOM_PLAYER_2":704,"FLAG_HIDE_UNION_ROOM_PLAYER_3":705,"FLAG_HIDE_UNION_ROOM_PLAYER_4":706,"FLAG_HIDE_UNION_ROOM_PLAYER_5":707,"FLAG_HIDE_UNION_ROOM_PLAYER_6":708,"FLAG_HIDE_UNION_ROOM_PLAYER_7":709,"FLAG_HIDE_UNION_ROOM_PLAYER_8":710,"FLAG_HIDE_VERDANTURF_TOWN_SCOTT":766,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLY":806,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLYS_UNCLE":809,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDA":984,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDAS_BOYFRIEND":808,"FLAG_HIDE_VICTORY_ROAD_ENTRANCE_WALLY":858,"FLAG_HIDE_VICTORY_ROAD_EXIT_WALLY":751,"FLAG_HIDE_WEATHER_INSTITUTE_1F_WORKERS":892,"FLAG_HIDE_WEATHER_INSTITUTE_2F_AQUA_GRUNT_M":992,"FLAG_HIDE_WEATHER_INSTITUTE_2F_WORKERS":893,"FLAG_HO_OH_IS_RECOVERING":1256,"FLAG_INTERACTED_WITH_DEVON_EMPLOYEE_GOODS_STOLEN":159,"FLAG_INTERACTED_WITH_STEVEN_SPACE_CENTER":205,"FLAG_IS_CHAMPION":2175,"FLAG_ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":1100,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":1102,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":1078,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":1101,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":1077,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":1095,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":1099,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":1097,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":1096,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":1098,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":1124,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":1071,"FLAG_ITEM_AQUA_HIDEOUT_B1F_NUGGET":1132,"FLAG_ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":1072,"FLAG_ITEM_ARTISAN_CAVE_1F_CARBOS":1163,"FLAG_ITEM_ARTISAN_CAVE_B1F_HP_UP":1162,"FLAG_ITEM_FIERY_PATH_FIRE_STONE":1111,"FLAG_ITEM_FIERY_PATH_TM_TOXIC":1091,"FLAG_ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":1050,"FLAG_ITEM_GRANITE_CAVE_B1F_POKE_BALL":1051,"FLAG_ITEM_GRANITE_CAVE_B2F_RARE_CANDY":1054,"FLAG_ITEM_GRANITE_CAVE_B2F_REPEL":1053,"FLAG_ITEM_JAGGED_PASS_BURN_HEAL":1070,"FLAG_ITEM_LILYCOVE_CITY_MAX_REPEL":1042,"FLAG_ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":1151,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":1165,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":1164,"FLAG_ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":1166,"FLAG_ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":1167,"FLAG_ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":1059,"FLAG_ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":1168,"FLAG_ITEM_MAUVILLE_CITY_X_SPEED":1116,"FLAG_ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":1045,"FLAG_ITEM_METEOR_FALLS_1F_1R_MOON_STONE":1046,"FLAG_ITEM_METEOR_FALLS_1F_1R_PP_UP":1047,"FLAG_ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":1044,"FLAG_ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":1080,"FLAG_ITEM_MOSSDEEP_CITY_NET_BALL":1043,"FLAG_ITEM_MOSSDEEP_STEVENS_HOUSE_HM08":1133,"FLAG_ITEM_MT_PYRE_2F_ULTRA_BALL":1129,"FLAG_ITEM_MT_PYRE_3F_SUPER_REPEL":1120,"FLAG_ITEM_MT_PYRE_4F_SEA_INCENSE":1130,"FLAG_ITEM_MT_PYRE_5F_LAX_INCENSE":1052,"FLAG_ITEM_MT_PYRE_6F_TM_SHADOW_BALL":1089,"FLAG_ITEM_MT_PYRE_EXTERIOR_MAX_POTION":1073,"FLAG_ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":1074,"FLAG_ITEM_NEW_MAUVILLE_ESCAPE_ROPE":1076,"FLAG_ITEM_NEW_MAUVILLE_FULL_HEAL":1122,"FLAG_ITEM_NEW_MAUVILLE_PARALYZE_HEAL":1123,"FLAG_ITEM_NEW_MAUVILLE_THUNDER_STONE":1110,"FLAG_ITEM_NEW_MAUVILLE_ULTRA_BALL":1075,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MASTER_BALL":1125,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MAX_ELIXIR":1126,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B2F_NEST_BALL":1127,"FLAG_ITEM_PETALBURG_CITY_ETHER":1040,"FLAG_ITEM_PETALBURG_CITY_MAX_REVIVE":1039,"FLAG_ITEM_PETALBURG_WOODS_ETHER":1058,"FLAG_ITEM_PETALBURG_WOODS_GREAT_BALL":1056,"FLAG_ITEM_PETALBURG_WOODS_PARALYZE_HEAL":1117,"FLAG_ITEM_PETALBURG_WOODS_X_ATTACK":1055,"FLAG_ITEM_ROUTE_102_POTION":1000,"FLAG_ITEM_ROUTE_103_GUARD_SPEC":1114,"FLAG_ITEM_ROUTE_103_PP_UP":1137,"FLAG_ITEM_ROUTE_104_POKE_BALL":1057,"FLAG_ITEM_ROUTE_104_POTION":1135,"FLAG_ITEM_ROUTE_104_PP_UP":1002,"FLAG_ITEM_ROUTE_104_X_ACCURACY":1115,"FLAG_ITEM_ROUTE_105_IRON":1003,"FLAG_ITEM_ROUTE_106_PROTEIN":1004,"FLAG_ITEM_ROUTE_108_STAR_PIECE":1139,"FLAG_ITEM_ROUTE_109_POTION":1140,"FLAG_ITEM_ROUTE_109_PP_UP":1005,"FLAG_ITEM_ROUTE_110_DIRE_HIT":1007,"FLAG_ITEM_ROUTE_110_ELIXIR":1141,"FLAG_ITEM_ROUTE_110_RARE_CANDY":1006,"FLAG_ITEM_ROUTE_111_ELIXIR":1142,"FLAG_ITEM_ROUTE_111_HP_UP":1010,"FLAG_ITEM_ROUTE_111_STARDUST":1009,"FLAG_ITEM_ROUTE_111_TM_SANDSTORM":1008,"FLAG_ITEM_ROUTE_112_NUGGET":1011,"FLAG_ITEM_ROUTE_113_HYPER_POTION":1143,"FLAG_ITEM_ROUTE_113_MAX_ETHER":1012,"FLAG_ITEM_ROUTE_113_SUPER_REPEL":1013,"FLAG_ITEM_ROUTE_114_ENERGY_POWDER":1160,"FLAG_ITEM_ROUTE_114_PROTEIN":1015,"FLAG_ITEM_ROUTE_114_RARE_CANDY":1014,"FLAG_ITEM_ROUTE_115_GREAT_BALL":1118,"FLAG_ITEM_ROUTE_115_HEAL_POWDER":1144,"FLAG_ITEM_ROUTE_115_IRON":1018,"FLAG_ITEM_ROUTE_115_PP_UP":1161,"FLAG_ITEM_ROUTE_115_SUPER_POTION":1016,"FLAG_ITEM_ROUTE_115_TM_FOCUS_PUNCH":1017,"FLAG_ITEM_ROUTE_116_ETHER":1019,"FLAG_ITEM_ROUTE_116_HP_UP":1021,"FLAG_ITEM_ROUTE_116_POTION":1146,"FLAG_ITEM_ROUTE_116_REPEL":1020,"FLAG_ITEM_ROUTE_116_X_SPECIAL":1001,"FLAG_ITEM_ROUTE_117_GREAT_BALL":1022,"FLAG_ITEM_ROUTE_117_REVIVE":1023,"FLAG_ITEM_ROUTE_118_HYPER_POTION":1121,"FLAG_ITEM_ROUTE_119_ELIXIR_1":1026,"FLAG_ITEM_ROUTE_119_ELIXIR_2":1147,"FLAG_ITEM_ROUTE_119_HYPER_POTION_1":1029,"FLAG_ITEM_ROUTE_119_HYPER_POTION_2":1106,"FLAG_ITEM_ROUTE_119_LEAF_STONE":1027,"FLAG_ITEM_ROUTE_119_NUGGET":1134,"FLAG_ITEM_ROUTE_119_RARE_CANDY":1028,"FLAG_ITEM_ROUTE_119_SUPER_REPEL":1024,"FLAG_ITEM_ROUTE_119_ZINC":1025,"FLAG_ITEM_ROUTE_120_FULL_HEAL":1031,"FLAG_ITEM_ROUTE_120_HYPER_POTION":1107,"FLAG_ITEM_ROUTE_120_NEST_BALL":1108,"FLAG_ITEM_ROUTE_120_NUGGET":1030,"FLAG_ITEM_ROUTE_120_REVIVE":1148,"FLAG_ITEM_ROUTE_121_CARBOS":1103,"FLAG_ITEM_ROUTE_121_REVIVE":1149,"FLAG_ITEM_ROUTE_121_ZINC":1150,"FLAG_ITEM_ROUTE_123_CALCIUM":1032,"FLAG_ITEM_ROUTE_123_ELIXIR":1109,"FLAG_ITEM_ROUTE_123_PP_UP":1152,"FLAG_ITEM_ROUTE_123_REVIVAL_HERB":1153,"FLAG_ITEM_ROUTE_123_ULTRA_BALL":1104,"FLAG_ITEM_ROUTE_124_BLUE_SHARD":1093,"FLAG_ITEM_ROUTE_124_RED_SHARD":1092,"FLAG_ITEM_ROUTE_124_YELLOW_SHARD":1066,"FLAG_ITEM_ROUTE_125_BIG_PEARL":1154,"FLAG_ITEM_ROUTE_126_GREEN_SHARD":1105,"FLAG_ITEM_ROUTE_127_CARBOS":1035,"FLAG_ITEM_ROUTE_127_RARE_CANDY":1155,"FLAG_ITEM_ROUTE_127_ZINC":1034,"FLAG_ITEM_ROUTE_132_PROTEIN":1156,"FLAG_ITEM_ROUTE_132_RARE_CANDY":1036,"FLAG_ITEM_ROUTE_133_BIG_PEARL":1037,"FLAG_ITEM_ROUTE_133_MAX_REVIVE":1157,"FLAG_ITEM_ROUTE_133_STAR_PIECE":1038,"FLAG_ITEM_ROUTE_134_CARBOS":1158,"FLAG_ITEM_ROUTE_134_STAR_PIECE":1159,"FLAG_ITEM_RUSTBORO_CITY_X_DEFEND":1041,"FLAG_ITEM_RUSTURF_TUNNEL_MAX_ETHER":1049,"FLAG_ITEM_RUSTURF_TUNNEL_POKE_BALL":1048,"FLAG_ITEM_SAFARI_ZONE_NORTH_CALCIUM":1119,"FLAG_ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":1169,"FLAG_ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":1094,"FLAG_ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":1170,"FLAG_ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":1131,"FLAG_ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":1079,"FLAG_ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":1090,"FLAG_ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":1081,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":1113,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":1112,"FLAG_ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":1082,"FLAG_ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":1083,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":1060,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":1061,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":1062,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":1063,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":1064,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":1065,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":1067,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":1068,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":1069,"FLAG_ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":1084,"FLAG_ITEM_VICTORY_ROAD_1F_PP_UP":1085,"FLAG_ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":1087,"FLAG_ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":1086,"FLAG_ITEM_VICTORY_ROAD_B2F_FULL_HEAL":1088,"FLAG_KECLEON_FLED_FORTREE":295,"FLAG_KYOGRE_ESCAPED_SEAFLOOR_CAVERN":129,"FLAG_KYOGRE_IS_RECOVERING":1273,"FLAG_LANDMARK_ABANDONED_SHIP":2206,"FLAG_LANDMARK_ALTERING_CAVE":2269,"FLAG_LANDMARK_ANCIENT_TOMB":2233,"FLAG_LANDMARK_ARTISAN_CAVE":2271,"FLAG_LANDMARK_BATTLE_FRONTIER":2216,"FLAG_LANDMARK_BERRY_MASTERS_HOUSE":2243,"FLAG_LANDMARK_DESERT_RUINS":2230,"FLAG_LANDMARK_DESERT_UNDERPASS":2270,"FLAG_LANDMARK_FIERY_PATH":2218,"FLAG_LANDMARK_FLOWER_SHOP":2204,"FLAG_LANDMARK_FOSSIL_MANIACS_HOUSE":2231,"FLAG_LANDMARK_GLASS_WORKSHOP":2212,"FLAG_LANDMARK_HUNTERS_HOUSE":2235,"FLAG_LANDMARK_ISLAND_CAVE":2229,"FLAG_LANDMARK_LANETTES_HOUSE":2213,"FLAG_LANDMARK_MIRAGE_TOWER":120,"FLAG_LANDMARK_MR_BRINEY_HOUSE":2205,"FLAG_LANDMARK_NEW_MAUVILLE":2208,"FLAG_LANDMARK_OLD_LADY_REST_SHOP":2209,"FLAG_LANDMARK_POKEMON_DAYCARE":2214,"FLAG_LANDMARK_POKEMON_LEAGUE":2228,"FLAG_LANDMARK_SCORCHED_SLAB":2232,"FLAG_LANDMARK_SEAFLOOR_CAVERN":2215,"FLAG_LANDMARK_SEALED_CHAMBER":2236,"FLAG_LANDMARK_SEASHORE_HOUSE":2207,"FLAG_LANDMARK_SKY_PILLAR":2238,"FLAG_LANDMARK_SOUTHERN_ISLAND":2217,"FLAG_LANDMARK_TRAINER_HILL":2274,"FLAG_LANDMARK_TRICK_HOUSE":2210,"FLAG_LANDMARK_TUNNELERS_REST_HOUSE":2234,"FLAG_LANDMARK_WINSTRATE_FAMILY":2211,"FLAG_LATIAS_IS_RECOVERING":1263,"FLAG_LATIOS_IS_RECOVERING":1255,"FLAG_LATIOS_OR_LATIAS_ROAMING":255,"FLAG_LEGENDARIES_IN_SOOTOPOLIS":83,"FLAG_LILYCOVE_RECEIVED_BERRY":1208,"FLAG_LUGIA_IS_RECOVERING":1257,"FLAG_MAP_SCRIPT_CHECKED_DEOXYS":2259,"FLAG_MATCH_CALL_REGISTERED":348,"FLAG_MAUVILLE_GYM_BARRIERS_STATE":99,"FLAG_MET_ARCHIE_METEOR_FALLS":207,"FLAG_MET_ARCHIE_SOOTOPOLIS":308,"FLAG_MET_BATTLE_FRONTIER_BREEDER":339,"FLAG_MET_BATTLE_FRONTIER_GAMBLER":343,"FLAG_MET_BATTLE_FRONTIER_MANIAC":340,"FLAG_MET_DEVON_EMPLOYEE":287,"FLAG_MET_DIVING_TREASURE_HUNTER":217,"FLAG_MET_FANCLUB_YOUNGER_BROTHER":300,"FLAG_MET_FRONTIER_BEAUTY_MOVE_TUTOR":346,"FLAG_MET_FRONTIER_SWIMMER_MOVE_TUTOR":347,"FLAG_MET_HIDDEN_POWER_GIVER":118,"FLAG_MET_MAXIE_SOOTOPOLIS":309,"FLAG_MET_PRETTY_PETAL_SHOP_OWNER":127,"FLAG_MET_PROF_COZMO":244,"FLAG_MET_RIVAL_IN_HOUSE_AFTER_LILYCOVE":293,"FLAG_MET_RIVAL_LILYCOVE":292,"FLAG_MET_RIVAL_MOM":87,"FLAG_MET_RIVAL_RUSTBORO":288,"FLAG_MET_SCOTT_AFTER_OBTAINING_STONE_BADGE":459,"FLAG_MET_SCOTT_IN_EVERGRANDE":463,"FLAG_MET_SCOTT_IN_FALLARBOR":461,"FLAG_MET_SCOTT_IN_LILYCOVE":462,"FLAG_MET_SCOTT_IN_VERDANTURF":460,"FLAG_MET_SCOTT_ON_SS_TIDAL":464,"FLAG_MET_SCOTT_RUSTBORO":310,"FLAG_MET_SLATEPORT_FANCLUB_CHAIRMAN":342,"FLAG_MET_TEAM_AQUA_HARBOR":97,"FLAG_MET_WAILMER_TRAINER":218,"FLAG_MEW_IS_RECOVERING":1259,"FLAG_MIRAGE_TOWER_VISIBLE":334,"FLAG_MOSSDEEP_GYM_SWITCH_1":100,"FLAG_MOSSDEEP_GYM_SWITCH_2":101,"FLAG_MOSSDEEP_GYM_SWITCH_3":102,"FLAG_MOSSDEEP_GYM_SWITCH_4":103,"FLAG_MOVE_TUTOR_TAUGHT_DOUBLE_EDGE":441,"FLAG_MOVE_TUTOR_TAUGHT_DYNAMICPUNCH":440,"FLAG_MOVE_TUTOR_TAUGHT_EXPLOSION":442,"FLAG_MOVE_TUTOR_TAUGHT_FURY_CUTTER":435,"FLAG_MOVE_TUTOR_TAUGHT_METRONOME":437,"FLAG_MOVE_TUTOR_TAUGHT_MIMIC":436,"FLAG_MOVE_TUTOR_TAUGHT_ROLLOUT":434,"FLAG_MOVE_TUTOR_TAUGHT_SLEEP_TALK":438,"FLAG_MOVE_TUTOR_TAUGHT_SUBSTITUTE":439,"FLAG_MOVE_TUTOR_TAUGHT_SWAGGER":433,"FLAG_MR_BRINEY_SAILING_INTRO":147,"FLAG_MYSTERY_GIFT_1":485,"FLAG_MYSTERY_GIFT_10":494,"FLAG_MYSTERY_GIFT_11":495,"FLAG_MYSTERY_GIFT_12":496,"FLAG_MYSTERY_GIFT_13":497,"FLAG_MYSTERY_GIFT_14":498,"FLAG_MYSTERY_GIFT_15":499,"FLAG_MYSTERY_GIFT_2":486,"FLAG_MYSTERY_GIFT_3":487,"FLAG_MYSTERY_GIFT_4":488,"FLAG_MYSTERY_GIFT_5":489,"FLAG_MYSTERY_GIFT_6":490,"FLAG_MYSTERY_GIFT_7":491,"FLAG_MYSTERY_GIFT_8":492,"FLAG_MYSTERY_GIFT_9":493,"FLAG_MYSTERY_GIFT_DONE":484,"FLAG_NEVER_SET_0x0DC":220,"FLAG_NOT_READY_FOR_BATTLE_ROUTE_120":290,"FLAG_NURSE_MENTIONS_GOLD_CARD":345,"FLAG_NURSE_UNION_ROOM_REMINDER":2176,"FLAG_OCEANIC_MUSEUM_MET_REPORTER":105,"FLAG_OMIT_DIVE_FROM_STEVEN_LETTER":302,"FLAG_PACIFIDLOG_NPC_TRADE_COMPLETED":154,"FLAG_PENDING_DAYCARE_EGG":134,"FLAG_PETALBURG_MART_EXPANDED_ITEMS":296,"FLAG_POKERUS_EXPLAINED":273,"FLAG_PURCHASED_HARBOR_MAIL":104,"FLAG_RAYQUAZA_IS_RECOVERING":1279,"FLAG_RECEIVED_20_COINS":225,"FLAG_RECEIVED_6_SODA_POP":140,"FLAG_RECEIVED_ACRO_BIKE":1181,"FLAG_RECEIVED_AMULET_COIN":133,"FLAG_RECEIVED_AURORA_TICKET":314,"FLAG_RECEIVED_BADGE_1":1182,"FLAG_RECEIVED_BADGE_2":1183,"FLAG_RECEIVED_BADGE_3":1184,"FLAG_RECEIVED_BADGE_4":1185,"FLAG_RECEIVED_BADGE_5":1186,"FLAG_RECEIVED_BADGE_6":1187,"FLAG_RECEIVED_BADGE_7":1188,"FLAG_RECEIVED_BADGE_8":1189,"FLAG_RECEIVED_BELDUM":298,"FLAG_RECEIVED_BELUE_BERRY":252,"FLAG_RECEIVED_BIKE":90,"FLAG_RECEIVED_BLUE_SCARF":201,"FLAG_RECEIVED_CASTFORM":151,"FLAG_RECEIVED_CHARCOAL":254,"FLAG_RECEIVED_CHESTO_BERRY_ROUTE_104":246,"FLAG_RECEIVED_CLEANSE_TAG":282,"FLAG_RECEIVED_COIN_CASE":258,"FLAG_RECEIVED_CONTEST_PASS":150,"FLAG_RECEIVED_DEEP_SEA_SCALE":1190,"FLAG_RECEIVED_DEEP_SEA_TOOTH":1191,"FLAG_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":1172,"FLAG_RECEIVED_DEVON_SCOPE":285,"FLAG_RECEIVED_DOLL_LANETTE":131,"FLAG_RECEIVED_DURIN_BERRY":251,"FLAG_RECEIVED_EON_TICKET":474,"FLAG_RECEIVED_EXP_SHARE":272,"FLAG_RECEIVED_FANCLUB_TM_THIS_WEEK":299,"FLAG_RECEIVED_FIRST_POKEBALLS":233,"FLAG_RECEIVED_FOCUS_BAND":283,"FLAG_RECEIVED_GLASS_ORNAMENT":236,"FLAG_RECEIVED_GOLD_SHIELD":238,"FLAG_RECEIVED_GOOD_ROD":227,"FLAG_RECEIVED_GO_GOGGLES":221,"FLAG_RECEIVED_GREAT_BALL_PETALBURG_WOODS":1171,"FLAG_RECEIVED_GREAT_BALL_RUSTBORO_CITY":1173,"FLAG_RECEIVED_GREEN_SCARF":203,"FLAG_RECEIVED_HM_CUT":137,"FLAG_RECEIVED_HM_DIVE":123,"FLAG_RECEIVED_HM_FLASH":109,"FLAG_RECEIVED_HM_FLY":110,"FLAG_RECEIVED_HM_ROCK_SMASH":107,"FLAG_RECEIVED_HM_STRENGTH":106,"FLAG_RECEIVED_HM_SURF":122,"FLAG_RECEIVED_HM_WATERFALL":312,"FLAG_RECEIVED_ITEMFINDER":1176,"FLAG_RECEIVED_KINGS_ROCK":276,"FLAG_RECEIVED_LAVARIDGE_EGG":266,"FLAG_RECEIVED_LETTER":1174,"FLAG_RECEIVED_MACHO_BRACE":277,"FLAG_RECEIVED_MACH_BIKE":1180,"FLAG_RECEIVED_MAGMA_EMBLEM":1177,"FLAG_RECEIVED_MENTAL_HERB":223,"FLAG_RECEIVED_METEORITE":115,"FLAG_RECEIVED_MIRACLE_SEED":297,"FLAG_RECEIVED_MYSTIC_TICKET":315,"FLAG_RECEIVED_OLD_ROD":257,"FLAG_RECEIVED_OLD_SEA_MAP":316,"FLAG_RECEIVED_PAMTRE_BERRY":249,"FLAG_RECEIVED_PINK_SCARF":202,"FLAG_RECEIVED_POKEBLOCK_CASE":95,"FLAG_RECEIVED_POKEDEX_FROM_BIRCH":2276,"FLAG_RECEIVED_POKENAV":188,"FLAG_RECEIVED_POTION_OLDALE":132,"FLAG_RECEIVED_POWDER_JAR":337,"FLAG_RECEIVED_PREMIER_BALL_RUSTBORO":213,"FLAG_RECEIVED_QUICK_CLAW":275,"FLAG_RECEIVED_RED_OR_BLUE_ORB":212,"FLAG_RECEIVED_RED_SCARF":200,"FLAG_RECEIVED_REPEAT_BALL":256,"FLAG_RECEIVED_REVIVED_FOSSIL_MON":267,"FLAG_RECEIVED_RUNNING_SHOES":274,"FLAG_RECEIVED_SECRET_POWER":96,"FLAG_RECEIVED_SHOAL_SALT_1":952,"FLAG_RECEIVED_SHOAL_SALT_2":953,"FLAG_RECEIVED_SHOAL_SALT_3":954,"FLAG_RECEIVED_SHOAL_SALT_4":955,"FLAG_RECEIVED_SHOAL_SHELL_1":956,"FLAG_RECEIVED_SHOAL_SHELL_2":957,"FLAG_RECEIVED_SHOAL_SHELL_3":958,"FLAG_RECEIVED_SHOAL_SHELL_4":959,"FLAG_RECEIVED_SILK_SCARF":289,"FLAG_RECEIVED_SILVER_SHIELD":237,"FLAG_RECEIVED_SOFT_SAND":280,"FLAG_RECEIVED_SOOTHE_BELL":278,"FLAG_RECEIVED_SOOT_SACK":1033,"FLAG_RECEIVED_SPECIAL_PHRASE_HINT":85,"FLAG_RECEIVED_SPELON_BERRY":248,"FLAG_RECEIVED_SS_TICKET":291,"FLAG_RECEIVED_STARTER_DOLL":226,"FLAG_RECEIVED_SUN_STONE_MOSSDEEP":192,"FLAG_RECEIVED_SUPER_ROD":152,"FLAG_RECEIVED_TM_AERIAL_ACE":170,"FLAG_RECEIVED_TM_ATTRACT":235,"FLAG_RECEIVED_TM_BRICK_BREAK":121,"FLAG_RECEIVED_TM_BULK_UP":166,"FLAG_RECEIVED_TM_BULLET_SEED":262,"FLAG_RECEIVED_TM_CALM_MIND":171,"FLAG_RECEIVED_TM_DIG":261,"FLAG_RECEIVED_TM_FACADE":169,"FLAG_RECEIVED_TM_FRUSTRATION":1179,"FLAG_RECEIVED_TM_GIGA_DRAIN":232,"FLAG_RECEIVED_TM_HIDDEN_POWER":264,"FLAG_RECEIVED_TM_OVERHEAT":168,"FLAG_RECEIVED_TM_REST":234,"FLAG_RECEIVED_TM_RETURN":229,"FLAG_RECEIVED_TM_RETURN_2":1178,"FLAG_RECEIVED_TM_ROAR":231,"FLAG_RECEIVED_TM_ROCK_TOMB":165,"FLAG_RECEIVED_TM_SHOCK_WAVE":167,"FLAG_RECEIVED_TM_SLUDGE_BOMB":230,"FLAG_RECEIVED_TM_SNATCH":260,"FLAG_RECEIVED_TM_STEEL_WING":1175,"FLAG_RECEIVED_TM_THIEF":269,"FLAG_RECEIVED_TM_TORMENT":265,"FLAG_RECEIVED_TM_WATER_PULSE":172,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_1":1200,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_2":1201,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_3":1202,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_4":1203,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_5":1204,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_6":1205,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_7":1206,"FLAG_RECEIVED_WAILMER_DOLL":245,"FLAG_RECEIVED_WAILMER_PAIL":94,"FLAG_RECEIVED_WATMEL_BERRY":250,"FLAG_RECEIVED_WHITE_HERB":279,"FLAG_RECEIVED_YELLOW_SCARF":204,"FLAG_RECOVERED_DEVON_GOODS":143,"FLAG_REGICE_IS_RECOVERING":1260,"FLAG_REGIROCK_IS_RECOVERING":1261,"FLAG_REGISTEEL_IS_RECOVERING":1262,"FLAG_REGISTERED_STEVEN_POKENAV":305,"FLAG_REGISTER_RIVAL_POKENAV":124,"FLAG_REGI_DOORS_OPENED":228,"FLAG_REMATCH_ABIGAIL":387,"FLAG_REMATCH_AMY_AND_LIV":399,"FLAG_REMATCH_ANDRES":350,"FLAG_REMATCH_ANNA_AND_MEG":378,"FLAG_REMATCH_BENJAMIN":390,"FLAG_REMATCH_BERNIE":369,"FLAG_REMATCH_BRAWLY":415,"FLAG_REMATCH_BROOKE":356,"FLAG_REMATCH_CALVIN":383,"FLAG_REMATCH_CAMERON":373,"FLAG_REMATCH_CATHERINE":406,"FLAG_REMATCH_CINDY":359,"FLAG_REMATCH_CORY":401,"FLAG_REMATCH_CRISTIN":355,"FLAG_REMATCH_CYNDY":395,"FLAG_REMATCH_DALTON":368,"FLAG_REMATCH_DIANA":398,"FLAG_REMATCH_DRAKE":424,"FLAG_REMATCH_DUSTY":351,"FLAG_REMATCH_DYLAN":388,"FLAG_REMATCH_EDWIN":402,"FLAG_REMATCH_ELLIOT":384,"FLAG_REMATCH_ERNEST":400,"FLAG_REMATCH_ETHAN":370,"FLAG_REMATCH_FERNANDO":367,"FLAG_REMATCH_FLANNERY":417,"FLAG_REMATCH_GABRIELLE":405,"FLAG_REMATCH_GLACIA":423,"FLAG_REMATCH_HALEY":408,"FLAG_REMATCH_ISAAC":404,"FLAG_REMATCH_ISABEL":379,"FLAG_REMATCH_ISAIAH":385,"FLAG_REMATCH_JACKI":374,"FLAG_REMATCH_JACKSON":407,"FLAG_REMATCH_JAMES":409,"FLAG_REMATCH_JEFFREY":372,"FLAG_REMATCH_JENNY":397,"FLAG_REMATCH_JERRY":377,"FLAG_REMATCH_JESSICA":361,"FLAG_REMATCH_JOHN_AND_JAY":371,"FLAG_REMATCH_KAREN":376,"FLAG_REMATCH_KATELYN":389,"FLAG_REMATCH_KIRA_AND_DAN":412,"FLAG_REMATCH_KOJI":366,"FLAG_REMATCH_LAO":394,"FLAG_REMATCH_LILA_AND_ROY":354,"FLAG_REMATCH_LOLA":352,"FLAG_REMATCH_LYDIA":403,"FLAG_REMATCH_MADELINE":396,"FLAG_REMATCH_MARIA":386,"FLAG_REMATCH_MIGUEL":380,"FLAG_REMATCH_NICOLAS":392,"FLAG_REMATCH_NOB":365,"FLAG_REMATCH_NORMAN":418,"FLAG_REMATCH_PABLO":391,"FLAG_REMATCH_PHOEBE":422,"FLAG_REMATCH_RICKY":353,"FLAG_REMATCH_ROBERT":393,"FLAG_REMATCH_ROSE":349,"FLAG_REMATCH_ROXANNE":414,"FLAG_REMATCH_SAWYER":411,"FLAG_REMATCH_SHELBY":382,"FLAG_REMATCH_SIDNEY":421,"FLAG_REMATCH_STEVE":363,"FLAG_REMATCH_TATE_AND_LIZA":420,"FLAG_REMATCH_THALIA":360,"FLAG_REMATCH_TIMOTHY":381,"FLAG_REMATCH_TONY":364,"FLAG_REMATCH_TRENT":410,"FLAG_REMATCH_VALERIE":358,"FLAG_REMATCH_WALLACE":425,"FLAG_REMATCH_WALLY":413,"FLAG_REMATCH_WALTER":375,"FLAG_REMATCH_WATTSON":416,"FLAG_REMATCH_WILTON":357,"FLAG_REMATCH_WINONA":419,"FLAG_REMATCH_WINSTON":362,"FLAG_RESCUED_BIRCH":82,"FLAG_RETURNED_DEVON_GOODS":144,"FLAG_RETURNED_RED_OR_BLUE_ORB":259,"FLAG_RIVAL_LEFT_FOR_ROUTE103":301,"FLAG_ROUTE_111_RECEIVED_BERRY":1192,"FLAG_ROUTE_114_RECEIVED_BERRY":1193,"FLAG_ROUTE_120_RECEIVED_BERRY":1194,"FLAG_RUSTBORO_NPC_TRADE_COMPLETED":153,"FLAG_RUSTURF_TUNNEL_OPENED":199,"FLAG_SCOTT_CALL_BATTLE_FRONTIER":114,"FLAG_SCOTT_CALL_FORTREE_GYM":138,"FLAG_SCOTT_GIVES_BATTLE_POINTS":465,"FLAG_SECRET_BASE_REGISTRY_ENABLED":268,"FLAG_SET_WALL_CLOCK":81,"FLAG_SHOWN_AURORA_TICKET":431,"FLAG_SHOWN_BOX_WAS_FULL_MESSAGE":2263,"FLAG_SHOWN_EON_TICKET":430,"FLAG_SHOWN_MYSTIC_TICKET":475,"FLAG_SHOWN_OLD_SEA_MAP":432,"FLAG_SMART_PAINTING_MADE":163,"FLAG_SOOTOPOLIS_ARCHIE_MAXIE_LEAVE":158,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_1":1198,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_2":1199,"FLAG_SPECIAL_FLAG_UNUSED_0x4003":16387,"FLAG_SS_TIDAL_DISABLED":84,"FLAG_STEVEN_GUIDES_TO_CAVE_OF_ORIGIN":307,"FLAG_STORING_ITEMS_IN_PYRAMID_BAG":16388,"FLAG_SYS_ARENA_GOLD":2251,"FLAG_SYS_ARENA_SILVER":2250,"FLAG_SYS_BRAILLE_DIG":2223,"FLAG_SYS_BRAILLE_REGICE_COMPLETED":2225,"FLAG_SYS_B_DASH":2240,"FLAG_SYS_CAVE_BATTLE":2201,"FLAG_SYS_CAVE_SHIP":2199,"FLAG_SYS_CAVE_WONDER":2200,"FLAG_SYS_CHANGED_DEWFORD_TREND":2195,"FLAG_SYS_CHAT_USED":2149,"FLAG_SYS_CLOCK_SET":2197,"FLAG_SYS_CRUISE_MODE":2189,"FLAG_SYS_CTRL_OBJ_DELETE":2241,"FLAG_SYS_CYCLING_ROAD":2187,"FLAG_SYS_DOME_GOLD":2247,"FLAG_SYS_DOME_SILVER":2246,"FLAG_SYS_ENC_DOWN_ITEM":2222,"FLAG_SYS_ENC_UP_ITEM":2221,"FLAG_SYS_FACTORY_GOLD":2253,"FLAG_SYS_FACTORY_SILVER":2252,"FLAG_SYS_FRONTIER_PASS":2258,"FLAG_SYS_GAME_CLEAR":2148,"FLAG_SYS_MIX_RECORD":2196,"FLAG_SYS_MYSTERY_EVENT_ENABLE":2220,"FLAG_SYS_MYSTERY_GIFT_ENABLE":2267,"FLAG_SYS_NATIONAL_DEX":2198,"FLAG_SYS_PALACE_GOLD":2249,"FLAG_SYS_PALACE_SILVER":2248,"FLAG_SYS_PC_LANETTE":2219,"FLAG_SYS_PIKE_GOLD":2255,"FLAG_SYS_PIKE_SILVER":2254,"FLAG_SYS_POKEDEX_GET":2145,"FLAG_SYS_POKEMON_GET":2144,"FLAG_SYS_POKENAV_GET":2146,"FLAG_SYS_PYRAMID_GOLD":2257,"FLAG_SYS_PYRAMID_SILVER":2256,"FLAG_SYS_REGIROCK_PUZZLE_COMPLETED":2224,"FLAG_SYS_REGISTEEL_PUZZLE_COMPLETED":2226,"FLAG_SYS_RESET_RTC_ENABLE":2242,"FLAG_SYS_RIBBON_GET":2203,"FLAG_SYS_SAFARI_MODE":2188,"FLAG_SYS_SHOAL_ITEM":2239,"FLAG_SYS_SHOAL_TIDE":2202,"FLAG_SYS_TOWER_GOLD":2245,"FLAG_SYS_TOWER_SILVER":2244,"FLAG_SYS_TV_HOME":2192,"FLAG_SYS_TV_LATIAS_LATIOS":2237,"FLAG_SYS_TV_START":2194,"FLAG_SYS_TV_WATCH":2193,"FLAG_SYS_USE_FLASH":2184,"FLAG_SYS_USE_STRENGTH":2185,"FLAG_SYS_WEATHER_CTRL":2186,"FLAG_TEAM_AQUA_ESCAPED_IN_SUBMARINE":112,"FLAG_TEMP_1":1,"FLAG_TEMP_10":16,"FLAG_TEMP_11":17,"FLAG_TEMP_12":18,"FLAG_TEMP_13":19,"FLAG_TEMP_14":20,"FLAG_TEMP_15":21,"FLAG_TEMP_16":22,"FLAG_TEMP_17":23,"FLAG_TEMP_18":24,"FLAG_TEMP_19":25,"FLAG_TEMP_1A":26,"FLAG_TEMP_1B":27,"FLAG_TEMP_1C":28,"FLAG_TEMP_1D":29,"FLAG_TEMP_1E":30,"FLAG_TEMP_1F":31,"FLAG_TEMP_2":2,"FLAG_TEMP_3":3,"FLAG_TEMP_4":4,"FLAG_TEMP_5":5,"FLAG_TEMP_6":6,"FLAG_TEMP_7":7,"FLAG_TEMP_8":8,"FLAG_TEMP_9":9,"FLAG_TEMP_A":10,"FLAG_TEMP_B":11,"FLAG_TEMP_C":12,"FLAG_TEMP_D":13,"FLAG_TEMP_E":14,"FLAG_TEMP_F":15,"FLAG_TEMP_HIDE_MIRAGE_ISLAND_BERRY_TREE":17,"FLAG_TEMP_REGICE_PUZZLE_FAILED":3,"FLAG_TEMP_REGICE_PUZZLE_STARTED":2,"FLAG_TEMP_SKIP_GABBY_INTERVIEW":1,"FLAG_THANKED_FOR_PLAYING_WITH_WALLY":135,"FLAG_TOUGH_PAINTING_MADE":164,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_1":194,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_2":195,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_3":196,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_4":197,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_5":198,"FLAG_TV_EXPLAINED":98,"FLAG_UNLOCKED_TRENDY_SAYINGS":2150,"FLAG_USED_ROOM_1_KEY":240,"FLAG_USED_ROOM_2_KEY":241,"FLAG_USED_ROOM_4_KEY":242,"FLAG_USED_ROOM_6_KEY":243,"FLAG_USED_STORAGE_KEY":239,"FLAG_VISITED_DEWFORD_TOWN":2161,"FLAG_VISITED_EVER_GRANDE_CITY":2174,"FLAG_VISITED_FALLARBOR_TOWN":2163,"FLAG_VISITED_FORTREE_CITY":2170,"FLAG_VISITED_LAVARIDGE_TOWN":2162,"FLAG_VISITED_LILYCOVE_CITY":2171,"FLAG_VISITED_LITTLEROOT_TOWN":2159,"FLAG_VISITED_MAUVILLE_CITY":2168,"FLAG_VISITED_MOSSDEEP_CITY":2172,"FLAG_VISITED_OLDALE_TOWN":2160,"FLAG_VISITED_PACIFIDLOG_TOWN":2165,"FLAG_VISITED_PETALBURG_CITY":2166,"FLAG_VISITED_RUSTBORO_CITY":2169,"FLAG_VISITED_SLATEPORT_CITY":2167,"FLAG_VISITED_SOOTOPOLIS_CITY":2173,"FLAG_VISITED_VERDANTURF_TOWN":2164,"FLAG_WALLACE_GOES_TO_SKY_PILLAR":311,"FLAG_WALLY_SPEECH":193,"FLAG_WATTSON_REMATCH_AVAILABLE":91,"FLAG_WHITEOUT_TO_LAVARIDGE":108,"FLAG_WINGULL_DELIVERED_MAIL":224,"FLAG_WINGULL_SENT_ON_ERRAND":222,"FLAG_WONDER_CARD_UNUSED_1":317,"FLAG_WONDER_CARD_UNUSED_10":326,"FLAG_WONDER_CARD_UNUSED_11":327,"FLAG_WONDER_CARD_UNUSED_12":328,"FLAG_WONDER_CARD_UNUSED_13":329,"FLAG_WONDER_CARD_UNUSED_14":330,"FLAG_WONDER_CARD_UNUSED_15":331,"FLAG_WONDER_CARD_UNUSED_16":332,"FLAG_WONDER_CARD_UNUSED_17":333,"FLAG_WONDER_CARD_UNUSED_2":318,"FLAG_WONDER_CARD_UNUSED_3":319,"FLAG_WONDER_CARD_UNUSED_4":320,"FLAG_WONDER_CARD_UNUSED_5":321,"FLAG_WONDER_CARD_UNUSED_6":322,"FLAG_WONDER_CARD_UNUSED_7":323,"FLAG_WONDER_CARD_UNUSED_8":324,"FLAG_WONDER_CARD_UNUSED_9":325,"FLAVOR_BITTER":3,"FLAVOR_COUNT":5,"FLAVOR_DRY":1,"FLAVOR_SOUR":4,"FLAVOR_SPICY":0,"FLAVOR_SWEET":2,"GOOD_ROD":1,"ITEMS_COUNT":377,"ITEM_034":52,"ITEM_035":53,"ITEM_036":54,"ITEM_037":55,"ITEM_038":56,"ITEM_039":57,"ITEM_03A":58,"ITEM_03B":59,"ITEM_03C":60,"ITEM_03D":61,"ITEM_03E":62,"ITEM_048":72,"ITEM_052":82,"ITEM_057":87,"ITEM_058":88,"ITEM_059":89,"ITEM_05A":90,"ITEM_05B":91,"ITEM_05C":92,"ITEM_063":99,"ITEM_064":100,"ITEM_065":101,"ITEM_066":102,"ITEM_069":105,"ITEM_071":113,"ITEM_072":114,"ITEM_073":115,"ITEM_074":116,"ITEM_075":117,"ITEM_076":118,"ITEM_077":119,"ITEM_078":120,"ITEM_0EA":234,"ITEM_0EB":235,"ITEM_0EC":236,"ITEM_0ED":237,"ITEM_0EE":238,"ITEM_0EF":239,"ITEM_0F0":240,"ITEM_0F1":241,"ITEM_0F2":242,"ITEM_0F3":243,"ITEM_0F4":244,"ITEM_0F5":245,"ITEM_0F6":246,"ITEM_0F7":247,"ITEM_0F8":248,"ITEM_0F9":249,"ITEM_0FA":250,"ITEM_0FB":251,"ITEM_0FC":252,"ITEM_0FD":253,"ITEM_10B":267,"ITEM_15B":347,"ITEM_15C":348,"ITEM_ACRO_BIKE":272,"ITEM_AGUAV_BERRY":146,"ITEM_AMULET_COIN":189,"ITEM_ANTIDOTE":14,"ITEM_APICOT_BERRY":172,"ITEM_ARCHIPELAGO_PROGRESSION":112,"ITEM_ASPEAR_BERRY":137,"ITEM_AURORA_TICKET":371,"ITEM_AWAKENING":17,"ITEM_BADGE_1":226,"ITEM_BADGE_2":227,"ITEM_BADGE_3":228,"ITEM_BADGE_4":229,"ITEM_BADGE_5":230,"ITEM_BADGE_6":231,"ITEM_BADGE_7":232,"ITEM_BADGE_8":233,"ITEM_BASEMENT_KEY":271,"ITEM_BEAD_MAIL":127,"ITEM_BELUE_BERRY":167,"ITEM_BERRY_JUICE":44,"ITEM_BERRY_POUCH":365,"ITEM_BICYCLE":360,"ITEM_BIG_MUSHROOM":104,"ITEM_BIG_PEARL":107,"ITEM_BIKE_VOUCHER":352,"ITEM_BLACK_BELT":207,"ITEM_BLACK_FLUTE":42,"ITEM_BLACK_GLASSES":206,"ITEM_BLUE_FLUTE":39,"ITEM_BLUE_ORB":277,"ITEM_BLUE_SCARF":255,"ITEM_BLUE_SHARD":49,"ITEM_BLUK_BERRY":149,"ITEM_BRIGHT_POWDER":179,"ITEM_BURN_HEAL":15,"ITEM_B_USE_MEDICINE":1,"ITEM_B_USE_OTHER":2,"ITEM_CALCIUM":67,"ITEM_CARBOS":66,"ITEM_CARD_KEY":355,"ITEM_CHARCOAL":215,"ITEM_CHERI_BERRY":133,"ITEM_CHESTO_BERRY":134,"ITEM_CHOICE_BAND":186,"ITEM_CLAW_FOSSIL":287,"ITEM_CLEANSE_TAG":190,"ITEM_COIN_CASE":260,"ITEM_CONTEST_PASS":266,"ITEM_CORNN_BERRY":159,"ITEM_DEEP_SEA_SCALE":193,"ITEM_DEEP_SEA_TOOTH":192,"ITEM_DEVON_GOODS":269,"ITEM_DEVON_SCOPE":288,"ITEM_DIRE_HIT":74,"ITEM_DIVE_BALL":7,"ITEM_DOME_FOSSIL":358,"ITEM_DRAGON_FANG":216,"ITEM_DRAGON_SCALE":201,"ITEM_DREAM_MAIL":130,"ITEM_DURIN_BERRY":166,"ITEM_ELIXIR":36,"ITEM_ENERGY_POWDER":30,"ITEM_ENERGY_ROOT":31,"ITEM_ENIGMA_BERRY":175,"ITEM_EON_TICKET":275,"ITEM_ESCAPE_ROPE":85,"ITEM_ETHER":34,"ITEM_EVERSTONE":195,"ITEM_EXP_SHARE":182,"ITEM_FAB_MAIL":131,"ITEM_FAME_CHECKER":363,"ITEM_FIGY_BERRY":143,"ITEM_FIRE_STONE":95,"ITEM_FLUFFY_TAIL":81,"ITEM_FOCUS_BAND":196,"ITEM_FRESH_WATER":26,"ITEM_FULL_HEAL":23,"ITEM_FULL_RESTORE":19,"ITEM_GANLON_BERRY":169,"ITEM_GLITTER_MAIL":123,"ITEM_GOLD_TEETH":353,"ITEM_GOOD_ROD":263,"ITEM_GO_GOGGLES":279,"ITEM_GREAT_BALL":3,"ITEM_GREEN_SCARF":257,"ITEM_GREEN_SHARD":51,"ITEM_GREPA_BERRY":157,"ITEM_GUARD_SPEC":73,"ITEM_HARBOR_MAIL":122,"ITEM_HARD_STONE":204,"ITEM_HEAL_POWDER":32,"ITEM_HEART_SCALE":111,"ITEM_HELIX_FOSSIL":357,"ITEM_HM01":339,"ITEM_HM02":340,"ITEM_HM03":341,"ITEM_HM04":342,"ITEM_HM05":343,"ITEM_HM06":344,"ITEM_HM07":345,"ITEM_HM08":346,"ITEM_HM_CUT":339,"ITEM_HM_DIVE":346,"ITEM_HM_FLASH":343,"ITEM_HM_FLY":340,"ITEM_HM_ROCK_SMASH":344,"ITEM_HM_STRENGTH":342,"ITEM_HM_SURF":341,"ITEM_HM_WATERFALL":345,"ITEM_HONDEW_BERRY":156,"ITEM_HP_UP":63,"ITEM_HYPER_POTION":21,"ITEM_IAPAPA_BERRY":147,"ITEM_ICE_HEAL":16,"ITEM_IRON":65,"ITEM_ITEMFINDER":261,"ITEM_KELPSY_BERRY":154,"ITEM_KINGS_ROCK":187,"ITEM_LANSAT_BERRY":173,"ITEM_LAVA_COOKIE":38,"ITEM_LAX_INCENSE":221,"ITEM_LEAF_STONE":98,"ITEM_LEFTOVERS":200,"ITEM_LEMONADE":28,"ITEM_LEPPA_BERRY":138,"ITEM_LETTER":274,"ITEM_LIECHI_BERRY":168,"ITEM_LIFT_KEY":356,"ITEM_LIGHT_BALL":202,"ITEM_LIST_END":65535,"ITEM_LUCKY_EGG":197,"ITEM_LUCKY_PUNCH":222,"ITEM_LUM_BERRY":141,"ITEM_LUXURY_BALL":11,"ITEM_MACHO_BRACE":181,"ITEM_MACH_BIKE":259,"ITEM_MAGMA_EMBLEM":375,"ITEM_MAGNET":208,"ITEM_MAGOST_BERRY":160,"ITEM_MAGO_BERRY":145,"ITEM_MASTER_BALL":1,"ITEM_MAX_ELIXIR":37,"ITEM_MAX_ETHER":35,"ITEM_MAX_POTION":20,"ITEM_MAX_REPEL":84,"ITEM_MAX_REVIVE":25,"ITEM_MECH_MAIL":124,"ITEM_MENTAL_HERB":185,"ITEM_METAL_COAT":199,"ITEM_METAL_POWDER":223,"ITEM_METEORITE":280,"ITEM_MIRACLE_SEED":205,"ITEM_MOOMOO_MILK":29,"ITEM_MOON_STONE":94,"ITEM_MYSTIC_TICKET":370,"ITEM_MYSTIC_WATER":209,"ITEM_NANAB_BERRY":150,"ITEM_NEST_BALL":8,"ITEM_NET_BALL":6,"ITEM_NEVER_MELT_ICE":212,"ITEM_NOMEL_BERRY":162,"ITEM_NONE":0,"ITEM_NUGGET":110,"ITEM_OAKS_PARCEL":349,"ITEM_OLD_AMBER":354,"ITEM_OLD_ROD":262,"ITEM_OLD_SEA_MAP":376,"ITEM_ORANGE_MAIL":121,"ITEM_ORAN_BERRY":139,"ITEM_PAMTRE_BERRY":164,"ITEM_PARALYZE_HEAL":18,"ITEM_PEARL":106,"ITEM_PECHA_BERRY":135,"ITEM_PERSIM_BERRY":140,"ITEM_PETAYA_BERRY":171,"ITEM_PINAP_BERRY":152,"ITEM_PINK_SCARF":256,"ITEM_POISON_BARB":211,"ITEM_POKEBLOCK_CASE":273,"ITEM_POKE_BALL":4,"ITEM_POKE_DOLL":80,"ITEM_POKE_FLUTE":350,"ITEM_POMEG_BERRY":153,"ITEM_POTION":13,"ITEM_POWDER_JAR":372,"ITEM_PP_MAX":71,"ITEM_PP_UP":69,"ITEM_PREMIER_BALL":12,"ITEM_PROTEIN":64,"ITEM_QUALOT_BERRY":155,"ITEM_QUICK_CLAW":183,"ITEM_RABUTA_BERRY":161,"ITEM_RAINBOW_PASS":368,"ITEM_RARE_CANDY":68,"ITEM_RAWST_BERRY":136,"ITEM_RAZZ_BERRY":148,"ITEM_RED_FLUTE":41,"ITEM_RED_ORB":276,"ITEM_RED_SCARF":254,"ITEM_RED_SHARD":48,"ITEM_REPEAT_BALL":9,"ITEM_REPEL":86,"ITEM_RETRO_MAIL":132,"ITEM_REVIVAL_HERB":33,"ITEM_REVIVE":24,"ITEM_ROOM_1_KEY":281,"ITEM_ROOM_2_KEY":282,"ITEM_ROOM_4_KEY":283,"ITEM_ROOM_6_KEY":284,"ITEM_ROOT_FOSSIL":286,"ITEM_RUBY":373,"ITEM_SACRED_ASH":45,"ITEM_SAFARI_BALL":5,"ITEM_SALAC_BERRY":170,"ITEM_SAPPHIRE":374,"ITEM_SCANNER":278,"ITEM_SCOPE_LENS":198,"ITEM_SEA_INCENSE":220,"ITEM_SECRET_KEY":351,"ITEM_SHADOW_MAIL":128,"ITEM_SHARP_BEAK":210,"ITEM_SHELL_BELL":219,"ITEM_SHOAL_SALT":46,"ITEM_SHOAL_SHELL":47,"ITEM_SILK_SCARF":217,"ITEM_SILPH_SCOPE":359,"ITEM_SILVER_POWDER":188,"ITEM_SITRUS_BERRY":142,"ITEM_SMOKE_BALL":194,"ITEM_SODA_POP":27,"ITEM_SOFT_SAND":203,"ITEM_SOOTHE_BELL":184,"ITEM_SOOT_SACK":270,"ITEM_SOUL_DEW":191,"ITEM_SPELL_TAG":213,"ITEM_SPELON_BERRY":163,"ITEM_SS_TICKET":265,"ITEM_STARDUST":108,"ITEM_STARF_BERRY":174,"ITEM_STAR_PIECE":109,"ITEM_STICK":225,"ITEM_STORAGE_KEY":285,"ITEM_SUN_STONE":93,"ITEM_SUPER_POTION":22,"ITEM_SUPER_REPEL":83,"ITEM_SUPER_ROD":264,"ITEM_TAMATO_BERRY":158,"ITEM_TEA":369,"ITEM_TEACHY_TV":366,"ITEM_THICK_CLUB":224,"ITEM_THUNDER_STONE":96,"ITEM_TIMER_BALL":10,"ITEM_TINY_MUSHROOM":103,"ITEM_TM01":289,"ITEM_TM02":290,"ITEM_TM03":291,"ITEM_TM04":292,"ITEM_TM05":293,"ITEM_TM06":294,"ITEM_TM07":295,"ITEM_TM08":296,"ITEM_TM09":297,"ITEM_TM10":298,"ITEM_TM11":299,"ITEM_TM12":300,"ITEM_TM13":301,"ITEM_TM14":302,"ITEM_TM15":303,"ITEM_TM16":304,"ITEM_TM17":305,"ITEM_TM18":306,"ITEM_TM19":307,"ITEM_TM20":308,"ITEM_TM21":309,"ITEM_TM22":310,"ITEM_TM23":311,"ITEM_TM24":312,"ITEM_TM25":313,"ITEM_TM26":314,"ITEM_TM27":315,"ITEM_TM28":316,"ITEM_TM29":317,"ITEM_TM30":318,"ITEM_TM31":319,"ITEM_TM32":320,"ITEM_TM33":321,"ITEM_TM34":322,"ITEM_TM35":323,"ITEM_TM36":324,"ITEM_TM37":325,"ITEM_TM38":326,"ITEM_TM39":327,"ITEM_TM40":328,"ITEM_TM41":329,"ITEM_TM42":330,"ITEM_TM43":331,"ITEM_TM44":332,"ITEM_TM45":333,"ITEM_TM46":334,"ITEM_TM47":335,"ITEM_TM48":336,"ITEM_TM49":337,"ITEM_TM50":338,"ITEM_TM_AERIAL_ACE":328,"ITEM_TM_ATTRACT":333,"ITEM_TM_BLIZZARD":302,"ITEM_TM_BRICK_BREAK":319,"ITEM_TM_BULK_UP":296,"ITEM_TM_BULLET_SEED":297,"ITEM_TM_CALM_MIND":292,"ITEM_TM_CASE":364,"ITEM_TM_DIG":316,"ITEM_TM_DOUBLE_TEAM":320,"ITEM_TM_DRAGON_CLAW":290,"ITEM_TM_EARTHQUAKE":314,"ITEM_TM_FACADE":330,"ITEM_TM_FIRE_BLAST":326,"ITEM_TM_FLAMETHROWER":323,"ITEM_TM_FOCUS_PUNCH":289,"ITEM_TM_FRUSTRATION":309,"ITEM_TM_GIGA_DRAIN":307,"ITEM_TM_HAIL":295,"ITEM_TM_HIDDEN_POWER":298,"ITEM_TM_HYPER_BEAM":303,"ITEM_TM_ICE_BEAM":301,"ITEM_TM_IRON_TAIL":311,"ITEM_TM_LIGHT_SCREEN":304,"ITEM_TM_OVERHEAT":338,"ITEM_TM_PROTECT":305,"ITEM_TM_PSYCHIC":317,"ITEM_TM_RAIN_DANCE":306,"ITEM_TM_REFLECT":321,"ITEM_TM_REST":332,"ITEM_TM_RETURN":315,"ITEM_TM_ROAR":293,"ITEM_TM_ROCK_TOMB":327,"ITEM_TM_SAFEGUARD":308,"ITEM_TM_SANDSTORM":325,"ITEM_TM_SECRET_POWER":331,"ITEM_TM_SHADOW_BALL":318,"ITEM_TM_SHOCK_WAVE":322,"ITEM_TM_SKILL_SWAP":336,"ITEM_TM_SLUDGE_BOMB":324,"ITEM_TM_SNATCH":337,"ITEM_TM_SOLAR_BEAM":310,"ITEM_TM_STEEL_WING":335,"ITEM_TM_SUNNY_DAY":299,"ITEM_TM_TAUNT":300,"ITEM_TM_THIEF":334,"ITEM_TM_THUNDER":313,"ITEM_TM_THUNDERBOLT":312,"ITEM_TM_TORMENT":329,"ITEM_TM_TOXIC":294,"ITEM_TM_WATER_PULSE":291,"ITEM_TOWN_MAP":361,"ITEM_TRI_PASS":367,"ITEM_TROPIC_MAIL":129,"ITEM_TWISTED_SPOON":214,"ITEM_ULTRA_BALL":2,"ITEM_UNUSED_BERRY_1":176,"ITEM_UNUSED_BERRY_2":177,"ITEM_UNUSED_BERRY_3":178,"ITEM_UP_GRADE":218,"ITEM_USE_BAG_MENU":4,"ITEM_USE_FIELD":2,"ITEM_USE_MAIL":0,"ITEM_USE_PARTY_MENU":1,"ITEM_USE_PBLOCK_CASE":3,"ITEM_VS_SEEKER":362,"ITEM_WAILMER_PAIL":268,"ITEM_WATER_STONE":97,"ITEM_WATMEL_BERRY":165,"ITEM_WAVE_MAIL":126,"ITEM_WEPEAR_BERRY":151,"ITEM_WHITE_FLUTE":43,"ITEM_WHITE_HERB":180,"ITEM_WIKI_BERRY":144,"ITEM_WOOD_MAIL":125,"ITEM_X_ACCURACY":78,"ITEM_X_ATTACK":75,"ITEM_X_DEFEND":76,"ITEM_X_SPECIAL":79,"ITEM_X_SPEED":77,"ITEM_YELLOW_FLUTE":40,"ITEM_YELLOW_SCARF":258,"ITEM_YELLOW_SHARD":50,"ITEM_ZINC":70,"LAST_BALL":12,"LAST_BERRY_INDEX":175,"LAST_BERRY_MASTER_BERRY":162,"LAST_BERRY_MASTER_WIFE_BERRY":142,"LAST_KIRI_BERRY":162,"LAST_ROUTE_114_MAN_BERRY":152,"MACH_BIKE":0,"MAIL_NONE":255,"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":6207,"MAP_ABANDONED_SHIP_CORRIDORS_1F":6199,"MAP_ABANDONED_SHIP_CORRIDORS_B1F":6201,"MAP_ABANDONED_SHIP_DECK":6198,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":6209,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":6210,"MAP_ABANDONED_SHIP_ROOMS2_1F":6206,"MAP_ABANDONED_SHIP_ROOMS2_B1F":6203,"MAP_ABANDONED_SHIP_ROOMS_1F":6200,"MAP_ABANDONED_SHIP_ROOMS_B1F":6202,"MAP_ABANDONED_SHIP_ROOM_B1F":6205,"MAP_ABANDONED_SHIP_UNDERWATER1":6204,"MAP_ABANDONED_SHIP_UNDERWATER2":6208,"MAP_ALTERING_CAVE":6250,"MAP_ANCIENT_TOMB":6212,"MAP_AQUA_HIDEOUT_1F":6167,"MAP_AQUA_HIDEOUT_B1F":6168,"MAP_AQUA_HIDEOUT_B2F":6169,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":6218,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":6219,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":6220,"MAP_ARTISAN_CAVE_1F":6244,"MAP_ARTISAN_CAVE_B1F":6243,"MAP_BATTLE_COLOSSEUM_2P":6424,"MAP_BATTLE_COLOSSEUM_4P":6427,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":6686,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":6685,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":6684,"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":6677,"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":6675,"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":6674,"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":6676,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":6689,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":6687,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":6688,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":6680,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":6679,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":6678,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":6691,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":6690,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":6694,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":6693,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":6695,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":6692,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":6682,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":6681,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":6683,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":6664,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":6663,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":6662,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":6661,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":6673,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":6672,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":6671,"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":6698,"MAP_BATTLE_FRONTIER_LOUNGE1":6697,"MAP_BATTLE_FRONTIER_LOUNGE2":6699,"MAP_BATTLE_FRONTIER_LOUNGE3":6700,"MAP_BATTLE_FRONTIER_LOUNGE4":6701,"MAP_BATTLE_FRONTIER_LOUNGE5":6703,"MAP_BATTLE_FRONTIER_LOUNGE6":6704,"MAP_BATTLE_FRONTIER_LOUNGE7":6705,"MAP_BATTLE_FRONTIER_LOUNGE8":6707,"MAP_BATTLE_FRONTIER_LOUNGE9":6708,"MAP_BATTLE_FRONTIER_MART":6711,"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":6670,"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":6660,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":6709,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":6710,"MAP_BATTLE_FRONTIER_RANKING_HALL":6696,"MAP_BATTLE_FRONTIER_RECEPTION_GATE":6706,"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":6702,"MAP_BATTLE_PYRAMID_SQUARE01":6444,"MAP_BATTLE_PYRAMID_SQUARE02":6445,"MAP_BATTLE_PYRAMID_SQUARE03":6446,"MAP_BATTLE_PYRAMID_SQUARE04":6447,"MAP_BATTLE_PYRAMID_SQUARE05":6448,"MAP_BATTLE_PYRAMID_SQUARE06":6449,"MAP_BATTLE_PYRAMID_SQUARE07":6450,"MAP_BATTLE_PYRAMID_SQUARE08":6451,"MAP_BATTLE_PYRAMID_SQUARE09":6452,"MAP_BATTLE_PYRAMID_SQUARE10":6453,"MAP_BATTLE_PYRAMID_SQUARE11":6454,"MAP_BATTLE_PYRAMID_SQUARE12":6455,"MAP_BATTLE_PYRAMID_SQUARE13":6456,"MAP_BATTLE_PYRAMID_SQUARE14":6457,"MAP_BATTLE_PYRAMID_SQUARE15":6458,"MAP_BATTLE_PYRAMID_SQUARE16":6459,"MAP_BIRTH_ISLAND_EXTERIOR":6714,"MAP_BIRTH_ISLAND_HARBOR":6715,"MAP_CAVE_OF_ORIGIN_1F":6182,"MAP_CAVE_OF_ORIGIN_B1F":6186,"MAP_CAVE_OF_ORIGIN_ENTRANCE":6181,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":6183,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":6184,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":6185,"MAP_CONTEST_HALL":6428,"MAP_CONTEST_HALL_BEAUTY":6435,"MAP_CONTEST_HALL_COOL":6437,"MAP_CONTEST_HALL_CUTE":6439,"MAP_CONTEST_HALL_SMART":6438,"MAP_CONTEST_HALL_TOUGH":6436,"MAP_DESERT_RUINS":6150,"MAP_DESERT_UNDERPASS":6242,"MAP_DEWFORD_TOWN":11,"MAP_DEWFORD_TOWN_GYM":771,"MAP_DEWFORD_TOWN_HALL":772,"MAP_DEWFORD_TOWN_HOUSE1":768,"MAP_DEWFORD_TOWN_HOUSE2":773,"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":769,"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":770,"MAP_EVER_GRANDE_CITY":8,"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":4100,"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":4099,"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":4098,"MAP_EVER_GRANDE_CITY_HALL1":4101,"MAP_EVER_GRANDE_CITY_HALL2":4102,"MAP_EVER_GRANDE_CITY_HALL3":4103,"MAP_EVER_GRANDE_CITY_HALL4":4104,"MAP_EVER_GRANDE_CITY_HALL5":4105,"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":4107,"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":4097,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":4108,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":4109,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":4106,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":4110,"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":4096,"MAP_FALLARBOR_TOWN":13,"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":1283,"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":1282,"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":1281,"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":1286,"MAP_FALLARBOR_TOWN_MART":1280,"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":1287,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":1284,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":1285,"MAP_FARAWAY_ISLAND_ENTRANCE":6712,"MAP_FARAWAY_ISLAND_INTERIOR":6713,"MAP_FIERY_PATH":6158,"MAP_FORTREE_CITY":4,"MAP_FORTREE_CITY_DECORATION_SHOP":3081,"MAP_FORTREE_CITY_GYM":3073,"MAP_FORTREE_CITY_HOUSE1":3072,"MAP_FORTREE_CITY_HOUSE2":3077,"MAP_FORTREE_CITY_HOUSE3":3078,"MAP_FORTREE_CITY_HOUSE4":3079,"MAP_FORTREE_CITY_HOUSE5":3080,"MAP_FORTREE_CITY_MART":3076,"MAP_FORTREE_CITY_POKEMON_CENTER_1F":3074,"MAP_FORTREE_CITY_POKEMON_CENTER_2F":3075,"MAP_GRANITE_CAVE_1F":6151,"MAP_GRANITE_CAVE_B1F":6152,"MAP_GRANITE_CAVE_B2F":6153,"MAP_GRANITE_CAVE_STEVENS_ROOM":6154,"MAP_GROUPS_COUNT":34,"MAP_INSIDE_OF_TRUCK":6440,"MAP_ISLAND_CAVE":6211,"MAP_JAGGED_PASS":6157,"MAP_LAVARIDGE_TOWN":12,"MAP_LAVARIDGE_TOWN_GYM_1F":1025,"MAP_LAVARIDGE_TOWN_GYM_B1F":1026,"MAP_LAVARIDGE_TOWN_HERB_SHOP":1024,"MAP_LAVARIDGE_TOWN_HOUSE":1027,"MAP_LAVARIDGE_TOWN_MART":1028,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":1029,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":1030,"MAP_LILYCOVE_CITY":5,"MAP_LILYCOVE_CITY_CONTEST_HALL":3333,"MAP_LILYCOVE_CITY_CONTEST_LOBBY":3332,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":3328,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":3329,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":3344,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":3345,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":3346,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":3347,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":3348,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":3350,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":3349,"MAP_LILYCOVE_CITY_HARBOR":3338,"MAP_LILYCOVE_CITY_HOUSE1":3340,"MAP_LILYCOVE_CITY_HOUSE2":3341,"MAP_LILYCOVE_CITY_HOUSE3":3342,"MAP_LILYCOVE_CITY_HOUSE4":3343,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":3330,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":3331,"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":3339,"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":3334,"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":3335,"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":3337,"MAP_LILYCOVE_CITY_UNUSED_MART":3336,"MAP_LITTLEROOT_TOWN":9,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":256,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":257,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":258,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":259,"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":260,"MAP_MAGMA_HIDEOUT_1F":6230,"MAP_MAGMA_HIDEOUT_2F_1R":6231,"MAP_MAGMA_HIDEOUT_2F_2R":6232,"MAP_MAGMA_HIDEOUT_2F_3R":6237,"MAP_MAGMA_HIDEOUT_3F_1R":6233,"MAP_MAGMA_HIDEOUT_3F_2R":6234,"MAP_MAGMA_HIDEOUT_3F_3R":6236,"MAP_MAGMA_HIDEOUT_4F":6235,"MAP_MARINE_CAVE_END":6247,"MAP_MARINE_CAVE_ENTRANCE":6246,"MAP_MAUVILLE_CITY":2,"MAP_MAUVILLE_CITY_BIKE_SHOP":2561,"MAP_MAUVILLE_CITY_GAME_CORNER":2563,"MAP_MAUVILLE_CITY_GYM":2560,"MAP_MAUVILLE_CITY_HOUSE1":2562,"MAP_MAUVILLE_CITY_HOUSE2":2564,"MAP_MAUVILLE_CITY_MART":2567,"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":2565,"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":2566,"MAP_METEOR_FALLS_1F_1R":6144,"MAP_METEOR_FALLS_1F_2R":6145,"MAP_METEOR_FALLS_B1F_1R":6146,"MAP_METEOR_FALLS_B1F_2R":6147,"MAP_METEOR_FALLS_STEVENS_CAVE":6251,"MAP_MIRAGE_TOWER_1F":6238,"MAP_MIRAGE_TOWER_2F":6239,"MAP_MIRAGE_TOWER_3F":6240,"MAP_MIRAGE_TOWER_4F":6241,"MAP_MOSSDEEP_CITY":6,"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":3595,"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":3596,"MAP_MOSSDEEP_CITY_GYM":3584,"MAP_MOSSDEEP_CITY_HOUSE1":3585,"MAP_MOSSDEEP_CITY_HOUSE2":3586,"MAP_MOSSDEEP_CITY_HOUSE3":3590,"MAP_MOSSDEEP_CITY_HOUSE4":3592,"MAP_MOSSDEEP_CITY_MART":3589,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":3587,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":3588,"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":3593,"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":3594,"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":3591,"MAP_MT_CHIMNEY":6156,"MAP_MT_CHIMNEY_CABLE_CAR_STATION":4865,"MAP_MT_PYRE_1F":6159,"MAP_MT_PYRE_2F":6160,"MAP_MT_PYRE_3F":6161,"MAP_MT_PYRE_4F":6162,"MAP_MT_PYRE_5F":6163,"MAP_MT_PYRE_6F":6164,"MAP_MT_PYRE_EXTERIOR":6165,"MAP_MT_PYRE_SUMMIT":6166,"MAP_NAVEL_ROCK_B1F":6725,"MAP_NAVEL_ROCK_BOTTOM":6743,"MAP_NAVEL_ROCK_DOWN01":6732,"MAP_NAVEL_ROCK_DOWN02":6733,"MAP_NAVEL_ROCK_DOWN03":6734,"MAP_NAVEL_ROCK_DOWN04":6735,"MAP_NAVEL_ROCK_DOWN05":6736,"MAP_NAVEL_ROCK_DOWN06":6737,"MAP_NAVEL_ROCK_DOWN07":6738,"MAP_NAVEL_ROCK_DOWN08":6739,"MAP_NAVEL_ROCK_DOWN09":6740,"MAP_NAVEL_ROCK_DOWN10":6741,"MAP_NAVEL_ROCK_DOWN11":6742,"MAP_NAVEL_ROCK_ENTRANCE":6724,"MAP_NAVEL_ROCK_EXTERIOR":6722,"MAP_NAVEL_ROCK_FORK":6726,"MAP_NAVEL_ROCK_HARBOR":6723,"MAP_NAVEL_ROCK_TOP":6731,"MAP_NAVEL_ROCK_UP1":6727,"MAP_NAVEL_ROCK_UP2":6728,"MAP_NAVEL_ROCK_UP3":6729,"MAP_NAVEL_ROCK_UP4":6730,"MAP_NEW_MAUVILLE_ENTRANCE":6196,"MAP_NEW_MAUVILLE_INSIDE":6197,"MAP_OLDALE_TOWN":10,"MAP_OLDALE_TOWN_HOUSE1":512,"MAP_OLDALE_TOWN_HOUSE2":513,"MAP_OLDALE_TOWN_MART":516,"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":514,"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":515,"MAP_PACIFIDLOG_TOWN":15,"MAP_PACIFIDLOG_TOWN_HOUSE1":1794,"MAP_PACIFIDLOG_TOWN_HOUSE2":1795,"MAP_PACIFIDLOG_TOWN_HOUSE3":1796,"MAP_PACIFIDLOG_TOWN_HOUSE4":1797,"MAP_PACIFIDLOG_TOWN_HOUSE5":1798,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":1792,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":1793,"MAP_PETALBURG_CITY":0,"MAP_PETALBURG_CITY_GYM":2049,"MAP_PETALBURG_CITY_HOUSE1":2050,"MAP_PETALBURG_CITY_HOUSE2":2051,"MAP_PETALBURG_CITY_MART":2054,"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":2052,"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":2053,"MAP_PETALBURG_CITY_WALLYS_HOUSE":2048,"MAP_PETALBURG_WOODS":6155,"MAP_RECORD_CORNER":6426,"MAP_ROUTE101":16,"MAP_ROUTE102":17,"MAP_ROUTE103":18,"MAP_ROUTE104":19,"MAP_ROUTE104_MR_BRINEYS_HOUSE":4352,"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":4353,"MAP_ROUTE104_PROTOTYPE":6912,"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":6913,"MAP_ROUTE105":20,"MAP_ROUTE106":21,"MAP_ROUTE107":22,"MAP_ROUTE108":23,"MAP_ROUTE109":24,"MAP_ROUTE109_SEASHORE_HOUSE":7168,"MAP_ROUTE110":25,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":7435,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":7436,"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":7426,"MAP_ROUTE110_TRICK_HOUSE_END":7425,"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":7424,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":7427,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":7428,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":7429,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":7430,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":7431,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":7432,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":7433,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":7434,"MAP_ROUTE111":26,"MAP_ROUTE111_OLD_LADYS_REST_STOP":4609,"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":4608,"MAP_ROUTE112":27,"MAP_ROUTE112_CABLE_CAR_STATION":4864,"MAP_ROUTE113":28,"MAP_ROUTE113_GLASS_WORKSHOP":7680,"MAP_ROUTE114":29,"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":5120,"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":5121,"MAP_ROUTE114_LANETTES_HOUSE":5122,"MAP_ROUTE115":30,"MAP_ROUTE116":31,"MAP_ROUTE116_TUNNELERS_REST_HOUSE":5376,"MAP_ROUTE117":32,"MAP_ROUTE117_POKEMON_DAY_CARE":5632,"MAP_ROUTE118":33,"MAP_ROUTE119":34,"MAP_ROUTE119_HOUSE":8194,"MAP_ROUTE119_WEATHER_INSTITUTE_1F":8192,"MAP_ROUTE119_WEATHER_INSTITUTE_2F":8193,"MAP_ROUTE120":35,"MAP_ROUTE121":36,"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":5888,"MAP_ROUTE122":37,"MAP_ROUTE123":38,"MAP_ROUTE123_BERRY_MASTERS_HOUSE":7936,"MAP_ROUTE124":39,"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":8448,"MAP_ROUTE125":40,"MAP_ROUTE126":41,"MAP_ROUTE127":42,"MAP_ROUTE128":43,"MAP_ROUTE129":44,"MAP_ROUTE130":45,"MAP_ROUTE131":46,"MAP_ROUTE132":47,"MAP_ROUTE133":48,"MAP_ROUTE134":49,"MAP_RUSTBORO_CITY":3,"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":2827,"MAP_RUSTBORO_CITY_DEVON_CORP_1F":2816,"MAP_RUSTBORO_CITY_DEVON_CORP_2F":2817,"MAP_RUSTBORO_CITY_DEVON_CORP_3F":2818,"MAP_RUSTBORO_CITY_FLAT1_1F":2824,"MAP_RUSTBORO_CITY_FLAT1_2F":2825,"MAP_RUSTBORO_CITY_FLAT2_1F":2829,"MAP_RUSTBORO_CITY_FLAT2_2F":2830,"MAP_RUSTBORO_CITY_FLAT2_3F":2831,"MAP_RUSTBORO_CITY_GYM":2819,"MAP_RUSTBORO_CITY_HOUSE1":2826,"MAP_RUSTBORO_CITY_HOUSE2":2828,"MAP_RUSTBORO_CITY_HOUSE3":2832,"MAP_RUSTBORO_CITY_MART":2823,"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":2821,"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":2822,"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":2820,"MAP_RUSTURF_TUNNEL":6148,"MAP_SAFARI_ZONE_NORTH":6657,"MAP_SAFARI_ZONE_NORTHEAST":6668,"MAP_SAFARI_ZONE_NORTHWEST":6656,"MAP_SAFARI_ZONE_REST_HOUSE":6667,"MAP_SAFARI_ZONE_SOUTH":6659,"MAP_SAFARI_ZONE_SOUTHEAST":6669,"MAP_SAFARI_ZONE_SOUTHWEST":6658,"MAP_SCORCHED_SLAB":6217,"MAP_SEAFLOOR_CAVERN_ENTRANCE":6171,"MAP_SEAFLOOR_CAVERN_ROOM1":6172,"MAP_SEAFLOOR_CAVERN_ROOM2":6173,"MAP_SEAFLOOR_CAVERN_ROOM3":6174,"MAP_SEAFLOOR_CAVERN_ROOM4":6175,"MAP_SEAFLOOR_CAVERN_ROOM5":6176,"MAP_SEAFLOOR_CAVERN_ROOM6":6177,"MAP_SEAFLOOR_CAVERN_ROOM7":6178,"MAP_SEAFLOOR_CAVERN_ROOM8":6179,"MAP_SEAFLOOR_CAVERN_ROOM9":6180,"MAP_SEALED_CHAMBER_INNER_ROOM":6216,"MAP_SEALED_CHAMBER_OUTER_ROOM":6215,"MAP_SECRET_BASE_BLUE_CAVE1":6402,"MAP_SECRET_BASE_BLUE_CAVE2":6408,"MAP_SECRET_BASE_BLUE_CAVE3":6414,"MAP_SECRET_BASE_BLUE_CAVE4":6420,"MAP_SECRET_BASE_BROWN_CAVE1":6401,"MAP_SECRET_BASE_BROWN_CAVE2":6407,"MAP_SECRET_BASE_BROWN_CAVE3":6413,"MAP_SECRET_BASE_BROWN_CAVE4":6419,"MAP_SECRET_BASE_RED_CAVE1":6400,"MAP_SECRET_BASE_RED_CAVE2":6406,"MAP_SECRET_BASE_RED_CAVE3":6412,"MAP_SECRET_BASE_RED_CAVE4":6418,"MAP_SECRET_BASE_SHRUB1":6405,"MAP_SECRET_BASE_SHRUB2":6411,"MAP_SECRET_BASE_SHRUB3":6417,"MAP_SECRET_BASE_SHRUB4":6423,"MAP_SECRET_BASE_TREE1":6404,"MAP_SECRET_BASE_TREE2":6410,"MAP_SECRET_BASE_TREE3":6416,"MAP_SECRET_BASE_TREE4":6422,"MAP_SECRET_BASE_YELLOW_CAVE1":6403,"MAP_SECRET_BASE_YELLOW_CAVE2":6409,"MAP_SECRET_BASE_YELLOW_CAVE3":6415,"MAP_SECRET_BASE_YELLOW_CAVE4":6421,"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":6194,"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":6195,"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":6190,"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":6227,"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":6191,"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":6193,"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":6192,"MAP_SKY_PILLAR_1F":6223,"MAP_SKY_PILLAR_2F":6224,"MAP_SKY_PILLAR_3F":6225,"MAP_SKY_PILLAR_4F":6226,"MAP_SKY_PILLAR_5F":6228,"MAP_SKY_PILLAR_ENTRANCE":6221,"MAP_SKY_PILLAR_OUTSIDE":6222,"MAP_SKY_PILLAR_TOP":6229,"MAP_SLATEPORT_CITY":1,"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":2308,"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":2307,"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":2306,"MAP_SLATEPORT_CITY_HARBOR":2313,"MAP_SLATEPORT_CITY_HOUSE":2314,"MAP_SLATEPORT_CITY_MART":2317,"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":2309,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":2311,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":2312,"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":2315,"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":2316,"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":2310,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":2304,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":2305,"MAP_SOOTOPOLIS_CITY":7,"MAP_SOOTOPOLIS_CITY_GYM_1F":3840,"MAP_SOOTOPOLIS_CITY_GYM_B1F":3841,"MAP_SOOTOPOLIS_CITY_HOUSE1":3845,"MAP_SOOTOPOLIS_CITY_HOUSE2":3846,"MAP_SOOTOPOLIS_CITY_HOUSE3":3847,"MAP_SOOTOPOLIS_CITY_HOUSE4":3848,"MAP_SOOTOPOLIS_CITY_HOUSE5":3849,"MAP_SOOTOPOLIS_CITY_HOUSE6":3850,"MAP_SOOTOPOLIS_CITY_HOUSE7":3851,"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":3852,"MAP_SOOTOPOLIS_CITY_MART":3844,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":3853,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":3854,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":3842,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":3843,"MAP_SOUTHERN_ISLAND_EXTERIOR":6665,"MAP_SOUTHERN_ISLAND_INTERIOR":6666,"MAP_SS_TIDAL_CORRIDOR":6441,"MAP_SS_TIDAL_LOWER_DECK":6442,"MAP_SS_TIDAL_ROOMS":6443,"MAP_TERRA_CAVE_END":6249,"MAP_TERRA_CAVE_ENTRANCE":6248,"MAP_TRADE_CENTER":6425,"MAP_TRAINER_HILL_1F":6717,"MAP_TRAINER_HILL_2F":6718,"MAP_TRAINER_HILL_3F":6719,"MAP_TRAINER_HILL_4F":6720,"MAP_TRAINER_HILL_ELEVATOR":6744,"MAP_TRAINER_HILL_ENTRANCE":6716,"MAP_TRAINER_HILL_ROOF":6721,"MAP_UNDERWATER_MARINE_CAVE":6245,"MAP_UNDERWATER_ROUTE105":55,"MAP_UNDERWATER_ROUTE124":50,"MAP_UNDERWATER_ROUTE125":56,"MAP_UNDERWATER_ROUTE126":51,"MAP_UNDERWATER_ROUTE127":52,"MAP_UNDERWATER_ROUTE128":53,"MAP_UNDERWATER_ROUTE129":54,"MAP_UNDERWATER_ROUTE134":6213,"MAP_UNDERWATER_SEAFLOOR_CAVERN":6170,"MAP_UNDERWATER_SEALED_CHAMBER":6214,"MAP_UNDERWATER_SOOTOPOLIS_CITY":6149,"MAP_UNION_ROOM":6460,"MAP_UNUSED_CONTEST_HALL1":6429,"MAP_UNUSED_CONTEST_HALL2":6430,"MAP_UNUSED_CONTEST_HALL3":6431,"MAP_UNUSED_CONTEST_HALL4":6432,"MAP_UNUSED_CONTEST_HALL5":6433,"MAP_UNUSED_CONTEST_HALL6":6434,"MAP_VERDANTURF_TOWN":14,"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":1538,"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":1537,"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":1536,"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":1543,"MAP_VERDANTURF_TOWN_HOUSE":1544,"MAP_VERDANTURF_TOWN_MART":1539,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":1540,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":1541,"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":1542,"MAP_VICTORY_ROAD_1F":6187,"MAP_VICTORY_ROAD_B1F":6188,"MAP_VICTORY_ROAD_B2F":6189,"MAX_BAG_ITEM_CAPACITY":99,"MAX_BERRY_CAPACITY":999,"MAX_BERRY_INDEX":178,"MAX_ITEM_DIGITS":3,"MAX_PC_ITEM_CAPACITY":999,"MAX_TRAINERS_COUNT":864,"MOVES_COUNT":355,"MOVE_ABSORB":71,"MOVE_ACID":51,"MOVE_ACID_ARMOR":151,"MOVE_AERIAL_ACE":332,"MOVE_AEROBLAST":177,"MOVE_AGILITY":97,"MOVE_AIR_CUTTER":314,"MOVE_AMNESIA":133,"MOVE_ANCIENT_POWER":246,"MOVE_ARM_THRUST":292,"MOVE_AROMATHERAPY":312,"MOVE_ASSIST":274,"MOVE_ASTONISH":310,"MOVE_ATTRACT":213,"MOVE_AURORA_BEAM":62,"MOVE_BARRAGE":140,"MOVE_BARRIER":112,"MOVE_BATON_PASS":226,"MOVE_BEAT_UP":251,"MOVE_BELLY_DRUM":187,"MOVE_BIDE":117,"MOVE_BIND":20,"MOVE_BITE":44,"MOVE_BLAST_BURN":307,"MOVE_BLAZE_KICK":299,"MOVE_BLIZZARD":59,"MOVE_BLOCK":335,"MOVE_BODY_SLAM":34,"MOVE_BONEMERANG":155,"MOVE_BONE_CLUB":125,"MOVE_BONE_RUSH":198,"MOVE_BOUNCE":340,"MOVE_BRICK_BREAK":280,"MOVE_BUBBLE":145,"MOVE_BUBBLE_BEAM":61,"MOVE_BULK_UP":339,"MOVE_BULLET_SEED":331,"MOVE_CALM_MIND":347,"MOVE_CAMOUFLAGE":293,"MOVE_CHARGE":268,"MOVE_CHARM":204,"MOVE_CLAMP":128,"MOVE_COMET_PUNCH":4,"MOVE_CONFUSE_RAY":109,"MOVE_CONFUSION":93,"MOVE_CONSTRICT":132,"MOVE_CONVERSION":160,"MOVE_CONVERSION_2":176,"MOVE_COSMIC_POWER":322,"MOVE_COTTON_SPORE":178,"MOVE_COUNTER":68,"MOVE_COVET":343,"MOVE_CRABHAMMER":152,"MOVE_CROSS_CHOP":238,"MOVE_CRUNCH":242,"MOVE_CRUSH_CLAW":306,"MOVE_CURSE":174,"MOVE_CUT":15,"MOVE_DEFENSE_CURL":111,"MOVE_DESTINY_BOND":194,"MOVE_DETECT":197,"MOVE_DIG":91,"MOVE_DISABLE":50,"MOVE_DIVE":291,"MOVE_DIZZY_PUNCH":146,"MOVE_DOOM_DESIRE":353,"MOVE_DOUBLE_EDGE":38,"MOVE_DOUBLE_KICK":24,"MOVE_DOUBLE_SLAP":3,"MOVE_DOUBLE_TEAM":104,"MOVE_DRAGON_BREATH":225,"MOVE_DRAGON_CLAW":337,"MOVE_DRAGON_DANCE":349,"MOVE_DRAGON_RAGE":82,"MOVE_DREAM_EATER":138,"MOVE_DRILL_PECK":65,"MOVE_DYNAMIC_PUNCH":223,"MOVE_EARTHQUAKE":89,"MOVE_EGG_BOMB":121,"MOVE_EMBER":52,"MOVE_ENCORE":227,"MOVE_ENDEAVOR":283,"MOVE_ENDURE":203,"MOVE_ERUPTION":284,"MOVE_EXPLOSION":153,"MOVE_EXTRASENSORY":326,"MOVE_EXTREME_SPEED":245,"MOVE_FACADE":263,"MOVE_FAINT_ATTACK":185,"MOVE_FAKE_OUT":252,"MOVE_FAKE_TEARS":313,"MOVE_FALSE_SWIPE":206,"MOVE_FEATHER_DANCE":297,"MOVE_FIRE_BLAST":126,"MOVE_FIRE_PUNCH":7,"MOVE_FIRE_SPIN":83,"MOVE_FISSURE":90,"MOVE_FLAIL":175,"MOVE_FLAMETHROWER":53,"MOVE_FLAME_WHEEL":172,"MOVE_FLASH":148,"MOVE_FLATTER":260,"MOVE_FLY":19,"MOVE_FOCUS_ENERGY":116,"MOVE_FOCUS_PUNCH":264,"MOVE_FOLLOW_ME":266,"MOVE_FORESIGHT":193,"MOVE_FRENZY_PLANT":338,"MOVE_FRUSTRATION":218,"MOVE_FURY_ATTACK":31,"MOVE_FURY_CUTTER":210,"MOVE_FURY_SWIPES":154,"MOVE_FUTURE_SIGHT":248,"MOVE_GIGA_DRAIN":202,"MOVE_GLARE":137,"MOVE_GRASS_WHISTLE":320,"MOVE_GROWL":45,"MOVE_GROWTH":74,"MOVE_GRUDGE":288,"MOVE_GUILLOTINE":12,"MOVE_GUST":16,"MOVE_HAIL":258,"MOVE_HARDEN":106,"MOVE_HAZE":114,"MOVE_HEADBUTT":29,"MOVE_HEAL_BELL":215,"MOVE_HEAT_WAVE":257,"MOVE_HELPING_HAND":270,"MOVE_HIDDEN_POWER":237,"MOVE_HI_JUMP_KICK":136,"MOVE_HORN_ATTACK":30,"MOVE_HORN_DRILL":32,"MOVE_HOWL":336,"MOVE_HYDRO_CANNON":308,"MOVE_HYDRO_PUMP":56,"MOVE_HYPER_BEAM":63,"MOVE_HYPER_FANG":158,"MOVE_HYPER_VOICE":304,"MOVE_HYPNOSIS":95,"MOVE_ICE_BALL":301,"MOVE_ICE_BEAM":58,"MOVE_ICE_PUNCH":8,"MOVE_ICICLE_SPEAR":333,"MOVE_ICY_WIND":196,"MOVE_IMPRISON":286,"MOVE_INGRAIN":275,"MOVE_IRON_DEFENSE":334,"MOVE_IRON_TAIL":231,"MOVE_JUMP_KICK":26,"MOVE_KARATE_CHOP":2,"MOVE_KINESIS":134,"MOVE_KNOCK_OFF":282,"MOVE_LEAF_BLADE":348,"MOVE_LEECH_LIFE":141,"MOVE_LEECH_SEED":73,"MOVE_LEER":43,"MOVE_LICK":122,"MOVE_LIGHT_SCREEN":113,"MOVE_LOCK_ON":199,"MOVE_LOVELY_KISS":142,"MOVE_LOW_KICK":67,"MOVE_LUSTER_PURGE":295,"MOVE_MACH_PUNCH":183,"MOVE_MAGICAL_LEAF":345,"MOVE_MAGIC_COAT":277,"MOVE_MAGNITUDE":222,"MOVE_MEAN_LOOK":212,"MOVE_MEDITATE":96,"MOVE_MEGAHORN":224,"MOVE_MEGA_DRAIN":72,"MOVE_MEGA_KICK":25,"MOVE_MEGA_PUNCH":5,"MOVE_MEMENTO":262,"MOVE_METAL_CLAW":232,"MOVE_METAL_SOUND":319,"MOVE_METEOR_MASH":309,"MOVE_METRONOME":118,"MOVE_MILK_DRINK":208,"MOVE_MIMIC":102,"MOVE_MIND_READER":170,"MOVE_MINIMIZE":107,"MOVE_MIRROR_COAT":243,"MOVE_MIRROR_MOVE":119,"MOVE_MIST":54,"MOVE_MIST_BALL":296,"MOVE_MOONLIGHT":236,"MOVE_MORNING_SUN":234,"MOVE_MUDDY_WATER":330,"MOVE_MUD_SHOT":341,"MOVE_MUD_SLAP":189,"MOVE_MUD_SPORT":300,"MOVE_NATURE_POWER":267,"MOVE_NEEDLE_ARM":302,"MOVE_NIGHTMARE":171,"MOVE_NIGHT_SHADE":101,"MOVE_NONE":0,"MOVE_OCTAZOOKA":190,"MOVE_ODOR_SLEUTH":316,"MOVE_OUTRAGE":200,"MOVE_OVERHEAT":315,"MOVE_PAIN_SPLIT":220,"MOVE_PAY_DAY":6,"MOVE_PECK":64,"MOVE_PERISH_SONG":195,"MOVE_PETAL_DANCE":80,"MOVE_PIN_MISSILE":42,"MOVE_POISON_FANG":305,"MOVE_POISON_GAS":139,"MOVE_POISON_POWDER":77,"MOVE_POISON_STING":40,"MOVE_POISON_TAIL":342,"MOVE_POUND":1,"MOVE_POWDER_SNOW":181,"MOVE_PRESENT":217,"MOVE_PROTECT":182,"MOVE_PSYBEAM":60,"MOVE_PSYCHIC":94,"MOVE_PSYCHO_BOOST":354,"MOVE_PSYCH_UP":244,"MOVE_PSYWAVE":149,"MOVE_PURSUIT":228,"MOVE_QUICK_ATTACK":98,"MOVE_RAGE":99,"MOVE_RAIN_DANCE":240,"MOVE_RAPID_SPIN":229,"MOVE_RAZOR_LEAF":75,"MOVE_RAZOR_WIND":13,"MOVE_RECOVER":105,"MOVE_RECYCLE":278,"MOVE_REFLECT":115,"MOVE_REFRESH":287,"MOVE_REST":156,"MOVE_RETURN":216,"MOVE_REVENGE":279,"MOVE_REVERSAL":179,"MOVE_ROAR":46,"MOVE_ROCK_BLAST":350,"MOVE_ROCK_SLIDE":157,"MOVE_ROCK_SMASH":249,"MOVE_ROCK_THROW":88,"MOVE_ROCK_TOMB":317,"MOVE_ROLE_PLAY":272,"MOVE_ROLLING_KICK":27,"MOVE_ROLLOUT":205,"MOVE_SACRED_FIRE":221,"MOVE_SAFEGUARD":219,"MOVE_SANDSTORM":201,"MOVE_SAND_ATTACK":28,"MOVE_SAND_TOMB":328,"MOVE_SCARY_FACE":184,"MOVE_SCRATCH":10,"MOVE_SCREECH":103,"MOVE_SECRET_POWER":290,"MOVE_SEISMIC_TOSS":69,"MOVE_SELF_DESTRUCT":120,"MOVE_SHADOW_BALL":247,"MOVE_SHADOW_PUNCH":325,"MOVE_SHARPEN":159,"MOVE_SHEER_COLD":329,"MOVE_SHOCK_WAVE":351,"MOVE_SIGNAL_BEAM":324,"MOVE_SILVER_WIND":318,"MOVE_SING":47,"MOVE_SKETCH":166,"MOVE_SKILL_SWAP":285,"MOVE_SKULL_BASH":130,"MOVE_SKY_ATTACK":143,"MOVE_SKY_UPPERCUT":327,"MOVE_SLACK_OFF":303,"MOVE_SLAM":21,"MOVE_SLASH":163,"MOVE_SLEEP_POWDER":79,"MOVE_SLEEP_TALK":214,"MOVE_SLUDGE":124,"MOVE_SLUDGE_BOMB":188,"MOVE_SMELLING_SALT":265,"MOVE_SMOG":123,"MOVE_SMOKESCREEN":108,"MOVE_SNATCH":289,"MOVE_SNORE":173,"MOVE_SOFT_BOILED":135,"MOVE_SOLAR_BEAM":76,"MOVE_SONIC_BOOM":49,"MOVE_SPARK":209,"MOVE_SPIDER_WEB":169,"MOVE_SPIKES":191,"MOVE_SPIKE_CANNON":131,"MOVE_SPITE":180,"MOVE_SPIT_UP":255,"MOVE_SPLASH":150,"MOVE_SPORE":147,"MOVE_STEEL_WING":211,"MOVE_STOCKPILE":254,"MOVE_STOMP":23,"MOVE_STRENGTH":70,"MOVE_STRING_SHOT":81,"MOVE_STRUGGLE":165,"MOVE_STUN_SPORE":78,"MOVE_SUBMISSION":66,"MOVE_SUBSTITUTE":164,"MOVE_SUNNY_DAY":241,"MOVE_SUPERPOWER":276,"MOVE_SUPERSONIC":48,"MOVE_SUPER_FANG":162,"MOVE_SURF":57,"MOVE_SWAGGER":207,"MOVE_SWALLOW":256,"MOVE_SWEET_KISS":186,"MOVE_SWEET_SCENT":230,"MOVE_SWIFT":129,"MOVE_SWORDS_DANCE":14,"MOVE_SYNTHESIS":235,"MOVE_TACKLE":33,"MOVE_TAIL_GLOW":294,"MOVE_TAIL_WHIP":39,"MOVE_TAKE_DOWN":36,"MOVE_TAUNT":269,"MOVE_TEETER_DANCE":298,"MOVE_TELEPORT":100,"MOVE_THIEF":168,"MOVE_THRASH":37,"MOVE_THUNDER":87,"MOVE_THUNDERBOLT":85,"MOVE_THUNDER_PUNCH":9,"MOVE_THUNDER_SHOCK":84,"MOVE_THUNDER_WAVE":86,"MOVE_TICKLE":321,"MOVE_TORMENT":259,"MOVE_TOXIC":92,"MOVE_TRANSFORM":144,"MOVE_TRICK":271,"MOVE_TRIPLE_KICK":167,"MOVE_TRI_ATTACK":161,"MOVE_TWINEEDLE":41,"MOVE_TWISTER":239,"MOVE_UNAVAILABLE":65535,"MOVE_UPROAR":253,"MOVE_VICE_GRIP":11,"MOVE_VINE_WHIP":22,"MOVE_VITAL_THROW":233,"MOVE_VOLT_TACKLE":344,"MOVE_WATERFALL":127,"MOVE_WATER_GUN":55,"MOVE_WATER_PULSE":352,"MOVE_WATER_SPORT":346,"MOVE_WATER_SPOUT":323,"MOVE_WEATHER_BALL":311,"MOVE_WHIRLPOOL":250,"MOVE_WHIRLWIND":18,"MOVE_WILL_O_WISP":261,"MOVE_WING_ATTACK":17,"MOVE_WISH":273,"MOVE_WITHDRAW":110,"MOVE_WRAP":35,"MOVE_YAWN":281,"MOVE_ZAP_CANNON":192,"MUS_ABANDONED_SHIP":381,"MUS_ABNORMAL_WEATHER":443,"MUS_AQUA_MAGMA_HIDEOUT":430,"MUS_AWAKEN_LEGEND":388,"MUS_BIRCH_LAB":383,"MUS_B_ARENA":458,"MUS_B_DOME":467,"MUS_B_DOME_LOBBY":473,"MUS_B_FACTORY":469,"MUS_B_FRONTIER":457,"MUS_B_PALACE":463,"MUS_B_PIKE":468,"MUS_B_PYRAMID":461,"MUS_B_PYRAMID_TOP":462,"MUS_B_TOWER":465,"MUS_B_TOWER_RS":384,"MUS_CABLE_CAR":425,"MUS_CAUGHT":352,"MUS_CAVE_OF_ORIGIN":386,"MUS_CONTEST":440,"MUS_CONTEST_LOBBY":452,"MUS_CONTEST_RESULTS":446,"MUS_CONTEST_WINNER":439,"MUS_CREDITS":455,"MUS_CYCLING":403,"MUS_C_COMM_CENTER":356,"MUS_C_VS_LEGEND_BEAST":358,"MUS_DESERT":409,"MUS_DEWFORD":427,"MUS_DUMMY":0,"MUS_ENCOUNTER_AQUA":419,"MUS_ENCOUNTER_BRENDAN":421,"MUS_ENCOUNTER_CHAMPION":454,"MUS_ENCOUNTER_COOL":417,"MUS_ENCOUNTER_ELITE_FOUR":450,"MUS_ENCOUNTER_FEMALE":407,"MUS_ENCOUNTER_GIRL":379,"MUS_ENCOUNTER_HIKER":451,"MUS_ENCOUNTER_INTENSE":416,"MUS_ENCOUNTER_INTERVIEWER":453,"MUS_ENCOUNTER_MAGMA":441,"MUS_ENCOUNTER_MALE":380,"MUS_ENCOUNTER_MAY":415,"MUS_ENCOUNTER_RICH":397,"MUS_ENCOUNTER_SUSPICIOUS":423,"MUS_ENCOUNTER_SWIMMER":385,"MUS_ENCOUNTER_TWINS":449,"MUS_END":456,"MUS_EVER_GRANDE":422,"MUS_EVOLUTION":377,"MUS_EVOLUTION_INTRO":376,"MUS_EVOLVED":371,"MUS_FALLARBOR":437,"MUS_FOLLOW_ME":420,"MUS_FORTREE":382,"MUS_GAME_CORNER":426,"MUS_GSC_PEWTER":357,"MUS_GSC_ROUTE38":351,"MUS_GYM":364,"MUS_HALL_OF_FAME":436,"MUS_HALL_OF_FAME_ROOM":447,"MUS_HEAL":368,"MUS_HELP":410,"MUS_INTRO":414,"MUS_INTRO_BATTLE":442,"MUS_LEVEL_UP":367,"MUS_LILYCOVE":408,"MUS_LILYCOVE_MUSEUM":373,"MUS_LINK_CONTEST_P1":393,"MUS_LINK_CONTEST_P2":394,"MUS_LINK_CONTEST_P3":395,"MUS_LINK_CONTEST_P4":396,"MUS_LITTLEROOT":405,"MUS_LITTLEROOT_TEST":350,"MUS_MOVE_DELETED":378,"MUS_MT_CHIMNEY":406,"MUS_MT_PYRE":432,"MUS_MT_PYRE_EXTERIOR":434,"MUS_NONE":65535,"MUS_OBTAIN_BADGE":369,"MUS_OBTAIN_BERRY":387,"MUS_OBTAIN_B_POINTS":459,"MUS_OBTAIN_ITEM":370,"MUS_OBTAIN_SYMBOL":466,"MUS_OBTAIN_TMHM":372,"MUS_OCEANIC_MUSEUM":375,"MUS_OLDALE":363,"MUS_PETALBURG":362,"MUS_PETALBURG_WOODS":366,"MUS_POKE_CENTER":400,"MUS_POKE_MART":404,"MUS_RAYQUAZA_APPEARS":464,"MUS_REGISTER_MATCH_CALL":460,"MUS_RG_BERRY_PICK":542,"MUS_RG_CAUGHT":534,"MUS_RG_CAUGHT_INTRO":531,"MUS_RG_CELADON":521,"MUS_RG_CINNABAR":491,"MUS_RG_CREDITS":502,"MUS_RG_CYCLING":494,"MUS_RG_DEX_RATING":529,"MUS_RG_ENCOUNTER_BOY":497,"MUS_RG_ENCOUNTER_DEOXYS":555,"MUS_RG_ENCOUNTER_GIRL":496,"MUS_RG_ENCOUNTER_GYM_LEADER":554,"MUS_RG_ENCOUNTER_RIVAL":527,"MUS_RG_ENCOUNTER_ROCKET":495,"MUS_RG_FOLLOW_ME":484,"MUS_RG_FUCHSIA":520,"MUS_RG_GAME_CORNER":485,"MUS_RG_GAME_FREAK":533,"MUS_RG_GYM":487,"MUS_RG_HALL_OF_FAME":498,"MUS_RG_HEAL":493,"MUS_RG_INTRO_FIGHT":489,"MUS_RG_JIGGLYPUFF":488,"MUS_RG_LAVENDER":492,"MUS_RG_MT_MOON":500,"MUS_RG_MYSTERY_GIFT":541,"MUS_RG_NET_CENTER":540,"MUS_RG_NEW_GAME_EXIT":537,"MUS_RG_NEW_GAME_INSTRUCT":535,"MUS_RG_NEW_GAME_INTRO":536,"MUS_RG_OAK":514,"MUS_RG_OAK_LAB":513,"MUS_RG_OBTAIN_KEY_ITEM":530,"MUS_RG_PALLET":512,"MUS_RG_PEWTER":526,"MUS_RG_PHOTO":532,"MUS_RG_POKE_CENTER":515,"MUS_RG_POKE_FLUTE":550,"MUS_RG_POKE_JUMP":538,"MUS_RG_POKE_MANSION":501,"MUS_RG_POKE_TOWER":518,"MUS_RG_RIVAL_EXIT":528,"MUS_RG_ROCKET_HIDEOUT":486,"MUS_RG_ROUTE1":503,"MUS_RG_ROUTE11":506,"MUS_RG_ROUTE24":504,"MUS_RG_ROUTE3":505,"MUS_RG_SEVII_123":547,"MUS_RG_SEVII_45":548,"MUS_RG_SEVII_67":549,"MUS_RG_SEVII_CAVE":543,"MUS_RG_SEVII_DUNGEON":546,"MUS_RG_SEVII_ROUTE":545,"MUS_RG_SILPH":519,"MUS_RG_SLOW_PALLET":557,"MUS_RG_SS_ANNE":516,"MUS_RG_SURF":517,"MUS_RG_TEACHY_TV_MENU":558,"MUS_RG_TEACHY_TV_SHOW":544,"MUS_RG_TITLE":490,"MUS_RG_TRAINER_TOWER":556,"MUS_RG_UNION_ROOM":539,"MUS_RG_VERMILLION":525,"MUS_RG_VICTORY_GYM_LEADER":524,"MUS_RG_VICTORY_ROAD":507,"MUS_RG_VICTORY_TRAINER":522,"MUS_RG_VICTORY_WILD":523,"MUS_RG_VIRIDIAN_FOREST":499,"MUS_RG_VS_CHAMPION":511,"MUS_RG_VS_DEOXYS":551,"MUS_RG_VS_GYM_LEADER":508,"MUS_RG_VS_LEGEND":553,"MUS_RG_VS_MEWTWO":552,"MUS_RG_VS_TRAINER":509,"MUS_RG_VS_WILD":510,"MUS_ROULETTE":392,"MUS_ROUTE101":359,"MUS_ROUTE104":401,"MUS_ROUTE110":360,"MUS_ROUTE113":418,"MUS_ROUTE118":32767,"MUS_ROUTE119":402,"MUS_ROUTE120":361,"MUS_ROUTE122":374,"MUS_RUSTBORO":399,"MUS_SAFARI_ZONE":428,"MUS_SAILING":431,"MUS_SCHOOL":435,"MUS_SEALED_CHAMBER":438,"MUS_SLATEPORT":433,"MUS_SLOTS_JACKPOT":389,"MUS_SLOTS_WIN":390,"MUS_SOOTOPOLIS":445,"MUS_SURF":365,"MUS_TITLE":413,"MUS_TOO_BAD":391,"MUS_TRICK_HOUSE":448,"MUS_UNDERWATER":411,"MUS_VERDANTURF":398,"MUS_VICTORY_AQUA_MAGMA":424,"MUS_VICTORY_GYM_LEADER":354,"MUS_VICTORY_LEAGUE":355,"MUS_VICTORY_ROAD":429,"MUS_VICTORY_TRAINER":412,"MUS_VICTORY_WILD":353,"MUS_VS_AQUA_MAGMA":475,"MUS_VS_AQUA_MAGMA_LEADER":483,"MUS_VS_CHAMPION":478,"MUS_VS_ELITE_FOUR":482,"MUS_VS_FRONTIER_BRAIN":471,"MUS_VS_GYM_LEADER":477,"MUS_VS_KYOGRE_GROUDON":480,"MUS_VS_MEW":472,"MUS_VS_RAYQUAZA":470,"MUS_VS_REGI":479,"MUS_VS_RIVAL":481,"MUS_VS_TRAINER":476,"MUS_VS_WILD":474,"MUS_WEATHER_GROUDON":444,"NUM_BADGES":8,"NUM_BERRY_MASTER_BERRIES":10,"NUM_BERRY_MASTER_BERRIES_SKIPPED":20,"NUM_BERRY_MASTER_WIFE_BERRIES":10,"NUM_DAILY_FLAGS":64,"NUM_HIDDEN_MACHINES":8,"NUM_KIRI_BERRIES":10,"NUM_KIRI_BERRIES_SKIPPED":20,"NUM_ROUTE_114_MAN_BERRIES":5,"NUM_ROUTE_114_MAN_BERRIES_SKIPPED":15,"NUM_SPECIAL_FLAGS":128,"NUM_SPECIES":412,"NUM_TECHNICAL_MACHINES":50,"NUM_TEMP_FLAGS":32,"NUM_WATER_STAGES":4,"NUM_WONDER_CARD_FLAGS":20,"OLD_ROD":0,"PH_CHOICE_BLEND":589,"PH_CHOICE_HELD":590,"PH_CHOICE_SOLO":591,"PH_CLOTH_BLEND":565,"PH_CLOTH_HELD":566,"PH_CLOTH_SOLO":567,"PH_CURE_BLEND":604,"PH_CURE_HELD":605,"PH_CURE_SOLO":606,"PH_DRESS_BLEND":568,"PH_DRESS_HELD":569,"PH_DRESS_SOLO":570,"PH_FACE_BLEND":562,"PH_FACE_HELD":563,"PH_FACE_SOLO":564,"PH_FLEECE_BLEND":571,"PH_FLEECE_HELD":572,"PH_FLEECE_SOLO":573,"PH_FOOT_BLEND":595,"PH_FOOT_HELD":596,"PH_FOOT_SOLO":597,"PH_GOAT_BLEND":583,"PH_GOAT_HELD":584,"PH_GOAT_SOLO":585,"PH_GOOSE_BLEND":598,"PH_GOOSE_HELD":599,"PH_GOOSE_SOLO":600,"PH_KIT_BLEND":574,"PH_KIT_HELD":575,"PH_KIT_SOLO":576,"PH_LOT_BLEND":580,"PH_LOT_HELD":581,"PH_LOT_SOLO":582,"PH_MOUTH_BLEND":592,"PH_MOUTH_HELD":593,"PH_MOUTH_SOLO":594,"PH_NURSE_BLEND":607,"PH_NURSE_HELD":608,"PH_NURSE_SOLO":609,"PH_PRICE_BLEND":577,"PH_PRICE_HELD":578,"PH_PRICE_SOLO":579,"PH_STRUT_BLEND":601,"PH_STRUT_HELD":602,"PH_STRUT_SOLO":603,"PH_THOUGHT_BLEND":586,"PH_THOUGHT_HELD":587,"PH_THOUGHT_SOLO":588,"PH_TRAP_BLEND":559,"PH_TRAP_HELD":560,"PH_TRAP_SOLO":561,"SE_A":25,"SE_APPLAUSE":105,"SE_ARENA_TIMEUP1":265,"SE_ARENA_TIMEUP2":266,"SE_BALL":23,"SE_BALLOON_BLUE":75,"SE_BALLOON_RED":74,"SE_BALLOON_YELLOW":76,"SE_BALL_BOUNCE_1":56,"SE_BALL_BOUNCE_2":57,"SE_BALL_BOUNCE_3":58,"SE_BALL_BOUNCE_4":59,"SE_BALL_OPEN":15,"SE_BALL_THROW":61,"SE_BALL_TRADE":60,"SE_BALL_TRAY_BALL":115,"SE_BALL_TRAY_ENTER":114,"SE_BALL_TRAY_EXIT":116,"SE_BANG":20,"SE_BERRY_BLENDER":53,"SE_BIKE_BELL":11,"SE_BIKE_HOP":34,"SE_BOO":22,"SE_BREAKABLE_DOOR":77,"SE_BRIDGE_WALK":71,"SE_CARD":54,"SE_CLICK":36,"SE_CONTEST_CONDITION_LOSE":38,"SE_CONTEST_CURTAIN_FALL":98,"SE_CONTEST_CURTAIN_RISE":97,"SE_CONTEST_HEART":96,"SE_CONTEST_ICON_CHANGE":99,"SE_CONTEST_ICON_CLEAR":100,"SE_CONTEST_MONS_TURN":101,"SE_CONTEST_PLACE":24,"SE_DEX_PAGE":109,"SE_DEX_SCROLL":108,"SE_DEX_SEARCH":112,"SE_DING_DONG":73,"SE_DOOR":8,"SE_DOWNPOUR":83,"SE_DOWNPOUR_STOP":84,"SE_E":28,"SE_EFFECTIVE":13,"SE_EGG_HATCH":113,"SE_ELEVATOR":89,"SE_ESCALATOR":80,"SE_EXIT":9,"SE_EXP":33,"SE_EXP_MAX":91,"SE_FAILURE":32,"SE_FAINT":16,"SE_FALL":43,"SE_FIELD_POISON":79,"SE_FLEE":17,"SE_FU_ZAKU":37,"SE_GLASS_FLUTE":117,"SE_I":26,"SE_ICE_BREAK":41,"SE_ICE_CRACK":42,"SE_ICE_STAIRS":40,"SE_INTRO_BLAST":103,"SE_ITEMFINDER":72,"SE_LAVARIDGE_FALL_WARP":39,"SE_LEDGE":10,"SE_LOW_HEALTH":90,"SE_MUD_BALL":78,"SE_MUGSHOT":104,"SE_M_ABSORB":180,"SE_M_ABSORB_2":179,"SE_M_ACID_ARMOR":218,"SE_M_ATTRACT":226,"SE_M_ATTRACT2":227,"SE_M_BARRIER":208,"SE_M_BATON_PASS":224,"SE_M_BELLY_DRUM":185,"SE_M_BIND":170,"SE_M_BITE":161,"SE_M_BLIZZARD":153,"SE_M_BLIZZARD2":154,"SE_M_BONEMERANG":187,"SE_M_BRICK_BREAK":198,"SE_M_BUBBLE":124,"SE_M_BUBBLE2":125,"SE_M_BUBBLE3":126,"SE_M_BUBBLE_BEAM":182,"SE_M_BUBBLE_BEAM2":183,"SE_M_CHARGE":213,"SE_M_CHARM":212,"SE_M_COMET_PUNCH":139,"SE_M_CONFUSE_RAY":196,"SE_M_COSMIC_POWER":243,"SE_M_CRABHAMMER":142,"SE_M_CUT":128,"SE_M_DETECT":209,"SE_M_DIG":175,"SE_M_DIVE":233,"SE_M_DIZZY_PUNCH":176,"SE_M_DOUBLE_SLAP":134,"SE_M_DOUBLE_TEAM":135,"SE_M_DRAGON_RAGE":171,"SE_M_EARTHQUAKE":234,"SE_M_EMBER":151,"SE_M_ENCORE":222,"SE_M_ENCORE2":223,"SE_M_EXPLOSION":178,"SE_M_FAINT_ATTACK":190,"SE_M_FIRE_PUNCH":147,"SE_M_FLAMETHROWER":146,"SE_M_FLAME_WHEEL":144,"SE_M_FLAME_WHEEL2":145,"SE_M_FLATTER":229,"SE_M_FLY":158,"SE_M_GIGA_DRAIN":199,"SE_M_GRASSWHISTLE":231,"SE_M_GUST":132,"SE_M_GUST2":133,"SE_M_HAIL":242,"SE_M_HARDEN":120,"SE_M_HAZE":246,"SE_M_HEADBUTT":162,"SE_M_HEAL_BELL":195,"SE_M_HEAT_WAVE":240,"SE_M_HORN_ATTACK":166,"SE_M_HYDRO_PUMP":164,"SE_M_HYPER_BEAM":215,"SE_M_HYPER_BEAM2":247,"SE_M_ICY_WIND":137,"SE_M_JUMP_KICK":143,"SE_M_LEER":192,"SE_M_LICK":188,"SE_M_LOCK_ON":210,"SE_M_MEGA_KICK":140,"SE_M_MEGA_KICK2":141,"SE_M_METRONOME":186,"SE_M_MILK_DRINK":225,"SE_M_MINIMIZE":204,"SE_M_MIST":168,"SE_M_MOONLIGHT":211,"SE_M_MORNING_SUN":228,"SE_M_NIGHTMARE":121,"SE_M_PAY_DAY":174,"SE_M_PERISH_SONG":173,"SE_M_PETAL_DANCE":202,"SE_M_POISON_POWDER":169,"SE_M_PSYBEAM":189,"SE_M_PSYBEAM2":200,"SE_M_RAIN_DANCE":127,"SE_M_RAZOR_WIND":136,"SE_M_RAZOR_WIND2":160,"SE_M_REFLECT":207,"SE_M_REVERSAL":217,"SE_M_ROCK_THROW":131,"SE_M_SACRED_FIRE":149,"SE_M_SACRED_FIRE2":150,"SE_M_SANDSTORM":219,"SE_M_SAND_ATTACK":159,"SE_M_SAND_TOMB":230,"SE_M_SCRATCH":155,"SE_M_SCREECH":181,"SE_M_SELF_DESTRUCT":177,"SE_M_SING":172,"SE_M_SKETCH":205,"SE_M_SKY_UPPERCUT":238,"SE_M_SNORE":197,"SE_M_SOLAR_BEAM":201,"SE_M_SPIT_UP":232,"SE_M_STAT_DECREASE":245,"SE_M_STAT_INCREASE":239,"SE_M_STRENGTH":214,"SE_M_STRING_SHOT":129,"SE_M_STRING_SHOT2":130,"SE_M_SUPERSONIC":184,"SE_M_SURF":163,"SE_M_SWAGGER":193,"SE_M_SWAGGER2":194,"SE_M_SWEET_SCENT":236,"SE_M_SWIFT":206,"SE_M_SWORDS_DANCE":191,"SE_M_TAIL_WHIP":167,"SE_M_TAKE_DOWN":152,"SE_M_TEETER_DANCE":244,"SE_M_TELEPORT":203,"SE_M_THUNDERBOLT":118,"SE_M_THUNDERBOLT2":119,"SE_M_THUNDER_WAVE":138,"SE_M_TOXIC":148,"SE_M_TRI_ATTACK":220,"SE_M_TRI_ATTACK2":221,"SE_M_TWISTER":235,"SE_M_UPROAR":241,"SE_M_VICEGRIP":156,"SE_M_VITAL_THROW":122,"SE_M_VITAL_THROW2":123,"SE_M_WATERFALL":216,"SE_M_WHIRLPOOL":165,"SE_M_WING_ATTACK":157,"SE_M_YAWN":237,"SE_N":30,"SE_NOTE_A":67,"SE_NOTE_B":68,"SE_NOTE_C":62,"SE_NOTE_C_HIGH":69,"SE_NOTE_D":63,"SE_NOTE_E":64,"SE_NOTE_F":65,"SE_NOTE_G":66,"SE_NOT_EFFECTIVE":12,"SE_O":29,"SE_ORB":107,"SE_PC_LOGIN":2,"SE_PC_OFF":3,"SE_PC_ON":4,"SE_PIKE_CURTAIN_CLOSE":267,"SE_PIKE_CURTAIN_OPEN":268,"SE_PIN":21,"SE_POKENAV_CALL":263,"SE_POKENAV_HANG_UP":264,"SE_POKENAV_OFF":111,"SE_POKENAV_ON":110,"SE_PUDDLE":70,"SE_RAIN":85,"SE_RAIN_STOP":86,"SE_REPEL":47,"SE_RG_BAG_CURSOR":252,"SE_RG_BAG_POCKET":253,"SE_RG_BALL_CLICK":254,"SE_RG_CARD_FLIP":249,"SE_RG_CARD_FLIPPING":250,"SE_RG_CARD_OPEN":251,"SE_RG_DEOXYS_MOVE":260,"SE_RG_DOOR":248,"SE_RG_HELP_CLOSE":258,"SE_RG_HELP_ERROR":259,"SE_RG_HELP_OPEN":257,"SE_RG_POKE_JUMP_FAILURE":262,"SE_RG_POKE_JUMP_SUCCESS":261,"SE_RG_SHOP":255,"SE_RG_SS_ANNE_HORN":256,"SE_ROTATING_GATE":48,"SE_ROULETTE_BALL":92,"SE_ROULETTE_BALL2":93,"SE_SAVE":55,"SE_SELECT":5,"SE_SHINY":102,"SE_SHIP":19,"SE_SHOP":95,"SE_SLIDING_DOOR":18,"SE_SUCCESS":31,"SE_SUDOWOODO_SHAKE":269,"SE_SUPER_EFFECTIVE":14,"SE_SWITCH":35,"SE_TAILLOW_WING_FLAP":94,"SE_THUNDER":87,"SE_THUNDER2":88,"SE_THUNDERSTORM":81,"SE_THUNDERSTORM_STOP":82,"SE_TRUCK_DOOR":52,"SE_TRUCK_MOVE":49,"SE_TRUCK_STOP":50,"SE_TRUCK_UNLOAD":51,"SE_U":27,"SE_UNLOCK":44,"SE_USE_ITEM":1,"SE_VEND":106,"SE_WALL_HIT":7,"SE_WARP_IN":45,"SE_WARP_OUT":46,"SE_WIN_OPEN":6,"SPECIAL_FLAGS_END":16511,"SPECIAL_FLAGS_START":16384,"SPECIES_ABRA":63,"SPECIES_ABSOL":376,"SPECIES_AERODACTYL":142,"SPECIES_AGGRON":384,"SPECIES_AIPOM":190,"SPECIES_ALAKAZAM":65,"SPECIES_ALTARIA":359,"SPECIES_AMPHAROS":181,"SPECIES_ANORITH":390,"SPECIES_ARBOK":24,"SPECIES_ARCANINE":59,"SPECIES_ARIADOS":168,"SPECIES_ARMALDO":391,"SPECIES_ARON":382,"SPECIES_ARTICUNO":144,"SPECIES_AZUMARILL":184,"SPECIES_AZURILL":350,"SPECIES_BAGON":395,"SPECIES_BALTOY":318,"SPECIES_BANETTE":378,"SPECIES_BARBOACH":323,"SPECIES_BAYLEEF":153,"SPECIES_BEAUTIFLY":292,"SPECIES_BEEDRILL":15,"SPECIES_BELDUM":398,"SPECIES_BELLOSSOM":182,"SPECIES_BELLSPROUT":69,"SPECIES_BLASTOISE":9,"SPECIES_BLAZIKEN":282,"SPECIES_BLISSEY":242,"SPECIES_BRELOOM":307,"SPECIES_BULBASAUR":1,"SPECIES_BUTTERFREE":12,"SPECIES_CACNEA":344,"SPECIES_CACTURNE":345,"SPECIES_CAMERUPT":340,"SPECIES_CARVANHA":330,"SPECIES_CASCOON":293,"SPECIES_CASTFORM":385,"SPECIES_CATERPIE":10,"SPECIES_CELEBI":251,"SPECIES_CHANSEY":113,"SPECIES_CHARIZARD":6,"SPECIES_CHARMANDER":4,"SPECIES_CHARMELEON":5,"SPECIES_CHIKORITA":152,"SPECIES_CHIMECHO":411,"SPECIES_CHINCHOU":170,"SPECIES_CLAMPERL":373,"SPECIES_CLAYDOL":319,"SPECIES_CLEFABLE":36,"SPECIES_CLEFAIRY":35,"SPECIES_CLEFFA":173,"SPECIES_CLOYSTER":91,"SPECIES_COMBUSKEN":281,"SPECIES_CORPHISH":326,"SPECIES_CORSOLA":222,"SPECIES_CRADILY":389,"SPECIES_CRAWDAUNT":327,"SPECIES_CROBAT":169,"SPECIES_CROCONAW":159,"SPECIES_CUBONE":104,"SPECIES_CYNDAQUIL":155,"SPECIES_DELCATTY":316,"SPECIES_DELIBIRD":225,"SPECIES_DEOXYS":410,"SPECIES_DEWGONG":87,"SPECIES_DIGLETT":50,"SPECIES_DITTO":132,"SPECIES_DODRIO":85,"SPECIES_DODUO":84,"SPECIES_DONPHAN":232,"SPECIES_DRAGONAIR":148,"SPECIES_DRAGONITE":149,"SPECIES_DRATINI":147,"SPECIES_DROWZEE":96,"SPECIES_DUGTRIO":51,"SPECIES_DUNSPARCE":206,"SPECIES_DUSCLOPS":362,"SPECIES_DUSKULL":361,"SPECIES_DUSTOX":294,"SPECIES_EEVEE":133,"SPECIES_EGG":412,"SPECIES_EKANS":23,"SPECIES_ELECTABUZZ":125,"SPECIES_ELECTRIKE":337,"SPECIES_ELECTRODE":101,"SPECIES_ELEKID":239,"SPECIES_ENTEI":244,"SPECIES_ESPEON":196,"SPECIES_EXEGGCUTE":102,"SPECIES_EXEGGUTOR":103,"SPECIES_EXPLOUD":372,"SPECIES_FARFETCHD":83,"SPECIES_FEAROW":22,"SPECIES_FEEBAS":328,"SPECIES_FERALIGATR":160,"SPECIES_FLAAFFY":180,"SPECIES_FLAREON":136,"SPECIES_FLYGON":334,"SPECIES_FORRETRESS":205,"SPECIES_FURRET":162,"SPECIES_GARDEVOIR":394,"SPECIES_GASTLY":92,"SPECIES_GENGAR":94,"SPECIES_GEODUDE":74,"SPECIES_GIRAFARIG":203,"SPECIES_GLALIE":347,"SPECIES_GLIGAR":207,"SPECIES_GLOOM":44,"SPECIES_GOLBAT":42,"SPECIES_GOLDEEN":118,"SPECIES_GOLDUCK":55,"SPECIES_GOLEM":76,"SPECIES_GOREBYSS":375,"SPECIES_GRANBULL":210,"SPECIES_GRAVELER":75,"SPECIES_GRIMER":88,"SPECIES_GROUDON":405,"SPECIES_GROVYLE":278,"SPECIES_GROWLITHE":58,"SPECIES_GRUMPIG":352,"SPECIES_GULPIN":367,"SPECIES_GYARADOS":130,"SPECIES_HARIYAMA":336,"SPECIES_HAUNTER":93,"SPECIES_HERACROSS":214,"SPECIES_HITMONCHAN":107,"SPECIES_HITMONLEE":106,"SPECIES_HITMONTOP":237,"SPECIES_HOOTHOOT":163,"SPECIES_HOPPIP":187,"SPECIES_HORSEA":116,"SPECIES_HOUNDOOM":229,"SPECIES_HOUNDOUR":228,"SPECIES_HO_OH":250,"SPECIES_HUNTAIL":374,"SPECIES_HYPNO":97,"SPECIES_IGGLYBUFF":174,"SPECIES_ILLUMISE":387,"SPECIES_IVYSAUR":2,"SPECIES_JIGGLYPUFF":39,"SPECIES_JIRACHI":409,"SPECIES_JOLTEON":135,"SPECIES_JUMPLUFF":189,"SPECIES_JYNX":124,"SPECIES_KABUTO":140,"SPECIES_KABUTOPS":141,"SPECIES_KADABRA":64,"SPECIES_KAKUNA":14,"SPECIES_KANGASKHAN":115,"SPECIES_KECLEON":317,"SPECIES_KINGDRA":230,"SPECIES_KINGLER":99,"SPECIES_KIRLIA":393,"SPECIES_KOFFING":109,"SPECIES_KRABBY":98,"SPECIES_KYOGRE":404,"SPECIES_LAIRON":383,"SPECIES_LANTURN":171,"SPECIES_LAPRAS":131,"SPECIES_LARVITAR":246,"SPECIES_LATIAS":407,"SPECIES_LATIOS":408,"SPECIES_LEDIAN":166,"SPECIES_LEDYBA":165,"SPECIES_LICKITUNG":108,"SPECIES_LILEEP":388,"SPECIES_LINOONE":289,"SPECIES_LOMBRE":296,"SPECIES_LOTAD":295,"SPECIES_LOUDRED":371,"SPECIES_LUDICOLO":297,"SPECIES_LUGIA":249,"SPECIES_LUNATONE":348,"SPECIES_LUVDISC":325,"SPECIES_MACHAMP":68,"SPECIES_MACHOKE":67,"SPECIES_MACHOP":66,"SPECIES_MAGBY":240,"SPECIES_MAGCARGO":219,"SPECIES_MAGIKARP":129,"SPECIES_MAGMAR":126,"SPECIES_MAGNEMITE":81,"SPECIES_MAGNETON":82,"SPECIES_MAKUHITA":335,"SPECIES_MANECTRIC":338,"SPECIES_MANKEY":56,"SPECIES_MANTINE":226,"SPECIES_MAREEP":179,"SPECIES_MARILL":183,"SPECIES_MAROWAK":105,"SPECIES_MARSHTOMP":284,"SPECIES_MASQUERAIN":312,"SPECIES_MAWILE":355,"SPECIES_MEDICHAM":357,"SPECIES_MEDITITE":356,"SPECIES_MEGANIUM":154,"SPECIES_MEOWTH":52,"SPECIES_METAGROSS":400,"SPECIES_METANG":399,"SPECIES_METAPOD":11,"SPECIES_MEW":151,"SPECIES_MEWTWO":150,"SPECIES_MIGHTYENA":287,"SPECIES_MILOTIC":329,"SPECIES_MILTANK":241,"SPECIES_MINUN":354,"SPECIES_MISDREAVUS":200,"SPECIES_MOLTRES":146,"SPECIES_MR_MIME":122,"SPECIES_MUDKIP":283,"SPECIES_MUK":89,"SPECIES_MURKROW":198,"SPECIES_NATU":177,"SPECIES_NIDOKING":34,"SPECIES_NIDOQUEEN":31,"SPECIES_NIDORAN_F":29,"SPECIES_NIDORAN_M":32,"SPECIES_NIDORINA":30,"SPECIES_NIDORINO":33,"SPECIES_NINCADA":301,"SPECIES_NINETALES":38,"SPECIES_NINJASK":302,"SPECIES_NOCTOWL":164,"SPECIES_NONE":0,"SPECIES_NOSEPASS":320,"SPECIES_NUMEL":339,"SPECIES_NUZLEAF":299,"SPECIES_OCTILLERY":224,"SPECIES_ODDISH":43,"SPECIES_OLD_UNOWN_B":252,"SPECIES_OLD_UNOWN_C":253,"SPECIES_OLD_UNOWN_D":254,"SPECIES_OLD_UNOWN_E":255,"SPECIES_OLD_UNOWN_F":256,"SPECIES_OLD_UNOWN_G":257,"SPECIES_OLD_UNOWN_H":258,"SPECIES_OLD_UNOWN_I":259,"SPECIES_OLD_UNOWN_J":260,"SPECIES_OLD_UNOWN_K":261,"SPECIES_OLD_UNOWN_L":262,"SPECIES_OLD_UNOWN_M":263,"SPECIES_OLD_UNOWN_N":264,"SPECIES_OLD_UNOWN_O":265,"SPECIES_OLD_UNOWN_P":266,"SPECIES_OLD_UNOWN_Q":267,"SPECIES_OLD_UNOWN_R":268,"SPECIES_OLD_UNOWN_S":269,"SPECIES_OLD_UNOWN_T":270,"SPECIES_OLD_UNOWN_U":271,"SPECIES_OLD_UNOWN_V":272,"SPECIES_OLD_UNOWN_W":273,"SPECIES_OLD_UNOWN_X":274,"SPECIES_OLD_UNOWN_Y":275,"SPECIES_OLD_UNOWN_Z":276,"SPECIES_OMANYTE":138,"SPECIES_OMASTAR":139,"SPECIES_ONIX":95,"SPECIES_PARAS":46,"SPECIES_PARASECT":47,"SPECIES_PELIPPER":310,"SPECIES_PERSIAN":53,"SPECIES_PHANPY":231,"SPECIES_PICHU":172,"SPECIES_PIDGEOT":18,"SPECIES_PIDGEOTTO":17,"SPECIES_PIDGEY":16,"SPECIES_PIKACHU":25,"SPECIES_PILOSWINE":221,"SPECIES_PINECO":204,"SPECIES_PINSIR":127,"SPECIES_PLUSLE":353,"SPECIES_POLITOED":186,"SPECIES_POLIWAG":60,"SPECIES_POLIWHIRL":61,"SPECIES_POLIWRATH":62,"SPECIES_PONYTA":77,"SPECIES_POOCHYENA":286,"SPECIES_PORYGON":137,"SPECIES_PORYGON2":233,"SPECIES_PRIMEAPE":57,"SPECIES_PSYDUCK":54,"SPECIES_PUPITAR":247,"SPECIES_QUAGSIRE":195,"SPECIES_QUILAVA":156,"SPECIES_QWILFISH":211,"SPECIES_RAICHU":26,"SPECIES_RAIKOU":243,"SPECIES_RALTS":392,"SPECIES_RAPIDASH":78,"SPECIES_RATICATE":20,"SPECIES_RATTATA":19,"SPECIES_RAYQUAZA":406,"SPECIES_REGICE":402,"SPECIES_REGIROCK":401,"SPECIES_REGISTEEL":403,"SPECIES_RELICANTH":381,"SPECIES_REMORAID":223,"SPECIES_RHYDON":112,"SPECIES_RHYHORN":111,"SPECIES_ROSELIA":363,"SPECIES_SABLEYE":322,"SPECIES_SALAMENCE":397,"SPECIES_SANDSHREW":27,"SPECIES_SANDSLASH":28,"SPECIES_SCEPTILE":279,"SPECIES_SCIZOR":212,"SPECIES_SCYTHER":123,"SPECIES_SEADRA":117,"SPECIES_SEAKING":119,"SPECIES_SEALEO":342,"SPECIES_SEEDOT":298,"SPECIES_SEEL":86,"SPECIES_SENTRET":161,"SPECIES_SEVIPER":379,"SPECIES_SHARPEDO":331,"SPECIES_SHEDINJA":303,"SPECIES_SHELGON":396,"SPECIES_SHELLDER":90,"SPECIES_SHIFTRY":300,"SPECIES_SHROOMISH":306,"SPECIES_SHUCKLE":213,"SPECIES_SHUPPET":377,"SPECIES_SILCOON":291,"SPECIES_SKARMORY":227,"SPECIES_SKIPLOOM":188,"SPECIES_SKITTY":315,"SPECIES_SLAKING":366,"SPECIES_SLAKOTH":364,"SPECIES_SLOWBRO":80,"SPECIES_SLOWKING":199,"SPECIES_SLOWPOKE":79,"SPECIES_SLUGMA":218,"SPECIES_SMEARGLE":235,"SPECIES_SMOOCHUM":238,"SPECIES_SNEASEL":215,"SPECIES_SNORLAX":143,"SPECIES_SNORUNT":346,"SPECIES_SNUBBULL":209,"SPECIES_SOLROCK":349,"SPECIES_SPEAROW":21,"SPECIES_SPHEAL":341,"SPECIES_SPINARAK":167,"SPECIES_SPINDA":308,"SPECIES_SPOINK":351,"SPECIES_SQUIRTLE":7,"SPECIES_STANTLER":234,"SPECIES_STARMIE":121,"SPECIES_STARYU":120,"SPECIES_STEELIX":208,"SPECIES_SUDOWOODO":185,"SPECIES_SUICUNE":245,"SPECIES_SUNFLORA":192,"SPECIES_SUNKERN":191,"SPECIES_SURSKIT":311,"SPECIES_SWABLU":358,"SPECIES_SWALOT":368,"SPECIES_SWAMPERT":285,"SPECIES_SWELLOW":305,"SPECIES_SWINUB":220,"SPECIES_TAILLOW":304,"SPECIES_TANGELA":114,"SPECIES_TAUROS":128,"SPECIES_TEDDIURSA":216,"SPECIES_TENTACOOL":72,"SPECIES_TENTACRUEL":73,"SPECIES_TOGEPI":175,"SPECIES_TOGETIC":176,"SPECIES_TORCHIC":280,"SPECIES_TORKOAL":321,"SPECIES_TOTODILE":158,"SPECIES_TRAPINCH":332,"SPECIES_TREECKO":277,"SPECIES_TROPIUS":369,"SPECIES_TYPHLOSION":157,"SPECIES_TYRANITAR":248,"SPECIES_TYROGUE":236,"SPECIES_UMBREON":197,"SPECIES_UNOWN":201,"SPECIES_UNOWN_B":413,"SPECIES_UNOWN_C":414,"SPECIES_UNOWN_D":415,"SPECIES_UNOWN_E":416,"SPECIES_UNOWN_EMARK":438,"SPECIES_UNOWN_F":417,"SPECIES_UNOWN_G":418,"SPECIES_UNOWN_H":419,"SPECIES_UNOWN_I":420,"SPECIES_UNOWN_J":421,"SPECIES_UNOWN_K":422,"SPECIES_UNOWN_L":423,"SPECIES_UNOWN_M":424,"SPECIES_UNOWN_N":425,"SPECIES_UNOWN_O":426,"SPECIES_UNOWN_P":427,"SPECIES_UNOWN_Q":428,"SPECIES_UNOWN_QMARK":439,"SPECIES_UNOWN_R":429,"SPECIES_UNOWN_S":430,"SPECIES_UNOWN_T":431,"SPECIES_UNOWN_U":432,"SPECIES_UNOWN_V":433,"SPECIES_UNOWN_W":434,"SPECIES_UNOWN_X":435,"SPECIES_UNOWN_Y":436,"SPECIES_UNOWN_Z":437,"SPECIES_URSARING":217,"SPECIES_VAPOREON":134,"SPECIES_VENOMOTH":49,"SPECIES_VENONAT":48,"SPECIES_VENUSAUR":3,"SPECIES_VIBRAVA":333,"SPECIES_VICTREEBEL":71,"SPECIES_VIGOROTH":365,"SPECIES_VILEPLUME":45,"SPECIES_VOLBEAT":386,"SPECIES_VOLTORB":100,"SPECIES_VULPIX":37,"SPECIES_WAILMER":313,"SPECIES_WAILORD":314,"SPECIES_WALREIN":343,"SPECIES_WARTORTLE":8,"SPECIES_WEEDLE":13,"SPECIES_WEEPINBELL":70,"SPECIES_WEEZING":110,"SPECIES_WHISCASH":324,"SPECIES_WHISMUR":370,"SPECIES_WIGGLYTUFF":40,"SPECIES_WINGULL":309,"SPECIES_WOBBUFFET":202,"SPECIES_WOOPER":194,"SPECIES_WURMPLE":290,"SPECIES_WYNAUT":360,"SPECIES_XATU":178,"SPECIES_YANMA":193,"SPECIES_ZANGOOSE":380,"SPECIES_ZAPDOS":145,"SPECIES_ZIGZAGOON":288,"SPECIES_ZUBAT":41,"SUPER_ROD":2,"SYSTEM_FLAGS":2144,"TEMP_FLAGS_END":31,"TEMP_FLAGS_START":0,"TRAINERS_COUNT":855,"TRAINER_AARON":397,"TRAINER_ABIGAIL_1":358,"TRAINER_ABIGAIL_2":360,"TRAINER_ABIGAIL_3":361,"TRAINER_ABIGAIL_4":362,"TRAINER_ABIGAIL_5":363,"TRAINER_AIDAN":674,"TRAINER_AISHA":757,"TRAINER_ALAN":630,"TRAINER_ALBERT":80,"TRAINER_ALBERTO":12,"TRAINER_ALEX":413,"TRAINER_ALEXA":670,"TRAINER_ALEXIA":90,"TRAINER_ALEXIS":248,"TRAINER_ALICE":448,"TRAINER_ALIX":750,"TRAINER_ALLEN":333,"TRAINER_ALLISON":387,"TRAINER_ALVARO":849,"TRAINER_ALYSSA":701,"TRAINER_AMY_AND_LIV_1":481,"TRAINER_AMY_AND_LIV_2":482,"TRAINER_AMY_AND_LIV_3":485,"TRAINER_AMY_AND_LIV_4":487,"TRAINER_AMY_AND_LIV_5":488,"TRAINER_AMY_AND_LIV_6":489,"TRAINER_ANABEL":805,"TRAINER_ANDREA":613,"TRAINER_ANDRES_1":737,"TRAINER_ANDRES_2":812,"TRAINER_ANDRES_3":813,"TRAINER_ANDRES_4":814,"TRAINER_ANDRES_5":815,"TRAINER_ANDREW":336,"TRAINER_ANGELICA":436,"TRAINER_ANGELINA":712,"TRAINER_ANGELO":802,"TRAINER_ANNA_AND_MEG_1":287,"TRAINER_ANNA_AND_MEG_2":288,"TRAINER_ANNA_AND_MEG_3":289,"TRAINER_ANNA_AND_MEG_4":290,"TRAINER_ANNA_AND_MEG_5":291,"TRAINER_ANNIKA":502,"TRAINER_ANTHONY":352,"TRAINER_ARCHIE":34,"TRAINER_ASHLEY":655,"TRAINER_ATHENA":577,"TRAINER_ATSUSHI":190,"TRAINER_AURON":506,"TRAINER_AUSTINA":58,"TRAINER_AUTUMN":217,"TRAINER_AXLE":203,"TRAINER_BARNY":343,"TRAINER_BARRY":163,"TRAINER_BEAU":212,"TRAINER_BECK":414,"TRAINER_BECKY":470,"TRAINER_BEN":323,"TRAINER_BENJAMIN_1":353,"TRAINER_BENJAMIN_2":354,"TRAINER_BENJAMIN_3":355,"TRAINER_BENJAMIN_4":356,"TRAINER_BENJAMIN_5":357,"TRAINER_BENNY":407,"TRAINER_BERKE":74,"TRAINER_BERNIE_1":206,"TRAINER_BERNIE_2":207,"TRAINER_BERNIE_3":208,"TRAINER_BERNIE_4":209,"TRAINER_BERNIE_5":210,"TRAINER_BETH":445,"TRAINER_BETHANY":301,"TRAINER_BEVERLY":441,"TRAINER_BIANCA":706,"TRAINER_BILLY":319,"TRAINER_BLAKE":235,"TRAINER_BRANDEN":745,"TRAINER_BRANDI":756,"TRAINER_BRANDON":811,"TRAINER_BRAWLY_1":266,"TRAINER_BRAWLY_2":774,"TRAINER_BRAWLY_3":775,"TRAINER_BRAWLY_4":776,"TRAINER_BRAWLY_5":777,"TRAINER_BRAXTON":75,"TRAINER_BRENDA":454,"TRAINER_BRENDAN_LILYCOVE_MUDKIP":661,"TRAINER_BRENDAN_LILYCOVE_TORCHIC":663,"TRAINER_BRENDAN_LILYCOVE_TREECKO":662,"TRAINER_BRENDAN_PLACEHOLDER":853,"TRAINER_BRENDAN_ROUTE_103_MUDKIP":520,"TRAINER_BRENDAN_ROUTE_103_TORCHIC":526,"TRAINER_BRENDAN_ROUTE_103_TREECKO":523,"TRAINER_BRENDAN_ROUTE_110_MUDKIP":521,"TRAINER_BRENDAN_ROUTE_110_TORCHIC":527,"TRAINER_BRENDAN_ROUTE_110_TREECKO":524,"TRAINER_BRENDAN_ROUTE_119_MUDKIP":522,"TRAINER_BRENDAN_ROUTE_119_TORCHIC":528,"TRAINER_BRENDAN_ROUTE_119_TREECKO":525,"TRAINER_BRENDAN_RUSTBORO_MUDKIP":593,"TRAINER_BRENDAN_RUSTBORO_TORCHIC":599,"TRAINER_BRENDAN_RUSTBORO_TREECKO":592,"TRAINER_BRENDEN":572,"TRAINER_BRENT":223,"TRAINER_BRIANNA":118,"TRAINER_BRICE":626,"TRAINER_BRIDGET":129,"TRAINER_BROOKE_1":94,"TRAINER_BROOKE_2":101,"TRAINER_BROOKE_3":102,"TRAINER_BROOKE_4":103,"TRAINER_BROOKE_5":104,"TRAINER_BRYAN":744,"TRAINER_BRYANT":746,"TRAINER_CALE":764,"TRAINER_CALLIE":763,"TRAINER_CALVIN_1":318,"TRAINER_CALVIN_2":328,"TRAINER_CALVIN_3":329,"TRAINER_CALVIN_4":330,"TRAINER_CALVIN_5":331,"TRAINER_CAMDEN":374,"TRAINER_CAMERON_1":238,"TRAINER_CAMERON_2":239,"TRAINER_CAMERON_3":240,"TRAINER_CAMERON_4":241,"TRAINER_CAMERON_5":242,"TRAINER_CAMRON":739,"TRAINER_CARLEE":464,"TRAINER_CAROL":471,"TRAINER_CAROLINA":741,"TRAINER_CAROLINE":99,"TRAINER_CARTER":345,"TRAINER_CATHERINE_1":559,"TRAINER_CATHERINE_2":562,"TRAINER_CATHERINE_3":563,"TRAINER_CATHERINE_4":564,"TRAINER_CATHERINE_5":565,"TRAINER_CEDRIC":475,"TRAINER_CELIA":743,"TRAINER_CELINA":705,"TRAINER_CHAD":174,"TRAINER_CHANDLER":698,"TRAINER_CHARLIE":66,"TRAINER_CHARLOTTE":714,"TRAINER_CHASE":378,"TRAINER_CHESTER":408,"TRAINER_CHIP":45,"TRAINER_CHRIS":693,"TRAINER_CINDY_1":114,"TRAINER_CINDY_2":117,"TRAINER_CINDY_3":120,"TRAINER_CINDY_4":121,"TRAINER_CINDY_5":122,"TRAINER_CINDY_6":123,"TRAINER_CLARENCE":580,"TRAINER_CLARISSA":435,"TRAINER_CLARK":631,"TRAINER_CLAUDE":338,"TRAINER_CLIFFORD":584,"TRAINER_COBY":709,"TRAINER_COLE":201,"TRAINER_COLIN":405,"TRAINER_COLTON":294,"TRAINER_CONNIE":128,"TRAINER_CONOR":511,"TRAINER_CORA":428,"TRAINER_CORY_1":740,"TRAINER_CORY_2":816,"TRAINER_CORY_3":817,"TRAINER_CORY_4":818,"TRAINER_CORY_5":819,"TRAINER_CRISSY":614,"TRAINER_CRISTIAN":574,"TRAINER_CRISTIN_1":767,"TRAINER_CRISTIN_2":828,"TRAINER_CRISTIN_3":829,"TRAINER_CRISTIN_4":830,"TRAINER_CRISTIN_5":831,"TRAINER_CYNDY_1":427,"TRAINER_CYNDY_2":430,"TRAINER_CYNDY_3":431,"TRAINER_CYNDY_4":432,"TRAINER_CYNDY_5":433,"TRAINER_DAISUKE":189,"TRAINER_DAISY":36,"TRAINER_DALE":341,"TRAINER_DALTON_1":196,"TRAINER_DALTON_2":197,"TRAINER_DALTON_3":198,"TRAINER_DALTON_4":199,"TRAINER_DALTON_5":200,"TRAINER_DANA":458,"TRAINER_DANIELLE":650,"TRAINER_DAPHNE":115,"TRAINER_DARCY":733,"TRAINER_DARIAN":696,"TRAINER_DARIUS":803,"TRAINER_DARRIN":154,"TRAINER_DAVID":158,"TRAINER_DAVIS":539,"TRAINER_DAWSON":694,"TRAINER_DAYTON":760,"TRAINER_DEAN":164,"TRAINER_DEANDRE":715,"TRAINER_DEBRA":460,"TRAINER_DECLAN":15,"TRAINER_DEMETRIUS":375,"TRAINER_DENISE":444,"TRAINER_DEREK":227,"TRAINER_DEVAN":753,"TRAINER_DEZ_AND_LUKE":640,"TRAINER_DIANA_1":474,"TRAINER_DIANA_2":477,"TRAINER_DIANA_3":478,"TRAINER_DIANA_4":479,"TRAINER_DIANA_5":480,"TRAINER_DIANNE":417,"TRAINER_DILLON":327,"TRAINER_DOMINIK":152,"TRAINER_DONALD":224,"TRAINER_DONNY":384,"TRAINER_DOUG":618,"TRAINER_DOUGLAS":153,"TRAINER_DRAKE":264,"TRAINER_DREW":211,"TRAINER_DUDLEY":173,"TRAINER_DUNCAN":496,"TRAINER_DUSTY_1":44,"TRAINER_DUSTY_2":47,"TRAINER_DUSTY_3":48,"TRAINER_DUSTY_4":49,"TRAINER_DUSTY_5":50,"TRAINER_DWAYNE":493,"TRAINER_DYLAN_1":364,"TRAINER_DYLAN_2":365,"TRAINER_DYLAN_3":366,"TRAINER_DYLAN_4":367,"TRAINER_DYLAN_5":368,"TRAINER_ED":13,"TRAINER_EDDIE":332,"TRAINER_EDGAR":79,"TRAINER_EDMOND":491,"TRAINER_EDWARD":232,"TRAINER_EDWARDO":404,"TRAINER_EDWIN_1":512,"TRAINER_EDWIN_2":515,"TRAINER_EDWIN_3":516,"TRAINER_EDWIN_4":517,"TRAINER_EDWIN_5":518,"TRAINER_ELI":501,"TRAINER_ELIJAH":742,"TRAINER_ELLIOT_1":339,"TRAINER_ELLIOT_2":346,"TRAINER_ELLIOT_3":347,"TRAINER_ELLIOT_4":348,"TRAINER_ELLIOT_5":349,"TRAINER_ERIC":632,"TRAINER_ERNEST_1":492,"TRAINER_ERNEST_2":497,"TRAINER_ERNEST_3":498,"TRAINER_ERNEST_4":499,"TRAINER_ERNEST_5":500,"TRAINER_ETHAN_1":216,"TRAINER_ETHAN_2":219,"TRAINER_ETHAN_3":220,"TRAINER_ETHAN_4":221,"TRAINER_ETHAN_5":222,"TRAINER_EVERETT":850,"TRAINER_FABIAN":759,"TRAINER_FELIX":38,"TRAINER_FERNANDO_1":195,"TRAINER_FERNANDO_2":832,"TRAINER_FERNANDO_3":833,"TRAINER_FERNANDO_4":834,"TRAINER_FERNANDO_5":835,"TRAINER_FLAGS_END":2143,"TRAINER_FLAGS_START":1280,"TRAINER_FLANNERY_1":268,"TRAINER_FLANNERY_2":782,"TRAINER_FLANNERY_3":783,"TRAINER_FLANNERY_4":784,"TRAINER_FLANNERY_5":785,"TRAINER_FLINT":654,"TRAINER_FOSTER":46,"TRAINER_FRANKLIN":170,"TRAINER_FREDRICK":29,"TRAINER_GABBY_AND_TY_1":51,"TRAINER_GABBY_AND_TY_2":52,"TRAINER_GABBY_AND_TY_3":53,"TRAINER_GABBY_AND_TY_4":54,"TRAINER_GABBY_AND_TY_5":55,"TRAINER_GABBY_AND_TY_6":56,"TRAINER_GABRIELLE_1":9,"TRAINER_GABRIELLE_2":840,"TRAINER_GABRIELLE_3":841,"TRAINER_GABRIELLE_4":842,"TRAINER_GABRIELLE_5":843,"TRAINER_GARRET":138,"TRAINER_GARRISON":547,"TRAINER_GEORGE":73,"TRAINER_GEORGIA":281,"TRAINER_GERALD":648,"TRAINER_GILBERT":169,"TRAINER_GINA_AND_MIA_1":483,"TRAINER_GINA_AND_MIA_2":486,"TRAINER_GLACIA":263,"TRAINER_GRACE":450,"TRAINER_GREG":619,"TRAINER_GRETA":808,"TRAINER_GRUNT_AQUA_HIDEOUT_1":2,"TRAINER_GRUNT_AQUA_HIDEOUT_2":3,"TRAINER_GRUNT_AQUA_HIDEOUT_3":4,"TRAINER_GRUNT_AQUA_HIDEOUT_4":5,"TRAINER_GRUNT_AQUA_HIDEOUT_5":27,"TRAINER_GRUNT_AQUA_HIDEOUT_6":28,"TRAINER_GRUNT_AQUA_HIDEOUT_7":192,"TRAINER_GRUNT_AQUA_HIDEOUT_8":193,"TRAINER_GRUNT_JAGGED_PASS":570,"TRAINER_GRUNT_MAGMA_HIDEOUT_1":716,"TRAINER_GRUNT_MAGMA_HIDEOUT_10":725,"TRAINER_GRUNT_MAGMA_HIDEOUT_11":726,"TRAINER_GRUNT_MAGMA_HIDEOUT_12":727,"TRAINER_GRUNT_MAGMA_HIDEOUT_13":728,"TRAINER_GRUNT_MAGMA_HIDEOUT_14":729,"TRAINER_GRUNT_MAGMA_HIDEOUT_15":730,"TRAINER_GRUNT_MAGMA_HIDEOUT_16":731,"TRAINER_GRUNT_MAGMA_HIDEOUT_2":717,"TRAINER_GRUNT_MAGMA_HIDEOUT_3":718,"TRAINER_GRUNT_MAGMA_HIDEOUT_4":719,"TRAINER_GRUNT_MAGMA_HIDEOUT_5":720,"TRAINER_GRUNT_MAGMA_HIDEOUT_6":721,"TRAINER_GRUNT_MAGMA_HIDEOUT_7":722,"TRAINER_GRUNT_MAGMA_HIDEOUT_8":723,"TRAINER_GRUNT_MAGMA_HIDEOUT_9":724,"TRAINER_GRUNT_MT_CHIMNEY_1":146,"TRAINER_GRUNT_MT_CHIMNEY_2":579,"TRAINER_GRUNT_MT_PYRE_1":23,"TRAINER_GRUNT_MT_PYRE_2":24,"TRAINER_GRUNT_MT_PYRE_3":25,"TRAINER_GRUNT_MT_PYRE_4":569,"TRAINER_GRUNT_MUSEUM_1":20,"TRAINER_GRUNT_MUSEUM_2":21,"TRAINER_GRUNT_PETALBURG_WOODS":10,"TRAINER_GRUNT_RUSTURF_TUNNEL":16,"TRAINER_GRUNT_SEAFLOOR_CAVERN_1":6,"TRAINER_GRUNT_SEAFLOOR_CAVERN_2":7,"TRAINER_GRUNT_SEAFLOOR_CAVERN_3":8,"TRAINER_GRUNT_SEAFLOOR_CAVERN_4":14,"TRAINER_GRUNT_SEAFLOOR_CAVERN_5":567,"TRAINER_GRUNT_SPACE_CENTER_1":22,"TRAINER_GRUNT_SPACE_CENTER_2":116,"TRAINER_GRUNT_SPACE_CENTER_3":586,"TRAINER_GRUNT_SPACE_CENTER_4":587,"TRAINER_GRUNT_SPACE_CENTER_5":588,"TRAINER_GRUNT_SPACE_CENTER_6":589,"TRAINER_GRUNT_SPACE_CENTER_7":590,"TRAINER_GRUNT_UNUSED":568,"TRAINER_GRUNT_WEATHER_INST_1":17,"TRAINER_GRUNT_WEATHER_INST_2":18,"TRAINER_GRUNT_WEATHER_INST_3":19,"TRAINER_GRUNT_WEATHER_INST_4":26,"TRAINER_GRUNT_WEATHER_INST_5":596,"TRAINER_GWEN":59,"TRAINER_HAILEY":697,"TRAINER_HALEY_1":604,"TRAINER_HALEY_2":607,"TRAINER_HALEY_3":608,"TRAINER_HALEY_4":609,"TRAINER_HALEY_5":610,"TRAINER_HALLE":546,"TRAINER_HANNAH":244,"TRAINER_HARRISON":578,"TRAINER_HAYDEN":707,"TRAINER_HECTOR":513,"TRAINER_HEIDI":469,"TRAINER_HELENE":751,"TRAINER_HENRY":668,"TRAINER_HERMAN":167,"TRAINER_HIDEO":651,"TRAINER_HITOSHI":180,"TRAINER_HOPE":96,"TRAINER_HUDSON":510,"TRAINER_HUEY":490,"TRAINER_HUGH":399,"TRAINER_HUMBERTO":402,"TRAINER_IMANI":442,"TRAINER_IRENE":476,"TRAINER_ISAAC_1":538,"TRAINER_ISAAC_2":541,"TRAINER_ISAAC_3":542,"TRAINER_ISAAC_4":543,"TRAINER_ISAAC_5":544,"TRAINER_ISABELLA":595,"TRAINER_ISABELLE":736,"TRAINER_ISABEL_1":302,"TRAINER_ISABEL_2":303,"TRAINER_ISABEL_3":304,"TRAINER_ISABEL_4":305,"TRAINER_ISABEL_5":306,"TRAINER_ISAIAH_1":376,"TRAINER_ISAIAH_2":379,"TRAINER_ISAIAH_3":380,"TRAINER_ISAIAH_4":381,"TRAINER_ISAIAH_5":382,"TRAINER_ISOBEL":383,"TRAINER_IVAN":337,"TRAINER_JACE":204,"TRAINER_JACK":172,"TRAINER_JACKI_1":249,"TRAINER_JACKI_2":250,"TRAINER_JACKI_3":251,"TRAINER_JACKI_4":252,"TRAINER_JACKI_5":253,"TRAINER_JACKSON_1":552,"TRAINER_JACKSON_2":555,"TRAINER_JACKSON_3":556,"TRAINER_JACKSON_4":557,"TRAINER_JACKSON_5":558,"TRAINER_JACLYN":243,"TRAINER_JACOB":351,"TRAINER_JAIDEN":749,"TRAINER_JAMES_1":621,"TRAINER_JAMES_2":622,"TRAINER_JAMES_3":623,"TRAINER_JAMES_4":624,"TRAINER_JAMES_5":625,"TRAINER_JANI":418,"TRAINER_JANICE":605,"TRAINER_JARED":401,"TRAINER_JASMINE":359,"TRAINER_JAYLEN":326,"TRAINER_JAZMYN":503,"TRAINER_JEFF":202,"TRAINER_JEFFREY_1":226,"TRAINER_JEFFREY_2":228,"TRAINER_JEFFREY_3":229,"TRAINER_JEFFREY_4":230,"TRAINER_JEFFREY_5":231,"TRAINER_JENNA":560,"TRAINER_JENNIFER":95,"TRAINER_JENNY_1":449,"TRAINER_JENNY_2":465,"TRAINER_JENNY_3":466,"TRAINER_JENNY_4":467,"TRAINER_JENNY_5":468,"TRAINER_JEROME":156,"TRAINER_JERRY_1":273,"TRAINER_JERRY_2":276,"TRAINER_JERRY_3":277,"TRAINER_JERRY_4":278,"TRAINER_JERRY_5":279,"TRAINER_JESSICA_1":127,"TRAINER_JESSICA_2":132,"TRAINER_JESSICA_3":133,"TRAINER_JESSICA_4":134,"TRAINER_JESSICA_5":135,"TRAINER_JOCELYN":425,"TRAINER_JODY":91,"TRAINER_JOEY":322,"TRAINER_JOHANNA":647,"TRAINER_JOHNSON":754,"TRAINER_JOHN_AND_JAY_1":681,"TRAINER_JOHN_AND_JAY_2":682,"TRAINER_JOHN_AND_JAY_3":683,"TRAINER_JOHN_AND_JAY_4":684,"TRAINER_JOHN_AND_JAY_5":685,"TRAINER_JONAH":667,"TRAINER_JONAS":504,"TRAINER_JONATHAN":598,"TRAINER_JOSE":617,"TRAINER_JOSEPH":700,"TRAINER_JOSH":320,"TRAINER_JOSHUA":237,"TRAINER_JOSUE":738,"TRAINER_JUAN_1":272,"TRAINER_JUAN_2":798,"TRAINER_JUAN_3":799,"TRAINER_JUAN_4":800,"TRAINER_JUAN_5":801,"TRAINER_JULIE":100,"TRAINER_JULIO":566,"TRAINER_JUSTIN":215,"TRAINER_KAI":713,"TRAINER_KALEB":699,"TRAINER_KARA":457,"TRAINER_KAREN_1":280,"TRAINER_KAREN_2":282,"TRAINER_KAREN_3":283,"TRAINER_KAREN_4":284,"TRAINER_KAREN_5":285,"TRAINER_KATELYNN":325,"TRAINER_KATELYN_1":386,"TRAINER_KATELYN_2":388,"TRAINER_KATELYN_3":389,"TRAINER_KATELYN_4":390,"TRAINER_KATELYN_5":391,"TRAINER_KATE_AND_JOY":286,"TRAINER_KATHLEEN":583,"TRAINER_KATIE":455,"TRAINER_KAYLA":247,"TRAINER_KAYLEE":462,"TRAINER_KAYLEY":505,"TRAINER_KEEGAN":205,"TRAINER_KEIGO":652,"TRAINER_KEIRA":93,"TRAINER_KELVIN":507,"TRAINER_KENT":620,"TRAINER_KEVIN":171,"TRAINER_KIM_AND_IRIS":678,"TRAINER_KINDRA":106,"TRAINER_KIRA_AND_DAN_1":642,"TRAINER_KIRA_AND_DAN_2":643,"TRAINER_KIRA_AND_DAN_3":644,"TRAINER_KIRA_AND_DAN_4":645,"TRAINER_KIRA_AND_DAN_5":646,"TRAINER_KIRK":191,"TRAINER_KIYO":181,"TRAINER_KOICHI":182,"TRAINER_KOJI_1":672,"TRAINER_KOJI_2":824,"TRAINER_KOJI_3":825,"TRAINER_KOJI_4":826,"TRAINER_KOJI_5":827,"TRAINER_KYLA":443,"TRAINER_KYRA":748,"TRAINER_LAO_1":419,"TRAINER_LAO_2":421,"TRAINER_LAO_3":422,"TRAINER_LAO_4":423,"TRAINER_LAO_5":424,"TRAINER_LARRY":213,"TRAINER_LAURA":426,"TRAINER_LAUREL":463,"TRAINER_LAWRENCE":710,"TRAINER_LEAF":852,"TRAINER_LEAH":35,"TRAINER_LEA_AND_JED":641,"TRAINER_LENNY":628,"TRAINER_LEONARD":495,"TRAINER_LEONARDO":576,"TRAINER_LEONEL":762,"TRAINER_LEROY":77,"TRAINER_LILA_AND_ROY_1":687,"TRAINER_LILA_AND_ROY_2":688,"TRAINER_LILA_AND_ROY_3":689,"TRAINER_LILA_AND_ROY_4":690,"TRAINER_LILA_AND_ROY_5":691,"TRAINER_LILITH":573,"TRAINER_LINDA":461,"TRAINER_LISA_AND_RAY":692,"TRAINER_LOLA_1":57,"TRAINER_LOLA_2":60,"TRAINER_LOLA_3":61,"TRAINER_LOLA_4":62,"TRAINER_LOLA_5":63,"TRAINER_LORENZO":553,"TRAINER_LUCAS_1":629,"TRAINER_LUCAS_2":633,"TRAINER_LUCY":810,"TRAINER_LUIS":151,"TRAINER_LUNG":420,"TRAINER_LYDIA_1":545,"TRAINER_LYDIA_2":548,"TRAINER_LYDIA_3":549,"TRAINER_LYDIA_4":550,"TRAINER_LYDIA_5":551,"TRAINER_LYLE":616,"TRAINER_MACEY":591,"TRAINER_MADELINE_1":434,"TRAINER_MADELINE_2":437,"TRAINER_MADELINE_3":438,"TRAINER_MADELINE_4":439,"TRAINER_MADELINE_5":440,"TRAINER_MAKAYLA":758,"TRAINER_MARC":571,"TRAINER_MARCEL":11,"TRAINER_MARCOS":702,"TRAINER_MARIA_1":369,"TRAINER_MARIA_2":370,"TRAINER_MARIA_3":371,"TRAINER_MARIA_4":372,"TRAINER_MARIA_5":373,"TRAINER_MARIELA":848,"TRAINER_MARK":145,"TRAINER_MARLENE":752,"TRAINER_MARLEY":508,"TRAINER_MARTHA":473,"TRAINER_MARY":89,"TRAINER_MATT":30,"TRAINER_MATTHEW":157,"TRAINER_MAURA":246,"TRAINER_MAXIE_MAGMA_HIDEOUT":601,"TRAINER_MAXIE_MOSSDEEP":734,"TRAINER_MAXIE_MT_CHIMNEY":602,"TRAINER_MAY_LILYCOVE_MUDKIP":664,"TRAINER_MAY_LILYCOVE_TORCHIC":666,"TRAINER_MAY_LILYCOVE_TREECKO":665,"TRAINER_MAY_PLACEHOLDER":854,"TRAINER_MAY_ROUTE_103_MUDKIP":529,"TRAINER_MAY_ROUTE_103_TORCHIC":535,"TRAINER_MAY_ROUTE_103_TREECKO":532,"TRAINER_MAY_ROUTE_110_MUDKIP":530,"TRAINER_MAY_ROUTE_110_TORCHIC":536,"TRAINER_MAY_ROUTE_110_TREECKO":533,"TRAINER_MAY_ROUTE_119_MUDKIP":531,"TRAINER_MAY_ROUTE_119_TORCHIC":537,"TRAINER_MAY_ROUTE_119_TREECKO":534,"TRAINER_MAY_RUSTBORO_MUDKIP":600,"TRAINER_MAY_RUSTBORO_TORCHIC":769,"TRAINER_MAY_RUSTBORO_TREECKO":768,"TRAINER_MELINA":755,"TRAINER_MELISSA":124,"TRAINER_MEL_AND_PAUL":680,"TRAINER_MICAH":255,"TRAINER_MICHELLE":98,"TRAINER_MIGUEL_1":293,"TRAINER_MIGUEL_2":295,"TRAINER_MIGUEL_3":296,"TRAINER_MIGUEL_4":297,"TRAINER_MIGUEL_5":298,"TRAINER_MIKE_1":634,"TRAINER_MIKE_2":635,"TRAINER_MISSY":447,"TRAINER_MITCHELL":540,"TRAINER_MIU_AND_YUKI":484,"TRAINER_MOLLIE":137,"TRAINER_MYLES":765,"TRAINER_NANCY":472,"TRAINER_NAOMI":119,"TRAINER_NATE":582,"TRAINER_NED":340,"TRAINER_NICHOLAS":585,"TRAINER_NICOLAS_1":392,"TRAINER_NICOLAS_2":393,"TRAINER_NICOLAS_3":394,"TRAINER_NICOLAS_4":395,"TRAINER_NICOLAS_5":396,"TRAINER_NIKKI":453,"TRAINER_NOB_1":183,"TRAINER_NOB_2":184,"TRAINER_NOB_3":185,"TRAINER_NOB_4":186,"TRAINER_NOB_5":187,"TRAINER_NOLAN":342,"TRAINER_NOLAND":809,"TRAINER_NOLEN":161,"TRAINER_NONE":0,"TRAINER_NORMAN_1":269,"TRAINER_NORMAN_2":786,"TRAINER_NORMAN_3":787,"TRAINER_NORMAN_4":788,"TRAINER_NORMAN_5":789,"TRAINER_OLIVIA":130,"TRAINER_OWEN":83,"TRAINER_PABLO_1":377,"TRAINER_PABLO_2":820,"TRAINER_PABLO_3":821,"TRAINER_PABLO_4":822,"TRAINER_PABLO_5":823,"TRAINER_PARKER":72,"TRAINER_PAT":766,"TRAINER_PATRICIA":105,"TRAINER_PAUL":275,"TRAINER_PAULA":429,"TRAINER_PAXTON":594,"TRAINER_PERRY":398,"TRAINER_PETE":735,"TRAINER_PHIL":400,"TRAINER_PHILLIP":494,"TRAINER_PHOEBE":262,"TRAINER_PRESLEY":403,"TRAINER_PRESTON":233,"TRAINER_QUINCY":324,"TRAINER_RACHEL":761,"TRAINER_RANDALL":71,"TRAINER_RED":851,"TRAINER_REED":675,"TRAINER_RELI_AND_IAN":686,"TRAINER_REYNA":509,"TRAINER_RHETT":703,"TRAINER_RICHARD":166,"TRAINER_RICK":615,"TRAINER_RICKY_1":64,"TRAINER_RICKY_2":67,"TRAINER_RICKY_3":68,"TRAINER_RICKY_4":69,"TRAINER_RICKY_5":70,"TRAINER_RILEY":653,"TRAINER_ROBERT_1":406,"TRAINER_ROBERT_2":409,"TRAINER_ROBERT_3":410,"TRAINER_ROBERT_4":411,"TRAINER_ROBERT_5":412,"TRAINER_ROBIN":612,"TRAINER_RODNEY":165,"TRAINER_ROGER":669,"TRAINER_ROLAND":160,"TRAINER_RONALD":350,"TRAINER_ROSE_1":37,"TRAINER_ROSE_2":40,"TRAINER_ROSE_3":41,"TRAINER_ROSE_4":42,"TRAINER_ROSE_5":43,"TRAINER_ROXANNE_1":265,"TRAINER_ROXANNE_2":770,"TRAINER_ROXANNE_3":771,"TRAINER_ROXANNE_4":772,"TRAINER_ROXANNE_5":773,"TRAINER_RUBEN":671,"TRAINER_SALLY":611,"TRAINER_SAMANTHA":245,"TRAINER_SAMUEL":81,"TRAINER_SANTIAGO":168,"TRAINER_SARAH":695,"TRAINER_SAWYER_1":1,"TRAINER_SAWYER_2":836,"TRAINER_SAWYER_3":837,"TRAINER_SAWYER_4":838,"TRAINER_SAWYER_5":839,"TRAINER_SEBASTIAN":554,"TRAINER_SHANE":214,"TRAINER_SHANNON":97,"TRAINER_SHARON":452,"TRAINER_SHAWN":194,"TRAINER_SHAYLA":747,"TRAINER_SHEILA":125,"TRAINER_SHELBY_1":313,"TRAINER_SHELBY_2":314,"TRAINER_SHELBY_3":315,"TRAINER_SHELBY_4":316,"TRAINER_SHELBY_5":317,"TRAINER_SHELLY_SEAFLOOR_CAVERN":33,"TRAINER_SHELLY_WEATHER_INSTITUTE":32,"TRAINER_SHIRLEY":126,"TRAINER_SIDNEY":261,"TRAINER_SIENNA":459,"TRAINER_SIMON":65,"TRAINER_SOPHIA":561,"TRAINER_SOPHIE":708,"TRAINER_SPENCER":159,"TRAINER_SPENSER":807,"TRAINER_STAN":162,"TRAINER_STEVEN":804,"TRAINER_STEVE_1":143,"TRAINER_STEVE_2":147,"TRAINER_STEVE_3":148,"TRAINER_STEVE_4":149,"TRAINER_STEVE_5":150,"TRAINER_SUSIE":456,"TRAINER_SYLVIA":575,"TRAINER_TABITHA_MAGMA_HIDEOUT":732,"TRAINER_TABITHA_MOSSDEEP":514,"TRAINER_TABITHA_MT_CHIMNEY":597,"TRAINER_TAKAO":179,"TRAINER_TAKASHI":416,"TRAINER_TALIA":385,"TRAINER_TAMMY":107,"TRAINER_TANYA":451,"TRAINER_TARA":446,"TRAINER_TASHA":109,"TRAINER_TATE_AND_LIZA_1":271,"TRAINER_TATE_AND_LIZA_2":794,"TRAINER_TATE_AND_LIZA_3":795,"TRAINER_TATE_AND_LIZA_4":796,"TRAINER_TATE_AND_LIZA_5":797,"TRAINER_TAYLOR":225,"TRAINER_TED":274,"TRAINER_TERRY":581,"TRAINER_THALIA_1":144,"TRAINER_THALIA_2":844,"TRAINER_THALIA_3":845,"TRAINER_THALIA_4":846,"TRAINER_THALIA_5":847,"TRAINER_THOMAS":256,"TRAINER_TIANA":603,"TRAINER_TIFFANY":131,"TRAINER_TIMMY":334,"TRAINER_TIMOTHY_1":307,"TRAINER_TIMOTHY_2":308,"TRAINER_TIMOTHY_3":309,"TRAINER_TIMOTHY_4":310,"TRAINER_TIMOTHY_5":311,"TRAINER_TISHA":676,"TRAINER_TOMMY":321,"TRAINER_TONY_1":155,"TRAINER_TONY_2":175,"TRAINER_TONY_3":176,"TRAINER_TONY_4":177,"TRAINER_TONY_5":178,"TRAINER_TORI_AND_TIA":677,"TRAINER_TRAVIS":218,"TRAINER_TRENT_1":627,"TRAINER_TRENT_2":636,"TRAINER_TRENT_3":637,"TRAINER_TRENT_4":638,"TRAINER_TRENT_5":639,"TRAINER_TUCKER":806,"TRAINER_TYRA_AND_IVY":679,"TRAINER_TYRON":704,"TRAINER_VALERIE_1":108,"TRAINER_VALERIE_2":110,"TRAINER_VALERIE_3":111,"TRAINER_VALERIE_4":112,"TRAINER_VALERIE_5":113,"TRAINER_VANESSA":300,"TRAINER_VICKY":312,"TRAINER_VICTOR":292,"TRAINER_VICTORIA":299,"TRAINER_VINCENT":76,"TRAINER_VIOLET":39,"TRAINER_VIRGIL":234,"TRAINER_VITO":82,"TRAINER_VIVI":606,"TRAINER_VIVIAN":649,"TRAINER_WADE":344,"TRAINER_WALLACE":335,"TRAINER_WALLY_MAUVILLE":656,"TRAINER_WALLY_VR_1":519,"TRAINER_WALLY_VR_2":657,"TRAINER_WALLY_VR_3":658,"TRAINER_WALLY_VR_4":659,"TRAINER_WALLY_VR_5":660,"TRAINER_WALTER_1":254,"TRAINER_WALTER_2":257,"TRAINER_WALTER_3":258,"TRAINER_WALTER_4":259,"TRAINER_WALTER_5":260,"TRAINER_WARREN":88,"TRAINER_WATTSON_1":267,"TRAINER_WATTSON_2":778,"TRAINER_WATTSON_3":779,"TRAINER_WATTSON_4":780,"TRAINER_WATTSON_5":781,"TRAINER_WAYNE":673,"TRAINER_WENDY":92,"TRAINER_WILLIAM":236,"TRAINER_WILTON_1":78,"TRAINER_WILTON_2":84,"TRAINER_WILTON_3":85,"TRAINER_WILTON_4":86,"TRAINER_WILTON_5":87,"TRAINER_WINONA_1":270,"TRAINER_WINONA_2":790,"TRAINER_WINONA_3":791,"TRAINER_WINONA_4":792,"TRAINER_WINONA_5":793,"TRAINER_WINSTON_1":136,"TRAINER_WINSTON_2":139,"TRAINER_WINSTON_3":140,"TRAINER_WINSTON_4":141,"TRAINER_WINSTON_5":142,"TRAINER_WYATT":711,"TRAINER_YASU":415,"TRAINER_YUJI":188,"TRAINER_ZANDER":31},"legendary_encounters":[{"address":2538600,"catch_flag":429,"defeat_flag":428,"level":30,"species":410},{"address":2354334,"catch_flag":480,"defeat_flag":447,"level":70,"species":405},{"address":2543160,"catch_flag":146,"defeat_flag":476,"level":70,"species":250},{"address":2354112,"catch_flag":479,"defeat_flag":446,"level":70,"species":404},{"address":2385623,"catch_flag":457,"defeat_flag":456,"level":50,"species":407},{"address":2385687,"catch_flag":482,"defeat_flag":481,"level":50,"species":408},{"address":2543443,"catch_flag":145,"defeat_flag":477,"level":70,"species":249},{"address":2538177,"catch_flag":458,"defeat_flag":455,"level":30,"species":151},{"address":2347488,"catch_flag":478,"defeat_flag":448,"level":70,"species":406},{"address":2345460,"catch_flag":427,"defeat_flag":444,"level":40,"species":402},{"address":2298183,"catch_flag":426,"defeat_flag":443,"level":40,"species":401},{"address":2345731,"catch_flag":483,"defeat_flag":445,"level":40,"species":403}],"locations":{"BADGE_1":{"address":2188036,"default_item":226,"flag":1182},"BADGE_2":{"address":2095131,"default_item":227,"flag":1183},"BADGE_3":{"address":2167252,"default_item":228,"flag":1184},"BADGE_4":{"address":2103246,"default_item":229,"flag":1185},"BADGE_5":{"address":2129781,"default_item":230,"flag":1186},"BADGE_6":{"address":2202122,"default_item":231,"flag":1187},"BADGE_7":{"address":2243964,"default_item":232,"flag":1188},"BADGE_8":{"address":2262314,"default_item":233,"flag":1189},"BERRY_TREE_01":{"address":5843562,"default_item":135,"flag":612},"BERRY_TREE_02":{"address":5843564,"default_item":139,"flag":613},"BERRY_TREE_03":{"address":5843566,"default_item":142,"flag":614},"BERRY_TREE_04":{"address":5843568,"default_item":139,"flag":615},"BERRY_TREE_05":{"address":5843570,"default_item":133,"flag":616},"BERRY_TREE_06":{"address":5843572,"default_item":138,"flag":617},"BERRY_TREE_07":{"address":5843574,"default_item":133,"flag":618},"BERRY_TREE_08":{"address":5843576,"default_item":133,"flag":619},"BERRY_TREE_09":{"address":5843578,"default_item":142,"flag":620},"BERRY_TREE_10":{"address":5843580,"default_item":138,"flag":621},"BERRY_TREE_11":{"address":5843582,"default_item":139,"flag":622},"BERRY_TREE_12":{"address":5843584,"default_item":142,"flag":623},"BERRY_TREE_13":{"address":5843586,"default_item":135,"flag":624},"BERRY_TREE_14":{"address":5843588,"default_item":155,"flag":625},"BERRY_TREE_15":{"address":5843590,"default_item":153,"flag":626},"BERRY_TREE_16":{"address":5843592,"default_item":150,"flag":627},"BERRY_TREE_17":{"address":5843594,"default_item":150,"flag":628},"BERRY_TREE_18":{"address":5843596,"default_item":150,"flag":629},"BERRY_TREE_19":{"address":5843598,"default_item":148,"flag":630},"BERRY_TREE_20":{"address":5843600,"default_item":148,"flag":631},"BERRY_TREE_21":{"address":5843602,"default_item":136,"flag":632},"BERRY_TREE_22":{"address":5843604,"default_item":135,"flag":633},"BERRY_TREE_23":{"address":5843606,"default_item":135,"flag":634},"BERRY_TREE_24":{"address":5843608,"default_item":136,"flag":635},"BERRY_TREE_25":{"address":5843610,"default_item":152,"flag":636},"BERRY_TREE_26":{"address":5843612,"default_item":134,"flag":637},"BERRY_TREE_27":{"address":5843614,"default_item":151,"flag":638},"BERRY_TREE_28":{"address":5843616,"default_item":151,"flag":639},"BERRY_TREE_29":{"address":5843618,"default_item":151,"flag":640},"BERRY_TREE_30":{"address":5843620,"default_item":153,"flag":641},"BERRY_TREE_31":{"address":5843622,"default_item":142,"flag":642},"BERRY_TREE_32":{"address":5843624,"default_item":142,"flag":643},"BERRY_TREE_33":{"address":5843626,"default_item":142,"flag":644},"BERRY_TREE_34":{"address":5843628,"default_item":153,"flag":645},"BERRY_TREE_35":{"address":5843630,"default_item":153,"flag":646},"BERRY_TREE_36":{"address":5843632,"default_item":153,"flag":647},"BERRY_TREE_37":{"address":5843634,"default_item":137,"flag":648},"BERRY_TREE_38":{"address":5843636,"default_item":137,"flag":649},"BERRY_TREE_39":{"address":5843638,"default_item":137,"flag":650},"BERRY_TREE_40":{"address":5843640,"default_item":135,"flag":651},"BERRY_TREE_41":{"address":5843642,"default_item":135,"flag":652},"BERRY_TREE_42":{"address":5843644,"default_item":135,"flag":653},"BERRY_TREE_43":{"address":5843646,"default_item":148,"flag":654},"BERRY_TREE_44":{"address":5843648,"default_item":150,"flag":655},"BERRY_TREE_45":{"address":5843650,"default_item":152,"flag":656},"BERRY_TREE_46":{"address":5843652,"default_item":151,"flag":657},"BERRY_TREE_47":{"address":5843654,"default_item":140,"flag":658},"BERRY_TREE_48":{"address":5843656,"default_item":137,"flag":659},"BERRY_TREE_49":{"address":5843658,"default_item":136,"flag":660},"BERRY_TREE_50":{"address":5843660,"default_item":134,"flag":661},"BERRY_TREE_51":{"address":5843662,"default_item":142,"flag":662},"BERRY_TREE_52":{"address":5843664,"default_item":150,"flag":663},"BERRY_TREE_53":{"address":5843666,"default_item":150,"flag":664},"BERRY_TREE_54":{"address":5843668,"default_item":142,"flag":665},"BERRY_TREE_55":{"address":5843670,"default_item":149,"flag":666},"BERRY_TREE_56":{"address":5843672,"default_item":149,"flag":667},"BERRY_TREE_57":{"address":5843674,"default_item":136,"flag":668},"BERRY_TREE_58":{"address":5843676,"default_item":153,"flag":669},"BERRY_TREE_59":{"address":5843678,"default_item":153,"flag":670},"BERRY_TREE_60":{"address":5843680,"default_item":157,"flag":671},"BERRY_TREE_61":{"address":5843682,"default_item":157,"flag":672},"BERRY_TREE_62":{"address":5843684,"default_item":138,"flag":673},"BERRY_TREE_63":{"address":5843686,"default_item":142,"flag":674},"BERRY_TREE_64":{"address":5843688,"default_item":138,"flag":675},"BERRY_TREE_65":{"address":5843690,"default_item":157,"flag":676},"BERRY_TREE_66":{"address":5843692,"default_item":134,"flag":677},"BERRY_TREE_67":{"address":5843694,"default_item":152,"flag":678},"BERRY_TREE_68":{"address":5843696,"default_item":140,"flag":679},"BERRY_TREE_69":{"address":5843698,"default_item":154,"flag":680},"BERRY_TREE_70":{"address":5843700,"default_item":154,"flag":681},"BERRY_TREE_71":{"address":5843702,"default_item":154,"flag":682},"BERRY_TREE_72":{"address":5843704,"default_item":157,"flag":683},"BERRY_TREE_73":{"address":5843706,"default_item":155,"flag":684},"BERRY_TREE_74":{"address":5843708,"default_item":155,"flag":685},"BERRY_TREE_75":{"address":5843710,"default_item":142,"flag":686},"BERRY_TREE_76":{"address":5843712,"default_item":133,"flag":687},"BERRY_TREE_77":{"address":5843714,"default_item":140,"flag":688},"BERRY_TREE_78":{"address":5843716,"default_item":140,"flag":689},"BERRY_TREE_79":{"address":5843718,"default_item":155,"flag":690},"BERRY_TREE_80":{"address":5843720,"default_item":139,"flag":691},"BERRY_TREE_81":{"address":5843722,"default_item":139,"flag":692},"BERRY_TREE_82":{"address":5843724,"default_item":168,"flag":693},"BERRY_TREE_83":{"address":5843726,"default_item":156,"flag":694},"BERRY_TREE_84":{"address":5843728,"default_item":156,"flag":695},"BERRY_TREE_85":{"address":5843730,"default_item":142,"flag":696},"BERRY_TREE_86":{"address":5843732,"default_item":138,"flag":697},"BERRY_TREE_87":{"address":5843734,"default_item":135,"flag":698},"BERRY_TREE_88":{"address":5843736,"default_item":142,"flag":699},"HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":{"address":5497200,"default_item":281,"flag":531},"HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":{"address":5497212,"default_item":282,"flag":532},"HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":{"address":5497224,"default_item":283,"flag":533},"HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":{"address":5497236,"default_item":284,"flag":534},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":{"address":5500100,"default_item":67,"flag":601},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":{"address":5500124,"default_item":65,"flag":604},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":{"address":5500112,"default_item":64,"flag":603},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":{"address":5500088,"default_item":70,"flag":602},"HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":{"address":5435924,"default_item":110,"flag":528},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":{"address":5487372,"default_item":195,"flag":548},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":{"address":5487384,"default_item":195,"flag":549},"HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":{"address":5489116,"default_item":23,"flag":577},"HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":{"address":5489128,"default_item":3,"flag":576},"HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":{"address":5435672,"default_item":16,"flag":500},"HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":{"address":5432608,"default_item":111,"flag":527},"HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":{"address":5432632,"default_item":4,"flag":575},"HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":{"address":5432620,"default_item":69,"flag":543},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":{"address":5490440,"default_item":35,"flag":578},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":{"address":5490428,"default_item":2,"flag":529},"HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":{"address":5490796,"default_item":68,"flag":580},"HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":{"address":5490784,"default_item":70,"flag":579},"HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":{"address":5525804,"default_item":45,"flag":609},"HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":{"address":5428972,"default_item":68,"flag":595},"HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":{"address":5487908,"default_item":4,"flag":561},"HIDDEN_ITEM_PETALBURG_WOODS_POTION":{"address":5487872,"default_item":13,"flag":558},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":{"address":5487884,"default_item":103,"flag":559},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":{"address":5487896,"default_item":103,"flag":560},"HIDDEN_ITEM_ROUTE_104_ANTIDOTE":{"address":5438492,"default_item":14,"flag":585},"HIDDEN_ITEM_ROUTE_104_HEART_SCALE":{"address":5438504,"default_item":111,"flag":588},"HIDDEN_ITEM_ROUTE_104_POKE_BALL":{"address":5438468,"default_item":4,"flag":562},"HIDDEN_ITEM_ROUTE_104_POTION":{"address":5438480,"default_item":13,"flag":537},"HIDDEN_ITEM_ROUTE_104_SUPER_POTION":{"address":5438456,"default_item":22,"flag":544},"HIDDEN_ITEM_ROUTE_105_BIG_PEARL":{"address":5438748,"default_item":107,"flag":611},"HIDDEN_ITEM_ROUTE_105_HEART_SCALE":{"address":5438736,"default_item":111,"flag":589},"HIDDEN_ITEM_ROUTE_106_HEART_SCALE":{"address":5438932,"default_item":111,"flag":547},"HIDDEN_ITEM_ROUTE_106_POKE_BALL":{"address":5438908,"default_item":4,"flag":563},"HIDDEN_ITEM_ROUTE_106_STARDUST":{"address":5438920,"default_item":108,"flag":546},"HIDDEN_ITEM_ROUTE_108_RARE_CANDY":{"address":5439340,"default_item":68,"flag":586},"HIDDEN_ITEM_ROUTE_109_ETHER":{"address":5440016,"default_item":34,"flag":564},"HIDDEN_ITEM_ROUTE_109_GREAT_BALL":{"address":5440004,"default_item":3,"flag":551},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":{"address":5439992,"default_item":111,"flag":552},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":{"address":5440028,"default_item":111,"flag":590},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":{"address":5440040,"default_item":111,"flag":591},"HIDDEN_ITEM_ROUTE_109_REVIVE":{"address":5439980,"default_item":24,"flag":550},"HIDDEN_ITEM_ROUTE_110_FULL_HEAL":{"address":5441308,"default_item":23,"flag":555},"HIDDEN_ITEM_ROUTE_110_GREAT_BALL":{"address":5441284,"default_item":3,"flag":553},"HIDDEN_ITEM_ROUTE_110_POKE_BALL":{"address":5441296,"default_item":4,"flag":565},"HIDDEN_ITEM_ROUTE_110_REVIVE":{"address":5441272,"default_item":24,"flag":554},"HIDDEN_ITEM_ROUTE_111_PROTEIN":{"address":5443220,"default_item":64,"flag":556},"HIDDEN_ITEM_ROUTE_111_RARE_CANDY":{"address":5443232,"default_item":68,"flag":557},"HIDDEN_ITEM_ROUTE_111_STARDUST":{"address":5443160,"default_item":108,"flag":502},"HIDDEN_ITEM_ROUTE_113_ETHER":{"address":5444488,"default_item":34,"flag":503},"HIDDEN_ITEM_ROUTE_113_NUGGET":{"address":5444512,"default_item":110,"flag":598},"HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":{"address":5444500,"default_item":320,"flag":530},"HIDDEN_ITEM_ROUTE_114_CARBOS":{"address":5445340,"default_item":66,"flag":504},"HIDDEN_ITEM_ROUTE_114_REVIVE":{"address":5445364,"default_item":24,"flag":542},"HIDDEN_ITEM_ROUTE_115_HEART_SCALE":{"address":5446176,"default_item":111,"flag":597},"HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":{"address":5447056,"default_item":206,"flag":596},"HIDDEN_ITEM_ROUTE_116_SUPER_POTION":{"address":5447044,"default_item":22,"flag":545},"HIDDEN_ITEM_ROUTE_117_REPEL":{"address":5447708,"default_item":86,"flag":572},"HIDDEN_ITEM_ROUTE_118_HEART_SCALE":{"address":5448404,"default_item":111,"flag":566},"HIDDEN_ITEM_ROUTE_118_IRON":{"address":5448392,"default_item":65,"flag":567},"HIDDEN_ITEM_ROUTE_119_CALCIUM":{"address":5449972,"default_item":67,"flag":505},"HIDDEN_ITEM_ROUTE_119_FULL_HEAL":{"address":5450056,"default_item":23,"flag":568},"HIDDEN_ITEM_ROUTE_119_MAX_ETHER":{"address":5450068,"default_item":35,"flag":587},"HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":{"address":5449984,"default_item":2,"flag":506},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":{"address":5451596,"default_item":68,"flag":571},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":{"address":5451620,"default_item":68,"flag":569},"HIDDEN_ITEM_ROUTE_120_REVIVE":{"address":5451608,"default_item":24,"flag":584},"HIDDEN_ITEM_ROUTE_120_ZINC":{"address":5451632,"default_item":70,"flag":570},"HIDDEN_ITEM_ROUTE_121_FULL_HEAL":{"address":5452540,"default_item":23,"flag":573},"HIDDEN_ITEM_ROUTE_121_HP_UP":{"address":5452516,"default_item":63,"flag":539},"HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":{"address":5452552,"default_item":25,"flag":600},"HIDDEN_ITEM_ROUTE_121_NUGGET":{"address":5452528,"default_item":110,"flag":540},"HIDDEN_ITEM_ROUTE_123_HYPER_POTION":{"address":5454100,"default_item":21,"flag":574},"HIDDEN_ITEM_ROUTE_123_PP_UP":{"address":5454112,"default_item":69,"flag":599},"HIDDEN_ITEM_ROUTE_123_RARE_CANDY":{"address":5454124,"default_item":68,"flag":610},"HIDDEN_ITEM_ROUTE_123_REVIVE":{"address":5454088,"default_item":24,"flag":541},"HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":{"address":5454052,"default_item":83,"flag":507},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":{"address":5455620,"default_item":111,"flag":592},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":{"address":5455632,"default_item":111,"flag":593},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":{"address":5455644,"default_item":111,"flag":594},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":{"address":5517256,"default_item":68,"flag":606},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":{"address":5517268,"default_item":70,"flag":607},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":{"address":5517432,"default_item":19,"flag":605},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":{"address":5517420,"default_item":69,"flag":608},"HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":{"address":5511292,"default_item":200,"flag":535},"HIDDEN_ITEM_TRICK_HOUSE_NUGGET":{"address":5526716,"default_item":110,"flag":501},"HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":{"address":5456992,"default_item":107,"flag":511},"HIDDEN_ITEM_UNDERWATER_124_CALCIUM":{"address":5457016,"default_item":67,"flag":536},"HIDDEN_ITEM_UNDERWATER_124_CARBOS":{"address":5456956,"default_item":66,"flag":508},"HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":{"address":5456968,"default_item":51,"flag":509},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":{"address":5457004,"default_item":111,"flag":513},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":{"address":5457028,"default_item":111,"flag":538},"HIDDEN_ITEM_UNDERWATER_124_PEARL":{"address":5456980,"default_item":106,"flag":510},"HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":{"address":5457140,"default_item":107,"flag":520},"HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":{"address":5457152,"default_item":49,"flag":512},"HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":{"address":5457068,"default_item":111,"flag":514},"HIDDEN_ITEM_UNDERWATER_126_IRON":{"address":5457116,"default_item":65,"flag":519},"HIDDEN_ITEM_UNDERWATER_126_PEARL":{"address":5457104,"default_item":106,"flag":517},"HIDDEN_ITEM_UNDERWATER_126_STARDUST":{"address":5457092,"default_item":108,"flag":516},"HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":{"address":5457080,"default_item":2,"flag":515},"HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":{"address":5457128,"default_item":50,"flag":518},"HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":{"address":5457224,"default_item":111,"flag":523},"HIDDEN_ITEM_UNDERWATER_127_HP_UP":{"address":5457212,"default_item":63,"flag":522},"HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":{"address":5457236,"default_item":48,"flag":524},"HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":{"address":5457200,"default_item":109,"flag":521},"HIDDEN_ITEM_UNDERWATER_128_PEARL":{"address":5457288,"default_item":106,"flag":526},"HIDDEN_ITEM_UNDERWATER_128_PROTEIN":{"address":5457276,"default_item":64,"flag":525},"HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":{"address":5493932,"default_item":2,"flag":581},"HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":{"address":5494744,"default_item":36,"flag":582},"HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":{"address":5494756,"default_item":84,"flag":583},"ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":{"address":2709805,"default_item":285,"flag":1100},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":{"address":2709857,"default_item":306,"flag":1102},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":{"address":2709831,"default_item":278,"flag":1078},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":{"address":2709844,"default_item":97,"flag":1101},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":{"address":2709818,"default_item":11,"flag":1077},"ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":{"address":2709740,"default_item":122,"flag":1095},"ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":{"address":2709792,"default_item":24,"flag":1099},"ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":{"address":2709766,"default_item":7,"flag":1097},"ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":{"address":2709753,"default_item":85,"flag":1096},"ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":{"address":2709779,"default_item":301,"flag":1098},"ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":{"address":2710039,"default_item":1,"flag":1124},"ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":{"address":2710065,"default_item":37,"flag":1071},"ITEM_AQUA_HIDEOUT_B1F_NUGGET":{"address":2710052,"default_item":110,"flag":1132},"ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":{"address":2710078,"default_item":8,"flag":1072},"ITEM_ARTISAN_CAVE_1F_CARBOS":{"address":2710416,"default_item":66,"flag":1163},"ITEM_ARTISAN_CAVE_B1F_HP_UP":{"address":2710403,"default_item":63,"flag":1162},"ITEM_FIERY_PATH_FIRE_STONE":{"address":2709584,"default_item":95,"flag":1111},"ITEM_FIERY_PATH_TM_TOXIC":{"address":2709597,"default_item":294,"flag":1091},"ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":{"address":2709519,"default_item":85,"flag":1050},"ITEM_GRANITE_CAVE_B1F_POKE_BALL":{"address":2709532,"default_item":4,"flag":1051},"ITEM_GRANITE_CAVE_B2F_RARE_CANDY":{"address":2709558,"default_item":68,"flag":1054},"ITEM_GRANITE_CAVE_B2F_REPEL":{"address":2709545,"default_item":86,"flag":1053},"ITEM_JAGGED_PASS_BURN_HEAL":{"address":2709571,"default_item":15,"flag":1070},"ITEM_LILYCOVE_CITY_MAX_REPEL":{"address":2709415,"default_item":84,"flag":1042},"ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":{"address":2710429,"default_item":68,"flag":1151},"ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":{"address":2710455,"default_item":19,"flag":1165},"ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":{"address":2710442,"default_item":37,"flag":1164},"ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":{"address":2710468,"default_item":110,"flag":1166},"ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":{"address":2710481,"default_item":71,"flag":1167},"ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":{"address":2710507,"default_item":85,"flag":1059},"ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":{"address":2710494,"default_item":25,"flag":1168},"ITEM_MAUVILLE_CITY_X_SPEED":{"address":2709389,"default_item":77,"flag":1116},"ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":{"address":2709623,"default_item":23,"flag":1045},"ITEM_METEOR_FALLS_1F_1R_MOON_STONE":{"address":2709636,"default_item":94,"flag":1046},"ITEM_METEOR_FALLS_1F_1R_PP_UP":{"address":2709649,"default_item":69,"flag":1047},"ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":{"address":2709610,"default_item":311,"flag":1044},"ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":{"address":2709662,"default_item":290,"flag":1080},"ITEM_MOSSDEEP_CITY_NET_BALL":{"address":2709428,"default_item":6,"flag":1043},"ITEM_MT_PYRE_2F_ULTRA_BALL":{"address":2709948,"default_item":2,"flag":1129},"ITEM_MT_PYRE_3F_SUPER_REPEL":{"address":2709961,"default_item":83,"flag":1120},"ITEM_MT_PYRE_4F_SEA_INCENSE":{"address":2709974,"default_item":220,"flag":1130},"ITEM_MT_PYRE_5F_LAX_INCENSE":{"address":2709987,"default_item":221,"flag":1052},"ITEM_MT_PYRE_6F_TM_SHADOW_BALL":{"address":2710000,"default_item":318,"flag":1089},"ITEM_MT_PYRE_EXTERIOR_MAX_POTION":{"address":2710013,"default_item":20,"flag":1073},"ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":{"address":2710026,"default_item":336,"flag":1074},"ITEM_NEW_MAUVILLE_ESCAPE_ROPE":{"address":2709688,"default_item":85,"flag":1076},"ITEM_NEW_MAUVILLE_FULL_HEAL":{"address":2709714,"default_item":23,"flag":1122},"ITEM_NEW_MAUVILLE_PARALYZE_HEAL":{"address":2709727,"default_item":18,"flag":1123},"ITEM_NEW_MAUVILLE_THUNDER_STONE":{"address":2709701,"default_item":96,"flag":1110},"ITEM_NEW_MAUVILLE_ULTRA_BALL":{"address":2709675,"default_item":2,"flag":1075},"ITEM_PETALBURG_CITY_ETHER":{"address":2709376,"default_item":34,"flag":1040},"ITEM_PETALBURG_CITY_MAX_REVIVE":{"address":2709363,"default_item":25,"flag":1039},"ITEM_PETALBURG_WOODS_ETHER":{"address":2709467,"default_item":34,"flag":1058},"ITEM_PETALBURG_WOODS_GREAT_BALL":{"address":2709454,"default_item":3,"flag":1056},"ITEM_PETALBURG_WOODS_PARALYZE_HEAL":{"address":2709480,"default_item":18,"flag":1117},"ITEM_PETALBURG_WOODS_X_ATTACK":{"address":2709441,"default_item":75,"flag":1055},"ITEM_ROUTE_102_POTION":{"address":2708375,"default_item":13,"flag":1000},"ITEM_ROUTE_103_GUARD_SPEC":{"address":2708388,"default_item":73,"flag":1114},"ITEM_ROUTE_103_PP_UP":{"address":2708401,"default_item":69,"flag":1137},"ITEM_ROUTE_104_POKE_BALL":{"address":2708427,"default_item":4,"flag":1057},"ITEM_ROUTE_104_POTION":{"address":2708453,"default_item":13,"flag":1135},"ITEM_ROUTE_104_PP_UP":{"address":2708414,"default_item":69,"flag":1002},"ITEM_ROUTE_104_X_ACCURACY":{"address":2708440,"default_item":78,"flag":1115},"ITEM_ROUTE_105_IRON":{"address":2708466,"default_item":65,"flag":1003},"ITEM_ROUTE_106_PROTEIN":{"address":2708479,"default_item":64,"flag":1004},"ITEM_ROUTE_108_STAR_PIECE":{"address":2708492,"default_item":109,"flag":1139},"ITEM_ROUTE_109_POTION":{"address":2708518,"default_item":13,"flag":1140},"ITEM_ROUTE_109_PP_UP":{"address":2708505,"default_item":69,"flag":1005},"ITEM_ROUTE_110_DIRE_HIT":{"address":2708544,"default_item":74,"flag":1007},"ITEM_ROUTE_110_ELIXIR":{"address":2708557,"default_item":36,"flag":1141},"ITEM_ROUTE_110_RARE_CANDY":{"address":2708531,"default_item":68,"flag":1006},"ITEM_ROUTE_111_ELIXIR":{"address":2708609,"default_item":36,"flag":1142},"ITEM_ROUTE_111_HP_UP":{"address":2708596,"default_item":63,"flag":1010},"ITEM_ROUTE_111_STARDUST":{"address":2708583,"default_item":108,"flag":1009},"ITEM_ROUTE_111_TM_SANDSTORM":{"address":2708570,"default_item":325,"flag":1008},"ITEM_ROUTE_112_NUGGET":{"address":2708622,"default_item":110,"flag":1011},"ITEM_ROUTE_113_HYPER_POTION":{"address":2708661,"default_item":21,"flag":1143},"ITEM_ROUTE_113_MAX_ETHER":{"address":2708635,"default_item":35,"flag":1012},"ITEM_ROUTE_113_SUPER_REPEL":{"address":2708648,"default_item":83,"flag":1013},"ITEM_ROUTE_114_ENERGY_POWDER":{"address":2708700,"default_item":30,"flag":1160},"ITEM_ROUTE_114_PROTEIN":{"address":2708687,"default_item":64,"flag":1015},"ITEM_ROUTE_114_RARE_CANDY":{"address":2708674,"default_item":68,"flag":1014},"ITEM_ROUTE_115_GREAT_BALL":{"address":2708752,"default_item":3,"flag":1118},"ITEM_ROUTE_115_HEAL_POWDER":{"address":2708765,"default_item":32,"flag":1144},"ITEM_ROUTE_115_IRON":{"address":2708739,"default_item":65,"flag":1018},"ITEM_ROUTE_115_PP_UP":{"address":2708778,"default_item":69,"flag":1161},"ITEM_ROUTE_115_SUPER_POTION":{"address":2708713,"default_item":22,"flag":1016},"ITEM_ROUTE_115_TM_FOCUS_PUNCH":{"address":2708726,"default_item":289,"flag":1017},"ITEM_ROUTE_116_ETHER":{"address":2708804,"default_item":34,"flag":1019},"ITEM_ROUTE_116_HP_UP":{"address":2708830,"default_item":63,"flag":1021},"ITEM_ROUTE_116_POTION":{"address":2708843,"default_item":13,"flag":1146},"ITEM_ROUTE_116_REPEL":{"address":2708817,"default_item":86,"flag":1020},"ITEM_ROUTE_116_X_SPECIAL":{"address":2708791,"default_item":79,"flag":1001},"ITEM_ROUTE_117_GREAT_BALL":{"address":2708856,"default_item":3,"flag":1022},"ITEM_ROUTE_117_REVIVE":{"address":2708869,"default_item":24,"flag":1023},"ITEM_ROUTE_118_HYPER_POTION":{"address":2708882,"default_item":21,"flag":1121},"ITEM_ROUTE_119_ELIXIR_1":{"address":2708921,"default_item":36,"flag":1026},"ITEM_ROUTE_119_ELIXIR_2":{"address":2708986,"default_item":36,"flag":1147},"ITEM_ROUTE_119_HYPER_POTION_1":{"address":2708960,"default_item":21,"flag":1029},"ITEM_ROUTE_119_HYPER_POTION_2":{"address":2708973,"default_item":21,"flag":1106},"ITEM_ROUTE_119_LEAF_STONE":{"address":2708934,"default_item":98,"flag":1027},"ITEM_ROUTE_119_NUGGET":{"address":2710104,"default_item":110,"flag":1134},"ITEM_ROUTE_119_RARE_CANDY":{"address":2708947,"default_item":68,"flag":1028},"ITEM_ROUTE_119_SUPER_REPEL":{"address":2708895,"default_item":83,"flag":1024},"ITEM_ROUTE_119_ZINC":{"address":2708908,"default_item":70,"flag":1025},"ITEM_ROUTE_120_FULL_HEAL":{"address":2709012,"default_item":23,"flag":1031},"ITEM_ROUTE_120_HYPER_POTION":{"address":2709025,"default_item":21,"flag":1107},"ITEM_ROUTE_120_NEST_BALL":{"address":2709038,"default_item":8,"flag":1108},"ITEM_ROUTE_120_NUGGET":{"address":2708999,"default_item":110,"flag":1030},"ITEM_ROUTE_120_REVIVE":{"address":2709051,"default_item":24,"flag":1148},"ITEM_ROUTE_121_CARBOS":{"address":2709064,"default_item":66,"flag":1103},"ITEM_ROUTE_121_REVIVE":{"address":2709077,"default_item":24,"flag":1149},"ITEM_ROUTE_121_ZINC":{"address":2709090,"default_item":70,"flag":1150},"ITEM_ROUTE_123_CALCIUM":{"address":2709103,"default_item":67,"flag":1032},"ITEM_ROUTE_123_ELIXIR":{"address":2709129,"default_item":36,"flag":1109},"ITEM_ROUTE_123_PP_UP":{"address":2709142,"default_item":69,"flag":1152},"ITEM_ROUTE_123_REVIVAL_HERB":{"address":2709155,"default_item":33,"flag":1153},"ITEM_ROUTE_123_ULTRA_BALL":{"address":2709116,"default_item":2,"flag":1104},"ITEM_ROUTE_124_BLUE_SHARD":{"address":2709181,"default_item":49,"flag":1093},"ITEM_ROUTE_124_RED_SHARD":{"address":2709168,"default_item":48,"flag":1092},"ITEM_ROUTE_124_YELLOW_SHARD":{"address":2709194,"default_item":50,"flag":1066},"ITEM_ROUTE_125_BIG_PEARL":{"address":2709207,"default_item":107,"flag":1154},"ITEM_ROUTE_126_GREEN_SHARD":{"address":2709220,"default_item":51,"flag":1105},"ITEM_ROUTE_127_CARBOS":{"address":2709246,"default_item":66,"flag":1035},"ITEM_ROUTE_127_RARE_CANDY":{"address":2709259,"default_item":68,"flag":1155},"ITEM_ROUTE_127_ZINC":{"address":2709233,"default_item":70,"flag":1034},"ITEM_ROUTE_132_PROTEIN":{"address":2709285,"default_item":64,"flag":1156},"ITEM_ROUTE_132_RARE_CANDY":{"address":2709272,"default_item":68,"flag":1036},"ITEM_ROUTE_133_BIG_PEARL":{"address":2709298,"default_item":107,"flag":1037},"ITEM_ROUTE_133_MAX_REVIVE":{"address":2709324,"default_item":25,"flag":1157},"ITEM_ROUTE_133_STAR_PIECE":{"address":2709311,"default_item":109,"flag":1038},"ITEM_ROUTE_134_CARBOS":{"address":2709337,"default_item":66,"flag":1158},"ITEM_ROUTE_134_STAR_PIECE":{"address":2709350,"default_item":109,"flag":1159},"ITEM_RUSTBORO_CITY_X_DEFEND":{"address":2709402,"default_item":76,"flag":1041},"ITEM_RUSTURF_TUNNEL_MAX_ETHER":{"address":2709506,"default_item":35,"flag":1049},"ITEM_RUSTURF_TUNNEL_POKE_BALL":{"address":2709493,"default_item":4,"flag":1048},"ITEM_SAFARI_ZONE_NORTH_CALCIUM":{"address":2709896,"default_item":67,"flag":1119},"ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":{"address":2709922,"default_item":110,"flag":1169},"ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":{"address":2709883,"default_item":310,"flag":1094},"ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":{"address":2709935,"default_item":107,"flag":1170},"ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":{"address":2709909,"default_item":25,"flag":1131},"ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":{"address":2709870,"default_item":299,"flag":1079},"ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":{"address":2710208,"default_item":314,"flag":1090},"ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":{"address":2710143,"default_item":107,"flag":1081},"ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":{"address":2710195,"default_item":212,"flag":1113},"ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":{"address":2710182,"default_item":295,"flag":1112},"ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":{"address":2710156,"default_item":68,"flag":1082},"ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":{"address":2710169,"default_item":16,"flag":1083},"ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":{"address":[2710221,2551006],"default_item":121,"flag":1060},"ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":{"address":[2710234,2551032],"default_item":122,"flag":1061},"ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":{"address":[2710247,2551058],"default_item":126,"flag":1062},"ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":{"address":[2710260,2551084],"default_item":128,"flag":1063},"ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":{"address":[2710273,2551110],"default_item":125,"flag":1064},"ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":{"address":[2710286,2551136],"default_item":124,"flag":1065},"ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":{"address":[2710299,2551162],"default_item":123,"flag":1067},"ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":{"address":[2710312,2551188],"default_item":129,"flag":1068},"ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":{"address":[2710325,2551214],"default_item":127,"flag":1069},"ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":{"address":2710338,"default_item":37,"flag":1084},"ITEM_VICTORY_ROAD_1F_PP_UP":{"address":2710351,"default_item":69,"flag":1085},"ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":{"address":2710377,"default_item":19,"flag":1087},"ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":{"address":2710364,"default_item":317,"flag":1086},"ITEM_VICTORY_ROAD_B2F_FULL_HEAL":{"address":2710390,"default_item":23,"flag":1088},"NPC_GIFT_BERRY_MASTERS_WIFE":{"address":2570453,"default_item":133,"flag":1197},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_1":{"address":2570263,"default_item":153,"flag":1195},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_2":{"address":2570315,"default_item":154,"flag":1196},"NPC_GIFT_FLOWER_SHOP_RECEIVED_BERRY":{"address":2284375,"default_item":133,"flag":1207},"NPC_GIFT_GOT_BASEMENT_KEY_FROM_WATTSON":{"address":1971718,"default_item":271,"flag":208},"NPC_GIFT_GOT_TM_THUNDERBOLT_FROM_WATTSON":{"address":1971754,"default_item":312,"flag":209},"NPC_GIFT_LILYCOVE_RECEIVED_BERRY":{"address":1985277,"default_item":141,"flag":1208},"NPC_GIFT_RECEIVED_6_SODA_POP":{"address":2543767,"default_item":27,"flag":140},"NPC_GIFT_RECEIVED_ACRO_BIKE":{"address":2170570,"default_item":272,"flag":1181},"NPC_GIFT_RECEIVED_AMULET_COIN":{"address":2716248,"default_item":189,"flag":133},"NPC_GIFT_RECEIVED_AURORA_TICKET":{"address":2716523,"default_item":371,"flag":314},"NPC_GIFT_RECEIVED_CHARCOAL":{"address":2102559,"default_item":215,"flag":254},"NPC_GIFT_RECEIVED_CHESTO_BERRY_ROUTE_104":{"address":2028703,"default_item":134,"flag":246},"NPC_GIFT_RECEIVED_CLEANSE_TAG":{"address":2312109,"default_item":190,"flag":282},"NPC_GIFT_RECEIVED_COIN_CASE":{"address":2179054,"default_item":260,"flag":258},"NPC_GIFT_RECEIVED_DEEP_SEA_SCALE":{"address":2162572,"default_item":193,"flag":1190},"NPC_GIFT_RECEIVED_DEEP_SEA_TOOTH":{"address":2162555,"default_item":192,"flag":1191},"NPC_GIFT_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":{"address":2295814,"default_item":269,"flag":1172},"NPC_GIFT_RECEIVED_DEVON_SCOPE":{"address":2065146,"default_item":288,"flag":285},"NPC_GIFT_RECEIVED_EON_TICKET":{"address":2716574,"default_item":275,"flag":474},"NPC_GIFT_RECEIVED_EXP_SHARE":{"address":2185525,"default_item":182,"flag":272},"NPC_GIFT_RECEIVED_FIRST_POKEBALLS":{"address":2085751,"default_item":4,"flag":233},"NPC_GIFT_RECEIVED_FOCUS_BAND":{"address":2337807,"default_item":196,"flag":283},"NPC_GIFT_RECEIVED_GOOD_ROD":{"address":2058408,"default_item":263,"flag":227},"NPC_GIFT_RECEIVED_GO_GOGGLES":{"address":2017746,"default_item":279,"flag":221},"NPC_GIFT_RECEIVED_GREAT_BALL_PETALBURG_WOODS":{"address":2300119,"default_item":3,"flag":1171},"NPC_GIFT_RECEIVED_GREAT_BALL_RUSTBORO_CITY":{"address":1977146,"default_item":3,"flag":1173},"NPC_GIFT_RECEIVED_HM_CUT":{"address":2199532,"default_item":339,"flag":137},"NPC_GIFT_RECEIVED_HM_DIVE":{"address":2252095,"default_item":346,"flag":123},"NPC_GIFT_RECEIVED_HM_FLASH":{"address":2298287,"default_item":343,"flag":109},"NPC_GIFT_RECEIVED_HM_FLY":{"address":2060636,"default_item":340,"flag":110},"NPC_GIFT_RECEIVED_HM_ROCK_SMASH":{"address":2174128,"default_item":344,"flag":107},"NPC_GIFT_RECEIVED_HM_STRENGTH":{"address":2295305,"default_item":342,"flag":106},"NPC_GIFT_RECEIVED_HM_SURF":{"address":2126671,"default_item":341,"flag":122},"NPC_GIFT_RECEIVED_HM_WATERFALL":{"address":1999854,"default_item":345,"flag":312},"NPC_GIFT_RECEIVED_ITEMFINDER":{"address":2039874,"default_item":261,"flag":1176},"NPC_GIFT_RECEIVED_KINGS_ROCK":{"address":1993670,"default_item":187,"flag":276},"NPC_GIFT_RECEIVED_LETTER":{"address":2185301,"default_item":274,"flag":1174},"NPC_GIFT_RECEIVED_MACHO_BRACE":{"address":2284472,"default_item":181,"flag":277},"NPC_GIFT_RECEIVED_MACH_BIKE":{"address":2170553,"default_item":259,"flag":1180},"NPC_GIFT_RECEIVED_MAGMA_EMBLEM":{"address":2316671,"default_item":375,"flag":1177},"NPC_GIFT_RECEIVED_MENTAL_HERB":{"address":2208103,"default_item":185,"flag":223},"NPC_GIFT_RECEIVED_METEORITE":{"address":2304222,"default_item":280,"flag":115},"NPC_GIFT_RECEIVED_MIRACLE_SEED":{"address":2300337,"default_item":205,"flag":297},"NPC_GIFT_RECEIVED_MYSTIC_TICKET":{"address":2716540,"default_item":370,"flag":315},"NPC_GIFT_RECEIVED_OLD_ROD":{"address":2012541,"default_item":262,"flag":257},"NPC_GIFT_RECEIVED_OLD_SEA_MAP":{"address":2716557,"default_item":376,"flag":316},"NPC_GIFT_RECEIVED_POKEBLOCK_CASE":{"address":2614193,"default_item":273,"flag":95},"NPC_GIFT_RECEIVED_POTION_OLDALE":{"address":2010888,"default_item":13,"flag":132},"NPC_GIFT_RECEIVED_POWDER_JAR":{"address":1962504,"default_item":372,"flag":337},"NPC_GIFT_RECEIVED_PREMIER_BALL_RUSTBORO":{"address":2200571,"default_item":12,"flag":213},"NPC_GIFT_RECEIVED_QUICK_CLAW":{"address":2192227,"default_item":183,"flag":275},"NPC_GIFT_RECEIVED_REPEAT_BALL":{"address":2053722,"default_item":9,"flag":256},"NPC_GIFT_RECEIVED_SECRET_POWER":{"address":2598914,"default_item":331,"flag":96},"NPC_GIFT_RECEIVED_SILK_SCARF":{"address":2101830,"default_item":217,"flag":289},"NPC_GIFT_RECEIVED_SOFT_SAND":{"address":2035664,"default_item":203,"flag":280},"NPC_GIFT_RECEIVED_SOOTHE_BELL":{"address":2151278,"default_item":184,"flag":278},"NPC_GIFT_RECEIVED_SOOT_SACK":{"address":2567245,"default_item":270,"flag":1033},"NPC_GIFT_RECEIVED_SS_TICKET":{"address":2716506,"default_item":265,"flag":291},"NPC_GIFT_RECEIVED_SUN_STONE_MOSSDEEP":{"address":2254406,"default_item":93,"flag":192},"NPC_GIFT_RECEIVED_SUPER_ROD":{"address":2251560,"default_item":264,"flag":152},"NPC_GIFT_RECEIVED_TM_AERIAL_ACE":{"address":2202201,"default_item":328,"flag":170},"NPC_GIFT_RECEIVED_TM_ATTRACT":{"address":2116413,"default_item":333,"flag":235},"NPC_GIFT_RECEIVED_TM_BRICK_BREAK":{"address":2269085,"default_item":319,"flag":121},"NPC_GIFT_RECEIVED_TM_BULK_UP":{"address":2095210,"default_item":296,"flag":166},"NPC_GIFT_RECEIVED_TM_BULLET_SEED":{"address":2028910,"default_item":297,"flag":262},"NPC_GIFT_RECEIVED_TM_CALM_MIND":{"address":2244066,"default_item":292,"flag":171},"NPC_GIFT_RECEIVED_TM_DIG":{"address":2286669,"default_item":316,"flag":261},"NPC_GIFT_RECEIVED_TM_FACADE":{"address":2129909,"default_item":330,"flag":169},"NPC_GIFT_RECEIVED_TM_FRUSTRATION":{"address":2124110,"default_item":309,"flag":1179},"NPC_GIFT_RECEIVED_TM_GIGA_DRAIN":{"address":2068012,"default_item":307,"flag":232},"NPC_GIFT_RECEIVED_TM_HIDDEN_POWER":{"address":2206905,"default_item":298,"flag":264},"NPC_GIFT_RECEIVED_TM_OVERHEAT":{"address":2103328,"default_item":338,"flag":168},"NPC_GIFT_RECEIVED_TM_REST":{"address":2236966,"default_item":332,"flag":234},"NPC_GIFT_RECEIVED_TM_RETURN":{"address":2113546,"default_item":315,"flag":229},"NPC_GIFT_RECEIVED_TM_RETURN_2":{"address":2124055,"default_item":315,"flag":1178},"NPC_GIFT_RECEIVED_TM_ROAR":{"address":2051750,"default_item":293,"flag":231},"NPC_GIFT_RECEIVED_TM_ROCK_TOMB":{"address":2188088,"default_item":327,"flag":165},"NPC_GIFT_RECEIVED_TM_SHOCK_WAVE":{"address":2167340,"default_item":322,"flag":167},"NPC_GIFT_RECEIVED_TM_SLUDGE_BOMB":{"address":2099189,"default_item":324,"flag":230},"NPC_GIFT_RECEIVED_TM_SNATCH":{"address":2360766,"default_item":337,"flag":260},"NPC_GIFT_RECEIVED_TM_STEEL_WING":{"address":2298866,"default_item":335,"flag":1175},"NPC_GIFT_RECEIVED_TM_THIEF":{"address":2154698,"default_item":334,"flag":269},"NPC_GIFT_RECEIVED_TM_TORMENT":{"address":2145260,"default_item":329,"flag":265},"NPC_GIFT_RECEIVED_TM_WATER_PULSE":{"address":2262402,"default_item":291,"flag":172},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_1":{"address":2550316,"default_item":68,"flag":1200},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_2":{"address":2550390,"default_item":10,"flag":1201},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_3":{"address":2550473,"default_item":204,"flag":1202},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_4":{"address":2550556,"default_item":194,"flag":1203},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_5":{"address":2550630,"default_item":300,"flag":1204},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_6":{"address":2550695,"default_item":208,"flag":1205},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_7":{"address":2550769,"default_item":71,"flag":1206},"NPC_GIFT_RECEIVED_WAILMER_PAIL":{"address":2284320,"default_item":268,"flag":94},"NPC_GIFT_RECEIVED_WHITE_HERB":{"address":2028770,"default_item":180,"flag":279},"NPC_GIFT_ROUTE_111_RECEIVED_BERRY":{"address":2045493,"default_item":148,"flag":1192},"NPC_GIFT_ROUTE_114_RECEIVED_BERRY":{"address":2051680,"default_item":149,"flag":1193},"NPC_GIFT_ROUTE_120_RECEIVED_BERRY":{"address":2064727,"default_item":143,"flag":1194},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_1":{"address":1998521,"default_item":153,"flag":1198},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_2":{"address":1998566,"default_item":143,"flag":1199},"POKEDEX_REWARD_001":{"address":5729368,"default_item":3,"flag":0},"POKEDEX_REWARD_002":{"address":5729370,"default_item":3,"flag":0},"POKEDEX_REWARD_003":{"address":5729372,"default_item":3,"flag":0},"POKEDEX_REWARD_004":{"address":5729374,"default_item":3,"flag":0},"POKEDEX_REWARD_005":{"address":5729376,"default_item":3,"flag":0},"POKEDEX_REWARD_006":{"address":5729378,"default_item":3,"flag":0},"POKEDEX_REWARD_007":{"address":5729380,"default_item":3,"flag":0},"POKEDEX_REWARD_008":{"address":5729382,"default_item":3,"flag":0},"POKEDEX_REWARD_009":{"address":5729384,"default_item":3,"flag":0},"POKEDEX_REWARD_010":{"address":5729386,"default_item":3,"flag":0},"POKEDEX_REWARD_011":{"address":5729388,"default_item":3,"flag":0},"POKEDEX_REWARD_012":{"address":5729390,"default_item":3,"flag":0},"POKEDEX_REWARD_013":{"address":5729392,"default_item":3,"flag":0},"POKEDEX_REWARD_014":{"address":5729394,"default_item":3,"flag":0},"POKEDEX_REWARD_015":{"address":5729396,"default_item":3,"flag":0},"POKEDEX_REWARD_016":{"address":5729398,"default_item":3,"flag":0},"POKEDEX_REWARD_017":{"address":5729400,"default_item":3,"flag":0},"POKEDEX_REWARD_018":{"address":5729402,"default_item":3,"flag":0},"POKEDEX_REWARD_019":{"address":5729404,"default_item":3,"flag":0},"POKEDEX_REWARD_020":{"address":5729406,"default_item":3,"flag":0},"POKEDEX_REWARD_021":{"address":5729408,"default_item":3,"flag":0},"POKEDEX_REWARD_022":{"address":5729410,"default_item":3,"flag":0},"POKEDEX_REWARD_023":{"address":5729412,"default_item":3,"flag":0},"POKEDEX_REWARD_024":{"address":5729414,"default_item":3,"flag":0},"POKEDEX_REWARD_025":{"address":5729416,"default_item":3,"flag":0},"POKEDEX_REWARD_026":{"address":5729418,"default_item":3,"flag":0},"POKEDEX_REWARD_027":{"address":5729420,"default_item":3,"flag":0},"POKEDEX_REWARD_028":{"address":5729422,"default_item":3,"flag":0},"POKEDEX_REWARD_029":{"address":5729424,"default_item":3,"flag":0},"POKEDEX_REWARD_030":{"address":5729426,"default_item":3,"flag":0},"POKEDEX_REWARD_031":{"address":5729428,"default_item":3,"flag":0},"POKEDEX_REWARD_032":{"address":5729430,"default_item":3,"flag":0},"POKEDEX_REWARD_033":{"address":5729432,"default_item":3,"flag":0},"POKEDEX_REWARD_034":{"address":5729434,"default_item":3,"flag":0},"POKEDEX_REWARD_035":{"address":5729436,"default_item":3,"flag":0},"POKEDEX_REWARD_036":{"address":5729438,"default_item":3,"flag":0},"POKEDEX_REWARD_037":{"address":5729440,"default_item":3,"flag":0},"POKEDEX_REWARD_038":{"address":5729442,"default_item":3,"flag":0},"POKEDEX_REWARD_039":{"address":5729444,"default_item":3,"flag":0},"POKEDEX_REWARD_040":{"address":5729446,"default_item":3,"flag":0},"POKEDEX_REWARD_041":{"address":5729448,"default_item":3,"flag":0},"POKEDEX_REWARD_042":{"address":5729450,"default_item":3,"flag":0},"POKEDEX_REWARD_043":{"address":5729452,"default_item":3,"flag":0},"POKEDEX_REWARD_044":{"address":5729454,"default_item":3,"flag":0},"POKEDEX_REWARD_045":{"address":5729456,"default_item":3,"flag":0},"POKEDEX_REWARD_046":{"address":5729458,"default_item":3,"flag":0},"POKEDEX_REWARD_047":{"address":5729460,"default_item":3,"flag":0},"POKEDEX_REWARD_048":{"address":5729462,"default_item":3,"flag":0},"POKEDEX_REWARD_049":{"address":5729464,"default_item":3,"flag":0},"POKEDEX_REWARD_050":{"address":5729466,"default_item":3,"flag":0},"POKEDEX_REWARD_051":{"address":5729468,"default_item":3,"flag":0},"POKEDEX_REWARD_052":{"address":5729470,"default_item":3,"flag":0},"POKEDEX_REWARD_053":{"address":5729472,"default_item":3,"flag":0},"POKEDEX_REWARD_054":{"address":5729474,"default_item":3,"flag":0},"POKEDEX_REWARD_055":{"address":5729476,"default_item":3,"flag":0},"POKEDEX_REWARD_056":{"address":5729478,"default_item":3,"flag":0},"POKEDEX_REWARD_057":{"address":5729480,"default_item":3,"flag":0},"POKEDEX_REWARD_058":{"address":5729482,"default_item":3,"flag":0},"POKEDEX_REWARD_059":{"address":5729484,"default_item":3,"flag":0},"POKEDEX_REWARD_060":{"address":5729486,"default_item":3,"flag":0},"POKEDEX_REWARD_061":{"address":5729488,"default_item":3,"flag":0},"POKEDEX_REWARD_062":{"address":5729490,"default_item":3,"flag":0},"POKEDEX_REWARD_063":{"address":5729492,"default_item":3,"flag":0},"POKEDEX_REWARD_064":{"address":5729494,"default_item":3,"flag":0},"POKEDEX_REWARD_065":{"address":5729496,"default_item":3,"flag":0},"POKEDEX_REWARD_066":{"address":5729498,"default_item":3,"flag":0},"POKEDEX_REWARD_067":{"address":5729500,"default_item":3,"flag":0},"POKEDEX_REWARD_068":{"address":5729502,"default_item":3,"flag":0},"POKEDEX_REWARD_069":{"address":5729504,"default_item":3,"flag":0},"POKEDEX_REWARD_070":{"address":5729506,"default_item":3,"flag":0},"POKEDEX_REWARD_071":{"address":5729508,"default_item":3,"flag":0},"POKEDEX_REWARD_072":{"address":5729510,"default_item":3,"flag":0},"POKEDEX_REWARD_073":{"address":5729512,"default_item":3,"flag":0},"POKEDEX_REWARD_074":{"address":5729514,"default_item":3,"flag":0},"POKEDEX_REWARD_075":{"address":5729516,"default_item":3,"flag":0},"POKEDEX_REWARD_076":{"address":5729518,"default_item":3,"flag":0},"POKEDEX_REWARD_077":{"address":5729520,"default_item":3,"flag":0},"POKEDEX_REWARD_078":{"address":5729522,"default_item":3,"flag":0},"POKEDEX_REWARD_079":{"address":5729524,"default_item":3,"flag":0},"POKEDEX_REWARD_080":{"address":5729526,"default_item":3,"flag":0},"POKEDEX_REWARD_081":{"address":5729528,"default_item":3,"flag":0},"POKEDEX_REWARD_082":{"address":5729530,"default_item":3,"flag":0},"POKEDEX_REWARD_083":{"address":5729532,"default_item":3,"flag":0},"POKEDEX_REWARD_084":{"address":5729534,"default_item":3,"flag":0},"POKEDEX_REWARD_085":{"address":5729536,"default_item":3,"flag":0},"POKEDEX_REWARD_086":{"address":5729538,"default_item":3,"flag":0},"POKEDEX_REWARD_087":{"address":5729540,"default_item":3,"flag":0},"POKEDEX_REWARD_088":{"address":5729542,"default_item":3,"flag":0},"POKEDEX_REWARD_089":{"address":5729544,"default_item":3,"flag":0},"POKEDEX_REWARD_090":{"address":5729546,"default_item":3,"flag":0},"POKEDEX_REWARD_091":{"address":5729548,"default_item":3,"flag":0},"POKEDEX_REWARD_092":{"address":5729550,"default_item":3,"flag":0},"POKEDEX_REWARD_093":{"address":5729552,"default_item":3,"flag":0},"POKEDEX_REWARD_094":{"address":5729554,"default_item":3,"flag":0},"POKEDEX_REWARD_095":{"address":5729556,"default_item":3,"flag":0},"POKEDEX_REWARD_096":{"address":5729558,"default_item":3,"flag":0},"POKEDEX_REWARD_097":{"address":5729560,"default_item":3,"flag":0},"POKEDEX_REWARD_098":{"address":5729562,"default_item":3,"flag":0},"POKEDEX_REWARD_099":{"address":5729564,"default_item":3,"flag":0},"POKEDEX_REWARD_100":{"address":5729566,"default_item":3,"flag":0},"POKEDEX_REWARD_101":{"address":5729568,"default_item":3,"flag":0},"POKEDEX_REWARD_102":{"address":5729570,"default_item":3,"flag":0},"POKEDEX_REWARD_103":{"address":5729572,"default_item":3,"flag":0},"POKEDEX_REWARD_104":{"address":5729574,"default_item":3,"flag":0},"POKEDEX_REWARD_105":{"address":5729576,"default_item":3,"flag":0},"POKEDEX_REWARD_106":{"address":5729578,"default_item":3,"flag":0},"POKEDEX_REWARD_107":{"address":5729580,"default_item":3,"flag":0},"POKEDEX_REWARD_108":{"address":5729582,"default_item":3,"flag":0},"POKEDEX_REWARD_109":{"address":5729584,"default_item":3,"flag":0},"POKEDEX_REWARD_110":{"address":5729586,"default_item":3,"flag":0},"POKEDEX_REWARD_111":{"address":5729588,"default_item":3,"flag":0},"POKEDEX_REWARD_112":{"address":5729590,"default_item":3,"flag":0},"POKEDEX_REWARD_113":{"address":5729592,"default_item":3,"flag":0},"POKEDEX_REWARD_114":{"address":5729594,"default_item":3,"flag":0},"POKEDEX_REWARD_115":{"address":5729596,"default_item":3,"flag":0},"POKEDEX_REWARD_116":{"address":5729598,"default_item":3,"flag":0},"POKEDEX_REWARD_117":{"address":5729600,"default_item":3,"flag":0},"POKEDEX_REWARD_118":{"address":5729602,"default_item":3,"flag":0},"POKEDEX_REWARD_119":{"address":5729604,"default_item":3,"flag":0},"POKEDEX_REWARD_120":{"address":5729606,"default_item":3,"flag":0},"POKEDEX_REWARD_121":{"address":5729608,"default_item":3,"flag":0},"POKEDEX_REWARD_122":{"address":5729610,"default_item":3,"flag":0},"POKEDEX_REWARD_123":{"address":5729612,"default_item":3,"flag":0},"POKEDEX_REWARD_124":{"address":5729614,"default_item":3,"flag":0},"POKEDEX_REWARD_125":{"address":5729616,"default_item":3,"flag":0},"POKEDEX_REWARD_126":{"address":5729618,"default_item":3,"flag":0},"POKEDEX_REWARD_127":{"address":5729620,"default_item":3,"flag":0},"POKEDEX_REWARD_128":{"address":5729622,"default_item":3,"flag":0},"POKEDEX_REWARD_129":{"address":5729624,"default_item":3,"flag":0},"POKEDEX_REWARD_130":{"address":5729626,"default_item":3,"flag":0},"POKEDEX_REWARD_131":{"address":5729628,"default_item":3,"flag":0},"POKEDEX_REWARD_132":{"address":5729630,"default_item":3,"flag":0},"POKEDEX_REWARD_133":{"address":5729632,"default_item":3,"flag":0},"POKEDEX_REWARD_134":{"address":5729634,"default_item":3,"flag":0},"POKEDEX_REWARD_135":{"address":5729636,"default_item":3,"flag":0},"POKEDEX_REWARD_136":{"address":5729638,"default_item":3,"flag":0},"POKEDEX_REWARD_137":{"address":5729640,"default_item":3,"flag":0},"POKEDEX_REWARD_138":{"address":5729642,"default_item":3,"flag":0},"POKEDEX_REWARD_139":{"address":5729644,"default_item":3,"flag":0},"POKEDEX_REWARD_140":{"address":5729646,"default_item":3,"flag":0},"POKEDEX_REWARD_141":{"address":5729648,"default_item":3,"flag":0},"POKEDEX_REWARD_142":{"address":5729650,"default_item":3,"flag":0},"POKEDEX_REWARD_143":{"address":5729652,"default_item":3,"flag":0},"POKEDEX_REWARD_144":{"address":5729654,"default_item":3,"flag":0},"POKEDEX_REWARD_145":{"address":5729656,"default_item":3,"flag":0},"POKEDEX_REWARD_146":{"address":5729658,"default_item":3,"flag":0},"POKEDEX_REWARD_147":{"address":5729660,"default_item":3,"flag":0},"POKEDEX_REWARD_148":{"address":5729662,"default_item":3,"flag":0},"POKEDEX_REWARD_149":{"address":5729664,"default_item":3,"flag":0},"POKEDEX_REWARD_150":{"address":5729666,"default_item":3,"flag":0},"POKEDEX_REWARD_151":{"address":5729668,"default_item":3,"flag":0},"POKEDEX_REWARD_152":{"address":5729670,"default_item":3,"flag":0},"POKEDEX_REWARD_153":{"address":5729672,"default_item":3,"flag":0},"POKEDEX_REWARD_154":{"address":5729674,"default_item":3,"flag":0},"POKEDEX_REWARD_155":{"address":5729676,"default_item":3,"flag":0},"POKEDEX_REWARD_156":{"address":5729678,"default_item":3,"flag":0},"POKEDEX_REWARD_157":{"address":5729680,"default_item":3,"flag":0},"POKEDEX_REWARD_158":{"address":5729682,"default_item":3,"flag":0},"POKEDEX_REWARD_159":{"address":5729684,"default_item":3,"flag":0},"POKEDEX_REWARD_160":{"address":5729686,"default_item":3,"flag":0},"POKEDEX_REWARD_161":{"address":5729688,"default_item":3,"flag":0},"POKEDEX_REWARD_162":{"address":5729690,"default_item":3,"flag":0},"POKEDEX_REWARD_163":{"address":5729692,"default_item":3,"flag":0},"POKEDEX_REWARD_164":{"address":5729694,"default_item":3,"flag":0},"POKEDEX_REWARD_165":{"address":5729696,"default_item":3,"flag":0},"POKEDEX_REWARD_166":{"address":5729698,"default_item":3,"flag":0},"POKEDEX_REWARD_167":{"address":5729700,"default_item":3,"flag":0},"POKEDEX_REWARD_168":{"address":5729702,"default_item":3,"flag":0},"POKEDEX_REWARD_169":{"address":5729704,"default_item":3,"flag":0},"POKEDEX_REWARD_170":{"address":5729706,"default_item":3,"flag":0},"POKEDEX_REWARD_171":{"address":5729708,"default_item":3,"flag":0},"POKEDEX_REWARD_172":{"address":5729710,"default_item":3,"flag":0},"POKEDEX_REWARD_173":{"address":5729712,"default_item":3,"flag":0},"POKEDEX_REWARD_174":{"address":5729714,"default_item":3,"flag":0},"POKEDEX_REWARD_175":{"address":5729716,"default_item":3,"flag":0},"POKEDEX_REWARD_176":{"address":5729718,"default_item":3,"flag":0},"POKEDEX_REWARD_177":{"address":5729720,"default_item":3,"flag":0},"POKEDEX_REWARD_178":{"address":5729722,"default_item":3,"flag":0},"POKEDEX_REWARD_179":{"address":5729724,"default_item":3,"flag":0},"POKEDEX_REWARD_180":{"address":5729726,"default_item":3,"flag":0},"POKEDEX_REWARD_181":{"address":5729728,"default_item":3,"flag":0},"POKEDEX_REWARD_182":{"address":5729730,"default_item":3,"flag":0},"POKEDEX_REWARD_183":{"address":5729732,"default_item":3,"flag":0},"POKEDEX_REWARD_184":{"address":5729734,"default_item":3,"flag":0},"POKEDEX_REWARD_185":{"address":5729736,"default_item":3,"flag":0},"POKEDEX_REWARD_186":{"address":5729738,"default_item":3,"flag":0},"POKEDEX_REWARD_187":{"address":5729740,"default_item":3,"flag":0},"POKEDEX_REWARD_188":{"address":5729742,"default_item":3,"flag":0},"POKEDEX_REWARD_189":{"address":5729744,"default_item":3,"flag":0},"POKEDEX_REWARD_190":{"address":5729746,"default_item":3,"flag":0},"POKEDEX_REWARD_191":{"address":5729748,"default_item":3,"flag":0},"POKEDEX_REWARD_192":{"address":5729750,"default_item":3,"flag":0},"POKEDEX_REWARD_193":{"address":5729752,"default_item":3,"flag":0},"POKEDEX_REWARD_194":{"address":5729754,"default_item":3,"flag":0},"POKEDEX_REWARD_195":{"address":5729756,"default_item":3,"flag":0},"POKEDEX_REWARD_196":{"address":5729758,"default_item":3,"flag":0},"POKEDEX_REWARD_197":{"address":5729760,"default_item":3,"flag":0},"POKEDEX_REWARD_198":{"address":5729762,"default_item":3,"flag":0},"POKEDEX_REWARD_199":{"address":5729764,"default_item":3,"flag":0},"POKEDEX_REWARD_200":{"address":5729766,"default_item":3,"flag":0},"POKEDEX_REWARD_201":{"address":5729768,"default_item":3,"flag":0},"POKEDEX_REWARD_202":{"address":5729770,"default_item":3,"flag":0},"POKEDEX_REWARD_203":{"address":5729772,"default_item":3,"flag":0},"POKEDEX_REWARD_204":{"address":5729774,"default_item":3,"flag":0},"POKEDEX_REWARD_205":{"address":5729776,"default_item":3,"flag":0},"POKEDEX_REWARD_206":{"address":5729778,"default_item":3,"flag":0},"POKEDEX_REWARD_207":{"address":5729780,"default_item":3,"flag":0},"POKEDEX_REWARD_208":{"address":5729782,"default_item":3,"flag":0},"POKEDEX_REWARD_209":{"address":5729784,"default_item":3,"flag":0},"POKEDEX_REWARD_210":{"address":5729786,"default_item":3,"flag":0},"POKEDEX_REWARD_211":{"address":5729788,"default_item":3,"flag":0},"POKEDEX_REWARD_212":{"address":5729790,"default_item":3,"flag":0},"POKEDEX_REWARD_213":{"address":5729792,"default_item":3,"flag":0},"POKEDEX_REWARD_214":{"address":5729794,"default_item":3,"flag":0},"POKEDEX_REWARD_215":{"address":5729796,"default_item":3,"flag":0},"POKEDEX_REWARD_216":{"address":5729798,"default_item":3,"flag":0},"POKEDEX_REWARD_217":{"address":5729800,"default_item":3,"flag":0},"POKEDEX_REWARD_218":{"address":5729802,"default_item":3,"flag":0},"POKEDEX_REWARD_219":{"address":5729804,"default_item":3,"flag":0},"POKEDEX_REWARD_220":{"address":5729806,"default_item":3,"flag":0},"POKEDEX_REWARD_221":{"address":5729808,"default_item":3,"flag":0},"POKEDEX_REWARD_222":{"address":5729810,"default_item":3,"flag":0},"POKEDEX_REWARD_223":{"address":5729812,"default_item":3,"flag":0},"POKEDEX_REWARD_224":{"address":5729814,"default_item":3,"flag":0},"POKEDEX_REWARD_225":{"address":5729816,"default_item":3,"flag":0},"POKEDEX_REWARD_226":{"address":5729818,"default_item":3,"flag":0},"POKEDEX_REWARD_227":{"address":5729820,"default_item":3,"flag":0},"POKEDEX_REWARD_228":{"address":5729822,"default_item":3,"flag":0},"POKEDEX_REWARD_229":{"address":5729824,"default_item":3,"flag":0},"POKEDEX_REWARD_230":{"address":5729826,"default_item":3,"flag":0},"POKEDEX_REWARD_231":{"address":5729828,"default_item":3,"flag":0},"POKEDEX_REWARD_232":{"address":5729830,"default_item":3,"flag":0},"POKEDEX_REWARD_233":{"address":5729832,"default_item":3,"flag":0},"POKEDEX_REWARD_234":{"address":5729834,"default_item":3,"flag":0},"POKEDEX_REWARD_235":{"address":5729836,"default_item":3,"flag":0},"POKEDEX_REWARD_236":{"address":5729838,"default_item":3,"flag":0},"POKEDEX_REWARD_237":{"address":5729840,"default_item":3,"flag":0},"POKEDEX_REWARD_238":{"address":5729842,"default_item":3,"flag":0},"POKEDEX_REWARD_239":{"address":5729844,"default_item":3,"flag":0},"POKEDEX_REWARD_240":{"address":5729846,"default_item":3,"flag":0},"POKEDEX_REWARD_241":{"address":5729848,"default_item":3,"flag":0},"POKEDEX_REWARD_242":{"address":5729850,"default_item":3,"flag":0},"POKEDEX_REWARD_243":{"address":5729852,"default_item":3,"flag":0},"POKEDEX_REWARD_244":{"address":5729854,"default_item":3,"flag":0},"POKEDEX_REWARD_245":{"address":5729856,"default_item":3,"flag":0},"POKEDEX_REWARD_246":{"address":5729858,"default_item":3,"flag":0},"POKEDEX_REWARD_247":{"address":5729860,"default_item":3,"flag":0},"POKEDEX_REWARD_248":{"address":5729862,"default_item":3,"flag":0},"POKEDEX_REWARD_249":{"address":5729864,"default_item":3,"flag":0},"POKEDEX_REWARD_250":{"address":5729866,"default_item":3,"flag":0},"POKEDEX_REWARD_251":{"address":5729868,"default_item":3,"flag":0},"POKEDEX_REWARD_252":{"address":5729870,"default_item":3,"flag":0},"POKEDEX_REWARD_253":{"address":5729872,"default_item":3,"flag":0},"POKEDEX_REWARD_254":{"address":5729874,"default_item":3,"flag":0},"POKEDEX_REWARD_255":{"address":5729876,"default_item":3,"flag":0},"POKEDEX_REWARD_256":{"address":5729878,"default_item":3,"flag":0},"POKEDEX_REWARD_257":{"address":5729880,"default_item":3,"flag":0},"POKEDEX_REWARD_258":{"address":5729882,"default_item":3,"flag":0},"POKEDEX_REWARD_259":{"address":5729884,"default_item":3,"flag":0},"POKEDEX_REWARD_260":{"address":5729886,"default_item":3,"flag":0},"POKEDEX_REWARD_261":{"address":5729888,"default_item":3,"flag":0},"POKEDEX_REWARD_262":{"address":5729890,"default_item":3,"flag":0},"POKEDEX_REWARD_263":{"address":5729892,"default_item":3,"flag":0},"POKEDEX_REWARD_264":{"address":5729894,"default_item":3,"flag":0},"POKEDEX_REWARD_265":{"address":5729896,"default_item":3,"flag":0},"POKEDEX_REWARD_266":{"address":5729898,"default_item":3,"flag":0},"POKEDEX_REWARD_267":{"address":5729900,"default_item":3,"flag":0},"POKEDEX_REWARD_268":{"address":5729902,"default_item":3,"flag":0},"POKEDEX_REWARD_269":{"address":5729904,"default_item":3,"flag":0},"POKEDEX_REWARD_270":{"address":5729906,"default_item":3,"flag":0},"POKEDEX_REWARD_271":{"address":5729908,"default_item":3,"flag":0},"POKEDEX_REWARD_272":{"address":5729910,"default_item":3,"flag":0},"POKEDEX_REWARD_273":{"address":5729912,"default_item":3,"flag":0},"POKEDEX_REWARD_274":{"address":5729914,"default_item":3,"flag":0},"POKEDEX_REWARD_275":{"address":5729916,"default_item":3,"flag":0},"POKEDEX_REWARD_276":{"address":5729918,"default_item":3,"flag":0},"POKEDEX_REWARD_277":{"address":5729920,"default_item":3,"flag":0},"POKEDEX_REWARD_278":{"address":5729922,"default_item":3,"flag":0},"POKEDEX_REWARD_279":{"address":5729924,"default_item":3,"flag":0},"POKEDEX_REWARD_280":{"address":5729926,"default_item":3,"flag":0},"POKEDEX_REWARD_281":{"address":5729928,"default_item":3,"flag":0},"POKEDEX_REWARD_282":{"address":5729930,"default_item":3,"flag":0},"POKEDEX_REWARD_283":{"address":5729932,"default_item":3,"flag":0},"POKEDEX_REWARD_284":{"address":5729934,"default_item":3,"flag":0},"POKEDEX_REWARD_285":{"address":5729936,"default_item":3,"flag":0},"POKEDEX_REWARD_286":{"address":5729938,"default_item":3,"flag":0},"POKEDEX_REWARD_287":{"address":5729940,"default_item":3,"flag":0},"POKEDEX_REWARD_288":{"address":5729942,"default_item":3,"flag":0},"POKEDEX_REWARD_289":{"address":5729944,"default_item":3,"flag":0},"POKEDEX_REWARD_290":{"address":5729946,"default_item":3,"flag":0},"POKEDEX_REWARD_291":{"address":5729948,"default_item":3,"flag":0},"POKEDEX_REWARD_292":{"address":5729950,"default_item":3,"flag":0},"POKEDEX_REWARD_293":{"address":5729952,"default_item":3,"flag":0},"POKEDEX_REWARD_294":{"address":5729954,"default_item":3,"flag":0},"POKEDEX_REWARD_295":{"address":5729956,"default_item":3,"flag":0},"POKEDEX_REWARD_296":{"address":5729958,"default_item":3,"flag":0},"POKEDEX_REWARD_297":{"address":5729960,"default_item":3,"flag":0},"POKEDEX_REWARD_298":{"address":5729962,"default_item":3,"flag":0},"POKEDEX_REWARD_299":{"address":5729964,"default_item":3,"flag":0},"POKEDEX_REWARD_300":{"address":5729966,"default_item":3,"flag":0},"POKEDEX_REWARD_301":{"address":5729968,"default_item":3,"flag":0},"POKEDEX_REWARD_302":{"address":5729970,"default_item":3,"flag":0},"POKEDEX_REWARD_303":{"address":5729972,"default_item":3,"flag":0},"POKEDEX_REWARD_304":{"address":5729974,"default_item":3,"flag":0},"POKEDEX_REWARD_305":{"address":5729976,"default_item":3,"flag":0},"POKEDEX_REWARD_306":{"address":5729978,"default_item":3,"flag":0},"POKEDEX_REWARD_307":{"address":5729980,"default_item":3,"flag":0},"POKEDEX_REWARD_308":{"address":5729982,"default_item":3,"flag":0},"POKEDEX_REWARD_309":{"address":5729984,"default_item":3,"flag":0},"POKEDEX_REWARD_310":{"address":5729986,"default_item":3,"flag":0},"POKEDEX_REWARD_311":{"address":5729988,"default_item":3,"flag":0},"POKEDEX_REWARD_312":{"address":5729990,"default_item":3,"flag":0},"POKEDEX_REWARD_313":{"address":5729992,"default_item":3,"flag":0},"POKEDEX_REWARD_314":{"address":5729994,"default_item":3,"flag":0},"POKEDEX_REWARD_315":{"address":5729996,"default_item":3,"flag":0},"POKEDEX_REWARD_316":{"address":5729998,"default_item":3,"flag":0},"POKEDEX_REWARD_317":{"address":5730000,"default_item":3,"flag":0},"POKEDEX_REWARD_318":{"address":5730002,"default_item":3,"flag":0},"POKEDEX_REWARD_319":{"address":5730004,"default_item":3,"flag":0},"POKEDEX_REWARD_320":{"address":5730006,"default_item":3,"flag":0},"POKEDEX_REWARD_321":{"address":5730008,"default_item":3,"flag":0},"POKEDEX_REWARD_322":{"address":5730010,"default_item":3,"flag":0},"POKEDEX_REWARD_323":{"address":5730012,"default_item":3,"flag":0},"POKEDEX_REWARD_324":{"address":5730014,"default_item":3,"flag":0},"POKEDEX_REWARD_325":{"address":5730016,"default_item":3,"flag":0},"POKEDEX_REWARD_326":{"address":5730018,"default_item":3,"flag":0},"POKEDEX_REWARD_327":{"address":5730020,"default_item":3,"flag":0},"POKEDEX_REWARD_328":{"address":5730022,"default_item":3,"flag":0},"POKEDEX_REWARD_329":{"address":5730024,"default_item":3,"flag":0},"POKEDEX_REWARD_330":{"address":5730026,"default_item":3,"flag":0},"POKEDEX_REWARD_331":{"address":5730028,"default_item":3,"flag":0},"POKEDEX_REWARD_332":{"address":5730030,"default_item":3,"flag":0},"POKEDEX_REWARD_333":{"address":5730032,"default_item":3,"flag":0},"POKEDEX_REWARD_334":{"address":5730034,"default_item":3,"flag":0},"POKEDEX_REWARD_335":{"address":5730036,"default_item":3,"flag":0},"POKEDEX_REWARD_336":{"address":5730038,"default_item":3,"flag":0},"POKEDEX_REWARD_337":{"address":5730040,"default_item":3,"flag":0},"POKEDEX_REWARD_338":{"address":5730042,"default_item":3,"flag":0},"POKEDEX_REWARD_339":{"address":5730044,"default_item":3,"flag":0},"POKEDEX_REWARD_340":{"address":5730046,"default_item":3,"flag":0},"POKEDEX_REWARD_341":{"address":5730048,"default_item":3,"flag":0},"POKEDEX_REWARD_342":{"address":5730050,"default_item":3,"flag":0},"POKEDEX_REWARD_343":{"address":5730052,"default_item":3,"flag":0},"POKEDEX_REWARD_344":{"address":5730054,"default_item":3,"flag":0},"POKEDEX_REWARD_345":{"address":5730056,"default_item":3,"flag":0},"POKEDEX_REWARD_346":{"address":5730058,"default_item":3,"flag":0},"POKEDEX_REWARD_347":{"address":5730060,"default_item":3,"flag":0},"POKEDEX_REWARD_348":{"address":5730062,"default_item":3,"flag":0},"POKEDEX_REWARD_349":{"address":5730064,"default_item":3,"flag":0},"POKEDEX_REWARD_350":{"address":5730066,"default_item":3,"flag":0},"POKEDEX_REWARD_351":{"address":5730068,"default_item":3,"flag":0},"POKEDEX_REWARD_352":{"address":5730070,"default_item":3,"flag":0},"POKEDEX_REWARD_353":{"address":5730072,"default_item":3,"flag":0},"POKEDEX_REWARD_354":{"address":5730074,"default_item":3,"flag":0},"POKEDEX_REWARD_355":{"address":5730076,"default_item":3,"flag":0},"POKEDEX_REWARD_356":{"address":5730078,"default_item":3,"flag":0},"POKEDEX_REWARD_357":{"address":5730080,"default_item":3,"flag":0},"POKEDEX_REWARD_358":{"address":5730082,"default_item":3,"flag":0},"POKEDEX_REWARD_359":{"address":5730084,"default_item":3,"flag":0},"POKEDEX_REWARD_360":{"address":5730086,"default_item":3,"flag":0},"POKEDEX_REWARD_361":{"address":5730088,"default_item":3,"flag":0},"POKEDEX_REWARD_362":{"address":5730090,"default_item":3,"flag":0},"POKEDEX_REWARD_363":{"address":5730092,"default_item":3,"flag":0},"POKEDEX_REWARD_364":{"address":5730094,"default_item":3,"flag":0},"POKEDEX_REWARD_365":{"address":5730096,"default_item":3,"flag":0},"POKEDEX_REWARD_366":{"address":5730098,"default_item":3,"flag":0},"POKEDEX_REWARD_367":{"address":5730100,"default_item":3,"flag":0},"POKEDEX_REWARD_368":{"address":5730102,"default_item":3,"flag":0},"POKEDEX_REWARD_369":{"address":5730104,"default_item":3,"flag":0},"POKEDEX_REWARD_370":{"address":5730106,"default_item":3,"flag":0},"POKEDEX_REWARD_371":{"address":5730108,"default_item":3,"flag":0},"POKEDEX_REWARD_372":{"address":5730110,"default_item":3,"flag":0},"POKEDEX_REWARD_373":{"address":5730112,"default_item":3,"flag":0},"POKEDEX_REWARD_374":{"address":5730114,"default_item":3,"flag":0},"POKEDEX_REWARD_375":{"address":5730116,"default_item":3,"flag":0},"POKEDEX_REWARD_376":{"address":5730118,"default_item":3,"flag":0},"POKEDEX_REWARD_377":{"address":5730120,"default_item":3,"flag":0},"POKEDEX_REWARD_378":{"address":5730122,"default_item":3,"flag":0},"POKEDEX_REWARD_379":{"address":5730124,"default_item":3,"flag":0},"POKEDEX_REWARD_380":{"address":5730126,"default_item":3,"flag":0},"POKEDEX_REWARD_381":{"address":5730128,"default_item":3,"flag":0},"POKEDEX_REWARD_382":{"address":5730130,"default_item":3,"flag":0},"POKEDEX_REWARD_383":{"address":5730132,"default_item":3,"flag":0},"POKEDEX_REWARD_384":{"address":5730134,"default_item":3,"flag":0},"POKEDEX_REWARD_385":{"address":5730136,"default_item":3,"flag":0},"POKEDEX_REWARD_386":{"address":5730138,"default_item":3,"flag":0},"TRAINER_AARON_REWARD":{"address":5602878,"default_item":104,"flag":1677},"TRAINER_ABIGAIL_1_REWARD":{"address":5602800,"default_item":106,"flag":1638},"TRAINER_AIDAN_REWARD":{"address":5603432,"default_item":104,"flag":1954},"TRAINER_AISHA_REWARD":{"address":5603598,"default_item":106,"flag":2037},"TRAINER_ALBERTO_REWARD":{"address":5602108,"default_item":108,"flag":1292},"TRAINER_ALBERT_REWARD":{"address":5602244,"default_item":104,"flag":1360},"TRAINER_ALEXA_REWARD":{"address":5603424,"default_item":104,"flag":1950},"TRAINER_ALEXIA_REWARD":{"address":5602264,"default_item":104,"flag":1370},"TRAINER_ALEX_REWARD":{"address":5602910,"default_item":104,"flag":1693},"TRAINER_ALICE_REWARD":{"address":5602980,"default_item":103,"flag":1728},"TRAINER_ALIX_REWARD":{"address":5603584,"default_item":106,"flag":2030},"TRAINER_ALLEN_REWARD":{"address":5602750,"default_item":103,"flag":1613},"TRAINER_ALLISON_REWARD":{"address":5602858,"default_item":104,"flag":1667},"TRAINER_ALYSSA_REWARD":{"address":5603486,"default_item":106,"flag":1981},"TRAINER_AMY_AND_LIV_1_REWARD":{"address":5603046,"default_item":103,"flag":1761},"TRAINER_ANDREA_REWARD":{"address":5603310,"default_item":106,"flag":1893},"TRAINER_ANDRES_1_REWARD":{"address":5603558,"default_item":104,"flag":2017},"TRAINER_ANDREW_REWARD":{"address":5602756,"default_item":106,"flag":1616},"TRAINER_ANGELICA_REWARD":{"address":5602956,"default_item":104,"flag":1716},"TRAINER_ANGELINA_REWARD":{"address":5603508,"default_item":106,"flag":1992},"TRAINER_ANGELO_REWARD":{"address":5603688,"default_item":104,"flag":2082},"TRAINER_ANNA_AND_MEG_1_REWARD":{"address":5602658,"default_item":106,"flag":1567},"TRAINER_ANNIKA_REWARD":{"address":5603088,"default_item":107,"flag":1782},"TRAINER_ANTHONY_REWARD":{"address":5602788,"default_item":106,"flag":1632},"TRAINER_ARCHIE_REWARD":{"address":5602152,"default_item":107,"flag":1314},"TRAINER_ASHLEY_REWARD":{"address":5603394,"default_item":106,"flag":1935},"TRAINER_ATHENA_REWARD":{"address":5603238,"default_item":104,"flag":1857},"TRAINER_ATSUSHI_REWARD":{"address":5602464,"default_item":104,"flag":1470},"TRAINER_AURON_REWARD":{"address":5603096,"default_item":104,"flag":1786},"TRAINER_AUSTINA_REWARD":{"address":5602200,"default_item":103,"flag":1338},"TRAINER_AUTUMN_REWARD":{"address":5602518,"default_item":106,"flag":1497},"TRAINER_AXLE_REWARD":{"address":5602490,"default_item":108,"flag":1483},"TRAINER_BARNY_REWARD":{"address":5602770,"default_item":104,"flag":1623},"TRAINER_BARRY_REWARD":{"address":5602410,"default_item":106,"flag":1443},"TRAINER_BEAU_REWARD":{"address":5602508,"default_item":106,"flag":1492},"TRAINER_BECKY_REWARD":{"address":5603024,"default_item":106,"flag":1750},"TRAINER_BECK_REWARD":{"address":5602912,"default_item":104,"flag":1694},"TRAINER_BENJAMIN_1_REWARD":{"address":5602790,"default_item":106,"flag":1633},"TRAINER_BEN_REWARD":{"address":5602730,"default_item":106,"flag":1603},"TRAINER_BERKE_REWARD":{"address":5602232,"default_item":104,"flag":1354},"TRAINER_BERNIE_1_REWARD":{"address":5602496,"default_item":106,"flag":1486},"TRAINER_BETHANY_REWARD":{"address":5602686,"default_item":107,"flag":1581},"TRAINER_BETH_REWARD":{"address":5602974,"default_item":103,"flag":1725},"TRAINER_BEVERLY_REWARD":{"address":5602966,"default_item":103,"flag":1721},"TRAINER_BIANCA_REWARD":{"address":5603496,"default_item":106,"flag":1986},"TRAINER_BILLY_REWARD":{"address":5602722,"default_item":103,"flag":1599},"TRAINER_BLAKE_REWARD":{"address":5602554,"default_item":108,"flag":1515},"TRAINER_BRANDEN_REWARD":{"address":5603574,"default_item":106,"flag":2025},"TRAINER_BRANDI_REWARD":{"address":5603596,"default_item":106,"flag":2036},"TRAINER_BRAWLY_1_REWARD":{"address":5602616,"default_item":104,"flag":1546},"TRAINER_BRAXTON_REWARD":{"address":5602234,"default_item":104,"flag":1355},"TRAINER_BRENDAN_LILYCOVE_MUDKIP_REWARD":{"address":5603406,"default_item":104,"flag":1941},"TRAINER_BRENDAN_LILYCOVE_TORCHIC_REWARD":{"address":5603410,"default_item":104,"flag":1943},"TRAINER_BRENDAN_LILYCOVE_TREECKO_REWARD":{"address":5603408,"default_item":104,"flag":1942},"TRAINER_BRENDAN_ROUTE_103_MUDKIP_REWARD":{"address":5603124,"default_item":106,"flag":1800},"TRAINER_BRENDAN_ROUTE_103_TORCHIC_REWARD":{"address":5603136,"default_item":106,"flag":1806},"TRAINER_BRENDAN_ROUTE_103_TREECKO_REWARD":{"address":5603130,"default_item":106,"flag":1803},"TRAINER_BRENDAN_ROUTE_110_MUDKIP_REWARD":{"address":5603126,"default_item":104,"flag":1801},"TRAINER_BRENDAN_ROUTE_110_TORCHIC_REWARD":{"address":5603138,"default_item":104,"flag":1807},"TRAINER_BRENDAN_ROUTE_110_TREECKO_REWARD":{"address":5603132,"default_item":104,"flag":1804},"TRAINER_BRENDAN_ROUTE_119_MUDKIP_REWARD":{"address":5603128,"default_item":104,"flag":1802},"TRAINER_BRENDAN_ROUTE_119_TORCHIC_REWARD":{"address":5603140,"default_item":104,"flag":1808},"TRAINER_BRENDAN_ROUTE_119_TREECKO_REWARD":{"address":5603134,"default_item":104,"flag":1805},"TRAINER_BRENDAN_RUSTBORO_MUDKIP_REWARD":{"address":5603270,"default_item":108,"flag":1873},"TRAINER_BRENDAN_RUSTBORO_TORCHIC_REWARD":{"address":5603282,"default_item":108,"flag":1879},"TRAINER_BRENDAN_RUSTBORO_TREECKO_REWARD":{"address":5603268,"default_item":108,"flag":1872},"TRAINER_BRENDA_REWARD":{"address":5602992,"default_item":106,"flag":1734},"TRAINER_BRENDEN_REWARD":{"address":5603228,"default_item":106,"flag":1852},"TRAINER_BRENT_REWARD":{"address":5602530,"default_item":104,"flag":1503},"TRAINER_BRIANNA_REWARD":{"address":5602320,"default_item":110,"flag":1398},"TRAINER_BRICE_REWARD":{"address":5603336,"default_item":106,"flag":1906},"TRAINER_BRIDGET_REWARD":{"address":5602342,"default_item":107,"flag":1409},"TRAINER_BROOKE_1_REWARD":{"address":5602272,"default_item":108,"flag":1374},"TRAINER_BRYANT_REWARD":{"address":5603576,"default_item":106,"flag":2026},"TRAINER_BRYAN_REWARD":{"address":5603572,"default_item":104,"flag":2024},"TRAINER_CALE_REWARD":{"address":5603612,"default_item":104,"flag":2044},"TRAINER_CALLIE_REWARD":{"address":5603610,"default_item":106,"flag":2043},"TRAINER_CALVIN_1_REWARD":{"address":5602720,"default_item":103,"flag":1598},"TRAINER_CAMDEN_REWARD":{"address":5602832,"default_item":104,"flag":1654},"TRAINER_CAMERON_1_REWARD":{"address":5602560,"default_item":108,"flag":1518},"TRAINER_CAMRON_REWARD":{"address":5603562,"default_item":104,"flag":2019},"TRAINER_CARLEE_REWARD":{"address":5603012,"default_item":106,"flag":1744},"TRAINER_CAROLINA_REWARD":{"address":5603566,"default_item":104,"flag":2021},"TRAINER_CAROLINE_REWARD":{"address":5602282,"default_item":104,"flag":1379},"TRAINER_CAROL_REWARD":{"address":5603026,"default_item":106,"flag":1751},"TRAINER_CARTER_REWARD":{"address":5602774,"default_item":104,"flag":1625},"TRAINER_CATHERINE_1_REWARD":{"address":5603202,"default_item":104,"flag":1839},"TRAINER_CEDRIC_REWARD":{"address":5603034,"default_item":108,"flag":1755},"TRAINER_CELIA_REWARD":{"address":5603570,"default_item":106,"flag":2023},"TRAINER_CELINA_REWARD":{"address":5603494,"default_item":108,"flag":1985},"TRAINER_CHAD_REWARD":{"address":5602432,"default_item":106,"flag":1454},"TRAINER_CHANDLER_REWARD":{"address":5603480,"default_item":103,"flag":1978},"TRAINER_CHARLIE_REWARD":{"address":5602216,"default_item":103,"flag":1346},"TRAINER_CHARLOTTE_REWARD":{"address":5603512,"default_item":106,"flag":1994},"TRAINER_CHASE_REWARD":{"address":5602840,"default_item":104,"flag":1658},"TRAINER_CHESTER_REWARD":{"address":5602900,"default_item":108,"flag":1688},"TRAINER_CHIP_REWARD":{"address":5602174,"default_item":104,"flag":1325},"TRAINER_CHRIS_REWARD":{"address":5603470,"default_item":108,"flag":1973},"TRAINER_CINDY_1_REWARD":{"address":5602312,"default_item":104,"flag":1394},"TRAINER_CLARENCE_REWARD":{"address":5603244,"default_item":106,"flag":1860},"TRAINER_CLARISSA_REWARD":{"address":5602954,"default_item":104,"flag":1715},"TRAINER_CLARK_REWARD":{"address":5603346,"default_item":106,"flag":1911},"TRAINER_CLAUDE_REWARD":{"address":5602760,"default_item":108,"flag":1618},"TRAINER_CLIFFORD_REWARD":{"address":5603252,"default_item":107,"flag":1864},"TRAINER_COBY_REWARD":{"address":5603502,"default_item":106,"flag":1989},"TRAINER_COLE_REWARD":{"address":5602486,"default_item":108,"flag":1481},"TRAINER_COLIN_REWARD":{"address":5602894,"default_item":108,"flag":1685},"TRAINER_COLTON_REWARD":{"address":5602672,"default_item":107,"flag":1574},"TRAINER_CONNIE_REWARD":{"address":5602340,"default_item":107,"flag":1408},"TRAINER_CONOR_REWARD":{"address":5603106,"default_item":104,"flag":1791},"TRAINER_CORY_1_REWARD":{"address":5603564,"default_item":108,"flag":2020},"TRAINER_CRISSY_REWARD":{"address":5603312,"default_item":106,"flag":1894},"TRAINER_CRISTIAN_REWARD":{"address":5603232,"default_item":106,"flag":1854},"TRAINER_CRISTIN_1_REWARD":{"address":5603618,"default_item":104,"flag":2047},"TRAINER_CYNDY_1_REWARD":{"address":5602938,"default_item":106,"flag":1707},"TRAINER_DAISUKE_REWARD":{"address":5602462,"default_item":106,"flag":1469},"TRAINER_DAISY_REWARD":{"address":5602156,"default_item":106,"flag":1316},"TRAINER_DALE_REWARD":{"address":5602766,"default_item":106,"flag":1621},"TRAINER_DALTON_1_REWARD":{"address":5602476,"default_item":106,"flag":1476},"TRAINER_DANA_REWARD":{"address":5603000,"default_item":106,"flag":1738},"TRAINER_DANIELLE_REWARD":{"address":5603384,"default_item":106,"flag":1930},"TRAINER_DAPHNE_REWARD":{"address":5602314,"default_item":110,"flag":1395},"TRAINER_DARCY_REWARD":{"address":5603550,"default_item":104,"flag":2013},"TRAINER_DARIAN_REWARD":{"address":5603476,"default_item":106,"flag":1976},"TRAINER_DARIUS_REWARD":{"address":5603690,"default_item":108,"flag":2083},"TRAINER_DARRIN_REWARD":{"address":5602392,"default_item":103,"flag":1434},"TRAINER_DAVID_REWARD":{"address":5602400,"default_item":103,"flag":1438},"TRAINER_DAVIS_REWARD":{"address":5603162,"default_item":106,"flag":1819},"TRAINER_DAWSON_REWARD":{"address":5603472,"default_item":104,"flag":1974},"TRAINER_DAYTON_REWARD":{"address":5603604,"default_item":108,"flag":2040},"TRAINER_DEANDRE_REWARD":{"address":5603514,"default_item":103,"flag":1995},"TRAINER_DEAN_REWARD":{"address":5602412,"default_item":103,"flag":1444},"TRAINER_DEBRA_REWARD":{"address":5603004,"default_item":106,"flag":1740},"TRAINER_DECLAN_REWARD":{"address":5602114,"default_item":106,"flag":1295},"TRAINER_DEMETRIUS_REWARD":{"address":5602834,"default_item":106,"flag":1655},"TRAINER_DENISE_REWARD":{"address":5602972,"default_item":103,"flag":1724},"TRAINER_DEREK_REWARD":{"address":5602538,"default_item":108,"flag":1507},"TRAINER_DEVAN_REWARD":{"address":5603590,"default_item":106,"flag":2033},"TRAINER_DEZ_AND_LUKE_REWARD":{"address":5603364,"default_item":108,"flag":1920},"TRAINER_DIANA_1_REWARD":{"address":5603032,"default_item":106,"flag":1754},"TRAINER_DIANNE_REWARD":{"address":5602918,"default_item":104,"flag":1697},"TRAINER_DILLON_REWARD":{"address":5602738,"default_item":106,"flag":1607},"TRAINER_DOMINIK_REWARD":{"address":5602388,"default_item":103,"flag":1432},"TRAINER_DONALD_REWARD":{"address":5602532,"default_item":104,"flag":1504},"TRAINER_DONNY_REWARD":{"address":5602852,"default_item":104,"flag":1664},"TRAINER_DOUGLAS_REWARD":{"address":5602390,"default_item":103,"flag":1433},"TRAINER_DOUG_REWARD":{"address":5603320,"default_item":106,"flag":1898},"TRAINER_DRAKE_REWARD":{"address":5602612,"default_item":110,"flag":1544},"TRAINER_DREW_REWARD":{"address":5602506,"default_item":106,"flag":1491},"TRAINER_DUNCAN_REWARD":{"address":5603076,"default_item":108,"flag":1776},"TRAINER_DUSTY_1_REWARD":{"address":5602172,"default_item":104,"flag":1324},"TRAINER_DWAYNE_REWARD":{"address":5603070,"default_item":106,"flag":1773},"TRAINER_DYLAN_1_REWARD":{"address":5602812,"default_item":106,"flag":1644},"TRAINER_EDGAR_REWARD":{"address":5602242,"default_item":104,"flag":1359},"TRAINER_EDMOND_REWARD":{"address":5603066,"default_item":106,"flag":1771},"TRAINER_EDWARDO_REWARD":{"address":5602892,"default_item":108,"flag":1684},"TRAINER_EDWARD_REWARD":{"address":5602548,"default_item":106,"flag":1512},"TRAINER_EDWIN_1_REWARD":{"address":5603108,"default_item":108,"flag":1792},"TRAINER_ED_REWARD":{"address":5602110,"default_item":104,"flag":1293},"TRAINER_ELIJAH_REWARD":{"address":5603568,"default_item":108,"flag":2022},"TRAINER_ELI_REWARD":{"address":5603086,"default_item":108,"flag":1781},"TRAINER_ELLIOT_1_REWARD":{"address":5602762,"default_item":106,"flag":1619},"TRAINER_ERIC_REWARD":{"address":5603348,"default_item":108,"flag":1912},"TRAINER_ERNEST_1_REWARD":{"address":5603068,"default_item":104,"flag":1772},"TRAINER_ETHAN_1_REWARD":{"address":5602516,"default_item":106,"flag":1496},"TRAINER_FABIAN_REWARD":{"address":5603602,"default_item":108,"flag":2039},"TRAINER_FELIX_REWARD":{"address":5602160,"default_item":104,"flag":1318},"TRAINER_FERNANDO_1_REWARD":{"address":5602474,"default_item":108,"flag":1475},"TRAINER_FLANNERY_1_REWARD":{"address":5602620,"default_item":107,"flag":1548},"TRAINER_FLINT_REWARD":{"address":5603392,"default_item":106,"flag":1934},"TRAINER_FOSTER_REWARD":{"address":5602176,"default_item":104,"flag":1326},"TRAINER_FRANKLIN_REWARD":{"address":5602424,"default_item":106,"flag":1450},"TRAINER_FREDRICK_REWARD":{"address":5602142,"default_item":104,"flag":1309},"TRAINER_GABRIELLE_1_REWARD":{"address":5602102,"default_item":104,"flag":1289},"TRAINER_GARRET_REWARD":{"address":5602360,"default_item":110,"flag":1418},"TRAINER_GARRISON_REWARD":{"address":5603178,"default_item":104,"flag":1827},"TRAINER_GEORGE_REWARD":{"address":5602230,"default_item":104,"flag":1353},"TRAINER_GERALD_REWARD":{"address":5603380,"default_item":104,"flag":1928},"TRAINER_GILBERT_REWARD":{"address":5602422,"default_item":106,"flag":1449},"TRAINER_GINA_AND_MIA_1_REWARD":{"address":5603050,"default_item":103,"flag":1763},"TRAINER_GLACIA_REWARD":{"address":5602610,"default_item":110,"flag":1543},"TRAINER_GRACE_REWARD":{"address":5602984,"default_item":106,"flag":1730},"TRAINER_GREG_REWARD":{"address":5603322,"default_item":106,"flag":1899},"TRAINER_GRUNT_AQUA_HIDEOUT_1_REWARD":{"address":5602088,"default_item":106,"flag":1282},"TRAINER_GRUNT_AQUA_HIDEOUT_2_REWARD":{"address":5602090,"default_item":106,"flag":1283},"TRAINER_GRUNT_AQUA_HIDEOUT_3_REWARD":{"address":5602092,"default_item":106,"flag":1284},"TRAINER_GRUNT_AQUA_HIDEOUT_4_REWARD":{"address":5602094,"default_item":106,"flag":1285},"TRAINER_GRUNT_AQUA_HIDEOUT_5_REWARD":{"address":5602138,"default_item":106,"flag":1307},"TRAINER_GRUNT_AQUA_HIDEOUT_6_REWARD":{"address":5602140,"default_item":106,"flag":1308},"TRAINER_GRUNT_AQUA_HIDEOUT_7_REWARD":{"address":5602468,"default_item":106,"flag":1472},"TRAINER_GRUNT_AQUA_HIDEOUT_8_REWARD":{"address":5602470,"default_item":106,"flag":1473},"TRAINER_GRUNT_MAGMA_HIDEOUT_10_REWARD":{"address":5603534,"default_item":106,"flag":2005},"TRAINER_GRUNT_MAGMA_HIDEOUT_11_REWARD":{"address":5603536,"default_item":106,"flag":2006},"TRAINER_GRUNT_MAGMA_HIDEOUT_12_REWARD":{"address":5603538,"default_item":106,"flag":2007},"TRAINER_GRUNT_MAGMA_HIDEOUT_13_REWARD":{"address":5603540,"default_item":106,"flag":2008},"TRAINER_GRUNT_MAGMA_HIDEOUT_14_REWARD":{"address":5603542,"default_item":106,"flag":2009},"TRAINER_GRUNT_MAGMA_HIDEOUT_15_REWARD":{"address":5603544,"default_item":106,"flag":2010},"TRAINER_GRUNT_MAGMA_HIDEOUT_16_REWARD":{"address":5603546,"default_item":106,"flag":2011},"TRAINER_GRUNT_MAGMA_HIDEOUT_1_REWARD":{"address":5603516,"default_item":106,"flag":1996},"TRAINER_GRUNT_MAGMA_HIDEOUT_2_REWARD":{"address":5603518,"default_item":106,"flag":1997},"TRAINER_GRUNT_MAGMA_HIDEOUT_3_REWARD":{"address":5603520,"default_item":106,"flag":1998},"TRAINER_GRUNT_MAGMA_HIDEOUT_4_REWARD":{"address":5603522,"default_item":106,"flag":1999},"TRAINER_GRUNT_MAGMA_HIDEOUT_5_REWARD":{"address":5603524,"default_item":106,"flag":2000},"TRAINER_GRUNT_MAGMA_HIDEOUT_6_REWARD":{"address":5603526,"default_item":106,"flag":2001},"TRAINER_GRUNT_MAGMA_HIDEOUT_7_REWARD":{"address":5603528,"default_item":106,"flag":2002},"TRAINER_GRUNT_MAGMA_HIDEOUT_8_REWARD":{"address":5603530,"default_item":106,"flag":2003},"TRAINER_GRUNT_MAGMA_HIDEOUT_9_REWARD":{"address":5603532,"default_item":106,"flag":2004},"TRAINER_GRUNT_MT_CHIMNEY_1_REWARD":{"address":5602376,"default_item":106,"flag":1426},"TRAINER_GRUNT_MT_CHIMNEY_2_REWARD":{"address":5603242,"default_item":106,"flag":1859},"TRAINER_GRUNT_MT_PYRE_1_REWARD":{"address":5602130,"default_item":106,"flag":1303},"TRAINER_GRUNT_MT_PYRE_2_REWARD":{"address":5602132,"default_item":106,"flag":1304},"TRAINER_GRUNT_MT_PYRE_3_REWARD":{"address":5602134,"default_item":106,"flag":1305},"TRAINER_GRUNT_MT_PYRE_4_REWARD":{"address":5603222,"default_item":106,"flag":1849},"TRAINER_GRUNT_MUSEUM_1_REWARD":{"address":5602124,"default_item":106,"flag":1300},"TRAINER_GRUNT_MUSEUM_2_REWARD":{"address":5602126,"default_item":106,"flag":1301},"TRAINER_GRUNT_PETALBURG_WOODS_REWARD":{"address":5602104,"default_item":103,"flag":1290},"TRAINER_GRUNT_RUSTURF_TUNNEL_REWARD":{"address":5602116,"default_item":103,"flag":1296},"TRAINER_GRUNT_SEAFLOOR_CAVERN_1_REWARD":{"address":5602096,"default_item":108,"flag":1286},"TRAINER_GRUNT_SEAFLOOR_CAVERN_2_REWARD":{"address":5602098,"default_item":108,"flag":1287},"TRAINER_GRUNT_SEAFLOOR_CAVERN_3_REWARD":{"address":5602100,"default_item":108,"flag":1288},"TRAINER_GRUNT_SEAFLOOR_CAVERN_4_REWARD":{"address":5602112,"default_item":108,"flag":1294},"TRAINER_GRUNT_SEAFLOOR_CAVERN_5_REWARD":{"address":5603218,"default_item":108,"flag":1847},"TRAINER_GRUNT_SPACE_CENTER_1_REWARD":{"address":5602128,"default_item":106,"flag":1302},"TRAINER_GRUNT_SPACE_CENTER_2_REWARD":{"address":5602316,"default_item":106,"flag":1396},"TRAINER_GRUNT_SPACE_CENTER_3_REWARD":{"address":5603256,"default_item":106,"flag":1866},"TRAINER_GRUNT_SPACE_CENTER_4_REWARD":{"address":5603258,"default_item":106,"flag":1867},"TRAINER_GRUNT_SPACE_CENTER_5_REWARD":{"address":5603260,"default_item":106,"flag":1868},"TRAINER_GRUNT_SPACE_CENTER_6_REWARD":{"address":5603262,"default_item":106,"flag":1869},"TRAINER_GRUNT_SPACE_CENTER_7_REWARD":{"address":5603264,"default_item":106,"flag":1870},"TRAINER_GRUNT_WEATHER_INST_1_REWARD":{"address":5602118,"default_item":106,"flag":1297},"TRAINER_GRUNT_WEATHER_INST_2_REWARD":{"address":5602120,"default_item":106,"flag":1298},"TRAINER_GRUNT_WEATHER_INST_3_REWARD":{"address":5602122,"default_item":106,"flag":1299},"TRAINER_GRUNT_WEATHER_INST_4_REWARD":{"address":5602136,"default_item":106,"flag":1306},"TRAINER_GRUNT_WEATHER_INST_5_REWARD":{"address":5603276,"default_item":106,"flag":1876},"TRAINER_GWEN_REWARD":{"address":5602202,"default_item":103,"flag":1339},"TRAINER_HAILEY_REWARD":{"address":5603478,"default_item":103,"flag":1977},"TRAINER_HALEY_1_REWARD":{"address":5603292,"default_item":103,"flag":1884},"TRAINER_HALLE_REWARD":{"address":5603176,"default_item":104,"flag":1826},"TRAINER_HANNAH_REWARD":{"address":5602572,"default_item":108,"flag":1524},"TRAINER_HARRISON_REWARD":{"address":5603240,"default_item":106,"flag":1858},"TRAINER_HAYDEN_REWARD":{"address":5603498,"default_item":106,"flag":1987},"TRAINER_HECTOR_REWARD":{"address":5603110,"default_item":104,"flag":1793},"TRAINER_HEIDI_REWARD":{"address":5603022,"default_item":106,"flag":1749},"TRAINER_HELENE_REWARD":{"address":5603586,"default_item":106,"flag":2031},"TRAINER_HENRY_REWARD":{"address":5603420,"default_item":104,"flag":1948},"TRAINER_HERMAN_REWARD":{"address":5602418,"default_item":106,"flag":1447},"TRAINER_HIDEO_REWARD":{"address":5603386,"default_item":106,"flag":1931},"TRAINER_HITOSHI_REWARD":{"address":5602444,"default_item":104,"flag":1460},"TRAINER_HOPE_REWARD":{"address":5602276,"default_item":104,"flag":1376},"TRAINER_HUDSON_REWARD":{"address":5603104,"default_item":104,"flag":1790},"TRAINER_HUEY_REWARD":{"address":5603064,"default_item":106,"flag":1770},"TRAINER_HUGH_REWARD":{"address":5602882,"default_item":108,"flag":1679},"TRAINER_HUMBERTO_REWARD":{"address":5602888,"default_item":108,"flag":1682},"TRAINER_IMANI_REWARD":{"address":5602968,"default_item":103,"flag":1722},"TRAINER_IRENE_REWARD":{"address":5603036,"default_item":106,"flag":1756},"TRAINER_ISAAC_1_REWARD":{"address":5603160,"default_item":106,"flag":1818},"TRAINER_ISABELLA_REWARD":{"address":5603274,"default_item":104,"flag":1875},"TRAINER_ISABELLE_REWARD":{"address":5603556,"default_item":103,"flag":2016},"TRAINER_ISABEL_1_REWARD":{"address":5602688,"default_item":104,"flag":1582},"TRAINER_ISAIAH_1_REWARD":{"address":5602836,"default_item":104,"flag":1656},"TRAINER_ISOBEL_REWARD":{"address":5602850,"default_item":104,"flag":1663},"TRAINER_IVAN_REWARD":{"address":5602758,"default_item":106,"flag":1617},"TRAINER_JACE_REWARD":{"address":5602492,"default_item":108,"flag":1484},"TRAINER_JACKI_1_REWARD":{"address":5602582,"default_item":108,"flag":1529},"TRAINER_JACKSON_1_REWARD":{"address":5603188,"default_item":104,"flag":1832},"TRAINER_JACK_REWARD":{"address":5602428,"default_item":106,"flag":1452},"TRAINER_JACLYN_REWARD":{"address":5602570,"default_item":106,"flag":1523},"TRAINER_JACOB_REWARD":{"address":5602786,"default_item":106,"flag":1631},"TRAINER_JAIDEN_REWARD":{"address":5603582,"default_item":106,"flag":2029},"TRAINER_JAMES_1_REWARD":{"address":5603326,"default_item":103,"flag":1901},"TRAINER_JANICE_REWARD":{"address":5603294,"default_item":103,"flag":1885},"TRAINER_JANI_REWARD":{"address":5602920,"default_item":103,"flag":1698},"TRAINER_JARED_REWARD":{"address":5602886,"default_item":108,"flag":1681},"TRAINER_JASMINE_REWARD":{"address":5602802,"default_item":103,"flag":1639},"TRAINER_JAYLEN_REWARD":{"address":5602736,"default_item":106,"flag":1606},"TRAINER_JAZMYN_REWARD":{"address":5603090,"default_item":106,"flag":1783},"TRAINER_JEFFREY_1_REWARD":{"address":5602536,"default_item":104,"flag":1506},"TRAINER_JEFF_REWARD":{"address":5602488,"default_item":108,"flag":1482},"TRAINER_JENNA_REWARD":{"address":5603204,"default_item":104,"flag":1840},"TRAINER_JENNIFER_REWARD":{"address":5602274,"default_item":104,"flag":1375},"TRAINER_JENNY_1_REWARD":{"address":5602982,"default_item":106,"flag":1729},"TRAINER_JEROME_REWARD":{"address":5602396,"default_item":103,"flag":1436},"TRAINER_JERRY_1_REWARD":{"address":5602630,"default_item":103,"flag":1553},"TRAINER_JESSICA_1_REWARD":{"address":5602338,"default_item":104,"flag":1407},"TRAINER_JOCELYN_REWARD":{"address":5602934,"default_item":106,"flag":1705},"TRAINER_JODY_REWARD":{"address":5602266,"default_item":104,"flag":1371},"TRAINER_JOEY_REWARD":{"address":5602728,"default_item":103,"flag":1602},"TRAINER_JOHANNA_REWARD":{"address":5603378,"default_item":104,"flag":1927},"TRAINER_JOHNSON_REWARD":{"address":5603592,"default_item":103,"flag":2034},"TRAINER_JOHN_AND_JAY_1_REWARD":{"address":5603446,"default_item":104,"flag":1961},"TRAINER_JONAH_REWARD":{"address":5603418,"default_item":104,"flag":1947},"TRAINER_JONAS_REWARD":{"address":5603092,"default_item":106,"flag":1784},"TRAINER_JONATHAN_REWARD":{"address":5603280,"default_item":104,"flag":1878},"TRAINER_JOSEPH_REWARD":{"address":5603484,"default_item":106,"flag":1980},"TRAINER_JOSE_REWARD":{"address":5603318,"default_item":103,"flag":1897},"TRAINER_JOSH_REWARD":{"address":5602724,"default_item":103,"flag":1600},"TRAINER_JOSUE_REWARD":{"address":5603560,"default_item":108,"flag":2018},"TRAINER_JUAN_1_REWARD":{"address":5602628,"default_item":109,"flag":1552},"TRAINER_JULIE_REWARD":{"address":5602284,"default_item":104,"flag":1380},"TRAINER_JULIO_REWARD":{"address":5603216,"default_item":108,"flag":1846},"TRAINER_KAI_REWARD":{"address":5603510,"default_item":108,"flag":1993},"TRAINER_KALEB_REWARD":{"address":5603482,"default_item":104,"flag":1979},"TRAINER_KARA_REWARD":{"address":5602998,"default_item":106,"flag":1737},"TRAINER_KAREN_1_REWARD":{"address":5602644,"default_item":103,"flag":1560},"TRAINER_KATELYNN_REWARD":{"address":5602734,"default_item":104,"flag":1605},"TRAINER_KATELYN_1_REWARD":{"address":5602856,"default_item":104,"flag":1666},"TRAINER_KATE_AND_JOY_REWARD":{"address":5602656,"default_item":106,"flag":1566},"TRAINER_KATHLEEN_REWARD":{"address":5603250,"default_item":108,"flag":1863},"TRAINER_KATIE_REWARD":{"address":5602994,"default_item":106,"flag":1735},"TRAINER_KAYLA_REWARD":{"address":5602578,"default_item":106,"flag":1527},"TRAINER_KAYLEY_REWARD":{"address":5603094,"default_item":104,"flag":1785},"TRAINER_KEEGAN_REWARD":{"address":5602494,"default_item":108,"flag":1485},"TRAINER_KEIGO_REWARD":{"address":5603388,"default_item":106,"flag":1932},"TRAINER_KELVIN_REWARD":{"address":5603098,"default_item":104,"flag":1787},"TRAINER_KENT_REWARD":{"address":5603324,"default_item":106,"flag":1900},"TRAINER_KEVIN_REWARD":{"address":5602426,"default_item":106,"flag":1451},"TRAINER_KIM_AND_IRIS_REWARD":{"address":5603440,"default_item":106,"flag":1958},"TRAINER_KINDRA_REWARD":{"address":5602296,"default_item":108,"flag":1386},"TRAINER_KIRA_AND_DAN_1_REWARD":{"address":5603368,"default_item":108,"flag":1922},"TRAINER_KIRK_REWARD":{"address":5602466,"default_item":106,"flag":1471},"TRAINER_KIYO_REWARD":{"address":5602446,"default_item":104,"flag":1461},"TRAINER_KOICHI_REWARD":{"address":5602448,"default_item":108,"flag":1462},"TRAINER_KOJI_1_REWARD":{"address":5603428,"default_item":104,"flag":1952},"TRAINER_KYLA_REWARD":{"address":5602970,"default_item":103,"flag":1723},"TRAINER_KYRA_REWARD":{"address":5603580,"default_item":104,"flag":2028},"TRAINER_LAO_1_REWARD":{"address":5602922,"default_item":103,"flag":1699},"TRAINER_LARRY_REWARD":{"address":5602510,"default_item":106,"flag":1493},"TRAINER_LAURA_REWARD":{"address":5602936,"default_item":106,"flag":1706},"TRAINER_LAUREL_REWARD":{"address":5603010,"default_item":106,"flag":1743},"TRAINER_LAWRENCE_REWARD":{"address":5603504,"default_item":106,"flag":1990},"TRAINER_LEAH_REWARD":{"address":5602154,"default_item":108,"flag":1315},"TRAINER_LEA_AND_JED_REWARD":{"address":5603366,"default_item":104,"flag":1921},"TRAINER_LENNY_REWARD":{"address":5603340,"default_item":108,"flag":1908},"TRAINER_LEONARDO_REWARD":{"address":5603236,"default_item":106,"flag":1856},"TRAINER_LEONARD_REWARD":{"address":5603074,"default_item":104,"flag":1775},"TRAINER_LEONEL_REWARD":{"address":5603608,"default_item":104,"flag":2042},"TRAINER_LILA_AND_ROY_1_REWARD":{"address":5603458,"default_item":106,"flag":1967},"TRAINER_LILITH_REWARD":{"address":5603230,"default_item":106,"flag":1853},"TRAINER_LINDA_REWARD":{"address":5603006,"default_item":106,"flag":1741},"TRAINER_LISA_AND_RAY_REWARD":{"address":5603468,"default_item":106,"flag":1972},"TRAINER_LOLA_1_REWARD":{"address":5602198,"default_item":103,"flag":1337},"TRAINER_LORENZO_REWARD":{"address":5603190,"default_item":104,"flag":1833},"TRAINER_LUCAS_1_REWARD":{"address":5603342,"default_item":108,"flag":1909},"TRAINER_LUIS_REWARD":{"address":5602386,"default_item":103,"flag":1431},"TRAINER_LUNG_REWARD":{"address":5602924,"default_item":103,"flag":1700},"TRAINER_LYDIA_1_REWARD":{"address":5603174,"default_item":106,"flag":1825},"TRAINER_LYLE_REWARD":{"address":5603316,"default_item":103,"flag":1896},"TRAINER_MACEY_REWARD":{"address":5603266,"default_item":108,"flag":1871},"TRAINER_MADELINE_1_REWARD":{"address":5602952,"default_item":108,"flag":1714},"TRAINER_MAKAYLA_REWARD":{"address":5603600,"default_item":104,"flag":2038},"TRAINER_MARCEL_REWARD":{"address":5602106,"default_item":104,"flag":1291},"TRAINER_MARCOS_REWARD":{"address":5603488,"default_item":106,"flag":1982},"TRAINER_MARC_REWARD":{"address":5603226,"default_item":106,"flag":1851},"TRAINER_MARIA_1_REWARD":{"address":5602822,"default_item":106,"flag":1649},"TRAINER_MARK_REWARD":{"address":5602374,"default_item":104,"flag":1425},"TRAINER_MARLENE_REWARD":{"address":5603588,"default_item":106,"flag":2032},"TRAINER_MARLEY_REWARD":{"address":5603100,"default_item":104,"flag":1788},"TRAINER_MARY_REWARD":{"address":5602262,"default_item":104,"flag":1369},"TRAINER_MATTHEW_REWARD":{"address":5602398,"default_item":103,"flag":1437},"TRAINER_MATT_REWARD":{"address":5602144,"default_item":104,"flag":1310},"TRAINER_MAURA_REWARD":{"address":5602576,"default_item":108,"flag":1526},"TRAINER_MAXIE_MAGMA_HIDEOUT_REWARD":{"address":5603286,"default_item":107,"flag":1881},"TRAINER_MAXIE_MT_CHIMNEY_REWARD":{"address":5603288,"default_item":104,"flag":1882},"TRAINER_MAY_LILYCOVE_MUDKIP_REWARD":{"address":5603412,"default_item":104,"flag":1944},"TRAINER_MAY_LILYCOVE_TORCHIC_REWARD":{"address":5603416,"default_item":104,"flag":1946},"TRAINER_MAY_LILYCOVE_TREECKO_REWARD":{"address":5603414,"default_item":104,"flag":1945},"TRAINER_MAY_ROUTE_103_MUDKIP_REWARD":{"address":5603142,"default_item":106,"flag":1809},"TRAINER_MAY_ROUTE_103_TORCHIC_REWARD":{"address":5603154,"default_item":106,"flag":1815},"TRAINER_MAY_ROUTE_103_TREECKO_REWARD":{"address":5603148,"default_item":106,"flag":1812},"TRAINER_MAY_ROUTE_110_MUDKIP_REWARD":{"address":5603144,"default_item":104,"flag":1810},"TRAINER_MAY_ROUTE_110_TORCHIC_REWARD":{"address":5603156,"default_item":104,"flag":1816},"TRAINER_MAY_ROUTE_110_TREECKO_REWARD":{"address":5603150,"default_item":104,"flag":1813},"TRAINER_MAY_ROUTE_119_MUDKIP_REWARD":{"address":5603146,"default_item":104,"flag":1811},"TRAINER_MAY_ROUTE_119_TORCHIC_REWARD":{"address":5603158,"default_item":104,"flag":1817},"TRAINER_MAY_ROUTE_119_TREECKO_REWARD":{"address":5603152,"default_item":104,"flag":1814},"TRAINER_MAY_RUSTBORO_MUDKIP_REWARD":{"address":5603284,"default_item":108,"flag":1880},"TRAINER_MAY_RUSTBORO_TORCHIC_REWARD":{"address":5603622,"default_item":108,"flag":2049},"TRAINER_MAY_RUSTBORO_TREECKO_REWARD":{"address":5603620,"default_item":108,"flag":2048},"TRAINER_MELINA_REWARD":{"address":5603594,"default_item":106,"flag":2035},"TRAINER_MELISSA_REWARD":{"address":5602332,"default_item":104,"flag":1404},"TRAINER_MEL_AND_PAUL_REWARD":{"address":5603444,"default_item":108,"flag":1960},"TRAINER_MICAH_REWARD":{"address":5602594,"default_item":107,"flag":1535},"TRAINER_MICHELLE_REWARD":{"address":5602280,"default_item":104,"flag":1378},"TRAINER_MIGUEL_1_REWARD":{"address":5602670,"default_item":104,"flag":1573},"TRAINER_MIKE_2_REWARD":{"address":5603354,"default_item":106,"flag":1915},"TRAINER_MISSY_REWARD":{"address":5602978,"default_item":103,"flag":1727},"TRAINER_MITCHELL_REWARD":{"address":5603164,"default_item":104,"flag":1820},"TRAINER_MIU_AND_YUKI_REWARD":{"address":5603052,"default_item":106,"flag":1764},"TRAINER_MOLLIE_REWARD":{"address":5602358,"default_item":104,"flag":1417},"TRAINER_MYLES_REWARD":{"address":5603614,"default_item":104,"flag":2045},"TRAINER_NANCY_REWARD":{"address":5603028,"default_item":106,"flag":1752},"TRAINER_NAOMI_REWARD":{"address":5602322,"default_item":110,"flag":1399},"TRAINER_NATE_REWARD":{"address":5603248,"default_item":107,"flag":1862},"TRAINER_NED_REWARD":{"address":5602764,"default_item":106,"flag":1620},"TRAINER_NICHOLAS_REWARD":{"address":5603254,"default_item":108,"flag":1865},"TRAINER_NICOLAS_1_REWARD":{"address":5602868,"default_item":104,"flag":1672},"TRAINER_NIKKI_REWARD":{"address":5602990,"default_item":106,"flag":1733},"TRAINER_NOB_1_REWARD":{"address":5602450,"default_item":106,"flag":1463},"TRAINER_NOLAN_REWARD":{"address":5602768,"default_item":108,"flag":1622},"TRAINER_NOLEN_REWARD":{"address":5602406,"default_item":106,"flag":1441},"TRAINER_NORMAN_1_REWARD":{"address":5602622,"default_item":107,"flag":1549},"TRAINER_OLIVIA_REWARD":{"address":5602344,"default_item":107,"flag":1410},"TRAINER_OWEN_REWARD":{"address":5602250,"default_item":104,"flag":1363},"TRAINER_PABLO_1_REWARD":{"address":5602838,"default_item":104,"flag":1657},"TRAINER_PARKER_REWARD":{"address":5602228,"default_item":104,"flag":1352},"TRAINER_PAT_REWARD":{"address":5603616,"default_item":104,"flag":2046},"TRAINER_PAXTON_REWARD":{"address":5603272,"default_item":104,"flag":1874},"TRAINER_PERRY_REWARD":{"address":5602880,"default_item":108,"flag":1678},"TRAINER_PETE_REWARD":{"address":5603554,"default_item":103,"flag":2015},"TRAINER_PHILLIP_REWARD":{"address":5603072,"default_item":104,"flag":1774},"TRAINER_PHIL_REWARD":{"address":5602884,"default_item":108,"flag":1680},"TRAINER_PHOEBE_REWARD":{"address":5602608,"default_item":110,"flag":1542},"TRAINER_PRESLEY_REWARD":{"address":5602890,"default_item":104,"flag":1683},"TRAINER_PRESTON_REWARD":{"address":5602550,"default_item":108,"flag":1513},"TRAINER_QUINCY_REWARD":{"address":5602732,"default_item":104,"flag":1604},"TRAINER_RACHEL_REWARD":{"address":5603606,"default_item":104,"flag":2041},"TRAINER_RANDALL_REWARD":{"address":5602226,"default_item":104,"flag":1351},"TRAINER_REED_REWARD":{"address":5603434,"default_item":106,"flag":1955},"TRAINER_RELI_AND_IAN_REWARD":{"address":5603456,"default_item":106,"flag":1966},"TRAINER_REYNA_REWARD":{"address":5603102,"default_item":108,"flag":1789},"TRAINER_RHETT_REWARD":{"address":5603490,"default_item":106,"flag":1983},"TRAINER_RICHARD_REWARD":{"address":5602416,"default_item":106,"flag":1446},"TRAINER_RICKY_1_REWARD":{"address":5602212,"default_item":103,"flag":1344},"TRAINER_RICK_REWARD":{"address":5603314,"default_item":103,"flag":1895},"TRAINER_RILEY_REWARD":{"address":5603390,"default_item":106,"flag":1933},"TRAINER_ROBERT_1_REWARD":{"address":5602896,"default_item":108,"flag":1686},"TRAINER_RODNEY_REWARD":{"address":5602414,"default_item":106,"flag":1445},"TRAINER_ROGER_REWARD":{"address":5603422,"default_item":104,"flag":1949},"TRAINER_ROLAND_REWARD":{"address":5602404,"default_item":106,"flag":1440},"TRAINER_RONALD_REWARD":{"address":5602784,"default_item":104,"flag":1630},"TRAINER_ROSE_1_REWARD":{"address":5602158,"default_item":106,"flag":1317},"TRAINER_ROXANNE_1_REWARD":{"address":5602614,"default_item":104,"flag":1545},"TRAINER_RUBEN_REWARD":{"address":5603426,"default_item":104,"flag":1951},"TRAINER_SAMANTHA_REWARD":{"address":5602574,"default_item":108,"flag":1525},"TRAINER_SAMUEL_REWARD":{"address":5602246,"default_item":104,"flag":1361},"TRAINER_SANTIAGO_REWARD":{"address":5602420,"default_item":106,"flag":1448},"TRAINER_SARAH_REWARD":{"address":5603474,"default_item":104,"flag":1975},"TRAINER_SAWYER_1_REWARD":{"address":5602086,"default_item":108,"flag":1281},"TRAINER_SHANE_REWARD":{"address":5602512,"default_item":106,"flag":1494},"TRAINER_SHANNON_REWARD":{"address":5602278,"default_item":104,"flag":1377},"TRAINER_SHARON_REWARD":{"address":5602988,"default_item":106,"flag":1732},"TRAINER_SHAWN_REWARD":{"address":5602472,"default_item":106,"flag":1474},"TRAINER_SHAYLA_REWARD":{"address":5603578,"default_item":108,"flag":2027},"TRAINER_SHEILA_REWARD":{"address":5602334,"default_item":104,"flag":1405},"TRAINER_SHELBY_1_REWARD":{"address":5602710,"default_item":108,"flag":1593},"TRAINER_SHELLY_SEAFLOOR_CAVERN_REWARD":{"address":5602150,"default_item":104,"flag":1313},"TRAINER_SHELLY_WEATHER_INSTITUTE_REWARD":{"address":5602148,"default_item":104,"flag":1312},"TRAINER_SHIRLEY_REWARD":{"address":5602336,"default_item":104,"flag":1406},"TRAINER_SIDNEY_REWARD":{"address":5602606,"default_item":110,"flag":1541},"TRAINER_SIENNA_REWARD":{"address":5603002,"default_item":106,"flag":1739},"TRAINER_SIMON_REWARD":{"address":5602214,"default_item":103,"flag":1345},"TRAINER_SOPHIE_REWARD":{"address":5603500,"default_item":106,"flag":1988},"TRAINER_SPENCER_REWARD":{"address":5602402,"default_item":106,"flag":1439},"TRAINER_STAN_REWARD":{"address":5602408,"default_item":106,"flag":1442},"TRAINER_STEVEN_REWARD":{"address":5603692,"default_item":109,"flag":2084},"TRAINER_STEVE_1_REWARD":{"address":5602370,"default_item":104,"flag":1423},"TRAINER_SUSIE_REWARD":{"address":5602996,"default_item":106,"flag":1736},"TRAINER_SYLVIA_REWARD":{"address":5603234,"default_item":108,"flag":1855},"TRAINER_TABITHA_MAGMA_HIDEOUT_REWARD":{"address":5603548,"default_item":104,"flag":2012},"TRAINER_TABITHA_MT_CHIMNEY_REWARD":{"address":5603278,"default_item":108,"flag":1877},"TRAINER_TAKAO_REWARD":{"address":5602442,"default_item":106,"flag":1459},"TRAINER_TAKASHI_REWARD":{"address":5602916,"default_item":106,"flag":1696},"TRAINER_TALIA_REWARD":{"address":5602854,"default_item":104,"flag":1665},"TRAINER_TAMMY_REWARD":{"address":5602298,"default_item":106,"flag":1387},"TRAINER_TANYA_REWARD":{"address":5602986,"default_item":106,"flag":1731},"TRAINER_TARA_REWARD":{"address":5602976,"default_item":103,"flag":1726},"TRAINER_TASHA_REWARD":{"address":5602302,"default_item":108,"flag":1389},"TRAINER_TATE_AND_LIZA_1_REWARD":{"address":5602626,"default_item":109,"flag":1551},"TRAINER_TAYLOR_REWARD":{"address":5602534,"default_item":104,"flag":1505},"TRAINER_THALIA_1_REWARD":{"address":5602372,"default_item":104,"flag":1424},"TRAINER_THOMAS_REWARD":{"address":5602596,"default_item":107,"flag":1536},"TRAINER_TIANA_REWARD":{"address":5603290,"default_item":103,"flag":1883},"TRAINER_TIFFANY_REWARD":{"address":5602346,"default_item":107,"flag":1411},"TRAINER_TIMMY_REWARD":{"address":5602752,"default_item":103,"flag":1614},"TRAINER_TIMOTHY_1_REWARD":{"address":5602698,"default_item":104,"flag":1587},"TRAINER_TISHA_REWARD":{"address":5603436,"default_item":106,"flag":1956},"TRAINER_TOMMY_REWARD":{"address":5602726,"default_item":103,"flag":1601},"TRAINER_TONY_1_REWARD":{"address":5602394,"default_item":103,"flag":1435},"TRAINER_TORI_AND_TIA_REWARD":{"address":5603438,"default_item":103,"flag":1957},"TRAINER_TRAVIS_REWARD":{"address":5602520,"default_item":106,"flag":1498},"TRAINER_TRENT_1_REWARD":{"address":5603338,"default_item":106,"flag":1907},"TRAINER_TYRA_AND_IVY_REWARD":{"address":5603442,"default_item":106,"flag":1959},"TRAINER_TYRON_REWARD":{"address":5603492,"default_item":106,"flag":1984},"TRAINER_VALERIE_1_REWARD":{"address":5602300,"default_item":108,"flag":1388},"TRAINER_VANESSA_REWARD":{"address":5602684,"default_item":104,"flag":1580},"TRAINER_VICKY_REWARD":{"address":5602708,"default_item":108,"flag":1592},"TRAINER_VICTORIA_REWARD":{"address":5602682,"default_item":106,"flag":1579},"TRAINER_VICTOR_REWARD":{"address":5602668,"default_item":106,"flag":1572},"TRAINER_VIOLET_REWARD":{"address":5602162,"default_item":104,"flag":1319},"TRAINER_VIRGIL_REWARD":{"address":5602552,"default_item":108,"flag":1514},"TRAINER_VITO_REWARD":{"address":5602248,"default_item":104,"flag":1362},"TRAINER_VIVIAN_REWARD":{"address":5603382,"default_item":106,"flag":1929},"TRAINER_VIVI_REWARD":{"address":5603296,"default_item":106,"flag":1886},"TRAINER_WADE_REWARD":{"address":5602772,"default_item":106,"flag":1624},"TRAINER_WALLACE_REWARD":{"address":5602754,"default_item":110,"flag":1615},"TRAINER_WALLY_MAUVILLE_REWARD":{"address":5603396,"default_item":108,"flag":1936},"TRAINER_WALLY_VR_1_REWARD":{"address":5603122,"default_item":107,"flag":1799},"TRAINER_WALTER_1_REWARD":{"address":5602592,"default_item":104,"flag":1534},"TRAINER_WARREN_REWARD":{"address":5602260,"default_item":104,"flag":1368},"TRAINER_WATTSON_1_REWARD":{"address":5602618,"default_item":104,"flag":1547},"TRAINER_WAYNE_REWARD":{"address":5603430,"default_item":104,"flag":1953},"TRAINER_WENDY_REWARD":{"address":5602268,"default_item":104,"flag":1372},"TRAINER_WILLIAM_REWARD":{"address":5602556,"default_item":106,"flag":1516},"TRAINER_WILTON_1_REWARD":{"address":5602240,"default_item":108,"flag":1358},"TRAINER_WINONA_1_REWARD":{"address":5602624,"default_item":107,"flag":1550},"TRAINER_WINSTON_1_REWARD":{"address":5602356,"default_item":104,"flag":1416},"TRAINER_WYATT_REWARD":{"address":5603506,"default_item":104,"flag":1991},"TRAINER_YASU_REWARD":{"address":5602914,"default_item":106,"flag":1695},"TRAINER_ZANDER_REWARD":{"address":5602146,"default_item":108,"flag":1311}},"maps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":{"header_address":4766420,"warp_table_address":5496844},"MAP_ABANDONED_SHIP_CORRIDORS_1F":{"header_address":4766196,"warp_table_address":5495920},"MAP_ABANDONED_SHIP_CORRIDORS_B1F":{"header_address":4766252,"warp_table_address":5496248},"MAP_ABANDONED_SHIP_DECK":{"header_address":4766168,"warp_table_address":5495812},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":{"fishing_encounters":{"address":5609088,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766476,"warp_table_address":5496908,"water_encounters":{"address":5609060,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":{"header_address":4766504,"warp_table_address":5497120},"MAP_ABANDONED_SHIP_ROOMS2_1F":{"header_address":4766392,"warp_table_address":5496752},"MAP_ABANDONED_SHIP_ROOMS2_B1F":{"header_address":4766308,"warp_table_address":5496484},"MAP_ABANDONED_SHIP_ROOMS_1F":{"header_address":4766224,"warp_table_address":5496132},"MAP_ABANDONED_SHIP_ROOMS_B1F":{"fishing_encounters":{"address":5606324,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766280,"warp_table_address":5496392,"water_encounters":{"address":5606296,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_ROOM_B1F":{"header_address":4766364,"warp_table_address":5496596},"MAP_ABANDONED_SHIP_UNDERWATER1":{"header_address":4766336,"warp_table_address":5496536},"MAP_ABANDONED_SHIP_UNDERWATER2":{"header_address":4766448,"warp_table_address":5496880},"MAP_ALTERING_CAVE":{"header_address":4767624,"land_encounters":{"address":5613400,"slots":[41,41,41,41,41,41,41,41,41,41,41,41]},"warp_table_address":5500436},"MAP_ANCIENT_TOMB":{"header_address":4766560,"warp_table_address":5497460},"MAP_AQUA_HIDEOUT_1F":{"header_address":4765300,"warp_table_address":5490892},"MAP_AQUA_HIDEOUT_B1F":{"header_address":4765328,"warp_table_address":5491152},"MAP_AQUA_HIDEOUT_B2F":{"header_address":4765356,"warp_table_address":5491516},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":{"header_address":4766728,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":{"header_address":4766756,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":{"header_address":4766784,"warp_table_address":4160749568},"MAP_ARTISAN_CAVE_1F":{"header_address":4767456,"land_encounters":{"address":5613344,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500172},"MAP_ARTISAN_CAVE_B1F":{"header_address":4767428,"land_encounters":{"address":5613288,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500064},"MAP_BATTLE_COLOSSEUM_2P":{"header_address":4768352,"warp_table_address":5509852},"MAP_BATTLE_COLOSSEUM_4P":{"header_address":4768436,"warp_table_address":5510152},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":{"header_address":4770228,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":{"header_address":4770200,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":{"header_address":4770172,"warp_table_address":5520908},"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":{"header_address":4769976,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":{"header_address":4769920,"warp_table_address":5519076},"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":{"header_address":4769892,"warp_table_address":5518968},"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":{"header_address":4769948,"warp_table_address":5519136},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":{"header_address":4770312,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":{"header_address":4770256,"warp_table_address":5521384},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":{"header_address":4770284,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":{"header_address":4770060,"warp_table_address":5520116},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":{"header_address":4770032,"warp_table_address":5519944},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":{"header_address":4770004,"warp_table_address":5519696},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":{"header_address":4770368,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":{"header_address":4770340,"warp_table_address":5521808},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":{"header_address":4770452,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":{"header_address":4770424,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":{"header_address":4770480,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":{"header_address":4770396,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":{"header_address":4770116,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":{"header_address":4770088,"warp_table_address":5520248},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":{"header_address":4770144,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":{"header_address":4769612,"warp_table_address":5516696},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":{"header_address":4769584,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":{"header_address":4769556,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":{"header_address":4769528,"warp_table_address":5516432},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":{"header_address":4769864,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":{"header_address":4769836,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":{"header_address":4769808,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":{"header_address":4770564,"warp_table_address":5523056},"MAP_BATTLE_FRONTIER_LOUNGE1":{"header_address":4770536,"warp_table_address":5522812},"MAP_BATTLE_FRONTIER_LOUNGE2":{"header_address":4770592,"warp_table_address":5523220},"MAP_BATTLE_FRONTIER_LOUNGE3":{"header_address":4770620,"warp_table_address":5523376},"MAP_BATTLE_FRONTIER_LOUNGE4":{"header_address":4770648,"warp_table_address":5523476},"MAP_BATTLE_FRONTIER_LOUNGE5":{"header_address":4770704,"warp_table_address":5523660},"MAP_BATTLE_FRONTIER_LOUNGE6":{"header_address":4770732,"warp_table_address":5523720},"MAP_BATTLE_FRONTIER_LOUNGE7":{"header_address":4770760,"warp_table_address":5523844},"MAP_BATTLE_FRONTIER_LOUNGE8":{"header_address":4770816,"warp_table_address":5524100},"MAP_BATTLE_FRONTIER_LOUNGE9":{"header_address":4770844,"warp_table_address":5524152},"MAP_BATTLE_FRONTIER_MART":{"header_address":4770928,"warp_table_address":5524588},"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":{"header_address":4769780,"warp_table_address":5518080},"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":{"header_address":4769500,"warp_table_address":5516048},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":{"header_address":4770872,"warp_table_address":5524308},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":{"header_address":4770900,"warp_table_address":5524448},"MAP_BATTLE_FRONTIER_RANKING_HALL":{"header_address":4770508,"warp_table_address":5522560},"MAP_BATTLE_FRONTIER_RECEPTION_GATE":{"header_address":4770788,"warp_table_address":5523992},"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":{"header_address":4770676,"warp_table_address":5523528},"MAP_BATTLE_PYRAMID_SQUARE01":{"header_address":4768912,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE02":{"header_address":4768940,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE03":{"header_address":4768968,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE04":{"header_address":4768996,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE05":{"header_address":4769024,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE06":{"header_address":4769052,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE07":{"header_address":4769080,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE08":{"header_address":4769108,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE09":{"header_address":4769136,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE10":{"header_address":4769164,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE11":{"header_address":4769192,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE12":{"header_address":4769220,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE13":{"header_address":4769248,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE14":{"header_address":4769276,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE15":{"header_address":4769304,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE16":{"header_address":4769332,"warp_table_address":4160749568},"MAP_BIRTH_ISLAND_EXTERIOR":{"header_address":4771012,"warp_table_address":5524876},"MAP_BIRTH_ISLAND_HARBOR":{"header_address":4771040,"warp_table_address":5524952},"MAP_CAVE_OF_ORIGIN_1F":{"header_address":4765720,"land_encounters":{"address":5609868,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493440},"MAP_CAVE_OF_ORIGIN_B1F":{"header_address":4765832,"warp_table_address":5493608},"MAP_CAVE_OF_ORIGIN_ENTRANCE":{"header_address":4765692,"land_encounters":{"address":5609812,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493404},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":{"header_address":4765748,"land_encounters":{"address":5609924,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493476},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":{"header_address":4765776,"land_encounters":{"address":5609980,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493512},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":{"header_address":4765804,"land_encounters":{"address":5610036,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493548},"MAP_CONTEST_HALL":{"header_address":4768464,"warp_table_address":4160749568},"MAP_CONTEST_HALL_BEAUTY":{"header_address":4768660,"warp_table_address":4160749568},"MAP_CONTEST_HALL_COOL":{"header_address":4768716,"warp_table_address":4160749568},"MAP_CONTEST_HALL_CUTE":{"header_address":4768772,"warp_table_address":4160749568},"MAP_CONTEST_HALL_SMART":{"header_address":4768744,"warp_table_address":4160749568},"MAP_CONTEST_HALL_TOUGH":{"header_address":4768688,"warp_table_address":4160749568},"MAP_DESERT_RUINS":{"header_address":4764824,"warp_table_address":5486828},"MAP_DESERT_UNDERPASS":{"header_address":4767400,"land_encounters":{"address":5613232,"slots":[132,370,132,371,132,370,371,132,370,132,371,132]},"warp_table_address":5500012},"MAP_DEWFORD_TOWN":{"fishing_encounters":{"address":5611588,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758300,"warp_table_address":5435180,"water_encounters":{"address":5611560,"slots":[72,309,309,310,310]}},"MAP_DEWFORD_TOWN_GYM":{"header_address":4759952,"warp_table_address":5460340},"MAP_DEWFORD_TOWN_HALL":{"header_address":4759980,"warp_table_address":5460640},"MAP_DEWFORD_TOWN_HOUSE1":{"header_address":4759868,"warp_table_address":5459856},"MAP_DEWFORD_TOWN_HOUSE2":{"header_address":4760008,"warp_table_address":5460748},"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":{"header_address":4759896,"warp_table_address":5459964},"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":{"header_address":4759924,"warp_table_address":5460104},"MAP_EVER_GRANDE_CITY":{"fishing_encounters":{"address":5611892,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4758216,"warp_table_address":5434048,"water_encounters":{"address":5611864,"slots":[72,309,309,310,310]}},"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":{"header_address":4764012,"warp_table_address":5483720},"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":{"header_address":4763984,"warp_table_address":5483612},"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":{"header_address":4763956,"warp_table_address":5483552},"MAP_EVER_GRANDE_CITY_HALL1":{"header_address":4764040,"warp_table_address":5483756},"MAP_EVER_GRANDE_CITY_HALL2":{"header_address":4764068,"warp_table_address":5483808},"MAP_EVER_GRANDE_CITY_HALL3":{"header_address":4764096,"warp_table_address":5483860},"MAP_EVER_GRANDE_CITY_HALL4":{"header_address":4764124,"warp_table_address":5483912},"MAP_EVER_GRANDE_CITY_HALL5":{"header_address":4764152,"warp_table_address":5483948},"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":{"header_address":4764208,"warp_table_address":5484180},"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":{"header_address":4763928,"warp_table_address":5483492},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":{"header_address":4764236,"warp_table_address":5484304},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":{"header_address":4764264,"warp_table_address":5484444},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":{"header_address":4764180,"warp_table_address":5484096},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":{"header_address":4764292,"warp_table_address":5484584},"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":{"header_address":4763900,"warp_table_address":5483432},"MAP_FALLARBOR_TOWN":{"header_address":4758356,"warp_table_address":5435792},"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760316,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760288,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760260,"warp_table_address":5462376},"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":{"header_address":4760400,"warp_table_address":5462888},"MAP_FALLARBOR_TOWN_MART":{"header_address":4760232,"warp_table_address":5462220},"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":{"header_address":4760428,"warp_table_address":5462948},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":{"header_address":4760344,"warp_table_address":5462656},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":{"header_address":4760372,"warp_table_address":5462796},"MAP_FARAWAY_ISLAND_ENTRANCE":{"header_address":4770956,"warp_table_address":5524672},"MAP_FARAWAY_ISLAND_INTERIOR":{"header_address":4770984,"warp_table_address":5524792},"MAP_FIERY_PATH":{"header_address":4765048,"land_encounters":{"address":5606456,"slots":[339,109,339,66,321,218,109,66,321,321,88,88]},"warp_table_address":5489344},"MAP_FORTREE_CITY":{"header_address":4758104,"warp_table_address":5431676},"MAP_FORTREE_CITY_DECORATION_SHOP":{"header_address":4762444,"warp_table_address":5473936},"MAP_FORTREE_CITY_GYM":{"header_address":4762220,"warp_table_address":5472984},"MAP_FORTREE_CITY_HOUSE1":{"header_address":4762192,"warp_table_address":5472756},"MAP_FORTREE_CITY_HOUSE2":{"header_address":4762332,"warp_table_address":5473504},"MAP_FORTREE_CITY_HOUSE3":{"header_address":4762360,"warp_table_address":5473588},"MAP_FORTREE_CITY_HOUSE4":{"header_address":4762388,"warp_table_address":5473696},"MAP_FORTREE_CITY_HOUSE5":{"header_address":4762416,"warp_table_address":5473804},"MAP_FORTREE_CITY_MART":{"header_address":4762304,"warp_table_address":5473420},"MAP_FORTREE_CITY_POKEMON_CENTER_1F":{"header_address":4762248,"warp_table_address":5473140},"MAP_FORTREE_CITY_POKEMON_CENTER_2F":{"header_address":4762276,"warp_table_address":5473280},"MAP_GRANITE_CAVE_1F":{"header_address":4764852,"land_encounters":{"address":5605988,"slots":[41,335,335,41,335,63,335,335,74,74,74,74]},"warp_table_address":5486956},"MAP_GRANITE_CAVE_B1F":{"header_address":4764880,"land_encounters":{"address":5606044,"slots":[41,382,382,382,41,63,335,335,322,322,322,322]},"warp_table_address":5487032},"MAP_GRANITE_CAVE_B2F":{"header_address":4764908,"land_encounters":{"address":5606372,"slots":[41,382,382,41,382,63,322,322,322,322,322,322]},"rock_smash_encounters":{"address":5606428,"slots":[74,320,74,74,74]},"warp_table_address":5487324},"MAP_GRANITE_CAVE_STEVENS_ROOM":{"header_address":4764936,"land_encounters":{"address":5608188,"slots":[41,335,335,41,335,63,335,335,382,382,382,382]},"warp_table_address":5487432},"MAP_INSIDE_OF_TRUCK":{"header_address":4768800,"warp_table_address":5510720},"MAP_ISLAND_CAVE":{"header_address":4766532,"warp_table_address":5497356},"MAP_JAGGED_PASS":{"header_address":4765020,"land_encounters":{"address":5606644,"slots":[339,339,66,339,351,66,351,66,339,351,339,351]},"warp_table_address":5488908},"MAP_LAVARIDGE_TOWN":{"header_address":4758328,"warp_table_address":5435516},"MAP_LAVARIDGE_TOWN_GYM_1F":{"header_address":4760064,"warp_table_address":5461036},"MAP_LAVARIDGE_TOWN_GYM_B1F":{"header_address":4760092,"warp_table_address":5461384},"MAP_LAVARIDGE_TOWN_HERB_SHOP":{"header_address":4760036,"warp_table_address":5460856},"MAP_LAVARIDGE_TOWN_HOUSE":{"header_address":4760120,"warp_table_address":5461668},"MAP_LAVARIDGE_TOWN_MART":{"header_address":4760148,"warp_table_address":5461776},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":{"header_address":4760176,"warp_table_address":5461908},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":{"header_address":4760204,"warp_table_address":5462056},"MAP_LILYCOVE_CITY":{"fishing_encounters":{"address":5611512,"slots":[129,72,129,72,313,313,313,120,313,313]},"header_address":4758132,"warp_table_address":5432368,"water_encounters":{"address":5611484,"slots":[72,309,309,310,310]}},"MAP_LILYCOVE_CITY_CONTEST_HALL":{"header_address":4762612,"warp_table_address":5476560},"MAP_LILYCOVE_CITY_CONTEST_LOBBY":{"header_address":4762584,"warp_table_address":5475596},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":{"header_address":4762472,"warp_table_address":5473996},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":{"header_address":4762500,"warp_table_address":5474224},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":{"header_address":4762920,"warp_table_address":5478044},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":{"header_address":4762948,"warp_table_address":5478228},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":{"header_address":4762976,"warp_table_address":5478392},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":{"header_address":4763004,"warp_table_address":5478556},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":{"header_address":4763032,"warp_table_address":5478768},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":{"header_address":4763088,"warp_table_address":5478984},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":{"header_address":4763060,"warp_table_address":5478908},"MAP_LILYCOVE_CITY_HARBOR":{"header_address":4762752,"warp_table_address":5477396},"MAP_LILYCOVE_CITY_HOUSE1":{"header_address":4762808,"warp_table_address":5477540},"MAP_LILYCOVE_CITY_HOUSE2":{"header_address":4762836,"warp_table_address":5477600},"MAP_LILYCOVE_CITY_HOUSE3":{"header_address":4762864,"warp_table_address":5477780},"MAP_LILYCOVE_CITY_HOUSE4":{"header_address":4762892,"warp_table_address":5477864},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":{"header_address":4762528,"warp_table_address":5474492},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":{"header_address":4762556,"warp_table_address":5474824},"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":{"header_address":4762780,"warp_table_address":5477456},"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":{"header_address":4762640,"warp_table_address":5476804},"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":{"header_address":4762668,"warp_table_address":5476944},"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":{"header_address":4762724,"warp_table_address":5477240},"MAP_LILYCOVE_CITY_UNUSED_MART":{"header_address":4762696,"warp_table_address":5476988},"MAP_LITTLEROOT_TOWN":{"header_address":4758244,"warp_table_address":5434528},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":{"header_address":4759588,"warp_table_address":5457588},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":{"header_address":4759616,"warp_table_address":5458080},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":{"header_address":4759644,"warp_table_address":5458324},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":{"header_address":4759672,"warp_table_address":5458816},"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":{"header_address":4759700,"warp_table_address":5459036},"MAP_MAGMA_HIDEOUT_1F":{"header_address":4767064,"land_encounters":{"address":5612560,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498844},"MAP_MAGMA_HIDEOUT_2F_1R":{"header_address":4767092,"land_encounters":{"address":5612616,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498992},"MAP_MAGMA_HIDEOUT_2F_2R":{"header_address":4767120,"land_encounters":{"address":5612672,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499180},"MAP_MAGMA_HIDEOUT_2F_3R":{"header_address":4767260,"land_encounters":{"address":5612952,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499696},"MAP_MAGMA_HIDEOUT_3F_1R":{"header_address":4767148,"land_encounters":{"address":5612728,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499288},"MAP_MAGMA_HIDEOUT_3F_2R":{"header_address":4767176,"land_encounters":{"address":5612784,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499380},"MAP_MAGMA_HIDEOUT_3F_3R":{"header_address":4767232,"land_encounters":{"address":5612896,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499660},"MAP_MAGMA_HIDEOUT_4F":{"header_address":4767204,"land_encounters":{"address":5612840,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499600},"MAP_MARINE_CAVE_END":{"header_address":4767540,"warp_table_address":5500288},"MAP_MARINE_CAVE_ENTRANCE":{"header_address":4767512,"warp_table_address":5500236},"MAP_MAUVILLE_CITY":{"header_address":4758048,"warp_table_address":5430380},"MAP_MAUVILLE_CITY_BIKE_SHOP":{"header_address":4761520,"warp_table_address":5469232},"MAP_MAUVILLE_CITY_GAME_CORNER":{"header_address":4761576,"warp_table_address":5469640},"MAP_MAUVILLE_CITY_GYM":{"header_address":4761492,"warp_table_address":5469060},"MAP_MAUVILLE_CITY_HOUSE1":{"header_address":4761548,"warp_table_address":5469316},"MAP_MAUVILLE_CITY_HOUSE2":{"header_address":4761604,"warp_table_address":5469988},"MAP_MAUVILLE_CITY_MART":{"header_address":4761688,"warp_table_address":5470424},"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":{"header_address":4761632,"warp_table_address":5470144},"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":{"header_address":4761660,"warp_table_address":5470308},"MAP_METEOR_FALLS_1F_1R":{"fishing_encounters":{"address":5610796,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4764656,"land_encounters":{"address":5610712,"slots":[41,41,41,41,41,349,349,349,41,41,41,41]},"warp_table_address":5486052,"water_encounters":{"address":5610768,"slots":[41,41,349,349,349]}},"MAP_METEOR_FALLS_1F_2R":{"fishing_encounters":{"address":5610928,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764684,"land_encounters":{"address":5610844,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486220,"water_encounters":{"address":5610900,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_1R":{"fishing_encounters":{"address":5611060,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764712,"land_encounters":{"address":5610976,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486284,"water_encounters":{"address":5611032,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_2R":{"fishing_encounters":{"address":5606596,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764740,"land_encounters":{"address":5606512,"slots":[42,42,395,349,395,349,395,349,42,42,42,42]},"warp_table_address":5486376,"water_encounters":{"address":5606568,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_STEVENS_CAVE":{"header_address":4767652,"land_encounters":{"address":5613904,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5500488},"MAP_MIRAGE_TOWER_1F":{"header_address":4767288,"land_encounters":{"address":5613008,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499732},"MAP_MIRAGE_TOWER_2F":{"header_address":4767316,"land_encounters":{"address":5613064,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499768},"MAP_MIRAGE_TOWER_3F":{"header_address":4767344,"land_encounters":{"address":5613120,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499852},"MAP_MIRAGE_TOWER_4F":{"header_address":4767372,"land_encounters":{"address":5613176,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499960},"MAP_MOSSDEEP_CITY":{"fishing_encounters":{"address":5611740,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758160,"warp_table_address":5433064,"water_encounters":{"address":5611712,"slots":[72,309,309,310,310]}},"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":{"header_address":4763424,"warp_table_address":5481712},"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":{"header_address":4763452,"warp_table_address":5481816},"MAP_MOSSDEEP_CITY_GYM":{"header_address":4763116,"warp_table_address":5479884},"MAP_MOSSDEEP_CITY_HOUSE1":{"header_address":4763144,"warp_table_address":5480232},"MAP_MOSSDEEP_CITY_HOUSE2":{"header_address":4763172,"warp_table_address":5480340},"MAP_MOSSDEEP_CITY_HOUSE3":{"header_address":4763284,"warp_table_address":5480812},"MAP_MOSSDEEP_CITY_HOUSE4":{"header_address":4763340,"warp_table_address":5481076},"MAP_MOSSDEEP_CITY_MART":{"header_address":4763256,"warp_table_address":5480752},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":{"header_address":4763200,"warp_table_address":5480448},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":{"header_address":4763228,"warp_table_address":5480612},"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":{"header_address":4763368,"warp_table_address":5481376},"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":{"header_address":4763396,"warp_table_address":5481636},"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":{"header_address":4763312,"warp_table_address":5480920},"MAP_MT_CHIMNEY":{"header_address":4764992,"warp_table_address":5488664},"MAP_MT_CHIMNEY_CABLE_CAR_STATION":{"header_address":4764460,"warp_table_address":5485144},"MAP_MT_PYRE_1F":{"header_address":4765076,"land_encounters":{"address":5606100,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489452},"MAP_MT_PYRE_2F":{"header_address":4765104,"land_encounters":{"address":5607796,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489712},"MAP_MT_PYRE_3F":{"header_address":4765132,"land_encounters":{"address":5607852,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489868},"MAP_MT_PYRE_4F":{"header_address":4765160,"land_encounters":{"address":5607908,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5489984},"MAP_MT_PYRE_5F":{"header_address":4765188,"land_encounters":{"address":5607964,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490100},"MAP_MT_PYRE_6F":{"header_address":4765216,"land_encounters":{"address":5608020,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490232},"MAP_MT_PYRE_EXTERIOR":{"header_address":4765244,"land_encounters":{"address":5608076,"slots":[377,377,377,377,37,37,37,37,309,309,309,309]},"warp_table_address":5490316},"MAP_MT_PYRE_SUMMIT":{"header_address":4765272,"land_encounters":{"address":5608132,"slots":[377,377,377,377,377,377,377,361,361,361,411,411]},"warp_table_address":5490656},"MAP_NAVEL_ROCK_B1F":{"header_address":4771320,"warp_table_address":5525524},"MAP_NAVEL_ROCK_BOTTOM":{"header_address":4771824,"warp_table_address":5526248},"MAP_NAVEL_ROCK_DOWN01":{"header_address":4771516,"warp_table_address":5525828},"MAP_NAVEL_ROCK_DOWN02":{"header_address":4771544,"warp_table_address":5525864},"MAP_NAVEL_ROCK_DOWN03":{"header_address":4771572,"warp_table_address":5525900},"MAP_NAVEL_ROCK_DOWN04":{"header_address":4771600,"warp_table_address":5525936},"MAP_NAVEL_ROCK_DOWN05":{"header_address":4771628,"warp_table_address":5525972},"MAP_NAVEL_ROCK_DOWN06":{"header_address":4771656,"warp_table_address":5526008},"MAP_NAVEL_ROCK_DOWN07":{"header_address":4771684,"warp_table_address":5526044},"MAP_NAVEL_ROCK_DOWN08":{"header_address":4771712,"warp_table_address":5526080},"MAP_NAVEL_ROCK_DOWN09":{"header_address":4771740,"warp_table_address":5526116},"MAP_NAVEL_ROCK_DOWN10":{"header_address":4771768,"warp_table_address":5526152},"MAP_NAVEL_ROCK_DOWN11":{"header_address":4771796,"warp_table_address":5526188},"MAP_NAVEL_ROCK_ENTRANCE":{"header_address":4771292,"warp_table_address":5525488},"MAP_NAVEL_ROCK_EXTERIOR":{"header_address":4771236,"warp_table_address":5525376},"MAP_NAVEL_ROCK_FORK":{"header_address":4771348,"warp_table_address":5525560},"MAP_NAVEL_ROCK_HARBOR":{"header_address":4771264,"warp_table_address":5525460},"MAP_NAVEL_ROCK_TOP":{"header_address":4771488,"warp_table_address":5525772},"MAP_NAVEL_ROCK_UP1":{"header_address":4771376,"warp_table_address":5525604},"MAP_NAVEL_ROCK_UP2":{"header_address":4771404,"warp_table_address":5525640},"MAP_NAVEL_ROCK_UP3":{"header_address":4771432,"warp_table_address":5525676},"MAP_NAVEL_ROCK_UP4":{"header_address":4771460,"warp_table_address":5525712},"MAP_NEW_MAUVILLE_ENTRANCE":{"header_address":4766112,"land_encounters":{"address":5610092,"slots":[100,81,100,81,100,81,100,81,100,81,100,81]},"warp_table_address":5495284},"MAP_NEW_MAUVILLE_INSIDE":{"header_address":4766140,"land_encounters":{"address":5607136,"slots":[100,81,100,81,100,81,100,81,100,81,101,82]},"warp_table_address":5495528},"MAP_OLDALE_TOWN":{"header_address":4758272,"warp_table_address":5434860},"MAP_OLDALE_TOWN_HOUSE1":{"header_address":4759728,"warp_table_address":5459276},"MAP_OLDALE_TOWN_HOUSE2":{"header_address":4759756,"warp_table_address":5459360},"MAP_OLDALE_TOWN_MART":{"header_address":4759840,"warp_table_address":5459748},"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":{"header_address":4759784,"warp_table_address":5459492},"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":{"header_address":4759812,"warp_table_address":5459632},"MAP_PACIFIDLOG_TOWN":{"fishing_encounters":{"address":5611816,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758412,"warp_table_address":5436288,"water_encounters":{"address":5611788,"slots":[72,309,309,310,310]}},"MAP_PACIFIDLOG_TOWN_HOUSE1":{"header_address":4760764,"warp_table_address":5464400},"MAP_PACIFIDLOG_TOWN_HOUSE2":{"header_address":4760792,"warp_table_address":5464508},"MAP_PACIFIDLOG_TOWN_HOUSE3":{"header_address":4760820,"warp_table_address":5464592},"MAP_PACIFIDLOG_TOWN_HOUSE4":{"header_address":4760848,"warp_table_address":5464700},"MAP_PACIFIDLOG_TOWN_HOUSE5":{"header_address":4760876,"warp_table_address":5464784},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":{"header_address":4760708,"warp_table_address":5464168},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":{"header_address":4760736,"warp_table_address":5464308},"MAP_PETALBURG_CITY":{"fishing_encounters":{"address":5611968,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4757992,"warp_table_address":5428704,"water_encounters":{"address":5611940,"slots":[183,183,183,183,183]}},"MAP_PETALBURG_CITY_GYM":{"header_address":4760932,"warp_table_address":5465168},"MAP_PETALBURG_CITY_HOUSE1":{"header_address":4760960,"warp_table_address":5465708},"MAP_PETALBURG_CITY_HOUSE2":{"header_address":4760988,"warp_table_address":5465792},"MAP_PETALBURG_CITY_MART":{"header_address":4761072,"warp_table_address":5466228},"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":{"header_address":4761016,"warp_table_address":5465948},"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":{"header_address":4761044,"warp_table_address":5466088},"MAP_PETALBURG_CITY_WALLYS_HOUSE":{"header_address":4760904,"warp_table_address":5464868},"MAP_PETALBURG_WOODS":{"header_address":4764964,"land_encounters":{"address":5605876,"slots":[286,290,306,286,291,293,290,306,304,364,304,364]},"warp_table_address":5487772},"MAP_RECORD_CORNER":{"header_address":4768408,"warp_table_address":5510036},"MAP_ROUTE101":{"header_address":4758440,"land_encounters":{"address":5604388,"slots":[290,286,290,290,286,286,290,286,288,288,288,288]},"warp_table_address":4160749568},"MAP_ROUTE102":{"fishing_encounters":{"address":5604528,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758468,"land_encounters":{"address":5604444,"slots":[286,290,286,290,295,295,288,288,288,392,288,298]},"warp_table_address":4160749568,"water_encounters":{"address":5604500,"slots":[183,183,183,183,118]}},"MAP_ROUTE103":{"fishing_encounters":{"address":5604660,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758496,"land_encounters":{"address":5604576,"slots":[286,286,286,286,309,288,288,288,309,309,309,309]},"warp_table_address":5437452,"water_encounters":{"address":5604632,"slots":[72,309,309,310,310]}},"MAP_ROUTE104":{"fishing_encounters":{"address":5604792,"slots":[129,129,129,129,129,129,129,129,129,129]},"header_address":4758524,"land_encounters":{"address":5604708,"slots":[286,290,286,183,183,286,304,304,309,309,309,309]},"warp_table_address":5438308,"water_encounters":{"address":5604764,"slots":[309,309,309,310,310]}},"MAP_ROUTE104_MR_BRINEYS_HOUSE":{"header_address":4764320,"warp_table_address":5484676},"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4764348,"warp_table_address":5484784},"MAP_ROUTE104_PROTOTYPE":{"header_address":4771880,"warp_table_address":4160749568},"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4771908,"warp_table_address":4160749568},"MAP_ROUTE105":{"fishing_encounters":{"address":5604868,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758552,"warp_table_address":5438720,"water_encounters":{"address":5604840,"slots":[72,309,309,310,310]}},"MAP_ROUTE106":{"fishing_encounters":{"address":5606728,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758580,"warp_table_address":5438892,"water_encounters":{"address":5606700,"slots":[72,309,309,310,310]}},"MAP_ROUTE107":{"fishing_encounters":{"address":5606804,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758608,"warp_table_address":4160749568,"water_encounters":{"address":5606776,"slots":[72,309,309,310,310]}},"MAP_ROUTE108":{"fishing_encounters":{"address":5606880,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758636,"warp_table_address":5439324,"water_encounters":{"address":5606852,"slots":[72,309,309,310,310]}},"MAP_ROUTE109":{"fishing_encounters":{"address":5606956,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758664,"warp_table_address":5439940,"water_encounters":{"address":5606928,"slots":[72,309,309,310,310]}},"MAP_ROUTE109_SEASHORE_HOUSE":{"header_address":4771936,"warp_table_address":5526472},"MAP_ROUTE110":{"fishing_encounters":{"address":5605000,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758692,"land_encounters":{"address":5604916,"slots":[286,337,367,337,354,43,354,367,309,309,353,353]},"warp_table_address":5440928,"water_encounters":{"address":5604972,"slots":[72,309,309,310,310]}},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":{"header_address":4772272,"warp_table_address":5529400},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":{"header_address":4772300,"warp_table_address":5529508},"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":{"header_address":4772020,"warp_table_address":5526740},"MAP_ROUTE110_TRICK_HOUSE_END":{"header_address":4771992,"warp_table_address":5526676},"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":{"header_address":4771964,"warp_table_address":5526532},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":{"header_address":4772048,"warp_table_address":5527152},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":{"header_address":4772076,"warp_table_address":5527328},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":{"header_address":4772104,"warp_table_address":5527616},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":{"header_address":4772132,"warp_table_address":5528072},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":{"header_address":4772160,"warp_table_address":5528248},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":{"header_address":4772188,"warp_table_address":5528752},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":{"header_address":4772216,"warp_table_address":5529024},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":{"header_address":4772244,"warp_table_address":5529320},"MAP_ROUTE111":{"fishing_encounters":{"address":5605160,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758720,"land_encounters":{"address":5605048,"slots":[27,332,27,332,318,318,27,332,318,344,344,344]},"rock_smash_encounters":{"address":5605132,"slots":[74,74,74,74,74]},"warp_table_address":5442448,"water_encounters":{"address":5605104,"slots":[183,183,183,183,118]}},"MAP_ROUTE111_OLD_LADYS_REST_STOP":{"header_address":4764404,"warp_table_address":5484976},"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":{"header_address":4764376,"warp_table_address":5484916},"MAP_ROUTE112":{"header_address":4758748,"land_encounters":{"address":5605208,"slots":[339,339,183,339,339,183,339,183,339,339,339,339]},"warp_table_address":5443604},"MAP_ROUTE112_CABLE_CAR_STATION":{"header_address":4764432,"warp_table_address":5485060},"MAP_ROUTE113":{"header_address":4758776,"land_encounters":{"address":5605264,"slots":[308,308,218,308,308,218,308,218,308,227,308,227]},"warp_table_address":5444092},"MAP_ROUTE113_GLASS_WORKSHOP":{"header_address":4772328,"warp_table_address":5529640},"MAP_ROUTE114":{"fishing_encounters":{"address":5605432,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758804,"land_encounters":{"address":5605320,"slots":[358,295,358,358,295,296,296,296,379,379,379,299]},"rock_smash_encounters":{"address":5605404,"slots":[74,74,74,74,74]},"warp_table_address":5445184,"water_encounters":{"address":5605376,"slots":[183,183,183,183,118]}},"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":{"header_address":4764488,"warp_table_address":5485204},"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":{"header_address":4764516,"warp_table_address":5485320},"MAP_ROUTE114_LANETTES_HOUSE":{"header_address":4764544,"warp_table_address":5485420},"MAP_ROUTE115":{"fishing_encounters":{"address":5607088,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758832,"land_encounters":{"address":5607004,"slots":[358,304,358,304,304,305,39,39,309,309,309,309]},"warp_table_address":5445988,"water_encounters":{"address":5607060,"slots":[72,309,309,310,310]}},"MAP_ROUTE116":{"header_address":4758860,"land_encounters":{"address":5605480,"slots":[286,370,301,63,301,304,304,304,286,286,315,315]},"warp_table_address":5446872},"MAP_ROUTE116_TUNNELERS_REST_HOUSE":{"header_address":4764572,"warp_table_address":5485564},"MAP_ROUTE117":{"fishing_encounters":{"address":5605620,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758888,"land_encounters":{"address":5605536,"slots":[286,43,286,43,183,43,387,387,387,387,386,298]},"warp_table_address":5447656,"water_encounters":{"address":5605592,"slots":[183,183,183,183,118]}},"MAP_ROUTE117_POKEMON_DAY_CARE":{"header_address":4764600,"warp_table_address":5485624},"MAP_ROUTE118":{"fishing_encounters":{"address":5605752,"slots":[129,72,129,72,330,331,330,330,330,330]},"header_address":4758916,"land_encounters":{"address":5605668,"slots":[288,337,288,337,289,338,309,309,309,309,309,317]},"warp_table_address":5448236,"water_encounters":{"address":5605724,"slots":[72,309,309,310,310]}},"MAP_ROUTE119":{"fishing_encounters":{"address":5607276,"slots":[129,72,129,72,330,330,330,330,330,330]},"header_address":4758944,"land_encounters":{"address":5607192,"slots":[288,289,288,43,289,43,43,43,369,369,369,317]},"warp_table_address":5449460,"water_encounters":{"address":5607248,"slots":[72,309,309,310,310]}},"MAP_ROUTE119_HOUSE":{"header_address":4772440,"warp_table_address":5530360},"MAP_ROUTE119_WEATHER_INSTITUTE_1F":{"header_address":4772384,"warp_table_address":5529880},"MAP_ROUTE119_WEATHER_INSTITUTE_2F":{"header_address":4772412,"warp_table_address":5530164},"MAP_ROUTE120":{"fishing_encounters":{"address":5607408,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758972,"land_encounters":{"address":5607324,"slots":[286,287,287,43,183,43,43,183,376,376,317,298]},"warp_table_address":5451160,"water_encounters":{"address":5607380,"slots":[183,183,183,183,118]}},"MAP_ROUTE121":{"fishing_encounters":{"address":5607540,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759000,"land_encounters":{"address":5607456,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5452364,"water_encounters":{"address":5607512,"slots":[72,309,309,310,310]}},"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":{"header_address":4764628,"warp_table_address":5485732},"MAP_ROUTE122":{"fishing_encounters":{"address":5607616,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759028,"warp_table_address":5452576,"water_encounters":{"address":5607588,"slots":[72,309,309,310,310]}},"MAP_ROUTE123":{"fishing_encounters":{"address":5607748,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759056,"land_encounters":{"address":5607664,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5453636,"water_encounters":{"address":5607720,"slots":[72,309,309,310,310]}},"MAP_ROUTE123_BERRY_MASTERS_HOUSE":{"header_address":4772356,"warp_table_address":5529724},"MAP_ROUTE124":{"fishing_encounters":{"address":5605828,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759084,"warp_table_address":5454436,"water_encounters":{"address":5605800,"slots":[72,309,309,310,310]}},"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":{"header_address":4772468,"warp_table_address":5530420},"MAP_ROUTE125":{"fishing_encounters":{"address":5608272,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759112,"warp_table_address":5454716,"water_encounters":{"address":5608244,"slots":[72,309,309,310,310]}},"MAP_ROUTE126":{"fishing_encounters":{"address":5608348,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759140,"warp_table_address":4160749568,"water_encounters":{"address":5608320,"slots":[72,309,309,310,310]}},"MAP_ROUTE127":{"fishing_encounters":{"address":5608424,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759168,"warp_table_address":4160749568,"water_encounters":{"address":5608396,"slots":[72,309,309,310,310]}},"MAP_ROUTE128":{"fishing_encounters":{"address":5608500,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4759196,"warp_table_address":4160749568,"water_encounters":{"address":5608472,"slots":[72,309,309,310,310]}},"MAP_ROUTE129":{"fishing_encounters":{"address":5608576,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759224,"warp_table_address":4160749568,"water_encounters":{"address":5608548,"slots":[72,309,309,310,314]}},"MAP_ROUTE130":{"fishing_encounters":{"address":5608708,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759252,"land_encounters":{"address":5608624,"slots":[360,360,360,360,360,360,360,360,360,360,360,360]},"warp_table_address":4160749568,"water_encounters":{"address":5608680,"slots":[72,309,309,310,310]}},"MAP_ROUTE131":{"fishing_encounters":{"address":5608784,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759280,"warp_table_address":5456116,"water_encounters":{"address":5608756,"slots":[72,309,309,310,310]}},"MAP_ROUTE132":{"fishing_encounters":{"address":5608860,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759308,"warp_table_address":4160749568,"water_encounters":{"address":5608832,"slots":[72,309,309,310,310]}},"MAP_ROUTE133":{"fishing_encounters":{"address":5608936,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759336,"warp_table_address":4160749568,"water_encounters":{"address":5608908,"slots":[72,309,309,310,310]}},"MAP_ROUTE134":{"fishing_encounters":{"address":5609012,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759364,"warp_table_address":4160749568,"water_encounters":{"address":5608984,"slots":[72,309,309,310,310]}},"MAP_RUSTBORO_CITY":{"header_address":4758076,"warp_table_address":5430936},"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":{"header_address":4762024,"warp_table_address":5472204},"MAP_RUSTBORO_CITY_DEVON_CORP_1F":{"header_address":4761716,"warp_table_address":5470532},"MAP_RUSTBORO_CITY_DEVON_CORP_2F":{"header_address":4761744,"warp_table_address":5470744},"MAP_RUSTBORO_CITY_DEVON_CORP_3F":{"header_address":4761772,"warp_table_address":5470852},"MAP_RUSTBORO_CITY_FLAT1_1F":{"header_address":4761940,"warp_table_address":5471808},"MAP_RUSTBORO_CITY_FLAT1_2F":{"header_address":4761968,"warp_table_address":5472044},"MAP_RUSTBORO_CITY_FLAT2_1F":{"header_address":4762080,"warp_table_address":5472372},"MAP_RUSTBORO_CITY_FLAT2_2F":{"header_address":4762108,"warp_table_address":5472464},"MAP_RUSTBORO_CITY_FLAT2_3F":{"header_address":4762136,"warp_table_address":5472548},"MAP_RUSTBORO_CITY_GYM":{"header_address":4761800,"warp_table_address":5471024},"MAP_RUSTBORO_CITY_HOUSE1":{"header_address":4761996,"warp_table_address":5472120},"MAP_RUSTBORO_CITY_HOUSE2":{"header_address":4762052,"warp_table_address":5472288},"MAP_RUSTBORO_CITY_HOUSE3":{"header_address":4762164,"warp_table_address":5472648},"MAP_RUSTBORO_CITY_MART":{"header_address":4761912,"warp_table_address":5471724},"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":{"header_address":4761856,"warp_table_address":5471444},"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":{"header_address":4761884,"warp_table_address":5471584},"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":{"header_address":4761828,"warp_table_address":5471252},"MAP_RUSTURF_TUNNEL":{"header_address":4764768,"land_encounters":{"address":5605932,"slots":[370,370,370,370,370,370,370,370,370,370,370,370]},"warp_table_address":5486644},"MAP_SAFARI_ZONE_NORTH":{"header_address":4769416,"land_encounters":{"address":5610280,"slots":[231,43,231,43,177,44,44,177,178,214,178,214]},"rock_smash_encounters":{"address":5610336,"slots":[74,74,74,74,74]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHEAST":{"header_address":4769724,"land_encounters":{"address":5612476,"slots":[190,216,190,216,191,165,163,204,228,241,228,241]},"rock_smash_encounters":{"address":5612532,"slots":[213,213,213,213,213]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHWEST":{"fishing_encounters":{"address":5610448,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769388,"land_encounters":{"address":5610364,"slots":[111,43,111,43,84,44,44,84,85,127,85,127]},"warp_table_address":4160749568,"water_encounters":{"address":5610420,"slots":[54,54,54,55,55]}},"MAP_SAFARI_ZONE_REST_HOUSE":{"header_address":4769696,"warp_table_address":5516996},"MAP_SAFARI_ZONE_SOUTH":{"header_address":4769472,"land_encounters":{"address":5606212,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515444},"MAP_SAFARI_ZONE_SOUTHEAST":{"fishing_encounters":{"address":5612428,"slots":[129,118,129,118,223,118,223,223,223,224]},"header_address":4769752,"land_encounters":{"address":5612344,"slots":[191,179,191,179,190,167,163,209,234,207,234,207]},"warp_table_address":4160749568,"water_encounters":{"address":5612400,"slots":[194,183,183,183,195]}},"MAP_SAFARI_ZONE_SOUTHWEST":{"fishing_encounters":{"address":5610232,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769444,"land_encounters":{"address":5610148,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515260,"water_encounters":{"address":5610204,"slots":[54,54,54,54,54]}},"MAP_SCORCHED_SLAB":{"header_address":4766700,"warp_table_address":5498144},"MAP_SEAFLOOR_CAVERN_ENTRANCE":{"fishing_encounters":{"address":5609764,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765412,"warp_table_address":5491796,"water_encounters":{"address":5609736,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM1":{"header_address":4765440,"land_encounters":{"address":5609136,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5491952},"MAP_SEAFLOOR_CAVERN_ROOM2":{"header_address":4765468,"land_encounters":{"address":5609192,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492188},"MAP_SEAFLOOR_CAVERN_ROOM3":{"header_address":4765496,"land_encounters":{"address":5609248,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492456},"MAP_SEAFLOOR_CAVERN_ROOM4":{"header_address":4765524,"land_encounters":{"address":5609304,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492548},"MAP_SEAFLOOR_CAVERN_ROOM5":{"header_address":4765552,"land_encounters":{"address":5609360,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492744},"MAP_SEAFLOOR_CAVERN_ROOM6":{"fishing_encounters":{"address":5609500,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765580,"land_encounters":{"address":5609416,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492788,"water_encounters":{"address":5609472,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM7":{"fishing_encounters":{"address":5609632,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765608,"land_encounters":{"address":5609548,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492832,"water_encounters":{"address":5609604,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM8":{"header_address":4765636,"land_encounters":{"address":5609680,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493156},"MAP_SEAFLOOR_CAVERN_ROOM9":{"header_address":4765664,"warp_table_address":5493360},"MAP_SEALED_CHAMBER_INNER_ROOM":{"header_address":4766672,"warp_table_address":5497984},"MAP_SEALED_CHAMBER_OUTER_ROOM":{"header_address":4766644,"warp_table_address":5497608},"MAP_SECRET_BASE_BLUE_CAVE1":{"header_address":4767736,"warp_table_address":5501652},"MAP_SECRET_BASE_BLUE_CAVE2":{"header_address":4767904,"warp_table_address":5503980},"MAP_SECRET_BASE_BLUE_CAVE3":{"header_address":4768072,"warp_table_address":5506308},"MAP_SECRET_BASE_BLUE_CAVE4":{"header_address":4768240,"warp_table_address":5508636},"MAP_SECRET_BASE_BROWN_CAVE1":{"header_address":4767708,"warp_table_address":5501264},"MAP_SECRET_BASE_BROWN_CAVE2":{"header_address":4767876,"warp_table_address":5503592},"MAP_SECRET_BASE_BROWN_CAVE3":{"header_address":4768044,"warp_table_address":5505920},"MAP_SECRET_BASE_BROWN_CAVE4":{"header_address":4768212,"warp_table_address":5508248},"MAP_SECRET_BASE_RED_CAVE1":{"header_address":4767680,"warp_table_address":5500876},"MAP_SECRET_BASE_RED_CAVE2":{"header_address":4767848,"warp_table_address":5503204},"MAP_SECRET_BASE_RED_CAVE3":{"header_address":4768016,"warp_table_address":5505532},"MAP_SECRET_BASE_RED_CAVE4":{"header_address":4768184,"warp_table_address":5507860},"MAP_SECRET_BASE_SHRUB1":{"header_address":4767820,"warp_table_address":5502816},"MAP_SECRET_BASE_SHRUB2":{"header_address":4767988,"warp_table_address":5505144},"MAP_SECRET_BASE_SHRUB3":{"header_address":4768156,"warp_table_address":5507472},"MAP_SECRET_BASE_SHRUB4":{"header_address":4768324,"warp_table_address":5509800},"MAP_SECRET_BASE_TREE1":{"header_address":4767792,"warp_table_address":5502428},"MAP_SECRET_BASE_TREE2":{"header_address":4767960,"warp_table_address":5504756},"MAP_SECRET_BASE_TREE3":{"header_address":4768128,"warp_table_address":5507084},"MAP_SECRET_BASE_TREE4":{"header_address":4768296,"warp_table_address":5509412},"MAP_SECRET_BASE_YELLOW_CAVE1":{"header_address":4767764,"warp_table_address":5502040},"MAP_SECRET_BASE_YELLOW_CAVE2":{"header_address":4767932,"warp_table_address":5504368},"MAP_SECRET_BASE_YELLOW_CAVE3":{"header_address":4768100,"warp_table_address":5506696},"MAP_SECRET_BASE_YELLOW_CAVE4":{"header_address":4768268,"warp_table_address":5509024},"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":{"header_address":4766056,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":{"header_address":4766084,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":{"fishing_encounters":{"address":5611436,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765944,"land_encounters":{"address":5611352,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494828,"water_encounters":{"address":5611408,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":{"header_address":4766980,"land_encounters":{"address":5612044,"slots":[41,341,41,341,41,341,346,341,42,346,42,346]},"warp_table_address":5498544},"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":{"fishing_encounters":{"address":5611304,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765972,"land_encounters":{"address":5611220,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494904,"water_encounters":{"address":5611276,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":{"header_address":4766028,"land_encounters":{"address":5611164,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495180},"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":{"header_address":4766000,"land_encounters":{"address":5611108,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495084},"MAP_SKY_PILLAR_1F":{"header_address":4766868,"land_encounters":{"address":5612100,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498328},"MAP_SKY_PILLAR_2F":{"header_address":4766896,"warp_table_address":5498372},"MAP_SKY_PILLAR_3F":{"header_address":4766924,"land_encounters":{"address":5612232,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498408},"MAP_SKY_PILLAR_4F":{"header_address":4766952,"warp_table_address":5498452},"MAP_SKY_PILLAR_5F":{"header_address":4767008,"land_encounters":{"address":5612288,"slots":[322,42,42,322,319,378,378,319,319,359,359,359]},"warp_table_address":5498572},"MAP_SKY_PILLAR_ENTRANCE":{"header_address":4766812,"warp_table_address":5498232},"MAP_SKY_PILLAR_OUTSIDE":{"header_address":4766840,"warp_table_address":5498292},"MAP_SKY_PILLAR_TOP":{"header_address":4767036,"warp_table_address":5498656},"MAP_SLATEPORT_CITY":{"fishing_encounters":{"address":5611664,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758020,"warp_table_address":5429836,"water_encounters":{"address":5611636,"slots":[72,309,309,310,310]}},"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":{"header_address":4761212,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":{"header_address":4761184,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":{"header_address":4761156,"warp_table_address":5466624},"MAP_SLATEPORT_CITY_HARBOR":{"header_address":4761352,"warp_table_address":5468328},"MAP_SLATEPORT_CITY_HOUSE":{"header_address":4761380,"warp_table_address":5468492},"MAP_SLATEPORT_CITY_MART":{"header_address":4761464,"warp_table_address":5468856},"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":{"header_address":4761240,"warp_table_address":5466832},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":{"header_address":4761296,"warp_table_address":5467456},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":{"header_address":4761324,"warp_table_address":5467856},"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":{"header_address":4761408,"warp_table_address":5468600},"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":{"header_address":4761436,"warp_table_address":5468740},"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":{"header_address":4761268,"warp_table_address":5467084},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":{"header_address":4761100,"warp_table_address":5466360},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":{"header_address":4761128,"warp_table_address":5466476},"MAP_SOOTOPOLIS_CITY":{"fishing_encounters":{"address":5612184,"slots":[129,72,129,129,129,129,129,130,130,130]},"header_address":4758188,"warp_table_address":5433852,"water_encounters":{"address":5612156,"slots":[129,129,129,129,129]}},"MAP_SOOTOPOLIS_CITY_GYM_1F":{"header_address":4763480,"warp_table_address":5481892},"MAP_SOOTOPOLIS_CITY_GYM_B1F":{"header_address":4763508,"warp_table_address":5482200},"MAP_SOOTOPOLIS_CITY_HOUSE1":{"header_address":4763620,"warp_table_address":5482664},"MAP_SOOTOPOLIS_CITY_HOUSE2":{"header_address":4763648,"warp_table_address":5482724},"MAP_SOOTOPOLIS_CITY_HOUSE3":{"header_address":4763676,"warp_table_address":5482808},"MAP_SOOTOPOLIS_CITY_HOUSE4":{"header_address":4763704,"warp_table_address":5482916},"MAP_SOOTOPOLIS_CITY_HOUSE5":{"header_address":4763732,"warp_table_address":5483000},"MAP_SOOTOPOLIS_CITY_HOUSE6":{"header_address":4763760,"warp_table_address":5483060},"MAP_SOOTOPOLIS_CITY_HOUSE7":{"header_address":4763788,"warp_table_address":5483144},"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":{"header_address":4763816,"warp_table_address":5483228},"MAP_SOOTOPOLIS_CITY_MART":{"header_address":4763592,"warp_table_address":5482580},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":{"header_address":4763844,"warp_table_address":5483312},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":{"header_address":4763872,"warp_table_address":5483380},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":{"header_address":4763536,"warp_table_address":5482324},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":{"header_address":4763564,"warp_table_address":5482464},"MAP_SOUTHERN_ISLAND_EXTERIOR":{"header_address":4769640,"warp_table_address":5516780},"MAP_SOUTHERN_ISLAND_INTERIOR":{"header_address":4769668,"warp_table_address":5516876},"MAP_SS_TIDAL_CORRIDOR":{"header_address":4768828,"warp_table_address":5510992},"MAP_SS_TIDAL_LOWER_DECK":{"header_address":4768856,"warp_table_address":5511276},"MAP_SS_TIDAL_ROOMS":{"header_address":4768884,"warp_table_address":5511508},"MAP_TERRA_CAVE_END":{"header_address":4767596,"warp_table_address":5500392},"MAP_TERRA_CAVE_ENTRANCE":{"header_address":4767568,"warp_table_address":5500332},"MAP_TRADE_CENTER":{"header_address":4768380,"warp_table_address":5509944},"MAP_TRAINER_HILL_1F":{"header_address":4771096,"warp_table_address":5525172},"MAP_TRAINER_HILL_2F":{"header_address":4771124,"warp_table_address":5525208},"MAP_TRAINER_HILL_3F":{"header_address":4771152,"warp_table_address":5525244},"MAP_TRAINER_HILL_4F":{"header_address":4771180,"warp_table_address":5525280},"MAP_TRAINER_HILL_ELEVATOR":{"header_address":4771852,"warp_table_address":5526300},"MAP_TRAINER_HILL_ENTRANCE":{"header_address":4771068,"warp_table_address":5525100},"MAP_TRAINER_HILL_ROOF":{"header_address":4771208,"warp_table_address":5525340},"MAP_UNDERWATER_MARINE_CAVE":{"header_address":4767484,"warp_table_address":5500208},"MAP_UNDERWATER_ROUTE105":{"header_address":4759532,"warp_table_address":5457348},"MAP_UNDERWATER_ROUTE124":{"header_address":4759392,"warp_table_address":4160749568,"water_encounters":{"address":5612016,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE125":{"header_address":4759560,"warp_table_address":5457384},"MAP_UNDERWATER_ROUTE126":{"header_address":4759420,"warp_table_address":5457052,"water_encounters":{"address":5606268,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE127":{"header_address":4759448,"warp_table_address":5457176},"MAP_UNDERWATER_ROUTE128":{"header_address":4759476,"warp_table_address":5457260},"MAP_UNDERWATER_ROUTE129":{"header_address":4759504,"warp_table_address":5457312},"MAP_UNDERWATER_ROUTE134":{"header_address":4766588,"warp_table_address":5497540},"MAP_UNDERWATER_SEAFLOOR_CAVERN":{"header_address":4765384,"warp_table_address":5491744},"MAP_UNDERWATER_SEALED_CHAMBER":{"header_address":4766616,"warp_table_address":5497568},"MAP_UNDERWATER_SOOTOPOLIS_CITY":{"header_address":4764796,"warp_table_address":5486768},"MAP_UNION_ROOM":{"header_address":4769360,"warp_table_address":5514872},"MAP_UNUSED_CONTEST_HALL1":{"header_address":4768492,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL2":{"header_address":4768520,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL3":{"header_address":4768548,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL4":{"header_address":4768576,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL5":{"header_address":4768604,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL6":{"header_address":4768632,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN":{"header_address":4758384,"warp_table_address":5436044},"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760512,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760484,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760456,"warp_table_address":5463128},"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":{"header_address":4760652,"warp_table_address":5463928},"MAP_VERDANTURF_TOWN_HOUSE":{"header_address":4760680,"warp_table_address":5464012},"MAP_VERDANTURF_TOWN_MART":{"header_address":4760540,"warp_table_address":5463408},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":{"header_address":4760568,"warp_table_address":5463540},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":{"header_address":4760596,"warp_table_address":5463680},"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":{"header_address":4760624,"warp_table_address":5463844},"MAP_VICTORY_ROAD_1F":{"header_address":4765860,"land_encounters":{"address":5606156,"slots":[42,336,383,371,41,335,42,336,382,370,382,370]},"warp_table_address":5493852},"MAP_VICTORY_ROAD_B1F":{"header_address":4765888,"land_encounters":{"address":5610496,"slots":[42,336,383,383,42,336,42,336,383,355,383,355]},"rock_smash_encounters":{"address":5610552,"slots":[75,74,75,75,75]},"warp_table_address":5494460},"MAP_VICTORY_ROAD_B2F":{"fishing_encounters":{"address":5610664,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4765916,"land_encounters":{"address":5610580,"slots":[42,322,383,383,42,322,42,322,383,355,383,355]},"warp_table_address":5494704,"water_encounters":{"address":5610636,"slots":[42,42,42,42,42]}}},"misc_pokemon":[{"address":2572358,"species":385},{"address":2018148,"species":360},{"address":2323175,"species":101},{"address":2323252,"species":101},{"address":2581669,"species":317},{"address":2581574,"species":317},{"address":2581688,"species":317},{"address":2581593,"species":317},{"address":2581612,"species":317},{"address":2581631,"species":317},{"address":2581650,"species":317},{"address":2065036,"species":317},{"address":2386223,"species":185},{"address":2339323,"species":100},{"address":2339400,"species":100},{"address":2339477,"species":100}],"misc_ram_addresses":{"CB2_Overworld":134768624,"gArchipelagoDeathLinkQueued":33804824,"gArchipelagoReceivedItem":33804776,"gMain":50340544,"gPlayerParty":33703196,"gSaveBlock1Ptr":50355596,"gSaveBlock2Ptr":50355600},"misc_rom_addresses":{"FindObjectEventPaletteIndexByTag":586344,"LoadObjectEventPalette":586116,"PatchObjectPalette":586244,"gArchipelagoInfo":5912960,"gArchipelagoItemNames":5896457,"gArchipelagoNameTable":5905457,"gArchipelagoOptions":5895556,"gArchipelagoPlayerNames":5895607,"gBattleMoves":3281380,"gEvolutionTable":3318404,"gLevelUpLearnsets":3334884,"gMonBackPicTable":3174912,"gMonFootprintTable":5726932,"gMonFrontPicTable":3205844,"gMonIconPaletteIndices":5784268,"gMonIconTable":5782508,"gMonPaletteTable":3178432,"gMonShinyPaletteTable":3181952,"gObjectEventBaseOam_16x16":5311020,"gObjectEventBaseOam_16x32":5311044,"gObjectEventBaseOam_32x32":5311052,"gObjectEventGraphicsInfoPointers":5294928,"gRandomizedBerryTreeItems":5843560,"gRandomizedSoundTable":10155508,"gSpeciesInfo":3296744,"gTMHMLearnsets":3289780,"gTrainerBackAnimsPtrTable":3188308,"gTrainerBackPicPaletteTable":3188436,"gTrainerBackPicTable":3188372,"gTrainerFrontPicPaletteTable":3187332,"gTrainerFrontPicTable":3186588,"gTrainers":3230072,"gTutorMoves":6428060,"sBackAnims_Brendan":3188244,"sBackAnims_Red":3188260,"sEggHatchTiles":3344020,"sEggPalette":3343988,"sEmpty6":14929745,"sNewGamePCItems":6210444,"sOamTables_16x16":5311100,"sOamTables_16x32":5311184,"sOamTables_32x32":5311268,"sObjectEventSpritePalettes":5320952,"sStarterMon":6021752,"sTMHMMoves":6432208,"sTrainerBackSpriteTemplates":3337568,"sTutorLearnsets":6428120},"species":[{"abilities":[0,0],"address":3296744,"base_stats":[0,0,0,0,0,0],"catch_rate":0,"evolutions":[],"friendship":0,"id":0,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3296772,"base_stats":[45,49,49,45,65,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":2}],"friendship":70,"id":1,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296800,"base_stats":[60,62,63,60,80,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":3}],"friendship":70,"id":2,"learnset":{"address":3308308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":38,"move_id":74},{"level":47,"move_id":235},{"level":56,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296828,"base_stats":[80,82,83,80,100,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":3,"learnset":{"address":3308338,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":1,"move_id":22},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":41,"move_id":74},{"level":53,"move_id":235},{"level":65,"move_id":76}]},"tmhm_learnset":"00E41E0886354730","types":[12,3]},{"abilities":[66,0],"address":3296856,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":5}],"friendship":70,"id":4,"learnset":{"address":3308368,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":19,"move_id":99},{"level":25,"move_id":184},{"level":31,"move_id":53},{"level":37,"move_id":163},{"level":43,"move_id":82},{"level":49,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296884,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":6}],"friendship":70,"id":5,"learnset":{"address":3308394,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":41,"move_id":163},{"level":48,"move_id":82},{"level":55,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296912,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":6,"learnset":{"address":3308420,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":1,"move_id":108},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":36,"move_id":17},{"level":44,"move_id":163},{"level":54,"move_id":82},{"level":64,"move_id":83}]},"tmhm_learnset":"00AE5EA4CE514633","types":[10,2]},{"abilities":[67,0],"address":3296940,"base_stats":[44,48,65,43,50,64],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":8}],"friendship":70,"id":7,"learnset":{"address":3308448,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":18,"move_id":44},{"level":23,"move_id":229},{"level":28,"move_id":182},{"level":33,"move_id":240},{"level":40,"move_id":130},{"level":47,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296968,"base_stats":[59,63,80,58,65,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":9}],"friendship":70,"id":8,"learnset":{"address":3308478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":37,"move_id":240},{"level":45,"move_id":130},{"level":53,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296996,"base_stats":[79,83,100,78,85,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":9,"learnset":{"address":3308508,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":1,"move_id":110},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":42,"move_id":240},{"level":55,"move_id":130},{"level":68,"move_id":56}]},"tmhm_learnset":"03B01E00CE537275","types":[11,11]},{"abilities":[19,0],"address":3297024,"base_stats":[45,30,35,45,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":11}],"friendship":70,"id":10,"learnset":{"address":3308538,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3297052,"base_stats":[50,20,55,30,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":12}],"friendship":70,"id":11,"learnset":{"address":3308548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[14,0],"address":3297080,"base_stats":[60,45,50,70,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":12,"learnset":{"address":3308560,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":77},{"level":14,"move_id":78},{"level":15,"move_id":79},{"level":18,"move_id":48},{"level":23,"move_id":18},{"level":28,"move_id":16},{"level":34,"move_id":60},{"level":40,"move_id":219},{"level":47,"move_id":318}]},"tmhm_learnset":"0040BE80B43F4620","types":[6,2]},{"abilities":[19,0],"address":3297108,"base_stats":[40,35,30,50,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":14}],"friendship":70,"id":13,"learnset":{"address":3308590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[61,0],"address":3297136,"base_stats":[45,25,50,35,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":15}],"friendship":70,"id":14,"learnset":{"address":3308600,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[68,0],"address":3297164,"base_stats":[65,80,40,75,45,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":15,"learnset":{"address":3308612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":31},{"level":10,"move_id":31},{"level":15,"move_id":116},{"level":20,"move_id":41},{"level":25,"move_id":99},{"level":30,"move_id":228},{"level":35,"move_id":42},{"level":40,"move_id":97},{"level":45,"move_id":283}]},"tmhm_learnset":"00843E88C4354620","types":[6,3]},{"abilities":[51,0],"address":3297192,"base_stats":[40,45,40,56,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":17}],"friendship":70,"id":16,"learnset":{"address":3308638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":19,"move_id":18},{"level":25,"move_id":17},{"level":31,"move_id":297},{"level":39,"move_id":97},{"level":47,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297220,"base_stats":[63,60,55,71,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":18}],"friendship":70,"id":17,"learnset":{"address":3308664,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":43,"move_id":97},{"level":52,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297248,"base_stats":[83,80,75,91,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":18,"learnset":{"address":3308690,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":1,"move_id":98},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":48,"move_id":97},{"level":62,"move_id":119}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[50,62],"address":3297276,"base_stats":[30,56,35,72,25,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":20}],"friendship":70,"id":19,"learnset":{"address":3308716,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":116},{"level":27,"move_id":228},{"level":34,"move_id":162},{"level":41,"move_id":283}]},"tmhm_learnset":"00843E02ADD33E20","types":[0,0]},{"abilities":[50,62],"address":3297304,"base_stats":[55,81,60,97,50,70],"catch_rate":127,"evolutions":[],"friendship":70,"id":20,"learnset":{"address":3308738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":184},{"level":30,"move_id":228},{"level":40,"move_id":162},{"level":50,"move_id":283}]},"tmhm_learnset":"00A43E02ADD37E30","types":[0,0]},{"abilities":[51,0],"address":3297332,"base_stats":[40,60,30,70,31,31],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":22}],"friendship":70,"id":21,"learnset":{"address":3308760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":19,"move_id":228},{"level":25,"move_id":332},{"level":31,"move_id":119},{"level":37,"move_id":65},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297360,"base_stats":[65,90,65,100,61,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":22,"learnset":{"address":3308784,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":43},{"level":1,"move_id":31},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":26,"move_id":228},{"level":32,"move_id":119},{"level":40,"move_id":65},{"level":47,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[22,61],"address":3297388,"base_stats":[35,60,44,55,40,54],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":24}],"friendship":70,"id":23,"learnset":{"address":3308806,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":25,"move_id":103},{"level":32,"move_id":51},{"level":37,"move_id":254},{"level":37,"move_id":256},{"level":37,"move_id":255},{"level":44,"move_id":114}]},"tmhm_learnset":"00213F088E570620","types":[3,3]},{"abilities":[22,61],"address":3297416,"base_stats":[60,85,69,80,65,79],"catch_rate":90,"evolutions":[],"friendship":70,"id":24,"learnset":{"address":3308834,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":40},{"level":1,"move_id":44},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":28,"move_id":103},{"level":38,"move_id":51},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255},{"level":56,"move_id":114}]},"tmhm_learnset":"00213F088E574620","types":[3,3]},{"abilities":[9,0],"address":3297444,"base_stats":[35,55,30,90,50,40],"catch_rate":190,"evolutions":[{"method":"ITEM","param":96,"species":26}],"friendship":70,"id":25,"learnset":{"address":3308862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":45},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":98},{"level":15,"move_id":104},{"level":20,"move_id":21},{"level":26,"move_id":85},{"level":33,"move_id":97},{"level":41,"move_id":87},{"level":50,"move_id":113}]},"tmhm_learnset":"00E01E02CDD38221","types":[13,13]},{"abilities":[9,0],"address":3297472,"base_stats":[60,90,55,100,90,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":26,"learnset":{"address":3308890,"moves":[{"level":1,"move_id":84},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":1,"move_id":85}]},"tmhm_learnset":"00E03E02CDD3C221","types":[13,13]},{"abilities":[8,0],"address":3297500,"base_stats":[50,75,85,40,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":28}],"friendship":70,"id":27,"learnset":{"address":3308900,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":23,"move_id":163},{"level":30,"move_id":129},{"level":37,"move_id":154},{"level":45,"move_id":328},{"level":53,"move_id":201}]},"tmhm_learnset":"00A43ED0CE510621","types":[4,4]},{"abilities":[8,0],"address":3297528,"base_stats":[75,100,110,65,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":28,"learnset":{"address":3308926,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":28},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":24,"move_id":163},{"level":33,"move_id":129},{"level":42,"move_id":154},{"level":52,"move_id":328},{"level":62,"move_id":201}]},"tmhm_learnset":"00A43ED0CE514621","types":[4,4]},{"abilities":[38,0],"address":3297556,"base_stats":[55,47,52,41,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":30}],"friendship":70,"id":29,"learnset":{"address":3308952,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":44},{"level":23,"move_id":270},{"level":30,"move_id":154},{"level":38,"move_id":260},{"level":47,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297584,"base_stats":[70,62,67,56,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":31}],"friendship":70,"id":30,"learnset":{"address":3308978,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":44},{"level":26,"move_id":270},{"level":34,"move_id":154},{"level":43,"move_id":260},{"level":53,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297612,"base_stats":[90,82,87,76,75,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":31,"learnset":{"address":3309004,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":34}]},"tmhm_learnset":"00B43FFEEFD37E35","types":[3,4]},{"abilities":[38,0],"address":3297640,"base_stats":[46,57,40,50,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":33}],"friendship":70,"id":32,"learnset":{"address":3309016,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":30},{"level":23,"move_id":270},{"level":30,"move_id":31},{"level":38,"move_id":260},{"level":47,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297668,"base_stats":[61,72,57,65,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":34}],"friendship":70,"id":33,"learnset":{"address":3309042,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":30},{"level":26,"move_id":270},{"level":34,"move_id":31},{"level":43,"move_id":260},{"level":53,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297696,"base_stats":[81,92,77,85,85,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":34,"learnset":{"address":3309068,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":116},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":37}]},"tmhm_learnset":"00B43F7EEFD37E35","types":[3,4]},{"abilities":[56,0],"address":3297724,"base_stats":[70,45,48,35,60,65],"catch_rate":150,"evolutions":[{"method":"ITEM","param":94,"species":36}],"friendship":140,"id":35,"learnset":{"address":3309080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":227},{"level":9,"move_id":47},{"level":13,"move_id":3},{"level":17,"move_id":266},{"level":21,"move_id":107},{"level":25,"move_id":111},{"level":29,"move_id":118},{"level":33,"move_id":322},{"level":37,"move_id":236},{"level":41,"move_id":113},{"level":45,"move_id":309}]},"tmhm_learnset":"00611E27FDFBB62D","types":[0,0]},{"abilities":[56,0],"address":3297752,"base_stats":[95,70,73,60,85,90],"catch_rate":25,"evolutions":[],"friendship":140,"id":36,"learnset":{"address":3309112,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":3},{"level":1,"move_id":107},{"level":1,"move_id":118}]},"tmhm_learnset":"00611E27FDFBF62D","types":[0,0]},{"abilities":[18,0],"address":3297780,"base_stats":[38,41,40,65,50,65],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":38}],"friendship":70,"id":37,"learnset":{"address":3309122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":5,"move_id":39},{"level":9,"move_id":46},{"level":13,"move_id":98},{"level":17,"move_id":261},{"level":21,"move_id":109},{"level":25,"move_id":286},{"level":29,"move_id":53},{"level":33,"move_id":219},{"level":37,"move_id":288},{"level":41,"move_id":83}]},"tmhm_learnset":"00021E248C590630","types":[10,10]},{"abilities":[18,0],"address":3297808,"base_stats":[73,76,75,100,81,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":38,"learnset":{"address":3309152,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":98},{"level":1,"move_id":109},{"level":1,"move_id":219},{"level":45,"move_id":83}]},"tmhm_learnset":"00021E248C594630","types":[10,10]},{"abilities":[56,0],"address":3297836,"base_stats":[115,45,20,20,45,25],"catch_rate":170,"evolutions":[{"method":"ITEM","param":94,"species":40}],"friendship":70,"id":39,"learnset":{"address":3309164,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":50},{"level":19,"move_id":205},{"level":24,"move_id":3},{"level":29,"move_id":156},{"level":34,"move_id":34},{"level":39,"move_id":102},{"level":44,"move_id":304},{"level":49,"move_id":38}]},"tmhm_learnset":"00611E27FDBBB625","types":[0,0]},{"abilities":[56,0],"address":3297864,"base_stats":[140,70,45,45,75,50],"catch_rate":50,"evolutions":[],"friendship":70,"id":40,"learnset":{"address":3309194,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":50},{"level":1,"move_id":111},{"level":1,"move_id":3}]},"tmhm_learnset":"00611E27FDBBF625","types":[0,0]},{"abilities":[39,0],"address":3297892,"base_stats":[40,45,35,55,30,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":42}],"friendship":70,"id":41,"learnset":{"address":3309204,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":141},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":26,"move_id":109},{"level":31,"move_id":314},{"level":36,"move_id":212},{"level":41,"move_id":305},{"level":46,"move_id":114}]},"tmhm_learnset":"00017F88A4170E20","types":[3,2]},{"abilities":[39,0],"address":3297920,"base_stats":[75,80,70,90,65,75],"catch_rate":90,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":169}],"friendship":70,"id":42,"learnset":{"address":3309232,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00017F88A4174E20","types":[3,2]},{"abilities":[34,0],"address":3297948,"base_stats":[45,50,55,30,75,65],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":44}],"friendship":70,"id":43,"learnset":{"address":3309260,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":23,"move_id":51},{"level":32,"move_id":236},{"level":39,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3297976,"base_stats":[60,65,70,40,85,75],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":45},{"method":"ITEM","param":93,"species":182}],"friendship":70,"id":44,"learnset":{"address":3309284,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":77},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":24,"move_id":51},{"level":35,"move_id":236},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298004,"base_stats":[75,80,85,50,100,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":45,"learnset":{"address":3309308,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":312},{"level":1,"move_id":78},{"level":1,"move_id":72},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884354720","types":[12,3]},{"abilities":[27,0],"address":3298032,"base_stats":[35,70,55,25,45,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":24,"species":47}],"friendship":70,"id":46,"learnset":{"address":3309320,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":25,"move_id":147},{"level":31,"move_id":163},{"level":37,"move_id":74},{"level":43,"move_id":202},{"level":49,"move_id":312}]},"tmhm_learnset":"00C43E888C350720","types":[6,12]},{"abilities":[27,0],"address":3298060,"base_stats":[60,95,80,30,60,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":47,"learnset":{"address":3309346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":78},{"level":1,"move_id":77},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":27,"move_id":147},{"level":35,"move_id":163},{"level":43,"move_id":74},{"level":51,"move_id":202},{"level":59,"move_id":312}]},"tmhm_learnset":"00C43E888C354720","types":[6,12]},{"abilities":[14,0],"address":3298088,"base_stats":[60,55,50,45,40,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":49}],"friendship":70,"id":48,"learnset":{"address":3309372,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":33,"move_id":60},{"level":36,"move_id":79},{"level":41,"move_id":94}]},"tmhm_learnset":"0040BE0894350620","types":[6,3]},{"abilities":[19,0],"address":3298116,"base_stats":[70,65,60,90,90,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":49,"learnset":{"address":3309398,"moves":[{"level":1,"move_id":318},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":1,"move_id":48},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":31,"move_id":16},{"level":36,"move_id":60},{"level":42,"move_id":79},{"level":52,"move_id":94}]},"tmhm_learnset":"0040BE8894354620","types":[6,3]},{"abilities":[8,71],"address":3298144,"base_stats":[10,55,25,95,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":26,"species":51}],"friendship":70,"id":50,"learnset":{"address":3309428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":33,"move_id":163},{"level":41,"move_id":89},{"level":49,"move_id":90}]},"tmhm_learnset":"00843EC88E110620","types":[4,4]},{"abilities":[8,71],"address":3298172,"base_stats":[35,80,50,120,50,70],"catch_rate":50,"evolutions":[],"friendship":70,"id":51,"learnset":{"address":3309452,"moves":[{"level":1,"move_id":161},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":1,"move_id":45},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":26,"move_id":328},{"level":38,"move_id":163},{"level":51,"move_id":89},{"level":64,"move_id":90}]},"tmhm_learnset":"00843EC88E114620","types":[4,4]},{"abilities":[53,0],"address":3298200,"base_stats":[40,45,35,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":28,"species":53}],"friendship":70,"id":52,"learnset":{"address":3309478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":28,"move_id":185},{"level":35,"move_id":103},{"level":41,"move_id":154},{"level":46,"move_id":163},{"level":50,"move_id":252}]},"tmhm_learnset":"00453F82ADD30E24","types":[0,0]},{"abilities":[7,0],"address":3298228,"base_stats":[65,70,60,115,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":53,"learnset":{"address":3309502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":44},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":29,"move_id":185},{"level":38,"move_id":103},{"level":46,"move_id":154},{"level":53,"move_id":163},{"level":59,"move_id":252}]},"tmhm_learnset":"00453F82ADD34E34","types":[0,0]},{"abilities":[6,13],"address":3298256,"base_stats":[50,52,48,55,65,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":33,"species":55}],"friendship":70,"id":54,"learnset":{"address":3309526,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":40,"move_id":154},{"level":50,"move_id":56}]},"tmhm_learnset":"03F01E80CC53326D","types":[11,11]},{"abilities":[6,13],"address":3298284,"base_stats":[80,82,78,85,95,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":55,"learnset":{"address":3309550,"moves":[{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":50},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":44,"move_id":154},{"level":58,"move_id":56}]},"tmhm_learnset":"03F01E80CC53726D","types":[11,11]},{"abilities":[72,0],"address":3298312,"base_stats":[40,80,35,70,35,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":57}],"friendship":70,"id":56,"learnset":{"address":3309574,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":33,"move_id":69},{"level":39,"move_id":238},{"level":45,"move_id":103},{"level":51,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD30EA1","types":[1,1]},{"abilities":[72,0],"address":3298340,"base_stats":[65,105,60,95,60,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":57,"learnset":{"address":3309600,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":67},{"level":1,"move_id":99},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":28,"move_id":99},{"level":36,"move_id":69},{"level":45,"move_id":238},{"level":54,"move_id":103},{"level":63,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD34EA1","types":[1,1]},{"abilities":[22,18],"address":3298368,"base_stats":[55,70,45,60,70,50],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":59}],"friendship":70,"id":58,"learnset":{"address":3309628,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":7,"move_id":52},{"level":13,"move_id":43},{"level":19,"move_id":316},{"level":25,"move_id":36},{"level":31,"move_id":172},{"level":37,"move_id":270},{"level":43,"move_id":97},{"level":49,"move_id":53}]},"tmhm_learnset":"00A23EA48C510630","types":[10,10]},{"abilities":[22,18],"address":3298396,"base_stats":[90,110,80,95,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":59,"learnset":{"address":3309654,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":1,"move_id":52},{"level":1,"move_id":316},{"level":49,"move_id":245}]},"tmhm_learnset":"00A23EA48C514630","types":[10,10]},{"abilities":[11,6],"address":3298424,"base_stats":[40,50,40,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":61}],"friendship":70,"id":60,"learnset":{"address":3309666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":25,"move_id":240},{"level":31,"move_id":34},{"level":37,"move_id":187},{"level":43,"move_id":56}]},"tmhm_learnset":"03103E009C133264","types":[11,11]},{"abilities":[11,6],"address":3298452,"base_stats":[65,65,65,90,50,50],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":62},{"method":"ITEM","param":187,"species":186}],"friendship":70,"id":61,"learnset":{"address":3309690,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":95},{"level":1,"move_id":55},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":27,"move_id":240},{"level":35,"move_id":34},{"level":43,"move_id":187},{"level":51,"move_id":56}]},"tmhm_learnset":"03B03E00DE133265","types":[11,11]},{"abilities":[11,6],"address":3298480,"base_stats":[90,85,95,70,70,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":62,"learnset":{"address":3309714,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":66},{"level":35,"move_id":66},{"level":51,"move_id":170}]},"tmhm_learnset":"03B03E40DE1372E5","types":[11,1]},{"abilities":[28,39],"address":3298508,"base_stats":[25,20,15,90,105,55],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":16,"species":64}],"friendship":70,"id":63,"learnset":{"address":3309728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":100}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298536,"base_stats":[40,35,30,105,120,70],"catch_rate":100,"evolutions":[{"method":"LEVEL","param":37,"species":65}],"friendship":70,"id":64,"learnset":{"address":3309738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":272},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298564,"base_stats":[55,50,45,120,135,85],"catch_rate":50,"evolutions":[],"friendship":70,"id":65,"learnset":{"address":3309766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":347},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45BCE29","types":[14,14]},{"abilities":[62,0],"address":3298592,"base_stats":[70,80,50,35,35,35],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":28,"species":67}],"friendship":70,"id":66,"learnset":{"address":3309794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":31,"move_id":233},{"level":37,"move_id":66},{"level":40,"move_id":238},{"level":43,"move_id":184},{"level":49,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298620,"base_stats":[80,100,70,45,50,60],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":68}],"friendship":70,"id":67,"learnset":{"address":3309824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298648,"base_stats":[90,130,80,55,65,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":68,"learnset":{"address":3309854,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1346A1","types":[1,1]},{"abilities":[34,0],"address":3298676,"base_stats":[50,75,35,40,70,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":70}],"friendship":70,"id":69,"learnset":{"address":3309884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":23,"move_id":51},{"level":30,"move_id":230},{"level":37,"move_id":75},{"level":45,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298704,"base_stats":[65,90,50,55,85,45],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":71}],"friendship":70,"id":70,"learnset":{"address":3309912,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":1,"move_id":74},{"level":1,"move_id":35},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":24,"move_id":51},{"level":33,"move_id":230},{"level":42,"move_id":75},{"level":54,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298732,"base_stats":[80,105,65,70,100,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":71,"learnset":{"address":3309940,"moves":[{"level":1,"move_id":22},{"level":1,"move_id":79},{"level":1,"move_id":230},{"level":1,"move_id":75}]},"tmhm_learnset":"00443E0884354720","types":[12,3]},{"abilities":[29,64],"address":3298760,"base_stats":[40,40,35,70,50,100],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":73}],"friendship":70,"id":72,"learnset":{"address":3309950,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":36,"move_id":112},{"level":43,"move_id":103},{"level":49,"move_id":56}]},"tmhm_learnset":"03143E0884173264","types":[11,3]},{"abilities":[29,64],"address":3298788,"base_stats":[80,70,65,100,80,120],"catch_rate":60,"evolutions":[],"friendship":70,"id":73,"learnset":{"address":3309976,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":48},{"level":1,"move_id":132},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":38,"move_id":112},{"level":47,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03143E0884177264","types":[11,3]},{"abilities":[69,5],"address":3298816,"base_stats":[40,80,100,20,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":75}],"friendship":70,"id":74,"learnset":{"address":3310002,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":26,"move_id":205},{"level":31,"move_id":350},{"level":36,"move_id":89},{"level":41,"move_id":153},{"level":46,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298844,"base_stats":[55,95,115,35,45,45],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":37,"species":76}],"friendship":70,"id":75,"learnset":{"address":3310030,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298872,"base_stats":[80,110,130,45,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":76,"learnset":{"address":3310058,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE114631","types":[5,4]},{"abilities":[50,18],"address":3298900,"base_stats":[50,85,55,90,65,65],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":40,"species":78}],"friendship":70,"id":77,"learnset":{"address":3310086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":45,"move_id":340},{"level":53,"move_id":126}]},"tmhm_learnset":"00221E2484710620","types":[10,10]},{"abilities":[50,18],"address":3298928,"base_stats":[65,100,70,105,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":78,"learnset":{"address":3310114,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":52},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":40,"move_id":31},{"level":50,"move_id":340},{"level":63,"move_id":126}]},"tmhm_learnset":"00221E2484714620","types":[10,10]},{"abilities":[12,20],"address":3298956,"base_stats":[90,65,65,15,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":80},{"method":"ITEM","param":187,"species":199}],"friendship":70,"id":79,"learnset":{"address":3310144,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":133},{"level":48,"move_id":94}]},"tmhm_learnset":"02709E24BE5B366C","types":[11,14]},{"abilities":[12,20],"address":3298984,"base_stats":[95,75,110,30,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":80,"learnset":{"address":3310168,"moves":[{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":37,"move_id":110},{"level":46,"move_id":133},{"level":54,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[42,5],"address":3299012,"base_stats":[25,35,70,45,95,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":82}],"friendship":70,"id":81,"learnset":{"address":3310194,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":32,"move_id":199},{"level":38,"move_id":129},{"level":44,"move_id":103},{"level":50,"move_id":192}]},"tmhm_learnset":"00400E0385930620","types":[13,8]},{"abilities":[42,5],"address":3299040,"base_stats":[50,60,95,70,120,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":82,"learnset":{"address":3310222,"moves":[{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":1,"move_id":84},{"level":1,"move_id":48},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":35,"move_id":199},{"level":44,"move_id":161},{"level":53,"move_id":103},{"level":62,"move_id":192}]},"tmhm_learnset":"00400E0385934620","types":[13,8]},{"abilities":[51,39],"address":3299068,"base_stats":[52,65,55,60,58,62],"catch_rate":45,"evolutions":[],"friendship":70,"id":83,"learnset":{"address":3310250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":6,"move_id":28},{"level":11,"move_id":43},{"level":16,"move_id":31},{"level":21,"move_id":282},{"level":26,"move_id":210},{"level":31,"move_id":14},{"level":36,"move_id":97},{"level":41,"move_id":163},{"level":46,"move_id":206}]},"tmhm_learnset":"000C7E8084510620","types":[0,2]},{"abilities":[50,48],"address":3299096,"base_stats":[35,85,45,75,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":85}],"friendship":70,"id":84,"learnset":{"address":3310278,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":33,"move_id":253},{"level":37,"move_id":65},{"level":45,"move_id":97}]},"tmhm_learnset":"00087E8084110620","types":[0,2]},{"abilities":[50,48],"address":3299124,"base_stats":[60,110,70,100,60,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":85,"learnset":{"address":3310302,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":228},{"level":1,"move_id":31},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":38,"move_id":253},{"level":47,"move_id":65},{"level":60,"move_id":97}]},"tmhm_learnset":"00087F8084114E20","types":[0,2]},{"abilities":[47,0],"address":3299152,"base_stats":[65,45,55,45,45,70],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":34,"species":87}],"friendship":70,"id":86,"learnset":{"address":3310326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":29},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":37,"move_id":36},{"level":41,"move_id":58},{"level":49,"move_id":219}]},"tmhm_learnset":"03103E00841B3264","types":[11,11]},{"abilities":[47,0],"address":3299180,"base_stats":[90,70,80,70,70,95],"catch_rate":75,"evolutions":[],"friendship":70,"id":87,"learnset":{"address":3310350,"moves":[{"level":1,"move_id":29},{"level":1,"move_id":45},{"level":1,"move_id":196},{"level":1,"move_id":62},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":34,"move_id":329},{"level":42,"move_id":36},{"level":51,"move_id":58},{"level":64,"move_id":219}]},"tmhm_learnset":"03103E00841B7264","types":[11,15]},{"abilities":[1,60],"address":3299208,"base_stats":[80,80,50,25,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":89}],"friendship":70,"id":88,"learnset":{"address":3310376,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":43,"move_id":188},{"level":53,"move_id":262}]},"tmhm_learnset":"00003F6E8D970E20","types":[3,3]},{"abilities":[1,60],"address":3299236,"base_stats":[105,105,75,50,65,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":89,"learnset":{"address":3310402,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":47,"move_id":188},{"level":61,"move_id":262}]},"tmhm_learnset":"00A03F6ECD974E21","types":[3,3]},{"abilities":[75,0],"address":3299264,"base_stats":[30,65,100,40,45,25],"catch_rate":190,"evolutions":[{"method":"ITEM","param":97,"species":91}],"friendship":70,"id":90,"learnset":{"address":3310428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":110},{"level":9,"move_id":48},{"level":17,"move_id":62},{"level":25,"move_id":182},{"level":33,"move_id":43},{"level":41,"move_id":128},{"level":49,"move_id":58}]},"tmhm_learnset":"02101E0084133264","types":[11,11]},{"abilities":[75,0],"address":3299292,"base_stats":[50,95,180,70,85,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":91,"learnset":{"address":3310450,"moves":[{"level":1,"move_id":110},{"level":1,"move_id":48},{"level":1,"move_id":62},{"level":1,"move_id":182},{"level":33,"move_id":191},{"level":41,"move_id":131}]},"tmhm_learnset":"02101F0084137264","types":[11,15]},{"abilities":[26,0],"address":3299320,"base_stats":[30,35,30,80,100,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":93}],"friendship":70,"id":92,"learnset":{"address":3310464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":28,"move_id":109},{"level":33,"move_id":138},{"level":36,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299348,"base_stats":[45,50,45,95,115,55],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":94}],"friendship":70,"id":93,"learnset":{"address":3310488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299376,"base_stats":[60,65,60,110,130,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":94,"learnset":{"address":3310514,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"00A1BF08F5974E21","types":[7,3]},{"abilities":[69,5],"address":3299404,"base_stats":[35,45,160,70,30,45],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":208}],"friendship":70,"id":95,"learnset":{"address":3310540,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":328},{"level":57,"move_id":38}]},"tmhm_learnset":"00A01F508E510E30","types":[5,4]},{"abilities":[15,0],"address":3299432,"base_stats":[60,48,45,42,43,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":26,"species":97}],"friendship":70,"id":96,"learnset":{"address":3310568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":31,"move_id":139},{"level":36,"move_id":96},{"level":40,"move_id":94},{"level":43,"move_id":244},{"level":45,"move_id":248}]},"tmhm_learnset":"0041BF01F41B8E29","types":[14,14]},{"abilities":[15,0],"address":3299460,"base_stats":[85,73,70,67,73,115],"catch_rate":75,"evolutions":[],"friendship":70,"id":97,"learnset":{"address":3310594,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":1,"move_id":50},{"level":1,"move_id":93},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":33,"move_id":139},{"level":40,"move_id":96},{"level":49,"move_id":94},{"level":55,"move_id":244},{"level":60,"move_id":248}]},"tmhm_learnset":"0041BF01F41BCE29","types":[14,14]},{"abilities":[52,75],"address":3299488,"base_stats":[30,105,90,50,25,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":28,"species":99}],"friendship":70,"id":98,"learnset":{"address":3310620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":34,"move_id":12},{"level":41,"move_id":182},{"level":45,"move_id":152}]},"tmhm_learnset":"02B43E408C133264","types":[11,11]},{"abilities":[52,75],"address":3299516,"base_stats":[55,130,115,75,50,50],"catch_rate":60,"evolutions":[],"friendship":70,"id":99,"learnset":{"address":3310646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":43},{"level":1,"move_id":11},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":38,"move_id":12},{"level":49,"move_id":182},{"level":57,"move_id":152}]},"tmhm_learnset":"02B43E408C137264","types":[11,11]},{"abilities":[43,9],"address":3299544,"base_stats":[40,30,50,100,55,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":101}],"friendship":70,"id":100,"learnset":{"address":3310672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":32,"move_id":205},{"level":37,"move_id":113},{"level":42,"move_id":129},{"level":46,"move_id":153},{"level":49,"move_id":243}]},"tmhm_learnset":"00402F0285938A20","types":[13,13]},{"abilities":[43,9],"address":3299572,"base_stats":[60,50,70,140,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":101,"learnset":{"address":3310700,"moves":[{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":1,"move_id":49},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":34,"move_id":205},{"level":41,"move_id":113},{"level":48,"move_id":129},{"level":54,"move_id":153},{"level":59,"move_id":243}]},"tmhm_learnset":"00402F028593CA20","types":[13,13]},{"abilities":[34,0],"address":3299600,"base_stats":[60,40,80,40,60,45],"catch_rate":90,"evolutions":[{"method":"ITEM","param":98,"species":103}],"friendship":70,"id":102,"learnset":{"address":3310728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":253},{"level":1,"move_id":95},{"level":7,"move_id":115},{"level":13,"move_id":73},{"level":19,"move_id":93},{"level":25,"move_id":78},{"level":31,"move_id":77},{"level":37,"move_id":79},{"level":43,"move_id":76}]},"tmhm_learnset":"0060BE0994358720","types":[12,14]},{"abilities":[34,0],"address":3299628,"base_stats":[95,95,85,55,125,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":103,"learnset":{"address":3310752,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":95},{"level":1,"move_id":93},{"level":19,"move_id":23},{"level":31,"move_id":121}]},"tmhm_learnset":"0060BE099435C720","types":[12,14]},{"abilities":[69,31],"address":3299656,"base_stats":[50,50,95,35,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":105}],"friendship":70,"id":104,"learnset":{"address":3310766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":125},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":29,"move_id":99},{"level":33,"move_id":206},{"level":37,"move_id":37},{"level":41,"move_id":198},{"level":45,"move_id":38}]},"tmhm_learnset":"00A03EF4CE513621","types":[4,4]},{"abilities":[69,31],"address":3299684,"base_stats":[60,80,110,45,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":105,"learnset":{"address":3310798,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":125},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":32,"move_id":99},{"level":39,"move_id":206},{"level":46,"move_id":37},{"level":53,"move_id":198},{"level":61,"move_id":38}]},"tmhm_learnset":"00A03EF4CE517621","types":[4,4]},{"abilities":[7,0],"address":3299712,"base_stats":[50,120,53,87,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":106,"learnset":{"address":3310830,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":24},{"level":6,"move_id":96},{"level":11,"move_id":27},{"level":16,"move_id":26},{"level":20,"move_id":280},{"level":21,"move_id":116},{"level":26,"move_id":136},{"level":31,"move_id":170},{"level":36,"move_id":193},{"level":41,"move_id":203},{"level":46,"move_id":25},{"level":51,"move_id":179}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[51,0],"address":3299740,"base_stats":[50,105,79,76,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":107,"learnset":{"address":3310862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":4},{"level":7,"move_id":97},{"level":13,"move_id":228},{"level":20,"move_id":183},{"level":26,"move_id":9},{"level":26,"move_id":8},{"level":26,"move_id":7},{"level":32,"move_id":327},{"level":38,"move_id":5},{"level":44,"move_id":197},{"level":50,"move_id":68}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[20,12],"address":3299768,"base_stats":[90,55,75,30,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":108,"learnset":{"address":3310892,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":122},{"level":7,"move_id":48},{"level":12,"move_id":111},{"level":18,"move_id":282},{"level":23,"move_id":23},{"level":29,"move_id":35},{"level":34,"move_id":50},{"level":40,"move_id":21},{"level":45,"move_id":103},{"level":51,"move_id":287}]},"tmhm_learnset":"00B43E76EFF37625","types":[0,0]},{"abilities":[26,0],"address":3299796,"base_stats":[40,65,95,35,60,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":35,"species":110}],"friendship":70,"id":109,"learnset":{"address":3310920,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":41,"move_id":153},{"level":45,"move_id":194},{"level":49,"move_id":262}]},"tmhm_learnset":"00403F2EA5930E20","types":[3,3]},{"abilities":[26,0],"address":3299824,"base_stats":[65,90,120,60,85,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":110,"learnset":{"address":3310946,"moves":[{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":1,"move_id":123},{"level":1,"move_id":120},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":44,"move_id":153},{"level":51,"move_id":194},{"level":58,"move_id":262}]},"tmhm_learnset":"00403F2EA5934E20","types":[3,3]},{"abilities":[31,69],"address":3299852,"base_stats":[80,85,95,25,30,30],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":42,"species":112}],"friendship":70,"id":111,"learnset":{"address":3310972,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":43,"move_id":36},{"level":52,"move_id":89},{"level":57,"move_id":224}]},"tmhm_learnset":"00A03E768FD33630","types":[4,5]},{"abilities":[31,69],"address":3299880,"base_stats":[105,130,120,40,45,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":112,"learnset":{"address":3310998,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":1,"move_id":23},{"level":1,"move_id":31},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":46,"move_id":36},{"level":58,"move_id":89},{"level":66,"move_id":224}]},"tmhm_learnset":"00B43E76CFD37631","types":[4,5]},{"abilities":[30,32],"address":3299908,"base_stats":[250,5,5,50,35,105],"catch_rate":30,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":242}],"friendship":140,"id":113,"learnset":{"address":3311024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":287},{"level":13,"move_id":135},{"level":17,"move_id":3},{"level":23,"move_id":107},{"level":29,"move_id":47},{"level":35,"move_id":121},{"level":41,"move_id":111},{"level":49,"move_id":113},{"level":57,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[34,0],"address":3299936,"base_stats":[65,55,115,60,100,40],"catch_rate":45,"evolutions":[],"friendship":70,"id":114,"learnset":{"address":3311054,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":275},{"level":1,"move_id":132},{"level":4,"move_id":79},{"level":10,"move_id":71},{"level":13,"move_id":74},{"level":19,"move_id":77},{"level":22,"move_id":22},{"level":28,"move_id":20},{"level":31,"move_id":72},{"level":37,"move_id":78},{"level":40,"move_id":21},{"level":46,"move_id":321}]},"tmhm_learnset":"00C43E0884354720","types":[12,12]},{"abilities":[48,0],"address":3299964,"base_stats":[105,95,80,90,40,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":115,"learnset":{"address":3311084,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":4},{"level":1,"move_id":43},{"level":7,"move_id":44},{"level":13,"move_id":39},{"level":19,"move_id":252},{"level":25,"move_id":5},{"level":31,"move_id":99},{"level":37,"move_id":203},{"level":43,"move_id":146},{"level":49,"move_id":179}]},"tmhm_learnset":"00B43EF6EFF37675","types":[0,0]},{"abilities":[33,0],"address":3299992,"base_stats":[30,40,70,60,70,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":32,"species":117}],"friendship":70,"id":116,"learnset":{"address":3311110,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":36,"move_id":97},{"level":43,"move_id":56},{"level":50,"move_id":349}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[38,0],"address":3300020,"base_stats":[55,65,95,85,95,45],"catch_rate":75,"evolutions":[{"method":"ITEM","param":201,"species":230}],"friendship":70,"id":117,"learnset":{"address":3311134,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[33,41],"address":3300048,"base_stats":[45,67,60,63,35,50],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":119}],"friendship":70,"id":118,"learnset":{"address":3311158,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":38,"move_id":127},{"level":43,"move_id":32},{"level":52,"move_id":97}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,41],"address":3300076,"base_stats":[80,92,65,68,65,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":119,"learnset":{"address":3311182,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":1,"move_id":48},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":41,"move_id":127},{"level":49,"move_id":32},{"level":61,"move_id":97}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[35,30],"address":3300104,"base_stats":[30,45,55,85,70,55],"catch_rate":225,"evolutions":[{"method":"ITEM","param":97,"species":121}],"friendship":70,"id":120,"learnset":{"address":3311206,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":6,"move_id":55},{"level":10,"move_id":229},{"level":15,"move_id":105},{"level":19,"move_id":293},{"level":24,"move_id":129},{"level":28,"move_id":61},{"level":33,"move_id":107},{"level":37,"move_id":113},{"level":42,"move_id":322},{"level":46,"move_id":56}]},"tmhm_learnset":"03500E019593B264","types":[11,11]},{"abilities":[35,30],"address":3300132,"base_stats":[60,75,85,115,100,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":121,"learnset":{"address":3311236,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":229},{"level":1,"move_id":105},{"level":1,"move_id":129},{"level":33,"move_id":109}]},"tmhm_learnset":"03508E019593F264","types":[11,14]},{"abilities":[43,0],"address":3300160,"base_stats":[40,45,65,90,100,120],"catch_rate":45,"evolutions":[],"friendship":70,"id":122,"learnset":{"address":3311248,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":112},{"level":5,"move_id":93},{"level":9,"move_id":164},{"level":13,"move_id":96},{"level":17,"move_id":3},{"level":21,"move_id":113},{"level":21,"move_id":115},{"level":25,"move_id":227},{"level":29,"move_id":60},{"level":33,"move_id":278},{"level":37,"move_id":271},{"level":41,"move_id":272},{"level":45,"move_id":94},{"level":49,"move_id":226},{"level":53,"move_id":219}]},"tmhm_learnset":"0041BF03F5BBCE29","types":[14,14]},{"abilities":[68,0],"address":3300188,"base_stats":[70,110,80,105,55,80],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":212}],"friendship":70,"id":123,"learnset":{"address":3311286,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":17},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00847E8084134620","types":[6,2]},{"abilities":[12,0],"address":3300216,"base_stats":[65,50,35,95,115,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":124,"learnset":{"address":3311314,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":1,"move_id":142},{"level":1,"move_id":181},{"level":9,"move_id":142},{"level":13,"move_id":181},{"level":21,"move_id":3},{"level":25,"move_id":8},{"level":35,"move_id":212},{"level":41,"move_id":313},{"level":51,"move_id":34},{"level":57,"move_id":195},{"level":67,"move_id":59}]},"tmhm_learnset":"0040BF01F413FA6D","types":[15,14]},{"abilities":[9,0],"address":3300244,"base_stats":[65,83,57,105,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":125,"learnset":{"address":3311342,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":1,"move_id":9},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":36,"move_id":103},{"level":47,"move_id":85},{"level":58,"move_id":87}]},"tmhm_learnset":"00E03E02D5D3C221","types":[13,13]},{"abilities":[49,0],"address":3300272,"base_stats":[65,95,57,93,100,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":126,"learnset":{"address":3311364,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":43},{"level":1,"move_id":123},{"level":1,"move_id":7},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":33,"move_id":241},{"level":41,"move_id":53},{"level":49,"move_id":109},{"level":57,"move_id":126}]},"tmhm_learnset":"00A03E24D4514621","types":[10,10]},{"abilities":[52,0],"address":3300300,"base_stats":[65,125,100,85,55,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":127,"learnset":{"address":3311390,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":11},{"level":1,"move_id":116},{"level":7,"move_id":20},{"level":13,"move_id":69},{"level":19,"move_id":106},{"level":25,"move_id":279},{"level":31,"move_id":280},{"level":37,"move_id":12},{"level":43,"move_id":66},{"level":49,"move_id":14}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,6]},{"abilities":[22,0],"address":3300328,"base_stats":[75,100,95,110,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":128,"learnset":{"address":3311416,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":8,"move_id":99},{"level":13,"move_id":30},{"level":19,"move_id":184},{"level":26,"move_id":228},{"level":34,"move_id":156},{"level":43,"move_id":37},{"level":53,"move_id":36}]},"tmhm_learnset":"00B01E7687F37624","types":[0,0]},{"abilities":[33,0],"address":3300356,"base_stats":[20,10,55,80,15,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":130}],"friendship":70,"id":129,"learnset":{"address":3311442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"0000000000000000","types":[11,11]},{"abilities":[22,0],"address":3300384,"base_stats":[95,125,79,81,60,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":130,"learnset":{"address":3311456,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":37},{"level":20,"move_id":44},{"level":25,"move_id":82},{"level":30,"move_id":43},{"level":35,"move_id":239},{"level":40,"move_id":56},{"level":45,"move_id":240},{"level":50,"move_id":349},{"level":55,"move_id":63}]},"tmhm_learnset":"03B01F3487937A74","types":[11,2]},{"abilities":[11,75],"address":3300412,"base_stats":[130,85,80,60,85,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":131,"learnset":{"address":3311482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":45},{"level":1,"move_id":47},{"level":7,"move_id":54},{"level":13,"move_id":34},{"level":19,"move_id":109},{"level":25,"move_id":195},{"level":31,"move_id":58},{"level":37,"move_id":240},{"level":43,"move_id":219},{"level":49,"move_id":56},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E0295DB7274","types":[11,15]},{"abilities":[7,0],"address":3300440,"base_stats":[48,48,48,48,48,48],"catch_rate":35,"evolutions":[],"friendship":70,"id":132,"learnset":{"address":3311510,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":144}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[50,0],"address":3300468,"base_stats":[55,55,50,55,45,65],"catch_rate":45,"evolutions":[{"method":"ITEM","param":96,"species":135},{"method":"ITEM","param":97,"species":134},{"method":"ITEM","param":95,"species":136},{"method":"FRIENDSHIP_DAY","param":0,"species":196},{"method":"FRIENDSHIP_NIGHT","param":0,"species":197}],"friendship":70,"id":133,"learnset":{"address":3311520,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":45},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":226},{"level":42,"move_id":36}]},"tmhm_learnset":"00001E00AC530620","types":[0,0]},{"abilities":[11,0],"address":3300496,"base_stats":[130,65,60,65,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":134,"learnset":{"address":3311542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":55},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":62},{"level":42,"move_id":114},{"level":47,"move_id":151},{"level":52,"move_id":56}]},"tmhm_learnset":"03101E00AC537674","types":[11,11]},{"abilities":[10,0],"address":3300524,"base_stats":[65,65,60,130,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":135,"learnset":{"address":3311568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":84},{"level":23,"move_id":98},{"level":30,"move_id":24},{"level":36,"move_id":42},{"level":42,"move_id":86},{"level":47,"move_id":97},{"level":52,"move_id":87}]},"tmhm_learnset":"00401E02ADD34630","types":[13,13]},{"abilities":[18,0],"address":3300552,"base_stats":[65,130,60,65,95,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":136,"learnset":{"address":3311594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":52},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":83},{"level":42,"move_id":123},{"level":47,"move_id":43},{"level":52,"move_id":53}]},"tmhm_learnset":"00021E24AC534630","types":[10,10]},{"abilities":[36,0],"address":3300580,"base_stats":[65,60,70,40,85,75],"catch_rate":45,"evolutions":[{"method":"ITEM","param":218,"species":233}],"friendship":70,"id":137,"learnset":{"address":3311620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":159},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[33,75],"address":3300608,"base_stats":[35,40,100,35,90,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":139}],"friendship":70,"id":138,"learnset":{"address":3311646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":43,"move_id":321},{"level":49,"move_id":246},{"level":55,"move_id":56}]},"tmhm_learnset":"03903E5084133264","types":[5,11]},{"abilities":[33,75],"address":3300636,"base_stats":[70,60,125,55,115,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":139,"learnset":{"address":3311672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":1,"move_id":44},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":40,"move_id":131},{"level":46,"move_id":321},{"level":55,"move_id":246},{"level":65,"move_id":56}]},"tmhm_learnset":"03903E5084137264","types":[5,11]},{"abilities":[33,4],"address":3300664,"base_stats":[30,80,90,55,55,45],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":141}],"friendship":70,"id":140,"learnset":{"address":3311700,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":43,"move_id":319},{"level":49,"move_id":72},{"level":55,"move_id":246}]},"tmhm_learnset":"01903ED08C173264","types":[5,11]},{"abilities":[33,4],"address":3300692,"base_stats":[60,115,105,80,65,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":141,"learnset":{"address":3311726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":71},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":40,"move_id":163},{"level":46,"move_id":319},{"level":55,"move_id":72},{"level":65,"move_id":246}]},"tmhm_learnset":"03943ED0CC177264","types":[5,11]},{"abilities":[69,46],"address":3300720,"base_stats":[80,105,65,130,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":142,"learnset":{"address":3311754,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":8,"move_id":97},{"level":15,"move_id":44},{"level":22,"move_id":48},{"level":29,"move_id":246},{"level":36,"move_id":184},{"level":43,"move_id":36},{"level":50,"move_id":63}]},"tmhm_learnset":"00A87FF486534E32","types":[5,2]},{"abilities":[17,47],"address":3300748,"base_stats":[160,110,65,30,65,110],"catch_rate":25,"evolutions":[],"friendship":70,"id":143,"learnset":{"address":3311778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":133},{"level":10,"move_id":111},{"level":15,"move_id":187},{"level":19,"move_id":29},{"level":24,"move_id":281},{"level":28,"move_id":156},{"level":28,"move_id":173},{"level":33,"move_id":34},{"level":37,"move_id":335},{"level":42,"move_id":343},{"level":46,"move_id":205},{"level":51,"move_id":63}]},"tmhm_learnset":"00301E76F7B37625","types":[0,0]},{"abilities":[46,0],"address":3300776,"base_stats":[90,85,100,85,95,125],"catch_rate":3,"evolutions":[],"friendship":35,"id":144,"learnset":{"address":3311812,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":181},{"level":13,"move_id":54},{"level":25,"move_id":97},{"level":37,"move_id":170},{"level":49,"move_id":58},{"level":61,"move_id":115},{"level":73,"move_id":59},{"level":85,"move_id":329}]},"tmhm_learnset":"00884E9184137674","types":[15,2]},{"abilities":[46,0],"address":3300804,"base_stats":[90,90,85,100,125,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":145,"learnset":{"address":3311836,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":84},{"level":13,"move_id":86},{"level":25,"move_id":97},{"level":37,"move_id":197},{"level":49,"move_id":65},{"level":61,"move_id":268},{"level":73,"move_id":113},{"level":85,"move_id":87}]},"tmhm_learnset":"00C84E928593C630","types":[13,2]},{"abilities":[46,0],"address":3300832,"base_stats":[90,100,90,90,125,85],"catch_rate":3,"evolutions":[],"friendship":35,"id":146,"learnset":{"address":3311860,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":1,"move_id":52},{"level":13,"move_id":83},{"level":25,"move_id":97},{"level":37,"move_id":203},{"level":49,"move_id":53},{"level":61,"move_id":219},{"level":73,"move_id":257},{"level":85,"move_id":143}]},"tmhm_learnset":"008A4EB4841B4630","types":[10,2]},{"abilities":[61,0],"address":3300860,"base_stats":[41,64,45,50,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":148}],"friendship":35,"id":147,"learnset":{"address":3311884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":36,"move_id":97},{"level":43,"move_id":219},{"level":50,"move_id":200},{"level":57,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[61,0],"address":3300888,"base_stats":[61,84,65,70,70,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":149}],"friendship":35,"id":148,"learnset":{"address":3311910,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":56,"move_id":200},{"level":65,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[39,0],"address":3300916,"base_stats":[91,134,95,80,100,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":149,"learnset":{"address":3311936,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":55,"move_id":17},{"level":61,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BC5EF6C7DB7677","types":[16,2]},{"abilities":[46,0],"address":3300944,"base_stats":[106,110,90,130,154,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":150,"learnset":{"address":3311964,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":50},{"level":11,"move_id":112},{"level":22,"move_id":129},{"level":33,"move_id":244},{"level":44,"move_id":248},{"level":55,"move_id":54},{"level":66,"move_id":94},{"level":77,"move_id":133},{"level":88,"move_id":105},{"level":99,"move_id":219}]},"tmhm_learnset":"00E18FF7F7FBFEED","types":[14,14]},{"abilities":[28,0],"address":3300972,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":151,"learnset":{"address":3311992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":10,"move_id":144},{"level":20,"move_id":5},{"level":30,"move_id":118},{"level":40,"move_id":94},{"level":50,"move_id":246}]},"tmhm_learnset":"03FFFFFFFFFFFFFF","types":[14,14]},{"abilities":[65,0],"address":3301000,"base_stats":[45,49,65,45,49,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":153}],"friendship":70,"id":152,"learnset":{"address":3312012,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":22,"move_id":235},{"level":29,"move_id":34},{"level":36,"move_id":113},{"level":43,"move_id":219},{"level":50,"move_id":76}]},"tmhm_learnset":"00441E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301028,"base_stats":[60,62,80,60,63,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":154}],"friendship":70,"id":153,"learnset":{"address":3312038,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":39,"move_id":113},{"level":47,"move_id":219},{"level":55,"move_id":76}]},"tmhm_learnset":"00E41E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301056,"base_stats":[80,82,100,80,83,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":154,"learnset":{"address":3312064,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":41,"move_id":113},{"level":51,"move_id":219},{"level":61,"move_id":76}]},"tmhm_learnset":"00E41E01867DC720","types":[12,12]},{"abilities":[66,0],"address":3301084,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":14,"species":156}],"friendship":70,"id":155,"learnset":{"address":3312090,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":19,"move_id":98},{"level":27,"move_id":172},{"level":36,"move_id":129},{"level":46,"move_id":53}]},"tmhm_learnset":"00061EA48C110620","types":[10,10]},{"abilities":[66,0],"address":3301112,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":157}],"friendship":70,"id":156,"learnset":{"address":3312112,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":42,"move_id":129},{"level":54,"move_id":53}]},"tmhm_learnset":"00A61EA4CC110631","types":[10,10]},{"abilities":[66,0],"address":3301140,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":157,"learnset":{"address":3312134,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":1,"move_id":52},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":45,"move_id":129},{"level":60,"move_id":53}]},"tmhm_learnset":"00A61EA4CE114631","types":[10,10]},{"abilities":[67,0],"address":3301168,"base_stats":[50,65,64,43,44,48],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":18,"species":159}],"friendship":70,"id":158,"learnset":{"address":3312156,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":20,"move_id":44},{"level":27,"move_id":184},{"level":35,"move_id":163},{"level":43,"move_id":103},{"level":52,"move_id":56}]},"tmhm_learnset":"03141E80CC533265","types":[11,11]},{"abilities":[67,0],"address":3301196,"base_stats":[65,80,80,58,59,63],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":160}],"friendship":70,"id":159,"learnset":{"address":3312180,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":37,"move_id":163},{"level":45,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03B41E80CC533275","types":[11,11]},{"abilities":[67,0],"address":3301224,"base_stats":[85,105,100,78,79,83],"catch_rate":45,"evolutions":[],"friendship":70,"id":160,"learnset":{"address":3312204,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":1,"move_id":55},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":38,"move_id":163},{"level":47,"move_id":103},{"level":58,"move_id":56}]},"tmhm_learnset":"03B41E80CE537277","types":[11,11]},{"abilities":[50,51],"address":3301252,"base_stats":[35,46,34,20,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":15,"species":162}],"friendship":70,"id":161,"learnset":{"address":3312228,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":17,"move_id":270},{"level":24,"move_id":21},{"level":31,"move_id":266},{"level":40,"move_id":156},{"level":49,"move_id":133}]},"tmhm_learnset":"00143E06ECF31625","types":[0,0]},{"abilities":[50,51],"address":3301280,"base_stats":[85,76,64,90,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":162,"learnset":{"address":3312254,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":98},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":19,"move_id":270},{"level":28,"move_id":21},{"level":37,"move_id":266},{"level":48,"move_id":156},{"level":59,"move_id":133}]},"tmhm_learnset":"00B43E06EDF37625","types":[0,0]},{"abilities":[15,51],"address":3301308,"base_stats":[60,30,30,50,36,56],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":164}],"friendship":70,"id":163,"learnset":{"address":3312280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":22,"move_id":115},{"level":28,"move_id":36},{"level":34,"move_id":93},{"level":48,"move_id":138}]},"tmhm_learnset":"00487E81B4130620","types":[0,2]},{"abilities":[15,51],"address":3301336,"base_stats":[100,50,50,70,76,96],"catch_rate":90,"evolutions":[],"friendship":70,"id":164,"learnset":{"address":3312304,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":193},{"level":1,"move_id":64},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":25,"move_id":115},{"level":33,"move_id":36},{"level":41,"move_id":93},{"level":57,"move_id":138}]},"tmhm_learnset":"00487E81B4134620","types":[0,2]},{"abilities":[68,48],"address":3301364,"base_stats":[40,20,30,55,40,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":166}],"friendship":70,"id":165,"learnset":{"address":3312328,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":22,"move_id":113},{"level":22,"move_id":115},{"level":22,"move_id":219},{"level":29,"move_id":226},{"level":36,"move_id":129},{"level":43,"move_id":97},{"level":50,"move_id":38}]},"tmhm_learnset":"00403E81CC3D8621","types":[6,2]},{"abilities":[68,48],"address":3301392,"base_stats":[55,35,50,85,55,110],"catch_rate":90,"evolutions":[],"friendship":70,"id":166,"learnset":{"address":3312356,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":48},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":24,"move_id":113},{"level":24,"move_id":115},{"level":24,"move_id":219},{"level":33,"move_id":226},{"level":42,"move_id":129},{"level":51,"move_id":97},{"level":60,"move_id":38}]},"tmhm_learnset":"00403E81CC3DC621","types":[6,2]},{"abilities":[68,15],"address":3301420,"base_stats":[40,60,40,30,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":168}],"friendship":70,"id":167,"learnset":{"address":3312384,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":23,"move_id":141},{"level":30,"move_id":154},{"level":37,"move_id":169},{"level":45,"move_id":97},{"level":53,"move_id":94}]},"tmhm_learnset":"00403E089C350620","types":[6,3]},{"abilities":[68,15],"address":3301448,"base_stats":[70,90,70,40,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":168,"learnset":{"address":3312410,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":1,"move_id":184},{"level":1,"move_id":132},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":25,"move_id":141},{"level":34,"move_id":154},{"level":43,"move_id":169},{"level":53,"move_id":97},{"level":63,"move_id":94}]},"tmhm_learnset":"00403E089C354620","types":[6,3]},{"abilities":[39,0],"address":3301476,"base_stats":[85,90,80,130,70,80],"catch_rate":90,"evolutions":[],"friendship":70,"id":169,"learnset":{"address":3312436,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00097F88A4174E20","types":[3,2]},{"abilities":[10,35],"address":3301504,"base_stats":[75,38,38,67,56,56],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":27,"species":171}],"friendship":70,"id":170,"learnset":{"address":3312464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":29,"move_id":109},{"level":37,"move_id":36},{"level":41,"move_id":56},{"level":49,"move_id":268}]},"tmhm_learnset":"03501E0285933264","types":[11,13]},{"abilities":[10,35],"address":3301532,"base_stats":[125,58,58,67,76,76],"catch_rate":75,"evolutions":[],"friendship":70,"id":171,"learnset":{"address":3312490,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":1,"move_id":48},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":32,"move_id":109},{"level":43,"move_id":36},{"level":50,"move_id":56},{"level":61,"move_id":268}]},"tmhm_learnset":"03501E0285937264","types":[11,13]},{"abilities":[9,0],"address":3301560,"base_stats":[20,40,15,60,35,35],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":25}],"friendship":70,"id":172,"learnset":{"address":3312516,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":204},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":186}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[56,0],"address":3301588,"base_stats":[50,25,28,15,45,55],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":35}],"friendship":140,"id":173,"learnset":{"address":3312532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":204},{"level":4,"move_id":227},{"level":8,"move_id":47},{"level":13,"move_id":186}]},"tmhm_learnset":"00401E27BC7B8624","types":[0,0]},{"abilities":[56,0],"address":3301616,"base_stats":[90,30,15,15,40,20],"catch_rate":170,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":39}],"friendship":70,"id":174,"learnset":{"address":3312548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":1,"move_id":204},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":186}]},"tmhm_learnset":"00401E27BC3B8624","types":[0,0]},{"abilities":[55,32],"address":3301644,"base_stats":[35,20,65,20,40,65],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":176}],"friendship":70,"id":175,"learnset":{"address":3312564,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C01E27B43B8624","types":[0,0]},{"abilities":[55,32],"address":3301672,"base_stats":[55,40,85,40,80,105],"catch_rate":75,"evolutions":[],"friendship":70,"id":176,"learnset":{"address":3312590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C85EA7F43BC625","types":[0,2]},{"abilities":[28,48],"address":3301700,"base_stats":[40,50,45,70,70,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":178}],"friendship":70,"id":177,"learnset":{"address":3312616,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":30,"move_id":273},{"level":30,"move_id":248},{"level":40,"move_id":109},{"level":50,"move_id":94}]},"tmhm_learnset":"0040FE81B4378628","types":[14,2]},{"abilities":[28,48],"address":3301728,"base_stats":[65,75,70,95,95,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":178,"learnset":{"address":3312638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":35,"move_id":273},{"level":35,"move_id":248},{"level":50,"move_id":109},{"level":65,"move_id":94}]},"tmhm_learnset":"0048FE81B437C628","types":[14,2]},{"abilities":[9,0],"address":3301756,"base_stats":[55,40,40,35,65,45],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":15,"species":180}],"friendship":70,"id":179,"learnset":{"address":3312660,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":84},{"level":16,"move_id":86},{"level":23,"move_id":178},{"level":30,"move_id":113},{"level":37,"move_id":87}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[9,0],"address":3301784,"base_stats":[70,55,55,45,80,60],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":181}],"friendship":70,"id":180,"learnset":{"address":3312680,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":36,"move_id":113},{"level":45,"move_id":87}]},"tmhm_learnset":"00E01E02C5D38221","types":[13,13]},{"abilities":[9,0],"address":3301812,"base_stats":[90,75,75,55,115,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":181,"learnset":{"address":3312700,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":1,"move_id":86},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":30,"move_id":9},{"level":42,"move_id":113},{"level":57,"move_id":87}]},"tmhm_learnset":"00E01E02C5D3C221","types":[13,13]},{"abilities":[34,0],"address":3301840,"base_stats":[75,80,85,50,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":182,"learnset":{"address":3312722,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":78},{"level":1,"move_id":345},{"level":44,"move_id":80},{"level":55,"move_id":76}]},"tmhm_learnset":"00441E08843D4720","types":[12,12]},{"abilities":[47,37],"address":3301868,"base_stats":[70,20,50,40,20,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":18,"species":184}],"friendship":70,"id":183,"learnset":{"address":3312736,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":21,"move_id":61},{"level":28,"move_id":38},{"level":36,"move_id":240},{"level":45,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[47,37],"address":3301896,"base_stats":[100,50,80,50,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":184,"learnset":{"address":3312762,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":39},{"level":1,"move_id":55},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":24,"move_id":61},{"level":34,"move_id":38},{"level":45,"move_id":240},{"level":57,"move_id":56}]},"tmhm_learnset":"03B01E00CC537265","types":[11,11]},{"abilities":[5,69],"address":3301924,"base_stats":[70,100,115,30,30,65],"catch_rate":65,"evolutions":[],"friendship":70,"id":185,"learnset":{"address":3312788,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":102},{"level":9,"move_id":175},{"level":17,"move_id":67},{"level":25,"move_id":157},{"level":33,"move_id":335},{"level":41,"move_id":185},{"level":49,"move_id":21},{"level":57,"move_id":38}]},"tmhm_learnset":"00A03E50CE110E29","types":[5,5]},{"abilities":[11,6],"address":3301952,"base_stats":[90,75,75,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":186,"learnset":{"address":3312812,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":195},{"level":35,"move_id":195},{"level":51,"move_id":207}]},"tmhm_learnset":"03B03E00DE137265","types":[11,11]},{"abilities":[34,0],"address":3301980,"base_stats":[35,35,40,50,35,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":188}],"friendship":70,"id":187,"learnset":{"address":3312826,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":20,"move_id":73},{"level":25,"move_id":178},{"level":30,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302008,"base_stats":[55,45,50,80,45,65],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":27,"species":189}],"friendship":70,"id":188,"learnset":{"address":3312854,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":29,"move_id":178},{"level":36,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302036,"base_stats":[75,55,70,110,55,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":189,"learnset":{"address":3312882,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":33,"move_id":178},{"level":44,"move_id":72}]},"tmhm_learnset":"00401E8084354720","types":[12,2]},{"abilities":[50,53],"address":3302064,"base_stats":[55,70,55,85,40,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":190,"learnset":{"address":3312910,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":6,"move_id":28},{"level":13,"move_id":310},{"level":18,"move_id":226},{"level":25,"move_id":321},{"level":31,"move_id":154},{"level":38,"move_id":129},{"level":43,"move_id":103},{"level":50,"move_id":97}]},"tmhm_learnset":"00A53E82EDF30E25","types":[0,0]},{"abilities":[34,0],"address":3302092,"base_stats":[30,30,30,30,30,30],"catch_rate":235,"evolutions":[{"method":"ITEM","param":93,"species":192}],"friendship":70,"id":191,"learnset":{"address":3312936,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":6,"move_id":74},{"level":13,"move_id":72},{"level":18,"move_id":275},{"level":25,"move_id":283},{"level":30,"move_id":241},{"level":37,"move_id":235},{"level":42,"move_id":202}]},"tmhm_learnset":"00441E08843D8720","types":[12,12]},{"abilities":[34,0],"address":3302120,"base_stats":[75,75,55,30,105,85],"catch_rate":120,"evolutions":[],"friendship":70,"id":192,"learnset":{"address":3312960,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":1},{"level":6,"move_id":74},{"level":13,"move_id":75},{"level":18,"move_id":275},{"level":25,"move_id":331},{"level":30,"move_id":241},{"level":37,"move_id":80},{"level":42,"move_id":76}]},"tmhm_learnset":"00441E08843DC720","types":[12,12]},{"abilities":[3,14],"address":3302148,"base_stats":[65,65,45,95,75,45],"catch_rate":75,"evolutions":[],"friendship":70,"id":193,"learnset":{"address":3312984,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":193},{"level":7,"move_id":98},{"level":13,"move_id":104},{"level":19,"move_id":49},{"level":25,"move_id":197},{"level":31,"move_id":48},{"level":37,"move_id":253},{"level":43,"move_id":17},{"level":49,"move_id":103}]},"tmhm_learnset":"00407E80B4350620","types":[6,2]},{"abilities":[6,11],"address":3302176,"base_stats":[55,45,45,15,25,25],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":195}],"friendship":70,"id":194,"learnset":{"address":3313010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":21,"move_id":133},{"level":31,"move_id":281},{"level":36,"move_id":89},{"level":41,"move_id":240},{"level":51,"move_id":54},{"level":51,"move_id":114}]},"tmhm_learnset":"03D01E188E533264","types":[11,4]},{"abilities":[6,11],"address":3302204,"base_stats":[95,85,85,35,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":195,"learnset":{"address":3313036,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":23,"move_id":133},{"level":35,"move_id":281},{"level":42,"move_id":89},{"level":49,"move_id":240},{"level":61,"move_id":54},{"level":61,"move_id":114}]},"tmhm_learnset":"03F01E58CE537265","types":[11,4]},{"abilities":[28,0],"address":3302232,"base_stats":[65,65,60,110,130,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":196,"learnset":{"address":3313062,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":93},{"level":23,"move_id":98},{"level":30,"move_id":129},{"level":36,"move_id":60},{"level":42,"move_id":244},{"level":47,"move_id":94},{"level":52,"move_id":234}]},"tmhm_learnset":"00449E01BC53C628","types":[14,14]},{"abilities":[28,0],"address":3302260,"base_stats":[95,65,110,65,60,130],"catch_rate":45,"evolutions":[],"friendship":35,"id":197,"learnset":{"address":3313088,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":228},{"level":23,"move_id":98},{"level":30,"move_id":109},{"level":36,"move_id":185},{"level":42,"move_id":212},{"level":47,"move_id":103},{"level":52,"move_id":236}]},"tmhm_learnset":"00451F00BC534E20","types":[17,17]},{"abilities":[15,0],"address":3302288,"base_stats":[60,85,42,91,85,42],"catch_rate":30,"evolutions":[],"friendship":35,"id":198,"learnset":{"address":3313114,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":9,"move_id":310},{"level":14,"move_id":228},{"level":22,"move_id":114},{"level":27,"move_id":101},{"level":35,"move_id":185},{"level":40,"move_id":269},{"level":48,"move_id":212}]},"tmhm_learnset":"00097F80A4130E28","types":[17,2]},{"abilities":[12,20],"address":3302316,"base_stats":[95,75,80,30,100,110],"catch_rate":70,"evolutions":[],"friendship":70,"id":199,"learnset":{"address":3313138,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":207},{"level":48,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[26,0],"address":3302344,"base_stats":[60,60,60,85,85,85],"catch_rate":45,"evolutions":[],"friendship":35,"id":200,"learnset":{"address":3313162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":149},{"level":6,"move_id":180},{"level":11,"move_id":310},{"level":17,"move_id":109},{"level":23,"move_id":212},{"level":30,"move_id":60},{"level":37,"move_id":220},{"level":45,"move_id":195},{"level":53,"move_id":288}]},"tmhm_learnset":"0041BF82B5930E28","types":[7,7]},{"abilities":[26,0],"address":3302372,"base_stats":[48,72,48,48,72,48],"catch_rate":225,"evolutions":[],"friendship":70,"id":201,"learnset":{"address":3313188,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":237}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[23,0],"address":3302400,"base_stats":[190,33,58,33,33,58],"catch_rate":45,"evolutions":[],"friendship":70,"id":202,"learnset":{"address":3313198,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":243},{"level":1,"move_id":219},{"level":1,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[39,48],"address":3302428,"base_stats":[70,80,65,85,90,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":203,"learnset":{"address":3313208,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":7,"move_id":310},{"level":13,"move_id":93},{"level":19,"move_id":23},{"level":25,"move_id":316},{"level":31,"move_id":97},{"level":37,"move_id":226},{"level":43,"move_id":60},{"level":49,"move_id":242}]},"tmhm_learnset":"00E0BE03B7D38628","types":[0,14]},{"abilities":[5,0],"address":3302456,"base_stats":[50,65,90,15,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":205}],"friendship":70,"id":204,"learnset":{"address":3313234,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":36,"move_id":153},{"level":43,"move_id":191},{"level":50,"move_id":38}]},"tmhm_learnset":"00A01E118E358620","types":[6,6]},{"abilities":[5,0],"address":3302484,"base_stats":[75,90,140,40,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":205,"learnset":{"address":3313258,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":1,"move_id":120},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":39,"move_id":153},{"level":49,"move_id":191},{"level":59,"move_id":38}]},"tmhm_learnset":"00A01E118E35C620","types":[6,8]},{"abilities":[32,50],"address":3302512,"base_stats":[100,70,70,45,65,65],"catch_rate":190,"evolutions":[],"friendship":70,"id":206,"learnset":{"address":3313282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":4,"move_id":111},{"level":11,"move_id":281},{"level":14,"move_id":137},{"level":21,"move_id":180},{"level":24,"move_id":228},{"level":31,"move_id":103},{"level":34,"move_id":36},{"level":41,"move_id":283}]},"tmhm_learnset":"00A03E66AFF3362C","types":[0,0]},{"abilities":[52,8],"address":3302540,"base_stats":[65,75,105,85,35,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":207,"learnset":{"address":3313308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":28},{"level":13,"move_id":106},{"level":20,"move_id":98},{"level":28,"move_id":185},{"level":36,"move_id":163},{"level":44,"move_id":103},{"level":52,"move_id":12}]},"tmhm_learnset":"00A47ED88E530620","types":[4,2]},{"abilities":[69,5],"address":3302568,"base_stats":[75,85,200,30,55,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":208,"learnset":{"address":3313332,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":242},{"level":57,"move_id":38}]},"tmhm_learnset":"00A41F508E514E30","types":[8,4]},{"abilities":[22,50],"address":3302596,"base_stats":[60,80,50,30,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":23,"species":210}],"friendship":70,"id":209,"learnset":{"address":3313360,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":26,"move_id":46},{"level":34,"move_id":99},{"level":43,"move_id":36},{"level":53,"move_id":242}]},"tmhm_learnset":"00A23F2EEFB30EB5","types":[0,0]},{"abilities":[22,22],"address":3302624,"base_stats":[90,120,75,45,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":210,"learnset":{"address":3313386,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":28,"move_id":46},{"level":38,"move_id":99},{"level":49,"move_id":36},{"level":61,"move_id":242}]},"tmhm_learnset":"00A23F6EEFF34EB5","types":[0,0]},{"abilities":[38,33],"address":3302652,"base_stats":[65,95,75,85,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":211,"learnset":{"address":3313412,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":191},{"level":1,"move_id":33},{"level":1,"move_id":40},{"level":10,"move_id":106},{"level":10,"move_id":107},{"level":19,"move_id":55},{"level":28,"move_id":42},{"level":37,"move_id":36},{"level":46,"move_id":56}]},"tmhm_learnset":"03101E0AA4133264","types":[11,3]},{"abilities":[68,0],"address":3302680,"base_stats":[70,130,100,65,55,80],"catch_rate":25,"evolutions":[],"friendship":70,"id":212,"learnset":{"address":3313434,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":232},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00A47E9084134620","types":[6,8]},{"abilities":[5,0],"address":3302708,"base_stats":[20,10,230,5,10,230],"catch_rate":190,"evolutions":[],"friendship":70,"id":213,"learnset":{"address":3313462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":9,"move_id":35},{"level":14,"move_id":227},{"level":23,"move_id":219},{"level":28,"move_id":117},{"level":37,"move_id":156}]},"tmhm_learnset":"00E01E588E190620","types":[6,5]},{"abilities":[68,62],"address":3302736,"base_stats":[80,125,75,85,40,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":214,"learnset":{"address":3313482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":30},{"level":11,"move_id":203},{"level":17,"move_id":31},{"level":23,"move_id":280},{"level":30,"move_id":68},{"level":37,"move_id":36},{"level":45,"move_id":179},{"level":53,"move_id":224}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,1]},{"abilities":[39,51],"address":3302764,"base_stats":[55,95,55,115,35,75],"catch_rate":60,"evolutions":[],"friendship":35,"id":215,"learnset":{"address":3313508,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":269},{"level":8,"move_id":98},{"level":15,"move_id":103},{"level":22,"move_id":185},{"level":29,"move_id":154},{"level":36,"move_id":97},{"level":43,"move_id":196},{"level":50,"move_id":163},{"level":57,"move_id":251},{"level":64,"move_id":232}]},"tmhm_learnset":"00B53F80EC533E69","types":[17,15]},{"abilities":[53,0],"address":3302792,"base_stats":[60,80,50,40,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":217}],"friendship":70,"id":216,"learnset":{"address":3313536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43F80CE130EB1","types":[0,0]},{"abilities":[62,0],"address":3302820,"base_stats":[90,130,75,55,75,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":217,"learnset":{"address":3313562,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":122},{"level":1,"move_id":154},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43FC0CE134EB1","types":[0,0]},{"abilities":[40,49],"address":3302848,"base_stats":[40,40,40,20,70,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":219}],"friendship":70,"id":218,"learnset":{"address":3313588,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":43,"move_id":157},{"level":50,"move_id":34}]},"tmhm_learnset":"00821E2584118620","types":[10,10]},{"abilities":[40,49],"address":3302876,"base_stats":[50,50,120,30,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":219,"learnset":{"address":3313612,"moves":[{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":1,"move_id":52},{"level":1,"move_id":88},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":48,"move_id":157},{"level":60,"move_id":34}]},"tmhm_learnset":"00A21E758611C620","types":[10,5]},{"abilities":[12,0],"address":3302904,"base_stats":[50,50,40,50,30,30],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":221}],"friendship":70,"id":220,"learnset":{"address":3313636,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":316},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":37,"move_id":54},{"level":46,"move_id":59},{"level":55,"move_id":133}]},"tmhm_learnset":"00A01E518E13B270","types":[15,4]},{"abilities":[12,0],"address":3302932,"base_stats":[100,100,80,50,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":221,"learnset":{"address":3313658,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":316},{"level":1,"move_id":181},{"level":1,"move_id":203},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":33,"move_id":31},{"level":42,"move_id":54},{"level":56,"move_id":59},{"level":70,"move_id":133}]},"tmhm_learnset":"00A01E518E13F270","types":[15,4]},{"abilities":[55,30],"address":3302960,"base_stats":[55,55,85,35,65,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":222,"learnset":{"address":3313682,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":106},{"level":12,"move_id":145},{"level":17,"move_id":105},{"level":17,"move_id":287},{"level":23,"move_id":61},{"level":28,"move_id":131},{"level":34,"move_id":350},{"level":39,"move_id":243},{"level":45,"move_id":246}]},"tmhm_learnset":"00B01E51BE1BB66C","types":[11,5]},{"abilities":[55,0],"address":3302988,"base_stats":[35,65,35,65,65,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":224}],"friendship":70,"id":223,"learnset":{"address":3313710,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":199},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":33,"move_id":116},{"level":44,"move_id":58},{"level":55,"move_id":63}]},"tmhm_learnset":"03103E2494137624","types":[11,11]},{"abilities":[21,0],"address":3303016,"base_stats":[75,105,75,45,105,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":224,"learnset":{"address":3313734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":132},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":25,"move_id":190},{"level":38,"move_id":116},{"level":54,"move_id":58},{"level":70,"move_id":63}]},"tmhm_learnset":"03103E2C94137724","types":[11,11]},{"abilities":[72,55],"address":3303044,"base_stats":[45,55,45,75,65,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":225,"learnset":{"address":3313760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":217}]},"tmhm_learnset":"00083E8084133265","types":[15,2]},{"abilities":[33,11],"address":3303072,"base_stats":[65,40,70,70,80,140],"catch_rate":25,"evolutions":[],"friendship":70,"id":226,"learnset":{"address":3313770,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":145},{"level":8,"move_id":48},{"level":15,"move_id":61},{"level":22,"move_id":36},{"level":29,"move_id":97},{"level":36,"move_id":17},{"level":43,"move_id":352},{"level":50,"move_id":109}]},"tmhm_learnset":"03101E8086133264","types":[11,2]},{"abilities":[51,5],"address":3303100,"base_stats":[65,80,140,70,40,70],"catch_rate":25,"evolutions":[],"friendship":70,"id":227,"learnset":{"address":3313794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":10,"move_id":28},{"level":13,"move_id":129},{"level":16,"move_id":97},{"level":26,"move_id":31},{"level":29,"move_id":314},{"level":32,"move_id":211},{"level":42,"move_id":191},{"level":45,"move_id":319}]},"tmhm_learnset":"008C7F9084110E30","types":[8,2]},{"abilities":[48,18],"address":3303128,"base_stats":[45,60,30,65,80,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":24,"species":229}],"friendship":35,"id":228,"learnset":{"address":3313820,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":25,"move_id":44},{"level":31,"move_id":316},{"level":37,"move_id":185},{"level":43,"move_id":53},{"level":49,"move_id":242}]},"tmhm_learnset":"00833F2CA4710E30","types":[17,10]},{"abilities":[48,18],"address":3303156,"base_stats":[75,90,50,95,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":229,"learnset":{"address":3313846,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":1,"move_id":336},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":27,"move_id":44},{"level":35,"move_id":316},{"level":43,"move_id":185},{"level":51,"move_id":53},{"level":59,"move_id":242}]},"tmhm_learnset":"00A33F2CA4714E30","types":[17,10]},{"abilities":[33,0],"address":3303184,"base_stats":[75,95,95,85,95,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":230,"learnset":{"address":3313872,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,16]},{"abilities":[53,0],"address":3303212,"base_stats":[90,60,60,40,40,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":25,"species":232}],"friendship":70,"id":231,"learnset":{"address":3313896,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":36},{"level":33,"move_id":205},{"level":41,"move_id":203},{"level":49,"move_id":38}]},"tmhm_learnset":"00A01E5086510630","types":[4,4]},{"abilities":[5,0],"address":3303240,"base_stats":[90,120,120,50,60,60],"catch_rate":60,"evolutions":[],"friendship":70,"id":232,"learnset":{"address":3313918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":30},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":31},{"level":33,"move_id":205},{"level":41,"move_id":229},{"level":49,"move_id":89}]},"tmhm_learnset":"00A01E5086514630","types":[4,4]},{"abilities":[36,0],"address":3303268,"base_stats":[85,80,90,60,105,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":233,"learnset":{"address":3313940,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":111},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[22,0],"address":3303296,"base_stats":[73,95,62,85,85,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":234,"learnset":{"address":3313966,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":43},{"level":13,"move_id":310},{"level":19,"move_id":95},{"level":25,"move_id":23},{"level":31,"move_id":28},{"level":37,"move_id":36},{"level":43,"move_id":109},{"level":49,"move_id":347}]},"tmhm_learnset":"0040BE03B7F38638","types":[0,0]},{"abilities":[20,0],"address":3303324,"base_stats":[55,20,35,75,20,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":235,"learnset":{"address":3313992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":166},{"level":11,"move_id":166},{"level":21,"move_id":166},{"level":31,"move_id":166},{"level":41,"move_id":166},{"level":51,"move_id":166},{"level":61,"move_id":166},{"level":71,"move_id":166},{"level":81,"move_id":166},{"level":91,"move_id":166}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[62,0],"address":3303352,"base_stats":[35,35,35,35,35,35],"catch_rate":75,"evolutions":[{"method":"LEVEL_ATK_LT_DEF","param":20,"species":107},{"method":"LEVEL_ATK_GT_DEF","param":20,"species":106},{"method":"LEVEL_ATK_EQ_DEF","param":20,"species":237}],"friendship":70,"id":236,"learnset":{"address":3314020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"00A03E00C61306A0","types":[1,1]},{"abilities":[22,0],"address":3303380,"base_stats":[50,95,95,70,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":237,"learnset":{"address":3314030,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":27},{"level":7,"move_id":116},{"level":13,"move_id":228},{"level":19,"move_id":98},{"level":20,"move_id":167},{"level":25,"move_id":229},{"level":31,"move_id":68},{"level":37,"move_id":97},{"level":43,"move_id":197},{"level":49,"move_id":283}]},"tmhm_learnset":"00A03E10CE1306A0","types":[1,1]},{"abilities":[12,0],"address":3303408,"base_stats":[45,30,15,65,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":124}],"friendship":70,"id":238,"learnset":{"address":3314058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":9,"move_id":186},{"level":13,"move_id":181},{"level":21,"move_id":93},{"level":25,"move_id":47},{"level":33,"move_id":212},{"level":37,"move_id":313},{"level":45,"move_id":94},{"level":49,"move_id":195},{"level":57,"move_id":59}]},"tmhm_learnset":"0040BE01B413B26C","types":[15,14]},{"abilities":[9,0],"address":3303436,"base_stats":[45,63,37,95,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":125}],"friendship":70,"id":239,"learnset":{"address":3314086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":33,"move_id":103},{"level":41,"move_id":85},{"level":49,"move_id":87}]},"tmhm_learnset":"00C03E02D5938221","types":[13,13]},{"abilities":[49,0],"address":3303464,"base_stats":[45,75,37,83,70,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":126}],"friendship":70,"id":240,"learnset":{"address":3314108,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":31,"move_id":241},{"level":37,"move_id":53},{"level":43,"move_id":109},{"level":49,"move_id":126}]},"tmhm_learnset":"00803E24D4510621","types":[10,10]},{"abilities":[47,0],"address":3303492,"base_stats":[95,80,105,100,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":241,"learnset":{"address":3314134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":8,"move_id":111},{"level":13,"move_id":23},{"level":19,"move_id":208},{"level":26,"move_id":117},{"level":34,"move_id":205},{"level":43,"move_id":34},{"level":53,"move_id":215}]},"tmhm_learnset":"00B01E52E7F37625","types":[0,0]},{"abilities":[30,32],"address":3303520,"base_stats":[255,10,10,55,75,135],"catch_rate":30,"evolutions":[],"friendship":140,"id":242,"learnset":{"address":3314160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":4,"move_id":39},{"level":7,"move_id":287},{"level":10,"move_id":135},{"level":13,"move_id":3},{"level":18,"move_id":107},{"level":23,"move_id":47},{"level":28,"move_id":121},{"level":33,"move_id":111},{"level":40,"move_id":113},{"level":47,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[46,0],"address":3303548,"base_stats":[90,85,75,115,115,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":243,"learnset":{"address":3314190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":84},{"level":21,"move_id":46},{"level":31,"move_id":98},{"level":41,"move_id":209},{"level":51,"move_id":115},{"level":61,"move_id":242},{"level":71,"move_id":87},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E138DD34638","types":[13,13]},{"abilities":[46,0],"address":3303576,"base_stats":[115,115,85,100,90,75],"catch_rate":3,"evolutions":[],"friendship":35,"id":244,"learnset":{"address":3314216,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":52},{"level":21,"move_id":46},{"level":31,"move_id":83},{"level":41,"move_id":23},{"level":51,"move_id":53},{"level":61,"move_id":207},{"level":71,"move_id":126},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E358C734638","types":[10,10]},{"abilities":[46,0],"address":3303604,"base_stats":[100,75,115,85,90,115],"catch_rate":3,"evolutions":[],"friendship":35,"id":245,"learnset":{"address":3314242,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":61},{"level":21,"move_id":240},{"level":31,"move_id":16},{"level":41,"move_id":62},{"level":51,"move_id":54},{"level":61,"move_id":243},{"level":71,"move_id":56},{"level":81,"move_id":347}]},"tmhm_learnset":"03940E118C53767C","types":[11,11]},{"abilities":[62,0],"address":3303632,"base_stats":[50,64,50,41,45,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":247}],"friendship":35,"id":246,"learnset":{"address":3314268,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":36,"move_id":184},{"level":43,"move_id":242},{"level":50,"move_id":89},{"level":57,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[61,0],"address":3303660,"base_stats":[70,84,70,51,65,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":248}],"friendship":35,"id":247,"learnset":{"address":3314294,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":56,"move_id":89},{"level":65,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[45,0],"address":3303688,"base_stats":[100,134,110,61,95,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":248,"learnset":{"address":3314320,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":61,"move_id":89},{"level":75,"move_id":63}]},"tmhm_learnset":"00B41FF6CFD37E37","types":[5,17]},{"abilities":[46,0],"address":3303716,"base_stats":[106,90,130,110,90,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":249,"learnset":{"address":3314346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":56},{"level":55,"move_id":240},{"level":66,"move_id":129},{"level":77,"move_id":177},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"03B8CE93B7DFF67C","types":[14,2]},{"abilities":[46,0],"address":3303744,"base_stats":[106,130,90,90,110,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":250,"learnset":{"address":3314374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":126},{"level":55,"move_id":241},{"level":66,"move_id":129},{"level":77,"move_id":221},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"00EA4EB7B7BFC638","types":[10,2]},{"abilities":[30,0],"address":3303772,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":251,"learnset":{"address":3314402,"moves":[{"level":1,"move_id":73},{"level":1,"move_id":93},{"level":1,"move_id":105},{"level":1,"move_id":215},{"level":10,"move_id":219},{"level":20,"move_id":246},{"level":30,"move_id":248},{"level":40,"move_id":226},{"level":50,"move_id":195}]},"tmhm_learnset":"00448E93B43FC62C","types":[14,12]},{"abilities":[0,0],"address":3303800,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":252,"learnset":{"address":3314422,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303828,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":253,"learnset":{"address":3314432,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303856,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":254,"learnset":{"address":3314442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303884,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":255,"learnset":{"address":3314452,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303912,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":256,"learnset":{"address":3314462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303940,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":257,"learnset":{"address":3314472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303968,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":258,"learnset":{"address":3314482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303996,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":259,"learnset":{"address":3314492,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304024,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":260,"learnset":{"address":3314502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304052,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":261,"learnset":{"address":3314512,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304080,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":262,"learnset":{"address":3314522,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304108,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":263,"learnset":{"address":3314532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304136,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":264,"learnset":{"address":3314542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304164,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":265,"learnset":{"address":3314552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304192,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":266,"learnset":{"address":3314562,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304220,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":267,"learnset":{"address":3314572,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304248,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":268,"learnset":{"address":3314582,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304276,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":269,"learnset":{"address":3314592,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304304,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":270,"learnset":{"address":3314602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304332,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":271,"learnset":{"address":3314612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304360,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":272,"learnset":{"address":3314622,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304388,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":273,"learnset":{"address":3314632,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304416,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":274,"learnset":{"address":3314642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304444,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":275,"learnset":{"address":3314652,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304472,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":276,"learnset":{"address":3314662,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3304500,"base_stats":[40,45,35,70,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":278}],"friendship":70,"id":277,"learnset":{"address":3314672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":228},{"level":21,"move_id":103},{"level":26,"move_id":72},{"level":31,"move_id":97},{"level":36,"move_id":21},{"level":41,"move_id":197},{"level":46,"move_id":202}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304528,"base_stats":[50,65,45,95,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":279}],"friendship":70,"id":278,"learnset":{"address":3314700,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":41,"move_id":21},{"level":47,"move_id":197},{"level":53,"move_id":206}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304556,"base_stats":[70,85,65,120,105,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":279,"learnset":{"address":3314730,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":43,"move_id":21},{"level":51,"move_id":197},{"level":59,"move_id":206}]},"tmhm_learnset":"00E41EC0CE7D4733","types":[12,12]},{"abilities":[66,0],"address":3304584,"base_stats":[45,60,40,45,70,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":281}],"friendship":70,"id":280,"learnset":{"address":3314760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":116},{"level":10,"move_id":52},{"level":16,"move_id":64},{"level":19,"move_id":28},{"level":25,"move_id":83},{"level":28,"move_id":98},{"level":34,"move_id":163},{"level":37,"move_id":119},{"level":43,"move_id":53}]},"tmhm_learnset":"00A61EE48C110620","types":[10,10]},{"abilities":[66,0],"address":3304612,"base_stats":[60,85,60,55,85,60],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":282}],"friendship":70,"id":281,"learnset":{"address":3314788,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":39,"move_id":163},{"level":43,"move_id":119},{"level":50,"move_id":327}]},"tmhm_learnset":"00A61EE4CC1106A1","types":[10,1]},{"abilities":[66,0],"address":3304640,"base_stats":[80,120,70,80,110,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":282,"learnset":{"address":3314818,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":36,"move_id":299},{"level":42,"move_id":163},{"level":49,"move_id":119},{"level":59,"move_id":327}]},"tmhm_learnset":"00A61EE4CE1146B1","types":[10,1]},{"abilities":[67,0],"address":3304668,"base_stats":[50,70,50,40,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":284}],"friendship":70,"id":283,"learnset":{"address":3314852,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":19,"move_id":193},{"level":24,"move_id":300},{"level":28,"move_id":36},{"level":33,"move_id":250},{"level":37,"move_id":182},{"level":42,"move_id":56},{"level":46,"move_id":283}]},"tmhm_learnset":"03B01E408C533264","types":[11,11]},{"abilities":[67,0],"address":3304696,"base_stats":[70,85,70,50,60,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":285}],"friendship":70,"id":284,"learnset":{"address":3314882,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":37,"move_id":330},{"level":42,"move_id":182},{"level":46,"move_id":89},{"level":53,"move_id":283}]},"tmhm_learnset":"03B01E408E533264","types":[11,4]},{"abilities":[67,0],"address":3304724,"base_stats":[100,110,90,60,85,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":285,"learnset":{"address":3314914,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":39,"move_id":330},{"level":46,"move_id":182},{"level":52,"move_id":89},{"level":61,"move_id":283}]},"tmhm_learnset":"03B01E40CE537275","types":[11,4]},{"abilities":[50,0],"address":3304752,"base_stats":[35,55,35,35,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":287}],"friendship":70,"id":286,"learnset":{"address":3314946,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":21,"move_id":46},{"level":25,"move_id":207},{"level":29,"move_id":184},{"level":33,"move_id":36},{"level":37,"move_id":269},{"level":41,"move_id":242},{"level":45,"move_id":168}]},"tmhm_learnset":"00813F00AC530E30","types":[17,17]},{"abilities":[22,0],"address":3304780,"base_stats":[70,90,70,70,60,60],"catch_rate":127,"evolutions":[],"friendship":70,"id":287,"learnset":{"address":3314978,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":336},{"level":1,"move_id":28},{"level":1,"move_id":44},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":22,"move_id":46},{"level":27,"move_id":207},{"level":32,"move_id":184},{"level":37,"move_id":36},{"level":42,"move_id":269},{"level":47,"move_id":242},{"level":52,"move_id":168}]},"tmhm_learnset":"00A13F00AC534E30","types":[17,17]},{"abilities":[53,0],"address":3304808,"base_stats":[38,30,41,60,30,41],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":289}],"friendship":70,"id":288,"learnset":{"address":3315010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":21,"move_id":300},{"level":25,"move_id":42},{"level":29,"move_id":343},{"level":33,"move_id":175},{"level":37,"move_id":156},{"level":41,"move_id":187}]},"tmhm_learnset":"00943E02ADD33624","types":[0,0]},{"abilities":[53,0],"address":3304836,"base_stats":[78,70,61,100,50,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":289,"learnset":{"address":3315040,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":23,"move_id":300},{"level":29,"move_id":154},{"level":35,"move_id":343},{"level":41,"move_id":163},{"level":47,"move_id":156},{"level":53,"move_id":187}]},"tmhm_learnset":"00B43E02ADD37634","types":[0,0]},{"abilities":[19,0],"address":3304864,"base_stats":[45,45,35,20,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_SILCOON","param":7,"species":291},{"method":"LEVEL_CASCOON","param":7,"species":293}],"friendship":70,"id":290,"learnset":{"address":3315070,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81},{"level":5,"move_id":40}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3304892,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":292}],"friendship":70,"id":291,"learnset":{"address":3315082,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[68,0],"address":3304920,"base_stats":[60,70,50,65,90,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":292,"learnset":{"address":3315094,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":10,"move_id":71},{"level":13,"move_id":16},{"level":17,"move_id":78},{"level":20,"move_id":234},{"level":24,"move_id":72},{"level":27,"move_id":18},{"level":31,"move_id":213},{"level":34,"move_id":318},{"level":38,"move_id":202}]},"tmhm_learnset":"00403E80B43D4620","types":[6,2]},{"abilities":[61,0],"address":3304948,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":294}],"friendship":70,"id":293,"learnset":{"address":3315122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[19,0],"address":3304976,"base_stats":[60,50,70,65,50,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":294,"learnset":{"address":3315134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":16},{"level":17,"move_id":182},{"level":20,"move_id":236},{"level":24,"move_id":60},{"level":27,"move_id":18},{"level":31,"move_id":113},{"level":34,"move_id":318},{"level":38,"move_id":92}]},"tmhm_learnset":"00403E88B435C620","types":[6,3]},{"abilities":[33,44],"address":3305004,"base_stats":[40,30,30,30,40,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":296}],"friendship":70,"id":295,"learnset":{"address":3315162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":21,"move_id":54},{"level":31,"move_id":240},{"level":43,"move_id":72}]},"tmhm_learnset":"00503E0084373764","types":[11,12]},{"abilities":[33,44],"address":3305032,"base_stats":[60,50,50,50,60,70],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":297}],"friendship":70,"id":296,"learnset":{"address":3315184,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":154},{"level":31,"move_id":346},{"level":37,"move_id":168},{"level":43,"move_id":253},{"level":49,"move_id":56}]},"tmhm_learnset":"03F03E00C4373764","types":[11,12]},{"abilities":[33,44],"address":3305060,"base_stats":[80,70,70,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":297,"learnset":{"address":3315212,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":45},{"level":1,"move_id":71},{"level":1,"move_id":267}]},"tmhm_learnset":"03F03E00C4377765","types":[11,12]},{"abilities":[34,48],"address":3305088,"base_stats":[40,40,50,30,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":299}],"friendship":70,"id":298,"learnset":{"address":3315222,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":21,"move_id":235},{"level":31,"move_id":241},{"level":43,"move_id":153}]},"tmhm_learnset":"00C01E00AC350720","types":[12,12]},{"abilities":[34,48],"address":3305116,"base_stats":[70,70,40,60,60,40],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":300}],"friendship":70,"id":299,"learnset":{"address":3315244,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":259},{"level":31,"move_id":185},{"level":37,"move_id":13},{"level":43,"move_id":207},{"level":49,"move_id":326}]},"tmhm_learnset":"00E43F40EC354720","types":[12,17]},{"abilities":[34,48],"address":3305144,"base_stats":[90,100,60,80,90,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":300,"learnset":{"address":3315272,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":1,"move_id":74},{"level":1,"move_id":267}]},"tmhm_learnset":"00E43FC0EC354720","types":[12,17]},{"abilities":[14,0],"address":3305172,"base_stats":[31,45,90,40,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_NINJASK","param":20,"species":302},{"method":"LEVEL_SHEDINJA","param":20,"species":303}],"friendship":70,"id":301,"learnset":{"address":3315282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":206},{"level":31,"move_id":189},{"level":38,"move_id":232},{"level":45,"move_id":91}]},"tmhm_learnset":"00440E90AC350620","types":[6,4]},{"abilities":[3,0],"address":3305200,"base_stats":[61,90,45,160,50,50],"catch_rate":120,"evolutions":[],"friendship":70,"id":302,"learnset":{"address":3315308,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":141},{"level":1,"move_id":28},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":20,"move_id":104},{"level":20,"move_id":210},{"level":20,"move_id":103},{"level":25,"move_id":14},{"level":31,"move_id":163},{"level":38,"move_id":97},{"level":45,"move_id":226}]},"tmhm_learnset":"00443E90AC354620","types":[6,2]},{"abilities":[25,0],"address":3305228,"base_stats":[1,90,45,40,30,30],"catch_rate":45,"evolutions":[],"friendship":70,"id":303,"learnset":{"address":3315340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":180},{"level":31,"move_id":109},{"level":38,"move_id":247},{"level":45,"move_id":288}]},"tmhm_learnset":"00442E90AC354620","types":[6,7]},{"abilities":[62,0],"address":3305256,"base_stats":[40,55,30,85,30,30],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":305}],"friendship":70,"id":304,"learnset":{"address":3315366,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":26,"move_id":283},{"level":34,"move_id":332},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[62,0],"address":3305284,"base_stats":[60,85,60,125,50,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":305,"learnset":{"address":3315390,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":98},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":28,"move_id":283},{"level":38,"move_id":332},{"level":49,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[27,0],"address":3305312,"base_stats":[60,40,60,35,40,60],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":23,"species":307}],"friendship":70,"id":306,"learnset":{"address":3315414,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":28,"move_id":77},{"level":36,"move_id":74},{"level":45,"move_id":202},{"level":54,"move_id":147}]},"tmhm_learnset":"00411E08843D0720","types":[12,12]},{"abilities":[27,0],"address":3305340,"base_stats":[60,130,80,70,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":307,"learnset":{"address":3315442,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":33},{"level":1,"move_id":78},{"level":1,"move_id":73},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":23,"move_id":183},{"level":28,"move_id":68},{"level":36,"move_id":327},{"level":45,"move_id":170},{"level":54,"move_id":223}]},"tmhm_learnset":"00E51E08C47D47A1","types":[12,1]},{"abilities":[20,0],"address":3305368,"base_stats":[60,60,60,60,60,60],"catch_rate":255,"evolutions":[],"friendship":70,"id":308,"learnset":{"address":3315472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":253},{"level":12,"move_id":185},{"level":16,"move_id":60},{"level":23,"move_id":95},{"level":27,"move_id":146},{"level":34,"move_id":298},{"level":38,"move_id":244},{"level":45,"move_id":38},{"level":49,"move_id":175},{"level":56,"move_id":37}]},"tmhm_learnset":"00E1BE42FC1B062D","types":[0,0]},{"abilities":[51,0],"address":3305396,"base_stats":[40,30,30,85,55,30],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":310}],"friendship":70,"id":309,"learnset":{"address":3315502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":31,"move_id":98},{"level":43,"move_id":228},{"level":55,"move_id":97}]},"tmhm_learnset":"00087E8284133264","types":[11,2]},{"abilities":[51,0],"address":3305424,"base_stats":[60,50,100,65,85,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":310,"learnset":{"address":3315524,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":346},{"level":1,"move_id":17},{"level":3,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":25,"move_id":182},{"level":33,"move_id":254},{"level":33,"move_id":256},{"level":47,"move_id":255},{"level":61,"move_id":56}]},"tmhm_learnset":"00187E8284137264","types":[11,2]},{"abilities":[33,0],"address":3305452,"base_stats":[40,30,32,65,50,52],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":312}],"friendship":70,"id":311,"learnset":{"address":3315552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":25,"move_id":61},{"level":31,"move_id":97},{"level":37,"move_id":54},{"level":37,"move_id":114}]},"tmhm_learnset":"00403E00A4373624","types":[6,11]},{"abilities":[22,0],"address":3305480,"base_stats":[70,60,62,60,80,82],"catch_rate":75,"evolutions":[],"friendship":70,"id":312,"learnset":{"address":3315576,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":98},{"level":1,"move_id":230},{"level":1,"move_id":346},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":26,"move_id":16},{"level":33,"move_id":184},{"level":40,"move_id":78},{"level":47,"move_id":318},{"level":53,"move_id":18}]},"tmhm_learnset":"00403E80A4377624","types":[6,2]},{"abilities":[41,12],"address":3305508,"base_stats":[130,70,35,60,70,35],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":40,"species":314}],"friendship":70,"id":313,"learnset":{"address":3315602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":150},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":41,"move_id":323},{"level":46,"move_id":133},{"level":50,"move_id":56}]},"tmhm_learnset":"03B01E4086133274","types":[11,11]},{"abilities":[41,12],"address":3305536,"base_stats":[170,90,45,60,90,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":314,"learnset":{"address":3315634,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":205},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":44,"move_id":323},{"level":52,"move_id":133},{"level":59,"move_id":56}]},"tmhm_learnset":"03B01E4086137274","types":[11,11]},{"abilities":[56,0],"address":3305564,"base_stats":[50,45,45,50,35,35],"catch_rate":255,"evolutions":[{"method":"ITEM","param":94,"species":316}],"friendship":70,"id":315,"learnset":{"address":3315666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":3,"move_id":39},{"level":7,"move_id":213},{"level":13,"move_id":47},{"level":15,"move_id":3},{"level":19,"move_id":274},{"level":25,"move_id":204},{"level":27,"move_id":185},{"level":31,"move_id":343},{"level":37,"move_id":215},{"level":39,"move_id":38}]},"tmhm_learnset":"00401E02ADFB362C","types":[0,0]},{"abilities":[56,0],"address":3305592,"base_stats":[70,65,65,70,55,55],"catch_rate":60,"evolutions":[],"friendship":70,"id":316,"learnset":{"address":3315696,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":213},{"level":1,"move_id":47},{"level":1,"move_id":3}]},"tmhm_learnset":"00E01E02ADFB762C","types":[0,0]},{"abilities":[16,0],"address":3305620,"base_stats":[60,90,70,40,60,120],"catch_rate":200,"evolutions":[],"friendship":70,"id":317,"learnset":{"address":3315706,"moves":[{"level":1,"move_id":168},{"level":1,"move_id":39},{"level":1,"move_id":310},{"level":1,"move_id":122},{"level":1,"move_id":10},{"level":4,"move_id":20},{"level":7,"move_id":185},{"level":12,"move_id":154},{"level":17,"move_id":60},{"level":24,"move_id":103},{"level":31,"move_id":163},{"level":40,"move_id":164},{"level":49,"move_id":246}]},"tmhm_learnset":"00E5BEE6EDF33625","types":[0,0]},{"abilities":[26,0],"address":3305648,"base_stats":[40,40,55,55,40,70],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":36,"species":319}],"friendship":70,"id":318,"learnset":{"address":3315734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":37,"move_id":322},{"level":45,"move_id":153}]},"tmhm_learnset":"00408E51BE339620","types":[4,14]},{"abilities":[26,0],"address":3305676,"base_stats":[60,70,105,75,70,120],"catch_rate":90,"evolutions":[],"friendship":70,"id":319,"learnset":{"address":3315764,"moves":[{"level":1,"move_id":100},{"level":1,"move_id":93},{"level":1,"move_id":106},{"level":1,"move_id":229},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":36,"move_id":63},{"level":42,"move_id":322},{"level":55,"move_id":153}]},"tmhm_learnset":"00E08E51BE33D620","types":[4,14]},{"abilities":[5,42],"address":3305704,"base_stats":[30,45,135,30,45,90],"catch_rate":255,"evolutions":[],"friendship":70,"id":320,"learnset":{"address":3315796,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":106},{"level":13,"move_id":88},{"level":16,"move_id":335},{"level":22,"move_id":86},{"level":28,"move_id":157},{"level":31,"move_id":201},{"level":37,"move_id":156},{"level":43,"move_id":192},{"level":46,"move_id":199}]},"tmhm_learnset":"00A01F5287910E20","types":[5,5]},{"abilities":[73,0],"address":3305732,"base_stats":[70,85,140,20,85,70],"catch_rate":90,"evolutions":[],"friendship":70,"id":321,"learnset":{"address":3315824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":4,"move_id":123},{"level":7,"move_id":174},{"level":14,"move_id":108},{"level":17,"move_id":83},{"level":20,"move_id":34},{"level":27,"move_id":182},{"level":30,"move_id":53},{"level":33,"move_id":334},{"level":40,"move_id":133},{"level":43,"move_id":175},{"level":46,"move_id":257}]},"tmhm_learnset":"00A21E2C84510620","types":[10,10]},{"abilities":[51,0],"address":3305760,"base_stats":[50,75,75,50,65,65],"catch_rate":45,"evolutions":[],"friendship":35,"id":322,"learnset":{"address":3315856,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":10},{"level":5,"move_id":193},{"level":9,"move_id":101},{"level":13,"move_id":310},{"level":17,"move_id":154},{"level":21,"move_id":252},{"level":25,"move_id":197},{"level":29,"move_id":185},{"level":33,"move_id":282},{"level":37,"move_id":109},{"level":41,"move_id":247},{"level":45,"move_id":212}]},"tmhm_learnset":"00C53FC2FC130E2D","types":[17,7]},{"abilities":[12,0],"address":3305788,"base_stats":[50,48,43,60,46,41],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":324}],"friendship":70,"id":323,"learnset":{"address":3315888,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":189},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":31,"move_id":89},{"level":36,"move_id":248},{"level":41,"move_id":90}]},"tmhm_learnset":"03101E5086133264","types":[11,4]},{"abilities":[12,0],"address":3305816,"base_stats":[110,78,73,60,76,71],"catch_rate":75,"evolutions":[],"friendship":70,"id":324,"learnset":{"address":3315918,"moves":[{"level":1,"move_id":321},{"level":1,"move_id":189},{"level":1,"move_id":300},{"level":1,"move_id":346},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":36,"move_id":89},{"level":46,"move_id":248},{"level":56,"move_id":90}]},"tmhm_learnset":"03B01E5086137264","types":[11,4]},{"abilities":[33,0],"address":3305844,"base_stats":[43,30,55,97,40,65],"catch_rate":225,"evolutions":[],"friendship":70,"id":325,"learnset":{"address":3315948,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":204},{"level":12,"move_id":55},{"level":16,"move_id":97},{"level":24,"move_id":36},{"level":28,"move_id":213},{"level":36,"move_id":186},{"level":40,"move_id":175},{"level":48,"move_id":219}]},"tmhm_learnset":"03101E00841B3264","types":[11,11]},{"abilities":[52,75],"address":3305872,"base_stats":[43,80,65,35,50,35],"catch_rate":205,"evolutions":[{"method":"LEVEL","param":30,"species":327}],"friendship":70,"id":326,"learnset":{"address":3315974,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":32,"move_id":269},{"level":35,"move_id":152},{"level":38,"move_id":14},{"level":44,"move_id":12}]},"tmhm_learnset":"01B41EC8CC133A64","types":[11,11]},{"abilities":[52,75],"address":3305900,"base_stats":[63,120,85,55,90,55],"catch_rate":155,"evolutions":[],"friendship":70,"id":327,"learnset":{"address":3316004,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":106},{"level":1,"move_id":11},{"level":1,"move_id":43},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":34,"move_id":269},{"level":39,"move_id":152},{"level":44,"move_id":14},{"level":52,"move_id":12}]},"tmhm_learnset":"03B41EC8CC137A64","types":[11,17]},{"abilities":[33,0],"address":3305928,"base_stats":[20,15,20,80,10,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":30,"species":329}],"friendship":70,"id":328,"learnset":{"address":3316034,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[63,0],"address":3305956,"base_stats":[95,60,79,81,100,125],"catch_rate":60,"evolutions":[],"friendship":70,"id":329,"learnset":{"address":3316048,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":5,"move_id":35},{"level":10,"move_id":346},{"level":15,"move_id":287},{"level":20,"move_id":352},{"level":25,"move_id":239},{"level":30,"move_id":105},{"level":35,"move_id":240},{"level":40,"move_id":56},{"level":45,"move_id":213},{"level":50,"move_id":219}]},"tmhm_learnset":"03101E00845B7264","types":[11,11]},{"abilities":[24,0],"address":3305984,"base_stats":[45,90,20,65,65,20],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":30,"species":331}],"friendship":35,"id":330,"learnset":{"address":3316078,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":31,"move_id":36},{"level":37,"move_id":207},{"level":43,"move_id":97}]},"tmhm_learnset":"03103F0084133A64","types":[11,17]},{"abilities":[24,0],"address":3306012,"base_stats":[70,120,40,95,95,40],"catch_rate":60,"evolutions":[],"friendship":35,"id":331,"learnset":{"address":3316104,"moves":[{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":1,"move_id":99},{"level":1,"move_id":116},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":33,"move_id":163},{"level":38,"move_id":269},{"level":43,"move_id":207},{"level":48,"move_id":130},{"level":53,"move_id":97}]},"tmhm_learnset":"03B03F4086137A74","types":[11,17]},{"abilities":[52,71],"address":3306040,"base_stats":[45,100,45,10,45,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":333}],"friendship":70,"id":332,"learnset":{"address":3316134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":41,"move_id":91},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A01E508E354620","types":[4,4]},{"abilities":[26,26],"address":3306068,"base_stats":[50,70,50,70,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":45,"species":334}],"friendship":70,"id":333,"learnset":{"address":3316158,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A85E508E354620","types":[4,16]},{"abilities":[26,26],"address":3306096,"base_stats":[80,100,80,100,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":334,"learnset":{"address":3316184,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":53,"move_id":201},{"level":65,"move_id":63}]},"tmhm_learnset":"00A85E748E754622","types":[4,16]},{"abilities":[47,62],"address":3306124,"base_stats":[72,60,30,25,20,30],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":24,"species":336}],"friendship":70,"id":335,"learnset":{"address":3316210,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":28,"move_id":282},{"level":31,"move_id":265},{"level":37,"move_id":187},{"level":40,"move_id":203},{"level":46,"move_id":69},{"level":49,"move_id":179}]},"tmhm_learnset":"00B01E40CE1306A1","types":[1,1]},{"abilities":[47,62],"address":3306152,"base_stats":[144,120,60,50,40,60],"catch_rate":200,"evolutions":[],"friendship":70,"id":336,"learnset":{"address":3316242,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":1,"move_id":28},{"level":1,"move_id":292},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":29,"move_id":282},{"level":33,"move_id":265},{"level":40,"move_id":187},{"level":44,"move_id":203},{"level":51,"move_id":69},{"level":55,"move_id":179}]},"tmhm_learnset":"00B01E40CE1346A1","types":[1,1]},{"abilities":[9,31],"address":3306180,"base_stats":[40,45,40,65,65,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":26,"species":338}],"friendship":70,"id":337,"learnset":{"address":3316274,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":28,"move_id":46},{"level":33,"move_id":44},{"level":36,"move_id":87},{"level":41,"move_id":268}]},"tmhm_learnset":"00603E0285D30230","types":[13,13]},{"abilities":[9,31],"address":3306208,"base_stats":[70,75,60,105,105,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":338,"learnset":{"address":3316304,"moves":[{"level":1,"move_id":86},{"level":1,"move_id":43},{"level":1,"move_id":336},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":31,"move_id":46},{"level":39,"move_id":44},{"level":45,"move_id":87},{"level":53,"move_id":268}]},"tmhm_learnset":"00603E0285D34230","types":[13,13]},{"abilities":[12,0],"address":3306236,"base_stats":[60,60,40,35,65,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":33,"species":340}],"friendship":70,"id":339,"learnset":{"address":3316334,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":35,"move_id":89},{"level":41,"move_id":53},{"level":49,"move_id":38}]},"tmhm_learnset":"00A21E748E110620","types":[10,4]},{"abilities":[40,0],"address":3306264,"base_stats":[70,100,70,40,105,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":340,"learnset":{"address":3316360,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":1,"move_id":52},{"level":1,"move_id":222},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":33,"move_id":157},{"level":37,"move_id":89},{"level":45,"move_id":284},{"level":55,"move_id":90}]},"tmhm_learnset":"00A21E748E114630","types":[10,4]},{"abilities":[47,0],"address":3306292,"base_stats":[70,40,50,25,55,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":342}],"friendship":70,"id":341,"learnset":{"address":3316388,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":59},{"level":49,"move_id":329}]},"tmhm_learnset":"03B01E4086533264","types":[15,11]},{"abilities":[47,0],"address":3306320,"base_stats":[90,60,70,45,75,70],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":44,"species":343}],"friendship":70,"id":342,"learnset":{"address":3316416,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":47,"move_id":59},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E4086533274","types":[15,11]},{"abilities":[47,0],"address":3306348,"base_stats":[110,80,90,65,95,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":343,"learnset":{"address":3316444,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":50,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"03B01E4086537274","types":[15,11]},{"abilities":[8,0],"address":3306376,"base_stats":[50,85,40,35,85,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":32,"species":345}],"friendship":35,"id":344,"learnset":{"address":3316472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":33,"move_id":191},{"level":37,"move_id":302},{"level":41,"move_id":178},{"level":45,"move_id":201}]},"tmhm_learnset":"00441E1084350721","types":[12,12]},{"abilities":[8,0],"address":3306404,"base_stats":[70,115,60,55,115,60],"catch_rate":60,"evolutions":[],"friendship":35,"id":345,"learnset":{"address":3316504,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":74},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":35,"move_id":191},{"level":41,"move_id":302},{"level":47,"move_id":178},{"level":53,"move_id":201}]},"tmhm_learnset":"00641E1084354721","types":[12,17]},{"abilities":[39,0],"address":3306432,"base_stats":[50,50,50,50,50,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":42,"species":347}],"friendship":70,"id":346,"learnset":{"address":3316536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":37,"move_id":258},{"level":43,"move_id":59}]},"tmhm_learnset":"00401E00A41BB264","types":[15,15]},{"abilities":[39,0],"address":3306460,"base_stats":[80,80,80,80,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":347,"learnset":{"address":3316564,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":1,"move_id":104},{"level":1,"move_id":44},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":42,"move_id":258},{"level":53,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"00401F00A61BFA64","types":[15,15]},{"abilities":[26,0],"address":3306488,"base_stats":[70,55,65,70,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":348,"learnset":{"address":3316594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":95},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":94},{"level":43,"move_id":248},{"level":49,"move_id":153}]},"tmhm_learnset":"00408E51B61BD228","types":[5,14]},{"abilities":[26,0],"address":3306516,"base_stats":[70,95,85,70,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":349,"learnset":{"address":3316620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":83},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":157},{"level":43,"move_id":76},{"level":49,"move_id":153}]},"tmhm_learnset":"00428E75B639C628","types":[5,14]},{"abilities":[47,37],"address":3306544,"base_stats":[50,20,40,20,20,40],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":183}],"friendship":70,"id":350,"learnset":{"address":3316646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":150},{"level":3,"move_id":204},{"level":6,"move_id":39},{"level":10,"move_id":145},{"level":15,"move_id":21},{"level":21,"move_id":55}]},"tmhm_learnset":"01101E0084533264","types":[0,0]},{"abilities":[47,20],"address":3306572,"base_stats":[60,25,35,60,70,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":352}],"friendship":70,"id":351,"learnset":{"address":3316666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":1,"move_id":150},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":34,"move_id":94},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":340}]},"tmhm_learnset":"0041BF03B4538E28","types":[14,14]},{"abilities":[47,20],"address":3306600,"base_stats":[80,45,65,80,90,110],"catch_rate":60,"evolutions":[],"friendship":70,"id":352,"learnset":{"address":3316696,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":149},{"level":1,"move_id":316},{"level":1,"move_id":60},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":37,"move_id":94},{"level":43,"move_id":156},{"level":43,"move_id":173},{"level":55,"move_id":340}]},"tmhm_learnset":"0041BF03B453CE29","types":[14,14]},{"abilities":[57,0],"address":3306628,"base_stats":[60,50,40,95,85,75],"catch_rate":200,"evolutions":[],"friendship":70,"id":353,"learnset":{"address":3316726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":313},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[58,0],"address":3306656,"base_stats":[60,40,50,95,75,85],"catch_rate":200,"evolutions":[],"friendship":70,"id":354,"learnset":{"address":3316756,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":204},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[52,22],"address":3306684,"base_stats":[50,85,85,50,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":355,"learnset":{"address":3316786,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":6,"move_id":313},{"level":11,"move_id":44},{"level":16,"move_id":230},{"level":21,"move_id":11},{"level":26,"move_id":185},{"level":31,"move_id":226},{"level":36,"move_id":242},{"level":41,"move_id":334},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255}]},"tmhm_learnset":"00A01F7CC4335E21","types":[8,8]},{"abilities":[74,0],"address":3306712,"base_stats":[30,40,55,60,40,55],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":37,"species":357}],"friendship":70,"id":356,"learnset":{"address":3316818,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":38,"move_id":244},{"level":42,"move_id":179},{"level":48,"move_id":105}]},"tmhm_learnset":"00E01E41F41386A9","types":[1,14]},{"abilities":[74,0],"address":3306740,"base_stats":[60,60,75,80,60,75],"catch_rate":90,"evolutions":[],"friendship":70,"id":357,"learnset":{"address":3316848,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":9},{"level":1,"move_id":8},{"level":1,"move_id":117},{"level":1,"move_id":96},{"level":1,"move_id":93},{"level":1,"move_id":197},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":40,"move_id":244},{"level":46,"move_id":179},{"level":54,"move_id":105}]},"tmhm_learnset":"00E01E41F413C6A9","types":[1,14]},{"abilities":[30,0],"address":3306768,"base_stats":[45,40,60,50,40,75],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":359}],"friendship":70,"id":358,"learnset":{"address":3316884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":38,"move_id":119},{"level":41,"move_id":287},{"level":48,"move_id":195}]},"tmhm_learnset":"00087E80843B1620","types":[0,2]},{"abilities":[30,0],"address":3306796,"base_stats":[75,70,90,80,70,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":359,"learnset":{"address":3316912,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":310},{"level":1,"move_id":47},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":35,"move_id":225},{"level":40,"move_id":349},{"level":45,"move_id":287},{"level":54,"move_id":195},{"level":59,"move_id":143}]},"tmhm_learnset":"00887EA4867B5632","types":[16,2]},{"abilities":[23,0],"address":3306824,"base_stats":[95,23,48,23,23,48],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":15,"species":202}],"friendship":70,"id":360,"learnset":{"address":3316944,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":150},{"level":1,"move_id":204},{"level":1,"move_id":227},{"level":15,"move_id":68},{"level":15,"move_id":243},{"level":15,"move_id":219},{"level":15,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[26,0],"address":3306852,"base_stats":[20,40,90,25,30,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":362}],"friendship":35,"id":361,"learnset":{"address":3316962,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":38,"move_id":261},{"level":45,"move_id":212},{"level":49,"move_id":248}]},"tmhm_learnset":"0041BF00B4133E28","types":[7,7]},{"abilities":[46,0],"address":3306880,"base_stats":[40,70,130,25,60,130],"catch_rate":90,"evolutions":[],"friendship":35,"id":362,"learnset":{"address":3316990,"moves":[{"level":1,"move_id":20},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":1,"move_id":50},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":37,"move_id":325},{"level":41,"move_id":261},{"level":51,"move_id":212},{"level":58,"move_id":248}]},"tmhm_learnset":"00E1BF40B6137E29","types":[7,7]},{"abilities":[30,38],"address":3306908,"base_stats":[50,60,45,65,100,80],"catch_rate":150,"evolutions":[],"friendship":70,"id":363,"learnset":{"address":3317020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":5,"move_id":74},{"level":9,"move_id":40},{"level":13,"move_id":78},{"level":17,"move_id":72},{"level":21,"move_id":73},{"level":25,"move_id":345},{"level":29,"move_id":320},{"level":33,"move_id":202},{"level":37,"move_id":230},{"level":41,"move_id":275},{"level":45,"move_id":92},{"level":49,"move_id":80},{"level":53,"move_id":312},{"level":57,"move_id":235}]},"tmhm_learnset":"00441E08A4350720","types":[12,3]},{"abilities":[54,0],"address":3306936,"base_stats":[60,60,60,30,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":365}],"friendship":70,"id":364,"learnset":{"address":3317058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E5B336A5","types":[0,0]},{"abilities":[72,0],"address":3306964,"base_stats":[80,80,80,90,55,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":366}],"friendship":70,"id":365,"learnset":{"address":3317082,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":116},{"level":1,"move_id":227},{"level":1,"move_id":253},{"level":7,"move_id":227},{"level":13,"move_id":253},{"level":19,"move_id":154},{"level":25,"move_id":203},{"level":31,"move_id":163},{"level":37,"move_id":68},{"level":43,"move_id":264},{"level":49,"move_id":179}]},"tmhm_learnset":"00A41EA6E7B33EB5","types":[0,0]},{"abilities":[54,0],"address":3306992,"base_stats":[150,160,100,100,95,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":366,"learnset":{"address":3317108,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":1,"move_id":227},{"level":1,"move_id":303},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":36,"move_id":207},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E7B37EB5","types":[0,0]},{"abilities":[64,60],"address":3307020,"base_stats":[70,43,53,40,43,53],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":26,"species":368}],"friendship":70,"id":367,"learnset":{"address":3317134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":28,"move_id":92},{"level":34,"move_id":254},{"level":34,"move_id":255},{"level":34,"move_id":256},{"level":39,"move_id":188}]},"tmhm_learnset":"00A11E0AA4371724","types":[3,3]},{"abilities":[64,60],"address":3307048,"base_stats":[100,73,83,55,73,83],"catch_rate":75,"evolutions":[],"friendship":70,"id":368,"learnset":{"address":3317164,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":281},{"level":1,"move_id":139},{"level":1,"move_id":124},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":26,"move_id":34},{"level":31,"move_id":92},{"level":40,"move_id":254},{"level":40,"move_id":255},{"level":40,"move_id":256},{"level":48,"move_id":188}]},"tmhm_learnset":"00A11E0AA4375724","types":[3,3]},{"abilities":[34,0],"address":3307076,"base_stats":[99,68,83,51,72,87],"catch_rate":200,"evolutions":[],"friendship":70,"id":369,"learnset":{"address":3317196,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":16},{"level":7,"move_id":74},{"level":11,"move_id":75},{"level":17,"move_id":23},{"level":21,"move_id":230},{"level":27,"move_id":18},{"level":31,"move_id":345},{"level":37,"move_id":34},{"level":41,"move_id":76},{"level":47,"move_id":235}]},"tmhm_learnset":"00EC5E80863D4730","types":[12,2]},{"abilities":[43,0],"address":3307104,"base_stats":[64,51,23,28,51,23],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":20,"species":371}],"friendship":70,"id":370,"learnset":{"address":3317224,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":21,"move_id":48},{"level":25,"move_id":23},{"level":31,"move_id":103},{"level":35,"move_id":46},{"level":41,"move_id":156},{"level":41,"move_id":214},{"level":45,"move_id":304}]},"tmhm_learnset":"00001E26A4333634","types":[0,0]},{"abilities":[43,0],"address":3307132,"base_stats":[84,71,43,48,71,43],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":40,"species":372}],"friendship":70,"id":371,"learnset":{"address":3317254,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":43,"move_id":46},{"level":51,"move_id":156},{"level":51,"move_id":214},{"level":57,"move_id":304}]},"tmhm_learnset":"00A21F26E6333E34","types":[0,0]},{"abilities":[43,0],"address":3307160,"base_stats":[104,91,63,68,91,63],"catch_rate":45,"evolutions":[],"friendship":70,"id":372,"learnset":{"address":3317284,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":40,"move_id":63},{"level":45,"move_id":46},{"level":55,"move_id":156},{"level":55,"move_id":214},{"level":63,"move_id":304}]},"tmhm_learnset":"00A21F26E6337E34","types":[0,0]},{"abilities":[75,0],"address":3307188,"base_stats":[35,64,85,32,74,55],"catch_rate":255,"evolutions":[{"method":"ITEM","param":192,"species":374},{"method":"ITEM","param":193,"species":375}],"friendship":70,"id":373,"learnset":{"address":3317316,"moves":[{"level":1,"move_id":128},{"level":1,"move_id":55},{"level":1,"move_id":250},{"level":1,"move_id":334}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,0],"address":3307216,"base_stats":[55,104,105,52,94,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":374,"learnset":{"address":3317326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":44},{"level":15,"move_id":103},{"level":22,"move_id":352},{"level":29,"move_id":184},{"level":36,"move_id":242},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03111E4084137264","types":[11,11]},{"abilities":[33,0],"address":3307244,"base_stats":[55,84,105,52,114,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":375,"learnset":{"address":3317350,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":93},{"level":15,"move_id":97},{"level":22,"move_id":352},{"level":29,"move_id":133},{"level":36,"move_id":94},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03101E00B41B7264","types":[11,11]},{"abilities":[46,0],"address":3307272,"base_stats":[65,130,60,75,75,60],"catch_rate":30,"evolutions":[],"friendship":35,"id":376,"learnset":{"address":3317374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":5,"move_id":43},{"level":9,"move_id":269},{"level":13,"move_id":98},{"level":17,"move_id":13},{"level":21,"move_id":44},{"level":26,"move_id":14},{"level":31,"move_id":104},{"level":36,"move_id":163},{"level":41,"move_id":248},{"level":46,"move_id":195}]},"tmhm_learnset":"00E53FB6A5D37E6C","types":[17,17]},{"abilities":[15,0],"address":3307300,"base_stats":[44,75,35,45,63,33],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":37,"species":378}],"friendship":35,"id":377,"learnset":{"address":3317404,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":282},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":37,"move_id":185},{"level":44,"move_id":247},{"level":49,"move_id":289},{"level":56,"move_id":288}]},"tmhm_learnset":"0041BF02B5930E28","types":[7,7]},{"abilities":[15,0],"address":3307328,"base_stats":[64,115,65,65,83,63],"catch_rate":45,"evolutions":[],"friendship":35,"id":378,"learnset":{"address":3317432,"moves":[{"level":1,"move_id":282},{"level":1,"move_id":103},{"level":1,"move_id":101},{"level":1,"move_id":174},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":39,"move_id":185},{"level":48,"move_id":247},{"level":55,"move_id":289},{"level":64,"move_id":288}]},"tmhm_learnset":"0041BF02B5934E28","types":[7,7]},{"abilities":[61,0],"address":3307356,"base_stats":[73,100,60,65,100,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":379,"learnset":{"address":3317460,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":7,"move_id":122},{"level":10,"move_id":44},{"level":16,"move_id":342},{"level":19,"move_id":103},{"level":25,"move_id":137},{"level":28,"move_id":242},{"level":34,"move_id":305},{"level":37,"move_id":207},{"level":43,"move_id":114}]},"tmhm_learnset":"00A13E0C8E570E20","types":[3,3]},{"abilities":[17,0],"address":3307384,"base_stats":[73,115,60,90,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":380,"learnset":{"address":3317488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":43},{"level":7,"move_id":98},{"level":10,"move_id":14},{"level":13,"move_id":210},{"level":19,"move_id":163},{"level":25,"move_id":228},{"level":31,"move_id":306},{"level":37,"move_id":269},{"level":46,"move_id":197},{"level":55,"move_id":206}]},"tmhm_learnset":"00A03EA6EDF73E35","types":[0,0]},{"abilities":[33,69],"address":3307412,"base_stats":[100,90,130,55,45,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":381,"learnset":{"address":3317518,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":8,"move_id":55},{"level":15,"move_id":317},{"level":22,"move_id":281},{"level":29,"move_id":36},{"level":36,"move_id":300},{"level":43,"move_id":246},{"level":50,"move_id":156},{"level":57,"move_id":38},{"level":64,"move_id":56}]},"tmhm_learnset":"03901E50861B726C","types":[11,5]},{"abilities":[5,69],"address":3307440,"base_stats":[50,70,100,30,40,40],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":32,"species":383}],"friendship":35,"id":382,"learnset":{"address":3317546,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":34,"move_id":182},{"level":39,"move_id":319},{"level":44,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307468,"base_stats":[60,90,140,40,50,50],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":42,"species":384}],"friendship":35,"id":383,"learnset":{"address":3317578,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":45,"move_id":319},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307496,"base_stats":[70,110,180,50,60,60],"catch_rate":45,"evolutions":[],"friendship":35,"id":384,"learnset":{"address":3317610,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":50,"move_id":319},{"level":63,"move_id":38}]},"tmhm_learnset":"00B41EF6CFF37E37","types":[8,5]},{"abilities":[59,0],"address":3307524,"base_stats":[70,70,70,70,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":385,"learnset":{"address":3317642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":10,"move_id":55},{"level":10,"move_id":52},{"level":10,"move_id":181},{"level":20,"move_id":240},{"level":20,"move_id":241},{"level":20,"move_id":258},{"level":30,"move_id":311}]},"tmhm_learnset":"00403E36A5B33664","types":[0,0]},{"abilities":[35,68],"address":3307552,"base_stats":[65,73,55,85,47,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":386,"learnset":{"address":3317666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":109},{"level":9,"move_id":104},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":294},{"level":25,"move_id":324},{"level":29,"move_id":182},{"level":33,"move_id":270},{"level":37,"move_id":38}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[12,0],"address":3307580,"base_stats":[65,47,55,85,73,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":387,"learnset":{"address":3317694,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":230},{"level":9,"move_id":204},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":273},{"level":25,"move_id":227},{"level":29,"move_id":260},{"level":33,"move_id":270},{"level":37,"move_id":343}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[21,0],"address":3307608,"base_stats":[66,41,77,23,61,87],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":389}],"friendship":70,"id":388,"learnset":{"address":3317722,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":43,"move_id":246},{"level":50,"move_id":254},{"level":50,"move_id":255},{"level":50,"move_id":256}]},"tmhm_learnset":"00001E1884350720","types":[5,12]},{"abilities":[21,0],"address":3307636,"base_stats":[86,81,97,43,81,107],"catch_rate":45,"evolutions":[],"friendship":70,"id":389,"learnset":{"address":3317750,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":132},{"level":1,"move_id":51},{"level":1,"move_id":275},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":48,"move_id":246},{"level":60,"move_id":254},{"level":60,"move_id":255},{"level":60,"move_id":256}]},"tmhm_learnset":"00A01E5886354720","types":[5,12]},{"abilities":[4,0],"address":3307664,"base_stats":[45,95,50,75,40,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":391}],"friendship":70,"id":390,"learnset":{"address":3317778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":43,"move_id":210},{"level":49,"move_id":163},{"level":55,"move_id":350}]},"tmhm_learnset":"00841ED0CC110624","types":[5,6]},{"abilities":[4,0],"address":3307692,"base_stats":[75,125,100,45,70,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":391,"learnset":{"address":3317806,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":300},{"level":1,"move_id":55},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":46,"move_id":210},{"level":55,"move_id":163},{"level":64,"move_id":350}]},"tmhm_learnset":"00A41ED0CE514624","types":[5,6]},{"abilities":[28,36],"address":3307720,"base_stats":[28,25,25,40,45,35],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":20,"species":393}],"friendship":35,"id":392,"learnset":{"address":3317834,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":45},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":31,"move_id":286},{"level":36,"move_id":248},{"level":41,"move_id":95},{"level":46,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307748,"base_stats":[38,35,35,50,65,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":394}],"friendship":35,"id":393,"learnset":{"address":3317862,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":40,"move_id":248},{"level":47,"move_id":95},{"level":54,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307776,"base_stats":[68,65,65,80,125,115],"catch_rate":45,"evolutions":[],"friendship":35,"id":394,"learnset":{"address":3317890,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":42,"move_id":248},{"level":51,"move_id":95},{"level":60,"move_id":138}]},"tmhm_learnset":"0041BF03B49BCE28","types":[14,14]},{"abilities":[69,0],"address":3307804,"base_stats":[45,75,60,50,40,30],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":396}],"friendship":35,"id":395,"learnset":{"address":3317918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":33,"move_id":225},{"level":37,"move_id":184},{"level":41,"move_id":242},{"level":49,"move_id":337},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[69,0],"address":3307832,"base_stats":[65,95,100,50,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":50,"species":397}],"friendship":35,"id":396,"learnset":{"address":3317948,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":56,"move_id":242},{"level":69,"move_id":337},{"level":78,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[22,0],"address":3307860,"base_stats":[95,135,80,100,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":397,"learnset":{"address":3317980,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":50,"move_id":19},{"level":61,"move_id":242},{"level":79,"move_id":337},{"level":93,"move_id":38}]},"tmhm_learnset":"00AC5EE4C6534632","types":[16,2]},{"abilities":[29,0],"address":3307888,"base_stats":[40,55,80,30,35,60],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":20,"species":399}],"friendship":35,"id":398,"learnset":{"address":3318014,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36}]},"tmhm_learnset":"0000000000000000","types":[8,14]},{"abilities":[29,0],"address":3307916,"base_stats":[60,75,100,50,55,80],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":45,"species":400}],"friendship":35,"id":399,"learnset":{"address":3318024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":50,"move_id":309},{"level":56,"move_id":97},{"level":62,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307944,"base_stats":[80,135,130,70,95,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":400,"learnset":{"address":3318052,"moves":[{"level":1,"move_id":36},{"level":1,"move_id":93},{"level":1,"move_id":232},{"level":1,"move_id":184},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":55,"move_id":309},{"level":66,"move_id":97},{"level":77,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307972,"base_stats":[80,100,200,50,50,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":401,"learnset":{"address":3318080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":153},{"level":9,"move_id":88},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E52CF994621","types":[5,5]},{"abilities":[29,0],"address":3308000,"base_stats":[80,50,100,50,100,200],"catch_rate":3,"evolutions":[],"friendship":35,"id":402,"learnset":{"address":3318106,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":196},{"level":1,"move_id":153},{"level":9,"move_id":196},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E02C79B7261","types":[15,15]},{"abilities":[29,0],"address":3308028,"base_stats":[80,75,150,50,75,150],"catch_rate":3,"evolutions":[],"friendship":35,"id":403,"learnset":{"address":3318132,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":232},{"level":1,"move_id":153},{"level":9,"move_id":232},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00ED2C79B4621","types":[8,8]},{"abilities":[2,0],"address":3308056,"base_stats":[100,100,90,90,150,140],"catch_rate":5,"evolutions":[],"friendship":0,"id":404,"learnset":{"address":3318160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":352},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":34},{"level":30,"move_id":347},{"level":35,"move_id":58},{"level":45,"move_id":56},{"level":50,"move_id":156},{"level":60,"move_id":329},{"level":65,"move_id":38},{"level":75,"move_id":323}]},"tmhm_learnset":"03B00E42C79B727C","types":[11,11]},{"abilities":[70,0],"address":3308084,"base_stats":[100,150,140,90,100,90],"catch_rate":5,"evolutions":[],"friendship":0,"id":405,"learnset":{"address":3318190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":341},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":163},{"level":30,"move_id":339},{"level":35,"move_id":89},{"level":45,"move_id":126},{"level":50,"move_id":156},{"level":60,"move_id":90},{"level":65,"move_id":76},{"level":75,"move_id":284}]},"tmhm_learnset":"00A60EF6CFF946B2","types":[4,4]},{"abilities":[77,0],"address":3308112,"base_stats":[105,150,90,95,150,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":406,"learnset":{"address":3318220,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":239},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":337},{"level":30,"move_id":349},{"level":35,"move_id":242},{"level":45,"move_id":19},{"level":50,"move_id":156},{"level":60,"move_id":245},{"level":65,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BA0EB6C7F376B6","types":[16,2]},{"abilities":[26,0],"address":3308140,"base_stats":[80,80,90,110,110,130],"catch_rate":3,"evolutions":[],"friendship":90,"id":407,"learnset":{"address":3318250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":273},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":346},{"level":30,"move_id":287},{"level":35,"move_id":296},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":204}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[26,0],"address":3308168,"base_stats":[80,90,80,110,130,110],"catch_rate":3,"evolutions":[],"friendship":90,"id":408,"learnset":{"address":3318280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":262},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":182},{"level":30,"move_id":287},{"level":35,"move_id":295},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":349}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[32,0],"address":3308196,"base_stats":[100,100,100,100,100,100],"catch_rate":3,"evolutions":[],"friendship":100,"id":409,"learnset":{"address":3318310,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":273},{"level":1,"move_id":93},{"level":5,"move_id":156},{"level":10,"move_id":129},{"level":15,"move_id":270},{"level":20,"move_id":94},{"level":25,"move_id":287},{"level":30,"move_id":156},{"level":35,"move_id":38},{"level":40,"move_id":248},{"level":45,"move_id":322},{"level":50,"move_id":353}]},"tmhm_learnset":"00408E93B59BC62C","types":[8,14]},{"abilities":[46,0],"address":3308224,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":410,"learnset":{"address":3318340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":35},{"level":5,"move_id":101},{"level":10,"move_id":104},{"level":15,"move_id":282},{"level":20,"move_id":228},{"level":25,"move_id":94},{"level":30,"move_id":129},{"level":35,"move_id":97},{"level":40,"move_id":105},{"level":45,"move_id":354},{"level":50,"move_id":245}]},"tmhm_learnset":"00E58FC3F5BBDE2D","types":[14,14]},{"abilities":[26,0],"address":3308252,"base_stats":[65,50,70,65,95,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":411,"learnset":{"address":3318370,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":6,"move_id":45},{"level":9,"move_id":310},{"level":14,"move_id":93},{"level":17,"move_id":36},{"level":22,"move_id":253},{"level":25,"move_id":281},{"level":30,"move_id":149},{"level":33,"move_id":38},{"level":38,"move_id":215},{"level":41,"move_id":219},{"level":46,"move_id":94}]},"tmhm_learnset":"00419F03B41B8E28","types":[14,14]}],"tmhm_moves":[264,337,352,347,46,92,258,339,331,237,241,269,58,59,63,113,182,240,202,219,218,76,231,85,87,89,216,91,94,247,280,104,115,351,53,188,201,126,317,332,259,263,290,156,213,168,211,285,289,315,15,19,57,70,148,249,127,291],"trainers":[{"address":3230072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[],"party_address":4160749568,"script_address":0},{"address":3230112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":74}],"party_address":3211124,"script_address":2304511},{"address":3230152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":286}],"party_address":3211132,"script_address":2321901},{"address":3230192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":330}],"party_address":3211140,"script_address":2323326},{"address":3230232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211156,"script_address":2323373},{"address":3230272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211164,"script_address":2324386},{"address":3230312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":286}],"party_address":3211172,"script_address":2326808},{"address":3230352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211180,"script_address":2326839},{"address":3230392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":41}],"party_address":3211188,"script_address":2328040},{"address":3230432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":315},{"level":26,"species":286},{"level":26,"species":288},{"level":26,"species":295},{"level":26,"species":298},{"level":26,"species":304}],"party_address":3211196,"script_address":2314251},{"address":3230472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":286}],"party_address":3211244,"script_address":0},{"address":3230512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":300}],"party_address":3211252,"script_address":2067580},{"address":3230552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":310},{"level":30,"species":178}],"party_address":3211268,"script_address":2068523},{"address":3230592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":380},{"level":30,"species":379}],"party_address":3211284,"script_address":2068554},{"address":3230632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211300,"script_address":2328071},{"address":3230672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3211308,"script_address":2069620},{"address":3230712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":286}],"party_address":3211316,"script_address":0},{"address":3230752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3211324,"script_address":2570959},{"address":3230792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":286},{"level":27,"species":330}],"party_address":3211340,"script_address":2572093},{"address":3230832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":286},{"level":26,"species":41},{"level":26,"species":330}],"party_address":3211356,"script_address":2572124},{"address":3230872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":330}],"party_address":3211380,"script_address":2157889},{"address":3230912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":41},{"level":14,"species":330}],"party_address":3211388,"script_address":2157948},{"address":3230952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":339}],"party_address":3211404,"script_address":2254636},{"address":3230992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211412,"script_address":2317522},{"address":3231032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211420,"script_address":2317553},{"address":3231072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":286},{"level":30,"species":330}],"party_address":3211428,"script_address":2317584},{"address":3231112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330}],"party_address":3211444,"script_address":2570990},{"address":3231152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211452,"script_address":2323414},{"address":3231192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211460,"script_address":2324427},{"address":3231232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":335},{"level":30,"species":67}],"party_address":3211468,"script_address":2068492},{"address":3231272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":287},{"level":34,"species":42}],"party_address":3211484,"script_address":2324250},{"address":3231312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":336}],"party_address":3211500,"script_address":2312702},{"address":3231352,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330},{"level":28,"species":287}],"party_address":3211508,"script_address":2572155},{"address":3231392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":331},{"level":37,"species":287}],"party_address":3211524,"script_address":2327156},{"address":3231432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":287},{"level":41,"species":169},{"level":43,"species":331}],"party_address":3211540,"script_address":2328478},{"address":3231472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":351}],"party_address":3211564,"script_address":2312671},{"address":3231512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211572,"script_address":2026085},{"address":3231552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":363},{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211588,"script_address":2058784},{"address":3231592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,0,0,0],"species":357},{"level":43,"moves":[29,89,0,0],"species":319}],"party_address":3211612,"script_address":2335547},{"address":3231632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":363},{"level":26,"species":44}],"party_address":3211644,"script_address":2068148},{"address":3231672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":363}],"party_address":3211660,"script_address":0},{"address":3231712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":306},{"level":28,"species":44},{"level":28,"species":363}],"party_address":3211676,"script_address":0},{"address":3231752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":306},{"level":31,"species":44},{"level":31,"species":363}],"party_address":3211700,"script_address":0},{"address":3231792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307},{"level":34,"species":44},{"level":34,"species":363}],"party_address":3211724,"script_address":0},{"address":3231832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,163,28,40],"species":28}],"party_address":3211748,"script_address":2046490},{"address":3231872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[60,120,201,246],"species":318},{"level":27,"moves":[91,163,28,40],"species":27},{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211764,"script_address":2065682},{"address":3231912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[91,163,28,40],"species":27},{"level":25,"moves":[91,163,28,40],"species":28}],"party_address":3211812,"script_address":2033540},{"address":3231952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211844,"script_address":0},{"address":3231992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[91,163,28,40],"species":28}],"party_address":3211860,"script_address":0},{"address":3232032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[91,163,28,40],"species":28}],"party_address":3211876,"script_address":0},{"address":3232072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[91,163,28,40],"species":28}],"party_address":3211892,"script_address":0},{"address":3232112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":81},{"level":17,"species":370}],"party_address":3211908,"script_address":0},{"address":3232152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":81},{"level":27,"species":371}],"party_address":3211924,"script_address":0},{"address":3232192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":82},{"level":30,"species":371}],"party_address":3211940,"script_address":0},{"address":3232232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":82},{"level":33,"species":371}],"party_address":3211956,"script_address":0},{"address":3232272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82},{"level":36,"species":371}],"party_address":3211972,"script_address":0},{"address":3232312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[49,86,63,85],"species":82},{"level":39,"moves":[54,23,48,48],"species":372}],"party_address":3211988,"script_address":0},{"address":3232352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":350}],"party_address":3212020,"script_address":2036011},{"address":3232392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212036,"script_address":2036121},{"address":3232432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212044,"script_address":2036152},{"address":3232472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183},{"level":26,"species":183}],"party_address":3212052,"script_address":0},{"address":3232512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":183},{"level":29,"species":183}],"party_address":3212068,"script_address":0},{"address":3232552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":183},{"level":32,"species":183}],"party_address":3212084,"script_address":0},{"address":3232592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":35,"species":184}],"party_address":3212100,"script_address":0},{"address":3232632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":13,"moves":[28,29,39,57],"species":288}],"party_address":3212116,"script_address":2035901},{"address":3232672,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":183}],"party_address":3212132,"script_address":2544001},{"address":3232712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212148,"script_address":2339831},{"address":3232752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[28,42,39,57],"species":289}],"party_address":3212156,"script_address":0},{"address":3232792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[28,42,39,57],"species":289}],"party_address":3212172,"script_address":0},{"address":3232832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[28,42,39,57],"species":289}],"party_address":3212188,"script_address":0},{"address":3232872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[28,42,39,57],"species":289}],"party_address":3212204,"script_address":0},{"address":3232912,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[98,97,17,0],"species":305}],"party_address":3212220,"script_address":2131164},{"address":3232952,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[42,146,8,0],"species":308}],"party_address":3212236,"script_address":2131228},{"address":3232992,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[47,68,247,0],"species":364}],"party_address":3212252,"script_address":2131292},{"address":3233032,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[116,163,0,0],"species":365}],"party_address":3212268,"script_address":2131356},{"address":3233072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[116,98,17,27],"species":305},{"level":28,"moves":[44,91,185,72],"species":332},{"level":28,"moves":[205,250,54,96],"species":313},{"level":28,"moves":[85,48,86,49],"species":82},{"level":28,"moves":[202,185,104,207],"species":300}],"party_address":3212284,"script_address":2068117},{"address":3233112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":322},{"level":44,"species":357},{"level":44,"species":331}],"party_address":3212364,"script_address":2565920},{"address":3233152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":355},{"level":46,"species":121}],"party_address":3212388,"script_address":2565982},{"address":3233192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":337},{"level":17,"species":313},{"level":17,"species":335}],"party_address":3212404,"script_address":2046693},{"address":3233232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":345},{"level":43,"species":310}],"party_address":3212428,"script_address":2332685},{"address":3233272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":82},{"level":43,"species":89}],"party_address":3212444,"script_address":2332716},{"address":3233312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":305},{"level":42,"species":355},{"level":42,"species":64}],"party_address":3212460,"script_address":2334375},{"address":3233352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":85},{"level":42,"species":64},{"level":42,"species":101},{"level":42,"species":300}],"party_address":3212484,"script_address":2335423},{"address":3233392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":317},{"level":42,"species":75},{"level":42,"species":314}],"party_address":3212516,"script_address":2335454},{"address":3233432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":337},{"level":26,"species":313},{"level":26,"species":335}],"party_address":3212540,"script_address":0},{"address":3233472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":313},{"level":29,"species":335}],"party_address":3212564,"script_address":0},{"address":3233512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":338},{"level":32,"species":313},{"level":32,"species":335}],"party_address":3212588,"script_address":0},{"address":3233552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":338},{"level":35,"species":313},{"level":35,"species":336}],"party_address":3212612,"script_address":0},{"address":3233592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":297}],"party_address":3212636,"script_address":2073950},{"address":3233632,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[185,95,0,0],"species":316}],"party_address":3212652,"script_address":2131420},{"address":3233672,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[111,38,247,0],"species":40}],"party_address":3212668,"script_address":2131484},{"address":3233712,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[14,163,0,0],"species":380}],"party_address":3212684,"script_address":2131548},{"address":3233752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[226,185,57,44],"species":355},{"level":29,"moves":[72,89,64,73],"species":363},{"level":29,"moves":[19,55,54,182],"species":310}],"party_address":3212700,"script_address":2068086},{"address":3233792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":383},{"level":45,"species":338}],"party_address":3212748,"script_address":2565951},{"address":3233832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":309},{"level":17,"species":339},{"level":17,"species":363}],"party_address":3212764,"script_address":2046803},{"address":3233872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":322}],"party_address":3212788,"script_address":2065651},{"address":3233912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3212796,"script_address":2332747},{"address":3233952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":319}],"party_address":3212804,"script_address":2334406},{"address":3233992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":321},{"level":42,"species":357},{"level":42,"species":297}],"party_address":3212812,"script_address":2334437},{"address":3234032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":227},{"level":43,"species":322}],"party_address":3212836,"script_address":2335485},{"address":3234072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":28},{"level":42,"species":38},{"level":42,"species":369}],"party_address":3212852,"script_address":2335516},{"address":3234112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":26,"species":339},{"level":26,"species":363}],"party_address":3212876,"script_address":0},{"address":3234152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":339},{"level":29,"species":363}],"party_address":3212900,"script_address":0},{"address":3234192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":339},{"level":32,"species":363}],"party_address":3212924,"script_address":0},{"address":3234232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":340},{"level":34,"species":363}],"party_address":3212948,"script_address":0},{"address":3234272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":348}],"party_address":3212972,"script_address":2564729},{"address":3234312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":361},{"level":30,"species":377}],"party_address":3212988,"script_address":2068461},{"address":3234352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":361},{"level":29,"species":377}],"party_address":3213004,"script_address":2067284},{"address":3234392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":322}],"party_address":3213020,"script_address":2315745},{"address":3234432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":377}],"party_address":3213028,"script_address":2315532},{"address":3234472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":322},{"level":31,"species":351}],"party_address":3213036,"script_address":0},{"address":3234512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":351},{"level":35,"species":322}],"party_address":3213052,"script_address":0},{"address":3234552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":351},{"level":40,"species":322}],"party_address":3213068,"script_address":0},{"address":3234592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":361},{"level":42,"species":322},{"level":42,"species":352}],"party_address":3213084,"script_address":0},{"address":3234632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213108,"script_address":2030087},{"address":3234672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[213,186,175,96],"species":325},{"level":39,"moves":[213,219,36,96],"species":325}],"party_address":3213116,"script_address":2265894},{"address":3234712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":287},{"level":28,"species":287},{"level":30,"species":339}],"party_address":3213148,"script_address":2254717},{"address":3234752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":11,"moves":[33,39,0,0],"species":288}],"party_address":3213172,"script_address":0},{"address":3234792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":40,"species":119}],"party_address":3213188,"script_address":2265677},{"address":3234832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3213196,"script_address":2361019},{"address":3234872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213204,"script_address":0},{"address":3234912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213212,"script_address":0},{"address":3234952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213220,"script_address":0},{"address":3234992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213228,"script_address":0},{"address":3235032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":183}],"party_address":3213244,"script_address":2304387},{"address":3235072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3213252,"script_address":2304418},{"address":3235112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":339}],"party_address":3213260,"script_address":2304449},{"address":3235152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[20,122,154,185],"species":317},{"level":29,"moves":[86,103,137,242],"species":379}],"party_address":3213268,"script_address":2067377},{"address":3235192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":118}],"party_address":3213300,"script_address":2265708},{"address":3235232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":184}],"party_address":3213308,"script_address":2265739},{"address":3235272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[78,250,240,96],"species":373},{"level":37,"moves":[13,152,96,0],"species":326},{"level":39,"moves":[253,154,252,96],"species":296}],"party_address":3213316,"script_address":2265770},{"address":3235312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":330},{"level":39,"species":331}],"party_address":3213364,"script_address":2265801},{"address":3235352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[20,122,154,185],"species":317},{"level":35,"moves":[86,103,137,242],"species":379}],"party_address":3213380,"script_address":0},{"address":3235392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[20,122,154,185],"species":317},{"level":38,"moves":[86,103,137,242],"species":379}],"party_address":3213412,"script_address":0},{"address":3235432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[20,122,154,185],"species":317},{"level":41,"moves":[86,103,137,242],"species":379}],"party_address":3213444,"script_address":0},{"address":3235472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[20,122,154,185],"species":317},{"level":44,"moves":[86,103,137,242],"species":379}],"party_address":3213476,"script_address":0},{"address":3235512,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213508,"script_address":2029901},{"address":3235552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":324},{"level":33,"species":356}],"party_address":3213516,"script_address":2074012},{"address":3235592,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":184}],"party_address":3213532,"script_address":2360988},{"address":3235632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213540,"script_address":0},{"address":3235672,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213548,"script_address":0},{"address":3235712,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213556,"script_address":0},{"address":3235752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213564,"script_address":0},{"address":3235792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3213580,"script_address":2051965},{"address":3235832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":116}],"party_address":3213588,"script_address":2340108},{"address":3235872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":111}],"party_address":3213604,"script_address":2312578},{"address":3235912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":339}],"party_address":3213612,"script_address":2304480},{"address":3235952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":383}],"party_address":3213620,"script_address":0},{"address":3235992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":383},{"level":29,"species":111}],"party_address":3213628,"script_address":0},{"address":3236032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":383},{"level":32,"species":111}],"party_address":3213644,"script_address":0},{"address":3236072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":384},{"level":35,"species":112}],"party_address":3213660,"script_address":0},{"address":3236112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213676,"script_address":2033571},{"address":3236152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":72}],"party_address":3213684,"script_address":2033602},{"address":3236192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":72}],"party_address":3213692,"script_address":2034185},{"address":3236232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":309},{"level":24,"species":72}],"party_address":3213708,"script_address":2034479},{"address":3236272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213732,"script_address":2034510},{"address":3236312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":73}],"party_address":3213740,"script_address":2034776},{"address":3236352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213748,"script_address":2034807},{"address":3236392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3213756,"script_address":2035777},{"address":3236432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309}],"party_address":3213772,"script_address":2069178},{"address":3236472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3213788,"script_address":2069209},{"address":3236512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":73}],"party_address":3213796,"script_address":2069789},{"address":3236552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":116}],"party_address":3213804,"script_address":2069820},{"address":3236592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213812,"script_address":2070163},{"address":3236632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":31,"species":309},{"level":31,"species":330}],"party_address":3213820,"script_address":2070194},{"address":3236672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213844,"script_address":2073229},{"address":3236712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310}],"party_address":3213852,"script_address":2073359},{"address":3236752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213860,"script_address":2073390},{"address":3236792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":73},{"level":33,"species":313}],"party_address":3213876,"script_address":2073291},{"address":3236832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3213892,"script_address":2073608},{"address":3236872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":342}],"party_address":3213900,"script_address":2073857},{"address":3236912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":341}],"party_address":3213908,"script_address":2073576},{"address":3236952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213916,"script_address":2074089},{"address":3236992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213924,"script_address":0},{"address":3237032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":313}],"party_address":3213948,"script_address":2069381},{"address":3237072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":331}],"party_address":3213964,"script_address":0},{"address":3237112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":331}],"party_address":3213972,"script_address":0},{"address":3237152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120},{"level":36,"species":331}],"party_address":3213980,"script_address":0},{"address":3237192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":121},{"level":39,"species":331}],"party_address":3213996,"script_address":0},{"address":3237232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3214012,"script_address":2095275},{"address":3237272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":66},{"level":32,"species":67}],"party_address":3214020,"script_address":2074213},{"address":3237312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":336}],"party_address":3214036,"script_address":2073701},{"address":3237352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":66},{"level":28,"species":67}],"party_address":3214044,"script_address":2052921},{"address":3237392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214060,"script_address":2052952},{"address":3237432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":67}],"party_address":3214068,"script_address":0},{"address":3237472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":66},{"level":29,"species":67}],"party_address":3214076,"script_address":0},{"address":3237512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":66},{"level":31,"species":67},{"level":31,"species":67}],"party_address":3214092,"script_address":0},{"address":3237552,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":66},{"level":33,"species":67},{"level":33,"species":67},{"level":33,"species":68}],"party_address":3214116,"script_address":0},{"address":3237592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":335},{"level":26,"species":67}],"party_address":3214148,"script_address":2557758},{"address":3237632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214164,"script_address":2046662},{"address":3237672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":336}],"party_address":3214172,"script_address":2315359},{"address":3237712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[98,86,209,43],"species":337},{"level":17,"moves":[12,95,103,0],"species":100}],"party_address":3214180,"script_address":2167608},{"address":3237752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":286},{"level":31,"species":41}],"party_address":3214212,"script_address":2323445},{"address":3237792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3214228,"script_address":2324458},{"address":3237832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":100},{"level":17,"species":81}],"party_address":3214236,"script_address":2167639},{"address":3237872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":337},{"level":30,"species":371}],"party_address":3214252,"script_address":2068709},{"address":3237912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81},{"level":15,"species":370}],"party_address":3214268,"script_address":2058956},{"address":3237952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":81},{"level":25,"species":370},{"level":25,"species":81}],"party_address":3214284,"script_address":0},{"address":3237992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81},{"level":28,"species":371},{"level":28,"species":81}],"party_address":3214308,"script_address":0},{"address":3238032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":82},{"level":31,"species":371},{"level":31,"species":82}],"party_address":3214332,"script_address":0},{"address":3238072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82},{"level":34,"species":372},{"level":34,"species":82}],"party_address":3214356,"script_address":0},{"address":3238112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214380,"script_address":2103394},{"address":3238152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":218},{"level":22,"species":218}],"party_address":3214388,"script_address":2103601},{"address":3238192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214404,"script_address":2103446},{"address":3238232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214412,"script_address":2103570},{"address":3238272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214420,"script_address":2103477},{"address":3238312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309}],"party_address":3214428,"script_address":2052075},{"address":3238352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":218},{"level":26,"species":309}],"party_address":3214444,"script_address":0},{"address":3238392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310}],"party_address":3214460,"script_address":0},{"address":3238432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":218},{"level":32,"species":310}],"party_address":3214476,"script_address":0},{"address":3238472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":219},{"level":35,"species":310}],"party_address":3214492,"script_address":0},{"address":3238512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,28,40,163],"species":27}],"party_address":3214508,"script_address":2046366},{"address":3238552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":21,"moves":[229,189,60,61],"species":318},{"level":21,"moves":[40,28,10,91],"species":27},{"level":21,"moves":[229,189,60,61],"species":318}],"party_address":3214524,"script_address":2046428},{"address":3238592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":299}],"party_address":3214572,"script_address":2049829},{"address":3238632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27},{"level":18,"species":299}],"party_address":3214580,"script_address":2051903},{"address":3238672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":317}],"party_address":3214596,"script_address":2557005},{"address":3238712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":288},{"level":20,"species":304}],"party_address":3214604,"script_address":2310199},{"address":3238752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3214620,"script_address":2310337},{"address":3238792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27}],"party_address":3214628,"script_address":2046600},{"address":3238832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":288},{"level":26,"species":304}],"party_address":3214636,"script_address":0},{"address":3238872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":289},{"level":29,"species":305}],"party_address":3214652,"script_address":0},{"address":3238912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":305},{"level":31,"species":289}],"party_address":3214668,"script_address":0},{"address":3238952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":28},{"level":34,"species":289}],"party_address":3214692,"script_address":0},{"address":3238992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":311}],"party_address":3214716,"script_address":2061044},{"address":3239032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":290},{"level":24,"species":291},{"level":24,"species":292}],"party_address":3214724,"script_address":2061075},{"address":3239072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":290},{"level":27,"species":293},{"level":27,"species":294}],"party_address":3214748,"script_address":2061106},{"address":3239112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":311},{"level":27,"species":311},{"level":27,"species":311}],"party_address":3214772,"script_address":2065541},{"address":3239152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":294},{"level":16,"species":292}],"party_address":3214796,"script_address":2057595},{"address":3239192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":311},{"level":31,"species":311}],"party_address":3214812,"script_address":0},{"address":3239232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":311},{"level":34,"species":311},{"level":34,"species":312}],"party_address":3214836,"script_address":0},{"address":3239272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":311},{"level":36,"species":290},{"level":36,"species":311},{"level":36,"species":312}],"party_address":3214860,"script_address":0},{"address":3239312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":311},{"level":38,"species":294},{"level":38,"species":311},{"level":38,"species":312},{"level":38,"species":292}],"party_address":3214892,"script_address":0},{"address":3239352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[237,0,0,0],"species":63}],"party_address":3214932,"script_address":2038374},{"address":3239392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3214948,"script_address":2244488},{"address":3239432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":392}],"party_address":3214956,"script_address":2244519},{"address":3239472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3214964,"script_address":2244550},{"address":3239512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":392},{"level":26,"species":393}],"party_address":3214972,"script_address":2314189},{"address":3239552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3214996,"script_address":2564698},{"address":3239592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":349}],"party_address":3215012,"script_address":2068179},{"address":3239632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":64},{"level":33,"species":349}],"party_address":3215020,"script_address":0},{"address":3239672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":64},{"level":38,"species":349}],"party_address":3215036,"script_address":0},{"address":3239712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3215052,"script_address":0},{"address":3239752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":349},{"level":45,"species":65}],"party_address":3215068,"script_address":0},{"address":3239792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[237,0,0,0],"species":63}],"party_address":3215084,"script_address":2038405},{"address":3239832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3215100,"script_address":2244581},{"address":3239872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":178}],"party_address":3215108,"script_address":2244612},{"address":3239912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3215116,"script_address":2244643},{"address":3239952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":202},{"level":26,"species":177},{"level":26,"species":64}],"party_address":3215124,"script_address":2314220},{"address":3239992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":393},{"level":41,"species":178}],"party_address":3215148,"script_address":2564760},{"address":3240032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":64},{"level":30,"species":348}],"party_address":3215164,"script_address":2068289},{"address":3240072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":64},{"level":34,"species":348}],"party_address":3215180,"script_address":0},{"address":3240112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":64},{"level":37,"species":348}],"party_address":3215196,"script_address":0},{"address":3240152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":64},{"level":40,"species":348}],"party_address":3215212,"script_address":0},{"address":3240192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":348},{"level":43,"species":65}],"party_address":3215228,"script_address":0},{"address":3240232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338}],"party_address":3215244,"script_address":2067174},{"address":3240272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":338},{"level":44,"species":338}],"party_address":3215252,"script_address":2360864},{"address":3240312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":380}],"party_address":3215268,"script_address":2360895},{"address":3240352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":338}],"party_address":3215276,"script_address":0},{"address":3240392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[29,28,60,154],"species":289},{"level":36,"moves":[98,209,60,46],"species":338}],"party_address":3215284,"script_address":0},{"address":3240432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[29,28,60,154],"species":289},{"level":39,"moves":[98,209,60,0],"species":338}],"party_address":3215316,"script_address":0},{"address":3240472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[29,28,60,154],"species":289},{"level":41,"moves":[154,50,93,244],"species":55},{"level":41,"moves":[98,209,60,46],"species":338}],"party_address":3215348,"script_address":0},{"address":3240512,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,38,28,242],"species":287},{"level":48,"moves":[3,104,207,70],"species":300},{"level":46,"moves":[73,185,46,178],"species":345},{"level":48,"moves":[57,14,70,7],"species":327},{"level":49,"moves":[76,157,14,163],"species":376}],"party_address":3215396,"script_address":2274753},{"address":3240552,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[69,109,174,182],"species":362},{"level":49,"moves":[247,32,5,185],"species":378},{"level":50,"moves":[247,104,101,185],"species":322},{"level":49,"moves":[247,94,85,7],"species":378},{"level":51,"moves":[247,58,157,89],"species":362}],"party_address":3215476,"script_address":2275380},{"address":3240592,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[227,34,2,45],"species":342},{"level":50,"moves":[113,242,196,58],"species":347},{"level":52,"moves":[213,38,2,59],"species":342},{"level":52,"moves":[247,153,2,58],"species":347},{"level":53,"moves":[57,34,58,73],"species":343}],"party_address":3215556,"script_address":2276062},{"address":3240632,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[61,81,182,38],"species":396},{"level":54,"moves":[38,225,93,76],"species":359},{"level":53,"moves":[108,93,57,34],"species":230},{"level":53,"moves":[53,242,225,89],"species":334},{"level":55,"moves":[53,81,157,242],"species":397}],"party_address":3215636,"script_address":2276724},{"address":3240672,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":12,"moves":[33,111,88,61],"species":74},{"level":12,"moves":[33,111,88,61],"species":74},{"level":15,"moves":[79,106,33,61],"species":320}],"party_address":3215716,"script_address":2187976},{"address":3240712,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[2,67,69,83],"species":66},{"level":16,"moves":[8,113,115,83],"species":356},{"level":19,"moves":[36,233,179,83],"species":335}],"party_address":3215764,"script_address":2095066},{"address":3240752,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":20,"moves":[205,209,120,95],"species":100},{"level":20,"moves":[95,43,98,80],"species":337},{"level":22,"moves":[48,95,86,49],"species":82},{"level":24,"moves":[98,86,95,80],"species":338}],"party_address":3215812,"script_address":2167181},{"address":3240792,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[59,36,222,241],"species":339},{"level":24,"moves":[59,123,113,241],"species":218},{"level":26,"moves":[59,33,241,213],"species":340},{"level":29,"moves":[59,241,34,213],"species":321}],"party_address":3215876,"script_address":2103186},{"address":3240832,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[42,60,7,227],"species":308},{"level":27,"moves":[163,7,227,185],"species":365},{"level":29,"moves":[163,187,7,29],"species":289},{"level":31,"moves":[68,25,7,185],"species":366}],"party_address":3215940,"script_address":2129756},{"address":3240872,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[195,119,219,76],"species":358},{"level":29,"moves":[241,76,76,235],"species":369},{"level":30,"moves":[55,48,182,76],"species":310},{"level":31,"moves":[28,31,211,76],"species":227},{"level":33,"moves":[89,225,93,76],"species":359}],"party_address":3216004,"script_address":2202062},{"address":3240912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[89,246,94,113],"species":319},{"level":41,"moves":[94,241,109,91],"species":178},{"level":42,"moves":[113,94,95,91],"species":348},{"level":42,"moves":[241,76,94,53],"species":349}],"party_address":3216084,"script_address":0},{"address":3240952,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[96,213,186,175],"species":325},{"level":41,"moves":[240,96,133,89],"species":324},{"level":43,"moves":[227,34,62,96],"species":342},{"level":43,"moves":[96,152,13,43],"species":327},{"level":46,"moves":[96,104,58,156],"species":230}],"party_address":3216148,"script_address":2262245},{"address":3240992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":392}],"party_address":3216228,"script_address":2054242},{"address":3241032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3216236,"script_address":2554598},{"address":3241072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":339},{"level":15,"species":43},{"level":15,"species":309}],"party_address":3216244,"script_address":2554629},{"address":3241112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":356}],"party_address":3216268,"script_address":0},{"address":3241152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":393},{"level":29,"species":356}],"party_address":3216284,"script_address":0},{"address":3241192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":393},{"level":32,"species":357}],"party_address":3216300,"script_address":0},{"address":3241232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":393},{"level":34,"species":378},{"level":34,"species":357}],"party_address":3216316,"script_address":0},{"address":3241272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":306}],"party_address":3216340,"script_address":2054490},{"address":3241312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":306},{"level":16,"species":292}],"party_address":3216348,"script_address":2554660},{"address":3241352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":370}],"party_address":3216364,"script_address":0},{"address":3241392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":306},{"level":29,"species":371}],"party_address":3216380,"script_address":0},{"address":3241432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":307},{"level":32,"species":371}],"party_address":3216396,"script_address":0},{"address":3241472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":307},{"level":35,"species":372}],"party_address":3216412,"script_address":0},{"address":3241512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[95,60,146,42],"species":308},{"level":32,"moves":[8,25,47,185],"species":366}],"party_address":3216428,"script_address":0},{"address":3241552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[45,39,29,60],"species":288},{"level":17,"moves":[33,116,36,0],"species":335}],"party_address":3216460,"script_address":0},{"address":3241592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[45,39,29,60],"species":288},{"level":30,"moves":[33,116,36,0],"species":335}],"party_address":3216492,"script_address":0},{"address":3241632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[45,39,29,60],"species":288},{"level":33,"moves":[33,116,36,0],"species":335}],"party_address":3216524,"script_address":0},{"address":3241672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[45,39,29,60],"species":289},{"level":36,"moves":[33,116,36,0],"species":335}],"party_address":3216556,"script_address":0},{"address":3241712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[45,39,29,60],"species":289},{"level":38,"moves":[33,116,36,0],"species":336}],"party_address":3216588,"script_address":0},{"address":3241752,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":16,"species":304},{"level":16,"species":288}],"party_address":3216620,"script_address":2045785},{"address":3241792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":15,"species":315}],"party_address":3216636,"script_address":2026353},{"address":3241832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[18,204,185,215],"species":315},{"level":36,"moves":[18,204,185,215],"species":315},{"level":40,"moves":[18,204,185,215],"species":315},{"level":12,"moves":[18,204,185,215],"species":315},{"level":30,"moves":[18,204,185,215],"species":315},{"level":42,"moves":[18,204,185,215],"species":316}],"party_address":3216644,"script_address":2360833},{"address":3241872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":315}],"party_address":3216740,"script_address":0},{"address":3241912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":315}],"party_address":3216748,"script_address":0},{"address":3241952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316}],"party_address":3216756,"script_address":0},{"address":3241992,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":316}],"party_address":3216764,"script_address":0},{"address":3242032,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":17,"species":363}],"party_address":3216772,"script_address":2045890},{"address":3242072,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":25}],"party_address":3216780,"script_address":2067143},{"address":3242112,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":350},{"level":37,"species":183},{"level":39,"species":184}],"party_address":3216788,"script_address":2265832},{"address":3242152,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":353},{"level":14,"species":354}],"party_address":3216812,"script_address":2038890},{"address":3242192,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":26,"species":353},{"level":26,"species":354}],"party_address":3216828,"script_address":0},{"address":3242232,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":353},{"level":29,"species":354}],"party_address":3216844,"script_address":0},{"address":3242272,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":353},{"level":32,"species":354}],"party_address":3216860,"script_address":0},{"address":3242312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":353},{"level":35,"species":354}],"party_address":3216876,"script_address":0},{"address":3242352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":336}],"party_address":3216892,"script_address":2052811},{"address":3242392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[36,26,28,91],"species":336}],"party_address":3216900,"script_address":0},{"address":3242432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[36,26,28,91],"species":336}],"party_address":3216916,"script_address":0},{"address":3242472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[36,187,28,91],"species":336}],"party_address":3216932,"script_address":0},{"address":3242512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[36,187,28,91],"species":336}],"party_address":3216948,"script_address":0},{"address":3242552,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[136,96,93,197],"species":356}],"party_address":3216964,"script_address":2046100},{"address":3242592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":356},{"level":21,"species":335}],"party_address":3216980,"script_address":2304277},{"address":3242632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":356},{"level":30,"species":335}],"party_address":3216996,"script_address":0},{"address":3242672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":357},{"level":33,"species":336}],"party_address":3217012,"script_address":0},{"address":3242712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":357},{"level":36,"species":336}],"party_address":3217028,"script_address":0},{"address":3242752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":357},{"level":39,"species":336}],"party_address":3217044,"script_address":0},{"address":3242792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":286}],"party_address":3217060,"script_address":2024678},{"address":3242832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":288},{"level":7,"species":298}],"party_address":3217068,"script_address":2029684},{"address":3242872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[33,0,0,0],"species":74}],"party_address":3217084,"script_address":2188154},{"address":3242912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3217100,"script_address":2188185},{"address":3242952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":66}],"party_address":3217116,"script_address":2054180},{"address":3242992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[29,28,45,85],"species":288},{"level":17,"moves":[133,124,25,1],"species":367}],"party_address":3217124,"script_address":2167670},{"address":3243032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[213,58,85,53],"species":366},{"level":43,"moves":[29,182,5,92],"species":362}],"party_address":3217156,"script_address":2332778},{"address":3243072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,94,85,91],"species":394},{"level":43,"moves":[89,247,76,24],"species":366}],"party_address":3217188,"script_address":2332809},{"address":3243112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":332}],"party_address":3217220,"script_address":2050594},{"address":3243152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3217228,"script_address":2050625},{"address":3243192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":287}],"party_address":3217236,"script_address":0},{"address":3243232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":305},{"level":30,"species":287}],"party_address":3217244,"script_address":0},{"address":3243272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":305},{"level":29,"species":289},{"level":33,"species":287}],"party_address":3217260,"script_address":0},{"address":3243312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":32,"species":289},{"level":36,"species":287}],"party_address":3217284,"script_address":0},{"address":3243352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":16,"species":288}],"party_address":3217308,"script_address":2553792},{"address":3243392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":3,"species":304}],"party_address":3217324,"script_address":2024926},{"address":3243432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":382},{"level":13,"species":337}],"party_address":3217340,"script_address":2039000},{"address":3243472,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[240,67,38,59],"species":314},{"level":55,"moves":[92,56,188,58],"species":73},{"level":56,"moves":[202,57,73,104],"species":297},{"level":56,"moves":[89,57,133,63],"species":324},{"level":56,"moves":[93,89,63,57],"species":130},{"level":58,"moves":[105,57,58,92],"species":329}],"party_address":3217356,"script_address":2277575},{"address":3243512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":10,"species":72},{"level":15,"species":129}],"party_address":3217452,"script_address":2026322},{"address":3243552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":6,"species":129},{"level":7,"species":129}],"party_address":3217476,"script_address":2029653},{"address":3243592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":129},{"level":17,"species":118},{"level":18,"species":323}],"party_address":3217500,"script_address":2052185},{"address":3243632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":10,"species":129},{"level":7,"species":72},{"level":10,"species":129}],"party_address":3217524,"script_address":2034247},{"address":3243672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72}],"party_address":3217548,"script_address":2034357},{"address":3243712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72},{"level":14,"species":313},{"level":11,"species":72},{"level":14,"species":313}],"party_address":3217556,"script_address":2038546},{"address":3243752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3217588,"script_address":2052216},{"address":3243792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3217596,"script_address":2058894},{"address":3243832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":72}],"party_address":3217612,"script_address":2058925},{"address":3243872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":73}],"party_address":3217620,"script_address":2036183},{"address":3243912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":27,"species":130},{"level":27,"species":130}],"party_address":3217636,"script_address":0},{"address":3243952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":130},{"level":26,"species":330},{"level":26,"species":72},{"level":29,"species":130}],"party_address":3217660,"script_address":0},{"address":3243992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":130},{"level":30,"species":330},{"level":30,"species":73},{"level":31,"species":130}],"party_address":3217692,"script_address":0},{"address":3244032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":130},{"level":33,"species":331},{"level":33,"species":130},{"level":35,"species":73}],"party_address":3217724,"script_address":0},{"address":3244072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":129},{"level":21,"species":130},{"level":23,"species":130},{"level":26,"species":130},{"level":30,"species":130},{"level":35,"species":130}],"party_address":3217756,"script_address":2073670},{"address":3244112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":100},{"level":6,"species":100},{"level":14,"species":81}],"party_address":3217804,"script_address":2038577},{"address":3244152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81}],"party_address":3217828,"script_address":2038608},{"address":3244192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217844,"script_address":2038639},{"address":3244232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":81}],"party_address":3217852,"script_address":0},{"address":3244272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":81}],"party_address":3217860,"script_address":0},{"address":3244312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82}],"party_address":3217868,"script_address":0},{"address":3244352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":82}],"party_address":3217876,"script_address":0},{"address":3244392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217884,"script_address":2038780},{"address":3244432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81},{"level":6,"species":100}],"party_address":3217892,"script_address":2038749},{"address":3244472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81}],"party_address":3217916,"script_address":0},{"address":3244512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":81}],"party_address":3217924,"script_address":0},{"address":3244552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82}],"party_address":3217932,"script_address":0},{"address":3244592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":82}],"party_address":3217940,"script_address":0},{"address":3244632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217948,"script_address":2057375},{"address":3244672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217956,"script_address":0},{"address":3244712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3217964,"script_address":0},{"address":3244752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3217972,"script_address":0},{"address":3244792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3217980,"script_address":0},{"address":3244832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217988,"script_address":2057485},{"address":3244872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217996,"script_address":0},{"address":3244912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3218004,"script_address":0},{"address":3244952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3218012,"script_address":0},{"address":3244992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3218020,"script_address":0},{"address":3245032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218028,"script_address":2070582},{"address":3245072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":288},{"level":25,"species":337}],"party_address":3218044,"script_address":2340077},{"address":3245112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218060,"script_address":2071332},{"address":3245152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218068,"script_address":2070380},{"address":3245192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218084,"script_address":2072978},{"address":3245232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218100,"script_address":0},{"address":3245272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218108,"script_address":0},{"address":3245312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218116,"script_address":0},{"address":3245352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218124,"script_address":0},{"address":3245392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218132,"script_address":2070318},{"address":3245432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218140,"script_address":2070613},{"address":3245472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218156,"script_address":2073545},{"address":3245512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218164,"script_address":2071442},{"address":3245552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":309},{"level":33,"species":120}],"party_address":3218172,"script_address":2073009},{"address":3245592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218188,"script_address":0},{"address":3245632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218196,"script_address":0},{"address":3245672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218204,"script_address":0},{"address":3245712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218212,"script_address":0},{"address":3245752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":359},{"level":37,"species":359}],"party_address":3218220,"script_address":2292701},{"address":3245792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":359}],"party_address":3218236,"script_address":0},{"address":3245832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":359},{"level":44,"species":359}],"party_address":3218252,"script_address":0},{"address":3245872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":395},{"level":46,"species":359},{"level":46,"species":359}],"party_address":3218268,"script_address":0},{"address":3245912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":49,"species":359},{"level":49,"species":359},{"level":49,"species":396}],"party_address":3218292,"script_address":0},{"address":3245952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[225,29,116,52],"species":395}],"party_address":3218316,"script_address":2074182},{"address":3245992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309}],"party_address":3218332,"script_address":2059066},{"address":3246032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":369}],"party_address":3218340,"script_address":2061450},{"address":3246072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":305}],"party_address":3218356,"script_address":2061481},{"address":3246112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":84},{"level":27,"species":227},{"level":27,"species":369}],"party_address":3218364,"script_address":2202267},{"address":3246152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":227}],"party_address":3218388,"script_address":2202391},{"address":3246192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":369},{"level":33,"species":178}],"party_address":3218396,"script_address":2070085},{"address":3246232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":84},{"level":29,"species":310}],"party_address":3218412,"script_address":2202298},{"address":3246272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":309},{"level":28,"species":177}],"party_address":3218428,"script_address":2065338},{"address":3246312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":358}],"party_address":3218444,"script_address":2065369},{"address":3246352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":305},{"level":36,"species":310},{"level":36,"species":178}],"party_address":3218452,"script_address":2563257},{"address":3246392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":305}],"party_address":3218476,"script_address":2059097},{"address":3246432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":177},{"level":32,"species":358}],"party_address":3218492,"script_address":0},{"address":3246472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":177},{"level":35,"species":359}],"party_address":3218508,"script_address":0},{"address":3246512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":177},{"level":38,"species":359}],"party_address":3218524,"script_address":0},{"address":3246552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":178}],"party_address":3218540,"script_address":0},{"address":3246592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":177},{"level":33,"species":305}],"party_address":3218556,"script_address":2074151},{"address":3246632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":369}],"party_address":3218572,"script_address":2073981},{"address":3246672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302}],"party_address":3218580,"script_address":2061512},{"address":3246712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302},{"level":25,"species":109}],"party_address":3218588,"script_address":2061543},{"address":3246752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,89,0,0],"species":319},{"level":43,"moves":[85,89,0,0],"species":171}],"party_address":3218604,"script_address":2335578},{"address":3246792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3218636,"script_address":2341860},{"address":3246832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,124,120],"species":109}],"party_address":3218644,"script_address":2050766},{"address":3246872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":109},{"level":18,"species":302}],"party_address":3218692,"script_address":2050876},{"address":3246912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[139,33,124,120],"species":109},{"level":24,"moves":[139,33,124,0],"species":109},{"level":24,"moves":[139,33,124,120],"species":109},{"level":26,"moves":[33,124,0,0],"species":109}],"party_address":3218708,"script_address":0},{"address":3246952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,0],"species":109},{"level":29,"moves":[33,124,0,0],"species":109}],"party_address":3218772,"script_address":0},{"address":3246992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":32,"moves":[33,124,0,0],"species":109}],"party_address":3218836,"script_address":0},{"address":3247032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[139,33,124,0],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":35,"moves":[33,124,0,0],"species":110}],"party_address":3218900,"script_address":0},{"address":3247072,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218964,"script_address":2095313},{"address":3247112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218972,"script_address":2095351},{"address":3247152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":335}],"party_address":3218980,"script_address":2053062},{"address":3247192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":356}],"party_address":3218996,"script_address":2557727},{"address":3247232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3219004,"script_address":2557789},{"address":3247272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3219012,"script_address":0},{"address":3247312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":356},{"level":29,"species":335}],"party_address":3219028,"script_address":0},{"address":3247352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":357},{"level":32,"species":336}],"party_address":3219044,"script_address":0},{"address":3247392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":357},{"level":35,"species":336}],"party_address":3219060,"script_address":0},{"address":3247432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":19,"moves":[52,33,222,241],"species":339}],"party_address":3219076,"script_address":2050656},{"address":3247472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":363},{"level":28,"species":313}],"party_address":3219092,"script_address":2065713},{"address":3247512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[240,55,87,96],"species":385}],"party_address":3219108,"script_address":2065744},{"address":3247552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[52,33,222,241],"species":339}],"party_address":3219124,"script_address":0},{"address":3247592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[52,36,222,241],"species":339}],"party_address":3219140,"script_address":0},{"address":3247632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[73,72,64,241],"species":363},{"level":34,"moves":[53,36,222,241],"species":339}],"party_address":3219156,"script_address":0},{"address":3247672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[73,202,76,241],"species":363},{"level":37,"moves":[53,36,89,241],"species":340}],"party_address":3219188,"script_address":0},{"address":3247712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":313}],"party_address":3219220,"script_address":2033633},{"address":3247752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3219236,"script_address":2033664},{"address":3247792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":313}],"party_address":3219244,"script_address":2034216},{"address":3247832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":118}],"party_address":3219252,"script_address":2034620},{"address":3247872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219268,"script_address":2034651},{"address":3247912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":116},{"level":25,"species":183}],"party_address":3219276,"script_address":2034838},{"address":3247952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219292,"script_address":2034869},{"address":3247992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":118},{"level":24,"species":309},{"level":24,"species":118}],"party_address":3219300,"script_address":2035808},{"address":3248032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3219324,"script_address":2069240},{"address":3248072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":183}],"party_address":3219332,"script_address":2069350},{"address":3248112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219340,"script_address":2069851},{"address":3248152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219348,"script_address":2069882},{"address":3248192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":183},{"level":33,"species":341}],"party_address":3219356,"script_address":2070225},{"address":3248232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":118}],"party_address":3219372,"script_address":2070256},{"address":3248272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":118},{"level":33,"species":341}],"party_address":3219380,"script_address":2073260},{"address":3248312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219396,"script_address":2073421},{"address":3248352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219404,"script_address":2073452},{"address":3248392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":184}],"party_address":3219412,"script_address":2073639},{"address":3248432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219420,"script_address":2070349},{"address":3248472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219436,"script_address":2073888},{"address":3248512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":116},{"level":33,"species":117}],"party_address":3219444,"script_address":2073919},{"address":3248552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":171},{"level":34,"species":310}],"party_address":3219460,"script_address":0},{"address":3248592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219476,"script_address":2074120},{"address":3248632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":119}],"party_address":3219492,"script_address":2071676},{"address":3248672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":313}],"party_address":3219500,"script_address":0},{"address":3248712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":313}],"party_address":3219508,"script_address":0},{"address":3248752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":120},{"level":43,"species":313}],"party_address":3219516,"script_address":0},{"address":3248792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":313},{"level":45,"species":121}],"party_address":3219532,"script_address":0},{"address":3248832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[91,28,40,163],"species":27},{"level":22,"moves":[229,189,60,61],"species":318}],"party_address":3219556,"script_address":2046397},{"address":3248872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[28,40,163,91],"species":27},{"level":22,"moves":[205,61,39,111],"species":183}],"party_address":3219588,"script_address":2046459},{"address":3248912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":304},{"level":17,"species":296}],"party_address":3219620,"script_address":2049860},{"address":3248952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":183},{"level":18,"species":296}],"party_address":3219636,"script_address":2051934},{"address":3248992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":315},{"level":23,"species":358}],"party_address":3219652,"script_address":2557036},{"address":3249032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":306},{"level":19,"species":43},{"level":19,"species":358}],"party_address":3219668,"script_address":2310092},{"address":3249072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[194,219,68,243],"species":202}],"party_address":3219692,"script_address":2315855},{"address":3249112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":306},{"level":17,"species":183}],"party_address":3219708,"script_address":2046631},{"address":3249152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":306},{"level":25,"species":44},{"level":25,"species":358}],"party_address":3219724,"script_address":0},{"address":3249192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":307},{"level":28,"species":44},{"level":28,"species":358}],"party_address":3219748,"script_address":0},{"address":3249232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307},{"level":31,"species":44},{"level":31,"species":358}],"party_address":3219772,"script_address":0},{"address":3249272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":307},{"level":40,"species":45},{"level":40,"species":359}],"party_address":3219796,"script_address":0},{"address":3249312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":353},{"level":15,"species":354}],"party_address":3219820,"script_address":0},{"address":3249352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":353},{"level":27,"species":354}],"party_address":3219836,"script_address":0},{"address":3249392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":298},{"level":6,"species":295}],"party_address":3219852,"script_address":0},{"address":3249432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":292},{"level":26,"species":294}],"party_address":3219868,"script_address":0},{"address":3249472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":353},{"level":9,"species":354}],"party_address":3219884,"script_address":0},{"address":3249512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[101,50,0,0],"species":361},{"level":10,"moves":[71,73,0,0],"species":306}],"party_address":3219900,"script_address":0},{"address":3249552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":353},{"level":30,"species":354}],"party_address":3219932,"script_address":0},{"address":3249592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[209,12,57,14],"species":353},{"level":33,"moves":[209,12,204,14],"species":354}],"party_address":3219948,"script_address":0},{"address":3249632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,12,57,14],"species":353},{"level":36,"moves":[87,12,204,14],"species":354}],"party_address":3219980,"script_address":0},{"address":3249672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":309},{"level":12,"species":66}],"party_address":3220012,"script_address":2035839},{"address":3249712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309}],"party_address":3220028,"script_address":2035870},{"address":3249752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":67}],"party_address":3220036,"script_address":2069913},{"address":3249792,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":66},{"level":11,"species":72}],"party_address":3220052,"script_address":2543939},{"address":3249832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":73},{"level":44,"species":67}],"party_address":3220076,"script_address":2360255},{"address":3249872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":66},{"level":43,"species":310},{"level":43,"species":67}],"party_address":3220092,"script_address":2360286},{"address":3249912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":341},{"level":25,"species":67}],"party_address":3220116,"script_address":2340984},{"address":3249952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":309},{"level":36,"species":72},{"level":36,"species":67}],"party_address":3220132,"script_address":0},{"address":3249992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":310},{"level":39,"species":72},{"level":39,"species":67}],"party_address":3220156,"script_address":0},{"address":3250032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":310},{"level":42,"species":72},{"level":42,"species":67}],"party_address":3220180,"script_address":0},{"address":3250072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":310},{"level":45,"species":67},{"level":45,"species":73}],"party_address":3220204,"script_address":0},{"address":3250112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3220228,"script_address":2103632},{"address":3250152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[175,96,216,213],"species":328},{"level":39,"moves":[175,96,216,213],"species":328}],"party_address":3220236,"script_address":2265863},{"address":3250192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":376}],"party_address":3220268,"script_address":2068647},{"address":3250232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[92,87,120,188],"species":109}],"party_address":3220276,"script_address":2068616},{"address":3250272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[241,55,53,76],"species":385}],"party_address":3220292,"script_address":2068585},{"address":3250312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":338},{"level":33,"species":68}],"party_address":3220308,"script_address":2070116},{"address":3250352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":341}],"party_address":3220324,"script_address":2074337},{"address":3250392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[44,46,86,85],"species":338}],"party_address":3220340,"script_address":2074306},{"address":3250432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":356},{"level":33,"species":336}],"party_address":3220356,"script_address":2074275},{"address":3250472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3220372,"script_address":2074244},{"address":3250512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":170},{"level":33,"species":336}],"party_address":3220380,"script_address":2074043},{"address":3250552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":296},{"level":14,"species":299}],"party_address":3220396,"script_address":2038436},{"address":3250592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":380},{"level":18,"species":379}],"party_address":3220412,"script_address":2053172},{"address":3250632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":340},{"level":38,"species":287},{"level":40,"species":42}],"party_address":3220428,"script_address":0},{"address":3250672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":299}],"party_address":3220452,"script_address":0},{"address":3250712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":299}],"party_address":3220468,"script_address":0},{"address":3250752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":299}],"party_address":3220484,"script_address":0},{"address":3250792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":297},{"level":35,"species":300}],"party_address":3220500,"script_address":0},{"address":3250832,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[76,219,225,93],"species":359},{"level":43,"moves":[47,18,204,185],"species":316},{"level":44,"moves":[89,73,202,92],"species":363},{"level":41,"moves":[48,85,161,103],"species":82},{"level":45,"moves":[104,91,94,248],"species":394}],"party_address":3220516,"script_address":2332529},{"address":3250872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220596,"script_address":2025759},{"address":3250912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309},{"level":20,"species":278}],"party_address":3220604,"script_address":2039798},{"address":3250952,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310},{"level":31,"species":278}],"party_address":3220628,"script_address":2060578},{"address":3250992,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220652,"script_address":2025703},{"address":3251032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220660,"script_address":2039742},{"address":3251072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220684,"script_address":2060522},{"address":3251112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220708,"script_address":2025731},{"address":3251152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220716,"script_address":2039770},{"address":3251192,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220740,"script_address":2060550},{"address":3251232,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220764,"script_address":2025675},{"address":3251272,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":218},{"level":20,"species":278}],"party_address":3220772,"script_address":2039622},{"address":3251312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":296},{"level":31,"species":278}],"party_address":3220796,"script_address":2060420},{"address":3251352,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220820,"script_address":2025619},{"address":3251392,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220828,"script_address":2039566},{"address":3251432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220852,"script_address":2060364},{"address":3251472,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220876,"script_address":2025647},{"address":3251512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220884,"script_address":2039594},{"address":3251552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220908,"script_address":2060392},{"address":3251592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":370},{"level":11,"species":288},{"level":11,"species":382},{"level":11,"species":286},{"level":11,"species":304},{"level":11,"species":335}],"party_address":3220932,"script_address":2057155},{"address":3251632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":127}],"party_address":3220980,"script_address":2068678},{"address":3251672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[153,115,113,94],"species":348},{"level":43,"moves":[153,115,113,247],"species":349}],"party_address":3220988,"script_address":2334468},{"address":3251712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":371},{"level":22,"species":289},{"level":22,"species":382},{"level":22,"species":287},{"level":22,"species":305},{"level":22,"species":335}],"party_address":3221020,"script_address":0},{"address":3251752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":371},{"level":25,"species":289},{"level":25,"species":382},{"level":25,"species":287},{"level":25,"species":305},{"level":25,"species":336}],"party_address":3221068,"script_address":0},{"address":3251792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":371},{"level":28,"species":289},{"level":28,"species":382},{"level":28,"species":287},{"level":28,"species":305},{"level":28,"species":336}],"party_address":3221116,"script_address":0},{"address":3251832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":371},{"level":31,"species":289},{"level":31,"species":383},{"level":31,"species":287},{"level":31,"species":305},{"level":31,"species":336}],"party_address":3221164,"script_address":0},{"address":3251872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":306},{"level":11,"species":183},{"level":11,"species":363},{"level":11,"species":315},{"level":11,"species":118}],"party_address":3221212,"script_address":2057265},{"address":3251912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":322},{"level":43,"species":376}],"party_address":3221260,"script_address":2334499},{"address":3251952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":28}],"party_address":3221276,"script_address":2341891},{"address":3251992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":309},{"level":22,"species":306},{"level":22,"species":183},{"level":22,"species":363},{"level":22,"species":315},{"level":22,"species":118}],"party_address":3221284,"script_address":0},{"address":3252032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":310},{"level":25,"species":307},{"level":25,"species":183},{"level":25,"species":363},{"level":25,"species":316},{"level":25,"species":118}],"party_address":3221332,"script_address":0},{"address":3252072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":310},{"level":28,"species":307},{"level":28,"species":183},{"level":28,"species":363},{"level":28,"species":316},{"level":28,"species":118}],"party_address":3221380,"script_address":0},{"address":3252112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":310},{"level":31,"species":307},{"level":31,"species":184},{"level":31,"species":363},{"level":31,"species":316},{"level":31,"species":119}],"party_address":3221428,"script_address":0},{"address":3252152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3221476,"script_address":2061230},{"address":3252192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":298},{"level":28,"species":299},{"level":28,"species":296}],"party_address":3221484,"script_address":2065479},{"address":3252232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":345}],"party_address":3221508,"script_address":2563288},{"address":3252272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307}],"party_address":3221516,"script_address":0},{"address":3252312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307}],"party_address":3221524,"script_address":0},{"address":3252352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":307}],"party_address":3221532,"script_address":0},{"address":3252392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":317},{"level":39,"species":307}],"party_address":3221540,"script_address":0},{"address":3252432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":44},{"level":26,"species":363}],"party_address":3221556,"script_address":2061340},{"address":3252472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":295},{"level":28,"species":296},{"level":28,"species":299}],"party_address":3221572,"script_address":2065510},{"address":3252512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":358},{"level":38,"species":363}],"party_address":3221596,"script_address":2563226},{"address":3252552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":44},{"level":30,"species":363}],"party_address":3221612,"script_address":0},{"address":3252592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":44},{"level":33,"species":363}],"party_address":3221628,"script_address":0},{"address":3252632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":44},{"level":36,"species":363}],"party_address":3221644,"script_address":0},{"address":3252672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":182},{"level":39,"species":363}],"party_address":3221660,"script_address":0},{"address":3252712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":81}],"party_address":3221676,"script_address":2310306},{"address":3252752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":287},{"level":35,"species":42}],"party_address":3221684,"script_address":2327187},{"address":3252792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":313},{"level":31,"species":41}],"party_address":3221700,"script_address":0},{"address":3252832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":30,"species":41}],"party_address":3221716,"script_address":2317615},{"address":3252872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":286},{"level":22,"species":339}],"party_address":3221732,"script_address":2309993},{"address":3252912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3221748,"script_address":2188216},{"address":3252952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3221764,"script_address":2095389},{"address":3252992,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3221772,"script_address":2095465},{"address":3253032,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":335}],"party_address":3221780,"script_address":2095427},{"address":3253072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":356}],"party_address":3221788,"script_address":2244674},{"address":3253112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3221796,"script_address":2070287},{"address":3253152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[87,86,98,0],"species":338},{"level":32,"moves":[57,168,0,0],"species":289}],"party_address":3221804,"script_address":2070768},{"address":3253192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":73}],"party_address":3221836,"script_address":2071645},{"address":3253232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":41}],"party_address":3221844,"script_address":2304070},{"address":3253272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3221852,"script_address":2073102},{"address":3253312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":203}],"party_address":3221860,"script_address":0},{"address":3253352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":351}],"party_address":3221868,"script_address":2244705},{"address":3253392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3221876,"script_address":2244829},{"address":3253432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3221884,"script_address":2244767},{"address":3253472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":202}],"party_address":3221892,"script_address":2244798},{"address":3253512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":286}],"party_address":3221900,"script_address":2254605},{"address":3253552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221916,"script_address":2254667},{"address":3253592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3221924,"script_address":2257768},{"address":3253632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":287}],"party_address":3221932,"script_address":2257818},{"address":3253672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221940,"script_address":2257868},{"address":3253712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":177}],"party_address":3221948,"script_address":2244736},{"address":3253752,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3221956,"script_address":1978559},{"address":3253792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3221972,"script_address":1978621},{"address":3253832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":305},{"level":33,"species":307}],"party_address":3221988,"script_address":2073732},{"address":3253872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3222004,"script_address":2069651},{"address":3253912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3222012,"script_address":2572062},{"address":3253952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":20,"species":286},{"level":22,"species":339},{"level":22,"species":41}],"party_address":3222028,"script_address":2304039},{"address":3253992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":317},{"level":33,"species":371}],"party_address":3222060,"script_address":2073794},{"address":3254032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":218},{"level":15,"species":283}],"party_address":3222076,"script_address":1978590},{"address":3254072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3222092,"script_address":1978317},{"address":3254112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":287},{"level":38,"species":169},{"level":39,"species":340}],"party_address":3222108,"script_address":2351441},{"address":3254152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":287},{"level":24,"species":41},{"level":25,"species":340}],"party_address":3222132,"script_address":2303440},{"address":3254192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":4,"species":306}],"party_address":3222156,"script_address":2024895},{"address":3254232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":295},{"level":6,"species":306}],"party_address":3222172,"script_address":2029715},{"address":3254272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":183}],"party_address":3222188,"script_address":2054459},{"address":3254312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183},{"level":15,"species":306},{"level":15,"species":339}],"party_address":3222196,"script_address":2045995},{"address":3254352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":306}],"party_address":3222220,"script_address":0},{"address":3254392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":307}],"party_address":3222236,"script_address":0},{"address":3254432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":307}],"party_address":3222252,"script_address":0},{"address":3254472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":296},{"level":34,"species":307}],"party_address":3222268,"script_address":0},{"address":3254512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":43}],"party_address":3222292,"script_address":2553761},{"address":3254552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":315},{"level":14,"species":306},{"level":14,"species":183}],"party_address":3222300,"script_address":2553823},{"address":3254592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325}],"party_address":3222324,"script_address":2265615},{"address":3254632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":118},{"level":39,"species":313}],"party_address":3222332,"script_address":2265646},{"address":3254672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":290},{"level":4,"species":290}],"party_address":3222348,"script_address":2024864},{"address":3254712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290}],"party_address":3222364,"script_address":2300392},{"address":3254752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":290},{"level":8,"species":301}],"party_address":3222396,"script_address":2054211},{"address":3254792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":301},{"level":28,"species":302}],"party_address":3222412,"script_address":2061137},{"address":3254832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222428,"script_address":2061168},{"address":3254872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302}],"party_address":3222444,"script_address":2061199},{"address":3254912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":301},{"level":6,"species":301}],"party_address":3222452,"script_address":2300423},{"address":3254952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":302}],"party_address":3222468,"script_address":0},{"address":3254992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":302}],"party_address":3222476,"script_address":0},{"address":3255032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":294},{"level":31,"species":302}],"party_address":3222492,"script_address":0},{"address":3255072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":311},{"level":33,"species":302},{"level":33,"species":294},{"level":33,"species":302}],"party_address":3222516,"script_address":0},{"address":3255112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":339},{"level":17,"species":66}],"party_address":3222548,"script_address":2049688},{"address":3255152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":17,"species":74},{"level":16,"species":74}],"party_address":3222564,"script_address":2049719},{"address":3255192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":66}],"party_address":3222588,"script_address":2051841},{"address":3255232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":339}],"party_address":3222604,"script_address":2051872},{"address":3255272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":74},{"level":22,"species":320},{"level":22,"species":75}],"party_address":3222620,"script_address":2557067},{"address":3255312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74}],"party_address":3222644,"script_address":2054428},{"address":3255352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":74},{"level":20,"species":318}],"party_address":3222652,"script_address":2310061},{"address":3255392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":9,"moves":[150,55,0,0],"species":313}],"party_address":3222668,"script_address":0},{"address":3255432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[16,45,0,0],"species":310},{"level":10,"moves":[44,184,0,0],"species":286}],"party_address":3222684,"script_address":0},{"address":3255472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":16,"species":74},{"level":16,"species":66}],"party_address":3222716,"script_address":2296023},{"address":3255512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":75}],"party_address":3222740,"script_address":0},{"address":3255552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":74},{"level":27,"species":74},{"level":27,"species":75},{"level":27,"species":75}],"party_address":3222772,"script_address":0},{"address":3255592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":74},{"level":30,"species":75},{"level":30,"species":75},{"level":30,"species":75}],"party_address":3222804,"script_address":0},{"address":3255632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":76}],"party_address":3222836,"script_address":0},{"address":3255672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":316},{"level":31,"species":338}],"party_address":3222868,"script_address":0},{"address":3255712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":325}],"party_address":3222884,"script_address":0},{"address":3255752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222900,"script_address":0},{"address":3255792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":386},{"level":30,"species":387}],"party_address":3222916,"script_address":0},{"address":3255832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":386},{"level":33,"species":387}],"party_address":3222932,"script_address":0},{"address":3255872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":386},{"level":36,"species":387}],"party_address":3222948,"script_address":0},{"address":3255912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":386},{"level":39,"species":387}],"party_address":3222964,"script_address":0},{"address":3255952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":118}],"party_address":3222980,"script_address":2543970},{"address":3255992,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[53,154,185,20],"species":317}],"party_address":3222988,"script_address":2103539},{"address":3256032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[117,197,93,9],"species":356},{"level":17,"moves":[9,197,93,96],"species":356}],"party_address":3223004,"script_address":2167701},{"address":3256072,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[117,197,93,7],"species":356}],"party_address":3223036,"script_address":2103508},{"address":3256112,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[33,120,124,108],"species":109},{"level":25,"moves":[33,139,124,108],"species":109}],"party_address":3223052,"script_address":2061574},{"address":3256152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[139,120,124,108],"species":109},{"level":28,"moves":[28,104,210,14],"species":302}],"party_address":3223084,"script_address":2065775},{"address":3256192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[141,154,170,91],"species":301},{"level":28,"moves":[33,120,124,108],"species":109}],"party_address":3223116,"script_address":2065806},{"address":3256232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":305},{"level":29,"species":178}],"party_address":3223148,"script_address":2202329},{"address":3256272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":358},{"level":27,"species":358},{"level":27,"species":358}],"party_address":3223164,"script_address":2202360},{"address":3256312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":392}],"party_address":3223188,"script_address":1971405},{"address":3256352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[76,219,225,93],"species":359},{"level":46,"moves":[47,18,204,185],"species":316},{"level":47,"moves":[89,73,202,92],"species":363},{"level":44,"moves":[48,85,161,103],"species":82},{"level":48,"moves":[104,91,94,248],"species":394}],"party_address":3223196,"script_address":2332607},{"address":3256392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[76,219,225,93],"species":359},{"level":49,"moves":[47,18,204,185],"species":316},{"level":50,"moves":[89,73,202,92],"species":363},{"level":47,"moves":[48,85,161,103],"species":82},{"level":51,"moves":[104,91,94,248],"species":394}],"party_address":3223276,"script_address":0},{"address":3256432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[76,219,225,93],"species":359},{"level":52,"moves":[47,18,204,185],"species":316},{"level":53,"moves":[89,73,202,92],"species":363},{"level":50,"moves":[48,85,161,103],"species":82},{"level":54,"moves":[104,91,94,248],"species":394}],"party_address":3223356,"script_address":0},{"address":3256472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[76,219,225,93],"species":359},{"level":55,"moves":[47,18,204,185],"species":316},{"level":56,"moves":[89,73,202,92],"species":363},{"level":53,"moves":[48,85,161,103],"species":82},{"level":57,"moves":[104,91,94,248],"species":394}],"party_address":3223436,"script_address":0},{"address":3256512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223516,"script_address":1986165},{"address":3256552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223548,"script_address":1986109},{"address":3256592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223580,"script_address":1986137},{"address":3256632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223612,"script_address":1986081},{"address":3256672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223644,"script_address":1986025},{"address":3256712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223676,"script_address":1986053},{"address":3256752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":31,"species":72},{"level":32,"species":331}],"party_address":3223708,"script_address":2070644},{"address":3256792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":34,"species":73}],"party_address":3223732,"script_address":2070675},{"address":3256832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":129},{"level":25,"species":129},{"level":35,"species":130}],"party_address":3223748,"script_address":2070706},{"address":3256872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":44},{"level":34,"species":184}],"party_address":3223772,"script_address":2071552},{"address":3256912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":300},{"level":34,"species":320}],"party_address":3223788,"script_address":2071583},{"address":3256952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":67}],"party_address":3223804,"script_address":2070799},{"address":3256992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":72},{"level":31,"species":72},{"level":36,"species":313}],"party_address":3223812,"script_address":2071614},{"address":3257032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":305},{"level":32,"species":227}],"party_address":3223836,"script_address":2070737},{"address":3257072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":341},{"level":33,"species":331}],"party_address":3223852,"script_address":2073040},{"address":3257112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170}],"party_address":3223868,"script_address":2073071},{"address":3257152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":308},{"level":19,"species":308}],"party_address":3223876,"script_address":0},{"address":3257192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[47,31,219,76],"species":358},{"level":35,"moves":[53,36,156,89],"species":339}],"party_address":3223892,"script_address":0},{"address":3257232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[74,78,72,73],"species":363},{"level":20,"moves":[111,205,44,88],"species":75}],"party_address":3223924,"script_address":0},{"address":3257272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[16,60,92,182],"species":294},{"level":27,"moves":[16,72,213,78],"species":292}],"party_address":3223956,"script_address":0},{"address":3257312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[94,7,244,182],"species":357},{"level":39,"moves":[8,61,156,187],"species":336}],"party_address":3223988,"script_address":0},{"address":3257352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,7,244,182],"species":357},{"level":43,"moves":[8,61,156,187],"species":336}],"party_address":3224020,"script_address":0},{"address":3257392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[94,7,244,182],"species":357},{"level":46,"moves":[8,61,156,187],"species":336}],"party_address":3224052,"script_address":0},{"address":3257432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":49,"moves":[94,7,244,182],"species":357},{"level":49,"moves":[8,61,156,187],"species":336}],"party_address":3224084,"script_address":0},{"address":3257472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[94,7,244,182],"species":357},{"level":52,"moves":[8,61,156,187],"species":336}],"party_address":3224116,"script_address":0},{"address":3257512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":33,"species":309}],"party_address":3224148,"script_address":0},{"address":3257552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170},{"level":33,"species":330}],"party_address":3224164,"script_address":0},{"address":3257592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":170},{"level":40,"species":330}],"party_address":3224180,"script_address":0},{"address":3257632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":171},{"level":43,"species":330}],"party_address":3224196,"script_address":0},{"address":3257672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":171},{"level":46,"species":331}],"party_address":3224212,"script_address":0},{"address":3257712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":51,"species":171},{"level":49,"species":331}],"party_address":3224228,"script_address":0},{"address":3257752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":118},{"level":25,"species":72}],"party_address":3224244,"script_address":0},{"address":3257792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":129},{"level":20,"species":72},{"level":26,"species":328},{"level":23,"species":330}],"party_address":3224260,"script_address":2061605},{"address":3257832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":288},{"level":8,"species":286}],"party_address":3224292,"script_address":2054707},{"address":3257872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":295},{"level":8,"species":288}],"party_address":3224308,"script_address":2054676},{"address":3257912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":129}],"party_address":3224324,"script_address":2030343},{"address":3257952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":183}],"party_address":3224332,"script_address":2036307},{"address":3257992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":72},{"level":12,"species":72}],"party_address":3224340,"script_address":2036276},{"address":3258032,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":354},{"level":14,"species":353}],"party_address":3224356,"script_address":2039032},{"address":3258072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":337},{"level":14,"species":100}],"party_address":3224372,"script_address":2039063},{"address":3258112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81}],"party_address":3224388,"script_address":2039094},{"address":3258152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":100}],"party_address":3224396,"script_address":2026463},{"address":3258192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":335}],"party_address":3224404,"script_address":2026494},{"address":3258232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":27}],"party_address":3224412,"script_address":2046975},{"address":3258272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":363}],"party_address":3224420,"script_address":2047006},{"address":3258312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306}],"party_address":3224428,"script_address":2046944},{"address":3258352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339}],"party_address":3224436,"script_address":2046913},{"address":3258392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":183},{"level":19,"species":296}],"party_address":3224444,"script_address":2050969},{"address":3258432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":227},{"level":19,"species":305}],"party_address":3224460,"script_address":2051000},{"address":3258472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":318},{"level":18,"species":27}],"party_address":3224476,"script_address":2051031},{"address":3258512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":382},{"level":18,"species":382}],"party_address":3224492,"script_address":2051062},{"address":3258552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":183}],"party_address":3224508,"script_address":2052309},{"address":3258592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3224524,"script_address":2052371},{"address":3258632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":299}],"party_address":3224532,"script_address":2052340},{"address":3258672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":14,"species":382},{"level":14,"species":337}],"party_address":3224540,"script_address":2059128},{"address":3258712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224564,"script_address":2347841},{"address":3258752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224572,"script_address":2347872},{"address":3258792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224580,"script_address":2348597},{"address":3258832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":41}],"party_address":3224588,"script_address":2348628},{"address":3258872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":339}],"party_address":3224604,"script_address":2348659},{"address":3258912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224620,"script_address":2349324},{"address":3258952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224628,"script_address":2349355},{"address":3258992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224636,"script_address":2349386},{"address":3259032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224644,"script_address":2350264},{"address":3259072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224652,"script_address":2350826},{"address":3259112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224660,"script_address":2351566},{"address":3259152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224668,"script_address":2351597},{"address":3259192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224676,"script_address":2351628},{"address":3259232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224684,"script_address":2348566},{"address":3259272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224692,"script_address":2349293},{"address":3259312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224700,"script_address":2350295},{"address":3259352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":339},{"level":28,"species":287},{"level":30,"species":41},{"level":33,"species":340}],"party_address":3224708,"script_address":2351659},{"address":3259392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":310},{"level":33,"species":340}],"party_address":3224740,"script_address":2073763},{"address":3259432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":287},{"level":43,"species":169},{"level":44,"species":340}],"party_address":3224756,"script_address":0},{"address":3259472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":72}],"party_address":3224780,"script_address":2026525},{"address":3259512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183}],"party_address":3224788,"script_address":2026556},{"address":3259552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":27},{"level":25,"species":27}],"party_address":3224796,"script_address":2033726},{"address":3259592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":309}],"party_address":3224812,"script_address":2033695},{"address":3259632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":120}],"party_address":3224828,"script_address":2034744},{"address":3259672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":309},{"level":24,"species":66},{"level":24,"species":72}],"party_address":3224836,"script_address":2034931},{"address":3259712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":338},{"level":24,"species":305},{"level":24,"species":338}],"party_address":3224860,"script_address":2034900},{"address":3259752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":227},{"level":25,"species":227}],"party_address":3224884,"script_address":2036338},{"address":3259792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":183},{"level":22,"species":296}],"party_address":3224900,"script_address":2047037},{"address":3259832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":27},{"level":22,"species":28}],"party_address":3224916,"script_address":2047068},{"address":3259872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":304},{"level":22,"species":299}],"party_address":3224932,"script_address":2047099},{"address":3259912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":18,"species":218}],"party_address":3224948,"script_address":2049891},{"address":3259952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306},{"level":18,"species":363}],"party_address":3224964,"script_address":2049922},{"address":3259992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":84},{"level":26,"species":85}],"party_address":3224980,"script_address":2053203},{"address":3260032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302},{"level":26,"species":367}],"party_address":3224996,"script_address":2053234},{"address":3260072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":64},{"level":26,"species":393}],"party_address":3225012,"script_address":2053265},{"address":3260112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3225028,"script_address":2053296},{"address":3260152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":351}],"party_address":3225044,"script_address":2053327},{"address":3260192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3225060,"script_address":2054738},{"address":3260232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":306},{"level":8,"species":295}],"party_address":3225076,"script_address":2054769},{"address":3260272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3225092,"script_address":2057834},{"address":3260312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3225100,"script_address":2057865},{"address":3260352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":356}],"party_address":3225108,"script_address":2057896},{"address":3260392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":363},{"level":33,"species":357}],"party_address":3225116,"script_address":2073825},{"address":3260432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":338}],"party_address":3225132,"script_address":2061636},{"address":3260472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":218},{"level":25,"species":339}],"party_address":3225140,"script_address":2061667},{"address":3260512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3225156,"script_address":2061698},{"address":3260552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[87,98,86,0],"species":338}],"party_address":3225164,"script_address":2065837},{"address":3260592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":356},{"level":28,"species":335}],"party_address":3225180,"script_address":2065868},{"address":3260632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":292}],"party_address":3225196,"script_address":2067487},{"address":3260672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":335},{"level":25,"species":309},{"level":25,"species":369},{"level":25,"species":288},{"level":25,"species":337},{"level":25,"species":339}],"party_address":3225212,"script_address":2067518},{"address":3260712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":286},{"level":25,"species":306},{"level":25,"species":337},{"level":25,"species":183},{"level":25,"species":27},{"level":25,"species":367}],"party_address":3225260,"script_address":2067549},{"address":3260752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":371},{"level":29,"species":365}],"party_address":3225308,"script_address":2067611},{"address":3260792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3225324,"script_address":1978255},{"address":3260832,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":321},{"level":15,"species":283}],"party_address":3225340,"script_address":1978286},{"address":3260872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[182,205,222,153],"species":76},{"level":35,"moves":[14,58,57,157],"species":140},{"level":35,"moves":[231,153,46,157],"species":95},{"level":37,"moves":[104,153,182,157],"species":320}],"party_address":3225356,"script_address":0},{"address":3260912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[182,58,157,57],"species":138},{"level":37,"moves":[182,205,222,153],"species":76},{"level":40,"moves":[14,58,57,157],"species":141},{"level":40,"moves":[231,153,46,157],"species":95},{"level":42,"moves":[104,153,182,157],"species":320}],"party_address":3225420,"script_address":0},{"address":3260952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[182,58,157,57],"species":139},{"level":42,"moves":[182,205,89,153],"species":76},{"level":45,"moves":[14,58,57,157],"species":141},{"level":45,"moves":[231,153,46,157],"species":95},{"level":47,"moves":[104,153,182,157],"species":320}],"party_address":3225500,"script_address":0},{"address":3260992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[157,63,48,182],"species":142},{"level":47,"moves":[8,205,89,153],"species":76},{"level":47,"moves":[182,58,157,57],"species":139},{"level":50,"moves":[14,58,57,157],"species":141},{"level":50,"moves":[231,153,46,157],"species":208},{"level":52,"moves":[104,153,182,157],"species":320}],"party_address":3225580,"script_address":0},{"address":3261032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[2,157,8,83],"species":68},{"level":33,"moves":[94,113,115,8],"species":356},{"level":35,"moves":[228,68,182,167],"species":237},{"level":37,"moves":[252,8,187,89],"species":336}],"party_address":3225676,"script_address":0},{"address":3261072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[2,157,8,83],"species":68},{"level":38,"moves":[94,113,115,8],"species":357},{"level":40,"moves":[228,68,182,167],"species":237},{"level":42,"moves":[252,8,187,89],"species":336}],"party_address":3225740,"script_address":0},{"address":3261112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[71,182,7,8],"species":107},{"level":43,"moves":[2,157,8,83],"species":68},{"level":43,"moves":[8,113,115,94],"species":357},{"level":45,"moves":[228,68,182,167],"species":237},{"level":47,"moves":[252,8,187,89],"species":336}],"party_address":3225804,"script_address":0},{"address":3261152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[25,8,89,83],"species":106},{"level":46,"moves":[71,182,7,8],"species":107},{"level":48,"moves":[238,157,8,83],"species":68},{"level":48,"moves":[8,113,115,94],"species":357},{"level":50,"moves":[228,68,182,167],"species":237},{"level":52,"moves":[252,8,187,89],"species":336}],"party_address":3225884,"script_address":0},{"address":3261192,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,182,86,113],"species":179},{"level":36,"moves":[205,87,153,240],"species":101},{"level":38,"moves":[48,182,87,240],"species":82},{"level":40,"moves":[44,86,87,182],"species":338}],"party_address":3225980,"script_address":0},{"address":3261232,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[87,21,240,95],"species":25},{"level":41,"moves":[87,182,86,113],"species":180},{"level":41,"moves":[205,87,153,240],"species":101},{"level":43,"moves":[48,182,87,240],"species":82},{"level":45,"moves":[44,86,87,182],"species":338}],"party_address":3226044,"script_address":0},{"address":3261272,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[87,21,240,182],"species":26},{"level":46,"moves":[87,182,86,113],"species":181},{"level":46,"moves":[205,87,153,240],"species":101},{"level":48,"moves":[48,182,87,240],"species":82},{"level":50,"moves":[44,86,87,182],"species":338}],"party_address":3226124,"script_address":0},{"address":3261312,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[129,8,9,113],"species":125},{"level":51,"moves":[87,21,240,182],"species":26},{"level":51,"moves":[87,182,86,113],"species":181},{"level":53,"moves":[205,87,153,240],"species":101},{"level":53,"moves":[48,182,87,240],"species":82},{"level":55,"moves":[44,86,87,182],"species":338}],"party_address":3226204,"script_address":0},{"address":3261352,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[59,213,113,157],"species":219},{"level":36,"moves":[53,213,76,84],"species":77},{"level":38,"moves":[59,241,89,213],"species":340},{"level":40,"moves":[59,241,153,213],"species":321}],"party_address":3226300,"script_address":0},{"address":3261392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[14,53,46,241],"species":58},{"level":43,"moves":[59,213,113,157],"species":219},{"level":41,"moves":[53,213,76,84],"species":77},{"level":43,"moves":[59,241,89,213],"species":340},{"level":45,"moves":[59,241,153,213],"species":321}],"party_address":3226364,"script_address":0},{"address":3261432,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,76,13,241],"species":228},{"level":46,"moves":[14,53,241,46],"species":58},{"level":48,"moves":[59,213,113,157],"species":219},{"level":46,"moves":[53,213,76,84],"species":78},{"level":48,"moves":[59,241,89,213],"species":340},{"level":50,"moves":[59,241,153,213],"species":321}],"party_address":3226444,"script_address":0},{"address":3261472,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":51,"moves":[14,53,241,46],"species":59},{"level":53,"moves":[59,213,113,157],"species":219},{"level":51,"moves":[46,76,13,241],"species":229},{"level":51,"moves":[53,213,76,84],"species":78},{"level":53,"moves":[59,241,89,213],"species":340},{"level":55,"moves":[59,241,153,213],"species":321}],"party_address":3226540,"script_address":0},{"address":3261512,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[113,47,29,8],"species":113},{"level":42,"moves":[59,247,38,126],"species":366},{"level":43,"moves":[42,29,7,95],"species":308},{"level":45,"moves":[63,53,85,247],"species":366}],"party_address":3226636,"script_address":0},{"address":3261552,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[59,247,38,126],"species":366},{"level":47,"moves":[113,47,29,8],"species":113},{"level":45,"moves":[252,146,203,179],"species":115},{"level":48,"moves":[42,29,7,95],"species":308},{"level":50,"moves":[63,53,85,247],"species":366}],"party_address":3226700,"script_address":0},{"address":3261592,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[59,247,38,126],"species":366},{"level":52,"moves":[113,47,29,8],"species":242},{"level":50,"moves":[252,146,203,179],"species":115},{"level":53,"moves":[42,29,7,95],"species":308},{"level":55,"moves":[63,53,85,247],"species":366}],"party_address":3226780,"script_address":0},{"address":3261632,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[59,247,38,126],"species":366},{"level":57,"moves":[182,47,29,8],"species":242},{"level":55,"moves":[252,146,203,179],"species":115},{"level":57,"moves":[36,182,126,89],"species":128},{"level":58,"moves":[42,29,7,95],"species":308},{"level":60,"moves":[63,53,85,247],"species":366}],"party_address":3226860,"script_address":0},{"address":3261672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[86,85,182,58],"species":147},{"level":38,"moves":[241,76,76,89],"species":369},{"level":41,"moves":[57,48,182,76],"species":310},{"level":43,"moves":[18,191,211,76],"species":227},{"level":45,"moves":[76,156,93,89],"species":359}],"party_address":3226956,"script_address":0},{"address":3261712,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[95,94,115,138],"species":163},{"level":43,"moves":[241,76,76,89],"species":369},{"level":45,"moves":[86,85,182,58],"species":148},{"level":46,"moves":[57,48,182,76],"species":310},{"level":48,"moves":[18,191,211,76],"species":227},{"level":50,"moves":[76,156,93,89],"species":359}],"party_address":3227036,"script_address":0},{"address":3261752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[95,94,115,138],"species":164},{"level":49,"moves":[241,76,76,89],"species":369},{"level":50,"moves":[86,85,182,58],"species":148},{"level":51,"moves":[57,48,182,76],"species":310},{"level":53,"moves":[18,191,211,76],"species":227},{"level":55,"moves":[76,156,93,89],"species":359}],"party_address":3227132,"script_address":0},{"address":3261792,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,94,115,138],"species":164},{"level":54,"moves":[241,76,76,89],"species":369},{"level":55,"moves":[57,48,182,76],"species":310},{"level":55,"moves":[63,85,89,58],"species":149},{"level":58,"moves":[18,191,211,76],"species":227},{"level":60,"moves":[143,156,93,89],"species":359}],"party_address":3227228,"script_address":0},{"address":3261832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[25,94,91,182],"species":79},{"level":49,"moves":[89,246,94,113],"species":319},{"level":49,"moves":[94,156,109,91],"species":178},{"level":50,"moves":[89,94,156,91],"species":348},{"level":50,"moves":[241,76,94,53],"species":349}],"party_address":3227324,"script_address":0},{"address":3261872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,138,29,182],"species":96},{"level":53,"moves":[25,94,91,182],"species":79},{"level":54,"moves":[89,153,94,113],"species":319},{"level":54,"moves":[94,156,109,91],"species":178},{"level":55,"moves":[89,94,156,91],"species":348},{"level":55,"moves":[241,76,94,53],"species":349}],"party_address":3227404,"script_address":0},{"address":3261912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":58,"moves":[95,138,29,182],"species":97},{"level":59,"moves":[89,153,94,113],"species":319},{"level":58,"moves":[25,94,91,182],"species":79},{"level":59,"moves":[94,156,109,91],"species":178},{"level":60,"moves":[89,94,156,91],"species":348},{"level":60,"moves":[241,76,94,53],"species":349}],"party_address":3227500,"script_address":0},{"address":3261952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":63,"moves":[95,138,29,182],"species":97},{"level":64,"moves":[89,153,94,113],"species":319},{"level":63,"moves":[25,94,91,182],"species":199},{"level":64,"moves":[94,156,109,91],"species":178},{"level":65,"moves":[89,94,156,91],"species":348},{"level":65,"moves":[241,76,94,53],"species":349}],"party_address":3227596,"script_address":0},{"address":3261992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[95,240,182,56],"species":60},{"level":46,"moves":[240,96,104,90],"species":324},{"level":48,"moves":[96,34,182,58],"species":343},{"level":48,"moves":[156,152,13,104],"species":327},{"level":51,"moves":[96,104,58,156],"species":230}],"party_address":3227692,"script_address":0},{"address":3262032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[95,240,182,56],"species":61},{"level":51,"moves":[240,96,104,90],"species":324},{"level":53,"moves":[96,34,182,58],"species":343},{"level":53,"moves":[156,12,13,104],"species":327},{"level":56,"moves":[96,104,58,156],"species":230}],"party_address":3227772,"script_address":0},{"address":3262072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[56,195,58,109],"species":131},{"level":58,"moves":[240,96,104,90],"species":324},{"level":56,"moves":[95,240,182,56],"species":61},{"level":58,"moves":[96,34,182,58],"species":343},{"level":58,"moves":[156,12,13,104],"species":327},{"level":61,"moves":[96,104,58,156],"species":230}],"party_address":3227852,"script_address":0},{"address":3262112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":61,"moves":[56,195,58,109],"species":131},{"level":63,"moves":[240,96,104,90],"species":324},{"level":61,"moves":[95,240,56,195],"species":186},{"level":63,"moves":[96,34,182,73],"species":343},{"level":63,"moves":[156,12,13,104],"species":327},{"level":66,"moves":[96,104,58,156],"species":230}],"party_address":3227948,"script_address":0},{"address":3262152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[95,98,204,0],"species":387},{"level":17,"moves":[95,98,109,0],"species":386}],"party_address":3228044,"script_address":2167732},{"address":3262192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":369}],"party_address":3228076,"script_address":2202422},{"address":3262232,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":77,"moves":[92,76,191,211],"species":227},{"level":75,"moves":[115,113,246,89],"species":319},{"level":76,"moves":[87,89,76,81],"species":384},{"level":76,"moves":[202,246,19,109],"species":389},{"level":76,"moves":[96,246,76,163],"species":391},{"level":78,"moves":[89,94,53,247],"species":400}],"party_address":3228084,"script_address":2354502},{"address":3262272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228180,"script_address":0},{"address":3262312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228188,"script_address":0},{"address":3262352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228196,"script_address":0},{"address":3262392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228204,"script_address":0},{"address":3262432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228212,"script_address":0},{"address":3262472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228220,"script_address":0},{"address":3262512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228228,"script_address":0},{"address":3262552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":27}],"party_address":3228236,"script_address":0},{"address":3262592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":320},{"level":33,"species":27},{"level":33,"species":27}],"party_address":3228252,"script_address":0},{"address":3262632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":320},{"level":35,"species":27},{"level":35,"species":27}],"party_address":3228276,"script_address":0},{"address":3262672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":320},{"level":37,"species":28},{"level":37,"species":28}],"party_address":3228300,"script_address":0},{"address":3262712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":309},{"level":30,"species":66},{"level":30,"species":72}],"party_address":3228324,"script_address":0},{"address":3262752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":66},{"level":32,"species":72}],"party_address":3228348,"script_address":0},{"address":3262792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":66},{"level":34,"species":73}],"party_address":3228372,"script_address":0},{"address":3262832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":310},{"level":36,"species":67},{"level":36,"species":73}],"party_address":3228396,"script_address":0},{"address":3262872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":120},{"level":37,"species":120}],"party_address":3228420,"script_address":0},{"address":3262912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":309},{"level":39,"species":120},{"level":39,"species":120}],"party_address":3228436,"script_address":0},{"address":3262952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":310},{"level":41,"species":120},{"level":41,"species":120}],"party_address":3228460,"script_address":0},{"address":3262992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":310},{"level":43,"species":121},{"level":43,"species":121}],"party_address":3228484,"script_address":0},{"address":3263032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":67},{"level":37,"species":67}],"party_address":3228508,"script_address":0},{"address":3263072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":335},{"level":39,"species":67},{"level":39,"species":67}],"party_address":3228524,"script_address":0},{"address":3263112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":336},{"level":41,"species":67},{"level":41,"species":67}],"party_address":3228548,"script_address":0},{"address":3263152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":336},{"level":43,"species":68},{"level":43,"species":68}],"party_address":3228572,"script_address":0},{"address":3263192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":371},{"level":35,"species":365}],"party_address":3228596,"script_address":0},{"address":3263232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":308},{"level":37,"species":371},{"level":37,"species":365}],"party_address":3228612,"script_address":0},{"address":3263272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":308},{"level":39,"species":371},{"level":39,"species":365}],"party_address":3228636,"script_address":0},{"address":3263312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":308},{"level":41,"species":372},{"level":41,"species":366}],"party_address":3228660,"script_address":0},{"address":3263352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":337},{"level":35,"species":337},{"level":35,"species":371}],"party_address":3228684,"script_address":0},{"address":3263392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":337},{"level":37,"species":338},{"level":37,"species":371}],"party_address":3228708,"script_address":0},{"address":3263432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":338},{"level":39,"species":338},{"level":39,"species":371}],"party_address":3228732,"script_address":0},{"address":3263472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":338},{"level":41,"species":338},{"level":41,"species":372}],"party_address":3228756,"script_address":0},{"address":3263512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":74},{"level":26,"species":339}],"party_address":3228780,"script_address":0},{"address":3263552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":66},{"level":28,"species":339},{"level":28,"species":75}],"party_address":3228796,"script_address":0},{"address":3263592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":66},{"level":30,"species":339},{"level":30,"species":75}],"party_address":3228820,"script_address":0},{"address":3263632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":340},{"level":33,"species":76}],"party_address":3228844,"script_address":0},{"address":3263672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":315},{"level":31,"species":287},{"level":31,"species":288},{"level":31,"species":295},{"level":31,"species":298},{"level":31,"species":304}],"party_address":3228868,"script_address":0},{"address":3263712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":315},{"level":33,"species":287},{"level":33,"species":289},{"level":33,"species":296},{"level":33,"species":299},{"level":33,"species":304}],"party_address":3228916,"script_address":0},{"address":3263752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316},{"level":35,"species":287},{"level":35,"species":289},{"level":35,"species":296},{"level":35,"species":299},{"level":35,"species":305}],"party_address":3228964,"script_address":0},{"address":3263792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":316},{"level":37,"species":287},{"level":37,"species":289},{"level":37,"species":297},{"level":37,"species":300},{"level":37,"species":305}],"party_address":3229012,"script_address":0},{"address":3263832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313},{"level":34,"species":116}],"party_address":3229060,"script_address":0},{"address":3263872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":325},{"level":36,"species":313},{"level":36,"species":117}],"party_address":3229076,"script_address":0},{"address":3263912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":325},{"level":38,"species":313},{"level":38,"species":117}],"party_address":3229100,"script_address":0},{"address":3263952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325},{"level":40,"species":314},{"level":40,"species":230}],"party_address":3229124,"script_address":0},{"address":3263992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":411}],"party_address":3229148,"script_address":2564791},{"address":3264032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":64}],"party_address":3229156,"script_address":2564822},{"address":3264072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":202}],"party_address":3229172,"script_address":0},{"address":3264112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":4}],"party_address":3229180,"script_address":0},{"address":3264152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":1}],"party_address":3229188,"script_address":0},{"address":3264192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":405}],"party_address":3229196,"script_address":0},{"address":3264232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":404}],"party_address":3229204,"script_address":0}],"warps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4":"MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0","MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2":"MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1","MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10","MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2":"MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11","MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3":"MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2","MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0":"MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4","MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3":"MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5","MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2":"MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6","MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4":"MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7","MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0":"MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8","MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9","MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2":"MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0","MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0":"MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1","MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0":"MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2","MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1":"MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3","MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2":"MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4","MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0":"MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5","MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10":"MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6","MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9":"MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7","MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0":"MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0","MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2","MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3","MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0":"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8","MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8":"MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0","MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11":"MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2","MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0","MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0","MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3","MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4","MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0","MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1","MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2","MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0","MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0":"MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0","MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0":"MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0","MAP_ALTERING_CAVE:0/MAP_ROUTE103:0":"MAP_ROUTE103:0/MAP_ALTERING_CAVE:0","MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0":"MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0","MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2":"MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1","MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1":"MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2","MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6":"MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0","MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0":"MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2","MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2":"MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0","MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0":"MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1","MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6":"MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10","MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22":"MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11","MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9":"MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12","MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18":"MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13","MAP_AQUA_HIDEOUT_B1F:14/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16":"MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15","MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15":"MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16","MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20":"MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17","MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13":"MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18","MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24":"MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19","MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1":"MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2","MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:21/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11":"MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22","MAP_AQUA_HIDEOUT_B1F:23/MAP_AQUA_HIDEOUT_B1F:17!":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19":"MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24","MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2":"MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3","MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7":"MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4","MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8":"MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5","MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10":"MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6","MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5":"MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8","MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1":"MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0","MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2":"MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1","MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3":"MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2","MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5":"MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3","MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8":"MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4","MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3":"MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5","MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7":"MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6","MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6":"MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7","MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4":"MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8","MAP_AQUA_HIDEOUT_B2F:9/MAP_AQUA_HIDEOUT_B1F:4!":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0","MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1":"MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1","MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0","MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1":"MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1","MAP_BATTLE_COLOSSEUM_2P:0,1/MAP_DYNAMIC:-1!":"","MAP_BATTLE_COLOSSEUM_4P:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:3/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0!":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2","MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2","MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0","MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0","MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0","MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0","MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0","MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0","MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0","MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0","MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0","MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0","MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0":"MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0":"MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0":"MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0":"MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0":"MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0":"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0":"MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0":"MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0":"MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0":"MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0":"MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0":"MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0":"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0":"MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0":"MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1","MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0","MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0":"MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0","MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0":"MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0","MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1":"MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0","MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3":"MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0":"MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:0/MAP_CAVE_OF_ORIGIN_1F:1!":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:1/MAP_CAVE_OF_ORIGIN_B1F:0!":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_DESERT_RUINS:0/MAP_ROUTE111:1":"MAP_ROUTE111:1/MAP_DESERT_RUINS:0","MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2":"MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1","MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1":"MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2","MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0","MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0":"MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0","MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1","MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0":"MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2","MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0":"MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3","MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0":"MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4","MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2":"MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0","MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0":"MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0","MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3":"MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0","MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4":"MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1":"MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0","MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1","MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0":"MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2","MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1":"MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1":"MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0":"MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1":"MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0":"MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1":"MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0":"MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1","MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0","MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1","MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0","MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1","MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0","MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1","MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0","MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1","MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0","MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1","MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1":"MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0":"MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1":"MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0":"MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0":"MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1":"MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0":"MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1","MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0":"MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0","MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0":"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1","MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2","MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0":"MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3","MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0":"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4","MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1":"MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0","MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3":"MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0","MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0":"MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0","MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4":"MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2":"MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1":"MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1","MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1":"MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1","MAP_FIERY_PATH:0/MAP_ROUTE112:4":"MAP_ROUTE112:4/MAP_FIERY_PATH:0","MAP_FIERY_PATH:1/MAP_ROUTE112:5":"MAP_ROUTE112:5/MAP_FIERY_PATH:1","MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0","MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0":"MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1","MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0":"MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2","MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0":"MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3","MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0":"MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4","MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0":"MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5","MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0":"MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6","MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0":"MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7","MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0":"MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8","MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8":"MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0","MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2":"MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0","MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1":"MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0","MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4":"MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0","MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5":"MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0","MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6":"MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0","MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7":"MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0","MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3":"MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0":"MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2","MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0","MAP_FORTREE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FORTREE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0":"MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0","MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0":"MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1","MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1":"MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2","MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0":"MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3","MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1":"MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0","MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2":"MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1","MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0":"MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2","MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1":"MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3","MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2":"MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4","MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3":"MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5","MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4":"MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6","MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2":"MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0","MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3":"MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1","MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4":"MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2","MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5":"MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3","MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6":"MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4","MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3":"MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0","MAP_INSIDE_OF_TRUCK:0,1,2/MAP_DYNAMIC:-1!":"","MAP_ISLAND_CAVE:0/MAP_ROUTE105:0":"MAP_ROUTE105:0/MAP_ISLAND_CAVE:0","MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2":"MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1","MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1":"MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2","MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3":"MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1","MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3":"MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3","MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0":"MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4","MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0":"MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0","MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0":"MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1","MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0":"MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2","MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3","MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0":"MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4","MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5","MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1":"MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0","MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8":"MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10","MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9":"MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11","MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10":"MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12","MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11":"MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13","MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12":"MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14","MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13":"MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15","MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14":"MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16","MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15":"MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17","MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16":"MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18","MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17":"MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19","MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0":"MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2","MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18":"MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20","MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20":"MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21","MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19":"MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22","MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21":"MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23","MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22":"MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24","MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23":"MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25","MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2":"MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3","MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4":"MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4","MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3":"MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5","MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1":"MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6","MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5":"MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7","MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6":"MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8","MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7":"MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9","MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2":"MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0","MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6":"MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1","MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12":"MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10","MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13":"MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11","MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14":"MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12","MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15":"MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13","MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16":"MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14","MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17":"MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15","MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18":"MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16","MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19":"MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17","MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20":"MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18","MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22":"MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19","MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3":"MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2","MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21":"MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20","MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23":"MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21","MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24":"MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22","MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25":"MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23","MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5":"MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3","MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4":"MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4","MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7":"MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5","MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8":"MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6","MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9":"MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7","MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10":"MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8","MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11":"MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9","MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0":"MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0","MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4":"MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0","MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2":"MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3":"MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5":"MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0","MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1","MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0":"MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10","MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0":"MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11","MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0":"MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12","MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2","MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13","MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4","MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1":"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5","MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0":"MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6","MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0":"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7","MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0":"MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8","MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0":"MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9","MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0","MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1","MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4":"MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0","MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0":"MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2","MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1":"MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1":"MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:3/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!":"","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0","MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12":"MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0","MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8":"MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0","MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9":"MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0","MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10":"MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0","MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11":"MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13":"MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0","MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7":"MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2":"MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5":"MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1","MAP_LILYCOVE_CITY_UNUSED_MART:0,1/MAP_LILYCOVE_CITY:0!":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0","MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1","MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0":"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1":"MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0":"MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2":"MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0","MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4":"MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0","MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1":"MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1","MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1":"MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2","MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0":"MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3","MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0":"MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0","MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1":"MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1","MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2":"MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2","MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0":"MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0","MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2":"MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1","MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3":"MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0","MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0":"MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1","MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0":"MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0","MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0":"MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1","MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2":"MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2","MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1":"MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0","MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1":"MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0","MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1":"MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1","MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0":"MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0","MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1":"MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1","MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0":"MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0","MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0":"MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0","MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0":"MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0","MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1","MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0":"MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2","MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0":"MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3","MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0":"MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4","MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0":"MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5","MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0":"MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6","MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2":"MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0","MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5":"MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0","MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0":"MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0","MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4":"MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0","MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6":"MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0","MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3":"MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1":"MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0":"MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0","MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0":"MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1","MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0":"MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2","MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4":"MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3","MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5":"MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4","MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0":"MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5","MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2":"MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0","MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0":"MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1","MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1":"MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2","MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2":"MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3","MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1":"MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0","MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2":"MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1","MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3":"MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2","MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0":"MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3","MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3":"MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4","MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4":"MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5","MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3":"MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0","MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5":"MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0","MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3":"MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0","MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1":"MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1","MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0":"MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0","MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1":"MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1","MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0":"MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0","MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0":"MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1","MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1":"MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0","MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0":"MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0","MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0":"MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1","MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2","MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0":"MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3","MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0":"MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4","MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0":"MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5","MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0":"MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6","MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1":"MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7","MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8","MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9":"MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2","MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0","MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1":"MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0","MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11":"MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10","MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10":"MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11","MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13":"MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12","MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12":"MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13","MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3":"MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2","MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2":"MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3","MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5":"MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4","MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4":"MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5","MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7":"MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6","MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6":"MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7","MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9":"MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8","MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8":"MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9","MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0":"MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0","MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3":"MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0","MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5":"MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0","MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7":"MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1","MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4":"MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2":"MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8":"MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2","MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0","MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6":"MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0","MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1":"MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1","MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3":"MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3","MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1":"MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1","MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0":"MAP_ROUTE122:0/MAP_MT_PYRE_1F:0","MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0":"MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1","MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0":"MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4","MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4":"MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5","MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4":"MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0","MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0":"MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1","MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4":"MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2","MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5":"MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3","MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5":"MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4","MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1":"MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0","MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1":"MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1","MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4":"MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2","MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5":"MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3","MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2":"MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4","MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3":"MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5","MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1":"MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0","MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1":"MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1","MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3":"MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2","MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4":"MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3","MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2":"MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4","MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3":"MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5","MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0":"MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0","MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0":"MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1","MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1":"MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2","MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2":"MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3","MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3":"MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4","MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0":"MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0","MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2":"MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1","MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1":"MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0","MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1":"MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1","MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1":"MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1","MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0":"MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0","MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1":"MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1","MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0":"MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0","MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2":"MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0","MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0":"MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1","MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1":"MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0","MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0":"MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1","MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1":"MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0","MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0":"MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1","MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1":"MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0","MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0":"MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1","MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1":"MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0","MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0":"MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1","MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1":"MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0","MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0":"MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1","MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1":"MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0","MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0":"MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1","MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1":"MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0","MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0":"MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1","MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1":"MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0","MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0":"MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1","MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1":"MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0","MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1":"MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1","MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0":"MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0","MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1":"MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1","MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0":"MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0","MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1":"MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1","MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0":"MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0","MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1":"MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1","MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0":"MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0","MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1":"MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1","MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0":"MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2","MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0":"MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0","MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1":"MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0","MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0":"MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0","MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0":"MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1","MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1":"MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0","MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0":"MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1","MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1":"MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0","MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0":"MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1","MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1":"MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0","MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0":"MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1","MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0":"MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0","MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0":"MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1","MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1":"MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0","MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0":"MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0","MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0":"MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1","MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2","MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0":"MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3","MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0":"MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0","MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1":"MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0","MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3":"MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2":"MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0","MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0":"MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1","MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0":"MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2","MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0":"MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3","MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0":"MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4","MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0":"MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5","MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1":"MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0","MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2":"MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0","MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3":"MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0","MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4":"MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0","MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5":"MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0":"MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0":"MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0","MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0":"MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1","MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0":"MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2","MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3","MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0":"MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4","MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0":"MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5","MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2":"MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0","MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8":"MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10","MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9":"MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12","MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16":"MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14","MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18":"MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15","MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14":"MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16","MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15":"MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18","MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3":"MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2","MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24":"MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20","MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26":"MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21","MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28":"MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22","MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30":"MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23","MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20":"MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24","MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21":"MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26","MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22":"MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28","MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2":"MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3","MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23":"MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30","MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34":"MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32","MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36":"MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33","MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32":"MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34","MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33":"MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36","MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6":"MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5","MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5":"MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6","MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10":"MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8","MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12":"MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9","MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0":"MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0","MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4":"MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0","MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5":"MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3":"MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1":"MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0","MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3":"MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1","MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5":"MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3","MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7":"MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5","MAP_RECORD_CORNER:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_ROUTE103:0/MAP_ALTERING_CAVE:0":"MAP_ALTERING_CAVE:0/MAP_ROUTE103:0","MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0":"MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0","MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0":"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1","MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1":"MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3","MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3":"MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5","MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5":"MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7","MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0":"MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0","MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1":"MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0","MAP_ROUTE105:0/MAP_ISLAND_CAVE:0":"MAP_ISLAND_CAVE:0/MAP_ROUTE105:0","MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0":"MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0","MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0":"MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0","MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0":"MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0","MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0":"MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0","MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0":"MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0","MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1","MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2","MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3","MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4","MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4":"MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5":"MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2":"MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3":"MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1":"MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:2,3/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0","MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0":"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1":"MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0":"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0","MAP_ROUTE111:1/MAP_DESERT_RUINS:0":"MAP_DESERT_RUINS:0/MAP_ROUTE111:1","MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0":"MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2","MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0":"MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3","MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0":"MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4","MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2":"MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0","MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0":"MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0","MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1":"MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1","MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1":"MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3","MAP_ROUTE112:4/MAP_FIERY_PATH:0":"MAP_FIERY_PATH:0/MAP_ROUTE112:4","MAP_ROUTE112:5/MAP_FIERY_PATH:1":"MAP_FIERY_PATH:1/MAP_ROUTE112:5","MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1":"MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1","MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0":"MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0","MAP_ROUTE113:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0":"MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0","MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0":"MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0","MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1","MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0":"MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2","MAP_ROUTE114:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1":"MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0":"MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2","MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2":"MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0","MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1":"MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0","MAP_ROUTE115:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE115:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0":"MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0","MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0":"MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1","MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2":"MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2","MAP_ROUTE116:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1":"MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0","MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0":"MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0","MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0":"MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0","MAP_ROUTE118:0/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE118:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0","MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0":"MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1","MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1":"MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0":"MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2","MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0","MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0":"MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0","MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0":"MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1","MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0":"MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0":"MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2","MAP_ROUTE122:0/MAP_MT_PYRE_1F:0":"MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0","MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0":"MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0","MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0":"MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0","MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0":"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0","MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0":"MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0","MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0","MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0":"MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0","MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0":"MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0","MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0":"MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1","MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0":"MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10","MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0":"MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11","MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0":"MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2","MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3","MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0":"MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4","MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6","MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0":"MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7","MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0":"MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8","MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0":"MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9","MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8":"MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0","MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6":"MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1","MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2","MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0","MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1","MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0","MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1":"MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0","MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0":"MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2","MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2":"MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0","MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10":"MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0","MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0":"MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2","MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2":"MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0","MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0":"MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1","MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1":"MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0","MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0":"MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0","MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7":"MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0","MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9":"MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0","MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11":"MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0","MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2":"MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3":"MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4":"MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0","MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0":"MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0","MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4":"MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1","MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2":"MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2","MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0":"MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0","MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0","MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0":"MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0","MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1":"MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:0/MAP_UNDERWATER_ROUTE128:0!":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0":"MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1","MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0":"MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1","MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0":"MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2","MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2":"MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0","MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0":"MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1","MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0":"MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2","MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0":"MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3","MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1":"MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0","MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1":"MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1","MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1":"MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2","MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1":"MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0","MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1":"MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1","MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2":"MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2","MAP_SEAFLOOR_CAVERN_ROOM4:3/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1":"MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0","MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1":"MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1","MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2":"MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2","MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2":"MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0","MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2":"MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1","MAP_SEAFLOOR_CAVERN_ROOM6:2/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3":"MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0","MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1":"MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1","MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0":"MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0","MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0":"MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1","MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0":"MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0","MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0":"MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0","MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0":"MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0","MAP_SECRET_BASE_BLUE_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0":"MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1","MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1":"MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0","MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0":"MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2","MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2":"MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0","MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0":"MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1","MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1":"MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0","MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0":"MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1","MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1":"MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2","MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1":"MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0","MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2":"MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1","MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0":"MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2","MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2":"MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0","MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0":"MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1","MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0":"MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0","MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0":"MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1","MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1":"MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0","MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0":"MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1","MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1":"MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0","MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0","MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0":"MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1","MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0":"MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10","MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2","MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0":"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3","MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0":"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4","MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7","MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0":"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6","MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0":"MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8","MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2":"MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9","MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3":"MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0","MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8":"MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0","MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9":"MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2","MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10":"MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0","MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1":"MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0","MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6":"MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7":"MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0":"MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4":"MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2":"MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0","MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0","MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0":"MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1","MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0":"MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10","MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0":"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11","MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12","MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0":"MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2","MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0":"MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3","MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0":"MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4","MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0":"MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5","MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0":"MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6","MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0":"MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7","MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0":"MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8","MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0":"MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9","MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2":"MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0","MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0":"MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2","MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2":"MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0","MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4":"MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0","MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5":"MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0","MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6":"MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0","MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7":"MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0","MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8":"MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0","MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9":"MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0","MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10":"MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0","MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11":"MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0","MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1":"MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12":"MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0":"MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1":"MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1","MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1":"MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1","MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0":"MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0","MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2":"MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1","MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4":"MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2","MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6":"MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3","MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8":"MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4","MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9":"MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5","MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10":"MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6","MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11":"MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7","MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0":"MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8","MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8":"MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0","MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0":"MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0","MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6":"MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10","MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7":"MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11","MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1":"MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2","MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2":"MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4","MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3":"MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6","MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4":"MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8","MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5":"MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9","MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1":"MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0","MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!":"","MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0":"MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1","MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!":"","MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2":"MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0","MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0":"MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1","MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1":"MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0","MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0":"MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1","MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1":"MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0","MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0":"MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1","MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1":"MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0","MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0":"MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1","MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1":"MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1","MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4":"MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0","MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0":"MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2","MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1":"MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0","MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1":"MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1","MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!":"","MAP_UNDERWATER_ROUTE105:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE105:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0":"MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0","MAP_UNDERWATER_ROUTE127:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE127:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0":"MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0","MAP_UNDERWATER_ROUTE129:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE129:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0":"MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0","MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0":"MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0","MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0":"MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0","MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!":"","MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0":"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0","MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0":"MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1","MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2","MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0":"MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3","MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1":"MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4","MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0":"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5","MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0":"MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6","MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0":"MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0","MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5":"MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0","MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6":"MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0","MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1":"MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2":"MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3":"MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0","MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2":"MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0","MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3":"MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1","MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5":"MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2","MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2":"MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3","MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4":"MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4","MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0":"MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0","MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2":"MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1","MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3":"MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2","MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1":"MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3","MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4":"MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4","MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2":"MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5","MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3":"MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6","MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0":"MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0","MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3":"MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1","MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1":"MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2","MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6":"MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3"}} diff --git a/worlds/pokemon_emerald/docs/adjuster_en.md b/worlds/pokemon_emerald/docs/adjuster_en.md new file mode 100644 index 000000000000..adb81b415ed7 --- /dev/null +++ b/worlds/pokemon_emerald/docs/adjuster_en.md @@ -0,0 +1,293 @@ +# Pokémon Gen 3 Adjuster for Pokémon Emerald + +1) [Introduction](#introduction) +2) [Quickstart](#quickstart) +3) [Sprite Pack](#sprite-pack) + 1) [Extracting Resources from the ROM](#extracting-resources-from-the-rom) + 2) [Pokémon Folder Specifications](#pokemon-folder-specifications) + 1) [Pokémon Folder Sprites](#pokemon-folder-sprites) + 2) [Pokémon Folder Exceptions](#pokemon-folder-exceptions) + 3) [Player Folder Specifications](#player-folder-specifications) + 1) [Player Folder Palettes](#player-folder-palettes) + 2) [Player Folder Sprites](#player-folder-sprites) + 3) [Player Folder Sprite Size Override](#player-folder-sprite-size-override) +4) [Pokémon Data Edition](#pokemon-data-edition) +5) [Applying the Sprite Pack](#applying-the-sprite-pack) + +## Introduction + +The Pokémon Gen 3 Adjuster allows anyone to apply a sprite pack to Pokémon Emerald, Pokémon Firered and Pokémon +Leafgreen, in order to personnalize runs made in Archipelago with these games. + +While its main goal is to apply said sprite packs to an AP-patched version of said ROMs, the tool also allows the +patching of vanilla ROMs. + +## Quickstart + +If you want to quickly get into using the adjuster, you can create a sprite pack by +[extracting resources from the ROM](#extracting-resources-from-the-rom). + +Once you have said pack, modify the sprites in it at your leisure, but feel free to check the specifications for each +folder if you encounter any problem. + +Once a ROM (or AP patch) and a sprite pack is given, you just need to [apply the sprite pack](#applying-the-sprite-pack) +and run your adjusted ROM in your emulator of choice, and you're good to go! + +## Sprite Pack + +A sprite pack is a folder containing folders with specific names for the various objects you want to replace. Here +is an example of a valid sprite pack, who replaces some resources from the Pokémon Latios and the Player Brendan: + +``` +Sprite Pack/ + Brendan/ + battle_back.png + battle_front.png + Latios/ + front_anim.png + back.png +``` + +Note: If sprites contain several frames, then said frames must be vertical: a `64x64px` sprite with `2` +frames will require a `64x128px` sprite. + +**Warning:** All sprites used in sprite packs must be Indexed PNG files. Some pixel editing +programs such as Aseprite allow you to make those easily instead of standard PNG files. + +Different types of folder exists: mainly Pokémon folders, and Player folders. + +### Extracting Resources from the ROM + +The Pokémon Gen 3 Adjuster allows you to extract resources from any object handled by the adjuster. In order to +extract a resource, a ROM or .apemerald patch must be given. + +Once a valid ROM or patch is given, a new module will appear within the adjuster named `Sprite Extractor`. In it, +you can either select one specific object to extract the resources of using the field given in it, or you can +extract all resources from the ROM with one button press. + +Once you press any of the `Extract` buttons, you must select a folder in which either all resources from the +currently selected object will be extracted, or in which a complete sprite pack will be extracted. + +Note: If you try to extract resources in a folder that doesn't exist, the adjuster will create said folders +first. + +### Pokémon Folder Specifications + +Pokémon folder names correspond to the name of the 386 Pokémon available within Generation 3 of Pokémon, with some +extras and exceptions. Here is a list of them: + +- Nidoran♂ => Nidoran Male +- Nidoran♀ => Nidoran Female +- Unown => Unown A +- All letter shapes of Unown have been added as Unown B, Unown C... Unown Z +- Unown ! => Unown Exclamation Mark +- Unown ? => Unown Question Mark +- The Egg folder has been added + +#### Pokémon Folder Sprites + +Generally, Pokémon folders will handle these sprites: + +- `front_anim.png`: This sprite replaces the animation used when displaying the enemy's Pokémon sprite in battle, +and the Pokémon sprite used when looking at a Pokémon's status in your team menu + - Required sprite size: `64x64px` sprite with `2` frames (`64x128px`) + - Required palette size: `16` colors max +- `sfront_anim.png`: Shiny variant of the animation used when displaying the enemy's Pokémon sprite in battle, and +the Pokémon sprite used when looking at a Pokémon's status in your team menu + - Same requirements as `front_anim.png` + - Make sure that the sprite's pixel data matches the one from `front_anim.png`, as only the sprite's palette + is used by the adjuster +- `back.png`: This sprite replaces the sprite used when displaying your Pokémon sprite in battle + - Required sprite size: `64x64px` sprite + - Required palette size: `16` colors max +- `sback.png`: Shiny variant of the sprite used when displaying your Pokémon sprite in battle + - Optional if `sfront_anim.png` is given + - Same requirements as `back.png` + - Make sure that the sprite's pixel data matches the one from `back.png`, as only the sprite's palette + is used by the adjuster +- `icon-X.png`: Icon used for the Pokémon in the team menu + - Required sprite size: `32x32px` sprite with `2` frames (`32x64px`) + - X must be a value between 0 and 2: This number will choose which icon palette to use + - Icon palettes: [Palette 0](./icon_palette_0.pal), [Palette 1](./icon_palette_1.pal), + [Palette 2](./icon_palette_2.pal) + - Alternatively, `Venusaur` uses Palette 1, `Charizard` uses Palette 0, and `Blastoise` uses Palette 2. You can + extract those objects to get icon sprites with the right palettes. +- `footprint.png`: Pokémon's footprint in the Pokédex + - Required sprite size: `16x16px` sprite + - Required palette: Exactly 2 colors: black (0, 0, 0) and white (255, 255, 255) + +#### Pokémon Folder Exceptions + +While most Pokémon follow the rules above, some of them have different requirements: + +- Castform: + - `front_anim.png` & `sfront_anim.png`: + - Required sprite size: `64x64px` sprite with `4` frames (`64x256px`) + - Required palette size: Exactly `64` colors + - Each frame uses colors from its 16-color palette: Frame 1 uses colors 1-16 from the palette, Frame 2 + uses colors 17-32 from the palette, etc... + - `back.png` & `sback.png`: + - Required sprite size: `64x64px` sprite with `4` frames (`64x256px`) + - Required palette size: Exactly `64` colors + - Each frame uses colors from its 16-color palette: Frame 1 uses colors 1-16 from the palette, Frame 2 + uses colors 17-32 from the palette, etc... +- Deoxys: + - `back.png` & `sback.png`: + - Required sprite size: `64x64px` sprite with `2` frames (`64x128px`) + - First frame for the Normal Deoxys form, second frame for the Speed Deoxys form + - `icon-X.png`: + - Required sprite size: `32x32` sprite with `4` frames (`32x128px`) + - First two frames for the Normal Deoxys form, last two frames for the Speed Deoxys form +- All Unowns: + - `front_anim.png` & `back.png`: + - Palette: Only Unown A's palette is used for all Unowns, so the existing colors of the palette must be + kept. Extract Unown A's sprites to get its palette, and only edit the pink colors in it + - `sfront_anim.png` & `sback.png`: + - Palette: Only Unown A's shiny palette is used for all Unowns, so the existing colors of the palette must + be kept. Extract Unown A's sprites to get its shiny palette, and only edit the pink colors in it + - `footprint.png`: + - Only Unown A's footprint is used for all Unowns, thus this sprite doesn't exist within the ROM, and will + be ignored by the adjuster +- Egg: + - `hatch_anim.png`: + - Required sprite size: `32x32px` sprite with `4` frames + `8x8px` sprite with `4` frames (`32x136px`) + - Required palette size: `16` colors max + - Extract the Egg sprite from the ROM to see this sprite's shape. It contains 4 frames for the hatching + animation, and 4 frames for eggshells shards flying around after hatching + +### Player Folder Specifications + +Player folder names correspond to the name of the male and female players within Emerald: `Brendan` for the male +trainer, and `May` for the female trainer. + +These sprites are separated in two categories: battle sprites and overworld sprites. The sprites' palettes must be +the same between battle sprites, and between overworld sprites, unless stated otherwise. + +#### Player Folder Palettes + +The palettes used for overworld sprites has some restrictions, as elements other than the player uses said palette: +- The arrow displayed when next to an exit from a sub-area (cave, dungeon) uses the color #10 from the palette, +- The exclamation mark displayed above trainers when they notice you before battling uses colors #15 and #16 from +the palette, +- The Pokémon you surf on in the overworld uses color #6 for its light shade, color #7 for its medium shade, and +color #16 for its dark shade, +- The Pokémon you fly on in the overworld uses color #6 for its light shade, color #7 for its medium shade, and +color #16 for its dark shade, + +For this reason, color #15 of the player's overworld palette must be white (255, 255, 255), and color #16 must be +black (0, 0, 0). + +#### Player Folder Sprites + +- `battle_back.png`: `Battle` sprite. This sprite replaces the animation used when the player is throwing a ball, +whether it's at the beginning of a battle, or in the Safari Zone + - Required sprite size: `64x64px` sprite with `4` OR `5` frames (`64x256px` OR `64x320px`) + - Required palette size: Exactly `16` colors + - If `4` frames are given, the player will use the `Emerald-style` ball throwing animation, and if `5` frames + are given, the player will use the `Firered/Leafgreen-style` ball thowing animation + - `Emerald-style` ball throwing animation: The last frame is the idle frame, the rest is the animation + - `Firered/Leafgreen-style` ball throwing animation: The first frame is the idle frame, the rest is the + animation +- `battle_front.png`: `Battle` sprite. This sprite replaces the sprite used when fighting your rival, at the +beginning and end of a battle, and the sprite used in the Trainer card. + - Required sprite size: `64x64px` sprite + - Required palette size: Exactly `16` colors +- `walking_running.png`: `Overworld` sprite. This sprite replaces the walking and running animations of the player +in the overworld. + - Required sprite size: `16x32px` sprite with `18` frames (`16x576px`) + - Required palette size: Exactly `16` colors, see [Player Folder Palettes](#player-folder-palettes) +- `reflection.png`: `Overworld` sprite. This sprite's palette is shown whenever the player stands in front of clear +water, in their reflection. + - Required sprite size: `16x32px` sprite with `18` frames (`16x576px`) + - Required palette size: Exactly `16` colors + - The palette must be a faded version of the overworld palette, to look like a reflection of the player in the + water +- `acro_bike.png`: `Overworld` sprite. This sprite replaces the Acro Bike animations of the player in the overworld. + - Required sprite size: `32x32px` sprite with `27` frames (`32x864px`) + - Required palette size: Exactly `16` colors, see [Player Folder Palettes](#player-folder-palettes) +- `mach_bike.png`: `Overworld` sprite. This sprite replaces the Mach Bike animations of the player in the overworld. + - Required sprite size: `32x32px` sprite with `9` frames (`32x288px`) + - Required palette size: Exactly `16` colors, see [Player Folder Palettes](#player-folder-palettes) +- `surfing.png`: `Overworld` sprite. This sprite replaces the surfing animations of the player in the overworld. + - Required sprite size: `32x32px` sprite with `12` frames (`32x384px`) + - Required palette size: Exactly `16` colors, see [Player Folder Palettes](#player-folder-palettes) +- `field_move.png`: `Overworld` sprite. This sprite replaces the animation used when the player uses an HM move in +the overworld such as Cut, Rock Smash or Strength. + - Required sprite size: `32x32px` sprite with `5` frames (`32x160px`) + - Required palette size: Exactly `16` colors, see [Player Folder Palettes](#player-folder-palettes) +- `underwater.png`: `Overworld` sprite. This sprite replaces the animation used when the player is swimming on a +Pokémon's back underwater. + - Required sprite size: `32x32px` sprite with `9` frames (`32x288px`) + - Required palette size: Exactly `16` colors. Since this palette is shared among both players, the existing + colors of the palette must be kept. Extract the player's sprites to get its palette, and only edit colors #2 + to #5, and colors #11 to #16 +- `fishing.png`: `Overworld` sprite. This sprite replaces the animation used when the player is fishing. + - Required sprite size: `32x32px` sprite with `12` frames (`32x384px`) + - Required palette size: Exactly `16` colors, see [Player Folder Palettes](#player-folder-palettes) +- `watering.png`: `Overworld` sprite. This sprite replaces the animation used when the player is watering berries. + - Required sprite size: `32x32px` sprite with `9` frames (`32x288px`) + - Required palette size: Exactly `16` colors, see [Player Folder Palettes](#player-folder-palettes) +- `decorating.png`: `Overworld` sprite. This sprite replaces the sprite used when the player is decorating their +secret base. + - Required sprite size: `16x32px` sprite + - Required palette size: Exactly `16` colors, see [Player Folder Palettes](#player-folder-palettes) + +#### Player Folder Sprite Size Override + +All overworld sprites frames can have a different size if you wish for your sprite to be bigger or smaller. In +order to change a sprite's size, you must add `-XxY` at the end of their file name, with `X` the width of the +sprite, and `Y` the height of the sprite. + +Currently, only three overworld sprite sizes are allowed: `16x16px`, `16x32px` and `32x32px`. + +For example, if you want the frames of the sprite `walking_running.png` to have a size of `32x32px`, then the +sprite must be named `walking_running-32x32.png`, and its size must be `32x576px`. + +## Pokémon Data Edition + +Once a sprite pack has been loaded into the adjuster, a `Sprite Preview` module will be added to it. It allows you +to preview the various sprites within the sprite pack, as well as their palette. + +If a valid ROM or AP patch have been given, then the `Pokémon Data Editor` module will appear. This module allows +you to edit some data related to the Pokémon in the current sprite pack. + +Here is a list of the values and their specifications: + +- HP: The Pokémon's base HP. Must be a number between 1 and 255. +- Attack: The Pokémon's base attack. Must be a number between 1 and 255. +- Defense: The Pokémon's base defense. Must be a number between 1 and 255. +- Sp. Attack: The Pokémon's base special attack. Must be a number between 1 and 255. +- Sp. Defense: The Pokémon's base special defense. Must be a number between 1 and 255. +- Speed: The Pokémon's base speed. Must be a number between 1 and 255. +- Type 1: The Pokémon's first type. Select a value within the given list. +- Type 2: The Pokémon's second type. Select a value within the given list. Make it match the first type if you want +the Pokémon to only have one type. +- Ability 1: The Pokémon's first ability. Select a value within the given list. +- Ability 2: The Pokémon's second ability. Select a value within the given list. Make it match the first ability if +you want the Pokémon to only have one ability. +- Gender Ratio: The Pokémon's gender ratio. Select a value within the given list. +- Forbid Flip: Dictates whether the Pokémon's sprite can be flipped or not when looking at the Pokémon's status +screen in your team. The sprite can't be flipped if the option is ticked, otherwise it can be flipped. +- Move Pool: The Pokémon's level up learnset. Each line must contain a move. Each move must be written in the +format `: `, with `` a known Pokémon move from this generation, and `` a number between 1 +and 100. + +**Warning:** Some of these values may overwrite randomization options selected in Archipelago: if the +Pokémon's base stats or level up move pool have been randomized, the adjuster will replace the randomized values +with its values. + +Hovering over a field's name will tell you more details about what kind of value it needs. Additionally, if the value's +text is red, blue or in bold, it will tell you exactly why. + +Saving any changes for the Pokémon's data will create a file named `data.txt` in the Pokémon's folder. The contents of +the file should not be modified manually. + +## Applying the Sprite Pack + +Once both a ROM (or AP patch) and a sprite pack have been passed to the adjuster, you can press the `Adjust ROM` +button and a new ROM will be made from the patch application, whih is usable as-is. + +In order to use this ROM instead of the standard AP-patched ROM with Archipelago, once BizHawk or any other +emulator is running, you should open the ROM made from the adjuster instead of the original one. Normally, the ROM +made by the adjuster should have the same name as the ROM or AP patch you passed to it, with `-adjusted` added at +the end of its name. diff --git a/worlds/pokemon_emerald/docs/icon_palette_0.pal b/worlds/pokemon_emerald/docs/icon_palette_0.pal new file mode 100644 index 000000000000..48a835b0db32 --- /dev/null +++ b/worlds/pokemon_emerald/docs/icon_palette_0.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +98 156 131 +131 131 115 +189 189 189 +255 255 255 +189 164 65 +246 246 41 +213 98 65 +246 148 41 +139 123 255 +98 74 205 +238 115 156 +255 180 164 +164 197 255 +106 172 156 +98 98 90 +65 65 65 diff --git a/worlds/pokemon_emerald/docs/icon_palette_1.pal b/worlds/pokemon_emerald/docs/icon_palette_1.pal new file mode 100644 index 000000000000..261ea164d941 --- /dev/null +++ b/worlds/pokemon_emerald/docs/icon_palette_1.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +98 156 131 +115 115 115 +189 189 189 +255 255 255 +123 156 74 +156 205 74 +148 246 74 +238 115 156 +246 148 246 +189 164 90 +246 230 41 +246 246 172 +213 213 106 +230 74 41 +98 98 90 +65 65 65 diff --git a/worlds/pokemon_emerald/docs/icon_palette_2.pal b/worlds/pokemon_emerald/docs/icon_palette_2.pal new file mode 100644 index 000000000000..30463baeb10d --- /dev/null +++ b/worlds/pokemon_emerald/docs/icon_palette_2.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +98 156 131 +123 123 123 +189 189 180 +255 255 255 +115 115 205 +164 172 246 +180 131 90 +238 197 139 +197 172 41 +246 246 41 +246 98 82 +148 123 205 +197 164 205 +189 41 156 +98 98 90 +65 65 65 From 2359cceb64075c684e1c45a5a831aafab8ec63f2 Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Mon, 1 Sep 2025 21:29:31 -0600 Subject: [PATCH 0687/1218] AHiT: Add Death Link amnesty options (#4694) * Add basic death link amnesty option * Add death wish amnesty option --- worlds/ahit/Options.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/worlds/ahit/Options.py b/worlds/ahit/Options.py index ab6ba46f19f3..981480970dd2 100644 --- a/worlds/ahit/Options.py +++ b/worlds/ahit/Options.py @@ -623,6 +623,23 @@ class ParadeTrapWeight(Range): default = 20 +class DeathLinkAmnesty(Range): + """Amount of forgiven deaths before sending a Death Link. + 0 means that every death will send a Death Link.""" + display_name = "Death Link Amnesty" + range_start = 0 + range_end = 20 + default = 0 + + +class DWDeathLinkAmnesty(Range): + """Amount of forgiven deaths before sending a Death Link during Death Wish levels.""" + display_name = "Death Wish Amnesty" + range_start = 0 + range_end = 30 + default = 5 + + @dataclass class AHITOptions(PerGameCommonOptions): start_inventory_from_pool: StartInventoryPool @@ -700,6 +717,8 @@ class AHITOptions(PerGameCommonOptions): ParadeTrapWeight: ParadeTrapWeight death_link: DeathLink + death_link_amnesty: DeathLinkAmnesty + dw_death_link_amnesty: DWDeathLinkAmnesty ahit_option_groups: Dict[str, List[Any]] = { @@ -769,4 +788,6 @@ class AHITOptions(PerGameCommonOptions): "MaxPonCost", "death_link", + "death_link_amnesty", + "dw_death_link_amnesty", ] From 5f1835c546be4866370c72f9235c2765ac3cac50 Mon Sep 17 00:00:00 2001 From: Ziktofel Date: Tue, 2 Sep 2025 17:40:58 +0200 Subject: [PATCH 0688/1218] SC2: Content update (#5312) Feature highlights: - Adds many content to the SC2 game - Allows custom mission order - Adds race-swapped missions for build missions (except Epilogue and NCO) - Allows War Council Nerfs (Protoss units can get pre - War Council State, alternative units get another custom nerf to match the power level of base units) - Revamps Predator's upgrade tree (never was considered strategically important) - Adds some units and upgrades - Locked and excluded items can specify quantity - Key mode (if opt-in, missions require keys to be unlocked on top of their regular regular requirements - Victory caches - Victory locations can grant multiple items to the multiworld instead of one - The generator is more resilient for generator failures as it validates logic for item excludes - Fixes the following issues: - https://github.com/ArchipelagoMW/Archipelago/issues/3531 - https://github.com/ArchipelagoMW/Archipelago/issues/3548 --- Starcraft2Client.py | 4 +- WebHostLib/static/assets/sc2Tracker.js | 82 +- WebHostLib/static/styles/sc2Tracker.css | 355 +- WebHostLib/static/styles/sc2TrackerAtlas.css | 3965 +++++ WebHostLib/templates/tracker__Starcraft2.html | 3334 ++-- WebHostLib/tracker.py | 1285 +- worlds/LauncherComponents.py | 2 - worlds/_sc2common/bot/game_data.py | 4 +- worlds/sc2/Client.py | 1630 -- worlds/sc2/ClientGui.py | 306 - worlds/sc2/ItemGroups.py | 100 - worlds/sc2/ItemNames.py | 661 - worlds/sc2/Items.py | 2554 --- worlds/sc2/Locations.py | 1635 -- worlds/sc2/MissionTables.py | 739 - worlds/sc2/Options.py | 908 - worlds/sc2/PoolFilter.py | 661 - worlds/sc2/Regions.py | 691 - worlds/sc2/Rules.py | 952 -- worlds/sc2/Starcraft2.kv | 28 - worlds/sc2/__init__.py | 1285 +- worlds/sc2/client.py | 2352 +++ worlds/sc2/client_gui.py | 655 + worlds/sc2/docs/contributors.md | 53 +- worlds/sc2/docs/custom_mission_orders_en.md | 1092 ++ worlds/sc2/docs/en_Starcraft 2.md | 35 +- worlds/sc2/docs/fr_Starcraft 2.md | 6 +- worlds/sc2/docs/setup_en.md | 132 +- worlds/sc2/docs/setup_fr.md | 2 +- worlds/sc2/gui_config.py | 98 + worlds/sc2/item/__init__.py | 173 + worlds/sc2/item/item_annotations.py | 178 + worlds/sc2/item/item_descriptions.py | 1127 ++ worlds/sc2/item/item_groups.py | 902 + worlds/sc2/item/item_names.py | 957 ++ worlds/sc2/item/item_parents.py | 266 + worlds/sc2/item/item_tables.py | 2415 +++ worlds/sc2/item/parent_names.py | 57 + worlds/sc2/location_groups.py | 40 + worlds/sc2/locations.py | 14175 ++++++++++++++++ worlds/sc2/mission_groups.py | 194 + worlds/sc2/mission_order/__init__.py | 66 + worlds/sc2/mission_order/entry_rules.py | 389 + worlds/sc2/mission_order/generation.py | 702 + worlds/sc2/mission_order/layout_types.py | 620 + worlds/sc2/mission_order/mission_pools.py | 251 + worlds/sc2/mission_order/nodes.py | 606 + worlds/sc2/mission_order/options.py | 472 + worlds/sc2/mission_order/presets_scripted.py | 164 + worlds/sc2/mission_order/presets_static.py | 916 + worlds/sc2/mission_order/slot_data.py | 53 + worlds/sc2/mission_tables.py | 577 + worlds/sc2/options.py | 1746 ++ worlds/sc2/pool_filter.py | 493 + worlds/sc2/regions.py | 532 + worlds/sc2/rules.py | 3582 ++++ worlds/sc2/settings.py | 49 + worlds/sc2/starcraft2.kv | 61 + worlds/sc2/test/test_Regions.py | 41 - worlds/sc2/test/test_base.py | 47 +- worlds/sc2/test/test_custom_mission_orders.py | 216 + worlds/sc2/test/test_generation.py | 1228 ++ worlds/sc2/test/test_item_filtering.py | 88 + worlds/sc2/test/test_itemdescriptions.py | 18 + worlds/sc2/test/test_itemgroups.py | 32 + worlds/sc2/test/test_items.py | 170 + worlds/sc2/test/test_location_groups.py | 37 + worlds/sc2/test/test_mission_groups.py | 9 + worlds/sc2/test/test_options.py | 20 +- worlds/sc2/test/test_regions.py | 40 + worlds/sc2/test/test_rules.py | 186 + worlds/sc2/test/test_usecases.py | 492 + worlds/sc2/transfer_data.py | 38 + 73 files changed, 46372 insertions(+), 13659 deletions(-) create mode 100644 WebHostLib/static/styles/sc2TrackerAtlas.css delete mode 100644 worlds/sc2/Client.py delete mode 100644 worlds/sc2/ClientGui.py delete mode 100644 worlds/sc2/ItemGroups.py delete mode 100644 worlds/sc2/ItemNames.py delete mode 100644 worlds/sc2/Items.py delete mode 100644 worlds/sc2/Locations.py delete mode 100644 worlds/sc2/MissionTables.py delete mode 100644 worlds/sc2/Options.py delete mode 100644 worlds/sc2/PoolFilter.py delete mode 100644 worlds/sc2/Regions.py delete mode 100644 worlds/sc2/Rules.py delete mode 100644 worlds/sc2/Starcraft2.kv create mode 100644 worlds/sc2/client.py create mode 100644 worlds/sc2/client_gui.py create mode 100644 worlds/sc2/docs/custom_mission_orders_en.md create mode 100644 worlds/sc2/gui_config.py create mode 100644 worlds/sc2/item/__init__.py create mode 100644 worlds/sc2/item/item_annotations.py create mode 100644 worlds/sc2/item/item_descriptions.py create mode 100644 worlds/sc2/item/item_groups.py create mode 100644 worlds/sc2/item/item_names.py create mode 100644 worlds/sc2/item/item_parents.py create mode 100644 worlds/sc2/item/item_tables.py create mode 100644 worlds/sc2/item/parent_names.py create mode 100644 worlds/sc2/location_groups.py create mode 100644 worlds/sc2/locations.py create mode 100644 worlds/sc2/mission_groups.py create mode 100644 worlds/sc2/mission_order/__init__.py create mode 100644 worlds/sc2/mission_order/entry_rules.py create mode 100644 worlds/sc2/mission_order/generation.py create mode 100644 worlds/sc2/mission_order/layout_types.py create mode 100644 worlds/sc2/mission_order/mission_pools.py create mode 100644 worlds/sc2/mission_order/nodes.py create mode 100644 worlds/sc2/mission_order/options.py create mode 100644 worlds/sc2/mission_order/presets_scripted.py create mode 100644 worlds/sc2/mission_order/presets_static.py create mode 100644 worlds/sc2/mission_order/slot_data.py create mode 100644 worlds/sc2/mission_tables.py create mode 100644 worlds/sc2/options.py create mode 100644 worlds/sc2/pool_filter.py create mode 100644 worlds/sc2/regions.py create mode 100644 worlds/sc2/rules.py create mode 100644 worlds/sc2/settings.py create mode 100644 worlds/sc2/starcraft2.kv delete mode 100644 worlds/sc2/test/test_Regions.py create mode 100644 worlds/sc2/test/test_custom_mission_orders.py create mode 100644 worlds/sc2/test/test_generation.py create mode 100644 worlds/sc2/test/test_item_filtering.py create mode 100644 worlds/sc2/test/test_itemdescriptions.py create mode 100644 worlds/sc2/test/test_itemgroups.py create mode 100644 worlds/sc2/test/test_items.py create mode 100644 worlds/sc2/test/test_location_groups.py create mode 100644 worlds/sc2/test/test_mission_groups.py create mode 100644 worlds/sc2/test/test_regions.py create mode 100644 worlds/sc2/test/test_rules.py create mode 100644 worlds/sc2/test/test_usecases.py create mode 100644 worlds/sc2/transfer_data.py diff --git a/Starcraft2Client.py b/Starcraft2Client.py index fb219a690460..14e1832074a4 100644 --- a/Starcraft2Client.py +++ b/Starcraft2Client.py @@ -3,9 +3,11 @@ import ModuleUpdate ModuleUpdate.update() -from worlds.sc2.Client import launch +from worlds.sc2.client import launch import Utils +# This is deprecated, replaced with the client hooked from the Launcher +# Will be removed in a following release if __name__ == "__main__": Utils.init_logging("Starcraft2Client", exception_logger="Client") launch() diff --git a/WebHostLib/static/assets/sc2Tracker.js b/WebHostLib/static/assets/sc2Tracker.js index 30d4acd60b7e..19cff21c0fa2 100644 --- a/WebHostLib/static/assets/sc2Tracker.js +++ b/WebHostLib/static/assets/sc2Tracker.js @@ -1,49 +1,43 @@ -window.addEventListener('load', () => { - // Reload tracker every 15 seconds - const url = window.location; - setInterval(() => { - const ajax = new XMLHttpRequest(); - ajax.onreadystatechange = () => { - if (ajax.readyState !== 4) { return; } +let updateSection = (sectionName, fakeDOM) => { + document.getElementById(sectionName).innerHTML = fakeDOM.getElementById(sectionName).innerHTML; +} - // Create a fake DOM using the returned HTML - const domParser = new DOMParser(); - const fakeDOM = domParser.parseFromString(ajax.responseText, 'text/html'); +window.addEventListener('load', () => { + // Reload tracker every 60 seconds (sync'd) + const url = window.location; + // Note: This synchronization code is adapted from code in trackerCommon.js + const targetSecond = parseInt(document.getElementById('player-tracker').getAttribute('data-second')) + 3; + console.log("Target second of refresh: " + targetSecond); - // Update item tracker - document.getElementById('inventory-table').innerHTML = fakeDOM.getElementById('inventory-table').innerHTML; - // Update only counters in the location-table - let counters = document.getElementsByClassName('counter'); - const fakeCounters = fakeDOM.getElementsByClassName('counter'); - for (let i = 0; i < counters.length; i++) { - counters[i].innerHTML = fakeCounters[i].innerHTML; - } + let getSleepTimeSeconds = () => { + // -40 % 60 is -40, which is absolutely wrong and should burn + var sleepSeconds = (((targetSecond - new Date().getSeconds()) % 60) + 60) % 60; + return sleepSeconds || 60; }; - ajax.open('GET', url); - ajax.send(); - }, 15000) - // Collapsible advancement sections - const categories = document.getElementsByClassName("location-category"); - for (let category of categories) { - let hide_id = category.id.split('_')[0]; - if (hide_id === 'Total') { - continue; - } - category.addEventListener('click', function() { - // Toggle the advancement list - document.getElementById(hide_id).classList.toggle("hide"); - // Change text of the header - const tab_header = document.getElementById(hide_id+'_header').children[0]; - const orig_text = tab_header.innerHTML; - let new_text; - if (orig_text.includes("▼")) { - new_text = orig_text.replace("▼", "▲"); - } - else { - new_text = orig_text.replace("▲", "▼"); - } - tab_header.innerHTML = new_text; - }); - } + let updateTracker = () => { + const ajax = new XMLHttpRequest(); + ajax.onreadystatechange = () => { + if (ajax.readyState !== 4) { return; } + + // Create a fake DOM using the returned HTML + const domParser = new DOMParser(); + const fakeDOM = domParser.parseFromString(ajax.responseText, 'text/html'); + + // Update dynamic sections + updateSection('player-info', fakeDOM); + updateSection('section-filler', fakeDOM); + updateSection('section-terran', fakeDOM); + updateSection('section-zerg', fakeDOM); + updateSection('section-protoss', fakeDOM); + updateSection('section-nova', fakeDOM); + updateSection('section-kerrigan', fakeDOM); + updateSection('section-keys', fakeDOM); + updateSection('section-locations', fakeDOM); + }; + ajax.open('GET', url); + ajax.send(); + updater = setTimeout(updateTracker, getSleepTimeSeconds() * 1000); + }; + window.updater = setTimeout(updateTracker, getSleepTimeSeconds() * 1000); }); diff --git a/WebHostLib/static/styles/sc2Tracker.css b/WebHostLib/static/styles/sc2Tracker.css index 29a719a110c8..3048213e43cb 100644 --- a/WebHostLib/static/styles/sc2Tracker.css +++ b/WebHostLib/static/styles/sc2Tracker.css @@ -1,160 +1,279 @@ -#player-tracker-wrapper{ - margin: 0; +*{ + margin: 0; + font-family: "JuraBook", monospace; } - -#tracker-table td { - vertical-align: top; +body{ + --icon-size: 36px; + --item-class-padding: 4px; } - -.inventory-table-area{ - border: 2px solid #000000; - border-radius: 4px; - padding: 3px 10px 3px 10px; +a{ + color: #1ae; } -.inventory-table-area:has(.inventory-table-terran) { - width: 690px; - background-color: #525494; +/* Section colours */ +#player-info{ + background-color: #37a; } - -.inventory-table-area:has(.inventory-table-zerg) { - width: 360px; - background-color: #9d60d2; +.player-tracker{ + max-width: 100%; } - -.inventory-table-area:has(.inventory-table-protoss) { - width: 400px; - background-color: #d2b260; +.tracker-section{ + background-color: grey; } - -#tracker-table .inventory-table td{ - width: 40px; - height: 40px; - text-align: center; - vertical-align: middle; +#terran-items{ + background-color: #3a7; } - -.inventory-table td.title{ - padding-top: 10px; - height: 20px; - font-family: "JuraBook", monospace; - font-size: 16px; - font-weight: bold; +#zerg-items{ + background-color: #d94; } - -.inventory-table img{ - height: 100%; - max-width: 40px; - max-height: 40px; - border: 1px solid #000000; - filter: grayscale(100%) contrast(75%) brightness(20%); - background-color: black; +#protoss-items{ + background-color: #37a; } - -.inventory-table img.acquired{ - filter: none; - background-color: black; +#nova-items{ + background-color: #777; } - -.inventory-table .tint-terran img.acquired { - filter: sepia(100%) saturate(300%) brightness(130%) hue-rotate(120deg) +#kerrigan-items{ + background-color: #a37; } - -.inventory-table .tint-protoss img.acquired { - filter: sepia(100%) saturate(1000%) brightness(110%) hue-rotate(180deg) +#keys{ + background-color: #aa2; } -.inventory-table .tint-level-1 img.acquired { - filter: sepia(100%) saturate(1000%) brightness(110%) hue-rotate(60deg) +/* Sections */ +.section-body{ + display: flex; + flex-flow: row wrap; + justify-content: flex-start; + align-items: flex-start; + padding-bottom: 3px; } - -.inventory-table .tint-level-2 img.acquired { - filter: sepia(100%) saturate(1000%) brightness(110%) hue-rotate(60deg) hue-rotate(120deg) +.section-body-2{ + display: flex; + flex-direction: column; } - -.inventory-table .tint-level-3 img.acquired { - filter: sepia(100%) saturate(1000%) brightness(110%) hue-rotate(60deg) hue-rotate(240deg) +.tracker-section:has(input.collapse-section[type=checkbox]:checked) .section-body, +.tracker-section:has(input.collapse-section[type=checkbox]:checked) .section-body-2{ + display: none; } - -.inventory-table div.counted-item { - position: relative; +.section-title{ + position: relative; + border-bottom: 3px solid black; + /* Prevent text selection */ + user-select: none; + -webkit-user-select: none; + -ms-user-select: none; } - -.inventory-table div.item-count { - width: 160px; - text-align: left; - color: black; - font-family: "JuraBook", monospace; - font-weight: bold; +input[type="checkbox"]{ + position: absolute; + cursor: pointer; + opacity: 0; + z-index: 1; + width: 100%; + height: 100%; } - -#location-table{ - border: 2px solid #000000; - border-radius: 4px; - background-color: #87b678; - padding: 10px 3px 3px; - font-family: "JuraBook", monospace; - font-size: 16px; - font-weight: bold; - cursor: default; +.section-title:hover h2{ + text-shadow: 0 0 4px #ddd; } - -#location-table table{ - width: 100%; +.f { + display: flex; + overflow: hidden; } -#location-table th{ - vertical-align: middle; - text-align: left; - padding-right: 10px; +/* Acquire item filters */ +.tracker-section img{ + height: 100%; + width: var(--icon-size); + height: var(--icon-size); + background-color: black; } - -#location-table td{ - padding-top: 2px; - padding-bottom: 2px; - line-height: 20px; +.unacquired, .lvl-0 .f{ + filter: grayscale(100%) contrast(80%) brightness(42%) blur(0.5px); } - -#location-table td.counter { - text-align: right; - font-size: 14px; +.spacer{ + width: var(--icon-size); + height: var(--icon-size); } -#location-table td.toggle-arrow { - text-align: right; +/* Item groups */ +.item-class{ + display: flex; + flex-flow: column; + justify-content: center; + padding: var(--item-class-padding); } - -#location-table tr#Total-header { - font-weight: bold; +.item-class-header{ + display: flex; + flex-flow: row; +} +.item-class-upgrades{ + /* Note: {display: flex; flex-flow: column wrap} */ + /* just breaks on Firefox (width does not scale to content) */ + display: grid; + grid-template-rows: repeat(4, auto); + grid-auto-flow: column; } -#location-table img{ - height: 100%; - max-width: 30px; - max-height: 30px; +/* Subsections */ +.section-toc{ + display: flex; + flex-direction: row; +} +.toc-box{ + position: relative; + padding-left: 15px; + padding-right: 15px; +} +.toc-box:hover{ + text-shadow: 0 0 7px white; +} +.ss-header{ + position: relative; + text-align: center; + writing-mode: sideways-lr; + user-select: none; + padding-top: 5px; + font-size: 115%; +} +.tracker-section:has(input.ss-1-toggle:checked) .ss-1{ + display: none; +} +.tracker-section:has(input.ss-2-toggle:checked) .ss-2{ + display: none; +} +.tracker-section:has(input.ss-3-toggle:checked) .ss-3{ + display: none; +} +.tracker-section:has(input.ss-4-toggle:checked) .ss-4{ + display: none; +} +.tracker-section:has(input.ss-5-toggle:checked) .ss-5{ + display: none; +} +.tracker-section:has(input.ss-6-toggle:checked) .ss-6{ + display: none; +} +.tracker-section:has(input.ss-7-toggle:checked) .ss-7{ + display: none; +} +.tracker-section:has(input.ss-1-toggle:hover) .ss-1{ + background-color: #fff5; + box-shadow: 0 0 1px 1px white; +} +.tracker-section:has(input.ss-2-toggle:hover) .ss-2{ + background-color: #fff5; + box-shadow: 0 0 1px 1px white; +} +.tracker-section:has(input.ss-3-toggle:hover) .ss-3{ + background-color: #fff5; + box-shadow: 0 0 1px 1px white; +} +.tracker-section:has(input.ss-4-toggle:hover) .ss-4{ + background-color: #fff5; + box-shadow: 0 0 1px 1px white; +} +.tracker-section:has(input.ss-5-toggle:hover) .ss-5{ + background-color: #fff5; + box-shadow: 0 0 1px 1px white; +} +.tracker-section:has(input.ss-6-toggle:hover) .ss-6{ + background-color: #fff5; + box-shadow: 0 0 1px 1px white; +} +.tracker-section:has(input.ss-7-toggle:hover) .ss-7{ + background-color: #fff5; + box-shadow: 0 0 1px 1px white; } -#location-table tbody.locations { - font-size: 16px; +/* Progressive items */ +.progressive{ + max-height: var(--icon-size); + display: contents; } -#location-table td.location-name { - padding-left: 16px; +.lvl-0 > :nth-child(2), +.lvl-0 > :nth-child(3), +.lvl-0 > :nth-child(4), +.lvl-0 > :nth-child(5){ + display: none; +} +.lvl-1 > :nth-child(2), +.lvl-1 > :nth-child(3), +.lvl-1 > :nth-child(4), +.lvl-1 > :nth-child(5){ + display: none; +} +.lvl-2 > :nth-child(1), +.lvl-2 > :nth-child(3), +.lvl-2 > :nth-child(4), +.lvl-2 > :nth-child(5){ + display: none; +} +.lvl-3 > :nth-child(1), +.lvl-3 > :nth-child(2), +.lvl-3 > :nth-child(4), +.lvl-3 > :nth-child(5){ + display: none; +} +.lvl-4 > :nth-child(1), +.lvl-4 > :nth-child(2), +.lvl-4 > :nth-child(3), +.lvl-4 > :nth-child(5){ + display: none; +} +.lvl-5 > :nth-child(1), +.lvl-5 > :nth-child(2), +.lvl-5 > :nth-child(3), +.lvl-5 > :nth-child(4){ + display: none; } -#location-table td:has(.location-column) { - vertical-align: top; +/* Filler item counters */ +.item-counter{ + display: table; + text-align: center; + padding: var(--item-class-padding); +} +.item-count{ + display: table-cell; + vertical-align: middle; + padding-left: 3px; + padding-right: 15px; } -#location-table .location-column { - width: 100%; - height: 100%; +/* Hidden items */ +.hidden-class:not(:has(img.acquired)){ + display: none; +} +.hidden-item:not(.acquired){ + display:none; } -#location-table .location-column .spacer { - min-height: 24px; +/* Keys */ +#keys ol, #keys ul{ + columns: 3; + -webkit-columns: 3; + -moz-columns: 3; +} +#keys li{ + padding-right: 15pt; } -.hide { - display: none; +/* Locations */ +#section-locations{ + padding-left: 5px; } +@media only screen and (min-width: 120ch){ + #section-locations ul{ + columns: 2; + -webkit-columns: 2; + -moz-columns: 2; + } +} +#locations li.checked{ + list-style-type: "✔ "; +} + +/* Allowing scrolling down a little further */ +.bottom-padding{ + min-height: 33vh; +} \ No newline at end of file diff --git a/WebHostLib/static/styles/sc2TrackerAtlas.css b/WebHostLib/static/styles/sc2TrackerAtlas.css new file mode 100644 index 000000000000..7fc8746f6f90 --- /dev/null +++ b/WebHostLib/static/styles/sc2TrackerAtlas.css @@ -0,0 +1,3965 @@ +.abilityicon_spawnbanelings_square-png{ + clip-path: xywh(0 0.0% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 49.93694829760403%); +} + +.abilityicon_spawnbroodlings_square-png{ + clip-path: xywh(0 0.12610340479192939% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 49.810844892812106%); +} + +.biomassrecovery_coop-png{ + clip-path: xywh(0 0.25220680958385877% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 49.68474148802018%); +} + +.btn-ability-dehaka-airbonusdamage-png{ + clip-path: xywh(0 0.37831021437578816% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 49.558638083228246%); +} + +.btn-ability-hornerhan-fleethyperjump-png{ + clip-path: xywh(0 0.5044136191677175% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 49.43253467843632%); +} + +.btn-ability-hornerhan-raven-analyzetarget-png{ + clip-path: xywh(0 0.6305170239596469% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 49.306431273644385%); +} + +.btn-ability-hornerhan-reaper-flightmode-png{ + clip-path: xywh(0 0.7566204287515763% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 49.18032786885246%); +} + +.btn-ability-hornerhan-salvagebonus-png{ + clip-path: xywh(0 0.8827238335435057% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 49.05422446406053%); +} + +.btn-ability-hornerhan-viking-missileupgrade-png{ + clip-path: xywh(0 1.008827238335435% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 48.9281210592686%); +} + +.btn-ability-hornerhan-viking-piercingattacks-png{ + clip-path: xywh(0 1.1349306431273645% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 48.80201765447667%); +} + +.btn-ability-hornerhan-widowmine-attackrange-png{ + clip-path: xywh(0 1.2610340479192939% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 48.675914249684745%); +} + +.btn-ability-hornerhan-widowmine-deathblossom-png{ + clip-path: xywh(0 1.3871374527112232% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 48.54981084489281%); +} + +.btn-ability-hornerhan-wraith-attackspeed-png{ + clip-path: xywh(0 1.5132408575031526% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 48.423707440100884%); +} + +.btn-ability-kerrigan-abilityefficiency-png{ + clip-path: xywh(0 1.639344262295082% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 48.29760403530895%); +} + +.btn-ability-kerrigan-apocalypse-png{ + clip-path: xywh(0 1.7654476670870114% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 48.17150063051702%); +} + +.btn-ability-kerrigan-automatedextractors-png{ + clip-path: xywh(0 1.8915510718789408% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 48.0453972257251%); +} + +.btn-ability-kerrigan-broodlingnest-png{ + clip-path: xywh(0 2.01765447667087% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 47.91929382093316%); +} + +.btn-ability-kerrigan-droppods-png{ + clip-path: xywh(0 2.1437578814627996% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 47.793190416141236%); +} + +.btn-ability-kerrigan-fury-png{ + clip-path: xywh(0 2.269861286254729% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 47.66708701134931%); +} + +.btn-ability-kerrigan-heroicfortitude-png{ + clip-path: xywh(0 2.3959646910466583% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 47.540983606557376%); +} + +.btn-ability-kerrigan-improvedoverlords-png{ + clip-path: xywh(0 2.5220680958385877% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 47.41488020176545%); +} + +.btn-ability-kerrigan-kineticblast-png{ + clip-path: xywh(0 2.648171500630517% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 47.288776796973515%); +} + +.btn-ability-kerrigan-leapingstrike-png{ + clip-path: xywh(0 2.7742749054224465% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 47.16267339218159%); +} + +.btn-ability-kerrigan-malignantcreep-png{ + clip-path: xywh(0 2.900378310214376% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 47.03656998738966%); +} + +.btn-ability-kerrigan-psychicshift-png{ + clip-path: xywh(0 3.0264817150063053% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 46.91046658259773%); +} + +.btn-ability-kerrigan-revive-png{ + clip-path: xywh(0 3.1525851197982346% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 46.7843631778058%); +} + +.btn-ability-kerrigan-twindrones-png{ + clip-path: xywh(0 3.278688524590164% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 46.658259773013874%); +} + +.btn-ability-kerrigan-vespeneefficiency-png{ + clip-path: xywh(0 3.4047919293820934% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 46.53215636822194%); +} + +.btn-ability-kerrigan-wildmutation-png{ + clip-path: xywh(0 3.530895334174023% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 46.406052963430014%); +} + +.btn-ability-kerrigan-zerglingreconstitution-png{ + clip-path: xywh(0 3.656998738965952% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 46.27994955863808%); +} + +.btn-ability-mengsk-battlecruiser-decksights-png{ + clip-path: xywh(0 3.7831021437578816% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 46.15384615384615%); +} + +.btn-ability-mengsk-ghost-pyrokineticimmolation_orange-png{ + clip-path: xywh(0 3.909205548549811% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 46.02774274905423%); +} + +.btn-ability-mengsk-ghost-staticempblast-png{ + clip-path: xywh(0 4.03530895334174% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 45.90163934426229%); +} + +.btn-ability-mengsk-ghost-tacticalmissilestrike-png{ + clip-path: xywh(0 4.16141235813367% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 45.775535939470366%); +} + +.btn-ability-mengsk-medivac-doublehealbeam-png{ + clip-path: xywh(0 4.287515762925599% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 45.64943253467844%); +} + +.btn-ability-mengsk-medivac-igniteafterburners-png{ + clip-path: xywh(0 4.4136191677175285% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 45.523329129886505%); +} + +.btn-ability-mengsk-siegetank-flyingtankarmament-png{ + clip-path: xywh(0 4.539722572509458% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 45.39722572509458%); +} + +.btn-ability-mengsk-viking-speed-png{ + clip-path: xywh(0 4.665825977301387% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 45.27112232030265%); +} + +.btn-ability-nova-domination-png{ + clip-path: xywh(0 4.791929382093317% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 45.14501891551072%); +} + +.btn-ability-protoss-adept-spiritform-png{ + clip-path: xywh(0 4.918032786885246% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 45.01891551071879%); +} + +.btn-ability-protoss-astralwind-png{ + clip-path: xywh(0 5.044136191677175% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 44.89281210592686%); +} + +.btn-ability-protoss-barrier-upgraded-png{ + clip-path: xywh(0 5.170239596469105% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 44.76670870113493%); +} + +.btn-ability-protoss-blink-color-png{ + clip-path: xywh(0 5.296343001261034% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 44.640605296343004%); +} + +.btn-ability-protoss-blinkshieldrestore-png{ + clip-path: xywh(0 5.422446406052964% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 44.51450189155107%); +} + +.btn-ability-protoss-carrierrepairdrones-png{ + clip-path: xywh(0 5.548549810844893% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 44.388398486759144%); +} + +.btn-ability-protoss-chargedblast-png{ + clip-path: xywh(0 5.674653215636822% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 44.26229508196721%); +} + +.btn-ability-protoss-coronabeam-png{ + clip-path: xywh(0 5.800756620428752% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 44.13619167717528%); +} + +.btn-ability-protoss-disintegration-png{ + clip-path: xywh(0 5.926860025220681% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 44.010088272383356%); +} + +.btn-ability-protoss-disruptionblast-png{ + clip-path: xywh(0 6.0529634300126105% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 43.88398486759142%); +} + +.btn-ability-protoss-doubleshieldrecharge-png{ + clip-path: xywh(0 6.17906683480454% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 43.757881462799496%); +} + +.btn-ability-protoss-dragoonchassis-png{ + clip-path: xywh(0 6.305170239596469% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 43.63177805800757%); +} + +.btn-ability-protoss-dualgravitonbeam-png{ + clip-path: xywh(0 6.431273644388399% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 43.505674653215635%); +} + +.btn-ability-protoss-entomb-png{ + clip-path: xywh(0 6.557377049180328% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 43.37957124842371%); +} + +.btn-ability-protoss-feedback-color-png{ + clip-path: xywh(0 6.683480453972257% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 43.25346784363178%); +} + +.btn-ability-protoss-firebeam-png{ + clip-path: xywh(0 6.809583858764187% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 43.12736443883985%); +} + +.btn-ability-protoss-forcefield-color-png{ + clip-path: xywh(0 6.935687263556116% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 43.00126103404792%); +} + +.btn-ability-protoss-forceofwill-png{ + clip-path: xywh(0 7.061790668348046% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 42.87515762925599%); +} + +.btn-ability-protoss-gravitonbeam-color-png{ + clip-path: xywh(0 7.187894073139975% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 42.74905422446406%); +} + +.btn-ability-protoss-hallucination-color-png{ + clip-path: xywh(0 7.313997477931904% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 42.622950819672134%); +} + +.btn-ability-protoss-lightningdash-png{ + clip-path: xywh(0 7.440100882723834% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 42.4968474148802%); +} + +.btn-ability-protoss-massrecall-png{ + clip-path: xywh(0 7.566204287515763% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 42.37074401008827%); +} + +.btn-ability-protoss-mindblast-png{ + clip-path: xywh(0 7.6923076923076925% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 42.24464060529634%); +} + +.btn-ability-protoss-oracle-stasiscalibration-png{ + clip-path: xywh(0 7.818411097099622% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 42.11853720050441%); +} + +.btn-ability-protoss-oraclepulsarcannonon-png{ + clip-path: xywh(0 7.944514501891551% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 41.992433795712486%); +} + +.btn-ability-protoss-phantomdash-png{ + clip-path: xywh(0 8.07061790668348% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 41.86633039092055%); +} + +.btn-ability-protoss-prismaticrange-png{ + clip-path: xywh(0 8.19672131147541% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 41.740226986128626%); +} + +.btn-ability-protoss-purify-png{ + clip-path: xywh(0 8.32282471626734% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 41.6141235813367%); +} + +.btn-ability-protoss-recallondeath-png{ + clip-path: xywh(0 8.448928121059268% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 41.488020176544765%); +} + +.btn-ability-protoss-reclamation-png{ + clip-path: xywh(0 8.575031525851198% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 41.36191677175284%); +} + +.btn-ability-protoss-shadowdash-png{ + clip-path: xywh(0 8.701134930643127% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 41.23581336696091%); +} + +.btn-ability-protoss-shadowfury-png{ + clip-path: xywh(0 8.827238335435057% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 41.10970996216898%); +} + +.btn-ability-protoss-shieldrecharge-png{ + clip-path: xywh(0 8.953341740226985% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 40.98360655737705%); +} + +.btn-ability-protoss-stasistrap-png{ + clip-path: xywh(0 9.079445145018916% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 40.85750315258512%); +} + +.btn-ability-protoss-supplicant-sacrificeon-png{ + clip-path: xywh(0 9.205548549810844% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 40.73139974779319%); +} + +.btn-ability-protoss-veilofshadowsvorazun-png{ + clip-path: xywh(0 9.331651954602775% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 40.60529634300126%); +} + +.btn-ability-protoss-voidstasis-png{ + clip-path: xywh(0 9.457755359394703% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 40.47919293820933%); +} + +.btn-ability-protoss-vulcanblaster-png{ + clip-path: xywh(0 9.583858764186633% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 40.3530895334174%); +} + +.btn-ability-protoss-warprelocatelvl2-png{ + clip-path: xywh(0 9.709962168978562% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 40.22698612862547%); +} + +.btn-ability-protoss-whirlwind-png{ + clip-path: xywh(0 9.836065573770492% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 40.10088272383354%); +} + +.btn-ability-spearofadun-chronomancy-png{ + clip-path: xywh(0 9.96216897856242% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 39.974779319041616%); +} + +.btn-ability-spearofadun-chronosurge-png{ + clip-path: xywh(0 10.08827238335435% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 39.84867591424968%); +} + +.btn-ability-spearofadun-deploypylon-png{ + clip-path: xywh(0 10.21437578814628% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 39.722572509457756%); +} + +.btn-ability-spearofadun-guardianshell-png{ + clip-path: xywh(0 10.34047919293821% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 39.59646910466583%); +} + +.btn-ability-spearofadun-massrecall-png{ + clip-path: xywh(0 10.466582597730138% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 39.470365699873895%); +} + +.btn-ability-spearofadun-matrixoverload-png{ + clip-path: xywh(0 10.592686002522068% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 39.34426229508197%); +} + +.btn-ability-spearofadun-nexusovercharge-png{ + clip-path: xywh(0 10.718789407313997% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 39.21815889029004%); +} + +.btn-ability-spearofadun-orbitalassimilator-png{ + clip-path: xywh(0 10.844892812105927% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 39.09205548549811%); +} + +.btn-ability-spearofadun-orbitalstrike-png{ + clip-path: xywh(0 10.970996216897856% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 38.96595208070618%); +} + +.btn-ability-spearofadun-purifierbeam-png{ + clip-path: xywh(0 11.097099621689786% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 38.83984867591425%); +} + +.btn-ability-spearofadun-reconstructionbeam-png{ + clip-path: xywh(0 11.223203026481714% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 38.71374527112232%); +} + +.btn-ability-spearofadun-shieldovercharge-png{ + clip-path: xywh(0 11.349306431273645% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 38.58764186633039%); +} + +.btn-ability-spearofadun-solarbombardment-png{ + clip-path: xywh(0 11.475409836065573% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 38.46153846153846%); +} + +.btn-ability-spearofadun-solarlance-png{ + clip-path: xywh(0 11.601513240857503% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 38.33543505674653%); +} + +.btn-ability-spearofadun-temporalfield-png{ + clip-path: xywh(0 11.727616645649432% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 38.2093316519546%); +} + +.btn-ability-spearofadun-timestop-png{ + clip-path: xywh(0 11.853720050441362% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 38.08322824716267%); +} + +.btn-ability-spearofadun-warpharmonization-png{ + clip-path: xywh(0 11.97982345523329% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 37.957124842370746%); +} + +.btn-ability-spearofadun-warpinreinforcements-png{ + clip-path: xywh(0 12.105926860025221% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 37.83102143757881%); +} + +.btn-ability-stetmann-banelingmanashield-png{ + clip-path: xywh(0 12.23203026481715% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 37.704918032786885%); +} + +.btn-ability-stetmann-corruptormissilebarrage-png{ + clip-path: xywh(0 12.35813366960908% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 37.57881462799496%); +} + +.btn-ability-stukov-plaugedmunitions-png{ + clip-path: xywh(0 12.484237074401008% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 37.452711223203025%); +} + +.btn-ability-swarm-kerrigan-chainreaction-png{ + clip-path: xywh(0 12.610340479192939% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 37.3266078184111%); +} + +.btn-ability-swarm-kerrigan-crushinggrip-png{ + clip-path: xywh(0 12.736443883984867% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 37.20050441361917%); +} + +.btn-ability-terran-calldownextrasupplies-color-png{ + clip-path: xywh(0 12.862547288776797% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 37.07440100882724%); +} + +.btn-ability-terran-cloak-color-png{ + clip-path: xywh(0 12.988650693568726% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 36.94829760403531%); +} + +.btn-ability-terran-detectionconedebuff-png{ + clip-path: xywh(0 13.114754098360656% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 36.82219419924338%); +} + +.btn-ability-terran-electricfield-png{ + clip-path: xywh(0 13.240857503152585% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 36.69609079445145%); +} + +.btn-ability-terran-emergencythrusters-png{ + clip-path: xywh(0 13.366960907944515% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 36.56998738965952%); +} + +.btn-ability-terran-emp-color-png{ + clip-path: xywh(0 13.493064312736443% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 36.44388398486759%); +} + +.btn-ability-terran-goliath-jetpack-png{ + clip-path: xywh(0 13.619167717528374% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 36.31778058007566%); +} + +.btn-ability-terran-hercules-tacticaljump-png{ + clip-path: xywh(0 13.745271122320302% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 36.19167717528373%); +} + +.btn-ability-terran-ignorearmor-png{ + clip-path: xywh(0 13.871374527112232% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 36.0655737704918%); +} + +.btn-ability-terran-liftoff-png{ + clip-path: xywh(0 13.997477931904161% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 35.939470365699876%); +} + +.btn-ability-terran-nuclearstrike-color-png{ + clip-path: xywh(0 14.123581336696091% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 35.81336696090794%); +} + +.btn-ability-terran-psidisruption-png{ + clip-path: xywh(0 14.24968474148802% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 35.687263556116015%); +} + +.btn-ability-terran-punishergrenade-color-png{ + clip-path: xywh(0 14.37578814627995% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 35.56116015132409%); +} + +.btn-ability-terran-restorationscbw-png{ + clip-path: xywh(0 14.501891551071878% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 35.435056746532155%); +} + +.btn-ability-terran-scannersweep-color-png{ + clip-path: xywh(0 14.627994955863809% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 35.30895334174023%); +} + +.btn-ability-terran-shreddermissile-color-png{ + clip-path: xywh(0 14.754098360655737% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 35.1828499369483%); +} + +.btn-ability-terran-spidermine-png{ + clip-path: xywh(0 14.880201765447667% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 35.05674653215637%); +} + +.btn-ability-terran-stimpack-color-png{ + clip-path: xywh(0 15.006305170239596% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 34.93064312736444%); +} + +.btn-ability-terran-unloadall-png{ + clip-path: xywh(0 15.132408575031526% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 34.80453972257251%); +} + +.btn-ability-terran-warpjump-png{ + clip-path: xywh(0 15.258511979823455% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 34.67843631778058%); +} + +.btn-ability-terran-widowminehidden-png{ + clip-path: xywh(0 15.384615384615385% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 34.552332912988646%); +} + +.btn-ability-thor-330mm-png{ + clip-path: xywh(0 15.510718789407314% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 34.42622950819672%); +} + +.btn-ability-tychus-herc-heavyimpact-png{ + clip-path: xywh(0 15.636822194199244% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 34.30012610340479%); +} + +.btn-ability-tychus-medivac-png{ + clip-path: xywh(0 15.762925598991172% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 34.17402269861286%); +} + +.btn-ability-zeratul-avatarofform-psionicblast-png{ + clip-path: xywh(0 15.889029003783103% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 34.04791929382093%); +} + +.btn-ability-zeratul-chargedcrystal-psionicwinds-png{ + clip-path: xywh(0 16.01513240857503% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 33.921815889029006%); +} + +.btn-ability-zeratul-darkarchon-maelstrom-png{ + clip-path: xywh(0 16.14123581336696% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 33.79571248423707%); +} + +.btn-ability-zeratul-immortal-forcecannon-png{ + clip-path: xywh(0 16.26733921815889% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 33.669609079445145%); +} + +.btn-ability-zeratul-observer-sensorarray-png{ + clip-path: xywh(0 16.39344262295082% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 33.54350567465322%); +} + +.btn-ability-zeratul-topbar-serdathlegion-png{ + clip-path: xywh(0 16.51954602774275% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 33.417402269861284%); +} + +.btn-ability-zerg-abathur-corrosivebilelarge-png{ + clip-path: xywh(0 16.64564943253468% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 33.29129886506936%); +} + +.btn-ability-zerg-acidspores-png{ + clip-path: xywh(0 16.77175283732661% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 33.16519546027743%); +} + +.btn-ability-zerg-burrow-color-png{ + clip-path: xywh(0 16.897856242118536% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 33.0390920554855%); +} + +.btn-ability-zerg-causticspray-png{ + clip-path: xywh(0 17.023959646910466% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 32.91298865069357%); +} + +.btn-ability-zerg-corruption-color-png{ + clip-path: xywh(0 17.150063051702396% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 32.786885245901644%); +} + +.btn-ability-zerg-creepspread-png{ + clip-path: xywh(0 17.276166456494327% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 32.66078184110971%); +} + +.btn-ability-zerg-creepteleport-png{ + clip-path: xywh(0 17.402269861286253% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 32.534678436317776%); +} + +.btn-ability-zerg-darkswarm-png{ + clip-path: xywh(0 17.528373266078184% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 32.40857503152586%); +} + +.btn-ability-zerg-deeptunnel-png{ + clip-path: xywh(0 17.654476670870114% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 32.28247162673392%); +} + +.btn-ability-zerg-dehaka-essencecollector-png{ + clip-path: xywh(0 17.780580075662044% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 32.15636822194199%); +} + +.btn-ability-zerg-dehaka-guardian-explosivespores-png{ + clip-path: xywh(0 17.90668348045397% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 32.03026481715006%); +} + +.btn-ability-zerg-dehaka-guardian-primordialfury-png{ + clip-path: xywh(0 18.0327868852459% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 31.904161412358135%); +} + +.btn-ability-zerg-dehaka-impaler-tenderize-png{ + clip-path: xywh(0 18.15889029003783% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 31.778058007566205%); +} + +.btn-ability-zerg-dehaka-tyrannozor-barrageofspikes-png{ + clip-path: xywh(0 18.284993694829762% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 31.651954602774275%); +} + +.btn-ability-zerg-dehaka-tyrannozor-tyrantprotection-png{ + clip-path: xywh(0 18.41109709962169% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 31.525851197982345%); +} + +.btn-ability-zerg-dehaka-ultralisk-brutalcharge-png{ + clip-path: xywh(0 18.53720050441362% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 31.399747793190418%); +} + +.btn-ability-zerg-dehaka-ultralisk-healingadaptation-png{ + clip-path: xywh(0 18.66330390920555% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 31.273644388398488%); +} + +.btn-ability-zerg-dehaka-ultralisk-impalingstrike-png{ + clip-path: xywh(0 18.78940731399748% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 31.147540983606557%); +} + +.btn-ability-zerg-fireroach-increasefiredamage-png{ + clip-path: xywh(0 18.915510718789406% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 31.021437578814627%); +} + +.btn-ability-zerg-fungalgrowth-color-png{ + clip-path: xywh(0 19.041614123581336% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 30.8953341740227%); +} + +.btn-ability-zerg-genemutation-thornsaura-png{ + clip-path: xywh(0 19.167717528373267% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 30.76923076923077%); +} + +.btn-ability-zerg-generatecreep-color-png{ + clip-path: xywh(0 19.293820933165197% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 30.64312736443884%); +} + +.btn-ability-zerg-overlord-oversight-off-png{ + clip-path: xywh(0 19.419924337957124% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 30.51702395964691%); +} + +.btn-ability-zerg-parasiticbomb-png{ + clip-path: xywh(0 19.546027742749054% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 30.390920554854983%); +} + +.btn-ability-zerg-rapidregeneration-color-png{ + clip-path: xywh(0 19.672131147540984% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 30.264817150063053%); +} + +.btn-ability-zerg-stukov-ensnare-png{ + clip-path: xywh(0 19.798234552332914% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 30.138713745271122%); +} + +.btn-ability-zerg-stukov-ensnarecdr-png{ + clip-path: xywh(0 19.92433795712484% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 30.012610340479192%); +} + +.btn-ability-zerg-transfusion-color-png{ + clip-path: xywh(0 20.05044136191677% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 29.886506935687265%); +} + +.btn-abilty-terran-lockdownscbw-png{ + clip-path: xywh(0 20.1765447667087% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 29.760403530895335%); +} + +.btn-accelerated-warp-png{ + clip-path: xywh(0 20.302648171500632% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 29.634300126103405%); +} + +.btn-adaptive-medpacks-png{ + clip-path: xywh(0 20.42875157629256% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 29.508196721311474%); +} + +.btn-advanced-construction-png{ + clip-path: xywh(0 20.55485498108449% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 29.382093316519548%); +} + +.btn-advanced-defensive-matrix-png{ + clip-path: xywh(0 20.68095838587642% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 29.255989911727617%); +} + +.btn-advanced-photon-blasters-png{ + clip-path: xywh(0 20.80706179066835% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 29.129886506935687%); +} + +.btn-advanced-targeting-png{ + clip-path: xywh(0 20.933165195460276% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 29.003783102143757%); +} + +.btn-afterburners-valkyrie-png{ + clip-path: xywh(0 21.059268600252206% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 28.87767969735183%); +} + +.btn-all-terrain-treads-png{ + clip-path: xywh(0 21.185372005044137% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 28.7515762925599%); +} + +.btn-amonshardsarmor-png{ + clip-path: xywh(0 21.311475409836067% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 28.62547288776797%); +} + +.btn-anti-surface-countermeasures-png{ + clip-path: xywh(0 21.437578814627994% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 28.49936948297604%); +} + +.btn-apial-sensors-png{ + clip-path: xywh(0 21.563682219419924% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 28.373266078184113%); +} + +.btn-arc-inducers-png{ + clip-path: xywh(0 21.689785624211854% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 28.247162673392182%); +} + +.btn-argus-talisman-png{ + clip-path: xywh(0 21.815889029003785% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 28.121059268600252%); +} + +.btn-armor-metling-blasters-png{ + clip-path: xywh(0 21.94199243379571% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 27.994955863808322%); +} + +.btn-atx-batteries-png{ + clip-path: xywh(0 22.06809583858764% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 27.868852459016395%); +} + +.btn-automated-mitosis-lvl1-png{ + clip-path: xywh(0 22.194199243379572% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 27.742749054224465%); +} + +.btn-banshee-cross-spectrum-dampeners-png{ + clip-path: xywh(0 22.320302648171502% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 27.616645649432535%); +} + +.btn-behemoth-stellarskin-png{ + clip-path: xywh(0 22.44640605296343% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 27.490542244640604%); +} + +.btn-blood-amulet-png{ + clip-path: xywh(0 22.57250945775536% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 27.364438839848678%); +} + +.btn-building-protoss-photoncannon-png{ + clip-path: xywh(0 22.69861286254729% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 27.238335435056747%); +} + +.btn-building-protoss-shieldbattery-png{ + clip-path: xywh(0 22.82471626733922% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 27.112232030264817%); +} + +.btn-building-stukov-infestedbunker-png{ + clip-path: xywh(0 22.950819672131146% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 26.986128625472887%); +} + +.btn-building-stukov-infestedturret-png{ + clip-path: xywh(0 23.076923076923077% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 26.86002522068096%); +} + +.btn-building-terran-autoturret-png{ + clip-path: xywh(0 23.203026481715007% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 26.73392181588903%); +} + +.btn-building-terran-bunker-png{ + clip-path: xywh(0 23.329129886506937% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 26.6078184110971%); +} + +.btn-building-terran-bunkerneosteel-png{ + clip-path: xywh(0 23.455233291298864% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 26.48171500630517%); +} + +.btn-building-terran-hivemindemulator-png{ + clip-path: xywh(0 23.581336696090794% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 26.355611601513242%); +} + +.btn-building-terran-missileturret-png{ + clip-path: xywh(0 23.707440100882724% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 26.229508196721312%); +} + +.btn-building-terran-planetaryfortress-png{ + clip-path: xywh(0 23.833543505674655% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 26.103404791929382%); +} + +.btn-building-terran-refineryautomated-png{ + clip-path: xywh(0 23.95964691046658% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 25.97730138713745%); +} + +.btn-building-terran-sensordome-png{ + clip-path: xywh(0 24.08575031525851% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 25.851197982345525%); +} + +.btn-building-terran-sigmaprojector-png{ + clip-path: xywh(0 24.211853720050442% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 25.725094577553595%); +} + +.btn-building-terran-techreactor-png{ + clip-path: xywh(0 24.337957124842372% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 25.598991172761664%); +} + +.btn-building-zerg-hive-png{ + clip-path: xywh(0 24.4640605296343% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 25.472887767969734%); +} + +.btn-building-zerg-nydusworm-png{ + clip-path: xywh(0 24.59016393442623% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 25.346784363177807%); +} + +.btn-building-zerg-spinecrawler-png{ + clip-path: xywh(0 24.71626733921816% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 25.220680958385877%); +} + +.btn-building-zerg-sporecannon-png{ + clip-path: xywh(0 24.84237074401009% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 25.094577553593947%); +} + +.btn-building-zerg-sporecrawler-png{ + clip-path: xywh(0 24.968474148802017% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 24.968474148802017%); +} + +.btn-caladrius-structure-png{ + clip-path: xywh(0 25.094577553593947% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 24.84237074401009%); +} + +.btn-chronostatic-reinforcement-png{ + clip-path: xywh(0 25.220680958385877% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 24.71626733921816%); +} + +.btn-command-cancel-png{ + clip-path: xywh(0 25.346784363177807% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 24.59016393442623%); +} + +.btn-concentrated-antimatter-png{ + clip-path: xywh(0 25.472887767969734% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 24.4640605296343%); +} + +.btn-disintegrating-particles-png{ + clip-path: xywh(0 25.598991172761664% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 24.337957124842372%); +} + +.btn-disruptor-dispersion-png{ + clip-path: xywh(0 25.725094577553595% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 24.211853720050442%); +} + +.btn-endless-servitude-png{ + clip-path: xywh(0 25.851197982345525% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 24.08575031525851%); +} + +.btn-enhanced-servo-striders-png{ + clip-path: xywh(0 25.97730138713745% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 23.95964691046658%); +} + +.btn-enhanced-shield-generator-png{ + clip-path: xywh(0 26.103404791929382% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 23.833543505674655%); +} + +.btn-eye-of-wrath-png{ + clip-path: xywh(0 26.229508196721312% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 23.707440100882724%); +} + +.btn-fire-suppression-system-lvl2-png{ + clip-path: xywh(0 26.355611601513242% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 23.581336696090794%); +} + +.btn-fleshfused-targeting-optics-png{ + clip-path: xywh(0 26.48171500630517% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 23.455233291298864%); +} + +.btn-forged-chassis-png{ + clip-path: xywh(0 26.6078184110971% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 23.329129886506937%); +} + +.btn-gaping-maw-png{ + clip-path: xywh(0 26.73392181588903% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 23.203026481715007%); +} + +.btn-gravitic-thrusters-png{ + clip-path: xywh(0 26.86002522068096% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 23.076923076923077%); +} + +.btn-high-explosive-munition-png{ + clip-path: xywh(0 26.986128625472887% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 22.950819672131146%); +} + +.btn-high-voltage-capacitors-png{ + clip-path: xywh(0 27.112232030264817% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 22.82471626733922%); +} + +.btn-hostile-environment-adaptation-png{ + clip-path: xywh(0 27.238335435056747% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 22.69861286254729%); +} + +.btn-hull-of-past-glories-png{ + clip-path: xywh(0 27.364438839848678% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 22.57250945775536%); +} + +.btn-hunter-seeker-weapon-png{ + clip-path: xywh(0 27.490542244640604% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 22.44640605296343%); +} + +.btn-iconic-wavelength-flux-png{ + clip-path: xywh(0 27.616645649432535% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 22.320302648171502%); +} + +.btn-improved-osmosis-png{ + clip-path: xywh(0 27.742749054224465% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 22.194199243379572%); +} + +.btn-infested-liberator-ag-png{ + clip-path: xywh(0 27.868852459016395% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 22.06809583858764%); +} + +.btn-integrated-power-png{ + clip-path: xywh(0 27.994955863808322% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 21.94199243379571%); +} + +.btn-jerry-rigged-patchjob-png{ + clip-path: xywh(0 28.121059268600252% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 21.815889029003785%); +} + +.btn-juggernaut-plating-herc-png{ + clip-path: xywh(0 28.247162673392182% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 21.689785624211854%); +} + +.btn-juggernaut-plating-marauder-png{ + clip-path: xywh(0 28.373266078184113% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 21.563682219419924%); +} + +.btn-jump-png{ + clip-path: xywh(0 28.49936948297604% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 21.437578814627994%); +} + +.btn-kryhas-cloak-png{ + clip-path: xywh(0 28.62547288776797% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 21.311475409836067%); +} + +.btn-latticed-shielding-png{ + clip-path: xywh(0 28.7515762925599% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 21.185372005044137%); +} + +.btn-launch-vector-compensator-png{ + clip-path: xywh(0 28.87767969735183% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 21.059268600252206%); +} + +.btn-lesser-shadow-fury-png{ + clip-path: xywh(0 29.003783102143757% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 20.933165195460276%); +} + +.btn-magellan-computation-systems-png{ + clip-path: xywh(0 29.129886506935687% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 20.80706179066835%); +} + +.btn-mobility-protocols-png{ + clip-path: xywh(0 29.255989911727617% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 20.68095838587642%); +} + +.btn-modernized-servos-png{ + clip-path: xywh(0 29.382093316519548% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 20.55485498108449%); +} + +.btn-moirai-impulse-drive-png{ + clip-path: xywh(0 29.508196721311474% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 20.42875157629256%); +} + +.btn-monstrous-resilience-aberration-png{ + clip-path: xywh(0 29.634300126103405% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 20.302648171500632%); +} + +.btn-monstrous-resilience-corruptor-png{ + clip-path: xywh(0 29.760403530895335% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 20.1765447667087%); +} + +.btn-neutron-shields-png{ + clip-path: xywh(0 29.886506935687265% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 20.05044136191677%); +} + +.btn-null-shroud-png{ + clip-path: xywh(0 30.012610340479192% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 19.92433795712484%); +} + +.btn-obliterate-png{ + clip-path: xywh(0 30.138713745271122% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 19.798234552332914%); +} + +.btn-orbital-fortress-png{ + clip-path: xywh(0 30.264817150063053% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 19.672131147540984%); +} + +.btn-pacification-protocols-png{ + clip-path: xywh(0 30.390920554854983% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 19.546027742749054%); +} + +.btn-peer-contempt-png{ + clip-path: xywh(0 30.51702395964691% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 19.419924337957124%); +} + +.btn-permacloak-banshee-png{ + clip-path: xywh(0 30.64312736443884% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 19.293820933165197%); +} + +.btn-permacloak-ghost-png{ + clip-path: xywh(0 30.76923076923077% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 19.167717528373267%); +} + +.btn-permacloak-medivac-png{ + clip-path: xywh(0 30.8953341740227% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 19.041614123581336%); +} + +.btn-permacloak-reaper-png{ + clip-path: xywh(0 31.021437578814627% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 18.915510718789406%); +} + +.btn-permacloak-spectre-png{ + clip-path: xywh(0 31.147540983606557% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 18.78940731399748%); +} + +.btn-permacloak-wraith-png{ + clip-path: xywh(0 31.273644388398488% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 18.66330390920555%); +} + +.btn-phase-blaster-png{ + clip-path: xywh(0 31.399747793190418% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 18.53720050441362%); +} + +.btn-phase-cloak-png{ + clip-path: xywh(0 31.525851197982345% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 18.41109709962169%); +} + +.btn-prescient-spores-png{ + clip-path: xywh(0 31.651954602774275% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 18.284993694829762%); +} + +.btn-progression-hornerhan-6-mirabuildtime-png{ + clip-path: xywh(0 31.778058007566205% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 18.15889029003783%); +} + +.btn-progression-protoss-fenix-1-zealotsuit-png{ + clip-path: xywh(0 31.904161412358135% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 18.0327868852459%); +} + +.btn-progression-protoss-fenix-6-forgeresearch-png{ + clip-path: xywh(0 32.03026481715006% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 17.90668348045397%); +} + +.btn-progression-zerg-dehaka-15-genemutation-png{ + clip-path: xywh(0 32.156368221941996% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 17.780580075662044%); +} + +.btn-progression-zerg-dehaka-7-newdehakaabilities-png{ + clip-path: xywh(0 32.28247162673392% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 17.65447667087011%); +} + +.btn-propellant-sacs-png{ + clip-path: xywh(0 32.40857503152585% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 17.528373266078184%); +} + +.btn-rapid-metamorph-png{ + clip-path: xywh(0 32.53467843631778% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 17.402269861286257%); +} + +.btn-regenerativebiosteel-blue-png{ + clip-path: xywh(0 32.66078184110971% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 17.276166456494323%); +} + +.btn-regenerativebiosteel-green-png{ + clip-path: xywh(0 32.78688524590164% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 17.150063051702396%); +} + +.btn-reintigrated-framework-png{ + clip-path: xywh(0 32.91298865069357% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 17.02395964691047%); +} + +.btn-research-terran-commandcenterreactor-png{ + clip-path: xywh(0 33.0390920554855% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 16.897856242118536%); +} + +.btn-research-terran-microfiltering-png{ + clip-path: xywh(0 33.16519546027743% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 16.77175283732661%); +} + +.btn-research-terran-orbitaldepots-png{ + clip-path: xywh(0 33.29129886506936% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 16.645649432534675%); +} + +.btn-research-terran-orbitalstrikerally-png{ + clip-path: xywh(0 33.417402269861284% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 16.51954602774275%); +} + +.btn-research-terran-ultracapacitors-png{ + clip-path: xywh(0 33.54350567465322% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 16.393442622950822%); +} + +.btn-research-terran-vanadiumplating-png{ + clip-path: xywh(0 33.669609079445145% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 16.267339218158888%); +} + +.btn-research-zerg-cellularreactor-png{ + clip-path: xywh(0 33.79571248423707% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 16.14123581336696%); +} + +.btn-research-zerg-fortifiedbunker-png{ + clip-path: xywh(0 33.921815889029006% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 16.015132408575035%); +} + +.btn-research-zerg-regenerativebio-steel-png{ + clip-path: xywh(0 34.04791929382093% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 15.8890290037831%); +} + +.btn-rogue-forces-png{ + clip-path: xywh(0 34.17402269861286% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 15.762925598991174%); +} + +.btn-royalliberator-png{ + clip-path: xywh(0 34.30012610340479% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 15.63682219419924%); +} + +.btn-scatter-veil-png{ + clip-path: xywh(0 34.42622950819672% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 15.510718789407314%); +} + +.btn-scv-cliffjump-png{ + clip-path: xywh(0 34.55233291298865% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 15.384615384615387%); +} + +.btn-seismic-sonar-png{ + clip-path: xywh(0 34.67843631778058% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 15.258511979823453%); +} + +.btn-shadow-guard-training-png{ + clip-path: xywh(0 34.80453972257251% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 15.132408575031526%); +} + +.btn-shield-capacity-png{ + clip-path: xywh(0 34.93064312736444% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 15.0063051702396%); +} + +.btn-side-missiles-png{ + clip-path: xywh(0 35.05674653215637% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 14.880201765447666%); +} + +.btn-skyward-chronoanomaly-png{ + clip-path: xywh(0 35.182849936948294% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 14.754098360655739%); +} + +.btn-solarite-lens-png{ + clip-path: xywh(0 35.30895334174023% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 14.627994955863805%); +} + +.btn-solarite-payload-png{ + clip-path: xywh(0 35.435056746532155% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 14.501891551071878%); +} + +.btn-stabilized-electrodes-png{ + clip-path: xywh(0 35.56116015132409% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 14.375788146279952%); +} + +.btn-sustaining-disruption-png{ + clip-path: xywh(0 35.687263556116015% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 14.249684741488018%); +} + +.btn-techupgrade-kinetic-foam-png{ + clip-path: xywh(0 35.81336696090794% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 14.123581336696091%); +} + +.btn-techupgrade-terran-cloakdistortionfield-color-png{ + clip-path: xywh(0 35.939470365699876% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 13.997477931904164%); +} + +.btn-techupgrade-terran-combatshield-color-png{ + clip-path: xywh(0 36.0655737704918% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 13.87137452711223%); +} + +.btn-techupgrade-terran-hellstormbatteries-color-png{ + clip-path: xywh(0 36.19167717528373% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 13.745271122320304%); +} + +.btn-techupgrade-terran-immortalityprotocol-color-png{ + clip-path: xywh(0 36.31778058007566% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 13.61916771752837%); +} + +.btn-techupgrade-terran-impalerrounds-color-png{ + clip-path: xywh(0 36.44388398486759% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 13.493064312736443%); +} + +.btn-techupgrade-terran-missilepods-color-level1-png{ + clip-path: xywh(0 36.569987389659524% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 13.366960907944517%); +} + +.btn-techupgrade-terran-ocularimplants-png{ + clip-path: xywh(0 36.69609079445145% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 13.240857503152583%); +} + +.btn-techupgrade-terran-psioniclash-color-png{ + clip-path: xywh(0 36.82219419924338% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 13.114754098360656%); +} + +.btn-techupgrade-terran-rapiddeployment-color-png{ + clip-path: xywh(0 36.94829760403531% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 12.98865069356873%); +} + +.btn-techupgrade-terran-shapedblast-color-png{ + clip-path: xywh(0 37.07440100882724% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 12.862547288776796%); +} + +.btn-techupgrade-terran-shapedhull-colored-png{ + clip-path: xywh(0 37.200504413619164% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 12.736443883984869%); +} + +.btn-techupgrade-terran-titaniumhousing-color-png{ + clip-path: xywh(0 37.3266078184111% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 12.610340479192935%); +} + +.btn-techupgrade-terran-tomahawkpowercell-color-png{ + clip-path: xywh(0 37.452711223203025% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 12.484237074401008%); +} + +.btn-techupgrade-terran-u238rounds-color-png{ + clip-path: xywh(0 37.57881462799496% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 12.358133669609082%); +} + +.btn-tips-armory-png{ + clip-path: xywh(0 37.704918032786885% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 12.232030264817148%); +} + +.btn-tips-flamingbetty-png{ + clip-path: xywh(0 37.83102143757881% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 12.105926860025221%); +} + +.btn-tips-laserdrillantiair-png{ + clip-path: xywh(0 37.957124842370746% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 11.979823455233294%); +} + +.btn-tips-terran-energynova-png{ + clip-path: xywh(0 38.08322824716267% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 11.85372005044136%); +} + +.btn-twilight-chassis-png{ + clip-path: xywh(0 38.2093316519546% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 11.727616645649434%); +} + +.btn-ued-rocketry-technology-png{ + clip-path: xywh(0 38.33543505674653% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 11.6015132408575%); +} + +.btn-ultrasonic-pulse-color-png{ + clip-path: xywh(0 38.46153846153846% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 11.475409836065573%); +} + +.btn-unit-biomechanicaldrone-png{ + clip-path: xywh(0 38.587641866330394% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 11.349306431273646%); +} + +.btn-unit-collection-primal-roachupgrade-png{ + clip-path: xywh(0 38.71374527112232% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 11.223203026481713%); +} + +.btn-unit-collection-primal-tyrannozor-png{ + clip-path: xywh(0 38.83984867591425% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 11.097099621689786%); +} + +.btn-unit-collection-probe-remastered-png{ + clip-path: xywh(0 38.96595208070618% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 10.97099621689786%); +} + +.btn-unit-collection-purifier-carrier-png{ + clip-path: xywh(0 39.09205548549811% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 10.844892812105925%); +} + +.btn-unit-collection-purifier-disruptor-png{ + clip-path: xywh(0 39.218158890290034% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 10.718789407313999%); +} + +.btn-unit-collection-purifier-immortal-png{ + clip-path: xywh(0 39.34426229508197% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 10.592686002522065%); +} + +.btn-unit-collection-taldarim-carrier-png{ + clip-path: xywh(0 39.470365699873895% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 10.466582597730138%); +} + +.btn-unit-collection-taldarim-phoenix-png{ + clip-path: xywh(0 39.59646910466583% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 10.340479192938211%); +} + +.btn-unit-collection-vikingfighter-covertops-png{ + clip-path: xywh(0 39.722572509457756% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 10.214375788146278%); +} + +.btn-unit-collection-wraith-junker-png{ + clip-path: xywh(0 39.84867591424968% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 10.08827238335435%); +} + +.btn-unit-hunterling-png{ + clip-path: xywh(0 39.974779319041616% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 9.962168978562424%); +} + +.btn-unit-infested-infestedmedic-png{ + clip-path: xywh(0 40.10088272383354% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 9.83606557377049%); +} + +.btn-unit-protoss-adept-purifier-png{ + clip-path: xywh(0 40.22698612862547% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 9.709962168978564%); +} + +.btn-unit-protoss-alarak-taldarim-supplicant-png{ + clip-path: xywh(0 40.3530895334174% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 9.58385876418663%); +} + +.btn-unit-protoss-arbiter-png{ + clip-path: xywh(0 40.47919293820933% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 9.457755359394703%); +} + +.btn-unit-protoss-archon-upgraded-png{ + clip-path: xywh(0 40.605296343001264% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 9.331651954602776%); +} + +.btn-unit-protoss-archon-png{ + clip-path: xywh(0 40.73139974779319% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 9.205548549810842%); +} + +.btn-unit-protoss-carrier-png{ + clip-path: xywh(0 40.85750315258512% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 9.079445145018916%); +} + +.btn-unit-protoss-colossus-taldarim-png{ + clip-path: xywh(0 40.98360655737705% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 8.953341740226989%); +} + +.btn-unit-protoss-colossus-png{ + clip-path: xywh(0 41.10970996216898% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 8.827238335435055%); +} + +.btn-unit-protoss-corsair-png{ + clip-path: xywh(0 41.235813366960905% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 8.701134930643128%); +} + +.btn-unit-protoss-darktemplar-aiur-png{ + clip-path: xywh(0 41.36191677175284% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 8.575031525851195%); +} + +.btn-unit-protoss-darktemplar-taldarim-png{ + clip-path: xywh(0 41.488020176544765% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 8.448928121059268%); +} + +.btn-unit-protoss-darktemplar-png{ + clip-path: xywh(0 41.6141235813367% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 8.322824716267341%); +} + +.btn-unit-protoss-dragoon-void-png{ + clip-path: xywh(0 41.740226986128626% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 8.196721311475407%); +} + +.btn-unit-protoss-fenix-png{ + clip-path: xywh(0 41.86633039092055% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 8.07061790668348%); +} + +.btn-unit-protoss-hightemplar-nerazim-png{ + clip-path: xywh(0 41.992433795712486% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 7.944514501891554%); +} + +.btn-unit-protoss-hightemplar-taldarim-png{ + clip-path: xywh(0 42.11853720050441% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 7.81841109709962%); +} + +.btn-unit-protoss-hightemplar-png{ + clip-path: xywh(0 42.24464060529634% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 7.692307692307693%); +} + +.btn-unit-protoss-immortal-nerazim-png{ + clip-path: xywh(0 42.37074401008827% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 7.56620428751576%); +} + +.btn-unit-protoss-immortal-taldarim-png{ + clip-path: xywh(0 42.4968474148802% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 7.440100882723833%); +} + +.btn-unit-protoss-immortal-png{ + clip-path: xywh(0 42.622950819672134% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 7.313997477931906%); +} + +.btn-unit-protoss-khaydarinmonolith-png{ + clip-path: xywh(0 42.74905422446406% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 7.187894073139972%); +} + +.btn-unit-protoss-mothership-taldarim-png{ + clip-path: xywh(0 42.87515762925599% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 7.061790668348046%); +} + +.btn-unit-protoss-observer-png{ + clip-path: xywh(0 43.00126103404792% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 6.935687263556119%); +} + +.btn-unit-protoss-oracle-png{ + clip-path: xywh(0 43.12736443883985% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 6.809583858764185%); +} + +.btn-unit-protoss-phoenix-purifier-png{ + clip-path: xywh(0 43.253467843631775% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 6.683480453972258%); +} + +.btn-unit-protoss-phoenix-png{ + clip-path: xywh(0 43.37957124842371% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 6.5573770491803245%); +} + +.btn-unit-protoss-probe-warpin-png{ + clip-path: xywh(0 43.505674653215635% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 6.431273644388398%); +} + +.btn-unit-protoss-probe-png{ + clip-path: xywh(0 43.63177805800757% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 6.305170239596471%); +} + +.btn-unit-protoss-reaver-png{ + clip-path: xywh(0 43.757881462799496% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 6.179066834804537%); +} + +.btn-unit-protoss-scout-png{ + clip-path: xywh(0 43.88398486759142% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 6.0529634300126105%); +} + +.btn-unit-protoss-scoutnerazim-png{ + clip-path: xywh(0 44.010088272383356% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 5.926860025220684%); +} + +.btn-unit-protoss-scoutpurifier-png{ + clip-path: xywh(0 44.13619167717528% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 5.80075662042875%); +} + +.btn-unit-protoss-scouttaldarim-png{ + clip-path: xywh(0 44.26229508196721% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 5.674653215636823%); +} + +.btn-unit-protoss-sentry-purifier-png{ + clip-path: xywh(0 44.388398486759144% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 5.548549810844889%); +} + +.btn-unit-protoss-sentry-taldarim-png{ + clip-path: xywh(0 44.51450189155107% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 5.422446406052963%); +} + +.btn-unit-protoss-sentry-png{ + clip-path: xywh(0 44.640605296343004% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 5.296343001261036%); +} + +.btn-unit-protoss-stalker-purifier-png{ + clip-path: xywh(0 44.76670870113493% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 5.170239596469102%); +} + +.btn-unit-protoss-stalker-taldarim-collection-ds-png{ + clip-path: xywh(0 44.89281210592686% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 5.044136191677175%); +} + +.btn-unit-protoss-stalker-png{ + clip-path: xywh(0 45.01891551071879% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 4.918032786885249%); +} + +.btn-unit-protoss-tempest-purifier-png{ + clip-path: xywh(0 45.14501891551072% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 4.791929382093315%); +} + +.btn-unit-protoss-voidray-purifier-png{ + clip-path: xywh(0 45.271122320302645% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 4.665825977301388%); +} + +.btn-unit-protoss-voidray-taldarim-png{ + clip-path: xywh(0 45.39722572509458% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 4.539722572509454%); +} + +.btn-unit-protoss-warpprism-png{ + clip-path: xywh(0 45.523329129886505% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 4.413619167717528%); +} + +.btn-unit-protoss-warpray-png{ + clip-path: xywh(0 45.64943253467844% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 4.287515762925601%); +} + +.btn-unit-protoss-zealot-nerazim-png{ + clip-path: xywh(0 45.775535939470366% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 4.161412358133667%); +} + +.btn-unit-protoss-zealot-purifier-png{ + clip-path: xywh(0 45.90163934426229% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 4.03530895334174%); +} + +.btn-unit-protoss-zealot-png{ + clip-path: xywh(0 46.02774274905423% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 3.9092055485498136%); +} + +.btn-unit-terran-autoturretblackops-png{ + clip-path: xywh(0 46.15384615384615% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 3.78310214375788%); +} + +.btn-unit-terran-banshee-mengsk-png{ + clip-path: xywh(0 46.27994955863808% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 3.656998738965953%); +} + +.btn-unit-terran-banshee-png{ + clip-path: xywh(0 46.406052963430014% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 3.5308953341740192%); +} + +.btn-unit-terran-bansheemercenary-png{ + clip-path: xywh(0 46.53215636822194% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 3.4047919293820925%); +} + +.btn-unit-terran-battlecruiser-png{ + clip-path: xywh(0 46.658259773013874% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 3.278688524590166%); +} + +.btn-unit-terran-battlecruiserloki-png{ + clip-path: xywh(0 46.7843631778058% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 3.152585119798232%); +} + +.btn-unit-terran-battlecruisermengsk-png{ + clip-path: xywh(0 46.91046658259773% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 3.0264817150063053%); +} + +.btn-unit-terran-cobra-png{ + clip-path: xywh(0 47.03656998738966% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 2.9003783102143785%); +} + +.btn-unit-terran-cyclone-png{ + clip-path: xywh(0 47.16267339218159% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 2.7742749054224447%); +} + +.btn-unit-terran-deathhead-png{ + clip-path: xywh(0 47.288776796973515% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 2.648171500630518%); +} + +.btn-unit-terran-firebat-png{ + clip-path: xywh(0 47.41488020176545% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 2.522068095838584%); +} + +.btn-unit-terran-firebatmercenary-png{ + clip-path: xywh(0 47.540983606557376% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 2.3959646910466574%); +} + +.btn-unit-terran-ghost-png{ + clip-path: xywh(0 47.66708701134931% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 2.2698612862547307%); +} + +.btn-unit-terran-ghostmengsk-png{ + clip-path: xywh(0 47.793190416141236% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 2.143757881462797%); +} + +.btn-unit-terran-goliath-mengsk-png{ + clip-path: xywh(0 47.91929382093316% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 2.01765447667087%); +} + +.btn-unit-terran-goliath-png{ + clip-path: xywh(0 48.0453972257251% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 1.8915510718789434%); +} + +.btn-unit-terran-goliathmercenary-png{ + clip-path: xywh(0 48.17150063051702% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 1.7654476670870096%); +} + +.btn-unit-terran-hellion-png{ + clip-path: xywh(0 48.29760403530895% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 1.639344262295083%); +} + +.btn-unit-terran-hellionbattlemode-png{ + clip-path: xywh(0 48.423707440100884% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 1.513240857503149%); +} + +.btn-unit-terran-herc-png{ + clip-path: xywh(0 48.54981084489281% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 1.3871374527112224%); +} + +.btn-unit-terran-hercules-png{ + clip-path: xywh(0 48.675914249684745% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 1.2610340479192956%); +} + +.btn-unit-terran-liberator-png{ + clip-path: xywh(0 48.80201765447667% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 1.1349306431273618%); +} + +.btn-unit-terran-liberatorblackops-png{ + clip-path: xywh(0 48.9281210592686% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 1.008827238335435%); +} + +.btn-unit-terran-marauder-png{ + clip-path: xywh(0 49.05422446406053% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 0.8827238335435084%); +} + +.btn-unit-terran-maraudermengsk-png{ + clip-path: xywh(0 49.18032786885246% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 0.7566204287515745%); +} + +.btn-unit-terran-maraudermercenary-png{ + clip-path: xywh(0 49.306431273644385% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 0.6305170239596478%); +} + +.btn-unit-terran-marine-mengsk-png{ + clip-path: xywh(0 49.43253467843632% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 0.504413619167714%); +} + +.btn-unit-terran-marine-png{ + clip-path: xywh(0 49.558638083228246% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 0.37831021437578727%); +} + +.btn-unit-terran-marinemercenary-png{ + clip-path: xywh(0 49.68474148802018% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 0.25220680958386055%); +} + +.btn-unit-terran-medic-mengsk-png{ + clip-path: xywh(0 49.810844892812106% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 0.12610340479192672%); +} + +.btn-unit-terran-medic-png{ + clip-path: xywh(0 49.93694829760403% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, 0.0%); +} + +.btn-unit-terran-medicelite-png{ + clip-path: xywh(0 50.06305170239597% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -0.12610340479192672%); +} + +.btn-unit-terran-medivac-png{ + clip-path: xywh(0 50.189155107187894% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -0.25220680958386055%); +} + +.btn-unit-terran-merc-thor-png{ + clip-path: xywh(0 50.31525851197982% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -0.37831021437578727%); +} + +.btn-unit-terran-mule-png{ + clip-path: xywh(0 50.441361916771754% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -0.504413619167714%); +} + +.btn-unit-terran-perditionturret-png{ + clip-path: xywh(0 50.56746532156368% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -0.6305170239596478%); +} + +.btn-unit-terran-predator-png{ + clip-path: xywh(0 50.693568726355615% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -0.7566204287515745%); +} + +.btn-unit-terran-raven-png{ + clip-path: xywh(0 50.81967213114754% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -0.8827238335435084%); +} + +.btn-unit-terran-reaper-png{ + clip-path: xywh(0 50.94577553593947% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -1.008827238335435%); +} + +.btn-unit-terran-sciencevessel-png{ + clip-path: xywh(0 51.0718789407314% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -1.1349306431273618%); +} + +.btn-unit-terran-siegetank-png{ + clip-path: xywh(0 51.19798234552333% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -1.2610340479192956%); +} + +.btn-unit-terran-siegetankmengsk-png{ + clip-path: xywh(0 51.324085750315255% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -1.3871374527112224%); +} + +.btn-unit-terran-siegetankmercenary-tank-png{ + clip-path: xywh(0 51.45018915510719% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -1.513240857503149%); +} + +.btn-unit-terran-spectre-png{ + clip-path: xywh(0 51.576292559899116% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -1.639344262295083%); +} + +.btn-unit-terran-thor-png{ + clip-path: xywh(0 51.70239596469105% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -1.7654476670870096%); +} + +.btn-unit-terran-thormengsk-png{ + clip-path: xywh(0 51.82849936948298% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -1.8915510718789434%); +} + +.btn-unit-terran-thorsiegemode-png{ + clip-path: xywh(0 51.9546027742749% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -2.01765447667087%); +} + +.btn-unit-terran-troopermengsk-png{ + clip-path: xywh(0 52.08070617906684% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -2.143757881462797%); +} + +.btn-unit-terran-valkyriescbw-png{ + clip-path: xywh(0 52.206809583858764% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -2.2698612862547307%); +} + +.btn-unit-terran-vikingfighter-png{ + clip-path: xywh(0 52.33291298865069% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -2.3959646910466574%); +} + +.btn-unit-terran-vikingmengskfighter-png{ + clip-path: xywh(0 52.459016393442624% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -2.522068095838584%); +} + +.btn-unit-terran-vikingmercenary-fighter-png{ + clip-path: xywh(0 52.58511979823455% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -2.648171500630518%); +} + +.btn-unit-terran-vulture-png{ + clip-path: xywh(0 52.711223203026485% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -2.7742749054224447%); +} + +.btn-unit-terran-warhound-png{ + clip-path: xywh(0 52.83732660781841% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -2.9003783102143785%); +} + +.btn-unit-terran-widowmine-png{ + clip-path: xywh(0 52.96343001261034% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -3.0264817150063053%); +} + +.btn-unit-terran-wraith-mengsk-png{ + clip-path: xywh(0 53.08953341740227% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -3.152585119798232%); +} + +.btn-unit-terran-wraith-png{ + clip-path: xywh(0 53.2156368221942% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -3.278688524590166%); +} + +.btn-unit-voidray-aiur-png{ + clip-path: xywh(0 53.341740226986126% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -3.4047919293820925%); +} + +.btn-unit-zerg-aberration-png{ + clip-path: xywh(0 53.46784363177806% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -3.5308953341740192%); +} + +.btn-unit-zerg-baneling-hunter-png{ + clip-path: xywh(0 53.593947036569986% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -3.656998738965953%); +} + +.btn-unit-zerg-baneling-png{ + clip-path: xywh(0 53.72005044136192% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -3.78310214375788%); +} + +.btn-unit-zerg-broodlord-png{ + clip-path: xywh(0 53.84615384615385% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -3.9092055485498136%); +} + +.btn-unit-zerg-broodqueen-png{ + clip-path: xywh(0 53.97225725094577% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -4.03530895334174%); +} + +.btn-unit-zerg-bullfrog-png{ + clip-path: xywh(0 54.09836065573771% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -4.161412358133667%); +} + +.btn-unit-zerg-classicqueen-png{ + clip-path: xywh(0 54.224464060529634% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -4.287515762925601%); +} + +.btn-unit-zerg-corruptor-png{ + clip-path: xywh(0 54.35056746532156% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -4.413619167717528%); +} + +.btn-unit-zerg-defilerscbw-png{ + clip-path: xywh(0 54.476670870113495% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -4.539722572509454%); +} + +.btn-unit-zerg-devourerex3-png{ + clip-path: xywh(0 54.60277427490542% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -4.665825977301388%); +} + +.btn-unit-zerg-hydralisk-remastered-png{ + clip-path: xywh(0 54.728877679697355% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -4.791929382093315%); +} + +.btn-unit-zerg-hydralisk-png{ + clip-path: xywh(0 54.85498108448928% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -4.918032786885249%); +} + +.btn-unit-zerg-impaler-png{ + clip-path: xywh(0 54.98108448928121% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -5.044136191677175%); +} + +.btn-unit-zerg-infestedbanshee-png{ + clip-path: xywh(0 55.10718789407314% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -5.170239596469102%); +} + +.btn-unit-zerg-infesteddiamondback-png{ + clip-path: xywh(0 55.23329129886507% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -5.296343001261036%); +} + +.btn-unit-zerg-infestedliberator-png{ + clip-path: xywh(0 55.359394703656996% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -5.422446406052963%); +} + +.btn-unit-zerg-infestedmarine-png{ + clip-path: xywh(0 55.48549810844893% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -5.548549810844889%); +} + +.btn-unit-zerg-infestedsiegetank-png{ + clip-path: xywh(0 55.611601513240856% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -5.674653215636823%); +} + +.btn-unit-zerg-infestor-png{ + clip-path: xywh(0 55.73770491803279% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -5.80075662042875%); +} + +.btn-unit-zerg-kerriganascended-png{ + clip-path: xywh(0 55.86380832282472% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -5.926860025220684%); +} + +.btn-unit-zerg-kerriganghost-png{ + clip-path: xywh(0 55.989911727616644% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -6.0529634300126105%); +} + +.btn-unit-zerg-kerriganinfested-png{ + clip-path: xywh(0 56.11601513240858% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -6.179066834804537%); +} + +.btn-unit-zerg-larva-png{ + clip-path: xywh(0 56.242118537200504% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -6.305170239596471%); +} + +.btn-unit-zerg-leviathan-png{ + clip-path: xywh(0 56.36822194199243% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -6.431273644388398%); +} + +.btn-unit-zerg-lurker-png{ + clip-path: xywh(0 56.494325346784365% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -6.5573770491803245%); +} + +.btn-unit-zerg-mutalisk-png{ + clip-path: xywh(0 56.62042875157629% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -6.683480453972258%); +} + +.btn-unit-zerg-nydusdragon-png{ + clip-path: xywh(0 56.746532156368225% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -6.809583858764185%); +} + +.btn-unit-zerg-overlordscbw-png{ + clip-path: xywh(0 56.87263556116015% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -6.935687263556119%); +} + +.btn-unit-zerg-overseer-png{ + clip-path: xywh(0 56.99873896595208% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -7.061790668348046%); +} + +.btn-unit-zerg-primalguardian-png{ + clip-path: xywh(0 57.12484237074401% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -7.187894073139972%); +} + +.btn-unit-zerg-ravager-png{ + clip-path: xywh(0 57.25094577553594% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -7.313997477931906%); +} + +.btn-unit-zerg-roach-corpser-png{ + clip-path: xywh(0 57.377049180327866% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -7.440100882723833%); +} + +.btn-unit-zerg-roach-vile-png{ + clip-path: xywh(0 57.5031525851198% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -7.56620428751576%); +} + +.btn-unit-zerg-roach-png{ + clip-path: xywh(0 57.62925598991173% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -7.692307692307693%); +} + +.btn-unit-zerg-roach_collection-png{ + clip-path: xywh(0 57.75535939470366% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -7.81841109709962%); +} + +.btn-unit-zerg-scourge-png{ + clip-path: xywh(0 57.88146279949559% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -7.944514501891554%); +} + +.btn-unit-zerg-swarmhost-carrion-png{ + clip-path: xywh(0 58.007566204287514% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -8.07061790668348%); +} + +.btn-unit-zerg-swarmhost-creeper-png{ + clip-path: xywh(0 58.13366960907945% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -8.196721311475407%); +} + +.btn-unit-zerg-swarmhost-png{ + clip-path: xywh(0 58.259773013871374% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -8.322824716267341%); +} + +.btn-unit-zerg-ultralisk-noxious-png{ + clip-path: xywh(0 58.3858764186633% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -8.448928121059268%); +} + +.btn-unit-zerg-ultralisk-rcz-png{ + clip-path: xywh(0 58.511979823455235% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -8.575031525851195%); +} + +.btn-unit-zerg-ultralisk-remastered-png{ + clip-path: xywh(0 58.63808322824716% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -8.701134930643128%); +} + +.btn-unit-zerg-ultralisk-torrasque-png{ + clip-path: xywh(0 58.764186633039095% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -8.827238335435055%); +} + +.btn-unit-zerg-ultralisk-png{ + clip-path: xywh(0 58.89029003783102% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -8.953341740226989%); +} + +.btn-unit-zerg-viper-png{ + clip-path: xywh(0 59.01639344262295% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -9.079445145018916%); +} + +.btn-unit-zerg-zergling-raptor-png{ + clip-path: xywh(0 59.14249684741488% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -9.205548549810842%); +} + +.btn-unit-zerg-zergling-scr-png{ + clip-path: xywh(0 59.26860025220681% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -9.331651954602776%); +} + +.btn-unit-zerg-zergling-swarmling-png{ + clip-path: xywh(0 59.394703656998736% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -9.457755359394703%); +} + +.btn-unit-zerg-zergling-png{ + clip-path: xywh(0 59.52080706179067% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -9.58385876418663%); +} + +.btn-unshackled-psionic-storm-png{ + clip-path: xywh(0 59.6469104665826% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -9.709962168978564%); +} + +.btn-upgrade-afaidofthedark-png{ + clip-path: xywh(0 59.77301387137453% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -9.83606557377049%); +} + +.btn-upgrade-artanis-healingpsionicstorm-png{ + clip-path: xywh(0 59.89911727616646% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -9.962168978562424%); +} + +.btn-upgrade-artanis-scarabsplashradius-png{ + clip-path: xywh(0 60.025220680958384% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -10.08827238335435%); +} + +.btn-upgrade-artanis-singularitycharge-png{ + clip-path: xywh(0 60.15132408575032% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -10.214375788146278%); +} + +.btn-upgrade-custom-triple-scourge-png{ + clip-path: xywh(0 60.277427490542244% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -10.340479192938211%); +} + +.btn-upgrade-increasedupgraderesearchspeed-png{ + clip-path: xywh(0 60.40353089533417% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -10.466582597730138%); +} + +.btn-upgrade-karax-energyregen200-png{ + clip-path: xywh(0 60.529634300126105% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -10.592686002522065%); +} + +.btn-upgrade-karax-pylonwarpininstantly-png{ + clip-path: xywh(0 60.65573770491803% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -10.718789407313999%); +} + +.btn-upgrade-karax-turretattackspeed-png{ + clip-path: xywh(0 60.781841109709966% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -10.844892812105925%); +} + +.btn-upgrade-karax-turretrange-png{ + clip-path: xywh(0 60.90794451450189% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -10.97099621689786%); +} + +.btn-upgrade-kerrigan-assimilationaura-png{ + clip-path: xywh(0 61.03404791929382% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -11.097099621689786%); +} + +.btn-upgrade-kerrigan-broodlordspeed-png{ + clip-path: xywh(0 61.16015132408575% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -11.223203026481713%); +} + +.btn-upgrade-kerrigan-crushinggripwave-png{ + clip-path: xywh(0 61.28625472887768% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -11.349306431273646%); +} + +.btn-upgrade-kerrigan-seismicspines-png{ + clip-path: xywh(0 61.412358133669606% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -11.475409836065573%); +} + +.btn-upgrade-mengsk-engineeringbay-dominionarmorlevel2-png{ + clip-path: xywh(0 61.53846153846154% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -11.6015132408575%); +} + +.btn-upgrade-mengsk-engineeringbay-dominionweaponslevel0-png{ + clip-path: xywh(0 61.66456494325347% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -11.727616645649434%); +} + +.btn-upgrade-mengsk-engineeringbay-neosteelfortifiedarmor-png{ + clip-path: xywh(0 61.7906683480454% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -11.85372005044136%); +} + +.btn-upgrade-mengsk-engineeringbay-orbitaldrop-png{ + clip-path: xywh(0 61.91677175283733% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -11.979823455233294%); +} + +.btn-upgrade-mengsk-ghostacademy-guidedtacticalstrike-png{ + clip-path: xywh(0 62.042875157629254% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -12.105926860025221%); +} + +.btn-upgrade-mengsk-trooper-flamethrower-png{ + clip-path: xywh(0 62.16897856242119% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -12.232030264817148%); +} + +.btn-upgrade-mengsk-trooper-missilelauncher-png{ + clip-path: xywh(0 62.295081967213115% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -12.358133669609082%); +} + +.btn-upgrade-mengsk-trooper-plasmarifle-png{ + clip-path: xywh(0 62.42118537200504% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -12.484237074401008%); +} + +.btn-upgrade-nova-blink-png{ + clip-path: xywh(0 62.547288776796975% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -12.610340479192935%); +} + +.btn-upgrade-nova-btn-upgrade-nova-flashgrenade-png{ + clip-path: xywh(0 62.6733921815889% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -12.736443883984869%); +} + +.btn-upgrade-nova-btn-upgrade-nova-pulsegrenade-png{ + clip-path: xywh(0 62.799495586380836% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -12.862547288776796%); +} + +.btn-upgrade-nova-equipment-apolloinfantrysuit-png{ + clip-path: xywh(0 62.92559899117276% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -12.98865069356873%); +} + +.btn-upgrade-nova-equipment-blinksuit-png{ + clip-path: xywh(0 63.05170239596469% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -13.114754098360656%); +} + +.btn-upgrade-nova-equipment-canisterrifle-png{ + clip-path: xywh(0 63.17780580075662% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -13.240857503152583%); +} + +.btn-upgrade-nova-equipment-ghostvisor-png{ + clip-path: xywh(0 63.30390920554855% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -13.366960907944517%); +} + +.btn-upgrade-nova-equipment-gunblade_sword-png{ + clip-path: xywh(0 63.430012610340476% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -13.493064312736443%); +} + +.btn-upgrade-nova-equipment-monomolecularblade-png{ + clip-path: xywh(0 63.55611601513241% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -13.61916771752837%); +} + +.btn-upgrade-nova-equipment-plasmagun-png{ + clip-path: xywh(0 63.68221941992434% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -13.745271122320304%); +} + +.btn-upgrade-nova-equipment-rangefinderoculus-png{ + clip-path: xywh(0 63.80832282471627% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -13.87137452711223%); +} + +.btn-upgrade-nova-equipment-shotgun-png{ + clip-path: xywh(0 63.9344262295082% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -13.997477931904164%); +} + +.btn-upgrade-nova-equipment-stealthsuit-png{ + clip-path: xywh(0 64.06052963430012% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -14.123581336696091%); +} + +.btn-upgrade-nova-holographicdecoy-png{ + clip-path: xywh(0 64.18663303909206% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -14.249684741488025%); +} + +.btn-upgrade-nova-jetpack-png{ + clip-path: xywh(0 64.31273644388399% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -14.375788146279945%); +} + +.btn-upgrade-nova-tacticalstealthsuit-png{ + clip-path: xywh(0 64.43883984867591% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -14.501891551071878%); +} + +.btn-upgrade-protoss-adeptshieldupgrade-png{ + clip-path: xywh(0 64.56494325346785% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -14.627994955863812%); +} + +.btn-upgrade-protoss-airarmorlevel1-png{ + clip-path: xywh(0 64.69104665825978% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -14.754098360655732%); +} + +.btn-upgrade-protoss-airarmorlevel2-png{ + clip-path: xywh(0 64.8171500630517% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -14.880201765447666%); +} + +.btn-upgrade-protoss-airarmorlevel3-png{ + clip-path: xywh(0 64.94325346784363% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -15.0063051702396%); +} + +.btn-upgrade-protoss-airarmorlevel4-png{ + clip-path: xywh(0 65.06935687263557% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -15.13240857503152%); +} + +.btn-upgrade-protoss-airarmorlevel5-png{ + clip-path: xywh(0 65.19546027742749% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -15.258511979823453%); +} + +.btn-upgrade-protoss-airweaponslevel1-png{ + clip-path: xywh(0 65.32156368221942% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -15.384615384615387%); +} + +.btn-upgrade-protoss-airweaponslevel2-png{ + clip-path: xywh(0 65.44766708701135% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -15.51071878940732%); +} + +.btn-upgrade-protoss-airweaponslevel3-png{ + clip-path: xywh(0 65.57377049180327% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -15.63682219419924%); +} + +.btn-upgrade-protoss-airweaponslevel4-png{ + clip-path: xywh(0 65.69987389659521% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -15.762925598991174%); +} + +.btn-upgrade-protoss-airweaponslevel5-png{ + clip-path: xywh(0 65.82597730138714% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -15.889029003783108%); +} + +.btn-upgrade-protoss-alarak-ascendantspsiorbtravelsfurther-png{ + clip-path: xywh(0 65.95208070617906% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -16.015132408575028%); +} + +.btn-upgrade-protoss-alarak-ascendantspermanentlybetter-png{ + clip-path: xywh(0 66.078184110971% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -16.14123581336696%); +} + +.btn-upgrade-protoss-alarak-graviticdrive-png{ + clip-path: xywh(0 66.20428751576293% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -16.267339218158895%); +} + +.btn-upgrade-protoss-alarak-havoctargetlockbuffed-png{ + clip-path: xywh(0 66.33039092055486% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -16.393442622950815%); +} + +.btn-upgrade-protoss-alarak-melleeweapon-png{ + clip-path: xywh(0 66.45649432534678% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -16.51954602774275%); +} + +.btn-upgrade-protoss-alarak-permanentcloak-png{ + clip-path: xywh(0 66.58259773013872% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -16.645649432534682%); +} + +.btn-upgrade-protoss-alarak-rangeincrease-png{ + clip-path: xywh(0 66.70870113493065% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -16.771752837326602%); +} + +.btn-upgrade-protoss-alarak-rangeweapon-png{ + clip-path: xywh(0 66.83480453972257% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -16.897856242118536%); +} + +.btn-upgrade-protoss-alarak-supplicantarmor-png{ + clip-path: xywh(0 66.9609079445145% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -17.02395964691047%); +} + +.btn-upgrade-protoss-alarak-supplicantextrashields-png{ + clip-path: xywh(0 67.08701134930644% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -17.15006305170239%); +} + +.btn-upgrade-protoss-fenix-adept-recochetglaiveupgraded-png{ + clip-path: xywh(0 67.21311475409836% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -17.276166456494323%); +} + +.btn-upgrade-protoss-fenix-adeptchampionbounceattack-png{ + clip-path: xywh(0 67.33921815889029% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -17.402269861286257%); +} + +.btn-upgrade-protoss-fenix-carrier-solarbeam-png{ + clip-path: xywh(0 67.46532156368222% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -17.52837326607819%); +} + +.btn-upgrade-protoss-fenix-disruptorpermanentcloak-png{ + clip-path: xywh(0 67.59142496847414% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -17.65447667087011%); +} + +.btn-upgrade-protoss-fenix-dragoonsolariteflare-png{ + clip-path: xywh(0 67.71752837326608% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -17.780580075662044%); +} + +.btn-upgrade-protoss-fenix-scoutchampionrange-png{ + clip-path: xywh(0 67.84363177805801% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -17.906683480453978%); +} + +.btn-upgrade-protoss-fenix-stasisfield-png{ + clip-path: xywh(0 67.96973518284993% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -18.032786885245898%); +} + +.btn-upgrade-protoss-fenix-zealotsuit-armorplate-png{ + clip-path: xywh(0 68.09583858764186% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -18.15889029003783%); +} + +.btn-upgrade-protoss-fluxvanes-png{ + clip-path: xywh(0 68.2219419924338% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -18.284993694829765%); +} + +.btn-upgrade-protoss-graviticbooster-png{ + clip-path: xywh(0 68.34804539722572% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -18.411097099621685%); +} + +.btn-upgrade-protoss-graviticdrive-png{ + clip-path: xywh(0 68.47414880201765% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -18.53720050441362%); +} + +.btn-upgrade-protoss-gravitoncatapult-png{ + clip-path: xywh(0 68.60025220680959% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -18.663303909205553%); +} + +.btn-upgrade-protoss-groundarmorlevel1-png{ + clip-path: xywh(0 68.72635561160152% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -18.789407313997472%); +} + +.btn-upgrade-protoss-groundarmorlevel2-png{ + clip-path: xywh(0 68.85245901639344% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -18.915510718789406%); +} + +.btn-upgrade-protoss-groundarmorlevel3-png{ + clip-path: xywh(0 68.97856242118537% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -19.04161412358134%); +} + +.btn-upgrade-protoss-groundarmorlevel4-png{ + clip-path: xywh(0 69.1046658259773% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -19.16771752837326%); +} + +.btn-upgrade-protoss-groundarmorlevel5-png{ + clip-path: xywh(0 69.23076923076923% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -19.293820933165193%); +} + +.btn-upgrade-protoss-groundweaponslevel1-png{ + clip-path: xywh(0 69.35687263556116% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -19.419924337957127%); +} + +.btn-upgrade-protoss-groundweaponslevel2-png{ + clip-path: xywh(0 69.4829760403531% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -19.54602774274906%); +} + +.btn-upgrade-protoss-groundweaponslevel3-png{ + clip-path: xywh(0 69.60907944514501% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -19.67213114754098%); +} + +.btn-upgrade-protoss-groundweaponslevel4-png{ + clip-path: xywh(0 69.73518284993695% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -19.798234552332914%); +} + +.btn-upgrade-protoss-groundweaponslevel5-png{ + clip-path: xywh(0 69.86128625472888% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -19.92433795712485%); +} + +.btn-upgrade-protoss-increasedscarabcapacityscbw-png{ + clip-path: xywh(0 69.9873896595208% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -20.050441361916768%); +} + +.btn-upgrade-protoss-khaydarinamulet-png{ + clip-path: xywh(0 70.11349306431273% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -20.1765447667087%); +} + +.btn-upgrade-protoss-phoenixrange-png{ + clip-path: xywh(0 70.23959646910467% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -20.302648171500635%); +} + +.btn-upgrade-protoss-researchbosoniccore-png{ + clip-path: xywh(0 70.36569987389659% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -20.428751576292555%); +} + +.btn-upgrade-protoss-researchgravitysling-png{ + clip-path: xywh(0 70.49180327868852% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -20.55485498108449%); +} + +.btn-upgrade-protoss-resonatingglaives-png{ + clip-path: xywh(0 70.61790668348046% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -20.680958385876423%); +} + +.btn-upgrade-protoss-shieldslevel1-png{ + clip-path: xywh(0 70.74401008827239% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -20.807061790668342%); +} + +.btn-upgrade-protoss-shieldslevel2-png{ + clip-path: xywh(0 70.87011349306431% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -20.933165195460276%); +} + +.btn-upgrade-protoss-shieldslevel3-png{ + clip-path: xywh(0 70.99621689785624% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -21.05926860025221%); +} + +.btn-upgrade-protoss-shieldslevel4-png{ + clip-path: xywh(0 71.12232030264818% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -21.18537200504413%); +} + +.btn-upgrade-protoss-shieldslevel5-png{ + clip-path: xywh(0 71.2484237074401% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -21.311475409836063%); +} + +.btn-upgrade-protoss-stalkerpurifier-reconstruction-png{ + clip-path: xywh(0 71.37452711223203% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -21.437578814627997%); +} + +.btn-upgrade-protoss-tectonicdisruptors-png{ + clip-path: xywh(0 71.50063051702396% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -21.56368221941993%); +} + +.btn-upgrade-protoss-vanguard-aoeradiusincreased-png{ + clip-path: xywh(0 71.62673392181588% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -21.68978562421185%); +} + +.btn-upgrade-protoss-vanguard-increasedarmordamage-png{ + clip-path: xywh(0 71.75283732660782% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -21.815889029003785%); +} + +.btn-upgrade-protoss-wrathwalker-cantargetairunits-png{ + clip-path: xywh(0 71.87894073139975% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -21.94199243379572%); +} + +.btn-upgrade-protoss-wrathwalker-chargetimeimproved-png{ + clip-path: xywh(0 72.00504413619167% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -22.068095838587638%); +} + +.btn-upgrade-psi-indoctrinator-png{ + clip-path: xywh(0 72.1311475409836% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -22.194199243379572%); +} + +.btn-upgrade-raynor-cerberusmines-png{ + clip-path: xywh(0 72.25725094577554% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -22.320302648171506%); +} + +.btn-upgrade-raynor-improvedsiegemode-png{ + clip-path: xywh(0 72.38335435056746% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -22.446406052963425%); +} + +.btn-upgrade-raynor-incineratorgauntlets-png{ + clip-path: xywh(0 72.50945775535939% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -22.57250945775536%); +} + +.btn-upgrade-raynor-juggernautplating-png{ + clip-path: xywh(0 72.63556116015133% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -22.698612862547293%); +} + +.btn-upgrade-raynor-maelstromrounds-png{ + clip-path: xywh(0 72.76166456494326% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -22.824716267339213%); +} + +.btn-upgrade-raynor-phobosclassweaponssystem-png{ + clip-path: xywh(0 72.88776796973518% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -22.950819672131146%); +} + +.btn-upgrade-raynor-replenishablemagazine-png{ + clip-path: xywh(0 73.01387137452711% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -23.07692307692308%); +} + +.btn-upgrade-raynor-ripwavemissiles-png{ + clip-path: xywh(0 73.13997477931905% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -23.203026481715%); +} + +.btn-upgrade-raynor-shockwavemissilebattery-png{ + clip-path: xywh(0 73.26607818411097% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -23.329129886506934%); +} + +.btn-upgrade-raynor-stabilizermedpacks-png{ + clip-path: xywh(0 73.3921815889029% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -23.455233291298867%); +} + +.btn-upgrade-reducedupgraderesearchcost-png{ + clip-path: xywh(0 73.51828499369483% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -23.5813366960908%); +} + +.btn-upgrade-siegetank-spidermines-png{ + clip-path: xywh(0 73.64438839848675% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -23.70744010088272%); +} + +.btn-upgrade-stetmann-banelingmanashieldefficiency-png{ + clip-path: xywh(0 73.77049180327869% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -23.833543505674655%); +} + +.btn-upgrade-stetmann-mechachitinousplating-png{ + clip-path: xywh(0 73.89659520807062% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -23.95964691046659%); +} + +.btn-upgrade-stetmann-zerglinghardenedshield-png{ + clip-path: xywh(0 74.02269861286254% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -24.085750315258508%); +} + +.btn-upgrade-swann-aresclasstargetingsystem-png{ + clip-path: xywh(0 74.14880201765448% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -24.211853720050442%); +} + +.btn-upgrade-swann-defensivematrix-png{ + clip-path: xywh(0 74.27490542244641% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -24.337957124842376%); +} + +.btn-upgrade-swann-displacementfield-png{ + clip-path: xywh(0 74.40100882723833% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -24.464060529634295%); +} + +.btn-upgrade-swann-firesuppressionsystem-png{ + clip-path: xywh(0 74.52711223203026% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -24.59016393442623%); +} + +.btn-upgrade-swann-hellarmor-png{ + clip-path: xywh(0 74.6532156368222% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -24.716267339218163%); +} + +.btn-upgrade-swann-improvedburstlaser-png{ + clip-path: xywh(0 74.77931904161413% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -24.842370744010083%); +} + +.btn-upgrade-swann-improvednanorepair-png{ + clip-path: xywh(0 74.90542244640605% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -24.968474148802017%); +} + +.btn-upgrade-swann-improvedturretattackspeed-png{ + clip-path: xywh(0 75.03152585119798% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -25.09457755359395%); +} + +.btn-upgrade-swann-multilockweaponsystem-png{ + clip-path: xywh(0 75.15762925598992% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -25.22068095838587%); +} + +.btn-upgrade-swann-scvdoublerepair-png{ + clip-path: xywh(0 75.28373266078184% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -25.346784363177804%); +} + +.btn-upgrade-swann-targetingoptics-png{ + clip-path: xywh(0 75.40983606557377% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -25.472887767969738%); +} + +.btn-upgrade-swann-vehiclerangeincrease-png{ + clip-path: xywh(0 75.5359394703657% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -25.59899117276167%); +} + +.btn-upgrade-terran-advanceballistics-png{ + clip-path: xywh(0 75.66204287515762% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -25.72509457755359%); +} + +.btn-upgrade-terran-behemothreactor-png{ + clip-path: xywh(0 75.78814627994956% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -25.851197982345525%); +} + +.btn-upgrade-terran-buildingarmor-png{ + clip-path: xywh(0 75.91424968474149% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -25.97730138713746%); +} + +.btn-upgrade-terran-cyclonerangeupgrade-png{ + clip-path: xywh(0 76.04035308953341% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -26.10340479192938%); +} + +.btn-upgrade-terran-durablematerials-png{ + clip-path: xywh(0 76.16645649432535% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -26.229508196721312%); +} + +.btn-upgrade-terran-highcapacityfueltanks-png{ + clip-path: xywh(0 76.29255989911728% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -26.355611601513246%); +} + +.btn-upgrade-terran-hisecautotracking-png{ + clip-path: xywh(0 76.4186633039092% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -26.481715006305166%); +} + +.btn-upgrade-terran-hyperflightrotors-png{ + clip-path: xywh(0 76.54476670870113% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -26.6078184110971%); +} + +.btn-upgrade-terran-infantryarmorlevel1-png{ + clip-path: xywh(0 76.67087011349307% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -26.733921815889033%); +} + +.btn-upgrade-terran-infantryarmorlevel2-png{ + clip-path: xywh(0 76.796973518285% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -26.860025220680953%); +} + +.btn-upgrade-terran-infantryarmorlevel3-png{ + clip-path: xywh(0 76.92307692307692% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -26.986128625472887%); +} + +.btn-upgrade-terran-infantryarmorlevel4-png{ + clip-path: xywh(0 77.04918032786885% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -27.11223203026482%); +} + +.btn-upgrade-terran-infantryarmorlevel5-png{ + clip-path: xywh(0 77.17528373266079% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -27.23833543505674%); +} + +.btn-upgrade-terran-infantryweaponslevel1-png{ + clip-path: xywh(0 77.3013871374527% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -27.364438839848674%); +} + +.btn-upgrade-terran-infantryweaponslevel2-png{ + clip-path: xywh(0 77.42749054224464% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -27.490542244640608%); +} + +.btn-upgrade-terran-infantryweaponslevel3-png{ + clip-path: xywh(0 77.55359394703657% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -27.61664564943254%); +} + +.btn-upgrade-terran-infantryweaponslevel4-png{ + clip-path: xywh(0 77.6796973518285% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -27.74274905422446%); +} + +.btn-upgrade-terran-infantryweaponslevel5-png{ + clip-path: xywh(0 77.80580075662043% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -27.868852459016395%); +} + +.btn-upgrade-terran-infernalpreigniter-png{ + clip-path: xywh(0 77.93190416141236% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -27.99495586380833%); +} + +.btn-upgrade-terran-interferencematrix-png{ + clip-path: xywh(0 78.05800756620428% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -28.12105926860025%); +} + +.btn-upgrade-terran-internalizedtechmodule-png{ + clip-path: xywh(0 78.18411097099622% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -28.247162673392182%); +} + +.btn-upgrade-terran-jumpjets-png{ + clip-path: xywh(0 78.31021437578815% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -28.373266078184116%); +} + +.btn-upgrade-terran-kd8chargeex3-png{ + clip-path: xywh(0 78.43631778058007% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -28.499369482976036%); +} + +.btn-upgrade-terran-lazertargetingsystem-png{ + clip-path: xywh(0 78.562421185372% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -28.62547288776797%); +} + +.btn-upgrade-terran-magfieldaccelerator-png{ + clip-path: xywh(0 78.68852459016394% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -28.751576292559903%); +} + +.btn-upgrade-terran-magrailmunitions-png{ + clip-path: xywh(0 78.81462799495587% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -28.877679697351823%); +} + +.btn-upgrade-terran-medivacemergencythrusters-png{ + clip-path: xywh(0 78.94073139974779% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -29.003783102143757%); +} + +.btn-upgrade-terran-neosteelframe-png{ + clip-path: xywh(0 79.06683480453972% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -29.12988650693569%); +} + +.btn-upgrade-terran-nova-bansheemissilestrik-png{ + clip-path: xywh(0 79.19293820933166% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -29.25598991172761%); +} + +.btn-upgrade-terran-nova-hellfiremissiles-png{ + clip-path: xywh(0 79.31904161412358% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -29.382093316519544%); +} + +.btn-upgrade-terran-nova-personaldefensivematrix-png{ + clip-path: xywh(0 79.44514501891551% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -29.508196721311478%); +} + +.btn-upgrade-terran-nova-siegetankrange-png{ + clip-path: xywh(0 79.57124842370744% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -29.634300126103412%); +} + +.btn-upgrade-terran-nova-specialordance-png{ + clip-path: xywh(0 79.69735182849936% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -29.76040353089533%); +} + +.btn-upgrade-terran-nova-terrandefendermodestructureattack-png{ + clip-path: xywh(0 79.8234552332913% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -29.886506935687265%); +} + +.btn-upgrade-terran-optimizedlogistics-png{ + clip-path: xywh(0 79.94955863808323% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -30.0126103404792%); +} + +.btn-upgrade-terran-reapercombatdrugs-png{ + clip-path: xywh(0 80.07566204287515% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -30.13871374527112%); +} + +.btn-upgrade-terran-replenishablemagazinelvl2-png{ + clip-path: xywh(0 80.20176544766709% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -30.264817150063053%); +} + +.btn-upgrade-terran-researchdrillingclaws-png{ + clip-path: xywh(0 80.32786885245902% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -30.390920554854986%); +} + +.btn-upgrade-terran-shipplatinglevel1-png{ + clip-path: xywh(0 80.45397225725094% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -30.517023959646906%); +} + +.btn-upgrade-terran-shipplatinglevel2-png{ + clip-path: xywh(0 80.58007566204287% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -30.64312736443884%); +} + +.btn-upgrade-terran-shipplatinglevel3-png{ + clip-path: xywh(0 80.7061790668348% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -30.769230769230774%); +} + +.btn-upgrade-terran-shipplatinglevel4-png{ + clip-path: xywh(0 80.83228247162674% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -30.895334174022693%); +} + +.btn-upgrade-terran-shipplatinglevel5-png{ + clip-path: xywh(0 80.95838587641866% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -31.021437578814627%); +} + +.btn-upgrade-terran-shipweaponslevel1-png{ + clip-path: xywh(0 81.0844892812106% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -31.14754098360656%); +} + +.btn-upgrade-terran-shipweaponslevel2-png{ + clip-path: xywh(0 81.21059268600253% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -31.27364438839848%); +} + +.btn-upgrade-terran-shipweaponslevel3-png{ + clip-path: xywh(0 81.33669609079445% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -31.399747793190414%); +} + +.btn-upgrade-terran-shipweaponslevel4-png{ + clip-path: xywh(0 81.46279949558638% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -31.525851197982348%); +} + +.btn-upgrade-terran-shipweaponslevel5-png{ + clip-path: xywh(0 81.58890290037832% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -31.651954602774282%); +} + +.btn-upgrade-terran-superstimppack-png{ + clip-path: xywh(0 81.71500630517023% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -31.7780580075662%); +} + +.btn-upgrade-terran-transformationservos-png{ + clip-path: xywh(0 81.84110970996217% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -31.904161412358135%); +} + +.btn-upgrade-terran-trilithium-power-cell-png{ + clip-path: xywh(0 81.9672131147541% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -32.03026481715007%); +} + +.btn-upgrade-terran-tungsten-spikes-png{ + clip-path: xywh(0 82.09331651954602% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -32.15636822194199%); +} + +.btn-upgrade-terran-twin-linkedflamethrower-color-png{ + clip-path: xywh(0 82.21941992433796% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -32.28247162673392%); +} + +.btn-upgrade-terran-vehicleplatinglevel1-png{ + clip-path: xywh(0 82.34552332912989% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -32.40857503152586%); +} + +.btn-upgrade-terran-vehicleplatinglevel2-png{ + clip-path: xywh(0 82.47162673392181% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -32.534678436317776%); +} + +.btn-upgrade-terran-vehicleplatinglevel3-png{ + clip-path: xywh(0 82.59773013871374% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -32.66078184110971%); +} + +.btn-upgrade-terran-vehicleplatinglevel4-png{ + clip-path: xywh(0 82.72383354350568% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -32.786885245901644%); +} + +.btn-upgrade-terran-vehicleplatinglevel5-png{ + clip-path: xywh(0 82.84993694829761% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -32.91298865069356%); +} + +.btn-upgrade-terran-vehicleweaponslevel1-png{ + clip-path: xywh(0 82.97604035308953% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -33.0390920554855%); +} + +.btn-upgrade-terran-vehicleweaponslevel2-png{ + clip-path: xywh(0 83.10214375788146% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -33.16519546027743%); +} + +.btn-upgrade-terran-vehicleweaponslevel3-png{ + clip-path: xywh(0 83.2282471626734% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -33.29129886506935%); +} + +.btn-upgrade-terran-vehicleweaponslevel4-png{ + clip-path: xywh(0 83.35435056746532% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -33.417402269861284%); +} + +.btn-upgrade-terran-vehicleweaponslevel5-png{ + clip-path: xywh(0 83.48045397225725% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -33.54350567465322%); +} + +.btn-upgrade-vorazun-corsairpermanentlycloaked-png{ + clip-path: xywh(0 83.60655737704919% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -33.66960907944514%); +} + +.btn-upgrade-vorazun-oraclepermanentlycloaked-png{ + clip-path: xywh(0 83.7326607818411% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -33.79571248423707%); +} + +.btn-upgrade-zagara-aberrationarmorcover-png{ + clip-path: xywh(0 83.85876418663304% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -33.921815889029006%); +} + +.btn-upgrade-zagara-increasebilelauncherrange-png{ + clip-path: xywh(0 83.98486759142497% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -34.04791929382094%); +} + +.btn-upgrade-zagara-scourgesplashdamage-png{ + clip-path: xywh(0 84.11097099621689% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -34.17402269861286%); +} + +.btn-upgrade-zerg-abathur-abduct-png{ + clip-path: xywh(0 84.23707440100883% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -34.30012610340479%); +} + +.btn-upgrade-zerg-abathur-biomass-png{ + clip-path: xywh(0 84.36317780580076% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -34.42622950819673%); +} + +.btn-upgrade-zerg-abathur-biomechanicaltransfusion-png{ + clip-path: xywh(0 84.48928121059268% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -34.552332912988646%); +} + +.btn-upgrade-zerg-abathur-castrange-png{ + clip-path: xywh(0 84.61538461538461% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -34.67843631778058%); +} + +.btn-upgrade-zerg-abathur-devourer-corrosivespray-png{ + clip-path: xywh(0 84.74148802017655% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -34.804539722572514%); +} + +.btn-upgrade-zerg-abathur-improvedmend-png{ + clip-path: xywh(0 84.86759142496848% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -34.930643127364434%); +} + +.btn-upgrade-zerg-abathur-incubationchamber-png{ + clip-path: xywh(0 84.9936948297604% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -35.05674653215637%); +} + +.btn-upgrade-zerg-abathur-prolongeddispersion-png{ + clip-path: xywh(0 85.11979823455233% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -35.1828499369483%); +} + +.btn-upgrade-zerg-adaptivecarapace-png{ + clip-path: xywh(0 85.24590163934427% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -35.30895334174022%); +} + +.btn-upgrade-zerg-adaptivetalons-png{ + clip-path: xywh(0 85.37200504413619% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -35.435056746532155%); +} + +.btn-upgrade-zerg-adrenaloverload-png{ + clip-path: xywh(0 85.49810844892812% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -35.56116015132409%); +} + +.btn-upgrade-zerg-airattacks-level1-png{ + clip-path: xywh(0 85.62421185372006% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -35.68726355611601%); +} + +.btn-upgrade-zerg-airattacks-level2-png{ + clip-path: xywh(0 85.75031525851198% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -35.81336696090794%); +} + +.btn-upgrade-zerg-airattacks-level3-png{ + clip-path: xywh(0 85.87641866330391% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -35.939470365699876%); +} + +.btn-upgrade-zerg-airattacks-level4-png{ + clip-path: xywh(0 86.00252206809584% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -36.06557377049181%); +} + +.btn-upgrade-zerg-airattacks-level5-png{ + clip-path: xywh(0 86.12862547288776% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -36.19167717528373%); +} + +.btn-upgrade-zerg-anabolicsynthesis-png{ + clip-path: xywh(0 86.2547288776797% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -36.31778058007566%); +} + +.btn-upgrade-zerg-ancillaryarmor-png{ + clip-path: xywh(0 86.38083228247163% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -36.4438839848676%); +} + +.btn-upgrade-zerg-buildingarmor-png{ + clip-path: xywh(0 86.50693568726355% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -36.56998738965952%); +} + +.btn-upgrade-zerg-burrowcharge-png{ + clip-path: xywh(0 86.63303909205548% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -36.69609079445145%); +} + +.btn-upgrade-zerg-burrowmove-png{ + clip-path: xywh(0 86.75914249684742% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -36.822194199243384%); +} + +.btn-upgrade-zerg-celldivisionon-png{ + clip-path: xywh(0 86.88524590163935% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -36.948297604035304%); +} + +.btn-upgrade-zerg-centrifugalhooks-png{ + clip-path: xywh(0 87.01134930643127% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -37.07440100882724%); +} + +.btn-upgrade-zerg-chitinousplating-png{ + clip-path: xywh(0 87.1374527112232% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -37.20050441361917%); +} + +.btn-upgrade-zerg-concentrated-spew-png{ + clip-path: xywh(0 87.26355611601514% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -37.32660781841109%); +} + +.btn-upgrade-zerg-corrosiveacid-png{ + clip-path: xywh(0 87.38965952080706% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -37.452711223203025%); +} + +.btn-upgrade-zerg-dehaka-tenderize-png{ + clip-path: xywh(0 87.51576292559899% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -37.57881462799496%); +} + +.btn-upgrade-zerg-demolition-png{ + clip-path: xywh(0 87.64186633039093% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -37.70491803278688%); +} + +.btn-upgrade-zerg-enduringcorruption-png{ + clip-path: xywh(0 87.76796973518285% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -37.83102143757881%); +} + +.btn-upgrade-zerg-evolveincreasedlocustlifetime-png{ + clip-path: xywh(0 87.89407313997478% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -37.957124842370746%); +} + +.btn-upgrade-zerg-evolvemuscularaugments-png{ + clip-path: xywh(0 88.02017654476671% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -38.08322824716268%); +} + +.btn-upgrade-zerg-explosiveglaive-png{ + clip-path: xywh(0 88.14627994955863% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -38.2093316519546%); +} + +.btn-upgrade-zerg-flyercarapace-level1-png{ + clip-path: xywh(0 88.27238335435057% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -38.33543505674653%); +} + +.btn-upgrade-zerg-flyercarapace-level2-png{ + clip-path: xywh(0 88.3984867591425% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -38.46153846153847%); +} + +.btn-upgrade-zerg-flyercarapace-level3-png{ + clip-path: xywh(0 88.52459016393442% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -38.58764186633039%); +} + +.btn-upgrade-zerg-flyercarapace-level4-png{ + clip-path: xywh(0 88.65069356872635% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -38.71374527112232%); +} + +.btn-upgrade-zerg-flyercarapace-level5-png{ + clip-path: xywh(0 88.77679697351829% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -38.839848675914254%); +} + +.btn-upgrade-zerg-frenzy-png{ + clip-path: xywh(0 88.90290037831022% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -38.965952080706174%); +} + +.btn-upgrade-zerg-glialreconstitution-png{ + clip-path: xywh(0 89.02900378310214% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -39.09205548549811%); +} + +.btn-upgrade-zerg-groovedspines-png{ + clip-path: xywh(0 89.15510718789407% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -39.21815889029004%); +} + +.btn-upgrade-zerg-groundcarapace-level1-png{ + clip-path: xywh(0 89.28121059268601% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -39.34426229508196%); +} + +.btn-upgrade-zerg-groundcarapace-level2-png{ + clip-path: xywh(0 89.40731399747793% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -39.470365699873895%); +} + +.btn-upgrade-zerg-groundcarapace-level3-png{ + clip-path: xywh(0 89.53341740226986% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -39.59646910466583%); +} + +.btn-upgrade-zerg-groundcarapace-level4-png{ + clip-path: xywh(0 89.6595208070618% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -39.72257250945775%); +} + +.btn-upgrade-zerg-groundcarapace-level5-png{ + clip-path: xywh(0 89.78562421185372% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -39.84867591424968%); +} + +.btn-upgrade-zerg-hardenedcarapace-png{ + clip-path: xywh(0 89.91172761664565% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -39.974779319041616%); +} + +.btn-upgrade-zerg-hotsgroovedspines-png{ + clip-path: xywh(0 90.03783102143758% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -40.10088272383355%); +} + +.btn-upgrade-zerg-hotsmetabolicboost-png{ + clip-path: xywh(0 90.1639344262295% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -40.22698612862547%); +} + +.btn-upgrade-zerg-hotstunnelingclaws-png{ + clip-path: xywh(0 90.29003783102144% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -40.3530895334174%); +} + +.btn-upgrade-zerg-hydriaticacid-png{ + clip-path: xywh(0 90.41614123581337% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -40.47919293820934%); +} + +.btn-upgrade-zerg-meleeattacks-level1-png{ + clip-path: xywh(0 90.54224464060529% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -40.60529634300126%); +} + +.btn-upgrade-zerg-meleeattacks-level2-png{ + clip-path: xywh(0 90.66834804539722% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -40.73139974779319%); +} + +.btn-upgrade-zerg-meleeattacks-level3-png{ + clip-path: xywh(0 90.79445145018916% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -40.857503152585124%); +} + +.btn-upgrade-zerg-meleeattacks-level4-png{ + clip-path: xywh(0 90.92055485498109% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -40.983606557377044%); +} + +.btn-upgrade-zerg-meleeattacks-level5-png{ + clip-path: xywh(0 91.04665825977301% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -41.10970996216898%); +} + +.btn-upgrade-zerg-missileattacks-level1-png{ + clip-path: xywh(0 91.17276166456494% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -41.23581336696091%); +} + +.btn-upgrade-zerg-missileattacks-level2-png{ + clip-path: xywh(0 91.29886506935688% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -41.36191677175283%); +} + +.btn-upgrade-zerg-missileattacks-level3-png{ + clip-path: xywh(0 91.4249684741488% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -41.488020176544765%); +} + +.btn-upgrade-zerg-missileattacks-level4-png{ + clip-path: xywh(0 91.55107187894073% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -41.6141235813367%); +} + +.btn-upgrade-zerg-missileattacks-level5-png{ + clip-path: xywh(0 91.67717528373267% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -41.74022698612862%); +} + +.btn-upgrade-zerg-monarchblades-png{ + clip-path: xywh(0 91.80327868852459% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -41.86633039092055%); +} + +.btn-upgrade-zerg-organiccarapace-png{ + clip-path: xywh(0 91.92938209331652% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -41.992433795712486%); +} + +.btn-upgrade-zerg-pneumatizedcarapace-png{ + clip-path: xywh(0 92.05548549810845% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -42.11853720050442%); +} + +.btn-upgrade-zerg-pressurizedglands-png{ + clip-path: xywh(0 92.18158890290037% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -42.24464060529634%); +} + +.btn-upgrade-zerg-rapidincubation-png{ + clip-path: xywh(0 92.3076923076923% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -42.37074401008827%); +} + +.btn-upgrade-zerg-rapidregeneration-png{ + clip-path: xywh(0 92.43379571248424% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -42.49684741488021%); +} + +.btn-upgrade-zerg-regenerativebile-png{ + clip-path: xywh(0 92.55989911727616% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -42.62295081967213%); +} + +.btn-upgrade-zerg-rupture-png{ + clip-path: xywh(0 92.6860025220681% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -42.74905422446406%); +} + +.btn-upgrade-zerg-stukov-bansheeburrowregeneration-png{ + clip-path: xywh(0 92.81210592686003% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -42.875157629255995%); +} + +.btn-upgrade-zerg-stukov-bansheemorelife-png{ + clip-path: xywh(0 92.93820933165196% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -43.001261034047914%); +} + +.btn-upgrade-zerg-stukov-bunkerformliferegenupgraded-png{ + clip-path: xywh(0 93.06431273644388% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -43.12736443883985%); +} + +.btn-upgrade-zerg-stukov-bunkerresearchbundle_05-png{ + clip-path: xywh(0 93.19041614123581% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -43.25346784363178%); +} + +.btn-upgrade-zerg-stukov-bunkerupgradeii_14-png{ + clip-path: xywh(0 93.31651954602775% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -43.3795712484237%); +} + +.btn-upgrade-zerg-stukov-diamondbacksnailtrail-png{ + clip-path: xywh(0 93.44262295081967% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -43.505674653215635%); +} + +.btn-upgrade-zerg-stukov-infestedbunkermorelife-png{ + clip-path: xywh(0 93.5687263556116% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -43.63177805800757%); +} + +.btn-upgrade-zerg-stukov-infestedliberatoraoe-png{ + clip-path: xywh(0 93.69482976040354% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -43.75788146279949%); +} + +.btn-upgrade-zerg-stukov-infestedliberatorswarmcloud-png{ + clip-path: xywh(0 93.82093316519546% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -43.88398486759142%); +} + +.btn-upgrade-zerg-stukov-infestedmarinerangeupgrade-png{ + clip-path: xywh(0 93.94703656998739% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -44.010088272383356%); +} + +.btn-upgrade-zerg-stukov-infestedspawnbroodling-png{ + clip-path: xywh(0 94.07313997477932% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -44.13619167717529%); +} + +.btn-upgrade-zerg-stukov-queenenergyregen-png{ + clip-path: xywh(0 94.19924337957124% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -44.26229508196721%); +} + +.btn-upgrade-zerg-stukov-researchqueenfungalgrowth-png{ + clip-path: xywh(0 94.32534678436318% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -44.388398486759144%); +} + +.btn-upgrade-zerg-stukov-siegetankammoregen-png{ + clip-path: xywh(0 94.45145018915511% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -44.51450189155108%); +} + +.btn-upgrade-zerg-stukov-siegetankbonusdamage-png{ + clip-path: xywh(0 94.57755359394703% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -44.640605296343%); +} + +.btn-upgrade-zerg-swarmfrenzy-png{ + clip-path: xywh(0 94.70365699873896% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -44.76670870113493%); +} + +.btn-upgrade-zerg-tissueassimilation-png{ + clip-path: xywh(0 94.8297604035309% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -44.892812105926865%); +} + +.btn-upgrade-zerg-tunnelingjaws-png{ + clip-path: xywh(0 94.95586380832283% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -45.018915510718784%); +} + +.btn-upgrade-zerg-ventralsacs-png{ + clip-path: xywh(0 95.08196721311475% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -45.14501891551072%); +} + +.btn-upgrade-zerg-viciousglaive-png{ + clip-path: xywh(0 95.20807061790669% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -45.27112232030265%); +} + +.btn-upgrade-zergling-armorshredding-png{ + clip-path: xywh(0 95.33417402269862% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -45.39722572509457%); +} + +.btn-veil-of-the-judicator-png{ + clip-path: xywh(0 95.46027742749054% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -45.523329129886505%); +} + +.btn-warp-refraction-png{ + clip-path: xywh(0 95.58638083228247% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -45.64943253467844%); +} + +.evolution_coop-png{ + clip-path: xywh(0 95.7124842370744% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -45.77553593947036%); +} + +.icon-bargain-bin-prices-png{ + clip-path: xywh(0 95.83858764186633% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -45.90163934426229%); +} + +.icon-gas-terran-nobg-png{ + clip-path: xywh(0 95.96469104665826% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -46.02774274905423%); +} + +.icon-health-nobg-png{ + clip-path: xywh(0 96.0907944514502% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -46.15384615384616%); +} + +.icon-mineral-nobg-png{ + clip-path: xywh(0 96.21689785624211% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -46.27994955863808%); +} + +.icon-shields-png{ + clip-path: xywh(0 96.34300126103405% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -46.406052963430014%); +} + +.icon-supply-protoss_nobg-png{ + clip-path: xywh(0 96.46910466582598% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -46.53215636822195%); +} + +.icon-supply-terran_nobg-png{ + clip-path: xywh(0 96.5952080706179% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -46.65825977301387%); +} + +.icon-supply-zerg_nobg-png{ + clip-path: xywh(0 96.72131147540983% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -46.7843631778058%); +} + +.icon-time-protoss-png{ + clip-path: xywh(0 96.84741488020177% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -46.910466582597735%); +} + +.potentbile_coop-png{ + clip-path: xywh(0 96.9735182849937% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -47.036569987389655%); +} + +.predatorcharge-png{ + clip-path: xywh(0 97.09962168978562% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -47.16267339218159%); +} + +.predatorvespene-png{ + clip-path: xywh(0 97.22572509457756% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -47.28877679697352%); +} + +.talent-artanis-level03-warpgatecharges-png{ + clip-path: xywh(0 97.35182849936949% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -47.41488020176544%); +} + +.talent-artanis-level14-startingmaxsupply-png{ + clip-path: xywh(0 97.47793190416141% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -47.540983606557376%); +} + +.talent-raynor-level03-firebatmedicrange-png{ + clip-path: xywh(0 97.60403530895334% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -47.66708701134931%); +} + +.talent-raynor-level08-orbitaldroppods-png{ + clip-path: xywh(0 97.73013871374528% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -47.79319041614123%); +} + +.talent-raynor-level14-infantryattackspeed-png{ + clip-path: xywh(0 97.8562421185372% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -47.91929382093316%); +} + +.talent-swann-level12-immortalityprotocol-png{ + clip-path: xywh(0 97.98234552332913% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -48.0453972257251%); +} + +.talent-swann-level14-vehiclehealthincrease-png{ + clip-path: xywh(0 98.10844892812106% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -48.17150063051703%); +} + +.talent-tychus-level02-additionaloutlaw-png{ + clip-path: xywh(0 98.23455233291298% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -48.29760403530895%); +} + +.talent-tychus-level07-firstdiscount-png{ + clip-path: xywh(0 98.36065573770492% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -48.423707440100884%); +} + +.talent-vorazun-level01-shadowstalk-png{ + clip-path: xywh(0 98.48675914249685% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -48.54981084489282%); +} + +.talent-vorazun-level05-unlockdarkarchon-png{ + clip-path: xywh(0 98.61286254728877% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -48.67591424968474%); +} + +.talent-zagara-level12-unlockswarmling-png{ + clip-path: xywh(0 98.7389659520807% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -48.80201765447667%); +} + +.talent-zagara-level14-unlocksplitterling-png{ + clip-path: xywh(0 98.86506935687264% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -48.928121059268605%); +} + +.tip_terrazinefog-png{ + clip-path: xywh(0 98.99117276166457% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -49.054224464060525%); +} + +.ui_aicommand_build_open_aggressivepush-png{ + clip-path: xywh(0 99.11727616645649% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -49.18032786885246%); +} + +.ui_btn_generic_exclemation_red-png{ + clip-path: xywh(0 99.24337957124843% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -49.30643127364439%); +} + +.ui_glues_help_armyicon_protoss-png{ + clip-path: xywh(0 99.36948297604036% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -49.43253467843631%); +} + +.ui_glues_help_armyicon_terran-png{ + clip-path: xywh(0 99.49558638083228% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -49.558638083228246%); +} + +.ui_glues_help_armyicon_zerg-png{ + clip-path: xywh(0 99.62168978562421% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -49.68474148802018%); +} + +.ui_tipicon_evolution_hydralisk-waves-png{ + clip-path: xywh(0 99.74779319041615% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -49.8108448928121%); +} + +.vultureautolaunchers-png{ + clip-path: xywh(0 99.87389659520807% 100% 0.12610340479192939%); + transform: scale(1, 793) translate(0, -49.93694829760403%); +} + diff --git a/WebHostLib/templates/tracker__Starcraft2.html b/WebHostLib/templates/tracker__Starcraft2.html index d365d126338d..932f21505d16 100644 --- a/WebHostLib/templates/tracker__Starcraft2.html +++ b/WebHostLib/templates/tracker__Starcraft2.html @@ -1,1092 +1,2254 @@ +{# Most of this file is generated using code from the ap-sc2-tracker-proto repo. #} -{% macro sc2_icon(name) -%} - -{% endmacro -%} -{% macro sc2_progressive_icon(name, url, level) -%} - -{% endmacro -%} -{% macro sc2_progressive_icon_with_custom_name(item_name, url, title) -%} - -{% endmacro -%} -{%+ macro sc2_tint_level(level) %} - tint-level-{{ level }} -{%+ endmacro %} -{% macro sc2_render_area(area) %} - - {{ area }} {{'▼' if area != 'Total'}} - {{ checks_done[area] }} / {{ checks_in_area[area] }} - - - {% for location in location_info[area] %} - - {{ location }} - {{ '✔' if location_info[area][location] else '' }} - - {% endfor %} - -{% endmacro -%} -{% macro sc2_loop_areas(column_index, column_count) %} - {% for area in checks_in_area if checks_in_area[area] > 0 and area != 'Total' %} - {% if loop.index0 < (loop.length / column_count) * (column_index + 1) - and loop.index0 >= (loop.length / column_count) * (column_index) %} - {{ sc2_render_area(area) }} - {% endif %} - {% endfor %} -{% endmacro -%} - {{ player_name }}'s Tracker - - - + {{ player_name }}'s Tracker + + + + - - - {# TODO: Replace this with a proper wrapper for each tracker when developing TrackerAPI. #} -
    - Switch To Generic Tracker + + +
    +
    +

    {{ player_name }}'s Starcraft 2 Tracker{{' - Finished' if game_finished}}

    - -
    - - - - - - - - - - - - - - -
    - - - - - - - - - - - - -
    -

    {{ player_name }}'s Starcraft 2 Tracker

    - Starting Resources -
    +{{ minerals_count }}
    +{{ vespene_count }}
    +{{ supply_count }}
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Terran -
    - Weapon & Armor Upgrades -
    {{ sc2_progressive_icon('Progressive Terran Infantry Weapon', terran_infantry_weapon_url, terran_infantry_weapon_level) }}{{ sc2_progressive_icon('Progressive Terran Infantry Armor', terran_infantry_armor_url, terran_infantry_armor_level) }}{{ sc2_progressive_icon('Progressive Terran Vehicle Weapon', terran_vehicle_weapon_url, terran_vehicle_weapon_level) }}{{ sc2_progressive_icon('Progressive Terran Vehicle Armor', terran_vehicle_armor_url, terran_vehicle_armor_level) }}{{ sc2_progressive_icon('Progressive Terran Ship Weapon', terran_ship_weapon_url, terran_ship_weapon_level) }}{{ sc2_progressive_icon('Progressive Terran Ship Armor', terran_ship_armor_url, terran_ship_armor_level) }}{{ sc2_icon('Ultra-Capacitors') }}{{ sc2_icon('Vanadium Plating') }}
    - Base -
    {{ sc2_icon('Bunker') }}{{ sc2_icon('Projectile Accelerator (Bunker)') }}{{ sc2_icon('Neosteel Bunker (Bunker)') }}{{ sc2_icon('Shrike Turret (Bunker)') }}{{ sc2_icon('Fortified Bunker (Bunker)') }}{{ sc2_icon('Missile Turret') }}{{ sc2_icon('Titanium Housing (Missile Turret)') }}{{ sc2_icon('Hellstorm Batteries (Missile Turret)') }}{{ sc2_icon('Tech Reactor') }}{{ sc2_icon('Orbital Depots') }}
    {{ sc2_icon('Command Center Reactor') }}{{ sc2_progressive_icon_with_custom_name('Progressive Orbital Command', orbital_command_url, orbital_command_name) }}{{ sc2_icon('Planetary Fortress') }}{{ sc2_progressive_icon_with_custom_name('Progressive Augmented Thrusters (Planetary Fortress)', augmented_thrusters_planetary_fortress_url, augmented_thrusters_planetary_fortress_name) }}{{ sc2_icon('Advanced Targeting (Planetary Fortress)') }}{{ sc2_icon('Micro-Filtering') }}{{ sc2_icon('Automated Refinery') }}{{ sc2_icon('Advanced Construction (SCV)') }}{{ sc2_icon('Dual-Fusion Welders (SCV)') }}{{ sc2_icon('Hostile Environment Adaptation (SCV)') }}
    {{ sc2_icon('Sensor Tower') }}{{ sc2_icon('Perdition Turret') }}{{ sc2_icon('Hive Mind Emulator') }}{{ sc2_icon('Psi Disrupter') }}
    - Infantry - - Vehicles -
    {{ sc2_icon('Marine') }}{{ sc2_progressive_icon_with_custom_name('Progressive Stimpack (Marine)', stimpack_marine_url, stimpack_marine_name) }}{{ sc2_icon('Combat Shield (Marine)') }}{{ sc2_icon('Laser Targeting System (Marine)') }}{{ sc2_icon('Magrail Munitions (Marine)') }}{{ sc2_icon('Optimized Logistics (Marine)') }}{{ sc2_icon('Hellion') }}{{ sc2_icon('Twin-Linked Flamethrower (Hellion)') }}{{ sc2_icon('Thermite Filaments (Hellion)') }}{{ sc2_icon('Hellbat Aspect (Hellion)') }}{{ sc2_icon('Smart Servos (Hellion)') }}{{ sc2_icon('Optimized Logistics (Hellion)') }}{{ sc2_icon('Jump Jets (Hellion)') }}
    {{ sc2_icon('Medic') }}{{ sc2_icon('Advanced Medic Facilities (Medic)') }}{{ sc2_icon('Stabilizer Medpacks (Medic)') }}{{ sc2_icon('Restoration (Medic)') }}{{ sc2_icon('Optical Flare (Medic)') }}{{ sc2_icon('Resource Efficiency (Medic)') }}{{ sc2_icon('Adaptive Medpacks (Medic)') }}{{ sc2_progressive_icon_with_custom_name('Progressive Stimpack (Hellion)', stimpack_hellion_url, stimpack_hellion_name) }}{{ sc2_icon('Infernal Plating (Hellion)') }}
    {{ sc2_icon('Nano Projector (Medic)') }}{{ sc2_icon('Vulture') }}{{ sc2_progressive_icon_with_custom_name('Progressive Replenishable Magazine (Vulture)', replenishable_magazine_vulture_url, replenishable_magazine_vulture_name) }}{{ sc2_icon('Ion Thrusters (Vulture)') }}{{ sc2_icon('Auto Launchers (Vulture)') }}{{ sc2_icon('Auto-Repair (Vulture)') }}
    {{ sc2_icon('Firebat') }}{{ sc2_icon('Incinerator Gauntlets (Firebat)') }}{{ sc2_icon('Juggernaut Plating (Firebat)') }}{{ sc2_progressive_icon_with_custom_name('Progressive Stimpack (Firebat)', stimpack_firebat_url, stimpack_firebat_name) }}{{ sc2_icon('Resource Efficiency (Firebat)') }}{{ sc2_icon('Infernal Pre-Igniter (Firebat)') }}{{ sc2_icon('Kinetic Foam (Firebat)') }}{{ sc2_icon('Cerberus Mine (Spider Mine)') }}{{ sc2_icon('High Explosive Munition (Spider Mine)') }}
    {{ sc2_icon('Nano Projectors (Firebat)') }}{{ sc2_icon('Goliath') }}{{ sc2_icon('Multi-Lock Weapons System (Goliath)') }}{{ sc2_icon('Ares-Class Targeting System (Goliath)') }}{{ sc2_icon('Jump Jets (Goliath)') }}{{ sc2_icon('Shaped Hull (Goliath)') }}{{ sc2_icon('Optimized Logistics (Goliath)') }}{{ sc2_icon('Resource Efficiency (Goliath)') }}
    {{ sc2_icon('Marauder') }}{{ sc2_icon('Concussive Shells (Marauder)') }}{{ sc2_icon('Kinetic Foam (Marauder)') }}{{ sc2_progressive_icon_with_custom_name('Progressive Stimpack (Marauder)', stimpack_marauder_url, stimpack_marauder_name) }}{{ sc2_icon('Laser Targeting System (Marauder)') }}{{ sc2_icon('Magrail Munitions (Marauder)') }}{{ sc2_icon('Internal Tech Module (Marauder)') }}{{ sc2_icon('Internal Tech Module (Goliath)') }}
    {{ sc2_icon('Juggernaut Plating (Marauder)') }}{{ sc2_icon('Diamondback') }}{{ sc2_progressive_icon_with_custom_name('Progressive Tri-Lithium Power Cell (Diamondback)', trilithium_power_cell_diamondback_url, trilithium_power_cell_diamondback_name) }}{{ sc2_icon('Shaped Hull (Diamondback)') }}{{ sc2_icon('Hyperfluxor (Diamondback)') }}{{ sc2_icon('Burst Capacitors (Diamondback)') }}{{ sc2_icon('Ion Thrusters (Diamondback)') }}{{ sc2_icon('Resource Efficiency (Diamondback)') }}
    {{ sc2_icon('Reaper') }}{{ sc2_icon('U-238 Rounds (Reaper)') }}{{ sc2_icon('G-4 Clusterbomb (Reaper)') }}{{ sc2_progressive_icon_with_custom_name('Progressive Stimpack (Reaper)', stimpack_reaper_url, stimpack_reaper_name) }}{{ sc2_icon('Laser Targeting System (Reaper)') }}{{ sc2_icon('Advanced Cloaking Field (Reaper)') }}{{ sc2_icon('Spider Mines (Reaper)') }}{{ sc2_icon('Siege Tank') }}{{ sc2_icon('Maelstrom Rounds (Siege Tank)') }}{{ sc2_icon('Shaped Blast (Siege Tank)') }}{{ sc2_icon('Jump Jets (Siege Tank)') }}{{ sc2_icon('Spider Mines (Siege Tank)') }}{{ sc2_icon('Smart Servos (Siege Tank)') }}{{ sc2_icon('Graduating Range (Siege Tank)') }}
    {{ sc2_icon('Combat Drugs (Reaper)') }}{{ sc2_icon('Jet Pack Overdrive (Reaper)') }}{{ sc2_icon('Laser Targeting System (Siege Tank)') }}{{ sc2_icon('Advanced Siege Tech (Siege Tank)') }}{{ sc2_icon('Internal Tech Module (Siege Tank)') }}{{ sc2_icon('Shaped Hull (Siege Tank)') }}{{ sc2_icon('Resource Efficiency (Siege Tank)') }}
    {{ sc2_icon('Ghost') }}{{ sc2_icon('Ocular Implants (Ghost)') }}{{ sc2_icon('Crius Suit (Ghost)') }}{{ sc2_icon('EMP Rounds (Ghost)') }}{{ sc2_icon('Lockdown (Ghost)') }}{{ sc2_icon('Resource Efficiency (Ghost)') }}{{ sc2_icon('Thor') }}{{ sc2_icon('330mm Barrage Cannon (Thor)') }}{{ sc2_progressive_icon_with_custom_name('Progressive Immortality Protocol (Thor)', immortality_protocol_thor_url, immortality_protocol_thor_name) }}{{ sc2_progressive_icon_with_custom_name('Progressive High Impact Payload (Thor)', high_impact_payload_thor_url, high_impact_payload_thor_name) }}{{ sc2_icon('Button With a Skull on It (Thor)') }}{{ sc2_icon('Laser Targeting System (Thor)') }}{{ sc2_icon('Large Scale Field Construction (Thor)') }}
    {{ sc2_icon('Spectre') }}{{ sc2_icon('Psionic Lash (Spectre)') }}{{ sc2_icon('Nyx-Class Cloaking Module (Spectre)') }}{{ sc2_icon('Impaler Rounds (Spectre)') }}{{ sc2_icon('Resource Efficiency (Spectre)') }}{{ sc2_icon('Predator') }}{{ sc2_icon('Resource Efficiency (Predator)') }}{{ sc2_icon('Cloak (Predator)') }}{{ sc2_icon('Charge (Predator)') }}{{ sc2_icon('Predator\'s Fury (Predator)') }}
    {{ sc2_icon('HERC') }}{{ sc2_icon('Juggernaut Plating (HERC)') }}{{ sc2_icon('Kinetic Foam (HERC)') }}{{ sc2_icon('Resource Efficiency (HERC)') }}{{ sc2_icon('Widow Mine') }}{{ sc2_icon('Drilling Claws (Widow Mine)') }}{{ sc2_icon('Concealment (Widow Mine)') }}{{ sc2_icon('Black Market Launchers (Widow Mine)') }}{{ sc2_icon('Executioner Missiles (Widow Mine)') }}
    {{ sc2_icon('Cyclone') }}{{ sc2_icon('Mag-Field Accelerators (Cyclone)') }}{{ sc2_icon('Mag-Field Launchers (Cyclone)') }}{{ sc2_icon('Targeting Optics (Cyclone)') }}{{ sc2_icon('Rapid Fire Launchers (Cyclone)') }}{{ sc2_icon('Resource Efficiency (Cyclone)') }}{{ sc2_icon('Internal Tech Module (Cyclone)') }}
    {{ sc2_icon('Warhound') }}{{ sc2_icon('Resource Efficiency (Warhound)') }}{{ sc2_icon('Reinforced Plating (Warhound)') }}
    - Starships -
    {{ sc2_icon('Medivac') }}{{ sc2_icon('Rapid Deployment Tube (Medivac)') }}{{ sc2_icon('Advanced Healing AI (Medivac)') }}{{ sc2_icon('Expanded Hull (Medivac)') }}{{ sc2_icon('Afterburners (Medivac)') }}{{ sc2_icon('Scatter Veil (Medivac)') }}{{ sc2_icon('Advanced Cloaking Field (Medivac)') }}{{ sc2_icon('Raven') }}{{ sc2_icon('Bio Mechanical Repair Drone (Raven)') }}{{ sc2_icon('Spider Mines (Raven)') }}{{ sc2_icon('Railgun Turret (Raven)') }}{{ sc2_icon('Hunter-Seeker Weapon (Raven)') }}{{ sc2_icon('Interference Matrix (Raven)') }}{{ sc2_icon('Anti-Armor Missile (Raven)') }}
    {{ sc2_icon('Wraith') }}{{ sc2_progressive_icon_with_custom_name('Progressive Tomahawk Power Cells (Wraith)', tomahawk_power_cells_wraith_url, tomahawk_power_cells_wraith_name) }}{{ sc2_icon('Displacement Field (Wraith)') }}{{ sc2_icon('Advanced Laser Technology (Wraith)') }}{{ sc2_icon('Trigger Override (Wraith)') }}{{ sc2_icon('Internal Tech Module (Wraith)') }}{{ sc2_icon('Resource Efficiency (Wraith)') }}{{ sc2_icon('Internal Tech Module (Raven)') }}{{ sc2_icon('Resource Efficiency (Raven)') }}{{ sc2_icon('Durable Materials (Raven)') }}
    {{ sc2_icon('Viking') }}{{ sc2_icon('Ripwave Missiles (Viking)') }}{{ sc2_icon('Phobos-Class Weapons System (Viking)') }}{{ sc2_icon('Smart Servos (Viking)') }}{{ sc2_icon('Anti-Mechanical Munition (Viking)') }}{{ sc2_icon('Shredder Rounds (Viking)') }}{{ sc2_icon('W.I.L.D. Missiles (Viking)') }}{{ sc2_icon('Science Vessel') }}{{ sc2_icon('EMP Shockwave (Science Vessel)') }}{{ sc2_icon('Defensive Matrix (Science Vessel)') }}{{ sc2_icon('Improved Nano-Repair (Science Vessel)') }}{{ sc2_icon('Advanced AI Systems (Science Vessel)') }}
    {{ sc2_icon('Banshee') }}{{ sc2_progressive_icon_with_custom_name('Progressive Cross-Spectrum Dampeners (Banshee)', crossspectrum_dampeners_banshee_url, crossspectrum_dampeners_banshee_name) }}{{ sc2_icon('Shockwave Missile Battery (Banshee)') }}{{ sc2_icon('Hyperflight Rotors (Banshee)') }}{{ sc2_icon('Laser Targeting System (Banshee)') }}{{ sc2_icon('Internal Tech Module (Banshee)') }}{{ sc2_icon('Shaped Hull (Banshee)') }}{{ sc2_icon('Hercules') }}{{ sc2_icon('Internal Fusion Module (Hercules)') }}{{ sc2_icon('Tactical Jump (Hercules)') }}
    {{ sc2_icon('Advanced Targeting Optics (Banshee)') }}{{ sc2_icon('Distortion Blasters (Banshee)') }}{{ sc2_icon('Rocket Barrage (Banshee)') }}{{ sc2_icon('Liberator') }}{{ sc2_icon('Advanced Ballistics (Liberator)') }}{{ sc2_icon('Raid Artillery (Liberator)') }}{{ sc2_icon('Cloak (Liberator)') }}{{ sc2_icon('Laser Targeting System (Liberator)') }}{{ sc2_icon('Optimized Logistics (Liberator)') }}{{ sc2_icon('Smart Servos (Liberator)') }}
    {{ sc2_icon('Battlecruiser') }}{{ sc2_progressive_icon('Progressive Missile Pods (Battlecruiser)', missile_pods_battlecruiser_url, missile_pods_battlecruiser_level) }}{{ sc2_progressive_icon_with_custom_name('Progressive Defensive Matrix (Battlecruiser)', defensive_matrix_battlecruiser_url, defensive_matrix_battlecruiser_name) }}{{ sc2_icon('Tactical Jump (Battlecruiser)') }}{{ sc2_icon('Cloak (Battlecruiser)') }}{{ sc2_icon('ATX Laser Battery (Battlecruiser)') }}{{ sc2_icon('Optimized Logistics (Battlecruiser)') }}{{ sc2_icon('Resource Efficiency (Liberator)') }}
    {{ sc2_icon('Internal Tech Module (Battlecruiser)') }}{{ sc2_icon('Behemoth Plating (Battlecruiser)') }}{{ sc2_icon('Covert Ops Engines (Battlecruiser)') }}{{ sc2_icon('Valkyrie') }}{{ sc2_icon('Enhanced Cluster Launchers (Valkyrie)') }}{{ sc2_icon('Shaped Hull (Valkyrie)') }}{{ sc2_icon('Flechette Missiles (Valkyrie)') }}{{ sc2_icon('Afterburners (Valkyrie)') }}{{ sc2_icon('Launching Vector Compensator (Valkyrie)') }}{{ sc2_icon('Resource Efficiency (Valkyrie)') }}
    - Mercenaries -
    {{ sc2_icon('War Pigs') }}{{ sc2_icon('Devil Dogs') }}{{ sc2_icon('Hammer Securities') }}{{ sc2_icon('Spartan Company') }}{{ sc2_icon('Siege Breakers') }}{{ sc2_icon('Hel\'s Angels') }}{{ sc2_icon('Dusk Wings') }}{{ sc2_icon('Jackson\'s Revenge') }}{{ sc2_icon('Skibi\'s Angels') }}{{ sc2_icon('Death Heads') }}{{ sc2_icon('Winged Nightmares') }}{{ sc2_icon('Midnight Riders') }}{{ sc2_icon('Brynhilds') }}{{ sc2_icon('Jotun') }}
    - General Upgrades -
    {{ sc2_progressive_icon('Progressive Fire-Suppression System', firesuppression_system_url, firesuppression_system_level) }}{{ sc2_icon('Orbital Strike') }}{{ sc2_icon('Cellular Reactor') }}{{ sc2_progressive_icon('Progressive Regenerative Bio-Steel', regenerative_biosteel_url, regenerative_biosteel_level) }}{{ sc2_icon('Structure Armor') }}{{ sc2_icon('Hi-Sec Auto Tracking') }}{{ sc2_icon('Advanced Optics') }}{{ sc2_icon('Rogue Forces') }}
    - Nova Equipment -
    {{ sc2_icon('C20A Canister Rifle (Nova Weapon)') }}{{ sc2_icon('Hellfire Shotgun (Nova Weapon)') }}{{ sc2_icon('Plasma Rifle (Nova Weapon)') }}{{ sc2_icon('Monomolecular Blade (Nova Weapon)') }}{{ sc2_icon('Blazefire Gunblade (Nova Weapon)') }}{{ sc2_icon('Stim Infusion (Nova Gadget)') }}{{ sc2_icon('Pulse Grenades (Nova Gadget)') }}{{ sc2_icon('Flashbang Grenades (Nova Gadget)') }}{{ sc2_icon('Ionic Force Field (Nova Gadget)') }}{{ sc2_icon('Holo Decoy (Nova Gadget)') }}
    {{ sc2_progressive_icon_with_custom_name('Progressive Stealth Suit Module (Nova Suit Module)', stealth_suit_module_nova_suit_module_url, stealth_suit_module_nova_suit_module_name) }}{{ sc2_icon('Energy Suit Module (Nova Suit Module)') }}{{ sc2_icon('Armored Suit Module (Nova Suit Module)') }}{{ sc2_icon('Jump Suit Module (Nova Suit Module)') }}{{ sc2_icon('Ghost Visor (Nova Equipment)') }}{{ sc2_icon('Rangefinder Oculus (Nova Equipment)') }}{{ sc2_icon('Domination (Nova Ability)') }}{{ sc2_icon('Blink (Nova Ability)') }}{{ sc2_icon('Tac Nuke Strike (Nova Ability)') }}
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Zerg -
    - Weapon & Armor Upgrades -
    {{ sc2_progressive_icon('Progressive Zerg Melee Attack', zerg_melee_attack_url, zerg_melee_attack_level) }}{{ sc2_progressive_icon('Progressive Zerg Missile Attack', zerg_missile_attack_url, zerg_missile_attack_level) }}{{ sc2_progressive_icon('Progressive Zerg Ground Carapace', zerg_ground_carapace_url, zerg_ground_carapace_level) }}{{ sc2_progressive_icon('Progressive Zerg Flyer Attack', zerg_flyer_attack_url, zerg_flyer_attack_level) }}{{ sc2_progressive_icon('Progressive Zerg Flyer Carapace', zerg_flyer_carapace_url, zerg_flyer_carapace_level) }}
    - Base -
    {{ sc2_icon('Automated Extractors (Kerrigan Tier 3)') }}{{ sc2_icon('Vespene Efficiency (Kerrigan Tier 5)') }}{{ sc2_icon('Twin Drones (Kerrigan Tier 5)') }}{{ sc2_icon('Improved Overlords (Kerrigan Tier 3)') }}{{ sc2_icon('Ventral Sacs (Overlord)') }}
    {{ sc2_icon('Malignant Creep (Kerrigan Tier 5)') }}{{ sc2_icon('Spine Crawler') }}{{ sc2_icon('Spore Crawler') }}
    - Units -
    {{ sc2_icon('Zergling') }}{{ sc2_icon('Raptor Strain (Zergling)') }}{{ sc2_icon('Swarmling Strain (Zergling)') }}{{ sc2_icon('Hardened Carapace (Zergling)') }}{{ sc2_icon('Adrenal Overload (Zergling)') }}{{ sc2_icon('Metabolic Boost (Zergling)') }}{{ sc2_icon('Shredding Claws (Zergling)') }}{{ sc2_icon('Zergling Reconstitution (Kerrigan Tier 3)') }}
    {{ sc2_icon('Baneling Aspect (Zergling)') }}{{ sc2_icon('Splitter Strain (Baneling)') }}{{ sc2_icon('Hunter Strain (Baneling)') }}{{ sc2_icon('Corrosive Acid (Baneling)') }}{{ sc2_icon('Rupture (Baneling)') }}{{ sc2_icon('Regenerative Acid (Baneling)') }}{{ sc2_icon('Centrifugal Hooks (Baneling)') }}
    {{ sc2_icon('Tunneling Jaws (Baneling)') }}{{ sc2_icon('Rapid Metamorph (Baneling)') }}
    {{ sc2_icon('Swarm Queen') }}{{ sc2_icon('Spawn Larvae (Swarm Queen)') }}{{ sc2_icon('Deep Tunnel (Swarm Queen)') }}{{ sc2_icon('Organic Carapace (Swarm Queen)') }}{{ sc2_icon('Bio-Mechanical Transfusion (Swarm Queen)') }}{{ sc2_icon('Resource Efficiency (Swarm Queen)') }}{{ sc2_icon('Incubator Chamber (Swarm Queen)') }}
    {{ sc2_icon('Roach') }}{{ sc2_icon('Vile Strain (Roach)') }}{{ sc2_icon('Corpser Strain (Roach)') }}{{ sc2_icon('Hydriodic Bile (Roach)') }}{{ sc2_icon('Adaptive Plating (Roach)') }}{{ sc2_icon('Tunneling Claws (Roach)') }}{{ sc2_icon('Glial Reconstitution (Roach)') }}{{ sc2_icon('Organic Carapace (Roach)') }}
    {{ sc2_icon('Ravager Aspect (Roach)') }}{{ sc2_icon('Potent Bile (Ravager)') }}{{ sc2_icon('Bloated Bile Ducts (Ravager)') }}{{ sc2_icon('Deep Tunnel (Ravager)') }}
    {{ sc2_icon('Hydralisk') }}{{ sc2_icon('Frenzy (Hydralisk)') }}{{ sc2_icon('Ancillary Carapace (Hydralisk)') }}{{ sc2_icon('Grooved Spines (Hydralisk)') }}{{ sc2_icon('Muscular Augments (Hydralisk)') }}{{ sc2_icon('Resource Efficiency (Hydralisk)') }}
    {{ sc2_icon('Impaler Aspect (Hydralisk)') }}{{ sc2_icon('Adaptive Talons (Impaler)') }}{{ sc2_icon('Secretion Glands (Impaler)') }}{{ sc2_icon('Hardened Tentacle Spines (Impaler)') }}
    {{ sc2_icon('Lurker Aspect (Hydralisk)') }}{{ sc2_icon('Seismic Spines (Lurker)') }}{{ sc2_icon('Adapted Spines (Lurker)') }}
    {{ sc2_icon('Aberration') }}
    {{ sc2_icon('Swarm Host') }}{{ sc2_icon('Carrion Strain (Swarm Host)') }}{{ sc2_icon('Creeper Strain (Swarm Host)') }}{{ sc2_icon('Burrow (Swarm Host)') }}{{ sc2_icon('Rapid Incubation (Swarm Host)') }}{{ sc2_icon('Pressurized Glands (Swarm Host)') }}{{ sc2_icon('Locust Metabolic Boost (Swarm Host)') }}{{ sc2_icon('Enduring Locusts (Swarm Host)') }}
    {{ sc2_icon('Organic Carapace (Swarm Host)') }}{{ sc2_icon('Resource Efficiency (Swarm Host)') }}
    {{ sc2_icon('Infestor') }}{{ sc2_icon('Infested Terran (Infestor)') }}{{ sc2_icon('Microbial Shroud (Infestor)') }}
    {{ sc2_icon('Defiler') }}
    {{ sc2_icon('Ultralisk') }}{{ sc2_icon('Noxious Strain (Ultralisk)') }}{{ sc2_icon('Torrasque Strain (Ultralisk)') }}{{ sc2_icon('Burrow Charge (Ultralisk)') }}{{ sc2_icon('Tissue Assimilation (Ultralisk)') }}{{ sc2_icon('Monarch Blades (Ultralisk)') }}{{ sc2_icon('Anabolic Synthesis (Ultralisk)') }}{{ sc2_icon('Chitinous Plating (Ultralisk)') }}
    {{ sc2_icon('Organic Carapace (Ultralisk)') }}{{ sc2_icon('Resource Efficiency (Ultralisk)') }}
    {{ sc2_icon('Mutalisk') }}{{ sc2_icon('Rapid Regeneration (Mutalisk)') }}{{ sc2_icon('Sundering Glaive (Mutalisk)') }}{{ sc2_icon('Vicious Glaive (Mutalisk)') }}{{ sc2_icon('Severing Glaive (Mutalisk)') }}{{ sc2_icon('Aerodynamic Glaive Shape (Mutalisk)') }}
    {{ sc2_icon('Corruptor') }}{{ sc2_icon('Corruption (Corruptor)') }}{{ sc2_icon('Caustic Spray (Corruptor)') }}
    {{ sc2_icon('Brood Lord Aspect (Mutalisk/Corruptor)') }}{{ sc2_icon('Porous Cartilage (Brood Lord)') }}{{ sc2_icon('Evolved Carapace (Brood Lord)') }}{{ sc2_icon('Splitter Mitosis (Brood Lord)') }}{{ sc2_icon('Resource Efficiency (Brood Lord)') }}
    {{ sc2_icon('Viper Aspect (Mutalisk/Corruptor)') }}{{ sc2_icon('Parasitic Bomb (Viper)') }}{{ sc2_icon('Paralytic Barbs (Viper)') }}{{ sc2_icon('Virulent Microbes (Viper)') }}
    {{ sc2_icon('Guardian Aspect (Mutalisk/Corruptor)') }}{{ sc2_icon('Prolonged Dispersion (Guardian)') }}{{ sc2_icon('Primal Adaptation (Guardian)') }}{{ sc2_icon('Soronan Acid (Guardian)') }}
    {{ sc2_icon('Devourer Aspect (Mutalisk/Corruptor)') }}{{ sc2_icon('Corrosive Spray (Devourer)') }}{{ sc2_icon('Gaping Maw (Devourer)') }}{{ sc2_icon('Improved Osmosis (Devourer)') }}{{ sc2_icon('Prescient Spores (Devourer)') }}
    {{ sc2_icon('Brood Queen') }}{{ sc2_icon('Fungal Growth (Brood Queen)') }}{{ sc2_icon('Ensnare (Brood Queen)') }}{{ sc2_icon('Enhanced Mitochondria (Brood Queen)') }}
    {{ sc2_icon('Scourge') }}{{ sc2_icon('Virulent Spores (Scourge)') }}{{ sc2_icon('Resource Efficiency (Scourge)') }}{{ sc2_icon('Swarm Scourge (Scourge)') }}
    - Mercenaries -
    {{ sc2_icon('Infested Medics') }}{{ sc2_icon('Infested Siege Tanks') }}{{ sc2_icon('Infested Banshees') }}
    - Kerrigan -
    Level: {{ kerrigan_level }}
    {{ sc2_icon('Primal Form (Kerrigan)') }}
    {{ sc2_icon('Kinetic Blast (Kerrigan Tier 1)') }}{{ sc2_icon('Heroic Fortitude (Kerrigan Tier 1)') }}{{ sc2_icon('Leaping Strike (Kerrigan Tier 1)') }}{{ sc2_icon('Crushing Grip (Kerrigan Tier 2)') }}{{ sc2_icon('Chain Reaction (Kerrigan Tier 2)') }}{{ sc2_icon('Psionic Shift (Kerrigan Tier 2)') }}
    {{ sc2_icon('Wild Mutation (Kerrigan Tier 4)') }}{{ sc2_icon('Spawn Banelings (Kerrigan Tier 4)') }}{{ sc2_icon('Mend (Kerrigan Tier 4)') }}{{ sc2_icon('Infest Broodlings (Kerrigan Tier 6)') }}{{ sc2_icon('Fury (Kerrigan Tier 6)') }}{{ sc2_icon('Ability Efficiency (Kerrigan Tier 6)') }}
    {{ sc2_icon('Apocalypse (Kerrigan Tier 7)') }}{{ sc2_icon('Spawn Leviathan (Kerrigan Tier 7)') }}{{ sc2_icon('Drop-Pods (Kerrigan Tier 7)') }}
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Protoss -
    - Weapon & Armor Upgrades -
    {{ sc2_progressive_icon('Progressive Protoss Ground Weapon', protoss_ground_weapon_url, protoss_ground_weapon_level) }}{{ sc2_progressive_icon('Progressive Protoss Ground Armor', protoss_ground_armor_url, protoss_ground_armor_level) }}{{ sc2_progressive_icon('Progressive Protoss Air Weapon', protoss_air_weapon_url, protoss_air_weapon_level) }}{{ sc2_progressive_icon('Progressive Protoss Air Armor', protoss_air_armor_url, protoss_air_armor_level) }}{{ sc2_progressive_icon('Progressive Protoss Shields', protoss_shields_url, protoss_shields_level) }}{{ sc2_icon('Quatro') }}
    - Base -
    {{ sc2_icon('Photon Cannon') }}{{ sc2_icon('Khaydarin Monolith') }}{{ sc2_icon('Shield Battery') }}{{ sc2_icon('Enhanced Targeting') }}{{ sc2_icon('Optimized Ordnance') }}{{ sc2_icon('Khalai Ingenuity') }}{{ sc2_icon('Orbital Assimilators') }}{{ sc2_icon('Amplified Assimilators') }}
    {{ sc2_icon('Warp Harmonization') }}{{ sc2_icon('Superior Warp Gates') }}{{ sc2_icon('Nexus Overcharge') }}
    - Gateway -
    {{ sc2_icon('Zealot') }}{{ sc2_icon('Centurion') }}{{ sc2_icon('Sentinel') }}{{ sc2_icon('Leg Enhancements (Zealot/Sentinel/Centurion)') }}{{ sc2_icon('Shield Capacity (Zealot/Sentinel/Centurion)') }}
    {{ sc2_icon('Supplicant') }}{{ sc2_icon('Blood Shield (Supplicant)') }}{{ sc2_icon('Soul Augmentation (Supplicant)') }}{{ sc2_icon('Shield Regeneration (Supplicant)') }}
    {{ sc2_icon('Sentry') }}{{ sc2_icon('Force Field (Sentry)') }}{{ sc2_icon('Hallucination (Sentry)') }}
    {{ sc2_icon('Energizer') }}{{ sc2_icon('Reclamation (Energizer)') }}{{ sc2_icon('Forged Chassis (Energizer)') }}{{ sc2_icon('Cloaking Module (Sentry/Energizer/Havoc)') }}{{ sc2_icon('Rapid Recharging (Sentry/Energizer/Havoc/Shield Battery)') }}
    {{ sc2_icon('Havoc') }}{{ sc2_icon('Detect Weakness (Havoc)') }}{{ sc2_icon('Bloodshard Resonance (Havoc)') }}
    {{ sc2_icon('Stalker') }}{{ sc2_icon('Instigator') }}{{ sc2_icon('Slayer') }}{{ sc2_icon('Disintegrating Particles (Stalker/Instigator/Slayer)') }}{{ sc2_icon('Particle Reflection (Stalker/Instigator/Slayer)') }}
    {{ sc2_icon('Dragoon') }}{{ sc2_icon('High Impact Phase Disruptor (Dragoon)') }}{{ sc2_icon('Trillic Compression System (Dragoon)') }}{{ sc2_icon('Singularity Charge (Dragoon)') }}{{ sc2_icon('Enhanced Strider Servos (Dragoon)') }}
    {{ sc2_icon('Adept') }}{{ sc2_icon('Shockwave (Adept)') }}{{ sc2_icon('Resonating Glaives (Adept)') }}{{ sc2_icon('Phase Bulwark (Adept)') }}
    {{ sc2_icon('High Templar') }}{{ sc2_icon('Signifier') }}{{ sc2_icon('Unshackled Psionic Storm (High Templar/Signifier)') }}{{ sc2_icon('Hallucination (High Templar/Signifier)') }}{{ sc2_icon('Khaydarin Amulet (High Templar/Signifier)') }}{{ sc2_icon('High Archon (Archon)') }}
    {{ sc2_icon('Ascendant') }}{{ sc2_icon('Power Overwhelming (Ascendant)') }}{{ sc2_icon('Chaotic Attunement (Ascendant)') }}{{ sc2_icon('Blood Amulet (Ascendant)') }}
    {{ sc2_icon('Dark Archon') }}{{ sc2_icon('Feedback (Dark Archon)') }}{{ sc2_icon('Maelstrom (Dark Archon)') }}{{ sc2_icon('Argus Talisman (Dark Archon)') }}
    {{ sc2_icon('Dark Templar') }}{{ sc2_icon('Dark Archon Meld (Dark Templar)') }}
    {{ sc2_icon('Avenger') }}{{ sc2_icon('Blood Hunter') }}{{ sc2_icon('Shroud of Adun (Dark Templar/Avenger/Blood Hunter)') }}{{ sc2_icon('Shadow Guard Training (Dark Templar/Avenger/Blood Hunter)') }}{{ sc2_icon('Blink (Dark Templar/Avenger/Blood Hunter)') }}{{ sc2_icon('Resource Efficiency (Dark Templar/Avenger/Blood Hunter)') }}
    - Robotics Facility -
    {{ sc2_icon('Warp Prism') }}{{ sc2_icon('Gravitic Drive (Warp Prism)') }}{{ sc2_icon('Phase Blaster (Warp Prism)') }}{{ sc2_icon('War Configuration (Warp Prism)') }}
    {{ sc2_icon('Immortal') }}{{ sc2_icon('Annihilator') }}{{ sc2_icon('Singularity Charge (Immortal/Annihilator)') }}{{ sc2_icon('Advanced Targeting Mechanics (Immortal/Annihilator)') }}
    {{ sc2_icon('Vanguard') }}{{ sc2_icon('Agony Launchers (Vanguard)') }}{{ sc2_icon('Matter Dispersion (Vanguard)') }}
    {{ sc2_icon('Colossus') }}{{ sc2_icon('Pacification Protocol (Colossus)') }}
    {{ sc2_icon('Wrathwalker') }}{{ sc2_icon('Rapid Power Cycling (Wrathwalker)') }}{{ sc2_icon('Eye of Wrath (Wrathwalker)') }}
    {{ sc2_icon('Observer') }}{{ sc2_icon('Gravitic Boosters (Observer)') }}{{ sc2_icon('Sensor Array (Observer)') }}
    {{ sc2_icon('Reaver') }}{{ sc2_icon('Scarab Damage (Reaver)') }}{{ sc2_icon('Solarite Payload (Reaver)') }}{{ sc2_icon('Reaver Capacity (Reaver)') }}{{ sc2_icon('Resource Efficiency (Reaver)') }}
    {{ sc2_icon('Disruptor') }}
    - Stargate -
    {{ sc2_icon('Phoenix') }}{{ sc2_icon('Mirage') }}{{ sc2_icon('Ionic Wavelength Flux (Phoenix/Mirage)') }}{{ sc2_icon('Anion Pulse-Crystals (Phoenix/Mirage)') }}
    {{ sc2_icon('Corsair') }}{{ sc2_icon('Stealth Drive (Corsair)') }}{{ sc2_icon('Argus Jewel (Corsair)') }}{{ sc2_icon('Sustaining Disruption (Corsair)') }}{{ sc2_icon('Neutron Shields (Corsair)') }}
    {{ sc2_icon('Destroyer') }}{{ sc2_icon('Reforged Bloodshard Core (Destroyer)') }}
    {{ sc2_icon('Void Ray') }}{{ sc2_icon('Flux Vanes (Void Ray/Destroyer)') }}
    {{ sc2_icon('Carrier') }}{{ sc2_icon('Graviton Catapult (Carrier)') }}{{ sc2_icon('Hull of Past Glories (Carrier)') }}
    {{ sc2_icon('Scout') }}{{ sc2_icon('Combat Sensor Array (Scout)') }}{{ sc2_icon('Apial Sensors (Scout)') }}{{ sc2_icon('Gravitic Thrusters (Scout)') }}{{ sc2_icon('Advanced Photon Blasters (Scout)') }}
    {{ sc2_icon('Tempest') }}{{ sc2_icon('Tectonic Destabilizers (Tempest)') }}{{ sc2_icon('Quantic Reactor (Tempest)') }}{{ sc2_icon('Gravity Sling (Tempest)') }}
    {{ sc2_icon('Mothership') }}
    {{ sc2_icon('Arbiter') }}{{ sc2_icon('Chronostatic Reinforcement (Arbiter)') }}{{ sc2_icon('Khaydarin Core (Arbiter)') }}{{ sc2_icon('Spacetime Anchor (Arbiter)') }}{{ sc2_icon('Resource Efficiency (Arbiter)') }}{{ sc2_icon('Enhanced Cloak Field (Arbiter)') }}
    {{ sc2_icon('Oracle') }}{{ sc2_icon('Stealth Drive (Oracle)') }}{{ sc2_icon('Stasis Calibration (Oracle)') }}{{ sc2_icon('Temporal Acceleration Beam (Oracle)') }}
    - General Upgrades -
    {{ sc2_icon('Matrix Overload') }}{{ sc2_icon('Guardian Shell') }}
    - Spear of Adun -
    {{ sc2_icon('Chrono Surge (Spear of Adun Calldown)') }}{{ sc2_progressive_icon_with_custom_name('Progressive Proxy Pylon (Spear of Adun Calldown)', proxy_pylon_spear_of_adun_calldown_url, proxy_pylon_spear_of_adun_calldown_name) }}{{ sc2_icon('Pylon Overcharge (Spear of Adun Calldown)') }}{{ sc2_icon('Mass Recall (Spear of Adun Calldown)') }}{{ sc2_icon('Shield Overcharge (Spear of Adun Calldown)') }}{{ sc2_icon('Deploy Fenix (Spear of Adun Calldown)') }}{{ sc2_icon('Reconstruction Beam (Spear of Adun Auto-Cast)') }}
    {{ sc2_icon('Orbital Strike (Spear of Adun Calldown)') }}{{ sc2_icon('Temporal Field (Spear of Adun Calldown)') }}{{ sc2_icon('Solar Lance (Spear of Adun Calldown)') }}{{ sc2_icon('Purifier Beam (Spear of Adun Calldown)') }}{{ sc2_icon('Time Stop (Spear of Adun Calldown)') }}{{ sc2_icon('Solar Bombardment (Spear of Adun Calldown)') }}{{ sc2_icon('Overwatch (Spear of Adun Auto-Cast)') }}
    -
    - - - - - - -
    - - {{ sc2_loop_areas(0, 3) }} -
    -
    - - {{ sc2_loop_areas(1, 3) }} -
    -
    - - {{ sc2_loop_areas(2, 3) }} - - {{ sc2_render_area('Total') }} -
     
    -
    -
    +
    +
    + +

    Filler Items

    +
    +
    +
    +
    + +
    + +{{minerals_count}} +
    +
    +
    + +
    + +{{vespene_count}} +
    +
    +
    + +
    + +{{supply_count}} +
    +
    +
    + +
    + +{{max_supply_count}} +
    +
    +
    + +
    + -{{reduced_supply_count}} +
    +
    +
    + +
    + {{construction_speed_count}} +
    +
    +
    + +
    + {{shield_regen_count}} +
    +
    +
    + +
    + {{upgrade_speed_count}} +
    +
    +
    + +
    + {{research_cost_count}} +
    +
    - - +
    +
    + +

    Terran Items

    +
    +
    +
    +
    + + Barracks +
    +
    + + Factory +
    +
    + + Starport +
    +
    + + Buildings +
    +
    + + Mercenaries +
    +
    + + Miscellaneous +
    +
    +
    +
    + — Barracks — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Factory — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Starport — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Buildings — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Mercenaries — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Miscellaneous — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +

    Zerg Items

    +
    +
    +
    +
    + + Ground +
    +
    + + Flyers +
    +
    + + Morphs +
    +
    + + Infested +
    +
    + + Buildings +
    +
    + + Mercenaries +
    +
    + + Miscellaneous +
    +
    +
    +
    + — Ground — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Flyers — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Morphs — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Infested — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Buildings — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Mercenaries — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Miscellaneous — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +

    Protoss Items

    +
    +
    +
    +
    + + Gateway +
    +
    + + Robotics Facility +
    +
    + + Stargate +
    +
    + + Buildings +
    +
    + + Miscellaneous +
    +
    +
    +
    + — Gateway — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Robotics Facility — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Stargate — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Buildings — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + — Miscellaneous — +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +

    Nova Items

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +

    Kerrigan Items

    +
    +
    +
    + + {{kerrigan_level}} +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +

    Keys

    +
    +
    +
      + {% for key_name, key_amount in keys.items() %} +
    • {{key_name}}{{ ' (' + (key_amount | string) + ')' if key_amount > 1}}
    • + {% endfor %} +
    +
    +
    +
    +
    + +

    Locations

    +
    + {{checked_locations | length}} / {{locations | length}} = {{((checked_locations | length) / (locations | length) * 100) | round(3)}}% +
    +
      + {% for mission_name, location_info in missions.items() %} +
    1. {{mission_name}}
        + {% for location_name, collected in location_info %} +
      • {{location_name}}
      • + {% endfor %} +
      +
    2. + {% endfor %} +
    +
    +
    +
    +
    + \ No newline at end of file diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py index 4b92f4b416ba..18145daea8d8 100644 --- a/WebHostLib/tracker.py +++ b/WebHostLib/tracker.py @@ -1247,1114 +1247,225 @@ def render_ChecksFinder_tracker(tracker_data: TrackerData, team: int, player: in if "Starcraft 2" in network_data_package["games"]: def render_Starcraft2_tracker(tracker_data: TrackerData, team: int, player: int) -> str: - SC2WOL_LOC_ID_OFFSET = 1000 - SC2HOTS_LOC_ID_OFFSET = 20000000 # Avoid clashes with The Legend of Zelda - SC2LOTV_LOC_ID_OFFSET = SC2HOTS_LOC_ID_OFFSET + 2000 - SC2NCO_LOC_ID_OFFSET = SC2LOTV_LOC_ID_OFFSET + 2500 - SC2WOL_ITEM_ID_OFFSET = 1000 - SC2HOTS_ITEM_ID_OFFSET = SC2WOL_ITEM_ID_OFFSET + 1000 - SC2LOTV_ITEM_ID_OFFSET = SC2HOTS_ITEM_ID_OFFSET + 1000 - + SC2HOTS_ITEM_ID_OFFSET = 2000 + SC2LOTV_ITEM_ID_OFFSET = 2000 + SC2_KEY_ITEM_ID_OFFSET = 4000 + NCO_LOCATION_ID_LOW = 20004500 + NCO_LOCATION_ID_HIGH = NCO_LOCATION_ID_LOW + 1000 + + STARTING_MINERALS_ITEM_ID = 1800 + STARTING_VESPENE_ITEM_ID = 1801 + STARTING_SUPPLY_ITEM_ID = 1802 + # NOTHING_ITEM_ID = 1803 + MAX_SUPPLY_ITEM_ID = 1804 + SHIELD_REGENERATION_ITEM_ID = 1805 + BUILDING_CONSTRUCTION_SPEED_ITEM_ID = 1806 + UPGRADE_RESEARCH_SPEED_ITEM_ID = 1807 + UPGRADE_RESEARCH_COST_ITEM_ID = 1808 + REDUCED_MAX_SUPPLY_ITEM_ID = 1850 slot_data = tracker_data.get_slot_data(team, player) - minerals_per_item = slot_data.get("minerals_per_item", 15) - vespene_per_item = slot_data.get("vespene_per_item", 15) - starting_supply_per_item = slot_data.get("starting_supply_per_item", 2) - - github_icon_base_url = "https://matthewmarinets.github.io/ap_sc2_icons/icons/" - organics_icon_base_url = "https://0rganics.org/archipelago/sc2wol/" - - icons = { - "Starting Minerals": github_icon_base_url + "blizzard/icon-mineral-nobg.png", - "Starting Vespene": github_icon_base_url + "blizzard/icon-gas-terran-nobg.png", - "Starting Supply": github_icon_base_url + "blizzard/icon-supply-terran_nobg.png", - - "Terran Infantry Weapons Level 1": github_icon_base_url + "blizzard/btn-upgrade-terran-infantryweaponslevel1.png", - "Terran Infantry Weapons Level 2": github_icon_base_url + "blizzard/btn-upgrade-terran-infantryweaponslevel2.png", - "Terran Infantry Weapons Level 3": github_icon_base_url + "blizzard/btn-upgrade-terran-infantryweaponslevel3.png", - "Terran Infantry Armor Level 1": github_icon_base_url + "blizzard/btn-upgrade-terran-infantryarmorlevel1.png", - "Terran Infantry Armor Level 2": github_icon_base_url + "blizzard/btn-upgrade-terran-infantryarmorlevel2.png", - "Terran Infantry Armor Level 3": github_icon_base_url + "blizzard/btn-upgrade-terran-infantryarmorlevel3.png", - "Terran Vehicle Weapons Level 1": github_icon_base_url + "blizzard/btn-upgrade-terran-vehicleweaponslevel1.png", - "Terran Vehicle Weapons Level 2": github_icon_base_url + "blizzard/btn-upgrade-terran-vehicleweaponslevel2.png", - "Terran Vehicle Weapons Level 3": github_icon_base_url + "blizzard/btn-upgrade-terran-vehicleweaponslevel3.png", - "Terran Vehicle Armor Level 1": github_icon_base_url + "blizzard/btn-upgrade-terran-vehicleplatinglevel1.png", - "Terran Vehicle Armor Level 2": github_icon_base_url + "blizzard/btn-upgrade-terran-vehicleplatinglevel2.png", - "Terran Vehicle Armor Level 3": github_icon_base_url + "blizzard/btn-upgrade-terran-vehicleplatinglevel3.png", - "Terran Ship Weapons Level 1": github_icon_base_url + "blizzard/btn-upgrade-terran-shipweaponslevel1.png", - "Terran Ship Weapons Level 2": github_icon_base_url + "blizzard/btn-upgrade-terran-shipweaponslevel2.png", - "Terran Ship Weapons Level 3": github_icon_base_url + "blizzard/btn-upgrade-terran-shipweaponslevel3.png", - "Terran Ship Armor Level 1": github_icon_base_url + "blizzard/btn-upgrade-terran-shipplatinglevel1.png", - "Terran Ship Armor Level 2": github_icon_base_url + "blizzard/btn-upgrade-terran-shipplatinglevel2.png", - "Terran Ship Armor Level 3": github_icon_base_url + "blizzard/btn-upgrade-terran-shipplatinglevel3.png", - - "Bunker": "https://static.wikia.nocookie.net/starcraft/images/c/c5/Bunker_SC2_Icon1.jpg", - "Missile Turret": "https://static.wikia.nocookie.net/starcraft/images/5/5f/MissileTurret_SC2_Icon1.jpg", - "Sensor Tower": "https://static.wikia.nocookie.net/starcraft/images/d/d2/SensorTower_SC2_Icon1.jpg", - - "Projectile Accelerator (Bunker)": github_icon_base_url + "blizzard/btn-upgrade-zerg-stukov-bunkerresearchbundle_05.png", - "Neosteel Bunker (Bunker)": organics_icon_base_url + "NeosteelBunker.png", - "Titanium Housing (Missile Turret)": organics_icon_base_url + "TitaniumHousing.png", - "Hellstorm Batteries (Missile Turret)": github_icon_base_url + "blizzard/btn-ability-stetmann-corruptormissilebarrage.png", - "Advanced Construction (SCV)": github_icon_base_url + "blizzard/btn-ability-mengsk-trooper-advancedconstruction.png", - "Dual-Fusion Welders (SCV)": github_icon_base_url + "blizzard/btn-upgrade-swann-scvdoublerepair.png", - "Hostile Environment Adaptation (SCV)": github_icon_base_url + "blizzard/btn-upgrade-swann-hellarmor.png", - "Fire-Suppression System Level 1": organics_icon_base_url + "Fire-SuppressionSystem.png", - "Fire-Suppression System Level 2": github_icon_base_url + "blizzard/btn-upgrade-swann-firesuppressionsystem.png", - - "Orbital Command": organics_icon_base_url + "OrbitalCommandCampaign.png", - "Planetary Command Module": github_icon_base_url + "original/btn-orbital-fortress.png", - "Lift Off (Planetary Fortress)": github_icon_base_url + "blizzard/btn-ability-terran-liftoff.png", - "Armament Stabilizers (Planetary Fortress)": github_icon_base_url + "blizzard/btn-ability-mengsk-siegetank-flyingtankarmament.png", - "Advanced Targeting (Planetary Fortress)": github_icon_base_url + "blizzard/btn-ability-terran-detectionconedebuff.png", - - "Marine": "https://static.wikia.nocookie.net/starcraft/images/4/47/Marine_SC2_Icon1.jpg", - "Medic": github_icon_base_url + "blizzard/btn-unit-terran-medic.png", - "Firebat": github_icon_base_url + "blizzard/btn-unit-terran-firebat.png", - "Marauder": "https://static.wikia.nocookie.net/starcraft/images/b/ba/Marauder_SC2_Icon1.jpg", - "Reaper": "https://static.wikia.nocookie.net/starcraft/images/7/7d/Reaper_SC2_Icon1.jpg", - "Ghost": "https://static.wikia.nocookie.net/starcraft/images/6/6e/Ghost_SC2_Icon1.jpg", - "Spectre": github_icon_base_url + "original/btn-unit-terran-spectre.png", - "HERC": github_icon_base_url + "blizzard/btn-unit-terran-herc.png", - - "Stimpack (Marine)": github_icon_base_url + "blizzard/btn-ability-terran-stimpack-color.png", - "Super Stimpack (Marine)": github_icon_base_url + "blizzard/btn-upgrade-terran-superstimppack.png", - "Combat Shield (Marine)": github_icon_base_url + "blizzard/btn-techupgrade-terran-combatshield-color.png", - "Laser Targeting System (Marine)": github_icon_base_url + "blizzard/btn-upgrade-terran-lazertargetingsystem.png", - "Magrail Munitions (Marine)": github_icon_base_url + "blizzard/btn-upgrade-terran-magrailmunitions.png", - "Optimized Logistics (Marine)": github_icon_base_url + "blizzard/btn-upgrade-terran-optimizedlogistics.png", - "Advanced Medic Facilities (Medic)": organics_icon_base_url + "AdvancedMedicFacilities.png", - "Stabilizer Medpacks (Medic)": github_icon_base_url + "blizzard/btn-upgrade-raynor-stabilizermedpacks.png", - "Restoration (Medic)": github_icon_base_url + "original/btn-ability-terran-restoration@scbw.png", - "Optical Flare (Medic)": github_icon_base_url + "blizzard/btn-upgrade-protoss-fenix-dragoonsolariteflare.png", - "Resource Efficiency (Medic)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Adaptive Medpacks (Medic)": github_icon_base_url + "blizzard/btn-ability-terran-heal-color.png", - "Nano Projector (Medic)": github_icon_base_url + "blizzard/talent-raynor-level03-firebatmedicrange.png", - "Incinerator Gauntlets (Firebat)": github_icon_base_url + "blizzard/btn-upgrade-raynor-incineratorgauntlets.png", - "Juggernaut Plating (Firebat)": github_icon_base_url + "blizzard/btn-upgrade-raynor-juggernautplating.png", - "Stimpack (Firebat)": github_icon_base_url + "blizzard/btn-ability-terran-stimpack-color.png", - "Super Stimpack (Firebat)": github_icon_base_url + "blizzard/btn-upgrade-terran-superstimppack.png", - "Resource Efficiency (Firebat)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Infernal Pre-Igniter (Firebat)": github_icon_base_url + "blizzard/btn-upgrade-terran-infernalpreigniter.png", - "Kinetic Foam (Firebat)": organics_icon_base_url + "KineticFoam.png", - "Nano Projectors (Firebat)": github_icon_base_url + "blizzard/talent-raynor-level03-firebatmedicrange.png", - "Concussive Shells (Marauder)": github_icon_base_url + "blizzard/btn-ability-terran-punishergrenade-color.png", - "Kinetic Foam (Marauder)": organics_icon_base_url + "KineticFoam.png", - "Stimpack (Marauder)": github_icon_base_url + "blizzard/btn-ability-terran-stimpack-color.png", - "Super Stimpack (Marauder)": github_icon_base_url + "blizzard/btn-upgrade-terran-superstimppack.png", - "Laser Targeting System (Marauder)": github_icon_base_url + "blizzard/btn-upgrade-terran-lazertargetingsystem.png", - "Magrail Munitions (Marauder)": github_icon_base_url + "blizzard/btn-upgrade-terran-magrailmunitions.png", - "Internal Tech Module (Marauder)": github_icon_base_url + "blizzard/btn-upgrade-terran-internalizedtechmodule.png", - "Juggernaut Plating (Marauder)": organics_icon_base_url + "JuggernautPlating.png", - "U-238 Rounds (Reaper)": organics_icon_base_url + "U-238Rounds.png", - "G-4 Clusterbomb (Reaper)": github_icon_base_url + "blizzard/btn-upgrade-terran-kd8chargeex3.png", - "Stimpack (Reaper)": github_icon_base_url + "blizzard/btn-ability-terran-stimpack-color.png", - "Super Stimpack (Reaper)": github_icon_base_url + "blizzard/btn-upgrade-terran-superstimppack.png", - "Laser Targeting System (Reaper)": github_icon_base_url + "blizzard/btn-upgrade-terran-lazertargetingsystem.png", - "Advanced Cloaking Field (Reaper)": github_icon_base_url + "original/btn-permacloak-reaper.png", - "Spider Mines (Reaper)": github_icon_base_url + "original/btn-ability-terran-spidermine.png", - "Combat Drugs (Reaper)": github_icon_base_url + "blizzard/btn-upgrade-terran-reapercombatdrugs.png", - "Jet Pack Overdrive (Reaper)": github_icon_base_url + "blizzard/btn-ability-hornerhan-reaper-flightmode.png", - "Ocular Implants (Ghost)": organics_icon_base_url + "OcularImplants.png", - "Crius Suit (Ghost)": github_icon_base_url + "original/btn-permacloak-ghost.png", - "EMP Rounds (Ghost)": github_icon_base_url + "blizzard/btn-ability-terran-emp-color.png", - "Lockdown (Ghost)": github_icon_base_url + "original/btn-abilty-terran-lockdown@scbw.png", - "Resource Efficiency (Ghost)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Psionic Lash (Spectre)": organics_icon_base_url + "PsionicLash.png", - "Nyx-Class Cloaking Module (Spectre)": github_icon_base_url + "original/btn-permacloak-spectre.png", - "Impaler Rounds (Spectre)": github_icon_base_url + "blizzard/btn-techupgrade-terran-impalerrounds.png", - "Resource Efficiency (Spectre)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Juggernaut Plating (HERC)": organics_icon_base_url + "JuggernautPlating.png", - "Kinetic Foam (HERC)": organics_icon_base_url + "KineticFoam.png", - "Resource Efficiency (HERC)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - - "Hellion": "https://static.wikia.nocookie.net/starcraft/images/5/56/Hellion_SC2_Icon1.jpg", - "Vulture": github_icon_base_url + "blizzard/btn-unit-terran-vulture.png", - "Goliath": github_icon_base_url + "blizzard/btn-unit-terran-goliath.png", - "Diamondback": github_icon_base_url + "blizzard/btn-unit-terran-cobra.png", - "Siege Tank": "https://static.wikia.nocookie.net/starcraft/images/5/57/SiegeTank_SC2_Icon1.jpg", - "Thor": "https://static.wikia.nocookie.net/starcraft/images/e/ef/Thor_SC2_Icon1.jpg", - "Predator": github_icon_base_url + "original/btn-unit-terran-predator.png", - "Widow Mine": github_icon_base_url + "blizzard/btn-unit-terran-widowmine.png", - "Cyclone": github_icon_base_url + "blizzard/btn-unit-terran-cyclone.png", - "Warhound": github_icon_base_url + "blizzard/btn-unit-terran-warhound.png", - - "Twin-Linked Flamethrower (Hellion)": github_icon_base_url + "blizzard/btn-upgrade-mengsk-trooper-flamethrower.png", - "Thermite Filaments (Hellion)": github_icon_base_url + "blizzard/btn-upgrade-terran-infernalpreigniter.png", - "Hellbat Aspect (Hellion)": github_icon_base_url + "blizzard/btn-unit-terran-hellionbattlemode.png", - "Smart Servos (Hellion)": github_icon_base_url + "blizzard/btn-upgrade-terran-transformationservos.png", - "Optimized Logistics (Hellion)": github_icon_base_url + "blizzard/btn-upgrade-terran-optimizedlogistics.png", - "Jump Jets (Hellion)": github_icon_base_url + "blizzard/btn-upgrade-terran-jumpjets.png", - "Stimpack (Hellion)": github_icon_base_url + "blizzard/btn-ability-terran-stimpack-color.png", - "Super Stimpack (Hellion)": github_icon_base_url + "blizzard/btn-upgrade-terran-superstimppack.png", - "Infernal Plating (Hellion)": github_icon_base_url + "blizzard/btn-upgrade-swann-hellarmor.png", - "Cerberus Mine (Spider Mine)": github_icon_base_url + "blizzard/btn-upgrade-raynor-cerberusmines.png", - "High Explosive Munition (Spider Mine)": github_icon_base_url + "original/btn-ability-terran-spidermine.png", - "Replenishable Magazine (Vulture)": github_icon_base_url + "blizzard/btn-upgrade-raynor-replenishablemagazine.png", - "Replenishable Magazine (Free) (Vulture)": github_icon_base_url + "blizzard/btn-upgrade-raynor-replenishablemagazine.png", - "Ion Thrusters (Vulture)": github_icon_base_url + "blizzard/btn-ability-terran-emergencythrusters.png", - "Auto Launchers (Vulture)": github_icon_base_url + "blizzard/btn-upgrade-terran-jotunboosters.png", - "Auto-Repair (Vulture)": github_icon_base_url + "blizzard/ui_tipicon_campaign_space01-repair.png", - "Multi-Lock Weapons System (Goliath)": github_icon_base_url + "blizzard/btn-upgrade-swann-multilockweaponsystem.png", - "Ares-Class Targeting System (Goliath)": github_icon_base_url + "blizzard/btn-upgrade-swann-aresclasstargetingsystem.png", - "Jump Jets (Goliath)": github_icon_base_url + "blizzard/btn-upgrade-terran-jumpjets.png", - "Optimized Logistics (Goliath)": github_icon_base_url + "blizzard/btn-upgrade-terran-optimizedlogistics.png", - "Shaped Hull (Goliath)": organics_icon_base_url + "ShapedHull.png", - "Resource Efficiency (Goliath)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Internal Tech Module (Goliath)": github_icon_base_url + "blizzard/btn-upgrade-terran-internalizedtechmodule.png", - "Tri-Lithium Power Cell (Diamondback)": github_icon_base_url + "original/btn-upgrade-terran-trilithium-power-cell.png", - "Tungsten Spikes (Diamondback)": github_icon_base_url + "original/btn-upgrade-terran-tungsten-spikes.png", - "Shaped Hull (Diamondback)": organics_icon_base_url + "ShapedHull.png", - "Hyperfluxor (Diamondback)": github_icon_base_url + "blizzard/btn-upgrade-mengsk-engineeringbay-orbitaldrop.png", - "Burst Capacitors (Diamondback)": github_icon_base_url + "blizzard/btn-ability-terran-electricfield.png", - "Ion Thrusters (Diamondback)": github_icon_base_url + "blizzard/btn-ability-terran-emergencythrusters.png", - "Resource Efficiency (Diamondback)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Maelstrom Rounds (Siege Tank)": github_icon_base_url + "blizzard/btn-upgrade-raynor-maelstromrounds.png", - "Shaped Blast (Siege Tank)": organics_icon_base_url + "ShapedBlast.png", - "Jump Jets (Siege Tank)": github_icon_base_url + "blizzard/btn-upgrade-terran-jumpjets.png", - "Spider Mines (Siege Tank)": github_icon_base_url + "blizzard/btn-upgrade-siegetank-spidermines.png", - "Smart Servos (Siege Tank)": github_icon_base_url + "blizzard/btn-upgrade-terran-transformationservos.png", - "Graduating Range (Siege Tank)": github_icon_base_url + "blizzard/btn-upgrade-terran-nova-siegetankrange.png", - "Laser Targeting System (Siege Tank)": github_icon_base_url + "blizzard/btn-upgrade-terran-lazertargetingsystem.png", - "Advanced Siege Tech (Siege Tank)": github_icon_base_url + "blizzard/btn-upgrade-raynor-improvedsiegemode.png", - "Internal Tech Module (Siege Tank)": github_icon_base_url + "blizzard/btn-upgrade-terran-internalizedtechmodule.png", - "Shaped Hull (Siege Tank)": organics_icon_base_url + "ShapedHull.png", - "Resource Efficiency (Siege Tank)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "330mm Barrage Cannon (Thor)": github_icon_base_url + "original/btn-ability-thor-330mm.png", - "Immortality Protocol (Thor)": github_icon_base_url + "blizzard/btn-techupgrade-terran-immortalityprotocol.png", - "Immortality Protocol (Free) (Thor)": github_icon_base_url + "blizzard/btn-techupgrade-terran-immortalityprotocol.png", - "High Impact Payload (Thor)": github_icon_base_url + "blizzard/btn-unit-terran-thorsiegemode.png", - "Smart Servos (Thor)": github_icon_base_url + "blizzard/btn-upgrade-terran-transformationservos.png", - "Button With a Skull on It (Thor)": github_icon_base_url + "blizzard/btn-ability-terran-nuclearstrike-color.png", - "Laser Targeting System (Thor)": github_icon_base_url + "blizzard/btn-upgrade-terran-lazertargetingsystem.png", - "Large Scale Field Construction (Thor)": github_icon_base_url + "blizzard/talent-swann-level12-immortalityprotocol.png", - "Resource Efficiency (Predator)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Cloak (Predator)": github_icon_base_url + "blizzard/btn-ability-terran-cloak-color.png", - "Charge (Predator)": github_icon_base_url + "blizzard/btn-ability-protoss-charge-color.png", - "Predator's Fury (Predator)": github_icon_base_url + "blizzard/btn-ability-protoss-shadowfury.png", - "Drilling Claws (Widow Mine)": github_icon_base_url + "blizzard/btn-upgrade-terran-researchdrillingclaws.png", - "Concealment (Widow Mine)": github_icon_base_url + "blizzard/btn-ability-terran-widowminehidden.png", - "Black Market Launchers (Widow Mine)": github_icon_base_url + "blizzard/btn-ability-hornerhan-widowmine-attackrange.png", - "Executioner Missiles (Widow Mine)": github_icon_base_url + "blizzard/btn-ability-hornerhan-widowmine-deathblossom.png", - "Mag-Field Accelerators (Cyclone)": github_icon_base_url + "blizzard/btn-upgrade-terran-magfieldaccelerator.png", - "Mag-Field Launchers (Cyclone)": github_icon_base_url + "blizzard/btn-upgrade-terran-cyclonerangeupgrade.png", - "Targeting Optics (Cyclone)": github_icon_base_url + "blizzard/btn-upgrade-swann-targetingoptics.png", - "Rapid Fire Launchers (Cyclone)": github_icon_base_url + "blizzard/btn-upgrade-raynor-ripwavemissiles.png", - "Resource Efficiency (Cyclone)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Internal Tech Module (Cyclone)": github_icon_base_url + "blizzard/btn-upgrade-terran-internalizedtechmodule.png", - "Resource Efficiency (Warhound)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Reinforced Plating (Warhound)": github_icon_base_url + "original/btn-research-zerg-fortifiedbunker.png", - - "Medivac": "https://static.wikia.nocookie.net/starcraft/images/d/db/Medivac_SC2_Icon1.jpg", - "Wraith": github_icon_base_url + "blizzard/btn-unit-terran-wraith.png", - "Viking": "https://static.wikia.nocookie.net/starcraft/images/2/2a/Viking_SC2_Icon1.jpg", - "Banshee": "https://static.wikia.nocookie.net/starcraft/images/3/32/Banshee_SC2_Icon1.jpg", - "Battlecruiser": "https://static.wikia.nocookie.net/starcraft/images/f/f5/Battlecruiser_SC2_Icon1.jpg", - "Raven": "https://static.wikia.nocookie.net/starcraft/images/1/19/SC2_Lab_Raven_Icon.png", - "Science Vessel": "https://static.wikia.nocookie.net/starcraft/images/c/c3/SC2_Lab_SciVes_Icon.png", - "Hercules": "https://static.wikia.nocookie.net/starcraft/images/4/40/SC2_Lab_Hercules_Icon.png", - "Liberator": github_icon_base_url + "blizzard/btn-unit-terran-liberator.png", - "Valkyrie": github_icon_base_url + "original/btn-unit-terran-valkyrie@scbw.png", - - "Rapid Deployment Tube (Medivac)": organics_icon_base_url + "RapidDeploymentTube.png", - "Advanced Healing AI (Medivac)": github_icon_base_url + "blizzard/btn-ability-mengsk-medivac-doublehealbeam.png", - "Expanded Hull (Medivac)": github_icon_base_url + "blizzard/btn-upgrade-mengsk-engineeringbay-neosteelfortifiedarmor.png", - "Afterburners (Medivac)": github_icon_base_url + "blizzard/btn-upgrade-terran-medivacemergencythrusters.png", - "Scatter Veil (Medivac)": github_icon_base_url + "blizzard/btn-upgrade-swann-defensivematrix.png", - "Advanced Cloaking Field (Medivac)": github_icon_base_url + "original/btn-permacloak-medivac.png", - "Tomahawk Power Cells (Wraith)": organics_icon_base_url + "TomahawkPowerCells.png", - "Unregistered Cloaking Module (Wraith)": github_icon_base_url + "original/btn-permacloak-wraith.png", - "Trigger Override (Wraith)": github_icon_base_url + "blizzard/btn-ability-hornerhan-wraith-attackspeed.png", - "Internal Tech Module (Wraith)": github_icon_base_url + "blizzard/btn-upgrade-terran-internalizedtechmodule.png", - "Resource Efficiency (Wraith)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Displacement Field (Wraith)": github_icon_base_url + "blizzard/btn-upgrade-swann-displacementfield.png", - "Advanced Laser Technology (Wraith)": github_icon_base_url + "blizzard/btn-upgrade-swann-improvedburstlaser.png", - "Ripwave Missiles (Viking)": github_icon_base_url + "blizzard/btn-upgrade-raynor-ripwavemissiles.png", - "Phobos-Class Weapons System (Viking)": github_icon_base_url + "blizzard/btn-upgrade-raynor-phobosclassweaponssystem.png", - "Smart Servos (Viking)": github_icon_base_url + "blizzard/btn-upgrade-terran-transformationservos.png", - "Anti-Mechanical Munition (Viking)": github_icon_base_url + "blizzard/btn-ability-terran-ignorearmor.png", - "Shredder Rounds (Viking)": github_icon_base_url + "blizzard/btn-ability-hornerhan-viking-piercingattacks.png", - "W.I.L.D. Missiles (Viking)": github_icon_base_url + "blizzard/btn-ability-hornerhan-viking-missileupgrade.png", - "Cross-Spectrum Dampeners (Banshee)": github_icon_base_url + "original/btn-banshee-cross-spectrum-dampeners.png", - "Advanced Cross-Spectrum Dampeners (Banshee)": github_icon_base_url + "original/btn-permacloak-banshee.png", - "Shockwave Missile Battery (Banshee)": github_icon_base_url + "blizzard/btn-upgrade-raynor-shockwavemissilebattery.png", - "Hyperflight Rotors (Banshee)": github_icon_base_url + "blizzard/btn-upgrade-terran-hyperflightrotors.png", - "Laser Targeting System (Banshee)": github_icon_base_url + "blizzard/btn-upgrade-terran-lazertargetingsystem.png", - "Internal Tech Module (Banshee)": github_icon_base_url + "blizzard/btn-upgrade-terran-internalizedtechmodule.png", - "Shaped Hull (Banshee)": organics_icon_base_url + "ShapedHull.png", - "Advanced Targeting Optics (Banshee)": github_icon_base_url + "blizzard/btn-ability-terran-detectionconedebuff.png", - "Distortion Blasters (Banshee)": github_icon_base_url + "blizzard/btn-techupgrade-terran-cloakdistortionfield.png", - "Rocket Barrage (Banshee)": github_icon_base_url + "blizzard/btn-upgrade-terran-nova-bansheemissilestrik.png", - "Missile Pods (Battlecruiser) Level 1": organics_icon_base_url + "MissilePods.png", - "Missile Pods (Battlecruiser) Level 2": github_icon_base_url + "blizzard/btn-upgrade-terran-nova-bansheemissilestrik.png", - "Defensive Matrix (Battlecruiser)": github_icon_base_url + "blizzard/btn-upgrade-swann-defensivematrix.png", - "Advanced Defensive Matrix (Battlecruiser)": github_icon_base_url + "blizzard/btn-upgrade-swann-defensivematrix.png", - "Tactical Jump (Battlecruiser)": github_icon_base_url + "blizzard/btn-ability-terran-warpjump.png", - "Cloak (Battlecruiser)": github_icon_base_url + "blizzard/btn-ability-terran-cloak-color.png", - "ATX Laser Battery (Battlecruiser)": github_icon_base_url + "blizzard/btn-upgrade-terran-nova-specialordance.png", - "Optimized Logistics (Battlecruiser)": github_icon_base_url + "blizzard/btn-upgrade-terran-optimizedlogistics.png", - "Internal Tech Module (Battlecruiser)": github_icon_base_url + "blizzard/btn-upgrade-terran-internalizedtechmodule.png", - "Behemoth Plating (Battlecruiser)": github_icon_base_url + "original/btn-research-zerg-fortifiedbunker.png", - "Covert Ops Engines (Battlecruiser)": github_icon_base_url + "blizzard/btn-ability-terran-emergencythrusters.png", - "Bio Mechanical Repair Drone (Raven)": github_icon_base_url + "blizzard/btn-unit-biomechanicaldrone.png", - "Spider Mines (Raven)": github_icon_base_url + "blizzard/btn-upgrade-siegetank-spidermines.png", - "Railgun Turret (Raven)": github_icon_base_url + "blizzard/btn-unit-terran-autoturretblackops.png", - "Hunter-Seeker Weapon (Raven)": github_icon_base_url + "blizzard/btn-upgrade-terran-nova-specialordance.png", - "Interference Matrix (Raven)": github_icon_base_url + "blizzard/btn-upgrade-terran-interferencematrix.png", - "Anti-Armor Missile (Raven)": github_icon_base_url + "blizzard/btn-ability-terran-shreddermissile-color.png", - "Internal Tech Module (Raven)": github_icon_base_url + "blizzard/btn-upgrade-terran-internalizedtechmodule.png", - "Resource Efficiency (Raven)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Durable Materials (Raven)": github_icon_base_url + "blizzard/btn-upgrade-terran-durablematerials.png", - "EMP Shockwave (Science Vessel)": github_icon_base_url + "blizzard/btn-ability-mengsk-ghost-staticempblast.png", - "Defensive Matrix (Science Vessel)": github_icon_base_url + "blizzard/btn-upgrade-swann-defensivematrix.png", - "Improved Nano-Repair (Science Vessel)": github_icon_base_url + "blizzard/btn-upgrade-swann-improvednanorepair.png", - "Advanced AI Systems (Science Vessel)": github_icon_base_url + "blizzard/btn-ability-mengsk-medivac-doublehealbeam.png", - "Internal Fusion Module (Hercules)": github_icon_base_url + "blizzard/btn-upgrade-terran-internalizedtechmodule.png", - "Tactical Jump (Hercules)": github_icon_base_url + "blizzard/btn-ability-terran-hercules-tacticaljump.png", - "Advanced Ballistics (Liberator)": github_icon_base_url + "blizzard/btn-upgrade-terran-advanceballistics.png", - "Raid Artillery (Liberator)": github_icon_base_url + "blizzard/btn-upgrade-terran-nova-terrandefendermodestructureattack.png", - "Cloak (Liberator)": github_icon_base_url + "blizzard/btn-ability-terran-cloak-color.png", - "Laser Targeting System (Liberator)": github_icon_base_url + "blizzard/btn-upgrade-terran-lazertargetingsystem.png", - "Optimized Logistics (Liberator)": github_icon_base_url + "blizzard/btn-upgrade-terran-optimizedlogistics.png", - "Smart Servos (Liberator)": github_icon_base_url + "blizzard/btn-upgrade-terran-transformationservos.png", - "Resource Efficiency (Liberator)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Enhanced Cluster Launchers (Valkyrie)": github_icon_base_url + "blizzard/btn-ability-stetmann-corruptormissilebarrage.png", - "Shaped Hull (Valkyrie)": organics_icon_base_url + "ShapedHull.png", - "Flechette Missiles (Valkyrie)": github_icon_base_url + "blizzard/btn-ability-hornerhan-viking-missileupgrade.png", - "Afterburners (Valkyrie)": github_icon_base_url + "blizzard/btn-upgrade-terran-medivacemergencythrusters.png", - "Launching Vector Compensator (Valkyrie)": github_icon_base_url + "blizzard/btn-ability-terran-emergencythrusters.png", - "Resource Efficiency (Valkyrie)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - - "War Pigs": "https://static.wikia.nocookie.net/starcraft/images/e/ed/WarPigs_SC2_Icon1.jpg", - "Devil Dogs": "https://static.wikia.nocookie.net/starcraft/images/3/33/DevilDogs_SC2_Icon1.jpg", - "Hammer Securities": "https://static.wikia.nocookie.net/starcraft/images/3/3b/HammerSecurity_SC2_Icon1.jpg", - "Spartan Company": "https://static.wikia.nocookie.net/starcraft/images/b/be/SpartanCompany_SC2_Icon1.jpg", - "Siege Breakers": "https://static.wikia.nocookie.net/starcraft/images/3/31/SiegeBreakers_SC2_Icon1.jpg", - "Hel's Angels": "https://static.wikia.nocookie.net/starcraft/images/6/63/HelsAngels_SC2_Icon1.jpg", - "Dusk Wings": "https://static.wikia.nocookie.net/starcraft/images/5/52/DuskWings_SC2_Icon1.jpg", - "Jackson's Revenge": "https://static.wikia.nocookie.net/starcraft/images/9/95/JacksonsRevenge_SC2_Icon1.jpg", - "Skibi's Angels": github_icon_base_url + "blizzard/btn-unit-terran-medicelite.png", - "Death Heads": github_icon_base_url + "blizzard/btn-unit-terran-deathhead.png", - "Winged Nightmares": github_icon_base_url + "blizzard/btn-unit-collection-wraith-junker.png", - "Midnight Riders": github_icon_base_url + "blizzard/btn-unit-terran-liberatorblackops.png", - "Brynhilds": github_icon_base_url + "blizzard/btn-unit-collection-vikingfighter-covertops.png", - "Jotun": github_icon_base_url + "blizzard/btn-unit-terran-thormengsk.png", - - "Ultra-Capacitors": "https://static.wikia.nocookie.net/starcraft/images/2/23/SC2_Lab_Ultra_Capacitors_Icon.png", - "Vanadium Plating": "https://static.wikia.nocookie.net/starcraft/images/6/67/SC2_Lab_VanPlating_Icon.png", - "Orbital Depots": "https://static.wikia.nocookie.net/starcraft/images/0/01/SC2_Lab_Orbital_Depot_Icon.png", - "Micro-Filtering": "https://static.wikia.nocookie.net/starcraft/images/2/20/SC2_Lab_MicroFilter_Icon.png", - "Automated Refinery": "https://static.wikia.nocookie.net/starcraft/images/7/71/SC2_Lab_Auto_Refinery_Icon.png", - "Command Center Reactor": "https://static.wikia.nocookie.net/starcraft/images/e/ef/SC2_Lab_CC_Reactor_Icon.png", - "Tech Reactor": "https://static.wikia.nocookie.net/starcraft/images/c/c5/SC2_Lab_Tech_Reactor_Icon.png", - "Orbital Strike": "https://static.wikia.nocookie.net/starcraft/images/d/df/SC2_Lab_Orb_Strike_Icon.png", - - "Shrike Turret (Bunker)": "https://static.wikia.nocookie.net/starcraft/images/4/44/SC2_Lab_Shrike_Turret_Icon.png", - "Fortified Bunker (Bunker)": "https://static.wikia.nocookie.net/starcraft/images/4/4f/SC2_Lab_FortBunker_Icon.png", - "Planetary Fortress": "https://static.wikia.nocookie.net/starcraft/images/0/0b/SC2_Lab_PlanetFortress_Icon.png", - "Perdition Turret": "https://static.wikia.nocookie.net/starcraft/images/a/af/SC2_Lab_PerdTurret_Icon.png", - "Cellular Reactor": "https://static.wikia.nocookie.net/starcraft/images/d/d8/SC2_Lab_CellReactor_Icon.png", - "Regenerative Bio-Steel Level 1": github_icon_base_url + "original/btn-regenerativebiosteel-green.png", - "Regenerative Bio-Steel Level 2": github_icon_base_url + "original/btn-regenerativebiosteel-blue.png", - "Regenerative Bio-Steel Level 3": github_icon_base_url + "blizzard/btn-research-zerg-regenerativebio-steel.png", - "Hive Mind Emulator": "https://static.wikia.nocookie.net/starcraft/images/b/bc/SC2_Lab_Hive_Emulator_Icon.png", - "Psi Disrupter": "https://static.wikia.nocookie.net/starcraft/images/c/cf/SC2_Lab_Psi_Disruptor_Icon.png", - - "Structure Armor": github_icon_base_url + "blizzard/btn-upgrade-terran-buildingarmor.png", - "Hi-Sec Auto Tracking": github_icon_base_url + "blizzard/btn-upgrade-terran-hisecautotracking.png", - "Advanced Optics": github_icon_base_url + "blizzard/btn-upgrade-swann-vehiclerangeincrease.png", - "Rogue Forces": github_icon_base_url + "blizzard/btn-unit-terran-tosh.png", - - "Ghost Visor (Nova Equipment)": github_icon_base_url + "blizzard/btn-upgrade-nova-equipment-ghostvisor.png", - "Rangefinder Oculus (Nova Equipment)": github_icon_base_url + "blizzard/btn-upgrade-nova-equipment-rangefinderoculus.png", - "Domination (Nova Ability)": github_icon_base_url + "blizzard/btn-ability-nova-domination.png", - "Blink (Nova Ability)": github_icon_base_url + "blizzard/btn-upgrade-nova-blink.png", - "Stealth Suit Module (Nova Suit Module)": github_icon_base_url + "blizzard/btn-upgrade-nova-equipment-stealthsuit.png", - "Cloak (Nova Suit Module)": github_icon_base_url + "blizzard/btn-ability-terran-cloak-color.png", - "Permanently Cloaked (Nova Suit Module)": github_icon_base_url + "blizzard/btn-upgrade-nova-tacticalstealthsuit.png", - "Energy Suit Module (Nova Suit Module)": github_icon_base_url + "blizzard/btn-upgrade-nova-equipment-apolloinfantrysuit.png", - "Armored Suit Module (Nova Suit Module)": github_icon_base_url + "blizzard/btn-upgrade-nova-equipment-blinksuit.png", - "Jump Suit Module (Nova Suit Module)": github_icon_base_url + "blizzard/btn-upgrade-nova-jetpack.png", - "C20A Canister Rifle (Nova Weapon)": github_icon_base_url + "blizzard/btn-upgrade-nova-equipment-canisterrifle.png", - "Hellfire Shotgun (Nova Weapon)": github_icon_base_url + "blizzard/btn-upgrade-nova-equipment-shotgun.png", - "Plasma Rifle (Nova Weapon)": github_icon_base_url + "blizzard/btn-upgrade-nova-equipment-plasmagun.png", - "Monomolecular Blade (Nova Weapon)": github_icon_base_url + "blizzard/btn-upgrade-nova-equipment-monomolecularblade.png", - "Blazefire Gunblade (Nova Weapon)": github_icon_base_url + "blizzard/btn-upgrade-nova-equipment-gunblade_sword.png", - "Stim Infusion (Nova Gadget)": github_icon_base_url + "blizzard/btn-upgrade-terran-superstimppack.png", - "Pulse Grenades (Nova Gadget)": github_icon_base_url + "blizzard/btn-upgrade-nova-btn-upgrade-nova-pulsegrenade.png", - "Flashbang Grenades (Nova Gadget)": github_icon_base_url + "blizzard/btn-upgrade-nova-btn-upgrade-nova-flashgrenade.png", - "Ionic Force Field (Nova Gadget)": github_icon_base_url + "blizzard/btn-upgrade-terran-nova-personaldefensivematrix.png", - "Holo Decoy (Nova Gadget)": github_icon_base_url + "blizzard/btn-upgrade-nova-holographicdecoy.png", - "Tac Nuke Strike (Nova Ability)": github_icon_base_url + "blizzard/btn-ability-terran-nuclearstrike-color.png", - - "Zerg Melee Attack Level 1": github_icon_base_url + "blizzard/btn-upgrade-zerg-meleeattacks-level1.png", - "Zerg Melee Attack Level 2": github_icon_base_url + "blizzard/btn-upgrade-zerg-meleeattacks-level2.png", - "Zerg Melee Attack Level 3": github_icon_base_url + "blizzard/btn-upgrade-zerg-meleeattacks-level3.png", - "Zerg Missile Attack Level 1": github_icon_base_url + "blizzard/btn-upgrade-zerg-missileattacks-level1.png", - "Zerg Missile Attack Level 2": github_icon_base_url + "blizzard/btn-upgrade-zerg-missileattacks-level2.png", - "Zerg Missile Attack Level 3": github_icon_base_url + "blizzard/btn-upgrade-zerg-missileattacks-level3.png", - "Zerg Ground Carapace Level 1": github_icon_base_url + "blizzard/btn-upgrade-zerg-groundcarapace-level1.png", - "Zerg Ground Carapace Level 2": github_icon_base_url + "blizzard/btn-upgrade-zerg-groundcarapace-level2.png", - "Zerg Ground Carapace Level 3": github_icon_base_url + "blizzard/btn-upgrade-zerg-groundcarapace-level3.png", - "Zerg Flyer Attack Level 1": github_icon_base_url + "blizzard/btn-upgrade-zerg-airattacks-level1.png", - "Zerg Flyer Attack Level 2": github_icon_base_url + "blizzard/btn-upgrade-zerg-airattacks-level2.png", - "Zerg Flyer Attack Level 3": github_icon_base_url + "blizzard/btn-upgrade-zerg-airattacks-level3.png", - "Zerg Flyer Carapace Level 1": github_icon_base_url + "blizzard/btn-upgrade-zerg-flyercarapace-level1.png", - "Zerg Flyer Carapace Level 2": github_icon_base_url + "blizzard/btn-upgrade-zerg-flyercarapace-level2.png", - "Zerg Flyer Carapace Level 3": github_icon_base_url + "blizzard/btn-upgrade-zerg-flyercarapace-level3.png", - - "Automated Extractors (Kerrigan Tier 3)": github_icon_base_url + "blizzard/btn-ability-kerrigan-automatedextractors.png", - "Vespene Efficiency (Kerrigan Tier 5)": github_icon_base_url + "blizzard/btn-ability-kerrigan-vespeneefficiency.png", - "Twin Drones (Kerrigan Tier 5)": github_icon_base_url + "blizzard/btn-ability-kerrigan-twindrones.png", - "Improved Overlords (Kerrigan Tier 3)": github_icon_base_url + "blizzard/btn-ability-kerrigan-improvedoverlords.png", - "Ventral Sacs (Overlord)": github_icon_base_url + "blizzard/btn-upgrade-zerg-ventralsacs.png", - "Malignant Creep (Kerrigan Tier 5)": github_icon_base_url + "blizzard/btn-ability-kerrigan-malignantcreep.png", - - "Spine Crawler": github_icon_base_url + "blizzard/btn-building-zerg-spinecrawler.png", - "Spore Crawler": github_icon_base_url + "blizzard/btn-building-zerg-sporecrawler.png", - - "Zergling": github_icon_base_url + "blizzard/btn-unit-zerg-zergling.png", - "Swarm Queen": github_icon_base_url + "blizzard/btn-unit-zerg-broodqueen.png", - "Roach": github_icon_base_url + "blizzard/btn-unit-zerg-roach.png", - "Hydralisk": github_icon_base_url + "blizzard/btn-unit-zerg-hydralisk.png", - "Aberration": github_icon_base_url + "blizzard/btn-unit-zerg-aberration.png", - "Mutalisk": github_icon_base_url + "blizzard/btn-unit-zerg-mutalisk.png", - "Corruptor": github_icon_base_url + "blizzard/btn-unit-zerg-corruptor.png", - "Swarm Host": github_icon_base_url + "blizzard/btn-unit-zerg-swarmhost.png", - "Infestor": github_icon_base_url + "blizzard/btn-unit-zerg-infestor.png", - "Defiler": github_icon_base_url + "original/btn-unit-zerg-defiler@scbw.png", - "Ultralisk": github_icon_base_url + "blizzard/btn-unit-zerg-ultralisk.png", - "Brood Queen": github_icon_base_url + "blizzard/btn-unit-zerg-classicqueen.png", - "Scourge": github_icon_base_url + "blizzard/btn-unit-zerg-scourge.png", - - "Baneling Aspect (Zergling)": github_icon_base_url + "blizzard/btn-unit-zerg-baneling.png", - "Ravager Aspect (Roach)": github_icon_base_url + "blizzard/btn-unit-zerg-ravager.png", - "Impaler Aspect (Hydralisk)": github_icon_base_url + "blizzard/btn-unit-zerg-impaler.png", - "Lurker Aspect (Hydralisk)": github_icon_base_url + "blizzard/btn-unit-zerg-lurker.png", - "Brood Lord Aspect (Mutalisk/Corruptor)": github_icon_base_url + "blizzard/btn-unit-zerg-broodlord.png", - "Viper Aspect (Mutalisk/Corruptor)": github_icon_base_url + "blizzard/btn-unit-zerg-viper.png", - "Guardian Aspect (Mutalisk/Corruptor)": github_icon_base_url + "blizzard/btn-unit-zerg-primalguardian.png", - "Devourer Aspect (Mutalisk/Corruptor)": github_icon_base_url + "blizzard/btn-unit-zerg-devourerex3.png", - - "Raptor Strain (Zergling)": github_icon_base_url + "blizzard/btn-unit-zerg-zergling-raptor.png", - "Swarmling Strain (Zergling)": github_icon_base_url + "blizzard/btn-unit-zerg-zergling-swarmling.png", - "Hardened Carapace (Zergling)": github_icon_base_url + "blizzard/btn-upgrade-zerg-hardenedcarapace.png", - "Adrenal Overload (Zergling)": github_icon_base_url + "blizzard/btn-upgrade-zerg-adrenaloverload.png", - "Metabolic Boost (Zergling)": github_icon_base_url + "blizzard/btn-upgrade-zerg-hotsmetabolicboost.png", - "Shredding Claws (Zergling)": github_icon_base_url + "blizzard/btn-upgrade-zergling-armorshredding.png", - "Zergling Reconstitution (Kerrigan Tier 3)": github_icon_base_url + "blizzard/btn-ability-kerrigan-zerglingreconstitution.png", - "Splitter Strain (Baneling)": github_icon_base_url + "blizzard/talent-zagara-level14-unlocksplitterling.png", - "Hunter Strain (Baneling)": github_icon_base_url + "blizzard/btn-ability-zerg-cliffjump-baneling.png", - "Corrosive Acid (Baneling)": github_icon_base_url + "blizzard/btn-upgrade-zerg-corrosiveacid.png", - "Rupture (Baneling)": github_icon_base_url + "blizzard/btn-upgrade-zerg-rupture.png", - "Regenerative Acid (Baneling)": github_icon_base_url + "blizzard/btn-upgrade-zerg-regenerativebile.png", - "Centrifugal Hooks (Baneling)": github_icon_base_url + "blizzard/btn-upgrade-zerg-centrifugalhooks.png", - "Tunneling Jaws (Baneling)": github_icon_base_url + "blizzard/btn-upgrade-zerg-tunnelingjaws.png", - "Rapid Metamorph (Baneling)": github_icon_base_url + "blizzard/btn-upgrade-terran-optimizedlogistics.png", - "Spawn Larvae (Swarm Queen)": github_icon_base_url + "blizzard/btn-unit-zerg-larva.png", - "Deep Tunnel (Swarm Queen)": github_icon_base_url + "blizzard/btn-ability-zerg-deeptunnel.png", - "Organic Carapace (Swarm Queen)": github_icon_base_url + "blizzard/btn-upgrade-zerg-organiccarapace.png", - "Bio-Mechanical Transfusion (Swarm Queen)": github_icon_base_url + "blizzard/btn-upgrade-zerg-abathur-biomechanicaltransfusion.png", - "Resource Efficiency (Swarm Queen)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Incubator Chamber (Swarm Queen)": github_icon_base_url + "blizzard/btn-upgrade-zerg-abathur-incubationchamber.png", - "Vile Strain (Roach)": github_icon_base_url + "blizzard/btn-unit-zerg-roach-vile.png", - "Corpser Strain (Roach)": github_icon_base_url + "blizzard/btn-unit-zerg-roach-corpser.png", - "Hydriodic Bile (Roach)": github_icon_base_url + "blizzard/btn-upgrade-zerg-hydriaticacid.png", - "Adaptive Plating (Roach)": github_icon_base_url + "blizzard/btn-upgrade-zerg-adaptivecarapace.png", - "Tunneling Claws (Roach)": github_icon_base_url + "blizzard/btn-upgrade-zerg-hotstunnelingclaws.png", - "Glial Reconstitution (Roach)": github_icon_base_url + "blizzard/btn-upgrade-zerg-glialreconstitution.png", - "Organic Carapace (Roach)": github_icon_base_url + "blizzard/btn-upgrade-zerg-organiccarapace.png", - "Potent Bile (Ravager)": github_icon_base_url + "blizzard/potentbile_coop.png", - "Bloated Bile Ducts (Ravager)": github_icon_base_url + "blizzard/btn-ability-zerg-abathur-corrosivebilelarge.png", - "Deep Tunnel (Ravager)": github_icon_base_url + "blizzard/btn-ability-zerg-deeptunnel.png", - "Frenzy (Hydralisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-frenzy.png", - "Ancillary Carapace (Hydralisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-ancillaryarmor.png", - "Grooved Spines (Hydralisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-hotsgroovedspines.png", - "Muscular Augments (Hydralisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-evolvemuscularaugments.png", - "Resource Efficiency (Hydralisk)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Adaptive Talons (Impaler)": github_icon_base_url + "blizzard/btn-upgrade-zerg-adaptivetalons.png", - "Secretion Glands (Impaler)": github_icon_base_url + "blizzard/btn-ability-zerg-creepspread.png", - "Hardened Tentacle Spines (Impaler)": github_icon_base_url + "blizzard/btn-ability-zerg-dehaka-impaler-tenderize.png", - "Seismic Spines (Lurker)": github_icon_base_url + "blizzard/btn-upgrade-kerrigan-seismicspines.png", - "Adapted Spines (Lurker)": github_icon_base_url + "blizzard/btn-upgrade-zerg-groovedspines.png", - "Vicious Glaive (Mutalisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-viciousglaive.png", - "Rapid Regeneration (Mutalisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-rapidregeneration.png", - "Sundering Glaive (Mutalisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-explosiveglaive.png", - "Severing Glaive (Mutalisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-explosiveglaive.png", - "Aerodynamic Glaive Shape (Mutalisk)": github_icon_base_url + "blizzard/btn-ability-dehaka-airbonusdamage.png", - "Corruption (Corruptor)": github_icon_base_url + "blizzard/btn-ability-zerg-causticspray.png", - "Caustic Spray (Corruptor)": github_icon_base_url + "blizzard/btn-ability-zerg-corruption-color.png", - "Porous Cartilage (Brood Lord)": github_icon_base_url + "blizzard/btn-upgrade-kerrigan-broodlordspeed.png", - "Evolved Carapace (Brood Lord)": github_icon_base_url + "blizzard/btn-upgrade-zerg-chitinousplating.png", - "Splitter Mitosis (Brood Lord)": github_icon_base_url + "blizzard/abilityicon_spawnbroodlings_square.png", - "Resource Efficiency (Brood Lord)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Parasitic Bomb (Viper)": github_icon_base_url + "blizzard/btn-ability-zerg-parasiticbomb.png", - "Paralytic Barbs (Viper)": github_icon_base_url + "blizzard/btn-upgrade-zerg-abathur-abduct.png", - "Virulent Microbes (Viper)": github_icon_base_url + "blizzard/btn-upgrade-zerg-abathur-castrange.png", - "Prolonged Dispersion (Guardian)": github_icon_base_url + "blizzard/btn-upgrade-zerg-abathur-prolongeddispersion.png", - "Primal Adaptation (Guardian)": github_icon_base_url + "blizzard/biomassrecovery_coop.png", - "Soronan Acid (Guardian)": github_icon_base_url + "blizzard/btn-upgrade-zerg-abathur-biomass.png", - "Corrosive Spray (Devourer)": github_icon_base_url + "blizzard/btn-upgrade-zerg-abathur-devourer-corrosivespray.png", - "Gaping Maw (Devourer)": github_icon_base_url + "blizzard/btn-ability-zerg-explode-color.png", - "Improved Osmosis (Devourer)": github_icon_base_url + "blizzard/btn-upgrade-zerg-pneumatizedcarapace.png", - "Prescient Spores (Devourer)": github_icon_base_url + "blizzard/btn-upgrade-zerg-airattacks-level2.png", - "Carrion Strain (Swarm Host)": github_icon_base_url + "blizzard/btn-unit-zerg-swarmhost-carrion.png", - "Creeper Strain (Swarm Host)": github_icon_base_url + "blizzard/btn-unit-zerg-swarmhost-creeper.png", - "Burrow (Swarm Host)": github_icon_base_url + "blizzard/btn-ability-zerg-burrow-color.png", - "Rapid Incubation (Swarm Host)": github_icon_base_url + "blizzard/btn-upgrade-zerg-rapidincubation.png", - "Pressurized Glands (Swarm Host)": github_icon_base_url + "blizzard/btn-upgrade-zerg-pressurizedglands.png", - "Locust Metabolic Boost (Swarm Host)": github_icon_base_url + "blizzard/btn-upgrade-zerg-glialreconstitution.png", - "Enduring Locusts (Swarm Host)": github_icon_base_url + "blizzard/btn-upgrade-zerg-evolveincreasedlocustlifetime.png", - "Organic Carapace (Swarm Host)": github_icon_base_url + "blizzard/btn-upgrade-zerg-organiccarapace.png", - "Resource Efficiency (Swarm Host)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Infested Terran (Infestor)": github_icon_base_url + "blizzard/btn-unit-zerg-infestedmarine.png", - "Microbial Shroud (Infestor)": github_icon_base_url + "blizzard/btn-ability-zerg-darkswarm.png", - "Noxious Strain (Ultralisk)": github_icon_base_url + "blizzard/btn-unit-zerg-ultralisk-noxious.png", - "Torrasque Strain (Ultralisk)": github_icon_base_url + "blizzard/btn-unit-zerg-ultralisk-torrasque.png", - "Burrow Charge (Ultralisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-burrowcharge.png", - "Tissue Assimilation (Ultralisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-tissueassimilation.png", - "Monarch Blades (Ultralisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-monarchblades.png", - "Anabolic Synthesis (Ultralisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-anabolicsynthesis.png", - "Chitinous Plating (Ultralisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-chitinousplating.png", - "Organic Carapace (Ultralisk)": github_icon_base_url + "blizzard/btn-upgrade-zerg-organiccarapace.png", - "Resource Efficiency (Ultralisk)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Fungal Growth (Brood Queen)": github_icon_base_url + "blizzard/btn-upgrade-zerg-stukov-researchqueenfungalgrowth.png", - "Ensnare (Brood Queen)": github_icon_base_url + "blizzard/btn-ability-zerg-fungalgrowth-color.png", - "Enhanced Mitochondria (Brood Queen)": github_icon_base_url + "blizzard/btn-upgrade-zerg-stukov-queenenergyregen.png", - "Virulent Spores (Scourge)": github_icon_base_url + "blizzard/btn-upgrade-zagara-scourgesplashdamage.png", - "Resource Efficiency (Scourge)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Swarm Scourge (Scourge)": github_icon_base_url + "original/btn-upgrade-custom-triple-scourge.png", - - "Infested Medics": github_icon_base_url + "blizzard/btn-unit-terran-medicelite.png", - "Infested Siege Tanks": github_icon_base_url + "original/btn-unit-terran-siegetankmercenary-tank.png", - "Infested Banshees": github_icon_base_url + "original/btn-unit-terran-bansheemercenary.png", - - "Primal Form (Kerrigan)": github_icon_base_url + "blizzard/btn-unit-zerg-kerriganinfested.png", - "Kinetic Blast (Kerrigan Tier 1)": github_icon_base_url + "blizzard/btn-ability-kerrigan-kineticblast.png", - "Heroic Fortitude (Kerrigan Tier 1)": github_icon_base_url + "blizzard/btn-ability-kerrigan-heroicfortitude.png", - "Leaping Strike (Kerrigan Tier 1)": github_icon_base_url + "blizzard/btn-ability-kerrigan-leapingstrike.png", - "Crushing Grip (Kerrigan Tier 2)": github_icon_base_url + "blizzard/btn-ability-swarm-kerrigan-crushinggrip.png", - "Chain Reaction (Kerrigan Tier 2)": github_icon_base_url + "blizzard/btn-ability-swarm-kerrigan-chainreaction.png", - "Psionic Shift (Kerrigan Tier 2)": github_icon_base_url + "blizzard/btn-ability-kerrigan-psychicshift.png", - "Wild Mutation (Kerrigan Tier 4)": github_icon_base_url + "blizzard/btn-ability-kerrigan-wildmutation.png", - "Spawn Banelings (Kerrigan Tier 4)": github_icon_base_url + "blizzard/abilityicon_spawnbanelings_square.png", - "Mend (Kerrigan Tier 4)": github_icon_base_url + "blizzard/btn-ability-zerg-transfusion-color.png", - "Infest Broodlings (Kerrigan Tier 6)": github_icon_base_url + "blizzard/abilityicon_spawnbroodlings_square.png", - "Fury (Kerrigan Tier 6)": github_icon_base_url + "blizzard/btn-ability-kerrigan-fury.png", - "Ability Efficiency (Kerrigan Tier 6)": github_icon_base_url + "blizzard/btn-ability-kerrigan-abilityefficiency.png", - "Apocalypse (Kerrigan Tier 7)": github_icon_base_url + "blizzard/btn-ability-kerrigan-apocalypse.png", - "Spawn Leviathan (Kerrigan Tier 7)": github_icon_base_url + "blizzard/btn-unit-zerg-leviathan.png", - "Drop-Pods (Kerrigan Tier 7)": github_icon_base_url + "blizzard/btn-ability-kerrigan-droppods.png", - - "Protoss Ground Weapon Level 1": github_icon_base_url + "blizzard/btn-upgrade-protoss-groundweaponslevel1.png", - "Protoss Ground Weapon Level 2": github_icon_base_url + "blizzard/btn-upgrade-protoss-groundweaponslevel2.png", - "Protoss Ground Weapon Level 3": github_icon_base_url + "blizzard/btn-upgrade-protoss-groundweaponslevel3.png", - "Protoss Ground Armor Level 1": github_icon_base_url + "blizzard/btn-upgrade-protoss-groundarmorlevel1.png", - "Protoss Ground Armor Level 2": github_icon_base_url + "blizzard/btn-upgrade-protoss-groundarmorlevel2.png", - "Protoss Ground Armor Level 3": github_icon_base_url + "blizzard/btn-upgrade-protoss-groundarmorlevel3.png", - "Protoss Shields Level 1": github_icon_base_url + "blizzard/btn-upgrade-protoss-shieldslevel1.png", - "Protoss Shields Level 2": github_icon_base_url + "blizzard/btn-upgrade-protoss-shieldslevel2.png", - "Protoss Shields Level 3": github_icon_base_url + "blizzard/btn-upgrade-protoss-shieldslevel3.png", - "Protoss Air Weapon Level 1": github_icon_base_url + "blizzard/btn-upgrade-protoss-airweaponslevel1.png", - "Protoss Air Weapon Level 2": github_icon_base_url + "blizzard/btn-upgrade-protoss-airweaponslevel2.png", - "Protoss Air Weapon Level 3": github_icon_base_url + "blizzard/btn-upgrade-protoss-airweaponslevel3.png", - "Protoss Air Armor Level 1": github_icon_base_url + "blizzard/btn-upgrade-protoss-airarmorlevel1.png", - "Protoss Air Armor Level 2": github_icon_base_url + "blizzard/btn-upgrade-protoss-airarmorlevel2.png", - "Protoss Air Armor Level 3": github_icon_base_url + "blizzard/btn-upgrade-protoss-airarmorlevel3.png", - - "Quatro": github_icon_base_url + "blizzard/btn-progression-protoss-fenix-6-forgeresearch.png", - - "Photon Cannon": github_icon_base_url + "blizzard/btn-building-protoss-photoncannon.png", - "Khaydarin Monolith": github_icon_base_url + "blizzard/btn-unit-protoss-khaydarinmonolith.png", - "Shield Battery": github_icon_base_url + "blizzard/btn-building-protoss-shieldbattery.png", - - "Enhanced Targeting": github_icon_base_url + "blizzard/btn-upgrade-karax-turretrange.png", - "Optimized Ordnance": github_icon_base_url + "blizzard/btn-upgrade-karax-turretattackspeed.png", - "Khalai Ingenuity": github_icon_base_url + "blizzard/btn-upgrade-karax-pylonwarpininstantly.png", - "Orbital Assimilators": github_icon_base_url + "blizzard/btn-ability-spearofadun-orbitalassimilator.png", - "Amplified Assimilators": github_icon_base_url + "original/btn-research-terran-microfiltering.png", - "Warp Harmonization": github_icon_base_url + "blizzard/btn-ability-spearofadun-warpharmonization.png", - "Superior Warp Gates": github_icon_base_url + "blizzard/talent-artanis-level03-warpgatecharges.png", - "Nexus Overcharge": github_icon_base_url + "blizzard/btn-ability-spearofadun-nexusovercharge.png", - - "Zealot": github_icon_base_url + "blizzard/btn-unit-protoss-zealot-aiur.png", - "Centurion": github_icon_base_url + "blizzard/btn-unit-protoss-zealot-nerazim.png", - "Sentinel": github_icon_base_url + "blizzard/btn-unit-protoss-zealot-purifier.png", - "Supplicant": github_icon_base_url + "blizzard/btn-unit-protoss-alarak-taldarim-supplicant.png", - "Sentry": github_icon_base_url + "blizzard/btn-unit-protoss-sentry.png", - "Energizer": github_icon_base_url + "blizzard/btn-unit-protoss-sentry-purifier.png", - "Havoc": github_icon_base_url + "blizzard/btn-unit-protoss-sentry-taldarim.png", - "Stalker": "https://static.wikia.nocookie.net/starcraft/images/0/0d/Icon_Protoss_Stalker.jpg", - "Instigator": github_icon_base_url + "blizzard/btn-unit-protoss-stalker-purifier.png", - "Slayer": github_icon_base_url + "blizzard/btn-unit-protoss-alarak-taldarim-stalker.png", - "Dragoon": github_icon_base_url + "blizzard/btn-unit-protoss-dragoon-void.png", - "Adept": github_icon_base_url + "blizzard/btn-unit-protoss-adept-purifier.png", - "High Templar": "https://static.wikia.nocookie.net/starcraft/images/a/a0/Icon_Protoss_High_Templar.jpg", - "Signifier": github_icon_base_url + "original/btn-unit-protoss-hightemplar-nerazim.png", - "Ascendant": github_icon_base_url + "blizzard/btn-unit-protoss-hightemplar-taldarim.png", - "Dark Archon": github_icon_base_url + "blizzard/talent-vorazun-level05-unlockdarkarchon.png", - "Dark Templar": "https://static.wikia.nocookie.net/starcraft/images/9/90/Icon_Protoss_Dark_Templar.jpg", - "Avenger": github_icon_base_url + "blizzard/btn-unit-protoss-darktemplar-aiur.png", - "Blood Hunter": github_icon_base_url + "blizzard/btn-unit-protoss-darktemplar-taldarim.png", - - "Leg Enhancements (Zealot/Sentinel/Centurion)": github_icon_base_url + "blizzard/btn-ability-protoss-charge-color.png", - "Shield Capacity (Zealot/Sentinel/Centurion)": github_icon_base_url + "blizzard/btn-upgrade-protoss-shieldslevel1.png", - "Blood Shield (Supplicant)": github_icon_base_url + "blizzard/btn-upgrade-protoss-alarak-supplicantarmor.png", - "Soul Augmentation (Supplicant)": github_icon_base_url + "blizzard/btn-upgrade-protoss-alarak-supplicantextrashields.png", - "Shield Regeneration (Supplicant)": github_icon_base_url + "blizzard/btn-ability-protoss-voidarmor.png", - "Force Field (Sentry)": github_icon_base_url + "blizzard/btn-ability-protoss-forcefield-color.png", - "Hallucination (Sentry)": github_icon_base_url + "blizzard/btn-ability-protoss-hallucination-color.png", - "Reclamation (Energizer)": github_icon_base_url + "blizzard/btn-ability-protoss-reclamation.png", - "Forged Chassis (Energizer)": github_icon_base_url + "blizzard/btn-upgrade-protoss-groundarmorlevel0.png", - "Detect Weakness (Havoc)": github_icon_base_url + "blizzard/btn-upgrade-protoss-alarak-havoctargetlockbuffed.png", - "Bloodshard Resonance (Havoc)": github_icon_base_url + "blizzard/btn-upgrade-protoss-alarak-rangeincrease.png", - "Cloaking Module (Sentry/Energizer/Havoc)": github_icon_base_url + "blizzard/btn-upgrade-protoss-alarak-permanentcloak.png", - "Rapid Recharging (Sentry/Energizer/Havoc/Shield Battery)": github_icon_base_url + "blizzard/btn-upgrade-karax-energyregen200.png", - "Disintegrating Particles (Stalker/Instigator/Slayer)": github_icon_base_url + "blizzard/btn-ability-protoss-phasedisruptor.png", - "Particle Reflection (Stalker/Instigator/Slayer)": github_icon_base_url + "blizzard/btn-upgrade-protoss-fenix-adeptchampionbounceattack.png", - "High Impact Phase Disruptor (Dragoon)": github_icon_base_url + "blizzard/btn-ability-protoss-phasedisruptor.png", - "Trillic Compression System (Dragoon)": github_icon_base_url + "blizzard/btn-ability-protoss-dragoonchassis.png", - "Singularity Charge (Dragoon)": github_icon_base_url + "blizzard/btn-upgrade-artanis-singularitycharge.png", - "Enhanced Strider Servos (Dragoon)": github_icon_base_url + "blizzard/btn-upgrade-terran-transformationservos.png", - "Shockwave (Adept)": github_icon_base_url + "blizzard/btn-upgrade-protoss-fenix-adept-recochetglaiveupgraded.png", - "Resonating Glaives (Adept)": github_icon_base_url + "blizzard/btn-upgrade-protoss-resonatingglaives.png", - "Phase Bulwark (Adept)": github_icon_base_url + "blizzard/btn-upgrade-protoss-adeptshieldupgrade.png", - "Unshackled Psionic Storm (High Templar/Signifier)": github_icon_base_url + "blizzard/btn-ability-protoss-psistorm.png", - "Hallucination (High Templar/Signifier)": github_icon_base_url + "blizzard/btn-ability-protoss-hallucination-color.png", - "Khaydarin Amulet (High Templar/Signifier)": github_icon_base_url + "blizzard/btn-upgrade-protoss-khaydarinamulet.png", - "High Archon (Archon)": github_icon_base_url + "blizzard/btn-upgrade-artanis-healingpsionicstorm.png", - "Power Overwhelming (Ascendant)": github_icon_base_url + "blizzard/btn-upgrade-protoss-alarak-ascendantspermanentlybetter.png", - "Chaotic Attunement (Ascendant)": github_icon_base_url + "blizzard/btn-upgrade-protoss-alarak-ascendant'spsiorbtravelsfurther.png", - "Blood Amulet (Ascendant)": github_icon_base_url + "blizzard/btn-upgrade-protoss-wrathwalker-chargetimeimproved.png", - "Feedback (Dark Archon)": github_icon_base_url + "blizzard/btn-ability-protoss-feedback-color.png", - "Maelstrom (Dark Archon)": github_icon_base_url + "blizzard/btn-ability-protoss-voidstasis.png", - "Argus Talisman (Dark Archon)": github_icon_base_url + "original/btn-upgrade-protoss-argustalisman@scbw.png", - "Dark Archon Meld (Dark Templar)": github_icon_base_url + "blizzard/talent-vorazun-level05-unlockdarkarchon.png", - "Shroud of Adun (Dark Templar/Avenger/Blood Hunter)": github_icon_base_url + "blizzard/talent-vorazun-level01-shadowstalk.png", - "Shadow Guard Training (Dark Templar/Avenger/Blood Hunter)": github_icon_base_url + "blizzard/btn-ability-terran-heal-color.png", - "Blink (Dark Templar/Avenger/Blood Hunter)": github_icon_base_url + "blizzard/btn-ability-protoss-shadowdash.png", - "Resource Efficiency (Dark Templar/Avenger/Blood Hunter)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - - "Warp Prism": github_icon_base_url + "blizzard/btn-unit-protoss-warpprism.png", - "Immortal": "https://static.wikia.nocookie.net/starcraft/images/c/c1/Icon_Protoss_Immortal.jpg", - "Annihilator": github_icon_base_url + "blizzard/btn-unit-protoss-immortal-nerazim.png", - "Vanguard": github_icon_base_url + "blizzard/btn-unit-protoss-immortal-taldarim.png", - "Colossus": github_icon_base_url + "blizzard/btn-unit-protoss-colossus-purifier.png", - "Wrathwalker": github_icon_base_url + "blizzard/btn-unit-protoss-colossus-taldarim.png", - "Observer": github_icon_base_url + "blizzard/btn-unit-protoss-observer.png", - "Reaver": github_icon_base_url + "blizzard/btn-unit-protoss-reaver.png", - "Disruptor": github_icon_base_url + "blizzard/btn-unit-protoss-disruptor.png", - - "Gravitic Drive (Warp Prism)": github_icon_base_url + "blizzard/btn-upgrade-protoss-graviticdrive.png", - "Phase Blaster (Warp Prism)": github_icon_base_url + "blizzard/btn-upgrade-protoss-airweaponslevel0.png", - "War Configuration (Warp Prism)": github_icon_base_url + "blizzard/btn-upgrade-protoss-alarak-graviticdrive.png", - "Singularity Charge (Immortal/Annihilator)": github_icon_base_url + "blizzard/btn-upgrade-artanis-singularitycharge.png", - "Advanced Targeting Mechanics (Immortal/Annihilator)": github_icon_base_url + "blizzard/btn-ability-terran-detectionconedebuff.png", - "Agony Launchers (Vanguard)": github_icon_base_url + "blizzard/btn-upgrade-protoss-vanguard-aoeradiusincreased.png", - "Matter Dispersion (Vanguard)": github_icon_base_url + "blizzard/btn-ability-terran-detectionconedebuff.png", - "Pacification Protocol (Colossus)": github_icon_base_url + "blizzard/btn-ability-protoss-chargedblast.png", - "Rapid Power Cycling (Wrathwalker)": github_icon_base_url + "blizzard/btn-upgrade-protoss-wrathwalker-chargetimeimproved.png", - "Eye of Wrath (Wrathwalker)": github_icon_base_url + "blizzard/btn-upgrade-protoss-extendedthermallance.png", - "Gravitic Boosters (Observer)": github_icon_base_url + "blizzard/btn-upgrade-protoss-graviticbooster.png", - "Sensor Array (Observer)": github_icon_base_url + "blizzard/btn-ability-zeratul-observer-sensorarray.png", - "Scarab Damage (Reaver)": github_icon_base_url + "blizzard/btn-ability-protoss-scarabshot.png", - "Solarite Payload (Reaver)": github_icon_base_url + "blizzard/btn-upgrade-artanis-scarabsplashradius.png", - "Reaver Capacity (Reaver)": github_icon_base_url + "original/btn-upgrade-protoss-increasedscarabcapacity@scbw.png", - "Resource Efficiency (Reaver)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - - "Phoenix": "https://static.wikia.nocookie.net/starcraft/images/b/b1/Icon_Protoss_Phoenix.jpg", - "Mirage": github_icon_base_url + "blizzard/btn-unit-protoss-phoenix-purifier.png", - "Corsair": github_icon_base_url + "blizzard/btn-unit-protoss-corsair.png", - "Destroyer": github_icon_base_url + "blizzard/btn-unit-protoss-voidray-taldarim.png", - "Void Ray": github_icon_base_url + "blizzard/btn-unit-protoss-voidray-nerazim.png", - "Carrier": "https://static.wikia.nocookie.net/starcraft/images/2/2c/Icon_Protoss_Carrier.jpg", - "Scout": github_icon_base_url + "original/btn-unit-protoss-scout.png", - "Tempest": github_icon_base_url + "blizzard/btn-unit-protoss-tempest-purifier.png", - "Mothership": github_icon_base_url + "blizzard/btn-unit-protoss-mothership-taldarim.png", - "Arbiter": github_icon_base_url + "blizzard/btn-unit-protoss-arbiter.png", - "Oracle": github_icon_base_url + "blizzard/btn-unit-protoss-oracle.png", - - "Ionic Wavelength Flux (Phoenix/Mirage)": github_icon_base_url + "blizzard/btn-upgrade-protoss-airweaponslevel0.png", - "Anion Pulse-Crystals (Phoenix/Mirage)": github_icon_base_url + "blizzard/btn-upgrade-protoss-phoenixrange.png", - "Stealth Drive (Corsair)": github_icon_base_url + "blizzard/btn-upgrade-vorazun-corsairpermanentlycloaked.png", - "Argus Jewel (Corsair)": github_icon_base_url + "blizzard/btn-ability-protoss-stasistrap.png", - "Sustaining Disruption (Corsair)": github_icon_base_url + "blizzard/btn-ability-protoss-disruptionweb.png", - "Neutron Shields (Corsair)": github_icon_base_url + "blizzard/btn-upgrade-protoss-shieldslevel1.png", - "Reforged Bloodshard Core (Destroyer)": github_icon_base_url + "blizzard/btn-amonshardsarmor.png", - "Flux Vanes (Void Ray/Destroyer)": github_icon_base_url + "blizzard/btn-upgrade-protoss-fluxvanes.png", - "Graviton Catapult (Carrier)": github_icon_base_url + "blizzard/btn-upgrade-protoss-gravitoncatapult.png", - "Hull of Past Glories (Carrier)": github_icon_base_url + "blizzard/btn-progression-protoss-fenix-14-colossusandcarrierchampionsresearch.png", - "Combat Sensor Array (Scout)": github_icon_base_url + "blizzard/btn-upgrade-protoss-fenix-scoutchampionrange.png", - "Apial Sensors (Scout)": github_icon_base_url + "blizzard/btn-upgrade-tychus-detection.png", - "Gravitic Thrusters (Scout)": github_icon_base_url + "blizzard/btn-upgrade-protoss-graviticbooster.png", - "Advanced Photon Blasters (Scout)": github_icon_base_url + "blizzard/btn-upgrade-protoss-airweaponslevel3.png", - "Tectonic Destabilizers (Tempest)": github_icon_base_url + "blizzard/btn-ability-protoss-disruptionblast.png", - "Quantic Reactor (Tempest)": github_icon_base_url + "blizzard/btn-upgrade-protoss-researchgravitysling.png", - "Gravity Sling (Tempest)": github_icon_base_url + "blizzard/btn-upgrade-protoss-tectonicdisruptors.png", - "Chronostatic Reinforcement (Arbiter)": github_icon_base_url + "blizzard/btn-upgrade-protoss-airarmorlevel2.png", - "Khaydarin Core (Arbiter)": github_icon_base_url + "blizzard/btn-upgrade-protoss-adeptshieldupgrade.png", - "Spacetime Anchor (Arbiter)": github_icon_base_url + "blizzard/btn-ability-protoss-stasisfield.png", - "Resource Efficiency (Arbiter)": github_icon_base_url + "blizzard/btn-ability-hornerhan-salvagebonus.png", - "Enhanced Cloak Field (Arbiter)": github_icon_base_url + "blizzard/btn-ability-stetmann-stetzonegenerator-speed.png", - "Stealth Drive (Oracle)": github_icon_base_url + "blizzard/btn-upgrade-vorazun-oraclepermanentlycloaked.png", - "Stasis Calibration (Oracle)": github_icon_base_url + "blizzard/btn-ability-protoss-oracle-stasiscalibration.png", - "Temporal Acceleration Beam (Oracle)": github_icon_base_url + "blizzard/btn-ability-protoss-oraclepulsarcannonon.png", - - "Matrix Overload": github_icon_base_url + "blizzard/btn-ability-spearofadun-matrixoverload.png", - "Guardian Shell": github_icon_base_url + "blizzard/btn-ability-spearofadun-guardianshell.png", - - "Chrono Surge (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-chronosurge.png", - "Proxy Pylon (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-deploypylon.png", - "Warp In Reinforcements (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-warpinreinforcements.png", - "Pylon Overcharge (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-protoss-purify.png", - "Orbital Strike (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-orbitalstrike.png", - "Temporal Field (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-temporalfield.png", - "Solar Lance (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-solarlance.png", - "Mass Recall (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-massrecall.png", - "Shield Overcharge (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-shieldovercharge.png", - "Deploy Fenix (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-unit-protoss-fenix.png", - "Purifier Beam (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-purifierbeam.png", - "Time Stop (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-timestop.png", - "Solar Bombardment (Spear of Adun Calldown)": github_icon_base_url + "blizzard/btn-ability-spearofadun-solarbombardment.png", - - "Reconstruction Beam (Spear of Adun Auto-Cast)": github_icon_base_url + "blizzard/btn-ability-spearofadun-reconstructionbeam.png", - "Overwatch (Spear of Adun Auto-Cast)": github_icon_base_url + "blizzard/btn-ability-zeratul-chargedcrystal-psionicwinds.png", - - "Nothing": "", - } - sc2wol_location_ids = { - "Liberation Day": range(SC2WOL_LOC_ID_OFFSET + 100, SC2WOL_LOC_ID_OFFSET + 200), - "The Outlaws": range(SC2WOL_LOC_ID_OFFSET + 200, SC2WOL_LOC_ID_OFFSET + 300), - "Zero Hour": range(SC2WOL_LOC_ID_OFFSET + 300, SC2WOL_LOC_ID_OFFSET + 400), - "Evacuation": range(SC2WOL_LOC_ID_OFFSET + 400, SC2WOL_LOC_ID_OFFSET + 500), - "Outbreak": range(SC2WOL_LOC_ID_OFFSET + 500, SC2WOL_LOC_ID_OFFSET + 600), - "Safe Haven": range(SC2WOL_LOC_ID_OFFSET + 600, SC2WOL_LOC_ID_OFFSET + 700), - "Haven's Fall": range(SC2WOL_LOC_ID_OFFSET + 700, SC2WOL_LOC_ID_OFFSET + 800), - "Smash and Grab": range(SC2WOL_LOC_ID_OFFSET + 800, SC2WOL_LOC_ID_OFFSET + 900), - "The Dig": range(SC2WOL_LOC_ID_OFFSET + 900, SC2WOL_LOC_ID_OFFSET + 1000), - "The Moebius Factor": range(SC2WOL_LOC_ID_OFFSET + 1000, SC2WOL_LOC_ID_OFFSET + 1100), - "Supernova": range(SC2WOL_LOC_ID_OFFSET + 1100, SC2WOL_LOC_ID_OFFSET + 1200), - "Maw of the Void": range(SC2WOL_LOC_ID_OFFSET + 1200, SC2WOL_LOC_ID_OFFSET + 1300), - "Devil's Playground": range(SC2WOL_LOC_ID_OFFSET + 1300, SC2WOL_LOC_ID_OFFSET + 1400), - "Welcome to the Jungle": range(SC2WOL_LOC_ID_OFFSET + 1400, SC2WOL_LOC_ID_OFFSET + 1500), - "Breakout": range(SC2WOL_LOC_ID_OFFSET + 1500, SC2WOL_LOC_ID_OFFSET + 1600), - "Ghost of a Chance": range(SC2WOL_LOC_ID_OFFSET + 1600, SC2WOL_LOC_ID_OFFSET + 1700), - "The Great Train Robbery": range(SC2WOL_LOC_ID_OFFSET + 1700, SC2WOL_LOC_ID_OFFSET + 1800), - "Cutthroat": range(SC2WOL_LOC_ID_OFFSET + 1800, SC2WOL_LOC_ID_OFFSET + 1900), - "Engine of Destruction": range(SC2WOL_LOC_ID_OFFSET + 1900, SC2WOL_LOC_ID_OFFSET + 2000), - "Media Blitz": range(SC2WOL_LOC_ID_OFFSET + 2000, SC2WOL_LOC_ID_OFFSET + 2100), - "Piercing the Shroud": range(SC2WOL_LOC_ID_OFFSET + 2100, SC2WOL_LOC_ID_OFFSET + 2200), - "Whispers of Doom": range(SC2WOL_LOC_ID_OFFSET + 2200, SC2WOL_LOC_ID_OFFSET + 2300), - "A Sinister Turn": range(SC2WOL_LOC_ID_OFFSET + 2300, SC2WOL_LOC_ID_OFFSET + 2400), - "Echoes of the Future": range(SC2WOL_LOC_ID_OFFSET + 2400, SC2WOL_LOC_ID_OFFSET + 2500), - "In Utter Darkness": range(SC2WOL_LOC_ID_OFFSET + 2500, SC2WOL_LOC_ID_OFFSET + 2600), - "Gates of Hell": range(SC2WOL_LOC_ID_OFFSET + 2600, SC2WOL_LOC_ID_OFFSET + 2700), - "Belly of the Beast": range(SC2WOL_LOC_ID_OFFSET + 2700, SC2WOL_LOC_ID_OFFSET + 2800), - "Shatter the Sky": range(SC2WOL_LOC_ID_OFFSET + 2800, SC2WOL_LOC_ID_OFFSET + 2900), - "All-In": range(SC2WOL_LOC_ID_OFFSET + 2900, SC2WOL_LOC_ID_OFFSET + 3000), - - "Lab Rat": range(SC2HOTS_LOC_ID_OFFSET + 100, SC2HOTS_LOC_ID_OFFSET + 200), - "Back in the Saddle": range(SC2HOTS_LOC_ID_OFFSET + 200, SC2HOTS_LOC_ID_OFFSET + 300), - "Rendezvous": range(SC2HOTS_LOC_ID_OFFSET + 300, SC2HOTS_LOC_ID_OFFSET + 400), - "Harvest of Screams": range(SC2HOTS_LOC_ID_OFFSET + 400, SC2HOTS_LOC_ID_OFFSET + 500), - "Shoot the Messenger": range(SC2HOTS_LOC_ID_OFFSET + 500, SC2HOTS_LOC_ID_OFFSET + 600), - "Enemy Within": range(SC2HOTS_LOC_ID_OFFSET + 600, SC2HOTS_LOC_ID_OFFSET + 700), - "Domination": range(SC2HOTS_LOC_ID_OFFSET + 700, SC2HOTS_LOC_ID_OFFSET + 800), - "Fire in the Sky": range(SC2HOTS_LOC_ID_OFFSET + 800, SC2HOTS_LOC_ID_OFFSET + 900), - "Old Soldiers": range(SC2HOTS_LOC_ID_OFFSET + 900, SC2HOTS_LOC_ID_OFFSET + 1000), - "Waking the Ancient": range(SC2HOTS_LOC_ID_OFFSET + 1000, SC2HOTS_LOC_ID_OFFSET + 1100), - "The Crucible": range(SC2HOTS_LOC_ID_OFFSET + 1100, SC2HOTS_LOC_ID_OFFSET + 1200), - "Supreme": range(SC2HOTS_LOC_ID_OFFSET + 1200, SC2HOTS_LOC_ID_OFFSET + 1300), - "Infested": range(SC2HOTS_LOC_ID_OFFSET + 1300, SC2HOTS_LOC_ID_OFFSET + 1400), - "Hand of Darkness": range(SC2HOTS_LOC_ID_OFFSET + 1400, SC2HOTS_LOC_ID_OFFSET + 1500), - "Phantoms of the Void": range(SC2HOTS_LOC_ID_OFFSET + 1500, SC2HOTS_LOC_ID_OFFSET + 1600), - "With Friends Like These": range(SC2HOTS_LOC_ID_OFFSET + 1600, SC2HOTS_LOC_ID_OFFSET + 1700), - "Conviction": range(SC2HOTS_LOC_ID_OFFSET + 1700, SC2HOTS_LOC_ID_OFFSET + 1800), - "Planetfall": range(SC2HOTS_LOC_ID_OFFSET + 1800, SC2HOTS_LOC_ID_OFFSET + 1900), - "Death From Above": range(SC2HOTS_LOC_ID_OFFSET + 1900, SC2HOTS_LOC_ID_OFFSET + 2000), - "The Reckoning": range(SC2HOTS_LOC_ID_OFFSET + 2000, SC2HOTS_LOC_ID_OFFSET + 2100), - - "Dark Whispers": range(SC2LOTV_LOC_ID_OFFSET + 100, SC2LOTV_LOC_ID_OFFSET + 200), - "Ghosts in the Fog": range(SC2LOTV_LOC_ID_OFFSET + 200, SC2LOTV_LOC_ID_OFFSET + 300), - "Evil Awoken": range(SC2LOTV_LOC_ID_OFFSET + 300, SC2LOTV_LOC_ID_OFFSET + 400), - - "For Aiur!": range(SC2LOTV_LOC_ID_OFFSET + 400, SC2LOTV_LOC_ID_OFFSET + 500), - "The Growing Shadow": range(SC2LOTV_LOC_ID_OFFSET + 500, SC2LOTV_LOC_ID_OFFSET + 600), - "The Spear of Adun": range(SC2LOTV_LOC_ID_OFFSET + 600, SC2LOTV_LOC_ID_OFFSET + 700), - "Sky Shield": range(SC2LOTV_LOC_ID_OFFSET + 700, SC2LOTV_LOC_ID_OFFSET + 800), - "Brothers in Arms": range(SC2LOTV_LOC_ID_OFFSET + 800, SC2LOTV_LOC_ID_OFFSET + 900), - "Amon's Reach": range(SC2LOTV_LOC_ID_OFFSET + 900, SC2LOTV_LOC_ID_OFFSET + 1000), - "Last Stand": range(SC2LOTV_LOC_ID_OFFSET + 1000, SC2LOTV_LOC_ID_OFFSET + 1100), - "Forbidden Weapon": range(SC2LOTV_LOC_ID_OFFSET + 1100, SC2LOTV_LOC_ID_OFFSET + 1200), - "Temple of Unification": range(SC2LOTV_LOC_ID_OFFSET + 1200, SC2LOTV_LOC_ID_OFFSET + 1300), - "The Infinite Cycle": range(SC2LOTV_LOC_ID_OFFSET + 1300, SC2LOTV_LOC_ID_OFFSET + 1400), - "Harbinger of Oblivion": range(SC2LOTV_LOC_ID_OFFSET + 1400, SC2LOTV_LOC_ID_OFFSET + 1500), - "Unsealing the Past": range(SC2LOTV_LOC_ID_OFFSET + 1500, SC2LOTV_LOC_ID_OFFSET + 1600), - "Purification": range(SC2LOTV_LOC_ID_OFFSET + 1600, SC2LOTV_LOC_ID_OFFSET + 1700), - "Steps of the Rite": range(SC2LOTV_LOC_ID_OFFSET + 1700, SC2LOTV_LOC_ID_OFFSET + 1800), - "Rak'Shir": range(SC2LOTV_LOC_ID_OFFSET + 1800, SC2LOTV_LOC_ID_OFFSET + 1900), - "Templar's Charge": range(SC2LOTV_LOC_ID_OFFSET + 1900, SC2LOTV_LOC_ID_OFFSET + 2000), - "Templar's Return": range(SC2LOTV_LOC_ID_OFFSET + 2000, SC2LOTV_LOC_ID_OFFSET + 2100), - "The Host": range(SC2LOTV_LOC_ID_OFFSET + 2100, SC2LOTV_LOC_ID_OFFSET + 2200), - "Salvation": range(SC2LOTV_LOC_ID_OFFSET + 2200, SC2LOTV_LOC_ID_OFFSET + 2300), - - "Into the Void": range(SC2LOTV_LOC_ID_OFFSET + 2300, SC2LOTV_LOC_ID_OFFSET + 2400), - "The Essence of Eternity": range(SC2LOTV_LOC_ID_OFFSET + 2400, SC2LOTV_LOC_ID_OFFSET + 2500), - "Amon's Fall": range(SC2LOTV_LOC_ID_OFFSET + 2500, SC2LOTV_LOC_ID_OFFSET + 2600), - - "The Escape": range(SC2NCO_LOC_ID_OFFSET + 100, SC2NCO_LOC_ID_OFFSET + 200), - "Sudden Strike": range(SC2NCO_LOC_ID_OFFSET + 200, SC2NCO_LOC_ID_OFFSET + 300), - "Enemy Intelligence": range(SC2NCO_LOC_ID_OFFSET + 300, SC2NCO_LOC_ID_OFFSET + 400), - "Trouble In Paradise": range(SC2NCO_LOC_ID_OFFSET + 400, SC2NCO_LOC_ID_OFFSET + 500), - "Night Terrors": range(SC2NCO_LOC_ID_OFFSET + 500, SC2NCO_LOC_ID_OFFSET + 600), - "Flashpoint": range(SC2NCO_LOC_ID_OFFSET + 600, SC2NCO_LOC_ID_OFFSET + 700), - "In the Enemy's Shadow": range(SC2NCO_LOC_ID_OFFSET + 700, SC2NCO_LOC_ID_OFFSET + 800), - "Dark Skies": range(SC2NCO_LOC_ID_OFFSET + 800, SC2NCO_LOC_ID_OFFSET + 900), - "End Game": range(SC2NCO_LOC_ID_OFFSET + 900, SC2NCO_LOC_ID_OFFSET + 1000), - } + inventory: collections.Counter[int] = tracker_data.get_player_inventory_counts(team, player) + item_id_to_name = tracker_data.item_id_to_name["Starcraft 2"] + location_id_to_name = tracker_data.location_id_to_name["Starcraft 2"] + # Filler item counters display_data = {} + display_data["minerals_count"] = slot_data.get("minerals_per_item", 15) * inventory.get(STARTING_MINERALS_ITEM_ID, 0) + display_data["vespene_count"] = slot_data.get("vespene_per_item", 15) * inventory.get(STARTING_VESPENE_ITEM_ID, 0) + display_data["supply_count"] = slot_data.get("starting_supply_per_item", 2) * inventory.get(STARTING_SUPPLY_ITEM_ID, 0) + display_data["max_supply_count"] = slot_data.get("maximum_supply_per_item", 1) * inventory.get(MAX_SUPPLY_ITEM_ID, 0) + display_data["reduced_supply_count"] = slot_data.get("maximum_supply_reduction_per_item", 1) * inventory.get(REDUCED_MAX_SUPPLY_ITEM_ID, 0) + display_data["construction_speed_count"] = inventory.get(BUILDING_CONSTRUCTION_SPEED_ITEM_ID, 0) + display_data["shield_regen_count"] = inventory.get(SHIELD_REGENERATION_ITEM_ID, 0) + display_data["upgrade_speed_count"] = inventory.get(UPGRADE_RESEARCH_SPEED_ITEM_ID, 0) + display_data["research_cost_count"] = inventory.get(UPGRADE_RESEARCH_COST_ITEM_ID, 0) + + # Locations + have_nco_locations = False + locations = tracker_data.get_player_locations(team, player) + checked_locations = tracker_data.get_player_checked_locations(team, player) + missions: dict[str, list[tuple[str, bool]]] = {} + for location_id in locations: + location_name = location_id_to_name.get(location_id, "") + if ":" not in location_name: + continue + mission_name = location_name.split(":", 1)[0] + missions.setdefault(mission_name, []).append((location_name, location_id in checked_locations)) + if location_id >= NCO_LOCATION_ID_LOW and location_id < NCO_LOCATION_ID_HIGH: + have_nco_locations = True + missions = {mission: missions[mission] for mission in sorted(missions)} - # Grouped Items - grouped_item_ids = { - "Progressive Terran Weapon Upgrade": 107 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Armor Upgrade": 108 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Infantry Upgrade": 109 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Vehicle Upgrade": 110 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Ship Upgrade": 111 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Weapon/Armor Upgrade": 112 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Zerg Weapon Upgrade": 105 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Armor Upgrade": 106 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Ground Upgrade": 107 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Flyer Upgrade": 108 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Weapon/Armor Upgrade": 109 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Protoss Weapon Upgrade": 105 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Armor Upgrade": 106 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Ground Upgrade": 107 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Air Upgrade": 108 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Weapon/Armor Upgrade": 109 + SC2LOTV_ITEM_ID_OFFSET, - } - grouped_item_replacements = { - "Progressive Terran Weapon Upgrade": ["Progressive Terran Infantry Weapon", - "Progressive Terran Vehicle Weapon", - "Progressive Terran Ship Weapon"], - "Progressive Terran Armor Upgrade": ["Progressive Terran Infantry Armor", - "Progressive Terran Vehicle Armor", - "Progressive Terran Ship Armor"], - "Progressive Terran Infantry Upgrade": ["Progressive Terran Infantry Weapon", - "Progressive Terran Infantry Armor"], - "Progressive Terran Vehicle Upgrade": ["Progressive Terran Vehicle Weapon", - "Progressive Terran Vehicle Armor"], - "Progressive Terran Ship Upgrade": ["Progressive Terran Ship Weapon", "Progressive Terran Ship Armor"], - "Progressive Zerg Weapon Upgrade": ["Progressive Zerg Melee Attack", "Progressive Zerg Missile Attack", - "Progressive Zerg Flyer Attack"], - "Progressive Zerg Armor Upgrade": ["Progressive Zerg Ground Carapace", - "Progressive Zerg Flyer Carapace"], - "Progressive Zerg Ground Upgrade": ["Progressive Zerg Melee Attack", "Progressive Zerg Missile Attack", - "Progressive Zerg Ground Carapace"], - "Progressive Zerg Flyer Upgrade": ["Progressive Zerg Flyer Attack", "Progressive Zerg Flyer Carapace"], - "Progressive Protoss Weapon Upgrade": ["Progressive Protoss Ground Weapon", - "Progressive Protoss Air Weapon"], - "Progressive Protoss Armor Upgrade": ["Progressive Protoss Ground Armor", "Progressive Protoss Shields", - "Progressive Protoss Air Armor"], - "Progressive Protoss Ground Upgrade": ["Progressive Protoss Ground Weapon", - "Progressive Protoss Ground Armor", - "Progressive Protoss Shields"], - "Progressive Protoss Air Upgrade": ["Progressive Protoss Air Weapon", "Progressive Protoss Air Armor", - "Progressive Protoss Shields"] - } - grouped_item_replacements["Progressive Terran Weapon/Armor Upgrade"] = \ - grouped_item_replacements["Progressive Terran Weapon Upgrade"] \ - + grouped_item_replacements["Progressive Terran Armor Upgrade"] - grouped_item_replacements["Progressive Zerg Weapon/Armor Upgrade"] = \ - grouped_item_replacements["Progressive Zerg Weapon Upgrade"] \ - + grouped_item_replacements["Progressive Zerg Armor Upgrade"] - grouped_item_replacements["Progressive Protoss Weapon/Armor Upgrade"] = \ - grouped_item_replacements["Progressive Protoss Weapon Upgrade"] \ - + grouped_item_replacements["Progressive Protoss Armor Upgrade"] - replacement_item_ids = { - "Progressive Terran Infantry Weapon": 100 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Infantry Armor": 102 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Vehicle Weapon": 103 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Vehicle Armor": 104 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Ship Weapon": 105 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Ship Armor": 106 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Zerg Melee Attack": 100 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Missile Attack": 101 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Ground Carapace": 102 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Flyer Attack": 103 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Flyer Carapace": 104 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Protoss Ground Weapon": 100 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Ground Armor": 101 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Shields": 102 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Air Weapon": 103 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Air Armor": 104 + SC2LOTV_ITEM_ID_OFFSET, - } - - inventory: collections.Counter = tracker_data.get_player_inventory_counts(team, player) - for grouped_item_name, grouped_item_id in grouped_item_ids.items(): - count: int = inventory[grouped_item_id] - if count > 0: - for replacement_item in grouped_item_replacements[grouped_item_name]: - replacement_id: int = replacement_item_ids[replacement_item] - if replacement_id not in inventory or count > inventory[replacement_id]: - # If two groups provide the same individual item, maximum is used - # (this behavior is used for Protoss Shields) - inventory[replacement_id] = count - - # Determine display for progressive items - progressive_items = { - "Progressive Terran Infantry Weapon": 100 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Infantry Armor": 102 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Vehicle Weapon": 103 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Vehicle Armor": 104 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Ship Weapon": 105 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Terran Ship Armor": 106 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Fire-Suppression System": 206 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Orbital Command": 207 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Stimpack (Marine)": 208 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Stimpack (Firebat)": 226 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Stimpack (Marauder)": 228 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Stimpack (Reaper)": 250 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Stimpack (Hellion)": 259 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Replenishable Magazine (Vulture)": 303 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Tri-Lithium Power Cell (Diamondback)": 306 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Tomahawk Power Cells (Wraith)": 312 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Cross-Spectrum Dampeners (Banshee)": 316 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Missile Pods (Battlecruiser)": 318 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Defensive Matrix (Battlecruiser)": 319 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Immortality Protocol (Thor)": 325 + SC2WOL_ITEM_ID_OFFSET, - "Progressive High Impact Payload (Thor)": 361 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Augmented Thrusters (Planetary Fortress)": 388 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Regenerative Bio-Steel": 617 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Stealth Suit Module (Nova Suit Module)": 904 + SC2WOL_ITEM_ID_OFFSET, - "Progressive Zerg Melee Attack": 100 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Missile Attack": 101 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Ground Carapace": 102 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Flyer Attack": 103 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Zerg Flyer Carapace": 104 + SC2HOTS_ITEM_ID_OFFSET, - "Progressive Protoss Ground Weapon": 100 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Ground Armor": 101 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Shields": 102 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Air Weapon": 103 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Protoss Air Armor": 104 + SC2LOTV_ITEM_ID_OFFSET, - "Progressive Proxy Pylon (Spear of Adun Calldown)": 701 + SC2LOTV_ITEM_ID_OFFSET, - } - # Format: L0, L1, L2, L3 - progressive_names = { - "Progressive Terran Infantry Weapon": ["Terran Infantry Weapons Level 1", - "Terran Infantry Weapons Level 1", - "Terran Infantry Weapons Level 2", - "Terran Infantry Weapons Level 3"], - "Progressive Terran Infantry Armor": ["Terran Infantry Armor Level 1", - "Terran Infantry Armor Level 1", - "Terran Infantry Armor Level 2", - "Terran Infantry Armor Level 3"], - "Progressive Terran Vehicle Weapon": ["Terran Vehicle Weapons Level 1", - "Terran Vehicle Weapons Level 1", - "Terran Vehicle Weapons Level 2", - "Terran Vehicle Weapons Level 3"], - "Progressive Terran Vehicle Armor": ["Terran Vehicle Armor Level 1", - "Terran Vehicle Armor Level 1", - "Terran Vehicle Armor Level 2", - "Terran Vehicle Armor Level 3"], - "Progressive Terran Ship Weapon": ["Terran Ship Weapons Level 1", - "Terran Ship Weapons Level 1", - "Terran Ship Weapons Level 2", - "Terran Ship Weapons Level 3"], - "Progressive Terran Ship Armor": ["Terran Ship Armor Level 1", - "Terran Ship Armor Level 1", - "Terran Ship Armor Level 2", - "Terran Ship Armor Level 3"], - "Progressive Fire-Suppression System": ["Fire-Suppression System Level 1", - "Fire-Suppression System Level 1", - "Fire-Suppression System Level 2"], - "Progressive Orbital Command": ["Orbital Command", "Orbital Command", - "Planetary Command Module"], - "Progressive Stimpack (Marine)": ["Stimpack (Marine)", "Stimpack (Marine)", - "Super Stimpack (Marine)"], - "Progressive Stimpack (Firebat)": ["Stimpack (Firebat)", "Stimpack (Firebat)", - "Super Stimpack (Firebat)"], - "Progressive Stimpack (Marauder)": ["Stimpack (Marauder)", "Stimpack (Marauder)", - "Super Stimpack (Marauder)"], - "Progressive Stimpack (Reaper)": ["Stimpack (Reaper)", "Stimpack (Reaper)", - "Super Stimpack (Reaper)"], - "Progressive Stimpack (Hellion)": ["Stimpack (Hellion)", "Stimpack (Hellion)", - "Super Stimpack (Hellion)"], - "Progressive Replenishable Magazine (Vulture)": ["Replenishable Magazine (Vulture)", - "Replenishable Magazine (Vulture)", - "Replenishable Magazine (Free) (Vulture)"], - "Progressive Tri-Lithium Power Cell (Diamondback)": ["Tri-Lithium Power Cell (Diamondback)", - "Tri-Lithium Power Cell (Diamondback)", - "Tungsten Spikes (Diamondback)"], - "Progressive Tomahawk Power Cells (Wraith)": ["Tomahawk Power Cells (Wraith)", - "Tomahawk Power Cells (Wraith)", - "Unregistered Cloaking Module (Wraith)"], - "Progressive Cross-Spectrum Dampeners (Banshee)": ["Cross-Spectrum Dampeners (Banshee)", - "Cross-Spectrum Dampeners (Banshee)", - "Advanced Cross-Spectrum Dampeners (Banshee)"], - "Progressive Missile Pods (Battlecruiser)": ["Missile Pods (Battlecruiser) Level 1", - "Missile Pods (Battlecruiser) Level 1", - "Missile Pods (Battlecruiser) Level 2"], - "Progressive Defensive Matrix (Battlecruiser)": ["Defensive Matrix (Battlecruiser)", - "Defensive Matrix (Battlecruiser)", - "Advanced Defensive Matrix (Battlecruiser)"], - "Progressive Immortality Protocol (Thor)": ["Immortality Protocol (Thor)", - "Immortality Protocol (Thor)", - "Immortality Protocol (Free) (Thor)"], - "Progressive High Impact Payload (Thor)": ["High Impact Payload (Thor)", - "High Impact Payload (Thor)", "Smart Servos (Thor)"], - "Progressive Augmented Thrusters (Planetary Fortress)": ["Lift Off (Planetary Fortress)", - "Lift Off (Planetary Fortress)", - "Armament Stabilizers (Planetary Fortress)"], - "Progressive Regenerative Bio-Steel": ["Regenerative Bio-Steel Level 1", - "Regenerative Bio-Steel Level 1", - "Regenerative Bio-Steel Level 2", - "Regenerative Bio-Steel Level 3"], - "Progressive Stealth Suit Module (Nova Suit Module)": ["Stealth Suit Module (Nova Suit Module)", - "Cloak (Nova Suit Module)", - "Permanently Cloaked (Nova Suit Module)"], - "Progressive Zerg Melee Attack": ["Zerg Melee Attack Level 1", - "Zerg Melee Attack Level 1", - "Zerg Melee Attack Level 2", - "Zerg Melee Attack Level 3"], - "Progressive Zerg Missile Attack": ["Zerg Missile Attack Level 1", - "Zerg Missile Attack Level 1", - "Zerg Missile Attack Level 2", - "Zerg Missile Attack Level 3"], - "Progressive Zerg Ground Carapace": ["Zerg Ground Carapace Level 1", - "Zerg Ground Carapace Level 1", - "Zerg Ground Carapace Level 2", - "Zerg Ground Carapace Level 3"], - "Progressive Zerg Flyer Attack": ["Zerg Flyer Attack Level 1", - "Zerg Flyer Attack Level 1", - "Zerg Flyer Attack Level 2", - "Zerg Flyer Attack Level 3"], - "Progressive Zerg Flyer Carapace": ["Zerg Flyer Carapace Level 1", - "Zerg Flyer Carapace Level 1", - "Zerg Flyer Carapace Level 2", - "Zerg Flyer Carapace Level 3"], - "Progressive Protoss Ground Weapon": ["Protoss Ground Weapon Level 1", - "Protoss Ground Weapon Level 1", - "Protoss Ground Weapon Level 2", - "Protoss Ground Weapon Level 3"], - "Progressive Protoss Ground Armor": ["Protoss Ground Armor Level 1", - "Protoss Ground Armor Level 1", - "Protoss Ground Armor Level 2", - "Protoss Ground Armor Level 3"], - "Progressive Protoss Shields": ["Protoss Shields Level 1", "Protoss Shields Level 1", - "Protoss Shields Level 2", "Protoss Shields Level 3"], - "Progressive Protoss Air Weapon": ["Protoss Air Weapon Level 1", - "Protoss Air Weapon Level 1", - "Protoss Air Weapon Level 2", - "Protoss Air Weapon Level 3"], - "Progressive Protoss Air Armor": ["Protoss Air Armor Level 1", - "Protoss Air Armor Level 1", - "Protoss Air Armor Level 2", - "Protoss Air Armor Level 3"], - "Progressive Proxy Pylon (Spear of Adun Calldown)": ["Proxy Pylon (Spear of Adun Calldown)", - "Proxy Pylon (Spear of Adun Calldown)", - "Warp In Reinforcements (Spear of Adun Calldown)"] - } - for item_name, item_id in progressive_items.items(): - level = min(inventory[item_id], len(progressive_names[item_name]) - 1) - display_name = progressive_names[item_name][level] - base_name = (item_name.split(maxsplit=1)[1].lower() - .replace(' ', '_') - .replace("-", "") - .replace("(", "") - .replace(")", "")) - display_data[base_name + "_level"] = level - display_data[base_name + "_url"] = icons[display_name] if display_name in icons else "FIXME" - display_data[base_name + "_name"] = display_name - - # Multi-items - multi_items = { - "Additional Starting Minerals": 800 + SC2WOL_ITEM_ID_OFFSET, - "Additional Starting Vespene": 801 + SC2WOL_ITEM_ID_OFFSET, - "Additional Starting Supply": 802 + SC2WOL_ITEM_ID_OFFSET - } - for item_name, item_id in multi_items.items(): - base_name = item_name.split()[-1].lower() - count = inventory[item_id] - if base_name == "supply": - count = count * starting_supply_per_item - elif base_name == "minerals": - count = count * minerals_per_item - elif base_name == "vespene": - count = count * vespene_per_item - display_data[base_name + "_count"] = count # Kerrigan level - level_items = { - "1 Kerrigan Level": 509 + SC2HOTS_ITEM_ID_OFFSET, - "2 Kerrigan Levels": 508 + SC2HOTS_ITEM_ID_OFFSET, - "3 Kerrigan Levels": 507 + SC2HOTS_ITEM_ID_OFFSET, - "4 Kerrigan Levels": 506 + SC2HOTS_ITEM_ID_OFFSET, - "5 Kerrigan Levels": 505 + SC2HOTS_ITEM_ID_OFFSET, - "6 Kerrigan Levels": 504 + SC2HOTS_ITEM_ID_OFFSET, - "7 Kerrigan Levels": 503 + SC2HOTS_ITEM_ID_OFFSET, - "8 Kerrigan Levels": 502 + SC2HOTS_ITEM_ID_OFFSET, - "9 Kerrigan Levels": 501 + SC2HOTS_ITEM_ID_OFFSET, - "10 Kerrigan Levels": 500 + SC2HOTS_ITEM_ID_OFFSET, - "14 Kerrigan Levels": 510 + SC2HOTS_ITEM_ID_OFFSET, - "35 Kerrigan Levels": 511 + SC2HOTS_ITEM_ID_OFFSET, - "70 Kerrigan Levels": 512 + SC2HOTS_ITEM_ID_OFFSET, - } - level_amounts = { - "1 Kerrigan Level": 1, - "2 Kerrigan Levels": 2, - "3 Kerrigan Levels": 3, - "4 Kerrigan Levels": 4, - "5 Kerrigan Levels": 5, - "6 Kerrigan Levels": 6, - "7 Kerrigan Levels": 7, - "8 Kerrigan Levels": 8, - "9 Kerrigan Levels": 9, - "10 Kerrigan Levels": 10, - "14 Kerrigan Levels": 14, - "35 Kerrigan Levels": 35, - "70 Kerrigan Levels": 70, - } + level_item_id_to_amount = ( + (509 + SC2HOTS_ITEM_ID_OFFSET, 1,), + (508 + SC2HOTS_ITEM_ID_OFFSET, 2,), + (507 + SC2HOTS_ITEM_ID_OFFSET, 3,), + (506 + SC2HOTS_ITEM_ID_OFFSET, 4,), + (505 + SC2HOTS_ITEM_ID_OFFSET, 5,), + (504 + SC2HOTS_ITEM_ID_OFFSET, 6,), + (503 + SC2HOTS_ITEM_ID_OFFSET, 7,), + (502 + SC2HOTS_ITEM_ID_OFFSET, 8,), + (501 + SC2HOTS_ITEM_ID_OFFSET, 9,), + (500 + SC2HOTS_ITEM_ID_OFFSET, 10,), + (510 + SC2HOTS_ITEM_ID_OFFSET, 14,), + (511 + SC2HOTS_ITEM_ID_OFFSET, 35,), + (512 + SC2HOTS_ITEM_ID_OFFSET, 70,), + ) kerrigan_level = 0 - for item_name, item_id in level_items.items(): - count = inventory[item_id] - amount = level_amounts[item_name] - kerrigan_level += count * amount + for item_id, levels_per_item in level_item_id_to_amount: + kerrigan_level += levels_per_item * inventory[item_id] display_data["kerrigan_level"] = kerrigan_level + # Hero presence + display_data["kerrigan_present"] = slot_data.get("kerrigan_presence", 0) == 0 + display_data["nova_present"] = have_nco_locations + + # Upgrades + TERRAN_INFANTRY_WEAPON_ID = 100 + SC2WOL_ITEM_ID_OFFSET + TERRAN_INFANTRY_ARMOR_ID = 102 + SC2WOL_ITEM_ID_OFFSET + TERRAN_VEHICLE_WEAPON_ID = 103 + SC2WOL_ITEM_ID_OFFSET + TERRAN_VEHICLE_ARMOR_ID = 104 + SC2WOL_ITEM_ID_OFFSET + TERRAN_SHIP_WEAPON_ID = 105 + SC2WOL_ITEM_ID_OFFSET + TERRAN_SHIP_ARMOR_ID = 106 + SC2WOL_ITEM_ID_OFFSET + ZERG_MELEE_ATTACK_ID = 100 + SC2HOTS_ITEM_ID_OFFSET + ZERG_MISSILE_ATTACK_ID = 101 + SC2HOTS_ITEM_ID_OFFSET + ZERG_GROUND_CARAPACE_ID = 102 + SC2HOTS_ITEM_ID_OFFSET + ZERG_FLYER_ATTACK_ID = 103 + SC2HOTS_ITEM_ID_OFFSET + ZERG_FLYER_CARAPACE_ID = 104 + SC2HOTS_ITEM_ID_OFFSET + PROTOSS_GROUND_WEAPON_ID = 100 + SC2LOTV_ITEM_ID_OFFSET + PROTOSS_GROUND_ARMOR_ID = 101 + SC2LOTV_ITEM_ID_OFFSET + PROTOSS_SHIELDS_ID = 102 + SC2LOTV_ITEM_ID_OFFSET + PROTOSS_AIR_WEAPON_ID = 103 + SC2LOTV_ITEM_ID_OFFSET + PROTOSS_AIR_ARMOR_ID = 104 + SC2LOTV_ITEM_ID_OFFSET + + # Bundles + TERRAN_WEAPON_UPGRADE_ID = 107 + SC2WOL_ITEM_ID_OFFSET + TERRAN_ARMOR_UPGRADE_ID = 108 + SC2WOL_ITEM_ID_OFFSET + TERRAN_INFANTRY_UPGRADE_ID = 109 + SC2WOL_ITEM_ID_OFFSET + TERRAN_VEHICLE_UPGRADE_ID = 110 + SC2WOL_ITEM_ID_OFFSET + TERRAN_SHIP_UPGRADE_ID = 111 + SC2WOL_ITEM_ID_OFFSET + TERRAN_WEAPON_ARMOR_UPGRADE_ID = 112 + SC2WOL_ITEM_ID_OFFSET + ZERG_WEAPON_UPGRADE_ID = 105 + SC2HOTS_ITEM_ID_OFFSET + ZERG_ARMOR_UPGRADE_ID = 106 + SC2HOTS_ITEM_ID_OFFSET + ZERG_GROUND_UPGRADE_ID = 107 + SC2HOTS_ITEM_ID_OFFSET + ZERG_FLYER_UPGRADE_ID = 108 + SC2HOTS_ITEM_ID_OFFSET + ZERG_WEAPON_ARMOR_UPGRADE_ID = 109 + SC2HOTS_ITEM_ID_OFFSET + PROTOSS_WEAPON_UPGRADE_ID = 105 + SC2LOTV_ITEM_ID_OFFSET + PROTOSS_ARMOR_UPGRADE_ID = 106 + SC2LOTV_ITEM_ID_OFFSET + PROTOSS_GROUND_UPGRADE_ID = 107 + SC2LOTV_ITEM_ID_OFFSET + PROTOSS_AIR_UPGRADE_ID = 108 + SC2LOTV_ITEM_ID_OFFSET + PROTOSS_WEAPON_ARMOR_UPGRADE_ID = 109 + SC2LOTV_ITEM_ID_OFFSET + grouped_item_replacements = { + TERRAN_WEAPON_UPGRADE_ID: [ + TERRAN_INFANTRY_WEAPON_ID, + TERRAN_VEHICLE_WEAPON_ID, + TERRAN_SHIP_WEAPON_ID, + ], + TERRAN_ARMOR_UPGRADE_ID: [ + TERRAN_INFANTRY_ARMOR_ID, + TERRAN_VEHICLE_ARMOR_ID, + TERRAN_SHIP_ARMOR_ID, + ], + TERRAN_INFANTRY_UPGRADE_ID: [ + TERRAN_INFANTRY_WEAPON_ID, + TERRAN_INFANTRY_ARMOR_ID, + ], + TERRAN_VEHICLE_UPGRADE_ID: [ + TERRAN_VEHICLE_WEAPON_ID, + TERRAN_VEHICLE_ARMOR_ID, + ], + TERRAN_SHIP_UPGRADE_ID: [ + TERRAN_SHIP_WEAPON_ID, + TERRAN_SHIP_ARMOR_ID + ], + ZERG_WEAPON_UPGRADE_ID: [ + ZERG_MELEE_ATTACK_ID, + ZERG_MISSILE_ATTACK_ID, + ZERG_FLYER_ATTACK_ID, + ], + ZERG_ARMOR_UPGRADE_ID: [ + ZERG_GROUND_CARAPACE_ID, + ZERG_FLYER_CARAPACE_ID, + ], + ZERG_GROUND_UPGRADE_ID: [ + ZERG_MELEE_ATTACK_ID, + ZERG_MISSILE_ATTACK_ID, + ZERG_GROUND_CARAPACE_ID, + ], + ZERG_FLYER_UPGRADE_ID: [ + ZERG_FLYER_ATTACK_ID, + ZERG_FLYER_CARAPACE_ID, + ], + PROTOSS_WEAPON_UPGRADE_ID: [ + PROTOSS_GROUND_WEAPON_ID, + PROTOSS_AIR_WEAPON_ID, + ], + PROTOSS_ARMOR_UPGRADE_ID: [ + PROTOSS_GROUND_ARMOR_ID, + PROTOSS_SHIELDS_ID, + PROTOSS_AIR_ARMOR_ID, + ], + PROTOSS_GROUND_UPGRADE_ID: [ + PROTOSS_GROUND_WEAPON_ID, + PROTOSS_GROUND_ARMOR_ID, + PROTOSS_SHIELDS_ID, + ], + PROTOSS_AIR_UPGRADE_ID: [ + PROTOSS_AIR_WEAPON_ID, + PROTOSS_AIR_ARMOR_ID, + PROTOSS_SHIELDS_ID, + ] + } + grouped_item_replacements[TERRAN_WEAPON_ARMOR_UPGRADE_ID] = ( + grouped_item_replacements[TERRAN_WEAPON_UPGRADE_ID] + + grouped_item_replacements[TERRAN_ARMOR_UPGRADE_ID] + ) + grouped_item_replacements[ZERG_WEAPON_ARMOR_UPGRADE_ID] = ( + grouped_item_replacements[ZERG_WEAPON_UPGRADE_ID] + + grouped_item_replacements[ZERG_ARMOR_UPGRADE_ID] + ) + grouped_item_replacements[PROTOSS_WEAPON_ARMOR_UPGRADE_ID] = ( + grouped_item_replacements[PROTOSS_WEAPON_UPGRADE_ID] + + grouped_item_replacements[PROTOSS_ARMOR_UPGRADE_ID] + ) + for bundle_id, upgrade_ids in grouped_item_replacements.items(): + bundle_amount = inventory[bundle_id] + for upgrade_id in upgrade_ids: + if bundle_amount > inventory[upgrade_id]: + # Only assign, don't add. + # This behaviour mimics protoss shields, where the output is + # the maximum bundle contribution, not the sum + inventory[upgrade_id] = bundle_amount + + # Victory condition game_state = tracker_data.get_player_client_status(team, player) - display_data["game_finished"] = game_state == 30 + display_data["game_finished"] = game_state == ClientStatus.CLIENT_GOAL - # Turn location IDs into mission objective counts - locations = tracker_data.get_player_locations(team, player) - checked_locations = tracker_data.get_player_checked_locations(team, player) - lookup_name = lambda id: tracker_data.location_id_to_name["Starcraft 2"][id] - location_info = {mission_name: {lookup_name(id): (id in checked_locations) for id in mission_locations if - id in set(locations)} for mission_name, mission_locations in - sc2wol_location_ids.items()} - checks_done = {mission_name: len( - [id for id in mission_locations if id in checked_locations and id in set(locations)]) for - mission_name, mission_locations in sc2wol_location_ids.items()} - checks_done['Total'] = len(checked_locations) - checks_in_area = {mission_name: len([id for id in mission_locations if id in set(locations)]) for - mission_name, mission_locations in sc2wol_location_ids.items()} - checks_in_area['Total'] = sum(checks_in_area.values()) + # Keys + keys: dict[str, int] = {} + for item_id, item_count in inventory.items(): + if item_id < SC2_KEY_ITEM_ID_OFFSET: + continue + keys[item_id_to_name[item_id]] = item_count - lookup_any_item_id_to_name = tracker_data.item_id_to_name["Starcraft 2"] return render_template( "tracker__Starcraft2.html", inventory=inventory, - icons=icons, - acquired_items={lookup_any_item_id_to_name[id] for id, count in inventory.items() if count > 0}, player=player, team=team, room=tracker_data.room, player_name=tracker_data.get_player_name(team, player), - checks_done=checks_done, - checks_in_area=checks_in_area, - location_info=location_info, + missions=missions, + locations=locations, + checked_locations=checked_locations, + location_id_to_name=location_id_to_name, + item_id_to_name=item_id_to_name, + keys=keys, + saving_second=tracker_data.get_room_saving_second(), **display_data, ) + _player_trackers["Starcraft 2"] = render_Starcraft2_tracker diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index 06c77ab060e3..7bd47d0bd35c 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -229,8 +229,6 @@ def install_apworld(apworld_path: str = "") -> None: Component('Zelda 1 Client', 'Zelda1Client', file_identifier=SuffixIdentifier('.aptloz')), # ChecksFinder Component('ChecksFinder Client', 'ChecksFinderClient'), - # Starcraft 2 - Component('Starcraft 2 Client', 'Starcraft2Client'), # Zillion Component('Zillion Client', 'ZillionClient', file_identifier=SuffixIdentifier('.apzl')), diff --git a/worlds/_sc2common/bot/game_data.py b/worlds/_sc2common/bot/game_data.py index 50f10bd6692e..ed0edf0b8cb4 100644 --- a/worlds/_sc2common/bot/game_data.py +++ b/worlds/_sc2common/bot/game_data.py @@ -19,7 +19,7 @@ def __init__(self, data): """ :param data: """ - self.abilities: Dict[int, AbilityData] = {} + self.abilities: Dict[int, AbilityData] = {a.ability_id: AbilityData(self, a) for a in data.abilities if a.available} self.units: Dict[int, UnitTypeData] = {u.unit_id: UnitTypeData(self, u) for u in data.units if u.available} self.upgrades: Dict[int, UpgradeData] = {u.upgrade_id: UpgradeData(self, u) for u in data.upgrades} # Cached UnitTypeIds so that conversion does not take long. This needs to be moved elsewhere if a new GameData object is created multiple times per game @@ -40,7 +40,7 @@ def __init__(self, game_data, proto): self._proto = proto # What happens if we comment this out? Should this not be commented out? What is its purpose? - assert self.id != 0 + # assert self.id != 0 # let the world burn def __repr__(self) -> str: return f"AbilityData(name={self._proto.button_name})" diff --git a/worlds/sc2/Client.py b/worlds/sc2/Client.py deleted file mode 100644 index 77b13a5acbdd..000000000000 --- a/worlds/sc2/Client.py +++ /dev/null @@ -1,1630 +0,0 @@ -from __future__ import annotations - -import asyncio -import copy -import ctypes -import enum -import inspect -import logging -import multiprocessing -import os.path -import re -import sys -import tempfile -import typing -import queue -import zipfile -import io -import random -import concurrent.futures -from pathlib import Path - -# CommonClient import first to trigger ModuleUpdater -from CommonClient import CommonContext, server_loop, ClientCommandProcessor, gui_enabled, get_base_parser -from Utils import init_logging, is_windows, async_start -from . import ItemNames, Options -from .ItemGroups import item_name_groups -from .Options import ( - MissionOrder, KerriganPrimalStatus, kerrigan_unit_available, KerriganPresence, - GameSpeed, GenericUpgradeItems, GenericUpgradeResearch, ColorChoice, GenericUpgradeMissions, - LocationInclusion, ExtraLocations, MasteryLocations, ChallengeLocations, VanillaLocations, - DisableForcedCamera, SkipCutscenes, GrantStoryTech, GrantStoryLevels, TakeOverAIAllies, RequiredTactics, - SpearOfAdunPresence, SpearOfAdunPresentInNoBuild, SpearOfAdunAutonomouslyCastAbilityPresence, - SpearOfAdunAutonomouslyCastPresentInNoBuild -) - - -if __name__ == "__main__": - init_logging("SC2Client", exception_logger="Client") - -logger = logging.getLogger("Client") -sc2_logger = logging.getLogger("Starcraft2") - -import nest_asyncio -from worlds._sc2common import bot -from worlds._sc2common.bot.data import Race -from worlds._sc2common.bot.main import run_game -from worlds._sc2common.bot.player import Bot -from .Items import (lookup_id_to_name, get_full_item_list, ItemData, type_flaggroups, upgrade_numbers, - upgrade_numbers_all) -from .Locations import SC2WOL_LOC_ID_OFFSET, LocationType, SC2HOTS_LOC_ID_OFFSET -from .MissionTables import (lookup_id_to_mission, SC2Campaign, lookup_name_to_mission, - lookup_id_to_campaign, MissionConnection, SC2Mission, campaign_mission_table, SC2Race) -from .Regions import MissionInfo - -import colorama -from Options import Option -from NetUtils import ClientStatus, NetworkItem, JSONtoTextParser, JSONMessagePart, add_json_item, add_json_location, add_json_text, JSONTypes -from MultiServer import mark_raw - -pool = concurrent.futures.ThreadPoolExecutor(1) -loop = asyncio.get_event_loop_policy().new_event_loop() -nest_asyncio.apply(loop) -MAX_BONUS: int = 28 -VICTORY_MODULO: int = 100 - -# GitHub repo where the Map/mod data is hosted for /download_data command -DATA_REPO_OWNER = "Ziktofel" -DATA_REPO_NAME = "Archipelago-SC2-data" -DATA_API_VERSION = "API3" - -# Bot controller -CONTROLLER_HEALTH: int = 38281 -CONTROLLER2_HEALTH: int = 38282 - -# Games -STARCRAFT2 = "Starcraft 2" -STARCRAFT2_WOL = "Starcraft 2 Wings of Liberty" - - -# Data version file path. -# This file is used to tell if the downloaded data are outdated -# Associated with /download_data command -def get_metadata_file() -> str: - return os.environ["SC2PATH"] + os.sep + "ArchipelagoSC2Metadata.txt" - - -class ConfigurableOptionType(enum.Enum): - INTEGER = enum.auto() - ENUM = enum.auto() - -class ConfigurableOptionInfo(typing.NamedTuple): - name: str - variable_name: str - option_class: typing.Type[Option] - option_type: ConfigurableOptionType = ConfigurableOptionType.ENUM - can_break_logic: bool = False - - -class ColouredMessage: - def __init__(self, text: str = '', *, keep_markup: bool = False) -> None: - self.parts: typing.List[dict] = [] - if text: - self(text, keep_markup=keep_markup) - def __call__(self, text: str, *, keep_markup: bool = False) -> 'ColouredMessage': - add_json_text(self.parts, text, keep_markup=keep_markup) - return self - def coloured(self, text: str, colour: str) -> 'ColouredMessage': - add_json_text(self.parts, text, type="color", color=colour) - return self - def location(self, location_id: int, player_id: int) -> 'ColouredMessage': - add_json_location(self.parts, location_id, player_id) - return self - def item(self, item_id: int, player_id: int, flags: int = 0) -> 'ColouredMessage': - add_json_item(self.parts, item_id, player_id, flags) - return self - def player(self, player_id: int) -> 'ColouredMessage': - add_json_text(self.parts, str(player_id), type=JSONTypes.player_id) - return self - def send(self, ctx: SC2Context) -> None: - ctx.on_print_json({"data": self.parts, "cmd": "PrintJSON"}) - - -class StarcraftClientProcessor(ClientCommandProcessor): - ctx: SC2Context - - def formatted_print(self, text: str) -> None: - """Prints with kivy formatting to the GUI, and also prints to command-line and to all logs""" - # Note(mm): Bold/underline can help readability, but unfortunately the CommonClient does not filter bold tags from command-line output. - # Regardless, using `on_print_json` to get formatted text in the GUI and output in the command-line and in the logs, - # without having to branch code from CommonClient - self.ctx.on_print_json({"data": [{"text": text, "keep_markup": True}]}) - - def _cmd_difficulty(self, difficulty: str = "") -> bool: - """Overrides the current difficulty set for the world. Takes the argument casual, normal, hard, or brutal""" - options = difficulty.split() - num_options = len(options) - - if num_options > 0: - difficulty_choice = options[0].lower() - if difficulty_choice == "casual": - self.ctx.difficulty_override = 0 - elif difficulty_choice == "normal": - self.ctx.difficulty_override = 1 - elif difficulty_choice == "hard": - self.ctx.difficulty_override = 2 - elif difficulty_choice == "brutal": - self.ctx.difficulty_override = 3 - else: - self.output("Unable to parse difficulty '" + options[0] + "'") - return False - - self.output("Difficulty set to " + options[0]) - return True - - else: - if self.ctx.difficulty == -1: - self.output("Please connect to a seed before checking difficulty.") - else: - current_difficulty = self.ctx.difficulty - if self.ctx.difficulty_override >= 0: - current_difficulty = self.ctx.difficulty_override - self.output("Current difficulty: " + ["Casual", "Normal", "Hard", "Brutal"][current_difficulty]) - self.output("To change the difficulty, add the name of the difficulty after the command.") - return False - - - def _cmd_game_speed(self, game_speed: str = "") -> bool: - """Overrides the current game speed for the world. - Takes the arguments default, slower, slow, normal, fast, faster""" - options = game_speed.split() - num_options = len(options) - - if num_options > 0: - speed_choice = options[0].lower() - if speed_choice == "default": - self.ctx.game_speed_override = 0 - elif speed_choice == "slower": - self.ctx.game_speed_override = 1 - elif speed_choice == "slow": - self.ctx.game_speed_override = 2 - elif speed_choice == "normal": - self.ctx.game_speed_override = 3 - elif speed_choice == "fast": - self.ctx.game_speed_override = 4 - elif speed_choice == "faster": - self.ctx.game_speed_override = 5 - else: - self.output("Unable to parse game speed '" + options[0] + "'") - return False - - self.output("Game speed set to " + options[0]) - return True - - else: - if self.ctx.game_speed == -1: - self.output("Please connect to a seed before checking game speed.") - else: - current_speed = self.ctx.game_speed - if self.ctx.game_speed_override >= 0: - current_speed = self.ctx.game_speed_override - self.output("Current game speed: " - + ["Default", "Slower", "Slow", "Normal", "Fast", "Faster"][current_speed]) - self.output("To change the game speed, add the name of the speed after the command," - " or Default to select based on difficulty.") - return False - - @mark_raw - def _cmd_received(self, filter_search: str = "") -> bool: - """List received items. - Pass in a parameter to filter the search by partial item name or exact item group.""" - # Groups must be matched case-sensitively, so we properly capitalize the search term - # eg. "Spear of Adun" over "Spear Of Adun" or "spear of adun" - # This fails a lot of item name matches, but those should be found by partial name match - formatted_filter_search = " ".join([(part.lower() if len(part) <= 3 else part.lower().capitalize()) for part in filter_search.split()]) - - def item_matches_filter(item_name: str) -> bool: - # The filter can be an exact group name or a partial item name - # Partial item name can be matched case-insensitively - if filter_search.lower() in item_name.lower(): - return True - # The search term should already be formatted as a group name - if formatted_filter_search in item_name_groups and item_name in item_name_groups[formatted_filter_search]: - return True - return False - - items = get_full_item_list() - categorized_items: typing.Dict[SC2Race, typing.List[int]] = {} - parent_to_child: typing.Dict[int, typing.List[int]] = {} - items_received: typing.Dict[int, typing.List[NetworkItem]] = {} - filter_match_count = 0 - for item in self.ctx.items_received: - items_received.setdefault(item.item, []).append(item) - items_received_set = set(items_received) - for item_data in items.values(): - if item_data.parent_item: - parent_to_child.setdefault(items[item_data.parent_item].code, []).append(item_data.code) - else: - categorized_items.setdefault(item_data.race, []).append(item_data.code) - for faction in SC2Race: - has_printed_faction_title = False - def print_faction_title(): - if not has_printed_faction_title: - self.formatted_print(f" [u]{faction.name}[/u] ") - - for item_id in categorized_items[faction]: - item_name = self.ctx.item_names.lookup_in_game(item_id) - received_child_items = items_received_set.intersection(parent_to_child.get(item_id, [])) - matching_children = [child for child in received_child_items - if item_matches_filter(self.ctx.item_names.lookup_in_game(child))] - received_items_of_this_type = items_received.get(item_id, []) - item_is_match = item_matches_filter(item_name) - if item_is_match or len(matching_children) > 0: - # Print found item if it or its children match the filter - if item_is_match: - filter_match_count += len(received_items_of_this_type) - for item in received_items_of_this_type: - print_faction_title() - has_printed_faction_title = True - (ColouredMessage('* ').item(item.item, self.ctx.slot, flags=item.flags) - (" from ").location(item.location, item.player) - (" by ").player(item.player) - ).send(self.ctx) - - if received_child_items: - # We have this item's children - if len(matching_children) == 0: - # ...but none of them match the filter - continue - - if not received_items_of_this_type: - # We didn't receive the item itself - print_faction_title() - has_printed_faction_title = True - ColouredMessage("- ").coloured(item_name, "black")(" - not obtained").send(self.ctx) - - for child_item in matching_children: - received_items_of_this_type = items_received.get(child_item, []) - for item in received_items_of_this_type: - filter_match_count += len(received_items_of_this_type) - (ColouredMessage(' * ').item(item.item, self.ctx.slot, flags=item.flags) - (" from ").location(item.location, item.player) - (" by ").player(item.player) - ).send(self.ctx) - - non_matching_children = len(received_child_items) - len(matching_children) - if non_matching_children > 0: - self.formatted_print(f" + {non_matching_children} child items that don't match the filter") - if filter_search == "": - self.formatted_print(f"[b]Obtained: {len(self.ctx.items_received)} items[/b]") - else: - self.formatted_print(f"[b]Filter \"{filter_search}\" found {filter_match_count} out of {len(self.ctx.items_received)} obtained items[/b]") - return True - - def _cmd_option(self, option_name: str = "", option_value: str = "") -> None: - """Sets a Starcraft game option that can be changed after generation. Use "/option list" to see all options.""" - - LOGIC_WARNING = f" *Note changing this may result in logically unbeatable games*\n" - - options = ( - ConfigurableOptionInfo('kerrigan_presence', 'kerrigan_presence', Options.KerriganPresence, can_break_logic=True), - ConfigurableOptionInfo('soa_presence', 'spear_of_adun_presence', Options.SpearOfAdunPresence, can_break_logic=True), - ConfigurableOptionInfo('soa_in_nobuilds', 'spear_of_adun_present_in_no_build', Options.SpearOfAdunPresentInNoBuild, can_break_logic=True), - ConfigurableOptionInfo('control_ally', 'take_over_ai_allies', Options.TakeOverAIAllies, can_break_logic=True), - ConfigurableOptionInfo('minerals_per_item', 'minerals_per_item', Options.MineralsPerItem, ConfigurableOptionType.INTEGER), - ConfigurableOptionInfo('gas_per_item', 'vespene_per_item', Options.VespenePerItem, ConfigurableOptionType.INTEGER), - ConfigurableOptionInfo('supply_per_item', 'starting_supply_per_item', Options.StartingSupplyPerItem, ConfigurableOptionType.INTEGER), - ConfigurableOptionInfo('no_forced_camera', 'disable_forced_camera', Options.DisableForcedCamera), - ConfigurableOptionInfo('skip_cutscenes', 'skip_cutscenes', Options.SkipCutscenes), - ) - - WARNING_COLOUR = "salmon" - CMD_COLOUR = "slateblue" - boolean_option_map = { - 'y': 'true', 'yes': 'true', 'n': 'false', 'no': 'false', - } - - help_message = ColouredMessage(inspect.cleandoc(""" - Options - -------------------- - """))('\n') - for option in options: - option_help_text = inspect.cleandoc(option.option_class.__doc__ or "No description provided.").split('\n', 1)[0] - help_message.coloured(option.name, CMD_COLOUR)(": " + " | ".join(option.option_class.options) - + f" -- {option_help_text}\n") - if option.can_break_logic: - help_message.coloured(LOGIC_WARNING, WARNING_COLOUR) - help_message("--------------------\nEnter an option without arguments to see its current value.\n") - - if not option_name or option_name == 'list' or option_name == 'help': - help_message.send(self.ctx) - return - for option in options: - if option_name == option.name: - option_value = boolean_option_map.get(option_value, option_value) - if not option_value: - pass - elif option.option_type == ConfigurableOptionType.ENUM and option_value in option.option_class.options: - self.ctx.__dict__[option.variable_name] = option.option_class.options[option_value] - elif option.option_type == ConfigurableOptionType.INTEGER: - try: - self.ctx.__dict__[option.variable_name] = int(option_value, base=0) - except: - self.output(f"{option_value} is not a valid integer") - else: - self.output(f"Unknown option value '{option_value}'") - ColouredMessage(f"{option.name} is '{option.option_class.get_option_name(self.ctx.__dict__[option.variable_name])}'").send(self.ctx) - break - else: - self.output(f"Unknown option '{option_name}'") - help_message.send(self.ctx) - - def _cmd_color(self, faction: str = "", color: str = "") -> None: - """Changes the player color for a given faction.""" - player_colors = [ - "White", "Red", "Blue", "Teal", - "Purple", "Yellow", "Orange", "Green", - "LightPink", "Violet", "LightGrey", "DarkGreen", - "Brown", "LightGreen", "DarkGrey", "Pink", - "Rainbow", "Random", "Default" - ] - var_names = { - 'raynor': 'player_color_raynor', - 'kerrigan': 'player_color_zerg', - 'primal': 'player_color_zerg_primal', - 'protoss': 'player_color_protoss', - 'nova': 'player_color_nova', - } - faction = faction.lower() - if not faction: - for faction_name, key in var_names.items(): - self.output(f"Current player color for {faction_name}: {player_colors[self.ctx.__dict__[key]]}") - self.output("To change your color, add the faction name and color after the command.") - self.output("Available factions: " + ', '.join(var_names)) - self.output("Available colors: " + ', '.join(player_colors)) - return - elif faction not in var_names: - self.output(f"Unknown faction '{faction}'.") - self.output("Available factions: " + ', '.join(var_names)) - return - match_colors = [player_color.lower() for player_color in player_colors] - if not color: - self.output(f"Current player color for {faction}: {player_colors[self.ctx.__dict__[var_names[faction]]]}") - self.output("To change this faction's colors, add the name of the color after the command.") - self.output("Available colors: " + ', '.join(player_colors)) - else: - if color.lower() not in match_colors: - self.output(color + " is not a valid color. Available colors: " + ', '.join(player_colors)) - return - if color.lower() == "random": - color = random.choice(player_colors[:16]) - self.ctx.__dict__[var_names[faction]] = match_colors.index(color.lower()) - self.ctx.pending_color_update = True - self.output(f"Color for {faction} set to " + player_colors[self.ctx.__dict__[var_names[faction]]]) - - def _cmd_disable_mission_check(self) -> bool: - """Disables the check to see if a mission is available to play. Meant for co-op runs where one player can play - the next mission in a chain the other player is doing.""" - self.ctx.missions_unlocked = True - sc2_logger.info("Mission check has been disabled") - return True - - def _cmd_play(self, mission_id: str = "") -> bool: - """Start a Starcraft 2 mission""" - - options = mission_id.split() - num_options = len(options) - - if num_options > 0: - mission_number = int(options[0]) - - self.ctx.play_mission(mission_number) - - else: - sc2_logger.info( - "Mission ID needs to be specified. Use /unfinished or /available to view ids for available missions.") - return False - - return True - - def _cmd_available(self) -> bool: - """Get what missions are currently available to play""" - - request_available_missions(self.ctx) - return True - - def _cmd_unfinished(self) -> bool: - """Get what missions are currently available to play and have not had all locations checked""" - - request_unfinished_missions(self.ctx) - return True - - @mark_raw - def _cmd_set_path(self, path: str = '') -> bool: - """Manually set the SC2 install directory (if the automatic detection fails).""" - if path: - os.environ["SC2PATH"] = path - is_mod_installed_correctly() - return True - else: - sc2_logger.warning("When using set_path, you must type the path to your SC2 install directory.") - return False - - def _cmd_download_data(self) -> bool: - """Download the most recent release of the necessary files for playing SC2 with - Archipelago. Will overwrite existing files.""" - pool.submit(self._download_data) - return True - - @staticmethod - def _download_data() -> bool: - if "SC2PATH" not in os.environ: - check_game_install_path() - - if os.path.exists(get_metadata_file()): - with open(get_metadata_file(), "r") as f: - metadata = f.read() - else: - metadata = None - - tempzip, metadata = download_latest_release_zip( - DATA_REPO_OWNER, DATA_REPO_NAME, DATA_API_VERSION, metadata=metadata, force_download=True) - - if tempzip: - try: - zipfile.ZipFile(tempzip).extractall(path=os.environ["SC2PATH"]) - sc2_logger.info(f"Download complete. Package installed.") - if metadata is not None: - with open(get_metadata_file(), "w") as f: - f.write(metadata) - finally: - os.remove(tempzip) - else: - sc2_logger.warning("Download aborted/failed. Read the log for more information.") - return False - return True - - -class SC2JSONtoTextParser(JSONtoTextParser): - def __init__(self, ctx) -> None: - self.handlers = { - "ItemSend": self._handle_color, - "ItemCheat": self._handle_color, - "Hint": self._handle_color, - } - super().__init__(ctx) - - def _handle_color(self, node: JSONMessagePart) -> str: - codes = node["color"].split(";") - buffer = "".join(self.color_code(code) for code in codes if code in self.color_codes) - return buffer + self._handle_text(node) + '' - - def color_code(self, code: str) -> str: - return '' - - -class SC2Context(CommonContext): - command_processor = StarcraftClientProcessor - game = STARCRAFT2 - items_handling = 0b111 - - def __init__(self, *args, **kwargs) -> None: - super(SC2Context, self).__init__(*args, **kwargs) - self.raw_text_parser = SC2JSONtoTextParser(self) - - self.difficulty = -1 - self.game_speed = -1 - self.disable_forced_camera = 0 - self.skip_cutscenes = 0 - self.all_in_choice = 0 - self.mission_order = 0 - self.player_color_raynor = ColorChoice.option_blue - self.player_color_zerg = ColorChoice.option_orange - self.player_color_zerg_primal = ColorChoice.option_purple - self.player_color_protoss = ColorChoice.option_blue - self.player_color_nova = ColorChoice.option_dark_grey - self.pending_color_update = False - self.kerrigan_presence = 0 - self.kerrigan_primal_status = 0 - self.levels_per_check = 0 - self.checks_per_level = 1 - self.mission_req_table: typing.Dict[SC2Campaign, typing.Dict[str, MissionInfo]] = {} - self.final_mission: int = 29 - self.announcements: queue.Queue = queue.Queue() - self.sc2_run_task: typing.Optional[asyncio.Task] = None - self.missions_unlocked: bool = False # allow launching missions ignoring requirements - self.generic_upgrade_missions = 0 - self.generic_upgrade_research = 0 - self.generic_upgrade_items = 0 - self.location_inclusions: typing.Dict[LocationType, int] = {} - self.plando_locations: typing.List[str] = [] - self.current_tooltip = None - self.last_loc_list = None - self.difficulty_override = -1 - self.game_speed_override = -1 - self.mission_id_to_location_ids: typing.Dict[int, typing.List[int]] = {} - self.last_bot: typing.Optional[ArchipelagoBot] = None - self.slot_data_version = 2 - self.grant_story_tech = 0 - self.required_tactics = RequiredTactics.option_standard - self.take_over_ai_allies = TakeOverAIAllies.option_false - self.spear_of_adun_presence = SpearOfAdunPresence.option_not_present - self.spear_of_adun_present_in_no_build = SpearOfAdunPresentInNoBuild.option_false - self.spear_of_adun_autonomously_cast_ability_presence = SpearOfAdunAutonomouslyCastAbilityPresence.option_not_present - self.spear_of_adun_autonomously_cast_present_in_no_build = SpearOfAdunAutonomouslyCastPresentInNoBuild.option_false - self.minerals_per_item = 15 - self.vespene_per_item = 15 - self.starting_supply_per_item = 2 - self.nova_covert_ops_only = False - self.kerrigan_levels_per_mission_completed = 0 - - async def server_auth(self, password_requested: bool = False) -> None: - self.game = STARCRAFT2 - if password_requested and not self.password: - await super(SC2Context, self).server_auth(password_requested) - await self.get_username() - await self.send_connect() - if self.ui: - self.ui.first_check = True - - def is_legacy_game(self): - return self.game == STARCRAFT2_WOL - - def event_invalid_game(self): - if self.is_legacy_game(): - self.game = STARCRAFT2 - super().event_invalid_game() - else: - self.game = STARCRAFT2_WOL - async_start(self.send_connect()) - - def on_package(self, cmd: str, args: dict) -> None: - if cmd == "Connected": - self.difficulty = args["slot_data"]["game_difficulty"] - self.game_speed = args["slot_data"].get("game_speed", GameSpeed.option_default) - self.disable_forced_camera = args["slot_data"].get("disable_forced_camera", DisableForcedCamera.default) - self.skip_cutscenes = args["slot_data"].get("skip_cutscenes", SkipCutscenes.default) - self.all_in_choice = args["slot_data"]["all_in_map"] - self.slot_data_version = args["slot_data"].get("version", 2) - slot_req_table: dict = args["slot_data"]["mission_req"] - - first_item = list(slot_req_table.keys())[0] - # Maintaining backwards compatibility with older slot data - if first_item in [str(campaign.id) for campaign in SC2Campaign]: - # Multi-campaign - self.mission_req_table = {} - for campaign_id in slot_req_table: - campaign = lookup_id_to_campaign[int(campaign_id)] - self.mission_req_table[campaign] = { - mission: self.parse_mission_info(mission_info) - for mission, mission_info in slot_req_table[campaign_id].items() - } - else: - # Old format - self.mission_req_table = {SC2Campaign.GLOBAL: { - mission: self.parse_mission_info(mission_info) - for mission, mission_info in slot_req_table.items() - } - } - - self.mission_order = args["slot_data"].get("mission_order", MissionOrder.option_vanilla) - self.final_mission = args["slot_data"].get("final_mission", SC2Mission.ALL_IN.id) - self.player_color_raynor = args["slot_data"].get("player_color_terran_raynor", ColorChoice.option_blue) - self.player_color_zerg = args["slot_data"].get("player_color_zerg", ColorChoice.option_orange) - self.player_color_zerg_primal = args["slot_data"].get("player_color_zerg_primal", ColorChoice.option_purple) - self.player_color_protoss = args["slot_data"].get("player_color_protoss", ColorChoice.option_blue) - self.player_color_nova = args["slot_data"].get("player_color_nova", ColorChoice.option_dark_grey) - self.generic_upgrade_missions = args["slot_data"].get("generic_upgrade_missions", GenericUpgradeMissions.default) - self.generic_upgrade_items = args["slot_data"].get("generic_upgrade_items", GenericUpgradeItems.option_individual_items) - self.generic_upgrade_research = args["slot_data"].get("generic_upgrade_research", GenericUpgradeResearch.option_vanilla) - self.kerrigan_presence = args["slot_data"].get("kerrigan_presence", KerriganPresence.option_vanilla) - self.kerrigan_primal_status = args["slot_data"].get("kerrigan_primal_status", KerriganPrimalStatus.option_vanilla) - self.kerrigan_levels_per_mission_completed = args["slot_data"].get("kerrigan_levels_per_mission_completed", 0) - self.kerrigan_levels_per_mission_completed_cap = args["slot_data"].get("kerrigan_levels_per_mission_completed_cap", -1) - self.kerrigan_total_level_cap = args["slot_data"].get("kerrigan_total_level_cap", -1) - self.grant_story_tech = args["slot_data"].get("grant_story_tech", GrantStoryTech.option_false) - self.grant_story_levels = args["slot_data"].get("grant_story_levels", GrantStoryLevels.option_additive) - self.required_tactics = args["slot_data"].get("required_tactics", RequiredTactics.option_standard) - self.take_over_ai_allies = args["slot_data"].get("take_over_ai_allies", TakeOverAIAllies.option_false) - self.spear_of_adun_presence = args["slot_data"].get("spear_of_adun_presence", SpearOfAdunPresence.option_not_present) - self.spear_of_adun_present_in_no_build = args["slot_data"].get("spear_of_adun_present_in_no_build", SpearOfAdunPresentInNoBuild.option_false) - self.spear_of_adun_autonomously_cast_ability_presence = args["slot_data"].get("spear_of_adun_autonomously_cast_ability_presence", SpearOfAdunAutonomouslyCastAbilityPresence.option_not_present) - self.spear_of_adun_autonomously_cast_present_in_no_build = args["slot_data"].get("spear_of_adun_autonomously_cast_present_in_no_build", SpearOfAdunAutonomouslyCastPresentInNoBuild.option_false) - self.minerals_per_item = args["slot_data"].get("minerals_per_item", 15) - self.vespene_per_item = args["slot_data"].get("vespene_per_item", 15) - self.starting_supply_per_item = args["slot_data"].get("starting_supply_per_item", 2) - self.nova_covert_ops_only = args["slot_data"].get("nova_covert_ops_only", False) - - if self.required_tactics == RequiredTactics.option_no_logic: - # Locking Grant Story Tech/Levels if no logic - self.grant_story_tech = GrantStoryTech.option_true - self.grant_story_levels = GrantStoryLevels.option_minimum - - self.location_inclusions = { - LocationType.VICTORY: LocationInclusion.option_enabled, # Victory checks are always enabled - LocationType.VANILLA: args["slot_data"].get("vanilla_locations", VanillaLocations.default), - LocationType.EXTRA: args["slot_data"].get("extra_locations", ExtraLocations.default), - LocationType.CHALLENGE: args["slot_data"].get("challenge_locations", ChallengeLocations.default), - LocationType.MASTERY: args["slot_data"].get("mastery_locations", MasteryLocations.default), - } - self.plando_locations = args["slot_data"].get("plando_locations", []) - - self.build_location_to_mission_mapping() - - # Looks for the required maps and mods for SC2. Runs check_game_install_path. - maps_present = is_mod_installed_correctly() - if os.path.exists(get_metadata_file()): - with open(get_metadata_file(), "r") as f: - current_ver = f.read() - sc2_logger.debug(f"Current version: {current_ver}") - if is_mod_update_available(DATA_REPO_OWNER, DATA_REPO_NAME, DATA_API_VERSION, current_ver): - sc2_logger.info("NOTICE: Update for required files found. Run /download_data to install.") - elif maps_present: - sc2_logger.warning("NOTICE: Your map files may be outdated (version number not found). " - "Run /download_data to update them.") - - @staticmethod - def parse_mission_info(mission_info: dict[str, typing.Any]) -> MissionInfo: - if mission_info.get("id") is not None: - mission_info["mission"] = lookup_id_to_mission[mission_info["id"]] - elif isinstance(mission_info["mission"], int): - mission_info["mission"] = lookup_id_to_mission[mission_info["mission"]] - - return MissionInfo( - **{field: value for field, value in mission_info.items() if field in MissionInfo._fields} - ) - - def find_campaign(self, mission_name: str) -> SC2Campaign: - data = self.mission_req_table - for campaign in data.keys(): - if mission_name in data[campaign].keys(): - return campaign - sc2_logger.info(f"Attempted to find campaign of unknown mission '{mission_name}'; defaulting to GLOBAL") - return SC2Campaign.GLOBAL - - - - def on_print_json(self, args: dict) -> None: - # goes to this world - if "receiving" in args and self.slot_concerns_self(args["receiving"]): - relevant = True - # found in this world - elif "item" in args and self.slot_concerns_self(args["item"].player): - relevant = True - # not related - else: - relevant = False - - if relevant: - self.announcements.put(self.raw_text_parser(copy.deepcopy(args["data"]))) - - super(SC2Context, self).on_print_json(args) - - def run_gui(self) -> None: - from .ClientGui import start_gui - start_gui(self) - - - async def shutdown(self) -> None: - await super(SC2Context, self).shutdown() - if self.last_bot: - self.last_bot.want_close = True - if self.sc2_run_task: - self.sc2_run_task.cancel() - - def play_mission(self, mission_id: int) -> bool: - if self.missions_unlocked or is_mission_available(self, mission_id): - if self.sc2_run_task: - if not self.sc2_run_task.done(): - sc2_logger.warning("Starcraft 2 Client is still running!") - self.sc2_run_task.cancel() # doesn't actually close the game, just stops the python task - if self.slot is None: - sc2_logger.warning("Launching Mission without Archipelago authentication, " - "checks will not be registered to server.") - self.sc2_run_task = asyncio.create_task(starcraft_launch(self, mission_id), - name="Starcraft 2 Launch") - return True - else: - sc2_logger.info( - f"{lookup_id_to_mission[mission_id].mission_name} is not currently unlocked. " - f"Use /unfinished or /available to see what is available.") - return False - - def build_location_to_mission_mapping(self) -> None: - mission_id_to_location_ids: typing.Dict[int, typing.Set[int]] = { - mission_info.mission.id: set() for campaign_mission in self.mission_req_table.values() for mission_info in campaign_mission.values() - } - - for loc in self.server_locations: - offset = SC2WOL_LOC_ID_OFFSET if loc < SC2HOTS_LOC_ID_OFFSET \ - else (SC2HOTS_LOC_ID_OFFSET - SC2Mission.ALL_IN.id * VICTORY_MODULO) - mission_id, objective = divmod(loc - offset, VICTORY_MODULO) - mission_id_to_location_ids[mission_id].add(objective) - self.mission_id_to_location_ids = {mission_id: sorted(objectives) for mission_id, objectives in - mission_id_to_location_ids.items()} - - def locations_for_mission(self, mission_name: str): - mission = lookup_name_to_mission[mission_name] - mission_id: int = mission.id - objectives = self.mission_id_to_location_ids[mission_id] - for objective in objectives: - yield get_location_offset(mission_id) + mission_id * VICTORY_MODULO + objective - - -class CompatItemHolder(typing.NamedTuple): - name: str - quantity: int = 1 - - -async def main(): - multiprocessing.freeze_support() - parser = get_base_parser() - parser.add_argument('--name', default=None, help="Slot Name to connect as.") - args = parser.parse_args() - - ctx = SC2Context(args.connect, args.password) - ctx.auth = args.name - if ctx.server_task is None: - ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop") - - if gui_enabled: - ctx.run_gui() - ctx.run_cli() - - await ctx.exit_event.wait() - - await ctx.shutdown() - -# These items must be given to the player if the game is generated on version 2 -API2_TO_API3_COMPAT_ITEMS: typing.Set[CompatItemHolder] = { - CompatItemHolder(ItemNames.PHOTON_CANNON), - CompatItemHolder(ItemNames.OBSERVER), - CompatItemHolder(ItemNames.WARP_HARMONIZATION), - CompatItemHolder(ItemNames.PROGRESSIVE_PROTOSS_GROUND_WEAPON, 3), - CompatItemHolder(ItemNames.PROGRESSIVE_PROTOSS_GROUND_ARMOR, 3), - CompatItemHolder(ItemNames.PROGRESSIVE_PROTOSS_SHIELDS, 3), - CompatItemHolder(ItemNames.PROGRESSIVE_PROTOSS_AIR_WEAPON, 3), - CompatItemHolder(ItemNames.PROGRESSIVE_PROTOSS_AIR_ARMOR, 3), - CompatItemHolder(ItemNames.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE, 3) -} - - -def compat_item_to_network_items(compat_item: CompatItemHolder) -> typing.List[NetworkItem]: - item_id = get_full_item_list()[compat_item.name].code - network_item = NetworkItem(item_id, 0, 0, 0) - return compat_item.quantity * [network_item] - - -def calculate_items(ctx: SC2Context) -> typing.Dict[SC2Race, typing.List[int]]: - items = ctx.items_received.copy() - # Items unlocked in API2 by default (Prophecy default items) - if ctx.slot_data_version < 3: - for compat_item in API2_TO_API3_COMPAT_ITEMS: - items.extend(compat_item_to_network_items(compat_item)) - - network_item: NetworkItem - accumulators: typing.Dict[SC2Race, typing.List[int]] = {race: [0 for _ in type_flaggroups[race]] for race in SC2Race} - - # Protoss Shield grouped item specific logic - shields_from_ground_upgrade: int = 0 - shields_from_air_upgrade: int = 0 - - item_list = get_full_item_list() - for network_item in items: - name: str = lookup_id_to_name[network_item.item] - item_data: ItemData = item_list[name] - - # exists exactly once - if item_data.quantity == 1: - accumulators[item_data.race][type_flaggroups[item_data.race][item_data.type]] |= 1 << item_data.number - - # exists multiple times - elif item_data.type in ["Upgrade", "Progressive Upgrade","Progressive Upgrade 2"]: - flaggroup = type_flaggroups[item_data.race][item_data.type] - - # Generic upgrades apply only to Weapon / Armor upgrades - if item_data.type != "Upgrade" or ctx.generic_upgrade_items == 0: - accumulators[item_data.race][flaggroup] += 1 << item_data.number - else: - if name == ItemNames.PROGRESSIVE_PROTOSS_GROUND_UPGRADE: - shields_from_ground_upgrade += 1 - if name == ItemNames.PROGRESSIVE_PROTOSS_AIR_UPGRADE: - shields_from_air_upgrade += 1 - for bundled_number in upgrade_numbers[item_data.number]: - accumulators[item_data.race][flaggroup] += 1 << bundled_number - - # Regen bio-steel nerf with API3 - undo for older games - if ctx.slot_data_version < 3 and name == ItemNames.PROGRESSIVE_REGENERATIVE_BIO_STEEL: - current_level = (accumulators[item_data.race][flaggroup] >> item_data.number) % 4 - if current_level == 2: - # Switch from level 2 to level 3 for compatibility - accumulators[item_data.race][flaggroup] += 1 << item_data.number - # sum - else: - if name == ItemNames.STARTING_MINERALS: - accumulators[item_data.race][type_flaggroups[item_data.race][item_data.type]] += ctx.minerals_per_item - elif name == ItemNames.STARTING_VESPENE: - accumulators[item_data.race][type_flaggroups[item_data.race][item_data.type]] += ctx.vespene_per_item - elif name == ItemNames.STARTING_SUPPLY: - accumulators[item_data.race][type_flaggroups[item_data.race][item_data.type]] += ctx.starting_supply_per_item - else: - accumulators[item_data.race][type_flaggroups[item_data.race][item_data.type]] += item_data.number - - # Fix Shields from generic upgrades by unit class (Maximum of ground/air upgrades) - if shields_from_ground_upgrade > 0 or shields_from_air_upgrade > 0: - shield_upgrade_level = max(shields_from_ground_upgrade, shields_from_air_upgrade) - shield_upgrade_item = item_list[ItemNames.PROGRESSIVE_PROTOSS_SHIELDS] - for _ in range(0, shield_upgrade_level): - accumulators[shield_upgrade_item.race][type_flaggroups[shield_upgrade_item.race][shield_upgrade_item.type]] += 1 << shield_upgrade_item.number - - # Kerrigan levels per check - accumulators[SC2Race.ZERG][type_flaggroups[SC2Race.ZERG]["Level"]] += (len(ctx.checked_locations) // ctx.checks_per_level) * ctx.levels_per_check - - # Upgrades from completed missions - if ctx.generic_upgrade_missions > 0: - total_missions = sum(len(ctx.mission_req_table[campaign]) for campaign in ctx.mission_req_table) - for race in SC2Race: - if "Upgrade" not in type_flaggroups[race]: - continue - upgrade_flaggroup = type_flaggroups[race]["Upgrade"] - num_missions = ctx.generic_upgrade_missions * total_missions - amounts = [ - num_missions // 100, - 2 * num_missions // 100, - 3 * num_missions // 100 - ] - upgrade_count = 0 - completed = len([id for id in ctx.mission_id_to_location_ids if get_location_offset(id) + VICTORY_MODULO * id in ctx.checked_locations]) - for amount in amounts: - if completed >= amount: - upgrade_count += 1 - # Equivalent to "Progressive Weapon/Armor Upgrade" item - for bundled_number in upgrade_numbers[upgrade_numbers_all[race]]: - accumulators[race][upgrade_flaggroup] += upgrade_count << bundled_number - - return accumulators - - -def calc_difficulty(difficulty: int): - if difficulty == 0: - return 'C' - elif difficulty == 1: - return 'N' - elif difficulty == 2: - return 'H' - elif difficulty == 3: - return 'B' - - return 'X' - - -def get_kerrigan_level(ctx: SC2Context, items: typing.Dict[SC2Race, typing.List[int]], missions_beaten: int) -> int: - item_value = items[SC2Race.ZERG][type_flaggroups[SC2Race.ZERG]["Level"]] - mission_value = missions_beaten * ctx.kerrigan_levels_per_mission_completed - if ctx.kerrigan_levels_per_mission_completed_cap != -1: - mission_value = min(mission_value, ctx.kerrigan_levels_per_mission_completed_cap) - total_value = item_value + mission_value - if ctx.kerrigan_total_level_cap != -1: - total_value = min(total_value, ctx.kerrigan_total_level_cap) - return total_value - - -def calculate_kerrigan_options(ctx: SC2Context) -> int: - options = 0 - - # Bits 0, 1 - # Kerrigan unit available - if ctx.kerrigan_presence in kerrigan_unit_available: - options |= 1 << 0 - - # Bit 2 - # Kerrigan primal status by map - if ctx.kerrigan_primal_status == KerriganPrimalStatus.option_vanilla: - options |= 1 << 2 - - return options - - -def caclulate_soa_options(ctx: SC2Context) -> int: - options = 0 - - # Bits 0, 1 - # SoA Calldowns available - soa_presence_value = 0 - if ctx.spear_of_adun_presence == SpearOfAdunPresence.option_not_present: - soa_presence_value = 0 - elif ctx.spear_of_adun_presence == SpearOfAdunPresence.option_lotv_protoss: - soa_presence_value = 1 - elif ctx.spear_of_adun_presence == SpearOfAdunPresence.option_protoss: - soa_presence_value = 2 - elif ctx.spear_of_adun_presence == SpearOfAdunPresence.option_everywhere: - soa_presence_value = 3 - options |= soa_presence_value << 0 - - # Bit 2 - # SoA Calldowns for no-builds - if ctx.spear_of_adun_present_in_no_build == SpearOfAdunPresentInNoBuild.option_true: - options |= 1 << 2 - - # Bits 3,4 - # Autocasts - soa_autocasts_presence_value = 0 - if ctx.spear_of_adun_autonomously_cast_ability_presence == SpearOfAdunAutonomouslyCastAbilityPresence.option_not_present: - soa_autocasts_presence_value = 0 - elif ctx.spear_of_adun_autonomously_cast_ability_presence == SpearOfAdunAutonomouslyCastAbilityPresence.option_lotv_protoss: - soa_autocasts_presence_value = 1 - elif ctx.spear_of_adun_autonomously_cast_ability_presence == SpearOfAdunAutonomouslyCastAbilityPresence.option_protoss: - soa_autocasts_presence_value = 2 - elif ctx.spear_of_adun_autonomously_cast_ability_presence == SpearOfAdunAutonomouslyCastAbilityPresence.option_everywhere: - soa_autocasts_presence_value = 3 - options |= soa_autocasts_presence_value << 3 - - # Bit 5 - # Autocasts in no-builds - if ctx.spear_of_adun_autonomously_cast_present_in_no_build == SpearOfAdunAutonomouslyCastPresentInNoBuild.option_true: - options |= 1 << 5 - - return options - -def kerrigan_primal(ctx: SC2Context, kerrigan_level: int) -> bool: - if ctx.kerrigan_primal_status == KerriganPrimalStatus.option_always_zerg: - return True - elif ctx.kerrigan_primal_status == KerriganPrimalStatus.option_always_human: - return False - elif ctx.kerrigan_primal_status == KerriganPrimalStatus.option_level_35: - return kerrigan_level >= 35 - elif ctx.kerrigan_primal_status == KerriganPrimalStatus.option_half_completion: - total_missions = len(ctx.mission_id_to_location_ids) - completed = sum((mission_id * VICTORY_MODULO + get_location_offset(mission_id)) in ctx.checked_locations - for mission_id in ctx.mission_id_to_location_ids) - return completed >= (total_missions / 2) - elif ctx.kerrigan_primal_status == KerriganPrimalStatus.option_item: - codes = [item.item for item in ctx.items_received] - return get_full_item_list()[ItemNames.KERRIGAN_PRIMAL_FORM].code in codes - return False - -async def starcraft_launch(ctx: SC2Context, mission_id: int): - sc2_logger.info(f"Launching {lookup_id_to_mission[mission_id].mission_name}. If game does not launch check log file for errors.") - - with DllDirectory(None): - run_game(bot.maps.get(lookup_id_to_mission[mission_id].map_file), [Bot(Race.Terran, ArchipelagoBot(ctx, mission_id), - name="Archipelago", fullscreen=True)], realtime=True) - - -class ArchipelagoBot(bot.bot_ai.BotAI): - __slots__ = [ - 'game_running', - 'mission_completed', - 'boni', - 'setup_done', - 'ctx', - 'mission_id', - 'want_close', - 'can_read_game', - 'last_received_update', - ] - - def __init__(self, ctx: SC2Context, mission_id: int): - self.game_running = False - self.mission_completed = False - self.want_close = False - self.can_read_game = False - self.last_received_update: int = 0 - self.setup_done = False - self.ctx = ctx - self.ctx.last_bot = self - self.mission_id = mission_id - self.boni = [False for _ in range(MAX_BONUS)] - - super(ArchipelagoBot, self).__init__() - - async def on_step(self, iteration: int): - if self.want_close: - self.want_close = False - await self._client.leave() - return - game_state = 0 - if not self.setup_done: - self.setup_done = True - start_items = calculate_items(self.ctx) - missions_beaten = self.missions_beaten_count() - kerrigan_level = get_kerrigan_level(self.ctx, start_items, missions_beaten) - kerrigan_options = calculate_kerrigan_options(self.ctx) - soa_options = caclulate_soa_options(self.ctx) - if self.ctx.difficulty_override >= 0: - difficulty = calc_difficulty(self.ctx.difficulty_override) - else: - difficulty = calc_difficulty(self.ctx.difficulty) - if self.ctx.game_speed_override >= 0: - game_speed = self.ctx.game_speed_override - else: - game_speed = self.ctx.game_speed - await self.chat_send("?SetOptions {} {} {} {} {} {} {} {} {} {} {} {} {}".format( - difficulty, - self.ctx.generic_upgrade_research, - self.ctx.all_in_choice, - game_speed, - self.ctx.disable_forced_camera, - self.ctx.skip_cutscenes, - kerrigan_options, - self.ctx.grant_story_tech, - self.ctx.take_over_ai_allies, - soa_options, - self.ctx.mission_order, - 1 if self.ctx.nova_covert_ops_only else 0, - self.ctx.grant_story_levels - )) - await self.chat_send("?GiveResources {} {} {}".format( - start_items[SC2Race.ANY][0], - start_items[SC2Race.ANY][1], - start_items[SC2Race.ANY][2] - )) - await self.updateTerranTech(start_items) - await self.updateZergTech(start_items, kerrigan_level) - await self.updateProtossTech(start_items) - await self.updateColors() - await self.chat_send("?LoadFinished") - self.last_received_update = len(self.ctx.items_received) - - else: - if self.ctx.pending_color_update: - await self.updateColors() - - if not self.ctx.announcements.empty(): - message = self.ctx.announcements.get(timeout=1) - await self.chat_send("?SendMessage " + message) - self.ctx.announcements.task_done() - - # Archipelago reads the health - controller1_state = 0 - controller2_state = 0 - for unit in self.all_own_units(): - if unit.health_max == CONTROLLER_HEALTH: - controller1_state = int(CONTROLLER_HEALTH - unit.health) - self.can_read_game = True - elif unit.health_max == CONTROLLER2_HEALTH: - controller2_state = int(CONTROLLER2_HEALTH - unit.health) - self.can_read_game = True - game_state = controller1_state + (controller2_state << 15) - - if iteration == 160 and not game_state & 1: - await self.chat_send("?SendMessage Warning: Archipelago unable to connect or has lost connection to " + - "Starcraft 2 (This is likely a map issue)") - - if self.last_received_update < len(self.ctx.items_received): - current_items = calculate_items(self.ctx) - missions_beaten = self.missions_beaten_count() - kerrigan_level = get_kerrigan_level(self.ctx, current_items, missions_beaten) - await self.updateTerranTech(current_items) - await self.updateZergTech(current_items, kerrigan_level) - await self.updateProtossTech(current_items) - self.last_received_update = len(self.ctx.items_received) - - if game_state & 1: - if not self.game_running: - print("Archipelago Connected") - self.game_running = True - - if self.can_read_game: - if game_state & (1 << 1) and not self.mission_completed: - if self.mission_id != self.ctx.final_mission: - print("Mission Completed") - await self.ctx.send_msgs( - [{"cmd": 'LocationChecks', - "locations": [get_location_offset(self.mission_id) + VICTORY_MODULO * self.mission_id]}]) - self.mission_completed = True - else: - print("Game Complete") - await self.ctx.send_msgs([{"cmd": 'StatusUpdate', "status": ClientStatus.CLIENT_GOAL}]) - self.mission_completed = True - - for x, completed in enumerate(self.boni): - if not completed and game_state & (1 << (x + 2)): - await self.ctx.send_msgs( - [{"cmd": 'LocationChecks', - "locations": [get_location_offset(self.mission_id) + VICTORY_MODULO * self.mission_id + x + 1]}]) - self.boni[x] = True - else: - await self.chat_send("?SendMessage LostConnection - Lost connection to game.") - - def missions_beaten_count(self): - return len([location for location in self.ctx.checked_locations if location % VICTORY_MODULO == 0]) - - async def updateColors(self): - await self.chat_send("?SetColor rr " + str(self.ctx.player_color_raynor)) - await self.chat_send("?SetColor ks " + str(self.ctx.player_color_zerg)) - await self.chat_send("?SetColor pz " + str(self.ctx.player_color_zerg_primal)) - await self.chat_send("?SetColor da " + str(self.ctx.player_color_protoss)) - await self.chat_send("?SetColor nova " + str(self.ctx.player_color_nova)) - self.ctx.pending_color_update = False - - async def updateTerranTech(self, current_items): - terran_items = current_items[SC2Race.TERRAN] - await self.chat_send("?GiveTerranTech {} {} {} {} {} {} {} {} {} {} {} {} {} {}".format( - terran_items[0], terran_items[1], terran_items[2], terran_items[3], terran_items[4], - terran_items[5], terran_items[6], terran_items[7], terran_items[8], terran_items[9], terran_items[10], - terran_items[11], terran_items[12], terran_items[13])) - - async def updateZergTech(self, current_items, kerrigan_level): - zerg_items = current_items[SC2Race.ZERG] - kerrigan_primal_by_items = kerrigan_primal(self.ctx, kerrigan_level) - kerrigan_primal_bot_value = 1 if kerrigan_primal_by_items else 0 - await self.chat_send("?GiveZergTech {} {} {} {} {} {} {} {} {} {} {} {}".format( - kerrigan_level, kerrigan_primal_bot_value, zerg_items[0], zerg_items[1], zerg_items[2], - zerg_items[3], zerg_items[4], zerg_items[5], zerg_items[6], zerg_items[9], zerg_items[10], zerg_items[11] - )) - - async def updateProtossTech(self, current_items): - protoss_items = current_items[SC2Race.PROTOSS] - await self.chat_send("?GiveProtossTech {} {} {} {} {} {} {} {} {} {}".format( - protoss_items[0], protoss_items[1], protoss_items[2], protoss_items[3], protoss_items[4], - protoss_items[5], protoss_items[6], protoss_items[7], protoss_items[8], protoss_items[9] - )) - - -def request_unfinished_missions(ctx: SC2Context) -> None: - if ctx.mission_req_table: - message = "Unfinished Missions: " - unlocks = initialize_blank_mission_dict(ctx.mission_req_table) - unfinished_locations: typing.Dict[SC2Mission, typing.List[str]] = {} - - _, unfinished_missions = calc_unfinished_missions(ctx, unlocks=unlocks) - - for mission in unfinished_missions: - objectives = set(ctx.locations_for_mission(mission)) - if objectives: - remaining_objectives = objectives.difference(ctx.checked_locations) - unfinished_locations[mission] = [ctx.location_names.lookup_in_game(location_id) for location_id in remaining_objectives] - else: - unfinished_locations[mission] = [] - - # Removing All-In from location pool - final_mission = lookup_id_to_mission[ctx.final_mission] - if final_mission in unfinished_missions.keys(): - message = f"Final Mission Available: {final_mission}[{ctx.final_mission}]\n" + message - if unfinished_missions[final_mission] == -1: - unfinished_missions.pop(final_mission) - - message += ", ".join(f"{mark_up_mission_name(ctx, mission, unlocks)}[{ctx.mission_req_table[ctx.find_campaign(mission)][mission].mission.id}] " + - mark_up_objectives( - f"[{len(unfinished_missions[mission])}/" - f"{sum(1 for _ in ctx.locations_for_mission(mission))}]", - ctx, unfinished_locations, mission) - for mission in unfinished_missions) - - if ctx.ui: - ctx.ui.log_panels['All'].on_message_markup(message) - ctx.ui.log_panels['Starcraft2'].on_message_markup(message) - else: - sc2_logger.info(message) - else: - sc2_logger.warning("No mission table found, you are likely not connected to a server.") - - -def calc_unfinished_missions(ctx: SC2Context, unlocks: typing.Optional[typing.Dict] = None): - unfinished_missions: typing.List[str] = [] - locations_completed: typing.List[typing.Union[typing.Set[int], typing.Literal[-1]]] = [] - - if not unlocks: - unlocks = initialize_blank_mission_dict(ctx.mission_req_table) - - available_missions = calc_available_missions(ctx, unlocks) - - for name in available_missions: - objectives = set(ctx.locations_for_mission(name)) - if objectives: - objectives_completed = ctx.checked_locations & objectives - if len(objectives_completed) < len(objectives): - unfinished_missions.append(name) - locations_completed.append(objectives_completed) - - else: # infer that this is the final mission as it has no objectives - unfinished_missions.append(name) - locations_completed.append(-1) - - return available_missions, dict(zip(unfinished_missions, locations_completed)) - - -def is_mission_available(ctx: SC2Context, mission_id_to_check: int) -> bool: - unfinished_missions = calc_available_missions(ctx) - - return any(mission_id_to_check == ctx.mission_req_table[ctx.find_campaign(mission)][mission].mission.id for mission in unfinished_missions) - - -def mark_up_mission_name(ctx: SC2Context, mission_name: str, unlock_table: typing.Dict) -> str: - """Checks if the mission is required for game completion and adds '*' to the name to mark that.""" - - campaign = ctx.find_campaign(mission_name) - mission_info = ctx.mission_req_table[campaign][mission_name] - if mission_info.completion_critical: - if ctx.ui: - message = "[color=AF99EF]" + mission_name + "[/color]" - else: - message = "*" + mission_name + "*" - else: - message = mission_name - - if ctx.ui: - campaign_missions = list(ctx.mission_req_table[campaign].keys()) - unlocks: typing.List[str] - index = campaign_missions.index(mission_name) - if index in unlock_table[campaign]: - unlocks = unlock_table[campaign][index] - else: - unlocks = [] - - if len(unlocks) > 0: - pre_message = f"[ref={mission_info.mission.id}|Unlocks: " - pre_message += ", ".join(f"{unlock}({ctx.mission_req_table[ctx.find_campaign(unlock)][unlock].mission.id})" for unlock in unlocks) - pre_message += f"]" - message = pre_message + message + "[/ref]" - - return message - - -def mark_up_objectives(message, ctx, unfinished_locations, mission): - formatted_message = message - - if ctx.ui: - locations = unfinished_locations[mission] - campaign = ctx.find_campaign(mission) - - pre_message = f"[ref={list(ctx.mission_req_table[campaign]).index(mission) + 30}|" - pre_message += "
    ".join(location for location in locations) - pre_message += f"]" - formatted_message = pre_message + message + "[/ref]" - - return formatted_message - - -def request_available_missions(ctx: SC2Context): - if ctx.mission_req_table: - message = "Available Missions: " - - # Initialize mission unlock table - unlocks = initialize_blank_mission_dict(ctx.mission_req_table) - - missions = calc_available_missions(ctx, unlocks) - message += \ - ", ".join(f"{mark_up_mission_name(ctx, mission, unlocks)}" - f"[{ctx.mission_req_table[ctx.find_campaign(mission)][mission].mission.id}]" - for mission in missions) - - if ctx.ui: - ctx.ui.log_panels['All'].on_message_markup(message) - ctx.ui.log_panels['Starcraft2'].on_message_markup(message) - else: - sc2_logger.info(message) - else: - sc2_logger.warning("No mission table found, you are likely not connected to a server.") - - -def calc_available_missions(ctx: SC2Context, unlocks: typing.Optional[dict] = None) -> typing.List[str]: - available_missions: typing.List[str] = [] - missions_complete = 0 - - # Get number of missions completed - for loc in ctx.checked_locations: - if loc % VICTORY_MODULO == 0: - missions_complete += 1 - - for campaign in ctx.mission_req_table: - # Go through the required missions for each mission and fill up unlock table used later for hover-over tooltips - for mission_name in ctx.mission_req_table[campaign]: - if unlocks: - for unlock in ctx.mission_req_table[campaign][mission_name].required_world: - parsed_unlock = parse_unlock(unlock) - # TODO prophecy-only wants to connect to WoL here - index = parsed_unlock.connect_to - 1 - unlock_mission = list(ctx.mission_req_table[parsed_unlock.campaign])[index] - unlock_campaign = ctx.find_campaign(unlock_mission) - if unlock_campaign in unlocks: - if index not in unlocks[unlock_campaign]: - unlocks[unlock_campaign][index] = list() - unlocks[unlock_campaign][index].append(mission_name) - - if mission_reqs_completed(ctx, mission_name, missions_complete): - available_missions.append(mission_name) - - return available_missions - - -def parse_unlock(unlock: typing.Union[typing.Dict[typing.Literal["connect_to", "campaign"], int], MissionConnection, int]) -> MissionConnection: - if isinstance(unlock, int): - # Legacy - return MissionConnection(unlock) - elif isinstance(unlock, MissionConnection): - return unlock - else: - # Multi-campaign - return MissionConnection(unlock["connect_to"], lookup_id_to_campaign[unlock["campaign"]]) - - -def mission_reqs_completed(ctx: SC2Context, mission_name: str, missions_complete: int) -> bool: - """Returns a bool signifying if the mission has all requirements complete and can be done - - Arguments: - ctx -- instance of SC2Context - locations_to_check -- the mission string name to check - missions_complete -- an int of how many missions have been completed - mission_path -- a list of missions that have already been checked - """ - campaign = ctx.find_campaign(mission_name) - - if len(ctx.mission_req_table[campaign][mission_name].required_world) >= 1: - # A check for when the requirements are being or'd - or_success = False - - # Loop through required missions - for req_mission in ctx.mission_req_table[campaign][mission_name].required_world: - req_success = True - parsed_req_mission = parse_unlock(req_mission) - - # Check if required mission has been completed - mission_id = ctx.mission_req_table[parsed_req_mission.campaign][ - list(ctx.mission_req_table[parsed_req_mission.campaign])[parsed_req_mission.connect_to - 1]].mission.id - if not (mission_id * VICTORY_MODULO + get_location_offset(mission_id)) in ctx.checked_locations: - if not ctx.mission_req_table[campaign][mission_name].or_requirements: - return False - else: - req_success = False - - # Grid-specific logic (to avoid long path checks and infinite recursion) - if ctx.mission_order in (MissionOrder.option_grid, MissionOrder.option_mini_grid, MissionOrder.option_medium_grid): - if req_success: - return True - else: - if parsed_req_mission == ctx.mission_req_table[campaign][mission_name].required_world[-1]: - return False - else: - continue - - # Recursively check required mission to see if it's requirements are met, in case !collect has been done - # Skipping recursive check on Grid settings to speed up checks and avoid infinite recursion - if not mission_reqs_completed(ctx, list(ctx.mission_req_table[parsed_req_mission.campaign])[parsed_req_mission.connect_to - 1], missions_complete): - if not ctx.mission_req_table[campaign][mission_name].or_requirements: - return False - else: - req_success = False - - # If requirement check succeeded mark or as satisfied - if ctx.mission_req_table[campaign][mission_name].or_requirements and req_success: - or_success = True - - if ctx.mission_req_table[campaign][mission_name].or_requirements: - # Return false if or requirements not met - if not or_success: - return False - - # Check number of missions - if missions_complete >= ctx.mission_req_table[campaign][mission_name].number: - return True - else: - return False - else: - return True - - -def initialize_blank_mission_dict(location_table: typing.Dict[SC2Campaign, typing.Dict[str, MissionInfo]]): - unlocks: typing.Dict[SC2Campaign, typing.Dict] = {} - - for mission in list(location_table): - unlocks[mission] = {} - - return unlocks - - -def check_game_install_path() -> bool: - # First thing: go to the default location for ExecuteInfo. - # An exception for Windows is included because it's very difficult to find ~\Documents if the user moved it. - if is_windows: - # The next five lines of utterly inscrutable code are brought to you by copy-paste from Stack Overflow. - # https://stackoverflow.com/questions/6227590/finding-the-users-my-documents-path/30924555# - import ctypes.wintypes - CSIDL_PERSONAL = 5 # My Documents - SHGFP_TYPE_CURRENT = 0 # Get current, not default value - - buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH) - ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf) - documentspath: str = buf.value - einfo = str(documentspath / Path("StarCraft II\\ExecuteInfo.txt")) - else: - einfo = str(bot.paths.get_home() / Path(bot.paths.USERPATH[bot.paths.PF])) - - # Check if the file exists. - if os.path.isfile(einfo): - - # Open the file and read it, picking out the latest executable's path. - with open(einfo) as f: - content = f.read() - if content: - search_result = re.search(r" = (.*)Versions", content) - if not search_result: - sc2_logger.warning(f"Found {einfo}, but it was empty. Run SC2 through the Blizzard launcher, " - "then try again.") - return False - base = search_result.group(1) - - if os.path.exists(base): - executable = bot.paths.latest_executeble(Path(base).expanduser() / "Versions") - - # Finally, check the path for an actual executable. - # If we find one, great. Set up the SC2PATH. - if os.path.isfile(executable): - sc2_logger.info(f"Found an SC2 install at {base}!") - sc2_logger.debug(f"Latest executable at {executable}.") - os.environ["SC2PATH"] = base - sc2_logger.debug(f"SC2PATH set to {base}.") - return True - else: - sc2_logger.warning(f"We may have found an SC2 install at {base}, but couldn't find {executable}.") - else: - sc2_logger.warning(f"{einfo} pointed to {base}, but we could not find an SC2 install there.") - else: - sc2_logger.warning(f"Couldn't find {einfo}. Run SC2 through the Blizzard launcher, then try again. " - f"If that fails, please run /set_path with your SC2 install directory.") - return False - - -def is_mod_installed_correctly() -> bool: - """Searches for all required files.""" - if "SC2PATH" not in os.environ: - check_game_install_path() - sc2_path: str = os.environ["SC2PATH"] - mapdir = sc2_path / Path('Maps/ArchipelagoCampaign') - mods = ["ArchipelagoCore", "ArchipelagoPlayer", "ArchipelagoPlayerSuper", "ArchipelagoPatches", - "ArchipelagoTriggers", "ArchipelagoPlayerWoL", "ArchipelagoPlayerHotS", - "ArchipelagoPlayerLotV", "ArchipelagoPlayerLotVPrologue", "ArchipelagoPlayerNCO"] - modfiles = [sc2_path / Path("Mods/" + mod + ".SC2Mod") for mod in mods] - wol_required_maps: typing.List[str] = ["WoL" + os.sep + mission.map_file + ".SC2Map" for mission in SC2Mission - if mission.campaign in (SC2Campaign.WOL, SC2Campaign.PROPHECY)] - hots_required_maps: typing.List[str] = ["HotS" + os.sep + mission.map_file + ".SC2Map" for mission in campaign_mission_table[SC2Campaign.HOTS]] - lotv_required_maps: typing.List[str] = ["LotV" + os.sep + mission.map_file + ".SC2Map" for mission in SC2Mission - if mission.campaign in (SC2Campaign.LOTV, SC2Campaign.PROLOGUE, SC2Campaign.EPILOGUE)] - nco_required_maps: typing.List[str] = ["NCO" + os.sep + mission.map_file + ".SC2Map" for mission in campaign_mission_table[SC2Campaign.NCO]] - required_maps = wol_required_maps + hots_required_maps + lotv_required_maps + nco_required_maps - needs_files = False - - # Check for maps. - missing_maps: typing.List[str] = [] - for mapfile in required_maps: - if not os.path.isfile(mapdir / mapfile): - missing_maps.append(mapfile) - if len(missing_maps) >= 19: - sc2_logger.warning(f"All map files missing from {mapdir}.") - needs_files = True - elif len(missing_maps) > 0: - for map in missing_maps: - sc2_logger.debug(f"Missing {map} from {mapdir}.") - sc2_logger.warning(f"Missing {len(missing_maps)} map files.") - needs_files = True - else: # Must be no maps missing - sc2_logger.info(f"All maps found in {mapdir}.") - - # Check for mods. - for modfile in modfiles: - if os.path.isfile(modfile) or os.path.isdir(modfile): - sc2_logger.info(f"Archipelago mod found at {modfile}.") - else: - sc2_logger.warning(f"Archipelago mod could not be found at {modfile}.") - needs_files = True - - # Final verdict. - if needs_files: - sc2_logger.warning(f"Required files are missing. Run /download_data to acquire them.") - return False - else: - sc2_logger.debug(f"All map/mod files are properly installed.") - return True - - -class DllDirectory: - # Credit to Black Sliver for this code. - # More info: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setdlldirectoryw - _old: typing.Optional[str] = None - _new: typing.Optional[str] = None - - def __init__(self, new: typing.Optional[str]): - self._new = new - - def __enter__(self): - old = self.get() - if self.set(self._new): - self._old = old - - def __exit__(self, *args): - if self._old is not None: - self.set(self._old) - - @staticmethod - def get() -> typing.Optional[str]: - if sys.platform == "win32": - n = ctypes.windll.kernel32.GetDllDirectoryW(0, None) - buf = ctypes.create_unicode_buffer(n) - ctypes.windll.kernel32.GetDllDirectoryW(n, buf) - return buf.value - # NOTE: other OS may support os.environ["LD_LIBRARY_PATH"], but this fix is windows-specific - return None - - @staticmethod - def set(s: typing.Optional[str]) -> bool: - if sys.platform == "win32": - return ctypes.windll.kernel32.SetDllDirectoryW(s) != 0 - # NOTE: other OS may support os.environ["LD_LIBRARY_PATH"], but this fix is windows-specific - return False - - -def download_latest_release_zip( - owner: str, - repo: str, - api_version: str, - metadata: typing.Optional[str] = None, - force_download=False -) -> typing.Tuple[str, typing.Optional[str]]: - """Downloads the latest release of a GitHub repo to the current directory as a .zip file.""" - import requests - - headers = {"Accept": 'application/vnd.github.v3+json'} - url = f"https://api.github.com/repos/{owner}/{repo}/releases/tags/{api_version}" - - r1 = requests.get(url, headers=headers) - if r1.status_code == 200: - latest_metadata = r1.json() - cleanup_downloaded_metadata(latest_metadata) - latest_metadata = str(latest_metadata) - # sc2_logger.info(f"Latest version: {latest_metadata}.") - else: - sc2_logger.warning(f"Status code: {r1.status_code}") - sc2_logger.warning(f"Failed to reach GitHub. Could not find download link.") - sc2_logger.warning(f"text: {r1.text}") - return "", metadata - - if (force_download is False) and (metadata == latest_metadata): - sc2_logger.info("Latest version already installed.") - return "", metadata - - sc2_logger.info(f"Attempting to download latest version of API version {api_version} of {repo}.") - download_url = r1.json()["assets"][0]["browser_download_url"] - - r2 = requests.get(download_url, headers=headers) - if r2.status_code == 200 and zipfile.is_zipfile(io.BytesIO(r2.content)): - tempdir = tempfile.gettempdir() - file = tempdir + os.sep + f"{repo}.zip" - with open(file, "wb") as fh: - fh.write(r2.content) - sc2_logger.info(f"Successfully downloaded {repo}.zip.") - return file, latest_metadata - else: - sc2_logger.warning(f"Status code: {r2.status_code}") - sc2_logger.warning("Download failed.") - sc2_logger.warning(f"text: {r2.text}") - return "", metadata - - -def cleanup_downloaded_metadata(medatada_json: dict) -> None: - for asset in medatada_json['assets']: - del asset['download_count'] - - -def is_mod_update_available(owner: str, repo: str, api_version: str, metadata: str) -> bool: - import requests - - headers = {"Accept": 'application/vnd.github.v3+json'} - url = f"https://api.github.com/repos/{owner}/{repo}/releases/tags/{api_version}" - - r1 = requests.get(url, headers=headers) - if r1.status_code == 200: - latest_metadata = r1.json() - cleanup_downloaded_metadata(latest_metadata) - latest_metadata = str(latest_metadata) - if metadata != latest_metadata: - return True - else: - return False - - else: - sc2_logger.warning(f"Failed to reach GitHub while checking for updates.") - sc2_logger.warning(f"Status code: {r1.status_code}") - sc2_logger.warning(f"text: {r1.text}") - return False - - -def get_location_offset(mission_id): - return SC2WOL_LOC_ID_OFFSET if mission_id <= SC2Mission.ALL_IN.id \ - else (SC2HOTS_LOC_ID_OFFSET - SC2Mission.ALL_IN.id * VICTORY_MODULO) - - -def launch(): - colorama.just_fix_windows_console() - asyncio.run(main()) - colorama.deinit() diff --git a/worlds/sc2/ClientGui.py b/worlds/sc2/ClientGui.py deleted file mode 100644 index d16acad83d9d..000000000000 --- a/worlds/sc2/ClientGui.py +++ /dev/null @@ -1,306 +0,0 @@ -from typing import * -import asyncio - -from NetUtils import JSONMessagePart -from kvui import GameManager, HoverBehavior, ServerToolTip, KivyJSONtoTextParser -from kivy.app import App -from kivy.clock import Clock -from kivy.uix.gridlayout import GridLayout -from kivy.lang import Builder -from kivy.uix.label import Label -from kivy.uix.button import Button -from kivymd.uix.tooltip import MDTooltip -from kivy.uix.scrollview import ScrollView -from kivy.properties import StringProperty - -from .Client import SC2Context, calc_unfinished_missions, parse_unlock -from .MissionTables import (lookup_id_to_mission, lookup_name_to_mission, campaign_race_exceptions, SC2Mission, SC2Race, - SC2Campaign) -from .Locations import LocationType, lookup_location_id_to_type -from .Options import LocationInclusion -from . import SC2World, get_first_mission - - -class HoverableButton(HoverBehavior, Button): - pass - - -class MissionButton(HoverableButton, MDTooltip): - tooltip_text = StringProperty("Test") - - def __init__(self, *args, **kwargs): - super(HoverableButton, self).__init__(**kwargs) - self._tooltip = ServerToolTip(text=self.text, markup=True) - self._tooltip.padding = [5, 2, 5, 2] - - def on_enter(self): - self._tooltip.text = self.tooltip_text - - if self.tooltip_text != "": - self.display_tooltip() - - def on_leave(self): - self.remove_tooltip() - - @property - def ctx(self) -> SC2Context: - return App.get_running_app().ctx - -class CampaignScroll(ScrollView): - pass - -class MultiCampaignLayout(GridLayout): - pass - -class CampaignLayout(GridLayout): - pass - -class MissionLayout(GridLayout): - pass - -class MissionCategory(GridLayout): - pass - - -class SC2JSONtoKivyParser(KivyJSONtoTextParser): - def _handle_text(self, node: JSONMessagePart): - if node.get("keep_markup", False): - for ref in node.get("refs", []): - node["text"] = f"[ref={self.ref_count}|{ref}]{node['text']}[/ref]" - self.ref_count += 1 - return super(KivyJSONtoTextParser, self)._handle_text(node) - else: - return super()._handle_text(node) - - -class SC2Manager(GameManager): - logging_pairs = [ - ("Client", "Archipelago"), - ("Starcraft2", "Starcraft2"), - ] - base_title = "Archipelago Starcraft 2 Client" - - campaign_panel: Optional[CampaignLayout] = None - last_checked_locations: Set[int] = set() - mission_id_to_button: Dict[int, MissionButton] = {} - launching: Union[bool, int] = False # if int -> mission ID - refresh_from_launching = True - first_check = True - first_mission = "" - ctx: SC2Context - - def __init__(self, ctx) -> None: - super().__init__(ctx) - self.json_to_kivy_parser = SC2JSONtoKivyParser(ctx) - - def clear_tooltip(self) -> None: - if self.ctx.current_tooltip: - App.get_running_app().root.remove_widget(self.ctx.current_tooltip) - - self.ctx.current_tooltip = None - - def build(self): - container = super().build() - - panel = self.add_client_tab("Starcraft 2 Launcher", CampaignScroll()) - self.campaign_panel = MultiCampaignLayout() - panel.content.add_widget(self.campaign_panel) - - Clock.schedule_interval(self.build_mission_table, 0.5) - - return container - - def build_mission_table(self, dt) -> None: - if (not self.launching and (not self.last_checked_locations == self.ctx.checked_locations or - not self.refresh_from_launching)) or self.first_check: - assert self.campaign_panel is not None - self.refresh_from_launching = True - - self.campaign_panel.clear_widgets() - if self.ctx.mission_req_table: - self.last_checked_locations = self.ctx.checked_locations.copy() - self.first_check = False - self.first_mission = get_first_mission(self.ctx.mission_req_table) - - self.mission_id_to_button = {} - - available_missions, unfinished_missions = calc_unfinished_missions(self.ctx) - - multi_campaign_layout_height = 0 - - for campaign, missions in sorted(self.ctx.mission_req_table.items(), key=lambda item: item[0].id): - categories: Dict[str, List[str]] = {} - - # separate missions into categories - for mission_index in missions: - mission_info = self.ctx.mission_req_table[campaign][mission_index] - if mission_info.category not in categories: - categories[mission_info.category] = [] - - categories[mission_info.category].append(mission_index) - - max_mission_count = max(len(categories[category]) for category in categories) - if max_mission_count == 1: - campaign_layout_height = 115 - else: - campaign_layout_height = (max_mission_count + 2) * 50 - multi_campaign_layout_height += campaign_layout_height - campaign_layout = CampaignLayout(size_hint_y=None, height=campaign_layout_height) - if campaign != SC2Campaign.GLOBAL: - campaign_layout.add_widget( - Label(text=campaign.campaign_name, size_hint_y=None, height=25, outline_width=1) - ) - mission_layout = MissionLayout() - - for category in categories: - category_name_height = 0 - category_spacing = 3 - if category.startswith('_'): - category_display_name = '' - else: - category_display_name = category - category_name_height += 25 - category_spacing = 10 - category_panel = MissionCategory(padding=[category_spacing,6,category_spacing,6]) - category_panel.add_widget( - Label(text=category_display_name, size_hint_y=None, height=category_name_height, outline_width=1)) - - for mission in categories[category]: - text: str = mission - tooltip: str = "" - mission_obj: SC2Mission = lookup_name_to_mission[mission] - mission_id: int = mission_obj.id - mission_data = self.ctx.mission_req_table[campaign][mission] - remaining_locations, plando_locations, remaining_count = self.sort_unfinished_locations(mission) - # Map has uncollected locations - if mission in unfinished_missions: - if self.any_valuable_locations(remaining_locations): - text = f"[color=6495ED]{text}[/color]" - else: - text = f"[color=A0BEF4]{text}[/color]" - elif mission in available_missions: - text = f"[color=FFFFFF]{text}[/color]" - # Map requirements not met - else: - text = f"[color=a9a9a9]{text}[/color]" - tooltip = f"Requires: " - if mission_data.required_world: - tooltip += ", ".join(list(self.ctx.mission_req_table[parse_unlock(req_mission).campaign])[parse_unlock(req_mission).connect_to - 1] for - req_mission in - mission_data.required_world) - - if mission_data.number: - tooltip += " and " - if mission_data.number: - tooltip += f"{self.ctx.mission_req_table[campaign][mission].number} missions completed" - - if mission_id == self.ctx.final_mission: - if mission in available_missions: - text = f"[color=FFBC95]{mission}[/color]" - else: - text = f"[color=D0C0BE]{mission}[/color]" - if tooltip: - tooltip += "\n" - tooltip += "Final Mission" - - if remaining_count > 0: - if tooltip: - tooltip += "\n\n" - tooltip += f"-- Uncollected locations --" - for loctype in LocationType: - if len(remaining_locations[loctype]) > 0: - if loctype == LocationType.VICTORY: - tooltip += f"\n- {remaining_locations[loctype][0]}" - else: - tooltip += f"\n{self.get_location_type_title(loctype)}:\n- " - tooltip += "\n- ".join(remaining_locations[loctype]) - if len(plando_locations) > 0: - tooltip += f"\nPlando:\n- " - tooltip += "\n- ".join(plando_locations) - - MISSION_BUTTON_HEIGHT = 50 - for pad in range(mission_data.ui_vertical_padding): - column_spacer = Label(text='', size_hint_y=None, height=MISSION_BUTTON_HEIGHT) - category_panel.add_widget(column_spacer) - mission_button = MissionButton(text=text, size_hint_y=None, height=MISSION_BUTTON_HEIGHT) - mission_race = mission_obj.race - if mission_race == SC2Race.ANY: - mission_race = mission_obj.campaign.race - race = campaign_race_exceptions.get(mission_obj, mission_race) - racial_colors = { - SC2Race.TERRAN: (0.24, 0.84, 0.68), - SC2Race.ZERG: (1, 0.65, 0.37), - SC2Race.PROTOSS: (0.55, 0.7, 1) - } - if race in racial_colors: - mission_button.background_color = racial_colors[race] - mission_button.tooltip_text = tooltip - mission_button.bind(on_press=self.mission_callback) - self.mission_id_to_button[mission_id] = mission_button - category_panel.add_widget(mission_button) - - category_panel.add_widget(Label(text="")) - mission_layout.add_widget(category_panel) - campaign_layout.add_widget(mission_layout) - self.campaign_panel.add_widget(campaign_layout) - self.campaign_panel.height = multi_campaign_layout_height - - elif self.launching: - assert self.campaign_panel is not None - self.refresh_from_launching = False - - self.campaign_panel.clear_widgets() - self.campaign_panel.add_widget(Label(text="Launching Mission: " + - lookup_id_to_mission[self.launching].mission_name)) - if self.ctx.ui: - self.ctx.ui.clear_tooltip() - - def mission_callback(self, button: MissionButton) -> None: - if not self.launching: - mission_id: int = next(k for k, v in self.mission_id_to_button.items() if v == button) - if self.ctx.play_mission(mission_id): - self.launching = mission_id - Clock.schedule_once(self.finish_launching, 10) - - def finish_launching(self, dt): - self.launching = False - - def sort_unfinished_locations(self, mission_name: str) -> Tuple[Dict[LocationType, List[str]], List[str], int]: - locations: Dict[LocationType, List[str]] = {loctype: [] for loctype in LocationType} - count = 0 - for loc in self.ctx.locations_for_mission(mission_name): - if loc in self.ctx.missing_locations: - count += 1 - locations[lookup_location_id_to_type[loc]].append(self.ctx.location_names.lookup_in_game(loc)) - - plando_locations = [] - for plando_loc in self.ctx.plando_locations: - for loctype in LocationType: - if plando_loc in locations[loctype]: - locations[loctype].remove(plando_loc) - plando_locations.append(plando_loc) - - return locations, plando_locations, count - - def any_valuable_locations(self, locations: Dict[LocationType, List[str]]) -> bool: - for loctype in LocationType: - if len(locations[loctype]) > 0 and self.ctx.location_inclusions[loctype] == LocationInclusion.option_enabled: - return True - return False - - def get_location_type_title(self, location_type: LocationType) -> str: - title = location_type.name.title().replace("_", " ") - if self.ctx.location_inclusions[location_type] == LocationInclusion.option_disabled: - title += " (Nothing)" - elif self.ctx.location_inclusions[location_type] == LocationInclusion.option_resources: - title += " (Resources)" - else: - title += "" - return title - -def start_gui(context: SC2Context): - context.ui = SC2Manager(context) - context.ui_task = asyncio.create_task(context.ui.async_run(), name="UI") - import pkgutil - data = pkgutil.get_data(SC2World.__module__, "Starcraft2.kv").decode() - Builder.load_string(data) diff --git a/worlds/sc2/ItemGroups.py b/worlds/sc2/ItemGroups.py deleted file mode 100644 index 3a3733044579..000000000000 --- a/worlds/sc2/ItemGroups.py +++ /dev/null @@ -1,100 +0,0 @@ -import typing -from . import Items, ItemNames -from .MissionTables import campaign_mission_table, SC2Campaign, SC2Mission - -""" -Item name groups, given to Archipelago and used in YAMLs and /received filtering. -For non-developers the following will be useful: -* Items with a bracket get groups named after the unbracketed part - * eg. "Advanced Healing AI (Medivac)" is accessible as "Advanced Healing AI" - * The exception to this are item names that would be ambiguous (eg. "Resource Efficiency") -* Item flaggroups get unique groups as well as combined groups for numbered flaggroups - * eg. "Unit" contains all units, "Armory" contains "Armory 1" through "Armory 6" - * The best place to look these up is at the bottom of Items.py -* Items that have a parent are grouped together - * eg. "Zergling Items" contains all items that have "Zergling" as a parent - * These groups do NOT contain the parent item - * This currently does not include items with multiple potential parents, like some LotV unit upgrades -* All items are grouped by their race ("Terran", "Protoss", "Zerg", "Any") -* Hand-crafted item groups can be found at the bottom of this file -""" - -item_name_groups: typing.Dict[str, typing.List[str]] = {} - -# Groups for use in world logic -item_name_groups["Missions"] = ["Beat " + mission.mission_name for mission in SC2Mission] -item_name_groups["WoL Missions"] = ["Beat " + mission.mission_name for mission in campaign_mission_table[SC2Campaign.WOL]] + \ - ["Beat " + mission.mission_name for mission in campaign_mission_table[SC2Campaign.PROPHECY]] - -# These item name groups should not show up in documentation -unlisted_item_name_groups = { - "Missions", "WoL Missions" -} - -# Some item names only differ in bracketed parts -# These items are ambiguous for short-hand name groups -bracketless_duplicates: typing.Set[str] -# This is a list of names in ItemNames with bracketed parts removed, for internal use -_shortened_names = [(name[:name.find(' (')] if '(' in name else name) - for name in [ItemNames.__dict__[name] for name in ItemNames.__dir__() if not name.startswith('_')]] -# Remove the first instance of every short-name from the full item list -bracketless_duplicates = set(_shortened_names) -for name in bracketless_duplicates: - _shortened_names.remove(name) -# The remaining short-names are the duplicates -bracketless_duplicates = set(_shortened_names) -del _shortened_names - -# All items get sorted into their data type -for item, data in Items.get_full_item_list().items(): - # Items get assigned to their flaggroup's type - item_name_groups.setdefault(data.type, []).append(item) - # Numbered flaggroups get sorted into an unnumbered group - # Currently supports numbers of one or two digits - if data.type[-2:].strip().isnumeric(): - type_group = data.type[:-2].strip() - item_name_groups.setdefault(type_group, []).append(item) - # Flaggroups with numbers are unlisted - unlisted_item_name_groups.add(data.type) - # Items with a bracket get a short-hand name group for ease of use in YAMLs - if '(' in item: - short_name = item[:item.find(' (')] - # Ambiguous short-names are dropped - if short_name not in bracketless_duplicates: - item_name_groups[short_name] = [item] - # Short-name groups are unlisted - unlisted_item_name_groups.add(short_name) - # Items with a parent get assigned to their parent's group - if data.parent_item: - # The parent groups need a special name, otherwise they are ambiguous with the parent - parent_group = f"{data.parent_item} Items" - item_name_groups.setdefault(parent_group, []).append(item) - # Parent groups are unlisted - unlisted_item_name_groups.add(parent_group) - # All items get assigned to their race's group - race_group = data.race.name.capitalize() - item_name_groups.setdefault(race_group, []).append(item) - - -# Hand-made groups -item_name_groups["Aiur"] = [ - ItemNames.ZEALOT, ItemNames.DRAGOON, ItemNames.SENTRY, ItemNames.AVENGER, ItemNames.HIGH_TEMPLAR, - ItemNames.IMMORTAL, ItemNames.REAVER, - ItemNames.PHOENIX, ItemNames.SCOUT, ItemNames.ARBITER, ItemNames.CARRIER, -] -item_name_groups["Nerazim"] = [ - ItemNames.CENTURION, ItemNames.STALKER, ItemNames.DARK_TEMPLAR, ItemNames.SIGNIFIER, ItemNames.DARK_ARCHON, - ItemNames.ANNIHILATOR, - ItemNames.CORSAIR, ItemNames.ORACLE, ItemNames.VOID_RAY, -] -item_name_groups["Tal'Darim"] = [ - ItemNames.SUPPLICANT, ItemNames.SLAYER, ItemNames.HAVOC, ItemNames.BLOOD_HUNTER, ItemNames.ASCENDANT, - ItemNames.VANGUARD, ItemNames.WRATHWALKER, - ItemNames.DESTROYER, ItemNames.MOTHERSHIP, - ItemNames.WARP_PRISM_PHASE_BLASTER, -] -item_name_groups["Purifier"] = [ - ItemNames.SENTINEL, ItemNames.ADEPT, ItemNames.INSTIGATOR, ItemNames.ENERGIZER, - ItemNames.COLOSSUS, ItemNames.DISRUPTOR, - ItemNames.MIRAGE, ItemNames.TEMPEST, -] \ No newline at end of file diff --git a/worlds/sc2/ItemNames.py b/worlds/sc2/ItemNames.py deleted file mode 100644 index 10c713910311..000000000000 --- a/worlds/sc2/ItemNames.py +++ /dev/null @@ -1,661 +0,0 @@ -""" -A complete collection of Starcraft 2 item names as strings. -Users of this data may make some assumptions about the structure of a name: -* The upgrade for a unit will end with the unit's name in parentheses -* Weapon / armor upgrades may be grouped by a common prefix specified within this file -""" - -# Terran Units -MARINE = "Marine" -MEDIC = "Medic" -FIREBAT = "Firebat" -MARAUDER = "Marauder" -REAPER = "Reaper" -HELLION = "Hellion" -VULTURE = "Vulture" -GOLIATH = "Goliath" -DIAMONDBACK = "Diamondback" -SIEGE_TANK = "Siege Tank" -MEDIVAC = "Medivac" -WRAITH = "Wraith" -VIKING = "Viking" -BANSHEE = "Banshee" -BATTLECRUISER = "Battlecruiser" -GHOST = "Ghost" -SPECTRE = "Spectre" -THOR = "Thor" -RAVEN = "Raven" -SCIENCE_VESSEL = "Science Vessel" -PREDATOR = "Predator" -HERCULES = "Hercules" -# Extended units -LIBERATOR = "Liberator" -VALKYRIE = "Valkyrie" -WIDOW_MINE = "Widow Mine" -CYCLONE = "Cyclone" -HERC = "HERC" -WARHOUND = "Warhound" - -# Terran Buildings -BUNKER = "Bunker" -MISSILE_TURRET = "Missile Turret" -SENSOR_TOWER = "Sensor Tower" -PLANETARY_FORTRESS = "Planetary Fortress" -PERDITION_TURRET = "Perdition Turret" -HIVE_MIND_EMULATOR = "Hive Mind Emulator" -PSI_DISRUPTER = "Psi Disrupter" - -# Terran Weapon / Armor Upgrades -TERRAN_UPGRADE_PREFIX = "Progressive Terran" -TERRAN_INFANTRY_UPGRADE_PREFIX = f"{TERRAN_UPGRADE_PREFIX} Infantry" -TERRAN_VEHICLE_UPGRADE_PREFIX = f"{TERRAN_UPGRADE_PREFIX} Vehicle" -TERRAN_SHIP_UPGRADE_PREFIX = f"{TERRAN_UPGRADE_PREFIX} Ship" - -PROGRESSIVE_TERRAN_INFANTRY_WEAPON = f"{TERRAN_INFANTRY_UPGRADE_PREFIX} Weapon" -PROGRESSIVE_TERRAN_INFANTRY_ARMOR = f"{TERRAN_INFANTRY_UPGRADE_PREFIX} Armor" -PROGRESSIVE_TERRAN_VEHICLE_WEAPON = f"{TERRAN_VEHICLE_UPGRADE_PREFIX} Weapon" -PROGRESSIVE_TERRAN_VEHICLE_ARMOR = f"{TERRAN_VEHICLE_UPGRADE_PREFIX} Armor" -PROGRESSIVE_TERRAN_SHIP_WEAPON = f"{TERRAN_SHIP_UPGRADE_PREFIX} Weapon" -PROGRESSIVE_TERRAN_SHIP_ARMOR = f"{TERRAN_SHIP_UPGRADE_PREFIX} Armor" -PROGRESSIVE_TERRAN_WEAPON_UPGRADE = f"{TERRAN_UPGRADE_PREFIX} Weapon Upgrade" -PROGRESSIVE_TERRAN_ARMOR_UPGRADE = f"{TERRAN_UPGRADE_PREFIX} Armor Upgrade" -PROGRESSIVE_TERRAN_INFANTRY_UPGRADE = f"{TERRAN_INFANTRY_UPGRADE_PREFIX} Upgrade" -PROGRESSIVE_TERRAN_VEHICLE_UPGRADE = f"{TERRAN_VEHICLE_UPGRADE_PREFIX} Upgrade" -PROGRESSIVE_TERRAN_SHIP_UPGRADE = f"{TERRAN_SHIP_UPGRADE_PREFIX} Upgrade" -PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE = f"{TERRAN_UPGRADE_PREFIX} Weapon/Armor Upgrade" - -# Mercenaries -WAR_PIGS = "War Pigs" -DEVIL_DOGS = "Devil Dogs" -HAMMER_SECURITIES = "Hammer Securities" -SPARTAN_COMPANY = "Spartan Company" -SIEGE_BREAKERS = "Siege Breakers" -HELS_ANGELS = "Hel's Angels" -DUSK_WINGS = "Dusk Wings" -JACKSONS_REVENGE = "Jackson's Revenge" -SKIBIS_ANGELS = "Skibi's Angels" -DEATH_HEADS = "Death Heads" -WINGED_NIGHTMARES = "Winged Nightmares" -MIDNIGHT_RIDERS = "Midnight Riders" -BRYNHILDS = "Brynhilds" -JOTUN = "Jotun" - -# Lab / Global -ULTRA_CAPACITORS = "Ultra-Capacitors" -VANADIUM_PLATING = "Vanadium Plating" -ORBITAL_DEPOTS = "Orbital Depots" -MICRO_FILTERING = "Micro-Filtering" -AUTOMATED_REFINERY = "Automated Refinery" -COMMAND_CENTER_REACTOR = "Command Center Reactor" -TECH_REACTOR = "Tech Reactor" -ORBITAL_STRIKE = "Orbital Strike" -CELLULAR_REACTOR = "Cellular Reactor" -PROGRESSIVE_REGENERATIVE_BIO_STEEL = "Progressive Regenerative Bio-Steel" -PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM = "Progressive Fire-Suppression System" -PROGRESSIVE_ORBITAL_COMMAND = "Progressive Orbital Command" -STRUCTURE_ARMOR = "Structure Armor" -HI_SEC_AUTO_TRACKING = "Hi-Sec Auto Tracking" -ADVANCED_OPTICS = "Advanced Optics" -ROGUE_FORCES = "Rogue Forces" - -# Terran Unit Upgrades -BANSHEE_HYPERFLIGHT_ROTORS = "Hyperflight Rotors (Banshee)" -BANSHEE_INTERNAL_TECH_MODULE = "Internal Tech Module (Banshee)" -BANSHEE_LASER_TARGETING_SYSTEM = "Laser Targeting System (Banshee)" -BANSHEE_PROGRESSIVE_CROSS_SPECTRUM_DAMPENERS = "Progressive Cross-Spectrum Dampeners (Banshee)" -BANSHEE_SHOCKWAVE_MISSILE_BATTERY = "Shockwave Missile Battery (Banshee)" -BANSHEE_SHAPED_HULL = "Shaped Hull (Banshee)" -BANSHEE_ADVANCED_TARGETING_OPTICS = "Advanced Targeting Optics (Banshee)" -BANSHEE_DISTORTION_BLASTERS = "Distortion Blasters (Banshee)" -BANSHEE_ROCKET_BARRAGE = "Rocket Barrage (Banshee)" -BATTLECRUISER_ATX_LASER_BATTERY = "ATX Laser Battery (Battlecruiser)" -BATTLECRUISER_CLOAK = "Cloak (Battlecruiser)" -BATTLECRUISER_PROGRESSIVE_DEFENSIVE_MATRIX = "Progressive Defensive Matrix (Battlecruiser)" -BATTLECRUISER_INTERNAL_TECH_MODULE = "Internal Tech Module (Battlecruiser)" -BATTLECRUISER_PROGRESSIVE_MISSILE_PODS = "Progressive Missile Pods (Battlecruiser)" -BATTLECRUISER_OPTIMIZED_LOGISTICS = "Optimized Logistics (Battlecruiser)" -BATTLECRUISER_TACTICAL_JUMP = "Tactical Jump (Battlecruiser)" -BATTLECRUISER_BEHEMOTH_PLATING = "Behemoth Plating (Battlecruiser)" -BATTLECRUISER_COVERT_OPS_ENGINES = "Covert Ops Engines (Battlecruiser)" -BUNKER_NEOSTEEL_BUNKER = "Neosteel Bunker (Bunker)" -BUNKER_PROJECTILE_ACCELERATOR = "Projectile Accelerator (Bunker)" -BUNKER_SHRIKE_TURRET = "Shrike Turret (Bunker)" -BUNKER_FORTIFIED_BUNKER = "Fortified Bunker (Bunker)" -CYCLONE_MAG_FIELD_ACCELERATORS = "Mag-Field Accelerators (Cyclone)" -CYCLONE_MAG_FIELD_LAUNCHERS = "Mag-Field Launchers (Cyclone)" -CYCLONE_RAPID_FIRE_LAUNCHERS = "Rapid Fire Launchers (Cyclone)" -CYCLONE_TARGETING_OPTICS = "Targeting Optics (Cyclone)" -CYCLONE_RESOURCE_EFFICIENCY = "Resource Efficiency (Cyclone)" -CYCLONE_INTERNAL_TECH_MODULE = "Internal Tech Module (Cyclone)" -DIAMONDBACK_BURST_CAPACITORS = "Burst Capacitors (Diamondback)" -DIAMONDBACK_HYPERFLUXOR = "Hyperfluxor (Diamondback)" -DIAMONDBACK_RESOURCE_EFFICIENCY = "Resource Efficiency (Diamondback)" -DIAMONDBACK_SHAPED_HULL = "Shaped Hull (Diamondback)" -DIAMONDBACK_PROGRESSIVE_TRI_LITHIUM_POWER_CELL = "Progressive Tri-Lithium Power Cell (Diamondback)" -DIAMONDBACK_ION_THRUSTERS = "Ion Thrusters (Diamondback)" -FIREBAT_INCINERATOR_GAUNTLETS = "Incinerator Gauntlets (Firebat)" -FIREBAT_JUGGERNAUT_PLATING = "Juggernaut Plating (Firebat)" -FIREBAT_RESOURCE_EFFICIENCY = "Resource Efficiency (Firebat)" -FIREBAT_PROGRESSIVE_STIMPACK = "Progressive Stimpack (Firebat)" -FIREBAT_INFERNAL_PRE_IGNITER = "Infernal Pre-Igniter (Firebat)" -FIREBAT_KINETIC_FOAM = "Kinetic Foam (Firebat)" -FIREBAT_NANO_PROJECTORS = "Nano Projectors (Firebat)" -GHOST_CRIUS_SUIT = "Crius Suit (Ghost)" -GHOST_EMP_ROUNDS = "EMP Rounds (Ghost)" -GHOST_LOCKDOWN = "Lockdown (Ghost)" -GHOST_OCULAR_IMPLANTS = "Ocular Implants (Ghost)" -GHOST_RESOURCE_EFFICIENCY = "Resource Efficiency (Ghost)" -GOLIATH_ARES_CLASS_TARGETING_SYSTEM = "Ares-Class Targeting System (Goliath)" -GOLIATH_JUMP_JETS = "Jump Jets (Goliath)" -GOLIATH_MULTI_LOCK_WEAPONS_SYSTEM = "Multi-Lock Weapons System (Goliath)" -GOLIATH_OPTIMIZED_LOGISTICS = "Optimized Logistics (Goliath)" -GOLIATH_SHAPED_HULL = "Shaped Hull (Goliath)" -GOLIATH_RESOURCE_EFFICIENCY = "Resource Efficiency (Goliath)" -GOLIATH_INTERNAL_TECH_MODULE = "Internal Tech Module (Goliath)" -HELLION_HELLBAT_ASPECT = "Hellbat Aspect (Hellion)" -HELLION_JUMP_JETS = "Jump Jets (Hellion)" -HELLION_OPTIMIZED_LOGISTICS = "Optimized Logistics (Hellion)" -HELLION_PROGRESSIVE_STIMPACK = "Progressive Stimpack (Hellion)" -HELLION_SMART_SERVOS = "Smart Servos (Hellion)" -HELLION_THERMITE_FILAMENTS = "Thermite Filaments (Hellion)" -HELLION_TWIN_LINKED_FLAMETHROWER = "Twin-Linked Flamethrower (Hellion)" -HELLION_INFERNAL_PLATING = "Infernal Plating (Hellion)" -HERC_JUGGERNAUT_PLATING = "Juggernaut Plating (HERC)" -HERC_KINETIC_FOAM = "Kinetic Foam (HERC)" -HERC_RESOURCE_EFFICIENCY = "Resource Efficiency (HERC)" -HERCULES_INTERNAL_FUSION_MODULE = "Internal Fusion Module (Hercules)" -HERCULES_TACTICAL_JUMP = "Tactical Jump (Hercules)" -LIBERATOR_ADVANCED_BALLISTICS = "Advanced Ballistics (Liberator)" -LIBERATOR_CLOAK = "Cloak (Liberator)" -LIBERATOR_LASER_TARGETING_SYSTEM = "Laser Targeting System (Liberator)" -LIBERATOR_OPTIMIZED_LOGISTICS = "Optimized Logistics (Liberator)" -LIBERATOR_RAID_ARTILLERY = "Raid Artillery (Liberator)" -LIBERATOR_SMART_SERVOS = "Smart Servos (Liberator)" -LIBERATOR_RESOURCE_EFFICIENCY = "Resource Efficiency (Liberator)" -MARAUDER_CONCUSSIVE_SHELLS = "Concussive Shells (Marauder)" -MARAUDER_INTERNAL_TECH_MODULE = "Internal Tech Module (Marauder)" -MARAUDER_KINETIC_FOAM = "Kinetic Foam (Marauder)" -MARAUDER_LASER_TARGETING_SYSTEM = "Laser Targeting System (Marauder)" -MARAUDER_MAGRAIL_MUNITIONS = "Magrail Munitions (Marauder)" -MARAUDER_PROGRESSIVE_STIMPACK = "Progressive Stimpack (Marauder)" -MARAUDER_JUGGERNAUT_PLATING = "Juggernaut Plating (Marauder)" -MARINE_COMBAT_SHIELD = "Combat Shield (Marine)" -MARINE_LASER_TARGETING_SYSTEM = "Laser Targeting System (Marine)" -MARINE_MAGRAIL_MUNITIONS = "Magrail Munitions (Marine)" -MARINE_OPTIMIZED_LOGISTICS = "Optimized Logistics (Marine)" -MARINE_PROGRESSIVE_STIMPACK = "Progressive Stimpack (Marine)" -MEDIC_ADVANCED_MEDIC_FACILITIES = "Advanced Medic Facilities (Medic)" -MEDIC_OPTICAL_FLARE = "Optical Flare (Medic)" -MEDIC_RESOURCE_EFFICIENCY = "Resource Efficiency (Medic)" -MEDIC_RESTORATION = "Restoration (Medic)" -MEDIC_STABILIZER_MEDPACKS = "Stabilizer Medpacks (Medic)" -MEDIC_ADAPTIVE_MEDPACKS = "Adaptive Medpacks (Medic)" -MEDIC_NANO_PROJECTOR = "Nano Projector (Medic)" -MEDIVAC_ADVANCED_HEALING_AI = "Advanced Healing AI (Medivac)" -MEDIVAC_AFTERBURNERS = "Afterburners (Medivac)" -MEDIVAC_EXPANDED_HULL = "Expanded Hull (Medivac)" -MEDIVAC_RAPID_DEPLOYMENT_TUBE = "Rapid Deployment Tube (Medivac)" -MEDIVAC_SCATTER_VEIL = "Scatter Veil (Medivac)" -MEDIVAC_ADVANCED_CLOAKING_FIELD = "Advanced Cloaking Field (Medivac)" -MISSILE_TURRET_HELLSTORM_BATTERIES = "Hellstorm Batteries (Missile Turret)" -MISSILE_TURRET_TITANIUM_HOUSING = "Titanium Housing (Missile Turret)" -PLANETARY_FORTRESS_PROGRESSIVE_AUGMENTED_THRUSTERS = "Progressive Augmented Thrusters (Planetary Fortress)" -PLANETARY_FORTRESS_ADVANCED_TARGETING = "Advanced Targeting (Planetary Fortress)" -PREDATOR_RESOURCE_EFFICIENCY = "Resource Efficiency (Predator)" -PREDATOR_CLOAK = "Cloak (Predator)" -PREDATOR_CHARGE = "Charge (Predator)" -PREDATOR_PREDATOR_S_FURY = "Predator's Fury (Predator)" -RAVEN_ANTI_ARMOR_MISSILE = "Anti-Armor Missile (Raven)" -RAVEN_BIO_MECHANICAL_REPAIR_DRONE = "Bio Mechanical Repair Drone (Raven)" -RAVEN_HUNTER_SEEKER_WEAPON = "Hunter-Seeker Weapon (Raven)" -RAVEN_INTERFERENCE_MATRIX = "Interference Matrix (Raven)" -RAVEN_INTERNAL_TECH_MODULE = "Internal Tech Module (Raven)" -RAVEN_RAILGUN_TURRET = "Railgun Turret (Raven)" -RAVEN_SPIDER_MINES = "Spider Mines (Raven)" -RAVEN_RESOURCE_EFFICIENCY = "Resource Efficiency (Raven)" -RAVEN_DURABLE_MATERIALS = "Durable Materials (Raven)" -REAPER_ADVANCED_CLOAKING_FIELD = "Advanced Cloaking Field (Reaper)" -REAPER_COMBAT_DRUGS = "Combat Drugs (Reaper)" -REAPER_G4_CLUSTERBOMB = "G-4 Clusterbomb (Reaper)" -REAPER_LASER_TARGETING_SYSTEM = "Laser Targeting System (Reaper)" -REAPER_PROGRESSIVE_STIMPACK = "Progressive Stimpack (Reaper)" -REAPER_SPIDER_MINES = "Spider Mines (Reaper)" -REAPER_U238_ROUNDS = "U-238 Rounds (Reaper)" -REAPER_JET_PACK_OVERDRIVE = "Jet Pack Overdrive (Reaper)" -SCIENCE_VESSEL_DEFENSIVE_MATRIX = "Defensive Matrix (Science Vessel)" -SCIENCE_VESSEL_EMP_SHOCKWAVE = "EMP Shockwave (Science Vessel)" -SCIENCE_VESSEL_IMPROVED_NANO_REPAIR = "Improved Nano-Repair (Science Vessel)" -SCIENCE_VESSEL_ADVANCED_AI_SYSTEMS = "Advanced AI Systems (Science Vessel)" -SCV_ADVANCED_CONSTRUCTION = "Advanced Construction (SCV)" -SCV_DUAL_FUSION_WELDERS = "Dual-Fusion Welders (SCV)" -SCV_HOSTILE_ENVIRONMENT_ADAPTATION = "Hostile Environment Adaptation (SCV)" -SIEGE_TANK_ADVANCED_SIEGE_TECH = "Advanced Siege Tech (Siege Tank)" -SIEGE_TANK_GRADUATING_RANGE = "Graduating Range (Siege Tank)" -SIEGE_TANK_INTERNAL_TECH_MODULE = "Internal Tech Module (Siege Tank)" -SIEGE_TANK_JUMP_JETS = "Jump Jets (Siege Tank)" -SIEGE_TANK_LASER_TARGETING_SYSTEM = "Laser Targeting System (Siege Tank)" -SIEGE_TANK_MAELSTROM_ROUNDS = "Maelstrom Rounds (Siege Tank)" -SIEGE_TANK_SHAPED_BLAST = "Shaped Blast (Siege Tank)" -SIEGE_TANK_SMART_SERVOS = "Smart Servos (Siege Tank)" -SIEGE_TANK_SPIDER_MINES = "Spider Mines (Siege Tank)" -SIEGE_TANK_SHAPED_HULL = "Shaped Hull (Siege Tank)" -SIEGE_TANK_RESOURCE_EFFICIENCY = "Resource Efficiency (Siege Tank)" -SPECTRE_IMPALER_ROUNDS = "Impaler Rounds (Spectre)" -SPECTRE_NYX_CLASS_CLOAKING_MODULE = "Nyx-Class Cloaking Module (Spectre)" -SPECTRE_PSIONIC_LASH = "Psionic Lash (Spectre)" -SPECTRE_RESOURCE_EFFICIENCY = "Resource Efficiency (Spectre)" -SPIDER_MINE_CERBERUS_MINE = "Cerberus Mine (Spider Mine)" -SPIDER_MINE_HIGH_EXPLOSIVE_MUNITION = "High Explosive Munition (Spider Mine)" -THOR_330MM_BARRAGE_CANNON = "330mm Barrage Cannon (Thor)" -THOR_PROGRESSIVE_IMMORTALITY_PROTOCOL = "Progressive Immortality Protocol (Thor)" -THOR_PROGRESSIVE_HIGH_IMPACT_PAYLOAD = "Progressive High Impact Payload (Thor)" -THOR_BUTTON_WITH_A_SKULL_ON_IT = "Button With a Skull on It (Thor)" -THOR_LASER_TARGETING_SYSTEM = "Laser Targeting System (Thor)" -THOR_LARGE_SCALE_FIELD_CONSTRUCTION = "Large Scale Field Construction (Thor)" -VALKYRIE_AFTERBURNERS = "Afterburners (Valkyrie)" -VALKYRIE_FLECHETTE_MISSILES = "Flechette Missiles (Valkyrie)" -VALKYRIE_ENHANCED_CLUSTER_LAUNCHERS = "Enhanced Cluster Launchers (Valkyrie)" -VALKYRIE_SHAPED_HULL = "Shaped Hull (Valkyrie)" -VALKYRIE_LAUNCHING_VECTOR_COMPENSATOR = "Launching Vector Compensator (Valkyrie)" -VALKYRIE_RESOURCE_EFFICIENCY = "Resource Efficiency (Valkyrie)" -VIKING_ANTI_MECHANICAL_MUNITION = "Anti-Mechanical Munition (Viking)" -VIKING_PHOBOS_CLASS_WEAPONS_SYSTEM = "Phobos-Class Weapons System (Viking)" -VIKING_RIPWAVE_MISSILES = "Ripwave Missiles (Viking)" -VIKING_SMART_SERVOS = "Smart Servos (Viking)" -VIKING_SHREDDER_ROUNDS = "Shredder Rounds (Viking)" -VIKING_WILD_MISSILES = "W.I.L.D. Missiles (Viking)" -VULTURE_AUTO_LAUNCHERS = "Auto Launchers (Vulture)" -VULTURE_ION_THRUSTERS = "Ion Thrusters (Vulture)" -VULTURE_PROGRESSIVE_REPLENISHABLE_MAGAZINE = "Progressive Replenishable Magazine (Vulture)" -VULTURE_AUTO_REPAIR = "Auto-Repair (Vulture)" -WARHOUND_RESOURCE_EFFICIENCY = "Resource Efficiency (Warhound)" -WARHOUND_REINFORCED_PLATING = "Reinforced Plating (Warhound)" -WIDOW_MINE_BLACK_MARKET_LAUNCHERS = "Black Market Launchers (Widow Mine)" -WIDOW_MINE_CONCEALMENT = "Concealment (Widow Mine)" -WIDOW_MINE_DRILLING_CLAWS = "Drilling Claws (Widow Mine)" -WIDOW_MINE_EXECUTIONER_MISSILES = "Executioner Missiles (Widow Mine)" -WRAITH_ADVANCED_LASER_TECHNOLOGY = "Advanced Laser Technology (Wraith)" -WRAITH_DISPLACEMENT_FIELD = "Displacement Field (Wraith)" -WRAITH_PROGRESSIVE_TOMAHAWK_POWER_CELLS = "Progressive Tomahawk Power Cells (Wraith)" -WRAITH_TRIGGER_OVERRIDE = "Trigger Override (Wraith)" -WRAITH_INTERNAL_TECH_MODULE = "Internal Tech Module (Wraith)" -WRAITH_RESOURCE_EFFICIENCY = "Resource Efficiency (Wraith)" - -# Nova -NOVA_GHOST_VISOR = "Ghost Visor (Nova Equipment)" -NOVA_RANGEFINDER_OCULUS = "Rangefinder Oculus (Nova Equipment)" -NOVA_DOMINATION = "Domination (Nova Ability)" -NOVA_BLINK = "Blink (Nova Ability)" -NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE = "Progressive Stealth Suit Module (Nova Suit Module)" -NOVA_ENERGY_SUIT_MODULE = "Energy Suit Module (Nova Suit Module)" -NOVA_ARMORED_SUIT_MODULE = "Armored Suit Module (Nova Suit Module)" -NOVA_JUMP_SUIT_MODULE = "Jump Suit Module (Nova Suit Module)" -NOVA_C20A_CANISTER_RIFLE = "C20A Canister Rifle (Nova Weapon)" -NOVA_HELLFIRE_SHOTGUN = "Hellfire Shotgun (Nova Weapon)" -NOVA_PLASMA_RIFLE = "Plasma Rifle (Nova Weapon)" -NOVA_MONOMOLECULAR_BLADE = "Monomolecular Blade (Nova Weapon)" -NOVA_BLAZEFIRE_GUNBLADE = "Blazefire Gunblade (Nova Weapon)" -NOVA_STIM_INFUSION = "Stim Infusion (Nova Gadget)" -NOVA_PULSE_GRENADES = "Pulse Grenades (Nova Gadget)" -NOVA_FLASHBANG_GRENADES = "Flashbang Grenades (Nova Gadget)" -NOVA_IONIC_FORCE_FIELD = "Ionic Force Field (Nova Gadget)" -NOVA_HOLO_DECOY = "Holo Decoy (Nova Gadget)" -NOVA_NUKE = "Tac Nuke Strike (Nova Ability)" - -# Zerg Units -ZERGLING = "Zergling" -SWARM_QUEEN = "Swarm Queen" -ROACH = "Roach" -HYDRALISK = "Hydralisk" -ABERRATION = "Aberration" -MUTALISK = "Mutalisk" -SWARM_HOST = "Swarm Host" -INFESTOR = "Infestor" -ULTRALISK = "Ultralisk" -CORRUPTOR = "Corruptor" -SCOURGE = "Scourge" -BROOD_QUEEN = "Brood Queen" -DEFILER = "Defiler" - -# Zerg Buildings -SPORE_CRAWLER = "Spore Crawler" -SPINE_CRAWLER = "Spine Crawler" - -# Zerg Weapon / Armor Upgrades -ZERG_UPGRADE_PREFIX = "Progressive Zerg" -ZERG_FLYER_UPGRADE_PREFIX = f"{ZERG_UPGRADE_PREFIX} Flyer" - -PROGRESSIVE_ZERG_MELEE_ATTACK = f"{ZERG_UPGRADE_PREFIX} Melee Attack" -PROGRESSIVE_ZERG_MISSILE_ATTACK = f"{ZERG_UPGRADE_PREFIX} Missile Attack" -PROGRESSIVE_ZERG_GROUND_CARAPACE = f"{ZERG_UPGRADE_PREFIX} Ground Carapace" -PROGRESSIVE_ZERG_FLYER_ATTACK = f"{ZERG_FLYER_UPGRADE_PREFIX} Attack" -PROGRESSIVE_ZERG_FLYER_CARAPACE = f"{ZERG_FLYER_UPGRADE_PREFIX} Carapace" -PROGRESSIVE_ZERG_WEAPON_UPGRADE = f"{ZERG_UPGRADE_PREFIX} Weapon Upgrade" -PROGRESSIVE_ZERG_ARMOR_UPGRADE = f"{ZERG_UPGRADE_PREFIX} Armor Upgrade" -PROGRESSIVE_ZERG_GROUND_UPGRADE = f"{ZERG_UPGRADE_PREFIX} Ground Upgrade" -PROGRESSIVE_ZERG_FLYER_UPGRADE = f"{ZERG_FLYER_UPGRADE_PREFIX} Upgrade" -PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE = f"{ZERG_UPGRADE_PREFIX} Weapon/Armor Upgrade" - -# Zerg Unit Upgrades -ZERGLING_HARDENED_CARAPACE = "Hardened Carapace (Zergling)" -ZERGLING_ADRENAL_OVERLOAD = "Adrenal Overload (Zergling)" -ZERGLING_METABOLIC_BOOST = "Metabolic Boost (Zergling)" -ZERGLING_SHREDDING_CLAWS = "Shredding Claws (Zergling)" -ROACH_HYDRIODIC_BILE = "Hydriodic Bile (Roach)" -ROACH_ADAPTIVE_PLATING = "Adaptive Plating (Roach)" -ROACH_TUNNELING_CLAWS = "Tunneling Claws (Roach)" -ROACH_GLIAL_RECONSTITUTION = "Glial Reconstitution (Roach)" -ROACH_ORGANIC_CARAPACE = "Organic Carapace (Roach)" -HYDRALISK_FRENZY = "Frenzy (Hydralisk)" -HYDRALISK_ANCILLARY_CARAPACE = "Ancillary Carapace (Hydralisk)" -HYDRALISK_GROOVED_SPINES = "Grooved Spines (Hydralisk)" -HYDRALISK_MUSCULAR_AUGMENTS = "Muscular Augments (Hydralisk)" -HYDRALISK_RESOURCE_EFFICIENCY = "Resource Efficiency (Hydralisk)" -BANELING_CORROSIVE_ACID = "Corrosive Acid (Baneling)" -BANELING_RUPTURE = "Rupture (Baneling)" -BANELING_REGENERATIVE_ACID = "Regenerative Acid (Baneling)" -BANELING_CENTRIFUGAL_HOOKS = "Centrifugal Hooks (Baneling)" -BANELING_TUNNELING_JAWS = "Tunneling Jaws (Baneling)" -BANELING_RAPID_METAMORPH = "Rapid Metamorph (Baneling)" -MUTALISK_VICIOUS_GLAIVE = "Vicious Glaive (Mutalisk)" -MUTALISK_RAPID_REGENERATION = "Rapid Regeneration (Mutalisk)" -MUTALISK_SUNDERING_GLAIVE = "Sundering Glaive (Mutalisk)" -MUTALISK_SEVERING_GLAIVE = "Severing Glaive (Mutalisk)" -MUTALISK_AERODYNAMIC_GLAIVE_SHAPE = "Aerodynamic Glaive Shape (Mutalisk)" -SWARM_HOST_BURROW = "Burrow (Swarm Host)" -SWARM_HOST_RAPID_INCUBATION = "Rapid Incubation (Swarm Host)" -SWARM_HOST_PRESSURIZED_GLANDS = "Pressurized Glands (Swarm Host)" -SWARM_HOST_LOCUST_METABOLIC_BOOST = "Locust Metabolic Boost (Swarm Host)" -SWARM_HOST_ENDURING_LOCUSTS = "Enduring Locusts (Swarm Host)" -SWARM_HOST_ORGANIC_CARAPACE = "Organic Carapace (Swarm Host)" -SWARM_HOST_RESOURCE_EFFICIENCY = "Resource Efficiency (Swarm Host)" -ULTRALISK_BURROW_CHARGE = "Burrow Charge (Ultralisk)" -ULTRALISK_TISSUE_ASSIMILATION = "Tissue Assimilation (Ultralisk)" -ULTRALISK_MONARCH_BLADES = "Monarch Blades (Ultralisk)" -ULTRALISK_ANABOLIC_SYNTHESIS = "Anabolic Synthesis (Ultralisk)" -ULTRALISK_CHITINOUS_PLATING = "Chitinous Plating (Ultralisk)" -ULTRALISK_ORGANIC_CARAPACE = "Organic Carapace (Ultralisk)" -ULTRALISK_RESOURCE_EFFICIENCY = "Resource Efficiency (Ultralisk)" -CORRUPTOR_CORRUPTION = "Corruption (Corruptor)" -CORRUPTOR_CAUSTIC_SPRAY = "Caustic Spray (Corruptor)" -SCOURGE_VIRULENT_SPORES = "Virulent Spores (Scourge)" -SCOURGE_RESOURCE_EFFICIENCY = "Resource Efficiency (Scourge)" -SCOURGE_SWARM_SCOURGE = "Swarm Scourge (Scourge)" -DEVOURER_CORROSIVE_SPRAY = "Corrosive Spray (Devourer)" -DEVOURER_GAPING_MAW = "Gaping Maw (Devourer)" -DEVOURER_IMPROVED_OSMOSIS = "Improved Osmosis (Devourer)" -DEVOURER_PRESCIENT_SPORES = "Prescient Spores (Devourer)" -GUARDIAN_PROLONGED_DISPERSION = "Prolonged Dispersion (Guardian)" -GUARDIAN_PRIMAL_ADAPTATION = "Primal Adaptation (Guardian)" -GUARDIAN_SORONAN_ACID = "Soronan Acid (Guardian)" -IMPALER_ADAPTIVE_TALONS = "Adaptive Talons (Impaler)" -IMPALER_SECRETION_GLANDS = "Secretion Glands (Impaler)" -IMPALER_HARDENED_TENTACLE_SPINES = "Hardened Tentacle Spines (Impaler)" -LURKER_SEISMIC_SPINES = "Seismic Spines (Lurker)" -LURKER_ADAPTED_SPINES = "Adapted Spines (Lurker)" -RAVAGER_POTENT_BILE = "Potent Bile (Ravager)" -RAVAGER_BLOATED_BILE_DUCTS = "Bloated Bile Ducts (Ravager)" -RAVAGER_DEEP_TUNNEL = "Deep Tunnel (Ravager)" -VIPER_PARASITIC_BOMB = "Parasitic Bomb (Viper)" -VIPER_PARALYTIC_BARBS = "Paralytic Barbs (Viper)" -VIPER_VIRULENT_MICROBES = "Virulent Microbes (Viper)" -BROOD_LORD_POROUS_CARTILAGE = "Porous Cartilage (Brood Lord)" -BROOD_LORD_EVOLVED_CARAPACE = "Evolved Carapace (Brood Lord)" -BROOD_LORD_SPLITTER_MITOSIS = "Splitter Mitosis (Brood Lord)" -BROOD_LORD_RESOURCE_EFFICIENCY = "Resource Efficiency (Brood Lord)" -INFESTOR_INFESTED_TERRAN = "Infested Terran (Infestor)" -INFESTOR_MICROBIAL_SHROUD = "Microbial Shroud (Infestor)" -SWARM_QUEEN_SPAWN_LARVAE = "Spawn Larvae (Swarm Queen)" -SWARM_QUEEN_DEEP_TUNNEL = "Deep Tunnel (Swarm Queen)" -SWARM_QUEEN_ORGANIC_CARAPACE = "Organic Carapace (Swarm Queen)" -SWARM_QUEEN_BIO_MECHANICAL_TRANSFUSION = "Bio-Mechanical Transfusion (Swarm Queen)" -SWARM_QUEEN_RESOURCE_EFFICIENCY = "Resource Efficiency (Swarm Queen)" -SWARM_QUEEN_INCUBATOR_CHAMBER = "Incubator Chamber (Swarm Queen)" -BROOD_QUEEN_FUNGAL_GROWTH = "Fungal Growth (Brood Queen)" -BROOD_QUEEN_ENSNARE = "Ensnare (Brood Queen)" -BROOD_QUEEN_ENHANCED_MITOCHONDRIA = "Enhanced Mitochondria (Brood Queen)" - -# Zerg Strains -ZERGLING_RAPTOR_STRAIN = "Raptor Strain (Zergling)" -ZERGLING_SWARMLING_STRAIN = "Swarmling Strain (Zergling)" -ROACH_VILE_STRAIN = "Vile Strain (Roach)" -ROACH_CORPSER_STRAIN = "Corpser Strain (Roach)" -BANELING_SPLITTER_STRAIN = "Splitter Strain (Baneling)" -BANELING_HUNTER_STRAIN = "Hunter Strain (Baneling)" -SWARM_HOST_CARRION_STRAIN = "Carrion Strain (Swarm Host)" -SWARM_HOST_CREEPER_STRAIN = "Creeper Strain (Swarm Host)" -ULTRALISK_NOXIOUS_STRAIN = "Noxious Strain (Ultralisk)" -ULTRALISK_TORRASQUE_STRAIN = "Torrasque Strain (Ultralisk)" - -# Morphs -ZERGLING_BANELING_ASPECT = "Baneling Aspect (Zergling)" -HYDRALISK_IMPALER_ASPECT = "Impaler Aspect (Hydralisk)" -HYDRALISK_LURKER_ASPECT = "Lurker Aspect (Hydralisk)" -MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT = "Brood Lord Aspect (Mutalisk/Corruptor)" -MUTALISK_CORRUPTOR_VIPER_ASPECT = "Viper Aspect (Mutalisk/Corruptor)" -MUTALISK_CORRUPTOR_GUARDIAN_ASPECT = "Guardian Aspect (Mutalisk/Corruptor)" -MUTALISK_CORRUPTOR_DEVOURER_ASPECT = "Devourer Aspect (Mutalisk/Corruptor)" -ROACH_RAVAGER_ASPECT = "Ravager Aspect (Roach)" - -# Zerg Mercs -INFESTED_MEDICS = "Infested Medics" -INFESTED_SIEGE_TANKS = "Infested Siege Tanks" -INFESTED_BANSHEES = "Infested Banshees" - -# Kerrigan Upgrades -KERRIGAN_KINETIC_BLAST = "Kinetic Blast (Kerrigan Tier 1)" -KERRIGAN_HEROIC_FORTITUDE = "Heroic Fortitude (Kerrigan Tier 1)" -KERRIGAN_LEAPING_STRIKE = "Leaping Strike (Kerrigan Tier 1)" -KERRIGAN_CRUSHING_GRIP = "Crushing Grip (Kerrigan Tier 2)" -KERRIGAN_CHAIN_REACTION = "Chain Reaction (Kerrigan Tier 2)" -KERRIGAN_PSIONIC_SHIFT = "Psionic Shift (Kerrigan Tier 2)" -KERRIGAN_WILD_MUTATION = "Wild Mutation (Kerrigan Tier 4)" -KERRIGAN_SPAWN_BANELINGS = "Spawn Banelings (Kerrigan Tier 4)" -KERRIGAN_MEND = "Mend (Kerrigan Tier 4)" -KERRIGAN_INFEST_BROODLINGS = "Infest Broodlings (Kerrigan Tier 6)" -KERRIGAN_FURY = "Fury (Kerrigan Tier 6)" -KERRIGAN_ABILITY_EFFICIENCY = "Ability Efficiency (Kerrigan Tier 6)" -KERRIGAN_APOCALYPSE = "Apocalypse (Kerrigan Tier 7)" -KERRIGAN_SPAWN_LEVIATHAN = "Spawn Leviathan (Kerrigan Tier 7)" -KERRIGAN_DROP_PODS = "Drop-Pods (Kerrigan Tier 7)" -KERRIGAN_PRIMAL_FORM = "Primal Form (Kerrigan)" - -# Misc Upgrades -KERRIGAN_ZERGLING_RECONSTITUTION = "Zergling Reconstitution (Kerrigan Tier 3)" -KERRIGAN_IMPROVED_OVERLORDS = "Improved Overlords (Kerrigan Tier 3)" -KERRIGAN_AUTOMATED_EXTRACTORS = "Automated Extractors (Kerrigan Tier 3)" -KERRIGAN_TWIN_DRONES = "Twin Drones (Kerrigan Tier 5)" -KERRIGAN_MALIGNANT_CREEP = "Malignant Creep (Kerrigan Tier 5)" -KERRIGAN_VESPENE_EFFICIENCY = "Vespene Efficiency (Kerrigan Tier 5)" -OVERLORD_VENTRAL_SACS = "Ventral Sacs (Overlord)" - -# Kerrigan Levels -KERRIGAN_LEVELS_1 = "1 Kerrigan Level" -KERRIGAN_LEVELS_2 = "2 Kerrigan Levels" -KERRIGAN_LEVELS_3 = "3 Kerrigan Levels" -KERRIGAN_LEVELS_4 = "4 Kerrigan Levels" -KERRIGAN_LEVELS_5 = "5 Kerrigan Levels" -KERRIGAN_LEVELS_6 = "6 Kerrigan Levels" -KERRIGAN_LEVELS_7 = "7 Kerrigan Levels" -KERRIGAN_LEVELS_8 = "8 Kerrigan Levels" -KERRIGAN_LEVELS_9 = "9 Kerrigan Levels" -KERRIGAN_LEVELS_10 = "10 Kerrigan Levels" -KERRIGAN_LEVELS_14 = "14 Kerrigan Levels" -KERRIGAN_LEVELS_35 = "35 Kerrigan Levels" -KERRIGAN_LEVELS_70 = "70 Kerrigan Levels" - -# Protoss Units -ZEALOT = "Zealot" -STALKER = "Stalker" -HIGH_TEMPLAR = "High Templar" -DARK_TEMPLAR = "Dark Templar" -IMMORTAL = "Immortal" -COLOSSUS = "Colossus" -PHOENIX = "Phoenix" -VOID_RAY = "Void Ray" -CARRIER = "Carrier" -OBSERVER = "Observer" -CENTURION = "Centurion" -SENTINEL = "Sentinel" -SUPPLICANT = "Supplicant" -INSTIGATOR = "Instigator" -SLAYER = "Slayer" -SENTRY = "Sentry" -ENERGIZER = "Energizer" -HAVOC = "Havoc" -SIGNIFIER = "Signifier" -ASCENDANT = "Ascendant" -AVENGER = "Avenger" -BLOOD_HUNTER = "Blood Hunter" -DRAGOON = "Dragoon" -DARK_ARCHON = "Dark Archon" -ADEPT = "Adept" -WARP_PRISM = "Warp Prism" -ANNIHILATOR = "Annihilator" -VANGUARD = "Vanguard" -WRATHWALKER = "Wrathwalker" -REAVER = "Reaver" -DISRUPTOR = "Disruptor" -MIRAGE = "Mirage" -CORSAIR = "Corsair" -DESTROYER = "Destroyer" -SCOUT = "Scout" -TEMPEST = "Tempest" -MOTHERSHIP = "Mothership" -ARBITER = "Arbiter" -ORACLE = "Oracle" - -# Upgrades -PROTOSS_UPGRADE_PREFIX = "Progressive Protoss" -PROTOSS_GROUND_UPGRADE_PREFIX = f"{PROTOSS_UPGRADE_PREFIX} Ground" -PROTOSS_AIR_UPGRADE_PREFIX = f"{PROTOSS_UPGRADE_PREFIX} Air" -PROGRESSIVE_PROTOSS_GROUND_WEAPON = f"{PROTOSS_GROUND_UPGRADE_PREFIX} Weapon" -PROGRESSIVE_PROTOSS_GROUND_ARMOR = f"{PROTOSS_GROUND_UPGRADE_PREFIX} Armor" -PROGRESSIVE_PROTOSS_SHIELDS = f"{PROTOSS_UPGRADE_PREFIX} Shields" -PROGRESSIVE_PROTOSS_AIR_WEAPON = f"{PROTOSS_AIR_UPGRADE_PREFIX} Weapon" -PROGRESSIVE_PROTOSS_AIR_ARMOR = f"{PROTOSS_AIR_UPGRADE_PREFIX} Armor" -PROGRESSIVE_PROTOSS_WEAPON_UPGRADE = f"{PROTOSS_UPGRADE_PREFIX} Weapon Upgrade" -PROGRESSIVE_PROTOSS_ARMOR_UPGRADE = f"{PROTOSS_UPGRADE_PREFIX} Armor Upgrade" -PROGRESSIVE_PROTOSS_GROUND_UPGRADE = f"{PROTOSS_GROUND_UPGRADE_PREFIX} Upgrade" -PROGRESSIVE_PROTOSS_AIR_UPGRADE = f"{PROTOSS_AIR_UPGRADE_PREFIX} Upgrade" -PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE = f"{PROTOSS_UPGRADE_PREFIX} Weapon/Armor Upgrade" - -# Buildings -PHOTON_CANNON = "Photon Cannon" -KHAYDARIN_MONOLITH = "Khaydarin Monolith" -SHIELD_BATTERY = "Shield Battery" - -# Unit Upgrades -SUPPLICANT_BLOOD_SHIELD = "Blood Shield (Supplicant)" -SUPPLICANT_SOUL_AUGMENTATION = "Soul Augmentation (Supplicant)" -SUPPLICANT_SHIELD_REGENERATION = "Shield Regeneration (Supplicant)" -ADEPT_SHOCKWAVE = "Shockwave (Adept)" -ADEPT_RESONATING_GLAIVES = "Resonating Glaives (Adept)" -ADEPT_PHASE_BULWARK = "Phase Bulwark (Adept)" -STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES = "Disintegrating Particles (Stalker/Instigator/Slayer)" -STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION = "Particle Reflection (Stalker/Instigator/Slayer)" -DRAGOON_HIGH_IMPACT_PHASE_DISRUPTORS = "High Impact Phase Disruptor (Dragoon)" -DRAGOON_TRILLIC_COMPRESSION_SYSTEM = "Trillic Compression System (Dragoon)" -DRAGOON_SINGULARITY_CHARGE = "Singularity Charge (Dragoon)" -DRAGOON_ENHANCED_STRIDER_SERVOS = "Enhanced Strider Servos (Dragoon)" -SCOUT_COMBAT_SENSOR_ARRAY = "Combat Sensor Array (Scout)" -SCOUT_APIAL_SENSORS = "Apial Sensors (Scout)" -SCOUT_GRAVITIC_THRUSTERS = "Gravitic Thrusters (Scout)" -SCOUT_ADVANCED_PHOTON_BLASTERS = "Advanced Photon Blasters (Scout)" -TEMPEST_TECTONIC_DESTABILIZERS = "Tectonic Destabilizers (Tempest)" -TEMPEST_QUANTIC_REACTOR = "Quantic Reactor (Tempest)" -TEMPEST_GRAVITY_SLING = "Gravity Sling (Tempest)" -PHOENIX_MIRAGE_IONIC_WAVELENGTH_FLUX = "Ionic Wavelength Flux (Phoenix/Mirage)" -PHOENIX_MIRAGE_ANION_PULSE_CRYSTALS = "Anion Pulse-Crystals (Phoenix/Mirage)" -CORSAIR_STEALTH_DRIVE = "Stealth Drive (Corsair)" -CORSAIR_ARGUS_JEWEL = "Argus Jewel (Corsair)" -CORSAIR_SUSTAINING_DISRUPTION = "Sustaining Disruption (Corsair)" -CORSAIR_NEUTRON_SHIELDS = "Neutron Shields (Corsair)" -ORACLE_STEALTH_DRIVE = "Stealth Drive (Oracle)" -ORACLE_STASIS_CALIBRATION = "Stasis Calibration (Oracle)" -ORACLE_TEMPORAL_ACCELERATION_BEAM = "Temporal Acceleration Beam (Oracle)" -ARBITER_CHRONOSTATIC_REINFORCEMENT = "Chronostatic Reinforcement (Arbiter)" -ARBITER_KHAYDARIN_CORE = "Khaydarin Core (Arbiter)" -ARBITER_SPACETIME_ANCHOR = "Spacetime Anchor (Arbiter)" -ARBITER_RESOURCE_EFFICIENCY = "Resource Efficiency (Arbiter)" -ARBITER_ENHANCED_CLOAK_FIELD = "Enhanced Cloak Field (Arbiter)" -CARRIER_GRAVITON_CATAPULT = "Graviton Catapult (Carrier)" -CARRIER_HULL_OF_PAST_GLORIES = "Hull of Past Glories (Carrier)" -VOID_RAY_DESTROYER_FLUX_VANES = "Flux Vanes (Void Ray/Destroyer)" -DESTROYER_REFORGED_BLOODSHARD_CORE = "Reforged Bloodshard Core (Destroyer)" -WARP_PRISM_GRAVITIC_DRIVE = "Gravitic Drive (Warp Prism)" -WARP_PRISM_PHASE_BLASTER = "Phase Blaster (Warp Prism)" -WARP_PRISM_WAR_CONFIGURATION = "War Configuration (Warp Prism)" -OBSERVER_GRAVITIC_BOOSTERS = "Gravitic Boosters (Observer)" -OBSERVER_SENSOR_ARRAY = "Sensor Array (Observer)" -REAVER_SCARAB_DAMAGE = "Scarab Damage (Reaver)" -REAVER_SOLARITE_PAYLOAD = "Solarite Payload (Reaver)" -REAVER_REAVER_CAPACITY = "Reaver Capacity (Reaver)" -REAVER_RESOURCE_EFFICIENCY = "Resource Efficiency (Reaver)" -VANGUARD_AGONY_LAUNCHERS = "Agony Launchers (Vanguard)" -VANGUARD_MATTER_DISPERSION = "Matter Dispersion (Vanguard)" -IMMORTAL_ANNIHILATOR_SINGULARITY_CHARGE = "Singularity Charge (Immortal/Annihilator)" -IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING_MECHANICS = "Advanced Targeting Mechanics (Immortal/Annihilator)" -COLOSSUS_PACIFICATION_PROTOCOL = "Pacification Protocol (Colossus)" -WRATHWALKER_RAPID_POWER_CYCLING = "Rapid Power Cycling (Wrathwalker)" -WRATHWALKER_EYE_OF_WRATH = "Eye of Wrath (Wrathwalker)" -DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_SHROUD_OF_ADUN = "Shroud of Adun (Dark Templar/Avenger/Blood Hunter)" -DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_SHADOW_GUARD_TRAINING = "Shadow Guard Training (Dark Templar/Avenger/Blood Hunter)" -DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_BLINK = "Blink (Dark Templar/Avenger/Blood Hunter)" -DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_RESOURCE_EFFICIENCY = "Resource Efficiency (Dark Templar/Avenger/Blood Hunter)" -DARK_TEMPLAR_DARK_ARCHON_MELD = "Dark Archon Meld (Dark Templar)" -HIGH_TEMPLAR_SIGNIFIER_UNSHACKLED_PSIONIC_STORM = "Unshackled Psionic Storm (High Templar/Signifier)" -HIGH_TEMPLAR_SIGNIFIER_HALLUCINATION = "Hallucination (High Templar/Signifier)" -HIGH_TEMPLAR_SIGNIFIER_KHAYDARIN_AMULET = "Khaydarin Amulet (High Templar/Signifier)" -ARCHON_HIGH_ARCHON = "High Archon (Archon)" -DARK_ARCHON_FEEDBACK = "Feedback (Dark Archon)" -DARK_ARCHON_MAELSTROM = "Maelstrom (Dark Archon)" -DARK_ARCHON_ARGUS_TALISMAN = "Argus Talisman (Dark Archon)" -ASCENDANT_POWER_OVERWHELMING = "Power Overwhelming (Ascendant)" -ASCENDANT_CHAOTIC_ATTUNEMENT = "Chaotic Attunement (Ascendant)" -ASCENDANT_BLOOD_AMULET = "Blood Amulet (Ascendant)" -SENTRY_ENERGIZER_HAVOC_CLOAKING_MODULE = "Cloaking Module (Sentry/Energizer/Havoc)" -SENTRY_ENERGIZER_HAVOC_SHIELD_BATTERY_RAPID_RECHARGING = "Rapid Recharging (Sentry/Energizer/Havoc/Shield Battery)" -SENTRY_FORCE_FIELD = "Force Field (Sentry)" -SENTRY_HALLUCINATION = "Hallucination (Sentry)" -ENERGIZER_RECLAMATION = "Reclamation (Energizer)" -ENERGIZER_FORGED_CHASSIS = "Forged Chassis (Energizer)" -HAVOC_DETECT_WEAKNESS = "Detect Weakness (Havoc)" -HAVOC_BLOODSHARD_RESONANCE = "Bloodshard Resonance (Havoc)" -ZEALOT_SENTINEL_CENTURION_LEG_ENHANCEMENTS = "Leg Enhancements (Zealot/Sentinel/Centurion)" -ZEALOT_SENTINEL_CENTURION_SHIELD_CAPACITY = "Shield Capacity (Zealot/Sentinel/Centurion)" - -# Spear Of Adun -SOA_CHRONO_SURGE = "Chrono Surge (Spear of Adun Calldown)" -SOA_PROGRESSIVE_PROXY_PYLON = "Progressive Proxy Pylon (Spear of Adun Calldown)" -SOA_PYLON_OVERCHARGE = "Pylon Overcharge (Spear of Adun Calldown)" -SOA_ORBITAL_STRIKE = "Orbital Strike (Spear of Adun Calldown)" -SOA_TEMPORAL_FIELD = "Temporal Field (Spear of Adun Calldown)" -SOA_SOLAR_LANCE = "Solar Lance (Spear of Adun Calldown)" -SOA_MASS_RECALL = "Mass Recall (Spear of Adun Calldown)" -SOA_SHIELD_OVERCHARGE = "Shield Overcharge (Spear of Adun Calldown)" -SOA_DEPLOY_FENIX = "Deploy Fenix (Spear of Adun Calldown)" -SOA_PURIFIER_BEAM = "Purifier Beam (Spear of Adun Calldown)" -SOA_TIME_STOP = "Time Stop (Spear of Adun Calldown)" -SOA_SOLAR_BOMBARDMENT = "Solar Bombardment (Spear of Adun Calldown)" - -# Generic upgrades -MATRIX_OVERLOAD = "Matrix Overload" -QUATRO = "Quatro" -NEXUS_OVERCHARGE = "Nexus Overcharge" -ORBITAL_ASSIMILATORS = "Orbital Assimilators" -WARP_HARMONIZATION = "Warp Harmonization" -GUARDIAN_SHELL = "Guardian Shell" -RECONSTRUCTION_BEAM = "Reconstruction Beam (Spear of Adun Auto-Cast)" -OVERWATCH = "Overwatch (Spear of Adun Auto-Cast)" -SUPERIOR_WARP_GATES = "Superior Warp Gates" -ENHANCED_TARGETING = "Enhanced Targeting" -OPTIMIZED_ORDNANCE = "Optimized Ordnance" -KHALAI_INGENUITY = "Khalai Ingenuity" -AMPLIFIED_ASSIMILATORS = "Amplified Assimilators" - -# Filler items -STARTING_MINERALS = "Additional Starting Minerals" -STARTING_VESPENE = "Additional Starting Vespene" -STARTING_SUPPLY = "Additional Starting Supply" -NOTHING = "Nothing" diff --git a/worlds/sc2/Items.py b/worlds/sc2/Items.py deleted file mode 100644 index ee1f34d75be9..000000000000 --- a/worlds/sc2/Items.py +++ /dev/null @@ -1,2554 +0,0 @@ -import inspect -from pydoc import describe - -from BaseClasses import Item, ItemClassification, MultiWorld -import typing - -from .Options import get_option_value, RequiredTactics -from .MissionTables import SC2Mission, SC2Race, SC2Campaign, campaign_mission_table -from . import ItemNames -from worlds.AutoWorld import World - - -class ItemData(typing.NamedTuple): - code: int - type: str - number: int # Important for bot commands to send the item into the game - race: SC2Race - classification: ItemClassification = ItemClassification.useful - quantity: int = 1 - parent_item: typing.Optional[str] = None - origin: typing.Set[str] = {"wol"} - description: typing.Optional[str] = None - important_for_filtering: bool = False - - def is_important_for_filtering(self): - return self.important_for_filtering \ - or self.classification == ItemClassification.progression \ - or self.classification == ItemClassification.progression_skip_balancing - - -class StarcraftItem(Item): - game: str = "Starcraft 2" - - -def get_full_item_list(): - return item_table - - -SC2WOL_ITEM_ID_OFFSET = 1000 -SC2HOTS_ITEM_ID_OFFSET = SC2WOL_ITEM_ID_OFFSET + 1000 -SC2LOTV_ITEM_ID_OFFSET = SC2HOTS_ITEM_ID_OFFSET + 1000 - -# Descriptions -WEAPON_ARMOR_UPGRADE_NOTE = inspect.cleandoc(""" - Must be researched during the mission if the mission type isn't set to auto-unlock generic upgrades. -""") -LASER_TARGETING_SYSTEMS_DESCRIPTION = "Increases vision by 2 and weapon range by 1." -STIMPACK_SMALL_COST = 10 -STIMPACK_SMALL_HEAL = 30 -STIMPACK_LARGE_COST = 20 -STIMPACK_LARGE_HEAL = 60 -STIMPACK_TEMPLATE = inspect.cleandoc(""" - Level 1: Stimpack: Increases unit movement and attack speed for 15 seconds. Injures the unit for {} life. - Level 2: Super Stimpack: Instead of injuring the unit, heals the unit for {} life instead. -""") -STIMPACK_SMALL_DESCRIPTION = STIMPACK_TEMPLATE.format(STIMPACK_SMALL_COST, STIMPACK_SMALL_HEAL) -STIMPACK_LARGE_DESCRIPTION = STIMPACK_TEMPLATE.format(STIMPACK_LARGE_COST, STIMPACK_LARGE_HEAL) -SMART_SERVOS_DESCRIPTION = "Increases transformation speed between modes." -INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE = "{} can be trained from a {} without an attached Tech Lab." -RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE = "Reduces {} resource and supply cost." -RESOURCE_EFFICIENCY_NO_SUPPLY_DESCRIPTION_TEMPLATE = "Reduces {} resource cost." -CLOAK_DESCRIPTION_TEMPLATE = "Allows {} to use the Cloak ability." - - -# The items are sorted by their IDs. The IDs shall be kept for compatibility with older games. -item_table = { - # WoL - ItemNames.MARINE: - ItemData(0 + SC2WOL_ITEM_ID_OFFSET, "Unit", 0, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="General-purpose infantry."), - ItemNames.MEDIC: - ItemData(1 + SC2WOL_ITEM_ID_OFFSET, "Unit", 1, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Support trooper. Heals nearby biological units."), - ItemNames.FIREBAT: - ItemData(2 + SC2WOL_ITEM_ID_OFFSET, "Unit", 2, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Specialized anti-infantry attacker."), - ItemNames.MARAUDER: - ItemData(3 + SC2WOL_ITEM_ID_OFFSET, "Unit", 3, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Heavy assault infantry."), - ItemNames.REAPER: - ItemData(4 + SC2WOL_ITEM_ID_OFFSET, "Unit", 4, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Raider. Capable of jumping up and down cliffs. Throws explosive mines."), - ItemNames.HELLION: - ItemData(5 + SC2WOL_ITEM_ID_OFFSET, "Unit", 5, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Fast scout. Has a flame attack that damages all enemy units in its line of fire."), - ItemNames.VULTURE: - ItemData(6 + SC2WOL_ITEM_ID_OFFSET, "Unit", 6, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Fast skirmish unit. Can use the Spider Mine ability."), - ItemNames.GOLIATH: - ItemData(7 + SC2WOL_ITEM_ID_OFFSET, "Unit", 7, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Heavy-fire support unit."), - ItemNames.DIAMONDBACK: - ItemData(8 + SC2WOL_ITEM_ID_OFFSET, "Unit", 8, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Fast, high-damage hovertank. Rail Gun can fire while the Diamondback is moving."), - ItemNames.SIEGE_TANK: - ItemData(9 + SC2WOL_ITEM_ID_OFFSET, "Unit", 9, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Heavy tank. Long-range artillery in Siege Mode."), - ItemNames.MEDIVAC: - ItemData(10 + SC2WOL_ITEM_ID_OFFSET, "Unit", 10, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Air transport. Heals nearby biological units."), - ItemNames.WRAITH: - ItemData(11 + SC2WOL_ITEM_ID_OFFSET, "Unit", 11, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Highly mobile flying unit. Excellent at surgical strikes."), - ItemNames.VIKING: - ItemData(12 + SC2WOL_ITEM_ID_OFFSET, "Unit", 12, SC2Race.TERRAN, - classification=ItemClassification.progression, - description=inspect.cleandoc( - """ - Durable support flyer. Loaded with strong anti-capital air missiles. - Can switch into Assault Mode to attack ground units. - """ - )), - ItemNames.BANSHEE: - ItemData(13 + SC2WOL_ITEM_ID_OFFSET, "Unit", 13, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Tactical-strike aircraft."), - ItemNames.BATTLECRUISER: - ItemData(14 + SC2WOL_ITEM_ID_OFFSET, "Unit", 14, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Powerful warship."), - ItemNames.GHOST: - ItemData(15 + SC2WOL_ITEM_ID_OFFSET, "Unit", 15, SC2Race.TERRAN, - classification=ItemClassification.progression, - description=inspect.cleandoc( - """ - Infiltration unit. Can use Snipe and Cloak abilities. Can also call down Tactical Nukes. - """ - )), - ItemNames.SPECTRE: - ItemData(16 + SC2WOL_ITEM_ID_OFFSET, "Unit", 16, SC2Race.TERRAN, - classification=ItemClassification.progression, - description=inspect.cleandoc( - """ - Infiltration unit. Can use Ultrasonic Pulse, Psionic Lash, and Cloak. - Can also call down Tactical Nukes. - """ - )), - ItemNames.THOR: - ItemData(17 + SC2WOL_ITEM_ID_OFFSET, "Unit", 17, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Heavy assault mech."), - # EE units - ItemNames.LIBERATOR: - ItemData(18 + SC2WOL_ITEM_ID_OFFSET, "Unit", 18, SC2Race.TERRAN, - classification=ItemClassification.progression, origin={"nco", "ext"}, - description=inspect.cleandoc( - """ - Artillery fighter. Loaded with missiles that deal area damage to enemy air targets. - Can switch into Defender Mode to provide siege support. - """ - )), - ItemNames.VALKYRIE: - ItemData(19 + SC2WOL_ITEM_ID_OFFSET, "Unit", 19, SC2Race.TERRAN, - classification=ItemClassification.progression, origin={"bw"}, - description=inspect.cleandoc( - """ - Advanced anti-aircraft fighter. - Able to use cluster missiles that deal area damage to air targets. - """ - )), - ItemNames.WIDOW_MINE: - ItemData(20 + SC2WOL_ITEM_ID_OFFSET, "Unit", 20, SC2Race.TERRAN, - classification=ItemClassification.progression, origin={"ext"}, - description=inspect.cleandoc( - """ - Robotic mine. Launches missiles at nearby enemy units while burrowed. - Attacks deal splash damage in a small area around the target. - Widow Mine is revealed when Sentinel Missile is on cooldown. - """ - )), - ItemNames.CYCLONE: - ItemData(21 + SC2WOL_ITEM_ID_OFFSET, "Unit", 21, SC2Race.TERRAN, - classification=ItemClassification.progression, origin={"ext"}, - description=inspect.cleandoc( - """ - Mobile assault vehicle. Can use Lock On to quickly fire while moving. - """ - )), - ItemNames.HERC: - ItemData(22 + SC2WOL_ITEM_ID_OFFSET, "Unit", 26, SC2Race.TERRAN, - classification=ItemClassification.progression, origin={"ext"}, - description=inspect.cleandoc( - """ - Front-line infantry. Can use Grapple. - """ - )), - ItemNames.WARHOUND: - ItemData(23 + SC2WOL_ITEM_ID_OFFSET, "Unit", 27, SC2Race.TERRAN, - classification=ItemClassification.progression, origin={"ext"}, - description=inspect.cleandoc( - """ - Anti-vehicle mech. Haywire missiles do bonus damage to mechanical units. - """ - )), - - # Some other items are moved to Upgrade group because of the way how the bot message is parsed - ItemNames.PROGRESSIVE_TERRAN_INFANTRY_WEAPON: - ItemData(100 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 0, SC2Race.TERRAN, - quantity=3, - description=inspect.cleandoc( - f""" - Increases damage of Terran infantry units. - {WEAPON_ARMOR_UPGRADE_NOTE} - """ - )), - ItemNames.PROGRESSIVE_TERRAN_INFANTRY_ARMOR: - ItemData(102 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 2, SC2Race.TERRAN, - quantity=3, - description=inspect.cleandoc( - f""" - Increases armor of Terran infantry units. - {WEAPON_ARMOR_UPGRADE_NOTE} - """ - )), - ItemNames.PROGRESSIVE_TERRAN_VEHICLE_WEAPON: - ItemData(103 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 4, SC2Race.TERRAN, - quantity=3, - description=inspect.cleandoc( - f""" - Increases damage of Terran vehicle units. - {WEAPON_ARMOR_UPGRADE_NOTE} - """ - )), - ItemNames.PROGRESSIVE_TERRAN_VEHICLE_ARMOR: - ItemData(104 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 6, SC2Race.TERRAN, - quantity=3, - description=inspect.cleandoc( - f""" - Increases armor of Terran vehicle units. - {WEAPON_ARMOR_UPGRADE_NOTE} - """ - )), - ItemNames.PROGRESSIVE_TERRAN_SHIP_WEAPON: - ItemData(105 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 8, SC2Race.TERRAN, - quantity=3, - description=inspect.cleandoc( - f""" - Increases damage of Terran starship units. - {WEAPON_ARMOR_UPGRADE_NOTE} - """ - )), - ItemNames.PROGRESSIVE_TERRAN_SHIP_ARMOR: - ItemData(106 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 10, SC2Race.TERRAN, - quantity=3, - description=inspect.cleandoc( - f""" - Increases armor of Terran starship units. - {WEAPON_ARMOR_UPGRADE_NOTE} - """ - )), - # Upgrade bundle 'number' values are used as indices to get affected 'number's - ItemNames.PROGRESSIVE_TERRAN_WEAPON_UPGRADE: ItemData(107 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 0, SC2Race.TERRAN, quantity=3), - ItemNames.PROGRESSIVE_TERRAN_ARMOR_UPGRADE: ItemData(108 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 1, SC2Race.TERRAN, quantity=3), - ItemNames.PROGRESSIVE_TERRAN_INFANTRY_UPGRADE: ItemData(109 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 2, SC2Race.TERRAN, quantity=3), - ItemNames.PROGRESSIVE_TERRAN_VEHICLE_UPGRADE: ItemData(110 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 3, SC2Race.TERRAN, quantity=3), - ItemNames.PROGRESSIVE_TERRAN_SHIP_UPGRADE: ItemData(111 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 4, SC2Race.TERRAN, quantity=3), - ItemNames.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE: ItemData(112 + SC2WOL_ITEM_ID_OFFSET, "Upgrade", 5, SC2Race.TERRAN, quantity=3), - - # Unit and structure upgrades - ItemNames.BUNKER_PROJECTILE_ACCELERATOR: - ItemData(200 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 0, SC2Race.TERRAN, - parent_item=ItemNames.BUNKER, - description="Increases range of all units in the Bunker by 1."), - ItemNames.BUNKER_NEOSTEEL_BUNKER: - ItemData(201 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 1, SC2Race.TERRAN, - parent_item=ItemNames.BUNKER, - description="Increases the number of Bunker slots by 2."), - ItemNames.MISSILE_TURRET_TITANIUM_HOUSING: - ItemData(202 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 2, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MISSILE_TURRET, - description="Increases Missile Turret life by 75."), - ItemNames.MISSILE_TURRET_HELLSTORM_BATTERIES: - ItemData(203 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 3, SC2Race.TERRAN, - parent_item=ItemNames.MISSILE_TURRET, - description="The Missile Turret unleashes an additional flurry of missiles with each attack."), - ItemNames.SCV_ADVANCED_CONSTRUCTION: - ItemData(204 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 4, SC2Race.TERRAN, - description="Multiple SCVs can construct a structure, reducing its construction time."), - ItemNames.SCV_DUAL_FUSION_WELDERS: - ItemData(205 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 5, SC2Race.TERRAN, - description="SCVs repair twice as fast."), - ItemNames.PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM: - ItemData(206 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 24, SC2Race.TERRAN, - quantity=2, - description=inspect.cleandoc( - """ - Level 1: While on low health, Terran structures are repaired to half health instead of burning down. - Level 2: Terran structures are repaired to full health instead of half health - """ - )), - ItemNames.PROGRESSIVE_ORBITAL_COMMAND: - ItemData(207 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 26, SC2Race.TERRAN, - quantity=2, classification=ItemClassification.progression, - description=inspect.cleandoc( - """ - Level 1: Allows Command Centers to use Scanner Sweep and Calldown: MULE abilities. - Level 2: Orbital Command abilities work even in Planetary Fortress mode. - """ - )), - ItemNames.MARINE_PROGRESSIVE_STIMPACK: - ItemData(208 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 0, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.MARINE, quantity=2, - description=STIMPACK_SMALL_DESCRIPTION), - ItemNames.MARINE_COMBAT_SHIELD: - ItemData(209 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 9, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.MARINE, - description="Increases Marine life by 10."), - ItemNames.MEDIC_ADVANCED_MEDIC_FACILITIES: - ItemData(210 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 10, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MEDIC, - description=INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Medics", "Barracks")), - ItemNames.MEDIC_STABILIZER_MEDPACKS: - ItemData(211 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 11, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.MEDIC, - description="Increases Medic heal speed. Reduces the amount of energy required for each heal."), - ItemNames.FIREBAT_INCINERATOR_GAUNTLETS: - ItemData(212 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 12, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.FIREBAT, - description="Increases Firebat's damage radius by 40%"), - ItemNames.FIREBAT_JUGGERNAUT_PLATING: - ItemData(213 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 13, SC2Race.TERRAN, - parent_item=ItemNames.FIREBAT, - description="Increases Firebat's armor by 2."), - ItemNames.MARAUDER_CONCUSSIVE_SHELLS: - ItemData(214 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 14, SC2Race.TERRAN, - parent_item=ItemNames.MARAUDER, - description="Marauder attack temporarily slows all units in target area."), - ItemNames.MARAUDER_KINETIC_FOAM: - ItemData(215 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 15, SC2Race.TERRAN, - parent_item=ItemNames.MARAUDER, - description="Increases Marauder life by 25."), - ItemNames.REAPER_U238_ROUNDS: - ItemData(216 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 16, SC2Race.TERRAN, - parent_item=ItemNames.REAPER, - description=inspect.cleandoc( - """ - Increases Reaper pistol attack range by 1. - Reaper pistols do additional 3 damage to Light Armor. - """ - )), - ItemNames.REAPER_G4_CLUSTERBOMB: - ItemData(217 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 17, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.REAPER, - description="Timed explosive that does heavy area damage."), - ItemNames.CYCLONE_MAG_FIELD_ACCELERATORS: - ItemData(218 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 18, SC2Race.TERRAN, - parent_item=ItemNames.CYCLONE, origin={"ext"}, - description="Increases Cyclone Lock On damage"), - ItemNames.CYCLONE_MAG_FIELD_LAUNCHERS: - ItemData(219 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 19, SC2Race.TERRAN, - parent_item=ItemNames.CYCLONE, origin={"ext"}, - description="Increases Cyclone attack range by 2."), - ItemNames.MARINE_LASER_TARGETING_SYSTEM: - ItemData(220 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 8, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MARINE, origin={"nco"}, - description=LASER_TARGETING_SYSTEMS_DESCRIPTION), - ItemNames.MARINE_MAGRAIL_MUNITIONS: - ItemData(221 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 20, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.MARINE, origin={"nco"}, - description="Deals 20 damage to target unit. Autocast on attack with a cooldown."), - ItemNames.MARINE_OPTIMIZED_LOGISTICS: - ItemData(222 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 21, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MARINE, origin={"nco"}, - description="Increases Marine training speed."), - ItemNames.MEDIC_RESTORATION: - ItemData(223 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 22, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MEDIC, origin={"bw"}, - description="Removes negative status effects from target allied unit."), - ItemNames.MEDIC_OPTICAL_FLARE: - ItemData(224 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 23, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MEDIC, origin={"bw"}, - description="Reduces vision range of target enemy unit. Disables detection."), - ItemNames.MEDIC_RESOURCE_EFFICIENCY: - ItemData(225 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 24, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MEDIC, origin={"bw"}, - description=RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE.format("Medic")), - ItemNames.FIREBAT_PROGRESSIVE_STIMPACK: - ItemData(226 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 6, SC2Race.TERRAN, - parent_item=ItemNames.FIREBAT, quantity=2, origin={"bw"}, - description=STIMPACK_LARGE_DESCRIPTION), - ItemNames.FIREBAT_RESOURCE_EFFICIENCY: - ItemData(227 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 25, SC2Race.TERRAN, - parent_item=ItemNames.FIREBAT, origin={"bw"}, - description=RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE.format("Firebat")), - ItemNames.MARAUDER_PROGRESSIVE_STIMPACK: - ItemData(228 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 8, SC2Race.TERRAN, - parent_item=ItemNames.MARAUDER, quantity=2, origin={"nco"}, - description=STIMPACK_LARGE_DESCRIPTION), - ItemNames.MARAUDER_LASER_TARGETING_SYSTEM: - ItemData(229 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 26, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MARAUDER, origin={"nco"}, - description=LASER_TARGETING_SYSTEMS_DESCRIPTION), - ItemNames.MARAUDER_MAGRAIL_MUNITIONS: - ItemData(230 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 27, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MARAUDER, origin={"nco"}, - description="Deals 20 damage to target unit. Autocast on attack with a cooldown."), - ItemNames.MARAUDER_INTERNAL_TECH_MODULE: - ItemData(231 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 28, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MARAUDER, origin={"nco"}, - description=INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Marauders", "Barracks")), - ItemNames.SCV_HOSTILE_ENVIRONMENT_ADAPTATION: - ItemData(232 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 29, SC2Race.TERRAN, - classification=ItemClassification.filler, origin={"bw"}, - description="Increases SCV life by 15 and attack speed slightly."), - ItemNames.MEDIC_ADAPTIVE_MEDPACKS: - ItemData(233 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 0, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.MEDIC, origin={"ext"}, - description="Allows Medics to heal mechanical and air units."), - ItemNames.MEDIC_NANO_PROJECTOR: - ItemData(234 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 1, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MEDIC, origin={"ext"}, - description="Increases Medic heal range by 2."), - ItemNames.FIREBAT_INFERNAL_PRE_IGNITER: - ItemData(235 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 2, SC2Race.TERRAN, - parent_item=ItemNames.FIREBAT, origin={"bw"}, - description="Firebats do an additional 4 damage to Light Armor."), - ItemNames.FIREBAT_KINETIC_FOAM: - ItemData(236 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 3, SC2Race.TERRAN, - parent_item=ItemNames.FIREBAT, origin={"ext"}, - description="Increases Firebat life by 100."), - ItemNames.FIREBAT_NANO_PROJECTORS: - ItemData(237 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 4, SC2Race.TERRAN, - parent_item=ItemNames.FIREBAT, origin={"ext"}, - description="Increases Firebat attack range by 2"), - ItemNames.MARAUDER_JUGGERNAUT_PLATING: - ItemData(238 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 5, SC2Race.TERRAN, - parent_item=ItemNames.MARAUDER, origin={"ext"}, - description="Increases Marauder's armor by 2."), - ItemNames.REAPER_JET_PACK_OVERDRIVE: - ItemData(239 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 6, SC2Race.TERRAN, - parent_item=ItemNames.REAPER, origin={"ext"}, - description=inspect.cleandoc( - """ - Allows the Reaper to fly for 10 seconds. - While flying, the Reaper can attack air units. - """ - )), - ItemNames.HELLION_INFERNAL_PLATING: - ItemData(240 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 7, SC2Race.TERRAN, - parent_item=ItemNames.HELLION, origin={"ext"}, - description="Increases Hellion and Hellbat armor by 2."), - ItemNames.VULTURE_AUTO_REPAIR: - ItemData(241 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 8, SC2Race.TERRAN, - parent_item=ItemNames.VULTURE, origin={"ext"}, - description="Vultures regenerate life."), - ItemNames.GOLIATH_SHAPED_HULL: - ItemData(242 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 9, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.GOLIATH, origin={"nco", "ext"}, - description="Increases Goliath life by 25."), - ItemNames.GOLIATH_RESOURCE_EFFICIENCY: - ItemData(243 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 10, SC2Race.TERRAN, - parent_item=ItemNames.GOLIATH, origin={"nco", "bw"}, - description=RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE.format("Goliath")), - ItemNames.GOLIATH_INTERNAL_TECH_MODULE: - ItemData(244 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 11, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.GOLIATH, origin={"nco", "bw"}, - description=INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Goliaths", "Factory")), - ItemNames.SIEGE_TANK_SHAPED_HULL: - ItemData(245 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 12, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.SIEGE_TANK, origin={"nco", "ext"}, - description="Increases Siege Tank life by 25."), - ItemNames.SIEGE_TANK_RESOURCE_EFFICIENCY: - ItemData(246 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 13, SC2Race.TERRAN, - parent_item=ItemNames.SIEGE_TANK, origin={"bw"}, - description=RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE.format("Siege Tank")), - ItemNames.PREDATOR_CLOAK: - ItemData(247 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 14, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.PREDATOR, origin={"ext"}, - description=CLOAK_DESCRIPTION_TEMPLATE.format("Predators")), - ItemNames.PREDATOR_CHARGE: - ItemData(248 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 15, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.PREDATOR, origin={"ext"}, - description="Allows Predators to intercept enemy ground units."), - ItemNames.MEDIVAC_SCATTER_VEIL: - ItemData(249 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 16, SC2Race.TERRAN, - parent_item=ItemNames.MEDIVAC, origin={"ext"}, - description="Medivacs get 100 shields."), - ItemNames.REAPER_PROGRESSIVE_STIMPACK: - ItemData(250 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 10, SC2Race.TERRAN, - parent_item=ItemNames.REAPER, quantity=2, origin={"nco"}, - description=STIMPACK_SMALL_DESCRIPTION), - ItemNames.REAPER_LASER_TARGETING_SYSTEM: - ItemData(251 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 17, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.REAPER, origin={"nco"}, - description=LASER_TARGETING_SYSTEMS_DESCRIPTION), - ItemNames.REAPER_ADVANCED_CLOAKING_FIELD: - ItemData(252 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 18, SC2Race.TERRAN, - parent_item=ItemNames.REAPER, origin={"nco"}, - description="Reapers are permanently cloaked."), - ItemNames.REAPER_SPIDER_MINES: - ItemData(253 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 19, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.REAPER, origin={"nco"}, - important_for_filtering=True, - description="Allows Reapers to lay Spider Mines. 3 charges per Reaper."), - ItemNames.REAPER_COMBAT_DRUGS: - ItemData(254 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 20, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.REAPER, origin={"ext"}, - description="Reapers regenerate life while out of combat."), - ItemNames.HELLION_HELLBAT_ASPECT: - ItemData(255 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 21, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.HELLION, origin={"nco"}, - description="Allows Hellions to transform into Hellbats."), - ItemNames.HELLION_SMART_SERVOS: - ItemData(256 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 22, SC2Race.TERRAN, - parent_item=ItemNames.HELLION, origin={"nco"}, - description="Transforms faster between modes. Hellions can attack while moving."), - ItemNames.HELLION_OPTIMIZED_LOGISTICS: - ItemData(257 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 23, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.HELLION, origin={"nco"}, - description="Increases Hellion training speed."), - ItemNames.HELLION_JUMP_JETS: - ItemData(258 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 24, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.HELLION, origin={"nco"}, - description=inspect.cleandoc( - """ - Increases movement speed in Hellion mode. - In Hellbat mode, launches the Hellbat toward enemy ground units and briefly stuns them. - """ - )), - ItemNames.HELLION_PROGRESSIVE_STIMPACK: - ItemData(259 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 12, SC2Race.TERRAN, - parent_item=ItemNames.HELLION, quantity=2, origin={"nco"}, - description=STIMPACK_LARGE_DESCRIPTION), - ItemNames.VULTURE_ION_THRUSTERS: - ItemData(260 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 25, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.VULTURE, origin={"bw"}, - description="Increases Vulture movement speed."), - ItemNames.VULTURE_AUTO_LAUNCHERS: - ItemData(261 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 26, SC2Race.TERRAN, - parent_item=ItemNames.VULTURE, origin={"bw"}, - description="Allows Vultures to attack while moving."), - ItemNames.SPIDER_MINE_HIGH_EXPLOSIVE_MUNITION: - ItemData(262 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 27, SC2Race.TERRAN, - origin={"bw"}, - description="Increases Spider mine damage."), - ItemNames.GOLIATH_JUMP_JETS: - ItemData(263 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 28, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.GOLIATH, origin={"nco"}, - description="Allows Goliaths to jump up and down cliffs."), - ItemNames.GOLIATH_OPTIMIZED_LOGISTICS: - ItemData(264 + SC2WOL_ITEM_ID_OFFSET, "Armory 2", 29, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.GOLIATH, origin={"nco"}, - description="Increases Goliath training speed."), - ItemNames.DIAMONDBACK_HYPERFLUXOR: - ItemData(265 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 0, SC2Race.TERRAN, - parent_item=ItemNames.DIAMONDBACK, origin={"ext"}, - description="Increases Diamondback attack speed."), - ItemNames.DIAMONDBACK_BURST_CAPACITORS: - ItemData(266 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 1, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.DIAMONDBACK, origin={"ext"}, - description=inspect.cleandoc( - """ - While not attacking, the Diamondback charges its weapon. - The next attack does 10 additional damage. - """ - )), - ItemNames.DIAMONDBACK_RESOURCE_EFFICIENCY: - ItemData(267 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 2, SC2Race.TERRAN, - parent_item=ItemNames.DIAMONDBACK, origin={"ext"}, - description=RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE.format("Diamondback")), - ItemNames.SIEGE_TANK_JUMP_JETS: - ItemData(268 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 3, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.SIEGE_TANK, origin={"nco"}, - description=inspect.cleandoc( - """ - Repositions Siege Tank to a target location. - Can be used in either mode and to jump up and down cliffs. - """ - )), - ItemNames.SIEGE_TANK_SPIDER_MINES: - ItemData(269 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 4, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.SIEGE_TANK, origin={"nco"}, - important_for_filtering=True, - description=inspect.cleandoc( - """ - Allows Siege Tanks to lay Spider Mines. - Lays 3 Spider Mines at once. 3 charges - """ - )), - ItemNames.SIEGE_TANK_SMART_SERVOS: - ItemData(270 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 5, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.SIEGE_TANK, origin={"nco"}, - description=SMART_SERVOS_DESCRIPTION), - ItemNames.SIEGE_TANK_GRADUATING_RANGE: - ItemData(271 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 6, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.SIEGE_TANK, origin={"ext"}, - description=inspect.cleandoc( - """ - Increases the Siege Tank's attack range by 1 every 3 seconds while in Siege Mode, - up to a maximum of 5 additional range. - """ - )), - ItemNames.SIEGE_TANK_LASER_TARGETING_SYSTEM: - ItemData(272 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 7, SC2Race.TERRAN, - parent_item=ItemNames.SIEGE_TANK, origin={"nco"}, - description=LASER_TARGETING_SYSTEMS_DESCRIPTION), - ItemNames.SIEGE_TANK_ADVANCED_SIEGE_TECH: - ItemData(273 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 8, SC2Race.TERRAN, - parent_item=ItemNames.SIEGE_TANK, origin={"ext"}, - description="Siege Tanks gain +3 armor in Siege Mode."), - ItemNames.SIEGE_TANK_INTERNAL_TECH_MODULE: - ItemData(274 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 9, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.SIEGE_TANK, origin={"nco"}, - description=INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Siege Tanks", "Factory")), - ItemNames.PREDATOR_RESOURCE_EFFICIENCY: - ItemData(275 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 10, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.PREDATOR, origin={"ext"}, - description="Decreases Predator resource and supply cost."), - ItemNames.MEDIVAC_EXPANDED_HULL: - ItemData(276 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 11, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MEDIVAC, origin={"ext"}, - description="Increases Medivac cargo space by 4."), - ItemNames.MEDIVAC_AFTERBURNERS: - ItemData(277 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 12, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MEDIVAC, origin={"ext"}, - description="Ability. Temporarily increases the Medivac's movement speed by 70%."), - ItemNames.WRAITH_ADVANCED_LASER_TECHNOLOGY: - ItemData(278 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 13, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.WRAITH, origin={"ext"}, - description=inspect.cleandoc( - """ - Burst Lasers do more damage and can hit both ground and air targets. - Replaces Gemini Missiles weapon. - """ - )), - ItemNames.VIKING_SMART_SERVOS: - ItemData(279 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 14, SC2Race.TERRAN, - parent_item=ItemNames.VIKING, origin={"ext"}, - description=SMART_SERVOS_DESCRIPTION), - ItemNames.VIKING_ANTI_MECHANICAL_MUNITION: - ItemData(280 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 15, SC2Race.TERRAN, - parent_item=ItemNames.VIKING, origin={"ext"}, - description="Increases Viking damage to mechanical units while in Assault Mode."), - ItemNames.DIAMONDBACK_ION_THRUSTERS: - ItemData(281 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 21, SC2Race.TERRAN, - parent_item=ItemNames.DIAMONDBACK, origin={"ext"}, - description="Increases Diamondback movement speed."), - ItemNames.WARHOUND_RESOURCE_EFFICIENCY: - ItemData(282 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 13, SC2Race.TERRAN, - parent_item=ItemNames.WARHOUND, origin={"ext"}, - description=RESOURCE_EFFICIENCY_NO_SUPPLY_DESCRIPTION_TEMPLATE.format("Warhound")), - ItemNames.WARHOUND_REINFORCED_PLATING: - ItemData(283 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 14, SC2Race.TERRAN, - parent_item=ItemNames.WARHOUND, origin={"ext"}, - description="Increases Warhound armor by 2."), - ItemNames.HERC_RESOURCE_EFFICIENCY: - ItemData(284 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 15, SC2Race.TERRAN, - parent_item=ItemNames.HERC, origin={"ext"}, - description=RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE.format("HERC")), - ItemNames.HERC_JUGGERNAUT_PLATING: - ItemData(285 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 16, SC2Race.TERRAN, - parent_item=ItemNames.HERC, origin={"ext"}, - description="Increases HERC armor by 2."), - ItemNames.HERC_KINETIC_FOAM: - ItemData(286 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 17, SC2Race.TERRAN, - parent_item=ItemNames.HERC, origin={"ext"}, - description="Increases HERC life by 50."), - - ItemNames.HELLION_TWIN_LINKED_FLAMETHROWER: - ItemData(300 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 16, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.HELLION, - description="Doubles the width of the Hellion's flame attack."), - ItemNames.HELLION_THERMITE_FILAMENTS: - ItemData(301 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 17, SC2Race.TERRAN, - parent_item=ItemNames.HELLION, - description="Hellions do an additional 10 damage to Light Armor."), - ItemNames.SPIDER_MINE_CERBERUS_MINE: - ItemData(302 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 18, SC2Race.TERRAN, - classification=ItemClassification.filler, - description="Increases trigger and blast radius of Spider Mines."), - ItemNames.VULTURE_PROGRESSIVE_REPLENISHABLE_MAGAZINE: - ItemData(303 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 16, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.VULTURE, quantity=2, - description=inspect.cleandoc( - """ - Level 1: Allows Vultures to replace used Spider Mines. Costs 15 minerals. - Level 2: Replacing used Spider Mines no longer costs minerals. - """ - )), - ItemNames.GOLIATH_MULTI_LOCK_WEAPONS_SYSTEM: - ItemData(304 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 19, SC2Race.TERRAN, - parent_item=ItemNames.GOLIATH, - description="Goliaths can attack both ground and air targets simultaneously."), - ItemNames.GOLIATH_ARES_CLASS_TARGETING_SYSTEM: - ItemData(305 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 20, SC2Race.TERRAN, - parent_item=ItemNames.GOLIATH, - description="Increases Goliath ground attack range by 1 and air by 3."), - ItemNames.DIAMONDBACK_PROGRESSIVE_TRI_LITHIUM_POWER_CELL: - ItemData(306 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade 2", 4, SC2Race.TERRAN, - parent_item=ItemNames.DIAMONDBACK, quantity=2, - description=inspect.cleandoc( - """ - Level 1: Tri-Lithium Power Cell: Increases Diamondback attack range by 1. - Level 2: Tungsten Spikes: Increases Diamondback attack range by 3. - """ - )), - ItemNames.DIAMONDBACK_SHAPED_HULL: - ItemData(307 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 22, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.DIAMONDBACK, - description="Increases Diamondback life by 50."), - ItemNames.SIEGE_TANK_MAELSTROM_ROUNDS: - ItemData(308 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 23, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.SIEGE_TANK, - description="Siege Tanks do an additional 40 damage to the primary target in Siege Mode."), - ItemNames.SIEGE_TANK_SHAPED_BLAST: - ItemData(309 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 24, SC2Race.TERRAN, - parent_item=ItemNames.SIEGE_TANK, - description="Reduces splash damage to friendly targets while in Siege Mode by 75%."), - ItemNames.MEDIVAC_RAPID_DEPLOYMENT_TUBE: - ItemData(310 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 25, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MEDIVAC, - description="Medivacs deploy loaded troops almost instantly."), - ItemNames.MEDIVAC_ADVANCED_HEALING_AI: - ItemData(311 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 26, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.MEDIVAC, - description="Medivacs can heal two targets at once."), - ItemNames.WRAITH_PROGRESSIVE_TOMAHAWK_POWER_CELLS: - ItemData(312 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 18, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.WRAITH, quantity=2, - description=inspect.cleandoc( - """ - Level 1: Tomahawk Power Cells: Increases Wraith starting energy by 100. - Level 2: Unregistered Cloaking Module: Wraiths do not require energy to cloak and remain cloaked. - """ - )), - ItemNames.WRAITH_DISPLACEMENT_FIELD: - ItemData(313 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 27, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.WRAITH, - description="Wraiths evade 20% of incoming attacks while cloaked."), - ItemNames.VIKING_RIPWAVE_MISSILES: - ItemData(314 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 28, SC2Race.TERRAN, - parent_item=ItemNames.VIKING, - description="Vikings do area damage while in Fighter Mode"), - ItemNames.VIKING_PHOBOS_CLASS_WEAPONS_SYSTEM: - ItemData(315 + SC2WOL_ITEM_ID_OFFSET, "Armory 3", 29, SC2Race.TERRAN, - parent_item=ItemNames.VIKING, - description="Increases Viking attack range by 1 in Assault mode and 2 in Fighter mode."), - ItemNames.BANSHEE_PROGRESSIVE_CROSS_SPECTRUM_DAMPENERS: - ItemData(316 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 2, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.BANSHEE, quantity=2, - description=inspect.cleandoc( - """ - Level 1: Banshees can remain cloaked twice as long. - Level 2: Banshees do not require energy to cloak and remain cloaked. - """ - )), - ItemNames.BANSHEE_SHOCKWAVE_MISSILE_BATTERY: - ItemData(317 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 0, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.BANSHEE, - description="Banshees do area damage in a straight line."), - ItemNames.BATTLECRUISER_PROGRESSIVE_MISSILE_PODS: - ItemData(318 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade 2", 2, SC2Race.TERRAN, - parent_item=ItemNames.BATTLECRUISER, quantity=2, - description="Spell. Missile Pods do damage to air targets in a target area."), - ItemNames.BATTLECRUISER_PROGRESSIVE_DEFENSIVE_MATRIX: - ItemData(319 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 20, SC2Race.TERRAN, - parent_item=ItemNames.BATTLECRUISER, quantity=2, - description=inspect.cleandoc( - """ - Level 1: Spell. For 20 seconds the Battlecruiser gains a shield that can absorb up to 200 damage. - Level 2: Passive. Battlecruiser gets 200 shields. - """ - )), - ItemNames.GHOST_OCULAR_IMPLANTS: - ItemData(320 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 2, SC2Race.TERRAN, - parent_item=ItemNames.GHOST, - description="Increases Ghost sight range by 3 and attack range by 2."), - ItemNames.GHOST_CRIUS_SUIT: - ItemData(321 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 3, SC2Race.TERRAN, - parent_item=ItemNames.GHOST, - description="Cloak no longer requires energy to activate or maintain."), - ItemNames.SPECTRE_PSIONIC_LASH: - ItemData(322 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 4, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.SPECTRE, - description="Spell. Deals 200 damage to a single target."), - ItemNames.SPECTRE_NYX_CLASS_CLOAKING_MODULE: - ItemData(323 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 5, SC2Race.TERRAN, - parent_item=ItemNames.SPECTRE, - description="Cloak no longer requires energy to activate or maintain."), - ItemNames.THOR_330MM_BARRAGE_CANNON: - ItemData(324 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 6, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.THOR, - description=inspect.cleandoc( - """ - Improves 250mm Strike Cannons ability to deal area damage and stun units in a small area. - Can be also freely aimed on ground. - """ - )), - ItemNames.THOR_PROGRESSIVE_IMMORTALITY_PROTOCOL: - ItemData(325 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 22, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.THOR, quantity=2, - description=inspect.cleandoc(""" - Level 1: Allows destroyed Thors to be reconstructed on the field. Costs Vespene Gas. - Level 2: Thors are automatically reconstructed after falling for free. - """ - )), - ItemNames.LIBERATOR_ADVANCED_BALLISTICS: - ItemData(326 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 7, SC2Race.TERRAN, - parent_item=ItemNames.LIBERATOR, origin={"ext"}, - description="Increases Liberator range by 3 in Defender Mode."), - ItemNames.LIBERATOR_RAID_ARTILLERY: - ItemData(327 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 8, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.LIBERATOR, origin={"nco"}, - description="Allows Liberators to attack structures while in Defender Mode."), - ItemNames.WIDOW_MINE_DRILLING_CLAWS: - ItemData(328 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 9, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.WIDOW_MINE, origin={"ext"}, - description="Allows Widow Mines to burrow and unburrow faster."), - ItemNames.WIDOW_MINE_CONCEALMENT: - ItemData(329 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 10, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.WIDOW_MINE, origin={"ext"}, - description="Burrowed Widow Mines are no longer revealed when the Sentinel Missile is on cooldown."), - ItemNames.MEDIVAC_ADVANCED_CLOAKING_FIELD: - ItemData(330 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 11, SC2Race.TERRAN, - parent_item=ItemNames.MEDIVAC, origin={"ext"}, - description="Medivacs are permanently cloaked."), - ItemNames.WRAITH_TRIGGER_OVERRIDE: - ItemData(331 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 12, SC2Race.TERRAN, - parent_item=ItemNames.WRAITH, origin={"ext"}, - description="Wraith attack speed increases by 10% with each attack, up to a maximum of 100%."), - ItemNames.WRAITH_INTERNAL_TECH_MODULE: - ItemData(332 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 13, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.WRAITH, origin={"bw"}, - description=INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Wraiths", "Starport")), - ItemNames.WRAITH_RESOURCE_EFFICIENCY: - ItemData(333 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 14, SC2Race.TERRAN, - parent_item=ItemNames.WRAITH, origin={"bw"}, - description=RESOURCE_EFFICIENCY_NO_SUPPLY_DESCRIPTION_TEMPLATE.format("Wraith")), - ItemNames.VIKING_SHREDDER_ROUNDS: - ItemData(334 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 15, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.VIKING, origin={"ext"}, - description="Attacks in Assault mode do line splash damage."), - ItemNames.VIKING_WILD_MISSILES: - ItemData(335 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 16, SC2Race.TERRAN, - parent_item=ItemNames.VIKING, origin={"ext"}, - description="Launches 5 rockets at the target unit. Each rocket does 25 (40 vs armored) damage."), - ItemNames.BANSHEE_SHAPED_HULL: - ItemData(336 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 17, SC2Race.TERRAN, - parent_item=ItemNames.BANSHEE, origin={"ext"}, - description="Increases Banshee life by 100."), - ItemNames.BANSHEE_ADVANCED_TARGETING_OPTICS: - ItemData(337 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 18, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.BANSHEE, origin={"ext"}, - description="Increases Banshee attack range by 2 while cloaked."), - ItemNames.BANSHEE_DISTORTION_BLASTERS: - ItemData(338 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 19, SC2Race.TERRAN, - parent_item=ItemNames.BANSHEE, origin={"ext"}, - description="Increases Banshee attack damage by 25% while cloaked."), - ItemNames.BANSHEE_ROCKET_BARRAGE: - ItemData(339 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 20, SC2Race.TERRAN, - parent_item=ItemNames.BANSHEE, origin={"ext"}, - description="Deals 75 damage to enemy ground units in the target area."), - ItemNames.GHOST_RESOURCE_EFFICIENCY: - ItemData(340 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 21, SC2Race.TERRAN, - parent_item=ItemNames.GHOST, origin={"bw"}, - description=RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE.format("Ghost")), - ItemNames.SPECTRE_RESOURCE_EFFICIENCY: - ItemData(341 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 22, SC2Race.TERRAN, - parent_item=ItemNames.SPECTRE, origin={"ext"}, - description=RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE.format("Spectre")), - ItemNames.THOR_BUTTON_WITH_A_SKULL_ON_IT: - ItemData(342 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 23, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.THOR, origin={"ext"}, - description="Allows Thors to launch nukes."), - ItemNames.THOR_LASER_TARGETING_SYSTEM: - ItemData(343 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 24, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.THOR, origin={"ext"}, - description=LASER_TARGETING_SYSTEMS_DESCRIPTION), - ItemNames.THOR_LARGE_SCALE_FIELD_CONSTRUCTION: - ItemData(344 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 25, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.THOR, origin={"ext"}, - description="Allows Thors to be built by SCVs like a structure."), - ItemNames.RAVEN_RESOURCE_EFFICIENCY: - ItemData(345 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 26, SC2Race.TERRAN, - parent_item=ItemNames.RAVEN, origin={"ext"}, - description=RESOURCE_EFFICIENCY_NO_SUPPLY_DESCRIPTION_TEMPLATE.format("Raven")), - ItemNames.RAVEN_DURABLE_MATERIALS: - ItemData(346 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 27, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.RAVEN, origin={"ext"}, - description="Extends timed life duration of Raven's summoned objects."), - ItemNames.SCIENCE_VESSEL_IMPROVED_NANO_REPAIR: - ItemData(347 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 28, SC2Race.TERRAN, - parent_item=ItemNames.SCIENCE_VESSEL, origin={"ext"}, - description="Nano-Repair no longer requires energy to use."), - ItemNames.SCIENCE_VESSEL_ADVANCED_AI_SYSTEMS: - ItemData(348 + SC2WOL_ITEM_ID_OFFSET, "Armory 4", 29, SC2Race.TERRAN, - parent_item=ItemNames.SCIENCE_VESSEL, origin={"ext"}, - description="Science Vessel can use Nano-Repair at two targets at once."), - ItemNames.CYCLONE_RESOURCE_EFFICIENCY: - ItemData(349 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 0, SC2Race.TERRAN, - parent_item=ItemNames.CYCLONE, origin={"ext"}, - description=RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE.format("Cyclone")), - ItemNames.BANSHEE_HYPERFLIGHT_ROTORS: - ItemData(350 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 1, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.BANSHEE, origin={"ext"}, - description="Increases Banshee movement speed."), - ItemNames.BANSHEE_LASER_TARGETING_SYSTEM: - ItemData(351 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 2, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.BANSHEE, origin={"nco"}, - description=LASER_TARGETING_SYSTEMS_DESCRIPTION), - ItemNames.BANSHEE_INTERNAL_TECH_MODULE: - ItemData(352 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 3, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.BANSHEE, origin={"nco"}, - description=INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Banshees", "Starport")), - ItemNames.BATTLECRUISER_TACTICAL_JUMP: - ItemData(353 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 4, SC2Race.TERRAN, - parent_item=ItemNames.BATTLECRUISER, origin={"nco", "ext"}, - description=inspect.cleandoc( - """ - Allows Battlecruisers to warp to a target location anywhere on the map. - """ - )), - ItemNames.BATTLECRUISER_CLOAK: - ItemData(354 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 5, SC2Race.TERRAN, - parent_item=ItemNames.BATTLECRUISER, origin={"nco"}, - description=CLOAK_DESCRIPTION_TEMPLATE.format("Battlecruisers")), - ItemNames.BATTLECRUISER_ATX_LASER_BATTERY: - ItemData(355 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 6, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.BATTLECRUISER, origin={"nco"}, - description=inspect.cleandoc( - """ - Battlecruisers can attack while moving, - do the same damage to both ground and air targets, and fire faster. - """ - )), - ItemNames.BATTLECRUISER_OPTIMIZED_LOGISTICS: - ItemData(356 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 7, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.BATTLECRUISER, origin={"ext"}, - description="Increases Battlecruiser training speed."), - ItemNames.BATTLECRUISER_INTERNAL_TECH_MODULE: - ItemData(357 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 8, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.BATTLECRUISER, origin={"nco"}, - description=INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Battlecruisers", "Starport")), - ItemNames.GHOST_EMP_ROUNDS: - ItemData(358 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 9, SC2Race.TERRAN, - parent_item=ItemNames.GHOST, origin={"ext"}, - description=inspect.cleandoc( - """ - Spell. Does 100 damage to shields and drains all energy from units in the targeted area. - Cloaked units hit by EMP are revealed for a short time. - """ - )), - ItemNames.GHOST_LOCKDOWN: - ItemData(359 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 10, SC2Race.TERRAN, - parent_item=ItemNames.GHOST, origin={"bw"}, - description="Spell. Stuns a target mechanical unit for a long time."), - ItemNames.SPECTRE_IMPALER_ROUNDS: - ItemData(360 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 11, SC2Race.TERRAN, - parent_item=ItemNames.SPECTRE, origin={"ext"}, - description="Spectres do additional damage to armored targets."), - ItemNames.THOR_PROGRESSIVE_HIGH_IMPACT_PAYLOAD: - ItemData(361 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 14, SC2Race.TERRAN, - parent_item=ItemNames.THOR, quantity=2, origin={"ext"}, - description=inspect.cleandoc( - f""" - Level 1: Allows Thors to transform in order to use an alternative air attack. - Level 2: {SMART_SERVOS_DESCRIPTION} - """ - )), - ItemNames.RAVEN_BIO_MECHANICAL_REPAIR_DRONE: - ItemData(363 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 12, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.RAVEN, origin={"nco"}, - description="Spell. Deploys a drone that can heal biological or mechanical units."), - ItemNames.RAVEN_SPIDER_MINES: - ItemData(364 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 13, SC2Race.TERRAN, - parent_item=ItemNames.RAVEN, origin={"nco"}, important_for_filtering=True, - description="Spell. Deploys 3 Spider Mines to a target location."), - ItemNames.RAVEN_RAILGUN_TURRET: - ItemData(365 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 14, SC2Race.TERRAN, - parent_item=ItemNames.RAVEN, origin={"nco"}, - description=inspect.cleandoc( - """ - Spell. Allows Ravens to deploy an advanced Auto-Turret, - that can attack enemy ground units in a straight line. - """ - )), - ItemNames.RAVEN_HUNTER_SEEKER_WEAPON: - ItemData(366 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 15, SC2Race.TERRAN, - classification=ItemClassification.progression, parent_item=ItemNames.RAVEN, origin={"nco"}, - description="Allows Ravens to attack with a Hunter-Seeker weapon."), - ItemNames.RAVEN_INTERFERENCE_MATRIX: - ItemData(367 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 16, SC2Race.TERRAN, - parent_item=ItemNames.RAVEN, origin={"ext"}, - description=inspect.cleandoc( - """ - Spell. Target enemy Mechanical or Psionic unit can't attack or use abilities for a short duration. - """ - )), - ItemNames.RAVEN_ANTI_ARMOR_MISSILE: - ItemData(368 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 17, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.RAVEN, origin={"ext"}, - description="Spell. Decreases target and nearby enemy units armor by 2."), - ItemNames.RAVEN_INTERNAL_TECH_MODULE: - ItemData(369 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 18, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.RAVEN, origin={"nco"}, - description=INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Ravens", "Starport")), - ItemNames.SCIENCE_VESSEL_EMP_SHOCKWAVE: - ItemData(370 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 19, SC2Race.TERRAN, - parent_item=ItemNames.SCIENCE_VESSEL, origin={"bw"}, - description="Spell. Depletes all energy and shields of all units in a target area."), - ItemNames.SCIENCE_VESSEL_DEFENSIVE_MATRIX: - ItemData(371 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 20, SC2Race.TERRAN, - parent_item=ItemNames.SCIENCE_VESSEL, origin={"bw"}, - description=inspect.cleandoc( - """ - Spell. Provides a target unit with a defensive barrier that can absorb up to 250 damage - """ - )), - ItemNames.CYCLONE_TARGETING_OPTICS: - ItemData(372 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 21, SC2Race.TERRAN, - parent_item=ItemNames.CYCLONE, origin={"ext"}, - description="Increases Cyclone Lock On casting range and the range while Locked On."), - ItemNames.CYCLONE_RAPID_FIRE_LAUNCHERS: - ItemData(373 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 22, SC2Race.TERRAN, - parent_item=ItemNames.CYCLONE, origin={"ext"}, - description="The first 12 shots of Lock On are fired more quickly."), - ItemNames.LIBERATOR_CLOAK: - ItemData(374 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 23, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.LIBERATOR, origin={"nco"}, - description=CLOAK_DESCRIPTION_TEMPLATE.format("Liberators")), - ItemNames.LIBERATOR_LASER_TARGETING_SYSTEM: - ItemData(375 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 24, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.LIBERATOR, origin={"ext"}, - description=LASER_TARGETING_SYSTEMS_DESCRIPTION), - ItemNames.LIBERATOR_OPTIMIZED_LOGISTICS: - ItemData(376 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 25, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.LIBERATOR, origin={"nco"}, - description="Increases Liberator training speed."), - ItemNames.WIDOW_MINE_BLACK_MARKET_LAUNCHERS: - ItemData(377 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 26, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.WIDOW_MINE, origin={"ext"}, - description="Increases Widow Mine Sentinel Missile range."), - ItemNames.WIDOW_MINE_EXECUTIONER_MISSILES: - ItemData(378 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 27, SC2Race.TERRAN, - parent_item=ItemNames.WIDOW_MINE, origin={"ext"}, - description=inspect.cleandoc( - """ - Reduces Sentinel Missile cooldown. - When killed, Widow Mines will launch several missiles at random enemy targets. - """ - )), - ItemNames.VALKYRIE_ENHANCED_CLUSTER_LAUNCHERS: - ItemData(379 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 28, - SC2Race.TERRAN, parent_item=ItemNames.VALKYRIE, origin={"ext"}, - description="Valkyries fire 2 additional rockets each volley."), - ItemNames.VALKYRIE_SHAPED_HULL: - ItemData(380 + SC2WOL_ITEM_ID_OFFSET, "Armory 5", 29, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.VALKYRIE, origin={"ext"}, - description="Increases Valkyrie life by 50."), - ItemNames.VALKYRIE_FLECHETTE_MISSILES: - ItemData(381 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 0, SC2Race.TERRAN, - parent_item=ItemNames.VALKYRIE, origin={"ext"}, - description="Equips Valkyries with Air-to-Surface missiles to attack ground units."), - ItemNames.VALKYRIE_AFTERBURNERS: - ItemData(382 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 1, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.VALKYRIE, origin={"ext"}, - description="Ability. Temporarily increases the Valkyries's movement speed by 70%."), - ItemNames.CYCLONE_INTERNAL_TECH_MODULE: - ItemData(383 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 2, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.CYCLONE, origin={"ext"}, - description=INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Cyclones", "Factory")), - ItemNames.LIBERATOR_SMART_SERVOS: - ItemData(384 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 3, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.LIBERATOR, origin={"nco"}, - description=SMART_SERVOS_DESCRIPTION), - ItemNames.LIBERATOR_RESOURCE_EFFICIENCY: - ItemData(385 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 4, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.LIBERATOR, origin={"ext"}, - description=RESOURCE_EFFICIENCY_NO_SUPPLY_DESCRIPTION_TEMPLATE.format("Liberator")), - ItemNames.HERCULES_INTERNAL_FUSION_MODULE: - ItemData(386 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 5, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.HERCULES, origin={"ext"}, - description="Hercules can be trained from a Starport without having a Fusion Core."), - ItemNames.HERCULES_TACTICAL_JUMP: - ItemData(387 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 6, SC2Race.TERRAN, - parent_item=ItemNames.HERCULES, origin={"ext"}, - description=inspect.cleandoc( - """ - Allows Hercules to warp to a target location anywhere on the map. - """ - )), - ItemNames.PLANETARY_FORTRESS_PROGRESSIVE_AUGMENTED_THRUSTERS: - ItemData(388 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 28, SC2Race.TERRAN, - parent_item=ItemNames.PLANETARY_FORTRESS, origin={"ext"}, quantity=2, - description=inspect.cleandoc( - """ - Level 1: Lift Off - Planetary Fortress can lift off. - Level 2: Armament Stabilizers - Planetary Fortress can attack while lifted off. - """ - )), - ItemNames.PLANETARY_FORTRESS_ADVANCED_TARGETING: - ItemData(389 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 7, SC2Race.TERRAN, - parent_item=ItemNames.PLANETARY_FORTRESS, origin={"ext"}, - description="Planetary Fortress can attack air units."), - ItemNames.VALKYRIE_LAUNCHING_VECTOR_COMPENSATOR: - ItemData(390 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 8, SC2Race.TERRAN, - classification=ItemClassification.filler, parent_item=ItemNames.VALKYRIE, origin={"ext"}, - description="Allows Valkyries to shoot air while moving."), - ItemNames.VALKYRIE_RESOURCE_EFFICIENCY: - ItemData(391 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 9, SC2Race.TERRAN, - parent_item=ItemNames.VALKYRIE, origin={"ext"}, - description=RESOURCE_EFFICIENCY_DESCRIPTION_TEMPLATE.format("Valkyrie")), - ItemNames.PREDATOR_PREDATOR_S_FURY: - ItemData(392 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 10, SC2Race.TERRAN, - parent_item=ItemNames.PREDATOR, origin={"ext"}, - description="Predators can use an attack that jumps between targets."), - ItemNames.BATTLECRUISER_BEHEMOTH_PLATING: - ItemData(393 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 11, SC2Race.TERRAN, - parent_item=ItemNames.BATTLECRUISER, origin={"ext"}, - description="Increases Battlecruiser armor by 2."), - ItemNames.BATTLECRUISER_COVERT_OPS_ENGINES: - ItemData(394 + SC2WOL_ITEM_ID_OFFSET, "Armory 6", 12, SC2Race.TERRAN, - parent_item=ItemNames.BATTLECRUISER, origin={"nco"}, - description="Increases Battlecruiser movement speed."), - - #Buildings - ItemNames.BUNKER: - ItemData(400 + SC2WOL_ITEM_ID_OFFSET, "Building", 0, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Defensive structure. Able to load infantry units, giving them +1 range to their attacks."), - ItemNames.MISSILE_TURRET: - ItemData(401 + SC2WOL_ITEM_ID_OFFSET, "Building", 1, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Anti-air defensive structure."), - ItemNames.SENSOR_TOWER: - ItemData(402 + SC2WOL_ITEM_ID_OFFSET, "Building", 2, SC2Race.TERRAN, - description="Reveals locations of enemy units at long range."), - - ItemNames.WAR_PIGS: - ItemData(500 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 0, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Mercenary Marines"), - ItemNames.DEVIL_DOGS: - ItemData(501 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 1, SC2Race.TERRAN, - classification=ItemClassification.filler, - description="Mercenary Firebats"), - ItemNames.HAMMER_SECURITIES: - ItemData(502 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 2, SC2Race.TERRAN, - description="Mercenary Marauders"), - ItemNames.SPARTAN_COMPANY: - ItemData(503 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 3, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Mercenary Goliaths"), - ItemNames.SIEGE_BREAKERS: - ItemData(504 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 4, SC2Race.TERRAN, - description="Mercenary Siege Tanks"), - ItemNames.HELS_ANGELS: - ItemData(505 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 5, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Mercenary Vikings"), - ItemNames.DUSK_WINGS: - ItemData(506 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 6, SC2Race.TERRAN, - description="Mercenary Banshees"), - ItemNames.JACKSONS_REVENGE: - ItemData(507 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 7, SC2Race.TERRAN, - description="Mercenary Battlecruiser"), - ItemNames.SKIBIS_ANGELS: - ItemData(508 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 8, SC2Race.TERRAN, - origin={"ext"}, - description="Mercenary Medics"), - ItemNames.DEATH_HEADS: - ItemData(509 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 9, SC2Race.TERRAN, - origin={"ext"}, - description="Mercenary Reapers"), - ItemNames.WINGED_NIGHTMARES: - ItemData(510 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 10, SC2Race.TERRAN, - classification=ItemClassification.progression, origin={"ext"}, - description="Mercenary Wraiths"), - ItemNames.MIDNIGHT_RIDERS: - ItemData(511 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 11, SC2Race.TERRAN, - origin={"ext"}, - description="Mercenary Liberators"), - ItemNames.BRYNHILDS: - ItemData(512 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 12, SC2Race.TERRAN, - classification=ItemClassification.progression, origin={"ext"}, - description="Mercenary Valkyries"), - ItemNames.JOTUN: - ItemData(513 + SC2WOL_ITEM_ID_OFFSET, "Mercenary", 13, SC2Race.TERRAN, - origin={"ext"}, - description="Mercenary Thor"), - - ItemNames.ULTRA_CAPACITORS: - ItemData(600 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 0, SC2Race.TERRAN, - description="Increases attack speed of units by 5% per weapon upgrade."), - ItemNames.VANADIUM_PLATING: - ItemData(601 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 1, SC2Race.TERRAN, - description="Increases the life of units by 5% per armor upgrade."), - ItemNames.ORBITAL_DEPOTS: - ItemData(602 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 2, SC2Race.TERRAN, - description="Supply depots are built instantly."), - ItemNames.MICRO_FILTERING: - ItemData(603 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 3, SC2Race.TERRAN, - description="Refineries produce Vespene gas 25% faster."), - ItemNames.AUTOMATED_REFINERY: - ItemData(604 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 4, SC2Race.TERRAN, - description="Eliminates the need for SCVs in vespene gas production."), - ItemNames.COMMAND_CENTER_REACTOR: - ItemData(605 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 5, SC2Race.TERRAN, - description="Command Centers can train two SCVs at once."), - ItemNames.RAVEN: - ItemData(606 + SC2WOL_ITEM_ID_OFFSET, "Unit", 22, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Aerial Caster unit."), - ItemNames.SCIENCE_VESSEL: - ItemData(607 + SC2WOL_ITEM_ID_OFFSET, "Unit", 23, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Aerial Caster unit. Can repair mechanical units."), - ItemNames.TECH_REACTOR: - ItemData(608 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 6, SC2Race.TERRAN, - description="Merges Tech Labs and Reactors into one add on structure to provide both functions."), - ItemNames.ORBITAL_STRIKE: - ItemData(609 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 7, SC2Race.TERRAN, - description="Trained units from Barracks are instantly deployed on rally point."), - ItemNames.BUNKER_SHRIKE_TURRET: - ItemData(610 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 6, SC2Race.TERRAN, - parent_item=ItemNames.BUNKER, - description="Adds an automated turret to Bunkers."), - ItemNames.BUNKER_FORTIFIED_BUNKER: - ItemData(611 + SC2WOL_ITEM_ID_OFFSET, "Armory 1", 7, SC2Race.TERRAN, - parent_item=ItemNames.BUNKER, - description="Bunkers have more life."), - ItemNames.PLANETARY_FORTRESS: - ItemData(612 + SC2WOL_ITEM_ID_OFFSET, "Building", 3, SC2Race.TERRAN, - classification=ItemClassification.progression, - description=inspect.cleandoc( - """ - Allows Command Centers to upgrade into a defensive structure with a turret and additional armor. - Planetary Fortresses cannot Lift Off, or cast Orbital Command spells. - """ - )), - ItemNames.PERDITION_TURRET: - ItemData(613 + SC2WOL_ITEM_ID_OFFSET, "Building", 4, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Automated defensive turret. Burrows down while no enemies are nearby."), - ItemNames.PREDATOR: - ItemData(614 + SC2WOL_ITEM_ID_OFFSET, "Unit", 24, SC2Race.TERRAN, - classification=ItemClassification.filler, - description="Anti-infantry specialist that deals area damage with each attack."), - ItemNames.HERCULES: - ItemData(615 + SC2WOL_ITEM_ID_OFFSET, "Unit", 25, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Massive transport ship."), - ItemNames.CELLULAR_REACTOR: - ItemData(616 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 8, SC2Race.TERRAN, - description="All Terran spellcasters get +100 starting and maximum energy."), - ItemNames.PROGRESSIVE_REGENERATIVE_BIO_STEEL: - ItemData(617 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade", 4, SC2Race.TERRAN, quantity=3, - classification= ItemClassification.progression, - description=inspect.cleandoc( - """ - Allows Terran mechanical units to regenerate health while not in combat. - Each level increases life regeneration speed. - """ - )), - ItemNames.HIVE_MIND_EMULATOR: - ItemData(618 + SC2WOL_ITEM_ID_OFFSET, "Building", 5, SC2Race.TERRAN, - ItemClassification.progression, - description="Defensive structure. Can permanently Mind Control Zerg units."), - ItemNames.PSI_DISRUPTER: - ItemData(619 + SC2WOL_ITEM_ID_OFFSET, "Building", 6, SC2Race.TERRAN, - classification=ItemClassification.progression, - description="Defensive structure. Slows the attack and movement speeds of all nearby Zerg units."), - ItemNames.STRUCTURE_ARMOR: - ItemData(620 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 9, SC2Race.TERRAN, - description="Increases armor of all Terran structures by 2.", origin={"ext"}), - ItemNames.HI_SEC_AUTO_TRACKING: - ItemData(621 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 10, SC2Race.TERRAN, - description="Increases attack range of all Terran structures by 1.", origin={"ext"}), - ItemNames.ADVANCED_OPTICS: - ItemData(622 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 11, SC2Race.TERRAN, - description="Increases attack range of all Terran mechanical units by 1.", origin={"ext"}), - ItemNames.ROGUE_FORCES: - ItemData(623 + SC2WOL_ITEM_ID_OFFSET, "Laboratory", 12, SC2Race.TERRAN, - description="Mercenary calldowns are no longer limited by charges.", origin={"ext"}), - - ItemNames.ZEALOT: - ItemData(700 + SC2WOL_ITEM_ID_OFFSET, "Unit", 0, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"wol", "lotv"}, - description="Powerful melee warrior. Can use the charge ability."), - ItemNames.STALKER: - ItemData(701 + SC2WOL_ITEM_ID_OFFSET, "Unit", 1, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"wol", "lotv"}, - description="Ranged attack strider. Can use the Blink ability."), - ItemNames.HIGH_TEMPLAR: - ItemData(702 + SC2WOL_ITEM_ID_OFFSET, "Unit", 2, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"wol", "lotv"}, - description="Potent psionic master. Can use the Feedback and Psionic Storm abilities. Can merge into an Archon."), - ItemNames.DARK_TEMPLAR: - ItemData(703 + SC2WOL_ITEM_ID_OFFSET, "Unit", 3, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"wol", "lotv"}, - description="Deadly warrior-assassin. Permanently cloaked. Can use the Shadow Fury ability."), - ItemNames.IMMORTAL: - ItemData(704 + SC2WOL_ITEM_ID_OFFSET, "Unit", 4, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"wol", "lotv"}, - description="Assault strider. Can use Barrier to absorb damage."), - ItemNames.COLOSSUS: - ItemData(705 + SC2WOL_ITEM_ID_OFFSET, "Unit", 5, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"wol", "lotv"}, - description="Battle strider with a powerful area attack. Can walk up and down cliffs. Attacks set fire to the ground, dealing extra damage to enemies over time."), - ItemNames.PHOENIX: - ItemData(706 + SC2WOL_ITEM_ID_OFFSET, "Unit", 6, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"wol", "lotv"}, - description="Air superiority starfighter. Can use Graviton Beam and Phasing Armor abilities."), - ItemNames.VOID_RAY: - ItemData(707 + SC2WOL_ITEM_ID_OFFSET, "Unit", 7, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"wol", "lotv"}, - description="Surgical strike craft. Has the Prismatic Alignment and Prismatic Range abilities."), - ItemNames.CARRIER: - ItemData(708 + SC2WOL_ITEM_ID_OFFSET, "Unit", 8, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"wol", "lotv"}, - description="Capital ship. Builds and launches Interceptors that attack enemy targets. Repair Drones heal nearby mechanical units."), - - # Filler items to fill remaining spots - ItemNames.STARTING_MINERALS: - ItemData(800 + SC2WOL_ITEM_ID_OFFSET, "Minerals", 15, SC2Race.ANY, quantity=0, - classification=ItemClassification.filler, - description="Increases the starting minerals for all missions."), - ItemNames.STARTING_VESPENE: - ItemData(801 + SC2WOL_ITEM_ID_OFFSET, "Vespene", 15, SC2Race.ANY, quantity=0, - classification=ItemClassification.filler, - description="Increases the starting vespene for all missions."), - ItemNames.STARTING_SUPPLY: - ItemData(802 + SC2WOL_ITEM_ID_OFFSET, "Supply", 2, SC2Race.ANY, quantity=0, - classification=ItemClassification.filler, - description="Increases the starting supply for all missions."), - # This item is used to "remove" location from the game. Never placed unless plando'd - ItemNames.NOTHING: - ItemData(803 + SC2WOL_ITEM_ID_OFFSET, "Nothing Group", 2, SC2Race.ANY, quantity=0, - classification=ItemClassification.trap, - description="Does nothing. Used to remove a location from the game."), - - # Nova gear - ItemNames.NOVA_GHOST_VISOR: - ItemData(900 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 0, SC2Race.TERRAN, origin={"nco"}, - description="Reveals the locations of enemy units in the fog of war around Nova. Can detect cloaked units."), - ItemNames.NOVA_RANGEFINDER_OCULUS: - ItemData(901 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 1, SC2Race.TERRAN, origin={"nco"}, - description="Increaases Nova's vision range and non-melee weapon attack range by 2. Also increases range of melee weapons by 1."), - ItemNames.NOVA_DOMINATION: - ItemData(902 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 2, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Gives Nova the ability to mind-control a target enemy unit."), - ItemNames.NOVA_BLINK: - ItemData(903 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 3, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Gives Nova the ability to teleport a short distance and cloak for 10s."), - ItemNames.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE: - ItemData(904 + SC2WOL_ITEM_ID_OFFSET, "Progressive Upgrade 2", 0, SC2Race.TERRAN, quantity=2, origin={"nco"}, - classification=ItemClassification.progression, - description=inspect.cleandoc( - """ - Level 1: Gives Nova the ability to cloak. - Level 2: Nova is permanently cloaked. - """ - )), - ItemNames.NOVA_ENERGY_SUIT_MODULE: - ItemData(905 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 4, SC2Race.TERRAN, origin={"nco"}, - description="Increases Nova's maximum energy and energy regeneration rate."), - ItemNames.NOVA_ARMORED_SUIT_MODULE: - ItemData(906 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 5, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Increases Nova's health by 100 and armour by 1. Nova also regenerates life quickly out of combat."), - ItemNames.NOVA_JUMP_SUIT_MODULE: - ItemData(907 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 6, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Increases Nova's movement speed and allows her to jump up and down cliffs."), - ItemNames.NOVA_C20A_CANISTER_RIFLE: - ItemData(908 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 7, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Allows Nova to equip the C20A Canister Rifle, which has a ranged attack and allows Nova to cast Snipe."), - ItemNames.NOVA_HELLFIRE_SHOTGUN: - ItemData(909 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 8, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Allows Nova to equip the Hellfire Shotgun, which has a short-range area attack in a cone and allows Nova to cast Penetrating Blast."), - ItemNames.NOVA_PLASMA_RIFLE: - ItemData(910 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 9, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Allows Nova to equip the Plasma Rifle, which has a rapidfire ranged attack and allows Nova to cast Plasma Shot."), - ItemNames.NOVA_MONOMOLECULAR_BLADE: - ItemData(911 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 10, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Allows Nova to equip the Monomolecular Blade, which has a melee attack and allows Nova to cast Dash Attack."), - ItemNames.NOVA_BLAZEFIRE_GUNBLADE: - ItemData(912 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 11, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Allows Nova to equip the Blazefire Gunblade, which has a melee attack and allows Nova to cast Fury of One."), - ItemNames.NOVA_STIM_INFUSION: - ItemData(913 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 12, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Gives Nova the ability to heal herself and temporarily increase her movement and attack speeds."), - ItemNames.NOVA_PULSE_GRENADES: - ItemData(914 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 13, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Gives Nova the ability to throw a grenade dealing large damage in an area."), - ItemNames.NOVA_FLASHBANG_GRENADES: - ItemData(915 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 14, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Gives Nova the ability to throw a grenade to stun enemies and disable detection in a large area."), - ItemNames.NOVA_IONIC_FORCE_FIELD: - ItemData(916 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 15, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Gives Nova the ability to shield herself temporarily."), - ItemNames.NOVA_HOLO_DECOY: - ItemData(917 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 16, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Gives Nova the ability to summon a decoy unit which enemies will prefer to target and takes reduced damage."), - ItemNames.NOVA_NUKE: - ItemData(918 + SC2WOL_ITEM_ID_OFFSET, "Nova Gear", 17, SC2Race.TERRAN, origin={"nco"}, - classification=ItemClassification.progression, - description="Gives Nova the ability to launch tactical nukes built from the Shadow Ops."), - - # HotS - ItemNames.ZERGLING: - ItemData(0 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 0, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Fast inexpensive melee attacker. Hatches in pairs from a single larva. Can morph into a Baneling."), - ItemNames.SWARM_QUEEN: - ItemData(1 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 1, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Ranged support caster. Can use the Spawn Creep Tumor and Rapid Transfusion abilities."), - ItemNames.ROACH: - ItemData(2 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 2, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Durable short ranged attacker. Regenerates life quickly when burrowed."), - ItemNames.HYDRALISK: - ItemData(3 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 3, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="High-damage generalist ranged attacker."), - ItemNames.ZERGLING_BANELING_ASPECT: - ItemData(4 + SC2HOTS_ITEM_ID_OFFSET, "Morph", 5, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Anti-ground suicide unit. Does damage over a small area on death."), - ItemNames.ABERRATION: - ItemData(5 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 5, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Durable melee attacker that deals heavy damage and can walk over other units."), - ItemNames.MUTALISK: - ItemData(6 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 6, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Fragile flying attacker. Attacks bounce between targets."), - ItemNames.SWARM_HOST: - ItemData(7 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 7, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Siege unit that attacks by rooting in place and continually spawning Locusts."), - ItemNames.INFESTOR: - ItemData(8 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 8, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Support caster that can move while burrowed. Can use the Fungal Growth, Parasitic Domination, and Consumption abilities."), - ItemNames.ULTRALISK: - ItemData(9 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 9, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Massive melee attacker. Has an area-damage cleave attack."), - ItemNames.SPORE_CRAWLER: - ItemData(10 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 10, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Anti-air defensive structure that can detect cloaked units."), - ItemNames.SPINE_CRAWLER: - ItemData(11 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 11, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"hots"}, - description="Anti-ground defensive structure."), - ItemNames.CORRUPTOR: - ItemData(12 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 12, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"ext"}, - description="Anti-air flying attacker specializing in taking down enemy capital ships."), - ItemNames.SCOURGE: - ItemData(13 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 13, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"bw", "ext"}, - description="Flying anti-air suicide unit. Hatches in pairs from a single larva."), - ItemNames.BROOD_QUEEN: - ItemData(14 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 4, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"bw", "ext"}, - description="Flying support caster. Can cast the Ocular Symbiote and Spawn Broodlings abilities."), - ItemNames.DEFILER: - ItemData(15 + SC2HOTS_ITEM_ID_OFFSET, "Unit", 14, SC2Race.ZERG, - classification=ItemClassification.progression, origin={"bw"}, - description="Support caster. Can use the Dark Swarm, Consume, and Plague abilities."), - - ItemNames.PROGRESSIVE_ZERG_MELEE_ATTACK: ItemData(100 + SC2HOTS_ITEM_ID_OFFSET, "Upgrade", 0, SC2Race.ZERG, quantity=3, origin={"hots"}), - ItemNames.PROGRESSIVE_ZERG_MISSILE_ATTACK: ItemData(101 + SC2HOTS_ITEM_ID_OFFSET, "Upgrade", 2, SC2Race.ZERG, quantity=3, origin={"hots"}), - ItemNames.PROGRESSIVE_ZERG_GROUND_CARAPACE: ItemData(102 + SC2HOTS_ITEM_ID_OFFSET, "Upgrade", 4, SC2Race.ZERG, quantity=3, origin={"hots"}), - ItemNames.PROGRESSIVE_ZERG_FLYER_ATTACK: ItemData(103 + SC2HOTS_ITEM_ID_OFFSET, "Upgrade", 6, SC2Race.ZERG, quantity=3, origin={"hots"}), - ItemNames.PROGRESSIVE_ZERG_FLYER_CARAPACE: ItemData(104 + SC2HOTS_ITEM_ID_OFFSET, "Upgrade", 8, SC2Race.ZERG, quantity=3, origin={"hots"}), - # Upgrade bundle 'number' values are used as indices to get affected 'number's - ItemNames.PROGRESSIVE_ZERG_WEAPON_UPGRADE: ItemData(105 + SC2HOTS_ITEM_ID_OFFSET, "Upgrade", 6, SC2Race.ZERG, quantity=3, origin={"hots"}), - ItemNames.PROGRESSIVE_ZERG_ARMOR_UPGRADE: ItemData(106 + SC2HOTS_ITEM_ID_OFFSET, "Upgrade", 7, SC2Race.ZERG, quantity=3, origin={"hots"}), - ItemNames.PROGRESSIVE_ZERG_GROUND_UPGRADE: ItemData(107 + SC2HOTS_ITEM_ID_OFFSET, "Upgrade", 8, SC2Race.ZERG, quantity=3, origin={"hots"}), - ItemNames.PROGRESSIVE_ZERG_FLYER_UPGRADE: ItemData(108 + SC2HOTS_ITEM_ID_OFFSET, "Upgrade", 9, SC2Race.ZERG, quantity=3, origin={"hots"}), - ItemNames.PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE: ItemData(109 + SC2HOTS_ITEM_ID_OFFSET, "Upgrade", 10, SC2Race.ZERG, quantity=3, origin={"hots"}), - - ItemNames.ZERGLING_HARDENED_CARAPACE: - ItemData(200 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 0, SC2Race.ZERG, parent_item=ItemNames.ZERGLING, - origin={"hots"}, description="Increases Zergling health by +10."), - ItemNames.ZERGLING_ADRENAL_OVERLOAD: - ItemData(201 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 1, SC2Race.ZERG, parent_item=ItemNames.ZERGLING, - origin={"hots"}, description="Increases Zergling attack speed."), - ItemNames.ZERGLING_METABOLIC_BOOST: - ItemData(202 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 2, SC2Race.ZERG, parent_item=ItemNames.ZERGLING, - origin={"hots"}, classification=ItemClassification.filler, - description="Increases Zergling movement speed."), - ItemNames.ROACH_HYDRIODIC_BILE: - ItemData(203 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 3, SC2Race.ZERG, parent_item=ItemNames.ROACH, - origin={"hots"}, description="Roaches deal +8 damage to light targets."), - ItemNames.ROACH_ADAPTIVE_PLATING: - ItemData(204 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 4, SC2Race.ZERG, parent_item=ItemNames.ROACH, - origin={"hots"}, description="Roaches gain +3 armour when their life is below 50%."), - ItemNames.ROACH_TUNNELING_CLAWS: - ItemData(205 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 5, SC2Race.ZERG, parent_item=ItemNames.ROACH, - origin={"hots"}, classification=ItemClassification.filler, - description="Allows Roaches to move while burrowed."), - ItemNames.HYDRALISK_FRENZY: - ItemData(206 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 6, SC2Race.ZERG, parent_item=ItemNames.HYDRALISK, - origin={"hots"}, - description="Allows Hydralisks to use the Frenzy ability, which increases their attack speed by 50%."), - ItemNames.HYDRALISK_ANCILLARY_CARAPACE: - ItemData(207 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 7, SC2Race.ZERG, parent_item=ItemNames.HYDRALISK, - origin={"hots"}, classification=ItemClassification.filler, description="Hydralisks gain +20 health."), - ItemNames.HYDRALISK_GROOVED_SPINES: - ItemData(208 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 8, SC2Race.ZERG, parent_item=ItemNames.HYDRALISK, - origin={"hots"}, description="Hydralisks gain +1 range."), - ItemNames.BANELING_CORROSIVE_ACID: - ItemData(209 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 9, SC2Race.ZERG, - parent_item=ItemNames.ZERGLING_BANELING_ASPECT, origin={"hots"}, - description="Increases the damage banelings deal to their primary target. Splash damage remains the same."), - ItemNames.BANELING_RUPTURE: - ItemData(210 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 10, SC2Race.ZERG, - parent_item=ItemNames.ZERGLING_BANELING_ASPECT, origin={"hots"}, - classification=ItemClassification.filler, - description="Increases the splash radius of baneling attacks."), - ItemNames.BANELING_REGENERATIVE_ACID: - ItemData(211 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 11, SC2Race.ZERG, - parent_item=ItemNames.ZERGLING_BANELING_ASPECT, origin={"hots"}, - classification=ItemClassification.filler, - description="Banelings will heal nearby friendly units when they explode."), - ItemNames.MUTALISK_VICIOUS_GLAIVE: - ItemData(212 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 12, SC2Race.ZERG, parent_item=ItemNames.MUTALISK, - origin={"hots"}, description="Mutalisks attacks will bounce an additional 3 times."), - ItemNames.MUTALISK_RAPID_REGENERATION: - ItemData(213 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 13, SC2Race.ZERG, parent_item=ItemNames.MUTALISK, - origin={"hots"}, description="Mutalisks will regenerate quickly when out of combat."), - ItemNames.MUTALISK_SUNDERING_GLAIVE: - ItemData(214 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 14, SC2Race.ZERG, parent_item=ItemNames.MUTALISK, - origin={"hots"}, description="Mutalisks deal increased damage to their primary target."), - ItemNames.SWARM_HOST_BURROW: - ItemData(215 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 15, SC2Race.ZERG, parent_item=ItemNames.SWARM_HOST, - origin={"hots"}, classification=ItemClassification.filler, - description="Allows Swarm Hosts to burrow instead of root to spawn locusts."), - ItemNames.SWARM_HOST_RAPID_INCUBATION: - ItemData(216 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 16, SC2Race.ZERG, parent_item=ItemNames.SWARM_HOST, - origin={"hots"}, description="Swarm Hosts will spawn locusts 20% faster."), - ItemNames.SWARM_HOST_PRESSURIZED_GLANDS: - ItemData(217 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 17, SC2Race.ZERG, parent_item=ItemNames.SWARM_HOST, - origin={"hots"}, classification=ItemClassification.progression, - description="Allows Swarm Host Locusts to attack air targets."), - ItemNames.ULTRALISK_BURROW_CHARGE: - ItemData(218 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 18, SC2Race.ZERG, parent_item=ItemNames.ULTRALISK, - origin={"hots"}, - description="Allows Ultralisks to burrow and charge at enemy units, knocking back and stunning units when it emerges."), - ItemNames.ULTRALISK_TISSUE_ASSIMILATION: - ItemData(219 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 19, SC2Race.ZERG, parent_item=ItemNames.ULTRALISK, - origin={"hots"}, description="Ultralisks recover health when they deal damage."), - ItemNames.ULTRALISK_MONARCH_BLADES: - ItemData(220 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 20, SC2Race.ZERG, parent_item=ItemNames.ULTRALISK, - origin={"hots"}, description="Ultralisks gain increased splash damage."), - ItemNames.CORRUPTOR_CAUSTIC_SPRAY: - ItemData(221 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 21, SC2Race.ZERG, parent_item=ItemNames.CORRUPTOR, - origin={"ext"}, - description="Allows Corruptors to use the Caustic Spray ability, which deals ramping damage to buildings over time."), - ItemNames.CORRUPTOR_CORRUPTION: - ItemData(222 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 22, SC2Race.ZERG, parent_item=ItemNames.CORRUPTOR, - origin={"ext"}, - description="Allows Corruptors to use the Corruption ability, which causes a target enemy unit to take increased damage."), - ItemNames.SCOURGE_VIRULENT_SPORES: - ItemData(223 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 23, SC2Race.ZERG, parent_item=ItemNames.SCOURGE, - origin={"ext"}, description="Scourge will deal splash damage."), - ItemNames.SCOURGE_RESOURCE_EFFICIENCY: - ItemData(224 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 24, SC2Race.ZERG, parent_item=ItemNames.SCOURGE, - origin={"ext"}, classification=ItemClassification.progression, - description="Reduces the cost of Scourge by 50 gas per egg."), - ItemNames.SCOURGE_SWARM_SCOURGE: - ItemData(225 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 25, SC2Race.ZERG, parent_item=ItemNames.SCOURGE, - origin={"ext"}, description="An extra Scourge will be built from each egg at no additional cost."), - ItemNames.ZERGLING_SHREDDING_CLAWS: - ItemData(226 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 26, SC2Race.ZERG, parent_item=ItemNames.ZERGLING, - origin={"ext"}, description="Zergling attacks will temporarily reduce their target's armour to 0."), - ItemNames.ROACH_GLIAL_RECONSTITUTION: - ItemData(227 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 27, SC2Race.ZERG, parent_item=ItemNames.ROACH, - origin={"ext"}, description="Increases Roach movement speed."), - ItemNames.ROACH_ORGANIC_CARAPACE: - ItemData(228 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 28, SC2Race.ZERG, parent_item=ItemNames.ROACH, - origin={"ext"}, description="Increases Roach health by +25."), - ItemNames.HYDRALISK_MUSCULAR_AUGMENTS: - ItemData(229 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 1", 29, SC2Race.ZERG, parent_item=ItemNames.HYDRALISK, - origin={"bw"}, description="Increases Hydralisk movement speed."), - ItemNames.HYDRALISK_RESOURCE_EFFICIENCY: - ItemData(230 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 0, SC2Race.ZERG, parent_item=ItemNames.HYDRALISK, - origin={"bw"}, description="Reduces Hydralisk resource cost by 25/25 and supply cost by 1."), - ItemNames.BANELING_CENTRIFUGAL_HOOKS: - ItemData(231 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 1, SC2Race.ZERG, - parent_item=ItemNames.ZERGLING_BANELING_ASPECT, origin={"ext"}, - description="Increases the movement speed of Banelings."), - ItemNames.BANELING_TUNNELING_JAWS: - ItemData(232 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 2, SC2Race.ZERG, - parent_item=ItemNames.ZERGLING_BANELING_ASPECT, origin={"ext"}, - description="Allows Banelings to move while burrowed."), - ItemNames.BANELING_RAPID_METAMORPH: - ItemData(233 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 3, SC2Race.ZERG, - parent_item=ItemNames.ZERGLING_BANELING_ASPECT, origin={"ext"}, description="Banelings morph faster."), - ItemNames.MUTALISK_SEVERING_GLAIVE: - ItemData(234 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 4, SC2Race.ZERG, parent_item=ItemNames.MUTALISK, - origin={"ext"}, description="Mutalisk bounce attacks will deal full damage."), - ItemNames.MUTALISK_AERODYNAMIC_GLAIVE_SHAPE: - ItemData(235 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 5, SC2Race.ZERG, parent_item=ItemNames.MUTALISK, - origin={"ext"}, description="Increases the attack range of Mutalisks by 2."), - ItemNames.SWARM_HOST_LOCUST_METABOLIC_BOOST: - ItemData(236 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 6, SC2Race.ZERG, parent_item=ItemNames.SWARM_HOST, - origin={"ext"}, classification=ItemClassification.filler, - description="Increases Locust movement speed."), - ItemNames.SWARM_HOST_ENDURING_LOCUSTS: - ItemData(237 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 7, SC2Race.ZERG, parent_item=ItemNames.SWARM_HOST, - origin={"ext"}, description="Increases the duration of Swarm Hosts' Locusts by 10s."), - ItemNames.SWARM_HOST_ORGANIC_CARAPACE: - ItemData(238 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 8, SC2Race.ZERG, parent_item=ItemNames.SWARM_HOST, - origin={"ext"}, description="Increases Swarm Host health by +40."), - ItemNames.SWARM_HOST_RESOURCE_EFFICIENCY: - ItemData(239 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 9, SC2Race.ZERG, parent_item=ItemNames.SWARM_HOST, - origin={"ext"}, description="Reduces Swarm Host resource cost by 100/25."), - ItemNames.ULTRALISK_ANABOLIC_SYNTHESIS: - ItemData(240 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 10, SC2Race.ZERG, parent_item=ItemNames.ULTRALISK, - origin={"bw"}, classification=ItemClassification.filler), - ItemNames.ULTRALISK_CHITINOUS_PLATING: - ItemData(241 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 11, SC2Race.ZERG, parent_item=ItemNames.ULTRALISK, - origin={"bw"}), - ItemNames.ULTRALISK_ORGANIC_CARAPACE: - ItemData(242 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 12, SC2Race.ZERG, parent_item=ItemNames.ULTRALISK, - origin={"ext"}), - ItemNames.ULTRALISK_RESOURCE_EFFICIENCY: - ItemData(243 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 13, SC2Race.ZERG, parent_item=ItemNames.ULTRALISK, - origin={"bw"}), - ItemNames.DEVOURER_CORROSIVE_SPRAY: - ItemData(244 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 14, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_DEVOURER_ASPECT, origin={"ext"}), - ItemNames.DEVOURER_GAPING_MAW: - ItemData(245 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 15, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_DEVOURER_ASPECT, origin={"ext"}), - ItemNames.DEVOURER_IMPROVED_OSMOSIS: - ItemData(246 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 16, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_DEVOURER_ASPECT, origin={"ext"}, - classification=ItemClassification.filler), - ItemNames.DEVOURER_PRESCIENT_SPORES: - ItemData(247 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 17, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_DEVOURER_ASPECT, origin={"ext"}), - ItemNames.GUARDIAN_PROLONGED_DISPERSION: - ItemData(248 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 18, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT, origin={"ext"}), - ItemNames.GUARDIAN_PRIMAL_ADAPTATION: - ItemData(249 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 19, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT, origin={"ext"}), - ItemNames.GUARDIAN_SORONAN_ACID: - ItemData(250 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 20, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT, origin={"ext"}), - ItemNames.IMPALER_ADAPTIVE_TALONS: - ItemData(251 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 21, SC2Race.ZERG, - parent_item=ItemNames.HYDRALISK_IMPALER_ASPECT, origin={"ext"}, - classification=ItemClassification.filler), - ItemNames.IMPALER_SECRETION_GLANDS: - ItemData(252 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 22, SC2Race.ZERG, - parent_item=ItemNames.HYDRALISK_IMPALER_ASPECT, origin={"ext"}), - ItemNames.IMPALER_HARDENED_TENTACLE_SPINES: - ItemData(253 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 23, SC2Race.ZERG, - parent_item=ItemNames.HYDRALISK_IMPALER_ASPECT, origin={"ext"}), - ItemNames.LURKER_SEISMIC_SPINES: - ItemData(254 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 24, SC2Race.ZERG, - parent_item=ItemNames.HYDRALISK_LURKER_ASPECT, origin={"ext"}), - ItemNames.LURKER_ADAPTED_SPINES: - ItemData(255 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 25, SC2Race.ZERG, - parent_item=ItemNames.HYDRALISK_LURKER_ASPECT, origin={"ext"}), - ItemNames.RAVAGER_POTENT_BILE: - ItemData(256 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 26, SC2Race.ZERG, - parent_item=ItemNames.ROACH_RAVAGER_ASPECT, origin={"ext"}), - ItemNames.RAVAGER_BLOATED_BILE_DUCTS: - ItemData(257 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 27, SC2Race.ZERG, - parent_item=ItemNames.ROACH_RAVAGER_ASPECT, origin={"ext"}), - ItemNames.RAVAGER_DEEP_TUNNEL: - ItemData(258 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 28, SC2Race.ZERG, - parent_item=ItemNames.ROACH_RAVAGER_ASPECT, origin={"ext"}), - ItemNames.VIPER_PARASITIC_BOMB: - ItemData(259 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 2", 29, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_VIPER_ASPECT, origin={"ext"}), - ItemNames.VIPER_PARALYTIC_BARBS: - ItemData(260 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 0, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_VIPER_ASPECT, origin={"ext"}), - ItemNames.VIPER_VIRULENT_MICROBES: - ItemData(261 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 1, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_VIPER_ASPECT, origin={"ext"}), - ItemNames.BROOD_LORD_POROUS_CARTILAGE: - ItemData(262 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 2, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT, origin={"ext"}), - ItemNames.BROOD_LORD_EVOLVED_CARAPACE: - ItemData(263 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 3, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT, origin={"ext"}), - ItemNames.BROOD_LORD_SPLITTER_MITOSIS: - ItemData(264 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 4, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT, origin={"ext"}), - ItemNames.BROOD_LORD_RESOURCE_EFFICIENCY: - ItemData(265 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 5, SC2Race.ZERG, - parent_item=ItemNames.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT, origin={"ext"}), - ItemNames.INFESTOR_INFESTED_TERRAN: - ItemData(266 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 6, SC2Race.ZERG, parent_item=ItemNames.INFESTOR, - origin={"ext"}), - ItemNames.INFESTOR_MICROBIAL_SHROUD: - ItemData(267 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 7, SC2Race.ZERG, parent_item=ItemNames.INFESTOR, - origin={"ext"}), - ItemNames.SWARM_QUEEN_SPAWN_LARVAE: - ItemData(268 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 8, SC2Race.ZERG, parent_item=ItemNames.SWARM_QUEEN, - origin={"ext"}), - ItemNames.SWARM_QUEEN_DEEP_TUNNEL: - ItemData(269 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 9, SC2Race.ZERG, parent_item=ItemNames.SWARM_QUEEN, - origin={"ext"}), - ItemNames.SWARM_QUEEN_ORGANIC_CARAPACE: - ItemData(270 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 10, SC2Race.ZERG, parent_item=ItemNames.SWARM_QUEEN, - origin={"ext"}, classification=ItemClassification.filler), - ItemNames.SWARM_QUEEN_BIO_MECHANICAL_TRANSFUSION: - ItemData(271 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 11, SC2Race.ZERG, parent_item=ItemNames.SWARM_QUEEN, - origin={"ext"}), - ItemNames.SWARM_QUEEN_RESOURCE_EFFICIENCY: - ItemData(272 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 12, SC2Race.ZERG, parent_item=ItemNames.SWARM_QUEEN, - origin={"ext"}), - ItemNames.SWARM_QUEEN_INCUBATOR_CHAMBER: - ItemData(273 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 13, SC2Race.ZERG, parent_item=ItemNames.SWARM_QUEEN, - origin={"ext"}), - ItemNames.BROOD_QUEEN_FUNGAL_GROWTH: - ItemData(274 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 14, SC2Race.ZERG, parent_item=ItemNames.BROOD_QUEEN, - origin={"ext"}), - ItemNames.BROOD_QUEEN_ENSNARE: - ItemData(275 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 15, SC2Race.ZERG, parent_item=ItemNames.BROOD_QUEEN, - origin={"ext"}), - ItemNames.BROOD_QUEEN_ENHANCED_MITOCHONDRIA: - ItemData(276 + SC2HOTS_ITEM_ID_OFFSET, "Mutation 3", 16, SC2Race.ZERG, parent_item=ItemNames.BROOD_QUEEN, - origin={"ext"}), - - ItemNames.ZERGLING_RAPTOR_STRAIN: - ItemData(300 + SC2HOTS_ITEM_ID_OFFSET, "Strain", 0, SC2Race.ZERG, parent_item=ItemNames.ZERGLING, - origin={"hots"}, - description="Allows Zerglings to jump up and down cliffs and leap onto enemies. Also increases Zergling attack damage by 2."), - ItemNames.ZERGLING_SWARMLING_STRAIN: - ItemData(301 + SC2HOTS_ITEM_ID_OFFSET, "Strain", 1, SC2Race.ZERG, parent_item=ItemNames.ZERGLING, - origin={"hots"}, - description="Zerglings will spawn instantly and with an extra Zergling per egg at no additional cost."), - ItemNames.ROACH_VILE_STRAIN: - ItemData(302 + SC2HOTS_ITEM_ID_OFFSET, "Strain", 2, SC2Race.ZERG, parent_item=ItemNames.ROACH, origin={"hots"}, - description="Roach attacks will slow the movement and attack speed of enemies."), - ItemNames.ROACH_CORPSER_STRAIN: - ItemData(303 + SC2HOTS_ITEM_ID_OFFSET, "Strain", 3, SC2Race.ZERG, parent_item=ItemNames.ROACH, origin={"hots"}, - description="Units killed after being attacked by Roaches will spawn 2 Roachlings."), - ItemNames.HYDRALISK_IMPALER_ASPECT: - ItemData(304 + SC2HOTS_ITEM_ID_OFFSET, "Morph", 0, SC2Race.ZERG, origin={"hots"}, - classification=ItemClassification.progression, - description="Allows Hydralisks to morph into Impalers."), - ItemNames.HYDRALISK_LURKER_ASPECT: - ItemData(305 + SC2HOTS_ITEM_ID_OFFSET, "Morph", 1, SC2Race.ZERG, origin={"hots"}, - classification=ItemClassification.progression, description="Allows Hydralisks to morph into Lurkers."), - ItemNames.BANELING_SPLITTER_STRAIN: - ItemData(306 + SC2HOTS_ITEM_ID_OFFSET, "Strain", 6, SC2Race.ZERG, - parent_item=ItemNames.ZERGLING_BANELING_ASPECT, origin={"hots"}, - description="Banelings will split into two smaller Splitterlings on exploding."), - ItemNames.BANELING_HUNTER_STRAIN: - ItemData(307 + SC2HOTS_ITEM_ID_OFFSET, "Strain", 7, SC2Race.ZERG, - parent_item=ItemNames.ZERGLING_BANELING_ASPECT, origin={"hots"}, - description="Allows Banelings to jump up and down cliffs and leap onto enemies."), - ItemNames.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT: - ItemData(308 + SC2HOTS_ITEM_ID_OFFSET, "Morph", 2, SC2Race.ZERG, origin={"hots"}, - classification=ItemClassification.progression, - description="Allows Mutalisks and Corruptors to morph into Brood Lords."), - ItemNames.MUTALISK_CORRUPTOR_VIPER_ASPECT: - ItemData(309 + SC2HOTS_ITEM_ID_OFFSET, "Morph", 3, SC2Race.ZERG, origin={"hots"}, - classification=ItemClassification.progression, - description="Allows Mutalisks and Corruptors to morph into Vipers."), - ItemNames.SWARM_HOST_CARRION_STRAIN: - ItemData(310 + SC2HOTS_ITEM_ID_OFFSET, "Strain", 10, SC2Race.ZERG, parent_item=ItemNames.SWARM_HOST, - origin={"hots"}, description="Swarm Hosts will spawn Flying Locusts."), - ItemNames.SWARM_HOST_CREEPER_STRAIN: - ItemData(311 + SC2HOTS_ITEM_ID_OFFSET, "Strain", 11, SC2Race.ZERG, parent_item=ItemNames.SWARM_HOST, - origin={"hots"}, classification=ItemClassification.filler, - description="Allows Swarm Hosts to teleport to any creep on the map in vision. Swarm Hosts will spread creep around them when rooted or burrowed."), - ItemNames.ULTRALISK_NOXIOUS_STRAIN: - ItemData(312 + SC2HOTS_ITEM_ID_OFFSET, "Strain", 12, SC2Race.ZERG, parent_item=ItemNames.ULTRALISK, - origin={"hots"}, classification=ItemClassification.filler, - description="Ultralisks will periodically spread poison, damaging nearby biological enemies."), - ItemNames.ULTRALISK_TORRASQUE_STRAIN: - ItemData(313 + SC2HOTS_ITEM_ID_OFFSET, "Strain", 13, SC2Race.ZERG, parent_item=ItemNames.ULTRALISK, - origin={"hots"}, description="Ultralisks will revive after being killed."), - - ItemNames.KERRIGAN_KINETIC_BLAST: ItemData(400 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 0, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_HEROIC_FORTITUDE: ItemData(401 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 1, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_LEAPING_STRIKE: ItemData(402 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 2, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_CRUSHING_GRIP: ItemData(403 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 3, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_CHAIN_REACTION: ItemData(404 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 4, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_PSIONIC_SHIFT: ItemData(405 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 5, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_ZERGLING_RECONSTITUTION: ItemData(406 + SC2HOTS_ITEM_ID_OFFSET, "Evolution Pit", 0, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.filler), - ItemNames.KERRIGAN_IMPROVED_OVERLORDS: ItemData(407 + SC2HOTS_ITEM_ID_OFFSET, "Evolution Pit", 1, SC2Race.ZERG, origin={"hots"}), - ItemNames.KERRIGAN_AUTOMATED_EXTRACTORS: ItemData(408 + SC2HOTS_ITEM_ID_OFFSET, "Evolution Pit", 2, SC2Race.ZERG, origin={"hots"}), - ItemNames.KERRIGAN_WILD_MUTATION: ItemData(409 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 6, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_SPAWN_BANELINGS: ItemData(410 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 7, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_MEND: ItemData(411 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 8, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_TWIN_DRONES: ItemData(412 + SC2HOTS_ITEM_ID_OFFSET, "Evolution Pit", 3, SC2Race.ZERG, origin={"hots"}), - ItemNames.KERRIGAN_MALIGNANT_CREEP: ItemData(413 + SC2HOTS_ITEM_ID_OFFSET, "Evolution Pit", 4, SC2Race.ZERG, origin={"hots"}), - ItemNames.KERRIGAN_VESPENE_EFFICIENCY: ItemData(414 + SC2HOTS_ITEM_ID_OFFSET, "Evolution Pit", 5, SC2Race.ZERG, origin={"hots"}), - ItemNames.KERRIGAN_INFEST_BROODLINGS: ItemData(415 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 9, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_FURY: ItemData(416 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 10, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_ABILITY_EFFICIENCY: ItemData(417 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 11, SC2Race.ZERG, origin={"hots"}), - ItemNames.KERRIGAN_APOCALYPSE: ItemData(418 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 12, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_SPAWN_LEVIATHAN: ItemData(419 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 13, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - ItemNames.KERRIGAN_DROP_PODS: ItemData(420 + SC2HOTS_ITEM_ID_OFFSET, "Ability", 14, SC2Race.ZERG, origin={"hots"}, classification=ItemClassification.progression), - # Handled separately from other abilities - ItemNames.KERRIGAN_PRIMAL_FORM: ItemData(421 + SC2HOTS_ITEM_ID_OFFSET, "Primal Form", 0, SC2Race.ZERG, origin={"hots"}), - - ItemNames.KERRIGAN_LEVELS_10: ItemData(500 + SC2HOTS_ITEM_ID_OFFSET, "Level", 10, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression), - ItemNames.KERRIGAN_LEVELS_9: ItemData(501 + SC2HOTS_ITEM_ID_OFFSET, "Level", 9, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression), - ItemNames.KERRIGAN_LEVELS_8: ItemData(502 + SC2HOTS_ITEM_ID_OFFSET, "Level", 8, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression), - ItemNames.KERRIGAN_LEVELS_7: ItemData(503 + SC2HOTS_ITEM_ID_OFFSET, "Level", 7, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression), - ItemNames.KERRIGAN_LEVELS_6: ItemData(504 + SC2HOTS_ITEM_ID_OFFSET, "Level", 6, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression), - ItemNames.KERRIGAN_LEVELS_5: ItemData(505 + SC2HOTS_ITEM_ID_OFFSET, "Level", 5, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression), - ItemNames.KERRIGAN_LEVELS_4: ItemData(506 + SC2HOTS_ITEM_ID_OFFSET, "Level", 4, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression_skip_balancing), - ItemNames.KERRIGAN_LEVELS_3: ItemData(507 + SC2HOTS_ITEM_ID_OFFSET, "Level", 3, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression_skip_balancing), - ItemNames.KERRIGAN_LEVELS_2: ItemData(508 + SC2HOTS_ITEM_ID_OFFSET, "Level", 2, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression_skip_balancing), - ItemNames.KERRIGAN_LEVELS_1: ItemData(509 + SC2HOTS_ITEM_ID_OFFSET, "Level", 1, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression_skip_balancing), - ItemNames.KERRIGAN_LEVELS_14: ItemData(510 + SC2HOTS_ITEM_ID_OFFSET, "Level", 14, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression), - ItemNames.KERRIGAN_LEVELS_35: ItemData(511 + SC2HOTS_ITEM_ID_OFFSET, "Level", 35, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression), - ItemNames.KERRIGAN_LEVELS_70: ItemData(512 + SC2HOTS_ITEM_ID_OFFSET, "Level", 70, SC2Race.ZERG, origin={"hots"}, quantity=0, classification=ItemClassification.progression), - - # Zerg Mercs - ItemNames.INFESTED_MEDICS: ItemData(600 + SC2HOTS_ITEM_ID_OFFSET, "Mercenary", 0, SC2Race.ZERG, origin={"ext"}), - ItemNames.INFESTED_SIEGE_TANKS: ItemData(601 + SC2HOTS_ITEM_ID_OFFSET, "Mercenary", 1, SC2Race.ZERG, origin={"ext"}), - ItemNames.INFESTED_BANSHEES: ItemData(602 + SC2HOTS_ITEM_ID_OFFSET, "Mercenary", 2, SC2Race.ZERG, origin={"ext"}), - - # Misc Upgrades - ItemNames.OVERLORD_VENTRAL_SACS: ItemData(700 + SC2HOTS_ITEM_ID_OFFSET, "Evolution Pit", 6, SC2Race.ZERG, origin={"bw"}), - - # Morphs - ItemNames.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT: ItemData(800 + SC2HOTS_ITEM_ID_OFFSET, "Morph", 6, SC2Race.ZERG, origin={"bw"}), - ItemNames.MUTALISK_CORRUPTOR_DEVOURER_ASPECT: ItemData(801 + SC2HOTS_ITEM_ID_OFFSET, "Morph", 7, SC2Race.ZERG, origin={"bw"}), - ItemNames.ROACH_RAVAGER_ASPECT: ItemData(802 + SC2HOTS_ITEM_ID_OFFSET, "Morph", 8, SC2Race.ZERG, origin={"ext"}), - - - # Protoss Units (those that aren't as items in WoL (Prophecy)) - ItemNames.OBSERVER: ItemData(0 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 9, SC2Race.PROTOSS, - classification=ItemClassification.filler, origin={"wol"}, - description="Flying spy. Cloak renders the unit invisible to enemies without detection."), - ItemNames.CENTURION: ItemData(1 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 10, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Powerful melee warrior. Has the Shadow Charge and Darkcoil abilities."), - ItemNames.SENTINEL: ItemData(2 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 11, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Powerful melee warrior. Has the Charge and Reconstruction abilities."), - ItemNames.SUPPLICANT: ItemData(3 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 12, SC2Race.PROTOSS, - classification=ItemClassification.filler, important_for_filtering=True, origin={"ext"}, - description="Powerful melee warrior. Has powerful damage resistant shields."), - ItemNames.INSTIGATOR: ItemData(4 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 13, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"ext"}, - description="Ranged support strider. Can store multiple Blink charges."), - ItemNames.SLAYER: ItemData(5 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 14, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"ext"}, - description="Ranged attack strider. Can use the Phase Blink and Phasing Armor abilities."), - ItemNames.SENTRY: ItemData(6 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 15, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Robotic support unit can use the Guardian Shield ability and restore the shields of nearby Protoss units."), - ItemNames.ENERGIZER: ItemData(7 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 16, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Robotic support unit. Can use the Chrono Beam ability and become stationary to power nearby structures."), - ItemNames.HAVOC: ItemData(8 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 17, SC2Race.PROTOSS, - origin={"lotv"}, important_for_filtering=True, - description="Robotic support unit. Can use the Target Lock and Force Field abilities and increase the range of nearby Protoss units."), - ItemNames.SIGNIFIER: ItemData(9 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 18, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"ext"}, - description="Potent permanently cloaked psionic master. Can use the Feedback and Crippling Psionic Storm abilities. Can merge into an Archon."), - ItemNames.ASCENDANT: ItemData(10 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 19, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Potent psionic master. Can use the Psionic Orb, Mind Blast, and Sacrifice abilities."), - ItemNames.AVENGER: ItemData(11 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 20, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Deadly warrior-assassin. Permanently cloaked. Recalls to the nearest Dark Shrine upon death."), - ItemNames.BLOOD_HUNTER: ItemData(12 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 21, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Deadly warrior-assassin. Permanently cloaked. Can use the Void Stasis ability."), - ItemNames.DRAGOON: ItemData(13 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 22, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Ranged assault strider. Has enhanced health and damage."), - ItemNames.DARK_ARCHON: ItemData(14 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 23, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Potent psionic master. Can use the Confuse and Mind Control abilities."), - ItemNames.ADEPT: ItemData(15 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 24, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Ranged specialist. Can use the Psionic Transfer ability."), - ItemNames.WARP_PRISM: ItemData(16 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 25, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"ext"}, - description="Flying transport. Can carry units and become stationary to deploy a power field."), - ItemNames.ANNIHILATOR: ItemData(17 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 26, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Assault Strider. Can use the Shadow Cannon ability to damage air and ground units."), - ItemNames.VANGUARD: ItemData(18 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 27, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Assault Strider. Deals splash damage around the primary target."), - ItemNames.WRATHWALKER: ItemData(19 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 28, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Battle strider with a powerful single target attack. Can walk up and down cliffs."), - ItemNames.REAVER: ItemData(20 + SC2LOTV_ITEM_ID_OFFSET, "Unit", 29, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Area damage siege unit. Builds and launches explosive Scarabs for high burst damage."), - ItemNames.DISRUPTOR: ItemData(21 + SC2LOTV_ITEM_ID_OFFSET, "Unit 2", 0, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"ext"}, - description="Robotic disruption unit. Can use the Purification Nova ability to deal heavy area damage."), - ItemNames.MIRAGE: ItemData(22 + SC2LOTV_ITEM_ID_OFFSET, "Unit 2", 1, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Air superiority starfighter. Can use Graviton Beam and Phasing Armor abilities."), - ItemNames.CORSAIR: ItemData(23 + SC2LOTV_ITEM_ID_OFFSET, "Unit 2", 2, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Air superiority starfighter. Can use the Disruption Web ability."), - ItemNames.DESTROYER: ItemData(24 + SC2LOTV_ITEM_ID_OFFSET, "Unit 2", 3, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Area assault craft. Can use the Destruction Beam ability to attack multiple units at once."), - ItemNames.SCOUT: ItemData(25 + SC2LOTV_ITEM_ID_OFFSET, "Unit 2", 4, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"ext"}, - description="Versatile high-speed fighter."), - ItemNames.TEMPEST: ItemData(26 + SC2LOTV_ITEM_ID_OFFSET, "Unit 2", 5, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Siege artillery craft. Attacks from long range. Can use the Disintegration ability."), - ItemNames.MOTHERSHIP: ItemData(27 + SC2LOTV_ITEM_ID_OFFSET, "Unit 2", 6, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Ultimate Protoss vessel, Can use the Vortex and Mass Recall abilities. Cloaks nearby units and structures."), - ItemNames.ARBITER: ItemData(28 + SC2LOTV_ITEM_ID_OFFSET, "Unit 2", 7, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="Army support craft. Has the Stasis Field and Recall abilities. Cloaks nearby units."), - ItemNames.ORACLE: ItemData(29 + SC2LOTV_ITEM_ID_OFFSET, "Unit 2", 8, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"ext"}, - description="Flying caster. Can use the Revelation and Stasis Ward abilities."), - - # Protoss Upgrades - ItemNames.PROGRESSIVE_PROTOSS_GROUND_WEAPON: ItemData(100 + SC2LOTV_ITEM_ID_OFFSET, "Upgrade", 0, SC2Race.PROTOSS, quantity=3, origin={"wol", "lotv"}), - ItemNames.PROGRESSIVE_PROTOSS_GROUND_ARMOR: ItemData(101 + SC2LOTV_ITEM_ID_OFFSET, "Upgrade", 2, SC2Race.PROTOSS, quantity=3, origin={"wol", "lotv"}), - ItemNames.PROGRESSIVE_PROTOSS_SHIELDS: ItemData(102 + SC2LOTV_ITEM_ID_OFFSET, "Upgrade", 4, SC2Race.PROTOSS, quantity=3, origin={"wol", "lotv"}), - ItemNames.PROGRESSIVE_PROTOSS_AIR_WEAPON: ItemData(103 + SC2LOTV_ITEM_ID_OFFSET, "Upgrade", 6, SC2Race.PROTOSS, quantity=3, origin={"wol", "lotv"}), - ItemNames.PROGRESSIVE_PROTOSS_AIR_ARMOR: ItemData(104 + SC2LOTV_ITEM_ID_OFFSET, "Upgrade", 8, SC2Race.PROTOSS, quantity=3, origin={"wol", "lotv"}), - # Upgrade bundle 'number' values are used as indices to get affected 'number's - ItemNames.PROGRESSIVE_PROTOSS_WEAPON_UPGRADE: ItemData(105 + SC2LOTV_ITEM_ID_OFFSET, "Upgrade", 11, SC2Race.PROTOSS, quantity=3, origin={"wol", "lotv"}), - ItemNames.PROGRESSIVE_PROTOSS_ARMOR_UPGRADE: ItemData(106 + SC2LOTV_ITEM_ID_OFFSET, "Upgrade", 12, SC2Race.PROTOSS, quantity=3, origin={"wol", "lotv"}), - ItemNames.PROGRESSIVE_PROTOSS_GROUND_UPGRADE: ItemData(107 + SC2LOTV_ITEM_ID_OFFSET, "Upgrade", 13, SC2Race.PROTOSS, quantity=3, origin={"wol", "lotv"}), - ItemNames.PROGRESSIVE_PROTOSS_AIR_UPGRADE: ItemData(108 + SC2LOTV_ITEM_ID_OFFSET, "Upgrade", 14, SC2Race.PROTOSS, quantity=3, origin={"wol", "lotv"}), - ItemNames.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE: ItemData(109 + SC2LOTV_ITEM_ID_OFFSET, "Upgrade", 15, SC2Race.PROTOSS, quantity=3, origin={"wol", "lotv"}), - - # Protoss Buildings - ItemNames.PHOTON_CANNON: ItemData(200 + SC2LOTV_ITEM_ID_OFFSET, "Building", 0, SC2Race.PROTOSS, classification=ItemClassification.progression, origin={"wol", "lotv"}), - ItemNames.KHAYDARIN_MONOLITH: ItemData(201 + SC2LOTV_ITEM_ID_OFFSET, "Building", 1, SC2Race.PROTOSS, classification=ItemClassification.progression, origin={"lotv"}), - ItemNames.SHIELD_BATTERY: ItemData(202 + SC2LOTV_ITEM_ID_OFFSET, "Building", 2, SC2Race.PROTOSS, classification=ItemClassification.progression, origin={"lotv"}), - - # Protoss Unit Upgrades - ItemNames.SUPPLICANT_BLOOD_SHIELD: ItemData(300 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 0, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"ext"}, parent_item=ItemNames.SUPPLICANT), - ItemNames.SUPPLICANT_SOUL_AUGMENTATION: ItemData(301 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 1, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"ext"}, parent_item=ItemNames.SUPPLICANT), - ItemNames.SUPPLICANT_SHIELD_REGENERATION: ItemData(302 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 2, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"ext"}, parent_item=ItemNames.SUPPLICANT), - ItemNames.ADEPT_SHOCKWAVE: ItemData(303 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 3, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ADEPT), - ItemNames.ADEPT_RESONATING_GLAIVES: ItemData(304 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 4, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ADEPT), - ItemNames.ADEPT_PHASE_BULWARK: ItemData(305 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 5, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ADEPT), - ItemNames.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES: ItemData(306 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 6, SC2Race.PROTOSS, origin={"ext"}, classification=ItemClassification.progression), - ItemNames.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION: ItemData(307 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 7, SC2Race.PROTOSS, origin={"ext"}, classification=ItemClassification.progression), - ItemNames.DRAGOON_HIGH_IMPACT_PHASE_DISRUPTORS: ItemData(308 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 8, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.DRAGOON), - ItemNames.DRAGOON_TRILLIC_COMPRESSION_SYSTEM: ItemData(309 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 9, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.DRAGOON), - ItemNames.DRAGOON_SINGULARITY_CHARGE: ItemData(310 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 10, SC2Race.PROTOSS, origin={"bw"}, parent_item=ItemNames.DRAGOON), - ItemNames.DRAGOON_ENHANCED_STRIDER_SERVOS: ItemData(311 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 11, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=ItemNames.DRAGOON), - ItemNames.SCOUT_COMBAT_SENSOR_ARRAY: ItemData(312 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 12, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.SCOUT), - ItemNames.SCOUT_APIAL_SENSORS: ItemData(313 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 13, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=ItemNames.SCOUT), - ItemNames.SCOUT_GRAVITIC_THRUSTERS: ItemData(314 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 14, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=ItemNames.SCOUT), - ItemNames.SCOUT_ADVANCED_PHOTON_BLASTERS: ItemData(315 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 15, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.SCOUT), - ItemNames.TEMPEST_TECTONIC_DESTABILIZERS: ItemData(316 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 16, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"ext"}, parent_item=ItemNames.TEMPEST), - ItemNames.TEMPEST_QUANTIC_REACTOR: ItemData(317 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 17, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"ext"}, parent_item=ItemNames.TEMPEST), - ItemNames.TEMPEST_GRAVITY_SLING: ItemData(318 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 18, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.TEMPEST), - ItemNames.PHOENIX_MIRAGE_IONIC_WAVELENGTH_FLUX: ItemData(319 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 19, SC2Race.PROTOSS, origin={"ext"}), - ItemNames.PHOENIX_MIRAGE_ANION_PULSE_CRYSTALS: ItemData(320 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 20, SC2Race.PROTOSS, origin={"ext"}), - ItemNames.CORSAIR_STEALTH_DRIVE: ItemData(321 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 21, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.CORSAIR), - ItemNames.CORSAIR_ARGUS_JEWEL: ItemData(322 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 22, SC2Race.PROTOSS, origin={"bw"}, parent_item=ItemNames.CORSAIR), - ItemNames.CORSAIR_SUSTAINING_DISRUPTION: ItemData(323 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 23, SC2Race.PROTOSS, origin={"bw"}, parent_item=ItemNames.CORSAIR), - ItemNames.CORSAIR_NEUTRON_SHIELDS: ItemData(324 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 24, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=ItemNames.CORSAIR), - ItemNames.ORACLE_STEALTH_DRIVE: ItemData(325 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 25, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ORACLE), - ItemNames.ORACLE_STASIS_CALIBRATION: ItemData(326 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 26, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ORACLE), - ItemNames.ORACLE_TEMPORAL_ACCELERATION_BEAM: ItemData(327 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 27, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ORACLE), - ItemNames.ARBITER_CHRONOSTATIC_REINFORCEMENT: ItemData(328 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 28, SC2Race.PROTOSS, origin={"bw"}, parent_item=ItemNames.ARBITER), - ItemNames.ARBITER_KHAYDARIN_CORE: ItemData(329 + SC2LOTV_ITEM_ID_OFFSET, "Forge 1", 29, SC2Race.PROTOSS, origin={"bw"}, parent_item=ItemNames.ARBITER), - ItemNames.ARBITER_SPACETIME_ANCHOR: ItemData(330 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 0, SC2Race.PROTOSS, origin={"bw"}, parent_item=ItemNames.ARBITER), - ItemNames.ARBITER_RESOURCE_EFFICIENCY: ItemData(331 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 1, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=ItemNames.ARBITER), - ItemNames.ARBITER_ENHANCED_CLOAK_FIELD: ItemData(332 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 2, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=ItemNames.ARBITER), - ItemNames.CARRIER_GRAVITON_CATAPULT: - ItemData(333 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 3, SC2Race.PROTOSS, origin={"wol"}, - parent_item=ItemNames.CARRIER, - description="Carriers can launch Interceptors more quickly."), - ItemNames.CARRIER_HULL_OF_PAST_GLORIES: - ItemData(334 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 4, SC2Race.PROTOSS, origin={"bw"}, - parent_item=ItemNames.CARRIER, - description="Carriers gain +2 armour."), - ItemNames.VOID_RAY_DESTROYER_FLUX_VANES: - ItemData(335 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 5, SC2Race.PROTOSS, classification=ItemClassification.filler, - origin={"ext"}, - description="Increases Void Ray and Destroyer movement speed."), - ItemNames.DESTROYER_REFORGED_BLOODSHARD_CORE: - ItemData(336 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 6, SC2Race.PROTOSS, origin={"ext"}, - parent_item=ItemNames.DESTROYER, - description="When fully charged, the Destroyer's Destruction Beam weapon does full damage to secondary targets."), - ItemNames.WARP_PRISM_GRAVITIC_DRIVE: - ItemData(337 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 7, SC2Race.PROTOSS, classification=ItemClassification.filler, - origin={"ext"}, parent_item=ItemNames.WARP_PRISM, - description="Increases the movement speed of Warp Prisms."), - ItemNames.WARP_PRISM_PHASE_BLASTER: - ItemData(338 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 8, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"ext"}, parent_item=ItemNames.WARP_PRISM, - description="Equips Warp Prisms with an auto-attack that can hit ground and air targets."), - ItemNames.WARP_PRISM_WAR_CONFIGURATION: ItemData(339 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 9, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.WARP_PRISM), - ItemNames.OBSERVER_GRAVITIC_BOOSTERS: ItemData(340 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 10, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=ItemNames.OBSERVER), - ItemNames.OBSERVER_SENSOR_ARRAY: ItemData(341 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 11, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=ItemNames.OBSERVER), - ItemNames.REAVER_SCARAB_DAMAGE: ItemData(342 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 12, SC2Race.PROTOSS, origin={"bw"}, parent_item=ItemNames.REAVER), - ItemNames.REAVER_SOLARITE_PAYLOAD: ItemData(343 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 13, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.REAVER), - ItemNames.REAVER_REAVER_CAPACITY: ItemData(344 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 14, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}, parent_item=ItemNames.REAVER), - ItemNames.REAVER_RESOURCE_EFFICIENCY: ItemData(345 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 15, SC2Race.PROTOSS, origin={"bw"}, parent_item=ItemNames.REAVER), - ItemNames.VANGUARD_AGONY_LAUNCHERS: ItemData(346 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 16, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.VANGUARD), - ItemNames.VANGUARD_MATTER_DISPERSION: ItemData(347 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 17, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.VANGUARD), - ItemNames.IMMORTAL_ANNIHILATOR_SINGULARITY_CHARGE: ItemData(348 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 18, SC2Race.PROTOSS, origin={"ext"}), - ItemNames.IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING_MECHANICS: ItemData(349 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 19, SC2Race.PROTOSS, classification=ItemClassification.progression, origin={"ext"}), - ItemNames.COLOSSUS_PACIFICATION_PROTOCOL: ItemData(350 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 20, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.COLOSSUS), - ItemNames.WRATHWALKER_RAPID_POWER_CYCLING: ItemData(351 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 21, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.WRATHWALKER), - ItemNames.WRATHWALKER_EYE_OF_WRATH: ItemData(352 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 22, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"ext"}, parent_item=ItemNames.WRATHWALKER), - ItemNames.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_SHROUD_OF_ADUN: ItemData(353 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 23, SC2Race.PROTOSS, origin={"ext"}), - ItemNames.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_SHADOW_GUARD_TRAINING: ItemData(354 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 24, SC2Race.PROTOSS, origin={"bw"}), - ItemNames.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_BLINK: ItemData(355 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 25, SC2Race.PROTOSS, classification=ItemClassification.progression, origin={"ext"}), - ItemNames.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_RESOURCE_EFFICIENCY: ItemData(356 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 26, SC2Race.PROTOSS, origin={"ext"}), - ItemNames.DARK_TEMPLAR_DARK_ARCHON_MELD: ItemData(357 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 27, SC2Race.PROTOSS, origin={"bw"}, important_for_filtering=True ,parent_item=ItemNames.DARK_TEMPLAR), - ItemNames.HIGH_TEMPLAR_SIGNIFIER_UNSHACKLED_PSIONIC_STORM: ItemData(358 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 28, SC2Race.PROTOSS, origin={"bw"}), - ItemNames.HIGH_TEMPLAR_SIGNIFIER_HALLUCINATION: ItemData(359 + SC2LOTV_ITEM_ID_OFFSET, "Forge 2", 29, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"bw"}), - ItemNames.HIGH_TEMPLAR_SIGNIFIER_KHAYDARIN_AMULET: ItemData(360 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 0, SC2Race.PROTOSS, origin={"bw"}), - ItemNames.ARCHON_HIGH_ARCHON: ItemData(361 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 1, SC2Race.PROTOSS, origin={"ext"}, important_for_filtering=True), - ItemNames.DARK_ARCHON_FEEDBACK: ItemData(362 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 2, SC2Race.PROTOSS, origin={"bw"}), - ItemNames.DARK_ARCHON_MAELSTROM: ItemData(363 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 3, SC2Race.PROTOSS, origin={"bw"}), - ItemNames.DARK_ARCHON_ARGUS_TALISMAN: ItemData(364 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 4, SC2Race.PROTOSS, origin={"bw"}), - ItemNames.ASCENDANT_POWER_OVERWHELMING: ItemData(365 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 5, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ASCENDANT), - ItemNames.ASCENDANT_CHAOTIC_ATTUNEMENT: ItemData(366 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 6, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ASCENDANT), - ItemNames.ASCENDANT_BLOOD_AMULET: ItemData(367 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 7, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ASCENDANT), - ItemNames.SENTRY_ENERGIZER_HAVOC_CLOAKING_MODULE: ItemData(368 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 8, SC2Race.PROTOSS, origin={"ext"}), - ItemNames.SENTRY_ENERGIZER_HAVOC_SHIELD_BATTERY_RAPID_RECHARGING: ItemData(369 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 9, SC2Race.PROTOSS, origin={"ext"}), - ItemNames.SENTRY_FORCE_FIELD: ItemData(370 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 10, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"ext"}, parent_item=ItemNames.SENTRY), - ItemNames.SENTRY_HALLUCINATION: ItemData(371 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 11, SC2Race.PROTOSS, classification=ItemClassification.filler, origin={"ext"}, parent_item=ItemNames.SENTRY), - ItemNames.ENERGIZER_RECLAMATION: ItemData(372 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 12, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ENERGIZER), - ItemNames.ENERGIZER_FORGED_CHASSIS: ItemData(373 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 13, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.ENERGIZER), - ItemNames.HAVOC_DETECT_WEAKNESS: ItemData(374 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 14, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.HAVOC), - ItemNames.HAVOC_BLOODSHARD_RESONANCE: ItemData(375 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 15, SC2Race.PROTOSS, origin={"ext"}, parent_item=ItemNames.HAVOC), - ItemNames.ZEALOT_SENTINEL_CENTURION_LEG_ENHANCEMENTS: ItemData(376 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 16, SC2Race.PROTOSS, origin={"bw"}), - ItemNames.ZEALOT_SENTINEL_CENTURION_SHIELD_CAPACITY: ItemData(377 + SC2LOTV_ITEM_ID_OFFSET, "Forge 3", 17, SC2Race.PROTOSS, origin={"bw"}), - - # SoA Calldown powers - ItemNames.SOA_CHRONO_SURGE: ItemData(700 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 0, SC2Race.PROTOSS, origin={"lotv"}), - ItemNames.SOA_PROGRESSIVE_PROXY_PYLON: ItemData(701 + SC2LOTV_ITEM_ID_OFFSET, "Progressive Upgrade", 0, SC2Race.PROTOSS, origin={"lotv"}, quantity=2), - ItemNames.SOA_PYLON_OVERCHARGE: ItemData(702 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 1, SC2Race.PROTOSS, origin={"ext"}), - ItemNames.SOA_ORBITAL_STRIKE: ItemData(703 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 2, SC2Race.PROTOSS, origin={"lotv"}), - ItemNames.SOA_TEMPORAL_FIELD: ItemData(704 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 3, SC2Race.PROTOSS, origin={"lotv"}), - ItemNames.SOA_SOLAR_LANCE: ItemData(705 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 4, SC2Race.PROTOSS, classification=ItemClassification.progression, origin={"lotv"}), - ItemNames.SOA_MASS_RECALL: ItemData(706 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 5, SC2Race.PROTOSS, origin={"lotv"}), - ItemNames.SOA_SHIELD_OVERCHARGE: ItemData(707 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 6, SC2Race.PROTOSS, origin={"lotv"}), - ItemNames.SOA_DEPLOY_FENIX: ItemData(708 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 7, SC2Race.PROTOSS, classification=ItemClassification.progression, origin={"lotv"}), - ItemNames.SOA_PURIFIER_BEAM: ItemData(709 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 8, SC2Race.PROTOSS, origin={"lotv"}), - ItemNames.SOA_TIME_STOP: ItemData(710 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 9, SC2Race.PROTOSS, classification=ItemClassification.progression, origin={"lotv"}), - ItemNames.SOA_SOLAR_BOMBARDMENT: ItemData(711 + SC2LOTV_ITEM_ID_OFFSET, "Spear of Adun", 10, SC2Race.PROTOSS, origin={"lotv"}), - - # Generic Protoss Upgrades - ItemNames.MATRIX_OVERLOAD: - ItemData(800 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 0, SC2Race.PROTOSS, origin={"lotv"}, - description=r"All friendly units gain 25% movement speed and 15% attack speed within a Pylon's power field and for 15 seconds after leaving it."), - ItemNames.QUATRO: - ItemData(801 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 1, SC2Race.PROTOSS, origin={"ext"}, - description="All friendly Protoss units gain the equivalent of their +1 armour, attack, and shield upgrades."), - ItemNames.NEXUS_OVERCHARGE: - ItemData(802 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 2, SC2Race.PROTOSS, origin={"lotv"}, - important_for_filtering=True, description="The Protoss Nexus gains a long-range auto-attack."), - ItemNames.ORBITAL_ASSIMILATORS: - ItemData(803 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 3, SC2Race.PROTOSS, origin={"lotv"}, - description="Assimilators automatically harvest Vespene Gas without the need for Probes."), - ItemNames.WARP_HARMONIZATION: - ItemData(804 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 4, SC2Race.PROTOSS, origin={"lotv"}, - description=r"Stargates and Robotics Facilities can transform to utilize Warp In technology. Warp In cooldowns are 20% faster than original build times."), - ItemNames.GUARDIAN_SHELL: - ItemData(805 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 5, SC2Race.PROTOSS, origin={"lotv"}, - description="The Spear of Adun passively shields friendly Protoss units before death, making them invulnerable for 5 seconds. Each unit can only be shielded once every 60 seconds."), - ItemNames.RECONSTRUCTION_BEAM: - ItemData(806 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 6, SC2Race.PROTOSS, - classification=ItemClassification.progression, origin={"lotv"}, - description="The Spear of Adun will passively heal mechanical units for 5 and non-biological structures for 10 life per second. Up to 3 targets can be repaired at once."), - ItemNames.OVERWATCH: - ItemData(807 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 7, SC2Race.PROTOSS, origin={"ext"}, - description="Once per second, the Spear of Adun will last-hit a damaged enemy unit that is below 50 health."), - ItemNames.SUPERIOR_WARP_GATES: - ItemData(808 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 8, SC2Race.PROTOSS, origin={"ext"}, - description="Protoss Warp Gates can hold up to 3 charges of unit warp-ins."), - ItemNames.ENHANCED_TARGETING: - ItemData(809 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 9, SC2Race.PROTOSS, origin={"ext"}, - description="Protoss defensive structures gain +2 range."), - ItemNames.OPTIMIZED_ORDNANCE: - ItemData(810 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 10, SC2Race.PROTOSS, origin={"ext"}, - description="Increases the attack speed of Protoss defensive structures by 25%."), - ItemNames.KHALAI_INGENUITY: - ItemData(811 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 11, SC2Race.PROTOSS, origin={"ext"}, - description="Pylons, Photon Cannons, Monoliths, and Shield Batteries warp in near-instantly."), - ItemNames.AMPLIFIED_ASSIMILATORS: - ItemData(812 + SC2LOTV_ITEM_ID_OFFSET, "Solarite Core", 12, SC2Race.PROTOSS, origin={"ext"}, - description=r"Assimilators produce Vespene gas 25% faster."), -} - - -def get_item_table(): - return item_table - - -basic_units = { - SC2Race.TERRAN: { - ItemNames.MARINE, - ItemNames.MARAUDER, - ItemNames.GOLIATH, - ItemNames.HELLION, - ItemNames.VULTURE, - ItemNames.WARHOUND, - }, - SC2Race.ZERG: { - ItemNames.ZERGLING, - ItemNames.SWARM_QUEEN, - ItemNames.ROACH, - ItemNames.HYDRALISK, - }, - SC2Race.PROTOSS: { - ItemNames.ZEALOT, - ItemNames.CENTURION, - ItemNames.SENTINEL, - ItemNames.STALKER, - ItemNames.INSTIGATOR, - ItemNames.SLAYER, - ItemNames.DRAGOON, - ItemNames.ADEPT, - } -} - -advanced_basic_units = { - SC2Race.TERRAN: basic_units[SC2Race.TERRAN].union({ - ItemNames.REAPER, - ItemNames.DIAMONDBACK, - ItemNames.VIKING, - ItemNames.SIEGE_TANK, - ItemNames.BANSHEE, - ItemNames.THOR, - ItemNames.BATTLECRUISER, - ItemNames.CYCLONE - }), - SC2Race.ZERG: basic_units[SC2Race.ZERG].union({ - ItemNames.INFESTOR, - ItemNames.ABERRATION, - }), - SC2Race.PROTOSS: basic_units[SC2Race.PROTOSS].union({ - ItemNames.DARK_TEMPLAR, - ItemNames.BLOOD_HUNTER, - ItemNames.AVENGER, - ItemNames.IMMORTAL, - ItemNames.ANNIHILATOR, - ItemNames.VANGUARD, - }) -} - -no_logic_starting_units = { - SC2Race.TERRAN: advanced_basic_units[SC2Race.TERRAN].union({ - ItemNames.FIREBAT, - ItemNames.GHOST, - ItemNames.SPECTRE, - ItemNames.WRAITH, - ItemNames.RAVEN, - ItemNames.PREDATOR, - ItemNames.LIBERATOR, - ItemNames.HERC, - }), - SC2Race.ZERG: advanced_basic_units[SC2Race.ZERG].union({ - ItemNames.ULTRALISK, - ItemNames.SWARM_HOST - }), - SC2Race.PROTOSS: advanced_basic_units[SC2Race.PROTOSS].union({ - ItemNames.CARRIER, - ItemNames.TEMPEST, - ItemNames.VOID_RAY, - ItemNames.DESTROYER, - ItemNames.COLOSSUS, - ItemNames.WRATHWALKER, - ItemNames.SCOUT, - ItemNames.HIGH_TEMPLAR, - ItemNames.SIGNIFIER, - ItemNames.ASCENDANT, - ItemNames.DARK_ARCHON, - ItemNames.SUPPLICANT, - }) -} - -not_balanced_starting_units = { - ItemNames.SIEGE_TANK, - ItemNames.THOR, - ItemNames.BANSHEE, - ItemNames.BATTLECRUISER, - ItemNames.ULTRALISK, - ItemNames.CARRIER, - ItemNames.TEMPEST, -} - - -def get_basic_units(world: World, race: SC2Race) -> typing.Set[str]: - logic_level = get_option_value(world, 'required_tactics') - if logic_level == RequiredTactics.option_no_logic: - return no_logic_starting_units[race] - elif logic_level == RequiredTactics.option_advanced: - return advanced_basic_units[race] - else: - return basic_units[race] - - -# Items that can be placed before resources if not already in -# General upgrades and Mercs -second_pass_placeable_items: typing.Tuple[str, ...] = ( - # Global weapon/armor upgrades - ItemNames.PROGRESSIVE_TERRAN_ARMOR_UPGRADE, - ItemNames.PROGRESSIVE_TERRAN_WEAPON_UPGRADE, - ItemNames.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE, - ItemNames.PROGRESSIVE_ZERG_ARMOR_UPGRADE, - ItemNames.PROGRESSIVE_ZERG_WEAPON_UPGRADE, - ItemNames.PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE, - ItemNames.PROGRESSIVE_PROTOSS_ARMOR_UPGRADE, - ItemNames.PROGRESSIVE_PROTOSS_WEAPON_UPGRADE, - ItemNames.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE, - ItemNames.PROGRESSIVE_PROTOSS_SHIELDS, - # Terran Buildings without upgrades - ItemNames.SENSOR_TOWER, - ItemNames.HIVE_MIND_EMULATOR, - ItemNames.PSI_DISRUPTER, - ItemNames.PERDITION_TURRET, - # Terran units without upgrades - ItemNames.HERC, - ItemNames.WARHOUND, - # General Terran upgrades without any dependencies - ItemNames.SCV_ADVANCED_CONSTRUCTION, - ItemNames.SCV_DUAL_FUSION_WELDERS, - ItemNames.PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM, - ItemNames.PROGRESSIVE_ORBITAL_COMMAND, - ItemNames.ULTRA_CAPACITORS, - ItemNames.VANADIUM_PLATING, - ItemNames.ORBITAL_DEPOTS, - ItemNames.MICRO_FILTERING, - ItemNames.AUTOMATED_REFINERY, - ItemNames.COMMAND_CENTER_REACTOR, - ItemNames.TECH_REACTOR, - ItemNames.CELLULAR_REACTOR, - ItemNames.PROGRESSIVE_REGENERATIVE_BIO_STEEL, # Place only L1 - ItemNames.STRUCTURE_ARMOR, - ItemNames.HI_SEC_AUTO_TRACKING, - ItemNames.ADVANCED_OPTICS, - ItemNames.ROGUE_FORCES, - # Mercenaries (All races) - *[item_name for item_name, item_data in get_full_item_list().items() - if item_data.type == "Mercenary"], - # Kerrigan and Nova levels, abilities and generally useful stuff - *[item_name for item_name, item_data in get_full_item_list().items() - if item_data.type in ("Level", "Ability", "Evolution Pit", "Nova Gear")], - ItemNames.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE, - # Zerg static defenses - ItemNames.SPORE_CRAWLER, - ItemNames.SPINE_CRAWLER, - # Defiler, Aberration (no upgrades) - ItemNames.DEFILER, - ItemNames.ABERRATION, - # Spear of Adun Abilities - ItemNames.SOA_CHRONO_SURGE, - ItemNames.SOA_PROGRESSIVE_PROXY_PYLON, - ItemNames.SOA_PYLON_OVERCHARGE, - ItemNames.SOA_ORBITAL_STRIKE, - ItemNames.SOA_TEMPORAL_FIELD, - ItemNames.SOA_SOLAR_LANCE, - ItemNames.SOA_MASS_RECALL, - ItemNames.SOA_SHIELD_OVERCHARGE, - ItemNames.SOA_DEPLOY_FENIX, - ItemNames.SOA_PURIFIER_BEAM, - ItemNames.SOA_TIME_STOP, - ItemNames.SOA_SOLAR_BOMBARDMENT, - # Protoss generic upgrades - ItemNames.MATRIX_OVERLOAD, - ItemNames.QUATRO, - ItemNames.NEXUS_OVERCHARGE, - ItemNames.ORBITAL_ASSIMILATORS, - ItemNames.WARP_HARMONIZATION, - ItemNames.GUARDIAN_SHELL, - ItemNames.RECONSTRUCTION_BEAM, - ItemNames.OVERWATCH, - ItemNames.SUPERIOR_WARP_GATES, - ItemNames.KHALAI_INGENUITY, - ItemNames.AMPLIFIED_ASSIMILATORS, - # Protoss static defenses - ItemNames.PHOTON_CANNON, - ItemNames.KHAYDARIN_MONOLITH, - ItemNames.SHIELD_BATTERY -) - - -filler_items: typing.Tuple[str, ...] = ( - ItemNames.STARTING_MINERALS, - ItemNames.STARTING_VESPENE, - ItemNames.STARTING_SUPPLY, -) - -# Defense rating table -# Commented defense ratings are handled in LogicMixin -defense_ratings = { - ItemNames.SIEGE_TANK: 5, - # "Maelstrom Rounds": 2, - ItemNames.PLANETARY_FORTRESS: 3, - # Bunker w/ Marine/Marauder: 3, - ItemNames.PERDITION_TURRET: 2, - ItemNames.VULTURE: 1, - ItemNames.BANSHEE: 1, - ItemNames.BATTLECRUISER: 1, - ItemNames.LIBERATOR: 4, - ItemNames.WIDOW_MINE: 1, - # "Concealment (Widow Mine)": 1 -} -zerg_defense_ratings = { - ItemNames.PERDITION_TURRET: 2, - # Bunker w/ Firebat: 2, - ItemNames.LIBERATOR: -2, - ItemNames.HIVE_MIND_EMULATOR: 3, - ItemNames.PSI_DISRUPTER: 3, -} -air_defense_ratings = { - ItemNames.MISSILE_TURRET: 2, -} - -kerrigan_levels = [item_name for item_name, item_data in get_full_item_list().items() - if item_data.type == "Level" and item_data.race == SC2Race.ZERG] - -spider_mine_sources = { - ItemNames.VULTURE, - ItemNames.REAPER_SPIDER_MINES, - ItemNames.SIEGE_TANK_SPIDER_MINES, - ItemNames.RAVEN_SPIDER_MINES, -} - -progressive_if_nco = { - ItemNames.MARINE_PROGRESSIVE_STIMPACK, - ItemNames.FIREBAT_PROGRESSIVE_STIMPACK, - ItemNames.BANSHEE_PROGRESSIVE_CROSS_SPECTRUM_DAMPENERS, - ItemNames.PROGRESSIVE_REGENERATIVE_BIO_STEEL, -} - -progressive_if_ext = { - ItemNames.VULTURE_PROGRESSIVE_REPLENISHABLE_MAGAZINE, - ItemNames.WRAITH_PROGRESSIVE_TOMAHAWK_POWER_CELLS, - ItemNames.BATTLECRUISER_PROGRESSIVE_DEFENSIVE_MATRIX, - ItemNames.BATTLECRUISER_PROGRESSIVE_MISSILE_PODS, - ItemNames.THOR_PROGRESSIVE_IMMORTALITY_PROTOCOL, - ItemNames.PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM, - ItemNames.DIAMONDBACK_PROGRESSIVE_TRI_LITHIUM_POWER_CELL, - ItemNames.PROGRESSIVE_ORBITAL_COMMAND -} - -kerrigan_actives: typing.List[typing.Set[str]] = [ - {ItemNames.KERRIGAN_KINETIC_BLAST, ItemNames.KERRIGAN_LEAPING_STRIKE}, - {ItemNames.KERRIGAN_CRUSHING_GRIP, ItemNames.KERRIGAN_PSIONIC_SHIFT}, - set(), - {ItemNames.KERRIGAN_WILD_MUTATION, ItemNames.KERRIGAN_SPAWN_BANELINGS, ItemNames.KERRIGAN_MEND}, - set(), - set(), - {ItemNames.KERRIGAN_APOCALYPSE, ItemNames.KERRIGAN_SPAWN_LEVIATHAN, ItemNames.KERRIGAN_DROP_PODS}, -] - -kerrigan_passives: typing.List[typing.Set[str]] = [ - {ItemNames.KERRIGAN_HEROIC_FORTITUDE}, - {ItemNames.KERRIGAN_CHAIN_REACTION}, - {ItemNames.KERRIGAN_ZERGLING_RECONSTITUTION, ItemNames.KERRIGAN_IMPROVED_OVERLORDS, ItemNames.KERRIGAN_AUTOMATED_EXTRACTORS}, - set(), - {ItemNames.KERRIGAN_TWIN_DRONES, ItemNames.KERRIGAN_MALIGNANT_CREEP, ItemNames.KERRIGAN_VESPENE_EFFICIENCY}, - {ItemNames.KERRIGAN_INFEST_BROODLINGS, ItemNames.KERRIGAN_FURY, ItemNames.KERRIGAN_ABILITY_EFFICIENCY}, - set(), -] - -kerrigan_only_passives = { - ItemNames.KERRIGAN_HEROIC_FORTITUDE, ItemNames.KERRIGAN_CHAIN_REACTION, - ItemNames.KERRIGAN_INFEST_BROODLINGS, ItemNames.KERRIGAN_FURY, ItemNames.KERRIGAN_ABILITY_EFFICIENCY, -} - -spear_of_adun_calldowns = { - ItemNames.SOA_CHRONO_SURGE, - ItemNames.SOA_PROGRESSIVE_PROXY_PYLON, - ItemNames.SOA_PYLON_OVERCHARGE, - ItemNames.SOA_ORBITAL_STRIKE, - ItemNames.SOA_TEMPORAL_FIELD, - ItemNames.SOA_SOLAR_LANCE, - ItemNames.SOA_MASS_RECALL, - ItemNames.SOA_SHIELD_OVERCHARGE, - ItemNames.SOA_DEPLOY_FENIX, - ItemNames.SOA_PURIFIER_BEAM, - ItemNames.SOA_TIME_STOP, - ItemNames.SOA_SOLAR_BOMBARDMENT -} - -spear_of_adun_castable_passives = { - ItemNames.RECONSTRUCTION_BEAM, - ItemNames.OVERWATCH, -} - -nova_equipment = { - *[item_name for item_name, item_data in get_full_item_list().items() - if item_data.type == "Nova Gear"], - ItemNames.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE -} - -# 'number' values of upgrades for upgrade bundle items -upgrade_numbers = [ - # Terran - {0, 4, 8}, # Weapon - {2, 6, 10}, # Armor - {0, 2}, # Infantry - {4, 6}, # Vehicle - {8, 10}, # Starship - {0, 2, 4, 6, 8, 10}, # All - # Zerg - {0, 2, 6}, # Weapon - {4, 8}, # Armor - {0, 2, 4}, # Ground - {6, 8}, # Flyer - {0, 2, 4, 6, 8}, # All - # Protoss - {0, 6}, # Weapon - {2, 4, 8}, # Armor - {0, 2}, # Ground, Shields are handled specially - {6, 8}, # Air, Shields are handled specially - {0, 2, 4, 6, 8}, # All -] -# 'upgrade_numbers' indices for all upgrades -upgrade_numbers_all = { - SC2Race.TERRAN: 5, - SC2Race.ZERG: 10, - SC2Race.PROTOSS: 15, -} - -# Names of upgrades to be included for different options -upgrade_included_names = [ - { # Individual Items - ItemNames.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, - ItemNames.PROGRESSIVE_TERRAN_INFANTRY_ARMOR, - ItemNames.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, - ItemNames.PROGRESSIVE_TERRAN_VEHICLE_ARMOR, - ItemNames.PROGRESSIVE_TERRAN_SHIP_WEAPON, - ItemNames.PROGRESSIVE_TERRAN_SHIP_ARMOR, - ItemNames.PROGRESSIVE_ZERG_MELEE_ATTACK, - ItemNames.PROGRESSIVE_ZERG_MISSILE_ATTACK, - ItemNames.PROGRESSIVE_ZERG_GROUND_CARAPACE, - ItemNames.PROGRESSIVE_ZERG_FLYER_ATTACK, - ItemNames.PROGRESSIVE_ZERG_FLYER_CARAPACE, - ItemNames.PROGRESSIVE_PROTOSS_GROUND_WEAPON, - ItemNames.PROGRESSIVE_PROTOSS_GROUND_ARMOR, - ItemNames.PROGRESSIVE_PROTOSS_SHIELDS, - ItemNames.PROGRESSIVE_PROTOSS_AIR_WEAPON, - ItemNames.PROGRESSIVE_PROTOSS_AIR_ARMOR, - }, - { # Bundle Weapon And Armor - ItemNames.PROGRESSIVE_TERRAN_WEAPON_UPGRADE, - ItemNames.PROGRESSIVE_TERRAN_ARMOR_UPGRADE, - ItemNames.PROGRESSIVE_ZERG_WEAPON_UPGRADE, - ItemNames.PROGRESSIVE_ZERG_ARMOR_UPGRADE, - ItemNames.PROGRESSIVE_PROTOSS_WEAPON_UPGRADE, - ItemNames.PROGRESSIVE_PROTOSS_ARMOR_UPGRADE, - }, - { # Bundle Unit Class - ItemNames.PROGRESSIVE_TERRAN_INFANTRY_UPGRADE, - ItemNames.PROGRESSIVE_TERRAN_VEHICLE_UPGRADE, - ItemNames.PROGRESSIVE_TERRAN_SHIP_UPGRADE, - ItemNames.PROGRESSIVE_ZERG_GROUND_UPGRADE, - ItemNames.PROGRESSIVE_ZERG_FLYER_UPGRADE, - ItemNames.PROGRESSIVE_PROTOSS_GROUND_UPGRADE, - ItemNames.PROGRESSIVE_PROTOSS_AIR_UPGRADE, - }, - { # Bundle All - ItemNames.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE, - ItemNames.PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE, - ItemNames.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE, - } -] - -lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in get_full_item_list().items() if - data.code} - -# Map type to expected int -type_flaggroups: typing.Dict[SC2Race, typing.Dict[str, int]] = { - SC2Race.ANY: { - "Minerals": 0, - "Vespene": 1, - "Supply": 2, - "Goal": 3, - "Nothing Group": 4, - }, - SC2Race.TERRAN: { - "Armory 1": 0, - "Armory 2": 1, - "Armory 3": 2, - "Armory 4": 3, - "Armory 5": 4, - "Armory 6": 5, - "Progressive Upgrade": 6, # Unit upgrades that exist multiple times (Stimpack / Super Stimpack) - "Laboratory": 7, - "Upgrade": 8, # Weapon / Armor upgrades - "Unit": 9, - "Building": 10, - "Mercenary": 11, - "Nova Gear": 12, - "Progressive Upgrade 2": 13, - }, - SC2Race.ZERG: { - "Ability": 0, - "Mutation 1": 1, - "Strain": 2, - "Morph": 3, - "Upgrade": 4, - "Mercenary": 5, - "Unit": 6, - "Level": 7, - "Primal Form": 8, - "Evolution Pit": 9, - "Mutation 2": 10, - "Mutation 3": 11 - }, - SC2Race.PROTOSS: { - "Unit": 0, - "Unit 2": 1, - "Upgrade": 2, # Weapon / Armor upgrades - "Building": 3, - "Progressive Upgrade": 4, - "Spear of Adun": 5, - "Solarite Core": 6, - "Forge 1": 7, - "Forge 2": 8, - "Forge 3": 9, - } -} diff --git a/worlds/sc2/Locations.py b/worlds/sc2/Locations.py deleted file mode 100644 index 42b1dd4d4eb0..000000000000 --- a/worlds/sc2/Locations.py +++ /dev/null @@ -1,1635 +0,0 @@ -from enum import IntEnum -from typing import List, Tuple, Optional, Callable, NamedTuple, Set, Any -from BaseClasses import MultiWorld -from . import ItemNames -from .Options import get_option_value, kerrigan_unit_available, RequiredTactics, GrantStoryTech, LocationInclusion, \ - EnableHotsMissions -from .Rules import SC2Logic - -from BaseClasses import Location -from worlds.AutoWorld import World - -SC2WOL_LOC_ID_OFFSET = 1000 -SC2HOTS_LOC_ID_OFFSET = 20000000 # Avoid clashes with The Legend of Zelda -SC2LOTV_LOC_ID_OFFSET = SC2HOTS_LOC_ID_OFFSET + 2000 -SC2NCO_LOC_ID_OFFSET = SC2LOTV_LOC_ID_OFFSET + 2500 - - -class SC2Location(Location): - game: str = "Starcraft2" - - -class LocationType(IntEnum): - VICTORY = 0 # Winning a mission - VANILLA = 1 # Objectives that provided metaprogression in the original campaign, along with a few other locations for a balanced experience - EXTRA = 2 # Additional locations based on mission progression, collecting in-mission rewards, etc. that do not significantly increase the challenge. - CHALLENGE = 3 # Challenging objectives, often harder than just completing a mission, and often associated with Achievements - MASTERY = 4 # Extremely challenging objectives often associated with Masteries and Feats of Strength in the original campaign - - -class LocationData(NamedTuple): - region: str - name: str - code: Optional[int] - type: LocationType - rule: Optional[Callable[[Any], bool]] = Location.access_rule - - -def get_location_types(world: World, inclusion_type: LocationInclusion) -> Set[LocationType]: - """ - - :param multiworld: - :param player: - :param inclusion_type: Level of inclusion to check for - :return: A list of location types that match the inclusion type - """ - exclusion_options = [ - ("vanilla_locations", LocationType.VANILLA), - ("extra_locations", LocationType.EXTRA), - ("challenge_locations", LocationType.CHALLENGE), - ("mastery_locations", LocationType.MASTERY) - ] - excluded_location_types = set() - for option_name, location_type in exclusion_options: - if get_option_value(world, option_name) is inclusion_type: - excluded_location_types.add(location_type) - return excluded_location_types - - -def get_plando_locations(world: World) -> List[str]: - """ - - :param multiworld: - :param player: - :return: A list of locations affected by a plando in a world - """ - if world is None: - return [] - plando_locations = [] - for plando_setting in world.options.plando_items: - plando_locations += plando_setting.locations - - return plando_locations - - -def get_locations(world: Optional[World]) -> Tuple[LocationData, ...]: - # Note: rules which are ended with or True are rules identified as needed later when restricted units is an option - logic_level = get_option_value(world, 'required_tactics') - adv_tactics = logic_level != RequiredTactics.option_standard - kerriganless = get_option_value(world, 'kerrigan_presence') not in kerrigan_unit_available \ - or get_option_value(world, "enable_hots_missions") == EnableHotsMissions.option_false - story_tech_granted = get_option_value(world, "grant_story_tech") == GrantStoryTech.option_true - logic = SC2Logic(world) - player = None if world is None else world.player - location_table: List[LocationData] = [ - # WoL - LocationData("Liberation Day", "Liberation Day: Victory", SC2WOL_LOC_ID_OFFSET + 100, LocationType.VICTORY), - LocationData("Liberation Day", "Liberation Day: First Statue", SC2WOL_LOC_ID_OFFSET + 101, LocationType.VANILLA), - LocationData("Liberation Day", "Liberation Day: Second Statue", SC2WOL_LOC_ID_OFFSET + 102, LocationType.VANILLA), - LocationData("Liberation Day", "Liberation Day: Third Statue", SC2WOL_LOC_ID_OFFSET + 103, LocationType.VANILLA), - LocationData("Liberation Day", "Liberation Day: Fourth Statue", SC2WOL_LOC_ID_OFFSET + 104, LocationType.VANILLA), - LocationData("Liberation Day", "Liberation Day: Fifth Statue", SC2WOL_LOC_ID_OFFSET + 105, LocationType.VANILLA), - LocationData("Liberation Day", "Liberation Day: Sixth Statue", SC2WOL_LOC_ID_OFFSET + 106, LocationType.VANILLA), - LocationData("Liberation Day", "Liberation Day: Special Delivery", SC2WOL_LOC_ID_OFFSET + 107, LocationType.EXTRA), - LocationData("Liberation Day", "Liberation Day: Transport", SC2WOL_LOC_ID_OFFSET + 108, LocationType.EXTRA), - LocationData("The Outlaws", "The Outlaws: Victory", SC2WOL_LOC_ID_OFFSET + 200, LocationType.VICTORY, - lambda state: logic.terran_early_tech(state)), - LocationData("The Outlaws", "The Outlaws: Rebel Base", SC2WOL_LOC_ID_OFFSET + 201, LocationType.VANILLA, - lambda state: logic.terran_early_tech(state)), - LocationData("The Outlaws", "The Outlaws: North Resource Pickups", SC2WOL_LOC_ID_OFFSET + 202, LocationType.EXTRA, - lambda state: logic.terran_early_tech(state)), - LocationData("The Outlaws", "The Outlaws: Bunker", SC2WOL_LOC_ID_OFFSET + 203, LocationType.VANILLA, - lambda state: logic.terran_early_tech(state)), - LocationData("The Outlaws", "The Outlaws: Close Resource Pickups", SC2WOL_LOC_ID_OFFSET + 204, LocationType.EXTRA), - LocationData("Zero Hour", "Zero Hour: Victory", SC2WOL_LOC_ID_OFFSET + 300, LocationType.VICTORY, - lambda state: logic.terran_common_unit(state) and - logic.terran_defense_rating(state, True) >= 2 and - (adv_tactics or logic.terran_basic_anti_air(state))), - LocationData("Zero Hour", "Zero Hour: First Group Rescued", SC2WOL_LOC_ID_OFFSET + 301, LocationType.VANILLA), - LocationData("Zero Hour", "Zero Hour: Second Group Rescued", SC2WOL_LOC_ID_OFFSET + 302, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state)), - LocationData("Zero Hour", "Zero Hour: Third Group Rescued", SC2WOL_LOC_ID_OFFSET + 303, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state) and - logic.terran_defense_rating(state, True) >= 2), - LocationData("Zero Hour", "Zero Hour: First Hatchery", SC2WOL_LOC_ID_OFFSET + 304, LocationType.CHALLENGE, - lambda state: logic.terran_competent_comp(state)), - LocationData("Zero Hour", "Zero Hour: Second Hatchery", SC2WOL_LOC_ID_OFFSET + 305, LocationType.CHALLENGE, - lambda state: logic.terran_competent_comp(state)), - LocationData("Zero Hour", "Zero Hour: Third Hatchery", SC2WOL_LOC_ID_OFFSET + 306, LocationType.CHALLENGE, - lambda state: logic.terran_competent_comp(state)), - LocationData("Zero Hour", "Zero Hour: Fourth Hatchery", SC2WOL_LOC_ID_OFFSET + 307, LocationType.CHALLENGE, - lambda state: logic.terran_competent_comp(state)), - LocationData("Zero Hour", "Zero Hour: Ride's on its Way", SC2WOL_LOC_ID_OFFSET + 308, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state)), - LocationData("Zero Hour", "Zero Hour: Hold Just a Little Longer", SC2WOL_LOC_ID_OFFSET + 309, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state) and - logic.terran_defense_rating(state, True) >= 2), - LocationData("Zero Hour", "Zero Hour: Cavalry's on the Way", SC2WOL_LOC_ID_OFFSET + 310, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state) and - logic.terran_defense_rating(state, True) >= 2), - LocationData("Evacuation", "Evacuation: Victory", SC2WOL_LOC_ID_OFFSET + 400, LocationType.VICTORY, - lambda state: logic.terran_early_tech(state) and - (adv_tactics and logic.terran_basic_anti_air(state) - or logic.terran_competent_anti_air(state))), - LocationData("Evacuation", "Evacuation: North Chrysalis", SC2WOL_LOC_ID_OFFSET + 401, LocationType.VANILLA), - LocationData("Evacuation", "Evacuation: West Chrysalis", SC2WOL_LOC_ID_OFFSET + 402, LocationType.VANILLA, - lambda state: logic.terran_early_tech(state)), - LocationData("Evacuation", "Evacuation: East Chrysalis", SC2WOL_LOC_ID_OFFSET + 403, LocationType.VANILLA, - lambda state: logic.terran_early_tech(state)), - LocationData("Evacuation", "Evacuation: Reach Hanson", SC2WOL_LOC_ID_OFFSET + 404, LocationType.EXTRA), - LocationData("Evacuation", "Evacuation: Secret Resource Stash", SC2WOL_LOC_ID_OFFSET + 405, LocationType.EXTRA), - LocationData("Evacuation", "Evacuation: Flawless", SC2WOL_LOC_ID_OFFSET + 406, LocationType.CHALLENGE, - lambda state: logic.terran_early_tech(state) and - logic.terran_defense_rating(state, True, False) >= 2 and - (adv_tactics and logic.terran_basic_anti_air(state) - or logic.terran_competent_anti_air(state))), - LocationData("Outbreak", "Outbreak: Victory", SC2WOL_LOC_ID_OFFSET + 500, LocationType.VICTORY, - lambda state: logic.terran_defense_rating(state, True, False) >= 4 and - (logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Outbreak", "Outbreak: Left Infestor", SC2WOL_LOC_ID_OFFSET + 501, LocationType.VANILLA, - lambda state: logic.terran_defense_rating(state, True, False) >= 2 and - (logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Outbreak", "Outbreak: Right Infestor", SC2WOL_LOC_ID_OFFSET + 502, LocationType.VANILLA, - lambda state: logic.terran_defense_rating(state, True, False) >= 2 and - (logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Outbreak", "Outbreak: North Infested Command Center", SC2WOL_LOC_ID_OFFSET + 503, LocationType.EXTRA, - lambda state: logic.terran_defense_rating(state, True, False) >= 2 and - (logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Outbreak", "Outbreak: South Infested Command Center", SC2WOL_LOC_ID_OFFSET + 504, LocationType.EXTRA, - lambda state: logic.terran_defense_rating(state, True, False) >= 2 and - (logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Outbreak", "Outbreak: Northwest Bar", SC2WOL_LOC_ID_OFFSET + 505, LocationType.EXTRA, - lambda state: logic.terran_defense_rating(state, True, False) >= 2 and - (logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Outbreak", "Outbreak: North Bar", SC2WOL_LOC_ID_OFFSET + 506, LocationType.EXTRA, - lambda state: logic.terran_defense_rating(state, True, False) >= 2 and - (logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Outbreak", "Outbreak: South Bar", SC2WOL_LOC_ID_OFFSET + 507, LocationType.EXTRA, - lambda state: logic.terran_defense_rating(state, True, False) >= 2 and - (logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Safe Haven", "Safe Haven: Victory", SC2WOL_LOC_ID_OFFSET + 600, LocationType.VICTORY, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state)), - LocationData("Safe Haven", "Safe Haven: North Nexus", SC2WOL_LOC_ID_OFFSET + 601, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state)), - LocationData("Safe Haven", "Safe Haven: East Nexus", SC2WOL_LOC_ID_OFFSET + 602, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state)), - LocationData("Safe Haven", "Safe Haven: South Nexus", SC2WOL_LOC_ID_OFFSET + 603, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state)), - LocationData("Safe Haven", "Safe Haven: First Terror Fleet", SC2WOL_LOC_ID_OFFSET + 604, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state)), - LocationData("Safe Haven", "Safe Haven: Second Terror Fleet", SC2WOL_LOC_ID_OFFSET + 605, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state)), - LocationData("Safe Haven", "Safe Haven: Third Terror Fleet", SC2WOL_LOC_ID_OFFSET + 606, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state)), - LocationData("Haven's Fall", "Haven's Fall: Victory", SC2WOL_LOC_ID_OFFSET + 700, LocationType.VICTORY, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state) and - logic.terran_defense_rating(state, True) >= 3), - LocationData("Haven's Fall", "Haven's Fall: North Hive", SC2WOL_LOC_ID_OFFSET + 701, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state) and - logic.terran_defense_rating(state, True) >= 3), - LocationData("Haven's Fall", "Haven's Fall: East Hive", SC2WOL_LOC_ID_OFFSET + 702, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state) and - logic.terran_defense_rating(state, True) >= 3), - LocationData("Haven's Fall", "Haven's Fall: South Hive", SC2WOL_LOC_ID_OFFSET + 703, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state) and - logic.terran_defense_rating(state, True) >= 3), - LocationData("Haven's Fall", "Haven's Fall: Northeast Colony Base", SC2WOL_LOC_ID_OFFSET + 704, LocationType.CHALLENGE, - lambda state: logic.terran_respond_to_colony_infestations(state)), - LocationData("Haven's Fall", "Haven's Fall: East Colony Base", SC2WOL_LOC_ID_OFFSET + 705, LocationType.CHALLENGE, - lambda state: logic.terran_respond_to_colony_infestations(state)), - LocationData("Haven's Fall", "Haven's Fall: Middle Colony Base", SC2WOL_LOC_ID_OFFSET + 706, LocationType.CHALLENGE, - lambda state: logic.terran_respond_to_colony_infestations(state)), - LocationData("Haven's Fall", "Haven's Fall: Southeast Colony Base", SC2WOL_LOC_ID_OFFSET + 707, LocationType.CHALLENGE, - lambda state: logic.terran_respond_to_colony_infestations(state)), - LocationData("Haven's Fall", "Haven's Fall: Southwest Colony Base", SC2WOL_LOC_ID_OFFSET + 708, LocationType.CHALLENGE, - lambda state: logic.terran_respond_to_colony_infestations(state)), - LocationData("Haven's Fall", "Haven's Fall: Southwest Gas Pickups", SC2WOL_LOC_ID_OFFSET + 709, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state) and - logic.terran_defense_rating(state, True) >= 3), - LocationData("Haven's Fall", "Haven's Fall: East Gas Pickups", SC2WOL_LOC_ID_OFFSET + 710, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state) and - logic.terran_defense_rating(state, True) >= 3), - LocationData("Haven's Fall", "Haven's Fall: Southeast Gas Pickups", SC2WOL_LOC_ID_OFFSET + 711, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state) and - logic.terran_competent_anti_air(state) and - logic.terran_defense_rating(state, True) >= 3), - LocationData("Smash and Grab", "Smash and Grab: Victory", SC2WOL_LOC_ID_OFFSET + 800, LocationType.VICTORY, - lambda state: logic.terran_common_unit(state) and - (adv_tactics and logic.terran_basic_anti_air(state) - or logic.terran_competent_anti_air(state))), - LocationData("Smash and Grab", "Smash and Grab: First Relic", SC2WOL_LOC_ID_OFFSET + 801, LocationType.VANILLA), - LocationData("Smash and Grab", "Smash and Grab: Second Relic", SC2WOL_LOC_ID_OFFSET + 802, LocationType.VANILLA), - LocationData("Smash and Grab", "Smash and Grab: Third Relic", SC2WOL_LOC_ID_OFFSET + 803, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state) and - (adv_tactics and logic.terran_basic_anti_air(state) - or logic.terran_competent_anti_air(state))), - LocationData("Smash and Grab", "Smash and Grab: Fourth Relic", SC2WOL_LOC_ID_OFFSET + 804, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state) and - (adv_tactics and logic.terran_basic_anti_air(state) - or logic.terran_competent_anti_air(state))), - LocationData("Smash and Grab", "Smash and Grab: First Forcefield Area Busted", SC2WOL_LOC_ID_OFFSET + 805, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state) and - (adv_tactics and logic.terran_basic_anti_air(state) - or logic.terran_competent_anti_air(state))), - LocationData("Smash and Grab", "Smash and Grab: Second Forcefield Area Busted", SC2WOL_LOC_ID_OFFSET + 806, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state) and - (adv_tactics and logic.terran_basic_anti_air(state) - or logic.terran_competent_anti_air(state))), - LocationData("The Dig", "The Dig: Victory", SC2WOL_LOC_ID_OFFSET + 900, LocationType.VICTORY, - lambda state: logic.terran_basic_anti_air(state) - and logic.terran_defense_rating(state, False, True) >= 8 - and logic.terran_defense_rating(state, False, False) >= 6 - and logic.terran_common_unit(state) - and (logic.marine_medic_upgrade(state) or adv_tactics)), - LocationData("The Dig", "The Dig: Left Relic", SC2WOL_LOC_ID_OFFSET + 901, LocationType.VANILLA, - lambda state: logic.terran_defense_rating(state, False, False) >= 6 - and logic.terran_common_unit(state) - and (logic.marine_medic_upgrade(state) or adv_tactics)), - LocationData("The Dig", "The Dig: Right Ground Relic", SC2WOL_LOC_ID_OFFSET + 902, LocationType.VANILLA, - lambda state: logic.terran_defense_rating(state, False, False) >= 6 - and logic.terran_common_unit(state) - and (logic.marine_medic_upgrade(state) or adv_tactics)), - LocationData("The Dig", "The Dig: Right Cliff Relic", SC2WOL_LOC_ID_OFFSET + 903, LocationType.VANILLA, - lambda state: logic.terran_defense_rating(state, False, False) >= 6 - and logic.terran_common_unit(state) - and (logic.marine_medic_upgrade(state) or adv_tactics)), - LocationData("The Dig", "The Dig: Moebius Base", SC2WOL_LOC_ID_OFFSET + 904, LocationType.EXTRA, - lambda state: logic.marine_medic_upgrade(state) or adv_tactics), - LocationData("The Dig", "The Dig: Door Outer Layer", SC2WOL_LOC_ID_OFFSET + 905, LocationType.EXTRA, - lambda state: logic.terran_defense_rating(state, False, False) >= 6 - and logic.terran_common_unit(state) - and (logic.marine_medic_upgrade(state) or adv_tactics)), - LocationData("The Dig", "The Dig: Door Thermal Barrier", SC2WOL_LOC_ID_OFFSET + 906, LocationType.EXTRA, - lambda state: logic.terran_basic_anti_air(state) - and logic.terran_defense_rating(state, False, True) >= 8 - and logic.terran_defense_rating(state, False, False) >= 6 - and logic.terran_common_unit(state) - and (logic.marine_medic_upgrade(state) or adv_tactics)), - LocationData("The Dig", "The Dig: Cutting Through the Core", SC2WOL_LOC_ID_OFFSET + 907, LocationType.EXTRA, - lambda state: logic.terran_basic_anti_air(state) - and logic.terran_defense_rating(state, False, True) >= 8 - and logic.terran_defense_rating(state, False, False) >= 6 - and logic.terran_common_unit(state) - and (logic.marine_medic_upgrade(state) or adv_tactics)), - LocationData("The Dig", "The Dig: Structure Access Imminent", SC2WOL_LOC_ID_OFFSET + 908, LocationType.EXTRA, - lambda state: logic.terran_basic_anti_air(state) - and logic.terran_defense_rating(state, False, True) >= 8 - and logic.terran_defense_rating(state, False, False) >= 6 - and logic.terran_common_unit(state) - and (logic.marine_medic_upgrade(state) or adv_tactics)), - LocationData("The Moebius Factor", "The Moebius Factor: Victory", SC2WOL_LOC_ID_OFFSET + 1000, LocationType.VICTORY, - lambda state: logic.terran_basic_anti_air(state) and - (logic.terran_air(state) - or state.has_any({ItemNames.MEDIVAC, ItemNames.HERCULES}, player) - and logic.terran_common_unit(state))), - LocationData("The Moebius Factor", "The Moebius Factor: 1st Data Core", SC2WOL_LOC_ID_OFFSET + 1001, LocationType.VANILLA), - LocationData("The Moebius Factor", "The Moebius Factor: 2nd Data Core", SC2WOL_LOC_ID_OFFSET + 1002, LocationType.VANILLA, - lambda state: (logic.terran_air(state) - or state.has_any({ItemNames.MEDIVAC, ItemNames.HERCULES}, player) - and logic.terran_common_unit(state))), - LocationData("The Moebius Factor", "The Moebius Factor: South Rescue", SC2WOL_LOC_ID_OFFSET + 1003, LocationType.EXTRA, - lambda state: logic.terran_can_rescue(state)), - LocationData("The Moebius Factor", "The Moebius Factor: Wall Rescue", SC2WOL_LOC_ID_OFFSET + 1004, LocationType.EXTRA, - lambda state: logic.terran_can_rescue(state)), - LocationData("The Moebius Factor", "The Moebius Factor: Mid Rescue", SC2WOL_LOC_ID_OFFSET + 1005, LocationType.EXTRA, - lambda state: logic.terran_can_rescue(state)), - LocationData("The Moebius Factor", "The Moebius Factor: Nydus Roof Rescue", SC2WOL_LOC_ID_OFFSET + 1006, LocationType.EXTRA, - lambda state: logic.terran_can_rescue(state)), - LocationData("The Moebius Factor", "The Moebius Factor: Alive Inside Rescue", SC2WOL_LOC_ID_OFFSET + 1007, LocationType.EXTRA, - lambda state: logic.terran_can_rescue(state)), - LocationData("The Moebius Factor", "The Moebius Factor: Brutalisk", SC2WOL_LOC_ID_OFFSET + 1008, LocationType.VANILLA, - lambda state: logic.terran_basic_anti_air(state) and - (logic.terran_air(state) - or state.has_any({ItemNames.MEDIVAC, ItemNames.HERCULES}, player) - and logic.terran_common_unit(state))), - LocationData("The Moebius Factor", "The Moebius Factor: 3rd Data Core", SC2WOL_LOC_ID_OFFSET + 1009, LocationType.VANILLA, - lambda state: logic.terran_basic_anti_air(state) and - (logic.terran_air(state) - or state.has_any({ItemNames.MEDIVAC, ItemNames.HERCULES}, player) - and logic.terran_common_unit(state))), - LocationData("Supernova", "Supernova: Victory", SC2WOL_LOC_ID_OFFSET + 1100, LocationType.VICTORY, - lambda state: logic.terran_beats_protoss_deathball(state)), - LocationData("Supernova", "Supernova: West Relic", SC2WOL_LOC_ID_OFFSET + 1101, LocationType.VANILLA), - LocationData("Supernova", "Supernova: North Relic", SC2WOL_LOC_ID_OFFSET + 1102, LocationType.VANILLA), - LocationData("Supernova", "Supernova: South Relic", SC2WOL_LOC_ID_OFFSET + 1103, LocationType.VANILLA, - lambda state: logic.terran_beats_protoss_deathball(state)), - LocationData("Supernova", "Supernova: East Relic", SC2WOL_LOC_ID_OFFSET + 1104, LocationType.VANILLA, - lambda state: logic.terran_beats_protoss_deathball(state)), - LocationData("Supernova", "Supernova: Landing Zone Cleared", SC2WOL_LOC_ID_OFFSET + 1105, LocationType.EXTRA), - LocationData("Supernova", "Supernova: Middle Base", SC2WOL_LOC_ID_OFFSET + 1106, LocationType.EXTRA, - lambda state: logic.terran_beats_protoss_deathball(state)), - LocationData("Supernova", "Supernova: Southeast Base", SC2WOL_LOC_ID_OFFSET + 1107, LocationType.EXTRA, - lambda state: logic.terran_beats_protoss_deathball(state)), - LocationData("Maw of the Void", "Maw of the Void: Victory", SC2WOL_LOC_ID_OFFSET + 1200, LocationType.VICTORY, - lambda state: logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: Landing Zone Cleared", SC2WOL_LOC_ID_OFFSET + 1201, LocationType.EXTRA), - LocationData("Maw of the Void", "Maw of the Void: Expansion Prisoners", SC2WOL_LOC_ID_OFFSET + 1202, LocationType.VANILLA, - lambda state: adv_tactics or logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: South Close Prisoners", SC2WOL_LOC_ID_OFFSET + 1203, LocationType.VANILLA, - lambda state: adv_tactics or logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: South Far Prisoners", SC2WOL_LOC_ID_OFFSET + 1204, LocationType.VANILLA, - lambda state: logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: North Prisoners", SC2WOL_LOC_ID_OFFSET + 1205, LocationType.VANILLA, - lambda state: logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: Mothership", SC2WOL_LOC_ID_OFFSET + 1206, LocationType.EXTRA, - lambda state: logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: Expansion Rip Field Generator", SC2WOL_LOC_ID_OFFSET + 1207, LocationType.EXTRA, - lambda state: adv_tactics or logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: Middle Rip Field Generator", SC2WOL_LOC_ID_OFFSET + 1208, LocationType.EXTRA, - lambda state: logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: Southeast Rip Field Generator", SC2WOL_LOC_ID_OFFSET + 1209, LocationType.EXTRA, - lambda state: logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: Stargate Rip Field Generator", SC2WOL_LOC_ID_OFFSET + 1210, LocationType.EXTRA, - lambda state: logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: Northwest Rip Field Generator", SC2WOL_LOC_ID_OFFSET + 1211, LocationType.CHALLENGE, - lambda state: logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: West Rip Field Generator", SC2WOL_LOC_ID_OFFSET + 1212, LocationType.CHALLENGE, - lambda state: logic.terran_survives_rip_field(state)), - LocationData("Maw of the Void", "Maw of the Void: Southwest Rip Field Generator", SC2WOL_LOC_ID_OFFSET + 1213, LocationType.CHALLENGE, - lambda state: logic.terran_survives_rip_field(state)), - LocationData("Devil's Playground", "Devil's Playground: Victory", SC2WOL_LOC_ID_OFFSET + 1300, LocationType.VICTORY, - lambda state: adv_tactics or - logic.terran_basic_anti_air(state) and ( - logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Devil's Playground", "Devil's Playground: Tosh's Miners", SC2WOL_LOC_ID_OFFSET + 1301, LocationType.VANILLA), - LocationData("Devil's Playground", "Devil's Playground: Brutalisk", SC2WOL_LOC_ID_OFFSET + 1302, LocationType.VANILLA, - lambda state: adv_tactics or logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player)), - LocationData("Devil's Playground", "Devil's Playground: North Reapers", SC2WOL_LOC_ID_OFFSET + 1303, LocationType.EXTRA), - LocationData("Devil's Playground", "Devil's Playground: Middle Reapers", SC2WOL_LOC_ID_OFFSET + 1304, LocationType.EXTRA, - lambda state: adv_tactics or logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player)), - LocationData("Devil's Playground", "Devil's Playground: Southwest Reapers", SC2WOL_LOC_ID_OFFSET + 1305, LocationType.EXTRA, - lambda state: adv_tactics or logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player)), - LocationData("Devil's Playground", "Devil's Playground: Southeast Reapers", SC2WOL_LOC_ID_OFFSET + 1306, LocationType.EXTRA, - lambda state: adv_tactics or - logic.terran_basic_anti_air(state) and ( - logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Devil's Playground", "Devil's Playground: East Reapers", SC2WOL_LOC_ID_OFFSET + 1307, LocationType.CHALLENGE, - lambda state: logic.terran_basic_anti_air(state) and - (adv_tactics or - logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Devil's Playground", "Devil's Playground: Zerg Cleared", SC2WOL_LOC_ID_OFFSET + 1308, LocationType.CHALLENGE, - lambda state: logic.terran_competent_anti_air(state) and ( - logic.terran_common_unit(state) or state.has(ItemNames.REAPER, player))), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: Victory", SC2WOL_LOC_ID_OFFSET + 1400, LocationType.VICTORY, - lambda state: logic.welcome_to_the_jungle_requirement(state)), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: Close Relic", SC2WOL_LOC_ID_OFFSET + 1401, LocationType.VANILLA), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: West Relic", SC2WOL_LOC_ID_OFFSET + 1402, LocationType.VANILLA, - lambda state: logic.welcome_to_the_jungle_requirement(state)), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: North-East Relic", SC2WOL_LOC_ID_OFFSET + 1403, LocationType.VANILLA, - lambda state: logic.welcome_to_the_jungle_requirement(state)), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: Middle Base", SC2WOL_LOC_ID_OFFSET + 1404, LocationType.EXTRA, - lambda state: logic.welcome_to_the_jungle_requirement(state)), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: Main Base", SC2WOL_LOC_ID_OFFSET + 1405, - LocationType.MASTERY, - lambda state: logic.welcome_to_the_jungle_requirement(state) - and logic.terran_beats_protoss_deathball(state) - and logic.terran_base_trasher(state)), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: No Terrazine Nodes Sealed", SC2WOL_LOC_ID_OFFSET + 1406, LocationType.CHALLENGE, - lambda state: logic.welcome_to_the_jungle_requirement(state) - and logic.terran_competent_ground_to_air(state) - and logic.terran_beats_protoss_deathball(state)), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: Up to 1 Terrazine Node Sealed", SC2WOL_LOC_ID_OFFSET + 1407, LocationType.CHALLENGE, - lambda state: logic.welcome_to_the_jungle_requirement(state) - and logic.terran_competent_ground_to_air(state) - and logic.terran_beats_protoss_deathball(state)), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: Up to 2 Terrazine Nodes Sealed", SC2WOL_LOC_ID_OFFSET + 1408, LocationType.CHALLENGE, - lambda state: logic.welcome_to_the_jungle_requirement(state) - and logic.terran_beats_protoss_deathball(state)), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: Up to 3 Terrazine Nodes Sealed", SC2WOL_LOC_ID_OFFSET + 1409, LocationType.CHALLENGE, - lambda state: logic.welcome_to_the_jungle_requirement(state) - and logic.terran_competent_comp(state)), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: Up to 4 Terrazine Nodes Sealed", SC2WOL_LOC_ID_OFFSET + 1410, LocationType.EXTRA, - lambda state: logic.welcome_to_the_jungle_requirement(state)), - LocationData("Welcome to the Jungle", "Welcome to the Jungle: Up to 5 Terrazine Nodes Sealed", SC2WOL_LOC_ID_OFFSET + 1411, LocationType.EXTRA, - lambda state: logic.welcome_to_the_jungle_requirement(state)), - LocationData("Breakout", "Breakout: Victory", SC2WOL_LOC_ID_OFFSET + 1500, LocationType.VICTORY), - LocationData("Breakout", "Breakout: Diamondback Prison", SC2WOL_LOC_ID_OFFSET + 1501, LocationType.VANILLA), - LocationData("Breakout", "Breakout: Siege Tank Prison", SC2WOL_LOC_ID_OFFSET + 1502, LocationType.VANILLA), - LocationData("Breakout", "Breakout: First Checkpoint", SC2WOL_LOC_ID_OFFSET + 1503, LocationType.EXTRA), - LocationData("Breakout", "Breakout: Second Checkpoint", SC2WOL_LOC_ID_OFFSET + 1504, LocationType.EXTRA), - LocationData("Ghost of a Chance", "Ghost of a Chance: Victory", SC2WOL_LOC_ID_OFFSET + 1600, LocationType.VICTORY), - LocationData("Ghost of a Chance", "Ghost of a Chance: Terrazine Tank", SC2WOL_LOC_ID_OFFSET + 1601, LocationType.EXTRA), - LocationData("Ghost of a Chance", "Ghost of a Chance: Jorium Stockpile", SC2WOL_LOC_ID_OFFSET + 1602, LocationType.EXTRA), - LocationData("Ghost of a Chance", "Ghost of a Chance: First Island Spectres", SC2WOL_LOC_ID_OFFSET + 1603, LocationType.VANILLA), - LocationData("Ghost of a Chance", "Ghost of a Chance: Second Island Spectres", SC2WOL_LOC_ID_OFFSET + 1604, LocationType.VANILLA), - LocationData("Ghost of a Chance", "Ghost of a Chance: Third Island Spectres", SC2WOL_LOC_ID_OFFSET + 1605, LocationType.VANILLA), - LocationData("The Great Train Robbery", "The Great Train Robbery: Victory", SC2WOL_LOC_ID_OFFSET + 1700, LocationType.VICTORY, - lambda state: logic.great_train_robbery_train_stopper(state) and - logic.terran_basic_anti_air(state)), - LocationData("The Great Train Robbery", "The Great Train Robbery: North Defiler", SC2WOL_LOC_ID_OFFSET + 1701, LocationType.VANILLA), - LocationData("The Great Train Robbery", "The Great Train Robbery: Mid Defiler", SC2WOL_LOC_ID_OFFSET + 1702, LocationType.VANILLA), - LocationData("The Great Train Robbery", "The Great Train Robbery: South Defiler", SC2WOL_LOC_ID_OFFSET + 1703, LocationType.VANILLA), - LocationData("The Great Train Robbery", "The Great Train Robbery: Close Diamondback", SC2WOL_LOC_ID_OFFSET + 1704, LocationType.EXTRA), - LocationData("The Great Train Robbery", "The Great Train Robbery: Northwest Diamondback", SC2WOL_LOC_ID_OFFSET + 1705, LocationType.EXTRA), - LocationData("The Great Train Robbery", "The Great Train Robbery: North Diamondback", SC2WOL_LOC_ID_OFFSET + 1706, LocationType.EXTRA), - LocationData("The Great Train Robbery", "The Great Train Robbery: Northeast Diamondback", SC2WOL_LOC_ID_OFFSET + 1707, LocationType.EXTRA), - LocationData("The Great Train Robbery", "The Great Train Robbery: Southwest Diamondback", SC2WOL_LOC_ID_OFFSET + 1708, LocationType.EXTRA), - LocationData("The Great Train Robbery", "The Great Train Robbery: Southeast Diamondback", SC2WOL_LOC_ID_OFFSET + 1709, LocationType.EXTRA), - LocationData("The Great Train Robbery", "The Great Train Robbery: Kill Team", SC2WOL_LOC_ID_OFFSET + 1710, LocationType.CHALLENGE, - lambda state: (adv_tactics or logic.terran_common_unit(state)) and - logic.great_train_robbery_train_stopper(state) and - logic.terran_basic_anti_air(state)), - LocationData("The Great Train Robbery", "The Great Train Robbery: Flawless", SC2WOL_LOC_ID_OFFSET + 1711, LocationType.CHALLENGE, - lambda state: logic.great_train_robbery_train_stopper(state) and - logic.terran_basic_anti_air(state)), - LocationData("The Great Train Robbery", "The Great Train Robbery: 2 Trains Destroyed", SC2WOL_LOC_ID_OFFSET + 1712, LocationType.EXTRA, - lambda state: logic.great_train_robbery_train_stopper(state)), - LocationData("The Great Train Robbery", "The Great Train Robbery: 4 Trains Destroyed", SC2WOL_LOC_ID_OFFSET + 1713, LocationType.EXTRA, - lambda state: logic.great_train_robbery_train_stopper(state) and - logic.terran_basic_anti_air(state)), - LocationData("The Great Train Robbery", "The Great Train Robbery: 6 Trains Destroyed", SC2WOL_LOC_ID_OFFSET + 1714, LocationType.EXTRA, - lambda state: logic.great_train_robbery_train_stopper(state) and - logic.terran_basic_anti_air(state)), - LocationData("Cutthroat", "Cutthroat: Victory", SC2WOL_LOC_ID_OFFSET + 1800, LocationType.VICTORY, - lambda state: logic.terran_common_unit(state) and - (adv_tactics or logic.terran_basic_anti_air)), - LocationData("Cutthroat", "Cutthroat: Mira Han", SC2WOL_LOC_ID_OFFSET + 1801, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state)), - LocationData("Cutthroat", "Cutthroat: North Relic", SC2WOL_LOC_ID_OFFSET + 1802, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state)), - LocationData("Cutthroat", "Cutthroat: Mid Relic", SC2WOL_LOC_ID_OFFSET + 1803, LocationType.VANILLA), - LocationData("Cutthroat", "Cutthroat: Southwest Relic", SC2WOL_LOC_ID_OFFSET + 1804, LocationType.VANILLA, - lambda state: logic.terran_common_unit(state)), - LocationData("Cutthroat", "Cutthroat: North Command Center", SC2WOL_LOC_ID_OFFSET + 1805, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state)), - LocationData("Cutthroat", "Cutthroat: South Command Center", SC2WOL_LOC_ID_OFFSET + 1806, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state)), - LocationData("Cutthroat", "Cutthroat: West Command Center", SC2WOL_LOC_ID_OFFSET + 1807, LocationType.EXTRA, - lambda state: logic.terran_common_unit(state)), - LocationData("Engine of Destruction", "Engine of Destruction: Victory", SC2WOL_LOC_ID_OFFSET + 1900, LocationType.VICTORY, - lambda state: logic.engine_of_destruction_requirement(state)), - LocationData("Engine of Destruction", "Engine of Destruction: Odin", SC2WOL_LOC_ID_OFFSET + 1901, LocationType.EXTRA, - lambda state: logic.marine_medic_upgrade(state)), - LocationData("Engine of Destruction", "Engine of Destruction: Loki", SC2WOL_LOC_ID_OFFSET + 1902, - LocationType.CHALLENGE, - lambda state: logic.engine_of_destruction_requirement(state)), - LocationData("Engine of Destruction", "Engine of Destruction: Lab Devourer", SC2WOL_LOC_ID_OFFSET + 1903, LocationType.VANILLA, - lambda state: logic.marine_medic_upgrade(state)), - LocationData("Engine of Destruction", "Engine of Destruction: North Devourer", SC2WOL_LOC_ID_OFFSET + 1904, LocationType.VANILLA, - lambda state: logic.engine_of_destruction_requirement(state)), - LocationData("Engine of Destruction", "Engine of Destruction: Southeast Devourer", SC2WOL_LOC_ID_OFFSET + 1905, LocationType.VANILLA, - lambda state: logic.engine_of_destruction_requirement(state)), - LocationData("Engine of Destruction", "Engine of Destruction: West Base", SC2WOL_LOC_ID_OFFSET + 1906, LocationType.EXTRA, - lambda state: logic.engine_of_destruction_requirement(state)), - LocationData("Engine of Destruction", "Engine of Destruction: Northwest Base", SC2WOL_LOC_ID_OFFSET + 1907, LocationType.EXTRA, - lambda state: logic.engine_of_destruction_requirement(state)), - LocationData("Engine of Destruction", "Engine of Destruction: Northeast Base", SC2WOL_LOC_ID_OFFSET + 1908, LocationType.EXTRA, - lambda state: logic.engine_of_destruction_requirement(state)), - LocationData("Engine of Destruction", "Engine of Destruction: Southeast Base", SC2WOL_LOC_ID_OFFSET + 1909, LocationType.EXTRA, - lambda state: logic.engine_of_destruction_requirement(state)), - LocationData("Media Blitz", "Media Blitz: Victory", SC2WOL_LOC_ID_OFFSET + 2000, LocationType.VICTORY, - lambda state: logic.terran_competent_comp(state)), - LocationData("Media Blitz", "Media Blitz: Tower 1", SC2WOL_LOC_ID_OFFSET + 2001, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Media Blitz", "Media Blitz: Tower 2", SC2WOL_LOC_ID_OFFSET + 2002, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Media Blitz", "Media Blitz: Tower 3", SC2WOL_LOC_ID_OFFSET + 2003, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Media Blitz", "Media Blitz: Science Facility", SC2WOL_LOC_ID_OFFSET + 2004, LocationType.VANILLA), - LocationData("Media Blitz", "Media Blitz: All Barracks", SC2WOL_LOC_ID_OFFSET + 2005, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Media Blitz", "Media Blitz: All Factories", SC2WOL_LOC_ID_OFFSET + 2006, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Media Blitz", "Media Blitz: All Starports", SC2WOL_LOC_ID_OFFSET + 2007, LocationType.EXTRA, - lambda state: adv_tactics or logic.terran_competent_comp(state)), - LocationData("Media Blitz", "Media Blitz: Odin Not Trashed", SC2WOL_LOC_ID_OFFSET + 2008, LocationType.CHALLENGE, - lambda state: logic.terran_competent_comp(state)), - LocationData("Media Blitz", "Media Blitz: Surprise Attack Ends", SC2WOL_LOC_ID_OFFSET + 2009, LocationType.EXTRA), - LocationData("Piercing the Shroud", "Piercing the Shroud: Victory", SC2WOL_LOC_ID_OFFSET + 2100, LocationType.VICTORY, - lambda state: logic.marine_medic_upgrade(state)), - LocationData("Piercing the Shroud", "Piercing the Shroud: Holding Cell Relic", SC2WOL_LOC_ID_OFFSET + 2101, LocationType.VANILLA), - LocationData("Piercing the Shroud", "Piercing the Shroud: Brutalisk Relic", SC2WOL_LOC_ID_OFFSET + 2102, LocationType.VANILLA, - lambda state: logic.marine_medic_upgrade(state)), - LocationData("Piercing the Shroud", "Piercing the Shroud: First Escape Relic", SC2WOL_LOC_ID_OFFSET + 2103, LocationType.VANILLA, - lambda state: logic.marine_medic_upgrade(state)), - LocationData("Piercing the Shroud", "Piercing the Shroud: Second Escape Relic", SC2WOL_LOC_ID_OFFSET + 2104, LocationType.VANILLA, - lambda state: logic.marine_medic_upgrade(state)), - LocationData("Piercing the Shroud", "Piercing the Shroud: Brutalisk", SC2WOL_LOC_ID_OFFSET + 2105, LocationType.VANILLA, - lambda state: logic.marine_medic_upgrade(state)), - LocationData("Piercing the Shroud", "Piercing the Shroud: Fusion Reactor", SC2WOL_LOC_ID_OFFSET + 2106, LocationType.EXTRA, - lambda state: logic.marine_medic_upgrade(state)), - LocationData("Piercing the Shroud", "Piercing the Shroud: Entrance Holding Pen", SC2WOL_LOC_ID_OFFSET + 2107, LocationType.EXTRA), - LocationData("Piercing the Shroud", "Piercing the Shroud: Cargo Bay Warbot", SC2WOL_LOC_ID_OFFSET + 2108, LocationType.EXTRA), - LocationData("Piercing the Shroud", "Piercing the Shroud: Escape Warbot", SC2WOL_LOC_ID_OFFSET + 2109, LocationType.EXTRA, - lambda state: logic.marine_medic_upgrade(state)), - LocationData("Whispers of Doom", "Whispers of Doom: Victory", SC2WOL_LOC_ID_OFFSET + 2200, LocationType.VICTORY), - LocationData("Whispers of Doom", "Whispers of Doom: First Hatchery", SC2WOL_LOC_ID_OFFSET + 2201, LocationType.VANILLA), - LocationData("Whispers of Doom", "Whispers of Doom: Second Hatchery", SC2WOL_LOC_ID_OFFSET + 2202, LocationType.VANILLA), - LocationData("Whispers of Doom", "Whispers of Doom: Third Hatchery", SC2WOL_LOC_ID_OFFSET + 2203, LocationType.VANILLA), - LocationData("Whispers of Doom", "Whispers of Doom: First Prophecy Fragment", SC2WOL_LOC_ID_OFFSET + 2204, LocationType.EXTRA), - LocationData("Whispers of Doom", "Whispers of Doom: Second Prophecy Fragment", SC2WOL_LOC_ID_OFFSET + 2205, LocationType.EXTRA), - LocationData("Whispers of Doom", "Whispers of Doom: Third Prophecy Fragment", SC2WOL_LOC_ID_OFFSET + 2206, LocationType.EXTRA), - LocationData("A Sinister Turn", "A Sinister Turn: Victory", SC2WOL_LOC_ID_OFFSET + 2300, LocationType.VICTORY, - lambda state: logic.protoss_common_unit(state) and logic.protoss_competent_anti_air(state)), - LocationData("A Sinister Turn", "A Sinister Turn: Robotics Facility", SC2WOL_LOC_ID_OFFSET + 2301, LocationType.VANILLA, - lambda state: adv_tactics or logic.protoss_common_unit(state)), - LocationData("A Sinister Turn", "A Sinister Turn: Dark Shrine", SC2WOL_LOC_ID_OFFSET + 2302, LocationType.VANILLA, - lambda state: adv_tactics or logic.protoss_common_unit(state)), - LocationData("A Sinister Turn", "A Sinister Turn: Templar Archives", SC2WOL_LOC_ID_OFFSET + 2303, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) and logic.protoss_competent_anti_air(state)), - LocationData("A Sinister Turn", "A Sinister Turn: Northeast Base", SC2WOL_LOC_ID_OFFSET + 2304, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) and logic.protoss_competent_anti_air(state)), - LocationData("A Sinister Turn", "A Sinister Turn: Southwest Base", SC2WOL_LOC_ID_OFFSET + 2305, LocationType.CHALLENGE, - lambda state: logic.protoss_common_unit(state) and logic.protoss_competent_anti_air(state)), - LocationData("A Sinister Turn", "A Sinister Turn: Maar", SC2WOL_LOC_ID_OFFSET + 2306, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state)), - LocationData("A Sinister Turn", "A Sinister Turn: Northwest Preserver", SC2WOL_LOC_ID_OFFSET + 2307, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) and logic.protoss_competent_anti_air(state)), - LocationData("A Sinister Turn", "A Sinister Turn: Southwest Preserver", SC2WOL_LOC_ID_OFFSET + 2308, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) and logic.protoss_competent_anti_air(state)), - LocationData("A Sinister Turn", "A Sinister Turn: East Preserver", SC2WOL_LOC_ID_OFFSET + 2309, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) and logic.protoss_competent_anti_air(state)), - LocationData("Echoes of the Future", "Echoes of the Future: Victory", SC2WOL_LOC_ID_OFFSET + 2400, LocationType.VICTORY, - lambda state: adv_tactics and logic.protoss_static_defense(state) or logic.protoss_common_unit(state) and logic.protoss_competent_anti_air(state)), - LocationData("Echoes of the Future", "Echoes of the Future: Close Obelisk", SC2WOL_LOC_ID_OFFSET + 2401, LocationType.VANILLA), - LocationData("Echoes of the Future", "Echoes of the Future: West Obelisk", SC2WOL_LOC_ID_OFFSET + 2402, LocationType.VANILLA, - lambda state: adv_tactics and logic.protoss_static_defense(state) or logic.protoss_common_unit(state)), - LocationData("Echoes of the Future", "Echoes of the Future: Base", SC2WOL_LOC_ID_OFFSET + 2403, LocationType.EXTRA), - LocationData("Echoes of the Future", "Echoes of the Future: Southwest Tendril", SC2WOL_LOC_ID_OFFSET + 2404, LocationType.EXTRA), - LocationData("Echoes of the Future", "Echoes of the Future: Southeast Tendril", SC2WOL_LOC_ID_OFFSET + 2405, LocationType.EXTRA, - lambda state: adv_tactics and logic.protoss_static_defense(state) or logic.protoss_common_unit(state)), - LocationData("Echoes of the Future", "Echoes of the Future: Northeast Tendril", SC2WOL_LOC_ID_OFFSET + 2406, LocationType.EXTRA, - lambda state: adv_tactics and logic.protoss_static_defense(state) or logic.protoss_common_unit(state)), - LocationData("Echoes of the Future", "Echoes of the Future: Northwest Tendril", SC2WOL_LOC_ID_OFFSET + 2407, LocationType.EXTRA, - lambda state: adv_tactics and logic.protoss_static_defense(state) or logic.protoss_common_unit(state)), - LocationData("In Utter Darkness", "In Utter Darkness: Defeat", SC2WOL_LOC_ID_OFFSET + 2500, LocationType.VICTORY), - LocationData("In Utter Darkness", "In Utter Darkness: Protoss Archive", SC2WOL_LOC_ID_OFFSET + 2501, LocationType.VANILLA, - lambda state: logic.last_stand_requirement(state)), - LocationData("In Utter Darkness", "In Utter Darkness: Kills", SC2WOL_LOC_ID_OFFSET + 2502, LocationType.VANILLA, - lambda state: logic.last_stand_requirement(state)), - LocationData("In Utter Darkness", "In Utter Darkness: Urun", SC2WOL_LOC_ID_OFFSET + 2503, LocationType.EXTRA), - LocationData("In Utter Darkness", "In Utter Darkness: Mohandar", SC2WOL_LOC_ID_OFFSET + 2504, LocationType.EXTRA, - lambda state: logic.last_stand_requirement(state)), - LocationData("In Utter Darkness", "In Utter Darkness: Selendis", SC2WOL_LOC_ID_OFFSET + 2505, LocationType.EXTRA, - lambda state: logic.last_stand_requirement(state)), - LocationData("In Utter Darkness", "In Utter Darkness: Artanis", SC2WOL_LOC_ID_OFFSET + 2506, LocationType.EXTRA, - lambda state: logic.last_stand_requirement(state)), - LocationData("Gates of Hell", "Gates of Hell: Victory", SC2WOL_LOC_ID_OFFSET + 2600, LocationType.VICTORY, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: Large Army", SC2WOL_LOC_ID_OFFSET + 2601, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: 2 Drop Pods", SC2WOL_LOC_ID_OFFSET + 2602, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: 4 Drop Pods", SC2WOL_LOC_ID_OFFSET + 2603, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: 6 Drop Pods", SC2WOL_LOC_ID_OFFSET + 2604, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: 8 Drop Pods", SC2WOL_LOC_ID_OFFSET + 2605, LocationType.CHALLENGE, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: Southwest Spore Cannon", SC2WOL_LOC_ID_OFFSET + 2606, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: Northwest Spore Cannon", SC2WOL_LOC_ID_OFFSET + 2607, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: Northeast Spore Cannon", SC2WOL_LOC_ID_OFFSET + 2608, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: East Spore Cannon", SC2WOL_LOC_ID_OFFSET + 2609, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: Southeast Spore Cannon", SC2WOL_LOC_ID_OFFSET + 2610, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Gates of Hell", "Gates of Hell: Expansion Spore Cannon", SC2WOL_LOC_ID_OFFSET + 2611, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state) and - logic.terran_defense_rating(state, True) > 6), - LocationData("Belly of the Beast", "Belly of the Beast: Victory", SC2WOL_LOC_ID_OFFSET + 2700, LocationType.VICTORY), - LocationData("Belly of the Beast", "Belly of the Beast: First Charge", SC2WOL_LOC_ID_OFFSET + 2701, LocationType.EXTRA), - LocationData("Belly of the Beast", "Belly of the Beast: Second Charge", SC2WOL_LOC_ID_OFFSET + 2702, LocationType.EXTRA), - LocationData("Belly of the Beast", "Belly of the Beast: Third Charge", SC2WOL_LOC_ID_OFFSET + 2703, LocationType.EXTRA), - LocationData("Belly of the Beast", "Belly of the Beast: First Group Rescued", SC2WOL_LOC_ID_OFFSET + 2704, LocationType.VANILLA), - LocationData("Belly of the Beast", "Belly of the Beast: Second Group Rescued", SC2WOL_LOC_ID_OFFSET + 2705, LocationType.VANILLA), - LocationData("Belly of the Beast", "Belly of the Beast: Third Group Rescued", SC2WOL_LOC_ID_OFFSET + 2706, LocationType.VANILLA), - LocationData("Shatter the Sky", "Shatter the Sky: Victory", SC2WOL_LOC_ID_OFFSET + 2800, LocationType.VICTORY, - lambda state: logic.terran_competent_comp(state)), - LocationData("Shatter the Sky", "Shatter the Sky: Close Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2801, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Shatter the Sky", "Shatter the Sky: Northwest Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2802, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Shatter the Sky", "Shatter the Sky: Southeast Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2803, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Shatter the Sky", "Shatter the Sky: Southwest Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2804, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Shatter the Sky", "Shatter the Sky: Leviathan", SC2WOL_LOC_ID_OFFSET + 2805, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Shatter the Sky", "Shatter the Sky: East Hatchery", SC2WOL_LOC_ID_OFFSET + 2806, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Shatter the Sky", "Shatter the Sky: North Hatchery", SC2WOL_LOC_ID_OFFSET + 2807, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state)), - LocationData("Shatter the Sky", "Shatter the Sky: Mid Hatchery", SC2WOL_LOC_ID_OFFSET + 2808, LocationType.EXTRA, - lambda state: logic.terran_competent_comp(state)), - LocationData("All-In", "All-In: Victory", SC2WOL_LOC_ID_OFFSET + 2900, LocationType.VICTORY, - lambda state: logic.all_in_requirement(state)), - LocationData("All-In", "All-In: First Kerrigan Attack", SC2WOL_LOC_ID_OFFSET + 2901, LocationType.EXTRA, - lambda state: logic.all_in_requirement(state)), - LocationData("All-In", "All-In: Second Kerrigan Attack", SC2WOL_LOC_ID_OFFSET + 2902, LocationType.EXTRA, - lambda state: logic.all_in_requirement(state)), - LocationData("All-In", "All-In: Third Kerrigan Attack", SC2WOL_LOC_ID_OFFSET + 2903, LocationType.EXTRA, - lambda state: logic.all_in_requirement(state)), - LocationData("All-In", "All-In: Fourth Kerrigan Attack", SC2WOL_LOC_ID_OFFSET + 2904, LocationType.EXTRA, - lambda state: logic.all_in_requirement(state)), - LocationData("All-In", "All-In: Fifth Kerrigan Attack", SC2WOL_LOC_ID_OFFSET + 2905, LocationType.EXTRA, - lambda state: logic.all_in_requirement(state)), - - # HotS - LocationData("Lab Rat", "Lab Rat: Victory", SC2HOTS_LOC_ID_OFFSET + 100, LocationType.VICTORY, - lambda state: logic.zerg_common_unit(state)), - LocationData("Lab Rat", "Lab Rat: Gather Minerals", SC2HOTS_LOC_ID_OFFSET + 101, LocationType.VANILLA), - LocationData("Lab Rat", "Lab Rat: South Zergling Group", SC2HOTS_LOC_ID_OFFSET + 102, LocationType.VANILLA, - lambda state: adv_tactics or logic.zerg_common_unit(state)), - LocationData("Lab Rat", "Lab Rat: East Zergling Group", SC2HOTS_LOC_ID_OFFSET + 103, LocationType.VANILLA, - lambda state: adv_tactics or logic.zerg_common_unit(state)), - LocationData("Lab Rat", "Lab Rat: West Zergling Group", SC2HOTS_LOC_ID_OFFSET + 104, LocationType.VANILLA, - lambda state: adv_tactics or logic.zerg_common_unit(state)), - LocationData("Lab Rat", "Lab Rat: Hatchery", SC2HOTS_LOC_ID_OFFSET + 105, LocationType.EXTRA), - LocationData("Lab Rat", "Lab Rat: Overlord", SC2HOTS_LOC_ID_OFFSET + 106, LocationType.EXTRA), - LocationData("Lab Rat", "Lab Rat: Gas Turrets", SC2HOTS_LOC_ID_OFFSET + 107, LocationType.EXTRA, - lambda state: adv_tactics or logic.zerg_common_unit(state)), - LocationData("Back in the Saddle", "Back in the Saddle: Victory", SC2HOTS_LOC_ID_OFFSET + 200, LocationType.VICTORY, - lambda state: logic.basic_kerrigan(state) or kerriganless or logic.story_tech_granted), - LocationData("Back in the Saddle", "Back in the Saddle: Defend the Tram", SC2HOTS_LOC_ID_OFFSET + 201, LocationType.EXTRA, - lambda state: logic.basic_kerrigan(state) or kerriganless or logic.story_tech_granted), - LocationData("Back in the Saddle", "Back in the Saddle: Kinetic Blast", SC2HOTS_LOC_ID_OFFSET + 202, LocationType.VANILLA), - LocationData("Back in the Saddle", "Back in the Saddle: Crushing Grip", SC2HOTS_LOC_ID_OFFSET + 203, LocationType.VANILLA), - LocationData("Back in the Saddle", "Back in the Saddle: Reach the Sublevel", SC2HOTS_LOC_ID_OFFSET + 204, LocationType.EXTRA), - LocationData("Back in the Saddle", "Back in the Saddle: Door Section Cleared", SC2HOTS_LOC_ID_OFFSET + 205, LocationType.EXTRA, - lambda state: logic.basic_kerrigan(state) or kerriganless or logic.story_tech_granted), - LocationData("Rendezvous", "Rendezvous: Victory", SC2HOTS_LOC_ID_OFFSET + 300, LocationType.VICTORY, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Rendezvous", "Rendezvous: Right Queen", SC2HOTS_LOC_ID_OFFSET + 301, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Rendezvous", "Rendezvous: Center Queen", SC2HOTS_LOC_ID_OFFSET + 302, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Rendezvous", "Rendezvous: Left Queen", SC2HOTS_LOC_ID_OFFSET + 303, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Rendezvous", "Rendezvous: Hold Out Finished", SC2HOTS_LOC_ID_OFFSET + 304, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Harvest of Screams", "Harvest of Screams: Victory", SC2HOTS_LOC_ID_OFFSET + 400, LocationType.VICTORY, - lambda state: logic.zerg_common_unit(state) - and logic.zerg_basic_anti_air(state)), - LocationData("Harvest of Screams", "Harvest of Screams: First Ursadon Matriarch", SC2HOTS_LOC_ID_OFFSET + 401, LocationType.VANILLA), - LocationData("Harvest of Screams", "Harvest of Screams: North Ursadon Matriarch", SC2HOTS_LOC_ID_OFFSET + 402, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state)), - LocationData("Harvest of Screams", "Harvest of Screams: West Ursadon Matriarch", SC2HOTS_LOC_ID_OFFSET + 403, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state)), - LocationData("Harvest of Screams", "Harvest of Screams: Lost Brood", SC2HOTS_LOC_ID_OFFSET + 404, LocationType.EXTRA), - LocationData("Harvest of Screams", "Harvest of Screams: Northeast Psi-link Spire", SC2HOTS_LOC_ID_OFFSET + 405, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state)), - LocationData("Harvest of Screams", "Harvest of Screams: Northwest Psi-link Spire", SC2HOTS_LOC_ID_OFFSET + 406, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) - and logic.zerg_basic_anti_air(state)), - LocationData("Harvest of Screams", "Harvest of Screams: Southwest Psi-link Spire", SC2HOTS_LOC_ID_OFFSET + 407, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) - and logic.zerg_basic_anti_air(state)), - LocationData("Harvest of Screams", "Harvest of Screams: Nafash", SC2HOTS_LOC_ID_OFFSET + 408, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) - and logic.zerg_basic_anti_air(state)), - LocationData("Shoot the Messenger", "Shoot the Messenger: Victory", SC2HOTS_LOC_ID_OFFSET + 500, LocationType.VICTORY, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Shoot the Messenger", "Shoot the Messenger: East Stasis Chamber", SC2HOTS_LOC_ID_OFFSET + 501, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) and logic.zerg_basic_anti_air(state)), - LocationData("Shoot the Messenger", "Shoot the Messenger: Center Stasis Chamber", SC2HOTS_LOC_ID_OFFSET + 502, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) or adv_tactics), - LocationData("Shoot the Messenger", "Shoot the Messenger: West Stasis Chamber", SC2HOTS_LOC_ID_OFFSET + 503, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) and logic.zerg_basic_anti_air(state)), - LocationData("Shoot the Messenger", "Shoot the Messenger: Destroy 4 Shuttles", SC2HOTS_LOC_ID_OFFSET + 504, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) and logic.zerg_basic_anti_air(state)), - LocationData("Shoot the Messenger", "Shoot the Messenger: Frozen Expansion", SC2HOTS_LOC_ID_OFFSET + 505, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state)), - LocationData("Shoot the Messenger", "Shoot the Messenger: Southwest Frozen Zerg", SC2HOTS_LOC_ID_OFFSET + 506, LocationType.EXTRA), - LocationData("Shoot the Messenger", "Shoot the Messenger: Southeast Frozen Zerg", SC2HOTS_LOC_ID_OFFSET + 507, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) or adv_tactics), - LocationData("Shoot the Messenger", "Shoot the Messenger: West Frozen Zerg", SC2HOTS_LOC_ID_OFFSET + 508, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) and logic.zerg_basic_anti_air(state)), - LocationData("Shoot the Messenger", "Shoot the Messenger: East Frozen Zerg", SC2HOTS_LOC_ID_OFFSET + 509, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) and logic.zerg_competent_anti_air(state)), - LocationData("Enemy Within", "Enemy Within: Victory", SC2HOTS_LOC_ID_OFFSET + 600, LocationType.VICTORY, - lambda state: logic.zerg_pass_vents(state) - and (logic.story_tech_granted - or state.has_any({ItemNames.ZERGLING_RAPTOR_STRAIN, ItemNames.ROACH, - ItemNames.HYDRALISK, ItemNames.INFESTOR}, player)) - ), - LocationData("Enemy Within", "Enemy Within: Infest Giant Ursadon", SC2HOTS_LOC_ID_OFFSET + 601, LocationType.VANILLA, - lambda state: logic.zerg_pass_vents(state)), - LocationData("Enemy Within", "Enemy Within: First Niadra Evolution", SC2HOTS_LOC_ID_OFFSET + 602, LocationType.VANILLA, - lambda state: logic.zerg_pass_vents(state)), - LocationData("Enemy Within", "Enemy Within: Second Niadra Evolution", SC2HOTS_LOC_ID_OFFSET + 603, LocationType.VANILLA, - lambda state: logic.zerg_pass_vents(state)), - LocationData("Enemy Within", "Enemy Within: Third Niadra Evolution", SC2HOTS_LOC_ID_OFFSET + 604, LocationType.VANILLA, - lambda state: logic.zerg_pass_vents(state)), - LocationData("Enemy Within", "Enemy Within: Warp Drive", SC2HOTS_LOC_ID_OFFSET + 605, LocationType.EXTRA, - lambda state: logic.zerg_pass_vents(state)), - LocationData("Enemy Within", "Enemy Within: Stasis Quadrant", SC2HOTS_LOC_ID_OFFSET + 606, LocationType.EXTRA, - lambda state: logic.zerg_pass_vents(state)), - LocationData("Domination", "Domination: Victory", SC2HOTS_LOC_ID_OFFSET + 700, LocationType.VICTORY, - lambda state: logic.zerg_common_unit(state) and logic.zerg_basic_anti_air(state)), - LocationData("Domination", "Domination: Center Infested Command Center", SC2HOTS_LOC_ID_OFFSET + 701, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state)), - LocationData("Domination", "Domination: North Infested Command Center", SC2HOTS_LOC_ID_OFFSET + 702, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state)), - LocationData("Domination", "Domination: Repel Zagara", SC2HOTS_LOC_ID_OFFSET + 703, LocationType.EXTRA), - LocationData("Domination", "Domination: Close Baneling Nest", SC2HOTS_LOC_ID_OFFSET + 704, LocationType.EXTRA), - LocationData("Domination", "Domination: South Baneling Nest", SC2HOTS_LOC_ID_OFFSET + 705, LocationType.EXTRA, - lambda state: adv_tactics or logic.zerg_common_unit(state)), - LocationData("Domination", "Domination: Southwest Baneling Nest", SC2HOTS_LOC_ID_OFFSET + 706, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state)), - LocationData("Domination", "Domination: Southeast Baneling Nest", SC2HOTS_LOC_ID_OFFSET + 707, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) and logic.zerg_basic_anti_air(state)), - LocationData("Domination", "Domination: North Baneling Nest", SC2HOTS_LOC_ID_OFFSET + 708, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state)), - LocationData("Domination", "Domination: Northeast Baneling Nest", SC2HOTS_LOC_ID_OFFSET + 709, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state)), - LocationData("Fire in the Sky", "Fire in the Sky: Victory", SC2HOTS_LOC_ID_OFFSET + 800, LocationType.VICTORY, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state) and - logic.spread_creep(state)), - LocationData("Fire in the Sky", "Fire in the Sky: West Biomass", SC2HOTS_LOC_ID_OFFSET + 801, LocationType.VANILLA), - LocationData("Fire in the Sky", "Fire in the Sky: North Biomass", SC2HOTS_LOC_ID_OFFSET + 802, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state) and - logic.spread_creep(state)), - LocationData("Fire in the Sky", "Fire in the Sky: South Biomass", SC2HOTS_LOC_ID_OFFSET + 803, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state) and - logic.spread_creep(state)), - LocationData("Fire in the Sky", "Fire in the Sky: Destroy 3 Gorgons", SC2HOTS_LOC_ID_OFFSET + 804, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state) and - logic.spread_creep(state)), - LocationData("Fire in the Sky", "Fire in the Sky: Close Zerg Rescue", SC2HOTS_LOC_ID_OFFSET + 805, LocationType.EXTRA), - LocationData("Fire in the Sky", "Fire in the Sky: South Zerg Rescue", SC2HOTS_LOC_ID_OFFSET + 806, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state)), - LocationData("Fire in the Sky", "Fire in the Sky: North Zerg Rescue", SC2HOTS_LOC_ID_OFFSET + 807, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state) and - logic.spread_creep(state)), - LocationData("Fire in the Sky", "Fire in the Sky: West Queen Rescue", SC2HOTS_LOC_ID_OFFSET + 808, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state) and - logic.spread_creep(state)), - LocationData("Fire in the Sky", "Fire in the Sky: East Queen Rescue", SC2HOTS_LOC_ID_OFFSET + 809, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state) and - logic.spread_creep(state)), - LocationData("Old Soldiers", "Old Soldiers: Victory", SC2HOTS_LOC_ID_OFFSET + 900, LocationType.VICTORY, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Old Soldiers", "Old Soldiers: East Science Lab", SC2HOTS_LOC_ID_OFFSET + 901, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Old Soldiers", "Old Soldiers: North Science Lab", SC2HOTS_LOC_ID_OFFSET + 902, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Old Soldiers", "Old Soldiers: Get Nuked", SC2HOTS_LOC_ID_OFFSET + 903, LocationType.EXTRA), - LocationData("Old Soldiers", "Old Soldiers: Entrance Gate", SC2HOTS_LOC_ID_OFFSET + 904, LocationType.EXTRA), - LocationData("Old Soldiers", "Old Soldiers: Citadel Gate", SC2HOTS_LOC_ID_OFFSET + 905, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Old Soldiers", "Old Soldiers: South Expansion", SC2HOTS_LOC_ID_OFFSET + 906, LocationType.EXTRA), - LocationData("Old Soldiers", "Old Soldiers: Rich Mineral Expansion", SC2HOTS_LOC_ID_OFFSET + 907, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Waking the Ancient", "Waking the Ancient: Victory", SC2HOTS_LOC_ID_OFFSET + 1000, LocationType.VICTORY, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Waking the Ancient", "Waking the Ancient: Center Essence Pool", SC2HOTS_LOC_ID_OFFSET + 1001, LocationType.VANILLA), - LocationData("Waking the Ancient", "Waking the Ancient: East Essence Pool", SC2HOTS_LOC_ID_OFFSET + 1002, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) and - (adv_tactics and logic.zerg_basic_anti_air(state) - or logic.zerg_competent_anti_air(state))), - LocationData("Waking the Ancient", "Waking the Ancient: South Essence Pool", SC2HOTS_LOC_ID_OFFSET + 1003, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) and - (adv_tactics and logic.zerg_basic_anti_air(state) - or logic.zerg_competent_anti_air(state))), - LocationData("Waking the Ancient", "Waking the Ancient: Finish Feeding", SC2HOTS_LOC_ID_OFFSET + 1004, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Waking the Ancient", "Waking the Ancient: South Proxy Primal Hive", SC2HOTS_LOC_ID_OFFSET + 1005, LocationType.CHALLENGE, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Waking the Ancient", "Waking the Ancient: East Proxy Primal Hive", SC2HOTS_LOC_ID_OFFSET + 1006, LocationType.CHALLENGE, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Waking the Ancient", "Waking the Ancient: South Main Primal Hive", SC2HOTS_LOC_ID_OFFSET + 1007, LocationType.CHALLENGE, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Waking the Ancient", "Waking the Ancient: East Main Primal Hive", SC2HOTS_LOC_ID_OFFSET + 1008, LocationType.CHALLENGE, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_competent_anti_air(state)), - LocationData("The Crucible", "The Crucible: Victory", SC2HOTS_LOC_ID_OFFSET + 1100, LocationType.VICTORY, - lambda state: logic.zerg_competent_defense(state) and - logic.zerg_competent_anti_air(state)), - LocationData("The Crucible", "The Crucible: Tyrannozor", SC2HOTS_LOC_ID_OFFSET + 1101, LocationType.VANILLA, - lambda state: logic.zerg_competent_defense(state) and - logic.zerg_competent_anti_air(state)), - LocationData("The Crucible", "The Crucible: Reach the Pool", SC2HOTS_LOC_ID_OFFSET + 1102, LocationType.VANILLA), - LocationData("The Crucible", "The Crucible: 15 Minutes Remaining", SC2HOTS_LOC_ID_OFFSET + 1103, LocationType.EXTRA, - lambda state: logic.zerg_competent_defense(state) and - logic.zerg_competent_anti_air(state)), - LocationData("The Crucible", "The Crucible: 5 Minutes Remaining", SC2HOTS_LOC_ID_OFFSET + 1104, LocationType.EXTRA, - lambda state: logic.zerg_competent_defense(state) and - logic.zerg_competent_anti_air(state)), - LocationData("The Crucible", "The Crucible: Pincer Attack", SC2HOTS_LOC_ID_OFFSET + 1105, LocationType.EXTRA, - lambda state: logic.zerg_competent_defense(state) and - logic.zerg_competent_anti_air(state)), - LocationData("The Crucible", "The Crucible: Yagdra Claims Brakk's Pack", SC2HOTS_LOC_ID_OFFSET + 1106, LocationType.EXTRA, - lambda state: logic.zerg_competent_defense(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Supreme", "Supreme: Victory", SC2HOTS_LOC_ID_OFFSET + 1200, LocationType.VICTORY, - lambda state: logic.supreme_requirement(state)), - LocationData("Supreme", "Supreme: First Relic", SC2HOTS_LOC_ID_OFFSET + 1201, LocationType.VANILLA, - lambda state: logic.supreme_requirement(state)), - LocationData("Supreme", "Supreme: Second Relic", SC2HOTS_LOC_ID_OFFSET + 1202, LocationType.VANILLA, - lambda state: logic.supreme_requirement(state)), - LocationData("Supreme", "Supreme: Third Relic", SC2HOTS_LOC_ID_OFFSET + 1203, LocationType.VANILLA, - lambda state: logic.supreme_requirement(state)), - LocationData("Supreme", "Supreme: Fourth Relic", SC2HOTS_LOC_ID_OFFSET + 1204, LocationType.VANILLA, - lambda state: logic.supreme_requirement(state)), - LocationData("Supreme", "Supreme: Yagdra", SC2HOTS_LOC_ID_OFFSET + 1205, LocationType.EXTRA, - lambda state: logic.supreme_requirement(state)), - LocationData("Supreme", "Supreme: Kraith", SC2HOTS_LOC_ID_OFFSET + 1206, LocationType.EXTRA, - lambda state: logic.supreme_requirement(state)), - LocationData("Supreme", "Supreme: Slivan", SC2HOTS_LOC_ID_OFFSET + 1207, LocationType.EXTRA, - lambda state: logic.supreme_requirement(state)), - LocationData("Infested", "Infested: Victory", SC2HOTS_LOC_ID_OFFSET + 1300, LocationType.VICTORY, - lambda state: logic.zerg_common_unit(state) and - ((logic.zerg_competent_anti_air(state) and state.has(ItemNames.INFESTOR, player)) or - (adv_tactics and logic.zerg_basic_anti_air(state)))), - LocationData("Infested", "Infested: East Science Facility", SC2HOTS_LOC_ID_OFFSET + 1301, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_basic_anti_air(state) and - logic.spread_creep(state)), - LocationData("Infested", "Infested: Center Science Facility", SC2HOTS_LOC_ID_OFFSET + 1302, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_basic_anti_air(state) and - logic.spread_creep(state)), - LocationData("Infested", "Infested: West Science Facility", SC2HOTS_LOC_ID_OFFSET + 1303, LocationType.VANILLA, - lambda state: logic.zerg_common_unit(state) and - logic.zerg_basic_anti_air(state) and - logic.spread_creep(state)), - LocationData("Infested", "Infested: First Intro Garrison", SC2HOTS_LOC_ID_OFFSET + 1304, LocationType.EXTRA), - LocationData("Infested", "Infested: Second Intro Garrison", SC2HOTS_LOC_ID_OFFSET + 1305, LocationType.EXTRA), - LocationData("Infested", "Infested: Base Garrison", SC2HOTS_LOC_ID_OFFSET + 1306, LocationType.EXTRA), - LocationData("Infested", "Infested: East Garrison", SC2HOTS_LOC_ID_OFFSET + 1307, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) - and logic.zerg_basic_anti_air(state) - and (adv_tactics or state.has(ItemNames.INFESTOR, player))), - LocationData("Infested", "Infested: Mid Garrison", SC2HOTS_LOC_ID_OFFSET + 1308, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) - and logic.zerg_basic_anti_air(state) - and (adv_tactics or state.has(ItemNames.INFESTOR, player))), - LocationData("Infested", "Infested: North Garrison", SC2HOTS_LOC_ID_OFFSET + 1309, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) - and logic.zerg_basic_anti_air(state) - and (adv_tactics or state.has(ItemNames.INFESTOR, player))), - LocationData("Infested", "Infested: Close Southwest Garrison", SC2HOTS_LOC_ID_OFFSET + 1310, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) - and logic.zerg_basic_anti_air(state) - and (adv_tactics or state.has(ItemNames.INFESTOR, player))), - LocationData("Infested", "Infested: Far Southwest Garrison", SC2HOTS_LOC_ID_OFFSET + 1311, LocationType.EXTRA, - lambda state: logic.zerg_common_unit(state) - and logic.zerg_basic_anti_air(state) - and (adv_tactics or state.has(ItemNames.INFESTOR, player))), - LocationData("Hand of Darkness", "Hand of Darkness: Victory", SC2HOTS_LOC_ID_OFFSET + 1400, LocationType.VICTORY, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Hand of Darkness", "Hand of Darkness: North Brutalisk", SC2HOTS_LOC_ID_OFFSET + 1401, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Hand of Darkness", "Hand of Darkness: South Brutalisk", SC2HOTS_LOC_ID_OFFSET + 1402, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Hand of Darkness", "Hand of Darkness: Kill 1 Hybrid", SC2HOTS_LOC_ID_OFFSET + 1403, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Hand of Darkness", "Hand of Darkness: Kill 2 Hybrid", SC2HOTS_LOC_ID_OFFSET + 1404, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Hand of Darkness", "Hand of Darkness: Kill 3 Hybrid", SC2HOTS_LOC_ID_OFFSET + 1405, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Hand of Darkness", "Hand of Darkness: Kill 4 Hybrid", SC2HOTS_LOC_ID_OFFSET + 1406, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Hand of Darkness", "Hand of Darkness: Kill 5 Hybrid", SC2HOTS_LOC_ID_OFFSET + 1407, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Hand of Darkness", "Hand of Darkness: Kill 6 Hybrid", SC2HOTS_LOC_ID_OFFSET + 1408, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Hand of Darkness", "Hand of Darkness: Kill 7 Hybrid", SC2HOTS_LOC_ID_OFFSET + 1409, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_basic_anti_air(state)), - LocationData("Phantoms of the Void", "Phantoms of the Void: Victory", SC2HOTS_LOC_ID_OFFSET + 1500, LocationType.VICTORY, - lambda state: logic.zerg_competent_comp(state) and - (logic.zerg_competent_anti_air(state) or adv_tactics)), - LocationData("Phantoms of the Void", "Phantoms of the Void: Northwest Crystal", SC2HOTS_LOC_ID_OFFSET + 1501, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - (logic.zerg_competent_anti_air(state) or adv_tactics)), - LocationData("Phantoms of the Void", "Phantoms of the Void: Northeast Crystal", SC2HOTS_LOC_ID_OFFSET + 1502, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - (logic.zerg_competent_anti_air(state) or adv_tactics)), - LocationData("Phantoms of the Void", "Phantoms of the Void: South Crystal", SC2HOTS_LOC_ID_OFFSET + 1503, LocationType.VANILLA), - LocationData("Phantoms of the Void", "Phantoms of the Void: Base Established", SC2HOTS_LOC_ID_OFFSET + 1504, LocationType.EXTRA), - LocationData("Phantoms of the Void", "Phantoms of the Void: Close Temple", SC2HOTS_LOC_ID_OFFSET + 1505, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - (logic.zerg_competent_anti_air(state) or adv_tactics)), - LocationData("Phantoms of the Void", "Phantoms of the Void: Mid Temple", SC2HOTS_LOC_ID_OFFSET + 1506, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - (logic.zerg_competent_anti_air(state) or adv_tactics)), - LocationData("Phantoms of the Void", "Phantoms of the Void: Southeast Temple", SC2HOTS_LOC_ID_OFFSET + 1507, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - (logic.zerg_competent_anti_air(state) or adv_tactics)), - LocationData("Phantoms of the Void", "Phantoms of the Void: Northeast Temple", SC2HOTS_LOC_ID_OFFSET + 1508, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - (logic.zerg_competent_anti_air(state) or adv_tactics)), - LocationData("Phantoms of the Void", "Phantoms of the Void: Northwest Temple", SC2HOTS_LOC_ID_OFFSET + 1509, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - (logic.zerg_competent_anti_air(state) or adv_tactics)), - LocationData("With Friends Like These", "With Friends Like These: Victory", SC2HOTS_LOC_ID_OFFSET + 1600, LocationType.VICTORY), - LocationData("With Friends Like These", "With Friends Like These: Pirate Capital Ship", SC2HOTS_LOC_ID_OFFSET + 1601, LocationType.VANILLA), - LocationData("With Friends Like These", "With Friends Like These: First Mineral Patch", SC2HOTS_LOC_ID_OFFSET + 1602, LocationType.VANILLA), - LocationData("With Friends Like These", "With Friends Like These: Second Mineral Patch", SC2HOTS_LOC_ID_OFFSET + 1603, LocationType.VANILLA), - LocationData("With Friends Like These", "With Friends Like These: Third Mineral Patch", SC2HOTS_LOC_ID_OFFSET + 1604, LocationType.VANILLA), - LocationData("Conviction", "Conviction: Victory", SC2HOTS_LOC_ID_OFFSET + 1700, LocationType.VICTORY, - lambda state: logic.two_kerrigan_actives(state) and - (logic.basic_kerrigan(state) or logic.story_tech_granted) or kerriganless), - LocationData("Conviction", "Conviction: First Secret Documents", SC2HOTS_LOC_ID_OFFSET + 1701, LocationType.VANILLA, - lambda state: logic.two_kerrigan_actives(state) or kerriganless), - LocationData("Conviction", "Conviction: Second Secret Documents", SC2HOTS_LOC_ID_OFFSET + 1702, LocationType.VANILLA, - lambda state: logic.two_kerrigan_actives(state) and - (logic.basic_kerrigan(state) or logic.story_tech_granted) or kerriganless), - LocationData("Conviction", "Conviction: Power Coupling", SC2HOTS_LOC_ID_OFFSET + 1703, LocationType.EXTRA, - lambda state: logic.two_kerrigan_actives(state) or kerriganless), - LocationData("Conviction", "Conviction: Door Blasted", SC2HOTS_LOC_ID_OFFSET + 1704, LocationType.EXTRA, - lambda state: logic.two_kerrigan_actives(state) or kerriganless), - LocationData("Planetfall", "Planetfall: Victory", SC2HOTS_LOC_ID_OFFSET + 1800, LocationType.VICTORY, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: East Gate", SC2HOTS_LOC_ID_OFFSET + 1801, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: Northwest Gate", SC2HOTS_LOC_ID_OFFSET + 1802, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: North Gate", SC2HOTS_LOC_ID_OFFSET + 1803, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: 1 Bile Launcher Deployed", SC2HOTS_LOC_ID_OFFSET + 1804, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: 2 Bile Launchers Deployed", SC2HOTS_LOC_ID_OFFSET + 1805, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: 3 Bile Launchers Deployed", SC2HOTS_LOC_ID_OFFSET + 1806, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: 4 Bile Launchers Deployed", SC2HOTS_LOC_ID_OFFSET + 1807, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: 5 Bile Launchers Deployed", SC2HOTS_LOC_ID_OFFSET + 1808, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: Sons of Korhal", SC2HOTS_LOC_ID_OFFSET + 1809, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: Night Wolves", SC2HOTS_LOC_ID_OFFSET + 1810, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: West Expansion", SC2HOTS_LOC_ID_OFFSET + 1811, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Planetfall", "Planetfall: Mid Expansion", SC2HOTS_LOC_ID_OFFSET + 1812, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Death From Above", "Death From Above: Victory", SC2HOTS_LOC_ID_OFFSET + 1900, LocationType.VICTORY, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Death From Above", "Death From Above: First Power Link", SC2HOTS_LOC_ID_OFFSET + 1901, LocationType.VANILLA), - LocationData("Death From Above", "Death From Above: Second Power Link", SC2HOTS_LOC_ID_OFFSET + 1902, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Death From Above", "Death From Above: Third Power Link", SC2HOTS_LOC_ID_OFFSET + 1903, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Death From Above", "Death From Above: Expansion Command Center", SC2HOTS_LOC_ID_OFFSET + 1904, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("Death From Above", "Death From Above: Main Path Command Center", SC2HOTS_LOC_ID_OFFSET + 1905, LocationType.EXTRA, - lambda state: logic.zerg_competent_comp(state) and - logic.zerg_competent_anti_air(state)), - LocationData("The Reckoning", "The Reckoning: Victory", SC2HOTS_LOC_ID_OFFSET + 2000, LocationType.VICTORY, - lambda state: logic.the_reckoning_requirement(state)), - LocationData("The Reckoning", "The Reckoning: South Lane", SC2HOTS_LOC_ID_OFFSET + 2001, LocationType.VANILLA, - lambda state: logic.the_reckoning_requirement(state)), - LocationData("The Reckoning", "The Reckoning: North Lane", SC2HOTS_LOC_ID_OFFSET + 2002, LocationType.VANILLA, - lambda state: logic.the_reckoning_requirement(state)), - LocationData("The Reckoning", "The Reckoning: East Lane", SC2HOTS_LOC_ID_OFFSET + 2003, LocationType.VANILLA, - lambda state: logic.the_reckoning_requirement(state)), - LocationData("The Reckoning", "The Reckoning: Odin", SC2HOTS_LOC_ID_OFFSET + 2004, LocationType.EXTRA, - lambda state: logic.the_reckoning_requirement(state)), - - # LotV Prologue - LocationData("Dark Whispers", "Dark Whispers: Victory", SC2LOTV_LOC_ID_OFFSET + 100, LocationType.VICTORY, - lambda state: logic.protoss_common_unit(state) \ - and logic.protoss_basic_anti_air(state)), - LocationData("Dark Whispers", "Dark Whispers: First Prisoner Group", SC2LOTV_LOC_ID_OFFSET + 101, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) \ - and logic.protoss_basic_anti_air(state)), - LocationData("Dark Whispers", "Dark Whispers: Second Prisoner Group", SC2LOTV_LOC_ID_OFFSET + 102, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) \ - and logic.protoss_basic_anti_air(state)), - LocationData("Dark Whispers", "Dark Whispers: First Pylon", SC2LOTV_LOC_ID_OFFSET + 103, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) \ - and logic.protoss_basic_anti_air(state)), - LocationData("Dark Whispers", "Dark Whispers: Second Pylon", SC2LOTV_LOC_ID_OFFSET + 104, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) \ - and logic.protoss_basic_anti_air(state)), - LocationData("Ghosts in the Fog", "Ghosts in the Fog: Victory", SC2LOTV_LOC_ID_OFFSET + 200, LocationType.VICTORY, - lambda state: logic.protoss_common_unit(state) \ - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Ghosts in the Fog", "Ghosts in the Fog: South Rock Formation", SC2LOTV_LOC_ID_OFFSET + 201, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) \ - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Ghosts in the Fog", "Ghosts in the Fog: West Rock Formation", SC2LOTV_LOC_ID_OFFSET + 202, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) \ - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Ghosts in the Fog", "Ghosts in the Fog: East Rock Formation", SC2LOTV_LOC_ID_OFFSET + 203, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) \ - and logic.protoss_anti_armor_anti_air(state) \ - and logic.protoss_can_attack_behind_chasm(state)), - LocationData("Evil Awoken", "Evil Awoken: Victory", SC2LOTV_LOC_ID_OFFSET + 300, LocationType.VICTORY, - lambda state: adv_tactics or logic.protoss_stalker_upgrade(state)), - LocationData("Evil Awoken", "Evil Awoken: Temple Investigated", SC2LOTV_LOC_ID_OFFSET + 301, LocationType.EXTRA), - LocationData("Evil Awoken", "Evil Awoken: Void Catalyst", SC2LOTV_LOC_ID_OFFSET + 302, LocationType.EXTRA), - LocationData("Evil Awoken", "Evil Awoken: First Particle Cannon", SC2LOTV_LOC_ID_OFFSET + 303, LocationType.VANILLA), - LocationData("Evil Awoken", "Evil Awoken: Second Particle Cannon", SC2LOTV_LOC_ID_OFFSET + 304, LocationType.VANILLA), - LocationData("Evil Awoken", "Evil Awoken: Third Particle Cannon", SC2LOTV_LOC_ID_OFFSET + 305, LocationType.VANILLA), - - - # LotV - LocationData("For Aiur!", "For Aiur!: Victory", SC2LOTV_LOC_ID_OFFSET + 400, LocationType.VICTORY), - LocationData("For Aiur!", "For Aiur!: Southwest Hive", SC2LOTV_LOC_ID_OFFSET + 401, LocationType.VANILLA), - LocationData("For Aiur!", "For Aiur!: Northwest Hive", SC2LOTV_LOC_ID_OFFSET + 402, LocationType.VANILLA), - LocationData("For Aiur!", "For Aiur!: Northeast Hive", SC2LOTV_LOC_ID_OFFSET + 403, LocationType.VANILLA), - LocationData("For Aiur!", "For Aiur!: East Hive", SC2LOTV_LOC_ID_OFFSET + 404, LocationType.VANILLA), - LocationData("For Aiur!", "For Aiur!: West Conduit", SC2LOTV_LOC_ID_OFFSET + 405, LocationType.EXTRA), - LocationData("For Aiur!", "For Aiur!: Middle Conduit", SC2LOTV_LOC_ID_OFFSET + 406, LocationType.EXTRA), - LocationData("For Aiur!", "For Aiur!: Northeast Conduit", SC2LOTV_LOC_ID_OFFSET + 407, LocationType.EXTRA), - LocationData("The Growing Shadow", "The Growing Shadow: Victory", SC2LOTV_LOC_ID_OFFSET + 500, LocationType.VICTORY, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("The Growing Shadow", "The Growing Shadow: Close Pylon", SC2LOTV_LOC_ID_OFFSET + 501, LocationType.VANILLA), - LocationData("The Growing Shadow", "The Growing Shadow: East Pylon", SC2LOTV_LOC_ID_OFFSET + 502, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("The Growing Shadow", "The Growing Shadow: West Pylon", SC2LOTV_LOC_ID_OFFSET + 503, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("The Growing Shadow", "The Growing Shadow: Nexus", SC2LOTV_LOC_ID_OFFSET + 504, LocationType.EXTRA), - LocationData("The Growing Shadow", "The Growing Shadow: Templar Base", SC2LOTV_LOC_ID_OFFSET + 505, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("The Spear of Adun", "The Spear of Adun: Victory", SC2LOTV_LOC_ID_OFFSET + 600, LocationType.VICTORY, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("The Spear of Adun", "The Spear of Adun: Close Warp Gate", SC2LOTV_LOC_ID_OFFSET + 601, LocationType.VANILLA), - LocationData("The Spear of Adun", "The Spear of Adun: West Warp Gate", SC2LOTV_LOC_ID_OFFSET + 602, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("The Spear of Adun", "The Spear of Adun: North Warp Gate", SC2LOTV_LOC_ID_OFFSET + 603, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("The Spear of Adun", "The Spear of Adun: North Power Cell", SC2LOTV_LOC_ID_OFFSET + 604, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("The Spear of Adun", "The Spear of Adun: East Power Cell", SC2LOTV_LOC_ID_OFFSET + 605, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("The Spear of Adun", "The Spear of Adun: South Power Cell", SC2LOTV_LOC_ID_OFFSET + 606, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("The Spear of Adun", "The Spear of Adun: Southeast Power Cell", SC2LOTV_LOC_ID_OFFSET + 607, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Sky Shield", "Sky Shield: Victory", SC2LOTV_LOC_ID_OFFSET + 700, LocationType.VICTORY, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("Sky Shield", "Sky Shield: Mid EMP Scrambler", SC2LOTV_LOC_ID_OFFSET + 701, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("Sky Shield", "Sky Shield: Southeast EMP Scrambler", SC2LOTV_LOC_ID_OFFSET + 702, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("Sky Shield", "Sky Shield: North EMP Scrambler", SC2LOTV_LOC_ID_OFFSET + 703, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("Sky Shield", "Sky Shield: Mid Stabilizer", SC2LOTV_LOC_ID_OFFSET + 704, LocationType.EXTRA), - LocationData("Sky Shield", "Sky Shield: Southwest Stabilizer", SC2LOTV_LOC_ID_OFFSET + 705, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("Sky Shield", "Sky Shield: Northwest Stabilizer", SC2LOTV_LOC_ID_OFFSET + 706, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("Sky Shield", "Sky Shield: Northeast Stabilizer", SC2LOTV_LOC_ID_OFFSET + 707, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("Sky Shield", "Sky Shield: Southeast Stabilizer", SC2LOTV_LOC_ID_OFFSET + 708, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("Sky Shield", "Sky Shield: West Raynor Base", SC2LOTV_LOC_ID_OFFSET + 709, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("Sky Shield", "Sky Shield: East Raynor Base", SC2LOTV_LOC_ID_OFFSET + 710, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_basic_anti_air(state)), - LocationData("Brothers in Arms", "Brothers in Arms: Victory", SC2LOTV_LOC_ID_OFFSET + 800, LocationType.VICTORY, - lambda state: logic.brothers_in_arms_requirement(state)), - LocationData("Brothers in Arms", "Brothers in Arms: Mid Science Facility", SC2LOTV_LOC_ID_OFFSET + 801, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) or logic.take_over_ai_allies), - LocationData("Brothers in Arms", "Brothers in Arms: North Science Facility", SC2LOTV_LOC_ID_OFFSET + 802, LocationType.VANILLA, - lambda state: logic.brothers_in_arms_requirement(state) - or logic.take_over_ai_allies - and logic.advanced_tactics - and ( - logic.terran_common_unit(state) - or logic.protoss_common_unit(state) - ) - ), - LocationData("Brothers in Arms", "Brothers in Arms: South Science Facility", SC2LOTV_LOC_ID_OFFSET + 803, LocationType.VANILLA, - lambda state: logic.brothers_in_arms_requirement(state)), - LocationData("Amon's Reach", "Amon's Reach: Victory", SC2LOTV_LOC_ID_OFFSET + 900, LocationType.VICTORY, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Amon's Reach", "Amon's Reach: Close Solarite Reserve", SC2LOTV_LOC_ID_OFFSET + 901, LocationType.VANILLA), - LocationData("Amon's Reach", "Amon's Reach: North Solarite Reserve", SC2LOTV_LOC_ID_OFFSET + 902, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Amon's Reach", "Amon's Reach: East Solarite Reserve", SC2LOTV_LOC_ID_OFFSET + 903, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Amon's Reach", "Amon's Reach: West Launch Bay", SC2LOTV_LOC_ID_OFFSET + 904, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Amon's Reach", "Amon's Reach: South Launch Bay", SC2LOTV_LOC_ID_OFFSET + 905, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Amon's Reach", "Amon's Reach: Northwest Launch Bay", SC2LOTV_LOC_ID_OFFSET + 906, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Amon's Reach", "Amon's Reach: East Launch Bay", SC2LOTV_LOC_ID_OFFSET + 907, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Last Stand", "Last Stand: Victory", SC2LOTV_LOC_ID_OFFSET + 1000, LocationType.VICTORY, - lambda state: logic.last_stand_requirement(state)), - LocationData("Last Stand", "Last Stand: West Zenith Stone", SC2LOTV_LOC_ID_OFFSET + 1001, LocationType.VANILLA, - lambda state: logic.last_stand_requirement(state)), - LocationData("Last Stand", "Last Stand: North Zenith Stone", SC2LOTV_LOC_ID_OFFSET + 1002, LocationType.VANILLA, - lambda state: logic.last_stand_requirement(state)), - LocationData("Last Stand", "Last Stand: East Zenith Stone", SC2LOTV_LOC_ID_OFFSET + 1003, LocationType.VANILLA, - lambda state: logic.last_stand_requirement(state)), - LocationData("Last Stand", "Last Stand: 1 Billion Zerg", SC2LOTV_LOC_ID_OFFSET + 1004, LocationType.EXTRA, - lambda state: logic.last_stand_requirement(state)), - LocationData("Last Stand", "Last Stand: 1.5 Billion Zerg", SC2LOTV_LOC_ID_OFFSET + 1005, LocationType.VANILLA, - lambda state: logic.last_stand_requirement(state) and ( - state.has_all({ItemNames.KHAYDARIN_MONOLITH, ItemNames.PHOTON_CANNON, ItemNames.SHIELD_BATTERY}, player) - or state.has_any({ItemNames.SOA_SOLAR_LANCE, ItemNames.SOA_DEPLOY_FENIX}, player) - )), - LocationData("Forbidden Weapon", "Forbidden Weapon: Victory", SC2LOTV_LOC_ID_OFFSET + 1100, LocationType.VICTORY, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Forbidden Weapon", "Forbidden Weapon: South Solarite", SC2LOTV_LOC_ID_OFFSET + 1101, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Forbidden Weapon", "Forbidden Weapon: North Solarite", SC2LOTV_LOC_ID_OFFSET + 1102, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Forbidden Weapon", "Forbidden Weapon: Northwest Solarite", SC2LOTV_LOC_ID_OFFSET + 1103, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Temple of Unification", "Temple of Unification: Victory", SC2LOTV_LOC_ID_OFFSET + 1200, LocationType.VICTORY, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Temple of Unification", "Temple of Unification: Mid Celestial Lock", SC2LOTV_LOC_ID_OFFSET + 1201, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Temple of Unification", "Temple of Unification: West Celestial Lock", SC2LOTV_LOC_ID_OFFSET + 1202, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Temple of Unification", "Temple of Unification: South Celestial Lock", SC2LOTV_LOC_ID_OFFSET + 1203, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Temple of Unification", "Temple of Unification: East Celestial Lock", SC2LOTV_LOC_ID_OFFSET + 1204, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Temple of Unification", "Temple of Unification: North Celestial Lock", SC2LOTV_LOC_ID_OFFSET + 1205, LocationType.EXTRA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("Temple of Unification", "Temple of Unification: Titanic Warp Prism", SC2LOTV_LOC_ID_OFFSET + 1206, LocationType.VANILLA, - lambda state: logic.protoss_common_unit(state) - and logic.protoss_anti_armor_anti_air(state)), - LocationData("The Infinite Cycle", "The Infinite Cycle: Victory", SC2LOTV_LOC_ID_OFFSET + 1300, LocationType.VICTORY, - lambda state: logic.the_infinite_cycle_requirement(state)), - LocationData("The Infinite Cycle", "The Infinite Cycle: First Hall of Revelation", SC2LOTV_LOC_ID_OFFSET + 1301, LocationType.EXTRA, - lambda state: logic.the_infinite_cycle_requirement(state)), - LocationData("The Infinite Cycle", "The Infinite Cycle: Second Hall of Revelation", SC2LOTV_LOC_ID_OFFSET + 1302, LocationType.EXTRA, - lambda state: logic.the_infinite_cycle_requirement(state)), - LocationData("The Infinite Cycle", "The Infinite Cycle: First Xel'Naga Device", SC2LOTV_LOC_ID_OFFSET + 1303, LocationType.VANILLA, - lambda state: logic.the_infinite_cycle_requirement(state)), - LocationData("The Infinite Cycle", "The Infinite Cycle: Second Xel'Naga Device", SC2LOTV_LOC_ID_OFFSET + 1304, LocationType.VANILLA, - lambda state: logic.the_infinite_cycle_requirement(state)), - LocationData("The Infinite Cycle", "The Infinite Cycle: Third Xel'Naga Device", SC2LOTV_LOC_ID_OFFSET + 1305, LocationType.VANILLA, - lambda state: logic.the_infinite_cycle_requirement(state)), - LocationData("Harbinger of Oblivion", "Harbinger of Oblivion: Victory", SC2LOTV_LOC_ID_OFFSET + 1400, LocationType.VICTORY, - lambda state: logic.harbinger_of_oblivion_requirement(state)), - LocationData("Harbinger of Oblivion", "Harbinger of Oblivion: Artanis", SC2LOTV_LOC_ID_OFFSET + 1401, LocationType.EXTRA), - LocationData("Harbinger of Oblivion", "Harbinger of Oblivion: Northwest Void Crystal", SC2LOTV_LOC_ID_OFFSET + 1402, LocationType.EXTRA, - lambda state: logic.harbinger_of_oblivion_requirement(state)), - LocationData("Harbinger of Oblivion", "Harbinger of Oblivion: Northeast Void Crystal", SC2LOTV_LOC_ID_OFFSET + 1403, LocationType.EXTRA, - lambda state: logic.harbinger_of_oblivion_requirement(state)), - LocationData("Harbinger of Oblivion", "Harbinger of Oblivion: Southwest Void Crystal", SC2LOTV_LOC_ID_OFFSET + 1404, LocationType.EXTRA, - lambda state: logic.harbinger_of_oblivion_requirement(state)), - LocationData("Harbinger of Oblivion", "Harbinger of Oblivion: Southeast Void Crystal", SC2LOTV_LOC_ID_OFFSET + 1405, LocationType.EXTRA, - lambda state: logic.harbinger_of_oblivion_requirement(state)), - LocationData("Harbinger of Oblivion", "Harbinger of Oblivion: South Xel'Naga Vessel", SC2LOTV_LOC_ID_OFFSET + 1406, LocationType.VANILLA), - LocationData("Harbinger of Oblivion", "Harbinger of Oblivion: Mid Xel'Naga Vessel", SC2LOTV_LOC_ID_OFFSET + 1407, LocationType.VANILLA, - lambda state: logic.harbinger_of_oblivion_requirement(state)), - LocationData("Harbinger of Oblivion", "Harbinger of Oblivion: North Xel'Naga Vessel", SC2LOTV_LOC_ID_OFFSET + 1408, LocationType.VANILLA, - lambda state: logic.harbinger_of_oblivion_requirement(state)), - LocationData("Unsealing the Past", "Unsealing the Past: Victory", SC2LOTV_LOC_ID_OFFSET + 1500, LocationType.VICTORY, - lambda state: logic.protoss_basic_splash(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Unsealing the Past", "Unsealing the Past: Zerg Cleared", SC2LOTV_LOC_ID_OFFSET + 1501, LocationType.EXTRA), - LocationData("Unsealing the Past", "Unsealing the Past: First Stasis Lock", SC2LOTV_LOC_ID_OFFSET + 1502, LocationType.EXTRA, - lambda state: logic.advanced_tactics \ - or logic.protoss_basic_splash(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Unsealing the Past", "Unsealing the Past: Second Stasis Lock", SC2LOTV_LOC_ID_OFFSET + 1503, LocationType.EXTRA, - lambda state: logic.protoss_basic_splash(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Unsealing the Past", "Unsealing the Past: Third Stasis Lock", SC2LOTV_LOC_ID_OFFSET + 1504, LocationType.EXTRA, - lambda state: logic.protoss_basic_splash(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Unsealing the Past", "Unsealing the Past: Fourth Stasis Lock", SC2LOTV_LOC_ID_OFFSET + 1505, LocationType.EXTRA, - lambda state: logic.protoss_basic_splash(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Unsealing the Past", "Unsealing the Past: South Power Core", SC2LOTV_LOC_ID_OFFSET + 1506, LocationType.VANILLA, - lambda state: logic.protoss_basic_splash(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Unsealing the Past", "Unsealing the Past: East Power Core", SC2LOTV_LOC_ID_OFFSET + 1507, LocationType.VANILLA, - lambda state: logic.protoss_basic_splash(state) - and logic.protoss_anti_light_anti_air(state)), - LocationData("Purification", "Purification: Victory", SC2LOTV_LOC_ID_OFFSET + 1600, LocationType.VICTORY, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: North Sector: West Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1601, LocationType.VANILLA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: North Sector: Northeast Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1602, LocationType.EXTRA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: North Sector: Southeast Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1603, LocationType.EXTRA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: South Sector: West Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1604, LocationType.VANILLA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: South Sector: North Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1605, LocationType.EXTRA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: South Sector: East Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1606, LocationType.EXTRA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: West Sector: West Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1607, LocationType.VANILLA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: West Sector: Mid Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1608, LocationType.EXTRA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: West Sector: East Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1609, LocationType.EXTRA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: East Sector: North Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1610, LocationType.VANILLA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: East Sector: West Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1611, LocationType.EXTRA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: East Sector: South Null Circuit", SC2LOTV_LOC_ID_OFFSET + 1612, LocationType.EXTRA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Purification", "Purification: Purifier Warden", SC2LOTV_LOC_ID_OFFSET + 1613, LocationType.VANILLA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Steps of the Rite", "Steps of the Rite: Victory", SC2LOTV_LOC_ID_OFFSET + 1700, LocationType.VICTORY, - lambda state: logic.steps_of_the_rite_requirement(state)), - LocationData("Steps of the Rite", "Steps of the Rite: First Terrazine Fog", SC2LOTV_LOC_ID_OFFSET + 1701, LocationType.EXTRA, - lambda state: logic.steps_of_the_rite_requirement(state)), - LocationData("Steps of the Rite", "Steps of the Rite: Southwest Guardian", SC2LOTV_LOC_ID_OFFSET + 1702, LocationType.EXTRA, - lambda state: logic.steps_of_the_rite_requirement(state)), - LocationData("Steps of the Rite", "Steps of the Rite: West Guardian", SC2LOTV_LOC_ID_OFFSET + 1703, LocationType.EXTRA, - lambda state: logic.steps_of_the_rite_requirement(state)), - LocationData("Steps of the Rite", "Steps of the Rite: Northwest Guardian", SC2LOTV_LOC_ID_OFFSET + 1704, LocationType.EXTRA, - lambda state: logic.steps_of_the_rite_requirement(state)), - LocationData("Steps of the Rite", "Steps of the Rite: Northeast Guardian", SC2LOTV_LOC_ID_OFFSET + 1705, LocationType.EXTRA, - lambda state: logic.steps_of_the_rite_requirement(state)), - LocationData("Steps of the Rite", "Steps of the Rite: North Mothership", SC2LOTV_LOC_ID_OFFSET + 1706, LocationType.VANILLA, - lambda state: logic.steps_of_the_rite_requirement(state)), - LocationData("Steps of the Rite", "Steps of the Rite: South Mothership", SC2LOTV_LOC_ID_OFFSET + 1707, LocationType.VANILLA, - lambda state: logic.steps_of_the_rite_requirement(state)), - LocationData("Rak'Shir", "Rak'Shir: Victory", SC2LOTV_LOC_ID_OFFSET + 1800, LocationType.VICTORY, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Rak'Shir", "Rak'Shir: North Slayn Elemental", SC2LOTV_LOC_ID_OFFSET + 1801, LocationType.VANILLA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Rak'Shir", "Rak'Shir: Southwest Slayn Elemental", SC2LOTV_LOC_ID_OFFSET + 1802, LocationType.VANILLA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Rak'Shir", "Rak'Shir: East Slayn Elemental", SC2LOTV_LOC_ID_OFFSET + 1803, LocationType.VANILLA, - lambda state: logic.protoss_competent_comp(state)), - LocationData("Templar's Charge", "Templar's Charge: Victory", SC2LOTV_LOC_ID_OFFSET + 1900, LocationType.VICTORY, - lambda state: logic.templars_charge_requirement(state)), - LocationData("Templar's Charge", "Templar's Charge: Northwest Power Core", SC2LOTV_LOC_ID_OFFSET + 1901, LocationType.EXTRA, - lambda state: logic.templars_charge_requirement(state)), - LocationData("Templar's Charge", "Templar's Charge: Northeast Power Core", SC2LOTV_LOC_ID_OFFSET + 1902, LocationType.EXTRA, - lambda state: logic.templars_charge_requirement(state)), - LocationData("Templar's Charge", "Templar's Charge: Southeast Power Core", SC2LOTV_LOC_ID_OFFSET + 1903, LocationType.EXTRA, - lambda state: logic.templars_charge_requirement(state)), - LocationData("Templar's Charge", "Templar's Charge: West Hybrid Stasis Chamber", SC2LOTV_LOC_ID_OFFSET + 1904, LocationType.VANILLA, - lambda state: logic.templars_charge_requirement(state)), - LocationData("Templar's Charge", "Templar's Charge: Southeast Hybrid Stasis Chamber", SC2LOTV_LOC_ID_OFFSET + 1905, LocationType.VANILLA, - lambda state: logic.protoss_fleet(state)), - LocationData("Templar's Return", "Templar's Return: Victory", SC2LOTV_LOC_ID_OFFSET + 2000, LocationType.VICTORY, - lambda state: logic.templars_return_requirement(state)), - LocationData("Templar's Return", "Templar's Return: Citadel: First Gate", SC2LOTV_LOC_ID_OFFSET + 2001, LocationType.EXTRA), - LocationData("Templar's Return", "Templar's Return: Citadel: Second Gate", SC2LOTV_LOC_ID_OFFSET + 2002, LocationType.EXTRA), - LocationData("Templar's Return", "Templar's Return: Citadel: Power Structure", SC2LOTV_LOC_ID_OFFSET + 2003, LocationType.VANILLA), - LocationData("Templar's Return", "Templar's Return: Temple Grounds: Gather Army", SC2LOTV_LOC_ID_OFFSET + 2004, LocationType.VANILLA, - lambda state: logic.templars_return_requirement(state)), - LocationData("Templar's Return", "Templar's Return: Temple Grounds: Power Structure", SC2LOTV_LOC_ID_OFFSET + 2005, LocationType.VANILLA, - lambda state: logic.templars_return_requirement(state)), - LocationData("Templar's Return", "Templar's Return: Caverns: Purifier", SC2LOTV_LOC_ID_OFFSET + 2006, LocationType.EXTRA, - lambda state: logic.templars_return_requirement(state)), - LocationData("Templar's Return", "Templar's Return: Caverns: Dark Templar", SC2LOTV_LOC_ID_OFFSET + 2007, LocationType.EXTRA, - lambda state: logic.templars_return_requirement(state)), - LocationData("The Host", "The Host: Victory", SC2LOTV_LOC_ID_OFFSET + 2100, LocationType.VICTORY, - lambda state: logic.the_host_requirement(state)), - LocationData("The Host", "The Host: Southeast Void Shard", SC2LOTV_LOC_ID_OFFSET + 2101, LocationType.EXTRA, - lambda state: logic.the_host_requirement(state)), - LocationData("The Host", "The Host: South Void Shard", SC2LOTV_LOC_ID_OFFSET + 2102, LocationType.EXTRA, - lambda state: logic.the_host_requirement(state)), - LocationData("The Host", "The Host: Southwest Void Shard", SC2LOTV_LOC_ID_OFFSET + 2103, LocationType.EXTRA, - lambda state: logic.the_host_requirement(state)), - LocationData("The Host", "The Host: North Void Shard", SC2LOTV_LOC_ID_OFFSET + 2104, LocationType.EXTRA, - lambda state: logic.the_host_requirement(state)), - LocationData("The Host", "The Host: Northwest Void Shard", SC2LOTV_LOC_ID_OFFSET + 2105, LocationType.EXTRA, - lambda state: logic.the_host_requirement(state)), - LocationData("The Host", "The Host: Nerazim Warp in Zone", SC2LOTV_LOC_ID_OFFSET + 2106, LocationType.VANILLA, - lambda state: logic.the_host_requirement(state)), - LocationData("The Host", "The Host: Tal'darim Warp in Zone", SC2LOTV_LOC_ID_OFFSET + 2107, LocationType.VANILLA, - lambda state: logic.the_host_requirement(state)), - LocationData("The Host", "The Host: Purifier Warp in Zone", SC2LOTV_LOC_ID_OFFSET + 2108, LocationType.VANILLA, - lambda state: logic.the_host_requirement(state)), - LocationData("Salvation", "Salvation: Victory", SC2LOTV_LOC_ID_OFFSET + 2200, LocationType.VICTORY, - lambda state: logic.salvation_requirement(state)), - LocationData("Salvation", "Salvation: Fabrication Matrix", SC2LOTV_LOC_ID_OFFSET + 2201, LocationType.EXTRA, - lambda state: logic.salvation_requirement(state)), - LocationData("Salvation", "Salvation: Assault Cluster", SC2LOTV_LOC_ID_OFFSET + 2202, LocationType.EXTRA, - lambda state: logic.salvation_requirement(state)), - LocationData("Salvation", "Salvation: Hull Breach", SC2LOTV_LOC_ID_OFFSET + 2203, LocationType.EXTRA, - lambda state: logic.salvation_requirement(state)), - LocationData("Salvation", "Salvation: Core Critical", SC2LOTV_LOC_ID_OFFSET + 2204, LocationType.EXTRA, - lambda state: logic.salvation_requirement(state)), - - # Epilogue - LocationData("Into the Void", "Into the Void: Victory", SC2LOTV_LOC_ID_OFFSET + 2300, LocationType.VICTORY, - lambda state: logic.into_the_void_requirement(state)), - LocationData("Into the Void", "Into the Void: Corruption Source", SC2LOTV_LOC_ID_OFFSET + 2301, LocationType.EXTRA), - LocationData("Into the Void", "Into the Void: Southwest Forward Position", SC2LOTV_LOC_ID_OFFSET + 2302, LocationType.VANILLA, - lambda state: logic.into_the_void_requirement(state)), - LocationData("Into the Void", "Into the Void: Northwest Forward Position", SC2LOTV_LOC_ID_OFFSET + 2303, LocationType.VANILLA, - lambda state: logic.into_the_void_requirement(state)), - LocationData("Into the Void", "Into the Void: Southeast Forward Position", SC2LOTV_LOC_ID_OFFSET + 2304, LocationType.VANILLA, - lambda state: logic.into_the_void_requirement(state)), - LocationData("Into the Void", "Into the Void: Northeast Forward Position", SC2LOTV_LOC_ID_OFFSET + 2305, LocationType.VANILLA), - LocationData("The Essence of Eternity", "The Essence of Eternity: Victory", SC2LOTV_LOC_ID_OFFSET + 2400, LocationType.VICTORY, - lambda state: logic.essence_of_eternity_requirement(state)), - LocationData("The Essence of Eternity", "The Essence of Eternity: Void Trashers", SC2LOTV_LOC_ID_OFFSET + 2401, LocationType.EXTRA), - LocationData("Amon's Fall", "Amon's Fall: Victory", SC2LOTV_LOC_ID_OFFSET + 2500, LocationType.VICTORY, - lambda state: logic.amons_fall_requirement(state)), - - # Nova Covert Ops - LocationData("The Escape", "The Escape: Victory", SC2NCO_LOC_ID_OFFSET + 100, LocationType.VICTORY, - lambda state: logic.the_escape_requirement(state)), - LocationData("The Escape", "The Escape: Rifle", SC2NCO_LOC_ID_OFFSET + 101, LocationType.VANILLA, - lambda state: logic.the_escape_first_stage_requirement(state)), - LocationData("The Escape", "The Escape: Grenades", SC2NCO_LOC_ID_OFFSET + 102, LocationType.VANILLA, - lambda state: logic.the_escape_first_stage_requirement(state)), - LocationData("The Escape", "The Escape: Agent Delta", SC2NCO_LOC_ID_OFFSET + 103, LocationType.VANILLA, - lambda state: logic.the_escape_requirement(state)), - LocationData("The Escape", "The Escape: Agent Pierce", SC2NCO_LOC_ID_OFFSET + 104, LocationType.VANILLA, - lambda state: logic.the_escape_requirement(state)), - LocationData("The Escape", "The Escape: Agent Stone", SC2NCO_LOC_ID_OFFSET + 105, LocationType.VANILLA, - lambda state: logic.the_escape_requirement(state)), - LocationData("Sudden Strike", "Sudden Strike: Victory", SC2NCO_LOC_ID_OFFSET + 200, LocationType.VICTORY, - lambda state: logic.sudden_strike_requirement(state)), - LocationData("Sudden Strike", "Sudden Strike: Research Center", SC2NCO_LOC_ID_OFFSET + 201, LocationType.VANILLA, - lambda state: logic.sudden_strike_can_reach_objectives(state)), - LocationData("Sudden Strike", "Sudden Strike: Weaponry Labs", SC2NCO_LOC_ID_OFFSET + 202, LocationType.VANILLA, - lambda state: logic.sudden_strike_can_reach_objectives(state)), - LocationData("Sudden Strike", "Sudden Strike: Brutalisk", SC2NCO_LOC_ID_OFFSET + 203, LocationType.EXTRA, - lambda state: logic.sudden_strike_requirement(state)), - LocationData("Enemy Intelligence", "Enemy Intelligence: Victory", SC2NCO_LOC_ID_OFFSET + 300, LocationType.VICTORY, - lambda state: logic.enemy_intelligence_third_stage_requirement(state)), - LocationData("Enemy Intelligence", "Enemy Intelligence: West Garrison", SC2NCO_LOC_ID_OFFSET + 301, LocationType.EXTRA, - lambda state: logic.enemy_intelligence_first_stage_requirement(state)), - LocationData("Enemy Intelligence", "Enemy Intelligence: Close Garrison", SC2NCO_LOC_ID_OFFSET + 302, LocationType.EXTRA, - lambda state: logic.enemy_intelligence_first_stage_requirement(state)), - LocationData("Enemy Intelligence", "Enemy Intelligence: Northeast Garrison", SC2NCO_LOC_ID_OFFSET + 303, LocationType.EXTRA, - lambda state: logic.enemy_intelligence_first_stage_requirement(state)), - LocationData("Enemy Intelligence", "Enemy Intelligence: Southeast Garrison", SC2NCO_LOC_ID_OFFSET + 304, LocationType.EXTRA, - lambda state: logic.enemy_intelligence_first_stage_requirement(state) - and logic.enemy_intelligence_cliff_garrison(state)), - LocationData("Enemy Intelligence", "Enemy Intelligence: South Garrison", SC2NCO_LOC_ID_OFFSET + 305, LocationType.EXTRA, - lambda state: logic.enemy_intelligence_first_stage_requirement(state)), - LocationData("Enemy Intelligence", "Enemy Intelligence: All Garrisons", SC2NCO_LOC_ID_OFFSET + 306, LocationType.VANILLA, - lambda state: logic.enemy_intelligence_first_stage_requirement(state) - and logic.enemy_intelligence_cliff_garrison(state)), - LocationData("Enemy Intelligence", "Enemy Intelligence: Forces Rescued", SC2NCO_LOC_ID_OFFSET + 307, LocationType.VANILLA, - lambda state: logic.enemy_intelligence_first_stage_requirement(state)), - LocationData("Enemy Intelligence", "Enemy Intelligence: Communications Hub", SC2NCO_LOC_ID_OFFSET + 308, LocationType.VANILLA, - lambda state: logic.enemy_intelligence_second_stage_requirement(state)), - LocationData("Trouble In Paradise", "Trouble In Paradise: Victory", SC2NCO_LOC_ID_OFFSET + 400, LocationType.VICTORY, - lambda state: logic.trouble_in_paradise_requirement(state)), - LocationData("Trouble In Paradise", "Trouble In Paradise: North Base: West Hatchery", SC2NCO_LOC_ID_OFFSET + 401, LocationType.VANILLA, - lambda state: logic.trouble_in_paradise_requirement(state)), - LocationData("Trouble In Paradise", "Trouble In Paradise: North Base: North Hatchery", SC2NCO_LOC_ID_OFFSET + 402, LocationType.VANILLA, - lambda state: logic.trouble_in_paradise_requirement(state)), - LocationData("Trouble In Paradise", "Trouble In Paradise: North Base: East Hatchery", SC2NCO_LOC_ID_OFFSET + 403, LocationType.VANILLA), - LocationData("Trouble In Paradise", "Trouble In Paradise: South Base: Northwest Hatchery", SC2NCO_LOC_ID_OFFSET + 404, LocationType.VANILLA, - lambda state: logic.trouble_in_paradise_requirement(state)), - LocationData("Trouble In Paradise", "Trouble In Paradise: South Base: Southwest Hatchery", SC2NCO_LOC_ID_OFFSET + 405, LocationType.VANILLA, - lambda state: logic.trouble_in_paradise_requirement(state)), - LocationData("Trouble In Paradise", "Trouble In Paradise: South Base: East Hatchery", SC2NCO_LOC_ID_OFFSET + 406, LocationType.VANILLA), - LocationData("Trouble In Paradise", "Trouble In Paradise: North Shield Projector", SC2NCO_LOC_ID_OFFSET + 407, LocationType.EXTRA, - lambda state: logic.trouble_in_paradise_requirement(state)), - LocationData("Trouble In Paradise", "Trouble In Paradise: East Shield Projector", SC2NCO_LOC_ID_OFFSET + 408, LocationType.EXTRA, - lambda state: logic.trouble_in_paradise_requirement(state)), - LocationData("Trouble In Paradise", "Trouble In Paradise: South Shield Projector", SC2NCO_LOC_ID_OFFSET + 409, LocationType.EXTRA, - lambda state: logic.trouble_in_paradise_requirement(state)), - LocationData("Trouble In Paradise", "Trouble In Paradise: West Shield Projector", SC2NCO_LOC_ID_OFFSET + 410, LocationType.EXTRA, - lambda state: logic.trouble_in_paradise_requirement(state)), - LocationData("Trouble In Paradise", "Trouble In Paradise: Fleet Beacon", SC2NCO_LOC_ID_OFFSET + 411, LocationType.VANILLA, - lambda state: logic.trouble_in_paradise_requirement(state)), - LocationData("Night Terrors", "Night Terrors: Victory", SC2NCO_LOC_ID_OFFSET + 500, LocationType.VICTORY, - lambda state: logic.night_terrors_requirement(state)), - LocationData("Night Terrors", "Night Terrors: 1 Terrazine Node Collected", SC2NCO_LOC_ID_OFFSET + 501, LocationType.EXTRA, - lambda state: logic.night_terrors_requirement(state)), - LocationData("Night Terrors", "Night Terrors: 2 Terrazine Nodes Collected", SC2NCO_LOC_ID_OFFSET + 502, LocationType.EXTRA, - lambda state: logic.night_terrors_requirement(state)), - LocationData("Night Terrors", "Night Terrors: 3 Terrazine Nodes Collected", SC2NCO_LOC_ID_OFFSET + 503, LocationType.EXTRA, - lambda state: logic.night_terrors_requirement(state)), - LocationData("Night Terrors", "Night Terrors: 4 Terrazine Nodes Collected", SC2NCO_LOC_ID_OFFSET + 504, LocationType.EXTRA, - lambda state: logic.night_terrors_requirement(state)), - LocationData("Night Terrors", "Night Terrors: 5 Terrazine Nodes Collected", SC2NCO_LOC_ID_OFFSET + 505, LocationType.EXTRA, - lambda state: logic.night_terrors_requirement(state)), - LocationData("Night Terrors", "Night Terrors: HERC Outpost", SC2NCO_LOC_ID_OFFSET + 506, LocationType.VANILLA, - lambda state: logic.night_terrors_requirement(state)), - LocationData("Night Terrors", "Night Terrors: Umojan Mine", SC2NCO_LOC_ID_OFFSET + 507, LocationType.EXTRA, - lambda state: logic.night_terrors_requirement(state)), - LocationData("Night Terrors", "Night Terrors: Blightbringer", SC2NCO_LOC_ID_OFFSET + 508, LocationType.VANILLA, - lambda state: logic.night_terrors_requirement(state) - and logic.nova_ranged_weapon(state) - and state.has_any( - {ItemNames.NOVA_HELLFIRE_SHOTGUN, ItemNames.NOVA_PULSE_GRENADES, ItemNames.NOVA_STIM_INFUSION, - ItemNames.NOVA_HOLO_DECOY}, player)), - LocationData("Night Terrors", "Night Terrors: Science Facility", SC2NCO_LOC_ID_OFFSET + 509, LocationType.EXTRA, - lambda state: logic.night_terrors_requirement(state)), - LocationData("Night Terrors", "Night Terrors: Eradicators", SC2NCO_LOC_ID_OFFSET + 510, LocationType.VANILLA, - lambda state: logic.night_terrors_requirement(state) - and logic.nova_any_weapon(state)), - LocationData("Flashpoint", "Flashpoint: Victory", SC2NCO_LOC_ID_OFFSET + 600, LocationType.VICTORY, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Close North Evidence Coordinates", SC2NCO_LOC_ID_OFFSET + 601, LocationType.EXTRA, - lambda state: state.has_any( - {ItemNames.LIBERATOR_RAID_ARTILLERY, ItemNames.RAVEN_HUNTER_SEEKER_WEAPON}, player) - or logic.terran_common_unit(state)), - LocationData("Flashpoint", "Flashpoint: Close East Evidence Coordinates", SC2NCO_LOC_ID_OFFSET + 602, LocationType.EXTRA, - lambda state: state.has_any( - {ItemNames.LIBERATOR_RAID_ARTILLERY, ItemNames.RAVEN_HUNTER_SEEKER_WEAPON}, player) - or logic.terran_common_unit(state)), - LocationData("Flashpoint", "Flashpoint: Far North Evidence Coordinates", SC2NCO_LOC_ID_OFFSET + 603, LocationType.EXTRA, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Far East Evidence Coordinates", SC2NCO_LOC_ID_OFFSET + 604, LocationType.EXTRA, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Experimental Weapon", SC2NCO_LOC_ID_OFFSET + 605, LocationType.VANILLA, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Northwest Subway Entrance", SC2NCO_LOC_ID_OFFSET + 606, LocationType.VANILLA, - lambda state: state.has_any( - {ItemNames.LIBERATOR_RAID_ARTILLERY, ItemNames.RAVEN_HUNTER_SEEKER_WEAPON}, player) - and logic.terran_common_unit(state) - or logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Southeast Subway Entrance", SC2NCO_LOC_ID_OFFSET + 607, LocationType.VANILLA, - lambda state: state.has_any( - {ItemNames.LIBERATOR_RAID_ARTILLERY, ItemNames.RAVEN_HUNTER_SEEKER_WEAPON}, player) - and logic.terran_common_unit(state) - or logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Northeast Subway Entrance", SC2NCO_LOC_ID_OFFSET + 608, LocationType.VANILLA, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Expansion Hatchery", SC2NCO_LOC_ID_OFFSET + 609, LocationType.EXTRA, - lambda state: state.has(ItemNames.LIBERATOR_RAID_ARTILLERY, player) and logic.terran_common_unit(state) - or logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Baneling Spawns", SC2NCO_LOC_ID_OFFSET + 610, LocationType.EXTRA, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Mutalisk Spawns", SC2NCO_LOC_ID_OFFSET + 611, LocationType.EXTRA, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Nydus Worm Spawns", SC2NCO_LOC_ID_OFFSET + 612, LocationType.EXTRA, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Lurker Spawns", SC2NCO_LOC_ID_OFFSET + 613, LocationType.EXTRA, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Brood Lord Spawns", SC2NCO_LOC_ID_OFFSET + 614, LocationType.EXTRA, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("Flashpoint", "Flashpoint: Ultralisk Spawns", SC2NCO_LOC_ID_OFFSET + 615, LocationType.EXTRA, - lambda state: logic.flashpoint_far_requirement(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Victory", SC2NCO_LOC_ID_OFFSET + 700, LocationType.VICTORY, - lambda state: logic.enemy_shadow_victory(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Sewers: Domination Visor", SC2NCO_LOC_ID_OFFSET + 701, LocationType.VANILLA, - lambda state: logic.enemy_shadow_domination(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Sewers: Resupply Crate", SC2NCO_LOC_ID_OFFSET + 702, LocationType.EXTRA, - lambda state: logic.enemy_shadow_first_stage(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Sewers: Facility Access", SC2NCO_LOC_ID_OFFSET + 703, LocationType.VANILLA, - lambda state: logic.enemy_shadow_first_stage(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Facility: Northwest Door Lock", SC2NCO_LOC_ID_OFFSET + 704, LocationType.VANILLA, - lambda state: logic.enemy_shadow_door_controls(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Facility: Southeast Door Lock", SC2NCO_LOC_ID_OFFSET + 705, LocationType.VANILLA, - lambda state: logic.enemy_shadow_door_controls(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Facility: Blazefire Gunblade", SC2NCO_LOC_ID_OFFSET + 706, LocationType.VANILLA, - lambda state: logic.enemy_shadow_second_stage(state) - and (story_tech_granted - or state.has(ItemNames.NOVA_BLINK, player) - or (adv_tactics and state.has_all({ItemNames.NOVA_DOMINATION, ItemNames.NOVA_HOLO_DECOY, ItemNames.NOVA_JUMP_SUIT_MODULE}, player)) - ) - ), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Facility: Blink Suit", SC2NCO_LOC_ID_OFFSET + 707, LocationType.VANILLA, - lambda state: logic.enemy_shadow_second_stage(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Facility: Advanced Weaponry", SC2NCO_LOC_ID_OFFSET + 708, LocationType.VANILLA, - lambda state: logic.enemy_shadow_second_stage(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Facility: Entrance Resupply Crate", SC2NCO_LOC_ID_OFFSET + 709, LocationType.EXTRA, - lambda state: logic.enemy_shadow_first_stage(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Facility: West Resupply Crate", SC2NCO_LOC_ID_OFFSET + 710, LocationType.EXTRA, - lambda state: logic.enemy_shadow_second_stage(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Facility: North Resupply Crate", SC2NCO_LOC_ID_OFFSET + 711, LocationType.EXTRA, - lambda state: logic.enemy_shadow_second_stage(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Facility: East Resupply Crate", SC2NCO_LOC_ID_OFFSET + 712, LocationType.EXTRA, - lambda state: logic.enemy_shadow_second_stage(state)), - LocationData("In the Enemy's Shadow", "In the Enemy's Shadow: Facility: South Resupply Crate", SC2NCO_LOC_ID_OFFSET + 713, LocationType.EXTRA, - lambda state: logic.enemy_shadow_second_stage(state)), - LocationData("Dark Skies", "Dark Skies: Victory", SC2NCO_LOC_ID_OFFSET + 800, LocationType.VICTORY, - lambda state: logic.dark_skies_requirement(state)), - LocationData("Dark Skies", "Dark Skies: First Squadron of Dominion Fleet", SC2NCO_LOC_ID_OFFSET + 801, LocationType.EXTRA, - lambda state: logic.dark_skies_requirement(state)), - LocationData("Dark Skies", "Dark Skies: Remainder of Dominion Fleet", SC2NCO_LOC_ID_OFFSET + 802, LocationType.EXTRA, - lambda state: logic.dark_skies_requirement(state)), - LocationData("Dark Skies", "Dark Skies: Ji'nara", SC2NCO_LOC_ID_OFFSET + 803, LocationType.EXTRA, - lambda state: logic.dark_skies_requirement(state)), - LocationData("Dark Skies", "Dark Skies: Science Facility", SC2NCO_LOC_ID_OFFSET + 804, LocationType.VANILLA, - lambda state: logic.dark_skies_requirement(state)), - LocationData("End Game", "End Game: Victory", SC2NCO_LOC_ID_OFFSET + 900, LocationType.VICTORY, - lambda state: logic.end_game_requirement(state) and logic.nova_any_weapon(state)), - LocationData("End Game", "End Game: Xanthos", SC2NCO_LOC_ID_OFFSET + 901, LocationType.VANILLA, - lambda state: logic.end_game_requirement(state)), - ] - - beat_events = [] - # Filtering out excluded locations - if world is not None: - excluded_location_types = get_location_types(world, LocationInclusion.option_disabled) - plando_locations = get_plando_locations(world) - exclude_locations = get_option_value(world, "exclude_locations") - location_table = [location for location in location_table - if (location.type is LocationType.VICTORY or location.name not in exclude_locations) - and location.type not in excluded_location_types - or location.name in plando_locations] - for i, location_data in enumerate(location_table): - # Removing all item-based logic on No Logic - if logic_level == RequiredTactics.option_no_logic: - location_data = location_data._replace(rule=Location.access_rule) - location_table[i] = location_data - # Generating Beat event locations - if location_data.name.endswith((": Victory", ": Defeat")): - beat_events.append( - location_data._replace(name="Beat " + location_data.name.rsplit(": ", 1)[0], code=None) - ) - return tuple(location_table + beat_events) - -lookup_location_id_to_type = {loc.code: loc.type for loc in get_locations(None) if loc.code is not None} \ No newline at end of file diff --git a/worlds/sc2/MissionTables.py b/worlds/sc2/MissionTables.py deleted file mode 100644 index 08e1f133deda..000000000000 --- a/worlds/sc2/MissionTables.py +++ /dev/null @@ -1,739 +0,0 @@ -from typing import NamedTuple, Dict, List, Set, Union, Literal, Iterable, Callable -from enum import IntEnum, Enum - - -class SC2Race(IntEnum): - ANY = 0 - TERRAN = 1 - ZERG = 2 - PROTOSS = 3 - - -class MissionPools(IntEnum): - STARTER = 0 - EASY = 1 - MEDIUM = 2 - HARD = 3 - VERY_HARD = 4 - FINAL = 5 - - -class SC2CampaignGoalPriority(IntEnum): - """ - Campaign's priority to goal election - """ - NONE = 0 - MINI_CAMPAIGN = 1 # A goal shouldn't be in a mini-campaign if there's at least one 'big' campaign - HARD = 2 # A campaign ending with a hard mission - VERY_HARD = 3 # A campaign ending with a very hard mission - EPILOGUE = 4 # Epilogue shall be always preferred as the goal if present - - -class SC2Campaign(Enum): - - def __new__(cls, *args, **kwargs): - value = len(cls.__members__) + 1 - obj = object.__new__(cls) - obj._value_ = value - return obj - - def __init__(self, campaign_id: int, name: str, goal_priority: SC2CampaignGoalPriority, race: SC2Race): - self.id = campaign_id - self.campaign_name = name - self.goal_priority = goal_priority - self.race = race - - def __lt__(self, other: "SC2Campaign"): - return self.id < other.id - - GLOBAL = 0, "Global", SC2CampaignGoalPriority.NONE, SC2Race.ANY - WOL = 1, "Wings of Liberty", SC2CampaignGoalPriority.VERY_HARD, SC2Race.TERRAN - PROPHECY = 2, "Prophecy", SC2CampaignGoalPriority.MINI_CAMPAIGN, SC2Race.PROTOSS - HOTS = 3, "Heart of the Swarm", SC2CampaignGoalPriority.HARD, SC2Race.ZERG - PROLOGUE = 4, "Whispers of Oblivion (Legacy of the Void: Prologue)", SC2CampaignGoalPriority.MINI_CAMPAIGN, SC2Race.PROTOSS - LOTV = 5, "Legacy of the Void", SC2CampaignGoalPriority.VERY_HARD, SC2Race.PROTOSS - EPILOGUE = 6, "Into the Void (Legacy of the Void: Epilogue)", SC2CampaignGoalPriority.EPILOGUE, SC2Race.ANY - NCO = 7, "Nova Covert Ops", SC2CampaignGoalPriority.HARD, SC2Race.TERRAN - - -class SC2Mission(Enum): - - def __new__(cls, *args, **kwargs): - value = len(cls.__members__) + 1 - obj = object.__new__(cls) - obj._value_ = value - return obj - - def __init__(self, mission_id: int, name: str, campaign: SC2Campaign, area: str, race: SC2Race, pool: MissionPools, map_file: str, build: bool = True): - self.id = mission_id - self.mission_name = name - self.campaign = campaign - self.area = area - self.race = race - self.pool = pool - self.map_file = map_file - self.build = build - - # Wings of Liberty - LIBERATION_DAY = 1, "Liberation Day", SC2Campaign.WOL, "Mar Sara", SC2Race.ANY, MissionPools.STARTER, "ap_liberation_day", False - THE_OUTLAWS = 2, "The Outlaws", SC2Campaign.WOL, "Mar Sara", SC2Race.TERRAN, MissionPools.EASY, "ap_the_outlaws" - ZERO_HOUR = 3, "Zero Hour", SC2Campaign.WOL, "Mar Sara", SC2Race.TERRAN, MissionPools.EASY, "ap_zero_hour" - EVACUATION = 4, "Evacuation", SC2Campaign.WOL, "Colonist", SC2Race.TERRAN, MissionPools.EASY, "ap_evacuation" - OUTBREAK = 5, "Outbreak", SC2Campaign.WOL, "Colonist", SC2Race.TERRAN, MissionPools.EASY, "ap_outbreak" - SAFE_HAVEN = 6, "Safe Haven", SC2Campaign.WOL, "Colonist", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_safe_haven" - HAVENS_FALL = 7, "Haven's Fall", SC2Campaign.WOL, "Colonist", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_havens_fall" - SMASH_AND_GRAB = 8, "Smash and Grab", SC2Campaign.WOL, "Artifact", SC2Race.TERRAN, MissionPools.EASY, "ap_smash_and_grab" - THE_DIG = 9, "The Dig", SC2Campaign.WOL, "Artifact", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_the_dig" - THE_MOEBIUS_FACTOR = 10, "The Moebius Factor", SC2Campaign.WOL, "Artifact", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_the_moebius_factor" - SUPERNOVA = 11, "Supernova", SC2Campaign.WOL, "Artifact", SC2Race.TERRAN, MissionPools.HARD, "ap_supernova" - MAW_OF_THE_VOID = 12, "Maw of the Void", SC2Campaign.WOL, "Artifact", SC2Race.TERRAN, MissionPools.HARD, "ap_maw_of_the_void" - DEVILS_PLAYGROUND = 13, "Devil's Playground", SC2Campaign.WOL, "Covert", SC2Race.TERRAN, MissionPools.EASY, "ap_devils_playground" - WELCOME_TO_THE_JUNGLE = 14, "Welcome to the Jungle", SC2Campaign.WOL, "Covert", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_welcome_to_the_jungle" - BREAKOUT = 15, "Breakout", SC2Campaign.WOL, "Covert", SC2Race.ANY, MissionPools.STARTER, "ap_breakout", False - GHOST_OF_A_CHANCE = 16, "Ghost of a Chance", SC2Campaign.WOL, "Covert", SC2Race.ANY, MissionPools.STARTER, "ap_ghost_of_a_chance", False - THE_GREAT_TRAIN_ROBBERY = 17, "The Great Train Robbery", SC2Campaign.WOL, "Rebellion", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_the_great_train_robbery" - CUTTHROAT = 18, "Cutthroat", SC2Campaign.WOL, "Rebellion", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_cutthroat" - ENGINE_OF_DESTRUCTION = 19, "Engine of Destruction", SC2Campaign.WOL, "Rebellion", SC2Race.TERRAN, MissionPools.HARD, "ap_engine_of_destruction" - MEDIA_BLITZ = 20, "Media Blitz", SC2Campaign.WOL, "Rebellion", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_media_blitz" - PIERCING_OF_THE_SHROUD = 21, "Piercing the Shroud", SC2Campaign.WOL, "Rebellion", SC2Race.TERRAN, MissionPools.STARTER, "ap_piercing_the_shroud", False - GATES_OF_HELL = 26, "Gates of Hell", SC2Campaign.WOL, "Char", SC2Race.TERRAN, MissionPools.HARD, "ap_gates_of_hell" - BELLY_OF_THE_BEAST = 27, "Belly of the Beast", SC2Campaign.WOL, "Char", SC2Race.ANY, MissionPools.STARTER, "ap_belly_of_the_beast", False - SHATTER_THE_SKY = 28, "Shatter the Sky", SC2Campaign.WOL, "Char", SC2Race.TERRAN, MissionPools.HARD, "ap_shatter_the_sky" - ALL_IN = 29, "All-In", SC2Campaign.WOL, "Char", SC2Race.TERRAN, MissionPools.VERY_HARD, "ap_all_in" - - # Prophecy - WHISPERS_OF_DOOM = 22, "Whispers of Doom", SC2Campaign.PROPHECY, "_1", SC2Race.ANY, MissionPools.STARTER, "ap_whispers_of_doom", False - A_SINISTER_TURN = 23, "A Sinister Turn", SC2Campaign.PROPHECY, "_2", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_a_sinister_turn" - ECHOES_OF_THE_FUTURE = 24, "Echoes of the Future", SC2Campaign.PROPHECY, "_3", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_echoes_of_the_future" - IN_UTTER_DARKNESS = 25, "In Utter Darkness", SC2Campaign.PROPHECY, "_4", SC2Race.PROTOSS, MissionPools.HARD, "ap_in_utter_darkness" - - # Heart of the Swarm - LAB_RAT = 30, "Lab Rat", SC2Campaign.HOTS, "Umoja", SC2Race.ZERG, MissionPools.STARTER, "ap_lab_rat" - BACK_IN_THE_SADDLE = 31, "Back in the Saddle", SC2Campaign.HOTS, "Umoja", SC2Race.ANY, MissionPools.STARTER, "ap_back_in_the_saddle", False - RENDEZVOUS = 32, "Rendezvous", SC2Campaign.HOTS, "Umoja", SC2Race.ZERG, MissionPools.EASY, "ap_rendezvous" - HARVEST_OF_SCREAMS = 33, "Harvest of Screams", SC2Campaign.HOTS, "Kaldir", SC2Race.ZERG, MissionPools.EASY, "ap_harvest_of_screams" - SHOOT_THE_MESSENGER = 34, "Shoot the Messenger", SC2Campaign.HOTS, "Kaldir", SC2Race.ZERG, MissionPools.EASY, "ap_shoot_the_messenger" - ENEMY_WITHIN = 35, "Enemy Within", SC2Campaign.HOTS, "Kaldir", SC2Race.ANY, MissionPools.EASY, "ap_enemy_within", False - DOMINATION = 36, "Domination", SC2Campaign.HOTS, "Char", SC2Race.ZERG, MissionPools.EASY, "ap_domination" - FIRE_IN_THE_SKY = 37, "Fire in the Sky", SC2Campaign.HOTS, "Char", SC2Race.ZERG, MissionPools.MEDIUM, "ap_fire_in_the_sky" - OLD_SOLDIERS = 38, "Old Soldiers", SC2Campaign.HOTS, "Char", SC2Race.ZERG, MissionPools.MEDIUM, "ap_old_soldiers" - WAKING_THE_ANCIENT = 39, "Waking the Ancient", SC2Campaign.HOTS, "Zerus", SC2Race.ZERG, MissionPools.MEDIUM, "ap_waking_the_ancient" - THE_CRUCIBLE = 40, "The Crucible", SC2Campaign.HOTS, "Zerus", SC2Race.ZERG, MissionPools.MEDIUM, "ap_the_crucible" - SUPREME = 41, "Supreme", SC2Campaign.HOTS, "Zerus", SC2Race.ANY, MissionPools.MEDIUM, "ap_supreme", False - INFESTED = 42, "Infested", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.ZERG, MissionPools.MEDIUM, "ap_infested" - HAND_OF_DARKNESS = 43, "Hand of Darkness", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.ZERG, MissionPools.HARD, "ap_hand_of_darkness" - PHANTOMS_OF_THE_VOID = 44, "Phantoms of the Void", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.ZERG, MissionPools.HARD, "ap_phantoms_of_the_void" - WITH_FRIENDS_LIKE_THESE = 45, "With Friends Like These", SC2Campaign.HOTS, "Dominion Space", SC2Race.ANY, MissionPools.STARTER, "ap_with_friends_like_these", False - CONVICTION = 46, "Conviction", SC2Campaign.HOTS, "Dominion Space", SC2Race.ANY, MissionPools.MEDIUM, "ap_conviction", False - PLANETFALL = 47, "Planetfall", SC2Campaign.HOTS, "Korhal", SC2Race.ZERG, MissionPools.HARD, "ap_planetfall" - DEATH_FROM_ABOVE = 48, "Death From Above", SC2Campaign.HOTS, "Korhal", SC2Race.ZERG, MissionPools.HARD, "ap_death_from_above" - THE_RECKONING = 49, "The Reckoning", SC2Campaign.HOTS, "Korhal", SC2Race.ZERG, MissionPools.HARD, "ap_the_reckoning" - - # Prologue - DARK_WHISPERS = 50, "Dark Whispers", SC2Campaign.PROLOGUE, "_1", SC2Race.PROTOSS, MissionPools.EASY, "ap_dark_whispers" - GHOSTS_IN_THE_FOG = 51, "Ghosts in the Fog", SC2Campaign.PROLOGUE, "_2", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_ghosts_in_the_fog" - EVIL_AWOKEN = 52, "Evil Awoken", SC2Campaign.PROLOGUE, "_3", SC2Race.PROTOSS, MissionPools.STARTER, "ap_evil_awoken", False - - # LotV - FOR_AIUR = 53, "For Aiur!", SC2Campaign.LOTV, "Aiur", SC2Race.ANY, MissionPools.STARTER, "ap_for_aiur", False - THE_GROWING_SHADOW = 54, "The Growing Shadow", SC2Campaign.LOTV, "Aiur", SC2Race.PROTOSS, MissionPools.EASY, "ap_the_growing_shadow" - THE_SPEAR_OF_ADUN = 55, "The Spear of Adun", SC2Campaign.LOTV, "Aiur", SC2Race.PROTOSS, MissionPools.EASY, "ap_the_spear_of_adun" - SKY_SHIELD = 56, "Sky Shield", SC2Campaign.LOTV, "Korhal", SC2Race.PROTOSS, MissionPools.EASY, "ap_sky_shield" - BROTHERS_IN_ARMS = 57, "Brothers in Arms", SC2Campaign.LOTV, "Korhal", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_brothers_in_arms" - AMON_S_REACH = 58, "Amon's Reach", SC2Campaign.LOTV, "Shakuras", SC2Race.PROTOSS, MissionPools.EASY, "ap_amon_s_reach" - LAST_STAND = 59, "Last Stand", SC2Campaign.LOTV, "Shakuras", SC2Race.PROTOSS, MissionPools.HARD, "ap_last_stand" - FORBIDDEN_WEAPON = 60, "Forbidden Weapon", SC2Campaign.LOTV, "Purifier", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_forbidden_weapon" - TEMPLE_OF_UNIFICATION = 61, "Temple of Unification", SC2Campaign.LOTV, "Ulnar", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_temple_of_unification" - THE_INFINITE_CYCLE = 62, "The Infinite Cycle", SC2Campaign.LOTV, "Ulnar", SC2Race.ANY, MissionPools.HARD, "ap_the_infinite_cycle", False - HARBINGER_OF_OBLIVION = 63, "Harbinger of Oblivion", SC2Campaign.LOTV, "Ulnar", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_harbinger_of_oblivion" - UNSEALING_THE_PAST = 64, "Unsealing the Past", SC2Campaign.LOTV, "Purifier", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_unsealing_the_past" - PURIFICATION = 65, "Purification", SC2Campaign.LOTV, "Purifier", SC2Race.PROTOSS, MissionPools.HARD, "ap_purification" - STEPS_OF_THE_RITE = 66, "Steps of the Rite", SC2Campaign.LOTV, "Tal'darim", SC2Race.PROTOSS, MissionPools.HARD, "ap_steps_of_the_rite" - RAK_SHIR = 67, "Rak'Shir", SC2Campaign.LOTV, "Tal'darim", SC2Race.PROTOSS, MissionPools.HARD, "ap_rak_shir" - TEMPLAR_S_CHARGE = 68, "Templar's Charge", SC2Campaign.LOTV, "Moebius", SC2Race.PROTOSS, MissionPools.HARD, "ap_templar_s_charge" - TEMPLAR_S_RETURN = 69, "Templar's Return", SC2Campaign.LOTV, "Return to Aiur", SC2Race.PROTOSS, MissionPools.EASY, "ap_templar_s_return", False - THE_HOST = 70, "The Host", SC2Campaign.LOTV, "Return to Aiur", SC2Race.PROTOSS, MissionPools.HARD, "ap_the_host", - SALVATION = 71, "Salvation", SC2Campaign.LOTV, "Return to Aiur", SC2Race.PROTOSS, MissionPools.VERY_HARD, "ap_salvation" - - # Epilogue - INTO_THE_VOID = 72, "Into the Void", SC2Campaign.EPILOGUE, "_1", SC2Race.PROTOSS, MissionPools.VERY_HARD, "ap_into_the_void" - THE_ESSENCE_OF_ETERNITY = 73, "The Essence of Eternity", SC2Campaign.EPILOGUE, "_2", SC2Race.TERRAN, MissionPools.VERY_HARD, "ap_the_essence_of_eternity" - AMON_S_FALL = 74, "Amon's Fall", SC2Campaign.EPILOGUE, "_3", SC2Race.ZERG, MissionPools.VERY_HARD, "ap_amon_s_fall" - - # Nova Covert Ops - THE_ESCAPE = 75, "The Escape", SC2Campaign.NCO, "_1", SC2Race.ANY, MissionPools.MEDIUM, "ap_the_escape", False - SUDDEN_STRIKE = 76, "Sudden Strike", SC2Campaign.NCO, "_1", SC2Race.TERRAN, MissionPools.EASY, "ap_sudden_strike" - ENEMY_INTELLIGENCE = 77, "Enemy Intelligence", SC2Campaign.NCO, "_1", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_enemy_intelligence" - TROUBLE_IN_PARADISE = 78, "Trouble In Paradise", SC2Campaign.NCO, "_2", SC2Race.TERRAN, MissionPools.HARD, "ap_trouble_in_paradise" - NIGHT_TERRORS = 79, "Night Terrors", SC2Campaign.NCO, "_2", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_night_terrors" - FLASHPOINT = 80, "Flashpoint", SC2Campaign.NCO, "_2", SC2Race.TERRAN, MissionPools.HARD, "ap_flashpoint" - IN_THE_ENEMY_S_SHADOW = 81, "In the Enemy's Shadow", SC2Campaign.NCO, "_3", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_in_the_enemy_s_shadow", False - DARK_SKIES = 82, "Dark Skies", SC2Campaign.NCO, "_3", SC2Race.TERRAN, MissionPools.HARD, "ap_dark_skies" - END_GAME = 83, "End Game", SC2Campaign.NCO, "_3", SC2Race.TERRAN, MissionPools.VERY_HARD, "ap_end_game" - - -class MissionConnection: - campaign: SC2Campaign - connect_to: int # -1 connects to Menu - - def __init__(self, connect_to, campaign = SC2Campaign.GLOBAL): - self.campaign = campaign - self.connect_to = connect_to - - def _asdict(self): - return { - "campaign": self.campaign.id, - "connect_to": self.connect_to - } - - -class MissionInfo(NamedTuple): - mission: SC2Mission - required_world: List[Union[MissionConnection, Dict[Literal["campaign", "connect_to"], int]]] - category: str - number: int = 0 # number of worlds need beaten - completion_critical: bool = False # missions needed to beat game - or_requirements: bool = False # true if the requirements should be or-ed instead of and-ed - ui_vertical_padding: int = 0 - - -class FillMission(NamedTuple): - type: MissionPools - connect_to: List[MissionConnection] - category: str - number: int = 0 # number of worlds need beaten - completion_critical: bool = False # missions needed to beat game - or_requirements: bool = False # true if the requirements should be or-ed instead of and-ed - removal_priority: int = 0 # how many missions missing from the pool required to remove this mission - - - -def vanilla_shuffle_order() -> Dict[SC2Campaign, List[FillMission]]: - return { - SC2Campaign.WOL: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1, SC2Campaign.WOL)], "Mar Sara", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(0, SC2Campaign.WOL)], "Mar Sara", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(1, SC2Campaign.WOL)], "Mar Sara", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(2, SC2Campaign.WOL)], "Colonist"), - FillMission(MissionPools.MEDIUM, [MissionConnection(3, SC2Campaign.WOL)], "Colonist"), - FillMission(MissionPools.HARD, [MissionConnection(4, SC2Campaign.WOL)], "Colonist", number=7), - FillMission(MissionPools.HARD, [MissionConnection(4, SC2Campaign.WOL)], "Colonist", number=7, removal_priority=1), - FillMission(MissionPools.EASY, [MissionConnection(2, SC2Campaign.WOL)], "Artifact", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(7, SC2Campaign.WOL)], "Artifact", number=8, completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(8, SC2Campaign.WOL)], "Artifact", number=11, completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(9, SC2Campaign.WOL)], "Artifact", number=14, completion_critical=True, removal_priority=7), - FillMission(MissionPools.HARD, [MissionConnection(10, SC2Campaign.WOL)], "Artifact", completion_critical=True, removal_priority=6), - FillMission(MissionPools.MEDIUM, [MissionConnection(2, SC2Campaign.WOL)], "Covert", number=4), - FillMission(MissionPools.MEDIUM, [MissionConnection(12, SC2Campaign.WOL)], "Covert"), - FillMission(MissionPools.HARD, [MissionConnection(13, SC2Campaign.WOL)], "Covert", number=8, removal_priority=3), - FillMission(MissionPools.HARD, [MissionConnection(13, SC2Campaign.WOL)], "Covert", number=8, removal_priority=2), - FillMission(MissionPools.MEDIUM, [MissionConnection(2, SC2Campaign.WOL)], "Rebellion", number=6), - FillMission(MissionPools.HARD, [MissionConnection(16, SC2Campaign.WOL)], "Rebellion"), - FillMission(MissionPools.HARD, [MissionConnection(17, SC2Campaign.WOL)], "Rebellion"), - FillMission(MissionPools.HARD, [MissionConnection(18, SC2Campaign.WOL)], "Rebellion", removal_priority=8), - FillMission(MissionPools.HARD, [MissionConnection(19, SC2Campaign.WOL)], "Rebellion", removal_priority=5), - FillMission(MissionPools.HARD, [MissionConnection(11, SC2Campaign.WOL)], "Char", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(21, SC2Campaign.WOL)], "Char", completion_critical=True, removal_priority=4), - FillMission(MissionPools.HARD, [MissionConnection(21, SC2Campaign.WOL)], "Char", completion_critical=True), - FillMission(MissionPools.FINAL, [MissionConnection(22, SC2Campaign.WOL), MissionConnection(23, SC2Campaign.WOL)], "Char", completion_critical=True, or_requirements=True) - ], - SC2Campaign.PROPHECY: [ - FillMission(MissionPools.MEDIUM, [MissionConnection(8, SC2Campaign.WOL)], "_1"), - FillMission(MissionPools.HARD, [MissionConnection(0, SC2Campaign.PROPHECY)], "_2", removal_priority=2), - FillMission(MissionPools.HARD, [MissionConnection(1, SC2Campaign.PROPHECY)], "_3", removal_priority=1), - FillMission(MissionPools.FINAL, [MissionConnection(2, SC2Campaign.PROPHECY)], "_4"), - ], - SC2Campaign.HOTS: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1, SC2Campaign.HOTS)], "Umoja", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(0, SC2Campaign.HOTS)], "Umoja", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(1, SC2Campaign.HOTS)], "Umoja", completion_critical=True, removal_priority=1), - FillMission(MissionPools.EASY, [MissionConnection(2, SC2Campaign.HOTS)], "Kaldir", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(3, SC2Campaign.HOTS)], "Kaldir", completion_critical=True, removal_priority=2), - FillMission(MissionPools.MEDIUM, [MissionConnection(4, SC2Campaign.HOTS)], "Kaldir", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(2, SC2Campaign.HOTS)], "Char", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(6, SC2Campaign.HOTS)], "Char", completion_critical=True, removal_priority=3), - FillMission(MissionPools.MEDIUM, [MissionConnection(7, SC2Campaign.HOTS)], "Char", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(5, SC2Campaign.HOTS), MissionConnection(8, SC2Campaign.HOTS)], "Zerus", completion_critical=True, or_requirements=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(9, SC2Campaign.HOTS)], "Zerus", completion_critical=True, removal_priority=4), - FillMission(MissionPools.MEDIUM, [MissionConnection(10, SC2Campaign.HOTS)], "Zerus", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(5, SC2Campaign.HOTS), MissionConnection(8, SC2Campaign.HOTS), MissionConnection(11, SC2Campaign.HOTS)], "Skygeirr Station", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(12, SC2Campaign.HOTS)], "Skygeirr Station", completion_critical=True, removal_priority=5), - FillMission(MissionPools.HARD, [MissionConnection(13, SC2Campaign.HOTS)], "Skygeirr Station", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(5, SC2Campaign.HOTS), MissionConnection(8, SC2Campaign.HOTS), MissionConnection(11, SC2Campaign.HOTS)], "Dominion Space", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(15, SC2Campaign.HOTS)], "Dominion Space", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(14, SC2Campaign.HOTS), MissionConnection(16, SC2Campaign.HOTS)], "Korhal", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(17, SC2Campaign.HOTS)], "Korhal", completion_critical=True), - FillMission(MissionPools.FINAL, [MissionConnection(18, SC2Campaign.HOTS)], "Korhal", completion_critical=True), - ], - SC2Campaign.PROLOGUE: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1, SC2Campaign.PROLOGUE)], "_1"), - FillMission(MissionPools.MEDIUM, [MissionConnection(0, SC2Campaign.PROLOGUE)], "_2", removal_priority=1), - FillMission(MissionPools.FINAL, [MissionConnection(1, SC2Campaign.PROLOGUE)], "_3") - ], - SC2Campaign.LOTV: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1, SC2Campaign.LOTV)], "Aiur", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(0, SC2Campaign.LOTV)], "Aiur", completion_critical=True, removal_priority=3), - FillMission(MissionPools.EASY, [MissionConnection(1, SC2Campaign.LOTV)], "Aiur", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(2, SC2Campaign.LOTV)], "Korhal", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(3, SC2Campaign.LOTV)], "Korhal", completion_critical=True, removal_priority=7), - FillMission(MissionPools.MEDIUM, [MissionConnection(2, SC2Campaign.LOTV)], "Shakuras", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(5, SC2Campaign.LOTV)], "Shakuras", completion_critical=True, removal_priority=6), - FillMission(MissionPools.HARD, [MissionConnection(4, SC2Campaign.LOTV), MissionConnection(6, SC2Campaign.LOTV)], "Purifier", completion_critical=True, or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(4, SC2Campaign.LOTV), MissionConnection(6, SC2Campaign.LOTV), MissionConnection(7, SC2Campaign.LOTV)], "Ulnar", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(8, SC2Campaign.LOTV)], "Ulnar", completion_critical=True, removal_priority=1), - FillMission(MissionPools.HARD, [MissionConnection(9, SC2Campaign.LOTV)], "Ulnar", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(10, SC2Campaign.LOTV)], "Purifier", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(11, SC2Campaign.LOTV)], "Purifier", completion_critical=True, removal_priority=5), - FillMission(MissionPools.HARD, [MissionConnection(10, SC2Campaign.LOTV)], "Tal'darim", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(13, SC2Campaign.LOTV)], "Tal'darim", completion_critical=True, removal_priority=4), - FillMission(MissionPools.HARD, [MissionConnection(12, SC2Campaign.LOTV), MissionConnection(14, SC2Campaign.LOTV)], "Moebius", completion_critical=True, or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(12, SC2Campaign.LOTV), MissionConnection(14, SC2Campaign.LOTV), MissionConnection(15, SC2Campaign.LOTV)], "Return to Aiur", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(16, SC2Campaign.LOTV)], "Return to Aiur", completion_critical=True, removal_priority=2), - FillMission(MissionPools.FINAL, [MissionConnection(17, SC2Campaign.LOTV)], "Return to Aiur", completion_critical=True), - ], - SC2Campaign.EPILOGUE: [ - FillMission(MissionPools.VERY_HARD, [MissionConnection(24, SC2Campaign.WOL), MissionConnection(19, SC2Campaign.HOTS), MissionConnection(18, SC2Campaign.LOTV)], "_1", completion_critical=True), - FillMission(MissionPools.VERY_HARD, [MissionConnection(0, SC2Campaign.EPILOGUE)], "_2", completion_critical=True, removal_priority=1), - FillMission(MissionPools.FINAL, [MissionConnection(1, SC2Campaign.EPILOGUE)], "_3", completion_critical=True), - ], - SC2Campaign.NCO: [ - FillMission(MissionPools.EASY, [MissionConnection(-1, SC2Campaign.NCO)], "_1", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(0, SC2Campaign.NCO)], "_1", completion_critical=True, removal_priority=6), - FillMission(MissionPools.MEDIUM, [MissionConnection(1, SC2Campaign.NCO)], "_1", completion_critical=True, removal_priority=5), - FillMission(MissionPools.HARD, [MissionConnection(2, SC2Campaign.NCO)], "_2", completion_critical=True, removal_priority=7), - FillMission(MissionPools.HARD, [MissionConnection(3, SC2Campaign.NCO)], "_2", completion_critical=True, removal_priority=4), - FillMission(MissionPools.HARD, [MissionConnection(4, SC2Campaign.NCO)], "_2", completion_critical=True, removal_priority=3), - FillMission(MissionPools.HARD, [MissionConnection(5, SC2Campaign.NCO)], "_3", completion_critical=True, removal_priority=2), - FillMission(MissionPools.HARD, [MissionConnection(6, SC2Campaign.NCO)], "_3", completion_critical=True, removal_priority=1), - FillMission(MissionPools.FINAL, [MissionConnection(7, SC2Campaign.NCO)], "_3", completion_critical=True), - ] - } - - -def mini_campaign_order() -> Dict[SC2Campaign, List[FillMission]]: - return { - SC2Campaign.WOL: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1, SC2Campaign.WOL)], "Mar Sara", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(0, SC2Campaign.WOL)], "Colonist"), - FillMission(MissionPools.MEDIUM, [MissionConnection(1, SC2Campaign.WOL)], "Colonist"), - FillMission(MissionPools.EASY, [MissionConnection(0, SC2Campaign.WOL)], "Artifact", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(3, SC2Campaign.WOL)], "Artifact", number=4, completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(4, SC2Campaign.WOL)], "Artifact", number=8, completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(0, SC2Campaign.WOL)], "Covert", number=2), - FillMission(MissionPools.HARD, [MissionConnection(6, SC2Campaign.WOL)], "Covert"), - FillMission(MissionPools.MEDIUM, [MissionConnection(0, SC2Campaign.WOL)], "Rebellion", number=3), - FillMission(MissionPools.HARD, [MissionConnection(8, SC2Campaign.WOL)], "Rebellion"), - FillMission(MissionPools.HARD, [MissionConnection(5, SC2Campaign.WOL)], "Char", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(5, SC2Campaign.WOL)], "Char", completion_critical=True), - FillMission(MissionPools.FINAL, [MissionConnection(10, SC2Campaign.WOL), MissionConnection(11, SC2Campaign.WOL)], "Char", completion_critical=True, or_requirements=True) - ], - SC2Campaign.PROPHECY: [ - FillMission(MissionPools.MEDIUM, [MissionConnection(4, SC2Campaign.WOL)], "_1"), - FillMission(MissionPools.FINAL, [MissionConnection(0, SC2Campaign.PROPHECY)], "_2"), - ], - SC2Campaign.HOTS: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1, SC2Campaign.HOTS)], "Umoja", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(0, SC2Campaign.HOTS)], "Kaldir"), - FillMission(MissionPools.MEDIUM, [MissionConnection(1, SC2Campaign.HOTS)], "Kaldir"), - FillMission(MissionPools.EASY, [MissionConnection(0, SC2Campaign.HOTS)], "Char"), - FillMission(MissionPools.MEDIUM, [MissionConnection(3, SC2Campaign.HOTS)], "Char"), - FillMission(MissionPools.MEDIUM, [MissionConnection(0, SC2Campaign.HOTS)], "Zerus", number=3), - FillMission(MissionPools.MEDIUM, [MissionConnection(5, SC2Campaign.HOTS)], "Zerus"), - FillMission(MissionPools.HARD, [MissionConnection(6, SC2Campaign.HOTS)], "Skygeirr Station", number=5), - FillMission(MissionPools.HARD, [MissionConnection(7, SC2Campaign.HOTS)], "Skygeirr Station"), - FillMission(MissionPools.HARD, [MissionConnection(6, SC2Campaign.HOTS)], "Dominion Space", number=5), - FillMission(MissionPools.HARD, [MissionConnection(9, SC2Campaign.HOTS)], "Dominion Space"), - FillMission(MissionPools.HARD, [MissionConnection(6, SC2Campaign.HOTS)], "Korhal", completion_critical=True, number=8), - FillMission(MissionPools.FINAL, [MissionConnection(11, SC2Campaign.HOTS)], "Korhal", completion_critical=True), - ], - SC2Campaign.PROLOGUE: [ - FillMission(MissionPools.EASY, [MissionConnection(-1, SC2Campaign.PROLOGUE)], "_1"), - FillMission(MissionPools.FINAL, [MissionConnection(0, SC2Campaign.PROLOGUE)], "_2") - ], - SC2Campaign.LOTV: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1, SC2Campaign.LOTV)], "Aiur",completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(0, SC2Campaign.LOTV)], "Aiur", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(1, SC2Campaign.LOTV)], "Korhal", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(1, SC2Campaign.LOTV)], "Shakuras", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(2, SC2Campaign.LOTV), MissionConnection(3, SC2Campaign.LOTV)], "Purifier", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(6, SC2Campaign.LOTV)], "Purifier", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(4, SC2Campaign.LOTV)], "Ulnar", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(6, SC2Campaign.LOTV)], "Tal'darim", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(5, SC2Campaign.LOTV), MissionConnection(7, SC2Campaign.LOTV)], "Return to Aiur", completion_critical=True), - FillMission(MissionPools.FINAL, [MissionConnection(8, SC2Campaign.LOTV)], "Return to Aiur", completion_critical=True), - ], - SC2Campaign.EPILOGUE: [ - FillMission(MissionPools.VERY_HARD, [MissionConnection(12, SC2Campaign.WOL), MissionConnection(12, SC2Campaign.HOTS), MissionConnection(9, SC2Campaign.LOTV)], "_1", completion_critical=True), - FillMission(MissionPools.FINAL, [MissionConnection(0, SC2Campaign.EPILOGUE)], "_2", completion_critical=True), - ], - SC2Campaign.NCO: [ - FillMission(MissionPools.EASY, [MissionConnection(-1, SC2Campaign.NCO)], "_1", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(0, SC2Campaign.NCO)], "_1", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(1, SC2Campaign.NCO)], "_2", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(2, SC2Campaign.NCO)], "_3", completion_critical=True), - FillMission(MissionPools.FINAL, [MissionConnection(3, SC2Campaign.NCO)], "_3", completion_critical=True), - ] - } - - -def gauntlet_order() -> Dict[SC2Campaign, List[FillMission]]: - return { - SC2Campaign.GLOBAL: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1)], "I", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(0)], "II", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(1)], "III", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(2)], "IV", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(3)], "V", completion_critical=True), - FillMission(MissionPools.HARD, [MissionConnection(4)], "VI", completion_critical=True), - FillMission(MissionPools.FINAL, [MissionConnection(5)], "Final", completion_critical=True) - ] - } - - -def mini_gauntlet_order() -> Dict[SC2Campaign, List[FillMission]]: - return { - SC2Campaign.GLOBAL: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1)], "I", completion_critical=True), - FillMission(MissionPools.EASY, [MissionConnection(0)], "II", completion_critical=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(1)], "III", completion_critical=True), - FillMission(MissionPools.FINAL, [MissionConnection(2)], "Final", completion_critical=True) - ] - } - - -def grid_order() -> Dict[SC2Campaign, List[FillMission]]: - return { - SC2Campaign.GLOBAL: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1)], "_1"), - FillMission(MissionPools.EASY, [MissionConnection(0)], "_1"), - FillMission(MissionPools.MEDIUM, [MissionConnection(1), MissionConnection(6), MissionConnection( 3)], "_1", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(2), MissionConnection(7)], "_1", or_requirements=True), - FillMission(MissionPools.EASY, [MissionConnection(0)], "_2"), - FillMission(MissionPools.MEDIUM, [MissionConnection(1), MissionConnection(4)], "_2", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(2), MissionConnection(5), MissionConnection(10), MissionConnection(7)], "_2", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(3), MissionConnection(6), MissionConnection(11)], "_2", or_requirements=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(4), MissionConnection(9), MissionConnection(12)], "_3", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(5), MissionConnection(8), MissionConnection(10), MissionConnection(13)], "_3", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(6), MissionConnection(9), MissionConnection(11), MissionConnection(14)], "_3", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(7), MissionConnection(10)], "_3", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(8), MissionConnection(13)], "_4", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(9), MissionConnection(12), MissionConnection(14)], "_4", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(10), MissionConnection(13)], "_4", or_requirements=True), - FillMission(MissionPools.FINAL, [MissionConnection(11), MissionConnection(14)], "_4", or_requirements=True) - ] - } - -def mini_grid_order() -> Dict[SC2Campaign, List[FillMission]]: - return { - SC2Campaign.GLOBAL: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1)], "_1"), - FillMission(MissionPools.EASY, [MissionConnection(0)], "_1"), - FillMission(MissionPools.MEDIUM, [MissionConnection(1), MissionConnection(5)], "_1", or_requirements=True), - FillMission(MissionPools.EASY, [MissionConnection(0)], "_2"), - FillMission(MissionPools.MEDIUM, [MissionConnection(1), MissionConnection(3)], "_2", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(2), MissionConnection(4)], "_2", or_requirements=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(3), MissionConnection(7)], "_3", or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(4), MissionConnection(6)], "_3", or_requirements=True), - FillMission(MissionPools.FINAL, [MissionConnection(5), MissionConnection(7)], "_3", or_requirements=True) - ] - } - -def tiny_grid_order() -> Dict[SC2Campaign, List[FillMission]]: - return { - SC2Campaign.GLOBAL: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1)], "_1"), - FillMission(MissionPools.MEDIUM, [MissionConnection(0)], "_1"), - FillMission(MissionPools.EASY, [MissionConnection(0)], "_2"), - FillMission(MissionPools.FINAL, [MissionConnection(1), MissionConnection(2)], "_2", or_requirements=True), - ] - } - -def blitz_order() -> Dict[SC2Campaign, List[FillMission]]: - return { - SC2Campaign.GLOBAL: [ - FillMission(MissionPools.STARTER, [MissionConnection(-1)], "I"), - FillMission(MissionPools.EASY, [MissionConnection(-1)], "I"), - FillMission(MissionPools.MEDIUM, [MissionConnection(0), MissionConnection(1)], "II", number=1, or_requirements=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(0), MissionConnection(1)], "II", number=1, or_requirements=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(0), MissionConnection(1)], "III", number=2, or_requirements=True), - FillMission(MissionPools.MEDIUM, [MissionConnection(0), MissionConnection(1)], "III", number=2, or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(0), MissionConnection(1)], "IV", number=3, or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(0), MissionConnection(1)], "IV", number=3, or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(0), MissionConnection(1)], "V", number=4, or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(0), MissionConnection(1)], "V", number=4, or_requirements=True), - FillMission(MissionPools.HARD, [MissionConnection(0), MissionConnection(1)], "Final", number=5, or_requirements=True), - FillMission(MissionPools.FINAL, [MissionConnection(0), MissionConnection(1)], "Final", number=5, or_requirements=True) - ] - } - - -mission_orders: List[Callable[[], Dict[SC2Campaign, List[FillMission]]]] = [ - vanilla_shuffle_order, - vanilla_shuffle_order, - mini_campaign_order, - grid_order, - mini_grid_order, - blitz_order, - gauntlet_order, - mini_gauntlet_order, - tiny_grid_order -] - - -vanilla_mission_req_table: Dict[SC2Campaign, Dict[str, MissionInfo]] = { - SC2Campaign.WOL: { - SC2Mission.LIBERATION_DAY.mission_name: MissionInfo(SC2Mission.LIBERATION_DAY, [], SC2Mission.LIBERATION_DAY.area, completion_critical=True), - SC2Mission.THE_OUTLAWS.mission_name: MissionInfo(SC2Mission.THE_OUTLAWS, [MissionConnection(1, SC2Campaign.WOL)], SC2Mission.THE_OUTLAWS.area, completion_critical=True), - SC2Mission.ZERO_HOUR.mission_name: MissionInfo(SC2Mission.ZERO_HOUR, [MissionConnection(2, SC2Campaign.WOL)], SC2Mission.ZERO_HOUR.area, completion_critical=True), - SC2Mission.EVACUATION.mission_name: MissionInfo(SC2Mission.EVACUATION, [MissionConnection(3, SC2Campaign.WOL)], SC2Mission.EVACUATION.area), - SC2Mission.OUTBREAK.mission_name: MissionInfo(SC2Mission.OUTBREAK, [MissionConnection(4, SC2Campaign.WOL)], SC2Mission.OUTBREAK.area), - SC2Mission.SAFE_HAVEN.mission_name: MissionInfo(SC2Mission.SAFE_HAVEN, [MissionConnection(5, SC2Campaign.WOL)], SC2Mission.SAFE_HAVEN.area, number=7), - SC2Mission.HAVENS_FALL.mission_name: MissionInfo(SC2Mission.HAVENS_FALL, [MissionConnection(5, SC2Campaign.WOL)], SC2Mission.HAVENS_FALL.area, number=7), - SC2Mission.SMASH_AND_GRAB.mission_name: MissionInfo(SC2Mission.SMASH_AND_GRAB, [MissionConnection(3, SC2Campaign.WOL)], SC2Mission.SMASH_AND_GRAB.area, completion_critical=True), - SC2Mission.THE_DIG.mission_name: MissionInfo(SC2Mission.THE_DIG, [MissionConnection(8, SC2Campaign.WOL)], SC2Mission.THE_DIG.area, number=8, completion_critical=True), - SC2Mission.THE_MOEBIUS_FACTOR.mission_name: MissionInfo(SC2Mission.THE_MOEBIUS_FACTOR, [MissionConnection(9, SC2Campaign.WOL)], SC2Mission.THE_MOEBIUS_FACTOR.area, number=11, completion_critical=True), - SC2Mission.SUPERNOVA.mission_name: MissionInfo(SC2Mission.SUPERNOVA, [MissionConnection(10, SC2Campaign.WOL)], SC2Mission.SUPERNOVA.area, number=14, completion_critical=True), - SC2Mission.MAW_OF_THE_VOID.mission_name: MissionInfo(SC2Mission.MAW_OF_THE_VOID, [MissionConnection(11, SC2Campaign.WOL)], SC2Mission.MAW_OF_THE_VOID.area, completion_critical=True), - SC2Mission.DEVILS_PLAYGROUND.mission_name: MissionInfo(SC2Mission.DEVILS_PLAYGROUND, [MissionConnection(3, SC2Campaign.WOL)], SC2Mission.DEVILS_PLAYGROUND.area, number=4), - SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name: MissionInfo(SC2Mission.WELCOME_TO_THE_JUNGLE, [MissionConnection(13, SC2Campaign.WOL)], SC2Mission.WELCOME_TO_THE_JUNGLE.area), - SC2Mission.BREAKOUT.mission_name: MissionInfo(SC2Mission.BREAKOUT, [MissionConnection(14, SC2Campaign.WOL)], SC2Mission.BREAKOUT.area, number=8), - SC2Mission.GHOST_OF_A_CHANCE.mission_name: MissionInfo(SC2Mission.GHOST_OF_A_CHANCE, [MissionConnection(14, SC2Campaign.WOL)], SC2Mission.GHOST_OF_A_CHANCE.area, number=8), - SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name: MissionInfo(SC2Mission.THE_GREAT_TRAIN_ROBBERY, [MissionConnection(3, SC2Campaign.WOL)], SC2Mission.THE_GREAT_TRAIN_ROBBERY.area, number=6), - SC2Mission.CUTTHROAT.mission_name: MissionInfo(SC2Mission.CUTTHROAT, [MissionConnection(17, SC2Campaign.WOL)], SC2Mission.THE_GREAT_TRAIN_ROBBERY.area), - SC2Mission.ENGINE_OF_DESTRUCTION.mission_name: MissionInfo(SC2Mission.ENGINE_OF_DESTRUCTION, [MissionConnection(18, SC2Campaign.WOL)], SC2Mission.ENGINE_OF_DESTRUCTION.area), - SC2Mission.MEDIA_BLITZ.mission_name: MissionInfo(SC2Mission.MEDIA_BLITZ, [MissionConnection(19, SC2Campaign.WOL)], SC2Mission.MEDIA_BLITZ.area), - SC2Mission.PIERCING_OF_THE_SHROUD.mission_name: MissionInfo(SC2Mission.PIERCING_OF_THE_SHROUD, [MissionConnection(20, SC2Campaign.WOL)], SC2Mission.PIERCING_OF_THE_SHROUD.area), - SC2Mission.GATES_OF_HELL.mission_name: MissionInfo(SC2Mission.GATES_OF_HELL, [MissionConnection(12, SC2Campaign.WOL)], SC2Mission.GATES_OF_HELL.area, completion_critical=True), - SC2Mission.BELLY_OF_THE_BEAST.mission_name: MissionInfo(SC2Mission.BELLY_OF_THE_BEAST, [MissionConnection(22, SC2Campaign.WOL)], SC2Mission.BELLY_OF_THE_BEAST.area, completion_critical=True), - SC2Mission.SHATTER_THE_SKY.mission_name: MissionInfo(SC2Mission.SHATTER_THE_SKY, [MissionConnection(22, SC2Campaign.WOL)], SC2Mission.SHATTER_THE_SKY.area, completion_critical=True), - SC2Mission.ALL_IN.mission_name: MissionInfo(SC2Mission.ALL_IN, [MissionConnection(23, SC2Campaign.WOL), MissionConnection(24, SC2Campaign.WOL)], SC2Mission.ALL_IN.area, or_requirements=True, completion_critical=True) - }, - SC2Campaign.PROPHECY: { - SC2Mission.WHISPERS_OF_DOOM.mission_name: MissionInfo(SC2Mission.WHISPERS_OF_DOOM, [MissionConnection(9, SC2Campaign.WOL)], SC2Mission.WHISPERS_OF_DOOM.area), - SC2Mission.A_SINISTER_TURN.mission_name: MissionInfo(SC2Mission.A_SINISTER_TURN, [MissionConnection(1, SC2Campaign.PROPHECY)], SC2Mission.A_SINISTER_TURN.area), - SC2Mission.ECHOES_OF_THE_FUTURE.mission_name: MissionInfo(SC2Mission.ECHOES_OF_THE_FUTURE, [MissionConnection(2, SC2Campaign.PROPHECY)], SC2Mission.ECHOES_OF_THE_FUTURE.area), - SC2Mission.IN_UTTER_DARKNESS.mission_name: MissionInfo(SC2Mission.IN_UTTER_DARKNESS, [MissionConnection(3, SC2Campaign.PROPHECY)], SC2Mission.IN_UTTER_DARKNESS.area) - }, - SC2Campaign.HOTS: { - SC2Mission.LAB_RAT.mission_name: MissionInfo(SC2Mission.LAB_RAT, [], SC2Mission.LAB_RAT.area, completion_critical=True), - SC2Mission.BACK_IN_THE_SADDLE.mission_name: MissionInfo(SC2Mission.BACK_IN_THE_SADDLE, [MissionConnection(1, SC2Campaign.HOTS)], SC2Mission.BACK_IN_THE_SADDLE.area, completion_critical=True), - SC2Mission.RENDEZVOUS.mission_name: MissionInfo(SC2Mission.RENDEZVOUS, [MissionConnection(2, SC2Campaign.HOTS)], SC2Mission.RENDEZVOUS.area, completion_critical=True), - SC2Mission.HARVEST_OF_SCREAMS.mission_name: MissionInfo(SC2Mission.HARVEST_OF_SCREAMS, [MissionConnection(3, SC2Campaign.HOTS)], SC2Mission.HARVEST_OF_SCREAMS.area), - SC2Mission.SHOOT_THE_MESSENGER.mission_name: MissionInfo(SC2Mission.SHOOT_THE_MESSENGER, [MissionConnection(4, SC2Campaign.HOTS)], SC2Mission.SHOOT_THE_MESSENGER.area), - SC2Mission.ENEMY_WITHIN.mission_name: MissionInfo(SC2Mission.ENEMY_WITHIN, [MissionConnection(5, SC2Campaign.HOTS)], SC2Mission.ENEMY_WITHIN.area), - SC2Mission.DOMINATION.mission_name: MissionInfo(SC2Mission.DOMINATION, [MissionConnection(3, SC2Campaign.HOTS)], SC2Mission.DOMINATION.area), - SC2Mission.FIRE_IN_THE_SKY.mission_name: MissionInfo(SC2Mission.FIRE_IN_THE_SKY, [MissionConnection(7, SC2Campaign.HOTS)], SC2Mission.FIRE_IN_THE_SKY.area), - SC2Mission.OLD_SOLDIERS.mission_name: MissionInfo(SC2Mission.OLD_SOLDIERS, [MissionConnection(8, SC2Campaign.HOTS)], SC2Mission.OLD_SOLDIERS.area), - SC2Mission.WAKING_THE_ANCIENT.mission_name: MissionInfo(SC2Mission.WAKING_THE_ANCIENT, [MissionConnection(6, SC2Campaign.HOTS), MissionConnection(9, SC2Campaign.HOTS)], SC2Mission.WAKING_THE_ANCIENT.area, completion_critical=True, or_requirements=True), - SC2Mission.THE_CRUCIBLE.mission_name: MissionInfo(SC2Mission.THE_CRUCIBLE, [MissionConnection(10, SC2Campaign.HOTS)], SC2Mission.THE_CRUCIBLE.area, completion_critical=True), - SC2Mission.SUPREME.mission_name: MissionInfo(SC2Mission.SUPREME, [MissionConnection(11, SC2Campaign.HOTS)], SC2Mission.SUPREME.area, completion_critical=True), - SC2Mission.INFESTED.mission_name: MissionInfo(SC2Mission.INFESTED, [MissionConnection(6, SC2Campaign.HOTS), MissionConnection(9, SC2Campaign.HOTS), MissionConnection(12, SC2Campaign.HOTS)], SC2Mission.INFESTED.area), - SC2Mission.HAND_OF_DARKNESS.mission_name: MissionInfo(SC2Mission.HAND_OF_DARKNESS, [MissionConnection(13, SC2Campaign.HOTS)], SC2Mission.HAND_OF_DARKNESS.area), - SC2Mission.PHANTOMS_OF_THE_VOID.mission_name: MissionInfo(SC2Mission.PHANTOMS_OF_THE_VOID, [MissionConnection(14, SC2Campaign.HOTS)], SC2Mission.PHANTOMS_OF_THE_VOID.area), - SC2Mission.WITH_FRIENDS_LIKE_THESE.mission_name: MissionInfo(SC2Mission.WITH_FRIENDS_LIKE_THESE, [MissionConnection(6, SC2Campaign.HOTS), MissionConnection(9, SC2Campaign.HOTS), MissionConnection(12, SC2Campaign.HOTS)], SC2Mission.WITH_FRIENDS_LIKE_THESE.area), - SC2Mission.CONVICTION.mission_name: MissionInfo(SC2Mission.CONVICTION, [MissionConnection(16, SC2Campaign.HOTS)], SC2Mission.CONVICTION.area), - SC2Mission.PLANETFALL.mission_name: MissionInfo(SC2Mission.PLANETFALL, [MissionConnection(15, SC2Campaign.HOTS), MissionConnection(17, SC2Campaign.HOTS)], SC2Mission.PLANETFALL.area, completion_critical=True), - SC2Mission.DEATH_FROM_ABOVE.mission_name: MissionInfo(SC2Mission.DEATH_FROM_ABOVE, [MissionConnection(18, SC2Campaign.HOTS)], SC2Mission.DEATH_FROM_ABOVE.area, completion_critical=True), - SC2Mission.THE_RECKONING.mission_name: MissionInfo(SC2Mission.THE_RECKONING, [MissionConnection(19, SC2Campaign.HOTS)], SC2Mission.THE_RECKONING.area, completion_critical=True), - }, - SC2Campaign.PROLOGUE: { - SC2Mission.DARK_WHISPERS.mission_name: MissionInfo(SC2Mission.DARK_WHISPERS, [], SC2Mission.DARK_WHISPERS.area), - SC2Mission.GHOSTS_IN_THE_FOG.mission_name: MissionInfo(SC2Mission.GHOSTS_IN_THE_FOG, [MissionConnection(1, SC2Campaign.PROLOGUE)], SC2Mission.GHOSTS_IN_THE_FOG.area), - SC2Mission.EVIL_AWOKEN.mission_name: MissionInfo(SC2Mission.EVIL_AWOKEN, [MissionConnection(2, SC2Campaign.PROLOGUE)], SC2Mission.EVIL_AWOKEN.area) - }, - SC2Campaign.LOTV: { - SC2Mission.FOR_AIUR.mission_name: MissionInfo(SC2Mission.FOR_AIUR, [], SC2Mission.FOR_AIUR.area, completion_critical=True), - SC2Mission.THE_GROWING_SHADOW.mission_name: MissionInfo(SC2Mission.THE_GROWING_SHADOW, [MissionConnection(1, SC2Campaign.LOTV)], SC2Mission.THE_GROWING_SHADOW.area, completion_critical=True), - SC2Mission.THE_SPEAR_OF_ADUN.mission_name: MissionInfo(SC2Mission.THE_SPEAR_OF_ADUN, [MissionConnection(2, SC2Campaign.LOTV)], SC2Mission.THE_SPEAR_OF_ADUN.area, completion_critical=True), - SC2Mission.SKY_SHIELD.mission_name: MissionInfo(SC2Mission.SKY_SHIELD, [MissionConnection(3, SC2Campaign.LOTV)], SC2Mission.SKY_SHIELD.area, completion_critical=True), - SC2Mission.BROTHERS_IN_ARMS.mission_name: MissionInfo(SC2Mission.BROTHERS_IN_ARMS, [MissionConnection(4, SC2Campaign.LOTV)], SC2Mission.BROTHERS_IN_ARMS.area, completion_critical=True), - SC2Mission.AMON_S_REACH.mission_name: MissionInfo(SC2Mission.AMON_S_REACH, [MissionConnection(3, SC2Campaign.LOTV)], SC2Mission.AMON_S_REACH.area, completion_critical=True), - SC2Mission.LAST_STAND.mission_name: MissionInfo(SC2Mission.LAST_STAND, [MissionConnection(6, SC2Campaign.LOTV)], SC2Mission.LAST_STAND.area, completion_critical=True), - SC2Mission.FORBIDDEN_WEAPON.mission_name: MissionInfo(SC2Mission.FORBIDDEN_WEAPON, [MissionConnection(5, SC2Campaign.LOTV), MissionConnection(7, SC2Campaign.LOTV)], SC2Mission.FORBIDDEN_WEAPON.area, completion_critical=True, or_requirements=True), - SC2Mission.TEMPLE_OF_UNIFICATION.mission_name: MissionInfo(SC2Mission.TEMPLE_OF_UNIFICATION, [MissionConnection(5, SC2Campaign.LOTV), MissionConnection(7, SC2Campaign.LOTV), MissionConnection(8, SC2Campaign.LOTV)], SC2Mission.TEMPLE_OF_UNIFICATION.area, completion_critical=True), - SC2Mission.THE_INFINITE_CYCLE.mission_name: MissionInfo(SC2Mission.THE_INFINITE_CYCLE, [MissionConnection(9, SC2Campaign.LOTV)], SC2Mission.THE_INFINITE_CYCLE.area, completion_critical=True), - SC2Mission.HARBINGER_OF_OBLIVION.mission_name: MissionInfo(SC2Mission.HARBINGER_OF_OBLIVION, [MissionConnection(10, SC2Campaign.LOTV)], SC2Mission.HARBINGER_OF_OBLIVION.area, completion_critical=True), - SC2Mission.UNSEALING_THE_PAST.mission_name: MissionInfo(SC2Mission.UNSEALING_THE_PAST, [MissionConnection(11, SC2Campaign.LOTV)], SC2Mission.UNSEALING_THE_PAST.area, completion_critical=True), - SC2Mission.PURIFICATION.mission_name: MissionInfo(SC2Mission.PURIFICATION, [MissionConnection(12, SC2Campaign.LOTV)], SC2Mission.PURIFICATION.area, completion_critical=True), - SC2Mission.STEPS_OF_THE_RITE.mission_name: MissionInfo(SC2Mission.STEPS_OF_THE_RITE, [MissionConnection(11, SC2Campaign.LOTV)], SC2Mission.STEPS_OF_THE_RITE.area, completion_critical=True), - SC2Mission.RAK_SHIR.mission_name: MissionInfo(SC2Mission.RAK_SHIR, [MissionConnection(14, SC2Campaign.LOTV)], SC2Mission.RAK_SHIR.area, completion_critical=True), - SC2Mission.TEMPLAR_S_CHARGE.mission_name: MissionInfo(SC2Mission.TEMPLAR_S_CHARGE, [MissionConnection(13, SC2Campaign.LOTV), MissionConnection(15, SC2Campaign.LOTV)], SC2Mission.TEMPLAR_S_CHARGE.area, completion_critical=True, or_requirements=True), - SC2Mission.TEMPLAR_S_RETURN.mission_name: MissionInfo(SC2Mission.TEMPLAR_S_RETURN, [MissionConnection(13, SC2Campaign.LOTV), MissionConnection(15, SC2Campaign.LOTV), MissionConnection(16, SC2Campaign.LOTV)], SC2Mission.TEMPLAR_S_RETURN.area, completion_critical=True), - SC2Mission.THE_HOST.mission_name: MissionInfo(SC2Mission.THE_HOST, [MissionConnection(17, SC2Campaign.LOTV)], SC2Mission.THE_HOST.area, completion_critical=True), - SC2Mission.SALVATION.mission_name: MissionInfo(SC2Mission.SALVATION, [MissionConnection(18, SC2Campaign.LOTV)], SC2Mission.SALVATION.area, completion_critical=True), - }, - SC2Campaign.EPILOGUE: { - SC2Mission.INTO_THE_VOID.mission_name: MissionInfo(SC2Mission.INTO_THE_VOID, [MissionConnection(25, SC2Campaign.WOL), MissionConnection(20, SC2Campaign.HOTS), MissionConnection(19, SC2Campaign.LOTV)], SC2Mission.INTO_THE_VOID.area, completion_critical=True), - SC2Mission.THE_ESSENCE_OF_ETERNITY.mission_name: MissionInfo(SC2Mission.THE_ESSENCE_OF_ETERNITY, [MissionConnection(1, SC2Campaign.EPILOGUE)], SC2Mission.THE_ESSENCE_OF_ETERNITY.area, completion_critical=True), - SC2Mission.AMON_S_FALL.mission_name: MissionInfo(SC2Mission.AMON_S_FALL, [MissionConnection(2, SC2Campaign.EPILOGUE)], SC2Mission.AMON_S_FALL.area, completion_critical=True), - }, - SC2Campaign.NCO: { - SC2Mission.THE_ESCAPE.mission_name: MissionInfo(SC2Mission.THE_ESCAPE, [], SC2Mission.THE_ESCAPE.area, completion_critical=True), - SC2Mission.SUDDEN_STRIKE.mission_name: MissionInfo(SC2Mission.SUDDEN_STRIKE, [MissionConnection(1, SC2Campaign.NCO)], SC2Mission.SUDDEN_STRIKE.area, completion_critical=True), - SC2Mission.ENEMY_INTELLIGENCE.mission_name: MissionInfo(SC2Mission.ENEMY_INTELLIGENCE, [MissionConnection(2, SC2Campaign.NCO)], SC2Mission.ENEMY_INTELLIGENCE.area, completion_critical=True), - SC2Mission.TROUBLE_IN_PARADISE.mission_name: MissionInfo(SC2Mission.TROUBLE_IN_PARADISE, [MissionConnection(3, SC2Campaign.NCO)], SC2Mission.TROUBLE_IN_PARADISE.area, completion_critical=True), - SC2Mission.NIGHT_TERRORS.mission_name: MissionInfo(SC2Mission.NIGHT_TERRORS, [MissionConnection(4, SC2Campaign.NCO)], SC2Mission.NIGHT_TERRORS.area, completion_critical=True), - SC2Mission.FLASHPOINT.mission_name: MissionInfo(SC2Mission.FLASHPOINT, [MissionConnection(5, SC2Campaign.NCO)], SC2Mission.FLASHPOINT.area, completion_critical=True), - SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name: MissionInfo(SC2Mission.IN_THE_ENEMY_S_SHADOW, [MissionConnection(6, SC2Campaign.NCO)], SC2Mission.IN_THE_ENEMY_S_SHADOW.area, completion_critical=True), - SC2Mission.DARK_SKIES.mission_name: MissionInfo(SC2Mission.DARK_SKIES, [MissionConnection(7, SC2Campaign.NCO)], SC2Mission.DARK_SKIES.area, completion_critical=True), - SC2Mission.END_GAME.mission_name: MissionInfo(SC2Mission.END_GAME, [MissionConnection(8, SC2Campaign.NCO)], SC2Mission.END_GAME.area, completion_critical=True), - } -} - -lookup_id_to_mission: Dict[int, SC2Mission] = { - mission.id: mission for mission in SC2Mission -} - -lookup_name_to_mission: Dict[str, SC2Mission] = { - mission.mission_name: mission for mission in SC2Mission -} - -lookup_id_to_campaign: Dict[int, SC2Campaign] = { - campaign.id: campaign for campaign in SC2Campaign -} - - -campaign_mission_table: Dict[SC2Campaign, Set[SC2Mission]] = { - campaign: set() for campaign in SC2Campaign -} -for mission in SC2Mission: - campaign_mission_table[mission.campaign].add(mission) - - -def get_campaign_difficulty(campaign: SC2Campaign, excluded_missions: Iterable[SC2Mission] = ()) -> MissionPools: - """ - - :param campaign: - :param excluded_missions: - :return: Campaign's the most difficult non-excluded mission - """ - excluded_mission_set = set(excluded_missions) - included_missions = campaign_mission_table[campaign].difference(excluded_mission_set) - return max([mission.pool for mission in included_missions]) - - -def get_campaign_goal_priority(campaign: SC2Campaign, excluded_missions: Iterable[SC2Mission] = ()) -> SC2CampaignGoalPriority: - """ - Gets a modified campaign goal priority. - If all the campaign's goal missions are excluded, it's ineligible to have the goal - If the campaign's very hard missions are excluded, the priority is lowered to hard - :param campaign: - :param excluded_missions: - :return: - """ - if excluded_missions is None: - return campaign.goal_priority - else: - goal_missions = set(get_campaign_potential_goal_missions(campaign)) - excluded_mission_set = set(excluded_missions) - remaining_goals = goal_missions.difference(excluded_mission_set) - if remaining_goals == set(): - # All potential goals are excluded, the campaign can't be a goal - return SC2CampaignGoalPriority.NONE - elif campaign.goal_priority == SC2CampaignGoalPriority.VERY_HARD: - # Check if a very hard campaign doesn't get rid of it's last very hard mission - difficulty = get_campaign_difficulty(campaign, excluded_missions) - if difficulty == MissionPools.VERY_HARD: - return SC2CampaignGoalPriority.VERY_HARD - else: - return SC2CampaignGoalPriority.HARD - else: - return campaign.goal_priority - - -class SC2CampaignGoal(NamedTuple): - mission: SC2Mission - location: str - - -campaign_final_mission_locations: Dict[SC2Campaign, SC2CampaignGoal] = { - SC2Campaign.WOL: SC2CampaignGoal(SC2Mission.ALL_IN, "All-In: Victory"), - SC2Campaign.PROPHECY: SC2CampaignGoal(SC2Mission.IN_UTTER_DARKNESS, "In Utter Darkness: Kills"), - SC2Campaign.HOTS: None, - SC2Campaign.PROLOGUE: SC2CampaignGoal(SC2Mission.EVIL_AWOKEN, "Evil Awoken: Victory"), - SC2Campaign.LOTV: SC2CampaignGoal(SC2Mission.SALVATION, "Salvation: Victory"), - SC2Campaign.EPILOGUE: None, - SC2Campaign.NCO: SC2CampaignGoal(SC2Mission.END_GAME, "End Game: Victory"), -} - -campaign_alt_final_mission_locations: Dict[SC2Campaign, Dict[SC2Mission, str]] = { - SC2Campaign.WOL: { - SC2Mission.MAW_OF_THE_VOID: "Maw of the Void: Victory", - SC2Mission.ENGINE_OF_DESTRUCTION: "Engine of Destruction: Victory", - SC2Mission.SUPERNOVA: "Supernova: Victory", - SC2Mission.GATES_OF_HELL: "Gates of Hell: Victory", - SC2Mission.SHATTER_THE_SKY: "Shatter the Sky: Victory" - }, - SC2Campaign.PROPHECY: None, - SC2Campaign.HOTS: { - SC2Mission.THE_RECKONING: "The Reckoning: Victory", - SC2Mission.THE_CRUCIBLE: "The Crucible: Victory", - SC2Mission.HAND_OF_DARKNESS: "Hand of Darkness: Victory", - SC2Mission.PHANTOMS_OF_THE_VOID: "Phantoms of the Void: Victory", - SC2Mission.PLANETFALL: "Planetfall: Victory", - SC2Mission.DEATH_FROM_ABOVE: "Death From Above: Victory" - }, - SC2Campaign.PROLOGUE: { - SC2Mission.GHOSTS_IN_THE_FOG: "Ghosts in the Fog: Victory" - }, - SC2Campaign.LOTV: { - SC2Mission.THE_HOST: "The Host: Victory", - SC2Mission.TEMPLAR_S_CHARGE: "Templar's Charge: Victory" - }, - SC2Campaign.EPILOGUE: { - SC2Mission.AMON_S_FALL: "Amon's Fall: Victory", - SC2Mission.INTO_THE_VOID: "Into the Void: Victory", - SC2Mission.THE_ESSENCE_OF_ETERNITY: "The Essence of Eternity: Victory", - }, - SC2Campaign.NCO: { - SC2Mission.FLASHPOINT: "Flashpoint: Victory", - SC2Mission.DARK_SKIES: "Dark Skies: Victory", - SC2Mission.NIGHT_TERRORS: "Night Terrors: Victory", - SC2Mission.TROUBLE_IN_PARADISE: "Trouble In Paradise: Victory" - } -} - -campaign_race_exceptions: Dict[SC2Mission, SC2Race] = { - SC2Mission.WITH_FRIENDS_LIKE_THESE: SC2Race.TERRAN -} - - -def get_goal_location(mission: SC2Mission) -> Union[str, None]: - """ - - :param mission: - :return: Goal location assigned to the goal mission - """ - campaign = mission.campaign - primary_campaign_goal = campaign_final_mission_locations[campaign] - if primary_campaign_goal is not None: - if primary_campaign_goal.mission == mission: - return primary_campaign_goal.location - - campaign_alt_goals = campaign_alt_final_mission_locations[campaign] - if campaign_alt_goals is not None and mission in campaign_alt_goals: - return campaign_alt_goals.get(mission) - - return mission.mission_name + ": Victory" - - -def get_campaign_potential_goal_missions(campaign: SC2Campaign) -> List[SC2Mission]: - """ - - :param campaign: - :return: All missions that can be the campaign's goal - """ - missions: List[SC2Mission] = list() - primary_goal_mission = campaign_final_mission_locations[campaign] - if primary_goal_mission is not None: - missions.append(primary_goal_mission.mission) - alt_goal_locations = campaign_alt_final_mission_locations[campaign] - if alt_goal_locations is not None: - for mission in alt_goal_locations.keys(): - missions.append(mission) - - return missions - - -def get_no_build_missions() -> List[SC2Mission]: - return [mission for mission in SC2Mission if not mission.build] diff --git a/worlds/sc2/Options.py b/worlds/sc2/Options.py deleted file mode 100644 index 88febb7096ef..000000000000 --- a/worlds/sc2/Options.py +++ /dev/null @@ -1,908 +0,0 @@ -from dataclasses import dataclass, fields, Field -from typing import FrozenSet, Union, Set - -from Options import Choice, Toggle, DefaultOnToggle, ItemSet, OptionSet, Range, PerGameCommonOptions -from .MissionTables import SC2Campaign, SC2Mission, lookup_name_to_mission, MissionPools, get_no_build_missions, \ - campaign_mission_table -from worlds.AutoWorld import World - - -class GameDifficulty(Choice): - """ - The difficulty of the campaign, affects enemy AI, starting units, and game speed. - - For those unfamiliar with the Archipelago randomizer, the recommended settings are one difficulty level - lower than the vanilla game - """ - display_name = "Game Difficulty" - option_casual = 0 - option_normal = 1 - option_hard = 2 - option_brutal = 3 - default = 1 - - -class GameSpeed(Choice): - """Optional setting to override difficulty-based game speed.""" - display_name = "Game Speed" - option_default = 0 - option_slower = 1 - option_slow = 2 - option_normal = 3 - option_fast = 4 - option_faster = 5 - default = option_default - - -class DisableForcedCamera(Toggle): - """ - Prevents the game from moving or locking the camera without the player's consent. - """ - display_name = "Disable Forced Camera Movement" - - -class SkipCutscenes(Toggle): - """ - Skips all cutscenes and prevents dialog from blocking progress. - """ - display_name = "Skip Cutscenes" - - -class AllInMap(Choice): - """Determines what version of All-In (WoL final map) that will be generated for the campaign.""" - display_name = "All In Map" - option_ground = 0 - option_air = 1 - - -class MissionOrder(Choice): - """ - Determines the order the missions are played in. The last three mission orders end in a random mission. - Vanilla (83 total if all campaigns enabled): Keeps the standard mission order and branching from the vanilla Campaigns. - Vanilla Shuffled (83 total if all campaigns enabled): Keeps same branching paths from the vanilla Campaigns but randomizes the order of missions within. - Mini Campaign (47 total if all campaigns enabled): Shorter version of the campaign with randomized missions and optional branches. - Medium Grid (16): A 4x4 grid of random missions. Start at the top-left and forge a path towards bottom-right mission to win. - Mini Grid (9): A 3x3 version of Grid. Complete the bottom-right mission to win. - Blitz (12): 12 random missions that open up very quickly. Complete the bottom-right mission to win. - Gauntlet (7): Linear series of 7 random missions to complete the campaign. - Mini Gauntlet (4): Linear series of 4 random missions to complete the campaign. - Tiny Grid (4): A 2x2 version of Grid. Complete the bottom-right mission to win. - Grid (variable): A grid that will resize to use all non-excluded missions. Corners may be omitted to make the grid more square. Complete the bottom-right mission to win. - """ - display_name = "Mission Order" - option_vanilla = 0 - option_vanilla_shuffled = 1 - option_mini_campaign = 2 - option_medium_grid = 3 - option_mini_grid = 4 - option_blitz = 5 - option_gauntlet = 6 - option_mini_gauntlet = 7 - option_tiny_grid = 8 - option_grid = 9 - - -class MaximumCampaignSize(Range): - """ - Sets an upper bound on how many missions to include when a variable-size mission order is selected. - If a set-size mission order is selected, does nothing. - """ - display_name = "Maximum Campaign Size" - range_start = 1 - range_end = 83 - default = 83 - - -class GridTwoStartPositions(Toggle): - """ - If turned on and 'grid' mission order is selected, removes a mission from the starting - corner sets the adjacent two missions as the starter missions. - """ - display_name = "Start with two unlocked missions on grid" - default = Toggle.option_false - - -class ColorChoice(Choice): - option_white = 0 - option_red = 1 - option_blue = 2 - option_teal = 3 - option_purple = 4 - option_yellow = 5 - option_orange = 6 - option_green = 7 - option_light_pink = 8 - option_violet = 9 - option_light_grey = 10 - option_dark_green = 11 - option_brown = 12 - option_light_green = 13 - option_dark_grey = 14 - option_pink = 15 - option_rainbow = 16 - option_default = 17 - default = option_default - - -class PlayerColorTerranRaynor(ColorChoice): - """Determines in-game team color for playable Raynor's Raiders (Terran) factions.""" - display_name = "Terran Player Color (Raynor)" - - -class PlayerColorProtoss(ColorChoice): - """Determines in-game team color for playable Protoss factions.""" - display_name = "Protoss Player Color" - - -class PlayerColorZerg(ColorChoice): - """Determines in-game team color for playable Zerg factions before Kerrigan becomes Primal Kerrigan.""" - display_name = "Zerg Player Color" - - -class PlayerColorZergPrimal(ColorChoice): - """Determines in-game team color for playable Zerg factions after Kerrigan becomes Primal Kerrigan.""" - display_name = "Zerg Player Color (Primal)" - - -class EnableWolMissions(DefaultOnToggle): - """ - Enables missions from main Wings of Liberty campaign. - """ - display_name = "Enable Wings of Liberty missions" - - -class EnableProphecyMissions(DefaultOnToggle): - """ - Enables missions from Prophecy mini-campaign. - """ - display_name = "Enable Prophecy missions" - - -class EnableHotsMissions(DefaultOnToggle): - """ - Enables missions from Heart of the Swarm campaign. - """ - display_name = "Enable Heart of the Swarm missions" - - -class EnableLotVPrologueMissions(DefaultOnToggle): - """ - Enables missions from Prologue campaign. - """ - display_name = "Enable Prologue (Legacy of the Void) missions" - - -class EnableLotVMissions(DefaultOnToggle): - """ - Enables missions from Legacy of the Void campaign. - """ - display_name = "Enable Legacy of the Void (main campaign) missions" - - -class EnableEpilogueMissions(DefaultOnToggle): - """ - Enables missions from Epilogue campaign. - These missions are considered very hard. - - Enabling Wings of Liberty, Heart of the Swarm and Legacy of the Void is strongly recommended in order to play Epilogue. - Not recommended for short mission orders. - See also: Exclude Very Hard Missions - """ - display_name = "Enable Epilogue missions" - - -class EnableNCOMissions(DefaultOnToggle): - """ - Enables missions from Nova Covert Ops campaign. - - Note: For best gameplay experience it's recommended to also enable Wings of Liberty campaign. - """ - display_name = "Enable Nova Covert Ops missions" - - -class ShuffleCampaigns(DefaultOnToggle): - """ - Shuffles the missions between campaigns if enabled. - Only available for Vanilla Shuffled and Mini Campaign mission order - """ - display_name = "Shuffle Campaigns" - - -class ShuffleNoBuild(DefaultOnToggle): - """ - Determines if the no-build missions are included in the shuffle. - If turned off, the no-build missions will not appear. Has no effect for Vanilla mission order. - """ - display_name = "Shuffle No-Build Missions" - - -class StarterUnit(Choice): - """ - Unlocks a random unit at the start of the game. - - Off: No units are provided, the first unit must be obtained from the randomizer - Balanced: A unit that doesn't give the player too much power early on is given - Any Starter Unit: Any starter unit can be given - """ - display_name = "Starter Unit" - option_off = 0 - option_balanced = 1 - option_any_starter_unit = 2 - - -class RequiredTactics(Choice): - """ - Determines the maximum tactical difficulty of the world (separate from mission difficulty). Higher settings - increase randomness. - - Standard: All missions can be completed with good micro and macro. - Advanced: Completing missions may require relying on starting units and micro-heavy units. - No Logic: Units and upgrades may be placed anywhere. LIKELY TO RENDER THE RUN IMPOSSIBLE ON HARDER DIFFICULTIES! - Locks Grant Story Tech option to true. - """ - display_name = "Required Tactics" - option_standard = 0 - option_advanced = 1 - option_no_logic = 2 - - -class GenericUpgradeMissions(Range): - """Determines the percentage of missions in the mission order that must be completed before - level 1 of all weapon and armor upgrades is unlocked. Level 2 upgrades require double the amount of missions, - and level 3 requires triple the amount. The required amounts are always rounded down. - If set to 0, upgrades are instead added to the item pool and must be found to be used.""" - display_name = "Generic Upgrade Missions" - range_start = 0 - range_end = 100 - default = 0 - - -class GenericUpgradeResearch(Choice): - """Determines how weapon and armor upgrades affect missions once unlocked. - - Vanilla: Upgrades must be researched as normal. - Auto In No-Build: In No-Build missions, upgrades are automatically researched. - In all other missions, upgrades must be researched as normal. - Auto In Build: In No-Build missions, upgrades are unavailable as normal. - In all other missions, upgrades are automatically researched. - Always Auto: Upgrades are automatically researched in all missions.""" - display_name = "Generic Upgrade Research" - option_vanilla = 0 - option_auto_in_no_build = 1 - option_auto_in_build = 2 - option_always_auto = 3 - - -class GenericUpgradeItems(Choice): - """Determines how weapon and armor upgrades are split into items. All options produce 3 levels of each item. - Does nothing if upgrades are unlocked by completed mission counts. - - Individual Items: All weapon and armor upgrades are each an item, - resulting in 18 total upgrade items for Terran and 15 total items for Zerg and Protoss each. - Bundle Weapon And Armor: All types of weapon upgrades are one item per race, - and all types of armor upgrades are one item per race, - resulting in 18 total items. - Bundle Unit Class: Weapon and armor upgrades are merged, - but upgrades are bundled separately for each race: - Infantry, Vehicle, and Starship upgrades for Terran (9 items), - Ground and Flyer upgrades for Zerg (6 items), - Ground and Air upgrades for Protoss (6 items), - resulting in 21 total items. - Bundle All: All weapon and armor upgrades are one item per race, - resulting in 9 total items.""" - display_name = "Generic Upgrade Items" - option_individual_items = 0 - option_bundle_weapon_and_armor = 1 - option_bundle_unit_class = 2 - option_bundle_all = 3 - - -class NovaCovertOpsItems(Toggle): - """ - If turned on, the equipment upgrades from Nova Covert Ops may be present in the world. - - If Nova Covert Ops campaign is enabled, this option is locked to be turned on. - """ - display_name = "Nova Covert Ops Items" - default = Toggle.option_true - - -class BroodWarItems(Toggle): - """If turned on, returning items from StarCraft: Brood War may appear in the world.""" - display_name = "Brood War Items" - default = Toggle.option_true - - -class ExtendedItems(Toggle): - """If turned on, original items that did not appear in Campaign mode may appear in the world.""" - display_name = "Extended Items" - default = Toggle.option_true - - -# Current maximum number of upgrades for a unit -MAX_UPGRADES_OPTION = 12 - - -class EnsureGenericItems(Range): - """ - Specifies a minimum percentage of the generic item pool that will be present for the slot. - The generic item pool is the pool of all generically useful items after all exclusions. - Generically-useful items include: Worker upgrades, Building upgrades, economy upgrades, - Mercenaries, Kerrigan levels and abilities, and Spear of Adun abilities - Increasing this percentage will make units less common. - """ - display_name = "Ensure Generic Items" - range_start = 0 - range_end = 100 - default = 25 - - -class MinNumberOfUpgrades(Range): - """ - Set a minimum to the number of upgrades a unit/structure can have. - Note that most units have 4 or 6 upgrades. - If a unit has fewer upgrades than the minimum, it will have all of its upgrades. - - Doesn't affect shared unit upgrades. - """ - display_name = "Minimum number of upgrades per unit/structure" - range_start = 0 - range_end = MAX_UPGRADES_OPTION - default = 2 - - -class MaxNumberOfUpgrades(Range): - """ - Set a maximum to the number of upgrades a unit/structure can have. -1 is used to define unlimited. - Note that most unit have 4 to 6 upgrades. - - Doesn't affect shared unit upgrades. - """ - display_name = "Maximum number of upgrades per unit/structure" - range_start = -1 - range_end = MAX_UPGRADES_OPTION - default = -1 - - -class KerriganPresence(Choice): - """ - Determines whether Kerrigan is playable outside of missions that require her. - - Vanilla: Kerrigan is playable as normal, appears in the same missions as in vanilla game. - Not Present: Kerrigan is not playable, unless the mission requires her to be present. Other hero units stay playable, - and locations normally requiring Kerrigan can be checked by any unit. - Kerrigan level items, active abilities and passive abilities affecting her will not appear. - In missions where the Kerrigan unit is required, story abilities are given in same way as Grant Story Tech is set to true - Not Present And No Passives: In addition to the above, Kerrigan's passive abilities affecting other units (such as Twin Drones) will not appear. - - Note: Always set to "Not Present" if Heart of the Swarm campaign is disabled. - """ - display_name = "Kerrigan Presence" - option_vanilla = 0 - option_not_present = 1 - option_not_present_and_no_passives = 2 - - -class KerriganLevelsPerMissionCompleted(Range): - """ - Determines how many levels Kerrigan gains when a mission is beaten. - - NOTE: Setting this too low can result in generation failures if The Infinite Cycle or Supreme are in the mission pool. - """ - display_name = "Levels Per Mission Beaten" - range_start = 0 - range_end = 20 - default = 0 - - -class KerriganLevelsPerMissionCompletedCap(Range): - """ - Limits how many total levels Kerrigan can gain from beating missions. This does not affect levels gained from items. - Set to -1 to disable this limit. - - NOTE: The following missions have these level requirements: - Supreme: 35 - The Infinite Cycle: 70 - See Grant Story Levels for more details. - """ - display_name = "Levels Per Mission Beaten Cap" - range_start = -1 - range_end = 140 - default = -1 - - -class KerriganLevelItemSum(Range): - """ - Determines the sum of the level items in the world. This does not affect levels gained from beating missions. - - NOTE: The following missions have these level requirements: - Supreme: 35 - The Infinite Cycle: 70 - See Grant Story Levels for more details. - """ - display_name = "Kerrigan Level Item Sum" - range_start = 0 - range_end = 140 - default = 70 - - -class KerriganLevelItemDistribution(Choice): - """Determines the amount and size of Kerrigan level items. - - Vanilla: Uses the distribution in the vanilla campaign. - This entails 32 individual levels and 6 packs of varying sizes. - This distribution always adds up to 70, ignoring the Level Item Sum setting. - Smooth: Uses a custom, condensed distribution of 10 items between sizes 4 and 10, - intended to fit more levels into settings with little room for filler while keeping some variance in level gains. - This distribution always adds up to 70, ignoring the Level Item Sum setting. - Size 70: Uses items worth 70 levels each. - Size 35: Uses items worth 35 levels each. - Size 14: Uses items worth 14 levels each. - Size 10: Uses items worth 10 levels each. - Size 7: Uses items worth 7 levels each. - Size 5: Uses items worth 5 levels each. - Size 2: Uses items worth 2 level eachs. - Size 1: Uses individual levels. As there are not enough locations in the game for this distribution, - this will result in a greatly reduced total level, and is likely to remove many other items.""" - display_name = "Kerrigan Level Item Distribution" - option_vanilla = 0 - option_smooth = 1 - option_size_70 = 2 - option_size_35 = 3 - option_size_14 = 4 - option_size_10 = 5 - option_size_7 = 6 - option_size_5 = 7 - option_size_2 = 8 - option_size_1 = 9 - default = option_smooth - - -class KerriganTotalLevelCap(Range): - """ - Limits how many total levels Kerrigan can gain from any source. Depending on your other settings, - there may be more levels available in the world, but they will not affect Kerrigan. - Set to -1 to disable this limit. - - NOTE: The following missions have these level requirements: - Supreme: 35 - The Infinite Cycle: 70 - See Grant Story Levels for more details. - """ - display_name = "Total Level Cap" - range_start = -1 - range_end = 140 - default = -1 - - -class StartPrimaryAbilities(Range): - """Number of Primary Abilities (Kerrigan Tier 1, 2, and 4) to start the game with. - If set to 4, a Tier 7 ability is also included.""" - display_name = "Starting Primary Abilities" - range_start = 0 - range_end = 4 - default = 0 - - -class KerriganPrimalStatus(Choice): - """Determines when Kerrigan appears in her Primal Zerg form. - This greatly increases her energy regeneration. - - Vanilla: Kerrigan is human in missions that canonically appear before The Crucible, - and zerg thereafter. - Always Zerg: Kerrigan is always zerg. - Always Human: Kerrigan is always human. - Level 35: Kerrigan is human until reaching level 35, and zerg thereafter. - Half Completion: Kerrigan is human until half of the missions in the world are completed, - and zerg thereafter. - Item: Kerrigan's Primal Form is an item. She is human until it is found, and zerg thereafter.""" - display_name = "Kerrigan Primal Status" - option_vanilla = 0 - option_always_zerg = 1 - option_always_human = 2 - option_level_35 = 3 - option_half_completion = 4 - option_item = 5 - - -class SpearOfAdunPresence(Choice): - """ - Determines in which missions Spear of Adun calldowns will be available. - Affects only abilities used from Spear of Adun top menu. - - Not Present: Spear of Adun calldowns are unavailable. - LotV Protoss: Spear of Adun calldowns are only available in LotV main campaign - Protoss: Spear od Adun calldowns are available in any Protoss mission - Everywhere: Spear od Adun calldowns are available in any mission of any race - """ - display_name = "Spear of Adun Presence" - option_not_present = 0 - option_lotv_protoss = 1 - option_protoss = 2 - option_everywhere = 3 - default = option_lotv_protoss - - # Fix case - @classmethod - def get_option_name(cls, value: int) -> str: - if value == SpearOfAdunPresence.option_lotv_protoss: - return "LotV Protoss" - else: - return super().get_option_name(value) - - -class SpearOfAdunPresentInNoBuild(Toggle): - """ - Determines if Spear of Adun calldowns are available in no-build missions. - - If turned on, Spear of Adun calldown powers are available in missions specified under "Spear of Adun Presence". - If turned off, Spear of Adun calldown powers are unavailable in all no-build missions - """ - display_name = "Spear of Adun Present in No-Build" - - -class SpearOfAdunAutonomouslyCastAbilityPresence(Choice): - """ - Determines availability of Spear of Adun powers, that are autonomously cast. - Affects abilities like Reconstruction Beam or Overwatch - - Not Presents: Autocasts are not available. - LotV Protoss: Spear of Adun autocasts are only available in LotV main campaign - Protoss: Spear od Adun autocasts are available in any Protoss mission - Everywhere: Spear od Adun autocasts are available in any mission of any race - """ - display_name = "Spear of Adun Autonomously Cast Powers Presence" - option_not_present = 0 - option_lotv_protoss = 1 - option_protoss = 2 - option_everywhere = 3 - default = option_lotv_protoss - - # Fix case - @classmethod - def get_option_name(cls, value: int) -> str: - if value == SpearOfAdunPresence.option_lotv_protoss: - return "LotV Protoss" - else: - return super().get_option_name(value) - - -class SpearOfAdunAutonomouslyCastPresentInNoBuild(Toggle): - """ - Determines if Spear of Adun autocasts are available in no-build missions. - - If turned on, Spear of Adun autocasts are available in missions specified under "Spear of Adun Autonomously Cast Powers Presence". - If turned off, Spear of Adun autocasts are unavailable in all no-build missions - """ - display_name = "Spear of Adun Autonomously Cast Powers Present in No-Build" - - -class GrantStoryTech(Toggle): - """ - If set true, grants special tech required for story mission completion for duration of the mission. - Otherwise, you need to find these tech by a normal means as items. - Affects story missions like Back in the Saddle and Supreme - - Locked to true if Required Tactics is set to no logic. - """ - display_name = "Grant Story Tech" - - -class GrantStoryLevels(Choice): - """ - If enabled, grants Kerrigan the required minimum levels for the following missions: - Supreme: 35 - The Infinite Cycle: 70 - The bonus levels only apply during the listed missions, and can exceed the Total Level Cap. - - If disabled, either of these missions is included, and there are not enough levels in the world, generation may fail. - To prevent this, either increase the amount of levels in the world, or enable this option. - - If disabled and Required Tactics is set to no logic, this option is forced to Minimum. - - Disabled: Kerrigan does not get bonus levels for these missions, - instead the levels must be gained from items or beating missions. - Additive: Kerrigan gains bonus levels equal to the mission's required level. - Minimum: Kerrigan is either at her real level, or at the mission's required level, - depending on which is higher. - """ - display_name = "Grant Story Levels" - option_disabled = 0 - option_additive = 1 - option_minimum = 2 - default = option_minimum - - -class TakeOverAIAllies(Toggle): - """ - On maps supporting this feature allows you to take control over an AI Ally. - """ - display_name = "Take Over AI Allies" - - -class LockedItems(ItemSet): - """Guarantees that these items will be unlockable""" - display_name = "Locked Items" - - -class ExcludedItems(ItemSet): - """Guarantees that these items will not be unlockable""" - display_name = "Excluded Items" - - -class ExcludedMissions(OptionSet): - """Guarantees that these missions will not appear in the campaign - Doesn't apply to vanilla mission order. - It may be impossible to build a valid campaign if too many missions are excluded.""" - display_name = "Excluded Missions" - valid_keys = {mission.mission_name for mission in SC2Mission} - - -class ExcludeVeryHardMissions(Choice): - """ - Excludes Very Hard missions outside of Epilogue campaign (All-In, Salvation, and all Epilogue missions are considered Very Hard). - Doesn't apply to "Vanilla" mission order. - - Default: Not excluded for mission orders "Vanilla Shuffled" or "Grid" with Maximum Campaign Size >= 20, - excluded for any other order - Yes: Non-Epilogue Very Hard missions are excluded and won't be generated - No: Non-Epilogue Very Hard missions can appear normally. Not recommended for too short mission orders. - - See also: Excluded Missions, Enable Epilogue Missions, Maximum Campaign Size - """ - display_name = "Exclude Very Hard Missions" - option_default = 0 - option_true = 1 - option_false = 2 - - @classmethod - def get_option_name(cls, value): - return ["Default", "Yes", "No"][int(value)] - - -class LocationInclusion(Choice): - option_enabled = 0 - option_resources = 1 - option_disabled = 2 - - -class VanillaLocations(LocationInclusion): - """ - Enables or disables item rewards for completing vanilla objectives. - Vanilla objectives are bonus objectives from the vanilla game, - along with some additional objectives to balance the missions. - Enable these locations for a balanced experience. - - Enabled: All locations fitting into this do their normal rewards - Resources: Forces these locations to contain Starting Resources - Disabled: Removes item rewards from these locations. - - Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. - See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) - """ - display_name = "Vanilla Locations" - - -class ExtraLocations(LocationInclusion): - """ - Enables or disables item rewards for mission progress and minor objectives. - This includes mandatory mission objectives, - collecting reinforcements and resource pickups, - destroying structures, and overcoming minor challenges. - Enables these locations to add more checks and items to your world. - - Enabled: All locations fitting into this do their normal rewards - Resources: Forces these locations to contain Starting Resources - Disabled: Removes item rewards from these locations. - - Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. - See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) - """ - display_name = "Extra Locations" - - -class ChallengeLocations(LocationInclusion): - """ - Enables or disables item rewards for completing challenge tasks. - Challenges are tasks that are more difficult than completing the mission, and are often based on achievements. - You might be required to visit the same mission later after getting stronger in order to finish these tasks. - Enable these locations to increase the difficulty of completing the multiworld. - - Enabled: All locations fitting into this do their normal rewards - Resources: Forces these locations to contain Starting Resources - Disabled: Removes item rewards from these locations. - - Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. - See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) - """ - display_name = "Challenge Locations" - - -class MasteryLocations(LocationInclusion): - """ - Enables or disables item rewards for overcoming especially difficult challenges. - These challenges are often based on Mastery achievements and Feats of Strength. - Enable these locations to add the most difficult checks to the world. - - Enabled: All locations fitting into this do their normal rewards - Resources: Forces these locations to contain Starting Resources - Disabled: Removes item rewards from these locations. - - Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. - See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) - """ - display_name = "Mastery Locations" - - -class MineralsPerItem(Range): - """ - Configures how many minerals are given per resource item. - """ - display_name = "Minerals Per Item" - range_start = 0 - range_end = 500 - default = 25 - - -class VespenePerItem(Range): - """ - Configures how much vespene gas is given per resource item. - """ - display_name = "Vespene Per Item" - range_start = 0 - range_end = 500 - default = 25 - - -class StartingSupplyPerItem(Range): - """ - Configures how much starting supply per is given per item. - """ - display_name = "Starting Supply Per Item" - range_start = 0 - range_end = 200 - default = 5 - - -@dataclass -class Starcraft2Options(PerGameCommonOptions): - game_difficulty: GameDifficulty - game_speed: GameSpeed - disable_forced_camera: DisableForcedCamera - skip_cutscenes: SkipCutscenes - all_in_map: AllInMap - mission_order: MissionOrder - maximum_campaign_size: MaximumCampaignSize - grid_two_start_positions: GridTwoStartPositions - player_color_terran_raynor: PlayerColorTerranRaynor - player_color_protoss: PlayerColorProtoss - player_color_zerg: PlayerColorZerg - player_color_zerg_primal: PlayerColorZergPrimal - enable_wol_missions: EnableWolMissions - enable_prophecy_missions: EnableProphecyMissions - enable_hots_missions: EnableHotsMissions - enable_lotv_prologue_missions: EnableLotVPrologueMissions - enable_lotv_missions: EnableLotVMissions - enable_epilogue_missions: EnableEpilogueMissions - enable_nco_missions: EnableNCOMissions - shuffle_campaigns: ShuffleCampaigns - shuffle_no_build: ShuffleNoBuild - starter_unit: StarterUnit - required_tactics: RequiredTactics - ensure_generic_items: EnsureGenericItems - min_number_of_upgrades: MinNumberOfUpgrades - max_number_of_upgrades: MaxNumberOfUpgrades - generic_upgrade_missions: GenericUpgradeMissions - generic_upgrade_research: GenericUpgradeResearch - generic_upgrade_items: GenericUpgradeItems - kerrigan_presence: KerriganPresence - kerrigan_levels_per_mission_completed: KerriganLevelsPerMissionCompleted - kerrigan_levels_per_mission_completed_cap: KerriganLevelsPerMissionCompletedCap - kerrigan_level_item_sum: KerriganLevelItemSum - kerrigan_level_item_distribution: KerriganLevelItemDistribution - kerrigan_total_level_cap: KerriganTotalLevelCap - start_primary_abilities: StartPrimaryAbilities - kerrigan_primal_status: KerriganPrimalStatus - spear_of_adun_presence: SpearOfAdunPresence - spear_of_adun_present_in_no_build: SpearOfAdunPresentInNoBuild - spear_of_adun_autonomously_cast_ability_presence: SpearOfAdunAutonomouslyCastAbilityPresence - spear_of_adun_autonomously_cast_present_in_no_build: SpearOfAdunAutonomouslyCastPresentInNoBuild - grant_story_tech: GrantStoryTech - grant_story_levels: GrantStoryLevels - take_over_ai_allies: TakeOverAIAllies - locked_items: LockedItems - excluded_items: ExcludedItems - excluded_missions: ExcludedMissions - exclude_very_hard_missions: ExcludeVeryHardMissions - nco_items: NovaCovertOpsItems - bw_items: BroodWarItems - ext_items: ExtendedItems - vanilla_locations: VanillaLocations - extra_locations: ExtraLocations - challenge_locations: ChallengeLocations - mastery_locations: MasteryLocations - minerals_per_item: MineralsPerItem - vespene_per_item: VespenePerItem - starting_supply_per_item: StartingSupplyPerItem - - -def get_option_value(world: World, name: str) -> Union[int, FrozenSet]: - if world is None: - field: Field = [class_field for class_field in fields(Starcraft2Options) if class_field.name == name][0] - return field.type.default - - player_option = getattr(world.options, name) - - return player_option.value - - -def get_enabled_campaigns(world: World) -> Set[SC2Campaign]: - enabled_campaigns = set() - if get_option_value(world, "enable_wol_missions"): - enabled_campaigns.add(SC2Campaign.WOL) - if get_option_value(world, "enable_prophecy_missions"): - enabled_campaigns.add(SC2Campaign.PROPHECY) - if get_option_value(world, "enable_hots_missions"): - enabled_campaigns.add(SC2Campaign.HOTS) - if get_option_value(world, "enable_lotv_prologue_missions"): - enabled_campaigns.add(SC2Campaign.PROLOGUE) - if get_option_value(world, "enable_lotv_missions"): - enabled_campaigns.add(SC2Campaign.LOTV) - if get_option_value(world, "enable_epilogue_missions"): - enabled_campaigns.add(SC2Campaign.EPILOGUE) - if get_option_value(world, "enable_nco_missions"): - enabled_campaigns.add(SC2Campaign.NCO) - return enabled_campaigns - - -def get_disabled_campaigns(world: World) -> Set[SC2Campaign]: - all_campaigns = set(SC2Campaign) - enabled_campaigns = get_enabled_campaigns(world) - disabled_campaigns = all_campaigns.difference(enabled_campaigns) - disabled_campaigns.remove(SC2Campaign.GLOBAL) - return disabled_campaigns - - -def get_excluded_missions(world: World) -> Set[SC2Mission]: - mission_order_type = get_option_value(world, "mission_order") - excluded_mission_names = get_option_value(world, "excluded_missions") - shuffle_no_build = get_option_value(world, "shuffle_no_build") - disabled_campaigns = get_disabled_campaigns(world) - - excluded_missions: Set[SC2Mission] = set([lookup_name_to_mission[name] for name in excluded_mission_names]) - - # Excluding Very Hard missions depending on options - if (get_option_value(world, "exclude_very_hard_missions") == ExcludeVeryHardMissions.option_true - ) or ( - get_option_value(world, "exclude_very_hard_missions") == ExcludeVeryHardMissions.option_default - and ( - mission_order_type not in [MissionOrder.option_vanilla_shuffled, MissionOrder.option_grid] - or ( - mission_order_type == MissionOrder.option_grid - and get_option_value(world, "maximum_campaign_size") < 20 - ) - ) - ): - excluded_missions = excluded_missions.union( - [mission for mission in SC2Mission if - mission.pool == MissionPools.VERY_HARD and mission.campaign != SC2Campaign.EPILOGUE] - ) - # Omitting No-Build missions if not shuffling no-build - if not shuffle_no_build: - excluded_missions = excluded_missions.union(get_no_build_missions()) - # Omitting missions not in enabled campaigns - for campaign in disabled_campaigns: - excluded_missions = excluded_missions.union(campaign_mission_table[campaign]) - - return excluded_missions - - -campaign_depending_orders = [ - MissionOrder.option_vanilla, - MissionOrder.option_vanilla_shuffled, - MissionOrder.option_mini_campaign -] - -kerrigan_unit_available = [ - KerriganPresence.option_vanilla, -] \ No newline at end of file diff --git a/worlds/sc2/PoolFilter.py b/worlds/sc2/PoolFilter.py deleted file mode 100644 index f5f6faa96d62..000000000000 --- a/worlds/sc2/PoolFilter.py +++ /dev/null @@ -1,661 +0,0 @@ -from typing import Callable, Dict, List, Set, Union, Tuple, Optional -from BaseClasses import Item, Location -from .Items import get_full_item_list, spider_mine_sources, second_pass_placeable_items, progressive_if_nco, \ - progressive_if_ext, spear_of_adun_calldowns, spear_of_adun_castable_passives, nova_equipment -from .MissionTables import mission_orders, MissionInfo, MissionPools, \ - get_campaign_goal_priority, campaign_final_mission_locations, campaign_alt_final_mission_locations, \ - SC2Campaign, SC2Race, SC2CampaignGoalPriority, SC2Mission -from .Options import get_option_value, MissionOrder, \ - get_enabled_campaigns, get_disabled_campaigns, RequiredTactics, kerrigan_unit_available, GrantStoryTech, \ - TakeOverAIAllies, SpearOfAdunPresence, SpearOfAdunAutonomouslyCastAbilityPresence, campaign_depending_orders, \ - ShuffleCampaigns, get_excluded_missions, ShuffleNoBuild, ExtraLocations, GrantStoryLevels -from . import ItemNames -from worlds.AutoWorld import World - -# Items with associated upgrades -UPGRADABLE_ITEMS = {item.parent_item for item in get_full_item_list().values() if item.parent_item} - -BARRACKS_UNITS = { - ItemNames.MARINE, ItemNames.MEDIC, ItemNames.FIREBAT, ItemNames.MARAUDER, - ItemNames.REAPER, ItemNames.GHOST, ItemNames.SPECTRE, ItemNames.HERC, -} -FACTORY_UNITS = { - ItemNames.HELLION, ItemNames.VULTURE, ItemNames.GOLIATH, ItemNames.DIAMONDBACK, - ItemNames.SIEGE_TANK, ItemNames.THOR, ItemNames.PREDATOR, ItemNames.WIDOW_MINE, - ItemNames.CYCLONE, ItemNames.WARHOUND, -} -STARPORT_UNITS = { - ItemNames.MEDIVAC, ItemNames.WRAITH, ItemNames.VIKING, ItemNames.BANSHEE, - ItemNames.BATTLECRUISER, ItemNames.HERCULES, ItemNames.SCIENCE_VESSEL, ItemNames.RAVEN, - ItemNames.LIBERATOR, ItemNames.VALKYRIE, -} - - -def filter_missions(world: World) -> Dict[MissionPools, List[SC2Mission]]: - - """ - Returns a semi-randomly pruned tuple of no-build, easy, medium, and hard mission sets - """ - world: World = world - mission_order_type = get_option_value(world, "mission_order") - shuffle_no_build = get_option_value(world, "shuffle_no_build") - enabled_campaigns = get_enabled_campaigns(world) - grant_story_tech = get_option_value(world, "grant_story_tech") == GrantStoryTech.option_true - grant_story_levels = get_option_value(world, "grant_story_levels") != GrantStoryLevels.option_disabled - extra_locations = get_option_value(world, "extra_locations") - excluded_missions: Set[SC2Mission] = get_excluded_missions(world) - mission_pools: Dict[MissionPools, List[SC2Mission]] = {} - for mission in SC2Mission: - if not mission_pools.get(mission.pool): - mission_pools[mission.pool] = list() - mission_pools[mission.pool].append(mission) - # A bit of safeguard: - for mission_pool in MissionPools: - if not mission_pools.get(mission_pool): - mission_pools[mission_pool] = [] - - if mission_order_type == MissionOrder.option_vanilla: - # Vanilla uses the entire mission pool - goal_priorities: Dict[SC2Campaign, SC2CampaignGoalPriority] = {campaign: get_campaign_goal_priority(campaign) for campaign in enabled_campaigns} - goal_level = max(goal_priorities.values()) - candidate_campaigns: List[SC2Campaign] = [campaign for campaign, goal_priority in goal_priorities.items() if goal_priority == goal_level] - candidate_campaigns.sort(key=lambda it: it.id) - goal_campaign = world.random.choice(candidate_campaigns) - if campaign_final_mission_locations[goal_campaign] is not None: - mission_pools[MissionPools.FINAL] = [campaign_final_mission_locations[goal_campaign].mission] - else: - mission_pools[MissionPools.FINAL] = [list(campaign_alt_final_mission_locations[goal_campaign].keys())[0]] - remove_final_mission_from_other_pools(mission_pools) - return mission_pools - - # Finding the goal map - goal_mission: Optional[SC2Mission] = None - if mission_order_type in campaign_depending_orders: - # Prefer long campaigns over shorter ones and harder missions over easier ones - goal_priorities = {campaign: get_campaign_goal_priority(campaign, excluded_missions) for campaign in enabled_campaigns} - goal_level = max(goal_priorities.values()) - candidate_campaigns: List[SC2Campaign] = [campaign for campaign, goal_priority in goal_priorities.items() if goal_priority == goal_level] - candidate_campaigns.sort(key=lambda it: it.id) - - goal_campaign = world.random.choice(candidate_campaigns) - primary_goal = campaign_final_mission_locations[goal_campaign] - if primary_goal is None or primary_goal.mission in excluded_missions: - # No primary goal or its mission is excluded - candidate_missions = list(campaign_alt_final_mission_locations[goal_campaign].keys()) - candidate_missions = [mission for mission in candidate_missions if mission not in excluded_missions] - if len(candidate_missions) == 0: - raise Exception("There are no valid goal missions. Please exclude fewer missions.") - goal_mission = world.random.choice(candidate_missions) - else: - goal_mission = primary_goal.mission - else: - # Find one of the missions with the hardest difficulty - available_missions: List[SC2Mission] = \ - [mission for mission in SC2Mission - if (mission not in excluded_missions and mission.campaign in enabled_campaigns)] - available_missions.sort(key=lambda it: it.id) - # Loop over pools, from hardest to easiest - for mission_pool in range(MissionPools.VERY_HARD, MissionPools.STARTER - 1, -1): - pool_missions: List[SC2Mission] = [mission for mission in available_missions if mission.pool == mission_pool] - if pool_missions: - goal_mission = world.random.choice(pool_missions) - break - if goal_mission is None: - raise Exception("There are no valid goal missions. Please exclude fewer missions.") - - # Excluding missions - for difficulty, mission_pool in mission_pools.items(): - mission_pools[difficulty] = [mission for mission in mission_pool if mission not in excluded_missions] - mission_pools[MissionPools.FINAL] = [goal_mission] - - # Mission pool changes - adv_tactics = get_option_value(world, "required_tactics") != RequiredTactics.option_standard - - def move_mission(mission: SC2Mission, current_pool, new_pool): - if mission in mission_pools[current_pool]: - mission_pools[current_pool].remove(mission) - mission_pools[new_pool].append(mission) - # WoL - if shuffle_no_build == ShuffleNoBuild.option_false or adv_tactics: - # Replacing No Build missions with Easy missions - # WoL - move_mission(SC2Mission.ZERO_HOUR, MissionPools.EASY, MissionPools.STARTER) - move_mission(SC2Mission.EVACUATION, MissionPools.EASY, MissionPools.STARTER) - move_mission(SC2Mission.DEVILS_PLAYGROUND, MissionPools.EASY, MissionPools.STARTER) - # LotV - move_mission(SC2Mission.THE_GROWING_SHADOW, MissionPools.EASY, MissionPools.STARTER) - move_mission(SC2Mission.THE_SPEAR_OF_ADUN, MissionPools.EASY, MissionPools.STARTER) - if extra_locations == ExtraLocations.option_enabled: - move_mission(SC2Mission.SKY_SHIELD, MissionPools.EASY, MissionPools.STARTER) - # Pushing this to Easy - move_mission(SC2Mission.THE_GREAT_TRAIN_ROBBERY, MissionPools.MEDIUM, MissionPools.EASY) - if shuffle_no_build == ShuffleNoBuild.option_false: - # Pushing Outbreak to Normal, as it cannot be placed as the second mission on Build-Only - move_mission(SC2Mission.OUTBREAK, MissionPools.EASY, MissionPools.MEDIUM) - # Pushing extra Normal missions to Easy - move_mission(SC2Mission.ECHOES_OF_THE_FUTURE, MissionPools.MEDIUM, MissionPools.EASY) - move_mission(SC2Mission.CUTTHROAT, MissionPools.MEDIUM, MissionPools.EASY) - # Additional changes on Advanced Tactics - if adv_tactics: - # WoL - move_mission(SC2Mission.THE_GREAT_TRAIN_ROBBERY, MissionPools.EASY, MissionPools.STARTER) - move_mission(SC2Mission.SMASH_AND_GRAB, MissionPools.EASY, MissionPools.STARTER) - move_mission(SC2Mission.THE_MOEBIUS_FACTOR, MissionPools.MEDIUM, MissionPools.EASY) - move_mission(SC2Mission.WELCOME_TO_THE_JUNGLE, MissionPools.MEDIUM, MissionPools.EASY) - move_mission(SC2Mission.ENGINE_OF_DESTRUCTION, MissionPools.HARD, MissionPools.MEDIUM) - # LotV - move_mission(SC2Mission.AMON_S_REACH, MissionPools.EASY, MissionPools.STARTER) - # Prophecy needs to be adjusted on tiny grid - if enabled_campaigns == {SC2Campaign.PROPHECY} and mission_order_type == MissionOrder.option_tiny_grid: - move_mission(SC2Mission.A_SINISTER_TURN, MissionPools.MEDIUM, MissionPools.EASY) - # Prologue's only valid starter is the goal mission - if enabled_campaigns == {SC2Campaign.PROLOGUE} \ - or mission_order_type in campaign_depending_orders \ - and get_option_value(world, "shuffle_campaigns") == ShuffleCampaigns.option_false: - move_mission(SC2Mission.DARK_WHISPERS, MissionPools.EASY, MissionPools.STARTER) - # HotS - kerriganless = get_option_value(world, "kerrigan_presence") not in kerrigan_unit_available \ - or SC2Campaign.HOTS not in enabled_campaigns - if adv_tactics: - # Medium -> Easy - for mission in (SC2Mission.FIRE_IN_THE_SKY, SC2Mission.WAKING_THE_ANCIENT, SC2Mission.CONVICTION): - move_mission(mission, MissionPools.MEDIUM, MissionPools.EASY) - # Hard -> Medium - move_mission(SC2Mission.PHANTOMS_OF_THE_VOID, MissionPools.HARD, MissionPools.MEDIUM) - if not kerriganless: - # Additional starter mission assuming player starts with minimal anti-air - move_mission(SC2Mission.WAKING_THE_ANCIENT, MissionPools.EASY, MissionPools.STARTER) - if grant_story_tech: - # Additional starter mission if player is granted story tech - move_mission(SC2Mission.ENEMY_WITHIN, MissionPools.EASY, MissionPools.STARTER) - move_mission(SC2Mission.TEMPLAR_S_RETURN, MissionPools.EASY, MissionPools.STARTER) - move_mission(SC2Mission.THE_ESCAPE, MissionPools.MEDIUM, MissionPools.STARTER) - move_mission(SC2Mission.IN_THE_ENEMY_S_SHADOW, MissionPools.MEDIUM, MissionPools.STARTER) - if (grant_story_tech and grant_story_levels) or kerriganless: - # The player has, all the stuff he needs, provided under these settings - move_mission(SC2Mission.SUPREME, MissionPools.MEDIUM, MissionPools.STARTER) - move_mission(SC2Mission.THE_INFINITE_CYCLE, MissionPools.HARD, MissionPools.STARTER) - if get_option_value(world, "take_over_ai_allies") == TakeOverAIAllies.option_true: - move_mission(SC2Mission.HARBINGER_OF_OBLIVION, MissionPools.MEDIUM, MissionPools.STARTER) - if len(mission_pools[MissionPools.STARTER]) < 2 and not kerriganless or adv_tactics: - # Conditionally moving Easy missions to Starter - move_mission(SC2Mission.HARVEST_OF_SCREAMS, MissionPools.EASY, MissionPools.STARTER) - move_mission(SC2Mission.DOMINATION, MissionPools.EASY, MissionPools.STARTER) - if len(mission_pools[MissionPools.STARTER]) < 2: - move_mission(SC2Mission.TEMPLAR_S_RETURN, MissionPools.EASY, MissionPools.STARTER) - if len(mission_pools[MissionPools.STARTER]) + len(mission_pools[MissionPools.EASY]) < 2: - # Flashpoint needs just a few items at start but competent comp at the end - move_mission(SC2Mission.FLASHPOINT, MissionPools.HARD, MissionPools.EASY) - - remove_final_mission_from_other_pools(mission_pools) - return mission_pools - - -def remove_final_mission_from_other_pools(mission_pools: Dict[MissionPools, List[SC2Mission]]): - final_missions = mission_pools[MissionPools.FINAL] - for pool, missions in mission_pools.items(): - if pool == MissionPools.FINAL: - continue - for final_mission in final_missions: - while final_mission in missions: - missions.remove(final_mission) - - -def get_item_upgrades(inventory: List[Item], parent_item: Union[Item, str]) -> List[Item]: - item_name = parent_item.name if isinstance(parent_item, Item) else parent_item - return [ - inv_item for inv_item in inventory - if get_full_item_list()[inv_item.name].parent_item == item_name - ] - - -def get_item_quantity(item: Item, world: World): - if (not get_option_value(world, "nco_items")) \ - and SC2Campaign.NCO in get_disabled_campaigns(world) \ - and item.name in progressive_if_nco: - return 1 - if (not get_option_value(world, "ext_items")) \ - and item.name in progressive_if_ext: - return 1 - return get_full_item_list()[item.name].quantity - - -def copy_item(item: Item): - return Item(item.name, item.classification, item.code, item.player) - - -def num_missions(world: World) -> int: - mission_order_type = get_option_value(world, "mission_order") - if mission_order_type != MissionOrder.option_grid: - mission_order = mission_orders[mission_order_type]() - misssions = [mission for campaign in mission_order for mission in mission_order[campaign]] - return len(misssions) - 1 # Menu - else: - mission_pools = filter_missions(world) - return sum(len(pool) for _, pool in mission_pools.items()) - - -class ValidInventory: - - def has(self, item: str, player: int): - return item in self.logical_inventory - - def has_any(self, items: Set[str], player: int): - return any(item in self.logical_inventory for item in items) - - def has_all(self, items: Set[str], player: int): - return all(item in self.logical_inventory for item in items) - - def has_group(self, item_group: str, player: int, count: int = 1): - return False # Deliberately fails here, as item pooling is not aware about mission layout - - def count_group(self, item_name_group: str, player: int) -> int: - return 0 # For item filtering assume no missions are beaten - - def count(self, item: str, player: int) -> int: - return len([inventory_item for inventory_item in self.logical_inventory if inventory_item == item]) - - def has_units_per_structure(self) -> bool: - return len(BARRACKS_UNITS.intersection(self.logical_inventory)) > self.min_units_per_structure and \ - len(FACTORY_UNITS.intersection(self.logical_inventory)) > self.min_units_per_structure and \ - len(STARPORT_UNITS.intersection(self.logical_inventory)) > self.min_units_per_structure - - def generate_reduced_inventory(self, inventory_size: int, mission_requirements: List[Tuple[str, Callable]]) -> List[Item]: - """Attempts to generate a reduced inventory that can fulfill the mission requirements.""" - inventory: List[Item] = list(self.item_pool) - locked_items: List[Item] = list(self.locked_items) - item_list = get_full_item_list() - self.logical_inventory = [ - item.name for item in inventory + locked_items + self.existing_items - if item_list[item.name].is_important_for_filtering() # Track all Progression items and those with complex rules for filtering - ] - requirements = mission_requirements - parent_items = self.item_children.keys() - parent_lookup = {child: parent for parent, children in self.item_children.items() for child in children} - minimum_upgrades = get_option_value(self.world, "min_number_of_upgrades") - - def attempt_removal(item: Item) -> bool: - inventory.remove(item) - # Only run logic checks when removing logic items - if item.name in self.logical_inventory: - self.logical_inventory.remove(item.name) - if not all(requirement(self) for (_, requirement) in mission_requirements): - # If item cannot be removed, lock or revert - self.logical_inventory.append(item.name) - for _ in range(get_item_quantity(item, self.world)): - locked_items.append(copy_item(item)) - return False - return True - - # Limit the maximum number of upgrades - maxNbUpgrade = get_option_value(self.world, "max_number_of_upgrades") - if maxNbUpgrade != -1: - unit_avail_upgrades = {} - # Needed to take into account locked/existing items - unit_nb_upgrades = {} - for item in inventory: - cItem = item_list[item.name] - if item.name in UPGRADABLE_ITEMS and item.name not in unit_avail_upgrades: - unit_avail_upgrades[item.name] = [] - unit_nb_upgrades[item.name] = 0 - elif cItem.parent_item is not None: - if cItem.parent_item not in unit_avail_upgrades: - unit_avail_upgrades[cItem.parent_item] = [item] - unit_nb_upgrades[cItem.parent_item] = 1 - else: - unit_avail_upgrades[cItem.parent_item].append(item) - unit_nb_upgrades[cItem.parent_item] += 1 - # For those two categories, we count them but dont include them in removal - for item in locked_items + self.existing_items: - cItem = item_list[item.name] - if item.name in UPGRADABLE_ITEMS and item.name not in unit_avail_upgrades: - unit_avail_upgrades[item.name] = [] - unit_nb_upgrades[item.name] = 0 - elif cItem.parent_item is not None: - if cItem.parent_item not in unit_avail_upgrades: - unit_nb_upgrades[cItem.parent_item] = 1 - else: - unit_nb_upgrades[cItem.parent_item] += 1 - # Making sure that the upgrades being removed is random - shuffled_unit_upgrade_list = list(unit_avail_upgrades.keys()) - self.world.random.shuffle(shuffled_unit_upgrade_list) - for unit in shuffled_unit_upgrade_list: - while (unit_nb_upgrades[unit] > maxNbUpgrade) \ - and (len(unit_avail_upgrades[unit]) > 0): - itemCandidate = self.world.random.choice(unit_avail_upgrades[unit]) - success = attempt_removal(itemCandidate) - # Whatever it succeed to remove the iventory or it fails and thus - # lock it, the upgrade is no longer available for removal - unit_avail_upgrades[unit].remove(itemCandidate) - if success: - unit_nb_upgrades[unit] -= 1 - - # Locking minimum upgrades for items that have already been locked/placed when minimum required - if minimum_upgrades > 0: - known_items = self.existing_items + locked_items - known_parents = [item for item in known_items if item in parent_items] - for parent in known_parents: - child_items = self.item_children[parent] - removable_upgrades = [item for item in inventory if item in child_items] - locked_upgrade_count = sum(1 if item in child_items else 0 for item in known_items) - self.world.random.shuffle(removable_upgrades) - while len(removable_upgrades) > 0 and locked_upgrade_count < minimum_upgrades: - item_to_lock = removable_upgrades.pop() - inventory.remove(item_to_lock) - locked_items.append(copy_item(item_to_lock)) - locked_upgrade_count += 1 - - if self.min_units_per_structure > 0 and self.has_units_per_structure(): - requirements.append(("Minimum units per structure", lambda state: state.has_units_per_structure())) - - # Determining if the full-size inventory can complete campaign - failed_locations: List[str] = [location for (location, requirement) in requirements if not requirement(self)] - if len(failed_locations) > 0: - raise Exception(f"Too many items excluded - couldn't satisfy access rules for the following locations:\n{failed_locations}") - - # Optionally locking generic items - generic_items = [item for item in inventory if item.name in second_pass_placeable_items] - reserved_generic_percent = get_option_value(self.world, "ensure_generic_items") / 100 - reserved_generic_amount = int(len(generic_items) * reserved_generic_percent) - removable_generic_items = [] - self.world.random.shuffle(generic_items) - for item in generic_items[:reserved_generic_amount]: - locked_items.append(copy_item(item)) - inventory.remove(item) - if item.name not in self.logical_inventory and item.name not in self.locked_items: - removable_generic_items.append(item) - - # Main cull process - unused_items: List[str] = [] # Reusable items for the second pass - while len(inventory) + len(locked_items) > inventory_size: - if len(inventory) == 0: - # There are more items than locations and all of them are already locked due to YAML or logic. - # First, drop non-logic generic items to free up space - while len(removable_generic_items) > 0 and len(locked_items) > inventory_size: - removed_item = removable_generic_items.pop() - locked_items.remove(removed_item) - # If there still isn't enough space, push locked items into start inventory - self.world.random.shuffle(locked_items) - while len(locked_items) > inventory_size: - item: Item = locked_items.pop() - self.multiworld.push_precollected(item) - break - # Select random item from removable items - item = self.world.random.choice(inventory) - # Do not remove item if it would drop upgrades below minimum - if minimum_upgrades > 0: - parent_item = parent_lookup.get(item, None) - if parent_item: - count = sum(1 if item in self.item_children[parent_item] else 0 for item in inventory + locked_items) - if count <= minimum_upgrades: - if parent_item in inventory: - # Attempt to remove parent instead, if possible - item = parent_item - else: - # Lock remaining upgrades - for item in self.item_children[parent_item]: - if item in inventory: - inventory.remove(item) - locked_items.append(copy_item(item)) - continue - - # Drop child items when removing a parent - if item in parent_items: - items_to_remove = [item for item in self.item_children[item] if item in inventory] - success = attempt_removal(item) - if success: - while len(items_to_remove) > 0: - item_to_remove = items_to_remove.pop() - if item_to_remove not in inventory: - continue - attempt_removal(item_to_remove) - else: - # Unimportant upgrades may be added again in the second pass - if attempt_removal(item): - unused_items.append(item.name) - - pool_items: List[str] = [item.name for item in (inventory + locked_items + self.existing_items)] - unused_items = [ - unused_item for unused_item in unused_items - if item_list[unused_item].parent_item is None - or item_list[unused_item].parent_item in pool_items - ] - - # Removing extra dependencies - # WoL - logical_inventory_set = set(self.logical_inventory) - if not spider_mine_sources & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Spider Mine)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Spider Mine)")] - if not BARRACKS_UNITS & logical_inventory_set: - inventory = [ - item for item in inventory - if not (item.name.startswith(ItemNames.TERRAN_INFANTRY_UPGRADE_PREFIX) - or item.name == ItemNames.ORBITAL_STRIKE)] - unused_items = [ - item_name for item_name in unused_items - if not (item_name.startswith( - ItemNames.TERRAN_INFANTRY_UPGRADE_PREFIX) - or item_name == ItemNames.ORBITAL_STRIKE)] - if not FACTORY_UNITS & logical_inventory_set: - inventory = [item for item in inventory if not item.name.startswith(ItemNames.TERRAN_VEHICLE_UPGRADE_PREFIX)] - unused_items = [item_name for item_name in unused_items if not item_name.startswith(ItemNames.TERRAN_VEHICLE_UPGRADE_PREFIX)] - if not STARPORT_UNITS & logical_inventory_set: - inventory = [item for item in inventory if not item.name.startswith(ItemNames.TERRAN_SHIP_UPGRADE_PREFIX)] - unused_items = [item_name for item_name in unused_items if not item_name.startswith(ItemNames.TERRAN_SHIP_UPGRADE_PREFIX)] - # HotS - # Baneling without sources => remove Baneling and upgrades - if (ItemNames.ZERGLING_BANELING_ASPECT in self.logical_inventory - and ItemNames.ZERGLING not in self.logical_inventory - and ItemNames.KERRIGAN_SPAWN_BANELINGS not in self.logical_inventory - ): - inventory = [item for item in inventory if item.name != ItemNames.ZERGLING_BANELING_ASPECT] - inventory = [item for item in inventory if item_list[item.name].parent_item != ItemNames.ZERGLING_BANELING_ASPECT] - unused_items = [item_name for item_name in unused_items if item_name != ItemNames.ZERGLING_BANELING_ASPECT] - unused_items = [item_name for item_name in unused_items if item_list[item_name].parent_item != ItemNames.ZERGLING_BANELING_ASPECT] - # Spawn Banelings without Zergling => remove Baneling unit, keep upgrades except macro ones - if (ItemNames.ZERGLING_BANELING_ASPECT in self.logical_inventory - and ItemNames.ZERGLING not in self.logical_inventory - and ItemNames.KERRIGAN_SPAWN_BANELINGS in self.logical_inventory - ): - inventory = [item for item in inventory if item.name != ItemNames.ZERGLING_BANELING_ASPECT] - inventory = [item for item in inventory if item.name != ItemNames.BANELING_RAPID_METAMORPH] - unused_items = [item_name for item_name in unused_items if item_name != ItemNames.ZERGLING_BANELING_ASPECT] - unused_items = [item_name for item_name in unused_items if item_name != ItemNames.BANELING_RAPID_METAMORPH] - if not {ItemNames.MUTALISK, ItemNames.CORRUPTOR, ItemNames.SCOURGE} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.startswith(ItemNames.ZERG_FLYER_UPGRADE_PREFIX)] - locked_items = [item for item in locked_items if not item.name.startswith(ItemNames.ZERG_FLYER_UPGRADE_PREFIX)] - unused_items = [item_name for item_name in unused_items if not item_name.startswith(ItemNames.ZERG_FLYER_UPGRADE_PREFIX)] - # T3 items removal rules - remove morph and its upgrades if the basic unit isn't in - if not {ItemNames.MUTALISK, ItemNames.CORRUPTOR} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Mutalisk/Corruptor)")] - inventory = [item for item in inventory if item_list[item.name].parent_item != ItemNames.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT] - inventory = [item for item in inventory if item_list[item.name].parent_item != ItemNames.MUTALISK_CORRUPTOR_DEVOURER_ASPECT] - inventory = [item for item in inventory if item_list[item.name].parent_item != ItemNames.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT] - inventory = [item for item in inventory if item_list[item.name].parent_item != ItemNames.MUTALISK_CORRUPTOR_VIPER_ASPECT] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Mutalisk/Corruptor)")] - unused_items = [item_name for item_name in unused_items if item_list[item_name].parent_item != ItemNames.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT] - unused_items = [item_name for item_name in unused_items if item_list[item_name].parent_item != ItemNames.MUTALISK_CORRUPTOR_DEVOURER_ASPECT] - unused_items = [item_name for item_name in unused_items if item_list[item_name].parent_item != ItemNames.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT] - unused_items = [item_name for item_name in unused_items if item_list[item_name].parent_item != ItemNames.MUTALISK_CORRUPTOR_VIPER_ASPECT] - if ItemNames.ROACH not in logical_inventory_set: - inventory = [item for item in inventory if item.name != ItemNames.ROACH_RAVAGER_ASPECT] - inventory = [item for item in inventory if item_list[item.name].parent_item != ItemNames.ROACH_RAVAGER_ASPECT] - unused_items = [item_name for item_name in unused_items if item_name != ItemNames.ROACH_RAVAGER_ASPECT] - unused_items = [item_name for item_name in unused_items if item_list[item_name].parent_item != ItemNames.ROACH_RAVAGER_ASPECT] - if ItemNames.HYDRALISK not in logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Hydralisk)")] - inventory = [item for item in inventory if item_list[item.name].parent_item != ItemNames.HYDRALISK_LURKER_ASPECT] - inventory = [item for item in inventory if item_list[item.name].parent_item != ItemNames.HYDRALISK_IMPALER_ASPECT] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Hydralisk)")] - unused_items = [item_name for item_name in unused_items if item_list[item_name].parent_item != ItemNames.HYDRALISK_LURKER_ASPECT] - unused_items = [item_name for item_name in unused_items if item_list[item_name].parent_item != ItemNames.HYDRALISK_IMPALER_ASPECT] - # LotV - # Shared unit upgrades between several units - if not {ItemNames.STALKER, ItemNames.INSTIGATOR, ItemNames.SLAYER} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Stalker/Instigator/Slayer)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Stalker/Instigator/Slayer)")] - if not {ItemNames.PHOENIX, ItemNames.MIRAGE} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Phoenix/Mirage)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Phoenix/Mirage)")] - if not {ItemNames.VOID_RAY, ItemNames.DESTROYER} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Void Ray/Destroyer)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Void Ray/Destroyer)")] - if not {ItemNames.IMMORTAL, ItemNames.ANNIHILATOR} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Immortal/Annihilator)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Immortal/Annihilator)")] - if not {ItemNames.DARK_TEMPLAR, ItemNames.AVENGER, ItemNames.BLOOD_HUNTER} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Dark Templar/Avenger/Blood Hunter)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Dark Templar/Avenger/Blood Hunter)")] - if not {ItemNames.HIGH_TEMPLAR, ItemNames.SIGNIFIER, ItemNames.ASCENDANT, ItemNames.DARK_TEMPLAR} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Archon)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Archon)")] - logical_inventory_set.difference_update([item_name for item_name in logical_inventory_set if item_name.endswith("(Archon)")]) - if not {ItemNames.HIGH_TEMPLAR, ItemNames.SIGNIFIER, ItemNames.ARCHON_HIGH_ARCHON} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(High Templar/Signifier)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(High Templar/Signifier)")] - if ItemNames.SUPPLICANT not in logical_inventory_set: - inventory = [item for item in inventory if item.name != ItemNames.ASCENDANT_POWER_OVERWHELMING] - unused_items = [item_name for item_name in unused_items if item_name != ItemNames.ASCENDANT_POWER_OVERWHELMING] - if not {ItemNames.DARK_ARCHON, ItemNames.DARK_TEMPLAR_DARK_ARCHON_MELD} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Dark Archon)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Dark Archon)")] - if not {ItemNames.SENTRY, ItemNames.ENERGIZER, ItemNames.HAVOC} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Sentry/Energizer/Havoc)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Sentry/Energizer/Havoc)")] - if not {ItemNames.SENTRY, ItemNames.ENERGIZER, ItemNames.HAVOC, ItemNames.SHIELD_BATTERY} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Sentry/Energizer/Havoc/Shield Battery)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Sentry/Energizer/Havoc/Shield Battery)")] - if not {ItemNames.ZEALOT, ItemNames.CENTURION, ItemNames.SENTINEL} & logical_inventory_set: - inventory = [item for item in inventory if not item.name.endswith("(Zealot/Sentinel/Centurion)")] - unused_items = [item_name for item_name in unused_items if not item_name.endswith("(Zealot/Sentinel/Centurion)")] - # Static defense upgrades only if static defense present - if not {ItemNames.PHOTON_CANNON, ItemNames.KHAYDARIN_MONOLITH, ItemNames.NEXUS_OVERCHARGE, ItemNames.SHIELD_BATTERY} & logical_inventory_set: - inventory = [item for item in inventory if item.name != ItemNames.ENHANCED_TARGETING] - unused_items = [item_name for item_name in unused_items if item_name != ItemNames.ENHANCED_TARGETING] - if not {ItemNames.PHOTON_CANNON, ItemNames.KHAYDARIN_MONOLITH, ItemNames.NEXUS_OVERCHARGE} & logical_inventory_set: - inventory = [item for item in inventory if item.name != ItemNames.OPTIMIZED_ORDNANCE] - unused_items = [item_name for item_name in unused_items if item_name != ItemNames.OPTIMIZED_ORDNANCE] - - # Cull finished, adding locked items back into inventory - inventory += locked_items - - # Replacing empty space with generically useful items - replacement_items = [item for item in self.item_pool - if (item not in inventory - and item not in self.locked_items - and ( - item.name in second_pass_placeable_items - or item.name in unused_items))] - self.world.random.shuffle(replacement_items) - while len(inventory) < inventory_size and len(replacement_items) > 0: - item = replacement_items.pop() - inventory.append(item) - - return inventory - - def __init__(self, world: World , - item_pool: List[Item], existing_items: List[Item], locked_items: List[Item], - used_races: Set[SC2Race], nova_equipment_used: bool): - self.multiworld = world.multiworld - self.player = world.player - self.world: World = world - self.logical_inventory = list() - self.locked_items = locked_items[:] - self.existing_items = existing_items - soa_presence = get_option_value(world, "spear_of_adun_presence") - soa_autocast_presence = get_option_value(world, "spear_of_adun_autonomously_cast_ability_presence") - # Initial filter of item pool - self.item_pool = [] - item_quantities: dict[str, int] = dict() - # Inventory restrictiveness based on number of missions with checks - mission_count = num_missions(world) - self.min_units_per_structure = int(mission_count / 7) - min_upgrades = 1 if mission_count < 10 else 2 - for item in item_pool: - item_info = get_full_item_list()[item.name] - if item_info.race != SC2Race.ANY and item_info.race not in used_races: - if soa_presence == SpearOfAdunPresence.option_everywhere \ - and item.name in spear_of_adun_calldowns: - # Add SoA powers regardless of used races as it's present everywhere - self.item_pool.append(item) - if soa_autocast_presence == SpearOfAdunAutonomouslyCastAbilityPresence.option_everywhere \ - and item.name in spear_of_adun_castable_passives: - self.item_pool.append(item) - # Drop any item belonging to a race not used in the campaign - continue - if item.name in nova_equipment and not nova_equipment_used: - # Drop Nova equipment if there's no NCO mission generated - continue - if item_info.type == "Upgrade": - # Locking upgrades based on mission duration - if item.name not in item_quantities: - item_quantities[item.name] = 0 - item_quantities[item.name] += 1 - if item_quantities[item.name] <= min_upgrades: - self.locked_items.append(item) - else: - self.item_pool.append(item) - elif item_info.type == "Goal": - self.locked_items.append(item) - else: - self.item_pool.append(item) - self.item_children: Dict[Item, List[Item]] = dict() - for item in self.item_pool + locked_items + existing_items: - if item.name in UPGRADABLE_ITEMS: - self.item_children[item] = get_item_upgrades(self.item_pool, item) - - -def filter_items(world: World, mission_req_table: Dict[SC2Campaign, Dict[str, MissionInfo]], location_cache: List[Location], - item_pool: List[Item], existing_items: List[Item], locked_items: List[Item]) -> List[Item]: - """ - Returns a semi-randomly pruned set of items based on number of available locations. - The returned inventory must be capable of logically accessing every location in the world. - """ - open_locations = [location for location in location_cache if location.item is None] - inventory_size = len(open_locations) - used_races = get_used_races(mission_req_table, world) - nova_equipment_used = is_nova_equipment_used(mission_req_table) - mission_requirements = [(location.name, location.access_rule) for location in location_cache] - valid_inventory = ValidInventory(world, item_pool, existing_items, locked_items, used_races, nova_equipment_used) - - valid_items = valid_inventory.generate_reduced_inventory(inventory_size, mission_requirements) - return valid_items - - -def get_used_races(mission_req_table: Dict[SC2Campaign, Dict[str, MissionInfo]], world: World) -> Set[SC2Race]: - grant_story_tech = get_option_value(world, "grant_story_tech") - take_over_ai_allies = get_option_value(world, "take_over_ai_allies") - kerrigan_presence = get_option_value(world, "kerrigan_presence") in kerrigan_unit_available \ - and SC2Campaign.HOTS in get_enabled_campaigns(world) - missions = missions_in_mission_table(mission_req_table) - - # By missions - races = set([mission.race for mission in missions]) - - # Conditionally logic-less no-builds (They're set to SC2Race.ANY): - if grant_story_tech == GrantStoryTech.option_false: - if SC2Mission.ENEMY_WITHIN in missions: - # Zerg units need to be unlocked - races.add(SC2Race.ZERG) - if kerrigan_presence \ - and not missions.isdisjoint({SC2Mission.BACK_IN_THE_SADDLE, SC2Mission.SUPREME, SC2Mission.CONVICTION, SC2Mission.THE_INFINITE_CYCLE}): - # You need some Kerrigan abilities (they're granted if Kerriganless or story tech granted) - races.add(SC2Race.ZERG) - - # If you take over the AI Ally, you need to have its race stuff - if take_over_ai_allies == TakeOverAIAllies.option_true \ - and not missions.isdisjoint({SC2Mission.THE_RECKONING}): - # Jimmy in The Reckoning - races.add(SC2Race.TERRAN) - - return races - -def is_nova_equipment_used(mission_req_table: Dict[SC2Campaign, Dict[str, MissionInfo]]) -> bool: - missions = missions_in_mission_table(mission_req_table) - return any([mission.campaign == SC2Campaign.NCO for mission in missions]) - - -def missions_in_mission_table(mission_req_table: Dict[SC2Campaign, Dict[str, MissionInfo]]) -> Set[SC2Mission]: - return set([mission.mission for campaign_missions in mission_req_table.values() for mission in - campaign_missions.values()]) diff --git a/worlds/sc2/Regions.py b/worlds/sc2/Regions.py deleted file mode 100644 index 273bc4a5e87c..000000000000 --- a/worlds/sc2/Regions.py +++ /dev/null @@ -1,691 +0,0 @@ -from typing import List, Dict, Tuple, Optional, Callable, NamedTuple, Union -import math - -from BaseClasses import MultiWorld, Region, Entrance, Location, CollectionState -from .Locations import LocationData -from .Options import get_option_value, MissionOrder, get_enabled_campaigns, campaign_depending_orders, \ - GridTwoStartPositions -from .MissionTables import MissionInfo, mission_orders, vanilla_mission_req_table, \ - MissionPools, SC2Campaign, get_goal_location, SC2Mission, MissionConnection -from .PoolFilter import filter_missions -from worlds.AutoWorld import World - - -class SC2MissionSlot(NamedTuple): - campaign: SC2Campaign - slot: Union[MissionPools, SC2Mission, None] - - -def create_regions( - world: World, locations: Tuple[LocationData, ...], location_cache: List[Location] -) -> Tuple[Dict[SC2Campaign, Dict[str, MissionInfo]], int, str]: - """ - Creates region connections by calling the multiworld's `connect()` methods - Returns a 3-tuple containing: - * dict[SC2Campaign, Dict[str, MissionInfo]] mapping a campaign and mission name to its data - * int The number of missions in the world - * str The name of the goal location - """ - mission_order_type: int = get_option_value(world, "mission_order") - - if mission_order_type == MissionOrder.option_vanilla: - return create_vanilla_regions(world, locations, location_cache) - elif mission_order_type == MissionOrder.option_grid: - return create_grid_regions(world, locations, location_cache) - else: - return create_structured_regions(world, locations, location_cache, mission_order_type) - -def create_vanilla_regions( - world: World, - locations: Tuple[LocationData, ...], - location_cache: List[Location], -) -> Tuple[Dict[SC2Campaign, Dict[str, MissionInfo]], int, str]: - locations_per_region = get_locations_per_region(locations) - regions = [create_region(world, locations_per_region, location_cache, "Menu")] - - mission_pools: Dict[MissionPools, List[SC2Mission]] = filter_missions(world) - final_mission = mission_pools[MissionPools.FINAL][0] - - enabled_campaigns = get_enabled_campaigns(world) - names: Dict[str, int] = {} - - # Generating all regions and locations for each enabled campaign - for campaign in sorted(enabled_campaigns): - for region_name in vanilla_mission_req_table[campaign].keys(): - regions.append(create_region(world, locations_per_region, location_cache, region_name)) - world.multiworld.regions += regions - vanilla_mission_reqs = {campaign: missions for campaign, missions in vanilla_mission_req_table.items() if campaign in enabled_campaigns} - - def wol_cleared_missions(state: CollectionState, mission_count: int) -> bool: - return state.has_group("WoL Missions", world.player, mission_count) - - player: int = world.player - if SC2Campaign.WOL in enabled_campaigns: - connect(world, names, 'Menu', 'Liberation Day') - connect(world, names, 'Liberation Day', 'The Outlaws', - lambda state: state.has("Beat Liberation Day", player)) - connect(world, names, 'The Outlaws', 'Zero Hour', - lambda state: state.has("Beat The Outlaws", player)) - connect(world, names, 'Zero Hour', 'Evacuation', - lambda state: state.has("Beat Zero Hour", player)) - connect(world, names, 'Evacuation', 'Outbreak', - lambda state: state.has("Beat Evacuation", player)) - connect(world, names, "Outbreak", "Safe Haven", - lambda state: wol_cleared_missions(state, 7) and state.has("Beat Outbreak", player)) - connect(world, names, "Outbreak", "Haven's Fall", - lambda state: wol_cleared_missions(state, 7) and state.has("Beat Outbreak", player)) - connect(world, names, 'Zero Hour', 'Smash and Grab', - lambda state: state.has("Beat Zero Hour", player)) - connect(world, names, 'Smash and Grab', 'The Dig', - lambda state: wol_cleared_missions(state, 8) and state.has("Beat Smash and Grab", player)) - connect(world, names, 'The Dig', 'The Moebius Factor', - lambda state: wol_cleared_missions(state, 11) and state.has("Beat The Dig", player)) - connect(world, names, 'The Moebius Factor', 'Supernova', - lambda state: wol_cleared_missions(state, 14) and state.has("Beat The Moebius Factor", player)) - connect(world, names, 'Supernova', 'Maw of the Void', - lambda state: state.has("Beat Supernova", player)) - connect(world, names, 'Zero Hour', "Devil's Playground", - lambda state: wol_cleared_missions(state, 4) and state.has("Beat Zero Hour", player)) - connect(world, names, "Devil's Playground", 'Welcome to the Jungle', - lambda state: state.has("Beat Devil's Playground", player)) - connect(world, names, "Welcome to the Jungle", 'Breakout', - lambda state: wol_cleared_missions(state, 8) and state.has("Beat Welcome to the Jungle", player)) - connect(world, names, "Welcome to the Jungle", 'Ghost of a Chance', - lambda state: wol_cleared_missions(state, 8) and state.has("Beat Welcome to the Jungle", player)) - connect(world, names, "Zero Hour", 'The Great Train Robbery', - lambda state: wol_cleared_missions(state, 6) and state.has("Beat Zero Hour", player)) - connect(world, names, 'The Great Train Robbery', 'Cutthroat', - lambda state: state.has("Beat The Great Train Robbery", player)) - connect(world, names, 'Cutthroat', 'Engine of Destruction', - lambda state: state.has("Beat Cutthroat", player)) - connect(world, names, 'Engine of Destruction', 'Media Blitz', - lambda state: state.has("Beat Engine of Destruction", player)) - connect(world, names, 'Media Blitz', 'Piercing the Shroud', - lambda state: state.has("Beat Media Blitz", player)) - connect(world, names, 'Maw of the Void', 'Gates of Hell', - lambda state: state.has("Beat Maw of the Void", player)) - connect(world, names, 'Gates of Hell', 'Belly of the Beast', - lambda state: state.has("Beat Gates of Hell", player)) - connect(world, names, 'Gates of Hell', 'Shatter the Sky', - lambda state: state.has("Beat Gates of Hell", player)) - connect(world, names, 'Gates of Hell', 'All-In', - lambda state: state.has('Beat Gates of Hell', player) and ( - state.has('Beat Shatter the Sky', player) or state.has('Beat Belly of the Beast', player))) - - if SC2Campaign.PROPHECY in enabled_campaigns: - if SC2Campaign.WOL in enabled_campaigns: - connect(world, names, 'The Dig', 'Whispers of Doom', - lambda state: state.has("Beat The Dig", player)), - else: - vanilla_mission_reqs[SC2Campaign.PROPHECY] = vanilla_mission_reqs[SC2Campaign.PROPHECY].copy() - vanilla_mission_reqs[SC2Campaign.PROPHECY][SC2Mission.WHISPERS_OF_DOOM.mission_name] = MissionInfo( - SC2Mission.WHISPERS_OF_DOOM, [], SC2Mission.WHISPERS_OF_DOOM.area) - connect(world, names, 'Menu', 'Whispers of Doom'), - connect(world, names, 'Whispers of Doom', 'A Sinister Turn', - lambda state: state.has("Beat Whispers of Doom", player)) - connect(world, names, 'A Sinister Turn', 'Echoes of the Future', - lambda state: state.has("Beat A Sinister Turn", player)) - connect(world, names, 'Echoes of the Future', 'In Utter Darkness', - lambda state: state.has("Beat Echoes of the Future", player)) - - if SC2Campaign.HOTS in enabled_campaigns: - connect(world, names, 'Menu', 'Lab Rat'), - connect(world, names, 'Lab Rat', 'Back in the Saddle', - lambda state: state.has("Beat Lab Rat", player)), - connect(world, names, 'Back in the Saddle', 'Rendezvous', - lambda state: state.has("Beat Back in the Saddle", player)), - connect(world, names, 'Rendezvous', 'Harvest of Screams', - lambda state: state.has("Beat Rendezvous", player)), - connect(world, names, 'Harvest of Screams', 'Shoot the Messenger', - lambda state: state.has("Beat Harvest of Screams", player)), - connect(world, names, 'Shoot the Messenger', 'Enemy Within', - lambda state: state.has("Beat Shoot the Messenger", player)), - connect(world, names, 'Rendezvous', 'Domination', - lambda state: state.has("Beat Rendezvous", player)), - connect(world, names, 'Domination', 'Fire in the Sky', - lambda state: state.has("Beat Domination", player)), - connect(world, names, 'Fire in the Sky', 'Old Soldiers', - lambda state: state.has("Beat Fire in the Sky", player)), - connect(world, names, 'Old Soldiers', 'Waking the Ancient', - lambda state: state.has("Beat Old Soldiers", player)), - connect(world, names, 'Enemy Within', 'Waking the Ancient', - lambda state: state.has("Beat Enemy Within", player)), - connect(world, names, 'Waking the Ancient', 'The Crucible', - lambda state: state.has("Beat Waking the Ancient", player)), - connect(world, names, 'The Crucible', 'Supreme', - lambda state: state.has("Beat The Crucible", player)), - connect(world, names, 'Supreme', 'Infested', - lambda state: state.has("Beat Supreme", player) and - state.has("Beat Old Soldiers", player) and - state.has("Beat Enemy Within", player)), - connect(world, names, 'Infested', 'Hand of Darkness', - lambda state: state.has("Beat Infested", player)), - connect(world, names, 'Hand of Darkness', 'Phantoms of the Void', - lambda state: state.has("Beat Hand of Darkness", player)), - connect(world, names, 'Supreme', 'With Friends Like These', - lambda state: state.has("Beat Supreme", player) and - state.has("Beat Old Soldiers", player) and - state.has("Beat Enemy Within", player)), - connect(world, names, 'With Friends Like These', 'Conviction', - lambda state: state.has("Beat With Friends Like These", player)), - connect(world, names, 'Conviction', 'Planetfall', - lambda state: state.has("Beat Conviction", player) and - state.has("Beat Phantoms of the Void", player)), - connect(world, names, 'Planetfall', 'Death From Above', - lambda state: state.has("Beat Planetfall", player)), - connect(world, names, 'Death From Above', 'The Reckoning', - lambda state: state.has("Beat Death From Above", player)), - - if SC2Campaign.PROLOGUE in enabled_campaigns: - connect(world, names, "Menu", "Dark Whispers") - connect(world, names, "Dark Whispers", "Ghosts in the Fog", - lambda state: state.has("Beat Dark Whispers", player)) - connect(world, names, "Ghosts in the Fog", "Evil Awoken", - lambda state: state.has("Beat Ghosts in the Fog", player)) - - if SC2Campaign.LOTV in enabled_campaigns: - connect(world, names, "Menu", "For Aiur!") - connect(world, names, "For Aiur!", "The Growing Shadow", - lambda state: state.has("Beat For Aiur!", player)), - connect(world, names, "The Growing Shadow", "The Spear of Adun", - lambda state: state.has("Beat The Growing Shadow", player)), - connect(world, names, "The Spear of Adun", "Sky Shield", - lambda state: state.has("Beat The Spear of Adun", player)), - connect(world, names, "Sky Shield", "Brothers in Arms", - lambda state: state.has("Beat Sky Shield", player)), - connect(world, names, "Brothers in Arms", "Forbidden Weapon", - lambda state: state.has("Beat Brothers in Arms", player)), - connect(world, names, "The Spear of Adun", "Amon's Reach", - lambda state: state.has("Beat The Spear of Adun", player)), - connect(world, names, "Amon's Reach", "Last Stand", - lambda state: state.has("Beat Amon's Reach", player)), - connect(world, names, "Last Stand", "Forbidden Weapon", - lambda state: state.has("Beat Last Stand", player)), - connect(world, names, "Forbidden Weapon", "Temple of Unification", - lambda state: state.has("Beat Brothers in Arms", player) - and state.has("Beat Last Stand", player) - and state.has("Beat Forbidden Weapon", player)), - connect(world, names, "Temple of Unification", "The Infinite Cycle", - lambda state: state.has("Beat Temple of Unification", player)), - connect(world, names, "The Infinite Cycle", "Harbinger of Oblivion", - lambda state: state.has("Beat The Infinite Cycle", player)), - connect(world, names, "Harbinger of Oblivion", "Unsealing the Past", - lambda state: state.has("Beat Harbinger of Oblivion", player)), - connect(world, names, "Unsealing the Past", "Purification", - lambda state: state.has("Beat Unsealing the Past", player)), - connect(world, names, "Purification", "Templar's Charge", - lambda state: state.has("Beat Purification", player)), - connect(world, names, "Harbinger of Oblivion", "Steps of the Rite", - lambda state: state.has("Beat Harbinger of Oblivion", player)), - connect(world, names, "Steps of the Rite", "Rak'Shir", - lambda state: state.has("Beat Steps of the Rite", player)), - connect(world, names, "Rak'Shir", "Templar's Charge", - lambda state: state.has("Beat Rak'Shir", player)), - connect(world, names, "Templar's Charge", "Templar's Return", - lambda state: state.has("Beat Purification", player) - and state.has("Beat Rak'Shir", player) - and state.has("Beat Templar's Charge", player)), - connect(world, names, "Templar's Return", "The Host", - lambda state: state.has("Beat Templar's Return", player)), - connect(world, names, "The Host", "Salvation", - lambda state: state.has("Beat The Host", player)), - - if SC2Campaign.EPILOGUE in enabled_campaigns: - # TODO: Make this aware about excluded campaigns - connect(world, names, "Salvation", "Into the Void", - lambda state: state.has("Beat Salvation", player) - and state.has("Beat The Reckoning", player) - and state.has("Beat All-In", player)), - connect(world, names, "Into the Void", "The Essence of Eternity", - lambda state: state.has("Beat Into the Void", player)), - connect(world, names, "The Essence of Eternity", "Amon's Fall", - lambda state: state.has("Beat The Essence of Eternity", player)), - - if SC2Campaign.NCO in enabled_campaigns: - connect(world, names, "Menu", "The Escape") - connect(world, names, "The Escape", "Sudden Strike", - lambda state: state.has("Beat The Escape", player)) - connect(world, names, "Sudden Strike", "Enemy Intelligence", - lambda state: state.has("Beat Sudden Strike", player)) - connect(world, names, "Enemy Intelligence", "Trouble In Paradise", - lambda state: state.has("Beat Enemy Intelligence", player)) - connect(world, names, "Trouble In Paradise", "Night Terrors", - lambda state: state.has("Beat Trouble In Paradise", player)) - connect(world, names, "Night Terrors", "Flashpoint", - lambda state: state.has("Beat Night Terrors", player)) - connect(world, names, "Flashpoint", "In the Enemy's Shadow", - lambda state: state.has("Beat Flashpoint", player)) - connect(world, names, "In the Enemy's Shadow", "Dark Skies", - lambda state: state.has("Beat In the Enemy's Shadow", player)) - connect(world, names, "Dark Skies", "End Game", - lambda state: state.has("Beat Dark Skies", player)) - - goal_location = get_goal_location(final_mission) - assert goal_location, f"Unable to find a goal location for mission {final_mission}" - setup_final_location(goal_location, location_cache) - - return (vanilla_mission_reqs, final_mission.id, goal_location) - - -def create_grid_regions( - world: World, - locations: Tuple[LocationData, ...], - location_cache: List[Location], -) -> Tuple[Dict[SC2Campaign, Dict[str, MissionInfo]], int, str]: - locations_per_region = get_locations_per_region(locations) - - mission_pools = filter_missions(world) - final_mission = mission_pools[MissionPools.FINAL][0] - - mission_pool = [mission for mission_pool in mission_pools.values() for mission in mission_pool] - - num_missions = min(len(mission_pool), get_option_value(world, "maximum_campaign_size")) - remove_top_left: bool = get_option_value(world, "grid_two_start_positions") == GridTwoStartPositions.option_true - - regions = [create_region(world, locations_per_region, location_cache, "Menu")] - names: Dict[str, int] = {} - missions: Dict[Tuple[int, int], SC2Mission] = {} - - grid_size_x, grid_size_y, num_corners_to_remove = get_grid_dimensions(num_missions + remove_top_left) - # pick missions in order along concentric diagonals - # each diagonal will have the same difficulty - # this keeps long sides from possibly stealing lower-difficulty missions from future columns - num_diagonals = grid_size_x + grid_size_y - 1 - diagonal_difficulty = MissionPools.STARTER - missions_to_add = mission_pools[MissionPools.STARTER] - for diagonal in range(num_diagonals): - if diagonal == num_diagonals - 1: - diagonal_difficulty = MissionPools.FINAL - grid_coords = (grid_size_x-1, grid_size_y-1) - missions[grid_coords] = final_mission - break - if diagonal == 0 and remove_top_left: - continue - diagonal_length = min(diagonal + 1, num_diagonals - diagonal, grid_size_x, grid_size_y) - if len(missions_to_add) < diagonal_length: - raise Exception(f"There are not enough {diagonal_difficulty.name} missions to fill the campaign. Please exclude fewer missions.") - for i in range(diagonal_length): - # (0,0) + (0,1)*diagonal + (1,-1)*i + (1,-1)*max(diagonal - grid_size_y + 1, 0) - grid_coords = (i + max(diagonal - grid_size_y + 1, 0), diagonal - i - max(diagonal - grid_size_y + 1, 0)) - if grid_coords == (grid_size_x - 1, 0) and num_corners_to_remove >= 2: - pass - elif grid_coords == (0, grid_size_y - 1) and num_corners_to_remove >= 1: - pass - else: - mission_index = world.random.randint(0, len(missions_to_add) - 1) - missions[grid_coords] = missions_to_add.pop(mission_index) - - if diagonal_difficulty < MissionPools.VERY_HARD: - diagonal_difficulty = MissionPools(diagonal_difficulty.value + 1) - missions_to_add.extend(mission_pools[diagonal_difficulty]) - - # Generating regions and locations from selected missions - for x in range(grid_size_x): - for y in range(grid_size_y): - if missions.get((x, y)): - regions.append(create_region(world, locations_per_region, location_cache, missions[(x, y)].mission_name)) - world.multiworld.regions += regions - - # This pattern is horrifying, why are we using the dict as an ordered dict??? - slot_map: Dict[Tuple[int, int], int] = {} - for index, coords in enumerate(missions): - slot_map[coords] = index + 1 - - mission_req_table: Dict[str, MissionInfo] = {} - for coords, mission in missions.items(): - prepend_vertical = 0 - if not mission: - continue - connections: List[MissionConnection] = [] - if coords == (0, 0) or (remove_top_left and sum(coords) == 1): - # Connect to the "Menu" starting region - connect(world, names, "Menu", mission.mission_name) - else: - for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)): - connected_coords = (coords[0] + dx, coords[1] + dy) - if connected_coords in missions: - # connections.append(missions[connected_coords]) - connections.append(MissionConnection(slot_map[connected_coords])) - connect(world, names, missions[connected_coords].mission_name, mission.mission_name, - make_grid_connect_rule(missions, connected_coords, world.player), - ) - if coords[1] == 1 and not missions.get((coords[0], 0)): - prepend_vertical = 1 - mission_req_table[mission.mission_name] = MissionInfo( - mission, - connections, - category=f'_{coords[0] + 1}', - or_requirements=True, - ui_vertical_padding=prepend_vertical, - ) - - final_mission_id = final_mission.id - # Changing the completion condition for alternate final missions into an event - final_location = get_goal_location(final_mission) - setup_final_location(final_location, location_cache) - - return {SC2Campaign.GLOBAL: mission_req_table}, final_mission_id, final_location - - -def make_grid_connect_rule( - missions: Dict[Tuple[int, int], SC2Mission], - connected_coords: Tuple[int, int], - player: int -) -> Callable[[CollectionState], bool]: - return lambda state: state.has(f"Beat {missions[connected_coords].mission_name}", player) - - -def create_structured_regions( - world: World, - locations: Tuple[LocationData, ...], - location_cache: List[Location], - mission_order_type: int, -) -> Tuple[Dict[SC2Campaign, Dict[str, MissionInfo]], int, str]: - locations_per_region = get_locations_per_region(locations) - - mission_order = mission_orders[mission_order_type]() - enabled_campaigns = get_enabled_campaigns(world) - shuffle_campaigns = get_option_value(world, "shuffle_campaigns") - - mission_pools: Dict[MissionPools, List[SC2Mission]] = filter_missions(world) - final_mission = mission_pools[MissionPools.FINAL][0] - - regions = [create_region(world, locations_per_region, location_cache, "Menu")] - - names: Dict[str, int] = {} - - mission_slots: List[SC2MissionSlot] = [] - mission_pool = [mission for mission_pool in mission_pools.values() for mission in mission_pool] - - if mission_order_type in campaign_depending_orders: - # Do slot removal per campaign - for campaign in enabled_campaigns: - campaign_mission_pool = [mission for mission in mission_pool if mission.campaign == campaign] - campaign_mission_pool_size = len(campaign_mission_pool) - - removals = len(mission_order[campaign]) - campaign_mission_pool_size - - for mission in mission_order[campaign]: - # Removing extra missions if mission pool is too small - if 0 < mission.removal_priority <= removals: - mission_slots.append(SC2MissionSlot(campaign, None)) - elif mission.type == MissionPools.FINAL: - if campaign == final_mission.campaign: - # Campaign is elected to be goal - mission_slots.append(SC2MissionSlot(campaign, final_mission)) - else: - # Not the goal, find the most difficult mission in the pool and set the difficulty - campaign_difficulty = max(mission.pool for mission in campaign_mission_pool) - mission_slots.append(SC2MissionSlot(campaign, campaign_difficulty)) - else: - mission_slots.append(SC2MissionSlot(campaign, mission.type)) - else: - order = mission_order[SC2Campaign.GLOBAL] - # Determining if missions must be removed - mission_pool_size = sum(len(mission_pool) for mission_pool in mission_pools.values()) - removals = len(order) - mission_pool_size - - # Initial fill out of mission list and marking All-In mission - for mission in order: - # Removing extra missions if mission pool is too small - if 0 < mission.removal_priority <= removals: - mission_slots.append(SC2MissionSlot(SC2Campaign.GLOBAL, None)) - elif mission.type == MissionPools.FINAL: - mission_slots.append(SC2MissionSlot(SC2Campaign.GLOBAL, final_mission)) - else: - mission_slots.append(SC2MissionSlot(SC2Campaign.GLOBAL, mission.type)) - - no_build_slots = [] - easy_slots = [] - medium_slots = [] - hard_slots = [] - very_hard_slots = [] - - # Search through missions to find slots needed to fill - for i in range(len(mission_slots)): - mission_slot = mission_slots[i] - if mission_slot is None: - continue - if isinstance(mission_slot, SC2MissionSlot): - if mission_slot.slot is None: - continue - if mission_slot.slot == MissionPools.STARTER: - no_build_slots.append(i) - elif mission_slot.slot == MissionPools.EASY: - easy_slots.append(i) - elif mission_slot.slot == MissionPools.MEDIUM: - medium_slots.append(i) - elif mission_slot.slot == MissionPools.HARD: - hard_slots.append(i) - elif mission_slot.slot == MissionPools.VERY_HARD: - very_hard_slots.append(i) - - def pick_mission(slot): - if shuffle_campaigns or mission_order_type not in campaign_depending_orders: - # Pick a mission from any campaign - filler = world.random.randint(0, len(missions_to_add) - 1) - mission = missions_to_add.pop(filler) - slot_campaign = mission_slots[slot].campaign - mission_slots[slot] = SC2MissionSlot(slot_campaign, mission) - else: - # Pick a mission from required campaign - slot_campaign = mission_slots[slot].campaign - campaign_mission_candidates = [mission for mission in missions_to_add if mission.campaign == slot_campaign] - mission = world.random.choice(campaign_mission_candidates) - missions_to_add.remove(mission) - mission_slots[slot] = SC2MissionSlot(slot_campaign, mission) - - # Add no_build missions to the pool and fill in no_build slots - missions_to_add: List[SC2Mission] = mission_pools[MissionPools.STARTER] - if len(no_build_slots) > len(missions_to_add): - raise Exception("There are no valid No-Build missions. Please exclude fewer missions.") - for slot in no_build_slots: - pick_mission(slot) - - # Add easy missions into pool and fill in easy slots - missions_to_add = missions_to_add + mission_pools[MissionPools.EASY] - if len(easy_slots) > len(missions_to_add): - raise Exception("There are not enough Easy missions to fill the campaign. Please exclude fewer missions.") - for slot in easy_slots: - pick_mission(slot) - - # Add medium missions into pool and fill in medium slots - missions_to_add = missions_to_add + mission_pools[MissionPools.MEDIUM] - if len(medium_slots) > len(missions_to_add): - raise Exception("There are not enough Easy and Medium missions to fill the campaign. Please exclude fewer missions.") - for slot in medium_slots: - pick_mission(slot) - - # Add hard missions into pool and fill in hard slots - missions_to_add = missions_to_add + mission_pools[MissionPools.HARD] - if len(hard_slots) > len(missions_to_add): - raise Exception("There are not enough missions to fill the campaign. Please exclude fewer missions.") - for slot in hard_slots: - pick_mission(slot) - - # Add very hard missions into pool and fill in very hard slots - missions_to_add = missions_to_add + mission_pools[MissionPools.VERY_HARD] - if len(very_hard_slots) > len(missions_to_add): - raise Exception("There are not enough missions to fill the campaign. Please exclude fewer missions.") - for slot in very_hard_slots: - pick_mission(slot) - - # Generating regions and locations from selected missions - for mission_slot in mission_slots: - if isinstance(mission_slot.slot, SC2Mission): - regions.append(create_region(world, locations_per_region, location_cache, mission_slot.slot.mission_name)) - world.multiworld.regions += regions - - campaigns: List[SC2Campaign] - if mission_order_type in campaign_depending_orders: - campaigns = list(enabled_campaigns) - else: - campaigns = [SC2Campaign.GLOBAL] - - mission_req_table: Dict[SC2Campaign, Dict[str, MissionInfo]] = {} - campaign_mission_slots: Dict[SC2Campaign, List[SC2MissionSlot]] = \ - { - campaign: [mission_slot for mission_slot in mission_slots if campaign == mission_slot.campaign] - for campaign in campaigns - } - - slot_map: Dict[SC2Campaign, List[int]] = dict() - - for campaign in campaigns: - mission_req_table.update({campaign: dict()}) - - # Mapping original mission slots to shifted mission slots when missions are removed - slot_map[campaign] = [] - slot_offset = 0 - for position, mission in enumerate(campaign_mission_slots[campaign]): - slot_map[campaign].append(position - slot_offset + 1) - if mission is None or mission.slot is None: - slot_offset += 1 - - def build_connection_rule(mission_names: List[str], missions_req: int) -> Callable: - player = world.player - if len(mission_names) > 1: - return lambda state: state.has_all({f"Beat {name}" for name in mission_names}, player) \ - and state.has_group("Missions", player, missions_req) - else: - return lambda state: state.has(f"Beat {mission_names[0]}", player) \ - and state.has_group("Missions", player, missions_req) - - for campaign in campaigns: - # Loop through missions to create requirements table and connect regions - for i, mission in enumerate(campaign_mission_slots[campaign]): - if mission is None or mission.slot is None: - continue - connections: List[MissionConnection] = [] - all_connections: List[SC2MissionSlot] = [] - connection: MissionConnection - for connection in mission_order[campaign][i].connect_to: - if connection.connect_to == -1: - continue - # If mission normally connects to an excluded campaign, connect to menu instead - if connection.campaign not in campaign_mission_slots: - connection.connect_to = -1 - continue - while campaign_mission_slots[connection.campaign][connection.connect_to].slot is None: - connection.connect_to -= 1 - all_connections.append(campaign_mission_slots[connection.campaign][connection.connect_to]) - for connection in mission_order[campaign][i].connect_to: - if connection.connect_to == -1: - connect(world, names, "Menu", mission.slot.mission_name) - else: - required_mission = campaign_mission_slots[connection.campaign][connection.connect_to] - if ((required_mission is None or required_mission.slot is None) - and not mission_order[campaign][i].completion_critical): # Drop non-critical null slots - continue - while required_mission is None or required_mission.slot is None: # Substituting null slot with prior slot - connection.connect_to -= 1 - required_mission = campaign_mission_slots[connection.campaign][connection.connect_to] - required_missions = [required_mission] if mission_order[campaign][i].or_requirements else all_connections - if isinstance(required_mission.slot, SC2Mission): - required_mission_name = required_mission.slot.mission_name - required_missions_names = [mission.slot.mission_name for mission in required_missions] - connect(world, names, required_mission_name, mission.slot.mission_name, - build_connection_rule(required_missions_names, mission_order[campaign][i].number)) - connections.append(MissionConnection(slot_map[connection.campaign][connection.connect_to], connection.campaign)) - - mission_req_table[campaign].update({mission.slot.mission_name: MissionInfo( - mission.slot, connections, mission_order[campaign][i].category, - number=mission_order[campaign][i].number, - completion_critical=mission_order[campaign][i].completion_critical, - or_requirements=mission_order[campaign][i].or_requirements)}) - - final_mission_id = final_mission.id - # Changing the completion condition for alternate final missions into an event - final_location = get_goal_location(final_mission) - setup_final_location(final_location, location_cache) - - return mission_req_table, final_mission_id, final_location - - -def setup_final_location(final_location, location_cache): - # Final location should be near the end of the cache - for i in range(len(location_cache) - 1, -1, -1): - if location_cache[i].name == final_location: - location_cache[i].address = None - break - - -def create_location(player: int, location_data: LocationData, region: Region, - location_cache: List[Location]) -> Location: - location = Location(player, location_data.name, location_data.code, region) - location.access_rule = location_data.rule - - location_cache.append(location) - - return location - - -def create_region(world: World, locations_per_region: Dict[str, List[LocationData]], - location_cache: List[Location], name: str) -> Region: - region = Region(name, world.player, world.multiworld) - - if name in locations_per_region: - for location_data in locations_per_region[name]: - location = create_location(world.player, location_data, region, location_cache) - region.locations.append(location) - - return region - - -def connect(world: World, used_names: Dict[str, int], source: str, target: str, - rule: Optional[Callable] = None): - source_region = world.get_region(source) - target_region = world.get_region(target) - - if target not in used_names: - used_names[target] = 1 - name = target - else: - used_names[target] += 1 - name = target + (' ' * used_names[target]) - - connection = Entrance(world.player, name, source_region) - - if rule: - connection.access_rule = rule - - source_region.exits.append(connection) - connection.connect(target_region) - - -def get_locations_per_region(locations: Tuple[LocationData, ...]) -> Dict[str, List[LocationData]]: - per_region: Dict[str, List[LocationData]] = {} - - for location in locations: - per_region.setdefault(location.region, []).append(location) - - return per_region - - -def get_factors(number: int) -> Tuple[int, int]: - """ - Simple factorization into pairs of numbers (x, y) using a sieve method. - Returns the factorization that is most square, i.e. where x + y is minimized. - Factor order is such that x <= y. - """ - assert number > 0 - for divisor in range(math.floor(math.sqrt(number)), 1, -1): - quotient = number // divisor - if quotient * divisor == number: - return divisor, quotient - return 1, number - - -def get_grid_dimensions(size: int) -> Tuple[int, int, int]: - """ - Get the dimensions of a grid mission order from the number of missions, int the format (x, y, error). - * Error will always be 0, 1, or 2, so the missions can be removed from the corners that aren't the start or end. - * Dimensions are chosen such that x <= y, as buttons in the UI are wider than they are tall. - * Dimensions are chosen to be maximally square. That is, x + y + error is minimized. - * If multiple options of the same rating are possible, the one with the larger error is chosen, - as it will appear more square. Compare 3x11 to 5x7-2 for an example of this. - """ - dimension_candidates: List[Tuple[int, int, int]] = [(*get_factors(size + x), x) for x in (2, 1, 0)] - best_dimension = min(dimension_candidates, key=sum) - return best_dimension - diff --git a/worlds/sc2/Rules.py b/worlds/sc2/Rules.py deleted file mode 100644 index 8b9097ea1d78..000000000000 --- a/worlds/sc2/Rules.py +++ /dev/null @@ -1,952 +0,0 @@ -from typing import Set - -from BaseClasses import CollectionState -from .Options import get_option_value, RequiredTactics, kerrigan_unit_available, AllInMap, \ - GrantStoryTech, GrantStoryLevels, TakeOverAIAllies, SpearOfAdunAutonomouslyCastAbilityPresence, \ - get_enabled_campaigns, MissionOrder -from .Items import get_basic_units, defense_ratings, zerg_defense_ratings, kerrigan_actives, air_defense_ratings, \ - kerrigan_levels, get_full_item_list -from .MissionTables import SC2Race, SC2Campaign -from . import ItemNames -from worlds.AutoWorld import World - - -class SC2Logic: - - def lock_any_item(self, state: CollectionState, items: Set[str]) -> bool: - """ - Guarantees that at least one of these items will remain in the world. Doesn't affect placement. - Needed for cases when the dynamic pool filtering could remove all the item prerequisites - :param state: - :param items: - :return: - """ - return self.is_item_placement(state) \ - or state.has_any(items, self.player) - - def is_item_placement(self, state): - """ - Tells if it's item placement or item pool filter - :param state: - :return: True for item placement, False for pool filter - """ - # has_group with count = 0 is always true for item placement and always false for SC2 item filtering - return state.has_group("Missions", self.player, 0) - - # WoL - def terran_common_unit(self, state: CollectionState) -> bool: - return state.has_any(self.basic_terran_units, self.player) - - def terran_early_tech(self, state: CollectionState): - """ - Basic combat unit that can be deployed quickly from mission start - :param state - :return: - """ - return ( - state.has_any({ItemNames.MARINE, ItemNames.FIREBAT, ItemNames.MARAUDER, ItemNames.REAPER, ItemNames.HELLION}, self.player) - or (self.advanced_tactics and state.has_any({ItemNames.GOLIATH, ItemNames.DIAMONDBACK, ItemNames.VIKING, ItemNames.BANSHEE}, self.player)) - ) - - def terran_air(self, state: CollectionState) -> bool: - """ - Air units or drops on advanced tactics - :param state: - :return: - """ - return (state.has_any({ItemNames.VIKING, ItemNames.WRAITH, ItemNames.BANSHEE, ItemNames.BATTLECRUISER}, self.player) or self.advanced_tactics - and state.has_any({ItemNames.HERCULES, ItemNames.MEDIVAC}, self.player) and self.terran_common_unit(state) - ) - - def terran_air_anti_air(self, state: CollectionState) -> bool: - """ - Air-to-air - :param state: - :return: - """ - return ( - state.has(ItemNames.VIKING, self.player) - or state.has_all({ItemNames.WRAITH, ItemNames.WRAITH_ADVANCED_LASER_TECHNOLOGY}, self.player) - or state.has_all({ItemNames.BATTLECRUISER, ItemNames.BATTLECRUISER_ATX_LASER_BATTERY}, self.player) - or self.advanced_tactics and state.has_any({ItemNames.WRAITH, ItemNames.VALKYRIE, ItemNames.BATTLECRUISER}, self.player) - ) - - def terran_competent_ground_to_air(self, state: CollectionState) -> bool: - """ - Ground-to-air - :param state: - :return: - """ - return ( - state.has(ItemNames.GOLIATH, self.player) - or state.has(ItemNames.MARINE, self.player) and self.terran_bio_heal(state) - or self.advanced_tactics and state.has(ItemNames.CYCLONE, self.player) - ) - - def terran_competent_anti_air(self, state: CollectionState) -> bool: - """ - Good AA unit - :param state: - :return: - """ - return ( - self.terran_competent_ground_to_air(state) - or self.terran_air_anti_air(state) - ) - - def welcome_to_the_jungle_requirement(self, state: CollectionState) -> bool: - """ - Welcome to the Jungle requirements - able to deal with Scouts, Void Rays, Zealots and Stalkers - :param state: - :return: - """ - return ( - self.terran_common_unit(state) - and self.terran_competent_ground_to_air(state) - ) or ( - self.advanced_tactics - and state.has_any({ItemNames.MARINE, ItemNames.VULTURE}, self.player) - and self.terran_air_anti_air(state) - ) - - def terran_basic_anti_air(self, state: CollectionState) -> bool: - """ - Basic AA to deal with few air units - :param state: - :return: - """ - return ( - state.has_any({ - ItemNames.MISSILE_TURRET, ItemNames.THOR, ItemNames.WAR_PIGS, ItemNames.SPARTAN_COMPANY, - ItemNames.HELS_ANGELS, ItemNames.BATTLECRUISER, ItemNames.MARINE, ItemNames.WRAITH, - ItemNames.VALKYRIE, ItemNames.CYCLONE, ItemNames.WINGED_NIGHTMARES, ItemNames.BRYNHILDS - }, self.player) - or self.terran_competent_anti_air(state) - or self.advanced_tactics and state.has_any({ItemNames.GHOST, ItemNames.SPECTRE, ItemNames.WIDOW_MINE, ItemNames.LIBERATOR}, self.player) - ) - - def terran_defense_rating(self, state: CollectionState, zerg_enemy: bool, air_enemy: bool = True) -> int: - """ - Ability to handle defensive missions - :param state: - :param zerg_enemy: - :param air_enemy: - :return: - """ - defense_score = sum((defense_ratings[item] for item in defense_ratings if state.has(item, self.player))) - # Manned Bunker - if state.has_any({ItemNames.MARINE, ItemNames.MARAUDER}, self.player) and state.has(ItemNames.BUNKER, self.player): - defense_score += 3 - elif zerg_enemy and state.has(ItemNames.FIREBAT, self.player) and state.has(ItemNames.BUNKER, self.player): - defense_score += 2 - # Siege Tank upgrades - if state.has_all({ItemNames.SIEGE_TANK, ItemNames.SIEGE_TANK_MAELSTROM_ROUNDS}, self.player): - defense_score += 2 - if state.has_all({ItemNames.SIEGE_TANK, ItemNames.SIEGE_TANK_GRADUATING_RANGE}, self.player): - defense_score += 1 - # Widow Mine upgrade - if state.has_all({ItemNames.WIDOW_MINE, ItemNames.WIDOW_MINE_CONCEALMENT}, self.player): - defense_score += 1 - # Viking with splash - if state.has_all({ItemNames.VIKING, ItemNames.VIKING_SHREDDER_ROUNDS}, self.player): - defense_score += 2 - - # General enemy-based rules - if zerg_enemy: - defense_score += sum((zerg_defense_ratings[item] for item in zerg_defense_ratings if state.has(item, self.player))) - if air_enemy: - defense_score += sum((air_defense_ratings[item] for item in air_defense_ratings if state.has(item, self.player))) - if air_enemy and zerg_enemy and state.has(ItemNames.VALKYRIE, self.player): - # Valkyries shred mass Mutas, most common air enemy that's massed in these cases - defense_score += 2 - # Advanced Tactics bumps defense rating requirements down by 2 - if self.advanced_tactics: - defense_score += 2 - return defense_score - - def terran_competent_comp(self, state: CollectionState) -> bool: - """ - Ability to deal with most of hard missions - :param state: - :return: - """ - return ( - ( - (state.has_any({ItemNames.MARINE, ItemNames.MARAUDER}, self.player) and self.terran_bio_heal(state)) - or state.has_any({ItemNames.THOR, ItemNames.BANSHEE, ItemNames.SIEGE_TANK}, self.player) - or state.has_all({ItemNames.LIBERATOR, ItemNames.LIBERATOR_RAID_ARTILLERY}, self.player) - ) - and self.terran_competent_anti_air(state) - ) or ( - state.has(ItemNames.BATTLECRUISER, self.player) and self.terran_common_unit(state) - ) - - def great_train_robbery_train_stopper(self, state: CollectionState) -> bool: - """ - Ability to deal with trains (moving target with a lot of HP) - :param state: - :return: - """ - return ( - state.has_any({ItemNames.SIEGE_TANK, ItemNames.DIAMONDBACK, ItemNames.MARAUDER, ItemNames.CYCLONE, ItemNames.BANSHEE}, self.player) - or self.advanced_tactics - and ( - state.has_all({ItemNames.REAPER, ItemNames.REAPER_G4_CLUSTERBOMB}, self.player) - or state.has_all({ItemNames.SPECTRE, ItemNames.SPECTRE_PSIONIC_LASH}, self.player) - or state.has_any({ItemNames.VULTURE, ItemNames.LIBERATOR}, self.player) - ) - ) - - def terran_can_rescue(self, state) -> bool: - """ - Rescuing in The Moebius Factor - :param state: - :return: - """ - return state.has_any({ItemNames.MEDIVAC, ItemNames.HERCULES, ItemNames.RAVEN, ItemNames.VIKING}, self.player) or self.advanced_tactics - - def terran_beats_protoss_deathball(self, state: CollectionState) -> bool: - """ - Ability to deal with Immortals, Colossi with some air support - :param state: - :return: - """ - return ( - ( - state.has_any({ItemNames.BANSHEE, ItemNames.BATTLECRUISER}, self.player) - or state.has_all({ItemNames.LIBERATOR, ItemNames.LIBERATOR_RAID_ARTILLERY}, self.player) - ) and self.terran_competent_anti_air(state) - or self.terran_competent_comp(state) and self.terran_air_anti_air(state) - ) - - def marine_medic_upgrade(self, state: CollectionState) -> bool: - """ - Infantry upgrade to infantry-only no-build segments - :param state: - :return: - """ - return state.has_any({ - ItemNames.MARINE_COMBAT_SHIELD, ItemNames.MARINE_MAGRAIL_MUNITIONS, ItemNames.MEDIC_STABILIZER_MEDPACKS - }, self.player) \ - or (state.count(ItemNames.MARINE_PROGRESSIVE_STIMPACK, self.player) >= 2 - and state.has_group("Missions", self.player, 1)) - - def terran_survives_rip_field(self, state: CollectionState) -> bool: - """ - Ability to deal with large areas with environment damage - :param state: - :return: - """ - return (state.has(ItemNames.BATTLECRUISER, self.player) - or self.terran_air(state) and self.terran_competent_anti_air(state) and self.terran_sustainable_mech_heal(state)) - - def terran_sustainable_mech_heal(self, state: CollectionState) -> bool: - """ - Can heal mech units without spending resources - :param state: - :return: - """ - return state.has(ItemNames.SCIENCE_VESSEL, self.player) \ - or state.has_all({ItemNames.MEDIC, ItemNames.MEDIC_ADAPTIVE_MEDPACKS}, self.player) \ - or state.count(ItemNames.PROGRESSIVE_REGENERATIVE_BIO_STEEL, self.player) >= 3 \ - or (self.advanced_tactics - and ( - state.has_all({ItemNames.RAVEN, ItemNames.RAVEN_BIO_MECHANICAL_REPAIR_DRONE}, self.player) - or state.count(ItemNames.PROGRESSIVE_REGENERATIVE_BIO_STEEL, self.player) >= 2) - ) - - def terran_bio_heal(self, state: CollectionState) -> bool: - """ - Ability to heal bio units - :param state: - :return: - """ - return state.has_any({ItemNames.MEDIC, ItemNames.MEDIVAC}, self.player) \ - or self.advanced_tactics and state.has_all({ItemNames.RAVEN, ItemNames.RAVEN_BIO_MECHANICAL_REPAIR_DRONE}, self.player) - - def terran_base_trasher(self, state: CollectionState) -> bool: - """ - Can attack heavily defended bases - :param state: - :return: - """ - return state.has(ItemNames.SIEGE_TANK, self.player) \ - or state.has_all({ItemNames.BATTLECRUISER, ItemNames.BATTLECRUISER_ATX_LASER_BATTERY}, self.player) \ - or state.has_all({ItemNames.LIBERATOR, ItemNames.LIBERATOR_RAID_ARTILLERY}, self.player) \ - or (self.advanced_tactics - and ((state.has_all({ItemNames.RAVEN, ItemNames.RAVEN_HUNTER_SEEKER_WEAPON}, self.player) - or self.can_nuke(state)) - and ( - state.has_all({ItemNames.VIKING, ItemNames.VIKING_SHREDDER_ROUNDS}, self.player) - or state.has_all({ItemNames.BANSHEE, ItemNames.BANSHEE_SHOCKWAVE_MISSILE_BATTERY}, self.player)) - ) - ) - - def terran_mobile_detector(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.RAVEN, ItemNames.SCIENCE_VESSEL, ItemNames.PROGRESSIVE_ORBITAL_COMMAND}, self.player) - - def can_nuke(self, state: CollectionState) -> bool: - """ - Ability to launch nukes - :param state: - :return: - """ - return (self.advanced_tactics - and (state.has_any({ItemNames.GHOST, ItemNames.SPECTRE}, self.player) - or state.has_all({ItemNames.THOR, ItemNames.THOR_BUTTON_WITH_A_SKULL_ON_IT}, self.player))) - - def terran_respond_to_colony_infestations(self, state: CollectionState) -> bool: - """ - Can deal quickly with Brood Lords and Mutas in Haven's Fall and being able to progress the mission - :param state: - :return: - """ - return ( - self.terran_common_unit(state) - and self.terran_competent_anti_air(state) - and ( - self.terran_air_anti_air(state) - or state.has_any({ItemNames.BATTLECRUISER, ItemNames.VALKYRIE}, self.player) - ) - and self.terran_defense_rating(state, True) >= 3 - ) - - def engine_of_destruction_requirement(self, state: CollectionState): - return self.marine_medic_upgrade(state) \ - and ( - self.terran_competent_anti_air(state) - and self.terran_common_unit(state) or state.has(ItemNames.WRAITH, self.player) - ) - - def all_in_requirement(self, state: CollectionState): - """ - All-in - :param state: - :return: - """ - beats_kerrigan = state.has_any({ItemNames.MARINE, ItemNames.BANSHEE, ItemNames.GHOST}, self.player) or self.advanced_tactics - if get_option_value(self.world, 'all_in_map') == AllInMap.option_ground: - # Ground - defense_rating = self.terran_defense_rating(state, True, False) - if state.has_any({ItemNames.BATTLECRUISER, ItemNames.BANSHEE}, self.player): - defense_rating += 2 - return defense_rating >= 13 and beats_kerrigan - else: - # Air - defense_rating = self.terran_defense_rating(state, True, True) - return defense_rating >= 9 and beats_kerrigan \ - and state.has_any({ItemNames.VIKING, ItemNames.BATTLECRUISER, ItemNames.VALKYRIE}, self.player) \ - and state.has_any({ItemNames.HIVE_MIND_EMULATOR, ItemNames.PSI_DISRUPTER, ItemNames.MISSILE_TURRET}, self.player) - - # HotS - def zerg_common_unit(self, state: CollectionState) -> bool: - return state.has_any(self.basic_zerg_units, self.player) - - def zerg_competent_anti_air(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.HYDRALISK, ItemNames.MUTALISK, ItemNames.CORRUPTOR, ItemNames.BROOD_QUEEN}, self.player) \ - or state.has_all({ItemNames.SWARM_HOST, ItemNames.SWARM_HOST_PRESSURIZED_GLANDS}, self.player) \ - or state.has_all({ItemNames.SCOURGE, ItemNames.SCOURGE_RESOURCE_EFFICIENCY}, self.player) \ - or (self.advanced_tactics and state.has(ItemNames.INFESTOR, self.player)) - - def zerg_basic_anti_air(self, state: CollectionState) -> bool: - return self.zerg_competent_anti_air(state) or self.kerrigan_unit_available in kerrigan_unit_available or \ - state.has_any({ItemNames.SWARM_QUEEN, ItemNames.SCOURGE}, self.player) or (self.advanced_tactics and state.has(ItemNames.SPORE_CRAWLER, self.player)) - - def morph_brood_lord(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.MUTALISK, ItemNames.CORRUPTOR}, self.player) \ - and state.has(ItemNames.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT, self.player) - - def morph_viper(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.MUTALISK, ItemNames.CORRUPTOR}, self.player) \ - and state.has(ItemNames.MUTALISK_CORRUPTOR_VIPER_ASPECT, self.player) - - def morph_impaler_or_lurker(self, state: CollectionState) -> bool: - return state.has(ItemNames.HYDRALISK, self.player) and state.has_any({ItemNames.HYDRALISK_IMPALER_ASPECT, ItemNames.HYDRALISK_LURKER_ASPECT}, self.player) - - def zerg_competent_comp(self, state: CollectionState) -> bool: - advanced = self.advanced_tactics - core_unit = state.has_any({ItemNames.ROACH, ItemNames.ABERRATION, ItemNames.ZERGLING}, self.player) - support_unit = state.has_any({ItemNames.SWARM_QUEEN, ItemNames.HYDRALISK}, self.player) \ - or self.morph_brood_lord(state) \ - or advanced and (state.has_any({ItemNames.INFESTOR, ItemNames.DEFILER}, self.player) or self.morph_viper(state)) - if core_unit and support_unit: - return True - vespene_unit = state.has_any({ItemNames.ULTRALISK, ItemNames.ABERRATION}, self.player) \ - or advanced and self.morph_viper(state) - return vespene_unit and state.has_any({ItemNames.ZERGLING, ItemNames.SWARM_QUEEN}, self.player) - - def spread_creep(self, state: CollectionState) -> bool: - return self.advanced_tactics or state.has(ItemNames.SWARM_QUEEN, self.player) - - def zerg_competent_defense(self, state: CollectionState) -> bool: - return ( - self.zerg_common_unit(state) - and ( - ( - state.has(ItemNames.SWARM_HOST, self.player) - or self.morph_brood_lord(state) - or self.morph_impaler_or_lurker(state) - ) or ( - self.advanced_tactics - and (self.morph_viper(state) - or state.has(ItemNames.SPINE_CRAWLER, self.player)) - ) - ) - ) - - def basic_kerrigan(self, state: CollectionState) -> bool: - # One active ability that can be used to defeat enemies directly on Standard - if not self.advanced_tactics and \ - not state.has_any({ItemNames.KERRIGAN_KINETIC_BLAST, ItemNames.KERRIGAN_LEAPING_STRIKE, - ItemNames.KERRIGAN_CRUSHING_GRIP, ItemNames.KERRIGAN_PSIONIC_SHIFT, - ItemNames.KERRIGAN_SPAWN_BANELINGS}, self.player): - return False - # Two non-ultimate abilities - count = 0 - for item in (ItemNames.KERRIGAN_KINETIC_BLAST, ItemNames.KERRIGAN_LEAPING_STRIKE, ItemNames.KERRIGAN_HEROIC_FORTITUDE, - ItemNames.KERRIGAN_CHAIN_REACTION, ItemNames.KERRIGAN_CRUSHING_GRIP, ItemNames.KERRIGAN_PSIONIC_SHIFT, - ItemNames.KERRIGAN_SPAWN_BANELINGS, ItemNames.KERRIGAN_INFEST_BROODLINGS, ItemNames.KERRIGAN_FURY): - if state.has(item, self.player): - count += 1 - if count >= 2: - return True - return False - - def two_kerrigan_actives(self, state: CollectionState) -> bool: - count = 0 - for i in range(7): - if state.has_any(kerrigan_actives[i], self.player): - count += 1 - return count >= 2 - - def zerg_pass_vents(self, state: CollectionState) -> bool: - return self.story_tech_granted \ - or state.has_any({ItemNames.ZERGLING, ItemNames.HYDRALISK, ItemNames.ROACH}, self.player) \ - or (self.advanced_tactics and state.has(ItemNames.INFESTOR, self.player)) - - def supreme_requirement(self, state: CollectionState) -> bool: - return self.story_tech_granted \ - or not self.kerrigan_unit_available \ - or ( - state.has_all({ItemNames.KERRIGAN_LEAPING_STRIKE, ItemNames.KERRIGAN_MEND}, self.player) - and self.kerrigan_levels(state, 35) - ) - - def kerrigan_levels(self, state: CollectionState, target: int) -> bool: - if self.story_levels_granted or not self.kerrigan_unit_available: - return True # Levels are granted - if self.kerrigan_levels_per_mission_completed > 0 \ - and self.kerrigan_levels_per_mission_completed_cap > 0 \ - and not self.is_item_placement(state): - # Levels can be granted from mission completion. - # Item pool filtering isn't aware of missions beaten. Assume that missions beaten will fulfill this rule. - return True - # Levels from missions beaten - levels = self.kerrigan_levels_per_mission_completed * state.count_group("Missions", self.player) - if self.kerrigan_levels_per_mission_completed_cap != -1: - levels = min(levels, self.kerrigan_levels_per_mission_completed_cap) - # Levels from items - for kerrigan_level_item in kerrigan_levels: - level_amount = get_full_item_list()[kerrigan_level_item].number - item_count = state.count(kerrigan_level_item, self.player) - levels += item_count * level_amount - # Total level cap - if self.kerrigan_total_level_cap != -1: - levels = min(levels, self.kerrigan_total_level_cap) - - return levels >= target - - - def the_reckoning_requirement(self, state: CollectionState) -> bool: - if self.take_over_ai_allies: - return self.terran_competent_comp(state) \ - and self.zerg_competent_comp(state) \ - and (self.zerg_competent_anti_air(state) - or self.terran_competent_anti_air(state)) - else: - return self.zerg_competent_comp(state) \ - and self.zerg_competent_anti_air(state) - - # LotV - - def protoss_common_unit(self, state: CollectionState) -> bool: - return state.has_any(self.basic_protoss_units, self.player) - - def protoss_basic_anti_air(self, state: CollectionState) -> bool: - return self.protoss_competent_anti_air(state) \ - or state.has_any({ItemNames.PHOENIX, ItemNames.MIRAGE, ItemNames.CORSAIR, ItemNames.CARRIER, ItemNames.SCOUT, - ItemNames.DARK_ARCHON, ItemNames.WRATHWALKER, ItemNames.MOTHERSHIP}, self.player) \ - or state.has_all({ItemNames.WARP_PRISM, ItemNames.WARP_PRISM_PHASE_BLASTER}, self.player) \ - or self.advanced_tactics and state.has_any( - {ItemNames.HIGH_TEMPLAR, ItemNames.SIGNIFIER, ItemNames.ASCENDANT, ItemNames.DARK_TEMPLAR, - ItemNames.SENTRY, ItemNames.ENERGIZER}, self.player) - - def protoss_anti_armor_anti_air(self, state: CollectionState) -> bool: - return self.protoss_competent_anti_air(state) \ - or state.has_any({ItemNames.SCOUT, ItemNames.WRATHWALKER}, self.player) \ - or (state.has_any({ItemNames.IMMORTAL, ItemNames.ANNIHILATOR}, self.player) - and state.has(ItemNames.IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING_MECHANICS, self.player)) - - def protoss_anti_light_anti_air(self, state: CollectionState) -> bool: - return self.protoss_competent_anti_air(state) \ - or state.has_any({ItemNames.PHOENIX, ItemNames.MIRAGE, ItemNames.CORSAIR, ItemNames.CARRIER}, self.player) - - def protoss_competent_anti_air(self, state: CollectionState) -> bool: - return state.has_any( - {ItemNames.STALKER, ItemNames.SLAYER, ItemNames.INSTIGATOR, ItemNames.DRAGOON, ItemNames.ADEPT, - ItemNames.VOID_RAY, ItemNames.DESTROYER, ItemNames.TEMPEST}, self.player) \ - or (state.has_any({ItemNames.PHOENIX, ItemNames.MIRAGE, ItemNames.CORSAIR, ItemNames.CARRIER}, self.player) - and state.has_any({ItemNames.SCOUT, ItemNames.WRATHWALKER}, self.player)) \ - or (self.advanced_tactics - and state.has_any({ItemNames.IMMORTAL, ItemNames.ANNIHILATOR}, self.player) - and state.has(ItemNames.IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING_MECHANICS, self.player)) - - def protoss_has_blink(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.STALKER, ItemNames.INSTIGATOR, ItemNames.SLAYER}, self.player) \ - or ( - state.has(ItemNames.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_BLINK, self.player) - and state.has_any({ItemNames.DARK_TEMPLAR, ItemNames.BLOOD_HUNTER, ItemNames.AVENGER}, self.player) - ) - - def protoss_can_attack_behind_chasm(self, state: CollectionState) -> bool: - return state.has_any( - {ItemNames.SCOUT, ItemNames.TEMPEST, - ItemNames.CARRIER, ItemNames.VOID_RAY, ItemNames.DESTROYER, ItemNames.MOTHERSHIP}, self.player) \ - or self.protoss_has_blink(state) \ - or (state.has(ItemNames.WARP_PRISM, self.player) - and (self.protoss_common_unit(state) or state.has(ItemNames.WARP_PRISM_PHASE_BLASTER, self.player))) \ - or (self.advanced_tactics - and state.has_any({ItemNames.ORACLE, ItemNames.ARBITER}, self.player)) - - def protoss_fleet(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.CARRIER, ItemNames.TEMPEST, ItemNames.VOID_RAY, ItemNames.DESTROYER}, self.player) - - def templars_return_requirement(self, state: CollectionState) -> bool: - return self.story_tech_granted \ - or ( - state.has_any({ItemNames.IMMORTAL, ItemNames.ANNIHILATOR}, self.player) - and state.has_any({ItemNames.COLOSSUS, ItemNames.VANGUARD, ItemNames.REAVER, ItemNames.DARK_TEMPLAR}, self.player) - and state.has_any({ItemNames.SENTRY, ItemNames.HIGH_TEMPLAR}, self.player) - ) - - def brothers_in_arms_requirement(self, state: CollectionState) -> bool: - return ( - self.protoss_common_unit(state) - and self.protoss_anti_armor_anti_air(state) - and self.protoss_hybrid_counter(state) - ) or ( - self.take_over_ai_allies - and ( - self.terran_common_unit(state) - or self.protoss_common_unit(state) - ) - and ( - self.terran_competent_anti_air(state) - or self.protoss_anti_armor_anti_air(state) - ) - and ( - self.protoss_hybrid_counter(state) - or state.has_any({ItemNames.BATTLECRUISER, ItemNames.LIBERATOR, ItemNames.SIEGE_TANK}, self.player) - or state.has_all({ItemNames.SPECTRE, ItemNames.SPECTRE_PSIONIC_LASH}, self.player) - or (state.has(ItemNames.IMMORTAL, self.player) - and state.has_any({ItemNames.MARINE, ItemNames.MARAUDER}, self.player) - and self.terran_bio_heal(state)) - ) - ) - - def protoss_hybrid_counter(self, state: CollectionState) -> bool: - """ - Ground Hybrids - """ - return state.has_any( - {ItemNames.ANNIHILATOR, ItemNames.ASCENDANT, ItemNames.TEMPEST, ItemNames.CARRIER, ItemNames.VOID_RAY, - ItemNames.WRATHWALKER, ItemNames.VANGUARD}, self.player) \ - or (state.has(ItemNames.IMMORTAL, self.player) or self.advanced_tactics) and state.has_any( - {ItemNames.STALKER, ItemNames.DRAGOON, ItemNames.ADEPT, ItemNames.INSTIGATOR, ItemNames.SLAYER}, self.player) - - def the_infinite_cycle_requirement(self, state: CollectionState) -> bool: - return self.story_tech_granted \ - or not self.kerrigan_unit_available \ - or ( - self.two_kerrigan_actives(state) - and self.basic_kerrigan(state) - and self.kerrigan_levels(state, 70) - ) - - def protoss_basic_splash(self, state: CollectionState) -> bool: - return state.has_any( - {ItemNames.ZEALOT, ItemNames.COLOSSUS, ItemNames.VANGUARD, ItemNames.HIGH_TEMPLAR, ItemNames.SIGNIFIER, - ItemNames.DARK_TEMPLAR, ItemNames.REAVER, ItemNames.ASCENDANT}, self.player) - - def protoss_static_defense(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.PHOTON_CANNON, ItemNames.KHAYDARIN_MONOLITH}, self.player) - - def last_stand_requirement(self, state: CollectionState) -> bool: - return self.protoss_common_unit(state) \ - and self.protoss_competent_anti_air(state) \ - and self.protoss_static_defense(state) \ - and ( - self.advanced_tactics - or self.protoss_basic_splash(state) - ) - - def harbinger_of_oblivion_requirement(self, state: CollectionState) -> bool: - return self.protoss_anti_armor_anti_air(state) and ( - self.take_over_ai_allies - or ( - self.protoss_common_unit(state) - and self.protoss_hybrid_counter(state) - ) - ) - - def protoss_competent_comp(self, state: CollectionState) -> bool: - return self.protoss_common_unit(state) \ - and self.protoss_competent_anti_air(state) \ - and self.protoss_hybrid_counter(state) \ - and self.protoss_basic_splash(state) - - def protoss_stalker_upgrade(self, state: CollectionState) -> bool: - return ( - state.has_any( - { - ItemNames.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES, - ItemNames.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION - }, self.player) - and self.lock_any_item(state, {ItemNames.STALKER, ItemNames.INSTIGATOR, ItemNames.SLAYER}) - ) - - def steps_of_the_rite_requirement(self, state: CollectionState) -> bool: - return self.protoss_competent_comp(state) \ - or ( - self.protoss_common_unit(state) - and self.protoss_competent_anti_air(state) - and self.protoss_static_defense(state) - ) - - def protoss_heal(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.CARRIER, ItemNames.SENTRY, ItemNames.SHIELD_BATTERY, ItemNames.RECONSTRUCTION_BEAM}, self.player) - - def templars_charge_requirement(self, state: CollectionState) -> bool: - return self.protoss_heal(state) \ - and self.protoss_anti_armor_anti_air(state) \ - and ( - self.protoss_fleet(state) - or (self.advanced_tactics - and self.protoss_competent_comp(state) - ) - ) - - def the_host_requirement(self, state: CollectionState) -> bool: - return (self.protoss_fleet(state) - and self.protoss_static_defense(state) - ) or ( - self.protoss_competent_comp(state) - and state.has(ItemNames.SOA_TIME_STOP, self.player) - ) - - def salvation_requirement(self, state: CollectionState) -> bool: - return [ - self.protoss_competent_comp(state), - self.protoss_fleet(state), - self.protoss_static_defense(state) - ].count(True) >= 2 - - def into_the_void_requirement(self, state: CollectionState) -> bool: - return self.protoss_competent_comp(state) \ - or ( - self.take_over_ai_allies - and ( - state.has(ItemNames.BATTLECRUISER, self.player) - or ( - state.has(ItemNames.ULTRALISK, self.player) - and self.protoss_competent_anti_air(state) - ) - ) - ) - - def essence_of_eternity_requirement(self, state: CollectionState) -> bool: - defense_score = self.terran_defense_rating(state, False, True) - if self.take_over_ai_allies and self.protoss_static_defense(state): - defense_score += 2 - return defense_score >= 10 \ - and ( - self.terran_competent_anti_air(state) - or self.take_over_ai_allies - and self.protoss_competent_anti_air(state) - ) \ - and ( - state.has(ItemNames.BATTLECRUISER, self.player) - or (state.has(ItemNames.BANSHEE, self.player) and state.has_any({ItemNames.VIKING, ItemNames.VALKYRIE}, - self.player)) - or self.take_over_ai_allies and self.protoss_fleet(state) - ) \ - and state.has_any({ItemNames.SIEGE_TANK, ItemNames.LIBERATOR}, self.player) - - def amons_fall_requirement(self, state: CollectionState) -> bool: - if self.take_over_ai_allies: - return ( - ( - state.has_any({ItemNames.BATTLECRUISER, ItemNames.CARRIER}, self.player) - ) - or (state.has(ItemNames.ULTRALISK, self.player) - and self.protoss_competent_anti_air(state) - and ( - state.has_any({ItemNames.LIBERATOR, ItemNames.BANSHEE, ItemNames.VALKYRIE, ItemNames.VIKING}, self.player) - or state.has_all({ItemNames.WRAITH, ItemNames.WRAITH_ADVANCED_LASER_TECHNOLOGY}, self.player) - or self.protoss_fleet(state) - ) - and (self.terran_sustainable_mech_heal(state) - or (self.spear_of_adun_autonomously_cast_presence == SpearOfAdunAutonomouslyCastAbilityPresence.option_everywhere - and state.has(ItemNames.RECONSTRUCTION_BEAM, self.player)) - ) - ) - ) \ - and self.terran_competent_anti_air(state) \ - and self.protoss_competent_comp(state) \ - and self.zerg_competent_comp(state) - else: - return state.has(ItemNames.MUTALISK, self.player) and self.zerg_competent_comp(state) - - def nova_any_weapon(self, state: CollectionState) -> bool: - return state.has_any( - {ItemNames.NOVA_C20A_CANISTER_RIFLE, ItemNames.NOVA_HELLFIRE_SHOTGUN, ItemNames.NOVA_PLASMA_RIFLE, - ItemNames.NOVA_MONOMOLECULAR_BLADE, ItemNames.NOVA_BLAZEFIRE_GUNBLADE}, self.player) - - def nova_ranged_weapon(self, state: CollectionState) -> bool: - return state.has_any( - {ItemNames.NOVA_C20A_CANISTER_RIFLE, ItemNames.NOVA_HELLFIRE_SHOTGUN, ItemNames.NOVA_PLASMA_RIFLE}, - self.player) - - def nova_splash(self, state: CollectionState) -> bool: - return state.has_any({ - ItemNames.NOVA_HELLFIRE_SHOTGUN, ItemNames.NOVA_BLAZEFIRE_GUNBLADE, ItemNames.NOVA_PULSE_GRENADES - }, self.player) \ - or self.advanced_tactics and state.has_any( - {ItemNames.NOVA_PLASMA_RIFLE, ItemNames.NOVA_MONOMOLECULAR_BLADE}, self.player) - - def nova_dash(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.NOVA_MONOMOLECULAR_BLADE, ItemNames.NOVA_BLINK}, self.player) - - def nova_full_stealth(self, state: CollectionState) -> bool: - return state.count(ItemNames.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE, self.player) >= 2 - - def nova_heal(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.NOVA_ARMORED_SUIT_MODULE, ItemNames.NOVA_STIM_INFUSION}, self.player) - - def nova_escape_assist(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.NOVA_BLINK, ItemNames.NOVA_HOLO_DECOY, ItemNames.NOVA_IONIC_FORCE_FIELD}, self.player) - - def the_escape_stuff_granted(self) -> bool: - """ - The NCO first mission requires having too much stuff first before actually able to do anything - :return: - """ - return self.story_tech_granted \ - or (self.mission_order == MissionOrder.option_vanilla and self.enabled_campaigns == {SC2Campaign.NCO}) - - def the_escape_first_stage_requirement(self, state: CollectionState) -> bool: - return self.the_escape_stuff_granted() \ - or (self.nova_ranged_weapon(state) and (self.nova_full_stealth(state) or self.nova_heal(state))) - - def the_escape_requirement(self, state: CollectionState) -> bool: - return self.the_escape_first_stage_requirement(state) \ - and (self.the_escape_stuff_granted() or self.nova_splash(state)) - - def terran_cliffjumper(self, state: CollectionState) -> bool: - return state.has(ItemNames.REAPER, self.player) \ - or state.has_all({ItemNames.GOLIATH, ItemNames.GOLIATH_JUMP_JETS}, self.player) \ - or state.has_all({ItemNames.SIEGE_TANK, ItemNames.SIEGE_TANK_JUMP_JETS}, self.player) - - def terran_able_to_snipe_defiler(self, state: CollectionState) -> bool: - return state.has_all({ItemNames.NOVA_JUMP_SUIT_MODULE, ItemNames.NOVA_C20A_CANISTER_RIFLE}, self.player) \ - or state.has_all({ItemNames.SIEGE_TANK, ItemNames.SIEGE_TANK_MAELSTROM_ROUNDS, ItemNames.SIEGE_TANK_JUMP_JETS}, self.player) - - def sudden_strike_requirement(self, state: CollectionState) -> bool: - return self.sudden_strike_can_reach_objectives(state) \ - and self.terran_able_to_snipe_defiler(state) \ - and state.has_any({ItemNames.SIEGE_TANK, ItemNames.VULTURE}, self.player) \ - and self.nova_splash(state) \ - and (self.terran_defense_rating(state, True, False) >= 2 - or state.has(ItemNames.NOVA_JUMP_SUIT_MODULE, self.player)) - - def sudden_strike_can_reach_objectives(self, state: CollectionState) -> bool: - return self.terran_cliffjumper(state) \ - or state.has_any({ItemNames.BANSHEE, ItemNames.VIKING}, self.player) \ - or ( - self.advanced_tactics - and state.has(ItemNames.MEDIVAC, self.player) - and state.has_any({ItemNames.MARINE, ItemNames.MARAUDER, ItemNames.VULTURE, ItemNames.HELLION, - ItemNames.GOLIATH}, self.player) - ) - - def enemy_intelligence_garrisonable_unit(self, state: CollectionState) -> bool: - """ - Has unit usable as a Garrison in Enemy Intelligence - :param state: - :return: - """ - return state.has_any( - {ItemNames.MARINE, ItemNames.REAPER, ItemNames.MARAUDER, ItemNames.GHOST, ItemNames.SPECTRE, - ItemNames.HELLION, ItemNames.GOLIATH, ItemNames.WARHOUND, ItemNames.DIAMONDBACK, ItemNames.VIKING}, - self.player) - - def enemy_intelligence_cliff_garrison(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.REAPER, ItemNames.VIKING, ItemNames.MEDIVAC, ItemNames.HERCULES}, self.player) \ - or state.has_all({ItemNames.GOLIATH, ItemNames.GOLIATH_JUMP_JETS}, self.player) \ - or self.advanced_tactics and state.has_any({ItemNames.HELS_ANGELS, ItemNames.BRYNHILDS}, self.player) - - def enemy_intelligence_first_stage_requirement(self, state: CollectionState) -> bool: - return self.enemy_intelligence_garrisonable_unit(state) \ - and (self.terran_competent_comp(state) - or ( - self.terran_common_unit(state) - and self.terran_competent_anti_air(state) - and state.has(ItemNames.NOVA_NUKE, self.player) - ) - ) \ - and self.terran_defense_rating(state, True, True) >= 5 - - def enemy_intelligence_second_stage_requirement(self, state: CollectionState) -> bool: - return self.enemy_intelligence_first_stage_requirement(state) \ - and self.enemy_intelligence_cliff_garrison(state) \ - and ( - self.story_tech_granted - or ( - self.nova_any_weapon(state) - and ( - self.nova_full_stealth(state) - or (self.nova_heal(state) - and self.nova_splash(state) - and self.nova_ranged_weapon(state)) - ) - ) - ) - - def enemy_intelligence_third_stage_requirement(self, state: CollectionState) -> bool: - return self.enemy_intelligence_second_stage_requirement(state) \ - and ( - self.story_tech_granted - or ( - state.has(ItemNames.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE, self.player) - and self.nova_dash(state) - ) - ) - - def trouble_in_paradise_requirement(self, state: CollectionState) -> bool: - return self.nova_any_weapon(state) \ - and self.nova_splash(state) \ - and self.terran_beats_protoss_deathball(state) \ - and self.terran_defense_rating(state, True, True) >= 7 - - def night_terrors_requirement(self, state: CollectionState) -> bool: - return self.terran_common_unit(state) \ - and self.terran_competent_anti_air(state) \ - and ( - # These can handle the waves of infested, even volatile ones - state.has(ItemNames.SIEGE_TANK, self.player) - or state.has_all({ItemNames.VIKING, ItemNames.VIKING_SHREDDER_ROUNDS}, self.player) - or ( - ( - # Regular infesteds - state.has(ItemNames.FIREBAT, self.player) - or state.has_all({ItemNames.HELLION, ItemNames.HELLION_HELLBAT_ASPECT}, self.player) - or ( - self.advanced_tactics - and state.has_any({ItemNames.PERDITION_TURRET, ItemNames.PLANETARY_FORTRESS}, self.player) - ) - ) - and self.terran_bio_heal(state) - and ( - # Volatile infesteds - state.has(ItemNames.LIBERATOR, self.player) - or ( - self.advanced_tactics - and state.has_any({ItemNames.HERC, ItemNames.VULTURE}, self.player) - ) - ) - ) - ) - - def flashpoint_far_requirement(self, state: CollectionState) -> bool: - return self.terran_competent_comp(state) \ - and self.terran_mobile_detector(state) \ - and self.terran_defense_rating(state, True, False) >= 6 - - def enemy_shadow_tripwires_tool(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.NOVA_FLASHBANG_GRENADES, ItemNames.NOVA_BLINK, ItemNames.NOVA_DOMINATION}, - self.player) - - def enemy_shadow_door_unlocks_tool(self, state: CollectionState) -> bool: - return state.has_any({ItemNames.NOVA_DOMINATION, ItemNames.NOVA_BLINK, ItemNames.NOVA_JUMP_SUIT_MODULE}, - self.player) - - def enemy_shadow_domination(self, state: CollectionState) -> bool: - return self.story_tech_granted \ - or (self.nova_ranged_weapon(state) - and (self.nova_full_stealth(state) - or state.has(ItemNames.NOVA_JUMP_SUIT_MODULE, self.player) - or (self.nova_heal(state) and self.nova_splash(state)) - ) - ) - - def enemy_shadow_first_stage(self, state: CollectionState) -> bool: - return self.enemy_shadow_domination(state) \ - and (self.story_tech_granted - or ((self.nova_full_stealth(state) and self.enemy_shadow_tripwires_tool(state)) - or (self.nova_heal(state) and self.nova_splash(state)) - ) - ) - - def enemy_shadow_second_stage(self, state: CollectionState) -> bool: - return self.enemy_shadow_first_stage(state) \ - and (self.story_tech_granted - or self.nova_splash(state) - or self.nova_heal(state) - or self.nova_escape_assist(state) - ) - - def enemy_shadow_door_controls(self, state: CollectionState) -> bool: - return self.enemy_shadow_second_stage(state) \ - and (self.story_tech_granted or self.enemy_shadow_door_unlocks_tool(state)) - - def enemy_shadow_victory(self, state: CollectionState) -> bool: - return self.enemy_shadow_door_controls(state) \ - and (self.story_tech_granted or self.nova_heal(state)) - - def dark_skies_requirement(self, state: CollectionState) -> bool: - return self.terran_common_unit(state) \ - and self.terran_beats_protoss_deathball(state) \ - and self.terran_defense_rating(state, False, True) >= 8 - - def end_game_requirement(self, state: CollectionState) -> bool: - return self.terran_competent_comp(state) \ - and self.terran_mobile_detector(state) \ - and ( - state.has_any({ItemNames.BATTLECRUISER, ItemNames.LIBERATOR, ItemNames.BANSHEE}, self.player) - or state.has_all({ItemNames.WRAITH, ItemNames.WRAITH_ADVANCED_LASER_TECHNOLOGY}, self.player) - ) \ - and (state.has_any({ItemNames.BATTLECRUISER, ItemNames.VIKING, ItemNames.LIBERATOR}, self.player) - or (self.advanced_tactics - and state.has_all({ItemNames.RAVEN, ItemNames.RAVEN_HUNTER_SEEKER_WEAPON}, self.player) - ) - ) - - def __init__(self, world: World): - self.world: World = world - self.player = None if world is None else world.player - self.logic_level = get_option_value(world, 'required_tactics') - self.advanced_tactics = self.logic_level != RequiredTactics.option_standard - self.take_over_ai_allies = get_option_value(world, "take_over_ai_allies") == TakeOverAIAllies.option_true - self.kerrigan_unit_available = get_option_value(world, 'kerrigan_presence') in kerrigan_unit_available \ - and SC2Campaign.HOTS in get_enabled_campaigns(world) - self.kerrigan_levels_per_mission_completed = get_option_value(world, "kerrigan_levels_per_mission_completed") - self.kerrigan_levels_per_mission_completed_cap = get_option_value(world, "kerrigan_levels_per_mission_completed_cap") - self.kerrigan_total_level_cap = get_option_value(world, "kerrigan_total_level_cap") - self.story_tech_granted = get_option_value(world, "grant_story_tech") == GrantStoryTech.option_true - self.story_levels_granted = get_option_value(world, "grant_story_levels") != GrantStoryLevels.option_disabled - self.basic_terran_units = get_basic_units(world, SC2Race.TERRAN) - self.basic_zerg_units = get_basic_units(world, SC2Race.ZERG) - self.basic_protoss_units = get_basic_units(world, SC2Race.PROTOSS) - self.spear_of_adun_autonomously_cast_presence = get_option_value(world, "spear_of_adun_autonomously_cast_ability_presence") - self.enabled_campaigns = get_enabled_campaigns(world) - self.mission_order = get_option_value(world, "mission_order") diff --git a/worlds/sc2/Starcraft2.kv b/worlds/sc2/Starcraft2.kv deleted file mode 100644 index 6b112c2f00a6..000000000000 --- a/worlds/sc2/Starcraft2.kv +++ /dev/null @@ -1,28 +0,0 @@ - - scroll_type: ["content", "bars"] - bar_width: dp(12) - effect_cls: "ScrollEffect" - - - cols: 1 - size_hint_y: None - height: self.minimum_height + 15 - padding: [5,0,dp(12),0] - -: - cols: 1 - -: - rows: 1 - -: - cols: 1 - spacing: [0,5] - -: - text_size: self.size - markup: True - halign: 'center' - valign: 'middle' - padding: [5,0,5,0] - outline_width: 1 diff --git a/worlds/sc2/__init__.py b/worlds/sc2/__init__.py index f11059a54ef5..0201ebf60f27 100644 --- a/worlds/sc2/__init__.py +++ b/worlds/sc2/__init__.py @@ -1,25 +1,49 @@ -import typing from dataclasses import fields +import logging -from typing import List, Set, Iterable, Sequence, Dict, Callable, Union +from typing import * from math import floor, ceil -from BaseClasses import Item, MultiWorld, Location, Tutorial, ItemClassification +from BaseClasses import Item, MultiWorld, Location, Tutorial, ItemClassification, CollectionState +from Options import Accessibility, OptionError from worlds.AutoWorld import WebWorld, World -from . import ItemNames -from .Items import StarcraftItem, filler_items, get_item_table, get_full_item_list, \ - get_basic_units, ItemData, upgrade_included_names, progressive_if_nco, kerrigan_actives, kerrigan_passives, \ - kerrigan_only_passives, progressive_if_ext, not_balanced_starting_units, spear_of_adun_calldowns, \ - spear_of_adun_castable_passives, nova_equipment -from .ItemGroups import item_name_groups -from .Locations import get_locations, LocationType, get_location_types, get_plando_locations -from .Regions import create_regions -from .Options import get_option_value, LocationInclusion, KerriganLevelItemDistribution, \ - KerriganPresence, KerriganPrimalStatus, RequiredTactics, kerrigan_unit_available, StarterUnit, SpearOfAdunPresence, \ - get_enabled_campaigns, SpearOfAdunAutonomouslyCastAbilityPresence, Starcraft2Options -from .PoolFilter import filter_items, get_item_upgrades, UPGRADABLE_ITEMS, missions_in_mission_table, get_used_races -from .MissionTables import MissionInfo, SC2Campaign, lookup_name_to_mission, SC2Mission, \ - SC2Race - +from . import location_groups +from .item.item_groups import unreleased_items, war_council_upgrades +from .item.item_tables import ( + get_full_item_list, + not_balanced_starting_units, WEAPON_ARMOR_UPGRADE_MAX_LEVEL, +) +from .item import FilterItem, ItemFilterFlags, StarcraftItem, item_groups, item_names, item_tables, item_parents, \ + ZergItemType, ProtossItemType, ItemData +from .locations import ( + get_locations, DEFAULT_LOCATION_LIST, get_location_types, get_location_flags, + get_plando_locations, LocationType, lookup_location_id_to_type +) +from .mission_order.layout_types import Gauntlet +from .options import ( + get_option_value, LocationInclusion, KerriganLevelItemDistribution, + KerriganPresence, KerriganPrimalStatus, kerrigan_unit_available, StarterUnit, SpearOfAdunPresence, + get_enabled_campaigns, SpearOfAdunPassiveAbilityPresence, Starcraft2Options, + GrantStoryTech, GenericUpgradeResearch, RequiredTactics, + upgrade_included_names, EnableVoidTrade, FillerItemsDistribution, MissionOrderScouting, option_groups, + NovaGhostOfAChanceVariant, MissionOrder, VanillaItemsOnly, ExcludeOverpoweredItems, + is_mission_in_soa_presence, +) +from .rules import get_basic_units, SC2Logic +from . import settings +from .pool_filter import filter_items +from .mission_tables import SC2Campaign, SC2Mission, SC2Race, MissionFlag +from .regions import create_mission_order +from .mission_order import SC2MissionOrder +from worlds.LauncherComponents import components, Component, launch as launch_component + +logger = logging.getLogger("Starcraft 2") +VICTORY_MODULO = 100 + +def launch_client(*args: str): + from .client import launch + launch_component(launch, name="Starcraft 2 Client", args=args) + +components.append(Component('Starcraft 2 Client', func=launch_client, game_name='Starcraft 2', supports_uri=True)) class Starcraft2WebWorld(WebWorld): setup_en = Tutorial( @@ -40,8 +64,18 @@ class Starcraft2WebWorld(WebWorld): ["Neocerber"] ) - tutorials = [setup_en, setup_fr] + custom_mission_orders_en = Tutorial( + "Custom Mission Order Usage Guide", + "Documentation for the custom_mission_order YAML option", + "English", + "custom_mission_orders_en.md", + "custom_mission_orders/en", + ["Salzkorn"] + ) + + tutorials = [setup_en, setup_fr, custom_mission_orders_en] game_info_languages = ["en", "fr"] + option_groups = option_groups class SC2World(World): @@ -52,90 +86,279 @@ class SC2World(World): game = "Starcraft 2" web = Starcraft2WebWorld() + settings: ClassVar[settings.Starcraft2Settings] item_name_to_id = {name: data.code for name, data in get_full_item_list().items()} - location_name_to_id = {location.name: location.code for location in get_locations(None)} + location_name_to_id = {location.name: location.code for location in DEFAULT_LOCATION_LIST} options_dataclass = Starcraft2Options options: Starcraft2Options - item_name_groups = item_name_groups - locked_locations: typing.List[str] - location_cache: typing.List[Location] - mission_req_table: Dict[SC2Campaign, Dict[str, MissionInfo]] = {} - final_mission_id: int - victory_item: str - required_client_version = 0, 4, 5 + item_name_groups = item_groups.item_name_groups # type: ignore + location_name_groups = location_groups.get_location_groups() + locked_locations: List[str] + """Locations locked to contain specific items, such as victory events or forced resources""" + location_cache: List[Location] + final_missions: List[int] + required_client_version = 0, 6, 4 + custom_mission_order: SC2MissionOrder + logic: Optional['SC2Logic'] + filler_items_distribution: Dict[str, int] def __init__(self, multiworld: MultiWorld, player: int): super(SC2World, self).__init__(multiworld, player) self.location_cache = [] self.locked_locations = [] + self.filler_items_distribution = FillerItemsDistribution.default + self.logic = None - def create_item(self, name: str) -> Item: + def create_item(self, name: str) -> StarcraftItem: data = get_full_item_list()[name] return StarcraftItem(name, data.classification, data.code, self.player) def create_regions(self): - self.mission_req_table, self.final_mission_id, self.victory_item = create_regions( + self.logic = SC2Logic(self) + self.custom_mission_order = create_mission_order( self, get_locations(self), self.location_cache ) + self.logic.nova_used = ( + MissionFlag.Nova in self.custom_mission_order.get_used_flags() + or ( + MissionFlag.WoLNova in self.custom_mission_order.get_used_flags() + and self.options.nova_ghost_of_a_chance_variant == NovaGhostOfAChanceVariant.option_nco + ) + ) - def create_items(self): - setup_events(self.player, self.locked_locations, self.location_cache) - - excluded_items = get_excluded_items(self) - - starter_items = assign_starter_items(self, excluded_items, self.locked_locations, self.location_cache) - - fill_resource_locations(self, self.locked_locations, self.location_cache) - - pool = get_item_pool(self, self.mission_req_table, starter_items, excluded_items, self.location_cache) + def create_items(self) -> None: + # Starcraft 2-specific item setup: + # * Filter item pool based on player options + # * Plando starter units + # * Start-inventory units if necessary for logic + # * Plando filler items based on location exclusions + # * If the item pool is less than the location count, add some filler items - fill_item_pool_with_dummy_items(self, self.locked_locations, self.location_cache, pool) + setup_events(self.player, self.locked_locations, self.location_cache) + set_up_filler_items_distribution(self) + + item_list: List[FilterItem] = create_and_flag_explicit_item_locks_and_excludes(self) + flag_excludes_by_faction_presence(self, item_list) + flag_mission_based_item_excludes(self, item_list) + flag_allowed_orphan_items(self, item_list) + flag_start_inventory(self, item_list) + flag_unused_upgrade_types(self, item_list) + flag_unreleased_items(item_list) + flag_user_excluded_item_sets(self, item_list) + flag_war_council_items(self, item_list) + flag_and_add_resource_locations(self, item_list) + flag_mission_order_required_items(self, item_list) + pruned_items: List[StarcraftItem] = prune_item_pool(self, item_list) + + start_inventory = [item for item in pruned_items if ItemFilterFlags.StartInventory in item.filter_flags] + pool = [item for item in pruned_items if ItemFilterFlags.StartInventory not in item.filter_flags] + + # Tell the logic which unit classes are used for required W/A upgrades + used_item_names: Set[str] = {item.name for item in pruned_items} + used_item_names = used_item_names.union(item.name for item in self.multiworld.itempool if item.player == self.player) + assert self.logic is not None + if used_item_names.isdisjoint(item_groups.barracks_wa_group): + self.logic.has_barracks_unit = False + if used_item_names.isdisjoint(item_groups.factory_wa_group): + self.logic.has_factory_unit = False + if used_item_names.isdisjoint(item_groups.starport_wa_group): + self.logic.has_starport_unit = False + if used_item_names.isdisjoint(item_groups.zerg_melee_wa): + self.logic.has_zerg_melee_unit = False + if used_item_names.isdisjoint(item_groups.zerg_ranged_wa): + self.logic.has_zerg_ranged_unit = False + if used_item_names.isdisjoint(item_groups.zerg_air_units): + self.logic.has_zerg_air_unit = False + if used_item_names.isdisjoint(item_groups.protoss_ground_wa): + self.logic.has_protoss_ground_unit = False + if used_item_names.isdisjoint(item_groups.protoss_air_wa): + self.logic.has_protoss_air_unit = False + + pad_item_pool_with_filler(self, len(self.location_cache) - len(self.locked_locations) - len(pool), pool) + + push_precollected_items_to_multiworld(self, start_inventory) self.multiworld.itempool += pool - def set_rules(self): - self.multiworld.completion_condition[self.player] = lambda state: state.has(self.victory_item, self.player) + def set_rules(self) -> None: + if self.options.required_tactics == RequiredTactics.option_no_logic: + # Forcing completed goal and minimal accessibility on no logic + self.options.accessibility.value = Accessibility.option_minimal + required_items = self.custom_mission_order.get_items_to_lock() + self.multiworld.completion_condition[self.player] = lambda state, required_items=required_items: all( # type: ignore + state.has(item, self.player, amount) for (item, amount) in required_items.items() + ) + else: + self.multiworld.completion_condition[self.player] = self.custom_mission_order.get_completion_condition(self.player) def get_filler_item_name(self) -> str: - return self.random.choice(filler_items) + # Assume `self.filler_items_distribution` is validated and has at least one non-zero entry + return self.random.choices(tuple(self.filler_items_distribution), weights=self.filler_items_distribution.values())[0] # type: ignore - def fill_slot_data(self): - slot_data = {} + def fill_slot_data(self) -> Mapping[str, Any]: + slot_data: Dict[str, Any] = {} for option_name in [field.name for field in fields(Starcraft2Options)]: option = get_option_value(self, option_name) if type(option) in {str, int}: slot_data[option_name] = int(option) - slot_req_table = {} - - # Serialize data - for campaign in self.mission_req_table: - slot_req_table[campaign.id] = {} - for mission in self.mission_req_table[campaign]: - slot_req_table[campaign.id][mission] = self.mission_req_table[campaign][mission]._asdict() - # Replace mission objects with mission IDs - slot_req_table[campaign.id][mission]["mission"] = slot_req_table[campaign.id][mission]["mission"].id - - for index in range(len(slot_req_table[campaign.id][mission]["required_world"])): - # TODO this is a band-aid, sometimes the mission_req_table already contains dicts - # as far as I can tell it's related to having multiple vanilla mission orders - if not isinstance(slot_req_table[campaign.id][mission]["required_world"][index], dict): - slot_req_table[campaign.id][mission]["required_world"][index] = slot_req_table[campaign.id][mission]["required_world"][index]._asdict() enabled_campaigns = get_enabled_campaigns(self) slot_data["plando_locations"] = get_plando_locations(self) - slot_data["nova_covert_ops_only"] = (enabled_campaigns == {SC2Campaign.NCO}) - slot_data["mission_req"] = slot_req_table - slot_data["final_mission"] = self.final_mission_id - slot_data["version"] = 3 + slot_data["use_nova_nco_fallback"] = ( + enabled_campaigns == {SC2Campaign.NCO} + and self.options.mission_order == MissionOrder.option_vanilla + ) + if (self.options.nova_ghost_of_a_chance_variant == NovaGhostOfAChanceVariant.option_nco + or ( + self.options.nova_ghost_of_a_chance_variant == NovaGhostOfAChanceVariant.option_auto + and MissionFlag.Nova in self.custom_mission_order.get_used_flags().keys() + ) + ): + slot_data["use_nova_wol_fallback"] = False + else: + slot_data["use_nova_wol_fallback"] = True + slot_data["final_mission_ids"] = self.custom_mission_order.get_final_mission_ids() + slot_data["custom_mission_order"] = self.custom_mission_order.get_slot_data() + slot_data["version"] = 4 if SC2Campaign.HOTS not in enabled_campaigns: slot_data["kerrigan_presence"] = KerriganPresence.option_not_present + + if self.options.mission_order_scouting != MissionOrderScouting.option_none: + mission_item_classification: Dict[str, int] = {} + for location in self.multiworld.get_locations(self.player): + # Event do not hold items + if not location.is_event: + assert location.address is not None + assert location.item is not None + if lookup_location_id_to_type[location.address] == LocationType.VICTORY_CACHE: + # Ensure that if there are multiple items given for finishing a mission and that at least + # one is progressive, the flag kept is progressive. + location_name = self.location_id_to_name[(location.address // VICTORY_MODULO) * VICTORY_MODULO] + old_classification = mission_item_classification.get(location_name, 0) + mission_item_classification[location_name] = old_classification | location.item.classification.as_flag() + else: + mission_item_classification[location.name] = location.item.classification.as_flag() + slot_data["mission_item_classification"] = mission_item_classification + + # Disable trade if there is no trade partner + traders = [ + world + for world in self.multiworld.worlds.values() + if world.game == self.game and world.options.enable_void_trade == EnableVoidTrade.option_true # type: ignore + ] + if len(traders) < 2: + slot_data["enable_void_trade"] = EnableVoidTrade.option_false + return slot_data + def pre_fill(self) -> None: + assert self.logic is not None + self.logic.total_mission_count = self.custom_mission_order.get_mission_count() + if ( + self.options.generic_upgrade_missions > 0 + and self.options.required_tactics != RequiredTactics.option_no_logic + ): + # Attempt to resolve a situation when the option is too high for the mission order rolled + weapon_armor_item_names = [ + item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE, + item_names.PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE + ] + def state_with_kerrigan_levels() -> CollectionState: + state: CollectionState = self.multiworld.get_all_state(False) + # Ignore dead ends caused by Kerrigan -> solve those in the next stage + state.collect(self.create_item(item_names.KERRIGAN_LEVELS_70)) + state.update_reachable_regions(self.player) + return state + + self._fill_needed_items(state_with_kerrigan_levels, weapon_armor_item_names, WEAPON_ARMOR_UPGRADE_MAX_LEVEL) + if ( + self.options.kerrigan_levels_per_mission_completed > 0 + and self.options.required_tactics != RequiredTactics.option_no_logic + ): + # Attempt to solve being locked by Kerrigan level requirements + self._fill_needed_items(lambda: self.multiworld.get_all_state(False), [item_names.KERRIGAN_LEVELS_1], 70) + + + def _fill_needed_items(self, all_state_getter: Callable[[],CollectionState], items_to_use: List[str], max_attempts: int) -> None: + """ + Helper for pre-fill, seeks if the world is actually solvable and inserts items to start inventory if necessary. + :param all_state_getter: + :param items_to_use: + :param max_attempts: + :return: + """ + for attempt in range(0, max_attempts): + all_state: CollectionState = all_state_getter() + location_failed = False + for location in self.location_cache: + if not (all_state.can_reach_location(location.name, self.player) + and all_state.can_reach_region(location.parent_region.name, self.player)): + location_failed = True + break + if location_failed: + for item_name in items_to_use: + item = self.multiworld.create_item(item_name, self.player) + self.multiworld.push_precollected(item) + else: + return + + + def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]) -> None: + """ + Generate information to hint where each mission is actually located in the mission order + :param hint_data: + """ + hint_data[self.player] = {} + for campaign in self.custom_mission_order.mission_order_node.campaigns: + for layout in campaign.layouts: + columns = layout.layout_type.get_visual_layout() + is_single_row_layout = max([len(column) for column in columns]) == 1 + for column_index, column in enumerate(columns): + for row_index, layout_mission in enumerate(column): + slot = layout.missions[layout_mission] + if hasattr(slot, "mission") and slot.mission is not None: + mission = slot.mission + campaign_name = campaign.get_visual_name() + layout_name = layout.get_visual_name() + if isinstance(layout.layout_type, Gauntlet): + # Linearize Gauntlet + column_name = str( + layout_mission + 1 + if layout_mission >= 0 + else layout.layout_type.size + layout_mission + 1 + ) + row_name = "" + else: + column_name = "" if len(columns) == 1 else _get_column_display(column_index, is_single_row_layout) + row_name = "" if is_single_row_layout else str(1 + row_index) + mission_position_name: str = campaign_name + " " + layout_name + " " + column_name + row_name + mission_position_name = mission_position_name.strip().replace(" ", " ") + if mission_position_name != "": + for location in self.get_region(mission.mission_name).get_locations(): + if location.address is not None: + hint_data[self.player][location.address] = mission_position_name + + +def _get_column_display(index: int, single_row_layout: bool) -> str: + """ + Helper function to display column name + :param index: + :param single_row_layout: + :return: + """ + if single_row_layout: + return str(index + 1) + else: + # Convert column name to a letter, from Z continue with AA and so on + f: Callable[[int], str] = lambda x: "" if x == 0 else f((x - 1) // 26) + chr((x - 1) % 26 + ord("A")) + return f(index + 1) + -def setup_events(player: int, locked_locations: typing.List[str], location_cache: typing.List[Location]): +def setup_events(player: int, locked_locations: List[str], location_cache: List[Location]) -> None: for location in location_cache: if location.address is None: item = Item(location.name, ItemClassification.progression, None, player) @@ -145,319 +368,661 @@ def setup_events(player: int, locked_locations: typing.List[str], location_cache location.place_locked_item(item) -def get_excluded_items(world: World) -> Set[str]: - excluded_items: Set[str] = set(get_option_value(world, 'excluded_items')) - for item in world.multiworld.precollected_items[world.player]: - excluded_items.add(item.name) - locked_items: Set[str] = set(get_option_value(world, 'locked_items')) - # Starter items are also excluded items - starter_items: Set[str] = set(get_option_value(world, 'start_inventory')) - item_table = get_full_item_list() - soa_presence = get_option_value(world, "spear_of_adun_presence") - soa_autocast_presence = get_option_value(world, "spear_of_adun_autonomously_cast_ability_presence") - enabled_campaigns = get_enabled_campaigns(world) - - # Ensure no item is both guaranteed and excluded - invalid_items = excluded_items.intersection(locked_items) - invalid_count = len(invalid_items) - # Don't count starter items that can appear multiple times - invalid_count -= len([item for item in starter_items.intersection(locked_items) if item_table[item].quantity != 1]) - if invalid_count > 0: - raise Exception(f"{invalid_count} item{'s are' if invalid_count > 1 else ' is'} both locked and excluded from generation. Please adjust your excluded items and locked items.") - - def smart_exclude(item_choices: Set[str], choices_to_keep: int): - expected_choices = len(item_choices) - if expected_choices == 0: - return - item_choices = set(item_choices) - starter_choices = item_choices.intersection(starter_items) - excluded_choices = item_choices.intersection(excluded_items) - item_choices.difference_update(excluded_choices) - item_choices.difference_update(locked_items) - candidates = sorted(item_choices) - exclude_amount = min(expected_choices - choices_to_keep - len(excluded_choices) + len(starter_choices), len(candidates)) - if exclude_amount > 0: - excluded_items.update(world.random.sample(candidates, exclude_amount)) - - # Nova gear exclusion if NCO not in campaigns - if SC2Campaign.NCO not in enabled_campaigns: - excluded_items = excluded_items.union(nova_equipment) - - kerrigan_presence = get_option_value(world, "kerrigan_presence") - # Exclude Primal Form item if option is not set or Kerrigan is unavailable - if get_option_value(world, "kerrigan_primal_status") != KerriganPrimalStatus.option_item or \ - (kerrigan_presence in {KerriganPresence.option_not_present, KerriganPresence.option_not_present_and_no_passives}): - excluded_items.add(ItemNames.KERRIGAN_PRIMAL_FORM) - - # no Kerrigan & remove all passives => remove all abilities - if kerrigan_presence == KerriganPresence.option_not_present_and_no_passives: - for tier in range(7): - smart_exclude(kerrigan_actives[tier].union(kerrigan_passives[tier]), 0) +def create_and_flag_explicit_item_locks_and_excludes(world: SC2World) -> List[FilterItem]: + """ + Handles `excluded_items`, `locked_items`, and `start_inventory` + Returns a list of all possible non-filler items that can be added, with an accompanying flags bitfield. + """ + excluded_items = world.options.excluded_items + unexcluded_items = world.options.unexcluded_items + locked_items = world.options.locked_items + start_inventory = world.options.start_inventory + key_items = world.custom_mission_order.get_items_to_lock() + + def resolve_count(count: Optional[int], max_count: int) -> int: + if count == 0: + return max_count + if count is None: + return 0 + if max_count == 0: + return count + return min(count, max_count) + + auto_excludes = {item_name: 1 for item_name in item_groups.legacy_items} + if world.options.exclude_overpowered_items.value == ExcludeOverpoweredItems.option_true: + for item_name in item_groups.overpowered_items: + auto_excludes[item_name] = 1 + + result: List[FilterItem] = [] + for item_name, item_data in item_tables.item_table.items(): + max_count = item_data.quantity + auto_excluded_count = auto_excludes.get(item_name) + excluded_count = excluded_items.get(item_name, auto_excluded_count) + unexcluded_count = unexcluded_items.get(item_name) + locked_count = locked_items.get(item_name) + start_count: Optional[int] = start_inventory.get(item_name) + key_count = key_items.get(item_name, 0) + # specifying 0 in the yaml means exclude / lock all + # start_inventory doesn't allow specifying 0 + # not specifying means don't exclude/lock/start + excluded_count = resolve_count(excluded_count, max_count) + unexcluded_count = resolve_count(unexcluded_count, max_count) + locked_count = resolve_count(locked_count, max_count) + start_count = resolve_count(start_count, max_count) + + excluded_count = max(0, excluded_count - unexcluded_count) + + # Priority: start_inventory >> locked_items >> excluded_items >> unspecified + if max_count == 0: + if excluded_count: + logger.warning(f"Item {item_name} was listed as excluded, but as a filler item, it cannot be explicitly excluded.") + excluded_count = 0 + max_count = start_count + locked_count + elif start_count > max_count: + logger.warning(f"Item {item_name} had start amount greater than maximum amount ({start_count} > {max_count}). Capping start amount to max.") + start_count = max_count + locked_count = 0 + excluded_count = 0 + elif locked_count + start_count > max_count: + logger.warning(f"Item {item_name} had locked + start amount greater than maximum amount " + f"({locked_count} + {start_count} > {max_count}). Capping locked amount to max - start.") + locked_count = max_count - start_count + excluded_count = 0 + elif excluded_count + locked_count + start_count > max_count: + logger.warning(f"Item {item_name} had excluded + locked + start amounts greater than maximum amount " + f"({excluded_count} + {locked_count} + {start_count} > {max_count}). Decreasing excluded amount.") + excluded_count = max_count - start_count - locked_count + # Make sure the final count creates enough items to satisfy key requirements + final_count = max(max_count, key_count) + for index in range(final_count): + result.append(FilterItem(item_name, item_data, index)) + if index < start_count: + result[-1].flags |= ItemFilterFlags.StartInventory + if index < locked_count + start_count: + result[-1].flags |= ItemFilterFlags.Locked + if item_name in world.options.non_local_items: + result[-1].flags |= ItemFilterFlags.NonLocal + if index >= max(max_count - excluded_count, key_count): + result[-1].flags |= ItemFilterFlags.UserExcluded + return result + + +def flag_excludes_by_faction_presence(world: SC2World, item_list: List[FilterItem]) -> None: + """Excludes items based on if their faction has a mission present where they can be used""" + missions = get_all_missions(world.custom_mission_order) + if world.options.take_over_ai_allies.value: + terran_missions = [mission for mission in missions if (MissionFlag.Terran|MissionFlag.AiTerranAlly) & mission.flags] + zerg_missions = [mission for mission in missions if (MissionFlag.Zerg|MissionFlag.AiZergAlly) & mission.flags] + protoss_missions = [mission for mission in missions if (MissionFlag.Protoss|MissionFlag.AiProtossAlly) & mission.flags] + else: + terran_missions = [mission for mission in missions if MissionFlag.Terran in mission.flags] + zerg_missions = [mission for mission in missions if MissionFlag.Zerg in mission.flags] + protoss_missions = [mission for mission in missions if MissionFlag.Protoss in mission.flags] + terran_build_missions = [mission for mission in terran_missions if MissionFlag.NoBuild not in mission.flags] + zerg_build_missions = [mission for mission in zerg_missions if MissionFlag.NoBuild not in mission.flags] + protoss_build_missions = [mission for mission in protoss_missions if MissionFlag.NoBuild not in mission.flags] + auto_upgrades_in_nobuilds = ( + world.options.generic_upgrade_research.value + in (GenericUpgradeResearch.option_always_auto, GenericUpgradeResearch.option_auto_in_no_build) + ) + + for item in item_list: + # Catch-all for all of a faction's items + if not terran_missions and item.data.race == SC2Race.TERRAN: + if item.name not in item_groups.nova_equipment: + item.flags |= ItemFilterFlags.FilterExcluded + continue + if not zerg_missions and item.data.race == SC2Race.ZERG: + if item.data.type != item_tables.ZergItemType.Ability \ + and item.data.type != ZergItemType.Level: + item.flags |= ItemFilterFlags.FilterExcluded + continue + if not protoss_missions and item.data.race == SC2Race.PROTOSS: + if item.name not in item_groups.soa_items: + item.flags |= ItemFilterFlags.FilterExcluded + continue + + # Faction units + if (not terran_build_missions + and item.data.type in (item_tables.TerranItemType.Unit, item_tables.TerranItemType.Building, item_tables.TerranItemType.Mercenary) + ): + item.flags |= ItemFilterFlags.FilterExcluded + if (not zerg_build_missions + and item.data.type in (item_tables.ZergItemType.Unit, item_tables.ZergItemType.Mercenary, item_tables.ZergItemType.Evolution_Pit) + ): + if (SC2Mission.ENEMY_WITHIN not in missions + or world.options.grant_story_tech.value == GrantStoryTech.option_grant + or item.name not in (item_names.ZERGLING, item_names.ROACH, item_names.HYDRALISK, item_names.INFESTOR) + ): + item.flags |= ItemFilterFlags.FilterExcluded + if (not protoss_build_missions + and item.data.type in ( + item_tables.ProtossItemType.Unit, + item_tables.ProtossItemType.Unit_2, + item_tables.ProtossItemType.Building, + ) + ): + # Note(mm): This doesn't exclude things like automated assimilators or warp gate improvements + # because that item type is mixed in with e.g. Reconstruction Beam and Overwatch + if (SC2Mission.TEMPLAR_S_RETURN not in missions + or world.options.grant_story_tech.value == GrantStoryTech.option_grant + or item.name not in ( + item_names.IMMORTAL, item_names.ANNIHILATOR, + item_names.COLOSSUS, item_names.VANGUARD, item_names.REAVER, item_names.DARK_TEMPLAR, + item_names.SENTRY, item_names.HIGH_TEMPLAR, + ) + ): + item.flags |= ItemFilterFlags.FilterExcluded + + # Faction +attack/armour upgrades + if (item.data.type == item_tables.TerranItemType.Upgrade + and not terran_build_missions + and not auto_upgrades_in_nobuilds + ): + item.flags |= ItemFilterFlags.FilterExcluded + if (item.data.type == item_tables.ZergItemType.Upgrade + and not zerg_build_missions + and not auto_upgrades_in_nobuilds + ): + item.flags |= ItemFilterFlags.FilterExcluded + if (item.data.type == item_tables.ProtossItemType.Upgrade + and not protoss_build_missions + and not auto_upgrades_in_nobuilds + ): + item.flags |= ItemFilterFlags.FilterExcluded + + +def flag_mission_based_item_excludes(world: SC2World, item_list: List[FilterItem]) -> None: + """ + Excludes items based on mission / campaign presence: Nova Gear, Kerrigan abilities, SOA + """ + missions = get_all_missions(world.custom_mission_order) + + kerrigan_missions = [mission for mission in missions if MissionFlag.Kerrigan in mission.flags] + kerrigan_build_missions = [mission for mission in kerrigan_missions if MissionFlag.NoBuild not in mission.flags] + nova_missions = [ + mission for mission in missions + if MissionFlag.Nova in mission.flags + or ( + world.options.nova_ghost_of_a_chance_variant == NovaGhostOfAChanceVariant.option_nco + and MissionFlag.WoLNova in mission.flags + ) + ] + + kerrigan_is_present = ( + len(kerrigan_missions) > 0 + and world.options.kerrigan_presence in kerrigan_unit_available + and SC2Campaign.HOTS in get_enabled_campaigns(world) # TODO: Kerrigan available all Zerg/Everywhere + ) + + # TvX build missions -- check flags + if world.options.take_over_ai_allies: + terran_build_missions = [mission for mission in missions if ( + (MissionFlag.Terran in mission.flags or MissionFlag.AiTerranAlly in mission.flags) + and MissionFlag.NoBuild not in mission.flags + )] + else: + terran_build_missions = [mission for mission in missions if ( + MissionFlag.Terran in mission.flags + and MissionFlag.NoBuild not in mission.flags + )] + tvz_build_missions = [mission for mission in terran_build_missions if MissionFlag.VsZerg in mission.flags] + tvp_build_missions = [mission for mission in terran_build_missions if MissionFlag.VsProtoss in mission.flags] + tvt_build_missions = [mission for mission in terran_build_missions if MissionFlag.VsTerran in mission.flags] + + # Check if SOA actives should be present + if world.options.spear_of_adun_presence != SpearOfAdunPresence.option_not_present: + soa_missions = missions + soa_missions = [ + m for m in soa_missions + if is_mission_in_soa_presence(world.options.spear_of_adun_presence.value, m) + ] + if not world.options.spear_of_adun_present_in_no_build: + soa_missions = [m for m in soa_missions if MissionFlag.NoBuild not in m.flags] + soa_presence = len(soa_missions) > 0 + else: + soa_presence = False + + # Check if SOA passives should be present + if world.options.spear_of_adun_passive_ability_presence != SpearOfAdunPassiveAbilityPresence.option_not_present: + soa_missions = missions + soa_missions = [ + m for m in soa_missions + if is_mission_in_soa_presence( + world.options.spear_of_adun_passive_ability_presence.value, + m, + SpearOfAdunPassiveAbilityPresence + ) + ] + if not world.options.spear_of_adun_passive_present_in_no_build: + soa_missions = [m for m in soa_missions if MissionFlag.NoBuild not in m.flags] + soa_passive_presence = len(soa_missions) > 0 else: - # no Kerrigan, but keep non-Kerrigan passives - if kerrigan_presence == KerriganPresence.option_not_present: - smart_exclude(kerrigan_only_passives, 0) - for tier in range(7): - smart_exclude(kerrigan_actives[tier], 0) - - # SOA exclusion, other cases are handled by generic race logic - if (soa_presence == SpearOfAdunPresence.option_lotv_protoss and SC2Campaign.LOTV not in enabled_campaigns) \ - or soa_presence == SpearOfAdunPresence.option_not_present: - excluded_items.update(spear_of_adun_calldowns) - if (soa_autocast_presence == SpearOfAdunAutonomouslyCastAbilityPresence.option_lotv_protoss \ - and SC2Campaign.LOTV not in enabled_campaigns) \ - or soa_autocast_presence == SpearOfAdunAutonomouslyCastAbilityPresence.option_not_present: - excluded_items.update(spear_of_adun_castable_passives) - - return excluded_items - - -def assign_starter_items(world: World, excluded_items: Set[str], locked_locations: List[str], location_cache: typing.List[Location]) -> List[Item]: - starter_items: List[Item] = [] - non_local_items = get_option_value(world, "non_local_items") - starter_unit = get_option_value(world, "starter_unit") - enabled_campaigns = get_enabled_campaigns(world) - first_mission = get_first_mission(world.mission_req_table) - # Ensuring that first mission is completable + soa_passive_presence = False + + remove_kerrigan_abils = ( + # TODO: Kerrigan presence Zerg/Everywhere + not kerrigan_is_present + or (world.options.grant_story_tech.value == GrantStoryTech.option_grant and not kerrigan_build_missions) + or ( + world.options.grant_story_tech.value == GrantStoryTech.option_allow_substitutes + and len(kerrigan_missions) == 1 + and kerrigan_missions[0] == SC2Mission.SUPREME + ) + ) + + for item in item_list: + # Filter Nova equipment if you never get Nova + if not nova_missions and (item.name in item_groups.nova_equipment): + item.flags |= ItemFilterFlags.FilterExcluded + + # Todo(mm): How should no-build only / grant_story_tech affect excluding Kerrigan items? + # Exclude Primal form based on Kerrigan presence or primal form option + if (item.data.type == item_tables.ZergItemType.Primal_Form + and ((not kerrigan_is_present) or world.options.kerrigan_primal_status != KerriganPrimalStatus.option_item) + ): + item.flags |= ItemFilterFlags.FilterExcluded + + # Remove Kerrigan abilities if there's no kerrigan + if item.data.type == item_tables.ZergItemType.Ability and remove_kerrigan_abils: + item.flags |= ItemFilterFlags.FilterExcluded + + # Remove Spear of Adun if it's off + if item.name in item_tables.spear_of_adun_calldowns and not soa_presence: + item.flags |= ItemFilterFlags.FilterExcluded + + # Remove Spear of Adun passives + if item.name in item_tables.spear_of_adun_castable_passives and not soa_passive_presence: + item.flags |= ItemFilterFlags.FilterExcluded + + # Remove matchup-specific items if you don't play that matchup + if (item.name in (item_names.HIVE_MIND_EMULATOR, item_names.PSI_DISRUPTER) + and not tvz_build_missions + ): + item.flags |= ItemFilterFlags.FilterExcluded + if (item.name in (item_names.PSI_INDOCTRINATOR, item_names.SONIC_DISRUPTER) + and not tvt_build_missions + ): + item.flags |= ItemFilterFlags.FilterExcluded + if (item.name in (item_names.PSI_SCREEN, item_names.ARGUS_AMPLIFIER) + and not tvp_build_missions + ): + item.flags |= ItemFilterFlags.FilterExcluded + return + + +def flag_allowed_orphan_items(world: SC2World, item_list: List[FilterItem]) -> None: + """Adds the `Allowed_Orphan` flag to items that shouldn't be filtered with their parents, like combat shield""" + missions = get_all_missions(world.custom_mission_order) + terran_nobuild_missions = any((MissionFlag.Terran|MissionFlag.NoBuild) in mission.flags and mission.campaign != SC2Campaign.NCO for mission in missions) + if terran_nobuild_missions: + for item in item_list: + if item.name in ( + item_names.MARINE_COMBAT_SHIELD, item_names.MARINE_PROGRESSIVE_STIMPACK, item_names.MARINE_MAGRAIL_MUNITIONS, + item_names.MEDIC_STABILIZER_MEDPACKS, item_names.MEDIC_NANO_PROJECTOR, item_names.MARINE_LASER_TARGETING_SYSTEM, + ): + item.flags |= ItemFilterFlags.AllowedOrphan + # These rules only trigger on Standard tactics + if SC2Mission.BELLY_OF_THE_BEAST in missions and world.options.required_tactics == RequiredTactics.option_standard: + for item in item_list: + if item.name in (item_names.FIREBAT_NANO_PROJECTORS, item_names.FIREBAT_NANO_PROJECTORS, item_names.FIREBAT_PROGRESSIVE_STIMPACK): + item.flags |= ItemFilterFlags.AllowedOrphan + if SC2Mission.EVIL_AWOKEN in missions and world.options.required_tactics == RequiredTactics.option_standard: + for item in item_list: + if item.name in (item_names.STALKER_PHASE_REACTOR, item_names.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES, item_names.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION): + item.flags |= ItemFilterFlags.AllowedOrphan + + +def flag_start_inventory(world: SC2World, item_list: List[FilterItem]) -> None: + """Adds items to start_inventory based on first mission logic and options like `starter_unit` and `start_primary_abilities`""" + potential_starters = world.custom_mission_order.get_starting_missions() + starter_mission_names = [mission.mission_name for mission in potential_starters] + starter_unit = int(world.options.starter_unit) + + # If starter_unit is off and the first mission doesn't have a no-logic location, force starter_unit on if starter_unit == StarterUnit.option_off: - starter_mission_locations = [location.name for location in location_cache - if location.parent_region.name == first_mission - and location.access_rule == Location.access_rule] + start_collection_state = CollectionState(world.multiworld) + starter_mission_locations = [location.name for location in world.location_cache + if location.parent_region + and location.parent_region.name in starter_mission_names + and location.access_rule(start_collection_state)] if not starter_mission_locations: # Force early unit if first mission is impossible without one starter_unit = StarterUnit.option_any_starter_unit if starter_unit != StarterUnit.option_off: - first_race = lookup_name_to_mission[first_mission].race - - if first_race == SC2Race.ANY: - # If the first mission is a logic-less no-build - mission_req_table: Dict[SC2Campaign, Dict[str, MissionInfo]] = world.mission_req_table - races = get_used_races(mission_req_table, world) - races.remove(SC2Race.ANY) - if lookup_name_to_mission[first_mission].race in races: - # The campaign's race is in (At least one mission that's not logic-less no-build exists) - first_race = lookup_name_to_mission[first_mission].campaign.race - elif len(races) > 0: - # The campaign only has logic-less no-build missions. Find any other valid race - first_race = world.random.choice(list(races)) - - if first_race != SC2Race.ANY: - # The race of the early unit has been chosen - basic_units = get_basic_units(world, first_race) - if starter_unit == StarterUnit.option_balanced: - basic_units = basic_units.difference(not_balanced_starting_units) - if first_mission == SC2Mission.DARK_WHISPERS.mission_name: - # Special case - you don't have a logicless location but need an AA - basic_units = basic_units.difference( - {ItemNames.ZEALOT, ItemNames.CENTURION, ItemNames.SENTINEL, ItemNames.BLOOD_HUNTER, - ItemNames.AVENGER, ItemNames.IMMORTAL, ItemNames.ANNIHILATOR, ItemNames.VANGUARD}) - if first_mission == SC2Mission.SUDDEN_STRIKE.mission_name: - # Special case - cliffjumpers - basic_units = {ItemNames.REAPER, ItemNames.GOLIATH, ItemNames.SIEGE_TANK, ItemNames.VIKING, ItemNames.BANSHEE} - local_basic_unit = sorted(item for item in basic_units if item not in non_local_items and item not in excluded_items) - if not local_basic_unit: - # Drop non_local_items constraint - local_basic_unit = sorted(item for item in basic_units if item not in excluded_items) - if not local_basic_unit: - raise Exception("Early Unit: At least one basic unit must be included") - - unit: Item = add_starter_item(world, excluded_items, local_basic_unit) - starter_items.append(unit) - - # NCO-only specific rules - if first_mission == SC2Mission.SUDDEN_STRIKE.mission_name: - support_item: Union[str, None] = None - if unit.name == ItemNames.REAPER: - support_item = ItemNames.REAPER_SPIDER_MINES - elif unit.name == ItemNames.GOLIATH: - support_item = ItemNames.GOLIATH_JUMP_JETS - elif unit.name == ItemNames.SIEGE_TANK: - support_item = ItemNames.SIEGE_TANK_JUMP_JETS - elif unit.name == ItemNames.VIKING: - support_item = ItemNames.VIKING_SMART_SERVOS - if support_item is not None: - starter_items.append(add_starter_item(world, excluded_items, [support_item])) - starter_items.append(add_starter_item(world, excluded_items, [ItemNames.NOVA_JUMP_SUIT_MODULE])) - starter_items.append( - add_starter_item(world, excluded_items, - [ - ItemNames.NOVA_HELLFIRE_SHOTGUN, - ItemNames.NOVA_PLASMA_RIFLE, - ItemNames.NOVA_PULSE_GRENADES - ])) - if enabled_campaigns == {SC2Campaign.NCO}: - starter_items.append(add_starter_item(world, excluded_items, [ItemNames.LIBERATOR_RAID_ARTILLERY])) - - starter_abilities = get_option_value(world, 'start_primary_abilities') - assert isinstance(starter_abilities, int) - if starter_abilities: - ability_count = starter_abilities - ability_tiers = [0, 1, 3] - world.random.shuffle(ability_tiers) - if ability_count > 3: - ability_tiers.append(6) - for tier in ability_tiers: - abilities = kerrigan_actives[tier].union(kerrigan_passives[tier]).difference(excluded_items, non_local_items) - if not abilities: - abilities = kerrigan_actives[tier].union(kerrigan_passives[tier]).difference(excluded_items) - if abilities: - ability_count -= 1 - starter_items.append(add_starter_item(world, excluded_items, list(abilities))) - if ability_count == 0: - break - - return starter_items - - -def get_first_mission(mission_req_table: Dict[SC2Campaign, Dict[str, MissionInfo]]) -> str: - # The first world should also be the starting world - campaigns = mission_req_table.keys() - lowest_id = min([campaign.id for campaign in campaigns]) - first_campaign = [campaign for campaign in campaigns if campaign.id == lowest_id][0] - first_mission = list(mission_req_table[first_campaign])[0] - return first_mission - - -def add_starter_item(world: World, excluded_items: Set[str], item_list: Sequence[str]) -> Item: - - item_name = world.random.choice(sorted(item_list)) - - excluded_items.add(item_name) - - item = create_item_with_correct_settings(world.player, item_name) - - world.multiworld.push_precollected(item) - - return item - - -def get_item_pool(world: World, mission_req_table: Dict[SC2Campaign, Dict[str, MissionInfo]], - starter_items: List[Item], excluded_items: Set[str], location_cache: List[Location]) -> List[Item]: - pool: List[Item] = [] - - # For the future: goal items like Artifact Shards go here - locked_items = [] - - # YAML items - yaml_locked_items = get_option_value(world, 'locked_items') - assert not isinstance(yaml_locked_items, int) - - # Adjust generic upgrade availability based on options - include_upgrades = get_option_value(world, 'generic_upgrade_missions') == 0 - upgrade_items = get_option_value(world, 'generic_upgrade_items') - assert isinstance(upgrade_items, int) - - # Include items from outside main campaigns - item_sets = {'wol', 'hots', 'lotv'} - if get_option_value(world, 'nco_items') \ - or SC2Campaign.NCO in get_enabled_campaigns(world): - item_sets.add('nco') - if get_option_value(world, 'bw_items'): - item_sets.add('bw') - if get_option_value(world, 'ext_items'): - item_sets.add('ext') - - def allowed_quantity(name: str, data: ItemData) -> int: - if name in excluded_items \ - or data.type == "Upgrade" and (not include_upgrades or name not in upgrade_included_names[upgrade_items]) \ - or not data.origin.intersection(item_sets): - return 0 - elif name in progressive_if_nco and 'nco' not in item_sets: - return 1 - elif name in progressive_if_ext and 'ext' not in item_sets: - return 1 - else: - return data.quantity - - for name, data in get_item_table().items(): - for _ in range(allowed_quantity(name, data)): - item = create_item_with_correct_settings(world.player, name) - if name in yaml_locked_items: - locked_items.append(item) + flag_start_unit(world, item_list, starter_unit) + + flag_start_abilities(world, item_list) + + +def flag_start_unit(world: SC2World, item_list: List[FilterItem], starter_unit: int) -> None: + first_mission = get_random_first_mission(world, world.custom_mission_order) + first_race = first_mission.race + + if first_race == SC2Race.ANY: + # If the first mission is a logic-less no-build + missions = get_all_missions(world.custom_mission_order) + build_missions = [mission for mission in missions if MissionFlag.NoBuild not in mission.flags] + races = {mission.race for mission in build_missions if mission.race != SC2Race.ANY} + if races: + first_race = world.random.choice(list(races)) + + if first_race != SC2Race.ANY: + possible_starter_items = { + item.name: item for item in item_list if (ItemFilterFlags.Plando|ItemFilterFlags.UserExcluded|ItemFilterFlags.FilterExcluded) & item.flags == 0 + } + + # The race of the early unit has been chosen + basic_units = get_basic_units(world.options.required_tactics.value, first_race) + if starter_unit == StarterUnit.option_balanced: + basic_units = basic_units.difference(not_balanced_starting_units) + if first_mission == SC2Mission.DARK_WHISPERS: + # Special case - you don't have a logicless location but need an AA + basic_units = basic_units.difference( + {item_names.ZEALOT, item_names.CENTURION, item_names.SENTINEL, item_names.BLOOD_HUNTER, + item_names.AVENGER, item_names.IMMORTAL, item_names.ANNIHILATOR, item_names.VANGUARD}) + if first_mission == SC2Mission.SUDDEN_STRIKE: + # Special case - cliffjumpers + basic_units = {item_names.REAPER, item_names.GOLIATH, item_names.SIEGE_TANK, item_names.VIKING, item_names.BANSHEE} + basic_unit_options = [ + item for item in possible_starter_items.values() + if item.name in basic_units + and ItemFilterFlags.StartInventory not in item.flags + ] + + # For Sudden Strike, starter units need an upgrade to help them get around + nco_support_items = { + item_names.REAPER: item_names.REAPER_SPIDER_MINES, + item_names.GOLIATH: item_names.GOLIATH_JUMP_JETS, + item_names.SIEGE_TANK: item_names.SIEGE_TANK_JUMP_JETS, + item_names.VIKING: item_names.VIKING_SMART_SERVOS, + } + if first_mission == SC2Mission.SUDDEN_STRIKE: + basic_unit_options = [ + item for item in basic_unit_options + if item.name not in nco_support_items + or nco_support_items[item.name] in possible_starter_items + and ((ItemFilterFlags.Plando|ItemFilterFlags.UserExcluded|ItemFilterFlags.FilterExcluded) & possible_starter_items[nco_support_items[item.name]].flags) == 0 + ] + if not basic_unit_options: + raise OptionError("Early Unit: At least one basic unit must be included") + local_basic_unit = [item for item in basic_unit_options if ItemFilterFlags.NonLocal not in item.flags] + if local_basic_unit: + basic_unit_options = local_basic_unit + + unit = world.random.choice(basic_unit_options) + unit.flags |= ItemFilterFlags.StartInventory + + # NCO-only specific rules + if first_mission == SC2Mission.SUDDEN_STRIKE: + if unit.name in nco_support_items: + support_item = possible_starter_items[nco_support_items[unit.name]] + support_item.flags |= ItemFilterFlags.StartInventory + if item_names.NOVA_JUMP_SUIT_MODULE in possible_starter_items: + possible_starter_items[item_names.NOVA_JUMP_SUIT_MODULE].flags |= ItemFilterFlags.StartInventory + if MissionFlag.Nova in first_mission.flags: + possible_starter_weapons = ( + item_names.NOVA_HELLFIRE_SHOTGUN, + item_names.NOVA_PLASMA_RIFLE, + item_names.NOVA_PULSE_GRENADES, + ) + starter_weapon_options = [item for item in possible_starter_items.values() if item.name in possible_starter_weapons] + starter_weapon = world.random.choice(starter_weapon_options) + starter_weapon.flags |= ItemFilterFlags.StartInventory + + +def flag_start_abilities(world: SC2World, item_list: List[FilterItem]) -> None: + starter_abilities = world.options.start_primary_abilities + if not starter_abilities: + return + assert starter_abilities <= 4 + ability_count = int(starter_abilities) + available_abilities = item_groups.kerrigan_non_ulimates + for i in range(ability_count): + potential_starter_abilities = [ + item for item in item_list + if item.name in available_abilities + and (ItemFilterFlags.UserExcluded|ItemFilterFlags.StartInventory|ItemFilterFlags.Plando) & item.flags == 0 + ] + if len(potential_starter_abilities) == 0 or i >= 3: + # Avoid picking an ultimate unless 4 starter abilities were asked for. + # Without this check, it would be possible to pick an ultimate if a previous tier failed + # to pick due to exclusions + available_abilities = item_groups.kerrigan_abilities + potential_starter_abilities = [ + item for item in item_list + if item.name in available_abilities + and (ItemFilterFlags.UserExcluded|ItemFilterFlags.StartInventory|ItemFilterFlags.Plando) & item.flags == 0 + ] + # Try to avoid giving non-local items unless there is no alternative + abilities = [item for item in potential_starter_abilities if ItemFilterFlags.NonLocal not in item.flags] + if not abilities: + abilities = potential_starter_abilities + if abilities: + ability = world.random.choice(abilities) + ability.flags |= ItemFilterFlags.StartInventory + + +def flag_unused_upgrade_types(world: SC2World, item_list: List[FilterItem]) -> None: + """Excludes +armour/attack upgrades based on generic upgrade strategy. + Caps upgrade items based on `max_upgrade_level`.""" + include_upgrades = world.options.generic_upgrade_missions == 0 + upgrade_items = world.options.generic_upgrade_items.value + upgrade_included_counts: Dict[str, int] = {} + for item in item_list: + if item.data.type in item_tables.upgrade_item_types: + if not include_upgrades or (item.name not in upgrade_included_names[upgrade_items]): + item.flags |= ItemFilterFlags.Removed else: - pool.append(item) - - existing_items = starter_items + [item for item in world.multiworld.precollected_items[world.player] if item not in starter_items] - existing_names = [item.name for item in existing_items] - - # Check the parent item integrity, exclude items - pool[:] = [item for item in pool if pool_contains_parent(item, pool + locked_items + existing_items)] - - # Removing upgrades for excluded items - for item_name in excluded_items: - if item_name in existing_names: - continue - invalid_upgrades = get_item_upgrades(pool, item_name) - for invalid_upgrade in invalid_upgrades: - pool.remove(invalid_upgrade) - - fill_pool_with_kerrigan_levels(world, pool) - filtered_pool = filter_items(world, mission_req_table, location_cache, pool, existing_items, locked_items) - return filtered_pool - - -def fill_item_pool_with_dummy_items(self: SC2World, locked_locations: List[str], - location_cache: List[Location], pool: List[Item]): - for _ in range(len(location_cache) - len(locked_locations) - len(pool)): - item = create_item_with_correct_settings(self.player, self.get_filler_item_name()) - pool.append(item) - - -def create_item_with_correct_settings(player: int, name: str) -> Item: - data = get_full_item_list()[name] - - item = Item(name, data.classification, data.code, player) - - return item - + included = upgrade_included_counts.get(item.name, 0) + if ( + included >= world.options.max_upgrade_level + and not (ItemFilterFlags.Locked|ItemFilterFlags.StartInventory) & item.flags + ): + item.flags |= ItemFilterFlags.FilterExcluded + elif ItemFilterFlags.UserExcluded not in item.flags: + upgrade_included_counts[item.name] = included + 1 + +def flag_unreleased_items(item_list: List[FilterItem]) -> None: + """Remove all unreleased items unless they're explicitly locked""" + for item in item_list: + if (item.name in unreleased_items + and not (ItemFilterFlags.Locked|ItemFilterFlags.StartInventory) & item.flags): + item.flags |= ItemFilterFlags.Removed + + +def flag_user_excluded_item_sets(world: SC2World, item_list: List[FilterItem]) -> None: + """Excludes items based on item set options (`only_vanilla_items`)""" + vanilla_nonprogressive_count = { + item_name: 0 for item_name in item_groups.terran_original_progressive_upgrades + } + if world.options.vanilla_items_only.value == VanillaItemsOnly.option_true: + vanilla_items = item_groups.vanilla_items + item_groups.nova_equipment + for item in item_list: + if ItemFilterFlags.UserExcluded in item.flags: + continue + if item.name not in vanilla_items: + item.flags |= ItemFilterFlags.UserExcluded + if item.name in item_groups.terran_original_progressive_upgrades: + if vanilla_nonprogressive_count[item.name]: + item.flags |= ItemFilterFlags.UserExcluded + vanilla_nonprogressive_count[item.name] += 1 + + excluded_count: Dict[str, int] = dict() + + +def flag_war_council_items(world: SC2World, item_list: List[FilterItem]) -> None: + """Excludes / start-inventories items based on `nerf_unit_baselines` option. + Will skip items that are excluded by other sources.""" + if world.options.war_council_nerfs: + return -def pool_contains_parent(item: Item, pool: Iterable[Item]): - item_data = get_full_item_list().get(item.name) - if item_data.parent_item is None: - # The item has not associated parent, the item is valid - return True - parent_item = item_data.parent_item - # Check if the pool contains the parent item - return parent_item in [pool_item.name for pool_item in pool] + flagged_item_names = [] + for item in item_list: + if ( + item.name in war_council_upgrades + and not ItemFilterFlags.Excluded & item.flags + and item.name not in flagged_item_names + ): + flagged_item_names.append(item.name) + item.flags |= ItemFilterFlags.StartInventory -def fill_resource_locations(world: World, locked_locations: List[str], location_cache: List[Location]): +def flag_and_add_resource_locations(world: SC2World, item_list: List[FilterItem]) -> None: """ Filters the locations in the world using a trash or Nothing item - :param multiworld: - :param player: - :param locked_locations: - :param location_cache: - :return: + :param world: The sc2 world object + :param item_list: The current list of items to append to """ - open_locations = [location for location in location_cache if location.item is None] + open_locations = [location for location in world.location_cache if location.item is None] plando_locations = get_plando_locations(world) - resource_location_types = get_location_types(world, LocationInclusion.option_resources) - location_data = {sc2_location.name: sc2_location for sc2_location in get_locations(world)} + filler_location_types = get_location_types(world, LocationInclusion.option_filler) + filler_location_flags = get_location_flags(world, LocationInclusion.option_filler) + location_data = {sc2_location.name: sc2_location for sc2_location in DEFAULT_LOCATION_LIST} for location in open_locations: # Go through the locations that aren't locked yet (early unit, etc) if location.name not in plando_locations: # The location is not plando'd sc2_location = location_data[location.name] - if sc2_location.type in resource_location_types: - item_name = world.random.choice(filler_items) + if (sc2_location.type in filler_location_types + or (sc2_location.flags & filler_location_flags) + ): + item_name = world.get_filler_item_name() item = create_item_with_correct_settings(world.player, item_name) + if item.classification & ItemClassification.progression: + # Scouting shall show Filler (or a trap) + item.classification = ItemClassification.filler location.place_locked_item(item) - locked_locations.append(location.name) + world.locked_locations.append(location.name) + + +def flag_mission_order_required_items(world: SC2World, item_list: List[FilterItem]) -> None: + """Marks items that are necessary for item rules in the mission order and forces them to be progression.""" + locks_required = world.custom_mission_order.get_items_to_lock() + locks_done = {item: 0 for item in locks_required} + for item in item_list: + if item.name in locks_required and locks_done[item.name] < locks_required[item.name]: + item.flags |= ItemFilterFlags.Locked + item.flags |= ItemFilterFlags.ForceProgression + locks_done[item.name] += 1 + + +def prune_item_pool(world: SC2World, item_list: List[FilterItem]) -> List[StarcraftItem]: + """Prunes the item pool size to be less than the number of available locations""" + + item_list = [ + item for item in item_list + if (ItemFilterFlags.Removed not in item.flags) + and (ItemFilterFlags.Unexcludable & item.flags or ItemFilterFlags.FilterExcluded not in item.flags) + ] + num_items = len(item_list) + last_num_items = -1 + while num_items != last_num_items: + # Remove orphan items until there are no more being removed + item_name_list = [item.name for item in item_list] + item_list = [item for item in item_list + if (ItemFilterFlags.Unexcludable|ItemFilterFlags.AllowedOrphan) & item.flags + or item_list_contains_parent(world, item.data, item_name_list)] + last_num_items = num_items + num_items = len(item_list) + + pool: List[StarcraftItem] = [] + for item in item_list: + ap_item = create_item_with_correct_settings(world.player, item.name, item.flags) + if ItemFilterFlags.ForceProgression in item.flags: + ap_item.classification = ItemClassification.progression + pool.append(ap_item) + + fill_pool_with_kerrigan_levels(world, pool) + filtered_pool = filter_items(world, world.location_cache, pool) + return filtered_pool + + +def item_list_contains_parent(world: SC2World, item_data: ItemData, item_name_list: List[str]) -> bool: + if item_data.parent is None: + # The item has no associated parent, the item is valid + return True + return item_parents.parent_present[item_data.parent](item_name_list, world.options) + + +def pad_item_pool_with_filler(world: SC2World, num_items: int, pool: List[StarcraftItem]): + for _ in range(num_items): + item = create_item_with_correct_settings(world.player, world.get_filler_item_name()) + pool.append(item) + + +def set_up_filler_items_distribution(world: SC2World) -> None: + world.filler_items_distribution = world.options.filler_items_distribution.value.copy() + prune_fillers(world) + if sum(world.filler_items_distribution.values()) == 0: + world.filler_items_distribution = FillerItemsDistribution.default.copy() + prune_fillers(world) + + +def prune_fillers(world): + mission_flags = world.custom_mission_order.get_used_flags() + include_protoss = ( + MissionFlag.Protoss in mission_flags + or (world.options.take_over_ai_allies and (MissionFlag.AiProtossAlly in mission_flags)) + ) + include_kerrigan = ( + MissionFlag.Kerrigan in mission_flags + and world.options.kerrigan_presence in kerrigan_unit_available + ) + generic_upgrade_research = world.options.generic_upgrade_research + if not include_protoss: + world.filler_items_distribution.pop(item_names.SHIELD_REGENERATION, 0) + if not include_kerrigan: + world.filler_items_distribution.pop(item_names.KERRIGAN_LEVELS_1, 0) + if (generic_upgrade_research in + [ + GenericUpgradeResearch.option_always_auto, + GenericUpgradeResearch.option_auto_in_build + ] + ): + world.filler_items_distribution.pop(item_names.UPGRADE_RESEARCH_SPEED, 0) + world.filler_items_distribution.pop(item_names.UPGRADE_RESEARCH_COST, 0) + + +def get_random_first_mission(world: SC2World, mission_order: SC2MissionOrder) -> SC2Mission: + # Pick an arbitrary lowest-difficulty starer mission + starting_missions = mission_order.get_starting_missions() + mission_difficulties = [ + (mission_order.mission_pools.get_modified_mission_difficulty(mission), mission) + for mission in starting_missions + ] + mission_difficulties.sort(key = lambda difficulty_mission_tuple: difficulty_mission_tuple[0]) + (lowest_difficulty, _) = mission_difficulties[0] + first_mission_candidates = [mission for (difficulty, mission) in mission_difficulties if difficulty == lowest_difficulty] + return world.random.choice(first_mission_candidates) + + +def get_all_missions(mission_order: SC2MissionOrder) -> List[SC2Mission]: + return mission_order.get_used_missions() + + +def create_item_with_correct_settings(player: int, name: str, filter_flags: ItemFilterFlags = ItemFilterFlags.Available) -> StarcraftItem: + data = item_tables.item_table[name] + + item = StarcraftItem(name, data.classification, data.code, player, filter_flags) + if ItemFilterFlags.ForceProgression & filter_flags: + item.classification = ItemClassification.progression -def place_exclusion_item(item_name, location, locked_locations, player): - item = create_item_with_correct_settings(player, item_name) - location.place_locked_item(item) - locked_locations.append(location.name) + return item -def fill_pool_with_kerrigan_levels(world: World, item_pool: List[Item]): - total_levels = get_option_value(world, "kerrigan_level_item_sum") - if get_option_value(world, "kerrigan_presence") not in kerrigan_unit_available \ - or total_levels == 0 \ - or SC2Campaign.HOTS not in get_enabled_campaigns(world): +def fill_pool_with_kerrigan_levels(world: SC2World, item_pool: List[StarcraftItem]): + total_levels = world.options.kerrigan_level_item_sum.value + missions = get_all_missions(world.custom_mission_order) + kerrigan_missions = [mission for mission in missions if MissionFlag.Kerrigan in mission.flags] + kerrigan_build_missions = [mission for mission in kerrigan_missions if MissionFlag.NoBuild not in mission.flags] + if (world.options.kerrigan_presence.value not in kerrigan_unit_available + or total_levels == 0 + or not kerrigan_missions + or (world.options.grant_story_levels and not kerrigan_build_missions) + ): return def add_kerrigan_level_items(level_amount: int, item_amount: int): @@ -468,7 +1033,7 @@ def add_kerrigan_level_items(level_amount: int, item_amount: int): item_pool.append(create_item_with_correct_settings(world.player, name)) sizes = [70, 35, 14, 10, 7, 5, 2, 1] - option = get_option_value(world, "kerrigan_level_item_distribution") + option = world.options.kerrigan_level_item_distribution.value assert isinstance(option, int) assert isinstance(total_levels, int) @@ -489,3 +1054,17 @@ def add_kerrigan_level_items(level_amount: int, item_amount: int): else: round_func = ceil add_kerrigan_level_items(size, round_func(float(total_levels) / size)) + + +def push_precollected_items_to_multiworld(world: SC2World, item_list: List[StarcraftItem]) -> None: + # Clear the pre-collected items, as AP will try to do this for us, + # and we want to be able to filer out precollected items in the case of upgrade packages. + auto_precollected_items = world.multiworld.precollected_items[world.player].copy() + world.multiworld.precollected_items[world.player].clear() + for item in auto_precollected_items: + world.multiworld.state.remove(item) + + for item in item_list: + if ItemFilterFlags.StartInventory not in item.filter_flags: + continue + world.multiworld.push_precollected(create_item_with_correct_settings(world.player, item.name, item.filter_flags)) diff --git a/worlds/sc2/client.py b/worlds/sc2/client.py new file mode 100644 index 000000000000..d64d44aea1f9 --- /dev/null +++ b/worlds/sc2/client.py @@ -0,0 +1,2352 @@ +from __future__ import annotations + +import asyncio +import collections +import copy +import ctypes +import enum +import functools +import inspect +import logging +import multiprocessing +import os.path +import re +import sys +import tempfile +import typing +import queue +import zipfile +import io +import random +import concurrent.futures +import time +import uuid +from pathlib import Path + +# CommonClient import first to trigger ModuleUpdater +from CommonClient import CommonContext, server_loop, ClientCommandProcessor, gui_enabled, get_base_parser +from Utils import init_logging, is_windows, async_start +from .item import item_names, item_parents, race_to_item_type +from .item.item_annotations import ITEM_NAME_ANNOTATIONS +from .item.item_groups import item_name_groups, unlisted_item_name_groups, ItemGroupNames +from . import options, VICTORY_MODULO +from .options import ( + MissionOrder, KerriganPrimalStatus, kerrigan_unit_available, KerriganPresence, EnableMorphling, GameDifficulty, + GameSpeed, GenericUpgradeItems, GenericUpgradeResearch, ColorChoice, GenericUpgradeMissions, MaxUpgradeLevel, + LocationInclusion, ExtraLocations, MasteryLocations, SpeedrunLocations, PreventativeLocations, ChallengeLocations, + VanillaLocations, + DisableForcedCamera, SkipCutscenes, GrantStoryTech, GrantStoryLevels, TakeOverAIAllies, RequiredTactics, + SpearOfAdunPresence, SpearOfAdunPresentInNoBuild, SpearOfAdunPassiveAbilityPresence, + SpearOfAdunPassivesPresentInNoBuild, EnableVoidTrade, VoidTradeAgeLimit, void_trade_age_limits_ms, VoidTradeWorkers, + DifficultyDamageModifier, MissionOrderScouting, GenericUpgradeResearchSpeedup, MercenaryHighlanders, WarCouncilNerfs, + is_mission_in_soa_presence, +) +from .mission_order.slot_data import CampaignSlotData, LayoutSlotData, MissionSlotData, MissionOrderObjectSlotData +from .mission_order.entry_rules import SubRuleRuleData, CountMissionsRuleData, MissionEntryRules +from .mission_tables import MissionFlag +from .transfer_data import normalized_unit_types, worker_units +from . import SC2World + + +if __name__ == "__main__": + init_logging("SC2Client", exception_logger="Client") + +logger = logging.getLogger("Client") +sc2_logger = logging.getLogger("Starcraft2") + +import nest_asyncio +from worlds._sc2common import bot +from worlds._sc2common.bot.data import Race +from worlds._sc2common.bot.main import run_game +from worlds._sc2common.bot.player import Bot +from .item.item_tables import ( + lookup_id_to_name, get_full_item_list, ItemData, + ZergItemType, upgrade_bundles, + WEAPON_ARMOR_UPGRADE_MAX_LEVEL, +) +from .locations import SC2WOL_LOC_ID_OFFSET, LocationType, LocationFlag, SC2HOTS_LOC_ID_OFFSET, VICTORY_CACHE_OFFSET +from .mission_tables import ( + lookup_id_to_mission, SC2Campaign, MissionInfo, + lookup_id_to_campaign, SC2Mission, campaign_mission_table, SC2Race +) + +import colorama +from .options import Option, upgrade_included_names +from NetUtils import ClientStatus, NetworkItem, JSONtoTextParser, JSONMessagePart, add_json_item, add_json_location, add_json_text, JSONTypes +from MultiServer import mark_raw + +pool = concurrent.futures.ThreadPoolExecutor(1) +loop = asyncio.get_event_loop_policy().new_event_loop() +nest_asyncio.apply(loop) +MAX_BONUS: int = 28 + +# GitHub repo where the Map/mod data is hosted for /download_data command +DATA_REPO_OWNER = "Ziktofel" +DATA_REPO_NAME = "Archipelago-SC2-data" +DATA_API_VERSION = "API4" + +# Bot controller +CONTROLLER_HEALTH: int = 38281 +CONTROLLER2_HEALTH: int = 38282 + +# Void Trade +TRADE_UNIT = "AP_TradeStructure" # ID of the unit +TRADE_SEND_BUTTON = "AP_TradeStructureDummySend" # ID of the button +TRADE_RECEIVE_1_BUTTON = "AP_TradeStructureDummyReceive" # ID of the button +TRADE_RECEIVE_5_BUTTON = "AP_TradeStructureDummyReceive5" # ID of the button +TRADE_DATASTORAGE_TEAM = "SC2_VoidTrade_" # + Team +TRADE_DATASTORAGE_SLOT = "slot_" # + Slot +TRADE_DATASTORAGE_LOCK = "_lock" +TRADE_LOCK_TIME = 5 # Time in seconds that the DataStorage may be considered safe to edit +TRADE_LOCK_WAIT_LIMIT = 540000 / 1.4 # Time in ms that the client may spend trying to get a lock (540000 = 9 minutes, 1.4 is 'faster' game speed's time scale) + +# Games +STARCRAFT2 = "Starcraft 2" +STARCRAFT2_WOL = "Starcraft 2 Wings of Liberty" + + +# Data version file path. +# This file is used to tell if the downloaded data are outdated +# Associated with /download_data command +def get_metadata_file() -> str: + return os.environ["SC2PATH"] + os.sep + "ArchipelagoSC2Metadata.txt" + + +def _remap_color_option(slot_data_version: int, color: int) -> int: + """Remap colour options for backwards compatibility with older slot data""" + if slot_data_version < 4 and color == ColorChoice.option_mengsk: + return ColorChoice.option_default + return color + + +class ConfigurableOptionType(enum.Enum): + INTEGER = enum.auto() + ENUM = enum.auto() + +class ConfigurableOptionInfo(typing.NamedTuple): + name: str + variable_name: str + option_class: typing.Type[Option] + option_type: ConfigurableOptionType = ConfigurableOptionType.ENUM + can_break_logic: bool = False + + +class ColouredMessage: + def __init__(self, text: str = '', *, keep_markup: bool = False) -> None: + self.parts: typing.List[dict] = [] + if text: + self(text, keep_markup=keep_markup) + def __call__(self, text: str, *, keep_markup: bool = False) -> 'ColouredMessage': + add_json_text(self.parts, text, keep_markup=keep_markup) + return self + def coloured(self, text: str, colour: str, *, keep_markup: bool = False) -> 'ColouredMessage': + add_json_text(self.parts, text, type="color", color=colour, keep_markup=keep_markup) + return self + def location(self, location_id: int, player_id: int) -> 'ColouredMessage': + add_json_location(self.parts, location_id, player_id) + return self + def item(self, item_id: int, player_id: int, flags: int = 0) -> 'ColouredMessage': + add_json_item(self.parts, item_id, player_id, flags) + return self + def player(self, player_id: int) -> 'ColouredMessage': + add_json_text(self.parts, str(player_id), type=JSONTypes.player_id) + return self + def send(self, ctx: SC2Context) -> None: + ctx.on_print_json({"data": self.parts, "cmd": "PrintJSON"}) + + +class StarcraftClientProcessor(ClientCommandProcessor): + ctx: SC2Context + + def formatted_print(self, text: str) -> None: + """Prints with kivy formatting to the GUI, and also prints to command-line and to all logs""" + # Note(mm): Bold/underline can help readability, but unfortunately the CommonClient does not filter bold tags from command-line output. + # Regardless, using `on_print_json` to get formatted text in the GUI and output in the command-line and in the logs, + # without having to branch code from CommonClient + self.ctx.on_print_json({"data": [{"text": text, "keep_markup": True}]}) + + def _cmd_difficulty(self, difficulty: str = "") -> bool: + """Overrides the current difficulty set for the world. Takes the argument casual, normal, hard, or brutal""" + arguments = difficulty.split() + num_arguments = len(arguments) + + if num_arguments > 0: + difficulty_choice = arguments[0].lower() + if difficulty_choice == "casual": + self.ctx.difficulty_override = 0 + elif difficulty_choice == "normal": + self.ctx.difficulty_override = 1 + elif difficulty_choice == "hard": + self.ctx.difficulty_override = 2 + elif difficulty_choice == "brutal": + self.ctx.difficulty_override = 3 + else: + self.output("Unable to parse difficulty '" + arguments[0] + "'") + return False + + self.output("Difficulty set to " + arguments[0]) + return True + + else: + if self.ctx.difficulty == -1: + self.output("Please connect to a seed before checking difficulty.") + else: + current_difficulty = self.ctx.difficulty + if self.ctx.difficulty_override >= 0: + current_difficulty = self.ctx.difficulty_override + self.output("Current difficulty: " + ["Casual", "Normal", "Hard", "Brutal"][current_difficulty]) + self.output("To change the difficulty, add the name of the difficulty after the command.") + return False + + + def _cmd_game_speed(self, game_speed: str = "") -> bool: + """Overrides the current game speed for the world. + Takes the arguments default, slower, slow, normal, fast, faster""" + arguments = game_speed.split() + num_arguments = len(arguments) + + if num_arguments > 0: + speed_choice = arguments[0].lower() + if speed_choice == "default": + self.ctx.game_speed_override = 0 + elif speed_choice == "slower": + self.ctx.game_speed_override = 1 + elif speed_choice == "slow": + self.ctx.game_speed_override = 2 + elif speed_choice == "normal": + self.ctx.game_speed_override = 3 + elif speed_choice == "fast": + self.ctx.game_speed_override = 4 + elif speed_choice == "faster": + self.ctx.game_speed_override = 5 + else: + self.output("Unable to parse game speed '" + arguments[0] + "'") + return False + + self.output("Game speed set to " + arguments[0]) + return True + + else: + if self.ctx.game_speed == -1: + self.output("Please connect to a seed before checking game speed.") + else: + current_speed = self.ctx.game_speed + if self.ctx.game_speed_override >= 0: + current_speed = self.ctx.game_speed_override + self.output("Current game speed: " + + ["Default", "Slower", "Slow", "Normal", "Fast", "Faster"][current_speed]) + self.output("To change the game speed, add the name of the speed after the command," + " or Default to select based on difficulty.") + return False + + @mark_raw + def _cmd_received(self, filter_search: str = "") -> bool: + """List received items. + Pass in a parameter to filter the search by partial item name or exact item group. + Use '/received recent ' to list the last 'number' items received (default 20).""" + if self.ctx.slot is None: + self.formatted_print("Connect to a slot to view what items are received.") + return True + if filter_search.casefold().startswith('recent'): + return self._received_recent(filter_search[len('recent'):].strip()) + # Groups must be matched case-sensitively, so we properly capitalize the search term + # eg. "Spear of Adun" over "Spear Of Adun" or "spear of adun" + # This fails a lot of item name matches, but those should be found by partial name match + group_filter = '' + for group_name in item_name_groups: + if group_name in unlisted_item_name_groups: + continue + if filter_search.casefold() == group_name.casefold(): + group_filter = group_name + break + + def item_matches_filter(item_name: str) -> bool: + # The filter can be an exact group name or a partial item name + # Partial item name can be matched case-insensitively + if filter_search.casefold() in item_name.casefold(): + return True + # The search term should already be formatted as a group name + if group_filter and item_name in item_name_groups[group_filter]: + return True + return False + + items = get_full_item_list() + categorized_items: typing.Dict[SC2Race, typing.List[typing.Union[int, str]]] = {} + parent_to_child: typing.Dict[typing.Union[int, str], typing.List[int]] = {} + items_received: typing.Dict[int, typing.List[NetworkItem]] = {} + for item in self.ctx.items_received: + items_received.setdefault(item.item, []).append(item) + items_received_set = set(items_received) + for item_data in items.values(): + if item_data.parent: + parent_rule = item_parents.parent_present[item_data.parent] + if parent_rule.constraint_group is not None and parent_rule.constraint_group in items: + parent_to_child.setdefault(items[parent_rule.constraint_group].code, []).append(item_data.code) + continue + race = items[parent_rule.parent_items()[0]].race + categorized_items.setdefault(race, []) + if parent_rule.display_string not in categorized_items[race]: + categorized_items[race].append(parent_rule.display_string) + parent_to_child.setdefault(parent_rule.display_string, []).append(item_data.code) + else: + categorized_items.setdefault(item_data.race, []).append(item_data.code) + + def display_info(element: typing.Union[SC2Race, str, int]) -> tuple: + """Return (should display, name, type, children, sum(obtained), sum(matching filter))""" + have_item = isinstance(element, int) and element in items_received_set + if isinstance(element, SC2Race): + children: typing.Sequence[typing.Union[str, int]] = categorized_items[faction] + name = element.name + elif isinstance(element, int): + children = parent_to_child.get(element, []) + name = self.ctx.item_names.lookup_in_game(element) + else: + assert isinstance(element, str) + children = parent_to_child[element] + name = element + matches_filter = item_matches_filter(name) + child_states = [display_info(child) for child in children] + return ( + (have_item and matches_filter) or any(child_state[0] for child_state in child_states), + name, + element, + child_states, + sum(child_state[4] for child_state in child_states) + have_item, + sum(child_state[5] for child_state in child_states) + (have_item and matches_filter), + ) + + def display_tree( + should_display: bool, name: str, element: typing.Union[SC2Race, str, int], child_states: tuple, indent: int = 0 + ) -> None: + if not should_display: + return + assert self.ctx.slot is not None + indent_str = " " * indent + if isinstance(element, SC2Race): + self.formatted_print(f" [u]{name}[/u] ") + for child in child_states: + display_tree(*child[:4]) + elif isinstance(element, str): + ColouredMessage(indent_str)("- ").coloured(name, "white").send(self.ctx) + for child in child_states: + display_tree(*child[:4], indent=indent+2) + elif isinstance(element, int): + items = items_received.get(element, []) + if not items: + ColouredMessage(indent_str)("- ").coloured(name, "red")(" - not obtained").send(self.ctx) + for item in items: + (ColouredMessage(indent_str)('- ') + .item(item.item, self.ctx.slot, flags=item.flags) + (" from ").location(item.location, item.player) + (" by ").player(item.player) + ).send(self.ctx) + for child in child_states: + display_tree(*child[:4], indent=indent+2) + non_matching_descendents = sum(child[5] - child[4] for child in children) + if non_matching_descendents > 0: + self.formatted_print(f"{indent_str} + {non_matching_descendents} child items that don't match the filter") + + + item_types_obtained = 0 + items_obtained_matching_filter = 0 + for faction in SC2Race: + should_display, name, element, children, faction_items_obtained, faction_items_matching_filter = display_info(faction) + item_types_obtained += faction_items_obtained + items_obtained_matching_filter += faction_items_matching_filter + display_tree(should_display, name, element, children) + if filter_search == "": + self.formatted_print(f"[b]Obtained: {len(self.ctx.items_received)} items ({item_types_obtained} types)[/b]") + else: + self.formatted_print(f"[b]Filter \"{filter_search}\" found {items_obtained_matching_filter} out of {item_types_obtained} obtained item types[/b]") + return True + + def _received_recent(self, amount: str) -> bool: + assert self.ctx.slot is not None + try: + display_amount = int(amount) + except ValueError: + display_amount = 20 + display_amount = min(display_amount, len(self.ctx.items_received)) + self.formatted_print(f"Last {display_amount} of {len(self.ctx.items_received)} items received (most recent last):") + for item in self.ctx.items_received[-display_amount:]: + ( + ColouredMessage() + .item(item.item, self.ctx.slot, item.flags) + (" from ").location(item.location, item.player) + (" by ").player(item.player) + ).send(self.ctx) + return True + + def _cmd_option(self, option_name: str = "", option_value: str = "") -> None: + """Sets a Starcraft game option that can be changed after generation. Use "/option list" to see all options.""" + + LOGIC_WARNING = " *Note changing this may result in logically unbeatable games*\n" + + configurable_options = ( + ConfigurableOptionInfo('speed', 'game_speed', options.GameSpeed), + ConfigurableOptionInfo('kerrigan_presence', 'kerrigan_presence', options.KerriganPresence, can_break_logic=True), + ConfigurableOptionInfo('kerrigan_level_cap', 'kerrigan_total_level_cap', options.KerriganTotalLevelCap, ConfigurableOptionType.INTEGER, can_break_logic=True), + ConfigurableOptionInfo('kerrigan_mission_level_cap', 'kerrigan_levels_per_mission_completed_cap', options.KerriganLevelsPerMissionCompletedCap, ConfigurableOptionType.INTEGER), + ConfigurableOptionInfo('kerrigan_levels_per_mission', 'kerrigan_levels_per_mission_completed', options.KerriganLevelsPerMissionCompleted, ConfigurableOptionType.INTEGER), + ConfigurableOptionInfo('grant_story_levels', 'grant_story_levels', options.GrantStoryLevels, can_break_logic=True), + ConfigurableOptionInfo('grant_story_tech', 'grant_story_tech', options.GrantStoryTech, can_break_logic=True), + ConfigurableOptionInfo('control_ally', 'take_over_ai_allies', options.TakeOverAIAllies, can_break_logic=True), + ConfigurableOptionInfo('soa_presence', 'spear_of_adun_presence', options.SpearOfAdunPresence, can_break_logic=True), + ConfigurableOptionInfo('soa_in_nobuilds', 'spear_of_adun_present_in_no_build', options.SpearOfAdunPresentInNoBuild, can_break_logic=True), + # Note(mm): Technically SOA passive presence is in the logic for Amon's Fall if Takeover AI Allies is true, + # but that's edge case enough I don't think we should warn about it. + ConfigurableOptionInfo('soa_passive_presence', 'spear_of_adun_passive_ability_presence', options.SpearOfAdunPassiveAbilityPresence), + ConfigurableOptionInfo('soa_passives_in_nobuilds', 'spear_of_adun_passive_present_in_no_build', options.SpearOfAdunPassivesPresentInNoBuild), + ConfigurableOptionInfo('max_upgrade_level', 'max_upgrade_level', options.MaxUpgradeLevel, ConfigurableOptionType.INTEGER), + ConfigurableOptionInfo('generic_upgrade_research', 'generic_upgrade_research', options.GenericUpgradeResearch), + ConfigurableOptionInfo('generic_upgrade_research_speedup', 'generic_upgrade_research_speedup', options.GenericUpgradeResearchSpeedup), + ConfigurableOptionInfo('minerals_per_item', 'minerals_per_item', options.MineralsPerItem, ConfigurableOptionType.INTEGER), + ConfigurableOptionInfo('gas_per_item', 'vespene_per_item', options.VespenePerItem, ConfigurableOptionType.INTEGER), + ConfigurableOptionInfo('supply_per_item', 'starting_supply_per_item', options.StartingSupplyPerItem, ConfigurableOptionType.INTEGER), + ConfigurableOptionInfo('max_supply_per_item', 'maximum_supply_per_item', options.MaximumSupplyPerItem, ConfigurableOptionType.INTEGER), + ConfigurableOptionInfo('reduced_supply_per_item', 'maximum_supply_reduction_per_item', options.MaximumSupplyReductionPerItem, ConfigurableOptionType.INTEGER), + ConfigurableOptionInfo('lowest_max_supply', 'lowest_maximum_supply', options.LowestMaximumSupply, ConfigurableOptionType.INTEGER), + ConfigurableOptionInfo('research_cost_per_item', 'research_cost_reduction_per_item', options.ResearchCostReductionPerItem, ConfigurableOptionType.INTEGER), + ConfigurableOptionInfo('no_forced_camera', 'disable_forced_camera', options.DisableForcedCamera), + ConfigurableOptionInfo('skip_cutscenes', 'skip_cutscenes', options.SkipCutscenes), + ConfigurableOptionInfo('enable_morphling', 'enable_morphling', options.EnableMorphling, can_break_logic=True), + ConfigurableOptionInfo('difficulty_damage_modifier', 'difficulty_damage_modifier', options.DifficultyDamageModifier), + ConfigurableOptionInfo('void_trade_age_limit', 'trade_age_limit', options.VoidTradeAgeLimit), + ConfigurableOptionInfo('void_trade_workers', 'trade_workers_allowed', options.VoidTradeWorkers), + ConfigurableOptionInfo('mercenary_highlanders', 'mercenary_highlanders', options.MercenaryHighlanders), + ) + + WARNING_COLOUR = "salmon" + CMD_COLOUR = "slateblue" + boolean_option_map = { + 'y': 'true', 'yes': 'true', 'n': 'false', 'no': 'false', 'true': 'true', 'false': 'false', + } + + help_message = ColouredMessage(inspect.cleandoc(""" + Options + -------------------- + """))('\n') + for option in configurable_options: + option_help_text = inspect.cleandoc(option.option_class.__doc__ or "No description provided.").split('\n', 1)[0] + help_message.coloured(option.name, CMD_COLOUR)(": " + " | ".join(option.option_class.options) + + f" -- {option_help_text}\n") + if option.can_break_logic: + help_message.coloured(LOGIC_WARNING, WARNING_COLOUR) + help_message("--------------------\nEnter an option without arguments to see its current value.\n") + + if not option_name or option_name == 'list' or option_name == 'help': + help_message.send(self.ctx) + return + for option in configurable_options: + if option_name == option.name: + option_value = boolean_option_map.get(option_value.lower(), option_value) + if not option_value: + pass + elif option.option_type == ConfigurableOptionType.ENUM and option_value in option.option_class.options: + self.ctx.__dict__[option.variable_name] = option.option_class.options[option_value] + elif option.option_type == ConfigurableOptionType.INTEGER: + try: + self.ctx.__dict__[option.variable_name] = int(option_value, base=0) + except: + self.output(f"{option_value} is not a valid integer") + else: + self.output(f"Unknown option value '{option_value}'") + ColouredMessage(f"{option.name} is '{option.option_class.get_option_name(self.ctx.__dict__[option.variable_name])}'").send(self.ctx) + break + else: + self.output(f"Unknown option '{option_name}'") + help_message.send(self.ctx) + + def _cmd_color(self, faction: str = "", color: str = "") -> None: + """Changes the player color for a given faction.""" + player_colors = [ + "White", "Red", "Blue", "Teal", + "Purple", "Yellow", "Orange", "Green", + "LightPink", "Violet", "LightGrey", "DarkGreen", + "Brown", "LightGreen", "DarkGrey", "Pink", + "Rainbow", "Mengsk", "BrightLime", "Arcane", "Ember", "HotPink", + "Random", "Default" + ] + var_names = { + 'raynor': 'player_color_raynor', + 'kerrigan': 'player_color_zerg', + 'primal': 'player_color_zerg_primal', + 'protoss': 'player_color_protoss', + 'nova': 'player_color_nova', + } + faction = faction.lower() + if not faction: + for faction_name, key in var_names.items(): + self.output(f"Current player color for {faction_name}: {player_colors[self.ctx.__dict__[key]]}") + self.output("To change your color, add the faction name and color after the command.") + self.output("Available factions: " + ', '.join(var_names)) + self.output("Available colors: " + ', '.join(player_colors)) + return + elif faction not in var_names: + self.output(f"Unknown faction '{faction}'.") + self.output("Available factions: " + ', '.join(var_names)) + return + match_colors = [player_color.lower() for player_color in player_colors] + if not color: + self.output(f"Current player color for {faction}: {player_colors[self.ctx.__dict__[var_names[faction]]]}") + self.output("To change this faction's colors, add the name of the color after the command.") + self.output("Available colors: " + ', '.join(player_colors)) + else: + if color.lower() not in match_colors: + self.output(color + " is not a valid color. Available colors: " + ', '.join(player_colors)) + return + if color.lower() == "random": + color = random.choice(player_colors[:-2]) + self.ctx.__dict__[var_names[faction]] = match_colors.index(color.lower()) + self.ctx.pending_color_update = True + self.output(f"Color for {faction} set to " + player_colors[self.ctx.__dict__[var_names[faction]]]) + + def _cmd_windowed_mode(self, value="") -> None: + """Controls whether sc2 will launch in Windowed mode. Persists across sessions.""" + if not value: + sc2_logger.info("Use `/windowed_mode [true|false]` to set the windowed mode") + elif value.casefold() in ('t', 'true', 'yes', 'y'): + SC2World.settings.game_windowed_mode = True + force_settings_save_on_close() + else: + SC2World.settings.game_windowed_mode = False + force_settings_save_on_close() + sc2_logger.info(f"Windowed mode is: {SC2World.settings.game_windowed_mode}") + + def _cmd_disable_mission_check(self) -> bool: + """Disables the check to see if a mission is available to play. Meant for co-op runs where one player can play + the next mission in a chain the other player is doing.""" + self.ctx.missions_unlocked = True + sc2_logger.info("Mission check has been disabled") + return True + + @mark_raw + def _cmd_set_path(self, path: str = '') -> bool: + """Manually set the SC2 install directory (if the automatic detection fails).""" + if path: + os.environ["SC2PATH"] = path + is_mod_installed_correctly() + return True + else: + sc2_logger.warning("When using set_path, you must type the path to your SC2 install directory.") + return False + + def _cmd_download_data(self) -> bool: + """Download the most recent release of the necessary files for playing SC2 with + Archipelago. Will overwrite existing files.""" + pool.submit(self._download_data, self.ctx) + return True + + @staticmethod + def _download_data(ctx: SC2Context) -> bool: + if "SC2PATH" not in os.environ: + check_game_install_path() + + if os.path.exists(get_metadata_file()): + with open(get_metadata_file(), "r") as f: + metadata = f.read() + else: + metadata = None + + tempzip, metadata = download_latest_release_zip( + DATA_REPO_OWNER, DATA_REPO_NAME, DATA_API_VERSION, metadata=metadata, force_download=True) + + if tempzip: + try: + zipfile.ZipFile(tempzip).extractall(path=os.environ["SC2PATH"]) + sc2_logger.info("Download complete. Package installed.") + if metadata is not None: + with open(get_metadata_file(), "w") as f: + f.write(metadata) + finally: + os.remove(tempzip) + else: + sc2_logger.warning("Download aborted/failed. Read the log for more information.") + return False + ctx.data_out_of_date = False + return True + + +class SC2JSONtoTextParser(JSONtoTextParser): + def __init__(self, ctx: SC2Context) -> None: + self.handlers = { + "ItemSend": self._handle_color, + "ItemCheat": self._handle_color, + "Hint": self._handle_color, + } + super().__init__(ctx) + + def _handle_color(self, node: JSONMessagePart) -> str: + codes = node["color"].split(";") + buffer = "".join(self.color_code(code) for code in codes if code in self.color_codes) + return buffer + self._handle_text(node) + '
    ' + + def _handle_item_name(self, node: JSONMessagePart) -> str: + if self.ctx.slot_info[node["player"]].game == STARCRAFT2: + annotation = ITEM_NAME_ANNOTATIONS.get(node["text"]) + if annotation is not None: + node["text"] += f" {annotation}" + return super()._handle_item_name(node) + + def color_code(self, code: str) -> str: + return '' + + +class SC2Context(CommonContext): + command_processor = StarcraftClientProcessor + game = STARCRAFT2 + items_handling = 0b111 + + def __init__(self, *args, **kwargs) -> None: + super(SC2Context, self).__init__(*args, **kwargs) + self.raw_text_parser = SC2JSONtoTextParser(self) + + self.data_out_of_date: bool = False + self.difficulty = -1 + self.game_speed = -1 + self.disable_forced_camera = 0 + self.skip_cutscenes = 0 + self.all_in_choice = 0 + self.mission_order = 0 + self.player_color_raynor = ColorChoice.option_blue + self.player_color_zerg = ColorChoice.option_orange + self.player_color_zerg_primal = ColorChoice.option_purple + self.player_color_protoss = ColorChoice.option_blue + self.player_color_nova = ColorChoice.option_dark_grey + self.pending_color_update = False + self.kerrigan_presence: int = KerriganPresence.default + self.kerrigan_primal_status = 0 + self.enable_morphling = EnableMorphling.default + self.custom_mission_order: typing.List[CampaignSlotData] = [] + self.mission_id_to_entry_rules: typing.Dict[int, MissionEntryRules] + self.final_mission_ids: typing.List[int] = [29] + self.final_locations: typing.List[int] = [] + self.announcements: queue.Queue = queue.Queue() + self.sc2_run_task: typing.Optional[asyncio.Task] = None + self.missions_unlocked: bool = False # allow launching missions ignoring requirements + self.max_upgrade_level: int = MaxUpgradeLevel.default + self.generic_upgrade_missions = 0 + self.generic_upgrade_research = 0 + self.generic_upgrade_research_speedup: int = GenericUpgradeResearchSpeedup.default + self.generic_upgrade_items = 0 + self.location_inclusions: typing.Dict[LocationType, int] = {} + self.location_inclusions_by_flag: typing.Dict[LocationFlag, int] = {} + self.plando_locations: typing.List[str] = [] + self.difficulty_override = -1 + self.game_speed_override = -1 + self.mission_id_to_location_ids: typing.Dict[int, typing.List[int]] = {} + self.last_bot: typing.Optional[ArchipelagoBot] = None + self.slot_data_version = 2 + self.required_tactics: int = RequiredTactics.default + self.grant_story_tech: int = GrantStoryTech.default + self.grant_story_levels: int = GrantStoryLevels.default + self.take_over_ai_allies: int = TakeOverAIAllies.default + self.spear_of_adun_presence = SpearOfAdunPresence.option_not_present + self.spear_of_adun_present_in_no_build = SpearOfAdunPresentInNoBuild.option_false + self.spear_of_adun_passive_ability_presence = SpearOfAdunPassiveAbilityPresence.option_not_present + self.spear_of_adun_passive_present_in_no_build = SpearOfAdunPassivesPresentInNoBuild.option_false + self.minerals_per_item: int = 15 # For backwards compat with games generated pre-0.4.5 + self.vespene_per_item: int = 15 # For backwards compat with games generated pre-0.4.5 + self.starting_supply_per_item: int = 2 # For backwards compat with games generated pre-0.4.5 + self.maximum_supply_per_item: int = 2 + self.maximum_supply_reduction_per_item: int = options.MaximumSupplyReductionPerItem.default + self.lowest_maximum_supply: int = options.LowestMaximumSupply.default + self.research_cost_reduction_per_item: int = options.ResearchCostReductionPerItem.default + self.use_nova_wol_fallback: bool = False + self.use_nova_nco_fallback: bool = False + self.mercenary_highlanders: bool = False + self.kerrigan_levels_per_mission_completed = 0 + self.trade_enabled: int = EnableVoidTrade.default + self.trade_age_limit: int = VoidTradeAgeLimit.default + self.trade_workers_allowed: int = VoidTradeWorkers.default + self.trade_underway: bool = False + self.trade_latest_reply: typing.Optional[dict] = None + self.trade_reply_event = asyncio.Event() + self.trade_lock_wait: int = 0 + self.trade_lock_start: typing.Optional[float] = None + self.trade_response: typing.Optional[str] = None + self.difficulty_damage_modifier: int = DifficultyDamageModifier.default + self.mission_order_scouting = MissionOrderScouting.option_none + self.mission_item_classification: typing.Optional[typing.Dict[str, int]] = None + self.war_council_nerfs: bool = False + + async def server_auth(self, password_requested: bool = False) -> None: + self.game = STARCRAFT2 + if password_requested and not self.password: + await super(SC2Context, self).server_auth(password_requested) + await self.get_username() + await self.send_connect() + if self.ui: + self.ui.first_check = True + + def is_legacy_game(self): + return self.game == STARCRAFT2_WOL + + def event_invalid_game(self): + if self.is_legacy_game(): + self.game = STARCRAFT2 + super().event_invalid_game() + else: + self.game = STARCRAFT2_WOL + async_start(self.send_connect()) + + def trade_storage_team(self) -> str: + return f"{TRADE_DATASTORAGE_TEAM}{self.team}" + + def trade_storage_slot(self) -> str: + return f"{TRADE_DATASTORAGE_SLOT}{self.slot}" + + def _apply_host_settings_to_options(self) -> None: + if str(SC2World.settings.game_difficulty).casefold() == 'casual': + self.difficulty = GameDifficulty.option_casual + elif str(SC2World.settings.game_difficulty).casefold() == 'normal': + self.difficulty = GameDifficulty.option_normal + elif str(SC2World.settings.game_difficulty).casefold() == 'hard': + self.difficulty = GameDifficulty.option_hard + elif str(SC2World.settings.game_difficulty).casefold() == 'brutal': + self.difficulty = GameDifficulty.option_brutal + + if str(SC2World.settings.game_speed).casefold() == 'slower': + self.game_speed = GameSpeed.option_slower + elif str(SC2World.settings.game_speed).casefold() == 'slow': + self.game_speed = GameSpeed.option_slow + elif str(SC2World.settings.game_speed).casefold() == 'normal': + self.game_speed = GameSpeed.option_normal + elif str(SC2World.settings.game_speed).casefold() == 'fast': + self.game_speed = GameSpeed.option_fast + elif str(SC2World.settings.game_speed).casefold() == 'faster': + self.game_speed = GameSpeed.option_faster + + if str(SC2World.settings.disable_forced_camera).casefold() == 'true': + self.disable_forced_camera = DisableForcedCamera.option_true + elif str(SC2World.settings.disable_forced_camera).casefold() == 'false': + self.disable_forced_camera = DisableForcedCamera.option_false + + if str(SC2World.settings.skip_cutscenes).casefold() == 'true': + self.skip_cutscenes = SkipCutscenes.option_true + elif str(SC2World.settings.skip_cutscenes).casefold() == 'false': + self.skip_cutscenes = SkipCutscenes.option_false + + def on_package(self, cmd: str, args: dict) -> None: + if cmd == "Connected": + # Set up the trade storage + async_start(self.send_msgs([ + { # We want to know about other clients' Set commands for locking + "cmd": "SetNotify", + "keys": [self.trade_storage_team()], + }, + { + "cmd": "Set", + "key": self.trade_storage_team(), + "default": { TRADE_DATASTORAGE_LOCK: 0 }, + "operations": [{"operation": "default", "value": None}] # value is ignored + } + ])) + + self.difficulty = args["slot_data"]["game_difficulty"] + self.game_speed = args["slot_data"].get("game_speed", GameSpeed.option_default) + self.disable_forced_camera = args["slot_data"].get("disable_forced_camera", DisableForcedCamera.default) + self.skip_cutscenes = args["slot_data"].get("skip_cutscenes", SkipCutscenes.default) + self.all_in_choice = args["slot_data"]["all_in_map"] + self.slot_data_version = args["slot_data"].get("version", 2) + + self._apply_host_settings_to_options() + + if self.slot_data_version < 4: + # Maintaining backwards compatibility with older slot data + slot_req_table: dict = args["slot_data"]["mission_req"] + + first_item = list(slot_req_table.keys())[0] + if first_item in [str(campaign.id) for campaign in SC2Campaign]: + # Multi-campaign + mission_req_table = {} + for campaign_id in slot_req_table: + campaign = lookup_id_to_campaign[int(campaign_id)] + mission_req_table[campaign] = { + mission: self.parse_mission_info(mission_info) + for mission, mission_info in slot_req_table[campaign_id].items() + } + else: + # Old format + mission_req_table = {SC2Campaign.GLOBAL: { + mission: self.parse_mission_info(mission_info) + for mission, mission_info in slot_req_table.items() + } + } + + self.custom_mission_order = self.parse_mission_req_table(mission_req_table) + + if self.slot_data_version >= 4: + self.custom_mission_order = [ + CampaignSlotData( + **{field:value for field, value in campaign_data.items() if field not in ["layouts", "entry_rule"]}, + entry_rule = SubRuleRuleData.parse_from_dict(campaign_data["entry_rule"]), + layouts = [ + LayoutSlotData( + **{field:value for field, value in layout_data.items() if field not in ["missions", "entry_rule"]}, + entry_rule = SubRuleRuleData.parse_from_dict(layout_data["entry_rule"]), + missions = [ + [ + MissionSlotData( + **{field:value for field, value in mission_data.items() if field != "entry_rule"}, + entry_rule = SubRuleRuleData.parse_from_dict(mission_data["entry_rule"]) + ) for mission_data in column + ] for column in layout_data["missions"] + ] + ) for layout_data in campaign_data["layouts"] + ] + ) for campaign_data in args["slot_data"]["custom_mission_order"] + ] + self.mission_id_to_entry_rules = { + mission.mission_id: MissionEntryRules(mission.entry_rule, layout.entry_rule, campaign.entry_rule) + for campaign in self.custom_mission_order for layout in campaign.layouts + for column in layout.missions for mission in column + } + + self.mission_order = args["slot_data"].get("mission_order", MissionOrder.option_vanilla) + if self.slot_data_version < 4: + self.final_mission_ids = [args["slot_data"].get("final_mission", SC2Mission.ALL_IN.id)] + else: + self.final_mission_ids = args["slot_data"].get("final_mission_ids", [SC2Mission.ALL_IN.id]) + self.final_locations = [get_location_id(mission_id, 0) for mission_id in self.final_mission_ids] + + self.player_color_raynor = _remap_color_option( + self.slot_data_version, + args["slot_data"].get("player_color_terran_raynor", ColorChoice.option_blue) + ) + self.player_color_zerg = _remap_color_option( + self.slot_data_version, + args["slot_data"].get("player_color_zerg", ColorChoice.option_orange) + ) + self.player_color_zerg_primal = _remap_color_option( + self.slot_data_version, + args["slot_data"].get("player_color_zerg_primal", ColorChoice.option_purple) + ) + self.player_color_protoss = _remap_color_option( + self.slot_data_version, + args["slot_data"].get("player_color_protoss", ColorChoice.option_blue) + ) + self.player_color_nova = _remap_color_option( + self.slot_data_version, + args["slot_data"].get("player_color_nova", ColorChoice.option_dark_grey) + ) + self.war_council_nerfs = args["slot_data"].get("war_council_nerfs", WarCouncilNerfs.option_false) + self.mercenary_highlanders = args["slot_data"].get("mercenary_highlanders", MercenaryHighlanders.option_false) + self.generic_upgrade_missions = args["slot_data"].get("generic_upgrade_missions", GenericUpgradeMissions.default) + self.max_upgrade_level = args["slot_data"].get("max_upgrade_level", MaxUpgradeLevel.default) + self.generic_upgrade_items = args["slot_data"].get("generic_upgrade_items", GenericUpgradeItems.option_individual_items) + self.generic_upgrade_research = args["slot_data"].get("generic_upgrade_research", GenericUpgradeResearch.option_vanilla) + self.generic_upgrade_research_speedup = args["slot_data"].get("generic_upgrade_research_speedup", GenericUpgradeResearchSpeedup.default) + self.kerrigan_presence = args["slot_data"].get("kerrigan_presence", KerriganPresence.option_vanilla) + self.kerrigan_primal_status = args["slot_data"].get("kerrigan_primal_status", KerriganPrimalStatus.option_vanilla) + self.kerrigan_levels_per_mission_completed = args["slot_data"].get("kerrigan_levels_per_mission_completed", 0) + self.kerrigan_levels_per_mission_completed_cap = args["slot_data"].get("kerrigan_levels_per_mission_completed_cap", -1) + self.kerrigan_total_level_cap = args["slot_data"].get("kerrigan_total_level_cap", -1) + self.enable_morphling = args["slot_data"].get("enable_morphling", EnableMorphling.option_false) + self.grant_story_tech = args["slot_data"].get("grant_story_tech", GrantStoryTech.option_no_grant) + self.grant_story_levels = args["slot_data"].get("grant_story_levels", GrantStoryLevels.option_additive) + self.required_tactics = args["slot_data"].get("required_tactics", RequiredTactics.option_standard) + self.take_over_ai_allies = args["slot_data"].get("take_over_ai_allies", TakeOverAIAllies.option_false) + self.spear_of_adun_presence = args["slot_data"].get("spear_of_adun_presence", SpearOfAdunPresence.option_not_present) + self.spear_of_adun_present_in_no_build = args["slot_data"].get("spear_of_adun_present_in_no_build", SpearOfAdunPresentInNoBuild.option_false) + if self.slot_data_version < 4: + self.spear_of_adun_passive_ability_presence = args["slot_data"].get("spear_of_adun_autonomously_cast_ability_presence", SpearOfAdunPassiveAbilityPresence.option_not_present) + self.spear_of_adun_passive_present_in_no_build = args["slot_data"].get("spear_of_adun_autonomously_cast_present_in_no_build", SpearOfAdunPassivesPresentInNoBuild.option_false) + else: + self.spear_of_adun_passive_ability_presence = args["slot_data"].get("spear_of_adun_passive_ability_presence", SpearOfAdunPassiveAbilityPresence.option_not_present) + self.spear_of_adun_passive_present_in_no_build = args["slot_data"].get("spear_of_adun_passive_present_in_no_build", SpearOfAdunPassivesPresentInNoBuild.option_false) + self.minerals_per_item = args["slot_data"].get("minerals_per_item", 15) + self.vespene_per_item = args["slot_data"].get("vespene_per_item", 15) + self.starting_supply_per_item = args["slot_data"].get("starting_supply_per_item", 2) + self.maximum_supply_per_item = args["slot_data"].get("maximum_supply_per_item", options.MaximumSupplyPerItem.default) + self.maximum_supply_reduction_per_item = args["slot_data"].get("maximum_supply_reduction_per_item", options.MaximumSupplyReductionPerItem.default) + self.lowest_maximum_supply = args["slot_data"].get("lowest_maximum_supply", options.LowestMaximumSupply.default) + self.research_cost_reduction_per_item = args["slot_data"].get("research_cost_reduction_per_item", options.ResearchCostReductionPerItem.default) + self.use_nova_wol_fallback = args["slot_data"].get("use_nova_wol_fallback", True) + if self.slot_data_version < 4: + self.use_nova_nco_fallback = args["slot_data"].get("nova_covert_ops_only", False) and self.mission_order == MissionOrder.option_vanilla + else: + self.use_nova_nco_fallback = args["slot_data"].get("use_nova_nco_fallback", False) + self.trade_enabled = args["slot_data"].get("enable_void_trade", EnableVoidTrade.option_false) + self.trade_age_limit = args["slot_data"].get("void_trade_age_limit", VoidTradeAgeLimit.default) + self.trade_workers_allowed = args["slot_data"].get("void_trade_workers", VoidTradeWorkers.default) + self.difficulty_damage_modifier = args["slot_data"].get("difficulty_damage_modifier", DifficultyDamageModifier.option_true) + self.mission_order_scouting = args["slot_data"].get("mission_order_scouting", MissionOrderScouting.option_none) + self.mission_item_classification = args["slot_data"].get("mission_item_classification") + + if self.required_tactics == RequiredTactics.option_no_logic: + # Locking Grant Story Tech/Levels if no logic + self.grant_story_tech = GrantStoryTech.option_grant + self.grant_story_levels = GrantStoryLevels.option_minimum + + self.location_inclusions = { + LocationType.VICTORY: LocationInclusion.option_enabled, # Victory checks are always enabled + LocationType.VICTORY_CACHE: LocationInclusion.option_enabled, # Victory checks are always enabled + LocationType.VANILLA: args["slot_data"].get("vanilla_locations", VanillaLocations.default), + LocationType.EXTRA: args["slot_data"].get("extra_locations", ExtraLocations.default), + LocationType.CHALLENGE: args["slot_data"].get("challenge_locations", ChallengeLocations.default), + LocationType.MASTERY: args["slot_data"].get("mastery_locations", MasteryLocations.default), + } + self.location_inclusions_by_flag = { + LocationFlag.SPEEDRUN: args["slot_data"].get("speedrun_locations", SpeedrunLocations.default), + LocationFlag.PREVENTATIVE: args["slot_data"].get("preventative_locations", PreventativeLocations.default), + } + self.plando_locations = args["slot_data"].get("plando_locations", []) + + self.build_location_to_mission_mapping() + + # Looks for the required maps and mods for SC2. Runs check_game_install_path. + maps_present = is_mod_installed_correctly() + if os.path.exists(get_metadata_file()): + with open(get_metadata_file(), "r") as f: + current_ver = f.read() + sc2_logger.debug(f"Current version: {current_ver}") + if is_mod_update_available(DATA_REPO_OWNER, DATA_REPO_NAME, DATA_API_VERSION, current_ver): + ( + ColouredMessage().coloured("NOTICE: Update for required files found. ", colour="red") + ("Run ").coloured("/download_data", colour="slateblue") + (" to install.") + ).send(self) + self.data_out_of_date = True + elif maps_present: + ( + ColouredMessage() + .coloured("NOTICE: Your map files may be outdated (version number not found). ", colour="red") + ("Run ").coloured("/download_data", colour="slateblue") + (" to install.") + ).send(self) + self.data_out_of_date = True + + ColouredMessage("[b]Check the Launcher tab to start playing.[/b]", keep_markup=True).send(self) + + elif cmd == "SetReply": + # Currently can only be Void Trade reply + self.trade_latest_reply = args + self.trade_reply_event.set() + + @staticmethod + def parse_mission_info(mission_info: dict[str, typing.Any]) -> MissionInfo: + if mission_info.get("id") is not None: + mission_info["mission"] = lookup_id_to_mission[mission_info["id"]] + elif isinstance(mission_info["mission"], int): + mission_info["mission"] = lookup_id_to_mission[mission_info["mission"]] + + return MissionInfo( + **{field: value for field, value in mission_info.items() if field in MissionInfo._fields} + ) + + @staticmethod + def parse_mission_req_table(mission_req_table: typing.Dict[SC2Campaign, typing.Dict[typing.Any, MissionInfo]]) -> typing.List[CampaignSlotData]: + campaigns: typing.List[typing.Tuple[int, CampaignSlotData]] = [] + rolling_rule_id = 0 + for (campaign, campaign_data) in mission_req_table.items(): + if campaign.campaign_name == "Global": + campaign_name = "" + else: + campaign_name = campaign.campaign_name + + categories: typing.Dict[str, typing.List[MissionSlotData]] = {} + for mission in campaign_data.values(): + if mission.category not in categories: + categories[mission.category] = [] + mission_id = mission.mission.id + sub_rules: typing.List[CountMissionsRuleData] = [] + missions: typing.List[int] + if mission.number: + amount = mission.number + missions = [ + mission.mission.id + for mission in mission_req_table[campaign].values() + ] + sub_rules.append(CountMissionsRuleData(missions, amount, [campaign_name])) + prev_missions: typing.List[int] = [] + if len(mission.required_world) > 0: + missions = [] + for connection in mission.required_world: + if isinstance(connection, dict): + required_campaign = {} + for camp, camp_data in mission_req_table.items(): + if camp.id == connection["campaign"]: + required_campaign = camp_data + break + required_mission_id = connection["connect_to"] + else: + required_campaign = mission_req_table[connection.campaign] + required_mission_id = connection.connect_to + required_mission = list(required_campaign.values())[required_mission_id - 1] + missions.append(required_mission.mission.id) + if required_mission.category == mission.category: + prev_missions.append(required_mission.mission.id) + if mission.or_requirements: + amount = 1 + else: + amount = len(missions) + sub_rules.append(CountMissionsRuleData(missions, amount, missions)) + entry_rule = SubRuleRuleData(rolling_rule_id, sub_rules, len(sub_rules)) + rolling_rule_id += 1 + categories[mission.category].append(MissionSlotData.legacy(mission_id, prev_missions, entry_rule)) + + layouts: typing.List[LayoutSlotData] = [] + for (layout, mission_slots) in categories.items(): + if layout.startswith("_"): + layout_name = "" + else: + layout_name = layout + layouts.append(LayoutSlotData.legacy(layout_name, [mission_slots])) + campaigns.append((campaign.id, CampaignSlotData.legacy(campaign_name, layouts))) + return [data for (_, data) in sorted(campaigns)] + + + def on_print_json(self, args: dict) -> None: + # goes to this world + if "receiving" in args and self.slot_concerns_self(args["receiving"]): + relevant = True + # found in this world + elif "item" in args and self.slot_concerns_self(args["item"].player): + relevant = True + # not related + else: + relevant = False + + if relevant: + self.announcements.put(self.raw_text_parser(copy.deepcopy(args["data"]))) + + super(SC2Context, self).on_print_json(args) + + def run_gui(self) -> None: + from .client_gui import start_gui + start_gui(self) + + async def shutdown(self) -> None: + await super(SC2Context, self).shutdown() + if self.last_bot: + self.last_bot.want_close = True + # If the client is not set up yet, the game is not done loading and must be force-closed + if not hasattr(self.last_bot, "client"): + bot.sc2process.kill_switch.kill_all() + if self.sc2_run_task: + self.sc2_run_task.cancel() + + async def disconnect(self, allow_autoreconnect: bool = False): + self.finished_game = False + await super(SC2Context, self).disconnect(allow_autoreconnect=allow_autoreconnect) + + def play_mission(self, mission_id: int) -> bool: + if self.missions_unlocked or is_mission_available(self, mission_id): + if self.sc2_run_task: + if not self.sc2_run_task.done(): + sc2_logger.warning("Starcraft 2 Client is still running!") + self.sc2_run_task.cancel() # doesn't actually close the game, just stops the python task + if self.slot is None: + sc2_logger.warning("Launching Mission without Archipelago authentication, " + "checks will not be registered to server.") + self.sc2_run_task = asyncio.create_task(starcraft_launch(self, mission_id), + name="Starcraft 2 Launch") + return True + else: + sc2_logger.info(f"{lookup_id_to_mission[mission_id].mission_name} is not currently unlocked.") + return False + + def build_location_to_mission_mapping(self) -> None: + mission_id_to_location_ids: typing.Dict[int, typing.Set[int]] = { + mission.mission_id: set() + for campaign in self.custom_mission_order for layout in campaign.layouts + for column in layout.missions for mission in column + } + + for loc in self.server_locations: + offset = ( + SC2WOL_LOC_ID_OFFSET + if loc < SC2HOTS_LOC_ID_OFFSET + else (SC2HOTS_LOC_ID_OFFSET - SC2Mission.ALL_IN.id * VICTORY_MODULO) + ) + mission_id, objective = divmod(loc - offset, VICTORY_MODULO) + mission_id_to_location_ids[mission_id].add(objective) + self.mission_id_to_location_ids = { + mission_id: sorted(objectives) + for mission_id, objectives in mission_id_to_location_ids.items() + } + + def locations_for_mission(self, mission: SC2Mission) -> typing.Iterable[int]: + mission_id: int = mission.id + objectives = self.mission_id_to_location_ids[mission_id] + for objective in objectives: + yield get_location_id(mission_id, objective) + + def locations_for_mission_id(self, mission_id: int) -> typing.Iterable[int]: + objectives = self.mission_id_to_location_ids[mission_id] + for objective in objectives: + yield get_location_id(mission_id, objective) + + def uncollected_locations_in_mission(self, mission: SC2Mission) -> typing.Iterable[int]: + for location_id in self.locations_for_mission(mission): + if location_id in self.missing_locations: + yield location_id + + def is_mission_completed(self, mission_id: int) -> bool: + return get_location_id(mission_id, 0) in self.checked_locations + + + async def trade_acquire_storage(self, keep_trying: bool = False) -> typing.Optional[dict]: + # This function was largely taken from the Pokemon Emerald client + """ + Acquires a lock on the Void Trade DataStorage. + Locking the key means you have exclusive access + to modifying the value until you unlock it or the key expires (5 seconds). + + If `keep_trying` is `True`, it will keep trying to acquire the lock + until successful. Otherwise it will return `None` if it fails to + acquire the lock. + """ + while not self.exit_event.is_set() and self.last_bot and self.last_bot.game_running: + lock = int(time.time_ns() / 1000000000) # in seconds + + # Make sure we're not past the waiting limit + # SC2 needs to be notified within 10 minutes of game time (training time of the dummy units) + if self.trade_lock_start is not None: + if self.last_bot.time - self.trade_lock_start >= TRADE_LOCK_WAIT_LIMIT: + self.trade_lock_wait = 0 + self.trade_lock_start = None + return None + elif keep_trying: + self.trade_lock_start = self.last_bot.time + + message_uuid = str(uuid.uuid4()) + await self.send_msgs([{ + "cmd": "Set", + "key": self.trade_storage_team(), + "default": { TRADE_DATASTORAGE_LOCK: 0 }, + "want_reply": True, + "operations": [{ "operation": "update", "value": { TRADE_DATASTORAGE_LOCK: lock } }], + "uuid": message_uuid, + }]) + + self.trade_reply_event.clear() + try: + await asyncio.wait_for(self.trade_reply_event.wait(), 5) + except asyncio.TimeoutError: + if not keep_trying: + return None + continue + + assert self.trade_latest_reply is not None + reply = copy.deepcopy(self.trade_latest_reply) + + # Make sure the most recently received update was triggered by our lock attempt + if reply.get("uuid", None) != message_uuid: + if not keep_trying: + return None + await asyncio.sleep(TRADE_LOCK_TIME) + continue + + # Make sure the current value of the lock is what we set it to + # (I think this should theoretically never run) + if reply["value"][TRADE_DATASTORAGE_LOCK] != lock: + if not keep_trying: + return None + await asyncio.sleep(TRADE_LOCK_TIME) + continue + + # Make sure that the lock value we replaced is at least 5 seconds old + # If it was unlocked before our change, its value was 0 and it will look decades old + if lock - reply["original_value"][TRADE_DATASTORAGE_LOCK] < TRADE_LOCK_TIME: + if not keep_trying: + return None + + # Multiple clients trying to lock the key may get stuck in a loop of checking the lock + # by trying to set it, which will extend its expiration. So if we see that the lock was + # too new when we replaced it, we should wait for increasingly longer periods so that + # eventually the lock will expire and a client will acquire it. + self.trade_lock_wait += TRADE_LOCK_TIME + self.trade_lock_wait += random.randrange(100, 500) / 1000 + + await asyncio.sleep(self.trade_lock_wait) + continue + + # We have the lock, reset the waiting period and return + self.trade_lock_wait = 0 + self.trade_lock_start = None + return reply + return None + + + async def trade_receive(self, amount: int = 1): + """ + Tries to pop `amount` units out of the trade storage. + """ + reply = await self.trade_acquire_storage(True) + + if reply is None: + self.trade_response = "?TradeFail Void Trade failed: Could not communicate with server. Trade cost refunded." + return None + + # Find available units + # Ignore units we sent ourselves + allowed_slots: typing.List[str] = [ + slot for slot in reply["value"] + if slot != TRADE_DATASTORAGE_LOCK \ + and slot != self.trade_storage_slot() + ] + # Filter out trades that are too old + if self.trade_age_limit != VoidTradeAgeLimit.option_disabled: + trade_time = reply["value"][TRADE_DATASTORAGE_LOCK] + allowed_age = void_trade_age_limits_ms[self.trade_age_limit] + is_young_enough = lambda send_time: trade_time - send_time <= allowed_age + else: + is_young_enough = lambda _: True + # Filter out banned units + if self.trade_workers_allowed == VoidTradeWorkers.option_false: + is_unit_allowed = lambda unit: unit not in worker_units + else: + is_unit_allowed = lambda _: True + + available_units: typing.List[typing.Tuple[str, str, int]] = [] + available_counts: typing.List[int] = [] + for slot in allowed_slots: + for (send_time, units) in reply["value"][slot].items(): + if is_young_enough(int(send_time)): + for (unit, count) in units.items(): + if is_unit_allowed(str(unit)): + available_units.append((unit, slot, send_time)) + available_counts.append(count) + + # Pick units to receive + # If there's not enough units in total, just pick as many as possible + # SC2 should handle the refund + available = sum(available_counts) + refunds = 0 + if available < amount: + refunds = amount - available + amount = available + if available == 0: + # random.sample crashes if counts is an empty list + units = [] + else: + units = random.sample(available_units, amount, counts = available_counts) + + # Build response data + unit_counts: typing.Dict[str, int] = {} + slots_to_update: typing.Dict[str, typing.Dict[int, typing.Dict[str, int]]] = {} + for (unit, slot, send_time) in units: + unit_counts[unit] = unit_counts.get(unit, 0) + 1 + if slot not in slots_to_update: + slots_to_update[slot] = copy.deepcopy(reply["value"][slot]) + slots_to_update[slot][send_time][unit] -= 1 + # Clean up units that were removed completely + if slots_to_update[slot][send_time][unit] == 0: + slots_to_update[slot][send_time].pop(unit) + # Clean up trades that were completely exhausted + if len(slots_to_update[slot][send_time]) == 0: + slots_to_update[slot].pop(send_time) + + await self.send_msgs([ + { # Update server storage + "cmd": "Set", + "key": self.trade_storage_team(), + "operations": [{ "operation": "update", "value": slots_to_update }] + }, + { # Release the lock + "cmd": "Set", + "key": self.trade_storage_team(), + "operations": [{ "operation": "update", "value": { TRADE_DATASTORAGE_LOCK: 0 } }] + } + ]) + + # Give units to bot + self.trade_response = f"?Trade {refunds} " + " ".join(f"{unit} {count}" for (unit, count) in unit_counts.items()) + + + async def trade_send(self, units: typing.List[str]): + """ + Tries to upload `units` to the trade DataStorage. + """ + reply = await self.trade_acquire_storage(True) + + if reply is None: + self.trade_response = "?TradeFail Void Trade failed: Could not communicate with server. Your units remain." + return None + + # Create a storage entry for the time the trade was confirmed + trade_time = reply["value"][TRADE_DATASTORAGE_LOCK] + storage_entry = {} + for unit in units: + storage_entry[unit] = storage_entry.get(unit, 0) + 1 + + # Update the storage with the new units + data: typing.Dict[int, typing.Dict[str, int]] = copy.deepcopy(reply["value"].get(self.trade_storage_slot(), {})) + data[trade_time] = storage_entry + + await self.send_msgs([ + { # Send the updated data + "cmd": "Set", + "key": self.trade_storage_team(), + "operations": [{ "operation": "update", "value": { self.trade_storage_slot(): data } }] + }, + { # Release the lock + "cmd": "Set", + "key": self.trade_storage_team(), + "operations": [{ "operation": "update", "value": { TRADE_DATASTORAGE_LOCK: 0 } }] + } + ]) + + # Notify the game + self.trade_response = "?TradeSuccess Void Trade successful: Units sent!" + + +class CompatItemHolder(typing.NamedTuple): + name: str + quantity: int = 1 + + +def parse_uri(uri: str) -> str: + if "://" in uri: + uri = uri.split("://", 1)[1] + return uri.split('?', 1)[0] + + +async def main(): + multiprocessing.freeze_support() + parser = get_base_parser() + parser.add_argument('--name', default=None, help="Slot Name to connect as.") + args, uri = parser.parse_known_args() + + if uri and uri[0].startswith('archipelago://'): + args.connect = parse_uri(' '.join(uri)) + + ctx = SC2Context(args.connect, args.password) + ctx.auth = args.name + if ctx.server_task is None: + ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop") + + if gui_enabled: + ctx.run_gui() + ctx.run_cli() + + await ctx.exit_event.wait() + + await ctx.shutdown() + +# These items must be given to the player if the game is generated on older versions +API2_TO_API3_COMPAT_ITEMS: typing.Set[CompatItemHolder] = { + CompatItemHolder(item_names.PHOTON_CANNON), + CompatItemHolder(item_names.OBSERVER), + CompatItemHolder(item_names.WARP_HARMONIZATION), + CompatItemHolder(item_names.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE, 3) +} +API3_TO_API4_COMPAT_ITEMS: typing.Set[CompatItemHolder] = { + # War Council + CompatItemHolder(item_names.ZEALOT_WHIRLWIND), + CompatItemHolder(item_names.CENTURION_RESOURCE_EFFICIENCY), + CompatItemHolder(item_names.SENTINEL_RESOURCE_EFFICIENCY), + CompatItemHolder(item_names.STALKER_PHASE_REACTOR), + CompatItemHolder(item_names.DRAGOON_PHALANX_SUIT), + CompatItemHolder(item_names.INSTIGATOR_MODERNIZED_SERVOS), + CompatItemHolder(item_names.ADEPT_DISRUPTIVE_TRANSFER), + CompatItemHolder(item_names.SLAYER_PHASE_BLINK), + CompatItemHolder(item_names.AVENGER_KRYHAS_CLOAK), + CompatItemHolder(item_names.DARK_TEMPLAR_LESSER_SHADOW_FURY), + CompatItemHolder(item_names.DARK_TEMPLAR_GREATER_SHADOW_FURY), + CompatItemHolder(item_names.BLOOD_HUNTER_BRUTAL_EFFICIENCY), + CompatItemHolder(item_names.SENTRY_DOUBLE_SHIELD_RECHARGE), + CompatItemHolder(item_names.ENERGIZER_MOBILE_CHRONO_BEAM), + CompatItemHolder(item_names.HAVOC_ENDURING_SIGHT), + CompatItemHolder(item_names.HIGH_TEMPLAR_PLASMA_SURGE), + CompatItemHolder(item_names.SIGNIFIER_FEEDBACK), + CompatItemHolder(item_names.ASCENDANT_BREATH_OF_CREATION), + CompatItemHolder(item_names.DARK_ARCHON_INDOMITABLE_WILL), + CompatItemHolder(item_names.IMMORTAL_IMPROVED_BARRIER), + CompatItemHolder(item_names.VANGUARD_RAPIDFIRE_CANNON), + CompatItemHolder(item_names.VANGUARD_FUSION_MORTARS), + CompatItemHolder(item_names.ANNIHILATOR_TWILIGHT_CHASSIS), + CompatItemHolder(item_names.COLOSSUS_FIRE_LANCE), + CompatItemHolder(item_names.WRATHWALKER_AERIAL_TRACKING), + CompatItemHolder(item_names.REAVER_KHALAI_REPLICATORS), + CompatItemHolder(item_names.PHOENIX_DOUBLE_GRAVITON_BEAM), + CompatItemHolder(item_names.CORSAIR_NETWORK_DISRUPTION), + CompatItemHolder(item_names.MIRAGE_GRAVITON_BEAM), + CompatItemHolder(item_names.VOID_RAY_PRISMATIC_RANGE), + CompatItemHolder(item_names.CARRIER_REPAIR_DRONES), + CompatItemHolder(item_names.TEMPEST_DISINTEGRATION), + CompatItemHolder(item_names.ARBITER_VESSEL_OF_THE_CONCLAVE), + CompatItemHolder(item_names.MOTHERSHIP_INTEGRATED_POWER), + # Other items + CompatItemHolder(item_names.ASCENDANT_ARCHON_MERGE), + CompatItemHolder(item_names.DARK_TEMPLAR_ARCHON_MERGE), + CompatItemHolder(item_names.SPORE_CRAWLER_BIO_BONUS), +} + +def compat_item_to_network_items(compat_item: CompatItemHolder) -> typing.List[NetworkItem]: + item_id = get_full_item_list()[compat_item.name].code + network_item = NetworkItem(item_id, 0, 0, 0) + return compat_item.quantity * [network_item] + + +def calculate_items(ctx: SC2Context) -> typing.Dict[SC2Race, typing.List[int]]: + items = ctx.items_received.copy() + item_list = get_full_item_list() + def create_network_item(item_name: str) -> NetworkItem: + return NetworkItem(item_list[item_name].code, 0, 0, 0) + + # Items unlocked in earlier generator versions by default (Prophecy defaults, war council, rebalances) + if ctx.slot_data_version < 3: + for compat_item in API2_TO_API3_COMPAT_ITEMS: + items.extend(compat_item_to_network_items(compat_item)) + if ctx.slot_data_version < 4: + for compat_item in API3_TO_API4_COMPAT_ITEMS: + items.extend(compat_item_to_network_items(compat_item)) + received_item_ids = set(item.item for item in ctx.items_received) + if item_list[item_names.GHOST_RESOURCE_EFFICIENCY].code in received_item_ids: + items.append(create_network_item(item_names.GHOST_BARGAIN_BIN_PRICES)) + if item_list[item_names.SPECTRE_RESOURCE_EFFICIENCY].code in received_item_ids: + items.append(create_network_item(item_names.SPECTRE_BARGAIN_BIN_PRICES)) + if item_list[item_names.ROGUE_FORCES].code in received_item_ids: + items.append(create_network_item(item_names.UNRESTRICTED_MUTATION)) + if item_list[item_names.SCOUT_RESOURCE_EFFICIENCY].code in received_item_ids: + items.append(create_network_item(item_names.SCOUT_SUPPLY_EFFICIENCY)) + if item_list[item_names.REAVER_RESOURCE_EFFICIENCY].code in received_item_ids: + items.append(create_network_item(item_names.REAVER_BARGAIN_BIN_PRICES)) + + # API < 4 Orbital Command Count (Deprecated item) + orbital_command_count: int = 0 + + network_item: NetworkItem + accumulators: typing.Dict[SC2Race, typing.List[int]] = { + race: [0 for element in item_type_enum_class if element.flag_word >= 0] + for race, item_type_enum_class in race_to_item_type.items() + } + + # Protoss Shield grouped item specific logic + shields_from_ground_upgrade: int = 0 + shields_from_air_upgrade: int = 0 + + for network_item in items: + name = lookup_id_to_name.get(network_item.item) + if name is None: + continue + item_data: ItemData = item_list[name] + + if item_data.type.flag_word < 0: + continue + + # exists exactly once + if item_data.quantity == 1 or name in item_name_groups[ItemGroupNames.UNRELEASED_ITEMS]: + accumulators[item_data.race][item_data.type.flag_word] |= 1 << item_data.number + + # exists multiple times + elif item_data.quantity > 1: + flaggroup = item_data.type.flag_word + + # Generic upgrades apply only to Weapon / Armor upgrades + if item_data.number >= 0: + accumulators[item_data.race][flaggroup] += 1 << item_data.number + else: + if name == item_names.PROGRESSIVE_PROTOSS_GROUND_UPGRADE: + shields_from_ground_upgrade += 1 + if name == item_names.PROGRESSIVE_PROTOSS_AIR_UPGRADE: + shields_from_air_upgrade += 1 + for bundled_number in get_bundle_upgrade_member_numbers(name): + accumulators[item_data.race][flaggroup] += 1 << bundled_number + + # Regen bio-steel nerf with API3 - undo for older games + if ctx.slot_data_version < 3 and name == item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL: + current_level = (accumulators[item_data.race][flaggroup] >> item_data.number) % 4 + if current_level == 2: + # Switch from level 2 to level 3 for compatibility + accumulators[item_data.race][flaggroup] += 1 << item_data.number + # sum + # Fillers, deprecated items + else: + if name == item_names.PROGRESSIVE_ORBITAL_COMMAND: + orbital_command_count += 1 + elif item_data.type == ZergItemType.Level: + accumulators[item_data.race][item_data.type.flag_word] += item_data.number + elif name == item_names.STARTING_MINERALS: + accumulators[item_data.race][item_data.type.flag_word] += ctx.minerals_per_item + elif name == item_names.STARTING_VESPENE: + accumulators[item_data.race][item_data.type.flag_word] += ctx.vespene_per_item + elif name == item_names.STARTING_SUPPLY: + accumulators[item_data.race][item_data.type.flag_word] += ctx.starting_supply_per_item + elif name == item_names.UPGRADE_RESEARCH_COST: + accumulators[item_data.race][item_data.type.flag_word] += ctx.research_cost_reduction_per_item + else: + accumulators[item_data.race][item_data.type.flag_word] += 1 + + # Fix Shields from generic upgrades by unit class (Maximum of ground/air upgrades) + if shields_from_ground_upgrade > 0 or shields_from_air_upgrade > 0: + shield_upgrade_level = max(shields_from_ground_upgrade, shields_from_air_upgrade) + shield_upgrade_item = item_list[item_names.PROGRESSIVE_PROTOSS_SHIELDS] + for _ in range(0, shield_upgrade_level): + accumulators[shield_upgrade_item.race][shield_upgrade_item.type.flag_word] += 1 << shield_upgrade_item.number + + # Deprecated Orbital Command handling (Backwards compatibility): + if orbital_command_count > 0: + orbital_command_replacement_items: typing.List[str] = [ + item_names.COMMAND_CENTER_SCANNER_SWEEP, + item_names.COMMAND_CENTER_MULE, + item_names.COMMAND_CENTER_EXTRA_SUPPLIES, + item_names.PLANETARY_FORTRESS_ORBITAL_MODULE + ] + replacement_item_ids = [get_full_item_list()[item_name].code for item_name in orbital_command_replacement_items] + if sum(item_id in replacement_item_ids for item_id in items) > 0: + logger.warning(inspect.cleandoc(""" + Both old Orbital Command and its replacements are present in the world. Skipping compatibility handling. + """)) + else: + # None of replacement items are present + # L1: MULE and Scanner Sweep + scanner_sweep_data = get_full_item_list()[item_names.COMMAND_CENTER_SCANNER_SWEEP] + mule_data = get_full_item_list()[item_names.COMMAND_CENTER_MULE] + accumulators[scanner_sweep_data.race][scanner_sweep_data.type.flag_word] += 1 << scanner_sweep_data.number + accumulators[mule_data.race][mule_data.type.flag_word] += 1 << mule_data.number + if orbital_command_count >= 2: + # L2 MULE and Scanner Sweep usable even in Planetary Fortress Mode + planetary_orbital_module_data = get_full_item_list()[item_names.PLANETARY_FORTRESS_ORBITAL_MODULE] + accumulators[planetary_orbital_module_data.race][planetary_orbital_module_data.type.flag_word] += \ + 1 << planetary_orbital_module_data.number + + # Upgrades from completed missions + if ctx.generic_upgrade_missions > 0: + total_missions = sum(len(column) for campaign in ctx.custom_mission_order for layout in campaign.layouts for column in layout.missions) + num_missions = int((ctx.generic_upgrade_missions / 100) * total_missions) + completed = len([mission_id for mission_id in ctx.mission_id_to_location_ids if ctx.is_mission_completed(mission_id)]) + upgrade_count = min(completed // num_missions, ctx.max_upgrade_level) if num_missions > 0 else ctx.max_upgrade_level + upgrade_count = min(upgrade_count, WEAPON_ARMOR_UPGRADE_MAX_LEVEL) + + # Equivalent to "Progressive Weapon/Armor Upgrade" item + global_upgrades: typing.Set[str] = upgrade_included_names[GenericUpgradeItems.option_bundle_all] + for global_upgrade in global_upgrades: + race = get_full_item_list()[global_upgrade].race + upgrade_flaggroup = race_to_item_type[race]["Upgrade"].flag_word + for bundled_number in get_bundle_upgrade_member_numbers(global_upgrade): + accumulators[race][upgrade_flaggroup] += upgrade_count << bundled_number + + return accumulators + + +def get_bundle_upgrade_member_numbers(bundled_item: str) -> typing.List[int]: + upgrade_elements: typing.List[str] = upgrade_bundles[bundled_item] + if bundled_item in (item_names.PROGRESSIVE_PROTOSS_GROUND_UPGRADE, item_names.PROGRESSIVE_PROTOSS_AIR_UPGRADE): + # Shields are handled as a maximum of those two + upgrade_elements = [item_name for item_name in upgrade_elements if item_name != item_names.PROGRESSIVE_PROTOSS_SHIELDS] + return [get_full_item_list()[item_name].number for item_name in upgrade_elements] + + +def calc_difficulty(difficulty: int): + if difficulty == 0: + return 'C' + elif difficulty == 1: + return 'N' + elif difficulty == 2: + return 'H' + elif difficulty == 3: + return 'B' + + return 'X' + + +def get_kerrigan_level(ctx: SC2Context, items: typing.Dict[SC2Race, typing.List[int]], missions_beaten: int) -> int: + item_value = items[SC2Race.ZERG][ZergItemType.Level.flag_word] + mission_value = missions_beaten * ctx.kerrigan_levels_per_mission_completed + if ctx.kerrigan_levels_per_mission_completed_cap != -1: + mission_value = min(mission_value, ctx.kerrigan_levels_per_mission_completed_cap) + total_value = item_value + mission_value + if ctx.kerrigan_total_level_cap != -1: + total_value = min(total_value, ctx.kerrigan_total_level_cap) + return total_value + + +def calculate_kerrigan_options(ctx: SC2Context) -> int: + result = 0 + + # Bits 0, 1 + # Kerrigan unit available + if ctx.kerrigan_presence in kerrigan_unit_available: + result |= 1 << 0 + + # Bit 2 + # Kerrigan primal status by map + if ctx.kerrigan_primal_status == KerriganPrimalStatus.option_vanilla: + result |= 1 << 2 + + return result + + +def caclulate_soa_options(ctx: SC2Context, mission: SC2Mission) -> int: + """ + Pack SOA options into a single integer with bitflags. + 0b000011 = SOA presence + 0b000100 = SOA in no-builds + 0b011000 = Passives presence + 0b100000 = PAssives in no-builds + """ + result = 0 + + # Bits 0, 1 + # SoA Calldowns available + soa_presence_value = 0 + if is_mission_in_soa_presence(ctx.spear_of_adun_presence, mission): + soa_presence_value = 3 + result |= soa_presence_value << 0 + + # Bit 2 + # SoA Calldowns for no-builds + if ctx.spear_of_adun_present_in_no_build == SpearOfAdunPresentInNoBuild.option_true: + result |= 1 << 2 + + # Bits 3,4 + # Autocasts + soa_autocasts_presence_value = 0 + if is_mission_in_soa_presence(ctx.spear_of_adun_passive_ability_presence, mission, SpearOfAdunPassiveAbilityPresence): + soa_autocasts_presence_value = 3 + # Guardian Shell breaks without SoA on version 4+, but can be generated without SoA on version 3 + if ctx.slot_data_version < 4 and MissionFlag.Protoss in mission.flags: + soa_autocasts_presence_value = 3 + result |= soa_autocasts_presence_value << 3 + + # Bit 5 + # Autocasts in no-builds + if ctx.spear_of_adun_passive_present_in_no_build == SpearOfAdunPassivesPresentInNoBuild.option_true: + result |= 1 << 5 + + return result + +def calculate_generic_upgrade_options(ctx: SC2Context) -> int: + result = 0 + + # Bits 0,1 + # Research mode + research_mode_value = 0 + if ctx.generic_upgrade_research == GenericUpgradeResearch.option_vanilla: + research_mode_value = 0 + elif ctx.generic_upgrade_research == GenericUpgradeResearch.option_auto_in_no_build: + research_mode_value = 1 + elif ctx.generic_upgrade_research == GenericUpgradeResearch.option_auto_in_build: + research_mode_value = 2 + elif ctx.generic_upgrade_research == GenericUpgradeResearch.option_always_auto: + research_mode_value = 3 + result |= research_mode_value << 0 + + # Bit 2 + # Speedup + if ctx.generic_upgrade_research_speedup == GenericUpgradeResearchSpeedup.option_true: + result |= 1 << 2 + + return result + +def calculate_trade_options(ctx: SC2Context) -> int: + result = 0 + + # Bit 0 + # Trade enabled + if ctx.trade_enabled: + result |= 1 << 0 + + # Bit 1 + # Workers allowed + if ctx.trade_workers_allowed == VoidTradeWorkers.option_true: + result |= 1 << 1 + + return result + +def kerrigan_primal(ctx: SC2Context, kerrigan_level: int) -> bool: + if ctx.kerrigan_primal_status == KerriganPrimalStatus.option_always_zerg: + return True + elif ctx.kerrigan_primal_status == KerriganPrimalStatus.option_always_human: + return False + elif ctx.kerrigan_primal_status == KerriganPrimalStatus.option_level_35: + return kerrigan_level >= 35 + elif ctx.kerrigan_primal_status == KerriganPrimalStatus.option_half_completion: + total_missions = len(ctx.mission_id_to_location_ids) + completed = sum(ctx.is_mission_completed(mission_id) + for mission_id in ctx.mission_id_to_location_ids) + return completed >= (total_missions / 2) + elif ctx.kerrigan_primal_status == KerriganPrimalStatus.option_item: + codes = [item.item for item in ctx.items_received] + return get_full_item_list()[item_names.KERRIGAN_PRIMAL_FORM].code in codes + return False + + +def get_mission_variant(mission_id: int) -> int: + mission_flags = lookup_id_to_mission[mission_id].flags + if MissionFlag.RaceSwap not in mission_flags: + return 0 + if MissionFlag.Terran in mission_flags: + return 1 + elif MissionFlag.Zerg in mission_flags: + return 2 + elif MissionFlag.Protoss in mission_flags: + return 3 + return 0 + + +def get_item_flag_word(item_name: str) -> int: + return get_full_item_list()[item_name].type.flag_word + + +async def starcraft_launch(ctx: SC2Context, mission_id: int): + sc2_logger.info(f"Launching {lookup_id_to_mission[mission_id].mission_name}. If game does not launch check log file for errors.") + + with DllDirectory(None): + run_game( + bot.maps.get(lookup_id_to_mission[mission_id].map_file), + [Bot(Race.Terran, ArchipelagoBot(ctx, mission_id), name="Archipelago", fullscreen=not SC2World.settings.game_windowed_mode)], + realtime=True, + ) + + +class ArchipelagoBot(bot.bot_ai.BotAI): + __slots__ = [ + 'game_running', + 'mission_completed', + 'boni', + 'setup_done', + 'ctx', + 'mission_id', + 'want_close', + 'can_read_game', + 'last_received_update', + 'last_trade_cargo', + 'last_supply_used' + ] + ctx: SC2Context + # defined in bot_ai_internal.py; seems to be mis-annotated as a float and later re-annotated as an int + supply_used: int + + def __init__(self, ctx: SC2Context, mission_id: int): + self.game_running = False + self.mission_completed = False + self.want_close = False + self.can_read_game = False + self.last_received_update: int = 0 + self.last_trade_cargo: set = set() + self.last_supply_used: int = 0 + self.trade_reply_cooldown: int = 0 + self.setup_done = False + self.ctx = ctx + self.ctx.last_bot = self + self.mission_id = mission_id + self.boni = [False for _ in range(MAX_BONUS)] + + super(ArchipelagoBot, self).__init__() + + async def on_step(self, iteration: int): + if self.want_close: + self.want_close = False + await self._client.leave() + return + game_state = 0 + if not self.setup_done: + self.setup_done = True + mission = lookup_id_to_mission[self.mission_id] + start_items = calculate_items(self.ctx) + missions_beaten = self.missions_beaten_count() + kerrigan_level = get_kerrigan_level(self.ctx, start_items, missions_beaten) + kerrigan_options = calculate_kerrigan_options(self.ctx) + soa_options = caclulate_soa_options(self.ctx, mission) + generic_upgrade_options = calculate_generic_upgrade_options(self.ctx) + trade_options = calculate_trade_options(self.ctx) + mission_variant = get_mission_variant(self.mission_id) # 0/1/2/3 for unchanged/Terran/Zerg/Protoss + nova_fallback: bool + if MissionFlag.Nova in mission.flags: + nova_fallback = self.ctx.use_nova_nco_fallback + elif MissionFlag.WoLNova in mission.flags: + nova_fallback = self.ctx.use_nova_wol_fallback + else: + nova_fallback = False + uncollected_objectives: typing.List[int] = self.get_uncollected_objectives() + if self.ctx.difficulty_override >= 0: + difficulty = calc_difficulty(self.ctx.difficulty_override) + else: + difficulty = calc_difficulty(self.ctx.difficulty) + if self.ctx.game_speed_override >= 0: + game_speed = self.ctx.game_speed_override + else: + game_speed = self.ctx.game_speed + await self.chat_send( + "?SetOptions" + f" {difficulty}" + f" {generic_upgrade_options}" + f" {self.ctx.all_in_choice}" + f" {game_speed}" + f" {self.ctx.disable_forced_camera}" + f" {self.ctx.skip_cutscenes}" + f" {kerrigan_options}" + f" {self.ctx.grant_story_tech}" + f" {self.ctx.take_over_ai_allies}" + f" {soa_options}" + f" {self.ctx.mission_order}" + f" {int(nova_fallback)}" + f" {self.ctx.grant_story_levels}" + f" {self.ctx.enable_morphling}" + f" {mission_variant}" + f" {trade_options}" + f" {self.ctx.difficulty_damage_modifier}" + f" {self.ctx.mercenary_highlanders}" # TODO: Possibly rework it into unit options in the next cycle + f" {self.ctx.war_council_nerfs}" + ) + await self.update_resources(start_items) + await self.update_terran_tech(start_items) + await self.update_zerg_tech(start_items, kerrigan_level) + await self.update_protoss_tech(start_items) + await self.update_misc_tech(start_items) + await self.update_colors() + if uncollected_objectives: + await self.chat_send("?UncollectedLocations {}".format( + functools.reduce(lambda a, b: a + " " + b, [str(x) for x in uncollected_objectives]) + )) + await self.chat_send("?LoadFinished") + self.last_received_update = len(self.ctx.items_received) + + else: + if self.ctx.pending_color_update: + await self.update_colors() + + if not self.ctx.announcements.empty(): + message = self.ctx.announcements.get(timeout=1) + await self.chat_send("?SendMessage " + message) + self.ctx.announcements.task_done() + + # Archipelago reads the health + controller1_state = 0 + controller2_state = 0 + for unit in self.all_own_units(): + if unit.health_max == CONTROLLER_HEALTH: + controller1_state = int(CONTROLLER_HEALTH - unit.health) + self.can_read_game = True + elif unit.health_max == CONTROLLER2_HEALTH: + controller2_state = int(CONTROLLER2_HEALTH - unit.health) + self.can_read_game = True + elif unit.name == TRADE_UNIT: + # Handle Void Trade requests + # Check for orders (for buildings this is usually research or training) + if not unit.is_idle and not self.ctx.trade_underway: + button = unit.orders[0].ability.button_name + if button == TRADE_SEND_BUTTON and len(self.last_trade_cargo) > 0: + units_to_send: typing.List[str] = [] + non_ap_units: typing.Set[str] = set() + for passenger in self.last_trade_cargo: + # Alternatively passenger._type_data.name but passenger.name seems to always match + unit_name = passenger.name + if unit_name.startswith("AP_"): + units_to_send.append(normalized_unit_types.get(unit_name, unit_name)) + else: + non_ap_units.add(unit_name) + if len(non_ap_units) > 0: + sc2_logger.info(f"Void Trade tried to send non-AP units: {', '.join(non_ap_units)}") + self.ctx.trade_response = "?TradeFail Void Trade rejected: Trade contains invalid units." + self.ctx.trade_underway = True + else: + self.ctx.trade_response = None + self.ctx.trade_underway = True + async_start(self.ctx.trade_send(units_to_send)) + elif button == TRADE_RECEIVE_1_BUTTON: + self.ctx.trade_underway = True + if self.supply_used != self.last_supply_used: + self.ctx.trade_response = None + async_start(self.ctx.trade_receive(1)) + else: + self.ctx.trade_response = "?TradeFail Void Trade rejected: Not enough supply." + elif button == TRADE_RECEIVE_5_BUTTON: + self.ctx.trade_underway = True + if self.supply_used != self.last_supply_used: + self.ctx.trade_response = None + async_start(self.ctx.trade_receive(5)) + else: + self.ctx.trade_response = "?TradeFail Void Trade rejected: Not enough supply." + elif not unit.is_idle and self.trade_reply_cooldown > 0: + self.trade_reply_cooldown -= 1 + elif unit.is_idle and self.trade_reply_cooldown > 0: + self.trade_reply_cooldown = 0 + self.ctx.trade_response = None + self.ctx.trade_underway = False + else: + # The API returns no passengers for researching/training buildings, + # so we need to buffer the passengers each frame + self.last_trade_cargo = unit.passengers + # SC2 has no good means of detecting when a unit is queued while supply capped, + # so a supply buffer here is the best we can do + self.last_supply_used = self.supply_used + game_state = controller1_state + (controller2_state << 15) + + if iteration == 160 and not game_state & 1: + await self.chat_send("?SendMessage Warning: Archipelago unable to connect or has lost connection to " + + "Starcraft 2 (This is likely a map issue)") + + if self.last_received_update < len(self.ctx.items_received): + current_items = calculate_items(self.ctx) + missions_beaten = self.missions_beaten_count() + kerrigan_level = get_kerrigan_level(self.ctx, current_items, missions_beaten) + await self.update_resources(current_items) + await self.update_terran_tech(current_items) + await self.update_zerg_tech(current_items, kerrigan_level) + await self.update_protoss_tech(current_items) + await self.update_misc_tech(current_items) + self.last_received_update = len(self.ctx.items_received) + + if game_state & 1: + if not self.game_running: + print("Archipelago Connected") + self.game_running = True + + if self.can_read_game: + if game_state & (1 << 1) and not self.mission_completed: + victory_locations = [get_location_id(self.mission_id, 0)] + send_victory = ( + self.mission_id in self.ctx.final_mission_ids and + len(self.ctx.final_locations) == len(self.ctx.checked_locations.union(victory_locations).intersection(self.ctx.final_locations)) + ) + + # Old slots don't have locations on goal + if not send_victory or self.ctx.slot_data_version >= 4: + sc2_logger.info("Mission Completed") + location_ids = self.ctx.mission_id_to_location_ids[self.mission_id] + victory_locations += sorted([ + get_location_id(self.mission_id, location_id) + for location_id in location_ids + if (location_id % VICTORY_MODULO) >= VICTORY_CACHE_OFFSET + ]) + await self.ctx.send_msgs( + [{"cmd": 'LocationChecks', + "locations": victory_locations}]) + self.mission_completed = True + + if send_victory: + print("Game Complete") + await self.ctx.send_msgs([{"cmd": 'StatusUpdate', "status": ClientStatus.CLIENT_GOAL}]) + self.mission_completed = True + self.ctx.finished_game = True + + for x, completed in enumerate(self.boni): + if not completed and game_state & (1 << (x + 2)): + await self.ctx.send_msgs( + [{"cmd": 'LocationChecks', + "locations": [get_location_id(self.mission_id, x + 1)]}]) + self.boni[x] = True + + # Send Void Trade results + if self.ctx.trade_response is not None and self.trade_reply_cooldown == 0: + await self.chat_send(self.ctx.trade_response) + # Wait an arbitrary amount of frames before trying again + self.trade_reply_cooldown = 60 + else: + await self.chat_send("?SendMessage LostConnection - Lost connection to game.") + + def get_uncollected_objectives(self) -> typing.List[int]: + result = [ + location % VICTORY_MODULO + for location in self.ctx.uncollected_locations_in_mission(lookup_id_to_mission[self.mission_id]) + if (location % VICTORY_MODULO) < VICTORY_CACHE_OFFSET + ] + return result + + def missions_beaten_count(self) -> int: + return len([location for location in self.ctx.checked_locations if location % VICTORY_MODULO == 0]) + + async def update_colors(self): + await self.chat_send("?SetColor rr " + str(self.ctx.player_color_raynor)) + await self.chat_send("?SetColor ks " + str(self.ctx.player_color_zerg)) + await self.chat_send("?SetColor pz " + str(self.ctx.player_color_zerg_primal)) + await self.chat_send("?SetColor da " + str(self.ctx.player_color_protoss)) + await self.chat_send("?SetColor nova " + str(self.ctx.player_color_nova)) + self.ctx.pending_color_update = False + + async def update_resources(self, current_items: typing.Dict[SC2Race, typing.List[int]]): + DEFAULT_MAX_SUPPLY = 200 + max_supply_amount = max( + DEFAULT_MAX_SUPPLY + + ( + current_items[SC2Race.ANY][get_item_flag_word(item_names.MAX_SUPPLY)] + * self.ctx.maximum_supply_per_item + ) + - ( + current_items[SC2Race.ANY][get_item_flag_word(item_names.REDUCED_MAX_SUPPLY)] + * self.ctx.maximum_supply_reduction_per_item + ), + self.ctx.lowest_maximum_supply, + ) + await self.chat_send("?GiveResources {} {} {} {}".format( + current_items[SC2Race.ANY][get_item_flag_word(item_names.STARTING_MINERALS)], + current_items[SC2Race.ANY][get_item_flag_word(item_names.STARTING_VESPENE)], + current_items[SC2Race.ANY][get_item_flag_word(item_names.STARTING_SUPPLY)], + max_supply_amount - DEFAULT_MAX_SUPPLY, + )) + + async def update_terran_tech(self, current_items: typing.Dict[SC2Race, typing.List[int]]): + terran_items = current_items[SC2Race.TERRAN] + await self.chat_send("?GiveTerranTech " + " ".join(map(str, terran_items))) + + async def update_zerg_tech(self, current_items: typing.Dict[SC2Race, typing.List[int]], kerrigan_level: int): + zerg_items = current_items[SC2Race.ZERG] + zerg_items = [value for index, value in enumerate(zerg_items) if index not in [ZergItemType.Level.flag_word, ZergItemType.Primal_Form.flag_word]] + kerrigan_primal_by_items = kerrigan_primal(self.ctx, kerrigan_level) + kerrigan_primal_bot_value = 1 if kerrigan_primal_by_items else 0 + await self.chat_send(f"?GiveZergTech {kerrigan_level} {kerrigan_primal_bot_value} " + ' '.join(map(str, zerg_items))) + + async def update_protoss_tech(self, current_items: typing.Dict[SC2Race, typing.List[int]]): + protoss_items = current_items[SC2Race.PROTOSS] + await self.chat_send("?GiveProtossTech " + " ".join(map(str, protoss_items))) + + async def update_misc_tech(self, current_items: typing.Dict[SC2Race, typing.List[int]]): + await self.chat_send("?GiveMiscTech {} {} {}".format( + current_items[SC2Race.ANY][get_item_flag_word(item_names.BUILDING_CONSTRUCTION_SPEED)], + current_items[SC2Race.ANY][get_item_flag_word(item_names.UPGRADE_RESEARCH_SPEED)], + current_items[SC2Race.ANY][get_item_flag_word(item_names.UPGRADE_RESEARCH_COST)], + )) + +def calc_unfinished_nodes( + ctx: SC2Context +) -> typing.Tuple[typing.List[int], typing.Dict[int, typing.List[int]], typing.List[int], typing.Set[int]]: + unfinished_missions: typing.Set[int] = set() + + available_missions, available_layouts, available_campaigns = calc_available_nodes(ctx) + + for mission_id in available_missions: + objectives = set(ctx.locations_for_mission_id(mission_id)) + if objectives: + objectives_completed = ctx.checked_locations & objectives + if len(objectives_completed) < len(objectives): + unfinished_missions.add(mission_id) + + return available_missions, available_layouts, available_campaigns, unfinished_missions + +def is_mission_available(ctx: SC2Context, mission_id_to_check: int) -> bool: + available_missions, _, _ = calc_available_nodes(ctx) + + return mission_id_to_check in available_missions + +def calc_available_nodes(ctx: SC2Context) -> typing.Tuple[typing.List[int], typing.Dict[int, typing.List[int]], typing.List[int]]: + beaten_missions: typing.Set[int] = {mission_id for mission_id in ctx.mission_id_to_entry_rules if ctx.is_mission_completed(mission_id)} + received_items = compute_received_items(ctx) + + mission_order_objects: typing.List[MissionOrderObjectSlotData] = [] + parent_objects: typing.List[typing.List[MissionOrderObjectSlotData]] = [] + for campaign in ctx.custom_mission_order: + mission_order_objects.append(campaign) + parent_objects.append([]) + for layout in campaign.layouts: + mission_order_objects.append(layout) + parent_objects.append([campaign]) + for column in layout.missions: + for mission in column: + if mission.mission_id == -1: + continue + mission_order_objects.append(mission) + parent_objects.append([campaign, layout]) + + candidate_accessible_objects: typing.List[MissionOrderObjectSlotData] = [ + mission_order_object for mission_order_object in mission_order_objects + if mission_order_object.entry_rule.is_accessible(beaten_missions, received_items) + ] + + accessible_objects: typing.List[MissionOrderObjectSlotData] = [] + + while len(candidate_accessible_objects) > 0: + accessible_missions: typing.List[MissionSlotData] = [mission_order_object for mission_order_object in accessible_objects if isinstance(mission_order_object, MissionSlotData)] + beaten_accessible_missions: typing.Set[int] = {mission.mission_id for mission in accessible_missions if mission.mission_id in beaten_missions} + accessible_objects_to_add: typing.List[MissionOrderObjectSlotData] = [] + for mission_order_object in candidate_accessible_objects: + if ( + mission_order_object.entry_rule.is_accessible(beaten_accessible_missions, received_items) + and all([ + parent_object.entry_rule.is_accessible(beaten_accessible_missions, received_items) + for parent_object in parent_objects[mission_order_objects.index(mission_order_object)] + ]) + ): + accessible_objects_to_add.append(mission_order_object) + if len(accessible_objects_to_add) > 0: + accessible_objects.extend(accessible_objects_to_add) + candidate_accessible_objects = [ + mission_order_object for mission_order_object in candidate_accessible_objects + if mission_order_object not in accessible_objects_to_add + ] + else: + break + + accessible_missions: typing.List[MissionSlotData] = [mission_order_object for mission_order_object in accessible_objects if isinstance(mission_order_object, MissionSlotData)] + beaten_accessible_missions: typing.Set[int] = {mission.mission_id for mission in accessible_missions if mission.mission_id in beaten_missions} + for mission_order_object in mission_order_objects: + # re-generate tooltip accessibility + for sub_rule in mission_order_object.entry_rule.sub_rules: + sub_rule.was_accessible = False + mission_order_object.entry_rule.is_accessible(beaten_accessible_missions, received_items) + + available_missions: typing.List[int] = [ + mission_order_object.mission_id for mission_order_object in accessible_objects + if isinstance(mission_order_object, MissionSlotData) + ] + available_campaign_objects: typing.List[CampaignSlotData] = [ + mission_order_object for mission_order_object in accessible_objects + if isinstance(mission_order_object, CampaignSlotData) + ] + available_campaigns: typing.List[int] = [ + campaign_idx for campaign_idx, campaign in enumerate(ctx.custom_mission_order) + if campaign in available_campaign_objects + ] + available_layout_objects: typing.List[LayoutSlotData] = [ + mission_order_object for mission_order_object in accessible_objects + if isinstance(mission_order_object, LayoutSlotData) + ] + available_layouts: typing.Dict[int, typing.List[int]] = { + campaign_idx: [ + layout_idx for layout_idx, layout in enumerate(campaign.layouts) if layout in available_layout_objects + ] + for campaign_idx, campaign in enumerate(ctx.custom_mission_order) + } + + return available_missions, available_layouts, available_campaigns + +def compute_received_items(ctx: SC2Context) -> typing.Counter[int]: + received_items: typing.Counter[int] = collections.Counter() + for network_item in ctx.items_received: + received_items[network_item.item] += 1 + return received_items + +def check_game_install_path() -> bool: + # First thing: go to the default location for ExecuteInfo. + # An exception for Windows is included because it's very difficult to find ~\Documents if the user moved it. + if is_windows: + # The next five lines of utterly inscrutable code are brought to you by copy-paste from Stack Overflow. + # https://stackoverflow.com/questions/6227590/finding-the-users-my-documents-path/30924555# + import ctypes.wintypes + CSIDL_PERSONAL = 5 # My Documents + SHGFP_TYPE_CURRENT = 0 # Get current, not default value + + buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH) + ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf) + documentspath: str = buf.value + einfo = str(documentspath / Path("StarCraft II\\ExecuteInfo.txt")) + else: + einfo = str(bot.paths.get_home() / Path(bot.paths.USERPATH[bot.paths.PF])) + + # Check if the file exists. + if os.path.isfile(einfo): + + # Open the file and read it, picking out the latest executable's path. + with open(einfo) as f: + content = f.read() + if content: + search_result = re.search(r" = (.*)Versions", content) + if not search_result: + sc2_logger.warning(f"Found {einfo}, but it was empty. Run SC2 through the Blizzard launcher, " + "then try again.") + return False + base = search_result.group(1) + + if os.path.exists(base): + executable = bot.paths.latest_executeble(Path(base).expanduser() / "Versions") + + # Finally, check the path for an actual executable. + # If we find one, great. Set up the SC2PATH. + if os.path.isfile(executable): + sc2_logger.info(f"Found an SC2 install at {base}!") + sc2_logger.debug(f"Latest executable at {executable}.") + os.environ["SC2PATH"] = base + sc2_logger.debug(f"SC2PATH set to {base}.") + return True + else: + sc2_logger.warning(f"We may have found an SC2 install at {base}, but couldn't find {executable}.") + else: + sc2_logger.warning(f"{einfo} pointed to {base}, but we could not find an SC2 install there.") + else: + sc2_logger.warning(f"Couldn't find {einfo}. Run SC2 through the Blizzard launcher, then try again. " + f"If that fails, please run /set_path with your SC2 install directory.") + return False + + +def is_mod_installed_correctly() -> bool: + """Searches for all required files.""" + if "SC2PATH" not in os.environ: + check_game_install_path() + sc2_path: str = os.environ["SC2PATH"] + mapdir = sc2_path / Path('Maps/ArchipelagoCampaign') + mods = ["ArchipelagoCore", "ArchipelagoPlayer", "ArchipelagoPlayerSuper", "ArchipelagoPatches", + "ArchipelagoTriggers", "ArchipelagoPlayerWoL", "ArchipelagoPlayerHotS", + "ArchipelagoPlayerLotV", "ArchipelagoPlayerLotVPrologue", "ArchipelagoPlayerNCO"] + modfiles = [sc2_path / Path("Mods/" + mod + ".SC2Mod") for mod in mods] + wol_required_maps: typing.List[str] = ["WoL" + os.sep + mission.map_file + ".SC2Map" for mission in SC2Mission + if mission.campaign in (SC2Campaign.WOL, SC2Campaign.PROPHECY)] + hots_required_maps: typing.List[str] = ["HotS" + os.sep + mission.map_file + ".SC2Map" for mission in campaign_mission_table[SC2Campaign.HOTS]] + lotv_required_maps: typing.List[str] = ["LotV" + os.sep + mission.map_file + ".SC2Map" for mission in SC2Mission + if mission.campaign in (SC2Campaign.LOTV, SC2Campaign.PROLOGUE, SC2Campaign.EPILOGUE)] + nco_required_maps: typing.List[str] = ["NCO" + os.sep + mission.map_file + ".SC2Map" for mission in campaign_mission_table[SC2Campaign.NCO]] + required_maps = wol_required_maps + hots_required_maps + lotv_required_maps + nco_required_maps + needs_files = False + + # Check for maps. + missing_maps: typing.List[str] = [] + for mapfile in required_maps: + if not os.path.isfile(mapdir / mapfile): + missing_maps.append(mapfile) + if len(missing_maps) >= 19: + sc2_logger.warning(f"All map files missing from {mapdir}.") + needs_files = True + elif len(missing_maps) > 0: + for map in missing_maps: + sc2_logger.debug(f"Missing {map} from {mapdir}.") + sc2_logger.warning(f"Missing {len(missing_maps)} map files.") + needs_files = True + else: # Must be no maps missing + sc2_logger.debug(f"All maps found in {mapdir}.") + + # Check for mods. + for modfile in modfiles: + if os.path.isfile(modfile) or os.path.isdir(modfile): + sc2_logger.debug(f"Archipelago mod found at {modfile}.") + else: + sc2_logger.warning(f"Archipelago mod could not be found at {modfile}.") + needs_files = True + + # Final verdict. + if needs_files: + sc2_logger.warning("Required files are missing. Run /download_data to acquire them.") + return False + else: + sc2_logger.debug("All map/mod files are properly installed.") + return True + + +class DllDirectory: + # Credit to Black Sliver for this code. + # More info: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setdlldirectoryw + _old: typing.Optional[str] = None + _new: typing.Optional[str] = None + + def __init__(self, new: typing.Optional[str]): + self._new = new + + def __enter__(self): + old = self.get() + if self.set(self._new): + self._old = old + + def __exit__(self, *args): + if self._old is not None: + self.set(self._old) + + @staticmethod + def get() -> typing.Optional[str]: + if sys.platform == "win32": + n = ctypes.windll.kernel32.GetDllDirectoryW(0, None) + buf = ctypes.create_unicode_buffer(n) + ctypes.windll.kernel32.GetDllDirectoryW(n, buf) + return buf.value + # NOTE: other OS may support os.environ["LD_LIBRARY_PATH"], but this fix is windows-specific + return None + + @staticmethod + def set(s: typing.Optional[str]) -> bool: + if sys.platform == "win32": + return ctypes.windll.kernel32.SetDllDirectoryW(s) != 0 + # NOTE: other OS may support os.environ["LD_LIBRARY_PATH"], but this fix is windows-specific + return False + + +def download_latest_release_zip( + owner: str, + repo: str, + api_version: str, + metadata: typing.Optional[str] = None, + force_download=False +) -> typing.Tuple[str, typing.Optional[str]]: + """Downloads the latest release of a GitHub repo to the current directory as a .zip file.""" + import requests + + headers = {"Accept": 'application/vnd.github.v3+json'} + url = f"https://api.github.com/repos/{owner}/{repo}/releases/tags/{api_version}" + + try: + r1 = requests.get(url, headers=headers) + if r1.status_code == 200: + latest_metadata = r1.json() + cleanup_downloaded_metadata(latest_metadata) + latest_metadata = str(latest_metadata) + # sc2_logger.info(f"Latest version: {latest_metadata}.") + else: + sc2_logger.warning(f"Status code: {r1.status_code}") + sc2_logger.warning("Failed to reach GitHub. Could not find download link.") + sc2_logger.warning(f"text: {r1.text}") + return "", metadata + + if (force_download is False) and (metadata == latest_metadata): + sc2_logger.info("Latest version already installed.") + return "", metadata + + sc2_logger.info(f"Attempting to download latest version of API version {api_version} of {repo}.") + download_url = r1.json()["assets"][0]["browser_download_url"] + + r2 = requests.get(download_url, headers=headers) + if r2.status_code == 200 and zipfile.is_zipfile(io.BytesIO(r2.content)): + tempdir = tempfile.gettempdir() + file = tempdir + os.sep + f"{repo}.zip" + with open(file, "wb") as fh: + fh.write(r2.content) + sc2_logger.info(f"Successfully downloaded {repo}.zip. Installing...") + return file, latest_metadata + else: + sc2_logger.warning(f"Status code: {r2.status_code}") + sc2_logger.warning("Download failed.") + sc2_logger.warning(f"text: {r2.text}") + return "", metadata + except requests.ConnectionError: + sc2_logger.warning("Failed to reach GitHub. Could not find download link.") + return "", metadata + + +def cleanup_downloaded_metadata(medatada_json: dict) -> None: + for asset in medatada_json['assets']: + del asset['download_count'] + + +def is_mod_update_available(owner: str, repo: str, api_version: str, metadata: str) -> bool: + import requests + + headers = {"Accept": 'application/vnd.github.v3+json'} + url = f"https://api.github.com/repos/{owner}/{repo}/releases/tags/{api_version}" + + try: + r1 = requests.get(url, headers=headers) + if r1.status_code == 200: + latest_metadata = r1.json() + cleanup_downloaded_metadata(latest_metadata) + latest_metadata = str(latest_metadata) + if metadata != latest_metadata: + return True + else: + return False + + else: + sc2_logger.warning("Failed to reach GitHub while checking for updates.") + sc2_logger.warning(f"Status code: {r1.status_code}") + sc2_logger.warning(f"text: {r1.text}") + return False + except requests.ConnectionError: + sc2_logger.warning("Failed to reach GitHub while checking for updates.") + return False + + +def get_location_offset(mission_id: int) -> int: + return SC2WOL_LOC_ID_OFFSET if mission_id <= SC2Mission.ALL_IN.id \ + else (SC2HOTS_LOC_ID_OFFSET - SC2Mission.ALL_IN.id * VICTORY_MODULO) + +def get_location_id(mission_id: int, objective_id: int) -> int: + return get_location_offset(mission_id) + mission_id * VICTORY_MODULO + objective_id + + +_has_forced_save = False +def force_settings_save_on_close() -> None: + """ + Settings has an existing auto-save feature, but it only triggers if a new key was introduced. + Force it to mark things as changed by introducing a new key and then cleaning up. + """ + global _has_forced_save + if _has_forced_save: + return + SC2World.settings.update({'invalid_attribute': True}) + del SC2World.settings.invalid_attribute + _has_forced_save = True + + +def launch(): + colorama.just_fix_windows_console() + asyncio.run(main()) + colorama.deinit() diff --git a/worlds/sc2/client_gui.py b/worlds/sc2/client_gui.py new file mode 100644 index 000000000000..6b2abcd9e96a --- /dev/null +++ b/worlds/sc2/client_gui.py @@ -0,0 +1,655 @@ +from typing import * +import asyncio +import logging + +from BaseClasses import ItemClassification +from NetUtils import JSONMessagePart +from kvui import GameManager, HoverBehavior, ServerToolTip, KivyJSONtoTextParser, LogtoUI +from kivy.app import App +from kivy.clock import Clock +from kivy.core.clipboard import Clipboard +from kivy.uix.gridlayout import GridLayout +from kivy.lang import Builder +from kivy.metrics import dp +from kivy.uix.label import Label +from kivy.uix.button import Button +from kivymd.uix.menu import MDDropdownMenu +from kivymd.uix.tooltip import MDTooltip +from kivy.uix.scrollview import ScrollView +from kivy.properties import StringProperty, BooleanProperty, NumericProperty + +from .client import SC2Context, calc_unfinished_nodes, is_mission_available, compute_received_items, STARCRAFT2 +from .item.item_descriptions import item_descriptions +from .item.item_annotations import ITEM_NAME_ANNOTATIONS +from .mission_order.entry_rules import RuleData, SubRuleRuleData, ItemRuleData +from .mission_tables import lookup_id_to_mission, campaign_race_exceptions, \ + SC2Mission, SC2Race +from .locations import LocationType, lookup_location_id_to_type, lookup_location_id_to_flags +from .options import LocationInclusion, MissionOrderScouting +from . import SC2World + + +class HoverableButton(HoverBehavior, Button): + pass + + +class MissionButton(HoverableButton, MDTooltip): + tooltip_text = StringProperty("Test") + mission_id = NumericProperty(-1) + is_exit = BooleanProperty(False) + is_goal = BooleanProperty(False) + showing_tooltip = BooleanProperty(False) + + def __init__(self, *args, **kwargs): + super(HoverableButton, self).__init__(**kwargs) + self._tooltip = ServerToolTip(text=self.text, markup=True) + self._tooltip.padding = [5, 2, 5, 2] + + def on_enter(self): + self._tooltip.text = self.tooltip_text + + if self.tooltip_text != "": + self.display_tooltip() + + def on_leave(self): + self.remove_tooltip() + + def display_tooltip(self, *args): + self.showing_tooltip = True + return super().display_tooltip(*args) + + def remove_tooltip(self, *args): + self.showing_tooltip = False + return super().remove_tooltip(*args) + + @property + def ctx(self) -> SC2Context: + return App.get_running_app().ctx + +class CampaignScroll(ScrollView): + border_on = BooleanProperty(False) + +class MultiCampaignLayout(GridLayout): + pass + +class DownloadDataWarningMessage(Label): + pass + +class CampaignLayout(GridLayout): + pass + +class RegionLayout(GridLayout): + pass + +class ColumnLayout(GridLayout): + pass + +class MissionLayout(GridLayout): + pass + +class MissionCategory(GridLayout): + pass + + +class SC2JSONtoKivyParser(KivyJSONtoTextParser): + def _handle_item_name(self, node: JSONMessagePart): + item_name = node["text"] + if self.ctx.slot_info[node["player"]].game != STARCRAFT2 or item_name not in item_descriptions: + return super()._handle_item_name(node) + + flags = node.get("flags", 0) + item_types = [] + if flags & ItemClassification.progression: + item_types.append("progression") + if flags & ItemClassification.useful: + item_types.append("useful") + if flags & ItemClassification.trap: + item_types.append("trap") + if not item_types: + item_types.append("normal") + + # TODO: Some descriptions are too long and get cut off. Is there a general solution or does someone need to manually check every description? + desc = item_descriptions[item_name].replace(". \n", ".
    ").replace(". ", ".
    ").replace("\n", "
    ") + annotation = ITEM_NAME_ANNOTATIONS.get(item_name) + if annotation is not None: + desc = f"{annotation}
    {desc}" + ref = "Item Class: " + ", ".join(item_types) + "

    " + desc + node.setdefault("refs", []).append(ref) + return super(KivyJSONtoTextParser, self)._handle_item_name(node) + + def _handle_text(self, node: JSONMessagePart): + if node.get("keep_markup", False): + for ref in node.get("refs", []): + node["text"] = f"[ref={self.ref_count}|{ref}]{node['text']}[/ref]" + self.ref_count += 1 + return super(KivyJSONtoTextParser, self)._handle_text(node) + else: + return super()._handle_text(node) + + +class SC2Manager(GameManager): + base_title = "Archipelago Starcraft 2 Client" + + campaign_panel: Optional[MultiCampaignLayout] = None + campaign_scroll_panel: Optional[CampaignScroll] = None + last_checked_locations: Set[int] = set() + last_items_received: List[int] = [] + last_shown_tooltip: int = -1 + last_data_out_of_date = False + mission_buttons: List[MissionButton] = [] + launching: Union[bool, int] = False # if int -> mission ID + refresh_from_launching = True + first_check = True + first_mission = "" + button_colors: Dict[SC2Race, Tuple[float, float, float]] = {} + ctx: SC2Context + + def __init__(self, ctx: SC2Context) -> None: + super().__init__(ctx) + self.json_to_kivy_parser = SC2JSONtoKivyParser(ctx) + self.minimized = False + + def on_start(self) -> None: + from . import gui_config + warnings, window_width, window_height = gui_config.get_window_defaults() + from kivy.core.window import Window + original_size_x, original_size_y = Window.size + Window.size = window_width, window_height + Window.left -= max((window_width - original_size_x) // 2, 0) + Window.top -= max((window_height - original_size_y) // 2, 0) + # Add the logging handler manually here instead of using `logging_pairs` to avoid adding 2 unnecessary tabs + logging.getLogger("Starcraft2").addHandler(LogtoUI(self.log_panels["All"].on_log)) + for startup_warning in warnings: + logging.getLogger("Starcraft2").warning(f"Startup WARNING: {startup_warning}") + for race in (SC2Race.TERRAN, SC2Race.PROTOSS, SC2Race.ZERG): + errors, color = gui_config.get_button_color(race.name) + self.button_colors[race] = color + for error in errors: + logging.getLogger("Starcraft2").warning(f"{race.name.title()} button color setting: {error}") + + def clear_tooltip(self) -> None: + for button in self.mission_buttons: + button.remove_tooltip() + + def shown_tooltip(self) -> int: + for button in self.mission_buttons: + if button.showing_tooltip: + return button.mission_id + return -1 + + def build(self): + container = super().build() + + panel = self.add_client_tab("Starcraft 2 Launcher", CampaignScroll()) + self.campaign_scroll_panel = panel.content + self.campaign_panel = MultiCampaignLayout() + panel.content.add_widget(self.campaign_panel) + + Clock.schedule_interval(self.build_mission_table, 0.5) + + return container + + def build_mission_table(self, dt) -> None: + if self.launching: + assert self.campaign_panel is not None + self.refresh_from_launching = False + + self.campaign_panel.clear_widgets() + self.campaign_panel.add_widget(Label( + text="Launching Mission: " + lookup_id_to_mission[self.launching].mission_name + )) + if self.ctx.ui: + self.ctx.ui.clear_tooltip() + return + + sorted_items_received = sorted([item.item for item in self.ctx.items_received]) + shown_tooltip = self.shown_tooltip() + hovering_tooltip = ( + self.last_shown_tooltip != -1 + and self.last_shown_tooltip == shown_tooltip + ) + data_changed = ( + self.last_checked_locations != self.ctx.checked_locations + or self.last_items_received != sorted_items_received + ) + needs_redraw = ( + data_changed + and not hovering_tooltip + or not self.refresh_from_launching + or self.last_data_out_of_date != self.ctx.data_out_of_date + or self.first_check + ) + self.last_shown_tooltip = shown_tooltip + if not needs_redraw: + return + + assert self.campaign_panel is not None + self.refresh_from_launching = True + + self.clear_tooltip() + self.campaign_panel.clear_widgets() + if self.ctx.data_out_of_date: + self.campaign_panel.add_widget(Label(text="", padding=[0, 5, 0, 5])) + warning_label = DownloadDataWarningMessage( + text="Map/Mod data is out of date. Run /download_data in the client", + padding=[0, 25, 0, 25], + ) + self.campaign_scroll_panel.border_on = True + self.campaign_panel.add_widget(warning_label) + else: + self.campaign_scroll_panel.border_on = False + self.last_data_out_of_date = self.ctx.data_out_of_date + if len(self.ctx.custom_mission_order) == 0: + self.campaign_panel.add_widget(Label(text="Connect to a world to see a mission layout here.")) + return + + self.last_checked_locations = self.ctx.checked_locations.copy() + self.last_items_received = sorted_items_received + self.first_check = False + + self.mission_buttons = [] + + available_missions, available_layouts, available_campaigns, unfinished_missions = calc_unfinished_nodes(self.ctx) + + # The MultiCampaignLayout widget needs a default height of 15 (set in the .kv) to display the above Labels correctly + multi_campaign_layout_height = 15 + + # Fetching IDs of all the locations with hints + self.hints_to_highlight = [] + hints = self.ctx.stored_data.get(f"_read_hints_{self.ctx.team}_{self.ctx.slot}") + if hints: + for hint in hints: + if hint['finding_player'] == self.ctx.slot and not hint['found']: + self.hints_to_highlight.append(hint['location']) + + MISSION_BUTTON_HEIGHT = 50 + MISSION_BUTTON_PADDING = 6 + for campaign_idx, campaign in enumerate(self.ctx.custom_mission_order): + longest_column = max(len(col) for layout in campaign.layouts for col in layout.missions) + if longest_column == 1: + campaign_layout_height = 115 + else: + campaign_layout_height = (longest_column + 2) * (MISSION_BUTTON_HEIGHT + MISSION_BUTTON_PADDING) + multi_campaign_layout_height += campaign_layout_height + campaign_layout = CampaignLayout(size_hint_y=None, height=campaign_layout_height) + campaign_layout.add_widget( + Label(text=campaign.name, size_hint_y=None, height=25, outline_width=1) + ) + mission_layout = MissionLayout(padding=[10,0,10,0]) + for layout_idx, layout in enumerate(campaign.layouts): + layout_panel = RegionLayout() + layout_panel.add_widget( + Label(text=layout.name, size_hint_y=None, height=25, outline_width=1)) + column_panel = ColumnLayout() + + for column in layout.missions: + category_panel = MissionCategory(padding=[3,MISSION_BUTTON_PADDING,3,MISSION_BUTTON_PADDING]) + + for mission in column: + mission_id = mission.mission_id + + # Empty mission slots + if mission_id == -1: + column_spacer = Label(text='', size_hint_y=None, height=MISSION_BUTTON_HEIGHT) + category_panel.add_widget(column_spacer) + continue + + mission_obj = lookup_id_to_mission[mission_id] + mission_finished = self.ctx.is_mission_completed(mission_id) + is_layout_exit = mission_id in layout.exits and not mission_finished + is_campaign_exit = mission_id in campaign.exits and not mission_finished + + text, tooltip = self.mission_text( + self.ctx, mission_id, mission_obj, + layout_idx, is_layout_exit, layout.name, + campaign_idx, is_campaign_exit, campaign.name, + available_missions, available_layouts, available_campaigns, unfinished_missions + ) + + mission_button = MissionButton(text=text, size_hint_y=None, height=MISSION_BUTTON_HEIGHT) + + mission_button.mission_id = mission_id + + if mission_id in self.ctx.final_mission_ids: + mission_button.is_goal = True + if is_layout_exit or is_campaign_exit: + mission_button.is_exit = True + + mission_race = mission_obj.race + if mission_race == SC2Race.ANY: + mission_race = mission_obj.campaign.race + race = campaign_race_exceptions.get(mission_obj, mission_race) + if race in self.button_colors: + mission_button.background_color = self.button_colors[race] + mission_button.tooltip_text = tooltip + mission_button.bind(on_press=self.mission_callback) + self.mission_buttons.append(mission_button) + category_panel.add_widget(mission_button) + + # layout_panel.add_widget(Label(text="")) + column_panel.add_widget(category_panel) + layout_panel.add_widget(column_panel) + mission_layout.add_widget(layout_panel) + campaign_layout.add_widget(mission_layout) + self.campaign_panel.add_widget(campaign_layout) + self.campaign_panel.height = multi_campaign_layout_height + + # For some reason the AP HoverBehavior won't send an enter event if a button spawns under the cursor, + # so manually send an enter event if a button is hovered immediately + for button in self.mission_buttons: + if button.hovered: + button.dispatch("on_enter") + break + + def mission_text( + self, ctx: SC2Context, mission_id: int, mission_obj: SC2Mission, + layout_id: int, is_layout_exit: bool, layout_name: str, campaign_id: int, is_campaign_exit: bool, campaign_name: str, + available_missions: List[int], available_layouts: Dict[int, List[int]], available_campaigns: List[int], + unfinished_missions: List[int] + ) -> Tuple[str, str]: + COLOR_MISSION_IMPORTANT = "6495ED" # blue + COLOR_MISSION_UNIMPORTANT = "A0BEF4" # lighter blue + COLOR_MISSION_CLEARED = "FFFFFF" # white + COLOR_MISSION_LOCKED = "A9A9A9" # gray + COLOR_PARENT_LOCKED = "848484" # darker gray + COLOR_MISSION_FINAL = "FFBC95" # orange + COLOR_MISSION_FINAL_LOCKED = "D0C0BE" # gray + orange + COLOR_FINAL_PARENT_LOCKED = "D0C0BE" # gray + orange + COLOR_FINAL_MISSION_REMINDER = "FF5151" # light red + COLOR_VICTORY_LOCATION = "FFC156" # gold + COLOR_TOOLTIP_DONE = "51FF51" # light green + COLOR_TOOLTIP_NOT_DONE = "FF5151" # light red + + text = mission_obj.mission_name + tooltip: str = "" + remaining_locations, plando_locations, remaining_count = self.sort_unfinished_locations(mission_id) + campaign_locked = campaign_id not in available_campaigns + layout_locked = layout_id not in available_layouts[campaign_id] + + # Map has uncollected locations + if mission_id in unfinished_missions: + if self.any_valuable_locations(remaining_locations): + text = f"[color={COLOR_MISSION_IMPORTANT}]{text}[/color]" + else: + text = f"[color={COLOR_MISSION_UNIMPORTANT}]{text}[/color]" + elif mission_id in available_missions: + text = f"[color={COLOR_MISSION_CLEARED}]{text}[/color]" + # Map requirements not met + else: + mission_rule, layout_rule, campaign_rule = ctx.mission_id_to_entry_rules[mission_id] + mission_has_rule = mission_rule.amount > 0 + layout_has_rule = layout_rule.amount > 0 + extra_reqs = False + if campaign_locked: + text = f"[color={COLOR_PARENT_LOCKED}]{text}[/color]" + tooltip += "To unlock this campaign, " + shown_rule = campaign_rule + extra_reqs = layout_has_rule or mission_has_rule + elif layout_locked: + text = f"[color={COLOR_PARENT_LOCKED}]{text}[/color]" + tooltip += "To unlock this questline, " + shown_rule = layout_rule + extra_reqs = mission_has_rule + else: + text = f"[color={COLOR_MISSION_LOCKED}]{text}[/color]" + tooltip += "To unlock this mission, " + shown_rule = mission_rule + rule_tooltip = shown_rule.tooltip(0, lookup_id_to_mission, COLOR_TOOLTIP_DONE, COLOR_TOOLTIP_NOT_DONE) + tooltip += rule_tooltip.replace(rule_tooltip[0], rule_tooltip[0].lower(), 1) + extra_word = "are" + if shown_rule.shows_single_rule(): + extra_word = "is" + tooltip += "." + if extra_reqs: + tooltip += f"\nThis mission has additional requirements\nthat will be shown once the above {extra_word} met." + + # Mark exit missions + exit_for: str = "" + if is_layout_exit: + exit_for += layout_name if layout_name else "this questline" + if is_campaign_exit: + if exit_for: + exit_for += " and " + exit_for += campaign_name if campaign_name else "this campaign" + if exit_for: + if tooltip: + tooltip += "\n\n" + tooltip += f"Required to beat {exit_for}" + + # Mark goal missions + if mission_id in self.ctx.final_mission_ids: + if mission_id in available_missions: + text = f"[color={COLOR_MISSION_FINAL}]{mission_obj.mission_name}[/color]" + elif campaign_locked or layout_locked: + text = f"[color={COLOR_FINAL_PARENT_LOCKED}]{mission_obj.mission_name}[/color]" + else: + text = f"[color={COLOR_MISSION_FINAL_LOCKED}]{mission_obj.mission_name}[/color]" + if tooltip and not exit_for: + tooltip += "\n\n" + elif exit_for: + tooltip += "\n" + if any(location_type == LocationType.VICTORY for (location_type, _, _) in remaining_locations): + tooltip += f"[color={COLOR_FINAL_MISSION_REMINDER}]Required to beat the world[/color]" + else: + tooltip += "This goal mission is already beaten.\nBeat the remaining goal missions to beat the world." + + # Populate remaining location list + if remaining_count > 0: + if tooltip: + tooltip += "\n\n" + tooltip += f"[b][color={COLOR_MISSION_IMPORTANT}]Uncollected locations[/color][/b]" + last_location_type = LocationType.VICTORY + victory_printed = False + + if self.ctx.mission_order_scouting != MissionOrderScouting.option_none: + mission_available = mission_id in available_missions + + scoutable = self.is_scoutable(remaining_locations, mission_available, layout_locked, campaign_locked) + else: + scoutable = False + + for location_type, location_name, _ in remaining_locations: + if location_type in (LocationType.VICTORY, LocationType.VICTORY_CACHE) and victory_printed: + continue + if location_type != last_location_type: + tooltip += f"\n[color={COLOR_MISSION_IMPORTANT}]{self.get_location_type_title(location_type)}:[/color]" + last_location_type = location_type + if location_type == LocationType.VICTORY: + victory_count = len([loc for loc in remaining_locations if loc[0] in (LocationType.VICTORY, LocationType.VICTORY_CACHE)]) + victory_loc = location_name.replace(":", f":[color={COLOR_VICTORY_LOCATION}]") + if victory_count > 1: + victory_loc += f' ({victory_count})' + tooltip += f"\n- {victory_loc}[/color]" + victory_printed = True + else: + tooltip += f"\n- {location_name}" + if scoutable: + tooltip += self.handle_scout_display(location_name) + if len(plando_locations) > 0: + tooltip += "\n[b]Plando:[/b]\n- " + tooltip += "\n- ".join(plando_locations) + + tooltip = f"[b]{text}[/b]\n" + tooltip + + #If the mission has any hints pointing to a check, add asterisks around the mission name + if any(tuple(x in self.hints_to_highlight for x in self.ctx.locations_for_mission_id(mission_id))): + text = "* " + text + " *" + + return text, tooltip + + + def mission_callback(self, button: MissionButton) -> None: + if button.last_touch.button == 'right': + self.open_mission_menu(button) + return + if not self.launching: + mission_id: int = button.mission_id + if self.ctx.play_mission(mission_id): + self.launching = mission_id + Clock.schedule_once(self.finish_launching, 10) + + def open_mission_menu(self, button: MissionButton) -> None: + # Will be assigned later, used to close menu in callbacks + menu = None + mission_id = button.mission_id + + def copy_mission_name(): + Clipboard.copy(lookup_id_to_mission[mission_id].mission_name) + menu.dismiss() + + menu_items = [ + { + "text": "Copy Mission Name", + "on_release": copy_mission_name, + } + ] + width_override = None + + hinted_item_ids = Counter() + hints = self.ctx.stored_data.get(f"_read_hints_{self.ctx.team}_{self.ctx.slot}") + if hints: + for hint in hints: + if hint['receiving_player'] == self.ctx.slot and not hint['found']: + hinted_item_ids[hint['item']] += 1 + + if not self.ctx.is_mission_completed(mission_id) and not is_mission_available(self.ctx, mission_id): + # Uncompleted and inaccessible missions can have items hinted if they're needed + # The inaccessible restriction is to ensure users don't waste hints on missions that they can already access + items_needed = self.resolve_items_needed(mission_id) + received_items = compute_received_items(self.ctx) + for item_id, amount in items_needed.items(): + # If we have already received or hinted enough of this item, skip it + if received_items[item_id] + hinted_item_ids[item_id] >= amount: + continue + if width_override is None: + width_override = dp(500) + item_name = self.ctx.item_names.lookup_in_game(item_id) + label_text = f"Hint Required Item: {item_name}" + + def hint_and_close(): + self.ctx.command_processor(self.ctx)(f"!hint {item_name}") + menu.dismiss() + + menu_items.append({ + "text": label_text, + "on_release": hint_and_close, + }) + + menu = MDDropdownMenu( + caller=button, + items=menu_items, + **({"width": width_override} if width_override else {}), + ) + menu.open() + + def resolve_items_needed(self, mission_id: int) -> Counter[int]: + def resolve_rule_to_items(rule: RuleData) -> Counter[int]: + if isinstance(rule, SubRuleRuleData): + all_items = Counter() + for sub_rule in rule.sub_rules: + # Take max of each item across all sub-rules + all_items |= resolve_rule_to_items(sub_rule) + return all_items + elif isinstance(rule, ItemRuleData): + return Counter(rule.item_ids) + else: + return Counter() + + rules = self.ctx.mission_id_to_entry_rules[mission_id] + # Take max value of each item across all rules using '|' + return (resolve_rule_to_items(rules.mission_rule) | + resolve_rule_to_items(rules.layout_rule) | + resolve_rule_to_items(rules.campaign_rule)) + + def finish_launching(self, dt): + self.launching = False + + def sort_unfinished_locations(self, mission_id: int) -> Tuple[List[Tuple[LocationType, str, int]], List[str], int]: + locations: List[Tuple[LocationType, str, int]] = [] + location_name_to_index: Dict[str, int] = {} + for loc in self.ctx.locations_for_mission_id(mission_id): + if loc in self.ctx.missing_locations: + location_name = self.ctx.location_names.lookup_in_game(loc) + location_name_to_index[location_name] = len(locations) + locations.append(( + lookup_location_id_to_type[loc], + location_name, + loc, + )) + count = len(locations) + + plando_locations = [] + elements_to_remove: Set[Tuple[LocationType, str, int]] = set() + for plando_loc_name in self.ctx.plando_locations: + if plando_loc_name in location_name_to_index: + elements_to_remove.add(locations[location_name_to_index[plando_loc_name]]) + plando_locations.append(plando_loc_name) + for element in elements_to_remove: + locations.remove(element) + + return sorted(locations), plando_locations, count + + def any_valuable_locations(self, locations: List[Tuple[LocationType, str, int]]) -> bool: + for location_type, _, location_id in locations: + if (self.ctx.location_inclusions[location_type] == LocationInclusion.option_enabled + and all( + self.ctx.location_inclusions_by_flag[flag] == LocationInclusion.option_enabled + for flag in lookup_location_id_to_flags[location_id].values() + ) + ): + return True + return False + + def get_location_type_title(self, location_type: LocationType) -> str: + title = location_type.name.title().replace("_", " ") + if self.ctx.location_inclusions[location_type] == LocationInclusion.option_disabled: + title += " (Nothing)" + elif self.ctx.location_inclusions[location_type] == LocationInclusion.option_filler: + title += " (Filler)" + else: + title += "" + return title + + def is_scoutable(self, remaining_locations, mission_available: bool, layout_locked: bool, campaign_locked: bool) -> bool: + if self.ctx.mission_order_scouting == MissionOrderScouting.option_all: + return True + elif self.ctx.mission_order_scouting == MissionOrderScouting.option_campaign and not campaign_locked: + return True + elif self.ctx.mission_order_scouting == MissionOrderScouting.option_layout and not layout_locked: + return True + elif self.ctx.mission_order_scouting == MissionOrderScouting.option_available and mission_available: + return True + elif self.ctx.mission_order_scouting == MissionOrderScouting.option_completed and len([loc for loc in remaining_locations if loc[0] in (LocationType.VICTORY, LocationType.VICTORY_CACHE)]) == 0: + # Assuming that when a mission is completed, all victory location are removed + return True + else: + return False + + def handle_scout_display(self, location_name: str) -> str: + if self.ctx.mission_item_classification is None: + return "" + # Only one information is provided for the victory locations of a mission + if " Cache (" in location_name: + location_name = location_name.split(" Cache")[0] + item_classification_key = self.ctx.mission_item_classification[location_name] + if ((ItemClassification.progression & item_classification_key) + and (ItemClassification.useful & item_classification_key) + ): + # Uncommon, but some games do this to show off that an item is super-important + # This can also happen on a victory display if the cache holds both progression and useful + return " [color=AF99EF](Useful+Progression)[/color]" + if ItemClassification.progression & item_classification_key: + return " [color=AF99EF](Progression)[/color]" + if ItemClassification.useful & item_classification_key: + return " [color=6D8BE8](Useful)[/color]" + if SC2World.settings.show_traps and ItemClassification.trap & item_classification_key: + return " [color=FA8072](Trap)[/color]" + return " [color=00EEEE](Filler)[/color]" + + +def start_gui(context: SC2Context): + context.ui = SC2Manager(context) + context.ui_task = asyncio.create_task(context.ui.async_run(), name="UI") + import pkgutil + data = pkgutil.get_data(SC2World.__module__, "starcraft2.kv").decode() + Builder.load_string(data) diff --git a/worlds/sc2/docs/contributors.md b/worlds/sc2/docs/contributors.md index 5b62466d7e45..b1e7e65511cf 100644 --- a/worlds/sc2/docs/contributors.md +++ b/worlds/sc2/docs/contributors.md @@ -1,19 +1,66 @@ # Contributors -Contibutors are listed with preferred or Discord names first, with github usernames prepended with an `@` +Contributors are listed with preferred or Discord names first, with GitHub usernames prepended with an `@`. +Within an update, contributors for earlier sections are not repeated for their contributions in later sections; +code contributors also reported bugs and participated in beta testing. -## Update 2024.0 +## Update 2025 ### Code Changes * Ziktofel (@Ziktofel) * Salzkorn (@Salzkorn) * EnvyDragon (@EnvyDragon) -* Phanerus (@MatthewMarinets) +* Phaneros (@MatthewMarinets) +* Magnemania (@Magnemania) +* Bones (@itsjustbones) +* Gemster (@Gemster312) +* SirChuckOfTheChuckles (@SirChuckOfTheChuckles) +* Snarky (@Snarky) +* MindHawk (@MindHawk) +* Cristall (@Cristall) +* WaikinDN (@WaikinDN) +* blorp77 (@blorp77) +* Dikhovinka (@AYaroslavskiy91) +* Subsourian (@Subsourian) + +### Additional Assets +* Alice Voltaire + +### Voice Acting +@-handles in this section are social media contacts rather than specifically GitHub in this section. + +* Subsourian (@Subsourian) - Signifier, Slayer +* GiantGrantGames (@GiantGrantGames) - Trireme +* Phaneros (@MatthewMarinets)- Skirmisher +* Durygathn - Dawnbringer +* 7thAce (@7thAce) - Pulsar +* Panicmoon (@panicmoon.bsky.social) - Skylord +* JayborinoPlays (@Jayborino) - Oppressor + +## Maintenance of 2024 release +* Ziktofel (@Ziktofel) +* Phaneros (@MatthewMarinets) +* Salzkorn (@Salzkorn) +* neocerber (@neocerber) +* Alchav (@Alchav) +* Berserker (@Berserker66) +* Exempt-Medic (@Exempt-Medic) + +And many members of the greater Archipelago community for core changes that affected the StarCraft 2 apworld. + +## Update 2024 +### Code Changes +* Ziktofel (@Ziktofel) +* Salzkorn (@Salzkorn) +* EnvyDragon (@EnvyDragon) +* Phaneros (@MatthewMarinets) * Madi Sylveon (@MadiMadsen) * Magnemania (@Magnemania) * Subsourian (@Subsourian) +* neocerber (@neocerber) * Hopop (@hopop201) * Alice Voltaire (@AliceVoltaire) * Genderdruid (@ArchonofFail) * CrazedCollie (@FoxOfWar) +* Bones (@itsjustbones) ### Additional Beta testing and bug reports * Varcklen (@Varcklen) diff --git a/worlds/sc2/docs/custom_mission_orders_en.md b/worlds/sc2/docs/custom_mission_orders_en.md new file mode 100644 index 000000000000..6aba753b699e --- /dev/null +++ b/worlds/sc2/docs/custom_mission_orders_en.md @@ -0,0 +1,1092 @@ +# Custom Mission Orders for Starcraft 2 + +
    + Table of Contents + +- [Custom Mission Orders for Starcraft 2](#custom-mission-orders-for-starcraft-2) + - [What is this?](#what-is-this) + - [Basic structure](#basic-structure) + - [Interactions with other YAML options](#interactions-with-other-yaml-options) + - [Instructions for building a mission order](#instructions-for-building-a-mission-order) + - [Shared options](#shared-options) + - [Display Name](#display-name) + - [Unique name](#unique-name) + - [Goal](#goal) + - [Exit](#exit) + - [Entry rules](#entry-rules) + - [Unique progression track](#unique-progression-track) + - [Difficulty](#difficulty) + - [Mission Pool](#mission-pool) + - [Campaign Options](#campaign-options) + - [Preset](#preset) + - [Campaign Presets](#campaign-presets) + - [Static Presets](#static-presets) + - [Preset Options](#preset-options) + - [Missions](#missions) + - [Shuffle Raceswaps](#shuffle-raceswaps) + - [Keys](#keys) + - [Golden Path](#golden-path) + - [Layout Options](#layout-options) + - [Type](#type) + - [Size](#size) + - [Missions](#missions-1) + - [Mission Slot Options](#mission-slot-options) + - [Entrance](#entrance) + - [Empty](#empty) + - [Next](#next) + - [Victory Cache](#victory-cache) + - [Layout Types](#layout-types) + - [Column](#column) + - [Grid](#grid) + - [Grid Index Functions](#grid-index-functions) + - [point(x, y)](#pointx-y) + - [rect(x, y, width, height)](#rectx-y-width-height) + - [Canvas](#canvas) + - [Canvas Index Functions](#canvas-index-functions) + - [group(character)](#groupcharacter) + - [Hopscotch](#hopscotch) + - [Hopscotch Index Functions](#hopscotch-index-functions) + - [top](#top) + - [bottom](#bottom) + - [middle](#middle) + - [corner(index)](#cornerindex) + - [Gauntlet](#gauntlet) + - [Blitz](#blitz) + - [Blitz Index Functions](#blitz-index-functions) + - [row(height)](#rowheight) +
    + +## What is this? + +This is usage documentation for the `custom_mission_order` YAML option for Starcraft 2. You can enable Custom Mission Orders by setting `mission_order: custom` in your YAML. + +You will need to know how to write a YAML before engaging with this feature, and should read the [Archipelago YAML documentation](https://archipelago.gg/tutorial/Archipelago/advanced_settings/en) before continuing here. + +Every example in this document should be valid to generate. + +## Basic structure + +Custom Mission Orders consist of three kinds of structures: +- The mission order itself contains campaigns (like Wings of Liberty) +- Campaigns contain layouts (like Mar Sara) +- Layouts contain mission slots (like Liberation Day) + +As a note, layouts are also called questlines in the UI. Layouts and questlines refer to the same thing, though this document will only use layouts. + +To illustrate, the following is what the default custom mission order currently looks like. If you're not sure what some options mean, they will be explained in more depth later. +```yaml + custom_mission_order: + # This is a campaign, defined by its name + Default Campaign: + # The campaign's name as displayed in the client + display_name: "null" + # Whether this campaign must have a unique name in the client + unique_name: false + # Conditions that must be fulfilled to access this campaign + entry_rules: [] + # Whether beating this campaign is part of the world's goal + goal: true + # The lowest difficulty of missions in this campaign + min_difficulty: relative + # The highest difficulty of missions in this campaign + max_difficulty: relative + # This is a special layout that defines defaults + # for other layouts in the campaign + global: + # The layout's name as displayed in the client + display_name: "null" + # Whether this layout must have a unique name in the client + unique_name: false + # Whether beating this layout is part of the world's goal + goal: false + # Whether this layout must be beaten to beat the campaign + exit: false + # Conditions that must be fulfilled to access this layout + entry_rules: [] + # Which missions are allowed to appear in this layout + mission_pool: + - all missions + # The lowest difficulty of missions in this layout + min_difficulty: relative + # The highest difficulty of missions in this layout + max_difficulty: relative + # Used for overwriting default options of mission slots, + # which are set by the layout type (see Default Layout) + missions: [] + # This is a regular layout, defined by its name + Default Layout: + # This defines how missions in the layout are organized, + # as well as how they connect to one another + type: grid + # How many total missions should appear in this layout + size: 9 +``` +This default option also defines default values (though you won't get the Default Campaign and Default Layout), so you can omit the options you don't want to change in your own YAML. + +Notably however, layouts are required to have both a `type` and a `size`, but neither have defaults. You must define both of them for every layout, either through your own `global` layout, or in the options of every individual layout. + +If you want multiple campaigns or layouts, it would look like this: +```yaml + custom_mission_order: + My first campaign!: + # Campaign options here + global: # Can be omitted if the above defaults work for you + # Makes all the other layouts only have Terran missions + mission_pool: + - terran missions + # Other layout options here + My first layout: + # Defining at least type and size of a layout is mandatory + type: column + size: 3 + # Other layout options here + my second layout: + type: grid + size: 4 + layout number 3: + type: column + size: 3 + # etc. + Second campaign: + the other first layout: + type: grid + size: 10 + # etc. +``` +If you don't want to have a campaign container for your layouts, you can also forego the campaign layer like this: +```yaml + custom_mission_order: + Example campaign-level layout: + # Make sure to always declare these two, like with regular layouts + type: column + size: 3 + + # Regular campaigns and campaign-less layouts + # can be mixed however you want + Some Campaign: + Some Layout: + type: column + size: 3 +``` +It is also possible to access mission slots by their index, which is defined by the type of the layout they are in. The below shows an example of how to access a mission slot, as well as the defaults for their options. + +However, keep in mind that layout types will set their own options for specific slots, overwriting the below defaults, and using this option in turn overwrites the values set by layout types. As before, the options are explained in more depth later. +```yaml + custom_mission_order: + My Campaign: + My Layout: + type: column + size: 5 + missions: + # 0 is often the layout's starting mission + # Any index between 0 and (size - 1) is accessible + - index: 0 + # Whether this mission is part of the world's goal + goal: false + # Whether this mission is accessible as soon as the + # layout is accessible + entrance: false + # Whether this mission is required to beat the layout + exit: false + # Whether this slot contains a mission at all + empty: false + # Conditions that must be fulfilled to access this mission + entry_rules: [] + # Which missions in the layout are unlocked by this mission + # This is normally set by the layout's type + next: [] + # Which missions are allowed to appear in this slot + # If not defined, the slot inherits the layout's pool + mission_pool: + - all missions + # Which specific difficulty this mission should have + difficulty: relative +``` +## Interactions with other YAML options + +Custom Mission Orders respect all the options that change which missions can appear as if the options' relevant missions had been excluded. For example, `selected_races: protoss` is equivalent to excluding all Zerg and Terran missions, and `enabled_campaigns: ["Wings of Liberty"]` is equivalent to excluding all but WoL missions. + +This means that if you want total control over available missions in your mission order via `mission_pool`s, you should enable all races and campaigns and leave your `excluded_missions` list empty, but you can also use these options to get rid of particular missions you never want and can then ignore those missions in your `mission_pool`s. + +There are, however, several options that are ignored by Custom Mission Orders: +- `mission_order`, because it has to be `custom` for your Custom Mission Order to apply +- `maximum_campaign_size`, because you determine the size of the mission order via layout `size` attributes +- `two_start_positions`, which you can instead determine in individual layouts of the appropriate `type`s (see Grid and Hopscotch sections below) +- `key_mode`, which you can still specify for presets (see Campaign Presets section), and can otherwise manually set up using Item entry rules + +## Instructions for building a mission order + +Normally when you play a Starcraft 2 world, you have a table of missions in the Archipelago SC2 Client, and hovering over a mission tells you what missions are required to access it. This is still true for custom mission orders, but you now have control over the way missions are visually organized, as well as their access requirements. + +This section is meant to offer some guidance when making your own mission order for the first time. + +To begin making your own mission order, think about how you visually want your missions laid out. This should inform the layout `type`s you want to use, and give you some idea about the overall structure of your mission order. + +For example, if you want to make a custom campaign like the vanilla ones, you will want a lot of layouts of [`type: column`](#column). If you want a Hopscotch layout with certain missions or races, a single layout with [`type: hopscotch`](#hopscotch) will suffice. If you want to play through a funny shape, you will want to draw with a [`type: canvas`](#canvas). If you just want to make a minor change to a vanilla campaign, you will want to start with a [`preset` campaign](#preset). + +The natural flow of a mission order is defined by the types of its layouts. It makes sense for a mission to unlock its neighbors, it makes sense for a Hopscotch layout to wrap around the sides, and it makes sense for a Column's final mission to be at the bottom. Layout types create their flow by setting [`next`](#next), [`entrance`](#entrance), [`exit`](#exit), and [`entry_rules`](#entry-rules) on missions. More on these in a little bit. + +Layout types dictate their own visual structure, and will only rarely make mission slots with `empty: true`. If you want a certain shape that's not exactly like an existing type, you can pick a type with more slots than you want and remove the extras by setting `empty: true` on them. + +With the basic setup in place, you should decide on what the goal of your mission order is. By default every campaign has `goal: true`, meaning all campaigns must be beaten to complete the world. You can additionally set `goal: true` on layouts and mission slots to require them to be beaten as well. If you set `goal: false` on everything, the mission order will default to setting the last campaign (lowest in your YAML) as the goal. + +After deciding on a goal, you can complicate your way towards it. At the start of a world, the only accessible missions in the mission order are all the missions marked `entrance: true`. When you beat one of these missions, it unlocks all the missions in the beaten mission's `next` list. This process repeats until all the missions are accessible. + +If this behavior isn't enough for your planned mission order, you can interrupt the natural flow of layout types using `entry_rules` in combination with `exit`. + +When this document refers to "beating" something, it means the following: +- A mission is beaten if it is accessible and its victory location is checked. +- Beating a layout means beating all the missions in the layout with `exit: true` +- Beating a campaign means beating all the layouts in the campaign with `exit: true` + +Note victory checks may be claimed by someone else running `!collect` in a multiworld and receiving an item on a victory check. Collecting victory cache checks do not count, only victory checks. + +Layouts will have their default exit missions set by the layout type. If you don't want to use this default, you will have to manually set `exit: false` on the default exits. Campaigns default to using the last layout in them (the lowest in your YAML) as their exit, but only if you don't manually set `exit: true` on a layout. + +Using `entry_rules`, you can make a mission require beating things other than those missions whose `next` points to it, and you can make layouts and campaigns not available from the start. + +Note that `entry_rules` are an addition to the `next` behavior. If you want a mission to completely ignore the natural flow and only use your `entry_rules`, simply set `entrance: true` on it. + +Please see the [`entry_rules`](#entry-rules) section below for available rules and examples. + +With your playthrough sufficiently complicated, it only remains to add flavor to your mission order by changing [`mission_pool`](#mission-pool) and [`difficulty`](#difficulty) options as you like them. These options are also explained below. + +To summarize: +- Start by setting up campaigns and layouts with appropriate layout `type`s and `size`s +- Decide the mission order's `goal`s +- Customize access requirements as desired: + - Use `entrance`, `next`, and `empty` on mission slots to change the unlocking order of missions within a layout + - Use `entry_rules` in combination with `exit` to add additional restrictions to missions, layouts, and campaigns +- Use the `mission_pool` and `difficulty` options to add flavor +- Finally, generate and have fun! + +## Shared options + +These are the options that are shared between at least two of campaigns, layouts and missions. All the options below are listed with their defaults. + +--- +### Display Name +```yaml +# For campaigns and layouts +display_name: "null" +``` +As shown in the examples, every campaign and layout is defined with a name in your YAML. This name is used to find campaigns and layouts within the mission order (see `entry_rules` section), and by default (meaning with `display_name: "null"`) it is also shown in the client. + +This option changes the name shown in the client without affecting the definition name. + +There are two special use cases for this option: +```yaml +# This means the campaign or layout +# will not have a title in the client +display_name: "" +``` +```yaml +# This will randomly pick a name from the given list of options +display_name: + - My First Choice + - My Second Choice + - My Third Choice +``` + +--- +### Unique name +```yaml +# For campaigns and layouts +unique_name: false +``` +This option prevents names from showing up multiple times in the client. It is recommended to be used in combination with lists of `display_name`s to prevent the generator from picking duplicate names. + +--- +### Goal +```yaml +# For campaigns +goal: true +``` +```yaml +# For layouts and missions +goal: false +``` +This determines whether the campaign, layout or mission is required to beat the world. If you turn this off for everything, the last defined campaign (meaning the lowest one in your YAML) is chosen by default. + +--- +### Exit +```yaml +# For layouts and missions +exit: false +``` +This determines whether beating the mission is required to beat its parent layout, and whether beating the layout is required to beat its parent campaign. + +--- +### Entry rules +```yaml +# For campaigns, layouts, and missions +entry_rules: [] +``` +This defines access restrictions for parts of the mission order. + +These are the available rules: +```yaml +entry_rules: + # Beat these things ("Beat rule") + - scope: [] + # Beat X amount of missions from these things ("Count rule") + - scope: [] + amount: -1 + # Find these items ("Item rule") + - items: {} + # Fulfill X amount of other conditions ("Subrule rule") + - rules: [] + amount: -1 +``` +Note that Item rules take both a name and amount for each item (see the example below). In general this rule treats items like the `locked_items` option, including that it will override `excluded_items`, but as a notable difference all items required for Item rules are marked as progression. If multiple Item rules require the same item, the largest required amount will be locked, **not** the sum of all amounts. + +Additionally, Item rules accept a special item: +```yaml +entry_rules: + - items: + Key: 1 +``` +This is a generic item that is converted to a key item for the specific scope it is under. Missions get Mission Keys, layouts get Questline Keys, and campaigns get Campaign Keys. If you want to know which specific key is created (for example to tie multiple unlocks to the same key), you can generate a test game and check in the client. + +You can also use one of the following key items for this purpose: +
    + Custom keys + + - `Terran Key` + - `Zerg Key` + - `Protoss Key` + - `Raynor Key` + - `Tychus Key` + - `Swann Key` + - `Stetmann Key` + - `Hanson Key` + - `Nova Key` + - `Tosh Key` + - `Valerian Key` + - `Warfield Key` + - `Mengsk Key` + - `Han Key` + - `Horner Key` + - `Kerrigan Key` + - `Zagara Key` + - `Abathur Key` + - `Yagdra Key` + - `Kraith Key` + - `Slivan Key` + - `Zurvan Key` + - `Brakk Key` + - `Stukov Key` + - `Dehaka Key` + - `Niadra Key` + - `Izsha Key` + - `Artanis Key` + - `Zeratul Key` + - `Tassadar Key` + - `Karax Key` + - `Vorazun Key` + - `Alarak Key` + - `Fenix Key` + - `Urun Key` + - `Mohandar Key` + - `Selendis Key` + - `Rohana Key` + - `Reigel Key` + - `Davis Key` + - `Ji'nara Key` + +
    + +These keys will never be used by the generator unless you specify them yourself. + +There is also a special type of key: +```yaml +entry_rules: + - items: + # These two forms are equivalent + Progressive Key: 5 + Progressive Key 5: 1 +``` +Progressive keys come in two forms: `Progressive Key: ` and `Progressive Key : 1`. In the latter form the item amount is ignored. Their track is used to group them, so all progressive keys with track 1 belong together, as do all with track 2, and so on. Item rules using progressive keys are sorted by how far into the mission order they appear and have their required amounts set automatically so that deeper rules require more keys, with each track of progressive keys performing its own sorting. + +Note that if any Item rule within a track belongs to a mission, the generator will accept ties, in which case the affected rules will require the same number of progressive keys. If a track only contains Item rules belonging to layouts and campaigns, the track will be sorted in definition order (top to bottom in your YAML), so there will be no ties. + +If you prefer not to manually specify the track, use the [`unique_progression_track`](#unique-progression-track) option. + +The Beat and Count rules both require a list of scopes. This list accepts addresses towards other parts of the mission order. + +The basic form of an address is `//`, where `` and `` are the definition names (not `display_names`!) of a campaign and a layout within that campaign, and `` is the index of a mission slot in that layout or an index function for the layout's type. See the section on your layout's type to find valid indices and functions. + +If you don't want to point all the way down to a mission slot, you can omit the later parts. `` and `/` are valid addresses, and will point to the entire specified campaign or layout. + +Futhermore, you can generically refer to the parent of an object using `..`, so if you are creating entry rules for a given layout and want to point at a different `` in the same ``, the following are identical: +- `../` +- `/` + +You can also chain these, so for a given mission `../..` will point to its parent campaign. + +Lastly, you can point to the whole mission order via `/..` (or the equivalent number of `..`s from a given layer), but this is only supported for Count rules and not Beat rules. + +Note that if you have a campaign-less layout, you will not require a `` part to find it, and `..` will skip the campaign layer. + +Below are examples of the available entry rules: +```yaml + custom_mission_order: + Some Missions: + type: grid + size: 9 + entry_rules: + # Item rule: + # To access the Some Missions layout, + # you have to find or receive your Marine + - items: + Marine: 1 + + Wings of Liberty: + Mar Sara: + type: column + size: 3 + Artifact: + type: column + size: 3 + entry_rules: + # Beat rule: + # To access the Artifact layout, + # you have to first beat Mar Sara + - scope: ../Mar Sara + Prophecy: + type: column + size: 3 + entry_rules: + # Beat rule: + # Beat the mission at index 1 in the Artifact layout + - scope: ../Artifact/1 + # This is identical to the above + # because this layout is already in Wings of Liberty + - scope: Wings of Liberty/Artifact/1 + Covert: + type: column + size: 3 + entry_rules: + # Count rule: + # Beat any 7 missions from Wings of Liberty + - scope: Wings of Liberty + amount: 7 + + Complicated Access: + type: column + size: 3 + entry_rules: + # Subrule rule: + # To access this layout, + # fulfill any 1 of the nested rules + # (See amount value at the bottom) + - rules: + # Nested Subrule rule: + # Fulfill all of the nested rules + # Amount can be at the top if you prefer + - amount: -1 # -1 means "all of them" + rules: + # Count rule: + # Beat any 5 missions from Wings of Liberty + - scope: Wings of Liberty + amount: 5 + # Count rule: + # Beat any 5 missions from Some Missions + - scope: Some Missions + amount: 5 + # Count rule: + # Beat any 10 combined missions from + # Wings of Liberty or Some Missions + - scope: + - Wings of Liberty + - Some Missions + amount: 10 + amount: 1 +``` +As this last example shows, the Subrule rule is a powerful tool for making arbitrarily complex requirements. Put plainly, the example accomplishes the following: To unlock the `Complicated Access` layout, either beat 5 missions in both the `Wings of Liberty` campaign and the `Some Missions` layout, or beat 10 missions across both of them. + +--- +### Unique progression track +```yaml +# For campaigns and layouts +unique_progression_track: 0 +``` +This option specifically affects Item entry rules using progressive keys. Progressive keys used by children of this campaign/layout that are on the given track will automatically be put on a track that is unique to the container instead. +```yaml + custom_mission_order: + First Column: + type: column + size: 3 + unique_progression_track: 0 # Default + missions: + - index: [1, 2] + entry_rules: + - items: + Progressive Key: 0 + Second Column: + type: column + size: 3 + unique_progression_track: 0 # Default + missions: + - index: [1, 2] + entry_rules: + - items: + Progressive Key: 0 +``` +In this example the two columns will use separate progressive keys for their missions. + +In the case that a mission slot uses a progressive key whose track matches the `unique_progression_track` of both its containing layout and campaign, the key will use the layout's unique track and not the campaign's. To avoid this behavior simply use different `unique_progression_track` values for the layout and campaign. + +--- +### Difficulty +```yaml +# These two apply to campaigns and layouts +min_difficulty: relative +max_difficulty: relative +# This one applies to missions +difficulty: relative +``` +Valid values are: +- Relative +- Starter +- Easy +- Medium +- Hard +- Very Hard + +These determine the difficulty of missions within campaigns, layouts, or specific mission slots. + +On `relative`, the difficulty of mission slots is dynamically scaled based on earliest possible access to that mission. By default, this scales the entire mission order to go from Starter missions at the start to Very Hard missions at the end. + +Campaigns can override these limits, layouts can likewise override the limits set by their campaigns, and missions can simply define their desired difficulty. + +In every case, if a mission's mission pool does not contain missions of an appropriate difficulty, it will attempt to find a mission of a nearby difficulty, preferring lower ones. + +```yaml + custom_mission_order: + Campaign: + min_difficulty: easy + max_difficulty: medium + Layout 1: + max_difficulty: hard + type: column + size: 3 + Layout 2: + type: column + size: 3 + missions: + - index: 0 + difficulty: starter +``` +In this example, `Campaign` is restricted to missions between Easy and Medium. `Layout 1` overrides Medium to be Hard instead, so its 3 missions will go from Easy to Hard. `Layout 2` keeps the campaign's limits, but its first mission is set to Starter. In this case, the first mission will be a Starter mission, but the other two missions will scale towards Medium as if the first had been an Easy one. + +--- +### Mission Pool +```yaml +# For layouts and missions +mission_pool: + - all missions +``` +Valid values are names of specific missions and names of mission groups. Group names can be looked up here: [APSC2 Mission Groups](https://matthewmarinets.github.io/ap_sc2_icons/missiongroups) + +If a mission defines this, it ignores the pool of its containing layout. To define a pool for a full campaign, define it in the `global` layout. + +This is a list of instructions for constructing a mission pool, executed from top to bottom, so the order of values is important. + +There are three available instructions: +- Addition: ``, `+` or `+ ` + - This adds the missions of the specified group into the pool +- Subtraction: `~` or `~ ` + - This removes the missions of the specified group from the pool + - Note that the operator is `~` and not `-`, because the latter is a reserved symbol in YAML. +- Intersection: `^` or `^ ` + - This removes all the missions from the pool that are not in the specified group. + +As a reminder, `` can also be the name of a specific mission. + +The first instruction in a pool must always be an addition. + +```yaml + custom_mission_order: + Campaign: + global: + type: column + size: 3 + mission_pool: + - terran missions + - ~ no-build missions + Layout A-1: + mission_pool: + - zerg missions + - ^ kerrigan missions + - + Lab Rat + Layout A-2: + missions: + - index: 0 + mission_pool: + - For Aiur! + - Liberation Day +``` +The following pools are constructed in this example: +- `Campaign` defines a pool that contains Terran missions, and then removes all No-Build missions from it. +- `Layout A-1` overrides this pool with Zerg missions, then keeps only the ones with Kerrigan in them, and then adds Lab Rat back to it. + - Lab Rat does not contain Kerrigan, but because the instruction to add it is placed after the instruction to remove non-Kerrigan missions, it is added regardless. +- The pool for the first mission of `Layout A-2` contains For Aiur! and Liberation Day. The remaining missions of `Layout A-2` use the Terran pool set by the `global` layout. + +## Campaign Options + +These options can only be used in campaigns. + +--- +### Preset +```yaml +preset: none +``` +This option loads a pre-built campaign into your mission order. Presets may accept additional options in addition to regular campaign options. + +With all presets, you can override their layout options by defining the layouts like normal in your YAML. +```yaml + custom_mission_order: + My Campaign: + preset: wol + prophecy + missions: random # Optional + shuffle_raceswaps: false # Optional + keys: none # Optional + Prophecy: + mission_pool: + - zerg missions +``` +This example loads the Wol + Prophecy preset and then changes Prophecy's missions to be Zerg instead of Protoss. + +See the following section for available presets. + +## Campaign Presets + +There are two kinds of presets: Static presets that are based on vanilla campaigns, and scripted presets that dynamically create a complex campaign based on extra required options. + +--- +### Static Presets +Available static presets are the following: +- `WoL + Prophecy` +- `WoL` +- `Prophecy` +- `HotS` +- `Prologue`, `LotV Prologue` +- `LotV` +- `Epilogue`, `LotV Epilogue` +- `NCO` +- `Mini WoL + Prophecy` +- `Mini WoL` +- `Mini Prophecy` +- `Mini HotS` +- `Mini Prologue`, `Mini LotV Prologue` +- `Mini LotV` +- `Mini Epilogue`, `Mini LotV Epilogue` +- `Mini NCO` + +For these presets, the layout names used to override settings match the names shown in the client, with some exceptions: +- Prophecy, Prologue and Epilogue contain a single Gauntlet each, which are named `Prophecy`, `Prologue` and `Epilogue` respectively. +- The Gauntlets in the Mini variants of the above are also named `Prophecy`, `Prologue` and `Epilogue`. +- NCO and Mini NCO contain three columns each, named `Mission Pack 1`, `Mission Pack 2` and `Mission Pack 3`. + +#### Preset Options +All static presets accept these options, as shown in the example above: + +##### Missions +The `missions` option accepts these possible values: +- `random` (default), which removes pre-defined `mission_pool` options from layouts and missions, meaning all missions will follow the pool defined in your campaign's `global` layout. This is the default if you don't define the `missions` option. +- `vanilla_shuffled`, which will leave `mission_pool`s on layouts to shuffle vanilla missions within their respective campaigns. +- `vanilla`, which will leave all missions as they are in the vanilla campaigns. + +##### Shuffle Raceswaps +The `shuffle_raceswaps` option accepts `true` and `false` (default). If enabled, the missions pools in the preset will contain raceswapped missions. This means `missions: vanilla_shuffled` will shuffle raceswaps alongside their regular variants, and `missions: vanilla` will allow a random variant of the mission in each slot. This option does nothing if `missions` is set to `random`. + +##### Keys +The `keys` option accepts these possible values: +- `none` (default), which does not add any Key Item rules to the preset. +- `layouts`, which adds Key Item rules to layouts besides the preset's left-most layout, in addition to their regular entry rules. +- `missions`, which adds Key Item rules to missions besides the preset's starter mission, in addition to their regular entry rules. +- `progressive_layouts`, which adds Progressive Key Item rules to layouts besides the preset's left-most layout, in addition to their regular entry rules. These progressive keys use track 0, with presets using the default `unique_progression_track: 0`. +- `progressive_missions`, which adds Progressive Key Item rules to missions besides the preset's starter mission, in addition to their regular entry rules. These progressive keys use track 1 and do not make use of `unique_progression_track`. +- `progressive_per_layout`, which adds Progressive Key Item rules to all missions within each layout besides the preset's left-most one. These progressive keys use track 0, with presets and their layouts using the default `unique_progression_track: 0`. + +--- +### Golden Path +```yaml +preset: golden path +size: # Required, no default, accepts positive numbers +two_start_positions: false +keys: none # Optional +``` +Golden Path aims to create a dynamically-sized campaign with branching paths to create a similar experience to the Wings of Liberty campaign. It accomplishes this by having a main column that requires an increasing number of missions to be beaten to advance, and a number of side columns that require progressing the main column to advance. The exit of a Golden Path campaign is the last mission of the main column. + +The `size` option defines the number of missions in the campaign. + +If `two_start_positions`, the first mission will be skipped, and the first two branches will be available from the start instead. + +The columns in a Golden Path get random names from a `display_name` list and have `unique_name: true` set on them. Their definition names for overriding options are `"0"`, `"1"`, `"2"`, etc., with `"0"` always being the main column, `"1"` being the left-most side column, and so on. + +Since the number of side columns depends on the number of missions, it is best to generate a test game for a given size to see how many columns are generated. + +Golden Path also accepts a `keys` option, which works like the same option for static presets, and accepts the following values: +- `none` (default), which does not add any Key Item rules to the preset. +- `layouts`, which adds Key Item rules to all side columns, in addition to their regular entry rules. +- `missions`, which adds Key Item rules to missions besides the preset's starter mission, in addition to their regular entry rules. +- `progressive_layouts`, which adds Progressive Key Item rules to all side columns, in addition to their regular entry rules. These progressive keys use track 0, with this preset using the default `unique_progression_track: 0`. +- `progressive_missions`, which adds Progressive Key Item rules to missions besides the preset's starter mission, in addition to their regular entry rules. These progressive keys use track 1 and do not make use of `unique_progression_track`. +- `progressive_per_layout`, which adds Progressive Key Item rules to all missions within each side column. These progressive keys use track 0, with this preset and its layouts using the default `unique_progression_track: 0`. + +## Layout Options + +Layouts may have special options depending on their `type`. These are covered in the section on Layout Types. +Below are the options that apply to every layout. + +--- +### Type +```yaml +type: # There is no default +``` +Determines how missions are placed relative to one another within a layout, as well as how they connect to each other. + +Currently, valid values are: +- Column +- Grid +- Hopscotch +- Gauntlet +- Blitz + +Details about specific layout types are covered at the end of this document. + +--- +### Size +```yaml +size: # There is no default +``` +Determines how many missions a layout contains. Valid values are positive numbers. + +### Missions +```yaml +missions: [] +``` +This is used to access mission slots and overwrite the options that the layout type set for them. Valid options for mission slots are covered below, but the `index` option used to find mission slots is explained here. + +Note that this list is evaluated from top to bottom, meaning if you perform conflicting changes on the same mission slot, the last defined operation (lowest in your YAML) will be the one that takes effect. + +The following example shows ways to access and modify missions: +```yaml + custom_mission_order: + My Example: + type: grid + size: 4 + missions: + # Indices can be a numerical value + # This sets the mission at index 1 to be an exit + - index: 1 + exit: true + # Indices can be special index functions + # Valid functions are 'exits', 'entrances', and 'all' + # These are available for all types of layouts + # This takes all exits, including the one set above, + # and turns them into non-exits + - index: exits + exit: false + # Indices can be index functions + # Available functions depend on the layout's type + # In this case the function will return the indices 1 and 3 + # and then mark those two slots as empty + - index: rect(1, 0, 1, 2) + empty: true + # Indices can be a list of valid values + # This takes all entrances as well as the mission at index 2 + # and marks all of them as both entrances and exits + - index: + - entrances + - 2 + entrance: true + exit: true +``` +The result of this example will be a grid where the two missions on the right are empty, and the two missions on the left are both entrances and exits. + +## Mission Slot Options + +For all options in mission slots, the layout type containing the mission slot choses the defaults, and any values you define override the type's defaults. + +--- +### Entrance +```yaml +entrance: false +``` +Determines whether this mission is an entrance for its containing layout. An entrance mission becomes available its parent layout's and campaign's `entry_rules` are fulfilled, but may further be restricted by its own `entry_rules`. + +If for any reason a mission cannot be unlocked by beating other missions, meaning that there is no mission whose `next` points at this mission, then this missions will be automatically marked as entrances. However, this cannot detect circular dependencies, for example if you cut off a section of a grid, so make sure to manually set entrances as appropriate in those cases. + +--- +### Empty +```yaml +empty: false +``` +Determines whether this mission slot contains a mission at all. If set to `true`, the slot is empty and will show up as a blank space in the client. + +Layout types have their own means of creating blank spaces in the client, and so rarely use this option. If you want complete control over a layout's slots, use a layout of `type: grid`. + +--- +### Next +```yaml +next: [] +``` +Valid values are indices of other missions within the same layout and index functions for the layout's type. Note that this does not accept addresses. + +This is the mechanism layout types use to establish mission flow. Overriding this will break the intended order of missions within a type. If you wish to add on to the type's flow rather than replace it, you must manually include the indices intended by the type. + +Mechanically, a mission is unlocked when any other mission that contains the former in its `next` list is beaten. If a mission is not present in any other mission's `next` list, it is automatically marked as an entrance. +```yaml + custom_mission_order: + Wings of Liberty: + Char: + type: column + size: 4 + missions: + - index: 0 + next: + - 1 + - 2 + - index: 1 + next: + - 3 + # The below two are default for a column + # and could be removed from this list + - index: 2 + next: + - 3 + - index: 3 + next: [] + +``` +This example creates the branching path within `Char` in the Vanilla mission order. + +--- +### Victory Cache +```yaml +victory_cache: 0 +``` +Valid values are integers in the range 0 to 10. Sets the number of extra locations given for victory on a mission. + +By default, when this value is not set, the option is set to 0 for goal missions and to the global `victory_cache` option for all other missions. + +## Layout Types + +The below types are listed with their custom options and their defaults. + +--- +### Column +```yaml +type: column +``` + +This is a linear order going from top to bottom. + +A `size: 5` column has the following indices: +```yaml +0 # This is the default entrance +1 +2 +3 +4 # This is the default exit (size - 1) +``` + +--- +### Grid +```yaml +type: grid +width: 0 # Accepts positive numbers +two_start_positions: false # Accepts true/false +``` +This is a rectangular order. Beating a mission unlocks adjacent missions in cardinal directions. + +`width` sets the width of the grid, and height is determined via `size` and `width`. If `width` is set to 0, the width and height are determined automatically. + +If `two_start_positions`, the top left corner will be set to `empty: true`, and its two neighbors will be entrances instead. + +If `size` is too small for the determined width and height, then slots in the bottom left and top right corners will be removed to fit the given `size`. These empty slots are still accessible by index. + +A `size: 25`, `width: 5` grid has the following indices: +```yaml + 0 1 2 3 4 + 5 6 7 8 9 +10 11 12 13 14 +15 16 17 18 19 +20 21 22 23 24 +``` +The top left corner (index `0`) is the default entrance. The bottom right corner (index `size - 1`) is the default exit. + +#### Grid Index Functions +Grid supports the following index functions: + +##### point(x, y) +`point(x, y)` returns the index at the given zero-based X and Y coordinates. In the above example, `point(2, 4)` is index `22`. + +##### rect(x, y, width, height) +`rect(x, y, width, height)` returns the indices within the rectangle defined by the starting point at the X and Y coordinates and the width and height arguments. In the above example, `rect(1, 2, 3, 2)` returns the indices `11, 12, 13, 16, 17, 18`. + +--- +### Canvas +```yaml +type: canvas +canvas: # No default +jump_distance_orthogonal: 1 # Accepts numbers >= 1 +jump_distance_diagonal: 1 # Accepts numbers >= 0 +``` + +This is a special type of grid that is created from a drawn canvas. For this type of layout `canvas` is required and `size` is ignored if specified. + +`canvas` is a list of strings that form a rectangular grid, from which the layout's `size` is determined automatically. Every space in the canvas creates an empty slot, while every character that is not a space creates a filled mission slot. The resulting grid determines its indices like [Grid](#Grid). + +```yaml +type: canvas +canvas: +- ' ggg ' # 0 +- ' ggggg ' # 1 +- ' ggggg ' # 2 +- ' bbb ggg rrr ' # 3 +- 'bbbbb g rrrrr' # 4 +- 'bbbbb rrrrr' # 5 +- ' ggg bbb ' # 6 +- 'ggggg bbbbb' # 7 +- 'gggg bbbb' # 8 +- 'ggg rrr bbb' # 9 +- ' gg rrrrr bb ' # 10 +- ' rrrrr ' # 11 +- ' rrrrr ' # 12 +- ' rrr ' # 13 +jump_distance_orthogonal: 2 +jump_distance_diagonal: 1 +missions: +- index: group(g) + mission_pool: Terran Missions +- index: group(b) + mission_pool: Protoss Missions +- index: group(r) + mission_pool: Zerg Missions +``` +This example draws the Archipelago logo using missions of different races as its colors. Note that while this example fits into 13 lines, there is no set limit for how many lines you may use, and likewise lines may be as long as you need them to be. Short lines are padded with spaces to match the longest line in the canvas, so lines are left-aligned in this case. + +You may have noticed that the above example has gaps between missions. Canvas layouts support jumping over gaps via `jump_distance_orthogonal` and `jump_distance_diagonal`, which determine the maximum distance over which two missions may be connected, in orthogonal and diagonal directions respectively. Missions at higher distances will only connect if there is no other mission in front of them. + +```yaml +type: canvas +canvas: +- 'A A' +- 'B XB' +jump_distance_orthogonal: 3 +jump_distance_diagonal: 0 +``` +In this example the two `A`s will connect because they are less than 3 missions apart, but the two `B`s will not connect because `X` is between them, and both `B`s will connect to `X` instead. Both sets of `AB`s will also connect because they are neighbors. + +Diagonal jumps function identically, with one exception: +```yaml +type: canvas +canvas: +- 'A ' +- ' B ' +- ' XC' +jump_distance_orthogonal: 1 +jump_distance_diagonal: 1 +``` +Missions that are diagonal neighbors only connect if they do not already share an orthogonal neighbor. In this example `A` and `B` connect, but `B` and `C` don't because `X` already connects them. No such restriction exists for higher-distance diagonal jumps, so it is recommended to keep `jump_distance_diagonal` low. + +Finally, the default entrance and exit on a canvas are dynamically set to be the non-empty slots that are closest to the top left and bottom right corner respectively, but only if you don't set any entrances or exits yourself. It is highly recommended to set your own entrance and exit. + +#### Canvas Index Functions +Canvas supports all of [Grid's index functions](#grid-index-functions), as well as the following: + +##### group(character) +`group(character)` returns the indices which match the given character on the canvas. In the Archipelago logo example, `group(g)` gives the indices of all the `g`s on the canvas. Note that there is no group for spaces, so `group(" ")` does not work. + +--- +### Hopscotch +```yaml +type: hopscotch +width: 7 # Accepts numbers >= 4 +spacer: 2 # Accepts numbers >= 1 +two_start_positions: false # Accepts true/false +``` + +This order alternates between one and two missions becoming available at a time. + +`width` determines how many mini columns are allowed to be next to one another before they wrap around the sides. `spacer` determines the amount of empty slots between diagonals in the client. + +If `two_start_positions`, the top left corner will be set to `empty: true`, and its two neighbors will be entrances instead. + +A `size: 23`, `width: 4`, `spacer: 1` Hopscotch layout has the following indices: +```yaml + 0 2 + 1 3 5 + 4 6 8 +11 7 9 +12 14 10 +13 15 17 + 16 18 20 + 19 21 + 22 +``` +The top left corner (index `0`) is the default entrance. The bottom-most mission of the lowest column (index `size - 1`) is the default exit. + +#### Hopscotch Index Functions +Hopscotch supports the following index functions: + +##### top +`top()` (or `top`) returns the indices of all the top-right corners. In the above example, it returns the indices `2, 5, 8, 11, 14, 17, 20`. + +##### bottom +`bottom()` (or `bottom`) returns the indices of all the bottom-left corners. In the above example, it returns the indices `1, 4, 7, 10, 13, 16, 19, 22`. + +##### middle +`middle()` (or `middle`) returns the indices of all the middle slots. In the above example, it returns the indices `0, 3, 6, 9, 12, 15, 18, 21`. + +##### corner(index) +`corner(index)` returns the indices within the given corner. A corner is a slot in the middle and the slots to the bottom and right of it. `corner(0)` would return `0, 1, 2`, `corner(1)` would return `3, 4, 5`, and so on. In the above example, `corner(7)` will only return `21, 22` because it does not have a right mission. + +--- +### Gauntlet +```yaml +type: gauntlet +width: 7 # Accepts positive numbers +``` +This type works the same way as column, but it goes horizontally instead of vertically. + +`width` is the maximum allowed missions on a row before it wraps around into a new row. + +A `size: 21`, `width: 7` gauntlet has the following indices: +```yaml + 0 1 2 3 4 5 6 + + 7 8 9 10 11 12 13 + +14 15 16 17 18 19 20 +``` +The left-most mission on the top row (index `0`) is the default entrance. The right-most mission on the bottom row (index `size - 1`) is the default exit. + +--- +### Blitz +```yaml +type: blitz +width: 0 # Accepts positive numbers +``` +This type features rows of missions, where beating a mission in a row unlocks the entire next row. + +`width` determines how many missions there are in a row. If set to 0, the width is determined automatically based on the total number of missions (the layout's `size`), but limited to be between 2 and 5. + +A `size: 20`, `width: 5` Blitz layout has the following indices: +```yaml + 0 1 2 3 4 + 5 6 7 8 9 +10 11 12 13 14 +15 16 17 18 19 +``` +The top left corner (index `0`) is the default entrance. The right-most mission on the bottom row (index `size - 1`) is the default exit. + +#### Blitz Index Functions +Blitz supports the following index function: + +##### row(height) +`row(height)` returns the indices of the row at the given zero-based height. In the above example, `row(1)` would return `5, 6, 7, 8, 9`. diff --git a/worlds/sc2/docs/en_Starcraft 2.md b/worlds/sc2/docs/en_Starcraft 2.md index e860e8a6b6bb..74ba46c31d37 100644 --- a/worlds/sc2/docs/en_Starcraft 2.md +++ b/worlds/sc2/docs/en_Starcraft 2.md @@ -12,7 +12,7 @@ The following unlocks are randomized as items: 1. Your ability to build any non-worker unit. 2. Unit specific upgrades including some combinations not available in the vanilla campaigns, such as both strain choices simultaneously for Zerg and every Spear of Adun upgrade simultaneously for Protoss! -3. Your ability to get the generic unit upgrades, such as attack and armour upgrades. +3. Your ability to get the generic unit upgrades, such as attack and armor upgrades. 4. Other miscellaneous upgrades such as laboratory upgrades and mercenaries for Terran, Kerrigan levels and upgrades for Zerg, and Spear of Adun upgrades for Protoss. 5. Small boosts to your starting mineral, vespene gas, and supply totals on each mission. @@ -94,22 +94,31 @@ Will overwrite existing files * Run without arguments to list all factions and colors that are available. * `/option [option_name] [option_value]` Sets an option normally controlled by your yaml after generation. * Run without arguments to list all options. + * Run without `option_value` to check the current value of the option * Options pertain to automatic cutscene skipping, Kerrigan presence, Spear of Adun presence, starting resource amounts, controlling AI allies, etc. * `/disable_mission_check` Disables the check to see if a mission is available to play. Meant for co-op runs where one player can play the next mission in a chain the other player is doing. -* `/play [mission_id]` Starts a StarCraft 2 mission based off of the mission_id provided -* `/available` Get what missions are currently available to play -* `/unfinished` Get what missions are currently available to play and have not had all locations checked * `/set_path [path]` Manually set the SC2 install directory (if the automatic detection fails) +* `/windowed_mode [true|false]` to toggle whether the game will start in windowed mode. Note that the behavior of the command `/received` was modified in the StarCraft 2 client. -In the Common client of Archipelago, the command returns the list of items received in the reverse order they were -received. -In the StarCraft 2 client, the returned list will be divided by races (i.e., Any, Protoss, Terran, and Zerg). -Additionally, upgrades are grouped beneath their corresponding units or buildings. -A filter parameter can be provided, e.g., `/received Thor`, to limit the number of items shown. -Every item whose name, race, or group name contains the provided parameter will be shown. + +* In the Common client of Archipelago, the command returns the list of items received in the reverse order they were + received. +* In the StarCraft 2 client, the returned list will be divided by races (i.e., Any, Protoss, Terran, and Zerg). + Additionally, upgrades are grouped beneath their corresponding units or buildings. +* A filter parameter can be provided, e.g., `/received Thor`, to limit the number of items shown. + * Every item whose name, race, or group name contains the provided parameter will be shown. +* Use `/received recent [amount]` to display the last `amount` items received in chronological order + * `amount` defaults to 20 if not specified + +## Client-side settings +Some settings can be set or overridden on the client side rather than within a world's options. +This can allow, for example, overriding difficulty to always be `hard` no matter what the world specified. +It can also modify display properties, like the client's window size on startup or the launcher button colours. + +Modify these within the `sc2_options` section of the host.yaml file within the Archipelago directory. ## Particularities in a multiworld @@ -118,9 +127,9 @@ Every item whose name, race, or group name contains the provided parameter will One of the default options of multiworlds is that once a world has achieved its goal, it collects its items from all other worlds. If you do not want this to happen, you should ask the person generating the multiworld to set the `Collect Permission` -option to something else, e.g., manual. +option to something else, such as "Manual" or "Allow on goal completion." If the generation is not done via the website, the person that does the generation should modify the `collect_mode` -option in their `host.yaml` file prior to generation. +option in their `host.yaml` file prior to generation. If the multiworld has already been generated, the host can use the command `/option collect_mode [value]` to change this option. @@ -135,4 +144,6 @@ This does not affect the game and can be ignored. - Currently, the StarCraft 2 client uses the Victory locations to determine which missions have been completed. As a result, the Archipelago collect feature can sometime grant access to missions that are connected to a mission that you did not complete. + - If all victory locations are collected in this manner, victory is not sent until the player replays a final mission + and recollects the victory location. diff --git a/worlds/sc2/docs/fr_Starcraft 2.md b/worlds/sc2/docs/fr_Starcraft 2.md index 190802e91bff..c340ecc2042a 100644 --- a/worlds/sc2/docs/fr_Starcraft 2.md +++ b/worlds/sc2/docs/fr_Starcraft 2.md @@ -112,10 +112,6 @@ supplémentaires données au début des missions, la capacité de contrôler les * `/disable_mission_check` Désactive les requit pour lancer les missions. Cette option a pour but de permettre de jouer en mode coopératif en permettant à un joueur de jouer à la prochaine mission de la chaîne qu'un autre joueur est en train d'entamer. -* `/play [mission_id]` Lance la mission correspondant à l'identifiant donné. -* `/available` Affiche les missions qui sont présentement accessibles. -* `/unfinished` Affiche les missions qui sont présentement accessibles et dont certains des objectifs permettant -l'accès à un *item* n'ont pas été accomplis. * `/set_path [path]` Permet de définir manuellement où *StarCraft 2* est installé ce qui est pertinent seulement si la détection automatique de cette dernière échoue. @@ -151,4 +147,4 @@ Cela n'affecte pas le jeu et peut être ignoré. - Actuellement, le client de *StarCraft 2* utilise la *location* associée à la victoire d'une mission pour déterminer si celle-ci a été complétée. En conséquence, la fonctionnalité *collect* d'*Archipelago* peut rendre accessible des missions connectées à une -mission que vous n'avez pas terminée. \ No newline at end of file +mission que vous n'avez pas terminée. diff --git a/worlds/sc2/docs/setup_en.md b/worlds/sc2/docs/setup_en.md index 4364008b58a7..0ddb9a3bf10e 100644 --- a/worlds/sc2/docs/setup_en.md +++ b/worlds/sc2/docs/setup_en.md @@ -62,69 +62,128 @@ If the Progression Balancing of one world is greater than that of others, items obtained early, and vice versa if its value is smaller. However, StarCraft 2 is more permissive regarding the items that can be used to progress, so this option has little influence on progression in a StarCraft 2 world. -StarCraft 2. Since this option increases the time required to generate a MultiWorld, we recommend deactivating it (i.e., setting it to zero) for a StarCraft 2 world. -#### How do I specify items in a list, like in excluded items? +#### What does Tactics Level do? + +Tactics level allows controlling the difficulty through what items you're likely to get early. +This is independent of game difficulty like causal, normal, hard, or brutal. + +"Standard" and "Advanced" levels are guaranteed to be beatable with the items you are given. +The logic is a little more restrictive than a player's creativity, so an advanced player is likely to have +more items than they need in any situation. These levels are entirely safe to use in a multiworld. + +The "Any Units" level only guarantees that a minimum number of faction-appropriate units or buildings are reachable +early on, with minimal restrictions on what those units are. +Generation will guarantee a number of faction-appropriate units are reachable before starting a mission, +based on the depth of that mission. For example, if the third mission is a zerg mission, it is guaranteed that 2 +zerg units are somewhere in the preceding 2 missions. This logic level is not guaranteed to be beatable, and may +require lowering the difficulty level (`/difficulty` in the client) if many no-build missions are excluded. + +The "No Logic" level provides no logical safeguards for beatability. It is only safe to use in a multiworld if the player curates +a start inventory or the organizer is okay with the possibility of the StarCraft 2 world being unbeatable. +Safeguards exist so that other games' items placed in the StarCraft 2 world are reachable under "Advanced" logic rules. + +#### How do I specify items in a list, like in enabled campaigns? You can look up the syntax for yaml collections in the [YAML specification](https://yaml.org/spec/1.2.2/#21-collections). -For lists, every item goes on its own line, started with a hyphen: +For lists, every item goes on its own line, started with a hyphen. +Putting each element on its own line makes it easy to toggle elements by commenting +(ie adding a `#` character at the start of the line). + +```yaml + enabled_campaigns: + - Wings of Liberty + # - Heart of the Swarm + - Legacy of the Void + - Nova Covert Ops + - Prophecy + - 'Whispers of Oblivion (Legacy of the Void: Prologue)' + # - 'Into the Void (Legacy of the Void: Epilogue)' +``` + +An inline syntax may also be used for short lists: ```yaml -excluded_items: - - Battlecruiser - - Drop-Pods (Kerrigan Tier 7) + enabled_campaigns: ['Wings of Liberty', 'Nova Covert Ops'] ``` An empty list is just a matching pair of square brackets: `[]`. -That's the default value in the template, which should let you know to use this syntax. +That's often the default value in the template, which should let you know to use this syntax. -#### How do I specify items for the starting inventory? +#### How do I specify items for key-value mappings, like starting inventory or filler item distribution? -The starting inventory is a YAML mapping rather than a list, which associates an item with the amount you start with. -The syntax looks like the item name, followed by a colon, then a whitespace character, and then the value: +Many options pertaining to the item pool are yaml mappings. +These are several lines, where each line looks like a name, followed by a colon, then a space, then a value. ```yaml -start_inventory: - Micro-Filtering: 1 - Additional Starting Vespene: 5 + start_inventory: + Micro-Filtering: 1 + Additional Starting Vespene: 5 + + locked_items: + MULE (Command Center): 1 ``` +For options like `start_inventory`, `locked_items`, `excluded_items`, and `unexcluded_items`, the value +is a number specifying how many copies of an item to start with/exclude/lock. +Note the name can also be an item group, and the value will then be added to the values for all the items +within the group. A value of `0` will exclude all copies of an item, but will add +0 if the value +is also specified by another name. + +For options like `filler_items_distribution`, the value is a number specifying the relative weight of +a filler item being that particular item. + +For the `custom_mission_order` option, the value is a nested structure of other mapppings to specify the structure +of the mission order. See the [Custom Mission Order documentation](/tutorial/Starcraft%202/custom_mission_orders_en) + An empty mapping is just a matching pair of curly braces: `{}`. That's the default value in the template, which should let you know to use this syntax. #### How do I know the exact names of items and locations? -The [*datapackage*](/datapackage) page of the Archipelago website provides a complete list of the items and locations -for each game that it currently supports, including StarCraft 2. - -You can also look up a complete list of the item names in the +You can look up a complete list of the item names in the [Icon Repository](https://matthewmarinets.github.io/ap_sc2_icons/) page. This page also contains supplementary information of each item. -However, the items shown in that page might differ from those shown in the datapackage page of Archipelago since the -former is generated, most of the time, from beta versions of StarCraft 2 Archipelago undergoing development. -As for the locations, you can see all the locations associated to a mission in your world by placing your cursor over -the mission in the 'StarCraft 2 Launcher' tab in the client. +Locations are of the format `: `. Names are most easily looked up by hovering +your mouse over a mission in the launcher tab of a client. Note this requires already generating a game connect to. + +This information can also be found in the [*datapackage*](/datapackage) page of the Archipelago website. +This page includes all data associated with all games. ## How do I join a MultiWorld game? 1. Run ArchipelagoStarcraft2Client.exe. - macOS users should instead follow the instructions found at ["Running in macOS"](#running-in-macos) for this step only. -2. Type `/connect [server ip]`. +2. In the Archipelago tab, type `/connect [server IP]`. - If you're running through the website, the server IP should be displayed near the top of the room page. + - The server IP may also be typed into the top bar, and then clicking "Connect" 3. Type your slot name from your YAML when prompted. 4. If the server has a password, enter that when prompted. 5. Once connected, switch to the 'StarCraft 2 Launcher' tab in the client. There, you can see all the missions in your -world. -Unreachable missions will have greyed-out text. Just click on an available mission to start it! +world. + +Unreachable missions will have greyed-out text. Completed missions (all locations collected) will have white text. +Accessible but incomplete missions will have blue text. Goal missions will have a gold border. +Mission buttons will have a color corresponding to the faction you play as in that mission. + +Click on an available mission to start it. ## The game isn't launching when I try to start a mission. -First, check the log file for issues (stored at `[Archipelago Directory]/logs/SC2Client.txt`). +Usually, this is caused by the mod files not being downloaded. +Make sure you have run `/download_data` in the Archipelago tab before playing. +You should only have to run `/download_data` again to pick up bugfixes and updates. + +Make sure that you are running an up-to-date version of the client. +Check the [Archipelago Releases Page](https://github.com/ArchipelagoMW/Archipelago/releases) to +look up what the latest version is (RC releases are not necessary; that stands for "Release Candidate"). + +If these things are in order, check the log file for issues (stored at `[Archipelago Directory]/logs/Starcraft2Client.txt`). If you can't figure out the log file, visit our [Discord's](https://discord.com/invite/8Z65BR2) tech-support channel for help. Please include a specific description of what's going wrong and attach your log file to your message. @@ -150,16 +209,15 @@ Note: to launch the client, you will need to run the command `python3 Starcraft2 ## Running in Linux -To run StarCraft 2 through Archipelago in Linux, you will need to install the game using Wine, then run the Linux build +To run StarCraft 2 through Archipelago on Linux, you will need to install the game using Wine, then run the Linux build of the Archipelago client. -Make sure you have StarCraft 2 installed using Wine, and that you have followed the -[installation procedures](#how-do-i-install-this-randomizer?) to add the Archipelago maps to the correct location. -You will not need to copy the `.dll` files. -If you're having trouble installing or running StarCraft 2 on Linux, it is recommend to use the Lutris installer. +Make sure you have StarCraft 2 installed using Wine, and you know where Wine and Starcraft 2 are installed. +If you're having trouble installing or running StarCraft 2 on Linux, it is recommended to use the Lutris installer. -Copy the following into a .sh file, replacing the values of **WINE** and **SC2PATH** variables with the relevant -locations, as well as setting **PATH_TO_ARCHIPELAGO** to the directory containing the AppImage if it is not in the same +Copy the following into a .sh file, preferably within your Archipelago directory, +replacing the values of **WINE** and **SC2PATH** variables with the relevant locations, +as well as setting **PATH_TO_ARCHIPELAGO** to the directory containing the AppImage if it is not in the same folder as the script. ```sh @@ -170,6 +228,13 @@ export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python # FIXME Replace with path to the version of Wine used to run SC2 export WINE="/usr/bin/wine" +# FIXME If using nondefault wineprefix for SC2 install (usual for Lutris installs), uncomment the next line and change the path +#export WINEPREFIX="/path/to/wineprefix" + +# FIXME Uncomment the following lines if experiencing issues with DXVK (like DDRAW.ddl does not exist) +#export WINEDLLOVERRIDES=d3d10core,d3d11,d3d12,d3d12core,d3d9,d3dcompiler_33,d3dcompiler_34,d3dcompiler_35,d3dcompiler_36,d3dcompiler_37,d3dcompiler_38,d3dcompiler_39,d3dcompiler_40,d3dcompiler_41,d3dcompiler_42,d3dcompiler_43,d3dcompiler_46,d3dcompiler_47,d3dx10,d3dx10_33,d3dx10_34,d3dx10_35,d3dx10_36,d3dx10_37,d3dx10_38,d3dx10_39,d3dx10_40,d3dx10_41,d3dx10_42,d3dx10_43,d3dx11_42,d3dx11_43,d3dx9_24,d3dx9_25,d3dx9_26,d3dx9_27,d3dx9_28,d3dx9_29,d3dx9_30,d3dx9_31,d3dx9_32,d3dx9_33,d3dx9_34,d3dx9_35,d3dx9_36,d3dx9_37,d3dx9_38,d3dx9_39,d3dx9_40,d3dx9_41,d3dx9_42,d3dx9_43,dxgi,nvapi,nvapi64 +#export DXVK_ENABLE_NVAPI=1 + # FIXME Replace with path to StarCraft II install folder export SC2PATH="/home/user/Games/starcraft-ii/drive_c/Program Files (x86)/StarCraft II/" @@ -193,3 +258,6 @@ below, replacing **${ID}** with the numerical ID. This will get all of the relevant environment variables Lutris sets to run StarCraft 2 in a script, including the path to the Wine binary that Lutris uses. You can then remove the line that runs the Battle.Net launcher and copy the code above into the existing script. + +Finally, you can run the script to start your Archipelago client, +and it should be able to launch Starcraft 2 when you start a mission. diff --git a/worlds/sc2/docs/setup_fr.md b/worlds/sc2/docs/setup_fr.md index 7cdb7225b431..5ce9b4b9eb14 100644 --- a/worlds/sc2/docs/setup_fr.md +++ b/worlds/sc2/docs/setup_fr.md @@ -87,7 +87,7 @@ Pour les listes, chaque *item* doit être sur sa propre ligne et doit être pré ```yaml excluded_items: - Battlecruiser - - Drop-Pods (Kerrigan Tier 7) + - Drop-Pods (Kerrigan Ability) ``` Une liste vide est représentée par une paire de crochets: `[]`. diff --git a/worlds/sc2/gui_config.py b/worlds/sc2/gui_config.py new file mode 100644 index 000000000000..b3039da19ebb --- /dev/null +++ b/worlds/sc2/gui_config.py @@ -0,0 +1,98 @@ +""" +Import this before importing client_gui.py to set window defaults from world settings. +""" +from .settings import Starcraft2Settings +from typing import List, Tuple, Any + + +def get_window_defaults() -> Tuple[List[str], int, int]: + """ + Gets the window size options from the sc2 settings. + Returns a list of warnings to be printed once the GUI is started, followed by the window width and height + """ + from . import SC2World + + # validate settings + warnings: List[str] = [] + if isinstance(SC2World.settings.window_height, int) and SC2World.settings.window_height > 0: + window_height = SC2World.settings.window_height + else: + warnings.append(f"Invalid value for options.yaml key sc2_options.window_height: '{SC2World.settings.window_height}'. Expected a positive integer.") + window_height = Starcraft2Settings.window_height + if isinstance(SC2World.settings.window_width, int) and SC2World.settings.window_width > 0: + window_width = SC2World.settings.window_width + else: + warnings.append(f"Invalid value for options.yaml key sc2_options.window_width: '{SC2World.settings.window_width}'. Expected a positive integer.") + window_width = Starcraft2Settings.window_width + + return warnings, window_width, window_height + + +def validate_color(color: Any, default: Tuple[float, float, float]) -> Tuple[Tuple[str, ...], Tuple[float, float, float]]: + if isinstance(color, int): + if color < 0: + return ('Integer color was negative; expected a value from 0 to 0xffffff',), default + return (), ( + ((color >> 8) & 0xff) / 255, + ((color >> 4) & 0xff) / 255, + ((color >> 0) & 0xff) / 255, + ) + elif color == 'default': + return (), default + elif color == 'white': + return (), (0.9, 0.9, 0.9) + elif color == 'black': + return (), (0.0, 0.0, 0.0) + elif color == 'grey': + return (), (0.345, 0.345, 0.345) + elif color == 'red': + return (), (0.85, 0.2, 0.1) + elif color == 'orange': + return (), (1.0, 0.65, 0.37) + elif color == 'green': + return (), (0.24, 0.84, 0.55) + elif color == 'blue': + return (), (0.3, 0.4, 1.0) + elif color == 'pink': + return (), (0.886, 0.176, 0.843) + elif not isinstance(color, list): + return (f'Invalid type {type(color)}; expected 3-element list or integer',), default + elif len(color) != 3: + return (f'Wrong number of elements in color; expected 3, got {len(color)}',), default + result: List[float] = [0.0, 0.0, 0.0] + errors: List[str] = [] + expected = 'expected a number from 0 to 1' + for index, element in enumerate(color): + if isinstance(element, int): + element = float(element) + if not isinstance(element, float): + errors.append(f'Invalid type {type(element)} at index {index}; {expected}') + continue + if element < 0: + errors.append(f'Negative element {element} at index {index}; {expected}') + continue + if element > 1: + errors.append(f'Element {element} at index {index} is greater than 1; {expected}') + result[index] = 1.0 + continue + result[index] = element + return tuple(errors), tuple(result) + + +def get_button_color(race: str) -> Tuple[Tuple[str, ...], Tuple[float, float, float]]: + from . import SC2World + baseline_color = 0.345 # the button graphic is grey, with this value in each color channel + if race == 'TERRAN': + user_color: list = SC2World.settings.terran_button_color + default_color = (0.0838, 0.2898, 0.2346) + elif race == 'PROTOSS': + user_color = SC2World.settings.protoss_button_color + default_color = (0.345, 0.22425, 0.12765) + elif race == 'ZERG': + user_color = SC2World.settings.zerg_button_color + default_color = (0.18975, 0.2415, 0.345) + else: + user_color = [baseline_color, baseline_color, baseline_color] + default_color = (baseline_color, baseline_color, baseline_color) + errors, color = validate_color(user_color, default_color) + return errors, tuple(x / baseline_color for x in color) diff --git a/worlds/sc2/item/__init__.py b/worlds/sc2/item/__init__.py new file mode 100644 index 000000000000..7316a5f113ad --- /dev/null +++ b/worlds/sc2/item/__init__.py @@ -0,0 +1,173 @@ +import enum +import typing +from dataclasses import dataclass +from typing import Optional, Union, Dict, Type + +from BaseClasses import Item, ItemClassification +from ..mission_tables import SC2Race + + +class ItemFilterFlags(enum.IntFlag): + """Removed > Start Inventory > Locked > Excluded > Requested > Culled""" + Available = 0 + StartInventory = enum.auto() + Locked = enum.auto() + """Used to flag items that are never allowed to be culled.""" + LogicLocked = enum.auto() + """Locked by item cull logic checks; logic-locked w/a upgrades may be removed if all parents are removed""" + Requested = enum.auto() + """Soft-locked items by item count checks during item culling; may be re-added""" + Removed = enum.auto() + """Marked for immediate removal""" + UserExcluded = enum.auto() + """Excluded by the user; display an error message if failing to exclude""" + FilterExcluded = enum.auto() + """Excluded by item filtering""" + Culled = enum.auto() + """Soft-removed by the item culling""" + NonLocal = enum.auto() + Plando = enum.auto() + AllowedOrphan = enum.auto() + """Used to flag items that shouldn't be filtered out with their parents""" + ForceProgression = enum.auto() + """Used to flag items that aren't classified as progression by default""" + + Unexcludable = StartInventory|Plando|Locked|LogicLocked + UnexcludableUpgrade = StartInventory|Plando|Locked + Uncullable = StartInventory|Plando|Locked|LogicLocked|Requested + Excluded = UserExcluded|FilterExcluded + RequestedOrBetter = StartInventory|Locked|LogicLocked|Requested + CulledOrBetter = Removed|Excluded|Culled + + +class StarcraftItem(Item): + game: str = "Starcraft 2" + filter_flags: ItemFilterFlags = ItemFilterFlags.Available + + def __init__(self, name: str, classification: ItemClassification, code: Optional[int], player: int, filter_flags: ItemFilterFlags = ItemFilterFlags.Available): + super().__init__(name, classification, code, player) + self.filter_flags = filter_flags + +class ItemTypeEnum(enum.Enum): + def __new__(cls, *args, **kwargs): + value = len(cls.__members__) + 1 + obj = object.__new__(cls) + obj._value_ = value + return obj + + def __init__(self, name: str, flag_word: int): + self.display_name = name + self.flag_word = flag_word + + +class TerranItemType(ItemTypeEnum): + Armory_1 = "Armory", 0 + """General Terran unit upgrades""" + Armory_2 = "Armory", 1 + Armory_3 = "Armory", 2 + Armory_4 = "Armory", 3 + Armory_5 = "Armory", 4 + Armory_6 = "Armory", 5 + Armory_7 = "Armory", 6 + Progressive = "Progressive Upgrade", 7 + Laboratory = "Laboratory", 8 + Upgrade = "Upgrade", 9 + Unit = "Unit", 10 + Building = "Building", 11 + Mercenary = "Mercenary", 12 + Nova_Gear = "Nova Gear", 13 + Progressive_2 = "Progressive Upgrade", 14 + Unit_2 = "Unit", 15 + + +class ZergItemType(ItemTypeEnum): + Ability = "Ability", 0 + """Kerrigan abilities""" + Mutation_1 = "Mutation", 1 + Strain = "Strain", 2 + Morph = "Morph", 3 + Upgrade = "Upgrade", 4 + Mercenary = "Mercenary", 5 + Unit = "Unit", 6 + Level = "Level", 7 + """Kerrigan level packs""" + Primal_Form = "Primal Form", 8 + Evolution_Pit = "Evolution Pit", 9 + """Zerg global economy upgrades, like automated extractors""" + Mutation_2 = "Mutation", 10 + Mutation_3 = "Mutation", 11 + Mutation_4 = "Mutation", 12 + Progressive = "Progressive Upgrade", 13 + Mutation_5 = "Mutation", 14 + + +class ProtossItemType(ItemTypeEnum): + Unit = "Unit", 0 + Unit_2 = "Unit", 1 + Upgrade = "Upgrade", 2 + Building = "Building", 3 + Progressive = "Progressive Upgrade", 4 + Spear_Of_Adun = "Spear of Adun", 5 + Solarite_Core = "Solarite Core", 6 + """Protoss global effects, such as reconstruction beam or automated assimilators""" + Forge_1 = "Forge", 7 + """General Protoss unit upgrades""" + Forge_2 = "Forge", 8 + """General Protoss unit upgrades""" + Forge_3 = "Forge", 9 + """General Protoss unit upgrades""" + Forge_4 = "Forge", 10 + """General Protoss unit upgrades""" + Forge_5 = "Forge", 11 + """General Protoss unit upgrades""" + War_Council = "War Council", 12 + War_Council_2 = "War Council", 13 + ShieldRegeneration = "Shield Regeneration Group", 14 + + +class FactionlessItemType(ItemTypeEnum): + Minerals = "Minerals", 0 + Vespene = "Vespene", 1 + Supply = "Supply", 2 + MaxSupply = "Max Supply", 3 + BuildingSpeed = "Building Speed", 4 + Nothing = "Nothing Group", 5 + Deprecated = "Deprecated", 6 + MaxSupplyTrap = "Max Supply Trap", 7 + ResearchSpeed = "Research Speed", 8 + ResearchCost = "Research Cost", 9 + Keys = "Keys", -1 + + +ItemType = Union[TerranItemType, ZergItemType, ProtossItemType, FactionlessItemType] +race_to_item_type: Dict[SC2Race, Type[ItemTypeEnum]] = { + SC2Race.ANY: FactionlessItemType, + SC2Race.TERRAN: TerranItemType, + SC2Race.ZERG: ZergItemType, + SC2Race.PROTOSS: ProtossItemType, +} + + +class ItemData(typing.NamedTuple): + code: int + type: ItemType + number: int # Important for bot commands to send the item into the game + race: SC2Race + classification: ItemClassification = ItemClassification.useful + quantity: int = 1 + parent: typing.Optional[str] = None + important_for_filtering: bool = False + + def is_important_for_filtering(self): + return ( + self.important_for_filtering + or self.classification == ItemClassification.progression + or self.classification == ItemClassification.progression_skip_balancing + ) + +@dataclass +class FilterItem: + name: str + data: ItemData + index: int = 0 + flags: ItemFilterFlags = ItemFilterFlags.Available diff --git a/worlds/sc2/item/item_annotations.py b/worlds/sc2/item/item_annotations.py new file mode 100644 index 000000000000..cd28e071b527 --- /dev/null +++ b/worlds/sc2/item/item_annotations.py @@ -0,0 +1,178 @@ +""" +Annotations to add to item names sent to the in-game message panel +""" +from . import item_names + +ITEM_NAME_ANNOTATIONS = { + item_names.MARINE: "(Barracks)", + item_names.MEDIC: "(Barracks)", + item_names.FIREBAT: "(Barracks)", + item_names.MARAUDER: "(Barracks)", + item_names.REAPER: "(Barracks)", + item_names.HELLION: "(Factory)", + item_names.VULTURE: "(Factory)", + item_names.GOLIATH: "(Factory)", + item_names.DIAMONDBACK: "(Factory)", + item_names.SIEGE_TANK: "(Factory)", + item_names.MEDIVAC: "(Starport)", + item_names.WRAITH: "(Starport)", + item_names.VIKING: "(Starport)", + item_names.BANSHEE: "(Starport)", + item_names.BATTLECRUISER: "(Starport)", + item_names.GHOST: "(Barracks)", + item_names.SPECTRE: "(Barracks)", + item_names.THOR: "(Factory)", + item_names.RAVEN: "(Starport)", + item_names.SCIENCE_VESSEL: "(Starport)", + item_names.PREDATOR: "(Factory)", + item_names.HERCULES: "(Starport)", + + item_names.HERC: "(Barracks)", + item_names.DOMINION_TROOPER: "(Barracks)", + item_names.WIDOW_MINE: "(Factory)", + item_names.CYCLONE: "(Factory)", + item_names.WARHOUND: "(Factory)", + item_names.LIBERATOR: "(Starport)", + item_names.VALKYRIE: "(Starport)", + + item_names.SON_OF_KORHAL: "(Elite Barracks)", + item_names.AEGIS_GUARD: "(Elite Barracks)", + item_names.FIELD_RESPONSE_THETA: "(Elite Barracks)", + item_names.EMPERORS_SHADOW: "(Elite Barracks)", + item_names.BULWARK_COMPANY: "(Elite Factory)", + item_names.SHOCK_DIVISION: "(Elite Factory)", + item_names.BLACKHAMMER: "(Elite Factory)", + item_names.SKY_FURY: "(Elite Starport)", + item_names.NIGHT_HAWK: "(Elite Starport)", + item_names.NIGHT_WOLF: "(Elite Starport)", + item_names.EMPERORS_GUARDIAN: "(Elite Starport)", + item_names.PRIDE_OF_AUGUSTRGRAD: "(Elite Starport)", + + item_names.WAR_PIGS: "(Terran Mercenary)", + item_names.DEVIL_DOGS: "(Terran Mercenary)", + item_names.HAMMER_SECURITIES: "(Terran Mercenary)", + item_names.SPARTAN_COMPANY: "(Terran Mercenary)", + item_names.SIEGE_BREAKERS: "(Terran Mercenary)", + item_names.HELS_ANGELS: "(Terran Mercenary)", + item_names.DUSK_WINGS: "(Terran Mercenary)", + item_names.JACKSONS_REVENGE: "(Terran Mercenary)", + item_names.SKIBIS_ANGELS: "(Terran Mercenary)", + item_names.DEATH_HEADS: "(Terran Mercenary)", + item_names.WINGED_NIGHTMARES: "(Terran Mercenary)", + item_names.MIDNIGHT_RIDERS: "(Terran Mercenary)", + item_names.BRYNHILDS: "(Terran Mercenary)", + item_names.JOTUN: "(Terran Mercenary)", + + item_names.BUNKER: "(Terran Building)", + item_names.MISSILE_TURRET: "(Terran Building)", + item_names.SENSOR_TOWER: "(Terran Building)", + item_names.PLANETARY_FORTRESS: "(Terran Building)", + item_names.PERDITION_TURRET: "(Terran Building)", + item_names.DEVASTATOR_TURRET: "(Terran Building)", + item_names.PSI_DISRUPTER: "(Terran Building)", + item_names.HIVE_MIND_EMULATOR: "(Terran Building)", + + item_names.ZERGLING: "(Larva)", + item_names.SWARM_QUEEN: "(Hatchery)", + item_names.ROACH: "(Larva)", + item_names.HYDRALISK: "(Larva)", + item_names.ABERRATION: "(Larva)", + item_names.MUTALISK: "(Larva)", + item_names.SWARM_HOST: "(Larva)", + item_names.INFESTOR: "(Larva)", + item_names.ULTRALISK: "(Larva)", + item_names.PYGALISK: "(Larva)", + item_names.CORRUPTOR: "(Larva)", + item_names.SCOURGE: "(Larva)", + item_names.BROOD_QUEEN: "(Larva)", + item_names.DEFILER: "(Larva)", + item_names.INFESTED_MARINE: "(Infested Barracks)", + item_names.INFESTED_SIEGE_TANK: "(Infested Factory)", + item_names.INFESTED_DIAMONDBACK: "(Infested Factory)", + item_names.BULLFROG: "(Infested Factory)", + item_names.INFESTED_BANSHEE: "(Infested Starport)", + item_names.INFESTED_LIBERATOR: "(Infested Starport)", + + item_names.ZERGLING_BANELING_ASPECT: "(Zergling Morph)", + item_names.HYDRALISK_IMPALER_ASPECT: "(Hydralisk Morph)", + item_names.HYDRALISK_LURKER_ASPECT: "(Hydralisk Morph)", + item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT: "(Mutalisk/Corruptor Morph)", + item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT: "(Mutalisk/Corruptor Morph)", + item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT: "(Mutalisk/Corruptor Morph)", + item_names.MUTALISK_CORRUPTOR_DEVOURER_ASPECT: "(Mutalisk/Corruptor Morph)", + item_names.ROACH_RAVAGER_ASPECT: "(Roach Morph)", + item_names.OVERLORD_OVERSEER_ASPECT: "(Overlord Morph)", + item_names.ROACH_PRIMAL_IGNITER_ASPECT: "(Roach Morph)", + item_names.ULTRALISK_TYRANNOZOR_ASPECT: "(Ultralisk Morph)", + + item_names.INFESTED_MEDICS: "(Zerg Mercenary)", + item_names.INFESTED_SIEGE_BREAKERS: "(Zerg Mercenary)", + item_names.INFESTED_DUSK_WINGS: "(Zerg Mercenary)", + item_names.DEVOURING_ONES: "(Zerg Mercenary)", + item_names.HUNTER_KILLERS: "(Zerg Mercenary)", + item_names.TORRASQUE_MERC: "(Zerg Mercenary)", + item_names.HUNTERLING: "(Zerg Mercenary)", + item_names.YGGDRASIL: "(Zerg Mercenary)", + item_names.CAUSTIC_HORRORS: "(Zerg Mercenary)", + + item_names.SPORE_CRAWLER: "(Zerg Building)", + item_names.SPINE_CRAWLER: "(Zerg Building)", + item_names.BILE_LAUNCHER: "(Zerg Building)", + item_names.INFESTED_BUNKER: "(Zerg Building)", + item_names.INFESTED_MISSILE_TURRET: "(Zerg Building)", + item_names.NYDUS_WORM: "(Nydus Network)", + item_names.ECHIDNA_WORM: "(Nydus Network)", + + item_names.ZEALOT: "(Gateway, Aiur)", + item_names.CENTURION: "(Gateway, Nerazim)", + item_names.SENTINEL: "(Gateway, Purifier)", + item_names.SUPPLICANT: "(Gateway, Tal'darim)", + item_names.STALKER: "(Gateway, Nerazim)", + item_names.INSTIGATOR: "(Gateway, Purifier)", + item_names.SLAYER: "(Gateway, Tal'darim)", + item_names.SENTRY: "(Gateway, Aiur)", + item_names.ENERGIZER: "(Gateway, Purifier)", + item_names.HAVOC: "(Gateway, Tal'darim)", + item_names.HIGH_TEMPLAR: "(Gateway, Aiur)", + item_names.SIGNIFIER: "(Gateway, Nerazim)", + item_names.ASCENDANT: "(Gateway, Tal'darim)", + item_names.DARK_TEMPLAR: "(Gateway, Nerazim)", + item_names.AVENGER: "(Gateway, Aiur)", + item_names.BLOOD_HUNTER: "(Gateway, Tal'darim)", + item_names.DRAGOON: "(Gateway, Aiur)", + item_names.DARK_ARCHON: "(Gateway, Nerazim)", + item_names.ADEPT: "(Gateway, Purifier)", + item_names.OBSERVER: "(Robotics Facility)", + item_names.WARP_PRISM: "(Robotics Facility)", + item_names.IMMORTAL: "(Robotics Facility, Aiur)", + item_names.ANNIHILATOR: "(Robotics Facility, Nerazim)", + item_names.VANGUARD: "(Robotics Facility, Tal'darim)", + item_names.STALWART: "(Robotics Facility, Purifier)", + item_names.COLOSSUS: "(Robotics Facility, Purifier)", + item_names.WRATHWALKER: "(Robotics Facility, Tal'darim)", + item_names.REAVER: "(Robotics Facility, Aiur)", + item_names.DISRUPTOR: "(Robotics Facility, Purifier)", + item_names.PHOENIX: "(Stargate, Aiur)", + item_names.MIRAGE: "(Stargate, Purifier)", + item_names.SKIRMISHER: "(Stargate, Tal'darim)", + item_names.CORSAIR: "(Stargate, Nerazim)", + item_names.VOID_RAY: "(Stargate, Nerazim)", + item_names.DESTROYER: "(Stargate, Tal'darim)", + item_names.PULSAR: "(Stargate, Aiur)", + item_names.DAWNBRINGER: "(Stargate, Purifier)", + item_names.SCOUT: "(Stargate, Aiur)", + item_names.OPPRESSOR: "(Stargate, Tal'darim)", + item_names.CALADRIUS: "(Stargate, Purifier)", + item_names.MISTWING: "(Stargate, Nerazim)", + item_names.CARRIER: "(Stargate, Aiur)", + item_names.SKYLORD: "(Stargate, Tal'darim)", + item_names.TRIREME: "(Stargate, Purifier)", + item_names.TEMPEST: "(Stargate, Purifier)", + item_names.MOTHERSHIP: "(Stargate, Tal'darim)", + item_names.ARBITER: "(Stargate, Aiur)", + item_names.ORACLE: "(Stargate, Nerazim)", + + item_names.PHOTON_CANNON: "(Protoss Building)", + item_names.KHAYDARIN_MONOLITH: "(Protoss Building)", + item_names.SHIELD_BATTERY: "(Protoss Building)", +} \ No newline at end of file diff --git a/worlds/sc2/item/item_descriptions.py b/worlds/sc2/item/item_descriptions.py new file mode 100644 index 000000000000..f1520df1424c --- /dev/null +++ b/worlds/sc2/item/item_descriptions.py @@ -0,0 +1,1127 @@ +""" +Contains descriptions for Starcraft 2 items. +""" +import inspect + +from . import item_tables, item_names + +WEAPON_ARMOR_UPGRADE_NOTE = inspect.cleandoc(""" + Must be researched during the mission if the mission type isn't set to auto-unlock generic upgrades. +""") +GENERIC_UPGRADE_TEMPLATE = "Increases {} of {} {}.\n" + WEAPON_ARMOR_UPGRADE_NOTE +TERRAN = "Terran" +ZERG = "Zerg" +PROTOSS = "Protoss" + +LASER_TARGETING_SYSTEMS_DESCRIPTION = "Increases vision by 2 and weapon range by 1." +STIMPACK_SMALL_COST = 10 +STIMPACK_SMALL_HEAL = 30 +STIMPACK_LARGE_COST = 20 +STIMPACK_LARGE_HEAL = 60 +STIMPACK_TEMPLATE = inspect.cleandoc(""" + Level 1: Stimpack: Increases unit movement and attack speed for 15 seconds. Injures the unit for {} life. + Level 2: Super Stimpack: Instead of injuring the unit, heals the unit for {} life instead. +""") +STIMPACK_SMALL_DESCRIPTION = STIMPACK_TEMPLATE.format(STIMPACK_SMALL_COST, STIMPACK_SMALL_HEAL) +STIMPACK_LARGE_DESCRIPTION = STIMPACK_TEMPLATE.format(STIMPACK_LARGE_COST, STIMPACK_LARGE_HEAL) +SMART_SERVOS_DESCRIPTION = "Increases transformation speed between modes." +INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE = "{} can be trained from a {} without an attached Tech Lab." +CLOAK_DESCRIPTION_TEMPLATE = "Allows {} to use the Cloak ability." + +DISPLAY_NAME_BROOD_LORD = "Brood Lord" +DISPLAY_NAME_CLOAKED_ASSASSIN = "Dark Templar, Avenger, and Blood Hunter" +DISPLAY_NAME_WORMS = "Nydus Worm and Echidna Worm" + +GENERIC_KEY_DESC = "Unlocks a part of the mission order." + +resource_efficiency_cost_reduction = { + item_names.REAPER: (0, 50, 0), + item_names.MEDIC: (25, 25, 1), + item_names.FIREBAT: (50, 0, 1), + item_names.GOLIATH: (50, 0, 1), + item_names.SIEGE_TANK: (0, 25, 1), + item_names.DIAMONDBACK: (0, 50, 1), + item_names.PREDATOR: (0, 75, 1), + item_names.WARHOUND: (75, 0, 0), + item_names.HERC: (25, 25, 1), + item_names.WRAITH: (0, 50, 0), + item_names.GHOST: (25, 25, 0), + item_names.SPECTRE: (25, 25, 0), + item_names.RAVEN: (0, 50, 0), + item_names.CYCLONE: (25, 50, 1), + item_names.WIDOW_MINE: (0, 25, 1), + item_names.LIBERATOR: (0, 25, 0), + item_names.VALKYRIE: (100, 25, 1), + item_names.MEDIVAC: (0, 50, 0), + item_names.DEVASTATOR_TURRET: (50, 0, 0), + item_names.MISSILE_TURRET: (25, 0, 0), + item_names.SCOURGE: (0, 50, 0), + item_names.HYDRALISK: (25, 25, 1), + item_names.SWARM_HOST: (100, 25, 0), + item_names.ULTRALISK: (100, 0, 2), + item_names.ABERRATION: (50, 25, 0), + item_names.CORRUPTOR: (50, 25, 0), + DISPLAY_NAME_BROOD_LORD: (0, 75, 0), + item_names.SWARM_QUEEN: (0, 50, 0), + item_names.ARBITER: (50, 0, 0), + item_names.REAVER: (50, 25, 1), + DISPLAY_NAME_CLOAKED_ASSASSIN: (0, 50, 0), + item_names.SCOUT: (75, 25, 0), + item_names.DESTROYER: (50, 25, 1), + DISPLAY_NAME_WORMS: (50, 75, 0), + + # Frightful Fleshwelder + item_names.INFESTED_SIEGE_TANK: (0, 25, 0), + item_names.INFESTED_DIAMONDBACK: (50, 0, 0), + item_names.INFESTED_BANSHEE: (25, 0, 0), + item_names.INFESTED_LIBERATOR: (0, 25, 0), + + # War Council + item_names.CENTURION: (0, 40, 0), + item_names.SENTINEL: (60, 0, 1), +} + +op_re_cost_reduction = { + item_names.GHOST: (100, 50, 1), + item_names.SPECTRE: (100, 50, 1), + item_names.REAVER: (50, 75, 1), + item_names.SCOUT: (50, 0, 1), +} + + +def _get_resource_efficiency_desc(item_name: str, reduction_map: dict = resource_efficiency_cost_reduction) -> str: + cost = reduction_map[item_name] + parts = [f"{cost[0]} minerals"] if cost[0] else [] + parts += [f"{cost[1]} gas"] if cost[1] else [] + parts += [f"{cost[2]} supply"] if cost[2] else [] + assert parts, f"{item_name} doesn't reduce cost by anything" + if len(parts) == 1: + amount = parts[0] + elif len(parts) == 2: + amount = " and ".join(parts) + else: + amount = ", ".join(parts[:-1]) + ", and " + parts[-1] + return (f"Reduces {item_name} cost by {amount}.") + + + +def _get_start_and_max_energy_desc(unit_name_plural: str, starting_amount_increase: int = 150, maximum_amount_increase: int = 50) -> str: + return f"{unit_name_plural} gain +{starting_amount_increase} starting energy and +{maximum_amount_increase} maximum energy." + + +def _ability_desc(unit_name_plural: str, ability_name: str, ability_description: str = '') -> str: + if ability_description: + suffix = f", \nwhich {ability_description}" + else: + suffix = "" + return f"{unit_name_plural} gain the {ability_name} ability{suffix}." + + +item_descriptions = { + item_names.MARINE: "General-purpose infantry.", + item_names.MEDIC: "Support trooper. Heals nearby biological units.", + item_names.FIREBAT: "Specialized anti-infantry attacker.", + item_names.MARAUDER: "Heavy assault infantry.", + item_names.REAPER: "Raider. Capable of jumping up and down cliffs. Throws explosive mines.", + item_names.HELLION: "Fast scout. Has a flame attack that damages all enemy units in its line of fire.", + item_names.VULTURE: "Fast skirmish unit. Can use the Spider Mine ability.", + item_names.GOLIATH: "Heavy-fire support unit.", + item_names.DIAMONDBACK: "Fast, high-damage hovertank. Rail Gun can fire while the Diamondback is moving.", + item_names.SIEGE_TANK: "Heavy tank. Long-range artillery in Siege Mode.", + item_names.MEDIVAC: "Air transport. Heals nearby biological units.", + item_names.WRAITH: "Highly mobile flying unit. Excellent at surgical strikes.", + item_names.VIKING: inspect.cleandoc(""" + Durable support flyer. Loaded with strong anti-capital air missiles. + Can switch into Assault Mode to attack ground units. + """), + item_names.BANSHEE: "Tactical-strike aircraft.", + item_names.BATTLECRUISER: "Powerful warship.", + item_names.GHOST: + "Infiltration unit. Can use Snipe and Cloak abilities. Can also call down Tactical Nukes.", + item_names.SPECTRE: inspect.cleandoc(""" + Infiltration unit. Can use Ultrasonic Pulse, Psionic Lash, and Cloak. + Can also call down Tactical Nukes. + """), + item_names.THOR: "Heavy assault mech.", + item_names.LIBERATOR: inspect.cleandoc(""" + Artillery fighter. Loaded with missiles that deal area damage to enemy air targets. + Can switch into Defender Mode to provide siege support. + """), + item_names.VALKYRIE: inspect.cleandoc(""" + Advanced anti-aircraft fighter. + Able to use cluster missiles that deal area damage to air targets. + """), + item_names.WIDOW_MINE: inspect.cleandoc(""" + Robotic mine. Launches missiles at nearby enemy units while burrowed. + Attacks deal splash damage in a small area around the target. + Widow Mine is revealed when Sentinel Missile is on cooldown. + """), + item_names.CYCLONE: "Mobile assault vehicle. Can use Lock On to quickly fire while moving.", + item_names.HERC: "Front-line infantry. Can use Grapple.", + item_names.WARHOUND: "Anti-vehicle mech. Haywire missiles do bonus damage to mechanical units.", + item_names.DOMINION_TROOPER: + "General-purpose infantry. Can be outfitted with weapons for different combat situations.", + item_names.PRIDE_OF_AUGUSTRGRAD: "Powerful Royal Guard warship.", + item_names.SKY_FURY: inspect.cleandoc(""" + Durable Royal Guard support flyer. Loaded with strong anti-capital air missiles. + Can switch into Assault Mode to attack ground units. + """), + item_names.SHOCK_DIVISION: "Royal Guard heavy tank. Long-range artillery in Siege Mode.", + item_names.BLACKHAMMER: "Royal Guard heavy assault mech.", + item_names.AEGIS_GUARD: "Royal Guard heavy assault infantry.", + item_names.EMPERORS_SHADOW: "Royal Guard specialist. Can use Pyrokinetic Immolation and EMP Blast abilities. Can call down Tactical missiles.", + item_names.SON_OF_KORHAL: "Royal Guard general-purpose infantry.", + item_names.BULWARK_COMPANY: "Royal Guard heavy-fire support unit.", + item_names.FIELD_RESPONSE_THETA: "Royal Guard support trooper. Heals nearby biological units.", + item_names.EMPERORS_GUARDIAN: inspect.cleandoc(""" + Royal Guard artillery fighter. Loaded with missiles that deal area damage to enemy air targets. + Can switch into Defender Mode to provide siege support. + """), + item_names.NIGHT_HAWK: "Royal Guard highly mobile flying unit. Excellent at surgical strikes.", + item_names.NIGHT_WOLF: "Royal Guard tactical-strike aircraft.", + item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON: GENERIC_UPGRADE_TEMPLATE.format("damage", TERRAN, "infantry"), + item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR: GENERIC_UPGRADE_TEMPLATE.format("armor", TERRAN, "infantry"), + item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON: GENERIC_UPGRADE_TEMPLATE.format("damage", TERRAN, "vehicles"), + item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR: GENERIC_UPGRADE_TEMPLATE.format("armor", TERRAN, "vehicles"), + item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON: GENERIC_UPGRADE_TEMPLATE.format("damage", TERRAN, "starships"), + item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR: GENERIC_UPGRADE_TEMPLATE.format("armor", TERRAN, "starships"), + item_names.PROGRESSIVE_TERRAN_WEAPON_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage", TERRAN, "units"), + item_names.PROGRESSIVE_TERRAN_ARMOR_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("armor", TERRAN, "units"), + item_names.PROGRESSIVE_TERRAN_INFANTRY_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage and armor", TERRAN, "infantry"), + item_names.PROGRESSIVE_TERRAN_VEHICLE_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage and armor", TERRAN, "vehicles"), + item_names.PROGRESSIVE_TERRAN_SHIP_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage and armor", TERRAN, "starships"), + item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage and armor", TERRAN, "units"), + item_names.BUNKER_PROJECTILE_ACCELERATOR: "Increases range of all units in the Bunker by 1.", + item_names.BUNKER_NEOSTEEL_BUNKER: "Increases the number of Bunker slots by 2.", + item_names.MISSILE_TURRET_TITANIUM_HOUSING: "Increases Missile Turret life by 75.", + item_names.MISSILE_TURRET_HELLSTORM_BATTERIES: "The Missile Turret unleashes an additional flurry of missiles with each attack.", + item_names.SCV_ADVANCED_CONSTRUCTION: "Multiple SCVs can construct a structure, reducing its construction time.", + item_names.SCV_DUAL_FUSION_WELDERS: "SCVs repair twice as fast.", + item_names.SCV_CONSTRUCTION_JUMP_JETS: "Allows SCVs to jump up and down cliffs.", + item_names.PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM: inspect.cleandoc(""" + Level 1: While on low health, Terran structures are repaired to half health instead of burning down. + Level 2: Terran structures are repaired to full health instead of half health. + """), + item_names.PROGRESSIVE_ORBITAL_COMMAND: inspect.cleandoc(""" + Deprecated. Replaced by Scanner Sweep, MULE, and Orbital Module (Planetary Fortress) + Level 1: Allows Command Centers to use Scanner Sweep and Calldown: MULE abilities. + Level 2: Orbital Command abilities work even in Planetary Fortress mode. + """), + item_names.MARINE_PROGRESSIVE_STIMPACK: STIMPACK_SMALL_DESCRIPTION, + item_names.MARINE_COMBAT_SHIELD: "Increases Marine life by 10.", + item_names.MEDIC_ADVANCED_MEDIC_FACILITIES: INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Medics", "Barracks"), + item_names.MEDIC_STABILIZER_MEDPACKS: "Increases Medic heal speed. Reduces the amount of energy required for each heal.", + item_names.FIREBAT_INCINERATOR_GAUNTLETS: "Increases Firebat's damage radius by 40%.", + item_names.FIREBAT_JUGGERNAUT_PLATING: "Increases Firebat's armor by 2.", + item_names.MARAUDER_CONCUSSIVE_SHELLS: "Marauder attack temporarily slows all units in target area.", + item_names.MARAUDER_KINETIC_FOAM: "Increases Marauder life by 25.", + item_names.REAPER_U238_ROUNDS: inspect.cleandoc(""" + Increases Reaper pistol attack range by 1. + Reaper pistols do additional 3 damage to Light Armor. + """), + item_names.REAPER_G4_CLUSTERBOMB: "Timed explosive that does heavy area damage.", + item_names.CYCLONE_MAG_FIELD_ACCELERATORS: "Increases Cyclone Lock-On damage.", + item_names.CYCLONE_MAG_FIELD_LAUNCHERS: "Increases Cyclone attack range by 2.", + item_names.MARINE_LASER_TARGETING_SYSTEM: LASER_TARGETING_SYSTEMS_DESCRIPTION, + item_names.MARINE_MAGRAIL_MUNITIONS: "Deals 20 damage to target unit. Autocast on attack with a cooldown.", + item_names.MARINE_OPTIMIZED_LOGISTICS: "Increases Marine training speed.", + item_names.MEDIC_RESTORATION: _ability_desc("Medics", "Restoration", "removes negative status effects from a target allied unit"), + item_names.MEDIC_OPTICAL_FLARE: _ability_desc("Medics", "Optical Flare", "reduces vision range of target enemy unit. Disables detection"), + item_names.MEDIC_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.MEDIC), + item_names.FIREBAT_PROGRESSIVE_STIMPACK: STIMPACK_LARGE_DESCRIPTION, + item_names.FIREBAT_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.FIREBAT), + item_names.MARAUDER_PROGRESSIVE_STIMPACK: STIMPACK_LARGE_DESCRIPTION, + item_names.MARAUDER_LASER_TARGETING_SYSTEM: LASER_TARGETING_SYSTEMS_DESCRIPTION, + item_names.MARAUDER_MAGRAIL_MUNITIONS: "Deals 20 damage to target unit. Autocast on attack with a cooldown.", + item_names.MARAUDER_INTERNAL_TECH_MODULE: INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Marauders", "Barracks"), + item_names.SCV_HOSTILE_ENVIRONMENT_ADAPTATION: "Increases SCV life by 15 and attack speed slightly.", + item_names.MEDIC_ADAPTIVE_MEDPACKS: "Allows Medics to heal mechanical and air units.", + item_names.MEDIC_NANO_PROJECTOR: "Increases Medic heal range by 2.", + item_names.FIREBAT_INFERNAL_PRE_IGNITER: "Firebats do an additional 4 damage to Light Armor.", + item_names.FIREBAT_KINETIC_FOAM: "Increases Firebat life by 100.", + item_names.FIREBAT_NANO_PROJECTORS: "Increases Firebat attack range by 2.", + item_names.MARAUDER_JUGGERNAUT_PLATING: "Increases Marauder's armor by 2.", + item_names.REAPER_JET_PACK_OVERDRIVE: inspect.cleandoc(""" + Allows the Reaper to fly for 10 seconds. + While flying, the Reaper can attack air units. + """), + item_names.HELLION_INFERNAL_PLATING: "Increases Hellion and Hellbat armor by 2.", + item_names.VULTURE_JERRYRIGGED_PATCHUP: "Vultures regenerate life.", + item_names.GOLIATH_SHAPED_HULL: "Increases Goliath life by 25.", + item_names.GOLIATH_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.GOLIATH), + item_names.GOLIATH_INTERNAL_TECH_MODULE: INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Goliaths", "Factory"), + item_names.SIEGE_TANK_SHAPED_HULL: "Increases Siege Tank life by 25.", + item_names.SIEGE_TANK_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.SIEGE_TANK), + item_names.PREDATOR_CLOAK: "Allows Predators to briefly cloak. Predators ignore unit collision while cloaked.", + item_names.PREDATOR_CHARGE: "Allows Predators to intercept enemy ground units, and applies an AoE slow on arrival.", + item_names.MEDIVAC_SCATTER_VEIL: "Medivacs get 100 shields.", + item_names.REAPER_PROGRESSIVE_STIMPACK: STIMPACK_SMALL_DESCRIPTION, + item_names.REAPER_LASER_TARGETING_SYSTEM: LASER_TARGETING_SYSTEMS_DESCRIPTION, + item_names.REAPER_ADVANCED_CLOAKING_FIELD: "Reapers are permanently cloaked.", + item_names.REAPER_SPIDER_MINES: "Allows Reapers to lay Spider Mines. 3 charges per Reaper.", + item_names.REAPER_COMBAT_DRUGS: "Reapers regenerate life while out of combat.", + item_names.HELLION_HELLBAT: "Allows Hellions to transform into Hellbats.", + item_names.HELLION_SMART_SERVOS: "Transforms faster between modes. Hellions can attack while moving.", + item_names.HELLION_OPTIMIZED_LOGISTICS: "Increases Hellion training speed.", + item_names.HELLION_JUMP_JETS: inspect.cleandoc(""" + Increases movement speed in Hellion mode. + In Hellbat mode, launches the Hellbat toward enemy ground units and briefly stuns them. + """), + item_names.HELLION_PROGRESSIVE_STIMPACK: STIMPACK_LARGE_DESCRIPTION, + item_names.VULTURE_ION_THRUSTERS: "Increases Vulture movement speed.", + item_names.VULTURE_AUTO_LAUNCHERS: "Allows Vultures to attack while moving.", + item_names.SPIDER_MINE_HIGH_EXPLOSIVE_MUNITION: "Increases Spider mine damage.", + item_names.GOLIATH_JUMP_JETS: "Allows Goliaths to jump up and down cliffs.", + item_names.GOLIATH_OPTIMIZED_LOGISTICS: "Increases Goliath training speed.", + item_names.DIAMONDBACK_HYPERFLUXOR: "Increases Diamondback attack speed.", + item_names.DIAMONDBACK_BURST_CAPACITORS: inspect.cleandoc(""" + While not attacking, the Diamondback charges its weapon. + The next attack does 10 additional damage. + """), + item_names.DIAMONDBACK_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.DIAMONDBACK), + item_names.SIEGE_TANK_JUMP_JETS: inspect.cleandoc(""" + Repositions Siege Tank to a target location. + Can be used in either mode and to jump up and down cliffs. + """), + item_names.SIEGE_TANK_SPIDER_MINES: inspect.cleandoc(""" + Allows Siege Tanks to lay Spider Mines. + Lays 3 Spider Mines at once. 3 charges. + """), + item_names.SIEGE_TANK_SMART_SERVOS: SMART_SERVOS_DESCRIPTION, + item_names.SIEGE_TANK_GRADUATING_RANGE: inspect.cleandoc(""" + Increases the Siege Tank's attack range by 1 every 3 seconds while in Siege Mode, + up to a maximum of 5 additional range. + """), + item_names.SIEGE_TANK_LASER_TARGETING_SYSTEM: LASER_TARGETING_SYSTEMS_DESCRIPTION, + item_names.SIEGE_TANK_ADVANCED_SIEGE_TECH: "Siege Tanks gain +3 armor in Siege Mode.", + item_names.SIEGE_TANK_INTERNAL_TECH_MODULE: INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Siege Tanks", "Factory"), + item_names.PREDATOR_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.PREDATOR), + item_names.MEDIVAC_EXPANDED_HULL: "Increases Medivac cargo space by 4.", + item_names.MEDIVAC_AFTERBURNERS: "Ability. Temporarily increases the Medivac's movement speed by 70%.", + item_names.WRAITH_ADVANCED_LASER_TECHNOLOGY: inspect.cleandoc(""" + Burst Lasers do more damage and can hit both ground and air targets. + Replaces Gemini Missiles weapon. + """), + item_names.VIKING_SMART_SERVOS: SMART_SERVOS_DESCRIPTION, + item_names.VIKING_ANTI_MECHANICAL_MUNITION: "Increases Viking damage to mechanical units while in Assault Mode.", + item_names.DIAMONDBACK_MAGLEV_PROPULSION: "Increases Diamondback movement speed.", + item_names.WARHOUND_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.WARHOUND), + item_names.WARHOUND_AXIOM_PLATING: "Increases Warhound armor by 2.", + item_names.WARHOUND_DEPLOY_TURRET: "Each Warhound can deploy a single-use Auto-Turret.", + item_names.HERC_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.HERC), + item_names.HERC_JUGGERNAUT_PLATING: "Increases HERC armor by 2.", + item_names.HERC_KINETIC_FOAM: "Increases HERC life by 50.", + item_names.REAPER_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.REAPER), + item_names.REAPER_BALLISTIC_FLIGHTSUIT: "Increases Reaper life by 10.", + item_names.SIEGE_TANK_PROGRESSIVE_TRANSPORT_HOOK: inspect.cleandoc(""" + Level 1: Allows Siege Tanks to be transported in Siege Mode. + Level 2: Siege Tanks in Siege Mode can attack air units while transported by a Medivac. + """), + item_names.SIEGE_TANK_ALLTERRAIN_TREADS: "Increases movement speed of Siege Tanks in Tank Mode.", + item_names.MEDIVAC_RAPID_REIGNITION_SYSTEMS: inspect.cleandoc(""" + Slightly increases Medivac movement speed. + Reduces Medivac's Afterburners ability cooldown. + """), + item_names.BATTLECRUISER_BEHEMOTH_REACTOR: "All Battlecruiser spells require 25 less energy to cast.", + item_names.THOR_RAPID_RELOAD: "Increases Thor's ground attack speed.", + item_names.LIBERATOR_GUERILLA_MISSILES: "Liberators in Fighter Mode apply an attack and movement debuff to enemies they attack.", + item_names.WIDOW_MINE_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.WIDOW_MINE), + item_names.HERC_GRAPPLE_PULL: "Allows HERCs to use their grappling gun to pull a ground unit towards the HERC.", + item_names.COMMAND_CENTER_SCANNER_SWEEP: "Temporarily reveals an area of the map, detecting cloaked and burrowed units.", + item_names.COMMAND_CENTER_MULE: "Summons a unit that gathers minerals more quickly than regular SCVs. Has timed life.", + item_names.COMMAND_CENTER_EXTRA_SUPPLIES: "Drops additional supplies, permanently increasing the supply output of the target Supply Depot by 8.", + item_names.HELLION_TWIN_LINKED_FLAMETHROWER: "Doubles the width of the Hellion's flame attack.", + item_names.HELLION_THERMITE_FILAMENTS: "Hellions do an additional 10 damage to Light Armor.", + item_names.SPIDER_MINE_CERBERUS_MINE: "Increases trigger and blast radius of Spider Mines.", + item_names.VULTURE_PROGRESSIVE_REPLENISHABLE_MAGAZINE: inspect.cleandoc(""" + Level 1: Allows Vultures to replace used Spider Mines. Costs 15 minerals. + Level 2: Replacing used Spider Mines no longer costs minerals. + """), + item_names.GOLIATH_MULTI_LOCK_WEAPONS_SYSTEM: "Goliaths can attack both ground and air targets simultaneously.", + item_names.GOLIATH_ARES_CLASS_TARGETING_SYSTEM: "Increases Goliath ground attack range by 1 and air by 3.", + item_names.DIAMONDBACK_PROGRESSIVE_TRI_LITHIUM_POWER_CELL: inspect.cleandoc(""" + Level 1: Tri-Lithium Power Cell: Increases Diamondback attack range by 1. + Level 2: Tungsten Spikes: Increases Diamondback attack range by 3. + """), + item_names.DIAMONDBACK_SHAPED_HULL: "Increases Diamondback life by 50.", + item_names.SIEGE_TANK_MAELSTROM_ROUNDS: "Siege Tanks do an additional 40 damage to the primary target in Siege Mode.", + item_names.SIEGE_TANK_SHAPED_BLAST: "Reduces splash damage to friendly targets while in Siege Mode by 75%.", + item_names.MEDIVAC_RAPID_DEPLOYMENT_TUBE: "Medivacs deploy loaded troops almost instantly.", + item_names.MEDIVAC_ADVANCED_HEALING_AI: "Medivacs can heal two targets at once.", + item_names.WRAITH_PROGRESSIVE_TOMAHAWK_POWER_CELLS: inspect.cleandoc(""" + Level 1: Tomahawk Power Cells: Increases Wraith starting energy by 100. + Level 2: Unregistered Cloaking Module: Wraiths do not require energy to cloak and remain cloaked. + """), + item_names.WRAITH_DISPLACEMENT_FIELD: "Wraiths evade 20% of incoming attacks while cloaked.", + item_names.VIKING_RIPWAVE_MISSILES: "Vikings do area damage while in Fighter Mode.", + item_names.VIKING_PHOBOS_CLASS_WEAPONS_SYSTEM: "Increases Viking attack range by 1 in Assault mode and 2 in Fighter mode.", + item_names.BANSHEE_PROGRESSIVE_CROSS_SPECTRUM_DAMPENERS: inspect.cleandoc(""" + Level 1: Banshees can remain cloaked twice as long. + Level 2: Banshees do not require energy to cloak and remain cloaked. + """), + item_names.BANSHEE_SHOCKWAVE_MISSILE_BATTERY: "Banshees do area damage in a straight line.", + item_names.BATTLECRUISER_PROGRESSIVE_MISSILE_PODS: inspect.cleandoc(f""" + {_ability_desc('Battlecruisers', 'Missile Pods', 'deals damage to air units in a target area')} + Level 1: Deals 40 damage (+50 vs light). + Level 2: Deals 110 damage and costs -50 less energy. + """), + item_names.BATTLECRUISER_PROGRESSIVE_DEFENSIVE_MATRIX: inspect.cleandoc(""" + Level 1: Spell. For 20 seconds the Battlecruiser gains a shield that can absorb up to 200 damage. + Level 2: Passive. Battlecruiser gets 200 shields. Can spend energy to fully recharge shields. + """), + item_names.GHOST_OCULAR_IMPLANTS: "Increases Ghost sight range by 3 and attack range by 2.", + item_names.GHOST_CRIUS_SUIT: "Cloak no longer requires energy to activate or maintain.", + item_names.SPECTRE_PSIONIC_LASH: "Spell. Deals 200 damage to a single target.", + item_names.SPECTRE_NYX_CLASS_CLOAKING_MODULE: "Cloak no longer requires energy to activate or maintain.", + item_names.THOR_330MM_BARRAGE_CANNON: inspect.cleandoc(""" + Improves 250mm Strike Cannons ability to deal area damage and stun units in a small area. + Can be also freely aimed on ground. + """), + item_names.THOR_PROGRESSIVE_IMMORTALITY_PROTOCOL: inspect.cleandoc(""" + Level 1: Allows destroyed Thors to be reconstructed on the field. Costs Vespene Gas. + Level 2: Thors are automatically reconstructed after falling for free. + """), + item_names.LIBERATOR_ADVANCED_BALLISTICS: "Increases Liberator range by 3 in Defender Mode.", + item_names.LIBERATOR_RAID_ARTILLERY: "Allows Liberators to attack structures while in Defender Mode.", + item_names.WIDOW_MINE_DRILLING_CLAWS: "Allows Widow Mines to burrow and unburrow faster.", + item_names.WIDOW_MINE_CONCEALMENT: "Burrowed Widow Mines are no longer revealed when the Sentinel Missile is on cooldown.", + item_names.WIDOW_MINE_DEMOLITION_PAYLOAD: "Allows Widow Mines to attack and damage structures.", + item_names.MEDIVAC_ADVANCED_CLOAKING_FIELD: "Medivacs are permanently cloaked.", + item_names.WRAITH_TRIGGER_OVERRIDE: "Wraith attack speed increases by 10% with each attack, up to a maximum of 100%.", + item_names.WRAITH_INTERNAL_TECH_MODULE: INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Wraiths", "Starport"), + item_names.WRAITH_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.WRAITH), + item_names.VIKING_SHREDDER_ROUNDS: "Attacks in Assault mode do line splash damage.", + item_names.VIKING_WILD_MISSILES: "Launches 5 rockets at the target unit. Each rocket does 25 (40 vs armored) damage.", + item_names.BANSHEE_SHAPED_HULL: "Increases Banshee life by 100.", + item_names.BANSHEE_ADVANCED_TARGETING_OPTICS: "Increases Banshee attack range by 2 while cloaked.", + item_names.BANSHEE_DISTORTION_BLASTERS: "Increases Banshee attack damage by 25% while cloaked.", + item_names.BANSHEE_ROCKET_BARRAGE: _ability_desc("Banshees", "Rocket Barrage", "deals 75 damage to enemy ground units in the target area"), + item_names.GHOST_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.GHOST), + item_names.GHOST_BARGAIN_BIN_PRICES: _get_resource_efficiency_desc(item_names.GHOST, op_re_cost_reduction), + item_names.SPECTRE_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.SPECTRE), + item_names.SPECTRE_BARGAIN_BIN_PRICES: _get_resource_efficiency_desc(item_names.SPECTRE, op_re_cost_reduction), + item_names.THOR_BUTTON_WITH_A_SKULL_ON_IT: "Allows Thors to launch nukes.", + item_names.THOR_LASER_TARGETING_SYSTEM: LASER_TARGETING_SYSTEMS_DESCRIPTION, + item_names.THOR_LARGE_SCALE_FIELD_CONSTRUCTION: "Allows Thors to be built by SCVs like a structure.", + item_names.RAVEN_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.RAVEN), + item_names.RAVEN_DURABLE_MATERIALS: "Extends timed life duration of Raven's summoned objects.", + item_names.SCIENCE_VESSEL_IMPROVED_NANO_REPAIR: "Nano-Repair no longer requires energy to use.", + item_names.SCIENCE_VESSEL_MAGELLAN_COMPUTATION_SYSTEMS: "Science Vessel can use Nano-Repair at two targets at once.", + item_names.CYCLONE_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.CYCLONE), + item_names.BANSHEE_HYPERFLIGHT_ROTORS: "Increases Banshee movement speed.", + item_names.BANSHEE_LASER_TARGETING_SYSTEM: LASER_TARGETING_SYSTEMS_DESCRIPTION, + item_names.BANSHEE_INTERNAL_TECH_MODULE: INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Banshees", "Starport"), + item_names.BATTLECRUISER_TACTICAL_JUMP: inspect.cleandoc(""" + Allows Battlecruisers to warp to a target location anywhere on the map. + """), + item_names.BATTLECRUISER_CLOAK: CLOAK_DESCRIPTION_TEMPLATE.format("Battlecruisers"), + item_names.BATTLECRUISER_ATX_LASER_BATTERY: inspect.cleandoc(""" + Battlecruisers can attack while moving, + do the same damage to both ground and air targets, and fire faster. + """), + item_names.BATTLECRUISER_OPTIMIZED_LOGISTICS: "Increases Battlecruiser training speed.", + item_names.BATTLECRUISER_INTERNAL_TECH_MODULE: INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Battlecruisers", "Starport"), + item_names.GHOST_EMP_ROUNDS: inspect.cleandoc(""" + Spell. Does 100 damage to shields and drains all energy from units in the targeted area. + Cloaked units hit by EMP are revealed for a short time. + """), + item_names.GHOST_LOCKDOWN: "Spell. Stuns a target mechanical unit for a long time.", + item_names.SPECTRE_IMPALER_ROUNDS: "Spectres do additional damage to armored targets.", + item_names.THOR_PROGRESSIVE_HIGH_IMPACT_PAYLOAD: inspect.cleandoc(f""" + Level 1: Allows Thors to transform in order to use an alternative air attack. + Level 2: {SMART_SERVOS_DESCRIPTION} + """), + item_names.RAVEN_BIO_MECHANICAL_REPAIR_DRONE: "Spell. Deploys a drone that can heal biological or mechanical units.", + item_names.RAVEN_SPIDER_MINES: "Spell. Deploys 3 Spider Mines to a target location.", + item_names.RAVEN_RAILGUN_TURRET: inspect.cleandoc(""" + Spell. Allows Ravens to deploy an advanced Auto-Turret, that can attack enemy ground units in a straight line. + """), + item_names.RAVEN_HUNTER_SEEKER_WEAPON: "Allows Ravens to attack with a Hunter-Seeker weapon.", + item_names.RAVEN_INTERFERENCE_MATRIX: inspect.cleandoc(""" + Spell. Target enemy Mechanical or Psionic unit can't attack or use abilities for a short duration. + """), + item_names.RAVEN_ANTI_ARMOR_MISSILE: "Spell. Decreases target and nearby enemy units armor by 2.", + item_names.RAVEN_INTERNAL_TECH_MODULE: INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Ravens", "Starport"), + item_names.SCIENCE_VESSEL_EMP_SHOCKWAVE: "Spell. Depletes all energy and shields of all units in a target area.", + item_names.SCIENCE_VESSEL_DEFENSIVE_MATRIX: inspect.cleandoc(""" + Spell. Provides a target unit with a defensive barrier that can absorb up to 250 damage. + """), + item_names.CYCLONE_TARGETING_OPTICS: "Increases Cyclone Lock On casting range and the range while Locked On.", + item_names.CYCLONE_RAPID_FIRE_LAUNCHERS: "The first 12 shots of Lock On are fired more quickly.", + item_names.LIBERATOR_CLOAK: CLOAK_DESCRIPTION_TEMPLATE.format("Liberators"), + item_names.LIBERATOR_LASER_TARGETING_SYSTEM: LASER_TARGETING_SYSTEMS_DESCRIPTION, + item_names.LIBERATOR_OPTIMIZED_LOGISTICS: "Increases Liberator training speed.", + item_names.WIDOW_MINE_BLACK_MARKET_LAUNCHERS: "Increases Widow Mine Sentinel Missile range.", + item_names.WIDOW_MINE_EXECUTIONER_MISSILES: inspect.cleandoc(""" + Reduces Sentinel Missile cooldown. + When killed, Widow Mines will launch several missiles at random enemy targets. + """), + item_names.VALKYRIE_ENHANCED_CLUSTER_LAUNCHERS: "Valkyries fire 2 additional rockets each volley.", + item_names.VALKYRIE_SHAPED_HULL: "Increases Valkyrie life by 50.", + item_names.VALKYRIE_FLECHETTE_MISSILES: "Equips Valkyries with Air-to-Surface missiles to attack ground units.", + item_names.VALKYRIE_AFTERBURNERS: "Ability. Temporarily increases the Valkyries's movement speed by 70%.", + item_names.CYCLONE_INTERNAL_TECH_MODULE: INTERNAL_TECH_MODULE_DESCRIPTION_TEMPLATE.format("Cyclones", "Factory"), + item_names.LIBERATOR_SMART_SERVOS: SMART_SERVOS_DESCRIPTION, + item_names.LIBERATOR_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.LIBERATOR), + item_names.HERCULES_INTERNAL_FUSION_MODULE: "Hercules can be trained from a Starport without having a Fusion Core.", + item_names.HERCULES_TACTICAL_JUMP: inspect.cleandoc(""" + Allows Hercules to warp to a target location anywhere on the map. + """), + item_names.PLANETARY_FORTRESS_PROGRESSIVE_AUGMENTED_THRUSTERS: inspect.cleandoc(""" + Level 1: Lift Off - Planetary Fortress can lift off. + Level 2: Armament Stabilizers - Planetary Fortress can attack while lifted off. + """), + item_names.PLANETARY_FORTRESS_IBIKS_TRACKING_SCANNERS: "Planetary Fortress can attack air units.", + item_names.VALKYRIE_LAUNCHING_VECTOR_COMPENSATOR: "Allows Valkyries to shoot air while moving.", + item_names.VALKYRIE_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.VALKYRIE), + item_names.PREDATOR_VESPENE_SYNTHESIS: "Gives 1 free Vespene per target hit with Lightning Field.", + item_names.PREDATOR_ADAPTIVE_DEFENSES: "Predators gain a shield that halves incoming ranged and splash damage while active.", + item_names.BATTLECRUISER_BEHEMOTH_PLATING: "Increases Battlecruiser armor by 2.", + item_names.BATTLECRUISER_MOIRAI_IMPULSE_DRIVE: "Increases Battlecruiser movement speed.", + item_names.PLANETARY_FORTRESS_ORBITAL_MODULE: inspect.cleandoc(""" + Allows Planetary Fortresses to use Scanner Sweep, MULE, and Extra Supplies if those abilities are owned. + """), + item_names.DEVASTATOR_TURRET_CONCUSSIVE_GRENADES: "Devastator Turrets slow enemies they hit. Does not stack with Marauder Concussive Shells.", + item_names.DEVASTATOR_TURRET_ANTI_ARMOR_MUNITIONS: "Increases Devastator Turret damage to armored targets by 10.", + item_names.DEVASTATOR_TURRET_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.DEVASTATOR_TURRET), + item_names.MISSILE_TURRET_RESOURCE_EFFICENCY: _get_resource_efficiency_desc(item_names.MISSILE_TURRET), + item_names.SENSOR_TOWER_ASSISTIVE_TARGETING: "Sensor Towers increase the attack range of defensive buildings in their direct sight range.", + item_names.SENSOR_TOWER_MUILTISPECTRUM_DOPPLER: "Sensor Towers gain +10 sight range and +5 radar range.", + item_names.SCIENCE_VESSEL_TACTICAL_JUMP: "Allows Science Vessels to warp to a target location anywhere on the map.", + item_names.LIBERATOR_UED_MISSILE_TECHNOLOGY: "Increases Liberator attack range in Fighter mode by 4.", + item_names.BATTLECRUISER_FIELD_ASSIST_TARGETING_SYSTEM: "Battlecruisers increase the attack range of nearby friendly ground units by 1.", + item_names.VIKING_AESIR_TURBINES: "Increases Viking movement speed by 55%.", + item_names.MEDIVAC_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.MEDIVAC), + item_names.EMPERORS_SHADOW_SOVEREIGN_TACTICAL_MISSILES: "Tactical Missile Strikes no longer need to be channeled.", + item_names.DOMINION_TROOPER_B2_HIGH_CAL_LMG: "Allows the Troopers to arm with a more powerful weapon, effective against all unit types.", + item_names.DOMINION_TROOPER_HAILSTORM_LAUNCHER: "Allows the Troopers to arm with a more powerful weapon, especially effective against armored air units.", + item_names.DOMINION_TROOPER_CPO7_SALAMANDER_FLAMETHROWER: "Allows the Troopers to arm with a more powerful weapon, especially effective against light ground units.", + item_names.DOMINION_TROOPER_ADVANCED_ALLOYS: "Trooper weapons cost 20 fewer gas and now last for 5 minutes when dropped on death.", + item_names.DOMINION_TROOPER_OPTIMIZED_LOGISTICS: "Increases Dominion Trooper training speed.", + item_names.BUNKER: "Defensive structure. Able to load infantry units, giving them +1 range to their attacks.", + item_names.MISSILE_TURRET: "Anti-air defensive structure.", + item_names.SENSOR_TOWER: "Reveals locations of enemy units at long range.", + item_names.WAR_PIGS: "Mercenary Marines.", + item_names.DEVIL_DOGS: "Mercenary Firebats.", + item_names.HAMMER_SECURITIES: "Mercenary Marauders.", + item_names.SPARTAN_COMPANY: "Mercenary Goliaths.", + item_names.SIEGE_BREAKERS: "Mercenary Siege Tanks.", + item_names.HELS_ANGELS: "Mercenary Vikings.", + item_names.DUSK_WINGS: "Mercenary Banshees.", + item_names.JACKSONS_REVENGE: "Mercenary Battlecruiser.", + item_names.SKIBIS_ANGELS: "Mercenary Medics.", + item_names.DEATH_HEADS: "Mercenary Reapers.", + item_names.WINGED_NIGHTMARES: "Mercenary Wraiths.", + item_names.MIDNIGHT_RIDERS: "Mercenary Liberators.", + item_names.BRYNHILDS: "Mercenary Valkyries.", + item_names.JOTUN: "Mercenary Thor.", + item_names.ULTRA_CAPACITORS: "Increases attack speed of units by 5% per weapon upgrade.", + item_names.VANADIUM_PLATING: "Increases the life of units by 5% per armor upgrade.", + item_names.ORBITAL_DEPOTS: "Supply depots are built instantly.", + item_names.MICRO_FILTERING: "Refineries produce Vespene gas 25% faster.", + item_names.AUTOMATED_REFINERY: "Eliminates the need for SCVs in vespene gas production.", + item_names.COMMAND_CENTER_COMMAND_CENTER_REACTOR: "Command Centers can train two SCVs at once.", + item_names.RAVEN: "Aerial Caster unit.", + item_names.SCIENCE_VESSEL: "Aerial Caster unit. Can repair mechanical units.", + item_names.TECH_REACTOR: "Merges Tech Labs and Reactors into one add on structure to provide both functions.", + item_names.ORBITAL_STRIKE: "Trained units from Barracks are instantly deployed on rally point.", + item_names.BUNKER_SHRIKE_TURRET: "Adds an automated turret to Bunkers.", + item_names.BUNKER_FORTIFIED_BUNKER: "Bunkers have more life.", + item_names.PLANETARY_FORTRESS: inspect.cleandoc(""" + Allows Command Centers to upgrade into a defensive structure with a turret and additional armor. + Planetary Fortresses cannot Lift Off, or cast Orbital Command spells. + """), + item_names.PERDITION_TURRET: "Automated defensive turret. Burrows down while no enemies are nearby.", + item_names.PREDATOR: "Anti-infantry specialist that deals area damage with each attack.", + item_names.HERCULES: "Massive transport ship.", + item_names.CELLULAR_REACTOR: "All Terran spellcasters get +100 starting and maximum energy.", + item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL: inspect.cleandoc(""" + Allows Terran mechanical units to regenerate health while not in combat. + Each level increases life regeneration speed. + """), + item_names.HIVE_MIND_EMULATOR: "Unlocks the Hive Mind Emulator defensive structure, and allows it to permanently Mind Control Zerg units.", + item_names.ARGUS_AMPLIFIER: "Unlocks the Hive Mind Emulator defensive structure, and allows it to permanently Mind Control Protoss units.", + item_names.PSI_INDOCTRINATOR: "Unlocks the Hive Mind Emulator defensive structure, and allows it to permanently Mind Control Terran units.", + item_names.PSI_DISRUPTER: "Unlocks the Psi Disrupter defensive structure, and allows it to slow the attack and movement speeds of all nearby Zerg units.", + item_names.PSI_SCREEN: "Unlocks the Psi Disrupter defensive structure, and allows it to slow the attack and movement speeds of all nearby Protoss units.", + item_names.SONIC_DISRUPTER: "Unlocks the Psi Disrupter defensive structure, and allows it to slow the attack and movement speeds of all nearby Terran units.", + item_names.DEVASTATOR_TURRET: "Defensive structure. Deals increased damage to armored targets. Attacks ground units.", + item_names.STRUCTURE_ARMOR: "Increases armor of all Terran structures by 2.", + item_names.HI_SEC_AUTO_TRACKING: "Increases attack range of all Terran structures by 1.", + item_names.ADVANCED_OPTICS: "Increases attack range of all Terran mechanical units by 1.", + item_names.ROGUE_FORCES: "Terran Mercenary calldowns are no longer limited by charges.", + item_names.MECHANICAL_KNOW_HOW: "Increases mechanical unit life by 20%.", + item_names.MERCENARY_MUNITIONS: "Increases attack speed of all Terran combat units by 15%.", + item_names.PROGRESSIVE_FAST_DELIVERY: "At level 1, you can request one Mercenary unit immediately at the start of a mission. Level 2 allows you to calldown 3 Mercenary units immediately.", + item_names.RAPID_REINFORCEMENT: "Reduces cooldowns of all Terran Mercenary calldowns by 60s.", + item_names.SIGNAL_BEACON: "Terran Mercenary Calldowns are instantly deployed on rally point.", + item_names.FUSION_CORE_FUSION_REACTOR: "Fusion Cores increase the energy regeneration of nearby units by +1 energy per second.", + item_names.ZEALOT: "Powerful melee warrior. Can use the charge ability.", + item_names.STALKER: "Ranged attack strider. Can use the Blink ability.", + item_names.HIGH_TEMPLAR: "Potent psionic master. Can use the Feedback and Psionic Storm abilities. Can merge into an Archon.", + item_names.DARK_TEMPLAR: "Deadly warrior-assassin. Permanently cloaked. Can use the Shadow Fury ability.", + item_names.IMMORTAL: "Assault strider. Can use Barrier to absorb damage.", + item_names.COLOSSUS: "Battle strider with a powerful area attack. Can walk up and down cliffs. Attacks set fire to the ground, dealing extra damage to enemies over time.", + item_names.PHOENIX: "Air superiority starfighter. Can use Graviton Beam and Phasing Armor abilities.", + item_names.VOID_RAY: "Surgical strike craft. Has the Prismatic Alignment and Prismatic Range abilities.", + item_names.CARRIER: "Capital ship. Builds and launches Interceptors that attack enemy targets. Repair Drones heal nearby mechanical units.", + item_names.STARTING_MINERALS: "Increases the starting minerals for all missions.", + item_names.STARTING_VESPENE: "Increases the starting vespene for all missions.", + item_names.STARTING_SUPPLY: "Increases the starting supply for all missions.", + item_names.NOTHING: "Does nothing. Used to remove a location from the game.", + item_names.MAX_SUPPLY: "Increases the maximum supply cap for all missions.", + item_names.REDUCED_MAX_SUPPLY: "Trap Item. Decreases the maximum supply cap for all missions.", + item_names.SHIELD_REGENERATION: "Increases shield regeneration of all own units.", + item_names.BUILDING_CONSTRUCTION_SPEED: "Increases building construction speed.", + item_names.UPGRADE_RESEARCH_SPEED: "Increases weapon and armor research speed.", + item_names.UPGRADE_RESEARCH_COST: "Decreases weapon and armor upgrade research cost.", + item_names.NOVA_GHOST_VISOR: "Reveals the locations of enemy units in the fog of war around Nova. Can detect cloaked units.", + item_names.NOVA_RANGEFINDER_OCULUS: "Increases Nova's vision range and non-melee weapon attack range by 2. Also increases range of melee weapons by 1.", + item_names.NOVA_DOMINATION: "Gives Nova the ability to mind-control a target enemy unit.", + item_names.NOVA_BLINK: "Gives Nova the ability to teleport a short distance and cloak for 10s.", + item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE: inspect.cleandoc(""" + Level 1: Gives Nova the ability to cloak. + Level 2: Nova is permanently cloaked. + """), + item_names.NOVA_ENERGY_SUIT_MODULE: "Increases Nova's maximum energy and energy regeneration rate.", + item_names.NOVA_ARMORED_SUIT_MODULE: "Increases Nova's health by 100 and armor by 1. Nova also regenerates life quickly out of combat.", + item_names.NOVA_JUMP_SUIT_MODULE: "Increases Nova's movement speed and allows her to jump up and down cliffs.", + item_names.NOVA_C20A_CANISTER_RIFLE: "Allows Nova to equip the C20A Canister Rifle, which has a ranged attack and allows Nova to cast Snipe.", + item_names.NOVA_HELLFIRE_SHOTGUN: "Allows Nova to equip the Hellfire Shotgun, which has a short-range area attack in a cone and allows Nova to cast Penetrating Blast.", + item_names.NOVA_PLASMA_RIFLE: "Allows Nova to equip the Plasma Rifle, which has a rapidfire ranged attack and allows Nova to cast Plasma Shot.", + item_names.NOVA_MONOMOLECULAR_BLADE: "Allows Nova to equip the Monomolecular Blade, which has a melee attack and allows Nova to cast Dash Attack.", + item_names.NOVA_BLAZEFIRE_GUNBLADE: "Allows Nova to equip the Blazefire Gunblade, which has a melee attack and allows Nova to cast Fury of One.", + item_names.NOVA_STIM_INFUSION: "Gives Nova the ability to heal herself and temporarily increase her movement and attack speeds.", + item_names.NOVA_PULSE_GRENADES: "Gives Nova the ability to throw a grenade dealing large damage in an area.", + item_names.NOVA_FLASHBANG_GRENADES: "Gives Nova the ability to throw a grenade to stun enemies and disable detection in a large area.", + item_names.NOVA_IONIC_FORCE_FIELD: "Gives Nova the ability to shield herself temporarily.", + item_names.NOVA_HOLO_DECOY: "Gives Nova the ability to summon a decoy unit which enemies will prefer to target and takes reduced damage.", + item_names.NOVA_NUKE: "Gives Nova the ability to launch tactical nukes built from the Shadow Ops.", + item_names.ZERGLING: "Fast inexpensive melee attacker. Hatches in pairs from a single larva. Can morph into a Baneling.", + item_names.SWARM_QUEEN: "Ranged support caster. Can use the Spawn Creep Tumor and Rapid Transfusion abilities.", + item_names.ROACH: "Durable short ranged attacker. Regenerates life quickly when burrowed.", + item_names.HYDRALISK: "High-damage generalist ranged attacker.", + item_names.ZERGLING_BANELING_ASPECT: "Anti-ground suicide unit. Does damage over a small area on death. Morphed from the Zergling.", + item_names.ABERRATION: "Durable melee attacker that deals heavy damage and can walk over other units.", + item_names.MUTALISK: "Fragile flying attacker. Attacks bounce between targets.", + item_names.SWARM_HOST: "Siege unit that attacks by rooting in place and continually spawning Locusts.", + item_names.INFESTOR: "Support caster that can move while burrowed. Can use the Fungal Growth, Parasitic Domination, and Consumption abilities.", + item_names.ULTRALISK: "Massive melee attacker. Has an area-damage cleave attack.", + item_names.PYGALISK: "Miniature melee attacker.", + item_names.SPORE_CRAWLER: "Anti-air defensive structure. Detects cloaked units and can uproot.", + item_names.SPINE_CRAWLER: "Anti-ground defensive structure. Can uproot to reposition itself.", + item_names.BILE_LAUNCHER: "Long-range anti-ground bombardment structure.", + item_names.CORRUPTOR: "Anti-air flying attacker specializing in taking down enemy capital ships.", + item_names.SCOURGE: "Flying anti-air suicide unit. Hatches in pairs from a single larva.", + item_names.BROOD_QUEEN: "Flying support caster. Can cast the Ocular Symbiote and Spawn Broodlings abilities.", + item_names.DEFILER: "Support caster. Can use the Dark Swarm, Consume, and Plague abilities.", + item_names.INFESTED_MARINE: "General-purpose Infested infantry. Has a timed life of 90 seconds.", + item_names.INFESTED_BUNKER: "Defensive structure. Periodically spawns Infested infantry that fight from inside. Acts as a mobile ground transport while uprooted.", + item_names.INFESTED_MISSILE_TURRET: "Anti-air defensive structure. Detects cloaked units and can uproot.", + item_names.INFESTED_SIEGE_TANK: "Siege tank. Can uproot itself to provide mobile tank support.", + item_names.INFESTED_DIAMONDBACK: "Fast, high-damage attacker. Can attack while moving and can bring flying units to the ground.", + item_names.BULLFROG: "Grounded transport. Launches itself through the air, dealing damage and unloading cargo on impact.", + item_names.INFESTED_BANSHEE: "Tactical-strike aircraft. Can cloak and can be upgraded to burrow.", + item_names.INFESTED_LIBERATOR: "Anti-Air flying attacker. Attacks deal high area-damage.", + item_names.PROGRESSIVE_ZERG_MELEE_ATTACK: GENERIC_UPGRADE_TEMPLATE.format("damage", ZERG, "melee ground units"), + item_names.PROGRESSIVE_ZERG_MISSILE_ATTACK: GENERIC_UPGRADE_TEMPLATE.format("damage", ZERG, "ranged ground units"), + item_names.PROGRESSIVE_ZERG_GROUND_CARAPACE: GENERIC_UPGRADE_TEMPLATE.format("armor", ZERG, "ground units"), + item_names.PROGRESSIVE_ZERG_FLYER_ATTACK: GENERIC_UPGRADE_TEMPLATE.format("damage", ZERG, "flyers"), + item_names.PROGRESSIVE_ZERG_FLYER_CARAPACE: GENERIC_UPGRADE_TEMPLATE.format("armor", ZERG, "flyers"), + item_names.PROGRESSIVE_ZERG_WEAPON_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage", ZERG, "units"), + item_names.PROGRESSIVE_ZERG_ARMOR_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("armor", ZERG, "units"), + item_names.PROGRESSIVE_ZERG_GROUND_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage and armor", ZERG, "ground units"), + item_names.PROGRESSIVE_ZERG_FLYER_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage and armor", ZERG, "flyers"), + item_names.PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage and armor", ZERG, "units"), + item_names.ZERGLING_HARDENED_CARAPACE: "Increases Zergling health by +10.", + item_names.ZERGLING_ADRENAL_OVERLOAD: "Increases Zergling attack speed.", + item_names.ZERGLING_METABOLIC_BOOST: "Increases Zergling movement speed.", + item_names.ROACH_HYDRIODIC_BILE: "Roaches deal +8 damage to light targets.", + item_names.ROACH_ADAPTIVE_PLATING: "Roaches gain +3 armor when their life is below 50%.", + item_names.ROACH_TUNNELING_CLAWS: "Allows Roaches to move while burrowed.", + item_names.HYDRALISK_FRENZY: "Allows Hydralisks to use the Frenzy ability, which increases their attack speed by 50%.", + item_names.HYDRALISK_ANCILLARY_CARAPACE: "Hydralisks gain +20 health.", + item_names.HYDRALISK_GROOVED_SPINES: "Hydralisks gain +1 range.", + item_names.BANELING_CORROSIVE_ACID: "Increases the damage banelings deal to their primary target. Splash damage remains the same.", + item_names.BANELING_RUPTURE: "Increases the splash radius of baneling attacks.", + item_names.BANELING_REGENERATIVE_ACID: "Banelings will heal nearby friendly units when they explode.", + item_names.MUTALISK_VICIOUS_GLAIVE: "Mutalisks attacks will bounce an additional 3 times.", + item_names.MUTALISK_RAPID_REGENERATION: "Mutalisks will regenerate quickly when out of combat.", + item_names.MUTALISK_SUNDERING_GLAIVE: "Mutalisks deal increased damage to their primary target.", + item_names.SWARM_HOST_BURROW: "Allows Swarm Hosts to burrow instead of root to spawn locusts.", + item_names.SWARM_HOST_RAPID_INCUBATION: "Swarm Hosts will spawn locusts 20% faster.", + item_names.SWARM_HOST_PRESSURIZED_GLANDS: "Allows Swarm Host Locusts to attack air targets.", + item_names.ULTRALISK_BURROW_CHARGE: "Allows Ultralisks to burrow and charge at enemy units, knocking back and stunning units when it emerges.", + item_names.ULTRALISK_TISSUE_ASSIMILATION: "Ultralisks recover health when they deal damage.", + item_names.ULTRALISK_MONARCH_BLADES: "Ultralisks gain increased splash damage.", + item_names.PYGALISK_STIM: _ability_desc("Pygalisks", "Stimpack", f"temporarily increases movement and attack speed at the cost of {STIMPACK_SMALL_COST} health"), + item_names.PYGALISK_DUCAL_BLADES: "Pygalisks do splash damage.", + item_names.PYGALISK_COMBAT_CARAPACE: "Increases Pygalisk health by +25.", + item_names.CORRUPTOR_CAUSTIC_SPRAY: "Allows Corruptors to use the Caustic Spray ability, which deals ramping damage to buildings over time.", + item_names.CORRUPTOR_CORRUPTION: "Allows Corruptors to use the Corruption ability, which causes a target enemy unit to take increased damage.", + item_names.SCOURGE_VIRULENT_SPORES: "Scourge will deal splash damage.", + item_names.SCOURGE_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.SCOURGE), + item_names.SCOURGE_SWARM_SCOURGE: "An extra Scourge will be built from each egg at no additional cost.", + item_names.ZERGLING_SHREDDING_CLAWS: "Zergling attacks will temporarily reduce their target's armor to 0.", + item_names.ROACH_GLIAL_RECONSTITUTION: "Increases Roach movement speed.", + item_names.ROACH_ORGANIC_CARAPACE: "Increases Roach health by +25.", + item_names.HYDRALISK_MUSCULAR_AUGMENTS: "Increases Hydralisk movement speed.", + item_names.HYDRALISK_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.HYDRALISK), + item_names.BANELING_CENTRIFUGAL_HOOKS: "Increases the movement speed of Banelings.", + item_names.BANELING_TUNNELING_JAWS: "Allows Banelings to move while burrowed.", + item_names.BANELING_RAPID_METAMORPH: "Banelings morph faster and no longer cost vespene gas to morph.", + item_names.MUTALISK_SEVERING_GLAIVE: "Mutalisk bounce attacks will deal full damage.", + item_names.MUTALISK_AERODYNAMIC_GLAIVE_SHAPE: "Increases the attack range of Mutalisks by 2.", + item_names.SWARM_HOST_LOCUST_METABOLIC_BOOST: "Increases Locust movement speed.", + item_names.SWARM_HOST_ENDURING_LOCUSTS: "Increases the duration of Swarm Hosts' Locusts by 10s.", + item_names.SWARM_HOST_ORGANIC_CARAPACE: "Increases Swarm Host health by +40.", + item_names.SWARM_HOST_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.SWARM_HOST), + item_names.ULTRALISK_ANABOLIC_SYNTHESIS: "Ultralisks gain increased movement speed.", + item_names.ULTRALISK_CHITINOUS_PLATING: "Ultralisks gain +2 armor.", + item_names.ULTRALISK_ORGANIC_CARAPACE: "Ultralisks gain +100 life.", + item_names.ULTRALISK_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.ULTRALISK), + item_names.DEVOURER_CORROSIVE_SPRAY: "Devourer attacks will now deal area damage.", + item_names.DEVOURER_GAPING_MAW: "Devourer's attack speed increased by 25%.", + item_names.DEVOURER_IMPROVED_OSMOSIS: "Devourer's Acid Spores duration increased by 50%.", + item_names.DEVOURER_PRESCIENT_SPORES: "Allows Devourers to attack ground targets.", + item_names.GUARDIAN_PROLONGED_DISPERSION: "Guardians gain +3 range.", + item_names.GUARDIAN_PRIMAL_ADAPTATION: "Allows Guardians to attack air units with a decreased attack damage.", + item_names.GUARDIAN_SORONAN_ACID: "Guardians deal +10 increased base damage to ground targets.", + item_names.GUARDIAN_PROPELLANT_SACS: "Guardians gain increased movement speed.", + item_names.GUARDIAN_EXPLOSIVE_SPORES: "Allows Guardians to launch an explosive spore at ground targets, dealing damage and knocking them back in an area.", + item_names.GUARDIAN_PRIMORDIAL_FURY: "Guardians gain increasing attack speed as they attack.", + item_names.IMPALER_ADAPTIVE_TALONS: "Impalers burrow faster.", + item_names.IMPALER_SECRETION_GLANDS: "Impalers generate creep while standing still or burrowed.", + item_names.IMPALER_SUNKEN_SPINES: "Impalers deal increased damage.", + item_names.LURKER_SEISMIC_SPINES: "Lurkers gain +6 range.", + item_names.LURKER_ADAPTED_SPINES: "Lurkers deal increased damage to non-light targets.", + item_names.RAVAGER_POTENT_BILE: "Ravager Corrosive Bile deals an additional +40 damage.", + item_names.RAVAGER_BLOATED_BILE_DUCTS: "Ravager Corrosive Bile hits a much larger area.", + item_names.RAVAGER_DEEP_TUNNEL: _ability_desc("Ravagers", "Deep Tunnel", "allows them to burrow to any visible location on the map"), + item_names.VIPER_PARASITIC_BOMB: _ability_desc("Vipers", "Parasitic Bomb", "inflicts an area-damaging effect on an enemy air unit"), + item_names.VIPER_PARALYTIC_BARBS: "Viper Abduct stuns units for an additional 5 seconds.", + item_names.VIPER_VIRULENT_MICROBES: "All Viper abilities gain +4 range.", + item_names.BROOD_LORD_POROUS_CARTILAGE: "Brood Lords gain increased movement speed.", + item_names.BROOD_LORD_BEHEMOTH_STELLARSKIN: "Brood Lords gain +100 life and +1 armor.", + item_names.BROOD_LORD_SPLITTER_MITOSIS: "Brood Lord attacks spawn twice as many broodlings.", + item_names.BROOD_LORD_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(DISPLAY_NAME_BROOD_LORD), + item_names.INFESTOR_INFESTED_TERRAN: _ability_desc("Infestors", "Spawn Infested Terran"), + item_names.INFESTOR_MICROBIAL_SHROUD: _ability_desc("Infestors", "Microbial Shroud", "reduces incoming damage from air units in an area"), + item_names.SPORE_CRAWLER_BIO_BONUS: "Spore Crawler gain +30 bonus damage against biological units.", + item_names.SWARM_QUEEN_SPAWN_LARVAE: _ability_desc("Swarm Queens", "Spawn Larvae"), + item_names.SWARM_QUEEN_DEEP_TUNNEL: _ability_desc("Swarm Queens", "Deep Tunnel"), + item_names.SWARM_QUEEN_ORGANIC_CARAPACE: "Swarm Queens gain +25 life.", + item_names.SWARM_QUEEN_BIO_MECHANICAL_TRANSFUSION: "Swarm Queen Burst Heal heals an additional +10 life and can now target mechanical units.", + item_names.SWARM_QUEEN_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.SWARM_QUEEN), + item_names.SWARM_QUEEN_INCUBATOR_CHAMBER: "Swarm Queens may now be built two at a time from the Hatchery, Lair, or Hive.", + item_names.BROOD_QUEEN_FUNGAL_GROWTH: _ability_desc("Brood Queens", "Fungal Growth"), + item_names.BROOD_QUEEN_ENSNARE: _ability_desc("Brood Queens", "Ensnare"), + item_names.BROOD_QUEEN_ENHANCED_MITOCHONDRIA: "Brood Queens start with maximum energy and gain increased energy regeneration. Like powerhouses (of the cell).", + item_names.DEFILER_PATHOGEN_PROJECTORS: "Defilers gain +4 cast range for Dark Swarm and Plague.", + item_names.DEFILER_TRAPDOOR_ADAPTATION: "Defilers can now use abilities while burrowed.", + item_names.DEFILER_PREDATORY_CONSUMPTION: "Defilers can now use Consume on any non-heroic biological unit, not just friendly Zerg.", + item_names.DEFILER_COMORBIDITY: "Plague now stacks up to three times, and depletes energy as well as health.", + item_names.ABERRATION_MONSTROUS_RESILIENCE: "Aberrations gain +140 life.", + item_names.ABERRATION_CONSTRUCT_REGENERATION: "Aberrations gain increased life regeneration.", + item_names.ABERRATION_PROTECTIVE_COVER: "Aberrations grant damage reduction to allied units directly beneath them.", + item_names.ABERRATION_BANELING_INCUBATION: "Aberrations spawn 2 Banelings upon death.", + item_names.ABERRATION_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.ABERRATION), + item_names.ABERRATION_PROGRESSIVE_BANELING_LAUNCH: inspect.cleandoc(""" + Level 1: Allows Aberrations to periodically throw generated Banelings at air targets. + Level 2: Can store up to 3 Banelings. Can consume Banelings to recharge faster. Thrown Banelings benefit from Baneling upgrades. + """), + item_names.CORRUPTOR_MONSTROUS_RESILIENCE: "Corruptors gain +100 life.", + item_names.CORRUPTOR_CONSTRUCT_REGENERATION: "Corruptors gain increased life regeneration.", + item_names.CORRUPTOR_SCOURGE_INCUBATION: "Corruptors spawn 2 Scourge upon death (3 with Swarm Scourge).", + item_names.CORRUPTOR_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.CORRUPTOR), + item_names.PRIMAL_IGNITER_CONCENTRATED_FIRE: "Primal Igniters deal +15 damage vs light armor.", + item_names.PRIMAL_IGNITER_PRIMAL_TENACITY: "Primal Igniters gain +100 health and +1 armor.", + item_names.INFESTED_SCV_BUILD_CHARGES: "Starting Infested SCV charges increased to 3. Maximum charges increased to 5.", + item_names.INFESTED_MARINE_PLAGUED_MUNITIONS: "Infested Marines deal an extra 50 damage over 15 seconds to targets they attack.", + item_names.INFESTED_MARINE_RETINAL_AUGMENTATION: "Infested Marines gain +1 range.", + item_names.INFESTED_BUNKER_CALCIFIED_ARMOR: "Infested Bunkers gain +3 armor.", + item_names.INFESTED_BUNKER_REGENERATIVE_PLATING: "Infested Bunkers gain increased life regeneration while rooted.", + item_names.INFESTED_BUNKER_ENGORGED_BUNKERS: "Infested Bunkers gain +2 cargo slots. Infested Trooper spawn cooldown is reduced by 20%.", + item_names.INFESTED_MISSILE_TURRET_BIOELECTRIC_PAYLOAD: "Increases anti-mechanical damage of Infested Missile Turrets by +6 per missile.", + item_names.INFESTED_MISSILE_TURRET_ACID_SPORE_VENTS: "Infested Missile Turrets gain a secondary weapon that applies Devourer Acid Spores in an area around the target.", + item_names.TYRANNOZOR_TYRANTS_PROTECTION: "Tyrannozors grant nearby friendly units 1 armor.", + item_names.TYRANNOZOR_BARRAGE_OF_SPIKES: _ability_desc("Tyrannozors", "Barrage of Spikes", "deals 60 damage to enemy ground units around the Tyrannozor"), + item_names.TYRANNOZOR_IMPALING_STRIKE: "Tyrannozor melee attacks have a 20% chance to stun for 2 seconds.", + item_names.TYRANNOZOR_HEALING_ADAPTATION: "Tyrannozors regenerate life quickly when out of combat.", + item_names.BILE_LAUNCHER_ARTILLERY_DUCTS: "Increases Bile Launcher range by +8.", + item_names.BILE_LAUNCHER_RAPID_BOMBARMENT: "Bile Launchers attack 40% faster.", + item_names.NYDUS_WORM_ECHIDNA_WORM_SUBTERRANEAN_SCALES: f"Increases {DISPLAY_NAME_WORMS} maximum health by 250 and armor by 1.", + item_names.NYDUS_WORM_ECHIDNA_WORM_JORMUNGANDR_STRAIN: f"Removes emerge time for {DISPLAY_NAME_WORMS}, and allows them to be salvaged to return the resources spent on them.", + item_names.NYDUS_WORM_RAVENOUS_APPETITE: "Allows Nydus Worms to unload and load units nearly instantly.", + item_names.NYDUS_WORM_ECHIDNA_WORM_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(DISPLAY_NAME_WORMS), + item_names.ECHIDNA_WORM_OUROBOROS_STRAIN: "Allows Echidna Worms to train a limited assortment of combat units (Zerglings, Roaches, Hydralisks, and Aberrations) at a reduced time and cost.", + item_names.INFESTED_SIEGE_TANK_PROGRESSIVE_AUTOMATED_MITOSIS: inspect.cleandoc(""" + Level 1: Infested Siege Tanks generate 1 Volatile Biomass every 30 seconds. + Level 2: Infested Siege Tanks generate 1 Volatile Biomass every 10 seconds. + """), + item_names.INFESTED_SIEGE_TANK_ACIDIC_ENZYMES: "Infested Siege Tanks deal an additional 15 damage to armored units and structures in both modes.", + item_names.INFESTED_SIEGE_TANK_DEEP_TUNNEL: _ability_desc("Infested Siege Tanks", "Deep Tunnel", "allows them to burrow to any visible location on the map covered in creep"), + item_names.INFESTED_SIEGE_TANK_SEISMIC_SONAR: "Infested Siege Tank Tentacle weapon gains +1 range. Volatile Burst weapon gains +3 range.", + item_names.INFESTED_SIEGE_TANK_BALANCED_ROOTS: "Allows Infested Siege Tanks to attack while moving with their Tentacle weapons.", + item_names.INFESTED_DIAMONDBACK_CAUSTIC_MUCUS: "Infested Diamondbacks leave behind a trail of acid when moving that deals 12 damage per second to enemy units.", + item_names.INFESTED_DIAMONDBACK_VIOLENT_ENZYMES: "Infested Diamondbacks deal an additional +8 damage.", + item_names.INFESTED_DIAMONDBACK_CONCENTRATED_SPEW: "Infested Diamondbacks gain +2 weapon range. Fungal Snare gains +2 range.", + item_names.INFESTED_DIAMONDBACK_PROGRESSIVE_FUNGAL_SNARE: inspect.cleandoc(""" + Level 1: Infested Diamondbacks gain the Fungal Snare ability, allowing them to temporarily ground flying units. + Level 2: Infested Diamondback Fungal Snare ability cooldown reduced by 15 seconds. + """), + item_names.BULLFROG_WILD_MUTATION: "Bullfrogs grant themselves and their cargo temporary health and an attack speed boost on impact.", + item_names.BULLFROG_RANGE: "Bullfrog leap gains +4 range, and unload-leap gains +6 range.", + item_names.BULLFROG_BROODLINGS: "Bullfrogs spawn two broodlings on impact, in addition to unloading their cargo.", + item_names.BULLFROG_HARD_IMPACT: "Bullfrogs deal more damage and stun longer on impact.", + item_names.INFESTED_BANSHEE_BRACED_EXOSKELETON: "Infested Banshees gain +100 life.", + item_names.INFESTED_BANSHEE_RAPID_HIBERNATION: "Infested Banshees regenerate 20 life and energy per second while burrowed.", + item_names.INFESTED_BANSHEE_FLESHFUSED_TARGETING_OPTICS: "Infested Banshees gain +2 range while cloaked.", + item_names.INFESTED_LIBERATOR_CLOUD_DISPERSAL: "Infested Liberators instantly transform into a cloud of microscopic organisms while attacking, reducing the damage they take by 85%.", + item_names.INFESTED_LIBERATOR_VIRAL_CONTAMINATION: "Increases the damage Infested Liberators deal to their primary target by 100%.", + item_names.INFESTED_LIBERATOR_DEFENDER_MODE: "Allows Infested Liberators to deploy into Defender Mode to attack ground units. Weapon knocks back the attack target and damages units behind it.", + item_names.INFESTED_SIEGE_TANK_FRIGHTFUL_FLESHWELDER: _get_resource_efficiency_desc(item_names.INFESTED_SIEGE_TANK), + item_names.INFESTED_DIAMONDBACK_FRIGHTFUL_FLESHWELDER: _get_resource_efficiency_desc(item_names.INFESTED_DIAMONDBACK), + item_names.INFESTED_BANSHEE_FRIGHTFUL_FLESHWELDER: _get_resource_efficiency_desc(item_names.INFESTED_BANSHEE), + item_names.INFESTED_LIBERATOR_FRIGHTFUL_FLESHWELDER: _get_resource_efficiency_desc(item_names.INFESTED_LIBERATOR), + item_names.ZERG_EXCAVATING_CLAWS: "Increases movement speed of uprooted Zerg structures, especially off creep. Also increases root speed.", + item_names.HIVE_CLUSTER_MATURATION: "Lairs are replaced with Hives, and Hatcheries can now upgrade directly to Hives at the Lair's original cost.", + item_names.MACROSCOPIC_RECUPERATION: "Zerg structures regenerate health rapidly while on creep and out of combat. Does not apply to uprooted structures, or structures with the Mechanical tag.", + item_names.BIOMECHANICAL_STOCKPILING: "Infested Factories and Starports can store 3 additional unit charges.", + item_names.BROODLING_SPORE_SATURATION: "Zerg buildings release twice as many broodlings on death. Zerg defensive structures release 4 broodlings on death.", + item_names.UNRESTRICTED_MUTATION: "Zerg Mercenary units are no longer limited by charges.", + item_names.CELL_DIVISION: "Adds additional units to Zerg Mercenary calldowns.", + item_names.EVOLUTIONARY_LEAP: "Halves the initial cooldown for all Zerg Mercenaries.", + item_names.SELF_SUFFICIENT: "Zerg Mercenaries no longer use supply.", + item_names.ZERGLING_RAPTOR_STRAIN: "Allows Zerglings to jump up and down cliffs and leap onto enemies. Also increases Zergling attack damage by 2.", + item_names.ZERGLING_SWARMLING_STRAIN: "Zerglings will spawn instantly and with an extra Zergling per egg at no additional cost.", + item_names.ROACH_VILE_STRAIN: "Roach attacks will slow the movement and attack speed of enemies.", + item_names.ROACH_CORPSER_STRAIN: "Units killed after being attacked by Roaches will spawn 2 Roachlings.", + item_names.HYDRALISK_IMPALER_ASPECT: "Allows Hydralisks to morph into Impalers.", + item_names.HYDRALISK_LURKER_ASPECT: "Allows Hydralisks to morph into Lurkers.", + item_names.BANELING_SPLITTER_STRAIN: "Banelings will split into two smaller Splitterlings on exploding.", + item_names.BANELING_HUNTER_STRAIN: "Allows Banelings to jump up and down cliffs and leap onto enemies.", + item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT: "Allows Mutalisks and Corruptors to morph into Brood Lords.", + item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT: "Allows Mutalisks and Corruptors to morph into Vipers.", + item_names.SWARM_HOST_CARRION_STRAIN: "Swarm Hosts will spawn Flying Locusts.", + item_names.SWARM_HOST_CREEPER_STRAIN: "Allows Swarm Hosts to teleport to any creep on the map in vision. Swarm Hosts will spread creep around them when rooted or burrowed.", + item_names.ULTRALISK_NOXIOUS_STRAIN: "Ultralisks will periodically spread poison, damaging nearby biological enemies.", + item_names.ULTRALISK_TORRASQUE_STRAIN: "Ultralisks will revive after being killed.", + item_names.KERRIGAN_KINETIC_BLAST: "Kerrigan deals 300 damage to target unit or structure from long range.", + item_names.KERRIGAN_HEROIC_FORTITUDE: "Kerrigan gains +200 maximum life and double life regeneration rate.", + item_names.KERRIGAN_LEAPING_STRIKE: "Kerrigan leaps to her target and deals 150 damage.", + item_names.KERRIGAN_CRUSHING_GRIP: "Kerrigan stuns enemies in a target area for 3 seconds and deals 30 damage over time. Heroic units are not stunned.", + item_names.KERRIGAN_CHAIN_REACTION: "Kerrigan's attacks deal normal damage to her target then jump to additional nearby enemies.", + item_names.KERRIGAN_PSIONIC_SHIFT: "Kerrigan dashes through enemies, dealing 50 damage to all enemies in her path.", + item_names.ZERGLING_RECONSTITUTION: "Killed Zerglings respawn from your primary Hatchery at no cost.", + item_names.OVERLORD_IMPROVED_OVERLORDS: "Overlords morph instantly and provide 50% more supply.", + item_names.AUTOMATED_EXTRACTORS: "Extractors automatically harvest Vespene Gas without the need for Drones.", + item_names.KERRIGAN_WILD_MUTATION: "Kerrigan gives all units in an area +200 max life and double attack speed for 10 seconds.", + item_names.KERRIGAN_SPAWN_BANELINGS: "Kerrigan spawns six Banelings with timed life.", + item_names.KERRIGAN_MEND: "Kerrigan heals for 150 life and heals nearby friendly units for 50 life. An additional +50% life is healed over 15 seconds.", + item_names.TWIN_DRONES: "Drones morph in groups of two at no additional cost and require less supply.", + item_names.MALIGNANT_CREEP: "Your units and structures gain increased life regeneration and 30% increased attack speed while on creep. Creep Tumors also spread creep faster and farther.", + item_names.VESPENE_EFFICIENCY: "Extractors produce Vespene gas 25% faster.", + item_names.ZERG_CREEP_STOMACH: "Zerg buildings no longer take damage off-creep. Defensive structures can now root off-creep.", + item_names.KERRIGAN_INFEST_BROODLINGS: "Enemies damaged by Kerrigan become infested and will spawn Broodlings with timed life if killed quickly.", + item_names.KERRIGAN_FURY: "Each of Kerrigan's attacks temporarily increase her attack speed by 15%. Can stack up to 75%.", + item_names.KERRIGAN_ABILITY_EFFICIENCY: "Kerrigan's abilities have their cooldown and energy cost reduced by 20%.", + item_names.KERRIGAN_APOCALYPSE: "Kerrigan deals 300 damage (+400 vs Structure) to enemies in a large area.", + item_names.KERRIGAN_SPAWN_LEVIATHAN: "Kerrigan summons a mighty flying Leviathan with timed life. Deals massive damage and has energy-based abilities.", + item_names.KERRIGAN_DROP_PODS: "Kerrigan drops Primal Zerg forces with timed life to the battlefield.", + item_names.KERRIGAN_PRIMAL_FORM: "Kerrigan takes on her Primal Zerg form and gains greatly increased energy regeneration.", + item_names.KERRIGAN_ASSIMILATION_AURA: "Causes all nearby enemies to drop resources when killed.", + item_names.KERRIGAN_IMMOBILIZATION_WAVE: "Deals 100 damage to enemies around a large area and stuns them for 10 seconds.", + item_names.KERRIGAN_LEVELS_10: "Gives Kerrigan +10 Levels.", + item_names.KERRIGAN_LEVELS_9: "Gives Kerrigan +9 Levels.", + item_names.KERRIGAN_LEVELS_8: "Gives Kerrigan +8 Levels.", + item_names.KERRIGAN_LEVELS_7: "Gives Kerrigan +7 Levels.", + item_names.KERRIGAN_LEVELS_6: "Gives Kerrigan +6 Levels.", + item_names.KERRIGAN_LEVELS_5: "Gives Kerrigan +5 Levels.", + item_names.KERRIGAN_LEVELS_4: "Gives Kerrigan +4 Levels.", + item_names.KERRIGAN_LEVELS_3: "Gives Kerrigan +3 Levels.", + item_names.KERRIGAN_LEVELS_2: "Gives Kerrigan +2 Levels.", + item_names.KERRIGAN_LEVELS_1: "Gives Kerrigan +1 Level.", + item_names.KERRIGAN_LEVELS_14: "Gives Kerrigan +14 Levels.", + item_names.KERRIGAN_LEVELS_35: "Gives Kerrigan +35 Levels.", + item_names.KERRIGAN_LEVELS_70: "Gives Kerrigan +70 Levels.", + item_names.INFESTED_MEDICS: "Mercenary infested Medics that may be called in from the Predator Nest.", + item_names.INFESTED_SIEGE_BREAKERS: "Mercenary infested Siege Breakers that may be called in from the Predator Nest.", + item_names.INFESTED_DUSK_WINGS: "Mercenary infested Dusk Wings that may be called in from the Predator Nest.", + item_names.HUNTER_KILLERS: "Elite Hydralisk strain. Summoned at the Predator Nest.", + item_names.DEVOURING_ONES: "Elite Zergling strain. Summoned at the Predator Nest.", + item_names.TORRASQUE_MERC: "Elite Ultralisk strain. Summoned at the Predator Nest.", + item_names.HUNTERLING: "Elite strain. Can jump up and down cliffs and stun enemies by jumping on them. Summoned at the Predator Nest.", + item_names.YGGDRASIL: "Elite Overlord strain that has the ability to transport buildings and ground units. Summoned at the Predator Nest.", + item_names.CAUSTIC_HORRORS: "Elite Roach Strain that has the ability to attack air units. Summoned at the Predator Nest.", + item_names.OVERLORD_VENTRAL_SACS: "Overlords gain the ability to transport ground units.", + item_names.OVERLORD_GENERATE_CREEP: "Overlords gain the ability to generate creep while standing still.", + item_names.OVERLORD_ANTENNAE: "Increases Overlord sight range.", + item_names.OVERLORD_PNEUMATIZED_CARAPACE: "Increases Overlord movement speed.", + item_names.OVERLORD_OVERSEER_ASPECT: "Allows Overlords to morph into Overseers. Overseers can use the Spawn Creep Tumor and Contaminate abilities.", + item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT: "Long-range anti-ground flyer. Can attack ground units. Morphed from the Mutalisk or Corruptor.", + item_names.MUTALISK_CORRUPTOR_DEVOURER_ASPECT: "Anti-air flyer. Attack inflict Acid Spores. Can attack air units. Morphed from the Mutalisk or Corruptor.", + item_names.ROACH_RAVAGER_ASPECT: "Ranged artillery. Can use Corrosive Bile. Can attack ground units. Morphed from the Roach.", + item_names.ROACH_PRIMAL_IGNITER_ASPECT: "Assault unit. Has an area-damage attack. Regenerates life quickly when burrowed. Can attack ground units. Morphed by merging two Roaches.", + item_names.NYDUS_WORM: "Long-range transport network. Nydus Worms and Nydus Networks can load friendly ground units to be unloaded to any other Nydus structure on the map.", + item_names.ECHIDNA_WORM: "Long-range deployable base. Unable to load and unload units, but can generate Creep and Creep Tumors. Can also serve as a dropoff point for resources and can create Drones.", + item_names.ULTRALISK_TYRANNOZOR_ASPECT: "Heavy assault beast. Has a ground-area attack, and powerful anti-air attack. Morphed by merging two Ultralisks.", + item_names.OBSERVER: "Flying spy. Cloak renders the unit invisible to enemies without detection.", + item_names.CENTURION: "Powerful melee warrior. Has the Shadow Charge and Darkcoil abilities.", + item_names.SENTINEL: "Powerful melee warrior. Has the Charge and Reconstruction abilities.", + item_names.SUPPLICANT: "Powerful melee warrior. Has powerful damage-resistant shields.", + item_names.INSTIGATOR: "Ranged support strider. Can store multiple Blink charges.", + item_names.SLAYER: "Ranged attack strider. Can use the Phase Blink and Phasing Armor abilities.", + item_names.SENTRY: "Robotic support unit. Can use the Guardian Shield ability and can restore the shields of nearby Protoss units.", + item_names.ENERGIZER: "Robotic support unit. Can use the Chrono Beam ability and can become stationary to power nearby structures.", + item_names.HAVOC: "Robotic support unit. Can use the Target Lock and Force Field abilities and increases the range of nearby Protoss units.", + item_names.SIGNIFIER: "Potent permanently cloaked psionic master. Can use the Feedback and Crippling Psionic Storm abilities. Can merge into an Archon.", + item_names.ASCENDANT: "Potent psionic master. Can use the Psionic Orb, Mind Blast, and Sacrifice abilities.", + item_names.AVENGER: "Deadly warrior-assassin. Permanently cloaked. Recalls to the nearest Dark Shrine upon death.", + item_names.BLOOD_HUNTER: "Deadly warrior-assassin. Permanently cloaked. Can use the Void Stasis ability.", + item_names.DRAGOON: "Ranged assault strider. Has enhanced health and damage.", + item_names.DARK_ARCHON: "Potent psionic master. Can use the Confuse and Mind Control abilities.", + item_names.ADEPT: "Ranged specialist. Can use the Psionic Transfer ability.", + item_names.WARP_PRISM: "Flying transport. Can carry units and become stationary to deploy a power field.", + item_names.ANNIHILATOR: "Assault Strider. Can use the Shadow Cannon ability to damage air and ground units.", + item_names.STALWART: "Assault strider. Has shields that deflect high-damage attacks.", + item_names.VANGUARD: "Assault Strider. Deals splash damage around the primary target.", + item_names.WRATHWALKER: "Battle strider with a powerful single-target attack. Can walk up and down cliffs.", + item_names.REAVER: "Area damage siege unit. Builds and launches explosive Scarabs for high burst damage.", + item_names.DISRUPTOR: "Robotic disruption unit. Can use the Purification Nova ability to deal heavy area damage.", + item_names.MIRAGE: "Air superiority starfighter. Can use Graviton Beam and Phasing Armor abilities.", + item_names.SKIRMISHER: "Fast skirmish starfighter. Can target ground units.", + item_names.CORSAIR: "Air superiority starfighter. Can use the Disruption Web ability.", + item_names.DESTROYER: "Area assault craft. Can use the Destruction Beam ability to attack multiple units at once.", + item_names.PULSAR: "Support craft. Applies a stacking slow to targets.", + item_names.DAWNBRINGER: "Flying Anti-Surface Assault Ship. Attacks in an area around the target. Attack count increases as it continues firing.", + item_names.SCOUT: "Versatile high-speed fighter. Has a powerful anti-armored air attack and a weaker anti-ground attack.", + item_names.OPPRESSOR: "Tal'Darim Scout variant. Has a weaker air attack, but a stronger ground attack. Can use the Vulcan Blaster ability.", + item_names.CALADRIUS: "Purifier Scout variant. Has no ground attack, but a stronger air attack, which can be upgraded to hit multiple targets. Can use the Corona Beam ability.", + item_names.MISTWING: "Nerazim Scout variant. Specialized stealth fighter. Can use the Cloak, Phantom Dash and Pilot (Transport) abilities.", + item_names.TEMPEST: "Siege artillery craft. Attacks from long range. Can use the Disintegration ability.", + item_names.MOTHERSHIP: "Ultimate Protoss vessel. Can use the Vortex and Mass Recall abilities.", + item_names.ARBITER: "Army support craft. Has the Stasis Field and Recall abilities. Cloaks nearby units.", + item_names.ORACLE: "Flying caster. Can use the Revelation and Stasis Ward abilities.", + item_names.SKYLORD: "Capital ship. Fires a powerful laser that deals damage in a line. Can use Tactical Jump ability.", + item_names.TRIREME: "Capital ship. Builds and launches Bombers that attack enemy targets.", + item_names.PROGRESSIVE_PROTOSS_GROUND_WEAPON: GENERIC_UPGRADE_TEMPLATE.format("damage", PROTOSS, "ground units"), + item_names.PROGRESSIVE_PROTOSS_GROUND_ARMOR: GENERIC_UPGRADE_TEMPLATE.format("armor", PROTOSS, "ground units"), + item_names.PROGRESSIVE_PROTOSS_SHIELDS: GENERIC_UPGRADE_TEMPLATE.format("shields", PROTOSS, "units"), + item_names.PROGRESSIVE_PROTOSS_AIR_WEAPON: GENERIC_UPGRADE_TEMPLATE.format("damage", PROTOSS, "starships"), + item_names.PROGRESSIVE_PROTOSS_AIR_ARMOR: GENERIC_UPGRADE_TEMPLATE.format("armor", PROTOSS, "starships"), + item_names.PROGRESSIVE_PROTOSS_WEAPON_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage", PROTOSS, "units"), + item_names.PROGRESSIVE_PROTOSS_ARMOR_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("armor", PROTOSS, "units"), + item_names.PROGRESSIVE_PROTOSS_GROUND_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage and armor", PROTOSS, "ground units"), + item_names.PROGRESSIVE_PROTOSS_AIR_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage and armor", PROTOSS, "starships"), + item_names.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE: GENERIC_UPGRADE_TEMPLATE.format("damage and armor", PROTOSS, "units"), + item_names.PHOTON_CANNON: "Protoss defensive structure. Can attack ground and air units.", + item_names.KHAYDARIN_MONOLITH: "Advanced Protoss defensive structure. Has superior range and damage, but is very expensive and attacks slowly.", + item_names.SHIELD_BATTERY: "Protoss defensive structure. Restores shields to nearby friendly units and structures.", + item_names.SUPPLICANT_BLOOD_SHIELD: "Increases the armor value of Supplicant shields.", + item_names.SUPPLICANT_SOUL_AUGMENTATION: "Increases Supplicant max shields by +25.", + item_names.SUPPLICANT_ENDLESS_SERVITUDE: "Increases Supplicant shield regeneration rate.", + item_names.SUPPLICANT_ZENITH_PITCH: "Allows Supplicants to attack air units.", + item_names.ADEPT_SHOCKWAVE: "When Adepts deal a finishing blow, their projectiles can jump onto 2 additional targets.", + item_names.ADEPT_RESONATING_GLAIVES: "Increases Adept attack speed.", + item_names.ADEPT_PHASE_BULWARK: "Increases Adept shield maximum by +50.", + item_names.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES: "Increases weapon damage of Stalkers, Instigators, and Slayers.", + item_names.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION: "Attacks fired by Stalkers, Instigators, and Slayers have a chance to bounce to additional targets for reduced damage.", + item_names.INSTIGATOR_BLINK_OVERDRIVE: "Instigators gain +2 maximum blink charges and +1 blink range.", + item_names.INSTIGATOR_RECONSTRUCTION: "Instigators gain the Reconstruction ability, allowing them to be reconstructed on death with a 240 seconds cooldown. Using Blink reduces the cooldown.", + item_names.DRAGOON_CONCENTRATED_ANTIMATTER: "Dragoons deal increased damage.", + item_names.DRAGOON_TRILLIC_COMPRESSION_SYSTEM: "Dragoons gain +20 life and their shield regeneration rate is doubled. Allows Dragoons to regenerate shields in combat.", + item_names.DRAGOON_SINGULARITY_CHARGE: "Increases Dragoon range by +2.", + item_names.DRAGOON_ENHANCED_STRIDER_SERVOS: "Increases Dragoon movement speed.", + item_names.SCOUT_COMBAT_SENSOR_ARRAY: "All Scout variants gain increased range against air and ground.", + item_names.SCOUT_APIAL_SENSORS: "Scouts gain increased sight range.", + item_names.SCOUT_GRAVITIC_THRUSTERS: "All Scout variants gain increased movement speed.", + item_names.SCOUT_ADVANCED_PHOTON_BLASTERS: "Scouts, Oppressors and Mist Wings gain increased damage against ground targets.", + item_names.SCOUT_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.SCOUT), + item_names.SCOUT_SUPPLY_EFFICIENCY: _get_resource_efficiency_desc(item_names.SCOUT, op_re_cost_reduction), + item_names.OPPRESSOR_ACCELERATED_WARP: "Oppressors gain increased training and warp-in speed.", + item_names.OPPRESSOR_ARMOR_MELTING_BLASTERS: "Oppressor ground weapons gain bonus damage to armored targets. Allows Vulcan Blaster to hit structures.", + item_names.CALADRIUS_SIDE_MISSILES: "Caladrius can hit up to 4 additional air targets with their missiles.", + item_names.CALADRIUS_STRUCTURE_TARGETING: "Allows Caladrius to hit ground structures with their anti-air missiles.", + item_names.CALADRIUS_SOLARITE_REACTOR: "If the Caladrius is low on shields, it recovers shields quickly for a short time.", + item_names.MISTWING_NULL_SHROUD: "Cloak no longer drains energy (but still prevents base energy regeneration). The Mist Wing becomes undetectable for 5 seconds upon cloaking.", + item_names.MISTWING_PILOT: _ability_desc("Mistwings", "Pilot", "can transport one unit as an additional co-pilot. A pilot grants a small bonus to damage and armor"), + item_names.TEMPEST_TECTONIC_DESTABILIZERS: "Tempests deal increased damage to buildings.", + item_names.TEMPEST_QUANTIC_REACTOR: "Tempests deal increased damage to massive units.", + item_names.TEMPEST_GRAVITY_SLING: "Tempests gain +8 range against air targets and +8 cast range.", + item_names.TEMPEST_INTERPLANETARY_RANGE: "Tempests gain +8 weapon range against all targets.", + item_names.PHOENIX_CLASS_IONIC_WAVELENGTH_FLUX: "Increases Phoenix, Mirage, and Skirmisher weapon damage by +2.", + item_names.PHOENIX_CLASS_ANION_PULSE_CRYSTALS: "Increases Phoenix, Mirage, and Skirmiser range by +2.", + item_names.CORSAIR_STEALTH_DRIVE: "Corsairs become permanently cloaked.", + item_names.CORSAIR_ARGUS_JEWEL: "Corsairs can store 2 charges of disruption web.", + item_names.CORSAIR_SUSTAINING_DISRUPTION: "Corsair disruption webs last longer.", + item_names.CORSAIR_NEUTRON_SHIELDS: "Increases corsair maximum shields by +20.", + item_names.ORACLE_STEALTH_DRIVE: "Oracles become permanently cloaked.", + item_names.ORACLE_SKYWARD_CHRONOANOMALY: "The Oracle's Stasis Ward can affect air units.", + item_names.ORACLE_TEMPORAL_ACCELERATION_BEAM: "Oracles no longer need to to spend energy to attack.", + item_names.ORACLE_BOSONIC_CORE: "Increases starting energy by 150 and maximum energy by 50.", + item_names.ARBITER_CHRONOSTATIC_REINFORCEMENT: "Arbiters gain +50 maximum life and +1 armor.", + item_names.ARBITER_KHAYDARIN_CORE: _get_start_and_max_energy_desc("Arbiters"), + item_names.ARBITER_SPACETIME_ANCHOR: "Allows Arbiters to use an alternate version of Stasis Field which lasts 50 seconds longer.", + item_names.ARBITER_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.ARBITER), + item_names.ARBITER_JUDICATORS_VEIL: "Increases Arbiter Cloaking Field range.", + item_names.CARRIER_TRIREME_GRAVITON_CATAPULT: "Carriers and Triremes can launch Interceptors and Bombers more quickly.", + item_names.CARRIER_SKYLORD_TRIREME_HULL_OF_PAST_GLORIES: "Carrier-class ships gain +2 armor.", + item_names.VOID_RAY_DESTROYER_PULSAR_DAWNBRINGER_FLUX_VANES: "Increases movement speed of Void Ray variants.", + item_names.DAWNBRINGER_ANTI_SURFACE_COUNTERMEASURES: "Dawnbringers take reduced damage from non-spell ground sources.", + item_names.DAWNBRINGER_ENHANCED_SHIELD_GENERATOR: "Increases Dawnbringer maximum shields by +50.", + item_names.PULSAR_CHRONOCLYSM: "Pulsar slow effect is also applied in an area around the primary target.", + item_names.PULSAR_ENTROPIC_REVERSAL: "Pulsars now regenerate life when out of combat.", + item_names.DESTROYER_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.DESTROYER), + item_names.WARP_PRISM_GRAVITIC_DRIVE: "Increases the movement speed of Warp Prisms.", + item_names.WARP_PRISM_PHASE_BLASTER: "Equips Warp Prisms with an auto-attack that can hit ground and air targets.", + item_names.WARP_PRISM_WAR_CONFIGURATION: "Warp Prisms transform faster and gain increased power radius in Phasing Mode.", + item_names.OBSERVER_GRAVITIC_BOOSTERS: "Increases Observer movement speed.", + item_names.OBSERVER_SENSOR_ARRAY: "Increases Observer sight range.", + item_names.REAVER_SCARAB_DAMAGE: "Reaver Scarabs deal +25 damage.", + item_names.REAVER_SOLARITE_PAYLOAD: "Reaver Scarabs gain increased splash damage radius.", + item_names.REAVER_REAVER_CAPACITY: "Reavers can store 10 Scarabs.", + item_names.REAVER_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(item_names.REAVER), + item_names.REAVER_BARGAIN_BIN_PRICES: _get_resource_efficiency_desc(item_names.REAVER, op_re_cost_reduction), + item_names.VANGUARD_AGONY_LAUNCHERS: "Increases Vanguard attack range by +2.", + item_names.VANGUARD_MATTER_DISPERSION: "Increases Vanguard attack area.", + item_names.IMMORTAL_ANNIHILATOR_SINGULARITY_CHARGE: "Increases Immortal and Annihilator attack range by +2.", + item_names.IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING: "Immortals and Annihilators can attack air units.", + item_names.IMMORTAL_ANNIHILATOR_DISRUPTOR_DISPERSION: "Immortals and Annihilators deal minor splash damage.", + item_names.STALWART_HIGH_VOLTAGE_CAPACITORS: "Increases Stalwart attack bounce range by +1.", + item_names.STALWART_REINTEGRATED_FRAMEWORK: "Increases the movement speed of Stalwarts.", + item_names.STALWART_STABILIZED_ELECTRODES: "Allows Stalwarts to attack while moving, and increases attack range by +1.", + item_names.STALWART_LATTICED_SHIELDING: "Increases Stalwart max shields by +50.", + item_names.DISRUPTOR_CLOAKING_MODULE: "Disruptors are permanently cloaked.", + item_names.DISRUPTOR_PERFECTED_POWER: "Allows Purification Nova to hit air units. Bonus damage to shields is now baseline for enemies (friendly damage unaffected).", + item_names.DISRUPTOR_RESTRAINED_DESTRUCTION: "Purification Nova does 50% reduced damage to friendly units and structures.", + item_names.COLOSSUS_PACIFICATION_PROTOCOL: "Increases Colossus attack speed.", + item_names.WRATHWALKER_RAPID_POWER_CYCLING: "Reduces the charging time and increases attack speed of the Wrathwalker's Charged Blast.", + item_names.WRATHWALKER_EYE_OF_WRATH: "Increases Wrathwalker weapon range by +1.", + item_names.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_SHROUD_OF_ADUN: f"Increases {DISPLAY_NAME_CLOAKED_ASSASSIN} maximum shields by +80.", + item_names.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_SHADOW_GUARD_TRAINING: f"Increases {DISPLAY_NAME_CLOAKED_ASSASSIN} maximum life by +40.", + item_names.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_BLINK: _ability_desc("Dark Templar, Avengers, and Blood Hunters", "Blink"), + item_names.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_RESOURCE_EFFICIENCY: _get_resource_efficiency_desc(DISPLAY_NAME_CLOAKED_ASSASSIN), + item_names.DARK_TEMPLAR_DARK_ARCHON_MELD: "Allows 2 Dark Templar to meld into a Dark Archon.", + item_names.DARK_TEMPLAR_ARCHON_MERGE: "Allows 2 Dark Templar to merge into a Archon.", + item_names.HIGH_TEMPLAR_SIGNIFIER_UNSHACKLED_PSIONIC_STORM: "High Templar and Signifiers deal increased damage with Psi Storm.", + item_names.HIGH_TEMPLAR_SIGNIFIER_HALLUCINATION: _ability_desc("High Templar and Signifiers", "Hallucination", "creates 2 hallucinated copies of a target unit"), + item_names.HIGH_TEMPLAR_SIGNIFIER_KHAYDARIN_AMULET: _get_start_and_max_energy_desc("High Templar and Signifiers"), + item_names.ARCHON_HIGH_ARCHON: "Archons can use High Templar abilities.", + item_names.ARCHON_TRANSCENDENCE: "Archons can float in the air. Can traverse cliffs and phase through most units. Increases Archon attack range by 1.", + item_names.ARCHON_POWER_SIPHON: _ability_desc("Archons", "Power Siphon", "deals damage to a target and replenishes shields over 2 seconds"), + item_names.ARCHON_ERADICATE: "On death, Archons launch towards nearby enemy ground units, dealing damage on impact.", + item_names.ARCHON_OBLITERATE: "Archon attacks get increased area of effect, and deal their biological bonus damage to all targets.", + item_names.DARK_ARCHON_FEEDBACK: _ability_desc("Dark Archons", "Feedback", "drains all energy from a target and deals 1 damage per point of energy drained"), + item_names.DARK_ARCHON_MAELSTROM: _ability_desc("Dark Archons", "Maelstrom", "stuns biological units in an area"), + item_names.DARK_ARCHON_ARGUS_TALISMAN: _get_start_and_max_energy_desc("Dark Archons"), + item_names.ASCENDANT_POWER_OVERWHELMING: "Ascendants gain the ability to sacrifice Supplicants for increased shields and spell damage.", + item_names.ASCENDANT_CHAOTIC_ATTUNEMENT: "Ascendants' Psionic Orbs gain 25% increased travel distance.", + item_names.ASCENDANT_BLOOD_AMULET: _get_start_and_max_energy_desc("Ascendants"), + item_names.ASCENDANT_ARCHON_MERGE: "Allows 2 Ascendants to merge into a Archon.", + item_names.SENTRY_ENERGIZER_HAVOC_CLOAKING_MODULE: "Sentries, Energizers, and Havocs become permanently cloaked.", + item_names.SENTRY_ENERGIZER_HAVOC_SHIELD_BATTERY_RAPID_RECHARGING: "Sentries, Energizers, and Havocs gain +100% energy regeneration rate.", + item_names.SENTRY_FORCE_FIELD: _ability_desc("Sentries", "Force Field", "creates a force field that blocks units from walking through"), + item_names.SENTRY_HALLUCINATION: _ability_desc("Sentries", "Hallucination", "creates hallucinated versions of Protoss units"), + item_names.ENERGIZER_RECLAMATION: _ability_desc("Energizers", "Reclamation", "temporarily takes control of an enemy mechanical unit. When the ability expires, the enemy unit self-destructs"), + item_names.ENERGIZER_FORGED_CHASSIS: "Increases Energizer Life by +20.", + item_names.HAVOC_DETECT_WEAKNESS: "Havocs' Target Lock gives an additional +15% damage bonus.", + item_names.HAVOC_BLOODSHARD_RESONANCE: "Havocs gain increased range for Squad Sight, Target Lock, and Force Field.", + item_names.ZEALOT_SENTINEL_CENTURION_LEG_ENHANCEMENTS: "Zealots, Sentinels, and Centurions gain increased movement speed.", + item_names.ZEALOT_SENTINEL_CENTURION_SHIELD_CAPACITY: "Zealots, Sentinels, and Centurions gain +30 maximum shields.", + item_names.ZEALOT_WHIRLWIND: "Zealot War Council ability.\nGives Zealots the whirlwind ability, dealing damage in an area over 3 seconds.", + item_names.CENTURION_RESOURCE_EFFICIENCY: "Centurion War Council upgrade.\n" + _get_resource_efficiency_desc( + item_names.CENTURION), + item_names.SENTINEL_RESOURCE_EFFICIENCY: "Sentinel War Council upgrade.\n" + _get_resource_efficiency_desc( + item_names.SENTINEL), + item_names.STALKER_PHASE_REACTOR: "Stalker War Council upgrade.\nStalkers restore 80 shields over 5 seconds after they Blink.", + item_names.DRAGOON_PHALANX_SUIT: "Dragoon War Council upgrade.\nDragoons gain +1 range, move slightly faster, and can form tighter formations.", + item_names.INSTIGATOR_MODERNIZED_SERVOS: "Instigator War Council upgrade.\nInstigators move 28% faster.", + item_names.ADEPT_DISRUPTIVE_TRANSFER: "Adept War Council upgrade.\nAdept shades apply a debuff to enemies they touch, increasing damage taken by +5.", + item_names.SLAYER_PHASE_BLINK: "Slayer War Council ability.\nSlayers can now blink. After blinking, the Slayer's next attack within 8 seconds deals double damage.", + item_names.AVENGER_KRYHAS_CLOAK: "Avenger War Council upgrade.\nAvengers are now permanently cloaked.", + item_names.DARK_TEMPLAR_LESSER_SHADOW_FURY: "Dark Templar War Council ability.\nDark Templar gain two strikes of their Shadow Fury ability.", + item_names.DARK_TEMPLAR_GREATER_SHADOW_FURY: "Dark Templar War Council ability.\nDark Templar gain three strikes of their Shadow Fury ability.", + item_names.BLOOD_HUNTER_BRUTAL_EFFICIENCY: "Blood Hunter War Council upgrade.\nBlood Hunters attack twice as quickly.", + item_names.SENTRY_DOUBLE_SHIELD_RECHARGE: "Sentry War Council upgrade.\nSentries can heal the shields of two targets at once.", + item_names.ENERGIZER_MOBILE_CHRONO_BEAM: "Energizer War Council upgrade.\nAllows Energizers to use Chrono Beam in Mobile Mode.", + item_names.HAVOC_ENDURING_SIGHT: "Havoc War Council upgrade.\nHavoc Squad Sight stays up indefinitely and no longer takes energy.", + item_names.HIGH_TEMPLAR_PLASMA_SURGE: "High Templar War Council upgrade.\nHigh Templar Psionic Storm will heal fiendly protoss shields under it.", + item_names.SIGNIFIER_FEEDBACK: "Signifier War Council ability.\n" + _ability_desc("Signifiers", "Feedback", "drains all energy from a target and deals 1 damage per point of energy drained"), + item_names.ASCENDANT_BREATH_OF_CREATION: "Ascendant War Council upgrade.\nAscendant spells cost -25 energy.", + item_names.DARK_ARCHON_INDOMITABLE_WILL: "Dark Archon War Council upgrade.\nCasting Mind Control will no longer deplete the Dark Archon's shields.", + item_names.IMMORTAL_IMPROVED_BARRIER: "Immortal War Council upgrade.\nThe Immortal's Barrier ability absorbs an additional +100 damage.", + item_names.VANGUARD_RAPIDFIRE_CANNON: "Vanguard War Council upgrade.\nVanguards attack 60% faster.", + item_names.VANGUARD_FUSION_MORTARS: "Vanguard War Council upgrade.\nVanguards deal +7 damage to armored targets per attack.", + item_names.ANNIHILATOR_TWILIGHT_CHASSIS: "Annihilator War Council upgrade.\nThe Annihilator gains +100 maximum life.", + item_names.STALWART_ARC_INDUCERS: "Stalwart War Council upgrade.\nStalwarts damage up to 3 additional units when attacking.", + item_names.COLOSSUS_FIRE_LANCE: "Colossus War Council upgrade.\nColossi set the ground on fire with their attacks, dealing damage to enemies over time.", + item_names.WRATHWALKER_AERIAL_TRACKING: "Wrathwalker War Council upgrade.\nWrathwalkers can now target air units.", + item_names.REAVER_KHALAI_REPLICATORS: "Reaver War Council upgrade.\nReaver Scarabs no longer cost minerals.", + item_names.DISRUPTOR_MOBILITY_PROTOCOLS: "Disruptor War Council upgrade.\nAllows the Disruptor to move while casting Purification Nova. Also allows the Disruptor to Blink.", + item_names.WARP_PRISM_WARP_REFRACTION: "Warp Prism War Council upgrade.\nWarp Prisms gain +5 pickup range and unload units 10 times faster.", + item_names.OBSERVER_INDUCE_SCOPOPHOBIA: "Observer War Council ability.\n" + _ability_desc("Observers", "Induce Scopophobia", "reduces the attack and movement speed of an enemy by 20%"), + item_names.PHOENIX_DOUBLE_GRAVITON_BEAM: "Phoenix War Council upgrade.\nPhoenixes can now use Graviton Beam to lift two targets at once.", + item_names.CORSAIR_NETWORK_DISRUPTION: "Corsair War Council upgrade.\nTriples the radius of Disruption Web.", + item_names.MIRAGE_GRAVITON_BEAM: "Mirage War Council ability.\nAllows Mirages to use Graviton Beam.", + item_names.SKIRMISHER_PEER_CONTEMPT: "Skirmisher War Council upgrade.\nAllows Skirmishers to target air units.", + item_names.VOID_RAY_PRISMATIC_RANGE: "Void Ray War Council upgrade.\nVoid Rays gain increased range as they charge their beam.", + item_names.DESTROYER_REFORGED_BLOODSHARD_CORE: "Destroyer War Council upgrade.\nIncreases the Destroyer's bounce attack damage to 3 (+2 vs armored) at all charge levels, and allows the bounces to benefit from protoss air weapon upgrades.", + item_names.PULSAR_CHRONO_SHEAR: "Pulsar War Council upgrade.\nFully-stacked slow on non-heroic targets also applies a defense debuff.", + item_names.DAWNBRINGER_SOLARITE_LENS: "Dawnbringer War Council upgrade.\nDawnbringers gain +2 range.", + item_names.CARRIER_REPAIR_DRONES: "Carrier War Council upgrade.\nCarriers gain 2 repair drones which heal nearby mechanical units.", + item_names.SKYLORD_JUMP: "Skylord War Council ability.\n" + _ability_desc("Skylords", "Jump", "instantly teleports the Skylord a short distance"), + item_names.TRIREME_SOLAR_BEAM: "Trireme War Council weapon.\nTriremes gain an anti-air laser attack that deals more damage over time.", + item_names.TEMPEST_DISINTEGRATION: "Tempest War Council ability.\n" + _ability_desc("Tempests", "Disintegration", "deals 500 damage to a target unit or structure over 20 seconds"), + item_names.SCOUT_EXPEDITIONARY_HULL: "Scout War Council upgrade.\nScouts gain +25 shields, +50 health, +1 shield armor, and reduced shield regeneration delay.", + item_names.ARBITER_VESSEL_OF_THE_CONCLAVE: "Arbiter War Council upgrade.\nReduces the energy cost of Recall by 50 and Stasis Field by 100.", + item_names.ORACLE_STASIS_CALIBRATION: "Oracle War Council upgrade.\nEnemies caught by the Oracle's Stasis Ward may now be attacked for the first 5 seconds of stasis.", + item_names.MOTHERSHIP_INTEGRATED_POWER: "Mothership War Council upgrade.\nAllows Motherships to move at full speed outside pylon power.", + item_names.OPPRESSOR_VULCAN_BLASTER: "Oppressor War Council ability.\n" + _ability_desc("Oppressors", "Vulcan Blaster", "activates a powerful short range anti-ground weapon for a limited time. Greatly reduces movement and turning speed, and disables other weapons while active"), + item_names.CALADRIUS_CORONA_BEAM: "Caladrius War Council ability.\n" + _ability_desc("Caladrius", "Corona Beam", "channels a beam that drains up to 100 of the Caladrius' shields to deal up to 200 damage over time to a single target"), + item_names.MISTWING_PHANTOM_DASH: "Mist Wing War Council ability.\n" + _ability_desc("Mist Wings", "Phantom Dash", "dashes forward to cover some distance quickly. Deals damage in a line if the Mist Wing is cloaked"), + item_names.SUPPLICANT_SACRIFICE: "Supplicant War Council ability.\nAllows Supplicants to sacrifice themselves to save nearby units from death.", + + + item_names.SOA_CHRONO_SURGE: "The Spear of Adun increases a target structure's unit warp in and research speeds by +1000% for 20 seconds.", + item_names.SOA_PROGRESSIVE_PROXY_PYLON: inspect.cleandoc(""" + Level 1: The Spear of Adun quickly warps in a Pylon to a target location. + Level 2: The Spear of Adun warps in a Pylon, 2 melee warriors, and 2 ranged warriors to a target location. + """), + item_names.SOA_PYLON_OVERCHARGE: "The Spear of Adun temporarily gives a target Pylon increased shields and a powerful attack.", + item_names.SOA_ORBITAL_STRIKE: "The Spear of Adun fires 5 laser blasts from orbit.", + item_names.SOA_TEMPORAL_FIELD: "The Spear of Adun creates 3 temporal fields that freeze enemy units and structures in time.", + item_names.SOA_SOLAR_LANCE: "The Spear of Adun strafes a target area with 3 laser beams.", + item_names.SOA_MASS_RECALL: "The Spear of Adun warps all units in a target area back to the primary Nexus and gives them a temporary shield.", + item_names.SOA_SHIELD_OVERCHARGE: "The Spear of Adun gives all friendly units a shield that absorbs 200 damage. Lasts 20 seconds.", + item_names.SOA_DEPLOY_FENIX: "The Spear of Adun drops Fenix onto the battlefield. Fenix is a powerful warrior who will fight for 30 seconds.", + item_names.SOA_PURIFIER_BEAM: "The Spear of Adun fires a wide laser that deals large amounts of damage in a moveable area. Lasts 15 seconds.", + item_names.SOA_TIME_STOP: "The Spear of Adun freezes all enemy units and structures in time for 20 seconds.", + item_names.SOA_SOLAR_BOMBARDMENT: "The Spear of Adun fires 200 laser blasts randomly over a wide area.", + item_names.MATRIX_OVERLOAD: "All friendly units gain 25% movement speed and 15% attack speed within a Pylon's power field and for 15 seconds after leaving it.", + item_names.QUATRO: "All friendly Protoss units gain the equivalent of their +1 armor, attack, and shield upgrades.", + item_names.NEXUS_OVERCHARGE: "The Protoss Nexus gains a long-range auto-attack.", + item_names.ORBITAL_ASSIMILATORS: "Assimilators automatically harvest Vespene Gas without the need for Probes.", + item_names.WARP_HARMONIZATION: "Stargates and Robotics Facilities can transform to utilize Warp In technology. Warp In cooldowns are 20% faster than original build times.", + item_names.GUARDIAN_SHELL: "The Spear of Adun passively shields friendly Protoss units before death, making them invulnerable for 5 seconds. Each unit can only be shielded once every 60 seconds.", + item_names.RECONSTRUCTION_BEAM: "The Spear of Adun will passively heal mechanical units for 5 and non-biological structures for 10 life per second. Up to 3 targets can be repaired at once.", + item_names.OVERWATCH: "Once per second, the Spear of Adun will last-hit a damaged enemy unit that is below 50 health.", + item_names.SUPERIOR_WARP_GATES: "Protoss Warp Gates can hold up to 3 charges of unit warp-ins.", + item_names.ENHANCED_TARGETING: "Protoss defensive structures gain +2 range.", + item_names.OPTIMIZED_ORDNANCE: "Increases the attack speed of Protoss defensive structures by 25%.", + item_names.KHALAI_INGENUITY: "Pylons, Photon Cannons, Monoliths, and Shield Batteries warp in near-instantly.", + item_names.AMPLIFIED_ASSIMILATORS: "Assimilators produce Vespene gas 25% faster.", + item_names.PROGRESSIVE_WARP_RELOCATE: inspect.cleandoc(""" + Level 1: Protoss structures can be moved anywhere within pylon power after a brief delay. Max 3 charges, shared globally. + Level 2: No longer consumes or requires charges. + """), + item_names.PROBE_WARPIN: "You can warp in additonal Probes from your Nexus to any visible location within a Pylon's power field. Has a 30 second cooldown and can store up to 2 charges.", + item_names.ELDER_PROBES: "You can warp in a group of 5 Elder Probes, tough builders from the Brood War. Elder Probes can provide a Power Field and get reconstructed on death. Can only be used once per mission.", +} + +# Key descriptions +key_descriptions = { + key: GENERIC_KEY_DESC + for key in item_tables.key_item_table.keys() +} +item_descriptions.update(key_descriptions) diff --git a/worlds/sc2/item/item_groups.py b/worlds/sc2/item/item_groups.py new file mode 100644 index 000000000000..ea65dc3e4aba --- /dev/null +++ b/worlds/sc2/item/item_groups.py @@ -0,0 +1,902 @@ +import typing +from . import item_tables, item_names +from .item_tables import key_item_table +from ..mission_tables import campaign_mission_table, SC2Campaign, SC2Mission, SC2Race + +""" +Item name groups, given to Archipelago and used in YAMLs and /received filtering. +For non-developers the following will be useful: +* Items with a bracket get groups named after the unbracketed part + * eg. "Advanced Healing AI (Medivac)" is accessible as "Advanced Healing AI" + * The exception to this are item names that would be ambiguous (eg. "Resource Efficiency") +* Item flaggroups get unique groups as well as combined groups for numbered flaggroups + * eg. "Unit" contains all units, "Armory" contains "Armory 1" through "Armory 6" + * The best place to look these up is at the bottom of Items.py +* Items that have a parent are grouped together + * eg. "Zergling Items" contains all items that have "Zergling" as a parent + * These groups do NOT contain the parent item + * This currently does not include items with multiple potential parents, like some LotV unit upgrades +* All items are grouped by their race ("Terran", "Protoss", "Zerg", "Any") +* Hand-crafted item groups can be found at the bottom of this file +""" + +item_name_groups: typing.Dict[str, typing.List[str]] = {} + +# Groups for use in world logic +item_name_groups["Missions"] = ["Beat " + mission.mission_name for mission in SC2Mission] +item_name_groups["WoL Missions"] = ["Beat " + mission.mission_name for mission in campaign_mission_table[SC2Campaign.WOL]] + \ + ["Beat " + mission.mission_name for mission in campaign_mission_table[SC2Campaign.PROPHECY]] + +# These item name groups should not show up in documentation +unlisted_item_name_groups = { + "Missions", "WoL Missions", + item_tables.TerranItemType.Progressive.display_name, + item_tables.TerranItemType.Nova_Gear.display_name, + item_tables.TerranItemType.Mercenary.display_name, + item_tables.ZergItemType.Ability.display_name, + item_tables.ZergItemType.Morph.display_name, + item_tables.ZergItemType.Strain.display_name, +} + +# Some item names only differ in bracketed parts +# These items are ambiguous for short-hand name groups +bracketless_duplicates: typing.Set[str] +# This is a list of names in ItemNames with bracketed parts removed, for internal use +_shortened_names = [(name[:name.find(' (')] if '(' in name else name) + for name in [item_names.__dict__[name] for name in item_names.__dir__() if not name.startswith('_')]] +# Remove the first instance of every short-name from the full item list +bracketless_duplicates = set(_shortened_names) +for name in bracketless_duplicates: + _shortened_names.remove(name) +# The remaining short-names are the duplicates +bracketless_duplicates = set(_shortened_names) +del _shortened_names + +# All items get sorted into their data type +for item, data in item_tables.get_full_item_list().items(): + # Items get assigned to their flaggroup's display type + item_name_groups.setdefault(data.type.display_name, []).append(item) + # Items with a bracket get a short-hand name group for ease of use in YAMLs + if '(' in item: + short_name = item[:item.find(' (')] + # Ambiguous short-names are dropped + if short_name not in bracketless_duplicates: + item_name_groups[short_name] = [item] + # Short-name groups are unlisted + unlisted_item_name_groups.add(short_name) + # Items with a parent get assigned to their parent's group + if data.parent: + # The parent groups need a special name, otherwise they are ambiguous with the parent + parent_group = f"{data.parent} Items" + item_name_groups.setdefault(parent_group, []).append(item) + # Parent groups are unlisted + unlisted_item_name_groups.add(parent_group) + # All items get assigned to their race's group + race_group = data.race.name.capitalize() + item_name_groups.setdefault(race_group, []).append(item) + + +# Hand-made groups +class ItemGroupNames: + TERRAN_ITEMS = "Terran Items" + """All Terran items""" + TERRAN_UNITS = "Terran Units" + TERRAN_GENERIC_UPGRADES = "Terran Generic Upgrades" + """+attack/armour upgrades""" + BARRACKS_UNITS = "Barracks Units" + FACTORY_UNITS = "Factory Units" + STARPORT_UNITS = "Starport Units" + WOL_UNITS = "WoL Units" + WOL_MERCS = "WoL Mercenaries" + WOL_BUILDINGS = "WoL Buildings" + WOL_UPGRADES = "WoL Upgrades" + WOL_ITEMS = "WoL Items" + """All items from vanilla WoL. Note some items are progressive where level 2 is not vanilla.""" + NCO_UNITS = "NCO Units" + NCO_BUILDINGS = "NCO Buildings" + NCO_UNIT_TECHNOLOGY = "NCO Unit Technology" + NCO_BASELINE_UPGRADES = "NCO Baseline Upgrades" + NCO_UPGRADES = "NCO Upgrades" + NOVA_EQUIPMENT = "Nova Equipment" + NOVA_WEAPONS = "Nova Weapons" + NOVA_GADGETS = "Nova Gadgets" + NCO_MAX_PROGRESSIVE_ITEMS = "NCO +Items" + """NCO item groups that should be set to maximum progressive amounts""" + NCO_MIN_PROGRESSIVE_ITEMS = "NCO -Items" + """NCO item groups that should be set to minimum progressive amounts (1)""" + TERRAN_BUILDINGS = "Terran Buildings" + TERRAN_MERCENARIES = "Terran Mercenaries" + TERRAN_STIMPACKS = "Terran Stimpacks" + TERRAN_PROGRESSIVE_UPGRADES = "Terran Progressive Upgrades" + TERRAN_ORIGINAL_PROGRESSIVE_UPGRADES = "Terran Original Progressive Upgrades" + """Progressive items where level 1 appeared in WoL""" + MENGSK_UNITS = "Mengsk Units" + TERRAN_VETERANCY_UNITS = "Terran Veterancy Units" + ORBITAL_COMMAND_ABILITIES = "Orbital Command Abilities" + WOL_ORBITAL_COMMAND_ABILITIES = "WoL Command Center Abilities" + + ZERG_ITEMS = "Zerg Items" + ZERG_UNITS = "Zerg Units" + ZERG_NONMORPH_UNITS = "Zerg Non-morph Units" + ZERG_GENERIC_UPGRADES = "Zerg Generic Upgrades" + """+attack/armour upgrades""" + HOTS_UNITS = "HotS Units" + HOTS_BUILDINGS = "HotS Buildings" + HOTS_STRAINS = "HotS Strains" + """Vanilla HotS strains (the upgrades you play a mini-mission for)""" + HOTS_MUTATIONS = "HotS Mutations" + """Vanilla HotS Mutations (basic toggleable unit upgrades)""" + HOTS_GLOBAL_UPGRADES = "HotS Global Upgrades" + HOTS_MORPHS = "HotS Morphs" + KERRIGAN_ABILITIES = "Kerrigan Abilities" + KERRIGAN_HOTS_ABILITIES = "Kerrigan HotS Abilities" + KERRIGAN_ACTIVE_ABILITIES = "Kerrigan Active Abilities" + KERRIGAN_LOGIC_ACTIVE_ABILITIES = "Kerrigan Logic Active Abilities" + KERRIGAN_PASSIVES = "Kerrigan Passives" + KERRIGAN_TIER_1 = "Kerrigan Tier 1" + KERRIGAN_TIER_2 = "Kerrigan Tier 2" + KERRIGAN_TIER_3 = "Kerrigan Tier 3" + KERRIGAN_TIER_4 = "Kerrigan Tier 4" + KERRIGAN_TIER_5 = "Kerrigan Tier 5" + KERRIGAN_TIER_6 = "Kerrigan Tier 6" + KERRIGAN_TIER_7 = "Kerrigan Tier 7" + KERRIGAN_ULTIMATES = "Kerrigan Ultimates" + KERRIGAN_LOGIC_ULTIMATES = "Kerrigan Logic Ultimates" + KERRIGAN_NON_ULTIMATES = "Kerrigan Non-Ultimates" + KERRIGAN_NON_ULTIMATE_ACTIVE_ABILITIES = "Kerrigan Non-Ultimate Active Abilities" + HOTS_ITEMS = "HotS Items" + """All items from vanilla HotS""" + OVERLORD_UPGRADES = "Overlord Upgrades" + ZERG_MORPHS = "Zerg Morphs" + ZERG_MERCENARIES = "Zerg Mercenaries" + ZERG_BUILDINGS = "Zerg Buildings" + INF_TERRAN_ITEMS = "Infested Terran Items" + """All items from Stukov co-op subfaction""" + INF_TERRAN_UNITS = "Infested Terran Units" + INF_TERRAN_UPGRADES = "Infested Terran Upgrades" + + PROTOSS_ITEMS = "Protoss Items" + PROTOSS_UNITS = "Protoss Units" + PROTOSS_GENERIC_UPGRADES = "Protoss Generic Upgrades" + """+attack/armour upgrades""" + GATEWAY_UNITS = "Gateway Units" + ROBO_UNITS = "Robo Units" + STARGATE_UNITS = "Stargate Units" + PROPHECY_UNITS = "Prophecy Units" + PROPHECY_BUILDINGS = "Prophecy Buildings" + LOTV_UNITS = "LotV Units" + LOTV_ITEMS = "LotV Items" + LOTV_GLOBAL_UPGRADES = "LotV Global Upgrades" + SOA_ITEMS = "SOA" + PROTOSS_GLOBAL_UPGRADES = "Protoss Global Upgrades" + PROTOSS_BUILDINGS = "Protoss Buildings" + WAR_COUNCIL = "Protoss War Council Upgrades" + AIUR_UNITS = "Aiur" + NERAZIM_UNITS = "Nerazim" + TAL_DARIM_UNITS = "Tal'Darim" + PURIFIER_UNITS = "Purifier" + + VANILLA_ITEMS = "Vanilla Items" + OVERPOWERED_ITEMS = "Overpowered Items" + UNRELEASED_ITEMS = "Unreleased Items" + LEGACY_ITEMS = "Legacy Items" + + KEYS = "Keys" + + @classmethod + def get_all_group_names(cls) -> typing.Set[str]: + return { + name for identifier, name in cls.__dict__.items() + if not identifier.startswith('_') + and not identifier.startswith('get_') + } + + +# Terran +item_name_groups[ItemGroupNames.TERRAN_ITEMS] = terran_items = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.race == SC2Race.TERRAN +] +item_name_groups[ItemGroupNames.TERRAN_UNITS] = terran_units = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type in ( + item_tables.TerranItemType.Unit, item_tables.TerranItemType.Unit_2, item_tables.TerranItemType.Mercenary) +] +item_name_groups[ItemGroupNames.TERRAN_GENERIC_UPGRADES] = terran_generic_upgrades = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type == item_tables.TerranItemType.Upgrade +] +barracks_wa_group = [ + item_names.MARINE, item_names.FIREBAT, item_names.MARAUDER, + item_names.REAPER, item_names.GHOST, item_names.SPECTRE, item_names.HERC, item_names.AEGIS_GUARD, + item_names.EMPERORS_SHADOW, item_names.DOMINION_TROOPER, item_names.SON_OF_KORHAL, +] +item_name_groups[ItemGroupNames.BARRACKS_UNITS] = barracks_units = (barracks_wa_group + [ + item_names.MEDIC, + item_names.FIELD_RESPONSE_THETA, +]) +factory_wa_group = [ + item_names.HELLION, item_names.VULTURE, item_names.GOLIATH, item_names.DIAMONDBACK, + item_names.SIEGE_TANK, item_names.THOR, item_names.PREDATOR, + item_names.CYCLONE, item_names.WARHOUND, item_names.SHOCK_DIVISION, item_names.BLACKHAMMER, + item_names.BULWARK_COMPANY, +] +item_name_groups[ItemGroupNames.FACTORY_UNITS] = factory_units = (factory_wa_group + [ + item_names.WIDOW_MINE, +]) +starport_wa_group = [ + item_names.WRAITH, item_names.VIKING, item_names.BANSHEE, + item_names.BATTLECRUISER, item_names.RAVEN_HUNTER_SEEKER_WEAPON, + item_names.LIBERATOR, item_names.VALKYRIE, item_names.PRIDE_OF_AUGUSTRGRAD, item_names.SKY_FURY, + item_names.EMPERORS_GUARDIAN, item_names.NIGHT_HAWK, item_names.NIGHT_WOLF, +] +item_name_groups[ItemGroupNames.STARPORT_UNITS] = starport_units = [ + item_names.MEDIVAC, item_names.WRAITH, item_names.VIKING, item_names.BANSHEE, + item_names.BATTLECRUISER, item_names.HERCULES, item_names.SCIENCE_VESSEL, item_names.RAVEN, + item_names.LIBERATOR, item_names.VALKYRIE, item_names.PRIDE_OF_AUGUSTRGRAD, item_names.SKY_FURY, + item_names.EMPERORS_GUARDIAN, item_names.NIGHT_HAWK, item_names.NIGHT_WOLF, +] +item_name_groups[ItemGroupNames.TERRAN_MERCENARIES] = terran_mercenaries = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type == item_tables.TerranItemType.Mercenary +] +item_name_groups[ItemGroupNames.NCO_UNITS] = nco_units = [ + item_names.MARINE, item_names.MARAUDER, item_names.REAPER, + item_names.HELLION, item_names.GOLIATH, item_names.SIEGE_TANK, + item_names.RAVEN, item_names.LIBERATOR, item_names.BANSHEE, item_names.BATTLECRUISER, + item_names.HERC, # From that one bonus objective in mission 5 +] +item_name_groups[ItemGroupNames.NCO_BUILDINGS] = nco_buildings = [ + item_names.BUNKER, item_names.MISSILE_TURRET, item_names.PLANETARY_FORTRESS, +] +item_name_groups[ItemGroupNames.NOVA_EQUIPMENT] = nova_equipment = [ + *[item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type == item_tables.TerranItemType.Nova_Gear], + item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE, +] +item_name_groups[ItemGroupNames.NOVA_WEAPONS] = nova_weapons = [ + item_names.NOVA_C20A_CANISTER_RIFLE, + item_names.NOVA_HELLFIRE_SHOTGUN, + item_names.NOVA_PLASMA_RIFLE, + item_names.NOVA_MONOMOLECULAR_BLADE, + item_names.NOVA_BLAZEFIRE_GUNBLADE, +] +item_name_groups[ItemGroupNames.NOVA_GADGETS] = nova_gadgets = [ + item_names.NOVA_STIM_INFUSION, + item_names.NOVA_PULSE_GRENADES, + item_names.NOVA_FLASHBANG_GRENADES, + item_names.NOVA_IONIC_FORCE_FIELD, + item_names.NOVA_HOLO_DECOY, +] +item_name_groups[ItemGroupNames.WOL_UNITS] = wol_units = [ + item_names.MARINE, item_names.MEDIC, item_names.FIREBAT, item_names.MARAUDER, item_names.REAPER, + item_names.HELLION, item_names.VULTURE, item_names.GOLIATH, item_names.DIAMONDBACK, item_names.SIEGE_TANK, + item_names.MEDIVAC, item_names.WRAITH, item_names.VIKING, item_names.BANSHEE, item_names.BATTLECRUISER, + item_names.GHOST, item_names.SPECTRE, item_names.THOR, + item_names.PREDATOR, item_names.HERCULES, + item_names.SCIENCE_VESSEL, item_names.RAVEN, +] +item_name_groups[ItemGroupNames.WOL_MERCS] = wol_mercs = [ + item_names.WAR_PIGS, item_names.DEVIL_DOGS, item_names.HAMMER_SECURITIES, + item_names.SPARTAN_COMPANY, item_names.SIEGE_BREAKERS, + item_names.HELS_ANGELS, item_names.DUSK_WINGS, item_names.JACKSONS_REVENGE, +] +item_name_groups[ItemGroupNames.WOL_BUILDINGS] = wol_buildings = [ + item_names.BUNKER, item_names.MISSILE_TURRET, item_names.SENSOR_TOWER, + item_names.PERDITION_TURRET, item_names.PLANETARY_FORTRESS, + item_names.HIVE_MIND_EMULATOR, item_names.PSI_DISRUPTER, +] +item_name_groups[ItemGroupNames.TERRAN_BUILDINGS] = terran_buildings = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type == item_tables.TerranItemType.Building or item_name in wol_buildings +] +item_name_groups[ItemGroupNames.MENGSK_UNITS] = [ + item_names.AEGIS_GUARD, item_names.EMPERORS_SHADOW, + item_names.SHOCK_DIVISION, item_names.BLACKHAMMER, + item_names.PRIDE_OF_AUGUSTRGRAD, item_names.SKY_FURY, + item_names.DOMINION_TROOPER, +] +item_name_groups[ItemGroupNames.TERRAN_VETERANCY_UNITS] = [ + item_names.AEGIS_GUARD, item_names.EMPERORS_SHADOW, item_names.SHOCK_DIVISION, item_names.BLACKHAMMER, + item_names.PRIDE_OF_AUGUSTRGRAD, item_names.SKY_FURY, item_names.SON_OF_KORHAL, item_names.FIELD_RESPONSE_THETA, + item_names.BULWARK_COMPANY, item_names.NIGHT_HAWK, item_names.EMPERORS_GUARDIAN, item_names.NIGHT_WOLF, +] +item_name_groups[ItemGroupNames.ORBITAL_COMMAND_ABILITIES] = orbital_command_abilities = [ + item_names.COMMAND_CENTER_SCANNER_SWEEP, + item_names.COMMAND_CENTER_MULE, + item_names.COMMAND_CENTER_EXTRA_SUPPLIES, +] +item_name_groups[ItemGroupNames.WOL_ORBITAL_COMMAND_ABILITIES] = wol_orbital_command_abilities = [ + item_names.COMMAND_CENTER_SCANNER_SWEEP, + item_names.COMMAND_CENTER_MULE, +] +spider_mine_sources = [ + item_names.VULTURE, + item_names.REAPER_SPIDER_MINES, + item_names.SIEGE_TANK_SPIDER_MINES, + item_names.RAVEN_SPIDER_MINES, +] + +# Terran Upgrades +item_name_groups[ItemGroupNames.WOL_UPGRADES] = wol_upgrades = [ + # Armory Base + item_names.BUNKER_PROJECTILE_ACCELERATOR, item_names.BUNKER_NEOSTEEL_BUNKER, + item_names.MISSILE_TURRET_TITANIUM_HOUSING, item_names.MISSILE_TURRET_HELLSTORM_BATTERIES, + item_names.SCV_ADVANCED_CONSTRUCTION, item_names.SCV_DUAL_FUSION_WELDERS, + item_names.PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM, item_names.COMMAND_CENTER_MULE, item_names.COMMAND_CENTER_SCANNER_SWEEP, + # Armory Infantry + item_names.MARINE_PROGRESSIVE_STIMPACK, item_names.MARINE_COMBAT_SHIELD, + item_names.MEDIC_ADVANCED_MEDIC_FACILITIES, item_names.MEDIC_STABILIZER_MEDPACKS, + item_names.FIREBAT_INCINERATOR_GAUNTLETS, item_names.FIREBAT_JUGGERNAUT_PLATING, + item_names.MARAUDER_CONCUSSIVE_SHELLS, item_names.MARAUDER_KINETIC_FOAM, + item_names.REAPER_U238_ROUNDS, item_names.REAPER_G4_CLUSTERBOMB, + # Armory Vehicles + item_names.HELLION_TWIN_LINKED_FLAMETHROWER, item_names.HELLION_THERMITE_FILAMENTS, + item_names.SPIDER_MINE_CERBERUS_MINE, item_names.VULTURE_PROGRESSIVE_REPLENISHABLE_MAGAZINE, + item_names.GOLIATH_MULTI_LOCK_WEAPONS_SYSTEM, item_names.GOLIATH_ARES_CLASS_TARGETING_SYSTEM, + item_names.DIAMONDBACK_PROGRESSIVE_TRI_LITHIUM_POWER_CELL, item_names.DIAMONDBACK_SHAPED_HULL, + item_names.SIEGE_TANK_MAELSTROM_ROUNDS, item_names.SIEGE_TANK_SHAPED_BLAST, + # Armory Starships + item_names.MEDIVAC_RAPID_DEPLOYMENT_TUBE, item_names.MEDIVAC_ADVANCED_HEALING_AI, + item_names.WRAITH_PROGRESSIVE_TOMAHAWK_POWER_CELLS, item_names.WRAITH_DISPLACEMENT_FIELD, + item_names.VIKING_RIPWAVE_MISSILES, item_names.VIKING_PHOBOS_CLASS_WEAPONS_SYSTEM, + item_names.BANSHEE_PROGRESSIVE_CROSS_SPECTRUM_DAMPENERS, item_names.BANSHEE_SHOCKWAVE_MISSILE_BATTERY, + item_names.BATTLECRUISER_PROGRESSIVE_MISSILE_PODS, item_names.BATTLECRUISER_PROGRESSIVE_DEFENSIVE_MATRIX, + # Armory Dominion + item_names.GHOST_OCULAR_IMPLANTS, item_names.GHOST_CRIUS_SUIT, + item_names.SPECTRE_PSIONIC_LASH, item_names.SPECTRE_NYX_CLASS_CLOAKING_MODULE, + item_names.THOR_330MM_BARRAGE_CANNON, item_names.THOR_PROGRESSIVE_IMMORTALITY_PROTOCOL, + # Lab Zerg + item_names.BUNKER_FORTIFIED_BUNKER, item_names.BUNKER_SHRIKE_TURRET, + item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL, item_names.CELLULAR_REACTOR, + # Other 3 levels are units/buildings (Perdition, PF, Hercules, Predator, HME, Psi Disrupter) + # Lab Protoss + item_names.VANADIUM_PLATING, item_names.ULTRA_CAPACITORS, + item_names.AUTOMATED_REFINERY, item_names.MICRO_FILTERING, + item_names.ORBITAL_DEPOTS, item_names.COMMAND_CENTER_COMMAND_CENTER_REACTOR, + item_names.ORBITAL_STRIKE, item_names.TECH_REACTOR, + # Other level is units (Raven, Science Vessel) +] +item_name_groups[ItemGroupNames.TERRAN_STIMPACKS] = terran_stimpacks = [ + item_names.MARINE_PROGRESSIVE_STIMPACK, + item_names.MARAUDER_PROGRESSIVE_STIMPACK, + item_names.REAPER_PROGRESSIVE_STIMPACK, + item_names.FIREBAT_PROGRESSIVE_STIMPACK, + item_names.HELLION_PROGRESSIVE_STIMPACK, +] +item_name_groups[ItemGroupNames.TERRAN_ORIGINAL_PROGRESSIVE_UPGRADES] = terran_original_progressive_upgrades = [ + item_names.PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM, + item_names.MARINE_PROGRESSIVE_STIMPACK, + item_names.VULTURE_PROGRESSIVE_REPLENISHABLE_MAGAZINE, + item_names.DIAMONDBACK_PROGRESSIVE_TRI_LITHIUM_POWER_CELL, + item_names.WRAITH_PROGRESSIVE_TOMAHAWK_POWER_CELLS, + item_names.BANSHEE_PROGRESSIVE_CROSS_SPECTRUM_DAMPENERS, + item_names.BATTLECRUISER_PROGRESSIVE_MISSILE_PODS, + item_names.BATTLECRUISER_PROGRESSIVE_DEFENSIVE_MATRIX, + item_names.THOR_PROGRESSIVE_IMMORTALITY_PROTOCOL, + item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL, +] +item_name_groups[ItemGroupNames.NCO_BASELINE_UPGRADES] = nco_baseline_upgrades = [ + item_names.BUNKER_NEOSTEEL_BUNKER, # Baseline from mission 2 + item_names.BUNKER_FORTIFIED_BUNKER, # Baseline from mission 2 + item_names.MARINE_COMBAT_SHIELD, # Baseline from mission 2 + item_names.MARAUDER_KINETIC_FOAM, # Baseline outside WOL + item_names.MARAUDER_CONCUSSIVE_SHELLS, # Baseline from mission 2 + item_names.REAPER_BALLISTIC_FLIGHTSUIT, # Baseline from mission 2 + item_names.HELLION_HELLBAT, # Baseline from mission 3 + item_names.GOLIATH_INTERNAL_TECH_MODULE, # Baseline from mission 4 + item_names.GOLIATH_SHAPED_HULL, + # ItemNames.GOLIATH_RESOURCE_EFFICIENCY, # Supply savings baseline in NCO, mineral savings is non-NCO + item_names.SIEGE_TANK_SHAPED_HULL, # Baseline NCO gives +10; this upgrade gives +25 + item_names.SIEGE_TANK_SHAPED_BLAST, # Baseline from mission 3 + item_names.LIBERATOR_RAID_ARTILLERY, # Baseline in mission 5 + item_names.RAVEN_BIO_MECHANICAL_REPAIR_DRONE, # Baseline in mission 5 + item_names.BATTLECRUISER_TACTICAL_JUMP, + item_names.BATTLECRUISER_MOIRAI_IMPULSE_DRIVE, + item_names.PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM, # Baseline from mission 2 + item_names.ORBITAL_DEPOTS, # Baseline from mission 2 + item_names.COMMAND_CENTER_SCANNER_SWEEP, # In NCO you must actually morph Command Center into Orbital Command + item_names.COMMAND_CENTER_EXTRA_SUPPLIES, # But in AP this works WoL-style +] + nco_buildings +item_name_groups[ItemGroupNames.NCO_UNIT_TECHNOLOGY] = nco_unit_technology = [ + item_names.MARINE_LASER_TARGETING_SYSTEM, + item_names.MARINE_PROGRESSIVE_STIMPACK, + item_names.MARINE_MAGRAIL_MUNITIONS, + item_names.MARINE_OPTIMIZED_LOGISTICS, + item_names.MARAUDER_LASER_TARGETING_SYSTEM, + item_names.MARAUDER_INTERNAL_TECH_MODULE, + item_names.MARAUDER_PROGRESSIVE_STIMPACK, + item_names.MARAUDER_MAGRAIL_MUNITIONS, + item_names.REAPER_SPIDER_MINES, + item_names.REAPER_LASER_TARGETING_SYSTEM, + item_names.REAPER_PROGRESSIVE_STIMPACK, + item_names.REAPER_ADVANCED_CLOAKING_FIELD, + # Reaper special ordnance gives anti-building attack, which is baseline in AP + item_names.HELLION_JUMP_JETS, + item_names.HELLION_PROGRESSIVE_STIMPACK, + item_names.HELLION_SMART_SERVOS, + item_names.HELLION_OPTIMIZED_LOGISTICS, + item_names.HELLION_THERMITE_FILAMENTS, # Called Infernal Pre-Igniter in NCO + item_names.GOLIATH_ARES_CLASS_TARGETING_SYSTEM, # Called Laser Targeting System in NCO + item_names.GOLIATH_JUMP_JETS, + item_names.GOLIATH_OPTIMIZED_LOGISTICS, + item_names.GOLIATH_MULTI_LOCK_WEAPONS_SYSTEM, + item_names.SIEGE_TANK_SPIDER_MINES, + item_names.SIEGE_TANK_JUMP_JETS, + item_names.SIEGE_TANK_INTERNAL_TECH_MODULE, + item_names.SIEGE_TANK_SMART_SERVOS, + # Tanks can't get Laser targeting system in NCO + item_names.BANSHEE_INTERNAL_TECH_MODULE, + item_names.BANSHEE_PROGRESSIVE_CROSS_SPECTRUM_DAMPENERS, + item_names.BANSHEE_SHOCKWAVE_MISSILE_BATTERY, # Banshee Special Ordnance + # Banshees can't get laser targeting systems in NCO + item_names.LIBERATOR_CLOAK, + item_names.LIBERATOR_SMART_SERVOS, + item_names.LIBERATOR_OPTIMIZED_LOGISTICS, + # Liberators can't get laser targeting system in NCO + item_names.RAVEN_SPIDER_MINES, + item_names.RAVEN_INTERNAL_TECH_MODULE, + item_names.RAVEN_RAILGUN_TURRET, # Raven Magrail Munitions + item_names.RAVEN_HUNTER_SEEKER_WEAPON, # Raven Special Ordnance + item_names.BATTLECRUISER_INTERNAL_TECH_MODULE, + item_names.BATTLECRUISER_CLOAK, + item_names.BATTLECRUISER_ATX_LASER_BATTERY, # Battlecruiser Special Ordnance + item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL, +] +item_name_groups[ItemGroupNames.NCO_UPGRADES] = nco_upgrades = nco_baseline_upgrades + nco_unit_technology +item_name_groups[ItemGroupNames.NCO_MAX_PROGRESSIVE_ITEMS] = nco_unit_technology + nova_equipment + terran_generic_upgrades +item_name_groups[ItemGroupNames.NCO_MIN_PROGRESSIVE_ITEMS] = nco_units + nco_baseline_upgrades +item_name_groups[ItemGroupNames.TERRAN_PROGRESSIVE_UPGRADES] = terran_progressive_items = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type in (item_tables.TerranItemType.Progressive, item_tables.TerranItemType.Progressive_2) +] +item_name_groups[ItemGroupNames.WOL_ITEMS] = vanilla_wol_items = ( + wol_units + + wol_buildings + + wol_mercs + + wol_upgrades + + orbital_command_abilities + + terran_generic_upgrades +) + +# Zerg +item_name_groups[ItemGroupNames.ZERG_ITEMS] = zerg_items = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.race == SC2Race.ZERG +] +item_name_groups[ItemGroupNames.ZERG_BUILDINGS] = zerg_buildings = [ + item_names.SPINE_CRAWLER, + item_names.SPORE_CRAWLER, + item_names.BILE_LAUNCHER, + item_names.INFESTED_BUNKER, + item_names.INFESTED_MISSILE_TURRET, + item_names.NYDUS_WORM, + item_names.ECHIDNA_WORM] +item_name_groups[ItemGroupNames.ZERG_NONMORPH_UNITS] = zerg_nonmorph_units = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type in ( + item_tables.ZergItemType.Unit, item_tables.ZergItemType.Mercenary + ) + and item_name not in zerg_buildings +] +item_name_groups[ItemGroupNames.ZERG_MORPHS] = zerg_morphs = [ + item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ZergItemType.Morph +] +item_name_groups[ItemGroupNames.ZERG_UNITS] = zerg_units = zerg_nonmorph_units + zerg_morphs +# For W/A upgrades +zerg_ground_units = [ + item_names.ZERGLING, item_names.SWARM_QUEEN, item_names.ROACH, item_names.HYDRALISK, item_names.ABERRATION, + item_names.SWARM_HOST, item_names.INFESTOR, item_names.ULTRALISK, item_names.ZERGLING_BANELING_ASPECT, + item_names.HYDRALISK_LURKER_ASPECT, item_names.HYDRALISK_IMPALER_ASPECT, item_names.ULTRALISK_TYRANNOZOR_ASPECT, + item_names.ROACH_RAVAGER_ASPECT, item_names.DEFILER, item_names.ROACH_PRIMAL_IGNITER_ASPECT, + item_names.PYGALISK, + item_names.INFESTED_MARINE, item_names.INFESTED_BUNKER, item_names.INFESTED_DIAMONDBACK, + item_names.INFESTED_SIEGE_TANK, +] +zerg_melee_wa = [ + item_names.ZERGLING, item_names.ABERRATION, item_names.ULTRALISK, item_names.ZERGLING_BANELING_ASPECT, + item_names.ULTRALISK_TYRANNOZOR_ASPECT, item_names.INFESTED_BUNKER, item_names.PYGALISK, +] +zerg_ranged_wa = [ + item_names.SWARM_QUEEN, item_names.ROACH, item_names.HYDRALISK, item_names.SWARM_HOST, + item_names.HYDRALISK_LURKER_ASPECT, item_names.HYDRALISK_IMPALER_ASPECT, item_names.ULTRALISK_TYRANNOZOR_ASPECT, + item_names.ROACH_RAVAGER_ASPECT, item_names.ROACH_PRIMAL_IGNITER_ASPECT, item_names.INFESTED_MARINE, + item_names.INFESTED_BUNKER, item_names.INFESTED_DIAMONDBACK, item_names.INFESTED_SIEGE_TANK, +] +zerg_air_units = [ + item_names.MUTALISK, item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT, item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT, + item_names.CORRUPTOR, item_names.BROOD_QUEEN, item_names.SCOURGE, item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT, + item_names.MUTALISK_CORRUPTOR_DEVOURER_ASPECT, item_names.INFESTED_BANSHEE, item_names.INFESTED_LIBERATOR, +] +item_name_groups[ItemGroupNames.ZERG_GENERIC_UPGRADES] = zerg_generic_upgrades = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type == item_tables.ZergItemType.Upgrade +] +item_name_groups[ItemGroupNames.HOTS_UNITS] = hots_units = [ + item_names.ZERGLING, item_names.SWARM_QUEEN, item_names.ROACH, item_names.HYDRALISK, + item_names.ABERRATION, item_names.SWARM_HOST, item_names.MUTALISK, + item_names.INFESTOR, item_names.ULTRALISK, + item_names.ZERGLING_BANELING_ASPECT, + item_names.HYDRALISK_LURKER_ASPECT, + item_names.HYDRALISK_IMPALER_ASPECT, + item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT, + item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT, +] +item_name_groups[ItemGroupNames.HOTS_BUILDINGS] = hots_buildings = [ + item_names.SPINE_CRAWLER, + item_names.SPORE_CRAWLER, +] +item_name_groups[ItemGroupNames.HOTS_MORPHS] = hots_morphs = [ + item_names.ZERGLING_BANELING_ASPECT, + item_names.HYDRALISK_IMPALER_ASPECT, + item_names.HYDRALISK_LURKER_ASPECT, + item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT, + item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT, +] +item_name_groups[ItemGroupNames.ZERG_MERCENARIES] = zerg_mercenaries = [ + item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ZergItemType.Mercenary +] +item_name_groups[ItemGroupNames.KERRIGAN_ABILITIES] = kerrigan_abilities = [ + item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ZergItemType.Ability +] +item_name_groups[ItemGroupNames.KERRIGAN_PASSIVES] = kerrigan_passives = [ + item_names.KERRIGAN_HEROIC_FORTITUDE, item_names.KERRIGAN_CHAIN_REACTION, + item_names.KERRIGAN_INFEST_BROODLINGS, item_names.KERRIGAN_FURY, item_names.KERRIGAN_ABILITY_EFFICIENCY, +] +item_name_groups[ItemGroupNames.KERRIGAN_ACTIVE_ABILITIES] = kerrigan_active_abilities = [ + item_name for item_name in kerrigan_abilities if item_name not in kerrigan_passives +] +item_name_groups[ItemGroupNames.KERRIGAN_LOGIC_ACTIVE_ABILITIES] = kerrigan_logic_active_abilities = [ + item_name for item_name in kerrigan_active_abilities if item_name != item_names.KERRIGAN_ASSIMILATION_AURA +] +item_name_groups[ItemGroupNames.KERRIGAN_TIER_1] = kerrigan_tier_1 = [ + item_names.KERRIGAN_CRUSHING_GRIP, item_names.KERRIGAN_HEROIC_FORTITUDE, item_names.KERRIGAN_LEAPING_STRIKE +] +item_name_groups[ItemGroupNames.KERRIGAN_TIER_2] = kerrigan_tier_2= [ + item_names.KERRIGAN_CRUSHING_GRIP, item_names.KERRIGAN_CHAIN_REACTION, item_names.KERRIGAN_PSIONIC_SHIFT +] +item_name_groups[ItemGroupNames.KERRIGAN_TIER_3] = kerrigan_tier_3 = [ + item_names.TWIN_DRONES, item_names.AUTOMATED_EXTRACTORS, item_names.ZERGLING_RECONSTITUTION +] +item_name_groups[ItemGroupNames.KERRIGAN_TIER_4] = kerrigan_tier_4 = [ + item_names.KERRIGAN_MEND, item_names.KERRIGAN_SPAWN_BANELINGS, item_names.KERRIGAN_WILD_MUTATION +] +item_name_groups[ItemGroupNames.KERRIGAN_TIER_5] = kerrigan_tier_5 = [ + item_names.MALIGNANT_CREEP, item_names.VESPENE_EFFICIENCY, item_names.OVERLORD_IMPROVED_OVERLORDS +] +item_name_groups[ItemGroupNames.KERRIGAN_TIER_6] = kerrigan_tier_6 = [ + item_names.KERRIGAN_INFEST_BROODLINGS, item_names.KERRIGAN_FURY, item_names.KERRIGAN_ABILITY_EFFICIENCY +] +item_name_groups[ItemGroupNames.KERRIGAN_TIER_7] = kerrigan_tier_7 = [ + item_names.KERRIGAN_APOCALYPSE, item_names.KERRIGAN_SPAWN_LEVIATHAN, item_names.KERRIGAN_DROP_PODS +] +item_name_groups[ItemGroupNames.KERRIGAN_ULTIMATES] = kerrigan_ultimates = [ + *kerrigan_tier_7, item_names.KERRIGAN_ASSIMILATION_AURA, item_names.KERRIGAN_IMMOBILIZATION_WAVE +] +item_name_groups[ItemGroupNames.KERRIGAN_NON_ULTIMATES] = kerrigan_non_ulimates = [ + item for item in kerrigan_abilities if item not in kerrigan_ultimates +] +item_name_groups[ItemGroupNames.KERRIGAN_LOGIC_ULTIMATES] = kerrigan_logic_ultimates = [ + item for item in kerrigan_ultimates if item != item_names.KERRIGAN_ASSIMILATION_AURA +] +item_name_groups[ItemGroupNames.KERRIGAN_NON_ULTIMATE_ACTIVE_ABILITIES] = kerrigan_non_ulimate_active_abilities = [ + item for item in kerrigan_non_ulimates if item in kerrigan_active_abilities +] +item_name_groups[ItemGroupNames.KERRIGAN_HOTS_ABILITIES] = kerrigan_hots_abilities = [ + ability for tiers in [ + kerrigan_tier_1, kerrigan_tier_2, kerrigan_tier_4, kerrigan_tier_6, kerrigan_tier_7 + ] for ability in tiers +] + +item_name_groups[ItemGroupNames.OVERLORD_UPGRADES] = [ + item_names.OVERLORD_ANTENNAE, + item_names.OVERLORD_VENTRAL_SACS, + item_names.OVERLORD_GENERATE_CREEP, + item_names.OVERLORD_PNEUMATIZED_CARAPACE, + item_names.OVERLORD_IMPROVED_OVERLORDS, + item_names.OVERLORD_OVERSEER_ASPECT, +] + +# Zerg Upgrades +item_name_groups[ItemGroupNames.HOTS_STRAINS] = hots_strains = [ + item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ZergItemType.Strain +] +item_name_groups[ItemGroupNames.HOTS_MUTATIONS] = hots_mutations = [ + item_names.ZERGLING_HARDENED_CARAPACE, item_names.ZERGLING_ADRENAL_OVERLOAD, item_names.ZERGLING_METABOLIC_BOOST, + item_names.BANELING_CORROSIVE_ACID, item_names.BANELING_RUPTURE, item_names.BANELING_REGENERATIVE_ACID, + item_names.ROACH_HYDRIODIC_BILE, item_names.ROACH_ADAPTIVE_PLATING, item_names.ROACH_TUNNELING_CLAWS, + item_names.HYDRALISK_FRENZY, item_names.HYDRALISK_ANCILLARY_CARAPACE, item_names.HYDRALISK_GROOVED_SPINES, + item_names.SWARM_HOST_BURROW, item_names.SWARM_HOST_RAPID_INCUBATION, item_names.SWARM_HOST_PRESSURIZED_GLANDS, + item_names.MUTALISK_VICIOUS_GLAIVE, item_names.MUTALISK_RAPID_REGENERATION, item_names.MUTALISK_SUNDERING_GLAIVE, + item_names.ULTRALISK_BURROW_CHARGE, item_names.ULTRALISK_TISSUE_ASSIMILATION, item_names.ULTRALISK_MONARCH_BLADES, +] +item_name_groups[ItemGroupNames.HOTS_GLOBAL_UPGRADES] = hots_global_upgrades = [ + item_names.ZERGLING_RECONSTITUTION, + item_names.OVERLORD_IMPROVED_OVERLORDS, + item_names.AUTOMATED_EXTRACTORS, + item_names.TWIN_DRONES, + item_names.MALIGNANT_CREEP, + item_names.VESPENE_EFFICIENCY, +] +item_name_groups[ItemGroupNames.HOTS_ITEMS] = vanilla_hots_items = ( + hots_units + + hots_buildings + + kerrigan_hots_abilities + + hots_mutations + + hots_strains + + hots_global_upgrades + + zerg_generic_upgrades +) + +# Zerg - Infested Terran (Stukov Co-op) +item_name_groups[ItemGroupNames.INF_TERRAN_UNITS] = infterr_units = [ + item_names.INFESTED_MARINE, + item_names.INFESTED_BUNKER, + item_names.BULLFROG, + item_names.INFESTED_DIAMONDBACK, + item_names.INFESTED_SIEGE_TANK, + item_names.INFESTED_LIBERATOR, + item_names.INFESTED_BANSHEE, +] +item_name_groups[ItemGroupNames.INF_TERRAN_UPGRADES] = infterr_upgrades = [ + item_names.INFESTED_SCV_BUILD_CHARGES, + item_names.INFESTED_MARINE_PLAGUED_MUNITIONS, + item_names.INFESTED_MARINE_RETINAL_AUGMENTATION, + item_names.INFESTED_BUNKER_CALCIFIED_ARMOR, + item_names.INFESTED_BUNKER_REGENERATIVE_PLATING, + item_names.INFESTED_BUNKER_ENGORGED_BUNKERS, + item_names.BULLFROG_WILD_MUTATION, + item_names.BULLFROG_BROODLINGS, + item_names.BULLFROG_HARD_IMPACT, + item_names.BULLFROG_RANGE, + item_names.INFESTED_DIAMONDBACK_CAUSTIC_MUCUS, + item_names.INFESTED_DIAMONDBACK_CONCENTRATED_SPEW, + item_names.INFESTED_DIAMONDBACK_PROGRESSIVE_FUNGAL_SNARE, + item_names.INFESTED_DIAMONDBACK_VIOLENT_ENZYMES, + item_names.INFESTED_SIEGE_TANK_ACIDIC_ENZYMES, + item_names.INFESTED_SIEGE_TANK_BALANCED_ROOTS, + item_names.INFESTED_SIEGE_TANK_DEEP_TUNNEL, + item_names.INFESTED_SIEGE_TANK_PROGRESSIVE_AUTOMATED_MITOSIS, + item_names.INFESTED_SIEGE_TANK_SEISMIC_SONAR, + item_names.INFESTED_LIBERATOR_CLOUD_DISPERSAL, + item_names.INFESTED_LIBERATOR_DEFENDER_MODE, + item_names.INFESTED_LIBERATOR_VIRAL_CONTAMINATION, + item_names.INFESTED_BANSHEE_FLESHFUSED_TARGETING_OPTICS, + item_names.INFESTED_BANSHEE_BRACED_EXOSKELETON, + item_names.INFESTED_BANSHEE_RAPID_HIBERNATION, + item_names.INFESTED_DIAMONDBACK_FRIGHTFUL_FLESHWELDER, + item_names.INFESTED_SIEGE_TANK_FRIGHTFUL_FLESHWELDER, + item_names.INFESTED_LIBERATOR_FRIGHTFUL_FLESHWELDER, + item_names.INFESTED_BANSHEE_FRIGHTFUL_FLESHWELDER, + item_names.INFESTED_MISSILE_TURRET_BIOELECTRIC_PAYLOAD, + item_names.INFESTED_MISSILE_TURRET_ACID_SPORE_VENTS, +] +item_name_groups[ItemGroupNames.INF_TERRAN_ITEMS] = ( + infterr_units + + infterr_upgrades + + [item_names.INFESTED_MISSILE_TURRET] +) + +# Protoss +item_name_groups[ItemGroupNames.PROTOSS_ITEMS] = protoss_items = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.race == SC2Race.PROTOSS +] +item_name_groups[ItemGroupNames.PROTOSS_UNITS] = protoss_units = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type in (item_tables.ProtossItemType.Unit, item_tables.ProtossItemType.Unit_2) +] +protoss_ground_wa = [ + item_names.ZEALOT, item_names.CENTURION, item_names.SENTINEL, item_names.SUPPLICANT, + item_names.SENTRY, item_names.ENERGIZER, + item_names.STALKER, item_names.INSTIGATOR, item_names.SLAYER, item_names.DRAGOON, item_names.ADEPT, + item_names.HIGH_TEMPLAR, item_names.SIGNIFIER, item_names.ASCENDANT, + item_names.DARK_TEMPLAR, item_names.BLOOD_HUNTER, item_names.AVENGER, + item_names.DARK_ARCHON, + item_names.IMMORTAL, item_names.ANNIHILATOR, item_names.VANGUARD, item_names.STALWART, + item_names.COLOSSUS, item_names.WRATHWALKER, + item_names.REAVER, +] +protoss_air_wa = [ + item_names.WARP_PRISM_PHASE_BLASTER, + item_names.PHOENIX, item_names.MIRAGE, item_names.CORSAIR, item_names.SKIRMISHER, + item_names.VOID_RAY, item_names.DESTROYER, item_names.PULSAR, item_names.DAWNBRINGER, + item_names.CARRIER, item_names.SKYLORD, item_names.TRIREME, + item_names.SCOUT, item_names.TEMPEST, item_names.MOTHERSHIP, + item_names.ARBITER, item_names.ORACLE, item_names.OPPRESSOR, + item_names.CALADRIUS, item_names.MISTWING, +] +item_name_groups[ItemGroupNames.PROTOSS_GENERIC_UPGRADES] = protoss_generic_upgrades = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type == item_tables.ProtossItemType.Upgrade +] +item_name_groups[ItemGroupNames.LOTV_UNITS] = lotv_units = [ + item_names.ZEALOT, item_names.CENTURION, item_names.SENTINEL, + item_names.STALKER, item_names.DRAGOON, item_names.ADEPT, + item_names.SENTRY, item_names.HAVOC, item_names.ENERGIZER, + item_names.HIGH_TEMPLAR, item_names.DARK_ARCHON, item_names.ASCENDANT, + item_names.DARK_TEMPLAR, item_names.AVENGER, item_names.BLOOD_HUNTER, + item_names.IMMORTAL, item_names.ANNIHILATOR, item_names.VANGUARD, + item_names.COLOSSUS, item_names.WRATHWALKER, item_names.REAVER, + item_names.PHOENIX, item_names.MIRAGE, item_names.CORSAIR, + item_names.VOID_RAY, item_names.DESTROYER, item_names.ARBITER, + item_names.CARRIER, item_names.TEMPEST, item_names.MOTHERSHIP, +] +item_name_groups[ItemGroupNames.PROPHECY_UNITS] = prophecy_units = [ + item_names.ZEALOT, item_names.STALKER, item_names.HIGH_TEMPLAR, item_names.DARK_TEMPLAR, + item_names.OBSERVER, item_names.COLOSSUS, + item_names.PHOENIX, item_names.VOID_RAY, item_names.CARRIER, +] +item_name_groups[ItemGroupNames.PROPHECY_BUILDINGS] = prophecy_buildings = [ + item_names.PHOTON_CANNON, +] +item_name_groups[ItemGroupNames.GATEWAY_UNITS] = gateway_units = [ + item_names.ZEALOT, item_names.CENTURION, item_names.SENTINEL, item_names.SUPPLICANT, + item_names.STALKER, item_names.INSTIGATOR, item_names.SLAYER, + item_names.SENTRY, item_names.HAVOC, item_names.ENERGIZER, + item_names.DRAGOON, item_names.ADEPT, item_names.DARK_ARCHON, + item_names.HIGH_TEMPLAR, item_names.SIGNIFIER, item_names.ASCENDANT, + item_names.DARK_TEMPLAR, item_names.AVENGER, item_names.BLOOD_HUNTER, +] +item_name_groups[ItemGroupNames.ROBO_UNITS] = robo_units = [ + item_names.WARP_PRISM, item_names.OBSERVER, + item_names.IMMORTAL, item_names.ANNIHILATOR, item_names.VANGUARD, item_names.STALWART, + item_names.COLOSSUS, item_names.WRATHWALKER, + item_names.REAVER, item_names.DISRUPTOR, +] +item_name_groups[ItemGroupNames.STARGATE_UNITS] = stargate_units = [ + item_names.PHOENIX, item_names.SKIRMISHER, item_names.MIRAGE, item_names.CORSAIR, + item_names.VOID_RAY, item_names.DESTROYER, item_names.PULSAR, item_names.DAWNBRINGER, + item_names.CARRIER, item_names.SKYLORD, item_names.TRIREME, + item_names.TEMPEST, item_names.SCOUT, item_names.MOTHERSHIP, + item_names.ARBITER, item_names.ORACLE, item_names.OPPRESSOR, + item_names.CALADRIUS, item_names.MISTWING, +] +item_name_groups[ItemGroupNames.PROTOSS_BUILDINGS] = protoss_buildings = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type == item_tables.ProtossItemType.Building +] +item_name_groups[ItemGroupNames.AIUR_UNITS] = [ + item_names.ZEALOT, item_names.DRAGOON, item_names.SENTRY, item_names.AVENGER, item_names.HIGH_TEMPLAR, + item_names.IMMORTAL, item_names.REAVER, + item_names.PHOENIX, item_names.SCOUT, item_names.ARBITER, item_names.CARRIER, +] +item_name_groups[ItemGroupNames.NERAZIM_UNITS] = [ + item_names.CENTURION, item_names.STALKER, item_names.DARK_TEMPLAR, item_names.SIGNIFIER, item_names.DARK_ARCHON, + item_names.ANNIHILATOR, + item_names.CORSAIR, item_names.ORACLE, item_names.VOID_RAY, item_names.MISTWING, +] +item_name_groups[ItemGroupNames.TAL_DARIM_UNITS] = [ + item_names.SUPPLICANT, item_names.SLAYER, item_names.HAVOC, item_names.BLOOD_HUNTER, item_names.ASCENDANT, + item_names.VANGUARD, item_names.WRATHWALKER, + item_names.SKIRMISHER, item_names.DESTROYER, item_names.SKYLORD, item_names.MOTHERSHIP, item_names.OPPRESSOR, +] +item_name_groups[ItemGroupNames.PURIFIER_UNITS] = [ + item_names.SENTINEL, item_names.ADEPT, item_names.INSTIGATOR, item_names.ENERGIZER, + item_names.STALWART, item_names.COLOSSUS, item_names.DISRUPTOR, + item_names.MIRAGE, item_names.DAWNBRINGER, item_names.TRIREME, item_names.TEMPEST, + item_names.CALADRIUS, +] +item_name_groups[ItemGroupNames.SOA_ITEMS] = soa_items = [ + *[item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ProtossItemType.Spear_Of_Adun], + item_names.SOA_PROGRESSIVE_PROXY_PYLON, +] +lotv_soa_items = [item_name for item_name in soa_items if item_name != item_names.SOA_PYLON_OVERCHARGE] +item_name_groups[ItemGroupNames.PROTOSS_GLOBAL_UPGRADES] = [ + item_name for item_name, item_data in item_tables.item_table.items() if item_data.type == item_tables.ProtossItemType.Solarite_Core +] +item_name_groups[ItemGroupNames.LOTV_GLOBAL_UPGRADES] = lotv_global_upgrades = [ + item_names.NEXUS_OVERCHARGE, + item_names.ORBITAL_ASSIMILATORS, + item_names.WARP_HARMONIZATION, + item_names.MATRIX_OVERLOAD, + item_names.GUARDIAN_SHELL, + item_names.RECONSTRUCTION_BEAM, +] +item_name_groups[ItemGroupNames.WAR_COUNCIL] = war_council_upgrades = [ + item_name for item_name, item_data in item_tables.item_table.items() + if item_data.type in (item_tables.ProtossItemType.War_Council, item_tables.ProtossItemType.War_Council_2) +] + +lotv_war_council_upgrades = [ + item_name for item_name, item_data in item_tables.item_table.items() + if ( + item_name in war_council_upgrades + and item_data.parent in item_name_groups[ItemGroupNames.LOTV_UNITS] + # Destroyers get a custom (non-vanilla) buff, not a nerf over their vanilla council state + and item_name != item_names.DESTROYER_REFORGED_BLOODSHARD_CORE + ) +] +item_name_groups[ItemGroupNames.LOTV_ITEMS] = vanilla_lotv_items = ( + lotv_units + + protoss_buildings + + lotv_soa_items + + lotv_global_upgrades + + protoss_generic_upgrades + + lotv_war_council_upgrades +) + +item_name_groups[ItemGroupNames.VANILLA_ITEMS] = vanilla_items = ( + vanilla_wol_items + vanilla_hots_items + vanilla_lotv_items +) + +item_name_groups[ItemGroupNames.OVERPOWERED_ITEMS] = overpowered_items = [ + # Terran general + item_names.SIEGE_TANK_GRADUATING_RANGE, + item_names.RAVEN_HUNTER_SEEKER_WEAPON, + item_names.BATTLECRUISER_ATX_LASER_BATTERY, + item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL, + item_names.MECHANICAL_KNOW_HOW, + item_names.MERCENARY_MUNITIONS, + + # Terran Mind Control + item_names.HIVE_MIND_EMULATOR, + item_names.PSI_INDOCTRINATOR, + item_names.ARGUS_AMPLIFIER, + + # Zerg Mind Control + item_names.INFESTOR, + + # Protoss Mind Control + item_names.DARK_ARCHON_INDOMITABLE_WILL, + + # Nova + item_names.NOVA_PLASMA_RIFLE, + + # Kerrigan + item_names.KERRIGAN_APOCALYPSE, + item_names.KERRIGAN_DROP_PODS, + item_names.KERRIGAN_SPAWN_LEVIATHAN, + item_names.KERRIGAN_IMMOBILIZATION_WAVE, + + # SOA + item_names.SOA_TIME_STOP, + item_names.SOA_SOLAR_LANCE, + item_names.SOA_DEPLOY_FENIX, + # Note: This is more an issue of having multiple ults at the same time, rather than solar bombardment in particular. + # Can be removed from the list if we get an SOA ult combined cooldown or energy cost on it. + item_names.SOA_SOLAR_BOMBARDMENT, + + # Protoss general + item_names.QUATRO, + item_names.MOTHERSHIP_INTEGRATED_POWER, + item_names.IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING, + + # Mindless Broodwar garbage + item_names.GHOST_BARGAIN_BIN_PRICES, + item_names.SPECTRE_BARGAIN_BIN_PRICES, + item_names.REAVER_BARGAIN_BIN_PRICES, + item_names.SCOUT_SUPPLY_EFFICIENCY, +] + +# Items not aimed to be officially released +# These need further balancing, and they shouldn't generate normally unless explicitly locked +# Added here to not confuse the client +item_name_groups[ItemGroupNames.UNRELEASED_ITEMS] = unreleased_items = [ + item_names.PRIDE_OF_AUGUSTRGRAD, + item_names.SKY_FURY, + item_names.SHOCK_DIVISION, + item_names.BLACKHAMMER, + item_names.AEGIS_GUARD, + item_names.EMPERORS_SHADOW, + item_names.SON_OF_KORHAL, + item_names.BULWARK_COMPANY, + item_names.FIELD_RESPONSE_THETA, + item_names.EMPERORS_GUARDIAN, + item_names.NIGHT_HAWK, + item_names.NIGHT_WOLF, + item_names.EMPERORS_SHADOW_SOVEREIGN_TACTICAL_MISSILES, +] + +# A place for traits that were released before but are to be taken down by default. +# If an item gets split to multiple ones, the original one should be set deprecated instead (see Orbital Command for an example). +# This is a place if you want to nerf or disable by default a previously released trait. +# Currently, it disables only the topmost level of the progressives. +# Don't place here anything that's present in the vanilla campaigns (if it's overpowered, use overpowered items instead) +item_name_groups[ItemGroupNames.LEGACY_ITEMS] = legacy_items = [ + item_names.ASCENDANT_ARCHON_MERGE, +] + +item_name_groups[ItemGroupNames.KEYS] = keys = [ + item_name for item_name in key_item_table.keys() +] diff --git a/worlds/sc2/item/item_names.py b/worlds/sc2/item/item_names.py new file mode 100644 index 000000000000..2fbd64bd3a1e --- /dev/null +++ b/worlds/sc2/item/item_names.py @@ -0,0 +1,957 @@ +""" +A complete collection of Starcraft 2 item names as strings. +Users of this data may make some assumptions about the structure of a name: +* The upgrade for a unit will end with the unit's name in parentheses +* Weapon / armor upgrades may be grouped by a common prefix specified within this file +""" + +# Terran Units +MARINE = "Marine" +MEDIC = "Medic" +FIREBAT = "Firebat" +MARAUDER = "Marauder" +REAPER = "Reaper" +HELLION = "Hellion" +VULTURE = "Vulture" +GOLIATH = "Goliath" +DIAMONDBACK = "Diamondback" +SIEGE_TANK = "Siege Tank" +MEDIVAC = "Medivac" +WRAITH = "Wraith" +VIKING = "Viking" +BANSHEE = "Banshee" +BATTLECRUISER = "Battlecruiser" +GHOST = "Ghost" +SPECTRE = "Spectre" +THOR = "Thor" +RAVEN = "Raven" +SCIENCE_VESSEL = "Science Vessel" +PREDATOR = "Predator" +HERCULES = "Hercules" +# Extended units +LIBERATOR = "Liberator" +VALKYRIE = "Valkyrie" +WIDOW_MINE = "Widow Mine" +CYCLONE = "Cyclone" +HERC = "HERC" +WARHOUND = "Warhound" +DOMINION_TROOPER = "Dominion Trooper" +# Elites +PRIDE_OF_AUGUSTRGRAD = "Pride of Augustgrad" +SKY_FURY = "Sky Fury" +SHOCK_DIVISION = "Shock Division" +BLACKHAMMER = "Blackhammer" +AEGIS_GUARD = "Aegis Guard" +EMPERORS_SHADOW = "Emperor's Shadow" +SON_OF_KORHAL = "Son of Korhal" +BULWARK_COMPANY = "Bulwark Company" +FIELD_RESPONSE_THETA = "Field Response Theta" +EMPERORS_GUARDIAN = "Emperor's Guardian" +NIGHT_HAWK = "Night Hawk" +NIGHT_WOLF = "Night Wolf" + +# Terran Buildings +BUNKER = "Bunker" +MISSILE_TURRET = "Missile Turret" +SENSOR_TOWER = "Sensor Tower" +PLANETARY_FORTRESS = "Planetary Fortress" +PERDITION_TURRET = "Perdition Turret" +# HIVE_MIND_EMULATOR = "Hive Mind Emulator"# moved to Lab / Global upgrades +# PSI_DISRUPTER = "Psi Disrupter" # moved to Lab / Global upgrades +DEVASTATOR_TURRET = "Devastator Turret" + +# Terran Weapon / Armor Upgrades +TERRAN_UPGRADE_PREFIX = "Progressive Terran" +TERRAN_INFANTRY_UPGRADE_PREFIX = f"{TERRAN_UPGRADE_PREFIX} Infantry" +TERRAN_VEHICLE_UPGRADE_PREFIX = f"{TERRAN_UPGRADE_PREFIX} Vehicle" +TERRAN_SHIP_UPGRADE_PREFIX = f"{TERRAN_UPGRADE_PREFIX} Ship" + +PROGRESSIVE_TERRAN_INFANTRY_WEAPON = f"{TERRAN_INFANTRY_UPGRADE_PREFIX} Weapon" +PROGRESSIVE_TERRAN_INFANTRY_ARMOR = f"{TERRAN_INFANTRY_UPGRADE_PREFIX} Armor" +PROGRESSIVE_TERRAN_VEHICLE_WEAPON = f"{TERRAN_VEHICLE_UPGRADE_PREFIX} Weapon" +PROGRESSIVE_TERRAN_VEHICLE_ARMOR = f"{TERRAN_VEHICLE_UPGRADE_PREFIX} Armor" +PROGRESSIVE_TERRAN_SHIP_WEAPON = f"{TERRAN_SHIP_UPGRADE_PREFIX} Weapon" +PROGRESSIVE_TERRAN_SHIP_ARMOR = f"{TERRAN_SHIP_UPGRADE_PREFIX} Armor" +PROGRESSIVE_TERRAN_WEAPON_UPGRADE = f"{TERRAN_UPGRADE_PREFIX} Weapon Upgrade" +PROGRESSIVE_TERRAN_ARMOR_UPGRADE = f"{TERRAN_UPGRADE_PREFIX} Armor Upgrade" +PROGRESSIVE_TERRAN_INFANTRY_UPGRADE = f"{TERRAN_INFANTRY_UPGRADE_PREFIX} Upgrade" +PROGRESSIVE_TERRAN_VEHICLE_UPGRADE = f"{TERRAN_VEHICLE_UPGRADE_PREFIX} Upgrade" +PROGRESSIVE_TERRAN_SHIP_UPGRADE = f"{TERRAN_SHIP_UPGRADE_PREFIX} Upgrade" +PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE = f"{TERRAN_UPGRADE_PREFIX} Weapon/Armor Upgrade" + +# Mercenaries +WAR_PIGS = "War Pigs" +DEVIL_DOGS = "Devil Dogs" +HAMMER_SECURITIES = "Hammer Securities" +SPARTAN_COMPANY = "Spartan Company" +SIEGE_BREAKERS = "Siege Breakers" +HELS_ANGELS = "Hel's Angels" +DUSK_WINGS = "Dusk Wings" +JACKSONS_REVENGE = "Jackson's Revenge" +SKIBIS_ANGELS = "Skibi's Angels" +DEATH_HEADS = "Death Heads" +WINGED_NIGHTMARES = "Winged Nightmares" +MIDNIGHT_RIDERS = "Midnight Riders" +BRYNHILDS = "Brynhilds" +JOTUN = "Jotun" + +# Lab / Global +ULTRA_CAPACITORS = "Ultra-Capacitors (Terran)" +VANADIUM_PLATING = "Vanadium Plating (Terran)" +ORBITAL_DEPOTS = "Orbital Depots (Terran)" +MICRO_FILTERING = "Micro-Filtering (Terran)" +AUTOMATED_REFINERY = "Automated Refinery (Terran)" +COMMAND_CENTER_COMMAND_CENTER_REACTOR = "Command Center Reactor (Command Center)" +COMMAND_CENTER_SCANNER_SWEEP = "Scanner Sweep (Command Center)" +COMMAND_CENTER_MULE = "MULE (Command Center)" +COMMAND_CENTER_EXTRA_SUPPLIES = "Extra Supplies (Command Center)" +TECH_REACTOR = "Tech Reactor (Terran)" +ORBITAL_STRIKE = "Orbital Strike (Barracks)" +CELLULAR_REACTOR = "Cellular Reactor (Terran)" +PROGRESSIVE_REGENERATIVE_BIO_STEEL = "Progressive Regenerative Bio-Steel (Terran)" +PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM = "Progressive Fire-Suppression System (Terran)" +STRUCTURE_ARMOR = "Structure Armor (Terran)" +HI_SEC_AUTO_TRACKING = "Hi-Sec Auto Tracking (Terran)" +ADVANCED_OPTICS = "Advanced Optics (Terran)" +ROGUE_FORCES = "Rogue Forces (Terran)" +MECHANICAL_KNOW_HOW = "Mechanical Know-how (Terran)" +MERCENARY_MUNITIONS = "Mercenary Munitions (Terran)" +PROGRESSIVE_FAST_DELIVERY = "Progressive Fast Delivery (Terran)" +RAPID_REINFORCEMENT = "Rapid Reinforcement (Terran)" +FUSION_CORE_FUSION_REACTOR = "Fusion Reactor (Fusion Core)" +PSI_DISRUPTER = "Psi Disrupter" +PSI_SCREEN = "Psi Screen (Psi Disrupter)" +SONIC_DISRUPTER = "Sonic Disrupter (Psi Disrupter)" +HIVE_MIND_EMULATOR = "Hive Mind Emulator" +PSI_INDOCTRINATOR = "Psi Indoctrinator (Hive Mind Emulator)" +ARGUS_AMPLIFIER = "Argus Amplifier (Hive Mind Emulator)" +SIGNAL_BEACON = "Signal Beacon (Terran)" + +# Terran Unit Upgrades +BANSHEE_HYPERFLIGHT_ROTORS = "Hyperflight Rotors (Banshee)" +BANSHEE_INTERNAL_TECH_MODULE = "Internal Tech Module (Banshee)" +BANSHEE_LASER_TARGETING_SYSTEM = "Laser Targeting System (Banshee)" +BANSHEE_PROGRESSIVE_CROSS_SPECTRUM_DAMPENERS = "Progressive Cross-Spectrum Dampeners (Banshee)" +BANSHEE_SHOCKWAVE_MISSILE_BATTERY = "Shockwave Missile Battery (Banshee)" +BANSHEE_SHAPED_HULL = "Shaped Hull (Banshee)" +BANSHEE_ADVANCED_TARGETING_OPTICS = "Advanced Targeting Optics (Banshee)" +BANSHEE_DISTORTION_BLASTERS = "Distortion Blasters (Banshee)" +BANSHEE_ROCKET_BARRAGE = "Rocket Barrage (Banshee)" +BATTLECRUISER_ATX_LASER_BATTERY = "ATX Laser Battery (Battlecruiser)" +BATTLECRUISER_CLOAK = "Cloak (Battlecruiser)" +BATTLECRUISER_PROGRESSIVE_DEFENSIVE_MATRIX = "Progressive Defensive Matrix (Battlecruiser)" +BATTLECRUISER_INTERNAL_TECH_MODULE = "Internal Tech Module (Battlecruiser)" +BATTLECRUISER_PROGRESSIVE_MISSILE_PODS = "Progressive Missile Pods (Battlecruiser)" +BATTLECRUISER_OPTIMIZED_LOGISTICS = "Optimized Logistics (Battlecruiser)" +BATTLECRUISER_TACTICAL_JUMP = "Tactical Jump (Battlecruiser)" +BATTLECRUISER_BEHEMOTH_PLATING = "Behemoth Plating (Battlecruiser)" +BATTLECRUISER_MOIRAI_IMPULSE_DRIVE = "Moirai Impulse Drive (Battlecruiser)" +BATTLECRUISER_BEHEMOTH_REACTOR = "Behemoth Reactor (Battlecruiser)" +BATTLECRUISER_FIELD_ASSIST_TARGETING_SYSTEM = "Field-Assist Target System (Battlecruiser)" +CYCLONE_MAG_FIELD_ACCELERATORS = "Mag-Field Accelerators (Cyclone)" +CYCLONE_MAG_FIELD_LAUNCHERS = "Mag-Field Launchers (Cyclone)" +CYCLONE_RAPID_FIRE_LAUNCHERS = "Rapid Fire Launchers (Cyclone)" +CYCLONE_TARGETING_OPTICS = "Targeting Optics (Cyclone)" +CYCLONE_RESOURCE_EFFICIENCY = "Resource Efficiency (Cyclone)" +CYCLONE_INTERNAL_TECH_MODULE = "Internal Tech Module (Cyclone)" +DIAMONDBACK_BURST_CAPACITORS = "Burst Capacitors (Diamondback)" +DIAMONDBACK_HYPERFLUXOR = "Hyperfluxor (Diamondback)" +DIAMONDBACK_RESOURCE_EFFICIENCY = "Resource Efficiency (Diamondback)" +DIAMONDBACK_SHAPED_HULL = "Shaped Hull (Diamondback)" +DIAMONDBACK_PROGRESSIVE_TRI_LITHIUM_POWER_CELL = "Progressive Tri-Lithium Power Cell (Diamondback)" +DIAMONDBACK_MAGLEV_PROPULSION = "Maglev Propulsion (Diamondback)" +DOMINION_TROOPER_B2_HIGH_CAL_LMG = "B-2 High-Cal LMG (Dominion Trooper)" +DOMINION_TROOPER_CPO7_SALAMANDER_FLAMETHROWER = "CPO-7 Salamander Flamethrower (Dominion Trooper)" +DOMINION_TROOPER_HAILSTORM_LAUNCHER = "Hailstorm Launcher (Dominion Trooper)" +DOMINION_TROOPER_ADVANCED_ALLOYS = "Advanced Alloys (Dominion Trooper)" +DOMINION_TROOPER_OPTIMIZED_LOGISTICS = "Optimized Logistics (Dominion Trooper)" +EMPERORS_SHADOW_SOVEREIGN_TACTICAL_MISSILES = "Sovereign Tactical Missiles (Emperor's Shadow)" +FIREBAT_INCINERATOR_GAUNTLETS = "Incinerator Gauntlets (Firebat)" +FIREBAT_JUGGERNAUT_PLATING = "Juggernaut Plating (Firebat)" +FIREBAT_RESOURCE_EFFICIENCY = "Resource Efficiency (Firebat)" +FIREBAT_PROGRESSIVE_STIMPACK = "Progressive Stimpack (Firebat)" +FIREBAT_INFERNAL_PRE_IGNITER = "Infernal Pre-Igniter (Firebat)" +FIREBAT_KINETIC_FOAM = "Kinetic Foam (Firebat)" +FIREBAT_NANO_PROJECTORS = "Nano Projectors (Firebat)" +GHOST_CRIUS_SUIT = "Crius Suit (Ghost)" +GHOST_EMP_ROUNDS = "EMP Rounds (Ghost)" +GHOST_LOCKDOWN = "Lockdown (Ghost)" +GHOST_OCULAR_IMPLANTS = "Ocular Implants (Ghost)" +GHOST_RESOURCE_EFFICIENCY = "Resource Efficiency (Ghost)" +GHOST_BARGAIN_BIN_PRICES = "Bargain Bin Prices (Ghost)" +GOLIATH_ARES_CLASS_TARGETING_SYSTEM = "Ares-Class Targeting System (Goliath)" +GOLIATH_JUMP_JETS = "Jump Jets (Goliath)" +GOLIATH_MULTI_LOCK_WEAPONS_SYSTEM = "Multi-Lock Weapons System (Goliath)" +GOLIATH_OPTIMIZED_LOGISTICS = "Optimized Logistics (Goliath)" +GOLIATH_SHAPED_HULL = "Shaped Hull (Goliath)" +GOLIATH_RESOURCE_EFFICIENCY = "Resource Efficiency (Goliath)" +GOLIATH_INTERNAL_TECH_MODULE = "Internal Tech Module (Goliath)" +HELLION_HELLBAT = "Hellbat (Hellion Morph)" +HELLION_JUMP_JETS = "Jump Jets (Hellion)" +HELLION_OPTIMIZED_LOGISTICS = "Optimized Logistics (Hellion)" +HELLION_PROGRESSIVE_STIMPACK = "Progressive Stimpack (Hellion)" +HELLION_SMART_SERVOS = "Smart Servos (Hellion)" +HELLION_THERMITE_FILAMENTS = "Thermite Filaments (Hellion)" +HELLION_TWIN_LINKED_FLAMETHROWER = "Twin-Linked Flamethrower (Hellion)" +HELLION_INFERNAL_PLATING = "Infernal Plating (Hellion)" +HERC_JUGGERNAUT_PLATING = "Juggernaut Plating (HERC)" +HERC_KINETIC_FOAM = "Kinetic Foam (HERC)" +HERC_RESOURCE_EFFICIENCY = "Resource Efficiency (HERC)" +HERC_GRAPPLE_PULL = "Grapple Pull (HERC)" +HERCULES_INTERNAL_FUSION_MODULE = "Internal Fusion Module (Hercules)" +HERCULES_TACTICAL_JUMP = "Tactical Jump (Hercules)" +LIBERATOR_ADVANCED_BALLISTICS = "Advanced Ballistics (Liberator)" +LIBERATOR_CLOAK = "Cloak (Liberator)" +LIBERATOR_LASER_TARGETING_SYSTEM = "Laser Targeting System (Liberator)" +LIBERATOR_OPTIMIZED_LOGISTICS = "Optimized Logistics (Liberator)" +LIBERATOR_RAID_ARTILLERY = "Raid Artillery (Liberator)" +LIBERATOR_SMART_SERVOS = "Smart Servos (Liberator)" +LIBERATOR_RESOURCE_EFFICIENCY = "Resource Efficiency (Liberator)" +LIBERATOR_GUERILLA_MISSILES = "Guerilla Missiles (Liberator)" +LIBERATOR_UED_MISSILE_TECHNOLOGY = "UED Missile Technology (Liberator)" +MARAUDER_CONCUSSIVE_SHELLS = "Concussive Shells (Marauder)" +MARAUDER_INTERNAL_TECH_MODULE = "Internal Tech Module (Marauder)" +MARAUDER_KINETIC_FOAM = "Kinetic Foam (Marauder)" +MARAUDER_LASER_TARGETING_SYSTEM = "Laser Targeting System (Marauder)" +MARAUDER_MAGRAIL_MUNITIONS = "Magrail Munitions (Marauder)" +MARAUDER_PROGRESSIVE_STIMPACK = "Progressive Stimpack (Marauder)" +MARAUDER_JUGGERNAUT_PLATING = "Juggernaut Plating (Marauder)" +MARINE_COMBAT_SHIELD = "Combat Shield (Marine)" +MARINE_LASER_TARGETING_SYSTEM = "Laser Targeting System (Marine)" +MARINE_MAGRAIL_MUNITIONS = "Magrail Munitions (Marine)" +MARINE_OPTIMIZED_LOGISTICS = "Optimized Logistics (Marine)" +MARINE_PROGRESSIVE_STIMPACK = "Progressive Stimpack (Marine)" +MEDIC_ADVANCED_MEDIC_FACILITIES = "Advanced Medic Facilities (Medic)" +MEDIC_OPTICAL_FLARE = "Optical Flare (Medic)" +MEDIC_RESOURCE_EFFICIENCY = "Resource Efficiency (Medic)" +MEDIC_RESTORATION = "Restoration (Medic)" +MEDIC_STABILIZER_MEDPACKS = "Stabilizer Medpacks (Medic)" +MEDIC_ADAPTIVE_MEDPACKS = "Adaptive Medpacks (Medic)" +MEDIC_NANO_PROJECTOR = "Nano Projector (Medic)" +MEDIVAC_ADVANCED_HEALING_AI = "Advanced Healing AI (Medivac)" +MEDIVAC_AFTERBURNERS = "Afterburners (Medivac)" +MEDIVAC_EXPANDED_HULL = "Expanded Hull (Medivac)" +MEDIVAC_RAPID_DEPLOYMENT_TUBE = "Rapid Deployment Tube (Medivac)" +MEDIVAC_SCATTER_VEIL = "Scatter Veil (Medivac)" +MEDIVAC_ADVANCED_CLOAKING_FIELD = "Advanced Cloaking Field (Medivac)" +MEDIVAC_RAPID_REIGNITION_SYSTEMS = "Rapid Reignition Systems (Medivac)" +MEDIVAC_RESOURCE_EFFICIENCY = "Resource Efficiency (Medivac)" +PREDATOR_RESOURCE_EFFICIENCY = "Resource Efficiency (Predator)" +PREDATOR_CLOAK = "Phase Cloak (Predator)" +PREDATOR_CHARGE = "Concussive Charge (Predator)" +PREDATOR_VESPENE_SYNTHESIS = "Vespene Synthesis (Predator)" +PREDATOR_ADAPTIVE_DEFENSES = "Adaptive Defenses (Predator)" +RAVEN_ANTI_ARMOR_MISSILE = "Anti-Armor Missile (Raven)" +RAVEN_BIO_MECHANICAL_REPAIR_DRONE = "Bio Mechanical Repair Drone (Raven)" +RAVEN_HUNTER_SEEKER_WEAPON = "Hunter-Seeker Weapon (Raven)" +RAVEN_INTERFERENCE_MATRIX = "Interference Matrix (Raven)" +RAVEN_INTERNAL_TECH_MODULE = "Internal Tech Module (Raven)" +RAVEN_RAILGUN_TURRET = "Railgun Turret (Raven)" +RAVEN_SPIDER_MINES = "Spider Mines (Raven)" +RAVEN_RESOURCE_EFFICIENCY = "Resource Efficiency (Raven)" +RAVEN_DURABLE_MATERIALS = "Durable Materials (Raven)" +REAPER_ADVANCED_CLOAKING_FIELD = "Advanced Cloaking Field (Reaper)" +REAPER_COMBAT_DRUGS = "Combat Drugs (Reaper)" +REAPER_G4_CLUSTERBOMB = "G-4 Clusterbomb (Reaper)" +REAPER_LASER_TARGETING_SYSTEM = "Laser Targeting System (Reaper)" +REAPER_PROGRESSIVE_STIMPACK = "Progressive Stimpack (Reaper)" +REAPER_SPIDER_MINES = "Spider Mines (Reaper)" +REAPER_U238_ROUNDS = "U-238 Rounds (Reaper)" +REAPER_JET_PACK_OVERDRIVE = "Jet Pack Overdrive (Reaper)" +REAPER_RESOURCE_EFFICIENCY = "Resource Efficiency (Reaper)" +REAPER_BALLISTIC_FLIGHTSUIT = "Ballistic Flightsuit (Reaper)" +SCIENCE_VESSEL_DEFENSIVE_MATRIX = "Defensive Matrix (Science Vessel)" +SCIENCE_VESSEL_EMP_SHOCKWAVE = "EMP Shockwave (Science Vessel)" +SCIENCE_VESSEL_IMPROVED_NANO_REPAIR = "Improved Nano-Repair (Science Vessel)" +SCIENCE_VESSEL_MAGELLAN_COMPUTATION_SYSTEMS = "Magellan Computation Systems (Science Vessel)" +SCIENCE_VESSEL_TACTICAL_JUMP = "Tactical Jump (Science Vessel)" +SCV_ADVANCED_CONSTRUCTION = "Advanced Construction (SCV)" +SCV_DUAL_FUSION_WELDERS = "Dual-Fusion Welders (SCV)" +SCV_HOSTILE_ENVIRONMENT_ADAPTATION = "Hostile Environment Adaptation (SCV)" +SCV_CONSTRUCTION_JUMP_JETS = "Construction Jump Jets (SCV)" +SIEGE_TANK_ADVANCED_SIEGE_TECH = "Advanced Siege Tech (Siege Tank)" +SIEGE_TANK_GRADUATING_RANGE = "Graduating Range (Siege Tank)" +SIEGE_TANK_INTERNAL_TECH_MODULE = "Internal Tech Module (Siege Tank)" +SIEGE_TANK_JUMP_JETS = "Jump Jets (Siege Tank)" +SIEGE_TANK_LASER_TARGETING_SYSTEM = "Laser Targeting System (Siege Tank)" +SIEGE_TANK_MAELSTROM_ROUNDS = "Maelstrom Rounds (Siege Tank)" +SIEGE_TANK_SHAPED_BLAST = "Shaped Blast (Siege Tank)" +SIEGE_TANK_SMART_SERVOS = "Smart Servos (Siege Tank)" +SIEGE_TANK_SPIDER_MINES = "Spider Mines (Siege Tank)" +SIEGE_TANK_SHAPED_HULL = "Shaped Hull (Siege Tank)" +SIEGE_TANK_RESOURCE_EFFICIENCY = "Resource Efficiency (Siege Tank)" +SIEGE_TANK_PROGRESSIVE_TRANSPORT_HOOK = "Progressive Transport Hook (Siege Tank)" +SIEGE_TANK_ALLTERRAIN_TREADS = "All-Terrain Treads (Siege Tank)" +SPECTRE_IMPALER_ROUNDS = "Impaler Rounds (Spectre)" +SPECTRE_NYX_CLASS_CLOAKING_MODULE = "Nyx-Class Cloaking Module (Spectre)" +SPECTRE_PSIONIC_LASH = "Psionic Lash (Spectre)" +SPECTRE_RESOURCE_EFFICIENCY = "Resource Efficiency (Spectre)" +SPECTRE_BARGAIN_BIN_PRICES = "Bargain Bin Prices (Spectre)" +SPIDER_MINE_CERBERUS_MINE = "Cerberus Mine (Spider Mine)" +SPIDER_MINE_HIGH_EXPLOSIVE_MUNITION = "High Explosive Munition (Spider Mine)" +THOR_330MM_BARRAGE_CANNON = "330mm Barrage Cannon (Thor)" +THOR_PROGRESSIVE_IMMORTALITY_PROTOCOL = "Progressive Immortality Protocol (Thor)" +THOR_PROGRESSIVE_HIGH_IMPACT_PAYLOAD = "Progressive High Impact Payload (Thor)" +THOR_BUTTON_WITH_A_SKULL_ON_IT = "Button With a Skull on It (Thor)" +THOR_LASER_TARGETING_SYSTEM = "Laser Targeting System (Thor)" +THOR_LARGE_SCALE_FIELD_CONSTRUCTION = "Large Scale Field Construction (Thor)" +THOR_RAPID_RELOAD = "Rapid Reload (Thor)" +VALKYRIE_AFTERBURNERS = "Afterburners (Valkyrie)" +VALKYRIE_FLECHETTE_MISSILES = "Flechette Missiles (Valkyrie)" +VALKYRIE_ENHANCED_CLUSTER_LAUNCHERS = "Enhanced Cluster Launchers (Valkyrie)" +VALKYRIE_SHAPED_HULL = "Shaped Hull (Valkyrie)" +VALKYRIE_LAUNCHING_VECTOR_COMPENSATOR = "Launching Vector Compensator (Valkyrie)" +VALKYRIE_RESOURCE_EFFICIENCY = "Resource Efficiency (Valkyrie)" +VIKING_ANTI_MECHANICAL_MUNITION = "Anti-Mechanical Munition (Viking)" +VIKING_PHOBOS_CLASS_WEAPONS_SYSTEM = "Phobos-Class Weapons System (Viking)" +VIKING_RIPWAVE_MISSILES = "Ripwave Missiles (Viking)" +VIKING_SMART_SERVOS = "Smart Servos (Viking)" +VIKING_SHREDDER_ROUNDS = "Shredder Rounds (Viking)" +VIKING_WILD_MISSILES = "W.I.L.D. Missiles (Viking)" +VIKING_AESIR_TURBINES = "Aesir Turbines (Viking)" +VULTURE_AUTO_LAUNCHERS = "Auto Launchers (Vulture)" +VULTURE_ION_THRUSTERS = "Ion Thrusters (Vulture)" +VULTURE_PROGRESSIVE_REPLENISHABLE_MAGAZINE = "Progressive Replenishable Magazine (Vulture)" +VULTURE_JERRYRIGGED_PATCHUP = "Jerry-Rigged Patchup (Vulture)" +WARHOUND_RESOURCE_EFFICIENCY = "Resource Efficiency (Warhound)" +WARHOUND_AXIOM_PLATING = "Axiom Plating (Warhound)" +WARHOUND_DEPLOY_TURRET = "Deploy Turret (Warhound)" +WIDOW_MINE_BLACK_MARKET_LAUNCHERS = "Black Market Launchers (Widow Mine)" +WIDOW_MINE_CONCEALMENT = "Concealment (Widow Mine)" +WIDOW_MINE_DEMOLITION_PAYLOAD = "Demolition Payload (Widow Mine)" +WIDOW_MINE_DRILLING_CLAWS = "Drilling Claws (Widow Mine)" +WIDOW_MINE_EXECUTIONER_MISSILES = "Executioner Missiles (Widow Mine)" +WIDOW_MINE_RESOURCE_EFFICIENCY = "Resource Efficiency (Widow Mine)" +WRAITH_ADVANCED_LASER_TECHNOLOGY = "Advanced Laser Technology (Wraith)" +WRAITH_DISPLACEMENT_FIELD = "Displacement Field (Wraith)" +WRAITH_PROGRESSIVE_TOMAHAWK_POWER_CELLS = "Progressive Tomahawk Power Cells (Wraith)" +WRAITH_TRIGGER_OVERRIDE = "Trigger Override (Wraith)" +WRAITH_INTERNAL_TECH_MODULE = "Internal Tech Module (Wraith)" +WRAITH_RESOURCE_EFFICIENCY = "Resource Efficiency (Wraith)" + +# Terran Building upgrades +BUNKER_NEOSTEEL_BUNKER = "Neosteel Bunker (Bunker)" +BUNKER_PROJECTILE_ACCELERATOR = "Projectile Accelerator (Bunker)" +BUNKER_SHRIKE_TURRET = "Shrike Turret (Bunker)" +BUNKER_FORTIFIED_BUNKER = "Fortified Bunker (Bunker)" +DEVASTATOR_TURRET_ANTI_ARMOR_MUNITIONS = "Anti-Armor Munitions (Devastator Turret)" +DEVASTATOR_TURRET_CONCUSSIVE_GRENADES = "Concussive Grenades (Devastator Turret)" +DEVASTATOR_TURRET_RESOURCE_EFFICIENCY = "Resource Efficiency (Devastator Turret)" +MISSILE_TURRET_HELLSTORM_BATTERIES = "Hellstorm Batteries (Missile Turret)" +MISSILE_TURRET_TITANIUM_HOUSING = "Titanium Housing (Missile Turret)" +MISSILE_TURRET_RESOURCE_EFFICENCY = "Resource Efficiency (Missile Turret)" +PLANETARY_FORTRESS_PROGRESSIVE_AUGMENTED_THRUSTERS = "Progressive Augmented Thrusters (Planetary Fortress)" +PLANETARY_FORTRESS_IBIKS_TRACKING_SCANNERS = "Ibiks Tracking Scanners (Planetary Fortress)" +PLANETARY_FORTRESS_ORBITAL_MODULE = "Orbital Module (Planetary Fortress)" +SENSOR_TOWER_ASSISTIVE_TARGETING = "Assistive Targeting (Sensor Tower)" +SENSOR_TOWER_MUILTISPECTRUM_DOPPLER = "Multispectrum Doppler (Sensor Tower)" + +# Nova +NOVA_GHOST_VISOR = "Ghost Visor (Nova Equipment)" +NOVA_RANGEFINDER_OCULUS = "Rangefinder Oculus (Nova Equipment)" +NOVA_DOMINATION = "Domination (Nova Ability)" +NOVA_BLINK = "Blink (Nova Ability)" +NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE = "Progressive Stealth Suit Module (Nova Suit Module)" +NOVA_ENERGY_SUIT_MODULE = "Energy Suit Module (Nova Suit Module)" +NOVA_ARMORED_SUIT_MODULE = "Armored Suit Module (Nova Suit Module)" +NOVA_JUMP_SUIT_MODULE = "Jump Suit Module (Nova Suit Module)" +NOVA_C20A_CANISTER_RIFLE = "C20A Canister Rifle (Nova Weapon)" +NOVA_HELLFIRE_SHOTGUN = "Hellfire Shotgun (Nova Weapon)" +NOVA_PLASMA_RIFLE = "Plasma Rifle (Nova Weapon)" +NOVA_MONOMOLECULAR_BLADE = "Monomolecular Blade (Nova Weapon)" +NOVA_BLAZEFIRE_GUNBLADE = "Blazefire Gunblade (Nova Weapon)" +NOVA_STIM_INFUSION = "Stim Infusion (Nova Gadget)" +NOVA_PULSE_GRENADES = "Pulse Grenades (Nova Gadget)" +NOVA_FLASHBANG_GRENADES = "Flashbang Grenades (Nova Gadget)" +NOVA_IONIC_FORCE_FIELD = "Ionic Force Field (Nova Gadget)" +NOVA_HOLO_DECOY = "Holo Decoy (Nova Gadget)" +NOVA_NUKE = "Tac Nuke Strike (Nova Ability)" + +# Zerg Units +ZERGLING = "Zergling" +SWARM_QUEEN = "Swarm Queen" +ROACH = "Roach" +HYDRALISK = "Hydralisk" +ABERRATION = "Aberration" +MUTALISK = "Mutalisk" +SWARM_HOST = "Swarm Host" +INFESTOR = "Infestor" +ULTRALISK = "Ultralisk" +PYGALISK = "Pygalisk" +CORRUPTOR = "Corruptor" +SCOURGE = "Scourge" +BROOD_QUEEN = "Brood Queen" +DEFILER = "Defiler" +INFESTED_MARINE = "Infested Marine" +INFESTED_SIEGE_TANK = "Infested Siege Tank" +INFESTED_DIAMONDBACK = "Infested Diamondback" +BULLFROG = "Bullfrog" +INFESTED_BANSHEE = "Infested Banshee" +INFESTED_LIBERATOR = "Infested Liberator" + +# Zerg Buildings +SPORE_CRAWLER = "Spore Crawler" +SPINE_CRAWLER = "Spine Crawler" +BILE_LAUNCHER = "Bile Launcher" +INFESTED_BUNKER = "Infested Bunker" +INFESTED_MISSILE_TURRET = "Infested Missile Turret" +NYDUS_WORM = "Nydus Worm" +ECHIDNA_WORM = "Echidna Worm" + +# Zerg Weapon / Armor Upgrades +ZERG_UPGRADE_PREFIX = "Progressive Zerg" +ZERG_FLYER_UPGRADE_PREFIX = f"{ZERG_UPGRADE_PREFIX} Flyer" + +PROGRESSIVE_ZERG_MELEE_ATTACK = f"{ZERG_UPGRADE_PREFIX} Melee Attack" +PROGRESSIVE_ZERG_MISSILE_ATTACK = f"{ZERG_UPGRADE_PREFIX} Missile Attack" +PROGRESSIVE_ZERG_GROUND_CARAPACE = f"{ZERG_UPGRADE_PREFIX} Ground Carapace" +PROGRESSIVE_ZERG_FLYER_ATTACK = f"{ZERG_FLYER_UPGRADE_PREFIX} Attack" +PROGRESSIVE_ZERG_FLYER_CARAPACE = f"{ZERG_FLYER_UPGRADE_PREFIX} Carapace" +PROGRESSIVE_ZERG_WEAPON_UPGRADE = f"{ZERG_UPGRADE_PREFIX} Weapon Upgrade" +PROGRESSIVE_ZERG_ARMOR_UPGRADE = f"{ZERG_UPGRADE_PREFIX} Armor Upgrade" +PROGRESSIVE_ZERG_GROUND_UPGRADE = f"{ZERG_UPGRADE_PREFIX} Ground Upgrade" +PROGRESSIVE_ZERG_FLYER_UPGRADE = f"{ZERG_FLYER_UPGRADE_PREFIX} Upgrade" +PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE = f"{ZERG_UPGRADE_PREFIX} Weapon/Armor Upgrade" + +# Zerg Unit Upgrades +ZERGLING_HARDENED_CARAPACE = "Hardened Carapace (Zergling)" +ZERGLING_ADRENAL_OVERLOAD = "Adrenal Overload (Zergling)" +ZERGLING_METABOLIC_BOOST = "Metabolic Boost (Zergling)" +ZERGLING_SHREDDING_CLAWS = "Shredding Claws (Zergling)" +ROACH_HYDRIODIC_BILE = "Hydriodic Bile (Roach)" +ROACH_ADAPTIVE_PLATING = "Adaptive Plating (Roach)" +ROACH_TUNNELING_CLAWS = "Tunneling Claws (Roach)" +ROACH_GLIAL_RECONSTITUTION = "Glial Reconstitution (Roach)" +ROACH_ORGANIC_CARAPACE = "Organic Carapace (Roach)" +HYDRALISK_FRENZY = "Frenzy (Hydralisk)" +HYDRALISK_ANCILLARY_CARAPACE = "Ancillary Carapace (Hydralisk)" +HYDRALISK_GROOVED_SPINES = "Grooved Spines (Hydralisk)" +HYDRALISK_MUSCULAR_AUGMENTS = "Muscular Augments (Hydralisk)" +HYDRALISK_RESOURCE_EFFICIENCY = "Resource Efficiency (Hydralisk)" +BANELING_CORROSIVE_ACID = "Corrosive Acid (Baneling)" +BANELING_RUPTURE = "Rupture (Baneling)" +BANELING_REGENERATIVE_ACID = "Regenerative Acid (Baneling)" +BANELING_CENTRIFUGAL_HOOKS = "Centrifugal Hooks (Baneling)" +BANELING_TUNNELING_JAWS = "Tunneling Jaws (Baneling)" +BANELING_RAPID_METAMORPH = "Rapid Metamorph (Baneling)" +MUTALISK_VICIOUS_GLAIVE = "Vicious Glaive (Mutalisk)" +MUTALISK_RAPID_REGENERATION = "Rapid Regeneration (Mutalisk)" +MUTALISK_SUNDERING_GLAIVE = "Sundering Glaive (Mutalisk)" +MUTALISK_SEVERING_GLAIVE = "Severing Glaive (Mutalisk)" +MUTALISK_AERODYNAMIC_GLAIVE_SHAPE = "Aerodynamic Glaive Shape (Mutalisk)" +SPORE_CRAWLER_BIO_BONUS = "Caustic Enzymes (Spore Crawler)" +SWARM_HOST_BURROW = "Burrow (Swarm Host)" +SWARM_HOST_RAPID_INCUBATION = "Rapid Incubation (Swarm Host)" +SWARM_HOST_PRESSURIZED_GLANDS = "Pressurized Glands (Swarm Host)" +SWARM_HOST_LOCUST_METABOLIC_BOOST = "Locust Metabolic Boost (Swarm Host)" +SWARM_HOST_ENDURING_LOCUSTS = "Enduring Locusts (Swarm Host)" +SWARM_HOST_ORGANIC_CARAPACE = "Organic Carapace (Swarm Host)" +SWARM_HOST_RESOURCE_EFFICIENCY = "Resource Efficiency (Swarm Host)" +ULTRALISK_BURROW_CHARGE = "Burrow Charge (Ultralisk)" +ULTRALISK_TISSUE_ASSIMILATION = "Tissue Assimilation (Ultralisk)" +ULTRALISK_MONARCH_BLADES = "Monarch Blades (Ultralisk)" +ULTRALISK_ANABOLIC_SYNTHESIS = "Anabolic Synthesis (Ultralisk)" +ULTRALISK_CHITINOUS_PLATING = "Chitinous Plating (Ultralisk)" +ULTRALISK_ORGANIC_CARAPACE = "Organic Carapace (Ultralisk)" +ULTRALISK_RESOURCE_EFFICIENCY = "Resource Efficiency (Ultralisk)" +PYGALISK_STIM = "Stimpack (Pygalisk)" +PYGALISK_DUCAL_BLADES = "Ducal Blades (Pygalisk)" +PYGALISK_COMBAT_CARAPACE = "Combat Carapace (Pygalisk)" +CORRUPTOR_CORRUPTION = "Corruption (Corruptor)" +CORRUPTOR_CAUSTIC_SPRAY = "Caustic Spray (Corruptor)" +SCOURGE_VIRULENT_SPORES = "Virulent Spores (Scourge)" +SCOURGE_RESOURCE_EFFICIENCY = "Resource Efficiency (Scourge)" +SCOURGE_SWARM_SCOURGE = "Swarm Scourge (Scourge)" +DEVOURER_CORROSIVE_SPRAY = "Corrosive Spray (Devourer)" +DEVOURER_GAPING_MAW = "Gaping Maw (Devourer)" +DEVOURER_IMPROVED_OSMOSIS = "Improved Osmosis (Devourer)" +DEVOURER_PRESCIENT_SPORES = "Prescient Spores (Devourer)" +GUARDIAN_PROLONGED_DISPERSION = "Prolonged Dispersion (Guardian)" +GUARDIAN_PRIMAL_ADAPTATION = "Primal Adaptation (Guardian)" +GUARDIAN_SORONAN_ACID = "Soronan Acid (Guardian)" +GUARDIAN_PROPELLANT_SACS = "Propellant Sacs (Guardian)" +GUARDIAN_EXPLOSIVE_SPORES = "Explosive Spores (Guardian)" +GUARDIAN_PRIMORDIAL_FURY = "Primordial Fury (Guardian)" +IMPALER_ADAPTIVE_TALONS = "Adaptive Talons (Impaler)" +IMPALER_SECRETION_GLANDS = "Secretion Glands (Impaler)" +IMPALER_SUNKEN_SPINES = "Sunken Spines (Impaler)" +LURKER_SEISMIC_SPINES = "Seismic Spines (Lurker)" +LURKER_ADAPTED_SPINES = "Adapted Spines (Lurker)" +RAVAGER_POTENT_BILE = "Potent Bile (Ravager)" +RAVAGER_BLOATED_BILE_DUCTS = "Bloated Bile Ducts (Ravager)" +RAVAGER_DEEP_TUNNEL = "Deep Tunnel (Ravager)" +VIPER_PARASITIC_BOMB = "Parasitic Bomb (Viper)" +VIPER_PARALYTIC_BARBS = "Paralytic Barbs (Viper)" +VIPER_VIRULENT_MICROBES = "Virulent Microbes (Viper)" +BROOD_LORD_POROUS_CARTILAGE = "Porous Cartilage (Brood Lord)" +BROOD_LORD_BEHEMOTH_STELLARSKIN = "Behemoth Stellarskin (Brood Lord)" +BROOD_LORD_SPLITTER_MITOSIS = "Splitter Mitosis (Brood Lord)" +BROOD_LORD_RESOURCE_EFFICIENCY = "Resource Efficiency (Brood Lord)" +INFESTOR_INFESTED_TERRAN = "Infested Terran (Infestor)" +INFESTOR_MICROBIAL_SHROUD = "Microbial Shroud (Infestor)" +SWARM_QUEEN_SPAWN_LARVAE = "Spawn Larvae (Swarm Queen)" +SWARM_QUEEN_DEEP_TUNNEL = "Deep Tunnel (Swarm Queen)" +SWARM_QUEEN_ORGANIC_CARAPACE = "Organic Carapace (Swarm Queen)" +SWARM_QUEEN_BIO_MECHANICAL_TRANSFUSION = "Bio-Mechanical Transfusion (Swarm Queen)" +SWARM_QUEEN_RESOURCE_EFFICIENCY = "Resource Efficiency (Swarm Queen)" +SWARM_QUEEN_INCUBATOR_CHAMBER = "Incubator Chamber (Swarm Queen)" +BROOD_QUEEN_FUNGAL_GROWTH = "Fungal Growth (Brood Queen)" +BROOD_QUEEN_ENSNARE = "Ensnare (Brood Queen)" +BROOD_QUEEN_ENHANCED_MITOCHONDRIA = "Enhanced Mitochondria (Brood Queen)" +DEFILER_PATHOGEN_PROJECTORS = "Pathogen Projectors (Defiler)" +DEFILER_TRAPDOOR_ADAPTATION = "Trapdoor Adaptation (Defiler)" +DEFILER_PREDATORY_CONSUMPTION = "Predatory Consumption (Defiler)" +DEFILER_COMORBIDITY = "Comorbidity (Defiler)" +ABERRATION_MONSTROUS_RESILIENCE = "Monstrous Resilience (Aberration)" +ABERRATION_CONSTRUCT_REGENERATION = "Construct Regeneration (Aberration)" +ABERRATION_BANELING_INCUBATION = "Baneling Incubation (Aberration)" +ABERRATION_PROTECTIVE_COVER = "Protective Cover (Aberration)" +ABERRATION_RESOURCE_EFFICIENCY = "Resource Efficiency (Aberration)" +ABERRATION_PROGRESSIVE_BANELING_LAUNCH = "Progressive Baneling Launch (Aberration)" +CORRUPTOR_MONSTROUS_RESILIENCE = "Monstrous Resilience (Corruptor)" +CORRUPTOR_CONSTRUCT_REGENERATION = "Construct Regeneration (Corruptor)" +CORRUPTOR_SCOURGE_INCUBATION = "Scourge Incubation (Corruptor)" +CORRUPTOR_RESOURCE_EFFICIENCY = "Resource Efficiency (Corruptor)" +PRIMAL_IGNITER_CONCENTRATED_FIRE = "Concentrated Fire (Primal Igniter)" +PRIMAL_IGNITER_PRIMAL_TENACITY = "Primal Tenacity (Primal Igniter)" +OVERLORD_IMPROVED_OVERLORDS = "Improved Overlords (Overlord)" +OVERLORD_VENTRAL_SACS = "Ventral Sacs (Overlord)" +OVERLORD_GENERATE_CREEP = "Generate Creep (Overlord)" +OVERLORD_PNEUMATIZED_CARAPACE = "Pneumatized Carapace (Overlord)" +OVERLORD_ANTENNAE = "Antennae (Overlord)" +INFESTED_SCV_BUILD_CHARGES = "Sustained Cultivation Ventricles (Infested SCV)" +INFESTED_MARINE_PLAGUED_MUNITIONS = "Plagued Munitions (Infested Marine)" +INFESTED_MARINE_RETINAL_AUGMENTATION = "Retinal Augmentation (Infested Marine)" +INFESTED_BUNKER_CALCIFIED_ARMOR = "Calcified Armor (Infested Bunker)" +INFESTED_BUNKER_REGENERATIVE_PLATING = "Regenerative Plating (Infested Bunker)" +INFESTED_BUNKER_ENGORGED_BUNKERS = "Engorged Bunkers (Infested Bunker)" +TYRANNOZOR_BARRAGE_OF_SPIKES = "Barrage of Spikes (Tyrannozor)" +TYRANNOZOR_TYRANTS_PROTECTION = "Tyrant's Protection (Tyrannozor)" +TYRANNOZOR_HEALING_ADAPTATION = "Healing Adaptation (Tyrannozor)" +TYRANNOZOR_IMPALING_STRIKE = "Impaling Strike (Tyrannozor)" +BILE_LAUNCHER_ARTILLERY_DUCTS = "Artillery Ducts (Bile Launcher)" +BILE_LAUNCHER_RAPID_BOMBARMENT = "Rapid Bombardment (Bile Launcher)" +NYDUS_WORM_ECHIDNA_WORM_SUBTERRANEAN_SCALES = "Subterranean Scales (Nydus Worm/Echidna Worm)" +NYDUS_WORM_ECHIDNA_WORM_JORMUNGANDR_STRAIN = "Jormungandr Strain (Nydus Worm/Echidna Worm)" +NYDUS_WORM_ECHIDNA_WORM_RESOURCE_EFFICIENCY = "Resource Efficiency (Nydus Worm/Echidna Worm)" +NYDUS_WORM_RAVENOUS_APPETITE = "Ravenous Appetite (Nydus Worm)" +ECHIDNA_WORM_OUROBOROS_STRAIN = "Ouroboros Strain (Echidna Worm)" +INFESTED_SIEGE_TANK_PROGRESSIVE_AUTOMATED_MITOSIS = "Progressive Automated Mitosis (Infested Siege Tank)" +INFESTED_SIEGE_TANK_ACIDIC_ENZYMES = "Acidic Enzymes (Infested Siege Tank)" +INFESTED_SIEGE_TANK_DEEP_TUNNEL = "Deep Tunnel (Infested Siege Tank)" +INFESTED_SIEGE_TANK_SEISMIC_SONAR = "Seismic Sonar (Infested Siege Tank)" +INFESTED_SIEGE_TANK_BALANCED_ROOTS = "Balanced Roots (Infested Siege Tank)" +INFESTED_DIAMONDBACK_CAUSTIC_MUCUS = "Caustic Mucus (Infested Diamondback)" +INFESTED_DIAMONDBACK_VIOLENT_ENZYMES = "Violent Enzymes (Infested Diamondback)" +INFESTED_DIAMONDBACK_CONCENTRATED_SPEW = "Concentrated Spew (Infested Diamondback)" +INFESTED_DIAMONDBACK_PROGRESSIVE_FUNGAL_SNARE = "Progressive Fungal Snare (Infested Diamondback)" +INFESTED_BANSHEE_BRACED_EXOSKELETON = "Braced Exoskeleton (Infested Banshee)" +INFESTED_BANSHEE_RAPID_HIBERNATION = "Rapid Hibernation (Infested Banshee)" +INFESTED_BANSHEE_FLESHFUSED_TARGETING_OPTICS = "Fleshfused Targeting Optics (Infested Banshee)" +INFESTED_LIBERATOR_CLOUD_DISPERSAL = "Cloud Dispersal (Infested Liberator)" +INFESTED_LIBERATOR_VIRAL_CONTAMINATION = "Viral Contamination (Infested Liberator)" +INFESTED_LIBERATOR_DEFENDER_MODE = "Defender Mode (Infested Liberator)" +INFESTED_SIEGE_TANK_FRIGHTFUL_FLESHWELDER = "Frightful Fleshwelder (Infested Siege Tank)" +INFESTED_DIAMONDBACK_FRIGHTFUL_FLESHWELDER = "Frightful Fleshwelder (Infested Diamondback)" +INFESTED_BANSHEE_FRIGHTFUL_FLESHWELDER = "Frightful Fleshwelder (Infested Banshee)" +INFESTED_LIBERATOR_FRIGHTFUL_FLESHWELDER = "Frightful Fleshwelder (Infested Liberator)" +INFESTED_MISSILE_TURRET_BIOELECTRIC_PAYLOAD = "Bioelectric Payload (Infested Missile Turret)" +INFESTED_MISSILE_TURRET_ACID_SPORE_VENTS = "Acid Spore Vents (Infested Missile Turret)" +BULLFROG_WILD_MUTATION = "Mutagen Vents (Bullfrog)" +BULLFROG_BROODLINGS = "Suffused With Vermin (Bullfrog)" +BULLFROG_HARD_IMPACT = "Lethal Impact (Bullfrog)" +BULLFROG_RANGE = "Catalytic Boosters (Bullfrog)" + +# Zerg Strains +ZERGLING_RAPTOR_STRAIN = "Raptor Strain (Zergling)" +ZERGLING_SWARMLING_STRAIN = "Swarmling Strain (Zergling)" +ROACH_VILE_STRAIN = "Vile Strain (Roach)" +ROACH_CORPSER_STRAIN = "Corpser Strain (Roach)" +BANELING_SPLITTER_STRAIN = "Splitter Strain (Baneling)" +BANELING_HUNTER_STRAIN = "Hunter Strain (Baneling)" +SWARM_HOST_CARRION_STRAIN = "Carrion Strain (Swarm Host)" +SWARM_HOST_CREEPER_STRAIN = "Creeper Strain (Swarm Host)" +ULTRALISK_NOXIOUS_STRAIN = "Noxious Strain (Ultralisk)" +ULTRALISK_TORRASQUE_STRAIN = "Torrasque Strain (Ultralisk)" + +# Morphs +ZERGLING_BANELING_ASPECT = "Baneling" +HYDRALISK_IMPALER_ASPECT = "Impaler" +HYDRALISK_LURKER_ASPECT = "Lurker" +MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT = "Brood Lord" +MUTALISK_CORRUPTOR_VIPER_ASPECT = "Viper" +MUTALISK_CORRUPTOR_GUARDIAN_ASPECT = "Guardian" +MUTALISK_CORRUPTOR_DEVOURER_ASPECT = "Devourer" +ROACH_RAVAGER_ASPECT = "Ravager" +OVERLORD_OVERSEER_ASPECT = "Overseer" +ROACH_PRIMAL_IGNITER_ASPECT = "Primal Igniter" +ULTRALISK_TYRANNOZOR_ASPECT = "Tyrannozor" + +# Zerg Mercs +INFESTED_MEDICS = "Infested Medics" +INFESTED_SIEGE_BREAKERS = "Infested Siege Breakers" +INFESTED_DUSK_WINGS = "Infested Dusk Wings" +DEVOURING_ONES = "Devouring Ones" +HUNTER_KILLERS = "Hunter Killers" +TORRASQUE_MERC = "Wise Old Torrasque" +HUNTERLING = "Hunterling" +YGGDRASIL = "Yggdrasil" +CAUSTIC_HORRORS = "Caustic Horrors" + + +# Kerrigan Upgrades +KERRIGAN_KINETIC_BLAST = "Kinetic Blast (Kerrigan Ability)" +KERRIGAN_HEROIC_FORTITUDE = "Heroic Fortitude (Kerrigan Passive)" +KERRIGAN_LEAPING_STRIKE = "Leaping Strike (Kerrigan Ability)" +KERRIGAN_CRUSHING_GRIP = "Crushing Grip (Kerrigan Ability)" +KERRIGAN_CHAIN_REACTION = "Chain Reaction (Kerrigan Passive)" +KERRIGAN_PSIONIC_SHIFT = "Psionic Shift (Kerrigan Ability)" +KERRIGAN_WILD_MUTATION = "Wild Mutation (Kerrigan Ability)" +KERRIGAN_SPAWN_BANELINGS = "Spawn Banelings (Kerrigan Ability)" +KERRIGAN_MEND = "Mend (Kerrigan Ability)" +KERRIGAN_INFEST_BROODLINGS = "Infest Broodlings (Kerrigan Passive)" +KERRIGAN_FURY = "Fury (Kerrigan Passive)" +KERRIGAN_ABILITY_EFFICIENCY = "Ability Efficiency (Kerrigan Passive)" +KERRIGAN_APOCALYPSE = "Apocalypse (Kerrigan Ability)" +KERRIGAN_SPAWN_LEVIATHAN = "Spawn Leviathan (Kerrigan Ability)" +KERRIGAN_DROP_PODS = "Drop-Pods (Kerrigan Ability)" +KERRIGAN_ASSIMILATION_AURA = "Assimilation Aura (Kerrigan Ability)" +KERRIGAN_IMMOBILIZATION_WAVE = "Immobilization Wave (Kerrigan Ability)" +KERRIGAN_PRIMAL_FORM = "Primal Form (Kerrigan)" + +# Misc Upgrades +ZERGLING_RECONSTITUTION = "Zergling Reconstitution (Zerg)" +AUTOMATED_EXTRACTORS = "Automated Extractors (Zerg)" +TWIN_DRONES = "Twin Drones (Zerg)" +MALIGNANT_CREEP = "Malignant Creep (Zerg)" +VESPENE_EFFICIENCY = "Vespene Efficiency (Zerg)" +ZERG_CREEP_STOMACH = "Creep Stomach (Zerg)" +ZERG_EXCAVATING_CLAWS = "Excavating Claws (Zerg)" +HIVE_CLUSTER_MATURATION = "Hive Cluster Maturation (Zerg)" +MACROSCOPIC_RECUPERATION = "Macroscopic Recuperation (Zerg)" +BIOMECHANICAL_STOCKPILING = "Bio-Mechanical Stockpiling (Zerg)" +BROODLING_SPORE_SATURATION = "Broodling Spore Saturation (Zerg)" +UNRESTRICTED_MUTATION = "Unrestricted Mutation (Zerg)" +CELL_DIVISION = "Cell Division (Zerg)" +EVOLUTIONARY_LEAP = "Evolutionary Leap (Zerg)" +SELF_SUFFICIENT = "Self-Sufficient (Zerg)" + +# Kerrigan Levels +KERRIGAN_LEVELS_1 = "1 Kerrigan Level" +KERRIGAN_LEVELS_2 = "2 Kerrigan Levels" +KERRIGAN_LEVELS_3 = "3 Kerrigan Levels" +KERRIGAN_LEVELS_4 = "4 Kerrigan Levels" +KERRIGAN_LEVELS_5 = "5 Kerrigan Levels" +KERRIGAN_LEVELS_6 = "6 Kerrigan Levels" +KERRIGAN_LEVELS_7 = "7 Kerrigan Levels" +KERRIGAN_LEVELS_8 = "8 Kerrigan Levels" +KERRIGAN_LEVELS_9 = "9 Kerrigan Levels" +KERRIGAN_LEVELS_10 = "10 Kerrigan Levels" +KERRIGAN_LEVELS_14 = "14 Kerrigan Levels" +KERRIGAN_LEVELS_35 = "35 Kerrigan Levels" +KERRIGAN_LEVELS_70 = "70 Kerrigan Levels" + +# Protoss Units +ZEALOT = "Zealot" +STALKER = "Stalker" +HIGH_TEMPLAR = "High Templar" +DARK_TEMPLAR = "Dark Templar" +IMMORTAL = "Immortal" +COLOSSUS = "Colossus" +PHOENIX = "Phoenix" +VOID_RAY = "Void Ray" +CARRIER = "Carrier" +SKYLORD = "Skylord" +TRIREME = "Trireme" +OBSERVER = "Observer" +CENTURION = "Centurion" +SENTINEL = "Sentinel" +SUPPLICANT = "Supplicant" +INSTIGATOR = "Instigator" +SLAYER = "Slayer" +SENTRY = "Sentry" +ENERGIZER = "Energizer" +HAVOC = "Havoc" +SIGNIFIER = "Signifier" +ASCENDANT = "Ascendant" +AVENGER = "Avenger" +BLOOD_HUNTER = "Blood Hunter" +DRAGOON = "Dragoon" +DARK_ARCHON = "Dark Archon" +ADEPT = "Adept" +WARP_PRISM = "Warp Prism" +ANNIHILATOR = "Annihilator" +VANGUARD = "Vanguard" +STALWART = "Stalwart" +WRATHWALKER = "Wrathwalker" +REAVER = "Reaver" +DISRUPTOR = "Disruptor" +MIRAGE = "Mirage" +SKIRMISHER = "Skirmisher" +CORSAIR = "Corsair" +DESTROYER = "Destroyer" +PULSAR = "Pulsar" +DAWNBRINGER = "Dawnbringer" +SCOUT = "Scout" +OPPRESSOR = "Oppressor" +CALADRIUS = "Caladrius" +MISTWING = "Mist Wing" +TEMPEST = "Tempest" +MOTHERSHIP = "Mothership" +ARBITER = "Arbiter" +ORACLE = "Oracle" + +# Upgrades +PROTOSS_UPGRADE_PREFIX = "Progressive Protoss" +PROTOSS_GROUND_UPGRADE_PREFIX = f"{PROTOSS_UPGRADE_PREFIX} Ground" +PROTOSS_AIR_UPGRADE_PREFIX = f"{PROTOSS_UPGRADE_PREFIX} Air" +PROGRESSIVE_PROTOSS_GROUND_WEAPON = f"{PROTOSS_GROUND_UPGRADE_PREFIX} Weapon" +PROGRESSIVE_PROTOSS_GROUND_ARMOR = f"{PROTOSS_GROUND_UPGRADE_PREFIX} Armor" +PROGRESSIVE_PROTOSS_SHIELDS = f"{PROTOSS_UPGRADE_PREFIX} Shields" +PROGRESSIVE_PROTOSS_AIR_WEAPON = f"{PROTOSS_AIR_UPGRADE_PREFIX} Weapon" +PROGRESSIVE_PROTOSS_AIR_ARMOR = f"{PROTOSS_AIR_UPGRADE_PREFIX} Armor" +PROGRESSIVE_PROTOSS_WEAPON_UPGRADE = f"{PROTOSS_UPGRADE_PREFIX} Weapon Upgrade" +PROGRESSIVE_PROTOSS_ARMOR_UPGRADE = f"{PROTOSS_UPGRADE_PREFIX} Armor Upgrade" +PROGRESSIVE_PROTOSS_GROUND_UPGRADE = f"{PROTOSS_GROUND_UPGRADE_PREFIX} Upgrade" +PROGRESSIVE_PROTOSS_AIR_UPGRADE = f"{PROTOSS_AIR_UPGRADE_PREFIX} Upgrade" +PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE = f"{PROTOSS_UPGRADE_PREFIX} Weapon/Armor Upgrade" + +# Buildings +PHOTON_CANNON = "Photon Cannon" +KHAYDARIN_MONOLITH = "Khaydarin Monolith" +SHIELD_BATTERY = "Shield Battery" + +# Unit Upgrades +SUPPLICANT_BLOOD_SHIELD = "Blood Shield (Supplicant)" +SUPPLICANT_SOUL_AUGMENTATION = "Soul Augmentation (Supplicant)" +SUPPLICANT_ENDLESS_SERVITUDE = "Endless Servitude (Supplicant)" +SUPPLICANT_ZENITH_PITCH = "Zenith Pitch (Supplicant)" +SUPPLICANT_SACRIFICE = "Sacrifice (Supplicant)" +ADEPT_SHOCKWAVE = "Shockwave (Adept)" +ADEPT_RESONATING_GLAIVES = "Resonating Glaives (Adept)" +ADEPT_PHASE_BULWARK = "Phase Bulwark (Adept)" +STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES = "Disintegrating Particles (Stalker/Instigator/Slayer)" +STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION = "Particle Reflection (Stalker/Instigator/Slayer)" +INSTIGATOR_BLINK_OVERDRIVE = "Blink Overdrive (Instigator)" +INSTIGATOR_RECONSTRUCTION = "Reconstruction (Instigator)" +DRAGOON_CONCENTRATED_ANTIMATTER = "Concentrated Antimatter (Dragoon)" +DRAGOON_TRILLIC_COMPRESSION_SYSTEM = "Trillic Compression System (Dragoon)" +DRAGOON_SINGULARITY_CHARGE = "Singularity Charge (Dragoon)" +DRAGOON_ENHANCED_STRIDER_SERVOS = "Enhanced Strider Servos (Dragoon)" +SCOUT_COMBAT_SENSOR_ARRAY = "Combat Sensor Array (Scout/Oppressor/Caladrius/Mist Wing)" +SCOUT_APIAL_SENSORS = "Apial Sensors (Scout)" +SCOUT_GRAVITIC_THRUSTERS = "Gravitic Thrusters (Scout/Oppressor/Caladrius/Mist Wing)" +SCOUT_ADVANCED_PHOTON_BLASTERS = "Advanced Photon Blasters (Scout/Oppressor/Mist Wing)" +SCOUT_RESOURCE_EFFICIENCY = "Resource Efficiency (Scout)" +SCOUT_SUPPLY_EFFICIENCY = "Supply Efficiency (Scout)" +TEMPEST_TECTONIC_DESTABILIZERS = "Tectonic Destabilizers (Tempest)" +TEMPEST_QUANTIC_REACTOR = "Quantic Reactor (Tempest)" +TEMPEST_GRAVITY_SLING = "Gravity Sling (Tempest)" +TEMPEST_INTERPLANETARY_RANGE = "Interplanetary Range (Tempest)" +PHOENIX_CLASS_IONIC_WAVELENGTH_FLUX = "Ionic Wavelength Flux (Phoenix/Mirage/Skirmisher)" +PHOENIX_CLASS_ANION_PULSE_CRYSTALS = "Anion Pulse-Crystals (Phoenix/Mirage/Skirmisher)" +CORSAIR_STEALTH_DRIVE = "Stealth Drive (Corsair)" +CORSAIR_ARGUS_JEWEL = "Argus Jewel (Corsair)" +CORSAIR_SUSTAINING_DISRUPTION = "Sustaining Disruption (Corsair)" +CORSAIR_NEUTRON_SHIELDS = "Neutron Shields (Corsair)" +ORACLE_STEALTH_DRIVE = "Stealth Drive (Oracle)" +ORACLE_SKYWARD_CHRONOANOMALY = "Skyward Chronoanomaly (Oracle)" +ORACLE_TEMPORAL_ACCELERATION_BEAM = "Temporal Acceleration Beam (Oracle)" +ORACLE_BOSONIC_CORE = "Bosonic Core (Oracle)" +ARBITER_CHRONOSTATIC_REINFORCEMENT = "Chronostatic Reinforcement (Arbiter)" +ARBITER_KHAYDARIN_CORE = "Khaydarin Core (Arbiter)" +ARBITER_SPACETIME_ANCHOR = "Spacetime Anchor (Arbiter)" +ARBITER_RESOURCE_EFFICIENCY = "Resource Efficiency (Arbiter)" +ARBITER_JUDICATORS_VEIL = "Judicator's Veil (Arbiter)" +CARRIER_TRIREME_GRAVITON_CATAPULT = "Graviton Catapult (Carrier/Trireme)" +CARRIER_SKYLORD_TRIREME_HULL_OF_PAST_GLORIES = "Hull of Past Glories (Carrier/Skylord/Trireme)" +VOID_RAY_DESTROYER_PULSAR_DAWNBRINGER_FLUX_VANES = "Flux Vanes (Void Ray/Destroyer/Pulsar/Dawnbringer)" +DAWNBRINGER_ANTI_SURFACE_COUNTERMEASURES = "Anti-Surface Countermeasures (Dawnbringer)" +DAWNBRINGER_ENHANCED_SHIELD_GENERATOR = "Enhanced Shield Generator (Dawnbringer)" +PULSAR_CHRONOCLYSM = "Chronoclysm (Pulsar)" +PULSAR_ENTROPIC_REVERSAL = "Entropic Reversal (Pulsar)" +DESTROYER_RESOURCE_EFFICIENCY = "Resource Efficiency (Destroyer)" +WARP_PRISM_GRAVITIC_DRIVE = "Gravitic Drive (Warp Prism)" +WARP_PRISM_PHASE_BLASTER = "Phase Blaster (Warp Prism)" +WARP_PRISM_WAR_CONFIGURATION = "War Configuration (Warp Prism)" +OBSERVER_GRAVITIC_BOOSTERS = "Gravitic Boosters (Observer)" +OBSERVER_SENSOR_ARRAY = "Sensor Array (Observer)" +REAVER_SCARAB_DAMAGE = "Scarab Damage (Reaver)" +REAVER_SOLARITE_PAYLOAD = "Solarite Payload (Reaver)" +REAVER_REAVER_CAPACITY = "Reaver Capacity (Reaver)" +REAVER_RESOURCE_EFFICIENCY = "Resource Efficiency (Reaver)" +REAVER_BARGAIN_BIN_PRICES = "Bargain Bin Prices (Reaver)" +VANGUARD_AGONY_LAUNCHERS = "Agony Launchers (Vanguard)" +VANGUARD_MATTER_DISPERSION = "Matter Dispersion (Vanguard)" +IMMORTAL_ANNIHILATOR_SINGULARITY_CHARGE = "Singularity Charge (Immortal/Annihilator)" +IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING = "Advanced Targeting (Immortal/Annihilator)" +IMMORTAL_ANNIHILATOR_DISRUPTOR_DISPERSION = "Disruptor Dispersion (Immortal/Annihilator)" +STALWART_HIGH_VOLTAGE_CAPACITORS = "High Voltage Capacitors (Stalwart)" +STALWART_REINTEGRATED_FRAMEWORK = "Reintegrated Framework (Stalwart)" +STALWART_STABILIZED_ELECTRODES = "Stabilized Electrodes (Stalwart)" +STALWART_LATTICED_SHIELDING = "Latticed Shielding (Stalwart)" +DISRUPTOR_CLOAKING_MODULE = "Cloaking Module (Disruptor)" +DISRUPTOR_PERFECTED_POWER = "Perfected Power (Disruptor)" +DISRUPTOR_RESTRAINED_DESTRUCTION = "Restrained Destruction (Disruptor)" +COLOSSUS_PACIFICATION_PROTOCOL = "Pacification Protocol (Colossus)" +WRATHWALKER_RAPID_POWER_CYCLING = "Rapid Power Cycling (Wrathwalker)" +WRATHWALKER_EYE_OF_WRATH = "Eye of Wrath (Wrathwalker)" +DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_SHROUD_OF_ADUN = "Shroud of Adun (Dark Templar/Avenger/Blood Hunter)" +DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_SHADOW_GUARD_TRAINING = "Shadow Guard Training (Dark Templar/Avenger/Blood Hunter)" +DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_BLINK = "Blink (Dark Templar/Avenger/Blood Hunter)" +DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_RESOURCE_EFFICIENCY = "Resource Efficiency (Dark Templar/Avenger/Blood Hunter)" +DARK_TEMPLAR_DARK_ARCHON_MELD = "Dark Archon Meld (Dark Templar)" +DARK_TEMPLAR_ARCHON_MERGE = "Archon Merge (Dark Templar)" +HIGH_TEMPLAR_SIGNIFIER_UNSHACKLED_PSIONIC_STORM = "Unshackled Psionic Storm (High Templar/Signifier)" +HIGH_TEMPLAR_SIGNIFIER_HALLUCINATION = "Hallucination (High Templar/Signifier)" +HIGH_TEMPLAR_SIGNIFIER_KHAYDARIN_AMULET = "Khaydarin Amulet (High Templar/Signifier)" +ARCHON_HIGH_ARCHON = "High Archon (Archon)" +ARCHON_TRANSCENDENCE = "Transcendence (Archon)" +ARCHON_POWER_SIPHON = "Power Siphon (Archon)" +ARCHON_ERADICATE = "Eradicate (Archon)" +ARCHON_OBLITERATE = "Obliterate (Archon)" +DARK_ARCHON_FEEDBACK = "Feedback (Dark Archon)" +DARK_ARCHON_MAELSTROM = "Maelstrom (Dark Archon)" +DARK_ARCHON_ARGUS_TALISMAN = "Argus Talisman (Dark Archon)" +ASCENDANT_POWER_OVERWHELMING = "Power Overwhelming (Ascendant)" +ASCENDANT_CHAOTIC_ATTUNEMENT = "Chaotic Attunement (Ascendant)" +ASCENDANT_BLOOD_AMULET = "Blood Amulet (Ascendant)" +ASCENDANT_ARCHON_MERGE = "Archon Merge (Ascendant)" +SENTRY_ENERGIZER_HAVOC_CLOAKING_MODULE = "Cloaking Module (Sentry/Energizer/Havoc)" +SENTRY_ENERGIZER_HAVOC_SHIELD_BATTERY_RAPID_RECHARGING = "Rapid Recharging (Sentry/Energizer/Havoc/Shield Battery)" +SENTRY_FORCE_FIELD = "Force Field (Sentry)" +SENTRY_HALLUCINATION = "Hallucination (Sentry)" +ENERGIZER_RECLAMATION = "Reclamation (Energizer)" +ENERGIZER_FORGED_CHASSIS = "Forged Chassis (Energizer)" +HAVOC_DETECT_WEAKNESS = "Detect Weakness (Havoc)" +HAVOC_BLOODSHARD_RESONANCE = "Bloodshard Resonance (Havoc)" +ZEALOT_SENTINEL_CENTURION_LEG_ENHANCEMENTS = "Leg Enhancements (Zealot/Sentinel/Centurion)" +ZEALOT_SENTINEL_CENTURION_SHIELD_CAPACITY = "Shield Capacity (Zealot/Sentinel/Centurion)" +OPPRESSOR_ACCELERATED_WARP = "Accelerated Warp (Oppressor)" +OPPRESSOR_ARMOR_MELTING_BLASTERS = "Armor Melting Blasters (Oppressor)" +CALADRIUS_SIDE_MISSILES = "Side Missiles (Caladrius)" +CALADRIUS_STRUCTURE_TARGETING = "Structure Targeting (Caladrius)" +CALADRIUS_SOLARITE_REACTOR = "Solarite Reactor (Caladrius)" +MISTWING_NULL_SHROUD = "Null Shroud (Mist Wing)" +MISTWING_PILOT = "Pilot (Mist Wing)" + +# War Council +ZEALOT_WHIRLWIND = "Whirlwind (Zealot)" +CENTURION_RESOURCE_EFFICIENCY = "Resource Efficiency (Centurion)" +SENTINEL_RESOURCE_EFFICIENCY = "Resource Efficiency (Sentinel)" +STALKER_PHASE_REACTOR = "Phase Reactor (Stalker)" +DRAGOON_PHALANX_SUIT = "Phalanx Suit (Dragoon)" +INSTIGATOR_MODERNIZED_SERVOS = "Modernized Servos (Instigator)" +ADEPT_DISRUPTIVE_TRANSFER = "Disruptive Transfer (Adept)" +SLAYER_PHASE_BLINK = "Phase Blink (Slayer)" +AVENGER_KRYHAS_CLOAK = "Kryhas Cloak (Avenger)" +DARK_TEMPLAR_LESSER_SHADOW_FURY = "Lesser Shadow Fury (Dark Templar)" +DARK_TEMPLAR_GREATER_SHADOW_FURY = "Greater Shadow Fury (Dark Templar)" +BLOOD_HUNTER_BRUTAL_EFFICIENCY = "Brutal Efficiency (Blood Hunter)" +SENTRY_DOUBLE_SHIELD_RECHARGE = "Double Shield Recharge (Sentry)" +ENERGIZER_MOBILE_CHRONO_BEAM = "Mobile Chrono Beam (Energizer)" +HAVOC_ENDURING_SIGHT = "Enduring Sight (Havoc)" +HIGH_TEMPLAR_PLASMA_SURGE = "Plasma Surge (High Templar)" +SIGNIFIER_FEEDBACK = "Feedback (Signifier)" +ASCENDANT_BREATH_OF_CREATION = "Breath of Creation (Ascendant)" +DARK_ARCHON_INDOMITABLE_WILL = "Indomitable Will (Dark Archon)" +IMMORTAL_IMPROVED_BARRIER = "Improved Barrier (Immortal)" +VANGUARD_RAPIDFIRE_CANNON = "Rapid-Fire Cannon (Vanguard)" +VANGUARD_FUSION_MORTARS = "Fusion Mortars (Vanguard)" +ANNIHILATOR_TWILIGHT_CHASSIS = "Twilight Chassis (Annihilator)" +STALWART_ARC_INDUCERS = "Arc Inducers (Stalwart)" +COLOSSUS_FIRE_LANCE = "Fire Lance (Colossus)" +WRATHWALKER_AERIAL_TRACKING = "Aerial Tracking (Wrathwalker)" +REAVER_KHALAI_REPLICATORS = "Khalai Replicators (Reaver)" +DISRUPTOR_MOBILITY_PROTOCOLS = "Mobility Protocols (Disruptor)" +WARP_PRISM_WARP_REFRACTION = "Warp Refraction (Warp Prism)" +OBSERVER_INDUCE_SCOPOPHOBIA = "Induce Scopophobia (Observer)" +PHOENIX_DOUBLE_GRAVITON_BEAM = "Double Graviton Beam (Phoenix)" +CORSAIR_NETWORK_DISRUPTION = "Network Disruption (Corsair)" +MIRAGE_GRAVITON_BEAM = "Graviton Beam (Mirage)" +SKIRMISHER_PEER_CONTEMPT = "Peer Contempt (Skirmisher)" +VOID_RAY_PRISMATIC_RANGE = "Prismatic Range (Void Ray)" +DESTROYER_REFORGED_BLOODSHARD_CORE = "Reforged Bloodshard Core (Destroyer)" +PULSAR_CHRONO_SHEAR = "Chrono Shear (Pulsar)" +DAWNBRINGER_SOLARITE_LENS = "Solarite Lens (Dawnbringer)" +CARRIER_REPAIR_DRONES = "Repair Drones (Carrier)" +SKYLORD_JUMP = "Jump (Skylord)" +TRIREME_SOLAR_BEAM = "Solar Beam (Trireme)" +TEMPEST_DISINTEGRATION = "Disintegration (Tempest)" +SCOUT_EXPEDITIONARY_HULL = "Expeditionary Hull (Scout)" +ARBITER_VESSEL_OF_THE_CONCLAVE = "Vessel of the Conclave (Arbiter)" +ORACLE_STASIS_CALIBRATION = "Stasis Calibration (Oracle)" +MOTHERSHIP_INTEGRATED_POWER = "Integrated Power (Mothership)" +OPPRESSOR_VULCAN_BLASTER = "Vulcan Blaster (Oppressor)" +CALADRIUS_CORONA_BEAM = "Corona Beam (Caladrius)" +MISTWING_PHANTOM_DASH = "Phantom Dash (Mist Wing)" + +# Spear Of Adun +SOA_CHRONO_SURGE = "Chrono Surge (Spear of Adun)" +SOA_PROGRESSIVE_PROXY_PYLON = "Progressive Proxy Pylon (Spear of Adun)" +SOA_PYLON_OVERCHARGE = "Pylon Overcharge (Spear of Adun)" +SOA_ORBITAL_STRIKE = "Orbital Strike (Spear of Adun)" +SOA_TEMPORAL_FIELD = "Temporal Field (Spear of Adun)" +SOA_SOLAR_LANCE = "Solar Lance (Spear of Adun)" +SOA_MASS_RECALL = "Mass Recall (Spear of Adun)" +SOA_SHIELD_OVERCHARGE = "Shield Overcharge (Spear of Adun)" +SOA_DEPLOY_FENIX = "Deploy Fenix (Spear of Adun)" +SOA_PURIFIER_BEAM = "Purifier Beam (Spear of Adun)" +SOA_TIME_STOP = "Time Stop (Spear of Adun)" +SOA_SOLAR_BOMBARDMENT = "Solar Bombardment (Spear of Adun)" + +# Generic upgrades +MATRIX_OVERLOAD = "Matrix Overload (Protoss)" +QUATRO = "Quatro (Protoss)" +NEXUS_OVERCHARGE = "Nexus Overcharge (Protoss)" +ORBITAL_ASSIMILATORS = "Orbital Assimilators (Protoss)" +WARP_HARMONIZATION = "Warp Harmonization (Protoss)" +GUARDIAN_SHELL = "Guardian Shell (Spear of Adun)" +RECONSTRUCTION_BEAM = "Reconstruction Beam (Spear of Adun)" +OVERWATCH = "Overwatch (Spear of Adun)" +SUPERIOR_WARP_GATES = "Superior Warp Gates (Protoss)" +ENHANCED_TARGETING = "Enhanced Targeting (Protoss)" +OPTIMIZED_ORDNANCE = "Optimized Ordnance (Protoss)" +KHALAI_INGENUITY = "Khalai Ingenuity (Protoss)" +AMPLIFIED_ASSIMILATORS = "Amplified Assimilators (Protoss)" +PROGRESSIVE_WARP_RELOCATE = "Progressive Warp Relocate (Protoss)" +PROBE_WARPIN = "Probe Warp-In (Protoss)" +ELDER_PROBES = "Elder Probes (Protoss)" + +# Filler items +STARTING_MINERALS = "Additional Starting Minerals" +STARTING_VESPENE = "Additional Starting Vespene" +STARTING_SUPPLY = "Additional Starting Supply" +MAX_SUPPLY = "Additional Maximum Supply" +SHIELD_REGENERATION = "Increased Shield Regeneration" +BUILDING_CONSTRUCTION_SPEED = "Increased Building Construction Speed" +UPGRADE_RESEARCH_SPEED = "Increased Upgrade Research Speed" +UPGRADE_RESEARCH_COST = "Reduced Upgrade Research Cost" + +# Trap +REDUCED_MAX_SUPPLY = "Decreased Maximum Supply" +NOTHING = "Nothing" + +# Deprecated +PROGRESSIVE_ORBITAL_COMMAND = "Progressive Orbital Command (Deprecated)" + +# Keys +_TEMPLATE_MISSION_KEY = "{} Mission Key" +_TEMPLATE_NAMED_LAYOUT_KEY = "{} ({}) Questline Key" +_TEMPLATE_NUMBERED_LAYOUT_KEY = "Questline Key #{}" +_TEMPLATE_NAMED_CAMPAIGN_KEY = "{} Campaign Key" +_TEMPLATE_NUMBERED_CAMPAIGN_KEY = "Campaign Key #{}" +_TEMPLATE_FLAVOR_KEY = "{} Key" +PROGRESSIVE_MISSION_KEY = "Progressive Mission Key" +PROGRESSIVE_QUESTLINE_KEY = "Progressive Questline Key" +_TEMPLATE_PROGRESSIVE_KEY = "Progressive Key #{}" + +# Names for flavor keys, feel free to add more, but add them to the Custom Mission Order docs too +# These will never be randomly created by the generator +_flavor_key_names = [ + "Terran", "Zerg", "Protoss", + "Raynor", "Tychus", "Swann", "Stetmann", "Hanson", "Nova", "Tosh", "Valerian", "Warfield", "Mengsk", "Han", "Horner", + "Kerrigan", "Zagara", "Abathur", "Yagdra", "Kraith", "Slivan", "Zurvan", "Brakk", "Stukov", "Dehaka", "Niadra", "Izsha", + "Artanis", "Zeratul", "Tassadar", "Karax", "Vorazun", "Alarak", "Fenix", "Urun", "Mohandar", "Selendis", "Rohana", + "Reigel", "Davis", "Ji'nara" +] diff --git a/worlds/sc2/item/item_parents.py b/worlds/sc2/item/item_parents.py new file mode 100644 index 000000000000..18b27b79d24a --- /dev/null +++ b/worlds/sc2/item/item_parents.py @@ -0,0 +1,266 @@ +""" +Utilities for telling item parentage hierarchy. +ItemData in item_tables.py will point from child item -> parent rule. +Rules have a `parent_items()` method which links rule -> parent items. +Rules may be more complex than all or any items being present. Call them to determine if they are satisfied. +""" + +from typing import Dict, List, Iterable, Sequence, Optional, TYPE_CHECKING +import abc +from . import item_names, parent_names, item_tables, item_groups + +if TYPE_CHECKING: + from ..options import Starcraft2Options + + +class PresenceRule(abc.ABC): + """Contract for a parent presence rule. This should be a protocol in Python 3.10+""" + constraint_group: Optional[str] + """Identifies the group this item rule is a part of, subject to min/max upgrades per unit""" + display_string: str + """Main item to count as the parent for min/max upgrades per unit purposes""" + @abc.abstractmethod + def __call__(self, inventory: Iterable[str], options: 'Starcraft2Options') -> bool: ... + @abc.abstractmethod + def parent_items(self) -> Sequence[str]: ... + + +class ItemPresent(PresenceRule): + def __init__(self, item_name: str) -> None: + self.item_name = item_name + self.constraint_group = item_name + self.display_string = item_name + + def __call__(self, inventory: Iterable[str], options: 'Starcraft2Options') -> bool: + return self.item_name in inventory + + def parent_items(self) -> List[str]: + return [self.item_name] + + +class AnyOf(PresenceRule): + def __init__(self, group: Iterable[str], main_item: Optional[str] = None, display_string: Optional[str] = None) -> None: + self.group = set(group) + self.constraint_group = main_item + self.display_string = display_string or main_item or ' | '.join(group) + + def __call__(self, inventory: Iterable[str], options: 'Starcraft2Options') -> bool: + return len(self.group.intersection(inventory)) > 0 + + def parent_items(self) -> List[str]: + return sorted(self.group) + + +class AllOf(PresenceRule): + def __init__(self, group: Iterable[str], main_item: Optional[str] = None) -> None: + self.group = set(group) + self.constraint_group = main_item + self.display_string = main_item or ' & '.join(group) + + def __call__(self, inventory: Iterable[str], options: 'Starcraft2Options') -> bool: + return len(self.group.intersection(inventory)) == len(self.group) + + def parent_items(self) -> List[str]: + return sorted(self.group) + + +class AnyOfGroupAndOneOtherItem(PresenceRule): + def __init__(self, group: Iterable[str], item_name: str) -> None: + self.group = set(group) + self.item_name = item_name + self.constraint_group = item_name + self.display_string = item_name + + def __call__(self, inventory: Iterable[str], options: 'Starcraft2Options') -> bool: + return (len(self.group.intersection(inventory)) > 0) and self.item_name in inventory + + def parent_items(self) -> List[str]: + return sorted(self.group) + [self.item_name] + + +class MorphlingOrItem(PresenceRule): + def __init__(self, item_name: str, has_parent: bool = True) -> None: + self.item_name = item_name + self.constraint_group = None # Keep morphs from counting towards the parent unit's upgrade count + self.display_string = f'{item_name} Morphs' + + def __call__(self, inventory: Iterable[str], options: 'Starcraft2Options') -> bool: + return (options.enable_morphling.value != 0) or self.item_name in inventory + + def parent_items(self) -> List[str]: + return [self.item_name] + + +class MorphlingOrAnyOf(PresenceRule): + def __init__(self, group: Iterable[str], display_string: str, main_item: Optional[str] = None) -> None: + self.group = set(group) + self.constraint_group = main_item + self.display_string = display_string + + def __call__(self, inventory: Iterable[str], options: 'Starcraft2Options') -> bool: + return (options.enable_morphling.value != 0) or (len(self.group.intersection(inventory)) > 0) + + def parent_items(self) -> List[str]: + return sorted(self.group) + + +parent_present: Dict[str, PresenceRule] = { + item_name: ItemPresent(item_name) + for item_name in item_tables.item_table +} + +# Terran +parent_present[parent_names.DOMINION_TROOPER_WEAPONS] = AnyOf([ + item_names.DOMINION_TROOPER_B2_HIGH_CAL_LMG, + item_names.DOMINION_TROOPER_CPO7_SALAMANDER_FLAMETHROWER, + item_names.DOMINION_TROOPER_HAILSTORM_LAUNCHER, +], main_item=item_names.DOMINION_TROOPER) +parent_present[parent_names.INFANTRY_UNITS] = AnyOf(item_groups.barracks_units, display_string='Terran Infantry') +parent_present[parent_names.INFANTRY_WEAPON_UNITS] = AnyOf(item_groups.barracks_wa_group, display_string='Terran Infantry') +parent_present[parent_names.ORBITAL_COMMAND_AND_PLANETARY] = AnyOfGroupAndOneOtherItem( + item_groups.orbital_command_abilities, + item_names.PLANETARY_FORTRESS, +) +parent_present[parent_names.SIEGE_TANK_AND_TRANSPORT] = AnyOfGroupAndOneOtherItem( + (item_names.MEDIVAC, item_names.HERCULES), + item_names.SIEGE_TANK, +) +parent_present[parent_names.SIEGE_TANK_AND_MEDIVAC] = AllOf((item_names.SIEGE_TANK, item_names.MEDIVAC), item_names.SIEGE_TANK) +parent_present[parent_names.SPIDER_MINE_SOURCE] = AnyOf(item_groups.spider_mine_sources, display_string='Spider Mines') +parent_present[parent_names.STARSHIP_UNITS] = AnyOf(item_groups.starport_units, display_string='Terran Starships') +parent_present[parent_names.STARSHIP_WEAPON_UNITS] = AnyOf(item_groups.starport_wa_group, display_string='Terran Starships') +parent_present[parent_names.VEHICLE_UNITS] = AnyOf(item_groups.factory_units, display_string='Terran Vehicles') +parent_present[parent_names.VEHICLE_WEAPON_UNITS] = AnyOf(item_groups.factory_wa_group, display_string='Terran Vehicles') +parent_present[parent_names.TERRAN_MERCENARIES] = AnyOf(item_groups.terran_mercenaries, display_string='Terran Mercenaries') + +# Zerg +parent_present[parent_names.ANY_NYDUS_WORM] = AnyOf((item_names.NYDUS_WORM, item_names.ECHIDNA_WORM), item_names.NYDUS_WORM) +parent_present[parent_names.BANELING_SOURCE] = AnyOf( + (item_names.ZERGLING_BANELING_ASPECT, item_names.KERRIGAN_SPAWN_BANELINGS), + item_names.ZERGLING_BANELING_ASPECT, +) +parent_present[parent_names.INFESTED_UNITS] = AnyOf(item_groups.infterr_units, display_string='Infested') +parent_present[parent_names.INFESTED_FACTORY_OR_STARPORT] = AnyOf( + (item_names.INFESTED_DIAMONDBACK, item_names.INFESTED_SIEGE_TANK, item_names.INFESTED_LIBERATOR, item_names.INFESTED_BANSHEE, item_names.BULLFROG) +) +parent_present[parent_names.MORPH_SOURCE_AIR] = MorphlingOrAnyOf((item_names.MUTALISK, item_names.CORRUPTOR), "Mutalisk/Corruptor Morphs") +parent_present[parent_names.MORPH_SOURCE_ROACH] = MorphlingOrItem(item_names.ROACH) +parent_present[parent_names.MORPH_SOURCE_ZERGLING] = MorphlingOrItem(item_names.ZERGLING) +parent_present[parent_names.MORPH_SOURCE_HYDRALISK] = MorphlingOrItem(item_names.HYDRALISK) +parent_present[parent_names.MORPH_SOURCE_ULTRALISK] = MorphlingOrItem(item_names.ULTRALISK) +parent_present[parent_names.ZERG_UPROOTABLE_BUILDINGS] = AnyOf( + (item_names.SPINE_CRAWLER, item_names.SPORE_CRAWLER, item_names.INFESTED_MISSILE_TURRET, item_names.INFESTED_BUNKER), +) +parent_present[parent_names.ZERG_MELEE_ATTACKER] = AnyOf(item_groups.zerg_melee_wa, display_string='Zerg Ground') +parent_present[parent_names.ZERG_MISSILE_ATTACKER] = AnyOf(item_groups.zerg_ranged_wa, display_string='Zerg Ground') +parent_present[parent_names.ZERG_CARAPACE_UNIT] = AnyOf(item_groups.zerg_ground_units, display_string='Zerg Flyers') +parent_present[parent_names.ZERG_FLYING_UNIT] = AnyOf(item_groups.zerg_air_units, display_string='Zerg Flyers') +parent_present[parent_names.ZERG_MERCENARIES] = AnyOf(item_groups.zerg_mercenaries, display_string='Zerg Mercenaries') +parent_present[parent_names.ZERG_OUROBOUROS_CONDITION] = AnyOfGroupAndOneOtherItem( + (item_names.ZERGLING, item_names.ROACH, item_names.HYDRALISK, item_names.ABERRATION), + item_names.ECHIDNA_WORM +) + +# Protoss +parent_present[parent_names.ARCHON_SOURCE] = AnyOf( + (item_names.HIGH_TEMPLAR, item_names.SIGNIFIER, item_names.ASCENDANT_ARCHON_MERGE, item_names.DARK_TEMPLAR_ARCHON_MERGE), + main_item="Archon", +) +parent_present[parent_names.CARRIER_CLASS] = AnyOf( + (item_names.CARRIER, item_names.TRIREME, item_names.SKYLORD), + main_item=item_names.CARRIER, +) +parent_present[parent_names.CARRIER_OR_TRIREME] = AnyOf( + (item_names.CARRIER, item_names.TRIREME), + main_item=item_names.CARRIER, +) +parent_present[parent_names.DARK_ARCHON_SOURCE] = AnyOf( + (item_names.DARK_ARCHON, item_names.DARK_TEMPLAR_DARK_ARCHON_MELD), + main_item=item_names.DARK_ARCHON, +) +parent_present[parent_names.DARK_TEMPLAR_CLASS] = AnyOf( + (item_names.DARK_TEMPLAR, item_names.AVENGER, item_names.BLOOD_HUNTER), + main_item=item_names.DARK_TEMPLAR, +) +parent_present[parent_names.STORM_CASTER] = AnyOf( + (item_names.HIGH_TEMPLAR, item_names.SIGNIFIER), + main_item=item_names.HIGH_TEMPLAR, +) +parent_present[parent_names.IMMORTAL_OR_ANNIHILATOR] = AnyOf( + (item_names.IMMORTAL, item_names.ANNIHILATOR), + main_item=item_names.IMMORTAL, +) +parent_present[parent_names.PHOENIX_CLASS] = AnyOf( + (item_names.PHOENIX, item_names.MIRAGE, item_names.SKIRMISHER), + main_item=item_names.PHOENIX, +) +parent_present[parent_names.SENTRY_CLASS] = AnyOf( + (item_names.SENTRY, item_names.ENERGIZER, item_names.HAVOC), + main_item=item_names.SENTRY, +) +parent_present[parent_names.SENTRY_CLASS_OR_SHIELD_BATTERY] = AnyOf( + (item_names.SENTRY, item_names.ENERGIZER, item_names.HAVOC, item_names.SHIELD_BATTERY), + main_item=item_names.SENTRY, +) +parent_present[parent_names.STALKER_CLASS] = AnyOf( + (item_names.STALKER, item_names.SLAYER, item_names.INSTIGATOR), + main_item=item_names.STALKER, +) +parent_present[parent_names.SUPPLICANT_AND_ASCENDANT] = AllOf( + (item_names.SUPPLICANT, item_names.ASCENDANT), + main_item=item_names.ASCENDANT, +) +parent_present[parent_names.VOID_RAY_CLASS] = AnyOf( + (item_names.VOID_RAY, item_names.DESTROYER, item_names.PULSAR, item_names.DAWNBRINGER), + main_item=item_names.VOID_RAY, +) +parent_present[parent_names.ZEALOT_OR_SENTINEL_OR_CENTURION] = AnyOf( + (item_names.ZEALOT, item_names.SENTINEL, item_names.CENTURION), + main_item=item_names.ZEALOT, +) +parent_present[parent_names.SCOUT_CLASS] = AnyOf( + (item_names.SCOUT, item_names.OPPRESSOR, item_names.CALADRIUS, item_names.MISTWING), + main_item=item_names.SCOUT, +) +parent_present[parent_names.SCOUT_OR_OPPRESSOR_OR_MISTWING] = AnyOf( + (item_names.SCOUT, item_names.OPPRESSOR, item_names.MISTWING), + main_item=item_names.SCOUT, +) +parent_present[parent_names.PROTOSS_STATIC_DEFENSE] = AnyOf( + (item_names.NEXUS_OVERCHARGE, item_names.PHOTON_CANNON, item_names.KHAYDARIN_MONOLITH, item_names.SHIELD_BATTERY), + main_item=item_names.PHOTON_CANNON, +) +parent_present[parent_names.PROTOSS_ATTACKING_BUILDING] = AnyOf( + (item_names.NEXUS_OVERCHARGE, item_names.PHOTON_CANNON, item_names.KHAYDARIN_MONOLITH), + main_item=item_names.PHOTON_CANNON, +) + + +parent_id_to_children: Dict[str, Sequence[str]] = {} +"""Parent identifier to child items. Only contains parent rules with children.""" +child_item_to_parent_items: Dict[str, Sequence[str]] = {} +"""Child item name to all parent items that can possibly affect its presence rule. Populated for all item names.""" + +parent_item_to_ids: Dict[str, Sequence[str]] = {} +"""Parent item to parent identifiers it affects. Populated for all items and parent IDs.""" +parent_item_to_children: Dict[str, Sequence[str]] = {} +"""Parent item to child item names. Populated for all items and parent IDs.""" +item_upgrade_groups: Dict[str, Sequence[str]] = {} +"""Mapping of upgradable item group -> child items. Only populated for groups with child items.""" +# Note(mm): "All items" promise satisfied by the basic ItemPresent auto-generated rules + +def _init() -> None: + for item_name, item_data in item_tables.item_table.items(): + if item_data.parent is None: + continue + parent_id_to_children.setdefault(item_data.parent, []).append(item_name) # type: ignore + child_item_to_parent_items[item_name] = parent_present[item_data.parent].parent_items() + + for parent_id, presence_func in parent_present.items(): + for parent_item in presence_func.parent_items(): + parent_item_to_ids.setdefault(parent_item, []).append(parent_id) # type: ignore + parent_item_to_children.setdefault(parent_item, []).extend(parent_id_to_children.get(parent_id, [])) # type: ignore + if presence_func.constraint_group is not None and parent_id_to_children.get(parent_id): + item_upgrade_groups.setdefault(presence_func.constraint_group, []).extend(parent_id_to_children[parent_id]) # type: ignore + +_init() diff --git a/worlds/sc2/item/item_tables.py b/worlds/sc2/item/item_tables.py new file mode 100644 index 000000000000..7fb198ea58ac --- /dev/null +++ b/worlds/sc2/item/item_tables.py @@ -0,0 +1,2415 @@ +from typing import * + +from BaseClasses import ItemClassification +import typing + +from ..mission_tables import SC2Mission, SC2Race, SC2Campaign +from ..item import parent_names, ItemData, TerranItemType, FactionlessItemType, ProtossItemType, ZergItemType +from ..mission_order.presets_static import get_used_layout_names +from . import item_names + + + +def get_full_item_list(): + return item_table + + +SC2WOL_ITEM_ID_OFFSET = 1000 +SC2HOTS_ITEM_ID_OFFSET = SC2WOL_ITEM_ID_OFFSET + 1000 +SC2LOTV_ITEM_ID_OFFSET = SC2HOTS_ITEM_ID_OFFSET + 1000 +SC2_KEY_ITEM_ID_OFFSET = SC2LOTV_ITEM_ID_OFFSET + 1000 +# Reserve this many IDs for missions, layouts, campaigns, and generic keys each +SC2_KEY_ITEM_SECTION_SIZE = 1000 + +WEAPON_ARMOR_UPGRADE_MAX_LEVEL = 5 + + +# The items are sorted by their IDs. The IDs shall be kept for compatibility with older games. +item_table = { + # WoL + item_names.MARINE: + ItemData(0 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 0, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.MEDIC: + ItemData(1 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 1, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.FIREBAT: + ItemData(2 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 2, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.MARAUDER: + ItemData(3 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 3, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.REAPER: + ItemData(4 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 4, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.HELLION: + ItemData(5 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 5, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.VULTURE: + ItemData(6 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 6, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.GOLIATH: + ItemData(7 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 7, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.DIAMONDBACK: + ItemData(8 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 8, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.SIEGE_TANK: + ItemData(9 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 9, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.MEDIVAC: + ItemData(10 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 10, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.WRAITH: + ItemData(11 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 11, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.VIKING: + ItemData(12 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 12, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.BANSHEE: + ItemData(13 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 13, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.BATTLECRUISER: + ItemData(14 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 14, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.GHOST: + ItemData(15 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 15, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.SPECTRE: + ItemData(16 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 16, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.THOR: + ItemData(17 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 17, SC2Race.TERRAN, + classification=ItemClassification.progression), + # EE units + item_names.LIBERATOR: + ItemData(18 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 18, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.VALKYRIE: + ItemData(19 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 19, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.WIDOW_MINE: + ItemData(20 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 20, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.CYCLONE: + ItemData(21 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 21, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.HERC: + ItemData(22 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 26, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.WARHOUND: + ItemData(23 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 27, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.DOMINION_TROOPER: + ItemData(24 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 4, SC2Race.TERRAN, + classification=ItemClassification.progression), + # Elites, currently disabled for balance + item_names.PRIDE_OF_AUGUSTRGRAD: + ItemData(50 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 28, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.SKY_FURY: + ItemData(51 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 29, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.SHOCK_DIVISION: + ItemData(52 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 0, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.BLACKHAMMER: + ItemData(53 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 1, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.AEGIS_GUARD: + ItemData(54 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 2, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.EMPERORS_SHADOW: + ItemData(55 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 3, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.SON_OF_KORHAL: + ItemData(56 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 5, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.BULWARK_COMPANY: + ItemData(57 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 6, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.FIELD_RESPONSE_THETA: + ItemData(58 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 7, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.EMPERORS_GUARDIAN: + ItemData(59 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 8, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NIGHT_HAWK: + ItemData(60 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 9, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NIGHT_WOLF: + ItemData(61 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit_2, 10, SC2Race.TERRAN, + classification=ItemClassification.progression), + + # Some other items are moved to Upgrade group because of the way how the bot message is parsed + item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON: ItemData(100 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, 0, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.INFANTRY_WEAPON_UNITS), + item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR: ItemData(102 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, 4, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.INFANTRY_UNITS), + item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON: ItemData(103 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, 8, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.VEHICLE_WEAPON_UNITS), + item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR: ItemData(104 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, 12, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.VEHICLE_UNITS), + item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON: ItemData(105 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, 16, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.STARSHIP_WEAPON_UNITS), + item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR: ItemData(106 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, 20, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.STARSHIP_UNITS), + # Bundles + item_names.PROGRESSIVE_TERRAN_WEAPON_UPGRADE: ItemData(107 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, -1, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_TERRAN_ARMOR_UPGRADE: ItemData(108 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, -1, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_TERRAN_INFANTRY_UPGRADE: ItemData(109 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, -1, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.INFANTRY_UNITS), + item_names.PROGRESSIVE_TERRAN_VEHICLE_UPGRADE: ItemData(110 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, -1, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.VEHICLE_UNITS), + item_names.PROGRESSIVE_TERRAN_SHIP_UPGRADE: ItemData(111 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, -1, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.STARSHIP_UNITS), + item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE: ItemData(112 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Upgrade, -1, SC2Race.TERRAN, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + + # Unit and structure upgrades + item_names.BUNKER_PROJECTILE_ACCELERATOR: + ItemData(200 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 0, SC2Race.TERRAN, + parent=item_names.BUNKER), + item_names.BUNKER_NEOSTEEL_BUNKER: + ItemData(201 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 1, SC2Race.TERRAN, + parent=item_names.BUNKER), + item_names.MISSILE_TURRET_TITANIUM_HOUSING: + ItemData(202 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 2, SC2Race.TERRAN, + parent=item_names.MISSILE_TURRET), + item_names.MISSILE_TURRET_HELLSTORM_BATTERIES: + ItemData(203 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 3, SC2Race.TERRAN, + parent=item_names.MISSILE_TURRET), + item_names.SCV_ADVANCED_CONSTRUCTION: + ItemData(204 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 4, SC2Race.TERRAN), + item_names.SCV_DUAL_FUSION_WELDERS: + ItemData(205 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 5, SC2Race.TERRAN), + item_names.PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM: + ItemData(206 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 24, SC2Race.TERRAN, + quantity=2), + item_names.PROGRESSIVE_ORBITAL_COMMAND: + ItemData(207 + SC2WOL_ITEM_ID_OFFSET, FactionlessItemType.Deprecated, -1, SC2Race.TERRAN, + quantity=0, classification=ItemClassification.progression), + item_names.MARINE_PROGRESSIVE_STIMPACK: + ItemData(208 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 0, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.MARINE, quantity=2), + item_names.MARINE_COMBAT_SHIELD: + ItemData(209 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 9, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.MARINE), + item_names.MEDIC_ADVANCED_MEDIC_FACILITIES: + ItemData(210 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 10, SC2Race.TERRAN, + parent=item_names.MEDIC), + item_names.MEDIC_STABILIZER_MEDPACKS: + ItemData(211 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 11, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.MEDIC), + item_names.FIREBAT_INCINERATOR_GAUNTLETS: + ItemData(212 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 12, SC2Race.TERRAN, + parent=item_names.FIREBAT), + item_names.FIREBAT_JUGGERNAUT_PLATING: + ItemData(213 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 13, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.FIREBAT), + item_names.MARAUDER_CONCUSSIVE_SHELLS: + ItemData(214 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 14, SC2Race.TERRAN, + parent=item_names.MARAUDER), + item_names.MARAUDER_KINETIC_FOAM: + ItemData(215 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 15, SC2Race.TERRAN, + parent=item_names.MARAUDER), + item_names.REAPER_U238_ROUNDS: + ItemData(216 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 16, SC2Race.TERRAN, + parent=item_names.REAPER), + item_names.REAPER_G4_CLUSTERBOMB: + ItemData(217 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 17, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.REAPER), + item_names.CYCLONE_MAG_FIELD_ACCELERATORS: + ItemData(218 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 18, SC2Race.TERRAN, + parent=item_names.CYCLONE), + item_names.CYCLONE_MAG_FIELD_LAUNCHERS: + ItemData(219 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 19, SC2Race.TERRAN, + parent=item_names.CYCLONE), + item_names.MARINE_LASER_TARGETING_SYSTEM: + ItemData(220 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 8, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.MARINE), + item_names.MARINE_MAGRAIL_MUNITIONS: + ItemData(221 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 20, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.MARINE), + item_names.MARINE_OPTIMIZED_LOGISTICS: + ItemData(222 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 21, SC2Race.TERRAN, + parent=item_names.MARINE), + item_names.MEDIC_RESTORATION: + ItemData(223 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 22, SC2Race.TERRAN, + parent=item_names.MEDIC), + item_names.MEDIC_OPTICAL_FLARE: + ItemData(224 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 23, SC2Race.TERRAN, + parent=item_names.MEDIC), + item_names.MEDIC_RESOURCE_EFFICIENCY: + ItemData(225 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 24, SC2Race.TERRAN, + parent=item_names.MEDIC), + item_names.FIREBAT_PROGRESSIVE_STIMPACK: + ItemData(226 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 6, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.FIREBAT, quantity=2), + item_names.FIREBAT_RESOURCE_EFFICIENCY: + ItemData(227 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 25, SC2Race.TERRAN, + parent=item_names.FIREBAT), + item_names.MARAUDER_PROGRESSIVE_STIMPACK: + ItemData(228 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 8, SC2Race.TERRAN, + parent=item_names.MARAUDER, quantity=2), + item_names.MARAUDER_LASER_TARGETING_SYSTEM: + ItemData(229 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 26, SC2Race.TERRAN, + parent=item_names.MARAUDER), + item_names.MARAUDER_MAGRAIL_MUNITIONS: + ItemData(230 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 27, SC2Race.TERRAN, + parent=item_names.MARAUDER), + item_names.MARAUDER_INTERNAL_TECH_MODULE: + ItemData(231 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 28, SC2Race.TERRAN, + parent=item_names.MARAUDER), + item_names.SCV_HOSTILE_ENVIRONMENT_ADAPTATION: + ItemData(232 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 29, SC2Race.TERRAN), + item_names.MEDIC_ADAPTIVE_MEDPACKS: + ItemData(233 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 0, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.MEDIC), + item_names.MEDIC_NANO_PROJECTOR: + ItemData(234 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 1, SC2Race.TERRAN, + parent=item_names.MEDIC), + item_names.FIREBAT_INFERNAL_PRE_IGNITER: + ItemData(235 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 2, SC2Race.TERRAN, + parent=item_names.FIREBAT), + item_names.FIREBAT_KINETIC_FOAM: + ItemData(236 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 3, SC2Race.TERRAN, + parent=item_names.FIREBAT), + item_names.FIREBAT_NANO_PROJECTORS: + ItemData(237 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 4, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.FIREBAT), + item_names.MARAUDER_JUGGERNAUT_PLATING: + ItemData(238 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 5, SC2Race.TERRAN, + parent=item_names.MARAUDER), + item_names.REAPER_JET_PACK_OVERDRIVE: + ItemData(239 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 6, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing, parent=item_names.REAPER), + item_names.HELLION_INFERNAL_PLATING: + ItemData(240 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 7, SC2Race.TERRAN, + parent=item_names.HELLION), + item_names.VULTURE_JERRYRIGGED_PATCHUP: + ItemData(241 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 8, SC2Race.TERRAN, + parent=item_names.VULTURE), + item_names.GOLIATH_SHAPED_HULL: + ItemData(242 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 9, SC2Race.TERRAN, + parent=item_names.GOLIATH), + item_names.GOLIATH_RESOURCE_EFFICIENCY: + ItemData(243 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 10, SC2Race.TERRAN, + parent=item_names.GOLIATH), + item_names.GOLIATH_INTERNAL_TECH_MODULE: + ItemData(244 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 11, SC2Race.TERRAN, + parent=item_names.GOLIATH), + item_names.SIEGE_TANK_SHAPED_HULL: + ItemData(245 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 12, SC2Race.TERRAN, + parent=item_names.SIEGE_TANK), + item_names.SIEGE_TANK_RESOURCE_EFFICIENCY: + ItemData(246 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 13, SC2Race.TERRAN, + parent=item_names.SIEGE_TANK), + item_names.PREDATOR_CLOAK: + ItemData(247 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 14, SC2Race.TERRAN, + parent=item_names.PREDATOR), + item_names.PREDATOR_CHARGE: + ItemData(248 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 15, SC2Race.TERRAN, + parent=item_names.PREDATOR), + item_names.MEDIVAC_SCATTER_VEIL: + ItemData(249 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 16, SC2Race.TERRAN, + parent=item_names.MEDIVAC), + item_names.REAPER_PROGRESSIVE_STIMPACK: + ItemData(250 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 10, SC2Race.TERRAN, + parent=item_names.REAPER, quantity=2), + item_names.REAPER_LASER_TARGETING_SYSTEM: + ItemData(251 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 17, SC2Race.TERRAN, + parent=item_names.REAPER), + item_names.REAPER_ADVANCED_CLOAKING_FIELD: + ItemData(252 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 18, SC2Race.TERRAN, + parent=item_names.REAPER), + item_names.REAPER_SPIDER_MINES: + ItemData(253 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 19, SC2Race.TERRAN, + parent=item_names.REAPER, + important_for_filtering=True), + item_names.REAPER_COMBAT_DRUGS: + ItemData(254 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 20, SC2Race.TERRAN, + parent=item_names.REAPER), + item_names.HELLION_HELLBAT: + ItemData(255 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 21, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.HELLION), + item_names.HELLION_SMART_SERVOS: + ItemData(256 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 22, SC2Race.TERRAN, + parent=item_names.HELLION), + item_names.HELLION_OPTIMIZED_LOGISTICS: + ItemData(257 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 23, SC2Race.TERRAN, + parent=item_names.HELLION), + item_names.HELLION_JUMP_JETS: + ItemData(258 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 24, SC2Race.TERRAN, + parent=item_names.HELLION), + item_names.HELLION_PROGRESSIVE_STIMPACK: + ItemData(259 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 12, SC2Race.TERRAN, + parent=item_names.HELLION, quantity=2), + item_names.VULTURE_ION_THRUSTERS: + ItemData(260 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 25, SC2Race.TERRAN, + parent=item_names.VULTURE), + item_names.VULTURE_AUTO_LAUNCHERS: + ItemData(261 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 26, SC2Race.TERRAN, + parent=item_names.VULTURE), + item_names.SPIDER_MINE_HIGH_EXPLOSIVE_MUNITION: + ItemData(262 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 27, SC2Race.TERRAN, + parent=parent_names.SPIDER_MINE_SOURCE), + item_names.GOLIATH_JUMP_JETS: + ItemData(263 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 28, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.GOLIATH), + item_names.GOLIATH_OPTIMIZED_LOGISTICS: + ItemData(264 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_2, 29, SC2Race.TERRAN, + parent=item_names.GOLIATH), + item_names.DIAMONDBACK_HYPERFLUXOR: + ItemData(265 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 0, SC2Race.TERRAN, + parent=item_names.DIAMONDBACK), + item_names.DIAMONDBACK_BURST_CAPACITORS: + ItemData(266 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 1, SC2Race.TERRAN, + parent=item_names.DIAMONDBACK), + item_names.DIAMONDBACK_RESOURCE_EFFICIENCY: + ItemData(267 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 2, SC2Race.TERRAN, + parent=item_names.DIAMONDBACK), + item_names.SIEGE_TANK_JUMP_JETS: + ItemData(268 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 3, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.SIEGE_TANK), + item_names.SIEGE_TANK_SPIDER_MINES: + ItemData(269 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 4, SC2Race.TERRAN, + parent=item_names.SIEGE_TANK, + important_for_filtering=True), + item_names.SIEGE_TANK_SMART_SERVOS: + ItemData(270 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 5, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.SIEGE_TANK), + item_names.SIEGE_TANK_GRADUATING_RANGE: + ItemData(271 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 6, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.SIEGE_TANK), + item_names.SIEGE_TANK_LASER_TARGETING_SYSTEM: + ItemData(272 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 7, SC2Race.TERRAN, + parent=item_names.SIEGE_TANK), + item_names.SIEGE_TANK_ADVANCED_SIEGE_TECH: + ItemData(273 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 8, SC2Race.TERRAN, + parent=item_names.SIEGE_TANK), + item_names.SIEGE_TANK_INTERNAL_TECH_MODULE: + ItemData(274 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 9, SC2Race.TERRAN, + parent=item_names.SIEGE_TANK), + item_names.PREDATOR_RESOURCE_EFFICIENCY: + ItemData(275 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 10, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.PREDATOR), + item_names.MEDIVAC_EXPANDED_HULL: + ItemData(276 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 11, SC2Race.TERRAN, + parent=item_names.MEDIVAC), + item_names.MEDIVAC_AFTERBURNERS: + ItemData(277 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 12, SC2Race.TERRAN, + parent=item_names.MEDIVAC), + item_names.WRAITH_ADVANCED_LASER_TECHNOLOGY: + ItemData(278 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 13, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.WRAITH), + item_names.VIKING_SMART_SERVOS: + ItemData(279 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 14, SC2Race.TERRAN, + parent=item_names.VIKING), + item_names.VIKING_ANTI_MECHANICAL_MUNITION: + ItemData(280 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 15, SC2Race.TERRAN, + parent=item_names.VIKING), + item_names.DIAMONDBACK_MAGLEV_PROPULSION: + ItemData(281 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 21, SC2Race.TERRAN, + parent=item_names.DIAMONDBACK), + item_names.WARHOUND_RESOURCE_EFFICIENCY: + ItemData(282 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 13, SC2Race.TERRAN, + parent=item_names.WARHOUND), + item_names.WARHOUND_AXIOM_PLATING: + ItemData(283 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 14, SC2Race.TERRAN, + parent=item_names.WARHOUND), + item_names.HERC_RESOURCE_EFFICIENCY: + ItemData(284 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 15, SC2Race.TERRAN, + parent=item_names.HERC), + item_names.HERC_JUGGERNAUT_PLATING: + ItemData(285 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 16, SC2Race.TERRAN, + parent=item_names.HERC), + item_names.HERC_KINETIC_FOAM: + ItemData(286 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 17, SC2Race.TERRAN, + parent=item_names.HERC), + item_names.REAPER_RESOURCE_EFFICIENCY: + ItemData(287 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 18, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.REAPER), + item_names.REAPER_BALLISTIC_FLIGHTSUIT: + ItemData(288 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 19, SC2Race.TERRAN, + parent=item_names.REAPER), + item_names.SIEGE_TANK_PROGRESSIVE_TRANSPORT_HOOK: + ItemData(289 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive_2, 6, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=parent_names.SIEGE_TANK_AND_TRANSPORT, quantity=2), + item_names.SIEGE_TANK_ALLTERRAIN_TREADS : + ItemData(290 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 20, SC2Race.TERRAN, + parent=item_names.SIEGE_TANK), + item_names.MEDIVAC_RAPID_REIGNITION_SYSTEMS: + ItemData(291 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 21, SC2Race.TERRAN, + parent=item_names.MEDIVAC), + item_names.BATTLECRUISER_BEHEMOTH_REACTOR: + ItemData(292 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 22, SC2Race.TERRAN, + parent=item_names.BATTLECRUISER), + item_names.THOR_RAPID_RELOAD: + ItemData(293 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 23, SC2Race.TERRAN, + parent=item_names.THOR), + item_names.LIBERATOR_GUERILLA_MISSILES: + ItemData(294 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 24, SC2Race.TERRAN, + parent=item_names.LIBERATOR), + item_names.WIDOW_MINE_RESOURCE_EFFICIENCY: + ItemData(295 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 25, SC2Race.TERRAN, + parent=item_names.WIDOW_MINE), + item_names.HERC_GRAPPLE_PULL: + ItemData(296 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 26, SC2Race.TERRAN, + parent=item_names.HERC), + item_names.COMMAND_CENTER_SCANNER_SWEEP: + ItemData(297 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 27, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.COMMAND_CENTER_MULE: + ItemData(298 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 28, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.COMMAND_CENTER_EXTRA_SUPPLIES: + ItemData(299 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 29, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.HELLION_TWIN_LINKED_FLAMETHROWER: + ItemData(300 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 16, SC2Race.TERRAN, + parent=item_names.HELLION), + item_names.HELLION_THERMITE_FILAMENTS: + ItemData(301 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 17, SC2Race.TERRAN, + parent=item_names.HELLION), + item_names.SPIDER_MINE_CERBERUS_MINE: + ItemData(302 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 18, SC2Race.TERRAN, + parent=parent_names.SPIDER_MINE_SOURCE), + item_names.VULTURE_PROGRESSIVE_REPLENISHABLE_MAGAZINE: + ItemData(303 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 16, SC2Race.TERRAN, + parent=item_names.VULTURE, quantity=2), + item_names.GOLIATH_MULTI_LOCK_WEAPONS_SYSTEM: + ItemData(304 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 19, SC2Race.TERRAN, + parent=item_names.GOLIATH), + item_names.GOLIATH_ARES_CLASS_TARGETING_SYSTEM: + ItemData(305 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 20, SC2Race.TERRAN, + parent=item_names.GOLIATH), + item_names.DIAMONDBACK_PROGRESSIVE_TRI_LITHIUM_POWER_CELL: + ItemData(306 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive_2, 4, SC2Race.TERRAN, + parent=item_names.DIAMONDBACK, quantity=2), + item_names.DIAMONDBACK_SHAPED_HULL: + ItemData(307 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 22, SC2Race.TERRAN, + parent=item_names.DIAMONDBACK), + item_names.SIEGE_TANK_MAELSTROM_ROUNDS: + ItemData(308 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 23, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.SIEGE_TANK), + item_names.SIEGE_TANK_SHAPED_BLAST: + ItemData(309 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 24, SC2Race.TERRAN, + parent=item_names.SIEGE_TANK), + item_names.MEDIVAC_RAPID_DEPLOYMENT_TUBE: + ItemData(310 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 25, SC2Race.TERRAN, + parent=item_names.MEDIVAC), + item_names.MEDIVAC_ADVANCED_HEALING_AI: + ItemData(311 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 26, SC2Race.TERRAN, + parent=item_names.MEDIVAC), + item_names.WRAITH_PROGRESSIVE_TOMAHAWK_POWER_CELLS: + ItemData(312 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 18, SC2Race.TERRAN, + parent=item_names.WRAITH, quantity=2), + item_names.WRAITH_DISPLACEMENT_FIELD: + ItemData(313 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 27, SC2Race.TERRAN, + parent=item_names.WRAITH), + item_names.VIKING_RIPWAVE_MISSILES: + ItemData(314 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 28, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.VIKING), + item_names.VIKING_PHOBOS_CLASS_WEAPONS_SYSTEM: + ItemData(315 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_3, 29, SC2Race.TERRAN, + parent=item_names.VIKING), + item_names.BANSHEE_PROGRESSIVE_CROSS_SPECTRUM_DAMPENERS: + ItemData(316 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 2, SC2Race.TERRAN, + parent=item_names.BANSHEE, quantity=2), + item_names.BANSHEE_SHOCKWAVE_MISSILE_BATTERY: + ItemData(317 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 0, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.BANSHEE), + item_names.BATTLECRUISER_PROGRESSIVE_MISSILE_PODS: + ItemData(318 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive_2, 2, SC2Race.TERRAN, + parent=item_names.BATTLECRUISER, quantity=2), + item_names.BATTLECRUISER_PROGRESSIVE_DEFENSIVE_MATRIX: + ItemData(319 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 20, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.BATTLECRUISER, quantity=2), + item_names.GHOST_OCULAR_IMPLANTS: + ItemData(320 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 2, SC2Race.TERRAN, + parent=item_names.GHOST), + item_names.GHOST_CRIUS_SUIT: + ItemData(321 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 3, SC2Race.TERRAN, + parent=item_names.GHOST), + item_names.SPECTRE_PSIONIC_LASH: + ItemData(322 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 4, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.SPECTRE), + item_names.SPECTRE_NYX_CLASS_CLOAKING_MODULE: + ItemData(323 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 5, SC2Race.TERRAN, + parent=item_names.SPECTRE), + item_names.THOR_330MM_BARRAGE_CANNON: + ItemData(324 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 6, SC2Race.TERRAN, + parent=item_names.THOR), + item_names.THOR_PROGRESSIVE_IMMORTALITY_PROTOCOL: + ItemData(325 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 22, SC2Race.TERRAN, + parent=item_names.THOR, quantity=2), + item_names.LIBERATOR_ADVANCED_BALLISTICS: + ItemData(326 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 7, SC2Race.TERRAN, + parent=item_names.LIBERATOR), + item_names.LIBERATOR_RAID_ARTILLERY: + ItemData(327 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 8, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.LIBERATOR), + item_names.WIDOW_MINE_DRILLING_CLAWS: + ItemData(328 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 9, SC2Race.TERRAN, + parent=item_names.WIDOW_MINE), + item_names.WIDOW_MINE_CONCEALMENT: + ItemData(329 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 10, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.WIDOW_MINE), + item_names.MEDIVAC_ADVANCED_CLOAKING_FIELD: + ItemData(330 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 11, SC2Race.TERRAN, + parent=item_names.MEDIVAC), + item_names.WRAITH_TRIGGER_OVERRIDE: + ItemData(331 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 12, SC2Race.TERRAN, + parent=item_names.WRAITH), + item_names.WRAITH_INTERNAL_TECH_MODULE: + ItemData(332 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 13, SC2Race.TERRAN, + parent=item_names.WRAITH), + item_names.WRAITH_RESOURCE_EFFICIENCY: + ItemData(333 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 14, SC2Race.TERRAN, + parent=item_names.WRAITH), + item_names.VIKING_SHREDDER_ROUNDS: + ItemData(334 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 15, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.VIKING), + item_names.VIKING_WILD_MISSILES: + ItemData(335 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 16, SC2Race.TERRAN, + parent=item_names.VIKING), + item_names.BANSHEE_SHAPED_HULL: + ItemData(336 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 17, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.BANSHEE), + item_names.BANSHEE_ADVANCED_TARGETING_OPTICS: + ItemData(337 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 18, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.BANSHEE), + item_names.BANSHEE_DISTORTION_BLASTERS: + ItemData(338 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 19, SC2Race.TERRAN, + parent=item_names.BANSHEE), + item_names.BANSHEE_ROCKET_BARRAGE: + ItemData(339 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 20, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.BANSHEE), + item_names.GHOST_RESOURCE_EFFICIENCY: + ItemData(340 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 21, SC2Race.TERRAN, + parent=item_names.GHOST), + item_names.SPECTRE_RESOURCE_EFFICIENCY: + ItemData(341 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 22, SC2Race.TERRAN, + parent=item_names.SPECTRE), + item_names.THOR_BUTTON_WITH_A_SKULL_ON_IT: + ItemData(342 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 23, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.THOR), + item_names.THOR_LASER_TARGETING_SYSTEM: + ItemData(343 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 24, SC2Race.TERRAN, + parent=item_names.THOR), + item_names.THOR_LARGE_SCALE_FIELD_CONSTRUCTION: + ItemData(344 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 25, SC2Race.TERRAN, + parent=item_names.THOR), + item_names.RAVEN_RESOURCE_EFFICIENCY: + ItemData(345 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 26, SC2Race.TERRAN, + parent=item_names.RAVEN), + item_names.RAVEN_DURABLE_MATERIALS: + ItemData(346 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 27, SC2Race.TERRAN, + parent=item_names.RAVEN), + item_names.SCIENCE_VESSEL_IMPROVED_NANO_REPAIR: + ItemData(347 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 28, SC2Race.TERRAN, + parent=item_names.SCIENCE_VESSEL), + item_names.SCIENCE_VESSEL_MAGELLAN_COMPUTATION_SYSTEMS: + ItemData(348 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 29, SC2Race.TERRAN, + parent=item_names.SCIENCE_VESSEL), + item_names.CYCLONE_RESOURCE_EFFICIENCY: + ItemData(349 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 0, SC2Race.TERRAN, + parent=item_names.CYCLONE), + item_names.BANSHEE_HYPERFLIGHT_ROTORS: + ItemData(350 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 1, SC2Race.TERRAN, + parent=item_names.BANSHEE), + item_names.BANSHEE_LASER_TARGETING_SYSTEM: + ItemData(351 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 2, SC2Race.TERRAN, + parent=item_names.BANSHEE), + item_names.BANSHEE_INTERNAL_TECH_MODULE: + ItemData(352 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 3, SC2Race.TERRAN, + parent=item_names.BANSHEE), + item_names.BATTLECRUISER_TACTICAL_JUMP: + ItemData(353 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 4, SC2Race.TERRAN, + parent=item_names.BATTLECRUISER), + item_names.BATTLECRUISER_CLOAK: + ItemData(354 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 5, SC2Race.TERRAN, + parent=item_names.BATTLECRUISER), + item_names.BATTLECRUISER_ATX_LASER_BATTERY: + ItemData(355 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 6, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.BATTLECRUISER), + item_names.BATTLECRUISER_OPTIMIZED_LOGISTICS: + ItemData(356 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 7, SC2Race.TERRAN, + parent=item_names.BATTLECRUISER), + item_names.BATTLECRUISER_INTERNAL_TECH_MODULE: + ItemData(357 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 8, SC2Race.TERRAN, + parent=item_names.BATTLECRUISER), + item_names.GHOST_EMP_ROUNDS: + ItemData(358 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 9, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.GHOST), + item_names.GHOST_LOCKDOWN: + ItemData(359 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 10, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.GHOST), + item_names.SPECTRE_IMPALER_ROUNDS: + ItemData(360 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 11, SC2Race.TERRAN, + parent=item_names.SPECTRE), + item_names.THOR_PROGRESSIVE_HIGH_IMPACT_PAYLOAD: + ItemData(361 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 14, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.THOR, quantity=2), + item_names.RAVEN_BIO_MECHANICAL_REPAIR_DRONE: + ItemData(363 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 12, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.RAVEN), + item_names.RAVEN_SPIDER_MINES: + ItemData(364 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 13, SC2Race.TERRAN, + parent=item_names.RAVEN, important_for_filtering=True), + item_names.RAVEN_RAILGUN_TURRET: + ItemData(365 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 14, SC2Race.TERRAN, + parent=item_names.RAVEN), + item_names.RAVEN_HUNTER_SEEKER_WEAPON: + ItemData(366 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 15, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.RAVEN), + item_names.RAVEN_INTERFERENCE_MATRIX: + ItemData(367 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 16, SC2Race.TERRAN, + parent=item_names.RAVEN), + item_names.RAVEN_ANTI_ARMOR_MISSILE: + ItemData(368 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 17, SC2Race.TERRAN, + parent=item_names.RAVEN), + item_names.RAVEN_INTERNAL_TECH_MODULE: + ItemData(369 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 18, SC2Race.TERRAN, + parent=item_names.RAVEN), + item_names.SCIENCE_VESSEL_EMP_SHOCKWAVE: + ItemData(370 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 19, SC2Race.TERRAN, + parent=item_names.SCIENCE_VESSEL), + item_names.SCIENCE_VESSEL_DEFENSIVE_MATRIX: + ItemData(371 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 20, SC2Race.TERRAN, + parent=item_names.SCIENCE_VESSEL), + item_names.CYCLONE_TARGETING_OPTICS: + ItemData(372 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 21, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.CYCLONE), + item_names.CYCLONE_RAPID_FIRE_LAUNCHERS: + ItemData(373 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 22, SC2Race.TERRAN, + parent=item_names.CYCLONE), + item_names.LIBERATOR_CLOAK: + ItemData(374 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 23, SC2Race.TERRAN, + parent=item_names.LIBERATOR), + item_names.LIBERATOR_LASER_TARGETING_SYSTEM: + ItemData(375 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 24, SC2Race.TERRAN, + parent=item_names.LIBERATOR), + item_names.LIBERATOR_OPTIMIZED_LOGISTICS: + ItemData(376 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 25, SC2Race.TERRAN, + parent=item_names.LIBERATOR), + item_names.WIDOW_MINE_BLACK_MARKET_LAUNCHERS: + ItemData(377 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 26, SC2Race.TERRAN, + parent=item_names.WIDOW_MINE), + item_names.WIDOW_MINE_EXECUTIONER_MISSILES: + ItemData(378 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 27, SC2Race.TERRAN, + parent=item_names.WIDOW_MINE), + item_names.VALKYRIE_ENHANCED_CLUSTER_LAUNCHERS: + ItemData(379 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 28, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.VALKYRIE), + item_names.VALKYRIE_SHAPED_HULL: + ItemData(380 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_5, 29, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.VALKYRIE), + item_names.VALKYRIE_FLECHETTE_MISSILES: + ItemData(381 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 0, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.VALKYRIE), + item_names.VALKYRIE_AFTERBURNERS: + ItemData(382 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 1, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.VALKYRIE), + item_names.CYCLONE_INTERNAL_TECH_MODULE: + ItemData(383 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 2, SC2Race.TERRAN, + parent=item_names.CYCLONE), + item_names.LIBERATOR_SMART_SERVOS: + ItemData(384 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 3, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.LIBERATOR), + item_names.LIBERATOR_RESOURCE_EFFICIENCY: + ItemData(385 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 4, SC2Race.TERRAN, + parent=item_names.LIBERATOR), + item_names.HERCULES_INTERNAL_FUSION_MODULE: + ItemData(386 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 5, SC2Race.TERRAN, + parent=item_names.HERCULES), + item_names.HERCULES_TACTICAL_JUMP: + ItemData(387 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 6, SC2Race.TERRAN, + parent=item_names.HERCULES), + item_names.PLANETARY_FORTRESS_PROGRESSIVE_AUGMENTED_THRUSTERS: + ItemData(388 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 28, SC2Race.TERRAN, + parent=item_names.PLANETARY_FORTRESS, quantity=2), + item_names.PLANETARY_FORTRESS_IBIKS_TRACKING_SCANNERS: + ItemData(389 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 7, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.PLANETARY_FORTRESS), + item_names.VALKYRIE_LAUNCHING_VECTOR_COMPENSATOR: + ItemData(390 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 8, SC2Race.TERRAN, + parent=item_names.VALKYRIE), + item_names.VALKYRIE_RESOURCE_EFFICIENCY: + ItemData(391 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 9, SC2Race.TERRAN, + parent=item_names.VALKYRIE), + item_names.PREDATOR_VESPENE_SYNTHESIS: + ItemData(392 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 10, SC2Race.TERRAN, + parent=item_names.PREDATOR), + item_names.BATTLECRUISER_BEHEMOTH_PLATING: + ItemData(393 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 11, SC2Race.TERRAN, + parent=item_names.BATTLECRUISER), + item_names.BATTLECRUISER_MOIRAI_IMPULSE_DRIVE: + ItemData(394 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_6, 12, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.BATTLECRUISER), + item_names.PLANETARY_FORTRESS_ORBITAL_MODULE: + ItemData(395 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_4, 1, SC2Race.TERRAN, + parent=parent_names.ORBITAL_COMMAND_AND_PLANETARY), + item_names.DEVASTATOR_TURRET_CONCUSSIVE_GRENADES: + ItemData(396 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 0, SC2Race.TERRAN, + parent=item_names.DEVASTATOR_TURRET), + item_names.DEVASTATOR_TURRET_ANTI_ARMOR_MUNITIONS: + ItemData(397 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 1, SC2Race.TERRAN, + parent=item_names.DEVASTATOR_TURRET), + item_names.DEVASTATOR_TURRET_RESOURCE_EFFICIENCY: + ItemData(398 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 2, SC2Race.TERRAN, + parent=item_names.DEVASTATOR_TURRET), + item_names.MISSILE_TURRET_RESOURCE_EFFICENCY: + ItemData(399 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 3, SC2Race.TERRAN, + parent=item_names.MISSILE_TURRET), + # Note(mm): WoL ID 400 collides with buildings; jump forward to leave buildings room + + #Buildings + item_names.BUNKER: + ItemData(400 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Building, 0, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.MISSILE_TURRET: + ItemData(401 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Building, 1, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.SENSOR_TOWER: + ItemData(402 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Building, 2, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.DEVASTATOR_TURRET: + ItemData(403 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Building, 7, SC2Race.TERRAN, + classification=ItemClassification.progression), + + item_names.WAR_PIGS: + ItemData(500 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 0, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.DEVIL_DOGS: + ItemData(501 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 1, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.HAMMER_SECURITIES: + ItemData(502 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 2, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.SPARTAN_COMPANY: + ItemData(503 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 3, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.SIEGE_BREAKERS: + ItemData(504 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 4, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.HELS_ANGELS: + ItemData(505 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 5, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.DUSK_WINGS: + ItemData(506 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 6, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.JACKSONS_REVENGE: + ItemData(507 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 7, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.SKIBIS_ANGELS: + ItemData(508 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 8, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.DEATH_HEADS: + ItemData(509 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 9, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.WINGED_NIGHTMARES: + ItemData(510 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 10, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.MIDNIGHT_RIDERS: + ItemData(511 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 11, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.BRYNHILDS: + ItemData(512 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 12, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + item_names.JOTUN: + ItemData(513 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Mercenary, 13, SC2Race.TERRAN, + classification=ItemClassification.progression_skip_balancing), + + item_names.ULTRA_CAPACITORS: + ItemData(600 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 0, SC2Race.TERRAN), + item_names.VANADIUM_PLATING: + ItemData(601 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 1, SC2Race.TERRAN), + item_names.ORBITAL_DEPOTS: + ItemData(602 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 2, SC2Race.TERRAN, classification=ItemClassification.progression), + item_names.MICRO_FILTERING: + ItemData(603 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 3, SC2Race.TERRAN, classification=ItemClassification.progression), + item_names.AUTOMATED_REFINERY: + ItemData(604 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 4, SC2Race.TERRAN, classification=ItemClassification.progression), + item_names.COMMAND_CENTER_COMMAND_CENTER_REACTOR: + ItemData(605 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 5, SC2Race.TERRAN, classification=ItemClassification.progression), + item_names.RAVEN: + ItemData(606 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 22, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.SCIENCE_VESSEL: + ItemData(607 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 23, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.TECH_REACTOR: + ItemData(608 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 6, SC2Race.TERRAN, classification=ItemClassification.progression), + item_names.ORBITAL_STRIKE: + ItemData(609 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 7, SC2Race.TERRAN, + parent=parent_names.INFANTRY_UNITS), + item_names.BUNKER_SHRIKE_TURRET: + ItemData(610 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 6, SC2Race.TERRAN, + parent=item_names.BUNKER), + item_names.BUNKER_FORTIFIED_BUNKER: + ItemData(611 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_1, 7, SC2Race.TERRAN, + parent=item_names.BUNKER), + item_names.PLANETARY_FORTRESS: + ItemData(612 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Building, 3, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.PERDITION_TURRET: + ItemData(613 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Building, 4, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.PREDATOR: + ItemData(614 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 24, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.HERCULES: + ItemData(615 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Unit, 25, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.CELLULAR_REACTOR: + ItemData(616 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 8, SC2Race.TERRAN), + item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL: + ItemData(617 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive, 4, SC2Race.TERRAN, quantity=3, + classification= ItemClassification.progression), + item_names.HIVE_MIND_EMULATOR: + ItemData(618 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 21, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.PSI_DISRUPTER: + ItemData(619 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 18, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.STRUCTURE_ARMOR: + ItemData(620 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 9, SC2Race.TERRAN), + item_names.HI_SEC_AUTO_TRACKING: + ItemData(621 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 10, SC2Race.TERRAN), + item_names.ADVANCED_OPTICS: + ItemData(622 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 11, SC2Race.TERRAN), + item_names.ROGUE_FORCES: + ItemData(623 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 12, SC2Race.TERRAN, classification=ItemClassification.progression, parent=parent_names.TERRAN_MERCENARIES), + item_names.MECHANICAL_KNOW_HOW: + ItemData(624 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 13, SC2Race.TERRAN), + item_names.MERCENARY_MUNITIONS: + ItemData(625 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 14, SC2Race.TERRAN), + item_names.PROGRESSIVE_FAST_DELIVERY: + ItemData(626 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive_2, 8, SC2Race.TERRAN, quantity=2, classification=ItemClassification.progression, parent=parent_names.TERRAN_MERCENARIES), + item_names.RAPID_REINFORCEMENT: + ItemData(627 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 16, SC2Race.TERRAN, classification=ItemClassification.progression, parent=parent_names.TERRAN_MERCENARIES), + item_names.FUSION_CORE_FUSION_REACTOR: + ItemData(628 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 17, SC2Race.TERRAN), + item_names.SONIC_DISRUPTER: + ItemData(629 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 19, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.PSI_SCREEN: + ItemData(630 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 20, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.ARGUS_AMPLIFIER: + ItemData(631 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 22, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.PSI_INDOCTRINATOR: + ItemData(632 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 23, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.SIGNAL_BEACON: + ItemData(633 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Laboratory, 24, SC2Race.TERRAN, parent=parent_names.TERRAN_MERCENARIES), + + # WoL Protoss takes SC2WOL + 700~708 + + item_names.SCIENCE_VESSEL_TACTICAL_JUMP: + ItemData(750 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 4, SC2Race.TERRAN, + parent=item_names.SCIENCE_VESSEL), + item_names.LIBERATOR_UED_MISSILE_TECHNOLOGY: + ItemData(751 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 5, SC2Race.TERRAN, + parent=item_names.LIBERATOR), + item_names.BATTLECRUISER_FIELD_ASSIST_TARGETING_SYSTEM: + ItemData(752 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 6, SC2Race.TERRAN, + parent=item_names.BATTLECRUISER), + item_names.PREDATOR_ADAPTIVE_DEFENSES: + ItemData(753 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 7, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.PREDATOR), + item_names.VIKING_AESIR_TURBINES: + ItemData(754 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 8, SC2Race.TERRAN, + parent=item_names.VIKING), + item_names.MEDIVAC_RESOURCE_EFFICIENCY: + ItemData(755 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 9, SC2Race.TERRAN, + parent=item_names.MEDIVAC), + item_names.EMPERORS_SHADOW_SOVEREIGN_TACTICAL_MISSILES: + ItemData(756 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 10, SC2Race.TERRAN, + parent=item_names.EMPERORS_SHADOW), + item_names.DOMINION_TROOPER_B2_HIGH_CAL_LMG: + ItemData(757 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 11, SC2Race.TERRAN, + parent=item_names.DOMINION_TROOPER, important_for_filtering=True), + item_names.DOMINION_TROOPER_HAILSTORM_LAUNCHER: + ItemData(758 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 12, SC2Race.TERRAN, + parent=item_names.DOMINION_TROOPER, important_for_filtering=True), + item_names.DOMINION_TROOPER_CPO7_SALAMANDER_FLAMETHROWER: + ItemData(759 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 13, SC2Race.TERRAN, + parent=item_names.DOMINION_TROOPER, important_for_filtering=True), + item_names.DOMINION_TROOPER_ADVANCED_ALLOYS: + ItemData(760 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 14, SC2Race.TERRAN, + parent=parent_names.DOMINION_TROOPER_WEAPONS), + item_names.DOMINION_TROOPER_OPTIMIZED_LOGISTICS: + ItemData(761 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 15, SC2Race.TERRAN, + parent=item_names.DOMINION_TROOPER), + item_names.SCV_CONSTRUCTION_JUMP_JETS: + ItemData(762 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 16, SC2Race.TERRAN), + item_names.WIDOW_MINE_DEMOLITION_PAYLOAD: + ItemData(763 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 17, SC2Race.TERRAN, + classification=ItemClassification.progression, parent=item_names.WIDOW_MINE), + item_names.SENSOR_TOWER_ASSISTIVE_TARGETING: + ItemData(764 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 18, SC2Race.TERRAN, + parent=item_names.SENSOR_TOWER), + item_names.SENSOR_TOWER_MUILTISPECTRUM_DOPPLER: + ItemData(765 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 19, SC2Race.TERRAN, + parent=item_names.SENSOR_TOWER), + item_names.WARHOUND_DEPLOY_TURRET: + ItemData(766 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 20, SC2Race.TERRAN, + parent=item_names.WARHOUND), + item_names.GHOST_BARGAIN_BIN_PRICES: + ItemData(767 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 21, SC2Race.TERRAN, + parent=item_names.GHOST), + item_names.SPECTRE_BARGAIN_BIN_PRICES: + ItemData(768 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Armory_7, 22, SC2Race.TERRAN, + parent=item_names.SPECTRE), + + # Filler items to fill remaining spots + item_names.STARTING_MINERALS: + ItemData(800 + SC2WOL_ITEM_ID_OFFSET, FactionlessItemType.Minerals, -1, SC2Race.ANY, quantity=0, + classification=ItemClassification.filler), + item_names.STARTING_VESPENE: + ItemData(801 + SC2WOL_ITEM_ID_OFFSET, FactionlessItemType.Vespene, -1, SC2Race.ANY, quantity=0, + classification=ItemClassification.filler), + item_names.STARTING_SUPPLY: + ItemData(802 + SC2WOL_ITEM_ID_OFFSET, FactionlessItemType.Supply, -1, SC2Race.ANY, quantity=0, + classification=ItemClassification.filler), + # This item is used to "remove" location from the game. Never placed unless plando'd + item_names.NOTHING: + ItemData(803 + SC2WOL_ITEM_ID_OFFSET, FactionlessItemType.Nothing, -1, SC2Race.ANY, quantity=0, + classification=ItemClassification.trap), + item_names.MAX_SUPPLY: + ItemData(804 + SC2WOL_ITEM_ID_OFFSET, FactionlessItemType.MaxSupply, -1, SC2Race.ANY, quantity=0, + classification=ItemClassification.filler), + item_names.SHIELD_REGENERATION: + ItemData(805 + SC2WOL_ITEM_ID_OFFSET, ProtossItemType.ShieldRegeneration, 1, SC2Race.PROTOSS, quantity=0, + classification=ItemClassification.filler), + item_names.BUILDING_CONSTRUCTION_SPEED: + ItemData(806 + SC2WOL_ITEM_ID_OFFSET, FactionlessItemType.BuildingSpeed, 1, SC2Race.ANY, quantity=0, + classification=ItemClassification.filler), + item_names.UPGRADE_RESEARCH_SPEED: + ItemData(807 + SC2WOL_ITEM_ID_OFFSET, FactionlessItemType.ResearchSpeed, 1, SC2Race.ANY, quantity=0, + classification=ItemClassification.filler), + item_names.UPGRADE_RESEARCH_COST: + ItemData(808 + SC2WOL_ITEM_ID_OFFSET, FactionlessItemType.ResearchCost, 1, SC2Race.ANY, quantity=0, + classification=ItemClassification.filler), + + # Trap Filler + item_names.REDUCED_MAX_SUPPLY: + ItemData(850 + SC2WOL_ITEM_ID_OFFSET, FactionlessItemType.MaxSupplyTrap, -1, SC2Race.ANY, quantity=0, + classification=ItemClassification.trap), + + + # Nova gear + item_names.NOVA_GHOST_VISOR: + ItemData(900 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 0, SC2Race.TERRAN, classification=ItemClassification.progression), + item_names.NOVA_RANGEFINDER_OCULUS: + ItemData(901 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 1, SC2Race.TERRAN), + item_names.NOVA_DOMINATION: + ItemData(902 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 2, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_BLINK: + ItemData(903 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 3, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE: + ItemData(904 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Progressive_2, 0, SC2Race.TERRAN, quantity=2, + classification=ItemClassification.progression), + item_names.NOVA_ENERGY_SUIT_MODULE: + ItemData(905 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 4, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_ARMORED_SUIT_MODULE: + ItemData(906 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 5, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_JUMP_SUIT_MODULE: + ItemData(907 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 6, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_C20A_CANISTER_RIFLE: + ItemData(908 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 7, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_HELLFIRE_SHOTGUN: + ItemData(909 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 8, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_PLASMA_RIFLE: + ItemData(910 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 9, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_MONOMOLECULAR_BLADE: + ItemData(911 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 10, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_BLAZEFIRE_GUNBLADE: + ItemData(912 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 11, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_STIM_INFUSION: + ItemData(913 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 12, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_PULSE_GRENADES: + ItemData(914 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 13, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_FLASHBANG_GRENADES: + ItemData(915 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 14, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_IONIC_FORCE_FIELD: + ItemData(916 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 15, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_HOLO_DECOY: + ItemData(917 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 16, SC2Race.TERRAN, + classification=ItemClassification.progression), + item_names.NOVA_NUKE: + ItemData(918 + SC2WOL_ITEM_ID_OFFSET, TerranItemType.Nova_Gear, 17, SC2Race.TERRAN, + classification=ItemClassification.progression), + + # HotS + item_names.ZERGLING: + ItemData(0 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 0, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.SWARM_QUEEN: + ItemData(1 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 1, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.ROACH: + ItemData(2 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 2, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.HYDRALISK: + ItemData(3 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 3, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.ZERGLING_BANELING_ASPECT: + ItemData(4 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 5, SC2Race.ZERG, + classification=ItemClassification.progression, parent=parent_names.MORPH_SOURCE_ZERGLING), + item_names.ABERRATION: + ItemData(5 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 5, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.MUTALISK: + ItemData(6 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 6, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.SWARM_HOST: + ItemData(7 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 7, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.INFESTOR: + ItemData(8 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 8, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.ULTRALISK: + ItemData(9 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 9, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.SPORE_CRAWLER: + ItemData(10 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 10, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.SPINE_CRAWLER: + ItemData(11 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 11, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.CORRUPTOR: + ItemData(12 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 12, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.SCOURGE: + ItemData(13 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 13, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.BROOD_QUEEN: + ItemData(14 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 4, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.DEFILER: + ItemData(15 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 14, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.INFESTED_MARINE: + ItemData(16 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 15, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.INFESTED_BUNKER: + ItemData(17 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 16, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.NYDUS_WORM: + ItemData(18 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 17, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.ECHIDNA_WORM: + ItemData(19 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 18, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.INFESTED_SIEGE_TANK: + ItemData(20 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 19, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.INFESTED_DIAMONDBACK: + ItemData(21 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 20, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.INFESTED_BANSHEE: + ItemData(22 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 21, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.INFESTED_LIBERATOR: + ItemData(23 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 22, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.INFESTED_MISSILE_TURRET: + ItemData(24 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 23, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.PYGALISK: + ItemData(25 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 24, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.BILE_LAUNCHER: + ItemData(26 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 25, SC2Race.ZERG, + classification=ItemClassification.progression), + item_names.BULLFROG: + ItemData(27 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Unit, 26, SC2Race.ZERG, + classification=ItemClassification.progression), + + item_names.PROGRESSIVE_ZERG_MELEE_ATTACK: ItemData(100 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Upgrade, 0, SC2Race.ZERG, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.ZERG_MELEE_ATTACKER), + item_names.PROGRESSIVE_ZERG_MISSILE_ATTACK: ItemData(101 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Upgrade, 4, SC2Race.ZERG, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.ZERG_MISSILE_ATTACKER), + item_names.PROGRESSIVE_ZERG_GROUND_CARAPACE: ItemData(102 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Upgrade, 8, SC2Race.ZERG, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.ZERG_CARAPACE_UNIT), + item_names.PROGRESSIVE_ZERG_FLYER_ATTACK: ItemData(103 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Upgrade, 12, SC2Race.ZERG, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.ZERG_FLYING_UNIT), + item_names.PROGRESSIVE_ZERG_FLYER_CARAPACE: ItemData(104 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Upgrade, 16, SC2Race.ZERG, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.ZERG_FLYING_UNIT), + # Bundles + item_names.PROGRESSIVE_ZERG_WEAPON_UPGRADE: ItemData(105 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Upgrade, -1, SC2Race.ZERG, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_ZERG_ARMOR_UPGRADE: ItemData(106 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Upgrade, -1, SC2Race.ZERG, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_ZERG_GROUND_UPGRADE: ItemData(107 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Upgrade, -1, SC2Race.ZERG, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.ZERG_CARAPACE_UNIT), + item_names.PROGRESSIVE_ZERG_FLYER_UPGRADE: ItemData(108 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Upgrade, -1, SC2Race.ZERG, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL, parent=parent_names.ZERG_FLYING_UNIT), + item_names.PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE: ItemData(109 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Upgrade, -1, SC2Race.ZERG, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + + item_names.ZERGLING_HARDENED_CARAPACE: + ItemData(200 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 0, SC2Race.ZERG, parent=item_names.ZERGLING), + item_names.ZERGLING_ADRENAL_OVERLOAD: + ItemData(201 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 1, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ZERGLING), + item_names.ZERGLING_METABOLIC_BOOST: + ItemData(202 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 2, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ZERGLING), + item_names.ROACH_HYDRIODIC_BILE: + ItemData(203 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 3, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ROACH), + item_names.ROACH_ADAPTIVE_PLATING: + ItemData(204 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 4, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ROACH), + item_names.ROACH_TUNNELING_CLAWS: + ItemData(205 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 5, SC2Race.ZERG, parent=item_names.ROACH), + item_names.HYDRALISK_FRENZY: + ItemData(206 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 6, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.HYDRALISK), + item_names.HYDRALISK_ANCILLARY_CARAPACE: + ItemData(207 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 7, SC2Race.ZERG, parent=item_names.HYDRALISK), + item_names.HYDRALISK_GROOVED_SPINES: + ItemData(208 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 8, SC2Race.ZERG, parent=item_names.HYDRALISK), + item_names.BANELING_CORROSIVE_ACID: + ItemData(209 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 9, SC2Race.ZERG, + classification=ItemClassification.progression, parent=parent_names.BANELING_SOURCE), + item_names.BANELING_RUPTURE: + ItemData(210 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 10, SC2Race.ZERG, + parent=parent_names.BANELING_SOURCE), + item_names.BANELING_REGENERATIVE_ACID: + ItemData(211 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 11, SC2Race.ZERG, + parent=parent_names.BANELING_SOURCE), + item_names.MUTALISK_VICIOUS_GLAIVE: + ItemData(212 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 12, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.MUTALISK), + item_names.MUTALISK_RAPID_REGENERATION: + ItemData(213 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 13, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.MUTALISK), + item_names.MUTALISK_SUNDERING_GLAIVE: + ItemData(214 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 14, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.MUTALISK), + item_names.SWARM_HOST_BURROW: + ItemData(215 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 15, SC2Race.ZERG, parent=item_names.SWARM_HOST), + item_names.SWARM_HOST_RAPID_INCUBATION: + ItemData(216 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 16, SC2Race.ZERG, parent=item_names.SWARM_HOST), + item_names.SWARM_HOST_PRESSURIZED_GLANDS: + ItemData(217 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 17, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.SWARM_HOST), + item_names.ULTRALISK_BURROW_CHARGE: + ItemData(218 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 18, SC2Race.ZERG, parent=item_names.ULTRALISK), + item_names.ULTRALISK_TISSUE_ASSIMILATION: + ItemData(219 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 19, SC2Race.ZERG, parent=item_names.ULTRALISK), + item_names.ULTRALISK_MONARCH_BLADES: + ItemData(220 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 20, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ULTRALISK), + item_names.CORRUPTOR_CAUSTIC_SPRAY: + ItemData(221 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 21, SC2Race.ZERG, parent=item_names.CORRUPTOR), + item_names.CORRUPTOR_CORRUPTION: + ItemData(222 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 22, SC2Race.ZERG, parent=item_names.CORRUPTOR), + item_names.SCOURGE_VIRULENT_SPORES: + ItemData(223 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 23, SC2Race.ZERG, parent=item_names.SCOURGE), + item_names.SCOURGE_RESOURCE_EFFICIENCY: + ItemData(224 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 24, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.SCOURGE), + item_names.SCOURGE_SWARM_SCOURGE: + ItemData(225 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 25, SC2Race.ZERG, parent=item_names.SCOURGE), + item_names.ZERGLING_SHREDDING_CLAWS: + ItemData(226 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 26, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ZERGLING), + item_names.ROACH_GLIAL_RECONSTITUTION: + ItemData(227 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 27, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ROACH), + item_names.ROACH_ORGANIC_CARAPACE: + ItemData(228 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 28, SC2Race.ZERG, parent=item_names.ROACH), + item_names.HYDRALISK_MUSCULAR_AUGMENTS: + ItemData(229 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_1, 29, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.HYDRALISK), + item_names.HYDRALISK_RESOURCE_EFFICIENCY: + ItemData(230 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 0, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.HYDRALISK), + item_names.BANELING_CENTRIFUGAL_HOOKS: + ItemData(231 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 1, SC2Race.ZERG, + parent=parent_names.BANELING_SOURCE), + item_names.BANELING_TUNNELING_JAWS: + ItemData(232 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 2, SC2Race.ZERG, + parent=parent_names.BANELING_SOURCE), + item_names.BANELING_RAPID_METAMORPH: + ItemData(233 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 3, SC2Race.ZERG, + parent=item_names.ZERGLING_BANELING_ASPECT), + item_names.MUTALISK_SEVERING_GLAIVE: + ItemData(234 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 4, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.MUTALISK), + item_names.MUTALISK_AERODYNAMIC_GLAIVE_SHAPE: + ItemData(235 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 5, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.MUTALISK), + item_names.SWARM_HOST_LOCUST_METABOLIC_BOOST: + ItemData(236 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 6, SC2Race.ZERG, parent=item_names.SWARM_HOST), + item_names.SWARM_HOST_ENDURING_LOCUSTS: + ItemData(237 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 7, SC2Race.ZERG, parent=item_names.SWARM_HOST), + item_names.SWARM_HOST_ORGANIC_CARAPACE: + ItemData(238 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 8, SC2Race.ZERG, parent=item_names.SWARM_HOST), + item_names.SWARM_HOST_RESOURCE_EFFICIENCY: + ItemData(239 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 9, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing, parent=item_names.SWARM_HOST), + item_names.ULTRALISK_ANABOLIC_SYNTHESIS: + ItemData(240 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 10, SC2Race.ZERG, parent=item_names.ULTRALISK), + item_names.ULTRALISK_CHITINOUS_PLATING: + ItemData(241 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 11, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ULTRALISK), + item_names.ULTRALISK_ORGANIC_CARAPACE: + ItemData(242 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 12, SC2Race.ZERG, parent=item_names.ULTRALISK), + item_names.ULTRALISK_RESOURCE_EFFICIENCY: + ItemData(243 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 13, SC2Race.ZERG, parent=item_names.ULTRALISK), + item_names.DEVOURER_CORROSIVE_SPRAY: + ItemData(244 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 14, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_DEVOURER_ASPECT), + item_names.DEVOURER_GAPING_MAW: + ItemData(245 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 15, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_DEVOURER_ASPECT), + item_names.DEVOURER_IMPROVED_OSMOSIS: + ItemData(246 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 16, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_DEVOURER_ASPECT), + item_names.DEVOURER_PRESCIENT_SPORES: + ItemData(247 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 17, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_DEVOURER_ASPECT, + classification=ItemClassification.progression), + item_names.GUARDIAN_PROLONGED_DISPERSION: + ItemData(248 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 18, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT), + item_names.GUARDIAN_PRIMAL_ADAPTATION: + ItemData(249 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 19, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT, + classification=ItemClassification.progression), + item_names.GUARDIAN_SORONAN_ACID: + ItemData(250 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 20, SC2Race.ZERG, + classification=ItemClassification.progression, parent=item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT), + item_names.IMPALER_ADAPTIVE_TALONS: + ItemData(251 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 21, SC2Race.ZERG, + parent=item_names.HYDRALISK_IMPALER_ASPECT), + item_names.IMPALER_SECRETION_GLANDS: + ItemData(252 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 22, SC2Race.ZERG, + parent=item_names.HYDRALISK_IMPALER_ASPECT), + item_names.IMPALER_SUNKEN_SPINES: + ItemData(253 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 23, SC2Race.ZERG, + classification=ItemClassification.progression, parent=item_names.HYDRALISK_IMPALER_ASPECT), + item_names.LURKER_SEISMIC_SPINES: + ItemData(254 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 24, SC2Race.ZERG, + classification=ItemClassification.progression, parent=item_names.HYDRALISK_LURKER_ASPECT), + item_names.LURKER_ADAPTED_SPINES: + ItemData(255 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 25, SC2Race.ZERG, + classification=ItemClassification.progression, parent=item_names.HYDRALISK_LURKER_ASPECT), + item_names.RAVAGER_POTENT_BILE: + ItemData(256 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 26, SC2Race.ZERG, + parent=item_names.ROACH_RAVAGER_ASPECT), + item_names.RAVAGER_BLOATED_BILE_DUCTS: + ItemData(257 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 27, SC2Race.ZERG, + parent=item_names.ROACH_RAVAGER_ASPECT), + item_names.RAVAGER_DEEP_TUNNEL: + ItemData(258 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 28, SC2Race.ZERG, + classification=ItemClassification.progression_skip_balancing, parent=item_names.ROACH_RAVAGER_ASPECT), + item_names.VIPER_PARASITIC_BOMB: + ItemData(259 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_2, 29, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT, + classification=ItemClassification.progression), + item_names.VIPER_PARALYTIC_BARBS: + ItemData(260 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 0, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT), + item_names.VIPER_VIRULENT_MICROBES: + ItemData(261 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 1, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT), + item_names.BROOD_LORD_POROUS_CARTILAGE: + ItemData(262 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 2, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT), + item_names.BROOD_LORD_BEHEMOTH_STELLARSKIN: + ItemData(263 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 3, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT), + item_names.BROOD_LORD_SPLITTER_MITOSIS: + ItemData(264 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 4, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT), + item_names.BROOD_LORD_RESOURCE_EFFICIENCY: + ItemData(265 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 5, SC2Race.ZERG, + parent=item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT), + item_names.INFESTOR_INFESTED_TERRAN: + ItemData(266 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 6, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.INFESTOR), + item_names.INFESTOR_MICROBIAL_SHROUD: + ItemData(267 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 7, SC2Race.ZERG, parent=item_names.INFESTOR), + item_names.SWARM_QUEEN_SPAWN_LARVAE: + ItemData(268 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 8, SC2Race.ZERG, parent=item_names.SWARM_QUEEN), + item_names.SWARM_QUEEN_DEEP_TUNNEL: + ItemData(269 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 9, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing, parent=item_names.SWARM_QUEEN), + item_names.SWARM_QUEEN_ORGANIC_CARAPACE: + ItemData(270 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 10, SC2Race.ZERG, parent=item_names.SWARM_QUEEN), + item_names.SWARM_QUEEN_BIO_MECHANICAL_TRANSFUSION: + ItemData(271 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 11, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.SWARM_QUEEN), + item_names.SWARM_QUEEN_RESOURCE_EFFICIENCY: + ItemData(272 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 12, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.SWARM_QUEEN), + item_names.SWARM_QUEEN_INCUBATOR_CHAMBER: + ItemData(273 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 13, SC2Race.ZERG, parent=item_names.SWARM_QUEEN), + item_names.BROOD_QUEEN_FUNGAL_GROWTH: + ItemData(274 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 14, SC2Race.ZERG, parent=item_names.BROOD_QUEEN), + item_names.BROOD_QUEEN_ENSNARE: + ItemData(275 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 15, SC2Race.ZERG, parent=item_names.BROOD_QUEEN), + item_names.BROOD_QUEEN_ENHANCED_MITOCHONDRIA: + ItemData(276 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 16, SC2Race.ZERG, parent=item_names.BROOD_QUEEN), + item_names.DEFILER_PATHOGEN_PROJECTORS: + ItemData(277 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 17, SC2Race.ZERG, parent=item_names.DEFILER), + item_names.DEFILER_TRAPDOOR_ADAPTATION: + ItemData(278 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 18, SC2Race.ZERG, parent=item_names.DEFILER), + item_names.DEFILER_PREDATORY_CONSUMPTION: + ItemData(279 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 19, SC2Race.ZERG, parent=item_names.DEFILER), + item_names.DEFILER_COMORBIDITY: + ItemData(280 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 20, SC2Race.ZERG, parent=item_names.DEFILER), + item_names.ABERRATION_MONSTROUS_RESILIENCE: + ItemData(281 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 21, SC2Race.ZERG, parent=item_names.ABERRATION), + item_names.ABERRATION_CONSTRUCT_REGENERATION: + ItemData(282 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 22, SC2Race.ZERG, parent=item_names.ABERRATION), + item_names.ABERRATION_BANELING_INCUBATION: + ItemData(283 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 23, SC2Race.ZERG, parent=item_names.ABERRATION), + item_names.ABERRATION_PROTECTIVE_COVER: + ItemData(284 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 24, SC2Race.ZERG, parent=item_names.ABERRATION), + item_names.ABERRATION_RESOURCE_EFFICIENCY: + ItemData(285 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 25, SC2Race.ZERG, parent=item_names.ABERRATION), + item_names.CORRUPTOR_MONSTROUS_RESILIENCE: + ItemData(286 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 26, SC2Race.ZERG, parent=item_names.CORRUPTOR), + item_names.CORRUPTOR_CONSTRUCT_REGENERATION: + ItemData(287 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 27, SC2Race.ZERG, parent=item_names.CORRUPTOR), + item_names.CORRUPTOR_SCOURGE_INCUBATION: + ItemData(288 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 28, SC2Race.ZERG, parent=item_names.CORRUPTOR), + item_names.CORRUPTOR_RESOURCE_EFFICIENCY: + ItemData(289 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_3, 29, SC2Race.ZERG, parent=item_names.CORRUPTOR), + item_names.PRIMAL_IGNITER_CONCENTRATED_FIRE: + ItemData(290 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 0, SC2Race.ZERG, parent=item_names.ROACH_PRIMAL_IGNITER_ASPECT), + item_names.PRIMAL_IGNITER_PRIMAL_TENACITY: + ItemData(291 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 1, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ROACH_PRIMAL_IGNITER_ASPECT), + item_names.INFESTED_SCV_BUILD_CHARGES: + ItemData(292 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 2, SC2Race.ZERG, parent=parent_names.INFESTED_UNITS), + item_names.INFESTED_MARINE_PLAGUED_MUNITIONS: + ItemData(293 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 3, SC2Race.ZERG, parent=item_names.INFESTED_MARINE), + item_names.INFESTED_MARINE_RETINAL_AUGMENTATION: + ItemData(294 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 4, SC2Race.ZERG, parent=item_names.INFESTED_MARINE), + item_names.INFESTED_BUNKER_CALCIFIED_ARMOR: + ItemData(295 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 6, SC2Race.ZERG, parent=item_names.INFESTED_BUNKER), + item_names.INFESTED_BUNKER_REGENERATIVE_PLATING: + ItemData(296 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 5, SC2Race.ZERG, parent=item_names.INFESTED_BUNKER), + item_names.INFESTED_BUNKER_ENGORGED_BUNKERS: + ItemData(297 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 7, SC2Race.ZERG, parent=item_names.INFESTED_BUNKER), + item_names.INFESTED_MISSILE_TURRET_BIOELECTRIC_PAYLOAD: + ItemData(298 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 6, SC2Race.ZERG, parent=item_names.INFESTED_MISSILE_TURRET), + item_names.INFESTED_MISSILE_TURRET_ACID_SPORE_VENTS: + ItemData(299 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 7, SC2Race.ZERG, parent=item_names.INFESTED_MISSILE_TURRET), + + item_names.ZERGLING_RAPTOR_STRAIN: + ItemData(300 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Strain, 0, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ZERGLING), + item_names.ZERGLING_SWARMLING_STRAIN: + ItemData(301 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Strain, 1, SC2Race.ZERG, parent=item_names.ZERGLING), + item_names.ROACH_VILE_STRAIN: + ItemData(302 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Strain, 2, SC2Race.ZERG, parent=item_names.ROACH), + item_names.ROACH_CORPSER_STRAIN: + ItemData(303 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Strain, 3, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ROACH), + item_names.HYDRALISK_IMPALER_ASPECT: + ItemData(304 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 0, SC2Race.ZERG, + classification=ItemClassification.progression, parent=parent_names.MORPH_SOURCE_HYDRALISK), + item_names.HYDRALISK_LURKER_ASPECT: + ItemData(305 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 1, SC2Race.ZERG, + classification=ItemClassification.progression, parent=parent_names.MORPH_SOURCE_HYDRALISK), + item_names.BANELING_SPLITTER_STRAIN: + ItemData(306 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Strain, 6, SC2Race.ZERG, classification=ItemClassification.progression, parent=parent_names.BANELING_SOURCE), + item_names.BANELING_HUNTER_STRAIN: + ItemData(307 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Strain, 7, SC2Race.ZERG, parent=parent_names.BANELING_SOURCE), + item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT: + ItemData(308 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 2, SC2Race.ZERG, + classification=ItemClassification.progression, parent=parent_names.MORPH_SOURCE_AIR), + item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT: + ItemData(309 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 3, SC2Race.ZERG, + classification=ItemClassification.progression, parent=parent_names.MORPH_SOURCE_AIR), + item_names.SWARM_HOST_CARRION_STRAIN: + ItemData(310 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Strain, 10, SC2Race.ZERG, parent=item_names.SWARM_HOST), + item_names.SWARM_HOST_CREEPER_STRAIN: + ItemData(311 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Strain, 11, SC2Race.ZERG, parent=item_names.SWARM_HOST), + item_names.ULTRALISK_NOXIOUS_STRAIN: + ItemData(312 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Strain, 12, SC2Race.ZERG, parent=item_names.ULTRALISK), + item_names.ULTRALISK_TORRASQUE_STRAIN: + ItemData(313 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Strain, 13, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ULTRALISK), + + item_names.TYRANNOZOR_TYRANTS_PROTECTION: + ItemData(350 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 8, SC2Race.ZERG, parent=item_names.ULTRALISK_TYRANNOZOR_ASPECT), + item_names.TYRANNOZOR_BARRAGE_OF_SPIKES: + ItemData(351 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 9, SC2Race.ZERG, parent=item_names.ULTRALISK_TYRANNOZOR_ASPECT), + item_names.TYRANNOZOR_IMPALING_STRIKE: + ItemData(352 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 10, SC2Race.ZERG, parent=item_names.ULTRALISK_TYRANNOZOR_ASPECT), + item_names.TYRANNOZOR_HEALING_ADAPTATION: + ItemData(353 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 11, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ULTRALISK_TYRANNOZOR_ASPECT), + item_names.NYDUS_WORM_ECHIDNA_WORM_SUBTERRANEAN_SCALES: + ItemData(354 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 12, SC2Race.ZERG, parent=parent_names.ANY_NYDUS_WORM), + item_names.NYDUS_WORM_ECHIDNA_WORM_JORMUNGANDR_STRAIN: + ItemData(355 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 13, SC2Race.ZERG, parent=parent_names.ANY_NYDUS_WORM), + item_names.NYDUS_WORM_ECHIDNA_WORM_RESOURCE_EFFICIENCY: + ItemData(356 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 14, SC2Race.ZERG, parent=parent_names.ANY_NYDUS_WORM), + item_names.ECHIDNA_WORM_OUROBOROS_STRAIN: + ItemData(357 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 15, SC2Race.ZERG, parent=parent_names.ZERG_OUROBOUROS_CONDITION), + item_names.NYDUS_WORM_RAVENOUS_APPETITE: + ItemData(358 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 16, SC2Race.ZERG, parent=item_names.NYDUS_WORM), + item_names.INFESTED_SIEGE_TANK_PROGRESSIVE_AUTOMATED_MITOSIS: + ItemData(359 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Progressive, 0, SC2Race.ZERG, + classification=ItemClassification.progression, parent=item_names.INFESTED_SIEGE_TANK, quantity=2), + item_names.INFESTED_SIEGE_TANK_ACIDIC_ENZYMES: + ItemData(360 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 17, SC2Race.ZERG, parent=item_names.INFESTED_SIEGE_TANK), + item_names.INFESTED_SIEGE_TANK_DEEP_TUNNEL: + ItemData(361 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 18, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing, parent=item_names.INFESTED_SIEGE_TANK), + item_names.INFESTED_DIAMONDBACK_CAUSTIC_MUCUS: + ItemData(362 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 19, SC2Race.ZERG, parent=item_names.INFESTED_DIAMONDBACK), + item_names.INFESTED_DIAMONDBACK_VIOLENT_ENZYMES: + ItemData(363 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 20, SC2Race.ZERG, parent=item_names.INFESTED_DIAMONDBACK), + item_names.INFESTED_BANSHEE_BRACED_EXOSKELETON: + ItemData(364 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 21, SC2Race.ZERG, parent=item_names.INFESTED_BANSHEE), + item_names.INFESTED_BANSHEE_RAPID_HIBERNATION: + ItemData(365 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 22, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.INFESTED_BANSHEE), + item_names.INFESTED_LIBERATOR_CLOUD_DISPERSAL: + ItemData(366 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 23, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.INFESTED_LIBERATOR), + item_names.INFESTED_LIBERATOR_VIRAL_CONTAMINATION: + ItemData(367 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 24, SC2Race.ZERG, parent=item_names.INFESTED_LIBERATOR), + item_names.GUARDIAN_PROPELLANT_SACS: + ItemData(368 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 25, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT), + item_names.GUARDIAN_EXPLOSIVE_SPORES: + ItemData(369 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 26, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT), + item_names.GUARDIAN_PRIMORDIAL_FURY: + ItemData(370 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 27, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT), + item_names.INFESTED_SIEGE_TANK_SEISMIC_SONAR: + ItemData(371 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 28, SC2Race.ZERG, parent=item_names.INFESTED_SIEGE_TANK), + item_names.INFESTED_BANSHEE_FLESHFUSED_TARGETING_OPTICS: + ItemData(372 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_4, 29, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.INFESTED_BANSHEE), + item_names.INFESTED_SIEGE_TANK_BALANCED_ROOTS: + ItemData(373 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 0, SC2Race.ZERG, parent=item_names.INFESTED_SIEGE_TANK), + item_names.INFESTED_DIAMONDBACK_PROGRESSIVE_FUNGAL_SNARE: + ItemData(374 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Progressive, 2, SC2Race.ZERG, + classification=ItemClassification.progression, parent=item_names.INFESTED_DIAMONDBACK, quantity=2), + item_names.INFESTED_DIAMONDBACK_CONCENTRATED_SPEW: + ItemData(375 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 1, SC2Race.ZERG, parent=item_names.INFESTED_DIAMONDBACK), + item_names.INFESTED_SIEGE_TANK_FRIGHTFUL_FLESHWELDER: + ItemData(376 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 2, SC2Race.ZERG, parent=item_names.INFESTED_SIEGE_TANK), + item_names.INFESTED_DIAMONDBACK_FRIGHTFUL_FLESHWELDER: + ItemData(377 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 3, SC2Race.ZERG, parent=item_names.INFESTED_DIAMONDBACK), + item_names.INFESTED_BANSHEE_FRIGHTFUL_FLESHWELDER: + ItemData(378 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 4, SC2Race.ZERG, parent=item_names.INFESTED_BANSHEE), + item_names.INFESTED_LIBERATOR_FRIGHTFUL_FLESHWELDER: + ItemData(379 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 5, SC2Race.ZERG, parent=item_names.INFESTED_LIBERATOR), + item_names.INFESTED_LIBERATOR_DEFENDER_MODE: + ItemData(380 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 8, SC2Race.ZERG, parent=item_names.INFESTED_LIBERATOR, + classification=ItemClassification.progression), + item_names.ABERRATION_PROGRESSIVE_BANELING_LAUNCH: + ItemData(381 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Progressive, 4, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.ABERRATION, quantity=2), + item_names.PYGALISK_STIM: + ItemData(382 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 9, SC2Race.ZERG, parent=item_names.PYGALISK), + item_names.PYGALISK_DUCAL_BLADES: + ItemData(383 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 10, SC2Race.ZERG, parent=item_names.PYGALISK), + item_names.PYGALISK_COMBAT_CARAPACE: + ItemData(384 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 11, SC2Race.ZERG, parent=item_names.PYGALISK), + item_names.BILE_LAUNCHER_ARTILLERY_DUCTS: + ItemData(385 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 12, SC2Race.ZERG, parent=item_names.BILE_LAUNCHER), + item_names.BILE_LAUNCHER_RAPID_BOMBARMENT: + ItemData(386 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 13, SC2Race.ZERG, classification=ItemClassification.progression, parent=item_names.BILE_LAUNCHER), + item_names.BULLFROG_WILD_MUTATION: + ItemData(387 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 14, SC2Race.ZERG, parent=item_names.BULLFROG), + item_names.BULLFROG_BROODLINGS: + ItemData(388 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 15, SC2Race.ZERG, parent=item_names.BULLFROG), + item_names.BULLFROG_HARD_IMPACT: + ItemData(389 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 16, SC2Race.ZERG, parent=item_names.BULLFROG), + item_names.BULLFROG_RANGE: + ItemData(390 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 17, SC2Race.ZERG, parent=item_names.BULLFROG), + item_names.SPORE_CRAWLER_BIO_BONUS: + ItemData(391 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mutation_5, 18, SC2Race.ZERG, parent=item_names.SPORE_CRAWLER), + + item_names.KERRIGAN_KINETIC_BLAST: ItemData(400 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 0, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_HEROIC_FORTITUDE: ItemData(401 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 1, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_LEAPING_STRIKE: ItemData(402 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 2, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_CRUSHING_GRIP: ItemData(403 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 3, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_CHAIN_REACTION: ItemData(404 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 4, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_PSIONIC_SHIFT: ItemData(405 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 5, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.ZERGLING_RECONSTITUTION: ItemData(406 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 0, SC2Race.ZERG, parent=item_names.ZERGLING), + item_names.OVERLORD_IMPROVED_OVERLORDS: ItemData(407 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 1, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.AUTOMATED_EXTRACTORS: ItemData(408 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 2, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_WILD_MUTATION: ItemData(409 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 6, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_SPAWN_BANELINGS: ItemData(410 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 7, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_MEND: ItemData(411 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 8, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.TWIN_DRONES: ItemData(412 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 3, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.MALIGNANT_CREEP: ItemData(413 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 4, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.VESPENE_EFFICIENCY: ItemData(414 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 5, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_INFEST_BROODLINGS: ItemData(415 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 9, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_FURY: ItemData(416 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 10, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_ABILITY_EFFICIENCY: ItemData(417 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 11, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_APOCALYPSE: ItemData(418 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 12, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_SPAWN_LEVIATHAN: ItemData(419 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 13, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.KERRIGAN_DROP_PODS: ItemData(420 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 14, SC2Race.ZERG, classification=ItemClassification.progression), + # Handled separately from other abilities + item_names.KERRIGAN_PRIMAL_FORM: ItemData(421 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Primal_Form, 0, SC2Race.ZERG), + item_names.KERRIGAN_ASSIMILATION_AURA: ItemData(422 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 15, SC2Race.ZERG), + item_names.KERRIGAN_IMMOBILIZATION_WAVE: ItemData(423 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Ability, 16, SC2Race.ZERG, classification=ItemClassification.progression), + + item_names.KERRIGAN_LEVELS_10: ItemData(500 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 10, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression), + item_names.KERRIGAN_LEVELS_9: ItemData(501 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 9, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression), + item_names.KERRIGAN_LEVELS_8: ItemData(502 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 8, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression), + item_names.KERRIGAN_LEVELS_7: ItemData(503 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 7, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression), + item_names.KERRIGAN_LEVELS_6: ItemData(504 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 6, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression), + item_names.KERRIGAN_LEVELS_5: ItemData(505 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 5, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression), + item_names.KERRIGAN_LEVELS_4: ItemData(506 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 4, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression_skip_balancing), + item_names.KERRIGAN_LEVELS_3: ItemData(507 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 3, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression_skip_balancing), + item_names.KERRIGAN_LEVELS_2: ItemData(508 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 2, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression_skip_balancing), + item_names.KERRIGAN_LEVELS_1: ItemData(509 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 1, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression_skip_balancing), + item_names.KERRIGAN_LEVELS_14: ItemData(510 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 14, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression), + item_names.KERRIGAN_LEVELS_35: ItemData(511 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 35, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression), + item_names.KERRIGAN_LEVELS_70: ItemData(512 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Level, 70, SC2Race.ZERG, quantity=0, classification=ItemClassification.progression), + + # Zerg Mercs + item_names.INFESTED_MEDICS: ItemData(600 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mercenary, 0, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + item_names.INFESTED_SIEGE_BREAKERS: ItemData(601 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mercenary, 1, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + item_names.INFESTED_DUSK_WINGS: ItemData(602 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mercenary, 2, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + item_names.DEVOURING_ONES: ItemData(603 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mercenary, 3, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + item_names.HUNTER_KILLERS: ItemData(604 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mercenary, 4, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + item_names.TORRASQUE_MERC: ItemData(605 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mercenary, 5, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + item_names.HUNTERLING: ItemData(606 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mercenary, 6, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + item_names.YGGDRASIL: ItemData(607 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mercenary, 7, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + item_names.CAUSTIC_HORRORS: ItemData(608 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Mercenary, 8, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + + + # Misc Upgrades + item_names.OVERLORD_VENTRAL_SACS: ItemData(700 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 6, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + item_names.OVERLORD_GENERATE_CREEP: ItemData(701 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 7, SC2Race.ZERG, classification=ItemClassification.progression_skip_balancing), + item_names.OVERLORD_ANTENNAE: ItemData(702 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 8, SC2Race.ZERG), + item_names.OVERLORD_PNEUMATIZED_CARAPACE: ItemData(703 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 9, SC2Race.ZERG), + item_names.ZERG_EXCAVATING_CLAWS: ItemData(704 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 11, SC2Race.ZERG, parent=parent_names.ZERG_UPROOTABLE_BUILDINGS), + item_names.ZERG_CREEP_STOMACH: ItemData(705 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 10, SC2Race.ZERG), + item_names.HIVE_CLUSTER_MATURATION: ItemData(706 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 12, SC2Race.ZERG), + item_names.MACROSCOPIC_RECUPERATION: ItemData(707 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 13, SC2Race.ZERG), + item_names.BIOMECHANICAL_STOCKPILING: ItemData(708 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 14, SC2Race.ZERG, parent=parent_names.INFESTED_FACTORY_OR_STARPORT), + item_names.BROODLING_SPORE_SATURATION: ItemData(709 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 15, SC2Race.ZERG), + item_names.CELL_DIVISION: ItemData(710 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 16, SC2Race.ZERG, classification=ItemClassification.progression, parent=parent_names.ZERG_MERCENARIES), + item_names.SELF_SUFFICIENT: ItemData(711 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 17, SC2Race.ZERG, classification=ItemClassification.progression, parent=parent_names.ZERG_MERCENARIES), + item_names.UNRESTRICTED_MUTATION: ItemData(712 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 18, SC2Race.ZERG, classification=ItemClassification.progression, parent=parent_names.ZERG_MERCENARIES), + item_names.EVOLUTIONARY_LEAP: ItemData(713 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Evolution_Pit, 19, SC2Race.ZERG, classification=ItemClassification.progression, parent=parent_names.ZERG_MERCENARIES), + + # Morphs + item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT: ItemData(800 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 6, SC2Race.ZERG, classification=ItemClassification.progression, parent=parent_names.MORPH_SOURCE_AIR), + item_names.MUTALISK_CORRUPTOR_DEVOURER_ASPECT: ItemData(801 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 7, SC2Race.ZERG, classification=ItemClassification.progression, parent=parent_names.MORPH_SOURCE_AIR), + item_names.ROACH_RAVAGER_ASPECT: ItemData(802 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 8, SC2Race.ZERG, classification=ItemClassification.progression, parent=parent_names.MORPH_SOURCE_ROACH), + item_names.OVERLORD_OVERSEER_ASPECT: ItemData(803 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 4, SC2Race.ZERG, classification=ItemClassification.progression), + item_names.ROACH_PRIMAL_IGNITER_ASPECT: ItemData(804 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 9, SC2Race.ZERG, classification=ItemClassification.progression, parent=parent_names.MORPH_SOURCE_ROACH), + item_names.ULTRALISK_TYRANNOZOR_ASPECT: ItemData(805 + SC2HOTS_ITEM_ID_OFFSET, ZergItemType.Morph, 10, SC2Race.ZERG, classification=ItemClassification.progression, parent=parent_names.MORPH_SOURCE_ULTRALISK), + + # Protoss Units + # The first several are in SC2WOL offset for historical reasons (show up in prophecy) + item_names.ZEALOT: + ItemData(700 + SC2WOL_ITEM_ID_OFFSET, ProtossItemType.Unit, 0, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.STALKER: + ItemData(701 + SC2WOL_ITEM_ID_OFFSET, ProtossItemType.Unit, 1, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.HIGH_TEMPLAR: + ItemData(702 + SC2WOL_ITEM_ID_OFFSET, ProtossItemType.Unit, 2, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.DARK_TEMPLAR: + ItemData(703 + SC2WOL_ITEM_ID_OFFSET, ProtossItemType.Unit, 3, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.IMMORTAL: + ItemData(704 + SC2WOL_ITEM_ID_OFFSET, ProtossItemType.Unit, 4, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.COLOSSUS: + ItemData(705 + SC2WOL_ITEM_ID_OFFSET, ProtossItemType.Unit, 5, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.PHOENIX: + ItemData(706 + SC2WOL_ITEM_ID_OFFSET, ProtossItemType.Unit, 6, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.VOID_RAY: + ItemData(707 + SC2WOL_ITEM_ID_OFFSET, ProtossItemType.Unit, 7, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.CARRIER: + ItemData(708 + SC2WOL_ITEM_ID_OFFSET, ProtossItemType.Unit, 8, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.OBSERVER: + ItemData(0 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 9, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.CENTURION: + ItemData(1 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 10, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.SENTINEL: + ItemData(2 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 11, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.SUPPLICANT: + ItemData(3 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 12, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.INSTIGATOR: + ItemData(4 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 13, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.SLAYER: + ItemData(5 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 14, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.SENTRY: + ItemData(6 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 15, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.ENERGIZER: + ItemData(7 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 16, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.HAVOC: + ItemData(8 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 17, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.SIGNIFIER: + ItemData(9 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 18, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.ASCENDANT: + ItemData(10 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 19, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.AVENGER: + ItemData(11 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 20, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.BLOOD_HUNTER: + ItemData(12 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 21, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.DRAGOON: + ItemData(13 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 22, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.DARK_ARCHON: + ItemData(14 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 23, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.ADEPT: + ItemData(15 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 24, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.WARP_PRISM: + ItemData(16 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 25, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.ANNIHILATOR: + ItemData(17 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 26, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.VANGUARD: + ItemData(18 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 27, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.WRATHWALKER: + ItemData(19 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 28, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.REAVER: + ItemData(20 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit, 29, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.DISRUPTOR: + ItemData(21 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 0, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.MIRAGE: + ItemData(22 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 1, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.CORSAIR: + ItemData(23 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 2, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.DESTROYER: + ItemData(24 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 3, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.SCOUT: + ItemData(25 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 4, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.TEMPEST: + ItemData(26 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 5, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.MOTHERSHIP: + ItemData(27 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 6, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.ARBITER: + ItemData(28 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 7, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.ORACLE: + ItemData(29 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 8, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.STALWART: + ItemData(30 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 9, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.PULSAR: + ItemData(31 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 10, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.DAWNBRINGER: + ItemData(32 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 11, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.SKYLORD: + ItemData(33 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 12, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.TRIREME: + ItemData(34 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 13, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.SKIRMISHER: + ItemData(35 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 14, SC2Race.PROTOSS, + classification=ItemClassification.progression), + # 36, 37 reserved for Mothership + item_names.OPPRESSOR: + ItemData(38 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 17, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.CALADRIUS: + ItemData(39 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 18, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.MISTWING: + ItemData(40 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Unit_2, 19, SC2Race.PROTOSS, + classification=ItemClassification.progression), + + # Protoss Upgrades + item_names.PROGRESSIVE_PROTOSS_GROUND_WEAPON: ItemData(100 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, 0, SC2Race.PROTOSS, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_PROTOSS_GROUND_ARMOR: ItemData(101 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, 4, SC2Race.PROTOSS, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_PROTOSS_SHIELDS: ItemData(102 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, 8, SC2Race.PROTOSS, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_PROTOSS_AIR_WEAPON: ItemData(103 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, 12, SC2Race.PROTOSS, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_PROTOSS_AIR_ARMOR: ItemData(104 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, 16, SC2Race.PROTOSS, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + # Bundles + item_names.PROGRESSIVE_PROTOSS_WEAPON_UPGRADE: ItemData(105 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, -1, SC2Race.PROTOSS, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_PROTOSS_ARMOR_UPGRADE: ItemData(106 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, -1, SC2Race.PROTOSS, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_PROTOSS_GROUND_UPGRADE: ItemData(107 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, -1, SC2Race.PROTOSS, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_PROTOSS_AIR_UPGRADE: ItemData(108 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, -1, SC2Race.PROTOSS, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + item_names.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE: ItemData(109 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Upgrade, -1, SC2Race.PROTOSS, classification=ItemClassification.progression, quantity=WEAPON_ARMOR_UPGRADE_MAX_LEVEL), + + # Protoss Buildings + item_names.PHOTON_CANNON: ItemData(200 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Building, 0, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.KHAYDARIN_MONOLITH: ItemData(201 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Building, 1, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.SHIELD_BATTERY: ItemData(202 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Building, 2, SC2Race.PROTOSS, classification=ItemClassification.progression), + + # Protoss Unit Upgrades + item_names.SUPPLICANT_BLOOD_SHIELD: ItemData(300 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 0, SC2Race.PROTOSS, parent=item_names.SUPPLICANT), + item_names.SUPPLICANT_SOUL_AUGMENTATION: ItemData(301 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 1, SC2Race.PROTOSS, parent=item_names.SUPPLICANT), + item_names.SUPPLICANT_ENDLESS_SERVITUDE: ItemData(302 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 2, SC2Race.PROTOSS, parent=item_names.SUPPLICANT), + item_names.ADEPT_SHOCKWAVE: ItemData(303 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 3, SC2Race.PROTOSS, parent=item_names.ADEPT), + item_names.ADEPT_RESONATING_GLAIVES: ItemData(304 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 4, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.ADEPT), + item_names.ADEPT_PHASE_BULWARK: ItemData(305 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 5, SC2Race.PROTOSS, parent=item_names.ADEPT), + item_names.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES: ItemData(306 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 6, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=parent_names.STALKER_CLASS), + item_names.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION: ItemData(307 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 7, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=parent_names.STALKER_CLASS), + item_names.DRAGOON_CONCENTRATED_ANTIMATTER: ItemData(308 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 8, SC2Race.PROTOSS, parent=item_names.DRAGOON), + item_names.DRAGOON_TRILLIC_COMPRESSION_SYSTEM: ItemData(309 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 9, SC2Race.PROTOSS, parent=item_names.DRAGOON), + item_names.DRAGOON_SINGULARITY_CHARGE: ItemData(310 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 10, SC2Race.PROTOSS, parent=item_names.DRAGOON), + item_names.DRAGOON_ENHANCED_STRIDER_SERVOS: ItemData(311 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 11, SC2Race.PROTOSS, parent=item_names.DRAGOON), + item_names.SCOUT_COMBAT_SENSOR_ARRAY: ItemData(312 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 12, SC2Race.PROTOSS, parent=parent_names.SCOUT_CLASS), + item_names.SCOUT_APIAL_SENSORS: ItemData(313 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 13, SC2Race.PROTOSS, parent=item_names.SCOUT), + item_names.SCOUT_GRAVITIC_THRUSTERS: ItemData(314 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 14, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=parent_names.SCOUT_CLASS), + item_names.SCOUT_ADVANCED_PHOTON_BLASTERS: ItemData(315 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 15, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=parent_names.SCOUT_OR_OPPRESSOR_OR_MISTWING), + item_names.TEMPEST_TECTONIC_DESTABILIZERS: ItemData(316 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 16, SC2Race.PROTOSS, parent=item_names.TEMPEST), + item_names.TEMPEST_QUANTIC_REACTOR: ItemData(317 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 17, SC2Race.PROTOSS, parent=item_names.TEMPEST), + item_names.TEMPEST_GRAVITY_SLING: ItemData(318 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 18, SC2Race.PROTOSS, parent=item_names.TEMPEST), + item_names.PHOENIX_CLASS_IONIC_WAVELENGTH_FLUX: ItemData(319 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 19, SC2Race.PROTOSS, parent=parent_names.PHOENIX_CLASS), + item_names.PHOENIX_CLASS_ANION_PULSE_CRYSTALS: ItemData(320 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 20, SC2Race.PROTOSS, parent=parent_names.PHOENIX_CLASS), + item_names.CORSAIR_STEALTH_DRIVE: ItemData(321 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 21, SC2Race.PROTOSS, parent=item_names.CORSAIR), + item_names.CORSAIR_ARGUS_JEWEL: ItemData(322 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 22, SC2Race.PROTOSS, parent=item_names.CORSAIR), + item_names.CORSAIR_SUSTAINING_DISRUPTION: ItemData(323 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 23, SC2Race.PROTOSS, parent=item_names.CORSAIR), + item_names.CORSAIR_NEUTRON_SHIELDS: ItemData(324 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 24, SC2Race.PROTOSS, parent=item_names.CORSAIR), + item_names.ORACLE_STEALTH_DRIVE: ItemData(325 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 25, SC2Race.PROTOSS, parent=item_names.ORACLE), + item_names.ORACLE_SKYWARD_CHRONOANOMALY: ItemData(544 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 26, SC2Race.PROTOSS, parent=item_names.ORACLE), + item_names.ORACLE_TEMPORAL_ACCELERATION_BEAM: ItemData(327 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 27, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.ORACLE), + item_names.ARBITER_CHRONOSTATIC_REINFORCEMENT: ItemData(328 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 28, SC2Race.PROTOSS, parent=item_names.ARBITER), + item_names.ARBITER_KHAYDARIN_CORE: ItemData(329 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_1, 29, SC2Race.PROTOSS, parent=item_names.ARBITER), + item_names.ARBITER_SPACETIME_ANCHOR: ItemData(330 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 0, SC2Race.PROTOSS, parent=item_names.ARBITER), + item_names.ARBITER_RESOURCE_EFFICIENCY: ItemData(331 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 1, SC2Race.PROTOSS, parent=item_names.ARBITER), + item_names.ARBITER_JUDICATORS_VEIL: ItemData(332 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 2, SC2Race.PROTOSS, parent=item_names.ARBITER), + item_names.CARRIER_TRIREME_GRAVITON_CATAPULT: + ItemData(333 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 3, SC2Race.PROTOSS, parent=parent_names.CARRIER_OR_TRIREME), + item_names.CARRIER_SKYLORD_TRIREME_HULL_OF_PAST_GLORIES: + ItemData(334 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 4, SC2Race.PROTOSS, parent=parent_names.CARRIER_CLASS), + item_names.VOID_RAY_DESTROYER_PULSAR_DAWNBRINGER_FLUX_VANES: + ItemData(335 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 5, SC2Race.PROTOSS, parent=parent_names.VOID_RAY_CLASS), + item_names.DESTROYER_RESOURCE_EFFICIENCY: ItemData(535 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 6, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.DESTROYER), + item_names.WARP_PRISM_GRAVITIC_DRIVE: + ItemData(337 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 7, SC2Race.PROTOSS, parent=item_names.WARP_PRISM), + item_names.WARP_PRISM_PHASE_BLASTER: + ItemData(338 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 8, SC2Race.PROTOSS, + classification=ItemClassification.progression, parent=item_names.WARP_PRISM), + item_names.WARP_PRISM_WAR_CONFIGURATION: ItemData(339 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 9, SC2Race.PROTOSS, parent=item_names.WARP_PRISM), + item_names.OBSERVER_GRAVITIC_BOOSTERS: ItemData(340 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 10, SC2Race.PROTOSS, parent=item_names.OBSERVER), + item_names.OBSERVER_SENSOR_ARRAY: ItemData(341 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 11, SC2Race.PROTOSS, parent=item_names.OBSERVER), + item_names.REAVER_SCARAB_DAMAGE: ItemData(342 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 12, SC2Race.PROTOSS, parent=item_names.REAVER), + item_names.REAVER_SOLARITE_PAYLOAD: ItemData(343 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 13, SC2Race.PROTOSS, parent=item_names.REAVER), + item_names.REAVER_REAVER_CAPACITY: ItemData(344 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 14, SC2Race.PROTOSS, parent=item_names.REAVER), + item_names.REAVER_RESOURCE_EFFICIENCY: ItemData(345 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 15, SC2Race.PROTOSS, parent=item_names.REAVER), + item_names.VANGUARD_AGONY_LAUNCHERS: ItemData(346 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 16, SC2Race.PROTOSS, parent=item_names.VANGUARD), + item_names.VANGUARD_MATTER_DISPERSION: ItemData(347 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 17, SC2Race.PROTOSS, parent=item_names.VANGUARD), + item_names.IMMORTAL_ANNIHILATOR_SINGULARITY_CHARGE: ItemData(348 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 18, SC2Race.PROTOSS, parent=parent_names.IMMORTAL_OR_ANNIHILATOR), + item_names.IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING: ItemData(349 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 19, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=parent_names.IMMORTAL_OR_ANNIHILATOR), + item_names.COLOSSUS_PACIFICATION_PROTOCOL: ItemData(350 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 20, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.COLOSSUS), + item_names.WRATHWALKER_RAPID_POWER_CYCLING: ItemData(351 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 21, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.WRATHWALKER), + item_names.WRATHWALKER_EYE_OF_WRATH: ItemData(352 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 22, SC2Race.PROTOSS, parent=item_names.WRATHWALKER), + item_names.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_SHROUD_OF_ADUN: ItemData(353 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 23, SC2Race.PROTOSS, parent=parent_names.DARK_TEMPLAR_CLASS), + item_names.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_SHADOW_GUARD_TRAINING: ItemData(354 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 24, SC2Race.PROTOSS, parent=parent_names.DARK_TEMPLAR_CLASS), + item_names.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_BLINK: ItemData(355 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 25, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=parent_names.DARK_TEMPLAR_CLASS), + item_names.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_RESOURCE_EFFICIENCY: ItemData(356 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 26, SC2Race.PROTOSS, parent=parent_names.DARK_TEMPLAR_CLASS), + item_names.DARK_TEMPLAR_DARK_ARCHON_MELD: ItemData(357 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 27, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.DARK_TEMPLAR), + item_names.HIGH_TEMPLAR_SIGNIFIER_UNSHACKLED_PSIONIC_STORM: ItemData(358 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 28, SC2Race.PROTOSS, parent=parent_names.STORM_CASTER), + item_names.HIGH_TEMPLAR_SIGNIFIER_HALLUCINATION: ItemData(359 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_2, 29, SC2Race.PROTOSS, parent=parent_names.STORM_CASTER), + item_names.HIGH_TEMPLAR_SIGNIFIER_KHAYDARIN_AMULET: ItemData(360 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 0, SC2Race.PROTOSS, parent=parent_names.STORM_CASTER), + item_names.ARCHON_HIGH_ARCHON: ItemData(361 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 1, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=parent_names.ARCHON_SOURCE), + item_names.DARK_ARCHON_FEEDBACK: ItemData(362 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 2, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=parent_names.DARK_ARCHON_SOURCE), + item_names.DARK_ARCHON_MAELSTROM: ItemData(363 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 3, SC2Race.PROTOSS, parent=parent_names.DARK_ARCHON_SOURCE), + item_names.DARK_ARCHON_ARGUS_TALISMAN: ItemData(364 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 4, SC2Race.PROTOSS, parent=parent_names.DARK_ARCHON_SOURCE), + item_names.ASCENDANT_POWER_OVERWHELMING: ItemData(365 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 5, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=parent_names.SUPPLICANT_AND_ASCENDANT), + item_names.ASCENDANT_CHAOTIC_ATTUNEMENT: ItemData(366 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 6, SC2Race.PROTOSS, parent=item_names.ASCENDANT), + item_names.ASCENDANT_BLOOD_AMULET: ItemData(367 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 7, SC2Race.PROTOSS, parent=item_names.ASCENDANT), + item_names.SENTRY_ENERGIZER_HAVOC_CLOAKING_MODULE: ItemData(368 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 8, SC2Race.PROTOSS, parent=parent_names.SENTRY_CLASS), + item_names.SENTRY_ENERGIZER_HAVOC_SHIELD_BATTERY_RAPID_RECHARGING: ItemData(369 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 9, SC2Race.PROTOSS, parent=parent_names.SENTRY_CLASS_OR_SHIELD_BATTERY), + item_names.SENTRY_FORCE_FIELD: ItemData(370 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 10, SC2Race.PROTOSS, parent=item_names.SENTRY), + item_names.SENTRY_HALLUCINATION: ItemData(371 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 11, SC2Race.PROTOSS, parent=item_names.SENTRY), + item_names.ENERGIZER_RECLAMATION: ItemData(372 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 12, SC2Race.PROTOSS, parent=item_names.ENERGIZER), + item_names.ENERGIZER_FORGED_CHASSIS: ItemData(373 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 13, SC2Race.PROTOSS, parent=item_names.ENERGIZER), + item_names.HAVOC_DETECT_WEAKNESS: ItemData(374 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 14, SC2Race.PROTOSS, parent=item_names.HAVOC), + item_names.HAVOC_BLOODSHARD_RESONANCE: ItemData(375 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 15, SC2Race.PROTOSS, parent=item_names.HAVOC), + item_names.ZEALOT_SENTINEL_CENTURION_LEG_ENHANCEMENTS: ItemData(376 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 16, SC2Race.PROTOSS, parent=parent_names.ZEALOT_OR_SENTINEL_OR_CENTURION), + item_names.ZEALOT_SENTINEL_CENTURION_SHIELD_CAPACITY: ItemData(377 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 17, SC2Race.PROTOSS, classification=ItemClassification.progression_skip_balancing, parent=parent_names.ZEALOT_OR_SENTINEL_OR_CENTURION), + item_names.ORACLE_BOSONIC_CORE: ItemData(378 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 18, SC2Race.PROTOSS, parent=item_names.ORACLE), + item_names.SCOUT_RESOURCE_EFFICIENCY: ItemData(379 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 19, SC2Race.PROTOSS, parent=item_names.SCOUT), + item_names.IMMORTAL_ANNIHILATOR_DISRUPTOR_DISPERSION: ItemData(380 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 20, SC2Race.PROTOSS, parent=parent_names.IMMORTAL_OR_ANNIHILATOR), + item_names.DISRUPTOR_CLOAKING_MODULE: ItemData(381 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 21, SC2Race.PROTOSS, parent=item_names.DISRUPTOR), + item_names.DISRUPTOR_PERFECTED_POWER: ItemData(382 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 22, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.DISRUPTOR), + item_names.DISRUPTOR_RESTRAINED_DESTRUCTION: ItemData(383 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 23, SC2Race.PROTOSS, parent=item_names.DISRUPTOR), + item_names.TEMPEST_INTERPLANETARY_RANGE: ItemData(384 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 24, SC2Race.PROTOSS, parent=item_names.TEMPEST), + item_names.DAWNBRINGER_ANTI_SURFACE_COUNTERMEASURES: ItemData(385 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 25, SC2Race.PROTOSS, parent=item_names.DAWNBRINGER), + item_names.DAWNBRINGER_ENHANCED_SHIELD_GENERATOR: ItemData(386 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 26, SC2Race.PROTOSS, parent=item_names.DAWNBRINGER), + item_names.STALWART_HIGH_VOLTAGE_CAPACITORS: ItemData(387 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 27, SC2Race.PROTOSS, parent=item_names.STALWART), + item_names.STALWART_REINTEGRATED_FRAMEWORK: ItemData(388 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 28, SC2Race.PROTOSS, parent=item_names.STALWART), + item_names.STALWART_STABILIZED_ELECTRODES: ItemData(389 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_3, 29, SC2Race.PROTOSS, parent=item_names.STALWART), + item_names.STALWART_LATTICED_SHIELDING: ItemData(390 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 0, SC2Race.PROTOSS, parent=item_names.STALWART), + item_names.ARCHON_TRANSCENDENCE: ItemData(391 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 1, SC2Race.PROTOSS, parent=parent_names.ARCHON_SOURCE), + item_names.ARCHON_POWER_SIPHON: ItemData(392 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 2, SC2Race.PROTOSS, parent=parent_names.ARCHON_SOURCE), + item_names.ARCHON_ERADICATE: ItemData(393 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 3, SC2Race.PROTOSS, parent=parent_names.ARCHON_SOURCE), + item_names.ARCHON_OBLITERATE: ItemData(394 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 4, SC2Race.PROTOSS, parent=parent_names.ARCHON_SOURCE), + item_names.SUPPLICANT_ZENITH_PITCH: ItemData(395 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 5, SC2Race.PROTOSS, classification=ItemClassification.progression_skip_balancing, parent=item_names.SUPPLICANT), + item_names.PULSAR_CHRONOCLYSM: ItemData(396 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 6, SC2Race.PROTOSS, parent=item_names.PULSAR), + item_names.PULSAR_ENTROPIC_REVERSAL: ItemData(397 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 7, SC2Race.PROTOSS, parent=item_names.PULSAR), + # 398-407 reserved for Mothership + item_names.OPPRESSOR_ACCELERATED_WARP: ItemData(408 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 18, SC2Race.PROTOSS, parent=item_names.OPPRESSOR), + item_names.OPPRESSOR_ARMOR_MELTING_BLASTERS: ItemData(409 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 19, SC2Race.PROTOSS, parent=item_names.OPPRESSOR), + item_names.CALADRIUS_SIDE_MISSILES: ItemData(410 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 20, SC2Race.PROTOSS, parent=item_names.CALADRIUS), + item_names.CALADRIUS_STRUCTURE_TARGETING: ItemData(411 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 21, SC2Race.PROTOSS, parent=item_names.CALADRIUS), + item_names.CALADRIUS_SOLARITE_REACTOR: ItemData(412 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 22, SC2Race.PROTOSS, parent=item_names.CALADRIUS), + item_names.MISTWING_NULL_SHROUD: ItemData(413 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 23, SC2Race.PROTOSS, parent=item_names.MISTWING), + item_names.MISTWING_PILOT: ItemData(414 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 24, SC2Race.PROTOSS, classification=ItemClassification.progression_skip_balancing, parent=item_names.MISTWING), + item_names.INSTIGATOR_BLINK_OVERDRIVE: ItemData(415 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 25, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.INSTIGATOR), + item_names.INSTIGATOR_RECONSTRUCTION: ItemData(416 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 26, SC2Race.PROTOSS, parent=item_names.INSTIGATOR), + item_names.DARK_TEMPLAR_ARCHON_MERGE: ItemData(417 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 27, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.DARK_TEMPLAR), + item_names.ASCENDANT_ARCHON_MERGE: ItemData(418 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 28, SC2Race.PROTOSS, classification=ItemClassification.progression_skip_balancing, parent=item_names.ASCENDANT), + item_names.SCOUT_SUPPLY_EFFICIENCY: ItemData(419 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 29, SC2Race.PROTOSS, parent=item_names.SCOUT), + item_names.REAVER_BARGAIN_BIN_PRICES: ItemData(420 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_5, 0, SC2Race.PROTOSS, parent=item_names.SCOUT), + + + # War Council + item_names.ZEALOT_WHIRLWIND: ItemData(500 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 0, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.ZEALOT), + item_names.CENTURION_RESOURCE_EFFICIENCY: ItemData(501 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 1, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.CENTURION), + item_names.SENTINEL_RESOURCE_EFFICIENCY: ItemData(502 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 2, SC2Race.PROTOSS, parent=item_names.SENTINEL), + item_names.STALKER_PHASE_REACTOR: ItemData(503 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 3, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.STALKER), + item_names.DRAGOON_PHALANX_SUIT: ItemData(504 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 4, SC2Race.PROTOSS, parent=item_names.DRAGOON), + item_names.INSTIGATOR_MODERNIZED_SERVOS: ItemData(505 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 5, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.INSTIGATOR), + item_names.ADEPT_DISRUPTIVE_TRANSFER: ItemData(506 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 6, SC2Race.PROTOSS, parent=item_names.ADEPT), + item_names.SLAYER_PHASE_BLINK: ItemData(507 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 7, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.SLAYER), + item_names.AVENGER_KRYHAS_CLOAK: ItemData(508 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 8, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.AVENGER), + item_names.DARK_TEMPLAR_LESSER_SHADOW_FURY: ItemData(509 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 9, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.DARK_TEMPLAR), + item_names.DARK_TEMPLAR_GREATER_SHADOW_FURY: ItemData(510 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 10, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.DARK_TEMPLAR), + item_names.BLOOD_HUNTER_BRUTAL_EFFICIENCY: ItemData(511 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 11, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.BLOOD_HUNTER), + item_names.SENTRY_DOUBLE_SHIELD_RECHARGE: ItemData(512 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 12, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.SENTRY), + item_names.ENERGIZER_MOBILE_CHRONO_BEAM: ItemData(513 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 13, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.ENERGIZER), + item_names.HAVOC_ENDURING_SIGHT: ItemData(514 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 14, SC2Race.PROTOSS, parent=item_names.HAVOC), + item_names.HIGH_TEMPLAR_PLASMA_SURGE: ItemData(515 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 15, SC2Race.PROTOSS, parent=item_names.HIGH_TEMPLAR), + item_names.SIGNIFIER_FEEDBACK: ItemData(516 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 16, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.SIGNIFIER), + item_names.ASCENDANT_BREATH_OF_CREATION: ItemData(517 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 17, SC2Race.PROTOSS, parent=item_names.ASCENDANT), + item_names.DARK_ARCHON_INDOMITABLE_WILL: ItemData(518 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 18, SC2Race.PROTOSS, parent=parent_names.DARK_ARCHON_SOURCE), + item_names.IMMORTAL_IMPROVED_BARRIER: ItemData(519 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 19, SC2Race.PROTOSS, parent=item_names.IMMORTAL), + item_names.VANGUARD_RAPIDFIRE_CANNON: ItemData(520 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 20, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.VANGUARD), + item_names.VANGUARD_FUSION_MORTARS: ItemData(521 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 21, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.VANGUARD), + item_names.ANNIHILATOR_TWILIGHT_CHASSIS: ItemData(522 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 22, SC2Race.PROTOSS, parent=item_names.ANNIHILATOR), + item_names.STALWART_ARC_INDUCERS: ItemData(523 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 23, SC2Race.PROTOSS, parent=item_names.STALWART), + item_names.COLOSSUS_FIRE_LANCE: ItemData(524 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 24, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.COLOSSUS), + item_names.WRATHWALKER_AERIAL_TRACKING: ItemData(525 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 25, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.WRATHWALKER), + item_names.REAVER_KHALAI_REPLICATORS: ItemData(526 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 26, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.REAVER), + item_names.DISRUPTOR_MOBILITY_PROTOCOLS: ItemData(527 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 27, SC2Race.PROTOSS, parent=item_names.DISRUPTOR), + item_names.WARP_PRISM_WARP_REFRACTION: ItemData(528 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 28, SC2Race.PROTOSS, parent=item_names.WARP_PRISM), + item_names.OBSERVER_INDUCE_SCOPOPHOBIA: ItemData(529 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council, 29, SC2Race.PROTOSS, parent=item_names.OBSERVER), + item_names.PHOENIX_DOUBLE_GRAVITON_BEAM: ItemData(530 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 0, SC2Race.PROTOSS, parent=item_names.PHOENIX), + item_names.CORSAIR_NETWORK_DISRUPTION: ItemData(531 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 1, SC2Race.PROTOSS, parent=item_names.CORSAIR), + item_names.MIRAGE_GRAVITON_BEAM: ItemData(532 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 2, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.MIRAGE), + item_names.SKIRMISHER_PEER_CONTEMPT: ItemData(533 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 3, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.SKIRMISHER), + item_names.VOID_RAY_PRISMATIC_RANGE: ItemData(534 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 4, SC2Race.PROTOSS, parent=item_names.VOID_RAY), + item_names.DESTROYER_REFORGED_BLOODSHARD_CORE: ItemData(336 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 5, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.DESTROYER), + item_names.PULSAR_CHRONO_SHEAR: ItemData(536 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 6, SC2Race.PROTOSS, parent=item_names.PULSAR), + item_names.DAWNBRINGER_SOLARITE_LENS: ItemData(537 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 7, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.DAWNBRINGER), + item_names.CARRIER_REPAIR_DRONES: ItemData(538 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 8, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.CARRIER), + item_names.SKYLORD_JUMP: ItemData(539 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 9, SC2Race.PROTOSS, parent=item_names.SKYLORD), + item_names.TRIREME_SOLAR_BEAM: ItemData(540 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 10, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.TRIREME), + item_names.TEMPEST_DISINTEGRATION: ItemData(541 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 11, SC2Race.PROTOSS, parent=item_names.TEMPEST), + item_names.SCOUT_EXPEDITIONARY_HULL: ItemData(542 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 12, SC2Race.PROTOSS, parent=item_names.SCOUT), + item_names.ARBITER_VESSEL_OF_THE_CONCLAVE: ItemData(543 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 13, SC2Race.PROTOSS, parent=item_names.ARBITER), + item_names.ORACLE_STASIS_CALIBRATION: ItemData(326 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 14, SC2Race.PROTOSS, parent=item_names.ORACLE), + item_names.MOTHERSHIP_INTEGRATED_POWER: ItemData(545 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 15, SC2Race.PROTOSS, parent=item_names.MOTHERSHIP), + # 546-549 reserved for Mothership + item_names.OPPRESSOR_VULCAN_BLASTER: ItemData(550 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 20, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.OPPRESSOR), + item_names.CALADRIUS_CORONA_BEAM: ItemData(551 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 21, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.CALADRIUS), + item_names.MISTWING_PHANTOM_DASH: ItemData(552 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 22, SC2Race.PROTOSS, parent=item_names.MISTWING), + item_names.SUPPLICANT_SACRIFICE: ItemData(553 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.War_Council_2, 23, SC2Race.PROTOSS, parent=item_names.SUPPLICANT), + + # SoA Calldown powers + item_names.SOA_CHRONO_SURGE: ItemData(700 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 0, SC2Race.PROTOSS), + item_names.SOA_PROGRESSIVE_PROXY_PYLON: ItemData(701 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Progressive, 0, SC2Race.PROTOSS, quantity=2, classification=ItemClassification.progression), + item_names.SOA_PYLON_OVERCHARGE: ItemData(702 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 1, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.SOA_ORBITAL_STRIKE: ItemData(703 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 2, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.SOA_TEMPORAL_FIELD: ItemData(704 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 3, SC2Race.PROTOSS), + item_names.SOA_SOLAR_LANCE: ItemData(705 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 4, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.SOA_MASS_RECALL: ItemData(706 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 5, SC2Race.PROTOSS), + item_names.SOA_SHIELD_OVERCHARGE: ItemData(707 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 6, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.SOA_DEPLOY_FENIX: ItemData(708 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 7, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.SOA_PURIFIER_BEAM: ItemData(709 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 8, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.SOA_TIME_STOP: ItemData(710 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 9, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.SOA_SOLAR_BOMBARDMENT: ItemData(711 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Spear_Of_Adun, 10, SC2Race.PROTOSS, classification=ItemClassification.progression), + + # Generic Protoss Upgrades + item_names.MATRIX_OVERLOAD: + ItemData(800 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 0, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.QUATRO: + ItemData(801 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 1, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.NEXUS_OVERCHARGE: + ItemData(802 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 2, SC2Race.PROTOSS, + classification=ItemClassification.progression, important_for_filtering=True), + item_names.ORBITAL_ASSIMILATORS: + ItemData(803 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 3, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.WARP_HARMONIZATION: + ItemData(804 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 4, SC2Race.PROTOSS, classification=ItemClassification.progression_skip_balancing), + item_names.GUARDIAN_SHELL: + ItemData(805 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 5, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.RECONSTRUCTION_BEAM: + ItemData(806 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 6, SC2Race.PROTOSS, + classification=ItemClassification.progression), + item_names.OVERWATCH: + ItemData(807 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 7, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.SUPERIOR_WARP_GATES: + ItemData(808 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 8, SC2Race.PROTOSS), + item_names.ENHANCED_TARGETING: + ItemData(809 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 9, SC2Race.PROTOSS, parent=parent_names.PROTOSS_STATIC_DEFENSE), + item_names.OPTIMIZED_ORDNANCE: + ItemData(810 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 10, SC2Race.PROTOSS, parent=parent_names.PROTOSS_ATTACKING_BUILDING), + item_names.KHALAI_INGENUITY: + ItemData(811 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 11, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.AMPLIFIED_ASSIMILATORS: + ItemData(812 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 12, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.PROGRESSIVE_WARP_RELOCATE: + ItemData(813 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Progressive, 2, SC2Race.PROTOSS, quantity=2, + classification=ItemClassification.progression), + item_names.PROBE_WARPIN: + ItemData(814 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 13, SC2Race.PROTOSS, classification=ItemClassification.progression), + item_names.ELDER_PROBES: + ItemData(815 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Solarite_Core, 14, SC2Race.PROTOSS, classification=ItemClassification.progression), +} + +# Add keys to item table +# Mission keys (key offset + 0-999) +# Mission IDs start at 1 so the item IDs are moved down a space +mission_key_item_table = { + item_names._TEMPLATE_MISSION_KEY.format(mission.mission_name): + ItemData(mission.id - 1 + SC2_KEY_ITEM_ID_OFFSET, FactionlessItemType.Keys, 0, SC2Race.ANY, + classification=ItemClassification.progression, quantity=0) + for mission in SC2Mission +} +# Numbered layout keys (key offset + 1000 - 1999) +numbered_layout_key_item_table = { + item_names._TEMPLATE_NUMBERED_LAYOUT_KEY.format(number + 1): + ItemData(number + SC2_KEY_ITEM_ID_OFFSET + SC2_KEY_ITEM_SECTION_SIZE, FactionlessItemType.Keys, 0, SC2Race.ANY, + classification=ItemClassification.progression, quantity=0) + for number in range(len(SC2Mission)) +} +# Numbered campaign keys (key offset + 2000 - 2999) +numbered_campaign_key_item_table = { + item_names._TEMPLATE_NUMBERED_CAMPAIGN_KEY.format(number + 1): + ItemData(number + SC2_KEY_ITEM_ID_OFFSET + SC2_KEY_ITEM_SECTION_SIZE * 2, FactionlessItemType.Keys, 0, SC2Race.ANY, + classification=ItemClassification.progression, quantity=0) + for number in range(len(SC2Mission)) +} +# Flavor keys (key offset + 3000 - 3999) +flavor_key_item_table = { + item_names._TEMPLATE_FLAVOR_KEY.format(name): + ItemData(i + SC2_KEY_ITEM_ID_OFFSET + SC2_KEY_ITEM_SECTION_SIZE * 3, FactionlessItemType.Keys, 0, SC2Race.ANY, + classification=ItemClassification.progression, quantity=0) + for (i, name) in enumerate(item_names._flavor_key_names) +} +# Named layout keys (key offset + 4000 - 4999) +campaign_to_layout_names = get_used_layout_names() +named_layout_key_item_table = { + item_names._TEMPLATE_NAMED_LAYOUT_KEY.format(layout_name, campaign.campaign_name): + ItemData(layout_start + i + SC2_KEY_ITEM_ID_OFFSET + SC2_KEY_ITEM_SECTION_SIZE * 4, FactionlessItemType.Keys, 0, SC2Race.ANY, + classification=ItemClassification.progression, quantity=0) + for (campaign, (layout_start, layout_names)) in campaign_to_layout_names.items() for (i, layout_name) in enumerate(layout_names) +} +# Named campaign keys (key offset + 5000 - 5999) +campaign_names = [campaign.campaign_name for campaign in SC2Campaign if campaign != SC2Campaign.GLOBAL] +named_campaign_key_item_table = { + item_names._TEMPLATE_NAMED_CAMPAIGN_KEY.format(campaign_name): + ItemData(i + SC2_KEY_ITEM_ID_OFFSET + SC2_KEY_ITEM_SECTION_SIZE * 5, FactionlessItemType.Keys, 0, SC2Race.ANY, + classification=ItemClassification.progression, quantity=0) + for (i, campaign_name) in enumerate(campaign_names) +} +# Numbered progressive keys (key offset + 6000 - 6999) +numbered_progressive_keys = { + item_names._TEMPLATE_PROGRESSIVE_KEY.format(number + 1): + ItemData(number + SC2_KEY_ITEM_ID_OFFSET + SC2_KEY_ITEM_SECTION_SIZE * 6, FactionlessItemType.Keys, 0, SC2Race.ANY, + classification=ItemClassification.progression, quantity=0) + for number in range(len(SC2Mission)) +} +# Special keys (key offset + 7000 - 7999) +special_keys = { + item_names.PROGRESSIVE_MISSION_KEY: + ItemData(0 + SC2_KEY_ITEM_ID_OFFSET + SC2_KEY_ITEM_SECTION_SIZE * 7, FactionlessItemType.Keys, 0, SC2Race.ANY, + classification=ItemClassification.progression, quantity=0), + item_names.PROGRESSIVE_QUESTLINE_KEY: + ItemData(1 + SC2_KEY_ITEM_ID_OFFSET + SC2_KEY_ITEM_SECTION_SIZE * 7, FactionlessItemType.Keys, 0, SC2Race.ANY, + classification=ItemClassification.progression, quantity=0), +} +key_item_table = {} +key_item_table.update(mission_key_item_table) +key_item_table.update(numbered_layout_key_item_table) +key_item_table.update(numbered_campaign_key_item_table) +key_item_table.update(flavor_key_item_table) +key_item_table.update(named_layout_key_item_table) +key_item_table.update(named_campaign_key_item_table) +key_item_table.update(numbered_progressive_keys) +key_item_table.update(special_keys) +item_table.update(key_item_table) + +def get_item_table(): + return item_table + + +basic_units = { + SC2Race.TERRAN: { + item_names.MARINE, + item_names.MARAUDER, + item_names.DOMINION_TROOPER, + item_names.GOLIATH, + item_names.HELLION, + item_names.VULTURE, + item_names.WARHOUND, + }, + SC2Race.ZERG: { + item_names.SWARM_QUEEN, + item_names.ROACH, + item_names.HYDRALISK, + }, + SC2Race.PROTOSS: { + item_names.ZEALOT, + item_names.CENTURION, + item_names.SENTINEL, + item_names.STALKER, + item_names.INSTIGATOR, + item_names.SLAYER, + item_names.ADEPT, + } +} + +advanced_basic_units = { + SC2Race.TERRAN: basic_units[SC2Race.TERRAN].union({ + item_names.REAPER, + item_names.DIAMONDBACK, + item_names.VIKING, + item_names.SIEGE_TANK, + item_names.BANSHEE, + item_names.THOR, + item_names.BATTLECRUISER, + item_names.CYCLONE + }), + SC2Race.ZERG: basic_units[SC2Race.ZERG].union({ + item_names.INFESTED_BANSHEE, + item_names.INFESTED_DIAMONDBACK, + item_names.INFESTOR, + item_names.ABERRATION, + }), + SC2Race.PROTOSS: basic_units[SC2Race.PROTOSS].union({ + item_names.DARK_TEMPLAR, + item_names.DRAGOON, + item_names.AVENGER, + item_names.IMMORTAL, + item_names.ANNIHILATOR, + item_names.VANGUARD, + item_names.SKIRMISHER, + }) +} + +no_logic_basic_units = { + SC2Race.TERRAN: advanced_basic_units[SC2Race.TERRAN].union({ + item_names.FIREBAT, + item_names.GHOST, + item_names.SPECTRE, + item_names.WRAITH, + item_names.RAVEN, + item_names.PREDATOR, + item_names.LIBERATOR, + item_names.HERC, + }), + SC2Race.ZERG: advanced_basic_units[SC2Race.ZERG].union({ + item_names.ZERGLING, + item_names.PYGALISK, + item_names.INFESTED_SIEGE_TANK, + item_names.ULTRALISK, + item_names.SWARM_HOST + }), + SC2Race.PROTOSS: advanced_basic_units[SC2Race.PROTOSS].union({ + item_names.BLOOD_HUNTER, + item_names.STALWART, + item_names.CARRIER, + item_names.SKYLORD, + item_names.TRIREME, + item_names.TEMPEST, + item_names.VOID_RAY, + item_names.DESTROYER, + item_names.PULSAR, + item_names.DAWNBRINGER, + item_names.COLOSSUS, + item_names.WRATHWALKER, + item_names.SCOUT, + item_names.OPPRESSOR, + item_names.MISTWING, + item_names.HIGH_TEMPLAR, + item_names.SIGNIFIER, + item_names.ASCENDANT, + item_names.DARK_ARCHON, + item_names.SUPPLICANT, + }) +} + +not_balanced_starting_units = { + item_names.SIEGE_TANK, + item_names.THOR, + item_names.BANSHEE, + item_names.BATTLECRUISER, + item_names.ULTRALISK, + item_names.CARRIER, + item_names.TEMPEST, +} + + +# Defense rating table +# Commented defense ratings are handled in LogicMixin +tvx_defense_ratings = { + item_names.SIEGE_TANK: 5, + # "Graduating Range": 1, + item_names.PLANETARY_FORTRESS: 3, + # Bunker w/ Marine/Marauder: 3, + item_names.PERDITION_TURRET: 2, + item_names.DEVASTATOR_TURRET: 2, + item_names.VULTURE: 1, + item_names.BANSHEE: 1, + item_names.BATTLECRUISER: 1, + item_names.LIBERATOR: 4, + item_names.WIDOW_MINE: 1, + # "Concealment (Widow Mine)": 1 +} +tvz_defense_ratings = { + item_names.PERDITION_TURRET: 2, + # Bunker w/ Firebat: 2, + item_names.LIBERATOR: -2, + item_names.HIVE_MIND_EMULATOR: 3, + item_names.PSI_DISRUPTER: 3, +} +tvx_air_defense_ratings = { + item_names.MISSILE_TURRET: 2, +} +zvx_defense_ratings = { + # Note that this doesn't include Kerrigan because this is just for race swaps, which doesn't involve her (for now) + item_names.SPINE_CRAWLER: 3, + # w/ Twin Drones: 1 + item_names.SWARM_QUEEN: 1, + item_names.SWARM_HOST: 1, + # impaler: 3 + # "Hardened Tentacle Spines (Impaler)": 2 + # lurker: 1 + # "Seismic Spines (Lurker)": 2 + # "Adapted Spines (Lurker)": 1 + # brood lord : 2 + # corpser roach: 1 + # creep tumors (swarm queen or overseer): 1 + # w/ malignant creep: 1 + # tanks with ammo: 5 + item_names.INFESTED_BUNKER: 3, + item_names.BILE_LAUNCHER: 2, +} +# zvz_defense_ratings = { + # corpser roach: 1 + # primal igniter: 2 + # lurker: 1 + # w/ adapted spines: -1 + # impaler: -1 +# } +zvx_air_defense_ratings = { + item_names.SPORE_CRAWLER: 2, + # w/ Twin Drones: 1 + item_names.INFESTED_MISSILE_TURRET: 2, +} +pvx_defense_ratings = { + item_names.PHOTON_CANNON: 2, + item_names.KHAYDARIN_MONOLITH: 3, + item_names.SHIELD_BATTERY: 1, + item_names.NEXUS_OVERCHARGE: 2, + item_names.SKYLORD: 1, + item_names.MATRIX_OVERLOAD: 1, + item_names.COLOSSUS: 1, + item_names.VANGUARD: 1, + item_names.REAVER: 1, +} +pvz_defense_ratings = { + item_names.KHAYDARIN_MONOLITH: -2, + item_names.COLOSSUS: 1, +} + +terran_passive_ratings = { + item_names.AUTOMATED_REFINERY: 4, + item_names.COMMAND_CENTER_MULE: 4, + item_names.ORBITAL_DEPOTS: 2, + item_names.COMMAND_CENTER_COMMAND_CENTER_REACTOR: 2, + item_names.COMMAND_CENTER_EXTRA_SUPPLIES: 2, + item_names.MICRO_FILTERING: 2, + item_names.TECH_REACTOR: 2 +} + +zerg_passive_ratings = { + item_names.TWIN_DRONES: 7, + item_names.AUTOMATED_EXTRACTORS: 4, + item_names.VESPENE_EFFICIENCY: 3, + item_names.OVERLORD_IMPROVED_OVERLORDS: 4, + item_names.MALIGNANT_CREEP: 2 +} + +protoss_passive_ratings = { + item_names.QUATRO: 4, + item_names.ORBITAL_ASSIMILATORS: 4, + item_names.AMPLIFIED_ASSIMILATORS: 3, + item_names.PROBE_WARPIN: 2, + item_names.ELDER_PROBES: 2, + item_names.MATRIX_OVERLOAD: 2 +} + +soa_energy_ratings = { + item_names.SOA_SOLAR_LANCE: 8, + item_names.SOA_DEPLOY_FENIX: 7, + item_names.SOA_TEMPORAL_FIELD: 6, + item_names.SOA_PROGRESSIVE_PROXY_PYLON: 5, # Requires Lvl 2 (Warp in Reinforcements) + item_names.SOA_SHIELD_OVERCHARGE: 5, + item_names.SOA_ORBITAL_STRIKE: 4 +} + +soa_passive_ratings = { + item_names.GUARDIAN_SHELL: 4, + item_names.OVERWATCH: 2 +} + +soa_ultimate_ratings = { + item_names.SOA_TIME_STOP: 4, + item_names.SOA_PURIFIER_BEAM: 3, + item_names.SOA_SOLAR_BOMBARDMENT: 3 +} + +kerrigan_levels = [ + item_name for item_name, item_data in item_table.items() + if item_data.type == ZergItemType.Level and item_data.race == SC2Race.ZERG +] + + +spear_of_adun_calldowns = { + item_names.SOA_CHRONO_SURGE, + item_names.SOA_PROGRESSIVE_PROXY_PYLON, + item_names.SOA_PYLON_OVERCHARGE, + item_names.SOA_ORBITAL_STRIKE, + item_names.SOA_TEMPORAL_FIELD, + item_names.SOA_SOLAR_LANCE, + item_names.SOA_MASS_RECALL, + item_names.SOA_SHIELD_OVERCHARGE, + item_names.SOA_DEPLOY_FENIX, + item_names.SOA_PURIFIER_BEAM, + item_names.SOA_TIME_STOP, + item_names.SOA_SOLAR_BOMBARDMENT +} + +spear_of_adun_castable_passives = { + item_names.RECONSTRUCTION_BEAM, + item_names.OVERWATCH, + item_names.GUARDIAN_SHELL, +} + +nova_equipment = { + *[item_name for item_name, item_data in get_full_item_list().items() + if item_data.type == TerranItemType.Nova_Gear], + item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE +} + +upgrade_bundles: Dict[str, List[str]] = { + # Terran + item_names.PROGRESSIVE_TERRAN_WEAPON_UPGRADE: + [ + item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, + item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, + item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON + ], + item_names.PROGRESSIVE_TERRAN_ARMOR_UPGRADE: + [ + item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR, + item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR, + item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR + ], + item_names.PROGRESSIVE_TERRAN_INFANTRY_UPGRADE: + [ + item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR + ], + item_names.PROGRESSIVE_TERRAN_VEHICLE_UPGRADE: + [ + item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR + ], + item_names.PROGRESSIVE_TERRAN_SHIP_UPGRADE: + [ + item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR + ], + item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE: + [ + item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR, + item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR, + item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR + ], + # Zerg + item_names.PROGRESSIVE_ZERG_WEAPON_UPGRADE: + [ + item_names.PROGRESSIVE_ZERG_MELEE_ATTACK, + item_names.PROGRESSIVE_ZERG_MISSILE_ATTACK, + item_names.PROGRESSIVE_ZERG_FLYER_ATTACK + ], + item_names.PROGRESSIVE_ZERG_ARMOR_UPGRADE: + [ + item_names.PROGRESSIVE_ZERG_GROUND_CARAPACE, item_names.PROGRESSIVE_ZERG_FLYER_CARAPACE + ], + item_names.PROGRESSIVE_ZERG_GROUND_UPGRADE: + [ + item_names.PROGRESSIVE_ZERG_MELEE_ATTACK, + item_names.PROGRESSIVE_ZERG_MISSILE_ATTACK, + item_names.PROGRESSIVE_ZERG_GROUND_CARAPACE + ], + item_names.PROGRESSIVE_ZERG_FLYER_UPGRADE: + [ + item_names.PROGRESSIVE_ZERG_FLYER_ATTACK, item_names.PROGRESSIVE_ZERG_FLYER_CARAPACE + ], + item_names.PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE: + [ + item_names.PROGRESSIVE_ZERG_MELEE_ATTACK, + item_names.PROGRESSIVE_ZERG_MISSILE_ATTACK, + item_names.PROGRESSIVE_ZERG_GROUND_CARAPACE, + item_names.PROGRESSIVE_ZERG_FLYER_ATTACK, + item_names.PROGRESSIVE_ZERG_FLYER_CARAPACE + ], + # Protoss + item_names.PROGRESSIVE_PROTOSS_WEAPON_UPGRADE: + [ + item_names.PROGRESSIVE_PROTOSS_GROUND_WEAPON, item_names.PROGRESSIVE_PROTOSS_AIR_WEAPON + ], + item_names.PROGRESSIVE_PROTOSS_ARMOR_UPGRADE: + [ + item_names.PROGRESSIVE_PROTOSS_GROUND_ARMOR, item_names.PROGRESSIVE_PROTOSS_AIR_ARMOR, + item_names.PROGRESSIVE_PROTOSS_SHIELDS + ], + item_names.PROGRESSIVE_PROTOSS_GROUND_UPGRADE: + [ + item_names.PROGRESSIVE_PROTOSS_GROUND_WEAPON, item_names.PROGRESSIVE_PROTOSS_GROUND_ARMOR, + item_names.PROGRESSIVE_PROTOSS_SHIELDS + ], + item_names.PROGRESSIVE_PROTOSS_AIR_UPGRADE: + [ + item_names.PROGRESSIVE_PROTOSS_AIR_WEAPON, item_names.PROGRESSIVE_PROTOSS_AIR_ARMOR, + item_names.PROGRESSIVE_PROTOSS_SHIELDS + ], + item_names.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE: + [ + item_names.PROGRESSIVE_PROTOSS_GROUND_WEAPON, item_names.PROGRESSIVE_PROTOSS_GROUND_ARMOR, + item_names.PROGRESSIVE_PROTOSS_AIR_WEAPON, item_names.PROGRESSIVE_PROTOSS_AIR_ARMOR, + item_names.PROGRESSIVE_PROTOSS_SHIELDS + ], +} + +# Used for logic +upgrade_bundle_inverted_lookup: Dict[str, List[str]] = dict() +for key, values in upgrade_bundles.items(): + for value in values: + if upgrade_bundle_inverted_lookup.get(value) is None: + upgrade_bundle_inverted_lookup[value] = list() + if (value != item_names.PROGRESSIVE_PROTOSS_SHIELDS + or key not in [ + item_names.PROGRESSIVE_PROTOSS_GROUND_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_AIR_UPGRADE + ] + ): + # Shield handling is trickier as it's max of Ground/Air group, not their sum + upgrade_bundle_inverted_lookup[value].append(key) + +lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in get_full_item_list().items() if + data.code} + +upgrade_item_types = (TerranItemType.Upgrade, ZergItemType.Upgrade, ProtossItemType.Upgrade) diff --git a/worlds/sc2/item/parent_names.py b/worlds/sc2/item/parent_names.py new file mode 100644 index 000000000000..8bf33becdffc --- /dev/null +++ b/worlds/sc2/item/parent_names.py @@ -0,0 +1,57 @@ +""" +Identifiers for complex item parent structures. +Defined separately from item_parents to avoid a circular import +item_names -> item_parent_names -> item_tables -> item_parents +""" + +# Terran +DOMINION_TROOPER_WEAPONS = "Dominion Trooper Weapons" +INFANTRY_UNITS = "Infantry Units" +INFANTRY_WEAPON_UNITS = "Infantry Weapon Units" +ORBITAL_COMMAND_AND_PLANETARY = "Orbital Command Abilities + Planetary Fortress" # MULE | Scan | Supply Drop +SIEGE_TANK_AND_TRANSPORT = "Siege Tank + Transport" +SIEGE_TANK_AND_MEDIVAC = "Siege Tank + Medivac" +SPIDER_MINE_SOURCE = "Spider Mine Source" +STARSHIP_UNITS = "Starship Units" +STARSHIP_WEAPON_UNITS = "Starship Weapon Units" +VEHICLE_UNITS = "Vehicle Units" +VEHICLE_WEAPON_UNITS = "Vehicle Weapon Units" +TERRAN_MERCENARIES = "Terran Mercenaries" + +# Zerg +ANY_NYDUS_WORM = "Any Nydus Worm" +BANELING_SOURCE = "Any Baneling Source" # Baneling aspect | Kerrigan Spawn Banelings +INFESTED_UNITS = "Infested Units" +INFESTED_FACTORY_OR_STARPORT = "Infested Factory or Starport" +MORPH_SOURCE_AIR = "Air Morph Source" # Morphling | Mutalisk | Corruptor +MORPH_SOURCE_ROACH = "Roach Morph Source" # Morphling | Roach +MORPH_SOURCE_ZERGLING = "Zergling Morph Source" # Morphling | Zergling +MORPH_SOURCE_HYDRALISK = "Hydralisk Morph Source" # Morphling | Hydralisk +MORPH_SOURCE_ULTRALISK = "Ultralisk Morph Source" # Morphling | Ultralisk +ZERG_UPROOTABLE_BUILDINGS = "Zerg Uprootable Buildings" +ZERG_MELEE_ATTACKER = "Zerg Melee Attacker" +ZERG_MISSILE_ATTACKER = "Zerg Missile Attacker" +ZERG_CARAPACE_UNIT = "Zerg Carapace Unit" +ZERG_FLYING_UNIT = "Zerg Flying Unit" +ZERG_MERCENARIES = "Zerg Mercenaries" +ZERG_OUROBOUROS_CONDITION = "Zerg Ourobouros Condition" + +# Protoss +ARCHON_SOURCE = "Any Archon Source" +CARRIER_CLASS = "Carrier Class" +CARRIER_OR_TRIREME = "Carrier | Trireme" +DARK_ARCHON_SOURCE = "Dark Archon Source" +DARK_TEMPLAR_CLASS = "Dark Templar Class" +STORM_CASTER = "Storm Caster" +IMMORTAL_OR_ANNIHILATOR = "Immortal | Annihilator" +PHOENIX_CLASS = "Phoenix Class" +SENTRY_CLASS = "Sentry Class" +SENTRY_CLASS_OR_SHIELD_BATTERY = "Sentry Class | Shield Battery" +STALKER_CLASS = "Stalker Class" +SUPPLICANT_AND_ASCENDANT = "Supplicant + Ascendant" +VOID_RAY_CLASS = "Void Ray Class" +ZEALOT_OR_SENTINEL_OR_CENTURION = "Zealot | Sentinel | Centurion" +PROTOSS_STATIC_DEFENSE = "Protoss Static Defense" +PROTOSS_ATTACKING_BUILDING = "Protoss Attacking Structure" +SCOUT_CLASS = "Scout Class" +SCOUT_OR_OPPRESSOR_OR_MISTWING = "Scout | Oppressor | Mist Wing" diff --git a/worlds/sc2/location_groups.py b/worlds/sc2/location_groups.py new file mode 100644 index 000000000000..c353558fb408 --- /dev/null +++ b/worlds/sc2/location_groups.py @@ -0,0 +1,40 @@ +""" +Location group definitions +""" + +from typing import Dict, Set, Iterable +from .locations import DEFAULT_LOCATION_LIST, LocationData +from .mission_tables import lookup_name_to_mission, MissionFlag + +def get_location_groups() -> Dict[str, Set[str]]: + result: Dict[str, Set[str]] = {} + locations: Iterable[LocationData] = DEFAULT_LOCATION_LIST + + for location in locations: + if location.code is None: + # Beat events + continue + mission = lookup_name_to_mission.get(location.region) + if mission is None: + continue + + if (MissionFlag.HasRaceSwap|MissionFlag.RaceSwap) & mission.flags: + # Location group including race-swapped variants of a location + agnostic_location_name = ( + location.name + .replace(' (Terran)', '') + .replace(' (Protoss)', '') + .replace(' (Zerg)', '') + ) + result.setdefault(agnostic_location_name, set()).add(location.name) + + # Location group including all locations in all raceswaps + result.setdefault(mission.mission_name[:mission.mission_name.find(' (')], set()).add(location.name) + + # Location group including all locations in a mission + result.setdefault(mission.mission_name, set()).add(location.name) + + # Location group by location category + result.setdefault(location.type.name.title(), set()).add(location.name) + + return result diff --git a/worlds/sc2/locations.py b/worlds/sc2/locations.py new file mode 100644 index 000000000000..0e00f4d7ea1a --- /dev/null +++ b/worlds/sc2/locations.py @@ -0,0 +1,14175 @@ +import enum +from typing import List, Tuple, Optional, Callable, NamedTuple, Set, TYPE_CHECKING +from .item import item_names +from .item.item_groups import kerrigan_logic_ultimates +from .options import ( + get_option_value, + RequiredTactics, + LocationInclusion, + KerriganPresence, + GrantStoryTech, + get_enabled_campaigns, +) +from .mission_tables import SC2Mission, SC2Campaign + +from BaseClasses import Location +from worlds.AutoWorld import World + +if TYPE_CHECKING: + from BaseClasses import CollectionState + from . import SC2World + +SC2WOL_LOC_ID_OFFSET = 1000 +SC2HOTS_LOC_ID_OFFSET = 20000000 # Avoid clashes with The Legend of Zelda +SC2LOTV_LOC_ID_OFFSET = SC2HOTS_LOC_ID_OFFSET + 2000 +SC2NCO_LOC_ID_OFFSET = SC2LOTV_LOC_ID_OFFSET + 2500 +SC2_RACESWAP_LOC_ID_OFFSET = SC2NCO_LOC_ID_OFFSET + 900 +VICTORY_CACHE_OFFSET = 90 + + +class SC2Location(Location): + game: str = "Starcraft2" + + +class LocationType(enum.IntEnum): + VICTORY = 0 # Winning a mission + VANILLA = 1 # Objectives that provided metaprogression in the original campaign, along with a few other locations for a balanced experience + EXTRA = 2 # Additional locations based on mission progression, collecting in-mission rewards, etc. that do not significantly increase the challenge. + CHALLENGE = 3 # Challenging objectives, often harder than just completing a mission, and often associated with Achievements + MASTERY = 4 # Extremely challenging objectives often associated with Masteries and Feats of Strength in the original campaign + VICTORY_CACHE = 5 # Bonus locations for beating a mission + + +class LocationFlag(enum.IntFlag): + NONE = 0 + BASEBUST = enum.auto() + """Locations about killing challenging bases""" + SPEEDRUN = enum.auto() + """Locations that are about doing something fast""" + PREVENTATIVE = enum.auto() + """Locations that are about preventing something from happening""" + + def values(self): + """Hacky iterator for backwards-compatibility with Python <= 3.10. Not necessary on Python 3.11+""" + return tuple( + val + for val in ( + LocationFlag.SPEEDRUN, + LocationFlag.PREVENTATIVE, + ) + if val in self + ) + + +class LocationData(NamedTuple): + region: str + name: str + code: int + type: LocationType + rule: Callable[["CollectionState"], bool] = Location.access_rule + flags: LocationFlag = LocationFlag.NONE + hard_rule: Optional[Callable[["CollectionState"], bool]] = None + + +def make_location_data( + region: str, + name: str, + code: int, + type: LocationType, + rule: Callable[["CollectionState"], bool] = Location.access_rule, + flags: LocationFlag = LocationFlag.NONE, + hard_rule: Optional[Callable[["CollectionState"], bool]] = None, +) -> LocationData: + return LocationData(region, f"{region}: {name}", code, type, rule, flags, hard_rule) + + +def get_location_types(world: "SC2World", inclusion_type: int) -> Set[LocationType]: + """ + :param world: The starcraft 2 world object + :param inclusion_type: Level of inclusion to check for + :return: A list of location types that match the inclusion type + """ + exclusion_options = [ + ("vanilla_locations", LocationType.VANILLA), + ("extra_locations", LocationType.EXTRA), + ("challenge_locations", LocationType.CHALLENGE), + ("mastery_locations", LocationType.MASTERY), + ] + excluded_location_types = set() + for option_name, location_type in exclusion_options: + if get_option_value(world, option_name) is inclusion_type: + excluded_location_types.add(location_type) + return excluded_location_types + + +def get_location_flags(world: "SC2World", inclusion_type: int) -> LocationFlag: + """ + :param world: The starcraft 2 world object + :param inclusion_type: Level of inclusion to check for + :return: A list of location types that match the inclusion type + """ + matching_location_flags = LocationFlag.NONE + if world.options.basebust_locations.value == inclusion_type: + matching_location_flags |= LocationFlag.BASEBUST + if world.options.speedrun_locations.value == inclusion_type: + matching_location_flags |= LocationFlag.SPEEDRUN + if world.options.preventative_locations.value == inclusion_type: + matching_location_flags |= LocationFlag.PREVENTATIVE + return matching_location_flags + + +def get_plando_locations(world: World) -> List[str]: + """ + :param multiworld: + :param player: + :return: A list of locations affected by a plando in a world + """ + if world is None: + return [] + plando_locations = [] + for plando_setting in world.options.plando_items: + plando_locations += plando_setting.locations + + return plando_locations + + +def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: + # Note: rules which are ended with or True are rules identified as needed later when restricted units is an option + if world is None: + logic_level = int(RequiredTactics.default) + kerriganless = False + else: + logic_level = world.options.required_tactics.value + kerriganless = ( + world.options.kerrigan_presence.value != KerriganPresence.option_vanilla + or SC2Campaign.HOTS not in get_enabled_campaigns(world) + ) + adv_tactics = logic_level != RequiredTactics.option_standard + if world is not None and world.logic is not None: + logic = world.logic + else: + from .rules import SC2Logic + + logic = SC2Logic(world) + player = 1 if world is None else world.player + location_table: List[LocationData] = [ + # WoL + make_location_data( + SC2Mission.LIBERATION_DAY.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 100, + LocationType.VICTORY, + ), + make_location_data( + SC2Mission.LIBERATION_DAY.mission_name, + "First Statue", + SC2WOL_LOC_ID_OFFSET + 101, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.LIBERATION_DAY.mission_name, + "Second Statue", + SC2WOL_LOC_ID_OFFSET + 102, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.LIBERATION_DAY.mission_name, + "Third Statue", + SC2WOL_LOC_ID_OFFSET + 103, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.LIBERATION_DAY.mission_name, + "Fourth Statue", + SC2WOL_LOC_ID_OFFSET + 104, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.LIBERATION_DAY.mission_name, + "Fifth Statue", + SC2WOL_LOC_ID_OFFSET + 105, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.LIBERATION_DAY.mission_name, + "Sixth Statue", + SC2WOL_LOC_ID_OFFSET + 106, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.LIBERATION_DAY.mission_name, + "Special Delivery", + SC2WOL_LOC_ID_OFFSET + 107, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.LIBERATION_DAY.mission_name, + "Transport", + SC2WOL_LOC_ID_OFFSET + 108, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_OUTLAWS.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 200, + LocationType.VICTORY, + logic.terran_early_tech, + ), + make_location_data( + SC2Mission.THE_OUTLAWS.mission_name, + "Rebel Base", + SC2WOL_LOC_ID_OFFSET + 201, + LocationType.VANILLA, + logic.terran_early_tech, + ), + make_location_data( + SC2Mission.THE_OUTLAWS.mission_name, + "North Resource Pickups", + SC2WOL_LOC_ID_OFFSET + 202, + LocationType.EXTRA, + logic.terran_early_tech, + ), + make_location_data( + SC2Mission.THE_OUTLAWS.mission_name, + "Bunker", + SC2WOL_LOC_ID_OFFSET + 203, + LocationType.VANILLA, + logic.terran_early_tech, + ), + make_location_data( + SC2Mission.THE_OUTLAWS.mission_name, + "Close Resource Pickups", + SC2WOL_LOC_ID_OFFSET + 204, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 300, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_defense_rating(state, True) >= 2 + and (adv_tactics or logic.terran_basic_anti_air(state)) + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "First Group Rescued", + SC2WOL_LOC_ID_OFFSET + 301, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "Second Group Rescued", + SC2WOL_LOC_ID_OFFSET + 302, + LocationType.VANILLA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "Third Group Rescued", + SC2WOL_LOC_ID_OFFSET + 303, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_defense_rating(state, True) >= 2 + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "First Hatchery", + SC2WOL_LOC_ID_OFFSET + 304, + LocationType.CHALLENGE, + logic.terran_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "Second Hatchery", + SC2WOL_LOC_ID_OFFSET + 305, + LocationType.CHALLENGE, + logic.terran_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "Third Hatchery", + SC2WOL_LOC_ID_OFFSET + 306, + LocationType.CHALLENGE, + logic.terran_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "Fourth Hatchery", + SC2WOL_LOC_ID_OFFSET + 307, + LocationType.CHALLENGE, + logic.terran_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "Ride's on its Way", + SC2WOL_LOC_ID_OFFSET + 308, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "Hold Just a Little Longer", + SC2WOL_LOC_ID_OFFSET + 309, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_defense_rating(state, True) >= 2 + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR.mission_name, + "Cavalry's on the Way", + SC2WOL_LOC_ID_OFFSET + 310, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_defense_rating(state, True) >= 2 + ), + ), + make_location_data( + SC2Mission.EVACUATION.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 400, + LocationType.VICTORY, + lambda state: ( + logic.terran_early_tech(state) + and ( + (adv_tactics and logic.terran_basic_anti_air(state)) + or logic.terran_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.EVACUATION.mission_name, + "North Chrysalis", + SC2WOL_LOC_ID_OFFSET + 401, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.EVACUATION.mission_name, + "West Chrysalis", + SC2WOL_LOC_ID_OFFSET + 402, + LocationType.VANILLA, + logic.terran_early_tech, + ), + make_location_data( + SC2Mission.EVACUATION.mission_name, + "East Chrysalis", + SC2WOL_LOC_ID_OFFSET + 403, + LocationType.VANILLA, + logic.terran_early_tech, + ), + make_location_data( + SC2Mission.EVACUATION.mission_name, + "Reach Hanson", + SC2WOL_LOC_ID_OFFSET + 404, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.EVACUATION.mission_name, + "Secret Resource Stash", + SC2WOL_LOC_ID_OFFSET + 405, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.EVACUATION.mission_name, + "Flawless", + SC2WOL_LOC_ID_OFFSET + 406, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_early_tech(state) + and logic.terran_defense_rating(state, True, False) >= 2 + and ( + (adv_tactics and logic.terran_basic_anti_air(state)) + or logic.terran_competent_anti_air(state) + ) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.EVACUATION.mission_name, + "Western Zerg Base", + SC2WOL_LOC_ID_OFFSET + 407, + LocationType.MASTERY, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_base_trasher(state) + and logic.terran_competent_anti_air(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.EVACUATION.mission_name, + "Eastern Zerg Base", + SC2WOL_LOC_ID_OFFSET + 408, + LocationType.MASTERY, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_base_trasher(state) + and logic.terran_competent_anti_air(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.OUTBREAK.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 500, + LocationType.VICTORY, + logic.terran_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK.mission_name, + "Left Infestor", + SC2WOL_LOC_ID_OFFSET + 501, + LocationType.VANILLA, + logic.terran_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK.mission_name, + "Right Infestor", + SC2WOL_LOC_ID_OFFSET + 502, + LocationType.VANILLA, + logic.terran_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK.mission_name, + "North Infested Command Center", + SC2WOL_LOC_ID_OFFSET + 503, + LocationType.EXTRA, + logic.terran_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK.mission_name, + "South Infested Command Center", + SC2WOL_LOC_ID_OFFSET + 504, + LocationType.EXTRA, + logic.terran_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK.mission_name, + "Northwest Bar", + SC2WOL_LOC_ID_OFFSET + 505, + LocationType.EXTRA, + logic.terran_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK.mission_name, + "North Bar", + SC2WOL_LOC_ID_OFFSET + 506, + LocationType.EXTRA, + logic.terran_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK.mission_name, + "South Bar", + SC2WOL_LOC_ID_OFFSET + 507, + LocationType.EXTRA, + logic.terran_outbreak_requirement, + ), + make_location_data( + SC2Mission.SAFE_HAVEN.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 600, + LocationType.VICTORY, + logic.terran_safe_haven_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.SAFE_HAVEN.mission_name, + "North Nexus", + SC2WOL_LOC_ID_OFFSET + 601, + LocationType.EXTRA, + logic.terran_safe_haven_requirement, + ), + make_location_data( + SC2Mission.SAFE_HAVEN.mission_name, + "East Nexus", + SC2WOL_LOC_ID_OFFSET + 602, + LocationType.EXTRA, + logic.terran_safe_haven_requirement, + ), + make_location_data( + SC2Mission.SAFE_HAVEN.mission_name, + "South Nexus", + SC2WOL_LOC_ID_OFFSET + 603, + LocationType.EXTRA, + logic.terran_safe_haven_requirement, + ), + make_location_data( + SC2Mission.SAFE_HAVEN.mission_name, + "First Terror Fleet", + SC2WOL_LOC_ID_OFFSET + 604, + LocationType.VANILLA, + logic.terran_safe_haven_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.SAFE_HAVEN.mission_name, + "Second Terror Fleet", + SC2WOL_LOC_ID_OFFSET + 605, + LocationType.VANILLA, + logic.terran_safe_haven_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.SAFE_HAVEN.mission_name, + "Third Terror Fleet", + SC2WOL_LOC_ID_OFFSET + 606, + LocationType.VANILLA, + logic.terran_safe_haven_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 700, + LocationType.VICTORY, + logic.terran_havens_fall_requirement, + hard_rule=logic.terran_any_anti_air_or_science_vessels, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "North Hive", + SC2WOL_LOC_ID_OFFSET + 701, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "East Hive", + SC2WOL_LOC_ID_OFFSET + 702, + LocationType.VANILLA, + logic.terran_havens_fall_requirement, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "South Hive", + SC2WOL_LOC_ID_OFFSET + 703, + LocationType.VANILLA, + logic.terran_havens_fall_requirement, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "Northeast Colony Base", + SC2WOL_LOC_ID_OFFSET + 704, + LocationType.CHALLENGE, + logic.terran_respond_to_colony_infestations, + hard_rule=logic.terran_any_anti_air_or_science_vessels, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "East Colony Base", + SC2WOL_LOC_ID_OFFSET + 705, + LocationType.CHALLENGE, + logic.terran_respond_to_colony_infestations, + hard_rule=logic.terran_any_anti_air_or_science_vessels, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "Middle Colony Base", + SC2WOL_LOC_ID_OFFSET + 706, + LocationType.CHALLENGE, + logic.terran_respond_to_colony_infestations, + hard_rule=logic.terran_any_anti_air_or_science_vessels, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "Southeast Colony Base", + SC2WOL_LOC_ID_OFFSET + 707, + LocationType.CHALLENGE, + logic.terran_respond_to_colony_infestations, + hard_rule=logic.terran_any_anti_air_or_science_vessels, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "Southwest Colony Base", + SC2WOL_LOC_ID_OFFSET + 708, + LocationType.CHALLENGE, + logic.terran_respond_to_colony_infestations, + hard_rule=logic.terran_any_anti_air_or_science_vessels, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "Southwest Gas Pickups", + SC2WOL_LOC_ID_OFFSET + 709, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "East Gas Pickups", + SC2WOL_LOC_ID_OFFSET + 710, + LocationType.EXTRA, + logic.terran_havens_fall_requirement, + ), + make_location_data( + SC2Mission.HAVENS_FALL.mission_name, + "Southeast Gas Pickups", + SC2WOL_LOC_ID_OFFSET + 711, + LocationType.EXTRA, + logic.terran_havens_fall_requirement, + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 800, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) + and ( + adv_tactics + and logic.terran_moderate_anti_air(state) + or logic.terran_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB.mission_name, + "First Relic", + SC2WOL_LOC_ID_OFFSET + 801, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB.mission_name, + "Second Relic", + SC2WOL_LOC_ID_OFFSET + 802, + LocationType.VANILLA, + lambda state: (adv_tactics or logic.terran_common_unit(state)), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB.mission_name, + "Third Relic", + SC2WOL_LOC_ID_OFFSET + 803, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and ( + adv_tactics + and logic.terran_moderate_anti_air(state) + or logic.terran_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB.mission_name, + "Fourth Relic", + SC2WOL_LOC_ID_OFFSET + 804, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and ( + adv_tactics + and logic.terran_moderate_anti_air(state) + or logic.terran_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB.mission_name, + "First Forcefield Area Busted", + SC2WOL_LOC_ID_OFFSET + 805, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and ( + adv_tactics + and logic.terran_moderate_anti_air(state) + or logic.terran_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB.mission_name, + "Second Forcefield Area Busted", + SC2WOL_LOC_ID_OFFSET + 806, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and ( + adv_tactics + and logic.terran_moderate_anti_air(state) + or logic.terran_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB.mission_name, + "Defeat Kerrigan", + SC2WOL_LOC_ID_OFFSET + 807, + LocationType.MASTERY, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_base_trasher(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 900, + LocationType.VICTORY, + lambda state: ( + ( + logic.terran_competent_anti_air(state) + or adv_tactics + and logic.terran_moderate_anti_air(state) + ) + and logic.terran_defense_rating(state, False, True) >= 8 + and logic.terran_common_unit(state) + and (logic.marine_medic_upgrade(state) or adv_tactics) + ), + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Left Relic", + SC2WOL_LOC_ID_OFFSET + 901, + LocationType.VANILLA, + lambda state: ( + logic.terran_defense_rating(state, False, False) >= 6 + and logic.terran_common_unit(state) + and (logic.marine_medic_upgrade(state) or adv_tactics) + ), + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Right Ground Relic", + SC2WOL_LOC_ID_OFFSET + 902, + LocationType.VANILLA, + lambda state: ( + logic.terran_defense_rating(state, False, False) >= 6 + and logic.terran_common_unit(state) + and (logic.marine_medic_upgrade(state) or adv_tactics) + ), + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Right Cliff Relic", + SC2WOL_LOC_ID_OFFSET + 903, + LocationType.VANILLA, + lambda state: ( + logic.terran_defense_rating(state, False, False) >= 6 + and logic.terran_common_unit(state) + and (logic.marine_medic_upgrade(state) or adv_tactics) + ), + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Moebius Base", + SC2WOL_LOC_ID_OFFSET + 904, + LocationType.EXTRA, + lambda state: logic.marine_medic_upgrade(state) or adv_tactics, + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Door Outer Layer", + SC2WOL_LOC_ID_OFFSET + 905, + LocationType.EXTRA, + lambda state: ( + logic.terran_defense_rating(state, False, False) >= 6 + and logic.terran_common_unit(state) + and (logic.marine_medic_upgrade(state) or adv_tactics) + ), + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Door Thermal Barrier", + SC2WOL_LOC_ID_OFFSET + 906, + LocationType.EXTRA, + lambda state: ( + ( + logic.terran_competent_anti_air(state) + or adv_tactics + and logic.terran_moderate_anti_air(state) + ) + and logic.terran_defense_rating(state, False, True) >= 8 + and logic.terran_common_unit(state) + and (logic.marine_medic_upgrade(state) or adv_tactics) + ), + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Cutting Through the Core", + SC2WOL_LOC_ID_OFFSET + 907, + LocationType.EXTRA, + lambda state: ( + ( + logic.terran_competent_anti_air(state) + or adv_tactics + and logic.terran_moderate_anti_air(state) + ) + and logic.terran_defense_rating(state, False, True) >= 8 + and logic.terran_common_unit(state) + and (logic.marine_medic_upgrade(state) or adv_tactics) + ), + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Structure Access Imminent", + SC2WOL_LOC_ID_OFFSET + 908, + LocationType.EXTRA, + lambda state: ( + ( + logic.terran_competent_anti_air(state) + or adv_tactics + and logic.terran_moderate_anti_air(state) + ) + and logic.terran_defense_rating(state, False, True) >= 8 + and logic.terran_common_unit(state) + and (logic.marine_medic_upgrade(state) or adv_tactics) + ), + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Northwestern Protoss Base", + SC2WOL_LOC_ID_OFFSET + 909, + LocationType.MASTERY, + lambda state: ( + logic.terran_beats_protoss_deathball(state) + and logic.terran_defense_rating(state, False, True) >= 8 + and logic.terran_common_unit(state) + and (logic.marine_medic_upgrade(state) or adv_tactics) + and logic.terran_base_trasher(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Northeastern Protoss Base", + SC2WOL_LOC_ID_OFFSET + 910, + LocationType.MASTERY, + lambda state: ( + logic.terran_beats_protoss_deathball(state) + and logic.terran_defense_rating(state, False, True) >= 8 + and logic.terran_common_unit(state) + and (logic.marine_medic_upgrade(state) or adv_tactics) + and logic.terran_base_trasher(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_DIG.mission_name, + "Eastern Protoss Base", + SC2WOL_LOC_ID_OFFSET + 911, + LocationType.MASTERY, + lambda state: ( + logic.terran_beats_protoss_deathball(state) + and logic.terran_defense_rating(state, False, True) >= 8 + and logic.terran_common_unit(state) + and logic.terran_base_trasher(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 1000, + LocationType.VICTORY, + lambda state: ( + ( + logic.terran_moderate_anti_air(state) + and state.has_any({item_names.MEDIVAC, item_names.HERCULES}, player) + or logic.terran_air_anti_air(state) + ) + and ( + logic.terran_air(state) + or state.has_any({item_names.MEDIVAC, item_names.HERCULES}, player) + and logic.terran_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR.mission_name, + "1st Data Core", + SC2WOL_LOC_ID_OFFSET + 1001, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR.mission_name, + "2nd Data Core", + SC2WOL_LOC_ID_OFFSET + 1002, + LocationType.VANILLA, + lambda state: ( + logic.terran_air(state) + or ( + state.has_any({item_names.MEDIVAC, item_names.HERCULES}, player) + and logic.terran_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR.mission_name, + "South Rescue", + SC2WOL_LOC_ID_OFFSET + 1003, + LocationType.EXTRA, + logic.terran_can_rescue, + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR.mission_name, + "Wall Rescue", + SC2WOL_LOC_ID_OFFSET + 1004, + LocationType.EXTRA, + logic.terran_can_rescue, + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR.mission_name, + "Mid Rescue", + SC2WOL_LOC_ID_OFFSET + 1005, + LocationType.EXTRA, + logic.terran_can_rescue, + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR.mission_name, + "Nydus Roof Rescue", + SC2WOL_LOC_ID_OFFSET + 1006, + LocationType.EXTRA, + logic.terran_can_rescue, + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR.mission_name, + "Alive Inside Rescue", + SC2WOL_LOC_ID_OFFSET + 1007, + LocationType.EXTRA, + logic.terran_can_rescue, + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR.mission_name, + "Brutalisk", + SC2WOL_LOC_ID_OFFSET + 1008, + LocationType.VANILLA, + lambda state: ( + ( + logic.terran_moderate_anti_air(state) + and state.has_any({item_names.MEDIVAC, item_names.HERCULES}, player) + or logic.terran_air_anti_air(state) + ) + and ( + logic.terran_air(state) + or state.has_any({item_names.MEDIVAC, item_names.HERCULES}, player) + and logic.terran_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR.mission_name, + "3rd Data Core", + SC2WOL_LOC_ID_OFFSET + 1009, + LocationType.VANILLA, + lambda state: ( + ( + logic.terran_moderate_anti_air(state) + and state.has_any({item_names.MEDIVAC, item_names.HERCULES}, player) + or logic.terran_air_anti_air(state) + ) + and ( + logic.terran_air(state) + or state.has_any({item_names.MEDIVAC, item_names.HERCULES}, player) + and logic.terran_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.SUPERNOVA.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 1100, + LocationType.VICTORY, + logic.terran_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA.mission_name, + "West Relic", + SC2WOL_LOC_ID_OFFSET + 1101, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.SUPERNOVA.mission_name, + "North Relic", + SC2WOL_LOC_ID_OFFSET + 1102, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.SUPERNOVA.mission_name, + "South Relic", + SC2WOL_LOC_ID_OFFSET + 1103, + LocationType.VANILLA, + logic.terran_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA.mission_name, + "East Relic", + SC2WOL_LOC_ID_OFFSET + 1104, + LocationType.VANILLA, + logic.terran_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA.mission_name, + "Landing Zone Cleared", + SC2WOL_LOC_ID_OFFSET + 1105, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.SUPERNOVA.mission_name, + "Middle Base", + SC2WOL_LOC_ID_OFFSET + 1106, + LocationType.EXTRA, + logic.terran_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA.mission_name, + "Southeast Base", + SC2WOL_LOC_ID_OFFSET + 1107, + LocationType.EXTRA, + logic.terran_supernova_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 1200, + LocationType.VICTORY, + logic.terran_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "Landing Zone Cleared", + SC2WOL_LOC_ID_OFFSET + 1201, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "Expansion Prisoners", + SC2WOL_LOC_ID_OFFSET + 1202, + LocationType.VANILLA, + lambda state: adv_tactics or logic.terran_maw_requirement(state), + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "South Close Prisoners", + SC2WOL_LOC_ID_OFFSET + 1203, + LocationType.VANILLA, + lambda state: adv_tactics or logic.terran_maw_requirement(state), + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "South Far Prisoners", + SC2WOL_LOC_ID_OFFSET + 1204, + LocationType.VANILLA, + logic.terran_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "North Prisoners", + SC2WOL_LOC_ID_OFFSET + 1205, + LocationType.VANILLA, + logic.terran_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "Mothership", + SC2WOL_LOC_ID_OFFSET + 1206, + LocationType.EXTRA, + logic.terran_maw_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "Expansion Rip Field Generator", + SC2WOL_LOC_ID_OFFSET + 1207, + LocationType.EXTRA, + lambda state: adv_tactics or logic.terran_maw_requirement(state), + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "Middle Rip Field Generator", + SC2WOL_LOC_ID_OFFSET + 1208, + LocationType.EXTRA, + logic.terran_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "Southeast Rip Field Generator", + SC2WOL_LOC_ID_OFFSET + 1209, + LocationType.EXTRA, + logic.terran_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "Stargate Rip Field Generator", + SC2WOL_LOC_ID_OFFSET + 1210, + LocationType.EXTRA, + logic.terran_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "Northwest Rip Field Generator", + SC2WOL_LOC_ID_OFFSET + 1211, + LocationType.CHALLENGE, + logic.terran_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "West Rip Field Generator", + SC2WOL_LOC_ID_OFFSET + 1212, + LocationType.CHALLENGE, + logic.terran_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID.mission_name, + "Southwest Rip Field Generator", + SC2WOL_LOC_ID_OFFSET + 1213, + LocationType.CHALLENGE, + logic.terran_maw_requirement, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 1300, + LocationType.VICTORY, + lambda state: ( + adv_tactics + or logic.terran_moderate_anti_air(state) + and ( + logic.terran_common_unit(state) + or state.has(item_names.REAPER, player) + ) + ), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND.mission_name, + "Tosh's Miners", + SC2WOL_LOC_ID_OFFSET + 1301, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND.mission_name, + "Brutalisk", + SC2WOL_LOC_ID_OFFSET + 1302, + LocationType.VANILLA, + lambda state: adv_tactics + or logic.terran_common_unit(state) + or state.has(item_names.REAPER, player), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND.mission_name, + "North Reapers", + SC2WOL_LOC_ID_OFFSET + 1303, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND.mission_name, + "Middle Reapers", + SC2WOL_LOC_ID_OFFSET + 1304, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND.mission_name, + "Southwest Reapers", + SC2WOL_LOC_ID_OFFSET + 1305, + LocationType.EXTRA, + lambda state: adv_tactics + or logic.terran_common_unit(state) + or state.has(item_names.REAPER, player), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND.mission_name, + "Southeast Reapers", + SC2WOL_LOC_ID_OFFSET + 1306, + LocationType.EXTRA, + lambda state: ( + adv_tactics + or logic.terran_moderate_anti_air(state) + and ( + logic.terran_common_unit(state) + or state.has(item_names.REAPER, player) + ) + ), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND.mission_name, + "East Reapers", + SC2WOL_LOC_ID_OFFSET + 1307, + LocationType.EXTRA, + lambda state: ( + logic.terran_moderate_anti_air(state) + and ( + adv_tactics + or logic.terran_common_unit(state) + or state.has(item_names.REAPER, player) + ) + ), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND.mission_name, + "Zerg Cleared", + SC2WOL_LOC_ID_OFFSET + 1308, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_competent_anti_air(state) + and ( + logic.terran_common_unit(state) + or state.has(item_names.REAPER, player) + ) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 1400, + LocationType.VICTORY, + logic.terran_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "Close Relic", + SC2WOL_LOC_ID_OFFSET + 1401, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "West Relic", + SC2WOL_LOC_ID_OFFSET + 1402, + LocationType.VANILLA, + logic.terran_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "North-East Relic", + SC2WOL_LOC_ID_OFFSET + 1403, + LocationType.VANILLA, + logic.terran_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "Middle Base", + SC2WOL_LOC_ID_OFFSET + 1404, + LocationType.EXTRA, + logic.terran_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "Protoss Cleared", + SC2WOL_LOC_ID_OFFSET + 1405, + LocationType.MASTERY, + lambda state: ( + logic.terran_welcome_to_the_jungle_requirement(state) + and logic.terran_beats_protoss_deathball(state) + and logic.terran_base_trasher(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "No Terrazine Nodes Sealed", + SC2WOL_LOC_ID_OFFSET + 1406, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_welcome_to_the_jungle_requirement(state) + and logic.terran_competent_ground_to_air(state) + and logic.terran_beats_protoss_deathball(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "Up to 1 Terrazine Node Sealed", + SC2WOL_LOC_ID_OFFSET + 1407, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_welcome_to_the_jungle_requirement(state) + and logic.terran_competent_ground_to_air(state) + and logic.terran_beats_protoss_deathball(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "Up to 2 Terrazine Nodes Sealed", + SC2WOL_LOC_ID_OFFSET + 1408, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_welcome_to_the_jungle_requirement(state) + and logic.terran_beats_protoss_deathball(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "Up to 3 Terrazine Nodes Sealed", + SC2WOL_LOC_ID_OFFSET + 1409, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_welcome_to_the_jungle_requirement(state) + and logic.terran_competent_comp(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "Up to 4 Terrazine Nodes Sealed", + SC2WOL_LOC_ID_OFFSET + 1410, + LocationType.EXTRA, + logic.terran_welcome_to_the_jungle_requirement, + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + "Up to 5 Terrazine Nodes Sealed", + SC2WOL_LOC_ID_OFFSET + 1411, + LocationType.EXTRA, + logic.terran_welcome_to_the_jungle_requirement, + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.BREAKOUT.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 1500, + LocationType.VICTORY, + ), + make_location_data( + SC2Mission.BREAKOUT.mission_name, + "Diamondback Prison", + SC2WOL_LOC_ID_OFFSET + 1501, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.BREAKOUT.mission_name, + "Siege Tank Prison", + SC2WOL_LOC_ID_OFFSET + 1502, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.BREAKOUT.mission_name, + "First Checkpoint", + SC2WOL_LOC_ID_OFFSET + 1503, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.BREAKOUT.mission_name, + "Second Checkpoint", + SC2WOL_LOC_ID_OFFSET + 1504, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.GHOST_OF_A_CHANCE.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 1600, + LocationType.VICTORY, + logic.ghost_of_a_chance_requirement, + hard_rule=logic.ghost_of_a_chance_requirement, + ), + make_location_data( + SC2Mission.GHOST_OF_A_CHANCE.mission_name, + "Terrazine Tank", + SC2WOL_LOC_ID_OFFSET + 1601, + LocationType.EXTRA, + logic.ghost_of_a_chance_requirement, + hard_rule=logic.ghost_of_a_chance_requirement, + ), + make_location_data( + SC2Mission.GHOST_OF_A_CHANCE.mission_name, + "Jorium Stockpile", + SC2WOL_LOC_ID_OFFSET + 1602, + LocationType.EXTRA, + logic.ghost_of_a_chance_requirement, + hard_rule=logic.ghost_of_a_chance_requirement, + ), + make_location_data( + SC2Mission.GHOST_OF_A_CHANCE.mission_name, + "First Island Spectres", + SC2WOL_LOC_ID_OFFSET + 1603, + LocationType.VANILLA, + logic.ghost_of_a_chance_requirement, + hard_rule=logic.ghost_of_a_chance_requirement, + ), + make_location_data( + SC2Mission.GHOST_OF_A_CHANCE.mission_name, + "Second Island Spectres", + SC2WOL_LOC_ID_OFFSET + 1604, + LocationType.VANILLA, + logic.ghost_of_a_chance_requirement, + hard_rule=logic.ghost_of_a_chance_requirement, + ), + make_location_data( + SC2Mission.GHOST_OF_A_CHANCE.mission_name, + "Third Island Spectres", + SC2WOL_LOC_ID_OFFSET + 1605, + LocationType.VANILLA, + logic.ghost_of_a_chance_requirement, + hard_rule=logic.ghost_of_a_chance_requirement, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 1700, + LocationType.VICTORY, + lambda state: ( + logic.terran_great_train_robbery_train_stopper(state) + and logic.terran_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "North Defiler", + SC2WOL_LOC_ID_OFFSET + 1701, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "Mid Defiler", + SC2WOL_LOC_ID_OFFSET + 1702, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "South Defiler", + SC2WOL_LOC_ID_OFFSET + 1703, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "Close Diamondback", + SC2WOL_LOC_ID_OFFSET + 1704, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "Northwest Diamondback", + SC2WOL_LOC_ID_OFFSET + 1705, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "North Diamondback", + SC2WOL_LOC_ID_OFFSET + 1706, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "Northeast Diamondback", + SC2WOL_LOC_ID_OFFSET + 1707, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "Southwest Diamondback", + SC2WOL_LOC_ID_OFFSET + 1708, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "Southeast Diamondback", + SC2WOL_LOC_ID_OFFSET + 1709, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "Kill Team", + SC2WOL_LOC_ID_OFFSET + 1710, + LocationType.CHALLENGE, + lambda state: ( + (adv_tactics or logic.terran_common_unit(state)) + and logic.terran_great_train_robbery_train_stopper(state) + and logic.terran_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "Flawless", + SC2WOL_LOC_ID_OFFSET + 1711, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_great_train_robbery_train_stopper(state) + and logic.terran_basic_anti_air(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "2 Trains Destroyed", + SC2WOL_LOC_ID_OFFSET + 1712, + LocationType.EXTRA, + logic.terran_great_train_robbery_train_stopper, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "4 Trains Destroyed", + SC2WOL_LOC_ID_OFFSET + 1713, + LocationType.EXTRA, + lambda state: ( + logic.terran_great_train_robbery_train_stopper(state) + and logic.terran_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name, + "6 Trains Destroyed", + SC2WOL_LOC_ID_OFFSET + 1714, + LocationType.EXTRA, + lambda state: ( + logic.terran_great_train_robbery_train_stopper(state) + and logic.terran_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.CUTTHROAT.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 1800, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) + and (adv_tactics or logic.terran_moderate_anti_air(state)) + ), + ), + make_location_data( + SC2Mission.CUTTHROAT.mission_name, + "Mira Han", + SC2WOL_LOC_ID_OFFSET + 1801, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT.mission_name, + "North Relic", + SC2WOL_LOC_ID_OFFSET + 1802, + LocationType.VANILLA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT.mission_name, + "Mid Relic", + SC2WOL_LOC_ID_OFFSET + 1803, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.CUTTHROAT.mission_name, + "Southwest Relic", + SC2WOL_LOC_ID_OFFSET + 1804, + LocationType.VANILLA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT.mission_name, + "North Command Center", + SC2WOL_LOC_ID_OFFSET + 1805, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT.mission_name, + "South Command Center", + SC2WOL_LOC_ID_OFFSET + 1806, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT.mission_name, + "West Command Center", + SC2WOL_LOC_ID_OFFSET + 1807, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 1900, + LocationType.VICTORY, + logic.terran_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION.mission_name, + "Odin", + SC2WOL_LOC_ID_OFFSET + 1901, + LocationType.EXTRA, + logic.marine_medic_upgrade, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION.mission_name, + "Loki", + SC2WOL_LOC_ID_OFFSET + 1902, + LocationType.CHALLENGE, + logic.terran_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION.mission_name, + "Lab Devourer", + SC2WOL_LOC_ID_OFFSET + 1903, + LocationType.VANILLA, + logic.marine_medic_upgrade, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION.mission_name, + "North Devourer", + SC2WOL_LOC_ID_OFFSET + 1904, + LocationType.VANILLA, + logic.terran_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION.mission_name, + "Southeast Devourer", + SC2WOL_LOC_ID_OFFSET + 1905, + LocationType.VANILLA, + logic.terran_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION.mission_name, + "West Base", + SC2WOL_LOC_ID_OFFSET + 1906, + LocationType.EXTRA, + logic.terran_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION.mission_name, + "Northwest Base", + SC2WOL_LOC_ID_OFFSET + 1907, + LocationType.EXTRA, + logic.terran_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION.mission_name, + "Northeast Base", + SC2WOL_LOC_ID_OFFSET + 1908, + LocationType.EXTRA, + logic.terran_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION.mission_name, + "Southeast Base", + SC2WOL_LOC_ID_OFFSET + 1909, + LocationType.EXTRA, + logic.terran_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 2000, + LocationType.VICTORY, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ.mission_name, + "Tower 1", + SC2WOL_LOC_ID_OFFSET + 2001, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ.mission_name, + "Tower 2", + SC2WOL_LOC_ID_OFFSET + 2002, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ.mission_name, + "Tower 3", + SC2WOL_LOC_ID_OFFSET + 2003, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ.mission_name, + "Science Facility", + SC2WOL_LOC_ID_OFFSET + 2004, + LocationType.VANILLA, + lambda state: adv_tactics or logic.terran_competent_comp(state), + ), + make_location_data( + SC2Mission.MEDIA_BLITZ.mission_name, + "All Barracks", + SC2WOL_LOC_ID_OFFSET + 2005, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ.mission_name, + "All Factories", + SC2WOL_LOC_ID_OFFSET + 2006, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ.mission_name, + "All Starports", + SC2WOL_LOC_ID_OFFSET + 2007, + LocationType.EXTRA, + lambda state: adv_tactics or logic.terran_competent_comp(state), + ), + make_location_data( + SC2Mission.MEDIA_BLITZ.mission_name, + "Odin Not Trashed", + SC2WOL_LOC_ID_OFFSET + 2008, + LocationType.CHALLENGE, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ.mission_name, + "Surprise Attack Ends", + SC2WOL_LOC_ID_OFFSET + 2009, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.PIERCING_OF_THE_SHROUD.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 2100, + LocationType.VICTORY, + logic.marine_medic_upgrade, + ), + make_location_data( + SC2Mission.PIERCING_OF_THE_SHROUD.mission_name, + "Holding Cell Relic", + SC2WOL_LOC_ID_OFFSET + 2101, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.PIERCING_OF_THE_SHROUD.mission_name, + "Brutalisk Relic", + SC2WOL_LOC_ID_OFFSET + 2102, + LocationType.VANILLA, + logic.marine_medic_upgrade, + ), + make_location_data( + SC2Mission.PIERCING_OF_THE_SHROUD.mission_name, + "First Escape Relic", + SC2WOL_LOC_ID_OFFSET + 2103, + LocationType.VANILLA, + logic.marine_medic_upgrade, + ), + make_location_data( + SC2Mission.PIERCING_OF_THE_SHROUD.mission_name, + "Second Escape Relic", + SC2WOL_LOC_ID_OFFSET + 2104, + LocationType.VANILLA, + logic.marine_medic_upgrade, + ), + make_location_data( + SC2Mission.PIERCING_OF_THE_SHROUD.mission_name, + "Brutalisk", + SC2WOL_LOC_ID_OFFSET + 2105, + LocationType.VANILLA, + logic.marine_medic_upgrade, + ), + make_location_data( + SC2Mission.PIERCING_OF_THE_SHROUD.mission_name, + "Fusion Reactor", + SC2WOL_LOC_ID_OFFSET + 2106, + LocationType.EXTRA, + logic.marine_medic_upgrade, + ), + make_location_data( + SC2Mission.PIERCING_OF_THE_SHROUD.mission_name, + "Entrance Holding Pen", + SC2WOL_LOC_ID_OFFSET + 2107, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.PIERCING_OF_THE_SHROUD.mission_name, + "Cargo Bay Warbot", + SC2WOL_LOC_ID_OFFSET + 2108, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.PIERCING_OF_THE_SHROUD.mission_name, + "Escape Warbot", + SC2WOL_LOC_ID_OFFSET + 2109, + LocationType.EXTRA, + logic.marine_medic_upgrade, + ), + make_location_data( + SC2Mission.WHISPERS_OF_DOOM.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 2200, + LocationType.VICTORY, + ), + make_location_data( + SC2Mission.WHISPERS_OF_DOOM.mission_name, + "First Hatchery", + SC2WOL_LOC_ID_OFFSET + 2201, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WHISPERS_OF_DOOM.mission_name, + "Second Hatchery", + SC2WOL_LOC_ID_OFFSET + 2202, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WHISPERS_OF_DOOM.mission_name, + "Third Hatchery", + SC2WOL_LOC_ID_OFFSET + 2203, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WHISPERS_OF_DOOM.mission_name, + "First Prophecy Fragment", + SC2WOL_LOC_ID_OFFSET + 2204, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.WHISPERS_OF_DOOM.mission_name, + "Second Prophecy Fragment", + SC2WOL_LOC_ID_OFFSET + 2205, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.WHISPERS_OF_DOOM.mission_name, + "Third Prophecy Fragment", + SC2WOL_LOC_ID_OFFSET + 2206, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.A_SINISTER_TURN.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 2300, + LocationType.VICTORY, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN.mission_name, + "Robotics Facility", + SC2WOL_LOC_ID_OFFSET + 2301, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN.mission_name, + "Dark Shrine", + SC2WOL_LOC_ID_OFFSET + 2302, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN.mission_name, + "Templar Archives", + SC2WOL_LOC_ID_OFFSET + 2303, + LocationType.VANILLA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN.mission_name, + "Northeast Base", + SC2WOL_LOC_ID_OFFSET + 2304, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN.mission_name, + "Southwest Base", + SC2WOL_LOC_ID_OFFSET + 2305, + LocationType.CHALLENGE, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_competent_anti_air(state), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.A_SINISTER_TURN.mission_name, + "Maar", + SC2WOL_LOC_ID_OFFSET + 2306, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.A_SINISTER_TURN.mission_name, + "Northwest Preserver", + SC2WOL_LOC_ID_OFFSET + 2307, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN.mission_name, + "Southwest Preserver", + SC2WOL_LOC_ID_OFFSET + 2308, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN.mission_name, + "East Preserver", + SC2WOL_LOC_ID_OFFSET + 2309, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_competent_anti_air(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 2400, + LocationType.VICTORY, + lambda state: ( + (adv_tactics and logic.protoss_static_defense(state)) + or ( + logic.protoss_common_unit(state) + and logic.protoss_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE.mission_name, + "Close Obelisk", + SC2WOL_LOC_ID_OFFSET + 2401, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE.mission_name, + "West Obelisk", + SC2WOL_LOC_ID_OFFSET + 2402, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE.mission_name, + "Base", + SC2WOL_LOC_ID_OFFSET + 2403, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE.mission_name, + "Southwest Tendril", + SC2WOL_LOC_ID_OFFSET + 2404, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE.mission_name, + "Southeast Tendril", + SC2WOL_LOC_ID_OFFSET + 2405, + LocationType.EXTRA, + lambda state: adv_tactics + and logic.protoss_static_defense(state) + or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE.mission_name, + "Northeast Tendril", + SC2WOL_LOC_ID_OFFSET + 2406, + LocationType.EXTRA, + lambda state: adv_tactics + and logic.protoss_static_defense(state) + or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE.mission_name, + "Northwest Tendril", + SC2WOL_LOC_ID_OFFSET + 2407, + LocationType.EXTRA, + lambda state: adv_tactics + and logic.protoss_static_defense(state) + or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS.mission_name, + "Defeat", + SC2WOL_LOC_ID_OFFSET + 2500, + LocationType.VICTORY, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS.mission_name, + "Protoss Archive", + SC2WOL_LOC_ID_OFFSET + 2501, + LocationType.VANILLA, + logic.protoss_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS.mission_name, + "Kills", + SC2WOL_LOC_ID_OFFSET + 2502, + LocationType.VANILLA, + logic.protoss_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS.mission_name, + "Urun", + SC2WOL_LOC_ID_OFFSET + 2503, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS.mission_name, + "Mohandar", + SC2WOL_LOC_ID_OFFSET + 2504, + LocationType.EXTRA, + logic.protoss_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS.mission_name, + "Selendis", + SC2WOL_LOC_ID_OFFSET + 2505, + LocationType.EXTRA, + logic.protoss_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS.mission_name, + "Artanis", + SC2WOL_LOC_ID_OFFSET + 2506, + LocationType.EXTRA, + logic.protoss_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 2600, + LocationType.VICTORY, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "Large Army", + SC2WOL_LOC_ID_OFFSET + 2601, + LocationType.VANILLA, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "2 Drop Pods", + SC2WOL_LOC_ID_OFFSET + 2602, + LocationType.VANILLA, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "4 Drop Pods", + SC2WOL_LOC_ID_OFFSET + 2603, + LocationType.VANILLA, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "6 Drop Pods", + SC2WOL_LOC_ID_OFFSET + 2604, + LocationType.EXTRA, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "8 Drop Pods", + SC2WOL_LOC_ID_OFFSET + 2605, + LocationType.CHALLENGE, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "Southwest Spore Cannon", + SC2WOL_LOC_ID_OFFSET + 2606, + LocationType.EXTRA, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "Northwest Spore Cannon", + SC2WOL_LOC_ID_OFFSET + 2607, + LocationType.EXTRA, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "Northeast Spore Cannon", + SC2WOL_LOC_ID_OFFSET + 2608, + LocationType.EXTRA, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "East Spore Cannon", + SC2WOL_LOC_ID_OFFSET + 2609, + LocationType.EXTRA, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "Southeast Spore Cannon", + SC2WOL_LOC_ID_OFFSET + 2610, + LocationType.EXTRA, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL.mission_name, + "Expansion Spore Cannon", + SC2WOL_LOC_ID_OFFSET + 2611, + LocationType.EXTRA, + logic.terran_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.BELLY_OF_THE_BEAST.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 2700, + LocationType.VICTORY, + lambda state: adv_tactics or logic.marine_medic_firebat_upgrade(state), + ), + make_location_data( + SC2Mission.BELLY_OF_THE_BEAST.mission_name, + "First Charge", + SC2WOL_LOC_ID_OFFSET + 2701, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.BELLY_OF_THE_BEAST.mission_name, + "Second Charge", + SC2WOL_LOC_ID_OFFSET + 2702, + LocationType.EXTRA, + lambda state: adv_tactics or logic.marine_medic_firebat_upgrade(state), + ), + make_location_data( + SC2Mission.BELLY_OF_THE_BEAST.mission_name, + "Third Charge", + SC2WOL_LOC_ID_OFFSET + 2703, + LocationType.EXTRA, + lambda state: adv_tactics or logic.marine_medic_firebat_upgrade(state), + ), + make_location_data( + SC2Mission.BELLY_OF_THE_BEAST.mission_name, + "First Group Rescued", + SC2WOL_LOC_ID_OFFSET + 2704, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.BELLY_OF_THE_BEAST.mission_name, + "Second Group Rescued", + SC2WOL_LOC_ID_OFFSET + 2705, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.BELLY_OF_THE_BEAST.mission_name, + "Third Group Rescued", + SC2WOL_LOC_ID_OFFSET + 2706, + LocationType.VANILLA, + lambda state: adv_tactics or logic.marine_medic_firebat_upgrade(state), + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 2800, + LocationType.VICTORY, + lambda state: logic.terran_competent_comp(state) + and logic.terran_army_weapon_armor_upgrade_min_level(state) >= 2, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY.mission_name, + "Close Coolant Tower", + SC2WOL_LOC_ID_OFFSET + 2801, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY.mission_name, + "Northwest Coolant Tower", + SC2WOL_LOC_ID_OFFSET + 2802, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY.mission_name, + "Southeast Coolant Tower", + SC2WOL_LOC_ID_OFFSET + 2803, + LocationType.VANILLA, + lambda state: logic.terran_competent_comp(state) + and logic.terran_army_weapon_armor_upgrade_min_level(state) >= 2, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY.mission_name, + "Southwest Coolant Tower", + SC2WOL_LOC_ID_OFFSET + 2804, + LocationType.VANILLA, + lambda state: logic.terran_competent_comp(state) + and logic.terran_army_weapon_armor_upgrade_min_level(state) >= 2, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY.mission_name, + "Leviathan", + SC2WOL_LOC_ID_OFFSET + 2805, + LocationType.VANILLA, + lambda state: logic.terran_competent_comp(state) + and logic.terran_army_weapon_armor_upgrade_min_level(state) >= 2, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY.mission_name, + "East Hatchery", + SC2WOL_LOC_ID_OFFSET + 2806, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY.mission_name, + "North Hatchery", + SC2WOL_LOC_ID_OFFSET + 2807, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY.mission_name, + "Mid Hatchery", + SC2WOL_LOC_ID_OFFSET + 2808, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.ALL_IN.mission_name, + "Victory", + SC2WOL_LOC_ID_OFFSET + 2900, + LocationType.VICTORY, + logic.terran_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN.mission_name, + "First Kerrigan Attack", + SC2WOL_LOC_ID_OFFSET + 2901, + LocationType.EXTRA, + logic.terran_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN.mission_name, + "Second Kerrigan Attack", + SC2WOL_LOC_ID_OFFSET + 2902, + LocationType.EXTRA, + logic.terran_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN.mission_name, + "Third Kerrigan Attack", + SC2WOL_LOC_ID_OFFSET + 2903, + LocationType.EXTRA, + logic.terran_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN.mission_name, + "Fourth Kerrigan Attack", + SC2WOL_LOC_ID_OFFSET + 2904, + LocationType.EXTRA, + logic.terran_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN.mission_name, + "Fifth Kerrigan Attack", + SC2WOL_LOC_ID_OFFSET + 2905, + LocationType.EXTRA, + logic.terran_all_in_requirement, + ), + # HotS + make_location_data( + SC2Mission.LAB_RAT.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 100, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit + or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) + ), + ), + make_location_data( + SC2Mission.LAB_RAT.mission_name, + "Gather Minerals", + SC2HOTS_LOC_ID_OFFSET + 101, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.LAB_RAT.mission_name, + "South Zergling Group", + SC2HOTS_LOC_ID_OFFSET + 102, + LocationType.VANILLA, + lambda state: adv_tactics + or ( + logic.zerg_common_unit + or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) + ), + ), + make_location_data( + SC2Mission.LAB_RAT.mission_name, + "East Zergling Group", + SC2HOTS_LOC_ID_OFFSET + 103, + LocationType.VANILLA, + lambda state: adv_tactics + or ( + logic.zerg_common_unit + or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) + ), + ), + make_location_data( + SC2Mission.LAB_RAT.mission_name, + "West Zergling Group", + SC2HOTS_LOC_ID_OFFSET + 104, + LocationType.VANILLA, + lambda state: adv_tactics + or ( + logic.zerg_common_unit + or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) + ), + ), + make_location_data( + SC2Mission.LAB_RAT.mission_name, + "Hatchery", + SC2HOTS_LOC_ID_OFFSET + 105, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.LAB_RAT.mission_name, + "Overlord", + SC2HOTS_LOC_ID_OFFSET + 106, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.LAB_RAT.mission_name, + "Gas Turrets", + SC2HOTS_LOC_ID_OFFSET + 107, + LocationType.EXTRA, + lambda state: adv_tactics + or ( + logic.zerg_common_unit + or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) + ), + ), + make_location_data( + SC2Mission.LAB_RAT.mission_name, + "Win In Under 10 Minutes", + SC2HOTS_LOC_ID_OFFSET + 108, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_common_unit + or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) + ), + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.BACK_IN_THE_SADDLE.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 200, + LocationType.VICTORY, + lambda state: logic.basic_kerrigan(state) + or kerriganless + or logic.grant_story_tech == GrantStoryTech.option_grant, + hard_rule=logic.zerg_any_units_back_in_the_saddle_requirement, + ), + make_location_data( + SC2Mission.BACK_IN_THE_SADDLE.mission_name, + "Defend the Tram", + SC2HOTS_LOC_ID_OFFSET + 201, + LocationType.EXTRA, + lambda state: logic.basic_kerrigan(state) + or kerriganless + or logic.grant_story_tech == GrantStoryTech.option_grant, + hard_rule=logic.zerg_any_units_back_in_the_saddle_requirement, + ), + make_location_data( + SC2Mission.BACK_IN_THE_SADDLE.mission_name, + "Kinetic Blast", + SC2HOTS_LOC_ID_OFFSET + 202, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.BACK_IN_THE_SADDLE.mission_name, + "Crushing Grip", + SC2HOTS_LOC_ID_OFFSET + 203, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.BACK_IN_THE_SADDLE.mission_name, + "Reach the Sublevel", + SC2HOTS_LOC_ID_OFFSET + 204, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.BACK_IN_THE_SADDLE.mission_name, + "Door Section Cleared", + SC2HOTS_LOC_ID_OFFSET + 205, + LocationType.EXTRA, + lambda state: logic.basic_kerrigan(state) + or kerriganless + or logic.grant_story_tech == GrantStoryTech.option_grant, + hard_rule=logic.zerg_any_units_back_in_the_saddle_requirement, + ), + make_location_data( + SC2Mission.RENDEZVOUS.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 300, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_basic_anti_air(state) + and logic.zerg_defense_rating(state, False, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS.mission_name, + "Right Queen", + SC2HOTS_LOC_ID_OFFSET + 301, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_basic_anti_air(state) + and logic.zerg_defense_rating(state, False, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS.mission_name, + "Center Queen", + SC2HOTS_LOC_ID_OFFSET + 302, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_basic_anti_air(state) + and logic.zerg_defense_rating(state, False, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS.mission_name, + "Left Queen", + SC2HOTS_LOC_ID_OFFSET + 303, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_basic_anti_air(state) + and logic.zerg_defense_rating(state, False, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS.mission_name, + "Hold Out Finished", + SC2HOTS_LOC_ID_OFFSET + 304, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_basic_anti_air(state) + and logic.zerg_defense_rating(state, False, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS.mission_name, + "Kill All Buildings Before Reinforcements", + SC2HOTS_LOC_ID_OFFSET + 305, + LocationType.MASTERY, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_competent_anti_air(state) + and (logic.basic_kerrigan(state) or kerriganless) + and logic.zerg_defense_rating(state, False, False) >= 3 + and logic.zerg_power_rating(state) >= 5 + ), + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 400, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS.mission_name, + "First Ursadon Matriarch", + SC2HOTS_LOC_ID_OFFSET + 401, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS.mission_name, + "North Ursadon Matriarch", + SC2HOTS_LOC_ID_OFFSET + 402, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS.mission_name, + "West Ursadon Matriarch", + SC2HOTS_LOC_ID_OFFSET + 403, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS.mission_name, + "Lost Brood", + SC2HOTS_LOC_ID_OFFSET + 404, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS.mission_name, + "Northeast Psi-link Spire", + SC2HOTS_LOC_ID_OFFSET + 405, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS.mission_name, + "Northwest Psi-link Spire", + SC2HOTS_LOC_ID_OFFSET + 406, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS.mission_name, + "Southwest Psi-link Spire", + SC2HOTS_LOC_ID_OFFSET + 407, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS.mission_name, + "Nafash", + SC2HOTS_LOC_ID_OFFSET + 408, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS.mission_name, + "20 Unfrozen Structures", + SC2HOTS_LOC_ID_OFFSET + 409, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 500, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "East Stasis Chamber", + SC2HOTS_LOC_ID_OFFSET + 501, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "Center Stasis Chamber", + SC2HOTS_LOC_ID_OFFSET + 502, + LocationType.VANILLA, + lambda state: logic.zerg_common_unit(state) or adv_tactics, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "West Stasis Chamber", + SC2HOTS_LOC_ID_OFFSET + 503, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "Destroy 4 Shuttles", + SC2HOTS_LOC_ID_OFFSET + 504, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "Frozen Expansion", + SC2HOTS_LOC_ID_OFFSET + 505, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "Southwest Frozen Zerg", + SC2HOTS_LOC_ID_OFFSET + 506, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "Southeast Frozen Zerg", + SC2HOTS_LOC_ID_OFFSET + 507, + LocationType.EXTRA, + lambda state: logic.zerg_common_unit(state) or adv_tactics, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "West Frozen Zerg", + SC2HOTS_LOC_ID_OFFSET + 508, + LocationType.EXTRA, + logic.zerg_common_unit_competent_aa, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "East Frozen Zerg", + SC2HOTS_LOC_ID_OFFSET + 509, + LocationType.EXTRA, + logic.zerg_common_unit_competent_aa, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "West Launch Bay", + SC2HOTS_LOC_ID_OFFSET + 510, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "Center Launch Bay", + SC2HOTS_LOC_ID_OFFSET + 511, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER.mission_name, + "East Launch Bay", + SC2HOTS_LOC_ID_OFFSET + 512, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ENEMY_WITHIN.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 600, + LocationType.VICTORY, + lambda state: ( + logic.zerg_pass_vents(state) + and ( + logic.grant_story_tech == GrantStoryTech.option_grant + or state.has_any( + { + item_names.ZERGLING_RAPTOR_STRAIN, + item_names.ROACH, + item_names.HYDRALISK, + item_names.INFESTOR, + }, + player, + ) + ) + ), + hard_rule=logic.zerg_pass_vents, + ), + make_location_data( + SC2Mission.ENEMY_WITHIN.mission_name, + "Infest Giant Ursadon", + SC2HOTS_LOC_ID_OFFSET + 601, + LocationType.VANILLA, + logic.zerg_pass_vents, + hard_rule=logic.zerg_pass_vents, + ), + make_location_data( + SC2Mission.ENEMY_WITHIN.mission_name, + "First Niadra Evolution", + SC2HOTS_LOC_ID_OFFSET + 602, + LocationType.VANILLA, + logic.zerg_pass_vents, + ), + make_location_data( + SC2Mission.ENEMY_WITHIN.mission_name, + "Second Niadra Evolution", + SC2HOTS_LOC_ID_OFFSET + 603, + LocationType.VANILLA, + logic.zerg_pass_vents, + hard_rule=logic.zerg_pass_vents, + ), + make_location_data( + SC2Mission.ENEMY_WITHIN.mission_name, + "Third Niadra Evolution", + SC2HOTS_LOC_ID_OFFSET + 604, + LocationType.VANILLA, + logic.zerg_pass_vents, + hard_rule=logic.zerg_pass_vents, + ), + make_location_data( + SC2Mission.ENEMY_WITHIN.mission_name, + "Warp Drive", + SC2HOTS_LOC_ID_OFFSET + 605, + LocationType.EXTRA, + logic.zerg_pass_vents, + hard_rule=logic.zerg_pass_vents, + ), + make_location_data( + SC2Mission.ENEMY_WITHIN.mission_name, + "Stasis Quadrant", + SC2HOTS_LOC_ID_OFFSET + 606, + LocationType.EXTRA, + logic.zerg_pass_vents, + hard_rule=logic.zerg_pass_vents, + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 700, + LocationType.VICTORY, + logic.zerg_common_unit_basic_aa, + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "Center Infested Command Center", + SC2HOTS_LOC_ID_OFFSET + 701, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "North Infested Command Center", + SC2HOTS_LOC_ID_OFFSET + 702, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "Repel Zagara", + SC2HOTS_LOC_ID_OFFSET + 703, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "Close Baneling Nest", + SC2HOTS_LOC_ID_OFFSET + 704, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "South Baneling Nest", + SC2HOTS_LOC_ID_OFFSET + 705, + LocationType.EXTRA, + lambda state: adv_tactics or logic.zerg_common_unit(state), + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "Southwest Baneling Nest", + SC2HOTS_LOC_ID_OFFSET + 706, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "Southeast Baneling Nest", + SC2HOTS_LOC_ID_OFFSET + 707, + LocationType.EXTRA, + logic.zerg_common_unit_basic_aa, + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "North Baneling Nest", + SC2HOTS_LOC_ID_OFFSET + 708, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "Northeast Baneling Nest", + SC2HOTS_LOC_ID_OFFSET + 709, + LocationType.EXTRA, + logic.zerg_common_unit_basic_aa, + ), + make_location_data( + SC2Mission.DOMINATION.mission_name, + "Win Without 100 Eggs", + SC2HOTS_LOC_ID_OFFSET + 710, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 800, + LocationType.VICTORY, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_moderate_anti_air(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "West Biomass", + SC2HOTS_LOC_ID_OFFSET + 801, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "North Biomass", + SC2HOTS_LOC_ID_OFFSET + 802, + LocationType.VANILLA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_moderate_anti_air(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "South Biomass", + SC2HOTS_LOC_ID_OFFSET + 803, + LocationType.VANILLA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_moderate_anti_air(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "Destroy 3 Gorgons", + SC2HOTS_LOC_ID_OFFSET + 804, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_moderate_anti_air(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "Close Zerg Rescue", + SC2HOTS_LOC_ID_OFFSET + 805, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "South Zerg Rescue", + SC2HOTS_LOC_ID_OFFSET + 806, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "North Zerg Rescue", + SC2HOTS_LOC_ID_OFFSET + 807, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_moderate_anti_air(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "West Queen Rescue", + SC2HOTS_LOC_ID_OFFSET + 808, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_moderate_anti_air(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "East Queen Rescue", + SC2HOTS_LOC_ID_OFFSET + 809, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_moderate_anti_air(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "South Orbital Command Center", + SC2HOTS_LOC_ID_OFFSET + 810, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_competent_comp(state) and logic.zerg_moderate_anti_air(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "Northwest Orbital Command Center", + SC2HOTS_LOC_ID_OFFSET + 811, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_competent_comp(state) and logic.zerg_moderate_anti_air(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY.mission_name, + "Southeast Orbital Command Center", + SC2HOTS_LOC_ID_OFFSET + 812, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_competent_comp(state) and logic.zerg_moderate_anti_air(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 900, + LocationType.VICTORY, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS.mission_name, + "East Science Lab", + SC2HOTS_LOC_ID_OFFSET + 901, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS.mission_name, + "North Science Lab", + SC2HOTS_LOC_ID_OFFSET + 902, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS.mission_name, + "Get Nuked", + SC2HOTS_LOC_ID_OFFSET + 903, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS.mission_name, + "Entrance Gate", + SC2HOTS_LOC_ID_OFFSET + 904, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS.mission_name, + "Citadel Gate", + SC2HOTS_LOC_ID_OFFSET + 905, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS.mission_name, + "South Expansion", + SC2HOTS_LOC_ID_OFFSET + 906, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS.mission_name, + "Rich Mineral Expansion", + SC2HOTS_LOC_ID_OFFSET + 907, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 1000, + LocationType.VICTORY, + logic.zerg_competent_comp_competent_aa, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT.mission_name, + "Center Essence Pool", + SC2HOTS_LOC_ID_OFFSET + 1001, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT.mission_name, + "East Essence Pool", + SC2HOTS_LOC_ID_OFFSET + 1002, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and ( + adv_tactics + and logic.zerg_basic_anti_air(state) + or logic.zerg_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT.mission_name, + "South Essence Pool", + SC2HOTS_LOC_ID_OFFSET + 1003, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and ( + adv_tactics + and logic.zerg_basic_anti_air(state) + or logic.zerg_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT.mission_name, + "Finish Feeding", + SC2HOTS_LOC_ID_OFFSET + 1004, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT.mission_name, + "South Proxy Primal Hive", + SC2HOTS_LOC_ID_OFFSET + 1005, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT.mission_name, + "East Proxy Primal Hive", + SC2HOTS_LOC_ID_OFFSET + 1006, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT.mission_name, + "South Main Primal Hive", + SC2HOTS_LOC_ID_OFFSET + 1007, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.BASEBUST, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT.mission_name, + "East Main Primal Hive", + SC2HOTS_LOC_ID_OFFSET + 1008, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.BASEBUST, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT.mission_name, + "Flawless", + SC2HOTS_LOC_ID_OFFSET + 1009, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.PREVENTATIVE, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.THE_CRUCIBLE.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 1100, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 7 + and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE.mission_name, + "Tyrannozor", + SC2HOTS_LOC_ID_OFFSET + 1101, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 7 + and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE.mission_name, + "Reach the Pool", + SC2HOTS_LOC_ID_OFFSET + 1102, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_CRUCIBLE.mission_name, + "15 Minutes Remaining", + SC2HOTS_LOC_ID_OFFSET + 1103, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 7 + and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE.mission_name, + "5 Minutes Remaining", + SC2HOTS_LOC_ID_OFFSET + 1104, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 7 + and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE.mission_name, + "Pincer Attack", + SC2HOTS_LOC_ID_OFFSET + 1105, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 7 + and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE.mission_name, + "Yagdra Claims Brakk's Pack", + SC2HOTS_LOC_ID_OFFSET + 1106, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 7 + and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SUPREME.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 1200, + LocationType.VICTORY, + logic.supreme_requirement, + hard_rule=logic.supreme_requirement, + ), + make_location_data( + SC2Mission.SUPREME.mission_name, + "First Relic", + SC2HOTS_LOC_ID_OFFSET + 1201, + LocationType.VANILLA, + logic.supreme_requirement, + hard_rule=logic.supreme_requirement, + ), + make_location_data( + SC2Mission.SUPREME.mission_name, + "Second Relic", + SC2HOTS_LOC_ID_OFFSET + 1202, + LocationType.VANILLA, + logic.supreme_requirement, + hard_rule=logic.supreme_requirement, + ), + make_location_data( + SC2Mission.SUPREME.mission_name, + "Third Relic", + SC2HOTS_LOC_ID_OFFSET + 1203, + LocationType.VANILLA, + logic.supreme_requirement, + hard_rule=logic.supreme_requirement, + ), + make_location_data( + SC2Mission.SUPREME.mission_name, + "Fourth Relic", + SC2HOTS_LOC_ID_OFFSET + 1204, + LocationType.VANILLA, + logic.supreme_requirement, + hard_rule=logic.supreme_requirement, + ), + make_location_data( + SC2Mission.SUPREME.mission_name, + "Yagdra", + SC2HOTS_LOC_ID_OFFSET + 1205, + LocationType.EXTRA, + logic.supreme_requirement, + hard_rule=logic.supreme_requirement, + ), + make_location_data( + SC2Mission.SUPREME.mission_name, + "Kraith", + SC2HOTS_LOC_ID_OFFSET + 1206, + LocationType.EXTRA, + logic.supreme_requirement, + hard_rule=logic.supreme_requirement, + ), + make_location_data( + SC2Mission.SUPREME.mission_name, + "Slivan", + SC2HOTS_LOC_ID_OFFSET + 1207, + LocationType.EXTRA, + logic.supreme_requirement, + hard_rule=logic.supreme_requirement, + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 1300, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit(state) + and ( + ( + logic.zerg_competent_anti_air(state) + and state.has(item_names.INFESTOR, player) + ) + or (adv_tactics and logic.zerg_moderate_anti_air(state)) + ) + ), + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "East Science Facility", + SC2HOTS_LOC_ID_OFFSET + 1301, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_moderate_anti_air(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "Center Science Facility", + SC2HOTS_LOC_ID_OFFSET + 1302, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_moderate_anti_air(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "West Science Facility", + SC2HOTS_LOC_ID_OFFSET + 1303, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_moderate_anti_air(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "First Intro Garrison", + SC2HOTS_LOC_ID_OFFSET + 1304, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "Second Intro Garrison", + SC2HOTS_LOC_ID_OFFSET + 1305, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "Base Garrison", + SC2HOTS_LOC_ID_OFFSET + 1306, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "East Garrison", + SC2HOTS_LOC_ID_OFFSET + 1307, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_moderate_anti_air(state) + and (adv_tactics or state.has(item_names.INFESTOR, player)) + ), + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "Mid Garrison", + SC2HOTS_LOC_ID_OFFSET + 1308, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_moderate_anti_air(state) + and (adv_tactics or state.has(item_names.INFESTOR, player)) + ), + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "North Garrison", + SC2HOTS_LOC_ID_OFFSET + 1309, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_moderate_anti_air(state) + and (adv_tactics or state.has(item_names.INFESTOR, player)) + ), + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "Close Southwest Garrison", + SC2HOTS_LOC_ID_OFFSET + 1310, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_moderate_anti_air(state) + and (adv_tactics or state.has(item_names.INFESTOR, player)) + ), + ), + make_location_data( + SC2Mission.INFESTED.mission_name, + "Far Southwest Garrison", + SC2HOTS_LOC_ID_OFFSET + 1311, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_moderate_anti_air(state) + and (adv_tactics or state.has(item_names.INFESTOR, player)) + ), + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 1400, + LocationType.VICTORY, + logic.zerg_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS.mission_name, + "North Brutalisk", + SC2HOTS_LOC_ID_OFFSET + 1401, + LocationType.VANILLA, + logic.zerg_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS.mission_name, + "South Brutalisk", + SC2HOTS_LOC_ID_OFFSET + 1402, + LocationType.VANILLA, + logic.zerg_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS.mission_name, + "Kill 1 Hybrid", + SC2HOTS_LOC_ID_OFFSET + 1403, + LocationType.EXTRA, + logic.zerg_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS.mission_name, + "Kill 2 Hybrid", + SC2HOTS_LOC_ID_OFFSET + 1404, + LocationType.EXTRA, + logic.zerg_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS.mission_name, + "Kill 3 Hybrid", + SC2HOTS_LOC_ID_OFFSET + 1405, + LocationType.EXTRA, + logic.zerg_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS.mission_name, + "Kill 4 Hybrid", + SC2HOTS_LOC_ID_OFFSET + 1406, + LocationType.EXTRA, + logic.zerg_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS.mission_name, + "Kill 5 Hybrid", + SC2HOTS_LOC_ID_OFFSET + 1407, + LocationType.EXTRA, + logic.zerg_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS.mission_name, + "Kill 6 Hybrid", + SC2HOTS_LOC_ID_OFFSET + 1408, + LocationType.EXTRA, + logic.zerg_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS.mission_name, + "Kill 7 Hybrid", + SC2HOTS_LOC_ID_OFFSET + 1409, + LocationType.EXTRA, + logic.zerg_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 1500, + LocationType.VICTORY, + lambda state: ( + logic.zerg_competent_comp(state) + and ( + logic.zerg_competent_anti_air(state) + or (adv_tactics and logic.zerg_moderate_anti_air(state)) + ) + ), + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID.mission_name, + "Northwest Crystal", + SC2HOTS_LOC_ID_OFFSET + 1501, + LocationType.VANILLA, + lambda state: ( + logic.zerg_competent_comp(state) + and ( + logic.zerg_competent_anti_air(state) + or (adv_tactics and logic.zerg_moderate_anti_air(state)) + ) + ), + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID.mission_name, + "Northeast Crystal", + SC2HOTS_LOC_ID_OFFSET + 1502, + LocationType.VANILLA, + lambda state: ( + logic.zerg_competent_comp(state) + and ( + logic.zerg_competent_anti_air(state) + or (adv_tactics and logic.zerg_moderate_anti_air(state)) + ) + ), + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID.mission_name, + "South Crystal", + SC2HOTS_LOC_ID_OFFSET + 1503, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID.mission_name, + "Base Established", + SC2HOTS_LOC_ID_OFFSET + 1504, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID.mission_name, + "Close Temple", + SC2HOTS_LOC_ID_OFFSET + 1505, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and ( + logic.zerg_competent_anti_air(state) + or (adv_tactics and logic.zerg_moderate_anti_air(state)) + ) + ), + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID.mission_name, + "Mid Temple", + SC2HOTS_LOC_ID_OFFSET + 1506, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and ( + logic.zerg_competent_anti_air(state) + or (adv_tactics and logic.zerg_moderate_anti_air(state)) + ) + ), + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID.mission_name, + "Southeast Temple", + SC2HOTS_LOC_ID_OFFSET + 1507, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and ( + logic.zerg_competent_anti_air(state) + or (adv_tactics and logic.zerg_moderate_anti_air(state)) + ) + ), + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID.mission_name, + "Northeast Temple", + SC2HOTS_LOC_ID_OFFSET + 1508, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and ( + logic.zerg_competent_anti_air(state) + or (adv_tactics and logic.zerg_moderate_anti_air(state)) + ) + ), + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID.mission_name, + "Northwest Temple", + SC2HOTS_LOC_ID_OFFSET + 1509, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and ( + logic.zerg_competent_anti_air(state) + or (adv_tactics and logic.zerg_moderate_anti_air(state)) + ) + ), + ), + make_location_data( + SC2Mission.WITH_FRIENDS_LIKE_THESE.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 1600, + LocationType.VICTORY, + ), + make_location_data( + SC2Mission.WITH_FRIENDS_LIKE_THESE.mission_name, + "Pirate Capital Ship", + SC2HOTS_LOC_ID_OFFSET + 1601, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WITH_FRIENDS_LIKE_THESE.mission_name, + "First Mineral Patch", + SC2HOTS_LOC_ID_OFFSET + 1602, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WITH_FRIENDS_LIKE_THESE.mission_name, + "Second Mineral Patch", + SC2HOTS_LOC_ID_OFFSET + 1603, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WITH_FRIENDS_LIKE_THESE.mission_name, + "Third Mineral Patch", + SC2HOTS_LOC_ID_OFFSET + 1604, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.CONVICTION.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 1700, + LocationType.VICTORY, + lambda state: ( + kerriganless + or ( + logic.two_kerrigan_actives(state) + and (logic.basic_kerrigan(state) or logic.grant_story_tech == GrantStoryTech.option_grant) + and logic.kerrigan_levels(state, 25) + ) + ), + ), + make_location_data( + SC2Mission.CONVICTION.mission_name, + "First Secret Documents", + SC2HOTS_LOC_ID_OFFSET + 1701, + LocationType.VANILLA, + lambda state: ( + logic.two_kerrigan_actives(state) and logic.kerrigan_levels(state, 25) + ) + or kerriganless, + ), + make_location_data( + SC2Mission.CONVICTION.mission_name, + "Second Secret Documents", + SC2HOTS_LOC_ID_OFFSET + 1702, + LocationType.VANILLA, + lambda state: ( + kerriganless + or ( + logic.two_kerrigan_actives(state) + and (logic.basic_kerrigan(state) or logic.grant_story_tech == GrantStoryTech.option_grant) + and logic.kerrigan_levels(state, 25) + ) + ), + ), + make_location_data( + SC2Mission.CONVICTION.mission_name, + "Power Coupling", + SC2HOTS_LOC_ID_OFFSET + 1703, + LocationType.EXTRA, + lambda state: ( + logic.two_kerrigan_actives(state) and logic.kerrigan_levels(state, 25) + ) + or kerriganless, + ), + make_location_data( + SC2Mission.CONVICTION.mission_name, + "Door Blasted", + SC2HOTS_LOC_ID_OFFSET + 1704, + LocationType.EXTRA, + lambda state: ( + logic.two_kerrigan_actives(state) and logic.kerrigan_levels(state, 25) + ) + or kerriganless, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 1800, + LocationType.VICTORY, + logic.zerg_planetfall_requirement, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "East Gate", + SC2HOTS_LOC_ID_OFFSET + 1801, + LocationType.VANILLA, + logic.zerg_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "Northwest Gate", + SC2HOTS_LOC_ID_OFFSET + 1802, + LocationType.VANILLA, + logic.zerg_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "North Gate", + SC2HOTS_LOC_ID_OFFSET + 1803, + LocationType.VANILLA, + logic.zerg_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "1 Bile Launcher Deployed", + SC2HOTS_LOC_ID_OFFSET + 1804, + LocationType.EXTRA, + logic.zerg_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "2 Bile Launchers Deployed", + SC2HOTS_LOC_ID_OFFSET + 1805, + LocationType.EXTRA, + logic.zerg_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "3 Bile Launchers Deployed", + SC2HOTS_LOC_ID_OFFSET + 1806, + LocationType.EXTRA, + logic.zerg_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "4 Bile Launchers Deployed", + SC2HOTS_LOC_ID_OFFSET + 1807, + LocationType.EXTRA, + logic.zerg_planetfall_requirement, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "5 Bile Launchers Deployed", + SC2HOTS_LOC_ID_OFFSET + 1808, + LocationType.EXTRA, + logic.zerg_planetfall_requirement, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "Sons of Korhal", + SC2HOTS_LOC_ID_OFFSET + 1809, + LocationType.EXTRA, + logic.zerg_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "Night Wolves", + SC2HOTS_LOC_ID_OFFSET + 1810, + LocationType.EXTRA, + logic.zerg_planetfall_requirement, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "West Expansion", + SC2HOTS_LOC_ID_OFFSET + 1811, + LocationType.EXTRA, + logic.zerg_planetfall_requirement, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL.mission_name, + "Mid Expansion", + SC2HOTS_LOC_ID_OFFSET + 1812, + LocationType.EXTRA, + logic.zerg_planetfall_requirement, + hard_rule=logic.zerg_kerrigan_or_any_anti_air, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 1900, + LocationType.VICTORY, + lambda state: logic.zerg_competent_comp_competent_aa(state) + and (adv_tactics or logic.zerg_base_buster(state)), + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE.mission_name, + "First Power Link", + SC2HOTS_LOC_ID_OFFSET + 1901, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE.mission_name, + "Second Power Link", + SC2HOTS_LOC_ID_OFFSET + 1902, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE.mission_name, + "Third Power Link", + SC2HOTS_LOC_ID_OFFSET + 1903, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE.mission_name, + "Expansion Command Center", + SC2HOTS_LOC_ID_OFFSET + 1904, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE.mission_name, + "Main Path Command Center", + SC2HOTS_LOC_ID_OFFSET + 1905, + LocationType.EXTRA, + lambda state: logic.zerg_competent_comp_competent_aa(state) + and (adv_tactics or logic.zerg_base_buster(state)), + ), + make_location_data( + SC2Mission.THE_RECKONING.mission_name, + "Victory", + SC2HOTS_LOC_ID_OFFSET + 2000, + LocationType.VICTORY, + logic.zerg_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING.mission_name, + "South Lane", + SC2HOTS_LOC_ID_OFFSET + 2001, + LocationType.VANILLA, + logic.zerg_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING.mission_name, + "North Lane", + SC2HOTS_LOC_ID_OFFSET + 2002, + LocationType.VANILLA, + logic.zerg_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING.mission_name, + "East Lane", + SC2HOTS_LOC_ID_OFFSET + 2003, + LocationType.VANILLA, + logic.zerg_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING.mission_name, + "Odin", + SC2HOTS_LOC_ID_OFFSET + 2004, + LocationType.EXTRA, + logic.zerg_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING.mission_name, + "Trash the Odin Early", + SC2HOTS_LOC_ID_OFFSET + 2005, + LocationType.MASTERY, + lambda state: ( + logic.zerg_the_reckoning_requirement(state) + and ( + kerriganless + or ( + logic.kerrigan_levels(state, 50, False) + and state.has_any(kerrigan_logic_ultimates, player) + ) + ) + and logic.zerg_power_rating(state) >= 10 + ), + flags=LocationFlag.SPEEDRUN, + ), + # LotV Prologue + make_location_data( + SC2Mission.DARK_WHISPERS.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 100, + LocationType.VICTORY, + logic.protoss_common_unit_basic_aa, + ), + make_location_data( + SC2Mission.DARK_WHISPERS.mission_name, + "First Prisoner Group", + SC2LOTV_LOC_ID_OFFSET + 101, + LocationType.VANILLA, + logic.protoss_common_unit_basic_aa, + ), + make_location_data( + SC2Mission.DARK_WHISPERS.mission_name, + "Second Prisoner Group", + SC2LOTV_LOC_ID_OFFSET + 102, + LocationType.VANILLA, + logic.protoss_common_unit_basic_aa, + ), + make_location_data( + SC2Mission.DARK_WHISPERS.mission_name, + "First Pylon", + SC2LOTV_LOC_ID_OFFSET + 103, + LocationType.VANILLA, + logic.protoss_common_unit_basic_aa, + ), + make_location_data( + SC2Mission.DARK_WHISPERS.mission_name, + "Second Pylon", + SC2LOTV_LOC_ID_OFFSET + 104, + LocationType.VANILLA, + logic.protoss_common_unit_basic_aa, + ), + make_location_data( + SC2Mission.DARK_WHISPERS.mission_name, + "Zerg Base", + SC2LOTV_LOC_ID_OFFSET + 105, + LocationType.MASTERY, + lambda state: logic.protoss_deathball(state) + and logic.protoss_power_rating(state) >= 6, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 200, + LocationType.VICTORY, + lambda state: logic.protoss_competent_comp(state) + and logic.protoss_mineral_dump(state), + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG.mission_name, + "South Rock Formation", + SC2LOTV_LOC_ID_OFFSET + 201, + LocationType.VANILLA, + lambda state: logic.protoss_competent_comp(state) + and logic.protoss_mineral_dump(state), + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG.mission_name, + "West Rock Formation", + SC2LOTV_LOC_ID_OFFSET + 202, + LocationType.VANILLA, + lambda state: logic.protoss_competent_comp(state) + and logic.protoss_mineral_dump(state), + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG.mission_name, + "East Rock Formation", + SC2LOTV_LOC_ID_OFFSET + 203, + LocationType.VANILLA, + lambda state: ( + logic.protoss_competent_comp(state) + and logic.protoss_mineral_dump(state) + and logic.protoss_can_attack_behind_chasm(state) + ), + ), + make_location_data( + SC2Mission.EVIL_AWOKEN.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 300, + LocationType.VICTORY, + lambda state: adv_tactics + or state.count_from_list( + ( + item_names.STALKER_PHASE_REACTOR, + item_names.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES, + item_names.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION, + ), + player, + ) + >= 2, + ), + make_location_data( + SC2Mission.EVIL_AWOKEN.mission_name, + "Temple Investigated", + SC2LOTV_LOC_ID_OFFSET + 301, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.EVIL_AWOKEN.mission_name, + "Void Catalyst", + SC2LOTV_LOC_ID_OFFSET + 302, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.EVIL_AWOKEN.mission_name, + "First Particle Cannon", + SC2LOTV_LOC_ID_OFFSET + 303, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.EVIL_AWOKEN.mission_name, + "Second Particle Cannon", + SC2LOTV_LOC_ID_OFFSET + 304, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.EVIL_AWOKEN.mission_name, + "Third Particle Cannon", + SC2LOTV_LOC_ID_OFFSET + 305, + LocationType.VANILLA, + ), + # LotV + make_location_data( + SC2Mission.FOR_AIUR.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 400, + LocationType.VICTORY, + ), + make_location_data( + SC2Mission.FOR_AIUR.mission_name, + "Southwest Hive", + SC2LOTV_LOC_ID_OFFSET + 401, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.FOR_AIUR.mission_name, + "Northwest Hive", + SC2LOTV_LOC_ID_OFFSET + 402, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.FOR_AIUR.mission_name, + "Northeast Hive", + SC2LOTV_LOC_ID_OFFSET + 403, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.FOR_AIUR.mission_name, + "East Hive", + SC2LOTV_LOC_ID_OFFSET + 404, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.FOR_AIUR.mission_name, + "West Conduit", + SC2LOTV_LOC_ID_OFFSET + 405, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.FOR_AIUR.mission_name, + "Middle Conduit", + SC2LOTV_LOC_ID_OFFSET + 406, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.FOR_AIUR.mission_name, + "Northeast Conduit", + SC2LOTV_LOC_ID_OFFSET + 407, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 500, + LocationType.VICTORY, + lambda state: logic.protoss_common_unit(state) + and (adv_tactics or logic.protoss_moderate_anti_air(state)), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW.mission_name, + "Close Pylon", + SC2LOTV_LOC_ID_OFFSET + 501, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW.mission_name, + "East Pylon", + SC2LOTV_LOC_ID_OFFSET + 502, + LocationType.VANILLA, + lambda state: logic.protoss_common_unit(state) + and (adv_tactics or logic.protoss_moderate_anti_air(state)), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW.mission_name, + "West Pylon", + SC2LOTV_LOC_ID_OFFSET + 503, + LocationType.VANILLA, + lambda state: logic.protoss_common_unit(state) + and (adv_tactics or logic.protoss_moderate_anti_air(state)), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW.mission_name, + "Nexus", + SC2LOTV_LOC_ID_OFFSET + 504, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW.mission_name, + "Templar Base", + SC2LOTV_LOC_ID_OFFSET + 505, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) + and (adv_tactics or logic.protoss_moderate_anti_air(state)), + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 600, + LocationType.VICTORY, + logic.protoss_spear_of_adun_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN.mission_name, + "Close Warp Gate", + SC2LOTV_LOC_ID_OFFSET + 601, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN.mission_name, + "West Warp Gate", + SC2LOTV_LOC_ID_OFFSET + 602, + LocationType.VANILLA, + logic.protoss_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN.mission_name, + "North Warp Gate", + SC2LOTV_LOC_ID_OFFSET + 603, + LocationType.VANILLA, + logic.protoss_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN.mission_name, + "North Power Cell", + SC2LOTV_LOC_ID_OFFSET + 604, + LocationType.EXTRA, + logic.protoss_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN.mission_name, + "East Power Cell", + SC2LOTV_LOC_ID_OFFSET + 605, + LocationType.EXTRA, + logic.protoss_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN.mission_name, + "South Power Cell", + SC2LOTV_LOC_ID_OFFSET + 606, + LocationType.EXTRA, + logic.protoss_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN.mission_name, + "Southeast Power Cell", + SC2LOTV_LOC_ID_OFFSET + 607, + LocationType.EXTRA, + logic.protoss_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 700, + LocationType.VICTORY, + logic.protoss_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "Mid EMP Scrambler", + SC2LOTV_LOC_ID_OFFSET + 701, + LocationType.VANILLA, + logic.protoss_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "Southeast EMP Scrambler", + SC2LOTV_LOC_ID_OFFSET + 702, + LocationType.VANILLA, + logic.protoss_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "North EMP Scrambler", + SC2LOTV_LOC_ID_OFFSET + 703, + LocationType.VANILLA, + logic.protoss_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "Mid Stabilizer", + SC2LOTV_LOC_ID_OFFSET + 704, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "Southwest Stabilizer", + SC2LOTV_LOC_ID_OFFSET + 705, + LocationType.EXTRA, + logic.protoss_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "Northwest Stabilizer", + SC2LOTV_LOC_ID_OFFSET + 706, + LocationType.EXTRA, + logic.protoss_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "Northeast Stabilizer", + SC2LOTV_LOC_ID_OFFSET + 707, + LocationType.EXTRA, + logic.protoss_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "Southeast Stabilizer", + SC2LOTV_LOC_ID_OFFSET + 708, + LocationType.EXTRA, + logic.protoss_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "West Raynor Base", + SC2LOTV_LOC_ID_OFFSET + 709, + LocationType.EXTRA, + logic.protoss_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD.mission_name, + "East Raynor Base", + SC2LOTV_LOC_ID_OFFSET + 710, + LocationType.EXTRA, + logic.protoss_sky_shield_requirement, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 800, + LocationType.VICTORY, + logic.protoss_brothers_in_arms_requirement, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS.mission_name, + "Mid Science Facility", + SC2LOTV_LOC_ID_OFFSET + 801, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS.mission_name, + "North Science Facility", + SC2LOTV_LOC_ID_OFFSET + 802, + LocationType.VANILLA, + lambda state: ( + logic.protoss_brothers_in_arms_requirement(state) + or ( + logic.take_over_ai_allies + and logic.advanced_tactics + and ( + logic.terran_common_unit(state) + or logic.protoss_common_unit(state) + ) + ) + ), + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS.mission_name, + "South Science Facility", + SC2LOTV_LOC_ID_OFFSET + 803, + LocationType.VANILLA, + logic.protoss_brothers_in_arms_requirement, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS.mission_name, + "Raynor Forward Positions", + SC2LOTV_LOC_ID_OFFSET + 804, + LocationType.EXTRA, + logic.protoss_brothers_in_arms_requirement, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS.mission_name, + "Valerian Forward Positions", + SC2LOTV_LOC_ID_OFFSET + 805, + LocationType.EXTRA, + logic.protoss_brothers_in_arms_requirement, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS.mission_name, + "Win in under 15 minutes", + SC2LOTV_LOC_ID_OFFSET + 806, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_brothers_in_arms_requirement(state) + and logic.protoss_deathball(state) + and logic.protoss_power_rating(state) >= 8 + ), + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.AMON_S_REACH.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 900, + LocationType.VICTORY, + logic.protoss_common_unit_anti_light_air, + ), + make_location_data( + SC2Mission.AMON_S_REACH.mission_name, + "Close Solarite Reserve", + SC2LOTV_LOC_ID_OFFSET + 901, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.AMON_S_REACH.mission_name, + "North Solarite Reserve", + SC2LOTV_LOC_ID_OFFSET + 902, + LocationType.VANILLA, + logic.protoss_common_unit_anti_light_air, + ), + make_location_data( + SC2Mission.AMON_S_REACH.mission_name, + "East Solarite Reserve", + SC2LOTV_LOC_ID_OFFSET + 903, + LocationType.VANILLA, + logic.protoss_common_unit_anti_light_air, + ), + make_location_data( + SC2Mission.AMON_S_REACH.mission_name, + "West Launch Bay", + SC2LOTV_LOC_ID_OFFSET + 904, + LocationType.EXTRA, + logic.protoss_common_unit_anti_light_air, + ), + make_location_data( + SC2Mission.AMON_S_REACH.mission_name, + "South Launch Bay", + SC2LOTV_LOC_ID_OFFSET + 905, + LocationType.EXTRA, + logic.protoss_common_unit_anti_light_air, + ), + make_location_data( + SC2Mission.AMON_S_REACH.mission_name, + "Northwest Launch Bay", + SC2LOTV_LOC_ID_OFFSET + 906, + LocationType.EXTRA, + logic.protoss_common_unit_anti_light_air, + ), + make_location_data( + SC2Mission.AMON_S_REACH.mission_name, + "East Launch Bay", + SC2LOTV_LOC_ID_OFFSET + 907, + LocationType.EXTRA, + logic.protoss_common_unit_anti_light_air, + ), + make_location_data( + SC2Mission.LAST_STAND.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 1000, + LocationType.VICTORY, + logic.protoss_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND.mission_name, + "West Zenith Stone", + SC2LOTV_LOC_ID_OFFSET + 1001, + LocationType.VANILLA, + logic.protoss_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND.mission_name, + "North Zenith Stone", + SC2LOTV_LOC_ID_OFFSET + 1002, + LocationType.VANILLA, + logic.protoss_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND.mission_name, + "East Zenith Stone", + SC2LOTV_LOC_ID_OFFSET + 1003, + LocationType.VANILLA, + logic.protoss_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND.mission_name, + "1 Billion Zerg", + SC2LOTV_LOC_ID_OFFSET + 1004, + LocationType.EXTRA, + logic.protoss_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND.mission_name, + "1.5 Billion Zerg", + SC2LOTV_LOC_ID_OFFSET + 1005, + LocationType.VANILLA, + lambda state: ( + logic.protoss_last_stand_requirement(state) + and ( + state.has_all( + { + item_names.KHAYDARIN_MONOLITH, + item_names.PHOTON_CANNON, + item_names.SHIELD_BATTERY, + }, + player, + ) + or state.has_any( + {item_names.SOA_SOLAR_LANCE, item_names.SOA_DEPLOY_FENIX}, + player, + ) + ) + and logic.protoss_defense_rating(state, False) >= 13 + ), + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 1100, + LocationType.VICTORY, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON.mission_name, + "South Solarite", + SC2LOTV_LOC_ID_OFFSET + 1101, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON.mission_name, + "North Solarite", + SC2LOTV_LOC_ID_OFFSET + 1102, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON.mission_name, + "Northwest Solarite", + SC2LOTV_LOC_ID_OFFSET + 1103, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON.mission_name, + "Rescue Sentries", + SC2LOTV_LOC_ID_OFFSET + 1104, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON.mission_name, + "Destroy Gateways", + SC2LOTV_LOC_ID_OFFSET + 1105, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 1200, + LocationType.VICTORY, + logic.protoss_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION.mission_name, + "Mid Celestial Lock", + SC2LOTV_LOC_ID_OFFSET + 1201, + LocationType.EXTRA, + logic.protoss_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION.mission_name, + "West Celestial Lock", + SC2LOTV_LOC_ID_OFFSET + 1202, + LocationType.EXTRA, + logic.protoss_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION.mission_name, + "South Celestial Lock", + SC2LOTV_LOC_ID_OFFSET + 1203, + LocationType.EXTRA, + logic.protoss_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION.mission_name, + "East Celestial Lock", + SC2LOTV_LOC_ID_OFFSET + 1204, + LocationType.EXTRA, + logic.protoss_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION.mission_name, + "North Celestial Lock", + SC2LOTV_LOC_ID_OFFSET + 1205, + LocationType.EXTRA, + logic.protoss_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION.mission_name, + "Titanic Warp Prism", + SC2LOTV_LOC_ID_OFFSET + 1206, + LocationType.VANILLA, + logic.protoss_temple_of_unification_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION.mission_name, + "Terran Main Base", + SC2LOTV_LOC_ID_OFFSET + 1207, + LocationType.MASTERY, + lambda state: logic.protoss_temple_of_unification_requirement(state) + and logic.protoss_deathball(state), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION.mission_name, + "Protoss Main Base", + SC2LOTV_LOC_ID_OFFSET + 1208, + LocationType.MASTERY, + lambda state: logic.protoss_temple_of_unification_requirement(state) + and logic.protoss_deathball(state), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_INFINITE_CYCLE.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 1300, + LocationType.VICTORY, + logic.the_infinite_cycle_requirement, + ), + make_location_data( + SC2Mission.THE_INFINITE_CYCLE.mission_name, + "First Hall of Revelation", + SC2LOTV_LOC_ID_OFFSET + 1301, + LocationType.EXTRA, + logic.the_infinite_cycle_requirement, + ), + make_location_data( + SC2Mission.THE_INFINITE_CYCLE.mission_name, + "Second Hall of Revelation", + SC2LOTV_LOC_ID_OFFSET + 1302, + LocationType.EXTRA, + logic.the_infinite_cycle_requirement, + ), + make_location_data( + SC2Mission.THE_INFINITE_CYCLE.mission_name, + "First Xel'Naga Device", + SC2LOTV_LOC_ID_OFFSET + 1303, + LocationType.VANILLA, + logic.the_infinite_cycle_requirement, + ), + make_location_data( + SC2Mission.THE_INFINITE_CYCLE.mission_name, + "Second Xel'Naga Device", + SC2LOTV_LOC_ID_OFFSET + 1304, + LocationType.VANILLA, + logic.the_infinite_cycle_requirement, + ), + make_location_data( + SC2Mission.THE_INFINITE_CYCLE.mission_name, + "Third Xel'Naga Device", + SC2LOTV_LOC_ID_OFFSET + 1305, + LocationType.VANILLA, + logic.the_infinite_cycle_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 1400, + LocationType.VICTORY, + logic.protoss_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION.mission_name, + "Artanis", + SC2LOTV_LOC_ID_OFFSET + 1401, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION.mission_name, + "Northwest Void Crystal", + SC2LOTV_LOC_ID_OFFSET + 1402, + LocationType.EXTRA, + logic.protoss_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION.mission_name, + "Northeast Void Crystal", + SC2LOTV_LOC_ID_OFFSET + 1403, + LocationType.EXTRA, + logic.protoss_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION.mission_name, + "Southwest Void Crystal", + SC2LOTV_LOC_ID_OFFSET + 1404, + LocationType.EXTRA, + logic.protoss_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION.mission_name, + "Southeast Void Crystal", + SC2LOTV_LOC_ID_OFFSET + 1405, + LocationType.EXTRA, + logic.protoss_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION.mission_name, + "South Xel'Naga Vessel", + SC2LOTV_LOC_ID_OFFSET + 1406, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION.mission_name, + "Mid Xel'Naga Vessel", + SC2LOTV_LOC_ID_OFFSET + 1407, + LocationType.VANILLA, + logic.protoss_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION.mission_name, + "North Xel'Naga Vessel", + SC2LOTV_LOC_ID_OFFSET + 1408, + LocationType.VANILLA, + logic.protoss_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 1500, + LocationType.VICTORY, + lambda state: ( + logic.protoss_deathball(state) + and logic.protoss_power_rating(state) >= 6 + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST.mission_name, + "Zerg Cleared", + SC2LOTV_LOC_ID_OFFSET + 1501, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST.mission_name, + "First Stasis Lock", + SC2LOTV_LOC_ID_OFFSET + 1502, + LocationType.EXTRA, + lambda state: ( + logic.protoss_deathball(state) + and logic.protoss_power_rating(state) >= 6 + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST.mission_name, + "Second Stasis Lock", + SC2LOTV_LOC_ID_OFFSET + 1503, + LocationType.EXTRA, + lambda state: ( + logic.protoss_deathball(state) + and logic.protoss_power_rating(state) >= 6 + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST.mission_name, + "Third Stasis Lock", + SC2LOTV_LOC_ID_OFFSET + 1504, + LocationType.EXTRA, + lambda state: ( + logic.protoss_deathball(state) + and logic.protoss_power_rating(state) >= 6 + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST.mission_name, + "Fourth Stasis Lock", + SC2LOTV_LOC_ID_OFFSET + 1505, + LocationType.EXTRA, + lambda state: ( + logic.protoss_deathball(state) + and logic.protoss_power_rating(state) >= 6 + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST.mission_name, + "South Power Core", + SC2LOTV_LOC_ID_OFFSET + 1506, + LocationType.VANILLA, + lambda state: ( + logic.protoss_deathball(state) + and logic.protoss_power_rating(state) >= 6 + and (adv_tactics or logic.protoss_fleet(state)) + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST.mission_name, + "East Power Core", + SC2LOTV_LOC_ID_OFFSET + 1507, + LocationType.VANILLA, + lambda state: ( + logic.protoss_deathball(state) + and logic.protoss_power_rating(state) >= 6 + and (adv_tactics or logic.protoss_fleet(state)) + ), + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 1600, + LocationType.VICTORY, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "North Sector: West Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1601, + LocationType.VANILLA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "North Sector: Northeast Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1602, + LocationType.EXTRA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "North Sector: Southeast Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1603, + LocationType.EXTRA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "South Sector: West Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1604, + LocationType.VANILLA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "South Sector: North Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1605, + LocationType.EXTRA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "South Sector: East Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1606, + LocationType.EXTRA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "West Sector: West Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1607, + LocationType.VANILLA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "West Sector: Mid Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1608, + LocationType.EXTRA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "West Sector: East Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1609, + LocationType.EXTRA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "East Sector: North Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1610, + LocationType.VANILLA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "East Sector: West Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1611, + LocationType.EXTRA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "East Sector: South Null Circuit", + SC2LOTV_LOC_ID_OFFSET + 1612, + LocationType.EXTRA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.PURIFICATION.mission_name, + "Purifier Warden", + SC2LOTV_LOC_ID_OFFSET + 1613, + LocationType.VANILLA, + logic.protoss_deathball, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 1700, + LocationType.VICTORY, + logic.protoss_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE.mission_name, + "First Terrazine Fog", + SC2LOTV_LOC_ID_OFFSET + 1701, + LocationType.EXTRA, + logic.protoss_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE.mission_name, + "Southwest Guardian", + SC2LOTV_LOC_ID_OFFSET + 1702, + LocationType.EXTRA, + logic.protoss_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE.mission_name, + "West Guardian", + SC2LOTV_LOC_ID_OFFSET + 1703, + LocationType.EXTRA, + logic.protoss_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE.mission_name, + "Northwest Guardian", + SC2LOTV_LOC_ID_OFFSET + 1704, + LocationType.EXTRA, + logic.protoss_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE.mission_name, + "Northeast Guardian", + SC2LOTV_LOC_ID_OFFSET + 1705, + LocationType.EXTRA, + logic.protoss_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE.mission_name, + "North Mothership", + SC2LOTV_LOC_ID_OFFSET + 1706, + LocationType.VANILLA, + logic.protoss_steps_of_the_rite_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE.mission_name, + "South Mothership", + SC2LOTV_LOC_ID_OFFSET + 1707, + LocationType.VANILLA, + logic.protoss_steps_of_the_rite_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa, + ), + make_location_data( + SC2Mission.RAK_SHIR.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 1800, + LocationType.VICTORY, + logic.protoss_rak_shir_requirement, + ), + make_location_data( + SC2Mission.RAK_SHIR.mission_name, + "North Slayn Elemental", + SC2LOTV_LOC_ID_OFFSET + 1801, + LocationType.VANILLA, + logic.protoss_rak_shir_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa, + ), + make_location_data( + SC2Mission.RAK_SHIR.mission_name, + "Southwest Slayn Elemental", + SC2LOTV_LOC_ID_OFFSET + 1802, + LocationType.VANILLA, + logic.protoss_rak_shir_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa, + ), + make_location_data( + SC2Mission.RAK_SHIR.mission_name, + "East Slayn Elemental", + SC2LOTV_LOC_ID_OFFSET + 1803, + LocationType.VANILLA, + logic.protoss_rak_shir_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa, + ), + make_location_data( + SC2Mission.RAK_SHIR.mission_name, + "Resource Pickups", + SC2LOTV_LOC_ID_OFFSET + 1804, + LocationType.EXTRA, + logic.protoss_rak_shir_requirement, + ), + make_location_data( + SC2Mission.RAK_SHIR.mission_name, + "Destroy Nexuses", + SC2LOTV_LOC_ID_OFFSET + 1805, + LocationType.CHALLENGE, + logic.protoss_rak_shir_requirement, + ), + make_location_data( + SC2Mission.RAK_SHIR.mission_name, + "Win in under 15 minutes", + SC2LOTV_LOC_ID_OFFSET + 1806, + LocationType.MASTERY, + logic.protoss_rak_shir_requirement, + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 1900, + LocationType.VICTORY, + logic.protoss_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE.mission_name, + "Northwest Power Core", + SC2LOTV_LOC_ID_OFFSET + 1901, + LocationType.EXTRA, + logic.protoss_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE.mission_name, + "Northeast Power Core", + SC2LOTV_LOC_ID_OFFSET + 1902, + LocationType.EXTRA, + logic.protoss_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE.mission_name, + "Southeast Power Core", + SC2LOTV_LOC_ID_OFFSET + 1903, + LocationType.EXTRA, + logic.protoss_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE.mission_name, + "West Hybrid Stasis Chamber", + SC2LOTV_LOC_ID_OFFSET + 1904, + LocationType.VANILLA, + logic.protoss_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE.mission_name, + "Southeast Hybrid Stasis Chamber", + SC2LOTV_LOC_ID_OFFSET + 1905, + LocationType.VANILLA, + logic.protoss_fleet, + ), + make_location_data( + SC2Mission.TEMPLAR_S_RETURN.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 2000, + LocationType.VICTORY, + logic.templars_return_phase_3_reach_dts_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_RETURN.mission_name, + "Citadel: First Gate", + SC2LOTV_LOC_ID_OFFSET + 2001, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.TEMPLAR_S_RETURN.mission_name, + "Citadel: Second Gate", + SC2LOTV_LOC_ID_OFFSET + 2002, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.TEMPLAR_S_RETURN.mission_name, + "Citadel: Power Structure", + SC2LOTV_LOC_ID_OFFSET + 2003, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.TEMPLAR_S_RETURN.mission_name, + "Temple Grounds: Gather Army", + SC2LOTV_LOC_ID_OFFSET + 2004, + LocationType.VANILLA, + logic.templars_return_phase_2_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_RETURN.mission_name, + "Temple Grounds: Power Structure", + SC2LOTV_LOC_ID_OFFSET + 2005, + LocationType.VANILLA, + logic.templars_return_phase_2_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_RETURN.mission_name, + "Caverns: Purifier", + SC2LOTV_LOC_ID_OFFSET + 2006, + LocationType.EXTRA, + logic.templars_return_phase_3_reach_colossus_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_RETURN.mission_name, + "Caverns: Dark Templar", + SC2LOTV_LOC_ID_OFFSET + 2007, + LocationType.EXTRA, + logic.templars_return_phase_3_reach_dts_requirement, + ), + make_location_data( + SC2Mission.THE_HOST.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 2100, + LocationType.VICTORY, + logic.protoss_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST.mission_name, + "Southeast Void Shard", + SC2LOTV_LOC_ID_OFFSET + 2101, + LocationType.EXTRA, + logic.protoss_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST.mission_name, + "South Void Shard", + SC2LOTV_LOC_ID_OFFSET + 2102, + LocationType.EXTRA, + logic.protoss_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST.mission_name, + "Southwest Void Shard", + SC2LOTV_LOC_ID_OFFSET + 2103, + LocationType.EXTRA, + logic.protoss_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST.mission_name, + "North Void Shard", + SC2LOTV_LOC_ID_OFFSET + 2104, + LocationType.EXTRA, + logic.protoss_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST.mission_name, + "Northwest Void Shard", + SC2LOTV_LOC_ID_OFFSET + 2105, + LocationType.EXTRA, + logic.protoss_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST.mission_name, + "Nerazim Warp in Zone", + SC2LOTV_LOC_ID_OFFSET + 2106, + LocationType.VANILLA, + logic.protoss_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST.mission_name, + "Tal'darim Warp in Zone", + SC2LOTV_LOC_ID_OFFSET + 2107, + LocationType.VANILLA, + logic.protoss_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST.mission_name, + "Purifier Warp in Zone", + SC2LOTV_LOC_ID_OFFSET + 2108, + LocationType.VANILLA, + logic.protoss_the_host_requirement, + ), + make_location_data( + SC2Mission.SALVATION.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 2200, + LocationType.VICTORY, + logic.protoss_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION.mission_name, + "Fabrication Matrix", + SC2LOTV_LOC_ID_OFFSET + 2201, + LocationType.EXTRA, + logic.protoss_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION.mission_name, + "Assault Cluster", + SC2LOTV_LOC_ID_OFFSET + 2202, + LocationType.EXTRA, + logic.protoss_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION.mission_name, + "Hull Breach", + SC2LOTV_LOC_ID_OFFSET + 2203, + LocationType.EXTRA, + logic.protoss_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION.mission_name, + "Core Critical", + SC2LOTV_LOC_ID_OFFSET + 2204, + LocationType.EXTRA, + logic.protoss_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION.mission_name, + "Kill Brutalisk", + SC2LOTV_LOC_ID_OFFSET + 2205, + LocationType.MASTERY, + logic.protoss_salvation_requirement, + ), + # Epilogue + make_location_data( + SC2Mission.INTO_THE_VOID.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 2300, + LocationType.VICTORY, + logic.into_the_void_requirement, + ), + make_location_data( + SC2Mission.INTO_THE_VOID.mission_name, + "Corruption Source", + SC2LOTV_LOC_ID_OFFSET + 2301, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.INTO_THE_VOID.mission_name, + "Southwest Forward Position", + SC2LOTV_LOC_ID_OFFSET + 2302, + LocationType.VANILLA, + logic.into_the_void_requirement, + ), + make_location_data( + SC2Mission.INTO_THE_VOID.mission_name, + "Northwest Forward Position", + SC2LOTV_LOC_ID_OFFSET + 2303, + LocationType.VANILLA, + logic.into_the_void_requirement, + ), + make_location_data( + SC2Mission.INTO_THE_VOID.mission_name, + "Southeast Forward Position", + SC2LOTV_LOC_ID_OFFSET + 2304, + LocationType.VANILLA, + logic.into_the_void_requirement, + ), + make_location_data( + SC2Mission.INTO_THE_VOID.mission_name, + "Northeast Forward Position", + SC2LOTV_LOC_ID_OFFSET + 2305, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_ESSENCE_OF_ETERNITY.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 2400, + LocationType.VICTORY, + logic.essence_of_eternity_requirement, + ), + make_location_data( + SC2Mission.THE_ESSENCE_OF_ETERNITY.mission_name, + "Initial Void Thrashers", + SC2LOTV_LOC_ID_OFFSET + 2401, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_ESSENCE_OF_ETERNITY.mission_name, + "Void Thrasher Wave 1", + SC2LOTV_LOC_ID_OFFSET + 2402, + LocationType.EXTRA, + logic.essence_of_eternity_requirement, + ), + make_location_data( + SC2Mission.THE_ESSENCE_OF_ETERNITY.mission_name, + "Void Thrasher Wave 2", + SC2LOTV_LOC_ID_OFFSET + 2403, + LocationType.EXTRA, + logic.essence_of_eternity_requirement, + ), + make_location_data( + SC2Mission.THE_ESSENCE_OF_ETERNITY.mission_name, + "Void Thrasher Wave 3", + SC2LOTV_LOC_ID_OFFSET + 2404, + LocationType.EXTRA, + logic.essence_of_eternity_requirement, + ), + make_location_data( + SC2Mission.THE_ESSENCE_OF_ETERNITY.mission_name, + "Void Thrasher Wave 4", + SC2LOTV_LOC_ID_OFFSET + 2405, + LocationType.EXTRA, + logic.essence_of_eternity_requirement, + ), + make_location_data( + SC2Mission.THE_ESSENCE_OF_ETERNITY.mission_name, + "No more than 15 Kerrigan Kills", + SC2LOTV_LOC_ID_OFFSET + 2406, + LocationType.MASTERY, + logic.essence_of_eternity_requirement, + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.AMON_S_FALL.mission_name, + "Victory", + SC2LOTV_LOC_ID_OFFSET + 2500, + LocationType.VICTORY, + logic.amons_fall_requirement, + ), + make_location_data( + SC2Mission.AMON_S_FALL.mission_name, + "Destroy 1 Crystal", + SC2LOTV_LOC_ID_OFFSET + 2501, + LocationType.EXTRA, + logic.amons_fall_requirement, + ), + make_location_data( + SC2Mission.AMON_S_FALL.mission_name, + "Destroy 2 Crystals", + SC2LOTV_LOC_ID_OFFSET + 2502, + LocationType.EXTRA, + logic.amons_fall_requirement, + ), + make_location_data( + SC2Mission.AMON_S_FALL.mission_name, + "Destroy 3 Crystals", + SC2LOTV_LOC_ID_OFFSET + 2503, + LocationType.EXTRA, + logic.amons_fall_requirement, + ), + make_location_data( + SC2Mission.AMON_S_FALL.mission_name, + "Destroy 4 Crystals", + SC2LOTV_LOC_ID_OFFSET + 2504, + LocationType.EXTRA, + logic.amons_fall_requirement, + ), + make_location_data( + SC2Mission.AMON_S_FALL.mission_name, + "Destroy 5 Crystals", + SC2LOTV_LOC_ID_OFFSET + 2505, + LocationType.EXTRA, + logic.amons_fall_requirement, + ), + make_location_data( + SC2Mission.AMON_S_FALL.mission_name, + "Destroy 6 Crystals", + SC2LOTV_LOC_ID_OFFSET + 2506, + LocationType.EXTRA, + logic.amons_fall_requirement, + ), + make_location_data( + SC2Mission.AMON_S_FALL.mission_name, + "Clear Void Chasms", + SC2LOTV_LOC_ID_OFFSET + 2507, + LocationType.MASTERY, + lambda state: logic.amons_fall_requirement(state) + and logic.spread_creep(state, False) + and logic.zerg_big_monsters(state), + ), + # Nova Covert Ops + make_location_data( + SC2Mission.THE_ESCAPE.mission_name, + "Victory", + SC2NCO_LOC_ID_OFFSET + 100, + LocationType.VICTORY, + logic.the_escape_requirement, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.THE_ESCAPE.mission_name, + "Rifle", + SC2NCO_LOC_ID_OFFSET + 101, + LocationType.VANILLA, + logic.the_escape_first_stage_requirement, + ), + make_location_data( + SC2Mission.THE_ESCAPE.mission_name, + "Grenades", + SC2NCO_LOC_ID_OFFSET + 102, + LocationType.VANILLA, + logic.the_escape_first_stage_requirement, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.THE_ESCAPE.mission_name, + "Agent Delta", + SC2NCO_LOC_ID_OFFSET + 103, + LocationType.VANILLA, + logic.the_escape_requirement, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.THE_ESCAPE.mission_name, + "Agent Pierce", + SC2NCO_LOC_ID_OFFSET + 104, + LocationType.VANILLA, + logic.the_escape_requirement, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.THE_ESCAPE.mission_name, + "Agent Stone", + SC2NCO_LOC_ID_OFFSET + 105, + LocationType.VANILLA, + logic.the_escape_requirement, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.SUDDEN_STRIKE.mission_name, + "Victory", + SC2NCO_LOC_ID_OFFSET + 200, + LocationType.VICTORY, + logic.sudden_strike_requirement, + ), + make_location_data( + SC2Mission.SUDDEN_STRIKE.mission_name, + "Research Center", + SC2NCO_LOC_ID_OFFSET + 201, + LocationType.VANILLA, + logic.sudden_strike_requirement, + ), + make_location_data( + SC2Mission.SUDDEN_STRIKE.mission_name, + "Weaponry Labs", + SC2NCO_LOC_ID_OFFSET + 202, + LocationType.VANILLA, + logic.sudden_strike_requirement, + ), + make_location_data( + SC2Mission.SUDDEN_STRIKE.mission_name, + "Brutalisk", + SC2NCO_LOC_ID_OFFSET + 203, + LocationType.EXTRA, + logic.sudden_strike_requirement, + ), + make_location_data( + SC2Mission.SUDDEN_STRIKE.mission_name, + "Gas Pickups", + SC2NCO_LOC_ID_OFFSET + 204, + LocationType.EXTRA, + lambda state: ( + logic.advanced_tactics or logic.sudden_strike_requirement(state) + ), + ), + make_location_data( + SC2Mission.SUDDEN_STRIKE.mission_name, + "Protect Buildings", + SC2NCO_LOC_ID_OFFSET + 205, + LocationType.CHALLENGE, + logic.sudden_strike_requirement, + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.SUDDEN_STRIKE.mission_name, + "Zerg Base", + SC2NCO_LOC_ID_OFFSET + 206, + LocationType.MASTERY, + lambda state: ( + logic.sudden_strike_requirement(state) + and logic.terran_competent_comp(state) + and logic.terran_base_trasher(state) + and logic.terran_power_rating(state) >= 8 + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ENEMY_INTELLIGENCE.mission_name, + "Victory", + SC2NCO_LOC_ID_OFFSET + 300, + LocationType.VICTORY, + logic.enemy_intelligence_third_stage_requirement, + hard_rule=logic.enemy_intelligence_cliff_garrison_and_nova_mobility, + ), + make_location_data( + SC2Mission.ENEMY_INTELLIGENCE.mission_name, + "West Garrison", + SC2NCO_LOC_ID_OFFSET + 301, + LocationType.EXTRA, + logic.enemy_intelligence_first_stage_requirement, + hard_rule=logic.enemy_intelligence_garrisonable_unit, + ), + make_location_data( + SC2Mission.ENEMY_INTELLIGENCE.mission_name, + "Close Garrison", + SC2NCO_LOC_ID_OFFSET + 302, + LocationType.EXTRA, + logic.enemy_intelligence_first_stage_requirement, + hard_rule=logic.enemy_intelligence_garrisonable_unit, + ), + make_location_data( + SC2Mission.ENEMY_INTELLIGENCE.mission_name, + "Northeast Garrison", + SC2NCO_LOC_ID_OFFSET + 303, + LocationType.EXTRA, + logic.enemy_intelligence_first_stage_requirement, + hard_rule=logic.enemy_intelligence_garrisonable_unit, + ), + make_location_data( + SC2Mission.ENEMY_INTELLIGENCE.mission_name, + "Southeast Garrison", + SC2NCO_LOC_ID_OFFSET + 304, + LocationType.EXTRA, + lambda state: ( + logic.enemy_intelligence_first_stage_requirement(state) + and logic.enemy_intelligence_cliff_garrison(state) + ), + hard_rule=logic.enemy_intelligence_cliff_garrison, + ), + make_location_data( + SC2Mission.ENEMY_INTELLIGENCE.mission_name, + "South Garrison", + SC2NCO_LOC_ID_OFFSET + 305, + LocationType.EXTRA, + logic.enemy_intelligence_first_stage_requirement, + hard_rule=logic.enemy_intelligence_garrisonable_unit, + ), + make_location_data( + SC2Mission.ENEMY_INTELLIGENCE.mission_name, + "All Garrisons", + SC2NCO_LOC_ID_OFFSET + 306, + LocationType.VANILLA, + lambda state: ( + logic.enemy_intelligence_first_stage_requirement(state) + and logic.enemy_intelligence_cliff_garrison(state) + ), + hard_rule=logic.enemy_intelligence_cliff_garrison, + ), + make_location_data( + SC2Mission.ENEMY_INTELLIGENCE.mission_name, + "Forces Rescued", + SC2NCO_LOC_ID_OFFSET + 307, + LocationType.VANILLA, + logic.enemy_intelligence_first_stage_requirement, + ), + make_location_data( + SC2Mission.ENEMY_INTELLIGENCE.mission_name, + "Communications Hub", + SC2NCO_LOC_ID_OFFSET + 308, + LocationType.VANILLA, + logic.enemy_intelligence_second_stage_requirement, + hard_rule=logic.enemy_intelligence_cliff_garrison_and_nova_mobility, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "Victory", + SC2NCO_LOC_ID_OFFSET + 400, + LocationType.VICTORY, + logic.trouble_in_paradise_requirement, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "North Base: West Hatchery", + SC2NCO_LOC_ID_OFFSET + 401, + LocationType.VANILLA, + logic.trouble_in_paradise_requirement, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "North Base: North Hatchery", + SC2NCO_LOC_ID_OFFSET + 402, + LocationType.VANILLA, + logic.trouble_in_paradise_requirement, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "North Base: East Hatchery", + SC2NCO_LOC_ID_OFFSET + 403, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "South Base: Northwest Hatchery", + SC2NCO_LOC_ID_OFFSET + 404, + LocationType.VANILLA, + logic.trouble_in_paradise_requirement, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "South Base: Southwest Hatchery", + SC2NCO_LOC_ID_OFFSET + 405, + LocationType.VANILLA, + logic.trouble_in_paradise_requirement, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "South Base: East Hatchery", + SC2NCO_LOC_ID_OFFSET + 406, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "North Shield Projector", + SC2NCO_LOC_ID_OFFSET + 407, + LocationType.EXTRA, + logic.trouble_in_paradise_requirement, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "East Shield Projector", + SC2NCO_LOC_ID_OFFSET + 408, + LocationType.EXTRA, + logic.trouble_in_paradise_requirement, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "South Shield Projector", + SC2NCO_LOC_ID_OFFSET + 409, + LocationType.EXTRA, + logic.trouble_in_paradise_requirement, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "West Shield Projector", + SC2NCO_LOC_ID_OFFSET + 410, + LocationType.EXTRA, + logic.trouble_in_paradise_requirement, + ), + make_location_data( + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + "Fleet Beacon", + SC2NCO_LOC_ID_OFFSET + 411, + LocationType.VANILLA, + logic.trouble_in_paradise_requirement, + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "Victory", + SC2NCO_LOC_ID_OFFSET + 500, + LocationType.VICTORY, + logic.night_terrors_requirement, + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "1 Terrazine Node Collected", + SC2NCO_LOC_ID_OFFSET + 501, + LocationType.EXTRA, + logic.night_terrors_requirement, + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "2 Terrazine Nodes Collected", + SC2NCO_LOC_ID_OFFSET + 502, + LocationType.EXTRA, + logic.night_terrors_requirement, + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "3 Terrazine Nodes Collected", + SC2NCO_LOC_ID_OFFSET + 503, + LocationType.EXTRA, + logic.night_terrors_requirement, + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "4 Terrazine Nodes Collected", + SC2NCO_LOC_ID_OFFSET + 504, + LocationType.EXTRA, + logic.night_terrors_requirement, + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "5 Terrazine Nodes Collected", + SC2NCO_LOC_ID_OFFSET + 505, + LocationType.EXTRA, + logic.night_terrors_requirement, + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "HERC Outpost", + SC2NCO_LOC_ID_OFFSET + 506, + LocationType.VANILLA, + logic.night_terrors_requirement, + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "Umojan Mine", + SC2NCO_LOC_ID_OFFSET + 507, + LocationType.EXTRA, + logic.night_terrors_requirement, + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "Blightbringer", + SC2NCO_LOC_ID_OFFSET + 508, + LocationType.VANILLA, + lambda state: ( + logic.night_terrors_requirement(state) + and logic.nova_ranged_weapon(state) + and state.has_any( + { + item_names.NOVA_HELLFIRE_SHOTGUN, + item_names.NOVA_PULSE_GRENADES, + item_names.NOVA_STIM_INFUSION, + item_names.NOVA_HOLO_DECOY, + }, + player, + ) + ), + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "Science Facility", + SC2NCO_LOC_ID_OFFSET + 509, + LocationType.EXTRA, + logic.night_terrors_requirement, + ), + make_location_data( + SC2Mission.NIGHT_TERRORS.mission_name, + "Eradicators", + SC2NCO_LOC_ID_OFFSET + 510, + LocationType.VANILLA, + lambda state: ( + logic.night_terrors_requirement(state) and logic.nova_any_weapon(state) + ), + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Victory", + SC2NCO_LOC_ID_OFFSET + 600, + LocationType.VICTORY, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Close North Evidence Coordinates", + SC2NCO_LOC_ID_OFFSET + 601, + LocationType.EXTRA, + lambda state: ( + state.has_any( + { + item_names.LIBERATOR_RAID_ARTILLERY, + item_names.RAVEN_HUNTER_SEEKER_WEAPON, + }, + player, + ) + or logic.terran_common_unit(state) + ), + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Close East Evidence Coordinates", + SC2NCO_LOC_ID_OFFSET + 602, + LocationType.EXTRA, + lambda state: ( + state.has_any( + { + item_names.LIBERATOR_RAID_ARTILLERY, + item_names.RAVEN_HUNTER_SEEKER_WEAPON, + }, + player, + ) + or logic.terran_common_unit(state) + ), + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Far North Evidence Coordinates", + SC2NCO_LOC_ID_OFFSET + 603, + LocationType.EXTRA, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Far East Evidence Coordinates", + SC2NCO_LOC_ID_OFFSET + 604, + LocationType.EXTRA, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Experimental Weapon", + SC2NCO_LOC_ID_OFFSET + 605, + LocationType.VANILLA, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Northwest Subway Entrance", + SC2NCO_LOC_ID_OFFSET + 606, + LocationType.VANILLA, + lambda state: ( + state.has_any( + { + item_names.LIBERATOR_RAID_ARTILLERY, + item_names.RAVEN_HUNTER_SEEKER_WEAPON, + }, + player, + ) + and logic.terran_common_unit(state) + or logic.flashpoint_far_requirement(state) + ), + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Southeast Subway Entrance", + SC2NCO_LOC_ID_OFFSET + 607, + LocationType.VANILLA, + lambda state: state.has_any( + { + item_names.LIBERATOR_RAID_ARTILLERY, + item_names.RAVEN_HUNTER_SEEKER_WEAPON, + }, + player, + ) + and logic.terran_common_unit(state) + or logic.flashpoint_far_requirement(state), + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Northeast Subway Entrance", + SC2NCO_LOC_ID_OFFSET + 608, + LocationType.VANILLA, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Expansion Hatchery", + SC2NCO_LOC_ID_OFFSET + 609, + LocationType.EXTRA, + lambda state: state.has(item_names.LIBERATOR_RAID_ARTILLERY, player) + and logic.terran_common_unit(state) + or logic.flashpoint_far_requirement(state), + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Baneling Spawns", + SC2NCO_LOC_ID_OFFSET + 610, + LocationType.EXTRA, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Mutalisk Spawns", + SC2NCO_LOC_ID_OFFSET + 611, + LocationType.EXTRA, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Nydus Worm Spawns", + SC2NCO_LOC_ID_OFFSET + 612, + LocationType.EXTRA, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Lurker Spawns", + SC2NCO_LOC_ID_OFFSET + 613, + LocationType.EXTRA, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Brood Lord Spawns", + SC2NCO_LOC_ID_OFFSET + 614, + LocationType.EXTRA, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.FLASHPOINT.mission_name, + "Ultralisk Spawns", + SC2NCO_LOC_ID_OFFSET + 615, + LocationType.EXTRA, + logic.flashpoint_far_requirement, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Victory", + SC2NCO_LOC_ID_OFFSET + 700, + LocationType.VICTORY, + logic.enemy_shadow_victory, + hard_rule=lambda state: logic.nova_beat_stone(state) + and logic.enemy_shadow_door_unlocks_tool(state), + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Sewers: Domination Visor", + SC2NCO_LOC_ID_OFFSET + 701, + LocationType.VANILLA, + logic.enemy_shadow_domination, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Sewers: Resupply Crate", + SC2NCO_LOC_ID_OFFSET + 702, + LocationType.EXTRA, + logic.enemy_shadow_first_stage, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Sewers: Facility Access", + SC2NCO_LOC_ID_OFFSET + 703, + LocationType.VANILLA, + logic.enemy_shadow_first_stage, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Facility: Northwest Door Lock", + SC2NCO_LOC_ID_OFFSET + 704, + LocationType.VANILLA, + logic.enemy_shadow_door_controls, + hard_rule=lambda state: logic.nova_any_nobuild_damage(state) + and logic.enemy_shadow_door_unlocks_tool(state), + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Facility: Southeast Door Lock", + SC2NCO_LOC_ID_OFFSET + 705, + LocationType.VANILLA, + logic.enemy_shadow_door_controls, + hard_rule=lambda state: logic.nova_any_nobuild_damage(state) + and logic.enemy_shadow_door_unlocks_tool(state), + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Facility: Blazefire Gunblade", + SC2NCO_LOC_ID_OFFSET + 706, + LocationType.VANILLA, + lambda state: ( + logic.enemy_shadow_second_stage(state) + and ( + logic.grant_story_tech == GrantStoryTech.option_grant + or state.has(item_names.NOVA_BLINK, player) + or ( + adv_tactics + and state.has_all( + { + item_names.NOVA_DOMINATION, + item_names.NOVA_HOLO_DECOY, + item_names.NOVA_JUMP_SUIT_MODULE, + }, + player, + ) + ) + ) + ), + hard_rule=logic.enemy_shadow_nova_damage_and_blazefire_unlock, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Facility: Blink Suit", + SC2NCO_LOC_ID_OFFSET + 707, + LocationType.VANILLA, + logic.enemy_shadow_second_stage, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Facility: Advanced Weaponry", + SC2NCO_LOC_ID_OFFSET + 708, + LocationType.VANILLA, + logic.enemy_shadow_second_stage, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Facility: Entrance Resupply Crate", + SC2NCO_LOC_ID_OFFSET + 709, + LocationType.EXTRA, + logic.enemy_shadow_first_stage, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Facility: West Resupply Crate", + SC2NCO_LOC_ID_OFFSET + 710, + LocationType.EXTRA, + logic.enemy_shadow_second_stage, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Facility: North Resupply Crate", + SC2NCO_LOC_ID_OFFSET + 711, + LocationType.EXTRA, + logic.enemy_shadow_second_stage, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Facility: East Resupply Crate", + SC2NCO_LOC_ID_OFFSET + 712, + LocationType.EXTRA, + logic.enemy_shadow_second_stage, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + "Facility: South Resupply Crate", + SC2NCO_LOC_ID_OFFSET + 713, + LocationType.EXTRA, + logic.enemy_shadow_second_stage, + hard_rule=logic.nova_any_nobuild_damage, + ), + make_location_data( + SC2Mission.DARK_SKIES.mission_name, + "Victory", + SC2NCO_LOC_ID_OFFSET + 800, + LocationType.VICTORY, + logic.dark_skies_requirement, + ), + make_location_data( + SC2Mission.DARK_SKIES.mission_name, + "First Squadron of Dominion Fleet", + SC2NCO_LOC_ID_OFFSET + 801, + LocationType.EXTRA, + logic.dark_skies_requirement, + ), + make_location_data( + SC2Mission.DARK_SKIES.mission_name, + "Remainder of Dominion Fleet", + SC2NCO_LOC_ID_OFFSET + 802, + LocationType.EXTRA, + logic.dark_skies_requirement, + ), + make_location_data( + SC2Mission.DARK_SKIES.mission_name, + "Ji'nara", + SC2NCO_LOC_ID_OFFSET + 803, + LocationType.EXTRA, + logic.dark_skies_requirement, + ), + make_location_data( + SC2Mission.DARK_SKIES.mission_name, + "Science Facility", + SC2NCO_LOC_ID_OFFSET + 804, + LocationType.VANILLA, + logic.dark_skies_requirement, + ), + make_location_data( + SC2Mission.END_GAME.mission_name, + "Victory", + SC2NCO_LOC_ID_OFFSET + 900, + LocationType.VICTORY, + lambda state: logic.end_game_requirement(state) + and logic.nova_any_weapon(state), + ), + make_location_data( + SC2Mission.END_GAME.mission_name, + "Destroy the Xanthos", + SC2NCO_LOC_ID_OFFSET + 901, + LocationType.VANILLA, + logic.end_game_requirement, + ), + make_location_data( + SC2Mission.END_GAME.mission_name, + "Disable Xanthos Railgun", + SC2NCO_LOC_ID_OFFSET + 902, + LocationType.EXTRA, + logic.end_game_requirement, + ), + make_location_data( + SC2Mission.END_GAME.mission_name, + "Disable Xanthos Flamethrower", + SC2NCO_LOC_ID_OFFSET + 903, + LocationType.EXTRA, + logic.end_game_requirement, + ), + make_location_data( + SC2Mission.END_GAME.mission_name, + "Disable Xanthos Fighter Bay", + SC2NCO_LOC_ID_OFFSET + 904, + LocationType.EXTRA, + logic.end_game_requirement, + ), + make_location_data( + SC2Mission.END_GAME.mission_name, + "Disable Xanthos Missile Pods", + SC2NCO_LOC_ID_OFFSET + 905, + LocationType.EXTRA, + logic.end_game_requirement, + ), + make_location_data( + SC2Mission.END_GAME.mission_name, + "Protect Hyperion", + SC2NCO_LOC_ID_OFFSET + 906, + LocationType.CHALLENGE, + logic.end_game_requirement, + ), + make_location_data( + SC2Mission.END_GAME.mission_name, + "Destroy Orbital Commands", + SC2NCO_LOC_ID_OFFSET + 907, + LocationType.CHALLENGE, + logic.end_game_requirement, + flags=LocationFlag.BASEBUST, + ), + # Mission Variants + # 10X/20X - Liberation Day + make_location_data( + SC2Mission.THE_OUTLAWS_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 300, + LocationType.VICTORY, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.THE_OUTLAWS_Z.mission_name, + "Rebel Base", + SC2_RACESWAP_LOC_ID_OFFSET + 301, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.THE_OUTLAWS_Z.mission_name, + "North Resource Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 302, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.THE_OUTLAWS_Z.mission_name, + "Bunker", + SC2_RACESWAP_LOC_ID_OFFSET + 303, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.THE_OUTLAWS_Z.mission_name, + "Close Resource Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 304, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_OUTLAWS_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 400, + LocationType.VICTORY, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.THE_OUTLAWS_P.mission_name, + "Rebel Base", + SC2_RACESWAP_LOC_ID_OFFSET + 401, + LocationType.VANILLA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.THE_OUTLAWS_P.mission_name, + "North Resource Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 402, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.THE_OUTLAWS_P.mission_name, + "Bunker", + SC2_RACESWAP_LOC_ID_OFFSET + 403, + LocationType.VANILLA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.THE_OUTLAWS_P.mission_name, + "Close Resource Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 404, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 500, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 5 + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "First Group Rescued", + SC2_RACESWAP_LOC_ID_OFFSET + 501, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "Second Group Rescued", + SC2_RACESWAP_LOC_ID_OFFSET + 502, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "Third Group Rescued", + SC2_RACESWAP_LOC_ID_OFFSET + 503, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 5 + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "First Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 504, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "Second Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 505, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "Third Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 506, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "Fourth Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 507, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "Ride's on its Way", + SC2_RACESWAP_LOC_ID_OFFSET + 508, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 5 + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "Hold Just a Little Longer", + SC2_RACESWAP_LOC_ID_OFFSET + 509, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 5 + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR_Z.mission_name, + "Cavalry's on the Way", + SC2_RACESWAP_LOC_ID_OFFSET + 510, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, True) >= 5 + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 600, + LocationType.VICTORY, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_light_anti_air(state) + and ( + state.has(item_names.PHOTON_CANNON, player) + or logic.protoss_basic_splash(state) + ) + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "First Group Rescued", + SC2_RACESWAP_LOC_ID_OFFSET + 601, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "Second Group Rescued", + SC2_RACESWAP_LOC_ID_OFFSET + 602, + LocationType.VANILLA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "Third Group Rescued", + SC2_RACESWAP_LOC_ID_OFFSET + 603, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_light_anti_air(state) + and ( + state.has(item_names.PHOTON_CANNON, player) + or logic.protoss_basic_splash(state) + ) + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "First Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 604, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "Second Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 605, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "Third Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 606, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "Fourth Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 607, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "Ride's on its Way", + SC2_RACESWAP_LOC_ID_OFFSET + 608, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_light_anti_air(state) + and ( + state.has(item_names.PHOTON_CANNON, player) + or logic.protoss_basic_splash(state) + ) + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "Hold Just a Little Longer", + SC2_RACESWAP_LOC_ID_OFFSET + 609, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_light_anti_air(state) + and ( + state.has(item_names.PHOTON_CANNON, player) + or logic.protoss_basic_splash(state) + ) + ), + ), + make_location_data( + SC2Mission.ZERO_HOUR_P.mission_name, + "Cavalry's on the Way", + SC2_RACESWAP_LOC_ID_OFFSET + 610, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_light_anti_air(state) + and ( + state.has(item_names.PHOTON_CANNON, player) + or logic.protoss_basic_splash(state) + ) + ), + ), + make_location_data( + SC2Mission.EVACUATION_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 700, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit(state) + and ( + logic.zerg_competent_anti_air(state) + or (adv_tactics and logic.zerg_basic_kerriganless_anti_air(state)) + ) + ), + ), + make_location_data( + SC2Mission.EVACUATION_Z.mission_name, + "North Chrysalis", + SC2_RACESWAP_LOC_ID_OFFSET + 701, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.EVACUATION_Z.mission_name, + "West Chrysalis", + SC2_RACESWAP_LOC_ID_OFFSET + 702, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.EVACUATION_Z.mission_name, + "East Chrysalis", + SC2_RACESWAP_LOC_ID_OFFSET + 703, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.EVACUATION_Z.mission_name, + "Reach Hanson", + SC2_RACESWAP_LOC_ID_OFFSET + 704, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.EVACUATION_Z.mission_name, + "Secret Resource Stash", + SC2_RACESWAP_LOC_ID_OFFSET + 705, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.EVACUATION_Z.mission_name, + "Flawless", + SC2_RACESWAP_LOC_ID_OFFSET + 706, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_common_unit(state) + and logic.zerg_defense_rating(state, True, False) >= 5 + and ( + (adv_tactics and logic.zerg_basic_kerriganless_anti_air(state)) + or logic.zerg_competent_anti_air(state) + ) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.EVACUATION_Z.mission_name, + "Western Zerg Base", + SC2_RACESWAP_LOC_ID_OFFSET + 707, + LocationType.MASTERY, + lambda state: ( + logic.zerg_common_unit_competent_aa(state) + and logic.zerg_base_buster(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.EVACUATION_Z.mission_name, + "Eastern Zerg Base", + SC2_RACESWAP_LOC_ID_OFFSET + 708, + LocationType.MASTERY, + lambda state: ( + logic.zerg_common_unit_competent_aa(state) + and logic.zerg_base_buster(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.EVACUATION_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 800, + LocationType.VICTORY, + lambda state: ( + logic.protoss_common_unit(state) + and ( + (adv_tactics and logic.protoss_basic_anti_air(state)) + or logic.protoss_anti_light_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.EVACUATION_P.mission_name, + "North Chrysalis", + SC2_RACESWAP_LOC_ID_OFFSET + 801, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.EVACUATION_P.mission_name, + "West Chrysalis", + SC2_RACESWAP_LOC_ID_OFFSET + 802, + LocationType.VANILLA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.EVACUATION_P.mission_name, + "East Chrysalis", + SC2_RACESWAP_LOC_ID_OFFSET + 803, + LocationType.VANILLA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.EVACUATION_P.mission_name, + "Reach Hanson", + SC2_RACESWAP_LOC_ID_OFFSET + 804, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.EVACUATION_P.mission_name, + "Secret Resource Stash", + SC2_RACESWAP_LOC_ID_OFFSET + 805, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.EVACUATION_P.mission_name, + "Flawless", + SC2_RACESWAP_LOC_ID_OFFSET + 806, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_defense_rating(state, True) >= 2 + and logic.protoss_common_unit(state) + and ( + (adv_tactics and logic.protoss_basic_anti_air(state)) + or logic.protoss_anti_light_anti_air(state) + ) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.EVACUATION_P.mission_name, + "Western Zerg Base", + SC2_RACESWAP_LOC_ID_OFFSET + 807, + LocationType.MASTERY, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.EVACUATION_P.mission_name, + "Eastern Zerg Base", + SC2_RACESWAP_LOC_ID_OFFSET + 808, + LocationType.MASTERY, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.OUTBREAK_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 900, + LocationType.VICTORY, + logic.zerg_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_Z.mission_name, + "Left Infestor", + SC2_RACESWAP_LOC_ID_OFFSET + 901, + LocationType.VANILLA, + logic.zerg_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_Z.mission_name, + "Right Infestor", + SC2_RACESWAP_LOC_ID_OFFSET + 902, + LocationType.VANILLA, + logic.zerg_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_Z.mission_name, + "North Infested Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 903, + LocationType.EXTRA, + logic.zerg_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_Z.mission_name, + "South Infested Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 904, + LocationType.EXTRA, + logic.zerg_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_Z.mission_name, + "Northwest Bar", + SC2_RACESWAP_LOC_ID_OFFSET + 905, + LocationType.EXTRA, + logic.zerg_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_Z.mission_name, + "North Bar", + SC2_RACESWAP_LOC_ID_OFFSET + 906, + LocationType.EXTRA, + logic.zerg_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_Z.mission_name, + "South Bar", + SC2_RACESWAP_LOC_ID_OFFSET + 907, + LocationType.EXTRA, + logic.zerg_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 1000, + LocationType.VICTORY, + logic.protoss_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_P.mission_name, + "Left Infestor", + SC2_RACESWAP_LOC_ID_OFFSET + 1001, + LocationType.VANILLA, + logic.protoss_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_P.mission_name, + "Right Infestor", + SC2_RACESWAP_LOC_ID_OFFSET + 1002, + LocationType.VANILLA, + logic.protoss_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_P.mission_name, + "North Infested Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 1003, + LocationType.EXTRA, + logic.protoss_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_P.mission_name, + "South Infested Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 1004, + LocationType.EXTRA, + logic.protoss_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_P.mission_name, + "Northwest Bar", + SC2_RACESWAP_LOC_ID_OFFSET + 1005, + LocationType.EXTRA, + logic.protoss_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_P.mission_name, + "North Bar", + SC2_RACESWAP_LOC_ID_OFFSET + 1006, + LocationType.EXTRA, + logic.protoss_outbreak_requirement, + ), + make_location_data( + SC2Mission.OUTBREAK_P.mission_name, + "South Bar", + SC2_RACESWAP_LOC_ID_OFFSET + 1007, + LocationType.EXTRA, + logic.protoss_outbreak_requirement, + ), + make_location_data( + SC2Mission.SAFE_HAVEN_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 1100, + LocationType.VICTORY, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.SAFE_HAVEN_Z.mission_name, + "North Nexus", + SC2_RACESWAP_LOC_ID_OFFSET + 1101, + LocationType.EXTRA, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.SAFE_HAVEN_Z.mission_name, + "East Nexus", + SC2_RACESWAP_LOC_ID_OFFSET + 1102, + LocationType.EXTRA, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.SAFE_HAVEN_Z.mission_name, + "South Nexus", + SC2_RACESWAP_LOC_ID_OFFSET + 1103, + LocationType.EXTRA, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.SAFE_HAVEN_Z.mission_name, + "First Terror Fleet", + SC2_RACESWAP_LOC_ID_OFFSET + 1104, + LocationType.VANILLA, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.SAFE_HAVEN_Z.mission_name, + "Second Terror Fleet", + SC2_RACESWAP_LOC_ID_OFFSET + 1105, + LocationType.VANILLA, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.SAFE_HAVEN_Z.mission_name, + "Third Terror Fleet", + SC2_RACESWAP_LOC_ID_OFFSET + 1106, + LocationType.VANILLA, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.SAFE_HAVEN_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 1200, + LocationType.VICTORY, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state), + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.SAFE_HAVEN_P.mission_name, + "North Nexus", + SC2_RACESWAP_LOC_ID_OFFSET + 1201, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state), + ), + make_location_data( + SC2Mission.SAFE_HAVEN_P.mission_name, + "East Nexus", + SC2_RACESWAP_LOC_ID_OFFSET + 1202, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state), + ), + make_location_data( + SC2Mission.SAFE_HAVEN_P.mission_name, + "South Nexus", + SC2_RACESWAP_LOC_ID_OFFSET + 1203, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state), + ), + make_location_data( + SC2Mission.SAFE_HAVEN_P.mission_name, + "First Terror Fleet", + SC2_RACESWAP_LOC_ID_OFFSET + 1204, + LocationType.VANILLA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state), + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.SAFE_HAVEN_P.mission_name, + "Second Terror Fleet", + SC2_RACESWAP_LOC_ID_OFFSET + 1205, + LocationType.VANILLA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state), + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.SAFE_HAVEN_P.mission_name, + "Third Terror Fleet", + SC2_RACESWAP_LOC_ID_OFFSET + 1206, + LocationType.VANILLA, + lambda state: logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state), + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 1300, + LocationType.VICTORY, + logic.zerg_havens_fall_requirement, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "North Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 1301, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "East Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 1302, + LocationType.VANILLA, + logic.zerg_havens_fall_requirement, + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "South Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 1303, + LocationType.VANILLA, + logic.zerg_havens_fall_requirement, + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "Northeast Colony Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1304, + LocationType.CHALLENGE, + logic.zerg_havens_fall_requirement, + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "East Colony Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1305, + LocationType.CHALLENGE, + logic.zerg_respond_to_colony_infestations, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "Middle Colony Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1306, + LocationType.CHALLENGE, + logic.zerg_respond_to_colony_infestations, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "Southeast Colony Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1307, + LocationType.CHALLENGE, + logic.zerg_respond_to_colony_infestations, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "Southwest Colony Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1308, + LocationType.CHALLENGE, + logic.zerg_respond_to_colony_infestations, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "Southwest Gas Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 1309, + LocationType.EXTRA, + lambda state: state.has_any( + (item_names.OVERLORD_VENTRAL_SACS, item_names.YGGDRASIL), player + ) + or adv_tactics + and state.has_all( + ( + item_names.INFESTED_BANSHEE, + item_names.INFESTED_BANSHEE_RAPID_HIBERNATION, + ), + player, + ), + hard_rule=logic.zerg_can_collect_pickup_across_gap, + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "East Gas Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 1310, + LocationType.EXTRA, + lambda state: ( + logic.zerg_havens_fall_requirement(state) + and ( + state.has(item_names.OVERLORD_VENTRAL_SACS, player) + or adv_tactics + and ( + state.has_all( + ( + item_names.INFESTED_BANSHEE, + item_names.INFESTED_BANSHEE_RAPID_HIBERNATION, + ), + player, + ) + or state.has(item_names.YGGDRASIL, player) + or logic.morph_viper(state) + ) + ) + ), + ), + make_location_data( + SC2Mission.HAVENS_FALL_Z.mission_name, + "Southeast Gas Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 1311, + LocationType.EXTRA, + lambda state: ( + logic.zerg_havens_fall_requirement(state) + and ( + state.has(item_names.OVERLORD_VENTRAL_SACS, player) + or adv_tactics + and ( + state.has_all( + ( + item_names.INFESTED_BANSHEE, + item_names.INFESTED_BANSHEE_RAPID_HIBERNATION, + ), + player, + ) + or state.has(item_names.YGGDRASIL, player) + ) + ) + ), + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 1400, + LocationType.VICTORY, + logic.protoss_havens_fall_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "North Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 1401, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "East Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 1402, + LocationType.VANILLA, + logic.protoss_havens_fall_requirement, + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "South Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 1403, + LocationType.VANILLA, + logic.protoss_havens_fall_requirement, + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "Northeast Colony Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1404, + LocationType.CHALLENGE, + logic.protoss_respond_to_colony_infestations, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "East Colony Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1405, + LocationType.CHALLENGE, + logic.protoss_respond_to_colony_infestations, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "Middle Colony Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1406, + LocationType.CHALLENGE, + logic.protoss_respond_to_colony_infestations, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "Southeast Colony Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1407, + LocationType.CHALLENGE, + logic.protoss_respond_to_colony_infestations, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "Southwest Colony Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1408, + LocationType.CHALLENGE, + logic.protoss_respond_to_colony_infestations, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "Southwest Gas Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 1409, + LocationType.EXTRA, + lambda state: ( + state.has(item_names.WARP_PRISM, player) + or adv_tactics + and ( + state.has_all( + (item_names.MISTWING, item_names.MISTWING_PILOT), player + ) + or state.has(item_names.ARBITER, player) + ) + ), + hard_rule=logic.protoss_any_gap_transport, + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "East Gas Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 1410, + LocationType.EXTRA, + lambda state: ( + logic.protoss_havens_fall_requirement(state) + and ( + state.has(item_names.WARP_PRISM, player) + or adv_tactics + and ( + state.has_all( + (item_names.MISTWING, item_names.MISTWING_PILOT), player + ) + or state.has(item_names.ARBITER, player) + ) + ) + ), + hard_rule=logic.protoss_any_gap_transport, + ), + make_location_data( + SC2Mission.HAVENS_FALL_P.mission_name, + "Southeast Gas Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 1411, + LocationType.EXTRA, + lambda state: ( + logic.protoss_havens_fall_requirement(state) + and ( + state.has(item_names.WARP_PRISM, player) + or adv_tactics + and ( + state.has_all( + (item_names.MISTWING, item_names.MISTWING_PILOT), player + ) + or state.has(item_names.ARBITER, player) + ) + ) + ), + hard_rule=logic.protoss_any_gap_transport, + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 1500, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit(state) + and ( + (adv_tactics and logic.zerg_moderate_anti_air(state)) + or logic.zerg_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_Z.mission_name, + "First Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1501, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_Z.mission_name, + "Second Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1502, + LocationType.VANILLA, + lambda state: logic.zerg_common_unit(state) + or state.has(item_names.OVERLORD_VENTRAL_SACS, player), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_Z.mission_name, + "Third Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1503, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and ( + (adv_tactics and logic.zerg_moderate_anti_air(state)) + or logic.zerg_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_Z.mission_name, + "Fourth Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1504, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) + and ( + (adv_tactics and logic.zerg_moderate_anti_air(state)) + or logic.zerg_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_Z.mission_name, + "First Forcefield Area Busted", + SC2_RACESWAP_LOC_ID_OFFSET + 1505, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and ( + (adv_tactics and logic.zerg_moderate_anti_air(state)) + or logic.zerg_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_Z.mission_name, + "Second Forcefield Area Busted", + SC2_RACESWAP_LOC_ID_OFFSET + 1506, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) + and ( + (adv_tactics and logic.zerg_moderate_anti_air(state)) + or logic.zerg_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_Z.mission_name, + "Defeat Kerrigan", + SC2_RACESWAP_LOC_ID_OFFSET + 1507, + LocationType.MASTERY, + lambda state: ( + logic.zerg_common_unit_competent_aa(state) + and logic.zerg_base_buster(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 1600, + LocationType.VICTORY, + lambda state: ( + logic.protoss_common_unit(state) + and ( + (adv_tactics and logic.protoss_basic_anti_air(state)) + or logic.protoss_anti_light_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_P.mission_name, + "First Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1601, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_P.mission_name, + "Second Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1602, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_P.mission_name, + "Third Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1603, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and ( + (adv_tactics and logic.protoss_basic_anti_air(state)) + or logic.protoss_anti_light_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_P.mission_name, + "Fourth Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1604, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and ( + (adv_tactics and logic.protoss_basic_anti_air(state)) + or logic.protoss_anti_light_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_P.mission_name, + "First Forcefield Area Busted", + SC2_RACESWAP_LOC_ID_OFFSET + 1605, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and ( + (adv_tactics and logic.protoss_basic_anti_air(state)) + or logic.protoss_anti_light_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_P.mission_name, + "Second Forcefield Area Busted", + SC2_RACESWAP_LOC_ID_OFFSET + 1606, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and ( + (adv_tactics and logic.protoss_basic_anti_air(state)) + or logic.protoss_anti_light_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.SMASH_AND_GRAB_P.mission_name, + "Defeat Kerrigan", + SC2_RACESWAP_LOC_ID_OFFSET + 1607, + LocationType.MASTERY, + logic.protoss_deathball, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 1700, + LocationType.VICTORY, + lambda state: ( + ( + logic.zerg_competent_anti_air(state) + or adv_tactics + and logic.zerg_moderate_anti_air(state) + ) + and logic.zerg_defense_rating(state, False, True) >= 8 + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Left Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1701, + LocationType.VANILLA, + lambda state: ( + logic.zerg_defense_rating(state, False, False) >= 6 + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Right Ground Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1702, + LocationType.VANILLA, + lambda state: ( + logic.zerg_defense_rating(state, False, False) >= 6 + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Right Cliff Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1703, + LocationType.VANILLA, + lambda state: ( + logic.zerg_defense_rating(state, False, False) >= 6 + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Moebius Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1704, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Door Outer Layer", + SC2_RACESWAP_LOC_ID_OFFSET + 1705, + LocationType.EXTRA, + lambda state: ( + logic.zerg_defense_rating(state, False, False) >= 6 + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Door Thermal Barrier", + SC2_RACESWAP_LOC_ID_OFFSET + 1706, + LocationType.EXTRA, + lambda state: ( + ( + logic.zerg_competent_anti_air(state) + or adv_tactics + and logic.zerg_moderate_anti_air(state) + ) + and logic.zerg_defense_rating(state, False, True) >= 8 + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Cutting Through the Core", + SC2_RACESWAP_LOC_ID_OFFSET + 1707, + LocationType.EXTRA, + lambda state: ( + ( + logic.zerg_competent_anti_air(state) + or adv_tactics + and logic.zerg_moderate_anti_air(state) + ) + and logic.zerg_defense_rating(state, False, True) >= 8 + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Structure Access Imminent", + SC2_RACESWAP_LOC_ID_OFFSET + 1708, + LocationType.EXTRA, + lambda state: ( + ( + logic.zerg_competent_anti_air(state) + or adv_tactics + and logic.zerg_moderate_anti_air(state) + ) + and logic.zerg_defense_rating(state, False, True) >= 8 + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Northwestern Protoss Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1709, + LocationType.MASTERY, + lambda state: ( + logic.zerg_competent_anti_air(state) + and logic.zerg_defense_rating(state, False, True) >= 8 + and logic.zerg_common_unit(state) + and logic.zerg_base_buster(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Northeastern Protoss Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1710, + LocationType.MASTERY, + lambda state: ( + logic.zerg_competent_anti_air(state) + and logic.zerg_defense_rating(state, False, True) >= 8 + and logic.zerg_common_unit(state) + and logic.zerg_base_buster(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_DIG_Z.mission_name, + "Eastern Protoss Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1711, + LocationType.MASTERY, + lambda state: ( + logic.zerg_competent_anti_air(state) + and logic.zerg_defense_rating(state, False, True) >= 8 + and logic.zerg_common_unit(state) + and logic.zerg_base_buster(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 1800, + LocationType.VICTORY, + lambda state: ( + ( + logic.protoss_anti_armor_anti_air(state) + or adv_tactics + and logic.protoss_moderate_anti_air(state) + ) + and logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Left Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1801, + LocationType.VANILLA, + lambda state: ( + logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Right Ground Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1802, + LocationType.VANILLA, + lambda state: ( + logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Right Cliff Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 1803, + LocationType.VANILLA, + lambda state: ( + logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Moebius Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1804, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Door Outer Layer", + SC2_RACESWAP_LOC_ID_OFFSET + 1805, + LocationType.EXTRA, + lambda state: ( + logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Door Thermal Barrier", + SC2_RACESWAP_LOC_ID_OFFSET + 1806, + LocationType.EXTRA, + lambda state: ( + ( + logic.protoss_anti_armor_anti_air(state) + or adv_tactics + and logic.protoss_moderate_anti_air(state) + ) + and logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Cutting Through the Core", + SC2_RACESWAP_LOC_ID_OFFSET + 1807, + LocationType.EXTRA, + lambda state: ( + ( + logic.protoss_anti_armor_anti_air(state) + or adv_tactics + and logic.protoss_moderate_anti_air(state) + ) + and logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Structure Access Imminent", + SC2_RACESWAP_LOC_ID_OFFSET + 1808, + LocationType.EXTRA, + lambda state: ( + ( + logic.protoss_anti_armor_anti_air(state) + or adv_tactics + and logic.protoss_moderate_anti_air(state) + ) + and logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Northwestern Protoss Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1809, + LocationType.MASTERY, + lambda state: ( + logic.protoss_anti_armor_anti_air + and logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + and logic.protoss_deathball(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Northeastern Protoss Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1810, + LocationType.MASTERY, + lambda state: ( + logic.protoss_anti_armor_anti_air(state) + and logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + and logic.protoss_deathball(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_DIG_P.mission_name, + "Eastern Protoss Base", + SC2_RACESWAP_LOC_ID_OFFSET + 1811, + LocationType.MASTERY, + lambda state: ( + logic.protoss_anti_armor_anti_air(state) + and logic.protoss_defense_rating(state, False) >= 6 + and logic.protoss_common_unit(state) + and logic.protoss_deathball(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 1900, + LocationType.VICTORY, + lambda state: ( + logic.zerg_moderate_anti_air(state) + and ( + logic.zerg_versatile_air(state) + or state.has_any( + { + item_names.YGGDRASIL, + item_names.OVERLORD_VENTRAL_SACS, + item_names.NYDUS_WORM, + item_names.BULLFROG, + }, + player, + ) + and logic.zerg_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_Z.mission_name, + "1st Data Core", + SC2_RACESWAP_LOC_ID_OFFSET + 1901, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_Z.mission_name, + "2nd Data Core", + SC2_RACESWAP_LOC_ID_OFFSET + 1902, + LocationType.VANILLA, + lambda state: ( + logic.zerg_versatile_air(state) + or state.has_any( + { + item_names.YGGDRASIL, + item_names.OVERLORD_VENTRAL_SACS, + item_names.NYDUS_WORM, + item_names.BULLFROG, + }, + player, + ) + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_Z.mission_name, + "South Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 1903, + LocationType.EXTRA, + lambda state: state.has_any( + { + item_names.YGGDRASIL, + item_names.OVERLORD_VENTRAL_SACS, + item_names.NYDUS_WORM, + item_names.BULLFROG, + }, + player, + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_Z.mission_name, + "Wall Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 1904, + LocationType.EXTRA, + lambda state: state.has_any( + { + item_names.YGGDRASIL, + item_names.OVERLORD_VENTRAL_SACS, + item_names.NYDUS_WORM, + item_names.BULLFROG, + }, + player, + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_Z.mission_name, + "Mid Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 1905, + LocationType.EXTRA, + lambda state: state.has_any( + { + item_names.YGGDRASIL, + item_names.OVERLORD_VENTRAL_SACS, + item_names.NYDUS_WORM, + item_names.BULLFROG, + }, + player, + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_Z.mission_name, + "Nydus Roof Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 1906, + LocationType.EXTRA, + lambda state: state.has_any( + { + item_names.YGGDRASIL, + item_names.OVERLORD_VENTRAL_SACS, + item_names.NYDUS_WORM, + item_names.BULLFROG, + }, + player, + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_Z.mission_name, + "Alive Inside Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 1907, + LocationType.EXTRA, + lambda state: state.has_any( + { + item_names.YGGDRASIL, + item_names.OVERLORD_VENTRAL_SACS, + item_names.NYDUS_WORM, + item_names.BULLFROG, + }, + player, + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_Z.mission_name, + "Brutalisk", + SC2_RACESWAP_LOC_ID_OFFSET + 1908, + LocationType.VANILLA, + lambda state: ( + logic.zerg_moderate_anti_air(state) + and ( + logic.zerg_versatile_air(state) + or state.has_any( + { + item_names.YGGDRASIL, + item_names.OVERLORD_VENTRAL_SACS, + item_names.NYDUS_WORM, + item_names.BULLFROG, + }, + player, + ) + and logic.zerg_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_Z.mission_name, + "3rd Data Core", + SC2_RACESWAP_LOC_ID_OFFSET + 1909, + LocationType.VANILLA, + lambda state: ( + logic.zerg_moderate_anti_air(state) + and ( + logic.zerg_versatile_air(state) + or state.has_any( + { + item_names.YGGDRASIL, + item_names.OVERLORD_VENTRAL_SACS, + item_names.NYDUS_WORM, + item_names.BULLFROG, + }, + player, + ) + and logic.zerg_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 2000, + LocationType.VICTORY, + lambda state: ( + logic.protoss_moderate_anti_air(state) + and ( + logic.protoss_fleet(state) + or state.has(item_names.WARP_PRISM, player) + and logic.protoss_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_P.mission_name, + "1st Data Core", + SC2_RACESWAP_LOC_ID_OFFSET + 2001, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_P.mission_name, + "2nd Data Core", + SC2_RACESWAP_LOC_ID_OFFSET + 2002, + LocationType.VANILLA, + lambda state: ( + logic.protoss_fleet(state) + or ( + state.has(item_names.WARP_PRISM, player) + and logic.protoss_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_P.mission_name, + "South Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 2003, + LocationType.EXTRA, + lambda state: adv_tactics or state.has(item_names.WARP_PRISM, player), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_P.mission_name, + "Wall Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 2004, + LocationType.EXTRA, + lambda state: adv_tactics or state.has(item_names.WARP_PRISM, player), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_P.mission_name, + "Mid Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 2005, + LocationType.EXTRA, + lambda state: adv_tactics or state.has(item_names.WARP_PRISM, player), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_P.mission_name, + "Nydus Roof Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 2006, + LocationType.EXTRA, + lambda state: adv_tactics or state.has(item_names.WARP_PRISM, player), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_P.mission_name, + "Alive Inside Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 2007, + LocationType.EXTRA, + lambda state: adv_tactics or state.has(item_names.WARP_PRISM, player), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_P.mission_name, + "Brutalisk", + SC2_RACESWAP_LOC_ID_OFFSET + 2008, + LocationType.VANILLA, + lambda state: ( + logic.protoss_moderate_anti_air(state) + and ( + logic.protoss_fleet(state) + or state.has(item_names.WARP_PRISM, player) + and logic.protoss_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.THE_MOEBIUS_FACTOR_P.mission_name, + "3rd Data Core", + SC2_RACESWAP_LOC_ID_OFFSET + 2009, + LocationType.VANILLA, + lambda state: ( + logic.protoss_moderate_anti_air(state) + and ( + logic.protoss_fleet(state) + or state.has(item_names.WARP_PRISM, player) + and logic.protoss_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.SUPERNOVA_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 2100, + LocationType.VICTORY, + logic.zerg_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA_Z.mission_name, + "West Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2101, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.SUPERNOVA_Z.mission_name, + "North Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2102, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.SUPERNOVA_Z.mission_name, + "South Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2103, + LocationType.VANILLA, + logic.zerg_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA_Z.mission_name, + "East Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2104, + LocationType.VANILLA, + logic.zerg_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA_Z.mission_name, + "Landing Zone Cleared", + SC2_RACESWAP_LOC_ID_OFFSET + 2105, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.SUPERNOVA_Z.mission_name, + "Middle Base", + SC2_RACESWAP_LOC_ID_OFFSET + 2106, + LocationType.EXTRA, + logic.zerg_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA_Z.mission_name, + "Southeast Base", + SC2_RACESWAP_LOC_ID_OFFSET + 2107, + LocationType.EXTRA, + logic.zerg_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 2200, + LocationType.VICTORY, + logic.protoss_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA_P.mission_name, + "West Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2201, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.SUPERNOVA_P.mission_name, + "North Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2202, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.SUPERNOVA_P.mission_name, + "South Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2203, + LocationType.VANILLA, + logic.protoss_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA_P.mission_name, + "East Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2204, + LocationType.VANILLA, + logic.protoss_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA_P.mission_name, + "Landing Zone Cleared", + SC2_RACESWAP_LOC_ID_OFFSET + 2205, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.SUPERNOVA_P.mission_name, + "Middle Base", + SC2_RACESWAP_LOC_ID_OFFSET + 2206, + LocationType.EXTRA, + logic.protoss_supernova_requirement, + ), + make_location_data( + SC2Mission.SUPERNOVA_P.mission_name, + "Southeast Base", + SC2_RACESWAP_LOC_ID_OFFSET + 2207, + LocationType.EXTRA, + logic.protoss_supernova_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 2300, + LocationType.VICTORY, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "Landing Zone Cleared", + SC2_RACESWAP_LOC_ID_OFFSET + 2301, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "Expansion Prisoners", + SC2_RACESWAP_LOC_ID_OFFSET + 2302, + LocationType.VANILLA, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "South Close Prisoners", + SC2_RACESWAP_LOC_ID_OFFSET + 2303, + LocationType.VANILLA, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "South Far Prisoners", + SC2_RACESWAP_LOC_ID_OFFSET + 2304, + LocationType.VANILLA, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "North Prisoners", + SC2_RACESWAP_LOC_ID_OFFSET + 2305, + LocationType.VANILLA, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "Mothership", + SC2_RACESWAP_LOC_ID_OFFSET + 2306, + LocationType.EXTRA, + logic.zerg_maw_requirement, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "Expansion Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2307, + LocationType.EXTRA, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "Middle Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2308, + LocationType.EXTRA, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "Southeast Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2309, + LocationType.EXTRA, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "Stargate Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2310, + LocationType.EXTRA, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "Northwest Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2311, + LocationType.CHALLENGE, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "West Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2312, + LocationType.CHALLENGE, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_Z.mission_name, + "Southwest Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2313, + LocationType.CHALLENGE, + logic.zerg_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 2400, + LocationType.VICTORY, + logic.protoss_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "Landing Zone Cleared", + SC2_RACESWAP_LOC_ID_OFFSET + 2401, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "Expansion Prisoners", + SC2_RACESWAP_LOC_ID_OFFSET + 2402, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_maw_requirement(state), + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "South Close Prisoners", + SC2_RACESWAP_LOC_ID_OFFSET + 2403, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_maw_requirement(state), + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "South Far Prisoners", + SC2_RACESWAP_LOC_ID_OFFSET + 2404, + LocationType.VANILLA, + logic.protoss_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "North Prisoners", + SC2_RACESWAP_LOC_ID_OFFSET + 2405, + LocationType.VANILLA, + logic.protoss_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "Mothership", + SC2_RACESWAP_LOC_ID_OFFSET + 2406, + LocationType.EXTRA, + logic.protoss_maw_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "Expansion Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2407, + LocationType.EXTRA, + lambda state: adv_tactics or logic.protoss_maw_requirement(state), + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "Middle Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2408, + LocationType.EXTRA, + logic.protoss_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "Southeast Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2409, + LocationType.EXTRA, + logic.protoss_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "Stargate Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2410, + LocationType.EXTRA, + logic.protoss_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "Northwest Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2411, + LocationType.CHALLENGE, + logic.protoss_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "West Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2412, + LocationType.CHALLENGE, + logic.protoss_maw_requirement, + ), + make_location_data( + SC2Mission.MAW_OF_THE_VOID_P.mission_name, + "Southwest Rip Field Generator", + SC2_RACESWAP_LOC_ID_OFFSET + 2413, + LocationType.CHALLENGE, + logic.protoss_maw_requirement, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 2500, + LocationType.VICTORY, + lambda state: ( + logic.zerg_moderate_anti_air(state) + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_Z.mission_name, + "Tosh's Miners", + SC2_RACESWAP_LOC_ID_OFFSET + 2501, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_Z.mission_name, + "Brutalisk", + SC2_RACESWAP_LOC_ID_OFFSET + 2502, + LocationType.VANILLA, + lambda state: logic.zerg_common_unit(state), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_Z.mission_name, + "North Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 2503, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_Z.mission_name, + "Middle Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 2504, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_Z.mission_name, + "Southwest Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 2505, + LocationType.EXTRA, + lambda state: logic.zerg_common_unit(state), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_Z.mission_name, + "Southeast Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 2506, + LocationType.EXTRA, + lambda state: ( + logic.zerg_moderate_anti_air(state) + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_Z.mission_name, + "East Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 2507, + LocationType.EXTRA, + lambda state: ( + logic.zerg_moderate_anti_air(state) + and logic.zerg_common_unit(state) + ), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_Z.mission_name, + "Zerg Cleared", + SC2_RACESWAP_LOC_ID_OFFSET + 2508, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_competent_anti_air(state) + and logic.zerg_common_unit(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 2600, + LocationType.VICTORY, + lambda state: ( + adv_tactics + or logic.protoss_basic_anti_air(state) + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_P.mission_name, + "Tosh's Miners", + SC2_RACESWAP_LOC_ID_OFFSET + 2601, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_P.mission_name, + "Brutalisk", + SC2_RACESWAP_LOC_ID_OFFSET + 2602, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_P.mission_name, + "North Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 2603, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_P.mission_name, + "Middle Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 2604, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_P.mission_name, + "Southwest Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 2605, + LocationType.EXTRA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_P.mission_name, + "Southeast Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 2606, + LocationType.EXTRA, + lambda state: ( + adv_tactics + or logic.protoss_basic_anti_air(state) + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_P.mission_name, + "East Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 2607, + LocationType.EXTRA, + lambda state: ( + adv_tactics + or logic.protoss_basic_anti_air(state) + and logic.protoss_common_unit(state) + ), + ), + make_location_data( + SC2Mission.DEVILS_PLAYGROUND_P.mission_name, + "Zerg Cleared", + SC2_RACESWAP_LOC_ID_OFFSET + 2608, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_competent_anti_air(state) + and (logic.protoss_common_unit(state)) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 2700, + LocationType.VICTORY, + logic.zerg_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "Close Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2701, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "West Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2702, + LocationType.VANILLA, + logic.zerg_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "North-East Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2703, + LocationType.VANILLA, + logic.zerg_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "Middle Base", + SC2_RACESWAP_LOC_ID_OFFSET + 2704, + LocationType.EXTRA, + logic.zerg_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "Protoss Cleared", + SC2_RACESWAP_LOC_ID_OFFSET + 2705, + LocationType.MASTERY, + lambda state: ( + logic.zerg_welcome_to_the_jungle_requirement(state) + and logic.zerg_competent_anti_air(state) + and logic.zerg_base_buster(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "No Terrazine Nodes Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2706, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_welcome_to_the_jungle_requirement(state) + and logic.zerg_competent_anti_air(state) + and logic.zerg_big_monsters(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "Up to 1 Terrazine Node Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2707, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_welcome_to_the_jungle_requirement(state) + and logic.zerg_competent_anti_air(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "Up to 2 Terrazine Nodes Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2708, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_welcome_to_the_jungle_requirement(state) + and logic.zerg_competent_anti_air(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "Up to 3 Terrazine Nodes Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2709, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_welcome_to_the_jungle_requirement(state) + and logic.zerg_competent_anti_air(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "Up to 4 Terrazine Nodes Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2710, + LocationType.EXTRA, + logic.zerg_welcome_to_the_jungle_requirement, + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_Z.mission_name, + "Up to 5 Terrazine Nodes Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2711, + LocationType.EXTRA, + logic.zerg_welcome_to_the_jungle_requirement, + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 2800, + LocationType.VICTORY, + logic.protoss_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "Close Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2801, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "West Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2802, + LocationType.VANILLA, + logic.protoss_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "North-East Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 2803, + LocationType.VANILLA, + logic.protoss_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "Middle Base", + SC2_RACESWAP_LOC_ID_OFFSET + 2804, + LocationType.EXTRA, + logic.protoss_welcome_to_the_jungle_requirement, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "Protoss Cleared", + SC2_RACESWAP_LOC_ID_OFFSET + 2805, + LocationType.MASTERY, + lambda state: ( + logic.protoss_welcome_to_the_jungle_requirement(state) + and logic.protoss_competent_comp(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "No Terrazine Nodes Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2806, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_welcome_to_the_jungle_requirement(state) + and logic.protoss_competent_comp(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "Up to 1 Terrazine Node Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2807, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_welcome_to_the_jungle_requirement(state) + and logic.protoss_competent_comp(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "Up to 2 Terrazine Nodes Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2808, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_welcome_to_the_jungle_requirement(state) + and logic.protoss_basic_splash(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "Up to 3 Terrazine Nodes Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2809, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_welcome_to_the_jungle_requirement(state) + and logic.protoss_basic_splash(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "Up to 4 Terrazine Nodes Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2810, + LocationType.EXTRA, + logic.protoss_welcome_to_the_jungle_requirement, + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.WELCOME_TO_THE_JUNGLE_P.mission_name, + "Up to 5 Terrazine Nodes Sealed", + SC2_RACESWAP_LOC_ID_OFFSET + 2811, + LocationType.EXTRA, + logic.protoss_welcome_to_the_jungle_requirement, + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 3300, + LocationType.VICTORY, + lambda state: ( + logic.zerg_great_train_robbery_train_stopper(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "North Defiler", + SC2_RACESWAP_LOC_ID_OFFSET + 3301, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "Mid Defiler", + SC2_RACESWAP_LOC_ID_OFFSET + 3302, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "South Defiler", + SC2_RACESWAP_LOC_ID_OFFSET + 3303, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "Close Infested Diamondback", + SC2_RACESWAP_LOC_ID_OFFSET + 3304, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "Northwest Infested Diamondback", + SC2_RACESWAP_LOC_ID_OFFSET + 3305, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "North Infested Diamondback", + SC2_RACESWAP_LOC_ID_OFFSET + 3306, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "Northeast Infested Diamondback", + SC2_RACESWAP_LOC_ID_OFFSET + 3307, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "Southwest Infested Diamondback", + SC2_RACESWAP_LOC_ID_OFFSET + 3308, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "Southeast Infested Diamondback", + SC2_RACESWAP_LOC_ID_OFFSET + 3309, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "Kill Team", + SC2_RACESWAP_LOC_ID_OFFSET + 3310, + LocationType.CHALLENGE, + lambda state: ( + (adv_tactics or logic.zerg_common_unit(state)) + and logic.zerg_great_train_robbery_train_stopper(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "Flawless", + SC2_RACESWAP_LOC_ID_OFFSET + 3311, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_great_train_robbery_train_stopper(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "2 Trains Destroyed", + SC2_RACESWAP_LOC_ID_OFFSET + 3312, + LocationType.EXTRA, + logic.zerg_great_train_robbery_train_stopper, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "4 Trains Destroyed", + SC2_RACESWAP_LOC_ID_OFFSET + 3313, + LocationType.EXTRA, + lambda state: ( + logic.zerg_great_train_robbery_train_stopper(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z.mission_name, + "6 Trains Destroyed", + SC2_RACESWAP_LOC_ID_OFFSET + 3314, + LocationType.EXTRA, + lambda state: ( + logic.zerg_great_train_robbery_train_stopper(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 3400, + LocationType.VICTORY, + lambda state: ( + logic.protoss_great_train_robbery_train_stopper(state) + and logic.protoss_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "North Defiler", + SC2_RACESWAP_LOC_ID_OFFSET + 3401, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "Mid Defiler", + SC2_RACESWAP_LOC_ID_OFFSET + 3402, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "South Defiler", + SC2_RACESWAP_LOC_ID_OFFSET + 3403, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "Close Immortal", + SC2_RACESWAP_LOC_ID_OFFSET + 3404, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "Northwest Immortal", + SC2_RACESWAP_LOC_ID_OFFSET + 3405, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "North Instigator", + SC2_RACESWAP_LOC_ID_OFFSET + 3406, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "Northeast Instigator", + SC2_RACESWAP_LOC_ID_OFFSET + 3407, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "Southwest Instigator", + SC2_RACESWAP_LOC_ID_OFFSET + 3408, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "Southeast Immortal", + SC2_RACESWAP_LOC_ID_OFFSET + 3409, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "Kill Team", + SC2_RACESWAP_LOC_ID_OFFSET + 3410, + LocationType.CHALLENGE, + lambda state: ( + (adv_tactics or logic.protoss_common_unit(state)) + and logic.protoss_great_train_robbery_train_stopper(state) + and logic.protoss_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "Flawless", + SC2_RACESWAP_LOC_ID_OFFSET + 3411, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_great_train_robbery_train_stopper(state) + and logic.protoss_basic_anti_air(state) + ), + flags=LocationFlag.PREVENTATIVE, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "2 Trains Destroyed", + SC2_RACESWAP_LOC_ID_OFFSET + 3412, + LocationType.EXTRA, + logic.protoss_great_train_robbery_train_stopper, + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "4 Trains Destroyed", + SC2_RACESWAP_LOC_ID_OFFSET + 3413, + LocationType.EXTRA, + lambda state: ( + logic.protoss_great_train_robbery_train_stopper(state) + and logic.protoss_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GREAT_TRAIN_ROBBERY_P.mission_name, + "6 Trains Destroyed", + SC2_RACESWAP_LOC_ID_OFFSET + 3414, + LocationType.EXTRA, + lambda state: ( + logic.protoss_great_train_robbery_train_stopper(state) + and logic.protoss_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.CUTTHROAT_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 3500, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit(state) + and (adv_tactics or logic.zerg_moderate_anti_air(state)) + ), + ), + make_location_data( + SC2Mission.CUTTHROAT_Z.mission_name, + "Mira Han", + SC2_RACESWAP_LOC_ID_OFFSET + 3501, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_Z.mission_name, + "North Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 3502, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_Z.mission_name, + "Mid Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 3503, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.CUTTHROAT_Z.mission_name, + "Southwest Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 3504, + LocationType.VANILLA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_Z.mission_name, + "North Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 3505, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_Z.mission_name, + "South Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 3506, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_Z.mission_name, + "West Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 3507, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 3600, + LocationType.VICTORY, + lambda state: ( + logic.protoss_common_unit(state) + and (adv_tactics or logic.protoss_basic_anti_air(state)) + ), + ), + make_location_data( + SC2Mission.CUTTHROAT_P.mission_name, + "Mira Han", + SC2_RACESWAP_LOC_ID_OFFSET + 3601, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_P.mission_name, + "North Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 3602, + LocationType.VANILLA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_P.mission_name, + "Mid Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 3603, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.CUTTHROAT_P.mission_name, + "Southwest Relic", + SC2_RACESWAP_LOC_ID_OFFSET + 3604, + LocationType.VANILLA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_P.mission_name, + "North Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 3605, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_P.mission_name, + "South Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 3606, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.CUTTHROAT_P.mission_name, + "West Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 3607, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 3700, + LocationType.VICTORY, + logic.zerg_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name, + "Odin", + SC2_RACESWAP_LOC_ID_OFFSET + 3701, + LocationType.EXTRA, + logic.zergling_hydra_roach_start, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name, + "Loki", + SC2_RACESWAP_LOC_ID_OFFSET + 3702, + LocationType.CHALLENGE, + logic.zerg_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name, + "Lab Devourer", + SC2_RACESWAP_LOC_ID_OFFSET + 3703, + LocationType.VANILLA, + logic.zergling_hydra_roach_start, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name, + "North Devourer", + SC2_RACESWAP_LOC_ID_OFFSET + 3704, + LocationType.VANILLA, + logic.zerg_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name, + "Southeast Devourer", + SC2_RACESWAP_LOC_ID_OFFSET + 3705, + LocationType.VANILLA, + logic.zerg_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name, + "West Base", + SC2_RACESWAP_LOC_ID_OFFSET + 3706, + LocationType.EXTRA, + logic.zerg_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name, + "Northwest Base", + SC2_RACESWAP_LOC_ID_OFFSET + 3707, + LocationType.EXTRA, + logic.zerg_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name, + "Northeast Base", + SC2_RACESWAP_LOC_ID_OFFSET + 3708, + LocationType.EXTRA, + logic.zerg_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name, + "Southeast Base", + SC2_RACESWAP_LOC_ID_OFFSET + 3709, + LocationType.EXTRA, + logic.zerg_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 3800, + LocationType.VICTORY, + logic.protoss_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name, + "Odin", + SC2_RACESWAP_LOC_ID_OFFSET + 3801, + LocationType.EXTRA, + logic.zealot_sentry_slayer_start, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name, + "Loki", + SC2_RACESWAP_LOC_ID_OFFSET + 3802, + LocationType.CHALLENGE, + logic.protoss_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name, + "Lab Devourer", + SC2_RACESWAP_LOC_ID_OFFSET + 3803, + LocationType.VANILLA, + logic.zealot_sentry_slayer_start, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name, + "North Devourer", + SC2_RACESWAP_LOC_ID_OFFSET + 3804, + LocationType.VANILLA, + logic.protoss_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name, + "Southeast Devourer", + SC2_RACESWAP_LOC_ID_OFFSET + 3805, + LocationType.VANILLA, + logic.protoss_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name, + "West Base", + SC2_RACESWAP_LOC_ID_OFFSET + 3806, + LocationType.EXTRA, + logic.protoss_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name, + "Northwest Base", + SC2_RACESWAP_LOC_ID_OFFSET + 3807, + LocationType.EXTRA, + logic.protoss_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name, + "Northeast Base", + SC2_RACESWAP_LOC_ID_OFFSET + 3808, + LocationType.EXTRA, + logic.protoss_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name, + "Southeast Base", + SC2_RACESWAP_LOC_ID_OFFSET + 3809, + LocationType.EXTRA, + logic.protoss_engine_of_destruction_requirement, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 3900, + LocationType.VICTORY, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_Z.mission_name, + "Tower 1", + SC2_RACESWAP_LOC_ID_OFFSET + 3901, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_Z.mission_name, + "Tower 2", + SC2_RACESWAP_LOC_ID_OFFSET + 3902, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_Z.mission_name, + "Tower 3", + SC2_RACESWAP_LOC_ID_OFFSET + 3903, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_Z.mission_name, + "Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 3904, + LocationType.VANILLA, + lambda state: ( + logic.advanced_tactics or logic.zerg_competent_comp_competent_aa(state) + ), + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_Z.mission_name, + "All Barracks", + SC2_RACESWAP_LOC_ID_OFFSET + 3905, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_Z.mission_name, + "All Factories", + SC2_RACESWAP_LOC_ID_OFFSET + 3906, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_Z.mission_name, + "All Starports", + SC2_RACESWAP_LOC_ID_OFFSET + 3907, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_Z.mission_name, + "Odin Not Trashed", + SC2_RACESWAP_LOC_ID_OFFSET + 3908, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_competent_comp_competent_aa(state) + and logic.zerg_repair_odin(state) + ), + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_Z.mission_name, + "Surprise Attack Ends", + SC2_RACESWAP_LOC_ID_OFFSET + 3909, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 4000, + LocationType.VICTORY, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_P.mission_name, + "Tower 1", + SC2_RACESWAP_LOC_ID_OFFSET + 4001, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_P.mission_name, + "Tower 2", + SC2_RACESWAP_LOC_ID_OFFSET + 4002, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_P.mission_name, + "Tower 3", + SC2_RACESWAP_LOC_ID_OFFSET + 4003, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_P.mission_name, + "Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 4004, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_competent_comp(state), + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_P.mission_name, + "All Barracks", + SC2_RACESWAP_LOC_ID_OFFSET + 4005, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_P.mission_name, + "All Factories", + SC2_RACESWAP_LOC_ID_OFFSET + 4006, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_P.mission_name, + "All Starports", + SC2_RACESWAP_LOC_ID_OFFSET + 4007, + LocationType.EXTRA, + lambda state: adv_tactics or logic.protoss_competent_comp(state), + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_P.mission_name, + "Odin Not Trashed", + SC2_RACESWAP_LOC_ID_OFFSET + 4008, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_competent_comp(state) and logic.protoss_repair_odin(state) + ), + ), + make_location_data( + SC2Mission.MEDIA_BLITZ_P.mission_name, + "Surprise Attack Ends", + SC2_RACESWAP_LOC_ID_OFFSET + 4009, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 4500, + LocationType.VICTORY, + lambda state: ( + logic.terran_competent_comp(state) + and logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_T.mission_name, + "Factory", + SC2_RACESWAP_LOC_ID_OFFSET + 4501, + LocationType.VANILLA, + lambda state: adv_tactics or logic.terran_common_unit(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_T.mission_name, + "Armory", + SC2_RACESWAP_LOC_ID_OFFSET + 4502, + LocationType.VANILLA, + lambda state: adv_tactics or logic.terran_common_unit(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_T.mission_name, + "Shadow Ops", + SC2_RACESWAP_LOC_ID_OFFSET + 4503, + LocationType.VANILLA, + lambda state: logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_T.mission_name, + "Northeast Base", + SC2_RACESWAP_LOC_ID_OFFSET + 4504, + LocationType.EXTRA, + lambda state: logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_T.mission_name, + "Southwest Base", + SC2_RACESWAP_LOC_ID_OFFSET + 4505, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_competent_comp(state) + and logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_T.mission_name, + "Maar", + SC2_RACESWAP_LOC_ID_OFFSET + 4506, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_T.mission_name, + "Northwest Preserver", + SC2_RACESWAP_LOC_ID_OFFSET + 4507, + LocationType.EXTRA, + lambda state: ( + logic.terran_competent_comp(state) + and logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_T.mission_name, + "Southwest Preserver", + SC2_RACESWAP_LOC_ID_OFFSET + 4508, + LocationType.EXTRA, + lambda state: ( + logic.terran_competent_comp(state) + and logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_T.mission_name, + "East Preserver", + SC2_RACESWAP_LOC_ID_OFFSET + 4509, + LocationType.EXTRA, + lambda state: ( + logic.terran_competent_comp(state) + and logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 4600, + LocationType.VICTORY, + lambda state: logic.zerg_competent_comp(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_Z.mission_name, + "Ultralisk Cavern", + SC2_RACESWAP_LOC_ID_OFFSET + 4601, + LocationType.VANILLA, + lambda state: (adv_tactics or logic.zerg_common_unit(state)) + and logic.spread_creep(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_Z.mission_name, + "Hydralisk Den", + SC2_RACESWAP_LOC_ID_OFFSET + 4602, + LocationType.VANILLA, + lambda state: (adv_tactics or logic.zerg_common_unit(state)) + and logic.spread_creep(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_Z.mission_name, + "Infestation Pit", + SC2_RACESWAP_LOC_ID_OFFSET + 4603, + LocationType.VANILLA, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state) + and logic.spread_creep(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_Z.mission_name, + "Northeast Base", + SC2_RACESWAP_LOC_ID_OFFSET + 4604, + LocationType.EXTRA, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_Z.mission_name, + "Southwest Base", + SC2_RACESWAP_LOC_ID_OFFSET + 4605, + LocationType.CHALLENGE, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_Z.mission_name, + "Maar", + SC2_RACESWAP_LOC_ID_OFFSET + 4606, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_Z.mission_name, + "Northwest Preserver", + SC2_RACESWAP_LOC_ID_OFFSET + 4607, + LocationType.EXTRA, + lambda state: logic.zerg_competent_comp(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_Z.mission_name, + "Southwest Preserver", + SC2_RACESWAP_LOC_ID_OFFSET + 4608, + LocationType.EXTRA, + lambda state: logic.zerg_competent_comp(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.A_SINISTER_TURN_Z.mission_name, + "East Preserver", + SC2_RACESWAP_LOC_ID_OFFSET + 4609, + LocationType.EXTRA, + lambda state: logic.zerg_competent_comp(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 4700, + LocationType.VICTORY, + lambda state: logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_T.mission_name, + "Close Obelisk", + SC2_RACESWAP_LOC_ID_OFFSET + 4701, + LocationType.VANILLA, + lambda state: adv_tactics or logic.terran_common_unit(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_T.mission_name, + "West Obelisk", + SC2_RACESWAP_LOC_ID_OFFSET + 4702, + LocationType.VANILLA, + lambda state: adv_tactics + or (logic.terran_common_unit(state) and logic.terran_basic_anti_air(state)), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_T.mission_name, + "Base", + SC2_RACESWAP_LOC_ID_OFFSET + 4703, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_T.mission_name, + "Southwest Tendril", + SC2_RACESWAP_LOC_ID_OFFSET + 4704, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_T.mission_name, + "Southeast Tendril", + SC2_RACESWAP_LOC_ID_OFFSET + 4705, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_T.mission_name, + "Northeast Tendril", + SC2_RACESWAP_LOC_ID_OFFSET + 4706, + LocationType.EXTRA, + lambda state: logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_T.mission_name, + "Northwest Tendril", + SC2_RACESWAP_LOC_ID_OFFSET + 4707, + LocationType.EXTRA, + lambda state: logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 4800, + LocationType.VICTORY, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_Z.mission_name, + "Close Obelisk", + SC2_RACESWAP_LOC_ID_OFFSET + 4801, + LocationType.VANILLA, + lambda state: adv_tactics or logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_Z.mission_name, + "West Obelisk", + SC2_RACESWAP_LOC_ID_OFFSET + 4802, + LocationType.VANILLA, + lambda state: ( + adv_tactics + or ( + logic.zerg_common_unit(state) + and logic.zerg_basic_kerriganless_anti_air(state) + and logic.spread_creep(state) + ) + ), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_Z.mission_name, + "Base", + SC2_RACESWAP_LOC_ID_OFFSET + 4803, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_Z.mission_name, + "Southwest Tendril", + SC2_RACESWAP_LOC_ID_OFFSET + 4804, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_Z.mission_name, + "Southeast Tendril", + SC2_RACESWAP_LOC_ID_OFFSET + 4805, + LocationType.EXTRA, + logic.zerg_common_unit, + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_Z.mission_name, + "Northeast Tendril", + SC2_RACESWAP_LOC_ID_OFFSET + 4806, + LocationType.EXTRA, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.ECHOES_OF_THE_FUTURE_Z.mission_name, + "Northwest Tendril", + SC2_RACESWAP_LOC_ID_OFFSET + 4807, + LocationType.EXTRA, + lambda state: logic.zerg_common_unit(state) + and logic.zerg_competent_anti_air(state), + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_T.mission_name, + "Defeat", + SC2_RACESWAP_LOC_ID_OFFSET + 4900, + LocationType.VICTORY, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_T.mission_name, + "Protoss Archive", + SC2_RACESWAP_LOC_ID_OFFSET + 4901, + LocationType.VANILLA, + logic.terran_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_T.mission_name, + "Kills", + SC2_RACESWAP_LOC_ID_OFFSET + 4902, + LocationType.VANILLA, + logic.terran_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_T.mission_name, + "Urun", + SC2_RACESWAP_LOC_ID_OFFSET + 4903, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_T.mission_name, + "Mohandar", + SC2_RACESWAP_LOC_ID_OFFSET + 4904, + LocationType.EXTRA, + logic.terran_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_T.mission_name, + "Selendis", + SC2_RACESWAP_LOC_ID_OFFSET + 4905, + LocationType.EXTRA, + logic.terran_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_T.mission_name, + "Artanis", + SC2_RACESWAP_LOC_ID_OFFSET + 4906, + LocationType.EXTRA, + logic.terran_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_Z.mission_name, + "Defeat", + SC2_RACESWAP_LOC_ID_OFFSET + 5000, + LocationType.VICTORY, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_Z.mission_name, + "Protoss Archive", + SC2_RACESWAP_LOC_ID_OFFSET + 5001, + LocationType.VANILLA, + logic.zerg_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_Z.mission_name, + "Kills", + SC2_RACESWAP_LOC_ID_OFFSET + 5002, + LocationType.VANILLA, + logic.zerg_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_Z.mission_name, + "Urun", + SC2_RACESWAP_LOC_ID_OFFSET + 5003, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_Z.mission_name, + "Mohandar", + SC2_RACESWAP_LOC_ID_OFFSET + 5004, + LocationType.EXTRA, + logic.zerg_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_Z.mission_name, + "Selendis", + SC2_RACESWAP_LOC_ID_OFFSET + 5005, + LocationType.EXTRA, + logic.zerg_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.IN_UTTER_DARKNESS_Z.mission_name, + "Artanis", + SC2_RACESWAP_LOC_ID_OFFSET + 5006, + LocationType.EXTRA, + logic.zerg_in_utter_darkness_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 5100, + LocationType.VICTORY, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "Large Army", + SC2_RACESWAP_LOC_ID_OFFSET + 5101, + LocationType.VANILLA, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "2 Drop Pods", + SC2_RACESWAP_LOC_ID_OFFSET + 5102, + LocationType.VANILLA, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "4 Drop Pods", + SC2_RACESWAP_LOC_ID_OFFSET + 5103, + LocationType.VANILLA, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "6 Drop Pods", + SC2_RACESWAP_LOC_ID_OFFSET + 5104, + LocationType.EXTRA, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "8 Drop Pods", + SC2_RACESWAP_LOC_ID_OFFSET + 5105, + LocationType.CHALLENGE, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "Southwest Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5106, + LocationType.EXTRA, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "Northwest Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5107, + LocationType.EXTRA, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "Northeast Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5108, + LocationType.EXTRA, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "East Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5109, + LocationType.EXTRA, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "Southeast Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5110, + LocationType.EXTRA, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_Z.mission_name, + "Expansion Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5111, + LocationType.EXTRA, + logic.zerg_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 5200, + LocationType.VICTORY, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "Large Army", + SC2_RACESWAP_LOC_ID_OFFSET + 5201, + LocationType.VANILLA, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "2 Drop Pods", + SC2_RACESWAP_LOC_ID_OFFSET + 5202, + LocationType.VANILLA, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "4 Drop Pods", + SC2_RACESWAP_LOC_ID_OFFSET + 5203, + LocationType.VANILLA, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "6 Drop Pods", + SC2_RACESWAP_LOC_ID_OFFSET + 5204, + LocationType.EXTRA, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "8 Drop Pods", + SC2_RACESWAP_LOC_ID_OFFSET + 5205, + LocationType.CHALLENGE, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "Southwest Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5206, + LocationType.EXTRA, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "Northwest Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5207, + LocationType.EXTRA, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "Northeast Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5208, + LocationType.EXTRA, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "East Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5209, + LocationType.EXTRA, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "Southeast Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5210, + LocationType.EXTRA, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.GATES_OF_HELL_P.mission_name, + "Expansion Spore Cannon", + SC2_RACESWAP_LOC_ID_OFFSET + 5211, + LocationType.EXTRA, + logic.protoss_gates_of_hell_requirement, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 5500, + LocationType.VICTORY, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_Z.mission_name, + "Close Coolant Tower", + SC2_RACESWAP_LOC_ID_OFFSET + 5501, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_Z.mission_name, + "Northwest Coolant Tower", + SC2_RACESWAP_LOC_ID_OFFSET + 5502, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_Z.mission_name, + "Southeast Coolant Tower", + SC2_RACESWAP_LOC_ID_OFFSET + 5503, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_Z.mission_name, + "Southwest Coolant Tower", + SC2_RACESWAP_LOC_ID_OFFSET + 5504, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_Z.mission_name, + "Leviathan", + SC2_RACESWAP_LOC_ID_OFFSET + 5505, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_Z.mission_name, + "East Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 5506, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_Z.mission_name, + "North Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 5507, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_Z.mission_name, + "Mid Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 5508, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 5600, + LocationType.VICTORY, + lambda state: logic.protoss_competent_comp(state) + and logic.protoss_army_weapon_armor_upgrade_min_level(state) >= 2, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_P.mission_name, + "Close Coolant Tower", + SC2_RACESWAP_LOC_ID_OFFSET + 5601, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_P.mission_name, + "Northwest Coolant Tower", + SC2_RACESWAP_LOC_ID_OFFSET + 5602, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_P.mission_name, + "Southeast Coolant Tower", + SC2_RACESWAP_LOC_ID_OFFSET + 5603, + LocationType.VANILLA, + lambda state: logic.protoss_competent_comp(state) + and logic.protoss_army_weapon_armor_upgrade_min_level(state) >= 2, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_P.mission_name, + "Southwest Coolant Tower", + SC2_RACESWAP_LOC_ID_OFFSET + 5604, + LocationType.VANILLA, + lambda state: logic.protoss_competent_comp(state) + and logic.protoss_army_weapon_armor_upgrade_min_level(state) >= 2, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_P.mission_name, + "Leviathan", + SC2_RACESWAP_LOC_ID_OFFSET + 5605, + LocationType.VANILLA, + lambda state: logic.protoss_competent_comp(state) + and logic.protoss_army_weapon_armor_upgrade_min_level(state) >= 2, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_P.mission_name, + "East Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 5606, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_P.mission_name, + "North Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 5607, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.SHATTER_THE_SKY_P.mission_name, + "Mid Hatchery", + SC2_RACESWAP_LOC_ID_OFFSET + 5608, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.ALL_IN_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 5700, + LocationType.VICTORY, + logic.zerg_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_Z.mission_name, + "First Kerrigan Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 5701, + LocationType.EXTRA, + logic.zerg_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_Z.mission_name, + "Second Kerrigan Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 5702, + LocationType.EXTRA, + logic.zerg_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_Z.mission_name, + "Third Kerrigan Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 5703, + LocationType.EXTRA, + logic.zerg_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_Z.mission_name, + "Fourth Kerrigan Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 5704, + LocationType.EXTRA, + logic.zerg_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_Z.mission_name, + "Fifth Kerrigan Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 5705, + LocationType.EXTRA, + logic.zerg_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 5800, + LocationType.VICTORY, + logic.protoss_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_P.mission_name, + "First Kerrigan Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 5801, + LocationType.EXTRA, + logic.protoss_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_P.mission_name, + "Second Kerrigan Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 5802, + LocationType.EXTRA, + logic.protoss_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_P.mission_name, + "Third Kerrigan Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 5803, + LocationType.EXTRA, + logic.protoss_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_P.mission_name, + "Fourth Kerrigan Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 5804, + LocationType.EXTRA, + logic.protoss_all_in_requirement, + ), + make_location_data( + SC2Mission.ALL_IN_P.mission_name, + "Fifth Kerrigan Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 5805, + LocationType.EXTRA, + logic.protoss_all_in_requirement, + ), + make_location_data( + SC2Mission.LAB_RAT_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 5900, + LocationType.VICTORY, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.LAB_RAT_T.mission_name, + "Gather Minerals", + SC2_RACESWAP_LOC_ID_OFFSET + 5901, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.LAB_RAT_T.mission_name, + "South Marine Group", + SC2_RACESWAP_LOC_ID_OFFSET + 5902, + LocationType.VANILLA, + lambda state: adv_tactics or logic.terran_common_unit(state), + ), + make_location_data( + SC2Mission.LAB_RAT_T.mission_name, + "East Marine Group", + SC2_RACESWAP_LOC_ID_OFFSET + 5903, + LocationType.VANILLA, + lambda state: adv_tactics or logic.terran_common_unit(state), + ), + make_location_data( + SC2Mission.LAB_RAT_T.mission_name, + "West Marine Group", + SC2_RACESWAP_LOC_ID_OFFSET + 5904, + LocationType.VANILLA, + lambda state: adv_tactics or logic.terran_common_unit(state), + ), + make_location_data( + SC2Mission.LAB_RAT_T.mission_name, + "Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 5905, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.LAB_RAT_T.mission_name, + "Supply Depot", + SC2_RACESWAP_LOC_ID_OFFSET + 5906, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.LAB_RAT_T.mission_name, + "Gas Turrets", + SC2_RACESWAP_LOC_ID_OFFSET + 5907, + LocationType.EXTRA, + lambda state: adv_tactics or logic.terran_common_unit(state), + ), + make_location_data( + SC2Mission.LAB_RAT_T.mission_name, + "Win In Under 10 Minutes", + SC2_RACESWAP_LOC_ID_OFFSET + 5908, + LocationType.CHALLENGE, + lambda state: logic.terran_common_unit(state) + and logic.terran_early_tech(state), + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.LAB_RAT_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 6000, + LocationType.VICTORY, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.LAB_RAT_P.mission_name, + "Gather Minerals", + SC2_RACESWAP_LOC_ID_OFFSET + 6001, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.LAB_RAT_P.mission_name, + "South Zealot Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6002, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.LAB_RAT_P.mission_name, + "East Zealot Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6003, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.LAB_RAT_P.mission_name, + "West Zealot Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6004, + LocationType.VANILLA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.LAB_RAT_P.mission_name, + "Nexus", + SC2_RACESWAP_LOC_ID_OFFSET + 6005, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.LAB_RAT_P.mission_name, + "Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 6006, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.LAB_RAT_P.mission_name, + "Gas Turrets", + SC2_RACESWAP_LOC_ID_OFFSET + 6007, + LocationType.EXTRA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.LAB_RAT_P.mission_name, + "Win In Under 10 Minutes", + SC2_RACESWAP_LOC_ID_OFFSET + 6008, + LocationType.CHALLENGE, + logic.protoss_common_unit, + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.RENDEZVOUS_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 6300, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_basic_anti_air(state) + and logic.terran_defense_rating(state, False, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS_T.mission_name, + "Right Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6301, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_basic_anti_air(state) + and logic.terran_defense_rating(state, False, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS_T.mission_name, + "Center Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6302, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_basic_anti_air(state) + and logic.terran_defense_rating(state, False, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS_T.mission_name, + "Left Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6303, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_basic_anti_air(state) + and logic.terran_defense_rating(state, False, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS_T.mission_name, + "Hold Out Finished", + SC2_RACESWAP_LOC_ID_OFFSET + 6304, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_basic_anti_air(state) + and logic.terran_defense_rating(state, False, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS_T.mission_name, + "Kill All Buildings Before Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 6305, + LocationType.MASTERY, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_comp(state) + and logic.terran_defense_rating(state, False, False) >= 3 + and logic.terran_power_rating(state) >= 5 + ), + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.RENDEZVOUS_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 6400, + LocationType.VICTORY, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_basic_anti_air(state) + and logic.protoss_defense_rating(state, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS_P.mission_name, + "Right Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6401, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_basic_anti_air(state) + and logic.protoss_defense_rating(state, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS_P.mission_name, + "Center Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6402, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_basic_anti_air(state) + and logic.protoss_defense_rating(state, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS_P.mission_name, + "Left Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6403, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_basic_anti_air(state) + and logic.protoss_defense_rating(state, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS_P.mission_name, + "Hold Out Finished", + SC2_RACESWAP_LOC_ID_OFFSET + 6404, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_basic_anti_air(state) + and logic.protoss_defense_rating(state, False) >= 3 + ), + ), + make_location_data( + SC2Mission.RENDEZVOUS_P.mission_name, + "Kill All Buildings Before Reinforcements", + SC2_RACESWAP_LOC_ID_OFFSET + 6405, + LocationType.MASTERY, + lambda state: ( + logic.protoss_competent_comp(state) + and logic.protoss_defense_rating(state, False) >= 3 + and logic.protoss_power_rating(state) >= 5 + ), + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 6500, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_T.mission_name, + "First Ursadon Matriarch", + SC2_RACESWAP_LOC_ID_OFFSET + 6501, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_T.mission_name, + "North Ursadon Matriarch", + SC2_RACESWAP_LOC_ID_OFFSET + 6502, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_T.mission_name, + "West Ursadon Matriarch", + SC2_RACESWAP_LOC_ID_OFFSET + 6503, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_T.mission_name, + "Lost Base", + SC2_RACESWAP_LOC_ID_OFFSET + 6504, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_T.mission_name, + "Northeast Psi-link Spire", + SC2_RACESWAP_LOC_ID_OFFSET + 6505, + LocationType.EXTRA, + lambda state: logic.terran_common_unit(state) or adv_tactics, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_T.mission_name, + "Northwest Psi-link Spire", + SC2_RACESWAP_LOC_ID_OFFSET + 6506, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_T.mission_name, + "Southwest Psi-link Spire", + SC2_RACESWAP_LOC_ID_OFFSET + 6507, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_T.mission_name, + "Nafash", + SC2_RACESWAP_LOC_ID_OFFSET + 6508, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_T.mission_name, + "20 Unfrozen Structures", + SC2_RACESWAP_LOC_ID_OFFSET + 6509, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 6600, + LocationType.VICTORY, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_P.mission_name, + "First Ursadon Matriarch", + SC2_RACESWAP_LOC_ID_OFFSET + 6601, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_P.mission_name, + "North Ursadon Matriarch", + SC2_RACESWAP_LOC_ID_OFFSET + 6602, + LocationType.VANILLA, + logic.protoss_common_unit_basic_aa, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_P.mission_name, + "West Ursadon Matriarch", + SC2_RACESWAP_LOC_ID_OFFSET + 6603, + LocationType.VANILLA, + logic.protoss_common_unit_basic_aa, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_P.mission_name, + "Lost Base", + SC2_RACESWAP_LOC_ID_OFFSET + 6604, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_P.mission_name, + "Northeast Psi-link Spire", + SC2_RACESWAP_LOC_ID_OFFSET + 6605, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) or adv_tactics, + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_P.mission_name, + "Northwest Psi-link Spire", + SC2_RACESWAP_LOC_ID_OFFSET + 6606, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_P.mission_name, + "Southwest Psi-link Spire", + SC2_RACESWAP_LOC_ID_OFFSET + 6607, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_P.mission_name, + "Nafash", + SC2_RACESWAP_LOC_ID_OFFSET + 6608, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.HARVEST_OF_SCREAMS_P.mission_name, + "20 Unfrozen Structures", + SC2_RACESWAP_LOC_ID_OFFSET + 6609, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 6700, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "East Stasis Chamber", + SC2_RACESWAP_LOC_ID_OFFSET + 6701, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "Center Stasis Chamber", + SC2_RACESWAP_LOC_ID_OFFSET + 6702, + LocationType.VANILLA, + lambda state: logic.terran_common_unit(state) or adv_tactics, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "West Stasis Chamber", + SC2_RACESWAP_LOC_ID_OFFSET + 6703, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "Destroy 4 Shuttles", + SC2_RACESWAP_LOC_ID_OFFSET + 6704, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "Frozen Expansion", + SC2_RACESWAP_LOC_ID_OFFSET + 6705, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "Southwest Frozen Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6706, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "Southeast Frozen Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6707, + LocationType.EXTRA, + lambda state: logic.terran_common_unit(state) or adv_tactics, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "West Frozen Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6708, + LocationType.EXTRA, + lambda state: logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "East Frozen Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6709, + LocationType.EXTRA, + lambda state: logic.terran_common_unit(state) + and logic.terran_competent_anti_air(state), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "West Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 6710, + LocationType.CHALLENGE, + lambda state: logic.terran_beats_protoss_deathball(state) + and logic.terran_common_unit(state), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "Center Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 6711, + LocationType.CHALLENGE, + lambda state: logic.terran_beats_protoss_deathball(state) + and logic.terran_competent_ground_to_air(state) + and logic.terran_common_unit(state), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, + "East Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 6712, + LocationType.CHALLENGE, + lambda state: logic.terran_beats_protoss_deathball(state) + and logic.terran_competent_ground_to_air(state) + and logic.terran_common_unit(state), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 6800, + LocationType.VICTORY, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "East Stasis Chamber", + SC2_RACESWAP_LOC_ID_OFFSET + 6801, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "Center Stasis Chamber", + SC2_RACESWAP_LOC_ID_OFFSET + 6802, + LocationType.VANILLA, + lambda state: logic.protoss_common_unit(state) or adv_tactics, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "West Stasis Chamber", + SC2_RACESWAP_LOC_ID_OFFSET + 6803, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "Destroy 4 Shuttles", + SC2_RACESWAP_LOC_ID_OFFSET + 6804, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "Frozen Expansion", + SC2_RACESWAP_LOC_ID_OFFSET + 6805, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "Southwest Frozen Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6806, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "Southeast Frozen Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6807, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) or adv_tactics, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "West Frozen Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6808, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "East Frozen Group", + SC2_RACESWAP_LOC_ID_OFFSET + 6809, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_armor_anti_air(state) + ), + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "West Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 6810, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "Center Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 6811, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, + "East Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 6812, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 7100, + LocationType.VICTORY, + lambda state: logic.terran_common_unit(state) + and (logic.terran_basic_anti_air(state) or adv_tactics), + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "Center Infested Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 7101, + LocationType.VANILLA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "North Infested Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 7102, + LocationType.VANILLA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "Repel Zagara", + SC2_RACESWAP_LOC_ID_OFFSET + 7103, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "Close Bunker", + SC2_RACESWAP_LOC_ID_OFFSET + 7104, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "South Bunker", + SC2_RACESWAP_LOC_ID_OFFSET + 7105, + LocationType.EXTRA, + lambda state: adv_tactics or logic.terran_common_unit(state), + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "Southwest Bunker", + SC2_RACESWAP_LOC_ID_OFFSET + 7106, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "Southeast Bunker", + SC2_RACESWAP_LOC_ID_OFFSET + 7107, + LocationType.EXTRA, + lambda state: logic.terran_common_unit(state) + and (logic.terran_basic_anti_air(state) or adv_tactics), + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "North Bunker", + SC2_RACESWAP_LOC_ID_OFFSET + 7108, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "Northeast Bunker", + SC2_RACESWAP_LOC_ID_OFFSET + 7109, + LocationType.EXTRA, + lambda state: logic.terran_common_unit(state) + and (logic.terran_basic_anti_air(state) or adv_tactics), + ), + make_location_data( + SC2Mission.DOMINATION_T.mission_name, + "Win Without 100 Eggs", + SC2_RACESWAP_LOC_ID_OFFSET + 7110, + LocationType.CHALLENGE, + logic.terran_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 7200, + LocationType.VICTORY, + lambda state: logic.protoss_common_unit(state) + and (adv_tactics or logic.protoss_basic_anti_air(state)), + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "Center Infested Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 7201, + LocationType.VANILLA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "North Infested Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 7202, + LocationType.VANILLA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "Repel Zagara", + SC2_RACESWAP_LOC_ID_OFFSET + 7203, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "Close Templar", + SC2_RACESWAP_LOC_ID_OFFSET + 7204, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "South Templar", + SC2_RACESWAP_LOC_ID_OFFSET + 7205, + LocationType.EXTRA, + lambda state: adv_tactics or logic.protoss_common_unit(state), + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "Southwest Templar", + SC2_RACESWAP_LOC_ID_OFFSET + 7206, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "Southeast Templar", + SC2_RACESWAP_LOC_ID_OFFSET + 7207, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) + and (adv_tactics or logic.protoss_basic_anti_air(state)), + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "North Templar", + SC2_RACESWAP_LOC_ID_OFFSET + 7208, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "Northeast Templar", + SC2_RACESWAP_LOC_ID_OFFSET + 7209, + LocationType.EXTRA, + lambda state: logic.protoss_common_unit(state) + and (adv_tactics or logic.protoss_basic_anti_air(state)), + ), + make_location_data( + SC2Mission.DOMINATION_P.mission_name, + "Win Without 100 Eggs", + SC2_RACESWAP_LOC_ID_OFFSET + 7210, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 7300, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "West Biomass", + SC2_RACESWAP_LOC_ID_OFFSET + 7301, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "North Biomass", + SC2_RACESWAP_LOC_ID_OFFSET + 7302, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "South Biomass", + SC2_RACESWAP_LOC_ID_OFFSET + 7303, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "Destroy 3 Gorgons", + SC2_RACESWAP_LOC_ID_OFFSET + 7304, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "Close Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 7305, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "South Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 7306, + LocationType.EXTRA, + logic.terran_common_unit, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "North Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 7307, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "West Medic Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 7308, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "East Medic Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 7309, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "South Orbital Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 7310, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "Northwest Orbital Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 7311, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_T.mission_name, + "Southeast Orbital Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 7312, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 7400, + LocationType.VICTORY, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "West Biomass", + SC2_RACESWAP_LOC_ID_OFFSET + 7401, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "North Biomass", + SC2_RACESWAP_LOC_ID_OFFSET + 7402, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "South Biomass", + SC2_RACESWAP_LOC_ID_OFFSET + 7403, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "Destroy 3 Gorgons", + SC2_RACESWAP_LOC_ID_OFFSET + 7404, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "Close Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 7405, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "South Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 7406, + LocationType.EXTRA, + logic.protoss_common_unit, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "North Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 7407, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "West Energizer Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 7408, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "East Energizer Rescue", + SC2_RACESWAP_LOC_ID_OFFSET + 7409, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "South Orbital Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 7410, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_competent_comp(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "Northwest Orbital Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 7411, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_competent_comp(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.FIRE_IN_THE_SKY_P.mission_name, + "Southeast Orbital Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 7412, + LocationType.CHALLENGE, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_competent_comp(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 7500, + LocationType.VICTORY, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_T.mission_name, + "East Science Lab", + SC2_RACESWAP_LOC_ID_OFFSET + 7501, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_T.mission_name, + "North Science Lab", + SC2_RACESWAP_LOC_ID_OFFSET + 7502, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_T.mission_name, + "Get Nuked", + SC2_RACESWAP_LOC_ID_OFFSET + 7503, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_T.mission_name, + "Entrance Gate", + SC2_RACESWAP_LOC_ID_OFFSET + 7504, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_T.mission_name, + "Citadel Gate", + SC2_RACESWAP_LOC_ID_OFFSET + 7505, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_T.mission_name, + "South Expansion", + SC2_RACESWAP_LOC_ID_OFFSET + 7506, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_T.mission_name, + "Rich Mineral Expansion", + SC2_RACESWAP_LOC_ID_OFFSET + 7507, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 7600, + LocationType.VICTORY, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_P.mission_name, + "East Science Lab", + SC2_RACESWAP_LOC_ID_OFFSET + 7601, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_P.mission_name, + "North Science Lab", + SC2_RACESWAP_LOC_ID_OFFSET + 7602, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_P.mission_name, + "Get Nuked", + SC2_RACESWAP_LOC_ID_OFFSET + 7603, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_P.mission_name, + "Entrance Gate", + SC2_RACESWAP_LOC_ID_OFFSET + 7604, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_P.mission_name, + "Citadel Gate", + SC2_RACESWAP_LOC_ID_OFFSET + 7605, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_P.mission_name, + "South Expansion", + SC2_RACESWAP_LOC_ID_OFFSET + 7606, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.OLD_SOLDIERS_P.mission_name, + "Rich Mineral Expansion", + SC2_RACESWAP_LOC_ID_OFFSET + 7607, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 7700, + LocationType.VICTORY, + lambda state: ( + logic.terran_competent_comp(state) and logic.terran_common_unit(state) + ), + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_T.mission_name, + "Center Essence Pool", + SC2_RACESWAP_LOC_ID_OFFSET + 7701, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_T.mission_name, + "East Essence Pool", + SC2_RACESWAP_LOC_ID_OFFSET + 7702, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and ( + adv_tactics + and logic.terran_basic_anti_air(state) + or logic.terran_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_T.mission_name, + "South Essence Pool", + SC2_RACESWAP_LOC_ID_OFFSET + 7703, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and ( + adv_tactics + and logic.terran_basic_anti_air(state) + or logic.terran_competent_anti_air(state) + ) + ), + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_T.mission_name, + "Finish Feeding", + SC2_RACESWAP_LOC_ID_OFFSET + 7704, + LocationType.EXTRA, + lambda state: ( + logic.terran_competent_comp(state) and logic.terran_common_unit(state) + ), + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_T.mission_name, + "South Proxy Primal Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 7705, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_competent_comp(state) and logic.terran_common_unit(state) + ), + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_T.mission_name, + "East Proxy Primal Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 7706, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_competent_comp(state) and logic.terran_common_unit(state) + ), + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_T.mission_name, + "South Main Primal Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 7707, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_competent_comp(state) and logic.terran_common_unit(state) + ), + flags=LocationFlag.BASEBUST, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_T.mission_name, + "East Main Primal Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 7708, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_competent_comp(state) and logic.terran_common_unit(state) + ), + flags=LocationFlag.BASEBUST, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_T.mission_name, + "Flawless", + SC2_RACESWAP_LOC_ID_OFFSET + 7709, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_competent_comp(state) + and logic.terran_common_unit(state) + and ( + # Fast unit + state.has_any( + ( + item_names.BANSHEE, + item_names.VULTURE, + item_names.DIAMONDBACK, + item_names.WARHOUND, + item_names.CYCLONE, + ), + player, + ) + or state.has_all( + (item_names.VALKYRIE, item_names.VALKYRIE_FLECHETTE_MISSILES), + player, + ) + or state.has_all( + ( + item_names.WRAITH, + item_names.WRAITH_ADVANCED_LASER_TECHNOLOGY, + ), + player, + ) + ) + ), + flags=LocationFlag.PREVENTATIVE, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 7800, + LocationType.VICTORY, + logic.protoss_competent_comp, + hard_rule=logic.protoss_any_anti_air_unit, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_P.mission_name, + "Center Essence Pool", + SC2_RACESWAP_LOC_ID_OFFSET + 7801, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_P.mission_name, + "East Essence Pool", + SC2_RACESWAP_LOC_ID_OFFSET + 7802, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_light_anti_air(state) + ), + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_P.mission_name, + "South Essence Pool", + SC2_RACESWAP_LOC_ID_OFFSET + 7803, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_anti_light_anti_air(state) + ), + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_P.mission_name, + "Finish Feeding", + SC2_RACESWAP_LOC_ID_OFFSET + 7804, + LocationType.EXTRA, + logic.protoss_competent_comp, + hard_rule=logic.protoss_any_anti_air_unit, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_P.mission_name, + "South Proxy Primal Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 7805, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_P.mission_name, + "East Proxy Primal Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 7806, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_P.mission_name, + "South Main Primal Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 7807, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + hard_rule=logic.protoss_any_anti_air_unit, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_P.mission_name, + "East Main Primal Hive", + SC2_RACESWAP_LOC_ID_OFFSET + 7808, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.BASEBUST, + hard_rule=logic.protoss_any_anti_air_unit, + ), + make_location_data( + SC2Mission.WAKING_THE_ANCIENT_P.mission_name, + "Flawless", + SC2_RACESWAP_LOC_ID_OFFSET + 7809, + LocationType.CHALLENGE, + logic.protoss_competent_comp, + flags=LocationFlag.PREVENTATIVE, + hard_rule=logic.protoss_any_anti_air_unit, + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 7900, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_defense_rating(state, True, True) >= 7 + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_T.mission_name, + "Tyrannozor", + SC2_RACESWAP_LOC_ID_OFFSET + 7901, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_defense_rating(state, True, True) >= 7 + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_T.mission_name, + "Reach the Pool", + SC2_RACESWAP_LOC_ID_OFFSET + 7902, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_T.mission_name, + "15 Minutes Remaining", + SC2_RACESWAP_LOC_ID_OFFSET + 7903, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_defense_rating(state, True, True) >= 7 + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_T.mission_name, + "5 Minutes Remaining", + SC2_RACESWAP_LOC_ID_OFFSET + 7904, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_defense_rating(state, True, True) >= 7 + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_T.mission_name, + "Pincer Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 7905, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_defense_rating(state, True, True) >= 7 + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_T.mission_name, + "Yagdra Claims Brakk's Pack", + SC2_RACESWAP_LOC_ID_OFFSET + 7906, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_defense_rating(state, True, True) >= 7 + and logic.terran_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 8000, + LocationType.VICTORY, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_defense_rating(state, True) >= 7 + and logic.protoss_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_P.mission_name, + "Tyrannozor", + SC2_RACESWAP_LOC_ID_OFFSET + 8001, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_defense_rating(state, True) >= 7 + and logic.protoss_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_P.mission_name, + "Reach the Pool", + SC2_RACESWAP_LOC_ID_OFFSET + 8002, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_P.mission_name, + "15 Minutes Remaining", + SC2_RACESWAP_LOC_ID_OFFSET + 8003, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_defense_rating(state, True) >= 7 + and logic.protoss_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_P.mission_name, + "5 Minutes Remaining", + SC2_RACESWAP_LOC_ID_OFFSET + 8004, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_defense_rating(state, True) >= 7 + and logic.protoss_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_P.mission_name, + "Pincer Attack", + SC2_RACESWAP_LOC_ID_OFFSET + 8005, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_defense_rating(state, True) >= 7 + and logic.protoss_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_CRUCIBLE_P.mission_name, + "Yagdra Claims Brakk's Pack", + SC2_RACESWAP_LOC_ID_OFFSET + 8006, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_defense_rating(state, True) >= 7 + and logic.protoss_competent_anti_air(state) + ), + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 8300, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "East Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 8301, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "Center Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 8302, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "West Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 8303, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "First Intro Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8304, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "Second Intro Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8305, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "Base Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8306, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "East Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8307, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_moderate_anti_air(state) + and (adv_tactics or logic.terran_infested_garrison_claimer(state)) + ), + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "Mid Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8308, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_moderate_anti_air(state) + and (adv_tactics or logic.terran_infested_garrison_claimer(state)) + ), + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "North Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8309, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_comp(state) + and (adv_tactics or logic.terran_infested_garrison_claimer(state)) + ), + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "Close Southwest Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8310, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_comp(state) + and (adv_tactics or logic.terran_infested_garrison_claimer(state)) + ), + ), + make_location_data( + SC2Mission.INFESTED_T.mission_name, + "Far Southwest Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8311, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_comp(state) + and (adv_tactics or logic.terran_infested_garrison_claimer(state)) + ), + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 8400, + LocationType.VICTORY, + logic.protoss_competent_comp, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "East Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 8401, + LocationType.VANILLA, + lambda state: ( + logic.protoss_common_unit(state) and logic.protoss_basic_anti_air(state) + ), + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "Center Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 8402, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "West Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 8403, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "First Intro Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8404, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "Second Intro Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8405, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "Base Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8406, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "East Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8407, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_basic_anti_air(state) + and (adv_tactics or logic.protoss_infested_garrison_claimer(state)) + ), + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "Mid Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8408, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_basic_anti_air(state) + and (adv_tactics or logic.protoss_infested_garrison_claimer(state)) + ), + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "North Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8409, + LocationType.EXTRA, + lambda state: ( + logic.protoss_common_unit(state) + and logic.protoss_competent_anti_air(state) + and (adv_tactics or logic.protoss_infested_garrison_claimer(state)) + ), + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "Close Southwest Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8410, + LocationType.EXTRA, + lambda state: ( + logic.protoss_competent_comp(state) + and (adv_tactics or logic.protoss_infested_garrison_claimer(state)) + ), + ), + make_location_data( + SC2Mission.INFESTED_P.mission_name, + "Far Southwest Garrison", + SC2_RACESWAP_LOC_ID_OFFSET + 8411, + LocationType.EXTRA, + lambda state: ( + logic.protoss_competent_comp(state) + and (adv_tactics or logic.protoss_infested_garrison_claimer(state)) + ), + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 8500, + LocationType.VICTORY, + logic.terran_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_T.mission_name, + "North War Bot", + SC2_RACESWAP_LOC_ID_OFFSET + 8501, + LocationType.VANILLA, + logic.terran_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_T.mission_name, + "South War Bot", + SC2_RACESWAP_LOC_ID_OFFSET + 8502, + LocationType.VANILLA, + logic.terran_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_T.mission_name, + "Kill 1 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8503, + LocationType.EXTRA, + logic.terran_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_T.mission_name, + "Kill 2 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8504, + LocationType.EXTRA, + logic.terran_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_T.mission_name, + "Kill 3 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8505, + LocationType.EXTRA, + logic.terran_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_T.mission_name, + "Kill 4 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8506, + LocationType.EXTRA, + logic.terran_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_T.mission_name, + "Kill 5 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8507, + LocationType.EXTRA, + logic.terran_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_T.mission_name, + "Kill 6 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8508, + LocationType.EXTRA, + logic.terran_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_T.mission_name, + "Kill 7 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8509, + LocationType.EXTRA, + logic.terran_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 8600, + LocationType.VICTORY, + logic.protoss_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_P.mission_name, + "North Stone Zealot", + SC2_RACESWAP_LOC_ID_OFFSET + 8601, + LocationType.VANILLA, + logic.protoss_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_P.mission_name, + "South Stone Zealot", + SC2_RACESWAP_LOC_ID_OFFSET + 8602, + LocationType.VANILLA, + logic.protoss_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_P.mission_name, + "Kill 1 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8603, + LocationType.EXTRA, + logic.protoss_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_P.mission_name, + "Kill 2 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8604, + LocationType.EXTRA, + logic.protoss_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_P.mission_name, + "Kill 3 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8605, + LocationType.EXTRA, + logic.protoss_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_P.mission_name, + "Kill 4 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8606, + LocationType.EXTRA, + logic.protoss_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_P.mission_name, + "Kill 5 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8607, + LocationType.EXTRA, + logic.protoss_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_P.mission_name, + "Kill 6 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8608, + LocationType.EXTRA, + logic.protoss_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.HAND_OF_DARKNESS_P.mission_name, + "Kill 7 Hybrid", + SC2_RACESWAP_LOC_ID_OFFSET + 8609, + LocationType.EXTRA, + logic.protoss_hand_of_darkness_requirement, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 8700, + LocationType.VICTORY, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name, + "Northwest Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 8701, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name, + "Northeast Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 8702, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name, + "South Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 8703, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name, + "Base Established", + SC2_RACESWAP_LOC_ID_OFFSET + 8704, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name, + "Close Temple", + SC2_RACESWAP_LOC_ID_OFFSET + 8705, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name, + "Mid Temple", + SC2_RACESWAP_LOC_ID_OFFSET + 8706, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name, + "Southeast Temple", + SC2_RACESWAP_LOC_ID_OFFSET + 8707, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name, + "Northeast Temple", + SC2_RACESWAP_LOC_ID_OFFSET + 8708, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name, + "Northwest Temple", + SC2_RACESWAP_LOC_ID_OFFSET + 8709, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 8800, + LocationType.VICTORY, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name, + "Northwest Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 8801, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name, + "Northeast Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 8802, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name, + "South Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 8803, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name, + "Base Established", + SC2_RACESWAP_LOC_ID_OFFSET + 8804, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name, + "Close Temple", + SC2_RACESWAP_LOC_ID_OFFSET + 8805, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name, + "Mid Temple", + SC2_RACESWAP_LOC_ID_OFFSET + 8806, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name, + "Southeast Temple", + SC2_RACESWAP_LOC_ID_OFFSET + 8807, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name, + "Northeast Temple", + SC2_RACESWAP_LOC_ID_OFFSET + 8808, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name, + "Northwest Temple", + SC2_RACESWAP_LOC_ID_OFFSET + 8809, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 9300, + LocationType.VICTORY, + logic.terran_planetfall_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "East Gate", + SC2_RACESWAP_LOC_ID_OFFSET + 9301, + LocationType.VANILLA, + logic.terran_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "Northwest Gate", + SC2_RACESWAP_LOC_ID_OFFSET + 9302, + LocationType.VANILLA, + logic.terran_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "North Gate", + SC2_RACESWAP_LOC_ID_OFFSET + 9303, + LocationType.VANILLA, + logic.terran_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "1 Laser Drill Deployed", + SC2_RACESWAP_LOC_ID_OFFSET + 9304, + LocationType.EXTRA, + logic.terran_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "2 Laser Drills Deployed", + SC2_RACESWAP_LOC_ID_OFFSET + 9305, + LocationType.EXTRA, + logic.terran_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "3 Laser Drills Deployed", + SC2_RACESWAP_LOC_ID_OFFSET + 9306, + LocationType.EXTRA, + logic.terran_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "4 Laser Drills Deployed", + SC2_RACESWAP_LOC_ID_OFFSET + 9307, + LocationType.EXTRA, + logic.terran_planetfall_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "5 Laser Drills Deployed", + SC2_RACESWAP_LOC_ID_OFFSET + 9308, + LocationType.EXTRA, + logic.terran_planetfall_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "Sons of Korhal", + SC2_RACESWAP_LOC_ID_OFFSET + 9309, + LocationType.EXTRA, + logic.terran_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "Night Wolves", + SC2_RACESWAP_LOC_ID_OFFSET + 9310, + LocationType.EXTRA, + logic.terran_planetfall_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "West Expansion", + SC2_RACESWAP_LOC_ID_OFFSET + 9311, + LocationType.EXTRA, + logic.terran_planetfall_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL_T.mission_name, + "Mid Expansion", + SC2_RACESWAP_LOC_ID_OFFSET + 9312, + LocationType.EXTRA, + logic.terran_planetfall_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 9400, + LocationType.VICTORY, + logic.protoss_planetfall_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "East Gate", + SC2_RACESWAP_LOC_ID_OFFSET + 9401, + LocationType.VANILLA, + logic.protoss_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "Northwest Gate", + SC2_RACESWAP_LOC_ID_OFFSET + 9402, + LocationType.VANILLA, + logic.protoss_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "North Gate", + SC2_RACESWAP_LOC_ID_OFFSET + 9403, + LocationType.VANILLA, + logic.protoss_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "1 Particle Cannon Deployed", + SC2_RACESWAP_LOC_ID_OFFSET + 9404, + LocationType.EXTRA, + logic.protoss_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "2 Particle Cannons Deployed", + SC2_RACESWAP_LOC_ID_OFFSET + 9405, + LocationType.EXTRA, + logic.protoss_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "3 Particle Cannons Deployed", + SC2_RACESWAP_LOC_ID_OFFSET + 9406, + LocationType.EXTRA, + logic.protoss_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "4 Particle Cannons Deployed", + SC2_RACESWAP_LOC_ID_OFFSET + 9407, + LocationType.EXTRA, + logic.protoss_planetfall_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "5 Particle Cannons Deployed", + SC2_RACESWAP_LOC_ID_OFFSET + 9408, + LocationType.EXTRA, + logic.protoss_planetfall_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "Sons of Korhal", + SC2_RACESWAP_LOC_ID_OFFSET + 9409, + LocationType.EXTRA, + logic.protoss_planetfall_requirement, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "Night Wolves", + SC2_RACESWAP_LOC_ID_OFFSET + 9410, + LocationType.EXTRA, + logic.protoss_planetfall_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "West Expansion", + SC2_RACESWAP_LOC_ID_OFFSET + 9411, + LocationType.EXTRA, + logic.protoss_planetfall_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.PLANETFALL_P.mission_name, + "Mid Expansion", + SC2_RACESWAP_LOC_ID_OFFSET + 9412, + LocationType.EXTRA, + logic.protoss_planetfall_requirement, + hard_rule=logic.protoss_any_anti_air_unit_or_soa_any_protoss, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 9500, + LocationType.VICTORY, + logic.terran_base_trasher, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_T.mission_name, + "First Power Link", + SC2_RACESWAP_LOC_ID_OFFSET + 9501, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_T.mission_name, + "Second Power Link", + SC2_RACESWAP_LOC_ID_OFFSET + 9502, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_T.mission_name, + "Third Power Link", + SC2_RACESWAP_LOC_ID_OFFSET + 9503, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_T.mission_name, + "Expansion Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 9504, + LocationType.EXTRA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_T.mission_name, + "Main Path Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 9505, + LocationType.EXTRA, + logic.terran_base_trasher, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 9600, + LocationType.VICTORY, + lambda state: logic.protoss_deathball + or (adv_tactics and logic.protoss_competent_comp(state)), + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_P.mission_name, + "First Power Link", + SC2_RACESWAP_LOC_ID_OFFSET + 9601, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_P.mission_name, + "Second Power Link", + SC2_RACESWAP_LOC_ID_OFFSET + 9602, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_P.mission_name, + "Third Power Link", + SC2_RACESWAP_LOC_ID_OFFSET + 9603, + LocationType.VANILLA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_P.mission_name, + "Expansion Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 9604, + LocationType.EXTRA, + logic.protoss_competent_comp, + ), + make_location_data( + SC2Mission.DEATH_FROM_ABOVE_P.mission_name, + "Main Path Command Center", + SC2_RACESWAP_LOC_ID_OFFSET + 9605, + LocationType.EXTRA, + lambda state: logic.protoss_deathball + or (adv_tactics and logic.protoss_competent_comp(state)), + ), + make_location_data( + SC2Mission.THE_RECKONING_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 9700, + LocationType.VICTORY, + logic.terran_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING_T.mission_name, + "South Lane", + SC2_RACESWAP_LOC_ID_OFFSET + 9701, + LocationType.VANILLA, + logic.terran_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING_T.mission_name, + "North Lane", + SC2_RACESWAP_LOC_ID_OFFSET + 9702, + LocationType.VANILLA, + logic.terran_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING_T.mission_name, + "East Lane", + SC2_RACESWAP_LOC_ID_OFFSET + 9703, + LocationType.VANILLA, + logic.terran_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING_T.mission_name, + "Odin", + SC2_RACESWAP_LOC_ID_OFFSET + 9704, + LocationType.EXTRA, + logic.terran_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING_T.mission_name, + "Trash the Odin Early", + SC2_RACESWAP_LOC_ID_OFFSET + 9705, + LocationType.MASTERY, + lambda state: ( + logic.terran_the_reckoning_requirement(state) + and logic.terran_power_rating(state) >= 10 + ), + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.THE_RECKONING_P.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 9800, + LocationType.VICTORY, + logic.protoss_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING_P.mission_name, + "South Lane", + SC2_RACESWAP_LOC_ID_OFFSET + 9801, + LocationType.VANILLA, + logic.protoss_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING_P.mission_name, + "North Lane", + SC2_RACESWAP_LOC_ID_OFFSET + 9802, + LocationType.VANILLA, + logic.protoss_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING_P.mission_name, + "East Lane", + SC2_RACESWAP_LOC_ID_OFFSET + 9803, + LocationType.VANILLA, + logic.protoss_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING_P.mission_name, + "Odin", + SC2_RACESWAP_LOC_ID_OFFSET + 9804, + LocationType.EXTRA, + logic.protoss_the_reckoning_requirement, + ), + make_location_data( + SC2Mission.THE_RECKONING_P.mission_name, + "Trash the Odin Early", + SC2_RACESWAP_LOC_ID_OFFSET + 9805, + LocationType.MASTERY, + lambda state: ( + logic.protoss_the_reckoning_requirement(state) + and ( + logic.protoss_fleet(state) + or logic.protoss_power_rating(state) >= 10 + ) + ), + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.DARK_WHISPERS_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 9900, + LocationType.VICTORY, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.DARK_WHISPERS_T.mission_name, + "First Prisoner Group", + SC2_RACESWAP_LOC_ID_OFFSET + 9901, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.DARK_WHISPERS_T.mission_name, + "Second Prisoner Group", + SC2_RACESWAP_LOC_ID_OFFSET + 9902, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.DARK_WHISPERS_T.mission_name, + "First Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 9903, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.DARK_WHISPERS_T.mission_name, + "Second Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 9904, + LocationType.VANILLA, + logic.terran_competent_comp, + ), + make_location_data( + SC2Mission.DARK_WHISPERS_T.mission_name, + "Zerg Base", + SC2_RACESWAP_LOC_ID_OFFSET + 9905, + LocationType.MASTERY, + lambda state: ( + logic.terran_competent_comp(state) + and logic.terran_base_trasher(state) + and logic.terran_power_rating(state) >= 6 + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.DARK_WHISPERS_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 10000, + LocationType.VICTORY, + lambda state: logic.zerg_competent_comp + and logic.zerg_moderate_anti_air(state), + ), + make_location_data( + SC2Mission.DARK_WHISPERS_Z.mission_name, + "First Prisoner Group", + SC2_RACESWAP_LOC_ID_OFFSET + 10001, + LocationType.VANILLA, + lambda state: logic.zerg_competent_comp + and logic.zerg_moderate_anti_air(state), + ), + make_location_data( + SC2Mission.DARK_WHISPERS_Z.mission_name, + "Second Prisoner Group", + SC2_RACESWAP_LOC_ID_OFFSET + 10002, + LocationType.VANILLA, + lambda state: logic.zerg_competent_comp + and logic.zerg_moderate_anti_air(state), + ), + make_location_data( + SC2Mission.DARK_WHISPERS_Z.mission_name, + "First Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 10003, + LocationType.VANILLA, + lambda state: logic.zerg_competent_comp + and logic.zerg_moderate_anti_air(state), + ), + make_location_data( + SC2Mission.DARK_WHISPERS_Z.mission_name, + "Second Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 10004, + LocationType.VANILLA, + lambda state: logic.zerg_competent_comp + and logic.zerg_moderate_anti_air(state), + ), + make_location_data( + SC2Mission.DARK_WHISPERS_Z.mission_name, + "Zerg Base", + SC2_RACESWAP_LOC_ID_OFFSET + 10005, + LocationType.MASTERY, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_moderate_anti_air(state) + and logic.zerg_base_buster(state) + and logic.zerg_power_rating(state) >= 6 + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 10100, + LocationType.VICTORY, + lambda state: ( + logic.terran_beats_protoss_deathball(state) + and logic.terran_mineral_dump(state) + ), + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG_T.mission_name, + "South Rock Formation", + SC2_RACESWAP_LOC_ID_OFFSET + 10101, + LocationType.VANILLA, + lambda state: ( + logic.terran_beats_protoss_deathball(state) + and logic.terran_mineral_dump(state) + ), + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG_T.mission_name, + "West Rock Formation", + SC2_RACESWAP_LOC_ID_OFFSET + 10102, + LocationType.VANILLA, + lambda state: ( + logic.terran_beats_protoss_deathball(state) + and logic.terran_mineral_dump(state) + ), + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG_T.mission_name, + "East Rock Formation", + SC2_RACESWAP_LOC_ID_OFFSET + 10103, + LocationType.VANILLA, + lambda state: ( + logic.terran_beats_protoss_deathball(state) + and logic.terran_mineral_dump(state) + and logic.terran_can_grab_ghosts_in_the_fog_east_rock_formation(state) + ), + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 10200, + LocationType.VICTORY, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_competent_anti_air(state) + and logic.zerg_mineral_dump(state) + ), + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG_Z.mission_name, + "South Rock Formation", + SC2_RACESWAP_LOC_ID_OFFSET + 10201, + LocationType.VANILLA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_competent_anti_air(state) + and logic.zerg_mineral_dump(state) + ), + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG_Z.mission_name, + "West Rock Formation", + SC2_RACESWAP_LOC_ID_OFFSET + 10202, + LocationType.VANILLA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_competent_anti_air(state) + and logic.zerg_mineral_dump(state) + ), + ), + make_location_data( + SC2Mission.GHOSTS_IN_THE_FOG_Z.mission_name, + "East Rock Formation", + SC2_RACESWAP_LOC_ID_OFFSET + 10203, + LocationType.VANILLA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_competent_anti_air(state) + and logic.zerg_mineral_dump(state) + and logic.zerg_can_grab_ghosts_in_the_fog_east_rock_formation(state) + ), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 10700, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) + and (adv_tactics or logic.terran_moderate_anti_air(state)) + ), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_T.mission_name, + "Close Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 10701, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_T.mission_name, + "East Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 10702, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and ( + adv_tactics + or ( + logic.terran_moderate_anti_air(state) + and logic.terran_any_air_unit(state) + ) + ) + ), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_T.mission_name, + "West Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 10703, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and (adv_tactics or logic.terran_moderate_anti_air(state)) + ), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_T.mission_name, + "Base", + SC2_RACESWAP_LOC_ID_OFFSET + 10704, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_T.mission_name, + "Templar Base", + SC2_RACESWAP_LOC_ID_OFFSET + 10705, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) + and (adv_tactics or logic.terran_moderate_anti_air(state)) + ), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 10800, + LocationType.VICTORY, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_Z.mission_name, + "Close Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 10801, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_Z.mission_name, + "East Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 10802, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_Z.mission_name, + "West Pylon", + SC2_RACESWAP_LOC_ID_OFFSET + 10803, + LocationType.VANILLA, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_Z.mission_name, + "Base", + SC2_RACESWAP_LOC_ID_OFFSET + 10804, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.THE_GROWING_SHADOW_Z.mission_name, + "Templar Base", + SC2_RACESWAP_LOC_ID_OFFSET + 10805, + LocationType.EXTRA, + lambda state: ( + logic.zerg_common_unit(state) and logic.zerg_moderate_anti_air(state) + ), + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 10900, + LocationType.VICTORY, + logic.terran_spear_of_adun_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_T.mission_name, + "Factory", + SC2_RACESWAP_LOC_ID_OFFSET + 10901, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_T.mission_name, + "Armory", + SC2_RACESWAP_LOC_ID_OFFSET + 10902, + LocationType.VANILLA, + logic.terran_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_T.mission_name, + "Starport", + SC2_RACESWAP_LOC_ID_OFFSET + 10903, + LocationType.VANILLA, + logic.terran_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_T.mission_name, + "North Power Cell", + SC2_RACESWAP_LOC_ID_OFFSET + 10904, + LocationType.EXTRA, + logic.terran_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_T.mission_name, + "East Power Cell", + SC2_RACESWAP_LOC_ID_OFFSET + 10905, + LocationType.EXTRA, + logic.terran_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_T.mission_name, + "South Power Cell", + SC2_RACESWAP_LOC_ID_OFFSET + 10906, + LocationType.EXTRA, + logic.terran_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_T.mission_name, + "Southeast Power Cell", + SC2_RACESWAP_LOC_ID_OFFSET + 10907, + LocationType.EXTRA, + logic.terran_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 11000, + LocationType.VICTORY, + logic.zerg_competent_comp_competent_aa, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_Z.mission_name, + "Baneling Nest", + SC2_RACESWAP_LOC_ID_OFFSET + 11001, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_Z.mission_name, + "Roach Warren", + SC2_RACESWAP_LOC_ID_OFFSET + 11002, + LocationType.VANILLA, + lambda state: ( + logic.zerg_spear_of_adun_requirement(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_Z.mission_name, + "Infestation Pit", + SC2_RACESWAP_LOC_ID_OFFSET + 11003, + LocationType.VANILLA, + lambda state: ( + logic.zerg_spear_of_adun_requirement(state) + and logic.spread_creep(state) + ), + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_Z.mission_name, + "North Power Cell", + SC2_RACESWAP_LOC_ID_OFFSET + 11004, + LocationType.EXTRA, + logic.zerg_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_Z.mission_name, + "East Power Cell", + SC2_RACESWAP_LOC_ID_OFFSET + 11005, + LocationType.EXTRA, + logic.zerg_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_Z.mission_name, + "South Power Cell", + SC2_RACESWAP_LOC_ID_OFFSET + 11006, + LocationType.EXTRA, + logic.zerg_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.THE_SPEAR_OF_ADUN_Z.mission_name, + "Southeast Power Cell", + SC2_RACESWAP_LOC_ID_OFFSET + 11007, + LocationType.EXTRA, + logic.zerg_spear_of_adun_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 11100, + LocationType.VICTORY, + logic.terran_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "Mid EMP Scrambler", + SC2_RACESWAP_LOC_ID_OFFSET + 11101, + LocationType.VANILLA, + logic.terran_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "Southeast EMP Scrambler", + SC2_RACESWAP_LOC_ID_OFFSET + 11102, + LocationType.VANILLA, + logic.terran_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "North EMP Scrambler", + SC2_RACESWAP_LOC_ID_OFFSET + 11103, + LocationType.VANILLA, + logic.terran_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "Mid Stabilizer", + SC2_RACESWAP_LOC_ID_OFFSET + 11104, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "Southwest Stabilizer", + SC2_RACESWAP_LOC_ID_OFFSET + 11105, + LocationType.EXTRA, + logic.terran_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "Northwest Stabilizer", + SC2_RACESWAP_LOC_ID_OFFSET + 11106, + LocationType.EXTRA, + logic.terran_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "Northeast Stabilizer", + SC2_RACESWAP_LOC_ID_OFFSET + 11107, + LocationType.EXTRA, + logic.terran_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "Southeast Stabilizer", + SC2_RACESWAP_LOC_ID_OFFSET + 11108, + LocationType.EXTRA, + logic.terran_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "West Raynor Base", + SC2_RACESWAP_LOC_ID_OFFSET + 11109, + LocationType.EXTRA, + logic.terran_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_T.mission_name, + "East Raynor Base", + SC2_RACESWAP_LOC_ID_OFFSET + 11110, + LocationType.EXTRA, + logic.terran_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 11200, + LocationType.VICTORY, + logic.zerg_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "Mid EMP Scrambler", + SC2_RACESWAP_LOC_ID_OFFSET + 11201, + LocationType.VANILLA, + logic.zerg_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "Southeast EMP Scrambler", + SC2_RACESWAP_LOC_ID_OFFSET + 11202, + LocationType.VANILLA, + logic.zerg_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "North EMP Scrambler", + SC2_RACESWAP_LOC_ID_OFFSET + 11203, + LocationType.VANILLA, + logic.zerg_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "Mid Stabilizer", + SC2_RACESWAP_LOC_ID_OFFSET + 11204, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "Southwest Stabilizer", + SC2_RACESWAP_LOC_ID_OFFSET + 11205, + LocationType.EXTRA, + logic.zerg_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "Northwest Stabilizer", + SC2_RACESWAP_LOC_ID_OFFSET + 11206, + LocationType.EXTRA, + logic.zerg_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "Northeast Stabilizer", + SC2_RACESWAP_LOC_ID_OFFSET + 11207, + LocationType.EXTRA, + logic.zerg_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "Southeast Stabilizer", + SC2_RACESWAP_LOC_ID_OFFSET + 11208, + LocationType.EXTRA, + logic.zerg_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "West Raynor Base", + SC2_RACESWAP_LOC_ID_OFFSET + 11209, + LocationType.EXTRA, + logic.zerg_sky_shield_requirement, + ), + make_location_data( + SC2Mission.SKY_SHIELD_Z.mission_name, + "East Raynor Base", + SC2_RACESWAP_LOC_ID_OFFSET + 11210, + LocationType.EXTRA, + logic.zerg_sky_shield_requirement, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 11300, + LocationType.VICTORY, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_T.mission_name, + "Mid Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 11301, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_T.mission_name, + "North Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 11302, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_competent_comp(state) + or ( + logic.take_over_ai_allies + and logic.advanced_tactics + and logic.terran_common_unit(state) + ) + ), + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_T.mission_name, + "South Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 11303, + LocationType.VANILLA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_T.mission_name, + "Raynor Forward Positions", + SC2_RACESWAP_LOC_ID_OFFSET + 11304, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_T.mission_name, + "Valerian Forward Positions", + SC2_RACESWAP_LOC_ID_OFFSET + 11305, + LocationType.EXTRA, + lambda state: ( + logic.terran_common_unit(state) and logic.terran_competent_comp(state) + ), + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_T.mission_name, + "Win in under 15 Minutes", + SC2_RACESWAP_LOC_ID_OFFSET + 11306, + LocationType.CHALLENGE, + lambda state: ( + logic.terran_common_unit(state) + and logic.terran_base_trasher(state) + and logic.terran_power_rating(state) >= 8 + ), + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 11400, + LocationType.VICTORY, + logic.zerg_brothers_in_arms_requirement, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_Z.mission_name, + "Mid Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 11401, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_Z.mission_name, + "North Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 11402, + LocationType.VANILLA, + lambda state: ( + logic.zerg_brothers_in_arms_requirement(state) + or ( + logic.take_over_ai_allies + and logic.advanced_tactics + and ( + logic.zerg_common_unit(state) or logic.terran_common_unit(state) + ) + ) + ), + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_Z.mission_name, + "South Science Facility", + SC2_RACESWAP_LOC_ID_OFFSET + 11403, + LocationType.VANILLA, + logic.zerg_brothers_in_arms_requirement, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_Z.mission_name, + "Raynor Forward Positions", + SC2_RACESWAP_LOC_ID_OFFSET + 11404, + LocationType.EXTRA, + logic.zerg_brothers_in_arms_requirement, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_Z.mission_name, + "Valerian Forward Positions", + SC2_RACESWAP_LOC_ID_OFFSET + 11405, + LocationType.EXTRA, + logic.zerg_brothers_in_arms_requirement, + ), + make_location_data( + SC2Mission.BROTHERS_IN_ARMS_Z.mission_name, + "Win in under 15 Minutes", + SC2_RACESWAP_LOC_ID_OFFSET + 11406, + LocationType.CHALLENGE, + lambda state: ( + logic.zerg_brothers_in_arms_requirement + and logic.zerg_base_buster(state) + and logic.zerg_power_rating(state) >= 8 + ), + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.AMON_S_REACH_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 11500, + LocationType.VICTORY, + lambda state: (logic.terran_competent_comp(state)), + ), + make_location_data( + SC2Mission.AMON_S_REACH_T.mission_name, + "Close Solarite Reserve", + SC2_RACESWAP_LOC_ID_OFFSET + 11501, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.AMON_S_REACH_T.mission_name, + "North Solarite Reserve", + SC2_RACESWAP_LOC_ID_OFFSET + 11502, + LocationType.VANILLA, + lambda state: (logic.terran_competent_comp(state)), + ), + make_location_data( + SC2Mission.AMON_S_REACH_T.mission_name, + "East Solarite Reserve", + SC2_RACESWAP_LOC_ID_OFFSET + 11503, + LocationType.VANILLA, + lambda state: (logic.terran_competent_comp(state)), + ), + make_location_data( + SC2Mission.AMON_S_REACH_T.mission_name, + "West Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 11504, + LocationType.EXTRA, + lambda state: (logic.terran_competent_comp(state)), + ), + make_location_data( + SC2Mission.AMON_S_REACH_T.mission_name, + "South Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 11505, + LocationType.EXTRA, + lambda state: (logic.terran_competent_comp(state)), + ), + make_location_data( + SC2Mission.AMON_S_REACH_T.mission_name, + "Northwest Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 11506, + LocationType.EXTRA, + lambda state: (logic.terran_competent_comp(state)), + ), + make_location_data( + SC2Mission.AMON_S_REACH_T.mission_name, + "East Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 11507, + LocationType.EXTRA, + lambda state: (logic.terran_competent_comp(state)), + ), + make_location_data( + SC2Mission.AMON_S_REACH_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 11600, + LocationType.VICTORY, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.AMON_S_REACH_Z.mission_name, + "Close Solarite Reserve", + SC2_RACESWAP_LOC_ID_OFFSET + 11601, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.AMON_S_REACH_Z.mission_name, + "North Solarite Reserve", + SC2_RACESWAP_LOC_ID_OFFSET + 11602, + LocationType.VANILLA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.AMON_S_REACH_Z.mission_name, + "East Solarite Reserve", + SC2_RACESWAP_LOC_ID_OFFSET + 11603, + LocationType.VANILLA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.AMON_S_REACH_Z.mission_name, + "West Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 11604, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.AMON_S_REACH_Z.mission_name, + "South Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 11605, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.AMON_S_REACH_Z.mission_name, + "Northwest Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 11606, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.AMON_S_REACH_Z.mission_name, + "East Launch Bay", + SC2_RACESWAP_LOC_ID_OFFSET + 11607, + LocationType.EXTRA, + lambda state: ( + logic.zerg_competent_comp(state) + and logic.zerg_basic_kerriganless_anti_air(state) + ), + ), + make_location_data( + SC2Mission.LAST_STAND_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 11700, + LocationType.VICTORY, + logic.terran_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND_T.mission_name, + "West Zenith Stone", + SC2_RACESWAP_LOC_ID_OFFSET + 11701, + LocationType.VANILLA, + logic.terran_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND_T.mission_name, + "North Zenith Stone", + SC2_RACESWAP_LOC_ID_OFFSET + 11702, + LocationType.VANILLA, + logic.terran_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND_T.mission_name, + "East Zenith Stone", + SC2_RACESWAP_LOC_ID_OFFSET + 11703, + LocationType.VANILLA, + logic.terran_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND_T.mission_name, + "1 Billion Zerg", + SC2_RACESWAP_LOC_ID_OFFSET + 11704, + LocationType.EXTRA, + logic.terran_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND_T.mission_name, + "1.5 Billion Zerg", + SC2_RACESWAP_LOC_ID_OFFSET + 11705, + LocationType.VANILLA, + lambda state: logic.terran_last_stand_requirement(state) + and logic.terran_defense_rating(state, True, True) >= 13, + ), + make_location_data( + SC2Mission.LAST_STAND_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 11800, + LocationType.VICTORY, + logic.zerg_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND_Z.mission_name, + "West Zenith Stone", + SC2_RACESWAP_LOC_ID_OFFSET + 11801, + LocationType.VANILLA, + logic.zerg_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND_Z.mission_name, + "North Zenith Stone", + SC2_RACESWAP_LOC_ID_OFFSET + 11802, + LocationType.VANILLA, + logic.zerg_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND_Z.mission_name, + "East Zenith Stone", + SC2_RACESWAP_LOC_ID_OFFSET + 11803, + LocationType.VANILLA, + logic.zerg_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND_Z.mission_name, + "1 Billion Zerg", + SC2_RACESWAP_LOC_ID_OFFSET + 11804, + LocationType.EXTRA, + logic.zerg_last_stand_requirement, + ), + make_location_data( + SC2Mission.LAST_STAND_Z.mission_name, + "1.5 Billion Zerg", + SC2_RACESWAP_LOC_ID_OFFSET + 11805, + LocationType.VANILLA, + logic.zerg_last_stand_requirement, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 11900, + LocationType.VICTORY, + logic.terran_beats_protoss_deathball, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_T.mission_name, + "South Solarite", + SC2_RACESWAP_LOC_ID_OFFSET + 11901, + LocationType.VANILLA, + logic.terran_beats_protoss_deathball, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_T.mission_name, + "North Solarite", + SC2_RACESWAP_LOC_ID_OFFSET + 11902, + LocationType.VANILLA, + logic.terran_beats_protoss_deathball, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_T.mission_name, + "Northwest Solarite", + SC2_RACESWAP_LOC_ID_OFFSET + 11903, + LocationType.VANILLA, + logic.terran_beats_protoss_deathball, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_T.mission_name, + "Rescue Medics", + SC2_RACESWAP_LOC_ID_OFFSET + 11904, + LocationType.EXTRA, + logic.terran_beats_protoss_deathball, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_T.mission_name, + "Destroy Gateways", + SC2_RACESWAP_LOC_ID_OFFSET + 11905, + LocationType.CHALLENGE, + logic.terran_beats_protoss_deathball, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 12000, + LocationType.VICTORY, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_Z.mission_name, + "South Solarite", + SC2_RACESWAP_LOC_ID_OFFSET + 12001, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_Z.mission_name, + "North Solarite", + SC2_RACESWAP_LOC_ID_OFFSET + 12002, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_Z.mission_name, + "Northwest Solarite", + SC2_RACESWAP_LOC_ID_OFFSET + 12003, + LocationType.VANILLA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_Z.mission_name, + "Rescue Infested Medics", + SC2_RACESWAP_LOC_ID_OFFSET + 12004, + LocationType.EXTRA, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.FORBIDDEN_WEAPON_Z.mission_name, + "Destroy Gateways", + SC2_RACESWAP_LOC_ID_OFFSET + 12005, + LocationType.CHALLENGE, + logic.zerg_competent_comp_competent_aa, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 12100, + LocationType.VICTORY, + logic.terran_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_T.mission_name, + "Mid Celestial Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12101, + LocationType.EXTRA, + logic.terran_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_T.mission_name, + "West Celestial Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12102, + LocationType.EXTRA, + logic.terran_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_T.mission_name, + "South Celestial Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12103, + LocationType.EXTRA, + logic.terran_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_T.mission_name, + "East Celestial Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12104, + LocationType.EXTRA, + logic.terran_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_T.mission_name, + "North Celestial Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12105, + LocationType.EXTRA, + logic.terran_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_T.mission_name, + "Titanic Warp Prism", + SC2_RACESWAP_LOC_ID_OFFSET + 12106, + LocationType.VANILLA, + logic.terran_temple_of_unification_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_T.mission_name, + "Terran Main Base", + SC2_RACESWAP_LOC_ID_OFFSET + 12107, + LocationType.MASTERY, + lambda state: ( + logic.terran_temple_of_unification_requirement(state) + and logic.terran_base_trasher(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_T.mission_name, + "Protoss Main Base", + SC2_RACESWAP_LOC_ID_OFFSET + 12108, + LocationType.MASTERY, + lambda state: ( + logic.terran_temple_of_unification_requirement(state) + and logic.terran_base_trasher(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 12200, + LocationType.VICTORY, + logic.zerg_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_Z.mission_name, + "Mid Celestial Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12201, + LocationType.EXTRA, + logic.zerg_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_Z.mission_name, + "West Celestial Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12202, + LocationType.EXTRA, + logic.zerg_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_Z.mission_name, + "South Celestial Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12203, + LocationType.EXTRA, + logic.zerg_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_Z.mission_name, + "East Celestial Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12204, + LocationType.EXTRA, + logic.zerg_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_Z.mission_name, + "North Celestial Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12205, + LocationType.EXTRA, + logic.zerg_temple_of_unification_requirement, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_Z.mission_name, + "Titanic Warp Prism", + SC2_RACESWAP_LOC_ID_OFFSET + 12206, + LocationType.VANILLA, + logic.zerg_temple_of_unification_requirement, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_Z.mission_name, + "Terran Main Base", + SC2_RACESWAP_LOC_ID_OFFSET + 12207, + LocationType.MASTERY, + lambda state: ( + logic.zerg_temple_of_unification_requirement(state) + and logic.zerg_base_buster(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.TEMPLE_OF_UNIFICATION_Z.mission_name, + "Protoss Main Base", + SC2_RACESWAP_LOC_ID_OFFSET + 12208, + LocationType.MASTERY, + lambda state: ( + logic.zerg_temple_of_unification_requirement(state) + and logic.zerg_base_buster(state) + ), + flags=LocationFlag.BASEBUST, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 12500, + LocationType.VICTORY, + logic.terran_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_T.mission_name, + "Artanis", + SC2_RACESWAP_LOC_ID_OFFSET + 12501, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_T.mission_name, + "Northwest Void Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 12502, + LocationType.EXTRA, + logic.terran_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_T.mission_name, + "Northeast Void Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 12503, + LocationType.EXTRA, + logic.terran_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_T.mission_name, + "Southwest Void Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 12504, + LocationType.EXTRA, + logic.terran_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_T.mission_name, + "Southeast Void Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 12505, + LocationType.EXTRA, + logic.terran_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_T.mission_name, + "South Xel'Naga Vessel", + SC2_RACESWAP_LOC_ID_OFFSET + 12506, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_T.mission_name, + "Mid Xel'Naga Vessel", + SC2_RACESWAP_LOC_ID_OFFSET + 12507, + LocationType.VANILLA, + logic.terran_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_T.mission_name, + "North Xel'Naga Vessel", + SC2_RACESWAP_LOC_ID_OFFSET + 12508, + LocationType.VANILLA, + logic.terran_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 12600, + LocationType.VICTORY, + logic.zerg_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_Z.mission_name, + "Artanis", + SC2_RACESWAP_LOC_ID_OFFSET + 12601, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_Z.mission_name, + "Northwest Void Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 12602, + LocationType.EXTRA, + logic.zerg_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_Z.mission_name, + "Northeast Void Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 12603, + LocationType.EXTRA, + logic.zerg_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_Z.mission_name, + "Southwest Void Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 12604, + LocationType.EXTRA, + logic.zerg_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_Z.mission_name, + "Southeast Void Crystal", + SC2_RACESWAP_LOC_ID_OFFSET + 12605, + LocationType.EXTRA, + logic.zerg_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_Z.mission_name, + "South Xel'Naga Vessel", + SC2_RACESWAP_LOC_ID_OFFSET + 12606, + LocationType.VANILLA, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_Z.mission_name, + "Mid Xel'Naga Vessel", + SC2_RACESWAP_LOC_ID_OFFSET + 12607, + LocationType.VANILLA, + logic.zerg_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.HARBINGER_OF_OBLIVION_Z.mission_name, + "North Xel'Naga Vessel", + SC2_RACESWAP_LOC_ID_OFFSET + 12608, + LocationType.VANILLA, + logic.zerg_harbinger_of_oblivion_requirement, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 12700, + LocationType.VICTORY, + logic.terran_unsealing_the_past_requirement, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_T.mission_name, + "Zerg Cleared", + SC2_RACESWAP_LOC_ID_OFFSET + 12701, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_T.mission_name, + "First Stasis Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12702, + LocationType.EXTRA, + lambda state: ( + logic.advanced_tactics + or logic.terran_unsealing_the_past_requirement(state) + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_T.mission_name, + "Second Stasis Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12703, + LocationType.EXTRA, + logic.terran_unsealing_the_past_requirement, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_T.mission_name, + "Third Stasis Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12704, + LocationType.EXTRA, + logic.terran_unsealing_the_past_requirement, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_T.mission_name, + "Fourth Stasis Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12705, + LocationType.EXTRA, + logic.terran_unsealing_the_past_requirement, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_T.mission_name, + "South Power Core", + SC2_RACESWAP_LOC_ID_OFFSET + 12706, + LocationType.VANILLA, + lambda state: ( + logic.terran_unsealing_the_past_requirement(state) + and ( + adv_tactics + or logic.terran_air(state) + or state.has_all( + {item_names.GOLIATH, item_names.GOLIATH_JUMP_JETS}, player + ) + ) + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_T.mission_name, + "East Power Core", + SC2_RACESWAP_LOC_ID_OFFSET + 12707, + LocationType.VANILLA, + lambda state: ( + logic.terran_unsealing_the_past_requirement(state) + and ( + adv_tactics + or logic.terran_air(state) + or state.has_all( + {item_names.GOLIATH, item_names.GOLIATH_JUMP_JETS}, player + ) + ) + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 12800, + LocationType.VICTORY, + logic.zerg_unsealing_the_past_requirement, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_Z.mission_name, + "Zerg Cleared", + SC2_RACESWAP_LOC_ID_OFFSET + 12801, + LocationType.EXTRA, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_Z.mission_name, + "First Stasis Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12802, + LocationType.EXTRA, + lambda state: ( + logic.advanced_tactics + or logic.zerg_unsealing_the_past_requirement(state) + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_Z.mission_name, + "Second Stasis Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12803, + LocationType.EXTRA, + logic.zerg_unsealing_the_past_requirement, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_Z.mission_name, + "Third Stasis Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12804, + LocationType.EXTRA, + logic.zerg_unsealing_the_past_requirement, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_Z.mission_name, + "Fourth Stasis Lock", + SC2_RACESWAP_LOC_ID_OFFSET + 12805, + LocationType.EXTRA, + logic.zerg_unsealing_the_past_requirement, + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_Z.mission_name, + "South Power Core", + SC2_RACESWAP_LOC_ID_OFFSET + 12806, + LocationType.VANILLA, + lambda state: ( + logic.zerg_unsealing_the_past_requirement(state) + and ( + adv_tactics + or ( + state.has(item_names.MUTALISK, player) + or logic.morph_brood_lord(state) + or logic.morph_guardian(state) + ) + ) + ), + ), + make_location_data( + SC2Mission.UNSEALING_THE_PAST_Z.mission_name, + "East Power Core", + SC2_RACESWAP_LOC_ID_OFFSET + 12807, + LocationType.VANILLA, + lambda state: ( + logic.zerg_unsealing_the_past_requirement(state) + and ( + adv_tactics + or ( + state.has(item_names.MUTALISK, player) + or logic.morph_brood_lord(state) + or logic.morph_guardian(state) + ) + ) + ), + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 12900, + LocationType.VICTORY, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "North Sector: West Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12901, + LocationType.VANILLA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "North Sector: Northeast Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12902, + LocationType.EXTRA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "North Sector: Southeast Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12903, + LocationType.EXTRA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "South Sector: West Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12904, + LocationType.VANILLA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "South Sector: North Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12905, + LocationType.EXTRA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "South Sector: East Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12906, + LocationType.EXTRA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "West Sector: West Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12907, + LocationType.VANILLA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "West Sector: Mid Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12908, + LocationType.EXTRA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "West Sector: East Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12909, + LocationType.EXTRA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "East Sector: North Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12910, + LocationType.VANILLA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "East Sector: West Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12911, + LocationType.EXTRA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "East Sector: South Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 12912, + LocationType.EXTRA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_T.mission_name, + "Purifier Warden", + SC2_RACESWAP_LOC_ID_OFFSET + 12913, + LocationType.VANILLA, + logic.terran_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 13000, + LocationType.VICTORY, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "North Sector: West Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13001, + LocationType.VANILLA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "North Sector: Northeast Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13002, + LocationType.EXTRA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "North Sector: Southeast Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13003, + LocationType.EXTRA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "South Sector: West Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13004, + LocationType.VANILLA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "South Sector: North Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13005, + LocationType.EXTRA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "South Sector: East Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13006, + LocationType.EXTRA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "West Sector: West Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13007, + LocationType.VANILLA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "West Sector: Mid Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13008, + LocationType.EXTRA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "West Sector: East Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13009, + LocationType.EXTRA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "East Sector: North Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13010, + LocationType.VANILLA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "East Sector: West Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13011, + LocationType.EXTRA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "East Sector: South Null Circuit", + SC2_RACESWAP_LOC_ID_OFFSET + 13012, + LocationType.EXTRA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.PURIFICATION_Z.mission_name, + "Purifier Warden", + SC2_RACESWAP_LOC_ID_OFFSET + 13013, + LocationType.VANILLA, + logic.zerg_purification_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 13100, + LocationType.VICTORY, + logic.terran_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_T.mission_name, + "First Terrazine Fog", + SC2_RACESWAP_LOC_ID_OFFSET + 13101, + LocationType.EXTRA, + logic.terran_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_T.mission_name, + "Southwest Guardian", + SC2_RACESWAP_LOC_ID_OFFSET + 13102, + LocationType.EXTRA, + logic.terran_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_T.mission_name, + "West Guardian", + SC2_RACESWAP_LOC_ID_OFFSET + 13103, + LocationType.EXTRA, + logic.terran_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_T.mission_name, + "Northwest Guardian", + SC2_RACESWAP_LOC_ID_OFFSET + 13104, + LocationType.EXTRA, + logic.terran_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_T.mission_name, + "Northeast Guardian", + SC2_RACESWAP_LOC_ID_OFFSET + 13105, + LocationType.EXTRA, + logic.terran_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_T.mission_name, + "North Mothership", + SC2_RACESWAP_LOC_ID_OFFSET + 13106, + LocationType.VANILLA, + logic.terran_steps_of_the_rite_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_T.mission_name, + "South Mothership", + SC2_RACESWAP_LOC_ID_OFFSET + 13107, + LocationType.VANILLA, + logic.terran_steps_of_the_rite_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 13200, + LocationType.VICTORY, + logic.zerg_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_Z.mission_name, + "First Terrazine Fog", + SC2_RACESWAP_LOC_ID_OFFSET + 13201, + LocationType.EXTRA, + logic.zerg_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_Z.mission_name, + "Southwest Guardian", + SC2_RACESWAP_LOC_ID_OFFSET + 13202, + LocationType.EXTRA, + logic.zerg_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_Z.mission_name, + "West Guardian", + SC2_RACESWAP_LOC_ID_OFFSET + 13203, + LocationType.EXTRA, + logic.zerg_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_Z.mission_name, + "Northwest Guardian", + SC2_RACESWAP_LOC_ID_OFFSET + 13204, + LocationType.EXTRA, + logic.zerg_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_Z.mission_name, + "Northeast Guardian", + SC2_RACESWAP_LOC_ID_OFFSET + 13205, + LocationType.EXTRA, + logic.zerg_steps_of_the_rite_requirement, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_Z.mission_name, + "North Mothership", + SC2_RACESWAP_LOC_ID_OFFSET + 13206, + LocationType.VANILLA, + logic.zerg_steps_of_the_rite_requirement, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.STEPS_OF_THE_RITE_Z.mission_name, + "South Mothership", + SC2_RACESWAP_LOC_ID_OFFSET + 13207, + LocationType.VANILLA, + logic.zerg_steps_of_the_rite_requirement, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.RAK_SHIR_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 13300, + LocationType.VICTORY, + logic.terran_rak_shir_requirement, + ), + make_location_data( + SC2Mission.RAK_SHIR_T.mission_name, + "North Slayn Elemental", + SC2_RACESWAP_LOC_ID_OFFSET + 13301, + LocationType.VANILLA, + logic.terran_rak_shir_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.RAK_SHIR_T.mission_name, + "Southwest Slayn Elemental", + SC2_RACESWAP_LOC_ID_OFFSET + 13302, + LocationType.VANILLA, + logic.terran_rak_shir_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.RAK_SHIR_T.mission_name, + "East Slayn Elemental", + SC2_RACESWAP_LOC_ID_OFFSET + 13303, + LocationType.VANILLA, + logic.terran_rak_shir_requirement, + hard_rule=logic.terran_any_anti_air, + ), + make_location_data( + SC2Mission.RAK_SHIR_T.mission_name, + "Resource Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 13304, + LocationType.EXTRA, + logic.terran_rak_shir_requirement, + ), + make_location_data( + SC2Mission.RAK_SHIR_T.mission_name, + "Destroy Nexuses", + SC2_RACESWAP_LOC_ID_OFFSET + 13305, + LocationType.CHALLENGE, + logic.terran_rak_shir_requirement, + ), + make_location_data( + SC2Mission.RAK_SHIR_T.mission_name, + "Win in under 15 minutes", + SC2_RACESWAP_LOC_ID_OFFSET + 13306, + LocationType.MASTERY, + logic.terran_rak_shir_requirement, + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.RAK_SHIR_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 13400, + LocationType.VICTORY, + logic.zerg_rak_shir_requirement, + ), + make_location_data( + SC2Mission.RAK_SHIR_Z.mission_name, + "North Slayn Elemental", + SC2_RACESWAP_LOC_ID_OFFSET + 13401, + LocationType.VANILLA, + logic.zerg_rak_shir_requirement, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.RAK_SHIR_Z.mission_name, + "Southwest Slayn Elemental", + SC2_RACESWAP_LOC_ID_OFFSET + 13402, + LocationType.VANILLA, + logic.zerg_rak_shir_requirement, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.RAK_SHIR_Z.mission_name, + "East Slayn Elemental", + SC2_RACESWAP_LOC_ID_OFFSET + 13403, + LocationType.VANILLA, + logic.zerg_rak_shir_requirement, + hard_rule=logic.zerg_any_anti_air, + ), + make_location_data( + SC2Mission.RAK_SHIR_Z.mission_name, + "Resource Pickups", + SC2_RACESWAP_LOC_ID_OFFSET + 13404, + LocationType.EXTRA, + logic.zerg_rak_shir_requirement, + ), + make_location_data( + SC2Mission.RAK_SHIR_Z.mission_name, + "Destroy Nexuses", + SC2_RACESWAP_LOC_ID_OFFSET + 13405, + LocationType.CHALLENGE, + logic.zerg_rak_shir_requirement, + ), + make_location_data( + SC2Mission.RAK_SHIR_Z.mission_name, + "Win in under 15 minutes", + SC2_RACESWAP_LOC_ID_OFFSET + 13406, + LocationType.MASTERY, + logic.zerg_rak_shir_requirement, + flags=LocationFlag.SPEEDRUN, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 13500, + LocationType.VICTORY, + logic.terran_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_T.mission_name, + "Northwest Power Core", + SC2_RACESWAP_LOC_ID_OFFSET + 13501, + LocationType.EXTRA, + logic.terran_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_T.mission_name, + "Northeast Power Core", + SC2_RACESWAP_LOC_ID_OFFSET + 13502, + LocationType.EXTRA, + logic.terran_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_T.mission_name, + "Southeast Power Core", + SC2_RACESWAP_LOC_ID_OFFSET + 13503, + LocationType.EXTRA, + logic.terran_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_T.mission_name, + "West Hybrid Stasis Chamber", + SC2_RACESWAP_LOC_ID_OFFSET + 13504, + LocationType.VANILLA, + logic.terran_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_T.mission_name, + "Southeast Hybrid Stasis Chamber", + SC2_RACESWAP_LOC_ID_OFFSET + 13505, + LocationType.VANILLA, + lambda state: ( + logic.terran_templars_charge_requirement(state) + and logic.terran_air(state) + ), + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 13600, + LocationType.VICTORY, + logic.zerg_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_Z.mission_name, + "Northwest Power Core", + SC2_RACESWAP_LOC_ID_OFFSET + 13601, + LocationType.EXTRA, + logic.zerg_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_Z.mission_name, + "Northeast Power Core", + SC2_RACESWAP_LOC_ID_OFFSET + 13602, + LocationType.EXTRA, + logic.zerg_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_Z.mission_name, + "Southeast Power Core", + SC2_RACESWAP_LOC_ID_OFFSET + 13603, + LocationType.EXTRA, + logic.zerg_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_Z.mission_name, + "West Hybrid Stasis Chamber", + SC2_RACESWAP_LOC_ID_OFFSET + 13604, + LocationType.VANILLA, + logic.zerg_templars_charge_requirement, + ), + make_location_data( + SC2Mission.TEMPLAR_S_CHARGE_Z.mission_name, + "Southeast Hybrid Stasis Chamber", + SC2_RACESWAP_LOC_ID_OFFSET + 13605, + LocationType.VANILLA, + logic.zerg_templars_charge_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 13900, + LocationType.VICTORY, + logic.terran_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_T.mission_name, + "Southeast Void Shard", + SC2_RACESWAP_LOC_ID_OFFSET + 13901, + LocationType.EXTRA, + logic.terran_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_T.mission_name, + "South Void Shard", + SC2_RACESWAP_LOC_ID_OFFSET + 13902, + LocationType.EXTRA, + logic.terran_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_T.mission_name, + "Southwest Void Shard", + SC2_RACESWAP_LOC_ID_OFFSET + 13903, + LocationType.EXTRA, + logic.terran_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_T.mission_name, + "North Void Shard", + SC2_RACESWAP_LOC_ID_OFFSET + 13904, + LocationType.EXTRA, + logic.terran_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_T.mission_name, + "Northwest Void Shard", + SC2_RACESWAP_LOC_ID_OFFSET + 13905, + LocationType.EXTRA, + logic.terran_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_T.mission_name, + "Nerazim Warp in Zone", + SC2_RACESWAP_LOC_ID_OFFSET + 13906, + LocationType.VANILLA, + logic.terran_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_T.mission_name, + "Tal'darim Warp in Zone", + SC2_RACESWAP_LOC_ID_OFFSET + 13907, + LocationType.VANILLA, + logic.terran_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_T.mission_name, + "Purifier Warp in Zone", + SC2_RACESWAP_LOC_ID_OFFSET + 13908, + LocationType.VANILLA, + logic.terran_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 14000, + LocationType.VICTORY, + logic.zerg_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_Z.mission_name, + "Southeast Void Shard", + SC2_RACESWAP_LOC_ID_OFFSET + 14001, + LocationType.EXTRA, + logic.zerg_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_Z.mission_name, + "South Void Shard", + SC2_RACESWAP_LOC_ID_OFFSET + 14002, + LocationType.EXTRA, + logic.zerg_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_Z.mission_name, + "Southwest Void Shard", + SC2_RACESWAP_LOC_ID_OFFSET + 14003, + LocationType.EXTRA, + logic.zerg_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_Z.mission_name, + "North Void Shard", + SC2_RACESWAP_LOC_ID_OFFSET + 14004, + LocationType.EXTRA, + logic.zerg_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_Z.mission_name, + "Northwest Void Shard", + SC2_RACESWAP_LOC_ID_OFFSET + 14005, + LocationType.EXTRA, + logic.zerg_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_Z.mission_name, + "Nerazim Warp in Zone", + SC2_RACESWAP_LOC_ID_OFFSET + 14006, + LocationType.VANILLA, + logic.zerg_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_Z.mission_name, + "Tal'darim Warp in Zone", + SC2_RACESWAP_LOC_ID_OFFSET + 14007, + LocationType.VANILLA, + logic.zerg_the_host_requirement, + ), + make_location_data( + SC2Mission.THE_HOST_Z.mission_name, + "Purifier Warp in Zone", + SC2_RACESWAP_LOC_ID_OFFSET + 14008, + LocationType.VANILLA, + logic.zerg_the_host_requirement, + ), + make_location_data( + SC2Mission.SALVATION_T.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 14100, + LocationType.VICTORY, + logic.terran_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_T.mission_name, + "Fabrication Matrix", + SC2_RACESWAP_LOC_ID_OFFSET + 14101, + LocationType.EXTRA, + logic.terran_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_T.mission_name, + "Assault Cluster", + SC2_RACESWAP_LOC_ID_OFFSET + 14102, + LocationType.EXTRA, + logic.terran_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_T.mission_name, + "Hull Breach", + SC2_RACESWAP_LOC_ID_OFFSET + 14103, + LocationType.EXTRA, + logic.terran_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_T.mission_name, + "Core Critical", + SC2_RACESWAP_LOC_ID_OFFSET + 14104, + LocationType.EXTRA, + logic.terran_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_T.mission_name, + "Kill Brutalisk", + SC2_RACESWAP_LOC_ID_OFFSET + 14105, + LocationType.MASTERY, + logic.terran_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_Z.mission_name, + "Victory", + SC2_RACESWAP_LOC_ID_OFFSET + 14200, + LocationType.VICTORY, + logic.zerg_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_Z.mission_name, + "Fabrication Matrix", + SC2_RACESWAP_LOC_ID_OFFSET + 14201, + LocationType.EXTRA, + logic.zerg_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_Z.mission_name, + "Assault Cluster", + SC2_RACESWAP_LOC_ID_OFFSET + 14202, + LocationType.EXTRA, + logic.zerg_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_Z.mission_name, + "Hull Breach", + SC2_RACESWAP_LOC_ID_OFFSET + 14203, + LocationType.EXTRA, + logic.zerg_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_Z.mission_name, + "Core Critical", + SC2_RACESWAP_LOC_ID_OFFSET + 14204, + LocationType.EXTRA, + logic.zerg_salvation_requirement, + ), + make_location_data( + SC2Mission.SALVATION_Z.mission_name, + "Kill Brutalisk", + SC2_RACESWAP_LOC_ID_OFFSET + 14205, + LocationType.MASTERY, + logic.zerg_salvation_requirement, + ), + ] + + # Filtering out excluded locations + if world is not None: + excluded_location_types = get_location_types( + world, LocationInclusion.option_disabled + ) + excluded_location_flags = get_location_flags( + world, LocationInclusion.option_disabled + ) + chance_location_types = get_location_types( + world, LocationInclusion.option_half_chance + ) + chance_location_flags = get_location_flags( + world, LocationInclusion.option_half_chance + ) + plando_locations = get_plando_locations(world) + exclude_locations = world.options.exclude_locations.value + + def include_location(location: LocationData) -> bool: + if location.type is LocationType.VICTORY: + return True + if location.name in plando_locations: + return True + if location.name in exclude_locations: + return False + if location.flags & excluded_location_flags: + return False + if location.type in excluded_location_types: + return False + if location.flags & chance_location_flags: + if world.random.random() < 0.5: + return False + if location.type in chance_location_types: + if world.random.random() < 0.5: + return False + return True + + location_table = [ + location for location in location_table if include_location(location) + ] + beat_events: List[LocationData] = [] + victory_caches: List[LocationData] = [] + VICTORY_CACHE_SIZE = 10 + for location_data in location_table: + # Generating Beat event and Victory Cache locations + if location_data.type == LocationType.VICTORY: + beat_events.append( + location_data._replace(name="Beat " + location_data.region, code=None) # type: ignore + ) + for v in range(VICTORY_CACHE_SIZE): + victory_caches.append( + location_data._replace( + name=location_data.name + f" Cache ({v + 1})", + code=location_data.code + VICTORY_CACHE_OFFSET + v, + type=LocationType.VICTORY_CACHE, + ) + ) + + return tuple(location_table + beat_events + victory_caches) + + +DEFAULT_LOCATION_LIST = get_locations(None) +"""A location table with `None` as the input world; does not contain logic rules""" + +lookup_location_id_to_type = { + loc.code: loc.type for loc in DEFAULT_LOCATION_LIST if loc.code is not None +} +lookup_location_id_to_flags = { + loc.code: loc.flags for loc in DEFAULT_LOCATION_LIST if loc.code is not None +} diff --git a/worlds/sc2/mission_groups.py b/worlds/sc2/mission_groups.py new file mode 100644 index 000000000000..de6e7d349caf --- /dev/null +++ b/worlds/sc2/mission_groups.py @@ -0,0 +1,194 @@ +""" +Mission group aliases for use in yaml options. +""" + +from typing import Dict, List, Set +from .mission_tables import SC2Mission, MissionFlag, SC2Campaign + + +class MissionGroupNames: + ALL_MISSIONS = "All Missions" + WOL_MISSIONS = "WoL Missions" + HOTS_MISSIONS = "HotS Missions" + LOTV_MISSIONS = "LotV Missions" + NCO_MISSIONS = "NCO Missions" + PROPHECY_MISSIONS = "Prophecy Missions" + PROLOGUE_MISSIONS = "Prologue Missions" + EPILOGUE_MISSIONS = "Epilogue Missions" + + TERRAN_MISSIONS = "Terran Missions" + ZERG_MISSIONS = "Zerg Missions" + PROTOSS_MISSIONS = "Protoss Missions" + NOBUILD_MISSIONS = "No-Build Missions" + DEFENSE_MISSIONS = "Defense Missions" + AUTO_SCROLLER_MISSIONS = "Auto-Scroller Missions" + COUNTDOWN_MISSIONS = "Countdown Missions" + KERRIGAN_MISSIONS = "Kerrigan Missions" + VANILLA_SOA_MISSIONS = "Vanilla SOA Missions" + TERRAN_ALLY_MISSIONS = "Controllable Terran Ally Missions" + ZERG_ALLY_MISSIONS = "Controllable Zerg Ally Missions" + PROTOSS_ALLY_MISSIONS = "Controllable Protoss Ally Missions" + VS_TERRAN_MISSIONS = "Vs Terran Missions" + VS_ZERG_MISSIONS = "Vs Zerg Missions" + VS_PROTOSS_MISSIONS = "Vs Protoss Missions" + RACESWAP_MISSIONS = "Raceswap Missions" + + # By planet + PLANET_MAR_SARA_MISSIONS = "Planet Mar Sara" + PLANET_CHAR_MISSIONS = "Planet Char" + PLANET_KORHAL_MISSIONS = "Planet Korhal" + PLANET_AIUR_MISSIONS = "Planet Aiur" + + # By quest chain + WOL_MAR_SARA_MISSIONS = "WoL Mar Sara" + WOL_COLONIST_MISSIONS = "WoL Colonist" + WOL_ARTIFACT_MISSIONS = "WoL Artifact" + WOL_COVERT_MISSIONS = "WoL Covert" + WOL_REBELLION_MISSIONS = "WoL Rebellion" + WOL_CHAR_MISSIONS = "WoL Char" + + HOTS_UMOJA_MISSIONS = "HotS Umoja" + HOTS_KALDIR_MISSIONS = "HotS Kaldir" + HOTS_CHAR_MISSIONS = "HotS Char" + HOTS_ZERUS_MISSIONS = "HotS Zerus" + HOTS_SKYGEIRR_MISSIONS = "HotS Skygeirr Station" + HOTS_DOMINION_SPACE_MISSIONS = "HotS Dominion Space" + HOTS_KORHAL_MISSIONS = "HotS Korhal" + + LOTV_AIUR_MISSIONS = "LotV Aiur" + LOTV_KORHAL_MISSIONS = "LotV Korhal" + LOTV_SHAKURAS_MISSIONS = "LotV Shakuras" + LOTV_ULNAR_MISSIONS = "LotV Ulnar" + LOTV_PURIFIER_MISSIONS = "LotV Purifier" + LOTV_TALDARIM_MISSIONS = "LotV Tal'darim" + LOTV_MOEBIUS_MISSIONS = "LotV Moebius" + LOTV_RETURN_TO_AIUR_MISSIONS = "LotV Return to Aiur" + + NCO_MISSION_PACK_1 = "NCO Mission Pack 1" + NCO_MISSION_PACK_2 = "NCO Mission Pack 2" + NCO_MISSION_PACK_3 = "NCO Mission Pack 3" + + @classmethod + def get_all_group_names(cls) -> Set[str]: + return { + name + for identifier, name in cls.__dict__.items() + if not identifier.startswith("_") and not identifier.startswith("get_") + } + + +mission_groups: Dict[str, List[str]] = {} + +mission_groups[MissionGroupNames.ALL_MISSIONS] = [mission.mission_name for mission in SC2Mission] +for group_name, campaign in ( + (MissionGroupNames.WOL_MISSIONS, SC2Campaign.WOL), + (MissionGroupNames.HOTS_MISSIONS, SC2Campaign.HOTS), + (MissionGroupNames.LOTV_MISSIONS, SC2Campaign.LOTV), + (MissionGroupNames.NCO_MISSIONS, SC2Campaign.NCO), + (MissionGroupNames.PROPHECY_MISSIONS, SC2Campaign.PROPHECY), + (MissionGroupNames.PROLOGUE_MISSIONS, SC2Campaign.PROLOGUE), + (MissionGroupNames.EPILOGUE_MISSIONS, SC2Campaign.EPILOGUE), +): + mission_groups[group_name] = [mission.mission_name for mission in SC2Mission if mission.campaign == campaign] + +for group_name, flags in ( + (MissionGroupNames.TERRAN_MISSIONS, MissionFlag.Terran), + (MissionGroupNames.ZERG_MISSIONS, MissionFlag.Zerg), + (MissionGroupNames.PROTOSS_MISSIONS, MissionFlag.Protoss), + (MissionGroupNames.NOBUILD_MISSIONS, MissionFlag.NoBuild), + (MissionGroupNames.DEFENSE_MISSIONS, MissionFlag.Defense), + (MissionGroupNames.AUTO_SCROLLER_MISSIONS, MissionFlag.AutoScroller), + (MissionGroupNames.COUNTDOWN_MISSIONS, MissionFlag.Countdown), + (MissionGroupNames.KERRIGAN_MISSIONS, MissionFlag.Kerrigan), + (MissionGroupNames.VANILLA_SOA_MISSIONS, MissionFlag.VanillaSoa), + (MissionGroupNames.TERRAN_ALLY_MISSIONS, MissionFlag.AiTerranAlly), + (MissionGroupNames.ZERG_ALLY_MISSIONS, MissionFlag.AiZergAlly), + (MissionGroupNames.PROTOSS_ALLY_MISSIONS, MissionFlag.AiProtossAlly), + (MissionGroupNames.VS_TERRAN_MISSIONS, MissionFlag.VsTerran), + (MissionGroupNames.VS_ZERG_MISSIONS, MissionFlag.VsZerg), + (MissionGroupNames.VS_PROTOSS_MISSIONS, MissionFlag.VsProtoss), + (MissionGroupNames.RACESWAP_MISSIONS, MissionFlag.RaceSwap), +): + mission_groups[group_name] = [mission.mission_name for mission in SC2Mission if flags in mission.flags] + +for group_name, campaign, chain_name in ( + (MissionGroupNames.WOL_MAR_SARA_MISSIONS, SC2Campaign.WOL, "Mar Sara"), + (MissionGroupNames.WOL_COLONIST_MISSIONS, SC2Campaign.WOL, "Colonist"), + (MissionGroupNames.WOL_ARTIFACT_MISSIONS, SC2Campaign.WOL, "Artifact"), + (MissionGroupNames.WOL_COVERT_MISSIONS, SC2Campaign.WOL, "Covert"), + (MissionGroupNames.WOL_REBELLION_MISSIONS, SC2Campaign.WOL, "Rebellion"), + (MissionGroupNames.WOL_CHAR_MISSIONS, SC2Campaign.WOL, "Char"), + (MissionGroupNames.HOTS_UMOJA_MISSIONS, SC2Campaign.HOTS, "Umoja"), + (MissionGroupNames.HOTS_KALDIR_MISSIONS, SC2Campaign.HOTS, "Kaldir"), + (MissionGroupNames.HOTS_CHAR_MISSIONS, SC2Campaign.HOTS, "Char"), + (MissionGroupNames.HOTS_ZERUS_MISSIONS, SC2Campaign.HOTS, "Zerus"), + (MissionGroupNames.HOTS_SKYGEIRR_MISSIONS, SC2Campaign.HOTS, "Skygeirr Station"), + (MissionGroupNames.HOTS_DOMINION_SPACE_MISSIONS, SC2Campaign.HOTS, "Dominion Space"), + (MissionGroupNames.HOTS_KORHAL_MISSIONS, SC2Campaign.HOTS, "Korhal"), + (MissionGroupNames.LOTV_AIUR_MISSIONS, SC2Campaign.LOTV, "Aiur"), + (MissionGroupNames.LOTV_KORHAL_MISSIONS, SC2Campaign.LOTV, "Korhal"), + (MissionGroupNames.LOTV_SHAKURAS_MISSIONS, SC2Campaign.LOTV, "Shakuras"), + (MissionGroupNames.LOTV_ULNAR_MISSIONS, SC2Campaign.LOTV, "Ulnar"), + (MissionGroupNames.LOTV_PURIFIER_MISSIONS, SC2Campaign.LOTV, "Purifier"), + (MissionGroupNames.LOTV_TALDARIM_MISSIONS, SC2Campaign.LOTV, "Tal'darim"), + (MissionGroupNames.LOTV_MOEBIUS_MISSIONS, SC2Campaign.LOTV, "Moebius"), + (MissionGroupNames.LOTV_RETURN_TO_AIUR_MISSIONS, SC2Campaign.LOTV, "Return to Aiur"), +): + mission_groups[group_name] = [ + mission.mission_name for mission in SC2Mission if mission.campaign == campaign and mission.area == chain_name + ] + +mission_groups[MissionGroupNames.NCO_MISSION_PACK_1] = [ + SC2Mission.THE_ESCAPE.mission_name, + SC2Mission.SUDDEN_STRIKE.mission_name, + SC2Mission.ENEMY_INTELLIGENCE.mission_name, +] +mission_groups[MissionGroupNames.NCO_MISSION_PACK_2] = [ + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + SC2Mission.NIGHT_TERRORS.mission_name, + SC2Mission.FLASHPOINT.mission_name, +] +mission_groups[MissionGroupNames.NCO_MISSION_PACK_3] = [ + SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name, + SC2Mission.DARK_SKIES.mission_name, + SC2Mission.END_GAME.mission_name, +] + +mission_groups[MissionGroupNames.PLANET_MAR_SARA_MISSIONS] = [ + SC2Mission.LIBERATION_DAY.mission_name, + SC2Mission.THE_OUTLAWS.mission_name, + SC2Mission.ZERO_HOUR.mission_name, +] +mission_groups[MissionGroupNames.PLANET_CHAR_MISSIONS] = [ + SC2Mission.GATES_OF_HELL.mission_name, + SC2Mission.BELLY_OF_THE_BEAST.mission_name, + SC2Mission.SHATTER_THE_SKY.mission_name, + SC2Mission.ALL_IN.mission_name, + SC2Mission.DOMINATION.mission_name, + SC2Mission.FIRE_IN_THE_SKY.mission_name, + SC2Mission.OLD_SOLDIERS.mission_name, +] +mission_groups[MissionGroupNames.PLANET_KORHAL_MISSIONS] = [ + SC2Mission.MEDIA_BLITZ.mission_name, + SC2Mission.PLANETFALL.mission_name, + SC2Mission.DEATH_FROM_ABOVE.mission_name, + SC2Mission.THE_RECKONING.mission_name, + SC2Mission.SKY_SHIELD.mission_name, + SC2Mission.BROTHERS_IN_ARMS.mission_name, +] +mission_groups[MissionGroupNames.PLANET_AIUR_MISSIONS] = [ + SC2Mission.ECHOES_OF_THE_FUTURE.mission_name, + SC2Mission.FOR_AIUR.mission_name, + SC2Mission.THE_GROWING_SHADOW.mission_name, + SC2Mission.THE_SPEAR_OF_ADUN.mission_name, + SC2Mission.TEMPLAR_S_RETURN.mission_name, + SC2Mission.THE_HOST.mission_name, + SC2Mission.SALVATION.mission_name, +] + +for mission in SC2Mission: + if mission.flags & MissionFlag.HasRaceSwap: + short_name = mission.get_short_name() + mission_groups[short_name] = [ + mission_var.mission_name for mission_var in SC2Mission if short_name in mission_var.mission_name + ] diff --git a/worlds/sc2/mission_order/__init__.py b/worlds/sc2/mission_order/__init__.py new file mode 100644 index 000000000000..ec533ccdd93e --- /dev/null +++ b/worlds/sc2/mission_order/__init__.py @@ -0,0 +1,66 @@ +from typing import List, Dict, Any, Callable, TYPE_CHECKING + +from BaseClasses import CollectionState +from ..mission_tables import SC2Mission, MissionFlag, get_goal_location +from .mission_pools import SC2MOGenMissionPools + +if TYPE_CHECKING: + from .nodes import SC2MOGenMissionOrder, SC2MOGenMission + +class SC2MissionOrder: + """ + Wrapper class for a generated mission order. Contains helper functions for getting data about generated missions. + """ + + def __init__(self, mission_order_node: 'SC2MOGenMissionOrder', mission_pools: SC2MOGenMissionPools): + self.mission_order_node: 'SC2MOGenMissionOrder' = mission_order_node + """Root node of the mission order structure.""" + self.mission_pools: SC2MOGenMissionPools = mission_pools + """Manager for missions in the mission order.""" + + def get_used_flags(self) -> Dict[MissionFlag, int]: + """Returns a dictionary of all used flags and their appearance count within the mission order. + Flags that don't appear in the mission order also don't appear in this dictionary.""" + return self.mission_pools.get_used_flags() + + def get_used_missions(self) -> List[SC2Mission]: + """Returns a list of all missions used in the mission order.""" + return self.mission_pools.get_used_missions() + + def get_mission_count(self) -> int: + """Returns the amount of missions in the mission order.""" + return sum( + len([mission for mission in layout.missions if not mission.option_empty]) + for campaign in self.mission_order_node.campaigns for layout in campaign.layouts + ) + + def get_starting_missions(self) -> List[SC2Mission]: + """Returns a list containing all the missions that are accessible without beating any other missions.""" + return [ + slot.mission + for campaign in self.mission_order_node.campaigns if campaign.is_always_unlocked() + for layout in campaign.layouts if layout.is_always_unlocked() + for slot in layout.missions if slot.is_always_unlocked() and not slot.option_empty + ] + + def get_completion_condition(self, player: int) -> Callable[[CollectionState], bool]: + """Returns a lambda to determine whether a state has beaten the mission order's required campaigns.""" + final_locations = [get_goal_location(mission.mission) for mission in self.get_final_missions()] + return lambda state, final_locations=final_locations: all(state.can_reach_location(loc, player) for loc in final_locations) + + def get_final_mission_ids(self) -> List[int]: + """Returns the IDs of all missions that are required to beat the mission order.""" + return [mission.mission.id for mission in self.get_final_missions()] + + def get_final_missions(self) -> List['SC2MOGenMission']: + """Returns the slots of all missions that are required to beat the mission order.""" + return self.mission_order_node.goal_missions + + def get_items_to_lock(self) -> Dict[str, int]: + """Returns a dict of item names and amounts that are required by Item entry rules.""" + return self.mission_order_node.items_to_lock + + def get_slot_data(self) -> List[Dict[str, Any]]: + """Parses the mission order into a format usable for slot data.""" + return self.mission_order_node.get_slot_data() + diff --git a/worlds/sc2/mission_order/entry_rules.py b/worlds/sc2/mission_order/entry_rules.py new file mode 100644 index 000000000000..cb3afb372750 --- /dev/null +++ b/worlds/sc2/mission_order/entry_rules.py @@ -0,0 +1,389 @@ +from __future__ import annotations +from typing import Set, Callable, Dict, List, Union, TYPE_CHECKING, Any, NamedTuple +from abc import ABC, abstractmethod +from dataclasses import dataclass + +from ..mission_tables import SC2Mission +from ..item.item_tables import item_table +from BaseClasses import CollectionState + +if TYPE_CHECKING: + from .nodes import SC2MOGenMission + + +class EntryRule(ABC): + buffer_fulfilled: bool + buffer_depth: int + + def __init__(self) -> None: + self.buffer_fulfilled = False + self.buffer_depth = -1 + + def is_always_fulfilled(self, in_region_creation: bool = False) -> bool: + return self.is_fulfilled(set(), in_region_creation) + + @abstractmethod + def _is_fulfilled(self, beaten_missions: Set[SC2MOGenMission], in_region_creation: bool) -> bool: + """Used during region creation to ensure a beatable mission order. + + `in_region_creation` should determine whether rules that cannot be handled during region creation (like Item rules) + report themselves as fulfilled or unfulfilled.""" + return False + + def is_fulfilled(self, beaten_missions: Set[SC2MOGenMission], in_region_creation: bool) -> bool: + if len(beaten_missions) == 0: + # Special-cased to avoid the buffer + # This is used to determine starting missions + return self._is_fulfilled(beaten_missions, in_region_creation) + self.buffer_fulfilled = self.buffer_fulfilled or self._is_fulfilled(beaten_missions, in_region_creation) + return self.buffer_fulfilled + + @abstractmethod + def _get_depth(self, beaten_missions: Set[SC2MOGenMission]) -> int: + """Used during region creation to determine the minimum depth this entry rule can be cleared at.""" + return -1 + + def get_depth(self, beaten_missions: Set[SC2MOGenMission]) -> int: + if not self.is_fulfilled(beaten_missions, in_region_creation = True): + return -1 + if self.buffer_depth == -1: + self.buffer_depth = self._get_depth(beaten_missions) + return self.buffer_depth + + @abstractmethod + def to_lambda(self, player: int) -> Callable[[CollectionState], bool]: + """Passed to Archipelago for use during item placement.""" + return lambda _: False + + @abstractmethod + def to_slot_data(self) -> RuleData: + """Used in the client to determine accessibility while playing and to populate tooltips.""" + pass + + +@dataclass +class RuleData(ABC): + @abstractmethod + def tooltip(self, indents: int, missions: Dict[int, SC2Mission], done_color: str, not_done_color: str) -> str: + return "" + + @abstractmethod + def shows_single_rule(self) -> bool: + return False + + @abstractmethod + def is_accessible( + self, beaten_missions: Set[int], received_items: Dict[int, int] + ) -> bool: + return False + + +class BeatMissionsEntryRule(EntryRule): + missions_to_beat: List[SC2MOGenMission] + visual_reqs: List[Union[str, SC2MOGenMission]] + + def __init__(self, missions_to_beat: List[SC2MOGenMission], visual_reqs: List[Union[str, SC2MOGenMission]]): + super().__init__() + self.missions_to_beat = missions_to_beat + self.visual_reqs = visual_reqs + + def _is_fulfilled(self, beaten_missions: Set[SC2MOGenMission], in_region_check: bool) -> bool: + return beaten_missions.issuperset(self.missions_to_beat) + + def _get_depth(self, beaten_missions: Set[SC2MOGenMission]) -> int: + return max(mission.min_depth for mission in self.missions_to_beat) + + def to_lambda(self, player: int) -> Callable[[CollectionState], bool]: + return lambda state: state.has_all([mission.beat_item() for mission in self.missions_to_beat], player) + + def to_slot_data(self) -> RuleData: + resolved_reqs: List[Union[str, int]] = [req if isinstance(req, str) else req.mission.id for req in self.visual_reqs] + mission_ids = [mission.mission.id for mission in self.missions_to_beat] + return BeatMissionsRuleData( + mission_ids, + resolved_reqs + ) + + +@dataclass +class BeatMissionsRuleData(RuleData): + mission_ids: List[int] + visual_reqs: List[Union[str, int]] + + def tooltip(self, indents: int, missions: Dict[int, SC2Mission], done_color: str, not_done_color: str) -> str: + indent = " ".join("" for _ in range(indents)) + if len(self.visual_reqs) == 1: + req = self.visual_reqs[0] + return f"Beat {missions[req].mission_name if isinstance(req, int) else req}" + tooltip = f"Beat all of these:\n{indent}- " + reqs = [missions[req].mission_name if isinstance(req, int) else req for req in self.visual_reqs] + tooltip += f"\n{indent}- ".join(req for req in reqs) + return tooltip + + def shows_single_rule(self) -> bool: + return len(self.visual_reqs) == 1 + + def is_accessible( + self, beaten_missions: Set[int], received_items: Dict[int, int] + ) -> bool: + # Beat rules are accessible if all their missions are beaten and accessible + if not beaten_missions.issuperset(self.mission_ids): + return False + return True + + +class CountMissionsEntryRule(EntryRule): + missions_to_count: List[SC2MOGenMission] + target_amount: int + visual_reqs: List[Union[str, SC2MOGenMission]] + + def __init__(self, missions_to_count: List[SC2MOGenMission], target_amount: int, visual_reqs: List[Union[str, SC2MOGenMission]]): + super().__init__() + self.missions_to_count = missions_to_count + if target_amount == -1 or target_amount > len(missions_to_count): + self.target_amount = len(missions_to_count) + else: + self.target_amount = target_amount + self.visual_reqs = visual_reqs + + def _is_fulfilled(self, beaten_missions: Set[SC2MOGenMission], in_region_check: bool) -> bool: + return self.target_amount <= len(beaten_missions.intersection(self.missions_to_count)) + + def _get_depth(self, beaten_missions: Set[SC2MOGenMission]) -> int: + sorted_missions = sorted(beaten_missions.intersection(self.missions_to_count), key = lambda mission: mission.min_depth) + mission_depth = max(mission.min_depth for mission in sorted_missions[:self.target_amount]) + return max(mission_depth, self.target_amount - 1) # -1 because depth is zero-based but amount is one-based + + def to_lambda(self, player: int) -> Callable[[CollectionState], bool]: + return lambda state: self.target_amount <= sum(state.has(mission.beat_item(), player) for mission in self.missions_to_count) + + def to_slot_data(self) -> RuleData: + resolved_reqs: List[Union[str, int]] = [req if isinstance(req, str) else req.mission.id for req in self.visual_reqs] + mission_ids = [mission.mission.id for mission in sorted(self.missions_to_count, key = lambda mission: mission.min_depth)] + return CountMissionsRuleData( + mission_ids, + self.target_amount, + resolved_reqs + ) + + +@dataclass +class CountMissionsRuleData(RuleData): + mission_ids: List[int] + amount: int + visual_reqs: List[Union[str, int]] + + def tooltip(self, indents: int, missions: Dict[int, SC2Mission], done_color: str, not_done_color: str) -> str: + indent = " ".join("" for _ in range(indents)) + if self.amount == len(self.mission_ids): + amount = "all" + else: + amount = str(self.amount) + if len(self.visual_reqs) == 1: + req = self.visual_reqs[0] + req_str = missions[req].mission_name if isinstance(req, int) else req + if self.amount == 1: + if type(req) == int: + return f"Beat {req_str}" + return f"Beat any mission from {req_str}" + return f"Beat {amount} missions from {req_str}" + if self.amount == 1: + tooltip = f"Beat any mission from:\n{indent}- " + else: + tooltip = f"Beat {amount} missions from:\n{indent}- " + reqs = [missions[req].mission_name if isinstance(req, int) else req for req in self.visual_reqs] + tooltip += f"\n{indent}- ".join(req for req in reqs) + return tooltip + + def shows_single_rule(self) -> bool: + return len(self.visual_reqs) == 1 + + def is_accessible( + self, beaten_missions: Set[int], received_items: Dict[int, int] + ) -> bool: + # Count rules are accessible if enough of their missions are beaten and accessible + return len([mission_id for mission_id in self.mission_ids if mission_id in beaten_missions]) >= self.amount + + +class SubRuleEntryRule(EntryRule): + rule_id: int + rules_to_check: List[EntryRule] + target_amount: int + min_depth: int + + def __init__(self, rules_to_check: List[EntryRule], target_amount: int, rule_id: int): + super().__init__() + self.rule_id = rule_id + self.rules_to_check = rules_to_check + self.min_depth = -1 + if target_amount == -1 or target_amount > len(rules_to_check): + self.target_amount = len(rules_to_check) + else: + self.target_amount = target_amount + + def _is_fulfilled(self, beaten_missions: Set[SC2MOGenMission], in_region_check: bool) -> bool: + return self.target_amount <= sum(rule.is_fulfilled(beaten_missions, in_region_check) for rule in self.rules_to_check) + + def _get_depth(self, beaten_missions: Set[SC2MOGenMission]) -> int: + if len(self.rules_to_check) == 0: + return self.min_depth + # It should be guaranteed by is_fulfilled that enough rules have a valid depth because they are fulfilled + filtered_rules = [rule for rule in self.rules_to_check if rule.get_depth(beaten_missions) > -1] + sorted_rules = sorted(filtered_rules, key = lambda rule: rule.get_depth(beaten_missions)) + required_depth = max(rule.get_depth(beaten_missions) for rule in sorted_rules[:self.target_amount]) + return max(required_depth, self.min_depth) + + def to_lambda(self, player: int) -> Callable[[CollectionState], bool]: + sub_lambdas = [rule.to_lambda(player) for rule in self.rules_to_check] + return lambda state, sub_lambdas=sub_lambdas: self.target_amount <= sum(sub_lambda(state) for sub_lambda in sub_lambdas) + + def to_slot_data(self) -> SubRuleRuleData: + sub_rules = [rule.to_slot_data() for rule in self.rules_to_check] + return SubRuleRuleData( + self.rule_id, + sub_rules, + self.target_amount + ) + + +@dataclass +class SubRuleRuleData(RuleData): + rule_id: int + sub_rules: List[RuleData] + amount: int + + @staticmethod + def parse_from_dict(data: Dict[str, Any]) -> SubRuleRuleData: + amount = data["amount"] + rule_id = data["rule_id"] + sub_rules: List[RuleData] = [] + for rule_data in data["sub_rules"]: + if "sub_rules" in rule_data: + rule: RuleData = SubRuleRuleData.parse_from_dict(rule_data) + elif "item_ids" in rule_data: + # Slot data converts Dict[int, int] to Dict[str, int] for some reason + item_ids = {int(item): item_amount for (item, item_amount) in rule_data["item_ids"].items()} + rule = ItemRuleData( + item_ids, + rule_data["visual_reqs"] + ) + elif "amount" in rule_data: + rule = CountMissionsRuleData( + **{field: value for field, value in rule_data.items()} + ) + else: + rule = BeatMissionsRuleData( + **{field: value for field, value in rule_data.items()} + ) + sub_rules.append(rule) + rule = SubRuleRuleData( + rule_id, + sub_rules, + amount + ) + return rule + + @staticmethod + def empty() -> SubRuleRuleData: + return SubRuleRuleData(-1, [], 0) + + def tooltip(self, indents: int, missions: Dict[int, SC2Mission], done_color: str, not_done_color: str) -> str: + indent = " ".join("" for _ in range(indents)) + if self.amount == len(self.sub_rules): + if self.amount == 1: + return self.sub_rules[0].tooltip(indents, missions, done_color, not_done_color) + amount = "all" + elif self.amount == 1: + amount = "any" + else: + amount = str(self.amount) + tooltip = f"Fulfill {amount} of these conditions:\n{indent}- " + subrule_tooltips: List[str] = [] + for rule in self.sub_rules: + sub_tooltip = rule.tooltip(indents + 4, missions, done_color, not_done_color) + if getattr(rule, "was_accessible", False): + subrule_tooltips.append(f"[color={done_color}]{sub_tooltip}[/color]") + else: + subrule_tooltips.append(f"[color={not_done_color}]{sub_tooltip}[/color]") + tooltip += f"\n{indent}- ".join(sub_tooltip for sub_tooltip in subrule_tooltips) + return tooltip + + def shows_single_rule(self) -> bool: + return self.amount == len(self.sub_rules) == 1 and self.sub_rules[0].shows_single_rule() + + def is_accessible( + self, beaten_missions: Set[int], received_items: Dict[int, int] + ) -> bool: + # Sub-rule rules are accessible if enough of their child rules are accessible + accessible_count = 0 + success = accessible_count >= self.amount + if self.amount > 0: + for rule in self.sub_rules: + if rule.is_accessible(beaten_missions, received_items): + rule.was_accessible = True + accessible_count += 1 + if accessible_count >= self.amount: + success = True + break + else: + rule.was_accessible = False + + return success + +class MissionEntryRules(NamedTuple): + mission_rule: SubRuleRuleData + layout_rule: SubRuleRuleData + campaign_rule: SubRuleRuleData + + +class ItemEntryRule(EntryRule): + items_to_check: Dict[str, int] + + def __init__(self, items_to_check: Dict[str, int]) -> None: + super().__init__() + self.items_to_check = items_to_check + + def _is_fulfilled(self, beaten_missions: Set[SC2MOGenMission], in_region_check: bool) -> bool: + # Region creation should assume items can be placed, + # but later uses (eg. starter missions) should respect that this locks a mission + return in_region_check + + def _get_depth(self, beaten_missions: Set[SC2MOGenMission]) -> int: + # Depth 0 means this rule requires 0 prior beaten missions + return 0 + + def to_lambda(self, player: int) -> Callable[[CollectionState], bool]: + return lambda state: state.has_all_counts(self.items_to_check, player) + + def to_slot_data(self) -> RuleData: + item_ids = {item_table[item].code: amount for (item, amount) in self.items_to_check.items()} + visual_reqs = [item if amount == 1 else str(amount) + "x " + item for (item, amount) in self.items_to_check.items()] + return ItemRuleData( + item_ids, + visual_reqs + ) + + +@dataclass +class ItemRuleData(RuleData): + item_ids: Dict[int, int] + visual_reqs: List[str] + + def tooltip(self, indents: int, missions: Dict[int, SC2Mission], done_color: str, not_done_color: str) -> str: + indent = " ".join("" for _ in range(indents)) + if len(self.visual_reqs) == 1: + return f"Find {self.visual_reqs[0]}" + tooltip = f"Find all of these:\n{indent}- " + tooltip += f"\n{indent}- ".join(req for req in self.visual_reqs) + return tooltip + + def shows_single_rule(self) -> bool: + return len(self.visual_reqs) == 1 + + def is_accessible( + self, beaten_missions: Set[int], received_items: Dict[int, int] + ) -> bool: + return all( + item in received_items and received_items[item] >= amount + for (item, amount) in self.item_ids.items() + ) diff --git a/worlds/sc2/mission_order/generation.py b/worlds/sc2/mission_order/generation.py new file mode 100644 index 000000000000..5582d7c31116 --- /dev/null +++ b/worlds/sc2/mission_order/generation.py @@ -0,0 +1,702 @@ +""" +Contains the complex data manipulation functions for mission order generation and Archipelago region creation. +Incoming data is validated to match specifications in .options.py. +The functions here are called from ..regions.py. +""" + +from typing import Set, Dict, Any, List, Tuple, Union, Optional, Callable, TYPE_CHECKING +import logging + +from BaseClasses import Location, Region, Entrance +from ..mission_tables import SC2Mission, MissionFlag, lookup_name_to_mission, lookup_id_to_mission +from ..item.item_tables import named_layout_key_item_table, named_campaign_key_item_table +from ..item import item_names +from .nodes import MissionOrderNode, SC2MOGenMissionOrder, SC2MOGenCampaign, SC2MOGenLayout, SC2MOGenMission +from .entry_rules import EntryRule, SubRuleEntryRule, ItemEntryRule, CountMissionsEntryRule, BeatMissionsEntryRule +from .mission_pools import ( + SC2MOGenMissionPools, Difficulty, modified_difficulty_thresholds, STANDARD_DIFFICULTY_FILL_ORDER +) +from .options import GENERIC_KEY_NAME, GENERIC_PROGRESSIVE_KEY_NAME + +if TYPE_CHECKING: + from ..locations import LocationData + from .. import SC2World + +def resolve_unlocks(mission_order: SC2MOGenMissionOrder): + """Parses a mission order's entry rule dicts into entry rule objects.""" + rolling_rule_id = 0 + for campaign in mission_order.campaigns: + entry_rule = { + "rules": campaign.option_entry_rules, + "amount": -1 + } + campaign.entry_rule = dict_to_entry_rule(mission_order, entry_rule, campaign, rolling_rule_id) + rolling_rule_id += 1 + for layout in campaign.layouts: + entry_rule = { + "rules": layout.option_entry_rules, + "amount": -1 + } + layout.entry_rule = dict_to_entry_rule(mission_order, entry_rule, layout, rolling_rule_id) + rolling_rule_id += 1 + for mission in layout.missions: + entry_rule = { + "rules": mission.option_entry_rules, + "amount": -1 + } + mission.entry_rule = dict_to_entry_rule(mission_order, entry_rule, mission, rolling_rule_id) + rolling_rule_id += 1 + # Manually make a rule for prev missions + if len(mission.prev) > 0: + mission.entry_rule.target_amount += 1 + mission.entry_rule.rules_to_check.append(CountMissionsEntryRule(mission.prev, 1, mission.prev)) + + +def dict_to_entry_rule(mission_order: SC2MOGenMissionOrder, data: Dict[str, Any], start_node: MissionOrderNode, rule_id: int = -1) -> EntryRule: + """Tries to create an entry rule object from an entry rule dict. The structure of these dicts is validated in .options.py.""" + if "items" in data: + items: Dict[str, int] = data["items"] + has_generic_key = False + for (item, amount) in items.items(): + if item.casefold() == GENERIC_KEY_NAME or item.casefold().startswith(GENERIC_PROGRESSIVE_KEY_NAME): + has_generic_key = True + continue # Don't try to lock the generic key + if item in mission_order.items_to_lock: + # Lock the greatest required amount of each item + mission_order.items_to_lock[item] = max(mission_order.items_to_lock[item], amount) + else: + mission_order.items_to_lock[item] = amount + rule = ItemEntryRule(items) + if has_generic_key: + mission_order.keys_to_resolve.setdefault(start_node, []).append(rule) + return rule + if "rules" in data: + rules = [dict_to_entry_rule(mission_order, subrule, start_node) for subrule in data["rules"]] + return SubRuleEntryRule(rules, data["amount"], rule_id) + if "scope" in data: + objects: List[Tuple[MissionOrderNode, str]] = [] + for address in data["scope"]: + resolved = resolve_address(mission_order, address, start_node) + objects.extend((obj, address) for obj in resolved) + visual_reqs = [obj.get_visual_requirement(start_node) for (obj, _) in objects] + missions: List[SC2MOGenMission] + if "amount" in data: + missions = [mission for (obj, _) in objects for mission in obj.get_missions() if not mission.option_empty] + if len(missions) == 0: + raise ValueError(f"Count rule did not find any missions at scopes: {data['scope']}") + return CountMissionsEntryRule(missions, data["amount"], visual_reqs) + missions = [] + for (obj, address) in objects: + obj.important_beat_event = True + exits = obj.get_exits() + if len(exits) == 0: + raise ValueError( + f"Address \"{address}\" found an unbeatable object. " + "This should mean the address contains \"..\" too often." + ) + missions.extend(exits) + return BeatMissionsEntryRule(missions, visual_reqs) + raise ValueError(f"Invalid data for entry rule: {data}") + + +def resolve_address(mission_order: SC2MOGenMissionOrder, address: str, start_node: MissionOrderNode) -> List[MissionOrderNode]: + """Tries to find a node in the mission order by following the given address.""" + if address.startswith("../") or address == "..": + # Relative address, starts from searching object + cursor = start_node + else: + # Absolute address, starts from the top + cursor = mission_order + address_so_far = "" + for term in address.split("/"): + if len(address_so_far) > 0: + address_so_far += "/" + address_so_far += term + if term == "..": + cursor = cursor.get_parent(address_so_far, address) + else: + result = cursor.search(term) + if result is None: + raise ValueError(f"Address \"{address_so_far}\" (from \"{address}\") tried to find a child for a mission.") + if len(result) == 0: + raise ValueError(f"Address \"{address_so_far}\" (from \"{address}\") could not find a {cursor.child_type_name()}.") + if len(result) > 1: + # Layouts are allowed to end with multiple missions via an index function + if type(result[0]) == SC2MOGenMission and address_so_far == address: + return result + raise ValueError((f"Address \"{address_so_far}\" (from \"{address}\") found more than one {cursor.child_type_name()}.")) + cursor = result[0] + if cursor == start_node: + raise ValueError( + f"Address \"{address_so_far}\" (from \"{address}\") returned to original object. " + "This is not allowed to avoid circular requirements." + ) + return [cursor] + + +######################## + + +def fill_depths(mission_order: SC2MOGenMissionOrder) -> None: + """ + Flood-fills the mission order by following its entry rules to determine the depth of all nodes. + This also ensures theoretical total accessibility of all nodes, but this is allowed to be violated by item placement and the accessibility setting. + """ + accessible_campaigns: Set[SC2MOGenCampaign] = {campaign for campaign in mission_order.campaigns if campaign.is_always_unlocked(in_region_creation=True)} + next_campaigns: Set[SC2MOGenCampaign] = set(mission_order.campaigns).difference(accessible_campaigns) + + accessible_layouts: Set[SC2MOGenLayout] = { + layout + for campaign in accessible_campaigns for layout in campaign.layouts + if layout.is_always_unlocked(in_region_creation=True) + } + next_layouts: Set[SC2MOGenLayout] = {layout for campaign in accessible_campaigns for layout in campaign.layouts}.difference(accessible_layouts) + + next_missions: Set[SC2MOGenMission] = {mission for layout in accessible_layouts for mission in layout.entrances} + beaten_missions: Set[SC2MOGenMission] = set() + + # Sanity check: Can any missions be accessed? + if len(next_missions) == 0: + raise Exception("Mission order has no possibly accessible missions") + + iterations = 0 + while len(next_missions) > 0: + # Check for accessible missions + cur_missions: Set[SC2MOGenMission] = { + mission for mission in next_missions + if mission.is_unlocked(beaten_missions, in_region_creation=True) + } + if len(cur_missions) == 0: + raise Exception(f"Mission order ran out of accessible missions during iteration {iterations}") + next_missions.difference_update(cur_missions) + # Set the depth counters of all currently accessible missions + new_beaten_missions: Set[SC2MOGenMission] = set() + while len(cur_missions) > 0: + mission = cur_missions.pop() + new_beaten_missions.add(mission) + # If the beaten missions at depth X unlock a mission, said mission can be beaten at depth X+1 + mission.min_depth = mission.entry_rule.get_depth(beaten_missions) + 1 + new_next = [ + next_mission for next_mission in mission.next if not ( + next_mission in cur_missions + or next_mission in beaten_missions + or next_mission in new_beaten_missions + ) + ] + next_missions.update(new_next) + + # Any campaigns/layouts/missions added after this point will be seen in the next iteration at the earliest + iterations += 1 + beaten_missions.update(new_beaten_missions) + + # Check for newly accessible campaigns & layouts + new_campaigns: Set[SC2MOGenCampaign] = set() + for campaign in next_campaigns: + if campaign.is_unlocked(beaten_missions, in_region_creation=True): + new_campaigns.add(campaign) + for campaign in new_campaigns: + accessible_campaigns.add(campaign) + next_layouts.update(campaign.layouts) + next_campaigns.remove(campaign) + for layout in campaign.layouts: + layout.entry_rule.min_depth = campaign.entry_rule.get_depth(beaten_missions) + new_layouts: Set[SC2MOGenLayout] = set() + for layout in next_layouts: + if layout.is_unlocked(beaten_missions, in_region_creation=True): + new_layouts.add(layout) + for layout in new_layouts: + accessible_layouts.add(layout) + next_missions.update(layout.entrances) + next_layouts.remove(layout) + for mission in layout.entrances: + mission.entry_rule.min_depth = layout.entry_rule.get_depth(beaten_missions) + + # Make sure we didn't miss anything + assert len(accessible_campaigns) == len(mission_order.campaigns) + assert len(accessible_layouts) == sum(len(campaign.layouts) for campaign in mission_order.campaigns) + total_missions = sum( + len([mission for mission in layout.missions if not mission.option_empty]) + for campaign in mission_order.campaigns for layout in campaign.layouts + ) + assert len(beaten_missions) == total_missions, f'Can only access {len(beaten_missions)} missions out of {total_missions}' + + # Fill campaign/layout depth values as min/max of their children + for campaign in mission_order.campaigns: + for layout in campaign.layouts: + depths = [mission.min_depth for mission in layout.missions if not mission.option_empty] + layout.min_depth = min(depths) + layout.max_depth = max(depths) + campaign.min_depth = min(layout.min_depth for layout in campaign.layouts) + campaign.max_depth = max(layout.max_depth for layout in campaign.layouts) + mission_order.max_depth = max(campaign.max_depth for campaign in mission_order.campaigns) + + +######################## + + +def resolve_difficulties(mission_order: SC2MOGenMissionOrder) -> None: + """Determines the concrete difficulty of all mission slots.""" + for campaign in mission_order.campaigns: + for layout in campaign.layouts: + if layout.option_min_difficulty == Difficulty.RELATIVE: + min_diff = campaign.option_min_difficulty + if min_diff == Difficulty.RELATIVE: + min_depth = 0 + else: + min_depth = campaign.min_depth + else: + min_diff = layout.option_min_difficulty + min_depth = layout.min_depth + + if layout.option_max_difficulty == Difficulty.RELATIVE: + max_diff = campaign.option_max_difficulty + if max_diff == Difficulty.RELATIVE: + max_depth = mission_order.max_depth + else: + max_depth = campaign.max_depth + else: + max_diff = layout.option_max_difficulty + max_depth = layout.max_depth + + depth_range = max_depth - min_depth + if depth_range == 0: + # This can happen if layout size is 1 or layout is all entrances + # Use minimum difficulty in this case + depth_range = 1 + # If min/max aren't relative, assume the limits are meant to show up + layout_thresholds = modified_difficulty_thresholds(min_diff, max_diff) + thresholds = sorted(layout_thresholds.keys()) + + for mission in layout.missions: + if mission.option_empty: + continue + if len(mission.option_mission_pool) == 1: + mission_order.fixed_missions.append(mission) + continue + if mission.option_difficulty == Difficulty.RELATIVE: + mission_thresh = int((mission.min_depth - min_depth) * 100 / depth_range) + for i in range(len(thresholds)): + if thresholds[i] > mission_thresh: + mission.option_difficulty = layout_thresholds[thresholds[i - 1]] + break + mission.option_difficulty = layout_thresholds[thresholds[-1]] + mission_order.sorted_missions[mission.option_difficulty].append(mission) + + +######################## + + +def fill_missions( + mission_order: SC2MOGenMissionOrder, mission_pools: SC2MOGenMissionPools, + world: 'SC2World', locked_missions: List[str], locations: Tuple['LocationData', ...], location_cache: List[Location] +) -> None: + """Places missions in all non-empty mission slots. Also responsible for creating Archipelago regions & locations for placed missions.""" + locations_per_region = get_locations_per_region(locations) + regions: List[Region] = [create_region(world, locations_per_region, location_cache, "Menu")] + locked_ids = [lookup_name_to_mission[mission].id for mission in locked_missions] + prefer_close_difficulty = world.options.difficulty_curve.value == world.options.difficulty_curve.option_standard + + def set_mission_in_slot(slot: SC2MOGenMission, mission: SC2Mission): + slot.mission = mission + slot.region = create_region(world, locations_per_region, location_cache, + mission.mission_name, slot) + + # Resolve slots with set mission names + for mission_slot in mission_order.fixed_missions: + mission_id = mission_slot.option_mission_pool.pop() + # Remove set mission from locked missions + locked_ids = [locked for locked in locked_ids if locked != mission_id] + mission = lookup_id_to_mission[mission_id] + if mission in mission_pools.get_used_missions(): + raise ValueError(f"Mission slot at address \"{mission_slot.get_address_to_node()}\" tried to plando an already plando'd mission.") + mission_pools.pull_specific_mission(mission) + set_mission_in_slot(mission_slot, mission) + regions.append(mission_slot.region) + + # Shuffle & sort all slots to pick from smallest to biggest pool with tie-breaks by difficulty (lowest to highest), then randomly + # Additionally sort goals by difficulty (highest to lowest) with random tie-breaks + sorted_goals: List[SC2MOGenMission] = [] + for difficulty in sorted(mission_order.sorted_missions.keys()): + world.random.shuffle(mission_order.sorted_missions[difficulty]) + sorted_goals.extend(mission for mission in mission_order.sorted_missions[difficulty] if mission in mission_order.goal_missions) + # Sort slots by difficulty, with difficulties sorted by fill order + # standard curve/close difficulty fills difficulties out->in, uneven fills easy->hard + if prefer_close_difficulty: + all_slots = [slot for diff in STANDARD_DIFFICULTY_FILL_ORDER for slot in mission_order.sorted_missions[diff]] + else: + all_slots = [slot for diff in sorted(mission_order.sorted_missions.keys()) for slot in mission_order.sorted_missions[diff]] + # Pick slots with a constrained mission pool first + all_slots.sort(key = lambda slot: len(slot.option_mission_pool.intersection(mission_pools.master_list))) + sorted_goals.reverse() + + # Randomly assign locked missions to appropriate difficulties + slots_for_locked: Dict[int, List[SC2MOGenMission]] = {locked: [] for locked in locked_ids} + for mission_slot in all_slots: + allowed_locked = mission_slot.option_mission_pool.intersection(locked_ids) + for locked in allowed_locked: + slots_for_locked[locked].append(mission_slot) + for (locked, allowed_slots) in slots_for_locked.items(): + locked_mission = lookup_id_to_mission[locked] + allowed_slots = [slot for slot in allowed_slots if slot in all_slots] + if len(allowed_slots) == 0: + logging.warning(f"SC2: Locked mission \"{locked_mission.mission_name}\" is not allowed in any remaining spot and will not be placed.") + continue + # This inherits the earlier sorting, but is now sorted again by relative difficulty + # The result is a sorting in order of nearest difficulty (preferring lower), then by smallest pool, then randomly + allowed_slots.sort(key = lambda slot: abs(slot.option_difficulty - locked_mission.pool + 1)) + # The first slot should be most appropriate + mission_slot = allowed_slots[0] + mission_pools.pull_specific_mission(locked_mission) + set_mission_in_slot(mission_slot, locked_mission) + regions.append(mission_slot.region) + all_slots.remove(mission_slot) + if mission_slot in sorted_goals: + sorted_goals.remove(mission_slot) + + # Pick goal missions first with stricter difficulty matching, and starting with harder goals + for goal_slot in sorted_goals: + try: + mission = mission_pools.pull_random_mission(world, goal_slot, prefer_close_difficulty=True) + set_mission_in_slot(goal_slot, mission) + regions.append(goal_slot.region) + all_slots.remove(goal_slot) + except IndexError: + raise IndexError( + f"Slot at address \"{goal_slot.get_address_to_node()}\" ran out of possible missions to place " + f"with {len(all_slots)} empty slots remaining." + ) + + # Pick random missions + remaining_count = len(all_slots) + for mission_slot in all_slots: + try: + mission = mission_pools.pull_random_mission(world, mission_slot, prefer_close_difficulty=prefer_close_difficulty) + set_mission_in_slot(mission_slot, mission) + regions.append(mission_slot.region) + remaining_count -= 1 + except IndexError: + raise IndexError( + f"Slot at address \"{mission_slot.get_address_to_node()}\" ran out of possible missions to place " + f"with {remaining_count} empty slots remaining." + ) + + world.multiworld.regions += regions + + +def get_locations_per_region(locations: Tuple['LocationData', ...]) -> Dict[str, List['LocationData']]: + per_region: Dict[str, List['LocationData']] = {} + + for location in locations: + per_region.setdefault(location.region, []).append(location) + + return per_region + + +def create_location(player: int, location_data: 'LocationData', region: Region, + location_cache: List[Location]) -> Location: + location = Location(player, location_data.name, location_data.code, region) + location.access_rule = location_data.rule + + location_cache.append(location) + return location + + +def create_minimal_logic_location( + world: 'SC2World', location_data: 'LocationData', region: Region, location_cache: List[Location], unit_count: int = 0, +) -> Location: + location = Location(world.player, location_data.name, location_data.code, region) + mission = lookup_name_to_mission.get(region.name) + if mission is None: + pass + elif location_data.hard_rule: + assert world.logic + unit_rule = world.logic.has_race_units(unit_count, mission.race) + location.access_rule = lambda state: unit_rule(state) and location_data.hard_rule(state) + else: + assert world.logic + location.access_rule = world.logic.has_race_units(unit_count, mission.race) + location_cache.append(location) + return location + + +def create_region( + world: 'SC2World', + locations_per_region: Dict[str, List['LocationData']], + location_cache: List[Location], + name: str, + slot: Optional[SC2MOGenMission] = None, +) -> Region: + MAX_UNIT_REQUIREMENT = 5 + region = Region(name, world.player, world.multiworld) + + from ..locations import LocationType + if slot is None: + target_victory_cache_locations = 0 + else: + target_victory_cache_locations = slot.option_victory_cache + victory_cache_locations = 0 + + # If the first mission is a build mission, + # require a unit everywhere except one location in the easiest category + mission_needs_unit = False + unit_given = False + easiest_category = LocationType.MASTERY + if slot is not None and slot.min_depth == 0: + mission = lookup_name_to_mission.get(region.name) + if mission is not None and MissionFlag.NoBuild not in mission.flags: + mission_needs_unit = True + for location_data in locations_per_region.get(name, ()): + if location_data.type == LocationType.VICTORY: + pass + elif location_data.type < easiest_category: + easiest_category = location_data.type + if easiest_category >= LocationType.CHALLENGE: + easiest_category = LocationType.VICTORY + + for location_data in locations_per_region.get(name, ()): + assert slot is not None + if location_data.type == LocationType.VICTORY_CACHE: + if victory_cache_locations >= target_victory_cache_locations: + continue + victory_cache_locations += 1 + if world.options.required_tactics.value == world.options.required_tactics.option_any_units: + if mission_needs_unit and not unit_given and location_data.type == easiest_category: + # Ensure there is at least one no-logic location if the first mission is a build mission + location = create_minimal_logic_location(world, location_data, region, location_cache, 0) + unit_given = True + elif location_data.type == LocationType.MASTERY: + # Mastery locations always require max units regardless of position in the ramp + location = create_minimal_logic_location(world, location_data, region, location_cache, MAX_UNIT_REQUIREMENT) + else: + # Required number of units = mission depth; +1 if it's a starting build mission; +1 if it's a challenge location + location = create_minimal_logic_location(world, location_data, region, location_cache, min( + slot.min_depth + mission_needs_unit + (location_data.type == LocationType.CHALLENGE), + MAX_UNIT_REQUIREMENT + )) + else: + location = create_location(world.player, location_data, region, location_cache) + region.locations.append(location) + + return region + + +######################## + + +def make_connections(mission_order: SC2MOGenMissionOrder, world: 'SC2World'): + """Creates Archipelago entrances between missions and creates access rules for the generator from entry rule objects.""" + names: Dict[str, int] = {} + player = world.player + for campaign in mission_order.campaigns: + for layout in campaign.layouts: + for mission in layout.missions: + if not mission.option_empty: + mission_rule = mission.entry_rule.to_lambda(player) + # Only layout entrances need to consider campaign & layout prerequisites + if mission.option_entrance: + campaign_rule = mission.parent().parent().entry_rule.to_lambda(player) + layout_rule = mission.parent().entry_rule.to_lambda(player) + unlock_rule = lambda state, campaign_rule=campaign_rule, layout_rule=layout_rule, mission_rule=mission_rule: \ + campaign_rule(state) and layout_rule(state) and mission_rule(state) + else: + unlock_rule = mission_rule + # Individually connect to previous missions + for prev_mission in mission.prev: + connect(world, names, prev_mission.mission.mission_name, mission.mission.mission_name, + lambda state, unlock_rule=unlock_rule: unlock_rule(state)) + # If there are no previous missions, connect to Menu instead + if len(mission.prev) == 0: + connect(world, names, "Menu", mission.mission.mission_name, + lambda state, unlock_rule=unlock_rule: unlock_rule(state)) + + +def connect(world: 'SC2World', used_names: Dict[str, int], source: str, target: str, + rule: Optional[Callable] = None): + source_region = world.get_region(source) + target_region = world.get_region(target) + + if target not in used_names: + used_names[target] = 1 + name = target + else: + used_names[target] += 1 + name = target + (' ' * used_names[target]) + + connection = Entrance(world.player, name, source_region) + + if rule: + connection.access_rule = rule + + source_region.exits.append(connection) + connection.connect(target_region) + + +######################## + + +def resolve_generic_keys(mission_order: SC2MOGenMissionOrder) -> None: + """ + Replaces placeholder keys in Item entry rules with their concrete counterparts. + Specifically this handles placing named keys into missions and vanilla campaigns/layouts, + and assigning correct progression tracks to progressive keys. + """ + layout_numbered_keys = 1 + campaign_numbered_keys = 1 + progression_tracks: Dict[int, List[Tuple[MissionOrderNode, ItemEntryRule]]] = {} + for (node, item_rules) in mission_order.keys_to_resolve.items(): + key_name = node.get_key_name() + # Generic keys in mission slots should always resolve to an existing key + # Layouts and campaigns may need to be switched for numbered keys + if isinstance(node, SC2MOGenLayout) and key_name not in named_layout_key_item_table: + key_name = item_names._TEMPLATE_NUMBERED_LAYOUT_KEY.format(layout_numbered_keys) + layout_numbered_keys += 1 + elif isinstance(node, SC2MOGenCampaign) and key_name not in named_campaign_key_item_table: + key_name = item_names._TEMPLATE_NUMBERED_CAMPAIGN_KEY.format(campaign_numbered_keys) + campaign_numbered_keys += 1 + + for item_rule in item_rules: + # Swap regular generic key names for the node's proper key name + item_rule.items_to_check = { + key_name if item_name.casefold() == GENERIC_KEY_NAME else item_name: amount + for (item_name, amount) in item_rule.items_to_check.items() + } + # Only lock the key if it was actually placed in this rule + if key_name in item_rule.items_to_check: + mission_order.items_to_lock[key_name] = max(item_rule.items_to_check[key_name], mission_order.items_to_lock.get(key_name, 0)) + + # Sort progressive keys by their given track + for (item_name, amount) in item_rule.items_to_check.items(): + if item_name.casefold() == GENERIC_PROGRESSIVE_KEY_NAME: + progression_tracks.setdefault(amount, []).append((node, item_rule)) + elif item_name.casefold().startswith(GENERIC_PROGRESSIVE_KEY_NAME): + track_string = item_name.split()[-1] + try: + track = int(track_string) + progression_tracks.setdefault(track, []).append((node, item_rule)) + except ValueError: + raise ValueError( + f"Progression track \"{track_string}\" for progressive key \"{item_name}: {amount}\" is not a valid number. " + "Valid formats are:\n" + f"- {GENERIC_PROGRESSIVE_KEY_NAME.title()}: X\n" + f"- {GENERIC_PROGRESSIVE_KEY_NAME.title()} X: 1" + ) + + def find_progressive_keys(item_rule: ItemEntryRule, track_to_find: int) -> List[str]: + return [ + item_name for (item_name, amount) in item_rule.items_to_check.items() + if (item_name.casefold() == GENERIC_PROGRESSIVE_KEY_NAME and amount == track_to_find) or ( + item_name.casefold().startswith(GENERIC_PROGRESSIVE_KEY_NAME) and + item_name.split()[-1] == str(track_to_find) + ) + ] + + def replace_progressive_keys(item_rule: ItemEntryRule, track_to_replace: int, new_key_name: str, new_key_amount: int): + keys_to_replace = find_progressive_keys(item_rule, track_to_replace) + new_items_to_check: Dict[str, int] = {} + for (item_name, amount) in item_rule.items_to_check.items(): + if item_name in keys_to_replace: + new_items_to_check[new_key_name] = new_key_amount + else: + new_items_to_check[item_name] = amount + item_rule.items_to_check = new_items_to_check + + # Change progressive keys to be unique for missions and layouts that request it + want_unique: Dict[MissionOrderNode, List[Tuple[MissionOrderNode, ItemEntryRule]]] = {} + empty_tracks: List[int] = [] + for track in progression_tracks: + # Sort keys to change by layout + new_unique_tracks: Dict[MissionOrderNode, List[Tuple[MissionOrderNode, ItemEntryRule]]] = {} + for (node, item_rule) in progression_tracks[track]: + if isinstance(node, SC2MOGenMission): + # Unique tracks for layouts take priority over campaigns + if node.parent().option_unique_progression_track == track: + new_unique_tracks.setdefault(node.parent(), []).append((node, item_rule)) + elif node.parent().parent().option_unique_progression_track == track: + new_unique_tracks.setdefault(node.parent().parent(), []).append((node, item_rule)) + elif isinstance(node, SC2MOGenLayout) and node.parent().option_unique_progression_track == track: + new_unique_tracks.setdefault(node.parent(), []).append((node, item_rule)) + # Remove found keys from their original progression track + for (container_node, rule_list) in new_unique_tracks.items(): + for node_and_rule in rule_list: + progression_tracks[track].remove(node_and_rule) + want_unique.setdefault(container_node, []).extend(rule_list) + if len(progression_tracks[track]) == 0: + empty_tracks.append(track) + for track in empty_tracks: + progression_tracks.pop(track) + + # Make sure all tracks that can't have keys have been taken care of + invalid_tracks: List[int] = [track for track in progression_tracks if track < 1 or track > len(SC2Mission)] + if len(invalid_tracks) > 0: + affected_key_list: Dict[MissionOrderNode, List[str]] = {} + for track in invalid_tracks: + for (node, item_rule) in progression_tracks[track]: + affected_key_list.setdefault(node, []).extend( + f"{key}: {item_rule.items_to_check[key]}" for key in find_progressive_keys(item_rule, track) + ) + affected_key_list_string = "\n- " + "\n- ".join( + f"{node.get_address_to_node()}: {affected_keys}" + for (node, affected_keys) in affected_key_list.items() + ) + raise ValueError( + "Some item rules contain progressive keys with invalid tracks:" + + affected_key_list_string + + f"\nPossible solutions are changing the tracks of affected keys to be in the range from 1 to {len(SC2Mission)}, " + "or changing the unique_progression_track of containing campaigns/layouts to match the invalid tracks." + ) + + # Assign new free progression tracks to nodes in definition order + next_free = 1 + nodes_to_assign = list(want_unique.keys()) + while len(want_unique) > 0: + while next_free in progression_tracks: + next_free += 1 + container_node = nodes_to_assign.pop(0) + progression_tracks[next_free] = want_unique.pop(container_node) + # Replace the affected keys in nodes with their correct counterparts + key_name = f"{GENERIC_PROGRESSIVE_KEY_NAME} {next_free}" + for (node, item_rule) in progression_tracks[next_free]: + # It's guaranteed by the sorting above that the container is either a layout or a campaign + replace_progressive_keys(item_rule, container_node.option_unique_progression_track, key_name, 1) + + # Give progressive keys a more fitting name if there's only one track and they all apply to the same type of node + progressive_flavor_name: Union[str, None] = None + if len(progression_tracks) == 1: + if all(isinstance(node, SC2MOGenLayout) for rule_list in progression_tracks.values() for (node, _) in rule_list): + progressive_flavor_name = item_names.PROGRESSIVE_QUESTLINE_KEY + elif all(isinstance(node, SC2MOGenMission) for rule_list in progression_tracks.values() for (node, _) in rule_list): + progressive_flavor_name = item_names.PROGRESSIVE_MISSION_KEY + + for (track, rule_list) in progression_tracks.items(): + key_name = item_names._TEMPLATE_PROGRESSIVE_KEY.format(track) if progressive_flavor_name is None else progressive_flavor_name + # Determine order in which the rules should unlock + ordered_item_rules: List[List[ItemEntryRule]] = [] + if not any(isinstance(node, SC2MOGenMission) for (node, _) in rule_list): + # No rule on this track belongs to a mission, so the rules can be kept in definition order + ordered_item_rules = [[item_rule] for (_, item_rule) in rule_list] + else: + # At least one rule belongs to a mission + # Sort rules by the depth of their nodes, ties get the same amount of keys + depth_to_rules: Dict[int, List[ItemEntryRule]] = {} + for (node, item_rule) in rule_list: + depth_to_rules.setdefault(node.get_min_depth(), []).append(item_rule) + ordered_item_rules = [depth_to_rules[depth] for depth in sorted(depth_to_rules.keys())] + + # Assign correct progressive keys to each rule + for (position, item_rules) in enumerate(ordered_item_rules): + for item_rule in item_rules: + keys_to_replace = [ + item_name for (item_name, amount) in item_rule.items_to_check.items() + if (item_name.casefold() == GENERIC_PROGRESSIVE_KEY_NAME and amount == track) or ( + item_name.casefold().startswith(GENERIC_PROGRESSIVE_KEY_NAME) and + item_name.split()[-1] == str(track) + ) + ] + new_items_to_check: Dict[str, int] = {} + for (item_name, amount) in item_rule.items_to_check.items(): + if item_name in keys_to_replace: + new_items_to_check[key_name] = position + 1 + else: + new_items_to_check[item_name] = amount + item_rule.items_to_check = new_items_to_check + mission_order.items_to_lock[key_name] = len(ordered_item_rules) diff --git a/worlds/sc2/mission_order/layout_types.py b/worlds/sc2/mission_order/layout_types.py new file mode 100644 index 000000000000..7581ac64f4b4 --- /dev/null +++ b/worlds/sc2/mission_order/layout_types.py @@ -0,0 +1,620 @@ +from __future__ import annotations +from typing import List, Callable, Set, Tuple, Union, TYPE_CHECKING, Dict, Any +import math +from abc import ABC, abstractmethod + +if TYPE_CHECKING: + from .nodes import SC2MOGenMission + +class LayoutType(ABC): + size: int + index_functions: List[str] = [] + """Names of available functions for mission indices. For list member `"my_fn"`, function should be called `idx_my_fn`.""" + + def __init__(self, size: int): + self.size = size + + def set_options(self, options: Dict[str, Any]) -> Dict[str, Any]: + """Get type-specific options from the provided dict. Should return unused values.""" + return options + + @abstractmethod + def make_slots(self, mission_factory: Callable[[], SC2MOGenMission]) -> List[SC2MOGenMission]: + """Use the provided `Callable` to create a one-dimensional list of mission slots and set up initial settings and connections. + + This should include at least one entrance and exit.""" + return [] + + def final_setup(self, missions: List[SC2MOGenMission]): + """Called after user changes to the layout are applied to make any final checks and changes. + + Implementers should make changes with caution, since it runs after a user's explicit commands are implemented.""" + return + + def parse_index(self, term: str) -> Union[Set[int], None]: + """From the given term, determine a list of desired target indices. The term is guaranteed to not be "entrances", "exits", or "all". + + If the term cannot be parsed, either raise an exception or return `None`.""" + return self.parse_index_as_function(term) + + def parse_index_as_function(self, term: str) -> Union[Set[int], None]: + """Helper function to interpret the term as a function call on the layout type, if it is declared in `self.index_functions`. + + Returns the function's return value if `term` is a valid function call, `None` otherwise.""" + left = term.find('(') + right = term.find(')') + if left == -1 and right == -1: + # Assume no args are desired + fn_name = term.strip() + fn_args = [] + elif left == -1 or right == -1: + return None + else: + fn_name = term[:left].strip() + fn_args_str = term[left + 1:right] + fn_args = [arg.strip() for arg in fn_args_str.split(',')] + + if fn_name in self.index_functions: + try: + return getattr(self, "idx_" + fn_name)(*fn_args) + except: + return None + else: + return None + + @abstractmethod + def get_visual_layout(self) -> List[List[int]]: + """Organize the mission slots into a list of columns from left to right and top to bottom. + The list should contain indices into the list created by `make_slots`. Intentionally empty spots should contain -1. + + The resulting 2D list should be rectangular.""" + pass + +class Column(LayoutType): + """Linear layout. Default entrance is index 0 at the top, default exit is index `size - 1` at the bottom.""" + + # 0 + # 1 + # 2 + + def make_slots(self, mission_factory: Callable[[], SC2MOGenMission]) -> List[SC2MOGenMission]: + missions = [mission_factory() for _ in range(self.size)] + missions[0].option_entrance = True + missions[-1].option_exit = True + for i in range(self.size - 1): + missions[i].next.append(missions[i + 1]) + return missions + + def get_visual_layout(self) -> List[List[int]]: + return [list(range(self.size))] + +class Grid(LayoutType): + """Rectangular grid. Default entrance is index 0 in the top left, default exit is index `size - 1` in the bottom right.""" + width: int + height: int + num_corners_to_remove: int + two_start_positions: bool + + index_functions = [ + "point", "rect" + ] + + # 0 1 2 + # 3 4 5 + # 6 7 8 + + def set_options(self, options: Dict[str, Any]) -> Dict[str, Any]: + self.two_start_positions = options.pop("two_start_positions", False) and self.size >= 2 + if self.two_start_positions: + self.size += 1 + width: int = options.pop("width", 0) + if width < 1: + self.width, self.height, self.num_corners_to_remove = Grid.get_grid_dimensions(self.size) + else: + self.width = width + self.height = math.ceil(self.size / self.width) + self.num_corners_to_remove = self.height * width - self.size + return options + + @staticmethod + def get_factors(number: int) -> Tuple[int, int]: + """ + Simple factorization into pairs of numbers (x, y) using a sieve method. + Returns the factorization that is most square, i.e. where x + y is minimized. + Factor order is such that x <= y. + """ + assert number > 0 + for divisor in range(math.floor(math.sqrt(number)), 1, -1): + quotient = number // divisor + if quotient * divisor == number: + return divisor, quotient + return 1, number + + @staticmethod + def get_grid_dimensions(size: int) -> Tuple[int, int, int]: + """ + Get the dimensions of a grid mission order from the number of missions, int the format (x, y, error). + * Error will always be 0, 1, or 2, so the missions can be removed from the corners that aren't the start or end. + * Dimensions are chosen such that x <= y, as buttons in the UI are wider than they are tall. + * Dimensions are chosen to be maximally square. That is, x + y + error is minimized. + * If multiple options of the same rating are possible, the one with the larger error is chosen, + as it will appear more square. Compare 3x11 to 5x7-2 for an example of this. + """ + dimension_candidates: List[Tuple[int, int, int]] = [(*Grid.get_factors(size + x), x) for x in (2, 1, 0)] + best_dimension = min(dimension_candidates, key=sum) + return best_dimension + + @staticmethod + def manhattan_distance(point1: Tuple[int, int], point2: Tuple[int, int]) -> int: + return abs(point1[0] - point2[0]) + abs(point1[1] - point2[1]) + + @staticmethod + def euclidean_distance_squared(point1: Tuple[int, int], point2: Tuple[int, int]) -> int: + return (point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2 + + @staticmethod + def euclidean_distance(point1: Tuple[int, int], point2: Tuple[int, int]) -> float: + return math.sqrt(Grid.euclidean_distance_squared(point1, point2)) + + def get_grid_coordinates(self, idx: int) -> Tuple[int, int]: + return (idx % self.width), (idx // self.width) + + def get_grid_index(self, x: int, y: int) -> int: + return y * self.width + x + + def is_valid_coordinates(self, x: int, y: int) -> bool: + return ( + 0 <= x < self.width and + 0 <= y < self.height + ) + + def make_slots(self, mission_factory: Callable[[], SC2MOGenMission]) -> List[SC2MOGenMission]: + missions = [mission_factory() for _ in range(self.width * self.height)] + if self.two_start_positions: + missions[0].option_empty = True + missions[1].option_entrance = True + missions[self.get_grid_index(0, 1)].option_entrance = True + else: + missions[0].option_entrance = True + missions[-1].option_exit = True + + for x in range(self.width): + left = x - 1 + right = x + 1 + for y in range(self.height): + up = y - 1 + down = y + 1 + idx = self.get_grid_index(x, y) + neighbours = [ + self.get_grid_index(nb_x, nb_y) + for (nb_x, nb_y) in [(left, y), (right, y), (x, up), (x, down)] + if self.is_valid_coordinates(nb_x, nb_y) + ] + missions[idx].next = [missions[nb] for nb in neighbours] + + # Empty corners + top_corners = math.floor(self.num_corners_to_remove / 2) + bottom_corners = math.ceil(self.num_corners_to_remove / 2) + + # Bottom left corners + y = self.height - 1 + x = 0 + leading_x = 0 + placed = 0 + while placed < bottom_corners: + if x == -1 or y == 0: + leading_x += 1 + x = leading_x + y = self.height - 1 + missions[self.get_grid_index(x, y)].option_empty = True + placed += 1 + x -= 1 + y -= 1 + + # Top right corners + y = 0 + x = self.width - 1 + leading_x = self.width - 1 + placed = 0 + while placed < top_corners: + if x == self.width or y == self.height - 1: + leading_x -= 1 + x = leading_x + y = 0 + missions[self.get_grid_index(x, y)].option_empty = True + placed += 1 + x += 1 + y += 1 + + return missions + + def get_visual_layout(self) -> List[List[int]]: + columns = [ + [self.get_grid_index(x, y) for y in range(self.height)] + for x in range(self.width) + ] + return columns + + def idx_point(self, x: str, y: str) -> Union[Set[int], None]: + try: + x = int(x) + y = int(y) + except: + return None + if self.is_valid_coordinates(x, y): + return {self.get_grid_index(x, y)} + return None + + def idx_rect(self, x: str, y: str, width: str, height: str) -> Union[Set[int], None]: + try: + x = int(x) + y = int(y) + width = int(width) + height = int(height) + except: + return None + indices = { + self.get_grid_index(pt_x, pt_y) + for pt_y in range(y, y + height) + for pt_x in range(x, x + width) + if self.is_valid_coordinates(pt_x, pt_y) + } + return indices + + +class Canvas(Grid): + """Rectangular grid that determines size and filled slots based on special canvas option.""" + canvas: List[str] + groups: Dict[str, List[int]] + jump_distance_orthogonal: int + jump_distance_diagonal: int + + jumps_orthogonal = [(-1, 0), (0, 1), (1, 0), (0, -1)] + jumps_diagonal = [(-1, -1), (-1, 1), (1, 1), (1, -1)] + + index_functions = Grid.index_functions + ["group"] + + def set_options(self, options: Dict[str, Any]) -> Dict[str, Any]: + self.width = options.pop("width") # Should be guaranteed by the option parser + self.height = math.ceil(self.size / self.width) + self.num_corners_to_remove = 0 + self.two_start_positions = False + self.jump_distance_orthogonal = max(options.pop("jump_distance_orthogonal", 1), 1) + self.jump_distance_diagonal = max(options.pop("jump_distance_diagonal", 1), 0) + + if "canvas" not in options: + raise KeyError("Canvas layout is missing required canvas option. Either create it or change type to Grid.") + self.canvas = options.pop("canvas") + # Pad short lines with spaces + longest_line = max(len(line) for line in self.canvas) + for idx in range(len(self.canvas)): + padding = ' ' * (longest_line - len(self.canvas[idx])) + self.canvas[idx] += padding + + self.groups = {} + for (line_idx, line) in enumerate(self.canvas): + for (char_idx, char) in enumerate(line): + self.groups.setdefault(char, []).append(self.get_grid_index(char_idx, line_idx)) + + return options + + def make_slots(self, mission_factory: Callable[[], SC2MOGenMission]) -> List[SC2MOGenMission]: + missions = super().make_slots(mission_factory) + missions[0].option_entrance = False + missions[-1].option_exit = False + + # Canvas spaces become empty slots + for idx in self.groups.get(" ", []): + missions[idx].option_empty = True + + # Raycast into jump directions to find nearest empty space + def jump(point: Tuple[int, int], direction: Tuple[int, int], distance: int) -> Tuple[int, int]: + return ( + point[0] + direction[0] * distance, + point[1] + direction[1] * distance + ) + + def raycast(point: Tuple[int, int], direction: Tuple[int, int], max_distance: int) -> Union[Tuple[int, SC2MOGenMission], None]: + for distance in range(1, max_distance + 1): + target = jump(point, direction, distance) + if self.is_valid_coordinates(*target): + target_mission = missions[self.get_grid_index(*target)] + if not target_mission.option_empty: + return (distance, target_mission) + else: + # Out of bounds + return None + return None + + for (idx, mission) in enumerate(missions): + if mission.option_empty: + continue + point = self.get_grid_coordinates(idx) + if self.jump_distance_orthogonal > 1: + for direction in Canvas.jumps_orthogonal: + target = raycast(point, direction, self.jump_distance_orthogonal) + if target is not None: + (distance, target_mission) = target + if distance > 1: + # Distance 1 orthogonal jumps already come from the base grid + mission.next.append(target[1]) + if self.jump_distance_diagonal > 0: + for direction in Canvas.jumps_diagonal: + target = raycast(point, direction, self.jump_distance_diagonal) + if target is not None: + (distance, target_mission) = target + if distance == 1: + # Keep distance 1 diagonal slots only if the orthogonal neighbours are empty + x_neighbour = jump(point, (direction[0], 0), 1) + y_neighbour = jump(point, (0, direction[1]), 1) + if ( + missions[self.get_grid_index(*x_neighbour)].option_empty and + missions[self.get_grid_index(*y_neighbour)].option_empty + ): + mission.next.append(target_mission) + else: + mission.next.append(target_mission) + + return missions + + def final_setup(self, missions: List[SC2MOGenMission]): + # Pick missions near the original start and end to set as default entrance/exit + # if the user didn't set one themselves + def distance_lambda(point: Tuple[int, int]) -> Callable[[Tuple[int, SC2MOGenMission]], int]: + return lambda idx_mission: Grid.euclidean_distance_squared(self.get_grid_coordinates(idx_mission[0]), point) + + if not any(mission.option_entrance for mission in missions): + top_left = self.get_grid_coordinates(0) + closest_to_top_left = sorted( + ((idx, mission) for (idx, mission) in enumerate(missions) if not mission.option_empty), + key = distance_lambda(top_left) + ) + closest_to_top_left[0][1].option_entrance = True + + if not any(mission.option_exit for mission in missions): + bottom_right = self.get_grid_coordinates(len(missions) - 1) + closest_to_bottom_right = sorted( + ((idx, mission) for (idx, mission) in enumerate(missions) if not mission.option_empty), + key = distance_lambda(bottom_right) + ) + closest_to_bottom_right[0][1].option_exit = True + + def idx_group(self, group: str) -> Union[Set[int], None]: + if group not in self.groups: + return None + return set(self.groups[group]) + + +class Hopscotch(LayoutType): + """Alternating between one and two available missions. + Default entrance is index 0 in the top left, default exit is index `size - 1` in the bottom right.""" + width: int + spacer: int + two_start_positions: bool + + index_functions = [ + "top", "bottom", "middle", "corner" + ] + + # 0 2 + # 1 3 5 + # 4 6 + # 7 + + def set_options(self, options: Dict[str, Any]) -> Dict[str, Any]: + self.two_start_positions = options.pop("two_start_positions", False) and self.size >= 2 + if self.two_start_positions: + self.size += 1 + width: int = options.pop("width", 7) + self.width = max(width, 4) + spacer: int = options.pop("spacer", 2) + self.spacer = max(spacer, 1) + return options + + def make_slots(self, mission_factory: Callable[[], SC2MOGenMission]) -> List[SC2MOGenMission]: + slots = [mission_factory() for _ in range(self.size)] + if self.two_start_positions: + slots[0].option_empty = True + slots[1].option_entrance = True + slots[2].option_entrance = True + else: + slots[0].option_entrance = True + slots[-1].option_exit = True + + cycle = 0 + for idx in range(self.size): + if cycle == 0: + indices = [idx + 1, idx + 2] + cycle = 2 + elif cycle == 1: + indices = [idx + 1] + cycle -= 1 + else: + indices = [idx + 2] + cycle -= 1 + for next_idx in indices: + if next_idx < self.size: + slots[idx].next.append(slots[next_idx]) + + return slots + + @staticmethod + def space_at_column(idx: int) -> List[int]: + # -1 0 1 2 3 4 5 + amount = idx - 1 + if amount > 0: + return [-1 for _ in range(amount)] + else: + return [] + + def get_visual_layout(self) -> List[List[int]]: + # size offset by 1 to account for first column of two slots + cols: List[List[int]] = [] + col: List[int] = [] + col_size = 1 + for idx in range(self.size): + if col_size == 3: + col_size = 1 + cols.append(col) + col = [idx] + else: + col_size += 1 + col.append(idx) + if len(col) > 0: + cols.append(col) + + final_cols: List[List[int]] = [Hopscotch.space_at_column(idx) for idx in range(min(len(cols), self.width))] + for (col_idx, col) in enumerate(cols): + if col_idx >= self.width: + final_cols[col_idx % self.width].extend([-1 for _ in range(self.spacer)]) + final_cols[col_idx % self.width].extend(col) + + fill_to_longest(final_cols) + + return final_cols + + def idx_bottom(self) -> Set[int]: + corners = math.ceil(self.size / 3) + indices = [num * 3 + 1 for num in range(corners)] + return { + idx for idx in indices if idx < self.size + } + + def idx_top(self) -> Set[int]: + corners = math.ceil(self.size / 3) + indices = [num * 3 + 2 for num in range(corners)] + return { + idx for idx in indices if idx < self.size + } + + def idx_middle(self) -> Set[int]: + corners = math.ceil(self.size / 3) + indices = [num * 3 for num in range(corners)] + return { + idx for idx in indices if idx < self.size + } + + def idx_corner(self, number: str) -> Union[Set[int], None]: + try: + number = int(number) + except: + return None + corners = math.ceil(self.size / 3) + if number >= corners: + return None + indices = [number * 3 + n for n in range(3)] + return { + idx for idx in indices if idx < self.size + } + + +class Gauntlet(LayoutType): + """Long, linear layout. Goes horizontally and wraps around. + Default entrance is index 0 in the top left, default exit is index `size - 1` in the bottom right.""" + width: int + + # 0 1 2 3 + # + # 4 5 6 7 + + def set_options(self, options: Dict[str, Any]) -> Dict[str, Any]: + width: int = options.pop("width", 7) + self.width = min(max(width, 4), self.size) + return options + + def make_slots(self, mission_factory: Callable[[], SC2MOGenMission]) -> List[SC2MOGenMission]: + missions = [mission_factory() for _ in range(self.size)] + missions[0].option_entrance = True + missions[-1].option_exit = True + for i in range(self.size - 1): + missions[i].next.append(missions[i + 1]) + return missions + + def get_visual_layout(self) -> List[List[int]]: + columns = [[] for _ in range(self.width)] + for idx in range(self.size): + if idx >= self.width: + columns[idx % self.width].append(-1) + columns[idx % self.width].append(idx) + + fill_to_longest(columns) + + return columns + +class Blitz(LayoutType): + """Rows of missions, one mission per row required. + Default entrances are every mission in the top row, default exit is a central mission in the bottom row.""" + width: int + + index_functions = [ + "row" + ] + + # 0 1 2 3 + # 4 5 6 7 + + def set_options(self, options: Dict[str, Any]) -> Dict[str, Any]: + width = options.pop("width", 0) + if width < 1: + min_width, max_width = 2, 5 + mission_divisor = 5 + self.width = min(max(self.size // mission_divisor, min_width), max_width) + else: + self.width = min(self.size, width) + return options + + def make_slots(self, mission_factory: Callable[[], SC2MOGenMission]) -> List[SC2MOGenMission]: + slots = [mission_factory() for _ in range(self.size)] + for idx in range(self.width): + slots[idx].option_entrance = True + + # TODO: this is copied from the original mission order and works, but I'm not sure on the intent + # middle_column = self.width // 2 + # if self.size % self.width > middle_column: + # final_row = self.width * (self.size // self.width) + # final_mission = final_row + middle_column + # else: + # final_mission = self.size - 1 + # slots[final_mission].option_exit = True + + rows = self.size // self.width + for row in range(rows): + for top in range(self.width): + idx = row * self.width + top + for bot in range(self.width): + other = (row + 1) * self.width + bot + if other < self.size: + slots[idx].next.append(slots[other]) + if row == rows-1: + slots[idx].option_exit = True + + return slots + + def get_visual_layout(self) -> List[List[int]]: + columns = [[] for _ in range(self.width)] + for idx in range(self.size): + columns[idx % self.width].append(idx) + + fill_to_longest(columns) + + return columns + + def idx_row(self, row: str) -> Union[Set[int], None]: + try: + row = int(row) + except: + return None + rows = math.ceil(self.size / self.width) + if row >= rows: + return None + indices = [row * self.width + col for col in range(self.width)] + return { + idx for idx in indices if idx < self.size + } + +def fill_to_longest(columns: List[List[int]]): + longest = max(len(col) for col in columns) + for idx in range(len(columns)): + length = len(columns[idx]) + if length < longest: + columns[idx].extend([-1 for _ in range(longest - length)]) \ No newline at end of file diff --git a/worlds/sc2/mission_order/mission_pools.py b/worlds/sc2/mission_order/mission_pools.py new file mode 100644 index 000000000000..a3ab99f461c4 --- /dev/null +++ b/worlds/sc2/mission_order/mission_pools.py @@ -0,0 +1,251 @@ +from enum import IntEnum +from typing import TYPE_CHECKING, Dict, Set, List, Iterable + +from Options import OptionError +from ..mission_tables import SC2Mission, lookup_id_to_mission, MissionFlag, SC2Campaign +from worlds.AutoWorld import World + +if TYPE_CHECKING: + from .nodes import SC2MOGenMission + +class Difficulty(IntEnum): + RELATIVE = 0 + STARTER = 1 + EASY = 2 + MEDIUM = 3 + HARD = 4 + VERY_HARD = 5 + +# TODO figure out an organic way to get these +DEFAULT_DIFFICULTY_THRESHOLDS = { + Difficulty.STARTER: 0, + Difficulty.EASY: 10, + Difficulty.MEDIUM: 35, + Difficulty.HARD: 65, + Difficulty.VERY_HARD: 90, + Difficulty.VERY_HARD + 1: 100 +} + +STANDARD_DIFFICULTY_FILL_ORDER = ( + Difficulty.VERY_HARD, + Difficulty.STARTER, + Difficulty.HARD, + Difficulty.EASY, + Difficulty.MEDIUM, +) +"""Fill mission slots outer->inner difficulties, +so if multiple pools get exhausted, they will tend to overflow towards the middle.""" + +def modified_difficulty_thresholds(min_difficulty: Difficulty, max_difficulty: Difficulty) -> Dict[int, Difficulty]: + if min_difficulty == Difficulty.RELATIVE: + min_difficulty = Difficulty.STARTER + if max_difficulty == Difficulty.RELATIVE: + max_difficulty = Difficulty.VERY_HARD + thresholds: Dict[int, Difficulty] = {} + min_thresh = DEFAULT_DIFFICULTY_THRESHOLDS[min_difficulty] + total_thresh = DEFAULT_DIFFICULTY_THRESHOLDS[max_difficulty + 1] - min_thresh + for difficulty in range(min_difficulty, max_difficulty + 1): + threshold = DEFAULT_DIFFICULTY_THRESHOLDS[difficulty] - min_thresh + threshold *= 100 // total_thresh + thresholds[threshold] = Difficulty(difficulty) + return thresholds + +class SC2MOGenMissionPools: + """ + Manages available and used missions for a mission order. + """ + master_list: Set[int] + difficulty_pools: Dict[Difficulty, Set[int]] + _used_flags: Dict[MissionFlag, int] + _used_missions: List[SC2Mission] + _updated_difficulties: Dict[int, Difficulty] + _flag_ratios: Dict[MissionFlag, float] + _flag_weights: Dict[MissionFlag, int] + + def __init__(self) -> None: + self.master_list = {mission.id for mission in SC2Mission} + self.difficulty_pools = { + diff: {mission.id for mission in SC2Mission if mission.pool + 1 == diff} + for diff in Difficulty if diff != Difficulty.RELATIVE + } + self._used_flags = {} + self._used_missions = [] + self._updated_difficulties = {} + self._flag_ratios = {} + self._flag_weights = {} + + def set_exclusions(self, excluded: Iterable[SC2Mission], unexcluded: Iterable[SC2Mission]) -> None: + """Prevents all the missions that appear in the `excluded` list, but not in the `unexcluded` list, + from appearing in the mission order.""" + total_exclusions = [mission.id for mission in excluded if mission not in unexcluded] + self.master_list.difference_update(total_exclusions) + + def get_allowed_mission_count(self) -> int: + return len(self.master_list) + + def count_allowed_missions(self, campaign: SC2Campaign) -> int: + allowed_missions = [ + mission_id + for mission_id in self.master_list + if lookup_id_to_mission[mission_id].campaign == campaign + ] + return len(allowed_missions) + + def move_mission(self, mission: SC2Mission, old_diff: Difficulty, new_diff: Difficulty) -> None: + """Changes the difficulty of the given `mission`. Does nothing if the mission is not allowed to appear + or if it isn't set to the `old_diff` difficulty.""" + if mission.id in self.master_list and mission.id in self.difficulty_pools[old_diff]: + self.difficulty_pools[old_diff].remove(mission.id) + self.difficulty_pools[new_diff].add(mission.id) + self._updated_difficulties[mission.id] = new_diff + + def get_modified_mission_difficulty(self, mission: SC2Mission) -> Difficulty: + if mission.id in self._updated_difficulties: + return self._updated_difficulties[mission.id] + return Difficulty(mission.pool + 1) + + def get_pool_size(self, diff: Difficulty) -> int: + """Returns the amount of missions of the given difficulty that are allowed to appear.""" + return len(self.difficulty_pools[diff]) + + def get_used_flags(self) -> Dict[MissionFlag, int]: + """Returns a dictionary of all used flags and their appearance count within the mission order. + Flags that don't appear in the mission order also don't appear in this dictionary.""" + return self._used_flags + + def get_used_missions(self) -> List[SC2Mission]: + """Returns a set of all missions used in the mission order.""" + return self._used_missions + + def set_flag_balances(self, flag_ratios: Dict[MissionFlag, int], flag_weights: Dict[MissionFlag, int]): + # Ensure the ratios are percentages + ratio_sum = sum(ratio for ratio in flag_ratios.values()) + self._flag_ratios = {flag: ratio / ratio_sum for flag, ratio in flag_ratios.items()} + self._flag_weights = flag_weights + + def pick_balanced_mission(self, world: World, pool: List[int]) -> int: + """Applies ratio-based and weight-based balancing to pick a preferred mission from a given mission pool.""" + # Currently only used for race balancing + # Untested for flags that may overlap or not be present at all, but should at least generate + balanced_pool = pool + if len(self._flag_ratios) > 0: + relevant_used_flag_count = max(sum(self._used_flags.get(flag, 0) for flag in self._flag_ratios), 1) + current_ratios = { + flag: self._used_flags.get(flag, 0) / relevant_used_flag_count + for flag in self._flag_ratios + } + # Desirability of missions is the difference between target and current ratios for relevant flags + flag_scores = { + flag: self._flag_ratios[flag] - current_ratios[flag] + for flag in self._flag_ratios + } + mission_scores = [ + sum( + flag_scores[flag] for flag in self._flag_ratios + if flag in lookup_id_to_mission[mission].flags + ) + for mission in balanced_pool + ] + # Only keep the missions that create the best balance + best_score = max(mission_scores) + balanced_pool = [mission for idx, mission in enumerate(balanced_pool) if mission_scores[idx] == best_score] + + balanced_weights = [1.0 for _ in balanced_pool] + if len(self._flag_weights) > 0: + relevant_used_flag_count = max(sum(self._used_flags.get(flag, 0) for flag in self._flag_weights), 1) + # Higher usage rate of relevant flags means lower desirability + flag_scores = { + flag: (relevant_used_flag_count - self._used_flags.get(flag, 0)) * self._flag_weights[flag] + for flag in self._flag_weights + } + # Mission scores are averaged across the mission's flags, + # else flags that aren't always present will inflate weights + mission_scores = [ + sum( + flag_scores[flag] for flag in self._flag_weights + if flag in lookup_id_to_mission[mission].flags + ) / sum(flag in lookup_id_to_mission[mission].flags for flag in self._flag_weights) + for mission in balanced_pool + ] + balanced_weights = mission_scores + + if sum(balanced_weights) == 0.0: + balanced_weights = [1.0 for _ in balanced_weights] + return world.random.choices(balanced_pool, balanced_weights, k=1)[0] + + def pull_specific_mission(self, mission: SC2Mission) -> None: + """Marks the given mission as present in the mission order.""" + # Remove the mission from the master list and whichever difficulty pool it is in + if mission.id in self.master_list: + self.master_list.remove(mission.id) + for diff in self.difficulty_pools: + if mission.id in self.difficulty_pools[diff]: + self.difficulty_pools[diff].remove(mission.id) + break + self._add_mission_stats(mission) + + def _add_mission_stats(self, mission: SC2Mission) -> None: + # Update used flag counts & missions + # Done weirdly for Python <= 3.10 compatibility + flag: MissionFlag + for flag in iter(MissionFlag): # type: ignore + if flag & mission.flags == flag: + self._used_flags.setdefault(flag, 0) + self._used_flags[flag] += 1 + self._used_missions.append(mission) + + def pull_random_mission(self, world: World, slot: 'SC2MOGenMission', *, prefer_close_difficulty: bool = False) -> SC2Mission: + """Picks a random mission from the mission pool of the given slot and marks it as present in the mission order. + + With `prefer_close_difficulty = True` the mission is picked to be as close to the slot's desired difficulty as possible.""" + pool = slot.option_mission_pool.intersection(self.master_list) + + difficulty_pools: Dict[int, List[int]] = { + diff: sorted(pool.intersection(self.difficulty_pools[diff])) + for diff in Difficulty if diff != Difficulty.RELATIVE + } + + if len(pool) == 0: + raise OptionError(f"No available mission to be picked for slot {slot.get_address_to_node()}.") + + desired_difficulty = slot.option_difficulty + if prefer_close_difficulty: + # Iteratively look up and down around the slot's desired difficulty + # Either a difficulty with valid missions is found, or an error is raised + difficulty_offset = 0 + final_pool = difficulty_pools[desired_difficulty] + while len(final_pool) == 0: + higher_diff = min(desired_difficulty + difficulty_offset + 1, Difficulty.VERY_HARD) + final_pool = difficulty_pools[higher_diff] + if len(final_pool) > 0: + break + lower_diff = max(desired_difficulty - difficulty_offset, Difficulty.STARTER) + final_pool = difficulty_pools[lower_diff] + if len(final_pool) > 0: + break + if lower_diff == Difficulty.STARTER and higher_diff == Difficulty.VERY_HARD: + raise IndexError() + difficulty_offset += 1 + + else: + # Consider missions from all lower difficulties as well the desired difficulty + # Only take from higher difficulties if no lower difficulty is possible + final_pool = [ + mission + for difficulty in range(Difficulty.STARTER, desired_difficulty + 1) + for mission in difficulty_pools[difficulty] + ] + difficulty_offset = 1 + while len(final_pool) == 0: + higher_difficulty = desired_difficulty + difficulty_offset + if higher_difficulty > Difficulty.VERY_HARD: + raise IndexError() + final_pool = difficulty_pools[higher_difficulty] + difficulty_offset += 1 + + # Remove the mission from the master list + mission = lookup_id_to_mission[self.pick_balanced_mission(world, final_pool)] + self.master_list.remove(mission.id) + self.difficulty_pools[self.get_modified_mission_difficulty(mission)].remove(mission.id) + self._add_mission_stats(mission) + return mission diff --git a/worlds/sc2/mission_order/nodes.py b/worlds/sc2/mission_order/nodes.py new file mode 100644 index 000000000000..a18a433c8812 --- /dev/null +++ b/worlds/sc2/mission_order/nodes.py @@ -0,0 +1,606 @@ +""" +Contains the data structures that make up a mission order. +Data in these structures is validated in .options.py and manipulated by .generation.py. +""" + +from __future__ import annotations +from typing import Dict, Set, Callable, List, Any, Type, Optional, Union, TYPE_CHECKING +from weakref import ref, ReferenceType +from dataclasses import asdict +from abc import ABC, abstractmethod +import logging + +from BaseClasses import Region, CollectionState +from ..mission_tables import SC2Mission +from ..item import item_names +from .layout_types import LayoutType +from .entry_rules import SubRuleEntryRule, ItemEntryRule +from .mission_pools import Difficulty +from .slot_data import CampaignSlotData, LayoutSlotData, MissionSlotData + +if TYPE_CHECKING: + from .. import SC2World + +class MissionOrderNode(ABC): + parent: Optional[ReferenceType[MissionOrderNode]] + important_beat_event: bool + + def get_parent(self, address_so_far: str, full_address: str) -> MissionOrderNode: + if self.parent is None: + raise ValueError( + f"Address \"{address_so_far}\" (from \"{full_address}\") could not find a parent object. " + "This should mean the address contains \"..\" too often." + ) + return self.parent() + + @abstractmethod + def search(self, term: str) -> Union[List[MissionOrderNode], None]: + raise NotImplementedError + + @abstractmethod + def child_type_name(self) -> str: + raise NotImplementedError + + @abstractmethod + def get_missions(self) -> List[SC2MOGenMission]: + raise NotImplementedError + + @abstractmethod + def get_exits(self) -> List[SC2MOGenMission]: + raise NotImplementedError + + @abstractmethod + def get_visual_requirement(self, start_node: MissionOrderNode) -> Union[str, SC2MOGenMission]: + raise NotImplementedError + + @abstractmethod + def get_key_name(self) -> str: + raise NotImplementedError + + @abstractmethod + def get_min_depth(self) -> int: + raise NotImplementedError + + @abstractmethod + def get_address_to_node(self) -> str: + raise NotImplementedError + + +class SC2MOGenMissionOrder(MissionOrderNode): + """ + The top-level data structure for mission orders. + """ + campaigns: List[SC2MOGenCampaign] + sorted_missions: Dict[Difficulty, List[SC2MOGenMission]] + """All mission slots in the mission order sorted by their difficulty, but not their depth.""" + fixed_missions: List[SC2MOGenMission] + """All mission slots that have a plando'd mission.""" + items_to_lock: Dict[str, int] + keys_to_resolve: Dict[MissionOrderNode, List[ItemEntryRule]] + goal_missions: List[SC2MOGenMission] + max_depth: int + + def __init__(self, world: 'SC2World', data: Dict[str, Any]): + self.campaigns = [] + self.sorted_missions = {diff: [] for diff in Difficulty if diff != Difficulty.RELATIVE} + self.fixed_missions = [] + self.items_to_lock = {} + self.keys_to_resolve = {} + self.goal_missions = [] + self.parent = None + + for (campaign_name, campaign_data) in data.items(): + campaign = SC2MOGenCampaign(world, ref(self), campaign_name, campaign_data) + self.campaigns.append(campaign) + + # Check that the mission order actually has a goal + for campaign in self.campaigns: + if campaign.option_goal: + self.goal_missions.extend(mission for mission in campaign.exits) + for layout in campaign.layouts: + if layout.option_goal: + self.goal_missions.extend(layout.exits) + for mission in layout.missions: + if mission.option_goal and not mission.option_empty: + self.goal_missions.append(mission) + # Remove duplicates + for goal in self.goal_missions: + while self.goal_missions.count(goal) > 1: + self.goal_missions.remove(goal) + + # If not, set the last defined campaign as goal + if len(self.goal_missions) == 0: + self.campaigns[-1].option_goal = True + self.goal_missions.extend(mission for mission in self.campaigns[-1].exits) + + # Apply victory cache option wherever the value has not yet been defined; must happen after goal missions are decided + for mission in self.get_missions(): + if mission.option_victory_cache != -1: + # Already set + continue + if mission in self.goal_missions: + mission.option_victory_cache = 0 + else: + mission.option_victory_cache = world.options.victory_cache.value + + # Resolve names + used_names: Set[str] = set() + for campaign in self.campaigns: + names = [campaign.option_name] if len(campaign.option_display_name) == 0 else campaign.option_display_name + if campaign.option_unique_name: + names = [name for name in names if name not in used_names] + campaign.display_name = world.random.choice(names) + used_names.add(campaign.display_name) + for layout in campaign.layouts: + names = [layout.option_name] if len(layout.option_display_name) == 0 else layout.option_display_name + if layout.option_unique_name: + names = [name for name in names if name not in used_names] + layout.display_name = world.random.choice(names) + used_names.add(layout.display_name) + + def get_slot_data(self) -> List[Dict[str, Any]]: + # [(campaign data, [(layout data, [[(mission data)]] )] )] + return [asdict(campaign.get_slot_data()) for campaign in self.campaigns] + + def search(self, term: str) -> Union[List[MissionOrderNode], None]: + return [ + campaign.layouts[0] if campaign.option_single_layout_campaign else campaign + for campaign in self.campaigns + if campaign.option_name.casefold() == term.casefold() + ] + + def child_type_name(self) -> str: + return "Campaign" + + def get_missions(self) -> List[SC2MOGenMission]: + return [mission for campaign in self.campaigns for layout in campaign.layouts for mission in layout.missions] + + def get_exits(self) -> List[SC2MOGenMission]: + return [] + + def get_visual_requirement(self, _start_node: MissionOrderNode) -> Union[str, SC2MOGenMission]: + return "All Missions" + + def get_key_name(self) -> str: + return super().get_key_name() # type: ignore + + def get_min_depth(self) -> int: + return super().get_min_depth() # type: ignore + + def get_address_to_node(self): + return self.campaigns[0].get_address_to_node() + "/.." + + +class SC2MOGenCampaign(MissionOrderNode): + option_name: str # name of this campaign + option_display_name: List[str] + option_unique_name: bool + option_entry_rules: List[Dict[str, Any]] + option_unique_progression_track: int # progressive keys under this campaign and on this track will be changed to a unique track + option_goal: bool # whether this campaign is required to beat the game + # minimum difficulty of this campaign + # 'relative': based on the median distance of the first mission + option_min_difficulty: Difficulty + # maximum difficulty of this campaign + # 'relative': based on the median distance of the last mission + option_max_difficulty: Difficulty + option_single_layout_campaign: bool + + # layouts of this campaign in correct order + layouts: List[SC2MOGenLayout] + exits: List[SC2MOGenMission] # missions required to beat this campaign (missions marked "exit" in layouts marked "exit") + entry_rule: SubRuleEntryRule + display_name: str + + min_depth: int + max_depth: int + + def __init__(self, world: 'SC2World', parent: ReferenceType[SC2MOGenMissionOrder], name: str, data: Dict[str, Any]): + self.parent = parent + self.important_beat_event = False + self.option_name = name + self.option_display_name = data["display_name"] + self.option_unique_name = data["unique_name"] + self.option_goal = data["goal"] + self.option_entry_rules = data["entry_rules"] + self.option_unique_progression_track = data["unique_progression_track"] + self.option_min_difficulty = Difficulty(data["min_difficulty"]) + self.option_max_difficulty = Difficulty(data["max_difficulty"]) + self.option_single_layout_campaign = data["single_layout_campaign"] + self.layouts = [] + self.exits = [] + + for (layout_name, layout_data) in data.items(): + if type(layout_data) == dict: + layout = SC2MOGenLayout(world, ref(self), layout_name, layout_data) + self.layouts.append(layout) + + # Collect required missions (marked layouts' exits) + if layout.option_exit: + self.exits.extend(layout.exits) + + # If no exits are set, use the last defined layout + if len(self.exits) == 0: + self.layouts[-1].option_exit = True + self.exits.extend(self.layouts[-1].exits) + + def is_beaten(self, beaten_missions: Set[SC2MOGenMission]) -> bool: + return beaten_missions.issuperset(self.exits) + + def is_always_unlocked(self, in_region_creation = False) -> bool: + return self.entry_rule.is_always_fulfilled(in_region_creation) + + def is_unlocked(self, beaten_missions: Set[SC2MOGenMission], in_region_creation = False) -> bool: + return self.entry_rule.is_fulfilled(beaten_missions, in_region_creation) + + def search(self, term: str) -> Union[List[MissionOrderNode], None]: + return [ + layout + for layout in self.layouts + if layout.option_name.casefold() == term.casefold() + ] + + def child_type_name(self) -> str: + return "Layout" + + def get_missions(self) -> List[SC2MOGenMission]: + return [mission for layout in self.layouts for mission in layout.missions] + + def get_exits(self) -> List[SC2MOGenMission]: + return self.exits + + def get_visual_requirement(self, start_node: MissionOrderNode) -> Union[str, SC2MOGenMission]: + visual_name = self.get_visual_name() + # Needs special handling for double-parent, which is valid for missions but errors for campaigns + first_parent = start_node.get_parent("", "") + if ( + first_parent is self or ( + first_parent.parent is not None and first_parent.get_parent("", "") is self + ) + ) and visual_name == "": + return "this campaign" + return visual_name + + def get_visual_name(self) -> str: + return self.display_name + + def get_key_name(self) -> str: + return item_names._TEMPLATE_NAMED_CAMPAIGN_KEY.format(self.get_visual_name()) + + def get_min_depth(self) -> int: + return self.min_depth + + def get_address_to_node(self) -> str: + return f"{self.option_name}" + + def get_slot_data(self) -> CampaignSlotData: + if self.important_beat_event: + exits = [slot.mission.id for slot in self.exits] + else: + exits = [] + + return CampaignSlotData( + self.get_visual_name(), + asdict(self.entry_rule.to_slot_data()), + exits, + [asdict(layout.get_slot_data()) for layout in self.layouts] + ) + + +class SC2MOGenLayout(MissionOrderNode): + option_name: str # name of this layout + option_display_name: List[str] # visual name of this layout + option_unique_name: bool + option_type: Type[LayoutType] # type of this layout + option_size: int # amount of missions in this layout + option_goal: bool # whether this layout is required to beat the game + option_exit: bool # whether this layout is required to beat its parent campaign + option_mission_pool: List[int] # IDs of valid missions for this layout + option_missions: List[Dict[str, Any]] + + option_entry_rules: List[Dict[str, Any]] + option_unique_progression_track: int # progressive keys under this layout and on this track will be changed to a unique track + + # minimum difficulty of this layout + # 'relative': based on the median distance of the first mission + option_min_difficulty: Difficulty + # maximum difficulty of this layout + # 'relative': based on the median distance of the last mission + option_max_difficulty: Difficulty + + missions: List[SC2MOGenMission] + layout_type: LayoutType + entrances: List[SC2MOGenMission] + exits: List[SC2MOGenMission] + entry_rule: SubRuleEntryRule + display_name: str + + min_depth: int + max_depth: int + + def __init__(self, world: 'SC2World', parent: ReferenceType[SC2MOGenCampaign], name: str, data: Dict): + self.parent: ReferenceType[SC2MOGenCampaign] = parent + self.important_beat_event = False + self.option_name = name + self.option_display_name = data.pop("display_name") + self.option_unique_name = data.pop("unique_name") + self.option_type = data.pop("type") + self.option_size = data.pop("size") + self.option_goal = data.pop("goal") + self.option_exit = data.pop("exit") + self.option_mission_pool = data.pop("mission_pool") + self.option_missions = data.pop("missions") + self.option_entry_rules = data.pop("entry_rules") + self.option_unique_progression_track = data.pop("unique_progression_track") + self.option_min_difficulty = Difficulty(data.pop("min_difficulty")) + self.option_max_difficulty = Difficulty(data.pop("max_difficulty")) + self.missions = [] + self.entrances = [] + self.exits = [] + + # Check for positive size now instead of during YAML validation to actively error with default size + if self.option_size == 0: + raise ValueError(f"Layout \"{self.option_name}\" has a size of 0.") + + # Build base layout + from . import layout_types + self.layout_type: LayoutType = getattr(layout_types, self.option_type)(self.option_size) + unused = self.layout_type.set_options(data) + if len(unused) > 0: + logging.warning(f"SC2 ({world.player_name}): Layout \"{self.option_name}\" has unknown options: {list(unused.keys())}") + mission_factory = lambda: SC2MOGenMission(ref(self), set(self.option_mission_pool)) + self.missions = self.layout_type.make_slots(mission_factory) + + # Update missions with user data + for mission_data in self.option_missions: + indices: Set[int] = set() + index_terms: List[Union[int, str]] = mission_data["index"] + for term in index_terms: + result = self.resolve_index_term(term) + indices.update(result) + for idx in indices: + self.missions[idx].update_with_data(mission_data) + + # Let layout respond to user changes + self.layout_type.final_setup(self.missions) + + for mission in self.missions: + if mission.option_entrance: + self.entrances.append(mission) + if mission.option_exit: + self.exits.append(mission) + if mission.option_next is not None: + mission.next = [self.missions[idx] for term in mission.option_next for idx in sorted(self.resolve_index_term(term))] + + # Set up missions' prev data + for mission in self.missions: + for next_mission in mission.next: + next_mission.prev.append(mission) + + # Remove empty missions from access data + for mission in self.missions: + if mission.option_empty: + for next_mission in mission.next: + next_mission.prev.remove(mission) + mission.next.clear() + for prev_mission in mission.prev: + prev_mission.next.remove(mission) + mission.prev.clear() + + # Clean up data and options + all_empty = True + for mission in self.missions: + if mission.option_empty: + # Empty missions cannot be entrances, exits, or required + # This is done now instead of earlier to make "set all default entrances to empty" not fail + if mission in self.entrances: + self.entrances.remove(mission) + mission.option_entrance = False + if mission in self.exits: + self.exits.remove(mission) + mission.option_exit = False + mission.option_goal = False + # Empty missions are also not allowed to cause secondary effects via entry rules (eg. create key items) + mission.option_entry_rules = [] + else: + all_empty = False + # Establish the following invariant: + # A non-empty mission has no prev missions <=> A non-empty mission is an entrance + # This is mandatory to guarantee the entire layout is accessible via consecutive .nexts + # Note that the opposite is not enforced for exits to allow fully optional layouts + if len(mission.prev) == 0: + mission.option_entrance = True + self.entrances.append(mission) + elif mission.option_entrance: + for prev_mission in mission.prev: + prev_mission.next.remove(mission) + mission.prev.clear() + if all_empty: + raise Exception(f"Layout \"{self.option_name}\" only contains empty mission slots.") + + def is_beaten(self, beaten_missions: Set[SC2MOGenMission]) -> bool: + return beaten_missions.issuperset(self.exits) + + def is_always_unlocked(self, in_region_creation = False) -> bool: + return self.entry_rule.is_always_fulfilled(in_region_creation) + + def is_unlocked(self, beaten_missions: Set[SC2MOGenMission], in_region_creation = False) -> bool: + return self.entry_rule.is_fulfilled(beaten_missions, in_region_creation) + + def resolve_index_term(self, term: Union[str, int], *, ignore_out_of_bounds: bool = True, reject_none: bool = True) -> Union[Set[int], None]: + try: + result = {int(term)} + except ValueError: + if term == "entrances": + result = {idx for idx in range(len(self.missions)) if self.missions[idx].option_entrance} + elif term == "exits": + result = {idx for idx in range(len(self.missions)) if self.missions[idx].option_exit} + elif term == "all": + result = {idx for idx in range(len(self.missions))} + else: + result = self.layout_type.parse_index(term) + if result is None and reject_none: + raise ValueError(f"Layout \"{self.option_name}\" could not resolve mission index term \"{term}\".") + if ignore_out_of_bounds: + result = [index for index in result if index >= 0 and index < len(self.missions)] + return result + + def get_parent(self, _address_so_far: str, _full_address: str) -> MissionOrderNode: + if self.parent().option_single_layout_campaign: + parent = self.parent().parent + else: + parent = self.parent + return parent() + + def search(self, term: str) -> Union[List[MissionOrderNode], None]: + indices = self.resolve_index_term(term, reject_none=False) + if indices is None: + # Let the address parser handle the fail case + return [] + missions = [self.missions[index] for index in sorted(indices)] + return missions + + def child_type_name(self) -> str: + return "Mission" + + def get_missions(self) -> List[SC2MOGenMission]: + return [mission for mission in self.missions] + + def get_exits(self) -> List[SC2MOGenMission]: + return self.exits + + def get_visual_requirement(self, start_node: MissionOrderNode) -> Union[str, SC2MOGenMission]: + visual_name = self.get_visual_name() + if start_node.get_parent("", "") is self and visual_name == "": + return "this questline" + return visual_name + + def get_visual_name(self) -> str: + return self.display_name + + def get_key_name(self) -> str: + return item_names._TEMPLATE_NAMED_LAYOUT_KEY.format(self.get_visual_name(), self.parent().get_visual_name()) + + def get_min_depth(self) -> int: + return self.min_depth + + def get_address_to_node(self) -> str: + campaign = self.parent() + if campaign.option_single_layout_campaign: + return f"{self.option_name}" + return self.parent().get_address_to_node() + f"/{self.option_name}" + + def get_slot_data(self) -> LayoutSlotData: + mission_slots = [ + [ + asdict(self.missions[idx].get_slot_data() if (idx >= 0 and not self.missions[idx].option_empty) else MissionSlotData.empty()) + for idx in column + ] + for column in self.layout_type.get_visual_layout() + ] + if self.important_beat_event: + exits = [slot.mission.id for slot in self.exits] + else: + exits = [] + + return LayoutSlotData( + self.get_visual_name(), + asdict(self.entry_rule.to_slot_data()), + exits, + mission_slots + ) + + +class SC2MOGenMission(MissionOrderNode): + option_goal: bool # whether this mission is required to beat the game + option_entrance: bool # whether this mission is unlocked when the layout is unlocked + option_exit: bool # whether this mission is required to beat its parent layout + option_empty: bool # whether this slot contains a mission at all + option_next: Union[None, List[Union[int, str]]] # indices of internally connected missions + option_entry_rules: List[Dict[str, Any]] + option_difficulty: Difficulty # difficulty pool this mission pulls from + option_mission_pool: Set[int] # Allowed mission IDs for this slot + option_victory_cache: int # Number of victory cache locations tied to the mission name + + entry_rule: SubRuleEntryRule + min_depth: int # Smallest amount of missions to beat before this slot is accessible + + mission: SC2Mission + region: Region + + next: List[SC2MOGenMission] + prev: List[SC2MOGenMission] + + def __init__(self, parent: ReferenceType[SC2MOGenLayout], parent_mission_pool: Set[int]): + self.parent: ReferenceType[SC2MOGenLayout] = parent + self.important_beat_event = False + self.option_mission_pool = parent_mission_pool + self.option_goal = False + self.option_entrance = False + self.option_exit = False + self.option_empty = False + self.option_next = None + self.option_entry_rules = [] + self.option_difficulty = Difficulty.RELATIVE + self.next = [] + self.prev = [] + self.min_depth = -1 + self.option_victory_cache = -1 + + def update_with_data(self, data: Dict): + self.option_goal = data.get("goal", self.option_goal) + self.option_entrance = data.get("entrance", self.option_entrance) + self.option_exit = data.get("exit", self.option_exit) + self.option_empty = data.get("empty", self.option_empty) + self.option_next = data.get("next", self.option_next) + self.option_entry_rules = data.get("entry_rules", self.option_entry_rules) + self.option_difficulty = data.get("difficulty", self.option_difficulty) + self.option_mission_pool = data.get("mission_pool", self.option_mission_pool) + self.option_victory_cache = data.get("victory_cache", -1) + + def is_always_unlocked(self, in_region_creation = False) -> bool: + return self.entry_rule.is_always_fulfilled(in_region_creation) + + def is_unlocked(self, beaten_missions: Set[SC2MOGenMission], in_region_creation = False) -> bool: + return self.entry_rule.is_fulfilled(beaten_missions, in_region_creation) + + def beat_item(self) -> str: + return f"Beat {self.mission.mission_name}" + + def beat_rule(self, player) -> Callable[[CollectionState], bool]: + return lambda state: state.has(self.beat_item(), player) + + def search(self, term: str) -> Union[List[MissionOrderNode], None]: + return None + + def child_type_name(self) -> str: + return "" + + def get_missions(self) -> List[SC2MOGenMission]: + return [self] + + def get_exits(self) -> List[SC2MOGenMission]: + return [self] + + def get_visual_requirement(self, _start_node: MissionOrderNode) -> Union[str, SC2MOGenMission]: + return self + + def get_key_name(self) -> str: + return item_names._TEMPLATE_MISSION_KEY.format(self.mission.mission_name) + + def get_min_depth(self) -> int: + return self.min_depth + + def get_address_to_node(self) -> str: + layout = self.parent() + assert layout is not None + index = layout.missions.index(self) + return layout.get_address_to_node() + f"/{index}" + + def get_slot_data(self) -> MissionSlotData: + return MissionSlotData( + self.mission.id, + [mission.mission.id for mission in self.prev], + self.entry_rule.to_slot_data(), + self.option_victory_cache, + ) diff --git a/worlds/sc2/mission_order/options.py b/worlds/sc2/mission_order/options.py new file mode 100644 index 000000000000..84630ba13a95 --- /dev/null +++ b/worlds/sc2/mission_order/options.py @@ -0,0 +1,472 @@ +""" +Contains the Custom Mission Order option. Also validates the option value, so generation can assume the data matches the specification. +""" + +from __future__ import annotations +import random + +from Options import OptionDict, Visibility +from schema import Schema, Optional, And, Or +import typing +from typing import Any, Union, Dict, Set, List +import copy + +from ..mission_tables import lookup_name_to_mission +from ..mission_groups import mission_groups +from ..item.item_tables import item_table +from ..item.item_groups import item_name_groups +from . import layout_types +from .layout_types import LayoutType, Column, Grid, Hopscotch, Gauntlet, Blitz, Canvas +from .mission_pools import Difficulty +from .presets_static import ( + static_preset, preset_mini_wol_with_prophecy, preset_mini_wol, preset_mini_hots, preset_mini_prophecy, + preset_mini_lotv_prologue, preset_mini_lotv, preset_mini_lotv_epilogue, preset_mini_nco, + preset_wol_with_prophecy, preset_wol, preset_prophecy, preset_hots, preset_lotv_prologue, + preset_lotv_epilogue, preset_lotv, preset_nco +) +from .presets_scripted import make_golden_path + +GENERIC_KEY_NAME = "Key".casefold() +GENERIC_PROGRESSIVE_KEY_NAME = "Progressive Key".casefold() + +STR_OPTION_VALUES: Dict[str, Dict[str, Any]] = { + "type": { + "column": Column.__name__, "grid": Grid.__name__, "hopscotch": Hopscotch.__name__, "gauntlet": Gauntlet.__name__, "blitz": Blitz.__name__, + "canvas": Canvas.__name__, + }, + "difficulty": { + "relative": Difficulty.RELATIVE.value, "starter": Difficulty.STARTER.value, "easy": Difficulty.EASY.value, + "medium": Difficulty.MEDIUM.value, "hard": Difficulty.HARD.value, "very hard": Difficulty.VERY_HARD.value + }, + "preset": { + "none": lambda _: {}, + "wol + prophecy": static_preset(preset_wol_with_prophecy), + "wol": static_preset(preset_wol), + "prophecy": static_preset(preset_prophecy), + "hots": static_preset(preset_hots), + "prologue": static_preset(preset_lotv_prologue), + "lotv prologue": static_preset(preset_lotv_prologue), + "lotv": static_preset(preset_lotv), + "epilogue": static_preset(preset_lotv_epilogue), + "lotv epilogue": static_preset(preset_lotv_epilogue), + "nco": static_preset(preset_nco), + "mini wol + prophecy": static_preset(preset_mini_wol_with_prophecy), + "mini wol": static_preset(preset_mini_wol), + "mini prophecy": static_preset(preset_mini_prophecy), + "mini hots": static_preset(preset_mini_hots), + "mini prologue": static_preset(preset_mini_lotv_prologue), + "mini lotv prologue": static_preset(preset_mini_lotv_prologue), + "mini lotv": static_preset(preset_mini_lotv), + "mini epilogue": static_preset(preset_mini_lotv_epilogue), + "mini lotv epilogue": static_preset(preset_mini_lotv_epilogue), + "mini nco": static_preset(preset_mini_nco), + "golden path": make_golden_path + }, +} +STR_OPTION_VALUES["min_difficulty"] = STR_OPTION_VALUES["difficulty"] +STR_OPTION_VALUES["max_difficulty"] = STR_OPTION_VALUES["difficulty"] +GLOBAL_ENTRY = "global" + +StrOption = lambda cat: And(str, lambda val: val.lower() in STR_OPTION_VALUES[cat]) +IntNegOne = And(int, lambda val: val >= -1) +IntZero = And(int, lambda val: val >= 0) +IntOne = And(int, lambda val: val >= 1) +IntPercent = And(int, lambda val: 0 <= val <= 100) +IntZeroToTen = And(int, lambda val: 0 <= val <= 10) + +SubRuleEntryRule = { + "rules": [{str: object}], # recursive schema checking is too hard + "amount": IntNegOne, +} +MissionCountEntryRule = { + "scope": [str], + "amount": IntNegOne, +} +BeatMissionsEntryRule = { + "scope": [str], +} +ItemEntryRule = { + "items": {str: int} +} +EntryRule = Or(SubRuleEntryRule, MissionCountEntryRule, BeatMissionsEntryRule, ItemEntryRule) +SchemaDifficulty = Or(*[value.value for value in Difficulty]) + +class CustomMissionOrder(OptionDict): + """ + Used to generate a custom mission order. Please see documentation to understand usage. + Will do nothing unless `mission_order` is set to `custom`. + """ + display_name = "Custom Mission Order" + visibility = Visibility.template + value: Dict[str, Dict[str, Any]] + default = { + "Default Campaign": { + "display_name": "null", + "unique_name": False, + "entry_rules": [], + "unique_progression_track": 0, + "goal": True, + "min_difficulty": "relative", + "max_difficulty": "relative", + GLOBAL_ENTRY: { + "display_name": "null", + "unique_name": False, + "entry_rules": [], + "unique_progression_track": 0, + "goal": False, + "exit": False, + "mission_pool": ["all missions"], + "min_difficulty": "relative", + "max_difficulty": "relative", + "missions": [], + }, + "Default Layout": { + "type": "grid", + "size": 9, + }, + }, + } + schema = Schema({ + # Campaigns + str: { + "display_name": [str], + "unique_name": bool, + "entry_rules": [EntryRule], + "unique_progression_track": int, + "goal": bool, + "min_difficulty": SchemaDifficulty, + "max_difficulty": SchemaDifficulty, + "single_layout_campaign": bool, + # Layouts + str: { + "display_name": [str], + "unique_name": bool, + # Type options + "type": lambda val: issubclass(getattr(layout_types, val), LayoutType), + "size": IntOne, + # Link options + "exit": bool, + "goal": bool, + "entry_rules": [EntryRule], + "unique_progression_track": int, + # Mission pool options + "mission_pool": {int}, + "min_difficulty": SchemaDifficulty, + "max_difficulty": SchemaDifficulty, + # Allow arbitrary options for layout types + Optional(str): Or(int, str, bool, [Or(int, str, bool)]), + # Mission slots + "missions": [{ + "index": [Or(int, str)], + Optional("entrance"): bool, + Optional("exit"): bool, + Optional("goal"): bool, + Optional("empty"): bool, + Optional("next"): [Or(int, str)], + Optional("entry_rules"): [EntryRule], + Optional("mission_pool"): {int}, + Optional("difficulty"): SchemaDifficulty, + Optional("victory_cache"): IntZeroToTen, + }], + }, + } + }) + + def __init__(self, yaml_value: Dict[str, Dict[str, Any]]) -> None: + # This function constructs self.value by parts, + # so the parent constructor isn't called + self.value: Dict[str, Dict[str, Any]] = {} + if yaml_value == self.default: # If this option is default, it shouldn't mess with its own values + yaml_value = copy.deepcopy(self.default) + + for campaign in yaml_value: + self.value[campaign] = {} + + # Check if this campaign has a layout type, making it a campaign-level layout + single_layout_campaign = "type" in yaml_value[campaign] + if single_layout_campaign: + # Single-layout campaigns are not allowed to declare more layouts + single_layout = {key: val for (key, val) in yaml_value[campaign].items() if type(val) != dict} + yaml_value[campaign] = {campaign: single_layout} + # Campaign should inherit certain values from the layout + if "goal" not in single_layout or not single_layout["goal"]: + yaml_value[campaign]["goal"] = False + if "unique_progression_track" in single_layout: + yaml_value[campaign]["unique_progression_track"] = single_layout["unique_progression_track"] + # Hide campaign name for single-layout campaigns + yaml_value[campaign]["display_name"] = "" + yaml_value[campaign]["single_layout_campaign"] = single_layout_campaign + + # Check if this campaign has a global layout + global_dict = {} + for name in yaml_value[campaign]: + if name.lower() == GLOBAL_ENTRY: + global_dict = yaml_value[campaign].pop(name) + break + + # Strip layouts and unknown options from the campaign + # The latter are assumed to be preset options + preset_key: str = yaml_value[campaign].pop("preset", "none") + layout_keys = [key for (key, val) in yaml_value[campaign].items() if type(val) == dict] + layouts = {key: yaml_value[campaign].pop(key) for key in layout_keys} + preset_option_keys = [key for key in yaml_value[campaign] if key not in self.default["Default Campaign"]] + preset_option_keys.remove("single_layout_campaign") + preset_options = {key: yaml_value[campaign].pop(key) for key in preset_option_keys} + + # Resolve preset + preset: Dict[str, Any] = _resolve_string_option_single("preset", preset_key)(preset_options) + # Preset global is resolved internally to avoid conflict with user global + preset_global_dict = {} + for name in preset: + if name.lower() == GLOBAL_ENTRY: + preset_global_dict = preset.pop(name) + break + preset_layout_keys = [key for (key, val) in preset.items() if type(val) == dict] + preset_layouts = {key: preset.pop(key) for key in preset_layout_keys} + ordered_layouts = {key: copy.deepcopy(preset_global_dict) for key in preset_layout_keys} + for key in preset_layout_keys: + ordered_layouts[key].update(preset_layouts[key]) + # Final layouts are preset layouts (updated by same-name user layouts) followed by custom user layouts + for key in layouts: + if key in ordered_layouts: + # Mission slots for presets should go before user mission slots + if "missions" in layouts[key] and "missions" in ordered_layouts[key]: + layouts[key]["missions"] = ordered_layouts[key]["missions"] + layouts[key]["missions"] + ordered_layouts[key].update(layouts[key]) + else: + ordered_layouts[key] = layouts[key] + + # Campaign values = default options (except for default layouts) + preset options (except for layouts) + campaign options + self.value[campaign] = {key: value for (key, value) in self.default["Default Campaign"].items() if type(value) != dict} + self.value[campaign].update(preset) + self.value[campaign].update(yaml_value[campaign]) + _resolve_special_options(self.value[campaign]) + + for layout in ordered_layouts: + # Layout values = default options + campaign's global options + layout options + self.value[campaign][layout] = copy.deepcopy(self.default["Default Campaign"][GLOBAL_ENTRY]) + self.value[campaign][layout].update(global_dict) + self.value[campaign][layout].update(ordered_layouts[layout]) + _resolve_special_options(self.value[campaign][layout]) + + for mission_slot_index in range(len(self.value[campaign][layout]["missions"])): + # Defaults for mission slots are handled by the mission slot struct + _resolve_special_options(self.value[campaign][layout]["missions"][mission_slot_index]) + + # Overloaded to remove pre-init schema validation + # Schema is still validated after __init__ + @classmethod + def from_any(cls, data: Dict[str, Any]) -> CustomMissionOrder: + if type(data) == dict: + return cls(data) + else: + raise NotImplementedError(f"Cannot Convert from non-dictionary, got {type(data)}") + + +def _resolve_special_options(data: Dict[str, Any]): + # Handle range values & string-to-value conversions + for option in data: + option_value = data[option] + new_value = _resolve_special_option(option, option_value) + data[option] = new_value + + # Special case for canvas layouts determining their own size + if "type" in data and data["type"] == Canvas.__name__: + canvas: List[str] = data["canvas"] + longest_line = max(len(line) for line in canvas) + data["size"] = len(canvas) * longest_line + data["width"] = longest_line + + +def _resolve_special_option(option: str, option_value: Any) -> Any: + # Option values can be string representations of values + if option in STR_OPTION_VALUES: + return _resolve_string_option(option, option_value) + + if option == "mission_pool": + return _resolve_mission_pool(option_value) + + if option == "entry_rules": + rules = [_resolve_entry_rule(subrule) for subrule in option_value] + return rules + + if option == "display_name": + # Make sure all the values are strings + if type(option_value) == list: + names = [str(value) for value in option_value] + return names + elif option_value == "null": + # "null" means no custom display name + return [] + else: + return [str(option_value)] + + if option in ["index", "next"]: + # All index values could be ranges + if type(option_value) == list: + # Flatten any nested lists + indices = [idx for val in [idx if type(idx) == list else [idx] for idx in option_value] for idx in val] + indices = [_resolve_potential_range(index) for index in indices] + indices = [idx if type(idx) == int else str(idx) for idx in indices] + return indices + else: + idx = _resolve_potential_range(option_value) + return [idx if type(idx) == int else str(idx)] + + # Option values can be ranges + return _resolve_potential_range(option_value) + + +def _resolve_string_option_single(option: str, option_value: str) -> Any: + formatted_value = option_value.lower().replace("_", " ") + if formatted_value not in STR_OPTION_VALUES[option]: + raise ValueError( + f"Option \"{option}\" received unknown value \"{option_value}\".\n" + f"Allowed values are: {list(STR_OPTION_VALUES[option].keys())}" + ) + return STR_OPTION_VALUES[option][formatted_value] + + +def _resolve_string_option(option: str, option_value: Union[List[str], str]) -> Any: + if type(option_value) == list: + return [_resolve_string_option_single(option, val) for val in option_value] + else: + return _resolve_string_option_single(option, option_value) + + +def _resolve_entry_rule(option_value: Dict[str, Any]) -> Dict[str, Any]: + resolved: Dict[str, Any] = {} + mutually_exclusive: List[str] = [] + if "amount" in option_value: + resolved["amount"] = _resolve_potential_range(option_value["amount"]) + if "scope" in option_value: + mutually_exclusive.append("scope") + # A scope may be a list or a single address + if type(option_value["scope"]) == list: + resolved["scope"] = [str(subscope) for subscope in option_value["scope"]] + else: + resolved["scope"] = [str(option_value["scope"])] + if "rules" in option_value: + mutually_exclusive.append("rules") + resolved["rules"] = [_resolve_entry_rule(subrule) for subrule in option_value["rules"]] + # Make sure sub-rule rules have a specified amount + if "amount" not in option_value: + resolved["amount"] = -1 + if "items" in option_value: + mutually_exclusive.append("items") + option_items: Dict[str, Any] = option_value["items"] + resolved_items = {item: int(_resolve_potential_range(str(amount))) for (item, amount) in option_items.items()} + resolved_items = _resolve_item_names(resolved_items) + resolved["items"] = {} + for item in resolved_items: + if item not in item_table: + if item.casefold() == GENERIC_KEY_NAME or item.casefold().startswith(GENERIC_PROGRESSIVE_KEY_NAME): + resolved["items"][item] = max(0, resolved_items[item]) + continue + raise ValueError(f"Item rule contains \"{item}\", which is not a valid item name.") + amount = max(0, resolved_items[item]) + quantity = item_table[item].quantity + if amount == 0: + final_amount = quantity + elif quantity == 0: + final_amount = amount + else: + final_amount = amount + resolved["items"][item] = final_amount + if len(mutually_exclusive) > 1: + raise ValueError( + "Entry rule contains too many identifiers.\n" + f"Rule: {option_value}\n" + f"Remove all but one of these entries: {mutually_exclusive}" + ) + return resolved + + +def _resolve_potential_range(option_value: Union[Any, str]) -> Union[Any, int]: + # An option value may be a range + if type(option_value) == str and option_value.startswith("random-range-"): + resolved = _custom_range(option_value) + return resolved + else: + # As this is a catch-all function, + # assume non-range option values are handled elsewhere + # or intended to fall through + return option_value + + +def _resolve_mission_pool(option_value: Union[str, List[str]]) -> Set[int]: + if type(option_value) == str: + pool = _get_target_missions(option_value) + else: + pool: Set[int] = set() + for line in option_value: + if line.startswith("~"): + if len(pool) == 0: + raise ValueError(f"Mission Pool term {line} tried to remove missions from an empty pool.") + term = line[1:].strip() + missions = _get_target_missions(term) + pool.difference_update(missions) + elif line.startswith("^"): + if len(pool) == 0: + raise ValueError(f"Mission Pool term {line} tried to remove missions from an empty pool.") + term = line[1:].strip() + missions = _get_target_missions(term) + pool.intersection_update(missions) + else: + if line.startswith("+"): + term = line[1:].strip() + else: + term = line.strip() + missions = _get_target_missions(term) + pool.update(missions) + if len(pool) == 0: + raise ValueError(f"Mission pool evaluated to zero missions: {option_value}") + return pool + + +def _get_target_missions(term: str) -> Set[int]: + if term in lookup_name_to_mission: + return {lookup_name_to_mission[term].id} + else: + groups = [mission_groups[group] for group in mission_groups if group.casefold() == term.casefold()] + if len(groups) > 0: + return {lookup_name_to_mission[mission].id for mission in groups[0]} + else: + raise ValueError(f"Mission pool term \"{term}\" did not resolve to any specific mission or mission group.") + + +# Class-agnostic version of AP Options.Range.custom_range +def _custom_range(text: str) -> int: + textsplit = text.split("-") + try: + random_range = [int(textsplit[len(textsplit) - 2]), int(textsplit[len(textsplit) - 1])] + except ValueError: + raise ValueError(f"Invalid random range {text} for option {CustomMissionOrder.__name__}") + random_range.sort() + if text.startswith("random-range-low"): + return _triangular(random_range[0], random_range[1], random_range[0]) + elif text.startswith("random-range-middle"): + return _triangular(random_range[0], random_range[1]) + elif text.startswith("random-range-high"): + return _triangular(random_range[0], random_range[1], random_range[1]) + else: + return random.randint(random_range[0], random_range[1]) + + +def _triangular(lower: int, end: int, tri: typing.Optional[int] = None) -> int: + return int(round(random.triangular(lower, end, tri), 0)) + + +# Version of options.Sc2ItemDict.verify without World +def _resolve_item_names(value: Dict[str, int]) -> Dict[str, int]: + new_value: dict[str, int] = {} + case_insensitive_group_mapping = { + group_name.casefold(): group_value for group_name, group_value in item_name_groups.items() + } + case_insensitive_group_mapping.update({item.casefold(): {item} for item in item_table}) + for group_name in value: + item_names = case_insensitive_group_mapping.get(group_name.casefold(), {group_name}) + for item_name in item_names: + new_value[item_name] = new_value.get(item_name, 0) + value[group_name] + return new_value + \ No newline at end of file diff --git a/worlds/sc2/mission_order/presets_scripted.py b/worlds/sc2/mission_order/presets_scripted.py new file mode 100644 index 000000000000..010c7785a6b2 --- /dev/null +++ b/worlds/sc2/mission_order/presets_scripted.py @@ -0,0 +1,164 @@ +from typing import Dict, Any, List +import copy + +def _required_option(option: str, options: Dict[str, Any]) -> Any: + """Returns the option value, or raises an error if the option is not present.""" + if option not in options: + raise KeyError(f"Campaign preset is missing required option \"{option}\".") + return options.pop(option) + +def _validate_option(option: str, options: Dict[str, str], default: str, valid_values: List[str]) -> str: + """Returns the option value if it is present and valid, the default if it is not present, or raises an error if it is present but not valid.""" + result = options.pop(option, default) + if result not in valid_values: + raise ValueError(f"Preset option \"{option}\" received unknown value \"{result}\".") + return result + +def make_golden_path(options: Dict[str, Any]) -> Dict[str, Any]: + chain_name_options = ['Mar Sara', 'Agria', 'Redstone', 'Meinhoff', 'Haven', 'Tarsonis', 'Valhalla', 'Char', + 'Umoja', 'Kaldir', 'Zerus', 'Skygeirr Station', 'Dominion Space', 'Korhal', + 'Aiur', 'Glacius', 'Shakuras', 'Ulnar', 'Slayn', + 'Antiga', 'Braxis', 'Chau Sara', 'Moria', 'Tyrador', 'Xil', 'Zhakul', + 'Azeroth', 'Crouton', 'Draenor', 'Sanctuary'] + + size = max(_required_option("size", options), 4) + keys_option_values = ["none", "layouts", "missions", "progressive_layouts", "progressive_missions", "progressive_per_layout"] + keys_option = _validate_option("keys", options, "none", keys_option_values) + min_chains = 2 + max_chains = 6 + two_start_positions = options.pop("two_start_positions", False) + # Compensating for empty mission at start + if two_start_positions: + size += 1 + + class Campaign: + def __init__(self, missions_remaining: int): + self.chain_lengths = [1] + self.chain_padding = [0] + self.required_missions = [0] + self.padding = 0 + self.missions_remaining = missions_remaining + self.mission_counter = 1 + + def add_mission(self, chain: int, required_missions: int = 0, *, is_final: bool = False): + if self.missions_remaining == 0 and not is_final: + return + + self.mission_counter += 1 + self.chain_lengths[chain] += 1 + self.missions_remaining -= 1 + + if chain == 0: + self.padding += 1 + self.required_missions.append(required_missions) + + def add_chain(self): + self.chain_lengths.append(0) + self.chain_padding.append(self.padding) + + campaign = Campaign(size - 2) + current_required_missions = 0 + main_chain_length = 0 + while campaign.missions_remaining > 0: + main_chain_length += 1 + if main_chain_length % 2 == 1: # Adding branches + chains_to_make = 0 if len(campaign.chain_lengths) >= max_chains else min_chains if main_chain_length == 1 else 1 + for _ in range(chains_to_make): + campaign.add_chain() + # Updating branches + for side_chain in range(len(campaign.chain_lengths) - 1, 0, -1): + campaign.add_mission(side_chain) + # Adding main path mission + current_required_missions = (campaign.mission_counter * 3) // 4 + if two_start_positions: + # Compensating for skipped mission at start + current_required_missions -= 1 + campaign.add_mission(0, current_required_missions) + campaign.add_mission(0, current_required_missions, is_final = True) + + # Create mission order preset out of campaign + layout_base = { + "type": "column", + "display_name": chain_name_options, + "unique_name": True, + "missions": [], + } + # Optionally add key requirement to layouts + if keys_option == "layouts": + layout_base["entry_rules"] = [{ "items": { "Key": 1 }}] + elif keys_option == "progressive_layouts": + layout_base["entry_rules"] = [{ "items": { "Progressive Key": 0 }}] + preset = { + str(chain): copy.deepcopy(layout_base) for chain in range(len(campaign.chain_lengths)) + } + preset["0"]["exit"] = True + if not two_start_positions: + preset["0"].pop("entry_rules", []) + for chain in range(len(campaign.chain_lengths)): + length = campaign.chain_lengths[chain] + padding = campaign.chain_padding[chain] + preset[str(chain)]["size"] = padding + length + # Add padding to chain + if padding > 0: + preset[str(chain)]["missions"].append({ + "index": [pad for pad in range(padding)], + "empty": True + }) + + if chain == 0: + if two_start_positions: + preset["0"]["missions"].append({ + "index": 0, + "empty": True + }) + # Main path gets number requirements + for mission in range(1, len(campaign.required_missions)): + preset["0"]["missions"].append({ + "index": mission, + "entry_rules": [{ + "scope": "../..", + "amount": campaign.required_missions[mission] + }] + }) + # Optionally add key requirements except to the starter mission + if keys_option == "missions": + for slot in preset["0"]["missions"]: + if "entry_rules" in slot: + slot["entry_rules"].append({ "items": { "Key": 1 }}) + elif keys_option == "progressive_missions": + for slot in preset["0"]["missions"]: + if "entry_rules" in slot: + slot["entry_rules"].append({ "items": { "Progressive Key": 1 }}) + # No main chain keys for progressive_per_layout keys + else: + # Other paths get main path requirements + if two_start_positions and chain < 3: + preset[str(chain)].pop("entry_rules", []) + for mission in range(length): + target = padding + mission + if two_start_positions and mission == 0 and chain < 3: + preset[str(chain)]["missions"].append({ + "index": target, + "entrance": True + }) + else: + preset[str(chain)]["missions"].append({ + "index": target, + "entry_rules": [{ + "scope": f"../../0/{target}" + }] + }) + # Optionally add key requirements + if keys_option == "missions": + for slot in preset[str(chain)]["missions"]: + if "entry_rules" in slot: + slot["entry_rules"].append({ "items": { "Key": 1 }}) + elif keys_option == "progressive_missions": + for slot in preset[str(chain)]["missions"]: + if "entry_rules" in slot: + slot["entry_rules"].append({ "items": { "Progressive Key": 1 }}) + elif keys_option == "progressive_per_layout": + for slot in preset[str(chain)]["missions"]: + if "entry_rules" in slot: + slot["entry_rules"].append({ "items": { "Progressive Key": 0 }}) + return preset diff --git a/worlds/sc2/mission_order/presets_static.py b/worlds/sc2/mission_order/presets_static.py new file mode 100644 index 000000000000..b52e5f135975 --- /dev/null +++ b/worlds/sc2/mission_order/presets_static.py @@ -0,0 +1,916 @@ +from typing import Dict, Any, Callable, List, Tuple +import copy + +from ..mission_groups import MissionGroupNames +from ..mission_tables import SC2Mission, SC2Campaign + +preset_mini_wol_with_prophecy = { + "global": { + "type": "column", + "mission_pool": [ + MissionGroupNames.WOL_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ] + }, + "Mar Sara": { + "size": 1 + }, + "Colonist": { + "size": 2, + "entry_rules": [ + { "scope": "../Mar Sara" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Artifact": { + "size": 3, + "entry_rules": [ + { "scope": "../Mar Sara" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 1, "entry_rules": [{ "scope": "../..", "amount": 4 }, { "items": { "Key": 1 }}] }, + { "index": 2, "entry_rules": [{ "scope": "../..", "amount": 8 }, { "items": { "Key": 1 }}] } + ] + }, + "Prophecy": { + "size": 2, + "entry_rules": [ + { "scope": "../Artifact/1" }, + { "items": { "Key": 1 }} + ], + "mission_pool": [ + MissionGroupNames.PROPHECY_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Covert": { + "size": 2, + "entry_rules": [ + { "scope": "../Mar Sara" }, + { "scope": "..", "amount": 2 }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Rebellion": { + "size": 2, + "entry_rules": [ + { "scope": "../Mar Sara" }, + { "scope": "..", "amount": 3 }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Char": { + "size": 3, + "entry_rules": [ + { "scope": "../Artifact" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "next": [2] }, + { "index": 1, "entrance": True } + ] + } +} + +preset_mini_wol = copy.deepcopy(preset_mini_wol_with_prophecy) +preset_mini_prophecy = { "Prophecy": preset_mini_wol.pop("Prophecy") } +preset_mini_prophecy["Prophecy"].pop("entry_rules") +preset_mini_prophecy["Prophecy"]["type"] = "gauntlet" +preset_mini_prophecy["Prophecy"]["display_name"] = "" +preset_mini_prophecy["Prophecy"]["missions"].append({ "index": "entrances", "entry_rules": [] }) + +preset_mini_hots = { + "global": { + "type": "column", + "mission_pool": [ + MissionGroupNames.HOTS_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ] + }, + "Umoja": { + "size": 1, + }, + "Kaldir": { + "size": 2, + "entry_rules": [ + { "scope": "../Umoja" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Char": { + "size": 2, + "entry_rules": [ + { "scope": "../Umoja" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Zerus": { + "size": 2, + "entry_rules": [ + { "scope": "../Umoja" }, + { "scope": "..", "amount": 3 }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Skygeirr Station": { + "size": 2, + "entry_rules": [ + { "scope": "../Zerus" }, + { "scope": "..", "amount": 5 }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Dominion Space": { + "size": 2, + "entry_rules": [ + { "scope": "../Zerus" }, + { "scope": "..", "amount": 5 }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Korhal": { + "size": 2, + "entry_rules": [ + { "scope": "../Zerus" }, + { "scope": "..", "amount": 8 }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + } +} + +preset_mini_lotv_prologue = { + "min_difficulty": "easy", + "Prologue": { + "display_name": "", + "type": "gauntlet", + "size": 2, + "mission_pool": [ + MissionGroupNames.PROLOGUE_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ], + "missions": [ + { "index": 1, "entry_rules": [{ "items": { "Key": 1 }}] } + ] + } +} + +preset_mini_lotv = { + "global": { + "type": "column", + "mission_pool": [ + MissionGroupNames.LOTV_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ] + }, + "Aiur": { + "size": 2, + "missions": [ + { "index": 1, "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Korhal": { + "size": 1, + "entry_rules": [ + { "scope": "../Aiur" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Shakuras": { + "size": 1, + "entry_rules": [ + { "scope": "../Aiur" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Purifier": { + "size": 2, + "entry_rules": [ + { "scope": "../Korhal" }, + { "scope": "../Shakuras" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 1, "entry_rules": [{ "scope": "../../Ulnar" }, { "items": { "Key": 1 }}] } + ] + }, + "Ulnar": { + "size": 1, + "entry_rules": [ + { "scope": "../Purifier/0" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Tal'darim": { + "size": 1, + "entry_rules": [ + { "scope": "../Ulnar" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Return to Aiur": { + "size": 2, + "entry_rules": [ + { "scope": "../Purifier" }, + { "scope": "../Tal'darim" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + } +} + +preset_mini_lotv_epilogue = { + "min_difficulty": "very hard", + "Epilogue": { + "display_name": "", + "type": "gauntlet", + "size": 2, + "mission_pool": [ + MissionGroupNames.EPILOGUE_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ], + "missions": [ + { "index": 1, "entry_rules": [{ "items": { "Key": 1 }}] } + ] + } +} + +preset_mini_nco = { + "min_difficulty": "easy", + "global": { + "type": "column", + "mission_pool": [ + MissionGroupNames.NCO_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ] + }, + "Mission Pack 1": { + "size": 2, + "missions": [ + { "index": 1, "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Mission Pack 2": { + "size": 1, + "entry_rules": [ + { "scope": "../Mission Pack 1" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Mission Pack 3": { + "size": 2, + "entry_rules": [ + { "scope": "../Mission Pack 2" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, +} + +preset_wol_with_prophecy = { + "global": { + "type": "column", + "mission_pool": [ + MissionGroupNames.WOL_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ] + }, + "Mar Sara": { + "size": 3, + "missions": [ + { "index": 0, "mission_pool": SC2Mission.LIBERATION_DAY.mission_name }, + { "index": 1, "mission_pool": SC2Mission.THE_OUTLAWS.mission_name }, + { "index": 2, "mission_pool": SC2Mission.ZERO_HOUR.mission_name }, + { "index": [1, 2], "entry_rules": [{ "items": { "Key": 1 }}] } + ] + }, + "Colonist": { + "size": 4, + "entry_rules": [ + { "scope": "../Mar Sara" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": 1, "next": [2, 3] }, + { "index": 2, "next": [] }, + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": [2, 3], "entry_rules": [{ "scope": "../..", "amount": 7 }, { "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.EVACUATION.mission_name }, + { "index": 1, "mission_pool": SC2Mission.OUTBREAK.mission_name }, + { "index": 2, "mission_pool": SC2Mission.SAFE_HAVEN.mission_name }, + { "index": 3, "mission_pool": SC2Mission.HAVENS_FALL.mission_name }, + ] + }, + "Artifact": { + "size": 5, + "entry_rules": [ + { "scope": "../Mar Sara" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 1, "entry_rules": [{ "scope": "../..", "amount": 8 }, { "items": { "Key": 1 }}] }, + { "index": 2, "entry_rules": [{ "scope": "../..", "amount": 11 }, { "items": { "Key": 1 }}] }, + { "index": 3, "entry_rules": [{ "scope": "../..", "amount": 14 }, { "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.SMASH_AND_GRAB.mission_name }, + { "index": 1, "mission_pool": SC2Mission.THE_DIG.mission_name }, + { "index": 2, "mission_pool": SC2Mission.THE_MOEBIUS_FACTOR.mission_name }, + { "index": 3, "mission_pool": SC2Mission.SUPERNOVA.mission_name }, + { "index": 4, "mission_pool": SC2Mission.MAW_OF_THE_VOID.mission_name }, + ] + }, + "Prophecy": { + "size": 4, + "entry_rules": [ + { "scope": "../Artifact/1" }, + { "items": { "Key": 1 }} + ], + "mission_pool": [ + MissionGroupNames.PROPHECY_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.WHISPERS_OF_DOOM.mission_name }, + { "index": 1, "mission_pool": SC2Mission.A_SINISTER_TURN.mission_name }, + { "index": 2, "mission_pool": SC2Mission.ECHOES_OF_THE_FUTURE.mission_name }, + { "index": 3, "mission_pool": SC2Mission.IN_UTTER_DARKNESS.mission_name }, + ] + }, + "Covert": { + "size": 4, + "entry_rules": [ + { "scope": "../Mar Sara" }, + { "scope": "..", "amount": 4 }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": 1, "next": [2, 3] }, + { "index": 2, "next": [] }, + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": [2, 3], "entry_rules": [{ "scope": "../..", "amount": 8 }, { "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.DEVILS_PLAYGROUND.mission_name }, + { "index": 1, "mission_pool": SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name }, + { "index": 2, "mission_pool": SC2Mission.BREAKOUT.mission_name }, + { "index": 3, "mission_pool": SC2Mission.GHOST_OF_A_CHANCE.mission_name }, + ] + }, + "Rebellion": { + "size": 5, + "entry_rules": [ + { "scope": "../Mar Sara" }, + { "scope": "..", "amount": 6 }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.THE_GREAT_TRAIN_ROBBERY.mission_name }, + { "index": 1, "mission_pool": SC2Mission.CUTTHROAT.mission_name }, + { "index": 2, "mission_pool": SC2Mission.ENGINE_OF_DESTRUCTION.mission_name }, + { "index": 3, "mission_pool": SC2Mission.MEDIA_BLITZ.mission_name }, + { "index": 4, "mission_pool": SC2Mission.PIERCING_OF_THE_SHROUD.mission_name }, + ] + }, + "Char": { + "size": 4, + "entry_rules": [ + { "scope": "../Artifact" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": 0, "next": [1, 2] }, + { "index": [1, 2], "next": [3] }, + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.GATES_OF_HELL.mission_name }, + { "index": 1, "mission_pool": SC2Mission.BELLY_OF_THE_BEAST.mission_name }, + { "index": 2, "mission_pool": SC2Mission.SHATTER_THE_SKY.mission_name }, + { "index": 3, "mission_pool": SC2Mission.ALL_IN.mission_name }, + ] + } +} + +preset_wol = copy.deepcopy(preset_wol_with_prophecy) +preset_prophecy = { "Prophecy": preset_wol.pop("Prophecy") } +preset_prophecy["Prophecy"].pop("entry_rules") +preset_prophecy["Prophecy"]["type"] = "gauntlet" +preset_prophecy["Prophecy"]["display_name"] = "" +preset_prophecy["Prophecy"]["missions"].append({ "index": "entrances", "entry_rules": [] }) + +preset_hots = { + "global": { + "type": "column", + "mission_pool": [ + MissionGroupNames.HOTS_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ] + }, + "Umoja": { + "size": 3, + "missions": [ + { "index": [1, 2], "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.LAB_RAT.mission_name }, + { "index": 1, "mission_pool": SC2Mission.BACK_IN_THE_SADDLE.mission_name }, + { "index": 2, "mission_pool": SC2Mission.RENDEZVOUS.mission_name }, + ] + }, + "Kaldir": { + "size": 3, + "entry_rules": [ + { "scope": "../Umoja" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.HARVEST_OF_SCREAMS.mission_name }, + { "index": 1, "mission_pool": SC2Mission.SHOOT_THE_MESSENGER.mission_name }, + { "index": 2, "mission_pool": SC2Mission.ENEMY_WITHIN.mission_name }, + ] + }, + "Char": { + "size": 3, + "entry_rules": [ + { "scope": "../Umoja" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.DOMINATION.mission_name }, + { "index": 1, "mission_pool": SC2Mission.FIRE_IN_THE_SKY.mission_name }, + { "index": 2, "mission_pool": SC2Mission.OLD_SOLDIERS.mission_name }, + ] + }, + "Zerus": { + "size": 3, + "entry_rules": [ + { + "rules": [ + { "scope": "../Kaldir" }, + { "scope": "../Char" } + ], + "amount": 1 + }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.WAKING_THE_ANCIENT.mission_name }, + { "index": 1, "mission_pool": SC2Mission.THE_CRUCIBLE.mission_name }, + { "index": 2, "mission_pool": SC2Mission.SUPREME.mission_name }, + ] + }, + "Skygeirr Station": { + "size": 3, + "entry_rules": [ + { "scope": ["../Kaldir", "../Char", "../Zerus"] }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.INFESTED.mission_name }, + { "index": 1, "mission_pool": SC2Mission.HAND_OF_DARKNESS.mission_name }, + { "index": 2, "mission_pool": SC2Mission.PHANTOMS_OF_THE_VOID.mission_name }, + ] + }, + "Dominion Space": { + "size": 2, + "entry_rules": [ + { "scope": ["../Kaldir", "../Char", "../Zerus"] }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.WITH_FRIENDS_LIKE_THESE.mission_name }, + { "index": 1, "mission_pool": SC2Mission.CONVICTION.mission_name }, + ] + }, + "Korhal": { + "size": 3, + "entry_rules": [ + { "scope": ["../Skygeirr Station", "../Dominion Space"] }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.PLANETFALL.mission_name }, + { "index": 1, "mission_pool": SC2Mission.DEATH_FROM_ABOVE.mission_name }, + { "index": 2, "mission_pool": SC2Mission.THE_RECKONING.mission_name }, + ] + } +} + +preset_lotv_prologue = { + "min_difficulty": "easy", + "Prologue": { + "display_name": "", + "type": "gauntlet", + "size": 3, + "mission_pool": [ + MissionGroupNames.PROLOGUE_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ], + "missions": [ + { "index": [1, 2], "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.DARK_WHISPERS.mission_name }, + { "index": 1, "mission_pool": SC2Mission.GHOSTS_IN_THE_FOG.mission_name }, + { "index": 2, "mission_pool": SC2Mission.EVIL_AWOKEN.mission_name }, + ] + } +} + +preset_lotv = { + "global": { + "type": "column", + "mission_pool": [ + MissionGroupNames.LOTV_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ] + }, + "Aiur": { + "size": 3, + "missions": [ + { "index": [1, 2], "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.FOR_AIUR.mission_name }, + { "index": 1, "mission_pool": SC2Mission.THE_GROWING_SHADOW.mission_name }, + { "index": 2, "mission_pool": SC2Mission.THE_SPEAR_OF_ADUN.mission_name }, + ] + }, + "Korhal": { + "size": 2, + "entry_rules": [ + { "scope": "../Aiur" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.SKY_SHIELD.mission_name }, + { "index": 1, "mission_pool": SC2Mission.BROTHERS_IN_ARMS.mission_name }, + ] + }, + "Shakuras": { + "size": 2, + "entry_rules": [ + { "scope": "../Aiur" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.AMON_S_REACH.mission_name }, + { "index": 1, "mission_pool": SC2Mission.LAST_STAND.mission_name }, + ] + }, + "Purifier": { + "size": 3, + "entry_rules": [ + { + "rules": [ + { "scope": "../Korhal" }, + { "scope": "../Shakuras" } + ], + "amount": 1 + }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 1, "entry_rules": [{ "scope": "../../Ulnar" }, { "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.FORBIDDEN_WEAPON.mission_name }, + { "index": 1, "mission_pool": SC2Mission.UNSEALING_THE_PAST.mission_name }, + { "index": 2, "mission_pool": SC2Mission.PURIFICATION.mission_name }, + ] + }, + "Ulnar": { + "size": 3, + "entry_rules": [ + { + "scope": [ + "../Korhal", + "../Shakuras", + "../Purifier/0" + ] + }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.TEMPLE_OF_UNIFICATION.mission_name }, + { "index": 1, "mission_pool": SC2Mission.THE_INFINITE_CYCLE.mission_name }, + { "index": 2, "mission_pool": SC2Mission.HARBINGER_OF_OBLIVION.mission_name }, + ] + }, + "Tal'darim": { + "size": 2, + "entry_rules": [ + { "scope": "../Ulnar" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.STEPS_OF_THE_RITE.mission_name }, + { "index": 1, "mission_pool": SC2Mission.RAK_SHIR.mission_name }, + ] + }, + "Moebius": { + "size": 1, + "entry_rules": [ + { + "rules": [ + { "scope": "../Purifier" }, + { "scope": "../Tal'darim" } + ], + "amount": 1 + }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.TEMPLAR_S_CHARGE.mission_name }, + ] + }, + "Return to Aiur": { + "size": 3, + "entry_rules": [ + { "scope": "../Purifier" }, + { "scope": "../Tal'darim" }, + { "scope": "../Moebius" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.TEMPLAR_S_RETURN.mission_name }, + { "index": 1, "mission_pool": SC2Mission.THE_HOST.mission_name }, + { "index": 2, "mission_pool": SC2Mission.SALVATION.mission_name }, + ] + } +} + +preset_lotv_epilogue = { + "min_difficulty": "very hard", + "Epilogue": { + "display_name": "", + "type": "gauntlet", + "size": 3, + "mission_pool": [ + MissionGroupNames.EPILOGUE_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ], + "missions": [ + { "index": [1, 2], "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.INTO_THE_VOID.mission_name }, + { "index": 1, "mission_pool": SC2Mission.THE_ESSENCE_OF_ETERNITY.mission_name }, + { "index": 2, "mission_pool": SC2Mission.AMON_S_FALL.mission_name }, + ] + } +} + +preset_nco = { + "min_difficulty": "easy", + "global": { + "type": "column", + "mission_pool": [ + MissionGroupNames.NCO_MISSIONS, + "~ " + MissionGroupNames.RACESWAP_MISSIONS + ] + }, + "Mission Pack 1": { + "size": 3, + "missions": [ + { "index": [1, 2], "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.THE_ESCAPE.mission_name }, + { "index": 1, "mission_pool": SC2Mission.SUDDEN_STRIKE.mission_name }, + { "index": 2, "mission_pool": SC2Mission.ENEMY_INTELLIGENCE.mission_name }, + ] + }, + "Mission Pack 2": { + "size": 3, + "entry_rules": [ + { "scope": "../Mission Pack 1" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.TROUBLE_IN_PARADISE.mission_name }, + { "index": 1, "mission_pool": SC2Mission.NIGHT_TERRORS.mission_name }, + { "index": 2, "mission_pool": SC2Mission.FLASHPOINT.mission_name }, + ] + }, + "Mission Pack 3": { + "size": 3, + "entry_rules": [ + { "scope": "../Mission Pack 2" }, + { "items": { "Key": 1 }} + ], + "missions": [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": 0, "mission_pool": SC2Mission.IN_THE_ENEMY_S_SHADOW.mission_name }, + { "index": 1, "mission_pool": SC2Mission.DARK_SKIES.mission_name }, + { "index": 2, "mission_pool": SC2Mission.END_GAME.mission_name }, + ] + }, +} + +def _build_static_preset(preset: Dict[str, Any], options: Dict[str, Any]) -> Dict[str, Any]: + # Raceswap shuffling + raceswaps = options.pop("shuffle_raceswaps", False) + if not isinstance(raceswaps, bool): + raise ValueError( + f"Preset option \"shuffle_raceswaps\" received unknown value \"{raceswaps}\".\n" + "Valid values are: true, false" + ) + elif raceswaps == True: + # Remove "~ Raceswap Missions" operation from mission pool options + # Also add raceswap variants to plando'd vanilla missions + for layout in preset.values(): + if type(layout) == dict: + # Currently mission pools in layouts are always ["X campaign missions", "~ raceswap missions"] + layout_mission_pool: List[str] = layout.get("mission_pool", None) + if layout_mission_pool is not None: + layout_mission_pool.pop() + layout["mission_pool"] = layout_mission_pool + if "missions" in layout: + for slot in layout["missions"]: + # Currently mission pools in slots are always strings + slot_mission_pool: str = slot.get("mission_pool", None) + # Identify raceswappable missions by their race in brackets + if slot_mission_pool is not None and slot_mission_pool[-1] == ")": + mission_name = slot_mission_pool[:slot_mission_pool.rfind("(")] + new_mission_pool = [f"{mission_name}({race})" for race in ["Terran", "Zerg", "Protoss"]] + slot["mission_pool"] = new_mission_pool + # The presets are set up for no raceswaps, so raceswaps == False doesn't need to be covered + + # Mission pool selection + missions = options.pop("missions", "random") + if missions == "vanilla": + pass # use preset as it is + elif missions == "vanilla_shuffled": + # remove pre-set missions + for layout in preset.values(): + if type(layout) == dict and "missions" in layout: + for slot in layout["missions"]: + slot.pop("mission_pool", ()) + elif missions == "random": + # remove pre-set missions and mission pools + for layout in preset.values(): + if type(layout) == dict: + layout.pop("mission_pool", ()) + if "missions" in layout: + for slot in layout["missions"]: + slot.pop("mission_pool", ()) + else: + raise ValueError( + f"Preset option \"missions\" received unknown value \"{missions}\".\n" + "Valid values are: random, vanilla, vanilla_shuffled" + ) + + # Key rule selection + keys = options.pop("keys", "none") + if keys == "layouts": + # remove keys from mission entry rules + for layout in preset.values(): + if type(layout) == dict and "missions" in layout: + for slot in layout["missions"]: + if "entry_rules" in slot: + slot["entry_rules"] = _remove_key_rules(slot["entry_rules"]) + elif keys == "missions": + # remove keys from layout entry rules + for layout in preset.values(): + if type(layout) == dict and "entry_rules" in layout: + layout["entry_rules"] = _remove_key_rules(layout["entry_rules"]) + elif keys == "progressive_layouts": + # remove keys from mission entry rules, replace keys in layout entry rules with unique-track keys + for layout in preset.values(): + if type(layout) == dict: + if "entry_rules" in layout: + layout["entry_rules"] = _make_key_rules_progressive(layout["entry_rules"], 0) + if "missions" in layout: + for slot in layout["missions"]: + if "entry_rules" in slot: + slot["entry_rules"] = _remove_key_rules(slot["entry_rules"]) + elif keys == "progressive_missions": + # remove keys from layout entry rules, replace keys in mission entry rules + for layout in preset.values(): + if type(layout) == dict: + if "entry_rules" in layout: + layout["entry_rules"] = _remove_key_rules(layout["entry_rules"]) + if "missions" in layout: + for slot in layout["missions"]: + if "entry_rules" in slot: + slot["entry_rules"] = _make_key_rules_progressive(slot["entry_rules"], 1) + elif keys == "progressive_per_layout": + # remove keys from layout entry rules, replace keys in mission entry rules with unique-track keys + # specifically ignore layouts that have no entry rules (and are thus the first of their campaign) + for layout in preset.values(): + if type(layout) == dict and "entry_rules" in layout: + layout["entry_rules"] = _remove_key_rules(layout["entry_rules"]) + if "missions" in layout: + for slot in layout["missions"]: + if "entry_rules" in slot: + slot["entry_rules"] = _make_key_rules_progressive(slot["entry_rules"], 0) + elif keys == "none": + # remove keys from both layout and mission entry rules + for layout in preset.values(): + if type(layout) == dict: + if "entry_rules" in layout: + layout["entry_rules"] = _remove_key_rules(layout["entry_rules"]) + if "missions" in layout: + for slot in layout["missions"]: + if "entry_rules" in slot: + slot["entry_rules"] = _remove_key_rules(slot["entry_rules"]) + else: + raise ValueError( + f"Preset option \"keys\" received unknown value \"{keys}\".\n" + "Valid values are: none, missions, layouts, progressive_missions, progressive_layouts, progressive_per_layout" + ) + + return preset + +def _remove_key_rules(entry_rules: List[Dict[str, Any]]) -> List[Dict[str, Any]]: + return [rule for rule in entry_rules if not ("items" in rule and "Key" in rule["items"])] + +def _make_key_rules_progressive(entry_rules: List[Dict[str, Any]], track: int) -> List[Dict[str, Any]]: + for rule in entry_rules: + if "items" in rule and "Key" in rule["items"]: + new_items: Dict[str, Any] = {} + for (item, amount) in rule["items"].items(): + if item == "Key": + new_items["Progressive Key"] = track + else: + new_items[item] = amount + rule["items"] = new_items + return entry_rules + +def static_preset(preset: Dict[str, Any]) -> Callable[[Dict[str, Any]], Dict[str, Any]]: + return lambda options: _build_static_preset(copy.deepcopy(preset), options) + +def get_used_layout_names() -> Dict[SC2Campaign, Tuple[int, List[str]]]: + campaign_to_preset: Dict[SC2Campaign, Dict[str, Any]] = { + SC2Campaign.WOL: preset_wol_with_prophecy, + SC2Campaign.PROPHECY: preset_prophecy, + SC2Campaign.HOTS: preset_hots, + SC2Campaign.PROLOGUE: preset_lotv_prologue, + SC2Campaign.LOTV: preset_lotv, + SC2Campaign.EPILOGUE: preset_lotv_epilogue, + SC2Campaign.NCO: preset_nco + } + campaign_to_layout_names: Dict[SC2Campaign, Tuple[int, List[str]]] = { SC2Campaign.GLOBAL: (0, []) } + for campaign in SC2Campaign: + if campaign == SC2Campaign.GLOBAL: + continue + previous_campaign = [prev for prev in SC2Campaign if prev.id == campaign.id - 1][0] + previous_size = campaign_to_layout_names[previous_campaign][0] + preset = campaign_to_preset[campaign] + new_layouts = [value for value in preset.keys() if isinstance(preset[value], dict) and value != "global"] + campaign_to_layout_names[campaign] = (previous_size + len(campaign_to_layout_names[previous_campaign][1]), new_layouts) + campaign_to_layout_names.pop(SC2Campaign.GLOBAL) + return campaign_to_layout_names diff --git a/worlds/sc2/mission_order/slot_data.py b/worlds/sc2/mission_order/slot_data.py new file mode 100644 index 000000000000..44d4f405673c --- /dev/null +++ b/worlds/sc2/mission_order/slot_data.py @@ -0,0 +1,53 @@ +""" +Houses the data structures representing a mission order in slot data. +Creating these is handled by the nodes they represent in .nodes.py. +""" + +from __future__ import annotations +from typing import List, Protocol +from dataclasses import dataclass + +from .entry_rules import SubRuleRuleData + +class MissionOrderObjectSlotData(Protocol): + entry_rule: SubRuleRuleData + + +@dataclass +class CampaignSlotData: + name: str + entry_rule: SubRuleRuleData + exits: List[int] + layouts: List[LayoutSlotData] + + @staticmethod + def legacy(name: str, layouts: List[LayoutSlotData]) -> CampaignSlotData: + return CampaignSlotData(name, SubRuleRuleData.empty(), [], layouts) + + +@dataclass +class LayoutSlotData: + name: str + entry_rule: SubRuleRuleData + exits: List[int] + missions: List[List[MissionSlotData]] + + @staticmethod + def legacy(name: str, missions: List[List[MissionSlotData]]) -> LayoutSlotData: + return LayoutSlotData(name, SubRuleRuleData.empty(), [], missions) + + +@dataclass +class MissionSlotData: + mission_id: int + prev_mission_ids: List[int] + entry_rule: SubRuleRuleData + victory_cache_size: int = 0 + + @staticmethod + def empty() -> MissionSlotData: + return MissionSlotData(-1, [], SubRuleRuleData.empty()) + + @staticmethod + def legacy(mission_id: int, prev_mission_ids: List[int], entry_rule: SubRuleRuleData) -> MissionSlotData: + return MissionSlotData(mission_id, prev_mission_ids, entry_rule) diff --git a/worlds/sc2/mission_tables.py b/worlds/sc2/mission_tables.py new file mode 100644 index 000000000000..3dfe50ff2b1a --- /dev/null +++ b/worlds/sc2/mission_tables.py @@ -0,0 +1,577 @@ +from typing import NamedTuple, Dict, List, Set, Union, Literal, Iterable, Optional +from enum import IntEnum, Enum, IntFlag, auto + + +class SC2Race(IntEnum): + ANY = 0 + TERRAN = 1 + ZERG = 2 + PROTOSS = 3 + + def get_title(self): + return self.name.lower().capitalize() + + def get_mission_flag(self): + return MissionFlag.__getitem__(self.get_title()) + +class MissionPools(IntEnum): + STARTER = 0 + EASY = 1 + MEDIUM = 2 + HARD = 3 + VERY_HARD = 4 + FINAL = 5 + + +class MissionFlag(IntFlag): + none = 0 + Terran = auto() + Zerg = auto() + Protoss = auto() + NoBuild = auto() + Defense = auto() + AutoScroller = auto() # The mission is won by waiting out a timer or victory is gated behind a timer + Countdown = auto() # Overall, the mission must be beaten before a loss timer counts down + Kerrigan = auto() # The player controls Kerrigan in the mission + VanillaSoa = auto() # The player controls the Spear of Adun in the vanilla version of the mission + Nova = auto() # The player controls NCO Nova in the mission + AiTerranAlly = auto() # The mission has a Terran AI ally that can be taken over + AiZergAlly = auto() # The mission has a Zerg AI ally that can be taken over + AiProtossAlly = auto() # The mission has a Protoss AI ally that can be taken over + VsTerran = auto() + VsZerg = auto() + VsProtoss = auto() + HasRaceSwap = auto() # The mission has variants that use different factions from the vanilla experience. + RaceSwap = auto() # The mission uses different factions from the vanilla experience. + WoLNova = auto() # The player controls WoL Nova in the mission + + AiAlly = AiTerranAlly|AiZergAlly|AiProtossAlly + TimedDefense = AutoScroller|Defense + VsTZ = VsTerran|VsZerg + VsTP = VsTerran|VsProtoss + VsPZ = VsProtoss|VsZerg + VsAll = VsTerran|VsProtoss|VsZerg + + +class SC2CampaignGoalPriority(IntEnum): + """ + Campaign's priority to goal election + """ + NONE = 0 + MINI_CAMPAIGN = 1 # A goal shouldn't be in a mini-campaign if there's at least one 'big' campaign + HARD = 2 # A campaign ending with a hard mission + VERY_HARD = 3 # A campaign ending with a very hard mission + EPILOGUE = 4 # Epilogue shall be always preferred as the goal if present + + +class SC2Campaign(Enum): + + def __new__(cls, *args, **kwargs): + value = len(cls.__members__) + 1 + obj = object.__new__(cls) + obj._value_ = value + return obj + + def __init__(self, campaign_id: int, name: str, goal_priority: SC2CampaignGoalPriority, race: SC2Race): + self.id = campaign_id + self.campaign_name = name + self.goal_priority = goal_priority + self.race = race + + def __lt__(self, other: "SC2Campaign"): + return self.id < other.id + + GLOBAL = 0, "Global", SC2CampaignGoalPriority.NONE, SC2Race.ANY + WOL = 1, "Wings of Liberty", SC2CampaignGoalPriority.VERY_HARD, SC2Race.TERRAN + PROPHECY = 2, "Prophecy", SC2CampaignGoalPriority.MINI_CAMPAIGN, SC2Race.PROTOSS + HOTS = 3, "Heart of the Swarm", SC2CampaignGoalPriority.VERY_HARD, SC2Race.ZERG + PROLOGUE = 4, "Whispers of Oblivion (Legacy of the Void: Prologue)", SC2CampaignGoalPriority.MINI_CAMPAIGN, SC2Race.PROTOSS + LOTV = 5, "Legacy of the Void", SC2CampaignGoalPriority.VERY_HARD, SC2Race.PROTOSS + EPILOGUE = 6, "Into the Void (Legacy of the Void: Epilogue)", SC2CampaignGoalPriority.EPILOGUE, SC2Race.ANY + NCO = 7, "Nova Covert Ops", SC2CampaignGoalPriority.HARD, SC2Race.TERRAN + + +class SC2Mission(Enum): + + def __new__(cls, *args, **kwargs): + value = len(cls.__members__) + 1 + obj = object.__new__(cls) + obj._value_ = value + return obj + + def __init__(self, mission_id: int, name: str, campaign: SC2Campaign, area: str, race: SC2Race, pool: MissionPools, map_file: str, flags: MissionFlag): + self.id = mission_id + self.mission_name = name + self.campaign = campaign + self.area = area + self.race = race + self.pool = pool + self.map_file = map_file + self.flags = flags + + def get_short_name(self): + if self.mission_name.find(' (') == -1: + return self.mission_name + else: + return self.mission_name[:self.mission_name.find(' (')] + + # Wings of Liberty + LIBERATION_DAY = 1, "Liberation Day", SC2Campaign.WOL, "Mar Sara", SC2Race.ANY, MissionPools.STARTER, "ap_liberation_day", MissionFlag.Terran|MissionFlag.NoBuild|MissionFlag.VsTerran + THE_OUTLAWS = 2, "The Outlaws (Terran)", SC2Campaign.WOL, "Mar Sara", SC2Race.TERRAN, MissionPools.EASY, "ap_the_outlaws", MissionFlag.Terran|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + ZERO_HOUR = 3, "Zero Hour (Terran)", SC2Campaign.WOL, "Mar Sara", SC2Race.TERRAN, MissionPools.EASY, "ap_zero_hour", MissionFlag.Terran|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + EVACUATION = 4, "Evacuation (Terran)", SC2Campaign.WOL, "Colonist", SC2Race.TERRAN, MissionPools.EASY, "ap_evacuation", MissionFlag.Terran|MissionFlag.AutoScroller|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + OUTBREAK = 5, "Outbreak (Terran)", SC2Campaign.WOL, "Colonist", SC2Race.TERRAN, MissionPools.EASY, "ap_outbreak", MissionFlag.Terran|MissionFlag.Defense|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + SAFE_HAVEN = 6, "Safe Haven (Terran)", SC2Campaign.WOL, "Colonist", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_safe_haven", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + HAVENS_FALL = 7, "Haven's Fall (Terran)", SC2Campaign.WOL, "Colonist", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_havens_fall", MissionFlag.Terran|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + SMASH_AND_GRAB = 8, "Smash and Grab (Terran)", SC2Campaign.WOL, "Artifact", SC2Race.TERRAN, MissionPools.EASY, "ap_smash_and_grab", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsPZ|MissionFlag.HasRaceSwap + THE_DIG = 9, "The Dig (Terran)", SC2Campaign.WOL, "Artifact", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_the_dig", MissionFlag.Terran|MissionFlag.TimedDefense|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + THE_MOEBIUS_FACTOR = 10, "The Moebius Factor (Terran)", SC2Campaign.WOL, "Artifact", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_the_moebius_factor", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + SUPERNOVA = 11, "Supernova (Terran)", SC2Campaign.WOL, "Artifact", SC2Race.TERRAN, MissionPools.HARD, "ap_supernova", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + MAW_OF_THE_VOID = 12, "Maw of the Void (Terran)", SC2Campaign.WOL, "Artifact", SC2Race.TERRAN, MissionPools.HARD, "ap_maw_of_the_void", MissionFlag.Terran|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + DEVILS_PLAYGROUND = 13, "Devil's Playground (Terran)", SC2Campaign.WOL, "Covert", SC2Race.TERRAN, MissionPools.EASY, "ap_devils_playground", MissionFlag.Terran|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + WELCOME_TO_THE_JUNGLE = 14, "Welcome to the Jungle (Terran)", SC2Campaign.WOL, "Covert", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_welcome_to_the_jungle", MissionFlag.Terran|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + BREAKOUT = 15, "Breakout", SC2Campaign.WOL, "Covert", SC2Race.ANY, MissionPools.STARTER, "ap_breakout", MissionFlag.Terran|MissionFlag.NoBuild|MissionFlag.VsTerran + GHOST_OF_A_CHANCE = 16, "Ghost of a Chance", SC2Campaign.WOL, "Covert", SC2Race.ANY, MissionPools.STARTER, "ap_ghost_of_a_chance", MissionFlag.Terran|MissionFlag.NoBuild|MissionFlag.VsTerran|MissionFlag.WoLNova + THE_GREAT_TRAIN_ROBBERY = 17, "The Great Train Robbery (Terran)", SC2Campaign.WOL, "Rebellion", SC2Race.TERRAN, MissionPools.EASY, "ap_the_great_train_robbery", MissionFlag.Terran|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + CUTTHROAT = 18, "Cutthroat (Terran)", SC2Campaign.WOL, "Rebellion", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_cutthroat", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + ENGINE_OF_DESTRUCTION = 19, "Engine of Destruction (Terran)", SC2Campaign.WOL, "Rebellion", SC2Race.TERRAN, MissionPools.HARD, "ap_engine_of_destruction", MissionFlag.Terran|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + MEDIA_BLITZ = 20, "Media Blitz (Terran)", SC2Campaign.WOL, "Rebellion", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_media_blitz", MissionFlag.Terran|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + PIERCING_OF_THE_SHROUD = 21, "Piercing the Shroud", SC2Campaign.WOL, "Rebellion", SC2Race.TERRAN, MissionPools.STARTER, "ap_piercing_the_shroud", MissionFlag.Terran|MissionFlag.NoBuild|MissionFlag.VsAll + GATES_OF_HELL = 26, "Gates of Hell (Terran)", SC2Campaign.WOL, "Char", SC2Race.TERRAN, MissionPools.HARD, "ap_gates_of_hell", MissionFlag.Terran|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + BELLY_OF_THE_BEAST = 27, "Belly of the Beast", SC2Campaign.WOL, "Char", SC2Race.ANY, MissionPools.STARTER, "ap_belly_of_the_beast", MissionFlag.Terran|MissionFlag.NoBuild|MissionFlag.VsZerg + SHATTER_THE_SKY = 28, "Shatter the Sky (Terran)", SC2Campaign.WOL, "Char", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_shatter_the_sky", MissionFlag.Terran|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + ALL_IN = 29, "All-In (Terran)", SC2Campaign.WOL, "Char", SC2Race.TERRAN, MissionPools.VERY_HARD, "ap_all_in", MissionFlag.Terran|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + + # Prophecy + WHISPERS_OF_DOOM = 22, "Whispers of Doom", SC2Campaign.PROPHECY, "_1", SC2Race.ANY, MissionPools.STARTER, "ap_whispers_of_doom", MissionFlag.Protoss|MissionFlag.NoBuild|MissionFlag.VsZerg + A_SINISTER_TURN = 23, "A Sinister Turn (Protoss)", SC2Campaign.PROPHECY, "_2", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_a_sinister_turn", MissionFlag.Protoss|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + ECHOES_OF_THE_FUTURE = 24, "Echoes of the Future (Protoss)", SC2Campaign.PROPHECY, "_3", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_echoes_of_the_future", MissionFlag.Protoss|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + IN_UTTER_DARKNESS = 25, "In Utter Darkness (Protoss)", SC2Campaign.PROPHECY, "_4", SC2Race.PROTOSS, MissionPools.HARD, "ap_in_utter_darkness", MissionFlag.Protoss|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + + # Heart of the Swarm + LAB_RAT = 30, "Lab Rat (Zerg)", SC2Campaign.HOTS, "Umoja", SC2Race.ZERG, MissionPools.STARTER, "ap_lab_rat", MissionFlag.Zerg|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + BACK_IN_THE_SADDLE = 31, "Back in the Saddle", SC2Campaign.HOTS, "Umoja", SC2Race.ANY, MissionPools.STARTER, "ap_back_in_the_saddle", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.NoBuild|MissionFlag.VsTZ + RENDEZVOUS = 32, "Rendezvous (Zerg)", SC2Campaign.HOTS, "Umoja", SC2Race.ZERG, MissionPools.EASY, "ap_rendezvous", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + HARVEST_OF_SCREAMS = 33, "Harvest of Screams (Zerg)", SC2Campaign.HOTS, "Kaldir", SC2Race.ZERG, MissionPools.EASY, "ap_harvest_of_screams", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + SHOOT_THE_MESSENGER = 34, "Shoot the Messenger (Zerg)", SC2Campaign.HOTS, "Kaldir", SC2Race.ZERG, MissionPools.EASY, "ap_shoot_the_messenger", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.TimedDefense|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + ENEMY_WITHIN = 35, "Enemy Within", SC2Campaign.HOTS, "Kaldir", SC2Race.ANY, MissionPools.EASY, "ap_enemy_within", MissionFlag.Zerg|MissionFlag.NoBuild|MissionFlag.VsProtoss + DOMINATION = 36, "Domination (Zerg)", SC2Campaign.HOTS, "Char", SC2Race.ZERG, MissionPools.EASY, "ap_domination", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.Countdown|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + FIRE_IN_THE_SKY = 37, "Fire in the Sky (Zerg)", SC2Campaign.HOTS, "Char", SC2Race.ZERG, MissionPools.MEDIUM, "ap_fire_in_the_sky", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + OLD_SOLDIERS = 38, "Old Soldiers (Zerg)", SC2Campaign.HOTS, "Char", SC2Race.ZERG, MissionPools.MEDIUM, "ap_old_soldiers", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + WAKING_THE_ANCIENT = 39, "Waking the Ancient (Zerg)", SC2Campaign.HOTS, "Zerus", SC2Race.ZERG, MissionPools.MEDIUM, "ap_waking_the_ancient", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + THE_CRUCIBLE = 40, "The Crucible (Zerg)", SC2Campaign.HOTS, "Zerus", SC2Race.ZERG, MissionPools.MEDIUM, "ap_the_crucible", MissionFlag.Zerg|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + SUPREME = 41, "Supreme", SC2Campaign.HOTS, "Zerus", SC2Race.ANY, MissionPools.MEDIUM, "ap_supreme", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.NoBuild|MissionFlag.VsZerg + INFESTED = 42, "Infested (Zerg)", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.ZERG, MissionPools.MEDIUM, "ap_infested", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + HAND_OF_DARKNESS = 43, "Hand of Darkness (Zerg)", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.ZERG, MissionPools.HARD, "ap_hand_of_darkness", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + PHANTOMS_OF_THE_VOID = 44, "Phantoms of the Void (Zerg)", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.ZERG, MissionPools.MEDIUM, "ap_phantoms_of_the_void", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + WITH_FRIENDS_LIKE_THESE = 45, "With Friends Like These", SC2Campaign.HOTS, "Dominion Space", SC2Race.ANY, MissionPools.STARTER, "ap_with_friends_like_these", MissionFlag.Terran|MissionFlag.NoBuild|MissionFlag.VsTerran + CONVICTION = 46, "Conviction", SC2Campaign.HOTS, "Dominion Space", SC2Race.ANY, MissionPools.MEDIUM, "ap_conviction", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.NoBuild|MissionFlag.VsTerran + PLANETFALL = 47, "Planetfall (Zerg)", SC2Campaign.HOTS, "Korhal", SC2Race.ZERG, MissionPools.HARD, "ap_planetfall", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + DEATH_FROM_ABOVE = 48, "Death From Above (Zerg)", SC2Campaign.HOTS, "Korhal", SC2Race.ZERG, MissionPools.HARD, "ap_death_from_above", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + THE_RECKONING = 49, "The Reckoning (Zerg)", SC2Campaign.HOTS, "Korhal", SC2Race.ZERG, MissionPools.VERY_HARD, "ap_the_reckoning", MissionFlag.Zerg|MissionFlag.Kerrigan|MissionFlag.VsTerran|MissionFlag.AiTerranAlly|MissionFlag.HasRaceSwap + + # Prologue + DARK_WHISPERS = 50, "Dark Whispers (Protoss)", SC2Campaign.PROLOGUE, "_1", SC2Race.PROTOSS, MissionPools.EASY, "ap_dark_whispers", MissionFlag.Protoss|MissionFlag.Countdown|MissionFlag.VsTZ|MissionFlag.HasRaceSwap + GHOSTS_IN_THE_FOG = 51, "Ghosts in the Fog (Protoss)", SC2Campaign.PROLOGUE, "_2", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_ghosts_in_the_fog", MissionFlag.Protoss|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + EVIL_AWOKEN = 52, "Evil Awoken", SC2Campaign.PROLOGUE, "_3", SC2Race.PROTOSS, MissionPools.STARTER, "ap_evil_awoken", MissionFlag.Protoss|MissionFlag.NoBuild|MissionFlag.VsProtoss + + # LotV + FOR_AIUR = 53, "For Aiur!", SC2Campaign.LOTV, "Aiur", SC2Race.ANY, MissionPools.STARTER, "ap_for_aiur", MissionFlag.Protoss|MissionFlag.NoBuild|MissionFlag.VsZerg + THE_GROWING_SHADOW = 54, "The Growing Shadow (Protoss)", SC2Campaign.LOTV, "Aiur", SC2Race.PROTOSS, MissionPools.EASY, "ap_the_growing_shadow", MissionFlag.Protoss|MissionFlag.VsPZ|MissionFlag.HasRaceSwap + THE_SPEAR_OF_ADUN = 55, "The Spear of Adun (Protoss)", SC2Campaign.LOTV, "Aiur", SC2Race.PROTOSS, MissionPools.EASY, "ap_the_spear_of_adun", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsPZ|MissionFlag.HasRaceSwap + SKY_SHIELD = 56, "Sky Shield (Protoss)", SC2Campaign.LOTV, "Korhal", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_sky_shield", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.AiTerranAlly|MissionFlag.HasRaceSwap + BROTHERS_IN_ARMS = 57, "Brothers in Arms (Protoss)", SC2Campaign.LOTV, "Korhal", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_brothers_in_arms", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsTerran|MissionFlag.AiTerranAlly|MissionFlag.HasRaceSwap + AMON_S_REACH = 58, "Amon's Reach (Protoss)", SC2Campaign.LOTV, "Shakuras", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_amon_s_reach", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + LAST_STAND = 59, "Last Stand (Protoss)", SC2Campaign.LOTV, "Shakuras", SC2Race.PROTOSS, MissionPools.HARD, "ap_last_stand", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + FORBIDDEN_WEAPON = 60, "Forbidden Weapon (Protoss)", SC2Campaign.LOTV, "Purifier", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_forbidden_weapon", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + TEMPLE_OF_UNIFICATION = 61, "Temple of Unification (Protoss)", SC2Campaign.LOTV, "Ulnar", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_temple_of_unification", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsTP|MissionFlag.HasRaceSwap + THE_INFINITE_CYCLE = 62, "The Infinite Cycle", SC2Campaign.LOTV, "Ulnar", SC2Race.ANY, MissionPools.HARD, "ap_the_infinite_cycle", MissionFlag.Protoss|MissionFlag.Kerrigan|MissionFlag.NoBuild|MissionFlag.VsTP + HARBINGER_OF_OBLIVION = 63, "Harbinger of Oblivion (Protoss)", SC2Campaign.LOTV, "Ulnar", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_harbinger_of_oblivion", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.Countdown|MissionFlag.VsTP|MissionFlag.AiZergAlly|MissionFlag.HasRaceSwap + UNSEALING_THE_PAST = 64, "Unsealing the Past (Protoss)", SC2Campaign.LOTV, "Purifier", SC2Race.PROTOSS, MissionPools.HARD, "ap_unsealing_the_past", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.AutoScroller|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + PURIFICATION = 65, "Purification (Protoss)", SC2Campaign.LOTV, "Purifier", SC2Race.PROTOSS, MissionPools.HARD, "ap_purification", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsZerg|MissionFlag.HasRaceSwap + STEPS_OF_THE_RITE = 66, "Steps of the Rite (Protoss)", SC2Campaign.LOTV, "Tal'darim", SC2Race.PROTOSS, MissionPools.HARD, "ap_steps_of_the_rite", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + RAK_SHIR = 67, "Rak'Shir (Protoss)", SC2Campaign.LOTV, "Tal'darim", SC2Race.PROTOSS, MissionPools.HARD, "ap_rak_shir", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsProtoss|MissionFlag.HasRaceSwap + TEMPLAR_S_CHARGE = 68, "Templar's Charge (Protoss)", SC2Campaign.LOTV, "Moebius", SC2Race.PROTOSS, MissionPools.HARD, "ap_templar_s_charge", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsTerran|MissionFlag.HasRaceSwap + TEMPLAR_S_RETURN = 69, "Templar's Return", SC2Campaign.LOTV, "Return to Aiur", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_templar_s_return", MissionFlag.Protoss|MissionFlag.NoBuild|MissionFlag.VsPZ + THE_HOST = 70, "The Host (Protoss)", SC2Campaign.LOTV, "Return to Aiur", SC2Race.PROTOSS, MissionPools.VERY_HARD, "ap_the_host", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsAll|MissionFlag.HasRaceSwap + SALVATION = 71, "Salvation (Protoss)", SC2Campaign.LOTV, "Return to Aiur", SC2Race.PROTOSS, MissionPools.VERY_HARD, "ap_salvation", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.TimedDefense|MissionFlag.VsPZ|MissionFlag.AiProtossAlly|MissionFlag.HasRaceSwap + + # Epilogue + INTO_THE_VOID = 72, "Into the Void", SC2Campaign.EPILOGUE, "_1", SC2Race.PROTOSS, MissionPools.VERY_HARD, "ap_into_the_void", MissionFlag.Protoss|MissionFlag.VanillaSoa|MissionFlag.VsAll|MissionFlag.AiTerranAlly|MissionFlag.AiZergAlly + THE_ESSENCE_OF_ETERNITY = 73, "The Essence of Eternity", SC2Campaign.EPILOGUE, "_2", SC2Race.TERRAN, MissionPools.VERY_HARD, "ap_the_essence_of_eternity", MissionFlag.Terran|MissionFlag.TimedDefense|MissionFlag.VsAll|MissionFlag.AiZergAlly|MissionFlag.AiProtossAlly + AMON_S_FALL = 74, "Amon's Fall", SC2Campaign.EPILOGUE, "_3", SC2Race.ZERG, MissionPools.VERY_HARD, "ap_amon_s_fall", MissionFlag.Zerg|MissionFlag.AutoScroller|MissionFlag.VsAll|MissionFlag.AiTerranAlly|MissionFlag.AiProtossAlly + + # Nova Covert Ops + THE_ESCAPE = 75, "The Escape", SC2Campaign.NCO, "_1", SC2Race.ANY, MissionPools.MEDIUM, "ap_the_escape", MissionFlag.Terran|MissionFlag.Nova|MissionFlag.NoBuild|MissionFlag.VsTerran + SUDDEN_STRIKE = 76, "Sudden Strike", SC2Campaign.NCO, "_1", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_sudden_strike", MissionFlag.Terran|MissionFlag.Nova|MissionFlag.TimedDefense|MissionFlag.VsZerg + ENEMY_INTELLIGENCE = 77, "Enemy Intelligence", SC2Campaign.NCO, "_1", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_enemy_intelligence", MissionFlag.Terran|MissionFlag.Nova|MissionFlag.Defense|MissionFlag.VsZerg + TROUBLE_IN_PARADISE = 78, "Trouble In Paradise", SC2Campaign.NCO, "_2", SC2Race.TERRAN, MissionPools.HARD, "ap_trouble_in_paradise", MissionFlag.Terran|MissionFlag.Nova|MissionFlag.Countdown|MissionFlag.VsPZ + NIGHT_TERRORS = 79, "Night Terrors", SC2Campaign.NCO, "_2", SC2Race.TERRAN, MissionPools.HARD, "ap_night_terrors", MissionFlag.Terran|MissionFlag.Nova|MissionFlag.VsPZ + FLASHPOINT = 80, "Flashpoint", SC2Campaign.NCO, "_2", SC2Race.TERRAN, MissionPools.HARD, "ap_flashpoint", MissionFlag.Terran|MissionFlag.Nova|MissionFlag.VsZerg + IN_THE_ENEMY_S_SHADOW = 81, "In the Enemy's Shadow", SC2Campaign.NCO, "_3", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_in_the_enemy_s_shadow", MissionFlag.Terran|MissionFlag.Nova|MissionFlag.NoBuild|MissionFlag.VsTerran + DARK_SKIES = 82, "Dark Skies", SC2Campaign.NCO, "_3", SC2Race.TERRAN, MissionPools.HARD, "ap_dark_skies", MissionFlag.Terran|MissionFlag.Nova|MissionFlag.TimedDefense|MissionFlag.VsProtoss + END_GAME = 83, "End Game", SC2Campaign.NCO, "_3", SC2Race.TERRAN, MissionPools.VERY_HARD, "ap_end_game", MissionFlag.Terran|MissionFlag.Nova|MissionFlag.Defense|MissionFlag.VsTerran + + # Race-Swapped Variants + # 84/85 - Liberation Day + THE_OUTLAWS_Z = 86, "The Outlaws (Zerg)", SC2Campaign.WOL, "Mar Sara", SC2Race.ZERG, MissionPools.EASY, "ap_the_outlaws", MissionFlag.Zerg|MissionFlag.VsTerran|MissionFlag.RaceSwap + THE_OUTLAWS_P = 87, "The Outlaws (Protoss)", SC2Campaign.WOL, "Mar Sara", SC2Race.PROTOSS, MissionPools.EASY, "ap_the_outlaws", MissionFlag.Protoss|MissionFlag.VsTerran|MissionFlag.RaceSwap + ZERO_HOUR_Z = 88, "Zero Hour (Zerg)", SC2Campaign.WOL, "Mar Sara", SC2Race.ZERG, MissionPools.MEDIUM, "ap_zero_hour", MissionFlag.Zerg|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.RaceSwap + ZERO_HOUR_P = 89, "Zero Hour (Protoss)", SC2Campaign.WOL, "Mar Sara", SC2Race.PROTOSS, MissionPools.EASY, "ap_zero_hour", MissionFlag.Protoss|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.RaceSwap + EVACUATION_Z = 90, "Evacuation (Zerg)", SC2Campaign.WOL, "Colonist", SC2Race.ZERG, MissionPools.EASY, "ap_evacuation", MissionFlag.Zerg|MissionFlag.AutoScroller|MissionFlag.VsZerg|MissionFlag.RaceSwap + EVACUATION_P = 91, "Evacuation (Protoss)", SC2Campaign.WOL, "Colonist", SC2Race.PROTOSS, MissionPools.EASY, "ap_evacuation", MissionFlag.Protoss|MissionFlag.AutoScroller|MissionFlag.VsZerg|MissionFlag.RaceSwap + OUTBREAK_Z = 92, "Outbreak (Zerg)", SC2Campaign.WOL, "Colonist", SC2Race.ZERG, MissionPools.MEDIUM, "ap_outbreak", MissionFlag.Zerg|MissionFlag.Defense|MissionFlag.VsZerg|MissionFlag.RaceSwap + OUTBREAK_P = 93, "Outbreak (Protoss)", SC2Campaign.WOL, "Colonist", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_outbreak", MissionFlag.Protoss|MissionFlag.Defense|MissionFlag.VsZerg|MissionFlag.RaceSwap + SAFE_HAVEN_Z = 94, "Safe Haven (Zerg)", SC2Campaign.WOL, "Colonist", SC2Race.ZERG, MissionPools.MEDIUM, "ap_safe_haven", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.RaceSwap + SAFE_HAVEN_P = 95, "Safe Haven (Protoss)", SC2Campaign.WOL, "Colonist", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_safe_haven", MissionFlag.Protoss|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.RaceSwap + HAVENS_FALL_Z = 96, "Haven's Fall (Zerg)", SC2Campaign.WOL, "Colonist", SC2Race.ZERG, MissionPools.MEDIUM, "ap_havens_fall", MissionFlag.Zerg|MissionFlag.VsZerg|MissionFlag.RaceSwap + HAVENS_FALL_P = 97, "Haven's Fall (Protoss)", SC2Campaign.WOL, "Colonist", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_havens_fall", MissionFlag.Protoss|MissionFlag.VsZerg|MissionFlag.RaceSwap + SMASH_AND_GRAB_Z = 98, "Smash and Grab (Zerg)", SC2Campaign.WOL, "Artifact", SC2Race.ZERG, MissionPools.EASY, "ap_smash_and_grab", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsPZ|MissionFlag.RaceSwap + SMASH_AND_GRAB_P = 99, "Smash and Grab (Protoss)", SC2Campaign.WOL, "Artifact", SC2Race.PROTOSS, MissionPools.EASY, "ap_smash_and_grab", MissionFlag.Protoss|MissionFlag.Countdown|MissionFlag.VsPZ|MissionFlag.RaceSwap + THE_DIG_Z = 100, "The Dig (Zerg)", SC2Campaign.WOL, "Artifact", SC2Race.ZERG, MissionPools.MEDIUM, "ap_the_dig", MissionFlag.Zerg|MissionFlag.TimedDefense|MissionFlag.VsProtoss|MissionFlag.RaceSwap + THE_DIG_P = 101, "The Dig (Protoss)", SC2Campaign.WOL, "Artifact", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_the_dig", MissionFlag.Protoss|MissionFlag.TimedDefense|MissionFlag.VsProtoss|MissionFlag.RaceSwap + THE_MOEBIUS_FACTOR_Z = 102, "The Moebius Factor (Zerg)", SC2Campaign.WOL, "Artifact", SC2Race.ZERG, MissionPools.MEDIUM, "ap_the_moebius_factor", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsZerg|MissionFlag.RaceSwap + THE_MOEBIUS_FACTOR_P = 103, "The Moebius Factor (Protoss)", SC2Campaign.WOL, "Artifact", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_the_moebius_factor", MissionFlag.Protoss|MissionFlag.Countdown|MissionFlag.VsZerg|MissionFlag.RaceSwap + SUPERNOVA_Z = 104, "Supernova (Zerg)", SC2Campaign.WOL, "Artifact", SC2Race.ZERG, MissionPools.HARD, "ap_supernova", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.RaceSwap + SUPERNOVA_P = 105, "Supernova (Protoss)", SC2Campaign.WOL, "Artifact", SC2Race.PROTOSS, MissionPools.HARD, "ap_supernova", MissionFlag.Protoss|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.RaceSwap + MAW_OF_THE_VOID_Z = 106, "Maw of the Void (Zerg)", SC2Campaign.WOL, "Artifact", SC2Race.ZERG, MissionPools.HARD, "ap_maw_of_the_void", MissionFlag.Zerg|MissionFlag.VsProtoss|MissionFlag.RaceSwap + MAW_OF_THE_VOID_P = 107, "Maw of the Void (Protoss)", SC2Campaign.WOL, "Artifact", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_maw_of_the_void", MissionFlag.Protoss|MissionFlag.VsProtoss|MissionFlag.RaceSwap + DEVILS_PLAYGROUND_Z = 108, "Devil's Playground (Zerg)", SC2Campaign.WOL, "Covert", SC2Race.ZERG, MissionPools.EASY, "ap_devils_playground", MissionFlag.Zerg|MissionFlag.VsZerg|MissionFlag.RaceSwap + DEVILS_PLAYGROUND_P = 109, "Devil's Playground (Protoss)", SC2Campaign.WOL, "Covert", SC2Race.PROTOSS, MissionPools.EASY, "ap_devils_playground", MissionFlag.Protoss|MissionFlag.VsZerg|MissionFlag.RaceSwap + WELCOME_TO_THE_JUNGLE_Z = 110, "Welcome to the Jungle (Zerg)", SC2Campaign.WOL, "Covert", SC2Race.ZERG, MissionPools.HARD, "ap_welcome_to_the_jungle", MissionFlag.Zerg|MissionFlag.VsProtoss|MissionFlag.RaceSwap + WELCOME_TO_THE_JUNGLE_P = 111, "Welcome to the Jungle (Protoss)", SC2Campaign.WOL, "Covert", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_welcome_to_the_jungle", MissionFlag.Protoss|MissionFlag.VsProtoss|MissionFlag.RaceSwap + # 112/113 - Breakout + # 114/115 - Ghost of a Chance + THE_GREAT_TRAIN_ROBBERY_Z = 116, "The Great Train Robbery (Zerg)", SC2Campaign.WOL, "Rebellion", SC2Race.ZERG, MissionPools.EASY, "ap_the_great_train_robbery", MissionFlag.Zerg|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.RaceSwap + THE_GREAT_TRAIN_ROBBERY_P = 117, "The Great Train Robbery (Protoss)", SC2Campaign.WOL, "Rebellion", SC2Race.PROTOSS, MissionPools.EASY, "ap_the_great_train_robbery", MissionFlag.Protoss|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.RaceSwap + CUTTHROAT_Z = 118, "Cutthroat (Zerg)", SC2Campaign.WOL, "Rebellion", SC2Race.ZERG, MissionPools.MEDIUM, "ap_cutthroat", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.RaceSwap + CUTTHROAT_P = 119, "Cutthroat (Protoss)", SC2Campaign.WOL, "Rebellion", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_cutthroat", MissionFlag.Protoss|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.RaceSwap + ENGINE_OF_DESTRUCTION_Z = 120, "Engine of Destruction (Zerg)", SC2Campaign.WOL, "Rebellion", SC2Race.ZERG, MissionPools.HARD, "ap_engine_of_destruction", MissionFlag.Zerg|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.RaceSwap + ENGINE_OF_DESTRUCTION_P = 121, "Engine of Destruction (Protoss)", SC2Campaign.WOL, "Rebellion", SC2Race.PROTOSS, MissionPools.HARD, "ap_engine_of_destruction", MissionFlag.Protoss|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.RaceSwap + MEDIA_BLITZ_Z = 122, "Media Blitz (Zerg)", SC2Campaign.WOL, "Rebellion", SC2Race.ZERG, MissionPools.HARD, "ap_media_blitz", MissionFlag.Zerg|MissionFlag.VsTerran|MissionFlag.RaceSwap + MEDIA_BLITZ_P = 123, "Media Blitz (Protoss)", SC2Campaign.WOL, "Rebellion", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_media_blitz", MissionFlag.Protoss|MissionFlag.VsTerran|MissionFlag.RaceSwap + # 124/125 - Piercing the Shroud + # 126/127 - Whispers of Doom + A_SINISTER_TURN_T = 128, "A Sinister Turn (Terran)", SC2Campaign.PROPHECY, "_2", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_a_sinister_turn", MissionFlag.Terran|MissionFlag.VsProtoss|MissionFlag.RaceSwap + A_SINISTER_TURN_Z = 129, "A Sinister Turn (Zerg)", SC2Campaign.PROPHECY, "_2", SC2Race.ZERG, MissionPools.MEDIUM, "ap_a_sinister_turn", MissionFlag.Zerg|MissionFlag.VsProtoss|MissionFlag.RaceSwap + ECHOES_OF_THE_FUTURE_T = 130, "Echoes of the Future (Terran)", SC2Campaign.PROPHECY, "_3", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_echoes_of_the_future", MissionFlag.Terran|MissionFlag.VsZerg|MissionFlag.RaceSwap + ECHOES_OF_THE_FUTURE_Z = 131, "Echoes of the Future (Zerg)", SC2Campaign.PROPHECY, "_3", SC2Race.ZERG, MissionPools.MEDIUM, "ap_echoes_of_the_future", MissionFlag.Zerg|MissionFlag.VsZerg|MissionFlag.RaceSwap + IN_UTTER_DARKNESS_T = 132, "In Utter Darkness (Terran)", SC2Campaign.PROPHECY, "_4", SC2Race.TERRAN, MissionPools.HARD, "ap_in_utter_darkness", MissionFlag.Terran|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.RaceSwap + IN_UTTER_DARKNESS_Z = 133, "In Utter Darkness (Zerg)", SC2Campaign.PROPHECY, "_4", SC2Race.ZERG, MissionPools.HARD, "ap_in_utter_darkness", MissionFlag.Zerg|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.RaceSwap + GATES_OF_HELL_Z = 134, "Gates of Hell (Zerg)", SC2Campaign.WOL, "Char", SC2Race.ZERG, MissionPools.HARD, "ap_gates_of_hell", MissionFlag.Zerg|MissionFlag.VsZerg|MissionFlag.RaceSwap + GATES_OF_HELL_P = 135, "Gates of Hell (Protoss)", SC2Campaign.WOL, "Char", SC2Race.PROTOSS, MissionPools.HARD, "ap_gates_of_hell", MissionFlag.Protoss|MissionFlag.VsZerg|MissionFlag.RaceSwap + # 136/137 - Belly of the Beast + SHATTER_THE_SKY_Z = 138, "Shatter the Sky (Zerg)", SC2Campaign.WOL, "Char", SC2Race.ZERG, MissionPools.HARD, "ap_shatter_the_sky", MissionFlag.Zerg|MissionFlag.VsZerg|MissionFlag.RaceSwap + SHATTER_THE_SKY_P = 139, "Shatter the Sky (Protoss)", SC2Campaign.WOL, "Char", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_shatter_the_sky", MissionFlag.Protoss|MissionFlag.VsZerg|MissionFlag.RaceSwap + ALL_IN_Z = 140, "All-In (Zerg)", SC2Campaign.WOL, "Char", SC2Race.ZERG, MissionPools.VERY_HARD, "ap_all_in", MissionFlag.Zerg|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.RaceSwap + ALL_IN_P = 141, "All-In (Protoss)", SC2Campaign.WOL, "Char", SC2Race.PROTOSS, MissionPools.VERY_HARD, "ap_all_in", MissionFlag.Protoss|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.RaceSwap + LAB_RAT_T = 142, "Lab Rat (Terran)", SC2Campaign.HOTS, "Umoja", SC2Race.TERRAN, MissionPools.STARTER, "ap_lab_rat", MissionFlag.Terran|MissionFlag.VsTerran|MissionFlag.RaceSwap + LAB_RAT_P = 143, "Lab Rat (Protoss)", SC2Campaign.HOTS, "Umoja", SC2Race.PROTOSS, MissionPools.STARTER, "ap_lab_rat", MissionFlag.Protoss|MissionFlag.VsTerran|MissionFlag.RaceSwap + # 144/145 - Back in the Saddle + RENDEZVOUS_T = 146, "Rendezvous (Terran)", SC2Campaign.HOTS, "Umoja", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_rendezvous", MissionFlag.Terran|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.RaceSwap + RENDEZVOUS_P = 147, "Rendezvous (Protoss)", SC2Campaign.HOTS, "Umoja", SC2Race.PROTOSS, MissionPools.EASY, "ap_rendezvous", MissionFlag.Protoss|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.RaceSwap + HARVEST_OF_SCREAMS_T = 148, "Harvest of Screams (Terran)", SC2Campaign.HOTS, "Kaldir", SC2Race.TERRAN, MissionPools.EASY, "ap_harvest_of_screams", MissionFlag.Terran|MissionFlag.VsProtoss|MissionFlag.RaceSwap + HARVEST_OF_SCREAMS_P = 149, "Harvest of Screams (Protoss)", SC2Campaign.HOTS, "Kaldir", SC2Race.PROTOSS, MissionPools.EASY, "ap_harvest_of_screams", MissionFlag.Protoss|MissionFlag.VsProtoss|MissionFlag.RaceSwap + SHOOT_THE_MESSENGER_T = 150, "Shoot the Messenger (Terran)", SC2Campaign.HOTS, "Kaldir", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_shoot_the_messenger", MissionFlag.Terran|MissionFlag.TimedDefense|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.RaceSwap + SHOOT_THE_MESSENGER_P = 151, "Shoot the Messenger (Protoss)", SC2Campaign.HOTS, "Kaldir", SC2Race.PROTOSS, MissionPools.EASY, "ap_shoot_the_messenger", MissionFlag.Protoss|MissionFlag.TimedDefense|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.RaceSwap + # 152/153 - Enemy Within + DOMINATION_T = 154, "Domination (Terran)", SC2Campaign.HOTS, "Char", SC2Race.TERRAN, MissionPools.EASY, "ap_domination", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsZerg|MissionFlag.RaceSwap + DOMINATION_P = 155, "Domination (Protoss)", SC2Campaign.HOTS, "Char", SC2Race.PROTOSS, MissionPools.EASY, "ap_domination", MissionFlag.Protoss|MissionFlag.Countdown|MissionFlag.VsZerg|MissionFlag.RaceSwap + FIRE_IN_THE_SKY_T = 156, "Fire in the Sky (Terran)", SC2Campaign.HOTS, "Char", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_fire_in_the_sky", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.RaceSwap + FIRE_IN_THE_SKY_P = 157, "Fire in the Sky (Protoss)", SC2Campaign.HOTS, "Char", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_fire_in_the_sky", MissionFlag.Protoss|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.RaceSwap + OLD_SOLDIERS_T = 158, "Old Soldiers (Terran)", SC2Campaign.HOTS, "Char", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_old_soldiers", MissionFlag.Terran|MissionFlag.VsTerran|MissionFlag.RaceSwap + OLD_SOLDIERS_P = 159, "Old Soldiers (Protoss)", SC2Campaign.HOTS, "Char", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_old_soldiers", MissionFlag.Protoss|MissionFlag.VsTerran|MissionFlag.RaceSwap + WAKING_THE_ANCIENT_T = 160, "Waking the Ancient (Terran)", SC2Campaign.HOTS, "Zerus", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_waking_the_ancient", MissionFlag.Terran|MissionFlag.VsZerg|MissionFlag.RaceSwap + WAKING_THE_ANCIENT_P = 161, "Waking the Ancient (Protoss)", SC2Campaign.HOTS, "Zerus", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_waking_the_ancient", MissionFlag.Protoss|MissionFlag.VsZerg|MissionFlag.RaceSwap + THE_CRUCIBLE_T = 162, "The Crucible (Terran)", SC2Campaign.HOTS, "Zerus", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_the_crucible", MissionFlag.Terran|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.RaceSwap + THE_CRUCIBLE_P = 163, "The Crucible (Protoss)", SC2Campaign.HOTS, "Zerus", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_the_crucible", MissionFlag.Protoss|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.RaceSwap + # 164/165 - Supreme + INFESTED_T = 166, "Infested (Terran)", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_infested", MissionFlag.Terran|MissionFlag.VsTerran|MissionFlag.RaceSwap + INFESTED_P = 167, "Infested (Protoss)", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_infested", MissionFlag.Protoss|MissionFlag.VsTerran|MissionFlag.RaceSwap + HAND_OF_DARKNESS_T = 168, "Hand of Darkness (Terran)", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.TERRAN, MissionPools.HARD, "ap_hand_of_darkness", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.RaceSwap + HAND_OF_DARKNESS_P = 169, "Hand of Darkness (Protoss)", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.PROTOSS, MissionPools.HARD, "ap_hand_of_darkness", MissionFlag.Protoss|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.RaceSwap + PHANTOMS_OF_THE_VOID_T = 170, "Phantoms of the Void (Terran)", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_phantoms_of_the_void", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.RaceSwap + PHANTOMS_OF_THE_VOID_P = 171, "Phantoms of the Void (Protoss)", SC2Campaign.HOTS, "Skygeirr Station", SC2Race.PROTOSS, MissionPools.MEDIUM, "ap_phantoms_of_the_void", MissionFlag.Protoss|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.RaceSwap + # 172/173 - With Friends Like These + # 174/175 - Conviction + PLANETFALL_T = 176, "Planetfall (Terran)", SC2Campaign.HOTS, "Korhal", SC2Race.TERRAN, MissionPools.HARD, "ap_planetfall", MissionFlag.Terran|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.RaceSwap + PLANETFALL_P = 177, "Planetfall (Protoss)", SC2Campaign.HOTS, "Korhal", SC2Race.PROTOSS, MissionPools.HARD, "ap_planetfall", MissionFlag.Protoss|MissionFlag.AutoScroller|MissionFlag.VsTerran|MissionFlag.RaceSwap + DEATH_FROM_ABOVE_T = 178, "Death From Above (Terran)", SC2Campaign.HOTS, "Korhal", SC2Race.TERRAN, MissionPools.HARD, "ap_death_from_above", MissionFlag.Terran|MissionFlag.VsTerran|MissionFlag.RaceSwap + DEATH_FROM_ABOVE_P = 179, "Death From Above (Protoss)", SC2Campaign.HOTS, "Korhal", SC2Race.PROTOSS, MissionPools.HARD, "ap_death_from_above", MissionFlag.Protoss|MissionFlag.VsTerran|MissionFlag.RaceSwap + THE_RECKONING_T = 180, "The Reckoning (Terran)", SC2Campaign.HOTS, "Korhal", SC2Race.TERRAN, MissionPools.VERY_HARD, "ap_the_reckoning", MissionFlag.Terran|MissionFlag.VsTerran|MissionFlag.AiTerranAlly|MissionFlag.RaceSwap + THE_RECKONING_P = 181, "The Reckoning (Protoss)", SC2Campaign.HOTS, "Korhal", SC2Race.PROTOSS, MissionPools.VERY_HARD, "ap_the_reckoning", MissionFlag.Protoss|MissionFlag.VsTerran|MissionFlag.AiTerranAlly|MissionFlag.RaceSwap + DARK_WHISPERS_T = 182, "Dark Whispers (Terran)", SC2Campaign.PROLOGUE, "_1", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_dark_whispers", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsTZ|MissionFlag.RaceSwap + DARK_WHISPERS_Z = 183, "Dark Whispers (Zerg)", SC2Campaign.PROLOGUE, "_1", SC2Race.ZERG, MissionPools.MEDIUM, "ap_dark_whispers", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsTZ|MissionFlag.RaceSwap + GHOSTS_IN_THE_FOG_T = 184, "Ghosts in the Fog (Terran)", SC2Campaign.PROLOGUE, "_2", SC2Race.TERRAN, MissionPools.HARD, "ap_ghosts_in_the_fog", MissionFlag.Terran|MissionFlag.VsProtoss|MissionFlag.RaceSwap + GHOSTS_IN_THE_FOG_Z = 185, "Ghosts in the Fog (Zerg)", SC2Campaign.PROLOGUE, "_2", SC2Race.ZERG, MissionPools.HARD, "ap_ghosts_in_the_fog", MissionFlag.Zerg|MissionFlag.VsProtoss|MissionFlag.RaceSwap + # 186/187 - Evil Awoken + # 188/189 - For Aiur! + THE_GROWING_SHADOW_T = 190, "The Growing Shadow (Terran)", SC2Campaign.LOTV, "Aiur", SC2Race.TERRAN, MissionPools.EASY, "ap_the_growing_shadow", MissionFlag.Terran|MissionFlag.VsPZ|MissionFlag.RaceSwap + THE_GROWING_SHADOW_Z = 191, "The Growing Shadow (Zerg)", SC2Campaign.LOTV, "Aiur", SC2Race.ZERG, MissionPools.EASY, "ap_the_growing_shadow", MissionFlag.Zerg|MissionFlag.VsPZ|MissionFlag.RaceSwap + THE_SPEAR_OF_ADUN_T = 192, "The Spear of Adun (Terran)", SC2Campaign.LOTV, "Aiur", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_the_spear_of_adun", MissionFlag.Terran|MissionFlag.VsPZ|MissionFlag.RaceSwap + THE_SPEAR_OF_ADUN_Z = 193, "The Spear of Adun (Zerg)", SC2Campaign.LOTV, "Aiur", SC2Race.ZERG, MissionPools.MEDIUM, "ap_the_spear_of_adun", MissionFlag.Zerg|MissionFlag.VsPZ|MissionFlag.RaceSwap + SKY_SHIELD_T = 194, "Sky Shield (Terran)", SC2Campaign.LOTV, "Korhal", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_sky_shield", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.AiTerranAlly|MissionFlag.RaceSwap + SKY_SHIELD_Z = 195, "Sky Shield (Zerg)", SC2Campaign.LOTV, "Korhal", SC2Race.ZERG, MissionPools.MEDIUM, "ap_sky_shield", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsTerran|MissionFlag.AiTerranAlly|MissionFlag.RaceSwap + BROTHERS_IN_ARMS_T = 196, "Brothers in Arms (Terran)", SC2Campaign.LOTV, "Korhal", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_brothers_in_arms", MissionFlag.Terran|MissionFlag.VsTerran|MissionFlag.AiTerranAlly|MissionFlag.RaceSwap + BROTHERS_IN_ARMS_Z = 197, "Brothers in Arms (Zerg)", SC2Campaign.LOTV, "Korhal", SC2Race.ZERG, MissionPools.MEDIUM, "ap_brothers_in_arms", MissionFlag.Zerg|MissionFlag.VsTerran|MissionFlag.AiTerranAlly|MissionFlag.RaceSwap + AMON_S_REACH_T = 198, "Amon's Reach (Terran)", SC2Campaign.LOTV, "Shakuras", SC2Race.TERRAN, MissionPools.MEDIUM, "ap_amon_s_reach", MissionFlag.Terran|MissionFlag.VsZerg|MissionFlag.RaceSwap + AMON_S_REACH_Z = 199, "Amon's Reach (Zerg)", SC2Campaign.LOTV, "Shakuras", SC2Race.ZERG, MissionPools.MEDIUM, "ap_amon_s_reach", MissionFlag.Zerg|MissionFlag.VsZerg|MissionFlag.RaceSwap + LAST_STAND_T = 200, "Last Stand (Terran)", SC2Campaign.LOTV, "Shakuras", SC2Race.TERRAN, MissionPools.HARD, "ap_last_stand", MissionFlag.Terran|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.RaceSwap + LAST_STAND_Z = 201, "Last Stand (Zerg)", SC2Campaign.LOTV, "Shakuras", SC2Race.ZERG, MissionPools.HARD, "ap_last_stand", MissionFlag.Zerg|MissionFlag.TimedDefense|MissionFlag.VsZerg|MissionFlag.RaceSwap + FORBIDDEN_WEAPON_T = 202, "Forbidden Weapon (Terran)", SC2Campaign.LOTV, "Purifier", SC2Race.TERRAN, MissionPools.HARD, "ap_forbidden_weapon", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.RaceSwap + FORBIDDEN_WEAPON_Z = 203, "Forbidden Weapon (Zerg)", SC2Campaign.LOTV, "Purifier", SC2Race.ZERG, MissionPools.HARD, "ap_forbidden_weapon", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsProtoss|MissionFlag.RaceSwap + TEMPLE_OF_UNIFICATION_T = 204, "Temple of Unification (Terran)", SC2Campaign.LOTV, "Ulnar", SC2Race.TERRAN, MissionPools.HARD, "ap_temple_of_unification", MissionFlag.Terran|MissionFlag.VsTP|MissionFlag.RaceSwap + TEMPLE_OF_UNIFICATION_Z = 205, "Temple of Unification (Zerg)", SC2Campaign.LOTV, "Ulnar", SC2Race.ZERG, MissionPools.HARD, "ap_temple_of_unification", MissionFlag.Zerg|MissionFlag.VsTP|MissionFlag.RaceSwap + # 206/207 - The Infinite Cycle + HARBINGER_OF_OBLIVION_T = 208, "Harbinger of Oblivion (Terran)", SC2Campaign.LOTV, "Ulnar", SC2Race.TERRAN, MissionPools.HARD, "ap_harbinger_of_oblivion", MissionFlag.Terran|MissionFlag.Countdown|MissionFlag.VsTP|MissionFlag.AiZergAlly|MissionFlag.RaceSwap + HARBINGER_OF_OBLIVION_Z = 209, "Harbinger of Oblivion (Zerg)", SC2Campaign.LOTV, "Ulnar", SC2Race.ZERG, MissionPools.HARD, "ap_harbinger_of_oblivion", MissionFlag.Zerg|MissionFlag.Countdown|MissionFlag.VsTP|MissionFlag.AiZergAlly|MissionFlag.RaceSwap + UNSEALING_THE_PAST_T = 210, "Unsealing the Past (Terran)", SC2Campaign.LOTV, "Purifier", SC2Race.TERRAN, MissionPools.HARD, "ap_unsealing_the_past", MissionFlag.Terran|MissionFlag.AutoScroller|MissionFlag.VsZerg|MissionFlag.RaceSwap + UNSEALING_THE_PAST_Z = 211, "Unsealing the Past (Zerg)", SC2Campaign.LOTV, "Purifier", SC2Race.ZERG, MissionPools.HARD, "ap_unsealing_the_past", MissionFlag.Zerg|MissionFlag.AutoScroller|MissionFlag.VsZerg|MissionFlag.RaceSwap + PURIFICATION_T = 212, "Purification (Terran)", SC2Campaign.LOTV, "Purifier", SC2Race.TERRAN, MissionPools.HARD, "ap_purification", MissionFlag.Terran|MissionFlag.VsZerg|MissionFlag.RaceSwap + PURIFICATION_Z = 213, "Purification (Zerg)", SC2Campaign.LOTV, "Purifier", SC2Race.ZERG, MissionPools.HARD, "ap_purification", MissionFlag.Zerg|MissionFlag.VsZerg|MissionFlag.RaceSwap + STEPS_OF_THE_RITE_T = 214, "Steps of the Rite (Terran)", SC2Campaign.LOTV, "Tal'darim", SC2Race.TERRAN, MissionPools.HARD, "ap_steps_of_the_rite", MissionFlag.Terran|MissionFlag.VsProtoss|MissionFlag.RaceSwap + STEPS_OF_THE_RITE_Z = 215, "Steps of the Rite (Zerg)", SC2Campaign.LOTV, "Tal'darim", SC2Race.ZERG, MissionPools.HARD, "ap_steps_of_the_rite", MissionFlag.Zerg|MissionFlag.VsProtoss|MissionFlag.RaceSwap + RAK_SHIR_T = 216, "Rak'Shir (Terran)", SC2Campaign.LOTV, "Tal'darim", SC2Race.TERRAN, MissionPools.HARD, "ap_rak_shir", MissionFlag.Terran|MissionFlag.VsProtoss|MissionFlag.RaceSwap + RAK_SHIR_Z = 217, "Rak'Shir (Zerg)", SC2Campaign.LOTV, "Tal'darim", SC2Race.ZERG, MissionPools.HARD, "ap_rak_shir", MissionFlag.Zerg|MissionFlag.VsProtoss|MissionFlag.RaceSwap + TEMPLAR_S_CHARGE_T = 218, "Templar's Charge (Terran)", SC2Campaign.LOTV, "Moebius", SC2Race.TERRAN, MissionPools.HARD, "ap_templar_s_charge", MissionFlag.Terran|MissionFlag.VsTerran|MissionFlag.RaceSwap + TEMPLAR_S_CHARGE_Z = 219, "Templar's Charge (Zerg)", SC2Campaign.LOTV, "Moebius", SC2Race.ZERG, MissionPools.HARD, "ap_templar_s_charge", MissionFlag.Zerg|MissionFlag.VsTerran|MissionFlag.RaceSwap + # 220/221 - Templar's Return + THE_HOST_T = 222, "The Host (Terran)", SC2Campaign.LOTV, "Return to Aiur", SC2Race.TERRAN, MissionPools.VERY_HARD, "ap_the_host", MissionFlag.Terran|MissionFlag.VsAll|MissionFlag.RaceSwap + THE_HOST_Z = 223, "The Host (Zerg)", SC2Campaign.LOTV, "Return to Aiur", SC2Race.ZERG, MissionPools.VERY_HARD, "ap_the_host", MissionFlag.Zerg|MissionFlag.VsAll|MissionFlag.RaceSwap + SALVATION_T = 224, "Salvation (Terran)", SC2Campaign.LOTV, "Return to Aiur", SC2Race.TERRAN, MissionPools.VERY_HARD, "ap_salvation", MissionFlag.Terran|MissionFlag.TimedDefense|MissionFlag.VsPZ|MissionFlag.AiProtossAlly|MissionFlag.RaceSwap + SALVATION_Z = 225, "Salvation (Zerg)", SC2Campaign.LOTV, "Return to Aiur", SC2Race.ZERG, MissionPools.VERY_HARD, "ap_salvation", MissionFlag.Zerg|MissionFlag.TimedDefense|MissionFlag.VsPZ|MissionFlag.AiProtossAlly|MissionFlag.RaceSwap + # 226/227 - Into the Void + # 228/229 - The Essence of Eternity + # 230/231 - Amon's Fall + # 232/233 - The Escape + # 234/235 - Sudden Strike + # 236/237 - Enemy Intelligence + # 238/239 - Trouble In Paradise + # 240/241 - Night Terrors + # 242/243 - Flashpoint + # 244/245 - In the Enemy's Shadow + # 246/247 - Dark Skies + # 248/249 - End Game + + +class MissionConnection: + campaign: SC2Campaign + connect_to: int # -1 connects to Menu + + def __init__(self, connect_to, campaign = SC2Campaign.GLOBAL): + self.campaign = campaign + self.connect_to = connect_to + + def _asdict(self): + return { + "campaign": self.campaign.id, + "connect_to": self.connect_to + } + + +class MissionInfo(NamedTuple): + mission: SC2Mission + required_world: List[Union[MissionConnection, Dict[Literal["campaign", "connect_to"], int]]] + category: str + number: int = 0 # number of worlds need beaten + completion_critical: bool = False # missions needed to beat game + or_requirements: bool = False # true if the requirements should be or-ed instead of and-ed + ui_vertical_padding: int = 0 # How many blank padding tiles go above this mission in the launcher + + + +lookup_id_to_mission: Dict[int, SC2Mission] = { + mission.id: mission for mission in SC2Mission +} + +lookup_name_to_mission: Dict[str, SC2Mission] = { + mission.mission_name: mission for mission in SC2Mission +} +for mission in SC2Mission: + if MissionFlag.HasRaceSwap in mission.flags and ' (' in mission.mission_name: + # Short names for non-race-swapped missions for client compatibility + short_name = mission.get_short_name() + lookup_name_to_mission[short_name] = mission + +lookup_id_to_campaign: Dict[int, SC2Campaign] = { + campaign.id: campaign for campaign in SC2Campaign +} + + +campaign_mission_table: Dict[SC2Campaign, Set[SC2Mission]] = { + campaign: set() for campaign in SC2Campaign +} +for mission in SC2Mission: + campaign_mission_table[mission.campaign].add(mission) + + +def get_campaign_difficulty(campaign: SC2Campaign, excluded_missions: Iterable[SC2Mission] = ()) -> MissionPools: + """ + + :param campaign: + :param excluded_missions: + :return: Campaign's the most difficult non-excluded mission + """ + excluded_mission_set = set(excluded_missions) + included_missions = campaign_mission_table[campaign].difference(excluded_mission_set) + return max([mission.pool for mission in included_missions]) + + +def get_campaign_goal_priority(campaign: SC2Campaign, excluded_missions: Iterable[SC2Mission] = ()) -> SC2CampaignGoalPriority: + """ + Gets a modified campaign goal priority. + If all the campaign's goal missions are excluded, it's ineligible to have the goal + If the campaign's very hard missions are excluded, the priority is lowered to hard + :param campaign: + :param excluded_missions: + :return: + """ + if excluded_missions is None: + return campaign.goal_priority + else: + goal_missions = set(get_campaign_potential_goal_missions(campaign)) + excluded_mission_set = set(excluded_missions) + remaining_goals = goal_missions.difference(excluded_mission_set) + if remaining_goals == set(): + # All potential goals are excluded, the campaign can't be a goal + return SC2CampaignGoalPriority.NONE + elif campaign.goal_priority == SC2CampaignGoalPriority.VERY_HARD: + # Check if a very hard campaign doesn't get rid of it's last very hard mission + difficulty = get_campaign_difficulty(campaign, excluded_missions) + if difficulty == MissionPools.VERY_HARD: + return SC2CampaignGoalPriority.VERY_HARD + else: + return SC2CampaignGoalPriority.HARD + else: + return campaign.goal_priority + + +class SC2CampaignGoal(NamedTuple): + mission: SC2Mission + location: str + + +campaign_final_mission_locations: Dict[SC2Campaign, Optional[SC2CampaignGoal]] = { + SC2Campaign.WOL: SC2CampaignGoal(SC2Mission.ALL_IN, f'{SC2Mission.ALL_IN.mission_name}: Victory'), + SC2Campaign.PROPHECY: SC2CampaignGoal(SC2Mission.IN_UTTER_DARKNESS, f'{SC2Mission.IN_UTTER_DARKNESS.mission_name}: Defeat'), + SC2Campaign.HOTS: SC2CampaignGoal(SC2Mission.THE_RECKONING, f'{SC2Mission.THE_RECKONING.mission_name}: Victory'), + SC2Campaign.PROLOGUE: SC2CampaignGoal(SC2Mission.EVIL_AWOKEN, f'{SC2Mission.EVIL_AWOKEN.mission_name}: Victory'), + SC2Campaign.LOTV: SC2CampaignGoal(SC2Mission.SALVATION, f'{SC2Mission.SALVATION.mission_name}: Victory'), + SC2Campaign.EPILOGUE: None, + SC2Campaign.NCO: SC2CampaignGoal(SC2Mission.END_GAME, f'{SC2Mission.END_GAME.mission_name}: Victory'), +} + +campaign_alt_final_mission_locations: Dict[SC2Campaign, Dict[SC2Mission, str]] = { + SC2Campaign.WOL: { + SC2Mission.MAW_OF_THE_VOID: f'{SC2Mission.MAW_OF_THE_VOID.mission_name}: Victory', + SC2Mission.ENGINE_OF_DESTRUCTION: f'{SC2Mission.ENGINE_OF_DESTRUCTION.mission_name}: Victory', + SC2Mission.SUPERNOVA: f'{SC2Mission.SUPERNOVA.mission_name}: Victory', + SC2Mission.GATES_OF_HELL: f'{SC2Mission.GATES_OF_HELL.mission_name}: Victory', + SC2Mission.SHATTER_THE_SKY: f'{SC2Mission.SHATTER_THE_SKY.mission_name}: Victory', + + SC2Mission.MAW_OF_THE_VOID_Z: f'{SC2Mission.MAW_OF_THE_VOID_Z.mission_name}: Victory', + SC2Mission.ENGINE_OF_DESTRUCTION_Z: f'{SC2Mission.ENGINE_OF_DESTRUCTION_Z.mission_name}: Victory', + SC2Mission.SUPERNOVA_Z: f'{SC2Mission.SUPERNOVA_Z.mission_name}: Victory', + SC2Mission.GATES_OF_HELL_Z: f'{SC2Mission.GATES_OF_HELL_Z.mission_name}: Victory', + SC2Mission.SHATTER_THE_SKY_Z: f'{SC2Mission.SHATTER_THE_SKY_Z.mission_name}: Victory', + + SC2Mission.MAW_OF_THE_VOID_P: f'{SC2Mission.MAW_OF_THE_VOID_P.mission_name}: Victory', + SC2Mission.ENGINE_OF_DESTRUCTION_P: f'{SC2Mission.ENGINE_OF_DESTRUCTION_P.mission_name}: Victory', + SC2Mission.SUPERNOVA_P: f'{SC2Mission.SUPERNOVA_P.mission_name}: Victory', + SC2Mission.GATES_OF_HELL_P: f'{SC2Mission.GATES_OF_HELL_P.mission_name}: Victory', + SC2Mission.SHATTER_THE_SKY_P: f'{SC2Mission.SHATTER_THE_SKY_P.mission_name}: Victory' + }, + SC2Campaign.PROPHECY: {}, + SC2Campaign.HOTS: { + SC2Mission.THE_CRUCIBLE: f'{SC2Mission.THE_CRUCIBLE.mission_name}: Victory', + SC2Mission.HAND_OF_DARKNESS: f'{SC2Mission.HAND_OF_DARKNESS.mission_name}: Victory', + SC2Mission.PHANTOMS_OF_THE_VOID: f'{SC2Mission.PHANTOMS_OF_THE_VOID.mission_name}: Victory', + SC2Mission.PLANETFALL: f'{SC2Mission.PLANETFALL.mission_name}: Victory', + SC2Mission.DEATH_FROM_ABOVE: f'{SC2Mission.DEATH_FROM_ABOVE.mission_name}: Victory', + + SC2Mission.THE_CRUCIBLE_T: f'{SC2Mission.THE_CRUCIBLE_T.mission_name}: Victory', + SC2Mission.HAND_OF_DARKNESS_T: f'{SC2Mission.HAND_OF_DARKNESS_T.mission_name}: Victory', + SC2Mission.PHANTOMS_OF_THE_VOID_T: f'{SC2Mission.PHANTOMS_OF_THE_VOID_T.mission_name}: Victory', + SC2Mission.PLANETFALL_T: f'{SC2Mission.PLANETFALL_T.mission_name}: Victory', + SC2Mission.DEATH_FROM_ABOVE_T: f'{SC2Mission.DEATH_FROM_ABOVE_T.mission_name}: Victory', + + SC2Mission.THE_CRUCIBLE_P: f'{SC2Mission.THE_CRUCIBLE_P.mission_name}: Victory', + SC2Mission.HAND_OF_DARKNESS_P: f'{SC2Mission.HAND_OF_DARKNESS_P.mission_name}: Victory', + SC2Mission.PHANTOMS_OF_THE_VOID_P: f'{SC2Mission.PHANTOMS_OF_THE_VOID_P.mission_name}: Victory', + SC2Mission.PLANETFALL_P: f'{SC2Mission.PLANETFALL_P.mission_name}: Victory', + SC2Mission.DEATH_FROM_ABOVE_P: f'{SC2Mission.DEATH_FROM_ABOVE_P.mission_name}: Victory' + }, + SC2Campaign.PROLOGUE: { + SC2Mission.GHOSTS_IN_THE_FOG: f'{SC2Mission.GHOSTS_IN_THE_FOG.mission_name}: Victory', + SC2Mission.GHOSTS_IN_THE_FOG_T: f'{SC2Mission.GHOSTS_IN_THE_FOG_T.mission_name}: Victory', + SC2Mission.GHOSTS_IN_THE_FOG_Z: f'{SC2Mission.GHOSTS_IN_THE_FOG_Z.mission_name}: Victory' + }, + SC2Campaign.LOTV: { + SC2Mission.THE_HOST: f'{SC2Mission.THE_HOST.mission_name}: Victory', + SC2Mission.TEMPLAR_S_CHARGE: f'{SC2Mission.TEMPLAR_S_CHARGE.mission_name}: Victory', + + SC2Mission.THE_HOST_T: f'{SC2Mission.THE_HOST_T.mission_name}: Victory', + SC2Mission.TEMPLAR_S_CHARGE_T: f'{SC2Mission.TEMPLAR_S_CHARGE_T.mission_name}: Victory', + + SC2Mission.THE_HOST_Z: f'{SC2Mission.THE_HOST_Z.mission_name}: Victory', + SC2Mission.TEMPLAR_S_CHARGE_Z: f'{SC2Mission.TEMPLAR_S_CHARGE_Z.mission_name}: Victory' + }, + SC2Campaign.EPILOGUE: { + SC2Mission.AMON_S_FALL: f'{SC2Mission.AMON_S_FALL.mission_name}: Victory', + SC2Mission.INTO_THE_VOID: f'{SC2Mission.INTO_THE_VOID.mission_name}: Victory', + SC2Mission.THE_ESSENCE_OF_ETERNITY: f'{SC2Mission.THE_ESSENCE_OF_ETERNITY.mission_name}: Victory', + }, + SC2Campaign.NCO: { + SC2Mission.FLASHPOINT: f'{SC2Mission.FLASHPOINT.mission_name}: Victory', + SC2Mission.DARK_SKIES: f'{SC2Mission.DARK_SKIES.mission_name}: Victory', + SC2Mission.NIGHT_TERRORS: f'{SC2Mission.NIGHT_TERRORS.mission_name}: Victory', + SC2Mission.TROUBLE_IN_PARADISE: f'{SC2Mission.TROUBLE_IN_PARADISE.mission_name}: Victory' + } +} + +campaign_race_exceptions: Dict[SC2Mission, SC2Race] = { + SC2Mission.WITH_FRIENDS_LIKE_THESE: SC2Race.TERRAN +} + + +def get_goal_location(mission: SC2Mission) -> Union[str, None]: + """ + + :param mission: + :return: Goal location assigned to the goal mission + """ + campaign = mission.campaign + primary_campaign_goal = campaign_final_mission_locations[campaign] + if primary_campaign_goal is not None: + if primary_campaign_goal.mission == mission: + return primary_campaign_goal.location + + campaign_alt_goals = campaign_alt_final_mission_locations[campaign] + if mission in campaign_alt_goals: + return campaign_alt_goals.get(mission) + + return (mission.mission_name + ": Defeat") \ + if mission in [SC2Mission.IN_UTTER_DARKNESS, SC2Mission.IN_UTTER_DARKNESS_T, SC2Mission.IN_UTTER_DARKNESS_Z] \ + else mission.mission_name + ": Victory" + + +def get_campaign_potential_goal_missions(campaign: SC2Campaign) -> List[SC2Mission]: + """ + + :param campaign: + :return: All missions that can be the campaign's goal + """ + missions: List[SC2Mission] = list() + primary_goal_mission = campaign_final_mission_locations[campaign] + if primary_goal_mission is not None: + missions.append(primary_goal_mission.mission) + alt_goal_locations = campaign_alt_final_mission_locations[campaign] + if alt_goal_locations: + for mission in alt_goal_locations.keys(): + missions.append(mission) + + return missions + + +def get_missions_with_any_flags_in_list(flags: MissionFlag) -> List[SC2Mission]: + return [mission for mission in SC2Mission if flags & mission.flags] diff --git a/worlds/sc2/options.py b/worlds/sc2/options.py new file mode 100644 index 000000000000..08be7e187a35 --- /dev/null +++ b/worlds/sc2/options.py @@ -0,0 +1,1746 @@ +import functools +from dataclasses import fields, Field, dataclass +from typing import * +from datetime import timedelta + +from Options import ( + Choice, Toggle, DefaultOnToggle, OptionSet, Range, + PerGameCommonOptions, Option, VerifyKeys, StartInventory, + is_iterable_except_str, OptionGroup, Visibility, ItemDict +) +from Utils import get_fuzzy_results +from BaseClasses import PlandoOptions +from .item import item_names, item_tables +from .item.item_groups import kerrigan_active_abilities, kerrigan_passives, nova_weapons, nova_gadgets +from .mission_tables import ( + SC2Campaign, SC2Mission, lookup_name_to_mission, MissionPools, get_missions_with_any_flags_in_list, + campaign_mission_table, SC2Race, MissionFlag +) +from .mission_groups import mission_groups, MissionGroupNames +from .mission_order.options import CustomMissionOrder + +if TYPE_CHECKING: + from worlds.AutoWorld import World + from . import SC2World + + +class Sc2MissionSet(OptionSet): + """Option set made for handling missions and expanding mission groups""" + valid_keys: Iterable[str] = [x.mission_name for x in SC2Mission] + + @classmethod + def from_any(cls, data: Any): + if is_iterable_except_str(data): + return cls(data) + return cls.from_text(str(data)) + + def verify(self, world: Type['World'], player_name: str, plando_options: PlandoOptions) -> None: + """Overridden version of function from Options.VerifyKeys for a better error message""" + new_value: set[str] = set() + case_insensitive_group_mapping = { + group_name.casefold(): group_value for group_name, group_value in mission_groups.items() + } + case_insensitive_group_mapping.update({mission.mission_name.casefold(): [mission.mission_name] for mission in SC2Mission}) + for group_name in self.value: + item_names = case_insensitive_group_mapping.get(group_name.casefold(), {group_name}) + new_value.update(item_names) + self.value = new_value + for item_name in self.value: + if item_name not in self.valid_keys: + picks = get_fuzzy_results( + item_name, + list(self.valid_keys) + list(MissionGroupNames.get_all_group_names()), + limit=1, + ) + raise Exception(f"Mission {item_name} from option {self} " + f"is not a valid mission name from {world.game}. " + f"Did you mean '{picks[0][0]}' ({picks[0][1]}% sure)") + + def __iter__(self) -> Iterator[str]: + return self.value.__iter__() + + def __len__(self) -> int: + return self.value.__len__() + + +class SelectRaces(OptionSet): + """ + Pick which factions' missions and items can be shuffled into the world. + """ + display_name = "Select Playable Races" + valid_keys = {race.get_title() for race in SC2Race if race != SC2Race.ANY} + default = valid_keys + + +class GameDifficulty(Choice): + """ + The difficulty of the campaign, affects enemy AI, starting units, and game speed. + + For those unfamiliar with the Archipelago randomizer, the recommended settings are one difficulty level + lower than the vanilla game + """ + display_name = "Game Difficulty" + option_casual = 0 + option_normal = 1 + option_hard = 2 + option_brutal = 3 + default = 1 + + +class DifficultyDamageModifier(DefaultOnToggle): + """ + Enables or disables vanilla difficulty-based damage received modifier + Handles the 1.25 Brutal damage modifier in HotS and Prologue and 0.5 Casual damage modifier outside WoL and Prophecy + """ + display_name = "Difficulty Damage Modifier" + + +class GameSpeed(Choice): + """Optional setting to override difficulty-based game speed.""" + display_name = "Game Speed" + option_default = 0 + option_slower = 1 + option_slow = 2 + option_normal = 3 + option_fast = 4 + option_faster = 5 + default = option_default + + +class DisableForcedCamera(DefaultOnToggle): + """ + Prevents the game from moving or locking the camera without the player's consent. + """ + display_name = "Disable Forced Camera Movement" + + +class SkipCutscenes(Toggle): + """ + Skips all cutscenes and prevents dialog from blocking progress. + """ + display_name = "Skip Cutscenes" + + +class AllInMap(Choice): + """Determines what version of All-In (WoL final map) that will be generated for the campaign.""" + display_name = "All In Map" + option_ground = 0 + option_air = 1 + default = 'random' + + +class MissionOrder(Choice): + """ + Determines the order the missions are played in. The first three mission orders ignore the Maximum Campaign Size option. + Vanilla (83 total if all campaigns enabled): Keeps the standard mission order and branching from the vanilla Campaigns. + Vanilla Shuffled (83 total if all campaigns enabled): Keeps same branching paths from the vanilla Campaigns but randomizes the order of missions within. + Mini Campaign (47 total if all campaigns enabled): Shorter version of the campaign with randomized missions and optional branches. + Blitz: Missions are divided into sets. Complete one mission from a set to advance to the next set. + Gauntlet: A linear path of missions to complete the campaign. + Grid: Missions are arranged into a grid. Completing a mission unlocks the adjacent missions. Corners may be omitted to make the grid more square. Complete the bottom-right mission to win. + Golden Path: A required line of missions with several optional branches, similar to the Wings of Liberty campaign. + Hopscotch: Missions alternate between mandatory missions and pairs of optional missions. + Custom: Uses the YAML's custom mission order option. See documentation for usage. + """ + display_name = "Mission Order" + option_vanilla = 0 + option_vanilla_shuffled = 1 + option_mini_campaign = 2 + option_blitz = 5 + option_gauntlet = 6 + option_grid = 9 + option_golden_path = 10 + option_hopscotch = 11 + option_custom = 99 + + +class MaximumCampaignSize(Range): + """ + Sets an upper bound on how many missions to include when a variable-size mission order is selected. + If a set-size mission order is selected, does nothing. + """ + display_name = "Maximum Campaign Size" + range_start = 1 + range_end = len(SC2Mission) + default = 83 + + +class TwoStartPositions(Toggle): + """ + If turned on and 'grid', 'hopscotch', or 'golden_path' mission orders are selected, + removes the first mission and allows both of the next two missions to be played from the start. + """ + display_name = "Start with two unlocked missions on grid" + default = Toggle.option_false + + +class KeyMode(Choice): + """ + Optionally creates Key items that must be found in the multiworld to unlock parts of the mission order, + in addition to any regular requirements a mission may have. + + "Questline" options will only work for Vanilla, Vanilla Shuffled, Mini Campaign, and Golden Path mission orders. + + Disabled: Don't create any keys. + Questlines: Create keys for questlines besides the starter ones, eg. "Colonist (Wings of Liberty) Questline Key". + Missions: Create keys for missions besides the starter ones, eg. "Zero Hour Mission Key". + Progressive Questlines: Create one type of progressive key for questlines within each campaign, eg. "Progressive Key #1". + Progressive Missions: Create one type of progressive key for all missions, "Progressive Mission Key". + Progressive Per Questline: All questlines besides the starter ones get a unique progressive key for their missions, eg. "Progressive Key #1". + """ + display_name = "Key Mode" + option_disabled = 0 + option_questlines = 1 + option_missions = 2 + option_progressive_questlines = 3 + option_progressive_missions = 4 + option_progressive_per_questline = 5 + default = option_disabled + + +class ColorChoice(Choice): + option_white = 0 + option_red = 1 + option_blue = 2 + option_teal = 3 + option_purple = 4 + option_yellow = 5 + option_orange = 6 + option_green = 7 + option_light_pink = 8 + option_violet = 9 + option_light_grey = 10 + option_dark_green = 11 + option_brown = 12 + option_light_green = 13 + option_dark_grey = 14 + option_pink = 15 + option_rainbow = 16 + option_mengsk = 17 + option_bright_lime = 18 + option_arcane = 19 + option_ember = 20 + option_hot_pink = 21 + option_default = 22 + default = option_default + + +class PlayerColorTerranRaynor(ColorChoice): + """Determines in-game player team color in Wings of Liberty missions.""" + display_name = "Terran Player Color (Raynor)" + + +class PlayerColorProtoss(ColorChoice): + """Determines in-game player team color in Legacy of the Void missions.""" + display_name = "Protoss Player Color" + + +class PlayerColorZerg(ColorChoice): + """Determines in-game player team color in Heart of the Swarm missions before unlocking Primal Kerrigan.""" + display_name = "Zerg Player Color" + + +class PlayerColorZergPrimal(ColorChoice): + """Determines in-game player team color in Heart of the Swarm after unlocking Primal Kerrigan.""" + display_name = "Zerg Player Color (Primal)" + + +class PlayerColorNova(ColorChoice): + """Determines in-game player team color in Nova Covert Ops missions.""" + display_name = "Terran Player Color (Nova)" + + +class EnabledCampaigns(OptionSet): + """Determines which campaign's missions will be used""" + display_name = "Enabled Campaigns" + valid_keys = {campaign.campaign_name for campaign in SC2Campaign if campaign != SC2Campaign.GLOBAL} + default = valid_keys + + +class EnableRaceSwapVariants(Choice): + """ + Allow mission variants where you play a faction other than the one the map was initially + designed for. NOTE: Cutscenes are always skipped on race-swapped mission variants. + + Disabled: Don't shuffle any non-vanilla map variants into the pool. + Pick One: Shuffle up to 1 valid version of each map into the pool, depending on other settings. + Pick One Non-Vanilla: Shuffle up to 1 valid version other than the original one of each map into the pool, depending on other settings. + Shuffle All: Each version of a map can appear in the same pool (so a map can appear up to 3 times as different races) + Shuffle All Non-Vanilla: Each version of a map besides the original can appear in the same pool (so a map can appear up to 2 times as different races) + """ + display_name = "Enable Race-Swapped Mission Variants" + option_disabled = 0 + option_pick_one = 1 + option_pick_one_non_vanilla = 2 + option_shuffle_all = 3 + option_shuffle_all_non_vanilla = 4 + default = option_disabled + + +class EnableMissionRaceBalancing(Choice): + """ + If enabled, picks missions in such a way that the appearance rate of races is roughly equal. + The final rates may deviate if there are not enough missions enabled to accommodate each race. + + Disabled: Pick missions at random. + Semi Balanced: Use a weighting system to pick missions in a random, but roughly equal ratio. + Fully Balanced: Pick missions to preserve equal race counts whenever possible. + """ + display_name = "Enable Mission Race Balancing" + option_disabled = 0 + option_semi_balanced = 1 + option_fully_balanced = 2 + default = option_semi_balanced + + +class ShuffleCampaigns(DefaultOnToggle): + """ + Shuffles the missions between campaigns if enabled. + Only available for Vanilla Shuffled and Mini Campaign mission order + """ + display_name = "Shuffle Campaigns" + + +class ShuffleNoBuild(DefaultOnToggle): + """ + Determines if the no-build missions are included in the shuffle. + If turned off, the no-build missions will not appear. Has no effect for Vanilla mission order. + """ + display_name = "Shuffle No-Build Missions" + + +class StarterUnit(Choice): + """ + Unlocks a random unit at the start of the game. + + Off: No units are provided, the first unit must be obtained from the randomizer + Balanced: A unit that doesn't give the player too much power early on is given + Any Starter Unit: Any starter unit can be given + """ + display_name = "Starter Unit" + option_off = 0 + option_balanced = 1 + option_any_starter_unit = 2 + + +class RequiredTactics(Choice): + """ + Determines the maximum tactical difficulty of the world (separate from mission difficulty). + Higher settings increase randomness. + + Standard: All missions can be completed with good micro and macro. + Advanced: Completing missions may require relying on starting units and micro-heavy units. + Any Units: Logic guarantees faction-appropriate units appear early without regard to what those units are. + i.e. if the third mission is a protoss build mission, + logic guarantees at least 2 protoss units are reachable before starting it. + May render the run impossible on harder difficulties. + No Logic: Units and upgrades may be placed anywhere. LIKELY TO RENDER THE RUN IMPOSSIBLE ON HARDER DIFFICULTIES! + Locks Grant Story Tech option to true. + """ + display_name = "Required Tactics" + option_standard = 0 + option_advanced = 1 + option_any_units = 2 + option_no_logic = 3 + + +class EnableVoidTrade(Toggle): + """ + Enables the Void Trade Wormhole to be built from the Advanced Construction tab of SCVs, Drones and Probes. + This structure allows sending units to the Archipelago server, as well as buying random units from the server. + + Note: Always disabled if there is no other Starcraft II world with Void Trade enabled in the multiworld. You cannot receive units that you send. + """ + display_name = "Enable Void Trade" + + +class VoidTradeAgeLimit(Choice): + """ + Determines the maximum allowed age for units you can receive from Void Trade. + Units that are older than your choice will still be available to other players, but not to you. + + This does not put a time limit on units you send to other players. Your own units are only affected by other players' choices for this option. + """ + display_name = "Void Trade Age Limit" + option_disabled = 0 + option_1_week = 1 + option_1_day = 2 + option_4_hours = 3 + option_2_hours = 4 + option_1_hour = 5 + option_30_minutes = 6 + option_5_minutes = 7 + default = option_30_minutes + + +class VoidTradeWorkers(Toggle): + """ + If enabled, you are able to send and receive workers via Void Trade. + + Sending workers is a cheap way to get a lot of units from other players, + at the cost of reducing the strength of received units for other players. + + Receiving workers allows you to build units of other races, but potentially skips large parts of your multiworld progression. + """ + display_name = "Allow Workers in Void Trade" + + +class MaxUpgradeLevel(Range): + """Controls the maximum number of weapon/armor upgrades that can be found or unlocked.""" + display_name = "Maximum Upgrade Level" + range_start = 3 + range_end = 5 + default = 3 + + +class GenericUpgradeMissions(Range): + """ + Determines the percentage of missions in the mission order that must be completed before + level 1 of all weapon and armor upgrades is unlocked. Level 2 upgrades require double the amount of missions, + and level 3 requires triple the amount. The required amounts are always rounded down. + If set to 0, upgrades are instead added to the item pool and must be found to be used. + + If the mission order is unable to be beaten by this value (if above 0), the generator will place additional + weapon / armor upgrades into start inventory + """ + display_name = "Generic Upgrade Missions" + range_start = 0 + range_end = 100 # Higher values lead to fails often + default = 0 + + +class GenericUpgradeResearch(Choice): + """Determines how weapon and armor upgrades affect missions once unlocked. + + Vanilla: Upgrades must be researched as normal. + Auto In No-Build: In No-Build missions, upgrades are automatically researched. + In all other missions, upgrades must be researched as normal. + Auto In Build: In No-Build missions, upgrades are unavailable as normal. + In all other missions, upgrades are automatically researched. + Always Auto: Upgrades are automatically researched in all missions.""" + display_name = "Generic Upgrade Research" + option_vanilla = 0 + option_auto_in_no_build = 1 + option_auto_in_build = 2 + option_always_auto = 3 + + +class GenericUpgradeResearchSpeedup(Toggle): + """ + If turned on, the weapon and armor upgrades are researched more quickly if level 4 or higher is unlocked. + The research times of upgrades are cut proportionally, so you're able to hit the maximum available level + at the same time, as you'd hit level 3 normally. + + Turning this on will help you to be able to research level 4 or 5 upgrade levels in timed missions. + + Has no effect if Maximum Upgrade Level is set to 3 + or Generic Upgrade Research doesn't require you to research upgrades in build missions. + """ + display_name = "Generic Upgrade Research Speedup" + + +class GenericUpgradeItems(Choice): + """Determines how weapon and armor upgrades are split into items. + + All options produce a number of levels of each item equal to the Maximum Upgrade Level. + The examples below consider a Maximum Upgrade Level of 3. + + Does nothing if upgrades are unlocked by completed mission counts. + + Individual Items: All weapon and armor upgrades are each an item, + resulting in 18 total upgrade items for Terran and 15 total items for Zerg and Protoss each. + Bundle Weapon And Armor: All types of weapon upgrades are one item per race, + and all types of armor upgrades are one item per race, + resulting in 18 total items. + Bundle Unit Class: Weapon and armor upgrades are merged, + but upgrades are bundled separately for each race: + Infantry, Vehicle, and Starship upgrades for Terran (9 items), + Ground and Flyer upgrades for Zerg (6 items), + Ground and Air upgrades for Protoss (6 items), + resulting in 21 total items. + Bundle All: All weapon and armor upgrades are one item per race, + resulting in 9 total items.""" + display_name = "Generic Upgrade Items" + option_individual_items = 0 + option_bundle_weapon_and_armor = 1 + option_bundle_unit_class = 2 + option_bundle_all = 3 + + +class VanillaItemsOnly(Toggle): + """If turned on, the item pool is limited only to items that appear in the main 3 vanilla campaigns. + Weapon/Armor upgrades are unaffected; use max_upgrade_level to control maximum level. + Locked Items may override these exclusions.""" + display_name = "Vanilla Items Only" + + +class ExcludeOverpoweredItems(Toggle): + """ + If turned on, a curated list of very strong items are excluded. + These items were selected for promoting repetitive strategies, or for providing a lot of power in a boring way. + Recommended off for players looking for a challenge or for repeat playthroughs. + Excluding an OP item overrides the exclusion from this item rather than add to it. + OP items may be unexcluded or locked with Unexcluded Items or Locked Items options. + Enabling this can force a unit nerf even if Allow Unit Nerfs is set to false for some units. + """ + display_name = "Exclude Overpowered Items" + + +# Current maximum number of upgrades for a unit +MAX_UPGRADES_OPTION = 13 + + +class EnsureGenericItems(Range): + """ + Specifies a minimum percentage of the generic item pool that will be present for the slot. + The generic item pool is the pool of all generically useful items after all exclusions. + Generically-useful items include: Worker upgrades, Building upgrades, economy upgrades, + Mercenaries, Kerrigan levels and abilities, and Spear of Adun abilities + Increasing this percentage will make units less common. + """ + display_name = "Ensure Generic Items" + range_start = 0 + range_end = 100 + default = 25 + + +class MinNumberOfUpgrades(Range): + """ + Set a minimum to the number of upgrade items a unit/structure can have. + Note that most units have 4 to 6 upgrades. + If a unit has fewer upgrades than the minimum, it will have all of its upgrades. + + Doesn't affect shared unit upgrades. + """ + display_name = "Minimum number of upgrades per unit/structure" + range_start = 0 + range_end = MAX_UPGRADES_OPTION + default = 2 + + +class MaxNumberOfUpgrades(Range): + """ + Set a maximum to the number of upgrade items a unit/structure can have. + -1 is used to define unlimited. + Note that most units have 4 to 6 upgrades. + + Doesn't affect shared unit upgrades. + """ + display_name = "Maximum number of upgrades per unit/structure" + range_start = -1 + range_end = MAX_UPGRADES_OPTION + default = -1 + + +class MercenaryHighlanders(DefaultOnToggle): + """ + If enabled, it limits the controllable amount of certain mercenaries to 1, even if you have unlimited mercenaries upgrade. + With this upgrade you can still call the mercenary again if it dies. + + Affected mercenaries: Jackson's Revenge (Battlecruiser), Wise Old Torrasque (Ultralisk) + """ + display_name = "Mercenary Highlanders" + + +class KerriganPresence(Choice): + """ + Determines whether Kerrigan is playable outside of missions that require her. + + Vanilla: Kerrigan is playable as normal, appears in the same missions as in vanilla game. + Not Present: Kerrigan is not playable, unless the mission requires her to be present. Other hero units stay playable, + and locations normally requiring Kerrigan can be checked by any unit. + Kerrigan level items, active abilities and passive abilities affecting her will not appear. + In missions where the Kerrigan unit is required, story abilities are given in same way as Grant Story Tech is set to true + + Note: Always set to "Not Present" if Heart of the Swarm campaign is disabled. + """ + display_name = "Kerrigan Presence" + option_vanilla = 0 + option_not_present = 1 + + +class KerriganLevelsPerMissionCompleted(Range): + """ + Determines how many levels Kerrigan gains when a mission is beaten. + """ + display_name = "Levels Per Mission Beaten" + range_start = 0 + range_end = 20 + default = 0 + + +class KerriganLevelsPerMissionCompletedCap(Range): + """ + Limits how many total levels Kerrigan can gain from beating missions. This does not affect levels gained from items. + Set to -1 to disable this limit. + + NOTE: The following missions have these level requirements: + Supreme: 35 + The Infinite Cycle: 70 + See Grant Story Levels for more details. + """ + display_name = "Levels Per Mission Beaten Cap" + range_start = -1 + range_end = 140 + default = -1 + + +class KerriganLevelItemSum(Range): + """ + Determines the sum of the level items in the world. This does not affect levels gained from beating missions. + + NOTE: The following missions have these level requirements: + Supreme: 35 + The Infinite Cycle: 70 + See Grant Story Levels for more details. + """ + display_name = "Kerrigan Level Item Sum" + range_start = 0 + range_end = 140 + default = 70 + + +class KerriganLevelItemDistribution(Choice): + """Determines the amount and size of Kerrigan level items. + + Vanilla: Uses the distribution in the vanilla campaign. + This entails 32 individual levels and 6 packs of varying sizes. + This distribution always adds up to 70, ignoring the Level Item Sum setting. + Smooth: Uses a custom, condensed distribution of 10 items between sizes 4 and 10, + intended to fit more levels into settings with little room for filler while keeping some variance in level gains. + This distribution always adds up to 70, ignoring the Level Item Sum setting. + Size 70: Uses items worth 70 levels each. + Size 35: Uses items worth 35 levels each. + Size 14: Uses items worth 14 levels each. + Size 10: Uses items worth 10 levels each. + Size 7: Uses items worth 7 levels each. + Size 5: Uses items worth 5 levels each. + Size 2: Uses items worth 2 level eachs. + Size 1: Uses individual levels. As there are not enough locations in the game for this distribution, + this will result in a greatly reduced total level, and is likely to remove many other items.""" + display_name = "Kerrigan Level Item Distribution" + option_vanilla = 0 + option_smooth = 1 + option_size_70 = 2 + option_size_35 = 3 + option_size_14 = 4 + option_size_10 = 5 + option_size_7 = 6 + option_size_5 = 7 + option_size_2 = 8 + option_size_1 = 9 + default = option_smooth + + +class KerriganTotalLevelCap(Range): + """ + Limits how many total levels Kerrigan can gain from any source. + Depending on your other settings, there may be more levels available in the world, + but they will not affect Kerrigan. + Set to -1 to disable this limit. + + NOTE: The following missions have these level requirements: + Supreme: 35 + The Infinite Cycle: 70 + See Grant Story Levels for more details. + """ + display_name = "Total Level Cap" + range_start = -1 + range_end = 140 + default = -1 + + +class StartPrimaryAbilities(Range): + """Number of Primary Abilities (Kerrigan Tier 1, 2, and 4) to start the game with. + If set to 4, a Tier 7 ability is also included.""" + display_name = "Starting Primary Abilities" + range_start = 0 + range_end = 4 + default = 0 + + +class KerriganPrimalStatus(Choice): + """Determines when Kerrigan appears in her Primal Zerg form. + This greatly increases her energy regeneration. + + Vanilla: Kerrigan is human in missions that canonically appear before The Crucible, + and zerg thereafter. + Always Zerg: Kerrigan is always zerg. + Always Human: Kerrigan is always human. + Level 35: Kerrigan is human until reaching level 35, and zerg thereafter. + Half Completion: Kerrigan is human until half of the missions in the world are completed, + and zerg thereafter. + Item: Kerrigan's Primal Form is an item. She is human until it is found, and zerg thereafter.""" + display_name = "Kerrigan Primal Status" + option_vanilla = 0 + option_always_zerg = 1 + option_always_human = 2 + option_level_35 = 3 + option_half_completion = 4 + option_item = 5 + + +class KerriganMaxActiveAbilities(Range): + """ + Determines the maximum number of Kerrigan active abilities that can be present in the game + Additional abilities may spawn if those are required to beat the game. + """ + display_name = "Kerrigan Maximum Active Abilities" + range_start = 0 + range_end = len(kerrigan_active_abilities) + default = range_end + + +class KerriganMaxPassiveAbilities(Range): + """ + Determines the maximum number of Kerrigan passive abilities that can be present in the game + Additional abilities may spawn if those are required to beat the game. + """ + display_name = "Kerrigan Maximum Passive Abilities" + range_start = 0 + range_end = len(kerrigan_passives) + default = range_end + + +class EnableMorphling(Toggle): + """ + Determines whether the player can build Morphlings, which allow for inefficient morphing of advanced units + like Ravagers and Lurkers without requiring the base unit to be unlocked first. + """ + display_name = "Enable Morphling" + + +class WarCouncilNerfs(Toggle): + """ + Controls whether most Protoss units can initially be found in a nerfed state, with upgrades restoring their stronger power level. + For example, nerfed Zealots will lack the whirlwind upgrade until it is found as an item. + """ + display_name = "Allow Unit Nerfs" + + +class SpearOfAdunPresence(Choice): + """ + Determines in which missions Spear of Adun calldowns will be available. + Affects only abilities used from Spear of Adun top menu. + + Not Present: Spear of Adun calldowns are unavailable. + Vanilla: Spear of Adun calldowns are only available where they appear in the basegame (Protoss missions after The Growing Shadow) + Protoss: Spear of Adun calldowns are available in any Protoss mission + Everywhere: Spear of Adun calldowns are available in any mission of any race + Any Race LotV: Spear of Adun calldowns are available in any race-swapped variant of a LotV mission + """ + display_name = "Spear of Adun Presence" + option_not_present = 0 + option_vanilla = 4 + option_protoss = 2 + option_everywhere = 3 + option_any_race_lotv = 1 + default = option_vanilla + + # Fix case + @classmethod + def get_option_name(cls, value: int) -> str: + if value == SpearOfAdunPresence.option_any_race_lotv: + return "Any Race LotV" + else: + return super().get_option_name(value) + + +class SpearOfAdunPresentInNoBuild(Toggle): + """ + Determines if Spear of Adun calldowns are available in no-build missions. + + If turned on, Spear of Adun calldown powers are available in missions specified under "Spear of Adun Presence". + If turned off, Spear of Adun calldown powers are unavailable in all no-build missions + """ + display_name = "Spear of Adun Present in No-Build" + + +class SpearOfAdunPassiveAbilityPresence(Choice): + """ + Determines availability of Spear of Adun passive powers. + Affects abilities like Reconstruction Beam or Overwatch. + Does not affect building abilities like Orbital Assimilators or Warp Harmonization. + + Not Present: Autocasts are not available. + Vanilla: Spear of Adun calldowns are only available where it appears in the basegame (Protoss missions after The Growing Shadow) + Protoss: Spear of Adun autocasts are available in any Protoss mission + Everywhere: Spear of Adun autocasts are available in any mission of any race + Any Race LotV: Spear of Adun autocasts are available in any race-swapped variant of a LotV mission + """ + display_name = "Spear of Adun Passive Ability Presence" + option_not_present = 0 + option_any_race_lotv = 1 + option_protoss = 2 + option_everywhere = 3 + option_vanilla = 4 + default = option_vanilla + + # Fix case + @classmethod + def get_option_name(cls, value: int) -> str: + if value == SpearOfAdunPresence.option_any_race_lotv: + return "Any Race LotV" + else: + return super().get_option_name(value) + + +class SpearOfAdunPassivesPresentInNoBuild(Toggle): + """ + Determines if Spear of Adun autocasts are available in no-build missions. + + If turned on, Spear of Adun autocasts are available in missions specified under "Spear of Adun Passive Ability Presence". + If turned off, Spear of Adun autocasts are unavailable in all no-build missions + """ + display_name = "Spear of Adun Passive Abilities Present in No-Build" + + +class SpearOfAdunMaxActiveAbilities(Range): + """ + Determines the maximum number of Spear of Adun active abilities (top bar) that can be present in the game + Additional abilities may spawn if those are required to beat the game. + + Note: Warp in Reinforcements is treated as a second level of Warp in Pylon + """ + display_name = "Spear of Adun Maximum Active Abilities" + range_start = 0 + range_end = sum([item.quantity for item_name, item in item_tables.get_full_item_list().items() if item_name in item_tables.spear_of_adun_calldowns]) + default = range_end + + +class SpearOfAdunMaxAutocastAbilities(Range): + """ + Determines the maximum number of Spear of Adun passive abilities that can be present in the game + Additional abilities may spawn if those are required to beat the game. + Does not affect building abilities like Orbital Assimilators or Warp Harmonization. + """ + display_name = "Spear of Adun Maximum Passive Abilities" + range_start = 0 + range_end = sum(item.quantity for item_name, item in item_tables.get_full_item_list().items() if item_name in item_tables.spear_of_adun_castable_passives) + default = range_end + + +class GrantStoryTech(Choice): + """ + Controls handling of no-build missions that may require very specific items, such as Kerrigan or Nova abilities. + + no_grant: don't grant anything special; the player must find items to play the missions + grant: grant a minimal inventory that will allow the player to beat the mission, in addition to other items found + allow_substitutes: Reworks the most constrained mission - Supreme - to allow other items to substitute for Leaping Strike and Mend + + Locked to "grant" if Required Tactics is set to no logic. + """ + display_name = "Grant Story Tech" + option_no_grant = 0 + option_grant = 1 + option_allow_substitutes = 2 + + +class GrantStoryLevels(Choice): + """ + If enabled, grants Kerrigan the required minimum levels for the following missions: + Supreme: 35 + The Infinite Cycle: 70 + The bonus levels only apply during the listed missions, and can exceed the Total Level Cap. + + If disabled, either of these missions is included, and there are not enough levels in the world, generation may fail. + To prevent this, either increase the amount of levels in the world, or enable this option. + + If disabled and Required Tactics is set to no logic, this option is forced to Minimum. + + Disabled: Kerrigan does not get bonus levels for these missions, + instead the levels must be gained from items or beating missions. + Additive: Kerrigan gains bonus levels equal to the mission's required level. + Minimum: Kerrigan is either at her real level, or at the mission's required level, + depending on which is higher. + """ + display_name = "Grant Story Levels" + option_disabled = 0 + option_additive = 1 + option_minimum = 2 + default = option_minimum + + +class NovaMaxWeapons(Range): + """ + Determines maximum number of Nova weapons that can be present in the game + Additional weapons may spawn if those are required to beat the game. + + Note: Nova can swap between unlocked weapons anytime during the gameplay. + """ + display_name = "Nova Maximum Weapons" + range_start = 0 + range_end = len(nova_weapons) + default = range_end + + +class NovaMaxGadgets(Range): + """ + Determines maximum number of Nova gadgets that can be present in the game. + Gadgets are a vanilla category including 2 grenade abilities, Stim, Holo Decoy, and Ionic Force Field. + Additional gadgets may spawn if those are required to beat the game. + + Note: Nova can use any unlocked ability anytime during gameplay. + """ + display_name = "Nova Maximum Gadgets" + range_start = 0 + range_end = len(nova_gadgets) + default = range_end + + +class NovaGhostOfAChanceVariant(Choice): + """ + Determines which variant of Nova should be used in Ghost of a Chance mission. + + WoL: Uses Nova from Wings of Liberty campaign (vanilla) + NCO: Uses Nova from Nova Covert Ops campaign + Auto: Uses NCO if a mission from Nova Covert Ops is actually shuffled, if not uses WoL + """ + display_name = "Nova Ghost of Chance Variant" + option_wol = 0 + option_nco = 1 + option_auto = 2 + default = option_wol + + # Fix case + @classmethod + def get_option_name(cls, value: int) -> str: + if value == NovaGhostOfAChanceVariant.option_wol: + return "WoL" + elif value == NovaGhostOfAChanceVariant.option_nco: + return "NCO" + return super().get_option_name(value) + + +class TakeOverAIAllies(Toggle): + """ + On maps supporting this feature allows you to take control over an AI Ally. + """ + display_name = "Take Over AI Allies" + + +class Sc2ItemDict(Option[Dict[str, int]], VerifyKeys, Mapping[str, int]): + """A branch of ItemDict that supports item counts of 0""" + default = {} + supports_weighting = False + verify_item_name = True + # convert_name_groups = True + display_name = 'Unnamed dictionary' + minimum_value: int = 0 + + def __init__(self, value: Dict[str, int]): + self.value = {key: val for key, val in value.items()} + + @classmethod + def from_any(cls, data: Union[List[str], Dict[str, int]]) -> 'Sc2ItemDict': + if isinstance(data, list): + # This is a little default that gets us backwards compatibility with lists. + # It doesn't play nice with trigger merging dicts and lists together, though, so best not to advertise it overmuch. + data = {item: 0 for item in data} + if isinstance(data, dict): + for key, value in data.items(): + if not isinstance(value, int): + raise ValueError(f"Invalid type in '{cls.display_name}': element '{key}' maps to '{value}', expected an integer") + if value < cls.minimum_value: + raise ValueError(f"Invalid value for '{cls.display_name}': element '{key}' maps to {value}, which is less than the minimum ({cls.minimum_value})") + return cls(data) + else: + raise NotImplementedError(f"Cannot Convert from non-dictionary, got {type(data)}") + + def verify(self, world: Type['World'], player_name: str, plando_options: PlandoOptions) -> None: + """Overridden version of function from Options.VerifyKeys for a better error message""" + new_value: dict[str, int] = {} + case_insensitive_group_mapping = { + group_name.casefold(): group_value for group_name, group_value in world.item_name_groups.items() + } + case_insensitive_group_mapping.update({item.casefold(): {item} for item in world.item_names}) + for group_name in self.value: + item_names = case_insensitive_group_mapping.get(group_name.casefold(), {group_name}) + for item_name in item_names: + new_value[item_name] = new_value.get(item_name, 0) + self.value[group_name] + self.value = new_value + for item_name in self.value: + if item_name not in world.item_names: + from .item import item_groups + picks = get_fuzzy_results( + item_name, + list(world.item_names) + list(item_groups.ItemGroupNames.get_all_group_names()), + limit=1, + ) + raise Exception(f"Item {item_name} from option {self} " + f"is not a valid item name from {world.game}. " + f"Did you mean '{picks[0][0]}' ({picks[0][1]}% sure)") + + def get_option_name(self, value): + return ", ".join(f"{key}: {v}" for key, v in value.items()) + + def __getitem__(self, item: str) -> int: + return self.value.__getitem__(item) + + def __iter__(self) -> Iterator[str]: + return self.value.__iter__() + + def __len__(self) -> int: + return self.value.__len__() + + +class Sc2StartInventory(Sc2ItemDict): + """Start with these items.""" + display_name = StartInventory.display_name + + +class LockedItems(Sc2ItemDict): + """Guarantees that these items will be unlockable, in the amount specified. + Specify an amount of 0 to lock all copies of an item.""" + display_name = "Locked Items" + + +class ExcludedItems(Sc2ItemDict): + """Guarantees that these items will not be unlockable, in the amount specified. + Specify an amount of 0 to exclude all copies of an item.""" + display_name = "Excluded Items" + + +class UnexcludedItems(Sc2ItemDict): + """Undoes an item exclusion; useful for whitelisting or fine-tuning a category. + Specify an amount of 0 to unexclude all copies of an item.""" + display_name = "Unexcluded Items" + + +class ExcludedMissions(Sc2MissionSet): + """Guarantees that these missions will not appear in the campaign + Doesn't apply to vanilla mission order. + It may be impossible to build a valid campaign if too many missions are excluded.""" + display_name = "Excluded Missions" + valid_keys = {mission.mission_name for mission in SC2Mission} + + +class DifficultyCurve(Choice): + """ + Determines whether campaign missions will be placed with a smooth difficulty curve. + Standard: The campaign will start with easy missions and end with challenging missions. Short campaigns will be more difficult. + Uneven: The campaign will start with easy missions, but easy missions can still appear later in the campaign. Short campaigns will be easier. + """ + display_name = "Difficulty Curve" + option_standard = 0 + option_uneven = 1 + + +class ExcludeVeryHardMissions(Choice): + """ + Excludes Very Hard missions outside of Epilogue campaign (All-In, The Reckoning, Salvation, and all Epilogue missions are considered Very Hard). + Doesn't apply to "Vanilla" mission order. + + Default: Not excluded for mission orders "Vanilla Shuffled" or "Grid" with Maximum Campaign Size >= 20, + excluded for any other order + Yes: Non-Epilogue Very Hard missions are excluded and won't be generated + No: Non-Epilogue Very Hard missions can appear normally. Not recommended for too short mission orders. + + See also: Excluded Missions, Enabled Campaigns, Maximum Campaign Size + """ + display_name = "Exclude Very Hard Missions" + option_default = 0 + option_true = 1 + option_false = 2 + + @classmethod + def get_option_name(cls, value): + return ["Default", "Yes", "No"][int(value)] + + +class VictoryCache(Range): + """ + Controls how many additional checks are awarded for completing a mission. + Goal missions are unaffected by this option. + """ + display_name = "Victory Checks" + range_start = 0 + range_end = 10 + default = 0 + + +class LocationInclusion(Choice): + option_enabled = 0 + option_half_chance = 3 + option_filler = 1 + option_disabled = 2 + + +class VanillaLocations(LocationInclusion): + """ + Enables or disables checks for completing vanilla objectives. + Vanilla objectives are bonus objectives from the vanilla game, + along with some additional objectives to balance the missions. + Enable these locations for a balanced experience. + + Enabled: Locations of this type give normal rewards. + Half Chance: Locations of this type have a 50% chance of being excluded. + Filler: Forces these locations to contain filler items. + Disabled: Removes item rewards from these locations. + + Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. + See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) + """ + display_name = "Vanilla Locations" + + +class ExtraLocations(LocationInclusion): + """ + Enables or disables checks for mission progress and minor objectives. + This includes mandatory mission objectives, + collecting reinforcements and resource pickups, + destroying structures, and overcoming minor challenges. + Enables these locations to add more checks and items to your world. + + Enabled: Locations of this type give normal rewards. + Half Chance: Locations of this type have a 50% chance of being excluded. + Filler: Forces these locations to contain filler items. + Disabled: Removes item rewards from these locations. + + Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. + See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) + """ + display_name = "Extra Locations" + + +class ChallengeLocations(LocationInclusion): + """ + Enables or disables checks for completing challenge tasks. + Challenges are tasks that are more difficult than completing the mission, and are often based on achievements. + You might be required to visit the same mission later after getting stronger in order to finish these tasks. + Enable these locations to increase the difficulty of completing the multiworld. + + Enabled: Locations of this type give normal rewards. + Half Chance: Locations of this type have a 50% chance of being excluded. + Filler: Forces these locations to contain filler items. + Disabled: Removes item rewards from these locations. + + Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. + See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) + """ + display_name = "Challenge Locations" + + +class MasteryLocations(LocationInclusion): + """ + Enables or disables checks for overcoming especially difficult challenges. + These challenges are often based on Mastery achievements and Feats of Strength. + Enable these locations to add the most difficult checks to the world. + + Enabled: Locations of this type give normal rewards. + Half Chance: Locations of this type have a 50% chance of being excluded. + Filler: Forces these locations to contain filler items. + Disabled: Removes item rewards from these locations. + + Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. + See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) + """ + display_name = "Mastery Locations" + + +class BasebustLocations(LocationInclusion): + """ + Enables or disables checks for killing non-objective bases. + These challenges are about destroying enemy bases that you normally don't have to fight to win a mission. + Enable these locations if you like sieges or being rewarded for achieving alternate win conditions. + + Enabled: Locations of this type give normal rewards. + Half Chance: Locations of this type have a 50% chance of being excluded. + *Note setting this for both challenge and basebust will have a 25% of a challenge-basebust location spawning. + Filler: Forces these locations to contain filler items. + Disabled: Removes item rewards from these locations. + + Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. + See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) + """ + display_name = "Base-Bust Locations" + + +class SpeedrunLocations(LocationInclusion): + """ + Enables or disables checks for overcoming speedrun challenges. + These challenges are often based on speed achievements or community challenges. + Enable these locations if you want to be rewarded for going fast. + + Enabled: Locations of this type give normal rewards. + Half Chance: Locations of this type have a 50% chance of being excluded. + *Note setting this for both challenge and speedrun will have a 25% of a challenge-speedrun location spawning. + Filler: Forces these locations to contain filler items. + Disabled: Removes item rewards from these locations. + + Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. + See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) + """ + display_name = "Speedrun Locations" + + +class PreventativeLocations(LocationInclusion): + """ + Enables or disables checks for overcoming preventative challenges. + These challenges are about winning or achieving something while preventing something else from happening, + such as beating Evacuation without losing a colonist. + Enable these locations if you want to be rewarded for achieving a higher standard on some locations. + + Enabled: Locations of this type give normal rewards. + Half Chance: Locations of this type have a 50% chance of being excluded. + *Note setting this for both challenge and preventative will have a 25% of a challenge-preventative location spawning. + Filler: Forces these locations to contain filler items. + Disabled: Removes item rewards from these locations. + + Note: Individual locations subject to plando are always enabled, so the plando can be placed properly. + See also: Excluded Locations, Item Plando (https://archipelago.gg/tutorial/Archipelago/plando/en#item-plando) + """ + display_name = "Preventative Locations" + + +class MissionOrderScouting(Choice): + """ + Allow the Sc2 mission order client tabs to indicate the type of item (i.e., progression, useful, etc.) available at each location of a mission. + The option defines when this information will be available for the player. + By default, this option is deactivated. + + None: Never provide information + Completed: Only for missions that were completed + Available: Only for missions that are available to play + Layout: Only for missions that are in an accessible layout (e.g. Char, Mar Sara, etc.) + Campaign: Only for missions that are in an accessible campaign (e.g. WoL, HotS, etc.) + All: All missions + """ + display_name = "Mission Order Scouting" + option_none = 0 + option_completed = 1 + option_available = 2 + option_layout = 3 + option_campaign = 4 + option_all = 5 + + default = option_none + + +class FillerPercentage(Range): + """ + Percentage of the item pool filled with filler items. + If the world has more locations than items, additional filler items may be generated. + """ + display_name = "Filler Percentage" + range_start = 0 + range_end = 70 + default = 0 + + +class MineralsPerItem(Range): + """ + Configures how many minerals are given per resource item. + """ + display_name = "Minerals Per Item" + range_start = 0 + range_end = 200 + default = 25 + + +class VespenePerItem(Range): + """ + Configures how much vespene gas is given per resource item. + """ + display_name = "Vespene Per Item" + range_start = 0 + range_end = 200 + default = 25 + + +class StartingSupplyPerItem(Range): + """ + Configures how much starting supply per is given per item. + """ + display_name = "Starting Supply Per Item" + range_start = 0 + range_end = 16 + default = 2 + + +class MaximumSupplyPerItem(Range): + """ + Configures how much the maximum supply limit increases per item. + """ + display_name = "Maximum Supply Per Item" + range_start = 0 + range_end = 10 + default = 1 + + +class MaximumSupplyReductionPerItem(Range): + """ + Configures how much maximum supply is reduced per trap item. + """ + display_name = "Maximum Supply Reduction Per Item" + range_start = 1 + range_end = 10 + default = 1 + + +class LowestMaximumSupply(Range): + """Controls how far max supply reduction traps can reduce maximum supply.""" + display_name = "Lowest Maximum Supply" + range_start = 100 + range_end = 200 + default = 180 + +class ResearchCostReductionPerItem(Range): + """ + Controls how much weapon/armor research cost is cut per research cost filler item. + Affects both minerals and vespene. + """ + display_name = "Upgrade Cost Discount Per Item" + range_start = 0 + range_end = 10 + default = 2 + + +class FillerItemsDistribution(ItemDict): + """ + Controls the relative probability of each filler item being generated over others. + Items that are bound to specific race or option are automatically eliminated. + Kerrigan levels generated this way don't go against Kerrigan level item sum + """ + default = { + item_names.STARTING_MINERALS: 1, + item_names.STARTING_VESPENE: 1, + item_names.STARTING_SUPPLY: 1, + item_names.MAX_SUPPLY: 1, + item_names.SHIELD_REGENERATION: 1, + item_names.BUILDING_CONSTRUCTION_SPEED: 1, + item_names.KERRIGAN_LEVELS_1: 0, + item_names.UPGRADE_RESEARCH_SPEED: 1, + item_names.UPGRADE_RESEARCH_COST: 1, + item_names.REDUCED_MAX_SUPPLY: 0, + } + valid_keys = default.keys() + display_name = "Filler Items Distribution" + + def __init__(self, value: Dict[str, int]): + # Allow zeros that the parent class doesn't allow + if any(item_count < 0 for item_count in value.values()): + raise Exception("Cannot have negative item weight.") + super(ItemDict, self).__init__(value) + + +@dataclass +class Starcraft2Options(PerGameCommonOptions): + start_inventory: Sc2StartInventory # type: ignore + game_difficulty: GameDifficulty + difficulty_damage_modifier: DifficultyDamageModifier + game_speed: GameSpeed + disable_forced_camera: DisableForcedCamera + skip_cutscenes: SkipCutscenes + all_in_map: AllInMap + mission_order: MissionOrder + maximum_campaign_size: MaximumCampaignSize + two_start_positions: TwoStartPositions + key_mode: KeyMode + player_color_terran_raynor: PlayerColorTerranRaynor + player_color_protoss: PlayerColorProtoss + player_color_zerg: PlayerColorZerg + player_color_zerg_primal: PlayerColorZergPrimal + player_color_nova: PlayerColorNova + selected_races: SelectRaces + enabled_campaigns: EnabledCampaigns + enable_race_swap: EnableRaceSwapVariants + mission_race_balancing: EnableMissionRaceBalancing + shuffle_campaigns: ShuffleCampaigns + shuffle_no_build: ShuffleNoBuild + starter_unit: StarterUnit + required_tactics: RequiredTactics + enable_void_trade: EnableVoidTrade + void_trade_age_limit: VoidTradeAgeLimit + void_trade_workers: VoidTradeWorkers + ensure_generic_items: EnsureGenericItems + min_number_of_upgrades: MinNumberOfUpgrades + max_number_of_upgrades: MaxNumberOfUpgrades + mercenary_highlanders: MercenaryHighlanders + max_upgrade_level: MaxUpgradeLevel + generic_upgrade_missions: GenericUpgradeMissions + generic_upgrade_research: GenericUpgradeResearch + generic_upgrade_research_speedup: GenericUpgradeResearchSpeedup + generic_upgrade_items: GenericUpgradeItems + kerrigan_presence: KerriganPresence + kerrigan_levels_per_mission_completed: KerriganLevelsPerMissionCompleted + kerrigan_levels_per_mission_completed_cap: KerriganLevelsPerMissionCompletedCap + kerrigan_level_item_sum: KerriganLevelItemSum + kerrigan_level_item_distribution: KerriganLevelItemDistribution + kerrigan_total_level_cap: KerriganTotalLevelCap + start_primary_abilities: StartPrimaryAbilities + kerrigan_primal_status: KerriganPrimalStatus + kerrigan_max_active_abilities: KerriganMaxActiveAbilities + kerrigan_max_passive_abilities: KerriganMaxPassiveAbilities + enable_morphling: EnableMorphling + war_council_nerfs: WarCouncilNerfs + spear_of_adun_presence: SpearOfAdunPresence + spear_of_adun_present_in_no_build: SpearOfAdunPresentInNoBuild + spear_of_adun_passive_ability_presence: SpearOfAdunPassiveAbilityPresence + spear_of_adun_passive_present_in_no_build: SpearOfAdunPassivesPresentInNoBuild + spear_of_adun_max_active_abilities: SpearOfAdunMaxActiveAbilities + spear_of_adun_max_passive_abilities: SpearOfAdunMaxAutocastAbilities + grant_story_tech: GrantStoryTech + grant_story_levels: GrantStoryLevels + nova_max_weapons: NovaMaxWeapons + nova_max_gadgets: NovaMaxGadgets + nova_ghost_of_a_chance_variant: NovaGhostOfAChanceVariant + take_over_ai_allies: TakeOverAIAllies + locked_items: LockedItems + excluded_items: ExcludedItems + unexcluded_items: UnexcludedItems + excluded_missions: ExcludedMissions + difficulty_curve: DifficultyCurve + exclude_very_hard_missions: ExcludeVeryHardMissions + vanilla_items_only: VanillaItemsOnly + exclude_overpowered_items: ExcludeOverpoweredItems + victory_cache: VictoryCache + vanilla_locations: VanillaLocations + extra_locations: ExtraLocations + challenge_locations: ChallengeLocations + mastery_locations: MasteryLocations + basebust_locations: BasebustLocations + speedrun_locations: SpeedrunLocations + preventative_locations: PreventativeLocations + filler_percentage: FillerPercentage + minerals_per_item: MineralsPerItem + vespene_per_item: VespenePerItem + starting_supply_per_item: StartingSupplyPerItem + maximum_supply_per_item: MaximumSupplyPerItem + maximum_supply_reduction_per_item: MaximumSupplyReductionPerItem + lowest_maximum_supply: LowestMaximumSupply + research_cost_reduction_per_item: ResearchCostReductionPerItem + filler_items_distribution: FillerItemsDistribution + mission_order_scouting: MissionOrderScouting + + custom_mission_order: CustomMissionOrder + +option_groups = [ + OptionGroup("Difficulty Settings", [ + GameDifficulty, + GameSpeed, + StarterUnit, + RequiredTactics, + WarCouncilNerfs, + DifficultyCurve, + ]), + OptionGroup("Primary Campaign Settings", [ + MissionOrder, + MaximumCampaignSize, + EnabledCampaigns, + EnableRaceSwapVariants, + ShuffleNoBuild, + ]), + OptionGroup("Optional Campaign Settings", [ + KeyMode, + ShuffleCampaigns, + AllInMap, + TwoStartPositions, + SelectRaces, + ExcludeVeryHardMissions, + EnableMissionRaceBalancing, + ]), + OptionGroup("Unit Upgrades", [ + EnsureGenericItems, + MinNumberOfUpgrades, + MaxNumberOfUpgrades, + MaxUpgradeLevel, + GenericUpgradeMissions, + GenericUpgradeResearch, + GenericUpgradeResearchSpeedup, + GenericUpgradeItems, + ]), + OptionGroup("Kerrigan", [ + KerriganPresence, + GrantStoryLevels, + KerriganLevelsPerMissionCompleted, + KerriganLevelsPerMissionCompletedCap, + KerriganLevelItemSum, + KerriganLevelItemDistribution, + KerriganTotalLevelCap, + StartPrimaryAbilities, + KerriganPrimalStatus, + KerriganMaxActiveAbilities, + KerriganMaxPassiveAbilities, + ]), + OptionGroup("Spear of Adun", [ + SpearOfAdunPresence, + SpearOfAdunPresentInNoBuild, + SpearOfAdunPassiveAbilityPresence, + SpearOfAdunPassivesPresentInNoBuild, + SpearOfAdunMaxActiveAbilities, + SpearOfAdunMaxAutocastAbilities, + ]), + OptionGroup("Nova", [ + NovaMaxWeapons, + NovaMaxGadgets, + NovaGhostOfAChanceVariant, + ]), + OptionGroup("Race Specific Options", [ + EnableMorphling, + MercenaryHighlanders, + ]), + OptionGroup("Check Locations", [ + VictoryCache, + VanillaLocations, + ExtraLocations, + ChallengeLocations, + MasteryLocations, + BasebustLocations, + SpeedrunLocations, + PreventativeLocations, + ]), + OptionGroup("Filler Options", [ + FillerPercentage, + MineralsPerItem, + VespenePerItem, + StartingSupplyPerItem, + MaximumSupplyPerItem, + MaximumSupplyReductionPerItem, + LowestMaximumSupply, + ResearchCostReductionPerItem, + FillerItemsDistribution, + ]), + OptionGroup("Inclusions & Exclusions", [ + LockedItems, + ExcludedItems, + UnexcludedItems, + VanillaItemsOnly, + ExcludeOverpoweredItems, + ExcludedMissions, + ]), + OptionGroup("Advanced Gameplay", [ + MissionOrderScouting, + DifficultyDamageModifier, + TakeOverAIAllies, + EnableVoidTrade, + VoidTradeAgeLimit, + VoidTradeWorkers, + GrantStoryTech, + CustomMissionOrder, + ]), + OptionGroup("Cosmetics", [ + PlayerColorTerranRaynor, + PlayerColorProtoss, + PlayerColorZerg, + PlayerColorZergPrimal, + PlayerColorNova, + ]) +] + +def get_option_value(world: Union['SC2World', None], name: str) -> int: + """ + You should basically never use this unless `world` can be `None`. + Use `world.options..value` instead for better typing, autocomplete, and error messages. + """ + if world is None: + field: Field = [class_field for class_field in fields(Starcraft2Options) if class_field.name == name][0] + if isinstance(field.type, str): + if field.type in globals(): + return globals()[field.type].default + import Options + return Options.__dict__[field.type].default + return field.type.default + + player_option = getattr(world.options, name) + + return player_option.value + + +def get_enabled_races(world: Optional['SC2World']) -> Set[SC2Race]: + race_names = world.options.selected_races.value if world and len(world.options.selected_races.value) > 0 else SelectRaces.valid_keys + return {race for race in SC2Race if race.get_title() in race_names} + + +def get_enabled_campaigns(world: Optional['SC2World']) -> Set[SC2Campaign]: + if world is None: + return {campaign for campaign in SC2Campaign if campaign.campaign_name in EnabledCampaigns.default} + campaign_names = world.options.enabled_campaigns + campaigns = {campaign for campaign in SC2Campaign if campaign.campaign_name in campaign_names} + if (world.options.mission_order.value == MissionOrder.option_vanilla + and get_enabled_races(world) != {SC2Race.TERRAN, SC2Race.ZERG, SC2Race.PROTOSS} + and SC2Campaign.EPILOGUE in campaigns + ): + campaigns.remove(SC2Campaign.EPILOGUE) + if len(campaigns) == 0: + # Everything is disabled, roll as everything enabled + return {campaign for campaign in SC2Campaign if campaign != SC2Campaign.GLOBAL} + return campaigns + + +def get_disabled_campaigns(world: 'SC2World') -> Set[SC2Campaign]: + all_campaigns = set(SC2Campaign) + enabled_campaigns = get_enabled_campaigns(world) + disabled_campaigns = all_campaigns.difference(enabled_campaigns) + disabled_campaigns.remove(SC2Campaign.GLOBAL) + return disabled_campaigns + + +def get_disabled_flags(world: 'SC2World') -> MissionFlag: + excluded = ( + (MissionFlag.Terran | MissionFlag.Zerg | MissionFlag.Protoss) + ^ functools.reduce(lambda a, b: a | b, [race.get_mission_flag() for race in get_enabled_races(world)]) + ) + # filter out no-build missions + if not world.options.shuffle_no_build.value: + excluded |= MissionFlag.NoBuild + raceswap_option = world.options.enable_race_swap.value + if raceswap_option == EnableRaceSwapVariants.option_disabled: + excluded |= MissionFlag.RaceSwap + elif raceswap_option in [EnableRaceSwapVariants.option_pick_one_non_vanilla, EnableRaceSwapVariants.option_shuffle_all_non_vanilla]: + excluded |= MissionFlag.HasRaceSwap + # TODO: add more flags to potentially exclude once we have a way to get that from the player + return MissionFlag(excluded) + + +def get_excluded_missions(world: 'SC2World') -> Set[SC2Mission]: + mission_order_type = world.options.mission_order.value + excluded_mission_names = world.options.excluded_missions.value + disabled_campaigns = get_disabled_campaigns(world) + disabled_flags = get_disabled_flags(world) + + excluded_missions: Set[SC2Mission] = set([lookup_name_to_mission[name] for name in excluded_mission_names]) + + # Excluding Very Hard missions depending on options + if (mission_order_type != MissionOrder.option_vanilla and + ( + world.options.exclude_very_hard_missions == ExcludeVeryHardMissions.option_true + or ( + world.options.exclude_very_hard_missions == ExcludeVeryHardMissions.option_default + and ( + ( + mission_order_type in dynamic_mission_orders + and world.options.maximum_campaign_size < 20 + ) + or mission_order_type == MissionOrder.option_mini_campaign + ) + ) + ) + ): + excluded_missions = excluded_missions.union( + [mission for mission in SC2Mission if + mission.pool == MissionPools.VERY_HARD and mission.campaign != SC2Campaign.EPILOGUE] + ) + # Omitting missions with flags we don't want + if disabled_flags: + excluded_missions = excluded_missions.union(get_missions_with_any_flags_in_list(disabled_flags)) + # Omitting missions not in enabled campaigns + for campaign in disabled_campaigns: + excluded_missions = excluded_missions.union(campaign_mission_table[campaign]) + # Omitting unwanted mission variants + if world.options.enable_race_swap.value in [EnableRaceSwapVariants.option_pick_one, EnableRaceSwapVariants.option_pick_one_non_vanilla]: + swaps = [ + mission for mission in SC2Mission + if mission not in excluded_missions + and mission.flags & (MissionFlag.HasRaceSwap|MissionFlag.RaceSwap) + ] + while len(swaps) > 0: + curr = swaps[0] + variants = [mission for mission in swaps if mission.map_file == curr.map_file] + variants.sort(key=lambda mission: mission.id) + swaps = [mission for mission in swaps if mission not in variants] + if len(variants) > 1: + variants.pop(world.random.randint(0, len(variants)-1)) + excluded_missions = excluded_missions.union(variants) + + return excluded_missions + + +def is_mission_in_soa_presence( + spear_of_adun_presence: int, + mission: SC2Mission, + option_class: Type[SpearOfAdunPresence] | Type[SpearOfAdunPassiveAbilityPresence] = SpearOfAdunPresence +) -> bool: + """ + Returns True if the mission can have Spear of Adun abilities. + No-build presence must be checked separately. + """ + return ( + (spear_of_adun_presence == option_class.option_everywhere) + or (spear_of_adun_presence == option_class.option_protoss and MissionFlag.Protoss in mission.flags) + or (spear_of_adun_presence == option_class.option_any_race_lotv + and (mission.campaign == SC2Campaign.LOTV or MissionFlag.VanillaSoa in mission.flags) + ) + or (spear_of_adun_presence == option_class.option_vanilla + and (MissionFlag.VanillaSoa in mission.flags # Keeps SOA off on Growing Shadow, as that's vanilla behaviour + or (MissionFlag.NoBuild in mission.flags and mission.campaign == SC2Campaign.LOTV) + ) + ) + ) + + + +static_mission_orders = [ + MissionOrder.option_vanilla, + MissionOrder.option_vanilla_shuffled, + MissionOrder.option_mini_campaign, +] + +dynamic_mission_orders = [ + MissionOrder.option_golden_path, + MissionOrder.option_grid, + MissionOrder.option_gauntlet, + MissionOrder.option_blitz, + MissionOrder.option_hopscotch, +] + +LEGACY_GRID_ORDERS = {3, 4, 8} # Medium Grid, Mini Grid, and Tiny Grid respectively + +kerrigan_unit_available = [ + KerriganPresence.option_vanilla, +] + +# Names of upgrades to be included for different options +upgrade_included_names: Dict[int, Set[str]] = { + GenericUpgradeItems.option_individual_items: { + item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, + item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR, + item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, + item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR, + item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, + item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR, + item_names.PROGRESSIVE_ZERG_MELEE_ATTACK, + item_names.PROGRESSIVE_ZERG_MISSILE_ATTACK, + item_names.PROGRESSIVE_ZERG_GROUND_CARAPACE, + item_names.PROGRESSIVE_ZERG_FLYER_ATTACK, + item_names.PROGRESSIVE_ZERG_FLYER_CARAPACE, + item_names.PROGRESSIVE_PROTOSS_GROUND_WEAPON, + item_names.PROGRESSIVE_PROTOSS_GROUND_ARMOR, + item_names.PROGRESSIVE_PROTOSS_SHIELDS, + item_names.PROGRESSIVE_PROTOSS_AIR_WEAPON, + item_names.PROGRESSIVE_PROTOSS_AIR_ARMOR, + }, + GenericUpgradeItems.option_bundle_weapon_and_armor: { + item_names.PROGRESSIVE_TERRAN_WEAPON_UPGRADE, + item_names.PROGRESSIVE_TERRAN_ARMOR_UPGRADE, + item_names.PROGRESSIVE_ZERG_WEAPON_UPGRADE, + item_names.PROGRESSIVE_ZERG_ARMOR_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_WEAPON_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_ARMOR_UPGRADE, + }, + GenericUpgradeItems.option_bundle_unit_class: { + item_names.PROGRESSIVE_TERRAN_INFANTRY_UPGRADE, + item_names.PROGRESSIVE_TERRAN_VEHICLE_UPGRADE, + item_names.PROGRESSIVE_TERRAN_SHIP_UPGRADE, + item_names.PROGRESSIVE_ZERG_GROUND_UPGRADE, + item_names.PROGRESSIVE_ZERG_FLYER_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_GROUND_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_AIR_UPGRADE, + }, + GenericUpgradeItems.option_bundle_all: { + item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE, + item_names.PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE, + } +} + +# Mapping trade age limit options to their millisecond equivalents +void_trade_age_limits_ms: Dict[int, int] = { + VoidTradeAgeLimit.option_5_minutes: 1000 * int(timedelta(minutes = 5).total_seconds()), + VoidTradeAgeLimit.option_30_minutes: 1000 * int(timedelta(minutes = 30).total_seconds()), + VoidTradeAgeLimit.option_1_hour: 1000 * int(timedelta(hours = 1).total_seconds()), + VoidTradeAgeLimit.option_2_hours: 1000 * int(timedelta(hours = 2).total_seconds()), + VoidTradeAgeLimit.option_4_hours: 1000 * int(timedelta(hours = 4).total_seconds()), + VoidTradeAgeLimit.option_1_day: 1000 * int(timedelta(days = 1).total_seconds()), + VoidTradeAgeLimit.option_1_week: 1000 * int(timedelta(weeks = 1).total_seconds()), +} diff --git a/worlds/sc2/pool_filter.py b/worlds/sc2/pool_filter.py new file mode 100644 index 000000000000..31e47934ee9d --- /dev/null +++ b/worlds/sc2/pool_filter.py @@ -0,0 +1,493 @@ +import logging +from typing import Callable, Dict, List, Set, Tuple, TYPE_CHECKING, Iterable + +from BaseClasses import Location, ItemClassification +from .item import StarcraftItem, ItemFilterFlags, item_names, item_parents, item_groups +from .item.item_tables import item_table, TerranItemType, ZergItemType, spear_of_adun_calldowns, \ + spear_of_adun_castable_passives +from .options import RequiredTactics + +if TYPE_CHECKING: + from . import SC2World + + +# Items that can be placed before resources if not already in +# General upgrades and Mercs +second_pass_placeable_items: Tuple[str, ...] = ( + # Global weapon/armor upgrades + item_names.PROGRESSIVE_TERRAN_ARMOR_UPGRADE, + item_names.PROGRESSIVE_TERRAN_WEAPON_UPGRADE, + item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE, + item_names.PROGRESSIVE_ZERG_ARMOR_UPGRADE, + item_names.PROGRESSIVE_ZERG_WEAPON_UPGRADE, + item_names.PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_ARMOR_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_WEAPON_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_WEAPON_ARMOR_UPGRADE, + item_names.PROGRESSIVE_PROTOSS_SHIELDS, + # Terran Buildings without upgrades + item_names.SENSOR_TOWER, + item_names.HIVE_MIND_EMULATOR, + item_names.PSI_DISRUPTER, + item_names.PERDITION_TURRET, + # General Terran upgrades without any dependencies + item_names.SCV_ADVANCED_CONSTRUCTION, + item_names.SCV_DUAL_FUSION_WELDERS, + item_names.SCV_CONSTRUCTION_JUMP_JETS, + item_names.PROGRESSIVE_FIRE_SUPPRESSION_SYSTEM, + item_names.PROGRESSIVE_ORBITAL_COMMAND, + item_names.ULTRA_CAPACITORS, + item_names.VANADIUM_PLATING, + item_names.ORBITAL_DEPOTS, + item_names.MICRO_FILTERING, + item_names.AUTOMATED_REFINERY, + item_names.COMMAND_CENTER_COMMAND_CENTER_REACTOR, + item_names.COMMAND_CENTER_SCANNER_SWEEP, + item_names.COMMAND_CENTER_MULE, + item_names.COMMAND_CENTER_EXTRA_SUPPLIES, + item_names.TECH_REACTOR, + item_names.CELLULAR_REACTOR, + item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL, # Place only L1 + item_names.STRUCTURE_ARMOR, + item_names.HI_SEC_AUTO_TRACKING, + item_names.ADVANCED_OPTICS, + item_names.ROGUE_FORCES, + # Mercenaries (All races) + *[item_name for item_name, item_data in item_table.items() + if item_data.type in (TerranItemType.Mercenary, ZergItemType.Mercenary)], + # Kerrigan and Nova levels, abilities and generally useful stuff + *[item_name for item_name, item_data in item_table.items() + if item_data.type in ( + ZergItemType.Level, + ZergItemType.Ability, + ZergItemType.Evolution_Pit, + TerranItemType.Nova_Gear + )], + item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE, + # Zerg static defenses + item_names.SPORE_CRAWLER, + item_names.SPINE_CRAWLER, + # Overseer + item_names.OVERLORD_OVERSEER_ASPECT, + # Spear of Adun Abilities + item_names.SOA_CHRONO_SURGE, + item_names.SOA_PROGRESSIVE_PROXY_PYLON, + item_names.SOA_PYLON_OVERCHARGE, + item_names.SOA_ORBITAL_STRIKE, + item_names.SOA_TEMPORAL_FIELD, + item_names.SOA_SOLAR_LANCE, + item_names.SOA_MASS_RECALL, + item_names.SOA_SHIELD_OVERCHARGE, + item_names.SOA_DEPLOY_FENIX, + item_names.SOA_PURIFIER_BEAM, + item_names.SOA_TIME_STOP, + item_names.SOA_SOLAR_BOMBARDMENT, + # Protoss generic upgrades + item_names.MATRIX_OVERLOAD, + item_names.QUATRO, + item_names.NEXUS_OVERCHARGE, + item_names.ORBITAL_ASSIMILATORS, + item_names.WARP_HARMONIZATION, + item_names.GUARDIAN_SHELL, + item_names.RECONSTRUCTION_BEAM, + item_names.OVERWATCH, + item_names.SUPERIOR_WARP_GATES, + item_names.KHALAI_INGENUITY, + item_names.AMPLIFIED_ASSIMILATORS, + # Protoss static defenses + item_names.PHOTON_CANNON, + item_names.KHAYDARIN_MONOLITH, + item_names.SHIELD_BATTERY, +) + + +def copy_item(item: StarcraftItem) -> StarcraftItem: + return StarcraftItem(item.name, item.classification, item.code, item.player, item.filter_flags) + + +class ValidInventory: + def __init__(self, world: 'SC2World', item_pool: List[StarcraftItem]) -> None: + self.multiworld = world.multiworld + self.player = world.player + self.world: 'SC2World' = world + # Track all Progression items and those with complex rules for filtering + self.logical_inventory: Dict[str, int] = {} + for item in item_pool: + if not item_table[item.name].is_important_for_filtering(): + continue + self.logical_inventory.setdefault(item.name, 0) + self.logical_inventory[item.name] += 1 + self.item_pool = item_pool + self.item_name_to_item: Dict[str, List[StarcraftItem]] = {} + self.item_name_to_child_items: Dict[str, List[StarcraftItem]] = {} + for item in item_pool: + self.item_name_to_item.setdefault(item.name, []).append(item) + for parent_item in item_parents.child_item_to_parent_items.get(item.name, []): + self.item_name_to_child_items.setdefault(parent_item, []).append(item) + + def has(self, item: str, player: int, count: int = 1) -> bool: + return self.logical_inventory.get(item, 0) >= count + + def has_any(self, items: Set[str], player: int) -> bool: + return any(self.logical_inventory.get(item) for item in items) + + def has_all(self, items: Set[str], player: int) -> bool: + return all(self.logical_inventory.get(item) for item in items) + + def has_group(self, item_group: str, player: int, count: int = 1) -> bool: + return False # Deliberately fails here, as item pooling is not aware about mission layout + + def count_group(self, item_name_group: str, player: int) -> int: + return 0 # For item filtering assume no missions are beaten + + def count(self, item: str, player: int) -> int: + return self.logical_inventory.get(item, 0) + + def count_from_list(self, items: Iterable[str], player: int) -> int: + return sum(self.logical_inventory.get(item, 0) for item in items) + + def count_from_list_unique(self, items: Iterable[str], player: int) -> int: + return sum(item in self.logical_inventory for item in items) + + def generate_reduced_inventory(self, inventory_size: int, filler_amount: int, mission_requirements: List[Tuple[str, Callable]]) -> List[StarcraftItem]: + """Attempts to generate a reduced inventory that can fulfill the mission requirements.""" + inventory: List[StarcraftItem] = list(self.item_pool) + requirements = mission_requirements + min_upgrades_per_unit = self.world.options.min_number_of_upgrades.value + max_upgrades_per_unit = self.world.options.max_number_of_upgrades.value + if max_upgrades_per_unit > -1 and min_upgrades_per_unit > max_upgrades_per_unit: + logging.getLogger("Starcraft 2").warning( + f"min upgrades per unit is greater than max upgrades per unit ({min_upgrades_per_unit} > {max_upgrades_per_unit}). " + f"Setting both to minimum value ({min_upgrades_per_unit})" + ) + max_upgrades_per_unit = min_upgrades_per_unit + + def attempt_removal( + item: StarcraftItem, + remove_flag: ItemFilterFlags = ItemFilterFlags.FilterExcluded, + ) -> str: + """ + Returns empty string and applies `remove_flag` if the item is removable, + else returns a string containing failed locations and applies ItemFilterFlags.LogicLocked + """ + # Only run logic checks when removing logic items + if self.logical_inventory.get(item.name, 0) > 0: + self.logical_inventory[item.name] -= 1 + failed_rules = [name for name, requirement in mission_requirements if not requirement(self)] + if failed_rules: + # If item cannot be removed, lock and revert + self.logical_inventory[item.name] += 1 + item.filter_flags |= ItemFilterFlags.LogicLocked + return f"{len(failed_rules)} rules starting with \"{failed_rules[0]}\"" + if not self.logical_inventory[item.name]: + del self.logical_inventory[item.name] + item.filter_flags |= remove_flag + return "" + + def remove_child_items( + parent_item: StarcraftItem, + remove_flag: ItemFilterFlags = ItemFilterFlags.FilterExcluded, + ) -> None: + child_items = self.item_name_to_child_items.get(parent_item.name, []) + for child_item in child_items: + if (ItemFilterFlags.AllowedOrphan|ItemFilterFlags.Unexcludable) & child_item.filter_flags: + continue + parent_id = item_table[child_item.name].parent + assert parent_id is not None + if item_parents.parent_present[parent_id](self.logical_inventory, self.world.options): + continue + if not attempt_removal(child_item, remove_flag): + remove_child_items(child_item, remove_flag) + + def cull_items_over_maximum(group: List[StarcraftItem], allowed_max: int) -> None: + for item in group: + if len([x for x in group if ItemFilterFlags.Culled not in x.filter_flags]) <= allowed_max: + break + if ItemFilterFlags.Uncullable & item.filter_flags: + continue + attempt_removal(item, remove_flag=ItemFilterFlags.Culled) + + def request_minimum_items(group: List[StarcraftItem], requested_minimum) -> None: + for item in group: + if len([x for x in group if ItemFilterFlags.RequestedOrBetter & x.filter_flags]) >= requested_minimum: + break + if ItemFilterFlags.Culled & item.filter_flags: + continue + item.filter_flags |= ItemFilterFlags.Requested + + # Process Excluded items, validate if the item can get actually excluded + excluded_items: List[StarcraftItem] = [starcraft_item for starcraft_item in inventory if ItemFilterFlags.Excluded & starcraft_item.filter_flags] + self.world.random.shuffle(excluded_items) + for excluded_item in excluded_items: + if ItemFilterFlags.Unexcludable & excluded_item.filter_flags: + continue + removal_failed = attempt_removal(excluded_item, remove_flag=ItemFilterFlags.Removed) + if removal_failed: + if ItemFilterFlags.UserExcluded in excluded_item.filter_flags: + logging.getLogger("Starcraft 2").warning( + f"Cannot exclude item {excluded_item.name} as it would break {removal_failed}" + ) + else: + assert False, f"Item filtering excluded an item which is logically required: {excluded_item.name}" + continue + remove_child_items(excluded_item, remove_flag=ItemFilterFlags.Removed) + inventory = [item for item in inventory if ItemFilterFlags.Removed not in item.filter_flags] + + # Clear excluded flags; all existing ones should be implemented or out-of-logic + for item in inventory: + item.filter_flags &= ~ItemFilterFlags.Excluded + + # Determine item groups to be constrained by min/max upgrades per unit + group_to_item: Dict[str, List[StarcraftItem]] = {} + group: str = "" + for group, group_member_names in item_parents.item_upgrade_groups.items(): + group_to_item[group] = [] + for item_name in group_member_names: + inventory_items = self.item_name_to_item.get(item_name, []) + group_to_item[group].extend(item for item in inventory_items if ItemFilterFlags.Removed not in item.filter_flags) + + # Limit the maximum number of upgrades + if max_upgrades_per_unit != -1: + for group_name, group_items in group_to_item.items(): + self.world.random.shuffle(group_to_item[group]) + cull_items_over_maximum(group_items, max_upgrades_per_unit) + + # Requesting minimum upgrades for items that have already been locked/placed when minimum required + if min_upgrades_per_unit != -1: + for group_name, group_items in group_to_item.items(): + self.world.random.shuffle(group_items) + request_minimum_items(group_items, min_upgrades_per_unit) + + # Kerrigan max abilities + kerrigan_actives = [item for item in inventory if item.name in item_groups.kerrigan_active_abilities] + self.world.random.shuffle(kerrigan_actives) + cull_items_over_maximum(kerrigan_actives, self.world.options.kerrigan_max_active_abilities.value) + + kerrigan_passives = [item for item in inventory if item.name in item_groups.kerrigan_passives] + self.world.random.shuffle(kerrigan_passives) + cull_items_over_maximum(kerrigan_passives, self.world.options.kerrigan_max_passive_abilities.value) + + # Spear of Adun max abilities + spear_of_adun_actives = [item for item in inventory if item.name in spear_of_adun_calldowns] + self.world.random.shuffle(spear_of_adun_actives) + cull_items_over_maximum(spear_of_adun_actives, self.world.options.spear_of_adun_max_active_abilities.value) + + spear_of_adun_autocasts = [item for item in inventory if item.name in spear_of_adun_castable_passives] + self.world.random.shuffle(spear_of_adun_autocasts) + cull_items_over_maximum(spear_of_adun_autocasts, self.world.options.spear_of_adun_max_passive_abilities.value) + + # Nova items + nova_weapon_items = [item for item in inventory if item.name in item_groups.nova_weapons] + self.world.random.shuffle(nova_weapon_items) + cull_items_over_maximum(nova_weapon_items, self.world.options.nova_max_weapons.value) + + nova_gadget_items = [item for item in inventory if item.name in item_groups.nova_gadgets] + self.world.random.shuffle(nova_gadget_items) + cull_items_over_maximum(nova_gadget_items, self.world.options.nova_max_gadgets.value) + + # Determining if the full-size inventory can complete campaign + # Note(mm): Now that user excludes are checked against logic, this can probably never fail unless there's a bug. + failed_locations: List[str] = [location for (location, requirement) in requirements if not requirement(self)] + if len(failed_locations) > 0: + raise Exception(f"Too many items excluded - couldn't satisfy access rules for the following locations:\n{failed_locations}") + + # Optionally locking generic items + generic_items: List[StarcraftItem] = [ + starcraft_item for starcraft_item in inventory + if starcraft_item.name in second_pass_placeable_items + and ( + not ItemFilterFlags.CulledOrBetter & starcraft_item.filter_flags + or ItemFilterFlags.RequestedOrBetter & starcraft_item.filter_flags + ) + ] + reserved_generic_percent = self.world.options.ensure_generic_items.value / 100 + reserved_generic_amount = int(len(generic_items) * reserved_generic_percent) + self.world.random.shuffle(generic_items) + for starcraft_item in generic_items[:reserved_generic_amount]: + starcraft_item.filter_flags |= ItemFilterFlags.Requested + + # Main cull process + def remove_random_item( + removable: List[StarcraftItem], + dont_remove_flags: ItemFilterFlags, + remove_flag: ItemFilterFlags = ItemFilterFlags.Removed, + ) -> bool: + if len(removable) == 0: + return False + item = self.world.random.choice(removable) + # Do not remove item if it would drop upgrades below minimum + if min_upgrades_per_unit > 0: + group_name = None + parent = item_table[item.name].parent + if parent is not None: + group_name = item_parents.parent_present[parent].constraint_group + if group_name is not None: + children = group_to_item.get(group_name, []) + children = [x for x in children if not (ItemFilterFlags.CulledOrBetter & x.filter_flags)] + if len(children) <= min_upgrades_per_unit: + # Attempt to remove a parent instead, if possible + dont_remove = ItemFilterFlags.Removed|dont_remove_flags + parent_items = [ + parent_item + for parent_name in item_parents.child_item_to_parent_items[item.name] + for parent_item in self.item_name_to_item.get(parent_name, []) + if not (dont_remove & parent_item.filter_flags) + ] + if parent_items: + item = self.world.random.choice(parent_items) + else: + # Lock remaining upgrades + for item in children: + item.filter_flags |= ItemFilterFlags.Locked + return False + if not attempt_removal(item, remove_flag): + remove_child_items(item, remove_flag) + return True + return False + + def item_included(item: StarcraftItem) -> bool: + return bool( + ItemFilterFlags.Removed not in item.filter_flags + and ((ItemFilterFlags.Unexcludable|ItemFilterFlags.Excluded) & item.filter_flags) != ItemFilterFlags.Excluded + ) + + # Actually remove culled items; we won't re-add them + inventory = [ + item for item in inventory + if (((ItemFilterFlags.Uncullable|ItemFilterFlags.Culled) & item.filter_flags) != ItemFilterFlags.Culled) + ] + + # Part 1: Remove items that are not requested + start_inventory_size = len([item for item in inventory if ItemFilterFlags.StartInventory in item.filter_flags]) + current_inventory_size = len([item for item in inventory if item_included(item)]) + cullable_items = [item for item in inventory if not (ItemFilterFlags.Uncullable & item.filter_flags)] + while current_inventory_size - start_inventory_size > inventory_size - filler_amount: + if len(cullable_items) == 0: + if filler_amount > 0: + filler_amount -= 1 + else: + break + if remove_random_item(cullable_items, ItemFilterFlags.Uncullable): + inventory = [item for item in inventory if ItemFilterFlags.Removed not in item.filter_flags] + current_inventory_size = len([item for item in inventory if item_included(item)]) + cullable_items = [ + item for item in cullable_items + if not ((ItemFilterFlags.Removed|ItemFilterFlags.Uncullable) & item.filter_flags) + ] + + # Handle too many requested + if current_inventory_size - start_inventory_size > inventory_size - filler_amount: + for item in inventory: + item.filter_flags &= ~ItemFilterFlags.Requested + + # Part 2: If we need to remove more, allow removing requested items + excludable_items = [item for item in inventory if not (ItemFilterFlags.Unexcludable & item.filter_flags)] + while current_inventory_size - start_inventory_size > inventory_size - filler_amount: + if len(excludable_items) == 0: + break + if remove_random_item(excludable_items, ItemFilterFlags.Unexcludable): + inventory = [item for item in inventory if ItemFilterFlags.Removed not in item.filter_flags] + current_inventory_size = len([item for item in inventory if item_included(item)]) + excludable_items = [ + item for item in inventory + if not ((ItemFilterFlags.Removed|ItemFilterFlags.Unexcludable) & item.filter_flags) + ] + + # Part 3: If it still doesn't fit, move locked items to start inventory until it fits + precollect_items = current_inventory_size - inventory_size - start_inventory_size - filler_amount + if precollect_items > 0: + promotable = [ + item + for item in inventory + if ItemFilterFlags.StartInventory not in item.filter_flags + and ItemFilterFlags.Locked in item.filter_flags + ] + self.world.random.shuffle(promotable) + for item in promotable[:precollect_items]: + item.filter_flags |= ItemFilterFlags.StartInventory + start_inventory_size += 1 + + # Removing extra dependencies + # Transport Hook + if not self.logical_inventory.get(item_names.MEDIVAC): + # Don't allow L2 Siege Tank Transport Hook without Medivac + inventory_transport_hooks = [item for item in inventory if item.name == item_names.SIEGE_TANK_PROGRESSIVE_TRANSPORT_HOOK] + removable_transport_hooks = [item for item in inventory_transport_hooks if not (ItemFilterFlags.Unexcludable & item.filter_flags)] + if len(inventory_transport_hooks) > 1 and removable_transport_hooks: + inventory.remove(removable_transport_hooks[0]) + + # Weapon/Armour upgrades + def exclude_wa(prefix: str) -> List[StarcraftItem]: + return [ + item for item in inventory + if (ItemFilterFlags.UnexcludableUpgrade & item.filter_flags) + or not item.name.startswith(prefix) + ] + used_item_names: Set[str] = {item.name for item in inventory} + if used_item_names.isdisjoint(item_groups.barracks_wa_group): + inventory = exclude_wa(item_names.TERRAN_INFANTRY_UPGRADE_PREFIX) + if used_item_names.isdisjoint(item_groups.factory_wa_group): + inventory = exclude_wa(item_names.TERRAN_VEHICLE_UPGRADE_PREFIX) + if used_item_names.isdisjoint(item_groups.starport_wa_group): + inventory = exclude_wa(item_names.TERRAN_SHIP_UPGRADE_PREFIX) + if used_item_names.isdisjoint(item_groups.zerg_melee_wa): + inventory = exclude_wa(item_names.PROGRESSIVE_ZERG_MELEE_ATTACK) + if used_item_names.isdisjoint(item_groups.zerg_ranged_wa): + inventory = exclude_wa(item_names.PROGRESSIVE_ZERG_MISSILE_ATTACK) + if used_item_names.isdisjoint(item_groups.zerg_air_units): + inventory = exclude_wa(item_names.ZERG_FLYER_UPGRADE_PREFIX) + if used_item_names.isdisjoint(item_groups.protoss_ground_wa): + inventory = exclude_wa(item_names.PROTOSS_GROUND_UPGRADE_PREFIX) + if used_item_names.isdisjoint(item_groups.protoss_air_wa): + inventory = exclude_wa(item_names.PROTOSS_AIR_UPGRADE_PREFIX) + + # Part 4: Last-ditch effort to reduce inventory size; upgrades can go in start inventory + current_inventory_size = len(inventory) + precollect_items = current_inventory_size - inventory_size - start_inventory_size - filler_amount + if precollect_items > 0: + promotable = [ + item + for item in inventory + if ItemFilterFlags.StartInventory not in item.filter_flags + ] + self.world.random.shuffle(promotable) + for item in promotable[:precollect_items]: + item.filter_flags |= ItemFilterFlags.StartInventory + start_inventory_size += 1 + + assert current_inventory_size - start_inventory_size <= inventory_size - filler_amount, ( + f"Couldn't reduce inventory to fit. target={inventory_size}, poolsize={current_inventory_size}, " + f"start_inventory={starcraft_item}, filler_amount={filler_amount}" + ) + + return inventory + + +def filter_items(world: 'SC2World', location_cache: List[Location], item_pool: List[StarcraftItem]) -> List[StarcraftItem]: + """ + Returns a semi-randomly pruned set of items based on number of available locations. + The returned inventory must be capable of logically accessing every location in the world. + """ + open_locations = [location for location in location_cache if location.item is None] + inventory_size = len(open_locations) + # Most of the excluded locations get actually removed but Victory ones are mandatory in order to allow the game + # to progress normally. Since regular items aren't flagged as filler, we need to generate enough filler for those + # locations as we need to have something that can be actually placed there. + # Therefore, we reserve those to be filler. + excluded_locations = [location for location in open_locations if location.name in world.options.exclude_locations.value] + reserved_filler_count = len(excluded_locations) + target_nonfiller_item_count = inventory_size - reserved_filler_count + filler_amount = (inventory_size * world.options.filler_percentage) // 100 + if world.options.required_tactics.value == RequiredTactics.option_no_logic: + mission_requirements = [] + else: + mission_requirements = [(location.name, location.access_rule) for location in location_cache] + valid_inventory = ValidInventory(world, item_pool) + + valid_items = valid_inventory.generate_reduced_inventory(target_nonfiller_item_count, filler_amount, mission_requirements) + for _ in range(reserved_filler_count): + filler_item = world.create_item(world.get_filler_item_name()) + if filler_item.classification & ItemClassification.progression: + filler_item.classification = ItemClassification.filler # Must be flagged as Filler, even if it's a Kerrigan level + valid_items.append(filler_item) + return valid_items diff --git a/worlds/sc2/regions.py b/worlds/sc2/regions.py new file mode 100644 index 000000000000..26d127a1c5e9 --- /dev/null +++ b/worlds/sc2/regions.py @@ -0,0 +1,532 @@ +from typing import TYPE_CHECKING, List, Dict, Any, Tuple, Optional + +from Options import OptionError +from .locations import LocationData, Location +from .mission_tables import ( + SC2Mission, SC2Campaign, MissionFlag, get_campaign_goal_priority, + campaign_final_mission_locations, campaign_alt_final_mission_locations +) +from .options import ( + ShuffleNoBuild, RequiredTactics, ShuffleCampaigns, + kerrigan_unit_available, TakeOverAIAllies, MissionOrder, get_excluded_missions, get_enabled_campaigns, + static_mission_orders, + TwoStartPositions, KeyMode, EnableMissionRaceBalancing, EnableRaceSwapVariants, NovaGhostOfAChanceVariant, + WarCouncilNerfs, GrantStoryTech +) +from .mission_order.options import CustomMissionOrder +from .mission_order import SC2MissionOrder +from .mission_order.nodes import SC2MOGenMissionOrder, Difficulty +from .mission_order.mission_pools import SC2MOGenMissionPools +from .mission_order.generation import resolve_unlocks, fill_depths, resolve_difficulties, fill_missions, make_connections, resolve_generic_keys + +if TYPE_CHECKING: + from . import SC2World + + +def create_mission_order( + world: 'SC2World', locations: Tuple[LocationData, ...], location_cache: List[Location] +): + # 'locations' contains both actual game locations and beat event locations for all mission regions + # When a region (mission) is accessible, all its locations are potentially accessible + # Accessible in this context always means "its access rule evaluates to True" + # This includes the beat events, which copy the access rules of the victory locations + # Beat events being added to logical inventory is auto-magic: + # Event locations contain an event item of (by default) identical name, + # which Archipelago's generator will consider part of the logical inventory + # whenever the event location becomes accessible + + # Set up mission pools + mission_pools = SC2MOGenMissionPools() + mission_pools.set_exclusions(get_excluded_missions(world), []) # TODO set unexcluded + adjust_mission_pools(world, mission_pools) + setup_mission_pool_balancing(world, mission_pools) + + mission_order_type = world.options.mission_order + if mission_order_type == MissionOrder.option_custom: + mission_order_dict = world.options.custom_mission_order.value + else: + mission_order_option = create_regular_mission_order(world, mission_pools) + if mission_order_type in static_mission_orders: + # Static orders get converted early to curate preset content, so it can be used as-is + mission_order_dict = mission_order_option + else: + mission_order_dict = CustomMissionOrder(mission_order_option).value + mission_order = SC2MOGenMissionOrder(world, mission_order_dict) + + # Set up requirements for individual parts of the mission order + resolve_unlocks(mission_order) + + # Ensure total accessibilty and resolve relative difficulties + fill_depths(mission_order) + resolve_difficulties(mission_order) + + # Build the mission order + fill_missions(mission_order, mission_pools, world, [], locations, location_cache) # TODO set locked missions + make_connections(mission_order, world) + + # Fill in Key requirements now that missions are placed + resolve_generic_keys(mission_order) + + return SC2MissionOrder(mission_order, mission_pools) + +def adjust_mission_pools(world: 'SC2World', pools: SC2MOGenMissionPools): + # Mission pool changes + mission_order_type = world.options.mission_order.value + enabled_campaigns = get_enabled_campaigns(world) + adv_tactics = world.options.required_tactics.value != RequiredTactics.option_standard + shuffle_no_build = world.options.shuffle_no_build.value + extra_locations = world.options.extra_locations.value + grant_story_tech = world.options.grant_story_tech.value + grant_story_levels = world.options.grant_story_levels.value + war_council_nerfs = world.options.war_council_nerfs.value == WarCouncilNerfs.option_true + + # WoL + if shuffle_no_build == ShuffleNoBuild.option_false or adv_tactics: + # Replacing No Build missions with Easy missions + # WoL + pools.move_mission(SC2Mission.ZERO_HOUR, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.EVACUATION, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.EVACUATION_Z, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.EVACUATION_P, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.DEVILS_PLAYGROUND, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.DEVILS_PLAYGROUND_Z, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.DEVILS_PLAYGROUND_P, Difficulty.EASY, Difficulty.STARTER) + if world.options.required_tactics != RequiredTactics.option_any_units: + # Per playtester feedback: doing this mission with only one unit is flaky + # but there are enough viable comps that >= 2 random units is probably workable + pools.move_mission(SC2Mission.THE_GREAT_TRAIN_ROBBERY, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.THE_GREAT_TRAIN_ROBBERY_Z, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.THE_GREAT_TRAIN_ROBBERY_P, Difficulty.EASY, Difficulty.STARTER) + # LotV + pools.move_mission(SC2Mission.THE_GROWING_SHADOW, Difficulty.EASY, Difficulty.STARTER) + if shuffle_no_build == ShuffleNoBuild.option_false: + # Pushing Outbreak to Normal, as it cannot be placed as the second mission on Build-Only + pools.move_mission(SC2Mission.OUTBREAK, Difficulty.EASY, Difficulty.MEDIUM) + # Pushing extra Normal missions to Easy + pools.move_mission(SC2Mission.ECHOES_OF_THE_FUTURE, Difficulty.MEDIUM, Difficulty.EASY) + pools.move_mission(SC2Mission.CUTTHROAT, Difficulty.MEDIUM, Difficulty.EASY) + # Additional changes on Advanced Tactics + if adv_tactics: + # WoL + pools.move_mission(SC2Mission.SMASH_AND_GRAB, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.THE_MOEBIUS_FACTOR, Difficulty.MEDIUM, Difficulty.EASY) + pools.move_mission(SC2Mission.THE_MOEBIUS_FACTOR_Z, Difficulty.MEDIUM, Difficulty.EASY) + pools.move_mission(SC2Mission.THE_MOEBIUS_FACTOR_P, Difficulty.MEDIUM, Difficulty.EASY) + pools.move_mission(SC2Mission.WELCOME_TO_THE_JUNGLE, Difficulty.MEDIUM, Difficulty.EASY) + pools.move_mission(SC2Mission.ENGINE_OF_DESTRUCTION, Difficulty.HARD, Difficulty.MEDIUM) + # Prophecy needs to be adjusted if by itself + if enabled_campaigns == {SC2Campaign.PROPHECY}: + pools.move_mission(SC2Mission.A_SINISTER_TURN, Difficulty.MEDIUM, Difficulty.EASY) + # Prologue's only valid starter is the goal mission + if enabled_campaigns == {SC2Campaign.PROLOGUE} \ + or mission_order_type in static_mission_orders \ + and world.options.shuffle_campaigns.value == ShuffleCampaigns.option_false: + pools.move_mission(SC2Mission.DARK_WHISPERS, Difficulty.EASY, Difficulty.STARTER) + # HotS + kerriganless = world.options.kerrigan_presence.value not in kerrigan_unit_available \ + or SC2Campaign.HOTS not in enabled_campaigns + if grant_story_tech == GrantStoryTech.option_grant: + # Additional starter mission if player is granted story tech + pools.move_mission(SC2Mission.ENEMY_WITHIN, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.TEMPLAR_S_RETURN, Difficulty.MEDIUM, Difficulty.STARTER) + pools.move_mission(SC2Mission.THE_ESCAPE, Difficulty.MEDIUM, Difficulty.STARTER) + pools.move_mission(SC2Mission.IN_THE_ENEMY_S_SHADOW, Difficulty.MEDIUM, Difficulty.STARTER) + if not war_council_nerfs: + pools.move_mission(SC2Mission.TEMPLAR_S_RETURN, Difficulty.MEDIUM, Difficulty.STARTER) + if (grant_story_tech == GrantStoryTech.option_grant and grant_story_levels) or kerriganless: + # The player has, all the stuff he needs, provided under these settings + pools.move_mission(SC2Mission.SUPREME, Difficulty.MEDIUM, Difficulty.STARTER) + pools.move_mission(SC2Mission.THE_INFINITE_CYCLE, Difficulty.HARD, Difficulty.STARTER) + pools.move_mission(SC2Mission.CONVICTION, Difficulty.MEDIUM, Difficulty.STARTER) + if (grant_story_tech != GrantStoryTech.option_grant + and ( + world.options.nova_ghost_of_a_chance_variant == NovaGhostOfAChanceVariant.option_nco + or ( + SC2Campaign.NCO in enabled_campaigns + and world.options.nova_ghost_of_a_chance_variant.value == NovaGhostOfAChanceVariant.option_auto + ) + ) + ): + # Using NCO tech for this mission that must be acquired + pools.move_mission(SC2Mission.GHOST_OF_A_CHANCE, Difficulty.STARTER, Difficulty.MEDIUM) + if world.options.take_over_ai_allies.value == TakeOverAIAllies.option_true: + pools.move_mission(SC2Mission.HARBINGER_OF_OBLIVION, Difficulty.MEDIUM, Difficulty.STARTER) + if pools.get_pool_size(Difficulty.STARTER) < 2 and not kerriganless or adv_tactics: + # Conditionally moving Easy missions to Starter + pools.move_mission(SC2Mission.HARVEST_OF_SCREAMS, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.DOMINATION, Difficulty.EASY, Difficulty.STARTER) + if pools.get_pool_size(Difficulty.STARTER) < 2: + pools.move_mission(SC2Mission.DOMINATION, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.DOMINATION_T, Difficulty.EASY, Difficulty.STARTER) + pools.move_mission(SC2Mission.DOMINATION_P, Difficulty.EASY, Difficulty.STARTER) + if pools.get_pool_size(Difficulty.STARTER) + pools.get_pool_size(Difficulty.EASY) < 2: + # Flashpoint needs just a few items at start but competent comp at the end + pools.move_mission(SC2Mission.FLASHPOINT, Difficulty.HARD, Difficulty.EASY) + +def setup_mission_pool_balancing(world: 'SC2World', pools: SC2MOGenMissionPools): + race_mission_balance = world.options.mission_race_balancing.value + flag_ratios: Dict[MissionFlag, int] = {} + flag_weights: Dict[MissionFlag, int] = {} + if race_mission_balance == EnableMissionRaceBalancing.option_semi_balanced: + flag_weights = { MissionFlag.Terran: 1, MissionFlag.Zerg: 1, MissionFlag.Protoss: 1 } + elif race_mission_balance == EnableMissionRaceBalancing.option_fully_balanced: + flag_ratios = { MissionFlag.Terran: 1, MissionFlag.Zerg: 1, MissionFlag.Protoss: 1 } + pools.set_flag_balances(flag_ratios, flag_weights) + +def create_regular_mission_order(world: 'SC2World', mission_pools: SC2MOGenMissionPools) -> Dict[str, Dict[str, Any]]: + mission_order_type = world.options.mission_order.value + + if mission_order_type in static_mission_orders: + return create_static_mission_order(world, mission_order_type, mission_pools) + else: + return create_dynamic_mission_order(world, mission_order_type, mission_pools) + +def create_static_mission_order(world: 'SC2World', mission_order_type: int, mission_pools: SC2MOGenMissionPools) -> Dict[str, Dict[str, Any]]: + mission_order: Dict[str, Dict[str, Any]] = {} + + enabled_campaigns = get_enabled_campaigns(world) + if mission_order_type == MissionOrder.option_vanilla: + missions = "vanilla" + elif world.options.shuffle_campaigns.value == ShuffleCampaigns.option_true: + missions = "random" + else: + missions = "vanilla_shuffled" + + if world.options.enable_race_swap.value == EnableRaceSwapVariants.option_disabled: + shuffle_raceswaps = False + else: + # Picking specific raceswap variants is handled by mission exclusion + shuffle_raceswaps = True + + key_mode_option = world.options.key_mode.value + if key_mode_option == KeyMode.option_missions: + keys = "missions" + elif key_mode_option == KeyMode.option_questlines: + keys = "layouts" + elif key_mode_option == KeyMode.option_progressive_missions: + keys = "progressive_missions" + elif key_mode_option == KeyMode.option_progressive_questlines: + keys = "progressive_layouts" + elif key_mode_option == KeyMode.option_progressive_per_questline: + keys = "progressive_per_layout" + else: + keys = "none" + + if mission_order_type == MissionOrder.option_mini_campaign: + prefix = "mini " + else: + prefix = "" + + def mission_order_preset(name: str) -> Dict[str, str]: + return { + "preset": prefix + name, + "missions": missions, + "shuffle_raceswaps": shuffle_raceswaps, + "keys": keys + } + + prophecy_enabled = SC2Campaign.PROPHECY in enabled_campaigns + wol_enabled = SC2Campaign.WOL in enabled_campaigns + if wol_enabled: + mission_order[SC2Campaign.WOL.campaign_name] = mission_order_preset("wol") + + if prophecy_enabled: + mission_order[SC2Campaign.PROPHECY.campaign_name] = mission_order_preset("prophecy") + + if SC2Campaign.HOTS in enabled_campaigns: + mission_order[SC2Campaign.HOTS.campaign_name] = mission_order_preset("hots") + + if SC2Campaign.PROLOGUE in enabled_campaigns: + mission_order[SC2Campaign.PROLOGUE.campaign_name] = mission_order_preset("prologue") + + if SC2Campaign.LOTV in enabled_campaigns: + mission_order[SC2Campaign.LOTV.campaign_name] = mission_order_preset("lotv") + + if SC2Campaign.EPILOGUE in enabled_campaigns: + mission_order[SC2Campaign.EPILOGUE.campaign_name] = mission_order_preset("epilogue") + entry_rules = [] + if SC2Campaign.WOL in enabled_campaigns: + entry_rules.append({ "scope": SC2Campaign.WOL.campaign_name }) + if SC2Campaign.HOTS in enabled_campaigns: + entry_rules.append({ "scope": SC2Campaign.HOTS.campaign_name }) + if SC2Campaign.LOTV in enabled_campaigns: + entry_rules.append({ "scope": SC2Campaign.LOTV.campaign_name }) + mission_order[SC2Campaign.EPILOGUE.campaign_name]["entry_rules"] = entry_rules + + if SC2Campaign.NCO in enabled_campaigns: + mission_order[SC2Campaign.NCO.campaign_name] = mission_order_preset("nco") + + # Resolve immediately so the layout updates are simpler + mission_order = CustomMissionOrder(mission_order).value + + # WoL requirements should count missions from Prophecy if both are enabled, and Prophecy should require a WoL mission + # There is a preset that already does this, but special-casing this way is easier to work with for other code + if wol_enabled and prophecy_enabled: + fix_wol_prophecy_entry_rules(mission_order) + + # Vanilla Shuffled is allowed to drop some slots + if mission_order_type == MissionOrder.option_vanilla_shuffled: + remove_missions(world, mission_order, mission_pools) + + # Curate final missions and goal campaigns + force_final_missions(world, mission_order, mission_order_type) + + return mission_order + + +def fix_wol_prophecy_entry_rules(mission_order: Dict[str, Dict[str, Any]]): + prophecy_name = SC2Campaign.PROPHECY.campaign_name + + # Make the mission count entry rules in WoL also count Prophecy + def fix_entry_rule(entry_rule: Dict[str, Any], local_campaign_scope: str): + # This appends Prophecy to any scope that points at the local campaign (WoL) + if "scope" in entry_rule: + if entry_rule["scope"] == local_campaign_scope: + entry_rule["scope"] = [local_campaign_scope, prophecy_name] + elif isinstance(entry_rule["scope"], list) and local_campaign_scope in entry_rule["scope"]: + entry_rule["scope"] = entry_rule["scope"] + [prophecy_name] + + for layout_dict in mission_order[SC2Campaign.WOL.campaign_name].values(): + if not isinstance(layout_dict, dict): + continue + if "entry_rules" in layout_dict: + for entry_rule in layout_dict["entry_rules"]: + fix_entry_rule(entry_rule, "..") + if "missions" in layout_dict: + for mission_dict in layout_dict["missions"]: + if "entry_rules" in mission_dict: + for entry_rule in mission_dict["entry_rules"]: + fix_entry_rule(entry_rule, "../..") + + # Make Prophecy require Artifact's second mission + mission_order[prophecy_name][prophecy_name]["entry_rules"] = [{ "scope": [f"{SC2Campaign.WOL.campaign_name}/Artifact/1"]}] + + +def force_final_missions(world: 'SC2World', mission_order: Dict[str, Dict[str, Any]], mission_order_type: int): + goal_mission: Optional[SC2Mission] = None + excluded_missions = get_excluded_missions(world) + enabled_campaigns = get_enabled_campaigns(world) + raceswap_variants = [mission for mission in SC2Mission if mission.flags & MissionFlag.RaceSwap] + # Prefer long campaigns over shorter ones and harder missions over easier ones + goal_priorities = {campaign: get_campaign_goal_priority(campaign, excluded_missions) for campaign in enabled_campaigns} + goal_level = max(goal_priorities.values()) + candidate_campaigns: List[SC2Campaign] = [campaign for campaign, goal_priority in goal_priorities.items() if goal_priority == goal_level] + candidate_campaigns.sort(key=lambda it: it.id) + + # Vanilla Shuffled & Mini Campaign get a curated final mission + if mission_order_type != MissionOrder.option_vanilla: + for goal_campaign in candidate_campaigns: + primary_goal = campaign_final_mission_locations[goal_campaign] + if primary_goal is None or primary_goal.mission in excluded_missions: + # No primary goal or its mission is excluded + candidate_missions = list(campaign_alt_final_mission_locations[goal_campaign].keys()) + # Also allow raceswaps of curated final missions, provided they're not excluded + for candidate_with_raceswaps in [mission for mission in candidate_missions if mission.flags & MissionFlag.HasRaceSwap]: + raceswap_candidates = [mission for mission in raceswap_variants if mission.map_file == candidate_with_raceswaps.map_file] + candidate_missions.extend(raceswap_candidates) + candidate_missions = [mission for mission in candidate_missions if mission not in excluded_missions] + if len(candidate_missions) == 0: + raise OptionError(f"There are no valid goal missions for campaign {goal_campaign.campaign_name}. Please exclude fewer missions.") + goal_mission = world.random.choice(candidate_missions) + else: + goal_mission = primary_goal.mission + + # The goal layout for static presets is the layout corresponding to the last key + goal_layout = list(mission_order[goal_campaign.campaign_name].keys())[-1] + goal_index = mission_order[goal_campaign.campaign_name][goal_layout]["size"] - 1 + mission_order[goal_campaign.campaign_name][goal_layout]["missions"].append({ + "index": [goal_index], + "mission_pool": [goal_mission.id] + }) + + # Remove goal status from lower priority campaigns + for campaign in enabled_campaigns: + if campaign not in candidate_campaigns: + mission_order[campaign.campaign_name]["goal"] = False + +def remove_missions(world: 'SC2World', mission_order: Dict[str, Dict[str, Any]], mission_pools: SC2MOGenMissionPools): + enabled_campaigns = get_enabled_campaigns(world) + removed_counts: Dict[SC2Campaign, Dict[str, int]] = {} + for campaign in enabled_campaigns: + # Count missing missions for each campaign individually + campaign_size = sum(layout["size"] for layout in mission_order[campaign.campaign_name].values() if type(layout) == dict) + allowed_missions = mission_pools.count_allowed_missions(campaign) + removal_count = campaign_size - allowed_missions + if removal_count > len(removal_priorities[campaign]): + raise OptionError(f"Too many missions of campaign {campaign.campaign_name} excluded, cannot fill vanilla shuffled mission order.") + for layout in removal_priorities[campaign][:removal_count]: + removed_counts.setdefault(campaign, {}).setdefault(layout, 0) + removed_counts[campaign][layout] += 1 + mission_order[campaign.campaign_name][layout]["size"] -= 1 + + # Fix mission indices & nexts + for (campaign, layouts) in removed_counts.items(): + for (layout, amount) in layouts.items(): + new_size = mission_order[campaign.campaign_name][layout]["size"] + original_size = new_size + amount + for removed_idx in range(new_size, original_size): + for mission in mission_order[campaign.campaign_name][layout]["missions"]: + if "index" in mission and removed_idx in mission["index"]: + mission["index"].remove(removed_idx) + if "next" in mission and removed_idx in mission["next"]: + mission["next"].remove(removed_idx) + + # Special cases + if SC2Campaign.WOL in removed_counts: + if "Char" in removed_counts[SC2Campaign.WOL]: + # Remove the first two mission changes that create the branching path + mission_order[SC2Campaign.WOL.campaign_name]["Char"]["missions"] = mission_order[SC2Campaign.WOL.campaign_name]["Char"]["missions"][2:] + if SC2Campaign.NCO in removed_counts: + # Remove the whole last layout if its size is 0 + if "Mission Pack 3" in removed_counts[SC2Campaign.NCO] and removed_counts[SC2Campaign.NCO]["Mission Pack 3"] == 3: + mission_order[SC2Campaign.NCO.campaign_name].pop("Mission Pack 3") + +removal_priorities: Dict[SC2Campaign, List[str]] = { + SC2Campaign.WOL: [ + "Colonist", + "Covert", + "Covert", + "Char", + "Rebellion", + "Artifact", + "Artifact", + "Rebellion" + ], + SC2Campaign.PROPHECY: [ + "Prophecy", + "Prophecy" + ], + SC2Campaign.HOTS: [ + "Umoja", + "Kaldir", + "Char", + "Zerus", + "Skygeirr Station" + ], + SC2Campaign.PROLOGUE: [ + "Prologue", + ], + SC2Campaign.LOTV: [ + "Ulnar", + "Return to Aiur", + "Aiur", + "Tal'darim", + "Purifier", + "Shakuras", + "Korhal" + ], + SC2Campaign.EPILOGUE: [ + "Epilogue", + ], + SC2Campaign.NCO: [ + "Mission Pack 3", + "Mission Pack 3", + "Mission Pack 2", + "Mission Pack 2", + "Mission Pack 1", + "Mission Pack 1", + "Mission Pack 3" + ] +} + +def make_grid(world: 'SC2World', size: int) -> Dict[str, Dict[str, Any]]: + mission_order = { + "grid": { + "display_name": "", + "type": "grid", + "size": size, + "two_start_positions": world.options.two_start_positions.value == TwoStartPositions.option_true + } + } + return mission_order + +def make_golden_path(world: 'SC2World', size: int) -> Dict[str, Dict[str, Any]]: + key_mode = world.options.key_mode.value + if key_mode == KeyMode.option_missions: + keys = "missions" + elif key_mode == KeyMode.option_questlines: + keys = "layouts" + elif key_mode == KeyMode.option_progressive_missions: + keys = "progressive_missions" + elif key_mode == KeyMode.option_progressive_questlines: + keys = "progressive_layouts" + elif key_mode == KeyMode.option_progressive_per_questline: + keys = "progressive_per_layout" + else: + keys = "none" + + mission_order = { + "golden path": { + "display_name": "", + "preset": "golden path", + "size": size, + "keys": keys, + "two_start_positions": world.options.two_start_positions.value == TwoStartPositions.option_true + } + } + return mission_order + +def make_gauntlet(size: int) -> Dict[str, Dict[str, Any]]: + mission_order = { + "gauntlet": { + "display_name": "", + "type": "gauntlet", + "size": size, + } + } + return mission_order + +def make_blitz(size: int) -> Dict[str, Dict[str, Any]]: + mission_order = { + "blitz": { + "display_name": "", + "type": "blitz", + "size": size, + } + } + return mission_order + +def make_hopscotch(world: 'SC2World', size: int) -> Dict[str, Dict[str, Any]]: + mission_order = { + "hopscotch": { + "display_name": "", + "type": "hopscotch", + "size": size, + "two_start_positions": world.options.two_start_positions.value == TwoStartPositions.option_true + } + } + return mission_order + +def create_dynamic_mission_order(world: 'SC2World', mission_order_type: int, mission_pools: SC2MOGenMissionPools) -> Dict[str, Dict[str, Any]]: + num_missions = min(mission_pools.get_allowed_mission_count(), world.options.maximum_campaign_size.value) + num_missions = max(1, num_missions) + if mission_order_type == MissionOrder.option_golden_path: + return make_golden_path(world, num_missions) + + if mission_order_type == MissionOrder.option_grid: + mission_order = make_grid(world, num_missions) + elif mission_order_type == MissionOrder.option_gauntlet: + mission_order = make_gauntlet(num_missions) + elif mission_order_type == MissionOrder.option_blitz: + mission_order = make_blitz(num_missions) + elif mission_order_type == MissionOrder.option_hopscotch: + mission_order = make_hopscotch(world, num_missions) + else: + raise ValueError("Received unknown Mission Order type") + + # Optionally add key requirements + # This only works for layout types that don't define their own entry rules (which is currently all of them) + # Golden Path handles Key Mode on its own + key_mode = world.options.key_mode.value + if key_mode == KeyMode.option_missions: + mission_order[list(mission_order.keys())[0]]["missions"] = [ + { "index": "all", "entry_rules": [{ "items": { "Key": 1 }}] }, + { "index": "entrances", "entry_rules": [] } + ] + elif key_mode == KeyMode.option_progressive_missions: + mission_order[list(mission_order.keys())[0]]["missions"] = [ + { "index": "all", "entry_rules": [{ "items": { "Progressive Key": 1 }}] }, + { "index": "entrances", "entry_rules": [] } + ] + + return mission_order diff --git a/worlds/sc2/rules.py b/worlds/sc2/rules.py new file mode 100644 index 000000000000..030725946d83 --- /dev/null +++ b/worlds/sc2/rules.py @@ -0,0 +1,3582 @@ +from math import floor +from typing import TYPE_CHECKING, Set, Optional, Callable, Dict, Tuple, Iterable + +from BaseClasses import CollectionState, Location +from .item.item_groups import kerrigan_non_ulimates, kerrigan_logic_active_abilities +from .item.item_names import PROGRESSIVE_PROTOSS_AIR_WEAPON, PROGRESSIVE_PROTOSS_AIR_ARMOR, PROGRESSIVE_PROTOSS_SHIELDS +from .options import ( + RequiredTactics, + kerrigan_unit_available, + AllInMap, + GrantStoryTech, + GrantStoryLevels, + SpearOfAdunPassiveAbilityPresence, + SpearOfAdunPresence, + MissionOrder, + EnableMorphling, + NovaGhostOfAChanceVariant, + get_enabled_campaigns, + get_enabled_races, +) +from .item.item_tables import ( + tvx_defense_ratings, + tvz_defense_ratings, + tvx_air_defense_ratings, + kerrigan_levels, + get_full_item_list, + zvx_air_defense_ratings, + zvx_defense_ratings, + pvx_defense_ratings, + pvz_defense_ratings, + no_logic_basic_units, + advanced_basic_units, + basic_units, + upgrade_bundle_inverted_lookup, + WEAPON_ARMOR_UPGRADE_MAX_LEVEL, + soa_ultimate_ratings, + soa_energy_ratings, + terran_passive_ratings, + soa_passive_ratings, + zerg_passive_ratings, + protoss_passive_ratings, +) +from .mission_tables import SC2Race, SC2Campaign +from .item import item_groups, item_names + +if TYPE_CHECKING: + from . import SC2World + + +class SC2Logic: + def __init__(self, world: Optional["SC2World"]): + # Note: Don't store a reference to the world so we can cache this object on the world object + self.player = -1 if world is None else world.player + self.logic_level: int = world.options.required_tactics.value if world else RequiredTactics.default + self.advanced_tactics = self.logic_level != RequiredTactics.option_standard + self.take_over_ai_allies = bool(world and world.options.take_over_ai_allies) + self.kerrigan_unit_available = ( + (True if world is None else (world.options.kerrigan_presence.value in kerrigan_unit_available)) + and SC2Campaign.HOTS in get_enabled_campaigns(world) + and SC2Race.ZERG in get_enabled_races(world) + ) + self.kerrigan_levels_per_mission_completed = 0 if world is None else world.options.kerrigan_levels_per_mission_completed.value + self.kerrigan_levels_per_mission_completed_cap = -1 if world is None else world.options.kerrigan_levels_per_mission_completed_cap.value + self.kerrigan_total_level_cap = -1 if world is None else world.options.kerrigan_total_level_cap.value + self.morphling_enabled = False if world is None else (world.options.enable_morphling.value == EnableMorphling.option_true) + self.grant_story_tech = GrantStoryTech.option_no_grant if world is None else (world.options.grant_story_tech.value) + self.story_levels_granted = False if world is None else (world.options.grant_story_levels.value != GrantStoryLevels.option_disabled) + self.basic_terran_units = get_basic_units(self.logic_level, SC2Race.TERRAN) + self.basic_zerg_units = get_basic_units(self.logic_level, SC2Race.ZERG) + self.basic_protoss_units = get_basic_units(self.logic_level, SC2Race.PROTOSS) + self.spear_of_adun_presence = SpearOfAdunPresence.default if world is None else world.options.spear_of_adun_presence.value + self.spear_of_adun_passive_presence = ( + SpearOfAdunPassiveAbilityPresence.default if world is None else world.options.spear_of_adun_passive_ability_presence.value + ) + self.enabled_campaigns = get_enabled_campaigns(world) + self.mission_order = MissionOrder.default if world is None else world.options.mission_order.value + self.generic_upgrade_missions = 0 if world is None else world.options.generic_upgrade_missions.value + self.all_in_map = AllInMap.option_ground if world is None else world.options.all_in_map.value + self.nova_ghost_of_a_chance_variant = NovaGhostOfAChanceVariant.option_wol if world is None else world.options.nova_ghost_of_a_chance_variant.value + self.war_council_upgrades = True if world is None else not world.options.war_council_nerfs.value + self.base_power_rating = 2 if self.advanced_tactics else 0 + + # Must be set externally for accurate logic checking of upgrade level when generic_upgrade_missions is checked + self.total_mission_count = 1 + + # Must be set externally + self.nova_used = True + + # Conditionally set to False by the world after culling items + self.has_barracks_unit: bool = True + self.has_factory_unit: bool = True + self.has_starport_unit: bool = True + self.has_zerg_melee_unit: bool = True + self.has_zerg_ranged_unit: bool = True + self.has_zerg_air_unit: bool = True + self.has_protoss_ground_unit: bool = True + self.has_protoss_air_unit: bool = True + + self.unit_count_functions: Dict[Tuple[SC2Race, int], Callable[[CollectionState], bool]] = {} + """Cache of logic functions used by any_units logic level""" + + # Super Globals + + def is_item_placement(self, state: CollectionState) -> bool: + """ + Tells if it's item placement or item pool filter + :return: True for item placement, False for pool filter + """ + # has_group with count = 0 is always true for item placement and always false for SC2 item filtering + return state.has_group("Missions", self.player, 0) + + def get_very_hard_required_upgrade_level(self): + return 2 if self.advanced_tactics else 3 + + def weapon_armor_upgrade_count(self, upgrade_item: str, state: CollectionState) -> int: + assert upgrade_item in upgrade_bundle_inverted_lookup.keys() + count: int = 0 + if self.generic_upgrade_missions > 0: + if (not self.is_item_placement(state)) or self.logic_level == RequiredTactics.option_no_logic: + # Item pool filtering, W/A upgrades aren't items + # No Logic: Don't care about W/A in this case + return WEAPON_ARMOR_UPGRADE_MAX_LEVEL + else: + count += floor((100 / self.generic_upgrade_missions) * (state.count_group("Missions", self.player) / self.total_mission_count)) + count += state.count(upgrade_item, self.player) + count += state.count_from_list(upgrade_bundle_inverted_lookup[upgrade_item], self.player) + if upgrade_item == item_names.PROGRESSIVE_PROTOSS_SHIELDS: + count += max( + state.count(item_names.PROGRESSIVE_PROTOSS_GROUND_UPGRADE, self.player), + state.count(item_names.PROGRESSIVE_PROTOSS_AIR_UPGRADE, self.player), + ) + if upgrade_item in item_groups.protoss_generic_upgrades and state.has(item_names.QUATRO, self.player): + count += 1 + return count + + def soa_power_rating(self, state: CollectionState): + power_rating = 0 + # Spear of Adun Ultimates (Strongest) + for item, rating in soa_ultimate_ratings.items(): + if state.has(item, self.player): + power_rating += rating + break + # Spear of Adun ability that consumes energy (Strongest, then second strongest) + found_main_weapon = False + for item, rating in soa_energy_ratings.items(): + count = 1 + if item == item_names.SOA_PROGRESSIVE_PROXY_PYLON: + count = 2 + if state.has(item, self.player, count): + if not found_main_weapon: + power_rating += rating + found_main_weapon = True + else: + power_rating += rating // 2 + break + # Mass Recall (Negligible energy cost) + if state.has(item_names.SOA_MASS_RECALL, self.player): + power_rating += 2 + return power_rating + + # Global Terran + + def terran_power_rating(self, state: CollectionState) -> int: + power_score = self.base_power_rating + # Passive Score (Economic upgrades and global army upgrades) + power_score += sum((rating for item, rating in terran_passive_ratings.items() if state.has(item, self.player))) + # Spear of Adun + if self.spear_of_adun_presence == SpearOfAdunPresence.option_everywhere: + power_score += self.soa_power_rating(state) + if self.spear_of_adun_passive_presence == SpearOfAdunPassiveAbilityPresence.option_everywhere: + power_score += sum((rating for item, rating in soa_passive_ratings.items() if state.has(item, self.player))) + return power_score + + def terran_army_weapon_armor_upgrade_min_level(self, state: CollectionState) -> int: + """ + Minimum W/A upgrade level for unit classes present in the world + """ + count: int = WEAPON_ARMOR_UPGRADE_MAX_LEVEL + if self.has_barracks_unit: + count = min( + count, + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, state), + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR, state), + ) + if self.has_factory_unit: + count = min( + count, + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, state), + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR, state), + ) + if self.has_starport_unit: + count = min( + count, + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, state), + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR, state), + ) + return count + + def terran_very_hard_mission_weapon_armor_level(self, state: CollectionState) -> bool: + return self.terran_army_weapon_armor_upgrade_min_level(state) >= self.get_very_hard_required_upgrade_level() + + # WoL + def terran_common_unit(self, state: CollectionState) -> bool: + return state.has_any(self.basic_terran_units, self.player) + + def terran_early_tech(self, state: CollectionState): + """ + Basic combat unit that can be deployed quickly from mission start + :param state + :return: + """ + return state.has_any( + {item_names.MARINE, item_names.DOMINION_TROOPER, item_names.FIREBAT, item_names.MARAUDER, item_names.REAPER, item_names.HELLION}, + self.player, + ) or ( + self.advanced_tactics and state.has_any({item_names.GOLIATH, item_names.DIAMONDBACK, item_names.VIKING, item_names.BANSHEE}, self.player) + ) + + def terran_air(self, state: CollectionState) -> bool: + """ + Air units or drops on advanced tactics + """ + return ( + state.has_any({item_names.VIKING, item_names.WRAITH, item_names.BANSHEE, item_names.BATTLECRUISER}, self.player) + or state.has_all((item_names.VALKYRIE, item_names.VALKYRIE_FLECHETTE_MISSILES), self.player) + or state.has_all((item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY), self.player) + or ( + self.advanced_tactics + and ( + (state.has_any({item_names.HERCULES, item_names.MEDIVAC}, self.player) and self.terran_common_unit(state)) + or (state.has_all((item_names.RAVEN, item_names.RAVEN_HUNTER_SEEKER_WEAPON), self.player)) + ) + ) + ) + + def terran_air_anti_air(self, state: CollectionState) -> bool: + """ + Air-to-air + """ + return ( + state.has(item_names.VIKING, self.player) + or state.has_all({item_names.WRAITH, item_names.WRAITH_ADVANCED_LASER_TECHNOLOGY}, self.player) + or state.has_all({item_names.BATTLECRUISER, item_names.BATTLECRUISER_ATX_LASER_BATTERY}, self.player) + or ( + self.advanced_tactics + and state.has_any({item_names.WRAITH, item_names.VALKYRIE, item_names.BATTLECRUISER}, self.player) + and self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, state) >= 2 + ) + ) + + def terran_any_air_unit(self, state: CollectionState) -> bool: + return state.has_any( + { + item_names.VIKING, + item_names.MEDIVAC, + item_names.RAVEN, + item_names.BANSHEE, + item_names.SCIENCE_VESSEL, + item_names.BATTLECRUISER, + item_names.WRAITH, + item_names.HERCULES, + item_names.LIBERATOR, + item_names.VALKYRIE, + item_names.SKY_FURY, + item_names.NIGHT_HAWK, + item_names.EMPERORS_GUARDIAN, + item_names.NIGHT_WOLF, + item_names.PRIDE_OF_AUGUSTRGRAD, + }, + self.player, + ) + + def terran_competent_ground_to_air(self, state: CollectionState) -> bool: + """ + Ground-to-air + """ + return ( + state.has(item_names.GOLIATH, self.player) + or ( + state.has_any({item_names.MARINE, item_names.DOMINION_TROOPER}, self.player) + and self.terran_bio_heal(state) + and self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, state) >= 2 + ) + or self.advanced_tactics + and ( + state.has(item_names.CYCLONE, self.player) + or state.has_all((item_names.THOR, item_names.THOR_PROGRESSIVE_HIGH_IMPACT_PAYLOAD), self.player) + ) + ) + + def terran_competent_anti_air(self, state: CollectionState) -> bool: + """ + Good AA unit + """ + return self.terran_competent_ground_to_air(state) or self.terran_air_anti_air(state) + + def terran_any_anti_air(self, state: CollectionState) -> bool: + return ( + state.has_any( + ( + # Barracks + item_names.MARINE, + item_names.WAR_PIGS, + item_names.SON_OF_KORHAL, + item_names.DOMINION_TROOPER, + item_names.GHOST, + item_names.SPECTRE, + item_names.EMPERORS_SHADOW, + # Factory + item_names.GOLIATH, + item_names.SPARTAN_COMPANY, + item_names.BULWARK_COMPANY, + item_names.CYCLONE, + item_names.WIDOW_MINE, + item_names.THOR, + item_names.JOTUN, + item_names.BLACKHAMMER, + # Ships + item_names.WRAITH, + item_names.WINGED_NIGHTMARES, + item_names.NIGHT_HAWK, + item_names.VIKING, + item_names.HELS_ANGELS, + item_names.SKY_FURY, + item_names.LIBERATOR, + item_names.MIDNIGHT_RIDERS, + item_names.EMPERORS_GUARDIAN, + item_names.VALKYRIE, + item_names.BRYNHILDS, + item_names.BATTLECRUISER, + item_names.JACKSONS_REVENGE, + item_names.PRIDE_OF_AUGUSTRGRAD, + item_names.RAVEN, + # Buildings + item_names.MISSILE_TURRET, + ), + self.player, + ) + or state.has_all((item_names.REAPER, item_names.REAPER_JET_PACK_OVERDRIVE), self.player) + or state.has_all((item_names.PLANETARY_FORTRESS, item_names.PLANETARY_FORTRESS_IBIKS_TRACKING_SCANNERS), self.player) + or ( + state.has(item_names.MEDIVAC, self.player) + and state.has_any((item_names.SIEGE_TANK, item_names.SIEGE_BREAKERS, item_names.SHOCK_DIVISION), self.player) + and state.count(item_names.SIEGE_TANK_PROGRESSIVE_TRANSPORT_HOOK, self.player) >= 2 + ) + ) + + def terran_any_anti_air_or_science_vessels(self, state: CollectionState) -> bool: + return self.terran_any_anti_air(state) or state.has(item_names.SCIENCE_VESSEL, self.player) + + def terran_moderate_anti_air(self, state: CollectionState) -> bool: + return self.terran_competent_anti_air(state) or ( + state.has_any( + ( + item_names.MARINE, + item_names.DOMINION_TROOPER, + item_names.THOR, + item_names.CYCLONE, + item_names.BATTLECRUISER, + item_names.WRAITH, + item_names.VALKYRIE, + ), + self.player, + ) + or ( + state.has_all((item_names.MEDIVAC, item_names.SIEGE_TANK), self.player) + and state.count(item_names.SIEGE_TANK_PROGRESSIVE_TRANSPORT_HOOK, self.player) >= 2 + ) + or (self.advanced_tactics and state.has_any((item_names.GHOST, item_names.SPECTRE, item_names.LIBERATOR), self.player)) + ) + + def terran_basic_anti_air(self, state: CollectionState) -> bool: + """ + Basic AA to deal with few air units + """ + return ( + state.has_any( + ( + item_names.MISSILE_TURRET, + item_names.WAR_PIGS, + item_names.SPARTAN_COMPANY, + item_names.HELS_ANGELS, + item_names.WINGED_NIGHTMARES, + item_names.BRYNHILDS, + item_names.SKY_FURY, + item_names.SON_OF_KORHAL, + item_names.BULWARK_COMPANY, + ), + self.player, + ) + or self.terran_moderate_anti_air(state) + or self.advanced_tactics + and ( + state.has_any( + ( + item_names.WIDOW_MINE, + item_names.PRIDE_OF_AUGUSTRGRAD, + item_names.BLACKHAMMER, + item_names.EMPERORS_SHADOW, + item_names.EMPERORS_GUARDIAN, + item_names.NIGHT_HAWK, + ), + self.player, + ) + ) + ) + + def terran_defense_rating(self, state: CollectionState, zerg_enemy: bool, air_enemy: bool = True) -> int: + """ + Ability to handle defensive missions + :param state: + :param zerg_enemy: Whether the enemy is zerg + :param air_enemy: Whether the enemy attacks with air + :return: + """ + defense_score = sum((tvx_defense_ratings[item] for item in tvx_defense_ratings if state.has(item, self.player))) + # Manned Bunker + if state.has_any({item_names.MARINE, item_names.DOMINION_TROOPER, item_names.MARAUDER}, self.player) and state.has( + item_names.BUNKER, self.player + ): + defense_score += 3 + elif zerg_enemy and state.has(item_names.FIREBAT, self.player) and state.has(item_names.BUNKER, self.player): + defense_score += 2 + # Siege Tank upgrades + if state.has_all({item_names.SIEGE_TANK, item_names.SIEGE_TANK_MAELSTROM_ROUNDS}, self.player): + defense_score += 2 + if state.has_all({item_names.SIEGE_TANK, item_names.SIEGE_TANK_GRADUATING_RANGE}, self.player): + defense_score += 1 + # Widow Mine upgrade + if state.has_all({item_names.WIDOW_MINE, item_names.WIDOW_MINE_CONCEALMENT}, self.player): + defense_score += 1 + # Viking with splash + if state.has_all({item_names.VIKING, item_names.VIKING_SHREDDER_ROUNDS}, self.player): + defense_score += 2 + + # General enemy-based rules + if zerg_enemy: + defense_score += sum((tvz_defense_ratings[item] for item in tvz_defense_ratings if state.has(item, self.player))) + if air_enemy: + # Capped at 2 + defense_score += min(sum((tvx_air_defense_ratings[item] for item in tvx_air_defense_ratings if state.has(item, self.player))), 2) + if air_enemy and zerg_enemy and state.has(item_names.VALKYRIE, self.player): + # Valkyries shred mass Mutas, the most common air enemy that's massed in these cases + defense_score += 2 + # Advanced Tactics bumps defense rating requirements down by 2 + if self.advanced_tactics: + defense_score += 2 + return defense_score + + def terran_competent_comp(self, state: CollectionState) -> bool: + # All competent comps require anti-air + if not self.terran_competent_anti_air(state): + return False + # Infantry with Healing + infantry_weapons = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, state) + infantry_armor = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR, state) + infantry = state.has_any({item_names.MARINE, item_names.DOMINION_TROOPER, item_names.MARAUDER}, self.player) + if infantry_weapons >= 2 and infantry_armor >= 1 and infantry and self.terran_bio_heal(state): + return True + # Mass Air-To-Ground + ship_weapons = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, state) + ship_armor = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR, state) + if ship_weapons >= 1 and ship_armor >= 1: + air = ( + state.has_any({item_names.BANSHEE, item_names.BATTLECRUISER}, self.player) + or state.has_all({item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY}, self.player) + or state.has_all({item_names.WRAITH, item_names.WRAITH_ADVANCED_LASER_TECHNOLOGY}, self.player) + or state.has_all({item_names.VALKYRIE, item_names.VALKYRIE_FLECHETTE_MISSILES}, self.player) + and ship_weapons >= 2 + ) + if air and self.terran_mineral_dump(state): + return True + # Strong Mech + vehicle_weapons = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, state) + vehicle_armor = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR, state) + if vehicle_weapons >= 1 and vehicle_armor >= 1: + strong_vehicle = state.has_any({item_names.THOR, item_names.SIEGE_TANK}, self.player) + light_frontline = state.has_any( + {item_names.MARINE, item_names.DOMINION_TROOPER, item_names.HELLION, item_names.VULTURE}, self.player + ) or state.has_all({item_names.REAPER, item_names.REAPER_RESOURCE_EFFICIENCY}, self.player) + if strong_vehicle and light_frontline: + return True + # Mech with Healing + vehicle = state.has_any({item_names.GOLIATH, item_names.WARHOUND}, self.player) + micro_gas_vehicle = self.advanced_tactics and state.has_any({item_names.DIAMONDBACK, item_names.CYCLONE}, self.player) + if self.terran_sustainable_mech_heal(state) and (vehicle or (micro_gas_vehicle and light_frontline)): + return True + return False + + def terran_mineral_dump(self, state: CollectionState) -> bool: + """ + Can build something using only minerals + """ + return ( + state.has_any({item_names.MARINE, item_names.VULTURE, item_names.HELLION, item_names.SON_OF_KORHAL}, self.player) + or state.has_all({item_names.REAPER, item_names.REAPER_RESOURCE_EFFICIENCY}, self.player) + or (self.advanced_tactics and state.has_any({item_names.PERDITION_TURRET, item_names.DEVASTATOR_TURRET}, self.player)) + ) + + def terran_beats_protoss_deathball(self, state: CollectionState) -> bool: + """ + Ability to deal with Immortals, Colossi with some air support + """ + return ( + ( + state.has_any({item_names.BANSHEE, item_names.BATTLECRUISER}, self.player) + or state.has_all({item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY}, self.player) + ) + and self.terran_competent_anti_air(state) + or self.terran_competent_comp(state) + and self.terran_air_anti_air(state) + ) and self.terran_army_weapon_armor_upgrade_min_level(state) >= 2 + + def marine_medic_upgrade(self, state: CollectionState) -> bool: + """ + Infantry upgrade to infantry-only no-build segments + """ + return ( + state.has_any({item_names.MARINE_COMBAT_SHIELD, item_names.MARINE_MAGRAIL_MUNITIONS, item_names.MEDIC_STABILIZER_MEDPACKS}, self.player) + or (state.count(item_names.MARINE_PROGRESSIVE_STIMPACK, self.player) >= 2 and state.has_group("Missions", self.player, 1)) + or self.advanced_tactics + and state.has(item_names.MARINE_LASER_TARGETING_SYSTEM, self.player) + ) + + def marine_medic_firebat_upgrade(self, state: CollectionState) -> bool: + return ( + self.marine_medic_upgrade(state) + or state.count(item_names.FIREBAT_PROGRESSIVE_STIMPACK, self.player) >= 2 + or state.has_any((item_names.FIREBAT_NANO_PROJECTORS, item_names.FIREBAT_JUGGERNAUT_PLATING), self.player) + ) + + def terran_bio_heal(self, state: CollectionState) -> bool: + """ + Ability to heal bio units + """ + return state.has_any({item_names.MEDIC, item_names.MEDIVAC, item_names.FIELD_RESPONSE_THETA}, self.player) or ( + self.advanced_tactics and state.has_all({item_names.RAVEN, item_names.RAVEN_BIO_MECHANICAL_REPAIR_DRONE}, self.player) + ) + + def terran_base_trasher(self, state: CollectionState) -> bool: + """ + Can attack heavily defended bases + """ + if not self.terran_competent_comp(state): + return False + if not self.terran_very_hard_mission_weapon_armor_level(state): + return False + return ( + state.has_all((item_names.SIEGE_TANK, item_names.SIEGE_TANK_JUMP_JETS), self.player) + or state.has_all({item_names.BATTLECRUISER, item_names.BATTLECRUISER_ATX_LASER_BATTERY}, self.player) + or state.has_all({item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY}, self.player) + or ( + self.advanced_tactics + and (state.has_all({item_names.RAVEN, item_names.RAVEN_HUNTER_SEEKER_WEAPON}, self.player)) + and ( + state.has_all({item_names.VIKING, item_names.VIKING_SHREDDER_ROUNDS}, self.player) + or state.has_all({item_names.BANSHEE, item_names.BANSHEE_SHOCKWAVE_MISSILE_BATTERY}, self.player) + ) + ) + ) + + def terran_mobile_detector(self, state: CollectionState) -> bool: + return state.has_any({item_names.RAVEN, item_names.SCIENCE_VESSEL, item_names.COMMAND_CENTER_SCANNER_SWEEP}, self.player) + + def can_nuke(self, state: CollectionState) -> bool: + """ + Ability to launch nukes + """ + return self.advanced_tactics and ( + state.has_any({item_names.GHOST, item_names.SPECTRE}, self.player) + or state.has_all({item_names.THOR, item_names.THOR_BUTTON_WITH_A_SKULL_ON_IT}, self.player) + ) + + def terran_sustainable_mech_heal(self, state: CollectionState) -> bool: + """ + Can heal mech units without spending resources + """ + return ( + state.has(item_names.SCIENCE_VESSEL, self.player) + or ( + state.has_any({item_names.MEDIC, item_names.FIELD_RESPONSE_THETA}, self.player) + and state.has(item_names.MEDIC_ADAPTIVE_MEDPACKS, self.player) + ) + or state.count(item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL, self.player) >= 3 + or ( + self.advanced_tactics + and ( + state.has_all({item_names.RAVEN, item_names.RAVEN_BIO_MECHANICAL_REPAIR_DRONE}, self.player) + or state.count(item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL, self.player) >= 2 + ) + ) + ) + + def terran_cliffjumper(self, state: CollectionState) -> bool: + return ( + state.has(item_names.REAPER, self.player) + or state.has_all({item_names.GOLIATH, item_names.GOLIATH_JUMP_JETS}, self.player) + or state.has_all({item_names.SIEGE_TANK, item_names.SIEGE_TANK_JUMP_JETS}, self.player) + ) + + def nova_any_nobuild_damage(self, state: CollectionState) -> bool: + return state.has_any( + ( + item_names.NOVA_C20A_CANISTER_RIFLE, + item_names.NOVA_HELLFIRE_SHOTGUN, + item_names.NOVA_PLASMA_RIFLE, + item_names.NOVA_MONOMOLECULAR_BLADE, + item_names.NOVA_BLAZEFIRE_GUNBLADE, + item_names.NOVA_PULSE_GRENADES, + item_names.NOVA_DOMINATION, + ), + self.player, + ) + + def nova_any_weapon(self, state: CollectionState) -> bool: + return state.has_any( + { + item_names.NOVA_C20A_CANISTER_RIFLE, + item_names.NOVA_HELLFIRE_SHOTGUN, + item_names.NOVA_PLASMA_RIFLE, + item_names.NOVA_MONOMOLECULAR_BLADE, + item_names.NOVA_BLAZEFIRE_GUNBLADE, + }, + self.player, + ) + + def nova_ranged_weapon(self, state: CollectionState) -> bool: + return state.has_any({item_names.NOVA_C20A_CANISTER_RIFLE, item_names.NOVA_HELLFIRE_SHOTGUN, item_names.NOVA_PLASMA_RIFLE}, self.player) + + def nova_anti_air_weapon(self, state: CollectionState) -> bool: + return state.has_any({item_names.NOVA_C20A_CANISTER_RIFLE, item_names.NOVA_PLASMA_RIFLE, item_names.NOVA_BLAZEFIRE_GUNBLADE}, self.player) + + def nova_splash(self, state: CollectionState) -> bool: + return state.has_any({item_names.NOVA_HELLFIRE_SHOTGUN, item_names.NOVA_PULSE_GRENADES}, self.player) or ( + self.advanced_tactics and state.has_any({item_names.NOVA_PLASMA_RIFLE, item_names.NOVA_MONOMOLECULAR_BLADE}, self.player) + ) + + def nova_dash(self, state: CollectionState) -> bool: + return state.has_any({item_names.NOVA_MONOMOLECULAR_BLADE, item_names.NOVA_BLINK}, self.player) + + def nova_full_stealth(self, state: CollectionState) -> bool: + return state.count(item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE, self.player) >= 2 + + def nova_heal(self, state: CollectionState) -> bool: + return state.has_any({item_names.NOVA_ARMORED_SUIT_MODULE, item_names.NOVA_STIM_INFUSION}, self.player) + + def nova_escape_assist(self, state: CollectionState) -> bool: + return state.has_any({item_names.NOVA_BLINK, item_names.NOVA_HOLO_DECOY, item_names.NOVA_IONIC_FORCE_FIELD}, self.player) + + def nova_beat_stone(self, state: CollectionState) -> bool: + """ + Used for any units logic for beating Stone. Shotgun may not be possible; may need feedback. + """ + return ( + state.has_any(( + item_names.NOVA_DOMINATION, + item_names.NOVA_BLAZEFIRE_GUNBLADE, + item_names.NOVA_C20A_CANISTER_RIFLE, + ), self.player) + or (( + state.has_any(( + item_names.NOVA_PLASMA_RIFLE, + item_names.NOVA_MONOMOLECULAR_BLADE, + ), self.player) + or state.has_all(( + item_names.NOVA_HELLFIRE_SHOTGUN, + item_names.NOVA_STIM_INFUSION + ), self.player) + ) + and state.has_any(( + item_names.NOVA_JUMP_SUIT_MODULE, + item_names.NOVA_ARMORED_SUIT_MODULE, + item_names.NOVA_ENERGY_SUIT_MODULE, + ), self.player) + and state.has_any(( + item_names.NOVA_FLASHBANG_GRENADES, + item_names.NOVA_STIM_INFUSION, + item_names.NOVA_BLINK, + item_names.NOVA_IONIC_FORCE_FIELD, + ), self.player) + ) + ) + + # Global Zerg + def zerg_power_rating(self, state: CollectionState) -> int: + power_score = self.base_power_rating + # Passive Score (Economic upgrades and global army upgrades) + power_score += sum((rating for item, rating in zerg_passive_ratings.items() if state.has(item, self.player))) + # Spear of Adun + if self.spear_of_adun_presence == SpearOfAdunPresence.option_everywhere: + power_score += self.soa_power_rating(state) + if self.spear_of_adun_passive_presence == SpearOfAdunPassiveAbilityPresence.option_everywhere: + power_score += sum((rating for item, rating in soa_passive_ratings.items() if state.has(item, self.player))) + return power_score + + def zerg_defense_rating(self, state: CollectionState, zerg_enemy: bool, air_enemy: bool = True) -> int: + """ + Ability to handle defensive missions + :param state: + :param zerg_enemy: Whether the enemy is zerg + :param air_enemy: Whether the enemy attacks with air + """ + defense_score = sum((zvx_defense_ratings[item] for item in zvx_defense_ratings if state.has(item, self.player))) + # Twin Drones + if state.has(item_names.TWIN_DRONES, self.player): + if state.has(item_names.SPINE_CRAWLER, self.player): + defense_score += 1 + if state.has(item_names.SPORE_CRAWLER, self.player) and air_enemy: + defense_score += 1 + # Impaler + if self.morph_impaler(state): + defense_score += 3 + if state.has(item_names.IMPALER_SUNKEN_SPINES, self.player): + defense_score += 1 + if zerg_enemy: + defense_score += -1 + # Lurker + if self.morph_lurker(state): + defense_score += 2 + if state.has(item_names.LURKER_SEISMIC_SPINES, self.player): + defense_score += 2 + if state.has(item_names.LURKER_ADAPTED_SPINES, self.player) and not zerg_enemy: + defense_score += 1 + if zerg_enemy: + defense_score += 1 + # Brood Lord + if self.morph_brood_lord(state): + defense_score += 2 + # Corpser Roach + if state.has_all({item_names.ROACH, item_names.ROACH_CORPSER_STRAIN}, self.player): + defense_score += 1 + if zerg_enemy: + defense_score += 1 + # Igniter + if self.morph_igniter(state) and zerg_enemy: + defense_score += 2 + # Creep Tumors + if self.spread_creep(state, False): + if not zerg_enemy: + defense_score += 1 + if state.has(item_names.MALIGNANT_CREEP, self.player): + defense_score += 1 + # Infested Siege Tanks + if self.zerg_infested_tank_with_ammo(state): + defense_score += 5 + # Infested Liberators + if state.has_all((item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_DEFENDER_MODE), self.player): + defense_score += 3 + # Bile Launcher upgrades + if state.has_all((item_names.BILE_LAUNCHER, item_names.BILE_LAUNCHER_RAPID_BOMBARMENT), self.player): + defense_score += 2 + + # General enemy-based rules + if air_enemy: + # Capped at 2 + defense_score += min(sum((zvx_air_defense_ratings[item] for item in zvx_air_defense_ratings if state.has(item, self.player))), 2) + # Advanced Tactics bumps defense rating requirements down by 2 + if self.advanced_tactics: + defense_score += 2 + return defense_score + + def zerg_army_weapon_armor_upgrade_min_level(self, state: CollectionState) -> int: + count: int = WEAPON_ARMOR_UPGRADE_MAX_LEVEL + if self.has_zerg_melee_unit: + count = min(count, self.zerg_melee_weapon_armor_upgrade_min_level(state)) + if self.has_zerg_ranged_unit: + count = min(count, self.zerg_ranged_weapon_armor_upgrade_min_level(state)) + if self.has_zerg_air_unit: + count = min(count, self.zerg_flyer_weapon_armor_upgrade_min_level(state)) + return count + + def zerg_melee_weapon_armor_upgrade_min_level(self, state: CollectionState) -> int: + return min( + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_MELEE_ATTACK, state), + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_GROUND_CARAPACE, state), + ) + + def zerg_ranged_weapon_armor_upgrade_min_level(self, state: CollectionState) -> int: + return min( + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_MISSILE_ATTACK, state), + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_GROUND_CARAPACE, state), + ) + + def zerg_flyer_weapon_armor_upgrade_min_level(self, state: CollectionState) -> int: + return min( + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_FLYER_ATTACK, state), + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_FLYER_CARAPACE, state), + ) + + def zerg_can_collect_pickup_across_gap(self, state: CollectionState) -> bool: + """Any way for zerg to get any ground unit across gaps longer than viper yoink range to collect a pickup.""" + return ( + state.has_any( + ( + item_names.NYDUS_WORM, + item_names.ECHIDNA_WORM, + item_names.OVERLORD_VENTRAL_SACS, + item_names.YGGDRASIL, + item_names.INFESTED_BANSHEE, + ), + self.player, + ) + or (self.morph_ravager(state) and state.has(item_names.RAVAGER_DEEP_TUNNEL, self.player)) + or state.has_all( + ( + item_names.INFESTED_SIEGE_TANK, + item_names.INFESTED_SIEGE_TANK_DEEP_TUNNEL, + item_names.OVERLORD_GENERATE_CREEP, + ), + self.player, + ) + or state.has_all((item_names.SWARM_QUEEN_DEEP_TUNNEL, item_names.OVERLORD_OVERSEER_ASPECT), self.player) # Deep tunnel to a creep tumor + ) + + def zerg_has_infested_scv(self, state: CollectionState) -> bool: + return ( + state.has_any(( + item_names.INFESTED_MARINE, + item_names.INFESTED_BUNKER, + item_names.INFESTED_DIAMONDBACK, + item_names.INFESTED_SIEGE_TANK, + item_names.INFESTED_BANSHEE, + item_names.BULLFROG, + item_names.INFESTED_LIBERATOR, + item_names.INFESTED_MISSILE_TURRET, + ), self.player) + ) + + def zerg_very_hard_mission_weapon_armor_level(self, state: CollectionState) -> bool: + return self.zerg_army_weapon_armor_upgrade_min_level(state) >= self.get_very_hard_required_upgrade_level() + + def zerg_common_unit(self, state: CollectionState) -> bool: + return state.has_any(self.basic_zerg_units, self.player) + + def zerg_competent_anti_air(self, state: CollectionState) -> bool: + return state.has_any({item_names.HYDRALISK, item_names.MUTALISK, item_names.CORRUPTOR, item_names.BROOD_QUEEN}, self.player) or ( + self.advanced_tactics and state.has(item_names.INFESTOR, self.player) + ) + + def zerg_moderate_anti_air(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_anti_air(state) + or self.zerg_basic_air_to_air(state) + or ( + state.has(item_names.SWARM_QUEEN, self.player) + or state.has_all({item_names.SWARM_HOST, item_names.SWARM_HOST_PRESSURIZED_GLANDS}, self.player) + or (self.spread_creep(state, True) and state.has(item_names.INFESTED_BUNKER, self.player)) + ) + or (self.advanced_tactics and state.has(item_names.INFESTED_MARINE, self.player)) + ) + + def zerg_kerrigan_or_any_anti_air(self, state: CollectionState) -> bool: + return self.kerrigan_unit_available or self.zerg_any_anti_air(state) + + def zerg_any_anti_air(self, state: CollectionState) -> bool: + return ( + state.has_any( + ( + item_names.HYDRALISK, + item_names.SWARM_QUEEN, + item_names.BROOD_QUEEN, + item_names.MUTALISK, + item_names.CORRUPTOR, + item_names.SCOURGE, + item_names.INFESTOR, + item_names.INFESTED_MARINE, + item_names.INFESTED_LIBERATOR, + item_names.SPORE_CRAWLER, + item_names.INFESTED_MISSILE_TURRET, + item_names.INFESTED_BUNKER, + item_names.HUNTER_KILLERS, + item_names.CAUSTIC_HORRORS, + ), + self.player, + ) + or state.has_all((item_names.SWARM_HOST, item_names.SWARM_HOST_PRESSURIZED_GLANDS), self.player) + or state.has_all((item_names.ABERRATION, item_names.ABERRATION_PROGRESSIVE_BANELING_LAUNCH), self.player) + or state.has_all((item_names.INFESTED_DIAMONDBACK, item_names.INFESTED_DIAMONDBACK_PROGRESSIVE_FUNGAL_SNARE), self.player) + or self.morph_ravager(state) + or self.morph_viper(state) + or self.morph_devourer(state) + or (self.morph_guardian(state) and state.has(item_names.GUARDIAN_PRIMAL_ADAPTATION, self.player)) + ) + + def zerg_basic_anti_air(self, state: CollectionState) -> bool: + return self.zerg_basic_kerriganless_anti_air(state) or self.kerrigan_unit_available + + def zerg_basic_kerriganless_anti_air(self, state: CollectionState) -> bool: + return ( + self.zerg_moderate_anti_air(state) + or state.has_any((item_names.HUNTER_KILLERS, item_names.CAUSTIC_HORRORS), self.player) + or (self.advanced_tactics and state.has_any({item_names.SPORE_CRAWLER, item_names.INFESTED_MISSILE_TURRET}, self.player)) + ) + + def zerg_basic_air_to_air(self, state: CollectionState) -> bool: + return ( + state.has_any( + {item_names.MUTALISK, item_names.CORRUPTOR, item_names.BROOD_QUEEN, item_names.SCOURGE, item_names.INFESTED_LIBERATOR}, self.player + ) + or self.morph_devourer(state) + or self.morph_viper(state) + or (self.morph_guardian(state) and state.has(item_names.GUARDIAN_PRIMAL_ADAPTATION, self.player)) + ) + + def zerg_basic_air_to_ground(self, state: CollectionState) -> bool: + return ( + state.has_any({item_names.MUTALISK, item_names.INFESTED_BANSHEE}, self.player) + or self.morph_guardian(state) + or self.morph_brood_lord(state) + or (self.morph_devourer(state) and state.has(item_names.DEVOURER_PRESCIENT_SPORES, self.player)) + ) + + def zerg_versatile_air(self, state: CollectionState) -> bool: + return self.zerg_basic_air_to_air(state) and self.zerg_basic_air_to_ground(state) + + def zerg_infested_tank_with_ammo(self, state: CollectionState) -> bool: + return state.has(item_names.INFESTED_SIEGE_TANK, self.player) and ( + state.has_all({item_names.INFESTOR, item_names.INFESTOR_INFESTED_TERRAN}, self.player) + or state.has(item_names.INFESTED_BUNKER, self.player) + or (self.advanced_tactics and state.has(item_names.INFESTED_MARINE, self.player)) + or state.count(item_names.INFESTED_SIEGE_TANK_PROGRESSIVE_AUTOMATED_MITOSIS, self.player) >= (1 if self.advanced_tactics else 2) + ) + + def morph_baneling(self, state: CollectionState) -> bool: + return (state.has(item_names.ZERGLING, self.player) or self.morphling_enabled) and state.has(item_names.ZERGLING_BANELING_ASPECT, self.player) + + def morph_ravager(self, state: CollectionState) -> bool: + return (state.has(item_names.ROACH, self.player) or self.morphling_enabled) and state.has(item_names.ROACH_RAVAGER_ASPECT, self.player) + + def morph_brood_lord(self, state: CollectionState) -> bool: + return (state.has_any({item_names.MUTALISK, item_names.CORRUPTOR}, self.player) or self.morphling_enabled) and state.has( + item_names.MUTALISK_CORRUPTOR_BROOD_LORD_ASPECT, self.player + ) + + def morph_guardian(self, state: CollectionState) -> bool: + return (state.has_any({item_names.MUTALISK, item_names.CORRUPTOR}, self.player) or self.morphling_enabled) and state.has( + item_names.MUTALISK_CORRUPTOR_GUARDIAN_ASPECT, self.player + ) + + def morph_viper(self, state: CollectionState) -> bool: + return (state.has_any({item_names.MUTALISK, item_names.CORRUPTOR}, self.player) or self.morphling_enabled) and state.has( + item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT, self.player + ) + + def morph_devourer(self, state: CollectionState) -> bool: + return (state.has_any({item_names.MUTALISK, item_names.CORRUPTOR}, self.player) or self.morphling_enabled) and state.has( + item_names.MUTALISK_CORRUPTOR_DEVOURER_ASPECT, self.player + ) + + def morph_impaler(self, state: CollectionState) -> bool: + return (state.has(item_names.HYDRALISK, self.player) or self.morphling_enabled) and state.has( + item_names.HYDRALISK_IMPALER_ASPECT, self.player + ) + + def morph_lurker(self, state: CollectionState) -> bool: + return (state.has(item_names.HYDRALISK, self.player) or self.morphling_enabled) and state.has(item_names.HYDRALISK_LURKER_ASPECT, self.player) + + def morph_impaler_or_lurker(self, state: CollectionState) -> bool: + return self.morph_impaler(state) or self.morph_lurker(state) + + def morph_igniter(self, state: CollectionState) -> bool: + return (state.has(item_names.ROACH, self.player) or self.morphling_enabled) and state.has(item_names.ROACH_PRIMAL_IGNITER_ASPECT, self.player) + + def morph_tyrannozor(self, state: CollectionState) -> bool: + return state.has(item_names.ULTRALISK_TYRANNOZOR_ASPECT, self.player) and ( + state.has(item_names.ULTRALISK, self.player) or self.morphling_enabled + ) + + def zerg_competent_comp(self, state: CollectionState) -> bool: + if self.zerg_army_weapon_armor_upgrade_min_level(state) < 2: + return False + advanced = self.advanced_tactics + core_unit = state.has_any( + {item_names.ROACH, item_names.ABERRATION, item_names.ZERGLING, item_names.INFESTED_DIAMONDBACK}, self.player + ) or self.morph_igniter(state) + support_unit = ( + state.has_any({item_names.SWARM_QUEEN, item_names.HYDRALISK, item_names.INFESTED_BANSHEE}, self.player) + or self.morph_brood_lord(state) + or state.has_all((item_names.MUTALISK, item_names.MUTALISK_SEVERING_GLAIVE, item_names.MUTALISK_VICIOUS_GLAIVE), self.player) + or advanced + and (state.has_any({item_names.INFESTOR, item_names.DEFILER}, self.player) or self.morph_viper(state)) + ) + if core_unit and support_unit: + return True + vespene_unit = ( + state.has_any({item_names.ULTRALISK, item_names.ABERRATION}, self.player) + or ( + self.morph_guardian(state) + and state.has_any( + (item_names.GUARDIAN_SORONAN_ACID, item_names.GUARDIAN_EXPLOSIVE_SPORES, item_names.GUARDIAN_PRIMORDIAL_FURY), self.player + ) + ) + or advanced + and self.morph_viper(state) + ) + return vespene_unit and state.has_any({item_names.ZERGLING, item_names.SWARM_QUEEN}, self.player) + + def zerg_common_unit_basic_aa(self, state: CollectionState) -> bool: + return self.zerg_common_unit(state) and self.zerg_basic_anti_air(state) + + def zerg_common_unit_competent_aa(self, state: CollectionState) -> bool: + return self.zerg_common_unit(state) and self.zerg_competent_anti_air(state) + + def zerg_competent_comp_basic_aa(self, state: CollectionState) -> bool: + return self.zerg_competent_comp(state) and self.zerg_basic_anti_air(state) + + def zerg_competent_comp_competent_aa(self, state: CollectionState) -> bool: + return self.zerg_competent_comp(state) and self.zerg_competent_anti_air(state) + + def spread_creep(self, state: CollectionState, free_creep_tumor=True) -> bool: + return (self.advanced_tactics and free_creep_tumor) or state.has_any( + {item_names.SWARM_QUEEN, item_names.OVERLORD_OVERSEER_ASPECT}, self.player + ) + + def zerg_mineral_dump(self, state: CollectionState) -> bool: + return ( + state.has_any({item_names.ZERGLING, item_names.PYGALISK, item_names.INFESTED_BUNKER}, self.player) + or state.has_all({item_names.SWARM_QUEEN, item_names.SWARM_QUEEN_RESOURCE_EFFICIENCY}, self.player) + or (self.advanced_tactics and self.spread_creep(state) and state.has(item_names.SPINE_CRAWLER, self.player)) + ) + + def zerg_big_monsters(self, state: CollectionState) -> bool: + """ + Durable units with some capacity for damage + """ + return ( + self.morph_tyrannozor(state) + or state.has_any((item_names.ABERRATION, item_names.ULTRALISK), self.player) + or (self.spread_creep(state, False) and state.has(item_names.INFESTED_BUNKER, self.player)) + ) + + def zerg_base_buster(self, state: CollectionState) -> bool: + """Powerful and sustainable zerg anti-ground for busting big bases; anti-air not included""" + if not self.zerg_competent_comp(state): + return False + return ( + ( + self.zerg_melee_weapon_armor_upgrade_min_level(state) >= self.get_very_hard_required_upgrade_level() + and ( + self.morph_tyrannozor(state) + or ( + state.has(item_names.ULTRALISK, self.player) + and state.has_any((item_names.ULTRALISK_TORRASQUE_STRAIN, item_names.ULTRALISK_CHITINOUS_PLATING), self.player) + ) + or (self.morph_baneling(state) and state.has(item_names.BANELING_SPLITTER_STRAIN, self.player)) + ) + and state.has(item_names.SWARM_QUEEN, self.player) # Healing to sustain the frontline + ) + or ( + self.zerg_ranged_weapon_armor_upgrade_min_level(state) >= self.get_very_hard_required_upgrade_level() + and ( + self.morph_impaler(state) + or self.morph_lurker(state) + and state.has_all((item_names.LURKER_SEISMIC_SPINES, item_names.LURKER_ADAPTED_SPINES), self.player) + or state.has_all( + ( + item_names.ROACH, + item_names.ROACH_CORPSER_STRAIN, + item_names.ROACH_ADAPTIVE_PLATING, + item_names.ROACH_GLIAL_RECONSTITUTION, + ), + self.player, + ) + or self.morph_igniter(state) + and state.has(item_names.PRIMAL_IGNITER_PRIMAL_TENACITY, self.player) + or state.has_all((item_names.INFESTOR, item_names.INFESTOR_INFESTED_TERRAN), self.player) + or self.spread_creep(state, False) + and state.has(item_names.INFESTED_BUNKER, self.player) + or self.zerg_infested_tank_with_ammo(state) + # Highly-upgraded swarm hosts may also work, but that would require promoting many upgrades to progression + ) + ) + or ( + self.zerg_flyer_weapon_armor_upgrade_min_level(state) >= self.get_very_hard_required_upgrade_level() + and ( + self.morph_brood_lord(state) + or self.morph_guardian(state) + and state.has_all((item_names.GUARDIAN_PROPELLANT_SACS, item_names.GUARDIAN_SORONAN_ACID), self.player) + or state.has_all((item_names.INFESTED_BANSHEE, item_names.INFESTED_BANSHEE_FLESHFUSED_TARGETING_OPTICS), self.player) + # Highly-upgraded anti-ground devourers would also be good + ) + ) + ) + + def zergling_hydra_roach_start(self, state: CollectionState): + """ + Created mainly for engine of destruction start, but works for other missions with no-build starts. + """ + return state.has_any( + { + item_names.ZERGLING_ADRENAL_OVERLOAD, + item_names.HYDRALISK_FRENZY, + item_names.ROACH_HYDRIODIC_BILE, + item_names.ZERGLING_RAPTOR_STRAIN, + item_names.ROACH_CORPSER_STRAIN, + }, + self.player, + ) + + def kerrigan_levels(self, state: CollectionState, target: int, story_levels_available=True) -> bool: + if (story_levels_available and self.story_levels_granted) or not self.kerrigan_unit_available: + return True # Levels are granted + if ( + self.kerrigan_levels_per_mission_completed > 0 + and self.kerrigan_levels_per_mission_completed_cap != 0 + and not self.is_item_placement(state) + ): + # Levels can be granted from mission completion. + # Item pool filtering isn't aware of missions beaten. Assume that missions beaten will fulfill this rule. + return True + # Levels from missions beaten + levels = self.kerrigan_levels_per_mission_completed * state.count_group("Missions", self.player) + if self.kerrigan_levels_per_mission_completed_cap != -1: + levels = min(levels, self.kerrigan_levels_per_mission_completed_cap) + # Levels from items + for kerrigan_level_item in kerrigan_levels: + level_amount = get_full_item_list()[kerrigan_level_item].number + item_count = state.count(kerrigan_level_item, self.player) + levels += item_count * level_amount + # Total level cap + if self.kerrigan_total_level_cap != -1: + levels = min(levels, self.kerrigan_total_level_cap) + + return levels >= target + + def basic_kerrigan(self, state: CollectionState) -> bool: + # One active ability that can be used to defeat enemies directly on Standard + if not state.has_any( + ( + item_names.KERRIGAN_LEAPING_STRIKE, + item_names.KERRIGAN_KINETIC_BLAST, + item_names.KERRIGAN_SPAWN_BANELINGS, + item_names.KERRIGAN_PSIONIC_SHIFT, + item_names.KERRIGAN_CRUSHING_GRIP, + ), + self.player, + ): + return False + # Two non-ultimate abilities + count = 0 + for item in kerrigan_non_ulimates: + if state.has(item, self.player): + count += 1 + if count >= 2: + return True + return False + + def two_kerrigan_actives(self, state: CollectionState) -> bool: + count = 0 + for i in range(7): + if state.has_any(kerrigan_logic_active_abilities, self.player): + count += 1 + return count >= 2 + + # Global Protoss + def protoss_power_rating(self, state: CollectionState) -> int: + power_score = self.base_power_rating + # War Council Upgrades (all units are improved) + if self.war_council_upgrades: + power_score += 3 + # Passive Score (Economic upgrades and global army upgrades) + power_score += sum((rating for item, rating in protoss_passive_ratings.items() if state.has(item, self.player))) + # Spear of Adun + if self.spear_of_adun_presence in (SpearOfAdunPresence.option_everywhere, SpearOfAdunPresence.option_protoss): + power_score += self.soa_power_rating(state) + if self.spear_of_adun_passive_presence in (SpearOfAdunPassiveAbilityPresence.option_everywhere, SpearOfAdunPresence.option_protoss): + power_score += sum((rating for item, rating in soa_passive_ratings.items() if state.has(item, self.player))) + return power_score + + def protoss_army_weapon_armor_upgrade_min_level(self, state: CollectionState) -> int: + count: int = WEAPON_ARMOR_UPGRADE_MAX_LEVEL + 1 # +1 for Quatro + if self.has_protoss_ground_unit: + count = min( + count, + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_PROTOSS_GROUND_WEAPON, state), + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_PROTOSS_GROUND_ARMOR, state), + ) + if self.has_protoss_air_unit: + count = min( + count, + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_PROTOSS_AIR_WEAPON, state), + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_PROTOSS_AIR_ARMOR, state), + ) + if self.has_protoss_ground_unit or self.has_protoss_air_unit: + count = min( + count, + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_PROTOSS_SHIELDS, state), + ) + return count + + def protoss_very_hard_mission_weapon_armor_level(self, state: CollectionState) -> bool: + return self.protoss_army_weapon_armor_upgrade_min_level(state) >= self.get_very_hard_required_upgrade_level() + + def protoss_defense_rating(self, state: CollectionState, zerg_enemy: bool) -> int: + """ + Ability to handle defensive missions + :param state: + :param zerg_enemy: Whether the enemy is zerg + """ + defense_score = sum((pvx_defense_ratings[item] for item in pvx_defense_ratings if state.has(item, self.player))) + # Vanguard + rapid fire + if state.has_all((item_names.VANGUARD, item_names.VANGUARD_RAPIDFIRE_CANNON), self.player): + defense_score += 1 + # Fire Colossus + if state.has_all((item_names.COLOSSUS, item_names.COLOSSUS_FIRE_LANCE), self.player): + defense_score += 2 + if zerg_enemy: + defense_score += 2 + if ( + state.has_any((item_names.PHOTON_CANNON, item_names.KHAYDARIN_MONOLITH, item_names.NEXUS_OVERCHARGE), self.player) + and state.has(item_names.SHIELD_BATTERY, self.player) + ): + defense_score += 2 + + # No anti-air defense dict here, use an existing logic rule instead + if zerg_enemy: + defense_score += sum((pvz_defense_ratings[item] for item in pvz_defense_ratings if state.has(item, self.player))) + # Advanced Tactics bumps defense rating requirements down by 2 + if self.advanced_tactics: + defense_score += 2 + return defense_score + + def protoss_common_unit(self, state: CollectionState) -> bool: + return state.has_any(self.basic_protoss_units, self.player) + + def protoss_any_gap_transport(self, state: CollectionState) -> bool: + """Can get ground units across large gaps, larger than blink range""" + return ( + state.has_any( + ( + item_names.WARP_PRISM, + item_names.ARBITER, + ), + self.player, + ) + or state.has(item_names.SOA_PROGRESSIVE_PROXY_PYLON, self.player, count=2) + or state.has_all((item_names.MISTWING, item_names.MISTWING_PILOT), self.player) + or ( + state.has(item_names.SOA_PROGRESSIVE_PROXY_PYLON, self.player) + and ( + state.has_any(item_groups.gateway_units + [item_names.ELDER_PROBES, item_names.PROBE_WARPIN], self.player) + or (state.has(item_names.WARP_HARMONIZATION, self.player) and state.has_any(item_groups.protoss_ground_wa, self.player)) + ) + ) + ) + + def protoss_any_anti_air_unit_or_soa_any_protoss(self, state: CollectionState) -> bool: + return self.protoss_any_anti_air_unit(state) or ( + self.spear_of_adun_presence in (SpearOfAdunPresence.option_everywhere, SpearOfAdunPresence.option_protoss) + and self.protoss_any_anti_air_soa(state) + ) + + def protoss_any_anti_air_unit_or_soa(self, state: CollectionState) -> bool: + return self.protoss_any_anti_air_unit(state) or self.protoss_any_anti_air_soa(state) + + def protoss_any_anti_air_soa(self, state: CollectionState) -> bool: + return ( + state.has_any( + ( + item_names.SOA_ORBITAL_STRIKE, + item_names.SOA_SOLAR_LANCE, + item_names.SOA_SOLAR_BOMBARDMENT, + item_names.SOA_PURIFIER_BEAM, + item_names.SOA_PYLON_OVERCHARGE, + ), + self.player, + ) + or state.has(item_names.SOA_PROGRESSIVE_PROXY_PYLON, self.player, 2) # Warp-In Reinforcements + ) + + def protoss_any_anti_air_unit(self, state: CollectionState) -> bool: + return ( + state.has_any( + ( + # Gateway + item_names.STALKER, + item_names.SLAYER, + item_names.INSTIGATOR, + item_names.DRAGOON, + item_names.ADEPT, + item_names.SENTRY, + item_names.ENERGIZER, + item_names.HIGH_TEMPLAR, + item_names.SIGNIFIER, + item_names.ASCENDANT, + item_names.DARK_ARCHON, + # Robo + item_names.ANNIHILATOR, + # Stargate + item_names.PHOENIX, + item_names.MIRAGE, + item_names.CORSAIR, + item_names.SCOUT, + item_names.MISTWING, + item_names.CALADRIUS, + item_names.OPPRESSOR, + item_names.ARBITER, + item_names.VOID_RAY, + item_names.DESTROYER, + item_names.PULSAR, + item_names.CARRIER, + item_names.SKYLORD, + item_names.TEMPEST, + item_names.MOTHERSHIP, + # Buildings + item_names.NEXUS_OVERCHARGE, + item_names.PHOTON_CANNON, + item_names.KHAYDARIN_MONOLITH, + ), + self.player, + ) + or state.has_all((item_names.SUPPLICANT, item_names.SUPPLICANT_ZENITH_PITCH), self.player) + or state.has_all((item_names.WARP_PRISM, item_names.WARP_PRISM_PHASE_BLASTER), self.player) + or state.has_all((item_names.WRATHWALKER, item_names.WRATHWALKER_AERIAL_TRACKING), self.player) + or state.has_all((item_names.DISRUPTOR, item_names.DISRUPTOR_PERFECTED_POWER), self.player) + or state.has_all((item_names.IMMORTAL, item_names.IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING), self.player) + or state.has_all((item_names.SKIRMISHER, item_names.SKIRMISHER_PEER_CONTEMPT), self.player) + or state.has_all((item_names.TRIREME, item_names.TRIREME_SOLAR_BEAM), self.player) + or ( + state.has(item_names.DARK_TEMPLAR, self.player) + and state.has_any((item_names.DARK_TEMPLAR_DARK_ARCHON_MELD, item_names.DARK_TEMPLAR_ARCHON_MERGE), self.player) + ) + ) + + def protoss_basic_anti_air(self, state: CollectionState) -> bool: + return ( + self.protoss_competent_anti_air(state) + or state.has_any( + { + item_names.PHOENIX, + item_names.MIRAGE, + item_names.CORSAIR, + item_names.CARRIER, + item_names.SKYLORD, + item_names.SCOUT, + item_names.DARK_ARCHON, + item_names.MOTHERSHIP, + item_names.MISTWING, + item_names.CALADRIUS, + item_names.OPPRESSOR, + item_names.PULSAR, + item_names.DRAGOON, + }, + self.player, + ) + or state.has_all({item_names.TRIREME, item_names.TRIREME_SOLAR_BEAM}, self.player) + or state.has_all({item_names.WRATHWALKER, item_names.WRATHWALKER_AERIAL_TRACKING}, self.player) + or state.has_all({item_names.WARP_PRISM, item_names.WARP_PRISM_PHASE_BLASTER}, self.player) + or self.advanced_tactics + and state.has_any({item_names.HIGH_TEMPLAR, item_names.SIGNIFIER, item_names.SENTRY, item_names.ENERGIZER}, self.player) + or self.protoss_can_merge_archon(state) + or self.protoss_can_merge_dark_archon(state) + ) + + def protoss_anti_armor_anti_air(self, state: CollectionState) -> bool: + return ( + self.protoss_competent_anti_air(state) + or state.has_any((item_names.SCOUT, item_names.MISTWING, item_names.DRAGOON), self.player) + or ( + state.has_any({item_names.IMMORTAL, item_names.ANNIHILATOR}, self.player) + and state.has(item_names.IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING, self.player) + ) + or state.has_all({item_names.WRATHWALKER, item_names.WRATHWALKER_AERIAL_TRACKING}, self.player) + ) + + def protoss_anti_light_anti_air(self, state: CollectionState) -> bool: + return ( + self.protoss_competent_anti_air(state) + or state.has_any( + { + item_names.PHOENIX, + item_names.MIRAGE, + item_names.CORSAIR, + item_names.CARRIER, + }, + self.player, + ) + or state.has_all((item_names.SKIRMISHER, item_names.SKIRMISHER_PEER_CONTEMPT), self.player) + ) + + def protoss_moderate_anti_air(self, state: CollectionState) -> bool: + return ( + self.protoss_competent_anti_air(state) + or self.protoss_anti_light_anti_air(state) + or self.protoss_anti_armor_anti_air(state) + or state.has(item_names.SKYLORD, self.player) + ) + + def protoss_common_unit_basic_aa(self, state: CollectionState) -> bool: + return self.protoss_common_unit(state) and self.protoss_basic_anti_air(state) + + def protoss_common_unit_anti_light_air(self, state: CollectionState) -> bool: + return self.protoss_common_unit(state) and self.protoss_anti_light_anti_air(state) + + def protoss_common_unit_anti_armor_air(self, state: CollectionState) -> bool: + return self.protoss_common_unit(state) and self.protoss_anti_armor_anti_air(state) + + def protoss_competent_anti_air(self, state: CollectionState) -> bool: + return ( + state.has_any( + { + item_names.STALKER, + item_names.SLAYER, + item_names.INSTIGATOR, + item_names.ADEPT, + item_names.VOID_RAY, + item_names.DESTROYER, + item_names.TEMPEST, + item_names.CALADRIUS, + }, + self.player, + ) + or ( + ( + state.has_any( + { + item_names.PHOENIX, + item_names.MIRAGE, + item_names.CORSAIR, + item_names.CARRIER, + }, + self.player, + ) + or state.has_all((item_names.SKIRMISHER, item_names.SKIRMISHER_PEER_CONTEMPT), self.player) + ) + and ( + state.has_any((item_names.SCOUT, item_names.MISTWING, item_names.DRAGOON), self.player) + or state.has_all({item_names.WRATHWALKER, item_names.WRATHWALKER_AERIAL_TRACKING}, self.player) + or ( + state.has_any({item_names.IMMORTAL, item_names.ANNIHILATOR}, self.player) + and state.has(item_names.IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING, self.player) + ) + ) + ) + or ( + self.advanced_tactics + and state.has_any({item_names.IMMORTAL, item_names.ANNIHILATOR}, self.player) + and state.has(item_names.IMMORTAL_ANNIHILATOR_ADVANCED_TARGETING, self.player) + ) + ) + + def protoss_has_blink(self, state: CollectionState) -> bool: + return ( + state.has_any({item_names.STALKER, item_names.INSTIGATOR}, self.player) + or state.has_all({item_names.SLAYER, item_names.SLAYER_PHASE_BLINK}, self.player) + or ( + state.has(item_names.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_BLINK, self.player) + and state.has_any({item_names.DARK_TEMPLAR, item_names.BLOOD_HUNTER, item_names.AVENGER}, self.player) + ) + ) + + def protoss_fleet(self, state: CollectionState) -> bool: + return ( + ( + state.has_any( + { + item_names.CARRIER, + item_names.SKYLORD, + item_names.TEMPEST, + item_names.VOID_RAY, + item_names.DESTROYER, + }, + self.player, + ) + ) + or ( + state.has_all((item_names.TRIREME, item_names.TRIREME_SOLAR_BEAM), self.player) + and ( + state.has_any((item_names.PHOENIX, item_names.MIRAGE, item_names.CORSAIR), self.player) + or state.has_all((item_names.SKIRMISHER, item_names.SKIRMISHER_PEER_CONTEMPT), self.player) + ) + ) + and self.weapon_armor_upgrade_count(PROGRESSIVE_PROTOSS_AIR_WEAPON, state) >= 2 + and self.weapon_armor_upgrade_count(PROGRESSIVE_PROTOSS_AIR_ARMOR, state) >= 2 + and self.weapon_armor_upgrade_count(PROGRESSIVE_PROTOSS_SHIELDS, state) >= 2 + ) + + def protoss_hybrid_counter(self, state: CollectionState) -> bool: + """ + Ground Hybrids + """ + return ( + state.has_any( + { + item_names.ANNIHILATOR, + item_names.ASCENDANT, + item_names.TEMPEST, + item_names.CARRIER, + item_names.TRIREME, + item_names.VOID_RAY, + item_names.WRATHWALKER, + }, + self.player, + ) + or state.has_all((item_names.VANGUARD, item_names.VANGUARD_FUSION_MORTARS), self.player) + or ( + (state.has(item_names.IMMORTAL, self.player) or self.advanced_tactics) + and (state.has_any({item_names.STALKER, item_names.DRAGOON, item_names.ADEPT, item_names.INSTIGATOR, item_names.SLAYER}, self.player)) + ) + or (self.advanced_tactics and state.has_all((item_names.OPPRESSOR, item_names.OPPRESSOR_VULCAN_BLASTER), self.player)) + ) + + def protoss_basic_splash(self, state: CollectionState) -> bool: + return ( + state.has_any(( + item_names.COLOSSUS, + item_names.VANGUARD, + item_names.HIGH_TEMPLAR, + item_names.SIGNIFIER, + item_names.REAVER, + item_names.ASCENDANT, + item_names.DAWNBRINGER, + ), self.player) + or state.has_all((item_names.ZEALOT, item_names.ZEALOT_WHIRLWIND), self.player) + or ( + state.has_all( + (item_names.DARK_TEMPLAR, item_names.DARK_TEMPLAR_LESSER_SHADOW_FURY, item_names.DARK_TEMPLAR_GREATER_SHADOW_FURY), self.player + ) + ) + or ( + state.has(item_names.DESTROYER, self.player) + and ( + state.has_any(( + item_names.DESTROYER_REFORGED_BLOODSHARD_CORE, + item_names.DESTROYER_RESOURCE_EFFICIENCY, + ), self.player) + ) + ) + ) + + def protoss_static_defense(self, state: CollectionState) -> bool: + return state.has_any({item_names.PHOTON_CANNON, item_names.KHAYDARIN_MONOLITH}, self.player) + + def protoss_can_merge_archon(self, state: CollectionState) -> bool: + return ( + state.has_any({item_names.HIGH_TEMPLAR, item_names.SIGNIFIER}, self.player) + or state.has_all({item_names.ASCENDANT, item_names.ASCENDANT_ARCHON_MERGE}, self.player) + or state.has_all({item_names.DARK_TEMPLAR, item_names.DARK_TEMPLAR_ARCHON_MERGE}, self.player) + ) + + def protoss_can_merge_dark_archon(self, state: CollectionState) -> bool: + return state.has(item_names.DARK_ARCHON, self.player) or state.has_all( + {item_names.DARK_TEMPLAR, item_names.DARK_TEMPLAR_DARK_ARCHON_MELD}, self.player + ) + + def protoss_competent_comp(self, state: CollectionState) -> bool: + if not self.protoss_competent_anti_air(state): + return False + if self.protoss_fleet(state) and self.protoss_mineral_dump(state): + return True + if self.protoss_deathball(state): + return True + core_unit: bool = state.has_any( + ( + item_names.ZEALOT, + item_names.CENTURION, + item_names.SENTINEL, + item_names.STALKER, + item_names.INSTIGATOR, + item_names.SLAYER, + item_names.ADEPT, + ), + self.player, + ) + support_unit: bool = ( + state.has_any( + ( + item_names.SENTRY, + item_names.ENERGIZER, + item_names.IMMORTAL, + item_names.VANGUARD, + item_names.COLOSSUS, + item_names.REAVER, + item_names.VOID_RAY, + item_names.PHOENIX, + item_names.CORSAIR, + ), + self.player, + ) + or state.has_all((item_names.MIRAGE, item_names.MIRAGE_GRAVITON_BEAM), self.player) + or state.has_all( + (item_names.DARK_TEMPLAR, item_names.DARK_TEMPLAR_LESSER_SHADOW_FURY, item_names.DARK_TEMPLAR_GREATER_SHADOW_FURY), self.player + ) + or ( + self.advanced_tactics + and ( + state.has_any( + ( + item_names.HIGH_TEMPLAR, + item_names.SIGNIFIER, + item_names.ASCENDANT, + item_names.ANNIHILATOR, + item_names.WRATHWALKER, + item_names.SKIRMISHER, + item_names.ARBITER, + ), + self.player, + ) + ) + ) + ) + if core_unit and support_unit: + return True + return False + + def protoss_deathball(self, state: CollectionState) -> bool: + return ( + self.protoss_common_unit(state) + and self.protoss_competent_anti_air(state) + and self.protoss_hybrid_counter(state) + and self.protoss_basic_splash(state) + and self.protoss_army_weapon_armor_upgrade_min_level(state) >= 2 + ) + + def protoss_heal(self, state: CollectionState) -> bool: + return state.has_any((item_names.SENTRY, item_names.SHIELD_BATTERY, item_names.RECONSTRUCTION_BEAM), self.player) or state.has_all( + (item_names.CARRIER, item_names.CARRIER_REPAIR_DRONES), self.player + ) + + def protoss_mineral_dump(self, state: CollectionState) -> bool: + return ( + state.has_any((item_names.ZEALOT, item_names.SENTINEL, item_names.PHOTON_CANNON), self.player) + or state.has_all((item_names.CENTURION, item_names.CENTURION_RESOURCE_EFFICIENCY), self.player) + or self.advanced_tactics + and state.has_any((item_names.SUPPLICANT, item_names.SHIELD_BATTERY), self.player) + ) + + def zealot_sentry_slayer_start(self, state: CollectionState): + """ + Created mainly for engine of destruction start, but works for other missions with no-build starts. + """ + return state.has_any( + { + item_names.ZEALOT_WHIRLWIND, + item_names.SENTRY_DOUBLE_SHIELD_RECHARGE, + item_names.SLAYER_PHASE_BLINK, + item_names.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES, + item_names.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION, + }, + self.player, + ) + + # Mission-specific rules + def ghost_of_a_chance_requirement(self, state: CollectionState) -> bool: + return ( + self.grant_story_tech == GrantStoryTech.option_grant + or self.nova_ghost_of_a_chance_variant == NovaGhostOfAChanceVariant.option_wol + or not self.nova_used + or ( + self.nova_ranged_weapon(state) + and state.has_any({item_names.NOVA_DOMINATION, item_names.NOVA_C20A_CANISTER_RIFLE}, self.player) + and (self.nova_full_stealth(state) or self.nova_heal(state)) + and self.nova_anti_air_weapon(state) + ) + ) + + def terran_outbreak_requirement(self, state: CollectionState) -> bool: + """Outbreak mission requirement""" + return self.terran_defense_rating(state, True, False) >= 4 and (self.terran_common_unit(state) or state.has(item_names.REAPER, self.player)) + + def zerg_outbreak_requirement(self, state: CollectionState) -> bool: + """ + Outbreak mission requirement. + Need to boot out Aberration-based comp + """ + return ( + self.zerg_defense_rating(state, True, False) >= 4 + and self.zerg_common_unit(state) + and ( + state.has_any( + ( + item_names.SWARM_QUEEN, + item_names.HYDRALISK, + item_names.ROACH, + item_names.MUTALISK, + item_names.INFESTED_BANSHEE, + ), + self.player, + ) + or self.morph_lurker(state) + or self.morph_brood_lord(state) + or ( + self.advanced_tactics + and ( + self.morph_impaler(state) + or self.morph_igniter(state) + or state.has_any((item_names.INFESTED_DIAMONDBACK, item_names.INFESTED_SIEGE_TANK), self.player) + ) + ) + ) + ) + + def protoss_outbreak_requirement(self, state: CollectionState) -> bool: + """ + Outbreak mission requirement + Something other than Zealot-based comp is required. + """ + return ( + self.protoss_defense_rating(state, True) >= 4 + and self.protoss_common_unit(state) + and self.protoss_basic_splash(state) + and ( + state.has_any( + ( + item_names.STALKER, + item_names.SLAYER, + item_names.INSTIGATOR, + item_names.ADEPT, + item_names.COLOSSUS, + item_names.VANGUARD, + item_names.SKIRMISHER, + item_names.OPPRESSOR, + item_names.CARRIER, + item_names.SKYLORD, + item_names.TRIREME, + item_names.DAWNBRINGER, + ), + self.player, + ) + or (self.advanced_tactics and (state.has_any((item_names.VOID_RAY, item_names.DESTROYER), self.player))) + ) + ) + + def terran_safe_haven_requirement(self, state: CollectionState) -> bool: + """Safe Haven mission requirement""" + return self.terran_common_unit(state) and self.terran_competent_anti_air(state) + + def terran_havens_fall_requirement(self, state: CollectionState) -> bool: + """Haven's Fall mission requirement""" + return self.terran_common_unit(state) and ( + self.terran_competent_comp(state) + or ( + self.terran_competent_anti_air(state) + and ( + state.has_any((item_names.VIKING, item_names.BATTLECRUISER), self.player) + or state.has_all((item_names.WRAITH, item_names.WRAITH_ADVANCED_LASER_TECHNOLOGY), self.player) + or state.has_all((item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY), self.player) + ) + ) + ) + + def terran_respond_to_colony_infestations(self, state: CollectionState) -> bool: + """ + Can deal quickly with Brood Lords and Mutas in Haven's Fall and being able to progress the mission + """ + return self.terran_havens_fall_requirement(state) and ( + self.terran_air_anti_air(state) + or ( + state.has_any({item_names.BATTLECRUISER, item_names.VALKYRIE}, self.player) + and self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, state) >= 2 + ) + ) + + def zerg_havens_fall_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_common_unit(state) + and self.zerg_competent_anti_air(state) + and (state.has(item_names.MUTALISK, self.player) or self.zerg_competent_comp(state)) + ) + + def zerg_respond_to_colony_infestations(self, state: CollectionState) -> bool: + """ + Can deal quickly with Brood Lords and Mutas in Haven's Fall and being able to progress the mission + """ + return self.zerg_havens_fall_requirement(state) and ( + self.morph_devourer(state) + or state.has_any({item_names.MUTALISK, item_names.CORRUPTOR}, self.player) + or self.advanced_tactics + and (self.morph_viper(state) or state.has_any({item_names.BROOD_QUEEN, item_names.SCOURGE}, self.player)) + ) + + def protoss_havens_fall_requirement(self, state: CollectionState) -> bool: + return ( + self.protoss_common_unit(state) + and self.protoss_competent_anti_air(state) + and ( + self.protoss_competent_comp(state) + or ( + state.has_any((item_names.TEMPEST, item_names.SKYLORD, item_names.DESTROYER), self.player) + or ( + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_PROTOSS_AIR_WEAPON, state) >= 2 + and state.has(item_names.CARRIER, self.player) + or state.has_all((item_names.SKIRMISHER, item_names.SKIRMISHER_PEER_CONTEMPT), self.player) + ) + ) + ) + ) + + def protoss_respond_to_colony_infestations(self, state: CollectionState) -> bool: + """ + Can deal quickly with Brood Lords and Mutas in Haven's Fall and being able to progress the mission + """ + return self.protoss_havens_fall_requirement(state) and ( + state.has_any({item_names.CARRIER, item_names.SKYLORD, item_names.DESTROYER, item_names.TEMPEST}, self.player) + # handle mutas + or ( + state.has_any( + { + item_names.PHOENIX, + item_names.MIRAGE, + item_names.CORSAIR, + }, + self.player, + ) + or state.has_all((item_names.SKIRMISHER, item_names.SKIRMISHER_PEER_CONTEMPT), self.player) + ) + # handle brood lords and virophages + and ( + state.has_any( + { + item_names.VOID_RAY, + }, + self.player, + ) + or self.advanced_tactics + and state.has_all({item_names.SCOUT, item_names.MISTWING}, self.player) + ) + ) + + def terran_gates_of_hell_requirement(self, state: CollectionState) -> bool: + """Gates of Hell mission requirement""" + return self.terran_competent_comp(state) and (self.terran_defense_rating(state, True) > 6) + + def zerg_gates_of_hell_requirement(self, state: CollectionState) -> bool: + """Gates of Hell mission requirement""" + return self.zerg_competent_comp_competent_aa(state) and (self.zerg_defense_rating(state, True) > 8) + + def protoss_gates_of_hell_requirement(self, state: CollectionState) -> bool: + """Gates of Hell mission requirement""" + return self.protoss_competent_comp(state) and (self.protoss_defense_rating(state, True) > 6) + + def terran_welcome_to_the_jungle_requirement(self, state: CollectionState) -> bool: + """ + Welcome to the Jungle requirements - able to deal with Scouts, Void Rays, Zealots and Stalkers + """ + if self.terran_power_rating(state) < 5: + return False + return (self.terran_common_unit(state) and self.terran_competent_ground_to_air(state)) or ( + self.advanced_tactics + and state.has_any({item_names.MARINE, item_names.DOMINION_TROOPER, item_names.VULTURE}, self.player) + and self.terran_air_anti_air(state) + ) + + def zerg_welcome_to_the_jungle_requirement(self, state: CollectionState) -> bool: + """ + Welcome to the Jungle requirements - able to deal with Scouts, Void Rays, Zealots and Stalkers + """ + if self.zerg_power_rating(state) < 5: + return False + return (self.zerg_competent_comp(state) and state.has_any({item_names.HYDRALISK, item_names.MUTALISK}, self.player)) or ( + self.advanced_tactics + and self.zerg_common_unit(state) + and ( + state.has_any({item_names.MUTALISK, item_names.INFESTOR}, self.player) + or (self.morph_devourer(state) and state.has_any({item_names.HYDRALISK, item_names.SWARM_QUEEN}, self.player)) + or (self.morph_viper(state) and state.has(item_names.VIPER_PARASITIC_BOMB, self.player)) + ) + and self.zerg_army_weapon_armor_upgrade_min_level(state) >= 1 + ) + + def protoss_welcome_to_the_jungle_requirement(self, state: CollectionState) -> bool: + """ + Welcome to the Jungle requirements - able to deal with Scouts, Void Rays, Zealots and Stalkers + """ + if self.protoss_power_rating(state) < 5: + return False + return self.protoss_common_unit(state) and self.protoss_anti_armor_anti_air(state) + + def terran_can_grab_ghosts_in_the_fog_east_rock_formation(self, state: CollectionState) -> bool: + """ + Able to shoot by a long range or from air to claim the rock formation separated by a chasm + """ + return ( + state.has_any( + { + item_names.MEDIVAC, + item_names.HERCULES, + item_names.VIKING, + item_names.BANSHEE, + item_names.WRAITH, + item_names.SIEGE_TANK, + item_names.BATTLECRUISER, + item_names.NIGHT_HAWK, + item_names.NIGHT_WOLF, + item_names.SHOCK_DIVISION, + item_names.SKY_FURY, + }, + self.player, + ) + or state.has_all({item_names.VALKYRIE, item_names.VALKYRIE_FLECHETTE_MISSILES}, self.player) + or state.has_all({item_names.RAVEN, item_names.RAVEN_HUNTER_SEEKER_WEAPON}, self.player) + or ( + state.has_any({item_names.LIBERATOR, item_names.EMPERORS_GUARDIAN}, self.player) + and state.has(item_names.LIBERATOR_RAID_ARTILLERY, self.player) + ) + or ( + self.advanced_tactics + and ( + state.has_any( + { + item_names.HELS_ANGELS, + item_names.DUSK_WINGS, + item_names.WINGED_NIGHTMARES, + item_names.SIEGE_BREAKERS, + item_names.BRYNHILDS, + item_names.JACKSONS_REVENGE, + }, + self.player, + ) + ) + or state.has_all({item_names.MIDNIGHT_RIDERS, item_names.LIBERATOR_RAID_ARTILLERY}, self.player) + ) + ) + + def terran_great_train_robbery_train_stopper(self, state: CollectionState) -> bool: + """ + Ability to deal with trains (moving target with a lot of HP) + """ + return state.has_any( + {item_names.SIEGE_TANK, item_names.DIAMONDBACK, item_names.MARAUDER, item_names.CYCLONE, item_names.BANSHEE}, self.player + ) or ( + self.advanced_tactics + and ( + state.has_all({item_names.REAPER, item_names.REAPER_G4_CLUSTERBOMB}, self.player) + or state.has_all({item_names.SPECTRE, item_names.SPECTRE_PSIONIC_LASH}, self.player) + or state.has_any({item_names.VULTURE, item_names.LIBERATOR}, self.player) + ) + ) + + def zerg_great_train_robbery_train_stopper(self, state: CollectionState) -> bool: + """ + Ability to deal with trains (moving target with a lot of HP) + """ + return ( + state.has_any( + ( + item_names.ABERRATION, + item_names.INFESTED_DIAMONDBACK, + item_names.INFESTED_BANSHEE, + ), + self.player, + ) + or state.has_all({item_names.MUTALISK, item_names.MUTALISK_SUNDERING_GLAIVE}, self.player) + or state.has_all((item_names.HYDRALISK, item_names.HYDRALISK_MUSCULAR_AUGMENTS), self.player) + or ( + state.has(item_names.ZERGLING, self.player) + and ( + state.has_any( + (item_names.ZERGLING_SHREDDING_CLAWS, item_names.ZERGLING_SHREDDING_CLAWS, item_names.ZERGLING_RAPTOR_STRAIN), self.player + ) + ) + and (self.advanced_tactics or state.has_any((item_names.ZERGLING_METABOLIC_BOOST, item_names.ZERGLING_RAPTOR_STRAIN), self.player)) + ) + or self.zerg_infested_tank_with_ammo(state) + or (self.advanced_tactics and (self.morph_tyrannozor(state))) + ) + + def protoss_great_train_robbery_train_stopper(self, state: CollectionState) -> bool: + """ + Ability to deal with trains (moving target with a lot of HP) + """ + return ( + state.has_any( + (item_names.ANNIHILATOR, item_names.IMMORTAL, item_names.STALKER, item_names.WRATHWALKER, item_names.VOID_RAY, item_names.DESTROYER), + self.player, + ) + or state.has_all({item_names.SLAYER, item_names.SLAYER_PHASE_BLINK}, self.player) + or state.has_all((item_names.REAVER, item_names.REAVER_KHALAI_REPLICATORS), self.player) + or state.has_all({item_names.VANGUARD, item_names.VANGUARD_FUSION_MORTARS}, self.player) + or ( + state.has(item_names.INSTIGATOR, self.player) + and state.has_any((item_names.INSTIGATOR_BLINK_OVERDRIVE, item_names.INSTIGATOR_MODERNIZED_SERVOS), self.player) + ) + or (state.has_all((item_names.OPPRESSOR, item_names.SCOUT_GRAVITIC_THRUSTERS, item_names.SCOUT_ADVANCED_PHOTON_BLASTERS), self.player)) + or state.has_all((item_names.ORACLE, item_names.ORACLE_TEMPORAL_ACCELERATION_BEAM), self.player) + or ( + self.advanced_tactics + and ( + state.has(item_names.TEMPEST, self.player) + or state.has_all((item_names.ADEPT, item_names.ADEPT_RESONATING_GLAIVES), self.player) + or state.has_all({item_names.VANGUARD, item_names.VANGUARD_RAPIDFIRE_CANNON}, self.player) + or state.has_all((item_names.OPPRESSOR, item_names.SCOUT_GRAVITIC_THRUSTERS, item_names.OPPRESSOR_VULCAN_BLASTER), self.player) + or state.has_all((item_names.ASCENDANT, item_names.ASCENDANT_POWER_OVERWHELMING, item_names.SUPPLICANT), self.player) + or state.has_all( + (item_names.DARK_TEMPLAR, item_names.DARK_TEMPLAR_LESSER_SHADOW_FURY, item_names.DARK_TEMPLAR_GREATER_SHADOW_FURY), + self.player, + ) + or ( + state.has(item_names.DARK_TEMPLAR_AVENGER_BLOOD_HUNTER_BLINK, self.player) + and ( + state.has_any((item_names.DARK_TEMPLAR, item_names.AVENGER), self.player) + or state.has_all((item_names.BLOOD_HUNTER, item_names.BLOOD_HUNTER_BRUTAL_EFFICIENCY), self.player) + ) + ) + ) + ) + ) + + def terran_can_rescue(self, state) -> bool: + """ + Rescuing in The Moebius Factor + """ + return state.has_any({item_names.MEDIVAC, item_names.HERCULES, item_names.RAVEN, item_names.VIKING}, self.player) or self.advanced_tactics + + def terran_supernova_requirement(self, state) -> bool: + return self.terran_beats_protoss_deathball(state) and self.terran_power_rating(state) >= 6 + + def zerg_supernova_requirement(self, state) -> bool: + return ( + self.zerg_common_unit(state) + and self.zerg_power_rating(state) >= 6 + and (self.advanced_tactics or state.has(item_names.YGGDRASIL, self.player)) + ) + + def protoss_supernova_requirement(self, state: CollectionState): + return ( + ( + state.count(item_names.PROGRESSIVE_WARP_RELOCATE, self.player) >= 2 + or (self.advanced_tactics and state.has(item_names.PROGRESSIVE_WARP_RELOCATE, self.player)) + ) + and self.protoss_competent_anti_air(state) + and (self.protoss_fleet(state) or (self.protoss_competent_comp(state) and self.protoss_power_rating(state) >= 6)) + ) + + def terran_maw_requirement(self, state: CollectionState) -> bool: + """ + Ability to deal with large areas with environment damage + """ + return ( + state.has(item_names.BATTLECRUISER, self.player) + and ( + self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, state) >= 2 + or state.has(item_names.BATTLECRUISER_ATX_LASER_BATTERY, self.player) + ) + ) or ( + self.terran_air(state) + and ( + # Avoid dropping Troopers or units that do barely damage + state.has_any( + ( + item_names.GOLIATH, + item_names.THOR, + item_names.WARHOUND, + item_names.VIKING, + item_names.BANSHEE, + item_names.WRAITH, + item_names.BATTLECRUISER, + ), + self.player, + ) + or state.has_all((item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY), self.player) + or state.has_all((item_names.VALKYRIE, item_names.VALKYRIE_FLECHETTE_MISSILES), self.player) + or (state.has(item_names.MARAUDER, self.player) and self.terran_bio_heal(state)) + ) + and ( + # Can deal damage to air units inside rip fields + state.has_any((item_names.GOLIATH, item_names.CYCLONE, item_names.VIKING), self.player) + or ( + state.has_any((item_names.WRAITH, item_names.VALKYRIE, item_names.BATTLECRUISER), self.player) + and self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, state) >= 2 + ) + or state.has_all((item_names.THOR, item_names.THOR_PROGRESSIVE_HIGH_IMPACT_PAYLOAD), self.player) + ) + and self.terran_competent_comp(state) + and self.terran_competent_anti_air(state) + and self.terran_sustainable_mech_heal(state) + ) + + def zerg_maw_requirement(self, state: CollectionState) -> bool: + """ + Ability to cross defended gaps, deal with skytoss, and avoid costly losses. + """ + if self.advanced_tactics and state.has(item_names.INFESTOR, self.player): + return True + usable_muta = ( + state.has_all((item_names.MUTALISK, item_names.MUTALISK_RAPID_REGENERATION), self.player) + and state.has_any((item_names.MUTALISK_SEVERING_GLAIVE, item_names.MUTALISK_VICIOUS_GLAIVE), self.player) + and ( + state.has(item_names.MUTALISK_SUNDERING_GLAIVE, self.player) + or state.has_all((item_names.MUTALISK_SEVERING_GLAIVE, item_names.MUTALISK_VICIOUS_GLAIVE), self.player) + ) + ) + return ( + # Heal + ( + state.has(item_names.SWARM_QUEEN, self.player) + or self.advanced_tactics + and ((self.morph_tyrannozor(state) and state.has(item_names.TYRANNOZOR_HEALING_ADAPTATION, self.player)) or (usable_muta)) + ) + # Cross the gap + and ( + state.has_any((item_names.NYDUS_WORM, item_names.OVERLORD_VENTRAL_SACS), self.player) + or (self.advanced_tactics and state.has(item_names.YGGDRASIL, self.player)) + ) + # Air to ground + and (self.morph_brood_lord(state) or self.morph_guardian(state) or usable_muta) + # Ground to air + and ( + state.has(item_names.INFESTOR, self.player) + or self.morph_tyrannozor(state) + or state.has_all( + {item_names.SWARM_HOST, item_names.SWARM_HOST_RESOURCE_EFFICIENCY, item_names.SWARM_HOST_PRESSURIZED_GLANDS}, self.player + ) + or state.has_all({item_names.HYDRALISK, item_names.HYDRALISK_RESOURCE_EFFICIENCY}, self.player) + or state.has_all({item_names.INFESTED_DIAMONDBACK, item_names.INFESTED_DIAMONDBACK_PROGRESSIVE_FUNGAL_SNARE}, self.player) + ) + # Survives rip-field + and ( + state.has_any({item_names.ABERRATION, item_names.ROACH, item_names.ULTRALISK}, self.player) + or self.morph_tyrannozor(state) + or (self.advanced_tactics and usable_muta) + ) + # Air-to-air + and (state.has_any({item_names.MUTALISK, item_names.CORRUPTOR, item_names.INFESTED_LIBERATOR, item_names.BROOD_QUEEN}, self.player)) + # Upgrades / general + and self.zerg_competent_anti_air(state) + and self.zerg_competent_comp(state) + ) + + def protoss_maw_requirement(self, state: CollectionState) -> bool: + """ + Ability to cross defended gaps and deal with skytoss. + """ + return ( + ( + state.has(item_names.WARP_PRISM, self.player) + or ( + self.advanced_tactics + and (state.has(item_names.ARBITER, self.player) or state.has_all((item_names.MISTWING, item_names.MISTWING_PILOT), self.player)) + ) + ) + and self.protoss_common_unit_anti_armor_air(state) + and self.protoss_fleet(state) + ) + + def terran_engine_of_destruction_requirement(self, state: CollectionState) -> int: + power_rating = self.terran_power_rating(state) + if power_rating < 3 or not self.marine_medic_upgrade(state) or not self.terran_common_unit(state): + return False + if power_rating >= 7 and self.terran_competent_comp(state): + return True + else: + return ( + state.has_any((item_names.WRAITH, item_names.BATTLECRUISER), self.player) + or self.terran_air_anti_air(state) + and state.has_any((item_names.BANSHEE, item_names.LIBERATOR), self.player) + ) + + def zerg_engine_of_destruction_requirement(self, state: CollectionState) -> int: + power_rating = self.zerg_power_rating(state) + if ( + power_rating < 3 + or not self.zergling_hydra_roach_start(state) + or not self.zerg_common_unit(state) + or not self.zerg_competent_anti_air(state) + or not self.zerg_repair_odin(state) + ): + return False + if power_rating >= 7 and self.zerg_competent_comp(state): + return True + else: + return self.zerg_base_buster(state) + + def protoss_engine_of_destruction_requirement(self, state: CollectionState): + return ( + self.zealot_sentry_slayer_start(state) + and self.protoss_repair_odin(state) + and (self.protoss_deathball(state) or self.protoss_fleet(state)) + ) + + def zerg_repair_odin(self, state: CollectionState): + return ( + self.zerg_has_infested_scv(state) + or state.has_all({item_names.SWARM_QUEEN_BIO_MECHANICAL_TRANSFUSION, item_names.SWARM_QUEEN}, self.player) + or (self.advanced_tactics and state.has(item_names.SWARM_QUEEN, self.player)) + ) + + def protoss_repair_odin(self, state: CollectionState): + return ( + state.has(item_names.SENTRY, self.player) + or state.has_all((item_names.CARRIER, item_names.CARRIER_REPAIR_DRONES), self.player) + or ( + self.spear_of_adun_passive_presence + in [SpearOfAdunPassiveAbilityPresence.option_protoss, SpearOfAdunPassiveAbilityPresence.option_everywhere] + and state.has(item_names.RECONSTRUCTION_BEAM, self.player) + ) + or (self.advanced_tactics and state.has_all({item_names.SHIELD_BATTERY, item_names.KHALAI_INGENUITY}, self.player)) + ) + + def terran_in_utter_darkness_requirement(self, state: CollectionState) -> bool: + return self.terran_competent_comp(state) and self.terran_defense_rating(state, True, True) >= 8 + + def zerg_in_utter_darkness_requirement(self, state: CollectionState) -> bool: + return self.zerg_competent_comp(state) and self.zerg_competent_anti_air(state) and self.zerg_defense_rating(state, True, True) >= 8 + + def protoss_in_utter_darkness_requirement(self, state: CollectionState) -> bool: + return self.protoss_competent_comp(state) and self.protoss_defense_rating(state, True) >= 4 + + def terran_all_in_requirement(self, state: CollectionState): + """ + All-in + """ + if not self.terran_very_hard_mission_weapon_armor_level(state): + return False + beats_kerrigan = ( + state.has_any({item_names.MARINE, item_names.DOMINION_TROOPER, item_names.BANSHEE}, self.player) + or state.has_all({item_names.REAPER, item_names.REAPER_RESOURCE_EFFICIENCY}, self.player) + or (self.all_in_map == AllInMap.option_air and state.has_all((item_names.VALKYRIE, item_names.VALKYRIE_FLECHETTE_MISSILES), self.player)) + or (self.advanced_tactics and state.has_all((item_names.GHOST, item_names.GHOST_EMP_ROUNDS), self.player)) + ) + if not beats_kerrigan: + return False + if not self.terran_competent_comp(state): + return False + if self.all_in_map == AllInMap.option_ground: + # Ground + defense_rating = self.terran_defense_rating(state, True, False) + if state.has_any({item_names.BATTLECRUISER, item_names.BANSHEE}, self.player): + defense_rating += 2 + return defense_rating >= 13 + else: + # Air + defense_rating = self.terran_defense_rating(state, True, True) + return ( + defense_rating >= 9 + and self.terran_competent_anti_air(state) + and state.has_any({item_names.VIKING, item_names.BATTLECRUISER, item_names.VALKYRIE}, self.player) + and state.has_any({item_names.HIVE_MIND_EMULATOR, item_names.PSI_DISRUPTER, item_names.MISSILE_TURRET}, self.player) + ) + + def zerg_all_in_requirement(self, state: CollectionState): + """ + All-in (Zerg) + """ + if not self.zerg_very_hard_mission_weapon_armor_level(state): + return False + beats_kerrigan = ( + state.has_any({item_names.INFESTED_MARINE, item_names.INFESTED_BANSHEE, item_names.INFESTED_BUNKER}, self.player) + or state.has_all({item_names.SWARM_HOST, item_names.SWARM_HOST_RESOURCE_EFFICIENCY}, self.player) + or self.morph_brood_lord(state) + ) + if not beats_kerrigan: + return False + if not self.zerg_competent_comp(state): + return False + if self.all_in_map == AllInMap.option_ground: + # Ground + defense_rating = self.zerg_defense_rating(state, True, False) + if ( + state.has_any({item_names.MUTALISK, item_names.INFESTED_BANSHEE}, self.player) + or self.morph_brood_lord(state) + or self.morph_guardian(state) + ): + defense_rating += 3 + if state.has(item_names.SPINE_CRAWLER, self.player): + defense_rating += 2 + return defense_rating >= 13 + else: + # Air + defense_rating = self.zerg_defense_rating(state, True, True) + return ( + defense_rating >= 9 + and state.has_any({item_names.MUTALISK, item_names.CORRUPTOR}, self.player) + and state.has_any({item_names.SPORE_CRAWLER, item_names.INFESTED_MISSILE_TURRET}, self.player) + ) + + def protoss_all_in_requirement(self, state: CollectionState): + """ + All-in (Protoss) + """ + if not self.protoss_very_hard_mission_weapon_armor_level(state): + return False + beats_kerrigan = ( + # cheap units with multiple small attacks, or anything with Feedback + state.has_any({item_names.ZEALOT, item_names.SENTINEL, item_names.SKIRMISHER, item_names.HIGH_TEMPLAR}, self.player) + or state.has_all((item_names.CENTURION, item_names.CENTURION_RESOURCE_EFFICIENCY), self.player) + or state.has_all({item_names.SIGNIFIER, item_names.SIGNIFIER_FEEDBACK}, self.player) + or (self.protoss_can_merge_archon(state) and state.has(item_names.ARCHON_HIGH_ARCHON, self.player)) + or (self.protoss_can_merge_dark_archon(state) and state.has(item_names.DARK_ARCHON_FEEDBACK, self.player)) + ) + if not beats_kerrigan: + return False + if not self.protoss_competent_comp(state): + return False + if self.all_in_map == AllInMap.option_ground: + # Ground + defense_rating = self.protoss_defense_rating(state, True) + if ( + state.has_any({item_names.SKIRMISHER, item_names.DARK_TEMPLAR, item_names.TEMPEST, item_names.TRIREME}, self.player) + or state.has_all((item_names.BLOOD_HUNTER, item_names.BLOOD_HUNTER_BRUTAL_EFFICIENCY), self.player) + or state.has_all((item_names.AVENGER, item_names.AVENGER_KRYHAS_CLOAK), self.player) + ): + defense_rating += 2 + if state.has(item_names.PHOTON_CANNON, self.player): + defense_rating += 2 + return defense_rating >= 13 + else: + # Air + defense_rating = self.protoss_defense_rating(state, True) + if state.has(item_names.KHAYDARIN_MONOLITH, self.player): + defense_rating += 2 + if state.has(item_names.PHOTON_CANNON, self.player): + defense_rating += 2 + return defense_rating >= 9 and (state.has_any({item_names.TEMPEST, item_names.SKYLORD, item_names.VOID_RAY}, self.player)) + + def zerg_can_grab_ghosts_in_the_fog_east_rock_formation(self, state: CollectionState) -> bool: + return ( + state.has_any({item_names.MUTALISK, item_names.INFESTED_BANSHEE, item_names.OVERLORD_VENTRAL_SACS, item_names.INFESTOR}, self.player) + or (self.morph_devourer(state) and state.has(item_names.DEVOURER_PRESCIENT_SPORES, self.player)) + or (self.morph_guardian(state) and state.has(item_names.GUARDIAN_PRIMAL_ADAPTATION, self.player)) + or ((self.morph_guardian(state) or self.morph_brood_lord(state)) and self.zerg_basic_air_to_air(state)) + or ( + self.advanced_tactics + and ( + state.has_any({item_names.INFESTED_SIEGE_BREAKERS, item_names.INFESTED_DUSK_WINGS}, self.player) + or (state.has(item_names.HUNTERLING, self.player) and self.zerg_basic_air_to_air(state)) + ) + ) + ) + def zerg_any_units_back_in_the_saddle_requirement(self, state: CollectionState) -> bool: + return ( + self.grant_story_tech == GrantStoryTech.option_grant + # Note(mm): This check isn't necessary as self.kerrigan_levels cover it, + # and it's not fully desirable in future when we support non-grant story tech + kerriganless. + # or not self.kerrigan_presence + or state.has_any(( + # Cases tested by Snarky + item_names.KERRIGAN_KINETIC_BLAST, + item_names.KERRIGAN_LEAPING_STRIKE, + item_names.KERRIGAN_CRUSHING_GRIP, + item_names.KERRIGAN_PSIONIC_SHIFT, + item_names.KERRIGAN_SPAWN_BANELINGS, + item_names.KERRIGAN_FURY, + item_names.KERRIGAN_APOCALYPSE, + item_names.KERRIGAN_DROP_PODS, + item_names.KERRIGAN_SPAWN_LEVIATHAN, + item_names.KERRIGAN_IMMOBILIZATION_WAVE, # Involves a 1-minute cooldown wait before the ultra + item_names.KERRIGAN_MEND, # See note from THE EV below + ), self.player) + or self.kerrigan_levels(state, 20) + or (self.kerrigan_levels(state, 10) and state.has(item_names.KERRIGAN_CHAIN_REACTION, self.player)) + # Tested by THE EV, "facetank with Kerrigan and stutter step to the end with >10s left" + # > have to lure the first group of Zerg in the 2nd timed section into the first room of the second area + # > (with the heal box) so you can kill them before the timer starts. + # + # phaneros: Technically possible without the levels, but adding them in for safety margin and to hopefully + # make generation force this branch less often + or (state.has_any((item_names.KERRIGAN_HEROIC_FORTITUDE, item_names.KERRIGAN_INFEST_BROODLINGS), self.player) + and self.kerrigan_levels(state, 5) + ) + # Insufficient: Wild Mutation, Assimilation Aura + ) + + def zerg_pass_vents(self, state: CollectionState) -> bool: + return ( + self.grant_story_tech == GrantStoryTech.option_grant + or state.has_any({item_names.ZERGLING, item_names.HYDRALISK, item_names.ROACH}, self.player) + or (self.advanced_tactics and state.has(item_names.INFESTOR, self.player)) + ) + + def supreme_requirement(self, state: CollectionState) -> bool: + return ( + self.grant_story_tech == GrantStoryTech.option_grant + or not self.kerrigan_unit_available or (self.grant_story_tech == GrantStoryTech.option_allow_substitutes + and state.has_any(( + item_names.KERRIGAN_LEAPING_STRIKE, + item_names.OVERLORD_VENTRAL_SACS, + item_names.YGGDRASIL, + item_names.MUTALISK_CORRUPTOR_VIPER_ASPECT, + item_names.NYDUS_WORM, + item_names.BULLFROG, + ), self.player) + and state.has_any(( + item_names.KERRIGAN_MEND, + item_names.SWARM_QUEEN, + item_names.INFESTED_MEDICS, + ), self.player) + and self.kerrigan_levels(state, 35) + ) + or (state.has_all((item_names.KERRIGAN_LEAPING_STRIKE, item_names.KERRIGAN_MEND), self.player) and self.kerrigan_levels(state, 35)) + ) + + def terran_infested_garrison_claimer(self, state: CollectionState) -> bool: + return state.has_any((item_names.GHOST, item_names.SPECTRE, item_names.EMPERORS_SHADOW), self.player) + + def protoss_infested_garrison_claimer(self, state: CollectionState) -> bool: + return state.has_any( + (item_names.HIGH_TEMPLAR, item_names.SIGNIFIER, item_names.ASCENDANT), self.player + ) or self.protoss_can_merge_dark_archon(state) + + def terran_hand_of_darkness_requirement(self, state: CollectionState) -> bool: + return self.terran_competent_comp(state) and self.terran_power_rating(state) >= 6 + + def zerg_hand_of_darkness_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_comp(state) + and (self.zerg_competent_anti_air(state) or self.advanced_tactics and self.zerg_moderate_anti_air(state)) + and (self.basic_kerrigan(state) or self.zerg_power_rating(state) >= 4) + ) + + def protoss_hand_of_darkness_requirement(self, state: CollectionState) -> bool: + return self.protoss_competent_comp(state) and self.protoss_power_rating(state) >= 6 + + def terran_planetfall_requirement(self, state: CollectionState) -> bool: + return self.terran_beats_protoss_deathball(state) and self.terran_power_rating(state) >= 8 + + def zerg_planetfall_requirement(self, state: CollectionState) -> bool: + return self.zerg_competent_comp(state) and self.zerg_competent_anti_air(state) and self.zerg_power_rating(state) >= 8 + + def protoss_planetfall_requirement(self, state: CollectionState) -> bool: + return self.protoss_deathball(state) and self.protoss_power_rating(state) >= 8 + + def zerg_the_reckoning_requirement(self, state: CollectionState) -> bool: + if not (self.zerg_power_rating(state) >= 6 or self.basic_kerrigan(state)): + return False + if self.take_over_ai_allies: + return ( + self.terran_competent_comp(state) + and self.zerg_competent_comp(state) + and (self.zerg_competent_anti_air(state) or self.terran_competent_anti_air(state)) + and self.terran_very_hard_mission_weapon_armor_level(state) + and self.zerg_very_hard_mission_weapon_armor_level(state) + ) + else: + return self.zerg_competent_comp(state) and self.zerg_competent_anti_air(state) and self.zerg_very_hard_mission_weapon_armor_level(state) + + def terran_the_reckoning_requirement(self, state: CollectionState) -> bool: + return self.terran_very_hard_mission_weapon_armor_level(state) and self.terran_base_trasher(state) + + def protoss_the_reckoning_requirement(self, state: CollectionState) -> bool: + return ( + self.protoss_very_hard_mission_weapon_armor_level(state) + and self.protoss_deathball(state) + and (not self.take_over_ai_allies or (self.terran_competent_comp(state) and self.terran_very_hard_mission_weapon_armor_level(state))) + ) + + def protoss_can_attack_behind_chasm(self, state: CollectionState) -> bool: + return ( + state.has_any( + { + item_names.SCOUT, + item_names.TEMPEST, + item_names.CARRIER, + item_names.SKYLORD, + item_names.TRIREME, + item_names.VOID_RAY, + item_names.DESTROYER, + item_names.PULSAR, + item_names.DAWNBRINGER, + item_names.MOTHERSHIP, + }, + self.player, + ) + or self.protoss_has_blink(state) + or ( + state.has(item_names.WARP_PRISM, self.player) + and (self.protoss_common_unit(state) or state.has(item_names.WARP_PRISM_PHASE_BLASTER, self.player)) + ) + or (self.advanced_tactics and state.has_any({item_names.ORACLE, item_names.ARBITER}, self.player)) + ) + + def the_infinite_cycle_requirement(self, state: CollectionState) -> bool: + return ( + self.grant_story_tech == GrantStoryTech.option_grant + or not self.kerrigan_unit_available + or ( + state.has_any( + ( + item_names.KERRIGAN_KINETIC_BLAST, + item_names.KERRIGAN_SPAWN_BANELINGS, + item_names.KERRIGAN_LEAPING_STRIKE, + item_names.KERRIGAN_SPAWN_LEVIATHAN, + ), + self.player, + ) + and self.basic_kerrigan(state) + and self.kerrigan_levels(state, 70) + ) + ) + + def templars_return_phase_2_requirement(self, state: CollectionState) -> bool: + return ( + self.grant_story_tech == GrantStoryTech.option_grant + or self.advanced_tactics + or ( + state.has_any( + ( + item_names.IMMORTAL, + item_names.ANNIHILATOR, + item_names.VANGUARD, + item_names.COLOSSUS, + item_names.WRATHWALKER, + item_names.REAVER, + item_names.DARK_TEMPLAR, + item_names.HIGH_TEMPLAR, + item_names.ENERGIZER, + item_names.SENTRY, + ), + self.player, + ) + ) + ) + + def templars_return_phase_3_reach_colossus_requirement(self, state: CollectionState) -> bool: + return self.templars_return_phase_2_requirement(state) and ( + self.grant_story_tech == GrantStoryTech.option_grant + or self.advanced_tactics + and state.has_any({item_names.ZEALOT_WHIRLWIND, item_names.VANGUARD_RAPIDFIRE_CANNON}, self.player) + or state.has_all(( + item_names.ZEALOT_WHIRLWIND, item_names.VANGUARD_RAPIDFIRE_CANNON + ), self.player) + ) + + def templars_return_phase_3_reach_dts_requirement(self, state: CollectionState) -> bool: + return self.templars_return_phase_3_reach_colossus_requirement(state) and ( + self.grant_story_tech == GrantStoryTech.option_grant + or ( + (self.advanced_tactics or state.has(item_names.ENERGIZER_MOBILE_CHRONO_BEAM, self.player)) + and (state.has(item_names.COLOSSUS_FIRE_LANCE, self.player) + or ( + state.has_all( + { + item_names.COLOSSUS_PACIFICATION_PROTOCOL, + item_names.ENERGIZER_MOBILE_CHRONO_BEAM, + }, + self.player, + ) + ) + )) + ) + + def terran_spear_of_adun_requirement(self, state: CollectionState) -> bool: + return self.terran_common_unit(state) and self.terran_competent_anti_air(state) and self.terran_defense_rating(state, False, False) >= 5 + + def zerg_spear_of_adun_requirement(self, state: CollectionState) -> bool: + return self.zerg_common_unit(state) and self.zerg_competent_anti_air(state) and self.zerg_defense_rating(state, False, False) >= 5 + + def protoss_spear_of_adun_requirement(self, state: CollectionState) -> bool: + return ( + self.protoss_common_unit(state) + and self.protoss_anti_light_anti_air(state) + and ( + state.has_any((item_names.ZEALOT, item_names.CENTURION, item_names.SENTINEL, item_names.ADEPT), self.player) + or self.protoss_basic_splash(state) + ) + and self.protoss_defense_rating(state, False) >= 5 + ) + + def terran_sky_shield_requirement(self, state: CollectionState) -> bool: + return self.terran_common_unit(state) and self.terran_competent_anti_air(state) and self.terran_power_rating(state) >= 7 + + def zerg_sky_shield_requirement(self, state: CollectionState) -> bool: + return self.zerg_common_unit(state) and self.zerg_competent_anti_air(state) and self.zerg_power_rating(state) >= 7 + + def protoss_sky_shield_requirement(self, state: CollectionState) -> bool: + return self.protoss_common_unit(state) and self.protoss_competent_anti_air(state) and self.protoss_power_rating(state) >= 7 + + def protoss_brothers_in_arms_requirement(self, state: CollectionState) -> bool: + return (self.protoss_common_unit(state) and self.protoss_anti_armor_anti_air(state) and self.protoss_hybrid_counter(state)) or ( + self.take_over_ai_allies + and (self.terran_common_unit(state) or self.protoss_common_unit(state)) + and (self.terran_competent_anti_air(state) or self.protoss_anti_armor_anti_air(state)) + and ( + self.protoss_hybrid_counter(state) + or state.has_any({item_names.BATTLECRUISER, item_names.LIBERATOR, item_names.SIEGE_TANK}, self.player) + or (self.advanced_tactics and state.has_all({item_names.SPECTRE, item_names.SPECTRE_PSIONIC_LASH}, self.player)) + or ( + state.has(item_names.IMMORTAL, self.player) + and state.has_any({item_names.MARINE, item_names.DOMINION_TROOPER, item_names.MARAUDER}, self.player) + and self.terran_bio_heal(state) + ) + ) + ) + + def zerg_brothers_in_arms_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_common_unit(state) and self.zerg_competent_comp(state) and self.zerg_competent_anti_air(state) and self.zerg_big_monsters(state) + ) or ( + self.take_over_ai_allies + and (self.zerg_common_unit(state) or self.terran_common_unit(state)) + and (self.terran_competent_anti_air(state) or self.zerg_competent_anti_air(state)) + and ( + self.zerg_big_monsters(state) + or state.has_any({item_names.BATTLECRUISER, item_names.LIBERATOR, item_names.SIEGE_TANK}, self.player) + or (self.advanced_tactics and state.has_all({item_names.SPECTRE, item_names.SPECTRE_PSIONIC_LASH}, self.player)) + or ( + state.has(item_names.ABERRATION, self.player) + and state.has_any({item_names.MARINE, item_names.DOMINION_TROOPER, item_names.MARAUDER}, self.player) + and self.terran_bio_heal(state) + ) + ) + ) + + def protoss_amons_reach_requirement(self, state: CollectionState) -> bool: + return self.protoss_common_unit_anti_light_air(state) and self.protoss_basic_splash(state) and self.protoss_power_rating(state) >= 7 + + def protoss_last_stand_requirement(self, state: CollectionState) -> bool: + return ( + self.protoss_common_unit(state) + and self.protoss_competent_anti_air(state) + and self.protoss_static_defense(state) + and self.protoss_defense_rating(state, False) >= 8 + ) + + def terran_last_stand_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_common_unit(state) + and state.has_any({item_names.SIEGE_TANK, item_names.LIBERATOR}, self.player) + and state.has_any({item_names.PERDITION_TURRET, item_names.DEVASTATOR_TURRET, item_names.PLANETARY_FORTRESS}, self.player) + and self.terran_air_anti_air(state) + and state.has_any({item_names.VIKING, item_names.BATTLECRUISER}, self.player) + and self.terran_defense_rating(state, True, False) >= 10 + and self.terran_army_weapon_armor_upgrade_min_level(state) >= 2 + ) + + def zerg_last_stand_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_common_unit(state) + and self.zerg_competent_anti_air(state) + and state.has(item_names.SPINE_CRAWLER, self.player) + and ( + self.morph_lurker(state) + or state.has_all({item_names.MUTALISK, item_names.MUTALISK_SEVERING_GLAIVE, item_names.MUTALISK_VICIOUS_GLAIVE}, self.player) + or self.zerg_infested_tank_with_ammo(state) + or self.advanced_tactics + and state.has_all({item_names.ULTRALISK, item_names.ULTRALISK_CHITINOUS_PLATING, item_names.ULTRALISK_MONARCH_BLADES}, self.player) + ) + and ( + self.morph_impaler(state) + or state.has_all({item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_DEFENDER_MODE}, self.player) + or self.zerg_infested_tank_with_ammo(state) + or state.has(item_names.BILE_LAUNCHER, self.player) + ) + and ( + self.morph_devourer(state) + or state.has_all({item_names.MUTALISK, item_names.MUTALISK_SUNDERING_GLAIVE}, self.player) + or self.advanced_tactics + and state.has(item_names.BROOD_QUEEN, self.player) + ) + and self.zerg_mineral_dump(state) + and self.zerg_army_weapon_armor_upgrade_min_level(state) >= 2 + ) + + def terran_temple_of_unification_requirement(self, state: CollectionState) -> bool: + return self.terran_beats_protoss_deathball(state) and self.terran_power_rating(state) >= 10 + + def zerg_temple_of_unification_requirement(self, state: CollectionState) -> bool: + # Don't be locked to roach/hydra + return ( + self.zerg_competent_comp(state) + and self.zerg_competent_anti_air(state) + and ( + state.has(item_names.INFESTED_BANSHEE, self.player) + or state.has_all((item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_DEFENDER_MODE), self.player) + or state.has_all({item_names.MUTALISK, item_names.MUTALISK_SUNDERING_GLAIVE}, self.player) + or self.zerg_big_monsters(state) + or ( + self.advanced_tactics + and (state.has_any({item_names.INFESTOR, item_names.DEFILER, item_names.BROOD_QUEEN}, self.player) or self.morph_viper(state)) + ) + ) + and self.zerg_power_rating(state) >= 10 + ) + + def protoss_temple_of_unification_requirement(self, state: CollectionState) -> bool: + return self.protoss_competent_comp(state) and self.protoss_power_rating(state) >= 10 + + def protoss_harbinger_of_oblivion_requirement(self, state: CollectionState) -> bool: + return ( + self.protoss_anti_armor_anti_air(state) + and ( + self.take_over_ai_allies + and (self.protoss_common_unit(state) or self.zerg_common_unit(state)) + or (self.protoss_competent_comp(state) and self.protoss_hybrid_counter(state)) + ) + and self.protoss_power_rating(state) >= 6 + ) + + def terran_harbinger_of_oblivion_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_competent_anti_air(state) + and ( + self.take_over_ai_allies + and (self.terran_common_unit(state) or self.zerg_common_unit(state)) + or ( + self.terran_beats_protoss_deathball(state) + and state.has_any({item_names.BATTLECRUISER, item_names.LIBERATOR, item_names.SIEGE_TANK, item_names.THOR}, self.player) + ) + ) + and self.terran_power_rating(state) >= 6 + ) + + def zerg_harbinger_of_oblivion_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_anti_air(state) + and self.zerg_common_unit(state) + and (self.take_over_ai_allies or (self.zerg_competent_comp(state) and self.zerg_big_monsters(state))) + and self.zerg_power_rating(state) >= 6 + ) + + def terran_unsealing_the_past_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_competent_anti_air(state) + and self.terran_competent_comp(state) + and self.terran_power_rating(state) >= 6 + and ( + state.has_all({item_names.SIEGE_TANK, item_names.SIEGE_TANK_JUMP_JETS}, self.player) + or state.has_all( + {item_names.BATTLECRUISER, item_names.BATTLECRUISER_ATX_LASER_BATTERY, item_names.BATTLECRUISER_MOIRAI_IMPULSE_DRIVE}, self.player + ) + or ( + self.advanced_tactics + and ( + state.has_all({item_names.SIEGE_TANK, item_names.SIEGE_TANK_SMART_SERVOS}, self.player) + or ( + state.has_all({item_names.LIBERATOR, item_names.LIBERATOR_SMART_SERVOS}, self.player) + and ( + ( + state.has_all({item_names.HELLION, item_names.HELLION_HELLBAT}, self.player) + or state.has(item_names.FIREBAT, self.player) + ) + and self.terran_bio_heal(state) + or state.has_all({item_names.VIKING, item_names.VIKING_SHREDDER_ROUNDS}, self.player) + or state.has(item_names.BANSHEE, self.player) + ) + ) + ) + ) + ) + ) + + def zerg_unsealing_the_past_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_comp(state) + and self.zerg_competent_anti_air(state) + and self.zerg_power_rating(state) >= 6 + and ( + self.morph_brood_lord(state) + or self.zerg_big_monsters(state) + or state.has_all({item_names.MUTALISK, item_names.MUTALISK_SEVERING_GLAIVE, item_names.MUTALISK_VICIOUS_GLAIVE}, self.player) + or ( + self.advanced_tactics + and (self.morph_igniter(state) or (self.morph_lurker(state) and state.has(item_names.LURKER_SEISMIC_SPINES, self.player))) + ) + ) + ) + + def terran_purification_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_competent_comp(state) + and self.terran_very_hard_mission_weapon_armor_level(state) + and self.terran_defense_rating(state, True, False) >= 10 + and ( + state.has_any({item_names.LIBERATOR, item_names.THOR}, self.player) + or ( + state.has(item_names.SIEGE_TANK, self.player) + and (self.advanced_tactics or state.has(item_names.SIEGE_TANK_MAELSTROM_ROUNDS, self.player)) + ) + ) + and ( + state.has_all({item_names.VIKING, item_names.VIKING_SHREDDER_ROUNDS}, self.player) + or ( + state.has(item_names.BANSHEE, self.player) + and ( + state.has(item_names.BANSHEE_SHOCKWAVE_MISSILE_BATTERY, self.player) + or (self.advanced_tactics and state.has(item_names.BANSHEE_ROCKET_BARRAGE, self.player)) + ) + ) + ) + ) + + def zerg_purification_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_comp(state) + and self.zerg_competent_anti_air(state) + and self.zerg_defense_rating(state, True, True) >= 5 + and self.zerg_big_monsters(state) + and (state.has(item_names.ULTRALISK, self.player) or self.morph_igniter(state) or self.morph_lurker(state)) + ) + + def protoss_steps_of_the_rite_requirement(self, state: CollectionState) -> bool: + return self.protoss_deathball(state) or self.protoss_fleet(state) + + def terran_steps_of_the_rite_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_beats_protoss_deathball(state) + and ( + state.has_any({item_names.SIEGE_TANK, item_names.LIBERATOR}, self.player) + or state.has_all({item_names.BATTLECRUISER, item_names.BATTLECRUISER_ATX_LASER_BATTERY}, self.player) + or state.has_all((item_names.BANSHEE, item_names.BANSHEE_SHOCKWAVE_MISSILE_BATTERY), self.player) + ) + and ( + state.has_all({item_names.BATTLECRUISER, item_names.BATTLECRUISER_ATX_LASER_BATTERY}, self.player) + or state.has(item_names.VALKYRIE, self.player) + or state.has_all((item_names.VIKING, item_names.VIKING_RIPWAVE_MISSILES), self.player) + ) + and self.terran_very_hard_mission_weapon_armor_level(state) + ) + + def zerg_steps_of_the_rite_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_comp(state) + and self.zerg_competent_anti_air(state) + and self.zerg_base_buster(state) + and ( + self.morph_lurker(state) + or self.zerg_infested_tank_with_ammo(state) + or state.has_all({item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_DEFENDER_MODE}, self.player) + or (state.has(item_names.SWARM_QUEEN, self.player) and self.zerg_big_monsters(state)) + ) + and ( + state.has(item_names.INFESTED_LIBERATOR, self.player) + or state.has_all({item_names.MUTALISK, item_names.MUTALISK_SEVERING_GLAIVE, item_names.MUTALISK_VICIOUS_GLAIVE}, self.player) + or (state.has(item_names.MUTALISK, self.player) and self.morph_devourer(state)) + ) + ) + + def terran_rak_shir_requirement(self, state: CollectionState) -> bool: + return self.terran_beats_protoss_deathball(state) and self.terran_power_rating(state) >= 10 + + def zerg_rak_shir_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_comp(state) + and self.zerg_competent_anti_air(state) + and ( + self.zerg_big_monsters(state) + or state.has_all({item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_DEFENDER_MODE}, self.player) + or self.morph_impaler_or_lurker(state) + ) + and ( + state.has_all({item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_CLOUD_DISPERSAL}, self.player) + or ( + state.has(item_names.MUTALISK, self.player) + and (state.has(item_names.MUTALISK_SUNDERING_GLAIVE, self.player) or self.morph_devourer(state)) + ) + or state.has(item_names.CORRUPTOR, self.player) + or (self.advanced_tactics and state.has(item_names.INFESTOR, self.player)) + ) + and self.zerg_power_rating(state) >= 10 + ) + + def protoss_rak_shir_requirement(self, state: CollectionState) -> bool: + return (self.protoss_deathball(state) or self.protoss_fleet(state)) and self.protoss_power_rating(state) >= 10 + + def protoss_templars_charge_requirement(self, state: CollectionState) -> bool: + return ( + self.protoss_heal(state) + and self.protoss_anti_armor_anti_air(state) + and ( + self.protoss_fleet(state) + or ( + self.advanced_tactics + and self.protoss_competent_comp(state) + and ( + state.has_any((item_names.ARBITER, item_names.CORSAIR, item_names.PHOENIX), self.player) + or state.has_all((item_names.MIRAGE, item_names.MIRAGE_GRAVITON_BEAM), self.player) + ) + ) + ) + ) + + def terran_templars_charge_requirement(self, state: CollectionState) -> bool: + return self.terran_very_hard_mission_weapon_armor_level(state) and ( + ( + state.has_all({item_names.BATTLECRUISER, item_names.BATTLECRUISER_ATX_LASER_BATTERY}, self.player) + and state.count(item_names.BATTLECRUISER_PROGRESSIVE_DEFENSIVE_MATRIX, self.player) >= 2 + ) + or ( + self.terran_air_anti_air(state) + and self.terran_sustainable_mech_heal(state) + and ( + state.has_any({item_names.BANSHEE, item_names.BATTLECRUISER}, self.player) + or state.has_all({item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY}, self.player) + or (self.advanced_tactics and (state.has_all({item_names.WRAITH, item_names.WRAITH_ADVANCED_LASER_TECHNOLOGY}, self.player))) + ) + ) + ) + + def zerg_templars_charge_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_comp(state) + and self.zerg_competent_anti_air(state) + and state.has(item_names.SWARM_QUEEN, self.player) + and ( + self.morph_guardian(state) + or self.morph_brood_lord(state) + or state.has(item_names.INFESTED_BANSHEE, self.player) + or ( + self.advanced_tactics + and ( + state.has_all( + { + item_names.MUTALISK, + item_names.MUTALISK_SEVERING_GLAIVE, + item_names.MUTALISK_VICIOUS_GLAIVE, + item_names.MUTALISK_AERODYNAMIC_GLAIVE_SHAPE, + }, + self.player, + ) + or self.morph_viper(state) + ) + ) + ) + and ( + state.has_all({item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_CLOUD_DISPERSAL}, self.player) + or (self.morph_devourer(state) and state.has(item_names.MUTALISK, self.player)) + or state.has_all({item_names.MUTALISK, item_names.MUTALISK_SUNDERING_GLAIVE}, self.player) + ) + ) + + def protoss_the_host_requirement(self, state: CollectionState) -> bool: + return ( + self.protoss_fleet(state) and self.protoss_static_defense(state) and self.protoss_army_weapon_armor_upgrade_min_level(state) >= 2 + ) or ( + self.protoss_deathball(state) + and state.has(item_names.SOA_TIME_STOP, self.player) + or self.advanced_tactics + and (state.has_any((item_names.SOA_SHIELD_OVERCHARGE, item_names.SOA_SOLAR_BOMBARDMENT), self.player)) + ) + + def terran_the_host_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_beats_protoss_deathball(state) + and self.terran_very_hard_mission_weapon_armor_level(state) + and ( + ( + state.has_all({item_names.BATTLECRUISER, item_names.BATTLECRUISER_ATX_LASER_BATTERY}, self.player) + and state.count(item_names.BATTLECRUISER_PROGRESSIVE_DEFENSIVE_MATRIX, self.player) >= 2 + ) + or ( + self.terran_air_anti_air(state) + and self.terran_sustainable_mech_heal(state) + and ( + state.has_any({item_names.BANSHEE, item_names.BATTLECRUISER}, self.player) + or state.has_all({item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY}, self.player) + ) + ) + or ( + self.spear_of_adun_presence == SpearOfAdunPresence.option_everywhere + and state.has(item_names.SOA_TIME_STOP, self.player) + or self.advanced_tactics + and (state.has_any((item_names.SOA_SHIELD_OVERCHARGE, item_names.SOA_SOLAR_BOMBARDMENT), self.player)) + ) + ) + ) + + def zerg_the_host_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_comp(state) + and self.zerg_competent_anti_air(state) + and self.zerg_very_hard_mission_weapon_armor_level(state) + and self.zerg_base_buster(state) + and self.zerg_big_monsters(state) + and ( + (self.morph_brood_lord(state) or self.morph_guardian(state)) + and ( + (self.morph_devourer(state) and state.has(item_names.MUTALISK, self.player)) + or state.has_all((item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_CLOUD_DISPERSAL), self.player) + ) + or ( + state.has_all( + ( + item_names.MUTALISK, + item_names.MUTALISK_SEVERING_GLAIVE, + item_names.MUTALISK_VICIOUS_GLAIVE, + item_names.MUTALISK_SUNDERING_GLAIVE, + item_names.MUTALISK_RAPID_REGENERATION, + ), + self.player, + ) + ) + ) + or ( + self.spear_of_adun_presence == SpearOfAdunPresence.option_everywhere + and state.has(item_names.SOA_TIME_STOP, self.player) + or self.advanced_tactics + and (state.has_any((item_names.SOA_SHIELD_OVERCHARGE, item_names.SOA_SOLAR_BOMBARDMENT), self.player)) + ) + ) + + def protoss_salvation_requirement(self, state: CollectionState) -> bool: + return ( + ([self.protoss_competent_comp(state), self.protoss_fleet(state), self.protoss_static_defense(state)].count(True) >= 2) + and self.protoss_very_hard_mission_weapon_armor_level(state) + and self.protoss_power_rating(state) >= 6 + ) + + def terran_salvation_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_beats_protoss_deathball(state) + and self.terran_very_hard_mission_weapon_armor_level(state) + and self.terran_air_anti_air(state) + and state.has_any({item_names.SIEGE_TANK, item_names.LIBERATOR}, self.player) + and state.has_any({item_names.PERDITION_TURRET, item_names.DEVASTATOR_TURRET, item_names.PLANETARY_FORTRESS}, self.player) + and self.terran_power_rating(state) >= 6 + ) + + def zerg_salvation_requirement(self, state: CollectionState) -> bool: + return ( + self.zerg_competent_comp(state) + and self.zerg_competent_anti_air(state) + and state.has(item_names.SPINE_CRAWLER, self.player) + and self.zerg_very_hard_mission_weapon_armor_level(state) + and ( + self.morph_impaler_or_lurker(state) + or state.has_all({item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_DEFENDER_MODE}, self.player) + or state.has_all({item_names.MUTALISK, item_names.MUTALISK_SEVERING_GLAIVE, item_names.MUTALISK_VICIOUS_GLAIVE}, self.player) + ) + and ( + state.has_all({item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_CLOUD_DISPERSAL}, self.player) + or (self.morph_devourer(state) and state.has(item_names.MUTALISK, self.player)) + or state.has_all({item_names.MUTALISK, item_names.MUTALISK_SUNDERING_GLAIVE}, self.player) + ) + and self.zerg_power_rating(state) >= 6 + ) + + def into_the_void_requirement(self, state: CollectionState) -> bool: + if not self.protoss_very_hard_mission_weapon_armor_level(state): + return False + if self.take_over_ai_allies and not ( + self.terran_very_hard_mission_weapon_armor_level(state) and self.zerg_very_hard_mission_weapon_armor_level(state) + ): + return False + return self.protoss_competent_comp(state) or ( + self.take_over_ai_allies + and ( + state.has(item_names.BATTLECRUISER, self.player) + or (state.has(item_names.ULTRALISK, self.player) and self.protoss_competent_anti_air(state)) + ) + ) + + def essence_of_eternity_requirement(self, state: CollectionState) -> bool: + if not self.terran_very_hard_mission_weapon_armor_level(state): + return False + if self.take_over_ai_allies and not ( + self.protoss_very_hard_mission_weapon_armor_level(state) and self.zerg_very_hard_mission_weapon_armor_level(state) + ): + return False + defense_score = self.terran_defense_rating(state, False, True) + if self.take_over_ai_allies and self.protoss_static_defense(state): + defense_score += 2 + return ( + defense_score >= 12 + and (self.terran_competent_anti_air(state) or self.take_over_ai_allies and self.protoss_competent_anti_air(state)) + and ( + state.has(item_names.BATTLECRUISER, self.player) + or ( + state.has_any((item_names.BANSHEE, item_names.LIBERATOR), self.player) + and state.has_any({item_names.VIKING, item_names.VALKYRIE}, self.player) + ) + or self.take_over_ai_allies + and self.protoss_fleet(state) + ) + and self.terran_power_rating(state) >= 6 + ) + + def amons_fall_requirement(self, state: CollectionState) -> bool: + if not self.zerg_very_hard_mission_weapon_armor_level(state): + return False + if not self.zerg_competent_anti_air(state): + return False + if self.zerg_power_rating(state) < 6: + return False + if self.take_over_ai_allies and not ( + self.terran_very_hard_mission_weapon_armor_level(state) and self.protoss_very_hard_mission_weapon_armor_level(state) + ): + return False + if self.take_over_ai_allies: + return ( + ( + state.has_any({item_names.BATTLECRUISER, item_names.CARRIER, item_names.SKYLORD, item_names.TRIREME}, self.player) + or ( + state.has(item_names.ULTRALISK, self.player) + and self.protoss_competent_anti_air(state) + and ( + state.has_any({item_names.LIBERATOR, item_names.BANSHEE, item_names.VALKYRIE, item_names.VIKING}, self.player) + or state.has_all({item_names.WRAITH, item_names.WRAITH_ADVANCED_LASER_TECHNOLOGY}, self.player) + or self.protoss_fleet(state) + ) + and ( + self.terran_sustainable_mech_heal(state) + or ( + self.spear_of_adun_passive_presence == SpearOfAdunPassiveAbilityPresence.option_everywhere + and state.has(item_names.RECONSTRUCTION_BEAM, self.player) + ) + ) + ) + ) + and self.terran_competent_anti_air(state) + and self.protoss_deathball(state) + and self.zerg_competent_comp(state) + ) + else: + return ( + ( + state.has_any((item_names.MUTALISK, item_names.CORRUPTOR, item_names.BROOD_QUEEN, item_names.INFESTED_BANSHEE), self.player) + or state.has_all((item_names.INFESTED_LIBERATOR, item_names.INFESTED_LIBERATOR_CLOUD_DISPERSAL), self.player) + or state.has_all((item_names.SCOURGE, item_names.SCOURGE_RESOURCE_EFFICIENCY), self.player) + or self.morph_brood_lord(state) + or self.morph_guardian(state) + or self.morph_devourer(state) + ) + or (self.advanced_tactics and self.spread_creep(state, False) and self.zerg_big_monsters(state)) + ) and self.zerg_competent_comp(state) + + def the_escape_stuff_granted(self) -> bool: + """ + The NCO first mission requires having too much stuff first before actually able to do anything + :return: + """ + return self.grant_story_tech == GrantStoryTech.option_grant or (self.mission_order == MissionOrder.option_vanilla and self.enabled_campaigns == {SC2Campaign.NCO}) + + def the_escape_first_stage_requirement(self, state: CollectionState) -> bool: + return self.the_escape_stuff_granted() or (self.nova_ranged_weapon(state) and (self.nova_full_stealth(state) or self.nova_heal(state))) + + def the_escape_requirement(self, state: CollectionState) -> bool: + return self.the_escape_first_stage_requirement(state) and (self.the_escape_stuff_granted() or self.nova_splash(state)) + + def terran_able_to_snipe_defiler(self, state: CollectionState) -> bool: + return ( + state.has(item_names.BANSHEE, self.player) + or ( + state.has(item_names.NOVA_JUMP_SUIT_MODULE, self.player) + and (state.has_any({item_names.NOVA_DOMINATION, item_names.NOVA_C20A_CANISTER_RIFLE, item_names.NOVA_PULSE_GRENADES}, self.player)) + ) + or (state.has_all({item_names.SIEGE_TANK, item_names.SIEGE_TANK_MAELSTROM_ROUNDS, item_names.SIEGE_TANK_JUMP_JETS}, self.player)) + ) + + def sudden_strike_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_able_to_snipe_defiler(state) + and (self.terran_cliffjumper(state) or state.has(item_names.BANSHEE, self.player)) + and self.nova_splash(state) + and self.terran_defense_rating(state, True, False) >= 3 + and self.advanced_tactics + or state.has(item_names.NOVA_JUMP_SUIT_MODULE, self.player) + ) + + def enemy_intelligence_garrisonable_unit(self, state: CollectionState) -> bool: + """ + Has unit usable as a Garrison in Enemy Intelligence + """ + return ( + state.has_any(( + item_names.MARINE, + item_names.SON_OF_KORHAL, + item_names.REAPER, + item_names.MARAUDER, + item_names.GHOST, + item_names.SPECTRE, + item_names.HELLION, + item_names.GOLIATH, + item_names.WARHOUND, + item_names.DIAMONDBACK, + item_names.VIKING, + item_names.DOMINION_TROOPER, + ), self.player) + or (self.advanced_tactics + and state.has(item_names.ROGUE_FORCES, self.player) + and state.count_from_list(( + item_names.WAR_PIGS, + item_names.HAMMER_SECURITIES, + item_names.DEATH_HEADS, + item_names.SPARTAN_COMPANY, + item_names.HELS_ANGELS, + item_names.BRYNHILDS, + ), self.player) >= 3 + ) + ) + + def enemy_intelligence_cliff_garrison(self, state: CollectionState) -> bool: + return ( + state.has_any((item_names.REAPER, item_names.VIKING), self.player) + or (state.has_any((item_names.MEDIVAC, item_names.HERCULES), self.player) + and self.enemy_intelligence_garrisonable_unit(state) + ) + or state.has_all({item_names.GOLIATH, item_names.GOLIATH_JUMP_JETS}, self.player) + or (self.advanced_tactics and state.has_any({item_names.HELS_ANGELS, item_names.BRYNHILDS}, self.player)) + ) + + def enemy_intelligence_first_stage_requirement(self, state: CollectionState) -> bool: + return ( + self.enemy_intelligence_garrisonable_unit(state) + and ( + self.terran_competent_comp(state) + or (self.terran_common_unit(state) and self.terran_competent_anti_air(state) and state.has(item_names.NOVA_NUKE, self.player)) + ) + and self.terran_defense_rating(state, True, True) >= 5 + ) + + def enemy_intelligence_second_stage_requirement(self, state: CollectionState) -> bool: + return ( + self.enemy_intelligence_first_stage_requirement(state) + and self.enemy_intelligence_cliff_garrison(state) + and ( + self.grant_story_tech == GrantStoryTech.option_grant + or ( + self.nova_any_weapon(state) + and (self.nova_full_stealth(state) or (self.nova_heal(state) and self.nova_splash(state) and self.nova_ranged_weapon(state))) + ) + ) + ) + + def enemy_intelligence_third_stage_requirement(self, state: CollectionState) -> bool: + return self.enemy_intelligence_second_stage_requirement(state) and ( + self.grant_story_tech == GrantStoryTech.option_grant or (state.has(item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE, self.player) and self.nova_dash(state)) + ) + + def enemy_intelligence_cliff_garrison_and_nova_mobility(self, state: CollectionState) -> bool: + return self.enemy_intelligence_cliff_garrison(state) and ( + self.nova_any_nobuild_damage(state) + or ( + state.has(item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE, self.player, 2) + and state.has_any((item_names.NOVA_FLASHBANG_GRENADES, item_names.NOVA_BLINK), self.player) + ) + ) + + def trouble_in_paradise_requirement(self, state: CollectionState) -> bool: + return ( + self.nova_any_weapon(state) + and self.nova_splash(state) + and self.terran_beats_protoss_deathball(state) + and self.terran_defense_rating(state, True, True) >= 7 + and self.terran_power_rating(state) >= 5 + ) + + def night_terrors_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_common_unit(state) + and self.terran_competent_anti_air(state) + and ( + # These can handle the waves of infested, even volatile ones + state.has(item_names.SIEGE_TANK, self.player) + or state.has_all({item_names.VIKING, item_names.VIKING_SHREDDER_ROUNDS}, self.player) + or state.has_all((item_names.BANSHEE, item_names.BANSHEE_SHOCKWAVE_MISSILE_BATTERY), self.player) + or ( + ( + # Regular infesteds + ( + state.has_any((item_names.FIREBAT, item_names.REAPER), self.player) + or state.has_all({item_names.HELLION, item_names.HELLION_HELLBAT}, self.player) + ) + and self.terran_bio_heal(state) + or (self.advanced_tactics and state.has_any({item_names.PERDITION_TURRET, item_names.PLANETARY_FORTRESS}, self.player)) + ) + and ( + # Volatile infesteds + state.has(item_names.LIBERATOR, self.player) + or ( + self.advanced_tactics + and state.has(item_names.VULTURE, self.player) + or (state.has(item_names.HERC, self.player) and self.terran_bio_heal(state)) + ) + ) + ) + ) + and self.terran_army_weapon_armor_upgrade_min_level(state) >= 2 + ) + + def flashpoint_far_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_competent_comp(state) + and self.terran_mobile_detector(state) + and self.terran_defense_rating(state, True, False) >= 6 + and self.terran_army_weapon_armor_upgrade_min_level(state) >= 2 + and self.nova_splash(state) + and (self.advanced_tactics or self.terran_competent_ground_to_air(state)) + ) + + def enemy_shadow_tripwires_tool(self, state: CollectionState) -> bool: + return state.has_any({item_names.NOVA_FLASHBANG_GRENADES, item_names.NOVA_BLINK, item_names.NOVA_DOMINATION}, self.player) + + def enemy_shadow_door_unlocks_tool(self, state: CollectionState) -> bool: + return state.has_any({item_names.NOVA_DOMINATION, item_names.NOVA_BLINK, item_names.NOVA_JUMP_SUIT_MODULE}, self.player) + + def enemy_shadow_nova_damage_and_blazefire_unlock(self, state: CollectionState) -> bool: + return self.nova_any_nobuild_damage(state) and ( + state.has(item_names.NOVA_BLINK, self.player) or state.has_all((item_names.NOVA_HOLO_DECOY, item_names.NOVA_DOMINATION), self.player) + ) + + def enemy_shadow_domination(self, state: CollectionState) -> bool: + return self.grant_story_tech == GrantStoryTech.option_grant or ( + self.nova_ranged_weapon(state) + and ( + self.nova_full_stealth(state) + or state.has(item_names.NOVA_JUMP_SUIT_MODULE, self.player) + or (self.nova_heal(state) and self.nova_splash(state)) + ) + ) + + def enemy_shadow_first_stage(self, state: CollectionState) -> bool: + return self.enemy_shadow_domination(state) and ( + self.grant_story_tech == GrantStoryTech.option_grant + or ((self.nova_full_stealth(state) and self.enemy_shadow_tripwires_tool(state)) or (self.nova_heal(state) and self.nova_splash(state))) + ) + + def enemy_shadow_second_stage(self, state: CollectionState) -> bool: + return self.enemy_shadow_first_stage(state) and ( + self.grant_story_tech == GrantStoryTech.option_grant + or (self.nova_splash(state) or self.nova_heal(state) or self.nova_escape_assist(state)) + and (self.advanced_tactics or state.has(item_names.NOVA_GHOST_VISOR, self.player)) + ) + + def enemy_shadow_door_controls(self, state: CollectionState) -> bool: + return self.enemy_shadow_second_stage(state) and (self.grant_story_tech == GrantStoryTech.option_grant or self.enemy_shadow_door_unlocks_tool(state)) + + def enemy_shadow_victory(self, state: CollectionState) -> bool: + return self.enemy_shadow_door_controls(state) and (self.grant_story_tech == GrantStoryTech.option_grant or (self.nova_heal(state) and self.nova_beat_stone(state))) + + def dark_skies_requirement(self, state: CollectionState) -> bool: + return self.terran_common_unit(state) and self.terran_beats_protoss_deathball(state) and self.terran_defense_rating(state, False, True) >= 8 + + def end_game_requirement(self, state: CollectionState) -> bool: + return ( + self.terran_competent_comp(state) + and self.terran_mobile_detector(state) + and self.nova_any_weapon(state) + and self.nova_splash(state) + and ( + # Xanthos + state.has_any((item_names.BATTLECRUISER, item_names.VIKING, item_names.WARHOUND), self.player) + or state.has_all((item_names.LIBERATOR, item_names.LIBERATOR_SMART_SERVOS), self.player) + or state.has_all((item_names.THOR, item_names.THOR_PROGRESSIVE_HIGH_IMPACT_PAYLOAD), self.player) + or ( + state.has(item_names.VALKYRIE, self.player) + and state.has_any((item_names.VALKYRIE_AFTERBURNERS, item_names.VALKYRIE_SHAPED_HULL), self.player) + and state.has_any((item_names.VALKYRIE_FLECHETTE_MISSILES, item_names.VALKYRIE_ENHANCED_CLUSTER_LAUNCHERS), self.player) + ) + or (state.has(item_names.BANSHEE, self.player) and (self.advanced_tactics or state.has(item_names.BANSHEE_SHAPED_HULL, self.player))) + or ( + self.advanced_tactics + and ( + ( + state.has_all((item_names.MARINE, item_names.MARINE_PROGRESSIVE_STIMPACK), self.player) + and (self.terran_bio_heal(state) or state.count(item_names.MARINE_PROGRESSIVE_STIMPACK, self.player) >= 2) + ) + or (state.has(item_names.DOMINION_TROOPER, self.player) and self.terran_bio_heal(state)) + or state.has_all( + (item_names.PREDATOR, item_names.PREDATOR_RESOURCE_EFFICIENCY, item_names.PREDATOR_ADAPTIVE_DEFENSES), self.player + ) + or state.has_all((item_names.CYCLONE, item_names.CYCLONE_TARGETING_OPTICS), self.player) + ) + ) + ) + and ( # The enemy has 3/3 BCs + state.has_any( + (item_names.GOLIATH, item_names.VIKING, item_names.NOVA_C20A_CANISTER_RIFLE, item_names.NOVA_BLAZEFIRE_GUNBLADE), self.player + ) + or state.has_all((item_names.THOR, item_names.THOR_PROGRESSIVE_HIGH_IMPACT_PAYLOAD), self.player) + or state.has_all((item_names.GHOST, item_names.GHOST_LOCKDOWN), self.player) + or state.has_all((item_names.BATTLECRUISER, item_names.BATTLECRUISER_ATX_LASER_BATTERY), self.player) + ) + and self.terran_army_weapon_armor_upgrade_min_level(state) >= 3 + ) + + def has_terran_units(self, target: int) -> Callable[["CollectionState"], bool]: + def _has_terran_units(state: CollectionState) -> bool: + return (state.count_from_list_unique(item_groups.terran_units + item_groups.terran_buildings, self.player) >= target) and ( + # Anything that can hit buildings + state.has_any(( + # Infantry + item_names.MARINE, + item_names.FIREBAT, + item_names.MARAUDER, + item_names.REAPER, + item_names.HERC, + item_names.DOMINION_TROOPER, + item_names.GHOST, + item_names.SPECTRE, + # Vehicles + item_names.HELLION, + item_names.VULTURE, + item_names.SIEGE_TANK, + item_names.WARHOUND, + item_names.GOLIATH, + item_names.DIAMONDBACK, + item_names.THOR, + item_names.PREDATOR, + item_names.CYCLONE, + # Ships + item_names.WRAITH, + item_names.VIKING, + item_names.BANSHEE, + item_names.RAVEN, + item_names.BATTLECRUISER, + # RG + item_names.SON_OF_KORHAL, + item_names.AEGIS_GUARD, + item_names.EMPERORS_SHADOW, + item_names.BULWARK_COMPANY, + item_names.SHOCK_DIVISION, + item_names.BLACKHAMMER, + item_names.SKY_FURY, + item_names.NIGHT_WOLF, + item_names.NIGHT_HAWK, + item_names.PRIDE_OF_AUGUSTRGRAD, + ), self.player) + or state.has_all((item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY), self.player) + or state.has_all((item_names.EMPERORS_GUARDIAN, item_names.LIBERATOR_RAID_ARTILLERY), self.player) + or state.has_all((item_names.VALKYRIE, item_names.VALKYRIE_FLECHETTE_MISSILES), self.player) + or state.has_all((item_names.WIDOW_MINE, item_names.WIDOW_MINE_DEMOLITION_PAYLOAD), self.player) + or ( + state.has_any(( + # Mercs with shortest initial cooldown (300s) + item_names.WAR_PIGS, + item_names.DEATH_HEADS, + item_names.HELS_ANGELS, + item_names.WINGED_NIGHTMARES, + ), self.player) + # + 2 upgrades that allow getting faster/earlier mercs + and state.count_from_list(( + item_names.RAPID_REINFORCEMENT, + item_names.PROGRESSIVE_FAST_DELIVERY, + item_names.ROGUE_FORCES, + # item_names.SIGNAL_BEACON, # Probably doesn't help too much on the first unit + ), self.player) >= 2 + ) + ) + + return _has_terran_units + + def has_zerg_units(self, target: int) -> Callable[["CollectionState"], bool]: + def _has_zerg_units(state: CollectionState) -> bool: + num_units = ( + state.count_from_list_unique( + item_groups.zerg_nonmorph_units + item_groups.zerg_buildings + [item_names.OVERLORD_OVERSEER_ASPECT], + self.player + ) + + self.morph_baneling(state) + + self.morph_ravager(state) + + self.morph_igniter(state) + + self.morph_lurker(state) + + self.morph_impaler(state) + + self.morph_viper(state) + + self.morph_devourer(state) + + self.morph_brood_lord(state) + + self.morph_guardian(state) + + self.morph_tyrannozor(state) + ) + return ( + num_units >= target + and ( + # Anything that can hit buildings + state.has_any(( + item_names.ZERGLING, + item_names.SWARM_QUEEN, + item_names.ROACH, + item_names.HYDRALISK, + item_names.ABERRATION, + item_names.SWARM_HOST, + item_names.MUTALISK, + item_names.ULTRALISK, + item_names.PYGALISK, + item_names.INFESTED_MARINE, + item_names.INFESTED_BUNKER, + item_names.INFESTED_DIAMONDBACK, + item_names.INFESTED_SIEGE_TANK, + item_names.INFESTED_BANSHEE, + # Mercs with <= 300s first drop time + item_names.DEVOURING_ONES, + item_names.HUNTER_KILLERS, + item_names.CAUSTIC_HORRORS, + item_names.HUNTERLING, + ), self.player) + or state.has_all((item_names.INFESTOR, item_names.INFESTOR_INFESTED_TERRAN), self.player) + or self.morph_baneling(state) + or self.morph_lurker(state) + or self.morph_impaler(state) + or self.morph_brood_lord(state) + or self.morph_guardian(state) + or self.morph_ravager(state) + or self.morph_igniter(state) + or self.morph_tyrannozor(state) + or (self.morph_devourer(state) + and state.has(item_names.DEVOURER_PRESCIENT_SPORES, self.player) + ) + or ( + state.has_any(( + # Mercs with <= 300s first drop time + item_names.DEVOURING_ONES, + item_names.HUNTER_KILLERS, + item_names.CAUSTIC_HORRORS, + item_names.HUNTERLING, + ), self.player) + # + 2 upgrades that allow getting faster/earlier mercs + and state.count_from_list(( + item_names.UNRESTRICTED_MUTATION, + item_names.EVOLUTIONARY_LEAP, + item_names.CELL_DIVISION, + item_names.SELF_SUFFICIENT, + ), self.player) >= 2 + ) + ) + ) + + return _has_zerg_units + + def has_protoss_units(self, target: int) -> Callable[["CollectionState"], bool]: + def _has_protoss_units(state: CollectionState) -> bool: + return ( + state.count_from_list_unique(item_groups.protoss_units + item_groups.protoss_buildings + [item_names.NEXUS_OVERCHARGE], self.player) + >= target + ) and ( + # Anything that can hit buildings + state.has_any(( + # Gateway + item_names.ZEALOT, + item_names.CENTURION, + item_names.SENTINEL, + item_names.SUPPLICANT, + item_names.STALKER, + item_names.INSTIGATOR, + item_names.SLAYER, + item_names.DRAGOON, + item_names.ADEPT, + item_names.SENTRY, + item_names.ENERGIZER, + item_names.AVENGER, + item_names.DARK_TEMPLAR, + item_names.BLOOD_HUNTER, + item_names.HIGH_TEMPLAR, + item_names.SIGNIFIER, + item_names.ASCENDANT, + item_names.DARK_ARCHON, + # Robo + item_names.IMMORTAL, + item_names.ANNIHILATOR, + item_names.VANGUARD, + item_names.STALWART, + item_names.COLOSSUS, + item_names.WRATHWALKER, + item_names.REAVER, + item_names.DISRUPTOR, + # Stargate + item_names.SKIRMISHER, + item_names.SCOUT, + item_names.MISTWING, + item_names.OPPRESSOR, + item_names.PULSAR, + item_names.VOID_RAY, + item_names.DESTROYER, + item_names.DAWNBRINGER, + item_names.ARBITER, + item_names.ORACLE, + item_names.CARRIER, + item_names.TRIREME, + item_names.SKYLORD, + item_names.TEMPEST, + item_names.MOTHERSHIP, + ), self.player) + or state.has_all((item_names.WARP_PRISM, item_names.WARP_PRISM_PHASE_BLASTER), self.player) + or state.has_all((item_names.CALADRIUS, item_names.CALADRIUS_CORONA_BEAM), self.player) + or state.has_all((item_names.PHOTON_CANNON, item_names.KHALAI_INGENUITY), self.player) + or state.has_all((item_names.KHAYDARIN_MONOLITH, item_names.KHALAI_INGENUITY), self.player) + ) + + return _has_protoss_units + + def has_race_units(self, target: int, race: SC2Race) -> Callable[["CollectionState"], bool]: + if target == 0 or race == SC2Race.ANY: + return Location.access_rule + result = self.unit_count_functions.get((race, target)) + if result is not None: + return result + if race == SC2Race.TERRAN: + result = self.has_terran_units(target) + if race == SC2Race.ZERG: + result = self.has_zerg_units(target) + if race == SC2Race.PROTOSS: + result = self.has_protoss_units(target) + assert result + self.unit_count_functions[(race, target)] = result + return result + + +def get_basic_units(logic_level: int, race: SC2Race) -> Set[str]: + if logic_level > RequiredTactics.option_advanced: + return no_logic_basic_units[race] + elif logic_level == RequiredTactics.option_advanced: + return advanced_basic_units[race] + else: + return basic_units[race] diff --git a/worlds/sc2/settings.py b/worlds/sc2/settings.py new file mode 100644 index 000000000000..26253b1e65c3 --- /dev/null +++ b/worlds/sc2/settings.py @@ -0,0 +1,49 @@ +from typing import Union +import settings + + +class Starcraft2Settings(settings.Group): + class WindowWidth(int): + """The starting width the client window in pixels""" + + class WindowHeight(int): + """The starting height the client window in pixels""" + + class GameWindowedMode(settings.Bool): + """Controls whether the game should start in windowed mode""" + + class TerranButtonColor(list): + """Defines the colour of terran mission buttons in the launcher in rgb format (3 elements ranging from 0 to 1)""" + + class ZergButtonColor(list): + """Defines the colour of zerg mission buttons in the launcher in rgb format (3 elements ranging from 0 to 1)""" + + class ProtossButtonColor(list): + """Defines the colour of protoss mission buttons in the launcher in rgb format (3 elements ranging from 0 to 1)""" + + class DisableForcedCamera(str): + """Overrides the disable forced-camera slot option. Possible values: `true`, `false`, `default`. Default uses slot value""" + + class SkipCutscenes(str): + """Overrides the skip cutscenes slot option. Possible values: `true`, `false`, `default`. Default uses slot value""" + + class GameDifficulty(str): + """Overrides the slot's difficulty setting. Possible values: `casual`, `normal`, `hard`, `brutal`, `default`. Default uses slot value""" + + class GameSpeed(str): + """Overrides the slot's gamespeed setting. Possible values: `slower`, `slow`, `normal`, `fast`, `faster`, `default`. Default uses slot value""" + + class ShowTraps(settings.Bool): + """If set to true, in-client scouting will show traps as distinct from filler""" + + window_width: WindowWidth = WindowWidth(1080) + window_height: WindowHeight = WindowHeight(720) + game_windowed_mode: Union[GameWindowedMode, bool] = False + show_traps: Union[ShowTraps, bool] = False + disable_forced_camera: DisableForcedCamera = DisableForcedCamera("default") + skip_cutscenes: SkipCutscenes = SkipCutscenes("default") + game_difficulty: GameDifficulty = GameDifficulty("default") + game_speed: GameSpeed = GameSpeed("default") + terran_button_color: TerranButtonColor = TerranButtonColor([0.0838, 0.2898, 0.2346]) + zerg_button_color: ZergButtonColor = ZergButtonColor([0.345, 0.22425, 0.12765]) + protoss_button_color: ProtossButtonColor = ProtossButtonColor([0.18975, 0.2415, 0.345]) diff --git a/worlds/sc2/starcraft2.kv b/worlds/sc2/starcraft2.kv new file mode 100644 index 000000000000..9013986f2047 --- /dev/null +++ b/worlds/sc2/starcraft2.kv @@ -0,0 +1,61 @@ + + scroll_type: ["content", "bars"] + bar_width: dp(12) + effect_cls: "ScrollEffect" + canvas.after: + Color: + rgba: (0.82, 0.2, 0, root.border_on) + Line: + width: 1.5 + rectangle: self.x+1, self.y+1, self.width-1, self.height-1 + + + color: (1, 1, 1, 1) + canvas.before: + Color: + rgba: (0xd2/0xff, 0x33/0xff, 0, 1) + Rectangle: + pos: (self.x - 8, self.y - 8) + size: (self.width + 30, self.height + 16) + + + cols: 1 + size_hint_y: None + height: self.minimum_height + 15 + padding: [5,0,dp(12),0] + +: + cols: 1 + +: + rows: 1 + +: + cols: 1 + +: + rows: 1 + +: + cols: 1 + spacing: [0,5] + +: + text_size: self.size + markup: True + halign: 'center' + valign: 'middle' + padding: [5,0,5,0] + outline_width: 1 + canvas.before: + Color: + rgba: (1, 193/255, 86/255, root.is_goal) + Line: + width: 1 + rectangle: (self.x, self.y + 0.5, self.width, self.height) + canvas.after: + Color: + rgba: (0.8, 0.8, 0.8, root.is_exit) + Line: + width: 1 + rectangle: (self.x + 2, self.y + 3, self.width - 4, self.height - 4) \ No newline at end of file diff --git a/worlds/sc2/test/test_Regions.py b/worlds/sc2/test/test_Regions.py deleted file mode 100644 index c268b65da9a8..000000000000 --- a/worlds/sc2/test/test_Regions.py +++ /dev/null @@ -1,41 +0,0 @@ -import unittest -from .test_base import Sc2TestBase -from .. import Regions -from .. import Options, MissionTables - -class TestGridsizes(unittest.TestCase): - def test_grid_sizes_meet_specs(self): - self.assertTupleEqual((1, 2, 0), Regions.get_grid_dimensions(2)) - self.assertTupleEqual((1, 3, 0), Regions.get_grid_dimensions(3)) - self.assertTupleEqual((2, 2, 0), Regions.get_grid_dimensions(4)) - self.assertTupleEqual((2, 3, 1), Regions.get_grid_dimensions(5)) - self.assertTupleEqual((2, 4, 1), Regions.get_grid_dimensions(7)) - self.assertTupleEqual((2, 4, 0), Regions.get_grid_dimensions(8)) - self.assertTupleEqual((3, 3, 0), Regions.get_grid_dimensions(9)) - self.assertTupleEqual((2, 5, 0), Regions.get_grid_dimensions(10)) - self.assertTupleEqual((3, 4, 1), Regions.get_grid_dimensions(11)) - self.assertTupleEqual((3, 4, 0), Regions.get_grid_dimensions(12)) - self.assertTupleEqual((3, 5, 0), Regions.get_grid_dimensions(15)) - self.assertTupleEqual((4, 4, 0), Regions.get_grid_dimensions(16)) - self.assertTupleEqual((4, 6, 0), Regions.get_grid_dimensions(24)) - self.assertTupleEqual((5, 5, 0), Regions.get_grid_dimensions(25)) - self.assertTupleEqual((5, 6, 1), Regions.get_grid_dimensions(29)) - self.assertTupleEqual((5, 7, 2), Regions.get_grid_dimensions(33)) - - -class TestGridGeneration(Sc2TestBase): - options = { - "mission_order": Options.MissionOrder.option_grid, - "excluded_missions": [MissionTables.SC2Mission.ZERO_HOUR.mission_name,], - "enable_hots_missions": False, - "enable_prophecy_missions": True, - "enable_lotv_prologue_missions": False, - "enable_lotv_missions": False, - "enable_epilogue_missions": False, - "enable_nco_missions": False - } - - def test_size_matches_exclusions(self): - self.assertNotIn(MissionTables.SC2Mission.ZERO_HOUR.mission_name, self.multiworld.regions) - # WoL has 29 missions. -1 for Zero Hour being excluded, +1 for the automatically-added menu location - self.assertEqual(len(self.multiworld.regions), 29) diff --git a/worlds/sc2/test/test_base.py b/worlds/sc2/test/test_base.py index 28529e37edd5..6110814c3b01 100644 --- a/worlds/sc2/test/test_base.py +++ b/worlds/sc2/test/test_base.py @@ -1,11 +1,52 @@ from typing import * +import unittest +import random +from argparse import Namespace +from BaseClasses import MultiWorld, CollectionState, PlandoOptions +from Generate import get_seed_name +from worlds import AutoWorld +from test.general import gen_steps, call_all -from test.TestBase import WorldTestBase +from test.bases import WorldTestBase from .. import SC2World -from .. import Client +from .. import client class Sc2TestBase(WorldTestBase): - game = Client.SC2Context.game + game = client.SC2Context.game world: SC2World player: ClassVar[int] = 1 skip_long_tests: bool = True + + +class Sc2SetupTestBase(unittest.TestCase): + """ + A custom sc2-specific test base class that provides an explicit function to generate the world from options. + This allows potentially generating multiple worlds in one test case, useful for tracking down a rare / sporadic + crash. + """ + seed: Optional[int] = None + game = SC2World.game + player = 1 + def generate_world(self, options: Dict[str, Any]) -> None: + self.multiworld = MultiWorld(1) + self.multiworld.game[self.player] = self.game + self.multiworld.player_name = {self.player: "Tester"} + self.multiworld.set_seed(self.seed) + random.seed(self.multiworld.seed) + self.multiworld.seed_name = get_seed_name(random) # only called to get same RNG progression as Generate.py + args = Namespace() + for name, option in AutoWorld.AutoWorldRegister.world_types[self.game].options_dataclass.type_hints.items(): + new_option = option.from_any(options.get(name, option.default)) + new_option.verify(SC2World, "Tester", PlandoOptions.items|PlandoOptions.connections|PlandoOptions.texts|PlandoOptions.bosses) + setattr(args, name, { + 1: new_option + }) + self.multiworld.set_options(args) + self.world: SC2World = cast(SC2World, self.multiworld.worlds[self.player]) + self.multiworld.state = CollectionState(self.multiworld) + try: + for step in gen_steps: + call_all(self.multiworld, step) + except Exception as ex: + ex.add_note(f"Seed: {self.multiworld.seed}") + raise diff --git a/worlds/sc2/test/test_custom_mission_orders.py b/worlds/sc2/test/test_custom_mission_orders.py new file mode 100644 index 000000000000..f431e909a730 --- /dev/null +++ b/worlds/sc2/test/test_custom_mission_orders.py @@ -0,0 +1,216 @@ +""" +Unit tests for custom mission orders +""" + +from .test_base import Sc2SetupTestBase +from .. import MissionFlag +from ..item import item_tables, item_names +from BaseClasses import ItemClassification + +class TestCustomMissionOrders(Sc2SetupTestBase): + def test_mini_wol_generates(self): + world_options = { + 'mission_order': 'custom', + 'custom_mission_order': { + 'Mini Wings of Liberty': { + 'global': { + 'type': 'column', + 'mission_pool': [ + 'terran missions', + '^ wol missions' + ] + }, + 'Mar Sara': { + 'size': 1 + }, + 'Colonist': { + 'size': 2, + 'entry_rules': [{ + 'scope': '../Mar Sara' + }] + }, + 'Artifact': { + 'size': 3, + 'entry_rules': [{ + 'scope': '../Mar Sara' + }], + 'missions': [ + { + 'index': 1, + 'entry_rules': [{ + 'scope': 'Mini Wings of Liberty', + 'amount': 4 + }] + }, + { + 'index': 2, + 'entry_rules': [{ + 'scope': 'Mini Wings of Liberty', + 'amount': 8 + }] + } + ] + }, + 'Prophecy': { + 'size': 2, + 'entry_rules': [{ + 'scope': '../Artifact/1' + }], + 'mission_pool': [ + 'protoss missions', + '^ prophecy missions' + ] + }, + 'Covert': { + 'size': 2, + 'entry_rules': [{ + 'scope': 'Mini Wings of Liberty', + 'amount': 2 + }] + }, + 'Rebellion': { + 'size': 2, + 'entry_rules': [{ + 'scope': 'Mini Wings of Liberty', + 'amount': 3 + }] + }, + 'Char': { + 'size': 3, + 'entry_rules': [{ + 'scope': '../Artifact/2' + }], + 'missions': [ + { + 'index': 0, + 'next': [2] + }, + { + 'index': 1, + 'entrance': True + } + ] + } + } + } + } + + self.generate_world(world_options) + flags = self.world.custom_mission_order.get_used_flags() + self.assertEqual(flags[MissionFlag.Terran], 13) + self.assertEqual(flags[MissionFlag.Protoss], 2) + self.assertEqual(flags.get(MissionFlag.Zerg, 0), 0) + sc2_regions = set(self.multiworld.regions.region_cache[self.player]) - {"Menu"} + self.assertEqual(len(self.world.custom_mission_order.get_used_missions()), len(sc2_regions)) + + def test_locked_and_necessary_item_appears_once(self): + # This is a filler upgrade with a parent + test_item = item_names.MARINE_OPTIMIZED_LOGISTICS + world_options = { + 'mission_order': 'custom', + 'locked_items': { test_item: 1 }, + 'custom_mission_order': { + 'test': { + 'type': 'column', + 'size': 5, # Give the generator some space to place the key + 'max_difficulty': 'easy', + 'missions': [{ + 'index': 4, + 'entry_rules': [{ + 'items': { test_item: 1 } + }] + }] + } + } + } + + self.assertNotEqual(item_tables.item_table[test_item].classification, ItemClassification.progression, f"Test item {test_item} won't change classification") + + self.generate_world(world_options) + test_items_in_pool = [item for item in self.multiworld.itempool if item.name == test_item] + test_items_in_pool += [item for item in self.multiworld.precollected_items[self.player] if item.name == test_item] + self.assertEqual(len(test_items_in_pool), 1) + self.assertEqual(test_items_in_pool[0].classification, ItemClassification.progression) + + def test_start_inventory_and_necessary_item_appears_once(self): + # This is a filler upgrade with a parent + test_item = item_names.ZERGLING_METABOLIC_BOOST + world_options = { + 'mission_order': 'custom', + 'start_inventory': { test_item: 1 }, + 'custom_mission_order': { + 'test': { + 'type': 'column', + 'size': 5, # Give the generator some space to place the key + 'max_difficulty': 'easy', + 'missions': [{ + 'index': 4, + 'entry_rules': [{ + 'items': { test_item: 1 } + }] + }] + } + } + } + + self.generate_world(world_options) + test_items_in_pool = [item for item in self.multiworld.itempool if item.name == test_item] + self.assertEqual(len(test_items_in_pool), 0) + test_items_in_start_inventory = [item for item in self.multiworld.precollected_items[self.player] if item.name == test_item] + self.assertEqual(len(test_items_in_start_inventory), 1) + + def test_start_inventory_and_locked_and_necessary_item_appears_once(self): + # This is a filler upgrade with a parent + test_item = item_names.ZERGLING_METABOLIC_BOOST + world_options = { + 'mission_order': 'custom', + 'start_inventory': { test_item: 1 }, + 'locked_items': { test_item: 1 }, + 'custom_mission_order': { + 'test': { + 'type': 'column', + 'size': 5, # Give the generator some space to place the key + 'max_difficulty': 'easy', + 'missions': [{ + 'index': 4, + 'entry_rules': [{ + 'items': { test_item: 1 } + }] + }] + } + } + } + + self.generate_world(world_options) + test_items_in_pool = [item for item in self.multiworld.itempool if item.name == test_item] + self.assertEqual(len(test_items_in_pool), 0) + test_items_in_start_inventory = [item for item in self.multiworld.precollected_items[self.player] if item.name == test_item] + self.assertEqual(len(test_items_in_start_inventory), 1) + + def test_key_item_rule_creates_correct_item_amount(self): + # This is an item that normally only exists once + test_item = item_names.ZERGLING + test_amount = 3 + world_options = { + 'mission_order': 'custom', + 'locked_items': { test_item: 1 }, # Make sure it is generated as normal + 'custom_mission_order': { + 'test': { + 'type': 'column', + 'size': 12, # Give the generator some space to place the keys + 'max_difficulty': 'easy', + 'mission_pool': ['zerg missions'], # Make sure the item isn't excluded by race selection + 'missions': [{ + 'index': 10, + 'entry_rules': [{ + 'items': { test_item: test_amount } # Require more than the usual item amount + }] + }] + } + } + } + + self.generate_world(world_options) + test_items_in_pool = [item for item in self.multiworld.itempool if item.name == test_item] + test_items_in_start_inventory = [item for item in self.multiworld.precollected_items[self.player] if item.name == test_item] + self.assertEqual(len(test_items_in_pool + test_items_in_start_inventory), test_amount) diff --git a/worlds/sc2/test/test_generation.py b/worlds/sc2/test/test_generation.py new file mode 100644 index 000000000000..faedb19a9f9f --- /dev/null +++ b/worlds/sc2/test/test_generation.py @@ -0,0 +1,1228 @@ +""" +Unit tests for world generation +""" +from typing import * +from .test_base import Sc2SetupTestBase + +from .. import mission_groups, mission_tables, options, locations, SC2Mission, SC2Campaign, SC2Race, unreleased_items +from ..item import item_groups, item_tables, item_names +from .. import get_all_missions, get_random_first_mission +from ..options import EnabledCampaigns, NovaGhostOfAChanceVariant, MissionOrder, ExcludeOverpoweredItems, \ + VanillaItemsOnly, MaximumCampaignSize + + +class TestItemFiltering(Sc2SetupTestBase): + def test_explicit_locks_excludes_interact_and_set_flags(self): + world_options = { + 'locked_items': { + item_names.MARINE: 0, + item_names.MARAUDER: 0, + item_names.MEDIVAC: 1, + item_names.FIREBAT: 1, + item_names.ZEALOT: 0, + item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL: 2, + }, + 'excluded_items': { + item_names.MARINE: 0, + item_names.MARAUDER: 0, + item_names.MEDIVAC: 0, + item_names.FIREBAT: 1, + item_names.ZERGLING: 0, + item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL: 2, + } + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + itempool = [item.name for item in self.multiworld.itempool] + self.assertIn(item_names.MARINE, itempool) + self.assertIn(item_names.MARAUDER, itempool) + self.assertIn(item_names.MEDIVAC, itempool) + self.assertIn(item_names.FIREBAT, itempool) + self.assertIn(item_names.ZEALOT, itempool) + self.assertNotIn(item_names.ZERGLING, itempool) + regen_biosteel_items = [x for x in itempool if x == item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL] + self.assertEqual(len(regen_biosteel_items), 2) + + def test_unexcludes_cancel_out_excludes(self): + world_options = { + 'grant_story_tech': options.GrantStoryTech.option_grant, + 'excluded_items': { + item_groups.ItemGroupNames.NOVA_EQUIPMENT: 15, + item_names.MARINE_PROGRESSIVE_STIMPACK: 1, + item_names.MARAUDER_PROGRESSIVE_STIMPACK: 2, + item_names.MARINE: 0, + item_names.MARAUDER: 0, + item_names.REAPER: 1, + item_names.DIAMONDBACK: 0, + item_names.HELLION: 1, + # Additional excludes to increase the likelihood that unexcluded items actually appear + item_groups.ItemGroupNames.STARPORT_UNITS: 0, + item_names.WARHOUND: 0, + item_names.VULTURE: 0, + item_names.WIDOW_MINE: 0, + item_names.THOR: 0, + item_names.GHOST: 0, + item_names.SPECTRE: 0, + item_groups.ItemGroupNames.MENGSK_UNITS: 0, + item_groups.ItemGroupNames.TERRAN_VETERANCY_UNITS: 0, + }, + 'unexcluded_items': { + item_names.NOVA_PLASMA_RIFLE: 1, # Necessary to pass logic + item_names.NOVA_PULSE_GRENADES: 0, # Necessary to pass logic + item_names.NOVA_JUMP_SUIT_MODULE: 0, # Necessary to pass logic + item_groups.ItemGroupNames.BARRACKS_UNITS: 0, + item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE: 1, + item_names.HELLION: 1, + item_names.MARINE_PROGRESSIVE_STIMPACK: 1, + item_names.MARAUDER_PROGRESSIVE_STIMPACK: 0, + # Additional unexcludes for logic + item_names.MEDIVAC: 0, + item_names.BATTLECRUISER: 0, + item_names.SCIENCE_VESSEL: 0, + }, + # Terran-only + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + SC2Campaign.NCO.campaign_name + }, + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + itempool = [item.name for item in self.multiworld.itempool] + self.assertIn(item_names.MARINE, itempool) + self.assertIn(item_names.MARAUDER, itempool) + self.assertIn(item_names.REAPER, itempool) + self.assertEqual(itempool.count(item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE), 1, "Stealth suit occurred the wrong number of times") + self.assertIn(item_names.HELLION, itempool) + self.assertEqual(itempool.count(item_names.MARINE_PROGRESSIVE_STIMPACK), 2, f"Marine stimpacks weren't unexcluded (seed {self.multiworld.seed})") + self.assertEqual(itempool.count(item_names.MARAUDER_PROGRESSIVE_STIMPACK), 2, f"Marauder stimpacks weren't unexcluded (seed {self.multiworld.seed})") + self.assertNotIn(item_names.DIAMONDBACK, itempool) + self.assertNotIn(item_names.NOVA_BLAZEFIRE_GUNBLADE, itempool) + self.assertNotIn(item_names.NOVA_ENERGY_SUIT_MODULE, itempool) + + def test_excluding_groups_excludes_all_items_in_group(self): + world_options = { + 'excluded_items': [ + item_groups.ItemGroupNames.BARRACKS_UNITS.lower(), + ] + } + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + self.assertIn(item_names.MARINE, self.world.options.excluded_items) + for item_name in item_groups.barracks_units: + self.assertNotIn(item_name, itempool) + + def test_excluding_mission_groups_excludes_all_missions_in_group(self): + world_options = { + 'excluded_missions': [ + mission_groups.MissionGroupNames.HOTS_ZERUS_MISSIONS, + ], + 'mission_order': options.MissionOrder.option_grid, + } + self.generate_world(world_options) + missions = get_all_missions(self.world.custom_mission_order) + self.assertTrue(missions) + self.assertNotIn(mission_tables.SC2Mission.WAKING_THE_ANCIENT, missions) + self.assertNotIn(mission_tables.SC2Mission.THE_CRUCIBLE, missions) + self.assertNotIn(mission_tables.SC2Mission.SUPREME, missions) + + def test_excluding_campaigns_excludes_campaign_specific_items(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name + }, + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + world_items = [(item.name, item_tables.item_table[item.name]) for item in self.multiworld.itempool] + for item_name, item_data in world_items: + self.assertNotIn(item_data.type, item_tables.ProtossItemType) + self.assertNotIn(item_data.type, item_tables.ZergItemType) + self.assertNotEqual(item_data.type, item_tables.TerranItemType.Nova_Gear) + self.assertNotEqual(item_name, item_names.NOVA_PROGRESSIVE_STEALTH_SUIT_MODULE) + + def test_starter_unit_populates_start_inventory(self): + world_options = { + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + 'shuffle_no_build': options.ShuffleNoBuild.option_false, + 'mission_order': options.MissionOrder.option_grid, + 'starter_unit': options.StarterUnit.option_any_starter_unit, + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + self.assertTrue(self.multiworld.precollected_items[self.player]) + + def test_excluding_all_terran_missions_excludes_all_terran_items(self) -> None: + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'excluded_missions': [ + mission.mission_name for mission in mission_tables.SC2Mission + if mission_tables.MissionFlag.Terran in mission.flags + ], + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + world_items = [(item.name, item_tables.item_table[item.name]) for item in self.multiworld.itempool] + for item_name, item_data in world_items: + self.assertNotIn(item_data.type, item_tables.TerranItemType, f"Item '{item_name}' included when all terran missions are excluded") + + def test_excluding_all_terran_build_missions_excludes_all_terran_units(self) -> None: + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'excluded_missions': [ + mission.mission_name for mission in mission_tables.SC2Mission + if mission_tables.MissionFlag.Terran in mission.flags + and mission_tables.MissionFlag.NoBuild not in mission.flags + ], + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + world_items = [(item.name, item_tables.item_table[item.name]) for item in self.multiworld.itempool] + for item_name, item_data in world_items: + self.assertNotEqual(item_data.type, item_tables.TerranItemType.Unit, f"Item '{item_name}' included when all terran build missions are excluded") + self.assertNotEqual(item_data.type, item_tables.TerranItemType.Mercenary, f"Item '{item_name}' included when all terran build missions are excluded") + self.assertNotEqual(item_data.type, item_tables.TerranItemType.Building, f"Item '{item_name}' included when all terran build missions are excluded") + + def test_excluding_all_zerg_and_kerrigan_missions_excludes_all_zerg_items(self) -> None: + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'excluded_missions': [ + mission.mission_name for mission in mission_tables.SC2Mission + if (mission_tables.MissionFlag.Kerrigan | mission_tables.MissionFlag.Zerg) & mission.flags + ], + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + world_items = [(item.name, item_tables.item_table[item.name]) for item in self.multiworld.itempool] + for item_name, item_data in world_items: + self.assertNotIn(item_data.type, item_tables.ZergItemType, f"Item '{item_name}' included when all zerg missions are excluded") + + def test_excluding_all_zerg_build_missions_excludes_zerg_units(self) -> None: + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'excluded_missions': [ + *[mission.mission_name + for mission in mission_tables.SC2Mission + if mission_tables.MissionFlag.Zerg in mission.flags + and mission_tables.MissionFlag.NoBuild not in mission.flags], + mission_tables.SC2Mission.ENEMY_WITHIN.mission_name, + ], + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + world_items = [(item.name, item_tables.item_table[item.name]) for item in self.multiworld.itempool] + for item_name, item_data in world_items: + self.assertNotEqual(item_data.type, item_tables.ZergItemType.Unit, f"Item '{item_name}' included when all zerg build missions are excluded") + self.assertNotEqual(item_data.type, item_tables.ZergItemType.Mercenary, f"Item '{item_name}' included when all zerg build missions are excluded") + + def test_excluding_all_protoss_missions_excludes_all_protoss_items(self) -> None: + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'accessibility': 'locations', + 'excluded_missions': [ + *[mission.mission_name + for mission in mission_tables.SC2Mission + if mission_tables.MissionFlag.Protoss in mission.flags], + ], + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + world_items = [(item.name, item_tables.item_table[item.name]) for item in self.multiworld.itempool] + for item_name, item_data in world_items: + self.assertNotIn(item_data.type, item_tables.ProtossItemType, f"Item '{item_name}' included when all protoss missions are excluded") + + def test_excluding_all_protoss_build_missions_excludes_protoss_units(self) -> None: + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'accessibility': 'locations', + 'excluded_missions': [ + *[mission.mission_name + for mission in mission_tables.SC2Mission + if mission.race == mission_tables.SC2Race.PROTOSS + and mission_tables.MissionFlag.NoBuild not in mission.flags], + mission_tables.SC2Mission.TEMPLAR_S_RETURN.mission_name, + ], + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + world_items = [(item.name, item_tables.item_table[item.name]) for item in self.multiworld.itempool] + for item_name, item_data in world_items: + self.assertNotEqual(item_data.type, item_tables.ProtossItemType.Unit, f"Item '{item_name}' included when all protoss build missions are excluded") + self.assertNotEqual(item_data.type, item_tables.ProtossItemType.Unit_2, f"Item '{item_name}' included when all protoss build missions are excluded") + self.assertNotEqual(item_data.type, item_tables.ProtossItemType.Building, f"Item '{item_name}' included when all protoss build missions are excluded") + + def test_vanilla_items_only_excludes_terran_progressives(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + SC2Campaign.NCO.campaign_name + }, + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'accessibility': 'locations', + 'vanilla_items_only': True, + } + self.generate_world(world_options) + world_items = [(item.name, item_tables.item_table[item.name]) for item in self.multiworld.itempool] + self.assertTrue(world_items) + occurrences: Dict[str, int] = {} + for item_name, _ in world_items: + if item_name in item_groups.terran_progressive_items: + if item_name in item_groups.nova_equipment: + # The option imposes no contraint on Nova equipment + continue + occurrences.setdefault(item_name, 0) + occurrences[item_name] += 1 + self.assertLessEqual(occurrences[item_name], 1, f"'{item_name}' unexpectedly appeared multiple times in the pool") + + def test_vanilla_items_only_includes_only_nova_equipment_and_vanilla_and_filler_items(self) -> None: + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + # Avoid options that lock non-vanilla items for logic + 'spear_of_adun_presence': options.SpearOfAdunPresence.option_protoss, + 'required_tactics': options.RequiredTactics.option_advanced, + 'mastery_locations': options.MasteryLocations.option_disabled, + 'accessibility': 'locations', + 'vanilla_items_only': True, + # Move the unit nerf items from the start inventory to the pool, + # else this option could push non-vanilla items past this test + 'war_council_nerfs': True, + } + + self.generate_world(world_options) + + world_items = [(item.name, item_tables.item_table[item.name]) for item in self.multiworld.itempool] + self.assertTrue(world_items) + self.assertNotIn(item_names.DESTROYER_REFORGED_BLOODSHARD_CORE, world_items) + for item_name, item_data in world_items: + if item_data.quantity == 0: + continue + self.assertIn(item_name, item_groups.vanilla_items + item_groups.nova_equipment) + + def test_evil_awoken_with_vanilla_items_only_generates(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.PROLOGUE.campaign_name, + SC2Campaign.LOTV.campaign_name + }, + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'accessibility': 'locations', + 'vanilla_items_only': True, + } + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + self.assertTrue(itempool) + self.assertTrue(self.world.get_region(mission_tables.SC2Mission.EVIL_AWOKEN.mission_name)) + + def test_enemy_within_and_no_zerg_build_missions_generates(self) -> None: + world_options = { + # including WoL to allow for valid goal missions + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + SC2Campaign.HOTS.campaign_name + }, + 'excluded_missions': [ + mission.mission_name for mission in mission_tables.SC2Mission + if mission_tables.MissionFlag.Zerg in mission.flags + and mission_tables.MissionFlag.NoBuild not in mission.flags + ], + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'accessibility': 'locations', + 'vanilla_items_only': True, + } + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + self.assertTrue(itempool) + self.assertTrue(self.world.get_region(mission_tables.SC2Mission.ENEMY_WITHIN.mission_name)) + self.assertNotIn(item_names.ULTRALISK, itempool) + self.assertNotIn(item_names.SWARM_QUEEN, itempool) + self.assertNotIn(item_names.MUTALISK, itempool) + self.assertNotIn(item_names.CORRUPTOR, itempool) + self.assertNotIn(item_names.SCOURGE, itempool) + + def test_soa_items_are_included_in_wol_when_presence_set_to_everywhere(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + 'spear_of_adun_presence': options.SpearOfAdunPresence.option_everywhere, + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'accessibility': 'locations', + # Ensure enough locations to fit all wanted items + 'generic_upgrade_missions': 1, + 'victory_cache': 5, + 'excluded_items': {item_groups.ItemGroupNames.BARRACKS_UNITS: 0}, + } + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + self.assertTrue(itempool) + soa_items_in_pool = [item_name for item_name in itempool if item_tables.item_table[item_name].type == item_tables.ProtossItemType.Spear_Of_Adun] + self.assertGreater(len(soa_items_in_pool), 5) + + def test_lotv_only_doesnt_include_kerrigan_items_with_grant_story_tech(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.LOTV.campaign_name, + }, + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'accessibility': 'locations', + 'grant_story_tech': options.GrantStoryTech.option_grant, + } + self.generate_world(world_options) + missions = get_all_missions(self.world.custom_mission_order) + self.assertIn(mission_tables.SC2Mission.TEMPLE_OF_UNIFICATION, missions) + itempool = [item.name for item in self.multiworld.itempool] + self.assertTrue(itempool) + kerrigan_items_in_pool = set(item_groups.kerrigan_abilities).intersection(itempool) + self.assertFalse(kerrigan_items_in_pool) + kerrigan_passives_in_pool = set(item_groups.kerrigan_passives).intersection(itempool) + self.assertFalse(kerrigan_passives_in_pool) + + def test_excluding_zerg_units_with_morphling_enabled_doesnt_exclude_aspects(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.HOTS.campaign_name, + }, + 'required_tactics': options.RequiredTactics.option_no_logic, + 'enable_morphling': options.EnableMorphling.option_true, + 'excluded_items': [ + item_groups.ItemGroupNames.ZERG_UNITS.lower() + ], + 'unexcluded_items': [ + item_groups.ItemGroupNames.ZERG_MORPHS.lower() + ] + } + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + self.assertTrue(itempool) + aspects_in_pool = list(set(itempool).intersection(set(item_groups.zerg_morphs))) + self.assertTrue(aspects_in_pool) + units_in_pool = list(set(itempool).intersection(set(item_groups.zerg_units)) + .difference(set(item_groups.zerg_morphs))) + self.assertFalse(units_in_pool) + + def test_excluding_zerg_units_with_morphling_disabled_should_exclude_aspects(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.HOTS.campaign_name, + }, + 'required_tactics': options.RequiredTactics.option_no_logic, + 'enable_morphling': options.EnableMorphling.option_false, + 'excluded_items': [ + item_groups.ItemGroupNames.ZERG_UNITS.lower() + ], + 'unexcluded_items': [ + item_groups.ItemGroupNames.ZERG_MORPHS.lower() + ] + } + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + self.assertTrue(itempool) + aspects_in_pool = list(set(itempool).intersection(set(item_groups.zerg_morphs))) + if item_names.OVERLORD_OVERSEER_ASPECT in aspects_in_pool: + # Overseer morphs from Overlord, that's available always + aspects_in_pool.remove(item_names.OVERLORD_OVERSEER_ASPECT) + self.assertFalse(aspects_in_pool) + units_in_pool = list(set(itempool).intersection(set(item_groups.zerg_units)) + .difference(set(item_groups.zerg_morphs))) + self.assertFalse(units_in_pool) + + def test_deprecated_orbital_command_not_present(self) -> None: + """ + Orbital command got replaced. The item is still there for backwards compatibility. + It shouldn't be generated. + """ + world_options = {} + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + self.assertTrue(itempool) + self.assertNotIn(item_names.PROGRESSIVE_ORBITAL_COMMAND, itempool) + + def test_planetary_orbital_module_not_present_without_cc_spells(self) -> None: + world_options = { + "excluded_items": [ + item_names.COMMAND_CENTER_MULE, + item_names.COMMAND_CENTER_SCANNER_SWEEP, + item_names.COMMAND_CENTER_EXTRA_SUPPLIES + ], + "locked_items": [ + item_names.PLANETARY_FORTRESS + ] + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + self.assertTrue(itempool) + self.assertIn(item_names.PLANETARY_FORTRESS, itempool) + self.assertNotIn(item_names.PLANETARY_FORTRESS_ORBITAL_MODULE, itempool) + + def test_disabling_unit_nerfs_start_inventories_war_council_upgrades(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.PROPHECY.campaign_name, + SC2Campaign.PROLOGUE.campaign_name, + SC2Campaign.LOTV.campaign_name + }, + 'mission_order': options.MissionOrder.option_grid, + 'war_council_nerfs': options.WarCouncilNerfs.option_false, + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + war_council_item_names = set(item_groups.item_name_groups[item_groups.ItemGroupNames.WAR_COUNCIL]) + present_war_council_items = war_council_item_names.intersection(itempool) + starting_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + starting_war_council_items = war_council_item_names.intersection(starting_inventory) + + self.assertTrue(itempool) + self.assertFalse(present_war_council_items, f'Found war council upgrades when war_council_nerfs is false: {present_war_council_items}') + self.assertEqual(war_council_item_names, starting_war_council_items) + + def test_disabling_speedrun_locations_removes_them_from_the_pool(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.HOTS.campaign_name, + }, + 'mission_order': options.MissionOrder.option_grid, + 'speedrun_locations': options.SpeedrunLocations.option_disabled, + 'preventative_locations': options.PreventativeLocations.option_filler, + } + + self.generate_world(world_options) + world_regions = list(self.multiworld.regions) + world_location_names = [location.name for region in world_regions for location in region.locations] + all_location_names = [location_data.name for location_data in locations.DEFAULT_LOCATION_LIST] + speedrun_location_name = f"{mission_tables.SC2Mission.LAB_RAT.mission_name}: Win In Under 10 Minutes" + self.assertIn(speedrun_location_name, all_location_names) + self.assertNotIn(speedrun_location_name, world_location_names) + + def test_nco_and_wol_picks_correct_starting_mission(self): + world_options = { + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + SC2Campaign.NCO.campaign_name + }, + } + self.generate_world(world_options) + self.assertEqual(get_random_first_mission(self.world, self.world.custom_mission_order), mission_tables.SC2Mission.LIBERATION_DAY) + + def test_excluding_mission_short_name_excludes_all_variants_of_mission(self): + world_options = { + 'excluded_missions': [ + mission_tables.SC2Mission.ZERO_HOUR.mission_name.split(" (")[0] + ], + 'mission_order': options.MissionOrder.option_grid, + 'selected_races': options.SelectRaces.valid_keys, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + } + self.generate_world(world_options) + missions = get_all_missions(self.world.custom_mission_order) + self.assertTrue(missions) + self.assertNotIn(mission_tables.SC2Mission.ZERO_HOUR, missions) + self.assertNotIn(mission_tables.SC2Mission.ZERO_HOUR_Z, missions) + self.assertNotIn(mission_tables.SC2Mission.ZERO_HOUR_P, missions) + + def test_excluding_mission_variant_excludes_just_that_variant(self): + world_options = { + 'excluded_missions': [ + mission_tables.SC2Mission.ZERO_HOUR.mission_name + ], + 'mission_order': options.MissionOrder.option_grid, + 'selected_races': options.SelectRaces.valid_keys, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + } + self.generate_world(world_options) + missions = get_all_missions(self.world.custom_mission_order) + self.assertTrue(missions) + self.assertNotIn(mission_tables.SC2Mission.ZERO_HOUR, missions) + self.assertIn(mission_tables.SC2Mission.ZERO_HOUR_Z, missions) + self.assertIn(mission_tables.SC2Mission.ZERO_HOUR_P, missions) + + def test_weapon_armor_upgrades(self): + world_options = { + # Vanilla WoL with all missions + 'mission_order': options.MissionOrder.option_vanilla, + 'starter_unit': options.StarterUnit.option_off, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + 'start_inventory': { + item_names.GOLIATH: 1 # Don't fail with early item placement + }, + 'generic_upgrade_items': options.GenericUpgradeItems.option_individual_items, + # Disable locations in order to cause item culling + 'vanilla_locations': options.VanillaLocations.option_disabled, + 'extra_locations': options.ExtraLocations.option_disabled, + 'challenge_locations': options.ChallengeLocations.option_disabled, + 'mastery_locations': options.MasteryLocations.option_disabled, + 'speedrun_locations': options.SpeedrunLocations.option_disabled, + 'preventative_locations': options.PreventativeLocations.option_disabled, + } + + self.generate_world(world_options) + starting_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + itempool = [item.name for item in self.multiworld.itempool] + world_items = starting_inventory + itempool + vehicle_weapon_items = [x for x in world_items if x == item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON] + other_bundle_items = [ + x for x in world_items if x in ( + item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE, + item_names.PROGRESSIVE_TERRAN_WEAPON_UPGRADE, + item_names.PROGRESSIVE_TERRAN_VEHICLE_UPGRADE, + ) + ] + + # Under standard tactics you need to place L3 upgrades for available unit classes + self.assertGreaterEqual(len(vehicle_weapon_items), 3) + self.assertEqual(len(other_bundle_items), 0) + + def test_weapon_armor_upgrades_with_bundles(self): + world_options = { + # Vanilla WoL with all missions + 'mission_order': options.MissionOrder.option_vanilla, + 'starter_unit': options.StarterUnit.option_off, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + 'start_inventory': { + item_names.GOLIATH: 1 # Don't fail with early item placement + }, + 'generic_upgrade_items': options.GenericUpgradeItems.option_bundle_unit_class, + # Disable locations in order to cause item culling + 'vanilla_locations': options.VanillaLocations.option_disabled, + 'extra_locations': options.ExtraLocations.option_disabled, + 'challenge_locations': options.ChallengeLocations.option_disabled, + 'mastery_locations': options.MasteryLocations.option_disabled, + 'speedrun_locations': options.SpeedrunLocations.option_disabled, + 'preventative_locations': options.PreventativeLocations.option_disabled, + } + + self.generate_world(world_options) + starting_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + itempool = [item.name for item in self.multiworld.itempool] + world_items = starting_inventory + itempool + vehicle_upgrade_items = [x for x in world_items if x == item_names.PROGRESSIVE_TERRAN_VEHICLE_UPGRADE] + other_bundle_items = [ + x for x in world_items if x in ( + item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE, + item_names.PROGRESSIVE_TERRAN_WEAPON_UPGRADE, + item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, + ) + ] + + # Under standard tactics you need to place L3 upgrades for available unit classes + self.assertGreaterEqual(len(vehicle_upgrade_items), 3) + self.assertEqual(len(other_bundle_items), 0) + + def test_weapon_armor_upgrades_all_in_air(self): + world_options = { + # Vanilla WoL with all missions + 'mission_order': options.MissionOrder.option_vanilla, + 'starter_unit': options.StarterUnit.option_off, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + 'all_in_map': options.AllInMap.option_air, # All-in air forces an air unit + 'start_inventory': { + item_names.GOLIATH: 1 # Don't fail with early item placement + }, + 'generic_upgrade_items': options.GenericUpgradeItems.option_individual_items, + # Disable locations in order to cause item culling + 'vanilla_locations': options.VanillaLocations.option_disabled, + 'extra_locations': options.ExtraLocations.option_disabled, + 'challenge_locations': options.ChallengeLocations.option_disabled, + 'mastery_locations': options.MasteryLocations.option_disabled, + 'speedrun_locations': options.SpeedrunLocations.option_disabled, + 'preventative_locations': options.PreventativeLocations.option_disabled, + } + + self.generate_world(world_options) + starting_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + itempool = [item.name for item in self.multiworld.itempool] + world_items = starting_inventory + itempool + vehicle_weapon_items = [x for x in world_items if x == item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON] + ship_weapon_items = [x for x in world_items if x == item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON] + + # Under standard tactics you need to place L3 upgrades for available unit classes + self.assertGreaterEqual(len(vehicle_weapon_items), 3) + self.assertGreaterEqual(len(ship_weapon_items), 3) + + def test_weapon_armor_upgrades_generic_upgrade_missions(self): + """ + Tests the case when there aren't enough missions in order to get required weapon/armor upgrades + for logic requirements. + :return: + """ + world_options = { + # Vanilla WoL with all missions + 'mission_order': options.MissionOrder.option_vanilla, + 'required_tactics': options.RequiredTactics.option_standard, + 'starter_unit': options.StarterUnit.option_off, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + 'all_in_map': options.AllInMap.option_air, # All-in air forces an air unit + 'start_inventory': { + item_names.GOLIATH: 1 # Don't fail with early item placement + }, + 'generic_upgrade_items': options.GenericUpgradeItems.option_individual_items, + 'generic_upgrade_missions': 100, # Fallback happens by putting weapon/armor upgrades into starting inventory + } + + self.generate_world(world_options) + starting_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + upgrade_items = [x for x in starting_inventory if x == item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE] + + # Under standard tactics you need to place L3 upgrades for available unit classes + self.assertEqual(len(upgrade_items), 3) + + def test_weapon_armor_upgrades_generic_upgrade_missions_no_logic(self): + """ + Tests the case when there aren't enough missions in order to get required weapon/armor upgrades + for logic requirements. + + Except the case above it's No Logic, thus the fallback won't take place. + :return: + """ + world_options = { + # Vanilla WoL with all missions + 'mission_order': options.MissionOrder.option_vanilla, + 'required_tactics': options.RequiredTactics.option_no_logic, + 'starter_unit': options.StarterUnit.option_off, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + 'all_in_map': options.AllInMap.option_air, # All-in air forces an air unit + 'start_inventory': { + item_names.GOLIATH: 1 # Don't fail with early item placement + }, + 'generic_upgrade_items': options.GenericUpgradeItems.option_individual_items, + 'generic_upgrade_missions': 100, # Fallback happens by putting weapon/armor upgrades into starting inventory + } + + self.generate_world(world_options) + starting_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + upgrade_items = [x for x in starting_inventory if x == item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE] + + # No logic won't take the fallback to trigger + self.assertEqual(len(upgrade_items), 0) + + def test_weapon_armor_upgrades_generic_upgrade_missions_no_countermeasure_needed(self): + world_options = { + # Vanilla WoL with all missions + 'mission_order': options.MissionOrder.option_vanilla, + 'required_tactics': options.RequiredTactics.option_standard, + 'starter_unit': options.StarterUnit.option_off, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + 'all_in_map': options.AllInMap.option_air, # All-in air forces an air unit + 'start_inventory': { + item_names.GOLIATH: 1 # Don't fail with early item placement + }, + 'generic_upgrade_items': options.GenericUpgradeItems.option_individual_items, + 'generic_upgrade_missions': 1, # Weapon / Armor upgrades should be available almost instantly + } + + self.generate_world(world_options) + starting_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + upgrade_items = [x for x in starting_inventory if x == item_names.PROGRESSIVE_TERRAN_WEAPON_ARMOR_UPGRADE] + + # No additional starting inventory item placement is needed + self.assertEqual(len(upgrade_items), 0) + + def test_kerrigan_levels_per_mission_triggering_pre_fill(self): + world_options = { + # Vanilla WoL with all missions + 'mission_order': options.MissionOrder.option_custom, + 'custom_mission_order': { + 'campaign': { + 'goal': True, + 'layout': { + 'type': 'column', + 'size': 3, + 'missions': [ + { + 'index': 0, + 'mission_pool': [SC2Mission.LIBERATION_DAY.mission_name] + }, + { + 'index': 1, + 'mission_pool': [SC2Mission.THE_INFINITE_CYCLE.mission_name] + }, + { + 'index': 2, + 'mission_pool': [SC2Mission.THE_RECKONING.mission_name] + }, + ] + } + } + }, + 'required_tactics': options.RequiredTactics.option_standard, + 'starter_unit': options.StarterUnit.option_off, + 'generic_upgrade_items': options.GenericUpgradeItems.option_individual_items, + 'grant_story_levels': options.GrantStoryLevels.option_disabled, + 'kerrigan_levels_per_mission_completed': 1, + 'kerrigan_level_item_distribution': options.KerriganLevelItemDistribution.option_size_2, + } + + self.generate_world(world_options) + starting_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + kerrigan_1_stacks = [x for x in starting_inventory if x == item_names.KERRIGAN_LEVELS_1] + + self.assertGreater(len(kerrigan_1_stacks), 0) + + def test_kerrigan_levels_per_mission_and_generic_upgrades_both_triggering_pre_fill(self): + world_options = { + # Vanilla WoL with all missions + 'mission_order': options.MissionOrder.option_custom, + 'custom_mission_order': { + 'campaign': { + 'goal': True, + 'layout': { + 'type': 'column', + 'size': 3, + 'missions': [ + { + 'index': 0, + 'mission_pool': [SC2Mission.LIBERATION_DAY.mission_name] + }, + { + 'index': 1, + 'mission_pool': [SC2Mission.THE_INFINITE_CYCLE.mission_name] + }, + { + 'index': 2, + 'mission_pool': [SC2Mission.THE_RECKONING.mission_name] + }, + ] + } + } + }, + 'required_tactics': options.RequiredTactics.option_standard, + 'starter_unit': options.StarterUnit.option_off, + 'generic_upgrade_items': options.GenericUpgradeItems.option_individual_items, + 'grant_story_levels': options.GrantStoryLevels.option_disabled, + 'kerrigan_levels_per_mission_completed': 1, + 'kerrigan_level_item_distribution': options.KerriganLevelItemDistribution.option_size_2, + 'generic_upgrade_missions': 100, # Weapon / Armor upgrades + } + + self.generate_world(world_options) + starting_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + itempool = [item.name for item in self.multiworld.itempool] + kerrigan_1_stacks = [x for x in starting_inventory if x == item_names.KERRIGAN_LEVELS_1] + upgrade_items = [x for x in starting_inventory if x == item_names.PROGRESSIVE_ZERG_WEAPON_ARMOR_UPGRADE] + + self.assertGreater(len(kerrigan_1_stacks), 0) # Kerrigan levels were added + self.assertEqual(len(upgrade_items), 3) # W/A upgrades were added + self.assertNotIn(item_names.KERRIGAN_LEVELS_70, itempool) + self.assertNotIn(item_names.KERRIGAN_LEVELS_70, starting_inventory) + + + + def test_locking_required_items(self): + world_options = { + 'mission_order': options.MissionOrder.option_custom, + 'custom_mission_order': { + 'campaign': { + 'goal': True, + 'layout': { + 'type': 'column', + 'size': 2, + 'missions': [ + { + 'index': 0, + 'mission_pool': [SC2Mission.LIBERATION_DAY.mission_name] + }, + { + 'index': 1, + 'mission_pool': [SC2Mission.SUPREME.mission_name] + }, + ] + } + } + }, + 'grant_story_levels': options.GrantStoryLevels.option_additive, + 'excluded_items': [ + item_names.KERRIGAN_LEAPING_STRIKE, + item_names.KERRIGAN_MEND, + ] + } + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + # These items will be in the pool despite exclusions + self.assertIn(item_names.KERRIGAN_LEAPING_STRIKE, itempool) + self.assertIn(item_names.KERRIGAN_MEND, itempool) + + + def test_fully_balanced_mission_races(self): + """ + Tests whether fully balanced mission race balancing actually is fully balanced. + """ + campaign_size = 57 + self.assertEqual(campaign_size % 3, 0, "Chosen test size cannot be perfectly balanced") + world_options = { + # Reasonably large grid with enough missions to balance races + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': campaign_size, + 'enabled_campaigns': EnabledCampaigns.valid_keys, + 'selected_races': options.SelectRaces.valid_keys, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'mission_race_balancing': options.EnableMissionRaceBalancing.option_fully_balanced, + } + + self.generate_world(world_options) + world_regions = [region.name for region in self.multiworld.regions] + world_regions.remove('Menu') + missions = [mission_tables.lookup_name_to_mission[region] for region in world_regions] + race_flags = [mission_tables.MissionFlag.Terran, mission_tables.MissionFlag.Zerg, mission_tables.MissionFlag.Protoss] + race_counts = { flag: sum(flag in mission.flags for mission in missions) for flag in race_flags } + + self.assertEqual(race_counts[mission_tables.MissionFlag.Terran], race_counts[mission_tables.MissionFlag.Zerg]) + self.assertEqual(race_counts[mission_tables.MissionFlag.Zerg], race_counts[mission_tables.MissionFlag.Protoss]) + + def test_setting_filter_weight_to_zero_excludes_that_item(self) -> None: + world_options = { + 'filler_items_distribution': { + item_names.STARTING_MINERALS: 0, + item_names.STARTING_VESPENE: 1, + item_names.STARTING_SUPPLY: 0, + item_names.MAX_SUPPLY: 0, + item_names.REDUCED_MAX_SUPPLY: 0, + item_names.SHIELD_REGENERATION: 0, + item_names.BUILDING_CONSTRUCTION_SPEED: 0, + }, + # Exclude many items to get filler to generate + 'excluded_items': { + item_groups.ItemGroupNames.TERRAN_VETERANCY_UNITS: 0, + }, + 'max_number_of_upgrades': 2, + 'mission_order': options.MissionOrder.option_grid, + 'selected_races': { + SC2Race.TERRAN.get_title(), + }, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + self.assertNotIn(item_names.STARTING_MINERALS, itempool) + self.assertNotIn(item_names.STARTING_SUPPLY, itempool) + self.assertNotIn(item_names.MAX_SUPPLY, itempool) + self.assertNotIn(item_names.REDUCED_MAX_SUPPLY, itempool) + self.assertNotIn(item_names.SHIELD_REGENERATION, itempool) + self.assertNotIn(item_names.BUILDING_CONSTRUCTION_SPEED, itempool) + + self.assertIn(item_names.STARTING_VESPENE, itempool) + + def test_shields_filler_doesnt_appear_if_no_protoss_missions_appear(self) -> None: + world_options = { + 'filler_items_distribution': { + item_names.STARTING_MINERALS: 1, + item_names.STARTING_VESPENE: 0, + item_names.STARTING_SUPPLY: 0, + item_names.MAX_SUPPLY: 0, + item_names.REDUCED_MAX_SUPPLY: 1, + item_names.SHIELD_REGENERATION: 1, + item_names.BUILDING_CONSTRUCTION_SPEED: 0, + }, + # Exclude many items to get filler to generate + 'excluded_items': { + item_groups.ItemGroupNames.TERRAN_VETERANCY_UNITS: 0, + item_groups.ItemGroupNames.ZERG_MORPHS: 0, + }, + 'max_number_of_upgrades': 2, + 'mission_order': options.MissionOrder.option_grid, + 'selected_races': { + SC2Race.TERRAN.get_title(), + SC2Race.ZERG.get_title(), + }, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + self.assertNotIn(item_names.SHIELD_REGENERATION, itempool) + + self.assertNotIn(item_names.STARTING_VESPENE, itempool) + self.assertNotIn(item_names.STARTING_SUPPLY, itempool) + self.assertNotIn(item_names.MAX_SUPPLY, itempool) + self.assertNotIn(item_names.BUILDING_CONSTRUCTION_SPEED, itempool) + + self.assertIn(item_names.STARTING_MINERALS, itempool) + self.assertIn(item_names.REDUCED_MAX_SUPPLY, itempool) + + def test_weapon_armor_upgrade_items_capped_by_max_upgrade_level(self) -> None: + MAX_LEVEL = 3 + world_options = { + 'locked_items': { + item_groups.ItemGroupNames.TERRAN_GENERIC_UPGRADES: MAX_LEVEL, + item_groups.ItemGroupNames.ZERG_GENERIC_UPGRADES: MAX_LEVEL, + item_groups.ItemGroupNames.PROTOSS_GENERIC_UPGRADES: MAX_LEVEL + 1, + }, + 'max_upgrade_level': MAX_LEVEL, + 'mission_order': options.MissionOrder.option_grid, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'generic_upgrade_items': options.GenericUpgradeItems.option_bundle_weapon_and_armor + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + upgrade_item_counts: Dict[str, int] = {} + for item_name in itempool: + if item_tables.item_table[item_name].type in ( + item_tables.TerranItemType.Upgrade, + item_tables.ZergItemType.Upgrade, + item_tables.ProtossItemType.Upgrade, + ): + upgrade_item_counts[item_name] = upgrade_item_counts.get(item_name, 0) + 1 + expected_result = { + item_names.PROGRESSIVE_TERRAN_ARMOR_UPGRADE: MAX_LEVEL, + item_names.PROGRESSIVE_TERRAN_WEAPON_UPGRADE: MAX_LEVEL, + item_names.PROGRESSIVE_ZERG_ARMOR_UPGRADE: MAX_LEVEL, + item_names.PROGRESSIVE_ZERG_WEAPON_UPGRADE: MAX_LEVEL, + item_names.PROGRESSIVE_PROTOSS_ARMOR_UPGRADE: MAX_LEVEL + 1, + item_names.PROGRESSIVE_PROTOSS_WEAPON_UPGRADE: MAX_LEVEL + 1, + } + self.assertDictEqual(expected_result, upgrade_item_counts) + + def test_ghost_of_a_chance_generates_without_nco(self) -> None: + world_options = { + 'mission_order': MissionOrder.option_custom, + 'nova_ghost_of_a_chance_variant': NovaGhostOfAChanceVariant.option_auto, + 'custom_mission_order': { + 'test': { + 'type': 'column', + 'size': 1, # Give the generator some space to place the key + 'mission_pool': [ + SC2Mission.GHOST_OF_A_CHANCE.mission_name + ] + } + } + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + self.assertNotIn(item_names.NOVA_C20A_CANISTER_RIFLE, itempool) + self.assertNotIn(item_names.NOVA_DOMINATION, itempool) + + def test_ghost_of_a_chance_generates_using_nco_nova(self) -> None: + world_options = { + 'mission_order': MissionOrder.option_custom, + 'nova_ghost_of_a_chance_variant': NovaGhostOfAChanceVariant.option_nco, + 'custom_mission_order': { + 'test': { + 'type': 'column', + 'size': 2, # Give the generator some space to place the key + 'mission_pool': [ + SC2Mission.LIBERATION_DAY.mission_name, # Starter mission + SC2Mission.GHOST_OF_A_CHANCE.mission_name, + ] + } + } + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + self.assertGreater(len({item_names.NOVA_C20A_CANISTER_RIFLE, item_names.NOVA_DOMINATION}.intersection(itempool)), 0) + + def test_ghost_of_a_chance_generates_with_nco(self) -> None: + world_options = { + 'mission_order': MissionOrder.option_custom, + 'nova_ghost_of_a_chance_variant': NovaGhostOfAChanceVariant.option_auto, + 'custom_mission_order': { + 'test': { + 'type': 'column', + 'size': 3, # Give the generator some space to place the key + 'mission_pool': [ + SC2Mission.LIBERATION_DAY.mission_name, # Starter mission + SC2Mission.GHOST_OF_A_CHANCE.mission_name, + SC2Mission.FLASHPOINT.mission_name, # A NCO mission + ] + } + } + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + self.assertGreater(len({item_names.NOVA_C20A_CANISTER_RIFLE, item_names.NOVA_DOMINATION}.intersection(itempool)), 0) + + def test_exclude_overpowered_items(self) -> None: + world_options = { + 'mission_order': MissionOrder.option_grid, + 'exclude_overpowered_items': ExcludeOverpoweredItems.option_true, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'selected_races': [SC2Race.TERRAN.get_title()], + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + regen_biosteel_items = [item for item in itempool if item == item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL] + atx_laser_battery_items = [item for item in itempool if item == item_names.BATTLECRUISER_ATX_LASER_BATTERY] + + self.assertEqual(len(regen_biosteel_items), 2) # Progressive, only top level is excluded + self.assertEqual(len(atx_laser_battery_items), 0) # Non-progressive + + def test_exclude_overpowered_items_not_excluded(self) -> None: + world_options = { + 'mission_order': MissionOrder.option_grid, + 'exclude_overpowered_items': ExcludeOverpoweredItems.option_false, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'selected_races': [SC2Race.TERRAN.get_title()], + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + regen_biosteel_items = [item for item in itempool if item == item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL] + atx_laser_battery_items = [item for item in itempool if item == item_names.BATTLECRUISER_ATX_LASER_BATTERY] + + self.assertEqual(len(regen_biosteel_items), 3) + self.assertEqual(len(atx_laser_battery_items), 1) + + def test_exclude_overpowered_items_vanilla_only(self) -> None: + world_options = { + 'mission_order': MissionOrder.option_grid, + 'exclude_overpowered_items': ExcludeOverpoweredItems.option_true, + 'vanilla_items_only': VanillaItemsOnly.option_true, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'selected_races': [SC2Race.TERRAN.get_title()], + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + # Regen biosteel is in both of the lists + regen_biosteel_items = [item for item in itempool if item == item_names.PROGRESSIVE_REGENERATIVE_BIO_STEEL] + + self.assertEqual(len(regen_biosteel_items), 1) # One stack shall remain + + def test_exclude_locked_overpowered_items(self) -> None: + locked_item = item_names.BATTLECRUISER_ATX_LASER_BATTERY + world_options = { + 'mission_order': MissionOrder.option_grid, + 'exclude_overpowered_items': ExcludeOverpoweredItems.option_true, + 'locked_items': [locked_item], + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'selected_races': [SC2Race.TERRAN.get_title()], + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + atx_laser_battery_items = [item for item in itempool if item == locked_item] + + self.assertEqual(len(atx_laser_battery_items), 1) # Locked, remains + + def test_unreleased_item_quantity(self) -> None: + """ + Checks if all unreleased items are marked properly not to generate + """ + world_options = { + 'mission_order': MissionOrder.option_grid, + 'exclude_overpowered_items': ExcludeOverpoweredItems.option_false, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + items_to_check: List[str] = unreleased_items + for item in items_to_check: + self.assertNotIn(item, itempool) + + def test_unreleased_item_quantity_locked(self) -> None: + """ + Checks if all unreleased items are marked properly not to generate + Locking overrides this behavior - if they're locked, they must appear + """ + world_options = { + 'mission_order': MissionOrder.option_grid, + 'exclude_overpowered_items': ExcludeOverpoweredItems.option_false, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'locked_items': {item_name: 0 for item_name in unreleased_items}, + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + items_to_check: List[str] = unreleased_items + for item in items_to_check: + self.assertIn(item, itempool) + + def test_merc_excluded_excludes_merc_upgrades(self) -> None: + world_options = { + 'mission_order': MissionOrder.option_grid, + 'maximum_campaign_size': MaximumCampaignSize.range_end, + 'excluded_items': [item_name for item_name in item_groups.terran_mercenaries], + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + self.assertNotIn(item_names.ROGUE_FORCES, itempool) + + def test_unexcluded_items_applies_over_op_items(self) -> None: + world_options = { + 'mission_order': MissionOrder.option_grid, + 'maximum_campaign_size': MaximumCampaignSize.range_end, + 'exclude_overpowered_items': ExcludeOverpoweredItems.option_true, + 'unexcluded_items': [item_names.SOA_TIME_STOP], + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + + self.assertNotIn( + item_groups.overpowered_items[0], + itempool, + f"OP item {item_groups.overpowered_items[0]} in the item pool when exclude_overpowered_items was true" + ) + self.assertIn( + item_names.SOA_TIME_STOP, + itempool, + f"{item_names.SOA_TIME_STOP} was not unexcluded by unexcluded_items when exclude_overpowered_items was true" + ) + + def test_exclude_overpowered_items_and_not_allow_unit_nerfs(self) -> None: + world_options = { + 'mission_order': MissionOrder.option_grid, + 'maximum_campaign_size': MaximumCampaignSize.range_end, + 'exclude_overpowered_items': ExcludeOverpoweredItems.option_true, + 'war_council_nerfs': options.WarCouncilNerfs.option_false, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + } + + self.generate_world(world_options) + starting_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + + # A unit nerf happens due to excluding OP items + self.assertNotIn(item_names.MOTHERSHIP_INTEGRATED_POWER, starting_inventory) diff --git a/worlds/sc2/test/test_item_filtering.py b/worlds/sc2/test/test_item_filtering.py new file mode 100644 index 000000000000..898fb6da69c4 --- /dev/null +++ b/worlds/sc2/test/test_item_filtering.py @@ -0,0 +1,88 @@ +""" +Unit tests for item filtering like pool_filter.py +""" + +from .test_base import Sc2SetupTestBase +from ..item import item_groups, item_names +from .. import options +from ..mission_tables import SC2Race + +class ItemFilterTests(Sc2SetupTestBase): + def test_excluding_all_barracks_units_excludes_infantry_upgrades(self) -> None: + world_options = { + 'excluded_items': { + item_groups.ItemGroupNames.BARRACKS_UNITS: 0 + }, + 'required_tactics': 'standard', + 'min_number_of_upgrades': 1, + 'selected_races': { + SC2Race.TERRAN.get_title() + }, + 'mission_order': 'grid', + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + races = {mission.race for mission in self.world.custom_mission_order.get_used_missions()} + self.assertIn(SC2Race.TERRAN, races) + self.assertNotIn(SC2Race.ZERG, races) + self.assertNotIn(SC2Race.PROTOSS, races) + itempool = [item.name for item in self.multiworld.itempool] + self.assertNotIn(item_names.MARINE, itempool) + self.assertNotIn(item_names.MARAUDER, itempool) + + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, itempool) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR, itempool) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_INFANTRY_UPGRADE, itempool) + + def test_excluding_one_item_of_multi_parent_doesnt_filter_children(self) -> None: + world_options = { + 'locked_items': { + item_names.SENTINEL: 1, + item_names.CENTURION: 1, + }, + 'excluded_items': { + item_names.ZEALOT: 1, + # Exclude more items to make space + item_names.WRATHWALKER: 1, + item_names.ENERGIZER: 1, + item_names.AVENGER: 1, + item_names.ARBITER: 1, + item_names.VOID_RAY: 1, + item_names.PULSAR: 1, + item_names.DESTROYER: 1, + item_names.DAWNBRINGER: 1, + }, + 'min_number_of_upgrades': 2, + 'required_tactics': 'standard', + 'selected_races': { + SC2Race.PROTOSS.get_title() + }, + 'mission_order': 'grid', + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + itempool = [item.name for item in self.multiworld.itempool] + self.assertIn(item_names.ZEALOT_SENTINEL_CENTURION_SHIELD_CAPACITY, itempool) + self.assertIn(item_names.ZEALOT_SENTINEL_CENTURION_LEG_ENHANCEMENTS, itempool) + + def test_excluding_all_items_in_multiparent_excludes_child_items(self) -> None: + world_options = { + 'excluded_items': { + item_names.ZEALOT: 1, + item_names.SENTINEL: 1, + item_names.CENTURION: 1, + }, + 'min_number_of_upgrades': 2, + 'required_tactics': 'standard', + 'selected_races': { + SC2Race.PROTOSS.get_title() + }, + 'mission_order': 'grid', + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + itempool = [item.name for item in self.multiworld.itempool] + self.assertNotIn(item_names.ZEALOT_SENTINEL_CENTURION_SHIELD_CAPACITY, itempool) + self.assertNotIn(item_names.ZEALOT_SENTINEL_CENTURION_LEG_ENHANCEMENTS, itempool) + diff --git a/worlds/sc2/test/test_itemdescriptions.py b/worlds/sc2/test/test_itemdescriptions.py new file mode 100644 index 000000000000..a4fd6d5c2846 --- /dev/null +++ b/worlds/sc2/test/test_itemdescriptions.py @@ -0,0 +1,18 @@ +import unittest + +from ..item import item_descriptions, item_tables + + +class TestItemDescriptions(unittest.TestCase): + def test_all_items_have_description(self) -> None: + for item_name in item_tables.item_table: + self.assertIn(item_name, item_descriptions.item_descriptions) + + def test_all_descriptions_refer_to_item_and_end_in_dot(self) -> None: + for item_name, item_desc in item_descriptions.item_descriptions.items(): + self.assertIn(item_name, item_tables.item_table) + self.assertEqual(item_desc.strip()[-1], '.', msg=f"{item_name}'s item description does not end in a '.': '{item_desc}'") + + def test_item_descriptions_follow_single_space_after_period_style(self) -> None: + for item_name, item_desc in item_descriptions.item_descriptions.items(): + self.assertNotIn('. ', item_desc, f"Double-space after period in description for {item_name}") diff --git a/worlds/sc2/test/test_itemgroups.py b/worlds/sc2/test/test_itemgroups.py new file mode 100644 index 000000000000..43848d20b589 --- /dev/null +++ b/worlds/sc2/test/test_itemgroups.py @@ -0,0 +1,32 @@ +""" +Unit tests for item_groups.py +""" + +import unittest +from ..item import item_groups, item_tables + + +class ItemGroupsUnitTests(unittest.TestCase): + def test_all_production_structure_groups_capture_all_units(self) -> None: + self.assertCountEqual( + item_groups.terran_units, + item_groups.barracks_units + item_groups.factory_units + item_groups.starport_units + item_groups.terran_mercenaries + ) + self.assertCountEqual( + item_groups.protoss_units, + item_groups.gateway_units + item_groups.robo_units + item_groups.stargate_units + ) + + def test_terran_original_progressive_group_fully_contained_in_wol_upgrades(self) -> None: + for item_name in item_groups.terran_original_progressive_upgrades: + self.assertIn(item_tables.item_table[item_name].type, ( + item_tables.TerranItemType.Progressive, item_tables.TerranItemType.Progressive_2), f"{item_name} is not progressive") + self.assertIn(item_name, item_groups.wol_upgrades) + + def test_all_items_in_stimpack_group_are_stimpacks(self) -> None: + for item_name in item_groups.terran_stimpacks: + self.assertIn("Stimpack", item_name) + + def test_all_item_group_names_have_a_group_defined(self) -> None: + for display_name in item_groups.ItemGroupNames.get_all_group_names(): + self.assertIn(display_name, item_groups.item_name_groups) diff --git a/worlds/sc2/test/test_items.py b/worlds/sc2/test/test_items.py new file mode 100644 index 000000000000..049810b9564d --- /dev/null +++ b/worlds/sc2/test/test_items.py @@ -0,0 +1,170 @@ +import unittest +from typing import List, Set + +from ..item import item_tables + + +class TestItems(unittest.TestCase): + def test_grouped_upgrades_number(self) -> None: + """ + Tests if grouped upgrades have set number correctly + """ + bundled_items = item_tables.upgrade_bundles.keys() + bundled_item_data = [item_tables.get_full_item_list()[item_name] for item_name in bundled_items] + bundled_item_numbers = [item_data.number for item_data in bundled_item_data] + + check_numbers = [number == -1 for number in bundled_item_numbers] + + self.assertNotIn(False, check_numbers) + + def test_non_grouped_upgrades_number(self) -> None: + """ + Checks if non-grouped upgrades number is set correctly thus can be sent into the game. + """ + check_modulo = 4 + bundled_items = item_tables.upgrade_bundles.keys() + non_bundled_upgrades = [ + item_name for item_name in item_tables.get_full_item_list().keys() + if (item_name not in bundled_items + and item_tables.get_full_item_list()[item_name].type in item_tables.upgrade_item_types) + ] + non_bundled_upgrade_data = [item_tables.get_full_item_list()[item_name] for item_name in non_bundled_upgrades] + non_bundled_upgrade_numbers = [item_data.number for item_data in non_bundled_upgrade_data] + + check_numbers = [number % check_modulo == 0 for number in non_bundled_upgrade_numbers] + + self.assertNotIn(False, check_numbers) + + def test_bundles_contain_only_basic_elements(self) -> None: + """ + Checks if there are no bundles within bundles. + """ + bundled_items = item_tables.upgrade_bundles.keys() + bundle_elements: List[str] = [item_name for values in item_tables.upgrade_bundles.values() for item_name in values] + + for element in bundle_elements: + self.assertNotIn(element, bundled_items) + + def test_weapon_armor_level(self) -> None: + """ + Checks if Weapon/Armor upgrade level is correctly set to all Weapon/Armor upgrade items. + """ + weapon_armor_upgrades = [item for item in item_tables.get_full_item_list() if item_tables.get_item_table()[item].type in item_tables.upgrade_item_types] + + for weapon_armor_upgrade in weapon_armor_upgrades: + self.assertEqual(item_tables.get_full_item_list()[weapon_armor_upgrade].quantity, item_tables.WEAPON_ARMOR_UPGRADE_MAX_LEVEL) + + def test_item_ids_distinct(self) -> None: + """ + Verifies if there are no duplicates of item ID. + """ + item_ids: Set[int] = {item_tables.get_full_item_list()[item_name].code for item_name in item_tables.get_full_item_list()} + + self.assertEqual(len(item_ids), len(item_tables.get_full_item_list())) + + def test_number_distinct_in_item_type(self) -> None: + """ + Tests if each item is distinct for sending into the mod. + """ + item_types: List[item_tables.ItemTypeEnum] = [ + *[item.value for item in item_tables.TerranItemType], + *[item.value for item in item_tables.ZergItemType], + *[item.value for item in item_tables.ProtossItemType], + *[item.value for item in item_tables.FactionlessItemType] + ] + + self.assertGreater(len(item_types), 0) + + for item_type in item_types: + item_names: List[str] = [ + item_name for item_name in item_tables.get_full_item_list() + if item_tables.get_full_item_list()[item_name].number >= 0 # Negative numbers have special meaning + and item_tables.get_full_item_list()[item_name].type == item_type + ] + item_numbers: Set[int] = {item_tables.get_full_item_list()[item_name] for item_name in item_names} + + self.assertEqual(len(item_names), len(item_numbers)) + + def test_progressive_has_quantity(self) -> None: + """ + :return: + """ + progressive_groups: List[item_tables.ItemTypeEnum] = [ + item_tables.TerranItemType.Progressive, + item_tables.TerranItemType.Progressive_2, + item_tables.ProtossItemType.Progressive, + item_tables.ZergItemType.Progressive + ] + + quantities: List[int] = [ + item_tables.get_full_item_list()[item].quantity for item in item_tables.get_full_item_list() + if item_tables.get_full_item_list()[item].type in progressive_groups + ] + + self.assertNotIn(1, quantities) + + def test_non_progressive_quantity(self) -> None: + """ + Check if non-progressive items have quantity at most 1. + """ + non_progressive_single_entity_groups: List[item_tables.ItemTypeEnum] = [ + # Terran + item_tables.TerranItemType.Unit, + item_tables.TerranItemType.Unit_2, + item_tables.TerranItemType.Mercenary, + item_tables.TerranItemType.Armory_1, + item_tables.TerranItemType.Armory_2, + item_tables.TerranItemType.Armory_3, + item_tables.TerranItemType.Armory_4, + item_tables.TerranItemType.Armory_5, + item_tables.TerranItemType.Armory_6, + item_tables.TerranItemType.Armory_7, + item_tables.TerranItemType.Building, + item_tables.TerranItemType.Laboratory, + item_tables.TerranItemType.Nova_Gear, + # Zerg + item_tables.ZergItemType.Unit, + item_tables.ZergItemType.Mercenary, + item_tables.ZergItemType.Morph, + item_tables.ZergItemType.Strain, + item_tables.ZergItemType.Mutation_1, + item_tables.ZergItemType.Mutation_2, + item_tables.ZergItemType.Mutation_3, + item_tables.ZergItemType.Evolution_Pit, + item_tables.ZergItemType.Ability, + # Protoss + item_tables.ProtossItemType.Unit, + item_tables.ProtossItemType.Unit_2, + item_tables.ProtossItemType.Building, + item_tables.ProtossItemType.Forge_1, + item_tables.ProtossItemType.Forge_2, + item_tables.ProtossItemType.Forge_3, + item_tables.ProtossItemType.Forge_4, + item_tables.ProtossItemType.Solarite_Core, + item_tables.ProtossItemType.Spear_Of_Adun + ] + + quantities: List[int] = [ + item_tables.get_full_item_list()[item].quantity for item in item_tables.get_full_item_list() + if item_tables.get_full_item_list()[item].type in non_progressive_single_entity_groups + ] + + for quantity in quantities: + self.assertLessEqual(quantity, 1) + + def test_item_number_less_than_30(self) -> None: + """ + Checks if all item numbers are within bounds supported by game mod. + """ + not_checked_item_types: List[item_tables.ItemTypeEnum] = [ + item_tables.ZergItemType.Level + ] + items_to_check: List[str] = [ + item for item in item_tables.get_full_item_list() + if item_tables.get_full_item_list()[item].type not in not_checked_item_types + ] + + for item in items_to_check: + item_number = item_tables.get_full_item_list()[item].number + self.assertLess(item_number, 30) + diff --git a/worlds/sc2/test/test_location_groups.py b/worlds/sc2/test/test_location_groups.py new file mode 100644 index 000000000000..f429464f7c2f --- /dev/null +++ b/worlds/sc2/test/test_location_groups.py @@ -0,0 +1,37 @@ +import unittest +from .. import location_groups +from ..mission_tables import SC2Mission, MissionFlag + + +class TestLocationGroups(unittest.TestCase): + @classmethod + def setUpClass(cls) -> None: + cls.location_groups = location_groups.get_location_groups() + + def test_location_categories_have_a_group(self) -> None: + self.assertIn('Victory', self.location_groups) + self.assertIn(f'{SC2Mission.LIBERATION_DAY.mission_name}: Victory', self.location_groups['Victory']) + self.assertIn(f'{SC2Mission.IN_UTTER_DARKNESS.mission_name}: Defeat', self.location_groups['Victory']) + self.assertIn('Vanilla', self.location_groups) + self.assertIn(f'{SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name}: Close Relic', self.location_groups['Vanilla']) + self.assertIn('Extra', self.location_groups) + self.assertIn(f'{SC2Mission.SMASH_AND_GRAB.mission_name}: First Forcefield Area Busted', self.location_groups['Extra']) + self.assertIn('Challenge', self.location_groups) + self.assertIn(f'{SC2Mission.ZERO_HOUR.mission_name}: First Hatchery', self.location_groups['Challenge']) + self.assertIn('Mastery', self.location_groups) + self.assertIn(f'{SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name}: Protoss Cleared', self.location_groups['Mastery']) + + def test_missions_have_a_group(self) -> None: + self.assertIn(SC2Mission.LIBERATION_DAY.mission_name, self.location_groups) + self.assertIn(f'{SC2Mission.LIBERATION_DAY.mission_name}: Victory', self.location_groups[SC2Mission.LIBERATION_DAY.mission_name]) + self.assertIn(f'{SC2Mission.LIBERATION_DAY.mission_name}: Special Delivery', self.location_groups[SC2Mission.LIBERATION_DAY.mission_name]) + + def test_race_swapped_locations_share_a_group(self) -> None: + self.assertIn(MissionFlag.HasRaceSwap, SC2Mission.ZERO_HOUR.flags) + ZERO_HOUR = 'Zero Hour' + self.assertNotEqual(ZERO_HOUR, SC2Mission.ZERO_HOUR.mission_name) + self.assertIn(ZERO_HOUR, self.location_groups) + self.assertIn(f'{ZERO_HOUR}: Victory', self.location_groups) + self.assertIn(f'{SC2Mission.ZERO_HOUR.mission_name}: Victory', self.location_groups[f'{ZERO_HOUR}: Victory']) + self.assertIn(f'{SC2Mission.ZERO_HOUR_P.mission_name}: Victory', self.location_groups[f'{ZERO_HOUR}: Victory']) + self.assertIn(f'{SC2Mission.ZERO_HOUR_Z.mission_name}: Victory', self.location_groups[f'{ZERO_HOUR}: Victory']) diff --git a/worlds/sc2/test/test_mission_groups.py b/worlds/sc2/test/test_mission_groups.py new file mode 100644 index 000000000000..6db7325da7be --- /dev/null +++ b/worlds/sc2/test/test_mission_groups.py @@ -0,0 +1,9 @@ +import unittest +from .. import mission_groups + + +class TestMissionGroups(unittest.TestCase): + def test_all_mission_groups_are_defined_and_nonempty(self) -> None: + for mission_group_name in mission_groups.MissionGroupNames.get_all_group_names(): + self.assertIn(mission_group_name, mission_groups.mission_groups) + self.assertTrue(mission_groups.mission_groups[mission_group_name]) diff --git a/worlds/sc2/test/test_options.py b/worlds/sc2/test/test_options.py index 30d21f39697e..69b834da51f7 100644 --- a/worlds/sc2/test/test_options.py +++ b/worlds/sc2/test/test_options.py @@ -1,7 +1,19 @@ import unittest -from .test_base import Sc2TestBase -from .. import Options, MissionTables +from typing import Dict + +from .. import options +from ..item import item_parents + class TestOptions(unittest.TestCase): - def test_campaign_size_option_max_matches_number_of_missions(self): - self.assertEqual(Options.MaximumCampaignSize.range_end, len(MissionTables.SC2Mission)) + + def test_unit_max_upgrades_matching_items(self) -> None: + upgrade_group_to_count: Dict[str, int] = {} + for parent_id, child_list in item_parents.parent_id_to_children.items(): + main_parent = item_parents.parent_present[parent_id].constraint_group + if main_parent is None: + continue + upgrade_group_to_count.setdefault(main_parent, 0) + upgrade_group_to_count[main_parent] += len(child_list) + + self.assertEqual(options.MAX_UPGRADES_OPTION, max(upgrade_group_to_count.values())) diff --git a/worlds/sc2/test/test_regions.py b/worlds/sc2/test/test_regions.py new file mode 100644 index 000000000000..880a02f97374 --- /dev/null +++ b/worlds/sc2/test/test_regions.py @@ -0,0 +1,40 @@ +import unittest +from .test_base import Sc2TestBase +from .. import mission_tables, SC2Campaign +from .. import options +from ..mission_order.layout_types import Grid + +class TestGridsizes(unittest.TestCase): + def test_grid_sizes_meet_specs(self): + self.assertTupleEqual((1, 2, 0), Grid.get_grid_dimensions(2)) + self.assertTupleEqual((1, 3, 0), Grid.get_grid_dimensions(3)) + self.assertTupleEqual((2, 2, 0), Grid.get_grid_dimensions(4)) + self.assertTupleEqual((2, 3, 1), Grid.get_grid_dimensions(5)) + self.assertTupleEqual((2, 4, 1), Grid.get_grid_dimensions(7)) + self.assertTupleEqual((2, 4, 0), Grid.get_grid_dimensions(8)) + self.assertTupleEqual((3, 3, 0), Grid.get_grid_dimensions(9)) + self.assertTupleEqual((2, 5, 0), Grid.get_grid_dimensions(10)) + self.assertTupleEqual((3, 4, 1), Grid.get_grid_dimensions(11)) + self.assertTupleEqual((3, 4, 0), Grid.get_grid_dimensions(12)) + self.assertTupleEqual((3, 5, 0), Grid.get_grid_dimensions(15)) + self.assertTupleEqual((4, 4, 0), Grid.get_grid_dimensions(16)) + self.assertTupleEqual((4, 6, 0), Grid.get_grid_dimensions(24)) + self.assertTupleEqual((5, 5, 0), Grid.get_grid_dimensions(25)) + self.assertTupleEqual((5, 6, 1), Grid.get_grid_dimensions(29)) + self.assertTupleEqual((5, 7, 2), Grid.get_grid_dimensions(33)) + + +class TestGridGeneration(Sc2TestBase): + options = { + "mission_order": options.MissionOrder.option_grid, + "excluded_missions": [mission_tables.SC2Mission.ZERO_HOUR.mission_name,], + "enabled_campaigns": { + SC2Campaign.WOL.campaign_name, + SC2Campaign.PROPHECY.campaign_name, + } + } + + def test_size_matches_exclusions(self): + self.assertNotIn(mission_tables.SC2Mission.ZERO_HOUR.mission_name, self.multiworld.regions) + # WoL has 29 missions. -1 for Zero Hour being excluded, +1 for the automatically-added menu location + self.assertEqual(len(self.multiworld.regions), 29) diff --git a/worlds/sc2/test/test_rules.py b/worlds/sc2/test/test_rules.py new file mode 100644 index 000000000000..d43a4d4e2bbc --- /dev/null +++ b/worlds/sc2/test/test_rules.py @@ -0,0 +1,186 @@ +import itertools +from dataclasses import fields +from random import Random +import unittest +from typing import List, Set, Iterable + +from BaseClasses import ItemClassification, MultiWorld +import Options as CoreOptions +from .. import options, locations +from ..item import item_tables +from ..rules import SC2Logic +from ..mission_tables import SC2Race, MissionFlag, lookup_name_to_mission + + +class TestInventory: + """ + Runs checks against inventory with validation if all target items are progression and returns a random result + """ + def __init__(self) -> None: + self.random: Random = Random() + self.progression_types: Set[ItemClassification] = {ItemClassification.progression, ItemClassification.progression_skip_balancing} + + def is_item_progression(self, item: str) -> bool: + return item_tables.item_table[item].classification in self.progression_types + + def random_boolean(self): + return self.random.choice([True, False]) + + def has(self, item: str, player: int, count: int = 1): + if not self.is_item_progression(item): + raise AssertionError("Logic item {} is not a progression item".format(item)) + return self.random_boolean() + + def has_any(self, items: Set[str], player: int): + non_progression_items = [item for item in items if not self.is_item_progression(item)] + if len(non_progression_items) > 0: + raise AssertionError("Logic items {} are not progression items".format(non_progression_items)) + return self.random_boolean() + + def has_all(self, items: Set[str], player: int): + return self.has_any(items, player) + + def has_group(self, item_group: str, player: int, count: int = 1): + return self.random_boolean() + + def count_group(self, item_name_group: str, player: int) -> int: + return self.random.randrange(0, 20) + + def count(self, item: str, player: int) -> int: + if not self.is_item_progression(item): + raise AssertionError("Item {} is not a progression item".format(item)) + random_value: int = self.random.randrange(0, 5) + if random_value == 4: # 0-3 has a higher chance due to logic rules + return self.random.randrange(4, 100) + else: + return random_value + + def count_from_list(self, items: Iterable[str], player: int) -> int: + return sum(self.count(item_name, player) for item_name in items) + + def count_from_list_unique(self, items: Iterable[str], player: int) -> int: + return sum(self.count(item_name, player) for item_name in items) + + +class TestWorld: + """ + Mock world to simulate different player options for logic rules + """ + def __init__(self) -> None: + defaults = dict() + for field in fields(options.Starcraft2Options): + field_class = field.type + option_name = field.name + if isinstance(field_class, str): + if field_class in globals(): + field_class = globals()[field_class] + else: + field_class = CoreOptions.__dict__[field.type] + defaults[option_name] = field_class(options.get_option_value(None, option_name)) + self.options: options.Starcraft2Options = options.Starcraft2Options(**defaults) + + self.options.mission_order.value = options.MissionOrder.option_vanilla_shuffled + + self.player = 1 + self.multiworld = MultiWorld(1) + + +class TestRules(unittest.TestCase): + def setUp(self) -> None: + self.required_tactics_values: List[int] = [ + options.RequiredTactics.option_standard, options.RequiredTactics.option_advanced + ] + self.all_in_map_values: List[int] = [ + options.AllInMap.option_ground, options.AllInMap.option_air + ] + self.take_over_ai_allies_values: List[int] = [ + options.TakeOverAIAllies.option_true, options.TakeOverAIAllies.option_false + ] + self.kerrigan_presence_values: List[int] = [ + options.KerriganPresence.option_vanilla, options.KerriganPresence.option_not_present + ] + self.NUM_TEST_RUNS = 100 + + @staticmethod + def _get_world( + required_tactics: int = options.RequiredTactics.default, + all_in_map: int = options.AllInMap.default, + take_over_ai_allies: int = options.TakeOverAIAllies.default, + kerrigan_presence: int = options.KerriganPresence.default, + # setting this to everywhere catches one extra logic check for Amon's Fall without missing any + spear_of_adun_passive_presence: int = options.SpearOfAdunPassiveAbilityPresence.option_everywhere, + ) -> TestWorld: + test_world = TestWorld() + test_world.options.required_tactics.value = required_tactics + test_world.options.all_in_map.value = all_in_map + test_world.options.take_over_ai_allies.value = take_over_ai_allies + test_world.options.kerrigan_presence.value = kerrigan_presence + test_world.options.spear_of_adun_passive_ability_presence.value = spear_of_adun_passive_presence + test_world.logic = SC2Logic(test_world) # type: ignore + return test_world + + def test_items_in_rules_are_progression(self): + test_inventory = TestInventory() + for option in self.required_tactics_values: + test_world = self._get_world(required_tactics=option) + location_data = locations.get_locations(test_world) + for location in location_data: + for _ in range(self.NUM_TEST_RUNS): + location.rule(test_inventory) + + def test_items_in_all_in_are_progression(self): + test_inventory = TestInventory() + for test_options in itertools.product(self.required_tactics_values, self.all_in_map_values): + test_world = self._get_world(required_tactics=test_options[0], all_in_map=test_options[1]) + for location in locations.get_locations(test_world): + if 'All-In' not in location.region: + continue + for _ in range(self.NUM_TEST_RUNS): + location.rule(test_inventory) + + def test_items_in_kerriganless_missions_are_progression(self): + test_inventory = TestInventory() + for test_options in itertools.product(self.required_tactics_values, self.kerrigan_presence_values): + test_world = self._get_world(required_tactics=test_options[0], kerrigan_presence=test_options[1]) + for location in locations.get_locations(test_world): + mission = lookup_name_to_mission[location.region] + if MissionFlag.Kerrigan not in mission.flags: + continue + for _ in range(self.NUM_TEST_RUNS): + location.rule(test_inventory) + + def test_items_in_ai_takeover_missions_are_progression(self): + test_inventory = TestInventory() + for test_options in itertools.product(self.required_tactics_values, self.take_over_ai_allies_values): + test_world = self._get_world(required_tactics=test_options[0], take_over_ai_allies=test_options[1]) + for location in locations.get_locations(test_world): + mission = lookup_name_to_mission[location.region] + if MissionFlag.AiAlly not in mission.flags: + continue + for _ in range(self.NUM_TEST_RUNS): + location.rule(test_inventory) + + def test_items_in_hard_rules_are_progression(self): + test_inventory = TestInventory() + test_world = TestWorld() + test_world.options.required_tactics.value = options.RequiredTactics.option_any_units + test_world.logic = SC2Logic(test_world) + location_data = locations.get_locations(test_world) + for location in location_data: + if location.hard_rule is not None: + for _ in range(10): + location.hard_rule(test_inventory) + + def test_items_in_any_units_rules_are_progression(self): + test_inventory = TestInventory() + test_world = TestWorld() + test_world.options.required_tactics.value = options.RequiredTactics.option_any_units + logic = SC2Logic(test_world) + test_world.logic = logic + for race in (SC2Race.TERRAN, SC2Race.PROTOSS, SC2Race.ZERG): + for target in range(1, 5): + rule = logic.has_race_units(target, race) + for _ in range(10): + rule(test_inventory) + + diff --git a/worlds/sc2/test/test_usecases.py b/worlds/sc2/test/test_usecases.py new file mode 100644 index 000000000000..a87d176674ac --- /dev/null +++ b/worlds/sc2/test/test_usecases.py @@ -0,0 +1,492 @@ +""" +Unit tests for yaml usecases we want to support +""" + +from .test_base import Sc2SetupTestBase +from .. import get_all_missions, mission_tables, options +from ..item import item_groups, item_tables, item_names +from ..mission_tables import SC2Race, SC2Mission, SC2Campaign, MissionFlag +from ..options import EnabledCampaigns, MasteryLocations + + +class TestSupportedUseCases(Sc2SetupTestBase): + def test_vanilla_all_campaigns_generates(self) -> None: + world_options = { + 'mission_order': options.MissionOrder.option_vanilla, + 'enabled_campaigns': EnabledCampaigns.valid_keys, + } + + self.generate_world(world_options) + world_regions = [region.name for region in self.multiworld.regions if region.name != "Menu"] + + self.assertEqual(len(world_regions), 83, "Unexpected number of missions for vanilla mission order") + + def test_terran_with_nco_units_only_generates(self): + world_options = { + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + SC2Campaign.NCO.campaign_name + }, + 'excluded_items': { + item_groups.ItemGroupNames.TERRAN_UNITS: 0, + }, + 'unexcluded_items': { + item_groups.ItemGroupNames.NCO_UNITS: 0, + }, + 'max_number_of_upgrades': 2, + } + + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + world_item_names = [item.name for item in self.multiworld.itempool] + + self.assertIn(item_names.MARINE, world_item_names) + self.assertIn(item_names.RAVEN, world_item_names) + self.assertIn(item_names.LIBERATOR, world_item_names) + self.assertIn(item_names.BATTLECRUISER, world_item_names) + self.assertNotIn(item_names.DIAMONDBACK, world_item_names) + self.assertNotIn(item_names.DIAMONDBACK_BURST_CAPACITORS, world_item_names) + self.assertNotIn(item_names.VIKING, world_item_names) + + def test_nco_with_nobuilds_excluded_generates(self): + world_options = { + 'enabled_campaigns': { + SC2Campaign.NCO.campaign_name + }, + 'shuffle_no_build': options.ShuffleNoBuild.option_false, + 'mission_order': options.MissionOrder.option_mini_campaign, + } + + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + missions = get_all_missions(self.world.custom_mission_order) + + self.assertNotIn(mission_tables.SC2Mission.THE_ESCAPE, missions) + self.assertNotIn(mission_tables.SC2Mission.IN_THE_ENEMY_S_SHADOW, missions) + for mission in missions: + self.assertEqual(mission_tables.SC2Campaign.NCO, mission.campaign) + + def test_terran_with_nco_upgrades_units_only_generates(self): + world_options = { + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + SC2Campaign.NCO.campaign_name + }, + 'mission_order': options.MissionOrder.option_vanilla_shuffled, + 'excluded_items': { + item_groups.ItemGroupNames.TERRAN_ITEMS: 0, + }, + 'unexcluded_items': { + item_groups.ItemGroupNames.NCO_MAX_PROGRESSIVE_ITEMS: 0, + item_groups.ItemGroupNames.NCO_MIN_PROGRESSIVE_ITEMS: 1, + }, + 'excluded_missions': [ + # These missions have trouble fulfilling Terran Power Rating under these terms + SC2Mission.SUPERNOVA.mission_name, + SC2Mission.WELCOME_TO_THE_JUNGLE.mission_name, + SC2Mission.TROUBLE_IN_PARADISE.mission_name, + ], + 'mastery_locations': MasteryLocations.option_disabled, + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool + self.multiworld.precollected_items[1]] + self.assertTrue(world_item_names) + missions = get_all_missions(self.world.custom_mission_order) + + for mission in missions: + self.assertIn(mission_tables.MissionFlag.Terran, mission.flags) + self.assertIn(item_names.MARINE, world_item_names) + self.assertIn(item_names.MARAUDER, world_item_names) + self.assertIn(item_names.BUNKER, world_item_names) + self.assertIn(item_names.BANSHEE, world_item_names) + self.assertIn(item_names.BATTLECRUISER_ATX_LASER_BATTERY, world_item_names) + self.assertIn(item_names.NOVA_C20A_CANISTER_RIFLE, world_item_names) + self.assertGreaterEqual(world_item_names.count(item_names.BANSHEE_PROGRESSIVE_CROSS_SPECTRUM_DAMPENERS), 2) + self.assertGreaterEqual(world_item_names.count(item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON), 3) + self.assertNotIn(item_names.MEDIC, world_item_names) + self.assertNotIn(item_names.PSI_DISRUPTER, world_item_names) + self.assertNotIn(item_names.BATTLECRUISER_PROGRESSIVE_MISSILE_PODS, world_item_names) + self.assertNotIn(item_names.HELLION_INFERNAL_PLATING, world_item_names) + self.assertNotIn(item_names.CELLULAR_REACTOR, world_item_names) + self.assertNotIn(item_names.TECH_REACTOR, world_item_names) + + def test_nco_and_2_wol_missions_only_can_generate_with_vanilla_items_only(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + SC2Campaign.NCO.campaign_name + }, + 'excluded_missions': [ + mission.mission_name for mission in mission_tables.SC2Mission + if mission.campaign == mission_tables.SC2Campaign.WOL + and mission.mission_name not in (mission_tables.SC2Mission.LIBERATION_DAY.mission_name, mission_tables.SC2Mission.THE_OUTLAWS.mission_name) + ], + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'mastery_locations': options.MasteryLocations.option_disabled, + 'vanilla_items_only': True, + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + + self.assertTrue(item_names) + self.assertNotIn(item_names.LIBERATOR, world_item_names) + self.assertNotIn(item_names.MARAUDER_PROGRESSIVE_STIMPACK, world_item_names) + self.assertNotIn(item_names.HELLION_HELLBAT, world_item_names) + self.assertNotIn(item_names.BATTLECRUISER_CLOAK, world_item_names) + + def test_free_protoss_only_generates(self) -> None: + world_options = { + 'enabled_campaigns': { + SC2Campaign.PROPHECY.campaign_name, + SC2Campaign.PROLOGUE.campaign_name + }, + # todo(mm): Currently, these settings don't generate on grid because there are not enough EASY missions + 'mission_order': options.MissionOrder.option_vanilla_shuffled, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'accessibility': 'locations', + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + self.assertTrue(world_item_names) + missions = get_all_missions(self.world.custom_mission_order) + + self.assertEqual(len(missions), 7, "Wrong number of missions in free protoss seed") + for mission in missions: + self.assertIn(mission.campaign, (mission_tables.SC2Campaign.PROLOGUE, mission_tables.SC2Campaign.PROPHECY)) + for item_name in world_item_names: + self.assertIn(item_tables.item_table[item_name].race, (mission_tables.SC2Race.ANY, mission_tables.SC2Race.PROTOSS)) + + def test_resource_filler_items_may_be_put_in_start_inventory(self) -> None: + NUM_RESOURCE_ITEMS = 10 + world_options = { + 'start_inventory': { + item_names.STARTING_MINERALS: NUM_RESOURCE_ITEMS, + item_names.STARTING_VESPENE: NUM_RESOURCE_ITEMS, + item_names.STARTING_SUPPLY: NUM_RESOURCE_ITEMS, + }, + } + + self.generate_world(world_options) + start_item_names = [item.name for item in self.multiworld.precollected_items[self.player]] + + self.assertEqual(start_item_names.count(item_names.STARTING_MINERALS), NUM_RESOURCE_ITEMS, "Wrong number of starting minerals in starting inventory") + self.assertEqual(start_item_names.count(item_names.STARTING_VESPENE), NUM_RESOURCE_ITEMS, "Wrong number of starting vespene in starting inventory") + self.assertEqual(start_item_names.count(item_names.STARTING_SUPPLY), NUM_RESOURCE_ITEMS, "Wrong number of starting supply in starting inventory") + + def test_excluding_protoss_excludes_campaigns_and_items(self) -> None: + world_options = { + 'selected_races': { + SC2Race.TERRAN.get_title(), + SC2Race.ZERG.get_title(), + }, + 'enabled_campaigns': options.EnabledCampaigns.valid_keys, + 'mission_order': options.MissionOrder.option_grid, + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + world_regions = [region.name for region in self.multiworld.regions] + world_regions.remove('Menu') + + for item_name in world_item_names: + self.assertNotEqual(item_tables.item_table[item_name].race, mission_tables.SC2Race.PROTOSS, f"{item_name} is a PROTOSS item!") + for region in world_regions: + self.assertNotIn(mission_tables.lookup_name_to_mission[region].campaign, + (mission_tables.SC2Campaign.LOTV, mission_tables.SC2Campaign.PROPHECY, mission_tables.SC2Campaign.PROLOGUE), + f"{region} is a PROTOSS mission!") + + def test_excluding_terran_excludes_campaigns_and_items(self) -> None: + world_options = { + 'selected_races': { + SC2Race.ZERG.get_title(), + SC2Race.PROTOSS.get_title(), + }, + 'enabled_campaigns': EnabledCampaigns.valid_keys, + 'mission_order': options.MissionOrder.option_grid, + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + world_regions = [region.name for region in self.multiworld.regions] + world_regions.remove('Menu') + + for item_name in world_item_names: + self.assertNotEqual(item_tables.item_table[item_name].race, mission_tables.SC2Race.TERRAN, + f"{item_name} is a TERRAN item!") + for region in world_regions: + self.assertNotIn(mission_tables.lookup_name_to_mission[region].campaign, + (mission_tables.SC2Campaign.WOL, mission_tables.SC2Campaign.NCO), + f"{region} is a TERRAN mission!") + + def test_excluding_zerg_excludes_campaigns_and_items(self) -> None: + world_options = { + 'selected_races': { + SC2Race.TERRAN.get_title(), + SC2Race.PROTOSS.get_title(), + }, + 'enabled_campaigns': EnabledCampaigns.valid_keys, + 'mission_order': options.MissionOrder.option_grid, + 'excluded_missions': [ + SC2Mission.THE_INFINITE_CYCLE.mission_name + ] + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + world_regions = [region.name for region in self.multiworld.regions] + world_regions.remove('Menu') + + for item_name in world_item_names: + self.assertNotEqual(item_tables.item_table[item_name].race, mission_tables.SC2Race.ZERG, + f"{item_name} is a ZERG item!") + # have to manually exclude the only non-zerg HotS mission... + for region in filter(lambda region: region != "With Friends Like These", world_regions): + self.assertNotIn(mission_tables.lookup_name_to_mission[region].campaign, + ([mission_tables.SC2Campaign.HOTS]), + f"{region} is a ZERG mission!") + + def test_excluding_faction_on_vanilla_order_excludes_epilogue(self) -> None: + world_options = { + 'selected_races': { + SC2Race.TERRAN.get_title(), + SC2Race.PROTOSS.get_title(), + }, + 'enabled_campaigns': EnabledCampaigns.valid_keys, + 'mission_order': options.MissionOrder.option_vanilla, + } + + self.generate_world(world_options) + world_regions = [region.name for region in self.multiworld.regions] + world_regions.remove('Menu') + + for region in world_regions: + self.assertNotIn(mission_tables.lookup_name_to_mission[region].campaign, + ([mission_tables.SC2Campaign.EPILOGUE]), + f"{region} is an epilogue mission!") + + def test_race_swap_pick_one_has_correct_length_and_includes_swaps(self) -> None: + world_options = { + 'selected_races': options.SelectRaces.valid_keys, + 'enable_race_swap': options.EnableRaceSwapVariants.option_pick_one, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + 'mission_order': options.MissionOrder.option_grid, + 'excluded_missions': [mission_tables.SC2Mission.ZERO_HOUR.mission_name], + } + + self.generate_world(world_options) + world_regions = [region.name for region in self.multiworld.regions] + world_regions.remove('Menu') + NUM_WOL_MISSIONS = len([mission for mission in SC2Mission if mission.campaign == SC2Campaign.WOL and MissionFlag.RaceSwap not in mission.flags]) + races = set(mission_tables.lookup_name_to_mission[mission].race for mission in world_regions) + + self.assertEqual(len(world_regions), NUM_WOL_MISSIONS) + self.assertTrue(SC2Race.ZERG in races or SC2Race.PROTOSS in races) + + def test_start_inventory_upgrade_level_includes_only_correct_bundle(self) -> None: + world_options = { + 'start_inventory': { + item_groups.ItemGroupNames.TERRAN_GENERIC_UPGRADES: 1, + }, + 'locked_items': { + # One unit of each class to guarantee upgrades are available + item_names.MARINE: 1, + item_names.VULTURE: 1, + item_names.BANSHEE: 1, + }, + 'generic_upgrade_items': options.GenericUpgradeItems.option_bundle_unit_class, + 'selected_races': { + SC2Race.TERRAN.get_title(), + }, + 'enable_race_swap': options.EnableRaceSwapVariants.option_disabled, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name, + }, + 'mission_order': options.MissionOrder.option_grid, + } + self.generate_world(world_options) + self.assertTrue(self.multiworld.itempool) + world_item_names = [item.name for item in self.multiworld.itempool] + start_inventory = [item.name for item in self.multiworld.precollected_items[self.player]] + + # Start inventory + self.assertIn(item_names.PROGRESSIVE_TERRAN_INFANTRY_UPGRADE, start_inventory) + self.assertIn(item_names.PROGRESSIVE_TERRAN_VEHICLE_UPGRADE, start_inventory) + self.assertIn(item_names.PROGRESSIVE_TERRAN_SHIP_UPGRADE, start_inventory) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, start_inventory) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR, start_inventory) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, start_inventory) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR, start_inventory) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, start_inventory) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR, start_inventory) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_ARMOR_UPGRADE, start_inventory) + + # Additional items in pool -- standard tactics will require additional levels + self.assertIn(item_names.PROGRESSIVE_TERRAN_INFANTRY_UPGRADE, world_item_names) + self.assertIn(item_names.PROGRESSIVE_TERRAN_VEHICLE_UPGRADE, world_item_names) + self.assertIn(item_names.PROGRESSIVE_TERRAN_SHIP_UPGRADE, world_item_names) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, world_item_names) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR, world_item_names) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, world_item_names) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR, world_item_names) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, world_item_names) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR, world_item_names) + self.assertNotIn(item_names.PROGRESSIVE_TERRAN_ARMOR_UPGRADE, world_item_names) + + def test_kerrigan_max_active_abilities(self): + target_number: int = 8 + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'selected_races': { + SC2Race.ZERG.get_title(), + }, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'kerrigan_max_active_abilities': target_number, + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + kerrigan_actives = [item_name for item_name in world_item_names if item_name in item_groups.kerrigan_active_abilities] + + self.assertLessEqual(len(kerrigan_actives), target_number) + + def test_kerrigan_max_passive_abilities(self): + target_number: int = 3 + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'selected_races': { + SC2Race.ZERG.get_title(), + }, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'kerrigan_max_passive_abilities': target_number, + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + kerrigan_passives = [item_name for item_name in world_item_names if item_name in item_groups.kerrigan_passives] + + self.assertLessEqual(len(kerrigan_passives), target_number) + + def test_spear_of_adun_max_active_abilities(self): + target_number: int = 8 + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'selected_races': { + SC2Race.PROTOSS.get_title(), + }, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'spear_of_adun_max_active_abilities': target_number, + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + spear_of_adun_actives = [item_name for item_name in world_item_names if item_name in item_tables.spear_of_adun_calldowns] + + self.assertLessEqual(len(spear_of_adun_actives), target_number) + + + def test_spear_of_adun_max_autocasts(self): + target_number: int = 2 + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'selected_races': { + SC2Race.PROTOSS.get_title(), + }, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'spear_of_adun_max_passive_abilities': target_number, + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + spear_of_adun_autocasts = [item_name for item_name in world_item_names if item_name in item_tables.spear_of_adun_castable_passives] + + self.assertLessEqual(len(spear_of_adun_autocasts), target_number) + + + def test_nova_max_weapons(self): + target_number: int = 3 + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'selected_races': { + SC2Race.TERRAN.get_title(), + }, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'nova_max_weapons': target_number, + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + nova_weapons = [item_name for item_name in world_item_names if item_name in item_groups.nova_weapons] + + self.assertLessEqual(len(nova_weapons), target_number) + + + def test_nova_max_gadgets(self): + target_number: int = 3 + world_options = { + 'mission_order': options.MissionOrder.option_grid, + 'maximum_campaign_size': options.MaximumCampaignSize.range_end, + 'selected_races': { + SC2Race.TERRAN.get_title(), + }, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'nova_max_gadgets': target_number, + } + + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + nova_gadgets = [item_name for item_name in world_item_names if item_name in item_groups.nova_gadgets] + + self.assertLessEqual(len(nova_gadgets), target_number) + + def test_mercs_only(self) -> None: + world_options = { + 'selected_races': [ + SC2Race.TERRAN.get_title(), + SC2Race.ZERG.get_title(), + ], + 'required_tactics': options.RequiredTactics.option_any_units, + 'excluded_items': { + item_groups.ItemGroupNames.TERRAN_UNITS: 0, + item_groups.ItemGroupNames.ZERG_UNITS: 0, + }, + 'unexcluded_items': { + item_groups.ItemGroupNames.TERRAN_MERCENARIES: 0, + item_groups.ItemGroupNames.ZERG_MERCENARIES: 0, + }, + 'start_inventory': { + item_names.PROGRESSIVE_FAST_DELIVERY: 1, + item_names.ROGUE_FORCES: 1, + item_names.UNRESTRICTED_MUTATION: 1, + item_names.EVOLUTIONARY_LEAP: 1, + }, + 'mission_order': options.MissionOrder.option_grid, + 'excluded_missions': [ + SC2Mission.ENEMY_WITHIN.mission_name, # Requires a unit for Niadra to build + ], + } + self.generate_world(world_options) + world_item_names = [item.name for item in self.multiworld.itempool] + terran_nonmerc_units = tuple( + item_name + for item_name in world_item_names + if item_name in item_groups.terran_units and item_name not in item_groups.terran_mercenaries + ) + zerg_nonmerc_units = tuple( + item_name + for item_name in world_item_names + if item_name in item_groups.zerg_units and item_name not in item_groups.zerg_mercenaries + ) + + self.assertTupleEqual(terran_nonmerc_units, ()) + self.assertTupleEqual(zerg_nonmerc_units, ()) diff --git a/worlds/sc2/transfer_data.py b/worlds/sc2/transfer_data.py new file mode 100644 index 000000000000..0718c35004a8 --- /dev/null +++ b/worlds/sc2/transfer_data.py @@ -0,0 +1,38 @@ +from typing import Dict, List + +""" +This file is for handling SC2 data read via the bot +""" + +normalized_unit_types: Dict[str, str] = { + # Thor morphs + "AP_ThorAP": "AP_Thor", + "AP_MercThorAP": "AP_MercThor", + "AP_ThorMengskSieged": "AP_ThorMengsk", + "AP_ThorMengskAP": "AP_ThorMengsk", + # Siege Tank morphs + "AP_SiegeTankSiegedTransportable": "AP_SiegeTank", + "AP_SiegeTankMengskSiegedTransportable": "AP_SiegeTankMengsk", + "AP_SiegeBreakerSiegedTransportable": "AP_SiegeBreaker", + "AP_InfestedSiegeBreakerSiegedTransportable": "AP_InfestedSiegeBreaker", + "AP_StukovInfestedSiegeTank": "AP_StukovInfestedSiegeTankUprooted", + # Cargo size upgrades + "AP_FirebatOptimizedLogistics": "AP_Firebat", + "AP_DevilDogOptimizedLogistics": "AP_DevilDog", + "AP_GhostResourceEfficiency": "AP_Ghost", + "AP_GhostMengskResourceEfficiency": "AP_GhostMengsk", + "AP_SpectreResourceEfficiency": "AP_Spectre", + "AP_UltraliskResourceEfficiency": "AP_Ultralisk", + "AP_MercUltraliskResourceEfficiency": "AP_MercUltralisk", + "AP_ReaperResourceEfficiency": "AP_Reaper", + "AP_MercReaperResourceEfficiency": "AP_MercReaper", +} + +worker_units: List[str] = [ + "AP_SCV", + "AP_MULE", # Mules can't currently build (or be traded due to timed life), this is future proofing just in case + "AP_Drone", + "AP_SISCV", # Infested SCV + "AP_Probe", + "AP_ElderProbe", +] From a9f594d6b260a9f5b1b4ee0835933442069e0687 Mon Sep 17 00:00:00 2001 From: Ziktofel Date: Tue, 2 Sep 2025 23:50:29 +0200 Subject: [PATCH 0689/1218] SC2: Remove Starcraft2Client.py as Launcher.py got upgraded to work under Python 3.13 (#5406) --- Starcraft2Client.py | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 Starcraft2Client.py diff --git a/Starcraft2Client.py b/Starcraft2Client.py deleted file mode 100644 index 14e1832074a4..000000000000 --- a/Starcraft2Client.py +++ /dev/null @@ -1,13 +0,0 @@ -from __future__ import annotations - -import ModuleUpdate -ModuleUpdate.update() - -from worlds.sc2.client import launch -import Utils - -# This is deprecated, replaced with the client hooked from the Launcher -# Will be removed in a following release -if __name__ == "__main__": - Utils.init_logging("Starcraft2Client", exception_logger="Client") - launch() From 7a1311984f6110ff010703f82cc7f3639a85369e Mon Sep 17 00:00:00 2001 From: qwint Date: Wed, 3 Sep 2025 14:00:36 -0500 Subject: [PATCH 0690/1218] Docs: Update max py version to 3.13 #5410 --- docs/running from source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/running from source.md b/docs/running from source.md index 36bff8c8faba..efe6e2436189 100644 --- a/docs/running from source.md +++ b/docs/running from source.md @@ -10,7 +10,7 @@ What you'll need: * [Python 3.11.9 or newer](https://www.python.org/downloads/), not the Windows Store version * On Windows, please consider only using the latest supported version in production environments since security updates for older versions are not easily available. - * Python 3.12.x is currently the newest supported version + * Python 3.13.x is currently the newest supported version * pip: included in downloads from python.org, separate in many Linux distributions * Matching C compiler * possibly optional, read operating system specific sections From 8f88152532bba4e6e2dc620bb4a324037eff2feb Mon Sep 17 00:00:00 2001 From: qwint Date: Wed, 3 Sep 2025 14:01:56 -0500 Subject: [PATCH 0691/1218] MultiServer: Validate CreateHints status arg #5408 --- MultiServer.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MultiServer.py b/MultiServer.py index 11a9e394c6b6..2b58b3402e14 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1961,6 +1961,16 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): if not locations: await ctx.send_msgs(client, [{"cmd": "InvalidPacket", "type": "arguments", "text": "CreateHints: No locations specified.", "original_cmd": cmd}]) + return + + try: + status = HintStatus(status) + except ValueError as err: + await ctx.send_msgs(client, + [{"cmd": "InvalidPacket", "type": "arguments", + "text": f"Unknown Status: {err}", + "original_cmd": cmd}]) + return hints = [] From 3c28db0800ba2b09d806d57841bb5dd122766a1f Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Wed, 3 Sep 2025 15:02:32 -0400 Subject: [PATCH 0692/1218] LADX: Drop a marin text option that makes patching fail #5398 --- worlds/ladx/LADXR/patches/marin.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/worlds/ladx/LADXR/patches/marin.txt b/worlds/ladx/LADXR/patches/marin.txt index 782f4129ce6e..e287833a514f 100644 --- a/worlds/ladx/LADXR/patches/marin.txt +++ b/worlds/ladx/LADXR/patches/marin.txt @@ -424,7 +424,6 @@ Oh, look at that. Link's Awakened.\nYou did it, you beat the game. Excellent armaments, #####. Please return - \nCOVERED IN BLOOD -\n...safe and sound. Pray return to the Link's Awakening Sands. This Marin dialogue was inspired by The Witness's audiologs. -You're awake!\n....\nYou were warned.\nI'm now going to say every word beginning with Z!\nZA\nZABAGLIONE\nZABAGLIONES\nZABAIONE\nZABAIONES\nZABAJONE\nZABAJONES\nZABETA\nZABETAS\nZABRA\nZABRAS\nZABTIEH\nZABTIEHS\nZACATON\nZACATONS\nZACK\nZACKS\nZADDICK\nZADDIK\nZADDIKIM\nZADDIKS\nZAFFAR\nzAFFARS\nZAFFER\nZAFFERS\nZAFFIR\n....\n....\n....\nI'll let you off easy.\nThis time. Leave me alone, I'm Marinating. praise be to the tungsten cube If you play multiple seeds in a row, you can pretend that each run is the dream you awaken from in the next. From e342a20fde278f58c0655a976c86fdd7433a9717 Mon Sep 17 00:00:00 2001 From: PoryGone <98504756+PoryGone@users.noreply.github.com> Date: Wed, 3 Sep 2025 21:50:59 -0400 Subject: [PATCH 0693/1218] Celeste (Open World): Post-merge Logic Fix (#5415) * APWorld Skeleton * Hair Color Rando and first items * All interactable items * Checkpoint Items and Locations * First pass sample intermediate data * Bulk of Region/location code * JSON Data Parser * New items and Level Item mapping * Data Parsing fixes and most of 1a data * 1a complete data and region/location/item creation fixes * Add Key Location type and ID output * Add options to slot data * 1B Level Data * Added Location logging * Add Goal Area Options * 1c Level Data * Old Site A B C level data * Key/Binosanity and Hair Length options * Key Item/Location and Clutter Event handling * Remove generic 'keys' item * 3a level data * 3b and 3c level data * Chapter 4 level data * Chapter 5 Logic Data * Chapter 5 level data * Trap Support * Add TrapLink Support * Chapter 6 A/B/C Level Data * Add active_levels to slot_data * Item and Location Name Groups + style cleanups * Chapter 7 Level Data and Items, Gemsanity option * Goal Area and victory handling * Fix slot_data * Add Core Level Data * Carsanity * Farewell Level Data and ID Range Update * Farewell level data and handling * Music Shuffle * Require Cassettes * Change default trap expiration action to Deaths * Handle Poetry * Mod versioning * Rename folder, general cleanup * Additional Cleanup * Handle Farewell Golden Goal when Include Goldens is off * Better handling of Farewell Golden * Update Docs * Beta test bug fixes * Bump to v1.0.0 * Update Changelog * Several Logic tweaks * Update APWorld Version * Add Celeste (Open World) to README * Peer review changes * Logic Fixes: * Adjust Mirror Temple B Key logic * Increment APWorld version * Fix several logic bugs * Add missing link * Add Item Name Groups for common alternative item names * Account for Madeline's post-Celeste hair-dying activities * Account for ignored member variable and hardcoded color in Celeste codebase * Add Blue Clouds to the logic of reaching Farewell - intro-02-launch * Type checking workaround * Bump version number * Adjust Setup Guide * Minor typing fixes * Logic and PR fixes * Increment APWorld Version * Use more world helpers * Core review * CODEOWNERS * Minor logic fix and insert APWorld version into spoiler * Fix merge error --- worlds/celeste_open_world/__init__.py | 12 +++++++++++- worlds/celeste_open_world/data/CelesteLevelData.json | 8 ++++---- worlds/celeste_open_world/data/CelesteLevelData.py | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/worlds/celeste_open_world/__init__.py b/worlds/celeste_open_world/__init__.py index 38c3778e831c..c0661b559359 100644 --- a/worlds/celeste_open_world/__init__.py +++ b/worlds/celeste_open_world/__init__.py @@ -1,5 +1,6 @@ from copy import deepcopy import math +from typing import TextIO from BaseClasses import ItemClassification, Location, MultiWorld, Region, Tutorial from Utils import visualize_regions @@ -41,6 +42,8 @@ class CelesteOpenWorld(World): options_dataclass = CelesteOptions options: CelesteOptions + apworld_version = 10005 + level_data: dict[str, Level] = load_logic_data() location_name_to_id: dict[str, int] = location_data_table @@ -251,7 +254,7 @@ def set_rules(self) -> None: def fill_slot_data(self): return { - "apworld_version": 10004, + "apworld_version": self.apworld_version, "min_mod_version": 10000, "death_link": self.options.death_link.value, @@ -292,6 +295,13 @@ def fill_slot_data(self): "chosen_poem": self.random.randint(0, 119), } + @classmethod + def stage_write_spoiler_header(cls, multiworld: MultiWorld, spoiler_handle: TextIO): + major: int = cls.apworld_version // 10000 + minor: int = (cls.apworld_version % 10000) // 100 + bugfix: int = (cls.apworld_version % 100) + spoiler_handle.write(f"\nCeleste (Open World) APWorld v{major}.{minor}.{bugfix}\n") + def output_active_traps(self) -> dict[int, int]: trap_data = {} diff --git a/worlds/celeste_open_world/data/CelesteLevelData.json b/worlds/celeste_open_world/data/CelesteLevelData.json index 5b4edd9b88b4..9d636960452c 100644 --- a/worlds/celeste_open_world/data/CelesteLevelData.json +++ b/worlds/celeste_open_world/data/CelesteLevelData.json @@ -37055,6 +37055,10 @@ { "dest": "north-west", "rule": [ [ "double_dash_refills", "springs", "dash_switches" ] ] + }, + { + "dest": "south-east-door", + "rule": [] } ] }, @@ -37082,10 +37086,6 @@ "dest": "north-east-door", "rule": [] }, - { - "dest": "south-east-door", - "rule": [] - }, { "dest": "south-west-door", "rule": [] diff --git a/worlds/celeste_open_world/data/CelesteLevelData.py b/worlds/celeste_open_world/data/CelesteLevelData.py index f4c492dd4f8e..6ba43fc34d85 100644 --- a/worlds/celeste_open_world/data/CelesteLevelData.py +++ b/worlds/celeste_open_world/data/CelesteLevelData.py @@ -4771,11 +4771,11 @@ "10a_d-00_north---10a_d-00_south": RegionConnection("10a_d-00_north", "10a_d-00_south", [["Farewell - Power Source Key 5", ], ]), "10a_d-00_south-east---10a_d-00_south": RegionConnection("10a_d-00_south-east", "10a_d-00_south", [[ItemName.double_dash_refills, ItemName.dash_switches, ], ]), "10a_d-00_south-east---10a_d-00_north-west": RegionConnection("10a_d-00_south-east", "10a_d-00_north-west", [[ItemName.double_dash_refills, ItemName.springs, ItemName.dash_switches, ], ]), + "10a_d-00_south-east---10a_d-00_south-east-door": RegionConnection("10a_d-00_south-east", "10a_d-00_south-east-door", []), "10a_d-00_north-west---10a_d-00_south": RegionConnection("10a_d-00_north-west", "10a_d-00_south", [[ItemName.jellyfish, ItemName.dash_switches, ], ]), "10a_d-00_north-west---10a_d-00_breaker": RegionConnection("10a_d-00_north-west", "10a_d-00_breaker", [[ItemName.jellyfish, ItemName.springs, ItemName.dash_switches, ItemName.breaker_boxes, ], ]), "10a_d-00_breaker---10a_d-00_south": RegionConnection("10a_d-00_breaker", "10a_d-00_south", []), "10a_d-00_breaker---10a_d-00_north-east-door": RegionConnection("10a_d-00_breaker", "10a_d-00_north-east-door", []), - "10a_d-00_breaker---10a_d-00_south-east-door": RegionConnection("10a_d-00_breaker", "10a_d-00_south-east-door", []), "10a_d-00_breaker---10a_d-00_south-west-door": RegionConnection("10a_d-00_breaker", "10a_d-00_south-west-door", []), "10a_d-00_breaker---10a_d-00_west-door": RegionConnection("10a_d-00_breaker", "10a_d-00_west-door", []), "10a_d-00_breaker---10a_d-00_north-west-door": RegionConnection("10a_d-00_breaker", "10a_d-00_north-west-door", []), From 03992c43d981a3ec5d276a586f76d87766f2e328 Mon Sep 17 00:00:00 2001 From: qwint Date: Thu, 4 Sep 2025 09:58:24 -0500 Subject: [PATCH 0694/1218] Docs: update mac install instructions to reflect 3.13 support (#5411) --- worlds/generic/docs/mac_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/generic/docs/mac_en.md b/worlds/generic/docs/mac_en.md index 72f7d1a8b58b..b06593f5011d 100644 --- a/worlds/generic/docs/mac_en.md +++ b/worlds/generic/docs/mac_en.md @@ -3,7 +3,7 @@ Archipelago does not have a compiled release on macOS. However, it is possible t ## Prerequisite Software Here is a list of software to install and source code to download. 1. Python 3.11 "universal2" or newer from the [macOS Python downloads page](https://www.python.org/downloads/macos/). - **Python 3.13 is not supported yet.** + **Python 3.14 is not supported yet.** 2. Xcode from the [macOS App Store](https://apps.apple.com/us/app/xcode/id497799835). 3. The source code from the [Archipelago releases page](https://github.com/ArchipelagoMW/Archipelago/releases). 4. The asset with darwin in the name from the [SNI Github releases page](https://github.com/alttpo/sni/releases). From 42ace29db46f0fed3e2557ea77e84954d28c6042 Mon Sep 17 00:00:00 2001 From: PoryGone <98504756+PoryGone@users.noreply.github.com> Date: Thu, 4 Sep 2025 15:53:55 -0400 Subject: [PATCH 0695/1218] Celeste 64: Logic Fixes #5417 --- worlds/celeste64/Locations.py | 2 +- worlds/celeste64/Rules.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/worlds/celeste64/Locations.py b/worlds/celeste64/Locations.py index 9e202eca1203..ed4521ec1044 100644 --- a/worlds/celeste64/Locations.py +++ b/worlds/celeste64/Locations.py @@ -27,7 +27,7 @@ class Celeste64LocationData(NamedTuple): LocationName.strawberry_8: Celeste64LocationData(RegionName.nw_girders_island, celeste_64_base_id + 0x07), LocationName.strawberry_9: Celeste64LocationData(RegionName.granny_island, celeste_64_base_id + 0x08), LocationName.strawberry_10: Celeste64LocationData(RegionName.granny_island, celeste_64_base_id + 0x09), - LocationName.strawberry_11: Celeste64LocationData(RegionName.granny_island, celeste_64_base_id + 0x0A), + LocationName.strawberry_11: Celeste64LocationData(RegionName.highway_island, celeste_64_base_id + 0x0A), LocationName.strawberry_12: Celeste64LocationData(RegionName.badeline_tower_lower, celeste_64_base_id + 0x0B), LocationName.strawberry_13: Celeste64LocationData(RegionName.highway_island, celeste_64_base_id + 0x0C), LocationName.strawberry_14: Celeste64LocationData(RegionName.ne_feathers_island, celeste_64_base_id + 0x0D), diff --git a/worlds/celeste64/Rules.py b/worlds/celeste64/Rules.py index 3365a7cf9551..732e643b4b2d 100644 --- a/worlds/celeste64/Rules.py +++ b/worlds/celeste64/Rules.py @@ -82,12 +82,10 @@ def set_rules(world: Celeste64World): [ItemName.double_dash_refill, ItemName.air_dash]], LocationName.strawberry_15: [[ItemName.feather], [ItemName.ground_dash, ItemName.air_dash]], - LocationName.strawberry_17: [[ItemName.double_dash_refill, ItemName.traffic_block]], + LocationName.strawberry_17: [[ItemName.double_dash_refill]], LocationName.strawberry_18: [[ItemName.air_dash, ItemName.climb], [ItemName.double_dash_refill, ItemName.air_dash]], - LocationName.strawberry_19: [[ItemName.air_dash, ItemName.skid_jump], - [ItemName.double_dash_refill, ItemName.spring, ItemName.air_dash], - [ItemName.spring, ItemName.ground_dash, ItemName.air_dash]], + LocationName.strawberry_19: [[ItemName.air_dash]], LocationName.strawberry_20: [[ItemName.breakables, ItemName.air_dash]], LocationName.strawberry_21: [[ItemName.cassette, ItemName.traffic_block, ItemName.breakables, ItemName.air_dash]], From b0b3e3668f08d69ab909f0af50a7b0816c6e9cdf Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Thu, 4 Sep 2025 18:44:32 -0400 Subject: [PATCH 0696/1218] TUNIC: The Big Refactor (#5195) * Make it actually return false if it gets to the backup lists and fails them * Fix stuff after merge * Add outlet regions, create new regions as needed for them * Put together part of decoupled and direction pairs * make direction pairs work * Make decoupled work * Make fixed shop work again * Fix a few minor bugs * Fix a few minor bugs * Fix plando * god i love programming * Reorder portal list * Update portal sorter for variable shops * Add missing parameter * Some cleanup of prints and functions * Fix typo * it's aliiiiiive * Make seed groups not sync decoupled * Add test with full-shop plando * Fix bug with vanilla portals * Handle plando connections and direction pair errors * Update plando checking for decoupled * Fix typo * Fix exception text to be shorter * Add some more comments * Add todo note * Remove unused safety thing * Remove extra plando connections definition in options * Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log * Fix weird edge case that is technically user error * Add note to fixed shop * Fix parsing shop names in UT * Remove debug print * Actually make UT work * multiworld. to world. * Fix typo from merge * Make it so the shops show up in the entrance hints * Fix bug in ladder storage rules * Remove blank line * # Conflicts: # worlds/tunic/__init__.py # worlds/tunic/er_data.py # worlds/tunic/er_rules.py # worlds/tunic/er_scripts.py # worlds/tunic/rules.py # worlds/tunic/test/test_access.py * Fix issues after merge * Update plando connections stuff in docs * Make early bushes only contain grass * Fix library mistake * Backport changes to grass rando (#20) * Backport changes to grass rando * add_rule instead of set_rule for the special cases, add special cases for back of swamp laurels area cause I should've made a new region for the swamp upper entrance * Remove item name group for grass * Update grass rando option descriptions - Also ignore grass fill for single player games * Ignore grass fill option for solo rando * Update er_rules.py * Fix pre fill issue * Remove duplicate option * Add excluded grass locations back * Hide grass fill option from simple ui options page * Check for start with sword before setting grass rules * Update worlds/tunic/options.py Co-authored-by: Scipio Wright * has_stick -> has_melee * has_stick -> has_melee * Add a failsafe for direction pairing * Fix playthrough crash bug * Remove init from logicmixin * Updates per code review (thanks hesto) * has_stick to has_melee in newer update * has_stick to has_melee in newer update * Exclude grass from get_filler_item_name - non-grass rando games were accidentally seeing grass items get shuffled in as filler, which is funny but probably shouldn't happen * Update worlds/tunic/__init__.py Co-authored-by: Scipio Wright * Apply suggestions from code review Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: Scipio Wright * change the rest of grass_fill to local_fill * Filter out grass from filler_items * remove -> discard * Update worlds/tunic/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Starting out * Rules for breakable regions * # Conflicts: # worlds/tunic/__init__.py # worlds/tunic/combat_logic.py # worlds/tunic/er_data.py # worlds/tunic/er_rules.py # worlds/tunic/er_scripts.py * Cleanup more stuff after merge * Revert "Cleanup more stuff after merge" This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d. * Revert "# Conflicts:" This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30. * Cleanup more stuff after merge * change has_stick to has_melee * Update grass list with combat logic regions * More fixes from combat logic merge * Fix some dumb stuff (#21) * Reorganize pre fill for grass * make the rest of it work, it's pr ready, boom * Make it work in not pot shuffle * Merge grass rando * multiworld -> world get_location, use has_any * Swap out region for West Garden Before Terry grass * Adjust west garden rules to add west combat region * Adjust grass regions for south checkpoint grass * Adjust grass regions for after terry grass * Adjust grass regions for west combat grass * Adjust grass regions for dagger house grass * Adjust grass regions for south checkpoint grass, adjust regions and rules for some related locations * Finish the remainder of the west garden grass, reformat ruined atoll a little * More hex quest updates - Implement page ability shuffle for hex quest - Fix keys behind bosses if hex goal is less than 3 - Added check to fix conflicting hex quest options - Add option to slot data * Change option comparison * Change option checking and fix some stuff - also keep prayer first on low hex counts * Update option defaulting * Update option checking * Fix option assignment again * Merge in hex hunt * Merge in changes * Clean up imports * Add ability type to UT stuff * merge it all * Make local fill work across pot and grass (to be adjusted later) * Make separate pools for the grass and non-grass fills * Fix id overlap * Update option description * Fix default * Reorder localfill option desc * Load the purgatory ones in * Adjustments after merge * Fully remove logicrules * Fix UT support with fixed shop option * Add breakable shuffle to the ut stuff * Make it load in a specific number of locations * Add Silent's spoiler log ability thing * Fix for groups * Fix for groups * Fix typo * Fix hex quest UT support * Use .get * UT fixes, classification fixes * Rename some locations * Adjust guard house names * Adjust guard house names * Rework create_item * Fix for plando connections * Rename, add new breakables * Rename more stuff * Time to rename them again * Fix issue with fixed shop + decoupled * Put in an exception to catch that error in the future * Update create_item to match main * Update spoiler log lines for hex abilities * Burn the signs down * Bring over the combat logic fix * Merge in combat logic fix * Silly static method thing * Move a few areas to before well instead of east forest * Add an all_random hidden option for dev stuff * Port over changes from main * Fix west courtyard pot regions * Remove debug prints * Fix fortress courtyard and beneath the fortress loc groups again * Add exception handling to deal with duplicate apworlds * Fix typo * More missing loc group conversions * Initial fuse shuffle stuff * Fix gun missing from combat_items, add new for combat logic cache, very slight refactor of check_combat_reqs to let it do the changeover in a less complicated fashion, fix area being a boss area rather than non-boss area for a check * Add fuse shuffle logic * reorder atoll statue rule * Update traversal reqs * Remove fuse shuffle from temple door * Combine rules and option checking * Add bell shuffle; fix fuse location groups * Fix portal rules not requiring prayer * Merge the grass laurels exit grass PR * Merge in fortress bridge PR * Do a little clean up * Fix a regression * Update after merge * Some more stuff * More Silent changes * Update more info section in game info page * Fix rules for atoll and swamp fuses * Precollect cathedral fuse in ER * actually just make the fuse useful instead of progression * Add it to the swamp and cath rules too * Fix cath fuse name * Minor fixes and edits * Some UT stuff * Fix a couple more groups * Move a bunch of UT stuff to its own file * Fix up a couple UT things * Couple minor ER fixes * Formatting change * UT poptracker stuff enabled since it's optional in one of the releases * Add author string to world class * Adjust local fill option name * Update ut_stuff to match the PR * Add exception handling for UT with old apworld * Fix missing tracker_world * Remove extra entrance from cath main -> elevator Entry <-> Elev exists, Entry <-> Main exists So no connection is needed between Main and Elev * Fix so that decoupled doesn't incorrectly use get_portal_info and get_paired_portal * Fix so that decoupled doesn't incorrectly use get_portal_info and get_paired_portal * Update for breakables poptracker * Backup and warnings instead * Update typing * Delete old regions and rules, move stuff to logic_helpers and constants * Delete now much less useful tests * Fix breakables map tracking * Add more comments to init * Add todo to grass.py * Fix up tests * Pull out fuse and bell shuffle * Pull out fuse and bell shuffle * Update worlds/tunic/options.py Co-authored-by: qwint * Update worlds/tunic/logic_helpers.py Co-authored-by: qwint * {} -> () in state functions * {} -> () in state functions * Change {} -> () in state functions, use constant for gun * Remove floating constants in er_data * Finish hard deprecating FixedShop * Finish hard deprecating FixedShop * Fix zig skip showing up in decoupled fixed shop --------- Co-authored-by: silent-destroyer Co-authored-by: Silent <110704408+silent-destroyer@users.noreply.github.com> Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: qwint --- worlds/tunic/__init__.py | 243 ++++++++++------- worlds/tunic/breakables.py | 19 +- worlds/tunic/combat_logic.py | 46 ++-- worlds/tunic/constants.py | 51 ++++ worlds/tunic/er_data.py | 48 ++-- worlds/tunic/er_rules.py | 397 ++++++++++++++------------- worlds/tunic/er_scripts.py | 122 ++++++--- worlds/tunic/fuses.py | 30 +++ worlds/tunic/grass.py | 20 +- worlds/tunic/items.py | 23 +- worlds/tunic/ladder_storage_data.py | 20 +- worlds/tunic/locations.py | 26 +- worlds/tunic/logic_helpers.py | 98 +++++++ worlds/tunic/options.py | 76 ++---- worlds/tunic/regions.py | 25 -- worlds/tunic/rules.py | 402 ---------------------------- worlds/tunic/test/test_access.py | 21 +- 17 files changed, 749 insertions(+), 918 deletions(-) create mode 100644 worlds/tunic/constants.py create mode 100644 worlds/tunic/fuses.py create mode 100644 worlds/tunic/logic_helpers.py delete mode 100644 worlds/tunic/regions.py delete mode 100644 worlds/tunic/rules.py diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 84f1338ad5e3..db0357daaf27 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -1,25 +1,28 @@ from dataclasses import fields -from typing import Dict, List, Any, Tuple, TypedDict, ClassVar, Union, Set, TextIO from logging import warning -from BaseClasses import Region, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState -from .items import (item_name_to_id, item_table, item_name_groups, fool_tiers, filler_items, slot_data_item_names, - combat_items) -from .locations import location_table, location_name_groups, standard_location_name_to_id, hexagon_locations -from .rules import set_location_rules, set_region_rules, randomize_ability_unlocks, gold_hexagon +from typing import Any, TypedDict, ClassVar, TextIO + +from BaseClasses import Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState +from Options import PlandoConnection, OptionError, PerGameCommonOptions, Range, Removed +from settings import Group, Bool, FilePath +from worlds.AutoWorld import WebWorld, World + +# from .bells import bell_location_groups, bell_location_name_to_id +from .breakables import breakable_location_name_to_id, breakable_location_groups, breakable_location_table +from .combat_logic import area_data, CombatState +from .er_data import portal_mapping, RegionInfo, tunic_er_regions from .er_rules import set_er_location_rules -from .regions import tunic_regions from .er_scripts import create_er_regions, verify_plando_directions +# from .fuses import fuse_location_name_to_id, fuse_location_groups from .grass import grass_location_table, grass_location_name_to_id, grass_location_name_groups, excluded_grass_locations -from .er_data import portal_mapping, RegionInfo, tunic_er_regions +from .items import (item_name_to_id, item_table, item_name_groups, fool_tiers, filler_items, slot_data_item_names, + combat_items) +from .locations import location_table, location_name_groups, standard_location_name_to_id, hexagon_locations +from .logic_helpers import randomize_ability_unlocks, gold_hexagon from .options import (TunicOptions, EntranceRando, tunic_option_groups, tunic_option_presets, TunicPlandoConnections, - LaurelsLocation, LogicRules, LaurelsZips, IceGrappling, LadderStorage, check_options, - get_hexagons_in_pool, HexagonQuestAbilityUnlockType, EntranceLayout) -from .breakables import breakable_location_name_to_id, breakable_location_groups, breakable_location_table -from .combat_logic import area_data, CombatState + LaurelsLocation, LaurelsZips, IceGrappling, LadderStorage, EntranceLayout, + check_options, LocalFill, get_hexagons_in_pool, HexagonQuestAbilityUnlockType) from . import ut_stuff -from worlds.AutoWorld import WebWorld, World -from Options import PlandoConnection, OptionError, PerGameCommonOptions, Removed, Range -from settings import Group, Bool, FilePath class TunicSettings(Group): @@ -28,15 +31,15 @@ class DisableLocalSpoiler(Bool): class LimitGrassRando(Bool): """Limits the impact of Grass Randomizer on the multiworld by disallowing local_fill percentages below 95.""" - + class UTPoptrackerPath(FilePath): """Path to the user's TUNIC Poptracker Pack.""" description = "TUNIC Poptracker Pack zip file" required = False - disable_local_spoiler: Union[DisableLocalSpoiler, bool] = False - limit_grass_rando: Union[LimitGrassRando, bool] = True - ut_poptracker_path: Union[UTPoptrackerPath, str] = UTPoptrackerPath() + disable_local_spoiler: DisableLocalSpoiler | bool = False + limit_grass_rando: LimitGrassRando | bool = True + ut_poptracker_path: UTPoptrackerPath | str = UTPoptrackerPath() class TunicWeb(WebWorld): @@ -68,10 +71,10 @@ class SeedGroup(TypedDict): laurels_zips: bool # laurels_zips value ice_grappling: int # ice_grappling value ladder_storage: int # ls value - laurels_at_10_fairies: bool # laurels location value + laurels_at_10_fairies: bool # whether laurels location is set to 10 fairies entrance_layout: int # entrance layout value has_decoupled_enabled: bool # for checking that players don't have conflicting options - plando: List[PlandoConnection] # consolidated plando connections for the seed group + plando: list[PlandoConnection] # consolidated plando connections for the seed group class TunicWorld(World): @@ -82,54 +85,66 @@ class TunicWorld(World): """ game = "TUNIC" web = TunicWeb() + author: str = "SilentSR & ScipioWright" options: TunicOptions options_dataclass = TunicOptions settings: ClassVar[TunicSettings] item_name_groups = item_name_groups + # grass, breakables, fuses, and bells are separated out into their own files + # this makes for easier organization, at the cost of stuff like what's directly below here location_name_groups = location_name_groups for group_name, members in grass_location_name_groups.items(): location_name_groups.setdefault(group_name, set()).update(members) for group_name, members in breakable_location_groups.items(): location_name_groups.setdefault(group_name, set()).update(members) + # for group_name, members in fuse_location_groups.items(): + # location_name_groups.setdefault(group_name, set()).update(members) + # for group_name, members in bell_location_groups.items(): + # location_name_groups.setdefault(group_name, set()).update(members) item_name_to_id = item_name_to_id location_name_to_id = standard_location_name_to_id.copy() location_name_to_id.update(grass_location_name_to_id) location_name_to_id.update(breakable_location_name_to_id) - - player_location_table: Dict[str, int] - ability_unlocks: Dict[str, int] - slot_data_items: List[TunicItem] - tunic_portal_pairs: Dict[str, str] - er_portal_hints: Dict[int, str] - seed_groups: Dict[str, SeedGroup] = {} - used_shop_numbers: Set[int] - er_regions: Dict[str, RegionInfo] # absolutely needed so outlet regions work + # location_name_to_id.update(fuse_location_name_to_id) + # location_name_to_id.update(bell_location_name_to_id) + + player_location_table: dict[str, int] + ability_unlocks: dict[str, int] + slot_data_items: list[TunicItem] + tunic_portal_pairs: dict[str, str] + er_portal_hints: dict[int, str] + seed_groups: dict[str, SeedGroup] = {} + used_shop_numbers: set[int] + er_regions: dict[str, RegionInfo] # absolutely needed so outlet regions work # for the local_fill option - fill_items: List[TunicItem] - fill_locations: List[Location] + fill_items: list[TunicItem] + fill_locations: list[Location] + backup_locations: list[Location] amount_to_local_fill: int # so we only loop the multiworld locations once # if these are locations instead of their info, it gives a memory leak error - item_link_locations: Dict[int, Dict[str, List[Tuple[int, str]]]] = {} - player_item_link_locations: Dict[str, List[Location]] + item_link_locations: dict[int, dict[str, list[tuple[int, str]]]] = {} + player_item_link_locations: dict[str, list[Location]] using_ut: bool # so we can check if we're using UT only once - passthrough: Dict[str, Any] + passthrough: dict[str, Any] ut_can_gen_without_yaml = True # class var that tells it to ignore the player yaml tracker_world: ClassVar = ut_stuff.tracker_world def generate_early(self) -> None: + # if you have multiple APWorlds, we want it to fail here instead of at the end of gen try: int(self.settings.disable_local_spoiler) except AttributeError: raise Exception("You have a TUNIC APWorld in your lib/worlds folder and custom_worlds folder.\n" "This would cause an error at the end of generation.\n" "Please remove one of them, most likely the one in lib/worlds.") - + + # hidden option for me to do multi-slot test gens with random options more easily if self.options.all_random: for option_name in (attr.name for attr in fields(TunicOptions) if attr not in fields(PerGameCommonOptions)): @@ -145,10 +160,11 @@ def generate_early(self) -> None: option.value = self.random.choice(list(option.name_lookup)) check_options(self) - self.er_regions = tunic_er_regions.copy() + # empty plando connections if ER is off if self.options.plando_connections and not self.options.entrance_rando: self.options.plando_connections.value = () + # modify direction and order of plando connections for more consistency later on if self.options.plando_connections: def replace_connection(old_cxn: PlandoConnection, new_cxn: PlandoConnection, index: int) -> None: self.options.plando_connections.value.remove(old_cxn) @@ -180,6 +196,7 @@ def replace_connection(old_cxn: PlandoConnection, new_cxn: PlandoConnection, ind self.player_location_table = standard_location_name_to_id.copy() + # setup our defaults for the local_fill option if self.options.local_fill == -1: if self.options.grass_randomizer: if self.options.breakable_shuffle: @@ -206,9 +223,15 @@ def replace_connection(old_cxn: PlandoConnection, new_cxn: PlandoConnection, ind self.player_location_table.update({name: num for name, num in breakable_location_name_to_id.items() if not name.startswith("Purgatory")}) + # if self.options.shuffle_fuses: + # self.player_location_table.update(fuse_location_name_to_id) + # + # if self.options.shuffle_bells: + # self.player_location_table.update(bell_location_name_to_id) + @classmethod def stage_generate_early(cls, multiworld: MultiWorld) -> None: - tunic_worlds: Tuple[TunicWorld] = multiworld.get_game_worlds("TUNIC") + tunic_worlds: tuple[TunicWorld] = multiworld.get_game_worlds("TUNIC") for tunic in tunic_worlds: # setting up state combat logic stuff, see has_combat_reqs for its use # and this is magic so pycharm doesn't like it, unfortunately @@ -314,10 +337,10 @@ def create_item(self, name: str, classification: ItemClassification = None) -> T return TunicItem(name, itemclass, self.item_name_to_id[name], self.player) def create_items(self) -> None: - tunic_items: List[TunicItem] = [] + tunic_items: list[TunicItem] = [] self.slot_data_items = [] - items_to_create: Dict[str, int] = {item: data.quantity_in_item_pool for item, data in item_table.items()} + items_to_create: dict[str, int] = {item: data.quantity_in_item_pool for item, data in item_table.items()} # Calculate number of hexagons in item pool if self.options.hexagon_quest: @@ -377,7 +400,7 @@ def create_items(self) -> None: items_to_create[rgb_hexagon] = 0 # Filler items in the item pool - available_filler: List[str] = [filler for filler in items_to_create if items_to_create[filler] > 0 and + available_filler: list[str] = [filler for filler in items_to_create if items_to_create[filler] > 0 and item_table[filler].classification == ItemClassification.filler] # Remove filler to make room for other items @@ -457,8 +480,8 @@ def remove_filler(amount: int) -> None: # discard grass from non_local if it's meant to be limited if self.settings.limit_grass_rando: self.options.non_local_items.value.discard("Grass") - all_filler: List[TunicItem] = [] - non_filler: List[TunicItem] = [] + all_filler: list[TunicItem] = [] + non_filler: list[TunicItem] = [] for tunic_item in tunic_items: if (tunic_item.excludable and tunic_item.name not in self.options.local_items @@ -477,7 +500,7 @@ def pre_fill(self) -> None: if self.options.local_fill > 0 and self.multiworld.players > 1: # we need to reserve a couple locations so that we don't fill up every sphere 1 location sphere_one_locs = self.multiworld.get_reachable_locations(CollectionState(self.multiworld), self.player) - reserved_locations: Set[Location] = set(self.random.sample(sphere_one_locs, 2)) + reserved_locations: set[Location] = set(self.random.sample(sphere_one_locs, 2)) viable_locations = [loc for loc in self.multiworld.get_unfilled_locations(self.player) if loc not in reserved_locations and loc.name not in self.options.priority_locations.value] @@ -487,34 +510,91 @@ def pre_fill(self) -> None: f"This is likely due to excess plando or priority locations.") self.random.shuffle(viable_locations) self.fill_locations = viable_locations[:self.amount_to_local_fill] + self.backup_locations = viable_locations[self.amount_to_local_fill:] @classmethod def stage_pre_fill(cls, multiworld: MultiWorld) -> None: - tunic_fill_worlds: List[TunicWorld] = [world for world in multiworld.get_game_worlds("TUNIC") + tunic_fill_worlds: list[TunicWorld] = [world for world in multiworld.get_game_worlds("TUNIC") if world.options.local_fill.value > 0] if tunic_fill_worlds and multiworld.players > 1: - grass_fill: List[TunicItem] = [] - non_grass_fill: List[TunicItem] = [] - grass_fill_locations: List[Location] = [] - non_grass_fill_locations: List[Location] = [] + grass_fill: list[TunicItem] = [] + non_grass_fill: list[TunicItem] = [] + grass_fill_locations: list[Location] = [] + non_grass_fill_locations: list[Location] = [] + backup_grass_locations: list[Location] = [] + backup_non_grass_locations: list[Location] = [] for world in tunic_fill_worlds: if world.options.grass_randomizer: grass_fill.extend(world.fill_items) grass_fill_locations.extend(world.fill_locations) + backup_grass_locations.extend(world.backup_locations) else: non_grass_fill.extend(world.fill_items) non_grass_fill_locations.extend(world.fill_locations) + backup_non_grass_locations.extend(world.backup_locations) multiworld.random.shuffle(grass_fill) multiworld.random.shuffle(non_grass_fill) multiworld.random.shuffle(grass_fill_locations) multiworld.random.shuffle(non_grass_fill_locations) + multiworld.random.shuffle(backup_grass_locations) + multiworld.random.shuffle(backup_non_grass_locations) + + # these are slots that filled in TUNIC locations during pre_fill + out_of_spec_worlds = set() for filler_item in grass_fill: - grass_fill_locations.pop().place_locked_item(filler_item) + loc_to_fill = grass_fill_locations.pop() + try: + loc_to_fill.place_locked_item(filler_item) + except Exception: + out_of_spec_worlds.add(multiworld.worlds[loc_to_fill.item.player].game) + for loc in backup_grass_locations: + if not loc.item: + loc.place_locked_item(filler_item) + break + else: + out_of_spec_worlds.add(multiworld.worlds[loc_to_fill.item.player].game) + else: + raise Exception("TUNIC: Could not fulfill local_filler option. This issue is caused by another " + "world filling TUNIC locations during pre_fill.\n" + "Archipelago does not allow us to place items into the item pool after " + "create_items, so we cannot recover from this issue.\n" + f"This is likely caused by the following world(s): {out_of_spec_worlds}.\n" + f"Please let the world dev(s) for the listed world(s) know that there is an " + f"issue there.\n" + "As a workaround, you can try setting the local_filler option lower for " + "TUNIC slots with Breakable Shuffle or Grass Rando enabled. You may be able to " + "try generating again, as it may not happen every generation.") for filler_item in non_grass_fill: - non_grass_fill_locations.pop().place_locked_item(filler_item) + loc_to_fill = non_grass_fill_locations.pop() + try: + loc_to_fill.place_locked_item(filler_item) + except Exception: + out_of_spec_worlds.add(multiworld.worlds[loc_to_fill.item.player].game) + for loc in backup_non_grass_locations: + if not loc.item: + loc.place_locked_item(filler_item) + break + else: + out_of_spec_worlds.add(multiworld.worlds[loc_to_fill.item.player].game) + else: + raise Exception("TUNIC: Could not fulfill local_filler option. This issue is caused by another " + "world filling TUNIC locations during pre_fill.\n" + "Archipelago does not allow us to place items into the item pool after " + "create_items, so we cannot recover from this issue.\n" + f"This is likely caused by the following world(s): {out_of_spec_worlds}.\n" + f"Please let the world dev(s) for the listed world(s) know that there is an " + f"issue there.\n" + "As a workaround, you can try setting the local_filler option lower for " + "TUNIC slots with Breakable Shuffle or Grass Rando enabled. You may be able to " + "try generating again, as it may not happen every generation.") + if out_of_spec_worlds: + warning("TUNIC: At least one other world has filled TUNIC locations during pre_fill. This may " + "cause issues for games that rely on placing items in their own world during pre_fill.\n" + f"This is likely being caused by the following world(s): {out_of_spec_worlds}.\n" + "Please let the world dev(s) for the listed world(s) know that there is an issue there.") def create_regions(self) -> None: self.tunic_portal_pairs = {} @@ -522,48 +602,19 @@ def create_regions(self) -> None: self.ability_unlocks = randomize_ability_unlocks(self) # stuff for universal tracker support, can be ignored for standard gen - if self.using_ut: + if self.using_ut and self.options.hexagon_quest_ability_type == "hexagons": self.ability_unlocks["Pages 24-25 (Prayer)"] = self.passthrough["Hexagon Quest Prayer"] self.ability_unlocks["Pages 42-43 (Holy Cross)"] = self.passthrough["Hexagon Quest Holy Cross"] self.ability_unlocks["Pages 52-53 (Icebolt)"] = self.passthrough["Hexagon Quest Icebolt"] - # Most non-standard options use ER regions - if (self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic - or self.options.grass_randomizer or self.options.breakable_shuffle): - portal_pairs = create_er_regions(self) - if self.options.entrance_rando: - # these get interpreted by the game to tell it which entrances to connect - for portal1, portal2 in portal_pairs.items(): - self.tunic_portal_pairs[portal1.scene_destination()] = portal2.scene_destination() - else: - # uses the original rules, easier to navigate and reference - for region_name in tunic_regions: - region = Region(region_name, self.player, self.multiworld) - self.multiworld.regions.append(region) - - for region_name, exits in tunic_regions.items(): - region = self.get_region(region_name) - region.add_exits(exits) - - for location_name, location_id in self.player_location_table.items(): - region = self.get_region(location_table[location_name].region) - location = TunicLocation(self.player, location_name, location_id, region) - region.locations.append(location) - - victory_region = self.get_region("Spirit Arena") - victory_location = TunicLocation(self.player, "The Heir", None, victory_region) - victory_location.place_locked_item(TunicItem("Victory", ItemClassification.progression, None, self.player)) - self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) - victory_region.locations.append(victory_location) + portal_pairs = create_er_regions(self) + if self.options.entrance_rando: + # these get interpreted by the game to tell it which entrances to connect + for portal1, portal2 in portal_pairs.items(): + self.tunic_portal_pairs[portal1.scene_destination()] = portal2.scene_destination() def set_rules(self) -> None: - # same reason as in create_regions - if (self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic - or self.options.grass_randomizer or self.options.breakable_shuffle): - set_er_location_rules(self) - else: - set_region_rules(self) - set_location_rules(self) + set_er_location_rules(self) def get_filler_item_name(self) -> str: return self.random.choice(filler_items) @@ -582,14 +633,14 @@ def remove(self, state: CollectionState, item: Item) -> bool: return change def write_spoiler_header(self, spoiler_handle: TextIO): - if self.options.hexagon_quest and self.options.ability_shuffling\ - and self.options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: + if (self.options.hexagon_quest and self.options.ability_shuffling + and self.options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons): spoiler_handle.write("\nAbility Unlocks (Hexagon Quest):\n") for ability in self.ability_unlocks: # Remove parentheses for better readability spoiler_handle.write(f'{ability[ability.find("(")+1:ability.find(")")]}: {self.ability_unlocks[ability]} Gold Questagons\n') - def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]) -> None: + def extend_hint_information(self, hint_data: dict[int, dict[int, str]]) -> None: if self.options.entrance_rando: hint_data.update({self.player: {}}) # all state seems to have efficient paths @@ -626,7 +677,7 @@ def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]) -> None: if hint_text: hint_data[self.player][location.address] = hint_text - def get_real_location(self, location: Location) -> Tuple[str, int]: + def get_real_location(self, location: Location) -> tuple[str, int]: # if it's not in a group, it's not in an item link if location.player not in self.multiworld.groups or not location.item: return location.name, location.player @@ -638,8 +689,8 @@ def get_real_location(self, location: Location) -> Tuple[str, int]: f"Using a potentially incorrect location name instead.") return location.name, location.player - def fill_slot_data(self) -> Dict[str, Any]: - slot_data: Dict[str, Any] = { + def fill_slot_data(self) -> dict[str, Any]: + slot_data: dict[str, Any] = { "seed": self.random.randint(0, 2147483647), "start_with_sword": self.options.start_with_sword.value, "keys_behind_bosses": self.options.keys_behind_bosses.value, @@ -657,6 +708,8 @@ def fill_slot_data(self) -> Dict[str, Any]: "entrance_rando": int(bool(self.options.entrance_rando.value)), "decoupled": self.options.decoupled.value if self.options.entrance_rando else 0, "shuffle_ladders": self.options.shuffle_ladders.value, + # "shuffle_fuses": self.options.shuffle_fuses.value, + # "shuffle_bells": self.options.shuffle_bells.value, "grass_randomizer": self.options.grass_randomizer.value, "combat_logic": self.options.combat_logic.value, "Hexagon Quest Prayer": self.ability_unlocks["Pages 24-25 (Prayer)"], @@ -674,7 +727,7 @@ def fill_slot_data(self) -> Dict[str, Any]: # checking if groups so that this doesn't run if the player isn't in a group if groups: if not self.item_link_locations: - tunic_worlds: Tuple[TunicWorld] = self.multiworld.get_game_worlds("TUNIC") + tunic_worlds: tuple[TunicWorld] = self.multiworld.get_game_worlds("TUNIC") # figure out our groups and the items in them for tunic in tunic_worlds: for group in self.multiworld.get_player_groups(tunic.player): @@ -710,7 +763,7 @@ def fill_slot_data(self) -> Dict[str, Any]: # for the universal tracker, doesn't get called in standard gen # docs: https://github.com/FarisTheAncient/Archipelago/blob/tracker/worlds/tracker/docs/re-gen-passthrough.md @staticmethod - def interpret_slot_data(slot_data: Dict[str, Any]) -> Dict[str, Any]: + def interpret_slot_data(slot_data: dict[str, Any]) -> dict[str, Any]: # returning slot_data so it regens, giving it back in multiworld.re_gen_passthrough # we are using re_gen_passthrough over modifying the world here due to complexities with ER return slot_data diff --git a/worlds/tunic/breakables.py b/worlds/tunic/breakables.py index 156bece7ca0f..b9af437c8313 100644 --- a/worlds/tunic/breakables.py +++ b/worlds/tunic/breakables.py @@ -1,16 +1,16 @@ +from enum import IntEnum from typing import TYPE_CHECKING, NamedTuple -from enum import IntEnum from BaseClasses import CollectionState, Region from worlds.generic.Rules import set_rule -from .rules import has_sword, has_melee + +from .constants import base_id from .er_rules import can_shop -if TYPE_CHECKING: - from . import TunicWorld +from .logic_helpers import has_sword, has_melee -# just getting an id that is a decent chunk ahead of the grass ones -breakable_base_id = 509342400 + 8000 +if TYPE_CHECKING: + from . import TunicWorld class BreakableType(IntEnum): @@ -341,6 +341,7 @@ class TunicLocationData(NamedTuple): } +breakable_base_id = base_id + 8000 breakable_location_name_to_id: dict[str, int] = {name: breakable_base_id + index for index, name in enumerate(breakable_location_table)} @@ -358,6 +359,7 @@ class TunicLocationData(NamedTuple): "Beneath the Well Main": "Beneath the Well", "Well Boss": "Dark Tomb Checkpoint", "Dark Tomb Main": "Dark Tomb", + "Magic Dagger House": "West Garden House", "Fortress Courtyard Upper": "Fortress Courtyard", "Fortress Courtyard Upper pot": "Fortress Courtyard", "Fortress Courtyard west pots": "Fortress Courtyard", @@ -370,13 +372,16 @@ class TunicLocationData(NamedTuple): "Fortress Grave Path westmost pot": "Fortress Grave Path", "Fortress Grave Path pots": "Fortress Grave Path", "Dusty": "Fortress Leaf Piles", - "Frog Stairs Upper": "Frog Stairs", + "Frog Stairs Upper": "Frog Stairway", + "Frog's Domain Front": "Frog's Domain", + "Frog's Domain Main": "Frog's Domain", "Quarry Monastery Entry": "Quarry", "Quarry Back": "Quarry", "Lower Quarry": "Quarry", "Lower Quarry upper pots": "Quarry", "Even Lower Quarry": "Quarry", "Monastery Back": "Monastery", + "Cathedral Main": "Cathedral", } diff --git a/worlds/tunic/combat_logic.py b/worlds/tunic/combat_logic.py index dbf1e8640ff2..d12450fbcaee 100644 --- a/worlds/tunic/combat_logic.py +++ b/worlds/tunic/combat_logic.py @@ -1,10 +1,12 @@ -from typing import Dict, List, NamedTuple, Tuple, Optional -from enum import IntEnum from collections import defaultdict +from enum import IntEnum +from typing import NamedTuple + from BaseClasses import CollectionState -from .rules import has_sword, has_melee from worlds.AutoWorld import LogicMixin +from .logic_helpers import has_sword, has_melee + # the vanilla stats you are expected to have to get through an area, based on where they are in vanilla class AreaStats(NamedTuple): @@ -16,12 +18,12 @@ class AreaStats(NamedTuple): sp_level: int mp_level: int potion_count: int - equipment: List[str] = [] + equipment: list[str] = [] is_boss: bool = False # the vanilla upgrades/equipment you would have -area_data: Dict[str, AreaStats] = { +area_data: dict[str, AreaStats] = { # The upgrade page is right by the Well entrance. Upper Overworld by the chest in the top right might need something "Overworld": AreaStats(1, 1, 1, 1, 1, 1, 0, ["Stick"]), "East Forest": AreaStats(1, 1, 1, 1, 1, 1, 0, ["Sword"]), @@ -52,9 +54,9 @@ class AreaStats(NamedTuple): # these are used for caching which areas can currently be reached in state # Gauntlet does not have exclusively higher stat requirements, so it will be checked separately -boss_areas: List[str] = [name for name, data in area_data.items() if data.is_boss and name != "Gauntlet"] +boss_areas: list[str] = [name for name, data in area_data.items() if data.is_boss and name != "Gauntlet"] # Swamp does not have exclusively higher stat requirements, so it will be checked separately -non_boss_areas: List[str] = [name for name, data in area_data.items() if not data.is_boss and name != "Swamp"] +non_boss_areas: list[str] = [name for name, data in area_data.items() if not data.is_boss and name != "Swamp"] class CombatState(IntEnum): @@ -114,7 +116,7 @@ def has_combat_reqs(area_name: str, state: CollectionState, player: int) -> bool return met_combat_reqs -def check_combat_reqs(area_name: str, state: CollectionState, player: int, alt_data: Optional[AreaStats] = None) -> bool: +def check_combat_reqs(area_name: str, state: CollectionState, player: int, alt_data: AreaStats | None = None) -> bool: data = alt_data or area_data[area_name] extra_att_needed = 0 extra_def_needed = 0 @@ -303,7 +305,7 @@ def has_required_stats(data: AreaStats, state: CollectionState, player: int) -> # returns a tuple of your max attack level, the number of attack offerings -def get_att_level(state: CollectionState, player: int) -> Tuple[int, int]: +def get_att_level(state: CollectionState, player: int) -> tuple[int, int]: att_offerings = state.count("ATT Offering", player) att_upgrades = state.count("Hero Relic - ATT", player) sword_level = state.count("Sword Upgrade", player) @@ -315,44 +317,44 @@ def get_att_level(state: CollectionState, player: int) -> Tuple[int, int]: # returns a tuple of your max defense level, the number of defense offerings -def get_def_level(state: CollectionState, player: int) -> Tuple[int, int]: +def get_def_level(state: CollectionState, player: int) -> tuple[int, int]: def_offerings = state.count("DEF Offering", player) # defense falls off, can just cap it at 8 for simplicity return (min(8, 1 + def_offerings - + state.count_from_list({"Hero Relic - DEF", "Secret Legend", "Phonomath"}, player)) + + state.count_from_list(("Hero Relic - DEF", "Secret Legend", "Phonomath"), player)) + (2 if state.has("Shield", player) else 0) + (2 if state.has("Hero's Laurels", player) else 0), def_offerings) # returns a tuple of your max potion level, the number of potion offerings -def get_potion_level(state: CollectionState, player: int) -> Tuple[int, int]: +def get_potion_level(state: CollectionState, player: int) -> tuple[int, int]: potion_offerings = min(2, state.count("Potion Offering", player)) # your third potion upgrade (from offerings) costs 1,000 money, reasonable to assume you won't do that return (1 + potion_offerings - + state.count_from_list({"Hero Relic - POTION", "Just Some Pals", "Spring Falls", "Back To Work"}, player), + + state.count_from_list(("Hero Relic - POTION", "Just Some Pals", "Spring Falls", "Back To Work"), player), potion_offerings) # returns a tuple of your max hp level, the number of hp offerings -def get_hp_level(state: CollectionState, player: int) -> Tuple[int, int]: +def get_hp_level(state: CollectionState, player: int) -> tuple[int, int]: hp_offerings = state.count("HP Offering", player) return 1 + hp_offerings + state.count("Hero Relic - HP", player), hp_offerings # returns a tuple of your max sp level, the number of sp offerings -def get_sp_level(state: CollectionState, player: int) -> Tuple[int, int]: +def get_sp_level(state: CollectionState, player: int) -> tuple[int, int]: sp_offerings = state.count("SP Offering", player) return (1 + sp_offerings - + state.count_from_list({"Hero Relic - SP", "Mr Mayor", "Power Up", - "Regal Weasel", "Forever Friend"}, player), + + state.count_from_list(("Hero Relic - SP", "Mr Mayor", "Power Up", + "Regal Weasel", "Forever Friend"), player), sp_offerings) -def get_mp_level(state: CollectionState, player: int) -> Tuple[int, int]: +def get_mp_level(state: CollectionState, player: int) -> tuple[int, int]: mp_offerings = state.count("MP Offering", player) return (1 + mp_offerings - + state.count_from_list({"Hero Relic - MP", "Sacred Geometry", "Vintage", "Dusty"}, player), + + state.count_from_list(("Hero Relic - MP", "Sacred Geometry", "Vintage", "Dusty"), player), mp_offerings) @@ -426,9 +428,9 @@ def calc_def_sp_cost(def_upgrades: int, sp_upgrades: int) -> int: class TunicState(LogicMixin): - tunic_need_to_reset_combat_from_collect: Dict[int, bool] - tunic_need_to_reset_combat_from_remove: Dict[int, bool] - tunic_area_combat_state: Dict[int, Dict[str, int]] + tunic_need_to_reset_combat_from_collect: dict[int, bool] + tunic_need_to_reset_combat_from_remove: dict[int, bool] + tunic_area_combat_state: dict[int, dict[str, int]] def init_mixin(self, _): # the per-player need to reset the combat state when collecting a combat item diff --git a/worlds/tunic/constants.py b/worlds/tunic/constants.py new file mode 100644 index 000000000000..2543fd3c195c --- /dev/null +++ b/worlds/tunic/constants.py @@ -0,0 +1,51 @@ +base_id = 509342400 + +laurels = "Hero's Laurels" +grapple = "Magic Orb" +ice_dagger = "Magic Dagger" +fire_wand = "Magic Wand" +gun = "Gun" +lantern = "Lantern" +fairies = "Fairy" +coins = "Golden Coin" +prayer = "Pages 24-25 (Prayer)" +holy_cross = "Pages 42-43 (Holy Cross)" +icebolt = "Pages 52-53 (Icebolt)" +shield = "Shield" +key = "Key" +house_key = "Old House Key" +vault_key = "Fortress Vault Key" +mask = "Scavenger Mask" +red_hexagon = "Red Questagon" +green_hexagon = "Green Questagon" +blue_hexagon = "Blue Questagon" +gold_hexagon = "Gold Questagon" + +swamp_fuse_1 = "Swamp Fuse 1" +swamp_fuse_2 = "Swamp Fuse 2" +swamp_fuse_3 = "Swamp Fuse 3" +cathedral_elevator_fuse = "Cathedral Elevator Fuse" +quarry_fuse_1 = "Quarry Fuse 1" +quarry_fuse_2 = "Quarry Fuse 2" +ziggurat_miniboss_fuse = "Ziggurat Miniboss Fuse" +ziggurat_teleporter_fuse = "Ziggurat Teleporter Fuse" +fortress_exterior_fuse_1 = "Fortress Exterior Fuse 1" +fortress_exterior_fuse_2 = "Fortress Exterior Fuse 2" +fortress_courtyard_upper_fuse = "Fortress Courtyard Upper Fuse" +fortress_courtyard_lower_fuse = "Fortress Courtyard Fuse" +beneath_the_vault_fuse = "Beneath the Vault Fuse" # event needs to be renamed probably +fortress_candles_fuse = "Fortress Candles Fuse" +fortress_door_left_fuse = "Fortress Door Left Fuse" +fortress_door_right_fuse = "Fortress Door Right Fuse" +west_furnace_fuse = "West Furnace Fuse" +west_garden_fuse = "West Garden Fuse" +atoll_northeast_fuse = "Atoll Northeast Fuse" +atoll_northwest_fuse = "Atoll Northwest Fuse" +atoll_southeast_fuse = "Atoll Southeast Fuse" +atoll_southwest_fuse = "Atoll Southwest Fuse" +library_lab_fuse = "Library Lab Fuse" + +# "Quarry - [East] Bombable Wall" is excluded from this list since it has slightly different rules +bomb_walls = ["East Forest - Bombable Wall", "Eastern Vault Fortress - [East Wing] Bombable Wall", + "Overworld - [Central] Bombable Wall", "Overworld - [Southwest] Bombable Wall Near Fountain", + "Quarry - [West] Upper Area Bombable Wall", "Ruined Atoll - [Northwest] Bombable Wall"] diff --git a/worlds/tunic/er_data.py b/worlds/tunic/er_data.py index 744326aa2060..cfa215a34129 100644 --- a/worlds/tunic/er_data.py +++ b/worlds/tunic/er_data.py @@ -1,5 +1,5 @@ -from typing import Dict, NamedTuple, List, Optional, TYPE_CHECKING from enum import IntEnum +from typing import NamedTuple, TYPE_CHECKING if TYPE_CHECKING: from . import TunicWorld @@ -36,7 +36,7 @@ def destination_scene(self) -> str: # the vanilla connection return self.destination + ", " + self.scene() + self.tag -portal_mapping: List[Portal] = [ +portal_mapping: list[Portal] = [ Portal(name="Stick House Entrance", region="Overworld", destination="Sword Cave", tag="_", direction=Direction.north), Portal(name="Windmill Entrance", region="Overworld", @@ -535,7 +535,7 @@ def destination_scene(self) -> str: # the vanilla connection class RegionInfo(NamedTuple): game_scene: str # the name of the scene in the actual game dead_end: int = 0 # if a region has only one exit - outlet_region: Optional[str] = None + outlet_region: str | None = None is_fake_region: bool = False @@ -553,7 +553,7 @@ class DeadEnd(IntEnum): # key is the AP region name. "Fake" in region info just means the mod won't receive that info at all -tunic_er_regions: Dict[str, RegionInfo] = { +tunic_er_regions: dict[str, RegionInfo] = { "Menu": RegionInfo("Fake", dead_end=DeadEnd.all_cats, is_fake_region=True), "Overworld": RegionInfo("Overworld Redux"), # main overworld, the central area "Overworld Holy Cross": RegionInfo("Fake", dead_end=DeadEnd.all_cats, is_fake_region=True), # main overworld holy cross checks @@ -735,6 +735,7 @@ class DeadEnd(IntEnum): "Rooted Ziggurat Lower Entry": RegionInfo("ziggurat2020_3"), # the vanilla entry point side "Rooted Ziggurat Lower Front": RegionInfo("ziggurat2020_3"), # the front for combat logic "Rooted Ziggurat Lower Mid Checkpoint": RegionInfo("ziggurat2020_3"), # the mid-checkpoint before double admin + "Rooted Ziggurat Lower Miniboss Platform": RegionInfo("ziggurat2020_3"), # the double admin platform "Rooted Ziggurat Lower Back": RegionInfo("ziggurat2020_3"), # the boss side "Zig Skip Exit": RegionInfo("ziggurat2020_3", dead_end=DeadEnd.special, outlet_region="Rooted Ziggurat Lower Entry", is_fake_region=True), # for use with fixed shop on "Rooted Ziggurat Portal Room Entrance": RegionInfo("ziggurat2020_3", outlet_region="Rooted Ziggurat Lower Back"), # the door itself on the zig 3 side @@ -775,7 +776,6 @@ class DeadEnd(IntEnum): "Spirit Arena Victory": RegionInfo("Spirit Arena", dead_end=DeadEnd.all_cats, is_fake_region=True), } - # this is essentially a pared down version of the region connections in rules.py, with some minor differences # the main purpose of this is to make it so that you can access every region # most items are excluded from the rules here, since we can assume Archipelago will properly place them @@ -786,7 +786,7 @@ class DeadEnd(IntEnum): # LS# refers to ladder storage difficulties # LS rules are used for region connections here regardless of whether you have being knocked out of the air in logic # this is because it just means you can reach the entrances in that region via ladder storage -traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = { +traversal_requirements: dict[str, dict[str, list[list[str]]]] = { "Overworld": { "Overworld Beach": [], @@ -801,7 +801,7 @@ class DeadEnd(IntEnum): "Overworld Swamp Lower Entry": [], "Overworld Special Shop Entry": - [["Hyperdash"], ["LS1"]], + [["LS1"]], "Overworld Well Entry Area": [], "Overworld Ruined Passage Door": @@ -823,7 +823,7 @@ class DeadEnd(IntEnum): "Overworld Tunnel Turret": [["IG1"], ["LS1"], ["Hyperdash"]], "Overworld Temple Door": - [["IG2"], ["LS3"], ["Forest Belltower Upper", "Overworld Belltower"]], + [["Bell Shuffle"], ["IG2"], ["LS3"], ["Forest Belltower Upper", "Overworld Belltower"]], "Overworld Southeast Cross Door": [], "Overworld Fountain Cross Door": @@ -1229,7 +1229,7 @@ class DeadEnd(IntEnum): }, "West Garden by Portal": { "West Garden Portal": - [["West Garden South Checkpoint"]], + [["Fuse Shuffle"], ["West Garden South Checkpoint"]], "West Garden Portal Item": [["Hyperdash"]], }, @@ -1468,7 +1468,8 @@ class DeadEnd(IntEnum): "Eastern Vault Fortress": { "Eastern Vault Fortress Gold Door": - [["IG2"], ["Fortress Exterior from Overworld", "Beneath the Vault Back", "Fortress Courtyard Upper"]], + [["IG2"], ["Fuse Shuffle"], + ["Fortress Exterior from Overworld", "Beneath the Vault Back", "Fortress Courtyard Upper"]], }, "Eastern Vault Fortress Gold Door": { "Eastern Vault Fortress": @@ -1514,7 +1515,7 @@ class DeadEnd(IntEnum): "Fortress Arena": { "Fortress Arena Portal": - [["Fortress Exterior from Overworld", "Beneath the Vault Back", "Eastern Vault Fortress"]], + [["Fuse Shuffle"], ["Fortress Exterior from Overworld", "Beneath the Vault Back", "Eastern Vault Fortress"]], }, "Fortress Arena Portal": { "Fortress Arena": @@ -1547,7 +1548,7 @@ class DeadEnd(IntEnum): "Quarry Entry": { "Quarry Portal": - [["Quarry Connector"]], + [["Fuse Shuffle"], ["Quarry Connector"]], "Quarry": [], "Monastery Rope": @@ -1593,7 +1594,7 @@ class DeadEnd(IntEnum): "Even Lower Quarry": [], "Lower Quarry Zig Door": - [["Quarry", "Quarry Connector"], ["IG3"]], + [["Fuse Shuffle"], ["Quarry", "Quarry Connector"], ["IG3"]], }, "Monastery Rope": { "Quarry Back": @@ -1636,13 +1637,19 @@ class DeadEnd(IntEnum): [["Hyperdash"]], "Rooted Ziggurat Lower Front": [], - "Rooted Ziggurat Lower Back": + "Rooted Ziggurat Lower Miniboss Platform": + [], + }, + "Rooted Ziggurat Lower Miniboss Platform": { + "Rooted Ziggurat Lower Mid Checkpoint": [], + "Rooted Ziggurat Lower Back": + [] }, "Rooted Ziggurat Lower Back": { "Rooted Ziggurat Lower Entry": [["LS2"]], - "Rooted Ziggurat Lower Mid Checkpoint": + "Rooted Ziggurat Lower Miniboss Platform": [["Hyperdash"], ["IG1"]], "Rooted Ziggurat Portal Room Entrance": [], @@ -1658,7 +1665,7 @@ class DeadEnd(IntEnum): }, "Rooted Ziggurat Portal Room": { "Rooted Ziggurat Portal Room Exit": - [["Rooted Ziggurat Lower Back"]], + [["Fuse Shuffle"], ["Rooted Ziggurat Lower Back"]], "Rooted Ziggurat Portal": [], }, @@ -1742,7 +1749,6 @@ class DeadEnd(IntEnum): "Cathedral Main": [], }, - "Cathedral Gauntlet Checkpoint": { "Cathedral Gauntlet": [], @@ -1762,13 +1768,13 @@ class DeadEnd(IntEnum): "Far Shore to East Forest Region": [["Hyperdash"]], "Far Shore to Quarry Region": - [["Quarry Connector", "Quarry"]], + [["Fuse Shuffle"], ["Quarry Connector", "Quarry"]], "Far Shore to Library Region": - [["Library Lab"]], + [["Fuse Shuffle"], ["Library Lab"]], "Far Shore to West Garden Region": - [["West Garden South Checkpoint"]], + [["Fuse Shuffle"], ["West Garden South Checkpoint"]], "Far Shore to Fortress Region": - [["Fortress Exterior from Overworld", "Beneath the Vault Back", "Eastern Vault Fortress"]], + [["Fuse Shuffle"], ["Fortress Exterior from Overworld", "Beneath the Vault Back", "Eastern Vault Fortress"]], }, "Far Shore to Spawn Region": { "Far Shore": diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index edd6021cba6c..6d238693cc05 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -1,58 +1,32 @@ -from typing import Dict, FrozenSet, Tuple, TYPE_CHECKING +from typing import FrozenSet, TYPE_CHECKING + +from BaseClasses import Region from worlds.generic.Rules import set_rule, add_rule, forbid_item -from BaseClasses import Region, CollectionState -from .options import IceGrappling, LadderStorage, CombatLogic -from .rules import (has_ability, has_sword, has_melee, has_ice_grapple_logic, has_lantern, has_mask, can_ladder_storage, - laurels_zip, bomb_walls) -from .er_data import Portal, get_portal_outlet_region -from .ladder_storage_data import ow_ladder_groups, region_ladders, easy_ls, medium_ls, hard_ls + +# from .bells import set_bell_location_rules from .combat_logic import has_combat_reqs +from .constants import * +from .er_data import Portal, get_portal_outlet_region +# from .fuses import set_fuse_location_rules, has_fuses from .grass import set_grass_location_rules +from .ladder_storage_data import ow_ladder_groups, region_ladders, easy_ls, medium_ls, hard_ls +from .logic_helpers import (has_ability, has_ladder, has_melee, has_sword, has_lantern, has_mask, has_fuses, + can_shop, can_get_past_bushes, laurels_zip, has_ice_grapple_logic, can_ladder_storage) +from .options import IceGrappling, LadderStorage, CombatLogic if TYPE_CHECKING: from . import TunicWorld -laurels = "Hero's Laurels" -grapple = "Magic Orb" -ice_dagger = "Magic Dagger" -fire_wand = "Magic Wand" -gun = "Gun" -lantern = "Lantern" -fairies = "Fairy" -coins = "Golden Coin" -prayer = "Pages 24-25 (Prayer)" -holy_cross = "Pages 42-43 (Holy Cross)" -icebolt = "Pages 52-53 (Icebolt)" -key = "Key" -house_key = "Old House Key" -vault_key = "Fortress Vault Key" -mask = "Scavenger Mask" -red_hexagon = "Red Questagon" -green_hexagon = "Green Questagon" -blue_hexagon = "Blue Questagon" -gold_hexagon = "Gold Questagon" - - -def has_ladder(ladder: str, state: CollectionState, world: "TunicWorld") -> bool: - return not world.options.shuffle_ladders or state.has(ladder, world.player) +fuses_option = False # replace with options.shuffle_fuses when fuse shuffle is in +bells_option = False # replace with options.shuffle_bells when bell shuffle is in -def can_shop(state: CollectionState, world: "TunicWorld") -> bool: - return has_sword(state, world.player) and state.can_reach_region("Shop", world.player) - - -# for the ones that are not early bushes where ER can screw you over a bit -def can_get_past_bushes(state: CollectionState, world: "TunicWorld") -> bool: - # add in glass cannon + stick for grass rando - return has_sword(state, world.player) or state.has_any((fire_wand, laurels, gun), world.player) - - -def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_pairs: Dict[Portal, Portal]) -> None: +def set_er_region_rules(world: "TunicWorld", regions: dict[str, Region], portal_pairs: dict[Portal, Portal]) -> None: player = world.player options = world.options # input scene destination tag, returns portal's name and paired portal's outlet region or region - def get_portal_info(portal_sd: str) -> Tuple[str, str]: + def get_portal_info(portal_sd: str) -> tuple[str, str]: for portal1, portal2 in portal_pairs.items(): if portal1.scene_destination() == portal_sd: return portal1.name, get_portal_outlet_region(portal2, world) @@ -61,7 +35,7 @@ def get_portal_info(portal_sd: str) -> Tuple[str, str]: raise Exception(f"No matches found in get_portal_info for {portal_sd}") # input scene destination tag, returns paired portal's name and region - def get_paired_portal(portal_sd: str) -> Tuple[str, str]: + def get_paired_portal(portal_sd: str) -> tuple[str, str]: for portal1, portal2 in portal_pairs.items(): if portal1.scene_destination() == portal_sd: return portal2.name, portal2.region @@ -81,7 +55,7 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Overworld"].connect( connecting_region=regions["Overworld Beach"], rule=lambda state: has_ladder("Ladders in Overworld Town", state, world) - or state.has_any({laurels, grapple}, player)) + or state.has_any((laurels, grapple), player)) # regions["Overworld Beach"].connect( # connecting_region=regions["Overworld"], # rule=lambda state: has_ladder("Ladders in Overworld Town", state, world) @@ -114,14 +88,14 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: rule=lambda state: state.has(laurels, player)) regions["Overworld to Atoll Upper"].connect( connecting_region=regions["Overworld"], - rule=lambda state: state.has_any({laurels, grapple}, player)) + rule=lambda state: state.has_any((laurels, grapple), player)) regions["Overworld"].connect( connecting_region=regions["Overworld Belltower"], rule=lambda state: state.has(laurels, player) or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) - regions["Overworld Belltower"].connect( - connecting_region=regions["Overworld"]) + # regions["Overworld Belltower"].connect( + # connecting_region=regions["Overworld"]) # ice grapple rudeling across rubble, drop bridge, ice grapple rudeling down regions["Overworld Belltower"].connect( @@ -146,17 +120,17 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: connecting_region=regions["Overworld Ruined Passage Door"], rule=lambda state: state.has(key, player, 2) or laurels_zip(state, world)) - regions["Overworld Ruined Passage Door"].connect( - connecting_region=regions["Overworld"], - rule=lambda state: laurels_zip(state, world)) + # regions["Overworld Ruined Passage Door"].connect( + # connecting_region=regions["Overworld"], + # rule=lambda state: laurels_zip(state, world)) regions["Overworld"].connect( connecting_region=regions["After Ruined Passage"], rule=lambda state: has_ladder("Ladders near Weathervane", state, world) or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world)) - regions["After Ruined Passage"].connect( - connecting_region=regions["Overworld"], - rule=lambda state: has_ladder("Ladders near Weathervane", state, world)) + # regions["After Ruined Passage"].connect( + # connecting_region=regions["Overworld"], + # rule=lambda state: has_ladder("Ladders near Weathervane", state, world)) # for the hard ice grapple, get to the chest after the bomb wall, grab a slime, and grapple push down # you can ice grapple through the bomb wall, so no need for shop logic checking @@ -165,10 +139,10 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: rule=lambda state: has_ladder("Ladders near Weathervane", state, world) or state.has(laurels, player) or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world)) - regions["Above Ruined Passage"].connect( - connecting_region=regions["Overworld"], - rule=lambda state: has_ladder("Ladders near Weathervane", state, world) - or state.has(laurels, player)) + # regions["Above Ruined Passage"].connect( + # connecting_region=regions["Overworld"], + # rule=lambda state: has_ladder("Ladders near Weathervane", state, world) + # or state.has(laurels, player)) regions["After Ruined Passage"].connect( connecting_region=regions["Above Ruined Passage"], @@ -183,8 +157,7 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world)) regions["East Overworld"].connect( connecting_region=regions["Above Ruined Passage"], - rule=lambda state: has_ladder("Ladders near Weathervane", state, world) - or state.has(laurels, player)) + rule=lambda state: has_ladder("Ladders near Weathervane", state, world)) # nmg: ice grapple the slimes, works both ways consistently regions["East Overworld"].connect( @@ -198,9 +171,9 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: connecting_region=regions["East Overworld"], rule=lambda state: has_ladder("Ladders near Overworld Checkpoint", state, world) or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world)) - regions["East Overworld"].connect( - connecting_region=regions["Overworld"], - rule=lambda state: has_ladder("Ladders near Overworld Checkpoint", state, world)) + # regions["East Overworld"].connect( + # connecting_region=regions["Overworld"], + # rule=lambda state: has_ladder("Ladders near Overworld Checkpoint", state, world)) regions["East Overworld"].connect( connecting_region=regions["Overworld at Patrol Cave"]) @@ -220,9 +193,9 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: connecting_region=regions["Overworld above Patrol Cave"], rule=lambda state: has_ladder("Ladders near Overworld Checkpoint", state, world) or state.has(grapple, player)) - regions["Overworld above Patrol Cave"].connect( - connecting_region=regions["Overworld"], - rule=lambda state: has_ladder("Ladders near Overworld Checkpoint", state, world)) + # regions["Overworld above Patrol Cave"].connect( + # connecting_region=regions["Overworld"], + # rule=lambda state: has_ladder("Ladders near Overworld Checkpoint", state, world)) regions["East Overworld"].connect( connecting_region=regions["Overworld above Patrol Cave"], @@ -243,10 +216,10 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Upper Overworld"].connect( connecting_region=regions["Overworld above Quarry Entrance"], - rule=lambda state: state.has_any({grapple, laurels}, player)) + rule=lambda state: state.has_any((grapple, laurels), player)) regions["Overworld above Quarry Entrance"].connect( connecting_region=regions["Upper Overworld"], - rule=lambda state: state.has_any({grapple, laurels}, player)) + rule=lambda state: state.has_any((grapple, laurels), player)) # ice grapple push guard captain down the ledge regions["Upper Overworld"].connect( @@ -267,11 +240,11 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Overworld"].connect( connecting_region=regions["Overworld after Envoy"], - rule=lambda state: state.has_any({laurels, grapple, gun}, player) + rule=lambda state: state.has_any((laurels, grapple, gun), player) or state.has("Sword Upgrade", player, 4)) regions["Overworld after Envoy"].connect( connecting_region=regions["Overworld"], - rule=lambda state: state.has_any({laurels, grapple, gun}, player) + rule=lambda state: state.has_any((laurels, grapple, gun), player) or state.has("Sword Upgrade", player, 4)) regions["Overworld after Envoy"].connect( @@ -285,24 +258,24 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Overworld"].connect( connecting_region=regions["Overworld Quarry Entry"], rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) - regions["Overworld Quarry Entry"].connect( - connecting_region=regions["Overworld"], - rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_easy, state, world)) + # regions["Overworld Quarry Entry"].connect( + # connecting_region=regions["Overworld"], + # rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_easy, state, world)) regions["Overworld"].connect( connecting_region=regions["Overworld Swamp Upper Entry"], rule=lambda state: state.has(laurels, player)) - regions["Overworld Swamp Upper Entry"].connect( - connecting_region=regions["Overworld"], - rule=lambda state: state.has(laurels, player)) + # regions["Overworld Swamp Upper Entry"].connect( + # connecting_region=regions["Overworld"], + # rule=lambda state: state.has(laurels, player)) regions["Overworld"].connect( connecting_region=regions["Overworld Swamp Lower Entry"], rule=lambda state: has_ladder("Ladder to Swamp", state, world) or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world)) - regions["Overworld Swamp Lower Entry"].connect( - connecting_region=regions["Overworld"], - rule=lambda state: has_ladder("Ladder to Swamp", state, world)) + # regions["Overworld Swamp Lower Entry"].connect( + # connecting_region=regions["Overworld"], + # rule=lambda state: has_ladder("Ladder to Swamp", state, world)) regions["East Overworld"].connect( connecting_region=regions["Overworld Special Shop Entry"], @@ -335,33 +308,34 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: connecting_region=regions["Overworld Southeast Cross Door"], rule=lambda state: has_ability(holy_cross, state, world) or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world)) - regions["Overworld Southeast Cross Door"].connect( - connecting_region=regions["Overworld"], - rule=lambda state: has_ability(holy_cross, state, world)) + # regions["Overworld Southeast Cross Door"].connect( + # connecting_region=regions["Overworld"], + # rule=lambda state: has_ability(holy_cross, state, world)) regions["Overworld"].connect( connecting_region=regions["Overworld Fountain Cross Door"], rule=lambda state: has_ability(holy_cross, state, world) or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) - regions["Overworld Fountain Cross Door"].connect( - connecting_region=regions["Overworld"]) + # regions["Overworld Fountain Cross Door"].connect( + # connecting_region=regions["Overworld"]) ow_to_town_portal = regions["Overworld"].connect( connecting_region=regions["Overworld Town Portal"], rule=lambda state: has_ability(prayer, state, world)) - regions["Overworld Town Portal"].connect( - connecting_region=regions["Overworld"]) + # regions["Overworld Town Portal"].connect( + # connecting_region=regions["Overworld"]) regions["Overworld"].connect( connecting_region=regions["Overworld Spawn Portal"], rule=lambda state: has_ability(prayer, state, world)) - regions["Overworld Spawn Portal"].connect( - connecting_region=regions["Overworld"]) + # regions["Overworld Spawn Portal"].connect( + # connecting_region=regions["Overworld"]) # nmg: ice grapple through temple door regions["Overworld"].connect( connecting_region=regions["Overworld Temple Door"], - rule=lambda state: state.has_all({"Ring Eastern Bell", "Ring Western Bell"}, player) + rule=lambda state: (state.has_all(("Ring Eastern Bell", "Ring Western Bell"), player) and not bells_option) + or (state.has_all(("East Bell", "West Bell"), player) and bells_option) or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) regions["Overworld Temple Door"].connect( @@ -637,7 +611,8 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: connecting_region=regions["West Garden by Portal"]) regions["West Garden by Portal"].connect( connecting_region=regions["West Garden Portal"], - rule=lambda state: has_ability(prayer, state, world) and state.has("Activate West Garden Fuse", player)) + rule=lambda state: has_ability(prayer, state, world) + and has_fuses("Activate West Garden Fuse", state, world)) regions["West Garden by Portal"].connect( connecting_region=regions["West Garden Portal Item"], @@ -691,12 +666,16 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: atoll_statue = regions["Ruined Atoll"].connect( connecting_region=regions["Ruined Atoll Statue"], rule=lambda state: has_ability(prayer, state, world) - and ((has_ladder("Ladders in South Atoll", state, world) - and state.has_any((laurels, grapple), player) - and (has_sword(state, player) or state.has_any((fire_wand, gun), player))) - # shoot fuse and have the shot hit you mid-LS - or (can_ladder_storage(state, world) and state.has(fire_wand, player) - and options.ladder_storage >= LadderStorage.option_hard))) + and (((((has_ladder("Ladders in South Atoll", state, world) + and state.has_any((laurels, grapple), player) + and (has_sword(state, player) or state.has_any((gun, fire_wand), player))) + # shoot fuse and have the shot hit you mid-LS + or (can_ladder_storage(state, world) and state.has(fire_wand, player) + and options.ladder_storage >= LadderStorage.option_hard))) and not fuses_option) + or (state.has_all((atoll_northwest_fuse, atoll_northeast_fuse, atoll_southwest_fuse, atoll_southeast_fuse), player) + and fuses_option)) + ) + regions["Ruined Atoll Statue"].connect( connecting_region=regions["Ruined Atoll"]) @@ -742,7 +721,7 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Library Exterior by Tree"].connect( connecting_region=regions["Library Exterior Ladder Region"], - rule=lambda state: state.has_any({grapple, laurels}, player) + rule=lambda state: state.has_any((grapple, laurels), player) and has_ladder("Ladders in Library", state, world)) regions["Library Exterior Ladder Region"].connect( connecting_region=regions["Library Exterior by Tree"], @@ -785,7 +764,7 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Library Lab Lower"].connect( connecting_region=regions["Library Lab"], - rule=lambda state: state.has_any({grapple, laurels}, player) + rule=lambda state: state.has_any((grapple, laurels), player) and has_ladder("Ladders in Library", state, world)) regions["Library Lab"].connect( connecting_region=regions["Library Lab Lower"], @@ -802,7 +781,7 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Library Lab on Portal Pad"].connect( connecting_region=regions["Library Portal"], - rule=lambda state: has_ability(prayer, state, world)) + rule=lambda state: has_ability(prayer, state, world) and has_fuses("Activate Library Fuse", state, world)) regions["Library Portal"].connect( connecting_region=regions["Library Lab on Portal Pad"]) @@ -823,10 +802,14 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Fortress Exterior near cave"].connect( connecting_region=regions["Fortress Exterior from Overworld"], - rule=lambda state: state.has(laurels, player)) + rule=lambda state: state.has(laurels, player) + or (has_ability(prayer, state, world) and state.has(fortress_exterior_fuse_1, player) + and fuses_option)) regions["Fortress Exterior from Overworld"].connect( connecting_region=regions["Fortress Exterior near cave"], - rule=lambda state: state.has(laurels, player) or has_ability(prayer, state, world)) + rule=lambda state: state.has(laurels, player) + or (has_ability(prayer, state, world) and state.has(fortress_exterior_fuse_1, player) + if fuses_option else has_ability(prayer, state, world))) # shoot far fire pot, enemy gets aggro'd regions["Fortress Exterior near cave"].connect( @@ -889,12 +872,15 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Eastern Vault Fortress"].connect( connecting_region=regions["Eastern Vault Fortress Gold Door"], - rule=lambda state: state.has_all({"Activate Eastern Vault West Fuses", - "Activate Eastern Vault East Fuse"}, player) + rule=lambda state: (has_fuses("Activate Eastern Vault West Fuses", state, world) + and has_fuses("Activate Eastern Vault East Fuse", state, world)) or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) regions["Eastern Vault Fortress Gold Door"].connect( connecting_region=regions["Eastern Vault Fortress"], - rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_easy, state, world)) + rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_easy, state, world) + or (has_fuses("Activate Eastern Vault West Fuses", state, world) + and has_fuses("Activate Eastern Vault East Fuse", state, world) + and fuses_option)) fort_grave_entry_to_combat = regions["Fortress Grave Path Entry"].connect( connecting_region=regions["Fortress Grave Path Combat"]) @@ -925,7 +911,7 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Fortress Arena"].connect( connecting_region=regions["Fortress Arena Portal"], - rule=lambda state: state.has("Activate Eastern Vault West Fuses", player)) + rule=lambda state: has_ability(prayer, state, world) and has_fuses("Activate Eastern Vault West Fuses", state, world)) regions["Fortress Arena Portal"].connect( connecting_region=regions["Fortress Arena"]) @@ -939,7 +925,7 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Quarry Entry"].connect( connecting_region=regions["Quarry Portal"], - rule=lambda state: state.has("Activate Quarry Fuse", player)) + rule=lambda state: has_ability(prayer, state, world) and has_fuses("Activate Quarry Fuse", state, world)) regions["Quarry Portal"].connect( connecting_region=regions["Quarry Entry"]) @@ -990,7 +976,7 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Even Lower Quarry Isolated Chest"].connect( connecting_region=regions["Lower Quarry Zig Door"], - rule=lambda state: state.has("Activate Quarry Fuse", player) + rule=lambda state: has_fuses("Activate Quarry Fuse", state, world) or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world)) # don't need the mask for this either, please don't complain about not needing a mask here, you know what you did @@ -1037,21 +1023,26 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: zig_low_mid_to_front = regions["Rooted Ziggurat Lower Mid Checkpoint"].connect( connecting_region=regions["Rooted Ziggurat Lower Front"]) - zig_low_mid_to_back = regions["Rooted Ziggurat Lower Mid Checkpoint"].connect( + regions["Rooted Ziggurat Lower Mid Checkpoint"].connect( + connecting_region=regions["Rooted Ziggurat Lower Miniboss Platform"]) + zig_low_miniboss_to_mid = regions["Rooted Ziggurat Lower Miniboss Platform"].connect( + connecting_region=regions["Rooted Ziggurat Lower Mid Checkpoint"], + rule=lambda state: state.has(ziggurat_miniboss_fuse, player) if fuses_option + else (has_sword(state, player) and has_ability(prayer, state, world))) + # can ice grapple to the voidlings to get to the double admin fight, still need to pray at the fuse + zig_low_miniboss_to_back = regions["Rooted Ziggurat Lower Miniboss Platform"].connect( connecting_region=regions["Rooted Ziggurat Lower Back"], + rule=lambda state: state.has(laurels, player) or (state.has(ziggurat_miniboss_fuse, player) and fuses_option) + or (has_sword(state, player) and has_ability(prayer, state, world) and not fuses_option)) + regions["Rooted Ziggurat Lower Back"].connect( + connecting_region=regions["Rooted Ziggurat Lower Miniboss Platform"], rule=lambda state: state.has(laurels, player) - or (has_sword(state, player) and has_ability(prayer, state, world))) - # can ice grapple to the voidlings to get to the double admin fight, still need to pray at the fuse - zig_low_back_to_mid = regions["Rooted Ziggurat Lower Back"].connect( - connecting_region=regions["Rooted Ziggurat Lower Mid Checkpoint"], - rule=lambda state: (state.has(laurels, player) - or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world)) - and has_ability(prayer, state, world) - and has_sword(state, player)) + or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world) + or (state.has(ziggurat_miniboss_fuse, player) and fuses_option)) regions["Rooted Ziggurat Lower Back"].connect( connecting_region=regions["Rooted Ziggurat Portal Room Entrance"], - rule=lambda state: has_ability(prayer, state, world)) + rule=lambda state: has_fuses("Activate Ziggurat Fuse", state, world)) regions["Rooted Ziggurat Portal Room Entrance"].connect( connecting_region=regions["Rooted Ziggurat Lower Back"]) @@ -1059,11 +1050,11 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: connecting_region=regions["Rooted Ziggurat Portal Room"]) regions["Rooted Ziggurat Portal Room"].connect( connecting_region=regions["Rooted Ziggurat Portal"], - rule=lambda state: has_ability(prayer, state, world)) + rule=lambda state: has_fuses("Activate Ziggurat Fuse", state, world) and has_ability(prayer, state, world)) regions["Rooted Ziggurat Portal Room"].connect( connecting_region=regions["Rooted Ziggurat Portal Room Exit"], - rule=lambda state: state.has("Activate Ziggurat Fuse", player)) + rule=lambda state: has_fuses("Activate Ziggurat Fuse", state, world)) regions["Rooted Ziggurat Portal Room Exit"].connect( connecting_region=regions["Rooted Ziggurat Portal Room"]) @@ -1082,19 +1073,21 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: swamp_mid_to_cath = regions["Swamp Mid"].connect( connecting_region=regions["Swamp to Cathedral Main Entrance Region"], rule=lambda state: (has_ability(prayer, state, world) - and (has_sword(state, player)) + and has_sword(state, player) and (state.has(laurels, player) # blam yourself in the face with a wand shot off the fuse or (can_ladder_storage(state, world) and state.has(fire_wand, player) and options.ladder_storage >= LadderStorage.option_hard and (not options.shuffle_ladders - or state.has_any({"Ladders in Overworld Town", + or state.has_any(("Ladders in Overworld Town", "Ladder to Swamp", - "Ladders near Weathervane"}, player) + "Ladders near Weathervane"), player) or (state.has("Ladder to Ruined Atoll", player) and state.can_reach_region("Overworld Beach", player))))) and (not options.combat_logic - or has_combat_reqs("Swamp", state, player))) + or has_combat_reqs("Swamp", state, player)) + and not fuses_option) + or (state.has_all((swamp_fuse_1, swamp_fuse_2, swamp_fuse_3), player) and fuses_option) or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) if options.ladder_storage >= LadderStorage.option_hard and options.shuffle_ladders: @@ -1102,7 +1095,8 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Swamp to Cathedral Main Entrance Region"].connect( connecting_region=regions["Swamp Mid"], - rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_easy, state, world)) + rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_easy, state, world) + or (state.has_all((swamp_fuse_1, swamp_fuse_2, swamp_fuse_3), player) and fuses_option)) # grapple push the enemy by the door down, then grapple to it. Really jank regions["Swamp Mid"].connect( @@ -1148,7 +1142,7 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: cath_entry_to_elev = regions["Cathedral Entry"].connect( connecting_region=regions["Cathedral to Gauntlet"], - rule=lambda state: (has_ability(prayer, state, world) + rule=lambda state: ((state.has(cathedral_elevator_fuse, player) if fuses_option else has_ability(prayer, state, world)) or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) or options.entrance_rando) # elevator is always there in ER regions["Cathedral to Gauntlet"].connect( @@ -1159,11 +1153,6 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Cathedral Main"].connect( connecting_region=regions["Cathedral Entry"]) - cath_elev_to_main = regions["Cathedral to Gauntlet"].connect( - connecting_region=regions["Cathedral Main"]) - regions["Cathedral Main"].connect( - connecting_region=regions["Cathedral to Gauntlet"]) - regions["Cathedral Gauntlet Checkpoint"].connect( connecting_region=regions["Cathedral Gauntlet"]) @@ -1191,25 +1180,25 @@ def get_paired_portal(portal_sd: str) -> Tuple[str, str]: regions["Far Shore"].connect( connecting_region=regions["Far Shore to West Garden Region"], - rule=lambda state: state.has("Activate West Garden Fuse", player)) + rule=lambda state: has_fuses("Activate West Garden Fuse", state, world)) regions["Far Shore to West Garden Region"].connect( connecting_region=regions["Far Shore"]) regions["Far Shore"].connect( connecting_region=regions["Far Shore to Quarry Region"], - rule=lambda state: state.has("Activate Quarry Fuse", player)) + rule=lambda state: has_fuses("Activate Quarry Fuse", state, world)) regions["Far Shore to Quarry Region"].connect( connecting_region=regions["Far Shore"]) regions["Far Shore"].connect( connecting_region=regions["Far Shore to Fortress Region"], - rule=lambda state: state.has("Activate Eastern Vault West Fuses", player)) + rule=lambda state: has_fuses("Activate Eastern Vault West Fuses", state, world)) regions["Far Shore to Fortress Region"].connect( connecting_region=regions["Far Shore"]) regions["Far Shore"].connect( connecting_region=regions["Far Shore to Library Region"], - rule=lambda state: state.has("Activate Library Fuse", player)) + rule=lambda state: has_fuses("Activate Library Fuse", state, world)) regions["Far Shore to Library Region"].connect( connecting_region=regions["Far Shore"]) @@ -1239,7 +1228,7 @@ def ls_connect(origin_name: str, portal_sdt: str) -> None: non_ow_ls_list.extend(hard_ls) # create the ls elevation regions - ladder_regions: Dict[str, Region] = {} + ladder_regions: dict[str, Region] = {} for name in ow_ladder_groups.keys(): ladder_regions[name] = Region(name, player, world.multiworld) @@ -1409,10 +1398,10 @@ def ls_connect(origin_name: str, portal_sdt: str) -> None: lambda state: has_combat_reqs("Dark Tomb", state, player)) set_rule(wg_before_to_after_terry, - lambda state: state.has_any({laurels, ice_dagger}, player) + lambda state: state.has_any((laurels, ice_dagger), player) or has_combat_reqs("West Garden", state, player)) set_rule(wg_after_to_before_terry, - lambda state: state.has_any({laurels, ice_dagger}, player) + lambda state: state.has_any((laurels, ice_dagger), player) or has_combat_reqs("West Garden", state, player)) set_rule(wg_after_terry_to_west_combat, @@ -1453,25 +1442,23 @@ def ls_connect(origin_name: str, portal_sdt: str) -> None: lambda state: has_combat_reqs("Rooted Ziggurat", state, player)) set_rule(zig_low_mid_to_front, lambda state: has_combat_reqs("Rooted Ziggurat", state, player)) - set_rule(zig_low_mid_to_back, + set_rule(zig_low_miniboss_to_back, lambda state: state.has(laurels, player) - or (has_ability(prayer, state, world) and has_combat_reqs("Rooted Ziggurat", state, player))) - set_rule(zig_low_back_to_mid, - lambda state: (state.has(laurels, player) - or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world)) - and has_ability(prayer, state, world) - and has_combat_reqs("Rooted Ziggurat", state, player)) + or (state.has(ziggurat_miniboss_fuse, player) if fuses_option + else (has_ability(prayer, state, world) and has_combat_reqs("Rooted Ziggurat", state, player)))) + set_rule(zig_low_miniboss_to_mid, + lambda state: state.has(ziggurat_miniboss_fuse, player) if fuses_option + else (has_ability(prayer, state, world) and has_combat_reqs("Rooted Ziggurat", state, player))) # only activating the fuse requires combat logic set_rule(cath_entry_to_elev, lambda state: options.entrance_rando or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world) - or (has_ability(prayer, state, world) and has_combat_reqs("Swamp", state, player))) + or (state.has(cathedral_elevator_fuse, player) if fuses_option + else (has_ability(prayer, state, world) and has_combat_reqs("Swamp", state, player)))) set_rule(cath_entry_to_main, lambda state: has_combat_reqs("Swamp", state, player)) - set_rule(cath_elev_to_main, - lambda state: has_combat_reqs("Swamp", state, player)) # for spots where you can go into and come out of an entrance to reset enemy aggro if world.options.entrance_rando: @@ -1543,10 +1530,17 @@ def ls_connect(origin_name: str, portal_sdt: str) -> None: def set_er_location_rules(world: "TunicWorld") -> None: player = world.player + options = world.options - if world.options.grass_randomizer: + if options.grass_randomizer: set_grass_location_rules(world) + # if options.shuffle_fuses: + # set_fuse_location_rules(world) + # + # if options.shuffle_bells: + # set_bell_location_rules(world) + forbid_item(world.get_location("Secret Gathering Place - 20 Fairy Reward"), fairies, player) # Ability Shuffle Exclusive Rules @@ -1557,7 +1551,7 @@ def set_er_location_rules(world: "TunicWorld") -> None: set_rule(world.get_location("East Forest - Golden Obelisk Holy Cross"), lambda state: has_ability(holy_cross, state, world)) set_rule(world.get_location("Beneath the Well - [Powered Secret Room] Chest"), - lambda state: state.has("Activate Furnace Fuse", player)) + lambda state: has_fuses("Activate Furnace Fuse", state, world)) set_rule(world.get_location("West Garden - [North] Behind Holy Cross Door"), lambda state: has_ability(holy_cross, state, world)) set_rule(world.get_location("Library Hall - Holy Cross Chest"), @@ -1583,9 +1577,9 @@ def set_er_location_rules(world: "TunicWorld") -> None: # Overworld set_rule(world.get_location("Overworld - [Southwest] Grapple Chest Over Walkway"), - lambda state: state.has_any({grapple, laurels}, player)) + lambda state: state.has_any((grapple, laurels), player)) set_rule(world.get_location("Overworld - [Southwest] West Beach Guarded By Turret 2"), - lambda state: state.has_any({grapple, laurels}, player)) + lambda state: state.has_any((grapple, laurels), player)) set_rule(world.get_location("Overworld - [Southwest] From West Garden"), lambda state: state.has(laurels, player)) set_rule(world.get_location("Overworld - [Southeast] Page on Pillar by Swamp"), @@ -1635,9 +1629,9 @@ def set_er_location_rules(world: "TunicWorld") -> None: set_rule(world.get_location("East Forest - Lower Grapple Chest"), lambda state: state.has(grapple, player)) set_rule(world.get_location("East Forest - Lower Dash Chest"), - lambda state: state.has_all({grapple, laurels}, player)) + lambda state: state.has_all((grapple, laurels), player)) set_rule(world.get_location("East Forest - Ice Rod Grapple Chest"), lambda state: ( - state.has_all({grapple, ice_dagger, fire_wand}, player) and has_ability(icebolt, state, world))) + state.has_all((grapple, ice_dagger, fire_wand), player) and has_ability(icebolt, state, world))) # Dark Tomb # added to make combat logic smoother @@ -1669,11 +1663,11 @@ def set_er_location_rules(world: "TunicWorld") -> None: # Frog's Domain set_rule(world.get_location("Frog's Domain - Side Room Grapple Secret"), - lambda state: state.has_any({grapple, laurels}, player)) + lambda state: state.has_any((grapple, laurels), player)) set_rule(world.get_location("Frog's Domain - Grapple Above Hot Tub"), - lambda state: state.has_any({grapple, laurels}, player)) + lambda state: state.has_any((grapple, laurels), player)) set_rule(world.get_location("Frog's Domain - Escape Chest"), - lambda state: state.has_any({grapple, laurels}, player)) + lambda state: state.has_any((grapple, laurels), player)) # Library Lab set_rule(world.get_location("Library Lab - Page 1"), @@ -1695,7 +1689,7 @@ def set_er_location_rules(world: "TunicWorld") -> None: # Beneath the Vault set_rule(world.get_location("Beneath the Fortress - Bridge"), lambda state: has_lantern(state, world) and - (has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player))) + (has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player))) # Quarry set_rule(world.get_location("Quarry - [Central] Above Ladder Dash Chest"), @@ -1706,9 +1700,10 @@ def set_er_location_rules(world: "TunicWorld") -> None: set_rule(world.get_location("Rooted Ziggurat Upper - Near Bridge Switch"), lambda state: has_sword(state, player) or (state.has(fire_wand, player) and (state.has(laurels, player) - or world.options.entrance_rando))) + or options.entrance_rando))) set_rule(world.get_location("Rooted Ziggurat Lower - After Guarded Fuse"), - lambda state: has_sword(state, player) and has_ability(prayer, state, world)) + lambda state: state.has(ziggurat_miniboss_fuse, player) if fuses_option + else has_sword(state, player) and has_ability(prayer, state, world)) # Bosses set_rule(world.get_location("Fortress Arena - Siege Engine/Vault Key Pickup"), @@ -1750,34 +1745,36 @@ def set_er_location_rules(world: "TunicWorld") -> None: lambda state: state.has(laurels, player)) # Events - set_rule(world.get_location("Eastern Bell"), - lambda state: (has_melee(state, player) or state.has(fire_wand, player))) - set_rule(world.get_location("Western Bell"), - lambda state: (has_melee(state, player) or state.has(fire_wand, player))) - set_rule(world.get_location("Furnace Fuse"), - lambda state: has_ability(prayer, state, world)) - set_rule(world.get_location("South and West Fortress Exterior Fuses"), - lambda state: has_ability(prayer, state, world)) - set_rule(world.get_location("Upper and Central Fortress Exterior Fuses"), - lambda state: has_ability(prayer, state, world)) - set_rule(world.get_location("Beneath the Vault Fuse"), - lambda state: state.has("Activate South and West Fortress Exterior Fuses", player)) - set_rule(world.get_location("Eastern Vault West Fuses"), - lambda state: state.has("Activate Beneath the Vault Fuse", player)) - set_rule(world.get_location("Eastern Vault East Fuse"), - lambda state: state.has_all({"Activate Upper and Central Fortress Exterior Fuses", - "Activate South and West Fortress Exterior Fuses"}, player)) - set_rule(world.get_location("Quarry Connector Fuse"), - lambda state: has_ability(prayer, state, world) and state.has(grapple, player)) - set_rule(world.get_location("Quarry Fuse"), - lambda state: state.has("Activate Quarry Connector Fuse", player)) - set_rule(world.get_location("Ziggurat Fuse"), - lambda state: has_ability(prayer, state, world)) - set_rule(world.get_location("West Garden Fuse"), - lambda state: has_ability(prayer, state, world)) - set_rule(world.get_location("Library Fuse"), - lambda state: has_ability(prayer, state, world) and has_ladder("Ladders in Library", state, world)) - if not world.options.hexagon_quest: + if not bells_option: + set_rule(world.get_location("Eastern Bell"), + lambda state: (has_melee(state, player) or state.has(fire_wand, player))) + set_rule(world.get_location("Western Bell"), + lambda state: (has_melee(state, player) or state.has(fire_wand, player))) + if not fuses_option: + set_rule(world.get_location("Furnace Fuse"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("South and West Fortress Exterior Fuses"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("Upper and Central Fortress Exterior Fuses"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("Beneath the Vault Fuse"), + lambda state: state.has("Activate South and West Fortress Exterior Fuses", player)) + set_rule(world.get_location("Eastern Vault West Fuses"), + lambda state: state.has("Activate Beneath the Vault Fuse", player)) + set_rule(world.get_location("Eastern Vault East Fuse"), + lambda state: state.has_all(("Activate Upper and Central Fortress Exterior Fuses", + "Activate South and West Fortress Exterior Fuses"), player)) + set_rule(world.get_location("Quarry Connector Fuse"), + lambda state: has_ability(prayer, state, world) and state.has(grapple, player)) + set_rule(world.get_location("Quarry Fuse"), + lambda state: state.has("Activate Quarry Connector Fuse", player)) + set_rule(world.get_location("Ziggurat Fuse"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("West Garden Fuse"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("Library Fuse"), + lambda state: has_ability(prayer, state, world) and has_ladder("Ladders in Library", state, world)) + if not options.hexagon_quest: set_rule(world.get_location("Place Questagons"), lambda state: state.has_all((red_hexagon, blue_hexagon, green_hexagon), player)) @@ -1868,7 +1865,7 @@ def combat_logic_to_loc(loc_name: str, combat_req_area: str, set_instead: bool = # laurels past the enemies, then use the wand or gun to take care of the fairies that chased you add_rule(world.get_location("West Garden - [West Lowlands] Tree Holy Cross Chest"), - lambda state: state.has_any({fire_wand, "Gun"}, player)) + lambda state: state.has_any((fire_wand, gun), player)) combat_logic_to_loc("West Garden - [Central Lowlands] Chest Beneath Faeries", "West Garden") combat_logic_to_loc("West Garden - [Central Lowlands] Chest Beneath Save Point", "West Garden") combat_logic_to_loc("West Garden - [West Highlands] Upper Left Walkway", "West Garden") @@ -1880,13 +1877,14 @@ def combat_logic_to_loc(loc_name: str, combat_req_area: str, set_instead: bool = # could just do the last two, but this outputs better in the spoiler log # dagger is maybe viable here, but it's sketchy -- activate ladder switch, save to reset enemies, climb up - combat_logic_to_loc("Upper and Central Fortress Exterior Fuses", "Eastern Vault Fortress") - combat_logic_to_loc("Beneath the Vault Fuse", "Beneath the Vault") - combat_logic_to_loc("Eastern Vault West Fuses", "Eastern Vault Fortress") + if not fuses_option: + combat_logic_to_loc("Upper and Central Fortress Exterior Fuses", "Eastern Vault Fortress") + combat_logic_to_loc("Beneath the Vault Fuse", "Beneath the Vault") + combat_logic_to_loc("Eastern Vault West Fuses", "Eastern Vault Fortress") # if you come in from the left, you only need to fight small crabs add_rule(world.get_location("Ruined Atoll - [South] Near Birds"), - lambda state: has_melee(state, player) or state.has_any({laurels, "Gun"}, player)) + lambda state: has_melee(state, player) or state.has_any((laurels, gun), player)) # can get this one without fighting if you have laurels add_rule(world.get_location("Frog's Domain - Above Vault"), @@ -1898,8 +1896,21 @@ def combat_logic_to_loc(loc_name: str, combat_req_area: str, set_instead: bool = and (state.has(laurels, player) or world.options.entrance_rando)) or has_combat_reqs("Rooted Ziggurat", state, player)) set_rule(world.get_location("Rooted Ziggurat Lower - After Guarded Fuse"), - lambda state: has_ability(prayer, state, world) - and has_combat_reqs("Rooted Ziggurat", state, player)) + lambda state: state.has(ziggurat_miniboss_fuse, player) if fuses_option + else (has_ability(prayer, state, world) and has_combat_reqs("Rooted Ziggurat", state, player))) + + if fuses_option: + set_rule(world.get_location("Rooted Ziggurat Lower - [Miniboss] Activate Fuse"), + lambda state: has_ability(prayer, state, world) and has_combat_reqs("Rooted Ziggurat", state, player)) + combat_logic_to_loc("Beneath the Fortress - Activate Fuse", "Beneath the Vault") + combat_logic_to_loc("Fortress Courtyard - [Upper] Activate Fuse", "Eastern Vault Fortress") + combat_logic_to_loc("Fortress Courtyard - [Central] Activate Fuse", "Eastern Vault Fortress") + combat_logic_to_loc("Eastern Vault Fortress - [Candle Room] Activate Fuse", "Eastern Vault Fortress") + combat_logic_to_loc("Eastern Vault Fortress - [Left of Door] Activate Fuse", "Eastern Vault Fortress") + combat_logic_to_loc("Eastern Vault Fortress - [Right of Door] Activate Fuse", "Eastern Vault Fortress") + combat_logic_to_loc("Ruined Atoll - [Northwest] Activate Fuse", "Ruined Atoll") + combat_logic_to_loc("Ruined Atoll - [Southwest] Activate Fuse", "Ruined Atoll") + combat_logic_to_loc("Swamp - [Central] Activate Fuse", "Swamp") # replace the sword rule with this one combat_logic_to_loc("Swamp - [South Graveyard] 4 Orange Skulls", "Swamp", set_instead=True) diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index 9fc44d842cc4..81fb90d8f0ec 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -1,14 +1,16 @@ -from typing import Dict, List, Set, Tuple, TYPE_CHECKING +from copy import deepcopy +from random import Random +from typing import TYPE_CHECKING + from BaseClasses import Region, ItemClassification, Item, Location -from .locations import all_locations +from Options import PlandoConnection + +from .breakables import create_breakable_exclusive_regions, set_breakable_location_rules from .er_data import (Portal, portal_mapping, traversal_requirements, DeadEnd, Direction, RegionInfo, get_portal_outlet_region) from .er_rules import set_er_region_rules -from .breakables import create_breakable_exclusive_regions, set_breakable_location_rules -from Options import PlandoConnection +from .locations import all_locations from .options import EntranceRando, EntranceLayout -from random import Random -from copy import deepcopy if TYPE_CHECKING: from . import TunicWorld @@ -22,8 +24,8 @@ class TunicERLocation(Location): game: str = "TUNIC" -def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]: - regions: Dict[str, Region] = {} +def create_er_regions(world: "TunicWorld") -> dict[Portal, Portal]: + regions: dict[str, Region] = {} world.used_shop_numbers = set() for region_name, region_data in world.er_regions.items(): @@ -83,7 +85,7 @@ def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]: # keys are event names, values are event regions -tunic_events: Dict[str, str] = { +tunic_events: dict[str, str] = { "Eastern Bell": "Forest Belltower Upper", "Western Bell": "Overworld Belltower at Bell", "Furnace Fuse": "Furnace Fuse", @@ -101,7 +103,7 @@ def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]: } -def place_event_items(world: "TunicWorld", regions: Dict[str, Region]) -> None: +def place_event_items(world: "TunicWorld", regions: dict[str, Region]) -> None: for event_name, region_name in tunic_events.items(): region = regions[region_name] location = TunicERLocation(world.player, event_name, None, region) @@ -111,9 +113,13 @@ def place_event_items(world: "TunicWorld", regions: Dict[str, Region]) -> None: location.place_locked_item( TunicERItem("Unseal the Heir", ItemClassification.progression, None, world.player)) elif event_name.endswith("Bell"): + # if world.options.shuffle_bells: + # continue location.place_locked_item( TunicERItem("Ring " + event_name, ItemClassification.progression, None, world.player)) - else: + elif event_name.endswith("Fuse") or event_name.endswith("Fuses"): + # if world.options.shuffle_fuses: + # continue location.place_locked_item( TunicERItem("Activate " + event_name, ItemClassification.progression, None, world.player)) region.locations.append(location) @@ -135,7 +141,7 @@ def get_shop_num(world: "TunicWorld") -> int: # all shops are the same shop. however, you cannot get to all shops from the same shop entrance. # so, we need a bunch of shop regions that connect to the actual shop, but the actual shop cannot connect back -def create_shop_region(world: "TunicWorld", regions: Dict[str, Region], portal_num) -> None: +def create_shop_region(world: "TunicWorld", regions: dict[str, Region], portal_num) -> None: new_shop_name = f"Shop {portal_num}" world.er_regions[new_shop_name] = RegionInfo("Shop", dead_end=DeadEnd.all_cats) new_shop_region = Region(new_shop_name, world.player, world.multiworld) @@ -144,8 +150,8 @@ def create_shop_region(world: "TunicWorld", regions: Dict[str, Region], portal_n # for non-ER that uses the ER rules, we create a vanilla set of portal pairs -def vanilla_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal, Portal]: - portal_pairs: Dict[Portal, Portal] = {} +def vanilla_portals(world: "TunicWorld", regions: dict[str, Region]) -> dict[Portal, Portal]: + portal_pairs: dict[Portal, Portal] = {} # we don't want the zig skip exit for vanilla portals, since it shouldn't be considered for logic here portal_map = [portal for portal in portal_mapping if portal.name not in ["Ziggurat Lower Falling Entrance", "Purgatory Bottom Exit", "Purgatory Top Exit"]] @@ -182,10 +188,10 @@ def vanilla_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Por # repeat this phase until all regions are reachable # second phase: randomly pair dead ends to random two_plus # third phase: randomly pair the remaining two_plus to each other -def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal, Portal]: - portal_pairs: Dict[Portal, Portal] = {} - dead_ends: List[Portal] = [] - two_plus: List[Portal] = [] +def pair_portals(world: "TunicWorld", regions: dict[str, Region]) -> dict[Portal, Portal]: + portal_pairs: dict[Portal, Portal] = {} + dead_ends: list[Portal] = [] + two_plus: list[Portal] = [] player_name = world.player_name portal_map = portal_mapping.copy() laurels_zips = world.options.laurels_zips.value @@ -194,6 +200,10 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal entrance_layout = world.options.entrance_layout laurels_location = world.options.laurels_location decoupled = world.options.decoupled + # shuffle_fuses = bool(world.options.shuffle_fuses.value) + # shuffle_bells = bool(world.options.shuffle_bells.value) + shuffle_fuses = False + shuffle_bells = False traversal_reqs = deepcopy(traversal_requirements) has_laurels = True waterfall_plando = False @@ -207,7 +217,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal entrance_layout = seed_group["entrance_layout"] laurels_location = "10_fairies" if seed_group["laurels_at_10_fairies"] is True else False - logic_tricks: Tuple[bool, int, int] = (laurels_zips, ice_grappling, ladder_storage) + logic_tricks: tuple[bool, int, int] = (laurels_zips, ice_grappling, ladder_storage) # marking that you don't immediately have laurels if laurels_location == "10_fairies" and not world.using_ut: @@ -215,8 +225,8 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal # for the direction pairs option with decoupled off # tracks how many portals are in each direction in each list - two_plus_direction_tracker: Dict[int, int] = {direction: 0 for direction in range(8)} - dead_end_direction_tracker: Dict[int, int] = {direction: 0 for direction in range(8)} + two_plus_direction_tracker: dict[int, int] = {direction: 0 for direction in range(8)} + dead_end_direction_tracker: dict[int, int] = {direction: 0 for direction in range(8)} # for ensuring we have enough entrances in directions left that we don't leave dead ends without any def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: @@ -226,10 +236,6 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: return False return True - # If using Universal Tracker, restore portal_map. Could be cleaner, but it does not matter for UT even a little bit - if world.using_ut: - portal_map = portal_mapping.copy() - # create separate lists for dead ends and non-dead ends for portal in portal_map: dead_end_status = world.er_regions[portal.region].dead_end @@ -291,11 +297,12 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: dead_ends.append(shop_portal) dead_end_direction_tracker[shop_portal.direction] += 1 - connected_regions: Set[str] = set() + connected_regions: set[str] = set() # make better start region stuff when/if implementing random start start_region = "Overworld" connected_regions.add(start_region) - connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks) + connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks, + shuffle_fuses, shuffle_bells) if world.options.entrance_rando.value in EntranceRando.options.values(): plando_connections = world.options.plando_connections.value @@ -371,8 +378,8 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: else: modified_plando_connections = plando_connections - connected_shop_portal1s: Set[int] = set() - connected_shop_portal2s: Set[int] = set() + connected_shop_portal1s: set[int] = set() + connected_shop_portal2s: set[int] = set() for connection in modified_plando_connections: p_entrance = connection.entrance p_exit = connection.exit @@ -419,7 +426,15 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: break else: if p_entrance.startswith("Shop Portal "): - portal_num = int(p_entrance.split("Shop Portal ")[-1]) + try: + portal_num = int(p_entrance.split("Shop Portal ")[-1]) + except ValueError: + if "Previous Region" in p_entrance: + raise Exception("TUNIC: APWorld used for generation is incompatible with newer APWorld. " + "Please use the APWorld from Archipelago 0.6.1 instead.") + else: + raise Exception("TUNIC: Unknown error occurred in UT entrance setup, please contact " + "the TUNIC APWorld devs.") # shops 1-6 are south, 7 and 8 are east, and after that it just breaks direction pairs if portal_num <= 6: pdir = Direction.south @@ -452,7 +467,15 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: else: if not portal2: if p_exit.startswith("Shop Portal "): - portal_num = int(p_exit.split("Shop Portal ")[-1]) + try: + portal_num = int(p_exit.split("Shop Portal ")[-1]) + except ValueError: + if "Previous Region" in p_exit: + raise Exception("TUNIC: APWorld used for generation is incompatible with newer APWorld. " + "Please use the APWorld from Archipelago 0.6.1 instead.") + else: + raise Exception("TUNIC: Unknown error occurred in UT entrance setup, please contact " + "the TUNIC APWorld devs.") if portal_num <= 6: pdir = Direction.south elif portal_num in [7, 8]: @@ -510,13 +533,15 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: dead_end_direction_tracker[portal1.direction] -= 1 else: two_plus_direction_tracker[portal1.direction] -= 1 + if portal2_dead_end: dead_end_direction_tracker[portal2.direction] -= 1 else: two_plus_direction_tracker[portal2.direction] -= 1 # if we have plando connections, our connected regions may change somewhat - connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks) + connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks, + shuffle_fuses, shuffle_bells) # if there are an odd number of shops after plando, add another one, except in decoupled where it doesn't matter if not decoupled and len(world.used_shop_numbers) % 2 == 1: @@ -599,7 +624,6 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: connected_regions = backup_connected_regions.copy() rare_failure_count += 1 fail_count = 0 - if rare_failure_count > 100: raise Exception(f"Failed to pair regions due to rare pairing issues for {player_name}. " f"Unconnected regions: {non_dead_end_regions - connected_regions}.\n" @@ -633,7 +657,9 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: if waterfall_plando: cr = connected_regions.copy() cr.add(portal.region) - if "Secret Gathering Place" not in update_reachable_regions(cr, traversal_reqs, has_laurels, logic_tricks): + if "Secret Gathering Place" not in update_reachable_regions(cr, traversal_reqs, has_laurels, + logic_tricks, shuffle_fuses, + shuffle_bells): continue # if not waterfall_plando, then we just want to pair secret gathering place now elif portal.region != "Secret Gathering Place": @@ -682,8 +708,8 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: # once we have both portals, connect them and add the new region(s) to connected_regions if not has_laurels and "Secret Gathering Place" in connected_regions: has_laurels = True - connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks) - + connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks, + shuffle_fuses, shuffle_bells) portal_pairs[portal1] = portal2 two_plus_direction_tracker[portal1.direction] -= 1 two_plus_direction_tracker[portal2.direction] -= 1 @@ -745,7 +771,7 @@ def too_few_portals_for_direction_pairs(direction: int, offset: int) -> bool: # loop through our list of paired portals and make two-way connections -def create_randomized_entrances(world: "TunicWorld", portal_pairs: Dict[Portal, Portal], regions: Dict[str, Region]) -> None: +def create_randomized_entrances(world: "TunicWorld", portal_pairs: dict[Portal, Portal], regions: dict[str, Region]) -> None: for portal1, portal2 in portal_pairs.items(): # connect to the outlet region if there is one, if not connect to the actual region regions[portal1.region].connect( @@ -757,8 +783,9 @@ def create_randomized_entrances(world: "TunicWorld", portal_pairs: Dict[Portal, name=portal2.name) -def update_reachable_regions(connected_regions: Set[str], traversal_reqs: Dict[str, Dict[str, List[List[str]]]], - has_laurels: bool, logic: Tuple[bool, int, int]) -> Set[str]: +def update_reachable_regions(connected_regions: set[str], traversal_reqs: dict[str, dict[str, list[list[str]]]], + has_laurels: bool, logic: tuple[bool, int, int], shuffle_fuses: bool, + shuffle_bells: bool) -> set[str]: zips, ice_grapples, ls = logic # starting count, so we can run it again if this changes region_count = len(connected_regions) @@ -790,6 +817,12 @@ def update_reachable_regions(connected_regions: Set[str], traversal_reqs: Dict[s break elif req not in connected_regions: break + elif req == "Fuse Shuffle": + if not shuffle_fuses: + break + elif req == "Bell Shuffle": + if not shuffle_bells: + break else: met_traversal_reqs = True break @@ -798,13 +831,14 @@ def update_reachable_regions(connected_regions: Set[str], traversal_reqs: Dict[s # if the length of connected_regions changed, we got new regions, so we want to check those new origins if region_count != len(connected_regions): - connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic) + connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic, + shuffle_fuses, shuffle_bells) return connected_regions # which directions are opposites -direction_pairs: Dict[int, int] = { +direction_pairs: dict[int, int] = { Direction.north: Direction.south, Direction.south: Direction.north, Direction.east: Direction.west, @@ -848,9 +882,9 @@ def verify_plando_directions(connection: PlandoConnection) -> bool: # sort the portal dict by the name of the first portal, referring to the portal order in the master portal list -def sort_portals(portal_pairs: Dict[Portal, Portal], world: "TunicWorld") -> Dict[str, str]: - sorted_pairs: Dict[str, str] = {} - reference_list: List[str] = [portal.name for portal in portal_mapping] +def sort_portals(portal_pairs: dict[Portal, Portal], world: "TunicWorld") -> dict[str, str]: + sorted_pairs: dict[str, str] = {} + reference_list: list[str] = [portal.name for portal in portal_mapping] # due to plando, there can be a variable number of shops largest_shop_number = max(world.used_shop_numbers) diff --git a/worlds/tunic/fuses.py b/worlds/tunic/fuses.py new file mode 100644 index 000000000000..4f223582daf7 --- /dev/null +++ b/worlds/tunic/fuses.py @@ -0,0 +1,30 @@ +from .constants import * + +# for fuse locations and reusing event names to simplify er_rules +fuse_activation_reqs: dict[str, list[str]] = { + swamp_fuse_2: [swamp_fuse_1], + swamp_fuse_3: [swamp_fuse_1, swamp_fuse_2], + fortress_exterior_fuse_2: [fortress_exterior_fuse_1], + beneath_the_vault_fuse: [fortress_exterior_fuse_1, fortress_exterior_fuse_2], + fortress_candles_fuse: [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse], + fortress_door_left_fuse: [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse, + fortress_candles_fuse], + fortress_courtyard_upper_fuse: [fortress_exterior_fuse_1], + fortress_courtyard_lower_fuse: [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse], + fortress_door_right_fuse: [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse, fortress_courtyard_lower_fuse], + quarry_fuse_2: [quarry_fuse_1], + "Activate Furnace Fuse": [west_furnace_fuse], + "Activate South and West Fortress Exterior Fuses": [fortress_exterior_fuse_1, fortress_exterior_fuse_2], + "Activate Upper and Central Fortress Exterior Fuses": [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse, + fortress_courtyard_lower_fuse], + "Activate Beneath the Vault Fuse": [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse], + "Activate Eastern Vault West Fuses": [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse, + fortress_candles_fuse, fortress_door_left_fuse], + "Activate Eastern Vault East Fuse": [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse, + fortress_courtyard_lower_fuse, fortress_door_right_fuse], + "Activate Quarry Connector Fuse": [quarry_fuse_1], + "Activate Quarry Fuse": [quarry_fuse_1, quarry_fuse_2], + "Activate Ziggurat Fuse": [ziggurat_teleporter_fuse], + "Activate West Garden Fuse": [west_garden_fuse], + "Activate Library Fuse": [library_lab_fuse], +} diff --git a/worlds/tunic/grass.py b/worlds/tunic/grass.py index 971ac4c0fe98..f2aea40f7c9a 100644 --- a/worlds/tunic/grass.py +++ b/worlds/tunic/grass.py @@ -1,8 +1,11 @@ -from typing import Dict, NamedTuple, Optional, TYPE_CHECKING, Set +from typing import NamedTuple, TYPE_CHECKING from BaseClasses import CollectionState from worlds.generic.Rules import set_rule, add_rule -from .rules import has_sword, has_melee + +from .constants import base_id +from .logic_helpers import has_sword, has_melee + if TYPE_CHECKING: from . import TunicWorld @@ -10,12 +13,12 @@ class TunicLocationData(NamedTuple): region: str er_region: str # entrance rando region - location_group: Optional[str] = None - + location_group: str | None = None -location_base_id = 509342400 -grass_location_table: Dict[str, TunicLocationData] = { +# todo: remove region, make all of these regions append grass to the name +# and then set the rules on the region entrances instead of the locations directly +grass_location_table: dict[str, TunicLocationData] = { "Overworld - Overworld Grass (576) (7.0, 4.0, -223.0)": TunicLocationData("Overworld", "Overworld"), "Overworld - Overworld Grass (572) (6.0, 4.0, -223.0)": TunicLocationData("Overworld", "Overworld"), "Overworld - Overworld Grass (574) (7.0, 4.0, -224.0)": TunicLocationData("Overworld", "Overworld"), @@ -7763,9 +7766,10 @@ class TunicLocationData(NamedTuple): "Overworld - East Overworld Bush (64) (56.0, 44.0, -107.0)", } -grass_location_name_to_id: Dict[str, int] = {name: location_base_id + 302 + index for index, name in enumerate(grass_location_table)} +grass_base_id = base_id + 302 +grass_location_name_to_id: dict[str, int] = {name: grass_base_id + index for index, name in enumerate(grass_location_table)} -grass_location_name_groups: Dict[str, Set[str]] = {} +grass_location_name_groups: dict[str, set[str]] = {} for loc_name, loc_data in grass_location_table.items(): area_name = loc_name.split(" - ", 1)[0] # adding it to the normal location group and a grass-only one diff --git a/worlds/tunic/items.py b/worlds/tunic/items.py index a2b4140a6804..fe1e33e97df0 100644 --- a/worlds/tunic/items.py +++ b/worlds/tunic/items.py @@ -1,7 +1,10 @@ from itertools import groupby -from typing import Dict, List, Set, NamedTuple, Optional +from typing import NamedTuple + from BaseClasses import ItemClassification as IC +from .constants import base_id + class TunicItemData(NamedTuple): classification: IC @@ -9,12 +12,10 @@ class TunicItemData(NamedTuple): item_id_offset: int item_group: str = "" # classification if combat logic is on - combat_ic: Optional[IC] = None - + combat_ic: None | IC = None -item_base_id = 509342400 -item_table: Dict[str, TunicItemData] = { +item_table: dict[str, TunicItemData] = { "Firecracker x2": TunicItemData(IC.filler, 3, 0, "Bombs"), "Firecracker x3": TunicItemData(IC.filler, 3, 1, "Bombs"), "Firecracker x4": TunicItemData(IC.filler, 3, 2, "Bombs"), @@ -175,7 +176,7 @@ class TunicItemData(NamedTuple): } # items to be replaced by fool traps -fool_tiers: List[List[str]] = [ +fool_tiers: list[list[str]] = [ [], ["Money x1", "Money x10", "Money x15", "Money x16"], ["Money x1", "Money x10", "Money x15", "Money x16", "Money x20"], @@ -214,25 +215,25 @@ class TunicItemData(NamedTuple): "Gold Questagon", ] -combat_items: List[str] = [name for name, data in item_table.items() +combat_items: list[str] = [name for name, data in item_table.items() if data.combat_ic and IC.progression in data.combat_ic] combat_items.extend(["Stick", "Sword", "Sword Upgrade", "Magic Wand", "Hero's Laurels", "Gun"]) -item_name_to_id: Dict[str, int] = {name: item_base_id + data.item_id_offset for name, data in item_table.items()} +item_name_to_id: dict[str, int] = {name: base_id + data.item_id_offset for name, data in item_table.items()} -filler_items: List[str] = [name for name, data in item_table.items() if data.classification == IC.filler and name != "Grass"] +filler_items: list[str] = [name for name, data in item_table.items() if data.classification == IC.filler and name != "Grass"] def get_item_group(item_name: str) -> str: return item_table[item_name].item_group -item_name_groups: Dict[str, Set[str]] = { +item_name_groups: dict[str, set[str]] = { group: set(item_names) for group, item_names in groupby(sorted(item_table, key=get_item_group), get_item_group) if group != "" } # extra groups for the purpose of aliasing items -extra_groups: Dict[str, Set[str]] = { +extra_groups: dict[str, set[str]] = { "Laurels": {"Hero's Laurels"}, "Orb": {"Magic Orb"}, "Dagger": {"Magic Dagger"}, diff --git a/worlds/tunic/ladder_storage_data.py b/worlds/tunic/ladder_storage_data.py index f2d4b94406ac..99a51b406ca6 100644 --- a/worlds/tunic/ladder_storage_data.py +++ b/worlds/tunic/ladder_storage_data.py @@ -1,15 +1,15 @@ -from typing import Dict, List, Set, NamedTuple, Optional +from typing import NamedTuple # ladders in overworld, since it is the most complex area for ladder storage class OWLadderInfo(NamedTuple): - ladders: Set[str] # ladders where the top or bottom is at the same elevation - portals: List[str] # portals at the same elevation, only those without doors - regions: List[str] # regions where a melee enemy can hit you out of ladder storage + ladders: set[str] # ladders where the top or bottom is at the same elevation + portals: list[str] # portals at the same elevation, only those without doors + regions: list[str] # regions where a melee enemy can hit you out of ladder storage # groups for ladders at the same elevation, for use in determing whether you can ls to entrances in diff rulesets -ow_ladder_groups: Dict[str, OWLadderInfo] = { +ow_ladder_groups: dict[str, OWLadderInfo] = { # lowest elevation "LS Elev 0": OWLadderInfo({"Ladders in Overworld Town", "Ladder to Ruined Atoll", "Ladder to Swamp"}, ["Swamp Redux 2_conduit", "Overworld Cave_", "Atoll Redux_lower", "Maze Room_", @@ -49,7 +49,7 @@ class OWLadderInfo(NamedTuple): # ladders accessible within different regions of overworld, only those that are relevant # other scenes will just have them hardcoded since this type of structure is not necessary there -region_ladders: Dict[str, Set[str]] = { +region_ladders: dict[str, set[str]] = { "Overworld": {"Ladders near Weathervane", "Ladders near Overworld Checkpoint", "Ladders near Dark Tomb", "Ladders in Overworld Town", "Ladder to Swamp", "Ladders in Well"}, "Overworld Beach": {"Ladder to Ruined Atoll"}, @@ -63,11 +63,11 @@ class OWLadderInfo(NamedTuple): class LadderInfo(NamedTuple): origin: str # origin region destination: str # destination portal - ladders_req: Optional[str] = None # ladders required to do this + ladders_req: str | None = None # ladders required to do this dest_is_region: bool = False # whether it is a region that you are going to -easy_ls: List[LadderInfo] = [ +easy_ls: list[LadderInfo] = [ # In the furnace # Furnace ladder to the fuse entrance LadderInfo("Furnace Ladder Area", "Furnace, Overworld Redux_gyro_upper_north"), @@ -128,7 +128,7 @@ class LadderInfo(NamedTuple): ] # if we can gain elevation or get knocked down, add the harder ones -medium_ls: List[LadderInfo] = [ +medium_ls: list[LadderInfo] = [ # region-destination versions of easy ls spots LadderInfo("East Forest", "East Forest Dance Fox Spot", dest_is_region=True), # fortress courtyard knockdowns are never logically relevant, the fuse requires upper @@ -169,7 +169,7 @@ class LadderInfo(NamedTuple): LadderInfo("Back of Swamp", "Swamp Redux 2, Overworld Redux_wall"), ] -hard_ls: List[LadderInfo] = [ +hard_ls: list[LadderInfo] = [ # lower ladder, go into the waterfall then above the bonfire, up a ramp, then through the right wall LadderInfo("Beneath the Well Front", "Sewer, Sewer_Boss_", "Ladders in Well"), LadderInfo("Beneath the Well Front", "Sewer, Overworld Redux_west_aqueduct", "Ladders in Well"), diff --git a/worlds/tunic/locations.py b/worlds/tunic/locations.py index ced3d2233b6c..93c6164b88fd 100644 --- a/worlds/tunic/locations.py +++ b/worlds/tunic/locations.py @@ -1,17 +1,19 @@ -from typing import Dict, NamedTuple, Set, Optional, List -from .grass import grass_location_table +from typing import NamedTuple + +# from .bells import bell_location_table from .breakables import breakable_location_table +from .constants import base_id +# from .fuses import fuse_location_table +from .grass import grass_location_table class TunicLocationData(NamedTuple): region: str er_region: str # entrance rando region - location_group: Optional[str] = None - + location_group: str | None = None -location_base_id = 509342400 -location_table: Dict[str, TunicLocationData] = { +location_table: dict[str, TunicLocationData] = { "Beneath the Well - [Powered Secret Room] Chest": TunicLocationData("Beneath the Well", "Beneath the Well Back"), "Beneath the Well - [Entryway] Chest": TunicLocationData("Beneath the Well", "Beneath the Well Main"), "Beneath the Well - [Third Room] Beneath Platform Chest": TunicLocationData("Beneath the Well", "Beneath the Well Main"), @@ -243,7 +245,7 @@ class TunicLocationData(NamedTuple): "Rooted Ziggurat Lower - Near Corpses": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Entry"), "Rooted Ziggurat Lower - Spider Ambush": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Entry"), "Rooted Ziggurat Lower - Left Of Checkpoint Before Fuse": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Mid Checkpoint"), - "Rooted Ziggurat Lower - After Guarded Fuse": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Mid Checkpoint"), + "Rooted Ziggurat Lower - After Guarded Fuse": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Miniboss Platform"), "Rooted Ziggurat Lower - Guarded By Double Turrets": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Front"), "Rooted Ziggurat Lower - After 2nd Double Turret Chest": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Mid Checkpoint"), "Rooted Ziggurat Lower - Guarded By Double Turrets 2": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Front"), @@ -307,7 +309,7 @@ class TunicLocationData(NamedTuple): "West Garden - [Central Lowlands] Chest Near Shortcut Bridge": TunicLocationData("West Garden", "West Garden after Terry"), "West Garden - [West Highlands] Upper Left Walkway": TunicLocationData("West Garden", "West Garden South Checkpoint"), "West Garden - [Central Lowlands] Chest Beneath Save Point": TunicLocationData("West Garden", "West Garden South Checkpoint"), - "West Garden - [Central Highlands] Behind Guard Captain": TunicLocationData("West Garden", "West Garden before Boss"), + "West Garden - [Central Highlands] Behind Guard Captain": TunicLocationData("West Garden", "West Garden South Checkpoint"), "West Garden - [Central Highlands] After Garden Knight": TunicLocationData("Overworld", "West Garden after Boss", location_group="Bosses"), "West Garden - [South Highlands] Secret Chest Beneath Fuse": TunicLocationData("West Garden", "West Garden South Checkpoint"), "West Garden - [East Lowlands] Page Behind Ice Dagger House": TunicLocationData("West Garden", "West Garden Portal Item"), @@ -316,19 +318,21 @@ class TunicLocationData(NamedTuple): "Hero's Grave - Effigy Relic": TunicLocationData("West Garden", "Hero Relic - West Garden"), } -hexagon_locations: Dict[str, str] = { +hexagon_locations: dict[str, str] = { "Red Questagon": "Fortress Arena - Siege Engine/Vault Key Pickup", "Green Questagon": "Librarian - Hexagon Green", "Blue Questagon": "Rooted Ziggurat Lower - Hexagon Blue", } -standard_location_name_to_id: Dict[str, int] = {name: location_base_id + index for index, name in enumerate(location_table)} +standard_location_name_to_id: dict[str, int] = {name: base_id + index for index, name in enumerate(location_table)} all_locations = location_table.copy() all_locations.update(grass_location_table) all_locations.update(breakable_location_table) +# all_locations.update(fuse_location_table) +# all_locations.update(bell_location_table) -location_name_groups: Dict[str, Set[str]] = {} +location_name_groups: dict[str, set[str]] = {} for loc_name, loc_data in location_table.items(): loc_group_name = loc_name.split(" - ", 1)[0] location_name_groups.setdefault(loc_group_name, set()).add(loc_name) diff --git a/worlds/tunic/logic_helpers.py b/worlds/tunic/logic_helpers.py new file mode 100644 index 000000000000..1752bf8eb43d --- /dev/null +++ b/worlds/tunic/logic_helpers.py @@ -0,0 +1,98 @@ +from typing import TYPE_CHECKING + +from BaseClasses import CollectionState + +from .constants import * +from .fuses import fuse_activation_reqs +from .options import HexagonQuestAbilityUnlockType, IceGrappling + +if TYPE_CHECKING: + from . import TunicWorld + + +def randomize_ability_unlocks(world: "TunicWorld") -> dict[str, int]: + options = world.options + + abilities = [prayer, holy_cross, icebolt] + ability_requirement = [1, 1, 1] + world.random.shuffle(abilities) + + if options.hexagon_quest.value and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: + hexagon_goal = options.hexagon_goal.value + # Set ability unlocks to 25, 50, and 75% of goal amount + ability_requirement = [hexagon_goal // 4, hexagon_goal // 2, hexagon_goal * 3 // 4] + if any(req == 0 for req in ability_requirement): + ability_requirement = [1, 2, 3] + + return dict(zip(abilities, ability_requirement)) + + +def has_ability(ability: str, state: CollectionState, world: "TunicWorld") -> bool: + options = world.options + ability_unlocks = world.ability_unlocks + if not options.ability_shuffling: + return True + if options.hexagon_quest and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: + return state.has(gold_hexagon, world.player, ability_unlocks[ability]) + return state.has(ability, world.player) + + +# a check to see if you can whack things in melee at all +def has_melee(state: CollectionState, player: int) -> bool: + return state.has_any(("Stick", "Sword", "Sword Upgrade"), player) + + +def has_sword(state: CollectionState, player: int) -> bool: + return state.has("Sword", player) or state.has("Sword Upgrade", player, 2) + + +def laurels_zip(state: CollectionState, world: "TunicWorld") -> bool: + return world.options.laurels_zips and state.has(laurels, world.player) + + +def has_ice_grapple_logic(long_range: bool, difficulty: IceGrappling, state: CollectionState, world: "TunicWorld") -> bool: + if world.options.ice_grappling < difficulty: + return False + if not long_range: + return state.has_all((ice_dagger, grapple), world.player) + else: + return state.has_all((ice_dagger, fire_wand, grapple), world.player) and has_ability(icebolt, state, world) + + +def can_ladder_storage(state: CollectionState, world: "TunicWorld") -> bool: + if not world.options.ladder_storage: + return False + if world.options.ladder_storage_without_items: + return True + return has_melee(state, world.player) or state.has_any((grapple, shield), world.player) + + +def has_mask(state: CollectionState, world: "TunicWorld") -> bool: + return world.options.maskless or state.has(mask, world.player) + + +def has_lantern(state: CollectionState, world: "TunicWorld") -> bool: + return world.options.lanternless or state.has(lantern, world.player) + + +def has_ladder(ladder: str, state: CollectionState, world: "TunicWorld") -> bool: + return not world.options.shuffle_ladders or state.has(ladder, world.player) + + +def can_shop(state: CollectionState, world: "TunicWorld") -> bool: + return has_sword(state, world.player) and state.can_reach_region("Shop", world.player) + + +# for the ones that are not early bushes where ER can screw you over a bit +def can_get_past_bushes(state: CollectionState, world: "TunicWorld") -> bool: + # add in glass cannon + stick for grass rando + return has_sword(state, world.player) or state.has_any((fire_wand, laurels, gun), world.player) + + +def has_fuses(fuse_event: str, state: CollectionState, world: "TunicWorld") -> bool: + player = world.player + fuses_option = False # replace fuses_option with world.options.shuffle_fuses when fuse shuffle is in + if fuses_option: + return state.has_all(fuse_activation_reqs[fuse_event], player) + + return state.has(fuse_event, player) diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index 09e2d1d604ca..79bb033b05a0 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -1,12 +1,13 @@ -import logging from dataclasses import dataclass -from typing import Dict, Any, TYPE_CHECKING - from decimal import Decimal, ROUND_HALF_UP +import logging +from typing import Any, TYPE_CHECKING from Options import (DefaultOnToggle, Toggle, StartInventoryPool, Choice, Range, TextChoice, PlandoConnections, PerGameCommonOptions, OptionGroup, Removed, Visibility, NamedRange) + from .er_data import portal_mapping + if TYPE_CHECKING: from . import TunicWorld @@ -145,17 +146,6 @@ class EntranceRando(TextChoice): default = 0 -class FixedShop(Toggle): - """ - This option has been superseded by the Entrance Layout option. - If enabled, it will override the Entrance Layout option. - This is kept to keep older yamls working, and will be removed at a later date. - """ - visibility = Visibility.none - internal_name = "fixed_shop" - display_name = "Fewer Shops in Entrance Rando" - - class EntranceLayout(Choice): """ Decide how the Entrance Randomizer chooses how to pair the entrances. @@ -219,8 +209,8 @@ class GrassRandomizer(Toggle): class LocalFill(NamedRange): """ Choose the percentage of your filler/trap items that will be kept local or distributed to other TUNIC players with this option enabled. + This option defaults to 95% if you have Grass Randomizer enabled, 40% if you have Breakable Shuffle enabled, 96% if you have both, and 0% otherwise. If you have Grass Randomizer enabled, this option must be set to 95% or higher to avoid flooding the item pool. The host can remove this restriction by turning off the limit_grass_rando setting in host.yaml. - This option defaults to 95% if you have Grass Randomizer enabled, and to 0% otherwise. This option ignores items placed in your local_items or non_local_items. This option does nothing in single player games. """ @@ -332,6 +322,14 @@ class LadderStorageWithoutItems(Toggle): display_name = "Ladder Storage without Items" +class BreakableShuffle(Toggle): + """ + Turns approximately 250 breakable objects in the game into checks. + """ + internal_name = "breakable_shuffle" + display_name = "Breakable Shuffle" + + class HiddenAllRandom(Toggle): """ Sets all options that can be random to random. @@ -342,36 +340,9 @@ class HiddenAllRandom(Toggle): visibility = Visibility.none -class LogicRules(Choice): - """ - This option has been superseded by the individual trick options. - If set to nmg, it will set Ice Grappling to medium and Laurels Zips on. - If set to ur, it will do nmg as well as set Ladder Storage to medium. - It is here to avoid breaking old yamls, and will be removed at a later date. - """ - visibility = Visibility.none - internal_name = "logic_rules" - display_name = "Logic Rules" - option_restricted = 0 - option_no_major_glitches = 1 - alias_nmg = 1 - option_unrestricted = 2 - alias_ur = 2 - default = 0 - - -class BreakableShuffle(Toggle): - """ - Turns approximately 250 breakable objects in the game into checks. - """ - internal_name = "breakable_shuffle" - display_name = "Breakable Shuffle" - - @dataclass class TunicOptions(PerGameCommonOptions): start_inventory_from_pool: StartInventoryPool - sword_progression: SwordProgression start_with_sword: StartWithSword keys_behind_bosses: KeysBehindBosses @@ -386,6 +357,8 @@ class TunicOptions(PerGameCommonOptions): hexagon_quest_ability_type: HexagonQuestAbilityUnlockType shuffle_ladders: ShuffleLadders + # shuffle_fuses: ShuffleFuses + # shuffle_bells: ShuffleBells grass_randomizer: GrassRandomizer breakable_shuffle: BreakableShuffle local_fill: LocalFill @@ -393,7 +366,6 @@ class TunicOptions(PerGameCommonOptions): entrance_rando: EntranceRando entrance_layout: EntranceLayout decoupled: Decoupled - plando_connections: TunicPlandoConnections combat_logic: CombatLogic lanternless: Lanternless @@ -402,11 +374,13 @@ class TunicOptions(PerGameCommonOptions): ice_grappling: IceGrappling ladder_storage: LadderStorage ladder_storage_without_items: LadderStorageWithoutItems - + + plando_connections: TunicPlandoConnections + all_random: HiddenAllRandom - fixed_shop: FixedShop # will be removed at a later date - logic_rules: Removed # fully removed in the direction pairs update + fixed_shop: Removed + logic_rules: Removed tunic_option_groups = [ @@ -433,7 +407,7 @@ class TunicOptions(PerGameCommonOptions): ]), ] -tunic_option_presets: Dict[str, Dict[str, Any]] = { +tunic_option_presets: dict[str, dict[str, Any]] = { "Sync": { "ability_shuffling": True, }, @@ -460,14 +434,16 @@ class TunicOptions(PerGameCommonOptions): def check_options(world: "TunicWorld"): options = world.options - if options.hexagon_quest and options.ability_shuffling and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: + if (options.hexagon_quest and options.ability_shuffling + and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons): total_hexes = get_hexagons_in_pool(world) min_hexes = 3 if options.keys_behind_bosses: min_hexes = 15 if total_hexes < min_hexes: - logging.warning(f"TUNIC: Not enough Gold Hexagons in {world.player_name}'s item pool for Hexagon Ability Shuffle with the selected options. Ability Shuffle mode will be switched to Pages.") + logging.warning(f"TUNIC: Not enough Gold Hexagons in {world.player_name}'s item pool for Hexagon Ability " + "Shuffle with the selected options. Ability Shuffle mode will be switched to Pages.") options.hexagon_quest_ability_type.value = HexagonQuestAbilityUnlockType.option_pages @@ -475,4 +451,4 @@ def get_hexagons_in_pool(world: "TunicWorld"): # Calculate number of hexagons in item pool options = world.options return min(int((Decimal(100 + options.extra_hexagon_percentage) / 100 * options.hexagon_goal) - .to_integral_value(rounding=ROUND_HALF_UP)), 100) + .to_integral_value(rounding=ROUND_HALF_UP)), 100) diff --git a/worlds/tunic/regions.py b/worlds/tunic/regions.py deleted file mode 100644 index f21af11ee49d..000000000000 --- a/worlds/tunic/regions.py +++ /dev/null @@ -1,25 +0,0 @@ -tunic_regions: dict[str, tuple[str]] = { - "Menu": ("Overworld",), - "Overworld": ("Overworld Holy Cross", "East Forest", "Dark Tomb", "Beneath the Well", "West Garden", - "Ruined Atoll", "Eastern Vault Fortress", "Beneath the Vault", "Quarry Back", "Quarry", "Swamp", - "Spirit Arena"), - "Overworld Holy Cross": tuple(), - "East Forest": tuple(), - "Dark Tomb": ("West Garden",), - "Beneath the Well": tuple(), - "West Garden": tuple(), - "Ruined Atoll": ("Frog's Domain", "Library"), - "Frog's Domain": tuple(), - "Library": tuple(), - "Eastern Vault Fortress": ("Beneath the Vault",), - "Beneath the Vault": ("Eastern Vault Fortress",), - "Quarry Back": ("Quarry", "Monastery"), - "Quarry": ("Monastery", "Lower Quarry"), - "Monastery": ("Monastery Back",), - "Monastery Back": tuple(), - "Lower Quarry": ("Rooted Ziggurat",), - "Rooted Ziggurat": tuple(), - "Swamp": ("Cathedral",), - "Cathedral": tuple(), - "Spirit Arena": tuple() -} diff --git a/worlds/tunic/rules.py b/worlds/tunic/rules.py deleted file mode 100644 index 52d5c42e5115..000000000000 --- a/worlds/tunic/rules.py +++ /dev/null @@ -1,402 +0,0 @@ -from typing import Dict, TYPE_CHECKING - -from worlds.generic.Rules import set_rule, forbid_item, add_rule -from BaseClasses import CollectionState -from .options import LadderStorage, IceGrappling, HexagonQuestAbilityUnlockType -if TYPE_CHECKING: - from . import TunicWorld - -laurels = "Hero's Laurels" -grapple = "Magic Orb" -ice_dagger = "Magic Dagger" -fire_wand = "Magic Wand" -gun = "Gun" -lantern = "Lantern" -fairies = "Fairy" -coins = "Golden Coin" -prayer = "Pages 24-25 (Prayer)" -holy_cross = "Pages 42-43 (Holy Cross)" -icebolt = "Pages 52-53 (Icebolt)" -shield = "Shield" -key = "Key" -house_key = "Old House Key" -vault_key = "Fortress Vault Key" -mask = "Scavenger Mask" -red_hexagon = "Red Questagon" -green_hexagon = "Green Questagon" -blue_hexagon = "Blue Questagon" -gold_hexagon = "Gold Questagon" - -# "Quarry - [East] Bombable Wall" is excluded from this list since it has slightly different rules -bomb_walls = ["East Forest - Bombable Wall", "Eastern Vault Fortress - [East Wing] Bombable Wall", - "Overworld - [Central] Bombable Wall", "Overworld - [Southwest] Bombable Wall Near Fountain", - "Quarry - [West] Upper Area Bombable Wall", "Ruined Atoll - [Northwest] Bombable Wall"] - - -def randomize_ability_unlocks(world: "TunicWorld") -> Dict[str, int]: - random = world.random - options = world.options - - abilities = [prayer, holy_cross, icebolt] - ability_requirement = [1, 1, 1] - random.shuffle(abilities) - - if options.hexagon_quest.value and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: - hexagon_goal = options.hexagon_goal.value - # Set ability unlocks to 25, 50, and 75% of goal amount - ability_requirement = [hexagon_goal // 4, hexagon_goal // 2, hexagon_goal * 3 // 4] - if any(req == 0 for req in ability_requirement): - ability_requirement = [1, 2, 3] - - return dict(zip(abilities, ability_requirement)) - - -def has_ability(ability: str, state: CollectionState, world: "TunicWorld") -> bool: - options = world.options - ability_unlocks = world.ability_unlocks - if not options.ability_shuffling: - return True - if options.hexagon_quest and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: - return state.has(gold_hexagon, world.player, ability_unlocks[ability]) - return state.has(ability, world.player) - - -# a check to see if you can whack things in melee at all -def has_melee(state: CollectionState, player: int) -> bool: - return state.has_any({"Stick", "Sword", "Sword Upgrade"}, player) - - -def has_sword(state: CollectionState, player: int) -> bool: - return state.has("Sword", player) or state.has("Sword Upgrade", player, 2) - - -def laurels_zip(state: CollectionState, world: "TunicWorld") -> bool: - return world.options.laurels_zips and state.has(laurels, world.player) - - -def has_ice_grapple_logic(long_range: bool, difficulty: IceGrappling, state: CollectionState, world: "TunicWorld") -> bool: - if world.options.ice_grappling < difficulty: - return False - if not long_range: - return state.has_all({ice_dagger, grapple}, world.player) - else: - return state.has_all({ice_dagger, fire_wand, grapple}, world.player) and has_ability(icebolt, state, world) - - -def can_ladder_storage(state: CollectionState, world: "TunicWorld") -> bool: - if not world.options.ladder_storage: - return False - if world.options.ladder_storage_without_items: - return True - return has_melee(state, world.player) or state.has_any((grapple, shield), world.player) - - -def has_mask(state: CollectionState, world: "TunicWorld") -> bool: - return world.options.maskless or state.has(mask, world.player) - - -def has_lantern(state: CollectionState, world: "TunicWorld") -> bool: - return world.options.lanternless or state.has(lantern, world.player) - - -def set_region_rules(world: "TunicWorld") -> None: - player = world.player - options = world.options - - world.get_entrance("Overworld -> Overworld Holy Cross").access_rule = \ - lambda state: has_ability(holy_cross, state, world) - world.get_entrance("Overworld -> Beneath the Well").access_rule = \ - lambda state: has_melee(state, player) or state.has(fire_wand, player) - world.get_entrance("Overworld -> Dark Tomb").access_rule = \ - lambda state: has_lantern(state, world) - # laurels in, ladder storage in through the furnace, or ice grapple down the belltower - world.get_entrance("Overworld -> West Garden").access_rule = \ - lambda state: (state.has(laurels, player) - or can_ladder_storage(state, world) - or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world)) - world.get_entrance("Overworld -> Eastern Vault Fortress").access_rule = \ - lambda state: state.has(laurels, player) \ - or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world) \ - or can_ladder_storage(state, world) - # using laurels or ls to get in is covered by the -> Eastern Vault Fortress rules - world.get_entrance("Overworld -> Beneath the Vault").access_rule = \ - lambda state: (has_lantern(state, world) and has_ability(prayer, state, world) - # there's some boxes in the way - and (has_melee(state, player) or state.has_any((gun, grapple, fire_wand), player))) - world.get_entrance("Ruined Atoll -> Library").access_rule = \ - lambda state: (state.has_any({grapple, laurels}, player) and has_ability(prayer, state, world) - and (has_sword(state, player) or state.has_any((fire_wand, gun), player))) - world.get_entrance("Overworld -> Quarry").access_rule = \ - lambda state: (has_sword(state, player) or state.has(fire_wand, player)) \ - and (state.has_any({grapple, laurels, gun}, player) or can_ladder_storage(state, world)) - world.get_entrance("Quarry Back -> Quarry").access_rule = \ - lambda state: has_sword(state, player) or state.has(fire_wand, player) - world.get_entrance("Quarry Back -> Monastery").access_rule = \ - lambda state: state.has(laurels, player) - world.get_entrance("Monastery -> Monastery Back").access_rule = \ - lambda state: (has_sword(state, player) or state.has(fire_wand, player) - or laurels_zip(state, world)) - world.get_entrance("Quarry -> Lower Quarry").access_rule = \ - lambda state: has_mask(state, world) - world.get_entrance("Lower Quarry -> Rooted Ziggurat").access_rule = \ - lambda state: state.has(grapple, player) and has_ability(prayer, state, world) - world.get_entrance("Swamp -> Cathedral").access_rule = \ - lambda state: (state.has(laurels, player) and has_ability(prayer, state, world) and has_sword(state, player)) \ - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world) - world.get_entrance("Overworld -> Spirit Arena").access_rule = \ - lambda state: ((state.has(gold_hexagon, player, options.hexagon_goal.value) if options.hexagon_quest.value - else state.has_all({red_hexagon, green_hexagon, blue_hexagon}, player) - and state.has_group_unique("Hero Relics", player, 6)) - and has_ability(prayer, state, world) and has_sword(state, player) - and state.has_any({lantern, laurels}, player)) - - world.get_region("Quarry").connect(world.get_region("Rooted Ziggurat"), - rule=lambda state: has_ice_grapple_logic(True, IceGrappling.option_hard, state, world) - and has_ability(prayer, state, world)) - - if options.ladder_storage >= LadderStorage.option_medium: - # ls at any ladder in a safe spot in quarry to get to the monastery rope entrance - add_rule(world.get_entrance(entrance_name="Quarry Back -> Monastery"), - rule=lambda state: can_ladder_storage(state, world)) - - -def set_location_rules(world: "TunicWorld") -> None: - player = world.player - - forbid_item(world.get_location("Secret Gathering Place - 20 Fairy Reward"), fairies, player) - - # Ability Shuffle Exclusive Rules - set_rule(world.get_location("Far Shore - Page Pickup"), - lambda state: has_ability(prayer, state, world)) - set_rule(world.get_location("Fortress Courtyard - Chest Near Cave"), - lambda state: has_ability(prayer, state, world) - or state.has(laurels, player) - or can_ladder_storage(state, world) - or (has_ice_grapple_logic(True, IceGrappling.option_easy, state, world) - and has_lantern(state, world))) - set_rule(world.get_location("Fortress Courtyard - Page Near Cave"), - lambda state: has_ability(prayer, state, world) or state.has(laurels, player) - or can_ladder_storage(state, world) - or (has_ice_grapple_logic(True, IceGrappling.option_easy, state, world) - and has_lantern(state, world))) - set_rule(world.get_location("East Forest - Dancing Fox Spirit Holy Cross"), - lambda state: has_ability(holy_cross, state, world)) - set_rule(world.get_location("Forest Grave Path - Holy Cross Code by Grave"), - lambda state: has_ability(holy_cross, state, world)) - set_rule(world.get_location("East Forest - Golden Obelisk Holy Cross"), - lambda state: has_ability(holy_cross, state, world)) - set_rule(world.get_location("Beneath the Well - [Powered Secret Room] Chest"), - lambda state: has_ability(prayer, state, world)) - set_rule(world.get_location("West Garden - [North] Behind Holy Cross Door"), - lambda state: has_ability(holy_cross, state, world)) - set_rule(world.get_location("Library Hall - Holy Cross Chest"), - lambda state: has_ability(holy_cross, state, world)) - set_rule(world.get_location("Eastern Vault Fortress - [West Wing] Candles Holy Cross"), - lambda state: has_ability(holy_cross, state, world)) - set_rule(world.get_location("West Garden - [Central Highlands] Holy Cross (Blue Lines)"), - lambda state: has_ability(holy_cross, state, world)) - set_rule(world.get_location("Quarry - [Back Entrance] Bushes Holy Cross"), - lambda state: has_ability(holy_cross, state, world)) - set_rule(world.get_location("Cathedral - Secret Legend Trophy Chest"), - lambda state: has_ability(holy_cross, state, world)) - - # Overworld - set_rule(world.get_location("Overworld - [Southwest] Fountain Page"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("Overworld - [Southwest] Grapple Chest Over Walkway"), - lambda state: state.has_any({grapple, laurels}, player)) - set_rule(world.get_location("Overworld - [Southwest] West Beach Guarded By Turret 2"), - lambda state: state.has_any({grapple, laurels}, player)) - set_rule(world.get_location("Far Shore - Secret Chest"), - lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(world.get_location("Overworld - [Southeast] Page on Pillar by Swamp"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("Old House - Normal Chest"), - lambda state: state.has(house_key, player) - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world) - or laurels_zip(state, world)) - set_rule(world.get_location("Old House - Holy Cross Chest"), - lambda state: has_ability(holy_cross, state, world) and ( - state.has(house_key, player) - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world) - or laurels_zip(state, world))) - set_rule(world.get_location("Old House - Shield Pickup"), - lambda state: state.has(house_key, player) - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world) - or laurels_zip(state, world)) - set_rule(world.get_location("Overworld - [Northwest] Page on Pillar by Dark Tomb"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("Overworld - [Southwest] From West Garden"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("Overworld - [West] Chest After Bell"), - lambda state: state.has(laurels, player) - or (has_lantern(state, world) and has_sword(state, player)) - or can_ladder_storage(state, world)) - set_rule(world.get_location("Overworld - [Northwest] Chest Beneath Quarry Gate"), - lambda state: state.has_any({grapple, laurels}, player)) - set_rule(world.get_location("Overworld - [East] Grapple Chest"), - lambda state: state.has(grapple, player)) - set_rule(world.get_location("Special Shop - Secret Page Pickup"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("Sealed Temple - Holy Cross Chest"), - lambda state: has_ability(holy_cross, state, world) - and (state.has(laurels, player) or (has_lantern(state, world) and (has_sword(state, player) - or state.has(fire_wand, player))) - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))) - set_rule(world.get_location("Sealed Temple - Page Pickup"), - lambda state: state.has(laurels, player) - or (has_lantern(state, world) and (has_sword(state, player) or state.has(fire_wand, player))) - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) - set_rule(world.get_location("West Furnace - Lantern Pickup"), - lambda state: has_melee(state, player) or state.has_any({fire_wand, laurels}, player)) - - set_rule(world.get_location("Secret Gathering Place - 10 Fairy Reward"), - lambda state: state.has(fairies, player, 10)) - set_rule(world.get_location("Secret Gathering Place - 20 Fairy Reward"), - lambda state: state.has(fairies, player, 20)) - set_rule(world.get_location("Coins in the Well - 3 Coins"), - lambda state: state.has(coins, player, 3)) - set_rule(world.get_location("Coins in the Well - 6 Coins"), - lambda state: state.has(coins, player, 6)) - set_rule(world.get_location("Coins in the Well - 10 Coins"), - lambda state: state.has(coins, player, 10)) - set_rule(world.get_location("Coins in the Well - 15 Coins"), - lambda state: state.has(coins, player, 15)) - - # East Forest - set_rule(world.get_location("East Forest - Lower Grapple Chest"), - lambda state: state.has(grapple, player)) - set_rule(world.get_location("East Forest - Lower Dash Chest"), - lambda state: state.has_all({grapple, laurels}, player)) - set_rule(world.get_location("East Forest - Ice Rod Grapple Chest"), - lambda state: state.has_all({grapple, ice_dagger, fire_wand}, player) - and has_ability(icebolt, state, world)) - - # West Garden - set_rule(world.get_location("West Garden - [North] Across From Page Pickup"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("West Garden - [West] In Flooded Walkway"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("West Garden - [West Lowlands] Tree Holy Cross Chest"), - lambda state: state.has(laurels, player) and has_ability(holy_cross, state, world)) - set_rule(world.get_location("West Garden - [East Lowlands] Page Behind Ice Dagger House"), - lambda state: (state.has(laurels, player) and has_ability(prayer, state, world)) - or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world)) - set_rule(world.get_location("West Garden - [Central Lowlands] Below Left Walkway"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("West Garden - [Central Highlands] After Garden Knight"), - lambda state: state.has(laurels, player) - or (has_lantern(state, world) and has_sword(state, player)) - or can_ladder_storage(state, world)) - - # Ruined Atoll - set_rule(world.get_location("Ruined Atoll - [West] Near Kevin Block"), - lambda state: state.has(laurels, player)) - # ice grapple push a crab through the door - set_rule(world.get_location("Ruined Atoll - [East] Locked Room Lower Chest"), - lambda state: state.has(laurels, player) or state.has(key, player, 2) - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) - set_rule(world.get_location("Ruined Atoll - [East] Locked Room Upper Chest"), - lambda state: state.has(laurels, player) or state.has(key, player, 2) - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) - set_rule(world.get_location("Librarian - Hexagon Green"), - lambda state: has_sword(state, player)) - - # Frog's Domain - set_rule(world.get_location("Frog's Domain - Side Room Grapple Secret"), - lambda state: state.has_any({grapple, laurels}, player)) - set_rule(world.get_location("Frog's Domain - Grapple Above Hot Tub"), - lambda state: state.has_any({grapple, laurels}, player)) - set_rule(world.get_location("Frog's Domain - Escape Chest"), - lambda state: state.has_any({grapple, laurels}, player)) - - # Library Lab - set_rule(world.get_location("Library Lab - Page 1"), - lambda state: has_melee(state, player) or state.has_any((fire_wand, gun), player)) - set_rule(world.get_location("Library Lab - Page 2"), - lambda state: has_melee(state, player) or state.has_any((fire_wand, gun), player)) - set_rule(world.get_location("Library Lab - Page 3"), - lambda state: has_melee(state, player) or state.has_any((fire_wand, gun), player)) - - # Eastern Vault Fortress - # yes, you can clear the leaves with dagger - # gun isn't included since it can only break one leaf pile at a time, and we don't check how much mana you have - # but really, I expect the player to just throw a bomb at them if they don't have melee - set_rule(world.get_location("Fortress Leaf Piles - Secret Chest"), - lambda state: state.has(laurels, player) and (has_melee(state, player) or state.has(ice_dagger, player))) - set_rule(world.get_location("Fortress Arena - Siege Engine/Vault Key Pickup"), - lambda state: has_sword(state, player) - and (has_ability(prayer, state, world) - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))) - set_rule(world.get_location("Fortress Arena - Hexagon Red"), - lambda state: state.has(vault_key, player) - and (has_ability(prayer, state, world) - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))) - - # Beneath the Vault - set_rule(world.get_location("Beneath the Fortress - Bridge"), - lambda state: has_lantern(state, world) and - (has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player))) - set_rule(world.get_location("Beneath the Fortress - Obscured Behind Waterfall"), - lambda state: has_melee(state, player) and has_lantern(state, world)) - - # Quarry - set_rule(world.get_location("Quarry - [Central] Above Ladder Dash Chest"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("Rooted Ziggurat Upper - Near Bridge Switch"), - lambda state: has_sword(state, player) or state.has_all({fire_wand, laurels}, player)) - set_rule(world.get_location("Rooted Ziggurat Lower - Hexagon Blue"), - lambda state: has_sword(state, player)) - - # Swamp - set_rule(world.get_location("Cathedral Gauntlet - Gauntlet Reward"), - lambda state: (state.has(fire_wand, player) and has_sword(state, player)) - and (state.has(laurels, player) - or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))) - set_rule(world.get_location("Swamp - [Entrance] Above Entryway"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("Swamp - [South Graveyard] Upper Walkway Dash Chest"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("Swamp - [Outside Cathedral] Obscured Behind Memorial"), - lambda state: state.has(laurels, player)) - set_rule(world.get_location("Swamp - [South Graveyard] 4 Orange Skulls"), - lambda state: has_sword(state, player)) - - # Hero's Grave - set_rule(world.get_location("Hero's Grave - Tooth Relic"), - lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(world.get_location("Hero's Grave - Mushroom Relic"), - lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(world.get_location("Hero's Grave - Ash Relic"), - lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(world.get_location("Hero's Grave - Flowers Relic"), - lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(world.get_location("Hero's Grave - Effigy Relic"), - lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(world.get_location("Hero's Grave - Feathers Relic"), - lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - - # Bombable Walls - for location_name in bomb_walls: - # has_sword is there because you can buy bombs in the shop - set_rule(world.get_location(location_name), - lambda state: state.has(gun, player) - or has_sword(state, player) - or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world)) - add_rule(world.get_location("Cube Cave - Holy Cross Chest"), - lambda state: state.has(gun, player) - or has_sword(state, player) - or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world)) - # can't ice grapple to this one, not enough space - set_rule(world.get_location("Quarry - [East] Bombable Wall"), - lambda state: state.has(gun, player) or has_sword(state, player)) - - # Shop - set_rule(world.get_location("Shop - Potion 1"), - lambda state: has_sword(state, player)) - set_rule(world.get_location("Shop - Potion 2"), - lambda state: has_sword(state, player)) - set_rule(world.get_location("Shop - Coin 1"), - lambda state: has_sword(state, player)) - set_rule(world.get_location("Shop - Coin 2"), - lambda state: has_sword(state, player)) diff --git a/worlds/tunic/test/test_access.py b/worlds/tunic/test/test_access.py index 1896db5d132a..f5d429ac73db 100644 --- a/worlds/tunic/test/test_access.py +++ b/worlds/tunic/test/test_access.py @@ -5,13 +5,6 @@ class TestAccess(TunicTestBase): options = {options.CombatLogic.internal_name: options.CombatLogic.option_off} - # test whether you can get into the temple without laurels - def test_temple_access(self) -> None: - self.collect_all_but(["Hero's Laurels", "Lantern"]) - self.assertFalse(self.can_reach_location("Sealed Temple - Page Pickup")) - self.collect_by_name(["Lantern"]) - self.assertTrue(self.can_reach_location("Sealed Temple - Page Pickup")) - # test that the wells function properly. Since fairies is written the same way, that should succeed too def test_wells(self) -> None: self.collect_all_but(["Golden Coin"]) @@ -50,22 +43,12 @@ def test_hc_door_no_shuffle(self) -> None: self.assertTrue(self.can_reach_location("Fountain Cross Door - Page Pickup")) -class TestNormalGoal(TunicTestBase): - options = {options.HexagonQuest.internal_name: options.HexagonQuest.option_false} - - # test that you need the three colored hexes to reach the Heir in standard - def test_normal_goal(self) -> None: - location = ["The Heir"] - items = [["Red Questagon", "Blue Questagon", "Green Questagon"]] - self.assertAccessDependency(location, items) - - class TestER(TunicTestBase): options = {options.EntranceRando.internal_name: options.EntranceRando.option_yes, options.AbilityShuffling.internal_name: options.AbilityShuffling.option_true, options.HexagonQuest.internal_name: options.HexagonQuest.option_false, options.CombatLogic.internal_name: options.CombatLogic.option_off, - options.FixedShop.internal_name: options.FixedShop.option_true} + options.EntranceLayout.internal_name: options.EntranceLayout.option_fixed_shop} def test_overworld_hc_chest(self) -> None: # test to see that static connections are working properly -- this chest requires holy cross and is in Overworld @@ -99,7 +82,7 @@ class TestLadderStorage(TunicTestBase): options = {options.EntranceRando.internal_name: options.EntranceRando.option_yes, options.AbilityShuffling.internal_name: options.AbilityShuffling.option_true, options.HexagonQuest.internal_name: options.HexagonQuest.option_false, - options.FixedShop.internal_name: options.FixedShop.option_false, + options.EntranceLayout.internal_name: options.EntranceLayout.option_standard, options.LadderStorage.internal_name: options.LadderStorage.option_hard, options.LadderStorageWithoutItems.internal_name: options.LadderStorageWithoutItems.option_false, "plando_connections": [ From ef59a5ee11d63f673da3860e68ec9fcc1fde42ab Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Thu, 4 Sep 2025 19:04:21 -0400 Subject: [PATCH 0697/1218] TUNIC: Change non_local_items Earlier (#5249) --- worlds/tunic/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index db0357daaf27..9fca0a7d59f6 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -208,6 +208,10 @@ def replace_connection(old_cxn: PlandoConnection, new_cxn: PlandoConnection, ind else: self.options.local_fill.value = 0 + if self.options.local_fill > 0 and self.settings.limit_grass_rando: + # discard grass from non_local if it's meant to be limited + self.options.non_local_items.value.discard("Grass") + if self.options.grass_randomizer: if self.settings.limit_grass_rando and self.options.local_fill < 95 and self.multiworld.players > 1: raise OptionError(f"TUNIC: Player {self.player_name} has their Local Fill option set too low. " @@ -477,9 +481,6 @@ def remove_filler(amount: int) -> None: self.fill_items = [] if self.options.local_fill > 0 and self.multiworld.players > 1: # skip items marked local or non-local, let fill deal with them in its own way - # discard grass from non_local if it's meant to be limited - if self.settings.limit_grass_rando: - self.options.non_local_items.value.discard("Grass") all_filler: list[TunicItem] = [] non_filler: list[TunicItem] = [] for tunic_item in tunic_items: From 5b5e2c356723786b8b2df3ac69eac917cc79251b Mon Sep 17 00:00:00 2001 From: Kaito Sinclaire Date: Fri, 5 Sep 2025 07:21:08 -0700 Subject: [PATCH 0698/1218] SMZ3: Fix distribution of SM prizes (#5303) --- worlds/smz3/TotalSMZ3/WorldState.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/worlds/smz3/TotalSMZ3/WorldState.py b/worlds/smz3/TotalSMZ3/WorldState.py index bbffffa10739..8b2b56470ca4 100644 --- a/worlds/smz3/TotalSMZ3/WorldState.py +++ b/worlds/smz3/TotalSMZ3/WorldState.py @@ -1,6 +1,5 @@ from enum import Enum from typing import List -from copy import copy from .Patch import DropPrize from .Region import RewardType @@ -91,7 +90,11 @@ def __init__(self, distribution = None, boss = None, blue = None, red = None, pe self.Green = 1 if (distribution is not None): - self = copy(distribution) + self.Boss = distribution.Boss + self.Blue = distribution.Blue + self.Red = distribution.Red + self.Pend = distribution.Pend + self.Green = distribution.Green if (boss is not None): self.Boss = boss if (blue is not None): @@ -111,11 +114,11 @@ def Hit(self, p): p -= self.Boss if (p < 0): return (RewardType.AnyBossToken, WorldState.Distribution(self, boss = self.Boss - WorldState.Distribution.factor)) p -= self.Blue - if (p - self.Blue < 0): return (RewardType.CrystalBlue, WorldState.Distribution(self, blue = self.Blue - WorldState.Distribution.factor)) + if (p < 0): return (RewardType.CrystalBlue, WorldState.Distribution(self, blue = self.Blue - WorldState.Distribution.factor)) p -= self.Red - if (p - self.Red < 0): return (RewardType.CrystalRed, WorldState.Distribution(self, red = self.Red - WorldState.Distribution.factor)) + if (p < 0): return (RewardType.CrystalRed, WorldState.Distribution(self, red = self.Red - WorldState.Distribution.factor)) p -= self.Pend - if (p - self.Pend < 0): return (RewardType.PendantNonGreen, WorldState.Distribution(self, pend = self.Pend - 1)) + if (p < 0): return (RewardType.PendantNonGreen, WorldState.Distribution(self, pend = self.Pend - 1)) return (RewardType.PendantGreen, WorldState.Distribution(self, green = self.Green - 1)) def Generate(self, func): From 89be26a33a1209fe1cfdd1ada916e94459070dec Mon Sep 17 00:00:00 2001 From: Kaito Sinclaire Date: Fri, 5 Sep 2025 07:22:11 -0700 Subject: [PATCH 0699/1218] Heretic: Update Steam URL (#5304) --- worlds/heretic/docs/setup_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/heretic/docs/setup_en.md b/worlds/heretic/docs/setup_en.md index 5985dbb0992a..5475a00f90e7 100644 --- a/worlds/heretic/docs/setup_en.md +++ b/worlds/heretic/docs/setup_en.md @@ -2,7 +2,7 @@ ## Required Software -- [Heretic (e.g. Steam version)](https://store.steampowered.com/app/2390/Heretic_Shadow_of_the_Serpent_Riders/) +- [Heretic (e.g. Steam version)](https://store.steampowered.com/app/3286930/Heretic__Hexen/) - [Archipelago Crispy DOOM](https://github.com/Daivuk/apdoom/releases) (Same download for DOOM 1993, DOOM II and Heretic) ## Optional Software From 64d3c55d6277a5d1f7d051b8b4abd57b3abf406b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Fri, 5 Sep 2025 10:23:25 -0400 Subject: [PATCH 0700/1218] Stardew Valley: Add money logic to traveling merchant (#5327) * add rule to traveling merchant region * add a test so kaito is happy --- worlds/stardew_valley/rules.py | 2 +- .../test/rules/TestTravelingMerchant.py | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 worlds/stardew_valley/test/rules/TestTravelingMerchant.py diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index 2b7eec99607c..2fb95a98f62d 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -206,7 +206,7 @@ def set_entrance_rules(logic: StardewLogic, multiworld, player, world_options: S set_entrance_rule(multiworld, player, Entrance.enter_skull_cavern, logic.received(Wallet.skull_key)) set_entrance_rule(multiworld, player, LogicEntrance.talk_to_mines_dwarf, logic.wallet.can_speak_dwarf() & logic.tool.has_tool(Tool.pickaxe, ToolMaterial.iron)) - set_entrance_rule(multiworld, player, LogicEntrance.buy_from_traveling_merchant, logic.traveling_merchant.has_days()) + set_entrance_rule(multiworld, player, LogicEntrance.buy_from_traveling_merchant, logic.traveling_merchant.has_days() & logic.money.can_spend(1000)) set_entrance_rule(multiworld, player, LogicEntrance.buy_from_raccoon, logic.quest.has_raccoon_shop()) set_entrance_rule(multiworld, player, LogicEntrance.fish_in_waterfall, logic.skill.has_level(Skill.fishing, 5) & logic.tool.has_fishing_rod(2)) diff --git a/worlds/stardew_valley/test/rules/TestTravelingMerchant.py b/worlds/stardew_valley/test/rules/TestTravelingMerchant.py new file mode 100644 index 000000000000..57b88747909f --- /dev/null +++ b/worlds/stardew_valley/test/rules/TestTravelingMerchant.py @@ -0,0 +1,23 @@ +from ..bases import SVTestBase +from ...locations import location_table, LocationTags + + +class TestTravelingMerchant(SVTestBase): + + def test_purchase_from_traveling_merchant_requires_money(self): + traveling_merchant_location_names = [l for l in self.get_real_location_names() if LocationTags.TRAVELING_MERCHANT in location_table[l].tags] + + for traveling_merchant_day in ["Traveling Merchant: Sunday", "Traveling Merchant: Monday", "Traveling Merchant: Tuesday", + "Traveling Merchant: Wednesday", "Traveling Merchant: Thursday", "Traveling Merchant: Friday", + "Traveling Merchant: Saturday"]: + self.collect(traveling_merchant_day) + + for location_name in traveling_merchant_location_names: + location = self.multiworld.get_location(location_name, 1) + self.assert_cannot_reach_location(location, self.multiworld.state) + + self.collect("Shipping Bin") + + for location_name in traveling_merchant_location_names: + location = self.multiworld.get_location(location_name, 1) + self.assert_can_reach_location(location, self.multiworld.state) From 7a38e44e648103b92044b008cb027fbb94c07fb9 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 5 Sep 2025 09:24:20 -0500 Subject: [PATCH 0701/1218] Test: Deprecate TestBase (#5339) * deprecate TestBase and fix the last use of it in main * actually delete it because test discovery also imports it lmao --- test/TestBase.py | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 test/TestBase.py diff --git a/test/TestBase.py b/test/TestBase.py deleted file mode 100644 index bfd92346d301..000000000000 --- a/test/TestBase.py +++ /dev/null @@ -1,3 +0,0 @@ -from .bases import TestBase, WorldTestBase -from warnings import warn -warn("TestBase was renamed to bases", DeprecationWarning) From e518e41f67766724647b7bfd28791810e87ff9cd Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Fri, 5 Sep 2025 10:34:57 -0400 Subject: [PATCH 0702/1218] Hollow Knight: Make the connecting header separate from the yaml one (#5353) * Update setup_en.md * Update setup_pt_br.md --- worlds/hk/docs/setup_en.md | 2 +- worlds/hk/docs/setup_pt_br.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/hk/docs/setup_en.md b/worlds/hk/docs/setup_en.md index 0375867d4059..d49a4002e4b7 100644 --- a/worlds/hk/docs/setup_en.md +++ b/worlds/hk/docs/setup_en.md @@ -42,7 +42,7 @@ See the [basic multiworld setup guide](/tutorial/Archipelago/setup/en) here on t You can use the [game options page for Hollow Knight](/games/Hollow%20Knight/player-options) here on the Archipelago website to generate a YAML using a graphical interface. -### Joining an Archipelago Game in Hollow Knight +## Joining an Archipelago Game in Hollow Knight 1. Start the game after installing all necessary mods. 2. Create a **new save game.** 3. Select the **Archipelago** game mode from the mode selection screen. diff --git a/worlds/hk/docs/setup_pt_br.md b/worlds/hk/docs/setup_pt_br.md index 511ee0d55293..14e54db1315c 100644 --- a/worlds/hk/docs/setup_pt_br.md +++ b/worlds/hk/docs/setup_pt_br.md @@ -36,7 +36,7 @@ Olhe o [guia de configuração básica de um multiworld](/tutorial/Archipelago/s Você pode usar a [página de configurações do jogador para Hollow Knight](/games/Hollow%20Knight/player-options) aqui no site do Archipelago para gerar o YAML usando a interface gráfica. -### Entrando numa partida de Archipelago no Hollow Knight +## Entrando numa partida de Archipelago no Hollow Knight 1. Começe o jogo depois de instalar todos os mods necessários. 2. Crie um **novo jogo salvo.** 3. Selecione o modo de jogo **Archipelago** do menu de seleção. From b9fb5c8b441b50bb843f8d8a3f5c565e60287f5d Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Fri, 5 Sep 2025 10:37:31 -0400 Subject: [PATCH 0703/1218] Super Mario Land 2: Remove erroneous Coinsanity checks #5364 Co-authored-by: alchav --- worlds/marioland2/locations.py | 2 +- worlds/marioland2/logic.py | 4 ---- worlds/marioland2/options.py | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/worlds/marioland2/locations.py b/worlds/marioland2/locations.py index 02ae1cca9dc5..8908b8d3be24 100644 --- a/worlds/marioland2/locations.py +++ b/worlds/marioland2/locations.py @@ -419,7 +419,7 @@ "Tree Zone Secret Course": [(17, 23), (100, 23), (159, 23)], "Tree Zone 3": [(26, 40), (77, 24)], "Tree Zone 4": [(28, 27), (105, 25), (136, 22), (171, 10)], - "Tree Zone 5": [(123, 39), (138, 39), (146, 36)], + "Tree Zone 5": [(23, 41), (116, 42), (123, 39), (138, 39), (146, 36)], "Pumpkin Zone 1": [(23, 12), (72, 27), (98, 4), (189, 6)], "Pumpkin Zone 2": [(144, 23)], "Pumpkin Zone Secret Course 1": [(14, 15)], diff --git a/worlds/marioland2/logic.py b/worlds/marioland2/logic.py index 9934535572f9..5405e8287739 100644 --- a/worlds/marioland2/logic.py +++ b/worlds/marioland2/logic.py @@ -135,10 +135,6 @@ def tree_zone_5_boss(state, player): def tree_zone_5_coins(state, player, coins): auto_scroll = is_auto_scroll(state, player, "Tree Zone 5") reachable_coins = 0 - # Not actually sure if these platforms can be randomized / can make the coin blocks unreachable from below - if ((not state.multiworld.worlds[player].options.randomize_platforms) - or state.has_any(["Mushroom", "Fire Flower"], player)): - reachable_coins += 2 if state.has_any(["Mushroom", "Fire Flower"], player): reachable_coins += 2 if state.has("Carrot", player): diff --git a/worlds/marioland2/options.py b/worlds/marioland2/options.py index ace8444b3fb6..dfe5d6a6b6a4 100644 --- a/worlds/marioland2/options.py +++ b/worlds/marioland2/options.py @@ -81,7 +81,7 @@ class CoinsanityChecks(Range): """ display_name = "Coinsanity Checks" range_start = 31 - range_end = 2599 + range_end = 2597 default = 150 From 0d26b6426f0391bc7fd962ff2d5c65b173a9b461 Mon Sep 17 00:00:00 2001 From: qwint Date: Fri, 5 Sep 2025 09:42:12 -0500 Subject: [PATCH 0704/1218] Core: Remove lttp module requirement from generation #5384 --- Generate.py | 37 ++++++++++----------------- Main.py | 2 +- WebHost.py | 2 +- WebHostLib/generate.py | 54 ++++++++++++++++++++------------------- WebHostLib/lttpsprites.py | 2 +- worlds/bumpstik/Items.py | 25 ++++++++++-------- worlds/meritous/Items.py | 17 +++++++----- 7 files changed, 69 insertions(+), 70 deletions(-) diff --git a/Generate.py b/Generate.py index f9607e328bc8..5d65a688c7af 100644 --- a/Generate.py +++ b/Generate.py @@ -166,19 +166,10 @@ def main(args=None) -> tuple[argparse.Namespace, int]: f"A mix is also permitted.") from worlds.AutoWorld import AutoWorldRegister - from worlds.alttp.EntranceRandomizer import parse_arguments - erargs = parse_arguments(['--multi', str(args.multi)]) - erargs.seed = seed - erargs.plando_options = args.plando - erargs.spoiler = args.spoiler - erargs.race = args.race - erargs.outputname = seed_name - erargs.outputpath = args.outputpath - erargs.skip_prog_balancing = args.skip_prog_balancing - erargs.skip_output = args.skip_output - erargs.spoiler_only = args.spoiler_only - erargs.name = {} - erargs.csv_output = args.csv_output + args.outputname = seed_name + args.sprite = dict.fromkeys(range(1, args.multi+1), None) + args.sprite_pool = dict.fromkeys(range(1, args.multi+1), None) + args.name = {} settings_cache: dict[str, tuple[argparse.Namespace, ...]] = \ {fname: (tuple(roll_settings(yaml, args.plando) for yaml in yamls) if args.sameoptions else None) @@ -205,7 +196,7 @@ def main(args=None) -> tuple[argparse.Namespace, int]: for player in range(1, args.multi + 1): player_path_cache[player] = player_files.get(player, args.weights_file_path) name_counter = Counter() - erargs.player_options = {} + args.player_options = {} player = 1 while player <= args.multi: @@ -218,21 +209,21 @@ def main(args=None) -> tuple[argparse.Namespace, int]: for k, v in vars(settingsObject).items(): if v is not None: try: - getattr(erargs, k)[player] = v + getattr(args, k)[player] = v except AttributeError: - setattr(erargs, k, {player: v}) + setattr(args, k, {player: v}) except Exception as e: raise Exception(f"Error setting {k} to {v} for player {player}") from e # name was not specified - if player not in erargs.name: + if player not in args.name: if path == args.weights_file_path: # weights file, so we need to make the name unique - erargs.name[player] = f"Player{player}" + args.name[player] = f"Player{player}" else: # use the filename - erargs.name[player] = os.path.splitext(os.path.split(path)[-1])[0] - erargs.name[player] = handle_name(erargs.name[player], player, name_counter) + args.name[player] = os.path.splitext(os.path.split(path)[-1])[0] + args.name[player] = handle_name(args.name[player], player, name_counter) player += 1 except Exception as e: @@ -240,10 +231,10 @@ def main(args=None) -> tuple[argparse.Namespace, int]: else: raise RuntimeError(f'No weights specified for player {player}') - if len(set(name.lower() for name in erargs.name.values())) != len(erargs.name): - raise Exception(f"Names have to be unique. Names: {Counter(name.lower() for name in erargs.name.values())}") + if len(set(name.lower() for name in args.name.values())) != len(args.name): + raise Exception(f"Names have to be unique. Names: {Counter(name.lower() for name in args.name.values())}") - return erargs, seed + return args, seed def read_weights_yamls(path) -> tuple[Any, ...]: diff --git a/Main.py b/Main.py index bc2787579fac..6d81ff23a034 100644 --- a/Main.py +++ b/Main.py @@ -37,7 +37,7 @@ def main(args, seed=None, baked_server_options: dict[str, object] | None = None) logger = logging.getLogger() multiworld.set_seed(seed, args.race, str(args.outputname) if args.outputname else None) - multiworld.plando_options = args.plando_options + multiworld.plando_options = args.plando multiworld.game = args.game.copy() multiworld.player_name = args.name.copy() multiworld.sprite = args.sprite.copy() diff --git a/WebHost.py b/WebHost.py index 946eaa116f01..fd8daeb371bd 100644 --- a/WebHost.py +++ b/WebHost.py @@ -99,11 +99,11 @@ def copy_tutorials_files_to_static() -> None: multiprocessing.set_start_method('spawn') logging.basicConfig(format='[%(asctime)s] %(message)s', level=logging.INFO) - from WebHostLib.lttpsprites import update_sprites_lttp from WebHostLib.autolauncher import autohost, autogen, stop from WebHostLib.options import create as create_options_files try: + from WebHostLib.lttpsprites import update_sprites_lttp update_sprites_lttp() except Exception as e: logging.exception(e) diff --git a/WebHostLib/generate.py b/WebHostLib/generate.py index 02f5a0379aa2..6ca8c1c8a15f 100644 --- a/WebHostLib/generate.py +++ b/WebHostLib/generate.py @@ -12,12 +12,11 @@ from pony.orm import commit, db_session from BaseClasses import get_seed, seeddigits -from Generate import PlandoOptions, handle_name +from Generate import PlandoOptions, handle_name, mystery_argparse from Main import main as ERmain from Utils import __version__, restricted_dumps from WebHostLib import app from settings import ServerOptions, GeneratorOptions -from worlds.alttp.EntranceRandomizer import parse_arguments from .check import get_yaml_data, roll_options from .models import Generation, STATE_ERROR, STATE_QUEUED, Seed, UUID from .upload import upload_zip_to_db @@ -129,36 +128,39 @@ def task(): seedname = "W" + (f"{random.randint(0, pow(10, seeddigits) - 1)}".zfill(seeddigits)) - erargs = parse_arguments(['--multi', str(playercount)]) - erargs.seed = seed - erargs.name = {x: "" for x in range(1, playercount + 1)} # only so it can be overwritten in mystery - erargs.spoiler = meta["generator_options"].get("spoiler", 0) - erargs.race = race - erargs.outputname = seedname - erargs.outputpath = target.name - erargs.teams = 1 - erargs.plando_options = PlandoOptions.from_set(meta.setdefault("plando_options", - {"bosses", "items", "connections", "texts"})) - erargs.skip_prog_balancing = False - erargs.skip_output = False - erargs.spoiler_only = False - erargs.csv_output = False + args = mystery_argparse() + args.multi = playercount + args.seed = seed + args.name = {x: "" for x in range(1, playercount + 1)} # only so it can be overwritten in mystery + args.spoiler = meta["generator_options"].get("spoiler", 0) + args.race = race + args.outputname = seedname + args.outputpath = target.name + args.teams = 1 + args.plando_options = PlandoOptions.from_set(meta.setdefault("plando_options", + {"bosses", "items", "connections", "texts"})) + args.skip_prog_balancing = False + args.skip_output = False + args.spoiler_only = False + args.csv_output = False + args.sprite = dict.fromkeys(range(1, args.multi+1), None) + args.sprite_pool = dict.fromkeys(range(1, args.multi+1), None) name_counter = Counter() for player, (playerfile, settings) in enumerate(gen_options.items(), 1): for k, v in settings.items(): if v is not None: - if hasattr(erargs, k): - getattr(erargs, k)[player] = v + if hasattr(args, k): + getattr(args, k)[player] = v else: - setattr(erargs, k, {player: v}) - - if not erargs.name[player]: - erargs.name[player] = os.path.splitext(os.path.split(playerfile)[-1])[0] - erargs.name[player] = handle_name(erargs.name[player], player, name_counter) - if len(set(erargs.name.values())) != len(erargs.name): - raise Exception(f"Names have to be unique. Names: {Counter(erargs.name.values())}") - ERmain(erargs, seed, baked_server_options=meta["server_options"]) + setattr(args, k, {player: v}) + + if not args.name[player]: + args.name[player] = os.path.splitext(os.path.split(playerfile)[-1])[0] + args.name[player] = handle_name(args.name[player], player, name_counter) + if len(set(args.name.values())) != len(args.name): + raise Exception(f"Names have to be unique. Names: {Counter(args.name.values())}") + ERmain(args, seed, baked_server_options=meta["server_options"]) return upload_to_db(target.name, sid, owner, race) thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=1) diff --git a/WebHostLib/lttpsprites.py b/WebHostLib/lttpsprites.py index 9d780b13e12a..3bf596db4804 100644 --- a/WebHostLib/lttpsprites.py +++ b/WebHostLib/lttpsprites.py @@ -3,10 +3,10 @@ import json from Utils import local_path, user_path -from worlds.alttp.Rom import Sprite def update_sprites_lttp(): + from worlds.alttp.Rom import Sprite from tkinter import Tk from LttPAdjuster import get_image_for_sprite from LttPAdjuster import BackgroundTaskProgress diff --git a/worlds/bumpstik/Items.py b/worlds/bumpstik/Items.py index c714b7432027..c78668f7edea 100644 --- a/worlds/bumpstik/Items.py +++ b/worlds/bumpstik/Items.py @@ -6,7 +6,6 @@ import typing from BaseClasses import Item, ItemClassification -from worlds.alttp import ALTTPWorld class BumpStikLttPText(typing.NamedTuple): @@ -117,13 +116,17 @@ def __init__(self, name, classification, code, player): item: offset + x for x, item in enumerate(LttPCreditsText.keys()) } -ALTTPWorld.pedestal_credit_texts.update({item_table[name]: f"and the {texts.pedestal}" - for name, texts in LttPCreditsText.items()}) -ALTTPWorld.sickkid_credit_texts.update( - {item_table[name]: texts.sickkid for name, texts in LttPCreditsText.items()}) -ALTTPWorld.magicshop_credit_texts.update( - {item_table[name]: texts.magicshop for name, texts in LttPCreditsText.items()}) -ALTTPWorld.zora_credit_texts.update( - {item_table[name]: texts.zora for name, texts in LttPCreditsText.items()}) -ALTTPWorld.fluteboy_credit_texts.update( - {item_table[name]: texts.fluteboy for name, texts in LttPCreditsText.items()}) +try: + from worlds.alttp import ALTTPWorld + ALTTPWorld.pedestal_credit_texts.update({item_table[name]: f"and the {texts.pedestal}" + for name, texts in LttPCreditsText.items()}) + ALTTPWorld.sickkid_credit_texts.update( + {item_table[name]: texts.sickkid for name, texts in LttPCreditsText.items()}) + ALTTPWorld.magicshop_credit_texts.update( + {item_table[name]: texts.magicshop for name, texts in LttPCreditsText.items()}) + ALTTPWorld.zora_credit_texts.update( + {item_table[name]: texts.zora for name, texts in LttPCreditsText.items()}) + ALTTPWorld.fluteboy_credit_texts.update( + {item_table[name]: texts.fluteboy for name, texts in LttPCreditsText.items()}) +except ModuleNotFoundError: + pass diff --git a/worlds/meritous/Items.py b/worlds/meritous/Items.py index 9f28c5d178f0..030c93ddeca0 100644 --- a/worlds/meritous/Items.py +++ b/worlds/meritous/Items.py @@ -6,7 +6,6 @@ import typing from BaseClasses import Item, ItemClassification -from worlds.alttp import ALTTPWorld class MeritousLttPText(typing.NamedTuple): @@ -206,9 +205,13 @@ def __init__(self, name, advancement, code, player): "Crystals": ["Crystals x500", "Crystals x1000", "Crystals x2000"] } -ALTTPWorld.pedestal_credit_texts.update({item_table[name]: f"and the {texts.pedestal}" - for name, texts in LttPCreditsText.items()}) -ALTTPWorld.sickkid_credit_texts.update({item_table[name]: texts.sickkid for name, texts in LttPCreditsText.items()}) -ALTTPWorld.magicshop_credit_texts.update({item_table[name]: texts.magicshop for name, texts in LttPCreditsText.items()}) -ALTTPWorld.zora_credit_texts.update({item_table[name]: texts.zora for name, texts in LttPCreditsText.items()}) -ALTTPWorld.fluteboy_credit_texts.update({item_table[name]: texts.fluteboy for name, texts in LttPCreditsText.items()}) +try: + from worlds.alttp import ALTTPWorld + ALTTPWorld.pedestal_credit_texts.update({item_table[name]: f"and the {texts.pedestal}" + for name, texts in LttPCreditsText.items()}) + ALTTPWorld.sickkid_credit_texts.update({item_table[name]: texts.sickkid for name, texts in LttPCreditsText.items()}) + ALTTPWorld.magicshop_credit_texts.update({item_table[name]: texts.magicshop for name, texts in LttPCreditsText.items()}) + ALTTPWorld.zora_credit_texts.update({item_table[name]: texts.zora for name, texts in LttPCreditsText.items()}) + ALTTPWorld.fluteboy_credit_texts.update({item_table[name]: texts.fluteboy for name, texts in LttPCreditsText.items()}) +except ModuleNotFoundError: + pass From 8c2d246a537f09caa9a143a021e37e03773a0a96 Mon Sep 17 00:00:00 2001 From: Ziktofel Date: Fri, 5 Sep 2025 16:44:01 +0200 Subject: [PATCH 0705/1218] SC2: Restrict allow Orphan to missions that already require that (#5405) * Restrict Allow Orphan for items to missions that already require that * Add test for build mission orphan behavior * Update item lists for Allow Orphan flag * Update the unit test to clear that BotB is not in the mission list * Update unit test name --- worlds/sc2/__init__.py | 11 +++++---- worlds/sc2/test/test_generation.py | 36 +++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/worlds/sc2/__init__.py b/worlds/sc2/__init__.py index 0201ebf60f27..984c716e7501 100644 --- a/worlds/sc2/__init__.py +++ b/worlds/sc2/__init__.py @@ -654,18 +654,21 @@ def flag_mission_based_item_excludes(world: SC2World, item_list: List[FilterItem def flag_allowed_orphan_items(world: SC2World, item_list: List[FilterItem]) -> None: """Adds the `Allowed_Orphan` flag to items that shouldn't be filtered with their parents, like combat shield""" missions = get_all_missions(world.custom_mission_order) - terran_nobuild_missions = any((MissionFlag.Terran|MissionFlag.NoBuild) in mission.flags and mission.campaign != SC2Campaign.NCO for mission in missions) - if terran_nobuild_missions: + if SC2Mission.PIERCING_OF_THE_SHROUD in missions: for item in item_list: if item.name in ( item_names.MARINE_COMBAT_SHIELD, item_names.MARINE_PROGRESSIVE_STIMPACK, item_names.MARINE_MAGRAIL_MUNITIONS, - item_names.MEDIC_STABILIZER_MEDPACKS, item_names.MEDIC_NANO_PROJECTOR, item_names.MARINE_LASER_TARGETING_SYSTEM, + item_names.MEDIC_STABILIZER_MEDPACKS, item_names.MARINE_LASER_TARGETING_SYSTEM, ): item.flags |= ItemFilterFlags.AllowedOrphan # These rules only trigger on Standard tactics if SC2Mission.BELLY_OF_THE_BEAST in missions and world.options.required_tactics == RequiredTactics.option_standard: for item in item_list: - if item.name in (item_names.FIREBAT_NANO_PROJECTORS, item_names.FIREBAT_NANO_PROJECTORS, item_names.FIREBAT_PROGRESSIVE_STIMPACK): + if item.name in ( + item_names.MARINE_COMBAT_SHIELD, item_names.MARINE_PROGRESSIVE_STIMPACK, item_names.MARINE_MAGRAIL_MUNITIONS, + item_names.MEDIC_STABILIZER_MEDPACKS, item_names.MARINE_LASER_TARGETING_SYSTEM, + item_names.FIREBAT_NANO_PROJECTORS, item_names.FIREBAT_JUGGERNAUT_PLATING, item_names.FIREBAT_PROGRESSIVE_STIMPACK + ): item.flags |= ItemFilterFlags.AllowedOrphan if SC2Mission.EVIL_AWOKEN in missions and world.options.required_tactics == RequiredTactics.option_standard: for item in item_list: diff --git a/worlds/sc2/test/test_generation.py b/worlds/sc2/test/test_generation.py index faedb19a9f9f..67e302fec0eb 100644 --- a/worlds/sc2/test/test_generation.py +++ b/worlds/sc2/test/test_generation.py @@ -4,7 +4,8 @@ from typing import * from .test_base import Sc2SetupTestBase -from .. import mission_groups, mission_tables, options, locations, SC2Mission, SC2Campaign, SC2Race, unreleased_items +from .. import mission_groups, mission_tables, options, locations, SC2Mission, SC2Campaign, SC2Race, unreleased_items, \ + RequiredTactics from ..item import item_groups, item_tables, item_names from .. import get_all_missions, get_random_first_mission from ..options import EnabledCampaigns, NovaGhostOfAChanceVariant, MissionOrder, ExcludeOverpoweredItems, \ @@ -1226,3 +1227,36 @@ def test_exclude_overpowered_items_and_not_allow_unit_nerfs(self) -> None: # A unit nerf happens due to excluding OP items self.assertNotIn(item_names.MOTHERSHIP_INTEGRATED_POWER, starting_inventory) + + def test_terran_nobuild_sections_get_marine_medic_upgrades_with_units_excluded(self) -> None: + world_options = { + 'mission_order': MissionOrder.option_grid, + 'maximum_campaign_size': MaximumCampaignSize.range_end, + 'enabled_campaigns': { + SC2Campaign.WOL.campaign_name + }, + 'excluded_items': [item_names.MARINE, item_names.MEDIC], + 'shuffle_no_build': False, + 'required_tactics': RequiredTactics.option_standard + } + mm_logic_upgrades = { + item_names.MARINE_COMBAT_SHIELD, item_names.MARINE_MAGRAIL_MUNITIONS, + item_names.MARINE_LASER_TARGETING_SYSTEM, + item_names.MARINE_PROGRESSIVE_STIMPACK, item_names.MEDIC_STABILIZER_MEDPACKS + } + + self.generate_world(world_options) + itempool = [item.name for item in self.multiworld.itempool] + missions = self.multiworld.worlds[self.player].custom_mission_order.get_used_missions() + + # These missions are rolled + self.assertIn(SC2Mission.THE_DIG, missions) + self.assertIn(SC2Mission.ENGINE_OF_DESTRUCTION, missions) + # This is not rolled + self.assertNotIn(SC2Mission.PIERCING_OF_THE_SHROUD, missions) + self.assertNotIn(SC2Mission.BELLY_OF_THE_BEAST, missions) + # These items are excluded and shouldn't appear + self.assertNotIn(item_names.MARINE, itempool) + self.assertNotIn(item_names.MEDIC, itempool) + # An upgrade is requested by logic for The Dig and Engine of Destruction + self.assertGreaterEqual(len(set(itempool).intersection(mm_logic_upgrades)), 1) From 5c6dbdd98f54612bd4491e125bee55bc85b09005 Mon Sep 17 00:00:00 2001 From: Ziktofel Date: Fri, 5 Sep 2025 16:44:28 +0200 Subject: [PATCH 0706/1218] SC2: Update docs for Linux launch script to follow the core client migration (#5407) --- worlds/sc2/docs/setup_en.md | 2 +- worlds/sc2/docs/setup_fr.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/sc2/docs/setup_en.md b/worlds/sc2/docs/setup_en.md index 0ddb9a3bf10e..a8d03d5a3df2 100644 --- a/worlds/sc2/docs/setup_en.md +++ b/worlds/sc2/docs/setup_en.md @@ -247,7 +247,7 @@ PATH_TO_ARCHIPELAGO= ARCHIPELAGO="$(ls ${PATH_TO_ARCHIPELAGO:-$(dirname $0)}/Archipelago_*.AppImage | sort -r | head -1)" # Start the Archipelago client -$ARCHIPELAGO Starcraft2Client +$ARCHIPELAGO "Starcraft 2 Client" ``` For Lutris installs, you can run `lutris -l` to get the numerical ID of your StarCraft II install, then run the command diff --git a/worlds/sc2/docs/setup_fr.md b/worlds/sc2/docs/setup_fr.md index 5ce9b4b9eb14..4e7a9663aa91 100644 --- a/worlds/sc2/docs/setup_fr.md +++ b/worlds/sc2/docs/setup_fr.md @@ -203,7 +203,7 @@ PATH_TO_ARCHIPELAGO= ARCHIPELAGO="$(ls ${PATH_TO_ARCHIPELAGO:-$(dirname $0)}/Archipelago_*.AppImage | sort -r | head -1)" # Lance le client de Archipelago -$ARCHIPELAGO Starcraft2Client +$ARCHIPELAGO "Starcraft 2 Client" ``` Pour une installation via Lutris, vous pouvez exécuter `lutris -l` pour obtenir l'identifiant numérique de votre From 90058ee175ef01bfe96def411b518d9f8f130a15 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 5 Sep 2025 16:48:15 +0200 Subject: [PATCH 0707/1218] CommonClient: fix /items, /locations and /missing not working if the datapackage is local (#5350) --- CommonClient.py | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index bd7113cb6f75..b1d9aeb15624 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -99,17 +99,6 @@ def _cmd_received(self) -> bool: self.ctx.on_print_json({"data": parts, "cmd": "PrintJSON"}) return True - def get_current_datapackage(self) -> dict[str, typing.Any]: - """ - Return datapackage for current game if known. - - :return: The datapackage for the currently registered game. If not found, an empty dictionary will be returned. - """ - if not self.ctx.game: - return {} - checksum = self.ctx.checksums[self.ctx.game] - return Utils.load_data_package_for_checksum(self.ctx.game, checksum) - def _cmd_missing(self, filter_text = "") -> bool: """List all missing location checks, from your local game state. Can be given text, which will be used as filter.""" @@ -119,8 +108,8 @@ def _cmd_missing(self, filter_text = "") -> bool: count = 0 checked_count = 0 - lookup = self.get_current_datapackage().get("location_name_to_id", {}) - for location, location_id in lookup.items(): + lookup = self.ctx.location_names[self.ctx.game] + for location_id, location in lookup.items(): if filter_text and filter_text not in location: continue if location_id < 0: @@ -141,11 +130,10 @@ def _cmd_missing(self, filter_text = "") -> bool: self.output("No missing location checks found.") return True - def output_datapackage_part(self, key: str, name: str) -> bool: + def output_datapackage_part(self, name: typing.Literal["Item Names", "Location Names"]) -> bool: """ Helper to digest a specific section of this game's datapackage. - :param key: The dictionary key in the datapackage. :param name: Printed to the user as context for the part. :return: Whether the process was successful. @@ -154,23 +142,20 @@ def output_datapackage_part(self, key: str, name: str) -> bool: self.output(f"No game set, cannot determine {name}.") return False - lookup = self.get_current_datapackage().get(key) - if lookup is None: - self.output("datapackage not yet loaded, try again") - return False - + lookup = self.ctx.item_names if name == "Item Names" else self.ctx.location_names + lookup = lookup[self.ctx.game] self.output(f"{name} for {self.ctx.game}") - for key in lookup: - self.output(key) + for name in lookup.values(): + self.output(name) return True def _cmd_items(self) -> bool: """List all item names for the currently running game.""" - return self.output_datapackage_part("item_name_to_id", "Item Names") + return self.output_datapackage_part("Item Names") def _cmd_locations(self) -> bool: """List all location names for the currently running game.""" - return self.output_datapackage_part("location_name_to_id", "Location Names") + return self.output_datapackage_part("Location Names") def output_group_part(self, group_key: typing.Literal["item_name_groups", "location_name_groups"], filter_key: str, From e23720a9777166472d76041edfe55a707e7ca019 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 5 Sep 2025 16:48:39 +0200 Subject: [PATCH 0708/1218] LttP: shuffle around gitignore (#5307) --- data/sprites/{custom => alttp/remote}/.gitignore | 0 data/sprites/custom/link.apsprite | 7 ------- data/sprites/remote/.gitignore | 2 -- 3 files changed, 9 deletions(-) rename data/sprites/{custom => alttp/remote}/.gitignore (100%) delete mode 100644 data/sprites/custom/link.apsprite delete mode 100644 data/sprites/remote/.gitignore diff --git a/data/sprites/custom/.gitignore b/data/sprites/alttp/remote/.gitignore similarity index 100% rename from data/sprites/custom/.gitignore rename to data/sprites/alttp/remote/.gitignore diff --git a/data/sprites/custom/link.apsprite b/data/sprites/custom/link.apsprite deleted file mode 100644 index ea0e85c10695..000000000000 --- a/data/sprites/custom/link.apsprite +++ /dev/null @@ -1,7 +0,0 @@ -author: Nintendo -data: null -game: A Link to the Past -min_format_version: 1 -name: Link -format_version: 1 -sprite_version: 1 \ No newline at end of file diff --git a/data/sprites/remote/.gitignore b/data/sprites/remote/.gitignore deleted file mode 100644 index d6b7ef32c847..000000000000 --- a/data/sprites/remote/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore From 31b2eed1f9c26a9d4f0eeee6adfe6cefb4368e8b Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Fri, 5 Sep 2025 11:09:33 -0400 Subject: [PATCH 0709/1218] TUNIC: Make the local_fill option show up on the website #5348 --- worlds/tunic/options.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index 79bb033b05a0..ef0130d0eb10 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -209,8 +209,9 @@ class GrassRandomizer(Toggle): class LocalFill(NamedRange): """ Choose the percentage of your filler/trap items that will be kept local or distributed to other TUNIC players with this option enabled. - This option defaults to 95% if you have Grass Randomizer enabled, 40% if you have Breakable Shuffle enabled, 96% if you have both, and 0% otherwise. - If you have Grass Randomizer enabled, this option must be set to 95% or higher to avoid flooding the item pool. The host can remove this restriction by turning off the limit_grass_rando setting in host.yaml. + If you have Grass Randomizer enabled, this defaults to 95%. If you have Breakable Shuffle enabled, this defaults to 40%. If you have both enabled, this defaults to 96%. + If you have Grass Randomizer enabled, this option must be set to 95% or higher to avoid flooding the item pool. + The host can remove this restriction by turning off the limit_grass_rando setting in host.yaml. This setting can only be changed with local generation, it cannot be changed on the website. This option ignores items placed in your local_items or non_local_items. This option does nothing in single player games. """ @@ -222,7 +223,6 @@ class LocalFill(NamedRange): "default": -1 } default = -1 - visibility = Visibility.template | Visibility.complex_ui | Visibility.spoiler class TunicPlandoConnections(PlandoConnections): From 77cab1382754ac01554a078e44648dda2678429b Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Fri, 5 Sep 2025 23:20:37 +0200 Subject: [PATCH 0710/1218] ArchipIDLE: Remove game #5422 --- README.md | 1 - docs/CODEOWNERS | 3 - setup.py | 1 - worlds/archipidle/Items.py | 315 ------------------------ worlds/archipidle/Rules.py | 28 --- worlds/archipidle/__init__.py | 128 ---------- worlds/archipidle/docs/en_ArchipIDLE.md | 13 - worlds/archipidle/docs/guide_en.md | 12 - worlds/archipidle/docs/guide_fr.md | 11 - 9 files changed, 512 deletions(-) delete mode 100644 worlds/archipidle/Items.py delete mode 100644 worlds/archipidle/Rules.py delete mode 100644 worlds/archipidle/__init__.py delete mode 100644 worlds/archipidle/docs/en_ArchipIDLE.md delete mode 100644 worlds/archipidle/docs/guide_en.md delete mode 100644 worlds/archipidle/docs/guide_fr.md diff --git a/README.md b/README.md index 4a0aa614ffec..0431049b849c 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ Currently, the following games are supported: * Meritous * Super Metroid/Link to the Past combo randomizer (SMZ3) * ChecksFinder -* ArchipIDLE * Hollow Knight * The Witness * Sonic Adventure 2: Battle diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 44eb830b3a9f..d0de8332867c 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -21,9 +21,6 @@ # Aquaria /worlds/aquaria/ @tioui -# ArchipIDLE -/worlds/archipidle/ @LegendaryLinux - # Blasphemous /worlds/blasphemous/ @TRPG0 diff --git a/setup.py b/setup.py index 01342e4ece61..3f25ade7a7a1 100644 --- a/setup.py +++ b/setup.py @@ -65,7 +65,6 @@ non_apworlds: set[str] = { "A Link to the Past", "Adventure", - "ArchipIDLE", "Archipelago", "Lufia II Ancient Cave", "Meritous", diff --git a/worlds/archipidle/Items.py b/worlds/archipidle/Items.py deleted file mode 100644 index 94665631b711..000000000000 --- a/worlds/archipidle/Items.py +++ /dev/null @@ -1,315 +0,0 @@ -item_table = ( - 'An Old GeoCities Profile', - 'Very Funny Joke', - 'Motivational Video', - 'Staples Easy Button', - 'One Million Dollars', - 'Replica Master Sword', - 'VHS Copy of Jurassic Park', - '32GB USB Drive', - 'Pocket Protector', - 'Leftover Parts from IKEA Furniture', - 'Half-Empty Ink Cartridge for a Printer', - 'Watch Battery', - 'Towel', - 'Scarf', - '2012 Magic the Gathering Core Set Starter Box', - 'Poke\'mon Booster Pack', - 'USB Speakers', - 'Eco-Friendly Spork', - 'Cheeseburger', - 'Brand New Car', - 'Hunting Knife', - 'Zippo Lighter', - 'Red Shirt', - 'One-Up Mushroom', - 'Nokia N-GAGE', - '2-Liter of Sprite', - 'Free trial of the critically acclaimed MMORPG Final Fantasy XIV, including the entirety of A Realm Reborn and the award winning Heavensward and Stormblood expansions up to level 70 with no restrictions on playtime!', - 'Can of Compressed Air', - 'Striped Kitten', - 'USB Power Adapter', - 'Fortune Cookie', - 'Nintendo Power Glove', - 'The Lampshade of No Real Significance', - 'Kneepads of Allure', - 'Get Out of Jail Free Card', - 'Box Set of Stargate SG-1 Season 4', - 'The Missing Left Sock', - 'Poster Tube', - 'Electronic Picture Frame', - 'Bottle of Shampoo', - 'Your Mission, Should You Choose To Accept It', - 'Fanny Pack', - 'Robocop T-Shirt', - 'Suspiciously Small Monocle', - 'Table Saw', - 'Cookies and Cream Milkshake', - 'Deflated Accordion', - 'Grandma\'s Homemade Pie', - 'Invisible Lego on the Floor', - 'Pitfall Trap', - 'Flathead Screwdriver', - 'Leftover Pizza', - 'Voodoo Doll that Looks Like You', - 'Pink Shoelaces', - 'Half a Bottle of Scotch', - 'Reminder Not to Forget Aginah', - 'Medicine Ball', - 'Yoga Mat', - 'Chocolate Orange', - 'Old Concert Tickets', - 'The Pick of Destiny', - 'McGuffin', - 'Just a Regular McMuffin', - '34 Tacos', - 'Duct Tape', - 'Copy of Untitled Goose Game', - 'Partially Used Bed Bath & Beyond Gift Card', - 'Mostly Popped Bubble Wrap', - 'Expired Driver\'s License', - 'The Look, You Know the One', - 'Transformers Lunch Box', - 'MP3 Player', - 'Dry Sharpie', - 'Chalkboard Eraser', - 'Overhead Projector', - 'Physical Copy of the Japanese 1.0 Link to the Past', - 'Collectable Action Figure', - 'Box Set of The Lord of the Rings Books', - 'Lite-Bright', - 'Stories from the Good-Old-Days', - 'Un-Reproducable Bug Reports', - 'Autographed Copy of Shaq-Fu', - 'Game-Winning Baseball', - 'Portable Battery Bank', - 'Blockbuster Membership Card', - 'Offensive Bumper Sticker', - 'Last Sunday\'s Crossword Puzzle', - 'Rubik\'s Cube', - 'Your First Grey Hair', - 'Embarrassing Childhood Photo', - 'Abandoned Sphere One Check', - 'The Internet', - 'Late-Night Cartoons', - 'The Correct Usage of a Semicolon', - 'Microsoft Windows 95 Resource Kit', - 'Car-Phone', - 'Walkman Radio', - 'Relevant XKCD Comic', - 'Razor Scooter', - 'Set of Beyblades', - 'Box of Pogs', - 'Beanie-Baby Collection', - 'Laser Tag Gun', - 'Radio Controlled Car', - 'Boogie Board', - 'Air Jordans', - 'Rubber Duckie', - 'The Last Cookie in the Cookie Jar', - 'Tin-Foil Hat', - 'Button-Up Shirt', - 'Designer Brand Bag', - 'Trapper Keeper', - 'Fake Moustache', - 'Colored Pencils', - 'Pair of 3D Glasses', - 'Pair of Movie Tickets', - 'Refrigerator Magnets', - 'NASCAR Dinner Plates', - 'The Final Boss', - 'Unskippable Cutscenes', - '24 Rolls of Toilet Paper', - 'Canned Soup', - 'Warm Blanket', - '3D Printer', - 'Jetpack', - 'Hoverboard', - 'Joycons with No Drift', - 'Double Rainbow', - 'Ping Pong Ball', - 'Area 51 Arcade Cabinet', - 'Elephant in the Room', - 'The Pink Panther', - 'Denim Shorts', - 'Tennis Racket', - 'Collection of Stuffed Animals', - 'Old Cell Phone', - 'Nintendo Virtual Boy', - 'Box of 5.25 Inch Floppy Disks', - 'Bag of Miscellaneous Wires', - 'Garden Shovel', - 'Leather Gloves', - 'Knife of +9 VS Ogres', - 'Old, Smelly Cheese', - 'Linksys BEFSR41 Router', - 'Ethernet Cables for a LAN Party', - 'Mechanical Pencil', - 'Book of Graph Paper', - '300 Sheets of Printer Paper', - 'One AAA Battery', - 'Box of Old Game Controllers', - 'Sega Dreamcast', - 'Mario\'s Overalls', - 'Betamax Player', - 'Stray Lego', - 'Chocolate Chip Pancakes', - 'Two Blueberry Muffins', - 'Nintendo 64 Controller with a Perfect Thumbstick', - 'Cuckoo Crossing the Road', - 'One Eyed, One Horned, Flying Purple People-Eater', - 'Love Potion Number Nine', - 'Wireless Headphones', - 'Festive Keychain', - 'Bundle of Twisted Cables', - 'Plank of Wood', - 'Broken Ant Farm', - 'Thirty-six American Dollars', - 'Can of Shaving Cream', - 'Blue Hair Dye', - 'Mug Engraved with the AP Logo', - 'Tube of Toothpaste', - 'Album of Elevator Music', - 'Headlight Fluid', - 'Tickets to the Renaissance Faire', - 'Bag of Golf Balls', - 'Box of Packing Peanuts', - 'Bottle of Peanut Butter', - 'Breath of the Wild Cookbook', - 'Stardew Valley Cookbook', - 'Thirteen Angry Chickens', - 'Bowl of Cereal', - 'Rubber Snake', - 'Stale Sunflower Seeds', - 'Alarm Clock Without a Snooze Button', - 'Wet Pineapple', - 'Set of Scented Candles', - 'Adorable Stuffed Animal', - 'The Broodwitch', - 'Old Photo Album', - 'Trade Quest Item', - 'Pair of Fancy Boots', - 'Shoddy Pickaxe', - 'Adventurer\'s Sword', - 'Cute Puppy', - 'Box of Matches', - 'Set of Allen Wrenches', - 'Glass of Water', - 'Magic Shaggy Carpet', - 'Macaroni and Cheese', - 'Chocolate Chip Cookie Dough Ice Cream', - 'Fresh Strawberries', - 'Delicious Tacos', - 'The Krabby Patty Recipe', - 'Map to Waldo\'s Location', - 'Stray Cat', - 'Ham and Cheese Sandwich', - 'DVD Player', - 'Motorcycle Helmet', - 'Fake Flowers', - '6-Pack of Sponges', - 'Heated Pants', - 'Empty Glass Bottle', - 'Brown Paper Bag', - 'Model Train Set', - 'TV Remote', - 'RC Car', - 'Super Soaker 9000', - 'Giant Sunglasses', - 'World\'s Smallest Violin', - 'Pile of Fresh Warm Laundry', - 'Half-Empty Ice Cube Tray', - 'Bob Ross Afro Wig', - 'Empty Cardboard Box', - 'Packet of Soy Sauce', - 'Solutions to a Math Test', - 'Pencil Eraser', - 'The Great Pumpkin', - 'Very Expensive Toaster', - 'Pack of Colored Sharpies', - 'Bag of Chocolate Chips', - 'Grandma\'s Homemade Cookies', - 'Collection of Bottle Caps', - 'Pack of Playing Cards', - 'Boom Box', - 'Toy Sail Boat', - 'Smooth Nail File', - 'Colored Chalk', - 'Missing Button', - 'Rubber Band Ball', - 'Joystick', - 'Galaga Arcade Cabinet', - 'Anime Mouse Pad', - 'Orange and Yellow Glow Sticks', - 'Odd Bookmark', - 'Stray Dice', - 'Tooth Picks', - 'Dirty Dishes', - 'Poke\'mon Card Game Rule Book (Gen 1)', - 'Salt Shaker', - 'Digital Thermometer', - 'Infinite Improbability Drive', - 'Fire Extinguisher', - 'Beeping Smoke Alarm', - 'Greasy Spatula', - 'Progressive Auto Insurance', - 'Mace Windu\'s Purple Lightsaber', - 'An Old Fixer-Upper', - 'Gamer Chair', - 'Comfortable Reclining Chair', - 'Shirt Covered in Dog Hair', - 'Angry Praying Mantis', - 'Card Games on Motorcycles', - 'Trucker Hat', - 'The DK Rap', - 'Three Great Balls', - 'Some Very Sus Behavior', - 'Glass of Orange Juice', - 'Turkey Bacon', - 'Bald Barbie Doll', - 'Developer Commentary', - 'Subscription to Nintendo Power Magazine', - 'DeLorean Time Machine', - 'Unkillable Cockroach', - 'Dungeons & Dragons Rulebook', - 'Boxed Copy of Quest 64', - 'James Bond\'s Gadget Wristwatch', - 'Tube of Go-Gurt', - 'Digital Watch', - 'Laser Pointer', - 'The Secret Cow Level', - 'AOL Free Trial CD-ROM', - 'E.T. for Atari 2600', - 'Season 2 of Knight Rider', - 'Spam E-Mails', - 'Half-Life 3 Release Date', - 'Source Code of Jurassic Park', - 'Moldy Cheese', - 'Comic Book Collection', - 'Hardcover Copy of Scott Pilgrim VS the World', - 'Old Gym Shorts', - 'Very Cool Sunglasses', - 'Your High School Yearbook Picture', - 'Written Invitation to Prom', - 'The Star Wars Holiday Special', - 'Oil Change Coupon', - 'Finger Guns', - 'Box of Tabletop Games', - 'Sock Puppets', - 'The Dog of Wisdom', - 'Surprised Chipmunk', - 'Stonks', - 'A Shrubbery', - 'Roomba with a Knife', - 'Wet Cat', - 'The missing moderator, Frostwares', - '1,793 Crossbows', - 'Holographic First Edition Charizard (Gen 1)', - 'VR Headset', - 'Archipelago 1.0 Release Date', - 'Strand of Galadriel\'s Hair', - 'Can of Meow-Mix', - 'Shake-Weight', - 'DVD Collection of Billy Mays Infomercials', - 'Old CD Key', -) diff --git a/worlds/archipidle/Rules.py b/worlds/archipidle/Rules.py deleted file mode 100644 index 2cc6220c6927..000000000000 --- a/worlds/archipidle/Rules.py +++ /dev/null @@ -1,28 +0,0 @@ -from BaseClasses import MultiWorld -from worlds.AutoWorld import LogicMixin - - -class ArchipIDLELogic(LogicMixin): - def _archipidle_location_is_accessible(self, player_id, items_required): - return sum(self.prog_items[player_id].values()) >= items_required - - -def set_rules(world: MultiWorld, player: int): - for i in range(16, 31): - world.get_location(f"IDLE item number {i}", player).access_rule = lambda \ - state: state._archipidle_location_is_accessible(player, 4) - - for i in range(31, 51): - world.get_location(f"IDLE item number {i}", player).access_rule = lambda \ - state: state._archipidle_location_is_accessible(player, 10) - - for i in range(51, 101): - world.get_location(f"IDLE item number {i}", player).access_rule = lambda \ - state: state._archipidle_location_is_accessible(player, 20) - - for i in range(101, 201): - world.get_location(f"IDLE item number {i}", player).access_rule = lambda \ - state: state._archipidle_location_is_accessible(player, 40) - - world.completion_condition[player] =\ - lambda state: state.can_reach(world.get_location("IDLE item number 200", player), "Location", player) diff --git a/worlds/archipidle/__init__.py b/worlds/archipidle/__init__.py deleted file mode 100644 index f4345444efb9..000000000000 --- a/worlds/archipidle/__init__.py +++ /dev/null @@ -1,128 +0,0 @@ -from BaseClasses import Item, MultiWorld, Region, Location, Entrance, Tutorial, ItemClassification -from worlds.AutoWorld import World, WebWorld -from datetime import datetime -from .Items import item_table -from .Rules import set_rules - - -class ArchipIDLEWebWorld(WebWorld): - theme = 'partyTime' - tutorials = [ - Tutorial( - tutorial_name='Setup Guide', - description='A guide to playing Archipidle', - language='English', - file_name='guide_en.md', - link='guide/en', - authors=['Farrak Kilhn'] - ), - Tutorial( - tutorial_name='Guide d installation', - description='Un guide pour jouer à Archipidle', - language='Français', - file_name='guide_fr.md', - link='guide/fr', - authors=['TheLynk'] - ) - ] - - -class ArchipIDLEWorld(World): - """ - An idle game which sends a check every thirty to sixty seconds, up to two hundred checks. - """ - game = "ArchipIDLE" - topology_present = False - hidden = (datetime.now().month != 4) # ArchipIDLE is only visible during April - web = ArchipIDLEWebWorld() - - item_name_to_id = {} - start_id = 9000 - for item in item_table: - item_name_to_id[item] = start_id - start_id += 1 - - location_name_to_id = {} - start_id = 9000 - for i in range(1, 201): - location_name_to_id[f"IDLE item number {i}"] = start_id - start_id += 1 - - def set_rules(self): - set_rules(self.multiworld, self.player) - - def create_item(self, name: str) -> Item: - return Item(name, ItemClassification.progression, self.item_name_to_id[name], self.player) - - def create_items(self): - item_pool = [ - ArchipIDLEItem( - item_table[0], - ItemClassification.progression, - self.item_name_to_id[item_table[0]], - self.player - ) - ] - - for i in range(40): - item_pool.append(ArchipIDLEItem( - item_table[1], - ItemClassification.progression, - self.item_name_to_id[item_table[1]], - self.player - )) - - for i in range(40): - item_pool.append(ArchipIDLEItem( - item_table[2], - ItemClassification.filler, - self.item_name_to_id[item_table[2]], - self.player - )) - - item_table_copy = list(item_table[3:]) - self.random.shuffle(item_table_copy) - for i in range(119): - item_pool.append(ArchipIDLEItem( - item_table_copy[i], - ItemClassification.progression if i < 9 else ItemClassification.filler, - self.item_name_to_id[item_table_copy[i]], - self.player - )) - - self.multiworld.itempool += item_pool - - def create_regions(self): - self.multiworld.regions += [ - create_region(self.multiworld, self.player, 'Menu', None, ['Entrance to IDLE Zone']), - create_region(self.multiworld, self.player, 'IDLE Zone', self.location_name_to_id) - ] - - # link up our region with the entrance we just made - self.multiworld.get_entrance('Entrance to IDLE Zone', self.player)\ - .connect(self.multiworld.get_region('IDLE Zone', self.player)) - - def get_filler_item_name(self) -> str: - return self.multiworld.random.choice(item_table) - - -def create_region(world: MultiWorld, player: int, name: str, locations=None, exits=None): - region = Region(name, player, world) - if locations: - for location_name in locations.keys(): - location = ArchipIDLELocation(player, location_name, locations[location_name], region) - region.locations.append(location) - - if exits: - for _exit in exits: - region.exits.append(Entrance(player, _exit, region)) - - return region - - -class ArchipIDLEItem(Item): - game = "ArchipIDLE" - - -class ArchipIDLELocation(Location): - game: str = "ArchipIDLE" diff --git a/worlds/archipidle/docs/en_ArchipIDLE.md b/worlds/archipidle/docs/en_ArchipIDLE.md deleted file mode 100644 index c3b396c64901..000000000000 --- a/worlds/archipidle/docs/en_ArchipIDLE.md +++ /dev/null @@ -1,13 +0,0 @@ -# ArchipIDLE - -## What is this game? - -ArchipIDLE was originally the 2022 Archipelago April Fools' Day joke. It is an idle game that sends a location check -on regular intervals. Updated annually with more items, gimmicks, and features, the game is visible -only during the month of April. - -## Where is the options page? - -The [player options page for this game](../player-options) contains all the options you need to configure -and export a config file. - diff --git a/worlds/archipidle/docs/guide_en.md b/worlds/archipidle/docs/guide_en.md deleted file mode 100644 index c450ec421dfc..000000000000 --- a/worlds/archipidle/docs/guide_en.md +++ /dev/null @@ -1,12 +0,0 @@ -# ArchipIdle Setup Guide - -## Joining a MultiWorld Game -1. Generate a `.yaml` file from the [ArchipIDLE Player Options Page](/games/ArchipIDLE/player-options) -2. Open the ArchipIDLE Client in your web browser by either: - - Navigate to the [ArchipIDLE Client](http://idle.multiworld.link) - - Download the client and run it locally from the - [ArchipIDLE GitHub Releases Page](https://github.com/ArchipelagoMW/archipidle/releases) -3. Enter the server address in the `Server Address` field and press enter -4. Enter your slot name when prompted. This should be the same as the `name` you entered on the - options page above, or the `name` field in your yaml file. -5. Click the "Begin!" button. diff --git a/worlds/archipidle/docs/guide_fr.md b/worlds/archipidle/docs/guide_fr.md deleted file mode 100644 index dc0c8af3218c..000000000000 --- a/worlds/archipidle/docs/guide_fr.md +++ /dev/null @@ -1,11 +0,0 @@ -# Guide de configuration d'ArchipIdle - -## Rejoindre une partie MultiWorld -1. Générez un fichier `.yaml` à partir de la [page des paramètres du lecteur ArchipIDLE](/games/ArchipIDLE/player-options) -2. Ouvrez le client ArchipIDLE dans votre navigateur Web en : - - Accédez au [Client ArchipIDLE](http://idle.multiworld.link) - - Téléchargez le client et exécutez-le localement à partir du [Page des versions d'ArchipIDLE GitHub](https://github.com/ArchipelagoMW/archipidle/releases) -3. Entrez l'adresse du serveur dans le champ `Server Address` et appuyez sur Entrée -4. Entrez votre nom d'emplacement lorsque vous y êtes invité. Il doit être le même que le `name` que vous avez saisi sur le - page de configuration ci-dessus, ou le champ `name` dans votre fichier yaml. -5. Cliquez sur "Commencer !" bouton. From c5b404baa826facca272cb9bb96f75a90248a073 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Fri, 5 Sep 2025 21:33:13 +0000 Subject: [PATCH 0711/1218] CI: only trigger release action for bare semver (#5065) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8c5d87b0ba44..147f30942d99 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,7 +5,7 @@ name: Release on: push: tags: - - '*.*.*' + - 'v?[0-9]+.[0-9]+.[0-9]*' env: ENEMIZER_VERSION: 7.1 From c3c517a200d0adf771baf961f5f027a16d75e52c Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Sat, 6 Sep 2025 17:09:41 +0000 Subject: [PATCH 0712/1218] DS3: use yaml.safe_load (#5360) --- worlds/dark_souls_3/detailed_location_descriptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/detailed_location_descriptions.py b/worlds/dark_souls_3/detailed_location_descriptions.py index 6e6cf1eb0bc8..5a505a0e5793 100644 --- a/worlds/dark_souls_3/detailed_location_descriptions.py +++ b/worlds/dark_souls_3/detailed_location_descriptions.py @@ -22,7 +22,7 @@ response = requests.get(url) if response.status_code != 200: raise Exception(f"Got {response.status_code} when downloading static randomizer locations") - annotations = yaml.load(response.text, Loader=yaml.Loader) + annotations = yaml.safe_load(response.text) static_to_archi_regions = { area['Name']: area['Archipelago'] From 8a091c9e02062ea0f23ee81383b856e255ace926 Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Sat, 6 Sep 2025 11:21:36 -0600 Subject: [PATCH 0713/1218] Kivy: Fix MessageBox popups (#5193) --- data/client.kv | 7 ++----- kvui.py | 4 +--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/data/client.kv b/data/client.kv index ed63df135d24..08f4c8d71831 100644 --- a/data/client.kv +++ b/data/client.kv @@ -220,6 +220,8 @@ : theme_text_color: "Custom" text_color: 1, 1, 1, 1 +: + height: self.content.texture_size[1] + 80 : layout: layout bar_width: "12dp" @@ -233,8 +235,3 @@ spacing: 10 size_hint_y: None height: self.minimum_height -: - valign: "middle" - halign: "center" - text_size: self.width, None - height: self.texture_size[1] diff --git a/kvui.py b/kvui.py index e11e366d72d8..013cd3360939 100644 --- a/kvui.py +++ b/kvui.py @@ -720,13 +720,11 @@ def __init__(self, **kwargs): class MessageBox(Popup): - def __init__(self, title, text, error=False, **kwargs): - label = MessageBoxLabel(text=text) + label = MessageBoxLabel(text=text, padding=("6dp", "0dp")) separator_color = [217 / 255, 129 / 255, 122 / 255, 1.] if error else [47 / 255., 167 / 255., 212 / 255, 1.] super().__init__(title=title, content=label, size_hint=(0.5, None), width=max(100, int(label.width) + 40), separator_color=separator_color, **kwargs) - self.height += max(0, label.height - 18) class MDNavigationItemBase(MDNavigationItem): From 1b200fb20b5f4b4eec4b2a7df743c8f078cf1868 Mon Sep 17 00:00:00 2001 From: lgbarrere Date: Mon, 8 Sep 2025 10:37:51 +0200 Subject: [PATCH 0714/1218] Choo-Choo Charles: implement new game and documentations (#5287) * Add cccharles world to AP > The logic has been tested, the game can be completed > The logic is simple and it does not take into account options ! The documentations are a work in progress * Update documentations > Redacted French and English Setup Guides > Redacted French and English Game Pages * Handling PR#5287 remarks > Revert unexpected changes on .run\Archipelago Unittests.run.xml (base Archipelago file) > Fixed typo "querty" -> "qwerty" in fr and eng Game Pages > Adding "Game page in other languages" section to eng Game Page documentation > Improved Steam path in fr and eng Setup Guides * Handled PR remarks + fixes > Added get_filler_item_name() to remove warnings > Fixed irrelevant links for documentations > Used the Player Options page instead of the default YAML on GitHub > Reworded all locations to make them simple and clear > Split some locations that can be linked with an entrance rule > Reworked all options > Updated regions according to locations > Replaced unnecessary rules by rules on entrances * Empty Options.py Only the base options are handled yet, "work in progress" features removed. * Handled PR remark > Fixed specific UT name * Handled PR remarks > UT updated by replacing depreciated features * Add start_inventory_from_pool as option This start_inventory_from_pool option is like regular start inventory but it takes items from the pool and replaces them with fillers Co-authored-by: Scipio Wright * Handled PR remarks > Mainly fixed editorial and minor issues without impact on UT results (still passed) * Update the guides according to releases > Updated the depreciated guides because the may to release the Mod has been changed > Removed the fixed issues from 'Known Issues' > Add the "Mod Download" section to simplify the others sections. * Handled PR remark > base_id reduced to ensure it fits to signed int (32 bits) in case of future AP improvements * Handled PR remarks > Set topology_present to False because unnecessary > Added an exception in case of unknown item instead of using filler classification > Fixed an issue that caused the "Bug Spray" to be considered as filler > Reworked the test_claire_breakers() test to ensure the lighthouse mission can only be finished if at least 4 breakers are collected * Added Choo-Choo Charles to README.md * CCCharles: Added rules to win > The victory could be accessed from sphere 1, this is now fixed by adding the following items as requirements: - Temple Key - Green Egg - Blue Egg - Red Egg --------- Co-authored-by: Scipio Wright --- README.md | 1 + docs/CODEOWNERS | 3 + worlds/cccharles/BaseID.py | 2 + worlds/cccharles/Items.py | 167 ++++ worlds/cccharles/Locations.py | 914 ++++++++++++++++++ worlds/cccharles/Options.py | 7 + worlds/cccharles/Regions.py | 290 ++++++ worlds/cccharles/Rules.py | 215 ++++ worlds/cccharles/__init__.py | 171 ++++ worlds/cccharles/docs/en_Choo-Choo Charles.md | 39 + worlds/cccharles/docs/fr_Choo-Choo Charles.md | 36 + worlds/cccharles/docs/setup_en.md | 52 + worlds/cccharles/docs/setup_fr.md | 52 + worlds/cccharles/test/TestAccess.py | 27 + worlds/cccharles/test/__init__.py | 0 worlds/cccharles/test/bases.py | 5 + 16 files changed, 1981 insertions(+) create mode 100644 worlds/cccharles/BaseID.py create mode 100644 worlds/cccharles/Items.py create mode 100644 worlds/cccharles/Locations.py create mode 100644 worlds/cccharles/Options.py create mode 100644 worlds/cccharles/Regions.py create mode 100644 worlds/cccharles/Rules.py create mode 100644 worlds/cccharles/__init__.py create mode 100644 worlds/cccharles/docs/en_Choo-Choo Charles.md create mode 100644 worlds/cccharles/docs/fr_Choo-Choo Charles.md create mode 100644 worlds/cccharles/docs/setup_en.md create mode 100644 worlds/cccharles/docs/setup_fr.md create mode 100644 worlds/cccharles/test/TestAccess.py create mode 100644 worlds/cccharles/test/__init__.py create mode 100644 worlds/cccharles/test/bases.py diff --git a/README.md b/README.md index 0431049b849c..fa87190565dd 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ Currently, the following games are supported: * shapez * Paint * Celeste (Open World) +* Choo-Choo Charles For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/). Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index d0de8332867c..d5f35888090a 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -45,6 +45,9 @@ # ChecksFinder /worlds/checksfinder/ @SunCatMC +# Choo-Choo Charles +/worlds/cccharles/ @Yaranorgoth + # Civilization VI /worlds/civ6/ @hesto2 diff --git a/worlds/cccharles/BaseID.py b/worlds/cccharles/BaseID.py new file mode 100644 index 000000000000..ab88fb7a0608 --- /dev/null +++ b/worlds/cccharles/BaseID.py @@ -0,0 +1,2 @@ +# CCCharles base ID +base_id = 66600000 diff --git a/worlds/cccharles/Items.py b/worlds/cccharles/Items.py new file mode 100644 index 000000000000..0cf7ced0389b --- /dev/null +++ b/worlds/cccharles/Items.py @@ -0,0 +1,167 @@ +from BaseClasses import Item +from .BaseID import base_id + + +class CCCharlesItem(Item): + game = "Choo-Choo Charles" + + +optional_items = { + "Scraps": base_id + 1, + "30 Scraps Reward": base_id + 2, + "25 Scraps Reward": base_id + 3, + "35 Scraps Reward": base_id + 4, + "40 Scraps Reward": base_id + 5, + "South Mine Key": base_id + 6, + "North Mine Key": base_id + 7, + "Mountain Ruin Key": base_id + 8, + "Barn Key": base_id + 9, + "Candice's Key": base_id + 10, + "Dead Fish": base_id + 11, + "Lockpicks": base_id + 12, + "Ancient Tablet": base_id + 13, + "Blue Box": base_id + 14, + "Page Drawing": base_id + 15, + "Journal": base_id + 16, + "Timed Dynamite": base_id + 17, + "Box of Rockets": base_id + 18, + "Breaker": base_id + 19, + "Broken Bob": base_id + 20, + "Employment Contracts": base_id + 21, + "Mob Camp Key": base_id + 22, + "Jar of Pickles": base_id + 23 +} + +useless_items = { + "Orange Paint Can": base_id + 24, + "Green Paint Can": base_id + 25, + "White Paint Can": base_id + 26, + "Pink Paint Can": base_id + 27, + "Grey Paint Can": base_id + 28, + "Blue Paint Can": base_id + 29, + "Black Paint Can": base_id + 30, + "Lime Paint Can": base_id + 31, + "Teal Paint Can": base_id + 32, + "Red Paint Can": base_id + 33, + "Purple Paint Can": base_id + 34, + "The Boomer": base_id + 35, + "Bob": base_id + 36 +} + +progression_items = { + "Green Egg": base_id + 37, + "Blue Egg": base_id + 38, + "Red Egg": base_id + 39, + "Remote Explosive": base_id + 40, + "Remote Explosive x8": base_id + 41, # Originally, Paul gives 8 explosives at once + "Temple Key": base_id + 42, + "Bug Spray": base_id + 43 # Should only be considered progressive in Nightmare Mode +} + +item_groups = { + "Weapons": { + "Bug Spray", + "The Boomer", + "Bob" + }, + "Paint Can": { + "Orange Paint Can", + "Green Paint Can", + "White Paint Can", + "Pink Paint Can", + "Grey Paint Can", + "Blue Paint Can", + "Black Paint Can", + "Lime Paint Can", + "Teal Paint Can", + "Red Paint Can", + "Purple Paint Can" + }, + "Train Upgrade": { + "Scraps", + "30 Scraps Reward", + "25 Scraps Reward", + "40 Scraps Reward" + }, + "Dungeon Keys": { + "South Mine Key", + "North Mine Key", + "Mountain Ruin Key" + }, + "Building Keys": { + "Barn Key", + "Candice's Key", + "Mob Camp Key", + "Temple Key" + }, + "Mission Items": { + "Dead Fish", + "Lockpicks", + "Ancient Tablet", + "Blue Box", + "Page Drawing", + "Journal", + "Timed Dynamite", + "Box of Rockets", + "Breaker", + "Broken Bob", + "Employment Contracts", + "Jar of Pickles", + "Remote Explosive", + "Remote Explosive x8" + }, + "Eggs": { + "Green Egg", + "Blue Egg", + "Red Egg" + } +} + + +# All items excepted the duplications (no item amount) +unique_item_dict = {**optional_items, **useless_items, **progression_items} + +# All 691 items to add to the item pool +full_item_list = [] +full_item_list += ["Scraps"] * 637 # 636 + 1 as Scrap Reward (from Ronny) +full_item_list += ["30 Scraps Reward"] * 3 +full_item_list += ["25 Scraps Reward"] * 1 +full_item_list += ["35 Scraps Reward"] * 2 +full_item_list += ["40 Scraps Reward"] * 1 +full_item_list += ["South Mine Key"] * 1 +full_item_list += ["North Mine Key"] * 1 +full_item_list += ["Mountain Ruin Key"] * 1 +full_item_list += ["Barn Key"] * 1 +full_item_list += ["Candice's Key"] * 1 +full_item_list += ["Dead Fish"] * 1 +full_item_list += ["Lockpicks"] * 1 +full_item_list += ["Ancient Tablet"] * 1 +full_item_list += ["Blue Box"] * 1 +full_item_list += ["Page Drawing"] * 8 +full_item_list += ["Journal"] * 1 +full_item_list += ["Timed Dynamite"] * 1 +full_item_list += ["Box of Rockets"] * 1 +full_item_list += ["Breaker"] * 4 +full_item_list += ["Broken Bob"] * 1 +full_item_list += ["Employment Contracts"] * 1 +full_item_list += ["Mob Camp Key"] * 1 +full_item_list += ["Jar of Pickles"] * 1 +full_item_list += ["Orange Paint Can"] * 1 +full_item_list += ["Green Paint Can"] * 1 +full_item_list += ["White Paint Can"] * 1 +full_item_list += ["Pink Paint Can"] * 1 +full_item_list += ["Grey Paint Can"] * 1 +full_item_list += ["Blue Paint Can"] * 1 +full_item_list += ["Black Paint Can"] * 1 +full_item_list += ["Lime Paint Can"] * 1 +full_item_list += ["Teal Paint Can"] * 1 +full_item_list += ["Red Paint Can"] * 1 +full_item_list += ["Purple Paint Can"] * 1 +full_item_list += ["The Boomer"] * 1 +full_item_list += ["Bob"] * 1 +full_item_list += ["Green Egg"] * 1 +full_item_list += ["Blue Egg"] * 1 +full_item_list += ["Red Egg"] * 1 +full_item_list += ["Remote Explosive x8"] * 1 +full_item_list += ["Temple Key"] * 1 +full_item_list += ["Bug Spray"] * 1 diff --git a/worlds/cccharles/Locations.py b/worlds/cccharles/Locations.py new file mode 100644 index 000000000000..63b502bcf460 --- /dev/null +++ b/worlds/cccharles/Locations.py @@ -0,0 +1,914 @@ +from BaseClasses import Location +from .BaseID import base_id + + +class CCCharlesLocation(Location): + game = "Choo-Choo Charles" + +# "First Station": +# /!\ NOT CONSIDERED YET: train_keypickup Train_KeyPickup Photorealistic_Island (X=-8816.341 Y=23392.416 Z=10219.855) + +loc_start_camp = { + "Start Camp Scraps 1": base_id + 1000, # ItemPickup139_5 Camp (X=24006.348 Y=53777.297 Z=10860.107) + "Start Camp Scraps 2": base_id + 1001 # ItemPickup140_8 Camp (X=23951.754 Y=54897.230 Z=10895.235) +} + +loc_tony_tiddle_mission = { + "Barn Tony Tiddle Mission Start": base_id + 1002 # (dialog 5) -> barn_key (1) +} + +loc_barn = { + "Barn Scraps 1": base_id + 1003, # ItemPickup12 Photorealistic_Island (X=70582.805 Y=52591.066 Z=11976.719) + "Barn Scraps 2": base_id + 1004, # ItemPickup4_2 Photorealistic_Island (X=70536.641 Y=51890.633 Z=11986.488) + "Barn Scraps 3": base_id + 1005, # ItemPickup6 Photorealistic_Island (X=70750.336 Y=52275.828 Z=11994.434) + "Barn Scraps 4": base_id + 1006, # ItemPickup11 Photorealistic_Island (X=70937.719 Y=52989.066 Z=12003.523) + "Barn Scraps 5": base_id + 1007, # ItemPickup5 Photorealistic_Island (X=71303.508 Y=52232.188 Z=12003.997) + "Barn Scraps 6": base_id + 1008, # ItemPickup7 Photorealistic_Island (X=71678.672 Y=52825.531 Z=11977.212) + "Barn Scraps 7": base_id + 1009, # ItemPickup8 Photorealistic_Island (X=71506.961 Y=52357.293 Z=12362.159) + "Barn Scraps 8": base_id + 1010, # ItemPickup9 Photorealistic_Island (X=71029.875 Y=52384.613 Z=12362.159) + "Barn Scraps 9": base_id + 1011 # ItemPickup10 Photorealistic_Island (X=71129.594 Y=52600.262 Z=12364.142) +} + +loc_candice_mission = { + "Tutorial House Candice Mission Start": base_id + 1012 # (dialog 3) -> candice_key (2) +} + +loc_tutorial_house = { + "Tutorial House Scraps 1": base_id + 1013, # ItemPickup17_2 Photorealistic_Island (X=74745.852 Y=73865.555 Z=11426.619) + "Tutorial House Scraps 2": base_id + 1014, # ItemPickup18_2 Photorealistic_Island (X=74864.102 Y=73900.094 Z=11426.619) + "Tutorial House Scraps 3": base_id + 1015, # ItemPickup14_2 Photorealistic_Island (X=74877.625 Y=73738.594 Z=11422.057) \!/ Existing match 4 + "Tutorial House Scraps 4": base_id + 1016, # ItemPickup15_8 Photorealistic_Island (X=75068.992 Y=73971.133 Z=11426.619) + "Tutorial House Scraps 5": base_id + 1017, # ItemPickup21_1 Photorealistic_Island (X=74923.500 Y=73571.648 Z=11426.619) + "Tutorial House Scraps 6": base_id + 1018, # ItemPickup19 Photorealistic_Island (X=75194.906 Y=73495.719 Z=11426.619) + "Tutorial House Scraps 7": base_id + 1019, # ItemPickup13_3 Photorealistic_Island (X=75320.102 Y=73446.352 Z=11487.376) + "Tutorial House Scraps 8": base_id + 1020, # ItemPickup20 Photorealistic_Island (X=75298.680 Y=73580.531 Z=11426.619) + "Tutorial House Scraps 9": base_id + 1021 # ItemPickup16_3 Photorealistic_Island (X=75310.008 Y=73770.742 Z=11489.709) +} + +loc_swamp_edges = { + "Swamp Edges Scraps 1": base_id + 1022, # ItemPickup465_67 Swamp_EnvironmentDetails (X=81964.398 Y=72167.305 Z=10116.385) + "Swamp Edges Scraps 2": base_id + 1023, # ItemPickup460_52 Swamp_EnvironmentDetails (X=89674.047 Y=71610.008 Z=9482.095) + "Swamp Edges Scraps 3": base_id + 1024, # ItemPickup459_49 Swamp_EnvironmentDetails (X=91637.156 Y=73345.672 Z=9492.019) + "Swamp Edges Scraps 4": base_id + 1025, # ItemPickup458_46 Swamp_EnvironmentDetails (X=94601.117 Y=75064.117 Z=9567.464) + "Swamp Edges Scraps 5": base_id + 1026, # ItemPickup457_43 Swamp_EnvironmentDetails (X=95536.641 Y=72622.969 Z=9512.531) + "Swamp Edges Scraps 6": base_id + 1027, # ItemPickup456_40 Swamp_EnvironmentDetails (X=96419.922 Y=65508.676 Z=9838.949) + "Swamp Edges Scraps 7": base_id + 1028, # ItemPickup455_37 Swamp_EnvironmentDetails (X=98158.680 Y=63191.629 Z=10477.084) + "Swamp Edges Scraps 8": base_id + 1029, # ItemPickup55_29 Swamp_EnvironmentDetails (X=93421.820 Y=59200.461 Z=9545.312) + "Swamp Edges Scraps 9": base_id + 1030, # ItemPickup453_31 Swamp_EnvironmentDetails(X=92951.648 Y=56453.527 Z=9560.638) + "Swamp Edges Scraps 10": base_id + 1031, # ItemPickup454_34 Swamp_EnvironmentDetails (X=96943.297 Y=58754.043 Z=10728.124) + "Swamp Edges Scraps 11": base_id + 1032, # ItemPickup452_28 Swamp_EnvironmentDetails (X=95000.617 Y=53070.859 Z=10258.078) + "Swamp Edges Scraps 12": base_id + 1033, # ItemPickup451_25 Swamp_EnvironmentDetails (X=91390.703 Y=53628.707 Z=9498.378) + "Swamp Edges Scraps 13": base_id + 1034, # ItemPickup53_23 Swamp_EnvironmentDetails (X=87628.742 Y=51614.957 Z=9487.013) + "Swamp Edges Scraps 14": base_id + 1035, # ItemPickup448_16 Swamp_EnvironmentDetails (X=89785.992 Y=48603.844 Z=9573.859) + "Swamp Edges Scraps 15": base_id + 1036, # ItemPickup447_11 Swamp_EnvironmentDetails (X=89925.383 Y=46288.707 Z=9499.904) + "Swamp Edges Scraps 16": base_id + 1037, # ItemPickup446_8 Swamp_EnvironmentDetails (X=90848.938 Y=43133.535 Z=9729.535) + "Swamp Edges Scraps 17": base_id + 1038, # ItemPickup445_5 Swamp_EnvironmentDetails (X=87382.383 Y=42475.191 Z=9509.929) + "Swamp Edges Scraps 18": base_id + 1039, # ItemPickup444_2 Swamp_EnvironmentDetails (X=87481.820 Y=39316.820 Z=9757.511) + "Swamp Edges Scraps 19": base_id + 1040, # ItemPickup54_26 Swamp_EnvironmentDetails (X=86039.180 Y=37135.004 Z=9826.263) + "Swamp Edges Scraps 20": base_id + 1041, # ItemPickup475_97 Swamp_EnvironmentDetails (X=81798.609 Y=36766.922 Z=9479.318) + "Swamp Edges Scraps 21": base_id + 1042, # ItemPickup474_94 Swamp_EnvironmentDetails (X=79254.055 Y=40120.293 Z=9879.539) + "Swamp Edges Scraps 22": base_id + 1043, # ItemPickup473_91 Swamp_EnvironmentDetails (X=82251.773 Y=42454.027 Z=9482.057) + "Swamp Edges Scraps 23": base_id + 1044, # ItemPickup472_88 Swamp_EnvironmentDetails (X=84903.977 Y=48323.543 Z=9503.382) + "Swamp Edges Scraps 24": base_id + 1045, # ItemPickup471_85 Swamp_EnvironmentDetails (X=84238.609 Y=51239.547 Z=9529.745) + "Swamp Edges Scraps 25": base_id + 1046, # ItemPickup470_82 Swamp_EnvironmentDetails (X=84439.063 Y=53501.563 Z=9491.291) + "Swamp Edges Scraps 26": base_id + 1047, # ItemPickup52_20 Swamp_EnvironmentDetails (X=83025.086 Y=53275.348 Z=9694.177) + "Swamp Edges Scraps 27": base_id + 1048, # ItemPickup469_79 Swamp_EnvironmentDetails (X=79827.055 Y=54791.504 Z=10121.452) + "Swamp Edges Scraps 28": base_id + 1049, # ItemPickup468_76 Swamp_EnvironmentDetails (X=82266.461 Y=58126.316 Z=9660.493) + "Swamp Edges Scraps 29": base_id + 1050, # ItemPickup467_73 Swamp_EnvironmentDetails (X=75911.297 Y=65155.836 Z=10660.832) + "Swamp Edges Scraps 30": base_id + 1051, # ItemPickup466_70 Swamp_EnvironmentDetails (X=81171.641 Y=66836.125 Z=9673.756) + "Swamp Edges Scraps 31": base_id + 1052, # ItemPickup449_19 Swamp_EnvironmentDetails (X=95254.992 Y=40910.563 Z=10503.727) + "Swamp Edges Scraps 32": base_id + 1053 # ItemPickup450_22 Swamp_EnvironmentDetails (X=93992.992 Y=50773.484 Z=10238.064) +} + +loc_swamp_mission = { + "Swamp Shack Scraps 1": base_id + 1054, # ItemPickup51_17 Swamp_EnvironmentDetails (X=87685.797 Y=69754.008 Z=9629.617) + "Swamp Shack Scraps 2": base_id + 1055, # ItemPickup461_55 Swamp_EnvironmentDetails (X=87308.883 Y=69096.789 Z=9624.543) + "Swamp Islet Scraps 1": base_id + 1056, # ItemPickup462_58 Swamp_EnvironmentDetails (X=88101.219 Y=64553.148 Z=9557.692) + "Swamp Islet Scraps 2": base_id + 1057, # ItemPickup463_61 Swamp_EnvironmentDetails (X=87100.922 Y=63590.965 Z=9582.900) + "Swamp Islet Scraps 3": base_id + 1058, # ItemPickup464_64 Swamp_EnvironmentDetails (X=86399.656 Y=64290.805 Z=9493.576) + "Swamp Islet Dead Fish": base_id + 1059, # Swamp_FishPickup Swamp_EnvironmentDetails (X=87288.945 Y=64278.273 Z=9550.320) + "Swamp Lizbeth Murkwater Mission End": base_id + 1060 # (dialog 2) -> 30_scraps_reward +} + +loc_junkyard_area = { + "Junkyard Area Scraps 1": base_id + 1061, # ItemPickup185_29 Junkyard_Details1 (X=94184.391 Y=89760.258 Z=9331.188) + "Junkyard Area Scraps 2": base_id + 1062, # ItemPickup177_5 Junkyard_Details1 (X=91919.469 Y=89681.602 Z=9407.639) + "Junkyard Area Scraps 3": base_id + 1063, # ItemPickup46_5 Junkyard_Details (X=91696.078 Y=90453.563 Z=9480.997) + "Junkyard Area Scraps 4": base_id + 1064, # ItemPickup178_8 Junkyard_Details1 (X=92453.719 Y=91142.531 Z=9398.951) + "Junkyard Area Scraps 5": base_id + 1065, # ItemPickup182_20 Junkyard_Details1 (X=88645.453 Y=90374.930 Z=9507.291) + "Junkyard Area Scraps 6": base_id + 1066, # ItemPickup48_11 Junkyard_Details (X=88461.953 Y=92077.531 Z=9712.173) + "Junkyard Area Scraps 7": base_id + 1067, # ItemPickup49_14 Junkyard_Details (X=91521.555 Y=93773.641 Z=9421.457) + "Junkyard Area Scraps 8": base_id + 1068, # ItemPickup50_17 Junkyard_Details (X=94741.484 Y=92565.938 Z=9221.093) + "Junkyard Area Scraps 9": base_id + 1069, # ItemPickup186_32 Junkyard_Details1 (X=95256.008 Y=91356.789 Z=9251.082) + "Junkyard Area Scraps 10": base_id + 1070, # ItemPickup45_2 Junkyard_Details (X=94289.664 Y=89951.477 Z=9367.076) + "Junkyard Area Daryl Mission Start": base_id + 1071, # (dialog 4) -> Lockpicks (4) + "Junkyard Area Chest Ancient Tablet": base_id + 1072, # Junkyard_TabletPickup Junkyard_Details (X=90715.367 Y=92168.563 Z=9402.729) + "Junkyard Area Daryl Mission End": base_id + 1073 # (dialog 3) -> 25_scraps_reward +} + +loc_south_house = { + "South House Scraps 1": base_id + 1074, # ItemPickup361_26 Secret12_ExteriorDetails (X=85865.969 Y=103869.656 Z=9453.063) + "South House Scraps 2": base_id + 1075, # ItemPickup360_23 Secret12_ExteriorDetails (X=84403.742 Y=107229.039 Z=9067.245) + "South House Scraps 3": base_id + 1076, # ItemPickup359_20 Secret12_ExteriorDetails (X=83389.789 Y=108817.992 Z=8752.255) + "South House Scraps 4": base_id + 1077, # ItemPickup353_2 Secret12_ExteriorDetails (X=82413.547 Y=109697.477 Z=8637.677) + "South House Scraps 5": base_id + 1078, # ItemPickup354_5 Secret12_ExteriorDetails (X=83000.359 Y=110323.664 Z=8560.229) + "South House Scraps 6": base_id + 1079, # ItemPickup358_17 Secret12_ExteriorDetails (X=82072.625 Y=110482.664 Z=8682.441) + "South House Scraps 7": base_id + 1080, # ItemPickup24_30 Secret12_Details (X=81970.766 Y=111082.117 Z=8647.703) + "South House Scraps 8": base_id + 1081, # ItemPickup356_11 Secret12_ExteriorDetails (X=80915.375 Y=108689.758 Z=8377.754) + "South House Scraps 9": base_id + 1082, # ItemPickup355_8 Secret12_ExteriorDetails (X=81762.180 Y=111371.023 Z=7876.312) + "South House Scraps 10": base_id + 1083, # ItemPickup357_14 Secret12_ExteriorDetails (X=80663.336 Y=113306.695 Z=7226.475) + "South House Scraps 11": base_id + 1084, # ItemPickup23_21 Secret12_Details (X=80520.367 Y=113747.039 Z=7252.808) + "South House Scraps 12": base_id + 1085, # ItemPickup22_18 Secret12_Details (X=80830.273 Y=113871.383 Z=7201.687) + "South House Chest Scraps 1": base_id + 1086, # ItemPickup21 Secret12_Details (X=82079.922 Y=110808.602 Z=8739.324) + "South House Chest Scraps 2": base_id + 1087, # ItemPickup18 Secret12_Details (X=82102.664 Y=110813.664 Z=8726.308) + "South House Chest Scraps 3": base_id + 1088, # ItemPickup17 Secret12_Details (X=82091.547 Y=110810.906 Z=8721.354) \!/ Existing match 1 + "South House Chest Scraps 4": base_id + 1089, # ItemPickup16 Secret12_Details (X=82102.664 Y=110813.664 Z=8708.337) KO + "South House Chest Scraps 5": base_id + 1090, # ItemPickup14 Secret12_Details (X=82091.516 Y=110810.898 Z=8701.793) \!/ Existing match 3 + "South House Chest Scraps 6": base_id + 1091 # ItemPickup13_7 Secret12_Details (X=82102.664 Y=110813.625 Z=8688.776) +} + +loc_junkyard_shed = { + "Junkyard Shed Helen Mission Start": base_id + 1092, # (dialog 8) -> south_mine_key (6) + "Junkyard Shed Scraps 1": base_id + 1093, # ItemPickup424_23 Settlement_A_House_1 (X=98303.992 Y=84476.016 Z=9376.540) + "Junkyard Shed Scraps 2": base_id + 1094, # ItemPickup419_8 Settlement_A_House_1 (X=98174.680 Y=84067.383 Z=9249.197) + "Junkyard Shed Scraps 3": base_id + 1095, # ItemPickup418_5 Settlement_A_House_1 (X=97948.977 Y=83354.656 Z=9339.430) + "Junkyard Shed Scraps 4": base_id + 1096, # ItemPickup417_2 Settlement_A_House_1 (X=98208.391 Y=83088.047 Z=9273.632) + "Junkyard Shed Scraps 5": base_id + 1097, # ItemPickup420_11 Settlement_A_House_1 (X=97757.773 Y=82995.656 Z=9298.597) + "Junkyard Shed Scraps 6": base_id + 1098, # ItemPickup422_17 Settlement_A_House_1 (X=98776.102 Y=80881.133 Z=9286.782) + "Junkyard Shed Scraps 7": base_id + 1099, # ItemPickup421_14 Settlement_A_House_1 (X=99198.508 Y=82057.820 Z=9248.227) + "Junkyard Shed Scraps 8": base_id + 1100 # ItemPickup423_20 Settlement_A_House_1 (X=99208.617 Y=84383.125 Z=9257.880) +} + +loc_military_base = { + "Military Base Sgt Flint Mission End": base_id + 1101, # (dialog 2) -> bug_spray + "Military Base Scraps 1": base_id + 1102, # ItemPickup134_17 Bugspray_Main (X=105743.531 Y=83017.492 Z=9423.290) + "Military Base Scraps 2": base_id + 1103, # ItemPickup129_2 Bugspray_Main (X=108495.805 Y=81616.992 Z=9139.340) + "Military Base Scraps 3": base_id + 1104, # ItemPickup135_20 Bugspray_Main (X=108709.219 Y=85981.016 Z=9650.472) + "Military Base Scraps 4": base_id + 1105, # ItemPickup130_5 Bugspray_Main (X=112004.195 Y=83811.313 Z=8887.996) + "Military Base Scraps 5": base_id + 1106, # ItemPickup131_8 Bugspray_Main (X=110904.867 Y=82024.781 Z=9581.007) + "Military Base Scraps 6": base_id + 1107, # ItemPickup132_11 Bugspray_Main (X=112458.563 Y=81967.945 Z=9850.968) + "Military Base Scraps 7": base_id + 1108, # ItemPickup22_9 Bugspray_Details (X=112541.695 Y=81345.875 Z=9896.940) + "Military Base Scraps 8": base_id + 1109, # ItemPickup133_14 Bugspray_Main (X=111943.391 Y=79970.016 Z=10025.820) + "Military Base Scraps 9": base_id + 1110, # ItemPickup24_8 Bugspray_Details (X=112074.063 Y=83533.398 Z=9008.831) + "Military Base Scraps 10": base_id + 1111, # ItemPickup23_2 Bugspray_Details (X=110738.523 Y=85389.852 Z=9082.626) + "Military Base Scraps 11": base_id + 1112, # ItemPickup136_23 Bugspray_Main (X=112962.594 Y=85872.922 Z=8638.805) + "Military Base Scraps 12": base_id + 1113, # ItemPickup137_26 Bugspray_Main (X=116230.563 Y=84357.602 Z=8580.226) + "Military Base Orange Paint Can": base_id + 1114 # PaintCan_5 Bugspray_Details (X=111916.102 Y=83066.195 Z=9094.554) +} + +loc_south_mine_outside = { + "South Mine Outside Scraps 1": base_id + 1115, # ItemPickup20_1 Mine_1_OutsideMain (X=114794.375 Y=57211.855 Z=8523.348) + "South Mine Outside Scraps 2": base_id + 1116, # ItemPickup15_2 Mine_1_OutsideDetails (X=112523.438 Y=57693.836 Z=8639.382) + "South Mine Outside Scraps 3": base_id + 1117, # ItemPickup22_5 Mine_1_OutsideMain (X=112348.586 Y=59174.289 Z=8945.143) + "South Mine Outside Scraps 4": base_id + 1118, # ItemPickup13_2 Mine_1_OutsideDetails (X=110989.156 Y=57840.090 Z=8700.936) + "South Mine Outside Scraps 5": base_id + 1119, # ItemPickup16_1 Mine_1_OutsideDetails (X=110487.281 Y=54528.535 Z=8589.910) + "South Mine Outside Scraps 6": base_id + 1120, # ItemPickup18_1 Mine_1_OutsideMain (X=113727.297 Y=54791.703 Z=8424.460) + "South Mine Outside Scraps 7": base_id + 1121 # ItemPickup17_3 Mine_1_OutsideMain (X=113965.211 Y=53289.539 Z=8402.346) +} + +loc_south_mine_inside = { + "South Mine Inside Scraps 1": base_id + 1122, # ItemPickup23_4 Mine_1_Interior_1 (X=108659.945 Y=58712.691 Z=8763.015) + "South Mine Inside Scraps 2": base_id + 1123, # ItemPickup24_0 Mine_1_Interior_1 (X=104954.602 Y=61540.488 Z=7876.374) + "South Mine Inside Scraps 3": base_id + 1124, # ItemPickup26_0 Mine_1_Interior_1 (X=104436.758 Y=64091.211 Z=7872.767) + "South Mine Inside Scraps 4": base_id + 1125, # ItemPickup290_20 Mine_1_Interior_2 (X=101356.625 Y=66110.906 Z=8034.738) + "South Mine Inside Scraps 5": base_id + 1126, # ItemPickup287_8 Mine_1_Interior_2 (X=96888.820 Y=64458.559 Z=7917.468) + "South Mine Inside Scraps 6": base_id + 1127, # ItemPickup289_14 Mine_1_Interior_2 (X=95863.180 Y=63252.902 Z=7847.054) + "South Mine Inside Scraps 7": base_id + 1128, # ItemPickup288_11 Mine_1_Interior_2 (X=97337.219 Y=62921.438 Z=7884.393) + "South Mine Inside Scraps 8": base_id + 1129, # ItemPickup285_2 Mine_1_Interior_2 (X=96689.203 Y=61880.895 Z=7806.810) + "South Mine Inside Scraps 9": base_id + 1130, # ItemPickup286_5 Mine_1_Interior_2 (X=98403.227 Y=62812.531 Z=7880.947) + "South Mine Inside Green Egg": base_id + 1131, # ItemPickup14_2 Mine_1_Interior_2 (X=96753.219 Y=62909.504 Z=8030.018) \!/ Existing match 4 + "South Mine Inside Green Paint Can": base_id + 1132 # PaintCan_2 Mine_1_Interior_1 (X=108293.281 Y=64192.094 Z=7872.770) \!/ Existing match 5 +} + +loc_middle_station = { + "Middle Station White Paint Can": base_id + 1133, # PaintCan_2 Station_Details1 (X=34554.141 Y=-7395.408 Z=11897.556) \!/ Existing match 5 + "Middle Station Scraps 1": base_id + 1134, # ItemPickup431_20 Station_BuildingDetails (X=37710.504 Y=-6462.562 Z=11356.691) + "Middle Station Scraps 2": base_id + 1135, # ItemPickup425_2 Station_BuildingDetails (X=37034.340 Y=-4923.256 Z=11348.328) + "Middle Station Scraps 3": base_id + 1136, # ItemPickup427_8 Station_BuildingDetails (X=36689.164 Y=-3727.466 Z=11353.597) + "Middle Station Scraps 4": base_id + 1137, # ItemPickup426_5 Station_BuildingDetails (X=37207.629 Y=-3393.977 Z=11379.110) + "Middle Station Scraps 5": base_id + 1138, # ItemPickup429_14 Station_BuildingDetails (X=37988.219 Y=-3365.906 Z=11350.225) + "Middle Station Scraps 6": base_id + 1139, # ItemPickup428_11 Station_BuildingDetails (X=36956.242 Y=-2746.948 Z=11353.506) + "Middle Station Scraps 7": base_id + 1140, # ItemPickup430_17 Station_BuildingDetails (X=36638.492 Y=-6410.017 Z=11353.546) + "Middle Station Scraps 8": base_id + 1141, # ItemPickup433_26 Station_BuildingDetails (X=35931.168 Y=-7558.021 Z=11899.232) + "Middle Station Scraps 9": base_id + 1142, # ItemPickup434 Station_BuildingDetails (X=35636.855 Y=-7628.500 Z=11903.627) + "Middle Station Scraps 10": base_id + 1143, # ItemPickup435 Station_BuildingDetails (X=34894.152 Y=-7537.087 Z=11903.627) + "Middle Station Scraps 11": base_id + 1144, # ItemPickup13_4 Station_BuildingDetails (X=33505.609 Y=-7742.843 Z=11898.971) + "Middle Station Scraps 12": base_id + 1145, # ItemPickup440_5 Station_Details1 (X=37394.004 Y=-8395.084 Z=11389.296) + "Middle Station Scraps 13": base_id + 1146, # ItemPickup432_23 Station_BuildingDetails (X=36040.695 Y=-8068.016 Z=11456.609) + "Middle Station Scraps 14": base_id + 1147, # ItemPickup16_4 Station_BuildingDetails (X=35360.320 Y=-8441.443 Z=11457.823) + "Middle Station Scraps 15": base_id + 1148, # ItemPickup439_2 Station_Details1 (X=36311.324 Y=-9563.938 Z=11468.039) + "Middle Station Scraps 16": base_id + 1149, # ItemPickup442_11 Station_Details1 (X=33335.656 Y=-13872.785 Z=11189.906) + "Middle Station Scraps 17": base_id + 1150, # ItemPickup441_8 Station_Details1 (X=33129.984 Y=-14073.978 Z=11189.906) + "Middle Station Scraps 18": base_id + 1151, # ItemPickup436_31 Station_BuildingDetails (X=33587.488 Y=-7828.651 Z=11529.446) + "Middle Station Scraps 19": base_id + 1152, # ItemPickup14_3 Station_BuildingDetails (X=34007.254 Y=-7749.381 Z=11533.760) + "Middle Station Scraps 20": base_id + 1153, # ItemPickup443_14 Station_Details1 (X=31457.752 Y=-7120.744 Z=11421.197) + "Middle Station Theodore Mission End": base_id + 1154 # (dialog 2) -> 35_scraps_reward + # "Middle Station Scraps Glitch 1" ItemPickup437_34 (X=34217.613 Y=-9481.271 Z=11505.686) /!\ Glitched scrap + # "Middle Station Scraps Glitch 2" ItemPickup438_37 (X=36101.633 Y=-10459.024 Z=11385.937) /!\ Glitched scrap +} + +loc_canyon = { + "Canyon Scraps 1": base_id + 1155, # ItemPickup156_47 Canyon_Main (X=29432.162 Y=-3164.300 Z=11540.294) + "Canyon Scraps 2": base_id + 1156, # ItemPickup155_44 Canyon_Main (X=26331.086 Y=3036.740 Z=11701.688) + "Canyon Scraps 3": base_id + 1157, # ItemPickup154_41 Canyon_Main (X=22688.129 Y=3906.730 Z=12249.182) + "Canyon Scraps 4": base_id + 1158, # ItemPickup147_20 Canyon_Main (X=20546.193 Y=4371.471 Z=12128.874) + "Canyon Scraps 5": base_id + 1159, # ItemPickup148_23 Canyon_Main (X=20006.584 Y=4928.478 Z=12174.837) + "Canyon Scraps 6": base_id + 1160, # ItemPickup146_17 Canyon_Main (X=19251.633 Y=3798.014 Z=12170.390) + "Canyon Scraps 7": base_id + 1161, # ItemPickup149_26 Canyon_Main (X=18302.678 Y=7323.849 Z=12595.085) + "Canyon Scraps 8": base_id + 1162, # ItemPickup150_29 Canyon_Main (X=19019.563 Y=8172.146 Z=12640.462) + "Canyon Scraps 9": base_id + 1163, # ItemPickup142_5 Canyon_Main (X=18001.689 Y=11138.320 Z=13035.360) + "Canyon Scraps 10": base_id + 1164, # ItemPickup143_8 Canyon_Main (X=16381.525 Y=7191.394 Z=13682.453) + "Canyon Scraps 11": base_id + 1165, # ItemPickup144_11 Canyon_Main (X=18294.928 Y=7870.372 Z=14350.015) + "Canyon Scraps 12": base_id + 1166, # ItemPickup31_2 CanyonCamp_Details (X=20730.520 Y=8032.158 Z=14439.826) + "Canyon Scraps 13": base_id + 1167, # ItemPickup145_14 Canyon_Main (X=24752.658 Y=7959.624 Z=14363.087) + "Canyon Scraps 14": base_id + 1168, # ItemPickup141_2 Canyon_Main (X=20181.992 Y=13816.017 Z=14897.407) + "Canyon Scraps 15": base_id + 1169, # ItemPickup151_32 Canyon_Main (X=23172.160 Y=2842.120 Z=12954.566) + "Canyon Scraps 16": base_id + 1170, # ItemPickup152_35 Canyon_Main (X=22307.621 Y=-1180.840 Z=12451.548) + "Canyon Scraps 17": base_id + 1171, # ItemPickup153_38 Canyon_Main (X=28473.596 Y=6741.842 Z=13314.166) + "Canyon Blue Box": base_id + 1172 # Canyon_BlueBoxPickup CanyonCamp_Details (X=20338.525 Y=4989.111 Z=12323.649) +} + +loc_watchtower = { + "Watchtower Scraps 1": base_id + 1173, # ItemPickup373_13 Secret2_WatchTowerDetails (X=32760.389 Y=-28814.084 Z=10997.447) + "Watchtower Scraps 2": base_id + 1174, # ItemPickup22_6 Secret2_WatchTowerDetails (X=32801.668 Y=-31660.041 Z=10643.390) + "Watchtower Scraps 3": base_id + 1175, # ItemPickup372_10 Secret2_WatchTowerDetails (X=31018.063 Y=-33375.313 Z=11100.126) + "Watchtower Scraps 4": base_id + 1176, # ItemPickup22_16 Secret2_WatchTowerDetails (X=33308.215 Y=-35928.578 Z=10614.347) + "Watchtower Scraps 5": base_id + 1177, # ItemPickup22_2 Secret2_WatchTowerDetails (X=34304.262 Y=-33446.063 Z=10674.936) + "Watchtower Scraps 6": base_id + 1178, # ItemPickup370_2 Secret2_WatchTowerDetails (X=32869.453 Y=-33184.094 Z=10612.040) + "Watchtower Scraps 7": base_id + 1179, # ItemPickup374_16 Secret2_WatchTowerDetails (X=33210.707 Y=-32097.611 Z=11211.031) + "Watchtower Scraps 8": base_id + 1180, # ItemPickup22_10 Secret2_WatchTowerDetails (X=33246.262 Y=-32046.697 Z=11851.025) + "Watchtower Scraps 9": base_id + 1181, # ItemPickup22_8 Secret2_WatchTowerDetails (X=33553.156 Y=-31810.645 Z=11849.521) + "Watchtower Scraps 10": base_id + 1182, # ItemPickup371_7 Secret2_WatchTowerDetails (X=36151.621 Y=-31791.633 Z=11093.785) + "Watchtower Pink Paint Can": base_id + 1183 # PaintCan_2 Secret2_WatchTowerDetails (X=33069.133 Y=-32168.045 Z=11859.582) \!/ Existing match 5 +} + +loc_boulder_field = { + "Boulder Field Page Drawing 1": base_id + 1184, # Pages_Drawing1 Pages_Environment_Details (X=46232.703 Y=-37052.875 Z=9531.116) + "Boulder Field Page Drawing 2": base_id + 1185, # Pages_Drawing2 Pages_Environment_Details (X=51854.980 Y=-31332.070 Z=9804.927) + "Boulder Field Page Drawing 3": base_id + 1186, # Pages_Drawing3 Pages_Environment_Details (X=47595.750 Y=-29931.740 Z=9308.014) + "Boulder Field Page Drawing 4": base_id + 1187, # Pages_Drawing4 Pages_Environment_Details (X=43819.680 Y=-30378.770 Z=9706.599) + "Boulder Field Page Drawing 5": base_id + 1188, # Pages_Drawing5 Pages_Environment_Details (X=47494.746 Y=-20884.781 Z=9812.398) + "Boulder Field Page Drawing 6": base_id + 1189, # Pages_Drawing6 Pages_Environment_Details (X=43725.148 Y=-21952.570 Z=9744.351) + "Boulder Field Page Drawing 7": base_id + 1190, # Pages_Drawing7 Pages_Environment_Details (X=44752.465 Y=-16362.510 Z=10147.004) + "Boulder Field Page Drawing 8": base_id + 1191, # Pages_Drawing8 Pages_Environment_Details (X=50496.270 Y=-26090.533 Z=9835.365) + "Boulder Field Scraps 1": base_id + 1192, # ItemPickup293_8 Pages_Environment_Main (X=41385.406 Y=-32281.871 Z=10240.781) + "Boulder Field Scraps 2": base_id + 1193, # ItemPickup987321 Pages_House_Main (X=46654.969 Y=-38859.254 Z=9920.861) + "Boulder Field Scraps 3": base_id + 1194, # ItemPickup516121 Pages_House_Main (X=44765.836 Y=-41675.559 Z=9938.179) + "Boulder Field Scraps 4": base_id + 1195, # ItemPickup291_2 Pages_Environment_Main (X=50088.270 Y=-30669.107 Z=9267.371) + "Boulder Field Scraps 5": base_id + 1196, # ItemPickup303_38 Pages_Environment_Main (X=48014.609 Y=-28971.115 Z=9199.659) + "Boulder Field Scraps 6": base_id + 1197, # ItemPickup302_35 Pages_Environment_Main (X=50190.266 Y=-26243.977 Z=9648.289) + "Boulder Field Scraps 7": base_id + 1198, # ItemPickup305_44 Pages_Environment_Main (X=47802.246 Y=-22594.684 Z=9631.879) + "Boulder Field Scraps 8": base_id + 1199, # ItemPickup294_11 Pages_Environment_Main (X=44345.996 Y=-23408.535 Z=9659.643) + "Boulder Field Scraps 9": base_id + 1200, # ItemPickup295_14 Pages_Environment_Main (X=41620.590 Y=-22982.641 Z=9720.177) + "Boulder Field Scraps 10": base_id + 1201, # ItemPickup300_29 Pages_Environment_Main (X=52003.172 Y=-19163.049 Z=9925.105) + "Boulder Field Scraps 11": base_id + 1202, # ItemPickup301_32 Pages_Environment_Main (X=51422.176 Y=-22319.322 Z=10663.813) + "Boulder Field Scraps 12": base_id + 1203, # ItemPickup296_17 Pages_Environment_Main (X=43527.176 Y=-17952.570 Z=10812.458) + "Boulder Field Scraps 13": base_id + 1204, # ItemPickup297_20 Pages_Environment_Main (X=45241.871 Y=-15847.636 Z=9952.198) + "Boulder Field Scraps 14": base_id + 1205, # ItemPickup298_23 Pages_Environment_Main (X=46238.027 Y=-18407.420 Z=10199.825) + "Boulder Field Scraps 15": base_id + 1206, # ItemPickup299_26 Pages_Environment_Main (X=49835.617 Y=-17379.959 Z=9810.836) + "Boulder Field Scraps 16": base_id + 1207, # ItemPickup306_47 Pages_Environment_Main (X=45144.594 Y=-33817.090 Z=10136.658) + "Boulder Field Scraps 17": base_id + 1208, # ItemPickup292_5 Pages_Environment_Main (X=44336.184 Y=-37162.367 Z=9789.548) + "Boulder Field Scraps 18": base_id + 1209 # ItemPickup304_41 Pages_Environment_Main (X=44490.160 Y=-26442.754 Z=9974.022) +} + +loc_haunted_house = { + "Haunted House Sasha Mission End": base_id + 1210, # (dialog 2) -> 40_scraps_reward + "Haunted House Scraps 1": base_id + 1211, # ItemPickup1309876 Pages_House_Main (X=42900.188 Y=-43760.617 Z=9900.531) + "Haunted House Scraps 2": base_id + 1212, # ItemPickup22213 Pages_House_Main (X=43608.078 Y=-44642.434 Z=9922.888) + "Haunted House Scraps 3": base_id + 1213, # ItemPickup5423189 Pages_House_Main (X=43992.387 Y=-44259.336 Z=9877.623) + "Haunted House Scraps 4": base_id + 1214, # ItemPickup1312312 Pages_House_Main (X=43340.012 Y=-45362.617 Z=9882.796) + "Haunted House Scraps 5": base_id + 1215, # ItemPickup1596 Pages_House_Main (X=45105.383 Y=-45980.879 Z=9854.796) + "Haunted House Scraps 6": base_id + 1216 # ItemPickup8624 Pages_House_Main (X=45888.406 Y=-46050.246 Z=9555.326) +} + +loc_santiago_house = { + "Santiago House Scraps 1": base_id + 1217, # ItemPickup342_19 PortNPCHouse_Details (X=37271.445 Y=-46075.598 Z=10648.827) + "Santiago House Scraps 2": base_id + 1218, # ItemPickup37_5 PortNPCHouse_Details (X=38330.512 Y=-47184.668 Z=10387.618) + "Santiago House Scraps 3": base_id + 1219, # ItemPickup337_2 PortNPCHouse_Details (X=35720.422 Y=-49536.328 Z=10098.503) + "Santiago House Scraps 4": base_id + 1220, # ItemPickup344_25 PortNPCHouse_Details (X=35466.285 Y=-50363.078 Z=10098.504) + "Santiago House Scraps 5": base_id + 1221, # ItemPickup338_7 PortNPCHouse_Details (X=34274.289 Y=-49947.578 Z=10098.501) + "Santiago House Scraps 6": base_id + 1222, # ItemPickup341_16 PortNPCHouse_Details (X=35584.359 Y=-48195.172 Z=10323.833) + "Santiago House Scraps 7": base_id + 1223, # ItemPickup340_13 PortNPCHouse_Details (X=35019.766 Y=-49904.113 Z=10124.169) + "Santiago House Scraps 8": base_id + 1224, # ItemPickup339_10 PortNPCHouse_Details (X=35527.711 Y=-49614.801 Z=10124.016) + "Santiago House Scraps 9": base_id + 1225, # ItemPickup36_2 PortNPCHouse_Details (X=34471.707 Y=-49497.000 Z=10199.790) + "Santiago House Scraps 10": base_id + 1226, # ItemPickup343_22 PortNPCHouse_Details (X=37920.277 Y=-51867.754 Z=9847.511) + "Santiago House Journal": base_id + 1227 # Port_Journal_Pickup PortNPCHouse_Details (X=34690.777 Y=-49788.359 Z=10214.353) +} + +loc_port = { + "Port Grey Paint Can": base_id + 1228, # PaintCan_13 Port_Details (X=74641.648 Y=-11320.948 Z=7551.767) + "Port Scraps 1": base_id + 1229, # ItemPickup334_32 Port_Main (X=67315.281 Y=-13828.055 Z=10101.339) + "Port Scraps 2": base_id + 1230, # ItemPickup335_35 Port_Main (X=67679.508 Y=-14127.952 Z=10061.037) + "Port Scraps 3": base_id + 1231, # ItemPickup336_38 Port_Main (X=67062.219 Y=-15626.003 Z=10065.956) + "Port Scraps 4": base_id + 1232, # ItemPickup21_15 Port_Main (X=66140.914 Y=-16079.730 Z=10092.268) + "Port Scraps 5": base_id + 1233, # ItemPickup18_12 Port_Main (X=66824.719 Y=-14729.157 Z=10125.234) + "Port Scraps 6": base_id + 1234, # ItemPickup333_29 Port_Main (X=69777.258 Y=-8371.526 Z=9391.735) + "Port Scraps 7": base_id + 1235, # ItemPickup332_26 Port_Main (X=70339.695 Y=-11066.703 Z=8912.465) + "Port Scraps 8": base_id + 1236, # ItemPickup331_23 Port_Main (X=72729.508 Y=-7048.998 Z=8245.522) + "Port Scraps 9": base_id + 1237, # ItemPickup329_17 Port_Main (X=75896.070 Y=-8705.214 Z=7514.992) + "Port Scraps 10": base_id + 1238, # ItemPickup330_20 Port_Main (X=74264.211 Y=-10553.446 Z=7520.141) + "Port Scraps 11": base_id + 1239, # ItemPickup17_9 Port_Main (X=74328.117 Y=-11423.852 Z=7511.827) + "Port Scraps 12": base_id + 1240, # ItemPickup328_14 Port_Main (X=76753.164 Y=-10744.933 Z=7437.174) + "Port Scraps 13": base_id + 1241, # ItemPickup326_8 Port_Main (X=77330.414 Y=-11640.151 Z=7189.003) + "Port Scraps 14": base_id + 1242, # ItemPickup327_11 Port_Main (X=76403.516 Y=-12484.995 Z=7440.368) + "Port Scraps 15": base_id + 1243, # ItemPickup324_2 Port_Main (X=78651.977 Y=-12233.159 Z=7439.514) + "Port Scraps 16": base_id + 1244, # ItemPickup14_5 Port_Main (X=80336.297 Y=-12276.590 Z=7436.639) + "Port Scraps 17": base_id + 1245, # ItemPickup325_5 Port_Main (X=79845.086 Y=-13410.705 Z=7440.597) + "Port Scraps 18": base_id + 1246, # ItemPickup13_2 Port_Main (X=76156.719 Y=-12816.718 Z=7439.269) KO + "Port Scraps 19": base_id + 1247, # ItemPickup16 Port_Main (X=80754.914 Y=-14055.545 Z=7445.339) KO + "Port Santiago Mission End": base_id + 1248 # (dialog 3) -> 35_scraps_reward +} + +loc_trench_house = { + "Trench House Scraps 1": base_id + 1249, # ItemPickup157_2 DeadWoodsEnvironment (X=76340.328 Y=-42886.191 Z=9567.521) + "Trench House Scraps 2": base_id + 1250, # ItemPickup158_5 DeadWoodsEnvironment (X=76013.594 Y=-44140.141 Z=9413.147) + "Trench House Scraps 3": base_id + 1251, # ItemPickup159_11 DeadWoodsEnvironment (X=74408.320 Y=-45424.000 Z=9446.966) + "Trench House Scraps 4": base_id + 1252, # ItemPickup69_14 Secret8_BasementHouseDetails (X=75196.344 Y=-48321.504 Z=9453.302) + "Trench House Scraps 5": base_id + 1253, # ItemPickup160_14 DeadWoodsEnvironment (X=73467.273 Y=-48995.738 Z=9355.070) + "Trench House Scraps 6": base_id + 1254, # ItemPickup163_23 DeadWoodsEnvironment (X=76418.469 Y=-53239.539 Z=9276.892) + "Trench House Scraps 7": base_id + 1255, # ItemPickup173_56 DeadWoodsEnvironment (X=70719.875 Y=-54290.117 Z=9357.084) + "Trench House Scraps 8": base_id + 1256, # ItemPickup165_29 DeadWoodsEnvironment (X=70075.938 Y=-53041.973 Z=9675.481) + "Trench House Scraps 9": base_id + 1257, # ItemPickup162_20 DeadWoodsEnvironment (X=74745.711 Y=-52304.027 Z=9073.130) + "Trench House Scraps 10": base_id + 1258, # ItemPickup68_11 Secret8_BasementHouseDetails (X=74519.750 Y=-53603.063 Z=9078.054) + "Trench House Scraps 11": base_id + 1259, # ItemPickup161_17 DeadWoodsEnvironment (X=73747.492 Y=-52589.906 Z=9104.748) + "Trench House Scraps 12": base_id + 1260, # ItemPickup67_8 Secret8_BasementHouseDetails (X=74333.125 Y=-52847.961 Z=9124.773) + "Trench House Scraps 13": base_id + 1261, # ItemPickup66_5 Secret8_BasementHouseDetails (X=74062.195 Y=-52663.043 Z=9122.827) + "Trench House Scraps 14": base_id + 1262, # ItemPickup65_2 Secret8_BasementHouseDetails (X=74820.492 Y=-51350.051 Z=7956.387) + "Trench House Scraps 15": base_id + 1263, # ItemPickup164_26 DeadWoodsEnvironment (X=75286.289 Y=-51164.098 Z=7957.081) + "Trench House Scraps 16": base_id + 1264, # ItemPickup174_59 DeadWoodsEnvironment (X=68413.258 Y=-56872.816 Z=9349.443) + "Trench House Scraps 17": base_id + 1265, # ItemPickup175_62 DeadWoodsEnvironment (X=67281.281 Y=-59201.371 Z=9254.457) + "Trench House Scraps 18": base_id + 1266, # ItemPickup172_50 DeadWoodsEnvironment (X=69064.219 Y=-48796.352 Z=9770.164) + "Trench House Chest Scraps 1": base_id + 1267, # ItemPickup75123123 Secret8_BasementHouseDetails (X=75042.141 Y=-50830.891 Z=8005.156) + "Trench House Chest Scraps 2": base_id + 1268, # ItemPickup741123 Secret8_BasementHouseDetails (X=75066.516 Y=-50824.398 Z=7995.000) + "Trench House Chest Scraps 3": base_id + 1269, # ItemPickup729842 Secret8_BasementHouseDetails (X=75072.789 Y=-50818.441 Z=7986.979) + "Trench House Chest Scraps 4": base_id + 1270, # ItemPickup711123 Secret8_BasementHouseDetails (X=75038.656 Y=-50827.566 Z=7973.354) + "Trench House Chest Scraps 5": base_id + 1271, # ItemPickup73 Secret8_BasementHouseDetails (X=75060.406 Y=-50828.102 Z=7965.915) + "Trench House Chest Scraps 6": base_id + 1272 # ItemPickup7075674 Secret8_BasementHouseDetails (X=75056.648 Y=-50818.125 Z=7959.868) +} + +loc_doll_woods = { + "Doll Woods Scraps 1": base_id + 1273, # ItemPickup78_2 DeadWoodsDolls (X=60126.234 Y=-49668.906 Z=9970.880) + "Doll Woods Scraps 2": base_id + 1274, # ItemPickup166_32 DeadWoodsEnvironment (X=59854.066 Y=-47313.121 Z=10376.684) + "Doll Woods Scraps 3": base_id + 1275, # ItemPickup80_8 DeadWoodsDolls (X=59130.613 Y=-49597.789 Z=9930.675) + "Doll Woods Scraps 4": base_id + 1276, # ItemPickup168_38 DeadWoodsEnvironment (X=59785.973 Y=-51269.684 Z=10180.019) + "Doll Woods Scraps 5": base_id + 1277, # ItemPickup81_11 DeadWoodsDolls (X=58226.449 Y=-52660.801 Z=10576.626) + "Doll Woods Scraps 6": base_id + 1278, # ItemPickup167_35 DeadWoodsEnvironment (X=56243.176 Y=-49097.793 Z=10869.889) + "Doll Woods Scraps 7": base_id + 1279, # ItemPickup79_5 DeadWoodsDolls (X=59481.672 Y=-45288.137 Z=10897.672) + "Doll Woods Scraps 8": base_id + 1280, # ItemPickup170_44 DeadWoodsEnvironment (X=63807.668 Y=-44674.734 Z=10337.434) + "Doll Woods Scraps 9": base_id + 1281, # ItemPickup171_47 DeadWoodsEnvironment (X=68406.664 Y=-45721.813 Z=10021.356) + "Doll Woods Scraps 10": base_id + 1282 # ItemPickup169_41 DeadWoodsEnvironment (X=62898.469 Y=-47565.703 Z=10744.431) +} + +loc_lost_stairs = { + "Lost Stairs Scraps 1": base_id + 1283, # ItemPickup29_2 Secret1_Stairs2 (X=47087.617 Y=-53476.547 Z=9103.093) + "Lost Stairs Scraps 2": base_id + 1284 # ItemPickup30_5 Secret1_Stairs2 (X=47162.238 Y=-55318.094 Z=9127.096) +} + +loc_east_house = { + "East House Scraps 1": base_id + 1285, # ItemPickup409_5 Secret7_CliffHouseEnvironment (X=97507.664 Y=-53201.270 Z=9174.678) + "East House Scraps 2": base_id + 1286, # ItemPickup408_2 Secret7_CliffHouseEnvironment (X=98511.242 Y=-53899.414 Z=9016.314) + "East House Scraps 3": base_id + 1287, # ItemPickup410_8 Secret7_CliffHouseEnvironment (X=100688.102 Y=-54197.578 Z=8919.432) + "East House Scraps 4": base_id + 1288, # ItemPickup411_11 Secret7_CliffHouseEnvironment (X=103149.773 Y=-54659.980 Z=9002.535) + "East House Scraps 5": base_id + 1289, # ItemPickup416_26 Secret7_CliffHouseEnvironment (X=107458.172 Y=-55683.793 Z=9429.004) + "East House Scraps 6": base_id + 1290, # ItemPickup25_2 Secret7_CliffHouseEnvironment (X=109034.164 Y=-54360.703 Z=9495.910) + "East House Scraps 7": base_id + 1291, # ItemPickup413_17 Secret7_CliffHouseEnvironment (X=109245.148 Y=-55045.242 Z=9553.601) + "East House Scraps 8": base_id + 1292, # ItemPickup414_20 Secret7_CliffHouseEnvironment (X=112556.445 Y=-55851.754 Z=10049.954) + "East House Scraps 9": base_id + 1293, # ItemPickup415_23 Secret7_CliffHouseEnvironment (X=113131.469 Y=-56822.508 Z=10038.047) + "East House Scraps 10": base_id + 1294, # ItemPickup2599786 Secret7_CliffHouseDetails (X=112279.828 Y=-56743.781 Z=10029.549) + "East House Scraps 11": base_id + 1295, # ItemPickup253321 Secret7_CliffHouseDetails (X=112445.508 Y=-56280.320 Z=10059.164) + "East House Scraps 12": base_id + 1296, # ItemPickup2532323 Secret7_CliffHouseDetails (X=112562.211 Y=-56736.332 Z=10454.907) + "East House Scraps 13": base_id + 1297, # ItemPickup257655 Secret7_CliffHouseDetails (X=109313.320 Y=-58221.316 Z=9501.283) + "East House Scraps 14": base_id + 1298, # ItemPickup412_14 Secret7_CliffHouseEnvironment (X=104077.805 Y=-55987.301 Z=9066.847) + "East House Chest Scraps 1": base_id + 1299, # ItemPickup76246 Secret7_CliffHouseDetails (X=112317.242 Y=-55820.805 Z=10497.336) + "East House Chest Scraps 2": base_id + 1300, # ItemPickup76245 Secret7_CliffHouseDetails (X=112326.086 Y=-55808.477 Z=10485.685) + "East House Chest Scraps 3": base_id + 1301, # ItemPickup85131 Secret7_CliffHouseDetails (X=112329.031 Y=-55828.438 Z=10478.107) + "East House Chest Scraps 4": base_id + 1302, # ItemPickup56124 Secret7_CliffHouseDetails (X=112315.922 Y=-55820.102 Z=10466.683) + "East House Chest Scraps 5": base_id + 1303 # ItemPickup25123123123 Secret7_CliffHouseDetails (X=112337.922 Y=-55821.848 Z=10456.924) +} + +loc_rockets_testing_ground = { + "Rockets Testing Ground Timed Dynamite": base_id + 1304, # Boomer_DynamitePickup Boomer_RangeDetails (X=76476.609 Y=-65286.738 Z=8303.742) + "Rockets Testing Ground Scraps 1": base_id + 1305, # ItemPickup105_14 Boomer_HouseDetails (X=88925.570 Y=-63375.051 Z=8563.354) + "Rockets Testing Ground Scraps 2": base_id + 1306, # ItemPickup106_17 Boomer_HouseDetails (X=84234.016 Y=-64475.551 Z=8382.108) + "Rockets Testing Ground Scraps 3": base_id + 1307, # ItemPickup114_23 Boomer_RangeDetails (X=79349.438 Y=-64225.480 Z=8384.219) + "Rockets Testing Ground Scraps 4": base_id + 1308, # ItemPickup22_0 Boomer_RangeDetails (X=79831.070 Y=-65847.766 Z=8301.337) + "Rockets Testing Ground Scraps 5": base_id + 1309, # ItemPickup109_5 Boomer_RangeDetails (X=76526.500 Y=-65394.875 Z=8223.883) + "Rockets Testing Ground Scraps 6": base_id + 1310, # ItemPickup108_2 Boomer_RangeDetails (X=76237.977 Y=-67087.414 Z=8361.979) + "Rockets Testing Ground Scraps 7": base_id + 1311, # ItemPickup115_26 Boomer_RangeDetails (X=78857.672 Y=-67802.227 Z=8257.150) + "Rockets Testing Ground Scraps 8": base_id + 1312, # ItemPickup110_8 Boomer_RangeDetails (X=74878.570 Y=-62927.297 Z=8749.549) + "Rockets Testing Ground Scraps 9": base_id + 1313, # ItemPickup111_11 Boomer_RangeDetails (X=74542.641 Y=-61301.082 Z=9493.931) + "Rockets Testing Ground Scraps 10": base_id + 1314 # ItemPickup23_0 Boomer_RangeDetails (X=77020.859 Y=-62031.320 Z=8873.663) + # "Rockets Testing Ground Scraps Glitch 1" ItemPickup107_20 (X=81308.406 Y=-63482.320 Z=8533.338) /!\ Glitched scrap +} + +loc_rockets_testing_bunker = { + "Rockets Testing Bunker Scraps 1": base_id + 1315, # ItemPickup113_20 Boomer_RangeDetails (X=77552.094 Y=-61144.559 Z=8523.195) + "Rockets Testing Bunker Scraps 2": base_id + 1316, # ItemPickup112_14 Boomer_RangeDetails (X=77670.227 Y=-62029.941 Z=8570.785) + "Rockets Testing Bunker Box of Rockets": base_id + 1317 # Boomer_RocketsPickup Boomer_RangeDetails (X=77330.086 Y=-61504.324 Z=8523.195) +} + +loc_workshop = { + "Workshop Scraps 1": base_id + 1318, # ItemPickup103_8 Boomer_HouseDetails (X=93550.773 Y=-61901.797 Z=8828.551) + "Workshop Scraps 2": base_id + 1319, # ItemPickup102_5 Boomer_HouseDetails (X=93508.047 Y=-64009.910 Z=8783.468) + "Workshop Scraps 3": base_id + 1320, # ItemPickup101_2 Boomer_HouseDetails (X=92011.648 Y=-65572.281 Z=8736.709) + "Workshop Scraps 4": base_id + 1321, # ItemPickup24_2 Boomer_HouseDetails (X=92311.594 Y=-63045.211 Z=8749.977) + "Workshop Scraps 5": base_id + 1322, # ItemPickup104_11 Boomer_HouseDetails (X=91392.734 Y=-63527.629 Z=8709.268) + "Workshop Scraps 6": base_id + 1323, # ItemPickup25_1 Boomer_HouseDetails (X=92986.789 Y=-63012.047 Z=9235.383) + "Workshop John Smith Mission End": base_id + 1324 # (dialog 2) -> the_boomer +} + +loc_east_tower = { + "Greg Mission Start": base_id + 1325, # (dialog 6) -> north_mine_key + "East Tower Scraps 1": base_id + 1326, # ItemPickup231_17 Mine2_NPCHouseDetails (X=95448.250 Y=-67249.156 Z=8607.896) + "East Tower Scraps 2": base_id + 1327, # ItemPickup228_8 Mine2_NPCHouseDetails (X=96339.242 Y=-66374.828 Z=8650.519) + "East Tower Scraps 3": base_id + 1328, # ItemPickup229_11 Mine2_NPCHouseDetails (X=98540.711 Y=-67173.656 Z=8418.825) + "East Tower Scraps 4": base_id + 1329, # ItemPickup230_14 Mine2_NPCHouseDetails (X=97276.414 Y=-68495.008 Z=8337.229) + "East Tower Scraps 5": base_id + 1330, # ItemPickup227_5 Mine2_NPCHouseDetails (X=96470.820 Y=-66540.859 Z=8953.763) + "East Tower Scraps 6": base_id + 1331 # ItemPickup226_2 Mine2_NPCHouseDetails (X=96141.555 Y=-67013.445 Z=9399.308) +} + +loc_lighthouse = { + "Lighthouse Scraps 1": base_id + 1332, # ItemPickup200_41 LighthouseTerrainMain (X=100072.813 Y=-68645.688 Z=8150.313) + "Lighthouse Scraps 2": base_id + 1333, # ItemPickup198_35 LighthouseTerrainMain (X=105340.594 Y=-70828.602 Z=8436.780) + "Lighthouse Scraps 3": base_id + 1334, # ItemPickup199_38 LighthouseTerrainMain (X=103851.688 Y=-73396.625 Z=7973.290) + "Lighthouse Scraps 4": base_id + 1335, # ItemPickup196_29 LighthouseTerrainMain (X=107040.711 Y=-74021.555 Z=8303.216) + "Lighthouse Scraps 5": base_id + 1336, # ItemPickup197_32 LighthouseTerrainMain (X=110566.859 Y=-77435.961 Z=7642.565) + "Lighthouse Scraps 6": base_id + 1337, # ItemPickup32_2 LighthouseShed_Main (X=111451.352 Y=-77351.117 Z=7633.413) + "Lighthouse Scraps 7": base_id + 1338, # ItemPickup35_11 Lighthouse_Main (X=113078.500 Y=-78618.281 Z=7180.793) + "Lighthouse Scraps 8": base_id + 1339, # ItemPickup192_17 LighthouseTerrainMain (X=113396.305 Y=-80315.383 Z=7184.260) + "Lighthouse Scraps 9": base_id + 1340, # ItemPickup193_20 LighthouseTerrainMain (X=114057.484 Y=-81517.836 Z=7245.034) + "Lighthouse Scraps 10": base_id + 1341, # ItemPickup194_23 LighthouseTerrainMain (X=110915.156 Y=-78376.609 Z=7676.131) + "Lighthouse Scraps 11": base_id + 1342, # ItemPickup195_26 LighthouseTerrainMain (X=109341.703 Y=-79014.469 Z=8075.679) + "Lighthouse Scraps 12": base_id + 1343, # ItemPickup33_5 Lighthouse_Details (X=107006.578 Y=-81377.711 Z=8821.629) + "Lighthouse Scraps 13": base_id + 1344, # ItemPickup191_14 LighthouseTerrainMain (X=109240.195 Y=-82951.375 Z=8194.619) + "Lighthouse Scraps 14": base_id + 1345, # ItemPickup190_11 LighthouseTerrainMain (X=106295.719 Y=-84190.578 Z=8581.896) + "Lighthouse Scraps 15": base_id + 1346, # ItemPickup189_8 LighthouseTerrainMain (X=104233.883 Y=-84663.328 Z=7806.311) + "Lighthouse Scraps 16": base_id + 1347, # ItemPickup188_5 LighthouseTerrainMain (X=103209.227 Y=-81564.047 Z=8140.578) + "Lighthouse Scraps 17": base_id + 1348, # ItemPickup187_2 LighthouseTerrainMain (X=104795.555 Y=-81344.758 Z=8775.158) + "Lighthouse Scraps 18": base_id + 1349, # ItemPickup34_8 Lighthouse_Main (X=100843.914 Y=-78038.539 Z=7197.542) + "Lighthouse Breaker 1": base_id + 1350, # ItemPickup13_2 LighthouseShed_Main (X=110781.164 Y=-77296.813 Z=7757.248) \!/ Existing match 6 + "Lighthouse Breaker 2": base_id + 1351, # ItemPickup14 LighthouseShed_Main (X=110899.227 Y=-77239.031 Z=7757.134) \!/ Existing match 3 + "Lighthouse Breaker 3": base_id + 1352, # ItemPickup16 LighthouseShed_Main (X=110948.547 Y=-77253.336 Z=7757.134) \!/ Existing match 2 + "Lighthouse Breaker 4": base_id + 1353, # ItemPickup17 LighthouseShed_Main (X=111001.078 Y=-77205.047 Z=7757.134) \!/ Existing match 1 + "Lighthouse Claire Mission End": base_id + 1354 # (dialog 2) -> 30_scraps_reward +} + +loc_north_mine_outside = { + "North Mine Outside Scraps 1": base_id + 1355, # ItemPickup241_31 Mine2_OutsideDetails (X=-52376.746 Y=-101857.492 Z=10542.841) + "North Mine Outside Scraps 2": base_id + 1356, # ItemPickup242_34 Mine2_OutsideDetails (X=-53786.742 Y=-102067.789 Z=10858.948) + "North Mine Outside Scraps 3": base_id + 1357, # ItemPickup239_25 Mine2_OutsideDetails (X=-57502.777 Y=-105475.336 Z=10609.405) + "North Mine Outside Scraps 4": base_id + 1358, # ItemPickup16_2 Mine2_OutsideDetails (X=-58102.102 Y=-104007.906 Z=11146.535) + "North Mine Outside Scraps 5": base_id + 1359, # ItemPickup238_20 Mine2_OutsideDetails (X=-59474.840 Y=-105053.734 Z=11213.524) + "North Mine Outside Scraps 6": base_id + 1360, # ItemPickup240_28 Mine2_OutsideDetails (X=-55011.750 Y=-104936.359 Z=9935.366) + "North Mine Outside Scraps 7": base_id + 1361, # ItemPickup236_14 Mine2_OutsideDetails (X=-55594.863 Y=-107667.594 Z=9596.611) + "North Mine Outside Scraps 8": base_id + 1362, # ItemPickup15_1 Mine2_Interior2 (X=-56632.578 Y=-109503.406 Z=9280.788) + "North Mine Outside Scraps 9": base_id + 1363, # ItemPickup234_8 Mine2_OutsideDetails (X=-54645.418 Y=-110747.602 Z=9553.452) + "North Mine Outside Scraps 10": base_id + 1364, # ItemPickup232_2 Mine2_OutsideDetails (X=-51561.340 Y=-113574.813 Z=9414.959) + "North Mine Outside Scraps 11": base_id + 1365, # ItemPickup233_5 Mine2_OutsideDetails (X=-54072.105 Y=-112672.031 Z=10077.665) + "North Mine Outside Scraps 12": base_id + 1366, # ItemPickup237_17 Mine2_OutsideDetails (X=-58042.758 Y=-108748.656 Z=9693.470) + "North Mine Outside Scraps 13": base_id + 1367, # ItemPickup235_11 Mine2_OutsideDetails (X=-55717.227 Y=-110610.414 Z=9487.879) + "North Mine Outside Scraps 14": base_id + 1368 # ItemPickup13_2 Mine2_Interior2 (X=-52235.836 Y=-114501.117 Z=9462.438) KO +} + +loc_north_mine_inside = { + "North Mine Inside Scraps 1": base_id + 1369, # ItemPickup17_2 Mine2_Interior1 (X=-58433.055 Y=-104081.570 Z=9378.083) KO + "North Mine Inside Scraps 2": base_id + 1370, # ItemPickup246_2 Mine2_Interior1 (X=-58987.199 Y=-103262.906 Z=9186.494) + "North Mine Inside Scraps 3": base_id + 1371, # ItemPickup247_5 Mine2_Interior1 (X=-58812.801 Y=-99259.570 Z=8847.714) + "North Mine Inside Scraps 4": base_id + 1372, # ItemPickup248_8 Mine2_Interior1 (X=-56634.379 Y=-99529.563 Z=8851.877) + "North Mine Inside Scraps 5": base_id + 1373, # ItemPickup22_4 Mine2_Interior1 (X=-55604.477 Y=-98342.906 Z=8842.766) + "North Mine Inside Scraps 6": base_id + 1374, # ItemPickup250_14 Mine2_Interior1 (X=-54824.535 Y=-98526.492 Z=8852.156) + "North Mine Inside Scraps 7": base_id + 1375, # ItemPickup21_14 Mine2_Interior1 (X=-54887.254 Y=-99047.141 Z=8849.855) + "North Mine Inside Scraps 8": base_id + 1376, # ItemPickup20_2 Mine2_Interior1 (X=-55610.020 Y=-101877.961 Z=9081.042) + "North Mine Inside Scraps 9": base_id + 1377, # ItemPickup19_2 Mine2_Interior1 (X=-56519.340 Y=-101375.008 Z=9001.270) + "North Mine Inside Scraps 10": base_id + 1378, # ItemPickup249_11 Mine2_Interior1 (X=-53329.922 Y=-99469.773 Z=8848.643) + "North Mine Inside Scraps 11": base_id + 1379, # ItemPickup251_17 Mine2_Interior1 (X=-52814.828 Y=-96286.969 Z=8851.372) + "North Mine Inside Scraps 12": base_id + 1380, # ItemPickup24_1 Mine2_Interior1 (X=-52605.957 Y=-96535.156 Z=8940.480) + "North Mine Inside Scraps 13": base_id + 1381, # ItemPickup23_20 Mine2_Interior1 (X=-53237.699 Y=-96609.461 Z=8846.201) + "North Mine Inside Scraps 14": base_id + 1382, # ItemPickup18_5 Mine2_Interior1 (X=-58543.488 Y=-95879.695 Z=8981.646) + "North Mine Inside Blue Egg": base_id + 1383, # Mine2_Egg Mine2_Interior2 (X=-53592.195 Y=-99177.500 Z=8975.387) + "North Mine Inside Blue Paint Can": base_id + 1384 # PaintCan_2 Mine2_Interior2 (X=-56133.391 Y=-101870.047 Z=9004.720) \!/ Existing match 5 + # "North Mine Inside Secret Gear" ItemPickup26_2 (X=-55546.859 Y=-98209.852 Z=8429.085) /!\ Inaccessible gear +} + +loc_wood_bridge = { + "Wood Bridge Scraps 1": base_id + 1385, # ItemPickup127_35 Bridge_Details (X=-66790.141 Y=-110340.367 Z=10454.417) + "Wood Bridge Scraps 2": base_id + 1386, # ItemPickup18613654 Bridge_Details (X=-68364.586 Y=-111691.625 Z=10444.172) + "Wood Bridge Scraps 3": base_id + 1387, # ItemPickup1311221 Bridge_StructureDetails (X=-69013.555 Y=-112353.977 Z=10399.942) + "Wood Bridge Scraps 4": base_id + 1388, # ItemPickup93564 Bridge_StructureDetails (X=-70398.797 Y=-112916.945 Z=10372.192) + "Wood Bridge Scraps 5": base_id + 1389, # ItemPickup161323 Bridge_Details (X=-71336.172 Y=-106966.672 Z=8430.104) + "Wood Bridge Scraps 6": base_id + 1390, # ItemPickup128_38 Bridge_Details (X=-72776.086 Y=-107813.102 Z=8305.589) + "Wood Bridge Scraps 7": base_id + 1391, # ItemPickup17975 Bridge_Details (X=-75224.648 Y=-108280.867 Z=7929.499) + "Wood Bridge Scraps 8": base_id + 1392, # ItemPickup126_32 Bridge_Details (X=-68112.172 Y=-105119.656 Z=9458.937) + "Wood Bridge Scraps 9": base_id + 1393, # ItemPickup118_8 Bridge_Details (X=-71847.625 Y=-103623.203 Z=10707.521) + "Wood Bridge Scraps 10": base_id + 1394, # ItemPickup116_2 Bridge_Details (X=-71812.219 Y=-107256.094 Z=10780.134) + "Wood Bridge Scraps 11": base_id + 1395, # ItemPickup134321 Bridge_Details (X=-72011.570 Y=-109054.547 Z=10866.852) + "Wood Bridge Scraps 12": base_id + 1396, # ItemPickup117_5 Bridge_Details (X=-72862.430 Y=-106144.852 Z=10329.061) + "Wood Bridge Scraps 13": base_id + 1397 # ItemPickup1494567 Bridge_Details (X=-71843.117 Y=-107174.133 Z=10367.116) +} + +loc_museum = { + "Museum Scraps 1": base_id + 1398, # ItemPickup119_11 Bridge_Details (X=-69687.773 Y=-100002.406 Z=10806.339) + "Museum Scraps 2": base_id + 1399, # ItemPickup120_14 Bridge_Details (X=-68035.195 Y=-99480.672 Z=11049.731) + "Museum Scraps 3": base_id + 1400, # ItemPickup125_29 Bridge_Details (X=-66912.641 Y=-99976.750 Z=11064.357) + "Museum Scraps 4": base_id + 1401, # ItemPickup13532 Bridge_HouseDetails (X=-64901.117 Y=-99624.953 Z=11176.359) + "Museum Scraps 5": base_id + 1402, # ItemPickup121_17 Bridge_Details (X=-66082.328 Y=-98105.555 Z=11089.308) + "Museum Scraps 6": base_id + 1403, # ItemPickup21765 Bridge_HouseDetails (X=-67402.742 Y=-97735.133 Z=11153.927) + "Museum Scraps 7": base_id + 1404, # ItemPickup124_26 Bridge_Details (X=-66716.031 Y=-98282.508 Z=11195.624) + "Museum Scraps 8": base_id + 1405, # ItemPickup122_20 Bridge_Details (X=-66582.703 Y=-99092.461 Z=11630.082) + "Museum Scraps 9": base_id + 1406, # ItemPickup123_23 Bridge_Details (X=-66798.164 Y=-99550.266 Z=11547.321) + "Museum Scraps 10": base_id + 1407, # ItemPickup183423 Bridge_HouseDetails (X=-66850.336 Y=-99682.844 Z=11543.618) + "Museum Scraps 11": base_id + 1408, # ItemPickup244_40 Mine2_OutsideDetails (X=-60156.828 Y=-98516.953 Z=11811.422) + "Museum Scraps 12": base_id + 1409, # ItemPickup245_43 Mine2_OutsideDetails (X=-61195.203 Y=-98262.422 Z=11779.118) + "Museum Paul Mission Start": base_id + 1410, # (dialog 6) -> remote_explosive (x8) + "Museum Paul Mission End": base_id + 1411 # (dialog 3) -> temple_key +} + +loc_barbed_shelter = { + "Barbed Shelter Gertrude Mission Start": base_id + 1412, # (dialog 4) -> broken_bob + "Barbed Shelter Scraps 1": base_id + 1413, # ItemPickup100_8 Bob_NPCHouseMain (X=-72525.500 Y=-89333.734 Z=9820.663) + "Barbed Shelter Scraps 2": base_id + 1414, # ItemPickup98_2 Bob_NPCHouseMain (X=-74870.758 Y=-88576.641 Z=9836.814) + "Barbed Shelter Scraps 3": base_id + 1415, # ItemPickup22_1 Bob_NPCHouseDetails (X=-76193.914 Y=-88038.836 Z=9818.776) + "Barbed Shelter Scraps 4": base_id + 1416, # ItemPickup99_5 Bob_NPCHouseMain (X=-74494.859 Y=-87609.969 Z=9837.866) + "Barbed Shelter Scraps 5": base_id + 1417 # ItemPickup23_3 Bob_NPCHouseDetails (X=-74826.930 Y=-88402.039 Z=9929.854) +} + +loc_west_beach = { + "West Beach Chest Scraps 1": base_id + 1418, # ItemPickup9122346 Secret11_Details (X=-85934.047 Y=-89532.547 Z=7383.054) + "West Beach Chest Scraps 2": base_id + 1419, # ItemPickup84 Secret11_Details (X=-85933.977 Y=-89532.977 Z=7369.364) + "West Beach Chest Scraps 3": base_id + 1420, # ItemPickup9099877 Secret11_Details (X=-85951.000 Y=-89527.023 Z=7367.054) + "West Beach Chest Scraps 4": base_id + 1421, # ItemPickup89086423 Secret11_Details (X=-85932.461 Y=-89533.148 Z=7354.001) + "West Beach Chest Scraps 5": base_id + 1422, # ItemPickup83 Secret11_Details (X=-85950.930 Y=-89527.453 Z=7353.365) + "West Beach Chest Scraps 6": base_id + 1423, # ItemPickup82_2 Secret11_Details (X=-85932.391 Y=-89533.578 Z=7340.312) + "West Beach Scraps 1": base_id + 1424, # ItemPickup87_13 Secret11_Details (X=-84489.945 Y=-91235.977 Z=8360.803) + "West Beach Scraps 2": base_id + 1425, # ItemPickup349_2 Secret11_Details1 (X=-84386.320 Y=-90391.789 Z=8376.434) + "West Beach Scraps 3": base_id + 1426, # ItemPickup86_10 Secret11_Details (X=-84714.773 Y=-89876.992 Z=7707.064) + "West Beach Scraps 4": base_id + 1427, # ItemPickup350_5 Secret11_Details1 (X=-85478.672 Y=-90648.414 Z=7708.377) + "West Beach Scraps 5": base_id + 1428, # ItemPickup85_7 Secret11_Details (X=-86276.633 Y=-90674.289 Z=7532.364) + "West Beach Scraps 6": base_id + 1429, # ItemPickup88_16 Secret11_Details (X=-84363.055 Y=-87497.938 Z=7582.647) + "West Beach Scraps 7": base_id + 1430, # ItemPickup351_8 Secret11_Details1 (X=-86556.266 Y=-89748.484 Z=7297.274) + "West Beach Scraps 8": base_id + 1431 # ItemPickup352_11 Secret11_Details1 (X=-83210.836 Y=-92551.953 Z=8460.213) +} + +loc_church = { + "Church Black Paint Can": base_id + 1432, # PaintCan_4 Secret5_ChurchDetails (X=-67628.172 Y=-83801.375 Z=9865.983) + "Church Scraps 1": base_id + 1433, # ItemPickup391_11 Secret5_ChurchDetails (X=-64009.039 Y=-84252.156 Z=10258.335) + "Church Scraps 2": base_id + 1434, # ItemPickup389_5 Secret5_ChurchDetails (X=-66870.719 Y=-85202.180 Z=9843.936) + "Church Scraps 3": base_id + 1435, # ItemPickup388_2 Secret5_ChurchDetails (X=-68588.352 Y=-84041.867 Z=9790.541) + "Church Scraps 4": base_id + 1436, # ItemPickup396_26 Secret5_ChurchDetails (X=-67595.797 Y=-82120.094 Z=9818.303) + "Church Scraps 5": base_id + 1437, # ItemPickup390_8 Secret5_ChurchDetails (X=-67291.000 Y=-83324.836 Z=9774.942) + "Church Scraps 6": base_id + 1438, # ItemPickup392_14 Secret5_ChurchDetails (X=-65849.070 Y=-80676.477 Z=9895.943) + "Church Scraps 7": base_id + 1439, # ItemPickup395_23 Secret5_ChurchDetails (X=-65170.266 Y=-79155.227 Z=9904.275) + "Church Scraps 8": base_id + 1440, # ItemPickup24_4 Secret5_GraveyardMain (X=-64837.563 Y=-80885.305 Z=9906.755) + "Church Scraps 9": base_id + 1441, # ItemPickup22_3 Secret5_ChurchDetails (X=-68248.359 Y=-83578.008 Z=9807.300) + "Church Scraps 10": base_id + 1442, # ItemPickup23_5 Secret5_ChurchDetails (X=-67086.102 Y=-84605.086 Z=9805.521) + "Church Scraps 11": base_id + 1443, # ItemPickup393_17 Secret5_ChurchDetails (X=-67901.930 Y=-83477.625 Z=9812.613) + "Church Scraps 12": base_id + 1444 # ItemPickup394_20 Secret5_ChurchDetails (X=-65834.344 Y=-84192.102 Z=9987.823) +} + +loc_west_cottage = { + "West Cottage Gale Mission Start": base_id + 1445, # (dialog 10) -> mountain_ruin_key + "West Cottage Scraps 1": base_id + 1446, # ItemPickup15_3 Mine3_NPCHouse (X=-74407.695 Y=-81781.250 Z=10120.775) + "West Cottage Scraps 2": base_id + 1447, # ItemPickup283_5 Mine3_NPCHouseDetails (X=-73784.695 Y=-79414.359 Z=10128.285) + "West Cottage Scraps 3": base_id + 1448, # ItemPickup13_1 Mine3_NPCHouse (X=-73992.391 Y=-78600.094 Z=10162.495) + "West Cottage Scraps 4": base_id + 1449, # ItemPickup284_8 Mine3_NPCHouseDetails (X=-71623.000 Y=-75998.023 Z=10275.477) + "West Cottage Scraps 5": base_id + 1450 # ItemPickup282_2 Mine3_NPCHouseDetails (X=-72626.453 Y=-79391.070 Z=10211.037) +} + +loc_caravan = { + "Caravan Scraps 1": base_id + 1451, # ItemPickup348_11 Secret10_PAth (X=-52638.109 Y=-43924.395 Z=10579.809) + "Caravan Scraps 2": base_id + 1452, # ItemPickup347_8 Secret10_PAth (X=-50203.695 Y=-42865.672 Z=10778.871) + "Caravan Scraps 3": base_id + 1453, # ItemPickup346_5 Secret10_PAth (X=-48467.738 Y=-42018.488 Z=10818.758) + "Caravan Scraps 4": base_id + 1454, # ItemPickup77_14 Secret10_Details (X=-46325.219 Y=-41707.512 Z=11003.229) + "Caravan Scraps 5": base_id + 1455, # ItemPickup345_2 Secret10_PAth (X=-44557.043 Y=-40652.930 Z=11076.221) + "Caravan Scraps 6": base_id + 1456, # ItemPickup76_11 Secret10_Details (X=-43380.664 Y=-38207.152 Z=11165.370) + "Caravan Scraps 7": base_id + 1457, # ItemPickup73_2 Secret10_Details (X=-42919.410 Y=-38797.738 Z=11265.633) + "Caravan Scraps 8": base_id + 1458, # ItemPickup74_5 Secret10_Details (X=-42787.523 Y=-38601.820 Z=11254.003) + "Caravan Scraps 9": base_id + 1459, # ItemPickup75_8 Secret10_Details (X=-42711.363 Y=-39141.523 Z=11173.905) + "Caravan Chest Scraps 1": base_id + 1460, # ItemPickup71561 Secret10_Details (X=-42910.668 Y=-38297.309 Z=11233.402) + "Caravan Chest Scraps 2": base_id + 1461, # ItemPickup078654 Secret10_Details (X=-42904.344 Y=-38307.332 Z=11219.678) + "Caravan Chest Scraps 3": base_id + 1462, # ItemPickup02345 Secret10_Details (X=-42904.965 Y=-38280.383 Z=11208.191) + "Caravan Chest Scraps 4": base_id + 1463, # ItemPickup-6546483648 Secret10_Details (X=-42911.680 Y=-38315.254 Z=11204.225) + "Caravan Chest Scraps 5": base_id + 1464 # ItemPickup176752623547 Secret10_Details (X=-42905.090 Y=-38279.828 Z=11192.738) +} + +loc_trailer_cabin = { + "Trailer Cabin Scraps 1": base_id + 1465, # ItemPickup493_17 TrailerCabin_Details (X=-50702.449 Y=-38850.020 Z=10810.316) + "Trailer Cabin Scraps 2": base_id + 1466, # ItemPickup489_5 TrailerCabin_Details (X=-51365.684 Y=-38502.379 Z=10875.761) + "Trailer Cabin Scraps 3": base_id + 1467, # ItemPickup491_11 TrailerCabin_Details (X=-52397.570 Y=-37530.145 Z=10873.624) + "Trailer Cabin Scraps 4": base_id + 1468, # ItemPickup490_8 TrailerCabin_Details (X=-50625.746 Y=-37916.758 Z=10886.909) + "Trailer Cabin Scraps 5": base_id + 1469, # ItemPickup488_2 TrailerCabin_Details (X=-51201.051 Y=-37467.137 Z=10910.795) + "Trailer Cabin Scraps 6": base_id + 1470 # ItemPickup492_14 TrailerCabin_Details (X=-51891.320 Y=-40549.492 Z=10675.211) +} + +loc_towers = { + "Towers Scraps 1": base_id + 1471, # ItemPickup486_32 Towers_Environment_Details (X=-24434.766 Y=-25708.373 Z=11200.865) + "Towers Scraps 2": base_id + 1472, # ItemPickup483_23 Towers_Environment_Details (X=-20970.262 Y=-25678.754 Z=11731.241) + "Towers Scraps 3": base_id + 1473, # ItemPickup481_17 Towers_Environment_Details (X=-19812.230 Y=-27768.301 Z=12051.623) + "Towers Scraps 4": base_id + 1474, # ItemPickup484_26 Towers_Environment_Details (X=-19940.912 Y=-25411.576 Z=12035.366) + "Towers Scraps 5": base_id + 1475, # ItemPickup41_17 Towers_Environment (X=-18596.791 Y=-25100.035 Z=12290.350) + "Towers Scraps 6": base_id + 1476, # ItemPickup482_20 Towers_Environment_Details (X=-23302.396 Y=-23270.324 Z=12036.164) + "Towers Scraps 7": base_id + 1477, # ItemPickup487_35 Towers_Environment_Details (X=-22955.039 Y=-27576.859 Z=11211.258) + "Towers Scraps 8": base_id + 1478, # ItemPickup478_8 Towers_Environment_Details (X=-21485.520 Y=-29634.893 Z=11787.103) + "Towers Scraps 9": base_id + 1479, # ItemPickup477_5 Towers_Environment_Details (X=-23667.957 Y=-29825.240 Z=12035.269) + "Towers Scraps 10": base_id + 1480, # ItemPickup39_11 Towers_Environment (X=-25361.008 Y=-29794.301 Z=12026.073) + "Towers Scraps 11": base_id + 1481, # ItemPickup476_2 Towers_Environment_Details (X=-26549.584 Y=-32768.133 Z=12289.732) + "Towers Scraps 12": base_id + 1482, # ItemPickup38_8 Towers_Environment (X=-27240.127 Y=-27404.748 Z=12027.208) + "Towers Scraps 13": base_id + 1483, # ItemPickup40_14 Towers_Environment (X=-23231.639 Y=-27799.158 Z=11829.792) + "Towers Scraps 14": base_id + 1484, # ItemPickup485_29 Towers_Environment_Details (X=-22949.568 Y=-26146.012 Z=11702.730) + "Towers Scraps 15": base_id + 1485, # ItemPickup479_11 Towers_Environment_Details (X=-19726.715 Y=-32464.682 Z=12118.678) + "Towers Scraps 16": base_id + 1486, # ItemPickup1366543 Tower_BuildingsExteriorDetails (X=-23495.104 Y=-27644.689 Z=11872.844) + "Towers Scraps 17": base_id + 1487, # ItemPickup139978 Tower_BuildingsExteriorDetails (X=-23512.971 Y=-27493.051 Z=12218.543) + "Towers Scraps 18": base_id + 1488, # ItemPickup42_20 Towers_Environment (X=-22731.439 Y=-26331.393 Z=12102.758) + "Towers Scraps 19": base_id + 1489, # ItemPickup131123 Tower_BuildingsExteriorDetails (X=-22599.641 Y=-26454.590 Z=11752.040) + "Towers Scraps 20": base_id + 1490, # ItemPickup196987 Tower_BuildingsExteriorDetails (X=-22589.721 Y=-26397.414 Z=12571.282) + "Towers Scraps 21": base_id + 1491, # ItemPickup138787 Tower_BuildingsExteriorDetails (X=-22163.268 Y=-26775.938 Z=13107.048) + "Towers Scraps 22": base_id + 1492, # ItemPickup43_23 Towers_Environment (X=-21996.184 Y=-26754.393 Z=13105.997) + "Towers Scraps 23": base_id + 1493, # ItemPickup837454 Tower_BuildingsExteriorDetails (X=-24068.221 Y=-27874.443 Z=12819.666) + "Towers Scraps 24": base_id + 1494, # ItemPickup44_29 Towers_Environment (X=-23525.330 Y=-27770.035 Z=12612.871) + "Towers Scraps 25": base_id + 1495, # ItemPickup18932 Tower_BuildingsExteriorDetails (X=-23472.215 Y=-27617.404 Z=13213.256) + "Towers Scraps 26": base_id + 1496, # ItemPickup188348 Tower_BuildingsExteriorDetails (X=-23981.588 Y=-27984.385 Z=13219.854) + "Towers Scraps 27": base_id + 1497, # ItemPickup480_14 Towers_Environment_Details (X=-18696.230 Y=-34511.277 Z=12704.238) + "Towers Lime Paint Can": base_id + 1498, # PaintCan_2 Towers_BuildingsDetails (X=-22288.555 Y=-26022.281 Z=11835.892) \!/ Existing match 5 + "Towers Employment Contracts": base_id + 1499, # Towers_Files_Pickup Tower_BuildingsExteriorDetails (X=-24081.414 Y=-27637.459 Z=13679.163) + "Towers Ronny Mission End": base_id + 1500 # (dialog 3) -> 1_scraps_reward +} + +loc_north_beach = { + "North Beach Chest Scraps 1": base_id + 1501, # ItemPickup9254 Secret3_CampDetails (X=-74444.648 Y=-130627.672 Z=8793.757) + "North Beach Chest Scraps 2": base_id + 1502, # ItemPickup14523 Secret3_CampDetails (X=-74426.539 Y=-130626.547 Z=8781.948) + "North Beach Chest Scraps 3": base_id + 1503, # ItemPickup084537 Secret3_CampDetails (X=-74448.852 Y=-130632.367 Z=8772.555) + "North Beach Chest Scraps 4": base_id + 1504, # ItemPickup17754234 Secret3_CampDetails (X=-74425.523 Y=-130622.875 Z=8755.526) + "North Beach Scraps 1": base_id + 1505, # ItemPickup376_5 Secret3_CampDetails (X=-75003.078 Y=-131084.016 Z=8729.731) + "North Beach Scraps 2": base_id + 1506, # ItemPickup378_11 Secret3_CampDetails (X=-75477.758 Y=-129413.750 Z=9082.617) + "North Beach Scraps 3": base_id + 1507, # ItemPickup377_8 Secret3_CampDetails (X=-75608.453 Y=-130483.430 Z=8909.659) + "North Beach Scraps 4": base_id + 1508, # ItemPickup375_2 Secret3_CampDetails (X=-74143.469 Y=-131117.953 Z=8752.130) + "North Beach Scraps 5": base_id + 1509, # ItemPickup387_6 Secret4_BeachHouseMain (X=-80847.078 Y=-135628.719 Z=7915.444) + "North Beach Scraps 6": base_id + 1510, # ItemPickup386_3 Secret4_BeachHouseMain (X=-84044.789 Y=-137591.000 Z=7359.172) + "North Beach Scraps 7": base_id + 1511, # ItemPickup379_2 Secret4_BeachHouseDetails (X=-83992.836 Y=-132933.531 Z=7941.225) + "North Beach Scraps 8": base_id + 1512, # ItemPickup380_5 Secret4_BeachHouseDetails (X=-87355.734 Y=-134216.438 Z=7237.310) + "North Beach Scraps 9": base_id + 1513, # ItemPickup384_17 Secret4_BeachHouseDetails (X=-89213.844 Y=-134625.922 Z=7185.133) + "North Beach Scraps 10": base_id + 1514, # ItemPickup25_0 Secret4_BeachHouseDetails (X=-88423.430 Y=-135922.969 Z=7290.801) + "North Beach Scraps 11": base_id + 1515, # ItemPickup381_8 Secret4_BeachHouseDetails (X=-87668.977 Y=-136850.359 Z=7275.346) + "North Beach Scraps 12": base_id + 1516, # ItemPickup383_14 Secret4_BeachHouseDetails (X=-90241.328 Y=-136381.000 Z=7199.622) + "North Beach Scraps 13": base_id + 1517, # ItemPickup27_8 Secret4_BeachHouseDetails (X=-91728.680 Y=-135288.203 Z=7319.699) + "North Beach Scraps 14": base_id + 1518, # ItemPickup26_2 Secret4_BeachHouseDetails (X=-88789.039 Y=-135461.719 Z=7305.800) + "North Beach Scraps 15": base_id + 1519, # ItemPickup382_11 Secret4_BeachHouseDetails (X=-88572.078 Y=-135970.734 Z=7302.674) + "North Beach Teal Paint Can": base_id + 1520 # PaintCan_2 Secret4_BeachHouseDetails (X=-91706.805 Y=-134988.453 Z=7347.827) \!/ Existing match 5 + # "North Beach Scraps Glitch 1" ItemPickup385_20 (X=-77651.938 Y=-139721.453 Z=7261.729) /!\ Glitched scrap +} + +loc_mine_shaft = { + "Mine Shaft Chest Scraps 1": base_id + 1521, # ItemPickup0934569 Secret13_Details (X=-17360.789 Y=-74064.367 Z=8038.313) + "Mine Shaft Chest Scraps 2": base_id + 1522, # ItemPickup17234455622 Secret13_Details (X=-17360.814 Y=-74064.367 Z=8024.187) + "Mine Shaft Chest Scraps 3": base_id + 1523, # ItemPickup856743 Secret13_Details (X=-17361.059 Y=-74049.234 Z=8015.940) + "Mine Shaft Chest Scraps 4": base_id + 1524, # ItemPickup16456456 Secret13_Details (X=-17336.465 Y=-74087.063 Z=8009.707) + "Mine Shaft Chest Scraps 5": base_id + 1525, # ItemPickup234743 Secret13_Details (X=-17349.941 Y=-74075.484 Z=8004.179) + "Mine Shaft Chest Scraps 6": base_id + 1526, # ItemPickup1434563456 Secret13_Details (X=-17361.084 Y=-74049.234 Z=8001.814) + "Mine Shaft Chest Scraps 7": base_id + 1527, # ItemPickup13634563456 Secret13_Details (X=-17349.967 Y=-74075.484 Z=7990.054) + "Mine Shaft Scraps 1": base_id + 1528, # ItemPickup369_23 Secret13_Details (X=-16985.645 Y=-70377.273 Z=10837.127) + "Mine Shaft Scraps 2": base_id + 1529, # ItemPickup368_20 Secret13_Details (X=-18292.045 Y=-71003.563 Z=10975.308) + "Mine Shaft Scraps 3": base_id + 1530, # ItemPickup367_17 Secret13_Details (X=-16150.797 Y=-72075.289 Z=10609.141) + "Mine Shaft Scraps 4": base_id + 1531, # ItemPickup24456463 Secret13_EntranceDetails1 (X=-18404.480 Y=-71894.367 Z=10968.230) + "Mine Shaft Scraps 5": base_id + 1532, # ItemPickup2565644 Secret13_Details (X=-17777.268 Y=-71467.172 Z=10441.745) + "Mine Shaft Scraps 6": base_id + 1533, # ItemPickup366_14 Secret13_Details (X=-17630.971 Y=-72800.641 Z=8842.322) + "Mine Shaft Scraps 7": base_id + 1534, # ItemPickup18_8 Secret13_Details (X=-17979.719 Y=-73413.563 Z=8118.260) + "Mine Shaft Scraps 8": base_id + 1535, # ItemPickup21_11 Secret13_Details (X=-16554.467 Y=-74139.781 Z=7892.738) + "Mine Shaft Scraps 9": base_id + 1536, # ItemPickup365_11 Secret13_Details (X=-16343.033 Y=-74617.555 Z=7298.177) + "Mine Shaft Scraps 10": base_id + 1537, # ItemPickup22123 Secret13_Details (X=-12390.332 Y=-77620.320 Z=7324.504) + "Mine Shaft Scraps 11": base_id + 1538, # ItemPickup364_8 Secret13_Details (X=-10969.702 Y=-77961.477 Z=7297.171) + "Mine Shaft Scraps 12": base_id + 1539, # ItemPickup363_5 Secret13_Details (X=-9888.596 Y=-78208.930 Z=7269.473) + "Mine Shaft Scraps 13": base_id + 1540, # ItemPickup362_2 Secret13_Details (X=-8865.696 Y=-79063.977 Z=7247.677) + "Mine Shaft Scraps 14": base_id + 1541 # ItemPickup238976 Secret13_ExitDetails (X=-8143.984 Y=-79764.617 Z=7222.096) +} + +loc_mob_camp = { + "Mob Camp Key": base_id + 1542, # ItemPickup29_0 Bob_CampDetails2 (X=-29114.480 Y=-53608.520 Z=12839.528) + "Mob Camp Scraps 1": base_id + 1543, # ItemPickup25_5 Bob_CampDetails2 (X=-27373.525 Y=-53008.668 Z=12706.465) + "Mob Camp Scraps 2": base_id + 1544, # ItemPickup26_1 Bob_CampDetails2 (X=-28786.941 Y=-53009.762 Z=12760.727) + "Mob Camp Scraps 3": base_id + 1545, # ItemPickup13_14 Mine3_Mountain (X=-29650.207 Y=-53328.070 Z=12724.598) + "Mob Camp Scraps 4": base_id + 1546, # ItemPickup90_5 Bob_CampDetails2 (X=-31515.057 Y=-55533.324 Z=12344.274) + "Mob Camp Scraps 5": base_id + 1547, # ItemPickup49513294 Mine3_Mountain (X=-31847.229 Y=-55152.352 Z=11574.255) + "Mob Camp Scraps 6": base_id + 1548, # ItemPickup92_14 Bob_CampDetails2 (X=-31323.533 Y=-55432.871 Z=11245.139) + "Mob Camp Scraps 7": base_id + 1549, # ItemPickup91_8 Bob_CampDetails2 (X=-31583.443 Y=-55475.805 Z=11234.112) + "Mob Camp Scraps 8": base_id + 1550, # ItemPickup95_23 Bob_CampDetails2 (X=-32925.406 Y=-57157.605 Z=11086.322) + "Mob Camp Scraps 9": base_id + 1551, # ItemPickup96_26 Bob_CampDetails2 (X=-33052.488 Y=-58560.098 Z=11101.021) + "Mob Camp Scraps 10": base_id + 1552, # ItemPickup13121212 Mine3_Mountain (X=-32422.406 Y=-60145.063 Z=11203.182) + "Mob Camp Scraps 11": base_id + 1553, # ItemPickup93_17 Bob_CampDetails2 (X=-30891.457 Y=-60046.465 Z=11237.567) + "Mob Camp Scraps 12": base_id + 1554, # ItemPickup97_29 Bob_CampDetails2 (X=-31888.428 Y=-59222.645 Z=11179.302) + "Mob Camp Scraps 13": base_id + 1555, # ItemPickup62156 Mine3_Mountain (X=-31161.750 Y=-57410.789 Z=11279.820) + "Mob Camp Scraps 14": base_id + 1556, # ItemPickup24_3 Bob_CampDetails2 (X=-31256.545 Y=-59865.809 Z=11904.155) + "Mob Camp Scraps 15": base_id + 1557, # ItemPickup27_0 Bob_CampDetails2 (X=-31757.953 Y=-57179.258 Z=11295.150) + "Mob Camp Scraps 16": base_id + 1558 # ItemPickup89_2 Bob_CampDetails2 (X=-29137.043 Y=-54824.797 Z=12418.673) +} + +loc_mob_camp_locked_room = { + "Mob Camp Locked Room Scraps 1": base_id + 1559, # ItemPickup94_20 Bob_CampDetails2 (X=-31736.459 Y=-59761.465 Z=11211.379) + "Mob Camp Locked Room Scraps 2": base_id + 1560, # ItemPickup28_14 Bob_CampDetails2 (X=-32150.889 Y=-59879.594 Z=11297.058) + "Mob Camp Locked Room Stolen Bob": base_id + 1561 # Bob_Clickbox (X=-31771.172 Y=-59892.449 Z=11323.562) +} + +loc_mine_elevator_exit = { + "Mine Elevator Exit Scraps 1": base_id + 1562, # ItemPickup266_19 Mine3_ExitCampDetails (X=-29587.271 Y=-42650.797 Z=12515.042) + "Mine Elevator Exit Scraps 2": base_id + 1563, # ItemPickup265_16 Mine3_ExitCampDetails (X=-30727.555 Y=-42715.438 Z=12485.763) + "Mine Elevator Exit Scraps 3": base_id + 1564, # ItemPickup267_22 Mine3_ExitCampDetails (X=-29814.680 Y=-43722.777 Z=12518.878) + "Mine Elevator Exit Scraps 4": base_id + 1565, # ItemPickup261_2 Mine3_ExitCampDetails (X=-30983.000 Y=-42943.754 Z=12474.396) + "Mine Elevator Exit Scraps 5": base_id + 1566, # ItemPickup262_5 Mine3_ExitCampDetails (X=-31824.576 Y=-43997.270 Z=12345.908) + "Mine Elevator Exit Scraps 6": base_id + 1567, # ItemPickup268_25 Mine3_ExitCampDetails (X=-32553.924 Y=-44761.855 Z=12341.698) + "Mine Elevator Exit Scraps 7": base_id + 1568, # ItemPickup263_10 Mine3_ExitCampDetails (X=-33598.023 Y=-44369.297 Z=12438.430) + "Mine Elevator Exit Scraps 8": base_id + 1569, # ItemPickup264_13 Mine3_ExitCampDetails (X=-31947.459 Y=-42017.137 Z=12384.311) + "Mine Elevator Exit Scraps 9": base_id + 1570 # ItemPickup269_28 Mine3_ExitCampDetails (X=-30127.123 Y=-46004.891 Z=12229.104) +} + +loc_mountain_ruin_outside = { + "Mountain Ruin Outside Scraps 1": base_id + 1571, # ItemPickup112345556 Mine3_Outside (X=-2218.456 Y=-43914.789 Z=11238.952) + "Mountain Ruin Outside Scraps 2": base_id + 1572, # ItemPickup35621 Mine3_Outside (X=-2402.206 Y=-45494.766 Z=11244.650) + "Mountain Ruin Outside Scraps 3": base_id + 1573, # ItemPickup13000 Mine3_Outside (X=-2781.385 Y=-47365.313 Z=11235.389) + "Mountain Ruin Outside Scraps 4": base_id + 1574, # ItemPickup995959 Mine3_Outside (X=-2961.431 Y=-45445.973 Z=11255.289) + "Mountain Ruin Outside Scraps 5": base_id + 1575, # ItemPickup136999 Mine3_Outside (X=-5873.435 Y=-46300.633 Z=11228.667) + "Mountain Ruin Outside Scraps 6": base_id + 1576, # ItemPickup1589994 Mine3_Outside (X=-1823.357 Y=-47071.813 Z=11161.523) + "Mountain Ruin Outside Scraps 7": base_id + 1577, # ItemPickup09871230948 Mine3_Outside (X=-3478.155 Y=-49094.965 Z=11083.230) + "Mountain Ruin Outside Scraps 8": base_id + 1578, # ItemPickup258_20 Mine3_Camp (X=-4606.678 Y=-50246.180 Z=11613.938) + "Mountain Ruin Outside Scraps 9": base_id + 1579, # ItemPickup257_17 Mine3_Camp (X=-5454.638 Y=-53508.004 Z=12062.944) + "Mountain Ruin Outside Scraps 10": base_id + 1580, # ItemPickup18_3 Mine3_Camp (X=-8192.042 Y=-53726.535 Z=11947.394) + "Mountain Ruin Outside Scraps 11": base_id + 1581, # ItemPickup252_2 Mine3_Camp (X=-9409.834 Y=-53970.621 Z=11923.256) + "Mountain Ruin Outside Scraps 12": base_id + 1582, # ItemPickup254_8 Mine3_Camp (X=-8977.424 Y=-57134.637 Z=12232.596) + "Mountain Ruin Outside Scraps 13": base_id + 1583, # ItemPickup19_1 Mine3_Camp (X=-10449.292 Y=-56481.938 Z=12274.706) + "Mountain Ruin Outside Scraps 14": base_id + 1584, # ItemPickup255_11 Mine3_Camp (X=-10490.690 Y=-56584.301 Z=12281.096) + "Mountain Ruin Outside Scraps 15": base_id + 1585, # ItemPickup256_14 Mine3_Camp (X=-11600.937 Y=-55831.191 Z=12388.329) + "Mountain Ruin Outside Scraps 16": base_id + 1586, # ItemPickup259_23 Mine3_Camp (X=-3307.077 Y=-49973.461 Z=11282.041) + "Mountain Ruin Outside Scraps 17": base_id + 1587 # ItemPickup260_26 Mine3_Camp (X=-8878.345 Y=-49816.922 Z=13700.768) +} + +loc_mountain_ruin_inside = { + "Mountain Ruin Inside Scraps 1": base_id + 1588, # ItemPickup253_5 Mine3_Camp (X=-10647.446 Y=-52039.848 Z=11925.344) + "Mountain Ruin Inside Scraps 2": base_id + 1589, # ItemPickup270_2 Mine3_Interior1 (X=-12834.990 Y=-48683.176 Z=10200.083) + "Mountain Ruin Inside Scraps 3": base_id + 1590, # ItemPickup271_5 Mine3_Interior1 (X=-15748.594 Y=-44925.523 Z=10199.975) + "Mountain Ruin Inside Scraps 4": base_id + 1591, # ItemPickup20_3 Mine3_Interior1 (X=-15312.152 Y=-43957.055 Z=10350.783) + "Mountain Ruin Inside Scraps 5": base_id + 1592, # ItemPickup273_11 Mine3_Interior1 (X=-16709.586 Y=-44997.316 Z=10198.888) + "Mountain Ruin Inside Scraps 6": base_id + 1593, # ItemPickup272_8 Mine3_Interior1 (X=-17412.561 Y=-46041.977 Z=10349.650) + "Mountain Ruin Inside Scraps 7": base_id + 1594, # ItemPickup274_14 Mine3_Interior1 (X=-17452.596 Y=-43804.941 Z=10201.436) + "Mountain Ruin Inside Scraps 8": base_id + 1595, # ItemPickup21_2 Mine3_Interior1 (X=-18119.473 Y=-42001.453 Z=10198.855) + "Mountain Ruin Inside Scraps 9": base_id + 1596, # ItemPickup276_20 Mine3_Interior1 (X=-18975.068 Y=-42906.488 Z=10279.690) + "Mountain Ruin Inside Scraps 10": base_id + 1597, # ItemPickup277_26 Mine3_Interior1 (X=-19727.902 Y=-41581.039 Z=10199.614) + "Mountain Ruin Inside Scraps 11": base_id + 1598, # ItemPickup275_17 Mine3_Interior1 (X=-19187.891 Y=-40516.941 Z=10201.049) + "Mountain Ruin Inside Scraps 12": base_id + 1599, # ItemPickup278_29 Mine3_Interior1 (X=-22470.986 Y=-41602.875 Z=10073.847) + "Mountain Ruin Inside Scraps 13": base_id + 1600, # ItemPickup279_2 Mine3_Interior2 (X=-23717.383 Y=-42597.141 Z=7455.452) + "Mountain Ruin Inside Scraps 14": base_id + 1601, # ItemPickup22_7 Mine3_Interior2 (X=-24494.582 Y=-44598.086 Z=7433.633) + "Mountain Ruin Inside Scraps 15": base_id + 1602, # ItemPickup280_5 Mine3_Interior2 (X=-26783.293 Y=-42331.145 Z=7446.357) + "Mountain Ruin Inside Scraps 16": base_id + 1603, # ItemPickup281_8 Mine3_Interior2 (X=-28636.996 Y=-46745.340 Z=7430.463) + "Mountain Ruin Inside Scraps 17": base_id + 1604, # ItemPickup23_1 Mine3_Interior2 (X=-27752.643 Y=-47453.973 Z=7445.047) + "Mountain Ruin Inside Red Egg": base_id + 1605, # Mine3_EggPickup Mine3_Interior2 (X=-28254.400 Y=-45702.844 Z=7551.568) + "Mountain Ruin Inside Red Paint Can": base_id + 1606 # PaintCan_2 Mine3_Interior2 (X=-31391.293 Y=-44953.223 Z=7448.648) \!/ Existing match 5 +} + +loc_pickle_val = { + "Pickle Val Scraps 1": base_id + 1607, # ItemPickup56_2 Pickles_HouseDetails (X=60402.582 Y=25252.434 Z=11151.982) + "Pickle Val Scraps 2": base_id + 1608, # ItemPickup57_5 Pickles_HouseDetails (X=58717.516 Y=24457.180 Z=11343.938) + "Pickle Val Scraps 3": base_id + 1609, # ItemPickup311_14 Pickles_EnvironmentDetails (X=56455.688 Y=22324.875 Z=11655.192) + "Pickle Val Scraps 4": base_id + 1610, # ItemPickup310_11 Pickles_EnvironmentDetails (X=52888.387 Y=22541.955 Z=12428.012) + "Pickle Val Scraps 5": base_id + 1611, # ItemPickup58_2 Pickles_EnvironmentDetails (X=50374.863 Y=22073.027 Z=12591.468) + "Pickle Val Scraps 6": base_id + 1612, # ItemPickup309_8 Pickles_EnvironmentDetails (X=45985.988 Y=23063.826 Z=13043.497) + "Pickle Val Scraps 7": base_id + 1613, # ItemPickup316_27 Pickles_EnvironmentDetails (X=45533.469 Y=24876.168 Z=13015.539) + "Pickle Val Scraps 8": base_id + 1614, # ItemPickup317_30 Pickles_EnvironmentDetails (X=44928.848 Y=30913.396 Z=14273.230) + "Pickle Val Scraps 9": base_id + 1615, # ItemPickup321_42 Pickles_EnvironmentDetails (X=41572.684 Y=37403.539 Z=13527.379) + "Pickle Val Scraps 10": base_id + 1616, # ItemPickup61_11 Pickles_EnvironmentDetails (X=42266.566 Y=30556.238 Z=13584.196) + "Pickle Val Scraps 11": base_id + 1617, # ItemPickup314_21 Pickles_EnvironmentDetails (X=43356.219 Y=29465.746 Z=13449.486) + "Pickle Val Scraps 12": base_id + 1618, # ItemPickup323_48 Pickles_EnvironmentDetails (X=40893.461 Y=30669.398 Z=13465.039) + "Pickle Val Scraps 13": base_id + 1619, # ItemPickup318_33 Pickles_EnvironmentDetails (X=41276.863 Y=32313.068 Z=13480.846) + "Pickle Val Scraps 14": base_id + 1620, # ItemPickup319_36 Pickles_EnvironmentDetails (X=38630.031 Y=30471.996 Z=13571.207) + "Pickle Val Scraps 15": base_id + 1621, # ItemPickup320_39 Pickles_EnvironmentDetails (X=38596.938 Y=30050.293 Z=13559.574) + "Pickle Val Scraps 16": base_id + 1622, # ItemPickup60_8 Pickles_EnvironmentDetails (X=42042.520 Y=25136.820 Z=13077.339) + "Pickle Val Scraps 17": base_id + 1623, # ItemPickup308_5 Pickles_EnvironmentDetails (X=43770.914 Y=23307.234 Z=12374.002) + "Pickle Val Scraps 18": base_id + 1624, # ItemPickup59_5 Pickles_EnvironmentDetails (X=44672.641 Y=20936.520 Z=12198.017) + "Pickle Val Scraps 19": base_id + 1625, # ItemPickup307_2 Pickles_EnvironmentDetails (X=42844.730 Y=22869.387 Z=12832.900) + "Pickle Val Scraps 20": base_id + 1626, # ItemPickup315_24 Pickles_EnvironmentDetails (X=43397.758 Y=26367.248 Z=13005.097) + "Pickle Val Scraps 21": base_id + 1627, # ItemPickup322_45 Pickles_EnvironmentDetails (X=39352.430 Y=32668.316 Z=14494.778) + "Pickle Val Scraps 22": base_id + 1628, # ItemPickup313 Pickles_EnvironmentDetails (X=59688.781 Y=25266.756 Z=11425.324) + "Pickle Val Scraps 23": base_id + 1629, # ItemPickup312_17 Pickles_EnvironmentDetails (X=59197.871 Y=24760.773 Z=11425.324) + "Pickle Val Purple Paint Can": base_id + 1630, # PaintCan_7 Pickles_EnvironmentDetails (X=40394.855 Y=31546.465 Z=13472.573) + "Pickle Val Jar of Pickles": base_id + 1631, # Pickles_Pickup Pickles_Cave (X=38227.535 Y=30234.848 Z=13593.506) + "Pickle Val Pickle Lady Mission End": base_id + 1632 # (dialog 4) -> 30_scraps_reward +} + +loc_shrine_near_temple = { + "Shrine Near Temple Scraps 1": base_id + 1633, # ItemPickup3 Photorealistic_Island (X=-4675.183 Y=-21143.846 Z=11984.782) + "Shrine Near Temple Scraps 2": base_id + 1634, # ItemPickup_2 Photorealistic_Island (X=-4994.117 Y=-20496.621 Z=11874.112) + "Shrine Near Temple Scraps 3": base_id + 1635 # ItemPickup2 Photorealistic_Island (X=-4196.896 Y=-20477.025 Z=11882.833) +} + +loc_morse_bunker = { + "Morse Bunker Chest Scraps 1": base_id + 1636, # ItemPickup6512 Secret6_BunkerDetails (X=-47961.078 Y=-85433.031 Z=10615.777) + "Morse Bunker Chest Scraps 2": base_id + 1637, # ItemPickup9363 Secret6_BunkerDetails (X=-47958.617 Y=-85444.805 Z=10604.365) + "Morse Bunker Chest Scraps 3": base_id + 1638, # ItemPickup921436 Secret6_BunkerDetails (X=-47953.637 Y=-85426.172 Z=10592.347) + "Morse Bunker Chest Scraps 4": base_id + 1639, # ItemPickup0128704 Secret6_BunkerDetails (X=-47958.691 Y=-85444.805 Z=10587.060) + "Morse Bunker Chest Scraps 5": base_id + 1640, # ItemPickup64_8 Secret6_BunkerDetails (X=-47953.617 Y=-85426.172 Z=10574.149) + "Morse Bunker Scraps 1": base_id + 1641, # ItemPickup397_2 Secret6_BunkerDetails (X=-48336.863 Y=-85458.453 Z=10574.537) + "Morse Bunker Scraps 2": base_id + 1642, # ItemPickup62_2 Secret6_BunkerDetails (X=-48253.844 Y=-84944.609 Z=10573.793) + "Morse Bunker Scraps 3": base_id + 1643, # ItemPickup63_5 Secret6_BunkerDetails (X=-47272.422 Y=-84549.945 Z=10543.671) + "Morse Bunker Scraps 4": base_id + 1644, # ItemPickup398_5 Secret6_BunkerDetails (X=-47080.836 Y=-85268.281 Z=10564.355) + "Morse Bunker Scraps 5": base_id + 1645, # ItemPickup406_31 Secret6_BunkerDetails (X=-47913.855 Y=-85234.258 Z=10819.314) + "Morse Bunker Scraps 6": base_id + 1646, # ItemPickup405_28 Secret6_BunkerDetails (X=-46410.227 Y=-83293.742 Z=10361.746) + "Morse Bunker Scraps 7": base_id + 1647, # ItemPickup399_8 Secret6_BunkerDetails (X=-45204.199 Y=-84841.211 Z=10329.200) + "Morse Bunker Scraps 8": base_id + 1648, # ItemPickup401_14 Secret6_BunkerDetails (X=-43895.801 Y=-83794.750 Z=10265.661) + "Morse Bunker Scraps 9": base_id + 1649, # ItemPickup402_17 Secret6_BunkerDetails (X=-45163.078 Y=-80832.828 Z=10090.777) + "Morse Bunker Scraps 10": base_id + 1650, # ItemPickup403_20 Secret6_BunkerDetails (X=-46782.027 Y=-82284.805 Z=10289.180) + "Morse Bunker Scraps 11": base_id + 1651, # ItemPickup404_23 Secret6_BunkerDetails (X=-49240.047 Y=-83654.961 Z=10898.540) + "Morse Bunker Scraps 12": base_id + 1652, # ItemPickup407_34 Secret6_BunkerDetails (X=-46571.930 Y=-85962.773 Z=10697.339) + "Morse Bunker Scraps 13": base_id + 1653 # ItemPickup400_11 Secret6_BunkerDetails (X=-43472.793 Y=-85983.805 Z=10310.322) +} + +loc_prism_temple = { + "Prism Temple Chest Scraps 1": base_id + 1654, # ItemPickup16632 MainShrine_DetailsREPAIRED (X=12659.641 Y=-27827.016 Z=10930.621) + "Prism Temple Chest Scraps 2": base_id + 1655, # ItemPickup148864 MainShrine_DetailsREPAIRED (X=12648.021 Y=-27825.189 Z=10916.296) + "Prism Temple Chest Scraps 3": base_id + 1656, # ItemPickup13123 MainShrine_DetailsREPAIRED (X=12665.557 Y=-27836.633 Z=10905.999) + "Prism Temple Scraps 1": base_id + 1657, # ItemPickup225_77 MainShrine_ExteriorDetails (X=5281.087 Y=-16620.387 Z=10520.609) + "Prism Temple Scraps 2": base_id + 1658, # ItemPickup223_71 MainShrine_ExteriorDetails (X=15032.147 Y=-16788.352 Z=10992.200) + "Prism Temple Scraps 3": base_id + 1659, # ItemPickup222_68 MainShrine_ExteriorDetails (X=16591.920 Y=-18725.771 Z=11004.751) + "Prism Temple Scraps 4": base_id + 1660, # ItemPickup135123 MainShrine_DetailsREPAIRED (X=17940.854 Y=-20726.746 Z=10999.944) + "Prism Temple Scraps 5": base_id + 1661, # ItemPickup220_62 MainShrine_ExteriorDetails (X=18187.346 Y=-21390.066 Z=11025.650) + "Prism Temple Scraps 6": base_id + 1662, # ItemPickup218_56 MainShrine_ExteriorDetails (X=19218.670 Y=-24017.619 Z=10906.966) + "Prism Temple Scraps 7": base_id + 1663, # ItemPickup209_29 MainShrine_ExteriorDetails (X=7710.977 Y=-23469.254 Z=11012.888) + "Prism Temple Scraps 8": base_id + 1664, # ItemPickup138765 MainShrine_DetailsREPAIRED (X=8160.002 Y=-22335.266 Z=11016.638) + "Prism Temple Scraps 9": base_id + 1665, # ItemPickup210_32 MainShrine_ExteriorDetails (X=8637.903 Y=-24295.850 Z=10929.299) + "Prism Temple Scraps 10": base_id + 1666, # ItemPickup1112 MainShrine_DetailsREPAIRED (X=7923.367 Y=-25204.055 Z=10832.877) + "Prism Temple Scraps 11": base_id + 1667, # ItemPickup214_44 MainShrine_ExteriorDetails (X=10694.420 Y=-27246.365 Z=10569.074) + "Prism Temple Scraps 12": base_id + 1668, # ItemPickup215_47 MainShrine_ExteriorDetails (X=12892.631 Y=-26743.068 Z=10868.578) + "Prism Temple Scraps 13": base_id + 1669, # ItemPickup213_41 MainShrine_ExteriorDetails (X=12483.535 Y=-27253.867 Z=10876.461) + "Prism Temple Scraps 14": base_id + 1670, # ItemPickup212_38 MainShrine_ExteriorDetails (X=13259.813 Y=-27092.033 Z=10887.968) + "Prism Temple Scraps 15": base_id + 1671, # ItemPickup211_35 MainShrine_ExteriorDetails (X=9303.245 Y=-25057.908 Z=10943.273) + "Prism Temple Scraps 16": base_id + 1672, # ItemPickup201_2 MainShrine_ExteriorDetails (X=11750.875 Y=-22999.371 Z=12426.734) + "Prism Temple Scraps 17": base_id + 1673, # ItemPickup203_8 MainShrine_ExteriorDetails (X=12966.615 Y=-23568.324 Z=12519.387) + "Prism Temple Scraps 18": base_id + 1674, # ItemPickup204_11 MainShrine_ExteriorDetails (X=14093.343 Y=-22393.182 Z=12426.847) + "Prism Temple Scraps 19": base_id + 1675, # ItemPickup206_17 MainShrine_ExteriorDetails (X=13767.980 Y=-21269.568 Z=12425.791) + "Prism Temple Scraps 20": base_id + 1676, # ItemPickup207_23 MainShrine_ExteriorDetails (X=12882.754 Y=-20027.527 Z=12516.095) + "Prism Temple Scraps 21": base_id + 1677, # ItemPickup114535 MainShrine_DetailsREPAIRED (X=11883.399 Y=-20801.344 Z=12428.452) + "Prism Temple Scraps 22": base_id + 1678, # ItemPickup208_26 MainShrine_ExteriorDetails (X=13281.792 Y=-21302.344 Z=12902.728) + "Prism Temple Scraps 23": base_id + 1679, # ItemPickup205_14 MainShrine_ExteriorDetails (X=14190.678 Y=-23671.621 Z=11781.533) + "Prism Temple Scraps 24": base_id + 1680, # ItemPickup8903 MainShrine_DetailsREPAIRED (X=14311.736 Y=-22347.758 Z=11765.781) + "Prism Temple Scraps 25": base_id + 1681, # ItemPickup654 MainShrine_DetailsREPAIRED (X=13826.154 Y=-19923.131 Z=11755.189) + "Prism Temple Scraps 26": base_id + 1682, # ItemPickup224_74 MainShrine_ExteriorDetails (X=12443.228 Y=-18577.926 Z=11240.455) + "Prism Temple Scraps 27": base_id + 1683, # ItemPickup202_5 MainShrine_ExteriorDetails (X=10993.180 Y=-23783.047 Z=11754.121) + "Prism Temple Scraps 28": base_id + 1684, # ItemPickup13098 MainShrine_DetailsREPAIRED (X=16762.963 Y=-23634.342 Z=11031.588) + "Prism Temple Scraps 29": base_id + 1685, # ItemPickup221_65 MainShrine_ExteriorDetails (X=17804.979 Y=-23512.395 Z=11066.884) + "Prism Temple Scraps 30": base_id + 1686, # ItemPickup17123123565 MainShrine_DetailsREPAIRED (X=16998.229 Y=-23241.652 Z=11055.539) + "Prism Temple Scraps 31": base_id + 1687, # ItemPickup10812783 MainShrine_DetailsREPAIRED (X=17613.518 Y=-23799.813 Z=11057.277) + "Prism Temple Scraps 32": base_id + 1688, # ItemPickup216_50 MainShrine_ExteriorDetails (X=15342.375 Y=-24807.357 Z=11024.192) + "Prism Temple Scraps 33": base_id + 1689, # ItemPickup217_53 MainShrine_ExteriorDetails (X=15963.284 Y=-24834.156 Z=11021.444) + "Prism Temple Scraps 34": base_id + 1690 # ItemPickup219_59 MainShrine_ExteriorDetails (X=21563.559 Y=-23705.184 Z=10895.696) +} + + +# All locations +location_table: dict[str, int] = { + **loc_start_camp, + **loc_tony_tiddle_mission, + **loc_barn, + **loc_candice_mission, + **loc_tutorial_house, + **loc_swamp_edges, + **loc_swamp_mission, + **loc_junkyard_area, + **loc_south_house, + **loc_junkyard_shed, + **loc_military_base, + **loc_south_mine_outside, + **loc_south_mine_inside, + **loc_middle_station, + **loc_canyon, + **loc_watchtower, + **loc_boulder_field, + **loc_haunted_house, + **loc_santiago_house, + **loc_port, + **loc_trench_house, + **loc_doll_woods, + **loc_lost_stairs, + **loc_east_house, + **loc_rockets_testing_ground, + **loc_rockets_testing_bunker, + **loc_workshop, + **loc_east_tower, + **loc_lighthouse, + **loc_north_mine_outside, + **loc_north_mine_inside, + **loc_wood_bridge, + **loc_museum, + **loc_barbed_shelter, + **loc_west_beach, + **loc_church, + **loc_west_cottage, + **loc_caravan, + **loc_trailer_cabin, + **loc_towers, + **loc_north_beach, + **loc_mine_shaft, + **loc_mob_camp, + **loc_mob_camp_locked_room, + **loc_mine_elevator_exit, + **loc_mountain_ruin_outside, + **loc_mountain_ruin_inside, + **loc_prism_temple, + **loc_pickle_val, + **loc_shrine_near_temple, + **loc_morse_bunker +} diff --git a/worlds/cccharles/Options.py b/worlds/cccharles/Options.py new file mode 100644 index 000000000000..2ce1fc7afe03 --- /dev/null +++ b/worlds/cccharles/Options.py @@ -0,0 +1,7 @@ +from dataclasses import dataclass +from Options import PerGameCommonOptions, StartInventoryPool + + +@dataclass +class CCCharlesOptions(PerGameCommonOptions): + start_inventory_from_pool: StartInventoryPool diff --git a/worlds/cccharles/Regions.py b/worlds/cccharles/Regions.py new file mode 100644 index 000000000000..422301453c4e --- /dev/null +++ b/worlds/cccharles/Regions.py @@ -0,0 +1,290 @@ +from BaseClasses import MultiWorld, Region, ItemClassification +from .Items import CCCharlesItem +from .Options import CCCharlesOptions +from .Locations import ( + CCCharlesLocation, loc_start_camp, loc_tony_tiddle_mission, loc_barn, loc_candice_mission, \ + loc_tutorial_house, loc_swamp_edges, loc_swamp_mission, loc_junkyard_area, loc_south_house, \ + loc_junkyard_shed, loc_military_base, loc_south_mine_outside, loc_south_mine_inside, \ + loc_middle_station, loc_canyon, loc_watchtower, loc_boulder_field, loc_haunted_house, \ + loc_santiago_house, loc_port, loc_trench_house, loc_doll_woods, loc_lost_stairs, loc_east_house, \ + loc_rockets_testing_ground, loc_rockets_testing_bunker, loc_workshop, loc_east_tower, \ + loc_lighthouse, loc_north_mine_outside, loc_north_mine_inside, loc_wood_bridge, loc_museum, \ + loc_barbed_shelter, loc_west_beach, loc_church, loc_west_cottage, loc_caravan, loc_trailer_cabin, \ + loc_towers, loc_north_beach, loc_mine_shaft, loc_mob_camp, loc_mob_camp_locked_room, \ + loc_mine_elevator_exit, loc_mountain_ruin_outside, loc_mountain_ruin_inside, loc_prism_temple, \ + loc_pickle_val, loc_shrine_near_temple, loc_morse_bunker +) + + +def create_regions(world: MultiWorld, options: CCCharlesOptions, player: int) -> None: + menu_region = Region("Menu", player, world, "Aranearum") + world.regions.append(menu_region) + + start_camp_region = Region("Start Camp", player, world) + start_camp_region.add_locations(loc_start_camp, CCCharlesLocation) + world.regions.append(start_camp_region) + + tony_tiddle_mission_region = Region("Tony Tiddle Mission", player, world) + tony_tiddle_mission_region.add_locations(loc_tony_tiddle_mission, CCCharlesLocation) + world.regions.append(tony_tiddle_mission_region) + + barn_region = Region("Barn", player, world) + barn_region.add_locations(loc_barn, CCCharlesLocation) + world.regions.append(barn_region) + + candice_mission_region = Region("Candice Mission", player, world) + candice_mission_region.add_locations(loc_candice_mission, CCCharlesLocation) + world.regions.append(candice_mission_region) + + tutorial_house_region = Region("Tutorial House", player, world) + tutorial_house_region.add_locations(loc_tutorial_house, CCCharlesLocation) + world.regions.append(tutorial_house_region) + + swamp_edges_region = Region("Swamp Edges", player, world) + swamp_edges_region.add_locations(loc_swamp_edges, CCCharlesLocation) + world.regions.append(swamp_edges_region) + + swamp_mission_region = Region("Swamp Mission", player, world) + swamp_mission_region.add_locations(loc_swamp_mission, CCCharlesLocation) + world.regions.append(swamp_mission_region) + + junkyard_area_region = Region("Junkyard Area", player, world) + junkyard_area_region.add_locations(loc_junkyard_area, CCCharlesLocation) + world.regions.append(junkyard_area_region) + + south_house_region = Region("South House", player, world) + south_house_region.add_locations(loc_south_house, CCCharlesLocation) + world.regions.append(south_house_region) + + junkyard_shed_region = Region("Junkyard Shed", player, world) + junkyard_shed_region.add_locations(loc_junkyard_shed, CCCharlesLocation) + world.regions.append(junkyard_shed_region) + + military_base_region = Region("Military Base", player, world) + military_base_region.add_locations(loc_military_base, CCCharlesLocation) + world.regions.append(military_base_region) + + south_mine_outside_region = Region("South Mine Outside", player, world) + south_mine_outside_region.add_locations(loc_south_mine_outside, CCCharlesLocation) + world.regions.append(south_mine_outside_region) + + south_mine_inside_region = Region("South Mine Inside", player, world) + south_mine_inside_region.add_locations(loc_south_mine_inside, CCCharlesLocation) + world.regions.append(south_mine_inside_region) + + middle_station_region = Region("Middle Station", player, world) + middle_station_region.add_locations(loc_middle_station, CCCharlesLocation) + world.regions.append(middle_station_region) + + canyon_region = Region("Canyon", player, world) + canyon_region.add_locations(loc_canyon, CCCharlesLocation) + world.regions.append(canyon_region) + + watchtower_region = Region("Watchtower", player, world) + watchtower_region.add_locations(loc_watchtower, CCCharlesLocation) + world.regions.append(watchtower_region) + + boulder_field_region = Region("Boulder Field", player, world) + boulder_field_region.add_locations(loc_boulder_field, CCCharlesLocation) + world.regions.append(boulder_field_region) + + haunted_house_region = Region("Haunted House", player, world) + haunted_house_region.add_locations(loc_haunted_house, CCCharlesLocation) + world.regions.append(haunted_house_region) + + santiago_house_region = Region("Santiago House", player, world) + santiago_house_region.add_locations(loc_santiago_house, CCCharlesLocation) + world.regions.append(santiago_house_region) + + port_region = Region("Port", player, world) + port_region.add_locations(loc_port, CCCharlesLocation) + world.regions.append(port_region) + + trench_house_region = Region("Trench House", player, world) + trench_house_region.add_locations(loc_trench_house, CCCharlesLocation) + world.regions.append(trench_house_region) + + doll_woods_region = Region("Doll Woods", player, world) + doll_woods_region.add_locations(loc_doll_woods, CCCharlesLocation) + world.regions.append(doll_woods_region) + + lost_stairs_region = Region("Lost Stairs", player, world) + lost_stairs_region.add_locations(loc_lost_stairs, CCCharlesLocation) + world.regions.append(lost_stairs_region) + + east_house_region = Region("East House", player, world) + east_house_region.add_locations(loc_east_house, CCCharlesLocation) + world.regions.append(east_house_region) + + rockets_testing_ground_region = Region("Rockets Testing Ground", player, world) + rockets_testing_ground_region.add_locations(loc_rockets_testing_ground, CCCharlesLocation) + world.regions.append(rockets_testing_ground_region) + + rockets_testing_bunker_region = Region("Rockets Testing Bunker", player, world) + rockets_testing_bunker_region.add_locations(loc_rockets_testing_bunker, CCCharlesLocation) + world.regions.append(rockets_testing_bunker_region) + + workshop_region = Region("Workshop", player, world) + workshop_region.add_locations(loc_workshop, CCCharlesLocation) + world.regions.append(workshop_region) + + east_tower_region = Region("East Tower", player, world) + east_tower_region.add_locations(loc_east_tower, CCCharlesLocation) + world.regions.append(east_tower_region) + + lighthouse_region = Region("Lighthouse", player, world) + lighthouse_region.add_locations(loc_lighthouse, CCCharlesLocation) + world.regions.append(lighthouse_region) + + north_mine_outside_region = Region("North Mine Outside", player, world) + north_mine_outside_region.add_locations(loc_north_mine_outside, CCCharlesLocation) + world.regions.append(north_mine_outside_region) + + north_mine_inside_region = Region("North Mine Inside", player, world) + north_mine_inside_region.add_locations(loc_north_mine_inside, CCCharlesLocation) + world.regions.append(north_mine_inside_region) + + wood_bridge_region = Region("Wood Bridge", player, world) + wood_bridge_region.add_locations(loc_wood_bridge, CCCharlesLocation) + world.regions.append(wood_bridge_region) + + museum_region = Region("Museum", player, world) + museum_region.add_locations(loc_museum, CCCharlesLocation) + world.regions.append(museum_region) + + barbed_shelter_region = Region("Barbed Shelter", player, world) + barbed_shelter_region.add_locations(loc_barbed_shelter, CCCharlesLocation) + world.regions.append(barbed_shelter_region) + + west_beach_region = Region("West Beach", player, world) + west_beach_region.add_locations(loc_west_beach, CCCharlesLocation) + world.regions.append(west_beach_region) + + church_region = Region("Church", player, world) + church_region.add_locations(loc_church, CCCharlesLocation) + world.regions.append(church_region) + + west_cottage_region = Region("West Cottage", player, world) + west_cottage_region.add_locations(loc_west_cottage, CCCharlesLocation) + world.regions.append(west_cottage_region) + + caravan_region = Region("Caravan", player, world) + caravan_region.add_locations(loc_caravan, CCCharlesLocation) + world.regions.append(caravan_region) + + trailer_cabin_region = Region("Trailer Cabin", player, world) + trailer_cabin_region.add_locations(loc_trailer_cabin, CCCharlesLocation) + world.regions.append(trailer_cabin_region) + + towers_region = Region("Towers", player, world) + towers_region.add_locations(loc_towers, CCCharlesLocation) + world.regions.append(towers_region) + + north_beach_region = Region("North beach", player, world) + north_beach_region.add_locations(loc_north_beach, CCCharlesLocation) + world.regions.append(north_beach_region) + + mine_shaft_region = Region("Mine Shaft", player, world) + mine_shaft_region.add_locations(loc_mine_shaft, CCCharlesLocation) + world.regions.append(mine_shaft_region) + + mob_camp_region = Region("Mob Camp", player, world) + mob_camp_region.add_locations(loc_mob_camp, CCCharlesLocation) + world.regions.append(mob_camp_region) + + mob_camp_locked_room_region = Region("Mob Camp Locked Room", player, world) + mob_camp_locked_room_region.add_locations(loc_mob_camp_locked_room, CCCharlesLocation) + world.regions.append(mob_camp_locked_room_region) + + mine_elevator_exit_region = Region("Mine Elevator Exit", player, world) + mine_elevator_exit_region.add_locations(loc_mine_elevator_exit, CCCharlesLocation) + world.regions.append(mine_elevator_exit_region) + + mountain_ruin_outside_region = Region("Mountain Ruin Outside", player, world) + mountain_ruin_outside_region.add_locations(loc_mountain_ruin_outside, CCCharlesLocation) + world.regions.append(mountain_ruin_outside_region) + + mountain_ruin_inside_region = Region("Mountain Ruin Inside", player, world) + mountain_ruin_inside_region.add_locations(loc_mountain_ruin_inside, CCCharlesLocation) + world.regions.append(mountain_ruin_inside_region) + + prism_temple_region = Region("Prism Temple", player, world) + prism_temple_region.add_locations(loc_prism_temple, CCCharlesLocation) + world.regions.append(prism_temple_region) + + pickle_val_region = Region("Pickle Val", player, world) + pickle_val_region.add_locations(loc_pickle_val, CCCharlesLocation) + world.regions.append(pickle_val_region) + + shrine_near_temple_region = Region("Shrine Near Temple", player, world) + shrine_near_temple_region.add_locations(loc_shrine_near_temple, CCCharlesLocation) + world.regions.append(shrine_near_temple_region) + + morse_bunker_region = Region("Morse Bunker", player, world) + morse_bunker_region.add_locations(loc_morse_bunker, CCCharlesLocation) + world.regions.append(morse_bunker_region) + + # Place "Victory" event at "Final Boss" location + loc_final_boss = CCCharlesLocation(player, "Final Boss", None, prism_temple_region) + loc_final_boss.place_locked_item(CCCharlesItem("Victory", ItemClassification.progression, None, player)) + prism_temple_region.locations.append(loc_final_boss) + + # Connect the Regions by named Entrances that must have access Rules + menu_region.connect(start_camp_region) + menu_region.connect(tony_tiddle_mission_region) + menu_region.connect(barn_region) + tony_tiddle_mission_region.connect(barn_region, "Barn Door") + menu_region.connect(candice_mission_region) + menu_region.connect(tutorial_house_region) + candice_mission_region.connect(tutorial_house_region, "Tutorial House Door") + menu_region.connect(swamp_edges_region) + menu_region.connect(swamp_mission_region) + menu_region.connect(junkyard_area_region) + menu_region.connect(south_house_region) + menu_region.connect(junkyard_shed_region) + menu_region.connect(military_base_region) + menu_region.connect(south_mine_outside_region) + menu_region.connect(south_mine_inside_region) + south_mine_outside_region.connect(south_mine_inside_region, "South Mine Gate") + menu_region.connect(middle_station_region) + menu_region.connect(canyon_region) + menu_region.connect(watchtower_region) + menu_region.connect(boulder_field_region) + menu_region.connect(haunted_house_region) + menu_region.connect(santiago_house_region) + menu_region.connect(port_region) + menu_region.connect(trench_house_region) + menu_region.connect(doll_woods_region) + menu_region.connect(lost_stairs_region) + menu_region.connect(east_house_region) + menu_region.connect(rockets_testing_ground_region) + menu_region.connect(rockets_testing_bunker_region) + rockets_testing_ground_region.connect(rockets_testing_bunker_region, "Stuck Bunker Door") + menu_region.connect(workshop_region) + menu_region.connect(east_tower_region) + menu_region.connect(lighthouse_region) + menu_region.connect(north_mine_outside_region) + menu_region.connect(north_mine_inside_region) + north_mine_outside_region.connect(north_mine_inside_region, "North Mine Gate") + menu_region.connect(wood_bridge_region) + menu_region.connect(museum_region) + menu_region.connect(barbed_shelter_region) + menu_region.connect(west_beach_region) + menu_region.connect(church_region) + menu_region.connect(west_cottage_region) + menu_region.connect(caravan_region) + menu_region.connect(trailer_cabin_region) + menu_region.connect(towers_region) + menu_region.connect(north_beach_region) + menu_region.connect(mine_shaft_region) + menu_region.connect(mob_camp_region) + menu_region.connect(mob_camp_locked_room_region) + mob_camp_region.connect(mob_camp_locked_room_region, "Mob Camp Locked Door") + menu_region.connect(mine_elevator_exit_region) + menu_region.connect(mountain_ruin_outside_region) + menu_region.connect(mountain_ruin_inside_region) + mountain_ruin_outside_region.connect(mountain_ruin_inside_region, "Mountain Ruin Gate") + menu_region.connect(prism_temple_region) + menu_region.connect(pickle_val_region) + menu_region.connect(shrine_near_temple_region) + menu_region.connect(morse_bunker_region) diff --git a/worlds/cccharles/Rules.py b/worlds/cccharles/Rules.py new file mode 100644 index 000000000000..979aacd5294b --- /dev/null +++ b/worlds/cccharles/Rules.py @@ -0,0 +1,215 @@ +from BaseClasses import MultiWorld +from ..generic.Rules import set_rule +from .Options import CCCharlesOptions + +# Go mode: Green Egg + Blue Egg + Red Egg + Temple Key + Bug Spray (+ Remote Explosive x8 but the base game ignores it) + +def set_rules(world: MultiWorld, options: CCCharlesOptions, player: int) -> None: + # Tony Tiddle + set_rule(world.get_entrance("Barn Door", player), + lambda state: state.has("Barn Key", player)) + + # Candice + set_rule(world.get_entrance("Tutorial House Door", player), + lambda state: state.has("Candice's Key", player)) + + # Lizbeth Murkwater + set_rule(world.get_location("Swamp Lizbeth Murkwater Mission End", player), + lambda state: state.has("Dead Fish", player)) + + # Daryl + set_rule(world.get_location("Junkyard Area Chest Ancient Tablet", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Junkyard Area Daryl Mission End", player), + lambda state: state.has("Ancient Tablet", player)) + + # South House + set_rule(world.get_location("South House Chest Scraps 1", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("South House Chest Scraps 2", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("South House Chest Scraps 3", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("South House Chest Scraps 4", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("South House Chest Scraps 5", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("South House Chest Scraps 6", player), + lambda state: state.has("Lockpicks", player)) + + # South Mine + set_rule(world.get_entrance("South Mine Gate", player), + lambda state: state.has("South Mine Key", player)) + + set_rule(world.get_location("South Mine Inside Green Paint Can", player), + lambda state: state.has("Lockpicks", player)) + + # Theodore + set_rule(world.get_location("Middle Station Theodore Mission End", player), + lambda state: state.has("Blue Box", player)) + + # Watchtower + set_rule(world.get_location("Watchtower Pink Paint Can", player), + lambda state: state.has("Lockpicks", player)) + + # Sasha + set_rule(world.get_location("Haunted House Sasha Mission End", player), + lambda state: state.has("Page Drawing", player, 8)) + + # Santiago + set_rule(world.get_location("Port Santiago Mission End", player), + lambda state: state.has("Journal", player)) + + # Trench House + set_rule(world.get_location("Trench House Chest Scraps 1", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Trench House Chest Scraps 2", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Trench House Chest Scraps 3", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Trench House Chest Scraps 4", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Trench House Chest Scraps 5", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Trench House Chest Scraps 6", player), + lambda state: state.has("Lockpicks", player)) + + # East House + set_rule(world.get_location("East House Chest Scraps 1", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("East House Chest Scraps 2", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("East House Chest Scraps 3", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("East House Chest Scraps 4", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("East House Chest Scraps 5", player), + lambda state: state.has("Lockpicks", player)) + + # Rocket Testing Bunker + set_rule(world.get_entrance("Stuck Bunker Door", player), + lambda state: state.has("Timed Dynamite", player)) + + # John Smith + set_rule(world.get_location("Workshop John Smith Mission End", player), + lambda state: state.has("Box of Rockets", player)) + + # Claire + set_rule(world.get_location("Lighthouse Claire Mission End", player), + lambda state: state.has("Breaker", player, 4)) + + # North Mine + set_rule(world.get_entrance("North Mine Gate", player), + lambda state: state.has("North Mine Key", player)) + + set_rule(world.get_location("North Mine Inside Blue Paint Can", player), + lambda state: state.has("Lockpicks", player)) + + # Paul + set_rule(world.get_location("Museum Paul Mission End", player), + lambda state: state.has("Remote Explosive x8", player)) + # lambda state: state.has("Remote Explosive", player, 8)) # TODO: Add an option to split remote explosives + + # West Beach + set_rule(world.get_location("West Beach Chest Scraps 1", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("West Beach Chest Scraps 2", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("West Beach Chest Scraps 3", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("West Beach Chest Scraps 4", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("West Beach Chest Scraps 5", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("West Beach Chest Scraps 6", player), + lambda state: state.has("Lockpicks", player)) + + # Caravan + set_rule(world.get_location("Caravan Chest Scraps 1", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Caravan Chest Scraps 2", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Caravan Chest Scraps 3", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Caravan Chest Scraps 4", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Caravan Chest Scraps 5", player), + lambda state: state.has("Lockpicks", player)) + + # Ronny + set_rule(world.get_location("Towers Ronny Mission End", player), + lambda state: state.has("Employment Contracts", player)) + + # North Beach + set_rule(world.get_location("North Beach Chest Scraps 1", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("North Beach Chest Scraps 2", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("North Beach Chest Scraps 3", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("North Beach Chest Scraps 4", player), + lambda state: state.has("Lockpicks", player)) + + # Mine Shaft + set_rule(world.get_location("Mine Shaft Chest Scraps 1", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Mine Shaft Chest Scraps 2", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Mine Shaft Chest Scraps 3", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Mine Shaft Chest Scraps 4", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Mine Shaft Chest Scraps 5", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Mine Shaft Chest Scraps 6", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Mine Shaft Chest Scraps 7", player), + lambda state: state.has("Lockpicks", player)) + + # Mob Camp + set_rule(world.get_entrance("Mob Camp Locked Door", player), + lambda state: state.has("Mob Camp Key", player)) + + set_rule(world.get_location("Mob Camp Locked Room Stolen Bob", player), + lambda state: state.has("Broken Bob", player)) + + # Mountain Ruin + set_rule(world.get_entrance("Mountain Ruin Gate", player), + lambda state: state.has("Mountain Ruin Key", player)) + + set_rule(world.get_location("Mountain Ruin Inside Red Paint Can", player), + lambda state: state.has("Lockpicks", player)) + + # Prism Temple + set_rule(world.get_location("Prism Temple Chest Scraps 1", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Prism Temple Chest Scraps 2", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Prism Temple Chest Scraps 3", player), + lambda state: state.has("Lockpicks", player)) + + # Pickle Lady + set_rule(world.get_location("Pickle Val Jar of Pickles", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Pickle Val Pickle Lady Mission End", player), + lambda state: state.has("Jar of Pickles", player)) + + # Morse Bunker + set_rule(world.get_location("Morse Bunker Chest Scraps 1", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Morse Bunker Chest Scraps 2", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Morse Bunker Chest Scraps 3", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Morse Bunker Chest Scraps 4", player), + lambda state: state.has("Lockpicks", player)) + set_rule(world.get_location("Morse Bunker Chest Scraps 5", player), + lambda state: state.has("Lockpicks", player)) + + # Add rules to reach the "Go mode" + set_rule(world.get_location("Final Boss", player), + lambda state: state.has("Temple Key", player) + and state.has("Green Egg", player) + and state.has("Blue Egg", player) + and state.has("Red Egg", player)) + world.completion_condition[player] = lambda state: state.has("Victory", player) diff --git a/worlds/cccharles/__init__.py b/worlds/cccharles/__init__.py new file mode 100644 index 000000000000..6d40c0172d66 --- /dev/null +++ b/worlds/cccharles/__init__.py @@ -0,0 +1,171 @@ +from .Items import CCCharlesItem, unique_item_dict, full_item_list, item_groups +from .Locations import location_table +from .Options import CCCharlesOptions +from .Rules import set_rules +from .Regions import create_regions +from BaseClasses import Tutorial, ItemClassification +from worlds.AutoWorld import World, WebWorld + + +class CCCharlesWeb(WebWorld): + """ + Choo-Choo Charles is a horror game. + A devil spider train from hell called Charles chases any person it finds on an island. + The goal is to gather scraps to upgrade a train to fight Charles and travel by train to find 3 eggs + to lead Charles to a brutal death and save the island. + """ + + theme = "stone" + + setup_en = Tutorial( + "Multiworld Setup Guide", + "A guide to setup Choo-Choo Charles for the Archipelago MultiWorld Randomizer.", + "English", + "setup_en.md", + "setup/en", + ["Yaranorgoth"] + ) + + setup_fr = Tutorial( + "Guide d'Installation Multiworld", + "Un guide pour mettre en place Choo-Choo Charles pour le Randomiseur Multiworld Archipelago", + "Français", + "setup_fr.md", + "setup/fr", + ["Yaranorgoth"] + ) + + tutorials = [setup_en, setup_fr] + + game_info_languages = ["en", "fr"] + rich_text_options_doc = True + + +class CCCharlesWorld(World): + """ + An independent 3D horror game, taking place on an island. + The main gameplay consists of traveling and fighting a monster on board a train. + Upgrading the train requires leaving the train to gather resources with the threat of encountering the monster. + """ + + game = "Choo-Choo Charles" + + web = CCCharlesWeb() + + item_name_to_id = unique_item_dict + location_name_to_id = location_table + item_name_groups = item_groups + + # Options the player can set + options_dataclass = CCCharlesOptions + # Typing hints for all the options we defined + options: CCCharlesOptions + + topology_present = False # Hide path to required location checks in spoiler + + def create_regions(self) -> None: + create_regions(self.multiworld, self.options, self.player) + + def create_item(self, name: str) -> CCCharlesItem: + item_id = unique_item_dict[name] + + match name: + case "Scraps": + classification = ItemClassification.useful + case "30 Scraps Reward": + classification = ItemClassification.useful + case "25 Scraps Reward": + classification = ItemClassification.useful + case "35 Scraps Reward": + classification = ItemClassification.useful + case "40 Scraps Reward": + classification = ItemClassification.useful + case "South Mine Key": + classification = ItemClassification.progression + case "North Mine Key": + classification = ItemClassification.progression + case "Mountain Ruin Key": + classification = ItemClassification.progression + case "Barn Key": + classification = ItemClassification.progression + case "Candice's Key": + classification = ItemClassification.progression + case "Dead Fish": + classification = ItemClassification.progression + case "Lockpicks": + classification = ItemClassification.progression + case "Ancient Tablet": + classification = ItemClassification.progression + case "Blue Box": + classification = ItemClassification.progression + case "Page Drawing": + classification = ItemClassification.progression + case "Journal": + classification = ItemClassification.progression + case "Timed Dynamite": + classification = ItemClassification.progression + case "Box of Rockets": + classification = ItemClassification.progression + case "Breaker": + classification = ItemClassification.progression + case "Broken Bob": + classification = ItemClassification.progression + case "Employment Contracts": + classification = ItemClassification.progression + case "Mob Camp Key": + classification = ItemClassification.progression + case "Jar of Pickles": + classification = ItemClassification.progression + case "Orange Paint Can": + classification = ItemClassification.filler + case "Green Paint Can": + classification = ItemClassification.filler + case "White Paint Can": + classification = ItemClassification.filler + case "Pink Paint Can": + classification = ItemClassification.filler + case "Grey Paint Can": + classification = ItemClassification.filler + case "Blue Paint Can": + classification = ItemClassification.filler + case "Black Paint Can": + classification = ItemClassification.filler + case "Lime Paint Can": + classification = ItemClassification.filler + case "Teal Paint Can": + classification = ItemClassification.filler + case "Red Paint Can": + classification = ItemClassification.filler + case "Purple Paint Can": + classification = ItemClassification.filler + case "The Boomer": + classification = ItemClassification.filler + case "Bob": + classification = ItemClassification.filler + case "Green Egg": + classification = ItemClassification.progression + case "Blue Egg": + classification = ItemClassification.progression + case "Red Egg": + classification = ItemClassification.progression + case "Remote Explosive": + classification = ItemClassification.progression + case "Remote Explosive x8": + classification = ItemClassification.progression + case "Temple Key": + classification = ItemClassification.progression + case "Bug Spray": + classification = ItemClassification.progression + case _: # Should not occur + raise Exception("Unexpected case met: classification cannot be set for unknown item \"" + name + "\"") + + return CCCharlesItem(name, classification, item_id, self.player) + + def create_items(self) -> None: + self.multiworld.itempool += [self.create_item(item) for item in full_item_list] + + def set_rules(self) -> None: + set_rules(self.multiworld, self.options, self.player) + + def get_filler_item_name(self) -> str: + return "Scraps" diff --git a/worlds/cccharles/docs/en_Choo-Choo Charles.md b/worlds/cccharles/docs/en_Choo-Choo Charles.md new file mode 100644 index 000000000000..6d8ed39e03ea --- /dev/null +++ b/worlds/cccharles/docs/en_Choo-Choo Charles.md @@ -0,0 +1,39 @@ +# Choo-Choo Charles + +## Game page in other languages +* [Français](fr) + +## Where is the options page? +The [Player Options page](../player-options) contains all the options to configure and export a yaml config file. + +## What does randomization do to this game? +All scraps or any collectable item on the ground (except from Loot Crates) and items received from NPCs missions are considered as locations to check. + +## What is the goal of Choo-Choo Charles when randomized? +Beating the evil train from Hell named "Charles". + +## How is the game managed in Nightmare mode? +At death, the player has to restart a brand-new game, giving him the choice to stay under the Nightmare mode or continuing with the Normal mode if considered too hard. +In this case, all collected items will be redistributed in the inventory and the missions states will be kept. +The Deathlink is not implemented yet. When this option will be available, a choice will be provided to: +* Disable the Deathlink +* Enable the soft Deathlink with respawn at Player Train when a Deathlink event is received +* Enable the hard Deathlink with removal of the game save when a Deathlink event is received + +## What does another world's item look like in Choo-Choo Charles? +Items appearance are kept unchanged. +Any hint that cannot be normally represented in the game is replaced by the miniaturized "DeathDuck" Easter Egg that can be seen out from the physical wall limits of the original game. + +## How is the player informed by an item transmission and hints? +A message appears in game to inform what item is sent or received, including which world and what player the item comes from. +The same method is used for hints. + +## Is it possible to use hints in the game? +No, this is a work in progress. +The following options will be possible once the implementations are available: + +At any moment, the player can press one of the following keys to display a console in the game: +* "~" or "`" (qwerty) +* "²" (azerty) +* "F10" +Then, a hint can be revealed by typing "/hint [player] ". diff --git a/worlds/cccharles/docs/fr_Choo-Choo Charles.md b/worlds/cccharles/docs/fr_Choo-Choo Charles.md new file mode 100644 index 000000000000..42f0c48396c6 --- /dev/null +++ b/worlds/cccharles/docs/fr_Choo-Choo Charles.md @@ -0,0 +1,36 @@ +# Choo-Choo Charles + +## Où est la page d'options ? +La [page d'options du joueur pour ce jeu](../player-options) contient toutes les options pour configurer et exporter un fichier de configuration yaml. + +## Qu'est ce que la randomisation fait au jeu ? +Tous les débrits ou n'importe quel objet ramassable au sol (excepté les Caisses à Butin) et objets reçus par les missions de PNJs sont considérés comme emplacements à vérifier. + +## Quel est le but de Choo-Choo Charles lorsqu'il est randomisé ? +Vaincre le train démoniaque de l'Enfer nommé "Charles". + +## Comment le jeu est-il géré en mode Nightmare ? +À sa mort, le joueur doit relancer une toute nouvelle partie, lui donnant la possisilité de rester en mode Nightmare ou de poursuivre la partie en mode Normal s'il considère la partie trop difficile. +Dans ce cas, tous les objets collectés seront redistribués dans l'inventaire et les états des missions seront conservés. +Le Deathlink n'est pas implémenté pour l'instant. Lorsque cette option sera disponible, un choix sera fourni pour : +* Désactiver le Deathlink +* Activer le Deathlink modéré avec réapparition au Train du Joueur lorsqu'un évènement Deathlink est reçu +* Activer le Deathlink strict avec suppression de la sauvegarde lorsqu'un évènement Deathlink est reçu + +## À quoi ressemble un objet d'un autre monde dans Choo-Choo Charles ? +Les apparances des objets sont conservés. +Tout indice qui ne peut pas être représenté normalement dans le jeu est remplacé par l'Easter Egg "DeadDuck" miniaturisé qui peut être vu en dehors des limites murales physiques du jeu original. + +## Comment le joueur est-il informé par une transmission d'objet et des indices ? +Un message apparaît en jeu pour informer quel objet est envoyé ou reçu, incluant de quel monde et de quel joueur vient l'objet. +La même méthode est utilisée pour les indices. + +## Est-il possible d'utiliser les indices dans le jeu ? +Non, ceci est un travail en cours. +Les options suivantes seront possibles une fois les implémentations disponibles : + +À n'importe quel moment, le joueur peu appuyer sur l'une des touches suivantes pour afficher la console dans le jeu : +* "~" (qwerty) +* "²" (azerty) +* "F10" +Puis, un indice peut être révélé en tapant "/hint [player] " diff --git a/worlds/cccharles/docs/setup_en.md b/worlds/cccharles/docs/setup_en.md new file mode 100644 index 000000000000..8df0188c031b --- /dev/null +++ b/worlds/cccharles/docs/setup_en.md @@ -0,0 +1,52 @@ +# Choo-Choo Charles MultiWorld Setup Guide +This page is a simplified guide of the [Choo-Choo Charles Multiworld Randomizer Mod page](https://github.com/lgbarrere/CCCharles-Random?tab=readme-ov-file#cccharles-random). + +## Requirements and Required Softwares +* A computer running Windows (the Mod is not handled by Linux or Mac) +* [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) +* A legal copy of the Choo-Choo Charles original game (can be found on [Steam](https://store.steampowered.com/app/1766740/ChooChoo_Charles/)) + +## Mod Installation for playing +### Mod Download +All the required files of the Mod can be found in the [Releases](https://github.com/lgbarrere/CCCharles-Random/releases). +To use the Mod, download and unzip **CCCharles_Random.zip** somewhere safe, then follow the instructions in the next sections of this guide. This archive contains: +* The **Obscure/** folder loading the Mod itself, it runs the code handling all the randomized elements +* The **cccharles.apworld** file containing the randomization logic, used by the host to generate a random seed with the others games + +### Game Setup +The Mod can be installed and played by following these steps (see the [Mod Download](setup_en#mod-download) section to get **CCCharles_Random.zip**): +1. Copy the **Obscure/** folder from **CCCharles_Random.zip** to **\** (where the **Obscure/** folder and **Obscure.exe** are placed) +2. Launch the game, if "OFFLINE" is visible in the upper-right corner of the screen, the Mod is working + +### Create a Config (.yaml) File +The purpose of a YAML file is described in the [Basic Multiworld Setup Guide](https://archipelago.gg/tutorial/Archipelago/setup/en#generating-a-game). + +The [Player Options page](/games/Choo-Choo%20Charles/player-options) allows to configure personal options and export a config YAML file. + +## Joining a MultiWorld Game +Before playing, it is highly recommended to check out the **[Known Issues](setup_en#known-issues)** section +* The game console must be opened to type Archipelago commands, press "F10" key or "`" (or "~") key in querty ("²" key in azerty) +* Type ``/connect `` with \ and \ found on the hosting Archipelago web page in the form ``archipelago.gg:XXXXX`` and ``CCCharles`` +* Disconnection is automatic at game closure but can be manually done with ``/disconnect`` + +## Hosting a MultiWorld or Single-Player Game +See the [Mod Download](setup_en#mod-download) section to get the **cccharles.apworld** file. + +In this section, **Archipelago/** refers to the path where [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) is installed locally. + +Follow these steps to host a remote multiplayer or a local single-player session: +1. Double-click the **cccharles.apworld** to automatically install the world randomization logic +2. Put the **CCCharles.yaml** to **Archipelago/Players/** with the YAML of each player to host +3. Launch the Archipelago launcher and click "Generate" to configure a game with the YAMLs in **Archipelago/output/** +4. For a multiplayer session, go to the [Archipelago HOST GAME page](https://archipelago.gg/uploads) +5. Click "Upload File" and select the generated **AP_\.zip** in **Archipelago/output/** +6. Send the generated room page to each player + +For a local single-player session, click "Host" in the Archipelago launcher by using the generated **AP_\.zip** in **Archipelago/output/** + +## Known Issues +### Major issues +No major issue found. + +### Minor issues +* The current version of the command parser does not accept console commands with a player names containing whitespaces. It is recommended to use underscores "_" instead, for instance: CCCharles_Player_1. diff --git a/worlds/cccharles/docs/setup_fr.md b/worlds/cccharles/docs/setup_fr.md new file mode 100644 index 000000000000..386ec02587c6 --- /dev/null +++ b/worlds/cccharles/docs/setup_fr.md @@ -0,0 +1,52 @@ +# Guide d'Installation du MultiWorld Choo-Choo Charles +Cette page est un guide simplifié de la [page du Mod Randomiseur Multiworld de Choo-Choo Charles](https://github.com/lgbarrere/CCCharles-Random?tab=readme-ov-file#cccharles-random). + +## Exigences et Logiciels Nécessaires +* Un ordinateur utilisant Windows (le Mod n'est pas utilisable sous Linux ou Mac) +* [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) +* Une copie légale du jeu original Choo-Choo Charles (peut être trouvé sur [Steam](https://store.steampowered.com/app/1766740/ChooChoo_Charles/) + +## Installation du Mod pour jouer +### Téléchargement du Mod +Tous les fichiers nécessaires du Mod se trouvent dans les [Releases](https://github.com/lgbarrere/CCCharles-Random/releases). +Pour utiliser le Mod, télécharger et désarchiver **CCCharles_Random.zip** à un endroit sûr, puis suivre les instructions dans les sections suivantes de ce guide. Cette archive contient : +* Le dossier **Obscure/** qui charge le Mod lui-même, il lance le code qui gère tous les éléments randomisés +* Le fichier **cccharles.apworld** qui contient la logique de randomisation, utilisé par l'hôte pour générer une graine aléatoire avec les autres jeux + +### Préparation du Jeu +Le Mod peut être installé et joué en suivant les étapes suivantes (voir la section [Téléchargement du Mod](setup_fr#téléchargement-du-mod) pour récupérer **CCCharles_Random.zip**) : +1. Copier le dossier **Obscure/** de **CCCharles_Random.zip** vers **\** (où se situent le dossier **Obscure/** et **Obscure.exe**) +2. Lancer le jeu, si "OFFLINE" est visible dans le coin en haut à droite de l'écran, le Mod est actif + +### Créer un Fichier de Configuration (.yaml) +L'objectif d'un fichier YAML est décrit dans le [Guide d'Installation Basique du Multiworld](https://archipelago.gg/tutorial/Archipelago/setup/en#generating-a-game) (en anglais). + +La [page d'Options Joueur](/games/Choo-Choo%20Charles/player-options) permet de configurer des options personnelles et exporter un fichier de configuration YAML. + +## Rejoindre une Partie MultiWorld +Avant de jouer, il est fortement recommandé de consulter la section **[Problèmes Connus](setup_fr#probl%C3%A8mes-connus)**. +* La console du jeu doit être ouverte pour taper des commandes Archipelago, appuyer sur la touche "F10" ou "`" (ou "~") en querty (touche "²" en azerty) +* Taper ``/connect `` avec \ et \ trouvés sur la page web d'hébergement Archipelago sous la forme ``archipelago.gg:XXXXX`` et ``CCCharles`` +* La déconnexion est automatique à la fermeture du jeu mais peut être faite manuellement avec ``/disconnect`` + +## Héberger une partie MultiWorld ou un Seul Joueur +Voir la section [Téléchargement du Mod](setup_fr#téléchargement-du-mod) pour récupérer le fichier **cccharles.apworld**. + +Dans cette section, **Archipelago/** fait référence au chemin d'accès où [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) est installé localement. + +Suivre ces étapes pour héberger une session multijoueur à distance ou locale pour un seul joueur : +1. Double-cliquer sur **cccharles.apworld** pour installer automatiquement la logique de randomisation du monde +2. Placer le **CCCharles.yaml** dans **Archipelago/Players/** avec le YAML de chaque joueur à héberger +3. Exécuter le lanceur Archipelago et cliquer sur "Generate" pour configurer une partie avec les YAML dans **Archipelago/output/** +4. Pour une session multijoueur, aller à la [page Archipelago HOST GAME](https://archipelago.gg/uploads) +5. Cliquer sur "Upload File" et selectionner le **AP_\.zip** généré dans **Archipelago/output/** +6. Envoyer la page de la partie générée à chaque joueur + +Pour une session locale à un seul joueur, cliquer sur "Host" dans le lanceur Archipelago en utilisant **AP_\.zip** généré dans **Archipelago/output/** + +## Problèmes Connus +### Problèmes majeurs +Aucun problème majeur trouvé. + +### Problèmes mineurs +* La version actuelle de l'analyseur de commandes n'accepte pas des commandes de la console dont le nom du joueur contient des espaces. Il est recommandé d'utiliser des soulignés "_" à la place, par exemple : CCCharles_Player_1. diff --git a/worlds/cccharles/test/TestAccess.py b/worlds/cccharles/test/TestAccess.py new file mode 100644 index 000000000000..d088457c7a60 --- /dev/null +++ b/worlds/cccharles/test/TestAccess.py @@ -0,0 +1,27 @@ +from BaseClasses import CollectionState +from .bases import CCCharlesTestBase + + +class TestAccess(CCCharlesTestBase): + def test_claire_breakers(self) -> None: + """Test locations that require 4 Breakers""" + lighthouse_claire_mission_end = self.world.get_location("Lighthouse Claire Mission End") + + state = CollectionState(self.multiworld) + self.collect_all_but("Breaker") + + breakers_in_pool = self.get_items_by_name("Breaker") + self.assertGreaterEqual(len(breakers_in_pool), 4) # Check at least 4 Breakers are in the item pool + + for breaker in breakers_in_pool[:3]: + state.collect(breaker) # Collect 3 Breakers into state + self.assertFalse( + lighthouse_claire_mission_end.can_reach(state), + "Lighthouse Claire Mission End should not be reachable with only three Breakers" + ) + + state.collect(breakers_in_pool[3]) # Collect 4th breaker into state + self.assertTrue( + lighthouse_claire_mission_end.can_reach(state), + "Lighthouse Claire Mission End should have been reachable with four Breakers" + ) diff --git a/worlds/cccharles/test/__init__.py b/worlds/cccharles/test/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/worlds/cccharles/test/bases.py b/worlds/cccharles/test/bases.py new file mode 100644 index 000000000000..4c08d163ec60 --- /dev/null +++ b/worlds/cccharles/test/bases.py @@ -0,0 +1,5 @@ +from test.bases import WorldTestBase + + +class CCCharlesTestBase(WorldTestBase): + game = "Choo-Choo Charles" From 63f35128298e57245ccee053f6ac5c2f14b59293 Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 8 Sep 2025 04:11:46 -0500 Subject: [PATCH 0715/1218] Core: adds a custom KeyError for invalid item names (#4223) * adds a custom KeyError for raising on world.create_item() if the passed in name is invalid * Update __init__.py --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/AutoWorld.py | 4 ++++ worlds/generic/__init__.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 9233f3d21755..676171b7ff16 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -22,6 +22,10 @@ perf_logger = logging.getLogger("performance") +class InvalidItemError(KeyError): + pass + + class AutoWorldRegister(type): world_types: Dict[str, Type[World]] = {} __file__: str diff --git a/worlds/generic/__init__.py b/worlds/generic/__init__.py index 29f808b20272..fa53f31f7c1b 100644 --- a/worlds/generic/__init__.py +++ b/worlds/generic/__init__.py @@ -3,7 +3,7 @@ from BaseClasses import Item, Tutorial, ItemClassification -from ..AutoWorld import World, WebWorld +from ..AutoWorld import InvalidItemError, World, WebWorld from NetUtils import SlotType @@ -47,7 +47,7 @@ def generate_early(self): def create_item(self, name: str) -> Item: if name == "Nothing": return Item(name, ItemClassification.filler, -1, self.player) - raise KeyError(name) + raise InvalidItemError(name) class PlandoItem(NamedTuple): From 17dad8313e1e3c085fc08b9a1760ee3fb89f0d5c Mon Sep 17 00:00:00 2001 From: qwint Date: Mon, 8 Sep 2025 14:36:26 -0500 Subject: [PATCH 0716/1218] Test: Remove most dependencies on lttp (#5338) * removes the last dependencies on lttp in tests * removing test.bases.TestBase from docs as well * rename bases * move imports to bases --- docs/tests.md | 11 +- test/bases.py | 93 +------------- worlds/alttp/test/__init__.py | 22 ---- worlds/alttp/test/bases.py | 113 ++++++++++++++++++ worlds/alttp/test/dungeons/TestDungeon.py | 2 +- worlds/alttp/test/inverted/TestInverted.py | 17 ++- .../test/inverted/TestInvertedBombRules.py | 2 +- .../TestInvertedMinor.py | 19 ++- .../test/inverted_owg/TestInvertedOWG.py | 19 ++- worlds/alttp/test/items/TestDifficulty.py | 4 +- worlds/alttp/test/minor_glitches/TestMinor.py | 13 +- worlds/alttp/test/owg/TestVanillaOWG.py | 13 +- worlds/alttp/test/shops/TestSram.py | 4 +- worlds/alttp/test/vanilla/TestVanilla.py | 14 +-- worlds/pokemon_emerald/test/test_warps.py | 4 +- 15 files changed, 172 insertions(+), 178 deletions(-) create mode 100644 worlds/alttp/test/bases.py diff --git a/docs/tests.md b/docs/tests.md index 78cedbc514d5..0740072d7e83 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -82,10 +82,10 @@ overridden. For more information on what methods are available to your class, ch #### Alternatives to WorldTestBase -Unit tests can also be created using [TestBase](/test/bases.py#L16) or -[unittest.TestCase](https://docs.python.org/3/library/unittest.html#unittest.TestCase) depending on your use case. These -may be useful for generating a multiworld under very specific constraints without using the generic world setup, or for -testing portions of your code that can be tested without relying on a multiworld to be created first. +Unit tests can also be created using +[unittest.TestCase](https://docs.python.org/3/library/unittest.html#unittest.TestCase) directly. These may be useful +for generating a multiworld under very specific constraints without using the generic world setup, or for testing +portions of your code that can be tested without relying on a multiworld to be created first. #### Parametrization @@ -102,8 +102,7 @@ for multiple inputs) the base test. Some important things to consider when attem * Classes inheriting from `WorldTestBase`, including those created by the helpers in `test.param`, will run all base tests by default, make sure the produced tests actually do what you aim for and do not waste a lot of - extra CPU time. Consider using `TestBase` or `unittest.TestCase` directly - or setting `WorldTestBase.run_default_tests` to False. + extra CPU time. Consider using `unittest.TestCase` directly or setting `WorldTestBase.run_default_tests` to False. #### Performance Considerations diff --git a/test/bases.py b/test/bases.py index c9610c862da7..dd93ca6452dd 100644 --- a/test/bases.py +++ b/test/bases.py @@ -9,98 +9,7 @@ from worlds import AutoWorld from worlds.AutoWorld import World, call_all -from BaseClasses import Location, MultiWorld, CollectionState, ItemClassification, Item -from worlds.alttp.Items import item_factory - - -class TestBase(unittest.TestCase): - multiworld: MultiWorld - _state_cache = {} - - def get_state(self, items): - if (self.multiworld, tuple(items)) in self._state_cache: - return self._state_cache[self.multiworld, tuple(items)] - state = CollectionState(self.multiworld) - for item in items: - item.classification = ItemClassification.progression - state.collect(item, prevent_sweep=True) - state.sweep_for_advancements() - state.update_reachable_regions(1) - self._state_cache[self.multiworld, tuple(items)] = state - return state - - def get_path(self, state, region): - def flist_to_iter(node): - while node: - value, node = node - yield value - - from itertools import zip_longest - reversed_path_as_flist = state.path.get(region, (region, None)) - string_path_flat = reversed(list(map(str, flist_to_iter(reversed_path_as_flist)))) - # Now we combine the flat string list into (region, exit) pairs - pathsiter = iter(string_path_flat) - pathpairs = zip_longest(pathsiter, pathsiter) - return list(pathpairs) - - def run_location_tests(self, access_pool): - for i, (location, access, *item_pool) in enumerate(access_pool): - items = item_pool[0] - all_except = item_pool[1] if len(item_pool) > 1 else None - state = self._get_items(item_pool, all_except) - path = self.get_path(state, self.multiworld.get_location(location, 1).parent_region) - with self.subTest(msg="Reach Location", location=location, access=access, items=items, - all_except=all_except, path=path, entry=i): - - self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), access, - f"failed {self.multiworld.get_location(location, 1)} with: {item_pool}") - - # check for partial solution - if not all_except and access: # we are not supposed to be able to reach location with partial inventory - for missing_item in item_pool[0]: - with self.subTest(msg="Location reachable without required item", location=location, - items=item_pool[0], missing_item=missing_item, entry=i): - state = self._get_items_partial(item_pool, missing_item) - - self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), False, - f"failed {self.multiworld.get_location(location, 1)}: succeeded with " - f"{missing_item} removed from: {item_pool}") - - def run_entrance_tests(self, access_pool): - for i, (entrance, access, *item_pool) in enumerate(access_pool): - items = item_pool[0] - all_except = item_pool[1] if len(item_pool) > 1 else None - state = self._get_items(item_pool, all_except) - path = self.get_path(state, self.multiworld.get_entrance(entrance, 1).parent_region) - with self.subTest(msg="Reach Entrance", entrance=entrance, access=access, items=items, - all_except=all_except, path=path, entry=i): - - self.assertEqual(self.multiworld.get_entrance(entrance, 1).can_reach(state), access) - - # check for partial solution - if not all_except and access: # we are not supposed to be able to reach location with partial inventory - for missing_item in item_pool[0]: - with self.subTest(msg="Entrance reachable without required item", entrance=entrance, - items=item_pool[0], missing_item=missing_item, entry=i): - state = self._get_items_partial(item_pool, missing_item) - self.assertEqual(self.multiworld.get_entrance(entrance, 1).can_reach(state), False, - f"failed {self.multiworld.get_entrance(entrance, 1)} with: {item_pool}") - - def _get_items(self, item_pool, all_except): - if all_except and len(all_except) > 0: - items = self.multiworld.itempool[:] - items = [item for item in items if - item.name not in all_except and not ("Bottle" in item.name and "AnyBottle" in all_except)] - items.extend(item_factory(item_pool[0], self.multiworld.worlds[1])) - else: - items = item_factory(item_pool[0], self.multiworld.worlds[1]) - return self.get_state(items) - - def _get_items_partial(self, item_pool, missing_item): - new_items = item_pool[0].copy() - new_items.remove(missing_item) - items = item_factory(new_items, self.multiworld.worlds[1]) - return self.get_state(items) +from BaseClasses import Location, MultiWorld, CollectionState, Item class WorldTestBase(unittest.TestCase): diff --git a/worlds/alttp/test/__init__.py b/worlds/alttp/test/__init__.py index 031d508604d4..e69de29bb2d1 100644 --- a/worlds/alttp/test/__init__.py +++ b/worlds/alttp/test/__init__.py @@ -1,22 +0,0 @@ -import unittest -from argparse import Namespace - -from BaseClasses import MultiWorld, CollectionState -from worlds import AutoWorldRegister - - -class LTTPTestBase(unittest.TestCase): - def world_setup(self): - from worlds.alttp.Options import Medallion - self.multiworld = MultiWorld(1) - self.multiworld.game[1] = "A Link to the Past" - self.multiworld.set_seed(None) - args = Namespace() - for name, option in AutoWorldRegister.world_types["A Link to the Past"].options_dataclass.type_hints.items(): - setattr(args, name, {1: option.from_any(getattr(option, "default"))}) - self.multiworld.set_options(args) - self.multiworld.state = CollectionState(self.multiworld) - self.world = self.multiworld.worlds[1] - # by default medallion access is randomized, for unittests we set it to vanilla - self.world.options.misery_mire_medallion.value = Medallion.option_ether - self.world.options.turtle_rock_medallion.value = Medallion.option_quake diff --git a/worlds/alttp/test/bases.py b/worlds/alttp/test/bases.py new file mode 100644 index 000000000000..c3b4f47a69bf --- /dev/null +++ b/worlds/alttp/test/bases.py @@ -0,0 +1,113 @@ +import unittest +from argparse import Namespace + +from BaseClasses import MultiWorld, CollectionState, ItemClassification +from worlds import AutoWorldRegister +from ..Items import item_factory + + +class TestBase(unittest.TestCase): + multiworld: MultiWorld + _state_cache = {} + + def get_state(self, items): + if (self.multiworld, tuple(items)) in self._state_cache: + return self._state_cache[self.multiworld, tuple(items)] + state = CollectionState(self.multiworld) + for item in items: + item.classification = ItemClassification.progression + state.collect(item, prevent_sweep=True) + state.sweep_for_advancements() + state.update_reachable_regions(1) + self._state_cache[self.multiworld, tuple(items)] = state + return state + + def get_path(self, state, region): + def flist_to_iter(node): + while node: + value, node = node + yield value + + from itertools import zip_longest + reversed_path_as_flist = state.path.get(region, (region, None)) + string_path_flat = reversed(list(map(str, flist_to_iter(reversed_path_as_flist)))) + # Now we combine the flat string list into (region, exit) pairs + pathsiter = iter(string_path_flat) + pathpairs = zip_longest(pathsiter, pathsiter) + return list(pathpairs) + + def run_location_tests(self, access_pool): + for i, (location, access, *item_pool) in enumerate(access_pool): + items = item_pool[0] + all_except = item_pool[1] if len(item_pool) > 1 else None + state = self._get_items(item_pool, all_except) + path = self.get_path(state, self.multiworld.get_location(location, 1).parent_region) + with self.subTest(msg="Reach Location", location=location, access=access, items=items, + all_except=all_except, path=path, entry=i): + + self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), access, + f"failed {self.multiworld.get_location(location, 1)} with: {item_pool}") + + # check for partial solution + if not all_except and access: # we are not supposed to be able to reach location with partial inventory + for missing_item in item_pool[0]: + with self.subTest(msg="Location reachable without required item", location=location, + items=item_pool[0], missing_item=missing_item, entry=i): + state = self._get_items_partial(item_pool, missing_item) + + self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), False, + f"failed {self.multiworld.get_location(location, 1)}: succeeded with " + f"{missing_item} removed from: {item_pool}") + + def run_entrance_tests(self, access_pool): + for i, (entrance, access, *item_pool) in enumerate(access_pool): + items = item_pool[0] + all_except = item_pool[1] if len(item_pool) > 1 else None + state = self._get_items(item_pool, all_except) + path = self.get_path(state, self.multiworld.get_entrance(entrance, 1).parent_region) + with self.subTest(msg="Reach Entrance", entrance=entrance, access=access, items=items, + all_except=all_except, path=path, entry=i): + + self.assertEqual(self.multiworld.get_entrance(entrance, 1).can_reach(state), access) + + # check for partial solution + if not all_except and access: # we are not supposed to be able to reach location with partial inventory + for missing_item in item_pool[0]: + with self.subTest(msg="Entrance reachable without required item", entrance=entrance, + items=item_pool[0], missing_item=missing_item, entry=i): + state = self._get_items_partial(item_pool, missing_item) + self.assertEqual(self.multiworld.get_entrance(entrance, 1).can_reach(state), False, + f"failed {self.multiworld.get_entrance(entrance, 1)} with: {item_pool}") + + def _get_items(self, item_pool, all_except): + if all_except and len(all_except) > 0: + items = self.multiworld.itempool[:] + items = [item for item in items if + item.name not in all_except and not ("Bottle" in item.name and "AnyBottle" in all_except)] + items.extend(item_factory(item_pool[0], self.multiworld.worlds[1])) + else: + items = item_factory(item_pool[0], self.multiworld.worlds[1]) + return self.get_state(items) + + def _get_items_partial(self, item_pool, missing_item): + new_items = item_pool[0].copy() + new_items.remove(missing_item) + items = item_factory(new_items, self.multiworld.worlds[1]) + return self.get_state(items) + + +class LTTPTestBase(unittest.TestCase): + def world_setup(self): + from worlds.alttp.Options import Medallion + self.multiworld = MultiWorld(1) + self.multiworld.game[1] = "A Link to the Past" + self.multiworld.set_seed(None) + args = Namespace() + for name, option in AutoWorldRegister.world_types["A Link to the Past"].options_dataclass.type_hints.items(): + setattr(args, name, {1: option.from_any(getattr(option, "default"))}) + self.multiworld.set_options(args) + self.multiworld.state = CollectionState(self.multiworld) + self.world = self.multiworld.worlds[1] + # by default medallion access is randomized, for unittests we set it to vanilla + self.world.options.misery_mire_medallion.value = Medallion.option_ether + self.world.options.turtle_rock_medallion.value = Medallion.option_quake diff --git a/worlds/alttp/test/dungeons/TestDungeon.py b/worlds/alttp/test/dungeons/TestDungeon.py index c06955a12269..dd622c4f7fb8 100644 --- a/worlds/alttp/test/dungeons/TestDungeon.py +++ b/worlds/alttp/test/dungeons/TestDungeon.py @@ -5,7 +5,7 @@ from worlds.alttp.Items import item_factory from worlds.alttp.Regions import create_regions from worlds.alttp.Shops import create_shops -from worlds.alttp.test import LTTPTestBase +from worlds.alttp.test.bases import LTTPTestBase class TestDungeon(LTTPTestBase): diff --git a/worlds/alttp/test/inverted/TestInverted.py b/worlds/alttp/test/inverted/TestInverted.py index 3c86b6ba0a78..8dc02de730fd 100644 --- a/worlds/alttp/test/inverted/TestInverted.py +++ b/worlds/alttp/test/inverted/TestInverted.py @@ -1,13 +1,12 @@ -from worlds.alttp.Dungeons import get_dungeon_item_pool -from worlds.alttp.EntranceShuffle import link_inverted_entrances -from worlds.alttp.InvertedRegions import create_inverted_regions -from worlds.alttp.ItemPool import difficulties -from worlds.alttp.Items import item_factory -from worlds.alttp.Regions import mark_light_world_regions -from worlds.alttp.Shops import create_shops -from test.bases import TestBase +from ...Dungeons import get_dungeon_item_pool +from ...EntranceShuffle import link_inverted_entrances +from ...InvertedRegions import create_inverted_regions +from ...ItemPool import difficulties +from ...Items import item_factory +from ...Regions import mark_light_world_regions +from ...Shops import create_shops -from worlds.alttp.test import LTTPTestBase +from ..bases import LTTPTestBase, TestBase class TestInverted(TestBase, LTTPTestBase): diff --git a/worlds/alttp/test/inverted/TestInvertedBombRules.py b/worlds/alttp/test/inverted/TestInvertedBombRules.py index ab73d91108a1..5ad5270957cd 100644 --- a/worlds/alttp/test/inverted/TestInvertedBombRules.py +++ b/worlds/alttp/test/inverted/TestInvertedBombRules.py @@ -4,7 +4,7 @@ from worlds.alttp.InvertedRegions import create_inverted_regions from worlds.alttp.ItemPool import difficulties from worlds.alttp.Rules import set_inverted_big_bomb_rules -from worlds.alttp.test import LTTPTestBase +from worlds.alttp.test.bases import LTTPTestBase class TestInvertedBombRules(LTTPTestBase): diff --git a/worlds/alttp/test/inverted_minor_glitches/TestInvertedMinor.py b/worlds/alttp/test/inverted_minor_glitches/TestInvertedMinor.py index 972b617a29c6..958cd3e7288d 100644 --- a/worlds/alttp/test/inverted_minor_glitches/TestInvertedMinor.py +++ b/worlds/alttp/test/inverted_minor_glitches/TestInvertedMinor.py @@ -1,14 +1,13 @@ -from worlds.alttp.Dungeons import get_dungeon_item_pool -from worlds.alttp.EntranceShuffle import link_inverted_entrances -from worlds.alttp.InvertedRegions import create_inverted_regions -from worlds.alttp.ItemPool import difficulties -from worlds.alttp.Items import item_factory -from worlds.alttp.Options import GlitchesRequired -from worlds.alttp.Regions import mark_light_world_regions -from worlds.alttp.Shops import create_shops -from test.bases import TestBase +from ...Dungeons import get_dungeon_item_pool +from ...EntranceShuffle import link_inverted_entrances +from ...InvertedRegions import create_inverted_regions +from ...ItemPool import difficulties +from ...Items import item_factory +from ...Options import GlitchesRequired +from ...Regions import mark_light_world_regions +from ...Shops import create_shops -from worlds.alttp.test import LTTPTestBase +from ..bases import LTTPTestBase, TestBase class TestInvertedMinor(TestBase, LTTPTestBase): diff --git a/worlds/alttp/test/inverted_owg/TestInvertedOWG.py b/worlds/alttp/test/inverted_owg/TestInvertedOWG.py index 4be51f629809..8a6b570d7177 100644 --- a/worlds/alttp/test/inverted_owg/TestInvertedOWG.py +++ b/worlds/alttp/test/inverted_owg/TestInvertedOWG.py @@ -1,14 +1,13 @@ -from worlds.alttp.Dungeons import get_dungeon_item_pool -from worlds.alttp.EntranceShuffle import link_inverted_entrances -from worlds.alttp.InvertedRegions import create_inverted_regions -from worlds.alttp.ItemPool import difficulties -from worlds.alttp.Items import item_factory -from worlds.alttp.Options import GlitchesRequired -from worlds.alttp.Regions import mark_light_world_regions -from worlds.alttp.Shops import create_shops -from test.bases import TestBase +from ...Dungeons import get_dungeon_item_pool +from ...EntranceShuffle import link_inverted_entrances +from ...InvertedRegions import create_inverted_regions +from ...ItemPool import difficulties +from ...Items import item_factory +from ...Options import GlitchesRequired +from ...Regions import mark_light_world_regions +from ...Shops import create_shops -from worlds.alttp.test import LTTPTestBase +from ..bases import LTTPTestBase, TestBase class TestInvertedOWG(TestBase, LTTPTestBase): diff --git a/worlds/alttp/test/items/TestDifficulty.py b/worlds/alttp/test/items/TestDifficulty.py index 69dd8a4dc6ba..ff4deb858a72 100644 --- a/worlds/alttp/test/items/TestDifficulty.py +++ b/worlds/alttp/test/items/TestDifficulty.py @@ -1,5 +1,5 @@ -from worlds.alttp.ItemPool import difficulties -from test.bases import TestBase +from ...ItemPool import difficulties +from ..bases import TestBase base_items = 41 extra_counts = (15, 15, 10, 5, 25) diff --git a/worlds/alttp/test/minor_glitches/TestMinor.py b/worlds/alttp/test/minor_glitches/TestMinor.py index d5ffe8cac570..5ffb1ca8f9f2 100644 --- a/worlds/alttp/test/minor_glitches/TestMinor.py +++ b/worlds/alttp/test/minor_glitches/TestMinor.py @@ -1,11 +1,10 @@ -from worlds.alttp.Dungeons import get_dungeon_item_pool -from worlds.alttp.InvertedRegions import mark_dark_world_regions -from worlds.alttp.ItemPool import difficulties -from worlds.alttp.Items import item_factory -from test.bases import TestBase -from worlds.alttp.Options import GlitchesRequired +from ...Dungeons import get_dungeon_item_pool +from ...InvertedRegions import mark_dark_world_regions +from ...ItemPool import difficulties +from ...Items import item_factory +from ...Options import GlitchesRequired -from worlds.alttp.test import LTTPTestBase +from ..bases import LTTPTestBase, TestBase class TestMinor(TestBase, LTTPTestBase): diff --git a/worlds/alttp/test/owg/TestVanillaOWG.py b/worlds/alttp/test/owg/TestVanillaOWG.py index 6b6db1454b96..6c246865e9de 100644 --- a/worlds/alttp/test/owg/TestVanillaOWG.py +++ b/worlds/alttp/test/owg/TestVanillaOWG.py @@ -1,11 +1,10 @@ -from worlds.alttp.Dungeons import get_dungeon_item_pool -from worlds.alttp.InvertedRegions import mark_dark_world_regions -from worlds.alttp.ItemPool import difficulties -from worlds.alttp.Items import item_factory -from test.bases import TestBase -from worlds.alttp.Options import GlitchesRequired +from ...Dungeons import get_dungeon_item_pool +from ...InvertedRegions import mark_dark_world_regions +from ...ItemPool import difficulties +from ...Items import item_factory +from ...Options import GlitchesRequired -from worlds.alttp.test import LTTPTestBase +from ..bases import LTTPTestBase, TestBase class TestVanillaOWG(TestBase, LTTPTestBase): diff --git a/worlds/alttp/test/shops/TestSram.py b/worlds/alttp/test/shops/TestSram.py index 74a41a628988..a7dfd37cbec3 100644 --- a/worlds/alttp/test/shops/TestSram.py +++ b/worlds/alttp/test/shops/TestSram.py @@ -1,5 +1,5 @@ -from worlds.alttp.Shops import shop_table -from test.bases import TestBase +from ...Shops import shop_table +from ..bases import TestBase class TestSram(TestBase): diff --git a/worlds/alttp/test/vanilla/TestVanilla.py b/worlds/alttp/test/vanilla/TestVanilla.py index 031aec1ff914..2ddcdadc247a 100644 --- a/worlds/alttp/test/vanilla/TestVanilla.py +++ b/worlds/alttp/test/vanilla/TestVanilla.py @@ -1,10 +1,10 @@ -from worlds.alttp.Dungeons import get_dungeon_item_pool -from worlds.alttp.InvertedRegions import mark_dark_world_regions -from worlds.alttp.ItemPool import difficulties -from worlds.alttp.Items import item_factory -from test.bases import TestBase -from worlds.alttp.Options import GlitchesRequired -from worlds.alttp.test import LTTPTestBase +from ...Dungeons import get_dungeon_item_pool +from ...InvertedRegions import mark_dark_world_regions +from ...ItemPool import difficulties +from ...Items import item_factory +from ...Options import GlitchesRequired + +from ..bases import LTTPTestBase, TestBase class TestVanilla(TestBase, LTTPTestBase): diff --git a/worlds/pokemon_emerald/test/test_warps.py b/worlds/pokemon_emerald/test/test_warps.py index d1b5b01dcf7f..f210ff6b246f 100644 --- a/worlds/pokemon_emerald/test/test_warps.py +++ b/worlds/pokemon_emerald/test/test_warps.py @@ -1,8 +1,8 @@ -from test.bases import TestBase +from unittest import TestCase from ..data import Warp -class TestWarps(TestBase): +class TestWarps(TestCase): def test_warps_connect_ltr(self) -> None: # 2-way self.assertTrue(Warp("FAKE_MAP_A:0/FAKE_MAP_B:0").connects_to(Warp("FAKE_MAP_B:0/FAKE_MAP_A:0"))) From 18ac9210cb1205396901519cdd5bfad9dff3f543 Mon Sep 17 00:00:00 2001 From: PoryGone <98504756+PoryGone@users.noreply.github.com> Date: Mon, 8 Sep 2025 21:29:31 -0400 Subject: [PATCH 0717/1218] SA2B: Logic Fixes and Black Market Trap Name Improvements (#5427) * Logic fixes and more Chao and Fake Item names * Fix typo * Overhaul Shop Trap Item names --- worlds/sa2b/AestheticData.py | 419 +++++++++++++++++++++++++---------- worlds/sa2b/Rules.py | 5 +- worlds/sa2b/__init__.py | 12 +- 3 files changed, 313 insertions(+), 123 deletions(-) diff --git a/worlds/sa2b/AestheticData.py b/worlds/sa2b/AestheticData.py index 386b2850dfb7..794272919414 100644 --- a/worlds/sa2b/AestheticData.py +++ b/worlds/sa2b/AestheticData.py @@ -170,126 +170,309 @@ "Portia", "Graves", "Kaycee", + "Ghandi", + "Medli", + "Jak", + "Wario", + "Theo", ] -totally_real_item_names = [ - "Mallet", - "Lava Rod", - "Master Knife", - "Slippers", - "Spade", - - "Progressive Car Upgrade", - "Bonus Token", - - "Shortnail", - "Runmaster", - - "Courage Form", - "Auto Courage", - "Donald Defender", - "Goofy Blizzard", - "Ultimate Weapon", - - "Song of the Sky Whale", - "Gryphon Shoes", - "Wing Key", - "Strength Anklet", - - "Hairclip", - - "Key of Wisdom", - - "Baking", - "Progressive Block Mining", - - "Jar", - "Whistle of Space", - "Rito Tunic", - - "Kitchen Sink", - - "Rock Badge", - "Key Card", - "Pikachu", - "Eevee", - "HM02 Strength", - - "Progressive Astromancers", - "Progressive Chefs", - "The Living Safe", - "Lady Quinn", - - "Dio's Worst Enemy", - - "Pink Chaos Emerald", - "Black Chaos Emerald", - "Tails - Large Cannon", - "Eggman - Bazooka", - "Eggman - Booster", - "Knuckles - Shades", - "Sonic - Magic Shoes", - "Shadow - Bounce Bracelet", - "Rouge - Air Necklace", - "Big Key (Eggman's Pyramid)", - - "Sensor Bunker", - "Phantom", - "Soldier", - - "Plasma Suit", - "Gravity Beam", - "Hi-Jump Ball", - - "Cannon Unlock LLL", - "Feather Cap", - - "Progressive Yoshi", - "Purple Switch Palace", - "Cape Feather", - - "Cane of Bryan", - - "Van Repair", - "Autumn", - "Galaxy Knife", - "Green Cabbage Seeds", - - "Timespinner Cog 1", - - "Ladder", - - "Visible Dots", - - "CooCoo", - - "Blueberry", - - "Ear of Luigi", - - "Mega Nut", - - "DUELIST ALLIANCE", - "DUEL OVERLOAD", - "POWER OF THE ELEMENTS", - "S:P Little Knight", - "Red-Eyes Dark Dragoon", - - "Fire Hat", - - "Area: Taverly", - "Area: Meiyerditch", - "Fire Cape", - - "Donald Zeta Flare", - - "Category One of a Kind", - "Category Fuller House", - - "Passive Camoflage", - - "Earth Card", -] +totally_real_item_names: dict[str, list[str]] = { + "Bumper Stickers": [ + "Bonus Score", + "Boosting Bumper", + ], + + "Castlevania 64": [ + "Earth card", + "Venus card", + "Ax", + "Storehouse Key", + ], + + "Celeste 64": [ + "Blueberry", + "Side Flip", + "Triple Dash Refills", + "Swap Blocks", + "Dream Blocks", + ], + + "Celeste (Open World)": [ + "Green Boosters", + "Triple Dash Refills", + "Rising Platforms", + "Red Bubbles", + "Granny's Car Keys", + "Blueberry", + ], + + "Civilization VI": [ + "Advanced Trebuchets", + "The Wheel 2", + "NFTs", + ], + + "Donkey Kong Country 3": [ + "Progressive Car Upgrade", + "Bonus Token", + ], + + "Factorio": [ + "logistic-ai", + "progressive-militia", + "progressive-stronger-explosives", + "uranium-food", + ], + + "A Hat in Time": [ + "Fire Hat", + "69 Pons", + "Relic (Green Canyon)", + "Relic (Cooler Cow)", + "Time Fragment", + ], + + "Hollow Knight": [ + "Shortnail", + "Runmaster", + ], + + "Jak and Daxter The Precursor Legacy": [ + "69 Precursor Orbs", + "Jump Roll", + "Roll Kick", + ], + + "Kirby's Dream Land 3": [ + "CooCoo", + ], + + "Kingdom Hearts 2": [ + "Courage Form", + "Auto Courage", + "Donald Defender", + "Goofy Blizzard", + "Ultimate Weapon", + ], + + "Lingo": [ + "Art Gallery (First Floor)", + "Color Hunt - Pink Barrier", + ], + + "A Link to the Past": [ + "Mallet", + "Lava Rod", + "Master Knife", + "Slippers", + "Spade", + "Big Key (Dark Palace)", + "Big Key (Hera Tower)", + ], + + "Links Awakening DX": [ + "Song of the Sky Whale", + "Gryphon Shoes", + "Wing Key", + "Strength Anklet", + ], + + "Mario & Luigi Superstar Saga": [ + "Mega Nut", + ], + + "The Messenger": [ + "Key of Anger", + "Time Shard (69)", + "Hydro", + ], + + "Muse Dash": [ + "U.N. Owen Was Her", + "Renai Circulation", + "Flyers", + ], + + "Noita": [ + "Gold (69)", + "Sphere", + "Melee Die", + ], + + "Ocarina of Time": [ + "Jar", + "Whistle of Space", + "Rito Tunic", + "Boss Key (Forest Haven)", + "Boss Key (Swamp Palace)", + "Boss Key (Great Bay Temple)", + ], + + "Old School Runescape": [ + "Area: Taverly", + "Area: Meiyerditch", + "Fire Cape", + ], + + "Overcooked! 2": [ + "Kitchen Sink", + ], + + "Paint": [ + "AI Enhance", + "Paint Bucket", + "Pen", + ], + + "Pokemon Red and Blue": [ + "Rock Badge", + "Key Card", + "Pikachu", + "Eevee", + "HM02 Strength", + "HM05 Fly", + "HM01 Surf", + "Card Key 12F", + ], + + "Risk of Rain 2": [ + "Dio's Worst Enemy", + "Stage 5", + "Mythical Item", + ], + + "Rogue Legacy": [ + "Progressive Astromancers", + "Progressive Chefs", + "The Living Safe", + "Lady Quinn", + ], + + "Saving Princess": [ + "Fire Spreadshot", + "Volcano Key", + "Frozen Key", + ], + + "Secret of Evermore": [ + "Mantis Claw", + "Progressive pants", + "Deflect", + ], + + "shapez": [ + "Spinner", + "Toggle", + "Slicer", + "Splitter", + ], + + "SMZ3": [ + "Cane of Bryan", + ], + + "Sonic Adventure 2 Battle": [ + "Pink Chaos Emerald", + "Black Chaos Emerald", + "Tails - Large Cannon", + "Eggman - Bazooka", + "Eggman - Booster", + "Knuckles - Shades", + "Sonic - Magic Shoes", + "Shadow - Bounce Bracelet", + "Rouge - Air Necklace", + "Big Key (Eggman's Pyramid)", + ], + + "Starcraft 2": [ + "Sensor Bunker", + "Phantom", + "Soldier", + ], + + "Stardew Valley": [ + "Van Repair", + "Ship Repair", + "Autumn", + "Galaxy Knife", + "Green Cabbage Seeds", + "Casket", + "Pet Moonlight Jelly", + "Adventurer's Guild Key", + ], + + "Super Mario Land 2": [ + "Luigi Coin", + "Luigi Zone Progression", + "Hard Mode", + ], + + "Super Metroid": [ + "Plasma Suit", + "Gravity Beam", + "Hi-Jump Ball", + ], + + "Super Mario 64": [ + "Cannon Unlock LLL", + "Feather Cap", + ], + + "Super Mario World": [ + "Progressive Yoshi", + "Purple Switch Palace", + "Cape Feather", + "Fire Flower", + "Cling", + "Twirl Jump", + ], + + "Timespinner": [ + "Timespinner Cog 1", + "Leg Cannon", + ], + + "TUNIC": [ + "Ladder To West Forest", + "Money x69", + "Page 69", + "Master Sword", + ], + + "The Wind Waker": [ + "Ballad of Storms", + "Wind God's Song", + "Earth God's Song", + "Ordon's Pearl", + ], + + "The Witness": [ + "Visible Dots", + ], + + "Yacht Dice": [ + "Category One of a Kind", + "Category Fuller House", + ], + + "Yoshi's Island": [ + "Ear of Luigi", + "+69 Stars", + "Water Melon", + "World 7 Gate", + "Small Spring Ball", + ], + + "Yu-Gi-Oh! 2006": [ + "DUELIST ALLIANCE", + "DUEL OVERLOAD", + "POWER OF THE ELEMENTS", + "S:P Little Knight", + "Red-Eyes Dark Dragoon", + "Maxx C" + ], +} all_exits = [ 0x00, # Lobby to Neutral diff --git a/worlds/sa2b/Rules.py b/worlds/sa2b/Rules.py index a7ea9becb1cf..e5080f462a20 100644 --- a/worlds/sa2b/Rules.py +++ b/worlds/sa2b/Rules.py @@ -1406,7 +1406,8 @@ def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, pla lambda state: (state.has(ItemName.rouge_mystic_melody, player) and state.has(ItemName.rouge_treasure_scope, player))) add_rule(multiworld.get_location(LocationName.white_jungle_lifebox_2, player), - lambda state: state.has(ItemName.shadow_flame_ring, player)) + lambda state: (state.has(ItemName.shadow_flame_ring, player) and + state.has(ItemName.shadow_air_shoes, player))) add_rule(multiworld.get_location(LocationName.metal_harbor_lifebox_3, player), lambda state: state.has(ItemName.sonic_light_shoes, player)) @@ -2062,6 +2063,8 @@ def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, pla add_rule(multiworld.get_location(LocationName.mad_space_big, player), lambda state: state.has(ItemName.rouge_iron_boots, player)) + add_rule(multiworld.get_location(LocationName.cannon_core_big_1, player), + lambda state: state.has(ItemName.tails_booster, player)) add_rule(multiworld.get_location(LocationName.cannon_core_big_2, player), lambda state: state.has(ItemName.tails_booster, player) and state.has(ItemName.eggman_jet_engine, player)) diff --git a/worlds/sa2b/__init__.py b/worlds/sa2b/__init__.py index d7c9ceaebaef..21989626db9c 100644 --- a/worlds/sa2b/__init__.py +++ b/worlds/sa2b/__init__.py @@ -613,7 +613,8 @@ def any_chao_locations_active(self) -> bool: self.options.chao_stats.value > 0 or \ self.options.chao_animal_parts or \ self.options.chao_kindergarten or \ - self.options.black_market_slots.value > 0: + self.options.black_market_slots.value > 0 or \ + self.options.goal.value == 7: return True; return False @@ -757,13 +758,16 @@ def generate_black_market_data(self) -> typing.Dict[int, int]: item_names = [] player_names = [] progression_flags = [] - totally_real_item_names_copy = totally_real_item_names.copy() location_names = [(LocationName.chao_black_market_base + str(i)) for i in range(1, self.options.black_market_slots.value + 1)] locations = [self.multiworld.get_location(location_name, self.player) for location_name in location_names] for location in locations: if location.item.classification & ItemClassification.trap: - item_name = self.random.choice(totally_real_item_names_copy) - totally_real_item_names_copy.remove(item_name) + item_name = "" + if location.item.game in totally_real_item_names: + item_name = self.random.choice(totally_real_item_names[location.item.game]) + else: + random_game_names: list[str] = self.random.choice(list(totally_real_item_names.values())) + item_name = self.random.choice(random_game_names) item_names.append(item_name) else: item_names.append(location.item.name) From 287bb638a09ad6ef4d0c154d915fa569da76fbd5 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 9 Sep 2025 19:33:31 +0200 Subject: [PATCH 0718/1218] Docs: Kivy Style (#5425) Co-authored-by: Silvris <58583688+Silvris@users.noreply.github.com> Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> --- docs/style.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/style.md b/docs/style.md index 5333155db96a..bb1526faf50c 100644 --- a/docs/style.md +++ b/docs/style.md @@ -60,3 +60,9 @@ * Indent `case` inside `switch ` with 2 spaces. * Use single quotes. * Semicolons are required after every statement. + +## KV + +* Style should be defined in `.kv` as much as possible, only Python when unavailable. +* Should follow [our Python style](#python-code) where appropriate (quotation marks, indentation). +* When escaping a line break, add a space between code and backslash. From 9aa0bf72456e843aa1a8227b93c1bd4e3b26bd1e Mon Sep 17 00:00:00 2001 From: Rosalie <61372066+Rosalie-A@users.noreply.github.com> Date: Tue, 9 Sep 2025 18:42:32 -0400 Subject: [PATCH 0719/1218] FF1: New Maintainership (#5027) * Submitting myself for FF1 maintainership * Uncommented an important line. --- docs/CODEOWNERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index d5f35888090a..7b8e48af142e 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -72,6 +72,9 @@ # Faxanadu /worlds/faxanadu/ @Daivuk +# Final Fantasy (1) +/worlds/ff1/ @Rosalie-A + # Final Fantasy Mystic Quest /worlds/ffmq/ @Alchav @wildham0 @@ -241,9 +244,6 @@ # compatibility, these worlds may be deleted. If you are interested in stepping up as maintainer for # any of these worlds, please review `/docs/world maintainer.md` documentation. -# Final Fantasy (1) -# /worlds/ff1/ - # Ocarina of Time # /worlds/oot/ From 78b529fc239d1358983d3cd1faab0b5199d5f659 Mon Sep 17 00:00:00 2001 From: Colin <32756996+TriumphantBass@users.noreply.github.com> Date: Wed, 10 Sep 2025 07:27:13 -0700 Subject: [PATCH 0720/1218] Timespinner: Adds Lantern Check flags, Missing Traps (#5188) * Timespinner: Add Torch Flags * Add comment of all torch locations * Add gyre and dark forest lanterns * Add Ancient Pyramid * Don't make cube default progression * Add Emperors Tower * Add lake desolation, forest * Add lab * Add library, varndagroth * Add hangar * Add ramparts * Add Xarion * Add castle keep * Add royal towers * Add lake serene * Add remaining checks * Add missing region * Fix region names * Fix location id * Add traps to settings * Add restriction to elevator keycard torch * Set new traps to have quantity 0 by default * Scythe is now useful due to torch shredding * Add additional lantern * Un-disable missing lantern * Include location ids in tracker * Remove additional space * Fix paren * Add missing lantern * Remove tablet requirement for torches * Update filler V card * Fix brackets * Address feedback --- WebHostLib/tracker.py | 48 +- worlds/timespinner/Items.py | 8 +- worlds/timespinner/Locations.py | 990 ++++++++++++++++++++------ worlds/timespinner/LogicExtensions.py | 7 + worlds/timespinner/Options.py | 14 +- worlds/timespinner/Regions.py | 27 +- worlds/timespinner/__init__.py | 11 +- 7 files changed, 844 insertions(+), 261 deletions(-) diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py index 18145daea8d8..356eb9768434 100644 --- a/WebHostLib/tracker.py +++ b/WebHostLib/tracker.py @@ -954,30 +954,13 @@ def render_Timespinner_tracker(tracker_data: TrackerData, team: int, player: int "Lab Glasses": "https://timespinnerwiki.com/mediawiki/images/4/4a/Lab_Glasses.png", "Eye Orb": "https://timespinnerwiki.com/mediawiki/images/a/a4/Eye_Orb.png", "Lab Coat": "https://timespinnerwiki.com/mediawiki/images/5/51/Lab_Coat.png", - "Demon": "https://timespinnerwiki.com/mediawiki/images/f/f8/Familiar_Demon.png", + "Demon": "https://timespinnerwiki.com/mediawiki/images/f/f8/Familiar_Demon.png", + "Cube of Bodie": "https://timespinnerwiki.com/mediawiki/images/1/14/Menu_Icon_Stats.png" } timespinner_location_ids = { - "Present": [ - 1337000, 1337001, 1337002, 1337003, 1337004, 1337005, 1337006, 1337007, 1337008, 1337009, - 1337010, 1337011, 1337012, 1337013, 1337014, 1337015, 1337016, 1337017, 1337018, 1337019, - 1337020, 1337021, 1337022, 1337023, 1337024, 1337025, 1337026, 1337027, 1337028, 1337029, - 1337030, 1337031, 1337032, 1337033, 1337034, 1337035, 1337036, 1337037, 1337038, 1337039, - 1337040, 1337041, 1337042, 1337043, 1337044, 1337045, 1337046, 1337047, 1337048, 1337049, - 1337050, 1337051, 1337052, 1337053, 1337054, 1337055, 1337056, 1337057, 1337058, 1337059, - 1337060, 1337061, 1337062, 1337063, 1337064, 1337065, 1337066, 1337067, 1337068, 1337069, - 1337070, 1337071, 1337072, 1337073, 1337074, 1337075, 1337076, 1337077, 1337078, 1337079, - 1337080, 1337081, 1337082, 1337083, 1337084, 1337085], - "Past": [ - 1337086, 1337087, 1337088, 1337089, - 1337090, 1337091, 1337092, 1337093, 1337094, 1337095, 1337096, 1337097, 1337098, 1337099, - 1337100, 1337101, 1337102, 1337103, 1337104, 1337105, 1337106, 1337107, 1337108, 1337109, - 1337110, 1337111, 1337112, 1337113, 1337114, 1337115, 1337116, 1337117, 1337118, 1337119, - 1337120, 1337121, 1337122, 1337123, 1337124, 1337125, 1337126, 1337127, 1337128, 1337129, - 1337130, 1337131, 1337132, 1337133, 1337134, 1337135, 1337136, 1337137, 1337138, 1337139, - 1337140, 1337141, 1337142, 1337143, 1337144, 1337145, 1337146, 1337147, 1337148, 1337149, - 1337150, 1337151, 1337152, 1337153, 1337154, 1337155, - 1337171, 1337172, 1337173, 1337174, 1337175], + "Present": list(range(1337000, 1337085)), + "Past": list(range(1337086, 1337175)), "Ancient Pyramid": [ 1337236, 1337246, 1337247, 1337248, 1337249] @@ -985,26 +968,23 @@ def render_Timespinner_tracker(tracker_data: TrackerData, team: int, player: int slot_data = tracker_data.get_slot_data(team, player) if (slot_data["DownloadableItems"]): - timespinner_location_ids["Present"] += [ - 1337156, 1337157, 1337159, - 1337160, 1337161, 1337162, 1337163, 1337164, 1337165, 1337166, 1337167, 1337168, 1337169, - 1337170] + timespinner_location_ids["Present"] += [1337156, 1337157] + list(range(1337159, 1337170)) if (slot_data["Cantoran"]): timespinner_location_ids["Past"].append(1337176) if (slot_data["LoreChecks"]): - timespinner_location_ids["Present"] += [ - 1337177, 1337178, 1337179, - 1337180, 1337181, 1337182, 1337183, 1337184, 1337185, 1337186, 1337187] - timespinner_location_ids["Past"] += [ - 1337188, 1337189, - 1337190, 1337191, 1337192, 1337193, 1337194, 1337195, 1337196, 1337197, 1337198] + timespinner_location_ids["Present"] += list(range(1337177, 1337187)) + timespinner_location_ids["Past"] += list(range(1337188, 1337198)) if (slot_data["GyreArchives"]): - timespinner_location_ids["Ancient Pyramid"] += [ - 1337237, 1337238, 1337239, - 1337240, 1337241, 1337242, 1337243, 1337244, 1337245] + timespinner_location_ids["Ancient Pyramid"] += list(range(1337237, 1337245)) if (slot_data["PyramidStart"]): timespinner_location_ids["Ancient Pyramid"] += [ 1337233, 1337234, 1337235] + if (slot_data["PureTorcher"]): + timespinner_location_ids["Present"] += list(range(1337250, 1337352)) + list(range(1337422, 1337496)) + [1337506] + list(range(1337712, 1337779)) + [1337781, 1337782] + timespinner_location_ids["Past"] += list(range(1337497, 1337505)) + list(range(1337507, 1337711)) + [1337780] + timespinner_location_ids["Ancient Pyramid"] += list(range(1337369, 1337421)) + if (slot_data["GyreArchives"]): + timespinner_location_ids["Ancient Pyramid"] += list(range(1337353, 1337368)) display_data = {} diff --git a/worlds/timespinner/Items.py b/worlds/timespinner/Items.py index 4cfcc289fdc9..957c617675fb 100644 --- a/worlds/timespinner/Items.py +++ b/worlds/timespinner/Items.py @@ -174,7 +174,7 @@ class ItemData(NamedTuple): 'Corruption': ItemData('Orb Spell', 1337161), 'Lightwall': ItemData('Orb Spell', 1337162, progression=True), 'Bleak Ring': ItemData('Orb Passive', 1337163, useful=True), - 'Scythe Ring': ItemData('Orb Passive', 1337164), + 'Scythe Ring': ItemData('Orb Passive', 1337164, useful=True), 'Pyro Ring': ItemData('Orb Passive', 1337165, progression=True), 'Royal Ring': ItemData('Orb Passive', 1337166, progression=True), 'Shield Ring': ItemData('Orb Passive', 1337167), @@ -208,9 +208,11 @@ class ItemData(NamedTuple): 'Lab Access Research': ItemData('Lab Access', 1337196, progression=True), 'Lab Access Dynamo': ItemData('Lab Access', 1337197, progression=True), 'Drawbridge Key': ItemData('Key', 1337198, progression=True), - # 1337199 Reserved + 'Cube of Bodie': ItemData('Relic', 1337199, progression=True), 'Spider Trap': ItemData('Trap', 1337200, 0, trap=True), - # 1337201 - 1337248 Reserved + 'Lights Out Trap': ItemData('Trap', 1337201, 0, trap=True), + 'Palm Punch Trap': ItemData('Trap', 1337202, 0, trap=True), + # 1337203 - 1337248 Reserved 'Max Sand': ItemData('Stat', 1337249, 14) } diff --git a/worlds/timespinner/Locations.py b/worlds/timespinner/Locations.py index 21e5501e580f..ffd2f60eb910 100644 --- a/worlds/timespinner/Locations.py +++ b/worlds/timespinner/Locations.py @@ -22,236 +22,238 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio # 1337000 - 1337155 Generic locations # 1337171 - 1337175 New Pickup checks # 1337246 - 1337249 Ancient Pyramid + # 1337250 - 1337781 Torch checks + # 1337782 - 1337999 Reserved location_table: List[LocationData] = [ # Present item locations - LocationData('Tutorial', 'Tutorial: Yo Momma 1', 1337000), - LocationData('Tutorial', 'Tutorial: Yo Momma 2', 1337001), - LocationData('Lake desolation', 'Lake Desolation: Starter chest 2', 1337002), - LocationData('Lake desolation', 'Lake Desolation: Starter chest 3', 1337003), - LocationData('Lake desolation', 'Lake Desolation: Starter chest 1', 1337004), - LocationData('Lake desolation', 'Lake Desolation (Lower): Timespinner Wheel room', 1337005), - LocationData('Lake desolation', 'Lake Desolation: Forget me not chest', 1337006, lambda state: logic.has_fire(state) and state.can_reach('Upper Lake Serene', 'Region', player)), + LocationData('Tutorial', 'Tutorial: Yo Momma 1', 1337000), + LocationData('Tutorial', 'Tutorial: Yo Momma 2', 1337001), + LocationData('Lake desolation', 'Lake Desolation: Starter chest 2', 1337002), + LocationData('Lake desolation', 'Lake Desolation: Starter chest 3', 1337003), + LocationData('Lake desolation', 'Lake Desolation: Starter chest 1', 1337004), + LocationData('Lake desolation', 'Lake Desolation (Lower): Timespinner Wheel room', 1337005), + LocationData('Lake desolation', 'Lake Desolation: Forget me not chest', 1337006, lambda state: logic.has_fire(state) and state.can_reach('Upper Lake Serene', 'Region', player)), LocationData('Lake desolation', 'Lake Desolation (Lower): Chicken chest', 1337007, logic.has_timestop), - LocationData('Lower lake desolation', 'Lake Desolation (Lower): Not so secret room', 1337008, logic.can_break_walls), - LocationData('Lower lake desolation', 'Lake Desolation (Upper): Tank chest', 1337009, logic.has_timestop), - LocationData('Upper lake desolation', 'Lake Desolation (Upper): Oxygen recovery room', 1337010), - LocationData('Upper lake desolation', 'Lake Desolation (Upper): Secret room', 1337011, logic.can_break_walls), - LocationData('Upper lake desolation', 'Lake Desolation (Upper): Double jump cave platform', 1337012, logic.has_doublejump), - LocationData('Upper lake desolation', 'Lake Desolation (Upper): Double jump cave floor', 1337013), - LocationData('Upper lake desolation', 'Lake Desolation (Upper): Sparrow chest', 1337014), - LocationData('Upper lake desolation', 'Lake Desolation (Upper): Crash site pedestal', 1337015), - LocationData('Upper lake desolation', 'Lake Desolation (Upper): Crash site chest 1', 1337016, lambda state: state.has('Killed Maw', player)), - LocationData('Upper lake desolation', 'Lake Desolation (Upper): Crash site chest 2', 1337017, lambda state: state.has('Killed Maw', player)), - LocationData('Eastern lake desolation', 'Lake Desolation: Kitty Boss', 1337018), - LocationData('Library', 'Library: Basement', 1337019), - LocationData('Library', 'Library: Warp gate', 1337020), - LocationData('Library', 'Library: Librarian', 1337021), - LocationData('Library', 'Library: Reading nook chest', 1337022), - LocationData('Library', 'Library: Storage room chest 1', 1337023, logic.has_keycard_D), - LocationData('Library', 'Library: Storage room chest 2', 1337024, logic.has_keycard_D), - LocationData('Library', 'Library: Storage room chest 3', 1337025, logic.has_keycard_D), - LocationData('Library top', 'Library: Backer room chest 5', 1337026), - LocationData('Library top', 'Library: Backer room chest 4', 1337027), - LocationData('Library top', 'Library: Backer room chest 3', 1337028), - LocationData('Library top', 'Library: Backer room chest 2', 1337029), - LocationData('Library top', 'Library: Backer room chest 1', 1337030), - LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Elevator Key not required', 1337031), - LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Ye olde Timespinner', 1337032), - LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Bottom floor', 1337033, logic.has_keycard_C), - LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Air vents secret', 1337034, logic.can_break_walls), - LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Elevator chest', 1337035, lambda state: state.has('Elevator Keycard', player)), - LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers: Bridge', 1337036), - LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Elevator chest', 1337037), - LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Elevator card chest', 1337038, lambda state: state.has('Elevator Keycard', player) or logic.has_doublejump(state)), - LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Air vents right chest', 1337039, lambda state: state.has('Elevator Keycard', player) or logic.has_doublejump(state)), - LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Air vents left chest', 1337040, lambda state: state.has('Elevator Keycard', player) or logic.has_doublejump(state)), - LocationData('Varndagroth tower right (lower)', 'Varndagroth Towers (Right): Bottom floor', 1337041), - LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Varndagroth', 1337042, logic.has_keycard_C), - LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Spider Hell', 1337043, logic.has_keycard_A), - LocationData('Skeleton Shaft', 'Sealed Caves (Xarion): Skeleton', 1337044), - LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Shroom jump room', 1337045, logic.has_timestop), - LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Double shroom room', 1337046), - LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Jacksquat room', 1337047, logic.has_forwarddash_doublejump), - LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Below Jacksquat room', 1337048), - LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Secret room', 1337049, logic.can_break_walls), - LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Bottom left room', 1337050), - LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Last chance before Xarion', 1337051, logic.has_doublejump), - LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Xarion', 1337052, lambda state: not flooded.flood_xarion or state.has('Water Mask', player)), - LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Water hook', 1337053, lambda state: state.has('Water Mask', player)), - LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Siren room underwater right', 1337054, lambda state: state.has('Water Mask', player)), - LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Siren room underwater left', 1337055, lambda state: state.has('Water Mask', player)), - LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Cave after sirens chest 1', 1337056), - LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Cave after sirens chest 2', 1337057), - LocationData('Military Fortress', 'Military Fortress: Bomber chest', 1337058, lambda state: state.has('Timespinner Wheel', player) and logic.has_doublejump_of_npc(state)), - LocationData('Military Fortress', 'Military Fortress: Close combat room', 1337059), - LocationData('Military Fortress (hangar)', 'Military Fortress: Soldiers bridge', 1337060), - LocationData('Military Fortress (hangar)', 'Military Fortress: Giantess room', 1337061), - LocationData('Military Fortress (hangar)', 'Military Fortress: Giantess bridge', 1337062), - LocationData('Military Fortress (hangar)', 'Military Fortress: B door chest 2', 1337063, lambda state: logic.has_keycard_B(state) and (state.has('Water Mask', player) if flooded.flood_lab else logic.has_doublejump(state))), - LocationData('Military Fortress (hangar)', 'Military Fortress: B door chest 1', 1337064, lambda state: logic.has_keycard_B(state) and (state.has('Water Mask', player) if flooded.flood_lab else logic.has_doublejump(state))), - LocationData('Military Fortress (hangar)', 'Military Fortress: Pedestal', 1337065, lambda state: state.has('Water Mask', player) if flooded.flood_lab else (logic.has_doublejump_of_npc(state) or logic.has_forwarddash_doublejump(state))), - LocationData('The lab', 'Lab: Coffee break', 1337066), - LocationData('The lab', 'Lab: Lower trash right', 1337067, logic.has_doublejump), - LocationData('The lab', 'Lab: Lower trash left', 1337068, lambda state: logic.has_doublejump_of_npc(state) if options.lock_key_amadeus else logic.has_upwarddash(state) ), - LocationData('The lab', 'Lab: Below lab entrance', 1337069, logic.has_doublejump), - LocationData('The lab (power off)', 'Lab: Trash jump room', 1337070, lambda state: not options.lock_key_amadeus or logic.has_doublejump_of_npc(state) ), - LocationData('The lab (power off)', 'Lab: Dynamo Works', 1337071, lambda state: not options.lock_key_amadeus or (state.has_all(('Lab Access Research', 'Lab Access Dynamo'), player)) ), - LocationData('The lab (upper)', 'Lab: Genza (Blob Mom)', 1337072), - LocationData('The lab (power off)', 'Lab: Experiment #13', 1337073, lambda state: not options.lock_key_amadeus or state.has('Lab Access Experiment', player) ), - LocationData('The lab (upper)', 'Lab: Download and chest room chest', 1337074), - LocationData('The lab (upper)', 'Lab: Lab secret', 1337075, logic.can_break_walls), - LocationData('The lab (power off)', 'Lab: Spider Hell', 1337076, lambda state: logic.has_keycard_A(state) and not options.lock_key_amadeus or state.has('Lab Access Research', player)), - LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard bottom chest', 1337077), - LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard floor secret', 1337078, lambda state: logic.has_upwarddash(state) and logic.can_break_walls(state)), - LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard upper chest', 1337079, lambda state: logic.has_upwarddash(state)), - LocationData('Emperors tower', 'Emperor\'s Tower: Galactic sage room', 1337080), - LocationData('Emperors tower', 'Emperor\'s Tower: Bottom right tower', 1337081), - LocationData('Emperors tower', 'Emperor\'s Tower: Wayyyy up there', 1337082, logic.has_doublejump_of_npc), - LocationData('Emperors tower', 'Emperor\'s Tower: Left tower balcony', 1337083), - LocationData('Emperors tower', 'Emperor\'s Tower: Emperor\'s Chambers chest', 1337084), - LocationData('Emperors tower', 'Emperor\'s Tower: Emperor\'s Chambers pedestal', 1337085), + LocationData('Lower lake desolation', 'Lake Desolation (Lower): Not so secret room', 1337008, logic.can_break_walls), + LocationData('Lower lake desolation', 'Lake Desolation (Upper): Tank chest', 1337009, logic.has_timestop), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Oxygen recovery room', 1337010), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Secret room', 1337011, logic.can_break_walls), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Double jump cave platform', 1337012, logic.has_doublejump), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Double jump cave floor', 1337013), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Sparrow chest', 1337014), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Crash site pedestal', 1337015), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Crash site chest 1', 1337016, lambda state: state.has('Killed Maw', player)), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Crash site chest 2', 1337017, lambda state: state.has('Killed Maw', player)), + LocationData('Eastern lake desolation', 'Lake Desolation: Kitty Boss', 1337018), + LocationData('Library', 'Library: Basement', 1337019), + LocationData('Library', 'Library: Warp gate', 1337020), + LocationData('Library', 'Library: Librarian', 1337021), + LocationData('Library', 'Library: Reading nook chest', 1337022), + LocationData('Library', 'Library: Storage room chest 1', 1337023, logic.has_keycard_D), + LocationData('Library', 'Library: Storage room chest 2', 1337024, logic.has_keycard_D), + LocationData('Library', 'Library: Storage room chest 3', 1337025, logic.has_keycard_D), + LocationData('Library top', 'Library: Backer room chest 5', 1337026), + LocationData('Library top', 'Library: Backer room chest 4', 1337027), + LocationData('Library top', 'Library: Backer room chest 3', 1337028), + LocationData('Library top', 'Library: Backer room chest 2', 1337029), + LocationData('Library top', 'Library: Backer room chest 1', 1337030), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Elevator Key not required', 1337031), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Ye olde Timespinner', 1337032), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Bottom floor', 1337033, logic.has_keycard_C), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Air vents secret', 1337034, logic.can_break_walls), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Elevator chest', 1337035, lambda state: state.has('Elevator Keycard', player)), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers: Bridge', 1337036), + LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Elevator chest', 1337037), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Elevator card chest', 1337038, lambda state: state.has('Elevator Keycard', player) or logic.has_doublejump(state)), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Air vents right chest', 1337039, lambda state: state.has('Elevator Keycard', player) or logic.has_doublejump(state)), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Air vents left chest', 1337040, lambda state: state.has('Elevator Keycard', player) or logic.has_doublejump(state)), + LocationData('Varndagroth tower right (lower)', 'Varndagroth Towers (Right): Bottom floor', 1337041), + LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Varndagroth', 1337042, logic.has_keycard_C), + LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Spider Hell', 1337043, logic.has_keycard_A), + LocationData('Skeleton Shaft', 'Sealed Caves (Xarion): Skeleton', 1337044), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Shroom jump room', 1337045, logic.has_timestop), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Double shroom room', 1337046), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Jacksquat room', 1337047, logic.has_forwarddash_doublejump), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Below Jacksquat room', 1337048), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Secret room', 1337049, logic.can_break_walls), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Bottom left room', 1337050), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Last chance before Xarion', 1337051, logic.has_doublejump), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Xarion', 1337052, lambda state: not flooded.flood_xarion or state.has('Water Mask', player)), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Water hook', 1337053, lambda state: state.has('Water Mask', player)), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Siren room underwater right', 1337054, lambda state: state.has('Water Mask', player)), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Siren room underwater left', 1337055, lambda state: state.has('Water Mask', player)), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Cave after sirens chest 1', 1337056), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Cave after sirens chest 2', 1337057), + LocationData('Military Fortress', 'Military Fortress: Bomber chest', 1337058, lambda state: state.has('Timespinner Wheel', player) and logic.has_doublejump_of_npc(state)), + LocationData('Military Fortress', 'Military Fortress: Close combat room', 1337059), + LocationData('Military Fortress (hangar)', 'Military Fortress: Soldiers bridge', 1337060), + LocationData('Military Fortress (hangar)', 'Military Fortress: Giantess room', 1337061), + LocationData('Military Fortress (hangar)', 'Military Fortress: Giantess bridge', 1337062), + LocationData('Military Fortress (hangar)', 'Military Fortress: B door chest 2', 1337063, lambda state: logic.has_keycard_B(state) and (state.has('Water Mask', player) if flooded.flood_lab else logic.has_doublejump(state))), + LocationData('Military Fortress (hangar)', 'Military Fortress: B door chest 1', 1337064, lambda state: logic.has_keycard_B(state) and (state.has('Water Mask', player) if flooded.flood_lab else logic.has_doublejump(state))), + LocationData('Military Fortress (hangar)', 'Military Fortress: Pedestal', 1337065, lambda state: state.has('Water Mask', player) if flooded.flood_lab else (logic.has_doublejump_of_npc(state) or logic.has_forwarddash_doublejump(state))), + LocationData('Main Lab', 'Lab: Coffee break', 1337066), + LocationData('Main Lab', 'Lab: Lower trash right', 1337067, logic.has_doublejump), + LocationData('Main Lab', 'Lab: Lower trash left', 1337068, lambda state: logic.has_doublejump_of_npc(state) if options.lock_key_amadeus else logic.has_upwarddash(state) ), + LocationData('Main Lab', 'Lab: Below lab entrance', 1337069, logic.has_doublejump), + LocationData('Main Lab', 'Lab: Trash jump room', 1337070, lambda state: not options.lock_key_amadeus or logic.has_doublejump_of_npc(state) ), + LocationData('Lab Research', 'Lab: Dynamo Works', 1337071, lambda state: not options.lock_key_amadeus or ( state.has('Lab Access Dynamo', player) and logic.has_upwarddash(state) )), + LocationData('The lab (upper)', 'Lab: Genza (Blob Mom)', 1337072), + LocationData('Main Lab', 'Lab: Experiment #13', 1337073, lambda state: not options.lock_key_amadeus or state.has('Lab Access Experiment', player) ), + LocationData('The lab (upper)', 'Lab: Download and chest room chest', 1337074), + LocationData('The lab (upper)', 'Lab: Lab secret', 1337075, logic.can_break_walls), + LocationData('Lab Research', 'Lab: Spider Hell', 1337076, lambda state: logic.has_keycard_A(state)), + LocationData('Emperors tower (courtyard)', 'Emperor\'s Tower: Courtyard bottom chest', 1337077), + LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard floor secret', 1337078, lambda state: logic.has_upwarddash(state) and logic.can_break_walls(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard upper chest', 1337079, lambda state: logic.has_upwarddash(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Galactic sage room', 1337080), + LocationData('Emperors tower', 'Emperor\'s Tower: Bottom right tower', 1337081), + LocationData('Emperors tower', 'Emperor\'s Tower: Wayyyy up there', 1337082, logic.has_doublejump_of_npc), + LocationData('Emperors tower', 'Emperor\'s Tower: Left tower balcony', 1337083), + LocationData('Emperors tower', 'Emperor\'s Tower: Emperor\'s Chambers chest', 1337084), + LocationData('Emperors tower', 'Emperor\'s Tower: Emperor\'s Chambers pedestal', 1337085), LocationData('Emperors tower', 'Killed Emperor', EventId), # Past item locations - LocationData('Refugee Camp', 'Refugee Camp: Neliste\'s Bra', 1337086), - LocationData('Refugee Camp', 'Refugee Camp: Storage chest 3', 1337087), - LocationData('Refugee Camp', 'Refugee Camp: Storage chest 2', 1337088), - LocationData('Refugee Camp', 'Refugee Camp: Storage chest 1', 1337089), - LocationData('Forest', 'Forest: Refugee camp roof', 1337090), - LocationData('Forest', 'Forest: Bat jump ledge', 1337091, lambda state: logic.has_doublejump_of_npc(state) or logic.has_forwarddash_doublejump(state) or logic.has_fastjump_on_npc(state)), - LocationData('Forest', 'Forest: Green platform secret', 1337092, logic.can_break_walls), - LocationData('Forest', 'Forest: Rats guarded chest', 1337093), - LocationData('Forest', 'Forest: Waterfall chest 1', 1337094, lambda state: state.has('Water Mask', player)), - LocationData('Forest', 'Forest: Waterfall chest 2', 1337095, lambda state: state.has('Water Mask', player)), - LocationData('Forest', 'Forest: Batcave', 1337096), - LocationData('Forest', 'Castle Ramparts: In the moat', 1337097, lambda state: not flooded.flood_moat or state.has('Water Mask', player)), - LocationData('Left Side forest Caves', 'Forest: Before Serene single bat cave', 1337098), - LocationData('Upper Lake Serene', 'Lake Serene (Upper): Rat nest', 1337099), - LocationData('Upper Lake Serene', 'Lake Serene (Upper): Double jump cave platform', 1337100, logic.has_doublejump), - LocationData('Upper Lake Serene', 'Lake Serene (Upper): Double jump cave floor', 1337101), - LocationData('Upper Lake Serene', 'Lake Serene (Upper): Cave secret', 1337102, logic.can_break_walls), + LocationData('Refugee Camp', 'Refugee Camp: Neliste\'s Bra', 1337086), + LocationData('Refugee Camp', 'Refugee Camp: Storage chest 3', 1337087), + LocationData('Refugee Camp', 'Refugee Camp: Storage chest 2', 1337088), + LocationData('Refugee Camp', 'Refugee Camp: Storage chest 1', 1337089), + LocationData('Forest', 'Forest: Refugee camp roof', 1337090), + LocationData('Forest', 'Forest: Bat jump ledge', 1337091, lambda state: logic.has_doublejump_of_npc(state) or logic.has_forwarddash_doublejump(state) or logic.has_fastjump_on_npc(state)), + LocationData('Forest', 'Forest: Green platform secret', 1337092, logic.can_break_walls), + LocationData('Forest', 'Forest: Rats guarded chest', 1337093), + LocationData('Forest', 'Forest: Waterfall chest 1', 1337094, lambda state: state.has('Water Mask', player)), + LocationData('Forest', 'Forest: Waterfall chest 2', 1337095, lambda state: state.has('Water Mask', player)), + LocationData('Forest', 'Forest: Batcave', 1337096), + LocationData('Forest', 'Castle Ramparts: In the moat', 1337097, lambda state: not flooded.flood_moat or state.has('Water Mask', player)), + LocationData('Left Side forest Caves', 'Forest: Before Serene single bat cave', 1337098), + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Rat nest', 1337099), + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Double jump cave platform', 1337100, logic.has_doublejump), + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Double jump cave floor', 1337101), + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Cave secret', 1337102, logic.can_break_walls), LocationData('Upper Lake Serene', 'Lake Serene: Before Big Bird', 1337175), - LocationData('Upper Lake Serene', 'Lake Serene: Behind the vines', 1337103), - LocationData('Upper Lake Serene', 'Lake Serene: Pyramid keys room', 1337104), + LocationData('Upper Lake Serene', 'Lake Serene: Behind the vines', 1337103), + LocationData('Upper Lake Serene', 'Lake Serene: Pyramid keys room', 1337104), LocationData('Upper Lake Serene', 'Lake Serene (Upper): Chicken ledge', 1337174), - LocationData('Lower Lake Serene', 'Lake Serene (Lower): Deep dive', 1337105), - LocationData('Left Side forest Caves', 'Lake Serene (Lower): Under the eels', 1337106, lambda state: state.has('Water Mask', player)), - LocationData('Lower Lake Serene', 'Lake Serene (Lower): Water spikes room', 1337107), - LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater secret', 1337108, logic.can_break_walls), - LocationData('Lower Lake Serene', 'Lake Serene (Lower): T chest', 1337109, lambda state: flooded.flood_lake_serene or logic.has_doublejump_of_npc(state)), - LocationData('Left Side forest Caves', 'Lake Serene (Lower): Past the eels', 1337110, lambda state: state.has('Water Mask', player)), - LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater pedestal', 1337111, lambda state: flooded.flood_lake_serene or logic.has_doublejump(state)), - LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Shroom jump room', 1337112, lambda state: flooded.flood_maw or logic.has_doublejump(state)), - LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Secret room', 1337113, lambda state: logic.can_break_walls(state) and (not flooded.flood_maw or state.has('Water Mask', player))), - LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Bottom left room', 1337114, lambda state: not flooded.flood_maw or state.has('Water Mask', player)), - LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Single shroom room', 1337115), - LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Jackpot room chest 1', 1337116, lambda state: flooded.flood_maw or logic.has_forwarddash_doublejump(state)), - LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Jackpot room chest 2', 1337117, lambda state: flooded.flood_maw or logic.has_forwarddash_doublejump(state)), - LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Jackpot room chest 3', 1337118, lambda state: flooded.flood_maw or logic.has_forwarddash_doublejump(state)), - LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Jackpot room chest 4', 1337119, lambda state: flooded.flood_maw or logic.has_forwarddash_doublejump(state)), - LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Pedestal', 1337120, lambda state: not flooded.flood_maw or state.has('Water Mask', player)), - LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Last chance before Maw', 1337121, lambda state: flooded.flood_maw or logic.has_doublejump(state)), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Deep dive', 1337105), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Under the eels', 1337106, lambda state: state.has('Water Mask', player)), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Water spikes room', 1337107), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater secret', 1337108, logic.can_break_walls), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): T chest', 1337109, lambda state: flooded.flood_lake_serene or logic.has_doublejump_of_npc(state)), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Past the eels', 1337110, lambda state: state.has('Water Mask', player)), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater pedestal', 1337111, lambda state: flooded.flood_lake_serene or logic.has_doublejump(state)), + LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Shroom jump room', 1337112, lambda state: flooded.flood_maw or logic.has_doublejump(state)), + LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Secret room', 1337113, lambda state: logic.can_break_walls(state) and (not flooded.flood_maw or state.has('Water Mask', player))), + LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Bottom left room', 1337114, lambda state: not flooded.flood_maw or state.has('Water Mask', player)), + LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Single shroom room', 1337115), + LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Jackpot room chest 1', 1337116, lambda state: flooded.flood_maw or logic.has_forwarddash_doublejump(state)), + LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Jackpot room chest 2', 1337117, lambda state: flooded.flood_maw or logic.has_forwarddash_doublejump(state)), + LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Jackpot room chest 3', 1337118, lambda state: flooded.flood_maw or logic.has_forwarddash_doublejump(state)), + LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Jackpot room chest 4', 1337119, lambda state: flooded.flood_maw or logic.has_forwarddash_doublejump(state)), + LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Pedestal', 1337120, lambda state: not flooded.flood_maw or state.has('Water Mask', player)), + LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Last chance before Maw', 1337121, lambda state: flooded.flood_maw or logic.has_doublejump(state)), LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Plasma Crystal', 1337173, lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), - LocationData('Caves of Banishment (Maw)', 'Killed Maw', EventId, lambda state: state.has('Gas Mask', player)), - LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Mineshaft', 1337122, lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), - LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Wyvern room', 1337123), - LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Siren room above water chest', 1337124), - LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Siren room underwater left chest', 1337125, lambda state: state.has('Water Mask', player)), - LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Siren room underwater right chest', 1337126, lambda state: state.has('Water Mask', player)), + LocationData('Caves of Banishment (Maw)', 'Killed Maw', EventId, lambda state: state.has('Gas Mask', player)), + LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Mineshaft', 1337122, lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Wyvern room', 1337123), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Siren room above water chest', 1337124), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Siren room underwater left chest', 1337125, lambda state: state.has('Water Mask', player)), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Siren room underwater right chest', 1337126, lambda state: state.has('Water Mask', player)), LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Siren room underwater right ground', 1337172, lambda state: state.has('Water Mask', player)), - LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Water hook', 1337127, lambda state: state.has('Water Mask', player)), - LocationData('Castle Ramparts', 'Castle Ramparts: Bomber chest', 1337128, logic.has_multiple_small_jumps_of_npc), - LocationData('Castle Ramparts', 'Castle Ramparts: Freeze the engineer', 1337129, lambda state: state.has('Talaria Attachment', player) or logic.has_timestop(state)), - LocationData('Castle Ramparts', 'Castle Ramparts: Giantess guarded room', 1337130), - LocationData('Castle Ramparts', 'Castle Ramparts: Knight and archer guarded room', 1337131), - LocationData('Castle Ramparts', 'Castle Ramparts: Pedestal', 1337132), - LocationData('Castle Basement', 'Castle Basement: Secret pedestal', 1337133, logic.can_break_walls), - LocationData('Castle Basement', 'Castle Basement: Clean the castle basement', 1337134), - LocationData('Royal towers (lower)', 'Castle Keep: Yas queen room', 1337135, logic.has_pink), - LocationData('Castle Basement', 'Castle Basement: Giantess guarded chest', 1337136), - LocationData('Castle Basement', 'Castle Basement: Omelette chest', 1337137), - LocationData('Castle Basement', 'Castle Basement: Just an egg', 1337138), - LocationData('Castle Keep', 'Castle Keep: Under the twins', 1337139), - LocationData('Castle Keep', 'Killed Twins', EventId, logic.has_timestop), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Water hook', 1337127, lambda state: state.has('Water Mask', player)), + LocationData('Castle Ramparts', 'Castle Ramparts: Bomber chest', 1337128, logic.has_multiple_small_jumps_of_npc), + LocationData('Castle Ramparts', 'Castle Ramparts: Freeze the engineer', 1337129, lambda state: state.has('Talaria Attachment', player) or logic.has_timestop(state)), + LocationData('Castle Ramparts', 'Castle Ramparts: Giantess guarded room', 1337130), + LocationData('Castle Ramparts', 'Castle Ramparts: Knight and archer guarded room', 1337131), + LocationData('Castle Ramparts', 'Castle Ramparts: Pedestal', 1337132), + LocationData('Castle Basement', 'Castle Basement: Secret pedestal', 1337133, logic.can_break_walls), + LocationData('Castle Basement', 'Castle Basement: Clean the castle basement', 1337134), + LocationData('Royal towers (lower)', 'Castle Keep: Yas queen room', 1337135, logic.has_pink), + LocationData('Castle Basement', 'Castle Basement: Giantess guarded chest', 1337136), + LocationData('Castle Basement', 'Castle Basement: Omelette chest', 1337137), + LocationData('Castle Basement', 'Castle Basement: Just an egg', 1337138), + LocationData('Castle Keep', 'Castle Keep: Under the twins', 1337139), + LocationData('Castle Keep', 'Killed Twins', EventId, logic.has_timestop), LocationData('Castle Keep', 'Castle Keep: Advisor jump', 1337171, logic.has_timestop), - LocationData('Castle Keep', 'Castle Keep: Twins', 1337140, logic.has_timestop), - LocationData('Castle Keep', 'Castle Keep: Royal guard tiny room', 1337141, lambda state: logic.has_doublejump(state) or logic.has_fastjump_on_npc(state)), - LocationData('Royal towers (lower)', 'Royal Towers: Floor secret', 1337142, lambda state: logic.has_doublejump(state) and logic.can_break_walls(state)), - LocationData('Royal towers', 'Royal Towers: Pre-climb gap', 1337143), - LocationData('Royal towers', 'Royal Towers: Long balcony', 1337144, lambda state: not flooded.flood_courtyard or state.has('Water Mask', player)), - LocationData('Royal towers', 'Royal Towers: Past bottom struggle juggle', 1337145, lambda state: flooded.flood_courtyard or logic.has_doublejump_of_npc(state)), - LocationData('Royal towers', 'Royal Towers: Bottom struggle juggle', 1337146, logic.has_doublejump_of_npc), - LocationData('Royal towers (upper)', 'Royal Towers: Top struggle juggle', 1337147, logic.has_doublejump_of_npc), - LocationData('Royal towers (upper)', 'Royal Towers: No struggle required', 1337148), - LocationData('Royal towers', 'Royal Towers: Right tower freebie', 1337149), - LocationData('Royal towers (upper)', 'Royal Towers: Left tower small balcony', 1337150), - LocationData('Royal towers (upper)', 'Royal Towers: Left tower royal guard', 1337151), - LocationData('Royal towers (upper)', 'Royal Towers: Before Aelana', 1337152), - LocationData('Royal towers (upper)', 'Killed Aelana', EventId), - LocationData('Royal towers (upper)', 'Royal Towers: Aelana\'s attic', 1337153, logic.has_upwarddash), - LocationData('Royal towers (upper)', 'Royal Towers: Aelana\'s chest', 1337154), - LocationData('Royal towers (upper)', 'Royal Towers: Aelana\'s pedestal', 1337155), + LocationData('Castle Keep', 'Castle Keep: Twins', 1337140, logic.has_timestop), + LocationData('Castle Keep', 'Castle Keep: Royal guard tiny room', 1337141, lambda state: logic.has_doublejump(state) or logic.has_fastjump_on_npc(state)), + LocationData('Royal towers (lower)', 'Royal Towers: Floor secret', 1337142, lambda state: logic.has_doublejump(state) and logic.can_break_walls(state)), + LocationData('Royal towers', 'Royal Towers: Pre-climb gap', 1337143), + LocationData('Royal towers', 'Royal Towers: Long balcony', 1337144, lambda state: not flooded.flood_courtyard or state.has('Water Mask', player)), + LocationData('Royal towers', 'Royal Towers: Past bottom struggle juggle', 1337145, lambda state: flooded.flood_courtyard or logic.has_doublejump_of_npc(state)), + LocationData('Royal towers', 'Royal Towers: Bottom struggle juggle', 1337146, logic.has_doublejump_of_npc), + LocationData('Royal towers (upper)', 'Royal Towers: Top struggle juggle', 1337147, logic.has_doublejump_of_npc), + LocationData('Royal towers (upper)', 'Royal Towers: No struggle required', 1337148), + LocationData('Royal towers', 'Royal Towers: Right tower freebie', 1337149), + LocationData('Royal towers (upper)', 'Royal Towers: Left tower small balcony', 1337150), + LocationData('Royal towers (upper)', 'Royal Towers: Left tower royal guard', 1337151), + LocationData('Royal towers (upper)', 'Royal Towers: Before Aelana', 1337152), + LocationData('Royal towers (upper)', 'Killed Aelana', EventId), + LocationData('Royal towers (upper)', 'Royal Towers: Aelana\'s attic', 1337153, logic.has_upwarddash), + LocationData('Royal towers (upper)', 'Royal Towers: Aelana\'s chest', 1337154), + LocationData('Royal towers (upper)', 'Royal Towers: Aelana\'s pedestal', 1337155), # Ancient pyramid locations - LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Why not it\'s right there', 1337246), - LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Conviction guarded room', 1337247), - LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Pit secret room', 1337248, lambda state: logic.can_break_walls(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), - LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Regret chest', 1337249, lambda state: logic.can_break_walls(state) and (state.has('Water Mask', player) if flooded.flood_pyramid_shaft else logic.has_doublejump(state))), - LocationData('Ancient Pyramid (right)', 'Ancient Pyramid: Nightmare Door chest', 1337236, lambda state: not flooded.flood_pyramid_back or state.has('Water Mask', player)), + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Why not it\'s right there', 1337246), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Conviction guarded room', 1337247), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Pit secret room', 1337248, lambda state: logic.can_break_walls(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Regret chest', 1337249, lambda state: logic.can_break_walls(state) and (state.has('Water Mask', player) if flooded.flood_pyramid_shaft else logic.has_doublejump(state))), + LocationData('Ancient Pyramid (right)', 'Ancient Pyramid: Nightmare Door chest', 1337236, lambda state: not flooded.flood_pyramid_back or state.has('Water Mask', player)), LocationData('Ancient Pyramid (right)', 'Killed Nightmare', EventId, lambda state: state.has_all({'Timespinner Wheel', 'Timespinner Spindle', 'Timespinner Gear 1', 'Timespinner Gear 2', 'Timespinner Gear 3'}, player) and (not flooded.flood_pyramid_back or state.has('Water Mask', player))) ] # 1337156 - 1337170 Downloads if not options or options.downloadable_items: location_table += ( - LocationData('Library', 'Library: Terminal 2 (Lachiem)', 1337156, lambda state: state.has('Tablet', player)), - LocationData('Library', 'Library: Terminal 1 (Windaria)', 1337157, lambda state: state.has('Tablet', player)), + LocationData('Library', 'Library: Terminal 2 (Lachiem)', 1337156, lambda state: state.has('Tablet', player)), + LocationData('Library', 'Library: Terminal 1 (Windaria)', 1337157, lambda state: state.has('Tablet', player)), # 1337158 Is lost in time - LocationData('Library', 'Library: Terminal 3 (Emperor Nuvius)', 1337159, lambda state: state.has('Tablet', player)), - LocationData('Library', 'Library: V terminal 1 (War of the Sisters)', 1337160, lambda state: state.has_all({'Tablet', 'Library Keycard V'}, player)), - LocationData('Library', 'Library: V terminal 2 (Lake Desolation Map)', 1337161, lambda state: state.has_all({'Tablet', 'Library Keycard V'}, player)), - LocationData('Library', 'Library: V terminal 3 (Vilete)', 1337162, lambda state: state.has_all({'Tablet', 'Library Keycard V'}, player)), - LocationData('Library top', 'Library: Backer room terminal (Vandagray Metropolis Map)', 1337163, lambda state: state.has('Tablet', player)), - LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Medbay terminal (Bleakness Research)', 1337164, lambda state: state.has('Tablet', player) and logic.has_keycard_B(state)), - LocationData('The lab (upper)', 'Lab: Download and chest room terminal (Experiment #13)', 1337165, lambda state: state.has('Tablet', player)), - LocationData('The lab (power off)', 'Lab: Middle terminal (Amadeus Laboratory Map)', 1337166, lambda state: state.has('Tablet', player) and (not options.lock_key_amadeus or state.has('Lab Access Research', player))), - LocationData('The lab (power off)', 'Lab: Sentry platform terminal (Origins)', 1337167, lambda state: state.has('Tablet', player) and (not options.lock_key_amadeus or state.has('Lab Access Genza', player) or logic.can_teleport_to(state, "Time", "GateDadsTower"))), - LocationData('The lab', 'Lab: Experiment 13 terminal (W.R.E.C Farewell)', 1337168, lambda state: state.has('Tablet', player)), - LocationData('The lab', 'Lab: Left terminal (Biotechnology)', 1337169, lambda state: state.has('Tablet', player)), - LocationData('The lab (power off)', 'Lab: Right terminal (Experiment #11)', 1337170, lambda state: state.has('Tablet', player) and (not options.lock_key_amadeus or state.has('Lab Access Research', player))) + LocationData('Library', 'Library: Terminal 3 (Emperor Nuvius)', 1337159, lambda state: state.has('Tablet', player)), + LocationData('Library', 'Library: V terminal 1 (War of the Sisters)', 1337160, lambda state: state.has_all({'Tablet', 'Library Keycard V'}, player)), + LocationData('Library', 'Library: V terminal 2 (Lake Desolation Map)', 1337161, lambda state: state.has_all({'Tablet', 'Library Keycard V'}, player)), + LocationData('Library', 'Library: V terminal 3 (Vilete)', 1337162, lambda state: state.has_all({'Tablet', 'Library Keycard V'}, player)), + LocationData('Library top', 'Library: Backer room terminal (Vandagray Metropolis Map)', 1337163, lambda state: state.has('Tablet', player)), + LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Medbay terminal (Bleakness Research)', 1337164, lambda state: state.has('Tablet', player) and logic.has_keycard_B(state)), + LocationData('The lab (upper)', 'Lab: Download and chest room terminal (Experiment #13)', 1337165, lambda state: state.has('Tablet', player)), + LocationData('Lab Research', 'Lab: Middle terminal (Amadeus Laboratory Map)', 1337166, lambda state: state.has('Tablet', player)), + LocationData('Main Lab', 'Lab: Sentry platform terminal (Origins)', 1337167, lambda state: state.has('Tablet', player) and (not options.lock_key_amadeus or state.has('Lab Access Genza', player) or logic.can_teleport_to(state, "Time", "GateDadsTower"))), + LocationData('Main Lab', 'Lab: Experiment 13 terminal (W.R.E.C Farewell)', 1337168, lambda state: state.has('Tablet', player)), + LocationData('Main Lab', 'Lab: Left terminal (Biotechnology)', 1337169, lambda state: state.has('Tablet', player)), + LocationData('Lab Research', 'Lab: Right terminal (Experiment #11)', 1337170, lambda state: state.has('Tablet', player)) ) # 1337176 - 1337176 Cantoran if not options or options.cantoran: location_table += ( - LocationData('Left Side forest Caves', 'Lake Serene: Cantoran', 1337176), + LocationData('Left Side forest Caves', 'Lake Serene: Cantoran', 1337176), ) # 1337177 - 1337198 Lore Checks if not options or options.lore_checks: location_table += ( - LocationData('Lower lake desolation', 'Lake Desolation: Memory - Coyote Jump (Time Messenger)', 1337177), - LocationData('Library', 'Library: Memory - Waterway (A Message)', 1337178), - LocationData('Library top', 'Library: Memory - Library Gap (Lachiemi Sun)', 1337179), - LocationData('Library top', 'Library: Memory - Mr. Hat Portrait (Moonlit Night)', 1337180), - LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Memory - Elevator (Nomads)', 1337181, lambda state: state.has('Elevator Keycard', player)), - LocationData('Varndagroth tower right (lower)', 'Varndagroth Towers: Memory - Siren Elevator (Childhood)', 1337182, logic.has_keycard_B), - LocationData('Varndagroth tower right (lower)', 'Varndagroth Towers (Right): Memory - Bottom (Faron)', 1337183), - LocationData('Military Fortress', 'Military Fortress: Memory - Bomber Climb (A Solution)', 1337184, lambda state: state.has('Timespinner Wheel', player) and logic.has_doublejump_of_npc(state)), - LocationData('The lab', 'Lab: Memory - Genza\'s Secret Stash 1 (An Old Friend)', 1337185, logic.can_break_walls), - LocationData('The lab', 'Lab: Memory - Genza\'s Secret Stash 2 (Twilight Dinner)', 1337186, logic.can_break_walls), - LocationData('Emperors tower', 'Emperor\'s Tower: Memory - Way Up There (Final Circle)', 1337187, logic.has_doublejump_of_npc), - LocationData('Forest', 'Forest: Journal - Rats (Lachiem Expedition)', 1337188), - LocationData('Forest', 'Forest: Journal - Bat Jump Ledge (Peace Treaty)', 1337189, lambda state: logic.has_doublejump_of_npc(state) or logic.has_forwarddash_doublejump(state) or logic.has_fastjump_on_npc(state)), - LocationData('Forest', 'Forest: Journal - Floating in Moat (Prime Edicts)', 1337190, lambda state: not flooded.flood_moat or state.has('Water Mask', player)), - LocationData('Castle Ramparts', 'Castle Ramparts: Journal - Archer + Knight (Declaration of Independence)', 1337191), - LocationData('Castle Keep', 'Castle Keep: Journal - Under the Twins (Letter of Reference)', 1337192), - LocationData('Castle Basement', 'Castle Basement: Journal - Castle Loop Giantess (Political Advice)', 1337193), - LocationData('Royal towers (lower)', 'Royal Towers: Journal - Aelana\'s Room (Diplomatic Missive)', 1337194, logic.has_pink), - LocationData('Royal towers (upper)', 'Royal Towers: Journal - Top Struggle Juggle Base (War of the Sisters)', 1337195), - LocationData('Royal towers (upper)', 'Royal Towers: Journal - Aelana Boss (Stained Letter)', 1337196), - LocationData('Royal towers', 'Royal Towers: Journal - Near Bottom Struggle Juggle (Mission Findings)', 1337197, lambda state: flooded.flood_courtyard or logic.has_doublejump_of_npc(state)), - LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Journal - Lower Left Caves (Naivety)', 1337198) + LocationData('Lower lake desolation', 'Lake Desolation: Memory - Coyote Jump (Time Messenger)', 1337177), + LocationData('Library', 'Library: Memory - Waterway (A Message)', 1337178), + LocationData('Library top', 'Library: Memory - Library Gap (Lachiemi Sun)', 1337179), + LocationData('Library top', 'Library: Memory - Mr. Hat Portrait (Moonlit Night)', 1337180), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Memory - Elevator (Nomads)', 1337181, lambda state: state.has('Elevator Keycard', player)), + LocationData('Varndagroth tower right (lower)', 'Varndagroth Towers: Memory - Siren Elevator (Childhood)', 1337182, logic.has_keycard_B), + LocationData('Varndagroth tower right (lower)', 'Varndagroth Towers (Right): Memory - Bottom (Faron)', 1337183), + LocationData('Military Fortress', 'Military Fortress: Memory - Bomber Climb (A Solution)', 1337184, lambda state: state.has('Timespinner Wheel', player) and logic.has_doublejump_of_npc(state)), + LocationData('Main Lab', 'Lab: Memory - Genza\'s Secret Stash 1 (An Old Friend)', 1337185, logic.can_break_walls), + LocationData('Main Lab', 'Lab: Memory - Genza\'s Secret Stash 2 (Twilight Dinner)', 1337186, logic.can_break_walls), + LocationData('Emperors tower', 'Emperor\'s Tower: Memory - Way Up There (Final Circle)', 1337187, logic.has_doublejump_of_npc), + LocationData('Forest', 'Forest: Journal - Rats (Lachiem Expedition)', 1337188), + LocationData('Forest', 'Forest: Journal - Bat Jump Ledge (Peace Treaty)', 1337189, lambda state: logic.has_doublejump_of_npc(state) or logic.has_forwarddash_doublejump(state) or logic.has_fastjump_on_npc(state)), + LocationData('Forest', 'Forest: Journal - Floating in Moat (Prime Edicts)', 1337190, lambda state: not flooded.flood_moat or state.has('Water Mask', player)), + LocationData('Castle Ramparts', 'Castle Ramparts: Journal - Archer + Knight (Declaration of Independence)', 1337191), + LocationData('Castle Keep', 'Castle Keep: Journal - Under the Twins (Letter of Reference)', 1337192), + LocationData('Castle Basement', 'Castle Basement: Journal - Castle Loop Giantess (Political Advice)', 1337193), + LocationData('Royal towers (lower)', 'Royal Towers: Journal - Aelana\'s Room (Diplomatic Missive)', 1337194, logic.has_pink), + LocationData('Royal towers (upper)', 'Royal Towers: Journal - Top Struggle Juggle Base (War of the Sisters)', 1337195), + LocationData('Royal towers (upper)', 'Royal Towers: Journal - Aelana Boss (Stained Letter)', 1337196), + LocationData('Royal towers', 'Royal Towers: Journal - Near Bottom Struggle Juggle (Mission Findings)', 1337197, lambda state: flooded.flood_courtyard or logic.has_doublejump_of_npc(state)), + LocationData('Caves of Banishment (Maw)', 'Caves of Banishment (Maw): Journal - Lower Left Caves (Naivety)', 1337198) ) # 1337199 - 1337232 Reserved for future use @@ -259,9 +261,9 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio # 1337233 - 1337235 Pyramid Start checks if not options or options.pyramid_start: location_table += ( - LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Training Dummy', 1337233), - LocationData('Ancient Pyramid (entrance)', 'Temporal Gyre: Forest Entrance', 1337234, lambda state: logic.has_upwarddash(state) or logic.can_teleport_to(state, "Time", "GateGyre")), - LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Rubble', 1337235), + LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Training Dummy', 1337233), + LocationData('Ancient Pyramid (entrance)', 'Temporal Gyre: Forest Entrance', 1337234, lambda state: logic.has_upwarddash(state) or logic.can_teleport_to(state, "Time", "GateGyre")), + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Rubble', 1337235), ) # 1337236 Nightmare door @@ -269,15 +271,581 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio # 1337237 - 1337245 GyreArchives if not options or options.gyre_archives: location_table += ( - LocationData('Ravenlord\'s Lair', 'Ravenlord: Post fight (pedestal)', 1337237), - LocationData('Ifrit\'s Lair', 'Ifrit: Post fight (pedestal)', 1337238), - LocationData('Temporal Gyre', 'Temporal Gyre: Chest 1', 1337239), - LocationData('Temporal Gyre', 'Temporal Gyre: Chest 2', 1337240), - LocationData('Temporal Gyre', 'Temporal Gyre: Chest 3', 1337241), - LocationData('Ravenlord\'s Lair', 'Ravenlord: Pre fight', 1337242), - LocationData('Ravenlord\'s Lair', 'Ravenlord: Post fight (chest)', 1337243), - LocationData('Ifrit\'s Lair', 'Ifrit: Pre fight', 1337244), + LocationData('Ravenlord\'s Lair', 'Ravenlord: Post fight (pedestal)', 1337237), + LocationData('Ifrit\'s Lair', 'Ifrit: Post fight (pedestal)', 1337238), + LocationData('Temporal Gyre', 'Temporal Gyre: Chest 1', 1337239), + LocationData('Temporal Gyre', 'Temporal Gyre: Chest 2', 1337240), + LocationData('Temporal Gyre', 'Temporal Gyre: Chest 3', 1337241), + LocationData('Ravenlord\'s Lair', 'Ravenlord: Pre fight', 1337242), + LocationData('Ravenlord\'s Lair', 'Ravenlord: Post fight (chest)', 1337243), + LocationData('Ifrit\'s Lair', 'Ifrit: Pre fight', 1337244), LocationData('Ifrit\'s Lair', 'Ifrit: Post fight (chest)', 1337245), ) + + # 1337250 - 1337781 Torch checks + if not options or options.pure_torcher: + location_table += ( + LocationData('Lower lake desolation', 'Lake Desolation (Lower): Not So Secret Lantern', 1337250, lambda state: logic.can_break_walls(state) and logic.can_break_lanterns(state)), + LocationData('Lower lake desolation', 'Lake Desolation (Lower): Middle Room Lantern 1', 1337256, logic.can_break_lanterns), + LocationData('Lower lake desolation', 'Lake Desolation (Lower): Middle Room Lantern 2', 1337257, logic.can_break_lanterns), + LocationData('Lower lake desolation', 'Lake Desolation (Lower): Timespinner Wheel Lantern 1', 1337258, logic.can_break_lanterns), + LocationData('Lower lake desolation', 'Lake Desolation (Lower): Timespinner Wheel Lantern 2', 1337259, logic.can_break_lanterns), + + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Upper Left Room Lantern 1', 1337251, logic.can_break_lanterns), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Upper Left Room Lantern 2', 1337252, logic.can_break_lanterns), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Oxygen Recovery Lantern', 1337253, logic.can_break_lanterns), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Upper Right Room Lantern 1', 1337254, logic.can_break_lanterns), + LocationData('Upper lake desolation', 'Lake Desolation (Upper): Double jump Cave Lantern', 1337255, logic.can_break_lanterns), + + LocationData('Eastern lake desolation', 'Lake Desolation: Metropolis Bridge Lantern 1', 1337773, logic.can_break_lanterns), + LocationData('Eastern lake desolation', 'Lake Desolation: Metropolis Bridge Lantern 2', 1337774, logic.can_break_lanterns), + LocationData('Eastern lake desolation', 'Lake Desolation: Metropolis Bridge Lantern 3', 1337775, logic.can_break_lanterns), + LocationData('Eastern lake desolation', 'Lake Desolation: Metropolis Bridge Lantern 4', 1337776, logic.can_break_lanterns), + LocationData('Eastern lake desolation', 'Lake Desolation: Metropolis Bridge Lantern 5', 1337777, logic.can_break_lanterns), + LocationData('Eastern lake desolation', 'Lake Desolation: Metropolis Bridge Lantern 6', 1337778, logic.can_break_lanterns), + LocationData('Eastern lake desolation', 'Lake Desolation: Metropolis Bridge Lantern 7', 1337779, logic.can_break_lanterns), + + LocationData('Library', 'Library: Sewer Entrance Lantern', 1337489, logic.can_break_lanterns), + LocationData('Library', 'Library: Left Sewer Lantern 1', 1337422, logic.can_break_lanterns), + LocationData('Library', 'Library: Left Sewer Lantern 2', 1337423, logic.can_break_lanterns), + LocationData('Library', 'Library: Right Sewer Lantern 1', 1337424, logic.can_break_lanterns), + LocationData('Library', 'Library: Right Sewer Lantern 2', 1337425, logic.can_break_lanterns), + LocationData('Library', 'Library: Right Sewer Lantern 3', 1337426, logic.can_break_lanterns), + LocationData('Library', 'Library: Right Sewer Lantern 4', 1337427, logic.can_break_lanterns), + LocationData('Library', 'Library: Right Sewer Lantern 5', 1337428, logic.can_break_lanterns), + LocationData('Library', 'Library: Right Sewer Lantern 6', 1337429, logic.can_break_lanterns), + LocationData('Library', 'Library: Sewer Exit Lantern 1', 1337492, logic.can_break_lanterns), + LocationData('Library', 'Library: Sewer Exit Lantern 2', 1337493, logic.can_break_lanterns), + LocationData('Library', 'Library: Basement Lantern', 1337494, logic.can_break_lanterns), + LocationData('Library', 'Library: Exit Lantern', 1337450, logic.can_break_lanterns), + LocationData('Library', 'Library: Librarian Lantern 1', 1337463, logic.can_break_lanterns), + LocationData('Library', 'Library: Librarian Lantern 2', 1337464, logic.can_break_lanterns), + LocationData('Library', 'Library: Left Staircase Lantern 1', 1337465, logic.can_break_lanterns), + LocationData('Library', 'Library: Left Staircase Lantern 2', 1337466, logic.can_break_lanterns), + LocationData('Library', 'Library: Left Staircase Lantern 3', 1337467, logic.can_break_lanterns), + LocationData('Library', 'Library: Left Staircase Lantern 4', 1337468, logic.can_break_lanterns), + LocationData('Library', 'Library: Lantern 1', 1337471, logic.can_break_lanterns), + LocationData('Library', 'Library: Lantern 2', 1337472, logic.can_break_lanterns), + LocationData('Library', 'Library: Lantern 3', 1337473, logic.can_break_lanterns), + LocationData('Library', 'Library: Lantern 4', 1337474, logic.can_break_lanterns), + LocationData('Library', 'Library: Lantern 5', 1337475, logic.can_break_lanterns), + LocationData('Library', 'Library: Lantern 6', 1337476, logic.can_break_lanterns), + LocationData('Library', 'Library: Lantern 7', 1337477, logic.can_break_lanterns), + LocationData('Library', 'Library: Storage Room Lantern 1', 1337478, lambda state: logic.has_keycard_D(state) and logic.can_break_lanterns(state)), + LocationData('Library', 'Library: Storage Room Lantern 2', 1337479, lambda state: logic.has_keycard_D(state) and logic.can_break_lanterns(state)), + LocationData('Library', 'Library: Waterway Lantern 1', 1337480, logic.can_break_lanterns), + LocationData('Library', 'Library: Waterway Lantern 2', 1337481, logic.can_break_lanterns), + LocationData('Library', 'Library: V Room Lantern 1', 1337490, lambda state: state.has('Library Keycard V', player) and logic.can_break_lanterns(state)), + LocationData('Library', 'Library: V Room Lantern 2', 1337491, lambda state: state.has('Library Keycard V', player) and logic.can_break_lanterns(state)), + + LocationData('Library top', 'Library: Backer Room Lantern 1', 1337484, logic.can_break_lanterns), + LocationData('Library top', 'Library: Backer Room Lantern 2', 1337485, logic.can_break_lanterns), + LocationData('Library top', 'Library: Backer Room Lantern 3', 1337486, logic.can_break_lanterns), + LocationData('Library top', 'Library: Backer Room Lantern 4', 1337487, logic.can_break_lanterns), + LocationData('Library top', 'Library: Backer Room Lantern 5', 1337488, logic.can_break_lanterns), + LocationData('Library top', 'Library: Backer Stairs Lantern 1', 1337459, logic.can_break_lanterns), + LocationData('Library top', 'Library: Backer Stairs Lantern 2', 1337460, logic.can_break_lanterns), + LocationData('Library top', 'Library: Backer Stairs Lantern 3', 1337461, logic.can_break_lanterns), + LocationData('Library top', 'Library: Backer Stairs Lantern 4', 1337462, logic.can_break_lanterns), + LocationData('Library top', 'Library: Mr. Hat Lantern 1', 1337482, logic.can_break_lanterns), + LocationData('Library top', 'Library: Mr. Hat Lantern 2', 1337483, logic.can_break_lanterns), + + LocationData('Varndagroth tower left', 'Library: Moving Sidewalk Lantern 1', 1337430, logic.can_break_lanterns), + LocationData('Varndagroth tower left', 'Library: Moving Sidewalk Lantern 2', 1337431, logic.can_break_lanterns), + + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Entrance Lantern', 1337434, logic.can_break_lanterns), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Bottom Floor Lantern', 1337451, lambda state: logic.has_keycard_C(state) and logic.can_break_lanterns(state)), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Left Elevator Lantern 1', 1337452, lambda state: state.has('Elevator Keycard', player) and logic.can_break_lanterns(state)), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Left Elevator Lantern 2', 1337453, logic.can_break_lanterns), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Left Stairs Base Lantern 1', 1337469, logic.can_break_lanterns), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Left Stairs Base Lantern 2', 1337470, logic.can_break_lanterns), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Left Stairs Floor 2 Lantern 1', 1337432, logic.can_break_lanterns), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Left Stairs Floor 2 Lantern 2', 1337433, logic.can_break_lanterns), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Left Stairs Middle Lantern', 1337454, logic.can_break_lanterns), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Left Stairs Ladder Lantern 1', 1337455, logic.can_break_lanterns), + LocationData('Varndagroth tower left', 'Varndagroth Towers (Left): Left Stairs Ladder Lantern 2', 1337456, logic.can_break_lanterns), + + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers: Bridge Entrance Lantern 1', 1337457, logic.can_break_lanterns), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers: Bridge Entrance Lantern 2', 1337458, logic.can_break_lanterns), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Bridge Exit Lantern 1', 1337437, logic.can_break_lanterns), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Bridge Exit Lantern 2', 1337438, logic.can_break_lanterns), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Above Vents Lantern 1', 1337448, lambda state: (state.has('Elevator Keycard', player) or logic.has_doublejump(state)) and logic.can_break_lanterns(state)), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Above Vents Lantern 2', 1337449, lambda state: (state.has('Elevator Keycard', player) or logic.has_doublejump(state)) and logic.can_break_lanterns(state)), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Vent Lantern 1', 1337445, lambda state: (state.has('Elevator Keycard', player) or logic.has_doublejump(state)) and logic.can_break_lanterns(state)), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Vent Lantern 2', 1337446, lambda state: (state.has('Elevator Keycard', player) or logic.has_doublejump(state)) and logic.can_break_lanterns(state)), + LocationData('Varndagroth tower right (upper)', 'Varndagroth Towers (Right): Vent Lantern 3', 1337447, lambda state: (state.has('Elevator Keycard', player) or logic.has_doublejump(state)) and logic.can_break_lanterns(state)), + + LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Right Elevator Lantern 1', 1337439, logic.can_break_lanterns), + LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Right Elevator Lantern 2', 1337440, logic.can_break_lanterns), + LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Right Elevator Lantern 3', 1337441, logic.can_break_lanterns), + LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Right Elevator Lantern 4', 1337442, logic.can_break_lanterns), + LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Right Elevator Lantern 5', 1337443, logic.can_break_lanterns), + LocationData('Varndagroth tower right (elevator)', 'Varndagroth Towers (Right): Right Elevator Lantern 6', 1337444, logic.can_break_lanterns), + + LocationData('Varndagroth tower right (lower)', 'Varndagroth Towers (Right): Right Stairs Lantern 1', 1337435, logic.can_break_lanterns), + LocationData('Varndagroth tower right (lower)', 'Varndagroth Towers (Right): Right Stairs Lantern 2', 1337436, logic.can_break_lanterns), + LocationData('Varndagroth tower right (lower)', 'Varndagroth Towers (Right): Base Lantern 1', 1337495, logic.can_break_lanterns), + LocationData('Varndagroth tower right (lower)', 'Varndagroth Towers (Right): Base Lantern 2', 1337496, logic.can_break_lanterns), + + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Middle Hall Lantern 1', 1337721, logic.can_break_lanterns), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Middle Hall Lantern 2', 1337722, logic.can_break_lanterns), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Middle Hall Lantern 3', 1337723, logic.can_break_lanterns), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Middle Hall Lantern 4', 1337724, logic.can_break_lanterns), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): First Hall Lantern 1', 1337741, logic.can_break_lanterns), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): First Hall Lantern 2', 1337742, logic.can_break_lanterns), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): First Hall Lantern ', 1337743, logic.can_break_lanterns), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Condemned Shaft Lantern 1', 1337744, logic.can_break_lanterns), + LocationData('Sealed Caves (Sirens)', 'Sealed Caves (Sirens): Condemned Shaft Lantern 2', 1337745, logic.can_break_lanterns), + + LocationData('Skeleton Shaft', 'Sealed Caves (Xarion): Skeleton Lantern 1', 1337718, logic.can_break_lanterns), + LocationData('Skeleton Shaft', 'Sealed Caves (Xarion): Skeleton Lantern 2', 1337719, logic.can_break_lanterns), + LocationData('Skeleton Shaft', 'Sealed Caves (Xarion): Skeleton Lantern 3', 1337720, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): First Hall Lantern 1', 1337712, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): First Hall Lantern 2', 1337713, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): First Hall Lantern 3', 1337714, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): First Hall Lantern 4', 1337715, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): First Hall Lantern 5', 1337716, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): First Hall Lantern 6', 1337717, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Second Hall Lantern 1', 1337746, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Second Hall Lantern 2', 1337747, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Second Hall Lantern 3', 1337748, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Second Hall Lantern 4', 1337749, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Forked Shaft Lantern 1', 1337750, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Forked Shaft Lantern 2', 1337751, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Forked Shaft Lantern 3', 1337752, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Forked Shaft Lantern 4', 1337753, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Forked Shaft Lantern 5', 1337754, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Shroom Jump Lantern 1', 1337738, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Shroom Jump Lantern 2', 1337739, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Shroom Jump Lantern 3', 1337740, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Shroom Jump Lantern 4', 1337781, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Lower Fork Start Lantern 1', 1337761, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Lower Fork Start Lantern 2', 1337762, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Lower Fork Vertical Room Lantern 1', 1337769, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Lower Fork Vertical Room Lantern 2', 1337770, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Lower Fork Vertical Room Lantern 3', 1337771, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Lower Fork Vertical Room Lantern 4', 1337772, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Mini Jackpot Ledge Lantern', 1337733, lambda state: logic.has_forwarddash_doublejump(state) and logic.can_break_lanterns(state)), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Waterfall Lantern 1', 1337731, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Waterfall Lantern 2', 1337732, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Waterfall Lantern 3', 1337734, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Waterfall Lantern 4', 1337735, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Waterfall Lantern 5', 1337736, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Post-Fork Room Lantern 1', 1337763, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Post-Fork Room Lantern 2', 1337764, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Rejoined Hallway Lantern 1', 1337755, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Rejoined Hallway Lantern 2', 1337756, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Rejoined Hallway Lantern 3', 1337757, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Rejoined Hallway Lantern 4', 1337758, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Rejoined Hallway Lantern 5', 1337759, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Rejoined Hallway Lantern 6', 1337760, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Penultimate Hall Lantern 1', 1337725, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Penultimate Hall Lantern 2', 1337726, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Penultimate Hall Lantern 3', 1337727, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Penultimate Hall Lantern 4', 1337728, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Penultimate Hall Lantern 5', 1337729, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Penultimate Hall Lantern 6', 1337730, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Last Chance Room Lantern 1', 1337765, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Last Chance Room Lantern 2', 1337766, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Last Chance Room Lantern 3', 1337767, logic.can_break_lanterns), + LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Last Chance Room Lantern 4', 1337768, lambda state: logic.has_doublejump(state) and logic.can_break_lanterns(state)), + + LocationData('Forest', 'Forest: Rats Lantern', 1337498, logic.can_break_lanterns), + LocationData('Forest', 'Forest: Ramparts Bridge Lantern 1', 1337499, logic.can_break_lanterns), + LocationData('Forest', 'Forest: Ramparts Bridge Lantern 2', 1337500, logic.can_break_lanterns), + LocationData('Forest', 'Forest: Ramparts Bridge Lantern 3', 1337501, logic.can_break_lanterns), + LocationData('Forest', 'Forest: Batcave Lantern', 1337502, logic.can_break_lanterns), + LocationData('Forest', 'Forest: Lantern Before Broken Bridge', 1337503, logic.can_break_lanterns), + LocationData('Left Side forest Caves', 'Forest: Lantern Past Signpost', 1337497, logic.can_break_lanterns), + LocationData('Left Side forest Caves', 'Forest: Lantern After Broken Bridge', 1337504, logic.can_break_lanterns), + LocationData('Left Side forest Caves', 'Forest: Left Caves Lantern', 1337505, logic.can_break_lanterns), + + LocationData('Castle Ramparts', 'Castle Ramparts: Giantess Lantern 1', 1337507, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Giantess Lantern 2', 1337508, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Archer + Knight Lantern 1', 1337509, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Archer + Knight Lantern 2', 1337510, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Pedestal Lantern', 1337513, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Big Boulder Room Lantern 1', 1337514, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Big Boulder Room Lantern 2', 1337515, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Left Rooftops Lantern 1', 1337516, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Left Rooftops Lantern 2', 1337517, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Left Rooftops Lantern 3', 1337518, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Middle Hammer Lantern 1', 1337519, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Middle Hammer Lantern 2', 1337520, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Middle Hammer Lantern 3', 1337521, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Exit Lantern 1', 1337522, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Exit Lantern 2', 1337523, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Exit Lantern 3', 1337524, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Exit Lantern 4', 1337525, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Pedestal Stairs Lantern 1', 1337526, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Pedestal Stairs Lantern 2', 1337527, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Pedestal Stairs Lantern 3', 1337528, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Right Rooftops Lantern 1', 1337529, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Right Rooftops Lantern 2', 1337530, logic.can_break_lanterns), + LocationData('Castle Ramparts', 'Castle Ramparts: Right Rooftops Lantern 3', 1337531, logic.can_break_lanterns), + + LocationData('Castle Basement', 'Castle Basement: Entrance Lantern 1', 1337536, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Entrance Lantern 2', 1337537, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Entrance Lantern 3', 1337538, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Exit Lantern 1', 1337539, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Exit Lantern 2', 1337540, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Exit Climb Lantern 1', 1337541, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Exit Climb Lantern 2', 1337542, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: First Bird Hall Lantern 1', 1337543, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: First Bird Hall Lantern 2', 1337544, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Single Bird Lantern 1', 1337567, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Single Bird Lantern 2', 1337568, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Second Bird Hall Lantern 1', 1337569, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Second Bird Hall Lantern 2', 1337570, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Center Shaft Lantern 1', 1337579, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Center Shaft Lantern 2', 1337580, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Giantess Lantern 1', 1337581, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Giantess Lantern 2', 1337582, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Foyer Low Left Lantern', 1337563, logic.can_break_lanterns), + LocationData('Castle Basement', 'Castle Basement: Foyer Low Right Lantern', 1337560, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Foyer Mid Left Lantern', 1337562, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Foyer Mid Right Lantern', 1337561, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Foyer High Left Lantern', 1337564, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Foyer High Right Lantern', 1337565, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Beginning Lantern 1', 1337532, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Beginning Lantern 2', 1337533, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Beginning Lantern 3', 1337534, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Beginning Lantern 4', 1337535, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Far-Left Climb Double-Jump Lantern', 1337545, lambda state: logic.has_doublejump(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Far-Left Climb Lower Lantern 1', 1337546, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Far-Left Climb Lower Lantern 2', 1337547, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Under The Twins Hallway Lantern 1', 1337548, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Under The Twins Hallway Lantern 2', 1337549, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Under The Twins Hallway Lantern 3', 1337550, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Under The Twins Hallway Lantern 4', 1337551, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Right-Middle Hallway Lantern 1', 1337552, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Right-Middle Hallway Lantern 2', 1337553, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Right-Middle Hallway Lantern 3', 1337554, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Right-Middle Hallway Lantern 4', 1337555, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Tiny Royal Guard Room Lantern 1', 1337556, lambda state: logic.can_break_lanterns(state) and (logic.has_doublejump(state) or logic.has_fastjump_on_npc(state))), + LocationData('Castle Keep', 'Castle Keep: Tiny Royal Guard Room Lantern 2', 1337557, lambda state: logic.can_break_lanterns(state) and (logic.has_doublejump(state) or logic.has_fastjump_on_npc(state))), + LocationData('Castle Keep', 'Castle Keep: Royal Tower Entrance Lantern 1', 1337558, lambda state: logic.has_doublejump(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Royal Tower Entrance Lantern 2', 1337559, lambda state: logic.has_doublejump(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Below Royal Room Lantern', 1337566, lambda state: logic.has_doublejump(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Outside Aelana\'s Room Lantern 1', 1337571, lambda state: logic.has_doublejump(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Outside Aelana\'s Room Lantern 2', 1337572, lambda state: logic.has_doublejump(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Outside Aelana\'s Room Lantern 3', 1337573, lambda state: logic.has_doublejump(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Outside Aelana\'s Room Lantern 4', 1337574, lambda state: logic.has_doublejump(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Twins Door Lantern 1', 1337575, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Twins Door Lantern 2', 1337576, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Under The Twins Lantern 1', 1337577, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Under The Twins Lantern 2', 1337578, logic.can_break_lanterns), + LocationData('Castle Keep', 'Castle Keep: Twins Approach Lantern 1', 1337583, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Twins Approach Lantern 2', 1337584, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Twins Approach Lantern 3', 1337585, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Twins Stairwell Lantern 1', 1337586, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + LocationData('Castle Keep', 'Castle Keep: Twins Stairwell Lantern 2', 1337587, lambda state: logic.has_timestop(state) and logic.can_break_lanterns(state)), + + LocationData('Royal towers', 'Royal Towers: Long Balcony Lantern 1', 1337588, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_courtyard or state.has('Water Mask', player))), + LocationData('Royal towers', 'Royal Towers: Long Balcony Lantern 2', 1337589, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_courtyard or state.has('Water Mask', player))), + LocationData('Royal towers', 'Royal Towers: Long Balcony Lantern 3', 1337590, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_courtyard or state.has('Water Mask', player))), + LocationData('Royal towers', 'Royal Towers: Long Balcony Lantern 4', 1337591, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_courtyard or state.has('Water Mask', player))), + LocationData('Royal towers', 'Royal Towers: Long Balcony Lantern 5', 1337592, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_courtyard or state.has('Water Mask', player))), + LocationData('Royal towers', 'Royal Towers: Bottom Struggle Base Lantern 1', 1337593, lambda state: logic.can_break_lanterns(state) and (flooded.flood_courtyard or logic.has_doublejump_of_npc(state))), + LocationData('Royal towers', 'Royal Towers: Bottom Struggle Base Lantern 2', 1337594, lambda state: logic.can_break_lanterns(state) and (flooded.flood_courtyard or logic.has_doublejump_of_npc(state))), + LocationData('Royal towers', 'Royal Towers: Before Bottom Struggle Lantern 1', 1337605, lambda state: logic.can_break_lanterns(state) and (flooded.flood_courtyard or logic.has_doublejump_of_npc(state))), + LocationData('Royal towers', 'Royal Towers: Before Bottom Struggle Lantern 2', 1337606, lambda state: logic.can_break_lanterns(state) and (flooded.flood_courtyard or logic.has_doublejump_of_npc(state))), + LocationData('Royal towers', 'Royal Towers: Past Bottom Struggle Lantern 1', 1337607, lambda state: logic.can_break_lanterns(state) and (flooded.flood_courtyard or logic.has_doublejump_of_npc(state))), + LocationData('Royal towers', 'Royal Towers: Past Bottom Struggle Lantern 2', 1337608, lambda state: logic.can_break_lanterns(state) and (flooded.flood_courtyard or logic.has_doublejump_of_npc(state))), + LocationData('Royal towers (upper)', 'Royal Towers: Aelana\'s Attic Lantern 1', 1337780, lambda state: logic.has_upwarddash(state) and logic.can_break_lanterns(state)), + LocationData('Royal towers (upper)', 'Royal Towers: Aelana\'s Attic Lantern 2', 1337511, lambda state: logic.has_upwarddash(state) and logic.can_break_lanterns(state)), + LocationData('Royal towers (upper)', 'Royal Towers: Aelana\'s Attic Lantern 3', 1337512, lambda state: logic.has_upwarddash(state) and logic.can_break_lanterns(state)), + LocationData('Royal towers (upper)', 'Royal Towers: Before Aelana Lantern 1', 1337595, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Tower Base Entrance Lantern 1', 1337596, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Tower Base Entrance Lantern 2', 1337597, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Tower Base Entrance Lantern 3', 1337598, logic.can_break_lanterns), + LocationData('Royal towers', 'Royal Towers: Lantern Above Time-Stop Demon', 1337599, logic.can_break_lanterns), + LocationData('Royal towers (lower)', 'Royal Towers: Lantern Below Time-Stop Demon', 1337600, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Left Tower Base Lantern 1', 1337601, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Left Tower Base Lantern 2', 1337602, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Left Royal Guard Lantern 1', 1337603, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Left Royal Guard Lantern 2', 1337604, logic.can_break_lanterns), + LocationData('Royal towers', 'Royal Towers: Pre-Climb Lantern 1', 1337609, logic.can_break_lanterns), + LocationData('Royal towers', 'Royal Towers: Pre-Climb Lantern 2', 1337610, logic.can_break_lanterns), + LocationData('Royal towers', 'Royal Towers: Bottom Struggle Lantern', 1337611, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Final Climb Lantern 1', 1337612, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Final Climb Lantern 2', 1337613, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Right Tower Base Lantern 1', 1337614, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Right Tower Base Lantern 2', 1337615, logic.can_break_lanterns), + LocationData('Royal towers (upper)', 'Royal Towers: Right Tower Base Lantern 3', 1337616, logic.can_break_lanterns), + + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): First Hall Lantern 1', 1337674, logic.can_break_lanterns), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): First Hall Lantern 2', 1337675, logic.can_break_lanterns), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): First Hall Lantern 3', 1337676, logic.can_break_lanterns), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Second Hall Lantern 1', 1337700, logic.can_break_lanterns), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Second Hall Lantern 2', 1337701, logic.can_break_lanterns), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Second Hall Lantern 3', 1337702, logic.can_break_lanterns), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Second Hall Lantern 4', 1337703, logic.can_break_lanterns), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Middle Hall Lantern 1', 1337654, logic.can_break_lanterns), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Middle Hall Lantern 2', 1337655, logic.can_break_lanterns), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Middle Hall Lantern 3', 1337656, logic.can_break_lanterns), + LocationData('Caves of Banishment (Sirens)', 'Caves of Banishment (Sirens): Middle Hall Lantern 4', 1337657, logic.can_break_lanterns), + + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Not Dead Yet Lantern 1', 1337650, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Not Dead Yet Lantern 2', 1337651, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Not Dead Yet Lantern 3', 1337652, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Not Dead Yet Lantern 4', 1337653, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): First Hall Lantern 1', 1337643, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): First Hall Lantern 2', 1337644, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): First Hall Lantern 3', 1337645, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): First Hall Lantern 4', 1337646, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): First Hall Lantern 5', 1337647, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): First Hall Lantern 6', 1337648, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Second Hall Lantern 1', 1337682, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Second Hall Lantern 2', 1337683, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Second Hall Lantern 3', 1337684, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Second Hall Lantern 4', 1337685, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Shroom Jump Lantern 1', 1337670, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Shroom Jump Lantern 2', 1337671, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Shroom Jump Lantern 3', 1337672, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Shroom Jump Lantern 4', 1337673, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Forked Shaft Lantern 1', 1337686, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Forked Shaft Lantern 2', 1337687, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Forked Shaft Lantern 3', 1337688, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Forked Shaft Lantern 4', 1337689, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Forked Shaft Lantern 5', 1337690, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Lower Fork Vertical Room Lantern 1', 1337708, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Lower Fork Vertical Room Lantern 2', 1337709, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Lower Fork Vertical Room Lantern 3', 1337710, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Lower Fork Vertical Room Lantern 4', 1337711, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Penultimate Hall Lantern 1', 1337658, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Penultimate Hall Lantern 2', 1337659, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Penultimate Hall Lantern 3', 1337660, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Penultimate Hall Lantern 4', 1337661, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Penultimate Hall Lantern 5', 1337662, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Penultimate Hall Lantern 6', 1337663, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Jackpot Ledge Lantern', 1337666, lambda state: logic.has_forwarddash_doublejump(state) and logic.can_break_lanterns(state)), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Waterfall Lantern 1', 1337664, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Waterfall Lantern 2', 1337665, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Waterfall Lantern 3', 1337667, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Waterfall Lantern 4', 1337668, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Waterfall Lantern 5', 1337669, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Rejoined Hallway Lantern 1', 1337691, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Rejoined Hallway Lantern 2', 1337692, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Rejoined Hallway Lantern 3', 1337693, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Rejoined Hallway Lantern 4', 1337694, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Rejoined Hallway Lantern 5', 1337695, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Rejoined Hallway Lantern 6', 1337737, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Lower Fork Start Lantern 1', 1337696, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Lower Fork Start Lantern 2', 1337697, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Post-Fork Room Lantern 1', 1337698, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Post-Fork Room Lantern 2', 1337699, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Last Chance Lantern 1', 1337704, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Last Chance Lantern 2', 1337705, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Last Chance Lantern 3', 1337706, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Last Chance Lantern 4', 1337707, logic.can_break_lanterns), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Mineshaft Lantern 1', 1337677, lambda state: logic.can_break_lanterns(state) and state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Mineshaft Lantern 2', 1337678, lambda state: logic.can_break_lanterns(state) and state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Mineshaft Lantern 3', 1337679, lambda state: logic.can_break_lanterns(state) and state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Mineshaft Lantern 4', 1337680, lambda state: logic.can_break_lanterns(state) and state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), + LocationData('Caves of Banishment (Flooded)', 'Caves of Banishment (Maw): Mineshaft Lantern 5', 1337681, lambda state: logic.can_break_lanterns(state) and state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), + + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Intro Room Lantern', 1337617, logic.can_break_lanterns), + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Middle Cave Lantern', 1337621, logic.can_break_lanterns), + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Uncrashed Site Lantern 1', 1337622, logic.can_break_lanterns), + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Uncrashed Site Lantern 2', 1337623, logic.can_break_lanterns), + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Uncrashed Site Lantern 3', 1337624, logic.can_break_lanterns), + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Uncrashed Site Lantern 4', 1337625, logic.can_break_lanterns), + LocationData('Upper Lake Serene', 'Lake Serene (Upper): Past First Vine Lantern', 1337626, logic.can_break_lanterns), + LocationData('Left Side forest Caves', 'Lake Serene (Upper): Past Cantoran Lantern', 1337634, logic.can_break_lanterns), + LocationData('Left Side forest Caves', 'Lake Serene (Upper): Fork Dry Lantern', 1337631, logic.can_break_lanterns), + LocationData('Left Side forest Caves', 'Lake Serene (Upper): Fork Wet Lantern 1', 1337632, lambda state: logic.can_break_lanterns(state) and state.has('Water Mask', player)), + LocationData('Left Side forest Caves', 'Lake Serene (Upper): Fork Wet Lantern 2', 1337633, lambda state: logic.can_break_lanterns(state) and state.has('Water Mask', player)), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Above The Eels Lantern 1', 1337638, logic.can_break_lanterns), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Above The Eels Lantern 2', 1337639, logic.can_break_lanterns), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Under The Eels Lantern 1', 1337640, lambda state: logic.can_break_lanterns(state) and state.has('Water Mask', player)), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Under The Eels Lantern 2', 1337641, lambda state: logic.can_break_lanterns(state) and state.has('Water Mask', player)), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Under The Eels Lantern 3', 1337642, lambda state: logic.can_break_lanterns(state) and state.has('Water Mask', player)), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Under The Eels Lantern 4', 1337649, lambda state: logic.can_break_lanterns(state) and state.has('Water Mask', player)), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Past the Eels Lantern', 1337630, lambda state: logic.can_break_lanterns(state) and state.has('Water Mask', player)), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater Secret Lantern 1', 1337618, lambda state: logic.can_break_lanterns(state) and logic.can_break_walls(state)), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater Secret Lantern 2', 1337619, lambda state: logic.can_break_lanterns(state) and logic.can_break_walls(state)), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater Secret Lantern 3', 1337620, lambda state: logic.can_break_lanterns(state) and logic.can_break_walls(state)), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Water Spikes Lantern 1', 1337635, logic.can_break_lanterns), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Water Spikes Lantern 2', 1337636, logic.can_break_lanterns), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Water Spikes Lantern 3', 1337637, logic.can_break_lanterns), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater Lantern 1', 1337627, logic.can_break_lanterns), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater Lantern 2', 1337628, logic.can_break_lanterns), + LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater Lantern 3', 1337629, logic.can_break_lanterns), + + LocationData('Military Fortress', 'Military Fortress: Entrance Lantern 1', 1337260, logic.can_break_lanterns), + LocationData('Military Fortress', 'Military Fortress: Entrance Lantern 2', 1337261, logic.can_break_lanterns), + LocationData('Military Fortress', 'Military Fortress: Bombing Room Lower Lantern 1', 1337264, logic.can_break_lanterns), + LocationData('Military Fortress', 'Military Fortress: Bombing Room Lower Lantern 2', 1337266, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Bombing Room Upper Lantern 1', 1337263, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Bombing Room Upper Lantern 2', 1337265, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Left Bridge Lantern 1', 1337267, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Left Bridge Lantern 2', 1337268, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Left Bridge Lantern 3', 1337269, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Middle Room Lantern 1', 1337270, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Middle Room Lantern 2', 1337271, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Right Bridge Lantern 1', 1337274, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Right Bridge Lantern 2', 1337275, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Right Bridge Lantern 3', 1337276, logic.can_break_lanterns), + LocationData('Military Fortress (hangar)', 'Military Fortress: Spike Room Lantern 1', 1337262, lambda state: logic.can_break_lanterns(state) and (state.has('Water Mask', player) if flooded.flood_lab else logic.has_doublejump(state))), + LocationData('Military Fortress (hangar)', 'Military Fortress: Spike Room Lantern 2', 1337272, lambda state: logic.can_break_lanterns(state) and (state.has('Water Mask', player) if flooded.flood_lab else logic.has_doublejump(state))), + LocationData('Military Fortress (hangar)', 'Military Fortress: Pedestal Lantern', 1337273, lambda state: logic.can_break_lanterns(state) and (state.has('Water Mask', player) if flooded.flood_lab else (logic.has_doublejump_of_npc(state) or logic.has_forwarddash_doublejump(state)))), + + LocationData('Lab Entrance', 'Lab: Intro Hallway Lantern 1', 1337294, logic.can_break_lanterns), + LocationData('Lab Entrance', 'Lab: Intro Hallway Lantern 2', 1337782, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Coffee Lantern 1', 1337305, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Coffee Lantern 2', 1337306, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Coffee Lantern 3', 1337307, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Lower Trash Entrance Lantern 1', 1337277, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Lower Trash Entrance Lantern 2', 1337278, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Main Shaft Lantern 1', 1337297, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Main Shaft Lantern 2', 1337298, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Main Shaft Lantern 3', 1337299, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Main Shaft Lantern 4', 1337300, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Main Shaft Lantern 5', 1337301, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Main Shaft Lantern 6', 1337302, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Main Shaft Lantern 7', 1337303, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Main Shaft Lantern 8', 1337304, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Trash Stairs Lantern 1', 1337281, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Trash Stairs Lantern 2', 1337506, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Exp. 13 Terminal Lantern 1', 1337295, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Exp. 13 Terminal Lantern 2', 1337296, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Left Terminal Lantern 1', 1337308, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Left Terminal Lantern 2', 1337309, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Trash Jump Lantern 1', 1337282, lambda state: logic.can_break_lanterns(state) and (logic.has_doublejump_of_npc(state) if options.lock_key_amadeus else logic.has_upwarddash(state))), + LocationData('Main Lab', 'Lab: Trash Jump Lantern 2', 1337283, lambda state: logic.can_break_lanterns(state) and (logic.has_doublejump_of_npc(state) if options.lock_key_amadeus else logic.has_upwarddash(state))), + LocationData('Lab Research', 'Lab: Spider Hell Entrance Lantern 1', 1337290, logic.can_break_lanterns), + LocationData('Lab Research', 'Lab: Spider Hell Entrance Lantern 2', 1337291, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Lower Trash Lantern 1', 1337292, lambda state: logic.can_break_lanterns(state) and (logic.has_doublejump_of_npc(state) if options.lock_key_amadeus else logic.has_upwarddash(state))), + LocationData('Main Lab', 'Lab: Lower Trash Lantern 2', 1337293, lambda state: logic.can_break_lanterns(state) and (logic.has_doublejump_of_npc(state) if options.lock_key_amadeus else logic.has_upwarddash(state))), + LocationData('The lab (upper)', 'Lab: File Cabinet Lantern 1', 1337310, logic.can_break_lanterns), + LocationData('The lab (upper)', 'Lab: File Cabinet Lantern 2', 1337311, logic.can_break_lanterns), + LocationData('The lab (upper)', 'Lab: File Cabinet Staircase Lantern 1', 1337286, logic.can_break_lanterns), + LocationData('The lab (upper)', 'Lab: File Cabinet Staircase Lantern 2', 1337287, logic.can_break_lanterns), + LocationData('The lab (upper)', 'Lab: File Cabinet Staircase Lantern 3', 1337288, logic.can_break_lanterns), + LocationData('The lab (upper)', 'Lab: File Cabinet Staircase Lantern 4', 1337289, logic.can_break_lanterns), + LocationData('The lab (upper)', 'Lab: Genza Door Lantern 1', 1337284, logic.can_break_lanterns), + LocationData('The lab (upper)', 'Lab: Genza Door Lantern 2', 1337285, logic.can_break_lanterns), + LocationData('The lab (upper)', 'Lab: Download and Chest Lantern 1', 1337312, logic.can_break_lanterns), + LocationData('The lab (upper)', 'Lab: Download and Chest Lantern 2', 1337313, logic.can_break_lanterns), + LocationData('Main Lab', 'Lab: Sentry Lantern 1', 1337279, lambda state: logic.can_break_lanterns(state) and (not options.lock_key_amadeus or state.has('Lab Access Genza', player) or logic.can_teleport_to(state, "Time", "GateDadsTower"))), + LocationData('Main Lab', 'Lab: Sentry Lantern 2', 1337280, lambda state: logic.can_break_lanterns(state) and (not options.lock_key_amadeus or state.has('Lab Access Genza', player) or logic.can_teleport_to(state, "Time", "GateDadsTower"))), + + LocationData('Emperors tower (courtyard)', 'Emperor\'s Tower: Courtyard Lantern 1', 1337314, logic.can_break_lanterns), + LocationData('Emperors tower (courtyard)', 'Emperor\'s Tower: Courtyard Lantern 2', 1337316, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard Staircase Lantern', 1337315, logic.can_break_lanterns), + LocationData('Emperors tower (courtyard)', 'Emperor\'s Tower: Courtyard Bottom Lantern 1', 1337342, logic.can_break_lanterns), + LocationData('Emperors tower (courtyard)', 'Emperor\'s Tower: Courtyard Bottom Lantern 2', 1337343, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard Floor Secret Lantern 1', 1337336, lambda state: logic.has_upwarddash(state) and logic.can_break_walls(state) and logic.can_break_lanterns(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard Floor Secret Lantern 2', 1337337, lambda state: logic.has_upwarddash(state) and logic.can_break_walls(state) and logic.can_break_lanterns(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard Giantess Lantern 1', 1337331, lambda state: logic.has_upwarddash(state) and logic.can_break_lanterns(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard Giantess Lantern 2', 1337332, lambda state: logic.has_upwarddash(state) and logic.can_break_lanterns(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Courtyard Upper Lantern', 1337333, lambda state: logic.has_upwarddash(state) and logic.can_break_lanterns(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Hallway Lantern 1', 1337317, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Hallway Lantern 2', 1337318, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Hallway Lantern 3', 1337319, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Hallway Lantern 4', 1337320, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Left Room Lantern 1', 1337321, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Left Room Lantern 2', 1337322, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Outside Way Up There Lantern 1', 1337323, lambda state: logic.has_doublejump_of_npc(state) and logic.can_break_lanterns(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Outside Way Up There Lantern 2', 1337324, lambda state: logic.has_doublejump_of_npc(state) and logic.can_break_lanterns(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Way Up There Lantern 1', 1337325, lambda state: logic.has_doublejump_of_npc(state) and logic.can_break_lanterns(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Way Up There Lantern 2', 1337326, lambda state: logic.has_doublejump_of_npc(state) and logic.can_break_lanterns(state)), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Left Tower Lantern 1', 1337327, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Left Tower Lantern 2', 1337328, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Galactic Sage Lantern 1', 1337329, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Galactic Sage Lantern 2', 1337330, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Save Room Lantern 1', 1337334, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Save Room Lantern 2', 1337335, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Climb Past Stairs Lantern 1', 1337338, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Climb Past Stairs Lantern 2', 1337339, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Climb Past Stairs Lantern 3', 1337340, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Climb Past Stairs Lantern 4', 1337341, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Middle Bridge Lantern 1', 1337344, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Middle Bridge Lantern 2', 1337345, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Middle Bridge Lantern 3', 1337346, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Middle Bridge Lantern 4', 1337347, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Middle Bridge Lantern 5', 1337348, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Upper Left Tower Lantern 1', 1337349, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Upper Left Tower Lantern 2', 1337350, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Right Tower Lantern 1', 1337351, logic.can_break_lanterns), + LocationData('Emperors tower', 'Emperor\'s Tower: Lower Right Tower Lantern 2', 1337352, logic.can_break_lanterns), + + LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Pyramid Entrance Lantern 1', 1337369, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Pyramid Entrance Lantern 2', 1337370, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Pyramid Entrance Lantern 3', 1337371, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Pyramid Entrance Lantern 4', 1337372, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Pyramid Entrance Lantern 5', 1337373, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Pyramid Entrance Lantern 6', 1337374, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Training Dummy Lantern 1', 1337375, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Dark Forest: Training Dummy Lantern 2', 1337376, logic.can_break_lanterns), + + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Entrance Lantern 1', 1337377, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Entrance Lantern 2', 1337378, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Rubble Lantern 1', 1337399, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Rubble Lantern 2', 1337400, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Rubble Lantern 3', 1337401, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Entrance Climb Lantern 1', 1337393, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Entrance Climb Lantern 2', 1337394, logic.can_break_lanterns), + LocationData('Ancient Pyramid (entrance)', 'Ancient Pyramid: Why Not It\'s Right There Lantern', 1337386, logic.can_break_lanterns), + + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: First Enemy Lantern 1', 1337387, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: First Enemy Lantern 2', 1337388, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Upper-Left Stairway Lantern 1', 1337381, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Upper-Left Stairway Lantern 2', 1337382, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Upper-Left Stairway Lantern 3', 1337383, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Regret Shaft Lantern 1', 1337402, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Regret Shaft Lantern 2', 1337403, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Regret Lantern 1', 1337389, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Regret Lantern 2', 1337390, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Regret Lantern 3', 1337391, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Regret Lantern 4', 1337392, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Left Hallway Lantern 1', 1337395, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Left Hallway Lantern 2', 1337396, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Left Hallway Lantern 3', 1337397, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Left Hallway Lantern 4', 1337398, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Pit Secret Lantern 1', 1337404, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Pit Secret Lantern 2', 1337405, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Pit Secret\'s Secret Lantern 1', 1337406, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Pit Secret\'s Secret Lantern 2', 1337407, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Outside Inner Warp Lantern 1', 1337408, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Outside Inner Warp Lantern 2', 1337409, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Nightmare Stairway Entrance Lantern', 1337410, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Conviction Lantern 1', 1337411, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Conviction Lantern 2', 1337412, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: A Long Fall Lantern 1', 1337415, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: A Long Fall Lantern 2', 1337416, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_shaft or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Last Chance Before Shaft Lantern 1', 1337417, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Last Chance Before Shaft Lantern 2', 1337418, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Pit Secret Wall Lantern', 1337419, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Post-Shaft Hallway Lantern 1', 1337420, logic.can_break_lanterns), + LocationData('Ancient Pyramid (left)', 'Ancient Pyramid: Post-Shaft Hallway Lantern 2', 1337421, logic.can_break_lanterns), + + LocationData('Ancient Pyramid (right)', 'Ancient Pyramid: Upper-Right Stairway Lantern 1', 1337384, logic.can_break_lanterns), + LocationData('Ancient Pyramid (right)', 'Ancient Pyramid: Upper-Right Stairway Lantern 2', 1337385, logic.can_break_lanterns), + LocationData('Ancient Pyramid (right)', 'Ancient Pyramid: Nightmare Stairway Lantern 1', 1337379, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_back or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (right)', 'Ancient Pyramid: Nightmare Stairway Lantern 2"', 1337380, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_back or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (right)', 'Ancient Pyramid: Nightmare Door Lantern 1', 1337413, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_back or state.has('Water Mask', player))), + LocationData('Ancient Pyramid (right)', 'Ancient Pyramid: Nightmare Door Lantern 2', 1337414, lambda state: logic.can_break_lanterns(state) and (not flooded.flood_pyramid_back or state.has('Water Mask', player))), + ) + if not options or options.gyre_archives: + location_table += ( + LocationData('Temporal Gyre', 'Temporal Gyre: Room 1 Lantern 1', 1337353, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 1 Lantern 2', 1337354, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 2 Lantern 1', 1337355, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 2 Lantern 2', 1337356, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 3 Lantern 1', 1337357, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 3 Lantern 2', 1337358, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 4 Lantern 1', 1337359, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 4 Lantern 2', 1337360, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 5 Lantern 1', 1337361, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 5 Lantern 2', 1337362, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 6 Lantern 1', 1337363, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 6 Lantern 2', 1337364, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 7 Lantern 1', 1337365, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 7 Lantern 2', 1337366, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 8 Lantern 1', 1337367, logic.can_break_lanterns), + LocationData('Temporal Gyre', 'Temporal Gyre: Room 8 Lantern 2', 1337368, logic.can_break_lanterns), + ) return location_table diff --git a/worlds/timespinner/LogicExtensions.py b/worlds/timespinner/LogicExtensions.py index 878b69ae9c6e..a977b8a0ea5b 100644 --- a/worlds/timespinner/LogicExtensions.py +++ b/worlds/timespinner/LogicExtensions.py @@ -24,6 +24,7 @@ def __init__(self, player: int, options: Optional[TimespinnerOptions], self.flag_eye_spy = bool(options and options.eye_spy) self.flag_unchained_keys = bool(options and options.unchained_keys) self.flag_prism_break = bool(options and options.prism_break) + self.flag_find_the_flame = bool(options and options.find_the_flame) if precalculated_weights: if self.flag_unchained_keys: @@ -93,6 +94,12 @@ def can_break_walls(self, state: CollectionState) -> bool: else: return True + def can_break_lanterns(self, state: CollectionState) -> bool: + if self.flag_find_the_flame: + return state.has('Cube of Bodie', self.player) + else: + return True + def can_kill_all_3_bosses(self, state: CollectionState) -> bool: if self.flag_prism_break: return state.has_all({'Laser Access M', 'Laser Access I', 'Laser Access A'}, self.player) diff --git a/worlds/timespinner/Options.py b/worlds/timespinner/Options.py index 0b735ea3913a..35d9d630efb4 100644 --- a/worlds/timespinner/Options.py +++ b/worlds/timespinner/Options.py @@ -367,8 +367,8 @@ class TrapChance(Range): class Traps(OptionList): """List of traps that may be in the item pool to find""" display_name = "Traps Types" - valid_keys = { "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap", "Throw Stun Trap", "Spider Trap" } - default = [ "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap", "Throw Stun Trap", "Spider Trap" ] + valid_keys = { "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap", "Throw Stun Trap", "Spider Trap", "Lights Out Trap", "Palm Punch Trap" } + default = [ "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap", "Throw Stun Trap", "Spider Trap", "Lights Out Trap", "Palm Punch Trap" ] class PresentAccessWithWheelAndSpindle(Toggle): """When inverted, allows using the refugee camp warp when both the Timespinner Wheel and Spindle is acquired.""" @@ -399,6 +399,14 @@ class RoyalRoadblock(Toggle): """The Royal Towers entrance door requires a royal orb (Plasma Orb, Plasma Geyser, or Royal Ring) to enter.""" display_name = "Royal Roadblock" +class PureTorcher(Toggle): + """All lanterns contain checks. (Except tutorial)""" + display_name = "Pure Torcher" + +class FindTheFlame(Toggle): + """Lanterns in 'Pure Torcher' will not break without new item 'Cube of Bodie'.""" + display_name = "Find the Flame" + @dataclass class TimespinnerOptions(PerGameCommonOptions, DeathLinkMixin): start_with_jewelry_box: StartWithJewelryBox @@ -441,6 +449,8 @@ class TimespinnerOptions(PerGameCommonOptions, DeathLinkMixin): pyramid_start: PyramidStart gate_keep: GateKeep royal_roadblock: RoyalRoadblock + pure_torcher: PureTorcher + find_the_flame: FindTheFlame trap_chance: TrapChance traps: Traps diff --git a/worlds/timespinner/Regions.py b/worlds/timespinner/Regions.py index b9b1d10445ce..9580eb14feb7 100644 --- a/worlds/timespinner/Regions.py +++ b/worlds/timespinner/Regions.py @@ -28,9 +28,11 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp create_region(world, player, locations_per_region, 'Sealed Caves (Sirens)'), create_region(world, player, locations_per_region, 'Military Fortress'), create_region(world, player, locations_per_region, 'Military Fortress (hangar)'), - create_region(world, player, locations_per_region, 'The lab'), - create_region(world, player, locations_per_region, 'The lab (power off)'), + create_region(world, player, locations_per_region, 'Lab Entrance'), + create_region(world, player, locations_per_region, 'Main Lab'), + create_region(world, player, locations_per_region, 'Lab Research'), create_region(world, player, locations_per_region, 'The lab (upper)'), + create_region(world, player, locations_per_region, 'Emperors tower (courtyard)'), create_region(world, player, locations_per_region, 'Emperors tower'), create_region(world, player, locations_per_region, 'Skeleton Shaft'), create_region(world, player, locations_per_region, 'Sealed Caves (Xarion)'), @@ -41,6 +43,7 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp create_region(world, player, locations_per_region, 'Lower Lake Serene'), create_region(world, player, locations_per_region, 'Caves of Banishment (upper)'), create_region(world, player, locations_per_region, 'Caves of Banishment (Maw)'), + create_region(world, player, locations_per_region, 'Caves of Banishment (Flooded)'), create_region(world, player, locations_per_region, 'Caves of Banishment (Sirens)'), create_region(world, player, locations_per_region, 'Castle Ramparts'), create_region(world, player, locations_per_region, 'Castle Keep'), @@ -109,16 +112,19 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'Military Fortress', 'Temporal Gyre', lambda state: state.has('Timespinner Wheel', player) and logic.can_kill_all_3_bosses(state)) connect(world, player, 'Military Fortress', 'Military Fortress (hangar)', logic.has_doublejump) connect(world, player, 'Military Fortress (hangar)', 'Military Fortress') - connect(world, player, 'Military Fortress (hangar)', 'The lab', lambda state: logic.has_keycard_B(state) and (state.has('Water Mask', player) if flooded.flood_lab else logic.has_doublejump(state))) + connect(world, player, 'Military Fortress (hangar)', 'Lab Entrance', lambda state: state.has('Water Mask', player) if flooded.flood_lab else logic.has_doublejump(state)) + connect(world, player, 'Lab Entrance', 'Main Lab', lambda state: logic.has_keycard_B(state)) + connect(world, player, 'Main Lab', 'Lab Entrance') + connect(world, player, 'Lab Entrance', 'Military Fortress (hangar)') connect(world, player, 'Temporal Gyre', 'Military Fortress') - connect(world, player, 'The lab', 'Military Fortress') - connect(world, player, 'The lab', 'The lab (power off)', lambda state: options.lock_key_amadeus or logic.has_doublejump_of_npc(state)) - connect(world, player, 'The lab (power off)', 'The lab', lambda state: not flooded.flood_lab or state.has('Water Mask', player)) - connect(world, player, 'The lab (power off)', 'The lab (upper)', lambda state: logic.has_forwarddash_doublejump(state) and ((not options.lock_key_amadeus) or state.has('Lab Access Genza', player))) - connect(world, player, 'The lab (upper)', 'The lab (power off)', lambda state: options.lock_key_amadeus and state.has('Lab Access Genza', player)) - connect(world, player, 'The lab (upper)', 'Emperors tower', logic.has_forwarddash_doublejump) + connect(world, player, 'Main Lab', 'Lab Research', lambda state: state.has('Lab Access Research', player) if options.lock_key_amadeus else logic.has_doublejump_of_npc(state)) + connect(world, player, 'Main Lab', 'The lab (upper)', lambda state: logic.has_forwarddash_doublejump(state) and ((not options.lock_key_amadeus) or state.has('Lab Access Genza', player))) + connect(world, player, 'The lab (upper)', 'Main Lab', lambda state: options.lock_key_amadeus and state.has('Lab Access Genza', player)) + connect(world, player, 'The lab (upper)', 'Emperors tower (courtyard)', logic.has_forwarddash_doublejump) connect(world, player, 'The lab (upper)', 'Ancient Pyramid (entrance)', lambda state: state.has_all({'Timespinner Wheel', 'Timespinner Spindle', 'Timespinner Gear 1', 'Timespinner Gear 2', 'Timespinner Gear 3'}, player)) - connect(world, player, 'Emperors tower', 'The lab (upper)') + connect(world, player, 'Emperors tower (courtyard)', 'The lab (upper)') + connect(world, player, 'Emperors tower (courtyard)', 'Emperors tower', logic.has_doublejump) + connect(world, player, 'Emperors tower', 'Emperors tower (courtyard)') connect(world, player, 'Skeleton Shaft', 'Lake desolation') connect(world, player, 'Skeleton Shaft', 'Sealed Caves (Xarion)', logic.has_keycard_A) connect(world, player, 'Skeleton Shaft', 'Space time continuum', logic.has_teleport) @@ -145,6 +151,7 @@ def create_regions_and_locations(world: MultiWorld, player: int, options: Timesp connect(world, player, 'Caves of Banishment (upper)', 'Space time continuum', logic.has_teleport) connect(world, player, 'Caves of Banishment (Maw)', 'Caves of Banishment (upper)', lambda state: logic.has_doublejump(state) if not flooded.flood_maw else state.has('Water Mask', player)) connect(world, player, 'Caves of Banishment (Maw)', 'Caves of Banishment (Sirens)', lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player) ) + connect(world, player, 'Caves of Banishment (Maw)', 'Caves of Banishment (Flooded)', lambda state: flooded.flood_maw or state.has('Water Mask', player)) connect(world, player, 'Caves of Banishment (Maw)', 'Space time continuum', logic.has_teleport) connect(world, player, 'Caves of Banishment (Sirens)', 'Forest') connect(world, player, 'Castle Ramparts', 'Forest') diff --git a/worlds/timespinner/__init__.py b/worlds/timespinner/__init__.py index 77314d40ec7b..0bd9c7d19c80 100644 --- a/worlds/timespinner/__init__.py +++ b/worlds/timespinner/__init__.py @@ -132,6 +132,8 @@ def fill_slot_data(self) -> Dict[str, object]: "PyramidStart": self.options.pyramid_start.value, "GateKeep": self.options.gate_keep.value, "RoyalRoadblock": self.options.royal_roadblock.value, + "PureTorcher": self.options.pure_torcher.value, + "FindTheFlame": self.options.find_the_flame.value, "Traps": self.options.traps.value, "DeathLink": self.options.death_link.value, "StinkyMaw": True, @@ -298,7 +300,9 @@ def create_item(self, name: str) -> Item: if not item.advancement: return item - if (name == 'Tablet' or name == 'Library Keycard V') and not self.options.downloadable_items: + if name == 'Tablet' and not self.options.downloadable_items: + item.classification = ItemClassification.filler + elif name == 'Library Keycard V' and not (self.options.downloadable_items or self.options.pure_torcher): item.classification = ItemClassification.filler elif name == 'Oculus Ring' and not self.options.eye_spy: item.classification = ItemClassification.filler @@ -315,6 +319,8 @@ def create_item(self, name: str) -> Item: item.classification = ItemClassification.filler elif name == "Drawbridge Key" and not self.options.gate_keep: item.classification = ItemClassification.filler + elif name == "Cube of Bodie" and not self.options.find_the_flame: + item.classification = ItemClassification.filler return item @@ -361,6 +367,9 @@ def get_excluded_items(self) -> Set[str]: if not self.options.gate_keep: excluded_items.add('Drawbridge Key') + if not self.options.find_the_flame: + excluded_items.add('Cube of Bodie') + for item in self.multiworld.precollected_items[self.player]: if item.name not in self.item_name_groups['UseItem']: excluded_items.add(item.name) From 1322ce866eddb1ccf0ca042db93ceef8789d6029 Mon Sep 17 00:00:00 2001 From: gaithern <36639398+gaithern@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:49:32 -0500 Subject: [PATCH 0721/1218] Kingdom Hearts: Adding a bunch of new features (#5078) * Change vanilla_emblem_pieces to randomize_emblem_pieces * Add jungle slider and starting tools options * Update option name and add preset * GICU changes * unnecessary * Update Options.py * Fix has_all * Update Options.py * Update Options.py * Some potenitial logic changes * Oops * Oops 2 * Cups choice options * typos * Logic tweaks * Ice Titan and Superboss changes * Suggested change and one more * Updating some other option descriptions for clarity/typos * Update Locations.py * commit * SYNTHESIS * commit * commit * commit * Add command to change communication path I'm not a python programmer, so do excuse the code etiquette. This aims to allow Linux users to communicate to their proton directory. * commit * commit * commit * commit * commit * commit * commit * commit * Update Client.py * Update Locations.py * Update Regions.py * commit * commit * commit * Update Rules.py * commit * commit * commit * commit logic changes and linux fix from other branch * commit * commit * Update __init__.py * Update Rules.py * commit * commit * commit * commit * add starting accessory setting * fix starting accessories bug * Update Locations.py * commit * add ap cost rando * fix some problem locations * add raft materials * Update Client.py * OK WORK THIS TIME PLEASE * Corrected typos * setting up for logic difficulty * commit 1 * commit 2 * commit 3 * minor error fix * some logic changes and fixed some typos * tweaks * commit * SYNTHESIS * commit * commit * commit * commit * commit * commit * commit * commit * commit * commit * commit * Update Client.py * Update Locations.py * Update Regions.py * commit * commit * commit * Update Rules.py * commit * commit * commit * commit logic changes and linux fix from other branch * commit * commit * Update __init__.py * Update Rules.py * commit * commit * commit * commit * add starting accessory setting * fix starting accessories bug * Update Locations.py * commit * add ap cost rando * fix some problem locations * add raft materials * Update Client.py * cleanup * commit 4 * tweaks 2 * tweaks 3 * Reset * Update __init__.py * Change vanilla_emblem_pieces to randomize_emblem_pieces * Add jungle slider and starting tools options * unnecessary * Vanilla Puppies Part 1 The easy part * Update __init__.py I'm not certain this is the exact right chest for Tea Party Garden, Waterfall Cavern, HT Cemetery, or Neverland Hold but logically it's the same. Will do a test run later and fix if need be * Vanilla Puppies Part 3 Wrong toggle cause I just copied over Emblem Pieces oops * Vanilla Puppies Part 4 Forgor commented out code * Vanilla Puppies Part 5 I now realize how this works and that what I had before was redundant * Update __init__.py Learning much about strings * cleanup * Update __init__.py Only missed one! * Update option name and add preset * GICU changes * Update Options.py * Fix has_all * Update Options.py * Update Options.py * Cups choice options * typos * Ice Titan and Superboss changes * Some potenitial logic changes * Oops * Oops 2 * Logic tweaks * Suggested change and one more * Updating some other option descriptions for clarity/typos * Update Locations.py * Add command to change communication path I'm not a python programmer, so do excuse the code etiquette. This aims to allow Linux users to communicate to their proton directory. * Moving over changes from REVAMP * whoops * Fix patch files on the website * Update test_goal.py * commit * Update worlds/kh1/__init__.py Co-authored-by: Scipio Wright * change some default options * Missed a condition * let's try that * Update Options.py * unnecessary sub check * Some more cleanup * tuples * add icon * merge cleanup * merge cleanup 2 * merge clean up 3 * Update Data.py * Fix cups option * commit * Update Rules.py * Update Rules.py * phantom tweak * review commit * minor fixes * review 2 * minor typo fix * minor logic tweak * Update Client.py * Update __init__.py * Update Rules.py * Olympus Cup fixes * Update Options.py * even MORE tweaks * commit * Update Options.py * Update has_x_worlds * Update Rules.py * commit * Update Options.py * Update Options.py * Update Options.py * tweak 5 * Add Stacking Key Items and Halloween Town Key Item Bundle * Update worlds/kh1/Rules.py Co-authored-by: Scipio Wright * Update Rules.py * commit * Update worlds/kh1/__init__.py Co-authored-by: Scipio Wright * Update __init__.py * Update __init__.py * whoops * Update Rules.py * Update Rules.py * Fix documentation styling * Clean up option help text * Reordering options so they're consistent and fixing a logic bug when EOTW Unlock is item but door is emblems * Make have x world logic consider if the player has HAW on or not * Fix Atlantica beginner logic things, vanilla keyblade stats being broken, and some behind boss locations * Fix vanilla puppy option * hotfix for crabclaw logic * Fix defaults and some boss locations * Fix server spam * Remove 3 High Jump Item Workshop Logic, small client changes * Updates for PR --------- Co-authored-by: esutley Co-authored-by: Goblin God <37878138+esutley@users.noreply.github.com> Co-authored-by: River Buizel <4911928+rocket0634@users.noreply.github.com> Co-authored-by: omnises Co-authored-by: Omnises Nihilis <38057571+Omnises@users.noreply.github.com> Co-authored-by: Scipio Wright --- worlds/kh1/Client.py | 184 ++- worlds/kh1/Data.py | 202 +++ worlds/kh1/GenerateJSON.py | 67 + worlds/kh1/Items.py | 827 ++++------ worlds/kh1/Locations.py | 1290 ++++++++------- worlds/kh1/Options.py | 752 +++++++-- worlds/kh1/Presets.py | 302 +++- worlds/kh1/Regions.py | 209 ++- worlds/kh1/Rules.py | 2236 ++++++++++++-------------- worlds/kh1/__init__.py | 543 +++++-- worlds/kh1/docs/en_Kingdom Hearts.md | 41 +- worlds/kh1/docs/kh1_en.md | 117 +- worlds/kh1/icons/kh1_heart.ico | Bin 0 -> 4286 bytes worlds/kh1/icons/kh1_heart.png | Bin 0 -> 7821 bytes worlds/kh1/test/test_goal.py | 14 +- 15 files changed, 4026 insertions(+), 2758 deletions(-) create mode 100644 worlds/kh1/Data.py create mode 100644 worlds/kh1/GenerateJSON.py create mode 100644 worlds/kh1/icons/kh1_heart.ico create mode 100644 worlds/kh1/icons/kh1_heart.png diff --git a/worlds/kh1/Client.py b/worlds/kh1/Client.py index b98f21531207..9d3889d6ceb0 100644 --- a/worlds/kh1/Client.py +++ b/worlds/kh1/Client.py @@ -13,8 +13,6 @@ ModuleUpdate.update() import Utils -death_link = False -item_num = 1 logger = logging.getLogger("Client") @@ -34,62 +32,57 @@ class KH1ClientCommandProcessor(ClientCommandProcessor): def __init__(self, ctx): super().__init__(ctx) - def _cmd_deathlink(self): - """Toggles Deathlink""" - global death_link - if death_link: - death_link = False - self.output(f"Death Link turned off") - else: - death_link = True - self.output(f"Death Link turned on") - - def _cmd_goal(self): - """Prints goal setting""" - if "goal" in self.ctx.slot_data.keys(): - self.output(str(self.ctx.slot_data["goal"])) - else: - self.output("Unknown") + def _cmd_slot_data(self): + """Prints slot data settings for the connected seed""" + for key in self.ctx.slot_data.keys(): + if key not in ["remote_location_ids", "synthesis_item_name_byte_arrays"]: + self.output(str(key) + ": " + str(self.ctx.slot_data[key])) - def _cmd_eotw_unlock(self): - """Prints End of the World Unlock setting""" - if "required_reports_door" in self.ctx.slot_data.keys(): - if self.ctx.slot_data["required_reports_door"] > 13: - self.output("Item") - else: - self.output(str(self.ctx.slot_data["required_reports_eotw"]) + " reports") - else: - self.output("Unknown") - - def _cmd_door_unlock(self): - """Prints Final Rest Door Unlock setting""" - if "door" in self.ctx.slot_data.keys(): - if self.ctx.slot_data["door"] == "reports": - self.output(str(self.ctx.slot_data["required_reports_door"]) + " reports") + def _cmd_deathlink(self): + """If your Death Link setting is set to "Toggle", use this command to turn Death Link on and off.""" + if "death_link" in self.ctx.slot_data.keys(): + if self.ctx.slot_data["death_link"] == "toggle": + if self.ctx.death_link: + self.ctx.death_link = False + self.output(f"Death Link turned off") + else: + self.ctx.death_link = True + self.output(f"Death Link turned on") else: - self.output(str(self.ctx.slot_data["door"])) + self.output(f"'death_link' is not set to 'toggle' for this seed.") + self.output(f"'death_link' = " + str(self.ctx.slot_data["death_link"])) else: - self.output("Unknown") + self.output(f"No 'death_link' in slot_data keys. You probably aren't connected or are playing an older seed.") - def _cmd_advanced_logic(self): - """Prints advanced logic setting""" - if "advanced_logic" in self.ctx.slot_data.keys(): - self.output(str(self.ctx.slot_data["advanced_logic"])) + def _cmd_communication_path(self): + """Opens a file browser to allow Linux users to manually set their %LOCALAPPDATA% path""" + directory = Utils.open_directory("Select %LOCALAPPDATA% dir", "~/.local/share/Steam/steamapps/compatdata/2552430/pfx/drive_c/users/steamuser/AppData/Local") + if directory: + directory += "/KH1FM" + if not os.path.exists(directory): + os.makedirs(directory) + self.ctx.game_communication_path = directory else: - self.output("Unknown") + self.output(self.ctx.game_communication_path) class KH1Context(CommonContext): command_processor: int = KH1ClientCommandProcessor game = "Kingdom Hearts" - items_handling = 0b111 # full remote + items_handling = 0b011 # full remote except start inventory def __init__(self, server_address, password): super(KH1Context, self).__init__(server_address, password) self.send_index: int = 0 self.syncing = False self.awaiting_bridge = False - self.hinted_synth_location_ids = False - self.slot_data = {} + self.hinted_location_ids: list[int] = [] + self.slot_data: dict = {} + + # Moved globals into instance attributes + self.death_link: bool = False + self.item_num: int = 1 + self.remote_location_ids: list[int] = [] + # self.game_communication_path: files go in this path to pass data between us and the actual game if "localappdata" in os.environ: self.game_communication_path = os.path.expandvars(r"%localappdata%/KH1FM") @@ -103,6 +96,10 @@ def __init__(self, server_address, password): os.remove(root+"/"+file) async def server_auth(self, password_requested: bool = False): + for root, dirs, files in os.walk(self.game_communication_path): + for file in files: + if file.find("obtain") <= -1: + os.remove(root+"/"+file) if password_requested and not self.password: await super(KH1Context, self).server_auth(password_requested) await self.get_username() @@ -114,8 +111,7 @@ async def connection_closed(self): for file in files: if file.find("obtain") <= -1: os.remove(root + "/" + file) - global item_num - item_num = 1 + self.item_num = 1 @property def endpoints(self): @@ -130,8 +126,7 @@ async def shutdown(self): for file in files: if file.find("obtain") <= -1: os.remove(root+"/"+file) - global item_num - item_num = 1 + self.item_num = 1 def on_package(self, cmd: str, args: dict): if cmd in {"Connected"}: @@ -142,38 +137,34 @@ def on_package(self, cmd: str, args: dict): with open(os.path.join(self.game_communication_path, filename), 'w') as f: f.close() - #Handle Slot Data + # Handle Slot Data self.slot_data = args['slot_data'] for key in list(args['slot_data'].keys()): with open(os.path.join(self.game_communication_path, key + ".cfg"), 'w') as f: f.write(str(args['slot_data'][key])) f.close() - - ###Support Legacy Games - if "Required Reports" in list(args['slot_data'].keys()) and "required_reports_eotw" not in list(args['slot_data'].keys()): - reports_required = args['slot_data']["Required Reports"] - with open(os.path.join(self.game_communication_path, "required_reports.cfg"), 'w') as f: - f.write(str(reports_required)) - f.close() - ###End Support Legacy Games - - #End Handle Slot Data + if key == "remote_location_ids": + self.remote_location_ids = args['slot_data'][key] + if key == "death_link": + if args['slot_data']["death_link"] != "off": + self.death_link = True + # End Handle Slot Data if cmd in {"ReceivedItems"}: start_index = args["index"] if start_index != len(self.items_received): - global item_num for item in args['items']: found = False - item_filename = f"AP_{str(item_num)}.item" + item_filename = f"AP_{str(self.item_num)}.item" for filename in os.listdir(self.game_communication_path): if filename == item_filename: found = True if not found: - with open(os.path.join(self.game_communication_path, item_filename), 'w') as f: - f.write(str(NetworkItem(*item).item) + "\n" + str(NetworkItem(*item).location) + "\n" + str(NetworkItem(*item).player)) - f.close() - item_num = item_num + 1 + if (NetworkItem(*item).player == self.slot and (NetworkItem(*item).location in self.remote_location_ids) or (NetworkItem(*item).location < 0)) or NetworkItem(*item).player != self.slot: + with open(os.path.join(self.game_communication_path, item_filename), 'w') as f: + f.write(str(NetworkItem(*item).item) + "\n" + str(NetworkItem(*item).location) + "\n" + str(NetworkItem(*item).player)) + f.close() + self.item_num += 1 if cmd in {"RoomUpdate"}: if "checked_locations" in args: @@ -186,21 +177,39 @@ def on_package(self, cmd: str, args: dict): if args["type"] == "ItemSend": item = args["item"] networkItem = NetworkItem(*item) - recieverID = args["receiving"] + receiverID = args["receiving"] senderID = networkItem.player locationID = networkItem.location - if recieverID != self.slot and senderID == self.slot: - itemName = self.item_names.lookup_in_slot(networkItem.item, recieverID) + if receiverID == self.slot or senderID == self.slot: + itemName = self.item_names.lookup_in_slot(networkItem.item, receiverID)[:20] itemCategory = networkItem.flags - recieverName = self.player_names[recieverID] - filename = "sent" - with open(os.path.join(self.game_communication_path, filename), 'w') as f: - f.write( - re.sub('[^A-Za-z0-9 ]+', '',str(itemName))[:15] + "\n" - + re.sub('[^A-Za-z0-9 ]+', '',str(recieverName))[:6] + "\n" - + str(itemCategory) + "\n" - + str(locationID)) - f.close() + receiverName = self.player_names[receiverID][:20] + senderName = self.player_names[senderID][:20] + message = "" + if receiverID == self.slot and receiverID != senderID: # Item received from someone else + message = "From " + senderName + "\n" + itemName + elif senderID == self.slot and receiverID != senderID: # Item sent to someone else + message = itemName + "\nTo " + receiverName + elif locationID in self.remote_location_ids: # Found a remote item + message = itemName + filename = "msg" + if message != "": + if not os.path.exists(self.game_communication_path + "/" + filename): + with open(os.path.join(self.game_communication_path, filename), 'w') as f: + f.write(message) + f.close() + if args["type"] == "ItemCheat": + item = args["item"] + networkItem = NetworkItem(*item) + receiverID = args["receiving"] + if receiverID == self.slot: + itemName = self.item_names.lookup_in_slot(networkItem.item, receiverID)[:20] + filename = "msg" + message = "Received " + itemName + "\nfrom server" + if not os.path.exists(self.game_communication_path + "/" + filename): + with open(os.path.join(self.game_communication_path, filename), 'w') as f: + f.write(message) + f.close() def on_deathlink(self, data: dict[str, object]): self.last_death_link = max(data["time"], self.last_death_link) @@ -230,12 +239,11 @@ class KH1Manager(GameManager): async def game_watcher(ctx: KH1Context): from .Locations import lookup_id_to_name while not ctx.exit_event.is_set(): - global death_link - if death_link and "DeathLink" not in ctx.tags: - await ctx.update_death_link(death_link) - if not death_link and "DeathLink" in ctx.tags: - await ctx.update_death_link(death_link) - if ctx.syncing == True: + if ctx.death_link and "DeathLink" not in ctx.tags: + await ctx.update_death_link(ctx.death_link) + if not ctx.death_link and "DeathLink" in ctx.tags: + await ctx.update_death_link(ctx.death_link) + if ctx.syncing is True: sync_msg = [{'cmd': 'Sync'}] if ctx.locations_checked: sync_msg.append({"cmd": "LocationChecks", "locations": list(ctx.locations_checked)}) @@ -256,17 +264,17 @@ async def game_watcher(ctx: KH1Context): if st != "nil": if timegm(time.strptime(st, '%Y%m%d%H%M%S')) > ctx.last_death_link and int(time.time()) % int(timegm(time.strptime(st, '%Y%m%d%H%M%S'))) < 10: await ctx.send_death(death_text = "Sora was defeated!") - if file.find("insynthshop") > -1: - if not ctx.hinted_synth_location_ids: + if file.find("hint") > -1: + hint_location_id = int(file.split("hint", -1)[1]) + if hint_location_id not in ctx.hinted_location_ids: await ctx.send_msgs([{ "cmd": "LocationScouts", - "locations": [2656401,2656402,2656403,2656404,2656405,2656406], + "locations": [hint_location_id], "create_as_hint": 2 }]) - ctx.hinted_synth_location_ids = True + ctx.hinted_location_ids.append(hint_location_id) ctx.locations_checked = sending - message = [{"cmd": 'LocationChecks', "locations": sending}] - await ctx.send_msgs(message) + await ctx.check_locations(sending) if not ctx.finished_game and victory: await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) ctx.finished_game = True diff --git a/worlds/kh1/Data.py b/worlds/kh1/Data.py new file mode 100644 index 000000000000..19227c035bd3 --- /dev/null +++ b/worlds/kh1/Data.py @@ -0,0 +1,202 @@ +VANILLA_KEYBLADE_STATS = [ + {"STR": 3, "CRR": 20, "CRB": 0, "REC": 30, "MP": 0}, # Kingdom Key + {"STR": 1, "CRR": 20, "CRB": 0, "REC": 30, "MP": 0}, # Dream Sword + {"STR": 1, "CRR": 0, "CRB": 0, "REC": 60, "MP": 0}, # Dream Shield + {"STR": 1, "CRR": 10, "CRB": 0, "REC": 30, "MP": 0}, # Dream Rod + {"STR": 0, "CRR": 20, "CRB": 0, "REC": 30, "MP": 0}, # Wooden Sword + {"STR": 5, "CRR": 10, "CRB": 0, "REC": 1, "MP": 0}, # Jungle King + {"STR": 6, "CRR": 20, "CRB": 0, "REC": 60, "MP": 0}, # Three Wishes + {"STR": 8, "CRR": 10, "CRB": 2, "REC": 30, "MP": 1}, # Fairy Harp + {"STR": 7, "CRR": 40, "CRB": 0, "REC": 1, "MP": 0}, # Pumpkinhead + {"STR": 6, "CRR": 20, "CRB": 0, "REC": 30, "MP": 1}, # Crabclaw + {"STR": 13, "CRR": 40, "CRB": 0, "REC": 60, "MP": 0}, # Divine Rose + {"STR": 4, "CRR": 20, "CRB": 0, "REC": 30, "MP": 2}, # Spellbinder + {"STR": 10, "CRR": 20, "CRB": 2, "REC": 90, "MP": 0}, # Olympia + {"STR": 10, "CRR": 20, "CRB": 0, "REC": 30, "MP": 1}, # Lionheart + {"STR": 9, "CRR": 2, "CRB": 0, "REC": 90, "MP": -1}, # Metal Chocobo + {"STR": 9, "CRR": 40, "CRB": 0, "REC": 1, "MP": 1}, # Oathkeeper + {"STR": 11, "CRR": 20, "CRB": 2, "REC": 30, "MP": -1}, # Oblivion + {"STR": 7, "CRR": 20, "CRB": 0, "REC": 1, "MP": 2}, # Lady Luck + {"STR": 5, "CRR": 200, "CRB": 2, "REC": 1, "MP": 0}, # Wishing Star + {"STR": 14, "CRR": 40, "CRB": 2, "REC": 90, "MP": 2}, # Ultima Weapon + {"STR": 3, "CRR": 20, "CRB": 0, "REC": 1, "MP": 3}, # Diamond Dust + {"STR": 8, "CRR": 10, "CRB": 16, "REC": 90, "MP": -2}, # One-Winged Angel + ] +VANILLA_PUPPY_LOCATIONS = [ + "Traverse Town Mystical House Glide Chest", + "Traverse Town Alleyway Behind Crates Chest", + "Traverse Town Item Workshop Left Chest", + "Traverse Town Secret Waterway Near Stairs Chest", + "Wonderland Queen's Castle Hedge Right Blue Chest", + "Wonderland Lotus Forest Nut Chest", + "Wonderland Tea Party Garden Above Lotus Forest Entrance 1st Chest", + "Olympus Coliseum Coliseum Gates Right Blue Trinity Chest", + "Deep Jungle Hippo's Lagoon Center Chest", + "Deep Jungle Vines 2 Chest", + "Deep Jungle Waterfall Cavern Middle Chest", + "Deep Jungle Camp Blue Trinity Chest", + "Agrabah Cave of Wonders Treasure Room Across Platforms Chest", + "Halloween Town Oogie's Manor Hollow Chest", + "Neverland Pirate Ship Deck White Trinity Chest", + "Agrabah Cave of Wonders Hidden Room Left Chest", + "Agrabah Cave of Wonders Entrance Tall Tower Chest", + "Agrabah Palace Gates High Opposite Palace Chest", + "Monstro Chamber 3 Platform Above Chamber 2 Entrance Chest", + "Wonderland Lotus Forest Through the Painting Thunder Plant Chest", + "Hollow Bastion Grand Hall Left of Gate Chest", + "Halloween Town Cemetery By Cat Shape Chest", + "Halloween Town Moonlight Hill White Trinity Chest", + "Halloween Town Guillotine Square Pumpkin Structure Right Chest", + "Monstro Mouth High Platform Across from Boat Chest", + "Monstro Chamber 6 Low Chest", + "Monstro Chamber 5 Atop Barrel Chest", + "Neverland Hold Flight 1st Chest", + "Neverland Hold Yellow Trinity Green Chest", + "Neverland Captain's Cabin Chest", + "Hollow Bastion Rising Falls Floating Platform Near Save Chest", + "Hollow Bastion Castle Gates Gravity Chest", + "Hollow Bastion Lift Stop Outside Library Gravity Chest" + ] +CHAR_TO_KH = { + " ": 0x01, + "0": 0x21, + "1": 0x22, + "2": 0x23, + "3": 0x24, + "4": 0x25, + "5": 0x26, + "6": 0x27, + "7": 0x28, + "8": 0x29, + "9": 0x2A, + "A": 0x2B, + "B": 0x2C, + "C": 0x2D, + "D": 0x2E, + "E": 0x2F, + "F": 0x30, + "G": 0x31, + "H": 0x32, + "I": 0x33, + "J": 0x34, + "K": 0x35, + "L": 0x36, + "M": 0x37, + "N": 0x38, + "O": 0x39, + "P": 0x3A, + "Q": 0x3B, + "R": 0x3C, + "S": 0x3D, + "T": 0x3E, + "U": 0x3F, + "V": 0x40, + "W": 0x41, + "X": 0x42, + "Y": 0x43, + "Z": 0x44, + "a": 0x45, + "b": 0x46, + "c": 0x47, + "d": 0x48, + "e": 0x49, + "f": 0x4A, + "g": 0x4B, + "h": 0x4C, + "i": 0x4D, + "j": 0x4E, + "k": 0x4F, + "l": 0x50, + "m": 0x51, + "n": 0x52, + "o": 0x53, + "p": 0x54, + "q": 0x55, + "r": 0x56, + "s": 0x57, + "t": 0x58, + "u": 0x59, + "v": 0x5A, + "w": 0x5B, + "x": 0x5C, + "y": 0x5D, + "z": 0x5E + } +VANILLA_ABILITY_AP_COSTS = [ + {"Ability Name": "Treasure Magnet", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Combo Plus", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Air Combo Plus", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Critical Plus", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Second Wind", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Scan", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Sonic Blade", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Ars Arcanum", "AP Cost": 4, "Randomize": True}, + {"Ability Name": "Strike Raid", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Ragnarok", "AP Cost": 4, "Randomize": True}, + {"Ability Name": "Trinity Limit", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Cheer", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Vortex", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Aerial Sweep", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Counter Attack", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Blitz", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Guard", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Dodge Roll", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "MP Haste", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "MP Rage", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Second Chance", "AP Cost": 5, "Randomize": True}, + {"Ability Name": "Berserk", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Jackpot", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Lucky Strike", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Charge", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Rocket", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Tornado", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "MP Gift", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Raging Boar", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Asp's Bite", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Healing Herb", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Wind Armor", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Crescent", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Sandstorm", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Applause!", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Blazing Fury", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Icy Terror", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Bolts of Sorrow", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Ghostly Scream", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Hummingbird", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Time-Out", "AP Cost": 4, "Randomize": True}, + {"Ability Name": "Storm´s Eye", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Ferocious Lunge", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Furious Bellow", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Spiral Wave", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Thunder Potion", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Cure Potion", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Aero Potion", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Slapshot", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Sliding Dash", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Hurricane Blast", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Ripple Drive", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "Stun Impact", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Gravity Break", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Zantetsuken", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Tech Boost", "AP Cost": 2, "Randomize": True}, + {"Ability Name": "Encounter Plus", "AP Cost": 1, "Randomize": True}, + {"Ability Name": "Leaf Bracer", "AP Cost": 5, "Randomize": True}, + {"Ability Name": "Evolution", "AP Cost": 3, "Randomize": True}, + {"Ability Name": "EXP Zero", "AP Cost": 0, "Randomize": True}, + {"Ability Name": "Combo Master", "AP Cost": 3, "Randomize": True} + ] + +WORLD_KEY_ITEMS = { + "Footprints": "Wonderland", + "Entry Pass": "Olympus Coliseum", + "Slides": "Deep Jungle", + "Crystal Trident": "Atlantica", + "Forget-Me-Not": "Halloween Town", + "Jack-In-The-Box": "Halloween Town", + "Theon Vol. 6": "Hollow Bastion" +} + +LOGIC_BEGINNER = 0 +LOGIC_NORMAL = 5 +LOGIC_PROUD = 10 +LOGIC_MINIMAL = 15 \ No newline at end of file diff --git a/worlds/kh1/GenerateJSON.py b/worlds/kh1/GenerateJSON.py new file mode 100644 index 000000000000..fdd8f215d0ef --- /dev/null +++ b/worlds/kh1/GenerateJSON.py @@ -0,0 +1,67 @@ +import logging + +import yaml +import os +import io +from typing import TYPE_CHECKING, Dict, List, Optional, cast +import Utils +import zipfile +import json + +from .Locations import KH1Location, location_table + +from worlds.Files import APPlayerContainer + + + +class KH1Container(APPlayerContainer): + game: str = 'Kingdom Hearts' + patch_file_ending = ".zip" + + def __init__(self, patch_data: Dict[str, str] | io.BytesIO, base_path: str = "", output_directory: str = "", + player: Optional[int] = None, player_name: str = "", server: str = ""): + self.patch_data = patch_data + self.file_path = base_path + container_path = os.path.join(output_directory, base_path + ".zip") + super().__init__(container_path, player, player_name, server) + + def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None: + for filename, text in self.patch_data.items(): + opened_zipfile.writestr(filename, text) + super().write_contents(opened_zipfile) + + +def generate_json(world, output_directory): + mod_name = f"AP-{world.multiworld.seed_name}-P{world.player}-{world.multiworld.get_file_safe_player_name(world.player)}" + mod_dir = os.path.join(output_directory, mod_name + "_" + Utils.__version__) + + item_location_map = get_item_location_map(world) + settings = get_settings(world) + + files = { + "item_location_map.json": json.dumps(item_location_map), + "keyblade_stats.json": json.dumps(world.get_keyblade_stats()), + "settings.json": json.dumps(settings), + "ap_costs.json": json.dumps(world.get_ap_costs()) + } + + mod = KH1Container(files, mod_dir, output_directory, world.player, + world.multiworld.get_file_safe_player_name(world.player)) + mod.write() + +def get_item_location_map(world): + location_item_map = {} + for location in world.multiworld.get_filled_locations(world.player): + if location.name != "Final Ansem": + if world.player != location.item.player or (world.player == location.item.player and world.options.remote_items.current_key == "full" and (location_table[location.name].code < 2656800 or location_table[location.name].code > 2656814)): + item_id = 2641230 + else: + item_id = location.item.code + location_data = location_table[location.name] + location_id = location_data.code + location_item_map[location_id] = item_id + return location_item_map + +def get_settings(world): + settings = world.fill_slot_data() + return settings \ No newline at end of file diff --git a/worlds/kh1/Items.py b/worlds/kh1/Items.py index bac98a9b3284..c453d9042f71 100644 --- a/worlds/kh1/Items.py +++ b/worlds/kh1/Items.py @@ -10,518 +10,341 @@ class KH1Item(Item): class KH1ItemData(NamedTuple): category: str code: int + type: str classification: ItemClassification = ItemClassification.filler max_quantity: int = 1 weight: int = 1 def get_items_by_category(category: str) -> Dict[str, KH1ItemData]: - item_dict: Dict[str, KH1ItemData] = {} - for name, data in item_table.items(): - if data.category == category: - item_dict.setdefault(name, data) - - return item_dict - + return {name: data for name, data in item_table.items() if data.category == category} item_table: Dict[str, KH1ItemData] = { - "Victory": KH1ItemData("VIC", code = 264_0000, classification = ItemClassification.progression, ), - "Potion": KH1ItemData("Item", code = 264_1001, classification = ItemClassification.filler, ), - "Hi-Potion": KH1ItemData("Item", code = 264_1002, classification = ItemClassification.filler, ), - "Ether": KH1ItemData("Item", code = 264_1003, classification = ItemClassification.filler, ), - "Elixir": KH1ItemData("Item", code = 264_1004, classification = ItemClassification.filler, ), - #"B05": KH1ItemData("Item", code = 264_1005, classification = ItemClassification.filler, ), - "Mega-Potion": KH1ItemData("Item", code = 264_1006, classification = ItemClassification.filler, ), - "Mega-Ether": KH1ItemData("Item", code = 264_1007, classification = ItemClassification.filler, ), - "Megalixir": KH1ItemData("Item", code = 264_1008, classification = ItemClassification.filler, ), - #"Fury Stone": KH1ItemData("Synthesis", code = 264_1009, classification = ItemClassification.filler, ), - #"Power Stone": KH1ItemData("Synthesis", code = 264_1010, classification = ItemClassification.filler, ), - #"Energy Stone": KH1ItemData("Synthesis", code = 264_1011, classification = ItemClassification.filler, ), - #"Blazing Stone": KH1ItemData("Synthesis", code = 264_1012, classification = ItemClassification.filler, ), - #"Frost Stone": KH1ItemData("Synthesis", code = 264_1013, classification = ItemClassification.filler, ), - #"Lightning Stone": KH1ItemData("Synthesis", code = 264_1014, classification = ItemClassification.filler, ), - #"Dazzling Stone": KH1ItemData("Synthesis", code = 264_1015, classification = ItemClassification.filler, ), - #"Stormy Stone": KH1ItemData("Synthesis", code = 264_1016, classification = ItemClassification.filler, ), - "Protect Chain": KH1ItemData("Accessory", code = 264_1017, classification = ItemClassification.useful, ), - "Protera Chain": KH1ItemData("Accessory", code = 264_1018, classification = ItemClassification.useful, ), - "Protega Chain": KH1ItemData("Accessory", code = 264_1019, classification = ItemClassification.useful, ), - "Fire Ring": KH1ItemData("Accessory", code = 264_1020, classification = ItemClassification.useful, ), - "Fira Ring": KH1ItemData("Accessory", code = 264_1021, classification = ItemClassification.useful, ), - "Firaga Ring": KH1ItemData("Accessory", code = 264_1022, classification = ItemClassification.useful, ), - "Blizzard Ring": KH1ItemData("Accessory", code = 264_1023, classification = ItemClassification.useful, ), - "Blizzara Ring": KH1ItemData("Accessory", code = 264_1024, classification = ItemClassification.useful, ), - "Blizzaga Ring": KH1ItemData("Accessory", code = 264_1025, classification = ItemClassification.useful, ), - "Thunder Ring": KH1ItemData("Accessory", code = 264_1026, classification = ItemClassification.useful, ), - "Thundara Ring": KH1ItemData("Accessory", code = 264_1027, classification = ItemClassification.useful, ), - "Thundaga Ring": KH1ItemData("Accessory", code = 264_1028, classification = ItemClassification.useful, ), - "Ability Stud": KH1ItemData("Accessory", code = 264_1029, classification = ItemClassification.useful, ), - "Guard Earring": KH1ItemData("Accessory", code = 264_1030, classification = ItemClassification.useful, ), - "Master Earring": KH1ItemData("Accessory", code = 264_1031, classification = ItemClassification.useful, ), - "Chaos Ring": KH1ItemData("Accessory", code = 264_1032, classification = ItemClassification.useful, ), - "Dark Ring": KH1ItemData("Accessory", code = 264_1033, classification = ItemClassification.useful, ), - "Element Ring": KH1ItemData("Accessory", code = 264_1034, classification = ItemClassification.useful, ), - "Three Stars": KH1ItemData("Accessory", code = 264_1035, classification = ItemClassification.useful, ), - "Power Chain": KH1ItemData("Accessory", code = 264_1036, classification = ItemClassification.useful, ), - "Golem Chain": KH1ItemData("Accessory", code = 264_1037, classification = ItemClassification.useful, ), - "Titan Chain": KH1ItemData("Accessory", code = 264_1038, classification = ItemClassification.useful, ), - "Energy Bangle": KH1ItemData("Accessory", code = 264_1039, classification = ItemClassification.useful, ), - "Angel Bangle": KH1ItemData("Accessory", code = 264_1040, classification = ItemClassification.useful, ), - "Gaia Bangle": KH1ItemData("Accessory", code = 264_1041, classification = ItemClassification.useful, ), - "Magic Armlet": KH1ItemData("Accessory", code = 264_1042, classification = ItemClassification.useful, ), - "Rune Armlet": KH1ItemData("Accessory", code = 264_1043, classification = ItemClassification.useful, ), - "Atlas Armlet": KH1ItemData("Accessory", code = 264_1044, classification = ItemClassification.useful, ), - "Heartguard": KH1ItemData("Accessory", code = 264_1045, classification = ItemClassification.useful, ), - "Ribbon": KH1ItemData("Accessory", code = 264_1046, classification = ItemClassification.useful, ), - "Crystal Crown": KH1ItemData("Accessory", code = 264_1047, classification = ItemClassification.useful, ), - "Brave Warrior": KH1ItemData("Accessory", code = 264_1048, classification = ItemClassification.useful, ), - "Ifrit's Horn": KH1ItemData("Accessory", code = 264_1049, classification = ItemClassification.useful, ), - "Inferno Band": KH1ItemData("Accessory", code = 264_1050, classification = ItemClassification.useful, ), - "White Fang": KH1ItemData("Accessory", code = 264_1051, classification = ItemClassification.useful, ), - "Ray of Light": KH1ItemData("Accessory", code = 264_1052, classification = ItemClassification.useful, ), - "Holy Circlet": KH1ItemData("Accessory", code = 264_1053, classification = ItemClassification.useful, ), - "Raven's Claw": KH1ItemData("Accessory", code = 264_1054, classification = ItemClassification.useful, ), - "Omega Arts": KH1ItemData("Accessory", code = 264_1055, classification = ItemClassification.useful, ), - "EXP Earring": KH1ItemData("Accessory", code = 264_1056, classification = ItemClassification.useful, ), - #"A41": KH1ItemData("Accessory", code = 264_1057, classification = ItemClassification.useful, ), - "EXP Ring": KH1ItemData("Accessory", code = 264_1058, classification = ItemClassification.useful, ), - "EXP Bracelet": KH1ItemData("Accessory", code = 264_1059, classification = ItemClassification.useful, ), - "EXP Necklace": KH1ItemData("Accessory", code = 264_1060, classification = ItemClassification.useful, ), - "Firagun Band": KH1ItemData("Accessory", code = 264_1061, classification = ItemClassification.useful, ), - "Blizzagun Band": KH1ItemData("Accessory", code = 264_1062, classification = ItemClassification.useful, ), - "Thundagun Band": KH1ItemData("Accessory", code = 264_1063, classification = ItemClassification.useful, ), - "Ifrit Belt": KH1ItemData("Accessory", code = 264_1064, classification = ItemClassification.useful, ), - "Shiva Belt": KH1ItemData("Accessory", code = 264_1065, classification = ItemClassification.useful, ), - "Ramuh Belt": KH1ItemData("Accessory", code = 264_1066, classification = ItemClassification.useful, ), - "Moogle Badge": KH1ItemData("Accessory", code = 264_1067, classification = ItemClassification.useful, ), - "Cosmic Arts": KH1ItemData("Accessory", code = 264_1068, classification = ItemClassification.useful, ), - "Royal Crown": KH1ItemData("Accessory", code = 264_1069, classification = ItemClassification.useful, ), - "Prime Cap": KH1ItemData("Accessory", code = 264_1070, classification = ItemClassification.useful, ), - "Obsidian Ring": KH1ItemData("Accessory", code = 264_1071, classification = ItemClassification.useful, ), - #"A56": KH1ItemData("Accessory", code = 264_1072, classification = ItemClassification.filler, ), - #"A57": KH1ItemData("Accessory", code = 264_1073, classification = ItemClassification.filler, ), - #"A58": KH1ItemData("Accessory", code = 264_1074, classification = ItemClassification.filler, ), - #"A59": KH1ItemData("Accessory", code = 264_1075, classification = ItemClassification.filler, ), - #"A60": KH1ItemData("Accessory", code = 264_1076, classification = ItemClassification.filler, ), - #"A61": KH1ItemData("Accessory", code = 264_1077, classification = ItemClassification.filler, ), - #"A62": KH1ItemData("Accessory", code = 264_1078, classification = ItemClassification.filler, ), - #"A63": KH1ItemData("Accessory", code = 264_1079, classification = ItemClassification.filler, ), - #"A64": KH1ItemData("Accessory", code = 264_1080, classification = ItemClassification.filler, ), - #"Kingdom Key": KH1ItemData("Keyblades", code = 264_1081, classification = ItemClassification.useful, ), - #"Dream Sword": KH1ItemData("Keyblades", code = 264_1082, classification = ItemClassification.useful, ), - #"Dream Shield": KH1ItemData("Keyblades", code = 264_1083, classification = ItemClassification.useful, ), - #"Dream Rod": KH1ItemData("Keyblades", code = 264_1084, classification = ItemClassification.useful, ), - "Wooden Sword": KH1ItemData("Keyblades", code = 264_1085, classification = ItemClassification.useful, ), - "Jungle King": KH1ItemData("Keyblades", code = 264_1086, classification = ItemClassification.progression, ), - "Three Wishes": KH1ItemData("Keyblades", code = 264_1087, classification = ItemClassification.progression, ), - "Fairy Harp": KH1ItemData("Keyblades", code = 264_1088, classification = ItemClassification.progression, ), - "Pumpkinhead": KH1ItemData("Keyblades", code = 264_1089, classification = ItemClassification.progression, ), - "Crabclaw": KH1ItemData("Keyblades", code = 264_1090, classification = ItemClassification.useful, ), - "Divine Rose": KH1ItemData("Keyblades", code = 264_1091, classification = ItemClassification.progression, ), - "Spellbinder": KH1ItemData("Keyblades", code = 264_1092, classification = ItemClassification.useful, ), - "Olympia": KH1ItemData("Keyblades", code = 264_1093, classification = ItemClassification.progression, ), - "Lionheart": KH1ItemData("Keyblades", code = 264_1094, classification = ItemClassification.progression, ), - "Metal Chocobo": KH1ItemData("Keyblades", code = 264_1095, classification = ItemClassification.useful, ), - "Oathkeeper": KH1ItemData("Keyblades", code = 264_1096, classification = ItemClassification.progression, ), - "Oblivion": KH1ItemData("Keyblades", code = 264_1097, classification = ItemClassification.progression, ), - "Lady Luck": KH1ItemData("Keyblades", code = 264_1098, classification = ItemClassification.progression, ), - "Wishing Star": KH1ItemData("Keyblades", code = 264_1099, classification = ItemClassification.progression, ), - "Ultima Weapon": KH1ItemData("Keyblades", code = 264_1100, classification = ItemClassification.useful, ), - "Diamond Dust": KH1ItemData("Keyblades", code = 264_1101, classification = ItemClassification.useful, ), - "One-Winged Angel": KH1ItemData("Keyblades", code = 264_1102, classification = ItemClassification.useful, ), - #"Mage's Staff": KH1ItemData("Weapons", code = 264_1103, classification = ItemClassification.filler, ), - "Morning Star": KH1ItemData("Weapons", code = 264_1104, classification = ItemClassification.useful, ), - "Shooting Star": KH1ItemData("Weapons", code = 264_1105, classification = ItemClassification.useful, ), - "Magus Staff": KH1ItemData("Weapons", code = 264_1106, classification = ItemClassification.useful, ), - "Wisdom Staff": KH1ItemData("Weapons", code = 264_1107, classification = ItemClassification.useful, ), - "Warhammer": KH1ItemData("Weapons", code = 264_1108, classification = ItemClassification.useful, ), - "Silver Mallet": KH1ItemData("Weapons", code = 264_1109, classification = ItemClassification.useful, ), - "Grand Mallet": KH1ItemData("Weapons", code = 264_1110, classification = ItemClassification.useful, ), - "Lord Fortune": KH1ItemData("Weapons", code = 264_1111, classification = ItemClassification.useful, ), - "Violetta": KH1ItemData("Weapons", code = 264_1112, classification = ItemClassification.useful, ), - "Dream Rod (Donald)": KH1ItemData("Weapons", code = 264_1113, classification = ItemClassification.useful, ), - "Save the Queen": KH1ItemData("Weapons", code = 264_1114, classification = ItemClassification.useful, ), - "Wizard's Relic": KH1ItemData("Weapons", code = 264_1115, classification = ItemClassification.useful, ), - "Meteor Strike": KH1ItemData("Weapons", code = 264_1116, classification = ItemClassification.useful, ), - "Fantasista": KH1ItemData("Weapons", code = 264_1117, classification = ItemClassification.useful, ), - #"Unused (Donald)": KH1ItemData("Weapons", code = 264_1118, classification = ItemClassification.filler, ), - #"Knight's Shield": KH1ItemData("Weapons", code = 264_1119, classification = ItemClassification.filler, ), - "Mythril Shield": KH1ItemData("Weapons", code = 264_1120, classification = ItemClassification.useful, ), - "Onyx Shield": KH1ItemData("Weapons", code = 264_1121, classification = ItemClassification.useful, ), - "Stout Shield": KH1ItemData("Weapons", code = 264_1122, classification = ItemClassification.useful, ), - "Golem Shield": KH1ItemData("Weapons", code = 264_1123, classification = ItemClassification.useful, ), - "Adamant Shield": KH1ItemData("Weapons", code = 264_1124, classification = ItemClassification.useful, ), - "Smasher": KH1ItemData("Weapons", code = 264_1125, classification = ItemClassification.useful, ), - "Gigas Fist": KH1ItemData("Weapons", code = 264_1126, classification = ItemClassification.useful, ), - "Genji Shield": KH1ItemData("Weapons", code = 264_1127, classification = ItemClassification.useful, ), - "Herc's Shield": KH1ItemData("Weapons", code = 264_1128, classification = ItemClassification.useful, ), - "Dream Shield (Goofy)": KH1ItemData("Weapons", code = 264_1129, classification = ItemClassification.useful, ), - "Save the King": KH1ItemData("Weapons", code = 264_1130, classification = ItemClassification.useful, ), - "Defender": KH1ItemData("Weapons", code = 264_1131, classification = ItemClassification.useful, ), - "Mighty Shield": KH1ItemData("Weapons", code = 264_1132, classification = ItemClassification.useful, ), - "Seven Elements": KH1ItemData("Weapons", code = 264_1133, classification = ItemClassification.useful, ), - #"Unused (Goofy)": KH1ItemData("Weapons", code = 264_1134, classification = ItemClassification.filler, ), - #"Spear": KH1ItemData("Weapons", code = 264_1135, classification = ItemClassification.filler, ), - #"No Weapon": KH1ItemData("Weapons", code = 264_1136, classification = ItemClassification.filler, ), - #"Genie": KH1ItemData("Weapons", code = 264_1137, classification = ItemClassification.filler, ), - #"No Weapon": KH1ItemData("Weapons", code = 264_1138, classification = ItemClassification.filler, ), - #"No Weapon": KH1ItemData("Weapons", code = 264_1139, classification = ItemClassification.filler, ), - #"Tinker Bell": KH1ItemData("Weapons", code = 264_1140, classification = ItemClassification.filler, ), - #"Claws": KH1ItemData("Weapons", code = 264_1141, classification = ItemClassification.filler, ), - "Tent": KH1ItemData("Camping", code = 264_1142, classification = ItemClassification.filler, ), - "Camping Set": KH1ItemData("Camping", code = 264_1143, classification = ItemClassification.filler, ), - "Cottage": KH1ItemData("Camping", code = 264_1144, classification = ItemClassification.filler, ), - #"C04": KH1ItemData("Camping", code = 264_1145, classification = ItemClassification.filler, ), - #"C05": KH1ItemData("Camping", code = 264_1146, classification = ItemClassification.filler, ), - #"C06": KH1ItemData("Camping", code = 264_1147, classification = ItemClassification.filler, ), - #"C07": KH1ItemData("Camping", code = 264_1148, classification = ItemClassification.filler, ), - "Ansem's Report 11": KH1ItemData("Reports", code = 264_1149, classification = ItemClassification.progression, ), - "Ansem's Report 12": KH1ItemData("Reports", code = 264_1150, classification = ItemClassification.progression, ), - "Ansem's Report 13": KH1ItemData("Reports", code = 264_1151, classification = ItemClassification.progression, ), - "Power Up": KH1ItemData("Stat Ups", code = 264_1152, classification = ItemClassification.filler, ), - "Defense Up": KH1ItemData("Stat Ups", code = 264_1153, classification = ItemClassification.filler, ), - "AP Up": KH1ItemData("Stat Ups", code = 264_1154, classification = ItemClassification.filler, ), - #"Serenity Power": KH1ItemData("Synthesis", code = 264_1155, classification = ItemClassification.filler, ), - #"Dark Matter": KH1ItemData("Synthesis", code = 264_1156, classification = ItemClassification.filler, ), - #"Mythril Stone": KH1ItemData("Synthesis", code = 264_1157, classification = ItemClassification.filler, ), - "Fire Arts": KH1ItemData("Key", code = 264_1158, classification = ItemClassification.progression, ), - "Blizzard Arts": KH1ItemData("Key", code = 264_1159, classification = ItemClassification.progression, ), - "Thunder Arts": KH1ItemData("Key", code = 264_1160, classification = ItemClassification.progression, ), - "Cure Arts": KH1ItemData("Key", code = 264_1161, classification = ItemClassification.progression, ), - "Gravity Arts": KH1ItemData("Key", code = 264_1162, classification = ItemClassification.progression, ), - "Stop Arts": KH1ItemData("Key", code = 264_1163, classification = ItemClassification.progression, ), - "Aero Arts": KH1ItemData("Key", code = 264_1164, classification = ItemClassification.progression, ), - #"Shiitank Rank": KH1ItemData("Synthesis", code = 264_1165, classification = ItemClassification.filler, ), - #"Matsutake Rank": KH1ItemData("Synthesis", code = 264_1166, classification = ItemClassification.filler, ), - #"Mystery Mold": KH1ItemData("Synthesis", code = 264_1167, classification = ItemClassification.filler, ), - "Ansem's Report 1": KH1ItemData("Reports", code = 264_1168, classification = ItemClassification.progression, ), - "Ansem's Report 2": KH1ItemData("Reports", code = 264_1169, classification = ItemClassification.progression, ), - "Ansem's Report 3": KH1ItemData("Reports", code = 264_1170, classification = ItemClassification.progression, ), - "Ansem's Report 4": KH1ItemData("Reports", code = 264_1171, classification = ItemClassification.progression, ), - "Ansem's Report 5": KH1ItemData("Reports", code = 264_1172, classification = ItemClassification.progression, ), - "Ansem's Report 6": KH1ItemData("Reports", code = 264_1173, classification = ItemClassification.progression, ), - "Ansem's Report 7": KH1ItemData("Reports", code = 264_1174, classification = ItemClassification.progression, ), - "Ansem's Report 8": KH1ItemData("Reports", code = 264_1175, classification = ItemClassification.progression, ), - "Ansem's Report 9": KH1ItemData("Reports", code = 264_1176, classification = ItemClassification.progression, ), - "Ansem's Report 10": KH1ItemData("Reports", code = 264_1177, classification = ItemClassification.progression, ), - #"Khama Vol. 8": KH1ItemData("Key", code = 264_1178, classification = ItemClassification.progression, ), - #"Salegg Vol. 6": KH1ItemData("Key", code = 264_1179, classification = ItemClassification.progression, ), - #"Azal Vol. 3": KH1ItemData("Key", code = 264_1180, classification = ItemClassification.progression, ), - #"Mava Vol. 3": KH1ItemData("Key", code = 264_1181, classification = ItemClassification.progression, ), - #"Mava Vol. 6": KH1ItemData("Key", code = 264_1182, classification = ItemClassification.progression, ), - "Theon Vol. 6": KH1ItemData("Key", code = 264_1183, classification = ItemClassification.progression, ), - #"Nahara Vol. 5": KH1ItemData("Key", code = 264_1184, classification = ItemClassification.progression, ), - #"Hafet Vol. 4": KH1ItemData("Key", code = 264_1185, classification = ItemClassification.progression, ), - "Empty Bottle": KH1ItemData("Key", code = 264_1186, classification = ItemClassification.progression, max_quantity = 6 ), - #"Old Book": KH1ItemData("Key", code = 264_1187, classification = ItemClassification.progression, ), - "Emblem Piece (Flame)": KH1ItemData("Key", code = 264_1188, classification = ItemClassification.progression, ), - "Emblem Piece (Chest)": KH1ItemData("Key", code = 264_1189, classification = ItemClassification.progression, ), - "Emblem Piece (Statue)": KH1ItemData("Key", code = 264_1190, classification = ItemClassification.progression, ), - "Emblem Piece (Fountain)": KH1ItemData("Key", code = 264_1191, classification = ItemClassification.progression, ), - #"Log": KH1ItemData("Key", code = 264_1192, classification = ItemClassification.progression, ), - #"Cloth": KH1ItemData("Key", code = 264_1193, classification = ItemClassification.progression, ), - #"Rope": KH1ItemData("Key", code = 264_1194, classification = ItemClassification.progression, ), - #"Seagull Egg": KH1ItemData("Key", code = 264_1195, classification = ItemClassification.progression, ), - #"Fish": KH1ItemData("Key", code = 264_1196, classification = ItemClassification.progression, ), - #"Mushroom": KH1ItemData("Key", code = 264_1197, classification = ItemClassification.progression, ), - #"Coconut": KH1ItemData("Key", code = 264_1198, classification = ItemClassification.progression, ), - #"Drinking Water": KH1ItemData("Key", code = 264_1199, classification = ItemClassification.progression, ), - #"Navi-G Piece 1": KH1ItemData("Key", code = 264_1200, classification = ItemClassification.progression, ), - #"Navi-G Piece 2": KH1ItemData("Key", code = 264_1201, classification = ItemClassification.progression, ), - #"Navi-Gummi Unused": KH1ItemData("Key", code = 264_1202, classification = ItemClassification.progression, ), - #"Navi-G Piece 3": KH1ItemData("Key", code = 264_1203, classification = ItemClassification.progression, ), - #"Navi-G Piece 4": KH1ItemData("Key", code = 264_1204, classification = ItemClassification.progression, ), - #"Navi-Gummi": KH1ItemData("Key", code = 264_1205, classification = ItemClassification.progression, ), - #"Watergleam": KH1ItemData("Key", code = 264_1206, classification = ItemClassification.progression, ), - #"Naturespark": KH1ItemData("Key", code = 264_1207, classification = ItemClassification.progression, ), - #"Fireglow": KH1ItemData("Key", code = 264_1208, classification = ItemClassification.progression, ), - #"Earthshine": KH1ItemData("Key", code = 264_1209, classification = ItemClassification.progression, ), - "Crystal Trident": KH1ItemData("Key", code = 264_1210, classification = ItemClassification.progression, ), - "Postcard": KH1ItemData("Key", code = 264_1211, classification = ItemClassification.progression, max_quantity = 10), - "Torn Page 1": KH1ItemData("Torn Pages", code = 264_1212, classification = ItemClassification.progression, ), - "Torn Page 2": KH1ItemData("Torn Pages", code = 264_1213, classification = ItemClassification.progression, ), - "Torn Page 3": KH1ItemData("Torn Pages", code = 264_1214, classification = ItemClassification.progression, ), - "Torn Page 4": KH1ItemData("Torn Pages", code = 264_1215, classification = ItemClassification.progression, ), - "Torn Page 5": KH1ItemData("Torn Pages", code = 264_1216, classification = ItemClassification.progression, ), - "Slides": KH1ItemData("Key", code = 264_1217, classification = ItemClassification.progression, ), - #"Slide 2": KH1ItemData("Key", code = 264_1218, classification = ItemClassification.progression, ), - #"Slide 3": KH1ItemData("Key", code = 264_1219, classification = ItemClassification.progression, ), - #"Slide 4": KH1ItemData("Key", code = 264_1220, classification = ItemClassification.progression, ), - #"Slide 5": KH1ItemData("Key", code = 264_1221, classification = ItemClassification.progression, ), - #"Slide 6": KH1ItemData("Key", code = 264_1222, classification = ItemClassification.progression, ), - "Footprints": KH1ItemData("Key", code = 264_1223, classification = ItemClassification.progression, ), - #"Claw Marks": KH1ItemData("Key", code = 264_1224, classification = ItemClassification.progression, ), - #"Stench": KH1ItemData("Key", code = 264_1225, classification = ItemClassification.progression, ), - #"Antenna": KH1ItemData("Key", code = 264_1226, classification = ItemClassification.progression, ), - "Forget-Me-Not": KH1ItemData("Key", code = 264_1227, classification = ItemClassification.progression, ), - "Jack-In-The-Box": KH1ItemData("Key", code = 264_1228, classification = ItemClassification.progression, ), - "Entry Pass": KH1ItemData("Key", code = 264_1229, classification = ItemClassification.progression, ), - #"Hero License": KH1ItemData("Key", code = 264_1230, classification = ItemClassification.progression, ), - #"Pretty Stone": KH1ItemData("Synthesis", code = 264_1231, classification = ItemClassification.filler, ), - #"N41": KH1ItemData("Synthesis", code = 264_1232, classification = ItemClassification.filler, ), - #"Lucid Shard": KH1ItemData("Synthesis", code = 264_1233, classification = ItemClassification.filler, ), - #"Lucid Gem": KH1ItemData("Synthesis", code = 264_1234, classification = ItemClassification.filler, ), - #"Lucid Crystal": KH1ItemData("Synthesis", code = 264_1235, classification = ItemClassification.filler, ), - #"Spirit Shard": KH1ItemData("Synthesis", code = 264_1236, classification = ItemClassification.filler, ), - #"Spirit Gem": KH1ItemData("Synthesis", code = 264_1237, classification = ItemClassification.filler, ), - #"Power Shard": KH1ItemData("Synthesis", code = 264_1238, classification = ItemClassification.filler, ), - #"Power Gem": KH1ItemData("Synthesis", code = 264_1239, classification = ItemClassification.filler, ), - #"Power Crystal": KH1ItemData("Synthesis", code = 264_1240, classification = ItemClassification.filler, ), - #"Blaze Shard": KH1ItemData("Synthesis", code = 264_1241, classification = ItemClassification.filler, ), - #"Blaze Gem": KH1ItemData("Synthesis", code = 264_1242, classification = ItemClassification.filler, ), - #"Frost Shard": KH1ItemData("Synthesis", code = 264_1243, classification = ItemClassification.filler, ), - #"Frost Gem": KH1ItemData("Synthesis", code = 264_1244, classification = ItemClassification.filler, ), - #"Thunder Shard": KH1ItemData("Synthesis", code = 264_1245, classification = ItemClassification.filler, ), - #"Thunder Gem": KH1ItemData("Synthesis", code = 264_1246, classification = ItemClassification.filler, ), - #"Shiny Crystal": KH1ItemData("Synthesis", code = 264_1247, classification = ItemClassification.filler, ), - #"Bright Shard": KH1ItemData("Synthesis", code = 264_1248, classification = ItemClassification.filler, ), - #"Bright Gem": KH1ItemData("Synthesis", code = 264_1249, classification = ItemClassification.filler, ), - #"Bright Crystal": KH1ItemData("Synthesis", code = 264_1250, classification = ItemClassification.filler, ), - #"Mystery Goo": KH1ItemData("Synthesis", code = 264_1251, classification = ItemClassification.filler, ), - #"Gale": KH1ItemData("Synthesis", code = 264_1252, classification = ItemClassification.filler, ), - #"Mythril Shard": KH1ItemData("Synthesis", code = 264_1253, classification = ItemClassification.filler, ), - #"Mythril": KH1ItemData("Synthesis", code = 264_1254, classification = ItemClassification.filler, ), - #"Orichalcum": KH1ItemData("Synthesis", code = 264_1255, classification = ItemClassification.filler, ), - "High Jump": KH1ItemData("Shared Abilities", code = 264_2001, classification = ItemClassification.progression, ), - "Mermaid Kick": KH1ItemData("Shared Abilities", code = 264_2002, classification = ItemClassification.progression, ), - "Progressive Glide": KH1ItemData("Shared Abilities", code = 264_2003, classification = ItemClassification.progression, max_quantity = 2 ), - #"Superglide": KH1ItemData("Shared Abilities", code = 264_2004, classification = ItemClassification.progression, ), - "Puppy 01": KH1ItemData("Puppies", code = 264_2101, classification = ItemClassification.progression, ), - "Puppy 02": KH1ItemData("Puppies", code = 264_2102, classification = ItemClassification.progression, ), - "Puppy 03": KH1ItemData("Puppies", code = 264_2103, classification = ItemClassification.progression, ), - "Puppy 04": KH1ItemData("Puppies", code = 264_2104, classification = ItemClassification.progression, ), - "Puppy 05": KH1ItemData("Puppies", code = 264_2105, classification = ItemClassification.progression, ), - "Puppy 06": KH1ItemData("Puppies", code = 264_2106, classification = ItemClassification.progression, ), - "Puppy 07": KH1ItemData("Puppies", code = 264_2107, classification = ItemClassification.progression, ), - "Puppy 08": KH1ItemData("Puppies", code = 264_2108, classification = ItemClassification.progression, ), - "Puppy 09": KH1ItemData("Puppies", code = 264_2109, classification = ItemClassification.progression, ), - "Puppy 10": KH1ItemData("Puppies", code = 264_2110, classification = ItemClassification.progression, ), - "Puppy 11": KH1ItemData("Puppies", code = 264_2111, classification = ItemClassification.progression, ), - "Puppy 12": KH1ItemData("Puppies", code = 264_2112, classification = ItemClassification.progression, ), - "Puppy 13": KH1ItemData("Puppies", code = 264_2113, classification = ItemClassification.progression, ), - "Puppy 14": KH1ItemData("Puppies", code = 264_2114, classification = ItemClassification.progression, ), - "Puppy 15": KH1ItemData("Puppies", code = 264_2115, classification = ItemClassification.progression, ), - "Puppy 16": KH1ItemData("Puppies", code = 264_2116, classification = ItemClassification.progression, ), - "Puppy 17": KH1ItemData("Puppies", code = 264_2117, classification = ItemClassification.progression, ), - "Puppy 18": KH1ItemData("Puppies", code = 264_2118, classification = ItemClassification.progression, ), - "Puppy 19": KH1ItemData("Puppies", code = 264_2119, classification = ItemClassification.progression, ), - "Puppy 20": KH1ItemData("Puppies", code = 264_2120, classification = ItemClassification.progression, ), - "Puppy 21": KH1ItemData("Puppies", code = 264_2121, classification = ItemClassification.progression, ), - "Puppy 22": KH1ItemData("Puppies", code = 264_2122, classification = ItemClassification.progression, ), - "Puppy 23": KH1ItemData("Puppies", code = 264_2123, classification = ItemClassification.progression, ), - "Puppy 24": KH1ItemData("Puppies", code = 264_2124, classification = ItemClassification.progression, ), - "Puppy 25": KH1ItemData("Puppies", code = 264_2125, classification = ItemClassification.progression, ), - "Puppy 26": KH1ItemData("Puppies", code = 264_2126, classification = ItemClassification.progression, ), - "Puppy 27": KH1ItemData("Puppies", code = 264_2127, classification = ItemClassification.progression, ), - "Puppy 28": KH1ItemData("Puppies", code = 264_2128, classification = ItemClassification.progression, ), - "Puppy 29": KH1ItemData("Puppies", code = 264_2129, classification = ItemClassification.progression, ), - "Puppy 30": KH1ItemData("Puppies", code = 264_2130, classification = ItemClassification.progression, ), - "Puppy 31": KH1ItemData("Puppies", code = 264_2131, classification = ItemClassification.progression, ), - "Puppy 32": KH1ItemData("Puppies", code = 264_2132, classification = ItemClassification.progression, ), - "Puppy 33": KH1ItemData("Puppies", code = 264_2133, classification = ItemClassification.progression, ), - "Puppy 34": KH1ItemData("Puppies", code = 264_2134, classification = ItemClassification.progression, ), - "Puppy 35": KH1ItemData("Puppies", code = 264_2135, classification = ItemClassification.progression, ), - "Puppy 36": KH1ItemData("Puppies", code = 264_2136, classification = ItemClassification.progression, ), - "Puppy 37": KH1ItemData("Puppies", code = 264_2137, classification = ItemClassification.progression, ), - "Puppy 38": KH1ItemData("Puppies", code = 264_2138, classification = ItemClassification.progression, ), - "Puppy 39": KH1ItemData("Puppies", code = 264_2139, classification = ItemClassification.progression, ), - "Puppy 40": KH1ItemData("Puppies", code = 264_2140, classification = ItemClassification.progression, ), - "Puppy 41": KH1ItemData("Puppies", code = 264_2141, classification = ItemClassification.progression, ), - "Puppy 42": KH1ItemData("Puppies", code = 264_2142, classification = ItemClassification.progression, ), - "Puppy 43": KH1ItemData("Puppies", code = 264_2143, classification = ItemClassification.progression, ), - "Puppy 44": KH1ItemData("Puppies", code = 264_2144, classification = ItemClassification.progression, ), - "Puppy 45": KH1ItemData("Puppies", code = 264_2145, classification = ItemClassification.progression, ), - "Puppy 46": KH1ItemData("Puppies", code = 264_2146, classification = ItemClassification.progression, ), - "Puppy 47": KH1ItemData("Puppies", code = 264_2147, classification = ItemClassification.progression, ), - "Puppy 48": KH1ItemData("Puppies", code = 264_2148, classification = ItemClassification.progression, ), - "Puppy 49": KH1ItemData("Puppies", code = 264_2149, classification = ItemClassification.progression, ), - "Puppy 50": KH1ItemData("Puppies", code = 264_2150, classification = ItemClassification.progression, ), - "Puppy 51": KH1ItemData("Puppies", code = 264_2151, classification = ItemClassification.progression, ), - "Puppy 52": KH1ItemData("Puppies", code = 264_2152, classification = ItemClassification.progression, ), - "Puppy 53": KH1ItemData("Puppies", code = 264_2153, classification = ItemClassification.progression, ), - "Puppy 54": KH1ItemData("Puppies", code = 264_2154, classification = ItemClassification.progression, ), - "Puppy 55": KH1ItemData("Puppies", code = 264_2155, classification = ItemClassification.progression, ), - "Puppy 56": KH1ItemData("Puppies", code = 264_2156, classification = ItemClassification.progression, ), - "Puppy 57": KH1ItemData("Puppies", code = 264_2157, classification = ItemClassification.progression, ), - "Puppy 58": KH1ItemData("Puppies", code = 264_2158, classification = ItemClassification.progression, ), - "Puppy 59": KH1ItemData("Puppies", code = 264_2159, classification = ItemClassification.progression, ), - "Puppy 60": KH1ItemData("Puppies", code = 264_2160, classification = ItemClassification.progression, ), - "Puppy 61": KH1ItemData("Puppies", code = 264_2161, classification = ItemClassification.progression, ), - "Puppy 62": KH1ItemData("Puppies", code = 264_2162, classification = ItemClassification.progression, ), - "Puppy 63": KH1ItemData("Puppies", code = 264_2163, classification = ItemClassification.progression, ), - "Puppy 64": KH1ItemData("Puppies", code = 264_2164, classification = ItemClassification.progression, ), - "Puppy 65": KH1ItemData("Puppies", code = 264_2165, classification = ItemClassification.progression, ), - "Puppy 66": KH1ItemData("Puppies", code = 264_2166, classification = ItemClassification.progression, ), - "Puppy 67": KH1ItemData("Puppies", code = 264_2167, classification = ItemClassification.progression, ), - "Puppy 68": KH1ItemData("Puppies", code = 264_2168, classification = ItemClassification.progression, ), - "Puppy 69": KH1ItemData("Puppies", code = 264_2169, classification = ItemClassification.progression, ), - "Puppy 70": KH1ItemData("Puppies", code = 264_2170, classification = ItemClassification.progression, ), - "Puppy 71": KH1ItemData("Puppies", code = 264_2171, classification = ItemClassification.progression, ), - "Puppy 72": KH1ItemData("Puppies", code = 264_2172, classification = ItemClassification.progression, ), - "Puppy 73": KH1ItemData("Puppies", code = 264_2173, classification = ItemClassification.progression, ), - "Puppy 74": KH1ItemData("Puppies", code = 264_2174, classification = ItemClassification.progression, ), - "Puppy 75": KH1ItemData("Puppies", code = 264_2175, classification = ItemClassification.progression, ), - "Puppy 76": KH1ItemData("Puppies", code = 264_2176, classification = ItemClassification.progression, ), - "Puppy 77": KH1ItemData("Puppies", code = 264_2177, classification = ItemClassification.progression, ), - "Puppy 78": KH1ItemData("Puppies", code = 264_2178, classification = ItemClassification.progression, ), - "Puppy 79": KH1ItemData("Puppies", code = 264_2179, classification = ItemClassification.progression, ), - "Puppy 80": KH1ItemData("Puppies", code = 264_2180, classification = ItemClassification.progression, ), - "Puppy 81": KH1ItemData("Puppies", code = 264_2181, classification = ItemClassification.progression, ), - "Puppy 82": KH1ItemData("Puppies", code = 264_2182, classification = ItemClassification.progression, ), - "Puppy 83": KH1ItemData("Puppies", code = 264_2183, classification = ItemClassification.progression, ), - "Puppy 84": KH1ItemData("Puppies", code = 264_2184, classification = ItemClassification.progression, ), - "Puppy 85": KH1ItemData("Puppies", code = 264_2185, classification = ItemClassification.progression, ), - "Puppy 86": KH1ItemData("Puppies", code = 264_2186, classification = ItemClassification.progression, ), - "Puppy 87": KH1ItemData("Puppies", code = 264_2187, classification = ItemClassification.progression, ), - "Puppy 88": KH1ItemData("Puppies", code = 264_2188, classification = ItemClassification.progression, ), - "Puppy 89": KH1ItemData("Puppies", code = 264_2189, classification = ItemClassification.progression, ), - "Puppy 90": KH1ItemData("Puppies", code = 264_2190, classification = ItemClassification.progression, ), - "Puppy 91": KH1ItemData("Puppies", code = 264_2191, classification = ItemClassification.progression, ), - "Puppy 92": KH1ItemData("Puppies", code = 264_2192, classification = ItemClassification.progression, ), - "Puppy 93": KH1ItemData("Puppies", code = 264_2193, classification = ItemClassification.progression, ), - "Puppy 94": KH1ItemData("Puppies", code = 264_2194, classification = ItemClassification.progression, ), - "Puppy 95": KH1ItemData("Puppies", code = 264_2195, classification = ItemClassification.progression, ), - "Puppy 96": KH1ItemData("Puppies", code = 264_2196, classification = ItemClassification.progression, ), - "Puppy 97": KH1ItemData("Puppies", code = 264_2197, classification = ItemClassification.progression, ), - "Puppy 98": KH1ItemData("Puppies", code = 264_2198, classification = ItemClassification.progression, ), - "Puppy 99": KH1ItemData("Puppies", code = 264_2199, classification = ItemClassification.progression, ), - "Puppies 01-03": KH1ItemData("Puppies", code = 264_2201, classification = ItemClassification.progression, ), - "Puppies 04-06": KH1ItemData("Puppies", code = 264_2202, classification = ItemClassification.progression, ), - "Puppies 07-09": KH1ItemData("Puppies", code = 264_2203, classification = ItemClassification.progression, ), - "Puppies 10-12": KH1ItemData("Puppies", code = 264_2204, classification = ItemClassification.progression, ), - "Puppies 13-15": KH1ItemData("Puppies", code = 264_2205, classification = ItemClassification.progression, ), - "Puppies 16-18": KH1ItemData("Puppies", code = 264_2206, classification = ItemClassification.progression, ), - "Puppies 19-21": KH1ItemData("Puppies", code = 264_2207, classification = ItemClassification.progression, ), - "Puppies 22-24": KH1ItemData("Puppies", code = 264_2208, classification = ItemClassification.progression, ), - "Puppies 25-27": KH1ItemData("Puppies", code = 264_2209, classification = ItemClassification.progression, ), - "Puppies 28-30": KH1ItemData("Puppies", code = 264_2210, classification = ItemClassification.progression, ), - "Puppies 31-33": KH1ItemData("Puppies", code = 264_2211, classification = ItemClassification.progression, ), - "Puppies 34-36": KH1ItemData("Puppies", code = 264_2212, classification = ItemClassification.progression, ), - "Puppies 37-39": KH1ItemData("Puppies", code = 264_2213, classification = ItemClassification.progression, ), - "Puppies 40-42": KH1ItemData("Puppies", code = 264_2214, classification = ItemClassification.progression, ), - "Puppies 43-45": KH1ItemData("Puppies", code = 264_2215, classification = ItemClassification.progression, ), - "Puppies 46-48": KH1ItemData("Puppies", code = 264_2216, classification = ItemClassification.progression, ), - "Puppies 49-51": KH1ItemData("Puppies", code = 264_2217, classification = ItemClassification.progression, ), - "Puppies 52-54": KH1ItemData("Puppies", code = 264_2218, classification = ItemClassification.progression, ), - "Puppies 55-57": KH1ItemData("Puppies", code = 264_2219, classification = ItemClassification.progression, ), - "Puppies 58-60": KH1ItemData("Puppies", code = 264_2220, classification = ItemClassification.progression, ), - "Puppies 61-63": KH1ItemData("Puppies", code = 264_2221, classification = ItemClassification.progression, ), - "Puppies 64-66": KH1ItemData("Puppies", code = 264_2222, classification = ItemClassification.progression, ), - "Puppies 67-69": KH1ItemData("Puppies", code = 264_2223, classification = ItemClassification.progression, ), - "Puppies 70-72": KH1ItemData("Puppies", code = 264_2224, classification = ItemClassification.progression, ), - "Puppies 73-75": KH1ItemData("Puppies", code = 264_2225, classification = ItemClassification.progression, ), - "Puppies 76-78": KH1ItemData("Puppies", code = 264_2226, classification = ItemClassification.progression, ), - "Puppies 79-81": KH1ItemData("Puppies", code = 264_2227, classification = ItemClassification.progression, ), - "Puppies 82-84": KH1ItemData("Puppies", code = 264_2228, classification = ItemClassification.progression, ), - "Puppies 85-87": KH1ItemData("Puppies", code = 264_2229, classification = ItemClassification.progression, ), - "Puppies 88-90": KH1ItemData("Puppies", code = 264_2230, classification = ItemClassification.progression, ), - "Puppies 91-93": KH1ItemData("Puppies", code = 264_2231, classification = ItemClassification.progression, ), - "Puppies 94-96": KH1ItemData("Puppies", code = 264_2232, classification = ItemClassification.progression, ), - "Puppies 97-99": KH1ItemData("Puppies", code = 264_2233, classification = ItemClassification.progression, ), - "All Puppies": KH1ItemData("Puppies", code = 264_2240, classification = ItemClassification.progression, ), - "Treasure Magnet": KH1ItemData("Abilities", code = 264_3005, classification = ItemClassification.useful, max_quantity = 2 ), - "Combo Plus": KH1ItemData("Abilities", code = 264_3006, classification = ItemClassification.useful, max_quantity = 4 ), - "Air Combo Plus": KH1ItemData("Abilities", code = 264_3007, classification = ItemClassification.useful, max_quantity = 2 ), - "Critical Plus": KH1ItemData("Abilities", code = 264_3008, classification = ItemClassification.useful, max_quantity = 3 ), - #"Second Wind": KH1ItemData("Abilities", code = 264_3009, classification = ItemClassification.useful, ), - "Scan": KH1ItemData("Abilities", code = 264_3010, classification = ItemClassification.useful, ), - "Sonic Blade": KH1ItemData("Abilities", code = 264_3011, classification = ItemClassification.useful, ), - "Ars Arcanum": KH1ItemData("Abilities", code = 264_3012, classification = ItemClassification.useful, ), - "Strike Raid": KH1ItemData("Abilities", code = 264_3013, classification = ItemClassification.useful, ), - "Ragnarok": KH1ItemData("Abilities", code = 264_3014, classification = ItemClassification.useful, ), - "Trinity Limit": KH1ItemData("Abilities", code = 264_3015, classification = ItemClassification.useful, ), - "Cheer": KH1ItemData("Abilities", code = 264_3016, classification = ItemClassification.useful, ), - "Vortex": KH1ItemData("Abilities", code = 264_3017, classification = ItemClassification.useful, ), - "Aerial Sweep": KH1ItemData("Abilities", code = 264_3018, classification = ItemClassification.useful, ), - "Counterattack": KH1ItemData("Abilities", code = 264_3019, classification = ItemClassification.useful, ), - "Blitz": KH1ItemData("Abilities", code = 264_3020, classification = ItemClassification.useful, ), - "Guard": KH1ItemData("Abilities", code = 264_3021, classification = ItemClassification.progression, ), - "Dodge Roll": KH1ItemData("Abilities", code = 264_3022, classification = ItemClassification.progression, ), - "MP Haste": KH1ItemData("Abilities", code = 264_3023, classification = ItemClassification.useful, ), - "MP Rage": KH1ItemData("Abilities", code = 264_3024, classification = ItemClassification.progression, ), - "Second Chance": KH1ItemData("Abilities", code = 264_3025, classification = ItemClassification.progression, ), - "Berserk": KH1ItemData("Abilities", code = 264_3026, classification = ItemClassification.useful, ), - "Jackpot": KH1ItemData("Abilities", code = 264_3027, classification = ItemClassification.useful, ), - "Lucky Strike": KH1ItemData("Abilities", code = 264_3028, classification = ItemClassification.useful, ), - #"Charge": KH1ItemData("Abilities", code = 264_3029, classification = ItemClassification.useful, ), - #"Rocket": KH1ItemData("Abilities", code = 264_3030, classification = ItemClassification.useful, ), - #"Tornado": KH1ItemData("Abilities", code = 264_3031, classification = ItemClassification.useful, ), - #"MP Gift": KH1ItemData("Abilities", code = 264_3032, classification = ItemClassification.useful, ), - #"Raging Boar": KH1ItemData("Abilities", code = 264_3033, classification = ItemClassification.useful, ), - #"Asp's Bite": KH1ItemData("Abilities", code = 264_3034, classification = ItemClassification.useful, ), - #"Healing Herb": KH1ItemData("Abilities", code = 264_3035, classification = ItemClassification.useful, ), - #"Wind Armor": KH1ItemData("Abilities", code = 264_3036, classification = ItemClassification.useful, ), - #"Crescent": KH1ItemData("Abilities", code = 264_3037, classification = ItemClassification.useful, ), - #"Sandstorm": KH1ItemData("Abilities", code = 264_3038, classification = ItemClassification.useful, ), - #"Applause!": KH1ItemData("Abilities", code = 264_3039, classification = ItemClassification.useful, ), - #"Blazing Fury": KH1ItemData("Abilities", code = 264_3040, classification = ItemClassification.useful, ), - #"Icy Terror": KH1ItemData("Abilities", code = 264_3041, classification = ItemClassification.useful, ), - #"Bolts of Sorrow": KH1ItemData("Abilities", code = 264_3042, classification = ItemClassification.useful, ), - #"Ghostly Scream": KH1ItemData("Abilities", code = 264_3043, classification = ItemClassification.useful, ), - #"Humming Bird": KH1ItemData("Abilities", code = 264_3044, classification = ItemClassification.useful, ), - #"Time-Out": KH1ItemData("Abilities", code = 264_3045, classification = ItemClassification.useful, ), - #"Storm's Eye": KH1ItemData("Abilities", code = 264_3046, classification = ItemClassification.useful, ), - #"Ferocious Lunge": KH1ItemData("Abilities", code = 264_3047, classification = ItemClassification.useful, ), - #"Furious Bellow": KH1ItemData("Abilities", code = 264_3048, classification = ItemClassification.useful, ), - #"Spiral Wave": KH1ItemData("Abilities", code = 264_3049, classification = ItemClassification.useful, ), - #"Thunder Potion": KH1ItemData("Abilities", code = 264_3050, classification = ItemClassification.useful, ), - #"Cure Potion": KH1ItemData("Abilities", code = 264_3051, classification = ItemClassification.useful, ), - #"Aero Potion": KH1ItemData("Abilities", code = 264_3052, classification = ItemClassification.useful, ), - "Slapshot": KH1ItemData("Abilities", code = 264_3053, classification = ItemClassification.useful, ), - "Sliding Dash": KH1ItemData("Abilities", code = 264_3054, classification = ItemClassification.useful, ), - "Hurricane Blast": KH1ItemData("Abilities", code = 264_3055, classification = ItemClassification.useful, ), - "Ripple Drive": KH1ItemData("Abilities", code = 264_3056, classification = ItemClassification.useful, ), - "Stun Impact": KH1ItemData("Abilities", code = 264_3057, classification = ItemClassification.useful, ), - "Gravity Break": KH1ItemData("Abilities", code = 264_3058, classification = ItemClassification.useful, ), - "Zantetsuken": KH1ItemData("Abilities", code = 264_3059, classification = ItemClassification.useful, ), - "Tech Boost": KH1ItemData("Abilities", code = 264_3060, classification = ItemClassification.useful, max_quantity = 4 ), - "Encounter Plus": KH1ItemData("Abilities", code = 264_3061, classification = ItemClassification.useful, ), - "Leaf Bracer": KH1ItemData("Abilities", code = 264_3062, classification = ItemClassification.progression, ), - #"Evolution": KH1ItemData("Abilities", code = 264_3063, classification = ItemClassification.useful, ), - "EXP Zero": KH1ItemData("Abilities", code = 264_3064, classification = ItemClassification.useful, ), - "Combo Master": KH1ItemData("Abilities", code = 264_3065, classification = ItemClassification.progression, ), - "Max HP Increase": KH1ItemData("Level Up", code = 264_4001, classification = ItemClassification.useful, max_quantity = 15), - "Max MP Increase": KH1ItemData("Level Up", code = 264_4002, classification = ItemClassification.useful, max_quantity = 15), - "Max AP Increase": KH1ItemData("Level Up", code = 264_4003, classification = ItemClassification.useful, max_quantity = 15), - "Strength Increase": KH1ItemData("Level Up", code = 264_4004, classification = ItemClassification.useful, max_quantity = 15), - "Defense Increase": KH1ItemData("Level Up", code = 264_4005, classification = ItemClassification.useful, max_quantity = 15), - "Accessory Slot Increase": KH1ItemData("Limited Level Up", code = 264_4006, classification = ItemClassification.useful, max_quantity = 15), - "Item Slot Increase": KH1ItemData("Limited Level Up", code = 264_4007, classification = ItemClassification.useful, max_quantity = 15), - "Dumbo": KH1ItemData("Summons", code = 264_5000, classification = ItemClassification.progression, ), - "Bambi": KH1ItemData("Summons", code = 264_5001, classification = ItemClassification.progression, ), - "Genie": KH1ItemData("Summons", code = 264_5002, classification = ItemClassification.progression, ), - "Tinker Bell": KH1ItemData("Summons", code = 264_5003, classification = ItemClassification.progression, ), - "Mushu": KH1ItemData("Summons", code = 264_5004, classification = ItemClassification.progression, ), - "Simba": KH1ItemData("Summons", code = 264_5005, classification = ItemClassification.progression, ), - "Progressive Fire": KH1ItemData("Magic", code = 264_6001, classification = ItemClassification.progression, max_quantity = 3 ), - "Progressive Blizzard": KH1ItemData("Magic", code = 264_6002, classification = ItemClassification.progression, max_quantity = 3 ), - "Progressive Thunder": KH1ItemData("Magic", code = 264_6003, classification = ItemClassification.progression, max_quantity = 3 ), - "Progressive Cure": KH1ItemData("Magic", code = 264_6004, classification = ItemClassification.progression, max_quantity = 3 ), - "Progressive Gravity": KH1ItemData("Magic", code = 264_6005, classification = ItemClassification.progression, max_quantity = 3 ), - "Progressive Stop": KH1ItemData("Magic", code = 264_6006, classification = ItemClassification.progression, max_quantity = 3 ), - "Progressive Aero": KH1ItemData("Magic", code = 264_6007, classification = ItemClassification.progression, max_quantity = 3 ), - #"Traverse Town": KH1ItemData("Worlds", code = 264_7001, classification = ItemClassification.progression, ), - "Wonderland": KH1ItemData("Worlds", code = 264_7002, classification = ItemClassification.progression, ), - "Olympus Coliseum": KH1ItemData("Worlds", code = 264_7003, classification = ItemClassification.progression, ), - "Deep Jungle": KH1ItemData("Worlds", code = 264_7004, classification = ItemClassification.progression, ), - "Agrabah": KH1ItemData("Worlds", code = 264_7005, classification = ItemClassification.progression, ), - "Halloween Town": KH1ItemData("Worlds", code = 264_7006, classification = ItemClassification.progression, ), - "Atlantica": KH1ItemData("Worlds", code = 264_7007, classification = ItemClassification.progression, ), - "Neverland": KH1ItemData("Worlds", code = 264_7008, classification = ItemClassification.progression, ), - "Hollow Bastion": KH1ItemData("Worlds", code = 264_7009, classification = ItemClassification.progression, ), - "End of the World": KH1ItemData("Worlds", code = 264_7010, classification = ItemClassification.progression, ), - "Monstro": KH1ItemData("Worlds", code = 264_7011, classification = ItemClassification.progression, ), - "Blue Trinity": KH1ItemData("Trinities", code = 264_8001, classification = ItemClassification.progression, ), - "Red Trinity": KH1ItemData("Trinities", code = 264_8002, classification = ItemClassification.progression, ), - "Green Trinity": KH1ItemData("Trinities", code = 264_8003, classification = ItemClassification.progression, ), - "Yellow Trinity": KH1ItemData("Trinities", code = 264_8004, classification = ItemClassification.progression, ), - "White Trinity": KH1ItemData("Trinities", code = 264_8005, classification = ItemClassification.progression, ), - "Phil Cup": KH1ItemData("Cups", code = 264_9001, classification = ItemClassification.progression, ), - "Pegasus Cup": KH1ItemData("Cups", code = 264_9002, classification = ItemClassification.progression, ), - "Hercules Cup": KH1ItemData("Cups", code = 264_9003, classification = ItemClassification.progression, ), - #"Hades Cup": KH1ItemData("Cups", code = 264_9004, classification = ItemClassification.progression, ), + "Potion": KH1ItemData("Item", code = 264_1001, classification = ItemClassification.filler, type = "Item", ), + "Hi-Potion": KH1ItemData("Item", code = 264_1002, classification = ItemClassification.filler, type = "Item", ), + "Ether": KH1ItemData("Item", code = 264_1003, classification = ItemClassification.filler, type = "Item", ), + "Elixir": KH1ItemData("Item", code = 264_1004, classification = ItemClassification.filler, type = "Item", ), + #"B05": KH1ItemData("Item", code = 264_1005, classification = ItemClassification.filler, type = "Item", ), + "Mega-Potion": KH1ItemData("Item", code = 264_1006, classification = ItemClassification.filler, type = "Item", ), + "Mega-Ether": KH1ItemData("Item", code = 264_1007, classification = ItemClassification.filler, type = "Item", ), + "Megalixir": KH1ItemData("Item", code = 264_1008, classification = ItemClassification.filler, type = "Item", ), + "Torn Page": KH1ItemData("Torn Pages", code = 264_1009, classification = ItemClassification.progression, type = "Item", max_quantity = 5 ), + "Final Door Key": KH1ItemData("Key", code = 264_1010, classification = ItemClassification.progression, type = "Item", ), + "Destiny Islands": KH1ItemData("Worlds", code = 264_1011, classification = ItemClassification.progression, type = "Item", ), + "Raft Materials": KH1ItemData("Key", code = 264_1012, classification = ItemClassification.progression, type = "Item", max_quantity = 2 ), + #"Frost Stone": KH1ItemData("Synthesis", code = 264_1013, classification = ItemClassification.filler, type = "Item", ), + #"Lightning Stone": KH1ItemData("Synthesis", code = 264_1014, classification = ItemClassification.filler, type = "Item", ), + #"Dazzling Stone": KH1ItemData("Synthesis", code = 264_1015, classification = ItemClassification.filler, type = "Item", ), + #"Stormy Stone": KH1ItemData("Synthesis", code = 264_1016, classification = ItemClassification.filler, type = "Item", ), + "Protect Chain": KH1ItemData("Accessory", code = 264_1017, classification = ItemClassification.useful, type = "Item", ), + "Protera Chain": KH1ItemData("Accessory", code = 264_1018, classification = ItemClassification.useful, type = "Item", ), + "Protega Chain": KH1ItemData("Accessory", code = 264_1019, classification = ItemClassification.useful, type = "Item", ), + "Fire Ring": KH1ItemData("Accessory", code = 264_1020, classification = ItemClassification.useful, type = "Item", ), + "Fira Ring": KH1ItemData("Accessory", code = 264_1021, classification = ItemClassification.useful, type = "Item", ), + "Firaga Ring": KH1ItemData("Accessory", code = 264_1022, classification = ItemClassification.useful, type = "Item", ), + "Blizzard Ring": KH1ItemData("Accessory", code = 264_1023, classification = ItemClassification.useful, type = "Item", ), + "Blizzara Ring": KH1ItemData("Accessory", code = 264_1024, classification = ItemClassification.useful, type = "Item", ), + "Blizzaga Ring": KH1ItemData("Accessory", code = 264_1025, classification = ItemClassification.useful, type = "Item", ), + "Thunder Ring": KH1ItemData("Accessory", code = 264_1026, classification = ItemClassification.useful, type = "Item", ), + "Thundara Ring": KH1ItemData("Accessory", code = 264_1027, classification = ItemClassification.useful, type = "Item", ), + "Thundaga Ring": KH1ItemData("Accessory", code = 264_1028, classification = ItemClassification.useful, type = "Item", ), + "Ability Stud": KH1ItemData("Accessory", code = 264_1029, classification = ItemClassification.useful, type = "Item", ), + "Guard Earring": KH1ItemData("Accessory", code = 264_1030, classification = ItemClassification.useful, type = "Item", ), + "Master Earring": KH1ItemData("Accessory", code = 264_1031, classification = ItemClassification.useful, type = "Item", ), + "Chaos Ring": KH1ItemData("Accessory", code = 264_1032, classification = ItemClassification.useful, type = "Item", ), + "Dark Ring": KH1ItemData("Accessory", code = 264_1033, classification = ItemClassification.useful, type = "Item", ), + "Element Ring": KH1ItemData("Accessory", code = 264_1034, classification = ItemClassification.useful, type = "Item", ), + "Three Stars": KH1ItemData("Accessory", code = 264_1035, classification = ItemClassification.useful, type = "Item", ), + "Power Chain": KH1ItemData("Accessory", code = 264_1036, classification = ItemClassification.useful, type = "Item", ), + "Golem Chain": KH1ItemData("Accessory", code = 264_1037, classification = ItemClassification.useful, type = "Item", ), + "Titan Chain": KH1ItemData("Accessory", code = 264_1038, classification = ItemClassification.useful, type = "Item", ), + "Energy Bangle": KH1ItemData("Accessory", code = 264_1039, classification = ItemClassification.useful, type = "Item", ), + "Angel Bangle": KH1ItemData("Accessory", code = 264_1040, classification = ItemClassification.useful, type = "Item", ), + "Gaia Bangle": KH1ItemData("Accessory", code = 264_1041, classification = ItemClassification.useful, type = "Item", ), + "Magic Armlet": KH1ItemData("Accessory", code = 264_1042, classification = ItemClassification.useful, type = "Item", ), + "Rune Armlet": KH1ItemData("Accessory", code = 264_1043, classification = ItemClassification.useful, type = "Item", ), + "Atlas Armlet": KH1ItemData("Accessory", code = 264_1044, classification = ItemClassification.useful, type = "Item", ), + "Heartguard": KH1ItemData("Accessory", code = 264_1045, classification = ItemClassification.useful, type = "Item", ), + "Ribbon": KH1ItemData("Accessory", code = 264_1046, classification = ItemClassification.useful, type = "Item", ), + "Crystal Crown": KH1ItemData("Accessory", code = 264_1047, classification = ItemClassification.useful, type = "Item", ), + "Brave Warrior": KH1ItemData("Accessory", code = 264_1048, classification = ItemClassification.useful, type = "Item", ), + "Ifrit's Horn": KH1ItemData("Accessory", code = 264_1049, classification = ItemClassification.useful, type = "Item", ), + "Inferno Band": KH1ItemData("Accessory", code = 264_1050, classification = ItemClassification.useful, type = "Item", ), + "White Fang": KH1ItemData("Accessory", code = 264_1051, classification = ItemClassification.useful, type = "Item", ), + "Ray of Light": KH1ItemData("Accessory", code = 264_1052, classification = ItemClassification.useful, type = "Item", ), + "Holy Circlet": KH1ItemData("Accessory", code = 264_1053, classification = ItemClassification.useful, type = "Item", ), + "Raven's Claw": KH1ItemData("Accessory", code = 264_1054, classification = ItemClassification.useful, type = "Item", ), + "Omega Arts": KH1ItemData("Accessory", code = 264_1055, classification = ItemClassification.useful, type = "Item", ), + "EXP Earring": KH1ItemData("Accessory", code = 264_1056, classification = ItemClassification.useful, type = "Item", ), + #"A41": KH1ItemData("Accessory", code = 264_1057, classification = ItemClassification.useful, type = "Item", ), + "EXP Ring": KH1ItemData("Accessory", code = 264_1058, classification = ItemClassification.useful, type = "Item", ), + "EXP Bracelet": KH1ItemData("Accessory", code = 264_1059, classification = ItemClassification.useful, type = "Item", ), + "EXP Necklace": KH1ItemData("Accessory", code = 264_1060, classification = ItemClassification.useful, type = "Item", ), + "Firagun Band": KH1ItemData("Accessory", code = 264_1061, classification = ItemClassification.useful, type = "Item", ), + "Blizzagun Band": KH1ItemData("Accessory", code = 264_1062, classification = ItemClassification.useful, type = "Item", ), + "Thundagun Band": KH1ItemData("Accessory", code = 264_1063, classification = ItemClassification.useful, type = "Item", ), + "Ifrit Belt": KH1ItemData("Accessory", code = 264_1064, classification = ItemClassification.useful, type = "Item", ), + "Shiva Belt": KH1ItemData("Accessory", code = 264_1065, classification = ItemClassification.useful, type = "Item", ), + "Ramuh Belt": KH1ItemData("Accessory", code = 264_1066, classification = ItemClassification.useful, type = "Item", ), + "Moogle Badge": KH1ItemData("Accessory", code = 264_1067, classification = ItemClassification.useful, type = "Item", ), + "Cosmic Arts": KH1ItemData("Accessory", code = 264_1068, classification = ItemClassification.useful, type = "Item", ), + "Royal Crown": KH1ItemData("Accessory", code = 264_1069, classification = ItemClassification.useful, type = "Item", ), + "Prime Cap": KH1ItemData("Accessory", code = 264_1070, classification = ItemClassification.useful, type = "Item", ), + "Obsidian Ring": KH1ItemData("Accessory", code = 264_1071, classification = ItemClassification.useful, type = "Item", ), + #"A56": KH1ItemData("Accessory", code = 264_1072, classification = ItemClassification.filler, type = "Item", ), + #"A57": KH1ItemData("Accessory", code = 264_1073, classification = ItemClassification.filler, type = "Item", ), + #"A58": KH1ItemData("Accessory", code = 264_1074, classification = ItemClassification.filler, type = "Item", ), + #"A59": KH1ItemData("Accessory", code = 264_1075, classification = ItemClassification.filler, type = "Item", ), + #"A60": KH1ItemData("Accessory", code = 264_1076, classification = ItemClassification.filler, type = "Item", ), + #"A61": KH1ItemData("Accessory", code = 264_1077, classification = ItemClassification.filler, type = "Item", ), + #"A62": KH1ItemData("Accessory", code = 264_1078, classification = ItemClassification.filler, type = "Item", ), + #"A63": KH1ItemData("Accessory", code = 264_1079, classification = ItemClassification.filler, type = "Item", ), + #"A64": KH1ItemData("Accessory", code = 264_1080, classification = ItemClassification.filler, type = "Item", ), + #"Kingdom Key": KH1ItemData("Keyblades", code = 264_1081, classification = ItemClassification.useful, type = "Item", ), + #"Dream Sword": KH1ItemData("Keyblades", code = 264_1082, classification = ItemClassification.useful, type = "Item", ), + #"Dream Shield": KH1ItemData("Keyblades", code = 264_1083, classification = ItemClassification.useful, type = "Item", ), + #"Dream Rod": KH1ItemData("Keyblades", code = 264_1084, classification = ItemClassification.useful, type = "Item", ), + #"Wooden Sword": KH1ItemData("Keyblades", code = 264_1085, classification = ItemClassification.useful, type = "Item", ), + "Jungle King": KH1ItemData("Keyblades", code = 264_1086, classification = ItemClassification.progression, type = "Item", ), + "Three Wishes": KH1ItemData("Keyblades", code = 264_1087, classification = ItemClassification.progression, type = "Item", ), + "Fairy Harp": KH1ItemData("Keyblades", code = 264_1088, classification = ItemClassification.progression, type = "Item", ), + "Pumpkinhead": KH1ItemData("Keyblades", code = 264_1089, classification = ItemClassification.progression, type = "Item", ), + "Crabclaw": KH1ItemData("Keyblades", code = 264_1090, classification = ItemClassification.progression, type = "Item", ), + "Divine Rose": KH1ItemData("Keyblades", code = 264_1091, classification = ItemClassification.progression, type = "Item", ), + "Spellbinder": KH1ItemData("Keyblades", code = 264_1092, classification = ItemClassification.progression, type = "Item", ), + "Olympia": KH1ItemData("Keyblades", code = 264_1093, classification = ItemClassification.progression, type = "Item", ), + "Lionheart": KH1ItemData("Keyblades", code = 264_1094, classification = ItemClassification.progression, type = "Item", ), + "Metal Chocobo": KH1ItemData("Keyblades", code = 264_1095, classification = ItemClassification.useful, type = "Item", ), + "Oathkeeper": KH1ItemData("Keyblades", code = 264_1096, classification = ItemClassification.progression, type = "Item", ), + "Oblivion": KH1ItemData("Keyblades", code = 264_1097, classification = ItemClassification.progression, type = "Item", ), + "Lady Luck": KH1ItemData("Keyblades", code = 264_1098, classification = ItemClassification.progression, type = "Item", ), + "Wishing Star": KH1ItemData("Keyblades", code = 264_1099, classification = ItemClassification.progression, type = "Item", ), + "Ultima Weapon": KH1ItemData("Keyblades", code = 264_1100, classification = ItemClassification.useful, type = "Item", ), + "Diamond Dust": KH1ItemData("Keyblades", code = 264_1101, classification = ItemClassification.useful, type = "Item", ), + "One-Winged Angel": KH1ItemData("Keyblades", code = 264_1102, classification = ItemClassification.useful, type = "Item", ), + #"Mage's Staff": KH1ItemData("Weapons", code = 264_1103, classification = ItemClassification.filler, type = "Item", ), + "Morning Star": KH1ItemData("Weapons", code = 264_1104, classification = ItemClassification.useful, type = "Item", ), + "Shooting Star": KH1ItemData("Weapons", code = 264_1105, classification = ItemClassification.useful, type = "Item", ), + "Magus Staff": KH1ItemData("Weapons", code = 264_1106, classification = ItemClassification.useful, type = "Item", ), + "Wisdom Staff": KH1ItemData("Weapons", code = 264_1107, classification = ItemClassification.useful, type = "Item", ), + "Warhammer": KH1ItemData("Weapons", code = 264_1108, classification = ItemClassification.useful, type = "Item", ), + "Silver Mallet": KH1ItemData("Weapons", code = 264_1109, classification = ItemClassification.useful, type = "Item", ), + "Grand Mallet": KH1ItemData("Weapons", code = 264_1110, classification = ItemClassification.useful, type = "Item", ), + "Lord Fortune": KH1ItemData("Weapons", code = 264_1111, classification = ItemClassification.useful, type = "Item", ), + "Violetta": KH1ItemData("Weapons", code = 264_1112, classification = ItemClassification.useful, type = "Item", ), + "Dream Rod (Donald)": KH1ItemData("Weapons", code = 264_1113, classification = ItemClassification.useful, type = "Item", ), + "Save the Queen": KH1ItemData("Weapons", code = 264_1114, classification = ItemClassification.useful, type = "Item", ), + "Wizard's Relic": KH1ItemData("Weapons", code = 264_1115, classification = ItemClassification.useful, type = "Item", ), + "Meteor Strike": KH1ItemData("Weapons", code = 264_1116, classification = ItemClassification.useful, type = "Item", ), + "Fantasista": KH1ItemData("Weapons", code = 264_1117, classification = ItemClassification.useful, type = "Item", ), + #"Unused (Donald)": KH1ItemData("Weapons", code = 264_1118, classification = ItemClassification.filler, type = "Item", ), + #"Knight's Shield": KH1ItemData("Weapons", code = 264_1119, classification = ItemClassification.filler, type = "Item", ), + "Mythril Shield": KH1ItemData("Weapons", code = 264_1120, classification = ItemClassification.useful, type = "Item", ), + "Onyx Shield": KH1ItemData("Weapons", code = 264_1121, classification = ItemClassification.useful, type = "Item", ), + "Stout Shield": KH1ItemData("Weapons", code = 264_1122, classification = ItemClassification.useful, type = "Item", ), + "Golem Shield": KH1ItemData("Weapons", code = 264_1123, classification = ItemClassification.useful, type = "Item", ), + "Adamant Shield": KH1ItemData("Weapons", code = 264_1124, classification = ItemClassification.useful, type = "Item", ), + "Smasher": KH1ItemData("Weapons", code = 264_1125, classification = ItemClassification.useful, type = "Item", ), + "Gigas Fist": KH1ItemData("Weapons", code = 264_1126, classification = ItemClassification.useful, type = "Item", ), + "Genji Shield": KH1ItemData("Weapons", code = 264_1127, classification = ItemClassification.useful, type = "Item", ), + "Herc's Shield": KH1ItemData("Weapons", code = 264_1128, classification = ItemClassification.useful, type = "Item", ), + "Dream Shield (Goofy)": KH1ItemData("Weapons", code = 264_1129, classification = ItemClassification.useful, type = "Item", ), + "Save the King": KH1ItemData("Weapons", code = 264_1130, classification = ItemClassification.useful, type = "Item", ), + "Defender": KH1ItemData("Weapons", code = 264_1131, classification = ItemClassification.useful, type = "Item", ), + "Mighty Shield": KH1ItemData("Weapons", code = 264_1132, classification = ItemClassification.useful, type = "Item", ), + "Seven Elements": KH1ItemData("Weapons", code = 264_1133, classification = ItemClassification.useful, type = "Item", ), + #"Unused (Goofy)": KH1ItemData("Weapons", code = 264_1134, classification = ItemClassification.filler, type = "Item", ), + #"Spear": KH1ItemData("Weapons", code = 264_1135, classification = ItemClassification.filler, type = "Item", ), + #"No Weapon": KH1ItemData("Weapons", code = 264_1136, classification = ItemClassification.filler, type = "Item", ), + #"Genie": KH1ItemData("Weapons", code = 264_1137, classification = ItemClassification.filler, type = "Item", ), + #"No Weapon": KH1ItemData("Weapons", code = 264_1138, classification = ItemClassification.filler, type = "Item", ), + #"No Weapon": KH1ItemData("Weapons", code = 264_1139, classification = ItemClassification.filler, type = "Item", ), + #"Dagger": KH1ItemData("Weapons", code = 264_1140, classification = ItemClassification.filler, type = "Item", ), + #"Claws": KH1ItemData("Weapons", code = 264_1141, classification = ItemClassification.filler, type = "Item", ), + "Tent": KH1ItemData("Camping", code = 264_1142, classification = ItemClassification.filler, type = "Item", ), + "Camping Set": KH1ItemData("Camping", code = 264_1143, classification = ItemClassification.filler, type = "Item", ), + "Cottage": KH1ItemData("Camping", code = 264_1144, classification = ItemClassification.filler, type = "Item", ), + #"C04": KH1ItemData("Camping", code = 264_1145, classification = ItemClassification.filler, type = "Item", ), + #"C05": KH1ItemData("Camping", code = 264_1146, classification = ItemClassification.filler, type = "Item", ), + #"C06": KH1ItemData("Camping", code = 264_1147, classification = ItemClassification.filler, type = "Item", ), + #"C07": KH1ItemData("Camping", code = 264_1148, classification = ItemClassification.filler, type = "Item", ), + "Wonderland": KH1ItemData("Worlds", code = 264_1149, classification = ItemClassification.progression, type = "Item", ), + "Olympus Coliseum": KH1ItemData("Worlds", code = 264_1150, classification = ItemClassification.progression, type = "Item", ), + "Deep Jungle": KH1ItemData("Worlds", code = 264_1151, classification = ItemClassification.progression, type = "Item", ), + "Power Up": KH1ItemData("Stat Ups", code = 264_1152, classification = ItemClassification.filler, type = "Item", ), + "Defense Up": KH1ItemData("Stat Ups", code = 264_1153, classification = ItemClassification.filler, type = "Item", ), + "AP Up": KH1ItemData("Stat Ups", code = 264_1154, classification = ItemClassification.filler, type = "Item", ), + "Agrabah": KH1ItemData("Worlds", code = 264_1155, classification = ItemClassification.progression, type = "Item", ), + "Monstro": KH1ItemData("Worlds", code = 264_1156, classification = ItemClassification.progression, type = "Item", ), + "Atlantica": KH1ItemData("Worlds", code = 264_1157, classification = ItemClassification.progression, type = "Item", ), + "Fire Arts": KH1ItemData("Key", code = 264_1158, classification = ItemClassification.progression, type = "Item", ), + "Blizzard Arts": KH1ItemData("Key", code = 264_1159, classification = ItemClassification.progression, type = "Item", ), + "Thunder Arts": KH1ItemData("Key", code = 264_1160, classification = ItemClassification.progression, type = "Item", ), + "Cure Arts": KH1ItemData("Key", code = 264_1161, classification = ItemClassification.progression, type = "Item", ), + "Gravity Arts": KH1ItemData("Key", code = 264_1162, classification = ItemClassification.progression, type = "Item", ), + "Stop Arts": KH1ItemData("Key", code = 264_1163, classification = ItemClassification.progression, type = "Item", ), + "Aero Arts": KH1ItemData("Key", code = 264_1164, classification = ItemClassification.progression, type = "Item", ), + "Neverland": KH1ItemData("Worlds", code = 264_1165, classification = ItemClassification.progression, type = "Item", ), + "Halloween Town": KH1ItemData("Worlds", code = 264_1166, classification = ItemClassification.progression, type = "Item", ), + "Puppy": KH1ItemData("Key", code = 264_1167, classification = ItemClassification.progression, type = "Item", ), + "Hollow Bastion": KH1ItemData("Worlds", code = 264_1168, classification = ItemClassification.progression, type = "Item", ), + "End of the World": KH1ItemData("Worlds", code = 264_1169, classification = ItemClassification.progression, type = "Item", ), + "Blue Trinity": KH1ItemData("Trinities", code = 264_1170, classification = ItemClassification.progression, type = "Item", ), + "Red Trinity": KH1ItemData("Trinities", code = 264_1171, classification = ItemClassification.progression, type = "Item", ), + "Green Trinity": KH1ItemData("Trinities", code = 264_1172, classification = ItemClassification.progression, type = "Item", ), + "Yellow Trinity": KH1ItemData("Trinities", code = 264_1173, classification = ItemClassification.progression, type = "Item", ), + "White Trinity": KH1ItemData("Trinities", code = 264_1174, classification = ItemClassification.progression, type = "Item", ), + "Progressive Fire": KH1ItemData("Magic", code = 264_1175, classification = ItemClassification.progression, type = "Item", max_quantity = 3 ), + "Progressive Blizzard": KH1ItemData("Magic", code = 264_1176, classification = ItemClassification.progression, type = "Item", max_quantity = 3 ), + "Progressive Thunder": KH1ItemData("Magic", code = 264_1177, classification = ItemClassification.progression, type = "Item", max_quantity = 3 ), + "Progressive Cure": KH1ItemData("Magic", code = 264_1178, classification = ItemClassification.progression, type = "Item", max_quantity = 3 ), + "Progressive Gravity": KH1ItemData("Magic", code = 264_1179, classification = ItemClassification.progression, type = "Item", max_quantity = 3 ), + "Progressive Stop": KH1ItemData("Magic", code = 264_1180, classification = ItemClassification.progression, type = "Item", max_quantity = 3 ), + "Progressive Aero": KH1ItemData("Magic", code = 264_1181, classification = ItemClassification.progression, type = "Item", max_quantity = 3 ), + "Phil Cup": KH1ItemData("Cups", code = 264_1182, classification = ItemClassification.progression, type = "Item", ), + "Theon Vol. 6": KH1ItemData("Key", code = 264_1183, classification = ItemClassification.progression, type = "Item", ), + "Pegasus Cup": KH1ItemData("Cups", code = 264_1184, classification = ItemClassification.progression, type = "Item", ), + "Hercules Cup": KH1ItemData("Cups", code = 264_1185, classification = ItemClassification.progression, type = "Item", ), + #"Empty Bottle": KH1ItemData("Key", code = 264_1186, classification = ItemClassification.progression, type = "Item", max_quantity = 6 ), + #"Old Book": KH1ItemData("Key", code = 264_1187, classification = ItemClassification.progression, type = "Item", ), + "Emblem Piece (Flame)": KH1ItemData("Key", code = 264_1188, classification = ItemClassification.progression, type = "Item", ), + "Emblem Piece (Chest)": KH1ItemData("Key", code = 264_1189, classification = ItemClassification.progression, type = "Item", ), + "Emblem Piece (Statue)": KH1ItemData("Key", code = 264_1190, classification = ItemClassification.progression, type = "Item", ), + "Emblem Piece (Fountain)": KH1ItemData("Key", code = 264_1191, classification = ItemClassification.progression, type = "Item", ), + #"Log": KH1ItemData("DI", code = 264_1192, classification = ItemClassification.progression, type = "Item", max_quantity = 2 ), + #"Cloth": KH1ItemData("DI", code = 264_1193, classification = ItemClassification.progression, type = "Item", ), + #"Rope": KH1ItemData("DI", code = 264_1194, classification = ItemClassification.progression, type = "Item", ), + #"Seagull Egg": KH1ItemData("DI", code = 264_1195, classification = ItemClassification.progression, type = "Item", ), + #"Fish": KH1ItemData("DI", code = 264_1196, classification = ItemClassification.progression, type = "Item", max_quantity = 3 ), + #"Mushroom": KH1ItemData("DI", code = 264_1197, classification = ItemClassification.progression, type = "Item", max_quantity = 3 ), + #"Coconut": KH1ItemData("DI", code = 264_1198, classification = ItemClassification.progression, type = "Item", max_quantity = 2 ), + #"Drinking Water": KH1ItemData("DI", code = 264_1199, classification = ItemClassification.progression, type = "Item", ), + #"Navi-G Piece 1": KH1ItemData("Key", code = 264_1200, classification = ItemClassification.progression, type = "Item", ), + #"Navi-G Piece 2": KH1ItemData("Key", code = 264_1201, classification = ItemClassification.progression, type = "Item", ), + #"Navi-Gummi Unused": KH1ItemData("Key", code = 264_1202, classification = ItemClassification.progression, type = "Item", ), + #"Navi-G Piece 3": KH1ItemData("Key", code = 264_1203, classification = ItemClassification.progression, type = "Item", ), + #"Navi-G Piece 4": KH1ItemData("Key", code = 264_1204, classification = ItemClassification.progression, type = "Item", ), + #"Navi-Gummi": KH1ItemData("Key", code = 264_1205, classification = ItemClassification.progression, type = "Item", ), + #"Watergleam": KH1ItemData("Key", code = 264_1206, classification = ItemClassification.progression, type = "Item", ), + #"Naturespark": KH1ItemData("Key", code = 264_1207, classification = ItemClassification.progression, type = "Item", ), + #"Fireglow": KH1ItemData("Key", code = 264_1208, classification = ItemClassification.progression, type = "Item", ), + #"Earthshine": KH1ItemData("Key", code = 264_1209, classification = ItemClassification.progression, type = "Item", ), + "Crystal Trident": KH1ItemData("Key", code = 264_1210, classification = ItemClassification.progression, type = "Item", ), + "Postcard": KH1ItemData("Key", code = 264_1211, classification = ItemClassification.progression, type = "Item", max_quantity = 10), + #"Torn Page 1": KH1ItemData("Torn Pages", code = 264_1212, classification = ItemClassification.progression, type = "Item", ), + #"Torn Page 2": KH1ItemData("Torn Pages", code = 264_1213, classification = ItemClassification.progression, type = "Item", ), + #"Torn Page 3": KH1ItemData("Torn Pages", code = 264_1214, classification = ItemClassification.progression, type = "Item", ), + #"Torn Page 4": KH1ItemData("Torn Pages", code = 264_1215, classification = ItemClassification.progression, type = "Item", ), + #"Torn Page 5": KH1ItemData("Torn Pages", code = 264_1216, classification = ItemClassification.progression, type = "Item", ), + "Slides": KH1ItemData("Key", code = 264_1217, classification = ItemClassification.progression, type = "Item", ), + #"Slide 2": KH1ItemData("Key", code = 264_1218, classification = ItemClassification.progression, type = "Item", ), + #"Slide 3": KH1ItemData("Key", code = 264_1219, classification = ItemClassification.progression, type = "Item", ), + #"Slide 4": KH1ItemData("Key", code = 264_1220, classification = ItemClassification.progression, type = "Item", ), + #"Slide 5": KH1ItemData("Key", code = 264_1221, classification = ItemClassification.progression, type = "Item", ), + #"Slide 6": KH1ItemData("Key", code = 264_1222, classification = ItemClassification.progression, type = "Item", ), + "Footprints": KH1ItemData("Key", code = 264_1223, classification = ItemClassification.progression, type = "Item", ), + #"Claw Marks": KH1ItemData("Key", code = 264_1224, classification = ItemClassification.progression, type = "Item", ), + #"Stench": KH1ItemData("Key", code = 264_1225, classification = ItemClassification.progression, type = "Item", ), + #"Antenna": KH1ItemData("Key", code = 264_1226, classification = ItemClassification.progression, type = "Item", ), + "Forget-Me-Not": KH1ItemData("Key", code = 264_1227, classification = ItemClassification.progression, type = "Item", ), + "Jack-In-The-Box": KH1ItemData("Key", code = 264_1228, classification = ItemClassification.progression, type = "Item", ), + "Entry Pass": KH1ItemData("Key", code = 264_1229, classification = ItemClassification.progression, type = "Item", ), + #"AP Item": KH1ItemData("Key", code = 264_1230, classification = ItemClassification.progression, type = "Item", ), + "Dumbo": KH1ItemData("Summons", code = 264_1231, classification = ItemClassification.progression, type = "Item", ), + #"N41": KH1ItemData("Synthesis", code = 264_1232, classification = ItemClassification.filler, type = "Item", ), + "Bambi": KH1ItemData("Summons", code = 264_1233, classification = ItemClassification.progression, type = "Item", ), + "Genie": KH1ItemData("Summons", code = 264_1234, classification = ItemClassification.progression, type = "Item", ), + "Tinker Bell": KH1ItemData("Summons", code = 264_1235, classification = ItemClassification.progression, type = "Item", ), + "Mushu": KH1ItemData("Summons", code = 264_1236, classification = ItemClassification.progression, type = "Item", ), + "Simba": KH1ItemData("Summons", code = 264_1237, classification = ItemClassification.progression, type = "Item", ), + "Lucky Emblem": KH1ItemData("Key", code = 264_1238, classification = ItemClassification.progression, type = "Item", ), + "Max HP Increase": KH1ItemData("Level Up", code = 264_1239, classification = ItemClassification.useful, type = "Item", max_quantity = 15), + "Max MP Increase": KH1ItemData("Level Up", code = 264_1240, classification = ItemClassification.useful, type = "Item", max_quantity = 15), + "Max AP Increase": KH1ItemData("Level Up", code = 264_1241, classification = ItemClassification.useful, type = "Item", max_quantity = 15), + "Strength Increase": KH1ItemData("Level Up", code = 264_1242, classification = ItemClassification.useful, type = "Item", max_quantity = 15), + "Defense Increase": KH1ItemData("Level Up", code = 264_1243, classification = ItemClassification.useful, type = "Item", max_quantity = 15), + "Item Slot Increase": KH1ItemData("Limited Level Up", code = 264_1244, classification = ItemClassification.useful, type = "Item", max_quantity = 15), + "Accessory Slot Increase": KH1ItemData("Limited Level Up", code = 264_1245, classification = ItemClassification.useful, type = "Item", max_quantity = 15), + #"Thunder Gem": KH1ItemData("Synthesis", code = 264_1246, classification = ItemClassification.filler, type = "Item", ), + #"Shiny Crystal": KH1ItemData("Synthesis", code = 264_1247, classification = ItemClassification.filler, type = "Item", ), + #"Bright Shard": KH1ItemData("Synthesis", code = 264_1248, classification = ItemClassification.filler, type = "Item", ), + #"Bright Gem": KH1ItemData("Synthesis", code = 264_1249, classification = ItemClassification.filler, type = "Item", ), + #"Bright Crystal": KH1ItemData("Synthesis", code = 264_1250, classification = ItemClassification.filler, type = "Item", ), + #"Mystery Goo": KH1ItemData("Synthesis", code = 264_1251, classification = ItemClassification.filler, type = "Item", ), + #"Gale": KH1ItemData("Synthesis", code = 264_1252, classification = ItemClassification.filler, type = "Item", ), + #"Mythril Shard": KH1ItemData("Synthesis", code = 264_1253, classification = ItemClassification.filler, type = "Item", ), + "Mythril": KH1ItemData("Key", code = 264_1254, classification = ItemClassification.progression, type = "Item", max_quantity = 16), + "Orichalcum": KH1ItemData("Key", code = 264_1255, classification = ItemClassification.progression, type = "Item", max_quantity = 17), + "High Jump": KH1ItemData("Shared Abilities", code = 264_2001, classification = ItemClassification.progression, type = "Shared Ability", ), + "Mermaid Kick": KH1ItemData("Shared Abilities", code = 264_2002, classification = ItemClassification.progression, type = "Shared Ability", ), + "Progressive Glide": KH1ItemData("Shared Abilities", code = 264_2003, classification = ItemClassification.progression, type = "Shared Ability", max_quantity = 2 ), + #"Superglide": KH1ItemData("Shared Abilities", code = 264_2004, classification = ItemClassification.progression, type = "Ability", ), + "Treasure Magnet": KH1ItemData("Abilities", code = 264_3005, classification = ItemClassification.useful, type = "Ability", max_quantity = 2 ), + "Combo Plus": KH1ItemData("Abilities", code = 264_3006, classification = ItemClassification.useful, type = "Ability", max_quantity = 4 ), + "Air Combo Plus": KH1ItemData("Abilities", code = 264_3007, classification = ItemClassification.progression, type = "Ability", max_quantity = 2 ), + "Critical Plus": KH1ItemData("Abilities", code = 264_3008, classification = ItemClassification.useful, type = "Ability", max_quantity = 3 ), + #"Second Wind": KH1ItemData("Abilities", code = 264_3009, classification = ItemClassification.useful, type = "Ability", ), + "Scan": KH1ItemData("Abilities", code = 264_3010, classification = ItemClassification.useful, type = "Ability", ), + "Sonic Blade": KH1ItemData("Abilities", code = 264_3011, classification = ItemClassification.progression, type = "Ability", ), + "Ars Arcanum": KH1ItemData("Abilities", code = 264_3012, classification = ItemClassification.useful, type = "Ability", ), + "Strike Raid": KH1ItemData("Abilities", code = 264_3013, classification = ItemClassification.progression, type = "Ability", ), + "Ragnarok": KH1ItemData("Abilities", code = 264_3014, classification = ItemClassification.useful, type = "Ability", ), + "Trinity Limit": KH1ItemData("Abilities", code = 264_3015, classification = ItemClassification.useful, type = "Ability", ), + "Cheer": KH1ItemData("Abilities", code = 264_3016, classification = ItemClassification.useful, type = "Ability", ), + "Vortex": KH1ItemData("Abilities", code = 264_3017, classification = ItemClassification.useful, type = "Ability", ), + "Aerial Sweep": KH1ItemData("Abilities", code = 264_3018, classification = ItemClassification.useful, type = "Ability", ), + "Counterattack": KH1ItemData("Abilities", code = 264_3019, classification = ItemClassification.progression, type = "Ability", ), + "Blitz": KH1ItemData("Abilities", code = 264_3020, classification = ItemClassification.useful, type = "Ability", ), + "Guard": KH1ItemData("Abilities", code = 264_3021, classification = ItemClassification.progression, type = "Ability", ), + "Dodge Roll": KH1ItemData("Abilities", code = 264_3022, classification = ItemClassification.progression, type = "Ability", ), + "MP Haste": KH1ItemData("Abilities", code = 264_3023, classification = ItemClassification.useful, type = "Ability", ), + "MP Rage": KH1ItemData("Abilities", code = 264_3024, classification = ItemClassification.progression, type = "Ability", ), + "Second Chance": KH1ItemData("Abilities", code = 264_3025, classification = ItemClassification.progression, type = "Ability", ), + "Berserk": KH1ItemData("Abilities", code = 264_3026, classification = ItemClassification.useful, type = "Ability", ), + "Jackpot": KH1ItemData("Abilities", code = 264_3027, classification = ItemClassification.useful, type = "Ability", ), + "Lucky Strike": KH1ItemData("Abilities", code = 264_3028, classification = ItemClassification.useful, type = "Ability", ), + #"Charge": KH1ItemData("Abilities", code = 264_3029, classification = ItemClassification.useful, type = "Ability", ), + #"Rocket": KH1ItemData("Abilities", code = 264_3030, classification = ItemClassification.useful, type = "Ability", ), + #"Tornado": KH1ItemData("Abilities", code = 264_3031, classification = ItemClassification.useful, type = "Ability", ), + #"MP Gift": KH1ItemData("Abilities", code = 264_3032, classification = ItemClassification.useful, type = "Ability", ), + #"Raging Boar": KH1ItemData("Abilities", code = 264_3033, classification = ItemClassification.useful, type = "Ability", ), + #"Asp's Bite": KH1ItemData("Abilities", code = 264_3034, classification = ItemClassification.useful, type = "Ability", ), + #"Healing Herb": KH1ItemData("Abilities", code = 264_3035, classification = ItemClassification.useful, type = "Ability", ), + #"Wind Armor": KH1ItemData("Abilities", code = 264_3036, classification = ItemClassification.useful, type = "Ability", ), + #"Crescent": KH1ItemData("Abilities", code = 264_3037, classification = ItemClassification.useful, type = "Ability", ), + #"Sandstorm": KH1ItemData("Abilities", code = 264_3038, classification = ItemClassification.useful, type = "Ability", ), + #"Applause!": KH1ItemData("Abilities", code = 264_3039, classification = ItemClassification.useful, type = "Ability", ), + #"Blazing Fury": KH1ItemData("Abilities", code = 264_3040, classification = ItemClassification.useful, type = "Ability", ), + #"Icy Terror": KH1ItemData("Abilities", code = 264_3041, classification = ItemClassification.useful, type = "Ability", ), + #"Bolts of Sorrow": KH1ItemData("Abilities", code = 264_3042, classification = ItemClassification.useful, type = "Ability", ), + #"Ghostly Scream": KH1ItemData("Abilities", code = 264_3043, classification = ItemClassification.useful, type = "Ability", ), + #"Humming Bird": KH1ItemData("Abilities", code = 264_3044, classification = ItemClassification.useful, type = "Ability", ), + #"Time-Out": KH1ItemData("Abilities", code = 264_3045, classification = ItemClassification.useful, type = "Ability", ), + #"Storm's Eye": KH1ItemData("Abilities", code = 264_3046, classification = ItemClassification.useful, type = "Ability", ), + #"Ferocious Lunge": KH1ItemData("Abilities", code = 264_3047, classification = ItemClassification.useful, type = "Ability", ), + #"Furious Bellow": KH1ItemData("Abilities", code = 264_3048, classification = ItemClassification.useful, type = "Ability", ), + #"Spiral Wave": KH1ItemData("Abilities", code = 264_3049, classification = ItemClassification.useful, type = "Ability", ), + #"Thunder Potion": KH1ItemData("Abilities", code = 264_3050, classification = ItemClassification.useful, type = "Ability", ), + #"Cure Potion": KH1ItemData("Abilities", code = 264_3051, classification = ItemClassification.useful, type = "Ability", ), + #"Aero Potion": KH1ItemData("Abilities", code = 264_3052, classification = ItemClassification.useful, type = "Ability", ), + "Slapshot": KH1ItemData("Abilities", code = 264_3053, classification = ItemClassification.useful, type = "Ability", ), + "Sliding Dash": KH1ItemData("Abilities", code = 264_3054, classification = ItemClassification.useful, type = "Ability", ), + "Hurricane Blast": KH1ItemData("Abilities", code = 264_3055, classification = ItemClassification.useful, type = "Ability", ), + "Ripple Drive": KH1ItemData("Abilities", code = 264_3056, classification = ItemClassification.useful, type = "Ability", ), + "Stun Impact": KH1ItemData("Abilities", code = 264_3057, classification = ItemClassification.useful, type = "Ability", ), + "Gravity Break": KH1ItemData("Abilities", code = 264_3058, classification = ItemClassification.useful, type = "Ability", ), + "Zantetsuken": KH1ItemData("Abilities", code = 264_3059, classification = ItemClassification.useful, type = "Ability", ), + "Tech Boost": KH1ItemData("Abilities", code = 264_3060, classification = ItemClassification.useful, type = "Ability", max_quantity = 4 ), + "Encounter Plus": KH1ItemData("Abilities", code = 264_3061, classification = ItemClassification.useful, type = "Ability", ), + "Leaf Bracer": KH1ItemData("Abilities", code = 264_3062, classification = ItemClassification.progression, type = "Ability", ), + #"Evolution": KH1ItemData("Abilities", code = 264_3063, classification = ItemClassification.useful, type = "Ability", ), + "EXP Zero": KH1ItemData("Abilities", code = 264_3064, classification = ItemClassification.useful, type = "Ability", ), + "Combo Master": KH1ItemData("Abilities", code = 264_3065, classification = ItemClassification.progression, type = "Ability", ) } -event_item_table: Dict[str, KH1ItemData] = {} +event_item_table: Dict[str, KH1ItemData] = { + "Victory": KH1ItemData("Event", code = None, classification = ItemClassification.progression, type = "Event") +} #Make item categories item_name_groups: Dict[str, Set[str]] = {} diff --git a/worlds/kh1/Locations.py b/worlds/kh1/Locations.py index a82be70f090b..582d69a8a2d4 100644 --- a/worlds/kh1/Locations.py +++ b/worlds/kh1/Locations.py @@ -11,572 +11,758 @@ class KH1Location(Location): class KH1LocationData(NamedTuple): category: str - code: int + code: Optional[int] = None + type: Optional[str] = None + behind_boss: Optional[bool] = False - -def get_locations_by_category(category: str) -> Dict[str, KH1LocationData]: - location_dict: Dict[str, KH1LocationData] = {} - for name, data in location_table.items(): - if data.category == category: - location_dict.setdefault(name, data) - - return location_dict +def get_locations_by_type(type: str) -> Dict[str, KH1LocationData]: + return {name: data for name, data in location_table.items() if data.type == type} location_table: Dict[str, KH1LocationData] = { - #"Destiny Islands Chest": KH1LocationData("Destiny Islands", 265_0011), missable - "Traverse Town 1st District Candle Puzzle Chest": KH1LocationData("Traverse Town", 265_0211), - "Traverse Town 1st District Accessory Shop Roof Chest": KH1LocationData("Traverse Town", 265_0212), - "Traverse Town 2nd District Boots and Shoes Awning Chest": KH1LocationData("Traverse Town", 265_0213), - "Traverse Town 2nd District Rooftop Chest": KH1LocationData("Traverse Town", 265_0214), - "Traverse Town 2nd District Gizmo Shop Facade Chest": KH1LocationData("Traverse Town", 265_0251), - "Traverse Town Alleyway Balcony Chest": KH1LocationData("Traverse Town", 265_0252), - "Traverse Town Alleyway Blue Room Awning Chest": KH1LocationData("Traverse Town", 265_0253), - "Traverse Town Alleyway Corner Chest": KH1LocationData("Traverse Town", 265_0254), - "Traverse Town Green Room Clock Puzzle Chest": KH1LocationData("Traverse Town", 265_0292), - "Traverse Town Green Room Table Chest": KH1LocationData("Traverse Town", 265_0293), - "Traverse Town Red Room Chest": KH1LocationData("Traverse Town", 265_0294), - "Traverse Town Mystical House Yellow Trinity Chest": KH1LocationData("Traverse Town", 265_0331), - "Traverse Town Accessory Shop Chest": KH1LocationData("Traverse Town", 265_0332), - "Traverse Town Secret Waterway White Trinity Chest": KH1LocationData("Traverse Town", 265_0333), - "Traverse Town Geppetto's House Chest": KH1LocationData("Traverse Town", 265_0334), - "Traverse Town Item Workshop Right Chest": KH1LocationData("Traverse Town", 265_0371), - "Traverse Town 1st District Blue Trinity Balcony Chest": KH1LocationData("Traverse Town", 265_0411), - "Traverse Town Mystical House Glide Chest": KH1LocationData("Traverse Town", 265_0891), - "Traverse Town Alleyway Behind Crates Chest": KH1LocationData("Traverse Town", 265_0892), - "Traverse Town Item Workshop Left Chest": KH1LocationData("Traverse Town", 265_0893), - "Traverse Town Secret Waterway Near Stairs Chest": KH1LocationData("Traverse Town", 265_0894), - "Wonderland Rabbit Hole Green Trinity Chest": KH1LocationData("Wonderland", 265_0931), - "Wonderland Rabbit Hole Defeat Heartless 1 Chest": KH1LocationData("Wonderland", 265_0932), - "Wonderland Rabbit Hole Defeat Heartless 2 Chest": KH1LocationData("Wonderland", 265_0933), - "Wonderland Rabbit Hole Defeat Heartless 3 Chest": KH1LocationData("Wonderland", 265_0934), - "Wonderland Bizarre Room Green Trinity Chest": KH1LocationData("Wonderland", 265_0971), - "Wonderland Queen's Castle Hedge Left Red Chest": KH1LocationData("Wonderland", 265_1011), - "Wonderland Queen's Castle Hedge Right Blue Chest": KH1LocationData("Wonderland", 265_1012), - "Wonderland Queen's Castle Hedge Right Red Chest": KH1LocationData("Wonderland", 265_1013), - "Wonderland Lotus Forest Thunder Plant Chest": KH1LocationData("Wonderland", 265_1014), - "Wonderland Lotus Forest Through the Painting Thunder Plant Chest": KH1LocationData("Wonderland", 265_1051), - "Wonderland Lotus Forest Glide Chest": KH1LocationData("Wonderland", 265_1052), - "Wonderland Lotus Forest Nut Chest": KH1LocationData("Wonderland", 265_1053), - "Wonderland Lotus Forest Corner Chest": KH1LocationData("Wonderland", 265_1054), - "Wonderland Bizarre Room Lamp Chest": KH1LocationData("Wonderland", 265_1091), - "Wonderland Tea Party Garden Above Lotus Forest Entrance 2nd Chest": KH1LocationData("Wonderland", 265_1093), - "Wonderland Tea Party Garden Above Lotus Forest Entrance 1st Chest": KH1LocationData("Wonderland", 265_1094), - "Wonderland Tea Party Garden Bear and Clock Puzzle Chest": KH1LocationData("Wonderland", 265_1131), - "Wonderland Tea Party Garden Across From Bizarre Room Entrance Chest": KH1LocationData("Wonderland", 265_1132), - "Wonderland Lotus Forest Through the Painting White Trinity Chest": KH1LocationData("Wonderland", 265_1133), - "Deep Jungle Tree House Beneath Tree House Chest": KH1LocationData("Deep Jungle", 265_1213), - "Deep Jungle Tree House Rooftop Chest": KH1LocationData("Deep Jungle", 265_1214), - "Deep Jungle Hippo's Lagoon Center Chest": KH1LocationData("Deep Jungle", 265_1251), - "Deep Jungle Hippo's Lagoon Left Chest": KH1LocationData("Deep Jungle", 265_1252), - "Deep Jungle Hippo's Lagoon Right Chest": KH1LocationData("Deep Jungle", 265_1253), - "Deep Jungle Vines Chest": KH1LocationData("Deep Jungle", 265_1291), - "Deep Jungle Vines 2 Chest": KH1LocationData("Deep Jungle", 265_1292), - "Deep Jungle Climbing Trees Blue Trinity Chest": KH1LocationData("Deep Jungle", 265_1293), - "Deep Jungle Tunnel Chest": KH1LocationData("Deep Jungle", 265_1331), - "Deep Jungle Cavern of Hearts White Trinity Chest": KH1LocationData("Deep Jungle", 265_1332), - "Deep Jungle Camp Blue Trinity Chest": KH1LocationData("Deep Jungle", 265_1333), - "Deep Jungle Tent Chest": KH1LocationData("Deep Jungle", 265_1334), - "Deep Jungle Waterfall Cavern Low Chest": KH1LocationData("Deep Jungle", 265_1371), - "Deep Jungle Waterfall Cavern Middle Chest": KH1LocationData("Deep Jungle", 265_1372), - "Deep Jungle Waterfall Cavern High Wall Chest": KH1LocationData("Deep Jungle", 265_1373), - "Deep Jungle Waterfall Cavern High Middle Chest": KH1LocationData("Deep Jungle", 265_1374), - "Deep Jungle Cliff Right Cliff Left Chest": KH1LocationData("Deep Jungle", 265_1411), - "Deep Jungle Cliff Right Cliff Right Chest": KH1LocationData("Deep Jungle", 265_1412), - "Deep Jungle Tree House Suspended Boat Chest": KH1LocationData("Deep Jungle", 265_1413), - "100 Acre Wood Meadow Inside Log Chest": KH1LocationData("100 Acre Wood", 265_1654), - "100 Acre Wood Bouncing Spot Left Cliff Chest": KH1LocationData("100 Acre Wood", 265_1691), - "100 Acre Wood Bouncing Spot Right Tree Alcove Chest": KH1LocationData("100 Acre Wood", 265_1692), - "100 Acre Wood Bouncing Spot Under Giant Pot Chest": KH1LocationData("100 Acre Wood", 265_1693), - "Agrabah Plaza By Storage Chest": KH1LocationData("Agrabah", 265_1972), - "Agrabah Plaza Raised Terrace Chest": KH1LocationData("Agrabah", 265_1973), - "Agrabah Plaza Top Corner Chest": KH1LocationData("Agrabah", 265_1974), - "Agrabah Alley Chest": KH1LocationData("Agrabah", 265_2011), - "Agrabah Bazaar Across Windows Chest": KH1LocationData("Agrabah", 265_2012), - "Agrabah Bazaar High Corner Chest": KH1LocationData("Agrabah", 265_2013), - "Agrabah Main Street Right Palace Entrance Chest": KH1LocationData("Agrabah", 265_2014), - "Agrabah Main Street High Above Alley Entrance Chest": KH1LocationData("Agrabah", 265_2051), - "Agrabah Main Street High Above Palace Gates Entrance Chest": KH1LocationData("Agrabah", 265_2052), - "Agrabah Palace Gates Low Chest": KH1LocationData("Agrabah", 265_2053), - "Agrabah Palace Gates High Opposite Palace Chest": KH1LocationData("Agrabah", 265_2054), - "Agrabah Palace Gates High Close to Palace Chest": KH1LocationData("Agrabah", 265_2091), - "Agrabah Storage Green Trinity Chest": KH1LocationData("Agrabah", 265_2092), - "Agrabah Storage Behind Barrel Chest": KH1LocationData("Agrabah", 265_2093), - "Agrabah Cave of Wonders Entrance Left Chest": KH1LocationData("Agrabah", 265_2094), - "Agrabah Cave of Wonders Entrance Tall Tower Chest": KH1LocationData("Agrabah", 265_2131), - "Agrabah Cave of Wonders Hall High Left Chest": KH1LocationData("Agrabah", 265_2132), - "Agrabah Cave of Wonders Hall Near Bottomless Hall Chest": KH1LocationData("Agrabah", 265_2133), - "Agrabah Cave of Wonders Bottomless Hall Raised Platform Chest": KH1LocationData("Agrabah", 265_2134), - "Agrabah Cave of Wonders Bottomless Hall Pillar Chest": KH1LocationData("Agrabah", 265_2171), - "Agrabah Cave of Wonders Bottomless Hall Across Chasm Chest": KH1LocationData("Agrabah", 265_2172), - "Agrabah Cave of Wonders Treasure Room Across Platforms Chest": KH1LocationData("Agrabah", 265_2173), - "Agrabah Cave of Wonders Treasure Room Small Treasure Pile Chest": KH1LocationData("Agrabah", 265_2174), - "Agrabah Cave of Wonders Treasure Room Large Treasure Pile Chest": KH1LocationData("Agrabah", 265_2211), - "Agrabah Cave of Wonders Treasure Room Above Fire Chest": KH1LocationData("Agrabah", 265_2212), - "Agrabah Cave of Wonders Relic Chamber Jump from Stairs Chest": KH1LocationData("Agrabah", 265_2213), - "Agrabah Cave of Wonders Relic Chamber Stairs Chest": KH1LocationData("Agrabah", 265_2214), - "Agrabah Cave of Wonders Dark Chamber Abu Gem Chest": KH1LocationData("Agrabah", 265_2251), - "Agrabah Cave of Wonders Dark Chamber Across from Relic Chamber Entrance Chest": KH1LocationData("Agrabah", 265_2252), - "Agrabah Cave of Wonders Dark Chamber Bridge Chest": KH1LocationData("Agrabah", 265_2253), - "Agrabah Cave of Wonders Dark Chamber Near Save Chest": KH1LocationData("Agrabah", 265_2254), - "Agrabah Cave of Wonders Silent Chamber Blue Trinity Chest": KH1LocationData("Agrabah", 265_2291), - "Agrabah Cave of Wonders Hidden Room Right Chest": KH1LocationData("Agrabah", 265_2292), - "Agrabah Cave of Wonders Hidden Room Left Chest": KH1LocationData("Agrabah", 265_2293), - "Agrabah Aladdin's House Main Street Entrance Chest": KH1LocationData("Agrabah", 265_2294), - "Agrabah Aladdin's House Plaza Entrance Chest": KH1LocationData("Agrabah", 265_2331), - "Agrabah Cave of Wonders Entrance White Trinity Chest": KH1LocationData("Agrabah", 265_2332), - "Monstro Chamber 6 Other Platform Chest": KH1LocationData("Monstro", 265_2413), - "Monstro Chamber 6 Platform Near Chamber 5 Entrance Chest": KH1LocationData("Monstro", 265_2414), - "Monstro Chamber 6 Raised Area Near Chamber 1 Entrance Chest": KH1LocationData("Monstro", 265_2451), - "Monstro Chamber 6 Low Chest": KH1LocationData("Monstro", 265_2452), - "Atlantica Sunken Ship In Flipped Boat Chest": KH1LocationData("Atlantica", 265_2531), - "Atlantica Sunken Ship Seabed Chest": KH1LocationData("Atlantica", 265_2532), - "Atlantica Sunken Ship Inside Ship Chest": KH1LocationData("Atlantica", 265_2533), - "Atlantica Ariel's Grotto High Chest": KH1LocationData("Atlantica", 265_2534), - "Atlantica Ariel's Grotto Middle Chest": KH1LocationData("Atlantica", 265_2571), - "Atlantica Ariel's Grotto Low Chest": KH1LocationData("Atlantica", 265_2572), - "Atlantica Ursula's Lair Use Fire on Urchin Chest": KH1LocationData("Atlantica", 265_2573), - "Atlantica Undersea Gorge Jammed by Ariel's Grotto Chest": KH1LocationData("Atlantica", 265_2574), - "Atlantica Triton's Palace White Trinity Chest": KH1LocationData("Atlantica", 265_2611), - "Halloween Town Moonlight Hill White Trinity Chest": KH1LocationData("Halloween Town", 265_3014), - "Halloween Town Bridge Under Bridge": KH1LocationData("Halloween Town", 265_3051), - "Halloween Town Boneyard Tombstone Puzzle Chest": KH1LocationData("Halloween Town", 265_3052), - "Halloween Town Bridge Right of Gate Chest": KH1LocationData("Halloween Town", 265_3053), - "Halloween Town Cemetery Behind Grave Chest": KH1LocationData("Halloween Town", 265_3054), - "Halloween Town Cemetery By Cat Shape Chest": KH1LocationData("Halloween Town", 265_3091), - "Halloween Town Cemetery Between Graves Chest": KH1LocationData("Halloween Town", 265_3092), - "Halloween Town Oogie's Manor Lower Iron Cage Chest": KH1LocationData("Halloween Town", 265_3093), - "Halloween Town Oogie's Manor Upper Iron Cage Chest": KH1LocationData("Halloween Town", 265_3094), - "Halloween Town Oogie's Manor Hollow Chest": KH1LocationData("Halloween Town", 265_3131), - "Halloween Town Oogie's Manor Grounds Red Trinity Chest": KH1LocationData("Halloween Town", 265_3132), - "Halloween Town Guillotine Square High Tower Chest": KH1LocationData("Halloween Town", 265_3133), - "Halloween Town Guillotine Square Pumpkin Structure Left Chest": KH1LocationData("Halloween Town", 265_3134), - "Halloween Town Oogie's Manor Entrance Steps Chest": KH1LocationData("Halloween Town", 265_3171), - "Halloween Town Oogie's Manor Inside Entrance Chest": KH1LocationData("Halloween Town", 265_3172), - "Halloween Town Bridge Left of Gate Chest": KH1LocationData("Halloween Town", 265_3291), - "Halloween Town Cemetery By Striped Grave Chest": KH1LocationData("Halloween Town", 265_3292), - "Halloween Town Guillotine Square Under Jack's House Stairs Chest": KH1LocationData("Halloween Town", 265_3293), - "Halloween Town Guillotine Square Pumpkin Structure Right Chest": KH1LocationData("Halloween Town", 265_3294), - "Olympus Coliseum Coliseum Gates Left Behind Columns Chest": KH1LocationData("Olympus Coliseum", 265_3332), - "Olympus Coliseum Coliseum Gates Right Blue Trinity Chest": KH1LocationData("Olympus Coliseum", 265_3333), - "Olympus Coliseum Coliseum Gates Left Blue Trinity Chest": KH1LocationData("Olympus Coliseum", 265_3334), - "Olympus Coliseum Coliseum Gates White Trinity Chest": KH1LocationData("Olympus Coliseum", 265_3371), - "Olympus Coliseum Coliseum Gates Blizzara Chest": KH1LocationData("Olympus Coliseum", 265_3372), - "Olympus Coliseum Coliseum Gates Blizzaga Chest": KH1LocationData("Olympus Coliseum", 265_3373), - "Monstro Mouth Boat Deck Chest": KH1LocationData("Monstro", 265_3454), - "Monstro Mouth High Platform Boat Side Chest": KH1LocationData("Monstro", 265_3491), - "Monstro Mouth High Platform Across from Boat Chest": KH1LocationData("Monstro", 265_3492), - "Monstro Mouth Near Ship Chest": KH1LocationData("Monstro", 265_3493), - "Monstro Mouth Green Trinity Top of Boat Chest": KH1LocationData("Monstro", 265_3494), - "Monstro Chamber 2 Ground Chest": KH1LocationData("Monstro", 265_3534), - "Monstro Chamber 2 Platform Chest": KH1LocationData("Monstro", 265_3571), - "Monstro Chamber 5 Platform Chest": KH1LocationData("Monstro", 265_3613), - "Monstro Chamber 3 Ground Chest": KH1LocationData("Monstro", 265_3614), - "Monstro Chamber 3 Platform Above Chamber 2 Entrance Chest": KH1LocationData("Monstro", 265_3651), - "Monstro Chamber 3 Near Chamber 6 Entrance Chest": KH1LocationData("Monstro", 265_3652), - "Monstro Chamber 3 Platform Near Chamber 6 Entrance Chest": KH1LocationData("Monstro", 265_3653), - "Monstro Mouth High Platform Near Teeth Chest": KH1LocationData("Monstro", 265_3732), - "Monstro Chamber 5 Atop Barrel Chest": KH1LocationData("Monstro", 265_3733), - "Monstro Chamber 5 Low 2nd Chest": KH1LocationData("Monstro", 265_3734), - "Monstro Chamber 5 Low 1st Chest": KH1LocationData("Monstro", 265_3771), - "Neverland Pirate Ship Deck White Trinity Chest": KH1LocationData("Neverland", 265_3772), - "Neverland Pirate Ship Crows Nest Chest": KH1LocationData("Neverland", 265_3773), - "Neverland Hold Yellow Trinity Right Blue Chest": KH1LocationData("Neverland", 265_3774), - "Neverland Hold Yellow Trinity Left Blue Chest": KH1LocationData("Neverland", 265_3811), - "Neverland Galley Chest": KH1LocationData("Neverland", 265_3812), - "Neverland Cabin Chest": KH1LocationData("Neverland", 265_3813), - "Neverland Hold Flight 1st Chest": KH1LocationData("Neverland", 265_3814), - "Neverland Clock Tower Chest": KH1LocationData("Neverland", 265_4014), - "Neverland Hold Flight 2nd Chest": KH1LocationData("Neverland", 265_4051), - "Neverland Hold Yellow Trinity Green Chest": KH1LocationData("Neverland", 265_4052), - "Neverland Captain's Cabin Chest": KH1LocationData("Neverland", 265_4053), - "Hollow Bastion Rising Falls Water's Surface Chest": KH1LocationData("Hollow Bastion", 265_4054), - "Hollow Bastion Rising Falls Under Water 1st Chest": KH1LocationData("Hollow Bastion", 265_4091), - "Hollow Bastion Rising Falls Under Water 2nd Chest": KH1LocationData("Hollow Bastion", 265_4092), - "Hollow Bastion Rising Falls Floating Platform Near Save Chest": KH1LocationData("Hollow Bastion", 265_4093), - "Hollow Bastion Rising Falls Floating Platform Near Bubble Chest": KH1LocationData("Hollow Bastion", 265_4094), - "Hollow Bastion Rising Falls High Platform Chest": KH1LocationData("Hollow Bastion", 265_4131), - "Hollow Bastion Castle Gates Gravity Chest": KH1LocationData("Hollow Bastion", 265_4132), - "Hollow Bastion Castle Gates Freestanding Pillar Chest": KH1LocationData("Hollow Bastion", 265_4133), - "Hollow Bastion Castle Gates High Pillar Chest": KH1LocationData("Hollow Bastion", 265_4134), - "Hollow Bastion Great Crest Lower Chest": KH1LocationData("Hollow Bastion", 265_4171), - "Hollow Bastion Great Crest After Battle Platform Chest": KH1LocationData("Hollow Bastion", 265_4172), - "Hollow Bastion High Tower 2nd Gravity Chest": KH1LocationData("Hollow Bastion", 265_4173), - "Hollow Bastion High Tower 1st Gravity Chest": KH1LocationData("Hollow Bastion", 265_4174), - "Hollow Bastion High Tower Above Sliding Blocks Chest": KH1LocationData("Hollow Bastion", 265_4211), - "Hollow Bastion Library Top of Bookshelf Chest": KH1LocationData("Hollow Bastion", 265_4213), - "Hollow Bastion Library 1st Floor Turn the Carousel Chest": KH1LocationData("Hollow Bastion", 265_4214), - "Hollow Bastion Library Top of Bookshelf Turn the Carousel Chest": KH1LocationData("Hollow Bastion", 265_4251), - "Hollow Bastion Library 2nd Floor Turn the Carousel 1st Chest": KH1LocationData("Hollow Bastion", 265_4252), - "Hollow Bastion Library 2nd Floor Turn the Carousel 2nd Chest": KH1LocationData("Hollow Bastion", 265_4253), - "Hollow Bastion Lift Stop Library Node After High Tower Switch Gravity Chest": KH1LocationData("Hollow Bastion", 265_4254), - "Hollow Bastion Lift Stop Library Node Gravity Chest": KH1LocationData("Hollow Bastion", 265_4291), - "Hollow Bastion Lift Stop Under High Tower Sliding Blocks Chest": KH1LocationData("Hollow Bastion", 265_4292), - "Hollow Bastion Lift Stop Outside Library Gravity Chest": KH1LocationData("Hollow Bastion", 265_4293), - "Hollow Bastion Lift Stop Heartless Sigil Door Gravity Chest": KH1LocationData("Hollow Bastion", 265_4294), - "Hollow Bastion Base Level Bubble Under the Wall Platform Chest": KH1LocationData("Hollow Bastion", 265_4331), - "Hollow Bastion Base Level Platform Near Entrance Chest": KH1LocationData("Hollow Bastion", 265_4332), - "Hollow Bastion Base Level Near Crystal Switch Chest": KH1LocationData("Hollow Bastion", 265_4333), - "Hollow Bastion Waterway Near Save Chest": KH1LocationData("Hollow Bastion", 265_4334), - "Hollow Bastion Waterway Blizzard on Bubble Chest": KH1LocationData("Hollow Bastion", 265_4371), - "Hollow Bastion Waterway Unlock Passage from Base Level Chest": KH1LocationData("Hollow Bastion", 265_4372), - "Hollow Bastion Dungeon By Candles Chest": KH1LocationData("Hollow Bastion", 265_4373), - "Hollow Bastion Dungeon Corner Chest": KH1LocationData("Hollow Bastion", 265_4374), - "Hollow Bastion Grand Hall Steps Right Side Chest": KH1LocationData("Hollow Bastion", 265_4454), - "Hollow Bastion Grand Hall Oblivion Chest": KH1LocationData("Hollow Bastion", 265_4491), - "Hollow Bastion Grand Hall Left of Gate Chest": KH1LocationData("Hollow Bastion", 265_4492), - #"Hollow Bastion Entrance Hall Push the Statue Chest": KH1LocationData("Hollow Bastion", 265_4493), --handled later - "Hollow Bastion Entrance Hall Left of Emblem Door Chest": KH1LocationData("Hollow Bastion", 265_4212), - "Hollow Bastion Rising Falls White Trinity Chest": KH1LocationData("Hollow Bastion", 265_4494), - "End of the World Final Dimension 1st Chest": KH1LocationData("End of the World", 265_4531), - "End of the World Final Dimension 2nd Chest": KH1LocationData("End of the World", 265_4532), - "End of the World Final Dimension 3rd Chest": KH1LocationData("End of the World", 265_4533), - "End of the World Final Dimension 4th Chest": KH1LocationData("End of the World", 265_4534), - "End of the World Final Dimension 5th Chest": KH1LocationData("End of the World", 265_4571), - "End of the World Final Dimension 6th Chest": KH1LocationData("End of the World", 265_4572), - "End of the World Final Dimension 10th Chest": KH1LocationData("End of the World", 265_4573), - "End of the World Final Dimension 9th Chest": KH1LocationData("End of the World", 265_4574), - "End of the World Final Dimension 8th Chest": KH1LocationData("End of the World", 265_4611), - "End of the World Final Dimension 7th Chest": KH1LocationData("End of the World", 265_4612), - "End of the World Giant Crevasse 3rd Chest": KH1LocationData("End of the World", 265_4613), - "End of the World Giant Crevasse 5th Chest": KH1LocationData("End of the World", 265_4614), - "End of the World Giant Crevasse 1st Chest": KH1LocationData("End of the World", 265_4651), - "End of the World Giant Crevasse 4th Chest": KH1LocationData("End of the World", 265_4652), - "End of the World Giant Crevasse 2nd Chest": KH1LocationData("End of the World", 265_4653), - "End of the World World Terminus Traverse Town Chest": KH1LocationData("End of the World", 265_4654), - "End of the World World Terminus Wonderland Chest": KH1LocationData("End of the World", 265_4691), - "End of the World World Terminus Olympus Coliseum Chest": KH1LocationData("End of the World", 265_4692), - "End of the World World Terminus Deep Jungle Chest": KH1LocationData("End of the World", 265_4693), - "End of the World World Terminus Agrabah Chest": KH1LocationData("End of the World", 265_4694), - "End of the World World Terminus Atlantica Chest": KH1LocationData("End of the World", 265_4731), - "End of the World World Terminus Halloween Town Chest": KH1LocationData("End of the World", 265_4732), - "End of the World World Terminus Neverland Chest": KH1LocationData("End of the World", 265_4733), - "End of the World World Terminus 100 Acre Wood Chest": KH1LocationData("End of the World", 265_4734), - #"End of the World World Terminus Hollow Bastion Chest": KH1LocationData("End of the World", 265_4771), - "End of the World Final Rest Chest": KH1LocationData("End of the World", 265_4772), - "Monstro Chamber 6 White Trinity Chest": KH1LocationData("End of the World", 265_5092), - #"Awakening Chest": KH1LocationData("Awakening", 265_5093), missable + "Destiny Islands Chest": KH1LocationData("Destiny Islands", 265_0011, "Chest"), + "Traverse Town 1st District Candle Puzzle Chest": KH1LocationData("Traverse Town", 265_0211, "Chest"), + "Traverse Town 1st District Accessory Shop Roof Chest": KH1LocationData("Traverse Town", 265_0212, "Chest"), + "Traverse Town 2nd District Boots and Shoes Awning Chest": KH1LocationData("Traverse Town", 265_0213, "Chest"), + "Traverse Town 2nd District Rooftop Chest": KH1LocationData("Traverse Town", 265_0214, "Chest"), + "Traverse Town 2nd District Gizmo Shop Facade Chest": KH1LocationData("Traverse Town", 265_0251, "Chest"), + "Traverse Town Alleyway Balcony Chest": KH1LocationData("Traverse Town", 265_0252, "Chest"), + "Traverse Town Alleyway Blue Room Awning Chest": KH1LocationData("Traverse Town", 265_0253, "Chest"), + "Traverse Town Alleyway Corner Chest": KH1LocationData("Traverse Town", 265_0254, "Chest"), + "Traverse Town Green Room Clock Puzzle Chest": KH1LocationData("Traverse Town", 265_0292, "Chest"), + "Traverse Town Green Room Table Chest": KH1LocationData("Traverse Town", 265_0293, "Chest"), + "Traverse Town Red Room Chest": KH1LocationData("Traverse Town", 265_0294, "Chest"), + "Traverse Town Mystical House Yellow Trinity Chest": KH1LocationData("Traverse Town", 265_0331, "Chest"), + "Traverse Town Accessory Shop Chest": KH1LocationData("Traverse Town", 265_0332, "Chest"), + "Traverse Town Secret Waterway White Trinity Chest": KH1LocationData("Traverse Town", 265_0333, "Chest"), + "Traverse Town Geppetto's House Chest": KH1LocationData("Traverse Town", 265_0334, "Chest", True), + "Traverse Town Item Workshop Right Chest": KH1LocationData("Traverse Town", 265_0371, "Chest"), + "Traverse Town 1st District Blue Trinity Balcony Chest": KH1LocationData("Traverse Town", 265_0411, "Chest"), + "Traverse Town Mystical House Glide Chest": KH1LocationData("Traverse Town", 265_0891, "Chest"), + "Traverse Town Alleyway Behind Crates Chest": KH1LocationData("Traverse Town", 265_0892, "Chest"), + "Traverse Town Item Workshop Left Chest": KH1LocationData("Traverse Town", 265_0893, "Chest"), + "Traverse Town Secret Waterway Near Stairs Chest": KH1LocationData("Traverse Town", 265_0894, "Chest"), + "Wonderland Rabbit Hole Green Trinity Chest": KH1LocationData("Wonderland", 265_0931, "Chest"), + "Wonderland Rabbit Hole Defeat Heartless 1 Chest": KH1LocationData("Wonderland", 265_0932, "Chest"), + "Wonderland Rabbit Hole Defeat Heartless 2 Chest": KH1LocationData("Wonderland", 265_0933, "Chest"), + "Wonderland Rabbit Hole Defeat Heartless 3 Chest": KH1LocationData("Wonderland", 265_0934, "Chest"), + "Wonderland Bizarre Room Green Trinity Chest": KH1LocationData("Wonderland", 265_0971, "Chest"), + "Wonderland Queen's Castle Hedge Left Red Chest": KH1LocationData("Wonderland", 265_1011, "Chest"), + "Wonderland Queen's Castle Hedge Right Blue Chest": KH1LocationData("Wonderland", 265_1012, "Chest"), + "Wonderland Queen's Castle Hedge Right Red Chest": KH1LocationData("Wonderland", 265_1013, "Chest"), + "Wonderland Lotus Forest Thunder Plant Chest": KH1LocationData("Wonderland", 265_1014, "Chest"), + "Wonderland Lotus Forest Through the Painting Thunder Plant Chest": KH1LocationData("Wonderland", 265_1051, "Chest"), + "Wonderland Lotus Forest Glide Chest": KH1LocationData("Wonderland", 265_1052, "Chest"), + "Wonderland Lotus Forest Nut Chest": KH1LocationData("Wonderland", 265_1053, "Chest"), + "Wonderland Lotus Forest Corner Chest": KH1LocationData("Wonderland", 265_1054, "Chest"), + "Wonderland Bizarre Room Lamp Chest": KH1LocationData("Wonderland", 265_1091, "Chest"), + "Wonderland Tea Party Garden Above Lotus Forest Entrance 2nd Chest": KH1LocationData("Wonderland", 265_1093, "Chest"), + "Wonderland Tea Party Garden Above Lotus Forest Entrance 1st Chest": KH1LocationData("Wonderland", 265_1094, "Chest"), + "Wonderland Tea Party Garden Bear and Clock Puzzle Chest": KH1LocationData("Wonderland", 265_1131, "Chest"), + "Wonderland Tea Party Garden Across From Bizarre Room Entrance Chest": KH1LocationData("Wonderland", 265_1132, "Chest"), + "Wonderland Lotus Forest Through the Painting White Trinity Chest": KH1LocationData("Wonderland", 265_1133, "Chest"), + "Deep Jungle Tree House Beneath Tree House Chest": KH1LocationData("Deep Jungle", 265_1213, "Chest"), + "Deep Jungle Tree House Rooftop Chest": KH1LocationData("Deep Jungle", 265_1214, "Chest"), + "Deep Jungle Hippo's Lagoon Center Chest": KH1LocationData("Deep Jungle", 265_1251, "Chest"), + "Deep Jungle Hippo's Lagoon Left Chest": KH1LocationData("Deep Jungle", 265_1252, "Chest"), + "Deep Jungle Hippo's Lagoon Right Chest": KH1LocationData("Deep Jungle", 265_1253, "Chest"), + "Deep Jungle Vines Chest": KH1LocationData("Deep Jungle", 265_1291, "Chest"), + "Deep Jungle Vines 2 Chest": KH1LocationData("Deep Jungle", 265_1292, "Chest"), + "Deep Jungle Climbing Trees Blue Trinity Chest": KH1LocationData("Deep Jungle", 265_1293, "Chest"), + "Deep Jungle Tunnel Chest": KH1LocationData("Deep Jungle", 265_1331, "Chest"), + "Deep Jungle Cavern of Hearts White Trinity Chest": KH1LocationData("Deep Jungle", 265_1332, "Chest", True), + "Deep Jungle Camp Blue Trinity Chest": KH1LocationData("Deep Jungle", 265_1333, "Chest"), + "Deep Jungle Tent Chest": KH1LocationData("Deep Jungle", 265_1334, "Chest"), + "Deep Jungle Waterfall Cavern Low Chest": KH1LocationData("Deep Jungle", 265_1371, "Chest", True), + "Deep Jungle Waterfall Cavern Middle Chest": KH1LocationData("Deep Jungle", 265_1372, "Chest", True), + "Deep Jungle Waterfall Cavern High Wall Chest": KH1LocationData("Deep Jungle", 265_1373, "Chest", True), + "Deep Jungle Waterfall Cavern High Middle Chest": KH1LocationData("Deep Jungle", 265_1374, "Chest", True), + "Deep Jungle Cliff Right Cliff Left Chest": KH1LocationData("Deep Jungle", 265_1411, "Chest"), + "Deep Jungle Cliff Right Cliff Right Chest": KH1LocationData("Deep Jungle", 265_1412, "Chest"), + "Deep Jungle Tree House Suspended Boat Chest": KH1LocationData("Deep Jungle", 265_1413, "Chest"), + "100 Acre Wood Meadow Inside Log Chest": KH1LocationData("100 Acre Wood", 265_1654, "Chest"), + "100 Acre Wood Bouncing Spot Left Cliff Chest": KH1LocationData("100 Acre Wood", 265_1691, "Chest"), + "100 Acre Wood Bouncing Spot Right Tree Alcove Chest": KH1LocationData("100 Acre Wood", 265_1692, "Chest"), + "100 Acre Wood Bouncing Spot Under Giant Pot Chest": KH1LocationData("100 Acre Wood", 265_1693, "Chest"), + "Agrabah Plaza By Storage Chest": KH1LocationData("Agrabah", 265_1972, "Chest"), + "Agrabah Plaza Raised Terrace Chest": KH1LocationData("Agrabah", 265_1973, "Chest"), + "Agrabah Plaza Top Corner Chest": KH1LocationData("Agrabah", 265_1974, "Chest"), + "Agrabah Alley Chest": KH1LocationData("Agrabah", 265_2011, "Chest"), + "Agrabah Bazaar Across Windows Chest": KH1LocationData("Agrabah", 265_2012, "Chest"), + "Agrabah Bazaar High Corner Chest": KH1LocationData("Agrabah", 265_2013, "Chest"), + "Agrabah Main Street Right Palace Entrance Chest": KH1LocationData("Agrabah", 265_2014, "Chest"), + "Agrabah Main Street High Above Alley Entrance Chest": KH1LocationData("Agrabah", 265_2051, "Chest"), + "Agrabah Main Street High Above Palace Gates Entrance Chest": KH1LocationData("Agrabah", 265_2052, "Chest"), + "Agrabah Palace Gates Low Chest": KH1LocationData("Agrabah", 265_2053, "Chest", True), + "Agrabah Palace Gates High Opposite Palace Chest": KH1LocationData("Agrabah", 265_2054, "Chest", True), + "Agrabah Palace Gates High Close to Palace Chest": KH1LocationData("Agrabah", 265_2091, "Chest", True), + "Agrabah Storage Green Trinity Chest": KH1LocationData("Agrabah", 265_2092, "Chest"), + "Agrabah Storage Behind Barrel Chest": KH1LocationData("Agrabah", 265_2093, "Chest"), + "Agrabah Cave of Wonders Entrance Left Chest": KH1LocationData("Agrabah", 265_2094, "Chest", True), + "Agrabah Cave of Wonders Entrance Tall Tower Chest": KH1LocationData("Agrabah", 265_2131, "Chest", True), + "Agrabah Cave of Wonders Hall High Left Chest": KH1LocationData("Agrabah", 265_2132, "Chest", True), + "Agrabah Cave of Wonders Hall Near Bottomless Hall Chest": KH1LocationData("Agrabah", 265_2133, "Chest", True), + "Agrabah Cave of Wonders Bottomless Hall Raised Platform Chest": KH1LocationData("Agrabah", 265_2134, "Chest", True), + "Agrabah Cave of Wonders Bottomless Hall Pillar Chest": KH1LocationData("Agrabah", 265_2171, "Chest", True), + "Agrabah Cave of Wonders Bottomless Hall Across Chasm Chest": KH1LocationData("Agrabah", 265_2172, "Chest", True), + "Agrabah Cave of Wonders Treasure Room Across Platforms Chest": KH1LocationData("Agrabah", 265_2173, "Chest", True), + "Agrabah Cave of Wonders Treasure Room Small Treasure Pile Chest": KH1LocationData("Agrabah", 265_2174, "Chest", True), + "Agrabah Cave of Wonders Treasure Room Large Treasure Pile Chest": KH1LocationData("Agrabah", 265_2211, "Chest", True), + "Agrabah Cave of Wonders Treasure Room Above Fire Chest": KH1LocationData("Agrabah", 265_2212, "Chest", True), + "Agrabah Cave of Wonders Relic Chamber Jump from Stairs Chest": KH1LocationData("Agrabah", 265_2213, "Chest", True), + "Agrabah Cave of Wonders Relic Chamber Stairs Chest": KH1LocationData("Agrabah", 265_2214, "Chest", True), + "Agrabah Cave of Wonders Dark Chamber Abu Gem Chest": KH1LocationData("Agrabah", 265_2251, "Chest", True), + "Agrabah Cave of Wonders Dark Chamber Across from Relic Chamber Entrance Chest": KH1LocationData("Agrabah", 265_2252, "Chest", True), + "Agrabah Cave of Wonders Dark Chamber Bridge Chest": KH1LocationData("Agrabah", 265_2253, "Chest", True), + "Agrabah Cave of Wonders Dark Chamber Near Save Chest": KH1LocationData("Agrabah", 265_2254, "Chest", True), + "Agrabah Cave of Wonders Silent Chamber Blue Trinity Chest": KH1LocationData("Agrabah", 265_2291, "Chest", True), + "Agrabah Cave of Wonders Hidden Room Right Chest": KH1LocationData("Agrabah", 265_2292, "Chest", True), + "Agrabah Cave of Wonders Hidden Room Left Chest": KH1LocationData("Agrabah", 265_2293, "Chest", True), + "Agrabah Aladdin's House Main Street Entrance Chest": KH1LocationData("Agrabah", 265_2294, "Chest"), + "Agrabah Aladdin's House Plaza Entrance Chest": KH1LocationData("Agrabah", 265_2331, "Chest"), + "Agrabah Cave of Wonders Entrance White Trinity Chest": KH1LocationData("Agrabah", 265_2332, "Chest", True), + "Monstro Chamber 6 Other Platform Chest": KH1LocationData("Monstro", 265_2413, "Chest"), + "Monstro Chamber 6 Platform Near Chamber 5 Entrance Chest": KH1LocationData("Monstro", 265_2414, "Chest"), + "Monstro Chamber 6 Raised Area Near Chamber 1 Entrance Chest": KH1LocationData("Monstro", 265_2451, "Chest"), + "Monstro Chamber 6 Low Chest": KH1LocationData("Monstro", 265_2452, "Chest"), + "Atlantica Sunken Ship In Flipped Boat Chest": KH1LocationData("Atlantica", 265_2531, "Static"), + "Atlantica Sunken Ship Seabed Chest": KH1LocationData("Atlantica", 265_2532, "Static"), + "Atlantica Sunken Ship Inside Ship Chest": KH1LocationData("Atlantica", 265_2533, "Static"), + "Atlantica Ariel's Grotto High Chest": KH1LocationData("Atlantica", 265_2534, "Static"), + "Atlantica Ariel's Grotto Middle Chest": KH1LocationData("Atlantica", 265_2571, "Static"), + "Atlantica Ariel's Grotto Low Chest": KH1LocationData("Atlantica", 265_2572, "Static"), + "Atlantica Ursula's Lair Use Fire on Urchin Chest": KH1LocationData("Atlantica", 265_2573, "Static", True), + "Atlantica Undersea Gorge Jammed by Ariel's Grotto Chest": KH1LocationData("Atlantica", 265_2574, "Static"), + "Atlantica Triton's Palace White Trinity Chest": KH1LocationData("Atlantica", 265_2611, "Static"), + "Halloween Town Moonlight Hill White Trinity Chest": KH1LocationData("Halloween Town", 265_3014, "Chest"), + "Halloween Town Bridge Under Bridge": KH1LocationData("Halloween Town", 265_3051, "Chest"), + "Halloween Town Boneyard Tombstone Puzzle Chest": KH1LocationData("Halloween Town", 265_3052, "Chest"), + "Halloween Town Bridge Right of Gate Chest": KH1LocationData("Halloween Town", 265_3053, "Chest"), + "Halloween Town Cemetery Behind Grave Chest": KH1LocationData("Halloween Town", 265_3054, "Chest", True), + "Halloween Town Cemetery By Cat Shape Chest": KH1LocationData("Halloween Town", 265_3091, "Chest", True), + "Halloween Town Cemetery Between Graves Chest": KH1LocationData("Halloween Town", 265_3092, "Chest", True), + "Halloween Town Oogie's Manor Lower Iron Cage Chest": KH1LocationData("Halloween Town", 265_3093, "Chest"), + "Halloween Town Oogie's Manor Upper Iron Cage Chest": KH1LocationData("Halloween Town", 265_3094, "Chest"), + "Halloween Town Oogie's Manor Hollow Chest": KH1LocationData("Halloween Town", 265_3131, "Chest", True), + "Halloween Town Oogie's Manor Grounds Red Trinity Chest": KH1LocationData("Halloween Town", 265_3132, "Chest"), + "Halloween Town Guillotine Square High Tower Chest": KH1LocationData("Halloween Town", 265_3133, "Chest"), + "Halloween Town Guillotine Square Pumpkin Structure Left Chest": KH1LocationData("Halloween Town", 265_3134, "Chest"), + "Halloween Town Oogie's Manor Entrance Steps Chest": KH1LocationData("Halloween Town", 265_3171, "Chest"), + "Halloween Town Oogie's Manor Inside Entrance Chest": KH1LocationData("Halloween Town", 265_3172, "Chest"), + "Halloween Town Bridge Left of Gate Chest": KH1LocationData("Halloween Town", 265_3291, "Chest"), + "Halloween Town Cemetery By Striped Grave Chest": KH1LocationData("Halloween Town", 265_3292, "Chest", True), + "Halloween Town Guillotine Square Under Jack's House Stairs Chest": KH1LocationData("Halloween Town", 265_3293, "Chest"), + "Halloween Town Guillotine Square Pumpkin Structure Right Chest": KH1LocationData("Halloween Town", 265_3294, "Chest"), + "Olympus Coliseum Coliseum Gates Left Behind Columns Chest": KH1LocationData("Olympus Coliseum", 265_3332, "Chest"), + "Olympus Coliseum Coliseum Gates Right Blue Trinity Chest": KH1LocationData("Olympus Coliseum", 265_3333, "Chest"), + "Olympus Coliseum Coliseum Gates Left Blue Trinity Chest": KH1LocationData("Olympus Coliseum", 265_3334, "Chest"), + "Olympus Coliseum Coliseum Gates White Trinity Chest": KH1LocationData("Olympus Coliseum", 265_3371, "Chest"), + "Olympus Coliseum Coliseum Gates Blizzara Chest": KH1LocationData("Olympus Coliseum", 265_3372, "Chest"), + "Olympus Coliseum Coliseum Gates Blizzaga Chest": KH1LocationData("Olympus Coliseum", 265_3373, "Chest"), + "Monstro Mouth Boat Deck Chest": KH1LocationData("Monstro", 265_3454, "Chest", True), + "Monstro Mouth High Platform Boat Side Chest": KH1LocationData("Monstro", 265_3491, "Chest"), + "Monstro Mouth High Platform Across from Boat Chest": KH1LocationData("Monstro", 265_3492, "Chest"), + "Monstro Mouth Near Ship Chest": KH1LocationData("Monstro", 265_3493, "Chest"), + "Monstro Mouth Green Trinity Top of Boat Chest": KH1LocationData("Monstro", 265_3494, "Chest", True), + "Monstro Chamber 2 Ground Chest": KH1LocationData("Monstro", 265_3534, "Chest"), + "Monstro Chamber 2 Platform Chest": KH1LocationData("Monstro", 265_3571, "Chest"), + "Monstro Chamber 5 Platform Chest": KH1LocationData("Monstro", 265_3613, "Chest"), + "Monstro Chamber 3 Ground Chest": KH1LocationData("Monstro", 265_3614, "Chest"), + "Monstro Chamber 3 Platform Above Chamber 2 Entrance Chest": KH1LocationData("Monstro", 265_3651, "Chest"), + "Monstro Chamber 3 Near Chamber 6 Entrance Chest": KH1LocationData("Monstro", 265_3652, "Chest"), + "Monstro Chamber 3 Platform Near Chamber 6 Entrance Chest": KH1LocationData("Monstro", 265_3653, "Chest"), + "Monstro Mouth High Platform Near Teeth Chest": KH1LocationData("Monstro", 265_3732, "Chest", True), + "Monstro Chamber 5 Atop Barrel Chest": KH1LocationData("Monstro", 265_3733, "Chest"), + "Monstro Chamber 5 Low 2nd Chest": KH1LocationData("Monstro", 265_3734, "Chest"), + "Monstro Chamber 5 Low 1st Chest": KH1LocationData("Monstro", 265_3771, "Chest"), + "Neverland Pirate Ship Deck White Trinity Chest": KH1LocationData("Neverland", 265_3772, "Chest", True), + "Neverland Pirate Ship Crows Nest Chest": KH1LocationData("Neverland", 265_3773, "Chest", True), + "Neverland Hold Yellow Trinity Right Blue Chest": KH1LocationData("Neverland", 265_3774, "Chest"), + "Neverland Hold Yellow Trinity Left Blue Chest": KH1LocationData("Neverland", 265_3811, "Chest"), + "Neverland Galley Chest": KH1LocationData("Neverland", 265_3812, "Chest"), + "Neverland Cabin Chest": KH1LocationData("Neverland", 265_3813, "Chest", True), + "Neverland Hold Flight 1st Chest": KH1LocationData("Neverland", 265_3814, "Chest", True), + "Neverland Clock Tower Chest": KH1LocationData("Neverland", 265_4014, "Chest", True), + "Neverland Hold Flight 2nd Chest": KH1LocationData("Neverland", 265_4051, "Chest", True), + "Neverland Hold Yellow Trinity Green Chest": KH1LocationData("Neverland", 265_4052, "Chest"), + "Neverland Captain's Cabin Chest": KH1LocationData("Neverland", 265_4053, "Chest", True), + "Hollow Bastion Rising Falls Water's Surface Chest": KH1LocationData("Hollow Bastion", 265_4054, "Chest"), + "Hollow Bastion Rising Falls Under Water 1st Chest": KH1LocationData("Hollow Bastion", 265_4091, "Chest"), + "Hollow Bastion Rising Falls Under Water 2nd Chest": KH1LocationData("Hollow Bastion", 265_4092, "Chest", True), + "Hollow Bastion Rising Falls Floating Platform Near Save Chest": KH1LocationData("Hollow Bastion", 265_4093, "Chest"), + "Hollow Bastion Rising Falls Floating Platform Near Bubble Chest": KH1LocationData("Hollow Bastion", 265_4094, "Chest"), + "Hollow Bastion Rising Falls High Platform Chest": KH1LocationData("Hollow Bastion", 265_4131, "Chest"), + "Hollow Bastion Castle Gates Gravity Chest": KH1LocationData("Hollow Bastion", 265_4132, "Chest"), + "Hollow Bastion Castle Gates Freestanding Pillar Chest": KH1LocationData("Hollow Bastion", 265_4133, "Chest"), + "Hollow Bastion Castle Gates High Pillar Chest": KH1LocationData("Hollow Bastion", 265_4134, "Chest"), + "Hollow Bastion Great Crest Lower Chest": KH1LocationData("Hollow Bastion", 265_4171, "Chest", True), + "Hollow Bastion Great Crest After Battle Platform Chest": KH1LocationData("Hollow Bastion", 265_4172, "Chest", True), + "Hollow Bastion High Tower 2nd Gravity Chest": KH1LocationData("Hollow Bastion", 265_4173, "Chest", True), + "Hollow Bastion High Tower 1st Gravity Chest": KH1LocationData("Hollow Bastion", 265_4174, "Chest", True), + "Hollow Bastion High Tower Above Sliding Blocks Chest": KH1LocationData("Hollow Bastion", 265_4211, "Chest", True), + "Hollow Bastion Library Top of Bookshelf Chest": KH1LocationData("Hollow Bastion", 265_4213, "Chest", True), + "Hollow Bastion Library 1st Floor Turn the Carousel Chest": KH1LocationData("Hollow Bastion", 265_4214, "Static", True), + "Hollow Bastion Library Top of Bookshelf Turn the Carousel Chest": KH1LocationData("Hollow Bastion", 265_4251, "Static", True), + "Hollow Bastion Library 2nd Floor Turn the Carousel 1st Chest": KH1LocationData("Hollow Bastion", 265_4252, "Static", True), + "Hollow Bastion Library 2nd Floor Turn the Carousel 2nd Chest": KH1LocationData("Hollow Bastion", 265_4253, "Static", True), + "Hollow Bastion Lift Stop Library Node After High Tower Switch Gravity Chest": KH1LocationData("Hollow Bastion", 265_4254, "Chest", True), + "Hollow Bastion Lift Stop Library Node Gravity Chest": KH1LocationData("Hollow Bastion", 265_4291, "Chest", True), + "Hollow Bastion Lift Stop Under High Tower Sliding Blocks Chest": KH1LocationData("Hollow Bastion", 265_4292, "Chest", True), + "Hollow Bastion Lift Stop Outside Library Gravity Chest": KH1LocationData("Hollow Bastion", 265_4293, "Chest", True), + "Hollow Bastion Lift Stop Heartless Sigil Door Gravity Chest": KH1LocationData("Hollow Bastion", 265_4294, "Chest", True), + "Hollow Bastion Base Level Bubble Under the Wall Platform Chest": KH1LocationData("Hollow Bastion", 265_4331, "Chest"), + "Hollow Bastion Base Level Platform Near Entrance Chest": KH1LocationData("Hollow Bastion", 265_4332, "Chest"), + "Hollow Bastion Base Level Near Crystal Switch Chest": KH1LocationData("Hollow Bastion", 265_4333, "Chest"), + "Hollow Bastion Waterway Near Save Chest": KH1LocationData("Hollow Bastion", 265_4334, "Chest"), + "Hollow Bastion Waterway Blizzard on Bubble Chest": KH1LocationData("Hollow Bastion", 265_4371, "Chest"), + "Hollow Bastion Waterway Unlock Passage from Base Level Chest": KH1LocationData("Hollow Bastion", 265_4372, "Chest"), + "Hollow Bastion Dungeon By Candles Chest": KH1LocationData("Hollow Bastion", 265_4373, "Chest"), + "Hollow Bastion Dungeon Corner Chest": KH1LocationData("Hollow Bastion", 265_4374, "Chest"), + "Hollow Bastion Grand Hall Steps Right Side Chest": KH1LocationData("Hollow Bastion", 265_4454, "Chest", True), + "Hollow Bastion Grand Hall Oblivion Chest": KH1LocationData("Hollow Bastion", 265_4491, "Chest", True), + "Hollow Bastion Grand Hall Left of Gate Chest": KH1LocationData("Hollow Bastion", 265_4492, "Chest", True), + #"Hollow Bastion Entrance Hall Push the Statue Chest": KH1LocationData("Hollow Bastion", 265_4493, "Static"), --handled later + "Hollow Bastion Entrance Hall Left of Emblem Door Chest": KH1LocationData("Hollow Bastion", 265_4212, "Chest", True), + "Hollow Bastion Rising Falls White Trinity Chest": KH1LocationData("Hollow Bastion", 265_4494, "Chest", True), + "End of the World Final Dimension 1st Chest": KH1LocationData("End of the World", 265_4531, "Chest", True), + "End of the World Final Dimension 2nd Chest": KH1LocationData("End of the World", 265_4532, "Chest", True), + "End of the World Final Dimension 3rd Chest": KH1LocationData("End of the World", 265_4533, "Chest", True), + "End of the World Final Dimension 4th Chest": KH1LocationData("End of the World", 265_4534, "Chest", True), + "End of the World Final Dimension 5th Chest": KH1LocationData("End of the World", 265_4571, "Chest", True), + "End of the World Final Dimension 6th Chest": KH1LocationData("End of the World", 265_4572, "Chest", True), + "End of the World Final Dimension 10th Chest": KH1LocationData("End of the World", 265_4573, "Chest", True), + "End of the World Final Dimension 9th Chest": KH1LocationData("End of the World", 265_4574, "Chest", True), + "End of the World Final Dimension 8th Chest": KH1LocationData("End of the World", 265_4611, "Chest", True), + "End of the World Final Dimension 7th Chest": KH1LocationData("End of the World", 265_4612, "Chest", True), + "End of the World Giant Crevasse 3rd Chest": KH1LocationData("End of the World", 265_4613, "Chest", True), + "End of the World Giant Crevasse 5th Chest": KH1LocationData("End of the World", 265_4614, "Chest", True), + "End of the World Giant Crevasse 1st Chest": KH1LocationData("End of the World", 265_4651, "Chest", True), + "End of the World Giant Crevasse 4th Chest": KH1LocationData("End of the World", 265_4652, "Chest", True), + "End of the World Giant Crevasse 2nd Chest": KH1LocationData("End of the World", 265_4653, "Chest", True), + "End of the World World Terminus Traverse Town Chest": KH1LocationData("End of the World", 265_4654, "Chest", True), + "End of the World World Terminus Wonderland Chest": KH1LocationData("End of the World", 265_4691, "Chest", True), + "End of the World World Terminus Olympus Coliseum Chest": KH1LocationData("End of the World", 265_4692, "Chest", True), + "End of the World World Terminus Deep Jungle Chest": KH1LocationData("End of the World", 265_4693, "Chest", True), + "End of the World World Terminus Agrabah Chest": KH1LocationData("End of the World", 265_4694, "Chest", True), + "End of the World World Terminus Atlantica Chest": KH1LocationData("End of the World", 265_4731, "Static", True), + "End of the World World Terminus Halloween Town Chest": KH1LocationData("End of the World", 265_4732, "Chest", True), + "End of the World World Terminus Neverland Chest": KH1LocationData("End of the World", 265_4733, "Chest", True), + "End of the World World Terminus 100 Acre Wood Chest": KH1LocationData("End of the World", 265_4734, "Chest", True), + "End of the World World Terminus Hollow Bastion Chest": KH1LocationData("End of the World", 265_4771, "Chest", True), + "End of the World Final Rest Chest": KH1LocationData("End of the World", 265_4772, "Chest", True), + "Monstro Chamber 6 White Trinity Chest": KH1LocationData("Monstro", 265_5092, "Chest", True), + #"Awakening Chest": KH1LocationData("Awakening", 265_5093, "Chest"), missable - "Traverse Town Defeat Guard Armor Dodge Roll Event": KH1LocationData("Traverse Town", 265_6011), - "Traverse Town Defeat Guard Armor Fire Event": KH1LocationData("Traverse Town", 265_6012), - "Traverse Town Defeat Guard Armor Blue Trinity Event": KH1LocationData("Traverse Town", 265_6013), - "Traverse Town Leon Secret Waterway Earthshine Event": KH1LocationData("Traverse Town", 265_6014), - "Traverse Town Kairi Secret Waterway Oathkeeper Event": KH1LocationData("Traverse Town", 265_6015), - "Traverse Town Defeat Guard Armor Brave Warrior Event": KH1LocationData("Traverse Town", 265_6016), - "Deep Jungle Defeat Sabor White Fang Event": KH1LocationData("Deep Jungle", 265_6021), - "Deep Jungle Defeat Clayton Cure Event": KH1LocationData("Deep Jungle", 265_6022), - "Deep Jungle Seal Keyhole Jungle King Event": KH1LocationData("Deep Jungle", 265_6023), - "Deep Jungle Seal Keyhole Red Trinity Event": KH1LocationData("Deep Jungle", 265_6024), - "Olympus Coliseum Clear Phil's Training Thunder Event": KH1LocationData("Olympus Coliseum", 265_6031), - "Olympus Coliseum Defeat Cerberus Inferno Band Event": KH1LocationData("Olympus Coliseum", 265_6033), - "Wonderland Defeat Trickmaster Blizzard Event": KH1LocationData("Wonderland", 265_6041), - "Wonderland Defeat Trickmaster Ifrit's Horn Event": KH1LocationData("Wonderland", 265_6042), - "Agrabah Defeat Pot Centipede Ray of Light Event": KH1LocationData("Agrabah", 265_6051), - "Agrabah Defeat Jafar Blizzard Event": KH1LocationData("Agrabah", 265_6052), - "Agrabah Defeat Jafar Genie Fire Event": KH1LocationData("Agrabah", 265_6053), - "Agrabah Seal Keyhole Genie Event": KH1LocationData("Agrabah", 265_6054), - "Agrabah Seal Keyhole Three Wishes Event": KH1LocationData("Agrabah", 265_6055), - "Agrabah Seal Keyhole Green Trinity Event": KH1LocationData("Agrabah", 265_6056), - "Monstro Defeat Parasite Cage I Goofy Cheer Event": KH1LocationData("Monstro", 265_6061), - "Monstro Defeat Parasite Cage II Stop Event": KH1LocationData("Monstro", 265_6062), - "Atlantica Defeat Ursula I Mermaid Kick Event": KH1LocationData("Atlantica", 265_6071), - "Atlantica Defeat Ursula II Thunder Event": KH1LocationData("Atlantica", 265_6072), - "Atlantica Seal Keyhole Crabclaw Event": KH1LocationData("Atlantica", 265_6073), - "Halloween Town Defeat Oogie Boogie Holy Circlet Event": KH1LocationData("Halloween Town", 265_6081), - "Halloween Town Defeat Oogie's Manor Gravity Event": KH1LocationData("Halloween Town", 265_6082), - "Halloween Town Seal Keyhole Pumpkinhead Event": KH1LocationData("Halloween Town", 265_6083), - "Neverland Defeat Anti Sora Raven's Claw Event": KH1LocationData("Neverland", 265_6091), - "Neverland Encounter Hook Cure Event": KH1LocationData("Neverland", 265_6092), - "Neverland Seal Keyhole Fairy Harp Event": KH1LocationData("Neverland", 265_6093), - "Neverland Seal Keyhole Tinker Bell Event": KH1LocationData("Neverland", 265_6094), - "Neverland Seal Keyhole Glide Event": KH1LocationData("Neverland", 265_6095), - "Neverland Defeat Phantom Stop Event": KH1LocationData("Neverland", 265_6096), - "Neverland Defeat Captain Hook Ars Arcanum Event": KH1LocationData("Neverland", 265_6097), - "Hollow Bastion Defeat Riku I White Trinity Event": KH1LocationData("Hollow Bastion", 265_6101), - "Hollow Bastion Defeat Maleficent Donald Cheer Event": KH1LocationData("Hollow Bastion", 265_6102), - "Hollow Bastion Defeat Dragon Maleficent Fireglow Event": KH1LocationData("Hollow Bastion", 265_6103), - "Hollow Bastion Defeat Riku II Ragnarok Event": KH1LocationData("Hollow Bastion", 265_6104), - "Hollow Bastion Defeat Behemoth Omega Arts Event": KH1LocationData("Hollow Bastion", 265_6105), - "Hollow Bastion Speak to Princesses Fire Event": KH1LocationData("Hollow Bastion", 265_6106), - "End of the World Defeat Chernabog Superglide Event": KH1LocationData("End of the World", 265_6111), + "Traverse Town Defeat Guard Armor Dodge Roll Event": KH1LocationData("Traverse Town", 265_6011, "Reward"), + "Traverse Town Defeat Guard Armor Fire Event": KH1LocationData("Traverse Town", 265_6012, "Static"), + "Traverse Town Defeat Guard Armor Blue Trinity Event": KH1LocationData("Traverse Town", 265_6013, "Static"), + "Traverse Town Leon Secret Waterway Earthshine Event": KH1LocationData("Traverse Town", 265_6014, "Reward"), + "Traverse Town Kairi Secret Waterway Oathkeeper Event": KH1LocationData("Traverse Town", 265_6015, "Reward", True), + "Traverse Town Defeat Guard Armor Brave Warrior Event": KH1LocationData("Traverse Town", 265_6016, "Reward"), + "Deep Jungle Defeat Sabor White Fang Event": KH1LocationData("Deep Jungle", 265_6021, "Reward", True), + "Deep Jungle Defeat Clayton Cure Event": KH1LocationData("Deep Jungle", 265_6022, "Static", True), + "Deep Jungle Seal Keyhole Jungle King Event": KH1LocationData("Deep Jungle", 265_6023, "Reward", True), + "Deep Jungle Seal Keyhole Red Trinity Event": KH1LocationData("Deep Jungle", 265_6024, "Static", True), + "Olympus Coliseum Clear Phil's Training Thunder Event": KH1LocationData("Olympus Coliseum", 265_6031, "Static"), + "Olympus Coliseum Defeat Cerberus Inferno Band Event": KH1LocationData("Olympus Coliseum", 265_6033, "Reward", True), + "Wonderland Defeat Trickmaster Blizzard Event": KH1LocationData("Wonderland", 265_6041, "Static", True), + "Wonderland Defeat Trickmaster Ifrit's Horn Event": KH1LocationData("Wonderland", 265_6042, "Reward", True), + "Agrabah Defeat Pot Centipede Ray of Light Event": KH1LocationData("Agrabah", 265_6051, "Reward", True), + "Agrabah Defeat Jafar Blizzard Event": KH1LocationData("Agrabah", 265_6052, "Static", True), + "Agrabah Defeat Jafar Genie Fire Event": KH1LocationData("Agrabah", 265_6053, "Static", True), + "Agrabah Seal Keyhole Genie Event": KH1LocationData("Agrabah", 265_6054, "Static", True), + "Agrabah Seal Keyhole Three Wishes Event": KH1LocationData("Agrabah", 265_6055, "Reward", True), + "Agrabah Seal Keyhole Green Trinity Event": KH1LocationData("Agrabah", 265_6056, "Static", True), + "Monstro Defeat Parasite Cage I Goofy Cheer Event": KH1LocationData("Monstro", 265_6061, "Reward", True), + "Monstro Defeat Parasite Cage II Stop Event": KH1LocationData("Monstro", 265_6062, "Static", True), + "Atlantica Defeat Ursula I Mermaid Kick Event": KH1LocationData("Atlantica", 265_6071, "Reward", True), + "Atlantica Defeat Ursula II Thunder Event": KH1LocationData("Atlantica", 265_6072, "Static", True), + "Atlantica Seal Keyhole Crabclaw Event": KH1LocationData("Atlantica", 265_6073, "Reward", True), + "Halloween Town Defeat Oogie Boogie Holy Circlet Event": KH1LocationData("Halloween Town", 265_6081, "Reward", True), + "Halloween Town Defeat Oogie's Manor Gravity Event": KH1LocationData("Halloween Town", 265_6082, "Static", True), + "Halloween Town Seal Keyhole Pumpkinhead Event": KH1LocationData("Halloween Town", 265_6083, "Reward", True), + "Neverland Defeat Anti Sora Raven's Claw Event": KH1LocationData("Neverland", 265_6091, "Reward", True), + "Neverland Encounter Hook Cure Event": KH1LocationData("Neverland", 265_6092, "Static", True), + "Neverland Seal Keyhole Fairy Harp Event": KH1LocationData("Neverland", 265_6093, "Reward", True), + "Neverland Seal Keyhole Tinker Bell Event": KH1LocationData("Neverland", 265_6094, "Static", True), + "Neverland Seal Keyhole Glide Event": KH1LocationData("Neverland", 265_6095, "Reward", True), + "Neverland Defeat Phantom Stop Event": KH1LocationData("Neverland", 265_6096, "Static", True), + "Neverland Defeat Captain Hook Ars Arcanum Event": KH1LocationData("Neverland", 265_6097, "Reward", True), + "Hollow Bastion Defeat Riku I White Trinity Event": KH1LocationData("Hollow Bastion", 265_6101, "Static", True), + "Hollow Bastion Defeat Maleficent Donald Cheer Event": KH1LocationData("Hollow Bastion", 265_6102, "Reward", True), + "Hollow Bastion Defeat Dragon Maleficent Fireglow Event": KH1LocationData("Hollow Bastion", 265_6103, "Reward", True), + "Hollow Bastion Defeat Riku II Ragnarok Event": KH1LocationData("Hollow Bastion", 265_6104, "Reward", True), + "Hollow Bastion Defeat Behemoth Omega Arts Event": KH1LocationData("Hollow Bastion", 265_6105, "Reward", True), + "Hollow Bastion Speak to Princesses Fire Event": KH1LocationData("Hollow Bastion", 265_6106, "Static", True), + "End of the World Defeat Chernabog Superglide Event": KH1LocationData("End of the World", 265_6111, "Reward", True), + "Neverland Seal Keyhole Navi-G Piece Event": KH1LocationData("Neverland", 265_6112, "Static", True), + "Traverse Town Secret Waterway Navi Gummi Event": KH1LocationData("Traverse Town", 265_6113, "Static", True), + + "Traverse Town Mail Postcard 01 Event": KH1LocationData("Traverse Town", 265_6120, "Reward"), + "Traverse Town Mail Postcard 02 Event": KH1LocationData("Traverse Town", 265_6121, "Reward"), + "Traverse Town Mail Postcard 03 Event": KH1LocationData("Traverse Town", 265_6122, "Reward"), + "Traverse Town Mail Postcard 04 Event": KH1LocationData("Traverse Town", 265_6123, "Reward"), + "Traverse Town Mail Postcard 05 Event": KH1LocationData("Traverse Town", 265_6124, "Reward"), + "Traverse Town Mail Postcard 06 Event": KH1LocationData("Traverse Town", 265_6125, "Reward"), + "Traverse Town Mail Postcard 07 Event": KH1LocationData("Traverse Town", 265_6126, "Reward"), + "Traverse Town Mail Postcard 08 Event": KH1LocationData("Traverse Town", 265_6127, "Reward"), + "Traverse Town Mail Postcard 09 Event": KH1LocationData("Traverse Town", 265_6128, "Reward"), + "Traverse Town Mail Postcard 10 Event": KH1LocationData("Traverse Town", 265_6129, "Reward"), - "Traverse Town Mail Postcard 01 Event": KH1LocationData("Traverse Town", 265_6120), - "Traverse Town Mail Postcard 02 Event": KH1LocationData("Traverse Town", 265_6121), - "Traverse Town Mail Postcard 03 Event": KH1LocationData("Traverse Town", 265_6122), - "Traverse Town Mail Postcard 04 Event": KH1LocationData("Traverse Town", 265_6123), - "Traverse Town Mail Postcard 05 Event": KH1LocationData("Traverse Town", 265_6124), - "Traverse Town Mail Postcard 06 Event": KH1LocationData("Traverse Town", 265_6125), - "Traverse Town Mail Postcard 07 Event": KH1LocationData("Traverse Town", 265_6126), - "Traverse Town Mail Postcard 08 Event": KH1LocationData("Traverse Town", 265_6127), - "Traverse Town Mail Postcard 09 Event": KH1LocationData("Traverse Town", 265_6128), - "Traverse Town Mail Postcard 10 Event": KH1LocationData("Traverse Town", 265_6129), + "Traverse Town Defeat Opposite Armor Aero Event": KH1LocationData("Traverse Town", 265_6131, "Static", True), + "Traverse Town Defeat Opposite Armor Navi-G Piece Event": KH1LocationData("Traverse Town", 265_6132, "Static", True), - "Traverse Town Defeat Opposite Armor Aero Event": KH1LocationData("Traverse Town", 265_6131), + "Atlantica Undersea Gorge Blizzard Clam": KH1LocationData("Atlantica", 265_6201, "Static"), + "Atlantica Undersea Gorge Ocean Floor Clam": KH1LocationData("Atlantica", 265_6202, "Static"), + "Atlantica Undersea Valley Higher Cave Clam": KH1LocationData("Atlantica", 265_6203, "Static"), + "Atlantica Undersea Valley Lower Cave Clam": KH1LocationData("Atlantica", 265_6204, "Static"), + "Atlantica Undersea Valley Fire Clam": KH1LocationData("Atlantica", 265_6205, "Static"), + "Atlantica Undersea Valley Wall Clam": KH1LocationData("Atlantica", 265_6206, "Static"), + "Atlantica Undersea Valley Pillar Clam": KH1LocationData("Atlantica", 265_6207, "Static"), + "Atlantica Undersea Valley Ocean Floor Clam": KH1LocationData("Atlantica", 265_6208, "Static"), + "Atlantica Triton's Palace Thunder Clam": KH1LocationData("Atlantica", 265_6209, "Static"), + "Atlantica Triton's Palace Wall Right Clam": KH1LocationData("Atlantica", 265_6210, "Static"), + "Atlantica Triton's Palace Near Path Clam": KH1LocationData("Atlantica", 265_6211, "Static"), + "Atlantica Triton's Palace Wall Left Clam": KH1LocationData("Atlantica", 265_6212, "Static"), + "Atlantica Cavern Nook Clam": KH1LocationData("Atlantica", 265_6213, "Static"), + "Atlantica Below Deck Clam": KH1LocationData("Atlantica", 265_6214, "Static"), + "Atlantica Undersea Garden Clam": KH1LocationData("Atlantica", 265_6215, "Static"), + "Atlantica Undersea Cave Clam": KH1LocationData("Atlantica", 265_6216, "Static"), - "Atlantica Undersea Gorge Blizzard Clam": KH1LocationData("Atlantica", 265_6201), - "Atlantica Undersea Gorge Ocean Floor Clam": KH1LocationData("Atlantica", 265_6202), - "Atlantica Undersea Valley Higher Cave Clam": KH1LocationData("Atlantica", 265_6203), - "Atlantica Undersea Valley Lower Cave Clam": KH1LocationData("Atlantica", 265_6204), - "Atlantica Undersea Valley Fire Clam": KH1LocationData("Atlantica", 265_6205), - "Atlantica Undersea Valley Wall Clam": KH1LocationData("Atlantica", 265_6206), - "Atlantica Undersea Valley Pillar Clam": KH1LocationData("Atlantica", 265_6207), - "Atlantica Undersea Valley Ocean Floor Clam": KH1LocationData("Atlantica", 265_6208), - "Atlantica Triton's Palace Thunder Clam": KH1LocationData("Atlantica", 265_6209), - "Atlantica Triton's Palace Wall Right Clam": KH1LocationData("Atlantica", 265_6210), - "Atlantica Triton's Palace Near Path Clam": KH1LocationData("Atlantica", 265_6211), - "Atlantica Triton's Palace Wall Left Clam": KH1LocationData("Atlantica", 265_6212), - "Atlantica Cavern Nook Clam": KH1LocationData("Atlantica", 265_6213), - "Atlantica Below Deck Clam": KH1LocationData("Atlantica", 265_6214), - "Atlantica Undersea Garden Clam": KH1LocationData("Atlantica", 265_6215), - "Atlantica Undersea Cave Clam": KH1LocationData("Atlantica", 265_6216), + #"Traverse Town Magician's Study Turn in Naturespark": KH1LocationData("Traverse Town", 265_6300, "Static"), + #"Traverse Town Magician's Study Turn in Watergleam": KH1LocationData("Traverse Town", 265_6301, "Static"), + #"Traverse Town Magician's Study Turn in Fireglow": KH1LocationData("Traverse Town", 265_6302, "Static"), + #"Traverse Town Magician's Study Turn in all Summon Gems": KH1LocationData("Traverse Town", 265_6303, "Reward"), + "Traverse Town Geppetto's House Geppetto Reward 1": KH1LocationData("Traverse Town", 265_6304, "Static", True), + "Traverse Town Geppetto's House Geppetto Reward 4": KH1LocationData("Traverse Town", 265_6305, "Static", True), + "Traverse Town Geppetto's House Geppetto Reward 3": KH1LocationData("Traverse Town", 265_6306, "Static", True), + "Traverse Town Geppetto's House Geppetto Reward 5": KH1LocationData("Traverse Town", 265_6307, "Static", True), + "Traverse Town Geppetto's House Geppetto Reward 2": KH1LocationData("Traverse Town", 265_6308, "Static", True), + "Traverse Town Geppetto's House Geppetto All Summons Reward": KH1LocationData("Traverse Town", 265_6309, "Static", True), + "Traverse Town Geppetto's House Talk to Pinocchio": KH1LocationData("Traverse Town", 265_6310, "Static", True), + "Traverse Town Magician's Study Obtained All Arts Items": KH1LocationData("Traverse Town", 265_6311, "Reward"), + "Traverse Town Magician's Study Obtained All LV1 Magic": KH1LocationData("Traverse Town", 265_6312, "Reward"), + "Traverse Town Magician's Study Obtained All LV3 Magic": KH1LocationData("Traverse Town", 265_6313, "Reward"), + "Traverse Town Piano Room Return 10 Puppies": KH1LocationData("Traverse Town", 265_6314, "Static"), + "Traverse Town Piano Room Return 20 Puppies": KH1LocationData("Traverse Town", 265_6315, "Static"), + "Traverse Town Piano Room Return 30 Puppies": KH1LocationData("Traverse Town", 265_6316, "Static"), + "Traverse Town Piano Room Return 40 Puppies": KH1LocationData("Traverse Town", 265_6317, "Reward"), + "Traverse Town Piano Room Return 50 Puppies Reward 1": KH1LocationData("Traverse Town", 265_6318, "Static"), + "Traverse Town Piano Room Return 50 Puppies Reward 2": KH1LocationData("Traverse Town", 265_6319, "Reward"), + "Traverse Town Piano Room Return 60 Puppies": KH1LocationData("Traverse Town", 265_6320, "Reward"), + "Traverse Town Piano Room Return 70 Puppies": KH1LocationData("Traverse Town", 265_6321, "Reward"), + "Traverse Town Piano Room Return 80 Puppies": KH1LocationData("Traverse Town", 265_6322, "Static"), + "Traverse Town Piano Room Return 90 Puppies": KH1LocationData("Traverse Town", 265_6324, "Reward"), + "Traverse Town Piano Room Return 99 Puppies Reward 1": KH1LocationData("Traverse Town", 265_6326, "Static"), + "Traverse Town Piano Room Return 99 Puppies Reward 2": KH1LocationData("Traverse Town", 265_6327, "Static"), + "Olympus Coliseum Cloud Sonic Blade Event": KH1LocationData("Olympus Coliseum", 265_6032, "Reward", True), #Had to change the way we send this check, not changing location_id + "Olympus Coliseum Defeat Sephiroth One-Winged Angel Event": KH1LocationData("Olympus Coliseum", 265_6328, "Reward", True), + "Olympus Coliseum Defeat Ice Titan Diamond Dust Event": KH1LocationData("Olympus Coliseum", 265_6329, "Reward", True), + "Olympus Coliseum Gates Purple Jar After Defeating Hades": KH1LocationData("Olympus Coliseum", 265_6330, "Static", True), + "Halloween Town Guillotine Square Ring Jack's Doorbell 3 Times": KH1LocationData("Halloween Town", 265_6331, "Static"), + "Neverland Clock Tower 01:00 Door": KH1LocationData("Neverland", 265_6332, "Static", True), + "Neverland Clock Tower 02:00 Door": KH1LocationData("Neverland", 265_6333, "Static", True), + "Neverland Clock Tower 03:00 Door": KH1LocationData("Neverland", 265_6334, "Static", True), + "Neverland Clock Tower 04:00 Door": KH1LocationData("Neverland", 265_6335, "Static", True), + "Neverland Clock Tower 05:00 Door": KH1LocationData("Neverland", 265_6336, "Static", True), + "Neverland Clock Tower 06:00 Door": KH1LocationData("Neverland", 265_6337, "Static", True), + "Neverland Clock Tower 07:00 Door": KH1LocationData("Neverland", 265_6338, "Static", True), + "Neverland Clock Tower 08:00 Door": KH1LocationData("Neverland", 265_6339, "Static", True), + "Neverland Clock Tower 09:00 Door": KH1LocationData("Neverland", 265_6340, "Static", True), + "Neverland Clock Tower 10:00 Door": KH1LocationData("Neverland", 265_6341, "Static", True), + "Neverland Clock Tower 11:00 Door": KH1LocationData("Neverland", 265_6342, "Static", True), + "Neverland Clock Tower 12:00 Door": KH1LocationData("Neverland", 265_6343, "Static", True), + "Neverland Hold Aero Chest": KH1LocationData("Neverland", 265_6344, "Static"), + "100 Acre Wood Bouncing Spot Turn in Rare Nut 1": KH1LocationData("100 Acre Wood", 265_6345, "Static"), + "100 Acre Wood Bouncing Spot Turn in Rare Nut 2": KH1LocationData("100 Acre Wood", 265_6346, "Static"), + "100 Acre Wood Bouncing Spot Turn in Rare Nut 3": KH1LocationData("100 Acre Wood", 265_6347, "Static"), + "100 Acre Wood Bouncing Spot Turn in Rare Nut 4": KH1LocationData("100 Acre Wood", 265_6348, "Static"), + "100 Acre Wood Bouncing Spot Turn in Rare Nut 5": KH1LocationData("100 Acre Wood", 265_6349, "Static"), + "100 Acre Wood Pooh's House Owl Cheer": KH1LocationData("100 Acre Wood", 265_6350, "Reward"), + "100 Acre Wood Convert Torn Page 1": KH1LocationData("100 Acre Wood", 265_6351, "Reward"), + "100 Acre Wood Convert Torn Page 2": KH1LocationData("100 Acre Wood", 265_6352, "Reward"), + "100 Acre Wood Convert Torn Page 3": KH1LocationData("100 Acre Wood", 265_6353, "Static"), + "100 Acre Wood Convert Torn Page 4": KH1LocationData("100 Acre Wood", 265_6354, "Reward"), + "100 Acre Wood Convert Torn Page 5": KH1LocationData("100 Acre Wood", 265_6355, "Reward"), + "100 Acre Wood Pooh's House Start Fire": KH1LocationData("100 Acre Wood", 265_6356, "Static"), + "100 Acre Wood Pooh's Room Cabinet": KH1LocationData("100 Acre Wood", 265_6357, "Static"), + "100 Acre Wood Pooh's Room Chimney": KH1LocationData("100 Acre Wood", 265_6358, "Static"), + "100 Acre Wood Bouncing Spot Break Log": KH1LocationData("100 Acre Wood", 265_6359, "Static"), + "100 Acre Wood Bouncing Spot Fall Through Top of Tree Next to Pooh": KH1LocationData("100 Acre Wood", 265_6360, "Static"), + "Deep Jungle Camp Hi-Potion Experiment": KH1LocationData("Deep Jungle", 265_6361, "Static"), + "Deep Jungle Camp Ether Experiment": KH1LocationData("Deep Jungle", 265_6362, "Static"), + "Deep Jungle Camp Replication Experiment": KH1LocationData("Deep Jungle", 265_6363, "Static"), + "Deep Jungle Cliff Save Gorillas": KH1LocationData("Deep Jungle", 265_6364, "Static"), + "Deep Jungle Tree House Save Gorillas": KH1LocationData("Deep Jungle", 265_6365, "Static"), + "Deep Jungle Camp Save Gorillas": KH1LocationData("Deep Jungle", 265_6366, "Static"), + "Deep Jungle Bamboo Thicket Save Gorillas": KH1LocationData("Deep Jungle", 265_6367, "Static"), + "Deep Jungle Climbing Trees Save Gorillas": KH1LocationData("Deep Jungle", 265_6368, "Static"), + "Olympus Coliseum Olympia Chest": KH1LocationData("Olympus Coliseum", 265_6369, "Reward", True), + "Deep Jungle Jungle Slider 10 Fruits": KH1LocationData("Deep Jungle", 265_6370, "Reward", True), + "Deep Jungle Jungle Slider 20 Fruits": KH1LocationData("Deep Jungle", 265_6371, "Reward", True), + "Deep Jungle Jungle Slider 30 Fruits": KH1LocationData("Deep Jungle", 265_6372, "Reward", True), + "Deep Jungle Jungle Slider 40 Fruits": KH1LocationData("Deep Jungle", 265_6373, "Reward", True), + "Deep Jungle Jungle Slider 50 Fruits": KH1LocationData("Deep Jungle", 265_6374, "Reward", True), + #"Traverse Town 1st District Speak with Cid Event": KH1LocationData("Traverse Town", 265_6375, "Static"), + "Wonderland Bizarre Room Read Book": KH1LocationData("Wonderland", 265_6376, "Static"), + "Olympus Coliseum Coliseum Gates Green Trinity": KH1LocationData("Olympus Coliseum", 265_6377, "Static"), + "Agrabah Defeat Kurt Zisa Zantetsuken Event": KH1LocationData("Agrabah", 265_6378, "Reward", True), + "Hollow Bastion Defeat Unknown EXP Necklace Event": KH1LocationData("Hollow Bastion", 265_6379, "Reward", True), + "Olympus Coliseum Coliseum Gates Hero's License Event": KH1LocationData("Olympus Coliseum", 265_6380, "Static", True), + "Atlantica Sunken Ship Crystal Trident Event": KH1LocationData("Atlantica", 265_6381, "Static"), + "Halloween Town Graveyard Forget-Me-Not Event": KH1LocationData("Halloween Town", 265_6382, "Static"), + "Deep Jungle Tent Protect-G Event": KH1LocationData("Deep Jungle", 265_6383, "Static"), + "Deep Jungle Cavern of Hearts Navi-G Piece Event": KH1LocationData("Deep Jungle", 265_6384, "Static", True), + "Wonderland Bizarre Room Navi-G Piece Event": KH1LocationData("Wonderland", 265_6385, "Static", True), + "Olympus Coliseum Coliseum Gates Entry Pass Event": KH1LocationData("Olympus Coliseum", 265_6386, "Static"), - #"Traverse Town Magician's Study Turn in Naturespark": KH1LocationData("Traverse Town", 265_6300), - #"Traverse Town Magician's Study Turn in Watergleam": KH1LocationData("Traverse Town", 265_6301), - #"Traverse Town Magician's Study Turn in Fireglow": KH1LocationData("Traverse Town", 265_6302), - #"Traverse Town Magician's Study Turn in all Summon Gems": KH1LocationData("Traverse Town", 265_6303), - "Traverse Town Geppetto's House Geppetto Reward 1": KH1LocationData("Traverse Town", 265_6304), - "Traverse Town Geppetto's House Geppetto Reward 2": KH1LocationData("Traverse Town", 265_6305), - "Traverse Town Geppetto's House Geppetto Reward 3": KH1LocationData("Traverse Town", 265_6306), - "Traverse Town Geppetto's House Geppetto Reward 4": KH1LocationData("Traverse Town", 265_6307), - "Traverse Town Geppetto's House Geppetto Reward 5": KH1LocationData("Traverse Town", 265_6308), - "Traverse Town Geppetto's House Geppetto All Summons Reward": KH1LocationData("Traverse Town", 265_6309), - "Traverse Town Geppetto's House Talk to Pinocchio": KH1LocationData("Traverse Town", 265_6310), - "Traverse Town Magician's Study Obtained All Arts Items": KH1LocationData("Traverse Town", 265_6311), - "Traverse Town Magician's Study Obtained All LV1 Magic": KH1LocationData("Traverse Town", 265_6312), - "Traverse Town Magician's Study Obtained All LV3 Magic": KH1LocationData("Traverse Town", 265_6313), - "Traverse Town Piano Room Return 10 Puppies": KH1LocationData("Traverse Town", 265_6314), - "Traverse Town Piano Room Return 20 Puppies": KH1LocationData("Traverse Town", 265_6315), - "Traverse Town Piano Room Return 30 Puppies": KH1LocationData("Traverse Town", 265_6316), - "Traverse Town Piano Room Return 40 Puppies": KH1LocationData("Traverse Town", 265_6317), - "Traverse Town Piano Room Return 50 Puppies Reward 1": KH1LocationData("Traverse Town", 265_6318), - "Traverse Town Piano Room Return 50 Puppies Reward 2": KH1LocationData("Traverse Town", 265_6319), - "Traverse Town Piano Room Return 60 Puppies": KH1LocationData("Traverse Town", 265_6320), - "Traverse Town Piano Room Return 70 Puppies": KH1LocationData("Traverse Town", 265_6321), - "Traverse Town Piano Room Return 80 Puppies": KH1LocationData("Traverse Town", 265_6322), - "Traverse Town Piano Room Return 90 Puppies": KH1LocationData("Traverse Town", 265_6324), - "Traverse Town Piano Room Return 99 Puppies Reward 1": KH1LocationData("Traverse Town", 265_6326), - "Traverse Town Piano Room Return 99 Puppies Reward 2": KH1LocationData("Traverse Town", 265_6327), - "Olympus Coliseum Cloud Sonic Blade Event": KH1LocationData("Olympus Coliseum", 265_6032), #Had to change the way we send this check, not changing location_id - "Olympus Coliseum Defeat Sephiroth One-Winged Angel Event": KH1LocationData("Olympus Coliseum", 265_6328), - "Olympus Coliseum Defeat Ice Titan Diamond Dust Event": KH1LocationData("Olympus Coliseum", 265_6329), - "Olympus Coliseum Gates Purple Jar After Defeating Hades": KH1LocationData("Olympus Coliseum", 265_6330), - "Halloween Town Guillotine Square Ring Jack's Doorbell 3 Times": KH1LocationData("Halloween Town", 265_6331), - #"Neverland Clock Tower 01:00 Door": KH1LocationData("Neverland", 265_6332), - #"Neverland Clock Tower 02:00 Door": KH1LocationData("Neverland", 265_6333), - #"Neverland Clock Tower 03:00 Door": KH1LocationData("Neverland", 265_6334), - #"Neverland Clock Tower 04:00 Door": KH1LocationData("Neverland", 265_6335), - #"Neverland Clock Tower 05:00 Door": KH1LocationData("Neverland", 265_6336), - #"Neverland Clock Tower 06:00 Door": KH1LocationData("Neverland", 265_6337), - #"Neverland Clock Tower 07:00 Door": KH1LocationData("Neverland", 265_6338), - #"Neverland Clock Tower 08:00 Door": KH1LocationData("Neverland", 265_6339), - #"Neverland Clock Tower 09:00 Door": KH1LocationData("Neverland", 265_6340), - #"Neverland Clock Tower 10:00 Door": KH1LocationData("Neverland", 265_6341), - #"Neverland Clock Tower 11:00 Door": KH1LocationData("Neverland", 265_6342), - #"Neverland Clock Tower 12:00 Door": KH1LocationData("Neverland", 265_6343), - "Neverland Hold Aero Chest": KH1LocationData("Neverland", 265_6344), - "100 Acre Wood Bouncing Spot Turn in Rare Nut 1": KH1LocationData("100 Acre Wood", 265_6345), - "100 Acre Wood Bouncing Spot Turn in Rare Nut 2": KH1LocationData("100 Acre Wood", 265_6346), - "100 Acre Wood Bouncing Spot Turn in Rare Nut 3": KH1LocationData("100 Acre Wood", 265_6347), - "100 Acre Wood Bouncing Spot Turn in Rare Nut 4": KH1LocationData("100 Acre Wood", 265_6348), - "100 Acre Wood Bouncing Spot Turn in Rare Nut 5": KH1LocationData("100 Acre Wood", 265_6349), - "100 Acre Wood Pooh's House Owl Cheer": KH1LocationData("100 Acre Wood", 265_6350), - "100 Acre Wood Convert Torn Page 1": KH1LocationData("100 Acre Wood", 265_6351), - "100 Acre Wood Convert Torn Page 2": KH1LocationData("100 Acre Wood", 265_6352), - "100 Acre Wood Convert Torn Page 3": KH1LocationData("100 Acre Wood", 265_6353), - "100 Acre Wood Convert Torn Page 4": KH1LocationData("100 Acre Wood", 265_6354), - "100 Acre Wood Convert Torn Page 5": KH1LocationData("100 Acre Wood", 265_6355), - "100 Acre Wood Pooh's House Start Fire": KH1LocationData("100 Acre Wood", 265_6356), - "100 Acre Wood Pooh's Room Cabinet": KH1LocationData("100 Acre Wood", 265_6357), - "100 Acre Wood Pooh's Room Chimney": KH1LocationData("100 Acre Wood", 265_6358), - "100 Acre Wood Bouncing Spot Break Log": KH1LocationData("100 Acre Wood", 265_6359), - "100 Acre Wood Bouncing Spot Fall Through Top of Tree Next to Pooh": KH1LocationData("100 Acre Wood", 265_6360), - "Deep Jungle Camp Hi-Potion Experiment": KH1LocationData("Deep Jungle", 265_6361), - "Deep Jungle Camp Ether Experiment": KH1LocationData("Deep Jungle", 265_6362), - "Deep Jungle Camp Replication Experiment": KH1LocationData("Deep Jungle", 265_6363), - "Deep Jungle Cliff Save Gorillas": KH1LocationData("Deep Jungle", 265_6364), - "Deep Jungle Tree House Save Gorillas": KH1LocationData("Deep Jungle", 265_6365), - "Deep Jungle Camp Save Gorillas": KH1LocationData("Deep Jungle", 265_6366), - "Deep Jungle Bamboo Thicket Save Gorillas": KH1LocationData("Deep Jungle", 265_6367), - "Deep Jungle Climbing Trees Save Gorillas": KH1LocationData("Deep Jungle", 265_6368), - "Olympus Coliseum Olympia Chest": KH1LocationData("Olympus Coliseum", 265_6369), - "Deep Jungle Jungle Slider 10 Fruits": KH1LocationData("Deep Jungle", 265_6370), - "Deep Jungle Jungle Slider 20 Fruits": KH1LocationData("Deep Jungle", 265_6371), - "Deep Jungle Jungle Slider 30 Fruits": KH1LocationData("Deep Jungle", 265_6372), - "Deep Jungle Jungle Slider 40 Fruits": KH1LocationData("Deep Jungle", 265_6373), - "Deep Jungle Jungle Slider 50 Fruits": KH1LocationData("Deep Jungle", 265_6374), - "Traverse Town 1st District Speak with Cid Event": KH1LocationData("Traverse Town", 265_6375), - "Wonderland Bizarre Room Read Book": KH1LocationData("Wonderland", 265_6376), - "Olympus Coliseum Coliseum Gates Green Trinity": KH1LocationData("Olympus Coliseum", 265_6377), - "Agrabah Defeat Kurt Zisa Zantetsuken Event": KH1LocationData("Agrabah", 265_6378), - "Hollow Bastion Defeat Unknown EXP Necklace Event": KH1LocationData("Hollow Bastion", 265_6379), - "Olympus Coliseum Coliseum Gates Hero's License Event": KH1LocationData("Olympus Coliseum", 265_6380), - "Atlantica Sunken Ship Crystal Trident Event": KH1LocationData("Atlantica", 265_6381), - "Halloween Town Graveyard Forget-Me-Not Event": KH1LocationData("Halloween Town", 265_6382), - "Deep Jungle Tent Protect-G Event": KH1LocationData("Deep Jungle", 265_6383), - "Deep Jungle Cavern of Hearts Navi-G Piece Event": KH1LocationData("Deep Jungle", 265_6384), - "Wonderland Bizarre Room Navi-G Piece Event": KH1LocationData("Wonderland", 265_6385), - "Olympus Coliseum Coliseum Gates Entry Pass Event": KH1LocationData("Olympus Coliseum", 265_6386), + "Traverse Town Synth 15 Items": KH1LocationData("Traverse Town", 265_6400, "Reward"), + "Traverse Town Synth Item 01": KH1LocationData("Traverse Town", 265_6401, "Synth"), + "Traverse Town Synth Item 02": KH1LocationData("Traverse Town", 265_6402, "Synth"), + "Traverse Town Synth Item 03": KH1LocationData("Traverse Town", 265_6403, "Synth"), + "Traverse Town Synth Item 04": KH1LocationData("Traverse Town", 265_6404, "Synth"), + "Traverse Town Synth Item 05": KH1LocationData("Traverse Town", 265_6405, "Synth"), + "Traverse Town Synth Item 06": KH1LocationData("Traverse Town", 265_6406, "Synth"), + "Traverse Town Synth Item 06": KH1LocationData("Traverse Town", 265_6406, "Synth"), + "Traverse Town Synth Item 07": KH1LocationData("Traverse Town", 265_6407, "Synth"), + "Traverse Town Synth Item 08": KH1LocationData("Traverse Town", 265_6408, "Synth"), + "Traverse Town Synth Item 09": KH1LocationData("Traverse Town", 265_6409, "Synth"), + "Traverse Town Synth Item 10": KH1LocationData("Traverse Town", 265_6410, "Synth"), + "Traverse Town Synth Item 11": KH1LocationData("Traverse Town", 265_6411, "Synth"), + "Traverse Town Synth Item 12": KH1LocationData("Traverse Town", 265_6412, "Synth"), + "Traverse Town Synth Item 13": KH1LocationData("Traverse Town", 265_6413, "Synth"), + "Traverse Town Synth Item 14": KH1LocationData("Traverse Town", 265_6414, "Synth"), + "Traverse Town Synth Item 15": KH1LocationData("Traverse Town", 265_6415, "Synth"), + "Traverse Town Synth Item 16": KH1LocationData("Traverse Town", 265_6416, "Synth"), + "Traverse Town Synth Item 17": KH1LocationData("Traverse Town", 265_6417, "Synth"), + "Traverse Town Synth Item 18": KH1LocationData("Traverse Town", 265_6418, "Synth"), + "Traverse Town Synth Item 19": KH1LocationData("Traverse Town", 265_6419, "Synth"), + "Traverse Town Synth Item 20": KH1LocationData("Traverse Town", 265_6420, "Synth"), + "Traverse Town Synth Item 21": KH1LocationData("Traverse Town", 265_6421, "Synth"), + "Traverse Town Synth Item 22": KH1LocationData("Traverse Town", 265_6422, "Synth"), + "Traverse Town Synth Item 23": KH1LocationData("Traverse Town", 265_6423, "Synth"), + "Traverse Town Synth Item 24": KH1LocationData("Traverse Town", 265_6424, "Synth"), + "Traverse Town Synth Item 25": KH1LocationData("Traverse Town", 265_6425, "Synth"), + "Traverse Town Synth Item 26": KH1LocationData("Traverse Town", 265_6426, "Synth"), + "Traverse Town Synth Item 27": KH1LocationData("Traverse Town", 265_6427, "Synth"), + "Traverse Town Synth Item 28": KH1LocationData("Traverse Town", 265_6428, "Synth"), + "Traverse Town Synth Item 29": KH1LocationData("Traverse Town", 265_6429, "Synth"), + "Traverse Town Synth Item 30": KH1LocationData("Traverse Town", 265_6430, "Synth"), + "Traverse Town Synth Item 31": KH1LocationData("Traverse Town", 265_6431, "Synth"), + "Traverse Town Synth Item 32": KH1LocationData("Traverse Town", 265_6432, "Synth"), + "Traverse Town Synth Item 33": KH1LocationData("Traverse Town", 265_6433, "Synth"), - "Traverse Town Synth Log": KH1LocationData("Traverse Town", 265_6401), - "Traverse Town Synth Cloth": KH1LocationData("Traverse Town", 265_6402), - "Traverse Town Synth Rope": KH1LocationData("Traverse Town", 265_6403), - "Traverse Town Synth Seagull Egg": KH1LocationData("Traverse Town", 265_6404), - "Traverse Town Synth Fish": KH1LocationData("Traverse Town", 265_6405), - "Traverse Town Synth Mushroom": KH1LocationData("Traverse Town", 265_6406), + "Traverse Town Item Shop Postcard": KH1LocationData("Traverse Town", 265_6500, "Static"), + "Traverse Town 1st District Safe Postcard": KH1LocationData("Traverse Town", 265_6501, "Static"), + "Traverse Town Gizmo Shop Postcard 1": KH1LocationData("Traverse Town", 265_6502, "Static"), + "Traverse Town Gizmo Shop Postcard 2": KH1LocationData("Traverse Town", 265_6503, "Static"), + "Traverse Town Item Workshop Postcard": KH1LocationData("Traverse Town", 265_6504, "Static"), + "Traverse Town 3rd District Balcony Postcard": KH1LocationData("Traverse Town", 265_6505, "Static"), + "Traverse Town Geppetto's House Postcard": KH1LocationData("Traverse Town", 265_6506, "Static", True), + "Halloween Town Lab Torn Page": KH1LocationData("Halloween Town", 265_6508, "Static"), + "Hollow Bastion Entrance Hall Emblem Piece (Flame)": KH1LocationData("Hollow Bastion", 265_6516, "Static", True), + "Hollow Bastion Entrance Hall Emblem Piece (Chest)": KH1LocationData("Hollow Bastion", 265_6517, "Static", True), + "Hollow Bastion Entrance Hall Emblem Piece (Statue)": KH1LocationData("Hollow Bastion", 265_6518, "Static", True), + "Hollow Bastion Entrance Hall Emblem Piece (Fountain)": KH1LocationData("Hollow Bastion", 265_6519, "Static", True), + "Traverse Town 1st District Leon Gift": KH1LocationData("Traverse Town", 265_6520, "Reward"), + #"Traverse Town 1st District Aerith Gift": KH1LocationData("Traverse Town", 265_6521, "Reward"), + "Hollow Bastion Library Speak to Belle Divine Rose": KH1LocationData("Hollow Bastion", 265_6522, "Reward", True), + "Hollow Bastion Library Speak to Aerith Cure": KH1LocationData("Hollow Bastion", 265_6523, "Static", True), - "Traverse Town Item Shop Postcard": KH1LocationData("Traverse Town", 265_6500), - "Traverse Town 1st District Safe Postcard": KH1LocationData("Traverse Town", 265_6501), - "Traverse Town Gizmo Shop Postcard 1": KH1LocationData("Traverse Town", 265_6502), - "Traverse Town Gizmo Shop Postcard 2": KH1LocationData("Traverse Town", 265_6503), - "Traverse Town Item Workshop Postcard": KH1LocationData("Traverse Town", 265_6504), - "Traverse Town 3rd District Balcony Postcard": KH1LocationData("Traverse Town", 265_6505), - "Traverse Town Geppetto's House Postcard": KH1LocationData("Traverse Town", 265_6506), - "Halloween Town Lab Torn Page": KH1LocationData("Halloween Town", 265_6508), - "Hollow Bastion Entrance Hall Emblem Piece (Flame)": KH1LocationData("Hollow Bastion", 265_6516), - "Hollow Bastion Entrance Hall Emblem Piece (Chest)": KH1LocationData("Hollow Bastion", 265_6517), - "Hollow Bastion Entrance Hall Emblem Piece (Statue)": KH1LocationData("Hollow Bastion", 265_6518), - "Hollow Bastion Entrance Hall Emblem Piece (Fountain)": KH1LocationData("Hollow Bastion", 265_6519), - #"Traverse Town 1st District Leon Gift": KH1LocationData("Traverse Town", 265_6520), - #"Traverse Town 1st District Aerith Gift": KH1LocationData("Traverse Town", 265_6521), - "Hollow Bastion Library Speak to Belle Divine Rose": KH1LocationData("Hollow Bastion", 265_6522), - "Hollow Bastion Library Speak to Aerith Cure": KH1LocationData("Hollow Bastion", 265_6523), + "Traverse Town 1st District Blue Trinity by Exit Door": KH1LocationData("Traverse Town", 265_6600, "Prize"), + "Traverse Town 3rd District Blue Trinity": KH1LocationData("Traverse Town", 265_6601, "Prize"), + "Traverse Town Magician's Study Blue Trinity": KH1LocationData("Traverse Town", 265_6602, "Prize"), + "Wonderland Lotus Forest Blue Trinity in Alcove": KH1LocationData("Wonderland", 265_6603, "Prize"), + "Wonderland Lotus Forest Blue Trinity by Moving Boulder": KH1LocationData("Wonderland", 265_6604, "Prize"), + "Agrabah Bazaar Blue Trinity": KH1LocationData("Agrabah", 265_6605, "Prize"), + "Monstro Mouth Blue Trinity": KH1LocationData("Monstro", 265_6606, "Prize", True), + "Monstro Chamber 5 Blue Trinity": KH1LocationData("Monstro", 265_6607, "Prize"), + "Hollow Bastion Great Crest Blue Trinity": KH1LocationData("Hollow Bastion", 265_6608, "Prize", True), + "Hollow Bastion Dungeon Blue Trinity": KH1LocationData("Hollow Bastion", 265_6609, "Prize", True), + "Deep Jungle Treetop Green Trinity": KH1LocationData("Deep Jungle", 265_6610, "Prize"), + "Agrabah Cave of Wonders Treasure Room Red Trinity": KH1LocationData("Agrabah", 265_6611, "Prize", True), + "Monstro Throat Blue Trinity": KH1LocationData("Monstro", 265_6612, "Prize", True), + "Wonderland Bizarre Room Examine Flower Pot": KH1LocationData("Wonderland", 265_6613, "Prize"), + "Wonderland Lotus Forest Red Flowers on the Main Path": KH1LocationData("Wonderland", 265_6614, "Prize"), + "Wonderland Lotus Forest Yellow Flowers in Middle Clearing and Through Painting": KH1LocationData("Wonderland", 265_6615, "Prize"), + "Wonderland Lotus Forest Yellow Elixir Flower Through Painting": KH1LocationData("Wonderland", 265_6616, "Prize"), + "Wonderland Lotus Forest Red Flower Raise Lily Pads": KH1LocationData("Wonderland", 265_6617, "Prize"), + "Wonderland Tea Party Garden Left Cushioned Chair": KH1LocationData("Wonderland", 265_6618, "Prize"), + "Wonderland Tea Party Garden Left Pink Chair": KH1LocationData("Wonderland", 265_6619, "Prize"), + "Wonderland Tea Party Garden Right Yellow Chair": KH1LocationData("Wonderland", 265_6620, "Prize"), + "Wonderland Tea Party Garden Left Gray Chair": KH1LocationData("Wonderland", 265_6621, "Prize"), + "Wonderland Tea Party Garden Right Brown Chair": KH1LocationData("Wonderland", 265_6622, "Prize"), + "Hollow Bastion Lift Stop from Waterway Examine Node": KH1LocationData("Hollow Bastion", 265_6623, "Prize", True), - "Agrabah Defeat Jafar Genie Ansem's Report 1": KH1LocationData("Agrabah", 265_7018), - "Hollow Bastion Speak with Aerith Ansem's Report 2": KH1LocationData("Hollow Bastion", 265_7017), - "Atlantica Defeat Ursula II Ansem's Report 3": KH1LocationData("Atlantica", 265_7016), - "Hollow Bastion Speak with Aerith Ansem's Report 4": KH1LocationData("Hollow Bastion", 265_7015), - "Hollow Bastion Defeat Maleficent Ansem's Report 5": KH1LocationData("Hollow Bastion", 265_7014), - "Hollow Bastion Speak with Aerith Ansem's Report 6": KH1LocationData("Hollow Bastion", 265_7013), - "Halloween Town Defeat Oogie Boogie Ansem's Report 7": KH1LocationData("Halloween Town", 265_7012), - "Olympus Coliseum Defeat Hades Ansem's Report 8": KH1LocationData("Olympus Coliseum", 265_7011), - "Neverland Defeat Hook Ansem's Report 9": KH1LocationData("Neverland", 265_7028), - "Hollow Bastion Speak with Aerith Ansem's Report 10": KH1LocationData("Hollow Bastion", 265_7027), - "Agrabah Defeat Kurt Zisa Ansem's Report 11": KH1LocationData("Agrabah", 265_7026), - "Olympus Coliseum Defeat Sephiroth Ansem's Report 12": KH1LocationData("Olympus Coliseum", 265_7025), - "Hollow Bastion Defeat Unknown Ansem's Report 13": KH1LocationData("Hollow Bastion", 265_7024), - "Level 001": KH1LocationData("Levels", 265_8001), - "Level 002": KH1LocationData("Levels", 265_8002), - "Level 003": KH1LocationData("Levels", 265_8003), - "Level 004": KH1LocationData("Levels", 265_8004), - "Level 005": KH1LocationData("Levels", 265_8005), - "Level 006": KH1LocationData("Levels", 265_8006), - "Level 007": KH1LocationData("Levels", 265_8007), - "Level 008": KH1LocationData("Levels", 265_8008), - "Level 009": KH1LocationData("Levels", 265_8009), - "Level 010": KH1LocationData("Levels", 265_8010), - "Level 011": KH1LocationData("Levels", 265_8011), - "Level 012": KH1LocationData("Levels", 265_8012), - "Level 013": KH1LocationData("Levels", 265_8013), - "Level 014": KH1LocationData("Levels", 265_8014), - "Level 015": KH1LocationData("Levels", 265_8015), - "Level 016": KH1LocationData("Levels", 265_8016), - "Level 017": KH1LocationData("Levels", 265_8017), - "Level 018": KH1LocationData("Levels", 265_8018), - "Level 019": KH1LocationData("Levels", 265_8019), - "Level 020": KH1LocationData("Levels", 265_8020), - "Level 021": KH1LocationData("Levels", 265_8021), - "Level 022": KH1LocationData("Levels", 265_8022), - "Level 023": KH1LocationData("Levels", 265_8023), - "Level 024": KH1LocationData("Levels", 265_8024), - "Level 025": KH1LocationData("Levels", 265_8025), - "Level 026": KH1LocationData("Levels", 265_8026), - "Level 027": KH1LocationData("Levels", 265_8027), - "Level 028": KH1LocationData("Levels", 265_8028), - "Level 029": KH1LocationData("Levels", 265_8029), - "Level 030": KH1LocationData("Levels", 265_8030), - "Level 031": KH1LocationData("Levels", 265_8031), - "Level 032": KH1LocationData("Levels", 265_8032), - "Level 033": KH1LocationData("Levels", 265_8033), - "Level 034": KH1LocationData("Levels", 265_8034), - "Level 035": KH1LocationData("Levels", 265_8035), - "Level 036": KH1LocationData("Levels", 265_8036), - "Level 037": KH1LocationData("Levels", 265_8037), - "Level 038": KH1LocationData("Levels", 265_8038), - "Level 039": KH1LocationData("Levels", 265_8039), - "Level 040": KH1LocationData("Levels", 265_8040), - "Level 041": KH1LocationData("Levels", 265_8041), - "Level 042": KH1LocationData("Levels", 265_8042), - "Level 043": KH1LocationData("Levels", 265_8043), - "Level 044": KH1LocationData("Levels", 265_8044), - "Level 045": KH1LocationData("Levels", 265_8045), - "Level 046": KH1LocationData("Levels", 265_8046), - "Level 047": KH1LocationData("Levels", 265_8047), - "Level 048": KH1LocationData("Levels", 265_8048), - "Level 049": KH1LocationData("Levels", 265_8049), - "Level 050": KH1LocationData("Levels", 265_8050), - "Level 051": KH1LocationData("Levels", 265_8051), - "Level 052": KH1LocationData("Levels", 265_8052), - "Level 053": KH1LocationData("Levels", 265_8053), - "Level 054": KH1LocationData("Levels", 265_8054), - "Level 055": KH1LocationData("Levels", 265_8055), - "Level 056": KH1LocationData("Levels", 265_8056), - "Level 057": KH1LocationData("Levels", 265_8057), - "Level 058": KH1LocationData("Levels", 265_8058), - "Level 059": KH1LocationData("Levels", 265_8059), - "Level 060": KH1LocationData("Levels", 265_8060), - "Level 061": KH1LocationData("Levels", 265_8061), - "Level 062": KH1LocationData("Levels", 265_8062), - "Level 063": KH1LocationData("Levels", 265_8063), - "Level 064": KH1LocationData("Levels", 265_8064), - "Level 065": KH1LocationData("Levels", 265_8065), - "Level 066": KH1LocationData("Levels", 265_8066), - "Level 067": KH1LocationData("Levels", 265_8067), - "Level 068": KH1LocationData("Levels", 265_8068), - "Level 069": KH1LocationData("Levels", 265_8069), - "Level 070": KH1LocationData("Levels", 265_8070), - "Level 071": KH1LocationData("Levels", 265_8071), - "Level 072": KH1LocationData("Levels", 265_8072), - "Level 073": KH1LocationData("Levels", 265_8073), - "Level 074": KH1LocationData("Levels", 265_8074), - "Level 075": KH1LocationData("Levels", 265_8075), - "Level 076": KH1LocationData("Levels", 265_8076), - "Level 077": KH1LocationData("Levels", 265_8077), - "Level 078": KH1LocationData("Levels", 265_8078), - "Level 079": KH1LocationData("Levels", 265_8079), - "Level 080": KH1LocationData("Levels", 265_8080), - "Level 081": KH1LocationData("Levels", 265_8081), - "Level 082": KH1LocationData("Levels", 265_8082), - "Level 083": KH1LocationData("Levels", 265_8083), - "Level 084": KH1LocationData("Levels", 265_8084), - "Level 085": KH1LocationData("Levels", 265_8085), - "Level 086": KH1LocationData("Levels", 265_8086), - "Level 087": KH1LocationData("Levels", 265_8087), - "Level 088": KH1LocationData("Levels", 265_8088), - "Level 089": KH1LocationData("Levels", 265_8089), - "Level 090": KH1LocationData("Levels", 265_8090), - "Level 091": KH1LocationData("Levels", 265_8091), - "Level 092": KH1LocationData("Levels", 265_8092), - "Level 093": KH1LocationData("Levels", 265_8093), - "Level 094": KH1LocationData("Levels", 265_8094), - "Level 095": KH1LocationData("Levels", 265_8095), - "Level 096": KH1LocationData("Levels", 265_8096), - "Level 097": KH1LocationData("Levels", 265_8097), - "Level 098": KH1LocationData("Levels", 265_8098), - "Level 099": KH1LocationData("Levels", 265_8099), - "Level 100": KH1LocationData("Levels", 265_8100), - "Complete Phil Cup": KH1LocationData("Olympus Coliseum", 265_9001), - "Complete Phil Cup Solo": KH1LocationData("Olympus Coliseum", 265_9002), - "Complete Phil Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9003), - "Complete Pegasus Cup": KH1LocationData("Olympus Coliseum", 265_9004), - "Complete Pegasus Cup Solo": KH1LocationData("Olympus Coliseum", 265_9005), - "Complete Pegasus Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9006), - "Complete Hercules Cup": KH1LocationData("Olympus Coliseum", 265_9007), - "Complete Hercules Cup Solo": KH1LocationData("Olympus Coliseum", 265_9008), - "Complete Hercules Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9009), - "Complete Hades Cup": KH1LocationData("Olympus Coliseum", 265_9010), - "Complete Hades Cup Solo": KH1LocationData("Olympus Coliseum", 265_9011), - "Complete Hades Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9012), - "Hades Cup Defeat Cloud and Leon Event": KH1LocationData("Olympus Coliseum", 265_9013), - "Hades Cup Defeat Yuffie Event": KH1LocationData("Olympus Coliseum", 265_9014), - "Hades Cup Defeat Cerberus Event": KH1LocationData("Olympus Coliseum", 265_9015), - "Hades Cup Defeat Behemoth Event": KH1LocationData("Olympus Coliseum", 265_9016), - "Hades Cup Defeat Hades Event": KH1LocationData("Olympus Coliseum", 265_9017), - "Hercules Cup Defeat Cloud Event": KH1LocationData("Olympus Coliseum", 265_9018), - "Hercules Cup Yellow Trinity Event": KH1LocationData("Olympus Coliseum", 265_9019), - "Final Ansem": KH1LocationData("Final", 265_9999) + "Destiny Islands Seashore Capture Fish 1 (Day 2)": KH1LocationData("Destiny Islands", 265_6700, "Static"), + "Destiny Islands Seashore Capture Fish 2 (Day 2)": KH1LocationData("Destiny Islands", 265_6701, "Static"), + "Destiny Islands Seashore Capture Fish 3 (Day 2)": KH1LocationData("Destiny Islands", 265_6702, "Static"), + "Destiny Islands Seashore Gather Seagull Egg (Day 2)": KH1LocationData("Destiny Islands", 265_6703, "Static"), + "Destiny Islands Seashore Log on Riku's Island (Day 1)": KH1LocationData("Destiny Islands", 265_6704, "Static"), + "Destiny Islands Seashore Log under Bridge (Day 1)": KH1LocationData("Destiny Islands", 265_6705, "Static"), + "Destiny Islands Seashore Gather Cloth (Day 1)": KH1LocationData("Destiny Islands", 265_6706, "Static"), + "Destiny Islands Seashore Gather Rope (Day 1)": KH1LocationData("Destiny Islands", 265_6707, "Static"), + #"Destiny Islands Seashore Deliver Kairi Items (Day 1)": KH1LocationData("Destiny Islands", 265_6710, "Static"), + "Destiny Islands Secret Place Gather Mushroom (Day 2)": KH1LocationData("Destiny Islands", 265_6711, "Static"), + "Destiny Islands Cove Gather Mushroom Near Zip Line (Day 2)": KH1LocationData("Destiny Islands", 265_6712, "Static"), + "Destiny Islands Cove Gather Mushroom in Small Cave (Day 2)": KH1LocationData("Destiny Islands", 265_6713, "Static"), + "Destiny Islands Cove Talk to Kairi (Day 2)": KH1LocationData("Destiny Islands", 265_6714, "Static"), + "Destiny Islands Gather Drinking Water (Day 2)": KH1LocationData("Destiny Islands", 265_6715, "Static"), + #"Destiny Islands Cove Deliver Kairi Items (Day 2)": KH1LocationData("Destiny Islands", 265_6716, "Static"), + + "Donald Starting Accessory 1": KH1LocationData("Traverse Town", 265_6800, "Starting Accessory"), + "Donald Starting Accessory 2": KH1LocationData("Traverse Town", 265_6801, "Starting Accessory"), + "Goofy Starting Accessory 1": KH1LocationData("Traverse Town", 265_6802, "Starting Accessory"), + "Goofy Starting Accessory 2": KH1LocationData("Traverse Town", 265_6803, "Starting Accessory"), + "Tarzan Starting Accessory 1": KH1LocationData("Deep Jungle", 265_6804, "Starting Accessory"), + "Aladdin Starting Accessory 1": KH1LocationData("Agrabah", 265_6805, "Starting Accessory"), + "Aladdin Starting Accessory 2": KH1LocationData("Agrabah", 265_6806, "Starting Accessory"), + "Ariel Starting Accessory 1": KH1LocationData("Atlantica", 265_6807, "Starting Accessory"), + "Ariel Starting Accessory 2": KH1LocationData("Atlantica", 265_6808, "Starting Accessory"), + "Ariel Starting Accessory 3": KH1LocationData("Atlantica", 265_6809, "Starting Accessory"), + "Jack Starting Accessory 1": KH1LocationData("Halloween Town", 265_6810, "Starting Accessory"), + "Jack Starting Accessory 2": KH1LocationData("Halloween Town", 265_6811, "Starting Accessory"), + "Peter Pan Starting Accessory 1": KH1LocationData("Neverland", 265_6812, "Starting Accessory"), + "Peter Pan Starting Accessory 2": KH1LocationData("Neverland", 265_6813, "Starting Accessory"), + "Beast Starting Accessory 1": KH1LocationData("Hollow Bastion", 265_6814, "Starting Accessory"), + + "Agrabah Defeat Jafar Genie Ansem's Report 1": KH1LocationData("Agrabah", 265_7018, "Static", True), + "Hollow Bastion Speak with Aerith Ansem's Report 2": KH1LocationData("Hollow Bastion", 265_7017, "Static", True), + "Atlantica Defeat Ursula II Ansem's Report 3": KH1LocationData("Atlantica", 265_7016, "Static", True), + "Hollow Bastion Speak with Aerith Ansem's Report 4": KH1LocationData("Hollow Bastion", 265_7015, "Static", True), + "Hollow Bastion Defeat Maleficent Ansem's Report 5": KH1LocationData("Hollow Bastion", 265_7014, "Static", True), + "Hollow Bastion Speak with Aerith Ansem's Report 6": KH1LocationData("Hollow Bastion", 265_7013, "Static", True), + "Halloween Town Defeat Oogie Boogie Ansem's Report 7": KH1LocationData("Halloween Town", 265_7012, "Static", True), + "Olympus Coliseum Defeat Hades Ansem's Report 8": KH1LocationData("Olympus Coliseum", 265_7011, "Static", True), + "Neverland Defeat Hook Ansem's Report 9": KH1LocationData("Neverland", 265_7028, "Static", True), + "Hollow Bastion Speak with Aerith Ansem's Report 10": KH1LocationData("Hollow Bastion", 265_7027, "Static", True), + "Agrabah Defeat Kurt Zisa Ansem's Report 11": KH1LocationData("Agrabah", 265_7026, "Static", True), + "Olympus Coliseum Defeat Sephiroth Ansem's Report 12": KH1LocationData("Olympus Coliseum", 265_7025, "Static", True), + "Hollow Bastion Defeat Unknown Ansem's Report 13": KH1LocationData("Hollow Bastion", 265_7024, "Static", True), + #"Level 001 (Slot 1)": KH1LocationData("Levels", 265_8001, "Level Slot 1"), + "Level 002 (Slot 1)": KH1LocationData("Levels", 265_8002, "Level Slot 1"), + "Level 003 (Slot 1)": KH1LocationData("Levels", 265_8003, "Level Slot 1"), + "Level 004 (Slot 1)": KH1LocationData("Levels", 265_8004, "Level Slot 1"), + "Level 005 (Slot 1)": KH1LocationData("Levels", 265_8005, "Level Slot 1"), + "Level 006 (Slot 1)": KH1LocationData("Levels", 265_8006, "Level Slot 1"), + "Level 007 (Slot 1)": KH1LocationData("Levels", 265_8007, "Level Slot 1"), + "Level 008 (Slot 1)": KH1LocationData("Levels", 265_8008, "Level Slot 1"), + "Level 009 (Slot 1)": KH1LocationData("Levels", 265_8009, "Level Slot 1"), + "Level 010 (Slot 1)": KH1LocationData("Levels", 265_8010, "Level Slot 1"), + "Level 011 (Slot 1)": KH1LocationData("Levels", 265_8011, "Level Slot 1"), + "Level 012 (Slot 1)": KH1LocationData("Levels", 265_8012, "Level Slot 1"), + "Level 013 (Slot 1)": KH1LocationData("Levels", 265_8013, "Level Slot 1"), + "Level 014 (Slot 1)": KH1LocationData("Levels", 265_8014, "Level Slot 1"), + "Level 015 (Slot 1)": KH1LocationData("Levels", 265_8015, "Level Slot 1"), + "Level 016 (Slot 1)": KH1LocationData("Levels", 265_8016, "Level Slot 1"), + "Level 017 (Slot 1)": KH1LocationData("Levels", 265_8017, "Level Slot 1"), + "Level 018 (Slot 1)": KH1LocationData("Levels", 265_8018, "Level Slot 1"), + "Level 019 (Slot 1)": KH1LocationData("Levels", 265_8019, "Level Slot 1"), + "Level 020 (Slot 1)": KH1LocationData("Levels", 265_8020, "Level Slot 1"), + "Level 021 (Slot 1)": KH1LocationData("Levels", 265_8021, "Level Slot 1"), + "Level 022 (Slot 1)": KH1LocationData("Levels", 265_8022, "Level Slot 1"), + "Level 023 (Slot 1)": KH1LocationData("Levels", 265_8023, "Level Slot 1"), + "Level 024 (Slot 1)": KH1LocationData("Levels", 265_8024, "Level Slot 1"), + "Level 025 (Slot 1)": KH1LocationData("Levels", 265_8025, "Level Slot 1"), + "Level 026 (Slot 1)": KH1LocationData("Levels", 265_8026, "Level Slot 1"), + "Level 027 (Slot 1)": KH1LocationData("Levels", 265_8027, "Level Slot 1"), + "Level 028 (Slot 1)": KH1LocationData("Levels", 265_8028, "Level Slot 1"), + "Level 029 (Slot 1)": KH1LocationData("Levels", 265_8029, "Level Slot 1"), + "Level 030 (Slot 1)": KH1LocationData("Levels", 265_8030, "Level Slot 1"), + "Level 031 (Slot 1)": KH1LocationData("Levels", 265_8031, "Level Slot 1"), + "Level 032 (Slot 1)": KH1LocationData("Levels", 265_8032, "Level Slot 1"), + "Level 033 (Slot 1)": KH1LocationData("Levels", 265_8033, "Level Slot 1"), + "Level 034 (Slot 1)": KH1LocationData("Levels", 265_8034, "Level Slot 1"), + "Level 035 (Slot 1)": KH1LocationData("Levels", 265_8035, "Level Slot 1"), + "Level 036 (Slot 1)": KH1LocationData("Levels", 265_8036, "Level Slot 1"), + "Level 037 (Slot 1)": KH1LocationData("Levels", 265_8037, "Level Slot 1"), + "Level 038 (Slot 1)": KH1LocationData("Levels", 265_8038, "Level Slot 1"), + "Level 039 (Slot 1)": KH1LocationData("Levels", 265_8039, "Level Slot 1"), + "Level 040 (Slot 1)": KH1LocationData("Levels", 265_8040, "Level Slot 1"), + "Level 041 (Slot 1)": KH1LocationData("Levels", 265_8041, "Level Slot 1"), + "Level 042 (Slot 1)": KH1LocationData("Levels", 265_8042, "Level Slot 1"), + "Level 043 (Slot 1)": KH1LocationData("Levels", 265_8043, "Level Slot 1"), + "Level 044 (Slot 1)": KH1LocationData("Levels", 265_8044, "Level Slot 1"), + "Level 045 (Slot 1)": KH1LocationData("Levels", 265_8045, "Level Slot 1"), + "Level 046 (Slot 1)": KH1LocationData("Levels", 265_8046, "Level Slot 1"), + "Level 047 (Slot 1)": KH1LocationData("Levels", 265_8047, "Level Slot 1"), + "Level 048 (Slot 1)": KH1LocationData("Levels", 265_8048, "Level Slot 1"), + "Level 049 (Slot 1)": KH1LocationData("Levels", 265_8049, "Level Slot 1"), + "Level 050 (Slot 1)": KH1LocationData("Levels", 265_8050, "Level Slot 1"), + "Level 051 (Slot 1)": KH1LocationData("Levels", 265_8051, "Level Slot 1"), + "Level 052 (Slot 1)": KH1LocationData("Levels", 265_8052, "Level Slot 1"), + "Level 053 (Slot 1)": KH1LocationData("Levels", 265_8053, "Level Slot 1"), + "Level 054 (Slot 1)": KH1LocationData("Levels", 265_8054, "Level Slot 1"), + "Level 055 (Slot 1)": KH1LocationData("Levels", 265_8055, "Level Slot 1"), + "Level 056 (Slot 1)": KH1LocationData("Levels", 265_8056, "Level Slot 1"), + "Level 057 (Slot 1)": KH1LocationData("Levels", 265_8057, "Level Slot 1"), + "Level 058 (Slot 1)": KH1LocationData("Levels", 265_8058, "Level Slot 1"), + "Level 059 (Slot 1)": KH1LocationData("Levels", 265_8059, "Level Slot 1"), + "Level 060 (Slot 1)": KH1LocationData("Levels", 265_8060, "Level Slot 1"), + "Level 061 (Slot 1)": KH1LocationData("Levels", 265_8061, "Level Slot 1"), + "Level 062 (Slot 1)": KH1LocationData("Levels", 265_8062, "Level Slot 1"), + "Level 063 (Slot 1)": KH1LocationData("Levels", 265_8063, "Level Slot 1"), + "Level 064 (Slot 1)": KH1LocationData("Levels", 265_8064, "Level Slot 1"), + "Level 065 (Slot 1)": KH1LocationData("Levels", 265_8065, "Level Slot 1"), + "Level 066 (Slot 1)": KH1LocationData("Levels", 265_8066, "Level Slot 1"), + "Level 067 (Slot 1)": KH1LocationData("Levels", 265_8067, "Level Slot 1"), + "Level 068 (Slot 1)": KH1LocationData("Levels", 265_8068, "Level Slot 1"), + "Level 069 (Slot 1)": KH1LocationData("Levels", 265_8069, "Level Slot 1"), + "Level 070 (Slot 1)": KH1LocationData("Levels", 265_8070, "Level Slot 1"), + "Level 071 (Slot 1)": KH1LocationData("Levels", 265_8071, "Level Slot 1"), + "Level 072 (Slot 1)": KH1LocationData("Levels", 265_8072, "Level Slot 1"), + "Level 073 (Slot 1)": KH1LocationData("Levels", 265_8073, "Level Slot 1"), + "Level 074 (Slot 1)": KH1LocationData("Levels", 265_8074, "Level Slot 1"), + "Level 075 (Slot 1)": KH1LocationData("Levels", 265_8075, "Level Slot 1"), + "Level 076 (Slot 1)": KH1LocationData("Levels", 265_8076, "Level Slot 1"), + "Level 077 (Slot 1)": KH1LocationData("Levels", 265_8077, "Level Slot 1"), + "Level 078 (Slot 1)": KH1LocationData("Levels", 265_8078, "Level Slot 1"), + "Level 079 (Slot 1)": KH1LocationData("Levels", 265_8079, "Level Slot 1"), + "Level 080 (Slot 1)": KH1LocationData("Levels", 265_8080, "Level Slot 1"), + "Level 081 (Slot 1)": KH1LocationData("Levels", 265_8081, "Level Slot 1"), + "Level 082 (Slot 1)": KH1LocationData("Levels", 265_8082, "Level Slot 1"), + "Level 083 (Slot 1)": KH1LocationData("Levels", 265_8083, "Level Slot 1"), + "Level 084 (Slot 1)": KH1LocationData("Levels", 265_8084, "Level Slot 1"), + "Level 085 (Slot 1)": KH1LocationData("Levels", 265_8085, "Level Slot 1"), + "Level 086 (Slot 1)": KH1LocationData("Levels", 265_8086, "Level Slot 1"), + "Level 087 (Slot 1)": KH1LocationData("Levels", 265_8087, "Level Slot 1"), + "Level 088 (Slot 1)": KH1LocationData("Levels", 265_8088, "Level Slot 1"), + "Level 089 (Slot 1)": KH1LocationData("Levels", 265_8089, "Level Slot 1"), + "Level 090 (Slot 1)": KH1LocationData("Levels", 265_8090, "Level Slot 1"), + "Level 091 (Slot 1)": KH1LocationData("Levels", 265_8091, "Level Slot 1"), + "Level 092 (Slot 1)": KH1LocationData("Levels", 265_8092, "Level Slot 1"), + "Level 093 (Slot 1)": KH1LocationData("Levels", 265_8093, "Level Slot 1"), + "Level 094 (Slot 1)": KH1LocationData("Levels", 265_8094, "Level Slot 1"), + "Level 095 (Slot 1)": KH1LocationData("Levels", 265_8095, "Level Slot 1"), + "Level 096 (Slot 1)": KH1LocationData("Levels", 265_8096, "Level Slot 1"), + "Level 097 (Slot 1)": KH1LocationData("Levels", 265_8097, "Level Slot 1"), + "Level 098 (Slot 1)": KH1LocationData("Levels", 265_8098, "Level Slot 1"), + "Level 099 (Slot 1)": KH1LocationData("Levels", 265_8099, "Level Slot 1"), + "Level 100 (Slot 1)": KH1LocationData("Levels", 265_8100, "Level Slot 1"), + #"Level 001 (Slot 2)": KH1LocationData("Levels", 265_8101, "Level Slot 2"), + "Level 002 (Slot 2)": KH1LocationData("Levels", 265_8102, "Level Slot 2"), + "Level 003 (Slot 2)": KH1LocationData("Levels", 265_8103, "Level Slot 2"), + "Level 004 (Slot 2)": KH1LocationData("Levels", 265_8104, "Level Slot 2"), + "Level 005 (Slot 2)": KH1LocationData("Levels", 265_8105, "Level Slot 2"), + "Level 006 (Slot 2)": KH1LocationData("Levels", 265_8106, "Level Slot 2"), + "Level 007 (Slot 2)": KH1LocationData("Levels", 265_8107, "Level Slot 2"), + "Level 008 (Slot 2)": KH1LocationData("Levels", 265_8108, "Level Slot 2"), + "Level 009 (Slot 2)": KH1LocationData("Levels", 265_8109, "Level Slot 2"), + "Level 010 (Slot 2)": KH1LocationData("Levels", 265_8110, "Level Slot 2"), + "Level 011 (Slot 2)": KH1LocationData("Levels", 265_8111, "Level Slot 2"), + "Level 012 (Slot 2)": KH1LocationData("Levels", 265_8112, "Level Slot 2"), + "Level 013 (Slot 2)": KH1LocationData("Levels", 265_8113, "Level Slot 2"), + "Level 014 (Slot 2)": KH1LocationData("Levels", 265_8114, "Level Slot 2"), + "Level 015 (Slot 2)": KH1LocationData("Levels", 265_8115, "Level Slot 2"), + "Level 016 (Slot 2)": KH1LocationData("Levels", 265_8116, "Level Slot 2"), + "Level 017 (Slot 2)": KH1LocationData("Levels", 265_8117, "Level Slot 2"), + "Level 018 (Slot 2)": KH1LocationData("Levels", 265_8118, "Level Slot 2"), + "Level 019 (Slot 2)": KH1LocationData("Levels", 265_8119, "Level Slot 2"), + "Level 020 (Slot 2)": KH1LocationData("Levels", 265_8120, "Level Slot 2"), + "Level 021 (Slot 2)": KH1LocationData("Levels", 265_8121, "Level Slot 2"), + "Level 022 (Slot 2)": KH1LocationData("Levels", 265_8122, "Level Slot 2"), + "Level 023 (Slot 2)": KH1LocationData("Levels", 265_8123, "Level Slot 2"), + "Level 024 (Slot 2)": KH1LocationData("Levels", 265_8124, "Level Slot 2"), + "Level 025 (Slot 2)": KH1LocationData("Levels", 265_8125, "Level Slot 2"), + "Level 026 (Slot 2)": KH1LocationData("Levels", 265_8126, "Level Slot 2"), + "Level 027 (Slot 2)": KH1LocationData("Levels", 265_8127, "Level Slot 2"), + "Level 028 (Slot 2)": KH1LocationData("Levels", 265_8128, "Level Slot 2"), + "Level 029 (Slot 2)": KH1LocationData("Levels", 265_8129, "Level Slot 2"), + "Level 030 (Slot 2)": KH1LocationData("Levels", 265_8130, "Level Slot 2"), + "Level 031 (Slot 2)": KH1LocationData("Levels", 265_8131, "Level Slot 2"), + "Level 032 (Slot 2)": KH1LocationData("Levels", 265_8132, "Level Slot 2"), + "Level 033 (Slot 2)": KH1LocationData("Levels", 265_8133, "Level Slot 2"), + "Level 034 (Slot 2)": KH1LocationData("Levels", 265_8134, "Level Slot 2"), + "Level 035 (Slot 2)": KH1LocationData("Levels", 265_8135, "Level Slot 2"), + "Level 036 (Slot 2)": KH1LocationData("Levels", 265_8136, "Level Slot 2"), + "Level 037 (Slot 2)": KH1LocationData("Levels", 265_8137, "Level Slot 2"), + "Level 038 (Slot 2)": KH1LocationData("Levels", 265_8138, "Level Slot 2"), + "Level 039 (Slot 2)": KH1LocationData("Levels", 265_8139, "Level Slot 2"), + "Level 040 (Slot 2)": KH1LocationData("Levels", 265_8140, "Level Slot 2"), + "Level 041 (Slot 2)": KH1LocationData("Levels", 265_8141, "Level Slot 2"), + "Level 042 (Slot 2)": KH1LocationData("Levels", 265_8142, "Level Slot 2"), + "Level 043 (Slot 2)": KH1LocationData("Levels", 265_8143, "Level Slot 2"), + "Level 044 (Slot 2)": KH1LocationData("Levels", 265_8144, "Level Slot 2"), + "Level 045 (Slot 2)": KH1LocationData("Levels", 265_8145, "Level Slot 2"), + "Level 046 (Slot 2)": KH1LocationData("Levels", 265_8146, "Level Slot 2"), + "Level 047 (Slot 2)": KH1LocationData("Levels", 265_8147, "Level Slot 2"), + "Level 048 (Slot 2)": KH1LocationData("Levels", 265_8148, "Level Slot 2"), + "Level 049 (Slot 2)": KH1LocationData("Levels", 265_8149, "Level Slot 2"), + "Level 050 (Slot 2)": KH1LocationData("Levels", 265_8150, "Level Slot 2"), + "Level 051 (Slot 2)": KH1LocationData("Levels", 265_8151, "Level Slot 2"), + "Level 052 (Slot 2)": KH1LocationData("Levels", 265_8152, "Level Slot 2"), + "Level 053 (Slot 2)": KH1LocationData("Levels", 265_8153, "Level Slot 2"), + "Level 054 (Slot 2)": KH1LocationData("Levels", 265_8154, "Level Slot 2"), + "Level 055 (Slot 2)": KH1LocationData("Levels", 265_8155, "Level Slot 2"), + "Level 056 (Slot 2)": KH1LocationData("Levels", 265_8156, "Level Slot 2"), + "Level 057 (Slot 2)": KH1LocationData("Levels", 265_8157, "Level Slot 2"), + "Level 058 (Slot 2)": KH1LocationData("Levels", 265_8158, "Level Slot 2"), + "Level 059 (Slot 2)": KH1LocationData("Levels", 265_8159, "Level Slot 2"), + "Level 060 (Slot 2)": KH1LocationData("Levels", 265_8160, "Level Slot 2"), + "Level 061 (Slot 2)": KH1LocationData("Levels", 265_8161, "Level Slot 2"), + "Level 062 (Slot 2)": KH1LocationData("Levels", 265_8162, "Level Slot 2"), + "Level 063 (Slot 2)": KH1LocationData("Levels", 265_8163, "Level Slot 2"), + "Level 064 (Slot 2)": KH1LocationData("Levels", 265_8164, "Level Slot 2"), + "Level 065 (Slot 2)": KH1LocationData("Levels", 265_8165, "Level Slot 2"), + "Level 066 (Slot 2)": KH1LocationData("Levels", 265_8166, "Level Slot 2"), + "Level 067 (Slot 2)": KH1LocationData("Levels", 265_8167, "Level Slot 2"), + "Level 068 (Slot 2)": KH1LocationData("Levels", 265_8168, "Level Slot 2"), + "Level 069 (Slot 2)": KH1LocationData("Levels", 265_8169, "Level Slot 2"), + "Level 070 (Slot 2)": KH1LocationData("Levels", 265_8170, "Level Slot 2"), + "Level 071 (Slot 2)": KH1LocationData("Levels", 265_8171, "Level Slot 2"), + "Level 072 (Slot 2)": KH1LocationData("Levels", 265_8172, "Level Slot 2"), + "Level 073 (Slot 2)": KH1LocationData("Levels", 265_8173, "Level Slot 2"), + "Level 074 (Slot 2)": KH1LocationData("Levels", 265_8174, "Level Slot 2"), + "Level 075 (Slot 2)": KH1LocationData("Levels", 265_8175, "Level Slot 2"), + "Level 076 (Slot 2)": KH1LocationData("Levels", 265_8176, "Level Slot 2"), + "Level 077 (Slot 2)": KH1LocationData("Levels", 265_8177, "Level Slot 2"), + "Level 078 (Slot 2)": KH1LocationData("Levels", 265_8178, "Level Slot 2"), + "Level 079 (Slot 2)": KH1LocationData("Levels", 265_8179, "Level Slot 2"), + "Level 080 (Slot 2)": KH1LocationData("Levels", 265_8180, "Level Slot 2"), + "Level 081 (Slot 2)": KH1LocationData("Levels", 265_8181, "Level Slot 2"), + "Level 082 (Slot 2)": KH1LocationData("Levels", 265_8182, "Level Slot 2"), + "Level 083 (Slot 2)": KH1LocationData("Levels", 265_8183, "Level Slot 2"), + "Level 084 (Slot 2)": KH1LocationData("Levels", 265_8184, "Level Slot 2"), + "Level 085 (Slot 2)": KH1LocationData("Levels", 265_8185, "Level Slot 2"), + "Level 086 (Slot 2)": KH1LocationData("Levels", 265_8186, "Level Slot 2"), + "Level 087 (Slot 2)": KH1LocationData("Levels", 265_8187, "Level Slot 2"), + "Level 088 (Slot 2)": KH1LocationData("Levels", 265_8188, "Level Slot 2"), + "Level 089 (Slot 2)": KH1LocationData("Levels", 265_8189, "Level Slot 2"), + "Level 090 (Slot 2)": KH1LocationData("Levels", 265_8190, "Level Slot 2"), + "Level 091 (Slot 2)": KH1LocationData("Levels", 265_8191, "Level Slot 2"), + "Level 092 (Slot 2)": KH1LocationData("Levels", 265_8192, "Level Slot 2"), + "Level 093 (Slot 2)": KH1LocationData("Levels", 265_8193, "Level Slot 2"), + "Level 094 (Slot 2)": KH1LocationData("Levels", 265_8194, "Level Slot 2"), + "Level 095 (Slot 2)": KH1LocationData("Levels", 265_8195, "Level Slot 2"), + "Level 096 (Slot 2)": KH1LocationData("Levels", 265_8196, "Level Slot 2"), + "Level 097 (Slot 2)": KH1LocationData("Levels", 265_8197, "Level Slot 2"), + "Level 098 (Slot 2)": KH1LocationData("Levels", 265_8198, "Level Slot 2"), + "Level 099 (Slot 2)": KH1LocationData("Levels", 265_8199, "Level Slot 2"), + "Level 100 (Slot 2)": KH1LocationData("Levels", 265_8200, "Level Slot 2"), + "Complete Phil Cup": KH1LocationData("Olympus Coliseum", 265_9001, "Static", True), + "Complete Phil Cup Solo": KH1LocationData("Olympus Coliseum", 265_9002, "Reward", True), + "Complete Phil Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9003, "Reward", True), + "Complete Pegasus Cup": KH1LocationData("Olympus Coliseum", 265_9004, "Reward", True), + "Complete Pegasus Cup Solo": KH1LocationData("Olympus Coliseum", 265_9005, "Reward", True), + "Complete Pegasus Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9006, "Reward", True), + "Complete Hercules Cup": KH1LocationData("Olympus Coliseum", 265_9007, "Reward", True), + "Complete Hercules Cup Solo": KH1LocationData("Olympus Coliseum", 265_9008, "Reward", True), + "Complete Hercules Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9009, "Reward", True), + "Complete Hades Cup": KH1LocationData("Olympus Coliseum", 265_9010, "Reward", True), + "Complete Hades Cup Solo": KH1LocationData("Olympus Coliseum", 265_9011, "Reward", True), + "Complete Hades Cup Time Trial": KH1LocationData("Olympus Coliseum", 265_9012, "Reward", True), + "Hades Cup Defeat Cloud and Leon Event": KH1LocationData("Olympus Coliseum", 265_9013, "Reward", True), + "Hades Cup Defeat Yuffie Event": KH1LocationData("Olympus Coliseum", 265_9014, "Reward", True), + "Hades Cup Defeat Cerberus Event": KH1LocationData("Olympus Coliseum", 265_9015, "Static", True), + "Hades Cup Defeat Behemoth Event": KH1LocationData("Olympus Coliseum", 265_9016, "Static", True), + "Hades Cup Defeat Hades Event": KH1LocationData("Olympus Coliseum", 265_9017, "Static", True), + "Hercules Cup Defeat Cloud Event": KH1LocationData("Olympus Coliseum", 265_9018, "Reward", True), + "Hercules Cup Yellow Trinity Event": KH1LocationData("Olympus Coliseum", 265_9019, "Static", True) } -event_location_table: Dict[str, KH1LocationData] = {} +event_location_table: Dict[str, KH1LocationData] = { + "Final Ansem": KH1LocationData("Homecoming", 265_9999, "None", True) +} lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in location_table.items() if data.code} diff --git a/worlds/kh1/Options.py b/worlds/kh1/Options.py index 7a79d5c1ea92..1bdc478a4e2f 100644 --- a/worlds/kh1/Options.py +++ b/worlds/kh1/Options.py @@ -6,8 +6,9 @@ class StrengthIncrease(Range): """ Determines the number of Strength Increases to add to the multiworld. - The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. - Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + The randomizer will add all stat ups defined here into a pool and choose up to 99 to add to the multiworld. + + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 99 total) are chosen at random. """ display_name = "STR Increases" range_start = 0 @@ -18,8 +19,9 @@ class DefenseIncrease(Range): """ Determines the number of Defense Increases to add to the multiworld. - The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. - Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + The randomizer will add all stat ups defined here into a pool and choose up to 99 to add to the multiworld. + + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 99 total) are chosen at random. """ display_name = "DEF Increases" range_start = 0 @@ -30,8 +32,9 @@ class HPIncrease(Range): """ Determines the number of HP Increases to add to the multiworld. - The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. - Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + The randomizer will add all stat ups defined here into a pool and choose up to 99 to add to the multiworld. + + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 99 total) are chosen at random. """ display_name = "HP Increases" range_start = 0 @@ -42,8 +45,9 @@ class APIncrease(Range): """ Determines the number of AP Increases to add to the multiworld. - The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. - Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + The randomizer will add all stat ups defined here into a pool and choose up to 99 to add to the multiworld. + + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 99 total) are chosen at random. """ display_name = "AP Increases" range_start = 0 @@ -54,8 +58,9 @@ class MPIncrease(Range): """ Determines the number of MP Increases to add to the multiworld. - The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. - Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + The randomizer will add all stat ups defined here into a pool and choose up to 99 to add to the multiworld. + + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 99 total) are chosen at random. """ display_name = "MP Increases" range_start = 0 @@ -66,8 +71,9 @@ class AccessorySlotIncrease(Range): """ Determines the number of Accessory Slot Increases to add to the multiworld. - The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. - Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + The randomizer will add all stat ups defined here into a pool and choose up to 99 to add to the multiworld. + + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 99 total) are chosen at random. """ display_name = "Accessory Slot Increases" range_start = 0 @@ -78,8 +84,9 @@ class ItemSlotIncrease(Range): """ Determines the number of Item Slot Increases to add to the multiworld. - The randomizer will add all stat ups defined here into a pool and choose up to 100 to add to the multiworld. - Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 100 total) are chosen at random. + The randomizer will add all stat ups defined here into a pool and choose up to 99 to add to the multiworld. + + Accessory Slot Increases and Item Slot Increases are prioritized first, then the remaining items (up to 99 total) are chosen at random. """ display_name = "Item Slot Increases" range_start = 0 @@ -104,29 +111,45 @@ class SuperBosses(Toggle): """ display_name = "Super Bosses" -class Cups(Toggle): +class Cups(Choice): """ - Toggle whether to include checks behind completing Phil, Pegasus, Hercules, or Hades cups. - Please note that the cup items will still appear in the multiworld even if toggled off, as they are required to challenge Sephiroth. + Determines which cups have their locations added to the multiworld. + + Please note that the cup items will still appear in the multiworld even if set to off, as they are required to challenge Sephiroth. + + Off: All cup locations are removed + + Cups: Phil, Pegasus, and Hercules cups are included + + Hades Cup: Hades Cup is included in addition to Phil, Pegasus, and Hercules cups. If Super Bosses are enabled, then Ice Titan is included """ display_name = "Cups" + option_off = 0 + option_cups = 1 + option_hades_cup = 2 + default = 0 -class Goal(Choice): +class FinalRestDoorKey(Choice): """ - Determines when victory is achieved in your playthrough. + Determines what grants the player the Final Rest Door Key. Sephiroth: Defeat Sephiroth + Unknown: Defeat Unknown - Postcards: Turn in all 10 postcards in Traverse Town + + Postcards: Turn in an amount of postcards in Traverse Town + Final Ansem: Enter End of the World and defeat Ansem as normal - Puppies: Rescue and return all 99 puppies in Traverse Town + + Puppies: Rescue and return an amount of puppies in Traverse Town + Final Rest: Open the chest in End of the World Final Rest """ - display_name = "Goal" + display_name = "Final Rest Door Key" option_sephiroth = 0 option_unknown = 1 option_postcards = 2 - option_final_ansem = 3 + option_lucky_emblems = 3 option_puppies = 4 option_final_rest = 5 default = 3 @@ -135,89 +158,115 @@ class EndoftheWorldUnlock(Choice): """Determines how End of the World is unlocked. Item: You can receive an item called "End of the World" which unlocks the world - Reports: A certain amount of reports are required to unlock End of the World, which is defined in your options""" + + Lucky Emblems: A certain amount of lucky emblems are required to unlock End of the World, which is defined in your options""" display_name = "End of the World Unlock" option_item = 0 - option_reports = 1 + option_lucky_emblems = 1 default = 1 -class FinalRestDoor(Choice): - """Determines what conditions need to be met to manifest the door in Final Rest, allowing the player to challenge Ansem. - - Reports: A certain number of Ansem's Reports are required, determined by the "Reports to Open Final Rest Door" option - Puppies: Having all 99 puppies is required - Postcards: Turning in all 10 postcards is required - Superbosses: Defeating Sephiroth, Unknown, Kurt Zisa, and Phantom are required +class RequiredPostcards(Range): """ - display_name = "Final Rest Door" - option_reports = 0 - option_puppies = 1 - option_postcards = 2 - option_superbosses = 3 + If "Final Rest Door Key" is set to "Postcards", defines how many postcards are required. + """ + display_name = "Required Postcards" + default = 8 + range_start = 1 + range_end = 10 -class Puppies(Choice): +class RequiredPuppies(Choice): """ - Determines how dalmatian puppies are shuffled into the pool. - Full: All puppies are in one location - Triplets: Puppies are found in triplets just as they are in the base game - Individual: One puppy can be found per location + If "Final Rest Door Key" is set to "Puppies", defines how many puppies are required. """ - display_name = "Puppies" - option_full = 0 - option_triplets = 1 - option_individual = 2 - default = 1 + display_name = "Required Puppies" + default = 80 + option_10 = 10 + option_20 = 20 + option_30 = 30 + option_40 = 40 + option_50 = 50 + option_60 = 60 + option_70 = 70 + option_80 = 80 + option_90 = 90 + option_99 = 99 + +class PuppyValue(Range): + """ + Determines how many dalmatian puppies are given when a puppy item is found. + """ + display_name = "Puppy Value" + default = 3 + range_start = 1 + range_end = 99 + +class RandomizePuppies(DefaultOnToggle): + """ + If OFF, the "Puppy" item is worth 3 puppies and puppies are placed in vanilla locations. + + If ON, the "Puppy" item is worth an amount of puppies defined by "Puppy Value", and are shuffled randomly. + """ + display_name = "Randomize Puppies" class EXPMultiplier(NamedRange): """ Determines the multiplier to apply to EXP gained. """ display_name = "EXP Multiplier" - default = 16 - range_start = default // 4 + default = 16 * 4 + range_start = 16 // 4 range_end = 128 special_range_names = { - "0.25x": int(default // 4), - "0.5x": int(default // 2), - "1x": default, - "2x": default * 2, - "3x": default * 3, - "4x": default * 4, - "8x": default * 8, + "0.25x": int(16 // 4), + "0.5x": int(16 // 2), + "1x": 16, + "2x": 16 * 2, + "3x": 16 * 3, + "4x": 16 * 4, + "8x": 16 * 8, } -class RequiredReportsEotW(Range): +class RequiredLuckyEmblemsEotW(Range): """ - If End of the World Unlock is set to "Reports", determines the number of Ansem's Reports required to open End of the World. + If End of the World Unlock is set to "Lucky Emblems", determines the number of Lucky Emblems required. """ - display_name = "Reports to Open End of the World" - default = 4 + display_name = "Lucky Emblems to Open End of the World" + default = 7 range_start = 0 - range_end = 13 + range_end = 20 -class RequiredReportsDoor(Range): +class RequiredLuckyEmblemsDoor(Range): """ - If Final Rest Door is set to "Reports", determines the number of Ansem's Reports required to manifest the door in Final Rest to challenge Ansem. + If Final Rest Door Key is set to "Lucky Emblems", determines the number of Lucky Emblems required. """ - display_name = "Reports to Open Final Rest Door" - default = 4 + display_name = "Lucky Emblems to Open Final Rest Door" + default = 10 range_start = 0 - range_end = 13 + range_end = 20 -class ReportsInPool(Range): +class LuckyEmblemsInPool(Range): """ - Determines the number of Ansem's Reports in the item pool. + Determines the number of Lucky Emblems in the item pool. """ - display_name = "Reports in Pool" - default = 4 + display_name = "Lucky Emblems in Pool" + default = 13 range_start = 0 - range_end = 13 + range_end = 20 -class RandomizeKeybladeStats(DefaultOnToggle): +class KeybladeStats(Choice): """ Determines whether Keyblade stats should be randomized. + + Randomize: Randomly generates STR and MP bonuses for each keyblade between the defined minimums and maximums. + + Shuffle: Shuffles the stats of the vanilla keyblades amongst each other. + + Vanilla: Keyblade stats are unchanged. """ - display_name = "Randomize Keyblade Stats" + display_name = "Keyblade Stats" + option_randomize = 0 + option_shuffle = 1 + option_vanilla = 2 class KeybladeMinStrength(Range): """ @@ -237,6 +286,60 @@ class KeybladeMaxStrength(Range): range_start = 0 range_end = 20 +class KeybladeMinCritRateBonus(Range): + """ + Determines the minimum Crit Rate bonus a keyblade can have. + """ + display_name = "Keyblade Minimum Crit Rate Bonus" + default = 0 + range_start = 0 + range_end = 200 + +class KeybladeMaxCritRateBonus(Range): + """ + Determines the maximum Crit Rate bonus a keyblade can have. + """ + display_name = "Keyblade Maximum Crit Rate Bonus" + default = 200 + range_start = 0 + range_end = 200 + +class KeybladeMinCritSTRBonus(Range): + """ + Determines the minimum Crit STR bonus a keyblade can have. + """ + display_name = "Keyblade Minimum Crit Rate Bonus" + default = 0 + range_start = 0 + range_end = 16 + +class KeybladeMaxCritSTRBonus(Range): + """ + Determines the maximum Crit STR bonus a keyblade can have. + """ + display_name = "Keyblade Maximum Crit Rate Bonus" + default = 16 + range_start = 0 + range_end = 16 + +class KeybladeMinRecoil(Range): + """ + Determines the minimum recoil a keyblade can have. + """ + display_name = "Keyblade Minimum Recoil" + default = 1 + range_start = 1 + range_end = 90 + +class KeybladeMaxRecoil(Range): + """ + Determines the maximum recoil a keyblade can have. + """ + display_name = "Keyblade Maximum Recoil" + default = 90 + range_start = 1 + range_end = 90 + class KeybladeMinMP(Range): """ Determines the minimum MP bonus a keyblade can have. @@ -260,31 +363,43 @@ class LevelChecks(Range): Determines the maximum level for which checks can be obtained. """ display_name = "Level Checks" - default = 100 + default = 99 range_start = 0 - range_end = 100 + range_end = 99 class ForceStatsOnLevels(NamedRange): """ If this value is less than the value for Level Checks, this determines the minimum level from which only stat ups are obtained at level up locations. - For example, if you want to be able to find any multiworld item from levels 1-50, then just stat ups for levels 51-100, set this value to 51. + + For example, if you want to be able to find any multiworld item from levels 2-50, then just stat ups for levels 51-100, set this value to 51. """ display_name = "Force Stats on Level Starting From" - default = 1 - range_start = 1 + default = 2 + range_start = 2 range_end = 101 special_range_names = { "none": 101, "multiworld-to-level-50": 51, - "all": 1 + "all": 2 } class BadStartingWeapons(Toggle): """ - Forces Kingdom Key, Dream Sword, Dream Shield, and Dream Staff to have bad stats. + Forces Kingdom Key, Dream Sword, Dream Shield, and Dream Staff to have vanilla stats. """ display_name = "Bad Starting Weapons" +class DeathLink(Choice): + """ + If Sora is KO'ed, the other players with "Death Link" on will also be KO'ed. + The opposite is also true. + """ + display_name = "Death Link" + option_off = 0 + option_toggle = 1 + option_on = 2 + default = 0 + class DonaldDeathLink(Toggle): """ If Donald is KO'ed, so is Sora. If Death Link is toggled on in your client, this will send a death to everyone who enabled death link. @@ -300,35 +415,61 @@ class GoofyDeathLink(Toggle): class KeybladesUnlockChests(Toggle): """ If toggled on, the player is required to have a certain keyblade to open chests in certain worlds. + TT - Lionheart + WL - Lady Luck + OC - Olympia + DJ - Jungle King + AG - Three Wishes + MS - Wishing Star + HT - Pumpkinhead + NL - Fairy Harp + HB - Divine Rose + EotW - Oblivion - HAW - Oathkeeper + + HAW - Spellbinder + + DI - Oathkeeper Note: Does not apply to Atlantica, the emblem and carousel chests in Hollow Bastion, or the Aero chest in Neverland currently. """ display_name = "Keyblades Unlock Chests" -class InteractInBattle(Toggle): +class InteractInBattle(DefaultOnToggle): """ Allow Sora to talk to people, examine objects, and open chests in battle. """ display_name = "Interact in Battle" -class AdvancedLogic(Toggle): +class LogicDifficulty(Choice): """ - If on, logic may expect you to do advanced skips like using Combo Master, Dumbo, and other unusual methods to reach locations. + Determines what the randomizer logic may expect you to do to reach certain locations. + + Beginner: Logic only expects what would be the natural solution in vanilla gameplay or similar, as well as a guarantee of tools for boss fights. + + Normal: Logic expects some clever use of abilities, exploration of options, and competent combat ability; generally does not require advanced knowledge. + + Proud: Logic expects advanced knowledge of tricks and obscure interactions, such as using Combo Master, Dumbo, and other unusual methods to reach locations. + + Minimal: Logic expects the bare minimum to get to locations; may require extensive grinding, beating fights with no tools, and performing very difficult or tedious tricks. """ - display_name = "Advanced Logic" + display_name = "Logic Difficulty" + option_beginner = 0 + option_normal = 5 + option_proud = 10 + option_minimal = 15 + default = 5 -class ExtraSharedAbilities(Toggle): +class ExtraSharedAbilities(DefaultOnToggle): """ If on, adds extra shared abilities to the pool. These can stack, so multiple high jumps make you jump higher and multiple glides make you superglide faster. """ @@ -340,51 +481,361 @@ class EXPZeroInPool(Toggle): """ display_name = "EXP Zero in Pool" -class VanillaEmblemPieces(DefaultOnToggle): +class RandomizeEmblemPieces(Toggle): + """ + If off, the Hollow Bastion emblem pieces are in their vanilla locations. + """ + display_name = "Randomize Emblem Pieces" + +class RandomizePostcards(Choice): + """ + Determines how Postcards are randomized + + All: All Postcards are randomized + + Chests: Only the 3 Postcards in chests are randomized + + Vanilla: Postcards are in their original location + """ + display_name = "Randomize Postcards" + option_all = 0 + option_chests = 1 + option_vanilla = 2 + +class JungleSlider(Toggle): """ - If on, the Hollow Bastion emblem pieces are in their vanilla locations. + Determines whether checks are behind the Jungle Slider minigame. """ - display_name = "Vanilla Emblem Pieces" + display_name = "Jungle Slider" class StartingWorlds(Range): """ - Number of random worlds to start with in addition to Traverse Town, which is always available. Will only consider Atlantica if toggled, and will only consider End of the World if its unlock is set to "Item". + Number of random worlds to start with in addition to Traverse Town, which is always available. + + Will only consider Atlantica if toggled, and will only consider End of the World if its unlock is set to "Item". + + These are given by the server, and are received after connection. """ display_name = "Starting Worlds" - default = 0 + default = 4 range_start = 0 range_end = 10 + +class StartingTools(DefaultOnToggle): + """ + Determines whether you start with Scan and Dodge Roll. + + These are given by the server, and are received after connection. + """ + display_name = "Starting Tools" + +class RemoteItems(Choice): + """ + Determines if items can be placed on locations in your own world in such a way that will force them to be remote items. + + Off: When your items are placed in your world, they can only be placed in locations that they can be acquired without server connection (stats on levels, items in chests, etc). + + Allow: When your items are placed in your world, items that normally can't be placed in a location in-game are simply made remote (abilities on static events, etc). + + Full: All items are remote. Use this when doing something like a co-op seed. + """ + display_name = "Remote Items" + option_off = 0 + option_allow = 1 + option_full = 2 + default = 0 + +class Slot2LevelChecks(Range): + """ + Determines how many levels have an additional item. Usually, this item is an ability. + + If Remote Items is OFF, these checks will only contain abilities. + """ + display_name = "Slot 2 Level Checks" + default = 0 + range_start = 0 + range_end = 33 + +class ShortenGoMode(DefaultOnToggle): + """ + If on, the player warps to the final cutscene after defeating Ansem 1 > Darkside > Ansem 2, skipping World of Chaos. + """ + display_name = "Shorten Go Mode" + +class DestinyIslands(Toggle): + """ + If on, Adds a Destiny Islands item and a number of Raft Materials items to the pool. + + When "Destiny Islands" is found, Traverse Town will have an additional place to land - Seashore. + + "Raft Materials" allow progress into Day 2 and to Homecoming. The amount is defined in Day 2 Materials and Homecoming Materials. + """ + display_name = "Destiny Islands" + +class MythrilInPool(Range): + """ + Determines how much Mythril, one of the two synthesis items, is in the item pool. + + You need 16 to synth every recipe that requires it. + """ + display_name = "Mythril In Pool" + default = 20 + range_start = 16 + range_end = 30 + +class OrichalcumInPool(Range): + """ + Determines how much Orichalcum, one of the two synthesis items, is in the item pool. + + You need 17 to synth every recipe that requires it. + """ + display_name = "Mythril In Pool" + default = 20 + range_start = 17 + range_end = 30 + +class MythrilPrice(Range): + """ + Determines the cost of Mythril in each shop. + """ + display_name = "Mythril Price" + default = 500 + range_start = 100 + range_end = 5000 + +class OrichalcumPrice(Range): + """ + Determines the cost of Orichalcum in each shop. + """ + display_name = "Orichalcum Price" + default = 500 + range_start = 100 + range_end = 5000 + +class OneHP(Toggle): + """ + If on, forces Sora's max HP to 1 and removes the low health warning sound. + """ + display_name = "One HP" + +class FourByThree(Toggle): + """ + If on, changes the aspect ratio to 4 by 3. + """ + display_name = "4 by 3" + +class AutoAttack(Toggle): + """ + If on, you can combo by holding confirm. + """ + display_name = "Auto Attack" + +class BeepHack(Toggle): + """ + If on, removes low health warning sound. Works up to max health of 41. + """ + display_name = "Beep Hack" + +class ConsistentFinishers(Toggle): + """ + If on, 30% chance finishers are now 100% chance. + """ + display_name = "Consistent Finishers" + +class EarlySkip(DefaultOnToggle): + """ + If on, allows skipping cutscenes immediately that normally take time to be able to skip. + """ + display_name = "Early Skip" + +class FastCamera(Toggle): + """ + If on, speeds up camera movement and camera centering. + """ + display_name = "Fast Camera" + +class FasterAnimations(DefaultOnToggle): + """ + If on, speeds up animations during which you can't play. + """ + display_name = "Faster Animations" + +class Unlock0Volume(Toggle): + """ + If on, volume 1 mutes the audio channel. + """ + display_name = "Unlock 0 Volume" + +class Unskippable(DefaultOnToggle): + """ + If on, makes unskippable cutscenes skippable. + """ + display_name = "Unskippable" + +class AutoSave(DefaultOnToggle): + """ + If on, enables auto saving. + + Press L1+L2+R1+R2+D-Pad Left to instantly load continue state. + + Press L1+L2+R1+R2+D-Pad Right to instantly load autosave. + """ + display_name = "AutoSave" + +class WarpAnywhere(Toggle): + """ + If on, enables the player to warp at any time, even when not at a save point. + + Press L1+L2+R2+Select to open the Save/Warp menu at any time. + """ + display_name = "WarpAnywhere" + +class RandomizePartyMemberStartingAccessories(DefaultOnToggle): + """ + If on, the 10 accessories that some party members (Aladdin, Ariel, Jack, Peter Pan, Beast) start with are randomized. + + 10 random accessories will be distributed amongst any party member aside from Sora in their starting equipment. + """ + display_name = "Randomize Party Member Starting Accessories" + +class MaxLevelForSlot2LevelChecks(Range): + """ + Determines the max level for slot 2 level checks. + """ + display_name = "Max Level for Slot 2 Level Checks" + default = 50 + range_start = 2 + range_end = 100 + +class RandomizeAPCosts(Choice): + """ + Off: No randomization + Shuffle: Ability AP Costs will be shuffled amongst themselves. + + Randomize: Ability AP Costs will be randomized to the specified max and min. + + Distribute: Ability AP Costs will totalled and re-distributed randomly between the specified max and min. + """ + display_name = "Randomize AP Costs" + option_off = 0 + option_shuffle = 1 + option_randomize = 2 + option_distribute = 3 + default = 0 + +class MaxAPCost(Range): + """ + If Randomize AP Costs is set to Randomize or Distribute, this defined the max AP cost an ability can have. + """ + display_name = "Max AP Cost" + default = 5 + range_start = 4 + range_end = 9 + +class MinAPCost(Range): + """ + If Randomize AP Costs is set to Randomize or Distribute, this defined the min AP cost an ability can have. + """ + display_name = "Min AP Cost" + default = 0 + range_start = 0 + range_end = 2 + +class Day2Materials(Range): + """ + The amount of Raft Materials required to access Day 2. + """ + display_name = "Day 2 Materials" + default = 4 + range_start = 0 + range_end = 20 + +class HomecomingMaterials(Range): + """ + The amount of Raft Materials required to access Homecoming. + """ + display_name = "Homecoming Materials" + default = 10 + range_start = 0 + range_end = 20 + +class MaterialsInPool(Range): + """ + The amount of Raft Materials required to access Homecoming. + """ + display_name = "Materials in Pool" + default = 16 + range_start = 0 + range_end = 20 + +class StackingWorldItems(DefaultOnToggle): + """ + Multiple world items give you the world's associated key item. + + WL - Footprints + + OC - Entry Pass + + DJ - Slides + + HT - Forget-Me-Not and Jack-In-The-Box + + HB - Theon Vol. 6 + + Adds an extra world to the pool for each that has a key item (WL, OC, DJ, HT, HB). + + Forces Halloween Town Key Item Bundle ON. + """ + display_name = "Stacking World Items" + +class HalloweenTownKeyItemBundle(DefaultOnToggle): + """ + Obtaining the Forget-Me-Not automatically gives Jack-in-the-Box as well. + + Removes Jack-in-the-Box from the pool. + """ + display_name = "Halloween Town Key Item Bundle" @dataclass class KH1Options(PerGameCommonOptions): - goal: Goal + final_rest_door_key: FinalRestDoorKey end_of_the_world_unlock: EndoftheWorldUnlock - final_rest_door: FinalRestDoor - required_reports_eotw: RequiredReportsEotW - required_reports_door: RequiredReportsDoor - reports_in_pool: ReportsInPool + required_lucky_emblems_eotw: RequiredLuckyEmblemsEotW + required_lucky_emblems_door: RequiredLuckyEmblemsDoor + lucky_emblems_in_pool: LuckyEmblemsInPool + required_postcards: RequiredPostcards + required_puppies: RequiredPuppies super_bosses: SuperBosses atlantica: Atlantica hundred_acre_wood: HundredAcreWood cups: Cups - puppies: Puppies + randomize_puppies: RandomizePuppies + puppy_value: PuppyValue starting_worlds: StartingWorlds keyblades_unlock_chests: KeybladesUnlockChests interact_in_battle: InteractInBattle exp_multiplier: EXPMultiplier - advanced_logic: AdvancedLogic + logic_difficulty: LogicDifficulty extra_shared_abilities: ExtraSharedAbilities exp_zero_in_pool: EXPZeroInPool - vanilla_emblem_pieces: VanillaEmblemPieces + randomize_emblem_pieces: RandomizeEmblemPieces + randomize_postcards: RandomizePostcards donald_death_link: DonaldDeathLink goofy_death_link: GoofyDeathLink - randomize_keyblade_stats: RandomizeKeybladeStats + keyblade_stats: KeybladeStats bad_starting_weapons: BadStartingWeapons keyblade_min_str: KeybladeMinStrength keyblade_max_str: KeybladeMaxStrength + keyblade_min_crit_rate: KeybladeMinCritRateBonus + keyblade_max_crit_rate: KeybladeMaxCritRateBonus + keyblade_min_crit_str: KeybladeMinCritSTRBonus + keyblade_max_crit_str: KeybladeMaxCritSTRBonus + keyblade_min_recoil: KeybladeMinRecoil + keyblade_max_recoil: KeybladeMaxRecoil keyblade_min_mp: KeybladeMinMP keyblade_max_mp: KeybladeMaxMP level_checks: LevelChecks + slot_2_level_checks: Slot2LevelChecks force_stats_on_levels: ForceStatsOnLevels strength_increase: StrengthIncrease defense_increase: DefenseIncrease @@ -394,26 +845,68 @@ class KH1Options(PerGameCommonOptions): accessory_slot_increase: AccessorySlotIncrease item_slot_increase: ItemSlotIncrease start_inventory_from_pool: StartInventoryPool + jungle_slider: JungleSlider + starting_tools: StartingTools + remote_items: RemoteItems + shorten_go_mode: ShortenGoMode + death_link: DeathLink + destiny_islands: DestinyIslands + orichalcum_in_pool: OrichalcumInPool + orichalcum_price: OrichalcumPrice + mythril_in_pool: MythrilInPool + mythril_price: MythrilPrice + one_hp: OneHP + four_by_three: FourByThree + auto_attack: AutoAttack + beep_hack: BeepHack + consistent_finishers: ConsistentFinishers + early_skip: EarlySkip + fast_camera: FastCamera + faster_animations: FasterAnimations + unlock_0_volume: Unlock0Volume + unskippable: Unskippable + auto_save: AutoSave + warp_anywhere: WarpAnywhere + randomize_party_member_starting_accessories: RandomizePartyMemberStartingAccessories + max_level_for_slot_2_level_checks: MaxLevelForSlot2LevelChecks + randomize_ap_costs: RandomizeAPCosts + max_ap_cost: MaxAPCost + min_ap_cost: MinAPCost + day_2_materials: Day2Materials + homecoming_materials: HomecomingMaterials + materials_in_pool: MaterialsInPool + stacking_world_items: StackingWorldItems + halloween_town_key_item_bundle: HalloweenTownKeyItemBundle + kh1_option_groups = [ OptionGroup("Goal", [ - Goal, + FinalRestDoorKey, EndoftheWorldUnlock, - FinalRestDoor, - RequiredReportsDoor, - RequiredReportsEotW, - ReportsInPool, + RequiredLuckyEmblemsDoor, + RequiredLuckyEmblemsEotW, + LuckyEmblemsInPool, + RequiredPostcards, + RequiredPuppies, + DestinyIslands, + Day2Materials, + HomecomingMaterials, + MaterialsInPool, ]), OptionGroup("Locations", [ SuperBosses, Atlantica, Cups, HundredAcreWood, - VanillaEmblemPieces, + JungleSlider, + RandomizeEmblemPieces, + RandomizePostcards, ]), OptionGroup("Levels", [ EXPMultiplier, LevelChecks, + Slot2LevelChecks, + MaxLevelForSlot2LevelChecks, ForceStatsOnLevels, StrengthIncrease, DefenseIncrease, @@ -425,21 +918,58 @@ class KH1Options(PerGameCommonOptions): ]), OptionGroup("Keyblades", [ KeybladesUnlockChests, - RandomizeKeybladeStats, + KeybladeStats, BadStartingWeapons, - KeybladeMaxStrength, KeybladeMinStrength, - KeybladeMaxMP, + KeybladeMaxStrength, + KeybladeMinCritRateBonus, + KeybladeMaxCritRateBonus, + KeybladeMinCritSTRBonus, + KeybladeMaxCritSTRBonus, + KeybladeMinRecoil, + KeybladeMaxRecoil, KeybladeMinMP, + KeybladeMaxMP, + ]), + OptionGroup("Synth", [ + OrichalcumInPool, + OrichalcumPrice, + MythrilInPool, + MythrilPrice, + ]), + OptionGroup("AP Costs", [ + RandomizeAPCosts, + MaxAPCost, + MinAPCost ]), OptionGroup("Misc", [ StartingWorlds, - Puppies, + StartingTools, + RandomizePuppies, + PuppyValue, InteractInBattle, - AdvancedLogic, + LogicDifficulty, ExtraSharedAbilities, + StackingWorldItems, + HalloweenTownKeyItemBundle, EXPZeroInPool, + RandomizePartyMemberStartingAccessories, + DeathLink, DonaldDeathLink, GoofyDeathLink, + RemoteItems, + ShortenGoMode, + OneHP, + FourByThree, + AutoAttack, + BeepHack, + ConsistentFinishers, + EarlySkip, + FastCamera, + FasterAnimations, + Unlock0Volume, + Unskippable, + AutoSave, + WarpAnywhere ]) ] diff --git a/worlds/kh1/Presets.py b/worlds/kh1/Presets.py index 77b43b7624b9..33949a24e018 100644 --- a/worlds/kh1/Presets.py +++ b/worlds/kh1/Presets.py @@ -3,24 +3,33 @@ from .Options import * kh1_option_presets: Dict[str, Dict[str, Any]] = { - # Standard playthrough where your goal is to defeat Ansem, reaching him by acquiring enough reports. + # Standard playthrough where your goal is to defeat Ansem, reaching him by acquiring enough lucky emblems. "Final Ansem": { - "goal": Goal.option_final_ansem, - "end_of_the_world_unlock": EndoftheWorldUnlock.option_reports, - "final_rest_door": FinalRestDoor.option_reports, - "required_reports_eotw": 7, - "required_reports_door": 10, - "reports_in_pool": 13, + "final_rest_door_key": FinalRestDoorKey.option_lucky_emblems, + "end_of_the_world_unlock": EndoftheWorldUnlock.option_lucky_emblems, + "required_lucky_emblems_eotw": 7, + "required_lucky_emblems_door": 10, + "lucky_emblems_in_pool": 13, + "required_postcards": 10, + "required_puppies": 99, + "destiny_islands": True, + "day_2_materials": 4, + "homecoming_materials": 10, + "materials_in_pool": 13, "super_bosses": False, "atlantica": False, "hundred_acre_wood": False, - "cups": False, - "vanilla_emblem_pieces": True, + "cups": Cups.option_off, + "jungle_slider": False, + "randomize_emblem_pieces": False, + "randomize_postcards": RandomizePostcards.option_all, - "exp_multiplier": 48, - "level_checks": 100, - "force_stats_on_levels": 1, + "exp_multiplier": 64, + "level_checks": 99, + "slot_2_level_checks": 33, + "max_level_for_slot_2_level_checks": 50, + "force_stats_on_levels": 2, "strength_increase": 24, "defense_increase": 24, "hp_increase": 23, @@ -30,40 +39,83 @@ "item_slot_increase": 3, "keyblades_unlock_chests": False, - "randomize_keyblade_stats": True, + "keyblade_stats": KeybladeStats.option_shuffle, "bad_starting_weapons": False, "keyblade_max_str": 14, "keyblade_min_str": 3, + "keyblade_max_crit_rate": 200, + "keyblade_min_crit_rate": 0, + "keyblade_max_crit_str": 16, + "keyblade_min_crit_str": 0, + "keyblade_max_recoil": 90, + "keyblade_min_recoil": 1, "keyblade_max_mp": 3, "keyblade_min_mp": -2, - "puppies": Puppies.option_triplets, - "starting_worlds": 0, - "interact_in_battle": False, - "advanced_logic": False, - "extra_shared_abilities": False, + "orichalcum_in_pool": 20, + "orichalcum_price": 500, + "mythril_in_pool": 20, + "mythril_price": 500, + + "randomize_ap_costs": RandomizeAPCosts.option_off, + "max_ap_cost": 5, + "min_ap_cost": 0, + + "randomize_puppies": True, + "puppy_value": 3, + "starting_worlds": 4, + "starting_tools": True, + "interact_in_battle": True, + "logic_difficulty": LogicDifficulty.option_normal, + "extra_shared_abilities": True, + "stacking_world_items": True, + "halloween_town_key_item_bundle": True, "exp_zero_in_pool": False, + "randomize_party_member_starting_accessories": True, + "death_link": False, "donald_death_link": False, - "goofy_death_link": False + "goofy_death_link": False, + "remote_items": RemoteItems.option_off, + "shorten_go_mode": True, + "one_hp": False, + "four_by_three": False, + "beep_hack": False, + "consistent_finishers": False, + "early_skip": True, + "fast_camera": False, + "faster_animations": True, + "unlock_0_volume": False, + "unskippable": True, + "auto_save": True, + "warp_anywhere": False }, # Puppies are found individually, and the goal is to return them all. "Puppy Hunt": { - "goal": Goal.option_puppies, + "final_rest_door_key": FinalRestDoorKey.option_puppies, "end_of_the_world_unlock": EndoftheWorldUnlock.option_item, - "final_rest_door": FinalRestDoor.option_puppies, - "required_reports_eotw": 13, - "required_reports_door": 13, - "reports_in_pool": 13, + "required_lucky_emblems_eotw": 13, + "required_lucky_emblems_door": 13, + "lucky_emblems_in_pool": 13, + "required_postcards": 10, + "required_puppies": 99, + "destiny_islands": False, + "day_2_materials": 4, + "homecoming_materials": 10, + "materials_in_pool": 13, "super_bosses": False, "atlantica": False, "hundred_acre_wood": False, - "cups": False, - "vanilla_emblem_pieces": True, + "cups": Cups.option_off, + "jungle_slider": False, + "randomize_emblem_pieces": False, + "randomize_postcards": RandomizePostcards.option_all, - "exp_multiplier": 48, - "level_checks": 100, - "force_stats_on_levels": 1, + "exp_multiplier": 64, + "level_checks": 99, + "slot_2_level_checks": 33, + "max_level_for_slot_2_level_checks": 50, + "force_stats_on_levels": 2, "strength_increase": 24, "defense_increase": 24, "hp_increase": 23, @@ -73,40 +125,83 @@ "item_slot_increase": 3, "keyblades_unlock_chests": False, - "randomize_keyblade_stats": True, + "keyblade_stats": KeybladeStats.option_shuffle, "bad_starting_weapons": False, "keyblade_max_str": 14, "keyblade_min_str": 3, + "keyblade_max_crit_rate": 200, + "keyblade_min_crit_rate": 0, + "keyblade_max_crit_str": 16, + "keyblade_min_crit_str": 0, + "keyblade_max_recoil": 90, + "keyblade_min_recoil": 1, "keyblade_max_mp": 3, "keyblade_min_mp": -2, - "puppies": Puppies.option_individual, + "orichalcum_in_pool": 20, + "orichalcum_price": 500, + "mythril_in_pool": 20, + "mythril_price": 500, + + "randomize_ap_costs": RandomizeAPCosts.option_off, + "max_ap_cost": 5, + "min_ap_cost": 0, + + "randomize_puppies": True, + "puppy_value": 1, "starting_worlds": 0, - "interact_in_battle": False, - "advanced_logic": False, - "extra_shared_abilities": False, + "starting_tools": True, + "interact_in_battle": True, + "logic_difficulty": LogicDifficulty.option_normal, + "extra_shared_abilities": True, + "stacking_world_items": True, + "halloween_town_key_item_bundle": True, "exp_zero_in_pool": False, + "randomize_party_member_starting_accessories": True, + "death_link": False, "donald_death_link": False, - "goofy_death_link": False + "goofy_death_link": False, + "remote_items": RemoteItems.option_off, + "shorten_go_mode": True, + "one_hp": False, + "four_by_three": False, + "beep_hack": False, + "consistent_finishers": False, + "early_skip": True, + "fast_camera": False, + "faster_animations": True, + "unlock_0_volume": False, + "unskippable": True, + "auto_save": True, + "warp_anywhere": False }, # Advanced playthrough with most settings on. "Advanced": { - "goal": Goal.option_final_ansem, - "end_of_the_world_unlock": EndoftheWorldUnlock.option_reports, - "final_rest_door": FinalRestDoor.option_reports, - "required_reports_eotw": 7, - "required_reports_door": 10, - "reports_in_pool": 13, + "final_rest_door_key": FinalRestDoorKey.option_lucky_emblems, + "end_of_the_world_unlock": EndoftheWorldUnlock.option_lucky_emblems, + "required_lucky_emblems_eotw": 7, + "required_lucky_emblems_door": 10, + "lucky_emblems_in_pool": 13, + "required_postcards": 10, + "required_puppies": 99, + "destiny_islands": True, + "day_2_materials": 4, + "homecoming_materials": 10, + "materials_in_pool": 13, "super_bosses": True, "atlantica": True, "hundred_acre_wood": True, - "cups": True, - "vanilla_emblem_pieces": False, + "cups": Cups.option_off, + "jungle_slider": True, + "randomize_emblem_pieces": True, + "randomize_postcards": RandomizePostcards.option_all, - "exp_multiplier": 48, - "level_checks": 100, - "force_stats_on_levels": 1, + "exp_multiplier": 64, + "level_checks": 99, + "slot_2_level_checks": 33, + "max_level_for_slot_2_level_checks": 50, + "force_stats_on_levels": 2, "strength_increase": 24, "defense_increase": 24, "hp_increase": 23, @@ -116,40 +211,83 @@ "item_slot_increase": 3, "keyblades_unlock_chests": True, - "randomize_keyblade_stats": True, + "keyblade_stats": KeybladeStats.option_shuffle, "bad_starting_weapons": True, "keyblade_max_str": 14, "keyblade_min_str": 3, + "keyblade_max_crit_rate": 200, + "keyblade_min_crit_rate": 0, + "keyblade_max_crit_str": 16, + "keyblade_min_crit_str": 0, + "keyblade_max_recoil": 90, + "keyblade_min_recoil": 1, "keyblade_max_mp": 3, "keyblade_min_mp": -2, - "puppies": Puppies.option_triplets, + "orichalcum_in_pool": 20, + "orichalcum_price": 500, + "mythril_in_pool": 20, + "mythril_price": 500, + + "randomize_ap_costs": RandomizeAPCosts.option_off, + "max_ap_cost": 5, + "min_ap_cost": 0, + + "randomize_puppies": True, + "puppy_value": 3, "starting_worlds": 0, + "starting_tools": True, "interact_in_battle": True, - "advanced_logic": True, + "logic_difficulty": LogicDifficulty.option_proud, "extra_shared_abilities": True, + "stacking_world_items": True, + "halloween_town_key_item_bundle": True, "exp_zero_in_pool": True, + "randomize_party_member_starting_accessories": True, + "death_link": False, "donald_death_link": False, - "goofy_death_link": False + "goofy_death_link": False, + "remote_items": RemoteItems.option_off, + "shorten_go_mode": True, + "one_hp": False, + "four_by_three": False, + "beep_hack": False, + "consistent_finishers": False, + "early_skip": True, + "fast_camera": False, + "faster_animations": True, + "unlock_0_volume": False, + "unskippable": True, + "auto_save": True, + "warp_anywhere": False }, # Playthrough meant to enhance the level 1 experience. "Level 1": { - "goal": Goal.option_final_ansem, - "end_of_the_world_unlock": EndoftheWorldUnlock.option_reports, - "final_rest_door": FinalRestDoor.option_reports, - "required_reports_eotw": 7, - "required_reports_door": 10, - "reports_in_pool": 13, + "final_rest_door_key": FinalRestDoorKey.option_lucky_emblems, + "end_of_the_world_unlock": EndoftheWorldUnlock.option_lucky_emblems, + "required_lucky_emblems_eotw": 7, + "required_lucky_emblems_door": 10, + "lucky_emblems_in_pool": 13, + "required_postcards": 10, + "required_puppies": 99, + "destiny_islands": True, + "day_2_materials": 4, + "homecoming_materials": 10, + "materials_in_pool": 13, "super_bosses": False, "atlantica": False, "hundred_acre_wood": False, - "cups": False, - "vanilla_emblem_pieces": True, + "cups": Cups.option_off, + "jungle_slider": False, + "randomize_emblem_pieces": False, + "randomize_postcards": RandomizePostcards.option_all, "exp_multiplier": 16, "level_checks": 0, - "force_stats_on_levels": 101, + "slot_2_level_checks": 0, + "max_level_for_slot_2_level_checks": 50, + "force_stats_on_levels": 2, "strength_increase": 0, "defense_increase": 0, "hp_increase": 0, @@ -158,20 +296,54 @@ "item_slot_increase": 5, "keyblades_unlock_chests": False, - "randomize_keyblade_stats": True, + "keyblade_stats": KeybladeStats.option_shuffle, "bad_starting_weapons": False, "keyblade_max_str": 14, "keyblade_min_str": 3, + "keyblade_max_crit_rate": 200, + "keyblade_min_crit_rate": 0, + "keyblade_max_crit_str": 16, + "keyblade_min_crit_str": 0, + "keyblade_max_recoil": 90, + "keyblade_min_recoil": 1, "keyblade_max_mp": 3, "keyblade_min_mp": -2, - "puppies": Puppies.option_triplets, + "orichalcum_in_pool": 20, + "orichalcum_price": 500, + "mythril_in_pool": 20, + "mythril_price": 500, + + "randomize_ap_costs": RandomizeAPCosts.option_off, + "max_ap_cost": 5, + "min_ap_cost": 0, + + "randomize_puppies": True, + "puppy_value": 3, "starting_worlds": 0, - "interact_in_battle": False, - "advanced_logic": False, - "extra_shared_abilities": False, + "starting_tools": True, + "interact_in_battle": True, + "logic_difficulty": LogicDifficulty.option_normal, + "extra_shared_abilities": True, + "stacking_world_items": True, + "halloween_town_key_item_bundle": True, "exp_zero_in_pool": False, + "randomize_party_member_starting_accessories": True, + "death_link": False, "donald_death_link": False, - "goofy_death_link": False + "goofy_death_link": False, + "remote_items": RemoteItems.option_off, + "shorten_go_mode": True, + "one_hp": False, + "four_by_three": False, + "beep_hack": False, + "consistent_finishers": True, + "early_skip": True, + "fast_camera": False, + "faster_animations": True, + "unlock_0_volume": False, + "unskippable": True, + "auto_save": True, + "warp_anywhere": False } } diff --git a/worlds/kh1/Regions.py b/worlds/kh1/Regions.py index 6189adf2072c..ac622ce08133 100644 --- a/worlds/kh1/Regions.py +++ b/worlds/kh1/Regions.py @@ -9,12 +9,16 @@ class KH1RegionData(NamedTuple): region_exits: Optional[List[str]] -def create_regions(multiworld: MultiWorld, player: int, options): +def create_regions(kh1world): + multiworld = kh1world.multiworld + player = kh1world.player + options = kh1world.options + regions: Dict[str, KH1RegionData] = { - "Menu": KH1RegionData([], ["Awakening", "Levels"]), - "Awakening": KH1RegionData([], ["Destiny Islands"]), - "Destiny Islands": KH1RegionData([], ["Traverse Town"]), - "Traverse Town": KH1RegionData([], ["World Map"]), + "Menu": KH1RegionData([], ["Awakening", "Levels", "World Map"]), + "Awakening": KH1RegionData([], []), + "Destiny Islands": KH1RegionData([], []), + "Traverse Town": KH1RegionData([], []), "Wonderland": KH1RegionData([], []), "Olympus Coliseum": KH1RegionData([], []), "Deep Jungle": KH1RegionData([], []), @@ -27,17 +31,27 @@ def create_regions(multiworld: MultiWorld, player: int, options): "End of the World": KH1RegionData([], []), "100 Acre Wood": KH1RegionData([], []), "Levels": KH1RegionData([], []), - "World Map": KH1RegionData([], ["Wonderland", "Olympus Coliseum", "Deep Jungle", + "Homecoming": KH1RegionData([], []), + "World Map": KH1RegionData([], ["Destiny Islands", "Traverse Town", + "Wonderland", "Olympus Coliseum", "Deep Jungle", "Agrabah", "Monstro", "Atlantica", "Halloween Town", "Neverland", "Hollow Bastion", - "End of the World", "100 Acre Wood"]) + "End of the World", "100 Acre Wood", "Homecoming"]) } + + if not options.atlantica: + del regions["Atlantica"] + regions["World Map"].region_exits.remove("Atlantica") + if not options.destiny_islands: + del regions["Destiny Islands"] + regions["World Map"].region_exits.remove("Destiny Islands") # Set up locations regions["Agrabah"].locations.append("Agrabah Aladdin's House Main Street Entrance Chest") regions["Agrabah"].locations.append("Agrabah Aladdin's House Plaza Entrance Chest") regions["Agrabah"].locations.append("Agrabah Alley Chest") regions["Agrabah"].locations.append("Agrabah Bazaar Across Windows Chest") + regions["Agrabah"].locations.append("Agrabah Bazaar Blue Trinity") regions["Agrabah"].locations.append("Agrabah Bazaar High Corner Chest") regions["Agrabah"].locations.append("Agrabah Cave of Wonders Bottomless Hall Across Chasm Chest") regions["Agrabah"].locations.append("Agrabah Cave of Wonders Bottomless Hall Pillar Chest") @@ -59,6 +73,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Agrabah"].locations.append("Agrabah Cave of Wonders Treasure Room Above Fire Chest") regions["Agrabah"].locations.append("Agrabah Cave of Wonders Treasure Room Across Platforms Chest") regions["Agrabah"].locations.append("Agrabah Cave of Wonders Treasure Room Large Treasure Pile Chest") + regions["Agrabah"].locations.append("Agrabah Cave of Wonders Treasure Room Red Trinity") regions["Agrabah"].locations.append("Agrabah Cave of Wonders Treasure Room Small Treasure Pile Chest") regions["Agrabah"].locations.append("Agrabah Defeat Jafar Blizzard Event") regions["Agrabah"].locations.append("Agrabah Defeat Jafar Genie Ansem's Report 1") @@ -96,15 +111,11 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Deep Jungle"].locations.append("Deep Jungle Hippo's Lagoon Center Chest") regions["Deep Jungle"].locations.append("Deep Jungle Hippo's Lagoon Left Chest") regions["Deep Jungle"].locations.append("Deep Jungle Hippo's Lagoon Right Chest") - regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 10 Fruits") - regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 20 Fruits") - regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 30 Fruits") - regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 40 Fruits") - regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 50 Fruits") regions["Deep Jungle"].locations.append("Deep Jungle Seal Keyhole Jungle King Event") regions["Deep Jungle"].locations.append("Deep Jungle Seal Keyhole Red Trinity Event") regions["Deep Jungle"].locations.append("Deep Jungle Tent Chest") regions["Deep Jungle"].locations.append("Deep Jungle Tent Protect-G Event") + regions["Deep Jungle"].locations.append("Deep Jungle Treetop Green Trinity") regions["Deep Jungle"].locations.append("Deep Jungle Tree House Beneath Tree House Chest") regions["Deep Jungle"].locations.append("Deep Jungle Tree House Rooftop Chest") regions["Deep Jungle"].locations.append("Deep Jungle Tree House Save Gorillas") @@ -138,7 +149,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["End of the World"].locations.append("End of the World World Terminus Atlantica Chest") regions["End of the World"].locations.append("End of the World World Terminus Deep Jungle Chest") regions["End of the World"].locations.append("End of the World World Terminus Halloween Town Chest") - #regions["End of the World"].locations.append("End of the World World Terminus Hollow Bastion Chest") + regions["End of the World"].locations.append("End of the World World Terminus Hollow Bastion Chest") regions["End of the World"].locations.append("End of the World World Terminus Neverland Chest") regions["End of the World"].locations.append("End of the World World Terminus Olympus Coliseum Chest") regions["End of the World"].locations.append("End of the World World Terminus Traverse Town Chest") @@ -181,6 +192,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Maleficent Donald Cheer Event") regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Riku I White Trinity Event") regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Riku II Ragnarok Event") + regions["Hollow Bastion"].locations.append("Hollow Bastion Dungeon Blue Trinity") regions["Hollow Bastion"].locations.append("Hollow Bastion Dungeon By Candles Chest") regions["Hollow Bastion"].locations.append("Hollow Bastion Dungeon Corner Chest") regions["Hollow Bastion"].locations.append("Hollow Bastion Entrance Hall Emblem Piece (Chest)") @@ -192,6 +204,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Hollow Bastion"].locations.append("Hollow Bastion Grand Hall Oblivion Chest") regions["Hollow Bastion"].locations.append("Hollow Bastion Grand Hall Steps Right Side Chest") regions["Hollow Bastion"].locations.append("Hollow Bastion Great Crest After Battle Platform Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Great Crest Blue Trinity") regions["Hollow Bastion"].locations.append("Hollow Bastion Great Crest Lower Chest") regions["Hollow Bastion"].locations.append("Hollow Bastion High Tower 1st Gravity Chest") regions["Hollow Bastion"].locations.append("Hollow Bastion High Tower 2nd Gravity Chest") @@ -203,6 +216,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Hollow Bastion"].locations.append("Hollow Bastion Library Speak to Belle Divine Rose") regions["Hollow Bastion"].locations.append("Hollow Bastion Library Top of Bookshelf Chest") regions["Hollow Bastion"].locations.append("Hollow Bastion Library Top of Bookshelf Turn the Carousel Chest") + regions["Hollow Bastion"].locations.append("Hollow Bastion Lift Stop from Waterway Examine Node") regions["Hollow Bastion"].locations.append("Hollow Bastion Lift Stop Heartless Sigil Door Gravity Chest") regions["Hollow Bastion"].locations.append("Hollow Bastion Lift Stop Library Node After High Tower Switch Gravity Chest") regions["Hollow Bastion"].locations.append("Hollow Bastion Lift Stop Library Node Gravity Chest") @@ -230,6 +244,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Monstro"].locations.append("Monstro Chamber 3 Platform Above Chamber 2 Entrance Chest") regions["Monstro"].locations.append("Monstro Chamber 3 Platform Near Chamber 6 Entrance Chest") regions["Monstro"].locations.append("Monstro Chamber 5 Atop Barrel Chest") + regions["Monstro"].locations.append("Monstro Chamber 5 Blue Trinity") regions["Monstro"].locations.append("Monstro Chamber 5 Low 1st Chest") regions["Monstro"].locations.append("Monstro Chamber 5 Low 2nd Chest") regions["Monstro"].locations.append("Monstro Chamber 5 Platform Chest") @@ -240,26 +255,28 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Monstro"].locations.append("Monstro Chamber 6 White Trinity Chest") regions["Monstro"].locations.append("Monstro Defeat Parasite Cage I Goofy Cheer Event") regions["Monstro"].locations.append("Monstro Defeat Parasite Cage II Stop Event") + regions["Monstro"].locations.append("Monstro Mouth Blue Trinity") regions["Monstro"].locations.append("Monstro Mouth Boat Deck Chest") regions["Monstro"].locations.append("Monstro Mouth Green Trinity Top of Boat Chest") regions["Monstro"].locations.append("Monstro Mouth High Platform Across from Boat Chest") regions["Monstro"].locations.append("Monstro Mouth High Platform Boat Side Chest") regions["Monstro"].locations.append("Monstro Mouth High Platform Near Teeth Chest") regions["Monstro"].locations.append("Monstro Mouth Near Ship Chest") + regions["Monstro"].locations.append("Monstro Throat Blue Trinity") regions["Neverland"].locations.append("Neverland Cabin Chest") regions["Neverland"].locations.append("Neverland Captain's Cabin Chest") - #regions["Neverland"].locations.append("Neverland Clock Tower 01:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 02:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 03:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 04:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 05:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 06:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 07:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 08:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 09:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 10:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 11:00 Door") - #regions["Neverland"].locations.append("Neverland Clock Tower 12:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 01:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 02:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 03:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 04:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 05:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 06:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 07:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 08:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 09:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 10:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 11:00 Door") + regions["Neverland"].locations.append("Neverland Clock Tower 12:00 Door") regions["Neverland"].locations.append("Neverland Clock Tower Chest") regions["Neverland"].locations.append("Neverland Defeat Anti Sora Raven's Claw Event") regions["Neverland"].locations.append("Neverland Defeat Captain Hook Ars Arcanum Event") @@ -276,6 +293,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Neverland"].locations.append("Neverland Pirate Ship Deck White Trinity Chest") regions["Neverland"].locations.append("Neverland Seal Keyhole Fairy Harp Event") regions["Neverland"].locations.append("Neverland Seal Keyhole Glide Event") + regions["Neverland"].locations.append("Neverland Seal Keyhole Navi-G Piece Event") regions["Neverland"].locations.append("Neverland Seal Keyhole Tinker Bell Event") regions["Olympus Coliseum"].locations.append("Olympus Coliseum Clear Phil's Training Thunder Event") regions["Olympus Coliseum"].locations.append("Olympus Coliseum Cloud Sonic Blade Event") @@ -292,14 +310,16 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Traverse Town"].locations.append("Traverse Town 1st District Accessory Shop Roof Chest") #regions["Traverse Town"].locations.append("Traverse Town 1st District Aerith Gift") regions["Traverse Town"].locations.append("Traverse Town 1st District Blue Trinity Balcony Chest") + regions["Traverse Town"].locations.append("Traverse Town 1st District Blue Trinity by Exit Door") regions["Traverse Town"].locations.append("Traverse Town 1st District Candle Puzzle Chest") - #regions["Traverse Town"].locations.append("Traverse Town 1st District Leon Gift") + regions["Traverse Town"].locations.append("Traverse Town 1st District Leon Gift") regions["Traverse Town"].locations.append("Traverse Town 1st District Safe Postcard") - regions["Traverse Town"].locations.append("Traverse Town 1st District Speak with Cid Event") + #regions["Traverse Town"].locations.append("Traverse Town 1st District Speak with Cid Event") regions["Traverse Town"].locations.append("Traverse Town 2nd District Boots and Shoes Awning Chest") regions["Traverse Town"].locations.append("Traverse Town 2nd District Gizmo Shop Facade Chest") regions["Traverse Town"].locations.append("Traverse Town 2nd District Rooftop Chest") regions["Traverse Town"].locations.append("Traverse Town 3rd District Balcony Postcard") + regions["Traverse Town"].locations.append("Traverse Town 3rd District Blue Trinity") regions["Traverse Town"].locations.append("Traverse Town Accessory Shop Chest") regions["Traverse Town"].locations.append("Traverse Town Alleyway Balcony Chest") regions["Traverse Town"].locations.append("Traverse Town Alleyway Behind Crates Chest") @@ -310,6 +330,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Traverse Town"].locations.append("Traverse Town Defeat Guard Armor Dodge Roll Event") regions["Traverse Town"].locations.append("Traverse Town Defeat Guard Armor Fire Event") regions["Traverse Town"].locations.append("Traverse Town Defeat Opposite Armor Aero Event") + regions["Traverse Town"].locations.append("Traverse Town Defeat Opposite Armor Navi-G Piece Event") regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Chest") regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Geppetto All Summons Reward") regions["Traverse Town"].locations.append("Traverse Town Geppetto's House Geppetto Reward 1") @@ -329,6 +350,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Traverse Town"].locations.append("Traverse Town Item Workshop Right Chest") regions["Traverse Town"].locations.append("Traverse Town Kairi Secret Waterway Oathkeeper Event") regions["Traverse Town"].locations.append("Traverse Town Leon Secret Waterway Earthshine Event") + regions["Traverse Town"].locations.append("Traverse Town Magician's Study Blue Trinity") regions["Traverse Town"].locations.append("Traverse Town Magician's Study Obtained All Arts Items") regions["Traverse Town"].locations.append("Traverse Town Magician's Study Obtained All LV1 Magic") regions["Traverse Town"].locations.append("Traverse Town Magician's Study Obtained All LV3 Magic") @@ -357,26 +379,62 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 99 Puppies Reward 1") regions["Traverse Town"].locations.append("Traverse Town Piano Room Return 99 Puppies Reward 2") regions["Traverse Town"].locations.append("Traverse Town Red Room Chest") + regions["Traverse Town"].locations.append("Traverse Town Secret Waterway Navi Gummi Event") regions["Traverse Town"].locations.append("Traverse Town Secret Waterway Near Stairs Chest") regions["Traverse Town"].locations.append("Traverse Town Secret Waterway White Trinity Chest") - regions["Traverse Town"].locations.append("Traverse Town Synth Cloth") - regions["Traverse Town"].locations.append("Traverse Town Synth Fish") - regions["Traverse Town"].locations.append("Traverse Town Synth Log") - regions["Traverse Town"].locations.append("Traverse Town Synth Mushroom") - regions["Traverse Town"].locations.append("Traverse Town Synth Rope") - regions["Traverse Town"].locations.append("Traverse Town Synth Seagull Egg") + regions["Traverse Town"].locations.append("Traverse Town Synth 15 Items") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 01") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 02") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 03") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 04") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 05") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 06") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 07") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 08") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 09") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 10") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 11") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 12") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 13") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 14") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 15") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 16") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 17") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 18") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 19") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 20") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 21") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 22") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 23") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 24") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 25") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 26") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 27") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 28") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 29") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 30") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 31") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 32") + regions["Traverse Town"].locations.append("Traverse Town Synth Item 33") + regions["Wonderland"].locations.append("Wonderland Bizarre Room Examine Flower Pot") regions["Wonderland"].locations.append("Wonderland Bizarre Room Green Trinity Chest") regions["Wonderland"].locations.append("Wonderland Bizarre Room Lamp Chest") regions["Wonderland"].locations.append("Wonderland Bizarre Room Navi-G Piece Event") regions["Wonderland"].locations.append("Wonderland Bizarre Room Read Book") regions["Wonderland"].locations.append("Wonderland Defeat Trickmaster Blizzard Event") regions["Wonderland"].locations.append("Wonderland Defeat Trickmaster Ifrit's Horn Event") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Blue Trinity in Alcove") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Blue Trinity by Moving Boulder") regions["Wonderland"].locations.append("Wonderland Lotus Forest Corner Chest") regions["Wonderland"].locations.append("Wonderland Lotus Forest Glide Chest") regions["Wonderland"].locations.append("Wonderland Lotus Forest Nut Chest") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Red Flower Raise Lily Pads") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Red Flowers on the Main Path") regions["Wonderland"].locations.append("Wonderland Lotus Forest Through the Painting Thunder Plant Chest") regions["Wonderland"].locations.append("Wonderland Lotus Forest Through the Painting White Trinity Chest") regions["Wonderland"].locations.append("Wonderland Lotus Forest Thunder Plant Chest") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Yellow Elixir Flower Through Painting") + regions["Wonderland"].locations.append("Wonderland Lotus Forest Yellow Flowers in Middle Clearing and Through Painting") regions["Wonderland"].locations.append("Wonderland Queen's Castle Hedge Left Red Chest") regions["Wonderland"].locations.append("Wonderland Queen's Castle Hedge Right Blue Chest") regions["Wonderland"].locations.append("Wonderland Queen's Castle Hedge Right Red Chest") @@ -388,6 +446,11 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Wonderland"].locations.append("Wonderland Tea Party Garden Above Lotus Forest Entrance 2nd Chest") regions["Wonderland"].locations.append("Wonderland Tea Party Garden Across From Bizarre Room Entrance Chest") regions["Wonderland"].locations.append("Wonderland Tea Party Garden Bear and Clock Puzzle Chest") + regions["Wonderland"].locations.append("Wonderland Tea Party Garden Left Cushioned Chair") + regions["Wonderland"].locations.append("Wonderland Tea Party Garden Left Gray Chair") + regions["Wonderland"].locations.append("Wonderland Tea Party Garden Left Pink Chair") + regions["Wonderland"].locations.append("Wonderland Tea Party Garden Right Brown Chair") + regions["Wonderland"].locations.append("Wonderland Tea Party Garden Right Yellow Chair") if options.hundred_acre_wood: regions["100 Acre Wood"].locations.append("100 Acre Wood Meadow Inside Log Chest") regions["100 Acre Wood"].locations.append("100 Acre Wood Bouncing Spot Left Cliff Chest") @@ -440,7 +503,7 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Atlantica"].locations.append("Atlantica Undersea Cave Clam") regions["Atlantica"].locations.append("Atlantica Sunken Ship Crystal Trident Event") regions["Atlantica"].locations.append("Atlantica Defeat Ursula II Ansem's Report 3") - if options.cups: + if options.cups.current_key != "off": regions["Olympus Coliseum"].locations.append("Complete Phil Cup") regions["Olympus Coliseum"].locations.append("Complete Phil Cup Solo") regions["Olympus Coliseum"].locations.append("Complete Phil Cup Time Trial") @@ -450,50 +513,84 @@ def create_regions(multiworld: MultiWorld, player: int, options): regions["Olympus Coliseum"].locations.append("Complete Hercules Cup") regions["Olympus Coliseum"].locations.append("Complete Hercules Cup Solo") regions["Olympus Coliseum"].locations.append("Complete Hercules Cup Time Trial") - regions["Olympus Coliseum"].locations.append("Complete Hades Cup") - regions["Olympus Coliseum"].locations.append("Complete Hades Cup Solo") - regions["Olympus Coliseum"].locations.append("Complete Hades Cup Time Trial") - regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Cloud and Leon Event") - regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Yuffie Event") - regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Cerberus Event") - regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Behemoth Event") - regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Hades Event") regions["Olympus Coliseum"].locations.append("Hercules Cup Defeat Cloud Event") regions["Olympus Coliseum"].locations.append("Hercules Cup Yellow Trinity Event") - regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Hades Ansem's Report 8") regions["Olympus Coliseum"].locations.append("Olympus Coliseum Olympia Chest") - regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Ice Titan Diamond Dust Event") - regions["Olympus Coliseum"].locations.append("Olympus Coliseum Gates Purple Jar After Defeating Hades") + if options.cups.current_key == "hades_cup": + regions["Olympus Coliseum"].locations.append("Complete Hades Cup") + regions["Olympus Coliseum"].locations.append("Complete Hades Cup Solo") + regions["Olympus Coliseum"].locations.append("Complete Hades Cup Time Trial") + regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Cloud and Leon Event") + regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Yuffie Event") + regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Cerberus Event") + regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Behemoth Event") + regions["Olympus Coliseum"].locations.append("Hades Cup Defeat Hades Event") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Hades Ansem's Report 8") + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Gates Purple Jar After Defeating Hades") + if options.cups.current_key == "hades_cup" and options.super_bosses: + regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Ice Titan Diamond Dust Event") if options.super_bosses: regions["Neverland"].locations.append("Neverland Defeat Phantom Stop Event") regions["Agrabah"].locations.append("Agrabah Defeat Kurt Zisa Zantetsuken Event") regions["Agrabah"].locations.append("Agrabah Defeat Kurt Zisa Ansem's Report 11") - if options.super_bosses or options.goal.current_key == "sephiroth": + if options.super_bosses or options.final_rest_door_key.current_key == "sephiroth": regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Sephiroth Ansem's Report 12") regions["Olympus Coliseum"].locations.append("Olympus Coliseum Defeat Sephiroth One-Winged Angel Event") - if options.super_bosses or options.goal.current_key == "unknown": + if options.super_bosses or options.final_rest_door_key.current_key == "unknown": regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Unknown Ansem's Report 13") regions["Hollow Bastion"].locations.append("Hollow Bastion Defeat Unknown EXP Necklace Event") - for i in range(options.level_checks): - regions["Levels"].locations.append("Level " + str(i+1).rjust(3, '0')) - if options.goal.current_key == "final_ansem": - regions["End of the World"].locations.append("Final Ansem") + if options.jungle_slider: + regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 10 Fruits") + regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 20 Fruits") + regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 30 Fruits") + regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 40 Fruits") + regions["Deep Jungle"].locations.append("Deep Jungle Jungle Slider 50 Fruits") + for i in range(1,options.level_checks+1): + regions["Levels"].locations.append("Level " + str(i+1).rjust(3, '0') + " (Slot 1)") + if i+1 in kh1world.get_slot_2_levels(): + regions["Levels"].locations.append("Level " + str(i+1).rjust(3, '0') + " (Slot 2)") + if options.destiny_islands: + regions["Destiny Islands"].locations.append("Destiny Islands Seashore Capture Fish 1 (Day 2)") + regions["Destiny Islands"].locations.append("Destiny Islands Seashore Capture Fish 2 (Day 2)") + regions["Destiny Islands"].locations.append("Destiny Islands Seashore Capture Fish 3 (Day 2)") + regions["Destiny Islands"].locations.append("Destiny Islands Seashore Gather Seagull Egg (Day 2)") + regions["Destiny Islands"].locations.append("Destiny Islands Seashore Log on Riku's Island (Day 1)") + regions["Destiny Islands"].locations.append("Destiny Islands Seashore Log under Bridge (Day 1)") + regions["Destiny Islands"].locations.append("Destiny Islands Seashore Gather Cloth (Day 1)") + regions["Destiny Islands"].locations.append("Destiny Islands Seashore Gather Rope (Day 1)") + #regions["Destiny Islands"].locations.append("Destiny Islands Seashore Deliver Kairi Items (Day 1)") + regions["Destiny Islands"].locations.append("Destiny Islands Secret Place Gather Mushroom (Day 2)") + regions["Destiny Islands"].locations.append("Destiny Islands Cove Gather Mushroom Near Zip Line (Day 2)") + regions["Destiny Islands"].locations.append("Destiny Islands Cove Gather Mushroom in Small Cave (Day 2)") + regions["Destiny Islands"].locations.append("Destiny Islands Cove Talk to Kairi (Day 2)") + regions["Destiny Islands"].locations.append("Destiny Islands Gather Drinking Water (Day 2)") + #regions["Destiny Islands"].locations.append("Destiny Islands Cove Deliver Kairi Items (Day 2)") + regions["Destiny Islands"].locations.append("Destiny Islands Chest") + regions["Homecoming"].locations.append("Final Ansem") + + for location in kh1world.get_starting_accessory_locations(): + regions[location_table[location].category].locations.append(location) # Set up the regions correctly. for name, data in regions.items(): multiworld.regions.append(create_region(multiworld, player, name, data)) - -def connect_entrances(multiworld: MultiWorld, player: int): +def connect_entrances(kh1world): + multiworld = kh1world.multiworld + player = kh1world.player + options = kh1world.options + multiworld.get_entrance("Awakening", player).connect(multiworld.get_region("Awakening", player)) - multiworld.get_entrance("Destiny Islands", player).connect(multiworld.get_region("Destiny Islands", player)) + if options.destiny_islands: + multiworld.get_entrance("Destiny Islands", player).connect(multiworld.get_region("Destiny Islands", player)) multiworld.get_entrance("Traverse Town", player).connect(multiworld.get_region("Traverse Town", player)) multiworld.get_entrance("Wonderland", player).connect(multiworld.get_region("Wonderland", player)) multiworld.get_entrance("Olympus Coliseum", player).connect(multiworld.get_region("Olympus Coliseum", player)) multiworld.get_entrance("Deep Jungle", player).connect(multiworld.get_region("Deep Jungle", player)) multiworld.get_entrance("Agrabah", player).connect(multiworld.get_region("Agrabah", player)) multiworld.get_entrance("Monstro", player).connect(multiworld.get_region("Monstro", player)) - multiworld.get_entrance("Atlantica", player).connect(multiworld.get_region("Atlantica", player)) + if options.atlantica: + multiworld.get_entrance("Atlantica", player).connect(multiworld.get_region("Atlantica", player)) multiworld.get_entrance("Halloween Town", player).connect(multiworld.get_region("Halloween Town", player)) multiworld.get_entrance("Neverland", player).connect(multiworld.get_region("Neverland", player)) multiworld.get_entrance("Hollow Bastion", player).connect(multiworld.get_region("Hollow Bastion", player)) @@ -501,7 +598,7 @@ def connect_entrances(multiworld: MultiWorld, player: int): multiworld.get_entrance("100 Acre Wood", player).connect(multiworld.get_region("100 Acre Wood", player)) multiworld.get_entrance("World Map", player).connect(multiworld.get_region("World Map", player)) multiworld.get_entrance("Levels", player).connect(multiworld.get_region("Levels", player)) - + multiworld.get_entrance("Homecoming", player).connect(multiworld.get_region("Homecoming", player)) def create_region(multiworld: MultiWorld, player: int, name: str, data: KH1RegionData): region = Region(name, player, multiworld) diff --git a/worlds/kh1/Rules.py b/worlds/kh1/Rules.py index 130238e5048e..54a94326e4e6 100644 --- a/worlds/kh1/Rules.py +++ b/worlds/kh1/Rules.py @@ -1,41 +1,69 @@ from BaseClasses import CollectionState -from worlds.generic.Rules import add_rule +from worlds.generic.Rules import add_rule, add_item_rule from math import ceil +from BaseClasses import ItemClassification +from .Data import WORLD_KEY_ITEMS, LOGIC_BEGINNER, LOGIC_NORMAL, LOGIC_PROUD, LOGIC_MINIMAL -SINGLE_PUPPIES = ["Puppy " + str(i).rjust(2,"0") for i in range(1,100)] -TRIPLE_PUPPIES = ["Puppies " + str(3*(i-1)+1).rjust(2, "0") + "-" + str(3*(i-1)+3).rjust(2, "0") for i in range(1,34)] -TORN_PAGES = ["Torn Page " + str(i) for i in range(1,6)] -WORLDS = ["Wonderland", "Olympus Coliseum", "Deep Jungle", "Agrabah", "Monstro", "Atlantica", "Halloween Town", "Neverland", "Hollow Bastion", "End of the World"] -KEYBLADES = ["Lady Luck", "Olympia", "Jungle King", "Three Wishes", "Wishing Star", "Crabclaw", "Pumpkinhead", "Fairy Harp", "Divine Rose", "Oblivion"] +from .Locations import KH1Location, location_table +from .Items import KH1Item, item_table -def has_x_worlds(state: CollectionState, player: int, num_of_worlds: int, keyblades_unlock_chests: bool) -> bool: - worlds_acquired = 0.0 - for i in range(len(WORLDS)): - if state.has(WORLDS[i], player): - worlds_acquired = worlds_acquired + 0.5 - if (state.has(WORLDS[i], player) and (not keyblades_unlock_chests or state.has(KEYBLADES[i], player))) or (state.has(WORLDS[i], player) and WORLDS[i] == "Atlantica"): - worlds_acquired = worlds_acquired + 0.5 - return worlds_acquired >= num_of_worlds +WORLDS = ["Destiny Islands", "Traverse Town", "Wonderland", "Olympus Coliseum", "Deep Jungle", "Agrabah", "Monstro", "Atlantica", "Halloween Town", "Neverland", "Hollow Bastion", "End of the World", "100 Acre Wood"] +KEYBLADES = ["Oathkeeper", "Lionheart", "Lady Luck", "Olympia", "Jungle King", "Three Wishes", "Wishing Star", "Crabclaw", "Pumpkinhead", "Fairy Harp", "Divine Rose", "Oblivion", "Spellbinder"] +BROKEN_KEYBLADE_LOCKING_LOCATIONS = [ + "End of the World Final Dimension 2nd Chest", + "End of the World Final Dimension 4th Chest", + "End of the World Final Dimension 7th Chest", + "End of the World Final Dimension 8th Chest", + "End of the World Final Dimension 10th Chest", + "Neverland Hold Aero Chest", + "Hollow Bastion Library 1st Floor Turn the Carousel Chest", + "Hollow Bastion Library Top of Bookshelf Turn the Carousel Chest", + "Hollow Bastion Library 2nd Floor Turn the Carousel 1st Chest", + "Hollow Bastion Library 2nd Floor Turn the Carousel 2nd Chest", + "Hollow Bastion Entrance Hall Emblem Piece (Chest)", + "Atlantica Sunken Ship In Flipped Boat Chest", + "Atlantica Sunken Ship Seabed Chest", + "Atlantica Sunken Ship Inside Ship Chest", + "Atlantica Ariel's Grotto High Chest", + "Atlantica Ariel's Grotto Middle Chest", + "Atlantica Ariel's Grotto Low Chest", + "Atlantica Ursula's Lair Use Fire on Urchin Chest", + "Atlantica Undersea Gorge Jammed by Ariel's Grotto Chest", + "Atlantica Triton's Palace White Trinity Chest", + "Atlantica Sunken Ship Crystal Trident Event" +] -def has_emblems(state: CollectionState, player: int, keyblades_unlock_chests: bool) -> bool: +def has_x_worlds(state: CollectionState, player: int, num_of_worlds: int, keyblades_unlock_chests: bool, logic_difficulty: int, hundred_acre_wood: bool) -> bool: + if logic_difficulty >= LOGIC_MINIMAL: + return True + else: + worlds_acquired = 0.0 + for i in range(len(WORLDS)): + if WORLDS[i] == "Traverse Town": + worlds_acquired = worlds_acquired + 0.5 + if not keyblades_unlock_chests or state.has(KEYBLADES[i], player): + worlds_acquired = worlds_acquired + 0.5 + elif WORLDS[i] == "100 Acre Wood" and hundred_acre_wood: + if state.has("Progressive Fire", player): + worlds_acquired = worlds_acquired + 0.5 + if not keyblades_unlock_chests or state.has(KEYBLADES[i], player): + worlds_acquired = worlds_acquired + 0.5 + elif state.has(WORLDS[i], player): + worlds_acquired = worlds_acquired + 0.5 + if not keyblades_unlock_chests or state.has(KEYBLADES[i], player): + worlds_acquired = worlds_acquired + 0.5 + return worlds_acquired >= num_of_worlds + +def has_emblems(state: CollectionState, player: int, keyblades_unlock_chests: bool, logic_difficulty: int, hundred_acre_wood: bool) -> bool: return state.has_all({ "Emblem Piece (Flame)", "Emblem Piece (Chest)", "Emblem Piece (Statue)", "Emblem Piece (Fountain)", - "Hollow Bastion"}, player) and has_x_worlds(state, player, 5, keyblades_unlock_chests) - -def has_puppies_all(state: CollectionState, player: int, puppies_required: int) -> bool: - return state.has("All Puppies", player) - -def has_puppies_triplets(state: CollectionState, player: int, puppies_required: int) -> bool: - return state.has_from_list_unique(TRIPLE_PUPPIES, player, ceil(puppies_required / 3)) - -def has_puppies_individual(state: CollectionState, player: int, puppies_required: int) -> bool: - return state.has_from_list_unique(SINGLE_PUPPIES, player, puppies_required) + "Hollow Bastion"}, player) and has_x_worlds(state, player, 6, keyblades_unlock_chests, logic_difficulty, hundred_acre_wood) -def has_torn_pages(state: CollectionState, player: int, pages_required: int) -> bool: - return state.count_from_list_unique(TORN_PAGES, player) >= pages_required +def has_puppies(state: CollectionState, player: int, puppies_required: int, puppy_value: int) -> bool: + return (state.count("Puppy", player) * puppy_value) >= puppies_required def has_all_arts(state: CollectionState, player: int) -> bool: return state.has_all({"Fire Arts", "Blizzard Arts", "Thunder Arts", "Cure Arts", "Gravity Arts", "Stop Arts", "Aero Arts"}, player) @@ -53,198 +81,248 @@ def has_all_magic_lvx(state: CollectionState, player: int, level) -> bool: "Progressive Aero": level, "Progressive Stop": level}, player) -def has_offensive_magic(state: CollectionState, player: int) -> bool: - return state.has_any({"Progressive Fire", "Progressive Blizzard", "Progressive Thunder", "Progressive Gravity", "Progressive Stop"}, player) +def has_offensive_magic(state: CollectionState, player: int, logic_difficulty: int) -> bool: + return ( + state.has_any({"Progressive Fire", "Progressive Blizzard"}, player) + or (logic_difficulty > LOGIC_NORMAL and state.has_any({"Progressive Thunder", "Progressive Gravity"}, player)) + or (logic_difficulty > LOGIC_PROUD and state.has("Progressive Stop", player)) + ) -def has_reports(state: CollectionState, player: int, eotw_required_reports: int) -> bool: - return state.has_group_unique("Reports", player, eotw_required_reports) +def has_lucky_emblems(state: CollectionState, player: int, required_amt: int) -> bool: + return state.has("Lucky Emblem", player, required_amt) -def has_final_rest_door(state: CollectionState, player: int, final_rest_door_requirement: str, final_rest_door_required_reports: int, keyblades_unlock_chests: bool, puppies_choice: str): - if final_rest_door_requirement == "reports": - return state.has_group_unique("Reports", player, final_rest_door_required_reports) - if final_rest_door_requirement == "puppies": - if puppies_choice == "individual": - return has_puppies_individual(state, player, 99) - if puppies_choice == "triplets": - return has_puppies_triplets(state, player, 99) - return has_puppies_all(state, player, 99) - if final_rest_door_requirement == "postcards": - return state.has("Postcard", player, 10) - if final_rest_door_requirement == "superbosses": - return ( - state.has_all({"Olympus Coliseum", "Neverland", "Agrabah", "Hollow Bastion", "Green Trinity", "Phil Cup", "Pegasus Cup", "Hercules Cup", "Entry Pass"}, player) - and has_emblems(state, player, keyblades_unlock_chests) - and has_all_magic_lvx(state, player, 2) - and has_defensive_tools(state, player) - and has_x_worlds(state, player, 7, keyblades_unlock_chests) - ) +def has_final_rest_door(state: CollectionState, player: int, final_rest_door_requirement: str, final_rest_door_required_lucky_emblems: int): + if final_rest_door_requirement == "lucky_emblems": + return state.has("Lucky Emblem", player, final_rest_door_required_lucky_emblems) + else: + return state.has("Final Door Key", player) -def has_defensive_tools(state: CollectionState, player: int) -> bool: - return ( +def has_defensive_tools(state: CollectionState, player: int, logic_difficulty: int) -> bool: + if logic_difficulty >= LOGIC_MINIMAL: + return True + else: + return ( state.has_all_counts({"Progressive Cure": 2, "Leaf Bracer": 1, "Dodge Roll": 1}, player) and state.has_any_count({"Second Chance": 1, "MP Rage": 1, "Progressive Aero": 2}, player) ) +def has_basic_tools(state: CollectionState, player: int) -> bool: + return ( + state.has_all({"Dodge Roll", "Progressive Cure"}, player) + and state.has_any({"Combo Master", "Strike Raid", "Sonic Blade", "Counterattack"}, player) + and state.has_any({"Leaf Bracer", "Second Chance", "Guard"}, player) + and has_offensive_magic(state, player, 6) + ) + def can_dumbo_skip(state: CollectionState, player: int) -> bool: return ( state.has("Dumbo", player) and state.has_group("Magic", player) ) -def has_oogie_manor(state: CollectionState, player: int, advanced_logic: bool) -> bool: +def has_oogie_manor(state: CollectionState, player: int, logic_difficulty: int) -> bool: return ( - state.has("Progressive Fire", player) - or (advanced_logic and state.has("High Jump", player, 2)) - or (advanced_logic and state.has("High Jump", player) and state.has("Progressive Glide", player)) + state.has("Progressive Fire", player) + or (logic_difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) + or (logic_difficulty > LOGIC_NORMAL and state.has("High Jump", player, 2) or (state.has_all({"High Jump", "Progressive Glide"}, player))) + or (logic_difficulty > LOGIC_PROUD and state.has_any({"High Jump", "Progressive Glide"}, player)) + ) + +def has_item_workshop(state: CollectionState, player: int, logic_difficulty: int) -> bool: + return ( + state.has("Green Trinity", player) + or (logic_difficulty > LOGIC_NORMAL and state.has("High Jump", player, 2)) + ) + +def has_parasite_cage(state: CollectionState, player: int, logic_difficulty: int, worlds: bool) -> bool: + return ( + state.has("Monstro", player) + and + ( + state.has("High Jump", player) + or (logic_difficulty > LOGIC_BEGINNER and state.has("Progressive Glide", player)) + ) + and worlds + ) + +def has_key_item(state: CollectionState, player: int, key_item: str, stacking_world_items: bool, halloween_town_key_item_bundle: bool, difficulty: int, keyblades_unlock_chests: bool): + return ( + ( + state.has(key_item, player) + or (stacking_world_items and state.has(WORLD_KEY_ITEMS[key_item], player, 2)) + or (key_item == "Jack-In-The-Box" and state.has("Forget-Me-Not", player) and halloween_town_key_item_bundle) ) + # Adding this to make sure that if a beginner logic player is playing with keyblade locking, + # anything that would require the Crystal Trident should expect the player to be able to + # open the Crystal Trident chest. + and (key_item != "Crystal Trident" or difficulty > LOGIC_BEGINNER or not keyblades_unlock_chests or state.has("Crabclaw", player)) + ) def set_rules(kh1world): - multiworld = kh1world.multiworld - player = kh1world.player - options = kh1world.options - eotw_required_reports = kh1world.determine_reports_required_to_open_end_of_the_world() - final_rest_door_required_reports = kh1world.determine_reports_required_to_open_final_rest_door() - final_rest_door_requirement = kh1world.options.final_rest_door.current_key - - has_puppies = has_puppies_individual - if kh1world.options.puppies == "triplets": - has_puppies = has_puppies_triplets - elif kh1world.options.puppies == "full": - has_puppies = has_puppies_all + multiworld = kh1world.multiworld + player = kh1world.player + options = kh1world.options + eotw_required_lucky_emblems = kh1world.determine_lucky_emblems_required_to_open_end_of_the_world() + final_rest_door_required_lucky_emblems = kh1world.determine_lucky_emblems_required_to_open_final_rest_door() + final_rest_door_requirement = kh1world.options.final_rest_door_key.current_key + day_2_materials = kh1world.options.day_2_materials.value + homecoming_materials = kh1world.options.homecoming_materials.value + difficulty = kh1world.options.logic_difficulty.value # difficulty > 0 is Normal or higher; difficulty > 5 is Proud or higher; difficulty > 10 is Minimal and higher; others are for if another difficulty is added + stacking_world_items = kh1world.options.stacking_world_items.value + halloween_town_key_item_bundle = kh1world.options.halloween_town_key_item_bundle.value + end_of_the_world_unlock = kh1world.options.end_of_the_world_unlock.current_key + hundred_acre_wood = kh1world.options.hundred_acre_wood + add_rule(kh1world.get_location("Traverse Town 1st District Candle Puzzle Chest"), lambda state: state.has("Progressive Blizzard", player)) + add_rule(kh1world.get_location("Traverse Town 1st District Accessory Shop Roof Chest"), # this check could justifiably require high jump for Beginners + lambda state: state.has("High Jump", player)) or difficulty > LOGIC_BEGINNER add_rule(kh1world.get_location("Traverse Town Mystical House Yellow Trinity Chest"), lambda state: ( state.has("Progressive Fire", player) and ( state.has("Yellow Trinity", player) - or (options.advanced_logic and state.has("High Jump", player)) - or state.has("High Jump", player, 2) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 2)) + or (difficulty > LOGIC_NORMAL and state.has("High Jump", player)) ) )) add_rule(kh1world.get_location("Traverse Town Secret Waterway White Trinity Chest"), lambda state: state.has("White Trinity", player)) add_rule(kh1world.get_location("Traverse Town Geppetto's House Chest"), - lambda state: ( - state.has("Monstro", player) - and - ( - state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) - ) - and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) - )) + lambda state: (has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)))) add_rule(kh1world.get_location("Traverse Town Item Workshop Right Chest"), - lambda state: ( - state.has("Green Trinity", player) - or state.has("High Jump", player, 3) - )) + lambda state: (has_item_workshop(state, player, difficulty))) + add_rule(kh1world.get_location("Traverse Town Item Workshop Left Chest"), + lambda state: (has_item_workshop(state, player, difficulty))) add_rule(kh1world.get_location("Traverse Town 1st District Blue Trinity Balcony Chest"), lambda state: ( (state.has("Blue Trinity", player) and state.has("Progressive Glide", player)) - or (options.advanced_logic and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_NORMAL and state.has("Progressive Glide", player)) )) add_rule(kh1world.get_location("Traverse Town Mystical House Glide Chest"), lambda state: ( + state.has("Progressive Fire", player) + and ( state.has("Progressive Glide", player) or ( - options.advanced_logic + difficulty > LOGIC_NORMAL and ( - (state.has("High Jump", player) and state.has("Yellow Trinity", player)) - or state.has("High Jump", player, 2) + state.has("High Jump", player, 3) + or + ( + state.has("Combo Master", player) + and + ( + state.has("High Jump", player, 2) + or + ( + state.has("High Jump", player) + and state.has("Air Combo Plus", player, 2) + #or state.has("Yellow Trinity", player) + ) + ) + ) ) - and state.has("Combo Master", player) ) or ( - options.advanced_logic - and state.has("Mermaid Kick", player) + difficulty > LOGIC_PROUD + and + ( + state.has("Mermaid Kick", player) + or state.has("Combo Master", player) and (state.has("High Jump", player) or state.has("Air Combo Plus", player, 2)) + ) ) ) - and state.has("Progressive Fire", player) )) add_rule(kh1world.get_location("Traverse Town Alleyway Behind Crates Chest"), lambda state: state.has("Red Trinity", player)) - add_rule(kh1world.get_location("Traverse Town Item Workshop Left Chest"), - lambda state: ( - state.has("Green Trinity", player) - or state.has("High Jump", player, 3) - )) add_rule(kh1world.get_location("Wonderland Rabbit Hole Green Trinity Chest"), lambda state: state.has("Green Trinity", player)) add_rule(kh1world.get_location("Wonderland Rabbit Hole Defeat Heartless 3 Chest"), - lambda state: has_x_worlds(state, player, 5, options.keyblades_unlock_chests)) + lambda state: ( + has_x_worlds(state, player, 6, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + or (difficulty > LOGIC_NORMAL and has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) + or difficulty > LOGIC_PROUD + )) + add_rule(kh1world.get_location("Wonderland Bizarre Room Green Trinity Chest"), lambda state: state.has("Green Trinity", player)) add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Left Red Chest"), lambda state: ( - state.has("Footprints", player) + has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) or state.has("High Jump", player) - or state.has("Progressive Glide", player) + or (difficulty > LOGIC_BEGINNER and state.has("Progressive Glide", player)) )) add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Right Blue Chest"), lambda state: ( - state.has("Footprints", player) + has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) or state.has("High Jump", player) - or state.has("Progressive Glide", player) + or (difficulty > LOGIC_BEGINNER and state.has("Progressive Glide", player)) )) add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Right Red Chest"), lambda state: ( - state.has("Footprints", player) + has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) or state.has("High Jump", player) - or state.has("Progressive Glide", player) + or (difficulty > LOGIC_BEGINNER and state.has("Progressive Glide", player)) )) add_rule(kh1world.get_location("Wonderland Lotus Forest Thunder Plant Chest"), lambda state: ( - state.has_all({ - "Progressive Thunder", - "Footprints"}, player) + state.has("Progressive Thunder", player) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Wonderland Lotus Forest Through the Painting Thunder Plant Chest"), lambda state: ( - state.has_all({ - "Progressive Thunder", - "Footprints"}, player) + state.has("Progressive Thunder", player) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Wonderland Lotus Forest Glide Chest"), lambda state: ( state.has("Progressive Glide", player) or ( - options.advanced_logic + difficulty > LOGIC_NORMAL and (state.has("High Jump", player) or can_dumbo_skip(state, player)) - and state.has("Footprints", player) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + ) + or + ( + difficulty > LOGIC_PROUD + and state.has_all_counts({"Combo Master": 1, "High Jump": 3, "Air Combo Plus": 2}, player) ) )) add_rule(kh1world.get_location("Wonderland Lotus Forest Corner Chest"), lambda state: ( - ( - state.has("High Jump", player) - or state.has("Progressive Glide", player) - ) - or options.advanced_logic + state.has_all({"High Jump", "Progressive Glide"}, player) + or difficulty > LOGIC_BEGINNER and state.has_any({"High Jump","Progressive Glide"}, player) + or difficulty > LOGIC_NORMAL )) add_rule(kh1world.get_location("Wonderland Bizarre Room Lamp Chest"), - lambda state: state.has("Footprints", player)) + lambda state: has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Wonderland Tea Party Garden Above Lotus Forest Entrance 2nd Chest"), lambda state: ( state.has("Progressive Glide", player) or ( - state.has("High Jump", player, 2) - and state.has("Footprints", player) + difficulty > LOGIC_BEGINNER + and state.has("High Jump", player, 2) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + ) + or + ( + difficulty > LOGIC_NORMAL + and (state.has("High Jump", player) or can_dumbo_skip(state, player)) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) ) or ( - options.advanced_logic - and state.has_all({ - "High Jump", - "Footprints"}, player) + difficulty > LOGIC_PROUD + and state.has_all_counts({"Combo Master": 1, "High Jump": 3, "Air Combo Plus": 2}, player) ) )) add_rule(kh1world.get_location("Wonderland Tea Party Garden Above Lotus Forest Entrance 1st Chest"), @@ -252,288 +330,329 @@ def set_rules(kh1world): state.has("Progressive Glide", player) or ( - state.has("High Jump", player, 2) - and state.has("Footprints", player) + difficulty > LOGIC_BEGINNER + and state.has("High Jump", player, 2) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) ) or ( - options.advanced_logic - and state.has_all({ - "High Jump", - "Footprints"}, player) + difficulty > LOGIC_NORMAL + and (state.has("High Jump", player) or can_dumbo_skip(state, player)) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + ) + or + ( + difficulty > LOGIC_PROUD + and state.has_all_counts({"Combo Master": 1, "High Jump": 3, "Air Combo Plus": 2}, player) ) )) add_rule(kh1world.get_location("Wonderland Tea Party Garden Bear and Clock Puzzle Chest"), lambda state: ( - - state.has("Footprints", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) + has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + or state.has("Progressive Glide", player) + or + ( + difficulty > LOGIC_PROUD + and state.has_all_counts({"Combo Master": 1, "High Jump": 3, "Air Combo Plus": 2}, player) + ) )) add_rule(kh1world.get_location("Wonderland Tea Party Garden Across From Bizarre Room Entrance Chest"), lambda state: ( state.has("Progressive Glide", player) or ( - state.has("High Jump", player, 3) - and state.has("Footprints", player) + difficulty > LOGIC_BEGINNER + and state.has("High Jump", player, 3) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + ) + or + ( + difficulty > LOGIC_NORMAL + and + ( + ( + state.has_all({"High Jump", "Combo Master"}, player) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + ) + or (state.has("High Jump", player, 2) and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + ) ) or ( - options.advanced_logic - and state.has_all({ - "High Jump", - "Footprints", - "Combo Master"}, player) + difficulty > LOGIC_PROUD + and state.has_all_counts({"Combo Master": 1, "High Jump": 3, "Air Combo Plus": 2}, player) ) )) add_rule(kh1world.get_location("Wonderland Lotus Forest Through the Painting White Trinity Chest"), lambda state: ( - state.has_all({ - "White Trinity", - "Footprints"}, player) + state.has("White Trinity", player) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Deep Jungle Hippo's Lagoon Right Chest"), lambda state: ( - - state.has("High Jump", player) - or state.has("Progressive Glide", player) - or options.advanced_logic + state.has_all({"High Jump", "Progressive Glide"}, player) + or + ( + difficulty > LOGIC_BEGINNER + and (state.has("High Jump", player) + or state.has("Progressive Glide", player)) + ) + or + difficulty > LOGIC_NORMAL )) add_rule(kh1world.get_location("Deep Jungle Climbing Trees Blue Trinity Chest"), lambda state: state.has("Blue Trinity", player)) add_rule(kh1world.get_location("Deep Jungle Cavern of Hearts White Trinity Chest"), lambda state: ( - state.has_all({ - "White Trinity", - "Slides"}, player) + state.has("White Trinity", player) + and has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Deep Jungle Camp Blue Trinity Chest"), lambda state: state.has("Blue Trinity", player)) add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern Low Chest"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern Middle Chest"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern High Wall Chest"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern High Middle Chest"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Deep Jungle Tree House Rooftop Chest"), + lambda state: ( + state.has("High Jump", player) + or difficulty > LOGIC_NORMAL + )) add_rule(kh1world.get_location("Deep Jungle Tree House Suspended Boat Chest"), lambda state: ( state.has("Progressive Glide", player) - or options.advanced_logic + or difficulty > LOGIC_NORMAL )) add_rule(kh1world.get_location("Agrabah Main Street High Above Palace Gates Entrance Chest"), lambda state: ( state.has("High Jump", player) - or state.has("Progressive Glide", player) - or (options.advanced_logic and can_dumbo_skip(state, player)) + or (difficulty > LOGIC_BEGINNER and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_NORMAL and can_dumbo_skip(state, player)) )) add_rule(kh1world.get_location("Agrabah Palace Gates High Opposite Palace Chest"), lambda state: ( state.has("High Jump", player) - or options.advanced_logic + or (difficulty > LOGIC_NORMAL and state.has("Progressive Glide", player)) + or difficulty > LOGIC_PROUD )) add_rule(kh1world.get_location("Agrabah Palace Gates High Close to Palace Chest"), lambda state: ( + state.has_all({"High Jump", "Progressive Glide"}, player) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) + or ( - state.has_all({ - "High Jump", - "Progressive Glide"}, player) - or + difficulty > LOGIC_NORMAL + and ( - options.advanced_logic - and - ( - state.has("Combo Master", player) - or can_dumbo_skip(state, player) - ) + state.has("High Jump", player, 2) + or state.has("Progressive Glide", player) + or state.has_all({"High Jump", "Combo Master"}, player) ) ) - or state.has("High Jump", player, 3) - or (options.advanced_logic and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_PROUD and state.has("Combo Master", player)) # can_dumbo_skip(state, player) )) add_rule(kh1world.get_location("Agrabah Storage Green Trinity Chest"), lambda state: state.has("Green Trinity", player)) add_rule(kh1world.get_location("Agrabah Cave of Wonders Entrance Tall Tower Chest"), lambda state: ( state.has("Progressive Glide", player) - or (options.advanced_logic and state.has("Combo Master", player)) - or (options.advanced_logic and can_dumbo_skip(state, player)) - or state.has("High Jump", player, 2) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 2)) + or + ( + difficulty > LOGIC_NORMAL + and + ( + state.has("Combo Master", player) + or can_dumbo_skip(state, player) + or state.has("High Jump", player) + ) + ) + or difficulty > LOGIC_PROUD )) add_rule(kh1world.get_location("Agrabah Cave of Wonders Bottomless Hall Pillar Chest"), lambda state: ( - state.has("High Jump", player) - or state.has("Progressive Glide", player) - or options.advanced_logic + state.has("Progressive Glide", player) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player)) + or difficulty > LOGIC_NORMAL )) add_rule(kh1world.get_location("Agrabah Cave of Wonders Silent Chamber Blue Trinity Chest"), lambda state: state.has("Blue Trinity", player)) add_rule(kh1world.get_location("Agrabah Cave of Wonders Hidden Room Right Chest"), lambda state: ( state.has("Yellow Trinity", player) - or state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player)) + or (difficulty > LOGIC_NORMAL and state.has("Progressive Glide", player)) )) add_rule(kh1world.get_location("Agrabah Cave of Wonders Hidden Room Left Chest"), lambda state: ( state.has("Yellow Trinity", player) - or state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player)) + or (difficulty > LOGIC_NORMAL and state.has("Progressive Glide", player)) )) add_rule(kh1world.get_location("Agrabah Cave of Wonders Entrance White Trinity Chest"), lambda state: state.has("White Trinity", player)) - add_rule(kh1world.get_location("Monstro Chamber 6 Other Platform Chest"), - lambda state: ( - state.has_all(("High Jump", "Progressive Glide"), player) - or (options.advanced_logic and state.has("Combo Master", player)) - )) add_rule(kh1world.get_location("Monstro Chamber 6 Platform Near Chamber 5 Entrance Chest"), lambda state: ( state.has("High Jump", player) - or options.advanced_logic + or difficulty > LOGIC_NORMAL + )) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Dark Chamber Near Save Chest"), + lambda state: state.has_any({"High Jump", "Progressive Glide"}, player) or difficulty > LOGIC_BEGINNER) + add_rule(kh1world.get_location("Monstro Chamber 6 Other Platform Chest"), + lambda state: ( + state.has_all({"High Jump","Progressive Glide"}, player) + or + ( + difficulty > LOGIC_NORMAL + and + ( + state.has("Combo Master", player) + or state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + ) + or + difficulty > LOGIC_PROUD )) add_rule(kh1world.get_location("Monstro Chamber 6 Raised Area Near Chamber 1 Entrance Chest"), lambda state: ( - state.has_all(("High Jump", "Progressive Glide"), player) - or (options.advanced_logic and state.has("Combo Master", player)) + state.has_all({"High Jump","Progressive Glide"}, player) + or + ( + difficulty > LOGIC_NORMAL + and + ( + state.has("Combo Master", player) + or state.has("High Jump", player) + or state.has("Progressive Glide", player) + ) + ) + or + difficulty > LOGIC_PROUD )) add_rule(kh1world.get_location("Halloween Town Moonlight Hill White Trinity Chest"), lambda state: ( - state.has_all({ - "White Trinity", - "Forget-Me-Not"}, player) + state.has("White Trinity", player) + and has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Halloween Town Bridge Under Bridge"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Halloween Town Boneyard Tombstone Puzzle Chest"), - lambda state: state.has("Forget-Me-Not", player)) + lambda state: has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Halloween Town Bridge Right of Gate Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and ( state.has("Progressive Glide", player) - or options.advanced_logic + or state.has("High Jump", player, 3) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 2)) + or (difficulty > LOGIC_NORMAL and state.has("High Jump", player)) + or difficulty > LOGIC_PROUD ) )) add_rule(kh1world.get_location("Halloween Town Cemetery Behind Grave Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) - and has_oogie_manor(state, player, options.advanced_logic) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) )) add_rule(kh1world.get_location("Halloween Town Cemetery By Cat Shape Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) - and has_oogie_manor(state, player, options.advanced_logic) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) )) add_rule(kh1world.get_location("Halloween Town Cemetery Between Graves Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) - and has_oogie_manor(state, player, options.advanced_logic) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) )) add_rule(kh1world.get_location("Halloween Town Oogie's Manor Lower Iron Cage Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) - and has_oogie_manor(state, player, options.advanced_logic) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) + and (difficulty > LOGIC_BEGINNER or has_basic_tools or state.has("Progressive Glide", player)) + # difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 2) + # difficulty > LOGIC_NORMAL and state.has("Combo Master", player) or state.has("High Jump", player) + # difficulty > LOGIC_PROUD )) add_rule(kh1world.get_location("Halloween Town Oogie's Manor Upper Iron Cage Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) - and has_oogie_manor(state, player, options.advanced_logic) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) + and (difficulty > LOGIC_BEGINNER or has_basic_tools or state.has_all({"High Jump", "Progressive Glide"})) )) add_rule(kh1world.get_location("Halloween Town Oogie's Manor Hollow Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) - and has_oogie_manor(state, player, options.advanced_logic) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) )) add_rule(kh1world.get_location("Halloween Town Oogie's Manor Grounds Red Trinity Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not", - "Red Trinity"}, player) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and state.has("Red Trinity", player) )) add_rule(kh1world.get_location("Halloween Town Guillotine Square High Tower Chest"), lambda state: ( - state.has("High Jump", player) - or (options.advanced_logic and can_dumbo_skip(state, player)) - or (options.advanced_logic and state.has("Progressive Glide", player)) + state.has_all({"High Jump", "Progressive Glide"}, player) + or (difficulty > LOGIC_BEGINNER and (state.has("High Jump", player) or state.has("Progressive Glide", player))) + or (difficulty > LOGIC_NORMAL and can_dumbo_skip(state, player)) )) add_rule(kh1world.get_location("Halloween Town Guillotine Square Pumpkin Structure Left Chest"), lambda state: ( ( state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_BEGINNER and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_NORMAL and can_dumbo_skip(state, player)) ) and ( state.has("Progressive Glide", player) - or (options.advanced_logic and state.has("Combo Master", player)) - or state.has("High Jump", player, 2) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 2)) + or (difficulty > LOGIC_NORMAL and state.has("Combo Master", player)) + ) + )) + add_rule(kh1world.get_location("Halloween Town Guillotine Square Pumpkin Structure Right Chest"), + lambda state: ( + ( + state.has("High Jump", player) + or (difficulty > LOGIC_BEGINNER and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_NORMAL and can_dumbo_skip(state, player)) + ) + and + ( + state.has("Progressive Glide", player) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 2)) + or (difficulty > LOGIC_NORMAL and state.has("Combo Master", player)) ) )) add_rule(kh1world.get_location("Halloween Town Oogie's Manor Entrance Steps Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Halloween Town Oogie's Manor Inside Entrance Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Halloween Town Bridge Left of Gate Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and ( state.has("Progressive Glide", player) or state.has("High Jump", player) - or options.advanced_logic + or difficulty > LOGIC_NORMAL ) )) add_rule(kh1world.get_location("Halloween Town Cemetery By Striped Grave Chest"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) - and has_oogie_manor(state, player, options.advanced_logic) - )) - add_rule(kh1world.get_location("Halloween Town Guillotine Square Pumpkin Structure Right Chest"), - lambda state: ( - ( - state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) - ) - and - ( - state.has("Progressive Glide", player) - or (options.advanced_logic and state.has("Combo Master", player)) - or state.has("High Jump", player, 2) - ) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) )) add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Right Blue Trinity Chest"), lambda state: state.has("Blue Trinity", player)) @@ -548,37 +667,47 @@ def set_rules(kh1world): add_rule(kh1world.get_location("Monstro Mouth High Platform Boat Side Chest"), lambda state: ( state.has("High Jump", player) - or state.has("Progressive Glide", player) + or (difficulty > LOGIC_BEGINNER and state.has("Progressive Glide", player)) )) add_rule(kh1world.get_location("Monstro Mouth High Platform Across from Boat Chest"), lambda state: ( state.has("High Jump", player) - or state.has("Progressive Glide", player) + or (difficulty > LOGIC_BEGINNER and state.has("Progressive Glide", player)) )) add_rule(kh1world.get_location("Monstro Mouth Green Trinity Top of Boat Chest"), lambda state: ( ( state.has("High Jump", player) - or state.has("Progressive Glide", player) + or (difficulty > LOGIC_BEGINNER and state.has("Progressive Glide", player)) ) and state.has("Green Trinity", player) )) + add_rule(kh1world.get_location("Monstro Mouth Near Ship Chest"), + lambda state: (difficulty > LOGIC_BEGINNER or state.has_any({"High Jump","Progressive Glide"}, player) or has_basic_tools)) + add_rule(kh1world.get_location("Monstro Chamber 2 Platform Chest"), + lambda state: ( + state.has_any({"High Jump","Progressive Glide"}, player) + or difficulty > LOGIC_BEGINNER + )) add_rule(kh1world.get_location("Monstro Chamber 5 Platform Chest"), - lambda state: state.has("High Jump", player)) + lambda state: ( + state.has("High Jump", player) + or difficulty > LOGIC_NORMAL + )) add_rule(kh1world.get_location("Monstro Chamber 3 Platform Above Chamber 2 Entrance Chest"), lambda state: ( state.has("High Jump", player) - or options.advanced_logic + or difficulty > LOGIC_BEGINNER )) add_rule(kh1world.get_location("Monstro Chamber 3 Platform Near Chamber 6 Entrance Chest"), lambda state: ( state.has("High Jump", player) - or options.advanced_logic + or difficulty > LOGIC_BEGINNER )) add_rule(kh1world.get_location("Monstro Chamber 5 Atop Barrel Chest"), lambda state: ( state.has("High Jump", player) - or options.advanced_logic + or difficulty > LOGIC_NORMAL )) add_rule(kh1world.get_location("Neverland Pirate Ship Deck White Trinity Chest"), lambda state: ( @@ -598,27 +727,23 @@ def set_rules(kh1world): lambda state: ( state.has("Green Trinity", player) or state.has("Progressive Glide", player) - or state.has("High Jump", player, 3) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) )) add_rule(kh1world.get_location("Neverland Clock Tower Chest"), - lambda state: ( - state.has("Green Trinity", player) - and has_all_magic_lvx(state, player, 2) - and has_defensive_tools(state, player) - )) + lambda state: state.has("Green Trinity", player)) add_rule(kh1world.get_location("Neverland Hold Flight 2nd Chest"), lambda state: ( state.has("Green Trinity", player) or state.has("Progressive Glide", player) - or state.has("High Jump", player, 3) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) )) add_rule(kh1world.get_location("Neverland Hold Yellow Trinity Green Chest"), lambda state: state.has("Yellow Trinity", player)) add_rule(kh1world.get_location("Neverland Captain's Cabin Chest"), lambda state: state.has("Green Trinity", player)) add_rule(kh1world.get_location("Hollow Bastion Rising Falls Under Water 2nd Chest"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) - add_rule(kh1world.get_location("Hollow Bastion Rising Falls Floating Platform Near Save Chest"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) + add_rule(kh1world.get_location("Hollow Bastion Rising Falls Floating Platform Near Save Chest"), #might be possible with CM and 2ACP lambda state: ( state.has("High Jump", player) or state.has("Progressive Glide", player) @@ -633,87 +758,99 @@ def set_rules(kh1world): add_rule(kh1world.get_location("Hollow Bastion Rising Falls High Platform Chest"), lambda state: ( state.has("Progressive Glide", player) - or (state.has("Progressive Blizzard", player) and has_emblems(state, player, options.keyblades_unlock_chests)) - or (options.advanced_logic and state.has("Combo Master", player)) + or (state.has("Progressive Blizzard", player) and has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) + or (difficulty > LOGIC_NORMAL and (state.has("High Jump", player) or state.has("Combo Master", player))) + or difficulty > LOGIC_PROUD )) add_rule(kh1world.get_location("Hollow Bastion Castle Gates Gravity Chest"), lambda state: ( state.has("Progressive Gravity", player) and ( - has_emblems(state, player, options.keyblades_unlock_chests) - or (options.advanced_logic and state.has("High Jump", player, 2) and state.has("Progressive Glide", player)) - or (options.advanced_logic and can_dumbo_skip(state, player) and state.has("Progressive Glide", player)) + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3) and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_NORMAL and (state.has("High Jump", player, 2) or can_dumbo_skip(state, player)) and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_PROUD and state.has_all({"High Jump", "Progressive Glide"},player)) ) )) add_rule(kh1world.get_location("Hollow Bastion Castle Gates Freestanding Pillar Chest"), lambda state: ( - has_emblems(state, player, options.keyblades_unlock_chests) - or state.has("High Jump", player, 2) - or (options.advanced_logic and can_dumbo_skip(state, player)) + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) + or (difficulty > LOGIC_NORMAL and (state.has("High Jump", player, 2) or can_dumbo_skip(state, player))) + or (difficulty > LOGIC_PROUD and state.has_all({"High Jump", "Progressive Glide"},player)) )) add_rule(kh1world.get_location("Hollow Bastion Castle Gates High Pillar Chest"), lambda state: ( - has_emblems(state, player, options.keyblades_unlock_chests) - or state.has("High Jump", player, 2) - or (options.advanced_logic and can_dumbo_skip(state, player)) + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) + or (difficulty > LOGIC_NORMAL and (state.has("High Jump", player, 2) or can_dumbo_skip(state, player))) + or (difficulty > LOGIC_PROUD and state.has_all({"High Jump", "Progressive Glide"},player)) )) + add_rule(kh1world.get_location("Hollow Bastion Base Level Platform Near Entrance Chest"), + lambda state: (difficulty > LOGIC_BEGINNER or state.has_any({"Progressive Glide", "High Jump"}, player))) add_rule(kh1world.get_location("Hollow Bastion Great Crest Lower Chest"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Great Crest After Battle Platform Chest"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion High Tower 2nd Gravity Chest"), lambda state: ( state.has("Progressive Gravity", player) - and has_emblems(state, player, options.keyblades_unlock_chests) + and has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) )) add_rule(kh1world.get_location("Hollow Bastion High Tower 1st Gravity Chest"), lambda state: ( state.has("Progressive Gravity", player) - and has_emblems(state, player, options.keyblades_unlock_chests) + and has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) )) add_rule(kh1world.get_location("Hollow Bastion High Tower Above Sliding Blocks Chest"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Lift Stop Library Node After High Tower Switch Gravity Chest"), lambda state: ( state.has("Progressive Gravity", player) - and has_emblems(state, player, options.keyblades_unlock_chests) + and has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) )) add_rule(kh1world.get_location("Hollow Bastion Lift Stop Library Node Gravity Chest"), lambda state: state.has("Progressive Gravity", player)) add_rule(kh1world.get_location("Hollow Bastion Lift Stop Under High Tower Sliding Blocks Chest"), lambda state: ( - has_emblems(state, player, options.keyblades_unlock_chests) - and state.has_all({ - "Progressive Glide", - "Progressive Gravity"}, player) + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and state.has("Progressive Gravity", player) + and (difficulty > LOGIC_BEGINNER or state.has("Progressive Glide", player)) )) add_rule(kh1world.get_location("Hollow Bastion Lift Stop Outside Library Gravity Chest"), lambda state: state.has("Progressive Gravity", player)) add_rule(kh1world.get_location("Hollow Bastion Lift Stop Heartless Sigil Door Gravity Chest"), lambda state: ( state.has("Progressive Gravity", player) - and has_emblems(state, player, options.keyblades_unlock_chests) + and + ( + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3) and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_NORMAL and (state.has("High Jump", player, 2) or can_dumbo_skip(state, player)) and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_PROUD and state.has_all({"High Jump", "Progressive Glide"},player)) + ) )) add_rule(kh1world.get_location("Hollow Bastion Waterway Blizzard on Bubble Chest"), lambda state: ( (state.has("Progressive Blizzard", player) and state.has("High Jump", player)) - or state.has("High Jump", player, 3) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) )) add_rule(kh1world.get_location("Hollow Bastion Grand Hall Steps Right Side Chest"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Grand Hall Oblivion Chest"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Grand Hall Left of Gate Chest"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Left of Emblem Door Chest"), lambda state: ( state.has("High Jump", player) or ( - options.advanced_logic + difficulty > LOGIC_NORMAL and can_dumbo_skip(state, player) - and has_emblems(state, player, options.keyblades_unlock_chests) + and has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) ) )) add_rule(kh1world.get_location("Hollow Bastion Rising Falls White Trinity Chest"), @@ -721,84 +858,87 @@ def set_rules(kh1world): add_rule(kh1world.get_location("End of the World Giant Crevasse 5th Chest"), lambda state: ( state.has("Progressive Glide", player) + or difficulty > LOGIC_NORMAL )) add_rule(kh1world.get_location("End of the World Giant Crevasse 1st Chest"), lambda state: ( state.has("High Jump", player) or state.has("Progressive Glide", player) + or difficulty > LOGIC_PROUD )) + add_rule(kh1world.get_location("End of the World Giant Crevasse 2nd Chest"), + lambda state: (difficulty > LOGIC_BEGINNER or state.has_any({"High Jump", "Progressive Glide"}, player))) + add_rule(kh1world.get_location("End of the World Giant Crevasse 3rd Chest"), + lambda state: (difficulty > LOGIC_BEGINNER or state.has_any({"High Jump", "Progressive Glide"}, player))) add_rule(kh1world.get_location("End of the World Giant Crevasse 4th Chest"), lambda state: ( + state.has("Progressive Glide", player) + or ( - options.advanced_logic - and state.has("High Jump", player) - and state.has("Combo Master", player) + difficulty > LOGIC_NORMAL + and + ( + state.has_all({"High Jump", "Combo Master"}, player) + or state.has("High Jump", player, 2) + ) ) - or state.has("Progressive Glide", player) )) add_rule(kh1world.get_location("End of the World World Terminus Agrabah Chest"), lambda state: ( state.has("High Jump", player) or ( - options.advanced_logic + difficulty > LOGIC_NORMAL and can_dumbo_skip(state, player) and state.has("Progressive Glide", player) - ) + ) #difficulty > LOGIC_PROUD and (can_dumbo_skip(state, player) or state.has("Progressive Glide", player)) )) add_rule(kh1world.get_location("Monstro Chamber 6 White Trinity Chest"), lambda state: state.has("White Trinity", player)) add_rule(kh1world.get_location("Traverse Town Kairi Secret Waterway Oathkeeper Event"), lambda state: ( - has_emblems(state, player, options.keyblades_unlock_chests) + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and state.has("Hollow Bastion", player) + and has_x_worlds(state, player, 6, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + )) + add_rule(kh1world.get_location("Traverse Town Secret Waterway Navi Gummi Event"), + lambda state: ( + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) and state.has("Hollow Bastion", player) - and has_x_worlds(state, player, 5, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 6, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) )) add_rule(kh1world.get_location("Deep Jungle Defeat Sabor White Fang Event"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Defeat Clayton Cure Event"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Seal Keyhole Jungle King Event"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Seal Keyhole Red Trinity Event"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Olympus Coliseum Defeat Cerberus Inferno Band Event"), - lambda state: state.has("Entry Pass", player)) + lambda state: has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Olympus Coliseum Cloud Sonic Blade Event"), - lambda state: state.has("Entry Pass", player)) + lambda state: has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Wonderland Defeat Trickmaster Blizzard Event"), - lambda state: state.has("Footprints", player)) + lambda state: has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Wonderland Defeat Trickmaster Ifrit's Horn Event"), - lambda state: state.has("Footprints", player)) + lambda state: has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Monstro Defeat Parasite Cage II Stop Event"), - lambda state: ( - state.has("High Jump", player) - or - ( - options.advanced_logic - and state.has("Progressive Glide", player) - ) - )) + lambda state: (has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)))) add_rule(kh1world.get_location("Halloween Town Defeat Oogie Boogie Holy Circlet Event"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) - and has_oogie_manor(state, player, options.advanced_logic) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) )) add_rule(kh1world.get_location("Halloween Town Defeat Oogie's Manor Gravity Event"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) - and has_oogie_manor(state, player, options.advanced_logic) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) )) add_rule(kh1world.get_location("Halloween Town Seal Keyhole Pumpkinhead Event"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not"}, player) - and has_oogie_manor(state, player, options.advanced_logic) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) )) add_rule(kh1world.get_location("Neverland Defeat Anti Sora Raven's Claw Event"), lambda state: state.has("Green Trinity", player)) @@ -810,18 +950,20 @@ def set_rules(kh1world): lambda state: state.has("Green Trinity", player)) add_rule(kh1world.get_location("Neverland Seal Keyhole Glide Event"), lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Neverland Seal Keyhole Navi-G Piece Event"), + lambda state: state.has("Green Trinity", player)) add_rule(kh1world.get_location("Neverland Defeat Captain Hook Ars Arcanum Event"), lambda state: state.has("Green Trinity", player)) add_rule(kh1world.get_location("Hollow Bastion Defeat Maleficent Donald Cheer Event"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Defeat Dragon Maleficent Fireglow Event"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Defeat Riku II Ragnarok Event"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Defeat Behemoth Omega Arts Event"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Speak to Princesses Fire Event"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Traverse Town Mail Postcard 01 Event"), lambda state: state.has("Postcard", player)) add_rule(kh1world.get_location("Traverse Town Mail Postcard 02 Event"), @@ -844,130 +986,76 @@ def set_rules(kh1world): lambda state: state.has("Postcard", player, 10)) add_rule(kh1world.get_location("Traverse Town Defeat Opposite Armor Aero Event"), lambda state: state.has("Red Trinity", player)) + add_rule(kh1world.get_location("Traverse Town Defeat Opposite Armor Navi-G Piece Event"), + lambda state: state.has("Red Trinity", player)) add_rule(kh1world.get_location("Hollow Bastion Speak with Aerith Ansem's Report 2"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Speak with Aerith Ansem's Report 4"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Defeat Maleficent Ansem's Report 5"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Hollow Bastion Speak with Aerith Ansem's Report 6"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Halloween Town Defeat Oogie Boogie Ansem's Report 7"), lambda state: ( - state.has_all({ - "Jack-In-The-Box", - "Forget-Me-Not", - "Progressive Fire"}, player) + has_key_item(state, player, "Forget-Me-Not", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) and has_key_item(state, player, "Jack-In-The-Box", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_oogie_manor(state, player, difficulty) )) add_rule(kh1world.get_location("Neverland Defeat Hook Ansem's Report 9"), lambda state: state.has("Green Trinity", player)) add_rule(kh1world.get_location("Hollow Bastion Speak with Aerith Ansem's Report 10"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto Reward 1"), - lambda state: ( - state.has("Monstro", player) - and - ( - state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) - ) - and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) - )) + lambda state: has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood))) add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto Reward 2"), - lambda state: ( - state.has("Monstro", player) - and - ( - state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) - ) - and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) - )) + lambda state: has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood))) add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto Reward 3"), - lambda state: ( - state.has("Monstro", player) - and - ( - state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) - ) - and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) - )) + lambda state: has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood))) add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto Reward 4"), - lambda state: ( - state.has("Monstro", player) - and - ( - state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) - ) - and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) - )) + lambda state: has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood))) add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto Reward 5"), - lambda state: ( - state.has("Monstro", player) - and - ( - state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) - ) - and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) - )) + lambda state: has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood))) add_rule(kh1world.get_location("Traverse Town Geppetto's House Geppetto All Summons Reward"), - lambda state: ( - state.has("Monstro", player) - and - ( - state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) - ) + lambda state: + has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) and has_all_summons(state, player) - and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Traverse Town Geppetto's House Talk to Pinocchio"), - lambda state: ( - state.has("Monstro", player) - and - ( - state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) - ) - and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) - )) + lambda state: has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood))) add_rule(kh1world.get_location("Traverse Town Magician's Study Obtained All Arts Items"), lambda state: ( has_all_magic_lvx(state, player, 1) and has_all_arts(state, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, 0, hundred_acre_wood) #due to the softlock potential, I'm forcing it to logic normally instead of allowing the bypass )) add_rule(kh1world.get_location("Traverse Town Magician's Study Obtained All LV1 Magic"), lambda state: has_all_magic_lvx(state, player, 1)) add_rule(kh1world.get_location("Traverse Town Magician's Study Obtained All LV3 Magic"), lambda state: has_all_magic_lvx(state, player, 3)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 10 Puppies"), - lambda state: has_puppies(state, player, 10)) + lambda state: has_puppies(state, player, 10, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 20 Puppies"), - lambda state: has_puppies(state, player, 20)) + lambda state: has_puppies(state, player, 20, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 30 Puppies"), - lambda state: has_puppies(state, player, 30)) + lambda state: has_puppies(state, player, 30, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 40 Puppies"), - lambda state: has_puppies(state, player, 40)) + lambda state: has_puppies(state, player, 40, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 50 Puppies Reward 1"), - lambda state: has_puppies(state, player, 50)) + lambda state: has_puppies(state, player, 50, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 50 Puppies Reward 2"), - lambda state: has_puppies(state, player, 50)) + lambda state: has_puppies(state, player, 50, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 60 Puppies"), - lambda state: has_puppies(state, player, 60)) + lambda state: has_puppies(state, player, 60, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 70 Puppies"), - lambda state: has_puppies(state, player, 70)) + lambda state: has_puppies(state, player, 70, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 80 Puppies"), - lambda state: has_puppies(state, player, 80)) + lambda state: has_puppies(state, player, 80, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 90 Puppies"), - lambda state: has_puppies(state, player, 90)) + lambda state: has_puppies(state, player, 90, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 99 Puppies Reward 1"), - lambda state: has_puppies(state, player, 99)) + lambda state: has_puppies(state, player, 99, options.puppy_value.value)) add_rule(kh1world.get_location("Traverse Town Piano Room Return 99 Puppies Reward 2"), - lambda state: has_puppies(state, player, 99)) + lambda state: has_puppies(state, player, 99, options.puppy_value.value)) add_rule(kh1world.get_location("Neverland Hold Aero Chest"), lambda state: state.has("Yellow Trinity", player)) add_rule(kh1world.get_location("Deep Jungle Camp Hi-Potion Experiment"), @@ -977,258 +1065,312 @@ def set_rules(kh1world): add_rule(kh1world.get_location("Deep Jungle Camp Replication Experiment"), lambda state: state.has("Progressive Blizzard", player)) add_rule(kh1world.get_location("Deep Jungle Cliff Save Gorillas"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Tree House Save Gorillas"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Camp Save Gorillas"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Bamboo Thicket Save Gorillas"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Climbing Trees Save Gorillas"), - lambda state: state.has("Slides", player)) - add_rule(kh1world.get_location("Deep Jungle Jungle Slider 10 Fruits"), - lambda state: state.has("Slides", player)) - add_rule(kh1world.get_location("Deep Jungle Jungle Slider 20 Fruits"), - lambda state: state.has("Slides", player)) - add_rule(kh1world.get_location("Deep Jungle Jungle Slider 30 Fruits"), - lambda state: state.has("Slides", player)) - add_rule(kh1world.get_location("Deep Jungle Jungle Slider 40 Fruits"), - lambda state: state.has("Slides", player)) - add_rule(kh1world.get_location("Deep Jungle Jungle Slider 50 Fruits"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Wonderland Bizarre Room Read Book"), - lambda state: state.has("Footprints", player)) + lambda state: has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Green Trinity"), lambda state: state.has("Green Trinity", player)) add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Hero's License Event"), - lambda state: state.has("Entry Pass", player)) + lambda state: has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Deep Jungle Cavern of Hearts Navi-G Piece Event"), - lambda state: state.has("Slides", player)) + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Wonderland Bizarre Room Navi-G Piece Event"), - lambda state: state.has("Footprints", player)) - add_rule(kh1world.get_location("Traverse Town Synth Log"), + lambda state: has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Traverse Town Synth 15 Items"), lambda state: ( - state.has("Empty Bottle", player, 6) - and - ( - state.has("Green Trinity", player) - or state.has("High Jump", player, 3) - ) + min(state.count("Orichalcum", player),9) + min(state.count("Mythril", player),9) >= 15 + and has_item_workshop(state, player, difficulty) )) - add_rule(kh1world.get_location("Traverse Town Synth Cloth"), + for i in range(33): + add_rule(kh1world.get_location("Traverse Town Synth Item " + str(i+1).rjust(2,'0')), + lambda state: ( + state.has("Orichalcum", player, 17) + and state.has("Mythril", player, 16) + and has_item_workshop(state, player, difficulty) + )) + add_item_rule(kh1world.get_location("Traverse Town Synth Item " + str(i+1).rjust(2,'0')), + lambda i: (i.player != player or i.name not in ["Orichalcum", "Mythril"])) + add_rule(kh1world.get_location("Traverse Town Gizmo Shop Postcard 1"), + lambda state: state.has("Progressive Thunder", player)) + add_rule(kh1world.get_location("Traverse Town Gizmo Shop Postcard 2"), + lambda state: state.has("Progressive Thunder", player)) + add_rule(kh1world.get_location("Traverse Town Item Workshop Postcard"), + lambda state: (has_item_workshop(state, player, difficulty))) + add_rule(kh1world.get_location("Traverse Town Geppetto's House Postcard"), + lambda state: has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood))) + add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Flame)"), lambda state: ( - state.has("Empty Bottle", player, 6) - and ( - state.has("Green Trinity", player) - or state.has("High Jump", player, 3) + has_key_item(state, player, "Theon Vol. 6", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + or has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) + or (difficulty > LOGIC_NORMAL and state.has("High Jump", player, 2)) ) - )) - add_rule(kh1world.get_location("Traverse Town Synth Rope"), - lambda state: ( - state.has("Empty Bottle", player, 6) + and state.has("Progressive Fire", player) and ( - state.has("Green Trinity", player) - or state.has("High Jump", player, 3) + state.has("Progressive Glide", player) + or state.has("Progressive Thunder", player) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player)) + or difficulty > LOGIC_NORMAL ) )) - add_rule(kh1world.get_location("Traverse Town Synth Seagull Egg"), + add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Chest)"), lambda state: ( - state.has("Empty Bottle", player, 6) - and - ( - state.has("Green Trinity", player) - or state.has("High Jump", player, 3) - ) + has_key_item(state, player, "Theon Vol. 6", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + or has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) + or (difficulty > LOGIC_NORMAL and state.has("High Jump", player, 2)) )) - add_rule(kh1world.get_location("Traverse Town Synth Fish"), + add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Statue)"), lambda state: ( - state.has("Empty Bottle", player, 6) - and ( - state.has("Green Trinity", player) - or state.has("High Jump", player, 3) + has_key_item(state, player, "Theon Vol. 6", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + or has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) + or (difficulty > LOGIC_NORMAL and state.has("High Jump", player, 2)) ) + and state.has("Red Trinity", player) )) - add_rule(kh1world.get_location("Traverse Town Synth Mushroom"), + add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Fountain)"), lambda state: ( - state.has("Empty Bottle", player, 6) - and - ( - state.has("Green Trinity", player) - or state.has("High Jump", player, 3) - ) + has_key_item(state, player, "Theon Vol. 6", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + or has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3)) + or (difficulty > LOGIC_NORMAL and state.has("High Jump", player, 2)) )) - add_rule(kh1world.get_location("Traverse Town Gizmo Shop Postcard 1"), - lambda state: state.has("Progressive Thunder", player)) - add_rule(kh1world.get_location("Traverse Town Gizmo Shop Postcard 2"), - lambda state: state.has("Progressive Thunder", player)) - add_rule(kh1world.get_location("Traverse Town Item Workshop Postcard"), + add_rule(kh1world.get_location("Hollow Bastion Library Speak to Belle Divine Rose"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) + add_rule(kh1world.get_location("Hollow Bastion Library Speak to Aerith Cure"), + lambda state: has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) + add_rule(kh1world.get_location("Traverse Town 1st District Blue Trinity by Exit Door"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Traverse Town 3rd District Blue Trinity"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Traverse Town Magician's Study Blue Trinity"), lambda state: ( - state.has("Green Trinity", player) - or state.has("High Jump", player, 3) - )) - add_rule(kh1world.get_location("Traverse Town Geppetto's House Postcard"), + state.has_all({ + "Blue Trinity", + "Progressive Fire"}, player) + )) + add_rule(kh1world.get_location("Wonderland Lotus Forest Blue Trinity in Alcove"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Wonderland Lotus Forest Blue Trinity by Moving Boulder"), lambda state: ( - state.has("Monstro", player) - and + state.has("Blue Trinity", player) + and has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + )) + add_rule(kh1world.get_location("Agrabah Bazaar Blue Trinity"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Monstro Mouth Blue Trinity"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Monstro Throat Blue Trinity"), + lambda state: ( + state.has("Blue Trinity", player) + and has_parasite_cage(state, player, difficulty, has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) + )) + add_rule(kh1world.get_location("Monstro Chamber 5 Blue Trinity"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Hollow Bastion Great Crest Blue Trinity"), + lambda state: ( + state.has("Blue Trinity", player) + and has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + )) + add_rule(kh1world.get_location("Hollow Bastion Dungeon Blue Trinity"), + lambda state: state.has("Blue Trinity", player)) + add_rule(kh1world.get_location("Deep Jungle Treetop Green Trinity"), + lambda state: state.has("Green Trinity", player)) + add_rule(kh1world.get_location("Agrabah Cave of Wonders Treasure Room Red Trinity"), + lambda state: state.has("Red Trinity", player)) + add_rule(kh1world.get_location("Wonderland Bizarre Room Examine Flower Pot"), + lambda state: has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Wonderland Lotus Forest Yellow Elixir Flower Through Painting"), + lambda state: has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Wonderland Lotus Forest Red Flower Raise Lily Pads"), + lambda state: has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Wonderland Tea Party Garden Left Cushioned Chair"), + lambda state: ( + has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + or state.has("Progressive Glide", player) + or ( - state.has("High Jump", player) - or (options.advanced_logic and state.has("Progressive Glide", player)) + difficulty > LOGIC_PROUD + and state.has_all_counts({"Combo Master": 1, "High Jump": 3, "Air Combo Plus": 2}, player) ) - and has_x_worlds(state, player, 2, options.keyblades_unlock_chests) )) - add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Flame)"), + add_rule(kh1world.get_location("Wonderland Tea Party Garden Left Pink Chair"), lambda state: ( + has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + or state.has("Progressive Glide", player) + or ( - state.has("Theon Vol. 6", player) - or state.has("High Jump", player, 3) - or has_emblems(state, player, options.keyblades_unlock_chests) + difficulty > LOGIC_PROUD + and state.has_all_counts({"Combo Master": 1, "High Jump": 3, "Air Combo Plus": 2}, player) ) - and state.has("Progressive Fire", player) - and + )) + add_rule(kh1world.get_location("Wonderland Tea Party Garden Right Yellow Chair"), + lambda state: ( + has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + or state.has("Progressive Glide", player) + or ( - state.has("High Jump", player) - or state.has("Progressive Glide", player) - or state.has("Progressive Thunder", player) - or options.advanced_logic + difficulty > LOGIC_PROUD + and state.has_all_counts({"Combo Master": 1, "High Jump": 3, "Air Combo Plus": 2}, player) ) )) - add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Chest)"), + add_rule(kh1world.get_location("Wonderland Tea Party Garden Left Gray Chair"), lambda state: ( - state.has("Theon Vol. 6", player) - or state.has("High Jump", player, 3) - or has_emblems(state, player, options.keyblades_unlock_chests) + has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + or state.has("Progressive Glide", player) + or + ( + difficulty > LOGIC_PROUD + and state.has_all_counts({"Combo Master": 1, "High Jump": 3, "Air Combo Plus": 2}, player) + ) )) - add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Statue)"), + add_rule(kh1world.get_location("Wonderland Tea Party Garden Right Brown Chair"), lambda state: ( + has_key_item(state, player, "Footprints", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + or state.has("Progressive Glide", player) + or ( - state.has("Theon Vol. 6", player) - or state.has("High Jump", player, 3) - or has_emblems(state, player, options.keyblades_unlock_chests) + difficulty > LOGIC_PROUD + and state.has_all_counts({"Combo Master": 1, "High Jump": 3, "Air Combo Plus": 2}, player) ) - and state.has("Red Trinity", player) )) - add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Emblem Piece (Fountain)"), + add_rule(kh1world.get_location("Hollow Bastion Lift Stop from Waterway Examine Node"), lambda state: ( - state.has("Theon Vol. 6", player) - or state.has("High Jump", player, 3) - or has_emblems(state, player, options.keyblades_unlock_chests) + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + or (difficulty > LOGIC_BEGINNER and state.has("High Jump", player, 3) and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_NORMAL and (state.has("High Jump", player, 2) or can_dumbo_skip(state, player)) and state.has("Progressive Glide", player)) + or (difficulty > LOGIC_PROUD and state.has_all({"High Jump", "Progressive Glide"},player)) )) - add_rule(kh1world.get_location("Hollow Bastion Library Speak to Belle Divine Rose"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) - add_rule(kh1world.get_location("Hollow Bastion Library Speak to Aerith Cure"), - lambda state: has_emblems(state, player, options.keyblades_unlock_chests)) + for i in range(1,13): + add_rule(kh1world.get_location("Neverland Clock Tower " + str(i).rjust(2, "0") + ":00 Door"), + lambda state: state.has("Green Trinity", player)) if options.hundred_acre_wood: add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Left Cliff Chest"), lambda state: ( - has_torn_pages(state, player, 4) + state.has("Torn Page", player, 4) and ( - state.has("High Jump", player) - or state.has("Progressive Glide", player) + state.has_all({"High Jump", "Progressive Glide"},player) + or (difficulty > LOGIC_BEGINNER and (state.has("Progressive Glide", player) or state.has("High Jump", player))) + or difficulty > LOGIC_NORMAL ) )) add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Right Tree Alcove Chest"), lambda state: ( - has_torn_pages(state, player, 4) + state.has("Torn Page", player, 4) and ( - state.has("High Jump", player) - or state.has("Progressive Glide", player) + state.has_all({"High Jump", "Progressive Glide"},player) + or (difficulty > LOGIC_BEGINNER and (state.has("Progressive Glide", player) or state.has("High Jump", player))) + or difficulty > LOGIC_NORMAL ) )) add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Under Giant Pot Chest"), - lambda state: has_torn_pages(state, player, 4)) + lambda state: state.has("Torn Page", player, 4)) add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Turn in Rare Nut 1"), - lambda state: has_torn_pages(state, player, 4)) + lambda state: state.has("Torn Page", player, 4)) add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Turn in Rare Nut 2"), lambda state: ( - has_torn_pages(state, player, 4) + state.has("Torn Page", player, 4) and ( - state.has("High Jump", player) - or state.has("Progressive Glide", player) + state.has_all({"High Jump", "Progressive Glide"},player) + or (difficulty > LOGIC_BEGINNER and (state.has("Progressive Glide", player) or state.has("High Jump", player))) + or difficulty > LOGIC_NORMAL ) )) add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Turn in Rare Nut 3"), lambda state: ( - has_torn_pages(state, player, 4) + state.has("Torn Page", player, 4) and ( - state.has("High Jump", player) - or state.has("Progressive Glide", player) + state.has_all({"High Jump", "Progressive Glide"},player) + or (difficulty > LOGIC_BEGINNER and (state.has("Progressive Glide", player) or state.has("High Jump", player))) + or difficulty > LOGIC_NORMAL ) )) add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Turn in Rare Nut 4"), lambda state: ( - has_torn_pages(state, player, 4) + state.has("Torn Page", player, 4) and ( - state.has("High Jump", player) - or state.has("Progressive Glide", player) + state.has_all({"High Jump", "Progressive Glide"},player) + or (difficulty > LOGIC_BEGINNER and (state.has("Progressive Glide", player) or state.has("High Jump", player))) + or difficulty > LOGIC_NORMAL ) )) add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Turn in Rare Nut 5"), lambda state: ( - has_torn_pages(state, player, 4) + state.has("Torn Page", player, 4) and ( - state.has("High Jump", player) - or state.has("Progressive Glide", player) + state.has_all({"High Jump", "Progressive Glide"},player) + or (difficulty > LOGIC_BEGINNER and (state.has("Progressive Glide", player) or state.has("High Jump", player))) + or (difficulty > LOGIC_PROUD and state.has("Combo Master", player)) ) )) add_rule(kh1world.get_location("100 Acre Wood Pooh's House Owl Cheer"), - lambda state: has_torn_pages(state, player, 5)) + lambda state: state.has("Torn Page", player, 5)) add_rule(kh1world.get_location("100 Acre Wood Convert Torn Page 1"), - lambda state: has_torn_pages(state, player, 1)) + lambda state: state.has("Torn Page", player, 1)) add_rule(kh1world.get_location("100 Acre Wood Convert Torn Page 2"), - lambda state: has_torn_pages(state, player, 2)) + lambda state: state.has("Torn Page", player, 2)) add_rule(kh1world.get_location("100 Acre Wood Convert Torn Page 3"), - lambda state: has_torn_pages(state, player, 3)) + lambda state: state.has("Torn Page", player, 3)) add_rule(kh1world.get_location("100 Acre Wood Convert Torn Page 4"), - lambda state: has_torn_pages(state, player, 4)) + lambda state: state.has("Torn Page", player, 4)) add_rule(kh1world.get_location("100 Acre Wood Convert Torn Page 5"), - lambda state: has_torn_pages(state, player, 5)) + lambda state: state.has("Torn Page", player, 5)) add_rule(kh1world.get_location("100 Acre Wood Pooh's House Start Fire"), - lambda state: has_torn_pages(state, player, 3)) + lambda state: state.has("Torn Page", player, 3)) add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Break Log"), - lambda state: has_torn_pages(state, player, 4)) + lambda state: state.has("Torn Page", player, 4)) add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Fall Through Top of Tree Next to Pooh"), lambda state: ( - has_torn_pages(state, player, 4) + state.has("Torn Page", player, 4) and ( - state.has("High Jump", player) - or state.has("Progressive Glide", player) + state.has_all({"High Jump", "Progressive Glide"},player) + or (difficulty > LOGIC_BEGINNER and (state.has("Progressive Glide", player) or state.has("High Jump", player))) + or difficulty > LOGIC_NORMAL ) )) if options.atlantica: add_rule(kh1world.get_location("Atlantica Ursula's Lair Use Fire on Urchin Chest"), lambda state: ( - state.has_all({ - "Progressive Fire", - "Crystal Trident"}, player) + state.has("Progressive Fire", player) + and has_key_item(state, player, "Crystal Trident", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Atlantica Triton's Palace White Trinity Chest"), lambda state: state.has("White Trinity", player)) add_rule(kh1world.get_location("Atlantica Defeat Ursula I Mermaid Kick Event"), lambda state: ( - has_offensive_magic(state, player) - and state.has("Crystal Trident", player) + has_offensive_magic(state, player, difficulty) + and has_key_item(state, player, "Crystal Trident", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Atlantica Defeat Ursula II Thunder Event"), lambda state: ( state.has("Mermaid Kick", player) - and has_offensive_magic(state, player) - and state.has("Crystal Trident", player) + and has_offensive_magic(state, player, difficulty) + and has_key_item(state, player, "Crystal Trident", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Atlantica Seal Keyhole Crabclaw Event"), lambda state: ( state.has("Mermaid Kick", player) - and has_offensive_magic(state, player) - and state.has("Crystal Trident", player) + and has_offensive_magic(state, player, difficulty) + and has_key_item(state, player, "Crystal Trident", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Atlantica Undersea Gorge Blizzard Clam"), lambda state: state.has("Progressive Blizzard", player)) @@ -1237,721 +1379,411 @@ def set_rules(kh1world): add_rule(kh1world.get_location("Atlantica Triton's Palace Thunder Clam"), lambda state: state.has("Progressive Thunder", player)) add_rule(kh1world.get_location("Atlantica Cavern Nook Clam"), - lambda state: state.has("Crystal Trident", player)) + lambda state: has_key_item(state, player, "Crystal Trident", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) add_rule(kh1world.get_location("Atlantica Defeat Ursula II Ansem's Report 3"), lambda state: ( - state.has_all({ - "Mermaid Kick", - "Crystal Trident"}, player) - and has_offensive_magic(state, player) - )) - if options.cups: - add_rule(kh1world.get_location("Olympus Coliseum Defeat Hades Ansem's Report 8"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) + state.has("Mermaid Kick", player) + and has_key_item(state, player, "Crystal Trident", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_offensive_magic(state, player, difficulty) )) + if options.cups.current_key != "off": + if options.cups.current_key == "hades_cup": + add_rule(kh1world.get_location("Olympus Coliseum Defeat Hades Ansem's Report 8"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) add_rule(kh1world.get_location("Complete Phil Cup"), lambda state: ( - state.has_all({ - "Phil Cup", - "Entry Pass"}, player) + state.has("Phil Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Complete Phil Cup Solo"), lambda state: ( - state.has_all({ - "Phil Cup", - "Entry Pass"}, player) + state.has("Phil Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Complete Phil Cup Time Trial"), lambda state: ( - state.has_all({ - "Phil Cup", - "Entry Pass"}, player) + state.has("Phil Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Complete Pegasus Cup"), lambda state: ( - state.has_all({ - "Pegasus Cup", - "Entry Pass"}, player) + state.has("Pegasus Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Complete Pegasus Cup Solo"), lambda state: ( - state.has_all({ - "Pegasus Cup", - "Entry Pass"}, player) + state.has("Pegasus Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Complete Pegasus Cup Time Trial"), lambda state: ( - state.has_all({ - "Pegasus Cup", - "Entry Pass"}, player) + state.has("Pegasus Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) )) add_rule(kh1world.get_location("Complete Hercules Cup"), lambda state: ( - state.has_all({ - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) + state.has("Hercules Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) )) add_rule(kh1world.get_location("Complete Hercules Cup Solo"), lambda state: ( - state.has_all({ - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) + state.has("Hercules Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) )) add_rule(kh1world.get_location("Complete Hercules Cup Time Trial"), lambda state: ( - state.has_all({ - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) - )) - add_rule(kh1world.get_location("Complete Hades Cup"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) - )) - add_rule(kh1world.get_location("Complete Hades Cup Solo"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) - )) - add_rule(kh1world.get_location("Complete Hades Cup Time Trial"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) - )) - add_rule(kh1world.get_location("Hades Cup Defeat Cloud and Leon Event"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) - )) - add_rule(kh1world.get_location("Hades Cup Defeat Yuffie Event"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) - )) - add_rule(kh1world.get_location("Hades Cup Defeat Cerberus Event"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) - )) - add_rule(kh1world.get_location("Hades Cup Defeat Behemoth Event"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) - )) - add_rule(kh1world.get_location("Hades Cup Defeat Hades Event"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) + state.has("Hercules Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) )) add_rule(kh1world.get_location("Hercules Cup Defeat Cloud Event"), lambda state: ( - state.has_all({ - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) + state.has("Hercules Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) )) add_rule(kh1world.get_location("Hercules Cup Yellow Trinity Event"), lambda state: ( - state.has_all({ - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) - )) - add_rule(kh1world.get_location("Olympus Coliseum Defeat Ice Titan Diamond Dust Event"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass", - "Guard"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) - )) - add_rule(kh1world.get_location("Olympus Coliseum Gates Purple Jar After Defeating Hades"), - lambda state: ( - state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) + state.has("Hercules Cup", player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) )) + if options.cups.current_key == "hades_cup": + add_rule(kh1world.get_location("Complete Hades Cup"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) + add_rule(kh1world.get_location("Complete Hades Cup Solo"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) + add_rule(kh1world.get_location("Complete Hades Cup Time Trial"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) + add_rule(kh1world.get_location("Hades Cup Defeat Cloud and Leon Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) + add_rule(kh1world.get_location("Hades Cup Defeat Yuffie Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) + add_rule(kh1world.get_location("Hades Cup Defeat Cerberus Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) + add_rule(kh1world.get_location("Hades Cup Defeat Behemoth Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) + add_rule(kh1world.get_location("Hades Cup Defeat Hades Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) + add_rule(kh1world.get_location("Olympus Coliseum Gates Purple Jar After Defeating Hades"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) + if options.cups.current_key == "hades_cup" and options.super_bosses: + add_rule(kh1world.get_location("Olympus Coliseum Defeat Ice Titan Diamond Dust Event"), + lambda state: ( + state.has_all({ + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and (state.has("Guard", player) or difficulty > LOGIC_PROUD) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + )) add_rule(kh1world.get_location("Olympus Coliseum Olympia Chest"), lambda state: ( state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 4, options.keyblades_unlock_chests) - )) + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 4, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + )) if options.super_bosses: add_rule(kh1world.get_location("Neverland Defeat Phantom Stop Event"), lambda state: ( state.has("Green Trinity", player) - and has_all_magic_lvx(state, player, 2) - and has_defensive_tools(state, player) - and has_emblems(state, player, options.keyblades_unlock_chests) + and has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and + ( + has_all_magic_lvx(state, player, 3) + or (difficulty > LOGIC_BEGINNER and has_all_magic_lvx(state, player, 2)) + or (difficulty > LOGIC_NORMAL and state.has_all({"Progressive Fire", "Progressive Blizzard", "Progressive Thunder", "Progressive Stop"}, player)) + or + ( + difficulty > LOGIC_PROUD + and state.has_any({"Progressive Fire","Progressive Blizzard"}, player) + and state.has_any({"Progressive Fire","Progressive Thunder"}, player) + and state.has_any({"Progressive Thunder","Progressive Blizzard"}, player) + and state.has("Progressive Stop", player) + ) + ) + and (state.has("Leaf Bracer", player) or difficulty > LOGIC_NORMAL) )) add_rule(kh1world.get_location("Agrabah Defeat Kurt Zisa Ansem's Report 11"), lambda state: ( - has_emblems(state, player, options.keyblades_unlock_chests) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) - and state.has("Progressive Blizzard", player, 3) + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + and + ( + state.has("Progressive Blizzard", player, 3) + or (difficulty > LOGIC_BEGINNER and state.has_any_count({"Progressive Blizzard": 2, "Progressive Fire": 3,"Progressive Thunder": 3, "Progressive Gravity": 3}, player)) + or (difficulty > LOGIC_NORMAL and (state.has_any_count({"Progressive Blizzard": 1, "Progressive Fire": 2, "Progressive Thunder": 2, "Progressive Gravity": 2}, player))) + or (difficulty > LOGIC_PROUD and (state.has_any({"Progressive Fire", "Progressive Thunder", "Progressive Gravity"}, player) or (state.has_group("Magic", player) and state.has_all({"Mushu", "Genie", "Dumbo"}, player)))) + ) )) add_rule(kh1world.get_location("Agrabah Defeat Kurt Zisa Zantetsuken Event"), lambda state: ( - has_emblems(state, player, options.keyblades_unlock_chests) and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) and has_defensive_tools(state, player) and state.has("Progressive Blizzard", player, 3) + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + and + ( + state.has("Progressive Blizzard", player, 3) + or (difficulty > LOGIC_BEGINNER and state.has_any_count({"Progressive Blizzard": 2, "Progressive Fire": 3,"Progressive Thunder": 3, "Progressive Gravity": 3}, player)) + or (difficulty > LOGIC_NORMAL and (state.has_any_count({"Progressive Blizzard": 1, "Progressive Fire": 2, "Progressive Thunder": 2, "Progressive Gravity": 2}, player))) + or (difficulty > LOGIC_PROUD and (state.has_any({"Progressive Fire", "Progressive Thunder", "Progressive Gravity"}, player) or (state.has_group("Magic", player) and state.has_all({"Mushu", "Genie", "Dumbo"}, player)))) + ) )) - if options.super_bosses or options.goal.current_key == "sephiroth": + if options.super_bosses or options.final_rest_door_key.current_key == "sephiroth": add_rule(kh1world.get_location("Olympus Coliseum Defeat Sephiroth Ansem's Report 12"), lambda state: ( state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) )) add_rule(kh1world.get_location("Olympus Coliseum Defeat Sephiroth One-Winged Angel Event"), lambda state: ( state.has_all({ - "Phil Cup", - "Pegasus Cup", - "Hercules Cup", - "Entry Pass"}, player) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) + "Phil Cup", + "Pegasus Cup", + "Hercules Cup"}, player) + and has_key_item(state, player, "Entry Pass", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) )) - if options.super_bosses or options.goal.current_key == "unknown": + if options.super_bosses or options.final_rest_door_key.current_key == "unknown": add_rule(kh1world.get_location("Hollow Bastion Defeat Unknown Ansem's Report 13"), lambda state: ( - has_emblems(state, player, options.keyblades_unlock_chests) - and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + and (difficulty > LOGIC_BEGINNER or state.has("Progressive Gravity", player)) )) add_rule(kh1world.get_location("Hollow Bastion Defeat Unknown EXP Necklace Event"), lambda state: ( - has_emblems(state, player, options.keyblades_unlock_chests) and has_x_worlds(state, player, 7, options.keyblades_unlock_chests) - and has_defensive_tools(state, player) + has_emblems(state, player, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + and has_defensive_tools(state, player, difficulty) + and (difficulty > LOGIC_BEGINNER or state.has("Progressive Gravity", player)) )) - for i in range(options.level_checks): - add_rule(kh1world.get_location("Level " + str(i+1).rjust(3,'0')), + if options.jungle_slider: + add_rule(kh1world.get_location("Deep Jungle Jungle Slider 10 Fruits"), + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Deep Jungle Jungle Slider 20 Fruits"), + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Deep Jungle Jungle Slider 30 Fruits"), + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Deep Jungle Jungle Slider 40 Fruits"), + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + add_rule(kh1world.get_location("Deep Jungle Jungle Slider 50 Fruits"), + lambda state: has_key_item(state, player, "Slides", stacking_world_items, halloween_town_key_item_bundle, difficulty, options.keyblades_unlock_chests)) + if options.destiny_islands: + add_rule(kh1world.get_location("Destiny Islands Seashore Capture Fish 1 (Day 2)"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + add_rule(kh1world.get_location("Destiny Islands Seashore Capture Fish 2 (Day 2)"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + add_rule(kh1world.get_location("Destiny Islands Seashore Capture Fish 3 (Day 2)"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + add_rule(kh1world.get_location("Destiny Islands Seashore Gather Seagull Egg (Day 2)"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + add_rule(kh1world.get_location("Destiny Islands Secret Place Gather Mushroom (Day 2)"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + add_rule(kh1world.get_location("Destiny Islands Cove Gather Mushroom Near Zip Line (Day 2)"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + add_rule(kh1world.get_location("Destiny Islands Cove Gather Mushroom in Small Cave (Day 2)"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + #add_rule(kh1world.get_location("Destiny Islands Seashore Deliver Kairi Items (Day 1)"), + # lambda state: state.has("Raft Materials", player, day_2_materials)) + add_rule(kh1world.get_location("Destiny Islands Secret Place Gather Mushroom (Day 2)"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + add_rule(kh1world.get_location("Destiny Islands Cove Talk to Kairi (Day 2)"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + add_rule(kh1world.get_location("Destiny Islands Gather Drinking Water (Day 2)"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + add_rule(kh1world.get_location("Destiny Islands Chest"), + lambda state: state.has("Raft Materials", player, day_2_materials)) + #add_rule(kh1world.get_location("Destiny Islands Cove Deliver Kairi Items (Day 2)"), + # lambda state: state.has("Raft Materials", player, homecoming_materials)) + for i in range(1,options.level_checks+1): + add_rule(kh1world.get_location("Level " + str(i+1).rjust(3,'0') + " (Slot 1)"), lambda state, level_num=i: ( - has_x_worlds(state, player, min(((level_num//10)*2), 8), options.keyblades_unlock_chests) - )) - if options.goal.current_key == "final_ansem": - add_rule(kh1world.get_location("Final Ansem"), - lambda state: ( - has_final_rest_door(state, player, final_rest_door_requirement, final_rest_door_required_reports, options.keyblades_unlock_chests, options.puppies) + has_x_worlds(state, player, min(((level_num//10)*2), 8), options.keyblades_unlock_chests, difficulty, hundred_acre_wood) )) - if options.keyblades_unlock_chests: - add_rule(kh1world.get_location("Traverse Town 1st District Candle Puzzle Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town 1st District Accessory Shop Roof Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town 2nd District Boots and Shoes Awning Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town 2nd District Rooftop Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town 2nd District Gizmo Shop Facade Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Alleyway Balcony Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Alleyway Blue Room Awning Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Alleyway Corner Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Green Room Clock Puzzle Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Green Room Table Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Red Room Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Mystical House Yellow Trinity Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Accessory Shop Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Secret Waterway White Trinity Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Geppetto's House Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Item Workshop Right Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town 1st District Blue Trinity Balcony Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Mystical House Glide Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Alleyway Behind Crates Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Item Workshop Left Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Traverse Town Secret Waterway Near Stairs Chest"), - lambda state: state.has("Lionheart", player)) - add_rule(kh1world.get_location("Wonderland Rabbit Hole Green Trinity Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Rabbit Hole Defeat Heartless 1 Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Rabbit Hole Defeat Heartless 2 Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Rabbit Hole Defeat Heartless 3 Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Bizarre Room Green Trinity Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Left Red Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Right Blue Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Queen's Castle Hedge Right Red Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Lotus Forest Thunder Plant Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Lotus Forest Through the Painting Thunder Plant Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Lotus Forest Glide Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Lotus Forest Nut Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Lotus Forest Corner Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Bizarre Room Lamp Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Tea Party Garden Above Lotus Forest Entrance 2nd Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Tea Party Garden Above Lotus Forest Entrance 1st Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Tea Party Garden Bear and Clock Puzzle Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Tea Party Garden Across From Bizarre Room Entrance Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Wonderland Lotus Forest Through the Painting White Trinity Chest"), - lambda state: state.has("Lady Luck", player)) - add_rule(kh1world.get_location("Deep Jungle Tree House Beneath Tree House Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Tree House Rooftop Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Hippo's Lagoon Center Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Hippo's Lagoon Left Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Hippo's Lagoon Right Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Vines Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Vines 2 Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Climbing Trees Blue Trinity Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Tunnel Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Cavern of Hearts White Trinity Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Camp Blue Trinity Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Tent Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern Low Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern Middle Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern High Wall Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Waterfall Cavern High Middle Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Cliff Right Cliff Left Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Cliff Right Cliff Right Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Deep Jungle Tree House Suspended Boat Chest"), - lambda state: state.has("Jungle King", player)) - add_rule(kh1world.get_location("Agrabah Plaza By Storage Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Plaza Raised Terrace Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Plaza Top Corner Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Alley Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Bazaar Across Windows Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Bazaar High Corner Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Main Street Right Palace Entrance Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Main Street High Above Alley Entrance Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Main Street High Above Palace Gates Entrance Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Palace Gates Low Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Palace Gates High Opposite Palace Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Palace Gates High Close to Palace Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Storage Green Trinity Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Storage Behind Barrel Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Entrance Left Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Entrance Tall Tower Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Hall High Left Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Hall Near Bottomless Hall Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Bottomless Hall Raised Platform Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Bottomless Hall Pillar Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Bottomless Hall Across Chasm Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Treasure Room Across Platforms Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Treasure Room Small Treasure Pile Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Treasure Room Large Treasure Pile Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Treasure Room Above Fire Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Relic Chamber Jump from Stairs Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Relic Chamber Stairs Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Dark Chamber Abu Gem Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Dark Chamber Across from Relic Chamber Entrance Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Dark Chamber Bridge Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Dark Chamber Near Save Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Silent Chamber Blue Trinity Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Hidden Room Right Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Hidden Room Left Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Aladdin's House Main Street Entrance Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Aladdin's House Plaza Entrance Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Agrabah Cave of Wonders Entrance White Trinity Chest"), - lambda state: state.has("Three Wishes", player)) - add_rule(kh1world.get_location("Monstro Chamber 6 Other Platform Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 6 Platform Near Chamber 5 Entrance Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 6 Raised Area Near Chamber 1 Entrance Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 6 Low Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Halloween Town Moonlight Hill White Trinity Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Bridge Under Bridge"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Boneyard Tombstone Puzzle Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Bridge Right of Gate Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Cemetery Behind Grave Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Cemetery By Cat Shape Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Cemetery Between Graves Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Oogie's Manor Lower Iron Cage Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Oogie's Manor Upper Iron Cage Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Oogie's Manor Hollow Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Oogie's Manor Grounds Red Trinity Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Guillotine Square High Tower Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Guillotine Square Pumpkin Structure Left Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Oogie's Manor Entrance Steps Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Oogie's Manor Inside Entrance Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Bridge Left of Gate Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Cemetery By Striped Grave Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Guillotine Square Under Jack's House Stairs Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Halloween Town Guillotine Square Pumpkin Structure Right Chest"), - lambda state: state.has("Pumpkinhead", player)) - add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Left Behind Columns Chest"), - lambda state: state.has("Olympia", player)) - add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Right Blue Trinity Chest"), - lambda state: state.has("Olympia", player)) - add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Left Blue Trinity Chest"), - lambda state: state.has("Olympia", player)) - add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates White Trinity Chest"), - lambda state: state.has("Olympia", player)) - add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Blizzara Chest"), - lambda state: state.has("Olympia", player)) - add_rule(kh1world.get_location("Olympus Coliseum Coliseum Gates Blizzaga Chest"), - lambda state: state.has("Olympia", player)) - add_rule(kh1world.get_location("Monstro Mouth Boat Deck Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Mouth High Platform Boat Side Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Mouth High Platform Across from Boat Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Mouth Near Ship Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Mouth Green Trinity Top of Boat Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 2 Ground Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 2 Platform Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 5 Platform Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 3 Ground Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 3 Platform Above Chamber 2 Entrance Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 3 Near Chamber 6 Entrance Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 3 Platform Near Chamber 6 Entrance Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Mouth High Platform Near Teeth Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 5 Atop Barrel Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 5 Low 2nd Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Monstro Chamber 5 Low 1st Chest"), - lambda state: state.has("Wishing Star", player)) - add_rule(kh1world.get_location("Neverland Pirate Ship Deck White Trinity Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Neverland Pirate Ship Crows Nest Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Neverland Hold Yellow Trinity Right Blue Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Neverland Hold Yellow Trinity Left Blue Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Neverland Galley Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Neverland Cabin Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Neverland Hold Flight 1st Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Neverland Clock Tower Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Neverland Hold Flight 2nd Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Neverland Hold Yellow Trinity Green Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Neverland Captain's Cabin Chest"), - lambda state: state.has("Fairy Harp", player)) - add_rule(kh1world.get_location("Hollow Bastion Rising Falls Water's Surface Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Rising Falls Under Water 1st Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Rising Falls Under Water 2nd Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Rising Falls Floating Platform Near Save Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Rising Falls Floating Platform Near Bubble Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Rising Falls High Platform Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Castle Gates Gravity Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Castle Gates Freestanding Pillar Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Castle Gates High Pillar Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Great Crest Lower Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Great Crest After Battle Platform Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion High Tower 2nd Gravity Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion High Tower 1st Gravity Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion High Tower Above Sliding Blocks Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Library Top of Bookshelf Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Lift Stop Library Node After High Tower Switch Gravity Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Lift Stop Library Node Gravity Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Lift Stop Under High Tower Sliding Blocks Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Lift Stop Outside Library Gravity Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Lift Stop Heartless Sigil Door Gravity Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Base Level Bubble Under the Wall Platform Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Base Level Platform Near Entrance Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Base Level Near Crystal Switch Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Waterway Near Save Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Waterway Blizzard on Bubble Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Waterway Unlock Passage from Base Level Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Dungeon By Candles Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Dungeon Corner Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Grand Hall Steps Right Side Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Grand Hall Oblivion Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Grand Hall Left of Gate Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Entrance Hall Left of Emblem Door Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("Hollow Bastion Rising Falls White Trinity Chest"), - lambda state: state.has("Divine Rose", player)) - add_rule(kh1world.get_location("End of the World Final Dimension 1st Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Final Dimension 2nd Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Final Dimension 3rd Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Final Dimension 4th Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Final Dimension 5th Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Final Dimension 6th Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Final Dimension 10th Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Final Dimension 9th Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Final Dimension 8th Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Final Dimension 7th Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Giant Crevasse 3rd Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Giant Crevasse 5th Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Giant Crevasse 1st Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Giant Crevasse 4th Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Giant Crevasse 2nd Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World World Terminus Traverse Town Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World World Terminus Wonderland Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World World Terminus Olympus Coliseum Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World World Terminus Deep Jungle Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World World Terminus Agrabah Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World World Terminus Halloween Town Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World World Terminus Neverland Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World World Terminus 100 Acre Wood Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("End of the World Final Rest Chest"), - lambda state: state.has("Oblivion", player)) - add_rule(kh1world.get_location("Monstro Chamber 6 White Trinity Chest"), - lambda state: state.has("Oblivion", player)) - if options.hundred_acre_wood: - add_rule(kh1world.get_location("100 Acre Wood Meadow Inside Log Chest"), - lambda state: state.has("Oathkeeper", player)) - add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Left Cliff Chest"), - lambda state: state.has("Oathkeeper", player)) - add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Right Tree Alcove Chest"), - lambda state: state.has("Oathkeeper", player)) - add_rule(kh1world.get_location("100 Acre Wood Bouncing Spot Under Giant Pot Chest"), - lambda state: state.has("Oathkeeper", player)) - + if i+1 in kh1world.get_slot_2_levels(): + add_rule(kh1world.get_location("Level " + str(i+1).rjust(3,'0') + " (Slot 2)"), + lambda state, level_num=i: ( + has_x_worlds(state, player, min(((level_num//10)*2), 8), options.keyblades_unlock_chests, difficulty, hundred_acre_wood) + )) + add_rule(kh1world.get_location("Final Ansem"), + lambda state: ( + has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) # In logic, player is strong enough + and + ( + ( # Can DI Finish + state.has("Destiny Islands", player) + and state.has("Raft Materials", player, homecoming_materials) + ) + or + ( + ( # Has access to EotW + ( + has_lucky_emblems(state, player, eotw_required_lucky_emblems) + and end_of_the_world_unlock == "lucky_emblems" + ) + or state.has("End of the World", player) + ) + and has_final_rest_door(state, player, final_rest_door_requirement, final_rest_door_required_lucky_emblems) # Can open the Door + ) + ) + and has_defensive_tools(state, player, difficulty) + )) + for location in location_table.keys(): + try: + kh1world.get_location(location) + except KeyError: + continue + if difficulty == LOGIC_BEGINNER and location_table[location].behind_boss: + add_rule(kh1world.get_location(location), + lambda state: has_basic_tools(state, player)) + if options.remote_items.current_key == "off": + if location_table[location].type == "Static": + add_item_rule(kh1world.get_location(location), + lambda i: (i.player != player or item_table[i.name].type == "Item")) + if location_table[location].type == "Level Slot 1": + add_item_rule(kh1world.get_location(location), + lambda i: (i.player != player or item_table[i.name].category in ["Level Up", "Limited Level Up"])) + if location_table[location].type == "Level Slot 2": + add_item_rule(kh1world.get_location(location), + lambda i: (i.player != player or (item_table[i.name].category in ["Level Up", "Limited Level Up"] or item_table[i.name].type == "Ability"))) + if location_table[location].type == "Synth": + add_item_rule(kh1world.get_location(location), + lambda i: (i.player != player or (item_table[i.name].type == "Item"))) + if location_table[location].type == "Prize": + add_item_rule(kh1world.get_location(location), + lambda i: (i.player != player or (item_table[i.name].type == "Item"))) + if options.keyblades_unlock_chests: + if location_table[location].type == "Chest" or location in BROKEN_KEYBLADE_LOCKING_LOCATIONS: + location_world = location_table[location].category + location_required_keyblade = KEYBLADES[WORLDS.index(location_world)] + if location not in BROKEN_KEYBLADE_LOCKING_LOCATIONS: + add_rule(kh1world.get_location(location), + lambda state, location_required_keyblade = location_required_keyblade: state.has(location_required_keyblade, player)) + else: + add_rule(kh1world.get_location(location), + lambda state, location_required_keyblade = location_required_keyblade: state.has(location_required_keyblade, player) or difficulty > LOGIC_BEGINNER) + + if options.destiny_islands: + add_rule(kh1world.get_entrance("Destiny Islands"), + lambda state: state.has("Destiny Islands", player)) add_rule(kh1world.get_entrance("Wonderland"), - lambda state: state.has("Wonderland", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + lambda state: state.has("Wonderland", player) and has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_entrance("Olympus Coliseum"), - lambda state: state.has("Olympus Coliseum", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + lambda state: state.has("Olympus Coliseum", player) and has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_entrance("Deep Jungle"), - lambda state: state.has("Deep Jungle", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + lambda state: state.has("Deep Jungle", player) and has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_entrance("Agrabah"), - lambda state: state.has("Agrabah", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + lambda state: state.has("Agrabah", player) and has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_entrance("Monstro"), - lambda state: state.has("Monstro", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + lambda state: state.has("Monstro", player) and has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) if options.atlantica: add_rule(kh1world.get_entrance("Atlantica"), - lambda state: state.has("Atlantica", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + lambda state: state.has("Atlantica", player) and has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_entrance("Halloween Town"), - lambda state: state.has("Halloween Town", player) and has_x_worlds(state, player, 2, options.keyblades_unlock_chests)) + lambda state: state.has("Halloween Town", player) and has_x_worlds(state, player, 3, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_entrance("Neverland"), - lambda state: state.has("Neverland", player) and has_x_worlds(state, player, 3, options.keyblades_unlock_chests)) + lambda state: state.has("Neverland", player) and has_x_worlds(state, player, 4, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_entrance("Hollow Bastion"), - lambda state: state.has("Hollow Bastion", player) and has_x_worlds(state, player, 5, options.keyblades_unlock_chests)) + lambda state: state.has("Hollow Bastion", player) and has_x_worlds(state, player, 6, options.keyblades_unlock_chests, difficulty, hundred_acre_wood)) add_rule(kh1world.get_entrance("End of the World"), - lambda state: has_x_worlds(state, player, 7, options.keyblades_unlock_chests) and (has_reports(state, player, eotw_required_reports) or state.has("End of the World", player))) + lambda state: has_x_worlds(state, player, 8, options.keyblades_unlock_chests, difficulty, hundred_acre_wood) and ((has_lucky_emblems(state, player, eotw_required_lucky_emblems) and end_of_the_world_unlock == "lucky_emblems") or state.has("End of the World", player))) add_rule(kh1world.get_entrance("100 Acre Wood"), lambda state: state.has("Progressive Fire", player)) diff --git a/worlds/kh1/__init__.py b/worlds/kh1/__init__.py index ac0afca50142..f14f6ea341e3 100644 --- a/worlds/kh1/__init__.py +++ b/worlds/kh1/__init__.py @@ -1,23 +1,29 @@ import logging +import re from typing import List +from math import ceil from BaseClasses import Tutorial from worlds.AutoWorld import WebWorld, World from .Items import KH1Item, KH1ItemData, event_item_table, get_items_by_category, item_table, item_name_groups -from .Locations import KH1Location, location_table, get_locations_by_category, location_name_groups +from .Locations import KH1Location, location_table, get_locations_by_type, location_name_groups from .Options import KH1Options, kh1_option_groups from .Regions import connect_entrances, create_regions from .Rules import set_rules from .Presets import kh1_option_presets -from worlds.LauncherComponents import Component, components, Type, launch as launch_component - +from worlds.LauncherComponents import Component, components, Type, launch as launch_component, icon_paths +from .GenerateJSON import generate_json +from .Data import VANILLA_KEYBLADE_STATS, VANILLA_PUPPY_LOCATIONS, CHAR_TO_KH, VANILLA_ABILITY_AP_COSTS, WORLD_KEY_ITEMS +from worlds.LauncherComponents import Component, components, Type, launch_subprocess def launch_client(): from .Client import launch launch_component(launch, name="KH1 Client") -components.append(Component("KH1 Client", "KH1Client", func=launch_client, component_type=Type.CLIENT)) +components.append(Component("KH1 Client", "KH1Client", func=launch_client, component_type=Type.CLIENT, icon="kh1_heart")) + +icon_paths["kh1_heart"] = f"ap:{__name__}/icons/kh1_heart.png" class KH1Web(WebWorld): @@ -54,6 +60,19 @@ class KH1World(World): fillers.update(get_items_by_category("Item")) fillers.update(get_items_by_category("Camping")) fillers.update(get_items_by_category("Stat Ups")) + slot_2_levels: list[int] + keyblade_stats: list[dict[str, int]] + starting_accessory_locations: list[str] + starting_accessories: list[str] + ap_costs: list[dict[str, str | int | bool]] + + def __init__(self, multiworld, player): + super(KH1World, self).__init__(multiworld, player) + self.slot_2_levels = None + self.keyblade_stats = None + self.starting_accessory_locations = None + self.starting_accessories = None + self.ap_costs = None def create_items(self): self.place_predetermined_items() @@ -63,12 +82,29 @@ def create_items(self): possible_starting_worlds = ["Wonderland", "Olympus Coliseum", "Deep Jungle", "Agrabah", "Monstro", "Halloween Town", "Neverland", "Hollow Bastion"] if self.options.atlantica: possible_starting_worlds.append("Atlantica") + if self.options.destiny_islands: + possible_starting_worlds.append("Destiny Islands") if self.options.end_of_the_world_unlock == "item": possible_starting_worlds.append("End of the World") starting_worlds = self.random.sample(possible_starting_worlds, min(self.options.starting_worlds.value, len(possible_starting_worlds))) for starting_world in starting_worlds: self.multiworld.push_precollected(self.create_item(starting_world)) + # Handle starting tools + starting_tools = [] + if self.options.starting_tools: + starting_tools = ["Scan", "Dodge Roll"] + self.multiworld.push_precollected(self.create_item("Scan")) + self.multiworld.push_precollected(self.create_item("Dodge Roll")) + + # Handle starting party member accessories + starting_party_member_accessories = [] + starting_party_member_locations = [] + starting_party_member_locations = self.get_starting_accessory_locations() + starting_party_member_accessories = self.get_starting_accessories() + for i in range(len(starting_party_member_locations)): + self.get_location(self.starting_accessory_locations[i]).place_locked_item(self.create_item(self.starting_accessories[i])) + item_pool: List[KH1Item] = [] possible_level_up_item_pool = [] level_up_item_pool = [] @@ -94,19 +130,26 @@ def create_items(self): # Fill remaining pool with items from other pool self.random.shuffle(possible_level_up_item_pool) - level_up_item_pool = level_up_item_pool + possible_level_up_item_pool[:(100 - len(level_up_item_pool))] - - level_up_locations = list(get_locations_by_category("Levels").keys()) + level_up_item_pool = level_up_item_pool + possible_level_up_item_pool[:(99 - len(level_up_item_pool))] + + level_up_locations = list(get_locations_by_type("Level Slot 1").keys()) self.random.shuffle(level_up_item_pool) - current_level_for_placing_stats = self.options.force_stats_on_levels.value - while len(level_up_item_pool) > 0 and current_level_for_placing_stats <= self.options.level_checks: - self.get_location(level_up_locations[current_level_for_placing_stats - 1]).place_locked_item(self.create_item(level_up_item_pool.pop())) - current_level_for_placing_stats += 1 + current_level_index_for_placing_stats = self.options.force_stats_on_levels.value - 2 # Level 2 is index 0, Level 3 is index 1, etc + if self.options.remote_items.current_key == "off" and self.options.force_stats_on_levels.value != 2: + logging.info(f"{self.player_name}'s value {self.options.force_stats_on_levels.value} for force_stats_on_levels was changed\n" + f"Set to 2 as remote_items if \"off\"") + self.options.force_stats_on_levels.value = 2 + current_level_index_for_placing_stats = 0 + while len(level_up_item_pool) > 0 and current_level_index_for_placing_stats < self.options.level_checks: # With all levels in location pool, 99 level ups so need to go index 0-98 + self.get_location(level_up_locations[current_level_index_for_placing_stats]).place_locked_item(self.create_item(level_up_item_pool.pop())) + current_level_index_for_placing_stats += 1 + + # Calculate prefilled locations and items - prefilled_items = [] - if self.options.vanilla_emblem_pieces: - prefilled_items = prefilled_items + ["Emblem Piece (Flame)", "Emblem Piece (Chest)", "Emblem Piece (Fountain)", "Emblem Piece (Statue)"] + exclude_items = ["Final Door Key", "Lucky Emblem"] + if not self.options.randomize_emblem_pieces: + exclude_items = exclude_items + ["Emblem Piece (Flame)", "Emblem Piece (Chest)", "Emblem Piece (Fountain)", "Emblem Piece (Statue)"] total_locations = len(self.multiworld.get_unfilled_locations(self.player)) @@ -117,27 +160,29 @@ def create_items(self): quantity = data.max_quantity if data.category not in non_filler_item_categories: continue - if name in starting_worlds: + if name in starting_worlds or name in starting_tools or name in starting_party_member_accessories: continue - if data.category == "Puppies": - if self.options.puppies == "triplets" and "-" in name: - item_pool += [self.create_item(name) for _ in range(quantity)] - if self.options.puppies == "individual" and "Puppy" in name: - item_pool += [self.create_item(name) for _ in range(0, quantity)] - if self.options.puppies == "full" and name == "All Puppies": - item_pool += [self.create_item(name) for _ in range(0, quantity)] + if self.options.stacking_world_items and name in WORLD_KEY_ITEMS.keys() and name not in ("Crystal Trident", "Jack-In-The-Box"): # Handling these special cases separately + item_pool += [self.create_item(WORLD_KEY_ITEMS[name]) for _ in range(0, 1)] + elif self.options.halloween_town_key_item_bundle and name == "Jack-In-The-Box": + continue + elif name == "Puppy": + if self.options.randomize_puppies: + item_pool += [self.create_item(name) for _ in range(ceil(99/self.options.puppy_value.value))] elif name == "Atlantica": if self.options.atlantica: item_pool += [self.create_item(name) for _ in range(0, quantity)] elif name == "Mermaid Kick": + if self.options.atlantica and self.options.extra_shared_abilities: + item_pool += [self.create_item(name) for _ in range(0, 2)] + else: + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name == "Crystal Trident": if self.options.atlantica: - if self.options.extra_shared_abilities: - item_pool += [self.create_item(name) for _ in range(0, 2)] + if self.options.stacking_world_items: + item_pool += [self.create_item(WORLD_KEY_ITEMS[name]) for _ in range(0, 1)] else: item_pool += [self.create_item(name) for _ in range(0, quantity)] - elif name == "Crystal Trident": - if self.options.atlantica: - item_pool += [self.create_item(name) for _ in range(0, quantity)] elif name == "High Jump": if self.options.extra_shared_abilities: item_pool += [self.create_item(name) for _ in range(0, 3)] @@ -154,11 +199,26 @@ def create_items(self): elif name == "EXP Zero": if self.options.exp_zero_in_pool: item_pool += [self.create_item(name) for _ in range(0, quantity)] - elif name not in prefilled_items: + elif name == "Postcard": + if self.options.randomize_postcards.current_key == "chests": + item_pool += [self.create_item(name) for _ in range(0, 3)] + if self.options.randomize_postcards.current_key == "all": + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name == "Orichalcum": + item_pool += [self.create_item(name) for _ in range(0, self.options.orichalcum_in_pool.value)] + elif name == "Mythril": + item_pool += [self.create_item(name) for _ in range(0, self.options.mythril_in_pool.value)] + elif name == "Destiny Islands": + if self.options.destiny_islands: + item_pool += [self.create_item(name) for _ in range(0, quantity)] + elif name == "Raft Materials": + if self.options.destiny_islands: + item_pool += [self.create_item(name) for _ in range(0, self.options.materials_in_pool.value)] + elif name not in exclude_items: item_pool += [self.create_item(name) for _ in range(0, quantity)] - for i in range(self.determine_reports_in_pool()): - item_pool += [self.create_item("Ansem's Report " + str(i+1))] + for i in range(self.determine_lucky_emblems_in_pool()): + item_pool += [self.create_item("Lucky Emblem")] while len(item_pool) < total_locations and len(level_up_item_pool) > 0: item_pool += [self.create_item(level_up_item_pool.pop())] @@ -170,63 +230,117 @@ def create_items(self): self.multiworld.itempool += item_pool def place_predetermined_items(self) -> None: - goal_dict = { - "sephiroth": "Olympus Coliseum Defeat Sephiroth Ansem's Report 12", - "unknown": "Hollow Bastion Defeat Unknown Ansem's Report 13", - "postcards": "Traverse Town Mail Postcard 10 Event", - "final_ansem": "Final Ansem", - "puppies": "Traverse Town Piano Room Return 99 Puppies Reward 2", - "final_rest": "End of the World Final Rest Chest" - } - self.get_location(goal_dict[self.options.goal.current_key]).place_locked_item(self.create_item("Victory")) - if self.options.vanilla_emblem_pieces: + if self.options.final_rest_door_key.current_key not in ["puppies", "postcards", "lucky_emblems"]: + goal_dict = { + "sephiroth": "Olympus Coliseum Defeat Sephiroth Ansem's Report 12", + "unknown": "Hollow Bastion Defeat Unknown Ansem's Report 13", + "final_rest": "End of the World Final Rest Chest" + } + goal_location_name = goal_dict[self.options.final_rest_door_key.current_key] + elif self.options.final_rest_door_key.current_key == "postcards": + lpad_number = str(self.options.required_postcards).rjust(2, "0") + goal_location_name = "Traverse Town Mail Postcard " + lpad_number + " Event" + elif self.options.final_rest_door_key.current_key == "puppies": + required_puppies = self.options.required_puppies.value + goal_location_name = "Traverse Town Piano Room Return " + str(required_puppies) + " Puppies" + if required_puppies == 50 or required_puppies == 99: + goal_location_name = goal_location_name + " Reward 2" + if self.options.final_rest_door_key.current_key != "lucky_emblems": + self.get_location(goal_location_name).place_locked_item(self.create_item("Final Door Key")) + self.get_location("Final Ansem").place_locked_item(self.create_event("Victory")) + + if not self.options.randomize_emblem_pieces: self.get_location("Hollow Bastion Entrance Hall Emblem Piece (Flame)").place_locked_item(self.create_item("Emblem Piece (Flame)")) self.get_location("Hollow Bastion Entrance Hall Emblem Piece (Statue)").place_locked_item(self.create_item("Emblem Piece (Statue)")) self.get_location("Hollow Bastion Entrance Hall Emblem Piece (Fountain)").place_locked_item(self.create_item("Emblem Piece (Fountain)")) self.get_location("Hollow Bastion Entrance Hall Emblem Piece (Chest)").place_locked_item(self.create_item("Emblem Piece (Chest)")) + if self.options.randomize_postcards != "all": + self.get_location("Traverse Town Item Shop Postcard").place_locked_item(self.create_item("Postcard")) + self.get_location("Traverse Town 1st District Safe Postcard").place_locked_item(self.create_item("Postcard")) + self.get_location("Traverse Town Gizmo Shop Postcard 1").place_locked_item(self.create_item("Postcard")) + self.get_location("Traverse Town Gizmo Shop Postcard 2").place_locked_item(self.create_item("Postcard")) + self.get_location("Traverse Town Item Workshop Postcard").place_locked_item(self.create_item("Postcard")) + self.get_location("Traverse Town 3rd District Balcony Postcard").place_locked_item(self.create_item("Postcard")) + self.get_location("Traverse Town Geppetto's House Postcard").place_locked_item(self.create_item("Postcard")) + if self.options.randomize_postcards.current_key == "vanilla": + self.get_location("Traverse Town 1st District Accessory Shop Roof Chest").place_locked_item(self.create_item("Postcard")) + self.get_location("Traverse Town 2nd District Boots and Shoes Awning Chest").place_locked_item(self.create_item("Postcard")) + self.get_location("Traverse Town 1st District Blue Trinity Balcony Chest").place_locked_item(self.create_item("Postcard")) + if not self.options.randomize_puppies: + if self.options.puppy_value.value != 3: + self.options.puppy_value.value = 3 + logging.info(f"{self.player_name}'s value of {self.options.puppy_value.value} for puppy value was changed to 3 as Randomize Puppies is OFF") + for i, location in enumerate(VANILLA_PUPPY_LOCATIONS): + self.get_location(location).place_locked_item(self.create_item("Puppy")) def get_filler_item_name(self) -> str: weights = [data.weight for data in self.fillers.values()] return self.random.choices([filler for filler in self.fillers.keys()], weights)[0] def fill_slot_data(self) -> dict: - slot_data = {"xpmult": int(self.options.exp_multiplier)/16, - "required_reports_eotw": self.determine_reports_required_to_open_end_of_the_world(), - "required_reports_door": self.determine_reports_required_to_open_final_rest_door(), - "door": self.options.final_rest_door.current_key, - "seed": self.multiworld.seed_name, - "advanced_logic": bool(self.options.advanced_logic), - "hundred_acre_wood": bool(self.options.hundred_acre_wood), + slot_data = { "atlantica": bool(self.options.atlantica), - "goal": str(self.options.goal.current_key)} - if self.options.randomize_keyblade_stats: - min_str_bonus = min(self.options.keyblade_min_str.value, self.options.keyblade_max_str.value) - max_str_bonus = max(self.options.keyblade_min_str.value, self.options.keyblade_max_str.value) - self.options.keyblade_min_str.value = min_str_bonus - self.options.keyblade_max_str.value = max_str_bonus - min_mp_bonus = min(self.options.keyblade_min_mp.value, self.options.keyblade_max_mp.value) - max_mp_bonus = max(self.options.keyblade_min_mp.value, self.options.keyblade_max_mp.value) - self.options.keyblade_min_mp.value = min_mp_bonus - self.options.keyblade_max_mp.value = max_mp_bonus - slot_data["keyblade_stats"] = "" - for i in range(22): - if i < 4 and self.options.bad_starting_weapons: - slot_data["keyblade_stats"] = slot_data["keyblade_stats"] + "1,0," - else: - str_bonus = int(self.random.randint(min_str_bonus, max_str_bonus)) - mp_bonus = int(self.random.randint(min_mp_bonus, max_mp_bonus)) - slot_data["keyblade_stats"] = slot_data["keyblade_stats"] + str(str_bonus) + "," + str(mp_bonus) + "," - slot_data["keyblade_stats"] = slot_data["keyblade_stats"][:-1] - if self.options.donald_death_link: - slot_data["donalddl"] = "" - if self.options.goofy_death_link: - slot_data["goofydl"] = "" - if self.options.keyblades_unlock_chests: - slot_data["chestslocked"] = "" - else: - slot_data["chestsunlocked"] = "" - if self.options.interact_in_battle: - slot_data["interactinbattle"] = "" + "auto_attack": bool(self.options.auto_attack), + "auto_save": bool(self.options.auto_save), + "bad_starting_weapons": bool(self.options.bad_starting_weapons), + "beep_hack": bool(self.options.beep_hack), + "consistent_finishers": bool(self.options.consistent_finishers), + "cups": str(self.options.cups.current_key), + "day_2_materials": int(self.options.day_2_materials.value), + "death_link": str(self.options.death_link.current_key), + "destiny_islands": bool(self.options.destiny_islands), + "donald_death_link": bool(self.options.donald_death_link), + "early_skip": bool(self.options.early_skip), + "end_of_the_world_unlock": str(self.options.end_of_the_world_unlock.current_key), + "exp_multiplier": int(self.options.exp_multiplier.value)/16, + "exp_zero_in_pool": bool(self.options.exp_zero_in_pool), + "extra_shared_abilities": bool(self.options.extra_shared_abilities), + "fast_camera": bool(self.options.fast_camera), + "faster_animations": bool(self.options.faster_animations), + "final_rest_door_key": str(self.options.final_rest_door_key.current_key), + "force_stats_on_levels": int(self.options.force_stats_on_levels.value), + "four_by_three": bool(self.options.four_by_three), + "goofy_death_link": bool(self.options.goofy_death_link), + "halloween_town_key_item_bundle": bool(self.options.halloween_town_key_item_bundle), + "homecoming_materials": int(self.options.homecoming_materials.value), + "hundred_acre_wood": bool(self.options.hundred_acre_wood), + "interact_in_battle": bool(self.options.interact_in_battle), + "jungle_slider": bool(self.options.jungle_slider), + "keyblades_unlock_chests": bool(self.options.keyblades_unlock_chests), + "level_checks": int(self.options.level_checks.value), + "logic_difficulty": str(self.options.logic_difficulty.current_key), + "materials_in_pool": int(self.options.materials_in_pool.value), + "max_ap_cost": int(self.options.max_ap_cost.value), + "min_ap_cost": int(self.options.min_ap_cost.value), + "mythril_in_pool": int(self.options.mythril_in_pool.value), + "mythril_price": int(self.options.mythril_price.value), + "one_hp": bool(self.options.one_hp), + "orichalcum_in_pool": int(self.options.orichalcum_in_pool.value), + "orichalcum_price": int(self.options.orichalcum_price.value), + "puppy_value": int(self.options.puppy_value.value), + "randomize_ap_costs": str(self.options.randomize_ap_costs.current_key), + "randomize_emblem_pieces": bool(self.options.exp_zero_in_pool), + "randomize_party_member_starting_accessories": bool(self.options.randomize_party_member_starting_accessories), + "randomize_postcards": str(self.options.randomize_postcards.current_key), + "randomize_puppies": str(self.options.randomize_puppies.current_key), + "remote_items": str(self.options.remote_items.current_key), + "remote_location_ids": self.get_remote_location_ids(), + "required_lucky_emblems_door": self.determine_lucky_emblems_required_to_open_final_rest_door(), + "required_lucky_emblems_eotw": self.determine_lucky_emblems_required_to_open_end_of_the_world(), + "required_postcards": int(self.options.required_postcards.value), + "required_puppies": int(self.options.required_puppies.value), + "seed": self.multiworld.seed_name, + "shorten_go_mode": bool(self.options.shorten_go_mode), + "slot_2_level_checks": int(self.options.slot_2_level_checks.value), + "stacking_world_items": bool(self.options.stacking_world_items), + "starting_items": [item.code for item in self.multiworld.precollected_items[self.player]], + "starting_tools": bool(self.options.starting_tools), + "super_bosses": bool(self.options.super_bosses), + "synthesis_item_name_byte_arrays": self.get_synthesis_item_name_byte_arrays(), + "unlock_0_volume": bool(self.options.unlock_0_volume), + "unskippable": bool(self.options.unskippable), + "warp_anywhere": bool(self.options.warp_anywhere) + } return slot_data def create_item(self, name: str) -> KH1Item: @@ -241,45 +355,260 @@ def set_rules(self): set_rules(self) def create_regions(self): - create_regions(self.multiworld, self.player, self.options) - + create_regions(self) + def connect_entrances(self): - connect_entrances(self.multiworld, self.player) + connect_entrances(self) + + def generate_output(self, output_directory: str): + """ + Generates the json file for use with mod generator. + """ + generate_json(self, output_directory) def generate_early(self): - value_names = ["Reports to Open End of the World", "Reports to Open Final Rest Door", "Reports in Pool"] - initial_report_settings = [self.options.required_reports_eotw.value, self.options.required_reports_door.value, self.options.reports_in_pool.value] - self.change_numbers_of_reports_to_consider() - new_report_settings = [self.options.required_reports_eotw.value, self.options.required_reports_door.value, self.options.reports_in_pool.value] + self.determine_level_checks() + + value_names = ["Lucky Emblems to Open End of the World", "Lucky Emblems to Open Final Rest Door", "Lucky Emblems in Pool"] + initial_lucky_emblem_settings = [self.options.required_lucky_emblems_eotw.value, self.options.required_lucky_emblems_door.value, self.options.lucky_emblems_in_pool.value] + self.change_numbers_of_lucky_emblems_to_consider() + new_lucky_emblem_settings = [self.options.required_lucky_emblems_eotw.value, self.options.required_lucky_emblems_door.value, self.options.lucky_emblems_in_pool.value] for i in range(3): - if initial_report_settings[i] != new_report_settings[i]: - logging.info(f"{self.player_name}'s value {initial_report_settings[i]} for \"{value_names[i]}\" was invalid\n" - f"Setting \"{value_names[i]}\" value to {new_report_settings[i]}") + if initial_lucky_emblem_settings[i] != new_lucky_emblem_settings[i]: + logging.info(f"{self.player_name}'s value {initial_lucky_emblem_settings[i]} for \"{value_names[i]}\" was invalid\n" + f"Setting \"{value_names[i]}\" value to {new_lucky_emblem_settings[i]}") + + value_names = ["Day 2 Materials", "Homecoming Materials", "Materials in Pool"] + initial_materials_settings = [self.options.day_2_materials.value, self.options.homecoming_materials.value, self.options.materials_in_pool.value] + self.change_numbers_of_materials_to_consider() + new_materials_settings = [self.options.day_2_materials.value, self.options.homecoming_materials.value, self.options.materials_in_pool.value] + for i in range(3): + if initial_materials_settings[i] != new_materials_settings[i]: + logging.info(f"{self.player_name}'s value {initial_materials_settings[i]} for \"{value_names[i]}\" was invalid\n" + f"Setting \"{value_names[i]}\" value to {new_materials_settings[i]}") + + if self.options.stacking_world_items.value and not self.options.halloween_town_key_item_bundle.value: + logging.info(f"{self.player_name}'s value {self.options.halloween_town_key_item_bundle.value} for Halloween Town Key Item Bundle must be TRUE when Stacking World Items is on. Setting to TRUE") + self.options.halloween_town_key_item_bundle.value = True - def change_numbers_of_reports_to_consider(self) -> None: - if self.options.end_of_the_world_unlock == "reports" and self.options.final_rest_door == "reports": - self.options.required_reports_eotw.value, self.options.required_reports_door.value, self.options.reports_in_pool.value = sorted( - [self.options.required_reports_eotw.value, self.options.required_reports_door.value, self.options.reports_in_pool.value]) + def change_numbers_of_lucky_emblems_to_consider(self) -> None: + if self.options.end_of_the_world_unlock == "lucky_emblems" and self.options.final_rest_door_key == "lucky_emblems": + self.options.required_lucky_emblems_eotw.value, self.options.required_lucky_emblems_door.value, self.options.lucky_emblems_in_pool.value = sorted( + [self.options.required_lucky_emblems_eotw.value, self.options.required_lucky_emblems_door.value, self.options.lucky_emblems_in_pool.value]) - elif self.options.end_of_the_world_unlock == "reports": - self.options.required_reports_eotw.value, self.options.reports_in_pool.value = sorted( - [self.options.required_reports_eotw.value, self.options.reports_in_pool.value]) + elif self.options.end_of_the_world_unlock == "lucky_emblems": + self.options.required_lucky_emblems_eotw.value, self.options.lucky_emblems_in_pool.value = sorted( + [self.options.required_lucky_emblems_eotw.value, self.options.lucky_emblems_in_pool.value]) - elif self.options.final_rest_door == "reports": - self.options.required_reports_door.value, self.options.reports_in_pool.value = sorted( - [self.options.required_reports_door.value, self.options.reports_in_pool.value]) + elif self.options.final_rest_door_key == "lucky_emblems": + self.options.required_lucky_emblems_door.value, self.options.lucky_emblems_in_pool.value = sorted( + [self.options.required_lucky_emblems_door.value, self.options.lucky_emblems_in_pool.value]) - def determine_reports_in_pool(self) -> int: - if self.options.end_of_the_world_unlock == "reports" or self.options.final_rest_door == "reports": - return self.options.reports_in_pool.value + def determine_lucky_emblems_in_pool(self) -> int: + if self.options.end_of_the_world_unlock == "lucky_emblems" or self.options.final_rest_door_key == "lucky_emblems": + return self.options.lucky_emblems_in_pool.value return 0 - def determine_reports_required_to_open_end_of_the_world(self) -> int: - if self.options.end_of_the_world_unlock == "reports": - return self.options.required_reports_eotw.value - return 14 + def determine_lucky_emblems_required_to_open_end_of_the_world(self) -> int: + if self.options.end_of_the_world_unlock == "lucky_emblems": + return self.options.required_lucky_emblems_eotw.value + return -1 + + def determine_lucky_emblems_required_to_open_final_rest_door(self) -> int: + if self.options.final_rest_door_key == "lucky_emblems": + return self.options.required_lucky_emblems_door.value + return -1 + + def change_numbers_of_materials_to_consider(self) -> None: + if self.options.destiny_islands: + self.options.day_2_materials.value, self.options.homecoming_materials.value, self.options.materials_in_pool.value = sorted( + [self.options.day_2_materials.value, self.options.homecoming_materials.value, self.options.materials_in_pool.value]) + + def get_remote_location_ids(self): + remote_location_ids = [] + for location in self.multiworld.get_filled_locations(self.player): + if location.name != "Final Ansem": + location_data = location_table[location.name] + if self.options.remote_items.current_key == "full": + if location_data.type != "Starting Accessory": + remote_location_ids.append(location_data.code) + elif self.player == location.item.player and location.item.name != "Victory": + item_data = item_table[location.item.name] + if location_data.type == "Chest": + if item_data.type in ["Stats"]: + remote_location_ids.append(location_data.code) + if location_data.type == "Reward": + if item_data.type in ["Stats"]: + remote_location_ids.append(location_data.code) + if location_data.type == "Static": + if item_data.type not in ["Item"]: + remote_location_ids.append(location_data.code) + if location_data.type == "Level Slot 1": + if item_data.category not in ["Level Up", "Limited Level Up"]: + remote_location_ids.append(location_data.code) + if location_data.type == "Level Slot 2": + if item_data.category not in ["Level Up", "Limited Level Up", "Abilities"]: + remote_location_ids.append(location_data.code) + if location_data.type == "Synth": + if item_data.type not in ["Item"]: + remote_location_ids.append(location_data.code) + if location_data.type == "Prize": + if item_data.type not in ["Item"]: + remote_location_ids.append(location_data.code) + return remote_location_ids + + def get_slot_2_levels(self): + if self.slot_2_levels is None: + self.slot_2_levels = [] + if self.options.max_level_for_slot_2_level_checks - 1 > self.options.level_checks.value: + logging.info(f"{self.player_name}'s value of {self.options.max_level_for_slot_2_level_checks.value} for max level for slot 2 level checks is invalid as it exceeds their value of {self.options.level_checks.value} for Level Checks\n" + f"Setting max level for slot 2 level checks's value to {self.options.level_checks.value + 1}") + self.options.max_level_for_slot_2_level_checks.value = self.options.level_checks.value + 1 + if self.options.slot_2_level_checks.value > self.options.level_checks.value: + logging.info(f"{self.player_name}'s value of {self.options.slot_2_level_checks.value} for slot 2 level checks is invalid as it exceeds their value of {self.options.level_checks.value} for Level Checks\n" + f"Setting slot 2 level check's value to {self.options.level_checks.value}") + self.options.slot_2_level_checks.value = self.options.level_checks.value + if self.options.slot_2_level_checks > self.options.max_level_for_slot_2_level_checks - 1: + logging.info(f"{self.player_name}'s value of {self.options.slot_2_level_checks.value} for slot 2 level checks is invalid as it exceeds their value of {self.options.max_level_for_slot_2_level_checks.value} for Max Level for Slot 2 Level Checks\n" + f"Setting slot 2 level check's value to {self.options.max_level_for_slot_2_level_checks.value - 1}") + self.options.slot_2_level_checks.value = self.options.max_level_for_slot_2_level_checks.value - 1 + # Range is exclusive of the top, so if max_level_for_slot_2_level_checks is 2 then the top end of the range needs to be 3 as the only level it can choose is 2. + self.slot_2_levels = self.random.sample(range(2,self.options.max_level_for_slot_2_level_checks.value + 1), self.options.slot_2_level_checks.value) + return self.slot_2_levels + + def get_keyblade_stats(self): + # Create keyblade stat array from vanilla + keyblade_stats = [x.copy() for x in VANILLA_KEYBLADE_STATS] + # Handle shuffling keyblade stats + if self.options.keyblade_stats != "vanilla": + if self.options.keyblade_stats == "randomize": + # Fix any minimum and max values from settings + min_str_bonus = min(self.options.keyblade_min_str.value, self.options.keyblade_max_str.value) + max_str_bonus = max(self.options.keyblade_min_str.value, self.options.keyblade_max_str.value) + self.options.keyblade_min_str.value = min_str_bonus + self.options.keyblade_max_str.value = max_str_bonus + min_crit_rate = min(self.options.keyblade_min_crit_rate.value, self.options.keyblade_max_crit_rate.value) + max_crit_rate = max(self.options.keyblade_min_crit_rate.value, self.options.keyblade_max_crit_rate.value) + self.options.keyblade_min_crit_rate.value = min_crit_rate + self.options.keyblade_max_crit_rate.value = max_crit_rate + min_crit_str = min(self.options.keyblade_min_crit_str.value, self.options.keyblade_max_crit_str.value) + max_crit_str = max(self.options.keyblade_min_crit_str.value, self.options.keyblade_max_crit_str.value) + self.options.keyblade_min_crit_str.value = min_crit_str + self.options.keyblade_max_crit_str.value = max_crit_str + min_recoil = min(self.options.keyblade_min_recoil.value, self.options.keyblade_max_recoil.value) + max_recoil = max(self.options.keyblade_min_recoil.value, self.options.keyblade_max_recoil.value) + self.options.keyblade_min_recoil.value = min_recoil + self.options.keyblade_max_recoil.value = max_recoil + min_mp_bonus = min(self.options.keyblade_min_mp.value, self.options.keyblade_max_mp.value) + max_mp_bonus = max(self.options.keyblade_min_mp.value, self.options.keyblade_max_mp.value) + self.options.keyblade_min_mp.value = min_mp_bonus + self.options.keyblade_max_mp.value = max_mp_bonus + if self.options.bad_starting_weapons: + starting_weapons = keyblade_stats[:4] + other_weapons = keyblade_stats[4:] + else: + starting_weapons = [] + other_weapons = keyblade_stats + for keyblade in other_weapons: + keyblade["STR"] = self.random.randint(min_str_bonus, max_str_bonus) + keyblade["CRR"] = self.random.randint(min_crit_rate, max_crit_rate) + keyblade["CRB"] = self.random.randint(min_crit_str, max_crit_str) + keyblade["REC"] = self.random.randint(min_recoil, max_recoil) + keyblade["MP"] = self.random.randint(min_mp_bonus, max_mp_bonus) + keyblade_stats = starting_weapons + other_weapons + elif self.options.keyblade_stats == "shuffle": + if self.options.bad_starting_weapons: + starting_weapons = keyblade_stats[:4] + other_weapons = keyblade_stats[4:] + self.random.shuffle(other_weapons) + keyblade_stats = starting_weapons + other_weapons + else: + self.random.shuffle(keyblade_stats) + return keyblade_stats + + def determine_level_checks(self): + # Handle if remote_items is off and level_checks > number of stats items + total_level_up_items = min(99, + self.options.strength_increase.value +\ + self.options.defense_increase.value +\ + self.options.hp_increase.value +\ + self.options.mp_increase.value +\ + self.options.ap_increase.value +\ + self.options.accessory_slot_increase.value +\ + self.options.item_slot_increase.value) + if self.options.level_checks.value > total_level_up_items and self.options.remote_items.current_key == "off": + logging.info(f"{self.player_name}'s value {self.options.level_checks.value} for level_checks was changed.\n" + f"This value cannot be more than the number of stat items in the pool when \"remote_items\" is \"off\".\n" + f"Set to be equal to number of stat items in pool, {total_level_up_items}.") + self.options.level_checks.value = total_level_up_items + + def get_synthesis_item_name_byte_arrays(self): + # Get synth item names to show in synthesis menu + synthesis_byte_arrays = [] + for location in self.multiworld.get_filled_locations(self.player): + if location.name != "Final Ansem": + location_data = location_table[location.name] + if location_data.type == "Synth": + item_name = re.sub('[^A-Za-z0-9 ]+', '',str(location.item.name.replace("Progressive", "Prog")))[:14] + byte_array = [] + for character in item_name: + byte_array.append(CHAR_TO_KH[character]) + synthesis_byte_arrays.append(byte_array) + return synthesis_byte_arrays + + def get_starting_accessory_locations(self): + if self.starting_accessory_locations is None: + if self.options.randomize_party_member_starting_accessories: + self.starting_accessory_locations = list(get_locations_by_type("Starting Accessory").keys()) + if not self.options.atlantica: + self.starting_accessory_locations.remove("Ariel Starting Accessory 1") + self.starting_accessory_locations.remove("Ariel Starting Accessory 2") + self.starting_accessory_locations.remove("Ariel Starting Accessory 3") + self.starting_accessory_locations = self.random.sample(self.starting_accessory_locations, 10) + else: + self.starting_accessory_locations = [] + return self.starting_accessory_locations + + def get_starting_accessories(self): + if self.starting_accessories is None: + if self.options.randomize_party_member_starting_accessories: + self.starting_accessories = list(get_items_by_category("Accessory").keys()) + self.starting_accessories = self.random.sample(self.starting_accessories, 10) + else: + self.starting_accessories = [] + return self.starting_accessories - def determine_reports_required_to_open_final_rest_door(self) -> int: - if self.options.final_rest_door == "reports": - return self.options.required_reports_door.value - return 14 + def get_ap_costs(self): + if self.ap_costs is None: + ap_costs = VANILLA_ABILITY_AP_COSTS.copy() + if self.options.randomize_ap_costs.current_key == "shuffle": + possible_costs = [] + for ap_cost in VANILLA_ABILITY_AP_COSTS: + if ap_cost["Randomize"]: + possible_costs.append(ap_cost["AP Cost"]) + self.random.shuffle(possible_costs) + for ap_cost in ap_costs: + if ap_cost["Randomize"]: + ap_cost["AP Cost"] = possible_costs.pop(0) + elif self.options.randomize_ap_costs.current_key == "randomize": + for ap_cost in ap_costs: + if ap_cost["Randomize"]: + ap_cost["AP Cost"] = self.random.randint(self.options.min_ap_cost.value, self.options.max_ap_cost.value) + elif self.options.randomize_ap_costs.current_key == "distribute": + total_ap_value = 0 + for ap_cost in VANILLA_ABILITY_AP_COSTS: + if ap_cost["Randomize"]: + total_ap_value = total_ap_value + ap_cost["AP Cost"] + for ap_cost in ap_costs: + if ap_cost["Randomize"]: + total_ap_value = total_ap_value - self.options.min_ap_cost.value + ap_cost["AP Cost"] = self.options.min_ap_cost.value + while total_ap_value > 0: + ap_cost = self.random.choice(ap_costs) + if ap_cost["Randomize"]: + if ap_cost["AP Cost"] < self.options.max_ap_cost.value: + amount_to_add = self.random.randint(1, min(self.options.max_ap_cost.value - ap_cost["AP Cost"], total_ap_value)) + ap_cost["AP Cost"] = ap_cost["AP Cost"] + amount_to_add + total_ap_value = total_ap_value - amount_to_add + self.ap_costs = ap_costs + return self.ap_costs diff --git a/worlds/kh1/docs/en_Kingdom Hearts.md b/worlds/kh1/docs/en_Kingdom Hearts.md index 5167505efbbd..f0862672640f 100644 --- a/worlds/kh1/docs/en_Kingdom Hearts.md +++ b/worlds/kh1/docs/en_Kingdom Hearts.md @@ -7,7 +7,7 @@ configure and export a config file. ## What does randomization do to this game? -The Kingdom Hearts AP Randomizer randomizes most rewards in the game and adds several items which are used to unlock worlds, Olympus Coliseum cups, and world progression. +The Kingdom Hearts AP Randomizer randomizes rewards in the game and adds several items which are used to unlock worlds, Olympus Coliseum cups, and world progression. Worlds can only be accessed by finding the corresponding item. For example, you need to find the `Monstro` item to enter Monstro. @@ -21,49 +21,26 @@ Any weapon, accessory, spell, trinity, summon, world, key item, stat up, consuma ### Locations -Locations the player can find items include chests, event rewards, Atlantica clams, level up rewards, 101 Dalmatian rewards, and postcard rewards. +Locations the player can find items include: +- Chests +- Rewards +- Static Events +- Map Prizes from things such as Trinities, Wonderland flowers and chairs, etc. +- Level ups ## Which items can be in another player's world? Any of the items which can be shuffled may also be placed into another player's world. It is possible to choose to limit certain items to your own world. + ## When the player receives an item, what happens? -When the player receives an item, your client will display a message displaying the item you have obtained. You will also see a notification in the "LEVEL UP" box. +When the player receives an item, your client will display a message displaying the item you have obtained. You will also see a notification in the "INFORMATION" box. ## What do I do if I encounter a bug with the game? Please reach out to Gicu#7034 on Discord. -## How do I progress in a certain world? - -### The evidence boxes aren't spawning in Wonderland. - -Find `Footprints` in the multiworld. - -### I can't enter any cups in Olympus Coliseum. - -Firstly, find `Entry Pass` in the multiworld. Additionally, `Phil Cup`, `Pegasus Cup`, and `Hercules Cup` are all multiworld items. Finding all 3 grant you access to the Hades Cup and the Platinum Match. Clearing all cups lets you challenge Ice Titan. - -### The slides aren't spawning in Deep Jungle. - -Find `Slides` in the multiworld. - -### I can't progress in Atlantica. -Find `Crystal Trident` in the multiworld. - -### I can't progress in Halloween Town. - -Find `Forget-Me-Not` and `Jack-in-the-Box` in the multiworld. - -### The Hollow Bastion Library is missing a book. - -Find `Theon Vol. 6` in the multiworld. - -## How do I enter the End of the World? - -You can enter End of the World by obtaining a number of Ansem's Reports or by finding `End of the World` in the multiworld, depending on your options. - ## Credits This is a collaborative effort from several individuals in the Kingdom Hearts community, but most of all, denhonator. diff --git a/worlds/kh1/docs/kh1_en.md b/worlds/kh1/docs/kh1_en.md index 522da20b0dc9..f6b6a640673a 100644 --- a/worlds/kh1/docs/kh1_en.md +++ b/worlds/kh1/docs/kh1_en.md @@ -1,54 +1,99 @@ -# Kingdom Hearts Randomizer Setup Guide +# Kingdom Hearts Archipelago Randomizer Setup Guide -## Setting up the required mods +

    Required software

    -BEFORE MODDING, PLEASE INSTALL AND RUN KH1 AT LEAST ONCE. +- KINGDOM HEARTS -HD 1.5+2.5 ReMIX- from the [Epic Games Store](https://store.epicgames.com/en-US/discover/kingdom-hearts) or [Steam](https://store.steampowered.com/app/2552430/KINGDOM_HEARTS_HD_1525_ReMIX/) -1. Install OpenKH and the LUA Backend +- The latest release of [OpenKH](https://github.com/OpenKH/OpenKh/releases) - Download the [latest release of OpenKH](https://github.com/OpenKH/OpenKh/releases/tag/latest) - - Extract the files to a directory of your choosing. - - Open `OpenKh.Tools.ModsManager.exe` and run first time set up - - When prompted for game edition, choose `PC Release`, select which platform you're using (EGS or Steam), navigate to your `Kingdom Hearts I.5 + II.5` installation folder in the path box and click `Next` - - When prompted, install Panacea, then click `Next` - - When prompted, check KH1 plus any other AP game you play and click `Install and configure LUA backend`, then click `Next` - - Extracting game data for KH1 is unnecessary, but you may want to extract data for KH2 if you plan on playing KH2 AP - - Click `Finish` - -2. Open `OpenKh.Tools.ModsManager.exe` +- The latest release of the [Kingdom Hearts 1FM Randomizer Software](https://github.com/gaithern/KH1FM-RANDOMIZER/releases) -3. Click the drop-down menu at the top-right and choose `Kingdom Hearts 1` +- The latest release of [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) for the ArchipelagoKH1Client.exe -4. Click `Mods>Install a New Mod` +

    Setting up the required software

    -5. In `Add a new mod from GitHub` paste `gaithern/KH-1FM-AP-LUA` +

    OpenKH

    -6. Click `Install` +- Extract the OpenKH files to a directory of your choosing. +- When prompted for game edition, choose PC Release, select which platform you're using (EGS or Steam), navigate to your `Kingdom Hearts I.5 + II.5` installation folder in the path box and click `Next`. +- When prompted, install Panacea, then click `Next`. +- When prompted, check KH1 plus any other AP game you want to play, and click `Install and configure Lua backend`, then click `Next`. +- Extract the data for KH1. +- Click `Finish` -7. Navigate to Mod Loader and click `Build and Run` +

    Kingdom Hearts 1FM Randomizer Software

    +- Extract the Kingdom Hearts 1FM Randomizer Software files in a directory of your choosing. -## Configuring your YAML file +

    Obtaining and using the seed zip

    -### What is a YAML file and why do I need one? +- When you generate a game you will see a download link for a KH1 .zip seed on the room page. +- After downloading this zip, open `mod_generator.exe` in your Kingdom Hearts 1FM Randomizer Software folder. +- Direct `mod_generator.exe` to both your seed zip and your KH1 data folder extracted during your OpenKH set up. +- Click `start`. +- After some time, you will find a file in your `Output` folder called `mod_YYYYMMDDHHMMSS.zip` +- Open `OpenKh.Tools.ModsManager.exe` and ensure that the dropdown in the top right is set to `Kingdom Hearts 1` +- Click the green plus, choose `Select and install Mod Archive or Lua Script`, and direct the prompt to your new mod zip. +- You should now see a mod on your list called `KH1 Randomizer Seed XYZ` where XYZ is your seed hex value. +- Ensure this mod is checked, then, if you want to play right away, click `Mod Loader` at the top. +- Click `Build and Run`. Your modded game should now open. -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. +

    Connecting to your multiworld via the KH1 Client

    -### Where do I get a YAML file? +- Once your game is being hosted, open `ArchipelagoLauncher.exe`. +- Find `KH1 Client` and open it. +- At the top, in the `Server:` bar, type in the host address and port. +- Click the `Connect` button in the top right. +- If connection to the server was successful, you'll be prompted to type in your slot named in the `Command:` bar at the bottom. +- After typing your slot name, press enter. +- If all is well, you are now connected. -you can customize your settings by visiting the [Kingdom Hearts Options Page](/games/Kingdom%20Hearts/player-options). +

    FAQ

    -## Connect to the MultiWorld +

    The client did not confirm connection to the game, is that normal?

    -For first-time players, it is recommended to open your KH1 Client first before opening the game. +Yes, the game and client communicate via a game communication path set up in your in your `%AppData%` folder, and therefore don't need to establish a socket connection. -On the title screen, open your KH1 Client and connect to your multiworld. +

    I am not sending or receiving items.

    + +Check out this [troubleshooting guide](https://docs.google.com/document/d/1oAXxJWrNeqSL-tkB_01bLR0eT0urxz2FBo4URpq3VbM/edit?usp=sharing) + +

    Why aren't the evidence boxes spawning in Wonderland?

    + +You'll need to find `Footprints` in your multiworld. + +

    Why won't Phil let me start the Prelims?

    + +You'll need to find `Entry Pass` in the multiworld. + +

    Why aren't the slides spawning in Deep Jungle?

    + +You'll need to find `Slides` in the multiworld. + +

    Why can't I make progress in Atlantica?

    + +You'll need to find `Crystal Trident` in the multiworld. + +

    Why won't the doctor let me progress in Halloween Town?

    + +You'll need to find either `Forget-Me-Not` or `Jack-in-the-Box` in the multiworld. + +

    Why is there a book missing in the Hollow Bastion library?

    + +You'll need to find `Theon Vol. 6` in the multiworld. + +

    How do I unlock End of the World?

    + +Depending on your settings, your options are either finding a specified amount of `Lucky Emblems` or finding the item `End of the World`. + +

    How do I enter Destiny Islands?

    + +After obtaining the item `Destiny Islands`, you can land there as an additional option in Traverse Town. + +

    How do I progress to Destiny Islands Day 2 and 3?

    + +In order to access Day 2 and 3, you need to collect an amount of `Raft Materials` specified in your settings. When you start Day 3, you'll be immediately warped to Homecoming. + +

    Why can't I use the summon I obtained?

    + +You need at least one magic spell before you can use summons. diff --git a/worlds/kh1/icons/kh1_heart.ico b/worlds/kh1/icons/kh1_heart.ico new file mode 100644 index 0000000000000000000000000000000000000000..3c1bf320f6a471c455486952b9d402f31e137d53 GIT binary patch literal 4286 zcmcgvYiv|S6uysr+}-WIEEGzm+ZS4dS_>jCrEOYjZLySx;-fJ6xA!v+I;D;o} zM-+dkm|!&4C{o2x#72cGVodlUDi{=m7K#K6wjkI-+dY2YbhoVS7Ob_M=G%Mk%$f6@ zIp@rosix`pOH0%EtGyS{v?NW_vH^5y1pxb1!`Log7rHtI{HqUG!@v}zV|wbqRP=wg z7aonYrFbsnyMsSN)ZB*Rw`aJGEvYV}8nmW4MBJo_tUjwG$#%48xa|sF6e+AD+Q$6Cf>57~DLAx&7rzgmP5}y=|s6-S}TL{%s5MYHnlGv=!XsT*J8x9<+VJw zbj}T`d@H-mx?^pj4Rc`UQP|s#xi4SuirP>Gxqs6NT&8~f#T>VUBizh8OzaoRVK05w z0UhhcxeyDz5js?jiRk})32IwwWkAKUBDw$E(4lO-GsUiQ;r#4?+}l+nw_(iR z2RFMHW_pZ^Kh5;1wXeFy68aPU{|Pvkv;^ZXvV&-L!J8p=kA}V2a9p`EXA76A-;QY4u6I-i89>#vHYwV z?byTLBL+!My#-@afS#>1E5W$Xgq%GC9XACp@uU99hf_TA?06UJnvC_Dau9aX4(7^! z0CNR*5?P`cANzT3y#tx&tcEHy8$ld6CKG%-5 z5K zGX6D)RcsuYi}xYUc>z;_dwb_CUiljNK$~-XrcA;aKrZGAlq>K(np0blHV*SJ$6Wnqge9augnDX!RM4RkFo^d^oV6Qxmyx@M>0b3>`X7mGPIcGd< zdTXLb`I9*nsR7j(w*&E7DQf;7yjN0Z7+@V`Zoi3pCVg`fwVnQ9t|wc1C+`2@Z*l)% z-wDKHdqkG!F>{GJSVuR)4#ejaNDJc;NBVf~Jegt{t*;}FXOZL7D|cMgjW(Ps^e6n? z3E6jm_a_9*Fz;g*;Imj+&TT<1GjB#X_4ANj2^hfTnhS#~+@{vVJ;T%Ga_Rvd^8wQL3Ud3JP?A%cfc>yw%-2|}i^FCskS|enZ16RDGvo69w+L#Bd!}kuv zbU&~U@Ac>-Zy^w?i@C!+wH`8G#>jtxzO_IOaHVxa2+@LkBN}in)SDt}bO~$P>JClI$6*peF(dp9 X@CQ+kyG~!=I6?U~eN8CrY*_s_$G7B9 literal 0 HcmV?d00001 diff --git a/worlds/kh1/icons/kh1_heart.png b/worlds/kh1/icons/kh1_heart.png new file mode 100644 index 0000000000000000000000000000000000000000..512dc03c184f324b5a42d20b3dc6b29e3647ac8e GIT binary patch literal 7821 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 literal 0 HcmV?d00001 diff --git a/worlds/kh1/test/test_goal.py b/worlds/kh1/test/test_goal.py index 6b501404feee..b788be2fc14e 100644 --- a/worlds/kh1/test/test_goal.py +++ b/worlds/kh1/test/test_goal.py @@ -5,29 +5,29 @@ class TestDefault(KH1TestBase): class TestSephiroth(KH1TestBase): options = { - "Goal": 0, + "Final Rest Door Key": 0, } class TestUnknown(KH1TestBase): options = { - "Goal": 1, + "Final Rest Door Key": 1, } class TestPostcards(KH1TestBase): options = { - "Goal": 2, + "Final Rest Door Key": 2, } -class TestFinalAnsem(KH1TestBase): +class TestLuckyEmblems(KH1TestBase): options = { - "Goal": 3, + "Final Rest Door Key": 3, } class TestPuppies(KH1TestBase): options = { - "Goal": 4, + "Final Rest Door Key": 4, } class TestFinalRest(KH1TestBase): options = { - "Goal": 5, + "Final Rest Door Key": 5, } From aaaceebd91e23a5cec70ce20d411358fff355162 Mon Sep 17 00:00:00 2001 From: Ben Dixon Date: Wed, 10 Sep 2025 16:56:04 -0500 Subject: [PATCH 0722/1218] Timespinner: Add Boss Rando Type Options (#4466) * adding in boss rando type options for Timespinner * removing new options from the backwards compatible section * adding in boss rando type options for Timespinner * removing new options from the backwards compatible section * re-adding accidentally deleted line * better documenting the different boss rando types * adding missing options to the interpret_slot_data function * making boss override schema more strict and allow for weights * now actually rolling using the weights for boss rando overrides * adding boss rando overrides to the spoiler header * simplifying the schema for the manual boss mappings --- worlds/timespinner/Options.py | 71 ++++++++++++++++++++++ worlds/timespinner/PreCalculatedWeights.py | 51 ++++++++++++++++ worlds/timespinner/__init__.py | 12 +++- 3 files changed, 132 insertions(+), 2 deletions(-) diff --git a/worlds/timespinner/Options.py b/worlds/timespinner/Options.py index 35d9d630efb4..23a688b8b38e 100644 --- a/worlds/timespinner/Options.py +++ b/worlds/timespinner/Options.py @@ -53,6 +53,75 @@ class BossRando(Choice): option_unscaled = 2 alias_true = 1 +class BossRandoType(Choice): + """ + Sets what type of boss shuffling occurs. + Shuffle: Bosses will be shuffled amongst each other + Chaos: Bosses will be randomized with the chance of duplicate bosses + Singularity: All bosses will be replaced with a single boss + Manual: Bosses will be placed according to the Boss Rando Overrides setting + """ + display_name = "Boss Randomization Type" + option_shuffle = 0 + option_chaos = 1 + option_singularity = 2 + option_manual = 3 + +class BossRandoOverrides(OptionDict): + """ + Manual mapping of bosses to the boss they will be replaced with. + Bosses that you don't specify will be the vanilla boss. + """ + bosses = [ + "FelineSentry", + "Varndagroth", + "AzureQueen", + "GoldenIdol", + "Aelana", + "Maw", + "Cantoran", + "Genza", + "Nuvius", + "Vol", + "Prince", + "Xarion", + "Ravenlord", + "Ifrit", + "Sandman", + "Nightmare", + ] + + schema = Schema( + { + Optional(Or(*bosses)): Or( + And( + {Optional(boss): And(int, lambda n: n >= 0) for boss in bosses}, + lambda d: any(v > 0 for v in d.values()), + ), + *bosses + ) + } + ) + display_name = "Boss Rando Overrides" + default = { + "FelineSentry": "FelineSentry", + "Varndagroth": "Varndagroth", + "AzureQueen": "AzureQueen", + "GoldenIdol": "GoldenIdol", + "Aelana": "Aelana", + "Maw": "Maw", + "Cantoran": "Cantoran", + "Genza": "Genza", + "Nuvius": "Nuvius", + "Vol": "Vol", + "Prince": "Prince", + "Xarion": "Xarion", + "Ravenlord": "Ravenlord", + "Ifrit": "Ifrit", + "Sandman": "Sandman", + "Nightmare": "Nightmare" + } + class EnemyRando(Choice): "Wheter enemies will be randomized, and if their damage/hp should be scaled." display_name = "Enemy Randomization" @@ -420,6 +489,8 @@ class TimespinnerOptions(PerGameCommonOptions, DeathLinkMixin): cantoran: Cantoran lore_checks: LoreChecks boss_rando: BossRando + boss_rando_type: BossRandoType + boss_rando_overrides: BossRandoOverrides enemy_rando: EnemyRando damage_rando: DamageRando damage_rando_overrides: DamageRandoOverrides diff --git a/worlds/timespinner/PreCalculatedWeights.py b/worlds/timespinner/PreCalculatedWeights.py index 96551ea7f152..916de34696c9 100644 --- a/worlds/timespinner/PreCalculatedWeights.py +++ b/worlds/timespinner/PreCalculatedWeights.py @@ -21,6 +21,8 @@ class PreCalculatedWeights: flood_lake_serene_bridge: bool flood_lab: bool + boss_rando_overrides: Dict[str, str] + def __init__(self, options: TimespinnerOptions, random: Random): if options.rising_tides: weights_overrrides: Dict[str, Union[str, Dict[str, int]]] = self.get_flood_weights_overrides(options) @@ -51,6 +53,26 @@ def __init__(self, options: TimespinnerOptions, random: Random): self.flood_lake_serene_bridge = False self.flood_lab = False + boss_rando_weights_overrides: Dict[str, Union[str, Dict[str, int]]] = self.get_boss_rando_weights_overrides(options) + self.boss_rando_overrides = { + "FelineSentry": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "FelineSentry"), + "Varndagroth": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Varndagroth"), + "AzureQueen": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "AzureQueen"), + "GoldenIdol": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "GoldenIdol"), + "Aelana": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Aelana"), + "Maw": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Maw"), + "Cantoran": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Cantoran"), + "Genza": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Genza"), + "Nuvius": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Nuvius"), + "Vol": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Vol"), + "Prince": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Prince"), + "Xarion": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Xarion"), + "Ravenlord": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Ravenlord"), + "Ifrit": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Ifrit"), + "Sandman": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Sandman"), + "Nightmare": self.roll_boss_rando_setting(random, boss_rando_weights_overrides, "Nightmare") + } + self.pyramid_keys_unlock, self.present_key_unlock, self.past_key_unlock, self.time_key_unlock = \ self.get_pyramid_keys_unlocks(options, random, self.flood_maw, self.flood_xarion, self.flood_lab) @@ -142,3 +164,32 @@ def roll_flood_setting(random: Random, all_weights: Dict[str, Union[Dict[str, in return True, True elif result == "FloodedWithSavePointAvailable": return True, False + + @staticmethod + def get_boss_rando_weights_overrides(options: TimespinnerOptions) -> Dict[str, Union[str, Dict[str, int]]]: + weights_overrides_option: Union[int, Dict[str, Union[str, Dict[str, int]]]] = \ + options.boss_rando_overrides.value + + default_weights: Dict[str, Dict[str, int]] = options.boss_rando_overrides.default + + if not weights_overrides_option: + weights_overrides_option = default_weights + else: + for key, weights in default_weights.items(): + if not key in weights_overrides_option: + weights_overrides_option[key] = weights + + return weights_overrides_option + + @staticmethod + def roll_boss_rando_setting(random: Random, all_weights: Dict[str, Union[Dict[str, int], str]], + key: str) -> str: + + weights: Union[Dict[str, int], str] = all_weights[key] + + if isinstance(weights, dict): + result: str = random.choices(list(weights.keys()), weights=list(map(int, weights.values())))[0] + else: + result: str = weights + + return result diff --git a/worlds/timespinner/__init__.py b/worlds/timespinner/__init__.py index 0bd9c7d19c80..3f1178373e3b 100644 --- a/worlds/timespinner/__init__.py +++ b/worlds/timespinner/__init__.py @@ -3,7 +3,7 @@ from .Items import get_item_names_per_category from .Items import item_table, starter_melee_weapons, starter_spells, filler_items, starter_progression_items, pyramid_start_starter_progression_items from .Locations import get_location_datas, EventId -from .Options import BackwardsCompatiableTimespinnerOptions, Toggle +from .Options import BackwardsCompatiableTimespinnerOptions, Toggle, BossRandoType from .PreCalculatedWeights import PreCalculatedWeights from .Regions import create_regions_and_locations from worlds.AutoWorld import World, WebWorld @@ -104,6 +104,8 @@ def fill_slot_data(self) -> Dict[str, object]: "Cantoran": self.options.cantoran.value, "LoreChecks": self.options.lore_checks.value, "BossRando": self.options.boss_rando.value, + "BossRandoType": self.options.boss_rando_type.value, + "BossRandoOverrides": self.precalculated_weights.boss_rando_overrides, "EnemyRando": self.options.enemy_rando.value, "DamageRando": self.options.damage_rando.value, "DamageRandoOverrides": self.options.damage_rando_overrides.value, @@ -181,6 +183,8 @@ def interpret_slot_data(self, slot_data: Optional[Dict[str, Any]]) -> Optional[D self.options.cantoran.value = slot_data["Cantoran"] self.options.lore_checks.value = slot_data["LoreChecks"] self.options.boss_rando.value = slot_data["BossRando"] + self.options.boss_rando_type.value = slot_data["BossRandoType"] + self.precalculated_weights.boss_rando_overrides = slot_data["BossRandoOverrides"] self.options.damage_rando.value = slot_data["DamageRando"] self.options.damage_rando_overrides.value = slot_data["DamageRandoOverrides"] self.options.hp_cap.value = slot_data["HpCap"] @@ -201,6 +205,7 @@ def interpret_slot_data(self, slot_data: Optional[Dict[str, Any]]) -> Optional[D self.options.rising_tides.value = slot_data["RisingTides"] self.options.unchained_keys.value = slot_data["UnchainedKeys"] self.options.back_to_the_future.value = slot_data["PresentAccessWithWheelAndSpindle"] + self.options.prism_break.value = slot_data["PrismBreak"] self.options.traps.value = slot_data["Traps"] self.options.death_link.value = slot_data["DeathLink"] # Readonly slot_data["StinkyMaw"] @@ -237,7 +242,10 @@ def write_spoiler_header(self, spoiler_handle: TextIO) -> None: spoiler_handle.write(f'Mysterious Warp Beacon unlock: {self.precalculated_weights.time_key_unlock}\n') else: spoiler_handle.write(f'Twin Pyramid Keys unlock: {self.precalculated_weights.pyramid_keys_unlock}\n') - + + if self.options.boss_rando.value and self.options.boss_rando_type.value == BossRandoType.option_manual: + spoiler_handle.write(f'Selected bosses: {self.precalculated_weights.boss_rando_overrides}\n') + if self.options.rising_tides: flooded_areas: List[str] = [] From 27e50aa81a3684c02c5eaf0900d81a389cc70ca6 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Thu, 11 Sep 2025 00:42:52 +0200 Subject: [PATCH 0723/1218] =?UTF-8?q?MultiServer:=20Make=20it=20so=20hint?= =?UTF-8?q?=5Flocation=20doesn't=20set=20an=20automatic=20priority=C2=A0#4?= =?UTF-8?q?713?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MultiServer.py | 90 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 2b58b3402e14..45b1178d8412 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1135,8 +1135,13 @@ def register_location_checks(ctx: Context, team: int, slot: int, locations: typi ctx.save() -def collect_hints(ctx: Context, team: int, slot: int, item: typing.Union[int, str], auto_status: HintStatus) \ - -> typing.List[Hint]: +def collect_hints(ctx: Context, team: int, slot: int, item: typing.Union[int, str], + status: HintStatus | None = None) -> typing.List[Hint]: + """ + Collect a new hint for a given item id or name, with a given status. + If status is None (which is the default value), an automatic status will be determined from the item's quality. + """ + hints = [] slots: typing.Set[int] = {slot} for group_id, group in ctx.groups.items(): @@ -1152,25 +1157,38 @@ def collect_hints(ctx: Context, team: int, slot: int, item: typing.Union[int, st else: found = location_id in ctx.location_checks[team, finding_player] entrance = ctx.er_hint_data.get(finding_player, {}).get(location_id, "") - new_status = auto_status + if found: - new_status = HintStatus.HINT_FOUND - elif item_flags & ItemClassification.trap: - new_status = HintStatus.HINT_AVOID - hints.append(Hint(receiving_player, finding_player, location_id, item_id, found, entrance, - item_flags, new_status)) + status = HintStatus.HINT_FOUND + elif status is None: + if item_flags & ItemClassification.trap: + status = HintStatus.HINT_AVOID + else: + status = HintStatus.HINT_PRIORITY + + hints.append( + Hint(receiving_player, finding_player, location_id, item_id, found, entrance, item_flags, status) + ) return hints -def collect_hint_location_name(ctx: Context, team: int, slot: int, location: str, auto_status: HintStatus) \ - -> typing.List[Hint]: +def collect_hint_location_name(ctx: Context, team: int, slot: int, location: str, + status: HintStatus | None = HintStatus.HINT_UNSPECIFIED) -> typing.List[Hint]: + """ + Collect a new hint for a given location name, with a given status (defaults to "unspecified"). + If None is passed for the status, then an automatic status will be determined from the item's quality. + """ seeked_location: int = ctx.location_names_for_game(ctx.games[slot])[location] - return collect_hint_location_id(ctx, team, slot, seeked_location, auto_status) + return collect_hint_location_id(ctx, team, slot, seeked_location, status) -def collect_hint_location_id(ctx: Context, team: int, slot: int, seeked_location: int, auto_status: HintStatus) \ - -> typing.List[Hint]: +def collect_hint_location_id(ctx: Context, team: int, slot: int, seeked_location: int, + status: HintStatus | None = HintStatus.HINT_UNSPECIFIED) -> typing.List[Hint]: + """ + Collect a new hint for a given location id, with a given status (defaults to "unspecified"). + If None is passed for the status, then an automatic status will be determined from the item's quality. + """ prev_hint = ctx.get_hint(team, slot, seeked_location) if prev_hint: return [prev_hint] @@ -1180,13 +1198,16 @@ def collect_hint_location_id(ctx: Context, team: int, slot: int, seeked_location found = seeked_location in ctx.location_checks[team, slot] entrance = ctx.er_hint_data.get(slot, {}).get(seeked_location, "") - new_status = auto_status + if found: - new_status = HintStatus.HINT_FOUND - elif item_flags & ItemClassification.trap: - new_status = HintStatus.HINT_AVOID - return [Hint(receiving_player, slot, seeked_location, item_id, found, entrance, item_flags, - new_status)] + status = HintStatus.HINT_FOUND + elif status is None: + if item_flags & ItemClassification.trap: + status = HintStatus.HINT_AVOID + else: + status = HintStatus.HINT_PRIORITY + + return [Hint(receiving_player, slot, seeked_location, item_id, found, entrance, item_flags, status)] return [] @@ -1610,7 +1631,6 @@ def _cmd_getitem(self, item_name: str) -> bool: def get_hints(self, input_text: str, for_location: bool = False) -> bool: points_available = get_client_points(self.ctx, self.client) cost = self.ctx.get_hint_cost(self.client.slot) - auto_status = HintStatus.HINT_UNSPECIFIED if for_location else HintStatus.HINT_PRIORITY if not input_text: hints = {hint.re_check(self.ctx, self.client.team) for hint in self.ctx.hints[self.client.team, self.client.slot]} @@ -1636,9 +1656,9 @@ def get_hints(self, input_text: str, for_location: bool = False) -> bool: self.output(f"Sorry, \"{hint_name}\" is marked as non-hintable.") hints = [] elif not for_location: - hints = collect_hints(self.ctx, self.client.team, self.client.slot, hint_id, auto_status) + hints = collect_hints(self.ctx, self.client.team, self.client.slot, hint_id) else: - hints = collect_hint_location_id(self.ctx, self.client.team, self.client.slot, hint_id, auto_status) + hints = collect_hint_location_id(self.ctx, self.client.team, self.client.slot, hint_id) else: game = self.ctx.games[self.client.slot] @@ -1658,16 +1678,18 @@ def get_hints(self, input_text: str, for_location: bool = False) -> bool: hints = [] for item_name in self.ctx.item_name_groups[game][hint_name]: if item_name in self.ctx.item_names_for_game(game): # ensure item has an ID - hints.extend(collect_hints(self.ctx, self.client.team, self.client.slot, item_name, auto_status)) + hints.extend(collect_hints(self.ctx, self.client.team, self.client.slot, item_name)) elif not for_location and hint_name in self.ctx.item_names_for_game(game): # item name - hints = collect_hints(self.ctx, self.client.team, self.client.slot, hint_name, auto_status) + hints = collect_hints(self.ctx, self.client.team, self.client.slot, hint_name) elif hint_name in self.ctx.location_name_groups[game]: # location group name hints = [] for loc_name in self.ctx.location_name_groups[game][hint_name]: if loc_name in self.ctx.location_names_for_game(game): - hints.extend(collect_hint_location_name(self.ctx, self.client.team, self.client.slot, loc_name, auto_status)) + hints.extend( + collect_hint_location_name(self.ctx, self.client.team, self.client.slot, loc_name) + ) else: # location name - hints = collect_hint_location_name(self.ctx, self.client.team, self.client.slot, hint_name, auto_status) + hints = collect_hint_location_name(self.ctx, self.client.team, self.client.slot, hint_name) else: self.output(response) @@ -1945,8 +1967,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): target_item, target_player, flags = ctx.locations[client.slot][location] if create_as_hint: - hints.extend(collect_hint_location_id(ctx, client.team, client.slot, location, - HintStatus.HINT_UNSPECIFIED)) + hints.extend(collect_hint_location_id(ctx, client.team, client.slot, location)) locs.append(NetworkItem(target_item, location, target_player, flags)) ctx.notify_hints(client.team, hints, only_new=create_as_hint == 2, persist_even_if_found=True) if locs and create_as_hint: @@ -2359,9 +2380,9 @@ def _cmd_hint(self, player_name: str, *item_name: str) -> bool: hints = [] for item_name_from_group in self.ctx.item_name_groups[game][item]: if item_name_from_group in self.ctx.item_names_for_game(game): # ensure item has an ID - hints.extend(collect_hints(self.ctx, team, slot, item_name_from_group, HintStatus.HINT_PRIORITY)) + hints.extend(collect_hints(self.ctx, team, slot, item_name_from_group)) else: # item name or id - hints = collect_hints(self.ctx, team, slot, item, HintStatus.HINT_PRIORITY) + hints = collect_hints(self.ctx, team, slot, item) if hints: self.ctx.notify_hints(team, hints) @@ -2395,17 +2416,14 @@ def _cmd_hint_location(self, player_name: str, *location_name: str) -> bool: if usable: if isinstance(location, int): - hints = collect_hint_location_id(self.ctx, team, slot, location, - HintStatus.HINT_UNSPECIFIED) + hints = collect_hint_location_id(self.ctx, team, slot, location) elif game in self.ctx.location_name_groups and location in self.ctx.location_name_groups[game]: hints = [] for loc_name_from_group in self.ctx.location_name_groups[game][location]: if loc_name_from_group in self.ctx.location_names_for_game(game): - hints.extend(collect_hint_location_name(self.ctx, team, slot, loc_name_from_group, - HintStatus.HINT_UNSPECIFIED)) + hints.extend(collect_hint_location_name(self.ctx, team, slot, loc_name_from_group)) else: - hints = collect_hint_location_name(self.ctx, team, slot, location, - HintStatus.HINT_UNSPECIFIED) + hints = collect_hint_location_name(self.ctx, team, slot, location) if hints: self.ctx.notify_hints(team, hints) else: From 76a8b0d582b61e4457af0c54a06700528b8e9065 Mon Sep 17 00:00:00 2001 From: Yaranorgoth Date: Fri, 12 Sep 2025 23:32:42 +0200 Subject: [PATCH 0724/1218] CCCharles: Bug fix for cyclic connections of Entrances with the ignored rules by the logic (#5442) * Add cccharles world to AP > The logic has been tested, the game can be completed > The logic is simple and it does not take into account options ! The documentations are a work in progress * Update documentations > Redacted French and English Setup Guides > Redacted French and English Game Pages * Handling PR#5287 remarks > Revert unexpected changes on .run\Archipelago Unittests.run.xml (base Archipelago file) > Fixed typo "querty" -> "qwerty" in fr and eng Game Pages > Adding "Game page in other languages" section to eng Game Page documentation > Improved Steam path in fr and eng Setup Guides * Handled PR remarks + fixes > Added get_filler_item_name() to remove warnings > Fixed irrelevant links for documentations > Used the Player Options page instead of the default YAML on GitHub > Reworded all locations to make them simple and clear > Split some locations that can be linked with an entrance rule > Reworked all options > Updated regions according to locations > Replaced unnecessary rules by rules on entrances * Empty Options.py Only the base options are handled yet, "work in progress" features removed. * Handled PR remark > Fixed specific UT name * Handled PR remarks > UT updated by replacing depreciated features * Add start_inventory_from_pool as option This start_inventory_from_pool option is like regular start inventory but it takes items from the pool and replaces them with fillers Co-authored-by: Scipio Wright * Handled PR remarks > Mainly fixed editorial and minor issues without impact on UT results (still passed) * Update the guides according to releases > Updated the depreciated guides because the may to release the Mod has been changed > Removed the fixed issues from 'Known Issues' > Add the "Mod Download" section to simplify the others sections. * Handled PR remark > base_id reduced to ensure it fits to signed int (32 bits) in case of future AP improvements * Handled PR remarks > Set topology_present to False because unnecessary > Added an exception in case of unknown item instead of using filler classification > Fixed an issue that caused the "Bug Spray" to be considered as filler > Reworked the test_claire_breakers() test to ensure the lighthouse mission can only be finished if at least 4 breakers are collected * Added Choo-Choo Charles to README.md * CCCharles: Added rules to win > The victory could be accessed from sphere 1, this is now fixed by adding the following items as requirements: - Temple Key - Green Egg - Blue Egg - Red Egg * CCCharles: Fixed cyclic Entrances connections --------- Co-authored-by: Scipio Wright --- worlds/cccharles/Regions.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/worlds/cccharles/Regions.py b/worlds/cccharles/Regions.py index 422301453c4e..68239dc060f1 100644 --- a/worlds/cccharles/Regions.py +++ b/worlds/cccharles/Regions.py @@ -232,11 +232,9 @@ def create_regions(world: MultiWorld, options: CCCharlesOptions, player: int) -> # Connect the Regions by named Entrances that must have access Rules menu_region.connect(start_camp_region) menu_region.connect(tony_tiddle_mission_region) - menu_region.connect(barn_region) - tony_tiddle_mission_region.connect(barn_region, "Barn Door") + menu_region.connect(barn_region, "Barn Door") menu_region.connect(candice_mission_region) - menu_region.connect(tutorial_house_region) - candice_mission_region.connect(tutorial_house_region, "Tutorial House Door") + menu_region.connect(tutorial_house_region, "Tutorial House Door") menu_region.connect(swamp_edges_region) menu_region.connect(swamp_mission_region) menu_region.connect(junkyard_area_region) @@ -244,7 +242,6 @@ def create_regions(world: MultiWorld, options: CCCharlesOptions, player: int) -> menu_region.connect(junkyard_shed_region) menu_region.connect(military_base_region) menu_region.connect(south_mine_outside_region) - menu_region.connect(south_mine_inside_region) south_mine_outside_region.connect(south_mine_inside_region, "South Mine Gate") menu_region.connect(middle_station_region) menu_region.connect(canyon_region) @@ -258,13 +255,11 @@ def create_regions(world: MultiWorld, options: CCCharlesOptions, player: int) -> menu_region.connect(lost_stairs_region) menu_region.connect(east_house_region) menu_region.connect(rockets_testing_ground_region) - menu_region.connect(rockets_testing_bunker_region) rockets_testing_ground_region.connect(rockets_testing_bunker_region, "Stuck Bunker Door") menu_region.connect(workshop_region) menu_region.connect(east_tower_region) menu_region.connect(lighthouse_region) menu_region.connect(north_mine_outside_region) - menu_region.connect(north_mine_inside_region) north_mine_outside_region.connect(north_mine_inside_region, "North Mine Gate") menu_region.connect(wood_bridge_region) menu_region.connect(museum_region) @@ -278,11 +273,9 @@ def create_regions(world: MultiWorld, options: CCCharlesOptions, player: int) -> menu_region.connect(north_beach_region) menu_region.connect(mine_shaft_region) menu_region.connect(mob_camp_region) - menu_region.connect(mob_camp_locked_room_region) mob_camp_region.connect(mob_camp_locked_room_region, "Mob Camp Locked Door") menu_region.connect(mine_elevator_exit_region) menu_region.connect(mountain_ruin_outside_region) - menu_region.connect(mountain_ruin_inside_region) mountain_ruin_outside_region.connect(mountain_ruin_inside_region, "Mountain Ruin Gate") menu_region.connect(prism_temple_region) menu_region.connect(pickle_val_region) From 4e085894d2b177fdd34eccbcde70df804fc89842 Mon Sep 17 00:00:00 2001 From: Salzkorn Date: Fri, 12 Sep 2025 23:48:29 +0200 Subject: [PATCH 0725/1218] SC2: Region access rule speedups (#5426) --- worlds/sc2/mission_order/entry_rules.py | 75 +++++++++++++++++++++++-- worlds/sc2/mission_order/generation.py | 63 ++++++++++++++++----- 2 files changed, 120 insertions(+), 18 deletions(-) diff --git a/worlds/sc2/mission_order/entry_rules.py b/worlds/sc2/mission_order/entry_rules.py index cb3afb372750..afa872deb1a4 100644 --- a/worlds/sc2/mission_order/entry_rules.py +++ b/worlds/sc2/mission_order/entry_rules.py @@ -10,6 +10,10 @@ if TYPE_CHECKING: from .nodes import SC2MOGenMission +def always_true(state: CollectionState) -> bool: + """Helper method to avoid creating trivial lambdas""" + return True + class EntryRule(ABC): buffer_fulfilled: bool @@ -60,6 +64,11 @@ def to_slot_data(self) -> RuleData: """Used in the client to determine accessibility while playing and to populate tooltips.""" pass + @abstractmethod + def find_mandatory_mission(self) -> SC2MOGenMission | None: + """Should return any mission that is mandatory to fulfill the entry rule, or `None` if there is no such mission.""" + return None + @dataclass class RuleData(ABC): @@ -103,6 +112,11 @@ def to_slot_data(self) -> RuleData: mission_ids, resolved_reqs ) + + def find_mandatory_mission(self) -> SC2MOGenMission | None: + if len(self.missions_to_beat) > 0: + return self.missions_to_beat[0] + return None @dataclass @@ -140,7 +154,7 @@ class CountMissionsEntryRule(EntryRule): def __init__(self, missions_to_count: List[SC2MOGenMission], target_amount: int, visual_reqs: List[Union[str, SC2MOGenMission]]): super().__init__() self.missions_to_count = missions_to_count - if target_amount == -1 or target_amount > len(missions_to_count): + if target_amount <= -1 or target_amount > len(missions_to_count): self.target_amount = len(missions_to_count) else: self.target_amount = target_amount @@ -155,7 +169,20 @@ def _get_depth(self, beaten_missions: Set[SC2MOGenMission]) -> int: return max(mission_depth, self.target_amount - 1) # -1 because depth is zero-based but amount is one-based def to_lambda(self, player: int) -> Callable[[CollectionState], bool]: - return lambda state: self.target_amount <= sum(state.has(mission.beat_item(), player) for mission in self.missions_to_count) + if self.target_amount == 0: + return always_true + + beat_items = [mission.beat_item() for mission in self.missions_to_count] + def count_missions(state: CollectionState) -> bool: + count = 0 + for mission in range(len(self.missions_to_count)): + if state.has(beat_items[mission], player): + count += 1 + if count == self.target_amount: + return True + return False + + return count_missions def to_slot_data(self) -> RuleData: resolved_reqs: List[Union[str, int]] = [req if isinstance(req, str) else req.mission.id for req in self.visual_reqs] @@ -165,6 +192,11 @@ def to_slot_data(self) -> RuleData: self.target_amount, resolved_reqs ) + + def find_mandatory_mission(self) -> SC2MOGenMission | None: + if self.target_amount > 0 and self.target_amount == len(self.missions_to_count): + return self.missions_to_count[0] + return None @dataclass @@ -216,13 +248,21 @@ def __init__(self, rules_to_check: List[EntryRule], target_amount: int, rule_id: self.rule_id = rule_id self.rules_to_check = rules_to_check self.min_depth = -1 - if target_amount == -1 or target_amount > len(rules_to_check): + if target_amount <= -1 or target_amount > len(rules_to_check): self.target_amount = len(rules_to_check) else: self.target_amount = target_amount def _is_fulfilled(self, beaten_missions: Set[SC2MOGenMission], in_region_check: bool) -> bool: - return self.target_amount <= sum(rule.is_fulfilled(beaten_missions, in_region_check) for rule in self.rules_to_check) + if len(self.rules_to_check) == 0: + return True + count = 0 + for rule in self.rules_to_check: + if rule.is_fulfilled(beaten_missions, in_region_check): + count += 1 + if count == self.target_amount: + return True + return False def _get_depth(self, beaten_missions: Set[SC2MOGenMission]) -> int: if len(self.rules_to_check) == 0: @@ -235,7 +275,21 @@ def _get_depth(self, beaten_missions: Set[SC2MOGenMission]) -> int: def to_lambda(self, player: int) -> Callable[[CollectionState], bool]: sub_lambdas = [rule.to_lambda(player) for rule in self.rules_to_check] - return lambda state, sub_lambdas=sub_lambdas: self.target_amount <= sum(sub_lambda(state) for sub_lambda in sub_lambdas) + if self.target_amount == 0: + return always_true + if len(sub_lambdas) == 1: + return sub_lambdas[0] + + def count_rules(state: CollectionState) -> bool: + count = 0 + for sub_lambda in sub_lambdas: + if sub_lambda(state): + count += 1 + if count == self.target_amount: + return True + return False + + return count_rules def to_slot_data(self) -> SubRuleRuleData: sub_rules = [rule.to_slot_data() for rule in self.rules_to_check] @@ -244,6 +298,14 @@ def to_slot_data(self) -> SubRuleRuleData: sub_rules, self.target_amount ) + + def find_mandatory_mission(self) -> SC2MOGenMission | None: + if self.target_amount > 0 and self.target_amount == len(self.rules_to_check): + for sub_rule in self.rules_to_check: + mandatory_mission = sub_rule.find_mandatory_mission() + if mandatory_mission is not None: + return mandatory_mission + return None @dataclass @@ -362,6 +424,9 @@ def to_slot_data(self) -> RuleData: item_ids, visual_reqs ) + + def find_mandatory_mission(self) -> SC2MOGenMission | None: + return None @dataclass diff --git a/worlds/sc2/mission_order/generation.py b/worlds/sc2/mission_order/generation.py index 5582d7c31116..928c0a452678 100644 --- a/worlds/sc2/mission_order/generation.py +++ b/worlds/sc2/mission_order/generation.py @@ -491,23 +491,60 @@ def make_connections(mission_order: SC2MOGenMissionOrder, world: 'SC2World'): for layout in campaign.layouts: for mission in layout.missions: if not mission.option_empty: + mission_uses_rule = mission.entry_rule.target_amount > 0 mission_rule = mission.entry_rule.to_lambda(player) + mandatory_prereq = mission.entry_rule.find_mandatory_mission() # Only layout entrances need to consider campaign & layout prerequisites if mission.option_entrance: - campaign_rule = mission.parent().parent().entry_rule.to_lambda(player) - layout_rule = mission.parent().entry_rule.to_lambda(player) - unlock_rule = lambda state, campaign_rule=campaign_rule, layout_rule=layout_rule, mission_rule=mission_rule: \ - campaign_rule(state) and layout_rule(state) and mission_rule(state) - else: + campaign_uses_rule = campaign.entry_rule.target_amount > 0 + campaign_rule = campaign.entry_rule.to_lambda(player) + layout_uses_rule = layout.entry_rule.target_amount > 0 + layout_rule = layout.entry_rule.to_lambda(player) + + # Any mandatory prerequisite mission is good enough + mandatory_prereq = campaign.entry_rule.find_mandatory_mission() if mandatory_prereq is None else mandatory_prereq + mandatory_prereq = layout.entry_rule.find_mandatory_mission() if mandatory_prereq is None else mandatory_prereq + + # Avoid calling obviously unused lambdas + if campaign_uses_rule: + if layout_uses_rule: + if mission_uses_rule: + unlock_rule = lambda state, campaign_rule=campaign_rule, layout_rule=layout_rule, mission_rule=mission_rule: \ + campaign_rule(state) and layout_rule(state) and mission_rule(state) + else: + unlock_rule = lambda state, campaign_rule=campaign_rule, layout_rule=layout_rule: \ + campaign_rule(state) and layout_rule(state) + else: + if mission_uses_rule: + unlock_rule = lambda state, campaign_rule=campaign_rule, mission_rule=mission_rule: \ + campaign_rule(state) and mission_rule(state) + else: + unlock_rule = campaign_rule + elif layout_uses_rule: + if mission_uses_rule: + unlock_rule = lambda state, layout_rule=layout_rule, mission_rule=mission_rule: \ + layout_rule(state) and mission_rule(state) + else: + unlock_rule = layout_rule + elif mission_uses_rule: + unlock_rule = mission_rule + else: + unlock_rule = None + elif mission_uses_rule: unlock_rule = mission_rule - # Individually connect to previous missions - for prev_mission in mission.prev: - connect(world, names, prev_mission.mission.mission_name, mission.mission.mission_name, - lambda state, unlock_rule=unlock_rule: unlock_rule(state)) - # If there are no previous missions, connect to Menu instead - if len(mission.prev) == 0: - connect(world, names, "Menu", mission.mission.mission_name, - lambda state, unlock_rule=unlock_rule: unlock_rule(state)) + else: + unlock_rule = None + + # Connect to a discovered mandatory mission if possible + if mandatory_prereq is not None: + connect(world, names, mandatory_prereq.mission.mission_name, mission.mission.mission_name, unlock_rule) + else: + # If no mission is known to be mandatory, connect to all previous missions instead + for prev_mission in mission.prev: + connect(world, names, prev_mission.mission.mission_name, mission.mission.mission_name, unlock_rule) + # As a last resort connect to Menu + if len(mission.prev) == 0: + connect(world, names, "Menu", mission.mission.mission_name, unlock_rule) def connect(world: 'SC2World', used_names: Dict[str, int], source: str, target: str, From 597583577a3207f6a4ad2afd9165778a010d9070 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 13 Sep 2025 16:07:13 +0200 Subject: [PATCH 0726/1218] KH1: Remove top level script & remove script_name from its component (#5443) --- KH1Client.py | 9 --------- worlds/kh1/__init__.py | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 KH1Client.py diff --git a/KH1Client.py b/KH1Client.py deleted file mode 100644 index 4c3ed501901b..000000000000 --- a/KH1Client.py +++ /dev/null @@ -1,9 +0,0 @@ -if __name__ == '__main__': - import ModuleUpdate - ModuleUpdate.update() - - import Utils - Utils.init_logging("KH1Client", exception_logger="Client") - - from worlds.kh1.Client import launch - launch() diff --git a/worlds/kh1/__init__.py b/worlds/kh1/__init__.py index f14f6ea341e3..fbdc99206a2f 100644 --- a/worlds/kh1/__init__.py +++ b/worlds/kh1/__init__.py @@ -21,7 +21,7 @@ def launch_client(): launch_component(launch, name="KH1 Client") -components.append(Component("KH1 Client", "KH1Client", func=launch_client, component_type=Type.CLIENT, icon="kh1_heart")) +components.append(Component("KH1 Client", func=launch_client, component_type=Type.CLIENT, icon="kh1_heart")) icon_paths["kh1_heart"] = f"ap:{__name__}/icons/kh1_heart.png" From 9c00eb91d6eeb822ae565ab5a1dd86882d60e857 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 14 Sep 2025 02:01:41 +0200 Subject: [PATCH 0727/1218] WebHost: fix Internal Server Error if parallel access to /room/* happens (#5444) --- WebHostLib/misc.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WebHostLib/misc.py b/WebHostLib/misc.py index c57a6386127f..b3088267792f 100644 --- a/WebHostLib/misc.py +++ b/WebHostLib/misc.py @@ -260,7 +260,10 @@ def host_room(room: UUID): # indicate that the page should reload to get the assigned port should_refresh = ((not room.last_port and now - room.creation_time < datetime.timedelta(seconds=3)) or room.last_activity < now - datetime.timedelta(seconds=room.timeout)) - with db_session: + + if now - room.last_activity > datetime.timedelta(minutes=1): + # we only set last_activity if needed, otherwise parallel access on /room will cause an internal server error + # due to "pony.orm.core.OptimisticCheckError: Object Room was updated outside of current transaction" room.last_activity = now # will trigger a spinup, if it's not already running browser_tokens = "Mozilla", "Chrome", "Safari" From 71de33d7ddc00780f8af864c96b31d97bf61f788 Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Sat, 13 Sep 2025 18:02:03 -0600 Subject: [PATCH 0728/1218] CI: Fix peer review tag on undrafting a PR (#5282) * Move ready for review condition out of non-draft check * Remove condition on labeler * Revert condition --- .github/workflows/label-pull-requests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/label-pull-requests.yml b/.github/workflows/label-pull-requests.yml index 4a7d4034590a..1675c942bddb 100644 --- a/.github/workflows/label-pull-requests.yml +++ b/.github/workflows/label-pull-requests.yml @@ -12,7 +12,6 @@ env: jobs: labeler: name: 'Apply content-based labels' - if: github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' runs-on: ubuntu-latest steps: - uses: actions/labeler@v5 From 174d89c81f0a6e7115f78f8ddbf8af33762e062b Mon Sep 17 00:00:00 2001 From: Adrian Priestley <47989725+a-priestley@users.noreply.github.com> Date: Sun, 14 Sep 2025 09:54:53 -0230 Subject: [PATCH 0729/1218] feat(workflow): Implement new Github workflow for building and pushing container images (#5242) * fix(workflows): Update Docker workflow tag pattern - Change tag pattern from "v*" to "*.*.*" for better version matching - Add new semver pattern type for major version * squash! fix(workflows): Update Docker workflow tag pattern - Change tag pattern from "v*" to "*.*.*" for better version matching - Add new semver pattern type for major version * Update docker.yml * Update docker.yml * Update docker.yml * fix(docker): Correct copy command to use recursive flag for EnemizerCLI - Changed 'cp' to 'cp -r' to properly copy EnemizerCLI directory * fixup! Update docker.yml * fix(docker): Correct copy command to use recursive flag for EnemizerCLI - Changed 'cp' to 'cp -r' to properly copy EnemizerCLI directory * chore(workflow): Update Docker workflow to support multiple platforms - Removed matrix strategy for platform selection - Set platforms directly in the Docker Buildx step * docs(deployment): Update container deployment documentation - Specify minimum versions for Docker and Podman - Add requirement for Docker Buildx plugin * fix(workflows): Exclude specific paths from Docker build triggers - Prevent unnecessary builds for documentation and deployment files * feat(ci): Update Docker workflow for multi-architecture builds - Added new build job for ARM64 architecture support - Created a multi-arch manifest to manage image variants - Improved Docker Buildx setup and push steps for both architectures * fixup! feat(ci): Update Docker workflow for multi-architecture builds - Added new build job for ARM64 architecture support - Created a multi-arch manifest to manage image variants - Improved Docker Buildx setup and push steps for both architectures * fixup! feat(ci): Update Docker workflow for multi-architecture builds - Added new build job for ARM64 architecture support - Created a multi-arch manifest to manage image variants - Improved Docker Buildx setup and push steps for both architectures * fixup! feat(ci): Update Docker workflow for multi-architecture builds - Added new build job for ARM64 architecture support - Created a multi-arch manifest to manage image variants - Improved Docker Buildx setup and push steps for both architectures * fix(workflow): Cleanup temporary image tags * fixup! fix(workflow): Cleanup temporary image tags * fixup! fix(workflow): Cleanup temporary image tags * fixup! fix(workflow): Cleanup temporary image tags * fix(workflow): Apply scoped build cache to eliminate race condition between jobs. * fixup! fix(workflow): Apply scoped build cache to eliminate race condition between jobs. * Remove branch wildcard * Test comment * Revert wildcard removal * Remove `pr` event * Revert `pr` event removal * fixup! Revert `pr` event removal * Update docker.yml * Update docker.yml * Update docker.yml * feat(workflows): Add docker workflow to compute final tags - Introduce a step to compute final tags based on GitHub ref type - Ensure 'latest' tag is set for version tags * chore(workflow): Enable manual dispatch for Docker workflow - Add workflow_dispatch event trigger to allow manual runs * fix(workflows): Update Docker workflow to handle tag outputs correctly - Use readarray to handle tags as an array - Prevent duplicate latest tags in the tags list - Set multiline output for tags in GitHub Actions * Update docker.yml Use new `is_not_default_branch` condition * Update docker.yml Allow "v" prefix for semver git tags qualifying for `latest` image tag * Update docker.yml Tighten up `tags` push pattern mirroring that of `release` workflow. * Merge branch 'ArchipelagoMW:main' into main * Update docker.yml * Merge branch 'ArchipelagoMW:main' into docker_wf * Update docker.yml Use new `is_not_default_branch` condition * Update docker.yml Allow "v" prefix for semver git tags qualifying for `latest` image tag * Update docker.yml Tighten up `tags` push pattern mirroring that of `release` workflow. * ci(docker): refactor multi-arch build to use matrix strategy - Consolidate separate amd64 and arm64 jobs into a single build job - Introduce matrix for platform, runner, suffix, and cache-scope - Generalize tag computation and build steps with matrix variables * fixup! ci(docker): refactor multi-arch build to use matrix strategy - Consolidate separate amd64 and arm64 jobs into a single build job - Introduce matrix for platform, runner, suffix, and cache-scope - Generalize tag computation and build steps with matrix variables --- .github/workflows/docker.yml | 154 +++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 000000000000..cf9ce08faf38 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,154 @@ +name: Build and Publish Docker Images + +on: + push: + paths: + - "**" + - "!docs/**" + - "!deploy/**" + - "!setup.py" + - "!.gitignore" + - "!.github/workflows/**" + - ".github/workflows/docker.yml" + branches: + - "*" + tags: + - "v?[0-9]+.[0-9]+.[0-9]*" + workflow_dispatch: + +env: + REGISTRY: ghcr.io + +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + image-name: ${{ steps.image.outputs.name }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + package-name: ${{ steps.package.outputs.name }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set lowercase image name + id: image + run: | + echo "name=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT + + - name: Set package name + id: package + run: | + echo "name=$(basename ${GITHUB_REPOSITORY,,})" >> $GITHUB_OUTPUT + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ steps.image.outputs.name }} + tags: | + type=ref,event=branch,enable={{is_not_default_branch}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=nightly,enable={{is_default_branch}} + + - name: Compute final tags + id: final-tags + run: | + readarray -t tags <<< "${{ steps.meta.outputs.tags }}" + + if [[ "${{ github.ref_type }}" == "tag" ]]; then + tag="${{ github.ref_name }}" + if [[ "$tag" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + full_latest="${{ env.REGISTRY }}/${{ steps.image.outputs.name }}:latest" + # Check if latest is already in tags to avoid duplicates + if ! printf '%s\n' "${tags[@]}" | grep -q "^$full_latest$"; then + tags+=("$full_latest") + fi + fi + fi + + # Set multiline output + echo "tags<> $GITHUB_OUTPUT + printf '%s\n' "${tags[@]}" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + build: + needs: prepare + runs-on: ${{ matrix.runner }} + permissions: + contents: read + packages: write + strategy: + matrix: + include: + - platform: amd64 + runner: ubuntu-latest + suffix: amd64 + cache-scope: amd64 + - platform: arm64 + runner: ubuntu-24.04-arm + suffix: arm64 + cache-scope: arm64 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Compute suffixed tags + id: tags + run: | + readarray -t tags <<< "${{ needs.prepare.outputs.tags }}" + suffixed=() + for t in "${tags[@]}"; do + suffixed+=("$t-${{ matrix.suffix }}") + done + echo "tags=$(IFS=','; echo "${suffixed[*]}")" >> $GITHUB_OUTPUT + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + platforms: linux/${{ matrix.platform }} + push: true + tags: ${{ steps.tags.outputs.tags }} + labels: ${{ needs.prepare.outputs.labels }} + cache-from: type=gha,scope=${{ matrix.cache-scope }} + cache-to: type=gha,mode=max,scope=${{ matrix.cache-scope }} + provenance: false + + manifest: + needs: [prepare, build] + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create and push multi-arch manifest + run: | + readarray -t tag_array <<< "${{ needs.prepare.outputs.tags }}" + + for tag in "${tag_array[@]}"; do + docker manifest create "$tag" \ + "$tag-amd64" \ + "$tag-arm64" + + docker manifest push "$tag" + done From 9fdeecd9965b188e712f7ef4024a709d9836a79b Mon Sep 17 00:00:00 2001 From: JaredWeakStrike <96694163+JaredWeakStrike@users.noreply.github.com> Date: Sun, 14 Sep 2025 20:08:57 -0400 Subject: [PATCH 0730/1218] KH2: Remove top level client script (#5446) * initial commit * remove kh2client.exe from setup --- KH2Client.py | 8 -------- worlds/kh2/__init__.py | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 KH2Client.py diff --git a/KH2Client.py b/KH2Client.py deleted file mode 100644 index 69e4adf8bf7c..000000000000 --- a/KH2Client.py +++ /dev/null @@ -1,8 +0,0 @@ -import ModuleUpdate -import Utils -from worlds.kh2.Client import launch -ModuleUpdate.update() - -if __name__ == '__main__': - Utils.init_logging("KH2Client", exception_logger="Client") - launch() diff --git a/worlds/kh2/__init__.py b/worlds/kh2/__init__.py index 19c2aee61f12..3068e7bb56de 100644 --- a/worlds/kh2/__init__.py +++ b/worlds/kh2/__init__.py @@ -20,7 +20,7 @@ def launch_client(): launch_component(launch, name="KH2Client") -components.append(Component("KH2 Client", "KH2Client", func=launch_client, component_type=Type.CLIENT)) +components.append(Component("KH2 Client", func=launch_client, component_type=Type.CLIENT)) class KingdomHearts2Web(WebWorld): From 8f2b4a961f5c956ee5aa58aad01df919371fcb42 Mon Sep 17 00:00:00 2001 From: Sunny Bat Date: Tue, 16 Sep 2025 10:26:06 -0700 Subject: [PATCH 0731/1218] Raft: Add Zipline Tool requirement to Engine controls blueprint #5455 --- worlds/raft/locations.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/worlds/raft/locations.json b/worlds/raft/locations.json index 5f73c2f8b259..8d04e3046ab4 100644 --- a/worlds/raft/locations.json +++ b/worlds/raft/locations.json @@ -810,7 +810,10 @@ { "id": 48105, "name": "Engine controls blueprint", - "region": "CaravanIsland" + "region": "CaravanIsland", + "requiresAccessToItems": [ + "Zipline tool" + ] }, { "id": 48106, From 73718bbd618651d1f75da8382944173cc6295448 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 19 Sep 2025 03:52:31 +0200 Subject: [PATCH 0732/1218] Core: make APContainer seek archipelago.json (#5261) --- worlds/Files.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/worlds/Files.py b/worlds/Files.py index 27c0e9c42e35..ece60c69e737 100644 --- a/worlds/Files.py +++ b/worlds/Files.py @@ -92,7 +92,7 @@ class APContainer: version: ClassVar[int] = container_version compression_level: ClassVar[int] = 9 compression_method: ClassVar[int] = zipfile.ZIP_DEFLATED - + manifest_path: str = "archipelago.json" path: Optional[str] def __init__(self, path: Optional[str] = None): @@ -116,7 +116,7 @@ def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None: except Exception as e: raise Exception(f"Manifest {manifest} did not convert to json.") from e else: - opened_zipfile.writestr("archipelago.json", manifest_str) + opened_zipfile.writestr(self.manifest_path, manifest_str) def read(self, file: Optional[Union[str, BinaryIO]] = None) -> None: """Read data into patch object. file can be file-like, such as an outer zip file's stream.""" @@ -137,7 +137,18 @@ def read(self, file: Optional[Union[str, BinaryIO]] = None) -> None: raise InvalidDataError(f"{message}This might be the incorrect world version for this file") from e def read_contents(self, opened_zipfile: zipfile.ZipFile) -> Dict[str, Any]: - with opened_zipfile.open("archipelago.json", "r") as f: + try: + assert self.manifest_path.endswith("archipelago.json"), "Filename should be archipelago.json" + manifest_info = opened_zipfile.getinfo(self.manifest_path) + except KeyError as e: + for info in opened_zipfile.infolist(): + if info.filename.endswith("archipelago.json"): + manifest_info = info + self.manifest_path = info.filename + break + else: + raise e + with opened_zipfile.open(manifest_info, "r") as f: manifest = json.load(f) if manifest["compatible_version"] > self.version: raise Exception(f"File (version: {manifest['compatible_version']}) too new " @@ -248,10 +259,8 @@ def get_manifest(self) -> Dict[str, Any]: manifest["compatible_version"] = 5 return manifest - def read_contents(self, opened_zipfile: zipfile.ZipFile) -> None: - super(APProcedurePatch, self).read_contents(opened_zipfile) - with opened_zipfile.open("archipelago.json", "r") as f: - manifest = json.load(f) + def read_contents(self, opened_zipfile: zipfile.ZipFile) -> Dict[str, Any]: + manifest = super(APProcedurePatch, self).read_contents(opened_zipfile) if "procedure" not in manifest: # support patching files made before moving to procedures self.procedure = [("apply_bsdiff4", ["delta.bsdiff4"])] @@ -260,6 +269,7 @@ def read_contents(self, opened_zipfile: zipfile.ZipFile) -> None: for file in opened_zipfile.namelist(): if file not in ["archipelago.json"]: self.files[file] = opened_zipfile.read(file) + return manifest def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None: super(APProcedurePatch, self).write_contents(opened_zipfile) From 3af1e92813261639e484406bbd289b2b0ba07000 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sun, 21 Sep 2025 12:47:11 -0400 Subject: [PATCH 0733/1218] TUNIC: Update name of a chest in the UT poptracker map integration #5462 --- worlds/tunic/ut_stuff.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/tunic/ut_stuff.py b/worlds/tunic/ut_stuff.py index 2cf2f96a4ff2..1192b30d1778 100644 --- a/worlds/tunic/ut_stuff.py +++ b/worlds/tunic/ut_stuff.py @@ -96,6 +96,7 @@ def map_page_index(data: Any) -> int: "[Southwest] Chest Guarded By Turret/Behind the Trees": 509342519, "[Northwest] Shadowy Corner Chest/Dark Ramps Chest": 509342520, "[Southwest] Obscured In Tunnel To Beach/Deep in the Wall": 509342521, + "[Southwest] Obscured In Tunnel To Beach/Deep between the Trees": 509342521, "[Southwest] Grapple Chest Over Walkway/Jeffry": 509342522, "[Northwest] Chest Beneath Quarry Gate/Across the Bridge": 509342523, "[Southeast] Chest Near Swamp/Under the Bridge": 509342524, From 7badc3e745f3b50f1dd6d6d4619a16d373574331 Mon Sep 17 00:00:00 2001 From: Phaneros <31861583+MatthewMarinets@users.noreply.github.com> Date: Sun, 21 Sep 2025 09:54:22 -0700 Subject: [PATCH 0734/1218] SC2: Logic bugfixes (#5461) * sc2: Fixing always-true rules in locations.py; fixed two over-constrained rules that put vanilla out-of-logic * sc2: Minor min2() optimization in rules.py * sc2: Fixing a Shatter the Sky logic bug where w/a upgrades were checked too many times and for the wrong units --- worlds/sc2/locations.py | 62 ++++++++++----------- worlds/sc2/rules.py | 116 +++++++++++++++++++++------------------- 2 files changed, 88 insertions(+), 90 deletions(-) diff --git a/worlds/sc2/locations.py b/worlds/sc2/locations.py index 0e00f4d7ea1a..203d4d26218c 100644 --- a/worlds/sc2/locations.py +++ b/worlds/sc2/locations.py @@ -2150,8 +2150,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: "Victory", SC2WOL_LOC_ID_OFFSET + 2800, LocationType.VICTORY, - lambda state: logic.terran_competent_comp(state) - and logic.terran_army_weapon_armor_upgrade_min_level(state) >= 2, + lambda state: logic.terran_competent_comp(state, 2), ), make_location_data( SC2Mission.SHATTER_THE_SKY.mission_name, @@ -2172,24 +2171,21 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: "Southeast Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2803, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state) - and logic.terran_army_weapon_armor_upgrade_min_level(state) >= 2, + lambda state: logic.terran_competent_comp(state, 2), ), make_location_data( SC2Mission.SHATTER_THE_SKY.mission_name, "Southwest Coolant Tower", SC2WOL_LOC_ID_OFFSET + 2804, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state) - and logic.terran_army_weapon_armor_upgrade_min_level(state) >= 2, + lambda state: logic.terran_competent_comp(state, 2), ), make_location_data( SC2Mission.SHATTER_THE_SKY.mission_name, "Leviathan", SC2WOL_LOC_ID_OFFSET + 2805, LocationType.VANILLA, - lambda state: logic.terran_competent_comp(state) - and logic.terran_army_weapon_armor_upgrade_min_level(state) >= 2, + lambda state: logic.terran_competent_comp(state, 2), hard_rule=logic.terran_any_anti_air, ), make_location_data( @@ -2262,7 +2258,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2HOTS_LOC_ID_OFFSET + 100, LocationType.VICTORY, lambda state: ( - logic.zerg_common_unit + logic.zerg_common_unit(state) or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) ), ), @@ -2279,7 +2275,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: LocationType.VANILLA, lambda state: adv_tactics or ( - logic.zerg_common_unit + logic.zerg_common_unit(state) or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) ), ), @@ -2290,7 +2286,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: LocationType.VANILLA, lambda state: adv_tactics or ( - logic.zerg_common_unit + logic.zerg_common_unit(state) or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) ), ), @@ -2301,7 +2297,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: LocationType.VANILLA, lambda state: adv_tactics or ( - logic.zerg_common_unit + logic.zerg_common_unit(state) or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) ), ), @@ -2324,7 +2320,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: LocationType.EXTRA, lambda state: adv_tactics or ( - logic.zerg_common_unit + logic.zerg_common_unit(state) or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) ), ), @@ -2334,7 +2330,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2HOTS_LOC_ID_OFFSET + 108, LocationType.CHALLENGE, lambda state: ( - logic.zerg_common_unit + logic.zerg_common_unit(state) or state.has_any((item_names.ZERGLING, item_names.PYGALISK), player) ), flags=LocationFlag.SPEEDRUN, @@ -3862,15 +3858,11 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2LOTV_LOC_ID_OFFSET + 300, LocationType.VICTORY, lambda state: adv_tactics - or state.count_from_list( - ( - item_names.STALKER_PHASE_REACTOR, - item_names.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES, - item_names.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION, - ), - player, - ) - >= 2, + or state.has_any(( + item_names.STALKER_PHASE_REACTOR, + item_names.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES, + item_names.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION, + ), player), ), make_location_data( SC2Mission.EVIL_AWOKEN.mission_name, @@ -4582,7 +4574,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: lambda state: ( logic.protoss_deathball(state) and logic.protoss_power_rating(state) >= 6 - and (adv_tactics or logic.protoss_fleet(state)) + and (adv_tactics or logic.protoss_unsealing_the_past_ledge_requirement(state)) ), ), make_location_data( @@ -4593,7 +4585,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: lambda state: ( logic.protoss_deathball(state) and logic.protoss_power_rating(state) >= 6 - and (adv_tactics or logic.protoss_fleet(state)) + and (adv_tactics or logic.protoss_unsealing_the_past_ledge_requirement(state)) ), ), make_location_data( @@ -7256,7 +7248,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2_RACESWAP_LOC_ID_OFFSET + 1809, LocationType.MASTERY, lambda state: ( - logic.protoss_anti_armor_anti_air + logic.protoss_anti_armor_anti_air(state) and logic.protoss_defense_rating(state, False) >= 6 and logic.protoss_common_unit(state) and logic.protoss_deathball(state) @@ -9087,7 +9079,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: "Close Obelisk", SC2_RACESWAP_LOC_ID_OFFSET + 4801, LocationType.VANILLA, - lambda state: adv_tactics or logic.zerg_common_unit, + lambda state: adv_tactics or logic.zerg_common_unit(state), ), make_location_data( SC2Mission.ECHOES_OF_THE_FUTURE_Z.mission_name, @@ -11841,7 +11833,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: "Victory", SC2_RACESWAP_LOC_ID_OFFSET + 9600, LocationType.VICTORY, - lambda state: logic.protoss_deathball + lambda state: logic.protoss_deathball(state) or (adv_tactics and logic.protoss_competent_comp(state)), ), make_location_data( @@ -11876,7 +11868,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: "Main Path Command Center", SC2_RACESWAP_LOC_ID_OFFSET + 9605, LocationType.EXTRA, - lambda state: logic.protoss_deathball + lambda state: logic.protoss_deathball(state) or (adv_tactics and logic.protoss_competent_comp(state)), ), make_location_data( @@ -12026,7 +12018,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: "Victory", SC2_RACESWAP_LOC_ID_OFFSET + 10000, LocationType.VICTORY, - lambda state: logic.zerg_competent_comp + lambda state: logic.zerg_competent_comp(state) and logic.zerg_moderate_anti_air(state), ), make_location_data( @@ -12034,7 +12026,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: "First Prisoner Group", SC2_RACESWAP_LOC_ID_OFFSET + 10001, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp + lambda state: logic.zerg_competent_comp(state) and logic.zerg_moderate_anti_air(state), ), make_location_data( @@ -12042,7 +12034,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: "Second Prisoner Group", SC2_RACESWAP_LOC_ID_OFFSET + 10002, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp + lambda state: logic.zerg_competent_comp(state) and logic.zerg_moderate_anti_air(state), ), make_location_data( @@ -12050,7 +12042,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: "First Pylon", SC2_RACESWAP_LOC_ID_OFFSET + 10003, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp + lambda state: logic.zerg_competent_comp(state) and logic.zerg_moderate_anti_air(state), ), make_location_data( @@ -12058,7 +12050,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: "Second Pylon", SC2_RACESWAP_LOC_ID_OFFSET + 10004, LocationType.VANILLA, - lambda state: logic.zerg_competent_comp + lambda state: logic.zerg_competent_comp(state) and logic.zerg_moderate_anti_air(state), ), make_location_data( @@ -12661,7 +12653,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2_RACESWAP_LOC_ID_OFFSET + 11406, LocationType.CHALLENGE, lambda state: ( - logic.zerg_brothers_in_arms_requirement + logic.zerg_brothers_in_arms_requirement(state) and logic.zerg_base_buster(state) and logic.zerg_power_rating(state) >= 8 ), diff --git a/worlds/sc2/rules.py b/worlds/sc2/rules.py index 030725946d83..e6068ab22801 100644 --- a/worlds/sc2/rules.py +++ b/worlds/sc2/rules.py @@ -47,8 +47,15 @@ from . import SC2World +def min2(a: int, b: int) -> int: + """`min()` that only takes two values; faster than baseline int by about 2x""" + if a <= b: + return a + return b + + class SC2Logic: - def __init__(self, world: Optional["SC2World"]): + def __init__(self, world: Optional["SC2World"]) -> None: # Note: Don't store a reference to the world so we can cache this object on the world object self.player = -1 if world is None else world.player self.logic_level: int = world.options.required_tactics.value if world else RequiredTactics.default @@ -109,7 +116,7 @@ def is_item_placement(self, state: CollectionState) -> bool: # has_group with count = 0 is always true for item placement and always false for SC2 item filtering return state.has_group("Missions", self.player, 0) - def get_very_hard_required_upgrade_level(self): + def get_very_hard_required_upgrade_level(self) -> bool: return 2 if self.advanced_tactics else 3 def weapon_armor_upgrade_count(self, upgrade_item: str, state: CollectionState) -> int: @@ -133,7 +140,7 @@ def weapon_armor_upgrade_count(self, upgrade_item: str, state: CollectionState) count += 1 return count - def soa_power_rating(self, state: CollectionState): + def soa_power_rating(self, state: CollectionState) -> bool: power_rating = 0 # Spear of Adun Ultimates (Strongest) for item, rating in soa_ultimate_ratings.items(): @@ -203,7 +210,7 @@ def terran_very_hard_mission_weapon_armor_level(self, state: CollectionState) -> def terran_common_unit(self, state: CollectionState) -> bool: return state.has_any(self.basic_terran_units, self.player) - def terran_early_tech(self, state: CollectionState): + def terran_early_tech(self, state: CollectionState) -> bool: """ Basic combat unit that can be deployed quickly from mission start :param state @@ -447,7 +454,7 @@ def terran_defense_rating(self, state: CollectionState, zerg_enemy: bool, air_en defense_score += 2 return defense_score - def terran_competent_comp(self, state: CollectionState) -> bool: + def terran_competent_comp(self, state: CollectionState, upgrade_level: int = 1) -> bool: # All competent comps require anti-air if not self.terran_competent_anti_air(state): return False @@ -455,12 +462,12 @@ def terran_competent_comp(self, state: CollectionState) -> bool: infantry_weapons = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_INFANTRY_WEAPON, state) infantry_armor = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_INFANTRY_ARMOR, state) infantry = state.has_any({item_names.MARINE, item_names.DOMINION_TROOPER, item_names.MARAUDER}, self.player) - if infantry_weapons >= 2 and infantry_armor >= 1 and infantry and self.terran_bio_heal(state): + if infantry_weapons >= upgrade_level + 1 and infantry_armor >= upgrade_level and infantry and self.terran_bio_heal(state): return True # Mass Air-To-Ground ship_weapons = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_SHIP_WEAPON, state) ship_armor = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_SHIP_ARMOR, state) - if ship_weapons >= 1 and ship_armor >= 1: + if ship_weapons >= upgrade_level and ship_armor >= upgrade_level: air = ( state.has_any({item_names.BANSHEE, item_names.BATTLECRUISER}, self.player) or state.has_all({item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY}, self.player) @@ -473,7 +480,7 @@ def terran_competent_comp(self, state: CollectionState) -> bool: # Strong Mech vehicle_weapons = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_VEHICLE_WEAPON, state) vehicle_armor = self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_TERRAN_VEHICLE_ARMOR, state) - if vehicle_weapons >= 1 and vehicle_armor >= 1: + if vehicle_weapons >= upgrade_level and vehicle_armor >= upgrade_level: strong_vehicle = state.has_any({item_names.THOR, item_names.SIEGE_TANK}, self.player) light_frontline = state.has_any( {item_names.MARINE, item_names.DOMINION_TROOPER, item_names.HELLION, item_names.VULTURE}, self.player @@ -762,27 +769,27 @@ def zerg_defense_rating(self, state: CollectionState, zerg_enemy: bool, air_enem def zerg_army_weapon_armor_upgrade_min_level(self, state: CollectionState) -> int: count: int = WEAPON_ARMOR_UPGRADE_MAX_LEVEL if self.has_zerg_melee_unit: - count = min(count, self.zerg_melee_weapon_armor_upgrade_min_level(state)) + count = min2(count, self.zerg_melee_weapon_armor_upgrade_min_level(state)) if self.has_zerg_ranged_unit: - count = min(count, self.zerg_ranged_weapon_armor_upgrade_min_level(state)) + count = min2(count, self.zerg_ranged_weapon_armor_upgrade_min_level(state)) if self.has_zerg_air_unit: - count = min(count, self.zerg_flyer_weapon_armor_upgrade_min_level(state)) + count = min2(count, self.zerg_flyer_weapon_armor_upgrade_min_level(state)) return count def zerg_melee_weapon_armor_upgrade_min_level(self, state: CollectionState) -> int: - return min( + return min2( self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_MELEE_ATTACK, state), self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_GROUND_CARAPACE, state), ) def zerg_ranged_weapon_armor_upgrade_min_level(self, state: CollectionState) -> int: - return min( + return min2( self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_MISSILE_ATTACK, state), self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_GROUND_CARAPACE, state), ) def zerg_flyer_weapon_armor_upgrade_min_level(self, state: CollectionState) -> int: - return min( + return min2( self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_FLYER_ATTACK, state), self.weapon_armor_upgrade_count(item_names.PROGRESSIVE_ZERG_FLYER_CARAPACE, state), ) @@ -1082,20 +1089,17 @@ def zerg_base_buster(self, state: CollectionState) -> bool: ) ) - def zergling_hydra_roach_start(self, state: CollectionState): + def zergling_hydra_roach_start(self, state: CollectionState) -> bool: """ Created mainly for engine of destruction start, but works for other missions with no-build starts. """ - return state.has_any( - { + return state.has_any(( item_names.ZERGLING_ADRENAL_OVERLOAD, item_names.HYDRALISK_FRENZY, item_names.ROACH_HYDRIODIC_BILE, item_names.ZERGLING_RAPTOR_STRAIN, item_names.ROACH_CORPSER_STRAIN, - }, - self.player, - ) + ), self.player) def kerrigan_levels(self, state: CollectionState, target: int, story_levels_available=True) -> bool: if (story_levels_available and self.story_levels_granted) or not self.kerrigan_unit_available: @@ -1111,7 +1115,7 @@ def kerrigan_levels(self, state: CollectionState, target: int, story_levels_avai # Levels from missions beaten levels = self.kerrigan_levels_per_mission_completed * state.count_group("Missions", self.player) if self.kerrigan_levels_per_mission_completed_cap != -1: - levels = min(levels, self.kerrigan_levels_per_mission_completed_cap) + levels = min2(levels, self.kerrigan_levels_per_mission_completed_cap) # Levels from items for kerrigan_level_item in kerrigan_levels: level_amount = get_full_item_list()[kerrigan_level_item].number @@ -1119,7 +1123,7 @@ def kerrigan_levels(self, state: CollectionState, target: int, story_levels_avai levels += item_count * level_amount # Total level cap if self.kerrigan_total_level_cap != -1: - levels = min(levels, self.kerrigan_total_level_cap) + levels = min2(levels, self.kerrigan_total_level_cap) return levels >= target @@ -1625,20 +1629,17 @@ def protoss_mineral_dump(self, state: CollectionState) -> bool: and state.has_any((item_names.SUPPLICANT, item_names.SHIELD_BATTERY), self.player) ) - def zealot_sentry_slayer_start(self, state: CollectionState): + def zealot_sentry_slayer_start(self, state: CollectionState) -> bool: """ Created mainly for engine of destruction start, but works for other missions with no-build starts. """ - return state.has_any( - { + return state.has_any(( item_names.ZEALOT_WHIRLWIND, item_names.SENTRY_DOUBLE_SHIELD_RECHARGE, item_names.SLAYER_PHASE_BLINK, item_names.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES, item_names.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION, - }, - self.player, - ) + ), self.player) # Mission-specific rules def ghost_of_a_chance_requirement(self, state: CollectionState) -> bool: @@ -2012,7 +2013,7 @@ def zerg_supernova_requirement(self, state) -> bool: and (self.advanced_tactics or state.has(item_names.YGGDRASIL, self.player)) ) - def protoss_supernova_requirement(self, state: CollectionState): + def protoss_supernova_requirement(self, state: CollectionState) -> bool: return ( ( state.count(item_names.PROGRESSIVE_WARP_RELOCATE, self.player) >= 2 @@ -2133,7 +2134,7 @@ def protoss_maw_requirement(self, state: CollectionState) -> bool: and self.protoss_fleet(state) ) - def terran_engine_of_destruction_requirement(self, state: CollectionState) -> int: + def terran_engine_of_destruction_requirement(self, state: CollectionState) -> bool: power_rating = self.terran_power_rating(state) if power_rating < 3 or not self.marine_medic_upgrade(state) or not self.terran_common_unit(state): return False @@ -2146,7 +2147,7 @@ def terran_engine_of_destruction_requirement(self, state: CollectionState) -> in and state.has_any((item_names.BANSHEE, item_names.LIBERATOR), self.player) ) - def zerg_engine_of_destruction_requirement(self, state: CollectionState) -> int: + def zerg_engine_of_destruction_requirement(self, state: CollectionState) -> bool: power_rating = self.zerg_power_rating(state) if ( power_rating < 3 @@ -2161,21 +2162,21 @@ def zerg_engine_of_destruction_requirement(self, state: CollectionState) -> int: else: return self.zerg_base_buster(state) - def protoss_engine_of_destruction_requirement(self, state: CollectionState): + def protoss_engine_of_destruction_requirement(self, state: CollectionState) -> bool: return ( self.zealot_sentry_slayer_start(state) and self.protoss_repair_odin(state) and (self.protoss_deathball(state) or self.protoss_fleet(state)) ) - def zerg_repair_odin(self, state: CollectionState): + def zerg_repair_odin(self, state: CollectionState) -> bool: return ( self.zerg_has_infested_scv(state) or state.has_all({item_names.SWARM_QUEEN_BIO_MECHANICAL_TRANSFUSION, item_names.SWARM_QUEEN}, self.player) or (self.advanced_tactics and state.has(item_names.SWARM_QUEEN, self.player)) ) - def protoss_repair_odin(self, state: CollectionState): + def protoss_repair_odin(self, state: CollectionState) -> bool: return ( state.has(item_names.SENTRY, self.player) or state.has_all((item_names.CARRIER, item_names.CARRIER_REPAIR_DRONES), self.player) @@ -2196,7 +2197,7 @@ def zerg_in_utter_darkness_requirement(self, state: CollectionState) -> bool: def protoss_in_utter_darkness_requirement(self, state: CollectionState) -> bool: return self.protoss_competent_comp(state) and self.protoss_defense_rating(state, True) >= 4 - def terran_all_in_requirement(self, state: CollectionState): + def terran_all_in_requirement(self, state: CollectionState) -> bool: """ All-in """ @@ -2228,7 +2229,7 @@ def terran_all_in_requirement(self, state: CollectionState): and state.has_any({item_names.HIVE_MIND_EMULATOR, item_names.PSI_DISRUPTER, item_names.MISSILE_TURRET}, self.player) ) - def zerg_all_in_requirement(self, state: CollectionState): + def zerg_all_in_requirement(self, state: CollectionState) -> bool: """ All-in (Zerg) """ @@ -2264,7 +2265,7 @@ def zerg_all_in_requirement(self, state: CollectionState): and state.has_any({item_names.SPORE_CRAWLER, item_names.INFESTED_MISSILE_TURRET}, self.player) ) - def protoss_all_in_requirement(self, state: CollectionState): + def protoss_all_in_requirement(self, state: CollectionState) -> bool: """ All-in (Protoss) """ @@ -2436,21 +2437,19 @@ def protoss_the_reckoning_requirement(self, state: CollectionState) -> bool: def protoss_can_attack_behind_chasm(self, state: CollectionState) -> bool: return ( - state.has_any( - { - item_names.SCOUT, - item_names.TEMPEST, - item_names.CARRIER, - item_names.SKYLORD, - item_names.TRIREME, - item_names.VOID_RAY, - item_names.DESTROYER, - item_names.PULSAR, - item_names.DAWNBRINGER, - item_names.MOTHERSHIP, - }, - self.player, - ) + state.has_any(( + item_names.SCOUT, + item_names.SKIRMISHER, + item_names.TEMPEST, + item_names.CARRIER, + item_names.SKYLORD, + item_names.TRIREME, + item_names.VOID_RAY, + item_names.DESTROYER, + item_names.PULSAR, + item_names.DAWNBRINGER, + item_names.MOTHERSHIP, + ), self.player) or self.protoss_has_blink(state) or ( state.has(item_names.WARP_PRISM, self.player) @@ -2697,6 +2696,12 @@ def zerg_harbinger_of_oblivion_requirement(self, state: CollectionState) -> bool and (self.take_over_ai_allies or (self.zerg_competent_comp(state) and self.zerg_big_monsters(state))) and self.zerg_power_rating(state) >= 6 ) + + def protoss_unsealing_the_past_ledge_requirement(self, state: CollectionState) -> bool: + return ( + state.has_any((item_names.COLOSSUS, item_names.WRATHWALKER), self.player) + or self.protoss_can_attack_behind_chasm(state) + ) def terran_unsealing_the_past_requirement(self, state: CollectionState) -> bool: return ( @@ -2704,7 +2709,7 @@ def terran_unsealing_the_past_requirement(self, state: CollectionState) -> bool: and self.terran_competent_comp(state) and self.terran_power_rating(state) >= 6 and ( - state.has_all({item_names.SIEGE_TANK, item_names.SIEGE_TANK_JUMP_JETS}, self.player) + state.has_all((item_names.SIEGE_TANK, item_names.SIEGE_TANK_JUMP_JETS), self.player) or state.has_all( {item_names.BATTLECRUISER, item_names.BATTLECRUISER_ATX_LASER_BATTERY, item_names.BATTLECRUISER_MOIRAI_IMPULSE_DRIVE}, self.player ) @@ -3132,8 +3137,9 @@ def sudden_strike_requirement(self, state: CollectionState) -> bool: and (self.terran_cliffjumper(state) or state.has(item_names.BANSHEE, self.player)) and self.nova_splash(state) and self.terran_defense_rating(state, True, False) >= 3 - and self.advanced_tactics - or state.has(item_names.NOVA_JUMP_SUIT_MODULE, self.player) + and (self.advanced_tactics + or state.has(item_names.NOVA_JUMP_SUIT_MODULE, self.player) + ) ) def enemy_intelligence_garrisonable_unit(self, state: CollectionState) -> bool: From 1bd44e1e35bc45af61370323d79997369e49e007 Mon Sep 17 00:00:00 2001 From: agilbert1412 Date: Sun, 21 Sep 2025 12:58:15 -0400 Subject: [PATCH 0735/1218] Stardew Valley: Fixed Traveling merchant flaky test (#5434) * - Made the traveling cart test not be flaky due to worlds caching # Conflicts: # worlds/stardew_valley/rules.py * - Made the traveling merchant test less flaky # Conflicts: # worlds/stardew_valley/test/rules/TestTravelingMerchant.py --- worlds/stardew_valley/rules.py | 2 +- worlds/stardew_valley/test/rules/TestTravelingMerchant.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/worlds/stardew_valley/rules.py b/worlds/stardew_valley/rules.py index 2fb95a98f62d..7351871a3954 100644 --- a/worlds/stardew_valley/rules.py +++ b/worlds/stardew_valley/rules.py @@ -206,7 +206,7 @@ def set_entrance_rules(logic: StardewLogic, multiworld, player, world_options: S set_entrance_rule(multiworld, player, Entrance.enter_skull_cavern, logic.received(Wallet.skull_key)) set_entrance_rule(multiworld, player, LogicEntrance.talk_to_mines_dwarf, logic.wallet.can_speak_dwarf() & logic.tool.has_tool(Tool.pickaxe, ToolMaterial.iron)) - set_entrance_rule(multiworld, player, LogicEntrance.buy_from_traveling_merchant, logic.traveling_merchant.has_days() & logic.money.can_spend(1000)) + set_entrance_rule(multiworld, player, LogicEntrance.buy_from_traveling_merchant, logic.traveling_merchant.has_days() & logic.money.can_spend(1200)) set_entrance_rule(multiworld, player, LogicEntrance.buy_from_raccoon, logic.quest.has_raccoon_shop()) set_entrance_rule(multiworld, player, LogicEntrance.fish_in_waterfall, logic.skill.has_level(Skill.fishing, 5) & logic.tool.has_fishing_rod(2)) diff --git a/worlds/stardew_valley/test/rules/TestTravelingMerchant.py b/worlds/stardew_valley/test/rules/TestTravelingMerchant.py index 57b88747909f..aa7f46d07b03 100644 --- a/worlds/stardew_valley/test/rules/TestTravelingMerchant.py +++ b/worlds/stardew_valley/test/rules/TestTravelingMerchant.py @@ -1,8 +1,13 @@ from ..bases import SVTestBase +from ... import SeasonRandomization, EntranceRandomization from ...locations import location_table, LocationTags class TestTravelingMerchant(SVTestBase): + options = { + SeasonRandomization: SeasonRandomization.option_randomized_not_winter, + EntranceRandomization: EntranceRandomization.option_disabled, + } def test_purchase_from_traveling_merchant_requires_money(self): traveling_merchant_location_names = [l for l in self.get_real_location_names() if LocationTags.TRAVELING_MERCHANT in location_table[l].tags] From 9e96cece569c4fa9f0485a499c1d5862f1e10b0b Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Sun, 21 Sep 2025 12:59:40 -0400 Subject: [PATCH 0736/1218] LADX: Fix quickswap #5399 --- worlds/ladx/LADXR/generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/ladx/LADXR/generator.py b/worlds/ladx/LADXR/generator.py index 81ca66601049..4ae31d584941 100644 --- a/worlds/ladx/LADXR/generator.py +++ b/worlds/ladx/LADXR/generator.py @@ -242,9 +242,9 @@ def generateRom(base_rom: bytes, args, patch_data: Dict): # patches.health.setStartHealth(rom, 1) patches.inventory.songSelectAfterOcarinaSelect(rom) - if options["quickswap"] == 'a': + if options["quickswap"] == Options.Quickswap.option_a: patches.core.quickswap(rom, 1) - elif options["quickswap"] == 'b': + elif options["quickswap"] == Options.Quickswap.option_b: patches.core.quickswap(rom, 0) patches.core.addBootsControls(rom, options["boots_controls"]) From 6c45c8d606fdf771141807aad553b0953f8f2180 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 21 Sep 2025 19:23:29 +0200 Subject: [PATCH 0737/1218] Core: make countdown a "admin" only command (#5463) --- MultiServer.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 45b1178d8412..06223a3ee2dd 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1350,19 +1350,6 @@ def _error_parsing_command(self, exception: Exception): class CommonCommandProcessor(CommandProcessor): ctx: Context - def _cmd_countdown(self, seconds: str = "10") -> bool: - """Start a countdown in seconds""" - try: - timer = int(seconds, 10) - except ValueError: - timer = 10 - else: - if timer > 60 * 60: - raise ValueError(f"{timer} is invalid. Maximum is 1 hour.") - - async_start(countdown(self.ctx, timer)) - return True - def _cmd_options(self): """List all current options. Warning: lists password.""" self.output("Current options:") @@ -2259,6 +2246,19 @@ def _cmd_collect(self, player_name: str) -> bool: self.output(f"Could not find player {player_name} to collect") return False + def _cmd_countdown(self, seconds: str = "10") -> bool: + """Start a countdown in seconds""" + try: + timer = int(seconds, 10) + except ValueError: + timer = 10 + else: + if timer > 60 * 60: + raise ValueError(f"{timer} is invalid. Maximum is 1 hour.") + + async_start(countdown(self.ctx, timer)) + return True + @mark_raw def _cmd_release(self, player_name: str) -> bool: """Send out the remaining items from a player to their intended recipients.""" From 68187ba25fae8fa5ac448d2cc5eae8932e37a961 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 22 Sep 2025 00:17:10 +0200 Subject: [PATCH 0738/1218] WebHost: remove team argument from tracker arguments where it's irrelevant (#5272) --- WebHostLib/templates/genericTracker.html | 4 +- WebHostLib/templates/multispheretracker.html | 10 +-- .../templates/multitrackerHintTable.html | 4 +- WebHostLib/tracker.py | 74 +++++++++---------- 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/WebHostLib/templates/genericTracker.html b/WebHostLib/templates/genericTracker.html index b92097ceea08..2598aa12194b 100644 --- a/WebHostLib/templates/genericTracker.html +++ b/WebHostLib/templates/genericTracker.html @@ -98,7 +98,7 @@ {% if hint.finding_player == player %} {{ player_names_with_alias[(team, hint.finding_player)] }} - {% elif get_slot_info(team, hint.finding_player).type == 2 %} + {% elif get_slot_info(hint.finding_player).type == 2 %} {{ player_names_with_alias[(team, hint.finding_player)] }} {% else %} @@ -109,7 +109,7 @@ {% if hint.receiving_player == player %} {{ player_names_with_alias[(team, hint.receiving_player)] }} - {% elif get_slot_info(team, hint.receiving_player).type == 2 %} + {% elif get_slot_info(hint.receiving_player).type == 2 %} {{ player_names_with_alias[(team, hint.receiving_player)] }} {% else %} diff --git a/WebHostLib/templates/multispheretracker.html b/WebHostLib/templates/multispheretracker.html index a86697498396..56aa8704ed7e 100644 --- a/WebHostLib/templates/multispheretracker.html +++ b/WebHostLib/templates/multispheretracker.html @@ -45,15 +45,15 @@ {%- set current_sphere = loop.index %} {%- for player, sphere_location_ids in sphere.items() %} {%- set checked_locations = tracker_data.get_player_checked_locations(team, player) %} - {%- set finder_game = tracker_data.get_player_game(team, player) %} - {%- set player_location_data = tracker_data.get_player_locations(team, player) %} + {%- set finder_game = tracker_data.get_player_game(player) %} + {%- set player_location_data = tracker_data.get_player_locations(player) %} {%- for location_id in sphere_location_ids.intersection(checked_locations) %} {%- set item_id, receiver, item_flags = player_location_data[location_id] %} - {%- set receiver_game = tracker_data.get_player_game(team, receiver) %} + {%- set receiver_game = tracker_data.get_player_game(receiver) %} {{ current_sphere }} - {{ tracker_data.get_player_name(team, player) }} - {{ tracker_data.get_player_name(team, receiver) }} + {{ tracker_data.get_player_name(player) }} + {{ tracker_data.get_player_name(receiver) }} {{ tracker_data.item_id_to_name[receiver_game][item_id] }} {{ tracker_data.location_id_to_name[finder_game][location_id] }} {{ finder_game }} diff --git a/WebHostLib/templates/multitrackerHintTable.html b/WebHostLib/templates/multitrackerHintTable.html index fcc15fb37a9f..9d9d6249c171 100644 --- a/WebHostLib/templates/multitrackerHintTable.html +++ b/WebHostLib/templates/multitrackerHintTable.html @@ -22,14 +22,14 @@ -%} - {% if get_slot_info(team, hint.finding_player).type == 2 %} + {% if get_slot_info(hint.finding_player).type == 2 %} {{ player_names_with_alias[(team, hint.finding_player)] }} {% else %} {{ player_names_with_alias[(team, hint.finding_player)] }} {% endif %} - {% if get_slot_info(team, hint.receiving_player).type == 2 %} + {% if get_slot_info(hint.receiving_player).type == 2 %} {{ player_names_with_alias[(team, hint.receiving_player)] }} {% else %} {{ player_names_with_alias[(team, hint.receiving_player)] }} diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py index 356eb9768434..759bc7b625d5 100644 --- a/WebHostLib/tracker.py +++ b/WebHostLib/tracker.py @@ -85,27 +85,27 @@ def get_seed_name(self) -> str: """Retrieves the seed name.""" return self._multidata["seed_name"] - def get_slot_data(self, team: int, player: int) -> Dict[str, Any]: + def get_slot_data(self, player: int) -> Dict[str, Any]: """Retrieves the slot data for a given player.""" return self._multidata["slot_data"][player] - def get_slot_info(self, team: int, player: int) -> NetworkSlot: + def get_slot_info(self, player: int) -> NetworkSlot: """Retrieves the NetworkSlot data for a given player.""" return self._multidata["slot_info"][player] - def get_player_name(self, team: int, player: int) -> str: + def get_player_name(self, player: int) -> str: """Retrieves the slot name for a given player.""" - return self.get_slot_info(team, player).name + return self.get_slot_info(player).name - def get_player_game(self, team: int, player: int) -> str: + def get_player_game(self, player: int) -> str: """Retrieves the game for a given player.""" - return self.get_slot_info(team, player).game + return self.get_slot_info(player).game - def get_player_locations(self, team: int, player: int) -> Dict[int, ItemMetadata]: + def get_player_locations(self, player: int) -> Dict[int, ItemMetadata]: """Retrieves all locations with their containing item's metadata for a given player.""" return self._multidata["locations"][player] - def get_player_starting_inventory(self, team: int, player: int) -> List[int]: + def get_player_starting_inventory(self, player: int) -> List[int]: """Retrieves a list of all item codes a given slot starts with.""" return self._multidata["precollected_items"][player] @@ -116,7 +116,7 @@ def get_player_checked_locations(self, team: int, player: int) -> Set[int]: @_cache_results def get_player_missing_locations(self, team: int, player: int) -> Set[int]: """Retrieves the set of all locations not marked complete by this player.""" - return set(self.get_player_locations(team, player)) - self.get_player_checked_locations(team, player) + return set(self.get_player_locations(player)) - self.get_player_checked_locations(team, player) def get_player_received_items(self, team: int, player: int) -> List[NetworkItem]: """Returns all items received to this player in order of received.""" @@ -126,7 +126,7 @@ def get_player_received_items(self, team: int, player: int) -> List[NetworkItem] def get_player_inventory_counts(self, team: int, player: int) -> collections.Counter: """Retrieves a dictionary of all items received by their id and their received count.""" received_items = self.get_player_received_items(team, player) - starting_items = self.get_player_starting_inventory(team, player) + starting_items = self.get_player_starting_inventory(player) inventory = collections.Counter() for item in received_items: inventory[item.item] += 1 @@ -179,7 +179,7 @@ def get_team_hints(self) -> Dict[int, Set[Hint]]: def get_team_locations_total_count(self) -> Dict[int, int]: """Retrieves a dictionary of total player locations each team has.""" return { - team: sum(len(self.get_player_locations(team, player)) for player in players) + team: sum(len(self.get_player_locations(player)) for player in players) for team, players in self.get_all_players().items() } @@ -210,7 +210,7 @@ def get_all_players(self) -> Dict[int, List[int]]: return { 0: [ player for player, slot_info in self._multidata["slot_info"].items() - if self.get_slot_info(0, player).type == SlotType.player + if self.get_slot_info(player).type == SlotType.player ] } @@ -226,7 +226,7 @@ def get_room_saving_second(self) -> int: def get_room_locations(self) -> Dict[TeamPlayer, Dict[int, ItemMetadata]]: """Retrieves a dictionary of all locations and their associated item metadata per player.""" return { - (team, player): self.get_player_locations(team, player) + (team, player): self.get_player_locations(player) for team, players in self.get_all_players().items() for player in players } @@ -234,7 +234,7 @@ def get_room_locations(self) -> Dict[TeamPlayer, Dict[int, ItemMetadata]]: def get_room_games(self) -> Dict[TeamPlayer, str]: """Retrieves a dictionary of games for each player.""" return { - (team, player): self.get_player_game(team, player) + (team, player): self.get_player_game(player) for team, players in self.get_all_slots().items() for player in players } @@ -262,9 +262,9 @@ def get_room_long_player_names(self) -> Dict[TeamPlayer, str]: for player in players: alias = self.get_player_alias(team, player) if alias: - long_player_names[team, player] = f"{alias} ({self.get_player_name(team, player)})" + long_player_names[team, player] = f"{alias} ({self.get_player_name(player)})" else: - long_player_names[team, player] = self.get_player_name(team, player) + long_player_names[team, player] = self.get_player_name(player) return long_player_names @@ -344,7 +344,7 @@ def get_timeout_and_player_tracker(room: Room, tracked_team: int, tracked_player tracker_data = TrackerData(room) # Load and render the game-specific player tracker, or fallback to generic tracker if none exists. - game_specific_tracker = _player_trackers.get(tracker_data.get_player_game(tracked_team, tracked_player), None) + game_specific_tracker = _player_trackers.get(tracker_data.get_player_game(tracked_player), None) if game_specific_tracker and not generic: tracker = game_specific_tracker(tracker_data, tracked_team, tracked_player) else: @@ -409,10 +409,10 @@ def get_enabled_multiworld_trackers(room: Room) -> Dict[str, Callable]: def render_generic_tracker(tracker_data: TrackerData, team: int, player: int) -> str: - game = tracker_data.get_player_game(team, player) + game = tracker_data.get_player_game(player) received_items_in_order = {} - starting_inventory = tracker_data.get_player_starting_inventory(team, player) + starting_inventory = tracker_data.get_player_starting_inventory(player) for index, item in enumerate(starting_inventory): received_items_in_order[item] = index for index, network_item in enumerate(tracker_data.get_player_received_items(team, player), @@ -428,7 +428,7 @@ def render_generic_tracker(tracker_data: TrackerData, team: int, player: int) -> player=player, player_name=tracker_data.get_room_long_player_names()[team, player], inventory=tracker_data.get_player_inventory_counts(team, player), - locations=tracker_data.get_player_locations(team, player), + locations=tracker_data.get_player_locations(player), checked_locations=tracker_data.get_player_checked_locations(team, player), received_items=received_items_in_order, saving_second=tracker_data.get_room_saving_second(), @@ -500,7 +500,7 @@ def render_Factorio_multiworld_tracker(tracker_data: TrackerData, enabled_tracke tracker_data.item_id_to_name["Factorio"][item_id]: count for item_id, count in tracker_data.get_player_inventory_counts(team, player).items() }) for team, players in tracker_data.get_all_players().items() for player in players - if tracker_data.get_player_game(team, player) == "Factorio" + if tracker_data.get_player_game(player) == "Factorio" } return render_template( @@ -589,7 +589,7 @@ def prepare_inventories(team: int, player: int, inventory: Counter[str], tracker # Highlight 'bombs' if we received any bomb upgrades in bombless start. # In race mode, we'll just assume bombless start for simplicity. - if tracker_data.get_slot_data(team, player).get("bombless_start", True): + if tracker_data.get_slot_data(player).get("bombless_start", True): inventory["Bombs"] = sum(count for item, count in inventory.items() if item.startswith("Bomb Upgrade")) else: inventory["Bombs"] = 1 @@ -605,7 +605,7 @@ def render_ALinkToThePast_multiworld_tracker(tracker_data: TrackerData, enabled_ for code, count in tracker_data.get_player_inventory_counts(team, player).items() }) for team, players in tracker_data.get_all_players().items() - for player in players if tracker_data.get_slot_info(team, player).game == "A Link to the Past" + for player in players if tracker_data.get_slot_info(player).game == "A Link to the Past" } # Translate non-progression items to progression items for tracker simplicity. @@ -624,7 +624,7 @@ def render_ALinkToThePast_multiworld_tracker(tracker_data: TrackerData, enabled_ for region_name in known_regions } for team, players in tracker_data.get_all_players().items() - for player in players if tracker_data.get_slot_info(team, player).game == "A Link to the Past" + for player in players if tracker_data.get_slot_info(player).game == "A Link to the Past" } # Get a totals count. @@ -698,7 +698,7 @@ def render_ALinkToThePast_tracker(tracker_data: TrackerData, team: int, player: team=team, player=player, inventory=inventory, - player_name=tracker_data.get_player_name(team, player), + player_name=tracker_data.get_player_name(player), regions=regions, known_regions=known_regions, ) @@ -845,7 +845,7 @@ def lookup_and_trim(id, area): return full_name[len(area):] return full_name - locations = tracker_data.get_player_locations(team, player) + locations = tracker_data.get_player_locations(player) checked_locations = tracker_data.get_player_checked_locations(team, player).intersection(set(locations)) location_info = {} checks_done = {} @@ -907,7 +907,7 @@ def lookup_and_trim(id, area): player=player, team=team, room=tracker_data.room, - player_name=tracker_data.get_player_name(team, player), + player_name=tracker_data.get_player_name(player), icons=icons, acquired_items={lookup_any_item_id_to_name[id] for id, count in inventory.items() if count > 0}, checks_done=checks_done, checks_in_area=checks_in_area, location_info=location_info, @@ -966,7 +966,7 @@ def render_Timespinner_tracker(tracker_data: TrackerData, team: int, player: int 1337246, 1337247, 1337248, 1337249] } - slot_data = tracker_data.get_slot_data(team, player) + slot_data = tracker_data.get_slot_data(player) if (slot_data["DownloadableItems"]): timespinner_location_ids["Present"] += [1337156, 1337157] + list(range(1337159, 1337170)) if (slot_data["Cantoran"]): @@ -1015,7 +1015,7 @@ def render_Timespinner_tracker(tracker_data: TrackerData, team: int, player: int player=player, team=team, room=tracker_data.room, - player_name=tracker_data.get_player_name(team, player), + player_name=tracker_data.get_player_name(player), checks_done=checks_done, checks_in_area=checks_in_area, location_info=location_info, @@ -1124,7 +1124,7 @@ def render_SuperMetroid_tracker(tracker_data: TrackerData, team: int, player: in player=player, team=team, room=tracker_data.room, - player_name=tracker_data.get_player_name(team, player), + player_name=tracker_data.get_player_name(player), checks_done=checks_done, checks_in_area=checks_in_area, location_info=location_info, @@ -1174,7 +1174,7 @@ def render_ChecksFinder_tracker(tracker_data: TrackerData, team: int, player: in display_data = {} inventory = tracker_data.get_player_inventory_counts(team, player) - locations = tracker_data.get_player_locations(team, player) + locations = tracker_data.get_player_locations(player) # Multi-items multi_items = { @@ -1216,7 +1216,7 @@ def render_ChecksFinder_tracker(tracker_data: TrackerData, team: int, player: in player=player, team=team, room=tracker_data.room, - player_name=tracker_data.get_player_name(team, player), + player_name=tracker_data.get_player_name(player), checks_done=checks_done, checks_in_area=checks_in_area, location_info=location_info, @@ -1244,7 +1244,7 @@ def render_Starcraft2_tracker(tracker_data: TrackerData, team: int, player: int) UPGRADE_RESEARCH_SPEED_ITEM_ID = 1807 UPGRADE_RESEARCH_COST_ITEM_ID = 1808 REDUCED_MAX_SUPPLY_ITEM_ID = 1850 - slot_data = tracker_data.get_slot_data(team, player) + slot_data = tracker_data.get_slot_data(player) inventory: collections.Counter[int] = tracker_data.get_player_inventory_counts(team, player) item_id_to_name = tracker_data.item_id_to_name["Starcraft 2"] location_id_to_name = tracker_data.location_id_to_name["Starcraft 2"] @@ -1260,10 +1260,10 @@ def render_Starcraft2_tracker(tracker_data: TrackerData, team: int, player: int) display_data["shield_regen_count"] = inventory.get(SHIELD_REGENERATION_ITEM_ID, 0) display_data["upgrade_speed_count"] = inventory.get(UPGRADE_RESEARCH_SPEED_ITEM_ID, 0) display_data["research_cost_count"] = inventory.get(UPGRADE_RESEARCH_COST_ITEM_ID, 0) - + # Locations have_nco_locations = False - locations = tracker_data.get_player_locations(team, player) + locations = tracker_data.get_player_locations(player) checked_locations = tracker_data.get_player_checked_locations(team, player) missions: dict[str, list[tuple[str, bool]]] = {} for location_id in locations: @@ -1418,7 +1418,7 @@ def render_Starcraft2_tracker(tracker_data: TrackerData, team: int, player: int) # the maximum bundle contribution, not the sum inventory[upgrade_id] = bundle_amount - + # Victory condition game_state = tracker_data.get_player_client_status(team, player) display_data["game_finished"] = game_state == ClientStatus.CLIENT_GOAL @@ -1436,7 +1436,7 @@ def render_Starcraft2_tracker(tracker_data: TrackerData, team: int, player: int) player=player, team=team, room=tracker_data.room, - player_name=tracker_data.get_player_name(team, player), + player_name=tracker_data.get_player_name(player), missions=missions, locations=locations, checked_locations=checked_locations, From fb9011da637985f511f15bf0f77824089144b5f3 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 22 Sep 2025 00:25:12 +0200 Subject: [PATCH 0739/1218] WebHost: revamp /api/*tracker/ (#5388) --- WebHostLib/api/tracker.py | 246 +++++++++++++++++------------------ WebHostLib/tracker.py | 1 - docs/webhost api.md | 244 ++++++++++++++++------------------ test/webhost/test_tracker.py | 10 ++ 4 files changed, 246 insertions(+), 255 deletions(-) diff --git a/WebHostLib/api/tracker.py b/WebHostLib/api/tracker.py index 4ea3a2339233..4956e6441fa9 100644 --- a/WebHostLib/api/tracker.py +++ b/WebHostLib/api/tracker.py @@ -11,6 +11,47 @@ from WebHostLib.tracker import TrackerData +class PlayerAlias(TypedDict): + team: int + player: int + alias: str | None + + +class PlayerItemsReceived(TypedDict): + team: int + player: int + items: list[NetworkItem] + + +class PlayerChecksDone(TypedDict): + team: int + player: int + locations: list[int] + + +class TeamTotalChecks(TypedDict): + team: int + checks_done: int + + +class PlayerHints(TypedDict): + team: int + player: int + hints: list[Hint] + + +class PlayerTimer(TypedDict): + team: int + player: int + time: datetime | None + + +class PlayerStatus(TypedDict): + team: int + player: int + status: ClientStatus + + @api_endpoints.route("/tracker/") @cache.memoize(timeout=60) def tracker_data(tracker: UUID) -> dict[str, Any]: @@ -29,122 +70,77 @@ def tracker_data(tracker: UUID) -> dict[str, Any]: all_players: dict[int, list[int]] = tracker_data.get_all_players() - class PlayerAlias(TypedDict): - player: int - name: str | None - - player_aliases: list[dict[str, int | list[PlayerAlias]]] = [] + player_aliases: list[PlayerAlias] = [] """Slot aliases of all players.""" for team, players in all_players.items(): - team_player_aliases: list[PlayerAlias] = [] - team_aliases = {"team": team, "players": team_player_aliases} - player_aliases.append(team_aliases) for player in players: - team_player_aliases.append({"player": player, "alias": tracker_data.get_player_alias(team, player)}) - - class PlayerItemsReceived(TypedDict): - player: int - items: list[NetworkItem] + player_aliases.append({"team": team, "player": player, "alias": tracker_data.get_player_alias(team, player)}) - player_items_received: list[dict[str, int | list[PlayerItemsReceived]]] = [] + player_items_received: list[PlayerItemsReceived] = [] """Items received by each player.""" for team, players in all_players.items(): - player_received_items: list[PlayerItemsReceived] = [] - team_items_received = {"team": team, "players": player_received_items} - player_items_received.append(team_items_received) for player in players: - player_received_items.append( - {"player": player, "items": tracker_data.get_player_received_items(team, player)}) + player_items_received.append( + {"team": team, "player": player, "items": tracker_data.get_player_received_items(team, player)}) - class PlayerChecksDone(TypedDict): - player: int - locations: list[int] - - player_checks_done: list[dict[str, int | list[PlayerChecksDone]]] = [] + player_checks_done: list[PlayerChecksDone] = [] """ID of all locations checked by each player.""" for team, players in all_players.items(): - per_player_checks: list[PlayerChecksDone] = [] - team_checks_done = {"team": team, "players": per_player_checks} - player_checks_done.append(team_checks_done) for player in players: - per_player_checks.append( - {"player": player, "locations": sorted(tracker_data.get_player_checked_locations(team, player))}) + player_checks_done.append( + {"team": team, "player": player, "locations": sorted(tracker_data.get_player_checked_locations(team, player))}) - total_checks_done: list[dict[str, int]] = [ + total_checks_done: list[TeamTotalChecks] = [ {"team": team, "checks_done": checks_done} for team, checks_done in tracker_data.get_team_locations_checked_count().items() ] """Total number of locations checked for the entire multiworld per team.""" - class PlayerHints(TypedDict): - player: int - hints: list[Hint] - - hints: list[dict[str, int | list[PlayerHints]]] = [] + hints: list[PlayerHints] = [] """Hints that all players have used or received.""" for team, players in tracker_data.get_all_slots().items(): - per_player_hints: list[PlayerHints] = [] - team_hints = {"team": team, "players": per_player_hints} - hints.append(team_hints) for player in players: player_hints = sorted(tracker_data.get_player_hints(team, player)) - per_player_hints.append({"player": player, "hints": player_hints}) - slot_info = tracker_data.get_slot_info(team, player) + hints.append({"team": team, "player": player, "hints": player_hints}) + slot_info = tracker_data.get_slot_info(player) # this assumes groups are always after players if slot_info.type != SlotType.group: continue for member in slot_info.group_members: - team_hints[member]["hints"] += player_hints + hints[member - 1]["hints"] += player_hints - class PlayerTimer(TypedDict): - player: int - time: datetime | None - - activity_timers: list[dict[str, int | list[PlayerTimer]]] = [] + activity_timers: list[PlayerTimer] = [] """Time of last activity per player. Returned as RFC 1123 format and null if no connection has been made.""" for team, players in all_players.items(): - player_timers: list[PlayerTimer] = [] - team_timers = {"team": team, "players": player_timers} - activity_timers.append(team_timers) for player in players: - player_timers.append({"player": player, "time": None}) - - client_activity_timers: tuple[tuple[int, int], float] = tracker_data._multisave.get("client_activity_timers", ()) - for (team, player), timestamp in client_activity_timers: - # use index since we can rely on order - # FIX: key is "players" (not "player_timers") - activity_timers[team]["players"][player - 1]["time"] = datetime.fromtimestamp(timestamp, timezone.utc) + activity_timers.append({"team": team, "player": player, "time": None}) + for (team, player), timestamp in tracker_data._multisave.get("client_activity_timers", []): + for entry in activity_timers: + if entry["team"] == team and entry["player"] == player: + entry["time"] = datetime.fromtimestamp(timestamp, timezone.utc) + break - connection_timers: list[dict[str, int | list[PlayerTimer]]] = [] + connection_timers: list[PlayerTimer] = [] """Time of last connection per player. Returned as RFC 1123 format and null if no connection has been made.""" for team, players in all_players.items(): - player_timers: list[PlayerTimer] = [] - team_connection_timers = {"team": team, "players": player_timers} - connection_timers.append(team_connection_timers) for player in players: - player_timers.append({"player": player, "time": None}) - - client_connection_timers: tuple[tuple[int, int], float] = tracker_data._multisave.get( - "client_connection_timers", ()) - for (team, player), timestamp in client_connection_timers: - connection_timers[team]["players"][player - 1]["time"] = datetime.fromtimestamp(timestamp, timezone.utc) + connection_timers.append({"team": team, "player": player, "time": None}) - class PlayerStatus(TypedDict): - player: int - status: ClientStatus + for (team, player), timestamp in tracker_data._multisave.get("client_connection_timers", []): + # find the matching entry + for entry in connection_timers: + if entry["team"] == team and entry["player"] == player: + entry["time"] = datetime.fromtimestamp(timestamp, timezone.utc) + break - player_status: list[dict[str, int | list[PlayerStatus]]] = [] + player_status: list[PlayerStatus] = [] """The current client status for each player.""" for team, players in all_players.items(): - player_statuses: list[PlayerStatus] = [] - team_status = {"team": team, "players": player_statuses} - player_status.append(team_status) for player in players: - player_statuses.append({"player": player, "status": tracker_data.get_player_client_status(team, player)}) + player_status.append({"team": team, "player": player, "status": tracker_data.get_player_client_status(team, player)}) return { - **get_static_tracker_data(room), "aliases": player_aliases, "player_items_received": player_items_received, "player_checks_done": player_checks_done, @@ -153,80 +149,80 @@ class PlayerStatus(TypedDict): "activity_timers": activity_timers, "connection_timers": connection_timers, "player_status": player_status, - "datapackage": tracker_data._multidata["datapackage"], } -@cache.memoize() -def get_static_tracker_data(room: Room) -> dict[str, Any]: - """ - Builds and caches the static data for this active session tracker, so that it doesn't need to be recalculated. + +class PlayerGroups(TypedDict): + slot: int + name: str + members: list[int] + + +class PlayerSlotData(TypedDict): + player: int + slot_data: dict[str, Any] + + +@api_endpoints.route("/static_tracker/") +@cache.memoize(timeout=300) +def static_tracker_data(tracker: UUID) -> dict[str, Any]: """ + Outputs json data to /api/static_tracker/. + :param tracker: UUID of current session tracker. + + :return: Static tracking data for all players in the room. Typing and docstrings describe the format of each value. + """ + room: Room | None = Room.get(tracker=tracker) + if not room: + abort(404) tracker_data = TrackerData(room) all_players: dict[int, list[int]] = tracker_data.get_all_players() - class PlayerGroups(TypedDict): - slot: int - name: str - members: list[int] - - groups: list[dict[str, int | list[PlayerGroups]]] = [] + groups: list[PlayerGroups] = [] """The Slot ID of groups and the IDs of the group's members.""" for team, players in tracker_data.get_all_slots().items(): - groups_in_team: list[PlayerGroups] = [] - team_groups = {"team": team, "groups": groups_in_team} - groups.append(team_groups) for player in players: - slot_info = tracker_data.get_slot_info(team, player) + slot_info = tracker_data.get_slot_info(player) if slot_info.type != SlotType.group or not slot_info.group_members: continue - groups_in_team.append( + groups.append( { "slot": player, "name": slot_info.name, "members": list(slot_info.group_members), }) - class PlayerName(TypedDict): - player: int - name: str + break - player_names: list[dict[str, str | list[PlayerName]]] = [] - """Slot names of all players.""" - for team, players in all_players.items(): - per_team_player_names: list[PlayerName] = [] - team_names = {"team": team, "players": per_team_player_names} - player_names.append(team_names) - for player in players: - per_team_player_names.append({"player": player, "name": tracker_data.get_player_name(team, player)}) + return { + "groups": groups, + "datapackage": tracker_data._multidata["datapackage"], + } - class PlayerGame(TypedDict): - player: int - game: str +# It should be exceedingly rare that slot data is needed, so it's separated out. +@api_endpoints.route("/slot_data_tracker/") +@cache.memoize(timeout=300) +def tracker_slot_data(tracker: UUID) -> list[PlayerSlotData]: + """ + Outputs json data to /api/slot_data_tracker/. - games: list[dict[str, int | list[PlayerGame]]] = [] - """The game each player is playing.""" - for team, players in all_players.items(): - player_games: list[PlayerGame] = [] - team_games = {"team": team, "players": player_games} - games.append(team_games) - for player in players: - player_games.append({"player": player, "game": tracker_data.get_player_game(team, player)}) + :param tracker: UUID of current session tracker. - class PlayerSlotData(TypedDict): - player: int - slot_data: dict[str, Any] + :return: Slot data for all players in the room. Typing completely arbitrary per game. + """ + room: Room | None = Room.get(tracker=tracker) + if not room: + abort(404) + tracker_data = TrackerData(room) + + all_players: dict[int, list[int]] = tracker_data.get_all_players() - slot_data: list[dict[str, int | list[PlayerSlotData]]] = [] + slot_data: list[PlayerSlotData] = [] """Slot data for each player.""" for team, players in all_players.items(): - player_slot_data: list[PlayerSlotData] = [] - team_slot_data = {"team": team, "players": player_slot_data} - slot_data.append(team_slot_data) for player in players: - player_slot_data.append({"player": player, "slot_data": tracker_data.get_slot_data(team, player)}) + slot_data.append({"player": player, "slot_data": tracker_data.get_slot_data(player)}) + break - return { - "groups": groups, - "slot_data": slot_data, - } + return slot_data diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py index 759bc7b625d5..ead679fd980b 100644 --- a/WebHostLib/tracker.py +++ b/WebHostLib/tracker.py @@ -17,7 +17,6 @@ # Multisave is currently updated, at most, every minute. TRACKER_CACHE_TIMEOUT_IN_SECONDS = 60 -_multidata_cache = {} _multiworld_trackers: Dict[str, Callable] = {} _player_trackers: Dict[str, Callable] = {} diff --git a/docs/webhost api.md b/docs/webhost api.md index ca4b1ce71597..e34eb47f7493 100644 --- a/docs/webhost api.md +++ b/docs/webhost api.md @@ -18,6 +18,8 @@ Current endpoints: - [`/room_status/`](#roomstatus) - Tracker API - [`/tracker/`](#tracker) + - [`/static_tracker/`](#statictracker) + - [`/slot_data_tracker/`](#slotdatatracker) - User API - [`/get_rooms`](#getrooms) - [`/get_seeds`](#getseeds) @@ -254,8 +256,6 @@ can either be viewed while on a room tracker page, or from the [room's endpoint] Will provide a dict of tracker data with the following keys: -- item_link groups and their players (`groups`) -- Each player's slot_data (`slot_data`) - Each player's current alias (`aliases`) - Will return the name if there is none - A list of items each player has received as a NetworkItem (`player_items_received`) @@ -265,111 +265,55 @@ Will provide a dict of tracker data with the following keys: - The time of last activity of each player in RFC 1123 format (`activity_timers`) - The time of last active connection of each player in RFC 1123 format (`connection_timers`) - The current client status of each player (`player_status`) -- The datapackage hash for each player (`datapackage`) - - This hash can then be sent to the datapackage API to receive the appropriate datapackage as necessary - Example: ```json { - "groups": [ + "aliases": [ { "team": 0, - "groups": [ - { - "slot": 5, - "name": "testGroup", - "members": [ - 1, - 2 - ] - }, - { - "slot": 6, - "name": "myCoolLink", - "members": [ - 3, - 4 - ] - } - ] - } - ], - "slot_data": [ + "player": 1, + "alias": "Incompetence" + }, { "team": 0, - "players": [ - { - "player": 1, - "slot_data": { - "example_option": 1, - "other_option": 3 - } - }, - { - "player": 2, - "slot_data": { - "example_option": 1, - "other_option": 2 - } - } - ] + "player": 2, + "alias": "Slot_Name_2" } ], - "aliases": [ + "player_items_received": [ { "team": 0, - "players": [ - { - "player": 1, - "alias": "Incompetence" - }, - { - "player": 2, - "alias": "Slot_Name_2" - } + "player": 1, + "items": [ + [1, 1, 1, 0], + [2, 2, 2, 1] ] - } - ], - "player_items_received": [ + }, { "team": 0, - "players": [ - { - "player": 1, - "items": [ - [1, 1, 1, 0], - [2, 2, 2, 1] - ] - }, - { - "player": 2, - "items": [ - [1, 1, 1, 2], - [2, 2, 2, 0] - ] - } + "player": 2, + "items": [ + [1, 1, 1, 2], + [2, 2, 2, 0] ] } ], "player_checks_done": [ { "team": 0, - "players": [ - { - "player": 1, - "locations": [ - 1, - 2 - ] - }, - { - "player": 2, - "locations": [ - 1, - 2 - ] - } + "player": 1, + "locations": [ + 1, + 2 + ] + }, + { + "team": 0, + "player": 2, + "locations": [ + 1, + 2 ] } ], @@ -382,78 +326,120 @@ Example: "hints": [ { "team": 0, - "players": [ - { - "player": 1, - "hints": [ - [1, 2, 4, 6, 0, "", 4, 0] - ] - }, - { - "player": 2, - "hints": [] - } + "player": 1, + "hints": [ + [1, 2, 4, 6, 0, "", 4, 0] ] + }, + { + "team": 0, + "player": 2, + "hints": [] } ], "activity_timers": [ { "team": 0, - "players": [ - { - "player": 1, - "time": "Fri, 18 Apr 2025 20:35:45 GMT" - }, - { - "player": 2, - "time": "Fri, 18 Apr 2025 20:42:46 GMT" - } - ] + "player": 1, + "time": "Fri, 18 Apr 2025 20:35:45 GMT" + }, + { + "team": 0, + "player": 2, + "time": "Fri, 18 Apr 2025 20:42:46 GMT" } ], "connection_timers": [ { "team": 0, - "players": [ - { - "player": 1, - "time": "Fri, 18 Apr 2025 20:38:25 GMT" - }, - { - "player": 2, - "time": "Fri, 18 Apr 2025 21:03:00 GMT" - } - ] + "player": 1, + "time": "Fri, 18 Apr 2025 20:38:25 GMT" + }, + { + "team": 0, + "player": 2, + "time": "Fri, 18 Apr 2025 21:03:00 GMT" } ], "player_status": [ { "team": 0, - "players": [ - { - "player": 1, - "status": 0 - }, - { - "player": 2, - "status": 0 - } + "player": 1, + "status": 0 + }, + { + "team": 0, + "player": 2, + "status": 0 + } + ] +} +``` + +### `/static_tracker/` + +Will provide a dict of static tracker data with the following keys: + +- item_link groups and their players (`groups`) +- The datapackage hash for each game (`datapackage`) + - This hash can then be sent to the datapackage API to receive the appropriate datapackage as necessary + +Example: +```json +{ + "groups": [ + { + "slot": 5, + "name": "testGroup", + "members": [ + 1, + 2 + ] + }, + { + "slot": 6, + "name": "myCoolLink", + "members": [ + 3, + 4 ] } ], "datapackage": { "Archipelago": { "checksum": "ac9141e9ad0318df2fa27da5f20c50a842afeecb", - "version": 0 }, "The Messenger": { "checksum": "6991cbcda7316b65bcb072667f3ee4c4cae71c0b", - "version": 0 } } } ``` +### `/slot_data_tracker/` + +Will provide a list of each player's slot_data. + +Example: +```json +[ + { + "player": 1, + "slot_data": { + "example_option": 1, + "other_option": 3 + } + }, + { + "player": 2, + "slot_data": { + "example_option": 1, + "other_option": 2 + } + } +] +``` + ## User Endpoints User endpoints can get room and seed details from the current session tokens (cookies) @@ -554,4 +540,4 @@ Example: "seed_id": "a528e34c-3b4f-42a9-9f8f-00a4fd40bacb" } ] -``` +``` \ No newline at end of file diff --git a/test/webhost/test_tracker.py b/test/webhost/test_tracker.py index 58145d77f3bc..0796cdb24765 100644 --- a/test/webhost/test_tracker.py +++ b/test/webhost/test_tracker.py @@ -93,3 +93,13 @@ def test_invalid_if_modified_since(self) -> None: headers={"If-Modified-Since": "Wed, 21 Oct 2015 07:28:00"}, # missing timezone ) self.assertEqual(response.status_code, 400) + + def test_tracker_api(self) -> None: + """Verify that tracker api gives a reply for the room.""" + with self.app.test_request_context(): + with self.client.open(url_for("api.tracker_data", tracker=self.tracker_uuid)) as response: + self.assertEqual(response.status_code, 200) + with self.client.open(url_for("api.static_tracker_data", tracker=self.tracker_uuid)) as response: + self.assertEqual(response.status_code, 200) + with self.client.open(url_for("api.tracker_slot_data", tracker=self.tracker_uuid)) as response: + self.assertEqual(response.status_code, 200) From e256abfdfb7935827c1a77132481ea1273f6b822 Mon Sep 17 00:00:00 2001 From: CaitSith2 Date: Sun, 21 Sep 2025 18:07:33 -0700 Subject: [PATCH 0740/1218] Factorio: Allow to reconnect a timed out RCON client connection. (#5421) --- worlds/factorio/Client.py | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/worlds/factorio/Client.py b/worlds/factorio/Client.py index d7992c327635..51eb487f8465 100644 --- a/worlds/factorio/Client.py +++ b/worlds/factorio/Client.py @@ -59,6 +59,19 @@ def _cmd_toggle_send_filter(self): def _cmd_toggle_chat(self): """Toggle sending of chat messages from players on the Factorio server to Archipelago.""" self.ctx.toggle_bridge_chat_out() + + def _cmd_rcon_reconnect(self) -> bool: + """Reconnect the RCON client if its disconnected.""" + try: + result = self.ctx.rcon_client.send_command("/help") + if result: + self.output("RCON Client already connected.") + return True + except factorio_rcon.RCONNetworkError: + self.ctx.rcon_client = factorio_rcon.RCONClient("localhost", self.ctx.rcon_port, self.ctx.rcon_password, timeout=5) + self.output("RCON Client successfully reconnected.") + return True + return False class FactorioContext(CommonContext): @@ -242,7 +255,13 @@ async def game_watcher(ctx: FactorioContext): if ctx.rcon_client and time.perf_counter() > next_bridge: next_bridge = time.perf_counter() + 1 ctx.awaiting_bridge = False - data = json.loads(ctx.rcon_client.send_command("/ap-sync")) + try: + data = json.loads(ctx.rcon_client.send_command("/ap-sync")) + except factorio_rcon.RCONNotConnected: + continue + except factorio_rcon.RCONNetworkError: + bridge_logger.warning("RCON Client has unexpectedly lost connection. Please issue /rcon_reconnect.") + continue if not ctx.auth: pass # auth failed, wait for new attempt elif data["slot_name"] != ctx.auth: @@ -294,9 +313,13 @@ async def game_watcher(ctx: FactorioContext): "cmd": "Set", "key": ctx.energylink_key, "operations": [{"operation": "add", "value": value}] }])) - ctx.rcon_client.send_command( - f"/ap-energylink -{value}") - logger.debug(f"EnergyLink: Sent {format_SI_prefix(value)}J") + try: + ctx.rcon_client.send_command( + f"/ap-energylink -{value}") + except factorio_rcon.RCONNetworkError: + bridge_logger.warning("RCON Client has unexpectedly lost connection. Please issue /rcon_reconnect.") + else: + logger.debug(f"EnergyLink: Sent {format_SI_prefix(value)}J") await asyncio.sleep(0.1) From a99da85a22ac925cefdf7ef7e5de3ece6d28e671 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 24 Sep 2025 02:39:19 +0200 Subject: [PATCH 0741/1218] Core: APWorld manifest (#4516) Adds support for a manifest file (archipelago.json) inside an .apworld file. It tells AP the game, minimum core version (optional field), maximum core version (optional field), its own version (used to determine which file to prefer to load only currently) The file itself is marked as required starting with core 0.7.0, prior, just a warning is printed, with error trace. Co-authored-by: Doug Hoskisson Co-authored-by: qwint Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- Utils.py | 1 + docs/apworld specification.md | 16 ++++++++- setup.py | 19 ++++++++-- worlds/Files.py | 32 ++++++++++++++++- worlds/__init__.py | 68 +++++++++++++++++++++++++++++++++-- 5 files changed, 129 insertions(+), 7 deletions(-) diff --git a/Utils.py b/Utils.py index e73edd7137f2..d8dab4fcb070 100644 --- a/Utils.py +++ b/Utils.py @@ -49,6 +49,7 @@ def as_simple_string(self) -> str: __version__ = "0.6.4" version_tuple = tuplize_version(__version__) +version = Version(*version_tuple) is_linux = sys.platform.startswith("linux") is_macos = sys.platform == "darwin" diff --git a/docs/apworld specification.md b/docs/apworld specification.md index ed2e8b1c8ecb..39282e157446 100644 --- a/docs/apworld specification.md +++ b/docs/apworld specification.md @@ -19,7 +19,21 @@ the world's folder in `worlds/`. I.e. `worlds/ror2.apworld` containing `ror2/__i ## Metadata -No metadata is specified yet. +Metadata about the apworld is defined in an `archipelago.json` file inside the zip archive. +The current format version has at minimum: +```json +{ + "version": 6, + "compatible_version": 5, + "game": "Game Name" +} +``` + +with the following optional version fields using the format `"1.0.0"` to represent major.minor.build: +* `minimum_ap_version` and `maximum_ap_version` - which if present will each be compared against the current + Archipelago version respectively to filter those files from being loaded +* `world_version` - an arbitrary version for that world in order to only load the newest valid world. + An apworld without a world_version is always treated as older than one with a version ## Extra Data diff --git a/setup.py b/setup.py index 3f25ade7a7a1..81eee0172afc 100644 --- a/setup.py +++ b/setup.py @@ -371,6 +371,8 @@ def run(self) -> None: os.makedirs(self.buildfolder / "Players" / "Templates", exist_ok=True) from Options import generate_yaml_templates from worlds.AutoWorld import AutoWorldRegister + from worlds.Files import APWorldContainer + from Utils import version assert not non_apworlds - set(AutoWorldRegister.world_types), \ f"Unknown world {non_apworlds - set(AutoWorldRegister.world_types)} designated for .apworld" folders_to_remove: list[str] = [] @@ -379,13 +381,26 @@ def run(self) -> None: if worldname not in non_apworlds: file_name = os.path.split(os.path.dirname(worldtype.__file__))[1] world_directory = self.libfolder / "worlds" / file_name + if os.path.isfile(world_directory / "archipelago.json"): + manifest = json.load(open(world_directory / "archipelago.json")) + else: + manifest = {} # this method creates an apworld that cannot be moved to a different OS or minor python version, # which should be ok - with zipfile.ZipFile(self.libfolder / "worlds" / (file_name + ".apworld"), "x", zipfile.ZIP_DEFLATED, + zip_path = self.libfolder / "worlds" / (file_name + ".apworld") + apworld = APWorldContainer(str(zip_path)) + apworld.minimum_ap_version = version + apworld.maximum_ap_version = version + apworld.game = worldtype.game + manifest.update(apworld.get_manifest()) + apworld.manifest_path = f"{file_name}/archipelago.json" + with zipfile.ZipFile(zip_path, "x", zipfile.ZIP_DEFLATED, compresslevel=9) as zf: for path in world_directory.rglob("*.*"): relative_path = os.path.join(*path.parts[path.parts.index("worlds")+1:]) - zf.write(path, relative_path) + if not relative_path.endswith("archipelago.json"): + zf.write(path, relative_path) + zf.writestr(apworld.manifest_path, json.dumps(manifest)) folders_to_remove.append(file_name) shutil.rmtree(world_directory) shutil.copyfile("meta.yaml", self.buildfolder / "Players" / "Templates" / "meta.yaml") diff --git a/worlds/Files.py b/worlds/Files.py index ece60c69e737..709671ce5f8e 100644 --- a/worlds/Files.py +++ b/worlds/Files.py @@ -8,7 +8,8 @@ import threading from io import BytesIO -from typing import ClassVar, Dict, List, Literal, Tuple, Any, Optional, Union, BinaryIO, overload, Sequence +from typing import (ClassVar, Dict, List, Literal, Tuple, Any, Optional, Union, BinaryIO, overload, Sequence, + TYPE_CHECKING) import bsdiff4 @@ -16,6 +17,9 @@ del threading +if TYPE_CHECKING: + from Utils import Version + class AutoPatchRegister(abc.ABCMeta): patch_types: ClassVar[Dict[str, AutoPatchRegister]] = {} @@ -163,6 +167,32 @@ def get_manifest(self) -> Dict[str, Any]: } +class APWorldContainer(APContainer): + """A zipfile containing a world implementation.""" + game: str | None = None + world_version: "Version | None" = None + minimum_ap_version: "Version | None" = None + maximum_ap_version: "Version | None" = None + + def read_contents(self, opened_zipfile: zipfile.ZipFile) -> Dict[str, Any]: + from Utils import tuplize_version, Version + manifest = super().read_contents(opened_zipfile) + self.game = manifest["game"] + for version_key in ("world_version", "minimum_ap_version", "maximum_ap_version"): + if version_key in manifest: + setattr(self, version_key, Version(*tuplize_version(manifest[version_key]))) + return manifest + + def get_manifest(self) -> Dict[str, Any]: + manifest = super().get_manifest() + manifest["game"] = self.game + for version_key in ("world_version", "minimum_ap_version", "maximum_ap_version"): + version = getattr(self, version_key) + if version: + manifest[version_key] = version.as_simple_string() + return manifest + + class APPlayerContainer(APContainer): """A zipfile containing at least archipelago.json meant for a player""" game: ClassVar[Optional[str]] = None diff --git a/worlds/__init__.py b/worlds/__init__.py index 89f7bcd063f0..c363d7f20c6d 100644 --- a/worlds/__init__.py +++ b/worlds/__init__.py @@ -10,7 +10,7 @@ from typing import List from NetUtils import DataPackage -from Utils import local_path, user_path +from Utils import local_path, user_path, Version, version_tuple local_folder = os.path.dirname(__file__) user_folder = user_path("worlds") if user_path() != local_path() else user_path("custom_worlds") @@ -38,6 +38,7 @@ class WorldSource: is_zip: bool = False relative: bool = True # relative to regular world import folder time_taken: float = -1.0 + version: Version = Version(0, 0, 0) def __repr__(self) -> str: return f"{self.__class__.__name__}({self.path}, is_zip={self.is_zip}, relative={self.relative})" @@ -102,12 +103,73 @@ def load(self) -> bool: # import all submodules to trigger AutoWorldRegister world_sources.sort() +apworlds: list[WorldSource] = [] for world_source in world_sources: - world_source.load() + # load all loose files first: + if world_source.is_zip: + apworlds.append(world_source) + else: + world_source.load() -# Build the data package for each game. from .AutoWorld import AutoWorldRegister +if apworlds: + # encapsulation for namespace / gc purposes + def load_apworlds() -> None: + global apworlds + from .Files import APWorldContainer, InvalidDataError + core_compatible: list[tuple[WorldSource, APWorldContainer]] = [] + + def fail_world(game_name: str, reason: str, add_as_failed_to_load: bool = True) -> None: + if add_as_failed_to_load: + failed_world_loads.append(game_name) + logging.warning(reason) + + for apworld_source in apworlds: + apworld: APWorldContainer = APWorldContainer(apworld_source.resolved_path) + # populate metadata + try: + apworld.read() + except InvalidDataError as e: + if version_tuple < (0, 7, 0): + logging.error( + f"Invalid or missing manifest file for {apworld_source.resolved_path}. " + "This apworld will stop working with Archipelago 0.7.0." + ) + logging.error(e) + else: + raise e + + if apworld.minimum_ap_version and apworld.minimum_ap_version > version_tuple: + fail_world(apworld.game, + f"Did not load {apworld_source.path} " + f"as its minimum core version {apworld.minimum_ap_version} " + f"is higher than current core version {version_tuple}.") + elif apworld.maximum_ap_version and apworld.maximum_ap_version < version_tuple: + fail_world(apworld.game, + f"Did not load {apworld_source.path} " + f"as its maximum core version {apworld.maximum_ap_version} " + f"is lower than current core version {version_tuple}.") + else: + core_compatible.append((apworld_source, apworld)) + # load highest version first + core_compatible.sort( + key=lambda element: element[1].world_version if element[1].world_version else Version(0, 0, 0), + reverse=True) + for apworld_source, apworld in core_compatible: + if apworld.game and apworld.game in AutoWorldRegister.world_types: + fail_world(apworld.game, + f"Did not load {apworld_source.path} " + f"as its game {apworld.game} is already loaded.", + add_as_failed_to_load=False) + else: + apworld_source.load() + load_apworlds() + del load_apworlds + +del apworlds + +# Build the data package for each game. network_data_package: DataPackage = { "games": {world_name: world.get_data_package_data() for world_name, world in AutoWorldRegister.world_types.items()}, } From dc270303a941eab3e5b60ed1ec025b4545a6f826 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 24 Sep 2025 17:33:44 +0200 Subject: [PATCH 0742/1218] Core: improve formatting on /help command (#5381) --- MultiServer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MultiServer.py b/MultiServer.py index 06223a3ee2dd..23aab7b58b7d 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1321,7 +1321,8 @@ def get_help_text(self) -> str: argname += "=" + parameter.default argtext += argname argtext += " " - s += f"{self.marker}{command} {argtext}\n {method.__doc__}\n" + doctext = '\n '.join(inspect.getdoc(method).split('\n')) + s += f"{self.marker}{command} {argtext}\n {doctext}\n" return s def _cmd_help(self): From 4525bae8796f5374c31c9c7265c92494a4e57abe Mon Sep 17 00:00:00 2001 From: Etsuna <47378314+Etsuna@users.noreply.github.com> Date: Wed, 24 Sep 2025 20:08:14 +0200 Subject: [PATCH 0743/1218] Webhost: add total player location counts to tracker API (#5441) --- WebHostLib/api/tracker.py | 13 +++++++++++++ docs/webhost api.md | 16 +++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/WebHostLib/api/tracker.py b/WebHostLib/api/tracker.py index 4956e6441fa9..36692af42652 100644 --- a/WebHostLib/api/tracker.py +++ b/WebHostLib/api/tracker.py @@ -52,6 +52,12 @@ class PlayerStatus(TypedDict): status: ClientStatus +class PlayerLocationsTotal(TypedDict): + team: int + player: int + total_locations: int + + @api_endpoints.route("/tracker/") @cache.memoize(timeout=60) def tracker_data(tracker: UUID) -> dict[str, Any]: @@ -195,9 +201,16 @@ def static_tracker_data(tracker: UUID) -> dict[str, Any]: }) break + player_locations_total: list[PlayerLocationsTotal] = [] + for team, players in all_players.items(): + for player in players: + player_locations_total.append( + {"team": team, "player": player, "total_locations": len(tracker_data.get_player_locations(player))}) + return { "groups": groups, "datapackage": tracker_data._multidata["datapackage"], + "player_locations_total": player_locations_total, } # It should be exceedingly rare that slot data is needed, so it's separated out. diff --git a/docs/webhost api.md b/docs/webhost api.md index e34eb47f7493..048211348404 100644 --- a/docs/webhost api.md +++ b/docs/webhost api.md @@ -383,6 +383,8 @@ Will provide a dict of static tracker data with the following keys: - item_link groups and their players (`groups`) - The datapackage hash for each game (`datapackage`) - This hash can then be sent to the datapackage API to receive the appropriate datapackage as necessary +- The number of checks found vs. total checks available per player (`player_locations_total`) + - Same logic as the multitracker template: found = len(player_checks_done.locations) / total = player_locations_total.total_locations (all available checks). Example: ```json @@ -412,7 +414,19 @@ Example: "The Messenger": { "checksum": "6991cbcda7316b65bcb072667f3ee4c4cae71c0b", } - } + }, + "player_locations_total": [ + { + "player": 1, + "team" : 0, + "total_locations": 10 + }, + { + "player": 2, + "team" : 0, + "total_locations": 20 + } + ], } ``` From 4ae87edf371869d43e18b04999d8915852456d5e Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 24 Sep 2025 23:25:46 +0200 Subject: [PATCH 0744/1218] Core: apworld manifest launcher component (#5340) adds a launcher component that builds all apworlds on top of #4516 --------- Co-authored-by: Doug Hoskisson Co-authored-by: qwint Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/LauncherComponents.py | 38 +++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index 7bd47d0bd35c..b2187298ff15 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -5,7 +5,7 @@ from enum import Enum, auto from typing import Optional, Callable, List, Iterable, Tuple -from Utils import local_path, open_filename +from Utils import local_path, open_filename, is_frozen class Type(Enum): @@ -243,3 +243,39 @@ def install_apworld(apworld_path: str = "") -> None: 'icon': local_path('data', 'icon.png'), 'discord': local_path('data', 'discord-mark-blue.png'), } + +if not is_frozen(): + def _build_apworlds(): + import json + import os + import zipfile + + from worlds import AutoWorldRegister + from worlds.Files import APWorldContainer + + apworlds_folder = os.path.join("build", "apworlds") + os.makedirs(apworlds_folder, exist_ok=True) + for worldname, worldtype in AutoWorldRegister.world_types.items(): + file_name = os.path.split(os.path.dirname(worldtype.__file__))[1] + world_directory = os.path.join("worlds", file_name) + if os.path.isfile(os.path.join(world_directory, "archipelago.json")): + manifest = json.load(open(os.path.join(world_directory, "archipelago.json"))) + else: + manifest = {} + + zip_path = os.path.join(apworlds_folder, file_name + ".apworld") + apworld = APWorldContainer(str(zip_path)) + apworld.game = worldtype.game + manifest.update(apworld.get_manifest()) + apworld.manifest_path = f"{file_name}/archipelago.json" + with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED, + compresslevel=9) as zf: + for path in pathlib.Path(world_directory).rglob("*.*"): + relative_path = os.path.join(*path.parts[path.parts.index("worlds") + 1:]) + if "__MACOSX" in relative_path or ".DS_STORE" in relative_path or "__pycache__" in relative_path: + continue + if not relative_path.endswith("archipelago.json"): + zf.write(path, relative_path) + zf.writestr(apworld.manifest_path, json.dumps(manifest)) + + components.append(Component('Build apworlds', func=_build_apworlds, cli=True,)) From 24394561bd37c82b24d47d3f92924d089e32358d Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Thu, 25 Sep 2025 05:10:23 +0200 Subject: [PATCH 0745/1218] Core: Bump Container Version to 7, and make APWorldContainer use 7 as the compatible_version #5479 --- worlds/Files.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/Files.py b/worlds/Files.py index 709671ce5f8e..cc81a022dd86 100644 --- a/worlds/Files.py +++ b/worlds/Files.py @@ -69,7 +69,7 @@ def get_handler(game: Optional[str]) -> Union[AutoPatchExtensionRegister, List[A return handler -container_version: int = 6 +container_version: int = 7 def is_ap_player_container(game: str, data: bytes, player: int): @@ -186,6 +186,7 @@ def read_contents(self, opened_zipfile: zipfile.ZipFile) -> Dict[str, Any]: def get_manifest(self) -> Dict[str, Any]: manifest = super().get_manifest() manifest["game"] = self.game + manifest["compatible_version"] = 7 for version_key in ("world_version", "minimum_ap_version", "maximum_ap_version"): version = getattr(self, version_key) if version: From 12998bf6f4049ccb5f720bac4f24de3030e7dd0a Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sat, 27 Sep 2025 07:54:03 -0700 Subject: [PATCH 0746/1218] Pokemon Emerald: Fix missing fanfare address (#5490) --- worlds/pokemon_emerald/data/extracted_data.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/pokemon_emerald/data/extracted_data.json b/worlds/pokemon_emerald/data/extracted_data.json index d066e31bcdf0..def6338bc9a9 100644 --- a/worlds/pokemon_emerald/data/extracted_data.json +++ b/worlds/pokemon_emerald/data/extracted_data.json @@ -1 +1 @@ -{"_comment":"DO NOT MODIFY. This file was auto-generated. Your changes will likely be overwritten.","_rom_name":"pokemon emerald version / AP 5","constants":{"ABILITIES_COUNT":78,"ABILITY_AIR_LOCK":77,"ABILITY_ARENA_TRAP":71,"ABILITY_BATTLE_ARMOR":4,"ABILITY_BLAZE":66,"ABILITY_CACOPHONY":76,"ABILITY_CHLOROPHYLL":34,"ABILITY_CLEAR_BODY":29,"ABILITY_CLOUD_NINE":13,"ABILITY_COLOR_CHANGE":16,"ABILITY_COMPOUND_EYES":14,"ABILITY_CUTE_CHARM":56,"ABILITY_DAMP":6,"ABILITY_DRIZZLE":2,"ABILITY_DROUGHT":70,"ABILITY_EARLY_BIRD":48,"ABILITY_EFFECT_SPORE":27,"ABILITY_FLAME_BODY":49,"ABILITY_FLASH_FIRE":18,"ABILITY_FORECAST":59,"ABILITY_GUTS":62,"ABILITY_HUGE_POWER":37,"ABILITY_HUSTLE":55,"ABILITY_HYPER_CUTTER":52,"ABILITY_ILLUMINATE":35,"ABILITY_IMMUNITY":17,"ABILITY_INNER_FOCUS":39,"ABILITY_INSOMNIA":15,"ABILITY_INTIMIDATE":22,"ABILITY_KEEN_EYE":51,"ABILITY_LEVITATE":26,"ABILITY_LIGHTNING_ROD":31,"ABILITY_LIMBER":7,"ABILITY_LIQUID_OOZE":64,"ABILITY_MAGMA_ARMOR":40,"ABILITY_MAGNET_PULL":42,"ABILITY_MARVEL_SCALE":63,"ABILITY_MINUS":58,"ABILITY_NATURAL_CURE":30,"ABILITY_NONE":0,"ABILITY_OBLIVIOUS":12,"ABILITY_OVERGROW":65,"ABILITY_OWN_TEMPO":20,"ABILITY_PICKUP":53,"ABILITY_PLUS":57,"ABILITY_POISON_POINT":38,"ABILITY_PRESSURE":46,"ABILITY_PURE_POWER":74,"ABILITY_RAIN_DISH":44,"ABILITY_ROCK_HEAD":69,"ABILITY_ROUGH_SKIN":24,"ABILITY_RUN_AWAY":50,"ABILITY_SAND_STREAM":45,"ABILITY_SAND_VEIL":8,"ABILITY_SERENE_GRACE":32,"ABILITY_SHADOW_TAG":23,"ABILITY_SHED_SKIN":61,"ABILITY_SHELL_ARMOR":75,"ABILITY_SHIELD_DUST":19,"ABILITY_SOUNDPROOF":43,"ABILITY_SPEED_BOOST":3,"ABILITY_STATIC":9,"ABILITY_STENCH":1,"ABILITY_STICKY_HOLD":60,"ABILITY_STURDY":5,"ABILITY_SUCTION_CUPS":21,"ABILITY_SWARM":68,"ABILITY_SWIFT_SWIM":33,"ABILITY_SYNCHRONIZE":28,"ABILITY_THICK_FAT":47,"ABILITY_TORRENT":67,"ABILITY_TRACE":36,"ABILITY_TRUANT":54,"ABILITY_VITAL_SPIRIT":72,"ABILITY_VOLT_ABSORB":10,"ABILITY_WATER_ABSORB":11,"ABILITY_WATER_VEIL":41,"ABILITY_WHITE_SMOKE":73,"ABILITY_WONDER_GUARD":25,"ACRO_BIKE":1,"BAG_ITEM_CAPACITY_DIGITS":2,"BERRY_CAPACITY_DIGITS":3,"BERRY_FIRMNESS_HARD":3,"BERRY_FIRMNESS_SOFT":2,"BERRY_FIRMNESS_SUPER_HARD":5,"BERRY_FIRMNESS_UNKNOWN":0,"BERRY_FIRMNESS_VERY_HARD":4,"BERRY_FIRMNESS_VERY_SOFT":1,"BERRY_NONE":0,"BERRY_STAGE_BERRIES":5,"BERRY_STAGE_FLOWERING":4,"BERRY_STAGE_NO_BERRY":0,"BERRY_STAGE_PLANTED":1,"BERRY_STAGE_SPARKLING":255,"BERRY_STAGE_SPROUTED":2,"BERRY_STAGE_TALLER":3,"BERRY_TREES_COUNT":128,"BERRY_TREE_ROUTE_102_ORAN":2,"BERRY_TREE_ROUTE_102_PECHA":1,"BERRY_TREE_ROUTE_103_CHERI_1":5,"BERRY_TREE_ROUTE_103_CHERI_2":7,"BERRY_TREE_ROUTE_103_LEPPA":6,"BERRY_TREE_ROUTE_104_CHERI_1":8,"BERRY_TREE_ROUTE_104_CHERI_2":76,"BERRY_TREE_ROUTE_104_LEPPA":10,"BERRY_TREE_ROUTE_104_ORAN_1":4,"BERRY_TREE_ROUTE_104_ORAN_2":11,"BERRY_TREE_ROUTE_104_PECHA":13,"BERRY_TREE_ROUTE_104_SOIL_1":3,"BERRY_TREE_ROUTE_104_SOIL_2":9,"BERRY_TREE_ROUTE_104_SOIL_3":12,"BERRY_TREE_ROUTE_104_SOIL_4":75,"BERRY_TREE_ROUTE_110_NANAB_1":16,"BERRY_TREE_ROUTE_110_NANAB_2":17,"BERRY_TREE_ROUTE_110_NANAB_3":18,"BERRY_TREE_ROUTE_111_ORAN_1":80,"BERRY_TREE_ROUTE_111_ORAN_2":81,"BERRY_TREE_ROUTE_111_RAZZ_1":19,"BERRY_TREE_ROUTE_111_RAZZ_2":20,"BERRY_TREE_ROUTE_112_PECHA_1":22,"BERRY_TREE_ROUTE_112_PECHA_2":23,"BERRY_TREE_ROUTE_112_RAWST_1":21,"BERRY_TREE_ROUTE_112_RAWST_2":24,"BERRY_TREE_ROUTE_114_PERSIM_1":68,"BERRY_TREE_ROUTE_114_PERSIM_2":77,"BERRY_TREE_ROUTE_114_PERSIM_3":78,"BERRY_TREE_ROUTE_115_BLUK_1":55,"BERRY_TREE_ROUTE_115_BLUK_2":56,"BERRY_TREE_ROUTE_115_KELPSY_1":69,"BERRY_TREE_ROUTE_115_KELPSY_2":70,"BERRY_TREE_ROUTE_115_KELPSY_3":71,"BERRY_TREE_ROUTE_116_CHESTO_1":26,"BERRY_TREE_ROUTE_116_CHESTO_2":66,"BERRY_TREE_ROUTE_116_PINAP_1":25,"BERRY_TREE_ROUTE_116_PINAP_2":67,"BERRY_TREE_ROUTE_117_WEPEAR_1":27,"BERRY_TREE_ROUTE_117_WEPEAR_2":28,"BERRY_TREE_ROUTE_117_WEPEAR_3":29,"BERRY_TREE_ROUTE_118_SITRUS_1":31,"BERRY_TREE_ROUTE_118_SITRUS_2":33,"BERRY_TREE_ROUTE_118_SOIL":32,"BERRY_TREE_ROUTE_119_HONDEW_1":83,"BERRY_TREE_ROUTE_119_HONDEW_2":84,"BERRY_TREE_ROUTE_119_LEPPA":86,"BERRY_TREE_ROUTE_119_POMEG_1":34,"BERRY_TREE_ROUTE_119_POMEG_2":35,"BERRY_TREE_ROUTE_119_POMEG_3":36,"BERRY_TREE_ROUTE_119_SITRUS":85,"BERRY_TREE_ROUTE_120_ASPEAR_1":37,"BERRY_TREE_ROUTE_120_ASPEAR_2":38,"BERRY_TREE_ROUTE_120_ASPEAR_3":39,"BERRY_TREE_ROUTE_120_NANAB":44,"BERRY_TREE_ROUTE_120_PECHA_1":40,"BERRY_TREE_ROUTE_120_PECHA_2":41,"BERRY_TREE_ROUTE_120_PECHA_3":42,"BERRY_TREE_ROUTE_120_PINAP":45,"BERRY_TREE_ROUTE_120_RAZZ":43,"BERRY_TREE_ROUTE_120_WEPEAR":46,"BERRY_TREE_ROUTE_121_ASPEAR":48,"BERRY_TREE_ROUTE_121_CHESTO":50,"BERRY_TREE_ROUTE_121_NANAB_1":52,"BERRY_TREE_ROUTE_121_NANAB_2":53,"BERRY_TREE_ROUTE_121_PERSIM":47,"BERRY_TREE_ROUTE_121_RAWST":49,"BERRY_TREE_ROUTE_121_SOIL_1":51,"BERRY_TREE_ROUTE_121_SOIL_2":54,"BERRY_TREE_ROUTE_123_GREPA_1":60,"BERRY_TREE_ROUTE_123_GREPA_2":61,"BERRY_TREE_ROUTE_123_GREPA_3":65,"BERRY_TREE_ROUTE_123_GREPA_4":72,"BERRY_TREE_ROUTE_123_LEPPA_1":62,"BERRY_TREE_ROUTE_123_LEPPA_2":64,"BERRY_TREE_ROUTE_123_PECHA":87,"BERRY_TREE_ROUTE_123_POMEG_1":15,"BERRY_TREE_ROUTE_123_POMEG_2":30,"BERRY_TREE_ROUTE_123_POMEG_3":58,"BERRY_TREE_ROUTE_123_POMEG_4":59,"BERRY_TREE_ROUTE_123_QUALOT_1":14,"BERRY_TREE_ROUTE_123_QUALOT_2":73,"BERRY_TREE_ROUTE_123_QUALOT_3":74,"BERRY_TREE_ROUTE_123_QUALOT_4":79,"BERRY_TREE_ROUTE_123_RAWST":57,"BERRY_TREE_ROUTE_123_SITRUS":88,"BERRY_TREE_ROUTE_123_SOIL":63,"BERRY_TREE_ROUTE_130_LIECHI":82,"DAILY_FLAGS_END":2399,"DAILY_FLAGS_START":2336,"FIRST_BALL":1,"FIRST_BERRY_INDEX":133,"FIRST_BERRY_MASTER_BERRY":153,"FIRST_BERRY_MASTER_WIFE_BERRY":133,"FIRST_KIRI_BERRY":153,"FIRST_MAIL_INDEX":121,"FIRST_ROUTE_114_MAN_BERRY":148,"FLAGS_COUNT":2400,"FLAG_ADDED_MATCH_CALL_TO_POKENAV":304,"FLAG_ADVENTURE_STARTED":116,"FLAG_ARRIVED_AT_MARINE_CAVE_EMERGE_SPOT":2265,"FLAG_ARRIVED_AT_NAVEL_ROCK":2273,"FLAG_ARRIVED_AT_TERRA_CAVE_ENTRANCE":2266,"FLAG_ARRIVED_ON_FARAWAY_ISLAND":2264,"FLAG_BADGE01_GET":2151,"FLAG_BADGE02_GET":2152,"FLAG_BADGE03_GET":2153,"FLAG_BADGE04_GET":2154,"FLAG_BADGE05_GET":2155,"FLAG_BADGE06_GET":2156,"FLAG_BADGE07_GET":2157,"FLAG_BADGE08_GET":2158,"FLAG_BATTLE_FRONTIER_TRADE_DONE":156,"FLAG_BEAT_MAGMA_GRUNT_JAGGED_PASS":313,"FLAG_BEAUTY_PAINTING_MADE":161,"FLAG_BERRY_MASTERS_WIFE":1197,"FLAG_BERRY_MASTER_RECEIVED_BERRY_1":1195,"FLAG_BERRY_MASTER_RECEIVED_BERRY_2":1196,"FLAG_BERRY_TREES_START":612,"FLAG_BERRY_TREE_01":612,"FLAG_BERRY_TREE_02":613,"FLAG_BERRY_TREE_03":614,"FLAG_BERRY_TREE_04":615,"FLAG_BERRY_TREE_05":616,"FLAG_BERRY_TREE_06":617,"FLAG_BERRY_TREE_07":618,"FLAG_BERRY_TREE_08":619,"FLAG_BERRY_TREE_09":620,"FLAG_BERRY_TREE_10":621,"FLAG_BERRY_TREE_11":622,"FLAG_BERRY_TREE_12":623,"FLAG_BERRY_TREE_13":624,"FLAG_BERRY_TREE_14":625,"FLAG_BERRY_TREE_15":626,"FLAG_BERRY_TREE_16":627,"FLAG_BERRY_TREE_17":628,"FLAG_BERRY_TREE_18":629,"FLAG_BERRY_TREE_19":630,"FLAG_BERRY_TREE_20":631,"FLAG_BERRY_TREE_21":632,"FLAG_BERRY_TREE_22":633,"FLAG_BERRY_TREE_23":634,"FLAG_BERRY_TREE_24":635,"FLAG_BERRY_TREE_25":636,"FLAG_BERRY_TREE_26":637,"FLAG_BERRY_TREE_27":638,"FLAG_BERRY_TREE_28":639,"FLAG_BERRY_TREE_29":640,"FLAG_BERRY_TREE_30":641,"FLAG_BERRY_TREE_31":642,"FLAG_BERRY_TREE_32":643,"FLAG_BERRY_TREE_33":644,"FLAG_BERRY_TREE_34":645,"FLAG_BERRY_TREE_35":646,"FLAG_BERRY_TREE_36":647,"FLAG_BERRY_TREE_37":648,"FLAG_BERRY_TREE_38":649,"FLAG_BERRY_TREE_39":650,"FLAG_BERRY_TREE_40":651,"FLAG_BERRY_TREE_41":652,"FLAG_BERRY_TREE_42":653,"FLAG_BERRY_TREE_43":654,"FLAG_BERRY_TREE_44":655,"FLAG_BERRY_TREE_45":656,"FLAG_BERRY_TREE_46":657,"FLAG_BERRY_TREE_47":658,"FLAG_BERRY_TREE_48":659,"FLAG_BERRY_TREE_49":660,"FLAG_BERRY_TREE_50":661,"FLAG_BERRY_TREE_51":662,"FLAG_BERRY_TREE_52":663,"FLAG_BERRY_TREE_53":664,"FLAG_BERRY_TREE_54":665,"FLAG_BERRY_TREE_55":666,"FLAG_BERRY_TREE_56":667,"FLAG_BERRY_TREE_57":668,"FLAG_BERRY_TREE_58":669,"FLAG_BERRY_TREE_59":670,"FLAG_BERRY_TREE_60":671,"FLAG_BERRY_TREE_61":672,"FLAG_BERRY_TREE_62":673,"FLAG_BERRY_TREE_63":674,"FLAG_BERRY_TREE_64":675,"FLAG_BERRY_TREE_65":676,"FLAG_BERRY_TREE_66":677,"FLAG_BERRY_TREE_67":678,"FLAG_BERRY_TREE_68":679,"FLAG_BERRY_TREE_69":680,"FLAG_BERRY_TREE_70":681,"FLAG_BERRY_TREE_71":682,"FLAG_BERRY_TREE_72":683,"FLAG_BERRY_TREE_73":684,"FLAG_BERRY_TREE_74":685,"FLAG_BERRY_TREE_75":686,"FLAG_BERRY_TREE_76":687,"FLAG_BERRY_TREE_77":688,"FLAG_BERRY_TREE_78":689,"FLAG_BERRY_TREE_79":690,"FLAG_BERRY_TREE_80":691,"FLAG_BERRY_TREE_81":692,"FLAG_BERRY_TREE_82":693,"FLAG_BERRY_TREE_83":694,"FLAG_BERRY_TREE_84":695,"FLAG_BERRY_TREE_85":696,"FLAG_BERRY_TREE_86":697,"FLAG_BERRY_TREE_87":698,"FLAG_BERRY_TREE_88":699,"FLAG_BETTER_SHOPS_ENABLED":206,"FLAG_BIRCH_AIDE_MET":88,"FLAG_CANCEL_BATTLE_ROOM_CHALLENGE":119,"FLAG_CAUGHT_DEOXYS":429,"FLAG_CAUGHT_GROUDON":480,"FLAG_CAUGHT_HO_OH":146,"FLAG_CAUGHT_KYOGRE":479,"FLAG_CAUGHT_LATIAS":457,"FLAG_CAUGHT_LATIOS":482,"FLAG_CAUGHT_LUGIA":145,"FLAG_CAUGHT_MEW":458,"FLAG_CAUGHT_RAYQUAZA":478,"FLAG_CAUGHT_REGICE":427,"FLAG_CAUGHT_REGIROCK":426,"FLAG_CAUGHT_REGISTEEL":483,"FLAG_CHOSEN_MULTI_BATTLE_NPC_PARTNER":338,"FLAG_CHOSE_CLAW_FOSSIL":336,"FLAG_CHOSE_ROOT_FOSSIL":335,"FLAG_COLLECTED_ALL_GOLD_SYMBOLS":466,"FLAG_COLLECTED_ALL_SILVER_SYMBOLS":92,"FLAG_CONTEST_SKETCH_CREATED":270,"FLAG_COOL_PAINTING_MADE":160,"FLAG_CUTE_PAINTING_MADE":162,"FLAG_DAILY_APPRENTICE_LEAVES":2356,"FLAG_DAILY_BERRY_MASTERS_WIFE":2353,"FLAG_DAILY_BERRY_MASTER_RECEIVED_BERRY":2349,"FLAG_DAILY_CONTEST_LOBBY_RECEIVED_BERRY":2337,"FLAG_DAILY_FLOWER_SHOP_RECEIVED_BERRY":2352,"FLAG_DAILY_LILYCOVE_RECEIVED_BERRY":2351,"FLAG_DAILY_PICKED_LOTO_TICKET":2346,"FLAG_DAILY_ROUTE_111_RECEIVED_BERRY":2348,"FLAG_DAILY_ROUTE_114_RECEIVED_BERRY":2347,"FLAG_DAILY_ROUTE_120_RECEIVED_BERRY":2350,"FLAG_DAILY_SECRET_BASE":2338,"FLAG_DAILY_SOOTOPOLIS_RECEIVED_BERRY":2354,"FLAG_DECLINED_BIKE":89,"FLAG_DECLINED_RIVAL_BATTLE_LILYCOVE":286,"FLAG_DECLINED_WALLY_BATTLE_MAUVILLE":284,"FLAG_DECORATION_1":174,"FLAG_DECORATION_10":183,"FLAG_DECORATION_11":184,"FLAG_DECORATION_12":185,"FLAG_DECORATION_13":186,"FLAG_DECORATION_14":187,"FLAG_DECORATION_2":175,"FLAG_DECORATION_3":176,"FLAG_DECORATION_4":177,"FLAG_DECORATION_5":178,"FLAG_DECORATION_6":179,"FLAG_DECORATION_7":180,"FLAG_DECORATION_8":181,"FLAG_DECORATION_9":182,"FLAG_DEFEATED_DEOXYS":428,"FLAG_DEFEATED_DEWFORD_GYM":1265,"FLAG_DEFEATED_ELECTRODE_1_AQUA_HIDEOUT":452,"FLAG_DEFEATED_ELECTRODE_2_AQUA_HIDEOUT":453,"FLAG_DEFEATED_ELITE_4_DRAKE":1278,"FLAG_DEFEATED_ELITE_4_GLACIA":1277,"FLAG_DEFEATED_ELITE_4_PHOEBE":1276,"FLAG_DEFEATED_ELITE_4_SIDNEY":1275,"FLAG_DEFEATED_EVIL_TEAM_MT_CHIMNEY":139,"FLAG_DEFEATED_FORTREE_GYM":1269,"FLAG_DEFEATED_GROUDON":447,"FLAG_DEFEATED_GRUNT_SPACE_CENTER_1F":191,"FLAG_DEFEATED_HO_OH":476,"FLAG_DEFEATED_KECLEON_1_ROUTE_119":989,"FLAG_DEFEATED_KECLEON_1_ROUTE_120":982,"FLAG_DEFEATED_KECLEON_2_ROUTE_119":990,"FLAG_DEFEATED_KECLEON_2_ROUTE_120":985,"FLAG_DEFEATED_KECLEON_3_ROUTE_120":986,"FLAG_DEFEATED_KECLEON_4_ROUTE_120":987,"FLAG_DEFEATED_KECLEON_5_ROUTE_120":988,"FLAG_DEFEATED_KEKLEON_ROUTE_120_BRIDGE":970,"FLAG_DEFEATED_KYOGRE":446,"FLAG_DEFEATED_LATIAS":456,"FLAG_DEFEATED_LATIOS":481,"FLAG_DEFEATED_LAVARIDGE_GYM":1267,"FLAG_DEFEATED_LUGIA":477,"FLAG_DEFEATED_MAGMA_SPACE_CENTER":117,"FLAG_DEFEATED_MAUVILLE_GYM":1266,"FLAG_DEFEATED_METEOR_FALLS_STEVEN":1272,"FLAG_DEFEATED_MEW":455,"FLAG_DEFEATED_MOSSDEEP_GYM":1270,"FLAG_DEFEATED_PETALBURG_GYM":1268,"FLAG_DEFEATED_RAYQUAZA":448,"FLAG_DEFEATED_REGICE":444,"FLAG_DEFEATED_REGIROCK":443,"FLAG_DEFEATED_REGISTEEL":445,"FLAG_DEFEATED_RIVAL_ROUTE103":130,"FLAG_DEFEATED_RIVAL_ROUTE_104":125,"FLAG_DEFEATED_RIVAL_RUSTBORO":211,"FLAG_DEFEATED_RUSTBORO_GYM":1264,"FLAG_DEFEATED_SEASHORE_HOUSE":141,"FLAG_DEFEATED_SOOTOPOLIS_GYM":1271,"FLAG_DEFEATED_SS_TIDAL_TRAINERS":247,"FLAG_DEFEATED_SUDOWOODO":454,"FLAG_DEFEATED_VOLTORB_1_NEW_MAUVILLE":449,"FLAG_DEFEATED_VOLTORB_2_NEW_MAUVILLE":450,"FLAG_DEFEATED_VOLTORB_3_NEW_MAUVILLE":451,"FLAG_DEFEATED_WALLY_MAUVILLE":190,"FLAG_DEFEATED_WALLY_VICTORY_ROAD":126,"FLAG_DELIVERED_DEVON_GOODS":149,"FLAG_DELIVERED_STEVEN_LETTER":189,"FLAG_DEOXYS_IS_RECOVERING":1258,"FLAG_DEOXYS_ROCK_COMPLETE":2260,"FLAG_DEVON_GOODS_STOLEN":142,"FLAG_DOCK_REJECTED_DEVON_GOODS":148,"FLAG_DONT_TRANSITION_MUSIC":16385,"FLAG_ENABLE_BRAWLY_MATCH_CALL":468,"FLAG_ENABLE_FIRST_WALLY_POKENAV_CALL":136,"FLAG_ENABLE_FLANNERY_MATCH_CALL":470,"FLAG_ENABLE_JUAN_MATCH_CALL":473,"FLAG_ENABLE_MOM_MATCH_CALL":216,"FLAG_ENABLE_MR_STONE_POKENAV":344,"FLAG_ENABLE_MULTI_CORRIDOR_DOOR":16386,"FLAG_ENABLE_NORMAN_MATCH_CALL":306,"FLAG_ENABLE_PROF_BIRCH_MATCH_CALL":281,"FLAG_ENABLE_RIVAL_MATCH_CALL":253,"FLAG_ENABLE_ROXANNE_FIRST_CALL":128,"FLAG_ENABLE_ROXANNE_MATCH_CALL":467,"FLAG_ENABLE_SCOTT_MATCH_CALL":215,"FLAG_ENABLE_SHIP_BIRTH_ISLAND":2261,"FLAG_ENABLE_SHIP_FARAWAY_ISLAND":2262,"FLAG_ENABLE_SHIP_NAVEL_ROCK":2272,"FLAG_ENABLE_SHIP_SOUTHERN_ISLAND":2227,"FLAG_ENABLE_TATE_AND_LIZA_MATCH_CALL":472,"FLAG_ENABLE_WALLY_MATCH_CALL":214,"FLAG_ENABLE_WATTSON_MATCH_CALL":469,"FLAG_ENABLE_WINONA_MATCH_CALL":471,"FLAG_ENTERED_CONTEST":341,"FLAG_ENTERED_ELITE_FOUR":263,"FLAG_ENTERED_MIRAGE_TOWER":2268,"FLAG_EVIL_LEADER_PLEASE_STOP":219,"FLAG_EVIL_TEAM_ESCAPED_STERN_SPOKE":271,"FLAG_EXCHANGED_SCANNER":294,"FLAG_FAN_CLUB_STRENGTH_SHARED":210,"FLAG_FLOWER_SHOP_RECEIVED_BERRY":1207,"FLAG_FORCE_MIRAGE_TOWER_VISIBLE":157,"FLAG_FORTREE_NPC_TRADE_COMPLETED":155,"FLAG_GOOD_LUCK_SAFARI_ZONE":93,"FLAG_GOT_BASEMENT_KEY_FROM_WATTSON":208,"FLAG_GOT_TM_THUNDERBOLT_FROM_WATTSON":209,"FLAG_GROUDON_AWAKENED_MAGMA_HIDEOUT":111,"FLAG_GROUDON_IS_RECOVERING":1274,"FLAG_HAS_MATCH_CALL":303,"FLAG_HIDDEN_ITEMS_START":500,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":531,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":532,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":533,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":534,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":601,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":604,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":603,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":602,"FLAG_HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":528,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":548,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":549,"FLAG_HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":577,"FLAG_HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":576,"FLAG_HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":500,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":527,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":575,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":543,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":578,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":529,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":580,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":579,"FLAG_HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":609,"FLAG_HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":595,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":561,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POTION":558,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":559,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":560,"FLAG_HIDDEN_ITEM_ROUTE_104_ANTIDOTE":585,"FLAG_HIDDEN_ITEM_ROUTE_104_HEART_SCALE":588,"FLAG_HIDDEN_ITEM_ROUTE_104_POKE_BALL":562,"FLAG_HIDDEN_ITEM_ROUTE_104_POTION":537,"FLAG_HIDDEN_ITEM_ROUTE_104_SUPER_POTION":544,"FLAG_HIDDEN_ITEM_ROUTE_105_BIG_PEARL":611,"FLAG_HIDDEN_ITEM_ROUTE_105_HEART_SCALE":589,"FLAG_HIDDEN_ITEM_ROUTE_106_HEART_SCALE":547,"FLAG_HIDDEN_ITEM_ROUTE_106_POKE_BALL":563,"FLAG_HIDDEN_ITEM_ROUTE_106_STARDUST":546,"FLAG_HIDDEN_ITEM_ROUTE_108_RARE_CANDY":586,"FLAG_HIDDEN_ITEM_ROUTE_109_ETHER":564,"FLAG_HIDDEN_ITEM_ROUTE_109_GREAT_BALL":551,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":552,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":590,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":591,"FLAG_HIDDEN_ITEM_ROUTE_109_REVIVE":550,"FLAG_HIDDEN_ITEM_ROUTE_110_FULL_HEAL":555,"FLAG_HIDDEN_ITEM_ROUTE_110_GREAT_BALL":553,"FLAG_HIDDEN_ITEM_ROUTE_110_POKE_BALL":565,"FLAG_HIDDEN_ITEM_ROUTE_110_REVIVE":554,"FLAG_HIDDEN_ITEM_ROUTE_111_PROTEIN":556,"FLAG_HIDDEN_ITEM_ROUTE_111_RARE_CANDY":557,"FLAG_HIDDEN_ITEM_ROUTE_111_STARDUST":502,"FLAG_HIDDEN_ITEM_ROUTE_113_ETHER":503,"FLAG_HIDDEN_ITEM_ROUTE_113_NUGGET":598,"FLAG_HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":530,"FLAG_HIDDEN_ITEM_ROUTE_114_CARBOS":504,"FLAG_HIDDEN_ITEM_ROUTE_114_REVIVE":542,"FLAG_HIDDEN_ITEM_ROUTE_115_HEART_SCALE":597,"FLAG_HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":596,"FLAG_HIDDEN_ITEM_ROUTE_116_SUPER_POTION":545,"FLAG_HIDDEN_ITEM_ROUTE_117_REPEL":572,"FLAG_HIDDEN_ITEM_ROUTE_118_HEART_SCALE":566,"FLAG_HIDDEN_ITEM_ROUTE_118_IRON":567,"FLAG_HIDDEN_ITEM_ROUTE_119_CALCIUM":505,"FLAG_HIDDEN_ITEM_ROUTE_119_FULL_HEAL":568,"FLAG_HIDDEN_ITEM_ROUTE_119_MAX_ETHER":587,"FLAG_HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":506,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":571,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":569,"FLAG_HIDDEN_ITEM_ROUTE_120_REVIVE":584,"FLAG_HIDDEN_ITEM_ROUTE_120_ZINC":570,"FLAG_HIDDEN_ITEM_ROUTE_121_FULL_HEAL":573,"FLAG_HIDDEN_ITEM_ROUTE_121_HP_UP":539,"FLAG_HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":600,"FLAG_HIDDEN_ITEM_ROUTE_121_NUGGET":540,"FLAG_HIDDEN_ITEM_ROUTE_123_HYPER_POTION":574,"FLAG_HIDDEN_ITEM_ROUTE_123_PP_UP":599,"FLAG_HIDDEN_ITEM_ROUTE_123_RARE_CANDY":610,"FLAG_HIDDEN_ITEM_ROUTE_123_REVIVE":541,"FLAG_HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":507,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":592,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":593,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":594,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":606,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":607,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":605,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":608,"FLAG_HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":535,"FLAG_HIDDEN_ITEM_TRICK_HOUSE_NUGGET":501,"FLAG_HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":511,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CALCIUM":536,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CARBOS":508,"FLAG_HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":509,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":513,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":538,"FLAG_HIDDEN_ITEM_UNDERWATER_124_PEARL":510,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":520,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":512,"FLAG_HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":514,"FLAG_HIDDEN_ITEM_UNDERWATER_126_IRON":519,"FLAG_HIDDEN_ITEM_UNDERWATER_126_PEARL":517,"FLAG_HIDDEN_ITEM_UNDERWATER_126_STARDUST":516,"FLAG_HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":515,"FLAG_HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":518,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":523,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HP_UP":522,"FLAG_HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":524,"FLAG_HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":521,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PEARL":526,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PROTEIN":525,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":581,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":582,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":583,"FLAG_HIDE_APPRENTICE":701,"FLAG_HIDE_AQUA_HIDEOUT_1F_GRUNTS_BLOCKING_ENTRANCE":821,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_1":977,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_2":978,"FLAG_HIDE_AQUA_HIDEOUT_B2F_SUBMARINE_SHADOW":943,"FLAG_HIDE_AQUA_HIDEOUT_GRUNTS":924,"FLAG_HIDE_BATTLE_FRONTIER_RECEPTION_GATE_SCOTT":836,"FLAG_HIDE_BATTLE_FRONTIER_SUDOWOODO":842,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_1":711,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_2":712,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_3":713,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_4":714,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_5":715,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_6":716,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_1":864,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_2":865,"FLAG_HIDE_BATTLE_TOWER_OPPONENT":888,"FLAG_HIDE_BATTLE_TOWER_REPORTER":918,"FLAG_HIDE_BIRTH_ISLAND_DEOXYS_TRIANGLE":764,"FLAG_HIDE_BRINEYS_HOUSE_MR_BRINEY":739,"FLAG_HIDE_BRINEYS_HOUSE_PEEKO":881,"FLAG_HIDE_CAVE_OF_ORIGIN_B1F_WALLACE":820,"FLAG_HIDE_CHAMPIONS_ROOM_BIRCH":921,"FLAG_HIDE_CHAMPIONS_ROOM_RIVAL":920,"FLAG_HIDE_CONTEST_POKE_BALL":86,"FLAG_HIDE_DEOXYS":763,"FLAG_HIDE_DESERT_UNDERPASS_FOSSIL":874,"FLAG_HIDE_DEWFORD_HALL_SLUDGE_BOMB_MAN":940,"FLAG_HIDE_EVER_GRANDE_POKEMON_CENTER_1F_SCOTT":793,"FLAG_HIDE_FALLARBOR_AZURILL":907,"FLAG_HIDE_FALLARBOR_HOUSE_PROF_COZMO":928,"FLAG_HIDE_FALLARBOR_TOWN_BATTLE_TENT_SCOTT":767,"FLAG_HIDE_FALLORBOR_POKEMON_CENTER_LANETTE":871,"FLAG_HIDE_FANCLUB_BOY":790,"FLAG_HIDE_FANCLUB_LADY":792,"FLAG_HIDE_FANCLUB_LITTLE_BOY":791,"FLAG_HIDE_FANCLUB_OLD_LADY":789,"FLAG_HIDE_FORTREE_CITY_HOUSE_4_WINGULL":933,"FLAG_HIDE_FORTREE_CITY_KECLEON":969,"FLAG_HIDE_GRANITE_CAVE_STEVEN":833,"FLAG_HIDE_HO_OH":801,"FLAG_HIDE_JAGGED_PASS_MAGMA_GUARD":847,"FLAG_HIDE_LANETTES_HOUSE_LANETTE":870,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL":929,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL_ON_BIKE":930,"FLAG_HIDE_LILYCOVE_CITY_AQUA_GRUNTS":852,"FLAG_HIDE_LILYCOVE_CITY_RIVAL":971,"FLAG_HIDE_LILYCOVE_CITY_WAILMER":729,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER":832,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER_REPLACEMENT":873,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_1":774,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_2":895,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_REPORTER":802,"FLAG_HIDE_LILYCOVE_DEPARTMENT_STORE_ROOFTOP_SALE_WOMAN":962,"FLAG_HIDE_LILYCOVE_FAN_CLUB_INTERVIEWER":730,"FLAG_HIDE_LILYCOVE_HARBOR_EVENT_TICKET_TAKER":748,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_ATTENDANT":908,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_SAILOR":909,"FLAG_HIDE_LILYCOVE_HARBOR_SSTIDAL":861,"FLAG_HIDE_LILYCOVE_MOTEL_GAME_DESIGNERS":925,"FLAG_HIDE_LILYCOVE_MOTEL_SCOTT":787,"FLAG_HIDE_LILYCOVE_MUSEUM_CURATOR":775,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_1":776,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_2":777,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_3":778,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_4":779,"FLAG_HIDE_LILYCOVE_MUSEUM_TOURISTS":780,"FLAG_HIDE_LILYCOVE_POKEMON_CENTER_CONTEST_LADY_MON":993,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCH":795,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_BIRCH":721,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CHIKORITA":838,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CYNDAQUIL":811,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_TOTODILE":812,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_RIVAL":889,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_UNKNOWN_0x380":896,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_POKE_BALL":817,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_SWABLU_DOLL":815,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_BRENDAN":745,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_MOM":758,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_BEDROOM":760,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_MOM":784,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_SIBLING":735,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_TRUCK":761,"FLAG_HIDE_LITTLEROOT_TOWN_FAT_MAN":868,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_PICHU_DOLL":849,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_POKE_BALL":818,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MAY":746,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MOM":759,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_BEDROOM":722,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_MOM":785,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_SIBLING":736,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_TRUCK":762,"FLAG_HIDE_LITTLEROOT_TOWN_MOM_OUTSIDE":752,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_BEDROOM_MOM":757,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_1":754,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_2":755,"FLAG_HIDE_LITTLEROOT_TOWN_RIVAL":794,"FLAG_HIDE_LUGIA":800,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON":853,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON_ASLEEP":850,"FLAG_HIDE_MAGMA_HIDEOUT_GRUNTS":857,"FLAG_HIDE_MAGMA_HIDEOUT_MAXIE":867,"FLAG_HIDE_MAP_NAME_POPUP":16384,"FLAG_HIDE_MARINE_CAVE_KYOGRE":782,"FLAG_HIDE_MAUVILLE_CITY_SCOTT":765,"FLAG_HIDE_MAUVILLE_CITY_WALLY":804,"FLAG_HIDE_MAUVILLE_CITY_WALLYS_UNCLE":805,"FLAG_HIDE_MAUVILLE_CITY_WATTSON":912,"FLAG_HIDE_MAUVILLE_GYM_WATTSON":913,"FLAG_HIDE_METEOR_FALLS_1F_1R_COZMO":942,"FLAG_HIDE_METEOR_FALLS_TEAM_AQUA":938,"FLAG_HIDE_METEOR_FALLS_TEAM_MAGMA":939,"FLAG_HIDE_MEW":718,"FLAG_HIDE_MIRAGE_TOWER_CLAW_FOSSIL":964,"FLAG_HIDE_MIRAGE_TOWER_ROOT_FOSSIL":963,"FLAG_HIDE_MOSSDEEP_CITY_HOUSE_2_WINGULL":934,"FLAG_HIDE_MOSSDEEP_CITY_SCOTT":788,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_STEVEN":753,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_TEAM_MAGMA":756,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_STEVEN":863,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_TEAM_MAGMA":862,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_MAGMA_NOTE":737,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_BELDUM_POKEBALL":968,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_INVISIBLE_NINJA_BOY":727,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_STEVEN":967,"FLAG_HIDE_MOSSDEEP_CITY_TEAM_MAGMA":823,"FLAG_HIDE_MR_BRINEY_BOAT_DEWFORD_TOWN":743,"FLAG_HIDE_MR_BRINEY_DEWFORD_TOWN":740,"FLAG_HIDE_MT_CHIMNEY_LAVA_COOKIE_LADY":994,"FLAG_HIDE_MT_CHIMNEY_TEAM_AQUA":926,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA":927,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA_BATTLEABLE":981,"FLAG_HIDE_MT_CHIMNEY_TRAINERS":877,"FLAG_HIDE_MT_PYRE_SUMMIT_ARCHIE":916,"FLAG_HIDE_MT_PYRE_SUMMIT_MAXIE":856,"FLAG_HIDE_MT_PYRE_SUMMIT_TEAM_AQUA":917,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_1":974,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_2":975,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_3":976,"FLAG_HIDE_OLDALE_TOWN_RIVAL":979,"FLAG_HIDE_PETALBURG_CITY_SCOTT":995,"FLAG_HIDE_PETALBURG_CITY_WALLY":726,"FLAG_HIDE_PETALBURG_CITY_WALLYS_DAD":830,"FLAG_HIDE_PETALBURG_CITY_WALLYS_MOM":728,"FLAG_HIDE_PETALBURG_GYM_GREETER":781,"FLAG_HIDE_PETALBURG_GYM_NORMAN":772,"FLAG_HIDE_PETALBURG_GYM_WALLY":866,"FLAG_HIDE_PETALBURG_GYM_WALLYS_DAD":824,"FLAG_HIDE_PETALBURG_WOODS_AQUA_GRUNT":725,"FLAG_HIDE_PETALBURG_WOODS_DEVON_EMPLOYEE":724,"FLAG_HIDE_PLAYERS_HOUSE_DAD":734,"FLAG_HIDE_POKEMON_CENTER_2F_MYSTERY_GIFT_MAN":702,"FLAG_HIDE_REGICE":936,"FLAG_HIDE_REGIROCK":935,"FLAG_HIDE_REGISTEEL":937,"FLAG_HIDE_ROUTE_101_BIRCH":897,"FLAG_HIDE_ROUTE_101_BIRCH_STARTERS_BAG":700,"FLAG_HIDE_ROUTE_101_BIRCH_ZIGZAGOON_BATTLE":720,"FLAG_HIDE_ROUTE_101_BOY":991,"FLAG_HIDE_ROUTE_101_ZIGZAGOON":750,"FLAG_HIDE_ROUTE_103_BIRCH":898,"FLAG_HIDE_ROUTE_103_RIVAL":723,"FLAG_HIDE_ROUTE_104_MR_BRINEY":738,"FLAG_HIDE_ROUTE_104_MR_BRINEY_BOAT":742,"FLAG_HIDE_ROUTE_104_RIVAL":719,"FLAG_HIDE_ROUTE_104_WHITE_HERB_FLORIST":906,"FLAG_HIDE_ROUTE_109_MR_BRINEY":741,"FLAG_HIDE_ROUTE_109_MR_BRINEY_BOAT":744,"FLAG_HIDE_ROUTE_110_BIRCH":837,"FLAG_HIDE_ROUTE_110_RIVAL":919,"FLAG_HIDE_ROUTE_110_RIVAL_ON_BIKE":922,"FLAG_HIDE_ROUTE_110_TEAM_AQUA":900,"FLAG_HIDE_ROUTE_111_DESERT_FOSSIL":876,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_1":796,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_2":903,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_3":799,"FLAG_HIDE_ROUTE_111_PLAYER_DESCENT":875,"FLAG_HIDE_ROUTE_111_ROCK_SMASH_TIP_GUY":843,"FLAG_HIDE_ROUTE_111_SECRET_POWER_MAN":960,"FLAG_HIDE_ROUTE_111_VICKY_WINSTRATE":771,"FLAG_HIDE_ROUTE_111_VICTORIA_WINSTRATE":769,"FLAG_HIDE_ROUTE_111_VICTOR_WINSTRATE":768,"FLAG_HIDE_ROUTE_111_VIVI_WINSTRATE":770,"FLAG_HIDE_ROUTE_112_TEAM_MAGMA":819,"FLAG_HIDE_ROUTE_115_BOULDERS":825,"FLAG_HIDE_ROUTE_116_DEVON_EMPLOYEE":947,"FLAG_HIDE_ROUTE_116_DROPPED_GLASSES_MAN":813,"FLAG_HIDE_ROUTE_116_MR_BRINEY":891,"FLAG_HIDE_ROUTE_116_WANDAS_BOYFRIEND":894,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_1":797,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_2":901,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_3":904,"FLAG_HIDE_ROUTE_118_STEVEN":966,"FLAG_HIDE_ROUTE_119_RIVAL":851,"FLAG_HIDE_ROUTE_119_RIVAL_ON_BIKE":923,"FLAG_HIDE_ROUTE_119_SCOTT":786,"FLAG_HIDE_ROUTE_119_TEAM_AQUA":890,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_BRIDGE":822,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_SHELLY":915,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_1":798,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_2":902,"FLAG_HIDE_ROUTE_120_STEVEN":972,"FLAG_HIDE_ROUTE_121_TEAM_AQUA_GRUNTS":914,"FLAG_HIDE_ROUTE_128_ARCHIE":944,"FLAG_HIDE_ROUTE_128_MAXIE":945,"FLAG_HIDE_ROUTE_128_STEVEN":834,"FLAG_HIDE_RUSTBORO_CITY_AQUA_GRUNT":731,"FLAG_HIDE_RUSTBORO_CITY_DEVON_CORP_3F_EMPLOYEE":949,"FLAG_HIDE_RUSTBORO_CITY_DEVON_EMPLOYEE_1":732,"FLAG_HIDE_RUSTBORO_CITY_POKEMON_SCHOOL_SCOTT":999,"FLAG_HIDE_RUSTBORO_CITY_RIVAL":814,"FLAG_HIDE_RUSTBORO_CITY_SCIENTIST":844,"FLAG_HIDE_RUSTURF_TUNNEL_AQUA_GRUNT":878,"FLAG_HIDE_RUSTURF_TUNNEL_BRINEY":879,"FLAG_HIDE_RUSTURF_TUNNEL_PEEKO":880,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_1":931,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_2":932,"FLAG_HIDE_RUSTURF_TUNNEL_WANDA":983,"FLAG_HIDE_RUSTURF_TUNNEL_WANDAS_BOYFRIEND":807,"FLAG_HIDE_SAFARI_ZONE_SOUTH_CONSTRUCTION_WORKERS":717,"FLAG_HIDE_SAFARI_ZONE_SOUTH_EAST_EXPANSION":747,"FLAG_HIDE_SEAFLOOR_CAVERN_AQUA_GRUNTS":946,"FLAG_HIDE_SEAFLOOR_CAVERN_ENTRANCE_AQUA_GRUNT":941,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_ARCHIE":828,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE":859,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE_ASLEEP":733,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAGMA_GRUNTS":831,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAXIE":829,"FLAG_HIDE_SECRET_BASE_TRAINER":173,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA":773,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA_STILL":80,"FLAG_HIDE_SKY_PILLAR_WALLACE":855,"FLAG_HIDE_SLATEPORT_CITY_CAPTAIN_STERN":840,"FLAG_HIDE_SLATEPORT_CITY_CONTEST_REPORTER":803,"FLAG_HIDE_SLATEPORT_CITY_GABBY_AND_TY":835,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_AQUA_GRUNT":845,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_ARCHIE":846,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_CAPTAIN_STERN":841,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_PATRONS":905,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SS_TIDAL":860,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SUBMARINE_SHADOW":848,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_1":884,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_2":885,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_ARCHIE":886,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_CAPTAIN_STERN":887,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_AQUA_GRUNTS":883,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_FAMILIAR_AQUA_GRUNT":965,"FLAG_HIDE_SLATEPORT_CITY_SCOTT":749,"FLAG_HIDE_SLATEPORT_CITY_STERNS_SHIPYARD_MR_BRINEY":869,"FLAG_HIDE_SLATEPORT_CITY_TEAM_AQUA":882,"FLAG_HIDE_SLATEPORT_CITY_TM_SALESMAN":948,"FLAG_HIDE_SLATEPORT_MUSEUM_POPULATION":961,"FLAG_HIDE_SOOTOPOLIS_CITY_ARCHIE":826,"FLAG_HIDE_SOOTOPOLIS_CITY_GROUDON":998,"FLAG_HIDE_SOOTOPOLIS_CITY_KYOGRE":997,"FLAG_HIDE_SOOTOPOLIS_CITY_MAN_1":839,"FLAG_HIDE_SOOTOPOLIS_CITY_MAXIE":827,"FLAG_HIDE_SOOTOPOLIS_CITY_RAYQUAZA":996,"FLAG_HIDE_SOOTOPOLIS_CITY_RESIDENTS":854,"FLAG_HIDE_SOOTOPOLIS_CITY_STEVEN":973,"FLAG_HIDE_SOOTOPOLIS_CITY_WALLACE":816,"FLAG_HIDE_SOUTHERN_ISLAND_EON_STONE":910,"FLAG_HIDE_SOUTHERN_ISLAND_UNCHOSEN_EON_DUO_MON":911,"FLAG_HIDE_SS_TIDAL_CORRIDOR_MR_BRINEY":950,"FLAG_HIDE_SS_TIDAL_CORRIDOR_SCOTT":810,"FLAG_HIDE_SS_TIDAL_ROOMS_SNATCH_GIVER":951,"FLAG_HIDE_TERRA_CAVE_GROUDON":783,"FLAG_HIDE_TRICK_HOUSE_END_MAN":899,"FLAG_HIDE_TRICK_HOUSE_ENTRANCE_MAN":872,"FLAG_HIDE_UNDERWATER_SEA_FLOOR_CAVERN_STOLEN_SUBMARINE":980,"FLAG_HIDE_UNION_ROOM_PLAYER_1":703,"FLAG_HIDE_UNION_ROOM_PLAYER_2":704,"FLAG_HIDE_UNION_ROOM_PLAYER_3":705,"FLAG_HIDE_UNION_ROOM_PLAYER_4":706,"FLAG_HIDE_UNION_ROOM_PLAYER_5":707,"FLAG_HIDE_UNION_ROOM_PLAYER_6":708,"FLAG_HIDE_UNION_ROOM_PLAYER_7":709,"FLAG_HIDE_UNION_ROOM_PLAYER_8":710,"FLAG_HIDE_VERDANTURF_TOWN_SCOTT":766,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLY":806,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLYS_UNCLE":809,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDA":984,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDAS_BOYFRIEND":808,"FLAG_HIDE_VICTORY_ROAD_ENTRANCE_WALLY":858,"FLAG_HIDE_VICTORY_ROAD_EXIT_WALLY":751,"FLAG_HIDE_WEATHER_INSTITUTE_1F_WORKERS":892,"FLAG_HIDE_WEATHER_INSTITUTE_2F_AQUA_GRUNT_M":992,"FLAG_HIDE_WEATHER_INSTITUTE_2F_WORKERS":893,"FLAG_HO_OH_IS_RECOVERING":1256,"FLAG_INTERACTED_WITH_DEVON_EMPLOYEE_GOODS_STOLEN":159,"FLAG_INTERACTED_WITH_STEVEN_SPACE_CENTER":205,"FLAG_IS_CHAMPION":2175,"FLAG_ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":1100,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":1102,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":1078,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":1101,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":1077,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":1095,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":1099,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":1097,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":1096,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":1098,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":1124,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":1071,"FLAG_ITEM_AQUA_HIDEOUT_B1F_NUGGET":1132,"FLAG_ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":1072,"FLAG_ITEM_ARTISAN_CAVE_1F_CARBOS":1163,"FLAG_ITEM_ARTISAN_CAVE_B1F_HP_UP":1162,"FLAG_ITEM_FIERY_PATH_FIRE_STONE":1111,"FLAG_ITEM_FIERY_PATH_TM_TOXIC":1091,"FLAG_ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":1050,"FLAG_ITEM_GRANITE_CAVE_B1F_POKE_BALL":1051,"FLAG_ITEM_GRANITE_CAVE_B2F_RARE_CANDY":1054,"FLAG_ITEM_GRANITE_CAVE_B2F_REPEL":1053,"FLAG_ITEM_JAGGED_PASS_BURN_HEAL":1070,"FLAG_ITEM_LILYCOVE_CITY_MAX_REPEL":1042,"FLAG_ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":1151,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":1165,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":1164,"FLAG_ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":1166,"FLAG_ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":1167,"FLAG_ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":1059,"FLAG_ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":1168,"FLAG_ITEM_MAUVILLE_CITY_X_SPEED":1116,"FLAG_ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":1045,"FLAG_ITEM_METEOR_FALLS_1F_1R_MOON_STONE":1046,"FLAG_ITEM_METEOR_FALLS_1F_1R_PP_UP":1047,"FLAG_ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":1044,"FLAG_ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":1080,"FLAG_ITEM_MOSSDEEP_CITY_NET_BALL":1043,"FLAG_ITEM_MOSSDEEP_STEVENS_HOUSE_HM08":1133,"FLAG_ITEM_MT_PYRE_2F_ULTRA_BALL":1129,"FLAG_ITEM_MT_PYRE_3F_SUPER_REPEL":1120,"FLAG_ITEM_MT_PYRE_4F_SEA_INCENSE":1130,"FLAG_ITEM_MT_PYRE_5F_LAX_INCENSE":1052,"FLAG_ITEM_MT_PYRE_6F_TM_SHADOW_BALL":1089,"FLAG_ITEM_MT_PYRE_EXTERIOR_MAX_POTION":1073,"FLAG_ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":1074,"FLAG_ITEM_NEW_MAUVILLE_ESCAPE_ROPE":1076,"FLAG_ITEM_NEW_MAUVILLE_FULL_HEAL":1122,"FLAG_ITEM_NEW_MAUVILLE_PARALYZE_HEAL":1123,"FLAG_ITEM_NEW_MAUVILLE_THUNDER_STONE":1110,"FLAG_ITEM_NEW_MAUVILLE_ULTRA_BALL":1075,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MASTER_BALL":1125,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MAX_ELIXIR":1126,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B2F_NEST_BALL":1127,"FLAG_ITEM_PETALBURG_CITY_ETHER":1040,"FLAG_ITEM_PETALBURG_CITY_MAX_REVIVE":1039,"FLAG_ITEM_PETALBURG_WOODS_ETHER":1058,"FLAG_ITEM_PETALBURG_WOODS_GREAT_BALL":1056,"FLAG_ITEM_PETALBURG_WOODS_PARALYZE_HEAL":1117,"FLAG_ITEM_PETALBURG_WOODS_X_ATTACK":1055,"FLAG_ITEM_ROUTE_102_POTION":1000,"FLAG_ITEM_ROUTE_103_GUARD_SPEC":1114,"FLAG_ITEM_ROUTE_103_PP_UP":1137,"FLAG_ITEM_ROUTE_104_POKE_BALL":1057,"FLAG_ITEM_ROUTE_104_POTION":1135,"FLAG_ITEM_ROUTE_104_PP_UP":1002,"FLAG_ITEM_ROUTE_104_X_ACCURACY":1115,"FLAG_ITEM_ROUTE_105_IRON":1003,"FLAG_ITEM_ROUTE_106_PROTEIN":1004,"FLAG_ITEM_ROUTE_108_STAR_PIECE":1139,"FLAG_ITEM_ROUTE_109_POTION":1140,"FLAG_ITEM_ROUTE_109_PP_UP":1005,"FLAG_ITEM_ROUTE_110_DIRE_HIT":1007,"FLAG_ITEM_ROUTE_110_ELIXIR":1141,"FLAG_ITEM_ROUTE_110_RARE_CANDY":1006,"FLAG_ITEM_ROUTE_111_ELIXIR":1142,"FLAG_ITEM_ROUTE_111_HP_UP":1010,"FLAG_ITEM_ROUTE_111_STARDUST":1009,"FLAG_ITEM_ROUTE_111_TM_SANDSTORM":1008,"FLAG_ITEM_ROUTE_112_NUGGET":1011,"FLAG_ITEM_ROUTE_113_HYPER_POTION":1143,"FLAG_ITEM_ROUTE_113_MAX_ETHER":1012,"FLAG_ITEM_ROUTE_113_SUPER_REPEL":1013,"FLAG_ITEM_ROUTE_114_ENERGY_POWDER":1160,"FLAG_ITEM_ROUTE_114_PROTEIN":1015,"FLAG_ITEM_ROUTE_114_RARE_CANDY":1014,"FLAG_ITEM_ROUTE_115_GREAT_BALL":1118,"FLAG_ITEM_ROUTE_115_HEAL_POWDER":1144,"FLAG_ITEM_ROUTE_115_IRON":1018,"FLAG_ITEM_ROUTE_115_PP_UP":1161,"FLAG_ITEM_ROUTE_115_SUPER_POTION":1016,"FLAG_ITEM_ROUTE_115_TM_FOCUS_PUNCH":1017,"FLAG_ITEM_ROUTE_116_ETHER":1019,"FLAG_ITEM_ROUTE_116_HP_UP":1021,"FLAG_ITEM_ROUTE_116_POTION":1146,"FLAG_ITEM_ROUTE_116_REPEL":1020,"FLAG_ITEM_ROUTE_116_X_SPECIAL":1001,"FLAG_ITEM_ROUTE_117_GREAT_BALL":1022,"FLAG_ITEM_ROUTE_117_REVIVE":1023,"FLAG_ITEM_ROUTE_118_HYPER_POTION":1121,"FLAG_ITEM_ROUTE_119_ELIXIR_1":1026,"FLAG_ITEM_ROUTE_119_ELIXIR_2":1147,"FLAG_ITEM_ROUTE_119_HYPER_POTION_1":1029,"FLAG_ITEM_ROUTE_119_HYPER_POTION_2":1106,"FLAG_ITEM_ROUTE_119_LEAF_STONE":1027,"FLAG_ITEM_ROUTE_119_NUGGET":1134,"FLAG_ITEM_ROUTE_119_RARE_CANDY":1028,"FLAG_ITEM_ROUTE_119_SUPER_REPEL":1024,"FLAG_ITEM_ROUTE_119_ZINC":1025,"FLAG_ITEM_ROUTE_120_FULL_HEAL":1031,"FLAG_ITEM_ROUTE_120_HYPER_POTION":1107,"FLAG_ITEM_ROUTE_120_NEST_BALL":1108,"FLAG_ITEM_ROUTE_120_NUGGET":1030,"FLAG_ITEM_ROUTE_120_REVIVE":1148,"FLAG_ITEM_ROUTE_121_CARBOS":1103,"FLAG_ITEM_ROUTE_121_REVIVE":1149,"FLAG_ITEM_ROUTE_121_ZINC":1150,"FLAG_ITEM_ROUTE_123_CALCIUM":1032,"FLAG_ITEM_ROUTE_123_ELIXIR":1109,"FLAG_ITEM_ROUTE_123_PP_UP":1152,"FLAG_ITEM_ROUTE_123_REVIVAL_HERB":1153,"FLAG_ITEM_ROUTE_123_ULTRA_BALL":1104,"FLAG_ITEM_ROUTE_124_BLUE_SHARD":1093,"FLAG_ITEM_ROUTE_124_RED_SHARD":1092,"FLAG_ITEM_ROUTE_124_YELLOW_SHARD":1066,"FLAG_ITEM_ROUTE_125_BIG_PEARL":1154,"FLAG_ITEM_ROUTE_126_GREEN_SHARD":1105,"FLAG_ITEM_ROUTE_127_CARBOS":1035,"FLAG_ITEM_ROUTE_127_RARE_CANDY":1155,"FLAG_ITEM_ROUTE_127_ZINC":1034,"FLAG_ITEM_ROUTE_132_PROTEIN":1156,"FLAG_ITEM_ROUTE_132_RARE_CANDY":1036,"FLAG_ITEM_ROUTE_133_BIG_PEARL":1037,"FLAG_ITEM_ROUTE_133_MAX_REVIVE":1157,"FLAG_ITEM_ROUTE_133_STAR_PIECE":1038,"FLAG_ITEM_ROUTE_134_CARBOS":1158,"FLAG_ITEM_ROUTE_134_STAR_PIECE":1159,"FLAG_ITEM_RUSTBORO_CITY_X_DEFEND":1041,"FLAG_ITEM_RUSTURF_TUNNEL_MAX_ETHER":1049,"FLAG_ITEM_RUSTURF_TUNNEL_POKE_BALL":1048,"FLAG_ITEM_SAFARI_ZONE_NORTH_CALCIUM":1119,"FLAG_ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":1169,"FLAG_ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":1094,"FLAG_ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":1170,"FLAG_ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":1131,"FLAG_ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":1079,"FLAG_ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":1090,"FLAG_ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":1081,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":1113,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":1112,"FLAG_ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":1082,"FLAG_ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":1083,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":1060,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":1061,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":1062,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":1063,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":1064,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":1065,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":1067,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":1068,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":1069,"FLAG_ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":1084,"FLAG_ITEM_VICTORY_ROAD_1F_PP_UP":1085,"FLAG_ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":1087,"FLAG_ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":1086,"FLAG_ITEM_VICTORY_ROAD_B2F_FULL_HEAL":1088,"FLAG_KECLEON_FLED_FORTREE":295,"FLAG_KYOGRE_ESCAPED_SEAFLOOR_CAVERN":129,"FLAG_KYOGRE_IS_RECOVERING":1273,"FLAG_LANDMARK_ABANDONED_SHIP":2206,"FLAG_LANDMARK_ALTERING_CAVE":2269,"FLAG_LANDMARK_ANCIENT_TOMB":2233,"FLAG_LANDMARK_ARTISAN_CAVE":2271,"FLAG_LANDMARK_BATTLE_FRONTIER":2216,"FLAG_LANDMARK_BERRY_MASTERS_HOUSE":2243,"FLAG_LANDMARK_DESERT_RUINS":2230,"FLAG_LANDMARK_DESERT_UNDERPASS":2270,"FLAG_LANDMARK_FIERY_PATH":2218,"FLAG_LANDMARK_FLOWER_SHOP":2204,"FLAG_LANDMARK_FOSSIL_MANIACS_HOUSE":2231,"FLAG_LANDMARK_GLASS_WORKSHOP":2212,"FLAG_LANDMARK_HUNTERS_HOUSE":2235,"FLAG_LANDMARK_ISLAND_CAVE":2229,"FLAG_LANDMARK_LANETTES_HOUSE":2213,"FLAG_LANDMARK_MIRAGE_TOWER":120,"FLAG_LANDMARK_MR_BRINEY_HOUSE":2205,"FLAG_LANDMARK_NEW_MAUVILLE":2208,"FLAG_LANDMARK_OLD_LADY_REST_SHOP":2209,"FLAG_LANDMARK_POKEMON_DAYCARE":2214,"FLAG_LANDMARK_POKEMON_LEAGUE":2228,"FLAG_LANDMARK_SCORCHED_SLAB":2232,"FLAG_LANDMARK_SEAFLOOR_CAVERN":2215,"FLAG_LANDMARK_SEALED_CHAMBER":2236,"FLAG_LANDMARK_SEASHORE_HOUSE":2207,"FLAG_LANDMARK_SKY_PILLAR":2238,"FLAG_LANDMARK_SOUTHERN_ISLAND":2217,"FLAG_LANDMARK_TRAINER_HILL":2274,"FLAG_LANDMARK_TRICK_HOUSE":2210,"FLAG_LANDMARK_TUNNELERS_REST_HOUSE":2234,"FLAG_LANDMARK_WINSTRATE_FAMILY":2211,"FLAG_LATIAS_IS_RECOVERING":1263,"FLAG_LATIOS_IS_RECOVERING":1255,"FLAG_LATIOS_OR_LATIAS_ROAMING":255,"FLAG_LEGENDARIES_IN_SOOTOPOLIS":83,"FLAG_LILYCOVE_RECEIVED_BERRY":1208,"FLAG_LUGIA_IS_RECOVERING":1257,"FLAG_MAP_SCRIPT_CHECKED_DEOXYS":2259,"FLAG_MATCH_CALL_REGISTERED":348,"FLAG_MAUVILLE_GYM_BARRIERS_STATE":99,"FLAG_MET_ARCHIE_METEOR_FALLS":207,"FLAG_MET_ARCHIE_SOOTOPOLIS":308,"FLAG_MET_BATTLE_FRONTIER_BREEDER":339,"FLAG_MET_BATTLE_FRONTIER_GAMBLER":343,"FLAG_MET_BATTLE_FRONTIER_MANIAC":340,"FLAG_MET_DEVON_EMPLOYEE":287,"FLAG_MET_DIVING_TREASURE_HUNTER":217,"FLAG_MET_FANCLUB_YOUNGER_BROTHER":300,"FLAG_MET_FRONTIER_BEAUTY_MOVE_TUTOR":346,"FLAG_MET_FRONTIER_SWIMMER_MOVE_TUTOR":347,"FLAG_MET_HIDDEN_POWER_GIVER":118,"FLAG_MET_MAXIE_SOOTOPOLIS":309,"FLAG_MET_PRETTY_PETAL_SHOP_OWNER":127,"FLAG_MET_PROF_COZMO":244,"FLAG_MET_RIVAL_IN_HOUSE_AFTER_LILYCOVE":293,"FLAG_MET_RIVAL_LILYCOVE":292,"FLAG_MET_RIVAL_MOM":87,"FLAG_MET_RIVAL_RUSTBORO":288,"FLAG_MET_SCOTT_AFTER_OBTAINING_STONE_BADGE":459,"FLAG_MET_SCOTT_IN_EVERGRANDE":463,"FLAG_MET_SCOTT_IN_FALLARBOR":461,"FLAG_MET_SCOTT_IN_LILYCOVE":462,"FLAG_MET_SCOTT_IN_VERDANTURF":460,"FLAG_MET_SCOTT_ON_SS_TIDAL":464,"FLAG_MET_SCOTT_RUSTBORO":310,"FLAG_MET_SLATEPORT_FANCLUB_CHAIRMAN":342,"FLAG_MET_TEAM_AQUA_HARBOR":97,"FLAG_MET_WAILMER_TRAINER":218,"FLAG_MEW_IS_RECOVERING":1259,"FLAG_MIRAGE_TOWER_VISIBLE":334,"FLAG_MOSSDEEP_GYM_SWITCH_1":100,"FLAG_MOSSDEEP_GYM_SWITCH_2":101,"FLAG_MOSSDEEP_GYM_SWITCH_3":102,"FLAG_MOSSDEEP_GYM_SWITCH_4":103,"FLAG_MOVE_TUTOR_TAUGHT_DOUBLE_EDGE":441,"FLAG_MOVE_TUTOR_TAUGHT_DYNAMICPUNCH":440,"FLAG_MOVE_TUTOR_TAUGHT_EXPLOSION":442,"FLAG_MOVE_TUTOR_TAUGHT_FURY_CUTTER":435,"FLAG_MOVE_TUTOR_TAUGHT_METRONOME":437,"FLAG_MOVE_TUTOR_TAUGHT_MIMIC":436,"FLAG_MOVE_TUTOR_TAUGHT_ROLLOUT":434,"FLAG_MOVE_TUTOR_TAUGHT_SLEEP_TALK":438,"FLAG_MOVE_TUTOR_TAUGHT_SUBSTITUTE":439,"FLAG_MOVE_TUTOR_TAUGHT_SWAGGER":433,"FLAG_MR_BRINEY_SAILING_INTRO":147,"FLAG_MYSTERY_GIFT_1":485,"FLAG_MYSTERY_GIFT_10":494,"FLAG_MYSTERY_GIFT_11":495,"FLAG_MYSTERY_GIFT_12":496,"FLAG_MYSTERY_GIFT_13":497,"FLAG_MYSTERY_GIFT_14":498,"FLAG_MYSTERY_GIFT_15":499,"FLAG_MYSTERY_GIFT_2":486,"FLAG_MYSTERY_GIFT_3":487,"FLAG_MYSTERY_GIFT_4":488,"FLAG_MYSTERY_GIFT_5":489,"FLAG_MYSTERY_GIFT_6":490,"FLAG_MYSTERY_GIFT_7":491,"FLAG_MYSTERY_GIFT_8":492,"FLAG_MYSTERY_GIFT_9":493,"FLAG_MYSTERY_GIFT_DONE":484,"FLAG_NEVER_SET_0x0DC":220,"FLAG_NOT_READY_FOR_BATTLE_ROUTE_120":290,"FLAG_NURSE_MENTIONS_GOLD_CARD":345,"FLAG_NURSE_UNION_ROOM_REMINDER":2176,"FLAG_OCEANIC_MUSEUM_MET_REPORTER":105,"FLAG_OMIT_DIVE_FROM_STEVEN_LETTER":302,"FLAG_PACIFIDLOG_NPC_TRADE_COMPLETED":154,"FLAG_PENDING_DAYCARE_EGG":134,"FLAG_PETALBURG_MART_EXPANDED_ITEMS":296,"FLAG_POKERUS_EXPLAINED":273,"FLAG_PURCHASED_HARBOR_MAIL":104,"FLAG_RAYQUAZA_IS_RECOVERING":1279,"FLAG_RECEIVED_20_COINS":225,"FLAG_RECEIVED_6_SODA_POP":140,"FLAG_RECEIVED_ACRO_BIKE":1181,"FLAG_RECEIVED_AMULET_COIN":133,"FLAG_RECEIVED_AURORA_TICKET":314,"FLAG_RECEIVED_BADGE_1":1182,"FLAG_RECEIVED_BADGE_2":1183,"FLAG_RECEIVED_BADGE_3":1184,"FLAG_RECEIVED_BADGE_4":1185,"FLAG_RECEIVED_BADGE_5":1186,"FLAG_RECEIVED_BADGE_6":1187,"FLAG_RECEIVED_BADGE_7":1188,"FLAG_RECEIVED_BADGE_8":1189,"FLAG_RECEIVED_BELDUM":298,"FLAG_RECEIVED_BELUE_BERRY":252,"FLAG_RECEIVED_BIKE":90,"FLAG_RECEIVED_BLUE_SCARF":201,"FLAG_RECEIVED_CASTFORM":151,"FLAG_RECEIVED_CHARCOAL":254,"FLAG_RECEIVED_CHESTO_BERRY_ROUTE_104":246,"FLAG_RECEIVED_CLEANSE_TAG":282,"FLAG_RECEIVED_COIN_CASE":258,"FLAG_RECEIVED_CONTEST_PASS":150,"FLAG_RECEIVED_DEEP_SEA_SCALE":1190,"FLAG_RECEIVED_DEEP_SEA_TOOTH":1191,"FLAG_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":1172,"FLAG_RECEIVED_DEVON_SCOPE":285,"FLAG_RECEIVED_DOLL_LANETTE":131,"FLAG_RECEIVED_DURIN_BERRY":251,"FLAG_RECEIVED_EON_TICKET":474,"FLAG_RECEIVED_EXP_SHARE":272,"FLAG_RECEIVED_FANCLUB_TM_THIS_WEEK":299,"FLAG_RECEIVED_FIRST_POKEBALLS":233,"FLAG_RECEIVED_FOCUS_BAND":283,"FLAG_RECEIVED_GLASS_ORNAMENT":236,"FLAG_RECEIVED_GOLD_SHIELD":238,"FLAG_RECEIVED_GOOD_ROD":227,"FLAG_RECEIVED_GO_GOGGLES":221,"FLAG_RECEIVED_GREAT_BALL_PETALBURG_WOODS":1171,"FLAG_RECEIVED_GREAT_BALL_RUSTBORO_CITY":1173,"FLAG_RECEIVED_GREEN_SCARF":203,"FLAG_RECEIVED_HM_CUT":137,"FLAG_RECEIVED_HM_DIVE":123,"FLAG_RECEIVED_HM_FLASH":109,"FLAG_RECEIVED_HM_FLY":110,"FLAG_RECEIVED_HM_ROCK_SMASH":107,"FLAG_RECEIVED_HM_STRENGTH":106,"FLAG_RECEIVED_HM_SURF":122,"FLAG_RECEIVED_HM_WATERFALL":312,"FLAG_RECEIVED_ITEMFINDER":1176,"FLAG_RECEIVED_KINGS_ROCK":276,"FLAG_RECEIVED_LAVARIDGE_EGG":266,"FLAG_RECEIVED_LETTER":1174,"FLAG_RECEIVED_MACHO_BRACE":277,"FLAG_RECEIVED_MACH_BIKE":1180,"FLAG_RECEIVED_MAGMA_EMBLEM":1177,"FLAG_RECEIVED_MENTAL_HERB":223,"FLAG_RECEIVED_METEORITE":115,"FLAG_RECEIVED_MIRACLE_SEED":297,"FLAG_RECEIVED_MYSTIC_TICKET":315,"FLAG_RECEIVED_OLD_ROD":257,"FLAG_RECEIVED_OLD_SEA_MAP":316,"FLAG_RECEIVED_PAMTRE_BERRY":249,"FLAG_RECEIVED_PINK_SCARF":202,"FLAG_RECEIVED_POKEBLOCK_CASE":95,"FLAG_RECEIVED_POKEDEX_FROM_BIRCH":2276,"FLAG_RECEIVED_POKENAV":188,"FLAG_RECEIVED_POTION_OLDALE":132,"FLAG_RECEIVED_POWDER_JAR":337,"FLAG_RECEIVED_PREMIER_BALL_RUSTBORO":213,"FLAG_RECEIVED_QUICK_CLAW":275,"FLAG_RECEIVED_RED_OR_BLUE_ORB":212,"FLAG_RECEIVED_RED_SCARF":200,"FLAG_RECEIVED_REPEAT_BALL":256,"FLAG_RECEIVED_REVIVED_FOSSIL_MON":267,"FLAG_RECEIVED_RUNNING_SHOES":274,"FLAG_RECEIVED_SECRET_POWER":96,"FLAG_RECEIVED_SHOAL_SALT_1":952,"FLAG_RECEIVED_SHOAL_SALT_2":953,"FLAG_RECEIVED_SHOAL_SALT_3":954,"FLAG_RECEIVED_SHOAL_SALT_4":955,"FLAG_RECEIVED_SHOAL_SHELL_1":956,"FLAG_RECEIVED_SHOAL_SHELL_2":957,"FLAG_RECEIVED_SHOAL_SHELL_3":958,"FLAG_RECEIVED_SHOAL_SHELL_4":959,"FLAG_RECEIVED_SILK_SCARF":289,"FLAG_RECEIVED_SILVER_SHIELD":237,"FLAG_RECEIVED_SOFT_SAND":280,"FLAG_RECEIVED_SOOTHE_BELL":278,"FLAG_RECEIVED_SOOT_SACK":1033,"FLAG_RECEIVED_SPECIAL_PHRASE_HINT":85,"FLAG_RECEIVED_SPELON_BERRY":248,"FLAG_RECEIVED_SS_TICKET":291,"FLAG_RECEIVED_STARTER_DOLL":226,"FLAG_RECEIVED_SUN_STONE_MOSSDEEP":192,"FLAG_RECEIVED_SUPER_ROD":152,"FLAG_RECEIVED_TM_AERIAL_ACE":170,"FLAG_RECEIVED_TM_ATTRACT":235,"FLAG_RECEIVED_TM_BRICK_BREAK":121,"FLAG_RECEIVED_TM_BULK_UP":166,"FLAG_RECEIVED_TM_BULLET_SEED":262,"FLAG_RECEIVED_TM_CALM_MIND":171,"FLAG_RECEIVED_TM_DIG":261,"FLAG_RECEIVED_TM_FACADE":169,"FLAG_RECEIVED_TM_FRUSTRATION":1179,"FLAG_RECEIVED_TM_GIGA_DRAIN":232,"FLAG_RECEIVED_TM_HIDDEN_POWER":264,"FLAG_RECEIVED_TM_OVERHEAT":168,"FLAG_RECEIVED_TM_REST":234,"FLAG_RECEIVED_TM_RETURN":229,"FLAG_RECEIVED_TM_RETURN_2":1178,"FLAG_RECEIVED_TM_ROAR":231,"FLAG_RECEIVED_TM_ROCK_TOMB":165,"FLAG_RECEIVED_TM_SHOCK_WAVE":167,"FLAG_RECEIVED_TM_SLUDGE_BOMB":230,"FLAG_RECEIVED_TM_SNATCH":260,"FLAG_RECEIVED_TM_STEEL_WING":1175,"FLAG_RECEIVED_TM_THIEF":269,"FLAG_RECEIVED_TM_TORMENT":265,"FLAG_RECEIVED_TM_WATER_PULSE":172,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_1":1200,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_2":1201,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_3":1202,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_4":1203,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_5":1204,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_6":1205,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_7":1206,"FLAG_RECEIVED_WAILMER_DOLL":245,"FLAG_RECEIVED_WAILMER_PAIL":94,"FLAG_RECEIVED_WATMEL_BERRY":250,"FLAG_RECEIVED_WHITE_HERB":279,"FLAG_RECEIVED_YELLOW_SCARF":204,"FLAG_RECOVERED_DEVON_GOODS":143,"FLAG_REGICE_IS_RECOVERING":1260,"FLAG_REGIROCK_IS_RECOVERING":1261,"FLAG_REGISTEEL_IS_RECOVERING":1262,"FLAG_REGISTERED_STEVEN_POKENAV":305,"FLAG_REGISTER_RIVAL_POKENAV":124,"FLAG_REGI_DOORS_OPENED":228,"FLAG_REMATCH_ABIGAIL":387,"FLAG_REMATCH_AMY_AND_LIV":399,"FLAG_REMATCH_ANDRES":350,"FLAG_REMATCH_ANNA_AND_MEG":378,"FLAG_REMATCH_BENJAMIN":390,"FLAG_REMATCH_BERNIE":369,"FLAG_REMATCH_BRAWLY":415,"FLAG_REMATCH_BROOKE":356,"FLAG_REMATCH_CALVIN":383,"FLAG_REMATCH_CAMERON":373,"FLAG_REMATCH_CATHERINE":406,"FLAG_REMATCH_CINDY":359,"FLAG_REMATCH_CORY":401,"FLAG_REMATCH_CRISTIN":355,"FLAG_REMATCH_CYNDY":395,"FLAG_REMATCH_DALTON":368,"FLAG_REMATCH_DIANA":398,"FLAG_REMATCH_DRAKE":424,"FLAG_REMATCH_DUSTY":351,"FLAG_REMATCH_DYLAN":388,"FLAG_REMATCH_EDWIN":402,"FLAG_REMATCH_ELLIOT":384,"FLAG_REMATCH_ERNEST":400,"FLAG_REMATCH_ETHAN":370,"FLAG_REMATCH_FERNANDO":367,"FLAG_REMATCH_FLANNERY":417,"FLAG_REMATCH_GABRIELLE":405,"FLAG_REMATCH_GLACIA":423,"FLAG_REMATCH_HALEY":408,"FLAG_REMATCH_ISAAC":404,"FLAG_REMATCH_ISABEL":379,"FLAG_REMATCH_ISAIAH":385,"FLAG_REMATCH_JACKI":374,"FLAG_REMATCH_JACKSON":407,"FLAG_REMATCH_JAMES":409,"FLAG_REMATCH_JEFFREY":372,"FLAG_REMATCH_JENNY":397,"FLAG_REMATCH_JERRY":377,"FLAG_REMATCH_JESSICA":361,"FLAG_REMATCH_JOHN_AND_JAY":371,"FLAG_REMATCH_KAREN":376,"FLAG_REMATCH_KATELYN":389,"FLAG_REMATCH_KIRA_AND_DAN":412,"FLAG_REMATCH_KOJI":366,"FLAG_REMATCH_LAO":394,"FLAG_REMATCH_LILA_AND_ROY":354,"FLAG_REMATCH_LOLA":352,"FLAG_REMATCH_LYDIA":403,"FLAG_REMATCH_MADELINE":396,"FLAG_REMATCH_MARIA":386,"FLAG_REMATCH_MIGUEL":380,"FLAG_REMATCH_NICOLAS":392,"FLAG_REMATCH_NOB":365,"FLAG_REMATCH_NORMAN":418,"FLAG_REMATCH_PABLO":391,"FLAG_REMATCH_PHOEBE":422,"FLAG_REMATCH_RICKY":353,"FLAG_REMATCH_ROBERT":393,"FLAG_REMATCH_ROSE":349,"FLAG_REMATCH_ROXANNE":414,"FLAG_REMATCH_SAWYER":411,"FLAG_REMATCH_SHELBY":382,"FLAG_REMATCH_SIDNEY":421,"FLAG_REMATCH_STEVE":363,"FLAG_REMATCH_TATE_AND_LIZA":420,"FLAG_REMATCH_THALIA":360,"FLAG_REMATCH_TIMOTHY":381,"FLAG_REMATCH_TONY":364,"FLAG_REMATCH_TRENT":410,"FLAG_REMATCH_VALERIE":358,"FLAG_REMATCH_WALLACE":425,"FLAG_REMATCH_WALLY":413,"FLAG_REMATCH_WALTER":375,"FLAG_REMATCH_WATTSON":416,"FLAG_REMATCH_WILTON":357,"FLAG_REMATCH_WINONA":419,"FLAG_REMATCH_WINSTON":362,"FLAG_RESCUED_BIRCH":82,"FLAG_RETURNED_DEVON_GOODS":144,"FLAG_RETURNED_RED_OR_BLUE_ORB":259,"FLAG_RIVAL_LEFT_FOR_ROUTE103":301,"FLAG_ROUTE_111_RECEIVED_BERRY":1192,"FLAG_ROUTE_114_RECEIVED_BERRY":1193,"FLAG_ROUTE_120_RECEIVED_BERRY":1194,"FLAG_RUSTBORO_NPC_TRADE_COMPLETED":153,"FLAG_RUSTURF_TUNNEL_OPENED":199,"FLAG_SCOTT_CALL_BATTLE_FRONTIER":114,"FLAG_SCOTT_CALL_FORTREE_GYM":138,"FLAG_SCOTT_GIVES_BATTLE_POINTS":465,"FLAG_SECRET_BASE_REGISTRY_ENABLED":268,"FLAG_SET_WALL_CLOCK":81,"FLAG_SHOWN_AURORA_TICKET":431,"FLAG_SHOWN_BOX_WAS_FULL_MESSAGE":2263,"FLAG_SHOWN_EON_TICKET":430,"FLAG_SHOWN_MYSTIC_TICKET":475,"FLAG_SHOWN_OLD_SEA_MAP":432,"FLAG_SMART_PAINTING_MADE":163,"FLAG_SOOTOPOLIS_ARCHIE_MAXIE_LEAVE":158,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_1":1198,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_2":1199,"FLAG_SPECIAL_FLAG_UNUSED_0x4003":16387,"FLAG_SS_TIDAL_DISABLED":84,"FLAG_STEVEN_GUIDES_TO_CAVE_OF_ORIGIN":307,"FLAG_STORING_ITEMS_IN_PYRAMID_BAG":16388,"FLAG_SYS_ARENA_GOLD":2251,"FLAG_SYS_ARENA_SILVER":2250,"FLAG_SYS_BRAILLE_DIG":2223,"FLAG_SYS_BRAILLE_REGICE_COMPLETED":2225,"FLAG_SYS_B_DASH":2240,"FLAG_SYS_CAVE_BATTLE":2201,"FLAG_SYS_CAVE_SHIP":2199,"FLAG_SYS_CAVE_WONDER":2200,"FLAG_SYS_CHANGED_DEWFORD_TREND":2195,"FLAG_SYS_CHAT_USED":2149,"FLAG_SYS_CLOCK_SET":2197,"FLAG_SYS_CRUISE_MODE":2189,"FLAG_SYS_CTRL_OBJ_DELETE":2241,"FLAG_SYS_CYCLING_ROAD":2187,"FLAG_SYS_DOME_GOLD":2247,"FLAG_SYS_DOME_SILVER":2246,"FLAG_SYS_ENC_DOWN_ITEM":2222,"FLAG_SYS_ENC_UP_ITEM":2221,"FLAG_SYS_FACTORY_GOLD":2253,"FLAG_SYS_FACTORY_SILVER":2252,"FLAG_SYS_FRONTIER_PASS":2258,"FLAG_SYS_GAME_CLEAR":2148,"FLAG_SYS_MIX_RECORD":2196,"FLAG_SYS_MYSTERY_EVENT_ENABLE":2220,"FLAG_SYS_MYSTERY_GIFT_ENABLE":2267,"FLAG_SYS_NATIONAL_DEX":2198,"FLAG_SYS_PALACE_GOLD":2249,"FLAG_SYS_PALACE_SILVER":2248,"FLAG_SYS_PC_LANETTE":2219,"FLAG_SYS_PIKE_GOLD":2255,"FLAG_SYS_PIKE_SILVER":2254,"FLAG_SYS_POKEDEX_GET":2145,"FLAG_SYS_POKEMON_GET":2144,"FLAG_SYS_POKENAV_GET":2146,"FLAG_SYS_PYRAMID_GOLD":2257,"FLAG_SYS_PYRAMID_SILVER":2256,"FLAG_SYS_REGIROCK_PUZZLE_COMPLETED":2224,"FLAG_SYS_REGISTEEL_PUZZLE_COMPLETED":2226,"FLAG_SYS_RESET_RTC_ENABLE":2242,"FLAG_SYS_RIBBON_GET":2203,"FLAG_SYS_SAFARI_MODE":2188,"FLAG_SYS_SHOAL_ITEM":2239,"FLAG_SYS_SHOAL_TIDE":2202,"FLAG_SYS_TOWER_GOLD":2245,"FLAG_SYS_TOWER_SILVER":2244,"FLAG_SYS_TV_HOME":2192,"FLAG_SYS_TV_LATIAS_LATIOS":2237,"FLAG_SYS_TV_START":2194,"FLAG_SYS_TV_WATCH":2193,"FLAG_SYS_USE_FLASH":2184,"FLAG_SYS_USE_STRENGTH":2185,"FLAG_SYS_WEATHER_CTRL":2186,"FLAG_TEAM_AQUA_ESCAPED_IN_SUBMARINE":112,"FLAG_TEMP_1":1,"FLAG_TEMP_10":16,"FLAG_TEMP_11":17,"FLAG_TEMP_12":18,"FLAG_TEMP_13":19,"FLAG_TEMP_14":20,"FLAG_TEMP_15":21,"FLAG_TEMP_16":22,"FLAG_TEMP_17":23,"FLAG_TEMP_18":24,"FLAG_TEMP_19":25,"FLAG_TEMP_1A":26,"FLAG_TEMP_1B":27,"FLAG_TEMP_1C":28,"FLAG_TEMP_1D":29,"FLAG_TEMP_1E":30,"FLAG_TEMP_1F":31,"FLAG_TEMP_2":2,"FLAG_TEMP_3":3,"FLAG_TEMP_4":4,"FLAG_TEMP_5":5,"FLAG_TEMP_6":6,"FLAG_TEMP_7":7,"FLAG_TEMP_8":8,"FLAG_TEMP_9":9,"FLAG_TEMP_A":10,"FLAG_TEMP_B":11,"FLAG_TEMP_C":12,"FLAG_TEMP_D":13,"FLAG_TEMP_E":14,"FLAG_TEMP_F":15,"FLAG_TEMP_HIDE_MIRAGE_ISLAND_BERRY_TREE":17,"FLAG_TEMP_REGICE_PUZZLE_FAILED":3,"FLAG_TEMP_REGICE_PUZZLE_STARTED":2,"FLAG_TEMP_SKIP_GABBY_INTERVIEW":1,"FLAG_THANKED_FOR_PLAYING_WITH_WALLY":135,"FLAG_TOUGH_PAINTING_MADE":164,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_1":194,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_2":195,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_3":196,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_4":197,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_5":198,"FLAG_TV_EXPLAINED":98,"FLAG_UNLOCKED_TRENDY_SAYINGS":2150,"FLAG_USED_ROOM_1_KEY":240,"FLAG_USED_ROOM_2_KEY":241,"FLAG_USED_ROOM_4_KEY":242,"FLAG_USED_ROOM_6_KEY":243,"FLAG_USED_STORAGE_KEY":239,"FLAG_VISITED_DEWFORD_TOWN":2161,"FLAG_VISITED_EVER_GRANDE_CITY":2174,"FLAG_VISITED_FALLARBOR_TOWN":2163,"FLAG_VISITED_FORTREE_CITY":2170,"FLAG_VISITED_LAVARIDGE_TOWN":2162,"FLAG_VISITED_LILYCOVE_CITY":2171,"FLAG_VISITED_LITTLEROOT_TOWN":2159,"FLAG_VISITED_MAUVILLE_CITY":2168,"FLAG_VISITED_MOSSDEEP_CITY":2172,"FLAG_VISITED_OLDALE_TOWN":2160,"FLAG_VISITED_PACIFIDLOG_TOWN":2165,"FLAG_VISITED_PETALBURG_CITY":2166,"FLAG_VISITED_RUSTBORO_CITY":2169,"FLAG_VISITED_SLATEPORT_CITY":2167,"FLAG_VISITED_SOOTOPOLIS_CITY":2173,"FLAG_VISITED_VERDANTURF_TOWN":2164,"FLAG_WALLACE_GOES_TO_SKY_PILLAR":311,"FLAG_WALLY_SPEECH":193,"FLAG_WATTSON_REMATCH_AVAILABLE":91,"FLAG_WHITEOUT_TO_LAVARIDGE":108,"FLAG_WINGULL_DELIVERED_MAIL":224,"FLAG_WINGULL_SENT_ON_ERRAND":222,"FLAG_WONDER_CARD_UNUSED_1":317,"FLAG_WONDER_CARD_UNUSED_10":326,"FLAG_WONDER_CARD_UNUSED_11":327,"FLAG_WONDER_CARD_UNUSED_12":328,"FLAG_WONDER_CARD_UNUSED_13":329,"FLAG_WONDER_CARD_UNUSED_14":330,"FLAG_WONDER_CARD_UNUSED_15":331,"FLAG_WONDER_CARD_UNUSED_16":332,"FLAG_WONDER_CARD_UNUSED_17":333,"FLAG_WONDER_CARD_UNUSED_2":318,"FLAG_WONDER_CARD_UNUSED_3":319,"FLAG_WONDER_CARD_UNUSED_4":320,"FLAG_WONDER_CARD_UNUSED_5":321,"FLAG_WONDER_CARD_UNUSED_6":322,"FLAG_WONDER_CARD_UNUSED_7":323,"FLAG_WONDER_CARD_UNUSED_8":324,"FLAG_WONDER_CARD_UNUSED_9":325,"FLAVOR_BITTER":3,"FLAVOR_COUNT":5,"FLAVOR_DRY":1,"FLAVOR_SOUR":4,"FLAVOR_SPICY":0,"FLAVOR_SWEET":2,"GOOD_ROD":1,"ITEMS_COUNT":377,"ITEM_034":52,"ITEM_035":53,"ITEM_036":54,"ITEM_037":55,"ITEM_038":56,"ITEM_039":57,"ITEM_03A":58,"ITEM_03B":59,"ITEM_03C":60,"ITEM_03D":61,"ITEM_03E":62,"ITEM_048":72,"ITEM_052":82,"ITEM_057":87,"ITEM_058":88,"ITEM_059":89,"ITEM_05A":90,"ITEM_05B":91,"ITEM_05C":92,"ITEM_063":99,"ITEM_064":100,"ITEM_065":101,"ITEM_066":102,"ITEM_069":105,"ITEM_071":113,"ITEM_072":114,"ITEM_073":115,"ITEM_074":116,"ITEM_075":117,"ITEM_076":118,"ITEM_077":119,"ITEM_078":120,"ITEM_0EA":234,"ITEM_0EB":235,"ITEM_0EC":236,"ITEM_0ED":237,"ITEM_0EE":238,"ITEM_0EF":239,"ITEM_0F0":240,"ITEM_0F1":241,"ITEM_0F2":242,"ITEM_0F3":243,"ITEM_0F4":244,"ITEM_0F5":245,"ITEM_0F6":246,"ITEM_0F7":247,"ITEM_0F8":248,"ITEM_0F9":249,"ITEM_0FA":250,"ITEM_0FB":251,"ITEM_0FC":252,"ITEM_0FD":253,"ITEM_10B":267,"ITEM_15B":347,"ITEM_15C":348,"ITEM_ACRO_BIKE":272,"ITEM_AGUAV_BERRY":146,"ITEM_AMULET_COIN":189,"ITEM_ANTIDOTE":14,"ITEM_APICOT_BERRY":172,"ITEM_ARCHIPELAGO_PROGRESSION":112,"ITEM_ASPEAR_BERRY":137,"ITEM_AURORA_TICKET":371,"ITEM_AWAKENING":17,"ITEM_BADGE_1":226,"ITEM_BADGE_2":227,"ITEM_BADGE_3":228,"ITEM_BADGE_4":229,"ITEM_BADGE_5":230,"ITEM_BADGE_6":231,"ITEM_BADGE_7":232,"ITEM_BADGE_8":233,"ITEM_BASEMENT_KEY":271,"ITEM_BEAD_MAIL":127,"ITEM_BELUE_BERRY":167,"ITEM_BERRY_JUICE":44,"ITEM_BERRY_POUCH":365,"ITEM_BICYCLE":360,"ITEM_BIG_MUSHROOM":104,"ITEM_BIG_PEARL":107,"ITEM_BIKE_VOUCHER":352,"ITEM_BLACK_BELT":207,"ITEM_BLACK_FLUTE":42,"ITEM_BLACK_GLASSES":206,"ITEM_BLUE_FLUTE":39,"ITEM_BLUE_ORB":277,"ITEM_BLUE_SCARF":255,"ITEM_BLUE_SHARD":49,"ITEM_BLUK_BERRY":149,"ITEM_BRIGHT_POWDER":179,"ITEM_BURN_HEAL":15,"ITEM_B_USE_MEDICINE":1,"ITEM_B_USE_OTHER":2,"ITEM_CALCIUM":67,"ITEM_CARBOS":66,"ITEM_CARD_KEY":355,"ITEM_CHARCOAL":215,"ITEM_CHERI_BERRY":133,"ITEM_CHESTO_BERRY":134,"ITEM_CHOICE_BAND":186,"ITEM_CLAW_FOSSIL":287,"ITEM_CLEANSE_TAG":190,"ITEM_COIN_CASE":260,"ITEM_CONTEST_PASS":266,"ITEM_CORNN_BERRY":159,"ITEM_DEEP_SEA_SCALE":193,"ITEM_DEEP_SEA_TOOTH":192,"ITEM_DEVON_GOODS":269,"ITEM_DEVON_SCOPE":288,"ITEM_DIRE_HIT":74,"ITEM_DIVE_BALL":7,"ITEM_DOME_FOSSIL":358,"ITEM_DRAGON_FANG":216,"ITEM_DRAGON_SCALE":201,"ITEM_DREAM_MAIL":130,"ITEM_DURIN_BERRY":166,"ITEM_ELIXIR":36,"ITEM_ENERGY_POWDER":30,"ITEM_ENERGY_ROOT":31,"ITEM_ENIGMA_BERRY":175,"ITEM_EON_TICKET":275,"ITEM_ESCAPE_ROPE":85,"ITEM_ETHER":34,"ITEM_EVERSTONE":195,"ITEM_EXP_SHARE":182,"ITEM_FAB_MAIL":131,"ITEM_FAME_CHECKER":363,"ITEM_FIGY_BERRY":143,"ITEM_FIRE_STONE":95,"ITEM_FLUFFY_TAIL":81,"ITEM_FOCUS_BAND":196,"ITEM_FRESH_WATER":26,"ITEM_FULL_HEAL":23,"ITEM_FULL_RESTORE":19,"ITEM_GANLON_BERRY":169,"ITEM_GLITTER_MAIL":123,"ITEM_GOLD_TEETH":353,"ITEM_GOOD_ROD":263,"ITEM_GO_GOGGLES":279,"ITEM_GREAT_BALL":3,"ITEM_GREEN_SCARF":257,"ITEM_GREEN_SHARD":51,"ITEM_GREPA_BERRY":157,"ITEM_GUARD_SPEC":73,"ITEM_HARBOR_MAIL":122,"ITEM_HARD_STONE":204,"ITEM_HEAL_POWDER":32,"ITEM_HEART_SCALE":111,"ITEM_HELIX_FOSSIL":357,"ITEM_HM01":339,"ITEM_HM02":340,"ITEM_HM03":341,"ITEM_HM04":342,"ITEM_HM05":343,"ITEM_HM06":344,"ITEM_HM07":345,"ITEM_HM08":346,"ITEM_HM_CUT":339,"ITEM_HM_DIVE":346,"ITEM_HM_FLASH":343,"ITEM_HM_FLY":340,"ITEM_HM_ROCK_SMASH":344,"ITEM_HM_STRENGTH":342,"ITEM_HM_SURF":341,"ITEM_HM_WATERFALL":345,"ITEM_HONDEW_BERRY":156,"ITEM_HP_UP":63,"ITEM_HYPER_POTION":21,"ITEM_IAPAPA_BERRY":147,"ITEM_ICE_HEAL":16,"ITEM_IRON":65,"ITEM_ITEMFINDER":261,"ITEM_KELPSY_BERRY":154,"ITEM_KINGS_ROCK":187,"ITEM_LANSAT_BERRY":173,"ITEM_LAVA_COOKIE":38,"ITEM_LAX_INCENSE":221,"ITEM_LEAF_STONE":98,"ITEM_LEFTOVERS":200,"ITEM_LEMONADE":28,"ITEM_LEPPA_BERRY":138,"ITEM_LETTER":274,"ITEM_LIECHI_BERRY":168,"ITEM_LIFT_KEY":356,"ITEM_LIGHT_BALL":202,"ITEM_LIST_END":65535,"ITEM_LUCKY_EGG":197,"ITEM_LUCKY_PUNCH":222,"ITEM_LUM_BERRY":141,"ITEM_LUXURY_BALL":11,"ITEM_MACHO_BRACE":181,"ITEM_MACH_BIKE":259,"ITEM_MAGMA_EMBLEM":375,"ITEM_MAGNET":208,"ITEM_MAGOST_BERRY":160,"ITEM_MAGO_BERRY":145,"ITEM_MASTER_BALL":1,"ITEM_MAX_ELIXIR":37,"ITEM_MAX_ETHER":35,"ITEM_MAX_POTION":20,"ITEM_MAX_REPEL":84,"ITEM_MAX_REVIVE":25,"ITEM_MECH_MAIL":124,"ITEM_MENTAL_HERB":185,"ITEM_METAL_COAT":199,"ITEM_METAL_POWDER":223,"ITEM_METEORITE":280,"ITEM_MIRACLE_SEED":205,"ITEM_MOOMOO_MILK":29,"ITEM_MOON_STONE":94,"ITEM_MYSTIC_TICKET":370,"ITEM_MYSTIC_WATER":209,"ITEM_NANAB_BERRY":150,"ITEM_NEST_BALL":8,"ITEM_NET_BALL":6,"ITEM_NEVER_MELT_ICE":212,"ITEM_NOMEL_BERRY":162,"ITEM_NONE":0,"ITEM_NUGGET":110,"ITEM_OAKS_PARCEL":349,"ITEM_OLD_AMBER":354,"ITEM_OLD_ROD":262,"ITEM_OLD_SEA_MAP":376,"ITEM_ORANGE_MAIL":121,"ITEM_ORAN_BERRY":139,"ITEM_PAMTRE_BERRY":164,"ITEM_PARALYZE_HEAL":18,"ITEM_PEARL":106,"ITEM_PECHA_BERRY":135,"ITEM_PERSIM_BERRY":140,"ITEM_PETAYA_BERRY":171,"ITEM_PINAP_BERRY":152,"ITEM_PINK_SCARF":256,"ITEM_POISON_BARB":211,"ITEM_POKEBLOCK_CASE":273,"ITEM_POKE_BALL":4,"ITEM_POKE_DOLL":80,"ITEM_POKE_FLUTE":350,"ITEM_POMEG_BERRY":153,"ITEM_POTION":13,"ITEM_POWDER_JAR":372,"ITEM_PP_MAX":71,"ITEM_PP_UP":69,"ITEM_PREMIER_BALL":12,"ITEM_PROTEIN":64,"ITEM_QUALOT_BERRY":155,"ITEM_QUICK_CLAW":183,"ITEM_RABUTA_BERRY":161,"ITEM_RAINBOW_PASS":368,"ITEM_RARE_CANDY":68,"ITEM_RAWST_BERRY":136,"ITEM_RAZZ_BERRY":148,"ITEM_RED_FLUTE":41,"ITEM_RED_ORB":276,"ITEM_RED_SCARF":254,"ITEM_RED_SHARD":48,"ITEM_REPEAT_BALL":9,"ITEM_REPEL":86,"ITEM_RETRO_MAIL":132,"ITEM_REVIVAL_HERB":33,"ITEM_REVIVE":24,"ITEM_ROOM_1_KEY":281,"ITEM_ROOM_2_KEY":282,"ITEM_ROOM_4_KEY":283,"ITEM_ROOM_6_KEY":284,"ITEM_ROOT_FOSSIL":286,"ITEM_RUBY":373,"ITEM_SACRED_ASH":45,"ITEM_SAFARI_BALL":5,"ITEM_SALAC_BERRY":170,"ITEM_SAPPHIRE":374,"ITEM_SCANNER":278,"ITEM_SCOPE_LENS":198,"ITEM_SEA_INCENSE":220,"ITEM_SECRET_KEY":351,"ITEM_SHADOW_MAIL":128,"ITEM_SHARP_BEAK":210,"ITEM_SHELL_BELL":219,"ITEM_SHOAL_SALT":46,"ITEM_SHOAL_SHELL":47,"ITEM_SILK_SCARF":217,"ITEM_SILPH_SCOPE":359,"ITEM_SILVER_POWDER":188,"ITEM_SITRUS_BERRY":142,"ITEM_SMOKE_BALL":194,"ITEM_SODA_POP":27,"ITEM_SOFT_SAND":203,"ITEM_SOOTHE_BELL":184,"ITEM_SOOT_SACK":270,"ITEM_SOUL_DEW":191,"ITEM_SPELL_TAG":213,"ITEM_SPELON_BERRY":163,"ITEM_SS_TICKET":265,"ITEM_STARDUST":108,"ITEM_STARF_BERRY":174,"ITEM_STAR_PIECE":109,"ITEM_STICK":225,"ITEM_STORAGE_KEY":285,"ITEM_SUN_STONE":93,"ITEM_SUPER_POTION":22,"ITEM_SUPER_REPEL":83,"ITEM_SUPER_ROD":264,"ITEM_TAMATO_BERRY":158,"ITEM_TEA":369,"ITEM_TEACHY_TV":366,"ITEM_THICK_CLUB":224,"ITEM_THUNDER_STONE":96,"ITEM_TIMER_BALL":10,"ITEM_TINY_MUSHROOM":103,"ITEM_TM01":289,"ITEM_TM02":290,"ITEM_TM03":291,"ITEM_TM04":292,"ITEM_TM05":293,"ITEM_TM06":294,"ITEM_TM07":295,"ITEM_TM08":296,"ITEM_TM09":297,"ITEM_TM10":298,"ITEM_TM11":299,"ITEM_TM12":300,"ITEM_TM13":301,"ITEM_TM14":302,"ITEM_TM15":303,"ITEM_TM16":304,"ITEM_TM17":305,"ITEM_TM18":306,"ITEM_TM19":307,"ITEM_TM20":308,"ITEM_TM21":309,"ITEM_TM22":310,"ITEM_TM23":311,"ITEM_TM24":312,"ITEM_TM25":313,"ITEM_TM26":314,"ITEM_TM27":315,"ITEM_TM28":316,"ITEM_TM29":317,"ITEM_TM30":318,"ITEM_TM31":319,"ITEM_TM32":320,"ITEM_TM33":321,"ITEM_TM34":322,"ITEM_TM35":323,"ITEM_TM36":324,"ITEM_TM37":325,"ITEM_TM38":326,"ITEM_TM39":327,"ITEM_TM40":328,"ITEM_TM41":329,"ITEM_TM42":330,"ITEM_TM43":331,"ITEM_TM44":332,"ITEM_TM45":333,"ITEM_TM46":334,"ITEM_TM47":335,"ITEM_TM48":336,"ITEM_TM49":337,"ITEM_TM50":338,"ITEM_TM_AERIAL_ACE":328,"ITEM_TM_ATTRACT":333,"ITEM_TM_BLIZZARD":302,"ITEM_TM_BRICK_BREAK":319,"ITEM_TM_BULK_UP":296,"ITEM_TM_BULLET_SEED":297,"ITEM_TM_CALM_MIND":292,"ITEM_TM_CASE":364,"ITEM_TM_DIG":316,"ITEM_TM_DOUBLE_TEAM":320,"ITEM_TM_DRAGON_CLAW":290,"ITEM_TM_EARTHQUAKE":314,"ITEM_TM_FACADE":330,"ITEM_TM_FIRE_BLAST":326,"ITEM_TM_FLAMETHROWER":323,"ITEM_TM_FOCUS_PUNCH":289,"ITEM_TM_FRUSTRATION":309,"ITEM_TM_GIGA_DRAIN":307,"ITEM_TM_HAIL":295,"ITEM_TM_HIDDEN_POWER":298,"ITEM_TM_HYPER_BEAM":303,"ITEM_TM_ICE_BEAM":301,"ITEM_TM_IRON_TAIL":311,"ITEM_TM_LIGHT_SCREEN":304,"ITEM_TM_OVERHEAT":338,"ITEM_TM_PROTECT":305,"ITEM_TM_PSYCHIC":317,"ITEM_TM_RAIN_DANCE":306,"ITEM_TM_REFLECT":321,"ITEM_TM_REST":332,"ITEM_TM_RETURN":315,"ITEM_TM_ROAR":293,"ITEM_TM_ROCK_TOMB":327,"ITEM_TM_SAFEGUARD":308,"ITEM_TM_SANDSTORM":325,"ITEM_TM_SECRET_POWER":331,"ITEM_TM_SHADOW_BALL":318,"ITEM_TM_SHOCK_WAVE":322,"ITEM_TM_SKILL_SWAP":336,"ITEM_TM_SLUDGE_BOMB":324,"ITEM_TM_SNATCH":337,"ITEM_TM_SOLAR_BEAM":310,"ITEM_TM_STEEL_WING":335,"ITEM_TM_SUNNY_DAY":299,"ITEM_TM_TAUNT":300,"ITEM_TM_THIEF":334,"ITEM_TM_THUNDER":313,"ITEM_TM_THUNDERBOLT":312,"ITEM_TM_TORMENT":329,"ITEM_TM_TOXIC":294,"ITEM_TM_WATER_PULSE":291,"ITEM_TOWN_MAP":361,"ITEM_TRI_PASS":367,"ITEM_TROPIC_MAIL":129,"ITEM_TWISTED_SPOON":214,"ITEM_ULTRA_BALL":2,"ITEM_UNUSED_BERRY_1":176,"ITEM_UNUSED_BERRY_2":177,"ITEM_UNUSED_BERRY_3":178,"ITEM_UP_GRADE":218,"ITEM_USE_BAG_MENU":4,"ITEM_USE_FIELD":2,"ITEM_USE_MAIL":0,"ITEM_USE_PARTY_MENU":1,"ITEM_USE_PBLOCK_CASE":3,"ITEM_VS_SEEKER":362,"ITEM_WAILMER_PAIL":268,"ITEM_WATER_STONE":97,"ITEM_WATMEL_BERRY":165,"ITEM_WAVE_MAIL":126,"ITEM_WEPEAR_BERRY":151,"ITEM_WHITE_FLUTE":43,"ITEM_WHITE_HERB":180,"ITEM_WIKI_BERRY":144,"ITEM_WOOD_MAIL":125,"ITEM_X_ACCURACY":78,"ITEM_X_ATTACK":75,"ITEM_X_DEFEND":76,"ITEM_X_SPECIAL":79,"ITEM_X_SPEED":77,"ITEM_YELLOW_FLUTE":40,"ITEM_YELLOW_SCARF":258,"ITEM_YELLOW_SHARD":50,"ITEM_ZINC":70,"LAST_BALL":12,"LAST_BERRY_INDEX":175,"LAST_BERRY_MASTER_BERRY":162,"LAST_BERRY_MASTER_WIFE_BERRY":142,"LAST_KIRI_BERRY":162,"LAST_ROUTE_114_MAN_BERRY":152,"MACH_BIKE":0,"MAIL_NONE":255,"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":6207,"MAP_ABANDONED_SHIP_CORRIDORS_1F":6199,"MAP_ABANDONED_SHIP_CORRIDORS_B1F":6201,"MAP_ABANDONED_SHIP_DECK":6198,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":6209,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":6210,"MAP_ABANDONED_SHIP_ROOMS2_1F":6206,"MAP_ABANDONED_SHIP_ROOMS2_B1F":6203,"MAP_ABANDONED_SHIP_ROOMS_1F":6200,"MAP_ABANDONED_SHIP_ROOMS_B1F":6202,"MAP_ABANDONED_SHIP_ROOM_B1F":6205,"MAP_ABANDONED_SHIP_UNDERWATER1":6204,"MAP_ABANDONED_SHIP_UNDERWATER2":6208,"MAP_ALTERING_CAVE":6250,"MAP_ANCIENT_TOMB":6212,"MAP_AQUA_HIDEOUT_1F":6167,"MAP_AQUA_HIDEOUT_B1F":6168,"MAP_AQUA_HIDEOUT_B2F":6169,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":6218,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":6219,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":6220,"MAP_ARTISAN_CAVE_1F":6244,"MAP_ARTISAN_CAVE_B1F":6243,"MAP_BATTLE_COLOSSEUM_2P":6424,"MAP_BATTLE_COLOSSEUM_4P":6427,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":6686,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":6685,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":6684,"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":6677,"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":6675,"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":6674,"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":6676,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":6689,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":6687,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":6688,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":6680,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":6679,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":6678,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":6691,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":6690,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":6694,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":6693,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":6695,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":6692,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":6682,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":6681,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":6683,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":6664,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":6663,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":6662,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":6661,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":6673,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":6672,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":6671,"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":6698,"MAP_BATTLE_FRONTIER_LOUNGE1":6697,"MAP_BATTLE_FRONTIER_LOUNGE2":6699,"MAP_BATTLE_FRONTIER_LOUNGE3":6700,"MAP_BATTLE_FRONTIER_LOUNGE4":6701,"MAP_BATTLE_FRONTIER_LOUNGE5":6703,"MAP_BATTLE_FRONTIER_LOUNGE6":6704,"MAP_BATTLE_FRONTIER_LOUNGE7":6705,"MAP_BATTLE_FRONTIER_LOUNGE8":6707,"MAP_BATTLE_FRONTIER_LOUNGE9":6708,"MAP_BATTLE_FRONTIER_MART":6711,"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":6670,"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":6660,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":6709,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":6710,"MAP_BATTLE_FRONTIER_RANKING_HALL":6696,"MAP_BATTLE_FRONTIER_RECEPTION_GATE":6706,"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":6702,"MAP_BATTLE_PYRAMID_SQUARE01":6444,"MAP_BATTLE_PYRAMID_SQUARE02":6445,"MAP_BATTLE_PYRAMID_SQUARE03":6446,"MAP_BATTLE_PYRAMID_SQUARE04":6447,"MAP_BATTLE_PYRAMID_SQUARE05":6448,"MAP_BATTLE_PYRAMID_SQUARE06":6449,"MAP_BATTLE_PYRAMID_SQUARE07":6450,"MAP_BATTLE_PYRAMID_SQUARE08":6451,"MAP_BATTLE_PYRAMID_SQUARE09":6452,"MAP_BATTLE_PYRAMID_SQUARE10":6453,"MAP_BATTLE_PYRAMID_SQUARE11":6454,"MAP_BATTLE_PYRAMID_SQUARE12":6455,"MAP_BATTLE_PYRAMID_SQUARE13":6456,"MAP_BATTLE_PYRAMID_SQUARE14":6457,"MAP_BATTLE_PYRAMID_SQUARE15":6458,"MAP_BATTLE_PYRAMID_SQUARE16":6459,"MAP_BIRTH_ISLAND_EXTERIOR":6714,"MAP_BIRTH_ISLAND_HARBOR":6715,"MAP_CAVE_OF_ORIGIN_1F":6182,"MAP_CAVE_OF_ORIGIN_B1F":6186,"MAP_CAVE_OF_ORIGIN_ENTRANCE":6181,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":6183,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":6184,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":6185,"MAP_CONTEST_HALL":6428,"MAP_CONTEST_HALL_BEAUTY":6435,"MAP_CONTEST_HALL_COOL":6437,"MAP_CONTEST_HALL_CUTE":6439,"MAP_CONTEST_HALL_SMART":6438,"MAP_CONTEST_HALL_TOUGH":6436,"MAP_DESERT_RUINS":6150,"MAP_DESERT_UNDERPASS":6242,"MAP_DEWFORD_TOWN":11,"MAP_DEWFORD_TOWN_GYM":771,"MAP_DEWFORD_TOWN_HALL":772,"MAP_DEWFORD_TOWN_HOUSE1":768,"MAP_DEWFORD_TOWN_HOUSE2":773,"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":769,"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":770,"MAP_EVER_GRANDE_CITY":8,"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":4100,"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":4099,"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":4098,"MAP_EVER_GRANDE_CITY_HALL1":4101,"MAP_EVER_GRANDE_CITY_HALL2":4102,"MAP_EVER_GRANDE_CITY_HALL3":4103,"MAP_EVER_GRANDE_CITY_HALL4":4104,"MAP_EVER_GRANDE_CITY_HALL5":4105,"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":4107,"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":4097,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":4108,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":4109,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":4106,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":4110,"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":4096,"MAP_FALLARBOR_TOWN":13,"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":1283,"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":1282,"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":1281,"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":1286,"MAP_FALLARBOR_TOWN_MART":1280,"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":1287,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":1284,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":1285,"MAP_FARAWAY_ISLAND_ENTRANCE":6712,"MAP_FARAWAY_ISLAND_INTERIOR":6713,"MAP_FIERY_PATH":6158,"MAP_FORTREE_CITY":4,"MAP_FORTREE_CITY_DECORATION_SHOP":3081,"MAP_FORTREE_CITY_GYM":3073,"MAP_FORTREE_CITY_HOUSE1":3072,"MAP_FORTREE_CITY_HOUSE2":3077,"MAP_FORTREE_CITY_HOUSE3":3078,"MAP_FORTREE_CITY_HOUSE4":3079,"MAP_FORTREE_CITY_HOUSE5":3080,"MAP_FORTREE_CITY_MART":3076,"MAP_FORTREE_CITY_POKEMON_CENTER_1F":3074,"MAP_FORTREE_CITY_POKEMON_CENTER_2F":3075,"MAP_GRANITE_CAVE_1F":6151,"MAP_GRANITE_CAVE_B1F":6152,"MAP_GRANITE_CAVE_B2F":6153,"MAP_GRANITE_CAVE_STEVENS_ROOM":6154,"MAP_GROUPS_COUNT":34,"MAP_INSIDE_OF_TRUCK":6440,"MAP_ISLAND_CAVE":6211,"MAP_JAGGED_PASS":6157,"MAP_LAVARIDGE_TOWN":12,"MAP_LAVARIDGE_TOWN_GYM_1F":1025,"MAP_LAVARIDGE_TOWN_GYM_B1F":1026,"MAP_LAVARIDGE_TOWN_HERB_SHOP":1024,"MAP_LAVARIDGE_TOWN_HOUSE":1027,"MAP_LAVARIDGE_TOWN_MART":1028,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":1029,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":1030,"MAP_LILYCOVE_CITY":5,"MAP_LILYCOVE_CITY_CONTEST_HALL":3333,"MAP_LILYCOVE_CITY_CONTEST_LOBBY":3332,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":3328,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":3329,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":3344,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":3345,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":3346,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":3347,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":3348,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":3350,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":3349,"MAP_LILYCOVE_CITY_HARBOR":3338,"MAP_LILYCOVE_CITY_HOUSE1":3340,"MAP_LILYCOVE_CITY_HOUSE2":3341,"MAP_LILYCOVE_CITY_HOUSE3":3342,"MAP_LILYCOVE_CITY_HOUSE4":3343,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":3330,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":3331,"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":3339,"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":3334,"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":3335,"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":3337,"MAP_LILYCOVE_CITY_UNUSED_MART":3336,"MAP_LITTLEROOT_TOWN":9,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":256,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":257,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":258,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":259,"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":260,"MAP_MAGMA_HIDEOUT_1F":6230,"MAP_MAGMA_HIDEOUT_2F_1R":6231,"MAP_MAGMA_HIDEOUT_2F_2R":6232,"MAP_MAGMA_HIDEOUT_2F_3R":6237,"MAP_MAGMA_HIDEOUT_3F_1R":6233,"MAP_MAGMA_HIDEOUT_3F_2R":6234,"MAP_MAGMA_HIDEOUT_3F_3R":6236,"MAP_MAGMA_HIDEOUT_4F":6235,"MAP_MARINE_CAVE_END":6247,"MAP_MARINE_CAVE_ENTRANCE":6246,"MAP_MAUVILLE_CITY":2,"MAP_MAUVILLE_CITY_BIKE_SHOP":2561,"MAP_MAUVILLE_CITY_GAME_CORNER":2563,"MAP_MAUVILLE_CITY_GYM":2560,"MAP_MAUVILLE_CITY_HOUSE1":2562,"MAP_MAUVILLE_CITY_HOUSE2":2564,"MAP_MAUVILLE_CITY_MART":2567,"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":2565,"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":2566,"MAP_METEOR_FALLS_1F_1R":6144,"MAP_METEOR_FALLS_1F_2R":6145,"MAP_METEOR_FALLS_B1F_1R":6146,"MAP_METEOR_FALLS_B1F_2R":6147,"MAP_METEOR_FALLS_STEVENS_CAVE":6251,"MAP_MIRAGE_TOWER_1F":6238,"MAP_MIRAGE_TOWER_2F":6239,"MAP_MIRAGE_TOWER_3F":6240,"MAP_MIRAGE_TOWER_4F":6241,"MAP_MOSSDEEP_CITY":6,"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":3595,"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":3596,"MAP_MOSSDEEP_CITY_GYM":3584,"MAP_MOSSDEEP_CITY_HOUSE1":3585,"MAP_MOSSDEEP_CITY_HOUSE2":3586,"MAP_MOSSDEEP_CITY_HOUSE3":3590,"MAP_MOSSDEEP_CITY_HOUSE4":3592,"MAP_MOSSDEEP_CITY_MART":3589,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":3587,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":3588,"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":3593,"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":3594,"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":3591,"MAP_MT_CHIMNEY":6156,"MAP_MT_CHIMNEY_CABLE_CAR_STATION":4865,"MAP_MT_PYRE_1F":6159,"MAP_MT_PYRE_2F":6160,"MAP_MT_PYRE_3F":6161,"MAP_MT_PYRE_4F":6162,"MAP_MT_PYRE_5F":6163,"MAP_MT_PYRE_6F":6164,"MAP_MT_PYRE_EXTERIOR":6165,"MAP_MT_PYRE_SUMMIT":6166,"MAP_NAVEL_ROCK_B1F":6725,"MAP_NAVEL_ROCK_BOTTOM":6743,"MAP_NAVEL_ROCK_DOWN01":6732,"MAP_NAVEL_ROCK_DOWN02":6733,"MAP_NAVEL_ROCK_DOWN03":6734,"MAP_NAVEL_ROCK_DOWN04":6735,"MAP_NAVEL_ROCK_DOWN05":6736,"MAP_NAVEL_ROCK_DOWN06":6737,"MAP_NAVEL_ROCK_DOWN07":6738,"MAP_NAVEL_ROCK_DOWN08":6739,"MAP_NAVEL_ROCK_DOWN09":6740,"MAP_NAVEL_ROCK_DOWN10":6741,"MAP_NAVEL_ROCK_DOWN11":6742,"MAP_NAVEL_ROCK_ENTRANCE":6724,"MAP_NAVEL_ROCK_EXTERIOR":6722,"MAP_NAVEL_ROCK_FORK":6726,"MAP_NAVEL_ROCK_HARBOR":6723,"MAP_NAVEL_ROCK_TOP":6731,"MAP_NAVEL_ROCK_UP1":6727,"MAP_NAVEL_ROCK_UP2":6728,"MAP_NAVEL_ROCK_UP3":6729,"MAP_NAVEL_ROCK_UP4":6730,"MAP_NEW_MAUVILLE_ENTRANCE":6196,"MAP_NEW_MAUVILLE_INSIDE":6197,"MAP_OLDALE_TOWN":10,"MAP_OLDALE_TOWN_HOUSE1":512,"MAP_OLDALE_TOWN_HOUSE2":513,"MAP_OLDALE_TOWN_MART":516,"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":514,"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":515,"MAP_PACIFIDLOG_TOWN":15,"MAP_PACIFIDLOG_TOWN_HOUSE1":1794,"MAP_PACIFIDLOG_TOWN_HOUSE2":1795,"MAP_PACIFIDLOG_TOWN_HOUSE3":1796,"MAP_PACIFIDLOG_TOWN_HOUSE4":1797,"MAP_PACIFIDLOG_TOWN_HOUSE5":1798,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":1792,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":1793,"MAP_PETALBURG_CITY":0,"MAP_PETALBURG_CITY_GYM":2049,"MAP_PETALBURG_CITY_HOUSE1":2050,"MAP_PETALBURG_CITY_HOUSE2":2051,"MAP_PETALBURG_CITY_MART":2054,"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":2052,"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":2053,"MAP_PETALBURG_CITY_WALLYS_HOUSE":2048,"MAP_PETALBURG_WOODS":6155,"MAP_RECORD_CORNER":6426,"MAP_ROUTE101":16,"MAP_ROUTE102":17,"MAP_ROUTE103":18,"MAP_ROUTE104":19,"MAP_ROUTE104_MR_BRINEYS_HOUSE":4352,"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":4353,"MAP_ROUTE104_PROTOTYPE":6912,"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":6913,"MAP_ROUTE105":20,"MAP_ROUTE106":21,"MAP_ROUTE107":22,"MAP_ROUTE108":23,"MAP_ROUTE109":24,"MAP_ROUTE109_SEASHORE_HOUSE":7168,"MAP_ROUTE110":25,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":7435,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":7436,"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":7426,"MAP_ROUTE110_TRICK_HOUSE_END":7425,"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":7424,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":7427,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":7428,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":7429,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":7430,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":7431,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":7432,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":7433,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":7434,"MAP_ROUTE111":26,"MAP_ROUTE111_OLD_LADYS_REST_STOP":4609,"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":4608,"MAP_ROUTE112":27,"MAP_ROUTE112_CABLE_CAR_STATION":4864,"MAP_ROUTE113":28,"MAP_ROUTE113_GLASS_WORKSHOP":7680,"MAP_ROUTE114":29,"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":5120,"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":5121,"MAP_ROUTE114_LANETTES_HOUSE":5122,"MAP_ROUTE115":30,"MAP_ROUTE116":31,"MAP_ROUTE116_TUNNELERS_REST_HOUSE":5376,"MAP_ROUTE117":32,"MAP_ROUTE117_POKEMON_DAY_CARE":5632,"MAP_ROUTE118":33,"MAP_ROUTE119":34,"MAP_ROUTE119_HOUSE":8194,"MAP_ROUTE119_WEATHER_INSTITUTE_1F":8192,"MAP_ROUTE119_WEATHER_INSTITUTE_2F":8193,"MAP_ROUTE120":35,"MAP_ROUTE121":36,"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":5888,"MAP_ROUTE122":37,"MAP_ROUTE123":38,"MAP_ROUTE123_BERRY_MASTERS_HOUSE":7936,"MAP_ROUTE124":39,"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":8448,"MAP_ROUTE125":40,"MAP_ROUTE126":41,"MAP_ROUTE127":42,"MAP_ROUTE128":43,"MAP_ROUTE129":44,"MAP_ROUTE130":45,"MAP_ROUTE131":46,"MAP_ROUTE132":47,"MAP_ROUTE133":48,"MAP_ROUTE134":49,"MAP_RUSTBORO_CITY":3,"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":2827,"MAP_RUSTBORO_CITY_DEVON_CORP_1F":2816,"MAP_RUSTBORO_CITY_DEVON_CORP_2F":2817,"MAP_RUSTBORO_CITY_DEVON_CORP_3F":2818,"MAP_RUSTBORO_CITY_FLAT1_1F":2824,"MAP_RUSTBORO_CITY_FLAT1_2F":2825,"MAP_RUSTBORO_CITY_FLAT2_1F":2829,"MAP_RUSTBORO_CITY_FLAT2_2F":2830,"MAP_RUSTBORO_CITY_FLAT2_3F":2831,"MAP_RUSTBORO_CITY_GYM":2819,"MAP_RUSTBORO_CITY_HOUSE1":2826,"MAP_RUSTBORO_CITY_HOUSE2":2828,"MAP_RUSTBORO_CITY_HOUSE3":2832,"MAP_RUSTBORO_CITY_MART":2823,"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":2821,"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":2822,"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":2820,"MAP_RUSTURF_TUNNEL":6148,"MAP_SAFARI_ZONE_NORTH":6657,"MAP_SAFARI_ZONE_NORTHEAST":6668,"MAP_SAFARI_ZONE_NORTHWEST":6656,"MAP_SAFARI_ZONE_REST_HOUSE":6667,"MAP_SAFARI_ZONE_SOUTH":6659,"MAP_SAFARI_ZONE_SOUTHEAST":6669,"MAP_SAFARI_ZONE_SOUTHWEST":6658,"MAP_SCORCHED_SLAB":6217,"MAP_SEAFLOOR_CAVERN_ENTRANCE":6171,"MAP_SEAFLOOR_CAVERN_ROOM1":6172,"MAP_SEAFLOOR_CAVERN_ROOM2":6173,"MAP_SEAFLOOR_CAVERN_ROOM3":6174,"MAP_SEAFLOOR_CAVERN_ROOM4":6175,"MAP_SEAFLOOR_CAVERN_ROOM5":6176,"MAP_SEAFLOOR_CAVERN_ROOM6":6177,"MAP_SEAFLOOR_CAVERN_ROOM7":6178,"MAP_SEAFLOOR_CAVERN_ROOM8":6179,"MAP_SEAFLOOR_CAVERN_ROOM9":6180,"MAP_SEALED_CHAMBER_INNER_ROOM":6216,"MAP_SEALED_CHAMBER_OUTER_ROOM":6215,"MAP_SECRET_BASE_BLUE_CAVE1":6402,"MAP_SECRET_BASE_BLUE_CAVE2":6408,"MAP_SECRET_BASE_BLUE_CAVE3":6414,"MAP_SECRET_BASE_BLUE_CAVE4":6420,"MAP_SECRET_BASE_BROWN_CAVE1":6401,"MAP_SECRET_BASE_BROWN_CAVE2":6407,"MAP_SECRET_BASE_BROWN_CAVE3":6413,"MAP_SECRET_BASE_BROWN_CAVE4":6419,"MAP_SECRET_BASE_RED_CAVE1":6400,"MAP_SECRET_BASE_RED_CAVE2":6406,"MAP_SECRET_BASE_RED_CAVE3":6412,"MAP_SECRET_BASE_RED_CAVE4":6418,"MAP_SECRET_BASE_SHRUB1":6405,"MAP_SECRET_BASE_SHRUB2":6411,"MAP_SECRET_BASE_SHRUB3":6417,"MAP_SECRET_BASE_SHRUB4":6423,"MAP_SECRET_BASE_TREE1":6404,"MAP_SECRET_BASE_TREE2":6410,"MAP_SECRET_BASE_TREE3":6416,"MAP_SECRET_BASE_TREE4":6422,"MAP_SECRET_BASE_YELLOW_CAVE1":6403,"MAP_SECRET_BASE_YELLOW_CAVE2":6409,"MAP_SECRET_BASE_YELLOW_CAVE3":6415,"MAP_SECRET_BASE_YELLOW_CAVE4":6421,"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":6194,"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":6195,"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":6190,"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":6227,"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":6191,"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":6193,"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":6192,"MAP_SKY_PILLAR_1F":6223,"MAP_SKY_PILLAR_2F":6224,"MAP_SKY_PILLAR_3F":6225,"MAP_SKY_PILLAR_4F":6226,"MAP_SKY_PILLAR_5F":6228,"MAP_SKY_PILLAR_ENTRANCE":6221,"MAP_SKY_PILLAR_OUTSIDE":6222,"MAP_SKY_PILLAR_TOP":6229,"MAP_SLATEPORT_CITY":1,"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":2308,"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":2307,"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":2306,"MAP_SLATEPORT_CITY_HARBOR":2313,"MAP_SLATEPORT_CITY_HOUSE":2314,"MAP_SLATEPORT_CITY_MART":2317,"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":2309,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":2311,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":2312,"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":2315,"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":2316,"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":2310,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":2304,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":2305,"MAP_SOOTOPOLIS_CITY":7,"MAP_SOOTOPOLIS_CITY_GYM_1F":3840,"MAP_SOOTOPOLIS_CITY_GYM_B1F":3841,"MAP_SOOTOPOLIS_CITY_HOUSE1":3845,"MAP_SOOTOPOLIS_CITY_HOUSE2":3846,"MAP_SOOTOPOLIS_CITY_HOUSE3":3847,"MAP_SOOTOPOLIS_CITY_HOUSE4":3848,"MAP_SOOTOPOLIS_CITY_HOUSE5":3849,"MAP_SOOTOPOLIS_CITY_HOUSE6":3850,"MAP_SOOTOPOLIS_CITY_HOUSE7":3851,"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":3852,"MAP_SOOTOPOLIS_CITY_MART":3844,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":3853,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":3854,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":3842,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":3843,"MAP_SOUTHERN_ISLAND_EXTERIOR":6665,"MAP_SOUTHERN_ISLAND_INTERIOR":6666,"MAP_SS_TIDAL_CORRIDOR":6441,"MAP_SS_TIDAL_LOWER_DECK":6442,"MAP_SS_TIDAL_ROOMS":6443,"MAP_TERRA_CAVE_END":6249,"MAP_TERRA_CAVE_ENTRANCE":6248,"MAP_TRADE_CENTER":6425,"MAP_TRAINER_HILL_1F":6717,"MAP_TRAINER_HILL_2F":6718,"MAP_TRAINER_HILL_3F":6719,"MAP_TRAINER_HILL_4F":6720,"MAP_TRAINER_HILL_ELEVATOR":6744,"MAP_TRAINER_HILL_ENTRANCE":6716,"MAP_TRAINER_HILL_ROOF":6721,"MAP_UNDERWATER_MARINE_CAVE":6245,"MAP_UNDERWATER_ROUTE105":55,"MAP_UNDERWATER_ROUTE124":50,"MAP_UNDERWATER_ROUTE125":56,"MAP_UNDERWATER_ROUTE126":51,"MAP_UNDERWATER_ROUTE127":52,"MAP_UNDERWATER_ROUTE128":53,"MAP_UNDERWATER_ROUTE129":54,"MAP_UNDERWATER_ROUTE134":6213,"MAP_UNDERWATER_SEAFLOOR_CAVERN":6170,"MAP_UNDERWATER_SEALED_CHAMBER":6214,"MAP_UNDERWATER_SOOTOPOLIS_CITY":6149,"MAP_UNION_ROOM":6460,"MAP_UNUSED_CONTEST_HALL1":6429,"MAP_UNUSED_CONTEST_HALL2":6430,"MAP_UNUSED_CONTEST_HALL3":6431,"MAP_UNUSED_CONTEST_HALL4":6432,"MAP_UNUSED_CONTEST_HALL5":6433,"MAP_UNUSED_CONTEST_HALL6":6434,"MAP_VERDANTURF_TOWN":14,"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":1538,"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":1537,"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":1536,"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":1543,"MAP_VERDANTURF_TOWN_HOUSE":1544,"MAP_VERDANTURF_TOWN_MART":1539,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":1540,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":1541,"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":1542,"MAP_VICTORY_ROAD_1F":6187,"MAP_VICTORY_ROAD_B1F":6188,"MAP_VICTORY_ROAD_B2F":6189,"MAX_BAG_ITEM_CAPACITY":99,"MAX_BERRY_CAPACITY":999,"MAX_BERRY_INDEX":178,"MAX_ITEM_DIGITS":3,"MAX_PC_ITEM_CAPACITY":999,"MAX_TRAINERS_COUNT":864,"MOVES_COUNT":355,"MOVE_ABSORB":71,"MOVE_ACID":51,"MOVE_ACID_ARMOR":151,"MOVE_AERIAL_ACE":332,"MOVE_AEROBLAST":177,"MOVE_AGILITY":97,"MOVE_AIR_CUTTER":314,"MOVE_AMNESIA":133,"MOVE_ANCIENT_POWER":246,"MOVE_ARM_THRUST":292,"MOVE_AROMATHERAPY":312,"MOVE_ASSIST":274,"MOVE_ASTONISH":310,"MOVE_ATTRACT":213,"MOVE_AURORA_BEAM":62,"MOVE_BARRAGE":140,"MOVE_BARRIER":112,"MOVE_BATON_PASS":226,"MOVE_BEAT_UP":251,"MOVE_BELLY_DRUM":187,"MOVE_BIDE":117,"MOVE_BIND":20,"MOVE_BITE":44,"MOVE_BLAST_BURN":307,"MOVE_BLAZE_KICK":299,"MOVE_BLIZZARD":59,"MOVE_BLOCK":335,"MOVE_BODY_SLAM":34,"MOVE_BONEMERANG":155,"MOVE_BONE_CLUB":125,"MOVE_BONE_RUSH":198,"MOVE_BOUNCE":340,"MOVE_BRICK_BREAK":280,"MOVE_BUBBLE":145,"MOVE_BUBBLE_BEAM":61,"MOVE_BULK_UP":339,"MOVE_BULLET_SEED":331,"MOVE_CALM_MIND":347,"MOVE_CAMOUFLAGE":293,"MOVE_CHARGE":268,"MOVE_CHARM":204,"MOVE_CLAMP":128,"MOVE_COMET_PUNCH":4,"MOVE_CONFUSE_RAY":109,"MOVE_CONFUSION":93,"MOVE_CONSTRICT":132,"MOVE_CONVERSION":160,"MOVE_CONVERSION_2":176,"MOVE_COSMIC_POWER":322,"MOVE_COTTON_SPORE":178,"MOVE_COUNTER":68,"MOVE_COVET":343,"MOVE_CRABHAMMER":152,"MOVE_CROSS_CHOP":238,"MOVE_CRUNCH":242,"MOVE_CRUSH_CLAW":306,"MOVE_CURSE":174,"MOVE_CUT":15,"MOVE_DEFENSE_CURL":111,"MOVE_DESTINY_BOND":194,"MOVE_DETECT":197,"MOVE_DIG":91,"MOVE_DISABLE":50,"MOVE_DIVE":291,"MOVE_DIZZY_PUNCH":146,"MOVE_DOOM_DESIRE":353,"MOVE_DOUBLE_EDGE":38,"MOVE_DOUBLE_KICK":24,"MOVE_DOUBLE_SLAP":3,"MOVE_DOUBLE_TEAM":104,"MOVE_DRAGON_BREATH":225,"MOVE_DRAGON_CLAW":337,"MOVE_DRAGON_DANCE":349,"MOVE_DRAGON_RAGE":82,"MOVE_DREAM_EATER":138,"MOVE_DRILL_PECK":65,"MOVE_DYNAMIC_PUNCH":223,"MOVE_EARTHQUAKE":89,"MOVE_EGG_BOMB":121,"MOVE_EMBER":52,"MOVE_ENCORE":227,"MOVE_ENDEAVOR":283,"MOVE_ENDURE":203,"MOVE_ERUPTION":284,"MOVE_EXPLOSION":153,"MOVE_EXTRASENSORY":326,"MOVE_EXTREME_SPEED":245,"MOVE_FACADE":263,"MOVE_FAINT_ATTACK":185,"MOVE_FAKE_OUT":252,"MOVE_FAKE_TEARS":313,"MOVE_FALSE_SWIPE":206,"MOVE_FEATHER_DANCE":297,"MOVE_FIRE_BLAST":126,"MOVE_FIRE_PUNCH":7,"MOVE_FIRE_SPIN":83,"MOVE_FISSURE":90,"MOVE_FLAIL":175,"MOVE_FLAMETHROWER":53,"MOVE_FLAME_WHEEL":172,"MOVE_FLASH":148,"MOVE_FLATTER":260,"MOVE_FLY":19,"MOVE_FOCUS_ENERGY":116,"MOVE_FOCUS_PUNCH":264,"MOVE_FOLLOW_ME":266,"MOVE_FORESIGHT":193,"MOVE_FRENZY_PLANT":338,"MOVE_FRUSTRATION":218,"MOVE_FURY_ATTACK":31,"MOVE_FURY_CUTTER":210,"MOVE_FURY_SWIPES":154,"MOVE_FUTURE_SIGHT":248,"MOVE_GIGA_DRAIN":202,"MOVE_GLARE":137,"MOVE_GRASS_WHISTLE":320,"MOVE_GROWL":45,"MOVE_GROWTH":74,"MOVE_GRUDGE":288,"MOVE_GUILLOTINE":12,"MOVE_GUST":16,"MOVE_HAIL":258,"MOVE_HARDEN":106,"MOVE_HAZE":114,"MOVE_HEADBUTT":29,"MOVE_HEAL_BELL":215,"MOVE_HEAT_WAVE":257,"MOVE_HELPING_HAND":270,"MOVE_HIDDEN_POWER":237,"MOVE_HI_JUMP_KICK":136,"MOVE_HORN_ATTACK":30,"MOVE_HORN_DRILL":32,"MOVE_HOWL":336,"MOVE_HYDRO_CANNON":308,"MOVE_HYDRO_PUMP":56,"MOVE_HYPER_BEAM":63,"MOVE_HYPER_FANG":158,"MOVE_HYPER_VOICE":304,"MOVE_HYPNOSIS":95,"MOVE_ICE_BALL":301,"MOVE_ICE_BEAM":58,"MOVE_ICE_PUNCH":8,"MOVE_ICICLE_SPEAR":333,"MOVE_ICY_WIND":196,"MOVE_IMPRISON":286,"MOVE_INGRAIN":275,"MOVE_IRON_DEFENSE":334,"MOVE_IRON_TAIL":231,"MOVE_JUMP_KICK":26,"MOVE_KARATE_CHOP":2,"MOVE_KINESIS":134,"MOVE_KNOCK_OFF":282,"MOVE_LEAF_BLADE":348,"MOVE_LEECH_LIFE":141,"MOVE_LEECH_SEED":73,"MOVE_LEER":43,"MOVE_LICK":122,"MOVE_LIGHT_SCREEN":113,"MOVE_LOCK_ON":199,"MOVE_LOVELY_KISS":142,"MOVE_LOW_KICK":67,"MOVE_LUSTER_PURGE":295,"MOVE_MACH_PUNCH":183,"MOVE_MAGICAL_LEAF":345,"MOVE_MAGIC_COAT":277,"MOVE_MAGNITUDE":222,"MOVE_MEAN_LOOK":212,"MOVE_MEDITATE":96,"MOVE_MEGAHORN":224,"MOVE_MEGA_DRAIN":72,"MOVE_MEGA_KICK":25,"MOVE_MEGA_PUNCH":5,"MOVE_MEMENTO":262,"MOVE_METAL_CLAW":232,"MOVE_METAL_SOUND":319,"MOVE_METEOR_MASH":309,"MOVE_METRONOME":118,"MOVE_MILK_DRINK":208,"MOVE_MIMIC":102,"MOVE_MIND_READER":170,"MOVE_MINIMIZE":107,"MOVE_MIRROR_COAT":243,"MOVE_MIRROR_MOVE":119,"MOVE_MIST":54,"MOVE_MIST_BALL":296,"MOVE_MOONLIGHT":236,"MOVE_MORNING_SUN":234,"MOVE_MUDDY_WATER":330,"MOVE_MUD_SHOT":341,"MOVE_MUD_SLAP":189,"MOVE_MUD_SPORT":300,"MOVE_NATURE_POWER":267,"MOVE_NEEDLE_ARM":302,"MOVE_NIGHTMARE":171,"MOVE_NIGHT_SHADE":101,"MOVE_NONE":0,"MOVE_OCTAZOOKA":190,"MOVE_ODOR_SLEUTH":316,"MOVE_OUTRAGE":200,"MOVE_OVERHEAT":315,"MOVE_PAIN_SPLIT":220,"MOVE_PAY_DAY":6,"MOVE_PECK":64,"MOVE_PERISH_SONG":195,"MOVE_PETAL_DANCE":80,"MOVE_PIN_MISSILE":42,"MOVE_POISON_FANG":305,"MOVE_POISON_GAS":139,"MOVE_POISON_POWDER":77,"MOVE_POISON_STING":40,"MOVE_POISON_TAIL":342,"MOVE_POUND":1,"MOVE_POWDER_SNOW":181,"MOVE_PRESENT":217,"MOVE_PROTECT":182,"MOVE_PSYBEAM":60,"MOVE_PSYCHIC":94,"MOVE_PSYCHO_BOOST":354,"MOVE_PSYCH_UP":244,"MOVE_PSYWAVE":149,"MOVE_PURSUIT":228,"MOVE_QUICK_ATTACK":98,"MOVE_RAGE":99,"MOVE_RAIN_DANCE":240,"MOVE_RAPID_SPIN":229,"MOVE_RAZOR_LEAF":75,"MOVE_RAZOR_WIND":13,"MOVE_RECOVER":105,"MOVE_RECYCLE":278,"MOVE_REFLECT":115,"MOVE_REFRESH":287,"MOVE_REST":156,"MOVE_RETURN":216,"MOVE_REVENGE":279,"MOVE_REVERSAL":179,"MOVE_ROAR":46,"MOVE_ROCK_BLAST":350,"MOVE_ROCK_SLIDE":157,"MOVE_ROCK_SMASH":249,"MOVE_ROCK_THROW":88,"MOVE_ROCK_TOMB":317,"MOVE_ROLE_PLAY":272,"MOVE_ROLLING_KICK":27,"MOVE_ROLLOUT":205,"MOVE_SACRED_FIRE":221,"MOVE_SAFEGUARD":219,"MOVE_SANDSTORM":201,"MOVE_SAND_ATTACK":28,"MOVE_SAND_TOMB":328,"MOVE_SCARY_FACE":184,"MOVE_SCRATCH":10,"MOVE_SCREECH":103,"MOVE_SECRET_POWER":290,"MOVE_SEISMIC_TOSS":69,"MOVE_SELF_DESTRUCT":120,"MOVE_SHADOW_BALL":247,"MOVE_SHADOW_PUNCH":325,"MOVE_SHARPEN":159,"MOVE_SHEER_COLD":329,"MOVE_SHOCK_WAVE":351,"MOVE_SIGNAL_BEAM":324,"MOVE_SILVER_WIND":318,"MOVE_SING":47,"MOVE_SKETCH":166,"MOVE_SKILL_SWAP":285,"MOVE_SKULL_BASH":130,"MOVE_SKY_ATTACK":143,"MOVE_SKY_UPPERCUT":327,"MOVE_SLACK_OFF":303,"MOVE_SLAM":21,"MOVE_SLASH":163,"MOVE_SLEEP_POWDER":79,"MOVE_SLEEP_TALK":214,"MOVE_SLUDGE":124,"MOVE_SLUDGE_BOMB":188,"MOVE_SMELLING_SALT":265,"MOVE_SMOG":123,"MOVE_SMOKESCREEN":108,"MOVE_SNATCH":289,"MOVE_SNORE":173,"MOVE_SOFT_BOILED":135,"MOVE_SOLAR_BEAM":76,"MOVE_SONIC_BOOM":49,"MOVE_SPARK":209,"MOVE_SPIDER_WEB":169,"MOVE_SPIKES":191,"MOVE_SPIKE_CANNON":131,"MOVE_SPITE":180,"MOVE_SPIT_UP":255,"MOVE_SPLASH":150,"MOVE_SPORE":147,"MOVE_STEEL_WING":211,"MOVE_STOCKPILE":254,"MOVE_STOMP":23,"MOVE_STRENGTH":70,"MOVE_STRING_SHOT":81,"MOVE_STRUGGLE":165,"MOVE_STUN_SPORE":78,"MOVE_SUBMISSION":66,"MOVE_SUBSTITUTE":164,"MOVE_SUNNY_DAY":241,"MOVE_SUPERPOWER":276,"MOVE_SUPERSONIC":48,"MOVE_SUPER_FANG":162,"MOVE_SURF":57,"MOVE_SWAGGER":207,"MOVE_SWALLOW":256,"MOVE_SWEET_KISS":186,"MOVE_SWEET_SCENT":230,"MOVE_SWIFT":129,"MOVE_SWORDS_DANCE":14,"MOVE_SYNTHESIS":235,"MOVE_TACKLE":33,"MOVE_TAIL_GLOW":294,"MOVE_TAIL_WHIP":39,"MOVE_TAKE_DOWN":36,"MOVE_TAUNT":269,"MOVE_TEETER_DANCE":298,"MOVE_TELEPORT":100,"MOVE_THIEF":168,"MOVE_THRASH":37,"MOVE_THUNDER":87,"MOVE_THUNDERBOLT":85,"MOVE_THUNDER_PUNCH":9,"MOVE_THUNDER_SHOCK":84,"MOVE_THUNDER_WAVE":86,"MOVE_TICKLE":321,"MOVE_TORMENT":259,"MOVE_TOXIC":92,"MOVE_TRANSFORM":144,"MOVE_TRICK":271,"MOVE_TRIPLE_KICK":167,"MOVE_TRI_ATTACK":161,"MOVE_TWINEEDLE":41,"MOVE_TWISTER":239,"MOVE_UNAVAILABLE":65535,"MOVE_UPROAR":253,"MOVE_VICE_GRIP":11,"MOVE_VINE_WHIP":22,"MOVE_VITAL_THROW":233,"MOVE_VOLT_TACKLE":344,"MOVE_WATERFALL":127,"MOVE_WATER_GUN":55,"MOVE_WATER_PULSE":352,"MOVE_WATER_SPORT":346,"MOVE_WATER_SPOUT":323,"MOVE_WEATHER_BALL":311,"MOVE_WHIRLPOOL":250,"MOVE_WHIRLWIND":18,"MOVE_WILL_O_WISP":261,"MOVE_WING_ATTACK":17,"MOVE_WISH":273,"MOVE_WITHDRAW":110,"MOVE_WRAP":35,"MOVE_YAWN":281,"MOVE_ZAP_CANNON":192,"MUS_ABANDONED_SHIP":381,"MUS_ABNORMAL_WEATHER":443,"MUS_AQUA_MAGMA_HIDEOUT":430,"MUS_AWAKEN_LEGEND":388,"MUS_BIRCH_LAB":383,"MUS_B_ARENA":458,"MUS_B_DOME":467,"MUS_B_DOME_LOBBY":473,"MUS_B_FACTORY":469,"MUS_B_FRONTIER":457,"MUS_B_PALACE":463,"MUS_B_PIKE":468,"MUS_B_PYRAMID":461,"MUS_B_PYRAMID_TOP":462,"MUS_B_TOWER":465,"MUS_B_TOWER_RS":384,"MUS_CABLE_CAR":425,"MUS_CAUGHT":352,"MUS_CAVE_OF_ORIGIN":386,"MUS_CONTEST":440,"MUS_CONTEST_LOBBY":452,"MUS_CONTEST_RESULTS":446,"MUS_CONTEST_WINNER":439,"MUS_CREDITS":455,"MUS_CYCLING":403,"MUS_C_COMM_CENTER":356,"MUS_C_VS_LEGEND_BEAST":358,"MUS_DESERT":409,"MUS_DEWFORD":427,"MUS_DUMMY":0,"MUS_ENCOUNTER_AQUA":419,"MUS_ENCOUNTER_BRENDAN":421,"MUS_ENCOUNTER_CHAMPION":454,"MUS_ENCOUNTER_COOL":417,"MUS_ENCOUNTER_ELITE_FOUR":450,"MUS_ENCOUNTER_FEMALE":407,"MUS_ENCOUNTER_GIRL":379,"MUS_ENCOUNTER_HIKER":451,"MUS_ENCOUNTER_INTENSE":416,"MUS_ENCOUNTER_INTERVIEWER":453,"MUS_ENCOUNTER_MAGMA":441,"MUS_ENCOUNTER_MALE":380,"MUS_ENCOUNTER_MAY":415,"MUS_ENCOUNTER_RICH":397,"MUS_ENCOUNTER_SUSPICIOUS":423,"MUS_ENCOUNTER_SWIMMER":385,"MUS_ENCOUNTER_TWINS":449,"MUS_END":456,"MUS_EVER_GRANDE":422,"MUS_EVOLUTION":377,"MUS_EVOLUTION_INTRO":376,"MUS_EVOLVED":371,"MUS_FALLARBOR":437,"MUS_FOLLOW_ME":420,"MUS_FORTREE":382,"MUS_GAME_CORNER":426,"MUS_GSC_PEWTER":357,"MUS_GSC_ROUTE38":351,"MUS_GYM":364,"MUS_HALL_OF_FAME":436,"MUS_HALL_OF_FAME_ROOM":447,"MUS_HEAL":368,"MUS_HELP":410,"MUS_INTRO":414,"MUS_INTRO_BATTLE":442,"MUS_LEVEL_UP":367,"MUS_LILYCOVE":408,"MUS_LILYCOVE_MUSEUM":373,"MUS_LINK_CONTEST_P1":393,"MUS_LINK_CONTEST_P2":394,"MUS_LINK_CONTEST_P3":395,"MUS_LINK_CONTEST_P4":396,"MUS_LITTLEROOT":405,"MUS_LITTLEROOT_TEST":350,"MUS_MOVE_DELETED":378,"MUS_MT_CHIMNEY":406,"MUS_MT_PYRE":432,"MUS_MT_PYRE_EXTERIOR":434,"MUS_NONE":65535,"MUS_OBTAIN_BADGE":369,"MUS_OBTAIN_BERRY":387,"MUS_OBTAIN_B_POINTS":459,"MUS_OBTAIN_ITEM":370,"MUS_OBTAIN_SYMBOL":466,"MUS_OBTAIN_TMHM":372,"MUS_OCEANIC_MUSEUM":375,"MUS_OLDALE":363,"MUS_PETALBURG":362,"MUS_PETALBURG_WOODS":366,"MUS_POKE_CENTER":400,"MUS_POKE_MART":404,"MUS_RAYQUAZA_APPEARS":464,"MUS_REGISTER_MATCH_CALL":460,"MUS_RG_BERRY_PICK":542,"MUS_RG_CAUGHT":534,"MUS_RG_CAUGHT_INTRO":531,"MUS_RG_CELADON":521,"MUS_RG_CINNABAR":491,"MUS_RG_CREDITS":502,"MUS_RG_CYCLING":494,"MUS_RG_DEX_RATING":529,"MUS_RG_ENCOUNTER_BOY":497,"MUS_RG_ENCOUNTER_DEOXYS":555,"MUS_RG_ENCOUNTER_GIRL":496,"MUS_RG_ENCOUNTER_GYM_LEADER":554,"MUS_RG_ENCOUNTER_RIVAL":527,"MUS_RG_ENCOUNTER_ROCKET":495,"MUS_RG_FOLLOW_ME":484,"MUS_RG_FUCHSIA":520,"MUS_RG_GAME_CORNER":485,"MUS_RG_GAME_FREAK":533,"MUS_RG_GYM":487,"MUS_RG_HALL_OF_FAME":498,"MUS_RG_HEAL":493,"MUS_RG_INTRO_FIGHT":489,"MUS_RG_JIGGLYPUFF":488,"MUS_RG_LAVENDER":492,"MUS_RG_MT_MOON":500,"MUS_RG_MYSTERY_GIFT":541,"MUS_RG_NET_CENTER":540,"MUS_RG_NEW_GAME_EXIT":537,"MUS_RG_NEW_GAME_INSTRUCT":535,"MUS_RG_NEW_GAME_INTRO":536,"MUS_RG_OAK":514,"MUS_RG_OAK_LAB":513,"MUS_RG_OBTAIN_KEY_ITEM":530,"MUS_RG_PALLET":512,"MUS_RG_PEWTER":526,"MUS_RG_PHOTO":532,"MUS_RG_POKE_CENTER":515,"MUS_RG_POKE_FLUTE":550,"MUS_RG_POKE_JUMP":538,"MUS_RG_POKE_MANSION":501,"MUS_RG_POKE_TOWER":518,"MUS_RG_RIVAL_EXIT":528,"MUS_RG_ROCKET_HIDEOUT":486,"MUS_RG_ROUTE1":503,"MUS_RG_ROUTE11":506,"MUS_RG_ROUTE24":504,"MUS_RG_ROUTE3":505,"MUS_RG_SEVII_123":547,"MUS_RG_SEVII_45":548,"MUS_RG_SEVII_67":549,"MUS_RG_SEVII_CAVE":543,"MUS_RG_SEVII_DUNGEON":546,"MUS_RG_SEVII_ROUTE":545,"MUS_RG_SILPH":519,"MUS_RG_SLOW_PALLET":557,"MUS_RG_SS_ANNE":516,"MUS_RG_SURF":517,"MUS_RG_TEACHY_TV_MENU":558,"MUS_RG_TEACHY_TV_SHOW":544,"MUS_RG_TITLE":490,"MUS_RG_TRAINER_TOWER":556,"MUS_RG_UNION_ROOM":539,"MUS_RG_VERMILLION":525,"MUS_RG_VICTORY_GYM_LEADER":524,"MUS_RG_VICTORY_ROAD":507,"MUS_RG_VICTORY_TRAINER":522,"MUS_RG_VICTORY_WILD":523,"MUS_RG_VIRIDIAN_FOREST":499,"MUS_RG_VS_CHAMPION":511,"MUS_RG_VS_DEOXYS":551,"MUS_RG_VS_GYM_LEADER":508,"MUS_RG_VS_LEGEND":553,"MUS_RG_VS_MEWTWO":552,"MUS_RG_VS_TRAINER":509,"MUS_RG_VS_WILD":510,"MUS_ROULETTE":392,"MUS_ROUTE101":359,"MUS_ROUTE104":401,"MUS_ROUTE110":360,"MUS_ROUTE113":418,"MUS_ROUTE118":32767,"MUS_ROUTE119":402,"MUS_ROUTE120":361,"MUS_ROUTE122":374,"MUS_RUSTBORO":399,"MUS_SAFARI_ZONE":428,"MUS_SAILING":431,"MUS_SCHOOL":435,"MUS_SEALED_CHAMBER":438,"MUS_SLATEPORT":433,"MUS_SLOTS_JACKPOT":389,"MUS_SLOTS_WIN":390,"MUS_SOOTOPOLIS":445,"MUS_SURF":365,"MUS_TITLE":413,"MUS_TOO_BAD":391,"MUS_TRICK_HOUSE":448,"MUS_UNDERWATER":411,"MUS_VERDANTURF":398,"MUS_VICTORY_AQUA_MAGMA":424,"MUS_VICTORY_GYM_LEADER":354,"MUS_VICTORY_LEAGUE":355,"MUS_VICTORY_ROAD":429,"MUS_VICTORY_TRAINER":412,"MUS_VICTORY_WILD":353,"MUS_VS_AQUA_MAGMA":475,"MUS_VS_AQUA_MAGMA_LEADER":483,"MUS_VS_CHAMPION":478,"MUS_VS_ELITE_FOUR":482,"MUS_VS_FRONTIER_BRAIN":471,"MUS_VS_GYM_LEADER":477,"MUS_VS_KYOGRE_GROUDON":480,"MUS_VS_MEW":472,"MUS_VS_RAYQUAZA":470,"MUS_VS_REGI":479,"MUS_VS_RIVAL":481,"MUS_VS_TRAINER":476,"MUS_VS_WILD":474,"MUS_WEATHER_GROUDON":444,"NUM_BADGES":8,"NUM_BERRY_MASTER_BERRIES":10,"NUM_BERRY_MASTER_BERRIES_SKIPPED":20,"NUM_BERRY_MASTER_WIFE_BERRIES":10,"NUM_DAILY_FLAGS":64,"NUM_HIDDEN_MACHINES":8,"NUM_KIRI_BERRIES":10,"NUM_KIRI_BERRIES_SKIPPED":20,"NUM_ROUTE_114_MAN_BERRIES":5,"NUM_ROUTE_114_MAN_BERRIES_SKIPPED":15,"NUM_SPECIAL_FLAGS":128,"NUM_SPECIES":412,"NUM_TECHNICAL_MACHINES":50,"NUM_TEMP_FLAGS":32,"NUM_WATER_STAGES":4,"NUM_WONDER_CARD_FLAGS":20,"OLD_ROD":0,"PH_CHOICE_BLEND":589,"PH_CHOICE_HELD":590,"PH_CHOICE_SOLO":591,"PH_CLOTH_BLEND":565,"PH_CLOTH_HELD":566,"PH_CLOTH_SOLO":567,"PH_CURE_BLEND":604,"PH_CURE_HELD":605,"PH_CURE_SOLO":606,"PH_DRESS_BLEND":568,"PH_DRESS_HELD":569,"PH_DRESS_SOLO":570,"PH_FACE_BLEND":562,"PH_FACE_HELD":563,"PH_FACE_SOLO":564,"PH_FLEECE_BLEND":571,"PH_FLEECE_HELD":572,"PH_FLEECE_SOLO":573,"PH_FOOT_BLEND":595,"PH_FOOT_HELD":596,"PH_FOOT_SOLO":597,"PH_GOAT_BLEND":583,"PH_GOAT_HELD":584,"PH_GOAT_SOLO":585,"PH_GOOSE_BLEND":598,"PH_GOOSE_HELD":599,"PH_GOOSE_SOLO":600,"PH_KIT_BLEND":574,"PH_KIT_HELD":575,"PH_KIT_SOLO":576,"PH_LOT_BLEND":580,"PH_LOT_HELD":581,"PH_LOT_SOLO":582,"PH_MOUTH_BLEND":592,"PH_MOUTH_HELD":593,"PH_MOUTH_SOLO":594,"PH_NURSE_BLEND":607,"PH_NURSE_HELD":608,"PH_NURSE_SOLO":609,"PH_PRICE_BLEND":577,"PH_PRICE_HELD":578,"PH_PRICE_SOLO":579,"PH_STRUT_BLEND":601,"PH_STRUT_HELD":602,"PH_STRUT_SOLO":603,"PH_THOUGHT_BLEND":586,"PH_THOUGHT_HELD":587,"PH_THOUGHT_SOLO":588,"PH_TRAP_BLEND":559,"PH_TRAP_HELD":560,"PH_TRAP_SOLO":561,"SE_A":25,"SE_APPLAUSE":105,"SE_ARENA_TIMEUP1":265,"SE_ARENA_TIMEUP2":266,"SE_BALL":23,"SE_BALLOON_BLUE":75,"SE_BALLOON_RED":74,"SE_BALLOON_YELLOW":76,"SE_BALL_BOUNCE_1":56,"SE_BALL_BOUNCE_2":57,"SE_BALL_BOUNCE_3":58,"SE_BALL_BOUNCE_4":59,"SE_BALL_OPEN":15,"SE_BALL_THROW":61,"SE_BALL_TRADE":60,"SE_BALL_TRAY_BALL":115,"SE_BALL_TRAY_ENTER":114,"SE_BALL_TRAY_EXIT":116,"SE_BANG":20,"SE_BERRY_BLENDER":53,"SE_BIKE_BELL":11,"SE_BIKE_HOP":34,"SE_BOO":22,"SE_BREAKABLE_DOOR":77,"SE_BRIDGE_WALK":71,"SE_CARD":54,"SE_CLICK":36,"SE_CONTEST_CONDITION_LOSE":38,"SE_CONTEST_CURTAIN_FALL":98,"SE_CONTEST_CURTAIN_RISE":97,"SE_CONTEST_HEART":96,"SE_CONTEST_ICON_CHANGE":99,"SE_CONTEST_ICON_CLEAR":100,"SE_CONTEST_MONS_TURN":101,"SE_CONTEST_PLACE":24,"SE_DEX_PAGE":109,"SE_DEX_SCROLL":108,"SE_DEX_SEARCH":112,"SE_DING_DONG":73,"SE_DOOR":8,"SE_DOWNPOUR":83,"SE_DOWNPOUR_STOP":84,"SE_E":28,"SE_EFFECTIVE":13,"SE_EGG_HATCH":113,"SE_ELEVATOR":89,"SE_ESCALATOR":80,"SE_EXIT":9,"SE_EXP":33,"SE_EXP_MAX":91,"SE_FAILURE":32,"SE_FAINT":16,"SE_FALL":43,"SE_FIELD_POISON":79,"SE_FLEE":17,"SE_FU_ZAKU":37,"SE_GLASS_FLUTE":117,"SE_I":26,"SE_ICE_BREAK":41,"SE_ICE_CRACK":42,"SE_ICE_STAIRS":40,"SE_INTRO_BLAST":103,"SE_ITEMFINDER":72,"SE_LAVARIDGE_FALL_WARP":39,"SE_LEDGE":10,"SE_LOW_HEALTH":90,"SE_MUD_BALL":78,"SE_MUGSHOT":104,"SE_M_ABSORB":180,"SE_M_ABSORB_2":179,"SE_M_ACID_ARMOR":218,"SE_M_ATTRACT":226,"SE_M_ATTRACT2":227,"SE_M_BARRIER":208,"SE_M_BATON_PASS":224,"SE_M_BELLY_DRUM":185,"SE_M_BIND":170,"SE_M_BITE":161,"SE_M_BLIZZARD":153,"SE_M_BLIZZARD2":154,"SE_M_BONEMERANG":187,"SE_M_BRICK_BREAK":198,"SE_M_BUBBLE":124,"SE_M_BUBBLE2":125,"SE_M_BUBBLE3":126,"SE_M_BUBBLE_BEAM":182,"SE_M_BUBBLE_BEAM2":183,"SE_M_CHARGE":213,"SE_M_CHARM":212,"SE_M_COMET_PUNCH":139,"SE_M_CONFUSE_RAY":196,"SE_M_COSMIC_POWER":243,"SE_M_CRABHAMMER":142,"SE_M_CUT":128,"SE_M_DETECT":209,"SE_M_DIG":175,"SE_M_DIVE":233,"SE_M_DIZZY_PUNCH":176,"SE_M_DOUBLE_SLAP":134,"SE_M_DOUBLE_TEAM":135,"SE_M_DRAGON_RAGE":171,"SE_M_EARTHQUAKE":234,"SE_M_EMBER":151,"SE_M_ENCORE":222,"SE_M_ENCORE2":223,"SE_M_EXPLOSION":178,"SE_M_FAINT_ATTACK":190,"SE_M_FIRE_PUNCH":147,"SE_M_FLAMETHROWER":146,"SE_M_FLAME_WHEEL":144,"SE_M_FLAME_WHEEL2":145,"SE_M_FLATTER":229,"SE_M_FLY":158,"SE_M_GIGA_DRAIN":199,"SE_M_GRASSWHISTLE":231,"SE_M_GUST":132,"SE_M_GUST2":133,"SE_M_HAIL":242,"SE_M_HARDEN":120,"SE_M_HAZE":246,"SE_M_HEADBUTT":162,"SE_M_HEAL_BELL":195,"SE_M_HEAT_WAVE":240,"SE_M_HORN_ATTACK":166,"SE_M_HYDRO_PUMP":164,"SE_M_HYPER_BEAM":215,"SE_M_HYPER_BEAM2":247,"SE_M_ICY_WIND":137,"SE_M_JUMP_KICK":143,"SE_M_LEER":192,"SE_M_LICK":188,"SE_M_LOCK_ON":210,"SE_M_MEGA_KICK":140,"SE_M_MEGA_KICK2":141,"SE_M_METRONOME":186,"SE_M_MILK_DRINK":225,"SE_M_MINIMIZE":204,"SE_M_MIST":168,"SE_M_MOONLIGHT":211,"SE_M_MORNING_SUN":228,"SE_M_NIGHTMARE":121,"SE_M_PAY_DAY":174,"SE_M_PERISH_SONG":173,"SE_M_PETAL_DANCE":202,"SE_M_POISON_POWDER":169,"SE_M_PSYBEAM":189,"SE_M_PSYBEAM2":200,"SE_M_RAIN_DANCE":127,"SE_M_RAZOR_WIND":136,"SE_M_RAZOR_WIND2":160,"SE_M_REFLECT":207,"SE_M_REVERSAL":217,"SE_M_ROCK_THROW":131,"SE_M_SACRED_FIRE":149,"SE_M_SACRED_FIRE2":150,"SE_M_SANDSTORM":219,"SE_M_SAND_ATTACK":159,"SE_M_SAND_TOMB":230,"SE_M_SCRATCH":155,"SE_M_SCREECH":181,"SE_M_SELF_DESTRUCT":177,"SE_M_SING":172,"SE_M_SKETCH":205,"SE_M_SKY_UPPERCUT":238,"SE_M_SNORE":197,"SE_M_SOLAR_BEAM":201,"SE_M_SPIT_UP":232,"SE_M_STAT_DECREASE":245,"SE_M_STAT_INCREASE":239,"SE_M_STRENGTH":214,"SE_M_STRING_SHOT":129,"SE_M_STRING_SHOT2":130,"SE_M_SUPERSONIC":184,"SE_M_SURF":163,"SE_M_SWAGGER":193,"SE_M_SWAGGER2":194,"SE_M_SWEET_SCENT":236,"SE_M_SWIFT":206,"SE_M_SWORDS_DANCE":191,"SE_M_TAIL_WHIP":167,"SE_M_TAKE_DOWN":152,"SE_M_TEETER_DANCE":244,"SE_M_TELEPORT":203,"SE_M_THUNDERBOLT":118,"SE_M_THUNDERBOLT2":119,"SE_M_THUNDER_WAVE":138,"SE_M_TOXIC":148,"SE_M_TRI_ATTACK":220,"SE_M_TRI_ATTACK2":221,"SE_M_TWISTER":235,"SE_M_UPROAR":241,"SE_M_VICEGRIP":156,"SE_M_VITAL_THROW":122,"SE_M_VITAL_THROW2":123,"SE_M_WATERFALL":216,"SE_M_WHIRLPOOL":165,"SE_M_WING_ATTACK":157,"SE_M_YAWN":237,"SE_N":30,"SE_NOTE_A":67,"SE_NOTE_B":68,"SE_NOTE_C":62,"SE_NOTE_C_HIGH":69,"SE_NOTE_D":63,"SE_NOTE_E":64,"SE_NOTE_F":65,"SE_NOTE_G":66,"SE_NOT_EFFECTIVE":12,"SE_O":29,"SE_ORB":107,"SE_PC_LOGIN":2,"SE_PC_OFF":3,"SE_PC_ON":4,"SE_PIKE_CURTAIN_CLOSE":267,"SE_PIKE_CURTAIN_OPEN":268,"SE_PIN":21,"SE_POKENAV_CALL":263,"SE_POKENAV_HANG_UP":264,"SE_POKENAV_OFF":111,"SE_POKENAV_ON":110,"SE_PUDDLE":70,"SE_RAIN":85,"SE_RAIN_STOP":86,"SE_REPEL":47,"SE_RG_BAG_CURSOR":252,"SE_RG_BAG_POCKET":253,"SE_RG_BALL_CLICK":254,"SE_RG_CARD_FLIP":249,"SE_RG_CARD_FLIPPING":250,"SE_RG_CARD_OPEN":251,"SE_RG_DEOXYS_MOVE":260,"SE_RG_DOOR":248,"SE_RG_HELP_CLOSE":258,"SE_RG_HELP_ERROR":259,"SE_RG_HELP_OPEN":257,"SE_RG_POKE_JUMP_FAILURE":262,"SE_RG_POKE_JUMP_SUCCESS":261,"SE_RG_SHOP":255,"SE_RG_SS_ANNE_HORN":256,"SE_ROTATING_GATE":48,"SE_ROULETTE_BALL":92,"SE_ROULETTE_BALL2":93,"SE_SAVE":55,"SE_SELECT":5,"SE_SHINY":102,"SE_SHIP":19,"SE_SHOP":95,"SE_SLIDING_DOOR":18,"SE_SUCCESS":31,"SE_SUDOWOODO_SHAKE":269,"SE_SUPER_EFFECTIVE":14,"SE_SWITCH":35,"SE_TAILLOW_WING_FLAP":94,"SE_THUNDER":87,"SE_THUNDER2":88,"SE_THUNDERSTORM":81,"SE_THUNDERSTORM_STOP":82,"SE_TRUCK_DOOR":52,"SE_TRUCK_MOVE":49,"SE_TRUCK_STOP":50,"SE_TRUCK_UNLOAD":51,"SE_U":27,"SE_UNLOCK":44,"SE_USE_ITEM":1,"SE_VEND":106,"SE_WALL_HIT":7,"SE_WARP_IN":45,"SE_WARP_OUT":46,"SE_WIN_OPEN":6,"SPECIAL_FLAGS_END":16511,"SPECIAL_FLAGS_START":16384,"SPECIES_ABRA":63,"SPECIES_ABSOL":376,"SPECIES_AERODACTYL":142,"SPECIES_AGGRON":384,"SPECIES_AIPOM":190,"SPECIES_ALAKAZAM":65,"SPECIES_ALTARIA":359,"SPECIES_AMPHAROS":181,"SPECIES_ANORITH":390,"SPECIES_ARBOK":24,"SPECIES_ARCANINE":59,"SPECIES_ARIADOS":168,"SPECIES_ARMALDO":391,"SPECIES_ARON":382,"SPECIES_ARTICUNO":144,"SPECIES_AZUMARILL":184,"SPECIES_AZURILL":350,"SPECIES_BAGON":395,"SPECIES_BALTOY":318,"SPECIES_BANETTE":378,"SPECIES_BARBOACH":323,"SPECIES_BAYLEEF":153,"SPECIES_BEAUTIFLY":292,"SPECIES_BEEDRILL":15,"SPECIES_BELDUM":398,"SPECIES_BELLOSSOM":182,"SPECIES_BELLSPROUT":69,"SPECIES_BLASTOISE":9,"SPECIES_BLAZIKEN":282,"SPECIES_BLISSEY":242,"SPECIES_BRELOOM":307,"SPECIES_BULBASAUR":1,"SPECIES_BUTTERFREE":12,"SPECIES_CACNEA":344,"SPECIES_CACTURNE":345,"SPECIES_CAMERUPT":340,"SPECIES_CARVANHA":330,"SPECIES_CASCOON":293,"SPECIES_CASTFORM":385,"SPECIES_CATERPIE":10,"SPECIES_CELEBI":251,"SPECIES_CHANSEY":113,"SPECIES_CHARIZARD":6,"SPECIES_CHARMANDER":4,"SPECIES_CHARMELEON":5,"SPECIES_CHIKORITA":152,"SPECIES_CHIMECHO":411,"SPECIES_CHINCHOU":170,"SPECIES_CLAMPERL":373,"SPECIES_CLAYDOL":319,"SPECIES_CLEFABLE":36,"SPECIES_CLEFAIRY":35,"SPECIES_CLEFFA":173,"SPECIES_CLOYSTER":91,"SPECIES_COMBUSKEN":281,"SPECIES_CORPHISH":326,"SPECIES_CORSOLA":222,"SPECIES_CRADILY":389,"SPECIES_CRAWDAUNT":327,"SPECIES_CROBAT":169,"SPECIES_CROCONAW":159,"SPECIES_CUBONE":104,"SPECIES_CYNDAQUIL":155,"SPECIES_DELCATTY":316,"SPECIES_DELIBIRD":225,"SPECIES_DEOXYS":410,"SPECIES_DEWGONG":87,"SPECIES_DIGLETT":50,"SPECIES_DITTO":132,"SPECIES_DODRIO":85,"SPECIES_DODUO":84,"SPECIES_DONPHAN":232,"SPECIES_DRAGONAIR":148,"SPECIES_DRAGONITE":149,"SPECIES_DRATINI":147,"SPECIES_DROWZEE":96,"SPECIES_DUGTRIO":51,"SPECIES_DUNSPARCE":206,"SPECIES_DUSCLOPS":362,"SPECIES_DUSKULL":361,"SPECIES_DUSTOX":294,"SPECIES_EEVEE":133,"SPECIES_EGG":412,"SPECIES_EKANS":23,"SPECIES_ELECTABUZZ":125,"SPECIES_ELECTRIKE":337,"SPECIES_ELECTRODE":101,"SPECIES_ELEKID":239,"SPECIES_ENTEI":244,"SPECIES_ESPEON":196,"SPECIES_EXEGGCUTE":102,"SPECIES_EXEGGUTOR":103,"SPECIES_EXPLOUD":372,"SPECIES_FARFETCHD":83,"SPECIES_FEAROW":22,"SPECIES_FEEBAS":328,"SPECIES_FERALIGATR":160,"SPECIES_FLAAFFY":180,"SPECIES_FLAREON":136,"SPECIES_FLYGON":334,"SPECIES_FORRETRESS":205,"SPECIES_FURRET":162,"SPECIES_GARDEVOIR":394,"SPECIES_GASTLY":92,"SPECIES_GENGAR":94,"SPECIES_GEODUDE":74,"SPECIES_GIRAFARIG":203,"SPECIES_GLALIE":347,"SPECIES_GLIGAR":207,"SPECIES_GLOOM":44,"SPECIES_GOLBAT":42,"SPECIES_GOLDEEN":118,"SPECIES_GOLDUCK":55,"SPECIES_GOLEM":76,"SPECIES_GOREBYSS":375,"SPECIES_GRANBULL":210,"SPECIES_GRAVELER":75,"SPECIES_GRIMER":88,"SPECIES_GROUDON":405,"SPECIES_GROVYLE":278,"SPECIES_GROWLITHE":58,"SPECIES_GRUMPIG":352,"SPECIES_GULPIN":367,"SPECIES_GYARADOS":130,"SPECIES_HARIYAMA":336,"SPECIES_HAUNTER":93,"SPECIES_HERACROSS":214,"SPECIES_HITMONCHAN":107,"SPECIES_HITMONLEE":106,"SPECIES_HITMONTOP":237,"SPECIES_HOOTHOOT":163,"SPECIES_HOPPIP":187,"SPECIES_HORSEA":116,"SPECIES_HOUNDOOM":229,"SPECIES_HOUNDOUR":228,"SPECIES_HO_OH":250,"SPECIES_HUNTAIL":374,"SPECIES_HYPNO":97,"SPECIES_IGGLYBUFF":174,"SPECIES_ILLUMISE":387,"SPECIES_IVYSAUR":2,"SPECIES_JIGGLYPUFF":39,"SPECIES_JIRACHI":409,"SPECIES_JOLTEON":135,"SPECIES_JUMPLUFF":189,"SPECIES_JYNX":124,"SPECIES_KABUTO":140,"SPECIES_KABUTOPS":141,"SPECIES_KADABRA":64,"SPECIES_KAKUNA":14,"SPECIES_KANGASKHAN":115,"SPECIES_KECLEON":317,"SPECIES_KINGDRA":230,"SPECIES_KINGLER":99,"SPECIES_KIRLIA":393,"SPECIES_KOFFING":109,"SPECIES_KRABBY":98,"SPECIES_KYOGRE":404,"SPECIES_LAIRON":383,"SPECIES_LANTURN":171,"SPECIES_LAPRAS":131,"SPECIES_LARVITAR":246,"SPECIES_LATIAS":407,"SPECIES_LATIOS":408,"SPECIES_LEDIAN":166,"SPECIES_LEDYBA":165,"SPECIES_LICKITUNG":108,"SPECIES_LILEEP":388,"SPECIES_LINOONE":289,"SPECIES_LOMBRE":296,"SPECIES_LOTAD":295,"SPECIES_LOUDRED":371,"SPECIES_LUDICOLO":297,"SPECIES_LUGIA":249,"SPECIES_LUNATONE":348,"SPECIES_LUVDISC":325,"SPECIES_MACHAMP":68,"SPECIES_MACHOKE":67,"SPECIES_MACHOP":66,"SPECIES_MAGBY":240,"SPECIES_MAGCARGO":219,"SPECIES_MAGIKARP":129,"SPECIES_MAGMAR":126,"SPECIES_MAGNEMITE":81,"SPECIES_MAGNETON":82,"SPECIES_MAKUHITA":335,"SPECIES_MANECTRIC":338,"SPECIES_MANKEY":56,"SPECIES_MANTINE":226,"SPECIES_MAREEP":179,"SPECIES_MARILL":183,"SPECIES_MAROWAK":105,"SPECIES_MARSHTOMP":284,"SPECIES_MASQUERAIN":312,"SPECIES_MAWILE":355,"SPECIES_MEDICHAM":357,"SPECIES_MEDITITE":356,"SPECIES_MEGANIUM":154,"SPECIES_MEOWTH":52,"SPECIES_METAGROSS":400,"SPECIES_METANG":399,"SPECIES_METAPOD":11,"SPECIES_MEW":151,"SPECIES_MEWTWO":150,"SPECIES_MIGHTYENA":287,"SPECIES_MILOTIC":329,"SPECIES_MILTANK":241,"SPECIES_MINUN":354,"SPECIES_MISDREAVUS":200,"SPECIES_MOLTRES":146,"SPECIES_MR_MIME":122,"SPECIES_MUDKIP":283,"SPECIES_MUK":89,"SPECIES_MURKROW":198,"SPECIES_NATU":177,"SPECIES_NIDOKING":34,"SPECIES_NIDOQUEEN":31,"SPECIES_NIDORAN_F":29,"SPECIES_NIDORAN_M":32,"SPECIES_NIDORINA":30,"SPECIES_NIDORINO":33,"SPECIES_NINCADA":301,"SPECIES_NINETALES":38,"SPECIES_NINJASK":302,"SPECIES_NOCTOWL":164,"SPECIES_NONE":0,"SPECIES_NOSEPASS":320,"SPECIES_NUMEL":339,"SPECIES_NUZLEAF":299,"SPECIES_OCTILLERY":224,"SPECIES_ODDISH":43,"SPECIES_OLD_UNOWN_B":252,"SPECIES_OLD_UNOWN_C":253,"SPECIES_OLD_UNOWN_D":254,"SPECIES_OLD_UNOWN_E":255,"SPECIES_OLD_UNOWN_F":256,"SPECIES_OLD_UNOWN_G":257,"SPECIES_OLD_UNOWN_H":258,"SPECIES_OLD_UNOWN_I":259,"SPECIES_OLD_UNOWN_J":260,"SPECIES_OLD_UNOWN_K":261,"SPECIES_OLD_UNOWN_L":262,"SPECIES_OLD_UNOWN_M":263,"SPECIES_OLD_UNOWN_N":264,"SPECIES_OLD_UNOWN_O":265,"SPECIES_OLD_UNOWN_P":266,"SPECIES_OLD_UNOWN_Q":267,"SPECIES_OLD_UNOWN_R":268,"SPECIES_OLD_UNOWN_S":269,"SPECIES_OLD_UNOWN_T":270,"SPECIES_OLD_UNOWN_U":271,"SPECIES_OLD_UNOWN_V":272,"SPECIES_OLD_UNOWN_W":273,"SPECIES_OLD_UNOWN_X":274,"SPECIES_OLD_UNOWN_Y":275,"SPECIES_OLD_UNOWN_Z":276,"SPECIES_OMANYTE":138,"SPECIES_OMASTAR":139,"SPECIES_ONIX":95,"SPECIES_PARAS":46,"SPECIES_PARASECT":47,"SPECIES_PELIPPER":310,"SPECIES_PERSIAN":53,"SPECIES_PHANPY":231,"SPECIES_PICHU":172,"SPECIES_PIDGEOT":18,"SPECIES_PIDGEOTTO":17,"SPECIES_PIDGEY":16,"SPECIES_PIKACHU":25,"SPECIES_PILOSWINE":221,"SPECIES_PINECO":204,"SPECIES_PINSIR":127,"SPECIES_PLUSLE":353,"SPECIES_POLITOED":186,"SPECIES_POLIWAG":60,"SPECIES_POLIWHIRL":61,"SPECIES_POLIWRATH":62,"SPECIES_PONYTA":77,"SPECIES_POOCHYENA":286,"SPECIES_PORYGON":137,"SPECIES_PORYGON2":233,"SPECIES_PRIMEAPE":57,"SPECIES_PSYDUCK":54,"SPECIES_PUPITAR":247,"SPECIES_QUAGSIRE":195,"SPECIES_QUILAVA":156,"SPECIES_QWILFISH":211,"SPECIES_RAICHU":26,"SPECIES_RAIKOU":243,"SPECIES_RALTS":392,"SPECIES_RAPIDASH":78,"SPECIES_RATICATE":20,"SPECIES_RATTATA":19,"SPECIES_RAYQUAZA":406,"SPECIES_REGICE":402,"SPECIES_REGIROCK":401,"SPECIES_REGISTEEL":403,"SPECIES_RELICANTH":381,"SPECIES_REMORAID":223,"SPECIES_RHYDON":112,"SPECIES_RHYHORN":111,"SPECIES_ROSELIA":363,"SPECIES_SABLEYE":322,"SPECIES_SALAMENCE":397,"SPECIES_SANDSHREW":27,"SPECIES_SANDSLASH":28,"SPECIES_SCEPTILE":279,"SPECIES_SCIZOR":212,"SPECIES_SCYTHER":123,"SPECIES_SEADRA":117,"SPECIES_SEAKING":119,"SPECIES_SEALEO":342,"SPECIES_SEEDOT":298,"SPECIES_SEEL":86,"SPECIES_SENTRET":161,"SPECIES_SEVIPER":379,"SPECIES_SHARPEDO":331,"SPECIES_SHEDINJA":303,"SPECIES_SHELGON":396,"SPECIES_SHELLDER":90,"SPECIES_SHIFTRY":300,"SPECIES_SHROOMISH":306,"SPECIES_SHUCKLE":213,"SPECIES_SHUPPET":377,"SPECIES_SILCOON":291,"SPECIES_SKARMORY":227,"SPECIES_SKIPLOOM":188,"SPECIES_SKITTY":315,"SPECIES_SLAKING":366,"SPECIES_SLAKOTH":364,"SPECIES_SLOWBRO":80,"SPECIES_SLOWKING":199,"SPECIES_SLOWPOKE":79,"SPECIES_SLUGMA":218,"SPECIES_SMEARGLE":235,"SPECIES_SMOOCHUM":238,"SPECIES_SNEASEL":215,"SPECIES_SNORLAX":143,"SPECIES_SNORUNT":346,"SPECIES_SNUBBULL":209,"SPECIES_SOLROCK":349,"SPECIES_SPEAROW":21,"SPECIES_SPHEAL":341,"SPECIES_SPINARAK":167,"SPECIES_SPINDA":308,"SPECIES_SPOINK":351,"SPECIES_SQUIRTLE":7,"SPECIES_STANTLER":234,"SPECIES_STARMIE":121,"SPECIES_STARYU":120,"SPECIES_STEELIX":208,"SPECIES_SUDOWOODO":185,"SPECIES_SUICUNE":245,"SPECIES_SUNFLORA":192,"SPECIES_SUNKERN":191,"SPECIES_SURSKIT":311,"SPECIES_SWABLU":358,"SPECIES_SWALOT":368,"SPECIES_SWAMPERT":285,"SPECIES_SWELLOW":305,"SPECIES_SWINUB":220,"SPECIES_TAILLOW":304,"SPECIES_TANGELA":114,"SPECIES_TAUROS":128,"SPECIES_TEDDIURSA":216,"SPECIES_TENTACOOL":72,"SPECIES_TENTACRUEL":73,"SPECIES_TOGEPI":175,"SPECIES_TOGETIC":176,"SPECIES_TORCHIC":280,"SPECIES_TORKOAL":321,"SPECIES_TOTODILE":158,"SPECIES_TRAPINCH":332,"SPECIES_TREECKO":277,"SPECIES_TROPIUS":369,"SPECIES_TYPHLOSION":157,"SPECIES_TYRANITAR":248,"SPECIES_TYROGUE":236,"SPECIES_UMBREON":197,"SPECIES_UNOWN":201,"SPECIES_UNOWN_B":413,"SPECIES_UNOWN_C":414,"SPECIES_UNOWN_D":415,"SPECIES_UNOWN_E":416,"SPECIES_UNOWN_EMARK":438,"SPECIES_UNOWN_F":417,"SPECIES_UNOWN_G":418,"SPECIES_UNOWN_H":419,"SPECIES_UNOWN_I":420,"SPECIES_UNOWN_J":421,"SPECIES_UNOWN_K":422,"SPECIES_UNOWN_L":423,"SPECIES_UNOWN_M":424,"SPECIES_UNOWN_N":425,"SPECIES_UNOWN_O":426,"SPECIES_UNOWN_P":427,"SPECIES_UNOWN_Q":428,"SPECIES_UNOWN_QMARK":439,"SPECIES_UNOWN_R":429,"SPECIES_UNOWN_S":430,"SPECIES_UNOWN_T":431,"SPECIES_UNOWN_U":432,"SPECIES_UNOWN_V":433,"SPECIES_UNOWN_W":434,"SPECIES_UNOWN_X":435,"SPECIES_UNOWN_Y":436,"SPECIES_UNOWN_Z":437,"SPECIES_URSARING":217,"SPECIES_VAPOREON":134,"SPECIES_VENOMOTH":49,"SPECIES_VENONAT":48,"SPECIES_VENUSAUR":3,"SPECIES_VIBRAVA":333,"SPECIES_VICTREEBEL":71,"SPECIES_VIGOROTH":365,"SPECIES_VILEPLUME":45,"SPECIES_VOLBEAT":386,"SPECIES_VOLTORB":100,"SPECIES_VULPIX":37,"SPECIES_WAILMER":313,"SPECIES_WAILORD":314,"SPECIES_WALREIN":343,"SPECIES_WARTORTLE":8,"SPECIES_WEEDLE":13,"SPECIES_WEEPINBELL":70,"SPECIES_WEEZING":110,"SPECIES_WHISCASH":324,"SPECIES_WHISMUR":370,"SPECIES_WIGGLYTUFF":40,"SPECIES_WINGULL":309,"SPECIES_WOBBUFFET":202,"SPECIES_WOOPER":194,"SPECIES_WURMPLE":290,"SPECIES_WYNAUT":360,"SPECIES_XATU":178,"SPECIES_YANMA":193,"SPECIES_ZANGOOSE":380,"SPECIES_ZAPDOS":145,"SPECIES_ZIGZAGOON":288,"SPECIES_ZUBAT":41,"SUPER_ROD":2,"SYSTEM_FLAGS":2144,"TEMP_FLAGS_END":31,"TEMP_FLAGS_START":0,"TRAINERS_COUNT":855,"TRAINER_AARON":397,"TRAINER_ABIGAIL_1":358,"TRAINER_ABIGAIL_2":360,"TRAINER_ABIGAIL_3":361,"TRAINER_ABIGAIL_4":362,"TRAINER_ABIGAIL_5":363,"TRAINER_AIDAN":674,"TRAINER_AISHA":757,"TRAINER_ALAN":630,"TRAINER_ALBERT":80,"TRAINER_ALBERTO":12,"TRAINER_ALEX":413,"TRAINER_ALEXA":670,"TRAINER_ALEXIA":90,"TRAINER_ALEXIS":248,"TRAINER_ALICE":448,"TRAINER_ALIX":750,"TRAINER_ALLEN":333,"TRAINER_ALLISON":387,"TRAINER_ALVARO":849,"TRAINER_ALYSSA":701,"TRAINER_AMY_AND_LIV_1":481,"TRAINER_AMY_AND_LIV_2":482,"TRAINER_AMY_AND_LIV_3":485,"TRAINER_AMY_AND_LIV_4":487,"TRAINER_AMY_AND_LIV_5":488,"TRAINER_AMY_AND_LIV_6":489,"TRAINER_ANABEL":805,"TRAINER_ANDREA":613,"TRAINER_ANDRES_1":737,"TRAINER_ANDRES_2":812,"TRAINER_ANDRES_3":813,"TRAINER_ANDRES_4":814,"TRAINER_ANDRES_5":815,"TRAINER_ANDREW":336,"TRAINER_ANGELICA":436,"TRAINER_ANGELINA":712,"TRAINER_ANGELO":802,"TRAINER_ANNA_AND_MEG_1":287,"TRAINER_ANNA_AND_MEG_2":288,"TRAINER_ANNA_AND_MEG_3":289,"TRAINER_ANNA_AND_MEG_4":290,"TRAINER_ANNA_AND_MEG_5":291,"TRAINER_ANNIKA":502,"TRAINER_ANTHONY":352,"TRAINER_ARCHIE":34,"TRAINER_ASHLEY":655,"TRAINER_ATHENA":577,"TRAINER_ATSUSHI":190,"TRAINER_AURON":506,"TRAINER_AUSTINA":58,"TRAINER_AUTUMN":217,"TRAINER_AXLE":203,"TRAINER_BARNY":343,"TRAINER_BARRY":163,"TRAINER_BEAU":212,"TRAINER_BECK":414,"TRAINER_BECKY":470,"TRAINER_BEN":323,"TRAINER_BENJAMIN_1":353,"TRAINER_BENJAMIN_2":354,"TRAINER_BENJAMIN_3":355,"TRAINER_BENJAMIN_4":356,"TRAINER_BENJAMIN_5":357,"TRAINER_BENNY":407,"TRAINER_BERKE":74,"TRAINER_BERNIE_1":206,"TRAINER_BERNIE_2":207,"TRAINER_BERNIE_3":208,"TRAINER_BERNIE_4":209,"TRAINER_BERNIE_5":210,"TRAINER_BETH":445,"TRAINER_BETHANY":301,"TRAINER_BEVERLY":441,"TRAINER_BIANCA":706,"TRAINER_BILLY":319,"TRAINER_BLAKE":235,"TRAINER_BRANDEN":745,"TRAINER_BRANDI":756,"TRAINER_BRANDON":811,"TRAINER_BRAWLY_1":266,"TRAINER_BRAWLY_2":774,"TRAINER_BRAWLY_3":775,"TRAINER_BRAWLY_4":776,"TRAINER_BRAWLY_5":777,"TRAINER_BRAXTON":75,"TRAINER_BRENDA":454,"TRAINER_BRENDAN_LILYCOVE_MUDKIP":661,"TRAINER_BRENDAN_LILYCOVE_TORCHIC":663,"TRAINER_BRENDAN_LILYCOVE_TREECKO":662,"TRAINER_BRENDAN_PLACEHOLDER":853,"TRAINER_BRENDAN_ROUTE_103_MUDKIP":520,"TRAINER_BRENDAN_ROUTE_103_TORCHIC":526,"TRAINER_BRENDAN_ROUTE_103_TREECKO":523,"TRAINER_BRENDAN_ROUTE_110_MUDKIP":521,"TRAINER_BRENDAN_ROUTE_110_TORCHIC":527,"TRAINER_BRENDAN_ROUTE_110_TREECKO":524,"TRAINER_BRENDAN_ROUTE_119_MUDKIP":522,"TRAINER_BRENDAN_ROUTE_119_TORCHIC":528,"TRAINER_BRENDAN_ROUTE_119_TREECKO":525,"TRAINER_BRENDAN_RUSTBORO_MUDKIP":593,"TRAINER_BRENDAN_RUSTBORO_TORCHIC":599,"TRAINER_BRENDAN_RUSTBORO_TREECKO":592,"TRAINER_BRENDEN":572,"TRAINER_BRENT":223,"TRAINER_BRIANNA":118,"TRAINER_BRICE":626,"TRAINER_BRIDGET":129,"TRAINER_BROOKE_1":94,"TRAINER_BROOKE_2":101,"TRAINER_BROOKE_3":102,"TRAINER_BROOKE_4":103,"TRAINER_BROOKE_5":104,"TRAINER_BRYAN":744,"TRAINER_BRYANT":746,"TRAINER_CALE":764,"TRAINER_CALLIE":763,"TRAINER_CALVIN_1":318,"TRAINER_CALVIN_2":328,"TRAINER_CALVIN_3":329,"TRAINER_CALVIN_4":330,"TRAINER_CALVIN_5":331,"TRAINER_CAMDEN":374,"TRAINER_CAMERON_1":238,"TRAINER_CAMERON_2":239,"TRAINER_CAMERON_3":240,"TRAINER_CAMERON_4":241,"TRAINER_CAMERON_5":242,"TRAINER_CAMRON":739,"TRAINER_CARLEE":464,"TRAINER_CAROL":471,"TRAINER_CAROLINA":741,"TRAINER_CAROLINE":99,"TRAINER_CARTER":345,"TRAINER_CATHERINE_1":559,"TRAINER_CATHERINE_2":562,"TRAINER_CATHERINE_3":563,"TRAINER_CATHERINE_4":564,"TRAINER_CATHERINE_5":565,"TRAINER_CEDRIC":475,"TRAINER_CELIA":743,"TRAINER_CELINA":705,"TRAINER_CHAD":174,"TRAINER_CHANDLER":698,"TRAINER_CHARLIE":66,"TRAINER_CHARLOTTE":714,"TRAINER_CHASE":378,"TRAINER_CHESTER":408,"TRAINER_CHIP":45,"TRAINER_CHRIS":693,"TRAINER_CINDY_1":114,"TRAINER_CINDY_2":117,"TRAINER_CINDY_3":120,"TRAINER_CINDY_4":121,"TRAINER_CINDY_5":122,"TRAINER_CINDY_6":123,"TRAINER_CLARENCE":580,"TRAINER_CLARISSA":435,"TRAINER_CLARK":631,"TRAINER_CLAUDE":338,"TRAINER_CLIFFORD":584,"TRAINER_COBY":709,"TRAINER_COLE":201,"TRAINER_COLIN":405,"TRAINER_COLTON":294,"TRAINER_CONNIE":128,"TRAINER_CONOR":511,"TRAINER_CORA":428,"TRAINER_CORY_1":740,"TRAINER_CORY_2":816,"TRAINER_CORY_3":817,"TRAINER_CORY_4":818,"TRAINER_CORY_5":819,"TRAINER_CRISSY":614,"TRAINER_CRISTIAN":574,"TRAINER_CRISTIN_1":767,"TRAINER_CRISTIN_2":828,"TRAINER_CRISTIN_3":829,"TRAINER_CRISTIN_4":830,"TRAINER_CRISTIN_5":831,"TRAINER_CYNDY_1":427,"TRAINER_CYNDY_2":430,"TRAINER_CYNDY_3":431,"TRAINER_CYNDY_4":432,"TRAINER_CYNDY_5":433,"TRAINER_DAISUKE":189,"TRAINER_DAISY":36,"TRAINER_DALE":341,"TRAINER_DALTON_1":196,"TRAINER_DALTON_2":197,"TRAINER_DALTON_3":198,"TRAINER_DALTON_4":199,"TRAINER_DALTON_5":200,"TRAINER_DANA":458,"TRAINER_DANIELLE":650,"TRAINER_DAPHNE":115,"TRAINER_DARCY":733,"TRAINER_DARIAN":696,"TRAINER_DARIUS":803,"TRAINER_DARRIN":154,"TRAINER_DAVID":158,"TRAINER_DAVIS":539,"TRAINER_DAWSON":694,"TRAINER_DAYTON":760,"TRAINER_DEAN":164,"TRAINER_DEANDRE":715,"TRAINER_DEBRA":460,"TRAINER_DECLAN":15,"TRAINER_DEMETRIUS":375,"TRAINER_DENISE":444,"TRAINER_DEREK":227,"TRAINER_DEVAN":753,"TRAINER_DEZ_AND_LUKE":640,"TRAINER_DIANA_1":474,"TRAINER_DIANA_2":477,"TRAINER_DIANA_3":478,"TRAINER_DIANA_4":479,"TRAINER_DIANA_5":480,"TRAINER_DIANNE":417,"TRAINER_DILLON":327,"TRAINER_DOMINIK":152,"TRAINER_DONALD":224,"TRAINER_DONNY":384,"TRAINER_DOUG":618,"TRAINER_DOUGLAS":153,"TRAINER_DRAKE":264,"TRAINER_DREW":211,"TRAINER_DUDLEY":173,"TRAINER_DUNCAN":496,"TRAINER_DUSTY_1":44,"TRAINER_DUSTY_2":47,"TRAINER_DUSTY_3":48,"TRAINER_DUSTY_4":49,"TRAINER_DUSTY_5":50,"TRAINER_DWAYNE":493,"TRAINER_DYLAN_1":364,"TRAINER_DYLAN_2":365,"TRAINER_DYLAN_3":366,"TRAINER_DYLAN_4":367,"TRAINER_DYLAN_5":368,"TRAINER_ED":13,"TRAINER_EDDIE":332,"TRAINER_EDGAR":79,"TRAINER_EDMOND":491,"TRAINER_EDWARD":232,"TRAINER_EDWARDO":404,"TRAINER_EDWIN_1":512,"TRAINER_EDWIN_2":515,"TRAINER_EDWIN_3":516,"TRAINER_EDWIN_4":517,"TRAINER_EDWIN_5":518,"TRAINER_ELI":501,"TRAINER_ELIJAH":742,"TRAINER_ELLIOT_1":339,"TRAINER_ELLIOT_2":346,"TRAINER_ELLIOT_3":347,"TRAINER_ELLIOT_4":348,"TRAINER_ELLIOT_5":349,"TRAINER_ERIC":632,"TRAINER_ERNEST_1":492,"TRAINER_ERNEST_2":497,"TRAINER_ERNEST_3":498,"TRAINER_ERNEST_4":499,"TRAINER_ERNEST_5":500,"TRAINER_ETHAN_1":216,"TRAINER_ETHAN_2":219,"TRAINER_ETHAN_3":220,"TRAINER_ETHAN_4":221,"TRAINER_ETHAN_5":222,"TRAINER_EVERETT":850,"TRAINER_FABIAN":759,"TRAINER_FELIX":38,"TRAINER_FERNANDO_1":195,"TRAINER_FERNANDO_2":832,"TRAINER_FERNANDO_3":833,"TRAINER_FERNANDO_4":834,"TRAINER_FERNANDO_5":835,"TRAINER_FLAGS_END":2143,"TRAINER_FLAGS_START":1280,"TRAINER_FLANNERY_1":268,"TRAINER_FLANNERY_2":782,"TRAINER_FLANNERY_3":783,"TRAINER_FLANNERY_4":784,"TRAINER_FLANNERY_5":785,"TRAINER_FLINT":654,"TRAINER_FOSTER":46,"TRAINER_FRANKLIN":170,"TRAINER_FREDRICK":29,"TRAINER_GABBY_AND_TY_1":51,"TRAINER_GABBY_AND_TY_2":52,"TRAINER_GABBY_AND_TY_3":53,"TRAINER_GABBY_AND_TY_4":54,"TRAINER_GABBY_AND_TY_5":55,"TRAINER_GABBY_AND_TY_6":56,"TRAINER_GABRIELLE_1":9,"TRAINER_GABRIELLE_2":840,"TRAINER_GABRIELLE_3":841,"TRAINER_GABRIELLE_4":842,"TRAINER_GABRIELLE_5":843,"TRAINER_GARRET":138,"TRAINER_GARRISON":547,"TRAINER_GEORGE":73,"TRAINER_GEORGIA":281,"TRAINER_GERALD":648,"TRAINER_GILBERT":169,"TRAINER_GINA_AND_MIA_1":483,"TRAINER_GINA_AND_MIA_2":486,"TRAINER_GLACIA":263,"TRAINER_GRACE":450,"TRAINER_GREG":619,"TRAINER_GRETA":808,"TRAINER_GRUNT_AQUA_HIDEOUT_1":2,"TRAINER_GRUNT_AQUA_HIDEOUT_2":3,"TRAINER_GRUNT_AQUA_HIDEOUT_3":4,"TRAINER_GRUNT_AQUA_HIDEOUT_4":5,"TRAINER_GRUNT_AQUA_HIDEOUT_5":27,"TRAINER_GRUNT_AQUA_HIDEOUT_6":28,"TRAINER_GRUNT_AQUA_HIDEOUT_7":192,"TRAINER_GRUNT_AQUA_HIDEOUT_8":193,"TRAINER_GRUNT_JAGGED_PASS":570,"TRAINER_GRUNT_MAGMA_HIDEOUT_1":716,"TRAINER_GRUNT_MAGMA_HIDEOUT_10":725,"TRAINER_GRUNT_MAGMA_HIDEOUT_11":726,"TRAINER_GRUNT_MAGMA_HIDEOUT_12":727,"TRAINER_GRUNT_MAGMA_HIDEOUT_13":728,"TRAINER_GRUNT_MAGMA_HIDEOUT_14":729,"TRAINER_GRUNT_MAGMA_HIDEOUT_15":730,"TRAINER_GRUNT_MAGMA_HIDEOUT_16":731,"TRAINER_GRUNT_MAGMA_HIDEOUT_2":717,"TRAINER_GRUNT_MAGMA_HIDEOUT_3":718,"TRAINER_GRUNT_MAGMA_HIDEOUT_4":719,"TRAINER_GRUNT_MAGMA_HIDEOUT_5":720,"TRAINER_GRUNT_MAGMA_HIDEOUT_6":721,"TRAINER_GRUNT_MAGMA_HIDEOUT_7":722,"TRAINER_GRUNT_MAGMA_HIDEOUT_8":723,"TRAINER_GRUNT_MAGMA_HIDEOUT_9":724,"TRAINER_GRUNT_MT_CHIMNEY_1":146,"TRAINER_GRUNT_MT_CHIMNEY_2":579,"TRAINER_GRUNT_MT_PYRE_1":23,"TRAINER_GRUNT_MT_PYRE_2":24,"TRAINER_GRUNT_MT_PYRE_3":25,"TRAINER_GRUNT_MT_PYRE_4":569,"TRAINER_GRUNT_MUSEUM_1":20,"TRAINER_GRUNT_MUSEUM_2":21,"TRAINER_GRUNT_PETALBURG_WOODS":10,"TRAINER_GRUNT_RUSTURF_TUNNEL":16,"TRAINER_GRUNT_SEAFLOOR_CAVERN_1":6,"TRAINER_GRUNT_SEAFLOOR_CAVERN_2":7,"TRAINER_GRUNT_SEAFLOOR_CAVERN_3":8,"TRAINER_GRUNT_SEAFLOOR_CAVERN_4":14,"TRAINER_GRUNT_SEAFLOOR_CAVERN_5":567,"TRAINER_GRUNT_SPACE_CENTER_1":22,"TRAINER_GRUNT_SPACE_CENTER_2":116,"TRAINER_GRUNT_SPACE_CENTER_3":586,"TRAINER_GRUNT_SPACE_CENTER_4":587,"TRAINER_GRUNT_SPACE_CENTER_5":588,"TRAINER_GRUNT_SPACE_CENTER_6":589,"TRAINER_GRUNT_SPACE_CENTER_7":590,"TRAINER_GRUNT_UNUSED":568,"TRAINER_GRUNT_WEATHER_INST_1":17,"TRAINER_GRUNT_WEATHER_INST_2":18,"TRAINER_GRUNT_WEATHER_INST_3":19,"TRAINER_GRUNT_WEATHER_INST_4":26,"TRAINER_GRUNT_WEATHER_INST_5":596,"TRAINER_GWEN":59,"TRAINER_HAILEY":697,"TRAINER_HALEY_1":604,"TRAINER_HALEY_2":607,"TRAINER_HALEY_3":608,"TRAINER_HALEY_4":609,"TRAINER_HALEY_5":610,"TRAINER_HALLE":546,"TRAINER_HANNAH":244,"TRAINER_HARRISON":578,"TRAINER_HAYDEN":707,"TRAINER_HECTOR":513,"TRAINER_HEIDI":469,"TRAINER_HELENE":751,"TRAINER_HENRY":668,"TRAINER_HERMAN":167,"TRAINER_HIDEO":651,"TRAINER_HITOSHI":180,"TRAINER_HOPE":96,"TRAINER_HUDSON":510,"TRAINER_HUEY":490,"TRAINER_HUGH":399,"TRAINER_HUMBERTO":402,"TRAINER_IMANI":442,"TRAINER_IRENE":476,"TRAINER_ISAAC_1":538,"TRAINER_ISAAC_2":541,"TRAINER_ISAAC_3":542,"TRAINER_ISAAC_4":543,"TRAINER_ISAAC_5":544,"TRAINER_ISABELLA":595,"TRAINER_ISABELLE":736,"TRAINER_ISABEL_1":302,"TRAINER_ISABEL_2":303,"TRAINER_ISABEL_3":304,"TRAINER_ISABEL_4":305,"TRAINER_ISABEL_5":306,"TRAINER_ISAIAH_1":376,"TRAINER_ISAIAH_2":379,"TRAINER_ISAIAH_3":380,"TRAINER_ISAIAH_4":381,"TRAINER_ISAIAH_5":382,"TRAINER_ISOBEL":383,"TRAINER_IVAN":337,"TRAINER_JACE":204,"TRAINER_JACK":172,"TRAINER_JACKI_1":249,"TRAINER_JACKI_2":250,"TRAINER_JACKI_3":251,"TRAINER_JACKI_4":252,"TRAINER_JACKI_5":253,"TRAINER_JACKSON_1":552,"TRAINER_JACKSON_2":555,"TRAINER_JACKSON_3":556,"TRAINER_JACKSON_4":557,"TRAINER_JACKSON_5":558,"TRAINER_JACLYN":243,"TRAINER_JACOB":351,"TRAINER_JAIDEN":749,"TRAINER_JAMES_1":621,"TRAINER_JAMES_2":622,"TRAINER_JAMES_3":623,"TRAINER_JAMES_4":624,"TRAINER_JAMES_5":625,"TRAINER_JANI":418,"TRAINER_JANICE":605,"TRAINER_JARED":401,"TRAINER_JASMINE":359,"TRAINER_JAYLEN":326,"TRAINER_JAZMYN":503,"TRAINER_JEFF":202,"TRAINER_JEFFREY_1":226,"TRAINER_JEFFREY_2":228,"TRAINER_JEFFREY_3":229,"TRAINER_JEFFREY_4":230,"TRAINER_JEFFREY_5":231,"TRAINER_JENNA":560,"TRAINER_JENNIFER":95,"TRAINER_JENNY_1":449,"TRAINER_JENNY_2":465,"TRAINER_JENNY_3":466,"TRAINER_JENNY_4":467,"TRAINER_JENNY_5":468,"TRAINER_JEROME":156,"TRAINER_JERRY_1":273,"TRAINER_JERRY_2":276,"TRAINER_JERRY_3":277,"TRAINER_JERRY_4":278,"TRAINER_JERRY_5":279,"TRAINER_JESSICA_1":127,"TRAINER_JESSICA_2":132,"TRAINER_JESSICA_3":133,"TRAINER_JESSICA_4":134,"TRAINER_JESSICA_5":135,"TRAINER_JOCELYN":425,"TRAINER_JODY":91,"TRAINER_JOEY":322,"TRAINER_JOHANNA":647,"TRAINER_JOHNSON":754,"TRAINER_JOHN_AND_JAY_1":681,"TRAINER_JOHN_AND_JAY_2":682,"TRAINER_JOHN_AND_JAY_3":683,"TRAINER_JOHN_AND_JAY_4":684,"TRAINER_JOHN_AND_JAY_5":685,"TRAINER_JONAH":667,"TRAINER_JONAS":504,"TRAINER_JONATHAN":598,"TRAINER_JOSE":617,"TRAINER_JOSEPH":700,"TRAINER_JOSH":320,"TRAINER_JOSHUA":237,"TRAINER_JOSUE":738,"TRAINER_JUAN_1":272,"TRAINER_JUAN_2":798,"TRAINER_JUAN_3":799,"TRAINER_JUAN_4":800,"TRAINER_JUAN_5":801,"TRAINER_JULIE":100,"TRAINER_JULIO":566,"TRAINER_JUSTIN":215,"TRAINER_KAI":713,"TRAINER_KALEB":699,"TRAINER_KARA":457,"TRAINER_KAREN_1":280,"TRAINER_KAREN_2":282,"TRAINER_KAREN_3":283,"TRAINER_KAREN_4":284,"TRAINER_KAREN_5":285,"TRAINER_KATELYNN":325,"TRAINER_KATELYN_1":386,"TRAINER_KATELYN_2":388,"TRAINER_KATELYN_3":389,"TRAINER_KATELYN_4":390,"TRAINER_KATELYN_5":391,"TRAINER_KATE_AND_JOY":286,"TRAINER_KATHLEEN":583,"TRAINER_KATIE":455,"TRAINER_KAYLA":247,"TRAINER_KAYLEE":462,"TRAINER_KAYLEY":505,"TRAINER_KEEGAN":205,"TRAINER_KEIGO":652,"TRAINER_KEIRA":93,"TRAINER_KELVIN":507,"TRAINER_KENT":620,"TRAINER_KEVIN":171,"TRAINER_KIM_AND_IRIS":678,"TRAINER_KINDRA":106,"TRAINER_KIRA_AND_DAN_1":642,"TRAINER_KIRA_AND_DAN_2":643,"TRAINER_KIRA_AND_DAN_3":644,"TRAINER_KIRA_AND_DAN_4":645,"TRAINER_KIRA_AND_DAN_5":646,"TRAINER_KIRK":191,"TRAINER_KIYO":181,"TRAINER_KOICHI":182,"TRAINER_KOJI_1":672,"TRAINER_KOJI_2":824,"TRAINER_KOJI_3":825,"TRAINER_KOJI_4":826,"TRAINER_KOJI_5":827,"TRAINER_KYLA":443,"TRAINER_KYRA":748,"TRAINER_LAO_1":419,"TRAINER_LAO_2":421,"TRAINER_LAO_3":422,"TRAINER_LAO_4":423,"TRAINER_LAO_5":424,"TRAINER_LARRY":213,"TRAINER_LAURA":426,"TRAINER_LAUREL":463,"TRAINER_LAWRENCE":710,"TRAINER_LEAF":852,"TRAINER_LEAH":35,"TRAINER_LEA_AND_JED":641,"TRAINER_LENNY":628,"TRAINER_LEONARD":495,"TRAINER_LEONARDO":576,"TRAINER_LEONEL":762,"TRAINER_LEROY":77,"TRAINER_LILA_AND_ROY_1":687,"TRAINER_LILA_AND_ROY_2":688,"TRAINER_LILA_AND_ROY_3":689,"TRAINER_LILA_AND_ROY_4":690,"TRAINER_LILA_AND_ROY_5":691,"TRAINER_LILITH":573,"TRAINER_LINDA":461,"TRAINER_LISA_AND_RAY":692,"TRAINER_LOLA_1":57,"TRAINER_LOLA_2":60,"TRAINER_LOLA_3":61,"TRAINER_LOLA_4":62,"TRAINER_LOLA_5":63,"TRAINER_LORENZO":553,"TRAINER_LUCAS_1":629,"TRAINER_LUCAS_2":633,"TRAINER_LUCY":810,"TRAINER_LUIS":151,"TRAINER_LUNG":420,"TRAINER_LYDIA_1":545,"TRAINER_LYDIA_2":548,"TRAINER_LYDIA_3":549,"TRAINER_LYDIA_4":550,"TRAINER_LYDIA_5":551,"TRAINER_LYLE":616,"TRAINER_MACEY":591,"TRAINER_MADELINE_1":434,"TRAINER_MADELINE_2":437,"TRAINER_MADELINE_3":438,"TRAINER_MADELINE_4":439,"TRAINER_MADELINE_5":440,"TRAINER_MAKAYLA":758,"TRAINER_MARC":571,"TRAINER_MARCEL":11,"TRAINER_MARCOS":702,"TRAINER_MARIA_1":369,"TRAINER_MARIA_2":370,"TRAINER_MARIA_3":371,"TRAINER_MARIA_4":372,"TRAINER_MARIA_5":373,"TRAINER_MARIELA":848,"TRAINER_MARK":145,"TRAINER_MARLENE":752,"TRAINER_MARLEY":508,"TRAINER_MARTHA":473,"TRAINER_MARY":89,"TRAINER_MATT":30,"TRAINER_MATTHEW":157,"TRAINER_MAURA":246,"TRAINER_MAXIE_MAGMA_HIDEOUT":601,"TRAINER_MAXIE_MOSSDEEP":734,"TRAINER_MAXIE_MT_CHIMNEY":602,"TRAINER_MAY_LILYCOVE_MUDKIP":664,"TRAINER_MAY_LILYCOVE_TORCHIC":666,"TRAINER_MAY_LILYCOVE_TREECKO":665,"TRAINER_MAY_PLACEHOLDER":854,"TRAINER_MAY_ROUTE_103_MUDKIP":529,"TRAINER_MAY_ROUTE_103_TORCHIC":535,"TRAINER_MAY_ROUTE_103_TREECKO":532,"TRAINER_MAY_ROUTE_110_MUDKIP":530,"TRAINER_MAY_ROUTE_110_TORCHIC":536,"TRAINER_MAY_ROUTE_110_TREECKO":533,"TRAINER_MAY_ROUTE_119_MUDKIP":531,"TRAINER_MAY_ROUTE_119_TORCHIC":537,"TRAINER_MAY_ROUTE_119_TREECKO":534,"TRAINER_MAY_RUSTBORO_MUDKIP":600,"TRAINER_MAY_RUSTBORO_TORCHIC":769,"TRAINER_MAY_RUSTBORO_TREECKO":768,"TRAINER_MELINA":755,"TRAINER_MELISSA":124,"TRAINER_MEL_AND_PAUL":680,"TRAINER_MICAH":255,"TRAINER_MICHELLE":98,"TRAINER_MIGUEL_1":293,"TRAINER_MIGUEL_2":295,"TRAINER_MIGUEL_3":296,"TRAINER_MIGUEL_4":297,"TRAINER_MIGUEL_5":298,"TRAINER_MIKE_1":634,"TRAINER_MIKE_2":635,"TRAINER_MISSY":447,"TRAINER_MITCHELL":540,"TRAINER_MIU_AND_YUKI":484,"TRAINER_MOLLIE":137,"TRAINER_MYLES":765,"TRAINER_NANCY":472,"TRAINER_NAOMI":119,"TRAINER_NATE":582,"TRAINER_NED":340,"TRAINER_NICHOLAS":585,"TRAINER_NICOLAS_1":392,"TRAINER_NICOLAS_2":393,"TRAINER_NICOLAS_3":394,"TRAINER_NICOLAS_4":395,"TRAINER_NICOLAS_5":396,"TRAINER_NIKKI":453,"TRAINER_NOB_1":183,"TRAINER_NOB_2":184,"TRAINER_NOB_3":185,"TRAINER_NOB_4":186,"TRAINER_NOB_5":187,"TRAINER_NOLAN":342,"TRAINER_NOLAND":809,"TRAINER_NOLEN":161,"TRAINER_NONE":0,"TRAINER_NORMAN_1":269,"TRAINER_NORMAN_2":786,"TRAINER_NORMAN_3":787,"TRAINER_NORMAN_4":788,"TRAINER_NORMAN_5":789,"TRAINER_OLIVIA":130,"TRAINER_OWEN":83,"TRAINER_PABLO_1":377,"TRAINER_PABLO_2":820,"TRAINER_PABLO_3":821,"TRAINER_PABLO_4":822,"TRAINER_PABLO_5":823,"TRAINER_PARKER":72,"TRAINER_PAT":766,"TRAINER_PATRICIA":105,"TRAINER_PAUL":275,"TRAINER_PAULA":429,"TRAINER_PAXTON":594,"TRAINER_PERRY":398,"TRAINER_PETE":735,"TRAINER_PHIL":400,"TRAINER_PHILLIP":494,"TRAINER_PHOEBE":262,"TRAINER_PRESLEY":403,"TRAINER_PRESTON":233,"TRAINER_QUINCY":324,"TRAINER_RACHEL":761,"TRAINER_RANDALL":71,"TRAINER_RED":851,"TRAINER_REED":675,"TRAINER_RELI_AND_IAN":686,"TRAINER_REYNA":509,"TRAINER_RHETT":703,"TRAINER_RICHARD":166,"TRAINER_RICK":615,"TRAINER_RICKY_1":64,"TRAINER_RICKY_2":67,"TRAINER_RICKY_3":68,"TRAINER_RICKY_4":69,"TRAINER_RICKY_5":70,"TRAINER_RILEY":653,"TRAINER_ROBERT_1":406,"TRAINER_ROBERT_2":409,"TRAINER_ROBERT_3":410,"TRAINER_ROBERT_4":411,"TRAINER_ROBERT_5":412,"TRAINER_ROBIN":612,"TRAINER_RODNEY":165,"TRAINER_ROGER":669,"TRAINER_ROLAND":160,"TRAINER_RONALD":350,"TRAINER_ROSE_1":37,"TRAINER_ROSE_2":40,"TRAINER_ROSE_3":41,"TRAINER_ROSE_4":42,"TRAINER_ROSE_5":43,"TRAINER_ROXANNE_1":265,"TRAINER_ROXANNE_2":770,"TRAINER_ROXANNE_3":771,"TRAINER_ROXANNE_4":772,"TRAINER_ROXANNE_5":773,"TRAINER_RUBEN":671,"TRAINER_SALLY":611,"TRAINER_SAMANTHA":245,"TRAINER_SAMUEL":81,"TRAINER_SANTIAGO":168,"TRAINER_SARAH":695,"TRAINER_SAWYER_1":1,"TRAINER_SAWYER_2":836,"TRAINER_SAWYER_3":837,"TRAINER_SAWYER_4":838,"TRAINER_SAWYER_5":839,"TRAINER_SEBASTIAN":554,"TRAINER_SHANE":214,"TRAINER_SHANNON":97,"TRAINER_SHARON":452,"TRAINER_SHAWN":194,"TRAINER_SHAYLA":747,"TRAINER_SHEILA":125,"TRAINER_SHELBY_1":313,"TRAINER_SHELBY_2":314,"TRAINER_SHELBY_3":315,"TRAINER_SHELBY_4":316,"TRAINER_SHELBY_5":317,"TRAINER_SHELLY_SEAFLOOR_CAVERN":33,"TRAINER_SHELLY_WEATHER_INSTITUTE":32,"TRAINER_SHIRLEY":126,"TRAINER_SIDNEY":261,"TRAINER_SIENNA":459,"TRAINER_SIMON":65,"TRAINER_SOPHIA":561,"TRAINER_SOPHIE":708,"TRAINER_SPENCER":159,"TRAINER_SPENSER":807,"TRAINER_STAN":162,"TRAINER_STEVEN":804,"TRAINER_STEVE_1":143,"TRAINER_STEVE_2":147,"TRAINER_STEVE_3":148,"TRAINER_STEVE_4":149,"TRAINER_STEVE_5":150,"TRAINER_SUSIE":456,"TRAINER_SYLVIA":575,"TRAINER_TABITHA_MAGMA_HIDEOUT":732,"TRAINER_TABITHA_MOSSDEEP":514,"TRAINER_TABITHA_MT_CHIMNEY":597,"TRAINER_TAKAO":179,"TRAINER_TAKASHI":416,"TRAINER_TALIA":385,"TRAINER_TAMMY":107,"TRAINER_TANYA":451,"TRAINER_TARA":446,"TRAINER_TASHA":109,"TRAINER_TATE_AND_LIZA_1":271,"TRAINER_TATE_AND_LIZA_2":794,"TRAINER_TATE_AND_LIZA_3":795,"TRAINER_TATE_AND_LIZA_4":796,"TRAINER_TATE_AND_LIZA_5":797,"TRAINER_TAYLOR":225,"TRAINER_TED":274,"TRAINER_TERRY":581,"TRAINER_THALIA_1":144,"TRAINER_THALIA_2":844,"TRAINER_THALIA_3":845,"TRAINER_THALIA_4":846,"TRAINER_THALIA_5":847,"TRAINER_THOMAS":256,"TRAINER_TIANA":603,"TRAINER_TIFFANY":131,"TRAINER_TIMMY":334,"TRAINER_TIMOTHY_1":307,"TRAINER_TIMOTHY_2":308,"TRAINER_TIMOTHY_3":309,"TRAINER_TIMOTHY_4":310,"TRAINER_TIMOTHY_5":311,"TRAINER_TISHA":676,"TRAINER_TOMMY":321,"TRAINER_TONY_1":155,"TRAINER_TONY_2":175,"TRAINER_TONY_3":176,"TRAINER_TONY_4":177,"TRAINER_TONY_5":178,"TRAINER_TORI_AND_TIA":677,"TRAINER_TRAVIS":218,"TRAINER_TRENT_1":627,"TRAINER_TRENT_2":636,"TRAINER_TRENT_3":637,"TRAINER_TRENT_4":638,"TRAINER_TRENT_5":639,"TRAINER_TUCKER":806,"TRAINER_TYRA_AND_IVY":679,"TRAINER_TYRON":704,"TRAINER_VALERIE_1":108,"TRAINER_VALERIE_2":110,"TRAINER_VALERIE_3":111,"TRAINER_VALERIE_4":112,"TRAINER_VALERIE_5":113,"TRAINER_VANESSA":300,"TRAINER_VICKY":312,"TRAINER_VICTOR":292,"TRAINER_VICTORIA":299,"TRAINER_VINCENT":76,"TRAINER_VIOLET":39,"TRAINER_VIRGIL":234,"TRAINER_VITO":82,"TRAINER_VIVI":606,"TRAINER_VIVIAN":649,"TRAINER_WADE":344,"TRAINER_WALLACE":335,"TRAINER_WALLY_MAUVILLE":656,"TRAINER_WALLY_VR_1":519,"TRAINER_WALLY_VR_2":657,"TRAINER_WALLY_VR_3":658,"TRAINER_WALLY_VR_4":659,"TRAINER_WALLY_VR_5":660,"TRAINER_WALTER_1":254,"TRAINER_WALTER_2":257,"TRAINER_WALTER_3":258,"TRAINER_WALTER_4":259,"TRAINER_WALTER_5":260,"TRAINER_WARREN":88,"TRAINER_WATTSON_1":267,"TRAINER_WATTSON_2":778,"TRAINER_WATTSON_3":779,"TRAINER_WATTSON_4":780,"TRAINER_WATTSON_5":781,"TRAINER_WAYNE":673,"TRAINER_WENDY":92,"TRAINER_WILLIAM":236,"TRAINER_WILTON_1":78,"TRAINER_WILTON_2":84,"TRAINER_WILTON_3":85,"TRAINER_WILTON_4":86,"TRAINER_WILTON_5":87,"TRAINER_WINONA_1":270,"TRAINER_WINONA_2":790,"TRAINER_WINONA_3":791,"TRAINER_WINONA_4":792,"TRAINER_WINONA_5":793,"TRAINER_WINSTON_1":136,"TRAINER_WINSTON_2":139,"TRAINER_WINSTON_3":140,"TRAINER_WINSTON_4":141,"TRAINER_WINSTON_5":142,"TRAINER_WYATT":711,"TRAINER_YASU":415,"TRAINER_YUJI":188,"TRAINER_ZANDER":31},"legendary_encounters":[{"address":2538600,"catch_flag":429,"defeat_flag":428,"level":30,"species":410},{"address":2354334,"catch_flag":480,"defeat_flag":447,"level":70,"species":405},{"address":2543160,"catch_flag":146,"defeat_flag":476,"level":70,"species":250},{"address":2354112,"catch_flag":479,"defeat_flag":446,"level":70,"species":404},{"address":2385623,"catch_flag":457,"defeat_flag":456,"level":50,"species":407},{"address":2385687,"catch_flag":482,"defeat_flag":481,"level":50,"species":408},{"address":2543443,"catch_flag":145,"defeat_flag":477,"level":70,"species":249},{"address":2538177,"catch_flag":458,"defeat_flag":455,"level":30,"species":151},{"address":2347488,"catch_flag":478,"defeat_flag":448,"level":70,"species":406},{"address":2345460,"catch_flag":427,"defeat_flag":444,"level":40,"species":402},{"address":2298183,"catch_flag":426,"defeat_flag":443,"level":40,"species":401},{"address":2345731,"catch_flag":483,"defeat_flag":445,"level":40,"species":403}],"locations":{"BADGE_1":{"address":2188036,"default_item":226,"flag":1182},"BADGE_2":{"address":2095131,"default_item":227,"flag":1183},"BADGE_3":{"address":2167252,"default_item":228,"flag":1184},"BADGE_4":{"address":2103246,"default_item":229,"flag":1185},"BADGE_5":{"address":2129781,"default_item":230,"flag":1186},"BADGE_6":{"address":2202122,"default_item":231,"flag":1187},"BADGE_7":{"address":2243964,"default_item":232,"flag":1188},"BADGE_8":{"address":2262314,"default_item":233,"flag":1189},"BERRY_TREE_01":{"address":5843562,"default_item":135,"flag":612},"BERRY_TREE_02":{"address":5843564,"default_item":139,"flag":613},"BERRY_TREE_03":{"address":5843566,"default_item":142,"flag":614},"BERRY_TREE_04":{"address":5843568,"default_item":139,"flag":615},"BERRY_TREE_05":{"address":5843570,"default_item":133,"flag":616},"BERRY_TREE_06":{"address":5843572,"default_item":138,"flag":617},"BERRY_TREE_07":{"address":5843574,"default_item":133,"flag":618},"BERRY_TREE_08":{"address":5843576,"default_item":133,"flag":619},"BERRY_TREE_09":{"address":5843578,"default_item":142,"flag":620},"BERRY_TREE_10":{"address":5843580,"default_item":138,"flag":621},"BERRY_TREE_11":{"address":5843582,"default_item":139,"flag":622},"BERRY_TREE_12":{"address":5843584,"default_item":142,"flag":623},"BERRY_TREE_13":{"address":5843586,"default_item":135,"flag":624},"BERRY_TREE_14":{"address":5843588,"default_item":155,"flag":625},"BERRY_TREE_15":{"address":5843590,"default_item":153,"flag":626},"BERRY_TREE_16":{"address":5843592,"default_item":150,"flag":627},"BERRY_TREE_17":{"address":5843594,"default_item":150,"flag":628},"BERRY_TREE_18":{"address":5843596,"default_item":150,"flag":629},"BERRY_TREE_19":{"address":5843598,"default_item":148,"flag":630},"BERRY_TREE_20":{"address":5843600,"default_item":148,"flag":631},"BERRY_TREE_21":{"address":5843602,"default_item":136,"flag":632},"BERRY_TREE_22":{"address":5843604,"default_item":135,"flag":633},"BERRY_TREE_23":{"address":5843606,"default_item":135,"flag":634},"BERRY_TREE_24":{"address":5843608,"default_item":136,"flag":635},"BERRY_TREE_25":{"address":5843610,"default_item":152,"flag":636},"BERRY_TREE_26":{"address":5843612,"default_item":134,"flag":637},"BERRY_TREE_27":{"address":5843614,"default_item":151,"flag":638},"BERRY_TREE_28":{"address":5843616,"default_item":151,"flag":639},"BERRY_TREE_29":{"address":5843618,"default_item":151,"flag":640},"BERRY_TREE_30":{"address":5843620,"default_item":153,"flag":641},"BERRY_TREE_31":{"address":5843622,"default_item":142,"flag":642},"BERRY_TREE_32":{"address":5843624,"default_item":142,"flag":643},"BERRY_TREE_33":{"address":5843626,"default_item":142,"flag":644},"BERRY_TREE_34":{"address":5843628,"default_item":153,"flag":645},"BERRY_TREE_35":{"address":5843630,"default_item":153,"flag":646},"BERRY_TREE_36":{"address":5843632,"default_item":153,"flag":647},"BERRY_TREE_37":{"address":5843634,"default_item":137,"flag":648},"BERRY_TREE_38":{"address":5843636,"default_item":137,"flag":649},"BERRY_TREE_39":{"address":5843638,"default_item":137,"flag":650},"BERRY_TREE_40":{"address":5843640,"default_item":135,"flag":651},"BERRY_TREE_41":{"address":5843642,"default_item":135,"flag":652},"BERRY_TREE_42":{"address":5843644,"default_item":135,"flag":653},"BERRY_TREE_43":{"address":5843646,"default_item":148,"flag":654},"BERRY_TREE_44":{"address":5843648,"default_item":150,"flag":655},"BERRY_TREE_45":{"address":5843650,"default_item":152,"flag":656},"BERRY_TREE_46":{"address":5843652,"default_item":151,"flag":657},"BERRY_TREE_47":{"address":5843654,"default_item":140,"flag":658},"BERRY_TREE_48":{"address":5843656,"default_item":137,"flag":659},"BERRY_TREE_49":{"address":5843658,"default_item":136,"flag":660},"BERRY_TREE_50":{"address":5843660,"default_item":134,"flag":661},"BERRY_TREE_51":{"address":5843662,"default_item":142,"flag":662},"BERRY_TREE_52":{"address":5843664,"default_item":150,"flag":663},"BERRY_TREE_53":{"address":5843666,"default_item":150,"flag":664},"BERRY_TREE_54":{"address":5843668,"default_item":142,"flag":665},"BERRY_TREE_55":{"address":5843670,"default_item":149,"flag":666},"BERRY_TREE_56":{"address":5843672,"default_item":149,"flag":667},"BERRY_TREE_57":{"address":5843674,"default_item":136,"flag":668},"BERRY_TREE_58":{"address":5843676,"default_item":153,"flag":669},"BERRY_TREE_59":{"address":5843678,"default_item":153,"flag":670},"BERRY_TREE_60":{"address":5843680,"default_item":157,"flag":671},"BERRY_TREE_61":{"address":5843682,"default_item":157,"flag":672},"BERRY_TREE_62":{"address":5843684,"default_item":138,"flag":673},"BERRY_TREE_63":{"address":5843686,"default_item":142,"flag":674},"BERRY_TREE_64":{"address":5843688,"default_item":138,"flag":675},"BERRY_TREE_65":{"address":5843690,"default_item":157,"flag":676},"BERRY_TREE_66":{"address":5843692,"default_item":134,"flag":677},"BERRY_TREE_67":{"address":5843694,"default_item":152,"flag":678},"BERRY_TREE_68":{"address":5843696,"default_item":140,"flag":679},"BERRY_TREE_69":{"address":5843698,"default_item":154,"flag":680},"BERRY_TREE_70":{"address":5843700,"default_item":154,"flag":681},"BERRY_TREE_71":{"address":5843702,"default_item":154,"flag":682},"BERRY_TREE_72":{"address":5843704,"default_item":157,"flag":683},"BERRY_TREE_73":{"address":5843706,"default_item":155,"flag":684},"BERRY_TREE_74":{"address":5843708,"default_item":155,"flag":685},"BERRY_TREE_75":{"address":5843710,"default_item":142,"flag":686},"BERRY_TREE_76":{"address":5843712,"default_item":133,"flag":687},"BERRY_TREE_77":{"address":5843714,"default_item":140,"flag":688},"BERRY_TREE_78":{"address":5843716,"default_item":140,"flag":689},"BERRY_TREE_79":{"address":5843718,"default_item":155,"flag":690},"BERRY_TREE_80":{"address":5843720,"default_item":139,"flag":691},"BERRY_TREE_81":{"address":5843722,"default_item":139,"flag":692},"BERRY_TREE_82":{"address":5843724,"default_item":168,"flag":693},"BERRY_TREE_83":{"address":5843726,"default_item":156,"flag":694},"BERRY_TREE_84":{"address":5843728,"default_item":156,"flag":695},"BERRY_TREE_85":{"address":5843730,"default_item":142,"flag":696},"BERRY_TREE_86":{"address":5843732,"default_item":138,"flag":697},"BERRY_TREE_87":{"address":5843734,"default_item":135,"flag":698},"BERRY_TREE_88":{"address":5843736,"default_item":142,"flag":699},"HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":{"address":5497200,"default_item":281,"flag":531},"HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":{"address":5497212,"default_item":282,"flag":532},"HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":{"address":5497224,"default_item":283,"flag":533},"HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":{"address":5497236,"default_item":284,"flag":534},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":{"address":5500100,"default_item":67,"flag":601},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":{"address":5500124,"default_item":65,"flag":604},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":{"address":5500112,"default_item":64,"flag":603},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":{"address":5500088,"default_item":70,"flag":602},"HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":{"address":5435924,"default_item":110,"flag":528},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":{"address":5487372,"default_item":195,"flag":548},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":{"address":5487384,"default_item":195,"flag":549},"HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":{"address":5489116,"default_item":23,"flag":577},"HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":{"address":5489128,"default_item":3,"flag":576},"HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":{"address":5435672,"default_item":16,"flag":500},"HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":{"address":5432608,"default_item":111,"flag":527},"HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":{"address":5432632,"default_item":4,"flag":575},"HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":{"address":5432620,"default_item":69,"flag":543},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":{"address":5490440,"default_item":35,"flag":578},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":{"address":5490428,"default_item":2,"flag":529},"HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":{"address":5490796,"default_item":68,"flag":580},"HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":{"address":5490784,"default_item":70,"flag":579},"HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":{"address":5525804,"default_item":45,"flag":609},"HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":{"address":5428972,"default_item":68,"flag":595},"HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":{"address":5487908,"default_item":4,"flag":561},"HIDDEN_ITEM_PETALBURG_WOODS_POTION":{"address":5487872,"default_item":13,"flag":558},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":{"address":5487884,"default_item":103,"flag":559},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":{"address":5487896,"default_item":103,"flag":560},"HIDDEN_ITEM_ROUTE_104_ANTIDOTE":{"address":5438492,"default_item":14,"flag":585},"HIDDEN_ITEM_ROUTE_104_HEART_SCALE":{"address":5438504,"default_item":111,"flag":588},"HIDDEN_ITEM_ROUTE_104_POKE_BALL":{"address":5438468,"default_item":4,"flag":562},"HIDDEN_ITEM_ROUTE_104_POTION":{"address":5438480,"default_item":13,"flag":537},"HIDDEN_ITEM_ROUTE_104_SUPER_POTION":{"address":5438456,"default_item":22,"flag":544},"HIDDEN_ITEM_ROUTE_105_BIG_PEARL":{"address":5438748,"default_item":107,"flag":611},"HIDDEN_ITEM_ROUTE_105_HEART_SCALE":{"address":5438736,"default_item":111,"flag":589},"HIDDEN_ITEM_ROUTE_106_HEART_SCALE":{"address":5438932,"default_item":111,"flag":547},"HIDDEN_ITEM_ROUTE_106_POKE_BALL":{"address":5438908,"default_item":4,"flag":563},"HIDDEN_ITEM_ROUTE_106_STARDUST":{"address":5438920,"default_item":108,"flag":546},"HIDDEN_ITEM_ROUTE_108_RARE_CANDY":{"address":5439340,"default_item":68,"flag":586},"HIDDEN_ITEM_ROUTE_109_ETHER":{"address":5440016,"default_item":34,"flag":564},"HIDDEN_ITEM_ROUTE_109_GREAT_BALL":{"address":5440004,"default_item":3,"flag":551},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":{"address":5439992,"default_item":111,"flag":552},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":{"address":5440028,"default_item":111,"flag":590},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":{"address":5440040,"default_item":111,"flag":591},"HIDDEN_ITEM_ROUTE_109_REVIVE":{"address":5439980,"default_item":24,"flag":550},"HIDDEN_ITEM_ROUTE_110_FULL_HEAL":{"address":5441308,"default_item":23,"flag":555},"HIDDEN_ITEM_ROUTE_110_GREAT_BALL":{"address":5441284,"default_item":3,"flag":553},"HIDDEN_ITEM_ROUTE_110_POKE_BALL":{"address":5441296,"default_item":4,"flag":565},"HIDDEN_ITEM_ROUTE_110_REVIVE":{"address":5441272,"default_item":24,"flag":554},"HIDDEN_ITEM_ROUTE_111_PROTEIN":{"address":5443220,"default_item":64,"flag":556},"HIDDEN_ITEM_ROUTE_111_RARE_CANDY":{"address":5443232,"default_item":68,"flag":557},"HIDDEN_ITEM_ROUTE_111_STARDUST":{"address":5443160,"default_item":108,"flag":502},"HIDDEN_ITEM_ROUTE_113_ETHER":{"address":5444488,"default_item":34,"flag":503},"HIDDEN_ITEM_ROUTE_113_NUGGET":{"address":5444512,"default_item":110,"flag":598},"HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":{"address":5444500,"default_item":320,"flag":530},"HIDDEN_ITEM_ROUTE_114_CARBOS":{"address":5445340,"default_item":66,"flag":504},"HIDDEN_ITEM_ROUTE_114_REVIVE":{"address":5445364,"default_item":24,"flag":542},"HIDDEN_ITEM_ROUTE_115_HEART_SCALE":{"address":5446176,"default_item":111,"flag":597},"HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":{"address":5447056,"default_item":206,"flag":596},"HIDDEN_ITEM_ROUTE_116_SUPER_POTION":{"address":5447044,"default_item":22,"flag":545},"HIDDEN_ITEM_ROUTE_117_REPEL":{"address":5447708,"default_item":86,"flag":572},"HIDDEN_ITEM_ROUTE_118_HEART_SCALE":{"address":5448404,"default_item":111,"flag":566},"HIDDEN_ITEM_ROUTE_118_IRON":{"address":5448392,"default_item":65,"flag":567},"HIDDEN_ITEM_ROUTE_119_CALCIUM":{"address":5449972,"default_item":67,"flag":505},"HIDDEN_ITEM_ROUTE_119_FULL_HEAL":{"address":5450056,"default_item":23,"flag":568},"HIDDEN_ITEM_ROUTE_119_MAX_ETHER":{"address":5450068,"default_item":35,"flag":587},"HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":{"address":5449984,"default_item":2,"flag":506},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":{"address":5451596,"default_item":68,"flag":571},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":{"address":5451620,"default_item":68,"flag":569},"HIDDEN_ITEM_ROUTE_120_REVIVE":{"address":5451608,"default_item":24,"flag":584},"HIDDEN_ITEM_ROUTE_120_ZINC":{"address":5451632,"default_item":70,"flag":570},"HIDDEN_ITEM_ROUTE_121_FULL_HEAL":{"address":5452540,"default_item":23,"flag":573},"HIDDEN_ITEM_ROUTE_121_HP_UP":{"address":5452516,"default_item":63,"flag":539},"HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":{"address":5452552,"default_item":25,"flag":600},"HIDDEN_ITEM_ROUTE_121_NUGGET":{"address":5452528,"default_item":110,"flag":540},"HIDDEN_ITEM_ROUTE_123_HYPER_POTION":{"address":5454100,"default_item":21,"flag":574},"HIDDEN_ITEM_ROUTE_123_PP_UP":{"address":5454112,"default_item":69,"flag":599},"HIDDEN_ITEM_ROUTE_123_RARE_CANDY":{"address":5454124,"default_item":68,"flag":610},"HIDDEN_ITEM_ROUTE_123_REVIVE":{"address":5454088,"default_item":24,"flag":541},"HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":{"address":5454052,"default_item":83,"flag":507},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":{"address":5455620,"default_item":111,"flag":592},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":{"address":5455632,"default_item":111,"flag":593},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":{"address":5455644,"default_item":111,"flag":594},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":{"address":5517256,"default_item":68,"flag":606},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":{"address":5517268,"default_item":70,"flag":607},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":{"address":5517432,"default_item":19,"flag":605},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":{"address":5517420,"default_item":69,"flag":608},"HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":{"address":5511292,"default_item":200,"flag":535},"HIDDEN_ITEM_TRICK_HOUSE_NUGGET":{"address":5526716,"default_item":110,"flag":501},"HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":{"address":5456992,"default_item":107,"flag":511},"HIDDEN_ITEM_UNDERWATER_124_CALCIUM":{"address":5457016,"default_item":67,"flag":536},"HIDDEN_ITEM_UNDERWATER_124_CARBOS":{"address":5456956,"default_item":66,"flag":508},"HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":{"address":5456968,"default_item":51,"flag":509},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":{"address":5457004,"default_item":111,"flag":513},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":{"address":5457028,"default_item":111,"flag":538},"HIDDEN_ITEM_UNDERWATER_124_PEARL":{"address":5456980,"default_item":106,"flag":510},"HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":{"address":5457140,"default_item":107,"flag":520},"HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":{"address":5457152,"default_item":49,"flag":512},"HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":{"address":5457068,"default_item":111,"flag":514},"HIDDEN_ITEM_UNDERWATER_126_IRON":{"address":5457116,"default_item":65,"flag":519},"HIDDEN_ITEM_UNDERWATER_126_PEARL":{"address":5457104,"default_item":106,"flag":517},"HIDDEN_ITEM_UNDERWATER_126_STARDUST":{"address":5457092,"default_item":108,"flag":516},"HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":{"address":5457080,"default_item":2,"flag":515},"HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":{"address":5457128,"default_item":50,"flag":518},"HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":{"address":5457224,"default_item":111,"flag":523},"HIDDEN_ITEM_UNDERWATER_127_HP_UP":{"address":5457212,"default_item":63,"flag":522},"HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":{"address":5457236,"default_item":48,"flag":524},"HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":{"address":5457200,"default_item":109,"flag":521},"HIDDEN_ITEM_UNDERWATER_128_PEARL":{"address":5457288,"default_item":106,"flag":526},"HIDDEN_ITEM_UNDERWATER_128_PROTEIN":{"address":5457276,"default_item":64,"flag":525},"HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":{"address":5493932,"default_item":2,"flag":581},"HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":{"address":5494744,"default_item":36,"flag":582},"HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":{"address":5494756,"default_item":84,"flag":583},"ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":{"address":2709805,"default_item":285,"flag":1100},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":{"address":2709857,"default_item":306,"flag":1102},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":{"address":2709831,"default_item":278,"flag":1078},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":{"address":2709844,"default_item":97,"flag":1101},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":{"address":2709818,"default_item":11,"flag":1077},"ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":{"address":2709740,"default_item":122,"flag":1095},"ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":{"address":2709792,"default_item":24,"flag":1099},"ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":{"address":2709766,"default_item":7,"flag":1097},"ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":{"address":2709753,"default_item":85,"flag":1096},"ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":{"address":2709779,"default_item":301,"flag":1098},"ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":{"address":2710039,"default_item":1,"flag":1124},"ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":{"address":2710065,"default_item":37,"flag":1071},"ITEM_AQUA_HIDEOUT_B1F_NUGGET":{"address":2710052,"default_item":110,"flag":1132},"ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":{"address":2710078,"default_item":8,"flag":1072},"ITEM_ARTISAN_CAVE_1F_CARBOS":{"address":2710416,"default_item":66,"flag":1163},"ITEM_ARTISAN_CAVE_B1F_HP_UP":{"address":2710403,"default_item":63,"flag":1162},"ITEM_FIERY_PATH_FIRE_STONE":{"address":2709584,"default_item":95,"flag":1111},"ITEM_FIERY_PATH_TM_TOXIC":{"address":2709597,"default_item":294,"flag":1091},"ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":{"address":2709519,"default_item":85,"flag":1050},"ITEM_GRANITE_CAVE_B1F_POKE_BALL":{"address":2709532,"default_item":4,"flag":1051},"ITEM_GRANITE_CAVE_B2F_RARE_CANDY":{"address":2709558,"default_item":68,"flag":1054},"ITEM_GRANITE_CAVE_B2F_REPEL":{"address":2709545,"default_item":86,"flag":1053},"ITEM_JAGGED_PASS_BURN_HEAL":{"address":2709571,"default_item":15,"flag":1070},"ITEM_LILYCOVE_CITY_MAX_REPEL":{"address":2709415,"default_item":84,"flag":1042},"ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":{"address":2710429,"default_item":68,"flag":1151},"ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":{"address":2710455,"default_item":19,"flag":1165},"ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":{"address":2710442,"default_item":37,"flag":1164},"ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":{"address":2710468,"default_item":110,"flag":1166},"ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":{"address":2710481,"default_item":71,"flag":1167},"ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":{"address":2710507,"default_item":85,"flag":1059},"ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":{"address":2710494,"default_item":25,"flag":1168},"ITEM_MAUVILLE_CITY_X_SPEED":{"address":2709389,"default_item":77,"flag":1116},"ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":{"address":2709623,"default_item":23,"flag":1045},"ITEM_METEOR_FALLS_1F_1R_MOON_STONE":{"address":2709636,"default_item":94,"flag":1046},"ITEM_METEOR_FALLS_1F_1R_PP_UP":{"address":2709649,"default_item":69,"flag":1047},"ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":{"address":2709610,"default_item":311,"flag":1044},"ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":{"address":2709662,"default_item":290,"flag":1080},"ITEM_MOSSDEEP_CITY_NET_BALL":{"address":2709428,"default_item":6,"flag":1043},"ITEM_MT_PYRE_2F_ULTRA_BALL":{"address":2709948,"default_item":2,"flag":1129},"ITEM_MT_PYRE_3F_SUPER_REPEL":{"address":2709961,"default_item":83,"flag":1120},"ITEM_MT_PYRE_4F_SEA_INCENSE":{"address":2709974,"default_item":220,"flag":1130},"ITEM_MT_PYRE_5F_LAX_INCENSE":{"address":2709987,"default_item":221,"flag":1052},"ITEM_MT_PYRE_6F_TM_SHADOW_BALL":{"address":2710000,"default_item":318,"flag":1089},"ITEM_MT_PYRE_EXTERIOR_MAX_POTION":{"address":2710013,"default_item":20,"flag":1073},"ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":{"address":2710026,"default_item":336,"flag":1074},"ITEM_NEW_MAUVILLE_ESCAPE_ROPE":{"address":2709688,"default_item":85,"flag":1076},"ITEM_NEW_MAUVILLE_FULL_HEAL":{"address":2709714,"default_item":23,"flag":1122},"ITEM_NEW_MAUVILLE_PARALYZE_HEAL":{"address":2709727,"default_item":18,"flag":1123},"ITEM_NEW_MAUVILLE_THUNDER_STONE":{"address":2709701,"default_item":96,"flag":1110},"ITEM_NEW_MAUVILLE_ULTRA_BALL":{"address":2709675,"default_item":2,"flag":1075},"ITEM_PETALBURG_CITY_ETHER":{"address":2709376,"default_item":34,"flag":1040},"ITEM_PETALBURG_CITY_MAX_REVIVE":{"address":2709363,"default_item":25,"flag":1039},"ITEM_PETALBURG_WOODS_ETHER":{"address":2709467,"default_item":34,"flag":1058},"ITEM_PETALBURG_WOODS_GREAT_BALL":{"address":2709454,"default_item":3,"flag":1056},"ITEM_PETALBURG_WOODS_PARALYZE_HEAL":{"address":2709480,"default_item":18,"flag":1117},"ITEM_PETALBURG_WOODS_X_ATTACK":{"address":2709441,"default_item":75,"flag":1055},"ITEM_ROUTE_102_POTION":{"address":2708375,"default_item":13,"flag":1000},"ITEM_ROUTE_103_GUARD_SPEC":{"address":2708388,"default_item":73,"flag":1114},"ITEM_ROUTE_103_PP_UP":{"address":2708401,"default_item":69,"flag":1137},"ITEM_ROUTE_104_POKE_BALL":{"address":2708427,"default_item":4,"flag":1057},"ITEM_ROUTE_104_POTION":{"address":2708453,"default_item":13,"flag":1135},"ITEM_ROUTE_104_PP_UP":{"address":2708414,"default_item":69,"flag":1002},"ITEM_ROUTE_104_X_ACCURACY":{"address":2708440,"default_item":78,"flag":1115},"ITEM_ROUTE_105_IRON":{"address":2708466,"default_item":65,"flag":1003},"ITEM_ROUTE_106_PROTEIN":{"address":2708479,"default_item":64,"flag":1004},"ITEM_ROUTE_108_STAR_PIECE":{"address":2708492,"default_item":109,"flag":1139},"ITEM_ROUTE_109_POTION":{"address":2708518,"default_item":13,"flag":1140},"ITEM_ROUTE_109_PP_UP":{"address":2708505,"default_item":69,"flag":1005},"ITEM_ROUTE_110_DIRE_HIT":{"address":2708544,"default_item":74,"flag":1007},"ITEM_ROUTE_110_ELIXIR":{"address":2708557,"default_item":36,"flag":1141},"ITEM_ROUTE_110_RARE_CANDY":{"address":2708531,"default_item":68,"flag":1006},"ITEM_ROUTE_111_ELIXIR":{"address":2708609,"default_item":36,"flag":1142},"ITEM_ROUTE_111_HP_UP":{"address":2708596,"default_item":63,"flag":1010},"ITEM_ROUTE_111_STARDUST":{"address":2708583,"default_item":108,"flag":1009},"ITEM_ROUTE_111_TM_SANDSTORM":{"address":2708570,"default_item":325,"flag":1008},"ITEM_ROUTE_112_NUGGET":{"address":2708622,"default_item":110,"flag":1011},"ITEM_ROUTE_113_HYPER_POTION":{"address":2708661,"default_item":21,"flag":1143},"ITEM_ROUTE_113_MAX_ETHER":{"address":2708635,"default_item":35,"flag":1012},"ITEM_ROUTE_113_SUPER_REPEL":{"address":2708648,"default_item":83,"flag":1013},"ITEM_ROUTE_114_ENERGY_POWDER":{"address":2708700,"default_item":30,"flag":1160},"ITEM_ROUTE_114_PROTEIN":{"address":2708687,"default_item":64,"flag":1015},"ITEM_ROUTE_114_RARE_CANDY":{"address":2708674,"default_item":68,"flag":1014},"ITEM_ROUTE_115_GREAT_BALL":{"address":2708752,"default_item":3,"flag":1118},"ITEM_ROUTE_115_HEAL_POWDER":{"address":2708765,"default_item":32,"flag":1144},"ITEM_ROUTE_115_IRON":{"address":2708739,"default_item":65,"flag":1018},"ITEM_ROUTE_115_PP_UP":{"address":2708778,"default_item":69,"flag":1161},"ITEM_ROUTE_115_SUPER_POTION":{"address":2708713,"default_item":22,"flag":1016},"ITEM_ROUTE_115_TM_FOCUS_PUNCH":{"address":2708726,"default_item":289,"flag":1017},"ITEM_ROUTE_116_ETHER":{"address":2708804,"default_item":34,"flag":1019},"ITEM_ROUTE_116_HP_UP":{"address":2708830,"default_item":63,"flag":1021},"ITEM_ROUTE_116_POTION":{"address":2708843,"default_item":13,"flag":1146},"ITEM_ROUTE_116_REPEL":{"address":2708817,"default_item":86,"flag":1020},"ITEM_ROUTE_116_X_SPECIAL":{"address":2708791,"default_item":79,"flag":1001},"ITEM_ROUTE_117_GREAT_BALL":{"address":2708856,"default_item":3,"flag":1022},"ITEM_ROUTE_117_REVIVE":{"address":2708869,"default_item":24,"flag":1023},"ITEM_ROUTE_118_HYPER_POTION":{"address":2708882,"default_item":21,"flag":1121},"ITEM_ROUTE_119_ELIXIR_1":{"address":2708921,"default_item":36,"flag":1026},"ITEM_ROUTE_119_ELIXIR_2":{"address":2708986,"default_item":36,"flag":1147},"ITEM_ROUTE_119_HYPER_POTION_1":{"address":2708960,"default_item":21,"flag":1029},"ITEM_ROUTE_119_HYPER_POTION_2":{"address":2708973,"default_item":21,"flag":1106},"ITEM_ROUTE_119_LEAF_STONE":{"address":2708934,"default_item":98,"flag":1027},"ITEM_ROUTE_119_NUGGET":{"address":2710104,"default_item":110,"flag":1134},"ITEM_ROUTE_119_RARE_CANDY":{"address":2708947,"default_item":68,"flag":1028},"ITEM_ROUTE_119_SUPER_REPEL":{"address":2708895,"default_item":83,"flag":1024},"ITEM_ROUTE_119_ZINC":{"address":2708908,"default_item":70,"flag":1025},"ITEM_ROUTE_120_FULL_HEAL":{"address":2709012,"default_item":23,"flag":1031},"ITEM_ROUTE_120_HYPER_POTION":{"address":2709025,"default_item":21,"flag":1107},"ITEM_ROUTE_120_NEST_BALL":{"address":2709038,"default_item":8,"flag":1108},"ITEM_ROUTE_120_NUGGET":{"address":2708999,"default_item":110,"flag":1030},"ITEM_ROUTE_120_REVIVE":{"address":2709051,"default_item":24,"flag":1148},"ITEM_ROUTE_121_CARBOS":{"address":2709064,"default_item":66,"flag":1103},"ITEM_ROUTE_121_REVIVE":{"address":2709077,"default_item":24,"flag":1149},"ITEM_ROUTE_121_ZINC":{"address":2709090,"default_item":70,"flag":1150},"ITEM_ROUTE_123_CALCIUM":{"address":2709103,"default_item":67,"flag":1032},"ITEM_ROUTE_123_ELIXIR":{"address":2709129,"default_item":36,"flag":1109},"ITEM_ROUTE_123_PP_UP":{"address":2709142,"default_item":69,"flag":1152},"ITEM_ROUTE_123_REVIVAL_HERB":{"address":2709155,"default_item":33,"flag":1153},"ITEM_ROUTE_123_ULTRA_BALL":{"address":2709116,"default_item":2,"flag":1104},"ITEM_ROUTE_124_BLUE_SHARD":{"address":2709181,"default_item":49,"flag":1093},"ITEM_ROUTE_124_RED_SHARD":{"address":2709168,"default_item":48,"flag":1092},"ITEM_ROUTE_124_YELLOW_SHARD":{"address":2709194,"default_item":50,"flag":1066},"ITEM_ROUTE_125_BIG_PEARL":{"address":2709207,"default_item":107,"flag":1154},"ITEM_ROUTE_126_GREEN_SHARD":{"address":2709220,"default_item":51,"flag":1105},"ITEM_ROUTE_127_CARBOS":{"address":2709246,"default_item":66,"flag":1035},"ITEM_ROUTE_127_RARE_CANDY":{"address":2709259,"default_item":68,"flag":1155},"ITEM_ROUTE_127_ZINC":{"address":2709233,"default_item":70,"flag":1034},"ITEM_ROUTE_132_PROTEIN":{"address":2709285,"default_item":64,"flag":1156},"ITEM_ROUTE_132_RARE_CANDY":{"address":2709272,"default_item":68,"flag":1036},"ITEM_ROUTE_133_BIG_PEARL":{"address":2709298,"default_item":107,"flag":1037},"ITEM_ROUTE_133_MAX_REVIVE":{"address":2709324,"default_item":25,"flag":1157},"ITEM_ROUTE_133_STAR_PIECE":{"address":2709311,"default_item":109,"flag":1038},"ITEM_ROUTE_134_CARBOS":{"address":2709337,"default_item":66,"flag":1158},"ITEM_ROUTE_134_STAR_PIECE":{"address":2709350,"default_item":109,"flag":1159},"ITEM_RUSTBORO_CITY_X_DEFEND":{"address":2709402,"default_item":76,"flag":1041},"ITEM_RUSTURF_TUNNEL_MAX_ETHER":{"address":2709506,"default_item":35,"flag":1049},"ITEM_RUSTURF_TUNNEL_POKE_BALL":{"address":2709493,"default_item":4,"flag":1048},"ITEM_SAFARI_ZONE_NORTH_CALCIUM":{"address":2709896,"default_item":67,"flag":1119},"ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":{"address":2709922,"default_item":110,"flag":1169},"ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":{"address":2709883,"default_item":310,"flag":1094},"ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":{"address":2709935,"default_item":107,"flag":1170},"ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":{"address":2709909,"default_item":25,"flag":1131},"ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":{"address":2709870,"default_item":299,"flag":1079},"ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":{"address":2710208,"default_item":314,"flag":1090},"ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":{"address":2710143,"default_item":107,"flag":1081},"ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":{"address":2710195,"default_item":212,"flag":1113},"ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":{"address":2710182,"default_item":295,"flag":1112},"ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":{"address":2710156,"default_item":68,"flag":1082},"ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":{"address":2710169,"default_item":16,"flag":1083},"ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":{"address":[2710221,2551006],"default_item":121,"flag":1060},"ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":{"address":[2710234,2551032],"default_item":122,"flag":1061},"ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":{"address":[2710247,2551058],"default_item":126,"flag":1062},"ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":{"address":[2710260,2551084],"default_item":128,"flag":1063},"ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":{"address":[2710273,2551110],"default_item":125,"flag":1064},"ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":{"address":[2710286,2551136],"default_item":124,"flag":1065},"ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":{"address":[2710299,2551162],"default_item":123,"flag":1067},"ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":{"address":[2710312,2551188],"default_item":129,"flag":1068},"ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":{"address":[2710325,2551214],"default_item":127,"flag":1069},"ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":{"address":2710338,"default_item":37,"flag":1084},"ITEM_VICTORY_ROAD_1F_PP_UP":{"address":2710351,"default_item":69,"flag":1085},"ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":{"address":2710377,"default_item":19,"flag":1087},"ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":{"address":2710364,"default_item":317,"flag":1086},"ITEM_VICTORY_ROAD_B2F_FULL_HEAL":{"address":2710390,"default_item":23,"flag":1088},"NPC_GIFT_BERRY_MASTERS_WIFE":{"address":2570453,"default_item":133,"flag":1197},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_1":{"address":2570263,"default_item":153,"flag":1195},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_2":{"address":2570315,"default_item":154,"flag":1196},"NPC_GIFT_FLOWER_SHOP_RECEIVED_BERRY":{"address":2284375,"default_item":133,"flag":1207},"NPC_GIFT_GOT_BASEMENT_KEY_FROM_WATTSON":{"address":1971718,"default_item":271,"flag":208},"NPC_GIFT_GOT_TM_THUNDERBOLT_FROM_WATTSON":{"address":1971754,"default_item":312,"flag":209},"NPC_GIFT_LILYCOVE_RECEIVED_BERRY":{"address":1985277,"default_item":141,"flag":1208},"NPC_GIFT_RECEIVED_6_SODA_POP":{"address":2543767,"default_item":27,"flag":140},"NPC_GIFT_RECEIVED_ACRO_BIKE":{"address":2170570,"default_item":272,"flag":1181},"NPC_GIFT_RECEIVED_AMULET_COIN":{"address":2716248,"default_item":189,"flag":133},"NPC_GIFT_RECEIVED_AURORA_TICKET":{"address":2716523,"default_item":371,"flag":314},"NPC_GIFT_RECEIVED_CHARCOAL":{"address":2102559,"default_item":215,"flag":254},"NPC_GIFT_RECEIVED_CHESTO_BERRY_ROUTE_104":{"address":2028703,"default_item":134,"flag":246},"NPC_GIFT_RECEIVED_CLEANSE_TAG":{"address":2312109,"default_item":190,"flag":282},"NPC_GIFT_RECEIVED_COIN_CASE":{"address":2179054,"default_item":260,"flag":258},"NPC_GIFT_RECEIVED_DEEP_SEA_SCALE":{"address":2162572,"default_item":193,"flag":1190},"NPC_GIFT_RECEIVED_DEEP_SEA_TOOTH":{"address":2162555,"default_item":192,"flag":1191},"NPC_GIFT_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":{"address":2295814,"default_item":269,"flag":1172},"NPC_GIFT_RECEIVED_DEVON_SCOPE":{"address":2065146,"default_item":288,"flag":285},"NPC_GIFT_RECEIVED_EON_TICKET":{"address":2716574,"default_item":275,"flag":474},"NPC_GIFT_RECEIVED_EXP_SHARE":{"address":2185525,"default_item":182,"flag":272},"NPC_GIFT_RECEIVED_FIRST_POKEBALLS":{"address":2085751,"default_item":4,"flag":233},"NPC_GIFT_RECEIVED_FOCUS_BAND":{"address":2337807,"default_item":196,"flag":283},"NPC_GIFT_RECEIVED_GOOD_ROD":{"address":2058408,"default_item":263,"flag":227},"NPC_GIFT_RECEIVED_GO_GOGGLES":{"address":2017746,"default_item":279,"flag":221},"NPC_GIFT_RECEIVED_GREAT_BALL_PETALBURG_WOODS":{"address":2300119,"default_item":3,"flag":1171},"NPC_GIFT_RECEIVED_GREAT_BALL_RUSTBORO_CITY":{"address":1977146,"default_item":3,"flag":1173},"NPC_GIFT_RECEIVED_HM_CUT":{"address":2199532,"default_item":339,"flag":137},"NPC_GIFT_RECEIVED_HM_DIVE":{"address":2252095,"default_item":346,"flag":123},"NPC_GIFT_RECEIVED_HM_FLASH":{"address":2298287,"default_item":343,"flag":109},"NPC_GIFT_RECEIVED_HM_FLY":{"address":2060636,"default_item":340,"flag":110},"NPC_GIFT_RECEIVED_HM_ROCK_SMASH":{"address":2174128,"default_item":344,"flag":107},"NPC_GIFT_RECEIVED_HM_STRENGTH":{"address":2295305,"default_item":342,"flag":106},"NPC_GIFT_RECEIVED_HM_SURF":{"address":2126671,"default_item":341,"flag":122},"NPC_GIFT_RECEIVED_HM_WATERFALL":{"address":1999854,"default_item":345,"flag":312},"NPC_GIFT_RECEIVED_ITEMFINDER":{"address":2039874,"default_item":261,"flag":1176},"NPC_GIFT_RECEIVED_KINGS_ROCK":{"address":1993670,"default_item":187,"flag":276},"NPC_GIFT_RECEIVED_LETTER":{"address":2185301,"default_item":274,"flag":1174},"NPC_GIFT_RECEIVED_MACHO_BRACE":{"address":2284472,"default_item":181,"flag":277},"NPC_GIFT_RECEIVED_MACH_BIKE":{"address":2170553,"default_item":259,"flag":1180},"NPC_GIFT_RECEIVED_MAGMA_EMBLEM":{"address":2316671,"default_item":375,"flag":1177},"NPC_GIFT_RECEIVED_MENTAL_HERB":{"address":2208103,"default_item":185,"flag":223},"NPC_GIFT_RECEIVED_METEORITE":{"address":2304222,"default_item":280,"flag":115},"NPC_GIFT_RECEIVED_MIRACLE_SEED":{"address":2300337,"default_item":205,"flag":297},"NPC_GIFT_RECEIVED_MYSTIC_TICKET":{"address":2716540,"default_item":370,"flag":315},"NPC_GIFT_RECEIVED_OLD_ROD":{"address":2012541,"default_item":262,"flag":257},"NPC_GIFT_RECEIVED_OLD_SEA_MAP":{"address":2716557,"default_item":376,"flag":316},"NPC_GIFT_RECEIVED_POKEBLOCK_CASE":{"address":2614193,"default_item":273,"flag":95},"NPC_GIFT_RECEIVED_POTION_OLDALE":{"address":2010888,"default_item":13,"flag":132},"NPC_GIFT_RECEIVED_POWDER_JAR":{"address":1962504,"default_item":372,"flag":337},"NPC_GIFT_RECEIVED_PREMIER_BALL_RUSTBORO":{"address":2200571,"default_item":12,"flag":213},"NPC_GIFT_RECEIVED_QUICK_CLAW":{"address":2192227,"default_item":183,"flag":275},"NPC_GIFT_RECEIVED_REPEAT_BALL":{"address":2053722,"default_item":9,"flag":256},"NPC_GIFT_RECEIVED_SECRET_POWER":{"address":2598914,"default_item":331,"flag":96},"NPC_GIFT_RECEIVED_SILK_SCARF":{"address":2101830,"default_item":217,"flag":289},"NPC_GIFT_RECEIVED_SOFT_SAND":{"address":2035664,"default_item":203,"flag":280},"NPC_GIFT_RECEIVED_SOOTHE_BELL":{"address":2151278,"default_item":184,"flag":278},"NPC_GIFT_RECEIVED_SOOT_SACK":{"address":2567245,"default_item":270,"flag":1033},"NPC_GIFT_RECEIVED_SS_TICKET":{"address":2716506,"default_item":265,"flag":291},"NPC_GIFT_RECEIVED_SUN_STONE_MOSSDEEP":{"address":2254406,"default_item":93,"flag":192},"NPC_GIFT_RECEIVED_SUPER_ROD":{"address":2251560,"default_item":264,"flag":152},"NPC_GIFT_RECEIVED_TM_AERIAL_ACE":{"address":2202201,"default_item":328,"flag":170},"NPC_GIFT_RECEIVED_TM_ATTRACT":{"address":2116413,"default_item":333,"flag":235},"NPC_GIFT_RECEIVED_TM_BRICK_BREAK":{"address":2269085,"default_item":319,"flag":121},"NPC_GIFT_RECEIVED_TM_BULK_UP":{"address":2095210,"default_item":296,"flag":166},"NPC_GIFT_RECEIVED_TM_BULLET_SEED":{"address":2028910,"default_item":297,"flag":262},"NPC_GIFT_RECEIVED_TM_CALM_MIND":{"address":2244066,"default_item":292,"flag":171},"NPC_GIFT_RECEIVED_TM_DIG":{"address":2286669,"default_item":316,"flag":261},"NPC_GIFT_RECEIVED_TM_FACADE":{"address":2129909,"default_item":330,"flag":169},"NPC_GIFT_RECEIVED_TM_FRUSTRATION":{"address":2124110,"default_item":309,"flag":1179},"NPC_GIFT_RECEIVED_TM_GIGA_DRAIN":{"address":2068012,"default_item":307,"flag":232},"NPC_GIFT_RECEIVED_TM_HIDDEN_POWER":{"address":2206905,"default_item":298,"flag":264},"NPC_GIFT_RECEIVED_TM_OVERHEAT":{"address":2103328,"default_item":338,"flag":168},"NPC_GIFT_RECEIVED_TM_REST":{"address":2236966,"default_item":332,"flag":234},"NPC_GIFT_RECEIVED_TM_RETURN":{"address":2113546,"default_item":315,"flag":229},"NPC_GIFT_RECEIVED_TM_RETURN_2":{"address":2124055,"default_item":315,"flag":1178},"NPC_GIFT_RECEIVED_TM_ROAR":{"address":2051750,"default_item":293,"flag":231},"NPC_GIFT_RECEIVED_TM_ROCK_TOMB":{"address":2188088,"default_item":327,"flag":165},"NPC_GIFT_RECEIVED_TM_SHOCK_WAVE":{"address":2167340,"default_item":322,"flag":167},"NPC_GIFT_RECEIVED_TM_SLUDGE_BOMB":{"address":2099189,"default_item":324,"flag":230},"NPC_GIFT_RECEIVED_TM_SNATCH":{"address":2360766,"default_item":337,"flag":260},"NPC_GIFT_RECEIVED_TM_STEEL_WING":{"address":2298866,"default_item":335,"flag":1175},"NPC_GIFT_RECEIVED_TM_THIEF":{"address":2154698,"default_item":334,"flag":269},"NPC_GIFT_RECEIVED_TM_TORMENT":{"address":2145260,"default_item":329,"flag":265},"NPC_GIFT_RECEIVED_TM_WATER_PULSE":{"address":2262402,"default_item":291,"flag":172},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_1":{"address":2550316,"default_item":68,"flag":1200},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_2":{"address":2550390,"default_item":10,"flag":1201},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_3":{"address":2550473,"default_item":204,"flag":1202},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_4":{"address":2550556,"default_item":194,"flag":1203},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_5":{"address":2550630,"default_item":300,"flag":1204},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_6":{"address":2550695,"default_item":208,"flag":1205},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_7":{"address":2550769,"default_item":71,"flag":1206},"NPC_GIFT_RECEIVED_WAILMER_PAIL":{"address":2284320,"default_item":268,"flag":94},"NPC_GIFT_RECEIVED_WHITE_HERB":{"address":2028770,"default_item":180,"flag":279},"NPC_GIFT_ROUTE_111_RECEIVED_BERRY":{"address":2045493,"default_item":148,"flag":1192},"NPC_GIFT_ROUTE_114_RECEIVED_BERRY":{"address":2051680,"default_item":149,"flag":1193},"NPC_GIFT_ROUTE_120_RECEIVED_BERRY":{"address":2064727,"default_item":143,"flag":1194},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_1":{"address":1998521,"default_item":153,"flag":1198},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_2":{"address":1998566,"default_item":143,"flag":1199},"POKEDEX_REWARD_001":{"address":5729368,"default_item":3,"flag":0},"POKEDEX_REWARD_002":{"address":5729370,"default_item":3,"flag":0},"POKEDEX_REWARD_003":{"address":5729372,"default_item":3,"flag":0},"POKEDEX_REWARD_004":{"address":5729374,"default_item":3,"flag":0},"POKEDEX_REWARD_005":{"address":5729376,"default_item":3,"flag":0},"POKEDEX_REWARD_006":{"address":5729378,"default_item":3,"flag":0},"POKEDEX_REWARD_007":{"address":5729380,"default_item":3,"flag":0},"POKEDEX_REWARD_008":{"address":5729382,"default_item":3,"flag":0},"POKEDEX_REWARD_009":{"address":5729384,"default_item":3,"flag":0},"POKEDEX_REWARD_010":{"address":5729386,"default_item":3,"flag":0},"POKEDEX_REWARD_011":{"address":5729388,"default_item":3,"flag":0},"POKEDEX_REWARD_012":{"address":5729390,"default_item":3,"flag":0},"POKEDEX_REWARD_013":{"address":5729392,"default_item":3,"flag":0},"POKEDEX_REWARD_014":{"address":5729394,"default_item":3,"flag":0},"POKEDEX_REWARD_015":{"address":5729396,"default_item":3,"flag":0},"POKEDEX_REWARD_016":{"address":5729398,"default_item":3,"flag":0},"POKEDEX_REWARD_017":{"address":5729400,"default_item":3,"flag":0},"POKEDEX_REWARD_018":{"address":5729402,"default_item":3,"flag":0},"POKEDEX_REWARD_019":{"address":5729404,"default_item":3,"flag":0},"POKEDEX_REWARD_020":{"address":5729406,"default_item":3,"flag":0},"POKEDEX_REWARD_021":{"address":5729408,"default_item":3,"flag":0},"POKEDEX_REWARD_022":{"address":5729410,"default_item":3,"flag":0},"POKEDEX_REWARD_023":{"address":5729412,"default_item":3,"flag":0},"POKEDEX_REWARD_024":{"address":5729414,"default_item":3,"flag":0},"POKEDEX_REWARD_025":{"address":5729416,"default_item":3,"flag":0},"POKEDEX_REWARD_026":{"address":5729418,"default_item":3,"flag":0},"POKEDEX_REWARD_027":{"address":5729420,"default_item":3,"flag":0},"POKEDEX_REWARD_028":{"address":5729422,"default_item":3,"flag":0},"POKEDEX_REWARD_029":{"address":5729424,"default_item":3,"flag":0},"POKEDEX_REWARD_030":{"address":5729426,"default_item":3,"flag":0},"POKEDEX_REWARD_031":{"address":5729428,"default_item":3,"flag":0},"POKEDEX_REWARD_032":{"address":5729430,"default_item":3,"flag":0},"POKEDEX_REWARD_033":{"address":5729432,"default_item":3,"flag":0},"POKEDEX_REWARD_034":{"address":5729434,"default_item":3,"flag":0},"POKEDEX_REWARD_035":{"address":5729436,"default_item":3,"flag":0},"POKEDEX_REWARD_036":{"address":5729438,"default_item":3,"flag":0},"POKEDEX_REWARD_037":{"address":5729440,"default_item":3,"flag":0},"POKEDEX_REWARD_038":{"address":5729442,"default_item":3,"flag":0},"POKEDEX_REWARD_039":{"address":5729444,"default_item":3,"flag":0},"POKEDEX_REWARD_040":{"address":5729446,"default_item":3,"flag":0},"POKEDEX_REWARD_041":{"address":5729448,"default_item":3,"flag":0},"POKEDEX_REWARD_042":{"address":5729450,"default_item":3,"flag":0},"POKEDEX_REWARD_043":{"address":5729452,"default_item":3,"flag":0},"POKEDEX_REWARD_044":{"address":5729454,"default_item":3,"flag":0},"POKEDEX_REWARD_045":{"address":5729456,"default_item":3,"flag":0},"POKEDEX_REWARD_046":{"address":5729458,"default_item":3,"flag":0},"POKEDEX_REWARD_047":{"address":5729460,"default_item":3,"flag":0},"POKEDEX_REWARD_048":{"address":5729462,"default_item":3,"flag":0},"POKEDEX_REWARD_049":{"address":5729464,"default_item":3,"flag":0},"POKEDEX_REWARD_050":{"address":5729466,"default_item":3,"flag":0},"POKEDEX_REWARD_051":{"address":5729468,"default_item":3,"flag":0},"POKEDEX_REWARD_052":{"address":5729470,"default_item":3,"flag":0},"POKEDEX_REWARD_053":{"address":5729472,"default_item":3,"flag":0},"POKEDEX_REWARD_054":{"address":5729474,"default_item":3,"flag":0},"POKEDEX_REWARD_055":{"address":5729476,"default_item":3,"flag":0},"POKEDEX_REWARD_056":{"address":5729478,"default_item":3,"flag":0},"POKEDEX_REWARD_057":{"address":5729480,"default_item":3,"flag":0},"POKEDEX_REWARD_058":{"address":5729482,"default_item":3,"flag":0},"POKEDEX_REWARD_059":{"address":5729484,"default_item":3,"flag":0},"POKEDEX_REWARD_060":{"address":5729486,"default_item":3,"flag":0},"POKEDEX_REWARD_061":{"address":5729488,"default_item":3,"flag":0},"POKEDEX_REWARD_062":{"address":5729490,"default_item":3,"flag":0},"POKEDEX_REWARD_063":{"address":5729492,"default_item":3,"flag":0},"POKEDEX_REWARD_064":{"address":5729494,"default_item":3,"flag":0},"POKEDEX_REWARD_065":{"address":5729496,"default_item":3,"flag":0},"POKEDEX_REWARD_066":{"address":5729498,"default_item":3,"flag":0},"POKEDEX_REWARD_067":{"address":5729500,"default_item":3,"flag":0},"POKEDEX_REWARD_068":{"address":5729502,"default_item":3,"flag":0},"POKEDEX_REWARD_069":{"address":5729504,"default_item":3,"flag":0},"POKEDEX_REWARD_070":{"address":5729506,"default_item":3,"flag":0},"POKEDEX_REWARD_071":{"address":5729508,"default_item":3,"flag":0},"POKEDEX_REWARD_072":{"address":5729510,"default_item":3,"flag":0},"POKEDEX_REWARD_073":{"address":5729512,"default_item":3,"flag":0},"POKEDEX_REWARD_074":{"address":5729514,"default_item":3,"flag":0},"POKEDEX_REWARD_075":{"address":5729516,"default_item":3,"flag":0},"POKEDEX_REWARD_076":{"address":5729518,"default_item":3,"flag":0},"POKEDEX_REWARD_077":{"address":5729520,"default_item":3,"flag":0},"POKEDEX_REWARD_078":{"address":5729522,"default_item":3,"flag":0},"POKEDEX_REWARD_079":{"address":5729524,"default_item":3,"flag":0},"POKEDEX_REWARD_080":{"address":5729526,"default_item":3,"flag":0},"POKEDEX_REWARD_081":{"address":5729528,"default_item":3,"flag":0},"POKEDEX_REWARD_082":{"address":5729530,"default_item":3,"flag":0},"POKEDEX_REWARD_083":{"address":5729532,"default_item":3,"flag":0},"POKEDEX_REWARD_084":{"address":5729534,"default_item":3,"flag":0},"POKEDEX_REWARD_085":{"address":5729536,"default_item":3,"flag":0},"POKEDEX_REWARD_086":{"address":5729538,"default_item":3,"flag":0},"POKEDEX_REWARD_087":{"address":5729540,"default_item":3,"flag":0},"POKEDEX_REWARD_088":{"address":5729542,"default_item":3,"flag":0},"POKEDEX_REWARD_089":{"address":5729544,"default_item":3,"flag":0},"POKEDEX_REWARD_090":{"address":5729546,"default_item":3,"flag":0},"POKEDEX_REWARD_091":{"address":5729548,"default_item":3,"flag":0},"POKEDEX_REWARD_092":{"address":5729550,"default_item":3,"flag":0},"POKEDEX_REWARD_093":{"address":5729552,"default_item":3,"flag":0},"POKEDEX_REWARD_094":{"address":5729554,"default_item":3,"flag":0},"POKEDEX_REWARD_095":{"address":5729556,"default_item":3,"flag":0},"POKEDEX_REWARD_096":{"address":5729558,"default_item":3,"flag":0},"POKEDEX_REWARD_097":{"address":5729560,"default_item":3,"flag":0},"POKEDEX_REWARD_098":{"address":5729562,"default_item":3,"flag":0},"POKEDEX_REWARD_099":{"address":5729564,"default_item":3,"flag":0},"POKEDEX_REWARD_100":{"address":5729566,"default_item":3,"flag":0},"POKEDEX_REWARD_101":{"address":5729568,"default_item":3,"flag":0},"POKEDEX_REWARD_102":{"address":5729570,"default_item":3,"flag":0},"POKEDEX_REWARD_103":{"address":5729572,"default_item":3,"flag":0},"POKEDEX_REWARD_104":{"address":5729574,"default_item":3,"flag":0},"POKEDEX_REWARD_105":{"address":5729576,"default_item":3,"flag":0},"POKEDEX_REWARD_106":{"address":5729578,"default_item":3,"flag":0},"POKEDEX_REWARD_107":{"address":5729580,"default_item":3,"flag":0},"POKEDEX_REWARD_108":{"address":5729582,"default_item":3,"flag":0},"POKEDEX_REWARD_109":{"address":5729584,"default_item":3,"flag":0},"POKEDEX_REWARD_110":{"address":5729586,"default_item":3,"flag":0},"POKEDEX_REWARD_111":{"address":5729588,"default_item":3,"flag":0},"POKEDEX_REWARD_112":{"address":5729590,"default_item":3,"flag":0},"POKEDEX_REWARD_113":{"address":5729592,"default_item":3,"flag":0},"POKEDEX_REWARD_114":{"address":5729594,"default_item":3,"flag":0},"POKEDEX_REWARD_115":{"address":5729596,"default_item":3,"flag":0},"POKEDEX_REWARD_116":{"address":5729598,"default_item":3,"flag":0},"POKEDEX_REWARD_117":{"address":5729600,"default_item":3,"flag":0},"POKEDEX_REWARD_118":{"address":5729602,"default_item":3,"flag":0},"POKEDEX_REWARD_119":{"address":5729604,"default_item":3,"flag":0},"POKEDEX_REWARD_120":{"address":5729606,"default_item":3,"flag":0},"POKEDEX_REWARD_121":{"address":5729608,"default_item":3,"flag":0},"POKEDEX_REWARD_122":{"address":5729610,"default_item":3,"flag":0},"POKEDEX_REWARD_123":{"address":5729612,"default_item":3,"flag":0},"POKEDEX_REWARD_124":{"address":5729614,"default_item":3,"flag":0},"POKEDEX_REWARD_125":{"address":5729616,"default_item":3,"flag":0},"POKEDEX_REWARD_126":{"address":5729618,"default_item":3,"flag":0},"POKEDEX_REWARD_127":{"address":5729620,"default_item":3,"flag":0},"POKEDEX_REWARD_128":{"address":5729622,"default_item":3,"flag":0},"POKEDEX_REWARD_129":{"address":5729624,"default_item":3,"flag":0},"POKEDEX_REWARD_130":{"address":5729626,"default_item":3,"flag":0},"POKEDEX_REWARD_131":{"address":5729628,"default_item":3,"flag":0},"POKEDEX_REWARD_132":{"address":5729630,"default_item":3,"flag":0},"POKEDEX_REWARD_133":{"address":5729632,"default_item":3,"flag":0},"POKEDEX_REWARD_134":{"address":5729634,"default_item":3,"flag":0},"POKEDEX_REWARD_135":{"address":5729636,"default_item":3,"flag":0},"POKEDEX_REWARD_136":{"address":5729638,"default_item":3,"flag":0},"POKEDEX_REWARD_137":{"address":5729640,"default_item":3,"flag":0},"POKEDEX_REWARD_138":{"address":5729642,"default_item":3,"flag":0},"POKEDEX_REWARD_139":{"address":5729644,"default_item":3,"flag":0},"POKEDEX_REWARD_140":{"address":5729646,"default_item":3,"flag":0},"POKEDEX_REWARD_141":{"address":5729648,"default_item":3,"flag":0},"POKEDEX_REWARD_142":{"address":5729650,"default_item":3,"flag":0},"POKEDEX_REWARD_143":{"address":5729652,"default_item":3,"flag":0},"POKEDEX_REWARD_144":{"address":5729654,"default_item":3,"flag":0},"POKEDEX_REWARD_145":{"address":5729656,"default_item":3,"flag":0},"POKEDEX_REWARD_146":{"address":5729658,"default_item":3,"flag":0},"POKEDEX_REWARD_147":{"address":5729660,"default_item":3,"flag":0},"POKEDEX_REWARD_148":{"address":5729662,"default_item":3,"flag":0},"POKEDEX_REWARD_149":{"address":5729664,"default_item":3,"flag":0},"POKEDEX_REWARD_150":{"address":5729666,"default_item":3,"flag":0},"POKEDEX_REWARD_151":{"address":5729668,"default_item":3,"flag":0},"POKEDEX_REWARD_152":{"address":5729670,"default_item":3,"flag":0},"POKEDEX_REWARD_153":{"address":5729672,"default_item":3,"flag":0},"POKEDEX_REWARD_154":{"address":5729674,"default_item":3,"flag":0},"POKEDEX_REWARD_155":{"address":5729676,"default_item":3,"flag":0},"POKEDEX_REWARD_156":{"address":5729678,"default_item":3,"flag":0},"POKEDEX_REWARD_157":{"address":5729680,"default_item":3,"flag":0},"POKEDEX_REWARD_158":{"address":5729682,"default_item":3,"flag":0},"POKEDEX_REWARD_159":{"address":5729684,"default_item":3,"flag":0},"POKEDEX_REWARD_160":{"address":5729686,"default_item":3,"flag":0},"POKEDEX_REWARD_161":{"address":5729688,"default_item":3,"flag":0},"POKEDEX_REWARD_162":{"address":5729690,"default_item":3,"flag":0},"POKEDEX_REWARD_163":{"address":5729692,"default_item":3,"flag":0},"POKEDEX_REWARD_164":{"address":5729694,"default_item":3,"flag":0},"POKEDEX_REWARD_165":{"address":5729696,"default_item":3,"flag":0},"POKEDEX_REWARD_166":{"address":5729698,"default_item":3,"flag":0},"POKEDEX_REWARD_167":{"address":5729700,"default_item":3,"flag":0},"POKEDEX_REWARD_168":{"address":5729702,"default_item":3,"flag":0},"POKEDEX_REWARD_169":{"address":5729704,"default_item":3,"flag":0},"POKEDEX_REWARD_170":{"address":5729706,"default_item":3,"flag":0},"POKEDEX_REWARD_171":{"address":5729708,"default_item":3,"flag":0},"POKEDEX_REWARD_172":{"address":5729710,"default_item":3,"flag":0},"POKEDEX_REWARD_173":{"address":5729712,"default_item":3,"flag":0},"POKEDEX_REWARD_174":{"address":5729714,"default_item":3,"flag":0},"POKEDEX_REWARD_175":{"address":5729716,"default_item":3,"flag":0},"POKEDEX_REWARD_176":{"address":5729718,"default_item":3,"flag":0},"POKEDEX_REWARD_177":{"address":5729720,"default_item":3,"flag":0},"POKEDEX_REWARD_178":{"address":5729722,"default_item":3,"flag":0},"POKEDEX_REWARD_179":{"address":5729724,"default_item":3,"flag":0},"POKEDEX_REWARD_180":{"address":5729726,"default_item":3,"flag":0},"POKEDEX_REWARD_181":{"address":5729728,"default_item":3,"flag":0},"POKEDEX_REWARD_182":{"address":5729730,"default_item":3,"flag":0},"POKEDEX_REWARD_183":{"address":5729732,"default_item":3,"flag":0},"POKEDEX_REWARD_184":{"address":5729734,"default_item":3,"flag":0},"POKEDEX_REWARD_185":{"address":5729736,"default_item":3,"flag":0},"POKEDEX_REWARD_186":{"address":5729738,"default_item":3,"flag":0},"POKEDEX_REWARD_187":{"address":5729740,"default_item":3,"flag":0},"POKEDEX_REWARD_188":{"address":5729742,"default_item":3,"flag":0},"POKEDEX_REWARD_189":{"address":5729744,"default_item":3,"flag":0},"POKEDEX_REWARD_190":{"address":5729746,"default_item":3,"flag":0},"POKEDEX_REWARD_191":{"address":5729748,"default_item":3,"flag":0},"POKEDEX_REWARD_192":{"address":5729750,"default_item":3,"flag":0},"POKEDEX_REWARD_193":{"address":5729752,"default_item":3,"flag":0},"POKEDEX_REWARD_194":{"address":5729754,"default_item":3,"flag":0},"POKEDEX_REWARD_195":{"address":5729756,"default_item":3,"flag":0},"POKEDEX_REWARD_196":{"address":5729758,"default_item":3,"flag":0},"POKEDEX_REWARD_197":{"address":5729760,"default_item":3,"flag":0},"POKEDEX_REWARD_198":{"address":5729762,"default_item":3,"flag":0},"POKEDEX_REWARD_199":{"address":5729764,"default_item":3,"flag":0},"POKEDEX_REWARD_200":{"address":5729766,"default_item":3,"flag":0},"POKEDEX_REWARD_201":{"address":5729768,"default_item":3,"flag":0},"POKEDEX_REWARD_202":{"address":5729770,"default_item":3,"flag":0},"POKEDEX_REWARD_203":{"address":5729772,"default_item":3,"flag":0},"POKEDEX_REWARD_204":{"address":5729774,"default_item":3,"flag":0},"POKEDEX_REWARD_205":{"address":5729776,"default_item":3,"flag":0},"POKEDEX_REWARD_206":{"address":5729778,"default_item":3,"flag":0},"POKEDEX_REWARD_207":{"address":5729780,"default_item":3,"flag":0},"POKEDEX_REWARD_208":{"address":5729782,"default_item":3,"flag":0},"POKEDEX_REWARD_209":{"address":5729784,"default_item":3,"flag":0},"POKEDEX_REWARD_210":{"address":5729786,"default_item":3,"flag":0},"POKEDEX_REWARD_211":{"address":5729788,"default_item":3,"flag":0},"POKEDEX_REWARD_212":{"address":5729790,"default_item":3,"flag":0},"POKEDEX_REWARD_213":{"address":5729792,"default_item":3,"flag":0},"POKEDEX_REWARD_214":{"address":5729794,"default_item":3,"flag":0},"POKEDEX_REWARD_215":{"address":5729796,"default_item":3,"flag":0},"POKEDEX_REWARD_216":{"address":5729798,"default_item":3,"flag":0},"POKEDEX_REWARD_217":{"address":5729800,"default_item":3,"flag":0},"POKEDEX_REWARD_218":{"address":5729802,"default_item":3,"flag":0},"POKEDEX_REWARD_219":{"address":5729804,"default_item":3,"flag":0},"POKEDEX_REWARD_220":{"address":5729806,"default_item":3,"flag":0},"POKEDEX_REWARD_221":{"address":5729808,"default_item":3,"flag":0},"POKEDEX_REWARD_222":{"address":5729810,"default_item":3,"flag":0},"POKEDEX_REWARD_223":{"address":5729812,"default_item":3,"flag":0},"POKEDEX_REWARD_224":{"address":5729814,"default_item":3,"flag":0},"POKEDEX_REWARD_225":{"address":5729816,"default_item":3,"flag":0},"POKEDEX_REWARD_226":{"address":5729818,"default_item":3,"flag":0},"POKEDEX_REWARD_227":{"address":5729820,"default_item":3,"flag":0},"POKEDEX_REWARD_228":{"address":5729822,"default_item":3,"flag":0},"POKEDEX_REWARD_229":{"address":5729824,"default_item":3,"flag":0},"POKEDEX_REWARD_230":{"address":5729826,"default_item":3,"flag":0},"POKEDEX_REWARD_231":{"address":5729828,"default_item":3,"flag":0},"POKEDEX_REWARD_232":{"address":5729830,"default_item":3,"flag":0},"POKEDEX_REWARD_233":{"address":5729832,"default_item":3,"flag":0},"POKEDEX_REWARD_234":{"address":5729834,"default_item":3,"flag":0},"POKEDEX_REWARD_235":{"address":5729836,"default_item":3,"flag":0},"POKEDEX_REWARD_236":{"address":5729838,"default_item":3,"flag":0},"POKEDEX_REWARD_237":{"address":5729840,"default_item":3,"flag":0},"POKEDEX_REWARD_238":{"address":5729842,"default_item":3,"flag":0},"POKEDEX_REWARD_239":{"address":5729844,"default_item":3,"flag":0},"POKEDEX_REWARD_240":{"address":5729846,"default_item":3,"flag":0},"POKEDEX_REWARD_241":{"address":5729848,"default_item":3,"flag":0},"POKEDEX_REWARD_242":{"address":5729850,"default_item":3,"flag":0},"POKEDEX_REWARD_243":{"address":5729852,"default_item":3,"flag":0},"POKEDEX_REWARD_244":{"address":5729854,"default_item":3,"flag":0},"POKEDEX_REWARD_245":{"address":5729856,"default_item":3,"flag":0},"POKEDEX_REWARD_246":{"address":5729858,"default_item":3,"flag":0},"POKEDEX_REWARD_247":{"address":5729860,"default_item":3,"flag":0},"POKEDEX_REWARD_248":{"address":5729862,"default_item":3,"flag":0},"POKEDEX_REWARD_249":{"address":5729864,"default_item":3,"flag":0},"POKEDEX_REWARD_250":{"address":5729866,"default_item":3,"flag":0},"POKEDEX_REWARD_251":{"address":5729868,"default_item":3,"flag":0},"POKEDEX_REWARD_252":{"address":5729870,"default_item":3,"flag":0},"POKEDEX_REWARD_253":{"address":5729872,"default_item":3,"flag":0},"POKEDEX_REWARD_254":{"address":5729874,"default_item":3,"flag":0},"POKEDEX_REWARD_255":{"address":5729876,"default_item":3,"flag":0},"POKEDEX_REWARD_256":{"address":5729878,"default_item":3,"flag":0},"POKEDEX_REWARD_257":{"address":5729880,"default_item":3,"flag":0},"POKEDEX_REWARD_258":{"address":5729882,"default_item":3,"flag":0},"POKEDEX_REWARD_259":{"address":5729884,"default_item":3,"flag":0},"POKEDEX_REWARD_260":{"address":5729886,"default_item":3,"flag":0},"POKEDEX_REWARD_261":{"address":5729888,"default_item":3,"flag":0},"POKEDEX_REWARD_262":{"address":5729890,"default_item":3,"flag":0},"POKEDEX_REWARD_263":{"address":5729892,"default_item":3,"flag":0},"POKEDEX_REWARD_264":{"address":5729894,"default_item":3,"flag":0},"POKEDEX_REWARD_265":{"address":5729896,"default_item":3,"flag":0},"POKEDEX_REWARD_266":{"address":5729898,"default_item":3,"flag":0},"POKEDEX_REWARD_267":{"address":5729900,"default_item":3,"flag":0},"POKEDEX_REWARD_268":{"address":5729902,"default_item":3,"flag":0},"POKEDEX_REWARD_269":{"address":5729904,"default_item":3,"flag":0},"POKEDEX_REWARD_270":{"address":5729906,"default_item":3,"flag":0},"POKEDEX_REWARD_271":{"address":5729908,"default_item":3,"flag":0},"POKEDEX_REWARD_272":{"address":5729910,"default_item":3,"flag":0},"POKEDEX_REWARD_273":{"address":5729912,"default_item":3,"flag":0},"POKEDEX_REWARD_274":{"address":5729914,"default_item":3,"flag":0},"POKEDEX_REWARD_275":{"address":5729916,"default_item":3,"flag":0},"POKEDEX_REWARD_276":{"address":5729918,"default_item":3,"flag":0},"POKEDEX_REWARD_277":{"address":5729920,"default_item":3,"flag":0},"POKEDEX_REWARD_278":{"address":5729922,"default_item":3,"flag":0},"POKEDEX_REWARD_279":{"address":5729924,"default_item":3,"flag":0},"POKEDEX_REWARD_280":{"address":5729926,"default_item":3,"flag":0},"POKEDEX_REWARD_281":{"address":5729928,"default_item":3,"flag":0},"POKEDEX_REWARD_282":{"address":5729930,"default_item":3,"flag":0},"POKEDEX_REWARD_283":{"address":5729932,"default_item":3,"flag":0},"POKEDEX_REWARD_284":{"address":5729934,"default_item":3,"flag":0},"POKEDEX_REWARD_285":{"address":5729936,"default_item":3,"flag":0},"POKEDEX_REWARD_286":{"address":5729938,"default_item":3,"flag":0},"POKEDEX_REWARD_287":{"address":5729940,"default_item":3,"flag":0},"POKEDEX_REWARD_288":{"address":5729942,"default_item":3,"flag":0},"POKEDEX_REWARD_289":{"address":5729944,"default_item":3,"flag":0},"POKEDEX_REWARD_290":{"address":5729946,"default_item":3,"flag":0},"POKEDEX_REWARD_291":{"address":5729948,"default_item":3,"flag":0},"POKEDEX_REWARD_292":{"address":5729950,"default_item":3,"flag":0},"POKEDEX_REWARD_293":{"address":5729952,"default_item":3,"flag":0},"POKEDEX_REWARD_294":{"address":5729954,"default_item":3,"flag":0},"POKEDEX_REWARD_295":{"address":5729956,"default_item":3,"flag":0},"POKEDEX_REWARD_296":{"address":5729958,"default_item":3,"flag":0},"POKEDEX_REWARD_297":{"address":5729960,"default_item":3,"flag":0},"POKEDEX_REWARD_298":{"address":5729962,"default_item":3,"flag":0},"POKEDEX_REWARD_299":{"address":5729964,"default_item":3,"flag":0},"POKEDEX_REWARD_300":{"address":5729966,"default_item":3,"flag":0},"POKEDEX_REWARD_301":{"address":5729968,"default_item":3,"flag":0},"POKEDEX_REWARD_302":{"address":5729970,"default_item":3,"flag":0},"POKEDEX_REWARD_303":{"address":5729972,"default_item":3,"flag":0},"POKEDEX_REWARD_304":{"address":5729974,"default_item":3,"flag":0},"POKEDEX_REWARD_305":{"address":5729976,"default_item":3,"flag":0},"POKEDEX_REWARD_306":{"address":5729978,"default_item":3,"flag":0},"POKEDEX_REWARD_307":{"address":5729980,"default_item":3,"flag":0},"POKEDEX_REWARD_308":{"address":5729982,"default_item":3,"flag":0},"POKEDEX_REWARD_309":{"address":5729984,"default_item":3,"flag":0},"POKEDEX_REWARD_310":{"address":5729986,"default_item":3,"flag":0},"POKEDEX_REWARD_311":{"address":5729988,"default_item":3,"flag":0},"POKEDEX_REWARD_312":{"address":5729990,"default_item":3,"flag":0},"POKEDEX_REWARD_313":{"address":5729992,"default_item":3,"flag":0},"POKEDEX_REWARD_314":{"address":5729994,"default_item":3,"flag":0},"POKEDEX_REWARD_315":{"address":5729996,"default_item":3,"flag":0},"POKEDEX_REWARD_316":{"address":5729998,"default_item":3,"flag":0},"POKEDEX_REWARD_317":{"address":5730000,"default_item":3,"flag":0},"POKEDEX_REWARD_318":{"address":5730002,"default_item":3,"flag":0},"POKEDEX_REWARD_319":{"address":5730004,"default_item":3,"flag":0},"POKEDEX_REWARD_320":{"address":5730006,"default_item":3,"flag":0},"POKEDEX_REWARD_321":{"address":5730008,"default_item":3,"flag":0},"POKEDEX_REWARD_322":{"address":5730010,"default_item":3,"flag":0},"POKEDEX_REWARD_323":{"address":5730012,"default_item":3,"flag":0},"POKEDEX_REWARD_324":{"address":5730014,"default_item":3,"flag":0},"POKEDEX_REWARD_325":{"address":5730016,"default_item":3,"flag":0},"POKEDEX_REWARD_326":{"address":5730018,"default_item":3,"flag":0},"POKEDEX_REWARD_327":{"address":5730020,"default_item":3,"flag":0},"POKEDEX_REWARD_328":{"address":5730022,"default_item":3,"flag":0},"POKEDEX_REWARD_329":{"address":5730024,"default_item":3,"flag":0},"POKEDEX_REWARD_330":{"address":5730026,"default_item":3,"flag":0},"POKEDEX_REWARD_331":{"address":5730028,"default_item":3,"flag":0},"POKEDEX_REWARD_332":{"address":5730030,"default_item":3,"flag":0},"POKEDEX_REWARD_333":{"address":5730032,"default_item":3,"flag":0},"POKEDEX_REWARD_334":{"address":5730034,"default_item":3,"flag":0},"POKEDEX_REWARD_335":{"address":5730036,"default_item":3,"flag":0},"POKEDEX_REWARD_336":{"address":5730038,"default_item":3,"flag":0},"POKEDEX_REWARD_337":{"address":5730040,"default_item":3,"flag":0},"POKEDEX_REWARD_338":{"address":5730042,"default_item":3,"flag":0},"POKEDEX_REWARD_339":{"address":5730044,"default_item":3,"flag":0},"POKEDEX_REWARD_340":{"address":5730046,"default_item":3,"flag":0},"POKEDEX_REWARD_341":{"address":5730048,"default_item":3,"flag":0},"POKEDEX_REWARD_342":{"address":5730050,"default_item":3,"flag":0},"POKEDEX_REWARD_343":{"address":5730052,"default_item":3,"flag":0},"POKEDEX_REWARD_344":{"address":5730054,"default_item":3,"flag":0},"POKEDEX_REWARD_345":{"address":5730056,"default_item":3,"flag":0},"POKEDEX_REWARD_346":{"address":5730058,"default_item":3,"flag":0},"POKEDEX_REWARD_347":{"address":5730060,"default_item":3,"flag":0},"POKEDEX_REWARD_348":{"address":5730062,"default_item":3,"flag":0},"POKEDEX_REWARD_349":{"address":5730064,"default_item":3,"flag":0},"POKEDEX_REWARD_350":{"address":5730066,"default_item":3,"flag":0},"POKEDEX_REWARD_351":{"address":5730068,"default_item":3,"flag":0},"POKEDEX_REWARD_352":{"address":5730070,"default_item":3,"flag":0},"POKEDEX_REWARD_353":{"address":5730072,"default_item":3,"flag":0},"POKEDEX_REWARD_354":{"address":5730074,"default_item":3,"flag":0},"POKEDEX_REWARD_355":{"address":5730076,"default_item":3,"flag":0},"POKEDEX_REWARD_356":{"address":5730078,"default_item":3,"flag":0},"POKEDEX_REWARD_357":{"address":5730080,"default_item":3,"flag":0},"POKEDEX_REWARD_358":{"address":5730082,"default_item":3,"flag":0},"POKEDEX_REWARD_359":{"address":5730084,"default_item":3,"flag":0},"POKEDEX_REWARD_360":{"address":5730086,"default_item":3,"flag":0},"POKEDEX_REWARD_361":{"address":5730088,"default_item":3,"flag":0},"POKEDEX_REWARD_362":{"address":5730090,"default_item":3,"flag":0},"POKEDEX_REWARD_363":{"address":5730092,"default_item":3,"flag":0},"POKEDEX_REWARD_364":{"address":5730094,"default_item":3,"flag":0},"POKEDEX_REWARD_365":{"address":5730096,"default_item":3,"flag":0},"POKEDEX_REWARD_366":{"address":5730098,"default_item":3,"flag":0},"POKEDEX_REWARD_367":{"address":5730100,"default_item":3,"flag":0},"POKEDEX_REWARD_368":{"address":5730102,"default_item":3,"flag":0},"POKEDEX_REWARD_369":{"address":5730104,"default_item":3,"flag":0},"POKEDEX_REWARD_370":{"address":5730106,"default_item":3,"flag":0},"POKEDEX_REWARD_371":{"address":5730108,"default_item":3,"flag":0},"POKEDEX_REWARD_372":{"address":5730110,"default_item":3,"flag":0},"POKEDEX_REWARD_373":{"address":5730112,"default_item":3,"flag":0},"POKEDEX_REWARD_374":{"address":5730114,"default_item":3,"flag":0},"POKEDEX_REWARD_375":{"address":5730116,"default_item":3,"flag":0},"POKEDEX_REWARD_376":{"address":5730118,"default_item":3,"flag":0},"POKEDEX_REWARD_377":{"address":5730120,"default_item":3,"flag":0},"POKEDEX_REWARD_378":{"address":5730122,"default_item":3,"flag":0},"POKEDEX_REWARD_379":{"address":5730124,"default_item":3,"flag":0},"POKEDEX_REWARD_380":{"address":5730126,"default_item":3,"flag":0},"POKEDEX_REWARD_381":{"address":5730128,"default_item":3,"flag":0},"POKEDEX_REWARD_382":{"address":5730130,"default_item":3,"flag":0},"POKEDEX_REWARD_383":{"address":5730132,"default_item":3,"flag":0},"POKEDEX_REWARD_384":{"address":5730134,"default_item":3,"flag":0},"POKEDEX_REWARD_385":{"address":5730136,"default_item":3,"flag":0},"POKEDEX_REWARD_386":{"address":5730138,"default_item":3,"flag":0},"TRAINER_AARON_REWARD":{"address":5602878,"default_item":104,"flag":1677},"TRAINER_ABIGAIL_1_REWARD":{"address":5602800,"default_item":106,"flag":1638},"TRAINER_AIDAN_REWARD":{"address":5603432,"default_item":104,"flag":1954},"TRAINER_AISHA_REWARD":{"address":5603598,"default_item":106,"flag":2037},"TRAINER_ALBERTO_REWARD":{"address":5602108,"default_item":108,"flag":1292},"TRAINER_ALBERT_REWARD":{"address":5602244,"default_item":104,"flag":1360},"TRAINER_ALEXA_REWARD":{"address":5603424,"default_item":104,"flag":1950},"TRAINER_ALEXIA_REWARD":{"address":5602264,"default_item":104,"flag":1370},"TRAINER_ALEX_REWARD":{"address":5602910,"default_item":104,"flag":1693},"TRAINER_ALICE_REWARD":{"address":5602980,"default_item":103,"flag":1728},"TRAINER_ALIX_REWARD":{"address":5603584,"default_item":106,"flag":2030},"TRAINER_ALLEN_REWARD":{"address":5602750,"default_item":103,"flag":1613},"TRAINER_ALLISON_REWARD":{"address":5602858,"default_item":104,"flag":1667},"TRAINER_ALYSSA_REWARD":{"address":5603486,"default_item":106,"flag":1981},"TRAINER_AMY_AND_LIV_1_REWARD":{"address":5603046,"default_item":103,"flag":1761},"TRAINER_ANDREA_REWARD":{"address":5603310,"default_item":106,"flag":1893},"TRAINER_ANDRES_1_REWARD":{"address":5603558,"default_item":104,"flag":2017},"TRAINER_ANDREW_REWARD":{"address":5602756,"default_item":106,"flag":1616},"TRAINER_ANGELICA_REWARD":{"address":5602956,"default_item":104,"flag":1716},"TRAINER_ANGELINA_REWARD":{"address":5603508,"default_item":106,"flag":1992},"TRAINER_ANGELO_REWARD":{"address":5603688,"default_item":104,"flag":2082},"TRAINER_ANNA_AND_MEG_1_REWARD":{"address":5602658,"default_item":106,"flag":1567},"TRAINER_ANNIKA_REWARD":{"address":5603088,"default_item":107,"flag":1782},"TRAINER_ANTHONY_REWARD":{"address":5602788,"default_item":106,"flag":1632},"TRAINER_ARCHIE_REWARD":{"address":5602152,"default_item":107,"flag":1314},"TRAINER_ASHLEY_REWARD":{"address":5603394,"default_item":106,"flag":1935},"TRAINER_ATHENA_REWARD":{"address":5603238,"default_item":104,"flag":1857},"TRAINER_ATSUSHI_REWARD":{"address":5602464,"default_item":104,"flag":1470},"TRAINER_AURON_REWARD":{"address":5603096,"default_item":104,"flag":1786},"TRAINER_AUSTINA_REWARD":{"address":5602200,"default_item":103,"flag":1338},"TRAINER_AUTUMN_REWARD":{"address":5602518,"default_item":106,"flag":1497},"TRAINER_AXLE_REWARD":{"address":5602490,"default_item":108,"flag":1483},"TRAINER_BARNY_REWARD":{"address":5602770,"default_item":104,"flag":1623},"TRAINER_BARRY_REWARD":{"address":5602410,"default_item":106,"flag":1443},"TRAINER_BEAU_REWARD":{"address":5602508,"default_item":106,"flag":1492},"TRAINER_BECKY_REWARD":{"address":5603024,"default_item":106,"flag":1750},"TRAINER_BECK_REWARD":{"address":5602912,"default_item":104,"flag":1694},"TRAINER_BENJAMIN_1_REWARD":{"address":5602790,"default_item":106,"flag":1633},"TRAINER_BEN_REWARD":{"address":5602730,"default_item":106,"flag":1603},"TRAINER_BERKE_REWARD":{"address":5602232,"default_item":104,"flag":1354},"TRAINER_BERNIE_1_REWARD":{"address":5602496,"default_item":106,"flag":1486},"TRAINER_BETHANY_REWARD":{"address":5602686,"default_item":107,"flag":1581},"TRAINER_BETH_REWARD":{"address":5602974,"default_item":103,"flag":1725},"TRAINER_BEVERLY_REWARD":{"address":5602966,"default_item":103,"flag":1721},"TRAINER_BIANCA_REWARD":{"address":5603496,"default_item":106,"flag":1986},"TRAINER_BILLY_REWARD":{"address":5602722,"default_item":103,"flag":1599},"TRAINER_BLAKE_REWARD":{"address":5602554,"default_item":108,"flag":1515},"TRAINER_BRANDEN_REWARD":{"address":5603574,"default_item":106,"flag":2025},"TRAINER_BRANDI_REWARD":{"address":5603596,"default_item":106,"flag":2036},"TRAINER_BRAWLY_1_REWARD":{"address":5602616,"default_item":104,"flag":1546},"TRAINER_BRAXTON_REWARD":{"address":5602234,"default_item":104,"flag":1355},"TRAINER_BRENDAN_LILYCOVE_MUDKIP_REWARD":{"address":5603406,"default_item":104,"flag":1941},"TRAINER_BRENDAN_LILYCOVE_TORCHIC_REWARD":{"address":5603410,"default_item":104,"flag":1943},"TRAINER_BRENDAN_LILYCOVE_TREECKO_REWARD":{"address":5603408,"default_item":104,"flag":1942},"TRAINER_BRENDAN_ROUTE_103_MUDKIP_REWARD":{"address":5603124,"default_item":106,"flag":1800},"TRAINER_BRENDAN_ROUTE_103_TORCHIC_REWARD":{"address":5603136,"default_item":106,"flag":1806},"TRAINER_BRENDAN_ROUTE_103_TREECKO_REWARD":{"address":5603130,"default_item":106,"flag":1803},"TRAINER_BRENDAN_ROUTE_110_MUDKIP_REWARD":{"address":5603126,"default_item":104,"flag":1801},"TRAINER_BRENDAN_ROUTE_110_TORCHIC_REWARD":{"address":5603138,"default_item":104,"flag":1807},"TRAINER_BRENDAN_ROUTE_110_TREECKO_REWARD":{"address":5603132,"default_item":104,"flag":1804},"TRAINER_BRENDAN_ROUTE_119_MUDKIP_REWARD":{"address":5603128,"default_item":104,"flag":1802},"TRAINER_BRENDAN_ROUTE_119_TORCHIC_REWARD":{"address":5603140,"default_item":104,"flag":1808},"TRAINER_BRENDAN_ROUTE_119_TREECKO_REWARD":{"address":5603134,"default_item":104,"flag":1805},"TRAINER_BRENDAN_RUSTBORO_MUDKIP_REWARD":{"address":5603270,"default_item":108,"flag":1873},"TRAINER_BRENDAN_RUSTBORO_TORCHIC_REWARD":{"address":5603282,"default_item":108,"flag":1879},"TRAINER_BRENDAN_RUSTBORO_TREECKO_REWARD":{"address":5603268,"default_item":108,"flag":1872},"TRAINER_BRENDA_REWARD":{"address":5602992,"default_item":106,"flag":1734},"TRAINER_BRENDEN_REWARD":{"address":5603228,"default_item":106,"flag":1852},"TRAINER_BRENT_REWARD":{"address":5602530,"default_item":104,"flag":1503},"TRAINER_BRIANNA_REWARD":{"address":5602320,"default_item":110,"flag":1398},"TRAINER_BRICE_REWARD":{"address":5603336,"default_item":106,"flag":1906},"TRAINER_BRIDGET_REWARD":{"address":5602342,"default_item":107,"flag":1409},"TRAINER_BROOKE_1_REWARD":{"address":5602272,"default_item":108,"flag":1374},"TRAINER_BRYANT_REWARD":{"address":5603576,"default_item":106,"flag":2026},"TRAINER_BRYAN_REWARD":{"address":5603572,"default_item":104,"flag":2024},"TRAINER_CALE_REWARD":{"address":5603612,"default_item":104,"flag":2044},"TRAINER_CALLIE_REWARD":{"address":5603610,"default_item":106,"flag":2043},"TRAINER_CALVIN_1_REWARD":{"address":5602720,"default_item":103,"flag":1598},"TRAINER_CAMDEN_REWARD":{"address":5602832,"default_item":104,"flag":1654},"TRAINER_CAMERON_1_REWARD":{"address":5602560,"default_item":108,"flag":1518},"TRAINER_CAMRON_REWARD":{"address":5603562,"default_item":104,"flag":2019},"TRAINER_CARLEE_REWARD":{"address":5603012,"default_item":106,"flag":1744},"TRAINER_CAROLINA_REWARD":{"address":5603566,"default_item":104,"flag":2021},"TRAINER_CAROLINE_REWARD":{"address":5602282,"default_item":104,"flag":1379},"TRAINER_CAROL_REWARD":{"address":5603026,"default_item":106,"flag":1751},"TRAINER_CARTER_REWARD":{"address":5602774,"default_item":104,"flag":1625},"TRAINER_CATHERINE_1_REWARD":{"address":5603202,"default_item":104,"flag":1839},"TRAINER_CEDRIC_REWARD":{"address":5603034,"default_item":108,"flag":1755},"TRAINER_CELIA_REWARD":{"address":5603570,"default_item":106,"flag":2023},"TRAINER_CELINA_REWARD":{"address":5603494,"default_item":108,"flag":1985},"TRAINER_CHAD_REWARD":{"address":5602432,"default_item":106,"flag":1454},"TRAINER_CHANDLER_REWARD":{"address":5603480,"default_item":103,"flag":1978},"TRAINER_CHARLIE_REWARD":{"address":5602216,"default_item":103,"flag":1346},"TRAINER_CHARLOTTE_REWARD":{"address":5603512,"default_item":106,"flag":1994},"TRAINER_CHASE_REWARD":{"address":5602840,"default_item":104,"flag":1658},"TRAINER_CHESTER_REWARD":{"address":5602900,"default_item":108,"flag":1688},"TRAINER_CHIP_REWARD":{"address":5602174,"default_item":104,"flag":1325},"TRAINER_CHRIS_REWARD":{"address":5603470,"default_item":108,"flag":1973},"TRAINER_CINDY_1_REWARD":{"address":5602312,"default_item":104,"flag":1394},"TRAINER_CLARENCE_REWARD":{"address":5603244,"default_item":106,"flag":1860},"TRAINER_CLARISSA_REWARD":{"address":5602954,"default_item":104,"flag":1715},"TRAINER_CLARK_REWARD":{"address":5603346,"default_item":106,"flag":1911},"TRAINER_CLAUDE_REWARD":{"address":5602760,"default_item":108,"flag":1618},"TRAINER_CLIFFORD_REWARD":{"address":5603252,"default_item":107,"flag":1864},"TRAINER_COBY_REWARD":{"address":5603502,"default_item":106,"flag":1989},"TRAINER_COLE_REWARD":{"address":5602486,"default_item":108,"flag":1481},"TRAINER_COLIN_REWARD":{"address":5602894,"default_item":108,"flag":1685},"TRAINER_COLTON_REWARD":{"address":5602672,"default_item":107,"flag":1574},"TRAINER_CONNIE_REWARD":{"address":5602340,"default_item":107,"flag":1408},"TRAINER_CONOR_REWARD":{"address":5603106,"default_item":104,"flag":1791},"TRAINER_CORY_1_REWARD":{"address":5603564,"default_item":108,"flag":2020},"TRAINER_CRISSY_REWARD":{"address":5603312,"default_item":106,"flag":1894},"TRAINER_CRISTIAN_REWARD":{"address":5603232,"default_item":106,"flag":1854},"TRAINER_CRISTIN_1_REWARD":{"address":5603618,"default_item":104,"flag":2047},"TRAINER_CYNDY_1_REWARD":{"address":5602938,"default_item":106,"flag":1707},"TRAINER_DAISUKE_REWARD":{"address":5602462,"default_item":106,"flag":1469},"TRAINER_DAISY_REWARD":{"address":5602156,"default_item":106,"flag":1316},"TRAINER_DALE_REWARD":{"address":5602766,"default_item":106,"flag":1621},"TRAINER_DALTON_1_REWARD":{"address":5602476,"default_item":106,"flag":1476},"TRAINER_DANA_REWARD":{"address":5603000,"default_item":106,"flag":1738},"TRAINER_DANIELLE_REWARD":{"address":5603384,"default_item":106,"flag":1930},"TRAINER_DAPHNE_REWARD":{"address":5602314,"default_item":110,"flag":1395},"TRAINER_DARCY_REWARD":{"address":5603550,"default_item":104,"flag":2013},"TRAINER_DARIAN_REWARD":{"address":5603476,"default_item":106,"flag":1976},"TRAINER_DARIUS_REWARD":{"address":5603690,"default_item":108,"flag":2083},"TRAINER_DARRIN_REWARD":{"address":5602392,"default_item":103,"flag":1434},"TRAINER_DAVID_REWARD":{"address":5602400,"default_item":103,"flag":1438},"TRAINER_DAVIS_REWARD":{"address":5603162,"default_item":106,"flag":1819},"TRAINER_DAWSON_REWARD":{"address":5603472,"default_item":104,"flag":1974},"TRAINER_DAYTON_REWARD":{"address":5603604,"default_item":108,"flag":2040},"TRAINER_DEANDRE_REWARD":{"address":5603514,"default_item":103,"flag":1995},"TRAINER_DEAN_REWARD":{"address":5602412,"default_item":103,"flag":1444},"TRAINER_DEBRA_REWARD":{"address":5603004,"default_item":106,"flag":1740},"TRAINER_DECLAN_REWARD":{"address":5602114,"default_item":106,"flag":1295},"TRAINER_DEMETRIUS_REWARD":{"address":5602834,"default_item":106,"flag":1655},"TRAINER_DENISE_REWARD":{"address":5602972,"default_item":103,"flag":1724},"TRAINER_DEREK_REWARD":{"address":5602538,"default_item":108,"flag":1507},"TRAINER_DEVAN_REWARD":{"address":5603590,"default_item":106,"flag":2033},"TRAINER_DEZ_AND_LUKE_REWARD":{"address":5603364,"default_item":108,"flag":1920},"TRAINER_DIANA_1_REWARD":{"address":5603032,"default_item":106,"flag":1754},"TRAINER_DIANNE_REWARD":{"address":5602918,"default_item":104,"flag":1697},"TRAINER_DILLON_REWARD":{"address":5602738,"default_item":106,"flag":1607},"TRAINER_DOMINIK_REWARD":{"address":5602388,"default_item":103,"flag":1432},"TRAINER_DONALD_REWARD":{"address":5602532,"default_item":104,"flag":1504},"TRAINER_DONNY_REWARD":{"address":5602852,"default_item":104,"flag":1664},"TRAINER_DOUGLAS_REWARD":{"address":5602390,"default_item":103,"flag":1433},"TRAINER_DOUG_REWARD":{"address":5603320,"default_item":106,"flag":1898},"TRAINER_DRAKE_REWARD":{"address":5602612,"default_item":110,"flag":1544},"TRAINER_DREW_REWARD":{"address":5602506,"default_item":106,"flag":1491},"TRAINER_DUNCAN_REWARD":{"address":5603076,"default_item":108,"flag":1776},"TRAINER_DUSTY_1_REWARD":{"address":5602172,"default_item":104,"flag":1324},"TRAINER_DWAYNE_REWARD":{"address":5603070,"default_item":106,"flag":1773},"TRAINER_DYLAN_1_REWARD":{"address":5602812,"default_item":106,"flag":1644},"TRAINER_EDGAR_REWARD":{"address":5602242,"default_item":104,"flag":1359},"TRAINER_EDMOND_REWARD":{"address":5603066,"default_item":106,"flag":1771},"TRAINER_EDWARDO_REWARD":{"address":5602892,"default_item":108,"flag":1684},"TRAINER_EDWARD_REWARD":{"address":5602548,"default_item":106,"flag":1512},"TRAINER_EDWIN_1_REWARD":{"address":5603108,"default_item":108,"flag":1792},"TRAINER_ED_REWARD":{"address":5602110,"default_item":104,"flag":1293},"TRAINER_ELIJAH_REWARD":{"address":5603568,"default_item":108,"flag":2022},"TRAINER_ELI_REWARD":{"address":5603086,"default_item":108,"flag":1781},"TRAINER_ELLIOT_1_REWARD":{"address":5602762,"default_item":106,"flag":1619},"TRAINER_ERIC_REWARD":{"address":5603348,"default_item":108,"flag":1912},"TRAINER_ERNEST_1_REWARD":{"address":5603068,"default_item":104,"flag":1772},"TRAINER_ETHAN_1_REWARD":{"address":5602516,"default_item":106,"flag":1496},"TRAINER_FABIAN_REWARD":{"address":5603602,"default_item":108,"flag":2039},"TRAINER_FELIX_REWARD":{"address":5602160,"default_item":104,"flag":1318},"TRAINER_FERNANDO_1_REWARD":{"address":5602474,"default_item":108,"flag":1475},"TRAINER_FLANNERY_1_REWARD":{"address":5602620,"default_item":107,"flag":1548},"TRAINER_FLINT_REWARD":{"address":5603392,"default_item":106,"flag":1934},"TRAINER_FOSTER_REWARD":{"address":5602176,"default_item":104,"flag":1326},"TRAINER_FRANKLIN_REWARD":{"address":5602424,"default_item":106,"flag":1450},"TRAINER_FREDRICK_REWARD":{"address":5602142,"default_item":104,"flag":1309},"TRAINER_GABRIELLE_1_REWARD":{"address":5602102,"default_item":104,"flag":1289},"TRAINER_GARRET_REWARD":{"address":5602360,"default_item":110,"flag":1418},"TRAINER_GARRISON_REWARD":{"address":5603178,"default_item":104,"flag":1827},"TRAINER_GEORGE_REWARD":{"address":5602230,"default_item":104,"flag":1353},"TRAINER_GERALD_REWARD":{"address":5603380,"default_item":104,"flag":1928},"TRAINER_GILBERT_REWARD":{"address":5602422,"default_item":106,"flag":1449},"TRAINER_GINA_AND_MIA_1_REWARD":{"address":5603050,"default_item":103,"flag":1763},"TRAINER_GLACIA_REWARD":{"address":5602610,"default_item":110,"flag":1543},"TRAINER_GRACE_REWARD":{"address":5602984,"default_item":106,"flag":1730},"TRAINER_GREG_REWARD":{"address":5603322,"default_item":106,"flag":1899},"TRAINER_GRUNT_AQUA_HIDEOUT_1_REWARD":{"address":5602088,"default_item":106,"flag":1282},"TRAINER_GRUNT_AQUA_HIDEOUT_2_REWARD":{"address":5602090,"default_item":106,"flag":1283},"TRAINER_GRUNT_AQUA_HIDEOUT_3_REWARD":{"address":5602092,"default_item":106,"flag":1284},"TRAINER_GRUNT_AQUA_HIDEOUT_4_REWARD":{"address":5602094,"default_item":106,"flag":1285},"TRAINER_GRUNT_AQUA_HIDEOUT_5_REWARD":{"address":5602138,"default_item":106,"flag":1307},"TRAINER_GRUNT_AQUA_HIDEOUT_6_REWARD":{"address":5602140,"default_item":106,"flag":1308},"TRAINER_GRUNT_AQUA_HIDEOUT_7_REWARD":{"address":5602468,"default_item":106,"flag":1472},"TRAINER_GRUNT_AQUA_HIDEOUT_8_REWARD":{"address":5602470,"default_item":106,"flag":1473},"TRAINER_GRUNT_MAGMA_HIDEOUT_10_REWARD":{"address":5603534,"default_item":106,"flag":2005},"TRAINER_GRUNT_MAGMA_HIDEOUT_11_REWARD":{"address":5603536,"default_item":106,"flag":2006},"TRAINER_GRUNT_MAGMA_HIDEOUT_12_REWARD":{"address":5603538,"default_item":106,"flag":2007},"TRAINER_GRUNT_MAGMA_HIDEOUT_13_REWARD":{"address":5603540,"default_item":106,"flag":2008},"TRAINER_GRUNT_MAGMA_HIDEOUT_14_REWARD":{"address":5603542,"default_item":106,"flag":2009},"TRAINER_GRUNT_MAGMA_HIDEOUT_15_REWARD":{"address":5603544,"default_item":106,"flag":2010},"TRAINER_GRUNT_MAGMA_HIDEOUT_16_REWARD":{"address":5603546,"default_item":106,"flag":2011},"TRAINER_GRUNT_MAGMA_HIDEOUT_1_REWARD":{"address":5603516,"default_item":106,"flag":1996},"TRAINER_GRUNT_MAGMA_HIDEOUT_2_REWARD":{"address":5603518,"default_item":106,"flag":1997},"TRAINER_GRUNT_MAGMA_HIDEOUT_3_REWARD":{"address":5603520,"default_item":106,"flag":1998},"TRAINER_GRUNT_MAGMA_HIDEOUT_4_REWARD":{"address":5603522,"default_item":106,"flag":1999},"TRAINER_GRUNT_MAGMA_HIDEOUT_5_REWARD":{"address":5603524,"default_item":106,"flag":2000},"TRAINER_GRUNT_MAGMA_HIDEOUT_6_REWARD":{"address":5603526,"default_item":106,"flag":2001},"TRAINER_GRUNT_MAGMA_HIDEOUT_7_REWARD":{"address":5603528,"default_item":106,"flag":2002},"TRAINER_GRUNT_MAGMA_HIDEOUT_8_REWARD":{"address":5603530,"default_item":106,"flag":2003},"TRAINER_GRUNT_MAGMA_HIDEOUT_9_REWARD":{"address":5603532,"default_item":106,"flag":2004},"TRAINER_GRUNT_MT_CHIMNEY_1_REWARD":{"address":5602376,"default_item":106,"flag":1426},"TRAINER_GRUNT_MT_CHIMNEY_2_REWARD":{"address":5603242,"default_item":106,"flag":1859},"TRAINER_GRUNT_MT_PYRE_1_REWARD":{"address":5602130,"default_item":106,"flag":1303},"TRAINER_GRUNT_MT_PYRE_2_REWARD":{"address":5602132,"default_item":106,"flag":1304},"TRAINER_GRUNT_MT_PYRE_3_REWARD":{"address":5602134,"default_item":106,"flag":1305},"TRAINER_GRUNT_MT_PYRE_4_REWARD":{"address":5603222,"default_item":106,"flag":1849},"TRAINER_GRUNT_MUSEUM_1_REWARD":{"address":5602124,"default_item":106,"flag":1300},"TRAINER_GRUNT_MUSEUM_2_REWARD":{"address":5602126,"default_item":106,"flag":1301},"TRAINER_GRUNT_PETALBURG_WOODS_REWARD":{"address":5602104,"default_item":103,"flag":1290},"TRAINER_GRUNT_RUSTURF_TUNNEL_REWARD":{"address":5602116,"default_item":103,"flag":1296},"TRAINER_GRUNT_SEAFLOOR_CAVERN_1_REWARD":{"address":5602096,"default_item":108,"flag":1286},"TRAINER_GRUNT_SEAFLOOR_CAVERN_2_REWARD":{"address":5602098,"default_item":108,"flag":1287},"TRAINER_GRUNT_SEAFLOOR_CAVERN_3_REWARD":{"address":5602100,"default_item":108,"flag":1288},"TRAINER_GRUNT_SEAFLOOR_CAVERN_4_REWARD":{"address":5602112,"default_item":108,"flag":1294},"TRAINER_GRUNT_SEAFLOOR_CAVERN_5_REWARD":{"address":5603218,"default_item":108,"flag":1847},"TRAINER_GRUNT_SPACE_CENTER_1_REWARD":{"address":5602128,"default_item":106,"flag":1302},"TRAINER_GRUNT_SPACE_CENTER_2_REWARD":{"address":5602316,"default_item":106,"flag":1396},"TRAINER_GRUNT_SPACE_CENTER_3_REWARD":{"address":5603256,"default_item":106,"flag":1866},"TRAINER_GRUNT_SPACE_CENTER_4_REWARD":{"address":5603258,"default_item":106,"flag":1867},"TRAINER_GRUNT_SPACE_CENTER_5_REWARD":{"address":5603260,"default_item":106,"flag":1868},"TRAINER_GRUNT_SPACE_CENTER_6_REWARD":{"address":5603262,"default_item":106,"flag":1869},"TRAINER_GRUNT_SPACE_CENTER_7_REWARD":{"address":5603264,"default_item":106,"flag":1870},"TRAINER_GRUNT_WEATHER_INST_1_REWARD":{"address":5602118,"default_item":106,"flag":1297},"TRAINER_GRUNT_WEATHER_INST_2_REWARD":{"address":5602120,"default_item":106,"flag":1298},"TRAINER_GRUNT_WEATHER_INST_3_REWARD":{"address":5602122,"default_item":106,"flag":1299},"TRAINER_GRUNT_WEATHER_INST_4_REWARD":{"address":5602136,"default_item":106,"flag":1306},"TRAINER_GRUNT_WEATHER_INST_5_REWARD":{"address":5603276,"default_item":106,"flag":1876},"TRAINER_GWEN_REWARD":{"address":5602202,"default_item":103,"flag":1339},"TRAINER_HAILEY_REWARD":{"address":5603478,"default_item":103,"flag":1977},"TRAINER_HALEY_1_REWARD":{"address":5603292,"default_item":103,"flag":1884},"TRAINER_HALLE_REWARD":{"address":5603176,"default_item":104,"flag":1826},"TRAINER_HANNAH_REWARD":{"address":5602572,"default_item":108,"flag":1524},"TRAINER_HARRISON_REWARD":{"address":5603240,"default_item":106,"flag":1858},"TRAINER_HAYDEN_REWARD":{"address":5603498,"default_item":106,"flag":1987},"TRAINER_HECTOR_REWARD":{"address":5603110,"default_item":104,"flag":1793},"TRAINER_HEIDI_REWARD":{"address":5603022,"default_item":106,"flag":1749},"TRAINER_HELENE_REWARD":{"address":5603586,"default_item":106,"flag":2031},"TRAINER_HENRY_REWARD":{"address":5603420,"default_item":104,"flag":1948},"TRAINER_HERMAN_REWARD":{"address":5602418,"default_item":106,"flag":1447},"TRAINER_HIDEO_REWARD":{"address":5603386,"default_item":106,"flag":1931},"TRAINER_HITOSHI_REWARD":{"address":5602444,"default_item":104,"flag":1460},"TRAINER_HOPE_REWARD":{"address":5602276,"default_item":104,"flag":1376},"TRAINER_HUDSON_REWARD":{"address":5603104,"default_item":104,"flag":1790},"TRAINER_HUEY_REWARD":{"address":5603064,"default_item":106,"flag":1770},"TRAINER_HUGH_REWARD":{"address":5602882,"default_item":108,"flag":1679},"TRAINER_HUMBERTO_REWARD":{"address":5602888,"default_item":108,"flag":1682},"TRAINER_IMANI_REWARD":{"address":5602968,"default_item":103,"flag":1722},"TRAINER_IRENE_REWARD":{"address":5603036,"default_item":106,"flag":1756},"TRAINER_ISAAC_1_REWARD":{"address":5603160,"default_item":106,"flag":1818},"TRAINER_ISABELLA_REWARD":{"address":5603274,"default_item":104,"flag":1875},"TRAINER_ISABELLE_REWARD":{"address":5603556,"default_item":103,"flag":2016},"TRAINER_ISABEL_1_REWARD":{"address":5602688,"default_item":104,"flag":1582},"TRAINER_ISAIAH_1_REWARD":{"address":5602836,"default_item":104,"flag":1656},"TRAINER_ISOBEL_REWARD":{"address":5602850,"default_item":104,"flag":1663},"TRAINER_IVAN_REWARD":{"address":5602758,"default_item":106,"flag":1617},"TRAINER_JACE_REWARD":{"address":5602492,"default_item":108,"flag":1484},"TRAINER_JACKI_1_REWARD":{"address":5602582,"default_item":108,"flag":1529},"TRAINER_JACKSON_1_REWARD":{"address":5603188,"default_item":104,"flag":1832},"TRAINER_JACK_REWARD":{"address":5602428,"default_item":106,"flag":1452},"TRAINER_JACLYN_REWARD":{"address":5602570,"default_item":106,"flag":1523},"TRAINER_JACOB_REWARD":{"address":5602786,"default_item":106,"flag":1631},"TRAINER_JAIDEN_REWARD":{"address":5603582,"default_item":106,"flag":2029},"TRAINER_JAMES_1_REWARD":{"address":5603326,"default_item":103,"flag":1901},"TRAINER_JANICE_REWARD":{"address":5603294,"default_item":103,"flag":1885},"TRAINER_JANI_REWARD":{"address":5602920,"default_item":103,"flag":1698},"TRAINER_JARED_REWARD":{"address":5602886,"default_item":108,"flag":1681},"TRAINER_JASMINE_REWARD":{"address":5602802,"default_item":103,"flag":1639},"TRAINER_JAYLEN_REWARD":{"address":5602736,"default_item":106,"flag":1606},"TRAINER_JAZMYN_REWARD":{"address":5603090,"default_item":106,"flag":1783},"TRAINER_JEFFREY_1_REWARD":{"address":5602536,"default_item":104,"flag":1506},"TRAINER_JEFF_REWARD":{"address":5602488,"default_item":108,"flag":1482},"TRAINER_JENNA_REWARD":{"address":5603204,"default_item":104,"flag":1840},"TRAINER_JENNIFER_REWARD":{"address":5602274,"default_item":104,"flag":1375},"TRAINER_JENNY_1_REWARD":{"address":5602982,"default_item":106,"flag":1729},"TRAINER_JEROME_REWARD":{"address":5602396,"default_item":103,"flag":1436},"TRAINER_JERRY_1_REWARD":{"address":5602630,"default_item":103,"flag":1553},"TRAINER_JESSICA_1_REWARD":{"address":5602338,"default_item":104,"flag":1407},"TRAINER_JOCELYN_REWARD":{"address":5602934,"default_item":106,"flag":1705},"TRAINER_JODY_REWARD":{"address":5602266,"default_item":104,"flag":1371},"TRAINER_JOEY_REWARD":{"address":5602728,"default_item":103,"flag":1602},"TRAINER_JOHANNA_REWARD":{"address":5603378,"default_item":104,"flag":1927},"TRAINER_JOHNSON_REWARD":{"address":5603592,"default_item":103,"flag":2034},"TRAINER_JOHN_AND_JAY_1_REWARD":{"address":5603446,"default_item":104,"flag":1961},"TRAINER_JONAH_REWARD":{"address":5603418,"default_item":104,"flag":1947},"TRAINER_JONAS_REWARD":{"address":5603092,"default_item":106,"flag":1784},"TRAINER_JONATHAN_REWARD":{"address":5603280,"default_item":104,"flag":1878},"TRAINER_JOSEPH_REWARD":{"address":5603484,"default_item":106,"flag":1980},"TRAINER_JOSE_REWARD":{"address":5603318,"default_item":103,"flag":1897},"TRAINER_JOSH_REWARD":{"address":5602724,"default_item":103,"flag":1600},"TRAINER_JOSUE_REWARD":{"address":5603560,"default_item":108,"flag":2018},"TRAINER_JUAN_1_REWARD":{"address":5602628,"default_item":109,"flag":1552},"TRAINER_JULIE_REWARD":{"address":5602284,"default_item":104,"flag":1380},"TRAINER_JULIO_REWARD":{"address":5603216,"default_item":108,"flag":1846},"TRAINER_KAI_REWARD":{"address":5603510,"default_item":108,"flag":1993},"TRAINER_KALEB_REWARD":{"address":5603482,"default_item":104,"flag":1979},"TRAINER_KARA_REWARD":{"address":5602998,"default_item":106,"flag":1737},"TRAINER_KAREN_1_REWARD":{"address":5602644,"default_item":103,"flag":1560},"TRAINER_KATELYNN_REWARD":{"address":5602734,"default_item":104,"flag":1605},"TRAINER_KATELYN_1_REWARD":{"address":5602856,"default_item":104,"flag":1666},"TRAINER_KATE_AND_JOY_REWARD":{"address":5602656,"default_item":106,"flag":1566},"TRAINER_KATHLEEN_REWARD":{"address":5603250,"default_item":108,"flag":1863},"TRAINER_KATIE_REWARD":{"address":5602994,"default_item":106,"flag":1735},"TRAINER_KAYLA_REWARD":{"address":5602578,"default_item":106,"flag":1527},"TRAINER_KAYLEY_REWARD":{"address":5603094,"default_item":104,"flag":1785},"TRAINER_KEEGAN_REWARD":{"address":5602494,"default_item":108,"flag":1485},"TRAINER_KEIGO_REWARD":{"address":5603388,"default_item":106,"flag":1932},"TRAINER_KELVIN_REWARD":{"address":5603098,"default_item":104,"flag":1787},"TRAINER_KENT_REWARD":{"address":5603324,"default_item":106,"flag":1900},"TRAINER_KEVIN_REWARD":{"address":5602426,"default_item":106,"flag":1451},"TRAINER_KIM_AND_IRIS_REWARD":{"address":5603440,"default_item":106,"flag":1958},"TRAINER_KINDRA_REWARD":{"address":5602296,"default_item":108,"flag":1386},"TRAINER_KIRA_AND_DAN_1_REWARD":{"address":5603368,"default_item":108,"flag":1922},"TRAINER_KIRK_REWARD":{"address":5602466,"default_item":106,"flag":1471},"TRAINER_KIYO_REWARD":{"address":5602446,"default_item":104,"flag":1461},"TRAINER_KOICHI_REWARD":{"address":5602448,"default_item":108,"flag":1462},"TRAINER_KOJI_1_REWARD":{"address":5603428,"default_item":104,"flag":1952},"TRAINER_KYLA_REWARD":{"address":5602970,"default_item":103,"flag":1723},"TRAINER_KYRA_REWARD":{"address":5603580,"default_item":104,"flag":2028},"TRAINER_LAO_1_REWARD":{"address":5602922,"default_item":103,"flag":1699},"TRAINER_LARRY_REWARD":{"address":5602510,"default_item":106,"flag":1493},"TRAINER_LAURA_REWARD":{"address":5602936,"default_item":106,"flag":1706},"TRAINER_LAUREL_REWARD":{"address":5603010,"default_item":106,"flag":1743},"TRAINER_LAWRENCE_REWARD":{"address":5603504,"default_item":106,"flag":1990},"TRAINER_LEAH_REWARD":{"address":5602154,"default_item":108,"flag":1315},"TRAINER_LEA_AND_JED_REWARD":{"address":5603366,"default_item":104,"flag":1921},"TRAINER_LENNY_REWARD":{"address":5603340,"default_item":108,"flag":1908},"TRAINER_LEONARDO_REWARD":{"address":5603236,"default_item":106,"flag":1856},"TRAINER_LEONARD_REWARD":{"address":5603074,"default_item":104,"flag":1775},"TRAINER_LEONEL_REWARD":{"address":5603608,"default_item":104,"flag":2042},"TRAINER_LILA_AND_ROY_1_REWARD":{"address":5603458,"default_item":106,"flag":1967},"TRAINER_LILITH_REWARD":{"address":5603230,"default_item":106,"flag":1853},"TRAINER_LINDA_REWARD":{"address":5603006,"default_item":106,"flag":1741},"TRAINER_LISA_AND_RAY_REWARD":{"address":5603468,"default_item":106,"flag":1972},"TRAINER_LOLA_1_REWARD":{"address":5602198,"default_item":103,"flag":1337},"TRAINER_LORENZO_REWARD":{"address":5603190,"default_item":104,"flag":1833},"TRAINER_LUCAS_1_REWARD":{"address":5603342,"default_item":108,"flag":1909},"TRAINER_LUIS_REWARD":{"address":5602386,"default_item":103,"flag":1431},"TRAINER_LUNG_REWARD":{"address":5602924,"default_item":103,"flag":1700},"TRAINER_LYDIA_1_REWARD":{"address":5603174,"default_item":106,"flag":1825},"TRAINER_LYLE_REWARD":{"address":5603316,"default_item":103,"flag":1896},"TRAINER_MACEY_REWARD":{"address":5603266,"default_item":108,"flag":1871},"TRAINER_MADELINE_1_REWARD":{"address":5602952,"default_item":108,"flag":1714},"TRAINER_MAKAYLA_REWARD":{"address":5603600,"default_item":104,"flag":2038},"TRAINER_MARCEL_REWARD":{"address":5602106,"default_item":104,"flag":1291},"TRAINER_MARCOS_REWARD":{"address":5603488,"default_item":106,"flag":1982},"TRAINER_MARC_REWARD":{"address":5603226,"default_item":106,"flag":1851},"TRAINER_MARIA_1_REWARD":{"address":5602822,"default_item":106,"flag":1649},"TRAINER_MARK_REWARD":{"address":5602374,"default_item":104,"flag":1425},"TRAINER_MARLENE_REWARD":{"address":5603588,"default_item":106,"flag":2032},"TRAINER_MARLEY_REWARD":{"address":5603100,"default_item":104,"flag":1788},"TRAINER_MARY_REWARD":{"address":5602262,"default_item":104,"flag":1369},"TRAINER_MATTHEW_REWARD":{"address":5602398,"default_item":103,"flag":1437},"TRAINER_MATT_REWARD":{"address":5602144,"default_item":104,"flag":1310},"TRAINER_MAURA_REWARD":{"address":5602576,"default_item":108,"flag":1526},"TRAINER_MAXIE_MAGMA_HIDEOUT_REWARD":{"address":5603286,"default_item":107,"flag":1881},"TRAINER_MAXIE_MT_CHIMNEY_REWARD":{"address":5603288,"default_item":104,"flag":1882},"TRAINER_MAY_LILYCOVE_MUDKIP_REWARD":{"address":5603412,"default_item":104,"flag":1944},"TRAINER_MAY_LILYCOVE_TORCHIC_REWARD":{"address":5603416,"default_item":104,"flag":1946},"TRAINER_MAY_LILYCOVE_TREECKO_REWARD":{"address":5603414,"default_item":104,"flag":1945},"TRAINER_MAY_ROUTE_103_MUDKIP_REWARD":{"address":5603142,"default_item":106,"flag":1809},"TRAINER_MAY_ROUTE_103_TORCHIC_REWARD":{"address":5603154,"default_item":106,"flag":1815},"TRAINER_MAY_ROUTE_103_TREECKO_REWARD":{"address":5603148,"default_item":106,"flag":1812},"TRAINER_MAY_ROUTE_110_MUDKIP_REWARD":{"address":5603144,"default_item":104,"flag":1810},"TRAINER_MAY_ROUTE_110_TORCHIC_REWARD":{"address":5603156,"default_item":104,"flag":1816},"TRAINER_MAY_ROUTE_110_TREECKO_REWARD":{"address":5603150,"default_item":104,"flag":1813},"TRAINER_MAY_ROUTE_119_MUDKIP_REWARD":{"address":5603146,"default_item":104,"flag":1811},"TRAINER_MAY_ROUTE_119_TORCHIC_REWARD":{"address":5603158,"default_item":104,"flag":1817},"TRAINER_MAY_ROUTE_119_TREECKO_REWARD":{"address":5603152,"default_item":104,"flag":1814},"TRAINER_MAY_RUSTBORO_MUDKIP_REWARD":{"address":5603284,"default_item":108,"flag":1880},"TRAINER_MAY_RUSTBORO_TORCHIC_REWARD":{"address":5603622,"default_item":108,"flag":2049},"TRAINER_MAY_RUSTBORO_TREECKO_REWARD":{"address":5603620,"default_item":108,"flag":2048},"TRAINER_MELINA_REWARD":{"address":5603594,"default_item":106,"flag":2035},"TRAINER_MELISSA_REWARD":{"address":5602332,"default_item":104,"flag":1404},"TRAINER_MEL_AND_PAUL_REWARD":{"address":5603444,"default_item":108,"flag":1960},"TRAINER_MICAH_REWARD":{"address":5602594,"default_item":107,"flag":1535},"TRAINER_MICHELLE_REWARD":{"address":5602280,"default_item":104,"flag":1378},"TRAINER_MIGUEL_1_REWARD":{"address":5602670,"default_item":104,"flag":1573},"TRAINER_MIKE_2_REWARD":{"address":5603354,"default_item":106,"flag":1915},"TRAINER_MISSY_REWARD":{"address":5602978,"default_item":103,"flag":1727},"TRAINER_MITCHELL_REWARD":{"address":5603164,"default_item":104,"flag":1820},"TRAINER_MIU_AND_YUKI_REWARD":{"address":5603052,"default_item":106,"flag":1764},"TRAINER_MOLLIE_REWARD":{"address":5602358,"default_item":104,"flag":1417},"TRAINER_MYLES_REWARD":{"address":5603614,"default_item":104,"flag":2045},"TRAINER_NANCY_REWARD":{"address":5603028,"default_item":106,"flag":1752},"TRAINER_NAOMI_REWARD":{"address":5602322,"default_item":110,"flag":1399},"TRAINER_NATE_REWARD":{"address":5603248,"default_item":107,"flag":1862},"TRAINER_NED_REWARD":{"address":5602764,"default_item":106,"flag":1620},"TRAINER_NICHOLAS_REWARD":{"address":5603254,"default_item":108,"flag":1865},"TRAINER_NICOLAS_1_REWARD":{"address":5602868,"default_item":104,"flag":1672},"TRAINER_NIKKI_REWARD":{"address":5602990,"default_item":106,"flag":1733},"TRAINER_NOB_1_REWARD":{"address":5602450,"default_item":106,"flag":1463},"TRAINER_NOLAN_REWARD":{"address":5602768,"default_item":108,"flag":1622},"TRAINER_NOLEN_REWARD":{"address":5602406,"default_item":106,"flag":1441},"TRAINER_NORMAN_1_REWARD":{"address":5602622,"default_item":107,"flag":1549},"TRAINER_OLIVIA_REWARD":{"address":5602344,"default_item":107,"flag":1410},"TRAINER_OWEN_REWARD":{"address":5602250,"default_item":104,"flag":1363},"TRAINER_PABLO_1_REWARD":{"address":5602838,"default_item":104,"flag":1657},"TRAINER_PARKER_REWARD":{"address":5602228,"default_item":104,"flag":1352},"TRAINER_PAT_REWARD":{"address":5603616,"default_item":104,"flag":2046},"TRAINER_PAXTON_REWARD":{"address":5603272,"default_item":104,"flag":1874},"TRAINER_PERRY_REWARD":{"address":5602880,"default_item":108,"flag":1678},"TRAINER_PETE_REWARD":{"address":5603554,"default_item":103,"flag":2015},"TRAINER_PHILLIP_REWARD":{"address":5603072,"default_item":104,"flag":1774},"TRAINER_PHIL_REWARD":{"address":5602884,"default_item":108,"flag":1680},"TRAINER_PHOEBE_REWARD":{"address":5602608,"default_item":110,"flag":1542},"TRAINER_PRESLEY_REWARD":{"address":5602890,"default_item":104,"flag":1683},"TRAINER_PRESTON_REWARD":{"address":5602550,"default_item":108,"flag":1513},"TRAINER_QUINCY_REWARD":{"address":5602732,"default_item":104,"flag":1604},"TRAINER_RACHEL_REWARD":{"address":5603606,"default_item":104,"flag":2041},"TRAINER_RANDALL_REWARD":{"address":5602226,"default_item":104,"flag":1351},"TRAINER_REED_REWARD":{"address":5603434,"default_item":106,"flag":1955},"TRAINER_RELI_AND_IAN_REWARD":{"address":5603456,"default_item":106,"flag":1966},"TRAINER_REYNA_REWARD":{"address":5603102,"default_item":108,"flag":1789},"TRAINER_RHETT_REWARD":{"address":5603490,"default_item":106,"flag":1983},"TRAINER_RICHARD_REWARD":{"address":5602416,"default_item":106,"flag":1446},"TRAINER_RICKY_1_REWARD":{"address":5602212,"default_item":103,"flag":1344},"TRAINER_RICK_REWARD":{"address":5603314,"default_item":103,"flag":1895},"TRAINER_RILEY_REWARD":{"address":5603390,"default_item":106,"flag":1933},"TRAINER_ROBERT_1_REWARD":{"address":5602896,"default_item":108,"flag":1686},"TRAINER_RODNEY_REWARD":{"address":5602414,"default_item":106,"flag":1445},"TRAINER_ROGER_REWARD":{"address":5603422,"default_item":104,"flag":1949},"TRAINER_ROLAND_REWARD":{"address":5602404,"default_item":106,"flag":1440},"TRAINER_RONALD_REWARD":{"address":5602784,"default_item":104,"flag":1630},"TRAINER_ROSE_1_REWARD":{"address":5602158,"default_item":106,"flag":1317},"TRAINER_ROXANNE_1_REWARD":{"address":5602614,"default_item":104,"flag":1545},"TRAINER_RUBEN_REWARD":{"address":5603426,"default_item":104,"flag":1951},"TRAINER_SAMANTHA_REWARD":{"address":5602574,"default_item":108,"flag":1525},"TRAINER_SAMUEL_REWARD":{"address":5602246,"default_item":104,"flag":1361},"TRAINER_SANTIAGO_REWARD":{"address":5602420,"default_item":106,"flag":1448},"TRAINER_SARAH_REWARD":{"address":5603474,"default_item":104,"flag":1975},"TRAINER_SAWYER_1_REWARD":{"address":5602086,"default_item":108,"flag":1281},"TRAINER_SHANE_REWARD":{"address":5602512,"default_item":106,"flag":1494},"TRAINER_SHANNON_REWARD":{"address":5602278,"default_item":104,"flag":1377},"TRAINER_SHARON_REWARD":{"address":5602988,"default_item":106,"flag":1732},"TRAINER_SHAWN_REWARD":{"address":5602472,"default_item":106,"flag":1474},"TRAINER_SHAYLA_REWARD":{"address":5603578,"default_item":108,"flag":2027},"TRAINER_SHEILA_REWARD":{"address":5602334,"default_item":104,"flag":1405},"TRAINER_SHELBY_1_REWARD":{"address":5602710,"default_item":108,"flag":1593},"TRAINER_SHELLY_SEAFLOOR_CAVERN_REWARD":{"address":5602150,"default_item":104,"flag":1313},"TRAINER_SHELLY_WEATHER_INSTITUTE_REWARD":{"address":5602148,"default_item":104,"flag":1312},"TRAINER_SHIRLEY_REWARD":{"address":5602336,"default_item":104,"flag":1406},"TRAINER_SIDNEY_REWARD":{"address":5602606,"default_item":110,"flag":1541},"TRAINER_SIENNA_REWARD":{"address":5603002,"default_item":106,"flag":1739},"TRAINER_SIMON_REWARD":{"address":5602214,"default_item":103,"flag":1345},"TRAINER_SOPHIE_REWARD":{"address":5603500,"default_item":106,"flag":1988},"TRAINER_SPENCER_REWARD":{"address":5602402,"default_item":106,"flag":1439},"TRAINER_STAN_REWARD":{"address":5602408,"default_item":106,"flag":1442},"TRAINER_STEVEN_REWARD":{"address":5603692,"default_item":109,"flag":2084},"TRAINER_STEVE_1_REWARD":{"address":5602370,"default_item":104,"flag":1423},"TRAINER_SUSIE_REWARD":{"address":5602996,"default_item":106,"flag":1736},"TRAINER_SYLVIA_REWARD":{"address":5603234,"default_item":108,"flag":1855},"TRAINER_TABITHA_MAGMA_HIDEOUT_REWARD":{"address":5603548,"default_item":104,"flag":2012},"TRAINER_TABITHA_MT_CHIMNEY_REWARD":{"address":5603278,"default_item":108,"flag":1877},"TRAINER_TAKAO_REWARD":{"address":5602442,"default_item":106,"flag":1459},"TRAINER_TAKASHI_REWARD":{"address":5602916,"default_item":106,"flag":1696},"TRAINER_TALIA_REWARD":{"address":5602854,"default_item":104,"flag":1665},"TRAINER_TAMMY_REWARD":{"address":5602298,"default_item":106,"flag":1387},"TRAINER_TANYA_REWARD":{"address":5602986,"default_item":106,"flag":1731},"TRAINER_TARA_REWARD":{"address":5602976,"default_item":103,"flag":1726},"TRAINER_TASHA_REWARD":{"address":5602302,"default_item":108,"flag":1389},"TRAINER_TATE_AND_LIZA_1_REWARD":{"address":5602626,"default_item":109,"flag":1551},"TRAINER_TAYLOR_REWARD":{"address":5602534,"default_item":104,"flag":1505},"TRAINER_THALIA_1_REWARD":{"address":5602372,"default_item":104,"flag":1424},"TRAINER_THOMAS_REWARD":{"address":5602596,"default_item":107,"flag":1536},"TRAINER_TIANA_REWARD":{"address":5603290,"default_item":103,"flag":1883},"TRAINER_TIFFANY_REWARD":{"address":5602346,"default_item":107,"flag":1411},"TRAINER_TIMMY_REWARD":{"address":5602752,"default_item":103,"flag":1614},"TRAINER_TIMOTHY_1_REWARD":{"address":5602698,"default_item":104,"flag":1587},"TRAINER_TISHA_REWARD":{"address":5603436,"default_item":106,"flag":1956},"TRAINER_TOMMY_REWARD":{"address":5602726,"default_item":103,"flag":1601},"TRAINER_TONY_1_REWARD":{"address":5602394,"default_item":103,"flag":1435},"TRAINER_TORI_AND_TIA_REWARD":{"address":5603438,"default_item":103,"flag":1957},"TRAINER_TRAVIS_REWARD":{"address":5602520,"default_item":106,"flag":1498},"TRAINER_TRENT_1_REWARD":{"address":5603338,"default_item":106,"flag":1907},"TRAINER_TYRA_AND_IVY_REWARD":{"address":5603442,"default_item":106,"flag":1959},"TRAINER_TYRON_REWARD":{"address":5603492,"default_item":106,"flag":1984},"TRAINER_VALERIE_1_REWARD":{"address":5602300,"default_item":108,"flag":1388},"TRAINER_VANESSA_REWARD":{"address":5602684,"default_item":104,"flag":1580},"TRAINER_VICKY_REWARD":{"address":5602708,"default_item":108,"flag":1592},"TRAINER_VICTORIA_REWARD":{"address":5602682,"default_item":106,"flag":1579},"TRAINER_VICTOR_REWARD":{"address":5602668,"default_item":106,"flag":1572},"TRAINER_VIOLET_REWARD":{"address":5602162,"default_item":104,"flag":1319},"TRAINER_VIRGIL_REWARD":{"address":5602552,"default_item":108,"flag":1514},"TRAINER_VITO_REWARD":{"address":5602248,"default_item":104,"flag":1362},"TRAINER_VIVIAN_REWARD":{"address":5603382,"default_item":106,"flag":1929},"TRAINER_VIVI_REWARD":{"address":5603296,"default_item":106,"flag":1886},"TRAINER_WADE_REWARD":{"address":5602772,"default_item":106,"flag":1624},"TRAINER_WALLACE_REWARD":{"address":5602754,"default_item":110,"flag":1615},"TRAINER_WALLY_MAUVILLE_REWARD":{"address":5603396,"default_item":108,"flag":1936},"TRAINER_WALLY_VR_1_REWARD":{"address":5603122,"default_item":107,"flag":1799},"TRAINER_WALTER_1_REWARD":{"address":5602592,"default_item":104,"flag":1534},"TRAINER_WARREN_REWARD":{"address":5602260,"default_item":104,"flag":1368},"TRAINER_WATTSON_1_REWARD":{"address":5602618,"default_item":104,"flag":1547},"TRAINER_WAYNE_REWARD":{"address":5603430,"default_item":104,"flag":1953},"TRAINER_WENDY_REWARD":{"address":5602268,"default_item":104,"flag":1372},"TRAINER_WILLIAM_REWARD":{"address":5602556,"default_item":106,"flag":1516},"TRAINER_WILTON_1_REWARD":{"address":5602240,"default_item":108,"flag":1358},"TRAINER_WINONA_1_REWARD":{"address":5602624,"default_item":107,"flag":1550},"TRAINER_WINSTON_1_REWARD":{"address":5602356,"default_item":104,"flag":1416},"TRAINER_WYATT_REWARD":{"address":5603506,"default_item":104,"flag":1991},"TRAINER_YASU_REWARD":{"address":5602914,"default_item":106,"flag":1695},"TRAINER_ZANDER_REWARD":{"address":5602146,"default_item":108,"flag":1311}},"maps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":{"header_address":4766420,"warp_table_address":5496844},"MAP_ABANDONED_SHIP_CORRIDORS_1F":{"header_address":4766196,"warp_table_address":5495920},"MAP_ABANDONED_SHIP_CORRIDORS_B1F":{"header_address":4766252,"warp_table_address":5496248},"MAP_ABANDONED_SHIP_DECK":{"header_address":4766168,"warp_table_address":5495812},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":{"fishing_encounters":{"address":5609088,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766476,"warp_table_address":5496908,"water_encounters":{"address":5609060,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":{"header_address":4766504,"warp_table_address":5497120},"MAP_ABANDONED_SHIP_ROOMS2_1F":{"header_address":4766392,"warp_table_address":5496752},"MAP_ABANDONED_SHIP_ROOMS2_B1F":{"header_address":4766308,"warp_table_address":5496484},"MAP_ABANDONED_SHIP_ROOMS_1F":{"header_address":4766224,"warp_table_address":5496132},"MAP_ABANDONED_SHIP_ROOMS_B1F":{"fishing_encounters":{"address":5606324,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766280,"warp_table_address":5496392,"water_encounters":{"address":5606296,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_ROOM_B1F":{"header_address":4766364,"warp_table_address":5496596},"MAP_ABANDONED_SHIP_UNDERWATER1":{"header_address":4766336,"warp_table_address":5496536},"MAP_ABANDONED_SHIP_UNDERWATER2":{"header_address":4766448,"warp_table_address":5496880},"MAP_ALTERING_CAVE":{"header_address":4767624,"land_encounters":{"address":5613400,"slots":[41,41,41,41,41,41,41,41,41,41,41,41]},"warp_table_address":5500436},"MAP_ANCIENT_TOMB":{"header_address":4766560,"warp_table_address":5497460},"MAP_AQUA_HIDEOUT_1F":{"header_address":4765300,"warp_table_address":5490892},"MAP_AQUA_HIDEOUT_B1F":{"header_address":4765328,"warp_table_address":5491152},"MAP_AQUA_HIDEOUT_B2F":{"header_address":4765356,"warp_table_address":5491516},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":{"header_address":4766728,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":{"header_address":4766756,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":{"header_address":4766784,"warp_table_address":4160749568},"MAP_ARTISAN_CAVE_1F":{"header_address":4767456,"land_encounters":{"address":5613344,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500172},"MAP_ARTISAN_CAVE_B1F":{"header_address":4767428,"land_encounters":{"address":5613288,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500064},"MAP_BATTLE_COLOSSEUM_2P":{"header_address":4768352,"warp_table_address":5509852},"MAP_BATTLE_COLOSSEUM_4P":{"header_address":4768436,"warp_table_address":5510152},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":{"header_address":4770228,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":{"header_address":4770200,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":{"header_address":4770172,"warp_table_address":5520908},"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":{"header_address":4769976,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":{"header_address":4769920,"warp_table_address":5519076},"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":{"header_address":4769892,"warp_table_address":5518968},"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":{"header_address":4769948,"warp_table_address":5519136},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":{"header_address":4770312,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":{"header_address":4770256,"warp_table_address":5521384},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":{"header_address":4770284,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":{"header_address":4770060,"warp_table_address":5520116},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":{"header_address":4770032,"warp_table_address":5519944},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":{"header_address":4770004,"warp_table_address":5519696},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":{"header_address":4770368,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":{"header_address":4770340,"warp_table_address":5521808},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":{"header_address":4770452,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":{"header_address":4770424,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":{"header_address":4770480,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":{"header_address":4770396,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":{"header_address":4770116,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":{"header_address":4770088,"warp_table_address":5520248},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":{"header_address":4770144,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":{"header_address":4769612,"warp_table_address":5516696},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":{"header_address":4769584,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":{"header_address":4769556,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":{"header_address":4769528,"warp_table_address":5516432},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":{"header_address":4769864,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":{"header_address":4769836,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":{"header_address":4769808,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":{"header_address":4770564,"warp_table_address":5523056},"MAP_BATTLE_FRONTIER_LOUNGE1":{"header_address":4770536,"warp_table_address":5522812},"MAP_BATTLE_FRONTIER_LOUNGE2":{"header_address":4770592,"warp_table_address":5523220},"MAP_BATTLE_FRONTIER_LOUNGE3":{"header_address":4770620,"warp_table_address":5523376},"MAP_BATTLE_FRONTIER_LOUNGE4":{"header_address":4770648,"warp_table_address":5523476},"MAP_BATTLE_FRONTIER_LOUNGE5":{"header_address":4770704,"warp_table_address":5523660},"MAP_BATTLE_FRONTIER_LOUNGE6":{"header_address":4770732,"warp_table_address":5523720},"MAP_BATTLE_FRONTIER_LOUNGE7":{"header_address":4770760,"warp_table_address":5523844},"MAP_BATTLE_FRONTIER_LOUNGE8":{"header_address":4770816,"warp_table_address":5524100},"MAP_BATTLE_FRONTIER_LOUNGE9":{"header_address":4770844,"warp_table_address":5524152},"MAP_BATTLE_FRONTIER_MART":{"header_address":4770928,"warp_table_address":5524588},"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":{"header_address":4769780,"warp_table_address":5518080},"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":{"header_address":4769500,"warp_table_address":5516048},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":{"header_address":4770872,"warp_table_address":5524308},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":{"header_address":4770900,"warp_table_address":5524448},"MAP_BATTLE_FRONTIER_RANKING_HALL":{"header_address":4770508,"warp_table_address":5522560},"MAP_BATTLE_FRONTIER_RECEPTION_GATE":{"header_address":4770788,"warp_table_address":5523992},"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":{"header_address":4770676,"warp_table_address":5523528},"MAP_BATTLE_PYRAMID_SQUARE01":{"header_address":4768912,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE02":{"header_address":4768940,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE03":{"header_address":4768968,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE04":{"header_address":4768996,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE05":{"header_address":4769024,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE06":{"header_address":4769052,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE07":{"header_address":4769080,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE08":{"header_address":4769108,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE09":{"header_address":4769136,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE10":{"header_address":4769164,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE11":{"header_address":4769192,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE12":{"header_address":4769220,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE13":{"header_address":4769248,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE14":{"header_address":4769276,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE15":{"header_address":4769304,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE16":{"header_address":4769332,"warp_table_address":4160749568},"MAP_BIRTH_ISLAND_EXTERIOR":{"header_address":4771012,"warp_table_address":5524876},"MAP_BIRTH_ISLAND_HARBOR":{"header_address":4771040,"warp_table_address":5524952},"MAP_CAVE_OF_ORIGIN_1F":{"header_address":4765720,"land_encounters":{"address":5609868,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493440},"MAP_CAVE_OF_ORIGIN_B1F":{"header_address":4765832,"warp_table_address":5493608},"MAP_CAVE_OF_ORIGIN_ENTRANCE":{"header_address":4765692,"land_encounters":{"address":5609812,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493404},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":{"header_address":4765748,"land_encounters":{"address":5609924,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493476},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":{"header_address":4765776,"land_encounters":{"address":5609980,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493512},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":{"header_address":4765804,"land_encounters":{"address":5610036,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493548},"MAP_CONTEST_HALL":{"header_address":4768464,"warp_table_address":4160749568},"MAP_CONTEST_HALL_BEAUTY":{"header_address":4768660,"warp_table_address":4160749568},"MAP_CONTEST_HALL_COOL":{"header_address":4768716,"warp_table_address":4160749568},"MAP_CONTEST_HALL_CUTE":{"header_address":4768772,"warp_table_address":4160749568},"MAP_CONTEST_HALL_SMART":{"header_address":4768744,"warp_table_address":4160749568},"MAP_CONTEST_HALL_TOUGH":{"header_address":4768688,"warp_table_address":4160749568},"MAP_DESERT_RUINS":{"header_address":4764824,"warp_table_address":5486828},"MAP_DESERT_UNDERPASS":{"header_address":4767400,"land_encounters":{"address":5613232,"slots":[132,370,132,371,132,370,371,132,370,132,371,132]},"warp_table_address":5500012},"MAP_DEWFORD_TOWN":{"fishing_encounters":{"address":5611588,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758300,"warp_table_address":5435180,"water_encounters":{"address":5611560,"slots":[72,309,309,310,310]}},"MAP_DEWFORD_TOWN_GYM":{"header_address":4759952,"warp_table_address":5460340},"MAP_DEWFORD_TOWN_HALL":{"header_address":4759980,"warp_table_address":5460640},"MAP_DEWFORD_TOWN_HOUSE1":{"header_address":4759868,"warp_table_address":5459856},"MAP_DEWFORD_TOWN_HOUSE2":{"header_address":4760008,"warp_table_address":5460748},"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":{"header_address":4759896,"warp_table_address":5459964},"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":{"header_address":4759924,"warp_table_address":5460104},"MAP_EVER_GRANDE_CITY":{"fishing_encounters":{"address":5611892,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4758216,"warp_table_address":5434048,"water_encounters":{"address":5611864,"slots":[72,309,309,310,310]}},"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":{"header_address":4764012,"warp_table_address":5483720},"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":{"header_address":4763984,"warp_table_address":5483612},"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":{"header_address":4763956,"warp_table_address":5483552},"MAP_EVER_GRANDE_CITY_HALL1":{"header_address":4764040,"warp_table_address":5483756},"MAP_EVER_GRANDE_CITY_HALL2":{"header_address":4764068,"warp_table_address":5483808},"MAP_EVER_GRANDE_CITY_HALL3":{"header_address":4764096,"warp_table_address":5483860},"MAP_EVER_GRANDE_CITY_HALL4":{"header_address":4764124,"warp_table_address":5483912},"MAP_EVER_GRANDE_CITY_HALL5":{"header_address":4764152,"warp_table_address":5483948},"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":{"header_address":4764208,"warp_table_address":5484180},"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":{"header_address":4763928,"warp_table_address":5483492},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":{"header_address":4764236,"warp_table_address":5484304},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":{"header_address":4764264,"warp_table_address":5484444},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":{"header_address":4764180,"warp_table_address":5484096},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":{"header_address":4764292,"warp_table_address":5484584},"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":{"header_address":4763900,"warp_table_address":5483432},"MAP_FALLARBOR_TOWN":{"header_address":4758356,"warp_table_address":5435792},"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760316,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760288,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760260,"warp_table_address":5462376},"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":{"header_address":4760400,"warp_table_address":5462888},"MAP_FALLARBOR_TOWN_MART":{"header_address":4760232,"warp_table_address":5462220},"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":{"header_address":4760428,"warp_table_address":5462948},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":{"header_address":4760344,"warp_table_address":5462656},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":{"header_address":4760372,"warp_table_address":5462796},"MAP_FARAWAY_ISLAND_ENTRANCE":{"header_address":4770956,"warp_table_address":5524672},"MAP_FARAWAY_ISLAND_INTERIOR":{"header_address":4770984,"warp_table_address":5524792},"MAP_FIERY_PATH":{"header_address":4765048,"land_encounters":{"address":5606456,"slots":[339,109,339,66,321,218,109,66,321,321,88,88]},"warp_table_address":5489344},"MAP_FORTREE_CITY":{"header_address":4758104,"warp_table_address":5431676},"MAP_FORTREE_CITY_DECORATION_SHOP":{"header_address":4762444,"warp_table_address":5473936},"MAP_FORTREE_CITY_GYM":{"header_address":4762220,"warp_table_address":5472984},"MAP_FORTREE_CITY_HOUSE1":{"header_address":4762192,"warp_table_address":5472756},"MAP_FORTREE_CITY_HOUSE2":{"header_address":4762332,"warp_table_address":5473504},"MAP_FORTREE_CITY_HOUSE3":{"header_address":4762360,"warp_table_address":5473588},"MAP_FORTREE_CITY_HOUSE4":{"header_address":4762388,"warp_table_address":5473696},"MAP_FORTREE_CITY_HOUSE5":{"header_address":4762416,"warp_table_address":5473804},"MAP_FORTREE_CITY_MART":{"header_address":4762304,"warp_table_address":5473420},"MAP_FORTREE_CITY_POKEMON_CENTER_1F":{"header_address":4762248,"warp_table_address":5473140},"MAP_FORTREE_CITY_POKEMON_CENTER_2F":{"header_address":4762276,"warp_table_address":5473280},"MAP_GRANITE_CAVE_1F":{"header_address":4764852,"land_encounters":{"address":5605988,"slots":[41,335,335,41,335,63,335,335,74,74,74,74]},"warp_table_address":5486956},"MAP_GRANITE_CAVE_B1F":{"header_address":4764880,"land_encounters":{"address":5606044,"slots":[41,382,382,382,41,63,335,335,322,322,322,322]},"warp_table_address":5487032},"MAP_GRANITE_CAVE_B2F":{"header_address":4764908,"land_encounters":{"address":5606372,"slots":[41,382,382,41,382,63,322,322,322,322,322,322]},"rock_smash_encounters":{"address":5606428,"slots":[74,320,74,74,74]},"warp_table_address":5487324},"MAP_GRANITE_CAVE_STEVENS_ROOM":{"header_address":4764936,"land_encounters":{"address":5608188,"slots":[41,335,335,41,335,63,335,335,382,382,382,382]},"warp_table_address":5487432},"MAP_INSIDE_OF_TRUCK":{"header_address":4768800,"warp_table_address":5510720},"MAP_ISLAND_CAVE":{"header_address":4766532,"warp_table_address":5497356},"MAP_JAGGED_PASS":{"header_address":4765020,"land_encounters":{"address":5606644,"slots":[339,339,66,339,351,66,351,66,339,351,339,351]},"warp_table_address":5488908},"MAP_LAVARIDGE_TOWN":{"header_address":4758328,"warp_table_address":5435516},"MAP_LAVARIDGE_TOWN_GYM_1F":{"header_address":4760064,"warp_table_address":5461036},"MAP_LAVARIDGE_TOWN_GYM_B1F":{"header_address":4760092,"warp_table_address":5461384},"MAP_LAVARIDGE_TOWN_HERB_SHOP":{"header_address":4760036,"warp_table_address":5460856},"MAP_LAVARIDGE_TOWN_HOUSE":{"header_address":4760120,"warp_table_address":5461668},"MAP_LAVARIDGE_TOWN_MART":{"header_address":4760148,"warp_table_address":5461776},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":{"header_address":4760176,"warp_table_address":5461908},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":{"header_address":4760204,"warp_table_address":5462056},"MAP_LILYCOVE_CITY":{"fishing_encounters":{"address":5611512,"slots":[129,72,129,72,313,313,313,120,313,313]},"header_address":4758132,"warp_table_address":5432368,"water_encounters":{"address":5611484,"slots":[72,309,309,310,310]}},"MAP_LILYCOVE_CITY_CONTEST_HALL":{"header_address":4762612,"warp_table_address":5476560},"MAP_LILYCOVE_CITY_CONTEST_LOBBY":{"header_address":4762584,"warp_table_address":5475596},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":{"header_address":4762472,"warp_table_address":5473996},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":{"header_address":4762500,"warp_table_address":5474224},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":{"header_address":4762920,"warp_table_address":5478044},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":{"header_address":4762948,"warp_table_address":5478228},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":{"header_address":4762976,"warp_table_address":5478392},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":{"header_address":4763004,"warp_table_address":5478556},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":{"header_address":4763032,"warp_table_address":5478768},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":{"header_address":4763088,"warp_table_address":5478984},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":{"header_address":4763060,"warp_table_address":5478908},"MAP_LILYCOVE_CITY_HARBOR":{"header_address":4762752,"warp_table_address":5477396},"MAP_LILYCOVE_CITY_HOUSE1":{"header_address":4762808,"warp_table_address":5477540},"MAP_LILYCOVE_CITY_HOUSE2":{"header_address":4762836,"warp_table_address":5477600},"MAP_LILYCOVE_CITY_HOUSE3":{"header_address":4762864,"warp_table_address":5477780},"MAP_LILYCOVE_CITY_HOUSE4":{"header_address":4762892,"warp_table_address":5477864},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":{"header_address":4762528,"warp_table_address":5474492},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":{"header_address":4762556,"warp_table_address":5474824},"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":{"header_address":4762780,"warp_table_address":5477456},"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":{"header_address":4762640,"warp_table_address":5476804},"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":{"header_address":4762668,"warp_table_address":5476944},"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":{"header_address":4762724,"warp_table_address":5477240},"MAP_LILYCOVE_CITY_UNUSED_MART":{"header_address":4762696,"warp_table_address":5476988},"MAP_LITTLEROOT_TOWN":{"header_address":4758244,"warp_table_address":5434528},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":{"header_address":4759588,"warp_table_address":5457588},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":{"header_address":4759616,"warp_table_address":5458080},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":{"header_address":4759644,"warp_table_address":5458324},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":{"header_address":4759672,"warp_table_address":5458816},"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":{"header_address":4759700,"warp_table_address":5459036},"MAP_MAGMA_HIDEOUT_1F":{"header_address":4767064,"land_encounters":{"address":5612560,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498844},"MAP_MAGMA_HIDEOUT_2F_1R":{"header_address":4767092,"land_encounters":{"address":5612616,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498992},"MAP_MAGMA_HIDEOUT_2F_2R":{"header_address":4767120,"land_encounters":{"address":5612672,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499180},"MAP_MAGMA_HIDEOUT_2F_3R":{"header_address":4767260,"land_encounters":{"address":5612952,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499696},"MAP_MAGMA_HIDEOUT_3F_1R":{"header_address":4767148,"land_encounters":{"address":5612728,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499288},"MAP_MAGMA_HIDEOUT_3F_2R":{"header_address":4767176,"land_encounters":{"address":5612784,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499380},"MAP_MAGMA_HIDEOUT_3F_3R":{"header_address":4767232,"land_encounters":{"address":5612896,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499660},"MAP_MAGMA_HIDEOUT_4F":{"header_address":4767204,"land_encounters":{"address":5612840,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499600},"MAP_MARINE_CAVE_END":{"header_address":4767540,"warp_table_address":5500288},"MAP_MARINE_CAVE_ENTRANCE":{"header_address":4767512,"warp_table_address":5500236},"MAP_MAUVILLE_CITY":{"header_address":4758048,"warp_table_address":5430380},"MAP_MAUVILLE_CITY_BIKE_SHOP":{"header_address":4761520,"warp_table_address":5469232},"MAP_MAUVILLE_CITY_GAME_CORNER":{"header_address":4761576,"warp_table_address":5469640},"MAP_MAUVILLE_CITY_GYM":{"header_address":4761492,"warp_table_address":5469060},"MAP_MAUVILLE_CITY_HOUSE1":{"header_address":4761548,"warp_table_address":5469316},"MAP_MAUVILLE_CITY_HOUSE2":{"header_address":4761604,"warp_table_address":5469988},"MAP_MAUVILLE_CITY_MART":{"header_address":4761688,"warp_table_address":5470424},"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":{"header_address":4761632,"warp_table_address":5470144},"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":{"header_address":4761660,"warp_table_address":5470308},"MAP_METEOR_FALLS_1F_1R":{"fishing_encounters":{"address":5610796,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4764656,"land_encounters":{"address":5610712,"slots":[41,41,41,41,41,349,349,349,41,41,41,41]},"warp_table_address":5486052,"water_encounters":{"address":5610768,"slots":[41,41,349,349,349]}},"MAP_METEOR_FALLS_1F_2R":{"fishing_encounters":{"address":5610928,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764684,"land_encounters":{"address":5610844,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486220,"water_encounters":{"address":5610900,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_1R":{"fishing_encounters":{"address":5611060,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764712,"land_encounters":{"address":5610976,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486284,"water_encounters":{"address":5611032,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_2R":{"fishing_encounters":{"address":5606596,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764740,"land_encounters":{"address":5606512,"slots":[42,42,395,349,395,349,395,349,42,42,42,42]},"warp_table_address":5486376,"water_encounters":{"address":5606568,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_STEVENS_CAVE":{"header_address":4767652,"land_encounters":{"address":5613904,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5500488},"MAP_MIRAGE_TOWER_1F":{"header_address":4767288,"land_encounters":{"address":5613008,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499732},"MAP_MIRAGE_TOWER_2F":{"header_address":4767316,"land_encounters":{"address":5613064,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499768},"MAP_MIRAGE_TOWER_3F":{"header_address":4767344,"land_encounters":{"address":5613120,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499852},"MAP_MIRAGE_TOWER_4F":{"header_address":4767372,"land_encounters":{"address":5613176,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499960},"MAP_MOSSDEEP_CITY":{"fishing_encounters":{"address":5611740,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758160,"warp_table_address":5433064,"water_encounters":{"address":5611712,"slots":[72,309,309,310,310]}},"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":{"header_address":4763424,"warp_table_address":5481712},"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":{"header_address":4763452,"warp_table_address":5481816},"MAP_MOSSDEEP_CITY_GYM":{"header_address":4763116,"warp_table_address":5479884},"MAP_MOSSDEEP_CITY_HOUSE1":{"header_address":4763144,"warp_table_address":5480232},"MAP_MOSSDEEP_CITY_HOUSE2":{"header_address":4763172,"warp_table_address":5480340},"MAP_MOSSDEEP_CITY_HOUSE3":{"header_address":4763284,"warp_table_address":5480812},"MAP_MOSSDEEP_CITY_HOUSE4":{"header_address":4763340,"warp_table_address":5481076},"MAP_MOSSDEEP_CITY_MART":{"header_address":4763256,"warp_table_address":5480752},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":{"header_address":4763200,"warp_table_address":5480448},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":{"header_address":4763228,"warp_table_address":5480612},"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":{"header_address":4763368,"warp_table_address":5481376},"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":{"header_address":4763396,"warp_table_address":5481636},"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":{"header_address":4763312,"warp_table_address":5480920},"MAP_MT_CHIMNEY":{"header_address":4764992,"warp_table_address":5488664},"MAP_MT_CHIMNEY_CABLE_CAR_STATION":{"header_address":4764460,"warp_table_address":5485144},"MAP_MT_PYRE_1F":{"header_address":4765076,"land_encounters":{"address":5606100,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489452},"MAP_MT_PYRE_2F":{"header_address":4765104,"land_encounters":{"address":5607796,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489712},"MAP_MT_PYRE_3F":{"header_address":4765132,"land_encounters":{"address":5607852,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489868},"MAP_MT_PYRE_4F":{"header_address":4765160,"land_encounters":{"address":5607908,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5489984},"MAP_MT_PYRE_5F":{"header_address":4765188,"land_encounters":{"address":5607964,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490100},"MAP_MT_PYRE_6F":{"header_address":4765216,"land_encounters":{"address":5608020,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490232},"MAP_MT_PYRE_EXTERIOR":{"header_address":4765244,"land_encounters":{"address":5608076,"slots":[377,377,377,377,37,37,37,37,309,309,309,309]},"warp_table_address":5490316},"MAP_MT_PYRE_SUMMIT":{"header_address":4765272,"land_encounters":{"address":5608132,"slots":[377,377,377,377,377,377,377,361,361,361,411,411]},"warp_table_address":5490656},"MAP_NAVEL_ROCK_B1F":{"header_address":4771320,"warp_table_address":5525524},"MAP_NAVEL_ROCK_BOTTOM":{"header_address":4771824,"warp_table_address":5526248},"MAP_NAVEL_ROCK_DOWN01":{"header_address":4771516,"warp_table_address":5525828},"MAP_NAVEL_ROCK_DOWN02":{"header_address":4771544,"warp_table_address":5525864},"MAP_NAVEL_ROCK_DOWN03":{"header_address":4771572,"warp_table_address":5525900},"MAP_NAVEL_ROCK_DOWN04":{"header_address":4771600,"warp_table_address":5525936},"MAP_NAVEL_ROCK_DOWN05":{"header_address":4771628,"warp_table_address":5525972},"MAP_NAVEL_ROCK_DOWN06":{"header_address":4771656,"warp_table_address":5526008},"MAP_NAVEL_ROCK_DOWN07":{"header_address":4771684,"warp_table_address":5526044},"MAP_NAVEL_ROCK_DOWN08":{"header_address":4771712,"warp_table_address":5526080},"MAP_NAVEL_ROCK_DOWN09":{"header_address":4771740,"warp_table_address":5526116},"MAP_NAVEL_ROCK_DOWN10":{"header_address":4771768,"warp_table_address":5526152},"MAP_NAVEL_ROCK_DOWN11":{"header_address":4771796,"warp_table_address":5526188},"MAP_NAVEL_ROCK_ENTRANCE":{"header_address":4771292,"warp_table_address":5525488},"MAP_NAVEL_ROCK_EXTERIOR":{"header_address":4771236,"warp_table_address":5525376},"MAP_NAVEL_ROCK_FORK":{"header_address":4771348,"warp_table_address":5525560},"MAP_NAVEL_ROCK_HARBOR":{"header_address":4771264,"warp_table_address":5525460},"MAP_NAVEL_ROCK_TOP":{"header_address":4771488,"warp_table_address":5525772},"MAP_NAVEL_ROCK_UP1":{"header_address":4771376,"warp_table_address":5525604},"MAP_NAVEL_ROCK_UP2":{"header_address":4771404,"warp_table_address":5525640},"MAP_NAVEL_ROCK_UP3":{"header_address":4771432,"warp_table_address":5525676},"MAP_NAVEL_ROCK_UP4":{"header_address":4771460,"warp_table_address":5525712},"MAP_NEW_MAUVILLE_ENTRANCE":{"header_address":4766112,"land_encounters":{"address":5610092,"slots":[100,81,100,81,100,81,100,81,100,81,100,81]},"warp_table_address":5495284},"MAP_NEW_MAUVILLE_INSIDE":{"header_address":4766140,"land_encounters":{"address":5607136,"slots":[100,81,100,81,100,81,100,81,100,81,101,82]},"warp_table_address":5495528},"MAP_OLDALE_TOWN":{"header_address":4758272,"warp_table_address":5434860},"MAP_OLDALE_TOWN_HOUSE1":{"header_address":4759728,"warp_table_address":5459276},"MAP_OLDALE_TOWN_HOUSE2":{"header_address":4759756,"warp_table_address":5459360},"MAP_OLDALE_TOWN_MART":{"header_address":4759840,"warp_table_address":5459748},"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":{"header_address":4759784,"warp_table_address":5459492},"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":{"header_address":4759812,"warp_table_address":5459632},"MAP_PACIFIDLOG_TOWN":{"fishing_encounters":{"address":5611816,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758412,"warp_table_address":5436288,"water_encounters":{"address":5611788,"slots":[72,309,309,310,310]}},"MAP_PACIFIDLOG_TOWN_HOUSE1":{"header_address":4760764,"warp_table_address":5464400},"MAP_PACIFIDLOG_TOWN_HOUSE2":{"header_address":4760792,"warp_table_address":5464508},"MAP_PACIFIDLOG_TOWN_HOUSE3":{"header_address":4760820,"warp_table_address":5464592},"MAP_PACIFIDLOG_TOWN_HOUSE4":{"header_address":4760848,"warp_table_address":5464700},"MAP_PACIFIDLOG_TOWN_HOUSE5":{"header_address":4760876,"warp_table_address":5464784},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":{"header_address":4760708,"warp_table_address":5464168},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":{"header_address":4760736,"warp_table_address":5464308},"MAP_PETALBURG_CITY":{"fishing_encounters":{"address":5611968,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4757992,"warp_table_address":5428704,"water_encounters":{"address":5611940,"slots":[183,183,183,183,183]}},"MAP_PETALBURG_CITY_GYM":{"header_address":4760932,"warp_table_address":5465168},"MAP_PETALBURG_CITY_HOUSE1":{"header_address":4760960,"warp_table_address":5465708},"MAP_PETALBURG_CITY_HOUSE2":{"header_address":4760988,"warp_table_address":5465792},"MAP_PETALBURG_CITY_MART":{"header_address":4761072,"warp_table_address":5466228},"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":{"header_address":4761016,"warp_table_address":5465948},"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":{"header_address":4761044,"warp_table_address":5466088},"MAP_PETALBURG_CITY_WALLYS_HOUSE":{"header_address":4760904,"warp_table_address":5464868},"MAP_PETALBURG_WOODS":{"header_address":4764964,"land_encounters":{"address":5605876,"slots":[286,290,306,286,291,293,290,306,304,364,304,364]},"warp_table_address":5487772},"MAP_RECORD_CORNER":{"header_address":4768408,"warp_table_address":5510036},"MAP_ROUTE101":{"header_address":4758440,"land_encounters":{"address":5604388,"slots":[290,286,290,290,286,286,290,286,288,288,288,288]},"warp_table_address":4160749568},"MAP_ROUTE102":{"fishing_encounters":{"address":5604528,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758468,"land_encounters":{"address":5604444,"slots":[286,290,286,290,295,295,288,288,288,392,288,298]},"warp_table_address":4160749568,"water_encounters":{"address":5604500,"slots":[183,183,183,183,118]}},"MAP_ROUTE103":{"fishing_encounters":{"address":5604660,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758496,"land_encounters":{"address":5604576,"slots":[286,286,286,286,309,288,288,288,309,309,309,309]},"warp_table_address":5437452,"water_encounters":{"address":5604632,"slots":[72,309,309,310,310]}},"MAP_ROUTE104":{"fishing_encounters":{"address":5604792,"slots":[129,129,129,129,129,129,129,129,129,129]},"header_address":4758524,"land_encounters":{"address":5604708,"slots":[286,290,286,183,183,286,304,304,309,309,309,309]},"warp_table_address":5438308,"water_encounters":{"address":5604764,"slots":[309,309,309,310,310]}},"MAP_ROUTE104_MR_BRINEYS_HOUSE":{"header_address":4764320,"warp_table_address":5484676},"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4764348,"warp_table_address":5484784},"MAP_ROUTE104_PROTOTYPE":{"header_address":4771880,"warp_table_address":4160749568},"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4771908,"warp_table_address":4160749568},"MAP_ROUTE105":{"fishing_encounters":{"address":5604868,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758552,"warp_table_address":5438720,"water_encounters":{"address":5604840,"slots":[72,309,309,310,310]}},"MAP_ROUTE106":{"fishing_encounters":{"address":5606728,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758580,"warp_table_address":5438892,"water_encounters":{"address":5606700,"slots":[72,309,309,310,310]}},"MAP_ROUTE107":{"fishing_encounters":{"address":5606804,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758608,"warp_table_address":4160749568,"water_encounters":{"address":5606776,"slots":[72,309,309,310,310]}},"MAP_ROUTE108":{"fishing_encounters":{"address":5606880,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758636,"warp_table_address":5439324,"water_encounters":{"address":5606852,"slots":[72,309,309,310,310]}},"MAP_ROUTE109":{"fishing_encounters":{"address":5606956,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758664,"warp_table_address":5439940,"water_encounters":{"address":5606928,"slots":[72,309,309,310,310]}},"MAP_ROUTE109_SEASHORE_HOUSE":{"header_address":4771936,"warp_table_address":5526472},"MAP_ROUTE110":{"fishing_encounters":{"address":5605000,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758692,"land_encounters":{"address":5604916,"slots":[286,337,367,337,354,43,354,367,309,309,353,353]},"warp_table_address":5440928,"water_encounters":{"address":5604972,"slots":[72,309,309,310,310]}},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":{"header_address":4772272,"warp_table_address":5529400},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":{"header_address":4772300,"warp_table_address":5529508},"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":{"header_address":4772020,"warp_table_address":5526740},"MAP_ROUTE110_TRICK_HOUSE_END":{"header_address":4771992,"warp_table_address":5526676},"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":{"header_address":4771964,"warp_table_address":5526532},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":{"header_address":4772048,"warp_table_address":5527152},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":{"header_address":4772076,"warp_table_address":5527328},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":{"header_address":4772104,"warp_table_address":5527616},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":{"header_address":4772132,"warp_table_address":5528072},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":{"header_address":4772160,"warp_table_address":5528248},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":{"header_address":4772188,"warp_table_address":5528752},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":{"header_address":4772216,"warp_table_address":5529024},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":{"header_address":4772244,"warp_table_address":5529320},"MAP_ROUTE111":{"fishing_encounters":{"address":5605160,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758720,"land_encounters":{"address":5605048,"slots":[27,332,27,332,318,318,27,332,318,344,344,344]},"rock_smash_encounters":{"address":5605132,"slots":[74,74,74,74,74]},"warp_table_address":5442448,"water_encounters":{"address":5605104,"slots":[183,183,183,183,118]}},"MAP_ROUTE111_OLD_LADYS_REST_STOP":{"header_address":4764404,"warp_table_address":5484976},"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":{"header_address":4764376,"warp_table_address":5484916},"MAP_ROUTE112":{"header_address":4758748,"land_encounters":{"address":5605208,"slots":[339,339,183,339,339,183,339,183,339,339,339,339]},"warp_table_address":5443604},"MAP_ROUTE112_CABLE_CAR_STATION":{"header_address":4764432,"warp_table_address":5485060},"MAP_ROUTE113":{"header_address":4758776,"land_encounters":{"address":5605264,"slots":[308,308,218,308,308,218,308,218,308,227,308,227]},"warp_table_address":5444092},"MAP_ROUTE113_GLASS_WORKSHOP":{"header_address":4772328,"warp_table_address":5529640},"MAP_ROUTE114":{"fishing_encounters":{"address":5605432,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758804,"land_encounters":{"address":5605320,"slots":[358,295,358,358,295,296,296,296,379,379,379,299]},"rock_smash_encounters":{"address":5605404,"slots":[74,74,74,74,74]},"warp_table_address":5445184,"water_encounters":{"address":5605376,"slots":[183,183,183,183,118]}},"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":{"header_address":4764488,"warp_table_address":5485204},"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":{"header_address":4764516,"warp_table_address":5485320},"MAP_ROUTE114_LANETTES_HOUSE":{"header_address":4764544,"warp_table_address":5485420},"MAP_ROUTE115":{"fishing_encounters":{"address":5607088,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758832,"land_encounters":{"address":5607004,"slots":[358,304,358,304,304,305,39,39,309,309,309,309]},"warp_table_address":5445988,"water_encounters":{"address":5607060,"slots":[72,309,309,310,310]}},"MAP_ROUTE116":{"header_address":4758860,"land_encounters":{"address":5605480,"slots":[286,370,301,63,301,304,304,304,286,286,315,315]},"warp_table_address":5446872},"MAP_ROUTE116_TUNNELERS_REST_HOUSE":{"header_address":4764572,"warp_table_address":5485564},"MAP_ROUTE117":{"fishing_encounters":{"address":5605620,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758888,"land_encounters":{"address":5605536,"slots":[286,43,286,43,183,43,387,387,387,387,386,298]},"warp_table_address":5447656,"water_encounters":{"address":5605592,"slots":[183,183,183,183,118]}},"MAP_ROUTE117_POKEMON_DAY_CARE":{"header_address":4764600,"warp_table_address":5485624},"MAP_ROUTE118":{"fishing_encounters":{"address":5605752,"slots":[129,72,129,72,330,331,330,330,330,330]},"header_address":4758916,"land_encounters":{"address":5605668,"slots":[288,337,288,337,289,338,309,309,309,309,309,317]},"warp_table_address":5448236,"water_encounters":{"address":5605724,"slots":[72,309,309,310,310]}},"MAP_ROUTE119":{"fishing_encounters":{"address":5607276,"slots":[129,72,129,72,330,330,330,330,330,330]},"header_address":4758944,"land_encounters":{"address":5607192,"slots":[288,289,288,43,289,43,43,43,369,369,369,317]},"warp_table_address":5449460,"water_encounters":{"address":5607248,"slots":[72,309,309,310,310]}},"MAP_ROUTE119_HOUSE":{"header_address":4772440,"warp_table_address":5530360},"MAP_ROUTE119_WEATHER_INSTITUTE_1F":{"header_address":4772384,"warp_table_address":5529880},"MAP_ROUTE119_WEATHER_INSTITUTE_2F":{"header_address":4772412,"warp_table_address":5530164},"MAP_ROUTE120":{"fishing_encounters":{"address":5607408,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758972,"land_encounters":{"address":5607324,"slots":[286,287,287,43,183,43,43,183,376,376,317,298]},"warp_table_address":5451160,"water_encounters":{"address":5607380,"slots":[183,183,183,183,118]}},"MAP_ROUTE121":{"fishing_encounters":{"address":5607540,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759000,"land_encounters":{"address":5607456,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5452364,"water_encounters":{"address":5607512,"slots":[72,309,309,310,310]}},"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":{"header_address":4764628,"warp_table_address":5485732},"MAP_ROUTE122":{"fishing_encounters":{"address":5607616,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759028,"warp_table_address":5452576,"water_encounters":{"address":5607588,"slots":[72,309,309,310,310]}},"MAP_ROUTE123":{"fishing_encounters":{"address":5607748,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759056,"land_encounters":{"address":5607664,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5453636,"water_encounters":{"address":5607720,"slots":[72,309,309,310,310]}},"MAP_ROUTE123_BERRY_MASTERS_HOUSE":{"header_address":4772356,"warp_table_address":5529724},"MAP_ROUTE124":{"fishing_encounters":{"address":5605828,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759084,"warp_table_address":5454436,"water_encounters":{"address":5605800,"slots":[72,309,309,310,310]}},"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":{"header_address":4772468,"warp_table_address":5530420},"MAP_ROUTE125":{"fishing_encounters":{"address":5608272,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759112,"warp_table_address":5454716,"water_encounters":{"address":5608244,"slots":[72,309,309,310,310]}},"MAP_ROUTE126":{"fishing_encounters":{"address":5608348,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759140,"warp_table_address":4160749568,"water_encounters":{"address":5608320,"slots":[72,309,309,310,310]}},"MAP_ROUTE127":{"fishing_encounters":{"address":5608424,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759168,"warp_table_address":4160749568,"water_encounters":{"address":5608396,"slots":[72,309,309,310,310]}},"MAP_ROUTE128":{"fishing_encounters":{"address":5608500,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4759196,"warp_table_address":4160749568,"water_encounters":{"address":5608472,"slots":[72,309,309,310,310]}},"MAP_ROUTE129":{"fishing_encounters":{"address":5608576,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759224,"warp_table_address":4160749568,"water_encounters":{"address":5608548,"slots":[72,309,309,310,314]}},"MAP_ROUTE130":{"fishing_encounters":{"address":5608708,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759252,"land_encounters":{"address":5608624,"slots":[360,360,360,360,360,360,360,360,360,360,360,360]},"warp_table_address":4160749568,"water_encounters":{"address":5608680,"slots":[72,309,309,310,310]}},"MAP_ROUTE131":{"fishing_encounters":{"address":5608784,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759280,"warp_table_address":5456116,"water_encounters":{"address":5608756,"slots":[72,309,309,310,310]}},"MAP_ROUTE132":{"fishing_encounters":{"address":5608860,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759308,"warp_table_address":4160749568,"water_encounters":{"address":5608832,"slots":[72,309,309,310,310]}},"MAP_ROUTE133":{"fishing_encounters":{"address":5608936,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759336,"warp_table_address":4160749568,"water_encounters":{"address":5608908,"slots":[72,309,309,310,310]}},"MAP_ROUTE134":{"fishing_encounters":{"address":5609012,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759364,"warp_table_address":4160749568,"water_encounters":{"address":5608984,"slots":[72,309,309,310,310]}},"MAP_RUSTBORO_CITY":{"header_address":4758076,"warp_table_address":5430936},"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":{"header_address":4762024,"warp_table_address":5472204},"MAP_RUSTBORO_CITY_DEVON_CORP_1F":{"header_address":4761716,"warp_table_address":5470532},"MAP_RUSTBORO_CITY_DEVON_CORP_2F":{"header_address":4761744,"warp_table_address":5470744},"MAP_RUSTBORO_CITY_DEVON_CORP_3F":{"header_address":4761772,"warp_table_address":5470852},"MAP_RUSTBORO_CITY_FLAT1_1F":{"header_address":4761940,"warp_table_address":5471808},"MAP_RUSTBORO_CITY_FLAT1_2F":{"header_address":4761968,"warp_table_address":5472044},"MAP_RUSTBORO_CITY_FLAT2_1F":{"header_address":4762080,"warp_table_address":5472372},"MAP_RUSTBORO_CITY_FLAT2_2F":{"header_address":4762108,"warp_table_address":5472464},"MAP_RUSTBORO_CITY_FLAT2_3F":{"header_address":4762136,"warp_table_address":5472548},"MAP_RUSTBORO_CITY_GYM":{"header_address":4761800,"warp_table_address":5471024},"MAP_RUSTBORO_CITY_HOUSE1":{"header_address":4761996,"warp_table_address":5472120},"MAP_RUSTBORO_CITY_HOUSE2":{"header_address":4762052,"warp_table_address":5472288},"MAP_RUSTBORO_CITY_HOUSE3":{"header_address":4762164,"warp_table_address":5472648},"MAP_RUSTBORO_CITY_MART":{"header_address":4761912,"warp_table_address":5471724},"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":{"header_address":4761856,"warp_table_address":5471444},"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":{"header_address":4761884,"warp_table_address":5471584},"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":{"header_address":4761828,"warp_table_address":5471252},"MAP_RUSTURF_TUNNEL":{"header_address":4764768,"land_encounters":{"address":5605932,"slots":[370,370,370,370,370,370,370,370,370,370,370,370]},"warp_table_address":5486644},"MAP_SAFARI_ZONE_NORTH":{"header_address":4769416,"land_encounters":{"address":5610280,"slots":[231,43,231,43,177,44,44,177,178,214,178,214]},"rock_smash_encounters":{"address":5610336,"slots":[74,74,74,74,74]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHEAST":{"header_address":4769724,"land_encounters":{"address":5612476,"slots":[190,216,190,216,191,165,163,204,228,241,228,241]},"rock_smash_encounters":{"address":5612532,"slots":[213,213,213,213,213]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHWEST":{"fishing_encounters":{"address":5610448,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769388,"land_encounters":{"address":5610364,"slots":[111,43,111,43,84,44,44,84,85,127,85,127]},"warp_table_address":4160749568,"water_encounters":{"address":5610420,"slots":[54,54,54,55,55]}},"MAP_SAFARI_ZONE_REST_HOUSE":{"header_address":4769696,"warp_table_address":5516996},"MAP_SAFARI_ZONE_SOUTH":{"header_address":4769472,"land_encounters":{"address":5606212,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515444},"MAP_SAFARI_ZONE_SOUTHEAST":{"fishing_encounters":{"address":5612428,"slots":[129,118,129,118,223,118,223,223,223,224]},"header_address":4769752,"land_encounters":{"address":5612344,"slots":[191,179,191,179,190,167,163,209,234,207,234,207]},"warp_table_address":4160749568,"water_encounters":{"address":5612400,"slots":[194,183,183,183,195]}},"MAP_SAFARI_ZONE_SOUTHWEST":{"fishing_encounters":{"address":5610232,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769444,"land_encounters":{"address":5610148,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515260,"water_encounters":{"address":5610204,"slots":[54,54,54,54,54]}},"MAP_SCORCHED_SLAB":{"header_address":4766700,"warp_table_address":5498144},"MAP_SEAFLOOR_CAVERN_ENTRANCE":{"fishing_encounters":{"address":5609764,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765412,"warp_table_address":5491796,"water_encounters":{"address":5609736,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM1":{"header_address":4765440,"land_encounters":{"address":5609136,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5491952},"MAP_SEAFLOOR_CAVERN_ROOM2":{"header_address":4765468,"land_encounters":{"address":5609192,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492188},"MAP_SEAFLOOR_CAVERN_ROOM3":{"header_address":4765496,"land_encounters":{"address":5609248,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492456},"MAP_SEAFLOOR_CAVERN_ROOM4":{"header_address":4765524,"land_encounters":{"address":5609304,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492548},"MAP_SEAFLOOR_CAVERN_ROOM5":{"header_address":4765552,"land_encounters":{"address":5609360,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492744},"MAP_SEAFLOOR_CAVERN_ROOM6":{"fishing_encounters":{"address":5609500,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765580,"land_encounters":{"address":5609416,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492788,"water_encounters":{"address":5609472,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM7":{"fishing_encounters":{"address":5609632,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765608,"land_encounters":{"address":5609548,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492832,"water_encounters":{"address":5609604,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM8":{"header_address":4765636,"land_encounters":{"address":5609680,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493156},"MAP_SEAFLOOR_CAVERN_ROOM9":{"header_address":4765664,"warp_table_address":5493360},"MAP_SEALED_CHAMBER_INNER_ROOM":{"header_address":4766672,"warp_table_address":5497984},"MAP_SEALED_CHAMBER_OUTER_ROOM":{"header_address":4766644,"warp_table_address":5497608},"MAP_SECRET_BASE_BLUE_CAVE1":{"header_address":4767736,"warp_table_address":5501652},"MAP_SECRET_BASE_BLUE_CAVE2":{"header_address":4767904,"warp_table_address":5503980},"MAP_SECRET_BASE_BLUE_CAVE3":{"header_address":4768072,"warp_table_address":5506308},"MAP_SECRET_BASE_BLUE_CAVE4":{"header_address":4768240,"warp_table_address":5508636},"MAP_SECRET_BASE_BROWN_CAVE1":{"header_address":4767708,"warp_table_address":5501264},"MAP_SECRET_BASE_BROWN_CAVE2":{"header_address":4767876,"warp_table_address":5503592},"MAP_SECRET_BASE_BROWN_CAVE3":{"header_address":4768044,"warp_table_address":5505920},"MAP_SECRET_BASE_BROWN_CAVE4":{"header_address":4768212,"warp_table_address":5508248},"MAP_SECRET_BASE_RED_CAVE1":{"header_address":4767680,"warp_table_address":5500876},"MAP_SECRET_BASE_RED_CAVE2":{"header_address":4767848,"warp_table_address":5503204},"MAP_SECRET_BASE_RED_CAVE3":{"header_address":4768016,"warp_table_address":5505532},"MAP_SECRET_BASE_RED_CAVE4":{"header_address":4768184,"warp_table_address":5507860},"MAP_SECRET_BASE_SHRUB1":{"header_address":4767820,"warp_table_address":5502816},"MAP_SECRET_BASE_SHRUB2":{"header_address":4767988,"warp_table_address":5505144},"MAP_SECRET_BASE_SHRUB3":{"header_address":4768156,"warp_table_address":5507472},"MAP_SECRET_BASE_SHRUB4":{"header_address":4768324,"warp_table_address":5509800},"MAP_SECRET_BASE_TREE1":{"header_address":4767792,"warp_table_address":5502428},"MAP_SECRET_BASE_TREE2":{"header_address":4767960,"warp_table_address":5504756},"MAP_SECRET_BASE_TREE3":{"header_address":4768128,"warp_table_address":5507084},"MAP_SECRET_BASE_TREE4":{"header_address":4768296,"warp_table_address":5509412},"MAP_SECRET_BASE_YELLOW_CAVE1":{"header_address":4767764,"warp_table_address":5502040},"MAP_SECRET_BASE_YELLOW_CAVE2":{"header_address":4767932,"warp_table_address":5504368},"MAP_SECRET_BASE_YELLOW_CAVE3":{"header_address":4768100,"warp_table_address":5506696},"MAP_SECRET_BASE_YELLOW_CAVE4":{"header_address":4768268,"warp_table_address":5509024},"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":{"header_address":4766056,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":{"header_address":4766084,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":{"fishing_encounters":{"address":5611436,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765944,"land_encounters":{"address":5611352,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494828,"water_encounters":{"address":5611408,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":{"header_address":4766980,"land_encounters":{"address":5612044,"slots":[41,341,41,341,41,341,346,341,42,346,42,346]},"warp_table_address":5498544},"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":{"fishing_encounters":{"address":5611304,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765972,"land_encounters":{"address":5611220,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494904,"water_encounters":{"address":5611276,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":{"header_address":4766028,"land_encounters":{"address":5611164,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495180},"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":{"header_address":4766000,"land_encounters":{"address":5611108,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495084},"MAP_SKY_PILLAR_1F":{"header_address":4766868,"land_encounters":{"address":5612100,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498328},"MAP_SKY_PILLAR_2F":{"header_address":4766896,"warp_table_address":5498372},"MAP_SKY_PILLAR_3F":{"header_address":4766924,"land_encounters":{"address":5612232,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498408},"MAP_SKY_PILLAR_4F":{"header_address":4766952,"warp_table_address":5498452},"MAP_SKY_PILLAR_5F":{"header_address":4767008,"land_encounters":{"address":5612288,"slots":[322,42,42,322,319,378,378,319,319,359,359,359]},"warp_table_address":5498572},"MAP_SKY_PILLAR_ENTRANCE":{"header_address":4766812,"warp_table_address":5498232},"MAP_SKY_PILLAR_OUTSIDE":{"header_address":4766840,"warp_table_address":5498292},"MAP_SKY_PILLAR_TOP":{"header_address":4767036,"warp_table_address":5498656},"MAP_SLATEPORT_CITY":{"fishing_encounters":{"address":5611664,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758020,"warp_table_address":5429836,"water_encounters":{"address":5611636,"slots":[72,309,309,310,310]}},"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":{"header_address":4761212,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":{"header_address":4761184,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":{"header_address":4761156,"warp_table_address":5466624},"MAP_SLATEPORT_CITY_HARBOR":{"header_address":4761352,"warp_table_address":5468328},"MAP_SLATEPORT_CITY_HOUSE":{"header_address":4761380,"warp_table_address":5468492},"MAP_SLATEPORT_CITY_MART":{"header_address":4761464,"warp_table_address":5468856},"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":{"header_address":4761240,"warp_table_address":5466832},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":{"header_address":4761296,"warp_table_address":5467456},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":{"header_address":4761324,"warp_table_address":5467856},"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":{"header_address":4761408,"warp_table_address":5468600},"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":{"header_address":4761436,"warp_table_address":5468740},"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":{"header_address":4761268,"warp_table_address":5467084},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":{"header_address":4761100,"warp_table_address":5466360},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":{"header_address":4761128,"warp_table_address":5466476},"MAP_SOOTOPOLIS_CITY":{"fishing_encounters":{"address":5612184,"slots":[129,72,129,129,129,129,129,130,130,130]},"header_address":4758188,"warp_table_address":5433852,"water_encounters":{"address":5612156,"slots":[129,129,129,129,129]}},"MAP_SOOTOPOLIS_CITY_GYM_1F":{"header_address":4763480,"warp_table_address":5481892},"MAP_SOOTOPOLIS_CITY_GYM_B1F":{"header_address":4763508,"warp_table_address":5482200},"MAP_SOOTOPOLIS_CITY_HOUSE1":{"header_address":4763620,"warp_table_address":5482664},"MAP_SOOTOPOLIS_CITY_HOUSE2":{"header_address":4763648,"warp_table_address":5482724},"MAP_SOOTOPOLIS_CITY_HOUSE3":{"header_address":4763676,"warp_table_address":5482808},"MAP_SOOTOPOLIS_CITY_HOUSE4":{"header_address":4763704,"warp_table_address":5482916},"MAP_SOOTOPOLIS_CITY_HOUSE5":{"header_address":4763732,"warp_table_address":5483000},"MAP_SOOTOPOLIS_CITY_HOUSE6":{"header_address":4763760,"warp_table_address":5483060},"MAP_SOOTOPOLIS_CITY_HOUSE7":{"header_address":4763788,"warp_table_address":5483144},"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":{"header_address":4763816,"warp_table_address":5483228},"MAP_SOOTOPOLIS_CITY_MART":{"header_address":4763592,"warp_table_address":5482580},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":{"header_address":4763844,"warp_table_address":5483312},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":{"header_address":4763872,"warp_table_address":5483380},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":{"header_address":4763536,"warp_table_address":5482324},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":{"header_address":4763564,"warp_table_address":5482464},"MAP_SOUTHERN_ISLAND_EXTERIOR":{"header_address":4769640,"warp_table_address":5516780},"MAP_SOUTHERN_ISLAND_INTERIOR":{"header_address":4769668,"warp_table_address":5516876},"MAP_SS_TIDAL_CORRIDOR":{"header_address":4768828,"warp_table_address":5510992},"MAP_SS_TIDAL_LOWER_DECK":{"header_address":4768856,"warp_table_address":5511276},"MAP_SS_TIDAL_ROOMS":{"header_address":4768884,"warp_table_address":5511508},"MAP_TERRA_CAVE_END":{"header_address":4767596,"warp_table_address":5500392},"MAP_TERRA_CAVE_ENTRANCE":{"header_address":4767568,"warp_table_address":5500332},"MAP_TRADE_CENTER":{"header_address":4768380,"warp_table_address":5509944},"MAP_TRAINER_HILL_1F":{"header_address":4771096,"warp_table_address":5525172},"MAP_TRAINER_HILL_2F":{"header_address":4771124,"warp_table_address":5525208},"MAP_TRAINER_HILL_3F":{"header_address":4771152,"warp_table_address":5525244},"MAP_TRAINER_HILL_4F":{"header_address":4771180,"warp_table_address":5525280},"MAP_TRAINER_HILL_ELEVATOR":{"header_address":4771852,"warp_table_address":5526300},"MAP_TRAINER_HILL_ENTRANCE":{"header_address":4771068,"warp_table_address":5525100},"MAP_TRAINER_HILL_ROOF":{"header_address":4771208,"warp_table_address":5525340},"MAP_UNDERWATER_MARINE_CAVE":{"header_address":4767484,"warp_table_address":5500208},"MAP_UNDERWATER_ROUTE105":{"header_address":4759532,"warp_table_address":5457348},"MAP_UNDERWATER_ROUTE124":{"header_address":4759392,"warp_table_address":4160749568,"water_encounters":{"address":5612016,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE125":{"header_address":4759560,"warp_table_address":5457384},"MAP_UNDERWATER_ROUTE126":{"header_address":4759420,"warp_table_address":5457052,"water_encounters":{"address":5606268,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE127":{"header_address":4759448,"warp_table_address":5457176},"MAP_UNDERWATER_ROUTE128":{"header_address":4759476,"warp_table_address":5457260},"MAP_UNDERWATER_ROUTE129":{"header_address":4759504,"warp_table_address":5457312},"MAP_UNDERWATER_ROUTE134":{"header_address":4766588,"warp_table_address":5497540},"MAP_UNDERWATER_SEAFLOOR_CAVERN":{"header_address":4765384,"warp_table_address":5491744},"MAP_UNDERWATER_SEALED_CHAMBER":{"header_address":4766616,"warp_table_address":5497568},"MAP_UNDERWATER_SOOTOPOLIS_CITY":{"header_address":4764796,"warp_table_address":5486768},"MAP_UNION_ROOM":{"header_address":4769360,"warp_table_address":5514872},"MAP_UNUSED_CONTEST_HALL1":{"header_address":4768492,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL2":{"header_address":4768520,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL3":{"header_address":4768548,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL4":{"header_address":4768576,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL5":{"header_address":4768604,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL6":{"header_address":4768632,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN":{"header_address":4758384,"warp_table_address":5436044},"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760512,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760484,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760456,"warp_table_address":5463128},"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":{"header_address":4760652,"warp_table_address":5463928},"MAP_VERDANTURF_TOWN_HOUSE":{"header_address":4760680,"warp_table_address":5464012},"MAP_VERDANTURF_TOWN_MART":{"header_address":4760540,"warp_table_address":5463408},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":{"header_address":4760568,"warp_table_address":5463540},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":{"header_address":4760596,"warp_table_address":5463680},"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":{"header_address":4760624,"warp_table_address":5463844},"MAP_VICTORY_ROAD_1F":{"header_address":4765860,"land_encounters":{"address":5606156,"slots":[42,336,383,371,41,335,42,336,382,370,382,370]},"warp_table_address":5493852},"MAP_VICTORY_ROAD_B1F":{"header_address":4765888,"land_encounters":{"address":5610496,"slots":[42,336,383,383,42,336,42,336,383,355,383,355]},"rock_smash_encounters":{"address":5610552,"slots":[75,74,75,75,75]},"warp_table_address":5494460},"MAP_VICTORY_ROAD_B2F":{"fishing_encounters":{"address":5610664,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4765916,"land_encounters":{"address":5610580,"slots":[42,322,383,383,42,322,42,322,383,355,383,355]},"warp_table_address":5494704,"water_encounters":{"address":5610636,"slots":[42,42,42,42,42]}}},"misc_pokemon":[{"address":2572358,"species":385},{"address":2018148,"species":360},{"address":2323175,"species":101},{"address":2323252,"species":101},{"address":2581669,"species":317},{"address":2581574,"species":317},{"address":2581688,"species":317},{"address":2581593,"species":317},{"address":2581612,"species":317},{"address":2581631,"species":317},{"address":2581650,"species":317},{"address":2065036,"species":317},{"address":2386223,"species":185},{"address":2339323,"species":100},{"address":2339400,"species":100},{"address":2339477,"species":100}],"misc_ram_addresses":{"CB2_Overworld":134768624,"gArchipelagoDeathLinkQueued":33804824,"gArchipelagoReceivedItem":33804776,"gMain":50340544,"gPlayerParty":33703196,"gSaveBlock1Ptr":50355596,"gSaveBlock2Ptr":50355600},"misc_rom_addresses":{"FindObjectEventPaletteIndexByTag":586344,"LoadObjectEventPalette":586116,"PatchObjectPalette":586244,"gArchipelagoInfo":5912960,"gArchipelagoItemNames":5896457,"gArchipelagoNameTable":5905457,"gArchipelagoOptions":5895556,"gArchipelagoPlayerNames":5895607,"gBattleMoves":3281380,"gEvolutionTable":3318404,"gLevelUpLearnsets":3334884,"gMonBackPicTable":3174912,"gMonFootprintTable":5726932,"gMonFrontPicTable":3205844,"gMonIconPaletteIndices":5784268,"gMonIconTable":5782508,"gMonPaletteTable":3178432,"gMonShinyPaletteTable":3181952,"gObjectEventBaseOam_16x16":5311020,"gObjectEventBaseOam_16x32":5311044,"gObjectEventBaseOam_32x32":5311052,"gObjectEventGraphicsInfoPointers":5294928,"gRandomizedBerryTreeItems":5843560,"gRandomizedSoundTable":10155508,"gSpeciesInfo":3296744,"gTMHMLearnsets":3289780,"gTrainerBackAnimsPtrTable":3188308,"gTrainerBackPicPaletteTable":3188436,"gTrainerBackPicTable":3188372,"gTrainerFrontPicPaletteTable":3187332,"gTrainerFrontPicTable":3186588,"gTrainers":3230072,"gTutorMoves":6428060,"sBackAnims_Brendan":3188244,"sBackAnims_Red":3188260,"sEggHatchTiles":3344020,"sEggPalette":3343988,"sEmpty6":14929745,"sNewGamePCItems":6210444,"sOamTables_16x16":5311100,"sOamTables_16x32":5311184,"sOamTables_32x32":5311268,"sObjectEventSpritePalettes":5320952,"sStarterMon":6021752,"sTMHMMoves":6432208,"sTrainerBackSpriteTemplates":3337568,"sTutorLearnsets":6428120},"species":[{"abilities":[0,0],"address":3296744,"base_stats":[0,0,0,0,0,0],"catch_rate":0,"evolutions":[],"friendship":0,"id":0,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3296772,"base_stats":[45,49,49,45,65,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":2}],"friendship":70,"id":1,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296800,"base_stats":[60,62,63,60,80,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":3}],"friendship":70,"id":2,"learnset":{"address":3308308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":38,"move_id":74},{"level":47,"move_id":235},{"level":56,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296828,"base_stats":[80,82,83,80,100,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":3,"learnset":{"address":3308338,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":1,"move_id":22},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":41,"move_id":74},{"level":53,"move_id":235},{"level":65,"move_id":76}]},"tmhm_learnset":"00E41E0886354730","types":[12,3]},{"abilities":[66,0],"address":3296856,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":5}],"friendship":70,"id":4,"learnset":{"address":3308368,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":19,"move_id":99},{"level":25,"move_id":184},{"level":31,"move_id":53},{"level":37,"move_id":163},{"level":43,"move_id":82},{"level":49,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296884,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":6}],"friendship":70,"id":5,"learnset":{"address":3308394,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":41,"move_id":163},{"level":48,"move_id":82},{"level":55,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296912,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":6,"learnset":{"address":3308420,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":1,"move_id":108},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":36,"move_id":17},{"level":44,"move_id":163},{"level":54,"move_id":82},{"level":64,"move_id":83}]},"tmhm_learnset":"00AE5EA4CE514633","types":[10,2]},{"abilities":[67,0],"address":3296940,"base_stats":[44,48,65,43,50,64],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":8}],"friendship":70,"id":7,"learnset":{"address":3308448,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":18,"move_id":44},{"level":23,"move_id":229},{"level":28,"move_id":182},{"level":33,"move_id":240},{"level":40,"move_id":130},{"level":47,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296968,"base_stats":[59,63,80,58,65,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":9}],"friendship":70,"id":8,"learnset":{"address":3308478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":37,"move_id":240},{"level":45,"move_id":130},{"level":53,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296996,"base_stats":[79,83,100,78,85,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":9,"learnset":{"address":3308508,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":1,"move_id":110},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":42,"move_id":240},{"level":55,"move_id":130},{"level":68,"move_id":56}]},"tmhm_learnset":"03B01E00CE537275","types":[11,11]},{"abilities":[19,0],"address":3297024,"base_stats":[45,30,35,45,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":11}],"friendship":70,"id":10,"learnset":{"address":3308538,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3297052,"base_stats":[50,20,55,30,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":12}],"friendship":70,"id":11,"learnset":{"address":3308548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[14,0],"address":3297080,"base_stats":[60,45,50,70,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":12,"learnset":{"address":3308560,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":77},{"level":14,"move_id":78},{"level":15,"move_id":79},{"level":18,"move_id":48},{"level":23,"move_id":18},{"level":28,"move_id":16},{"level":34,"move_id":60},{"level":40,"move_id":219},{"level":47,"move_id":318}]},"tmhm_learnset":"0040BE80B43F4620","types":[6,2]},{"abilities":[19,0],"address":3297108,"base_stats":[40,35,30,50,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":14}],"friendship":70,"id":13,"learnset":{"address":3308590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[61,0],"address":3297136,"base_stats":[45,25,50,35,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":15}],"friendship":70,"id":14,"learnset":{"address":3308600,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[68,0],"address":3297164,"base_stats":[65,80,40,75,45,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":15,"learnset":{"address":3308612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":31},{"level":10,"move_id":31},{"level":15,"move_id":116},{"level":20,"move_id":41},{"level":25,"move_id":99},{"level":30,"move_id":228},{"level":35,"move_id":42},{"level":40,"move_id":97},{"level":45,"move_id":283}]},"tmhm_learnset":"00843E88C4354620","types":[6,3]},{"abilities":[51,0],"address":3297192,"base_stats":[40,45,40,56,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":17}],"friendship":70,"id":16,"learnset":{"address":3308638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":19,"move_id":18},{"level":25,"move_id":17},{"level":31,"move_id":297},{"level":39,"move_id":97},{"level":47,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297220,"base_stats":[63,60,55,71,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":18}],"friendship":70,"id":17,"learnset":{"address":3308664,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":43,"move_id":97},{"level":52,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297248,"base_stats":[83,80,75,91,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":18,"learnset":{"address":3308690,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":1,"move_id":98},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":48,"move_id":97},{"level":62,"move_id":119}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[50,62],"address":3297276,"base_stats":[30,56,35,72,25,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":20}],"friendship":70,"id":19,"learnset":{"address":3308716,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":116},{"level":27,"move_id":228},{"level":34,"move_id":162},{"level":41,"move_id":283}]},"tmhm_learnset":"00843E02ADD33E20","types":[0,0]},{"abilities":[50,62],"address":3297304,"base_stats":[55,81,60,97,50,70],"catch_rate":127,"evolutions":[],"friendship":70,"id":20,"learnset":{"address":3308738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":184},{"level":30,"move_id":228},{"level":40,"move_id":162},{"level":50,"move_id":283}]},"tmhm_learnset":"00A43E02ADD37E30","types":[0,0]},{"abilities":[51,0],"address":3297332,"base_stats":[40,60,30,70,31,31],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":22}],"friendship":70,"id":21,"learnset":{"address":3308760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":19,"move_id":228},{"level":25,"move_id":332},{"level":31,"move_id":119},{"level":37,"move_id":65},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297360,"base_stats":[65,90,65,100,61,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":22,"learnset":{"address":3308784,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":43},{"level":1,"move_id":31},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":26,"move_id":228},{"level":32,"move_id":119},{"level":40,"move_id":65},{"level":47,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[22,61],"address":3297388,"base_stats":[35,60,44,55,40,54],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":24}],"friendship":70,"id":23,"learnset":{"address":3308806,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":25,"move_id":103},{"level":32,"move_id":51},{"level":37,"move_id":254},{"level":37,"move_id":256},{"level":37,"move_id":255},{"level":44,"move_id":114}]},"tmhm_learnset":"00213F088E570620","types":[3,3]},{"abilities":[22,61],"address":3297416,"base_stats":[60,85,69,80,65,79],"catch_rate":90,"evolutions":[],"friendship":70,"id":24,"learnset":{"address":3308834,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":40},{"level":1,"move_id":44},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":28,"move_id":103},{"level":38,"move_id":51},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255},{"level":56,"move_id":114}]},"tmhm_learnset":"00213F088E574620","types":[3,3]},{"abilities":[9,0],"address":3297444,"base_stats":[35,55,30,90,50,40],"catch_rate":190,"evolutions":[{"method":"ITEM","param":96,"species":26}],"friendship":70,"id":25,"learnset":{"address":3308862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":45},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":98},{"level":15,"move_id":104},{"level":20,"move_id":21},{"level":26,"move_id":85},{"level":33,"move_id":97},{"level":41,"move_id":87},{"level":50,"move_id":113}]},"tmhm_learnset":"00E01E02CDD38221","types":[13,13]},{"abilities":[9,0],"address":3297472,"base_stats":[60,90,55,100,90,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":26,"learnset":{"address":3308890,"moves":[{"level":1,"move_id":84},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":1,"move_id":85}]},"tmhm_learnset":"00E03E02CDD3C221","types":[13,13]},{"abilities":[8,0],"address":3297500,"base_stats":[50,75,85,40,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":28}],"friendship":70,"id":27,"learnset":{"address":3308900,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":23,"move_id":163},{"level":30,"move_id":129},{"level":37,"move_id":154},{"level":45,"move_id":328},{"level":53,"move_id":201}]},"tmhm_learnset":"00A43ED0CE510621","types":[4,4]},{"abilities":[8,0],"address":3297528,"base_stats":[75,100,110,65,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":28,"learnset":{"address":3308926,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":28},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":24,"move_id":163},{"level":33,"move_id":129},{"level":42,"move_id":154},{"level":52,"move_id":328},{"level":62,"move_id":201}]},"tmhm_learnset":"00A43ED0CE514621","types":[4,4]},{"abilities":[38,0],"address":3297556,"base_stats":[55,47,52,41,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":30}],"friendship":70,"id":29,"learnset":{"address":3308952,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":44},{"level":23,"move_id":270},{"level":30,"move_id":154},{"level":38,"move_id":260},{"level":47,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297584,"base_stats":[70,62,67,56,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":31}],"friendship":70,"id":30,"learnset":{"address":3308978,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":44},{"level":26,"move_id":270},{"level":34,"move_id":154},{"level":43,"move_id":260},{"level":53,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297612,"base_stats":[90,82,87,76,75,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":31,"learnset":{"address":3309004,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":34}]},"tmhm_learnset":"00B43FFEEFD37E35","types":[3,4]},{"abilities":[38,0],"address":3297640,"base_stats":[46,57,40,50,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":33}],"friendship":70,"id":32,"learnset":{"address":3309016,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":30},{"level":23,"move_id":270},{"level":30,"move_id":31},{"level":38,"move_id":260},{"level":47,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297668,"base_stats":[61,72,57,65,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":34}],"friendship":70,"id":33,"learnset":{"address":3309042,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":30},{"level":26,"move_id":270},{"level":34,"move_id":31},{"level":43,"move_id":260},{"level":53,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297696,"base_stats":[81,92,77,85,85,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":34,"learnset":{"address":3309068,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":116},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":37}]},"tmhm_learnset":"00B43F7EEFD37E35","types":[3,4]},{"abilities":[56,0],"address":3297724,"base_stats":[70,45,48,35,60,65],"catch_rate":150,"evolutions":[{"method":"ITEM","param":94,"species":36}],"friendship":140,"id":35,"learnset":{"address":3309080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":227},{"level":9,"move_id":47},{"level":13,"move_id":3},{"level":17,"move_id":266},{"level":21,"move_id":107},{"level":25,"move_id":111},{"level":29,"move_id":118},{"level":33,"move_id":322},{"level":37,"move_id":236},{"level":41,"move_id":113},{"level":45,"move_id":309}]},"tmhm_learnset":"00611E27FDFBB62D","types":[0,0]},{"abilities":[56,0],"address":3297752,"base_stats":[95,70,73,60,85,90],"catch_rate":25,"evolutions":[],"friendship":140,"id":36,"learnset":{"address":3309112,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":3},{"level":1,"move_id":107},{"level":1,"move_id":118}]},"tmhm_learnset":"00611E27FDFBF62D","types":[0,0]},{"abilities":[18,0],"address":3297780,"base_stats":[38,41,40,65,50,65],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":38}],"friendship":70,"id":37,"learnset":{"address":3309122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":5,"move_id":39},{"level":9,"move_id":46},{"level":13,"move_id":98},{"level":17,"move_id":261},{"level":21,"move_id":109},{"level":25,"move_id":286},{"level":29,"move_id":53},{"level":33,"move_id":219},{"level":37,"move_id":288},{"level":41,"move_id":83}]},"tmhm_learnset":"00021E248C590630","types":[10,10]},{"abilities":[18,0],"address":3297808,"base_stats":[73,76,75,100,81,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":38,"learnset":{"address":3309152,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":98},{"level":1,"move_id":109},{"level":1,"move_id":219},{"level":45,"move_id":83}]},"tmhm_learnset":"00021E248C594630","types":[10,10]},{"abilities":[56,0],"address":3297836,"base_stats":[115,45,20,20,45,25],"catch_rate":170,"evolutions":[{"method":"ITEM","param":94,"species":40}],"friendship":70,"id":39,"learnset":{"address":3309164,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":50},{"level":19,"move_id":205},{"level":24,"move_id":3},{"level":29,"move_id":156},{"level":34,"move_id":34},{"level":39,"move_id":102},{"level":44,"move_id":304},{"level":49,"move_id":38}]},"tmhm_learnset":"00611E27FDBBB625","types":[0,0]},{"abilities":[56,0],"address":3297864,"base_stats":[140,70,45,45,75,50],"catch_rate":50,"evolutions":[],"friendship":70,"id":40,"learnset":{"address":3309194,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":50},{"level":1,"move_id":111},{"level":1,"move_id":3}]},"tmhm_learnset":"00611E27FDBBF625","types":[0,0]},{"abilities":[39,0],"address":3297892,"base_stats":[40,45,35,55,30,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":42}],"friendship":70,"id":41,"learnset":{"address":3309204,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":141},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":26,"move_id":109},{"level":31,"move_id":314},{"level":36,"move_id":212},{"level":41,"move_id":305},{"level":46,"move_id":114}]},"tmhm_learnset":"00017F88A4170E20","types":[3,2]},{"abilities":[39,0],"address":3297920,"base_stats":[75,80,70,90,65,75],"catch_rate":90,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":169}],"friendship":70,"id":42,"learnset":{"address":3309232,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00017F88A4174E20","types":[3,2]},{"abilities":[34,0],"address":3297948,"base_stats":[45,50,55,30,75,65],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":44}],"friendship":70,"id":43,"learnset":{"address":3309260,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":23,"move_id":51},{"level":32,"move_id":236},{"level":39,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3297976,"base_stats":[60,65,70,40,85,75],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":45},{"method":"ITEM","param":93,"species":182}],"friendship":70,"id":44,"learnset":{"address":3309284,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":77},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":24,"move_id":51},{"level":35,"move_id":236},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298004,"base_stats":[75,80,85,50,100,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":45,"learnset":{"address":3309308,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":312},{"level":1,"move_id":78},{"level":1,"move_id":72},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884354720","types":[12,3]},{"abilities":[27,0],"address":3298032,"base_stats":[35,70,55,25,45,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":24,"species":47}],"friendship":70,"id":46,"learnset":{"address":3309320,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":25,"move_id":147},{"level":31,"move_id":163},{"level":37,"move_id":74},{"level":43,"move_id":202},{"level":49,"move_id":312}]},"tmhm_learnset":"00C43E888C350720","types":[6,12]},{"abilities":[27,0],"address":3298060,"base_stats":[60,95,80,30,60,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":47,"learnset":{"address":3309346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":78},{"level":1,"move_id":77},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":27,"move_id":147},{"level":35,"move_id":163},{"level":43,"move_id":74},{"level":51,"move_id":202},{"level":59,"move_id":312}]},"tmhm_learnset":"00C43E888C354720","types":[6,12]},{"abilities":[14,0],"address":3298088,"base_stats":[60,55,50,45,40,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":49}],"friendship":70,"id":48,"learnset":{"address":3309372,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":33,"move_id":60},{"level":36,"move_id":79},{"level":41,"move_id":94}]},"tmhm_learnset":"0040BE0894350620","types":[6,3]},{"abilities":[19,0],"address":3298116,"base_stats":[70,65,60,90,90,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":49,"learnset":{"address":3309398,"moves":[{"level":1,"move_id":318},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":1,"move_id":48},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":31,"move_id":16},{"level":36,"move_id":60},{"level":42,"move_id":79},{"level":52,"move_id":94}]},"tmhm_learnset":"0040BE8894354620","types":[6,3]},{"abilities":[8,71],"address":3298144,"base_stats":[10,55,25,95,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":26,"species":51}],"friendship":70,"id":50,"learnset":{"address":3309428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":33,"move_id":163},{"level":41,"move_id":89},{"level":49,"move_id":90}]},"tmhm_learnset":"00843EC88E110620","types":[4,4]},{"abilities":[8,71],"address":3298172,"base_stats":[35,80,50,120,50,70],"catch_rate":50,"evolutions":[],"friendship":70,"id":51,"learnset":{"address":3309452,"moves":[{"level":1,"move_id":161},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":1,"move_id":45},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":26,"move_id":328},{"level":38,"move_id":163},{"level":51,"move_id":89},{"level":64,"move_id":90}]},"tmhm_learnset":"00843EC88E114620","types":[4,4]},{"abilities":[53,0],"address":3298200,"base_stats":[40,45,35,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":28,"species":53}],"friendship":70,"id":52,"learnset":{"address":3309478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":28,"move_id":185},{"level":35,"move_id":103},{"level":41,"move_id":154},{"level":46,"move_id":163},{"level":50,"move_id":252}]},"tmhm_learnset":"00453F82ADD30E24","types":[0,0]},{"abilities":[7,0],"address":3298228,"base_stats":[65,70,60,115,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":53,"learnset":{"address":3309502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":44},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":29,"move_id":185},{"level":38,"move_id":103},{"level":46,"move_id":154},{"level":53,"move_id":163},{"level":59,"move_id":252}]},"tmhm_learnset":"00453F82ADD34E34","types":[0,0]},{"abilities":[6,13],"address":3298256,"base_stats":[50,52,48,55,65,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":33,"species":55}],"friendship":70,"id":54,"learnset":{"address":3309526,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":40,"move_id":154},{"level":50,"move_id":56}]},"tmhm_learnset":"03F01E80CC53326D","types":[11,11]},{"abilities":[6,13],"address":3298284,"base_stats":[80,82,78,85,95,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":55,"learnset":{"address":3309550,"moves":[{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":50},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":44,"move_id":154},{"level":58,"move_id":56}]},"tmhm_learnset":"03F01E80CC53726D","types":[11,11]},{"abilities":[72,0],"address":3298312,"base_stats":[40,80,35,70,35,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":57}],"friendship":70,"id":56,"learnset":{"address":3309574,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":33,"move_id":69},{"level":39,"move_id":238},{"level":45,"move_id":103},{"level":51,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD30EA1","types":[1,1]},{"abilities":[72,0],"address":3298340,"base_stats":[65,105,60,95,60,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":57,"learnset":{"address":3309600,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":67},{"level":1,"move_id":99},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":28,"move_id":99},{"level":36,"move_id":69},{"level":45,"move_id":238},{"level":54,"move_id":103},{"level":63,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD34EA1","types":[1,1]},{"abilities":[22,18],"address":3298368,"base_stats":[55,70,45,60,70,50],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":59}],"friendship":70,"id":58,"learnset":{"address":3309628,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":7,"move_id":52},{"level":13,"move_id":43},{"level":19,"move_id":316},{"level":25,"move_id":36},{"level":31,"move_id":172},{"level":37,"move_id":270},{"level":43,"move_id":97},{"level":49,"move_id":53}]},"tmhm_learnset":"00A23EA48C510630","types":[10,10]},{"abilities":[22,18],"address":3298396,"base_stats":[90,110,80,95,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":59,"learnset":{"address":3309654,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":1,"move_id":52},{"level":1,"move_id":316},{"level":49,"move_id":245}]},"tmhm_learnset":"00A23EA48C514630","types":[10,10]},{"abilities":[11,6],"address":3298424,"base_stats":[40,50,40,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":61}],"friendship":70,"id":60,"learnset":{"address":3309666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":25,"move_id":240},{"level":31,"move_id":34},{"level":37,"move_id":187},{"level":43,"move_id":56}]},"tmhm_learnset":"03103E009C133264","types":[11,11]},{"abilities":[11,6],"address":3298452,"base_stats":[65,65,65,90,50,50],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":62},{"method":"ITEM","param":187,"species":186}],"friendship":70,"id":61,"learnset":{"address":3309690,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":95},{"level":1,"move_id":55},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":27,"move_id":240},{"level":35,"move_id":34},{"level":43,"move_id":187},{"level":51,"move_id":56}]},"tmhm_learnset":"03B03E00DE133265","types":[11,11]},{"abilities":[11,6],"address":3298480,"base_stats":[90,85,95,70,70,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":62,"learnset":{"address":3309714,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":66},{"level":35,"move_id":66},{"level":51,"move_id":170}]},"tmhm_learnset":"03B03E40DE1372E5","types":[11,1]},{"abilities":[28,39],"address":3298508,"base_stats":[25,20,15,90,105,55],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":16,"species":64}],"friendship":70,"id":63,"learnset":{"address":3309728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":100}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298536,"base_stats":[40,35,30,105,120,70],"catch_rate":100,"evolutions":[{"method":"LEVEL","param":37,"species":65}],"friendship":70,"id":64,"learnset":{"address":3309738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":272},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298564,"base_stats":[55,50,45,120,135,85],"catch_rate":50,"evolutions":[],"friendship":70,"id":65,"learnset":{"address":3309766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":347},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45BCE29","types":[14,14]},{"abilities":[62,0],"address":3298592,"base_stats":[70,80,50,35,35,35],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":28,"species":67}],"friendship":70,"id":66,"learnset":{"address":3309794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":31,"move_id":233},{"level":37,"move_id":66},{"level":40,"move_id":238},{"level":43,"move_id":184},{"level":49,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298620,"base_stats":[80,100,70,45,50,60],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":68}],"friendship":70,"id":67,"learnset":{"address":3309824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298648,"base_stats":[90,130,80,55,65,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":68,"learnset":{"address":3309854,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1346A1","types":[1,1]},{"abilities":[34,0],"address":3298676,"base_stats":[50,75,35,40,70,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":70}],"friendship":70,"id":69,"learnset":{"address":3309884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":23,"move_id":51},{"level":30,"move_id":230},{"level":37,"move_id":75},{"level":45,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298704,"base_stats":[65,90,50,55,85,45],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":71}],"friendship":70,"id":70,"learnset":{"address":3309912,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":1,"move_id":74},{"level":1,"move_id":35},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":24,"move_id":51},{"level":33,"move_id":230},{"level":42,"move_id":75},{"level":54,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298732,"base_stats":[80,105,65,70,100,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":71,"learnset":{"address":3309940,"moves":[{"level":1,"move_id":22},{"level":1,"move_id":79},{"level":1,"move_id":230},{"level":1,"move_id":75}]},"tmhm_learnset":"00443E0884354720","types":[12,3]},{"abilities":[29,64],"address":3298760,"base_stats":[40,40,35,70,50,100],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":73}],"friendship":70,"id":72,"learnset":{"address":3309950,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":36,"move_id":112},{"level":43,"move_id":103},{"level":49,"move_id":56}]},"tmhm_learnset":"03143E0884173264","types":[11,3]},{"abilities":[29,64],"address":3298788,"base_stats":[80,70,65,100,80,120],"catch_rate":60,"evolutions":[],"friendship":70,"id":73,"learnset":{"address":3309976,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":48},{"level":1,"move_id":132},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":38,"move_id":112},{"level":47,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03143E0884177264","types":[11,3]},{"abilities":[69,5],"address":3298816,"base_stats":[40,80,100,20,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":75}],"friendship":70,"id":74,"learnset":{"address":3310002,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":26,"move_id":205},{"level":31,"move_id":350},{"level":36,"move_id":89},{"level":41,"move_id":153},{"level":46,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298844,"base_stats":[55,95,115,35,45,45],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":37,"species":76}],"friendship":70,"id":75,"learnset":{"address":3310030,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298872,"base_stats":[80,110,130,45,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":76,"learnset":{"address":3310058,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE114631","types":[5,4]},{"abilities":[50,18],"address":3298900,"base_stats":[50,85,55,90,65,65],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":40,"species":78}],"friendship":70,"id":77,"learnset":{"address":3310086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":45,"move_id":340},{"level":53,"move_id":126}]},"tmhm_learnset":"00221E2484710620","types":[10,10]},{"abilities":[50,18],"address":3298928,"base_stats":[65,100,70,105,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":78,"learnset":{"address":3310114,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":52},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":40,"move_id":31},{"level":50,"move_id":340},{"level":63,"move_id":126}]},"tmhm_learnset":"00221E2484714620","types":[10,10]},{"abilities":[12,20],"address":3298956,"base_stats":[90,65,65,15,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":80},{"method":"ITEM","param":187,"species":199}],"friendship":70,"id":79,"learnset":{"address":3310144,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":133},{"level":48,"move_id":94}]},"tmhm_learnset":"02709E24BE5B366C","types":[11,14]},{"abilities":[12,20],"address":3298984,"base_stats":[95,75,110,30,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":80,"learnset":{"address":3310168,"moves":[{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":37,"move_id":110},{"level":46,"move_id":133},{"level":54,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[42,5],"address":3299012,"base_stats":[25,35,70,45,95,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":82}],"friendship":70,"id":81,"learnset":{"address":3310194,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":32,"move_id":199},{"level":38,"move_id":129},{"level":44,"move_id":103},{"level":50,"move_id":192}]},"tmhm_learnset":"00400E0385930620","types":[13,8]},{"abilities":[42,5],"address":3299040,"base_stats":[50,60,95,70,120,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":82,"learnset":{"address":3310222,"moves":[{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":1,"move_id":84},{"level":1,"move_id":48},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":35,"move_id":199},{"level":44,"move_id":161},{"level":53,"move_id":103},{"level":62,"move_id":192}]},"tmhm_learnset":"00400E0385934620","types":[13,8]},{"abilities":[51,39],"address":3299068,"base_stats":[52,65,55,60,58,62],"catch_rate":45,"evolutions":[],"friendship":70,"id":83,"learnset":{"address":3310250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":6,"move_id":28},{"level":11,"move_id":43},{"level":16,"move_id":31},{"level":21,"move_id":282},{"level":26,"move_id":210},{"level":31,"move_id":14},{"level":36,"move_id":97},{"level":41,"move_id":163},{"level":46,"move_id":206}]},"tmhm_learnset":"000C7E8084510620","types":[0,2]},{"abilities":[50,48],"address":3299096,"base_stats":[35,85,45,75,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":85}],"friendship":70,"id":84,"learnset":{"address":3310278,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":33,"move_id":253},{"level":37,"move_id":65},{"level":45,"move_id":97}]},"tmhm_learnset":"00087E8084110620","types":[0,2]},{"abilities":[50,48],"address":3299124,"base_stats":[60,110,70,100,60,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":85,"learnset":{"address":3310302,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":228},{"level":1,"move_id":31},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":38,"move_id":253},{"level":47,"move_id":65},{"level":60,"move_id":97}]},"tmhm_learnset":"00087F8084114E20","types":[0,2]},{"abilities":[47,0],"address":3299152,"base_stats":[65,45,55,45,45,70],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":34,"species":87}],"friendship":70,"id":86,"learnset":{"address":3310326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":29},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":37,"move_id":36},{"level":41,"move_id":58},{"level":49,"move_id":219}]},"tmhm_learnset":"03103E00841B3264","types":[11,11]},{"abilities":[47,0],"address":3299180,"base_stats":[90,70,80,70,70,95],"catch_rate":75,"evolutions":[],"friendship":70,"id":87,"learnset":{"address":3310350,"moves":[{"level":1,"move_id":29},{"level":1,"move_id":45},{"level":1,"move_id":196},{"level":1,"move_id":62},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":34,"move_id":329},{"level":42,"move_id":36},{"level":51,"move_id":58},{"level":64,"move_id":219}]},"tmhm_learnset":"03103E00841B7264","types":[11,15]},{"abilities":[1,60],"address":3299208,"base_stats":[80,80,50,25,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":89}],"friendship":70,"id":88,"learnset":{"address":3310376,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":43,"move_id":188},{"level":53,"move_id":262}]},"tmhm_learnset":"00003F6E8D970E20","types":[3,3]},{"abilities":[1,60],"address":3299236,"base_stats":[105,105,75,50,65,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":89,"learnset":{"address":3310402,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":47,"move_id":188},{"level":61,"move_id":262}]},"tmhm_learnset":"00A03F6ECD974E21","types":[3,3]},{"abilities":[75,0],"address":3299264,"base_stats":[30,65,100,40,45,25],"catch_rate":190,"evolutions":[{"method":"ITEM","param":97,"species":91}],"friendship":70,"id":90,"learnset":{"address":3310428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":110},{"level":9,"move_id":48},{"level":17,"move_id":62},{"level":25,"move_id":182},{"level":33,"move_id":43},{"level":41,"move_id":128},{"level":49,"move_id":58}]},"tmhm_learnset":"02101E0084133264","types":[11,11]},{"abilities":[75,0],"address":3299292,"base_stats":[50,95,180,70,85,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":91,"learnset":{"address":3310450,"moves":[{"level":1,"move_id":110},{"level":1,"move_id":48},{"level":1,"move_id":62},{"level":1,"move_id":182},{"level":33,"move_id":191},{"level":41,"move_id":131}]},"tmhm_learnset":"02101F0084137264","types":[11,15]},{"abilities":[26,0],"address":3299320,"base_stats":[30,35,30,80,100,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":93}],"friendship":70,"id":92,"learnset":{"address":3310464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":28,"move_id":109},{"level":33,"move_id":138},{"level":36,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299348,"base_stats":[45,50,45,95,115,55],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":94}],"friendship":70,"id":93,"learnset":{"address":3310488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299376,"base_stats":[60,65,60,110,130,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":94,"learnset":{"address":3310514,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"00A1BF08F5974E21","types":[7,3]},{"abilities":[69,5],"address":3299404,"base_stats":[35,45,160,70,30,45],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":208}],"friendship":70,"id":95,"learnset":{"address":3310540,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":328},{"level":57,"move_id":38}]},"tmhm_learnset":"00A01F508E510E30","types":[5,4]},{"abilities":[15,0],"address":3299432,"base_stats":[60,48,45,42,43,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":26,"species":97}],"friendship":70,"id":96,"learnset":{"address":3310568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":31,"move_id":139},{"level":36,"move_id":96},{"level":40,"move_id":94},{"level":43,"move_id":244},{"level":45,"move_id":248}]},"tmhm_learnset":"0041BF01F41B8E29","types":[14,14]},{"abilities":[15,0],"address":3299460,"base_stats":[85,73,70,67,73,115],"catch_rate":75,"evolutions":[],"friendship":70,"id":97,"learnset":{"address":3310594,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":1,"move_id":50},{"level":1,"move_id":93},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":33,"move_id":139},{"level":40,"move_id":96},{"level":49,"move_id":94},{"level":55,"move_id":244},{"level":60,"move_id":248}]},"tmhm_learnset":"0041BF01F41BCE29","types":[14,14]},{"abilities":[52,75],"address":3299488,"base_stats":[30,105,90,50,25,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":28,"species":99}],"friendship":70,"id":98,"learnset":{"address":3310620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":34,"move_id":12},{"level":41,"move_id":182},{"level":45,"move_id":152}]},"tmhm_learnset":"02B43E408C133264","types":[11,11]},{"abilities":[52,75],"address":3299516,"base_stats":[55,130,115,75,50,50],"catch_rate":60,"evolutions":[],"friendship":70,"id":99,"learnset":{"address":3310646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":43},{"level":1,"move_id":11},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":38,"move_id":12},{"level":49,"move_id":182},{"level":57,"move_id":152}]},"tmhm_learnset":"02B43E408C137264","types":[11,11]},{"abilities":[43,9],"address":3299544,"base_stats":[40,30,50,100,55,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":101}],"friendship":70,"id":100,"learnset":{"address":3310672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":32,"move_id":205},{"level":37,"move_id":113},{"level":42,"move_id":129},{"level":46,"move_id":153},{"level":49,"move_id":243}]},"tmhm_learnset":"00402F0285938A20","types":[13,13]},{"abilities":[43,9],"address":3299572,"base_stats":[60,50,70,140,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":101,"learnset":{"address":3310700,"moves":[{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":1,"move_id":49},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":34,"move_id":205},{"level":41,"move_id":113},{"level":48,"move_id":129},{"level":54,"move_id":153},{"level":59,"move_id":243}]},"tmhm_learnset":"00402F028593CA20","types":[13,13]},{"abilities":[34,0],"address":3299600,"base_stats":[60,40,80,40,60,45],"catch_rate":90,"evolutions":[{"method":"ITEM","param":98,"species":103}],"friendship":70,"id":102,"learnset":{"address":3310728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":253},{"level":1,"move_id":95},{"level":7,"move_id":115},{"level":13,"move_id":73},{"level":19,"move_id":93},{"level":25,"move_id":78},{"level":31,"move_id":77},{"level":37,"move_id":79},{"level":43,"move_id":76}]},"tmhm_learnset":"0060BE0994358720","types":[12,14]},{"abilities":[34,0],"address":3299628,"base_stats":[95,95,85,55,125,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":103,"learnset":{"address":3310752,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":95},{"level":1,"move_id":93},{"level":19,"move_id":23},{"level":31,"move_id":121}]},"tmhm_learnset":"0060BE099435C720","types":[12,14]},{"abilities":[69,31],"address":3299656,"base_stats":[50,50,95,35,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":105}],"friendship":70,"id":104,"learnset":{"address":3310766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":125},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":29,"move_id":99},{"level":33,"move_id":206},{"level":37,"move_id":37},{"level":41,"move_id":198},{"level":45,"move_id":38}]},"tmhm_learnset":"00A03EF4CE513621","types":[4,4]},{"abilities":[69,31],"address":3299684,"base_stats":[60,80,110,45,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":105,"learnset":{"address":3310798,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":125},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":32,"move_id":99},{"level":39,"move_id":206},{"level":46,"move_id":37},{"level":53,"move_id":198},{"level":61,"move_id":38}]},"tmhm_learnset":"00A03EF4CE517621","types":[4,4]},{"abilities":[7,0],"address":3299712,"base_stats":[50,120,53,87,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":106,"learnset":{"address":3310830,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":24},{"level":6,"move_id":96},{"level":11,"move_id":27},{"level":16,"move_id":26},{"level":20,"move_id":280},{"level":21,"move_id":116},{"level":26,"move_id":136},{"level":31,"move_id":170},{"level":36,"move_id":193},{"level":41,"move_id":203},{"level":46,"move_id":25},{"level":51,"move_id":179}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[51,0],"address":3299740,"base_stats":[50,105,79,76,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":107,"learnset":{"address":3310862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":4},{"level":7,"move_id":97},{"level":13,"move_id":228},{"level":20,"move_id":183},{"level":26,"move_id":9},{"level":26,"move_id":8},{"level":26,"move_id":7},{"level":32,"move_id":327},{"level":38,"move_id":5},{"level":44,"move_id":197},{"level":50,"move_id":68}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[20,12],"address":3299768,"base_stats":[90,55,75,30,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":108,"learnset":{"address":3310892,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":122},{"level":7,"move_id":48},{"level":12,"move_id":111},{"level":18,"move_id":282},{"level":23,"move_id":23},{"level":29,"move_id":35},{"level":34,"move_id":50},{"level":40,"move_id":21},{"level":45,"move_id":103},{"level":51,"move_id":287}]},"tmhm_learnset":"00B43E76EFF37625","types":[0,0]},{"abilities":[26,0],"address":3299796,"base_stats":[40,65,95,35,60,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":35,"species":110}],"friendship":70,"id":109,"learnset":{"address":3310920,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":41,"move_id":153},{"level":45,"move_id":194},{"level":49,"move_id":262}]},"tmhm_learnset":"00403F2EA5930E20","types":[3,3]},{"abilities":[26,0],"address":3299824,"base_stats":[65,90,120,60,85,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":110,"learnset":{"address":3310946,"moves":[{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":1,"move_id":123},{"level":1,"move_id":120},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":44,"move_id":153},{"level":51,"move_id":194},{"level":58,"move_id":262}]},"tmhm_learnset":"00403F2EA5934E20","types":[3,3]},{"abilities":[31,69],"address":3299852,"base_stats":[80,85,95,25,30,30],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":42,"species":112}],"friendship":70,"id":111,"learnset":{"address":3310972,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":43,"move_id":36},{"level":52,"move_id":89},{"level":57,"move_id":224}]},"tmhm_learnset":"00A03E768FD33630","types":[4,5]},{"abilities":[31,69],"address":3299880,"base_stats":[105,130,120,40,45,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":112,"learnset":{"address":3310998,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":1,"move_id":23},{"level":1,"move_id":31},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":46,"move_id":36},{"level":58,"move_id":89},{"level":66,"move_id":224}]},"tmhm_learnset":"00B43E76CFD37631","types":[4,5]},{"abilities":[30,32],"address":3299908,"base_stats":[250,5,5,50,35,105],"catch_rate":30,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":242}],"friendship":140,"id":113,"learnset":{"address":3311024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":287},{"level":13,"move_id":135},{"level":17,"move_id":3},{"level":23,"move_id":107},{"level":29,"move_id":47},{"level":35,"move_id":121},{"level":41,"move_id":111},{"level":49,"move_id":113},{"level":57,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[34,0],"address":3299936,"base_stats":[65,55,115,60,100,40],"catch_rate":45,"evolutions":[],"friendship":70,"id":114,"learnset":{"address":3311054,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":275},{"level":1,"move_id":132},{"level":4,"move_id":79},{"level":10,"move_id":71},{"level":13,"move_id":74},{"level":19,"move_id":77},{"level":22,"move_id":22},{"level":28,"move_id":20},{"level":31,"move_id":72},{"level":37,"move_id":78},{"level":40,"move_id":21},{"level":46,"move_id":321}]},"tmhm_learnset":"00C43E0884354720","types":[12,12]},{"abilities":[48,0],"address":3299964,"base_stats":[105,95,80,90,40,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":115,"learnset":{"address":3311084,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":4},{"level":1,"move_id":43},{"level":7,"move_id":44},{"level":13,"move_id":39},{"level":19,"move_id":252},{"level":25,"move_id":5},{"level":31,"move_id":99},{"level":37,"move_id":203},{"level":43,"move_id":146},{"level":49,"move_id":179}]},"tmhm_learnset":"00B43EF6EFF37675","types":[0,0]},{"abilities":[33,0],"address":3299992,"base_stats":[30,40,70,60,70,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":32,"species":117}],"friendship":70,"id":116,"learnset":{"address":3311110,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":36,"move_id":97},{"level":43,"move_id":56},{"level":50,"move_id":349}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[38,0],"address":3300020,"base_stats":[55,65,95,85,95,45],"catch_rate":75,"evolutions":[{"method":"ITEM","param":201,"species":230}],"friendship":70,"id":117,"learnset":{"address":3311134,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[33,41],"address":3300048,"base_stats":[45,67,60,63,35,50],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":119}],"friendship":70,"id":118,"learnset":{"address":3311158,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":38,"move_id":127},{"level":43,"move_id":32},{"level":52,"move_id":97}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,41],"address":3300076,"base_stats":[80,92,65,68,65,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":119,"learnset":{"address":3311182,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":1,"move_id":48},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":41,"move_id":127},{"level":49,"move_id":32},{"level":61,"move_id":97}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[35,30],"address":3300104,"base_stats":[30,45,55,85,70,55],"catch_rate":225,"evolutions":[{"method":"ITEM","param":97,"species":121}],"friendship":70,"id":120,"learnset":{"address":3311206,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":6,"move_id":55},{"level":10,"move_id":229},{"level":15,"move_id":105},{"level":19,"move_id":293},{"level":24,"move_id":129},{"level":28,"move_id":61},{"level":33,"move_id":107},{"level":37,"move_id":113},{"level":42,"move_id":322},{"level":46,"move_id":56}]},"tmhm_learnset":"03500E019593B264","types":[11,11]},{"abilities":[35,30],"address":3300132,"base_stats":[60,75,85,115,100,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":121,"learnset":{"address":3311236,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":229},{"level":1,"move_id":105},{"level":1,"move_id":129},{"level":33,"move_id":109}]},"tmhm_learnset":"03508E019593F264","types":[11,14]},{"abilities":[43,0],"address":3300160,"base_stats":[40,45,65,90,100,120],"catch_rate":45,"evolutions":[],"friendship":70,"id":122,"learnset":{"address":3311248,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":112},{"level":5,"move_id":93},{"level":9,"move_id":164},{"level":13,"move_id":96},{"level":17,"move_id":3},{"level":21,"move_id":113},{"level":21,"move_id":115},{"level":25,"move_id":227},{"level":29,"move_id":60},{"level":33,"move_id":278},{"level":37,"move_id":271},{"level":41,"move_id":272},{"level":45,"move_id":94},{"level":49,"move_id":226},{"level":53,"move_id":219}]},"tmhm_learnset":"0041BF03F5BBCE29","types":[14,14]},{"abilities":[68,0],"address":3300188,"base_stats":[70,110,80,105,55,80],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":212}],"friendship":70,"id":123,"learnset":{"address":3311286,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":17},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00847E8084134620","types":[6,2]},{"abilities":[12,0],"address":3300216,"base_stats":[65,50,35,95,115,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":124,"learnset":{"address":3311314,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":1,"move_id":142},{"level":1,"move_id":181},{"level":9,"move_id":142},{"level":13,"move_id":181},{"level":21,"move_id":3},{"level":25,"move_id":8},{"level":35,"move_id":212},{"level":41,"move_id":313},{"level":51,"move_id":34},{"level":57,"move_id":195},{"level":67,"move_id":59}]},"tmhm_learnset":"0040BF01F413FA6D","types":[15,14]},{"abilities":[9,0],"address":3300244,"base_stats":[65,83,57,105,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":125,"learnset":{"address":3311342,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":1,"move_id":9},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":36,"move_id":103},{"level":47,"move_id":85},{"level":58,"move_id":87}]},"tmhm_learnset":"00E03E02D5D3C221","types":[13,13]},{"abilities":[49,0],"address":3300272,"base_stats":[65,95,57,93,100,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":126,"learnset":{"address":3311364,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":43},{"level":1,"move_id":123},{"level":1,"move_id":7},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":33,"move_id":241},{"level":41,"move_id":53},{"level":49,"move_id":109},{"level":57,"move_id":126}]},"tmhm_learnset":"00A03E24D4514621","types":[10,10]},{"abilities":[52,0],"address":3300300,"base_stats":[65,125,100,85,55,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":127,"learnset":{"address":3311390,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":11},{"level":1,"move_id":116},{"level":7,"move_id":20},{"level":13,"move_id":69},{"level":19,"move_id":106},{"level":25,"move_id":279},{"level":31,"move_id":280},{"level":37,"move_id":12},{"level":43,"move_id":66},{"level":49,"move_id":14}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,6]},{"abilities":[22,0],"address":3300328,"base_stats":[75,100,95,110,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":128,"learnset":{"address":3311416,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":8,"move_id":99},{"level":13,"move_id":30},{"level":19,"move_id":184},{"level":26,"move_id":228},{"level":34,"move_id":156},{"level":43,"move_id":37},{"level":53,"move_id":36}]},"tmhm_learnset":"00B01E7687F37624","types":[0,0]},{"abilities":[33,0],"address":3300356,"base_stats":[20,10,55,80,15,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":130}],"friendship":70,"id":129,"learnset":{"address":3311442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"0000000000000000","types":[11,11]},{"abilities":[22,0],"address":3300384,"base_stats":[95,125,79,81,60,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":130,"learnset":{"address":3311456,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":37},{"level":20,"move_id":44},{"level":25,"move_id":82},{"level":30,"move_id":43},{"level":35,"move_id":239},{"level":40,"move_id":56},{"level":45,"move_id":240},{"level":50,"move_id":349},{"level":55,"move_id":63}]},"tmhm_learnset":"03B01F3487937A74","types":[11,2]},{"abilities":[11,75],"address":3300412,"base_stats":[130,85,80,60,85,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":131,"learnset":{"address":3311482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":45},{"level":1,"move_id":47},{"level":7,"move_id":54},{"level":13,"move_id":34},{"level":19,"move_id":109},{"level":25,"move_id":195},{"level":31,"move_id":58},{"level":37,"move_id":240},{"level":43,"move_id":219},{"level":49,"move_id":56},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E0295DB7274","types":[11,15]},{"abilities":[7,0],"address":3300440,"base_stats":[48,48,48,48,48,48],"catch_rate":35,"evolutions":[],"friendship":70,"id":132,"learnset":{"address":3311510,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":144}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[50,0],"address":3300468,"base_stats":[55,55,50,55,45,65],"catch_rate":45,"evolutions":[{"method":"ITEM","param":96,"species":135},{"method":"ITEM","param":97,"species":134},{"method":"ITEM","param":95,"species":136},{"method":"FRIENDSHIP_DAY","param":0,"species":196},{"method":"FRIENDSHIP_NIGHT","param":0,"species":197}],"friendship":70,"id":133,"learnset":{"address":3311520,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":45},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":226},{"level":42,"move_id":36}]},"tmhm_learnset":"00001E00AC530620","types":[0,0]},{"abilities":[11,0],"address":3300496,"base_stats":[130,65,60,65,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":134,"learnset":{"address":3311542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":55},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":62},{"level":42,"move_id":114},{"level":47,"move_id":151},{"level":52,"move_id":56}]},"tmhm_learnset":"03101E00AC537674","types":[11,11]},{"abilities":[10,0],"address":3300524,"base_stats":[65,65,60,130,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":135,"learnset":{"address":3311568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":84},{"level":23,"move_id":98},{"level":30,"move_id":24},{"level":36,"move_id":42},{"level":42,"move_id":86},{"level":47,"move_id":97},{"level":52,"move_id":87}]},"tmhm_learnset":"00401E02ADD34630","types":[13,13]},{"abilities":[18,0],"address":3300552,"base_stats":[65,130,60,65,95,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":136,"learnset":{"address":3311594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":52},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":83},{"level":42,"move_id":123},{"level":47,"move_id":43},{"level":52,"move_id":53}]},"tmhm_learnset":"00021E24AC534630","types":[10,10]},{"abilities":[36,0],"address":3300580,"base_stats":[65,60,70,40,85,75],"catch_rate":45,"evolutions":[{"method":"ITEM","param":218,"species":233}],"friendship":70,"id":137,"learnset":{"address":3311620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":159},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[33,75],"address":3300608,"base_stats":[35,40,100,35,90,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":139}],"friendship":70,"id":138,"learnset":{"address":3311646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":43,"move_id":321},{"level":49,"move_id":246},{"level":55,"move_id":56}]},"tmhm_learnset":"03903E5084133264","types":[5,11]},{"abilities":[33,75],"address":3300636,"base_stats":[70,60,125,55,115,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":139,"learnset":{"address":3311672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":1,"move_id":44},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":40,"move_id":131},{"level":46,"move_id":321},{"level":55,"move_id":246},{"level":65,"move_id":56}]},"tmhm_learnset":"03903E5084137264","types":[5,11]},{"abilities":[33,4],"address":3300664,"base_stats":[30,80,90,55,55,45],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":141}],"friendship":70,"id":140,"learnset":{"address":3311700,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":43,"move_id":319},{"level":49,"move_id":72},{"level":55,"move_id":246}]},"tmhm_learnset":"01903ED08C173264","types":[5,11]},{"abilities":[33,4],"address":3300692,"base_stats":[60,115,105,80,65,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":141,"learnset":{"address":3311726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":71},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":40,"move_id":163},{"level":46,"move_id":319},{"level":55,"move_id":72},{"level":65,"move_id":246}]},"tmhm_learnset":"03943ED0CC177264","types":[5,11]},{"abilities":[69,46],"address":3300720,"base_stats":[80,105,65,130,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":142,"learnset":{"address":3311754,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":8,"move_id":97},{"level":15,"move_id":44},{"level":22,"move_id":48},{"level":29,"move_id":246},{"level":36,"move_id":184},{"level":43,"move_id":36},{"level":50,"move_id":63}]},"tmhm_learnset":"00A87FF486534E32","types":[5,2]},{"abilities":[17,47],"address":3300748,"base_stats":[160,110,65,30,65,110],"catch_rate":25,"evolutions":[],"friendship":70,"id":143,"learnset":{"address":3311778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":133},{"level":10,"move_id":111},{"level":15,"move_id":187},{"level":19,"move_id":29},{"level":24,"move_id":281},{"level":28,"move_id":156},{"level":28,"move_id":173},{"level":33,"move_id":34},{"level":37,"move_id":335},{"level":42,"move_id":343},{"level":46,"move_id":205},{"level":51,"move_id":63}]},"tmhm_learnset":"00301E76F7B37625","types":[0,0]},{"abilities":[46,0],"address":3300776,"base_stats":[90,85,100,85,95,125],"catch_rate":3,"evolutions":[],"friendship":35,"id":144,"learnset":{"address":3311812,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":181},{"level":13,"move_id":54},{"level":25,"move_id":97},{"level":37,"move_id":170},{"level":49,"move_id":58},{"level":61,"move_id":115},{"level":73,"move_id":59},{"level":85,"move_id":329}]},"tmhm_learnset":"00884E9184137674","types":[15,2]},{"abilities":[46,0],"address":3300804,"base_stats":[90,90,85,100,125,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":145,"learnset":{"address":3311836,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":84},{"level":13,"move_id":86},{"level":25,"move_id":97},{"level":37,"move_id":197},{"level":49,"move_id":65},{"level":61,"move_id":268},{"level":73,"move_id":113},{"level":85,"move_id":87}]},"tmhm_learnset":"00C84E928593C630","types":[13,2]},{"abilities":[46,0],"address":3300832,"base_stats":[90,100,90,90,125,85],"catch_rate":3,"evolutions":[],"friendship":35,"id":146,"learnset":{"address":3311860,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":1,"move_id":52},{"level":13,"move_id":83},{"level":25,"move_id":97},{"level":37,"move_id":203},{"level":49,"move_id":53},{"level":61,"move_id":219},{"level":73,"move_id":257},{"level":85,"move_id":143}]},"tmhm_learnset":"008A4EB4841B4630","types":[10,2]},{"abilities":[61,0],"address":3300860,"base_stats":[41,64,45,50,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":148}],"friendship":35,"id":147,"learnset":{"address":3311884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":36,"move_id":97},{"level":43,"move_id":219},{"level":50,"move_id":200},{"level":57,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[61,0],"address":3300888,"base_stats":[61,84,65,70,70,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":149}],"friendship":35,"id":148,"learnset":{"address":3311910,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":56,"move_id":200},{"level":65,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[39,0],"address":3300916,"base_stats":[91,134,95,80,100,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":149,"learnset":{"address":3311936,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":55,"move_id":17},{"level":61,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BC5EF6C7DB7677","types":[16,2]},{"abilities":[46,0],"address":3300944,"base_stats":[106,110,90,130,154,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":150,"learnset":{"address":3311964,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":50},{"level":11,"move_id":112},{"level":22,"move_id":129},{"level":33,"move_id":244},{"level":44,"move_id":248},{"level":55,"move_id":54},{"level":66,"move_id":94},{"level":77,"move_id":133},{"level":88,"move_id":105},{"level":99,"move_id":219}]},"tmhm_learnset":"00E18FF7F7FBFEED","types":[14,14]},{"abilities":[28,0],"address":3300972,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":151,"learnset":{"address":3311992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":10,"move_id":144},{"level":20,"move_id":5},{"level":30,"move_id":118},{"level":40,"move_id":94},{"level":50,"move_id":246}]},"tmhm_learnset":"03FFFFFFFFFFFFFF","types":[14,14]},{"abilities":[65,0],"address":3301000,"base_stats":[45,49,65,45,49,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":153}],"friendship":70,"id":152,"learnset":{"address":3312012,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":22,"move_id":235},{"level":29,"move_id":34},{"level":36,"move_id":113},{"level":43,"move_id":219},{"level":50,"move_id":76}]},"tmhm_learnset":"00441E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301028,"base_stats":[60,62,80,60,63,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":154}],"friendship":70,"id":153,"learnset":{"address":3312038,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":39,"move_id":113},{"level":47,"move_id":219},{"level":55,"move_id":76}]},"tmhm_learnset":"00E41E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301056,"base_stats":[80,82,100,80,83,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":154,"learnset":{"address":3312064,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":41,"move_id":113},{"level":51,"move_id":219},{"level":61,"move_id":76}]},"tmhm_learnset":"00E41E01867DC720","types":[12,12]},{"abilities":[66,0],"address":3301084,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":14,"species":156}],"friendship":70,"id":155,"learnset":{"address":3312090,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":19,"move_id":98},{"level":27,"move_id":172},{"level":36,"move_id":129},{"level":46,"move_id":53}]},"tmhm_learnset":"00061EA48C110620","types":[10,10]},{"abilities":[66,0],"address":3301112,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":157}],"friendship":70,"id":156,"learnset":{"address":3312112,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":42,"move_id":129},{"level":54,"move_id":53}]},"tmhm_learnset":"00A61EA4CC110631","types":[10,10]},{"abilities":[66,0],"address":3301140,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":157,"learnset":{"address":3312134,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":1,"move_id":52},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":45,"move_id":129},{"level":60,"move_id":53}]},"tmhm_learnset":"00A61EA4CE114631","types":[10,10]},{"abilities":[67,0],"address":3301168,"base_stats":[50,65,64,43,44,48],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":18,"species":159}],"friendship":70,"id":158,"learnset":{"address":3312156,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":20,"move_id":44},{"level":27,"move_id":184},{"level":35,"move_id":163},{"level":43,"move_id":103},{"level":52,"move_id":56}]},"tmhm_learnset":"03141E80CC533265","types":[11,11]},{"abilities":[67,0],"address":3301196,"base_stats":[65,80,80,58,59,63],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":160}],"friendship":70,"id":159,"learnset":{"address":3312180,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":37,"move_id":163},{"level":45,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03B41E80CC533275","types":[11,11]},{"abilities":[67,0],"address":3301224,"base_stats":[85,105,100,78,79,83],"catch_rate":45,"evolutions":[],"friendship":70,"id":160,"learnset":{"address":3312204,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":1,"move_id":55},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":38,"move_id":163},{"level":47,"move_id":103},{"level":58,"move_id":56}]},"tmhm_learnset":"03B41E80CE537277","types":[11,11]},{"abilities":[50,51],"address":3301252,"base_stats":[35,46,34,20,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":15,"species":162}],"friendship":70,"id":161,"learnset":{"address":3312228,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":17,"move_id":270},{"level":24,"move_id":21},{"level":31,"move_id":266},{"level":40,"move_id":156},{"level":49,"move_id":133}]},"tmhm_learnset":"00143E06ECF31625","types":[0,0]},{"abilities":[50,51],"address":3301280,"base_stats":[85,76,64,90,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":162,"learnset":{"address":3312254,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":98},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":19,"move_id":270},{"level":28,"move_id":21},{"level":37,"move_id":266},{"level":48,"move_id":156},{"level":59,"move_id":133}]},"tmhm_learnset":"00B43E06EDF37625","types":[0,0]},{"abilities":[15,51],"address":3301308,"base_stats":[60,30,30,50,36,56],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":164}],"friendship":70,"id":163,"learnset":{"address":3312280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":22,"move_id":115},{"level":28,"move_id":36},{"level":34,"move_id":93},{"level":48,"move_id":138}]},"tmhm_learnset":"00487E81B4130620","types":[0,2]},{"abilities":[15,51],"address":3301336,"base_stats":[100,50,50,70,76,96],"catch_rate":90,"evolutions":[],"friendship":70,"id":164,"learnset":{"address":3312304,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":193},{"level":1,"move_id":64},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":25,"move_id":115},{"level":33,"move_id":36},{"level":41,"move_id":93},{"level":57,"move_id":138}]},"tmhm_learnset":"00487E81B4134620","types":[0,2]},{"abilities":[68,48],"address":3301364,"base_stats":[40,20,30,55,40,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":166}],"friendship":70,"id":165,"learnset":{"address":3312328,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":22,"move_id":113},{"level":22,"move_id":115},{"level":22,"move_id":219},{"level":29,"move_id":226},{"level":36,"move_id":129},{"level":43,"move_id":97},{"level":50,"move_id":38}]},"tmhm_learnset":"00403E81CC3D8621","types":[6,2]},{"abilities":[68,48],"address":3301392,"base_stats":[55,35,50,85,55,110],"catch_rate":90,"evolutions":[],"friendship":70,"id":166,"learnset":{"address":3312356,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":48},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":24,"move_id":113},{"level":24,"move_id":115},{"level":24,"move_id":219},{"level":33,"move_id":226},{"level":42,"move_id":129},{"level":51,"move_id":97},{"level":60,"move_id":38}]},"tmhm_learnset":"00403E81CC3DC621","types":[6,2]},{"abilities":[68,15],"address":3301420,"base_stats":[40,60,40,30,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":168}],"friendship":70,"id":167,"learnset":{"address":3312384,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":23,"move_id":141},{"level":30,"move_id":154},{"level":37,"move_id":169},{"level":45,"move_id":97},{"level":53,"move_id":94}]},"tmhm_learnset":"00403E089C350620","types":[6,3]},{"abilities":[68,15],"address":3301448,"base_stats":[70,90,70,40,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":168,"learnset":{"address":3312410,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":1,"move_id":184},{"level":1,"move_id":132},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":25,"move_id":141},{"level":34,"move_id":154},{"level":43,"move_id":169},{"level":53,"move_id":97},{"level":63,"move_id":94}]},"tmhm_learnset":"00403E089C354620","types":[6,3]},{"abilities":[39,0],"address":3301476,"base_stats":[85,90,80,130,70,80],"catch_rate":90,"evolutions":[],"friendship":70,"id":169,"learnset":{"address":3312436,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00097F88A4174E20","types":[3,2]},{"abilities":[10,35],"address":3301504,"base_stats":[75,38,38,67,56,56],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":27,"species":171}],"friendship":70,"id":170,"learnset":{"address":3312464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":29,"move_id":109},{"level":37,"move_id":36},{"level":41,"move_id":56},{"level":49,"move_id":268}]},"tmhm_learnset":"03501E0285933264","types":[11,13]},{"abilities":[10,35],"address":3301532,"base_stats":[125,58,58,67,76,76],"catch_rate":75,"evolutions":[],"friendship":70,"id":171,"learnset":{"address":3312490,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":1,"move_id":48},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":32,"move_id":109},{"level":43,"move_id":36},{"level":50,"move_id":56},{"level":61,"move_id":268}]},"tmhm_learnset":"03501E0285937264","types":[11,13]},{"abilities":[9,0],"address":3301560,"base_stats":[20,40,15,60,35,35],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":25}],"friendship":70,"id":172,"learnset":{"address":3312516,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":204},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":186}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[56,0],"address":3301588,"base_stats":[50,25,28,15,45,55],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":35}],"friendship":140,"id":173,"learnset":{"address":3312532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":204},{"level":4,"move_id":227},{"level":8,"move_id":47},{"level":13,"move_id":186}]},"tmhm_learnset":"00401E27BC7B8624","types":[0,0]},{"abilities":[56,0],"address":3301616,"base_stats":[90,30,15,15,40,20],"catch_rate":170,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":39}],"friendship":70,"id":174,"learnset":{"address":3312548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":1,"move_id":204},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":186}]},"tmhm_learnset":"00401E27BC3B8624","types":[0,0]},{"abilities":[55,32],"address":3301644,"base_stats":[35,20,65,20,40,65],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":176}],"friendship":70,"id":175,"learnset":{"address":3312564,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C01E27B43B8624","types":[0,0]},{"abilities":[55,32],"address":3301672,"base_stats":[55,40,85,40,80,105],"catch_rate":75,"evolutions":[],"friendship":70,"id":176,"learnset":{"address":3312590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C85EA7F43BC625","types":[0,2]},{"abilities":[28,48],"address":3301700,"base_stats":[40,50,45,70,70,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":178}],"friendship":70,"id":177,"learnset":{"address":3312616,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":30,"move_id":273},{"level":30,"move_id":248},{"level":40,"move_id":109},{"level":50,"move_id":94}]},"tmhm_learnset":"0040FE81B4378628","types":[14,2]},{"abilities":[28,48],"address":3301728,"base_stats":[65,75,70,95,95,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":178,"learnset":{"address":3312638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":35,"move_id":273},{"level":35,"move_id":248},{"level":50,"move_id":109},{"level":65,"move_id":94}]},"tmhm_learnset":"0048FE81B437C628","types":[14,2]},{"abilities":[9,0],"address":3301756,"base_stats":[55,40,40,35,65,45],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":15,"species":180}],"friendship":70,"id":179,"learnset":{"address":3312660,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":84},{"level":16,"move_id":86},{"level":23,"move_id":178},{"level":30,"move_id":113},{"level":37,"move_id":87}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[9,0],"address":3301784,"base_stats":[70,55,55,45,80,60],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":181}],"friendship":70,"id":180,"learnset":{"address":3312680,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":36,"move_id":113},{"level":45,"move_id":87}]},"tmhm_learnset":"00E01E02C5D38221","types":[13,13]},{"abilities":[9,0],"address":3301812,"base_stats":[90,75,75,55,115,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":181,"learnset":{"address":3312700,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":1,"move_id":86},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":30,"move_id":9},{"level":42,"move_id":113},{"level":57,"move_id":87}]},"tmhm_learnset":"00E01E02C5D3C221","types":[13,13]},{"abilities":[34,0],"address":3301840,"base_stats":[75,80,85,50,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":182,"learnset":{"address":3312722,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":78},{"level":1,"move_id":345},{"level":44,"move_id":80},{"level":55,"move_id":76}]},"tmhm_learnset":"00441E08843D4720","types":[12,12]},{"abilities":[47,37],"address":3301868,"base_stats":[70,20,50,40,20,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":18,"species":184}],"friendship":70,"id":183,"learnset":{"address":3312736,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":21,"move_id":61},{"level":28,"move_id":38},{"level":36,"move_id":240},{"level":45,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[47,37],"address":3301896,"base_stats":[100,50,80,50,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":184,"learnset":{"address":3312762,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":39},{"level":1,"move_id":55},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":24,"move_id":61},{"level":34,"move_id":38},{"level":45,"move_id":240},{"level":57,"move_id":56}]},"tmhm_learnset":"03B01E00CC537265","types":[11,11]},{"abilities":[5,69],"address":3301924,"base_stats":[70,100,115,30,30,65],"catch_rate":65,"evolutions":[],"friendship":70,"id":185,"learnset":{"address":3312788,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":102},{"level":9,"move_id":175},{"level":17,"move_id":67},{"level":25,"move_id":157},{"level":33,"move_id":335},{"level":41,"move_id":185},{"level":49,"move_id":21},{"level":57,"move_id":38}]},"tmhm_learnset":"00A03E50CE110E29","types":[5,5]},{"abilities":[11,6],"address":3301952,"base_stats":[90,75,75,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":186,"learnset":{"address":3312812,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":195},{"level":35,"move_id":195},{"level":51,"move_id":207}]},"tmhm_learnset":"03B03E00DE137265","types":[11,11]},{"abilities":[34,0],"address":3301980,"base_stats":[35,35,40,50,35,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":188}],"friendship":70,"id":187,"learnset":{"address":3312826,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":20,"move_id":73},{"level":25,"move_id":178},{"level":30,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302008,"base_stats":[55,45,50,80,45,65],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":27,"species":189}],"friendship":70,"id":188,"learnset":{"address":3312854,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":29,"move_id":178},{"level":36,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302036,"base_stats":[75,55,70,110,55,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":189,"learnset":{"address":3312882,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":33,"move_id":178},{"level":44,"move_id":72}]},"tmhm_learnset":"00401E8084354720","types":[12,2]},{"abilities":[50,53],"address":3302064,"base_stats":[55,70,55,85,40,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":190,"learnset":{"address":3312910,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":6,"move_id":28},{"level":13,"move_id":310},{"level":18,"move_id":226},{"level":25,"move_id":321},{"level":31,"move_id":154},{"level":38,"move_id":129},{"level":43,"move_id":103},{"level":50,"move_id":97}]},"tmhm_learnset":"00A53E82EDF30E25","types":[0,0]},{"abilities":[34,0],"address":3302092,"base_stats":[30,30,30,30,30,30],"catch_rate":235,"evolutions":[{"method":"ITEM","param":93,"species":192}],"friendship":70,"id":191,"learnset":{"address":3312936,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":6,"move_id":74},{"level":13,"move_id":72},{"level":18,"move_id":275},{"level":25,"move_id":283},{"level":30,"move_id":241},{"level":37,"move_id":235},{"level":42,"move_id":202}]},"tmhm_learnset":"00441E08843D8720","types":[12,12]},{"abilities":[34,0],"address":3302120,"base_stats":[75,75,55,30,105,85],"catch_rate":120,"evolutions":[],"friendship":70,"id":192,"learnset":{"address":3312960,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":1},{"level":6,"move_id":74},{"level":13,"move_id":75},{"level":18,"move_id":275},{"level":25,"move_id":331},{"level":30,"move_id":241},{"level":37,"move_id":80},{"level":42,"move_id":76}]},"tmhm_learnset":"00441E08843DC720","types":[12,12]},{"abilities":[3,14],"address":3302148,"base_stats":[65,65,45,95,75,45],"catch_rate":75,"evolutions":[],"friendship":70,"id":193,"learnset":{"address":3312984,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":193},{"level":7,"move_id":98},{"level":13,"move_id":104},{"level":19,"move_id":49},{"level":25,"move_id":197},{"level":31,"move_id":48},{"level":37,"move_id":253},{"level":43,"move_id":17},{"level":49,"move_id":103}]},"tmhm_learnset":"00407E80B4350620","types":[6,2]},{"abilities":[6,11],"address":3302176,"base_stats":[55,45,45,15,25,25],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":195}],"friendship":70,"id":194,"learnset":{"address":3313010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":21,"move_id":133},{"level":31,"move_id":281},{"level":36,"move_id":89},{"level":41,"move_id":240},{"level":51,"move_id":54},{"level":51,"move_id":114}]},"tmhm_learnset":"03D01E188E533264","types":[11,4]},{"abilities":[6,11],"address":3302204,"base_stats":[95,85,85,35,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":195,"learnset":{"address":3313036,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":23,"move_id":133},{"level":35,"move_id":281},{"level":42,"move_id":89},{"level":49,"move_id":240},{"level":61,"move_id":54},{"level":61,"move_id":114}]},"tmhm_learnset":"03F01E58CE537265","types":[11,4]},{"abilities":[28,0],"address":3302232,"base_stats":[65,65,60,110,130,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":196,"learnset":{"address":3313062,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":93},{"level":23,"move_id":98},{"level":30,"move_id":129},{"level":36,"move_id":60},{"level":42,"move_id":244},{"level":47,"move_id":94},{"level":52,"move_id":234}]},"tmhm_learnset":"00449E01BC53C628","types":[14,14]},{"abilities":[28,0],"address":3302260,"base_stats":[95,65,110,65,60,130],"catch_rate":45,"evolutions":[],"friendship":35,"id":197,"learnset":{"address":3313088,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":228},{"level":23,"move_id":98},{"level":30,"move_id":109},{"level":36,"move_id":185},{"level":42,"move_id":212},{"level":47,"move_id":103},{"level":52,"move_id":236}]},"tmhm_learnset":"00451F00BC534E20","types":[17,17]},{"abilities":[15,0],"address":3302288,"base_stats":[60,85,42,91,85,42],"catch_rate":30,"evolutions":[],"friendship":35,"id":198,"learnset":{"address":3313114,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":9,"move_id":310},{"level":14,"move_id":228},{"level":22,"move_id":114},{"level":27,"move_id":101},{"level":35,"move_id":185},{"level":40,"move_id":269},{"level":48,"move_id":212}]},"tmhm_learnset":"00097F80A4130E28","types":[17,2]},{"abilities":[12,20],"address":3302316,"base_stats":[95,75,80,30,100,110],"catch_rate":70,"evolutions":[],"friendship":70,"id":199,"learnset":{"address":3313138,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":207},{"level":48,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[26,0],"address":3302344,"base_stats":[60,60,60,85,85,85],"catch_rate":45,"evolutions":[],"friendship":35,"id":200,"learnset":{"address":3313162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":149},{"level":6,"move_id":180},{"level":11,"move_id":310},{"level":17,"move_id":109},{"level":23,"move_id":212},{"level":30,"move_id":60},{"level":37,"move_id":220},{"level":45,"move_id":195},{"level":53,"move_id":288}]},"tmhm_learnset":"0041BF82B5930E28","types":[7,7]},{"abilities":[26,0],"address":3302372,"base_stats":[48,72,48,48,72,48],"catch_rate":225,"evolutions":[],"friendship":70,"id":201,"learnset":{"address":3313188,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":237}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[23,0],"address":3302400,"base_stats":[190,33,58,33,33,58],"catch_rate":45,"evolutions":[],"friendship":70,"id":202,"learnset":{"address":3313198,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":243},{"level":1,"move_id":219},{"level":1,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[39,48],"address":3302428,"base_stats":[70,80,65,85,90,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":203,"learnset":{"address":3313208,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":7,"move_id":310},{"level":13,"move_id":93},{"level":19,"move_id":23},{"level":25,"move_id":316},{"level":31,"move_id":97},{"level":37,"move_id":226},{"level":43,"move_id":60},{"level":49,"move_id":242}]},"tmhm_learnset":"00E0BE03B7D38628","types":[0,14]},{"abilities":[5,0],"address":3302456,"base_stats":[50,65,90,15,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":205}],"friendship":70,"id":204,"learnset":{"address":3313234,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":36,"move_id":153},{"level":43,"move_id":191},{"level":50,"move_id":38}]},"tmhm_learnset":"00A01E118E358620","types":[6,6]},{"abilities":[5,0],"address":3302484,"base_stats":[75,90,140,40,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":205,"learnset":{"address":3313258,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":1,"move_id":120},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":39,"move_id":153},{"level":49,"move_id":191},{"level":59,"move_id":38}]},"tmhm_learnset":"00A01E118E35C620","types":[6,8]},{"abilities":[32,50],"address":3302512,"base_stats":[100,70,70,45,65,65],"catch_rate":190,"evolutions":[],"friendship":70,"id":206,"learnset":{"address":3313282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":4,"move_id":111},{"level":11,"move_id":281},{"level":14,"move_id":137},{"level":21,"move_id":180},{"level":24,"move_id":228},{"level":31,"move_id":103},{"level":34,"move_id":36},{"level":41,"move_id":283}]},"tmhm_learnset":"00A03E66AFF3362C","types":[0,0]},{"abilities":[52,8],"address":3302540,"base_stats":[65,75,105,85,35,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":207,"learnset":{"address":3313308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":28},{"level":13,"move_id":106},{"level":20,"move_id":98},{"level":28,"move_id":185},{"level":36,"move_id":163},{"level":44,"move_id":103},{"level":52,"move_id":12}]},"tmhm_learnset":"00A47ED88E530620","types":[4,2]},{"abilities":[69,5],"address":3302568,"base_stats":[75,85,200,30,55,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":208,"learnset":{"address":3313332,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":242},{"level":57,"move_id":38}]},"tmhm_learnset":"00A41F508E514E30","types":[8,4]},{"abilities":[22,50],"address":3302596,"base_stats":[60,80,50,30,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":23,"species":210}],"friendship":70,"id":209,"learnset":{"address":3313360,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":26,"move_id":46},{"level":34,"move_id":99},{"level":43,"move_id":36},{"level":53,"move_id":242}]},"tmhm_learnset":"00A23F2EEFB30EB5","types":[0,0]},{"abilities":[22,22],"address":3302624,"base_stats":[90,120,75,45,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":210,"learnset":{"address":3313386,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":28,"move_id":46},{"level":38,"move_id":99},{"level":49,"move_id":36},{"level":61,"move_id":242}]},"tmhm_learnset":"00A23F6EEFF34EB5","types":[0,0]},{"abilities":[38,33],"address":3302652,"base_stats":[65,95,75,85,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":211,"learnset":{"address":3313412,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":191},{"level":1,"move_id":33},{"level":1,"move_id":40},{"level":10,"move_id":106},{"level":10,"move_id":107},{"level":19,"move_id":55},{"level":28,"move_id":42},{"level":37,"move_id":36},{"level":46,"move_id":56}]},"tmhm_learnset":"03101E0AA4133264","types":[11,3]},{"abilities":[68,0],"address":3302680,"base_stats":[70,130,100,65,55,80],"catch_rate":25,"evolutions":[],"friendship":70,"id":212,"learnset":{"address":3313434,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":232},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00A47E9084134620","types":[6,8]},{"abilities":[5,0],"address":3302708,"base_stats":[20,10,230,5,10,230],"catch_rate":190,"evolutions":[],"friendship":70,"id":213,"learnset":{"address":3313462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":9,"move_id":35},{"level":14,"move_id":227},{"level":23,"move_id":219},{"level":28,"move_id":117},{"level":37,"move_id":156}]},"tmhm_learnset":"00E01E588E190620","types":[6,5]},{"abilities":[68,62],"address":3302736,"base_stats":[80,125,75,85,40,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":214,"learnset":{"address":3313482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":30},{"level":11,"move_id":203},{"level":17,"move_id":31},{"level":23,"move_id":280},{"level":30,"move_id":68},{"level":37,"move_id":36},{"level":45,"move_id":179},{"level":53,"move_id":224}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,1]},{"abilities":[39,51],"address":3302764,"base_stats":[55,95,55,115,35,75],"catch_rate":60,"evolutions":[],"friendship":35,"id":215,"learnset":{"address":3313508,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":269},{"level":8,"move_id":98},{"level":15,"move_id":103},{"level":22,"move_id":185},{"level":29,"move_id":154},{"level":36,"move_id":97},{"level":43,"move_id":196},{"level":50,"move_id":163},{"level":57,"move_id":251},{"level":64,"move_id":232}]},"tmhm_learnset":"00B53F80EC533E69","types":[17,15]},{"abilities":[53,0],"address":3302792,"base_stats":[60,80,50,40,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":217}],"friendship":70,"id":216,"learnset":{"address":3313536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43F80CE130EB1","types":[0,0]},{"abilities":[62,0],"address":3302820,"base_stats":[90,130,75,55,75,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":217,"learnset":{"address":3313562,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":122},{"level":1,"move_id":154},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43FC0CE134EB1","types":[0,0]},{"abilities":[40,49],"address":3302848,"base_stats":[40,40,40,20,70,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":219}],"friendship":70,"id":218,"learnset":{"address":3313588,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":43,"move_id":157},{"level":50,"move_id":34}]},"tmhm_learnset":"00821E2584118620","types":[10,10]},{"abilities":[40,49],"address":3302876,"base_stats":[50,50,120,30,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":219,"learnset":{"address":3313612,"moves":[{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":1,"move_id":52},{"level":1,"move_id":88},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":48,"move_id":157},{"level":60,"move_id":34}]},"tmhm_learnset":"00A21E758611C620","types":[10,5]},{"abilities":[12,0],"address":3302904,"base_stats":[50,50,40,50,30,30],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":221}],"friendship":70,"id":220,"learnset":{"address":3313636,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":316},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":37,"move_id":54},{"level":46,"move_id":59},{"level":55,"move_id":133}]},"tmhm_learnset":"00A01E518E13B270","types":[15,4]},{"abilities":[12,0],"address":3302932,"base_stats":[100,100,80,50,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":221,"learnset":{"address":3313658,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":316},{"level":1,"move_id":181},{"level":1,"move_id":203},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":33,"move_id":31},{"level":42,"move_id":54},{"level":56,"move_id":59},{"level":70,"move_id":133}]},"tmhm_learnset":"00A01E518E13F270","types":[15,4]},{"abilities":[55,30],"address":3302960,"base_stats":[55,55,85,35,65,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":222,"learnset":{"address":3313682,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":106},{"level":12,"move_id":145},{"level":17,"move_id":105},{"level":17,"move_id":287},{"level":23,"move_id":61},{"level":28,"move_id":131},{"level":34,"move_id":350},{"level":39,"move_id":243},{"level":45,"move_id":246}]},"tmhm_learnset":"00B01E51BE1BB66C","types":[11,5]},{"abilities":[55,0],"address":3302988,"base_stats":[35,65,35,65,65,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":224}],"friendship":70,"id":223,"learnset":{"address":3313710,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":199},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":33,"move_id":116},{"level":44,"move_id":58},{"level":55,"move_id":63}]},"tmhm_learnset":"03103E2494137624","types":[11,11]},{"abilities":[21,0],"address":3303016,"base_stats":[75,105,75,45,105,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":224,"learnset":{"address":3313734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":132},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":25,"move_id":190},{"level":38,"move_id":116},{"level":54,"move_id":58},{"level":70,"move_id":63}]},"tmhm_learnset":"03103E2C94137724","types":[11,11]},{"abilities":[72,55],"address":3303044,"base_stats":[45,55,45,75,65,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":225,"learnset":{"address":3313760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":217}]},"tmhm_learnset":"00083E8084133265","types":[15,2]},{"abilities":[33,11],"address":3303072,"base_stats":[65,40,70,70,80,140],"catch_rate":25,"evolutions":[],"friendship":70,"id":226,"learnset":{"address":3313770,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":145},{"level":8,"move_id":48},{"level":15,"move_id":61},{"level":22,"move_id":36},{"level":29,"move_id":97},{"level":36,"move_id":17},{"level":43,"move_id":352},{"level":50,"move_id":109}]},"tmhm_learnset":"03101E8086133264","types":[11,2]},{"abilities":[51,5],"address":3303100,"base_stats":[65,80,140,70,40,70],"catch_rate":25,"evolutions":[],"friendship":70,"id":227,"learnset":{"address":3313794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":10,"move_id":28},{"level":13,"move_id":129},{"level":16,"move_id":97},{"level":26,"move_id":31},{"level":29,"move_id":314},{"level":32,"move_id":211},{"level":42,"move_id":191},{"level":45,"move_id":319}]},"tmhm_learnset":"008C7F9084110E30","types":[8,2]},{"abilities":[48,18],"address":3303128,"base_stats":[45,60,30,65,80,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":24,"species":229}],"friendship":35,"id":228,"learnset":{"address":3313820,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":25,"move_id":44},{"level":31,"move_id":316},{"level":37,"move_id":185},{"level":43,"move_id":53},{"level":49,"move_id":242}]},"tmhm_learnset":"00833F2CA4710E30","types":[17,10]},{"abilities":[48,18],"address":3303156,"base_stats":[75,90,50,95,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":229,"learnset":{"address":3313846,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":1,"move_id":336},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":27,"move_id":44},{"level":35,"move_id":316},{"level":43,"move_id":185},{"level":51,"move_id":53},{"level":59,"move_id":242}]},"tmhm_learnset":"00A33F2CA4714E30","types":[17,10]},{"abilities":[33,0],"address":3303184,"base_stats":[75,95,95,85,95,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":230,"learnset":{"address":3313872,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,16]},{"abilities":[53,0],"address":3303212,"base_stats":[90,60,60,40,40,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":25,"species":232}],"friendship":70,"id":231,"learnset":{"address":3313896,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":36},{"level":33,"move_id":205},{"level":41,"move_id":203},{"level":49,"move_id":38}]},"tmhm_learnset":"00A01E5086510630","types":[4,4]},{"abilities":[5,0],"address":3303240,"base_stats":[90,120,120,50,60,60],"catch_rate":60,"evolutions":[],"friendship":70,"id":232,"learnset":{"address":3313918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":30},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":31},{"level":33,"move_id":205},{"level":41,"move_id":229},{"level":49,"move_id":89}]},"tmhm_learnset":"00A01E5086514630","types":[4,4]},{"abilities":[36,0],"address":3303268,"base_stats":[85,80,90,60,105,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":233,"learnset":{"address":3313940,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":111},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[22,0],"address":3303296,"base_stats":[73,95,62,85,85,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":234,"learnset":{"address":3313966,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":43},{"level":13,"move_id":310},{"level":19,"move_id":95},{"level":25,"move_id":23},{"level":31,"move_id":28},{"level":37,"move_id":36},{"level":43,"move_id":109},{"level":49,"move_id":347}]},"tmhm_learnset":"0040BE03B7F38638","types":[0,0]},{"abilities":[20,0],"address":3303324,"base_stats":[55,20,35,75,20,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":235,"learnset":{"address":3313992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":166},{"level":11,"move_id":166},{"level":21,"move_id":166},{"level":31,"move_id":166},{"level":41,"move_id":166},{"level":51,"move_id":166},{"level":61,"move_id":166},{"level":71,"move_id":166},{"level":81,"move_id":166},{"level":91,"move_id":166}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[62,0],"address":3303352,"base_stats":[35,35,35,35,35,35],"catch_rate":75,"evolutions":[{"method":"LEVEL_ATK_LT_DEF","param":20,"species":107},{"method":"LEVEL_ATK_GT_DEF","param":20,"species":106},{"method":"LEVEL_ATK_EQ_DEF","param":20,"species":237}],"friendship":70,"id":236,"learnset":{"address":3314020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"00A03E00C61306A0","types":[1,1]},{"abilities":[22,0],"address":3303380,"base_stats":[50,95,95,70,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":237,"learnset":{"address":3314030,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":27},{"level":7,"move_id":116},{"level":13,"move_id":228},{"level":19,"move_id":98},{"level":20,"move_id":167},{"level":25,"move_id":229},{"level":31,"move_id":68},{"level":37,"move_id":97},{"level":43,"move_id":197},{"level":49,"move_id":283}]},"tmhm_learnset":"00A03E10CE1306A0","types":[1,1]},{"abilities":[12,0],"address":3303408,"base_stats":[45,30,15,65,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":124}],"friendship":70,"id":238,"learnset":{"address":3314058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":9,"move_id":186},{"level":13,"move_id":181},{"level":21,"move_id":93},{"level":25,"move_id":47},{"level":33,"move_id":212},{"level":37,"move_id":313},{"level":45,"move_id":94},{"level":49,"move_id":195},{"level":57,"move_id":59}]},"tmhm_learnset":"0040BE01B413B26C","types":[15,14]},{"abilities":[9,0],"address":3303436,"base_stats":[45,63,37,95,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":125}],"friendship":70,"id":239,"learnset":{"address":3314086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":33,"move_id":103},{"level":41,"move_id":85},{"level":49,"move_id":87}]},"tmhm_learnset":"00C03E02D5938221","types":[13,13]},{"abilities":[49,0],"address":3303464,"base_stats":[45,75,37,83,70,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":126}],"friendship":70,"id":240,"learnset":{"address":3314108,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":31,"move_id":241},{"level":37,"move_id":53},{"level":43,"move_id":109},{"level":49,"move_id":126}]},"tmhm_learnset":"00803E24D4510621","types":[10,10]},{"abilities":[47,0],"address":3303492,"base_stats":[95,80,105,100,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":241,"learnset":{"address":3314134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":8,"move_id":111},{"level":13,"move_id":23},{"level":19,"move_id":208},{"level":26,"move_id":117},{"level":34,"move_id":205},{"level":43,"move_id":34},{"level":53,"move_id":215}]},"tmhm_learnset":"00B01E52E7F37625","types":[0,0]},{"abilities":[30,32],"address":3303520,"base_stats":[255,10,10,55,75,135],"catch_rate":30,"evolutions":[],"friendship":140,"id":242,"learnset":{"address":3314160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":4,"move_id":39},{"level":7,"move_id":287},{"level":10,"move_id":135},{"level":13,"move_id":3},{"level":18,"move_id":107},{"level":23,"move_id":47},{"level":28,"move_id":121},{"level":33,"move_id":111},{"level":40,"move_id":113},{"level":47,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[46,0],"address":3303548,"base_stats":[90,85,75,115,115,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":243,"learnset":{"address":3314190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":84},{"level":21,"move_id":46},{"level":31,"move_id":98},{"level":41,"move_id":209},{"level":51,"move_id":115},{"level":61,"move_id":242},{"level":71,"move_id":87},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E138DD34638","types":[13,13]},{"abilities":[46,0],"address":3303576,"base_stats":[115,115,85,100,90,75],"catch_rate":3,"evolutions":[],"friendship":35,"id":244,"learnset":{"address":3314216,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":52},{"level":21,"move_id":46},{"level":31,"move_id":83},{"level":41,"move_id":23},{"level":51,"move_id":53},{"level":61,"move_id":207},{"level":71,"move_id":126},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E358C734638","types":[10,10]},{"abilities":[46,0],"address":3303604,"base_stats":[100,75,115,85,90,115],"catch_rate":3,"evolutions":[],"friendship":35,"id":245,"learnset":{"address":3314242,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":61},{"level":21,"move_id":240},{"level":31,"move_id":16},{"level":41,"move_id":62},{"level":51,"move_id":54},{"level":61,"move_id":243},{"level":71,"move_id":56},{"level":81,"move_id":347}]},"tmhm_learnset":"03940E118C53767C","types":[11,11]},{"abilities":[62,0],"address":3303632,"base_stats":[50,64,50,41,45,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":247}],"friendship":35,"id":246,"learnset":{"address":3314268,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":36,"move_id":184},{"level":43,"move_id":242},{"level":50,"move_id":89},{"level":57,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[61,0],"address":3303660,"base_stats":[70,84,70,51,65,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":248}],"friendship":35,"id":247,"learnset":{"address":3314294,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":56,"move_id":89},{"level":65,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[45,0],"address":3303688,"base_stats":[100,134,110,61,95,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":248,"learnset":{"address":3314320,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":61,"move_id":89},{"level":75,"move_id":63}]},"tmhm_learnset":"00B41FF6CFD37E37","types":[5,17]},{"abilities":[46,0],"address":3303716,"base_stats":[106,90,130,110,90,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":249,"learnset":{"address":3314346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":56},{"level":55,"move_id":240},{"level":66,"move_id":129},{"level":77,"move_id":177},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"03B8CE93B7DFF67C","types":[14,2]},{"abilities":[46,0],"address":3303744,"base_stats":[106,130,90,90,110,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":250,"learnset":{"address":3314374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":126},{"level":55,"move_id":241},{"level":66,"move_id":129},{"level":77,"move_id":221},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"00EA4EB7B7BFC638","types":[10,2]},{"abilities":[30,0],"address":3303772,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":251,"learnset":{"address":3314402,"moves":[{"level":1,"move_id":73},{"level":1,"move_id":93},{"level":1,"move_id":105},{"level":1,"move_id":215},{"level":10,"move_id":219},{"level":20,"move_id":246},{"level":30,"move_id":248},{"level":40,"move_id":226},{"level":50,"move_id":195}]},"tmhm_learnset":"00448E93B43FC62C","types":[14,12]},{"abilities":[0,0],"address":3303800,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":252,"learnset":{"address":3314422,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303828,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":253,"learnset":{"address":3314432,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303856,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":254,"learnset":{"address":3314442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303884,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":255,"learnset":{"address":3314452,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303912,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":256,"learnset":{"address":3314462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303940,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":257,"learnset":{"address":3314472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303968,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":258,"learnset":{"address":3314482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303996,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":259,"learnset":{"address":3314492,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304024,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":260,"learnset":{"address":3314502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304052,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":261,"learnset":{"address":3314512,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304080,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":262,"learnset":{"address":3314522,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304108,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":263,"learnset":{"address":3314532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304136,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":264,"learnset":{"address":3314542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304164,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":265,"learnset":{"address":3314552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304192,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":266,"learnset":{"address":3314562,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304220,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":267,"learnset":{"address":3314572,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304248,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":268,"learnset":{"address":3314582,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304276,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":269,"learnset":{"address":3314592,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304304,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":270,"learnset":{"address":3314602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304332,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":271,"learnset":{"address":3314612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304360,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":272,"learnset":{"address":3314622,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304388,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":273,"learnset":{"address":3314632,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304416,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":274,"learnset":{"address":3314642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304444,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":275,"learnset":{"address":3314652,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304472,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":276,"learnset":{"address":3314662,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3304500,"base_stats":[40,45,35,70,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":278}],"friendship":70,"id":277,"learnset":{"address":3314672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":228},{"level":21,"move_id":103},{"level":26,"move_id":72},{"level":31,"move_id":97},{"level":36,"move_id":21},{"level":41,"move_id":197},{"level":46,"move_id":202}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304528,"base_stats":[50,65,45,95,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":279}],"friendship":70,"id":278,"learnset":{"address":3314700,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":41,"move_id":21},{"level":47,"move_id":197},{"level":53,"move_id":206}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304556,"base_stats":[70,85,65,120,105,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":279,"learnset":{"address":3314730,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":43,"move_id":21},{"level":51,"move_id":197},{"level":59,"move_id":206}]},"tmhm_learnset":"00E41EC0CE7D4733","types":[12,12]},{"abilities":[66,0],"address":3304584,"base_stats":[45,60,40,45,70,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":281}],"friendship":70,"id":280,"learnset":{"address":3314760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":116},{"level":10,"move_id":52},{"level":16,"move_id":64},{"level":19,"move_id":28},{"level":25,"move_id":83},{"level":28,"move_id":98},{"level":34,"move_id":163},{"level":37,"move_id":119},{"level":43,"move_id":53}]},"tmhm_learnset":"00A61EE48C110620","types":[10,10]},{"abilities":[66,0],"address":3304612,"base_stats":[60,85,60,55,85,60],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":282}],"friendship":70,"id":281,"learnset":{"address":3314788,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":39,"move_id":163},{"level":43,"move_id":119},{"level":50,"move_id":327}]},"tmhm_learnset":"00A61EE4CC1106A1","types":[10,1]},{"abilities":[66,0],"address":3304640,"base_stats":[80,120,70,80,110,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":282,"learnset":{"address":3314818,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":36,"move_id":299},{"level":42,"move_id":163},{"level":49,"move_id":119},{"level":59,"move_id":327}]},"tmhm_learnset":"00A61EE4CE1146B1","types":[10,1]},{"abilities":[67,0],"address":3304668,"base_stats":[50,70,50,40,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":284}],"friendship":70,"id":283,"learnset":{"address":3314852,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":19,"move_id":193},{"level":24,"move_id":300},{"level":28,"move_id":36},{"level":33,"move_id":250},{"level":37,"move_id":182},{"level":42,"move_id":56},{"level":46,"move_id":283}]},"tmhm_learnset":"03B01E408C533264","types":[11,11]},{"abilities":[67,0],"address":3304696,"base_stats":[70,85,70,50,60,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":285}],"friendship":70,"id":284,"learnset":{"address":3314882,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":37,"move_id":330},{"level":42,"move_id":182},{"level":46,"move_id":89},{"level":53,"move_id":283}]},"tmhm_learnset":"03B01E408E533264","types":[11,4]},{"abilities":[67,0],"address":3304724,"base_stats":[100,110,90,60,85,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":285,"learnset":{"address":3314914,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":39,"move_id":330},{"level":46,"move_id":182},{"level":52,"move_id":89},{"level":61,"move_id":283}]},"tmhm_learnset":"03B01E40CE537275","types":[11,4]},{"abilities":[50,0],"address":3304752,"base_stats":[35,55,35,35,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":287}],"friendship":70,"id":286,"learnset":{"address":3314946,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":21,"move_id":46},{"level":25,"move_id":207},{"level":29,"move_id":184},{"level":33,"move_id":36},{"level":37,"move_id":269},{"level":41,"move_id":242},{"level":45,"move_id":168}]},"tmhm_learnset":"00813F00AC530E30","types":[17,17]},{"abilities":[22,0],"address":3304780,"base_stats":[70,90,70,70,60,60],"catch_rate":127,"evolutions":[],"friendship":70,"id":287,"learnset":{"address":3314978,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":336},{"level":1,"move_id":28},{"level":1,"move_id":44},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":22,"move_id":46},{"level":27,"move_id":207},{"level":32,"move_id":184},{"level":37,"move_id":36},{"level":42,"move_id":269},{"level":47,"move_id":242},{"level":52,"move_id":168}]},"tmhm_learnset":"00A13F00AC534E30","types":[17,17]},{"abilities":[53,0],"address":3304808,"base_stats":[38,30,41,60,30,41],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":289}],"friendship":70,"id":288,"learnset":{"address":3315010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":21,"move_id":300},{"level":25,"move_id":42},{"level":29,"move_id":343},{"level":33,"move_id":175},{"level":37,"move_id":156},{"level":41,"move_id":187}]},"tmhm_learnset":"00943E02ADD33624","types":[0,0]},{"abilities":[53,0],"address":3304836,"base_stats":[78,70,61,100,50,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":289,"learnset":{"address":3315040,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":23,"move_id":300},{"level":29,"move_id":154},{"level":35,"move_id":343},{"level":41,"move_id":163},{"level":47,"move_id":156},{"level":53,"move_id":187}]},"tmhm_learnset":"00B43E02ADD37634","types":[0,0]},{"abilities":[19,0],"address":3304864,"base_stats":[45,45,35,20,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_SILCOON","param":7,"species":291},{"method":"LEVEL_CASCOON","param":7,"species":293}],"friendship":70,"id":290,"learnset":{"address":3315070,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81},{"level":5,"move_id":40}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3304892,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":292}],"friendship":70,"id":291,"learnset":{"address":3315082,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[68,0],"address":3304920,"base_stats":[60,70,50,65,90,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":292,"learnset":{"address":3315094,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":10,"move_id":71},{"level":13,"move_id":16},{"level":17,"move_id":78},{"level":20,"move_id":234},{"level":24,"move_id":72},{"level":27,"move_id":18},{"level":31,"move_id":213},{"level":34,"move_id":318},{"level":38,"move_id":202}]},"tmhm_learnset":"00403E80B43D4620","types":[6,2]},{"abilities":[61,0],"address":3304948,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":294}],"friendship":70,"id":293,"learnset":{"address":3315122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[19,0],"address":3304976,"base_stats":[60,50,70,65,50,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":294,"learnset":{"address":3315134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":16},{"level":17,"move_id":182},{"level":20,"move_id":236},{"level":24,"move_id":60},{"level":27,"move_id":18},{"level":31,"move_id":113},{"level":34,"move_id":318},{"level":38,"move_id":92}]},"tmhm_learnset":"00403E88B435C620","types":[6,3]},{"abilities":[33,44],"address":3305004,"base_stats":[40,30,30,30,40,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":296}],"friendship":70,"id":295,"learnset":{"address":3315162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":21,"move_id":54},{"level":31,"move_id":240},{"level":43,"move_id":72}]},"tmhm_learnset":"00503E0084373764","types":[11,12]},{"abilities":[33,44],"address":3305032,"base_stats":[60,50,50,50,60,70],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":297}],"friendship":70,"id":296,"learnset":{"address":3315184,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":154},{"level":31,"move_id":346},{"level":37,"move_id":168},{"level":43,"move_id":253},{"level":49,"move_id":56}]},"tmhm_learnset":"03F03E00C4373764","types":[11,12]},{"abilities":[33,44],"address":3305060,"base_stats":[80,70,70,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":297,"learnset":{"address":3315212,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":45},{"level":1,"move_id":71},{"level":1,"move_id":267}]},"tmhm_learnset":"03F03E00C4377765","types":[11,12]},{"abilities":[34,48],"address":3305088,"base_stats":[40,40,50,30,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":299}],"friendship":70,"id":298,"learnset":{"address":3315222,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":21,"move_id":235},{"level":31,"move_id":241},{"level":43,"move_id":153}]},"tmhm_learnset":"00C01E00AC350720","types":[12,12]},{"abilities":[34,48],"address":3305116,"base_stats":[70,70,40,60,60,40],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":300}],"friendship":70,"id":299,"learnset":{"address":3315244,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":259},{"level":31,"move_id":185},{"level":37,"move_id":13},{"level":43,"move_id":207},{"level":49,"move_id":326}]},"tmhm_learnset":"00E43F40EC354720","types":[12,17]},{"abilities":[34,48],"address":3305144,"base_stats":[90,100,60,80,90,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":300,"learnset":{"address":3315272,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":1,"move_id":74},{"level":1,"move_id":267}]},"tmhm_learnset":"00E43FC0EC354720","types":[12,17]},{"abilities":[14,0],"address":3305172,"base_stats":[31,45,90,40,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_NINJASK","param":20,"species":302},{"method":"LEVEL_SHEDINJA","param":20,"species":303}],"friendship":70,"id":301,"learnset":{"address":3315282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":206},{"level":31,"move_id":189},{"level":38,"move_id":232},{"level":45,"move_id":91}]},"tmhm_learnset":"00440E90AC350620","types":[6,4]},{"abilities":[3,0],"address":3305200,"base_stats":[61,90,45,160,50,50],"catch_rate":120,"evolutions":[],"friendship":70,"id":302,"learnset":{"address":3315308,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":141},{"level":1,"move_id":28},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":20,"move_id":104},{"level":20,"move_id":210},{"level":20,"move_id":103},{"level":25,"move_id":14},{"level":31,"move_id":163},{"level":38,"move_id":97},{"level":45,"move_id":226}]},"tmhm_learnset":"00443E90AC354620","types":[6,2]},{"abilities":[25,0],"address":3305228,"base_stats":[1,90,45,40,30,30],"catch_rate":45,"evolutions":[],"friendship":70,"id":303,"learnset":{"address":3315340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":180},{"level":31,"move_id":109},{"level":38,"move_id":247},{"level":45,"move_id":288}]},"tmhm_learnset":"00442E90AC354620","types":[6,7]},{"abilities":[62,0],"address":3305256,"base_stats":[40,55,30,85,30,30],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":305}],"friendship":70,"id":304,"learnset":{"address":3315366,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":26,"move_id":283},{"level":34,"move_id":332},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[62,0],"address":3305284,"base_stats":[60,85,60,125,50,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":305,"learnset":{"address":3315390,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":98},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":28,"move_id":283},{"level":38,"move_id":332},{"level":49,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[27,0],"address":3305312,"base_stats":[60,40,60,35,40,60],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":23,"species":307}],"friendship":70,"id":306,"learnset":{"address":3315414,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":28,"move_id":77},{"level":36,"move_id":74},{"level":45,"move_id":202},{"level":54,"move_id":147}]},"tmhm_learnset":"00411E08843D0720","types":[12,12]},{"abilities":[27,0],"address":3305340,"base_stats":[60,130,80,70,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":307,"learnset":{"address":3315442,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":33},{"level":1,"move_id":78},{"level":1,"move_id":73},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":23,"move_id":183},{"level":28,"move_id":68},{"level":36,"move_id":327},{"level":45,"move_id":170},{"level":54,"move_id":223}]},"tmhm_learnset":"00E51E08C47D47A1","types":[12,1]},{"abilities":[20,0],"address":3305368,"base_stats":[60,60,60,60,60,60],"catch_rate":255,"evolutions":[],"friendship":70,"id":308,"learnset":{"address":3315472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":253},{"level":12,"move_id":185},{"level":16,"move_id":60},{"level":23,"move_id":95},{"level":27,"move_id":146},{"level":34,"move_id":298},{"level":38,"move_id":244},{"level":45,"move_id":38},{"level":49,"move_id":175},{"level":56,"move_id":37}]},"tmhm_learnset":"00E1BE42FC1B062D","types":[0,0]},{"abilities":[51,0],"address":3305396,"base_stats":[40,30,30,85,55,30],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":310}],"friendship":70,"id":309,"learnset":{"address":3315502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":31,"move_id":98},{"level":43,"move_id":228},{"level":55,"move_id":97}]},"tmhm_learnset":"00087E8284133264","types":[11,2]},{"abilities":[51,0],"address":3305424,"base_stats":[60,50,100,65,85,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":310,"learnset":{"address":3315524,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":346},{"level":1,"move_id":17},{"level":3,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":25,"move_id":182},{"level":33,"move_id":254},{"level":33,"move_id":256},{"level":47,"move_id":255},{"level":61,"move_id":56}]},"tmhm_learnset":"00187E8284137264","types":[11,2]},{"abilities":[33,0],"address":3305452,"base_stats":[40,30,32,65,50,52],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":312}],"friendship":70,"id":311,"learnset":{"address":3315552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":25,"move_id":61},{"level":31,"move_id":97},{"level":37,"move_id":54},{"level":37,"move_id":114}]},"tmhm_learnset":"00403E00A4373624","types":[6,11]},{"abilities":[22,0],"address":3305480,"base_stats":[70,60,62,60,80,82],"catch_rate":75,"evolutions":[],"friendship":70,"id":312,"learnset":{"address":3315576,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":98},{"level":1,"move_id":230},{"level":1,"move_id":346},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":26,"move_id":16},{"level":33,"move_id":184},{"level":40,"move_id":78},{"level":47,"move_id":318},{"level":53,"move_id":18}]},"tmhm_learnset":"00403E80A4377624","types":[6,2]},{"abilities":[41,12],"address":3305508,"base_stats":[130,70,35,60,70,35],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":40,"species":314}],"friendship":70,"id":313,"learnset":{"address":3315602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":150},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":41,"move_id":323},{"level":46,"move_id":133},{"level":50,"move_id":56}]},"tmhm_learnset":"03B01E4086133274","types":[11,11]},{"abilities":[41,12],"address":3305536,"base_stats":[170,90,45,60,90,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":314,"learnset":{"address":3315634,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":205},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":44,"move_id":323},{"level":52,"move_id":133},{"level":59,"move_id":56}]},"tmhm_learnset":"03B01E4086137274","types":[11,11]},{"abilities":[56,0],"address":3305564,"base_stats":[50,45,45,50,35,35],"catch_rate":255,"evolutions":[{"method":"ITEM","param":94,"species":316}],"friendship":70,"id":315,"learnset":{"address":3315666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":3,"move_id":39},{"level":7,"move_id":213},{"level":13,"move_id":47},{"level":15,"move_id":3},{"level":19,"move_id":274},{"level":25,"move_id":204},{"level":27,"move_id":185},{"level":31,"move_id":343},{"level":37,"move_id":215},{"level":39,"move_id":38}]},"tmhm_learnset":"00401E02ADFB362C","types":[0,0]},{"abilities":[56,0],"address":3305592,"base_stats":[70,65,65,70,55,55],"catch_rate":60,"evolutions":[],"friendship":70,"id":316,"learnset":{"address":3315696,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":213},{"level":1,"move_id":47},{"level":1,"move_id":3}]},"tmhm_learnset":"00E01E02ADFB762C","types":[0,0]},{"abilities":[16,0],"address":3305620,"base_stats":[60,90,70,40,60,120],"catch_rate":200,"evolutions":[],"friendship":70,"id":317,"learnset":{"address":3315706,"moves":[{"level":1,"move_id":168},{"level":1,"move_id":39},{"level":1,"move_id":310},{"level":1,"move_id":122},{"level":1,"move_id":10},{"level":4,"move_id":20},{"level":7,"move_id":185},{"level":12,"move_id":154},{"level":17,"move_id":60},{"level":24,"move_id":103},{"level":31,"move_id":163},{"level":40,"move_id":164},{"level":49,"move_id":246}]},"tmhm_learnset":"00E5BEE6EDF33625","types":[0,0]},{"abilities":[26,0],"address":3305648,"base_stats":[40,40,55,55,40,70],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":36,"species":319}],"friendship":70,"id":318,"learnset":{"address":3315734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":37,"move_id":322},{"level":45,"move_id":153}]},"tmhm_learnset":"00408E51BE339620","types":[4,14]},{"abilities":[26,0],"address":3305676,"base_stats":[60,70,105,75,70,120],"catch_rate":90,"evolutions":[],"friendship":70,"id":319,"learnset":{"address":3315764,"moves":[{"level":1,"move_id":100},{"level":1,"move_id":93},{"level":1,"move_id":106},{"level":1,"move_id":229},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":36,"move_id":63},{"level":42,"move_id":322},{"level":55,"move_id":153}]},"tmhm_learnset":"00E08E51BE33D620","types":[4,14]},{"abilities":[5,42],"address":3305704,"base_stats":[30,45,135,30,45,90],"catch_rate":255,"evolutions":[],"friendship":70,"id":320,"learnset":{"address":3315796,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":106},{"level":13,"move_id":88},{"level":16,"move_id":335},{"level":22,"move_id":86},{"level":28,"move_id":157},{"level":31,"move_id":201},{"level":37,"move_id":156},{"level":43,"move_id":192},{"level":46,"move_id":199}]},"tmhm_learnset":"00A01F5287910E20","types":[5,5]},{"abilities":[73,0],"address":3305732,"base_stats":[70,85,140,20,85,70],"catch_rate":90,"evolutions":[],"friendship":70,"id":321,"learnset":{"address":3315824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":4,"move_id":123},{"level":7,"move_id":174},{"level":14,"move_id":108},{"level":17,"move_id":83},{"level":20,"move_id":34},{"level":27,"move_id":182},{"level":30,"move_id":53},{"level":33,"move_id":334},{"level":40,"move_id":133},{"level":43,"move_id":175},{"level":46,"move_id":257}]},"tmhm_learnset":"00A21E2C84510620","types":[10,10]},{"abilities":[51,0],"address":3305760,"base_stats":[50,75,75,50,65,65],"catch_rate":45,"evolutions":[],"friendship":35,"id":322,"learnset":{"address":3315856,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":10},{"level":5,"move_id":193},{"level":9,"move_id":101},{"level":13,"move_id":310},{"level":17,"move_id":154},{"level":21,"move_id":252},{"level":25,"move_id":197},{"level":29,"move_id":185},{"level":33,"move_id":282},{"level":37,"move_id":109},{"level":41,"move_id":247},{"level":45,"move_id":212}]},"tmhm_learnset":"00C53FC2FC130E2D","types":[17,7]},{"abilities":[12,0],"address":3305788,"base_stats":[50,48,43,60,46,41],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":324}],"friendship":70,"id":323,"learnset":{"address":3315888,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":189},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":31,"move_id":89},{"level":36,"move_id":248},{"level":41,"move_id":90}]},"tmhm_learnset":"03101E5086133264","types":[11,4]},{"abilities":[12,0],"address":3305816,"base_stats":[110,78,73,60,76,71],"catch_rate":75,"evolutions":[],"friendship":70,"id":324,"learnset":{"address":3315918,"moves":[{"level":1,"move_id":321},{"level":1,"move_id":189},{"level":1,"move_id":300},{"level":1,"move_id":346},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":36,"move_id":89},{"level":46,"move_id":248},{"level":56,"move_id":90}]},"tmhm_learnset":"03B01E5086137264","types":[11,4]},{"abilities":[33,0],"address":3305844,"base_stats":[43,30,55,97,40,65],"catch_rate":225,"evolutions":[],"friendship":70,"id":325,"learnset":{"address":3315948,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":204},{"level":12,"move_id":55},{"level":16,"move_id":97},{"level":24,"move_id":36},{"level":28,"move_id":213},{"level":36,"move_id":186},{"level":40,"move_id":175},{"level":48,"move_id":219}]},"tmhm_learnset":"03101E00841B3264","types":[11,11]},{"abilities":[52,75],"address":3305872,"base_stats":[43,80,65,35,50,35],"catch_rate":205,"evolutions":[{"method":"LEVEL","param":30,"species":327}],"friendship":70,"id":326,"learnset":{"address":3315974,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":32,"move_id":269},{"level":35,"move_id":152},{"level":38,"move_id":14},{"level":44,"move_id":12}]},"tmhm_learnset":"01B41EC8CC133A64","types":[11,11]},{"abilities":[52,75],"address":3305900,"base_stats":[63,120,85,55,90,55],"catch_rate":155,"evolutions":[],"friendship":70,"id":327,"learnset":{"address":3316004,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":106},{"level":1,"move_id":11},{"level":1,"move_id":43},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":34,"move_id":269},{"level":39,"move_id":152},{"level":44,"move_id":14},{"level":52,"move_id":12}]},"tmhm_learnset":"03B41EC8CC137A64","types":[11,17]},{"abilities":[33,0],"address":3305928,"base_stats":[20,15,20,80,10,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":30,"species":329}],"friendship":70,"id":328,"learnset":{"address":3316034,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[63,0],"address":3305956,"base_stats":[95,60,79,81,100,125],"catch_rate":60,"evolutions":[],"friendship":70,"id":329,"learnset":{"address":3316048,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":5,"move_id":35},{"level":10,"move_id":346},{"level":15,"move_id":287},{"level":20,"move_id":352},{"level":25,"move_id":239},{"level":30,"move_id":105},{"level":35,"move_id":240},{"level":40,"move_id":56},{"level":45,"move_id":213},{"level":50,"move_id":219}]},"tmhm_learnset":"03101E00845B7264","types":[11,11]},{"abilities":[24,0],"address":3305984,"base_stats":[45,90,20,65,65,20],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":30,"species":331}],"friendship":35,"id":330,"learnset":{"address":3316078,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":31,"move_id":36},{"level":37,"move_id":207},{"level":43,"move_id":97}]},"tmhm_learnset":"03103F0084133A64","types":[11,17]},{"abilities":[24,0],"address":3306012,"base_stats":[70,120,40,95,95,40],"catch_rate":60,"evolutions":[],"friendship":35,"id":331,"learnset":{"address":3316104,"moves":[{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":1,"move_id":99},{"level":1,"move_id":116},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":33,"move_id":163},{"level":38,"move_id":269},{"level":43,"move_id":207},{"level":48,"move_id":130},{"level":53,"move_id":97}]},"tmhm_learnset":"03B03F4086137A74","types":[11,17]},{"abilities":[52,71],"address":3306040,"base_stats":[45,100,45,10,45,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":333}],"friendship":70,"id":332,"learnset":{"address":3316134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":41,"move_id":91},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A01E508E354620","types":[4,4]},{"abilities":[26,26],"address":3306068,"base_stats":[50,70,50,70,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":45,"species":334}],"friendship":70,"id":333,"learnset":{"address":3316158,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A85E508E354620","types":[4,16]},{"abilities":[26,26],"address":3306096,"base_stats":[80,100,80,100,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":334,"learnset":{"address":3316184,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":53,"move_id":201},{"level":65,"move_id":63}]},"tmhm_learnset":"00A85E748E754622","types":[4,16]},{"abilities":[47,62],"address":3306124,"base_stats":[72,60,30,25,20,30],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":24,"species":336}],"friendship":70,"id":335,"learnset":{"address":3316210,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":28,"move_id":282},{"level":31,"move_id":265},{"level":37,"move_id":187},{"level":40,"move_id":203},{"level":46,"move_id":69},{"level":49,"move_id":179}]},"tmhm_learnset":"00B01E40CE1306A1","types":[1,1]},{"abilities":[47,62],"address":3306152,"base_stats":[144,120,60,50,40,60],"catch_rate":200,"evolutions":[],"friendship":70,"id":336,"learnset":{"address":3316242,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":1,"move_id":28},{"level":1,"move_id":292},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":29,"move_id":282},{"level":33,"move_id":265},{"level":40,"move_id":187},{"level":44,"move_id":203},{"level":51,"move_id":69},{"level":55,"move_id":179}]},"tmhm_learnset":"00B01E40CE1346A1","types":[1,1]},{"abilities":[9,31],"address":3306180,"base_stats":[40,45,40,65,65,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":26,"species":338}],"friendship":70,"id":337,"learnset":{"address":3316274,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":28,"move_id":46},{"level":33,"move_id":44},{"level":36,"move_id":87},{"level":41,"move_id":268}]},"tmhm_learnset":"00603E0285D30230","types":[13,13]},{"abilities":[9,31],"address":3306208,"base_stats":[70,75,60,105,105,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":338,"learnset":{"address":3316304,"moves":[{"level":1,"move_id":86},{"level":1,"move_id":43},{"level":1,"move_id":336},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":31,"move_id":46},{"level":39,"move_id":44},{"level":45,"move_id":87},{"level":53,"move_id":268}]},"tmhm_learnset":"00603E0285D34230","types":[13,13]},{"abilities":[12,0],"address":3306236,"base_stats":[60,60,40,35,65,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":33,"species":340}],"friendship":70,"id":339,"learnset":{"address":3316334,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":35,"move_id":89},{"level":41,"move_id":53},{"level":49,"move_id":38}]},"tmhm_learnset":"00A21E748E110620","types":[10,4]},{"abilities":[40,0],"address":3306264,"base_stats":[70,100,70,40,105,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":340,"learnset":{"address":3316360,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":1,"move_id":52},{"level":1,"move_id":222},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":33,"move_id":157},{"level":37,"move_id":89},{"level":45,"move_id":284},{"level":55,"move_id":90}]},"tmhm_learnset":"00A21E748E114630","types":[10,4]},{"abilities":[47,0],"address":3306292,"base_stats":[70,40,50,25,55,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":342}],"friendship":70,"id":341,"learnset":{"address":3316388,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":59},{"level":49,"move_id":329}]},"tmhm_learnset":"03B01E4086533264","types":[15,11]},{"abilities":[47,0],"address":3306320,"base_stats":[90,60,70,45,75,70],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":44,"species":343}],"friendship":70,"id":342,"learnset":{"address":3316416,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":47,"move_id":59},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E4086533274","types":[15,11]},{"abilities":[47,0],"address":3306348,"base_stats":[110,80,90,65,95,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":343,"learnset":{"address":3316444,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":50,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"03B01E4086537274","types":[15,11]},{"abilities":[8,0],"address":3306376,"base_stats":[50,85,40,35,85,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":32,"species":345}],"friendship":35,"id":344,"learnset":{"address":3316472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":33,"move_id":191},{"level":37,"move_id":302},{"level":41,"move_id":178},{"level":45,"move_id":201}]},"tmhm_learnset":"00441E1084350721","types":[12,12]},{"abilities":[8,0],"address":3306404,"base_stats":[70,115,60,55,115,60],"catch_rate":60,"evolutions":[],"friendship":35,"id":345,"learnset":{"address":3316504,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":74},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":35,"move_id":191},{"level":41,"move_id":302},{"level":47,"move_id":178},{"level":53,"move_id":201}]},"tmhm_learnset":"00641E1084354721","types":[12,17]},{"abilities":[39,0],"address":3306432,"base_stats":[50,50,50,50,50,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":42,"species":347}],"friendship":70,"id":346,"learnset":{"address":3316536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":37,"move_id":258},{"level":43,"move_id":59}]},"tmhm_learnset":"00401E00A41BB264","types":[15,15]},{"abilities":[39,0],"address":3306460,"base_stats":[80,80,80,80,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":347,"learnset":{"address":3316564,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":1,"move_id":104},{"level":1,"move_id":44},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":42,"move_id":258},{"level":53,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"00401F00A61BFA64","types":[15,15]},{"abilities":[26,0],"address":3306488,"base_stats":[70,55,65,70,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":348,"learnset":{"address":3316594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":95},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":94},{"level":43,"move_id":248},{"level":49,"move_id":153}]},"tmhm_learnset":"00408E51B61BD228","types":[5,14]},{"abilities":[26,0],"address":3306516,"base_stats":[70,95,85,70,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":349,"learnset":{"address":3316620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":83},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":157},{"level":43,"move_id":76},{"level":49,"move_id":153}]},"tmhm_learnset":"00428E75B639C628","types":[5,14]},{"abilities":[47,37],"address":3306544,"base_stats":[50,20,40,20,20,40],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":183}],"friendship":70,"id":350,"learnset":{"address":3316646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":150},{"level":3,"move_id":204},{"level":6,"move_id":39},{"level":10,"move_id":145},{"level":15,"move_id":21},{"level":21,"move_id":55}]},"tmhm_learnset":"01101E0084533264","types":[0,0]},{"abilities":[47,20],"address":3306572,"base_stats":[60,25,35,60,70,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":352}],"friendship":70,"id":351,"learnset":{"address":3316666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":1,"move_id":150},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":34,"move_id":94},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":340}]},"tmhm_learnset":"0041BF03B4538E28","types":[14,14]},{"abilities":[47,20],"address":3306600,"base_stats":[80,45,65,80,90,110],"catch_rate":60,"evolutions":[],"friendship":70,"id":352,"learnset":{"address":3316696,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":149},{"level":1,"move_id":316},{"level":1,"move_id":60},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":37,"move_id":94},{"level":43,"move_id":156},{"level":43,"move_id":173},{"level":55,"move_id":340}]},"tmhm_learnset":"0041BF03B453CE29","types":[14,14]},{"abilities":[57,0],"address":3306628,"base_stats":[60,50,40,95,85,75],"catch_rate":200,"evolutions":[],"friendship":70,"id":353,"learnset":{"address":3316726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":313},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[58,0],"address":3306656,"base_stats":[60,40,50,95,75,85],"catch_rate":200,"evolutions":[],"friendship":70,"id":354,"learnset":{"address":3316756,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":204},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[52,22],"address":3306684,"base_stats":[50,85,85,50,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":355,"learnset":{"address":3316786,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":6,"move_id":313},{"level":11,"move_id":44},{"level":16,"move_id":230},{"level":21,"move_id":11},{"level":26,"move_id":185},{"level":31,"move_id":226},{"level":36,"move_id":242},{"level":41,"move_id":334},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255}]},"tmhm_learnset":"00A01F7CC4335E21","types":[8,8]},{"abilities":[74,0],"address":3306712,"base_stats":[30,40,55,60,40,55],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":37,"species":357}],"friendship":70,"id":356,"learnset":{"address":3316818,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":38,"move_id":244},{"level":42,"move_id":179},{"level":48,"move_id":105}]},"tmhm_learnset":"00E01E41F41386A9","types":[1,14]},{"abilities":[74,0],"address":3306740,"base_stats":[60,60,75,80,60,75],"catch_rate":90,"evolutions":[],"friendship":70,"id":357,"learnset":{"address":3316848,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":9},{"level":1,"move_id":8},{"level":1,"move_id":117},{"level":1,"move_id":96},{"level":1,"move_id":93},{"level":1,"move_id":197},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":40,"move_id":244},{"level":46,"move_id":179},{"level":54,"move_id":105}]},"tmhm_learnset":"00E01E41F413C6A9","types":[1,14]},{"abilities":[30,0],"address":3306768,"base_stats":[45,40,60,50,40,75],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":359}],"friendship":70,"id":358,"learnset":{"address":3316884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":38,"move_id":119},{"level":41,"move_id":287},{"level":48,"move_id":195}]},"tmhm_learnset":"00087E80843B1620","types":[0,2]},{"abilities":[30,0],"address":3306796,"base_stats":[75,70,90,80,70,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":359,"learnset":{"address":3316912,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":310},{"level":1,"move_id":47},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":35,"move_id":225},{"level":40,"move_id":349},{"level":45,"move_id":287},{"level":54,"move_id":195},{"level":59,"move_id":143}]},"tmhm_learnset":"00887EA4867B5632","types":[16,2]},{"abilities":[23,0],"address":3306824,"base_stats":[95,23,48,23,23,48],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":15,"species":202}],"friendship":70,"id":360,"learnset":{"address":3316944,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":150},{"level":1,"move_id":204},{"level":1,"move_id":227},{"level":15,"move_id":68},{"level":15,"move_id":243},{"level":15,"move_id":219},{"level":15,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[26,0],"address":3306852,"base_stats":[20,40,90,25,30,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":362}],"friendship":35,"id":361,"learnset":{"address":3316962,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":38,"move_id":261},{"level":45,"move_id":212},{"level":49,"move_id":248}]},"tmhm_learnset":"0041BF00B4133E28","types":[7,7]},{"abilities":[46,0],"address":3306880,"base_stats":[40,70,130,25,60,130],"catch_rate":90,"evolutions":[],"friendship":35,"id":362,"learnset":{"address":3316990,"moves":[{"level":1,"move_id":20},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":1,"move_id":50},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":37,"move_id":325},{"level":41,"move_id":261},{"level":51,"move_id":212},{"level":58,"move_id":248}]},"tmhm_learnset":"00E1BF40B6137E29","types":[7,7]},{"abilities":[30,38],"address":3306908,"base_stats":[50,60,45,65,100,80],"catch_rate":150,"evolutions":[],"friendship":70,"id":363,"learnset":{"address":3317020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":5,"move_id":74},{"level":9,"move_id":40},{"level":13,"move_id":78},{"level":17,"move_id":72},{"level":21,"move_id":73},{"level":25,"move_id":345},{"level":29,"move_id":320},{"level":33,"move_id":202},{"level":37,"move_id":230},{"level":41,"move_id":275},{"level":45,"move_id":92},{"level":49,"move_id":80},{"level":53,"move_id":312},{"level":57,"move_id":235}]},"tmhm_learnset":"00441E08A4350720","types":[12,3]},{"abilities":[54,0],"address":3306936,"base_stats":[60,60,60,30,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":365}],"friendship":70,"id":364,"learnset":{"address":3317058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E5B336A5","types":[0,0]},{"abilities":[72,0],"address":3306964,"base_stats":[80,80,80,90,55,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":366}],"friendship":70,"id":365,"learnset":{"address":3317082,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":116},{"level":1,"move_id":227},{"level":1,"move_id":253},{"level":7,"move_id":227},{"level":13,"move_id":253},{"level":19,"move_id":154},{"level":25,"move_id":203},{"level":31,"move_id":163},{"level":37,"move_id":68},{"level":43,"move_id":264},{"level":49,"move_id":179}]},"tmhm_learnset":"00A41EA6E7B33EB5","types":[0,0]},{"abilities":[54,0],"address":3306992,"base_stats":[150,160,100,100,95,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":366,"learnset":{"address":3317108,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":1,"move_id":227},{"level":1,"move_id":303},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":36,"move_id":207},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E7B37EB5","types":[0,0]},{"abilities":[64,60],"address":3307020,"base_stats":[70,43,53,40,43,53],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":26,"species":368}],"friendship":70,"id":367,"learnset":{"address":3317134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":28,"move_id":92},{"level":34,"move_id":254},{"level":34,"move_id":255},{"level":34,"move_id":256},{"level":39,"move_id":188}]},"tmhm_learnset":"00A11E0AA4371724","types":[3,3]},{"abilities":[64,60],"address":3307048,"base_stats":[100,73,83,55,73,83],"catch_rate":75,"evolutions":[],"friendship":70,"id":368,"learnset":{"address":3317164,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":281},{"level":1,"move_id":139},{"level":1,"move_id":124},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":26,"move_id":34},{"level":31,"move_id":92},{"level":40,"move_id":254},{"level":40,"move_id":255},{"level":40,"move_id":256},{"level":48,"move_id":188}]},"tmhm_learnset":"00A11E0AA4375724","types":[3,3]},{"abilities":[34,0],"address":3307076,"base_stats":[99,68,83,51,72,87],"catch_rate":200,"evolutions":[],"friendship":70,"id":369,"learnset":{"address":3317196,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":16},{"level":7,"move_id":74},{"level":11,"move_id":75},{"level":17,"move_id":23},{"level":21,"move_id":230},{"level":27,"move_id":18},{"level":31,"move_id":345},{"level":37,"move_id":34},{"level":41,"move_id":76},{"level":47,"move_id":235}]},"tmhm_learnset":"00EC5E80863D4730","types":[12,2]},{"abilities":[43,0],"address":3307104,"base_stats":[64,51,23,28,51,23],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":20,"species":371}],"friendship":70,"id":370,"learnset":{"address":3317224,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":21,"move_id":48},{"level":25,"move_id":23},{"level":31,"move_id":103},{"level":35,"move_id":46},{"level":41,"move_id":156},{"level":41,"move_id":214},{"level":45,"move_id":304}]},"tmhm_learnset":"00001E26A4333634","types":[0,0]},{"abilities":[43,0],"address":3307132,"base_stats":[84,71,43,48,71,43],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":40,"species":372}],"friendship":70,"id":371,"learnset":{"address":3317254,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":43,"move_id":46},{"level":51,"move_id":156},{"level":51,"move_id":214},{"level":57,"move_id":304}]},"tmhm_learnset":"00A21F26E6333E34","types":[0,0]},{"abilities":[43,0],"address":3307160,"base_stats":[104,91,63,68,91,63],"catch_rate":45,"evolutions":[],"friendship":70,"id":372,"learnset":{"address":3317284,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":40,"move_id":63},{"level":45,"move_id":46},{"level":55,"move_id":156},{"level":55,"move_id":214},{"level":63,"move_id":304}]},"tmhm_learnset":"00A21F26E6337E34","types":[0,0]},{"abilities":[75,0],"address":3307188,"base_stats":[35,64,85,32,74,55],"catch_rate":255,"evolutions":[{"method":"ITEM","param":192,"species":374},{"method":"ITEM","param":193,"species":375}],"friendship":70,"id":373,"learnset":{"address":3317316,"moves":[{"level":1,"move_id":128},{"level":1,"move_id":55},{"level":1,"move_id":250},{"level":1,"move_id":334}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,0],"address":3307216,"base_stats":[55,104,105,52,94,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":374,"learnset":{"address":3317326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":44},{"level":15,"move_id":103},{"level":22,"move_id":352},{"level":29,"move_id":184},{"level":36,"move_id":242},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03111E4084137264","types":[11,11]},{"abilities":[33,0],"address":3307244,"base_stats":[55,84,105,52,114,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":375,"learnset":{"address":3317350,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":93},{"level":15,"move_id":97},{"level":22,"move_id":352},{"level":29,"move_id":133},{"level":36,"move_id":94},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03101E00B41B7264","types":[11,11]},{"abilities":[46,0],"address":3307272,"base_stats":[65,130,60,75,75,60],"catch_rate":30,"evolutions":[],"friendship":35,"id":376,"learnset":{"address":3317374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":5,"move_id":43},{"level":9,"move_id":269},{"level":13,"move_id":98},{"level":17,"move_id":13},{"level":21,"move_id":44},{"level":26,"move_id":14},{"level":31,"move_id":104},{"level":36,"move_id":163},{"level":41,"move_id":248},{"level":46,"move_id":195}]},"tmhm_learnset":"00E53FB6A5D37E6C","types":[17,17]},{"abilities":[15,0],"address":3307300,"base_stats":[44,75,35,45,63,33],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":37,"species":378}],"friendship":35,"id":377,"learnset":{"address":3317404,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":282},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":37,"move_id":185},{"level":44,"move_id":247},{"level":49,"move_id":289},{"level":56,"move_id":288}]},"tmhm_learnset":"0041BF02B5930E28","types":[7,7]},{"abilities":[15,0],"address":3307328,"base_stats":[64,115,65,65,83,63],"catch_rate":45,"evolutions":[],"friendship":35,"id":378,"learnset":{"address":3317432,"moves":[{"level":1,"move_id":282},{"level":1,"move_id":103},{"level":1,"move_id":101},{"level":1,"move_id":174},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":39,"move_id":185},{"level":48,"move_id":247},{"level":55,"move_id":289},{"level":64,"move_id":288}]},"tmhm_learnset":"0041BF02B5934E28","types":[7,7]},{"abilities":[61,0],"address":3307356,"base_stats":[73,100,60,65,100,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":379,"learnset":{"address":3317460,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":7,"move_id":122},{"level":10,"move_id":44},{"level":16,"move_id":342},{"level":19,"move_id":103},{"level":25,"move_id":137},{"level":28,"move_id":242},{"level":34,"move_id":305},{"level":37,"move_id":207},{"level":43,"move_id":114}]},"tmhm_learnset":"00A13E0C8E570E20","types":[3,3]},{"abilities":[17,0],"address":3307384,"base_stats":[73,115,60,90,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":380,"learnset":{"address":3317488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":43},{"level":7,"move_id":98},{"level":10,"move_id":14},{"level":13,"move_id":210},{"level":19,"move_id":163},{"level":25,"move_id":228},{"level":31,"move_id":306},{"level":37,"move_id":269},{"level":46,"move_id":197},{"level":55,"move_id":206}]},"tmhm_learnset":"00A03EA6EDF73E35","types":[0,0]},{"abilities":[33,69],"address":3307412,"base_stats":[100,90,130,55,45,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":381,"learnset":{"address":3317518,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":8,"move_id":55},{"level":15,"move_id":317},{"level":22,"move_id":281},{"level":29,"move_id":36},{"level":36,"move_id":300},{"level":43,"move_id":246},{"level":50,"move_id":156},{"level":57,"move_id":38},{"level":64,"move_id":56}]},"tmhm_learnset":"03901E50861B726C","types":[11,5]},{"abilities":[5,69],"address":3307440,"base_stats":[50,70,100,30,40,40],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":32,"species":383}],"friendship":35,"id":382,"learnset":{"address":3317546,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":34,"move_id":182},{"level":39,"move_id":319},{"level":44,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307468,"base_stats":[60,90,140,40,50,50],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":42,"species":384}],"friendship":35,"id":383,"learnset":{"address":3317578,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":45,"move_id":319},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307496,"base_stats":[70,110,180,50,60,60],"catch_rate":45,"evolutions":[],"friendship":35,"id":384,"learnset":{"address":3317610,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":50,"move_id":319},{"level":63,"move_id":38}]},"tmhm_learnset":"00B41EF6CFF37E37","types":[8,5]},{"abilities":[59,0],"address":3307524,"base_stats":[70,70,70,70,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":385,"learnset":{"address":3317642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":10,"move_id":55},{"level":10,"move_id":52},{"level":10,"move_id":181},{"level":20,"move_id":240},{"level":20,"move_id":241},{"level":20,"move_id":258},{"level":30,"move_id":311}]},"tmhm_learnset":"00403E36A5B33664","types":[0,0]},{"abilities":[35,68],"address":3307552,"base_stats":[65,73,55,85,47,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":386,"learnset":{"address":3317666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":109},{"level":9,"move_id":104},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":294},{"level":25,"move_id":324},{"level":29,"move_id":182},{"level":33,"move_id":270},{"level":37,"move_id":38}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[12,0],"address":3307580,"base_stats":[65,47,55,85,73,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":387,"learnset":{"address":3317694,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":230},{"level":9,"move_id":204},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":273},{"level":25,"move_id":227},{"level":29,"move_id":260},{"level":33,"move_id":270},{"level":37,"move_id":343}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[21,0],"address":3307608,"base_stats":[66,41,77,23,61,87],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":389}],"friendship":70,"id":388,"learnset":{"address":3317722,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":43,"move_id":246},{"level":50,"move_id":254},{"level":50,"move_id":255},{"level":50,"move_id":256}]},"tmhm_learnset":"00001E1884350720","types":[5,12]},{"abilities":[21,0],"address":3307636,"base_stats":[86,81,97,43,81,107],"catch_rate":45,"evolutions":[],"friendship":70,"id":389,"learnset":{"address":3317750,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":132},{"level":1,"move_id":51},{"level":1,"move_id":275},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":48,"move_id":246},{"level":60,"move_id":254},{"level":60,"move_id":255},{"level":60,"move_id":256}]},"tmhm_learnset":"00A01E5886354720","types":[5,12]},{"abilities":[4,0],"address":3307664,"base_stats":[45,95,50,75,40,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":391}],"friendship":70,"id":390,"learnset":{"address":3317778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":43,"move_id":210},{"level":49,"move_id":163},{"level":55,"move_id":350}]},"tmhm_learnset":"00841ED0CC110624","types":[5,6]},{"abilities":[4,0],"address":3307692,"base_stats":[75,125,100,45,70,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":391,"learnset":{"address":3317806,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":300},{"level":1,"move_id":55},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":46,"move_id":210},{"level":55,"move_id":163},{"level":64,"move_id":350}]},"tmhm_learnset":"00A41ED0CE514624","types":[5,6]},{"abilities":[28,36],"address":3307720,"base_stats":[28,25,25,40,45,35],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":20,"species":393}],"friendship":35,"id":392,"learnset":{"address":3317834,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":45},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":31,"move_id":286},{"level":36,"move_id":248},{"level":41,"move_id":95},{"level":46,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307748,"base_stats":[38,35,35,50,65,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":394}],"friendship":35,"id":393,"learnset":{"address":3317862,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":40,"move_id":248},{"level":47,"move_id":95},{"level":54,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307776,"base_stats":[68,65,65,80,125,115],"catch_rate":45,"evolutions":[],"friendship":35,"id":394,"learnset":{"address":3317890,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":42,"move_id":248},{"level":51,"move_id":95},{"level":60,"move_id":138}]},"tmhm_learnset":"0041BF03B49BCE28","types":[14,14]},{"abilities":[69,0],"address":3307804,"base_stats":[45,75,60,50,40,30],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":396}],"friendship":35,"id":395,"learnset":{"address":3317918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":33,"move_id":225},{"level":37,"move_id":184},{"level":41,"move_id":242},{"level":49,"move_id":337},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[69,0],"address":3307832,"base_stats":[65,95,100,50,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":50,"species":397}],"friendship":35,"id":396,"learnset":{"address":3317948,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":56,"move_id":242},{"level":69,"move_id":337},{"level":78,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[22,0],"address":3307860,"base_stats":[95,135,80,100,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":397,"learnset":{"address":3317980,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":50,"move_id":19},{"level":61,"move_id":242},{"level":79,"move_id":337},{"level":93,"move_id":38}]},"tmhm_learnset":"00AC5EE4C6534632","types":[16,2]},{"abilities":[29,0],"address":3307888,"base_stats":[40,55,80,30,35,60],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":20,"species":399}],"friendship":35,"id":398,"learnset":{"address":3318014,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36}]},"tmhm_learnset":"0000000000000000","types":[8,14]},{"abilities":[29,0],"address":3307916,"base_stats":[60,75,100,50,55,80],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":45,"species":400}],"friendship":35,"id":399,"learnset":{"address":3318024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":50,"move_id":309},{"level":56,"move_id":97},{"level":62,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307944,"base_stats":[80,135,130,70,95,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":400,"learnset":{"address":3318052,"moves":[{"level":1,"move_id":36},{"level":1,"move_id":93},{"level":1,"move_id":232},{"level":1,"move_id":184},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":55,"move_id":309},{"level":66,"move_id":97},{"level":77,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307972,"base_stats":[80,100,200,50,50,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":401,"learnset":{"address":3318080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":153},{"level":9,"move_id":88},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E52CF994621","types":[5,5]},{"abilities":[29,0],"address":3308000,"base_stats":[80,50,100,50,100,200],"catch_rate":3,"evolutions":[],"friendship":35,"id":402,"learnset":{"address":3318106,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":196},{"level":1,"move_id":153},{"level":9,"move_id":196},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E02C79B7261","types":[15,15]},{"abilities":[29,0],"address":3308028,"base_stats":[80,75,150,50,75,150],"catch_rate":3,"evolutions":[],"friendship":35,"id":403,"learnset":{"address":3318132,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":232},{"level":1,"move_id":153},{"level":9,"move_id":232},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00ED2C79B4621","types":[8,8]},{"abilities":[2,0],"address":3308056,"base_stats":[100,100,90,90,150,140],"catch_rate":5,"evolutions":[],"friendship":0,"id":404,"learnset":{"address":3318160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":352},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":34},{"level":30,"move_id":347},{"level":35,"move_id":58},{"level":45,"move_id":56},{"level":50,"move_id":156},{"level":60,"move_id":329},{"level":65,"move_id":38},{"level":75,"move_id":323}]},"tmhm_learnset":"03B00E42C79B727C","types":[11,11]},{"abilities":[70,0],"address":3308084,"base_stats":[100,150,140,90,100,90],"catch_rate":5,"evolutions":[],"friendship":0,"id":405,"learnset":{"address":3318190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":341},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":163},{"level":30,"move_id":339},{"level":35,"move_id":89},{"level":45,"move_id":126},{"level":50,"move_id":156},{"level":60,"move_id":90},{"level":65,"move_id":76},{"level":75,"move_id":284}]},"tmhm_learnset":"00A60EF6CFF946B2","types":[4,4]},{"abilities":[77,0],"address":3308112,"base_stats":[105,150,90,95,150,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":406,"learnset":{"address":3318220,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":239},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":337},{"level":30,"move_id":349},{"level":35,"move_id":242},{"level":45,"move_id":19},{"level":50,"move_id":156},{"level":60,"move_id":245},{"level":65,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BA0EB6C7F376B6","types":[16,2]},{"abilities":[26,0],"address":3308140,"base_stats":[80,80,90,110,110,130],"catch_rate":3,"evolutions":[],"friendship":90,"id":407,"learnset":{"address":3318250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":273},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":346},{"level":30,"move_id":287},{"level":35,"move_id":296},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":204}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[26,0],"address":3308168,"base_stats":[80,90,80,110,130,110],"catch_rate":3,"evolutions":[],"friendship":90,"id":408,"learnset":{"address":3318280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":262},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":182},{"level":30,"move_id":287},{"level":35,"move_id":295},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":349}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[32,0],"address":3308196,"base_stats":[100,100,100,100,100,100],"catch_rate":3,"evolutions":[],"friendship":100,"id":409,"learnset":{"address":3318310,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":273},{"level":1,"move_id":93},{"level":5,"move_id":156},{"level":10,"move_id":129},{"level":15,"move_id":270},{"level":20,"move_id":94},{"level":25,"move_id":287},{"level":30,"move_id":156},{"level":35,"move_id":38},{"level":40,"move_id":248},{"level":45,"move_id":322},{"level":50,"move_id":353}]},"tmhm_learnset":"00408E93B59BC62C","types":[8,14]},{"abilities":[46,0],"address":3308224,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":410,"learnset":{"address":3318340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":35},{"level":5,"move_id":101},{"level":10,"move_id":104},{"level":15,"move_id":282},{"level":20,"move_id":228},{"level":25,"move_id":94},{"level":30,"move_id":129},{"level":35,"move_id":97},{"level":40,"move_id":105},{"level":45,"move_id":354},{"level":50,"move_id":245}]},"tmhm_learnset":"00E58FC3F5BBDE2D","types":[14,14]},{"abilities":[26,0],"address":3308252,"base_stats":[65,50,70,65,95,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":411,"learnset":{"address":3318370,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":6,"move_id":45},{"level":9,"move_id":310},{"level":14,"move_id":93},{"level":17,"move_id":36},{"level":22,"move_id":253},{"level":25,"move_id":281},{"level":30,"move_id":149},{"level":33,"move_id":38},{"level":38,"move_id":215},{"level":41,"move_id":219},{"level":46,"move_id":94}]},"tmhm_learnset":"00419F03B41B8E28","types":[14,14]}],"tmhm_moves":[264,337,352,347,46,92,258,339,331,237,241,269,58,59,63,113,182,240,202,219,218,76,231,85,87,89,216,91,94,247,280,104,115,351,53,188,201,126,317,332,259,263,290,156,213,168,211,285,289,315,15,19,57,70,148,249,127,291],"trainers":[{"address":3230072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[],"party_address":4160749568,"script_address":0},{"address":3230112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":74}],"party_address":3211124,"script_address":2304511},{"address":3230152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":286}],"party_address":3211132,"script_address":2321901},{"address":3230192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":330}],"party_address":3211140,"script_address":2323326},{"address":3230232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211156,"script_address":2323373},{"address":3230272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211164,"script_address":2324386},{"address":3230312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":286}],"party_address":3211172,"script_address":2326808},{"address":3230352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211180,"script_address":2326839},{"address":3230392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":41}],"party_address":3211188,"script_address":2328040},{"address":3230432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":315},{"level":26,"species":286},{"level":26,"species":288},{"level":26,"species":295},{"level":26,"species":298},{"level":26,"species":304}],"party_address":3211196,"script_address":2314251},{"address":3230472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":286}],"party_address":3211244,"script_address":0},{"address":3230512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":300}],"party_address":3211252,"script_address":2067580},{"address":3230552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":310},{"level":30,"species":178}],"party_address":3211268,"script_address":2068523},{"address":3230592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":380},{"level":30,"species":379}],"party_address":3211284,"script_address":2068554},{"address":3230632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211300,"script_address":2328071},{"address":3230672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3211308,"script_address":2069620},{"address":3230712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":286}],"party_address":3211316,"script_address":0},{"address":3230752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3211324,"script_address":2570959},{"address":3230792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":286},{"level":27,"species":330}],"party_address":3211340,"script_address":2572093},{"address":3230832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":286},{"level":26,"species":41},{"level":26,"species":330}],"party_address":3211356,"script_address":2572124},{"address":3230872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":330}],"party_address":3211380,"script_address":2157889},{"address":3230912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":41},{"level":14,"species":330}],"party_address":3211388,"script_address":2157948},{"address":3230952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":339}],"party_address":3211404,"script_address":2254636},{"address":3230992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211412,"script_address":2317522},{"address":3231032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211420,"script_address":2317553},{"address":3231072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":286},{"level":30,"species":330}],"party_address":3211428,"script_address":2317584},{"address":3231112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330}],"party_address":3211444,"script_address":2570990},{"address":3231152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211452,"script_address":2323414},{"address":3231192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211460,"script_address":2324427},{"address":3231232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":335},{"level":30,"species":67}],"party_address":3211468,"script_address":2068492},{"address":3231272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":287},{"level":34,"species":42}],"party_address":3211484,"script_address":2324250},{"address":3231312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":336}],"party_address":3211500,"script_address":2312702},{"address":3231352,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330},{"level":28,"species":287}],"party_address":3211508,"script_address":2572155},{"address":3231392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":331},{"level":37,"species":287}],"party_address":3211524,"script_address":2327156},{"address":3231432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":287},{"level":41,"species":169},{"level":43,"species":331}],"party_address":3211540,"script_address":2328478},{"address":3231472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":351}],"party_address":3211564,"script_address":2312671},{"address":3231512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211572,"script_address":2026085},{"address":3231552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":363},{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211588,"script_address":2058784},{"address":3231592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,0,0,0],"species":357},{"level":43,"moves":[29,89,0,0],"species":319}],"party_address":3211612,"script_address":2335547},{"address":3231632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":363},{"level":26,"species":44}],"party_address":3211644,"script_address":2068148},{"address":3231672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":363}],"party_address":3211660,"script_address":0},{"address":3231712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":306},{"level":28,"species":44},{"level":28,"species":363}],"party_address":3211676,"script_address":0},{"address":3231752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":306},{"level":31,"species":44},{"level":31,"species":363}],"party_address":3211700,"script_address":0},{"address":3231792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307},{"level":34,"species":44},{"level":34,"species":363}],"party_address":3211724,"script_address":0},{"address":3231832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,163,28,40],"species":28}],"party_address":3211748,"script_address":2046490},{"address":3231872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[60,120,201,246],"species":318},{"level":27,"moves":[91,163,28,40],"species":27},{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211764,"script_address":2065682},{"address":3231912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[91,163,28,40],"species":27},{"level":25,"moves":[91,163,28,40],"species":28}],"party_address":3211812,"script_address":2033540},{"address":3231952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211844,"script_address":0},{"address":3231992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[91,163,28,40],"species":28}],"party_address":3211860,"script_address":0},{"address":3232032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[91,163,28,40],"species":28}],"party_address":3211876,"script_address":0},{"address":3232072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[91,163,28,40],"species":28}],"party_address":3211892,"script_address":0},{"address":3232112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":81},{"level":17,"species":370}],"party_address":3211908,"script_address":0},{"address":3232152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":81},{"level":27,"species":371}],"party_address":3211924,"script_address":0},{"address":3232192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":82},{"level":30,"species":371}],"party_address":3211940,"script_address":0},{"address":3232232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":82},{"level":33,"species":371}],"party_address":3211956,"script_address":0},{"address":3232272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82},{"level":36,"species":371}],"party_address":3211972,"script_address":0},{"address":3232312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[49,86,63,85],"species":82},{"level":39,"moves":[54,23,48,48],"species":372}],"party_address":3211988,"script_address":0},{"address":3232352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":350}],"party_address":3212020,"script_address":2036011},{"address":3232392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212036,"script_address":2036121},{"address":3232432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212044,"script_address":2036152},{"address":3232472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183},{"level":26,"species":183}],"party_address":3212052,"script_address":0},{"address":3232512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":183},{"level":29,"species":183}],"party_address":3212068,"script_address":0},{"address":3232552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":183},{"level":32,"species":183}],"party_address":3212084,"script_address":0},{"address":3232592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":35,"species":184}],"party_address":3212100,"script_address":0},{"address":3232632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":13,"moves":[28,29,39,57],"species":288}],"party_address":3212116,"script_address":2035901},{"address":3232672,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":183}],"party_address":3212132,"script_address":2544001},{"address":3232712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212148,"script_address":2339831},{"address":3232752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[28,42,39,57],"species":289}],"party_address":3212156,"script_address":0},{"address":3232792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[28,42,39,57],"species":289}],"party_address":3212172,"script_address":0},{"address":3232832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[28,42,39,57],"species":289}],"party_address":3212188,"script_address":0},{"address":3232872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[28,42,39,57],"species":289}],"party_address":3212204,"script_address":0},{"address":3232912,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[98,97,17,0],"species":305}],"party_address":3212220,"script_address":2131164},{"address":3232952,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[42,146,8,0],"species":308}],"party_address":3212236,"script_address":2131228},{"address":3232992,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[47,68,247,0],"species":364}],"party_address":3212252,"script_address":2131292},{"address":3233032,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[116,163,0,0],"species":365}],"party_address":3212268,"script_address":2131356},{"address":3233072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[116,98,17,27],"species":305},{"level":28,"moves":[44,91,185,72],"species":332},{"level":28,"moves":[205,250,54,96],"species":313},{"level":28,"moves":[85,48,86,49],"species":82},{"level":28,"moves":[202,185,104,207],"species":300}],"party_address":3212284,"script_address":2068117},{"address":3233112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":322},{"level":44,"species":357},{"level":44,"species":331}],"party_address":3212364,"script_address":2565920},{"address":3233152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":355},{"level":46,"species":121}],"party_address":3212388,"script_address":2565982},{"address":3233192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":337},{"level":17,"species":313},{"level":17,"species":335}],"party_address":3212404,"script_address":2046693},{"address":3233232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":345},{"level":43,"species":310}],"party_address":3212428,"script_address":2332685},{"address":3233272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":82},{"level":43,"species":89}],"party_address":3212444,"script_address":2332716},{"address":3233312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":305},{"level":42,"species":355},{"level":42,"species":64}],"party_address":3212460,"script_address":2334375},{"address":3233352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":85},{"level":42,"species":64},{"level":42,"species":101},{"level":42,"species":300}],"party_address":3212484,"script_address":2335423},{"address":3233392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":317},{"level":42,"species":75},{"level":42,"species":314}],"party_address":3212516,"script_address":2335454},{"address":3233432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":337},{"level":26,"species":313},{"level":26,"species":335}],"party_address":3212540,"script_address":0},{"address":3233472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":313},{"level":29,"species":335}],"party_address":3212564,"script_address":0},{"address":3233512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":338},{"level":32,"species":313},{"level":32,"species":335}],"party_address":3212588,"script_address":0},{"address":3233552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":338},{"level":35,"species":313},{"level":35,"species":336}],"party_address":3212612,"script_address":0},{"address":3233592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":297}],"party_address":3212636,"script_address":2073950},{"address":3233632,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[185,95,0,0],"species":316}],"party_address":3212652,"script_address":2131420},{"address":3233672,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[111,38,247,0],"species":40}],"party_address":3212668,"script_address":2131484},{"address":3233712,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[14,163,0,0],"species":380}],"party_address":3212684,"script_address":2131548},{"address":3233752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[226,185,57,44],"species":355},{"level":29,"moves":[72,89,64,73],"species":363},{"level":29,"moves":[19,55,54,182],"species":310}],"party_address":3212700,"script_address":2068086},{"address":3233792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":383},{"level":45,"species":338}],"party_address":3212748,"script_address":2565951},{"address":3233832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":309},{"level":17,"species":339},{"level":17,"species":363}],"party_address":3212764,"script_address":2046803},{"address":3233872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":322}],"party_address":3212788,"script_address":2065651},{"address":3233912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3212796,"script_address":2332747},{"address":3233952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":319}],"party_address":3212804,"script_address":2334406},{"address":3233992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":321},{"level":42,"species":357},{"level":42,"species":297}],"party_address":3212812,"script_address":2334437},{"address":3234032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":227},{"level":43,"species":322}],"party_address":3212836,"script_address":2335485},{"address":3234072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":28},{"level":42,"species":38},{"level":42,"species":369}],"party_address":3212852,"script_address":2335516},{"address":3234112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":26,"species":339},{"level":26,"species":363}],"party_address":3212876,"script_address":0},{"address":3234152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":339},{"level":29,"species":363}],"party_address":3212900,"script_address":0},{"address":3234192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":339},{"level":32,"species":363}],"party_address":3212924,"script_address":0},{"address":3234232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":340},{"level":34,"species":363}],"party_address":3212948,"script_address":0},{"address":3234272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":348}],"party_address":3212972,"script_address":2564729},{"address":3234312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":361},{"level":30,"species":377}],"party_address":3212988,"script_address":2068461},{"address":3234352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":361},{"level":29,"species":377}],"party_address":3213004,"script_address":2067284},{"address":3234392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":322}],"party_address":3213020,"script_address":2315745},{"address":3234432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":377}],"party_address":3213028,"script_address":2315532},{"address":3234472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":322},{"level":31,"species":351}],"party_address":3213036,"script_address":0},{"address":3234512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":351},{"level":35,"species":322}],"party_address":3213052,"script_address":0},{"address":3234552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":351},{"level":40,"species":322}],"party_address":3213068,"script_address":0},{"address":3234592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":361},{"level":42,"species":322},{"level":42,"species":352}],"party_address":3213084,"script_address":0},{"address":3234632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213108,"script_address":2030087},{"address":3234672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[213,186,175,96],"species":325},{"level":39,"moves":[213,219,36,96],"species":325}],"party_address":3213116,"script_address":2265894},{"address":3234712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":287},{"level":28,"species":287},{"level":30,"species":339}],"party_address":3213148,"script_address":2254717},{"address":3234752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":11,"moves":[33,39,0,0],"species":288}],"party_address":3213172,"script_address":0},{"address":3234792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":40,"species":119}],"party_address":3213188,"script_address":2265677},{"address":3234832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3213196,"script_address":2361019},{"address":3234872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213204,"script_address":0},{"address":3234912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213212,"script_address":0},{"address":3234952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213220,"script_address":0},{"address":3234992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213228,"script_address":0},{"address":3235032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":183}],"party_address":3213244,"script_address":2304387},{"address":3235072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3213252,"script_address":2304418},{"address":3235112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":339}],"party_address":3213260,"script_address":2304449},{"address":3235152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[20,122,154,185],"species":317},{"level":29,"moves":[86,103,137,242],"species":379}],"party_address":3213268,"script_address":2067377},{"address":3235192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":118}],"party_address":3213300,"script_address":2265708},{"address":3235232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":184}],"party_address":3213308,"script_address":2265739},{"address":3235272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[78,250,240,96],"species":373},{"level":37,"moves":[13,152,96,0],"species":326},{"level":39,"moves":[253,154,252,96],"species":296}],"party_address":3213316,"script_address":2265770},{"address":3235312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":330},{"level":39,"species":331}],"party_address":3213364,"script_address":2265801},{"address":3235352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[20,122,154,185],"species":317},{"level":35,"moves":[86,103,137,242],"species":379}],"party_address":3213380,"script_address":0},{"address":3235392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[20,122,154,185],"species":317},{"level":38,"moves":[86,103,137,242],"species":379}],"party_address":3213412,"script_address":0},{"address":3235432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[20,122,154,185],"species":317},{"level":41,"moves":[86,103,137,242],"species":379}],"party_address":3213444,"script_address":0},{"address":3235472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[20,122,154,185],"species":317},{"level":44,"moves":[86,103,137,242],"species":379}],"party_address":3213476,"script_address":0},{"address":3235512,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213508,"script_address":2029901},{"address":3235552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":324},{"level":33,"species":356}],"party_address":3213516,"script_address":2074012},{"address":3235592,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":184}],"party_address":3213532,"script_address":2360988},{"address":3235632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213540,"script_address":0},{"address":3235672,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213548,"script_address":0},{"address":3235712,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213556,"script_address":0},{"address":3235752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213564,"script_address":0},{"address":3235792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3213580,"script_address":2051965},{"address":3235832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":116}],"party_address":3213588,"script_address":2340108},{"address":3235872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":111}],"party_address":3213604,"script_address":2312578},{"address":3235912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":339}],"party_address":3213612,"script_address":2304480},{"address":3235952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":383}],"party_address":3213620,"script_address":0},{"address":3235992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":383},{"level":29,"species":111}],"party_address":3213628,"script_address":0},{"address":3236032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":383},{"level":32,"species":111}],"party_address":3213644,"script_address":0},{"address":3236072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":384},{"level":35,"species":112}],"party_address":3213660,"script_address":0},{"address":3236112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213676,"script_address":2033571},{"address":3236152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":72}],"party_address":3213684,"script_address":2033602},{"address":3236192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":72}],"party_address":3213692,"script_address":2034185},{"address":3236232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":309},{"level":24,"species":72}],"party_address":3213708,"script_address":2034479},{"address":3236272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213732,"script_address":2034510},{"address":3236312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":73}],"party_address":3213740,"script_address":2034776},{"address":3236352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213748,"script_address":2034807},{"address":3236392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3213756,"script_address":2035777},{"address":3236432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309}],"party_address":3213772,"script_address":2069178},{"address":3236472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3213788,"script_address":2069209},{"address":3236512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":73}],"party_address":3213796,"script_address":2069789},{"address":3236552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":116}],"party_address":3213804,"script_address":2069820},{"address":3236592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213812,"script_address":2070163},{"address":3236632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":31,"species":309},{"level":31,"species":330}],"party_address":3213820,"script_address":2070194},{"address":3236672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213844,"script_address":2073229},{"address":3236712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310}],"party_address":3213852,"script_address":2073359},{"address":3236752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213860,"script_address":2073390},{"address":3236792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":73},{"level":33,"species":313}],"party_address":3213876,"script_address":2073291},{"address":3236832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3213892,"script_address":2073608},{"address":3236872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":342}],"party_address":3213900,"script_address":2073857},{"address":3236912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":341}],"party_address":3213908,"script_address":2073576},{"address":3236952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213916,"script_address":2074089},{"address":3236992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213924,"script_address":0},{"address":3237032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":313}],"party_address":3213948,"script_address":2069381},{"address":3237072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":331}],"party_address":3213964,"script_address":0},{"address":3237112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":331}],"party_address":3213972,"script_address":0},{"address":3237152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120},{"level":36,"species":331}],"party_address":3213980,"script_address":0},{"address":3237192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":121},{"level":39,"species":331}],"party_address":3213996,"script_address":0},{"address":3237232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3214012,"script_address":2095275},{"address":3237272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":66},{"level":32,"species":67}],"party_address":3214020,"script_address":2074213},{"address":3237312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":336}],"party_address":3214036,"script_address":2073701},{"address":3237352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":66},{"level":28,"species":67}],"party_address":3214044,"script_address":2052921},{"address":3237392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214060,"script_address":2052952},{"address":3237432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":67}],"party_address":3214068,"script_address":0},{"address":3237472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":66},{"level":29,"species":67}],"party_address":3214076,"script_address":0},{"address":3237512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":66},{"level":31,"species":67},{"level":31,"species":67}],"party_address":3214092,"script_address":0},{"address":3237552,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":66},{"level":33,"species":67},{"level":33,"species":67},{"level":33,"species":68}],"party_address":3214116,"script_address":0},{"address":3237592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":335},{"level":26,"species":67}],"party_address":3214148,"script_address":2557758},{"address":3237632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214164,"script_address":2046662},{"address":3237672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":336}],"party_address":3214172,"script_address":2315359},{"address":3237712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[98,86,209,43],"species":337},{"level":17,"moves":[12,95,103,0],"species":100}],"party_address":3214180,"script_address":2167608},{"address":3237752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":286},{"level":31,"species":41}],"party_address":3214212,"script_address":2323445},{"address":3237792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3214228,"script_address":2324458},{"address":3237832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":100},{"level":17,"species":81}],"party_address":3214236,"script_address":2167639},{"address":3237872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":337},{"level":30,"species":371}],"party_address":3214252,"script_address":2068709},{"address":3237912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81},{"level":15,"species":370}],"party_address":3214268,"script_address":2058956},{"address":3237952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":81},{"level":25,"species":370},{"level":25,"species":81}],"party_address":3214284,"script_address":0},{"address":3237992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81},{"level":28,"species":371},{"level":28,"species":81}],"party_address":3214308,"script_address":0},{"address":3238032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":82},{"level":31,"species":371},{"level":31,"species":82}],"party_address":3214332,"script_address":0},{"address":3238072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82},{"level":34,"species":372},{"level":34,"species":82}],"party_address":3214356,"script_address":0},{"address":3238112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214380,"script_address":2103394},{"address":3238152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":218},{"level":22,"species":218}],"party_address":3214388,"script_address":2103601},{"address":3238192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214404,"script_address":2103446},{"address":3238232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214412,"script_address":2103570},{"address":3238272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214420,"script_address":2103477},{"address":3238312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309}],"party_address":3214428,"script_address":2052075},{"address":3238352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":218},{"level":26,"species":309}],"party_address":3214444,"script_address":0},{"address":3238392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310}],"party_address":3214460,"script_address":0},{"address":3238432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":218},{"level":32,"species":310}],"party_address":3214476,"script_address":0},{"address":3238472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":219},{"level":35,"species":310}],"party_address":3214492,"script_address":0},{"address":3238512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,28,40,163],"species":27}],"party_address":3214508,"script_address":2046366},{"address":3238552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":21,"moves":[229,189,60,61],"species":318},{"level":21,"moves":[40,28,10,91],"species":27},{"level":21,"moves":[229,189,60,61],"species":318}],"party_address":3214524,"script_address":2046428},{"address":3238592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":299}],"party_address":3214572,"script_address":2049829},{"address":3238632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27},{"level":18,"species":299}],"party_address":3214580,"script_address":2051903},{"address":3238672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":317}],"party_address":3214596,"script_address":2557005},{"address":3238712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":288},{"level":20,"species":304}],"party_address":3214604,"script_address":2310199},{"address":3238752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3214620,"script_address":2310337},{"address":3238792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27}],"party_address":3214628,"script_address":2046600},{"address":3238832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":288},{"level":26,"species":304}],"party_address":3214636,"script_address":0},{"address":3238872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":289},{"level":29,"species":305}],"party_address":3214652,"script_address":0},{"address":3238912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":305},{"level":31,"species":289}],"party_address":3214668,"script_address":0},{"address":3238952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":28},{"level":34,"species":289}],"party_address":3214692,"script_address":0},{"address":3238992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":311}],"party_address":3214716,"script_address":2061044},{"address":3239032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":290},{"level":24,"species":291},{"level":24,"species":292}],"party_address":3214724,"script_address":2061075},{"address":3239072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":290},{"level":27,"species":293},{"level":27,"species":294}],"party_address":3214748,"script_address":2061106},{"address":3239112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":311},{"level":27,"species":311},{"level":27,"species":311}],"party_address":3214772,"script_address":2065541},{"address":3239152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":294},{"level":16,"species":292}],"party_address":3214796,"script_address":2057595},{"address":3239192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":311},{"level":31,"species":311}],"party_address":3214812,"script_address":0},{"address":3239232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":311},{"level":34,"species":311},{"level":34,"species":312}],"party_address":3214836,"script_address":0},{"address":3239272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":311},{"level":36,"species":290},{"level":36,"species":311},{"level":36,"species":312}],"party_address":3214860,"script_address":0},{"address":3239312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":311},{"level":38,"species":294},{"level":38,"species":311},{"level":38,"species":312},{"level":38,"species":292}],"party_address":3214892,"script_address":0},{"address":3239352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[237,0,0,0],"species":63}],"party_address":3214932,"script_address":2038374},{"address":3239392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3214948,"script_address":2244488},{"address":3239432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":392}],"party_address":3214956,"script_address":2244519},{"address":3239472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3214964,"script_address":2244550},{"address":3239512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":392},{"level":26,"species":393}],"party_address":3214972,"script_address":2314189},{"address":3239552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3214996,"script_address":2564698},{"address":3239592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":349}],"party_address":3215012,"script_address":2068179},{"address":3239632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":64},{"level":33,"species":349}],"party_address":3215020,"script_address":0},{"address":3239672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":64},{"level":38,"species":349}],"party_address":3215036,"script_address":0},{"address":3239712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3215052,"script_address":0},{"address":3239752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":349},{"level":45,"species":65}],"party_address":3215068,"script_address":0},{"address":3239792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[237,0,0,0],"species":63}],"party_address":3215084,"script_address":2038405},{"address":3239832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3215100,"script_address":2244581},{"address":3239872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":178}],"party_address":3215108,"script_address":2244612},{"address":3239912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3215116,"script_address":2244643},{"address":3239952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":202},{"level":26,"species":177},{"level":26,"species":64}],"party_address":3215124,"script_address":2314220},{"address":3239992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":393},{"level":41,"species":178}],"party_address":3215148,"script_address":2564760},{"address":3240032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":64},{"level":30,"species":348}],"party_address":3215164,"script_address":2068289},{"address":3240072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":64},{"level":34,"species":348}],"party_address":3215180,"script_address":0},{"address":3240112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":64},{"level":37,"species":348}],"party_address":3215196,"script_address":0},{"address":3240152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":64},{"level":40,"species":348}],"party_address":3215212,"script_address":0},{"address":3240192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":348},{"level":43,"species":65}],"party_address":3215228,"script_address":0},{"address":3240232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338}],"party_address":3215244,"script_address":2067174},{"address":3240272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":338},{"level":44,"species":338}],"party_address":3215252,"script_address":2360864},{"address":3240312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":380}],"party_address":3215268,"script_address":2360895},{"address":3240352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":338}],"party_address":3215276,"script_address":0},{"address":3240392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[29,28,60,154],"species":289},{"level":36,"moves":[98,209,60,46],"species":338}],"party_address":3215284,"script_address":0},{"address":3240432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[29,28,60,154],"species":289},{"level":39,"moves":[98,209,60,0],"species":338}],"party_address":3215316,"script_address":0},{"address":3240472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[29,28,60,154],"species":289},{"level":41,"moves":[154,50,93,244],"species":55},{"level":41,"moves":[98,209,60,46],"species":338}],"party_address":3215348,"script_address":0},{"address":3240512,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,38,28,242],"species":287},{"level":48,"moves":[3,104,207,70],"species":300},{"level":46,"moves":[73,185,46,178],"species":345},{"level":48,"moves":[57,14,70,7],"species":327},{"level":49,"moves":[76,157,14,163],"species":376}],"party_address":3215396,"script_address":2274753},{"address":3240552,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[69,109,174,182],"species":362},{"level":49,"moves":[247,32,5,185],"species":378},{"level":50,"moves":[247,104,101,185],"species":322},{"level":49,"moves":[247,94,85,7],"species":378},{"level":51,"moves":[247,58,157,89],"species":362}],"party_address":3215476,"script_address":2275380},{"address":3240592,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[227,34,2,45],"species":342},{"level":50,"moves":[113,242,196,58],"species":347},{"level":52,"moves":[213,38,2,59],"species":342},{"level":52,"moves":[247,153,2,58],"species":347},{"level":53,"moves":[57,34,58,73],"species":343}],"party_address":3215556,"script_address":2276062},{"address":3240632,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[61,81,182,38],"species":396},{"level":54,"moves":[38,225,93,76],"species":359},{"level":53,"moves":[108,93,57,34],"species":230},{"level":53,"moves":[53,242,225,89],"species":334},{"level":55,"moves":[53,81,157,242],"species":397}],"party_address":3215636,"script_address":2276724},{"address":3240672,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":12,"moves":[33,111,88,61],"species":74},{"level":12,"moves":[33,111,88,61],"species":74},{"level":15,"moves":[79,106,33,61],"species":320}],"party_address":3215716,"script_address":2187976},{"address":3240712,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[2,67,69,83],"species":66},{"level":16,"moves":[8,113,115,83],"species":356},{"level":19,"moves":[36,233,179,83],"species":335}],"party_address":3215764,"script_address":2095066},{"address":3240752,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":20,"moves":[205,209,120,95],"species":100},{"level":20,"moves":[95,43,98,80],"species":337},{"level":22,"moves":[48,95,86,49],"species":82},{"level":24,"moves":[98,86,95,80],"species":338}],"party_address":3215812,"script_address":2167181},{"address":3240792,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[59,36,222,241],"species":339},{"level":24,"moves":[59,123,113,241],"species":218},{"level":26,"moves":[59,33,241,213],"species":340},{"level":29,"moves":[59,241,34,213],"species":321}],"party_address":3215876,"script_address":2103186},{"address":3240832,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[42,60,7,227],"species":308},{"level":27,"moves":[163,7,227,185],"species":365},{"level":29,"moves":[163,187,7,29],"species":289},{"level":31,"moves":[68,25,7,185],"species":366}],"party_address":3215940,"script_address":2129756},{"address":3240872,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[195,119,219,76],"species":358},{"level":29,"moves":[241,76,76,235],"species":369},{"level":30,"moves":[55,48,182,76],"species":310},{"level":31,"moves":[28,31,211,76],"species":227},{"level":33,"moves":[89,225,93,76],"species":359}],"party_address":3216004,"script_address":2202062},{"address":3240912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[89,246,94,113],"species":319},{"level":41,"moves":[94,241,109,91],"species":178},{"level":42,"moves":[113,94,95,91],"species":348},{"level":42,"moves":[241,76,94,53],"species":349}],"party_address":3216084,"script_address":0},{"address":3240952,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[96,213,186,175],"species":325},{"level":41,"moves":[240,96,133,89],"species":324},{"level":43,"moves":[227,34,62,96],"species":342},{"level":43,"moves":[96,152,13,43],"species":327},{"level":46,"moves":[96,104,58,156],"species":230}],"party_address":3216148,"script_address":2262245},{"address":3240992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":392}],"party_address":3216228,"script_address":2054242},{"address":3241032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3216236,"script_address":2554598},{"address":3241072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":339},{"level":15,"species":43},{"level":15,"species":309}],"party_address":3216244,"script_address":2554629},{"address":3241112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":356}],"party_address":3216268,"script_address":0},{"address":3241152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":393},{"level":29,"species":356}],"party_address":3216284,"script_address":0},{"address":3241192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":393},{"level":32,"species":357}],"party_address":3216300,"script_address":0},{"address":3241232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":393},{"level":34,"species":378},{"level":34,"species":357}],"party_address":3216316,"script_address":0},{"address":3241272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":306}],"party_address":3216340,"script_address":2054490},{"address":3241312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":306},{"level":16,"species":292}],"party_address":3216348,"script_address":2554660},{"address":3241352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":370}],"party_address":3216364,"script_address":0},{"address":3241392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":306},{"level":29,"species":371}],"party_address":3216380,"script_address":0},{"address":3241432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":307},{"level":32,"species":371}],"party_address":3216396,"script_address":0},{"address":3241472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":307},{"level":35,"species":372}],"party_address":3216412,"script_address":0},{"address":3241512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[95,60,146,42],"species":308},{"level":32,"moves":[8,25,47,185],"species":366}],"party_address":3216428,"script_address":0},{"address":3241552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[45,39,29,60],"species":288},{"level":17,"moves":[33,116,36,0],"species":335}],"party_address":3216460,"script_address":0},{"address":3241592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[45,39,29,60],"species":288},{"level":30,"moves":[33,116,36,0],"species":335}],"party_address":3216492,"script_address":0},{"address":3241632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[45,39,29,60],"species":288},{"level":33,"moves":[33,116,36,0],"species":335}],"party_address":3216524,"script_address":0},{"address":3241672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[45,39,29,60],"species":289},{"level":36,"moves":[33,116,36,0],"species":335}],"party_address":3216556,"script_address":0},{"address":3241712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[45,39,29,60],"species":289},{"level":38,"moves":[33,116,36,0],"species":336}],"party_address":3216588,"script_address":0},{"address":3241752,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":16,"species":304},{"level":16,"species":288}],"party_address":3216620,"script_address":2045785},{"address":3241792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":15,"species":315}],"party_address":3216636,"script_address":2026353},{"address":3241832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[18,204,185,215],"species":315},{"level":36,"moves":[18,204,185,215],"species":315},{"level":40,"moves":[18,204,185,215],"species":315},{"level":12,"moves":[18,204,185,215],"species":315},{"level":30,"moves":[18,204,185,215],"species":315},{"level":42,"moves":[18,204,185,215],"species":316}],"party_address":3216644,"script_address":2360833},{"address":3241872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":315}],"party_address":3216740,"script_address":0},{"address":3241912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":315}],"party_address":3216748,"script_address":0},{"address":3241952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316}],"party_address":3216756,"script_address":0},{"address":3241992,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":316}],"party_address":3216764,"script_address":0},{"address":3242032,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":17,"species":363}],"party_address":3216772,"script_address":2045890},{"address":3242072,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":25}],"party_address":3216780,"script_address":2067143},{"address":3242112,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":350},{"level":37,"species":183},{"level":39,"species":184}],"party_address":3216788,"script_address":2265832},{"address":3242152,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":353},{"level":14,"species":354}],"party_address":3216812,"script_address":2038890},{"address":3242192,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":26,"species":353},{"level":26,"species":354}],"party_address":3216828,"script_address":0},{"address":3242232,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":353},{"level":29,"species":354}],"party_address":3216844,"script_address":0},{"address":3242272,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":353},{"level":32,"species":354}],"party_address":3216860,"script_address":0},{"address":3242312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":353},{"level":35,"species":354}],"party_address":3216876,"script_address":0},{"address":3242352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":336}],"party_address":3216892,"script_address":2052811},{"address":3242392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[36,26,28,91],"species":336}],"party_address":3216900,"script_address":0},{"address":3242432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[36,26,28,91],"species":336}],"party_address":3216916,"script_address":0},{"address":3242472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[36,187,28,91],"species":336}],"party_address":3216932,"script_address":0},{"address":3242512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[36,187,28,91],"species":336}],"party_address":3216948,"script_address":0},{"address":3242552,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[136,96,93,197],"species":356}],"party_address":3216964,"script_address":2046100},{"address":3242592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":356},{"level":21,"species":335}],"party_address":3216980,"script_address":2304277},{"address":3242632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":356},{"level":30,"species":335}],"party_address":3216996,"script_address":0},{"address":3242672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":357},{"level":33,"species":336}],"party_address":3217012,"script_address":0},{"address":3242712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":357},{"level":36,"species":336}],"party_address":3217028,"script_address":0},{"address":3242752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":357},{"level":39,"species":336}],"party_address":3217044,"script_address":0},{"address":3242792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":286}],"party_address":3217060,"script_address":2024678},{"address":3242832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":288},{"level":7,"species":298}],"party_address":3217068,"script_address":2029684},{"address":3242872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[33,0,0,0],"species":74}],"party_address":3217084,"script_address":2188154},{"address":3242912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3217100,"script_address":2188185},{"address":3242952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":66}],"party_address":3217116,"script_address":2054180},{"address":3242992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[29,28,45,85],"species":288},{"level":17,"moves":[133,124,25,1],"species":367}],"party_address":3217124,"script_address":2167670},{"address":3243032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[213,58,85,53],"species":366},{"level":43,"moves":[29,182,5,92],"species":362}],"party_address":3217156,"script_address":2332778},{"address":3243072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,94,85,91],"species":394},{"level":43,"moves":[89,247,76,24],"species":366}],"party_address":3217188,"script_address":2332809},{"address":3243112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":332}],"party_address":3217220,"script_address":2050594},{"address":3243152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3217228,"script_address":2050625},{"address":3243192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":287}],"party_address":3217236,"script_address":0},{"address":3243232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":305},{"level":30,"species":287}],"party_address":3217244,"script_address":0},{"address":3243272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":305},{"level":29,"species":289},{"level":33,"species":287}],"party_address":3217260,"script_address":0},{"address":3243312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":32,"species":289},{"level":36,"species":287}],"party_address":3217284,"script_address":0},{"address":3243352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":16,"species":288}],"party_address":3217308,"script_address":2553792},{"address":3243392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":3,"species":304}],"party_address":3217324,"script_address":2024926},{"address":3243432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":382},{"level":13,"species":337}],"party_address":3217340,"script_address":2039000},{"address":3243472,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[240,67,38,59],"species":314},{"level":55,"moves":[92,56,188,58],"species":73},{"level":56,"moves":[202,57,73,104],"species":297},{"level":56,"moves":[89,57,133,63],"species":324},{"level":56,"moves":[93,89,63,57],"species":130},{"level":58,"moves":[105,57,58,92],"species":329}],"party_address":3217356,"script_address":2277575},{"address":3243512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":10,"species":72},{"level":15,"species":129}],"party_address":3217452,"script_address":2026322},{"address":3243552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":6,"species":129},{"level":7,"species":129}],"party_address":3217476,"script_address":2029653},{"address":3243592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":129},{"level":17,"species":118},{"level":18,"species":323}],"party_address":3217500,"script_address":2052185},{"address":3243632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":10,"species":129},{"level":7,"species":72},{"level":10,"species":129}],"party_address":3217524,"script_address":2034247},{"address":3243672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72}],"party_address":3217548,"script_address":2034357},{"address":3243712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72},{"level":14,"species":313},{"level":11,"species":72},{"level":14,"species":313}],"party_address":3217556,"script_address":2038546},{"address":3243752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3217588,"script_address":2052216},{"address":3243792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3217596,"script_address":2058894},{"address":3243832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":72}],"party_address":3217612,"script_address":2058925},{"address":3243872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":73}],"party_address":3217620,"script_address":2036183},{"address":3243912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":27,"species":130},{"level":27,"species":130}],"party_address":3217636,"script_address":0},{"address":3243952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":130},{"level":26,"species":330},{"level":26,"species":72},{"level":29,"species":130}],"party_address":3217660,"script_address":0},{"address":3243992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":130},{"level":30,"species":330},{"level":30,"species":73},{"level":31,"species":130}],"party_address":3217692,"script_address":0},{"address":3244032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":130},{"level":33,"species":331},{"level":33,"species":130},{"level":35,"species":73}],"party_address":3217724,"script_address":0},{"address":3244072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":129},{"level":21,"species":130},{"level":23,"species":130},{"level":26,"species":130},{"level":30,"species":130},{"level":35,"species":130}],"party_address":3217756,"script_address":2073670},{"address":3244112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":100},{"level":6,"species":100},{"level":14,"species":81}],"party_address":3217804,"script_address":2038577},{"address":3244152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81}],"party_address":3217828,"script_address":2038608},{"address":3244192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217844,"script_address":2038639},{"address":3244232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":81}],"party_address":3217852,"script_address":0},{"address":3244272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":81}],"party_address":3217860,"script_address":0},{"address":3244312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82}],"party_address":3217868,"script_address":0},{"address":3244352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":82}],"party_address":3217876,"script_address":0},{"address":3244392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217884,"script_address":2038780},{"address":3244432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81},{"level":6,"species":100}],"party_address":3217892,"script_address":2038749},{"address":3244472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81}],"party_address":3217916,"script_address":0},{"address":3244512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":81}],"party_address":3217924,"script_address":0},{"address":3244552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82}],"party_address":3217932,"script_address":0},{"address":3244592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":82}],"party_address":3217940,"script_address":0},{"address":3244632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217948,"script_address":2057375},{"address":3244672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217956,"script_address":0},{"address":3244712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3217964,"script_address":0},{"address":3244752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3217972,"script_address":0},{"address":3244792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3217980,"script_address":0},{"address":3244832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217988,"script_address":2057485},{"address":3244872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217996,"script_address":0},{"address":3244912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3218004,"script_address":0},{"address":3244952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3218012,"script_address":0},{"address":3244992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3218020,"script_address":0},{"address":3245032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218028,"script_address":2070582},{"address":3245072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":288},{"level":25,"species":337}],"party_address":3218044,"script_address":2340077},{"address":3245112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218060,"script_address":2071332},{"address":3245152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218068,"script_address":2070380},{"address":3245192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218084,"script_address":2072978},{"address":3245232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218100,"script_address":0},{"address":3245272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218108,"script_address":0},{"address":3245312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218116,"script_address":0},{"address":3245352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218124,"script_address":0},{"address":3245392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218132,"script_address":2070318},{"address":3245432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218140,"script_address":2070613},{"address":3245472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218156,"script_address":2073545},{"address":3245512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218164,"script_address":2071442},{"address":3245552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":309},{"level":33,"species":120}],"party_address":3218172,"script_address":2073009},{"address":3245592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218188,"script_address":0},{"address":3245632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218196,"script_address":0},{"address":3245672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218204,"script_address":0},{"address":3245712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218212,"script_address":0},{"address":3245752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":359},{"level":37,"species":359}],"party_address":3218220,"script_address":2292701},{"address":3245792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":359}],"party_address":3218236,"script_address":0},{"address":3245832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":359},{"level":44,"species":359}],"party_address":3218252,"script_address":0},{"address":3245872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":395},{"level":46,"species":359},{"level":46,"species":359}],"party_address":3218268,"script_address":0},{"address":3245912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":49,"species":359},{"level":49,"species":359},{"level":49,"species":396}],"party_address":3218292,"script_address":0},{"address":3245952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[225,29,116,52],"species":395}],"party_address":3218316,"script_address":2074182},{"address":3245992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309}],"party_address":3218332,"script_address":2059066},{"address":3246032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":369}],"party_address":3218340,"script_address":2061450},{"address":3246072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":305}],"party_address":3218356,"script_address":2061481},{"address":3246112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":84},{"level":27,"species":227},{"level":27,"species":369}],"party_address":3218364,"script_address":2202267},{"address":3246152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":227}],"party_address":3218388,"script_address":2202391},{"address":3246192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":369},{"level":33,"species":178}],"party_address":3218396,"script_address":2070085},{"address":3246232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":84},{"level":29,"species":310}],"party_address":3218412,"script_address":2202298},{"address":3246272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":309},{"level":28,"species":177}],"party_address":3218428,"script_address":2065338},{"address":3246312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":358}],"party_address":3218444,"script_address":2065369},{"address":3246352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":305},{"level":36,"species":310},{"level":36,"species":178}],"party_address":3218452,"script_address":2563257},{"address":3246392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":305}],"party_address":3218476,"script_address":2059097},{"address":3246432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":177},{"level":32,"species":358}],"party_address":3218492,"script_address":0},{"address":3246472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":177},{"level":35,"species":359}],"party_address":3218508,"script_address":0},{"address":3246512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":177},{"level":38,"species":359}],"party_address":3218524,"script_address":0},{"address":3246552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":178}],"party_address":3218540,"script_address":0},{"address":3246592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":177},{"level":33,"species":305}],"party_address":3218556,"script_address":2074151},{"address":3246632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":369}],"party_address":3218572,"script_address":2073981},{"address":3246672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302}],"party_address":3218580,"script_address":2061512},{"address":3246712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302},{"level":25,"species":109}],"party_address":3218588,"script_address":2061543},{"address":3246752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,89,0,0],"species":319},{"level":43,"moves":[85,89,0,0],"species":171}],"party_address":3218604,"script_address":2335578},{"address":3246792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3218636,"script_address":2341860},{"address":3246832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,124,120],"species":109}],"party_address":3218644,"script_address":2050766},{"address":3246872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":109},{"level":18,"species":302}],"party_address":3218692,"script_address":2050876},{"address":3246912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[139,33,124,120],"species":109},{"level":24,"moves":[139,33,124,0],"species":109},{"level":24,"moves":[139,33,124,120],"species":109},{"level":26,"moves":[33,124,0,0],"species":109}],"party_address":3218708,"script_address":0},{"address":3246952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,0],"species":109},{"level":29,"moves":[33,124,0,0],"species":109}],"party_address":3218772,"script_address":0},{"address":3246992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":32,"moves":[33,124,0,0],"species":109}],"party_address":3218836,"script_address":0},{"address":3247032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[139,33,124,0],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":35,"moves":[33,124,0,0],"species":110}],"party_address":3218900,"script_address":0},{"address":3247072,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218964,"script_address":2095313},{"address":3247112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218972,"script_address":2095351},{"address":3247152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":335}],"party_address":3218980,"script_address":2053062},{"address":3247192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":356}],"party_address":3218996,"script_address":2557727},{"address":3247232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3219004,"script_address":2557789},{"address":3247272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3219012,"script_address":0},{"address":3247312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":356},{"level":29,"species":335}],"party_address":3219028,"script_address":0},{"address":3247352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":357},{"level":32,"species":336}],"party_address":3219044,"script_address":0},{"address":3247392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":357},{"level":35,"species":336}],"party_address":3219060,"script_address":0},{"address":3247432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":19,"moves":[52,33,222,241],"species":339}],"party_address":3219076,"script_address":2050656},{"address":3247472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":363},{"level":28,"species":313}],"party_address":3219092,"script_address":2065713},{"address":3247512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[240,55,87,96],"species":385}],"party_address":3219108,"script_address":2065744},{"address":3247552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[52,33,222,241],"species":339}],"party_address":3219124,"script_address":0},{"address":3247592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[52,36,222,241],"species":339}],"party_address":3219140,"script_address":0},{"address":3247632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[73,72,64,241],"species":363},{"level":34,"moves":[53,36,222,241],"species":339}],"party_address":3219156,"script_address":0},{"address":3247672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[73,202,76,241],"species":363},{"level":37,"moves":[53,36,89,241],"species":340}],"party_address":3219188,"script_address":0},{"address":3247712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":313}],"party_address":3219220,"script_address":2033633},{"address":3247752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3219236,"script_address":2033664},{"address":3247792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":313}],"party_address":3219244,"script_address":2034216},{"address":3247832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":118}],"party_address":3219252,"script_address":2034620},{"address":3247872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219268,"script_address":2034651},{"address":3247912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":116},{"level":25,"species":183}],"party_address":3219276,"script_address":2034838},{"address":3247952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219292,"script_address":2034869},{"address":3247992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":118},{"level":24,"species":309},{"level":24,"species":118}],"party_address":3219300,"script_address":2035808},{"address":3248032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3219324,"script_address":2069240},{"address":3248072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":183}],"party_address":3219332,"script_address":2069350},{"address":3248112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219340,"script_address":2069851},{"address":3248152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219348,"script_address":2069882},{"address":3248192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":183},{"level":33,"species":341}],"party_address":3219356,"script_address":2070225},{"address":3248232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":118}],"party_address":3219372,"script_address":2070256},{"address":3248272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":118},{"level":33,"species":341}],"party_address":3219380,"script_address":2073260},{"address":3248312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219396,"script_address":2073421},{"address":3248352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219404,"script_address":2073452},{"address":3248392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":184}],"party_address":3219412,"script_address":2073639},{"address":3248432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219420,"script_address":2070349},{"address":3248472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219436,"script_address":2073888},{"address":3248512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":116},{"level":33,"species":117}],"party_address":3219444,"script_address":2073919},{"address":3248552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":171},{"level":34,"species":310}],"party_address":3219460,"script_address":0},{"address":3248592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219476,"script_address":2074120},{"address":3248632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":119}],"party_address":3219492,"script_address":2071676},{"address":3248672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":313}],"party_address":3219500,"script_address":0},{"address":3248712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":313}],"party_address":3219508,"script_address":0},{"address":3248752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":120},{"level":43,"species":313}],"party_address":3219516,"script_address":0},{"address":3248792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":313},{"level":45,"species":121}],"party_address":3219532,"script_address":0},{"address":3248832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[91,28,40,163],"species":27},{"level":22,"moves":[229,189,60,61],"species":318}],"party_address":3219556,"script_address":2046397},{"address":3248872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[28,40,163,91],"species":27},{"level":22,"moves":[205,61,39,111],"species":183}],"party_address":3219588,"script_address":2046459},{"address":3248912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":304},{"level":17,"species":296}],"party_address":3219620,"script_address":2049860},{"address":3248952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":183},{"level":18,"species":296}],"party_address":3219636,"script_address":2051934},{"address":3248992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":315},{"level":23,"species":358}],"party_address":3219652,"script_address":2557036},{"address":3249032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":306},{"level":19,"species":43},{"level":19,"species":358}],"party_address":3219668,"script_address":2310092},{"address":3249072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[194,219,68,243],"species":202}],"party_address":3219692,"script_address":2315855},{"address":3249112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":306},{"level":17,"species":183}],"party_address":3219708,"script_address":2046631},{"address":3249152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":306},{"level":25,"species":44},{"level":25,"species":358}],"party_address":3219724,"script_address":0},{"address":3249192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":307},{"level":28,"species":44},{"level":28,"species":358}],"party_address":3219748,"script_address":0},{"address":3249232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307},{"level":31,"species":44},{"level":31,"species":358}],"party_address":3219772,"script_address":0},{"address":3249272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":307},{"level":40,"species":45},{"level":40,"species":359}],"party_address":3219796,"script_address":0},{"address":3249312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":353},{"level":15,"species":354}],"party_address":3219820,"script_address":0},{"address":3249352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":353},{"level":27,"species":354}],"party_address":3219836,"script_address":0},{"address":3249392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":298},{"level":6,"species":295}],"party_address":3219852,"script_address":0},{"address":3249432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":292},{"level":26,"species":294}],"party_address":3219868,"script_address":0},{"address":3249472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":353},{"level":9,"species":354}],"party_address":3219884,"script_address":0},{"address":3249512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[101,50,0,0],"species":361},{"level":10,"moves":[71,73,0,0],"species":306}],"party_address":3219900,"script_address":0},{"address":3249552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":353},{"level":30,"species":354}],"party_address":3219932,"script_address":0},{"address":3249592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[209,12,57,14],"species":353},{"level":33,"moves":[209,12,204,14],"species":354}],"party_address":3219948,"script_address":0},{"address":3249632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,12,57,14],"species":353},{"level":36,"moves":[87,12,204,14],"species":354}],"party_address":3219980,"script_address":0},{"address":3249672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":309},{"level":12,"species":66}],"party_address":3220012,"script_address":2035839},{"address":3249712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309}],"party_address":3220028,"script_address":2035870},{"address":3249752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":67}],"party_address":3220036,"script_address":2069913},{"address":3249792,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":66},{"level":11,"species":72}],"party_address":3220052,"script_address":2543939},{"address":3249832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":73},{"level":44,"species":67}],"party_address":3220076,"script_address":2360255},{"address":3249872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":66},{"level":43,"species":310},{"level":43,"species":67}],"party_address":3220092,"script_address":2360286},{"address":3249912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":341},{"level":25,"species":67}],"party_address":3220116,"script_address":2340984},{"address":3249952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":309},{"level":36,"species":72},{"level":36,"species":67}],"party_address":3220132,"script_address":0},{"address":3249992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":310},{"level":39,"species":72},{"level":39,"species":67}],"party_address":3220156,"script_address":0},{"address":3250032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":310},{"level":42,"species":72},{"level":42,"species":67}],"party_address":3220180,"script_address":0},{"address":3250072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":310},{"level":45,"species":67},{"level":45,"species":73}],"party_address":3220204,"script_address":0},{"address":3250112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3220228,"script_address":2103632},{"address":3250152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[175,96,216,213],"species":328},{"level":39,"moves":[175,96,216,213],"species":328}],"party_address":3220236,"script_address":2265863},{"address":3250192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":376}],"party_address":3220268,"script_address":2068647},{"address":3250232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[92,87,120,188],"species":109}],"party_address":3220276,"script_address":2068616},{"address":3250272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[241,55,53,76],"species":385}],"party_address":3220292,"script_address":2068585},{"address":3250312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":338},{"level":33,"species":68}],"party_address":3220308,"script_address":2070116},{"address":3250352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":341}],"party_address":3220324,"script_address":2074337},{"address":3250392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[44,46,86,85],"species":338}],"party_address":3220340,"script_address":2074306},{"address":3250432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":356},{"level":33,"species":336}],"party_address":3220356,"script_address":2074275},{"address":3250472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3220372,"script_address":2074244},{"address":3250512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":170},{"level":33,"species":336}],"party_address":3220380,"script_address":2074043},{"address":3250552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":296},{"level":14,"species":299}],"party_address":3220396,"script_address":2038436},{"address":3250592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":380},{"level":18,"species":379}],"party_address":3220412,"script_address":2053172},{"address":3250632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":340},{"level":38,"species":287},{"level":40,"species":42}],"party_address":3220428,"script_address":0},{"address":3250672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":299}],"party_address":3220452,"script_address":0},{"address":3250712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":299}],"party_address":3220468,"script_address":0},{"address":3250752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":299}],"party_address":3220484,"script_address":0},{"address":3250792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":297},{"level":35,"species":300}],"party_address":3220500,"script_address":0},{"address":3250832,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[76,219,225,93],"species":359},{"level":43,"moves":[47,18,204,185],"species":316},{"level":44,"moves":[89,73,202,92],"species":363},{"level":41,"moves":[48,85,161,103],"species":82},{"level":45,"moves":[104,91,94,248],"species":394}],"party_address":3220516,"script_address":2332529},{"address":3250872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220596,"script_address":2025759},{"address":3250912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309},{"level":20,"species":278}],"party_address":3220604,"script_address":2039798},{"address":3250952,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310},{"level":31,"species":278}],"party_address":3220628,"script_address":2060578},{"address":3250992,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220652,"script_address":2025703},{"address":3251032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220660,"script_address":2039742},{"address":3251072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220684,"script_address":2060522},{"address":3251112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220708,"script_address":2025731},{"address":3251152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220716,"script_address":2039770},{"address":3251192,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220740,"script_address":2060550},{"address":3251232,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220764,"script_address":2025675},{"address":3251272,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":218},{"level":20,"species":278}],"party_address":3220772,"script_address":2039622},{"address":3251312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":296},{"level":31,"species":278}],"party_address":3220796,"script_address":2060420},{"address":3251352,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220820,"script_address":2025619},{"address":3251392,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220828,"script_address":2039566},{"address":3251432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220852,"script_address":2060364},{"address":3251472,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220876,"script_address":2025647},{"address":3251512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220884,"script_address":2039594},{"address":3251552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220908,"script_address":2060392},{"address":3251592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":370},{"level":11,"species":288},{"level":11,"species":382},{"level":11,"species":286},{"level":11,"species":304},{"level":11,"species":335}],"party_address":3220932,"script_address":2057155},{"address":3251632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":127}],"party_address":3220980,"script_address":2068678},{"address":3251672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[153,115,113,94],"species":348},{"level":43,"moves":[153,115,113,247],"species":349}],"party_address":3220988,"script_address":2334468},{"address":3251712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":371},{"level":22,"species":289},{"level":22,"species":382},{"level":22,"species":287},{"level":22,"species":305},{"level":22,"species":335}],"party_address":3221020,"script_address":0},{"address":3251752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":371},{"level":25,"species":289},{"level":25,"species":382},{"level":25,"species":287},{"level":25,"species":305},{"level":25,"species":336}],"party_address":3221068,"script_address":0},{"address":3251792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":371},{"level":28,"species":289},{"level":28,"species":382},{"level":28,"species":287},{"level":28,"species":305},{"level":28,"species":336}],"party_address":3221116,"script_address":0},{"address":3251832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":371},{"level":31,"species":289},{"level":31,"species":383},{"level":31,"species":287},{"level":31,"species":305},{"level":31,"species":336}],"party_address":3221164,"script_address":0},{"address":3251872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":306},{"level":11,"species":183},{"level":11,"species":363},{"level":11,"species":315},{"level":11,"species":118}],"party_address":3221212,"script_address":2057265},{"address":3251912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":322},{"level":43,"species":376}],"party_address":3221260,"script_address":2334499},{"address":3251952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":28}],"party_address":3221276,"script_address":2341891},{"address":3251992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":309},{"level":22,"species":306},{"level":22,"species":183},{"level":22,"species":363},{"level":22,"species":315},{"level":22,"species":118}],"party_address":3221284,"script_address":0},{"address":3252032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":310},{"level":25,"species":307},{"level":25,"species":183},{"level":25,"species":363},{"level":25,"species":316},{"level":25,"species":118}],"party_address":3221332,"script_address":0},{"address":3252072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":310},{"level":28,"species":307},{"level":28,"species":183},{"level":28,"species":363},{"level":28,"species":316},{"level":28,"species":118}],"party_address":3221380,"script_address":0},{"address":3252112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":310},{"level":31,"species":307},{"level":31,"species":184},{"level":31,"species":363},{"level":31,"species":316},{"level":31,"species":119}],"party_address":3221428,"script_address":0},{"address":3252152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3221476,"script_address":2061230},{"address":3252192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":298},{"level":28,"species":299},{"level":28,"species":296}],"party_address":3221484,"script_address":2065479},{"address":3252232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":345}],"party_address":3221508,"script_address":2563288},{"address":3252272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307}],"party_address":3221516,"script_address":0},{"address":3252312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307}],"party_address":3221524,"script_address":0},{"address":3252352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":307}],"party_address":3221532,"script_address":0},{"address":3252392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":317},{"level":39,"species":307}],"party_address":3221540,"script_address":0},{"address":3252432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":44},{"level":26,"species":363}],"party_address":3221556,"script_address":2061340},{"address":3252472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":295},{"level":28,"species":296},{"level":28,"species":299}],"party_address":3221572,"script_address":2065510},{"address":3252512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":358},{"level":38,"species":363}],"party_address":3221596,"script_address":2563226},{"address":3252552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":44},{"level":30,"species":363}],"party_address":3221612,"script_address":0},{"address":3252592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":44},{"level":33,"species":363}],"party_address":3221628,"script_address":0},{"address":3252632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":44},{"level":36,"species":363}],"party_address":3221644,"script_address":0},{"address":3252672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":182},{"level":39,"species":363}],"party_address":3221660,"script_address":0},{"address":3252712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":81}],"party_address":3221676,"script_address":2310306},{"address":3252752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":287},{"level":35,"species":42}],"party_address":3221684,"script_address":2327187},{"address":3252792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":313},{"level":31,"species":41}],"party_address":3221700,"script_address":0},{"address":3252832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":30,"species":41}],"party_address":3221716,"script_address":2317615},{"address":3252872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":286},{"level":22,"species":339}],"party_address":3221732,"script_address":2309993},{"address":3252912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3221748,"script_address":2188216},{"address":3252952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3221764,"script_address":2095389},{"address":3252992,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3221772,"script_address":2095465},{"address":3253032,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":335}],"party_address":3221780,"script_address":2095427},{"address":3253072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":356}],"party_address":3221788,"script_address":2244674},{"address":3253112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3221796,"script_address":2070287},{"address":3253152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[87,86,98,0],"species":338},{"level":32,"moves":[57,168,0,0],"species":289}],"party_address":3221804,"script_address":2070768},{"address":3253192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":73}],"party_address":3221836,"script_address":2071645},{"address":3253232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":41}],"party_address":3221844,"script_address":2304070},{"address":3253272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3221852,"script_address":2073102},{"address":3253312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":203}],"party_address":3221860,"script_address":0},{"address":3253352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":351}],"party_address":3221868,"script_address":2244705},{"address":3253392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3221876,"script_address":2244829},{"address":3253432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3221884,"script_address":2244767},{"address":3253472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":202}],"party_address":3221892,"script_address":2244798},{"address":3253512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":286}],"party_address":3221900,"script_address":2254605},{"address":3253552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221916,"script_address":2254667},{"address":3253592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3221924,"script_address":2257768},{"address":3253632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":287}],"party_address":3221932,"script_address":2257818},{"address":3253672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221940,"script_address":2257868},{"address":3253712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":177}],"party_address":3221948,"script_address":2244736},{"address":3253752,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3221956,"script_address":1978559},{"address":3253792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3221972,"script_address":1978621},{"address":3253832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":305},{"level":33,"species":307}],"party_address":3221988,"script_address":2073732},{"address":3253872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3222004,"script_address":2069651},{"address":3253912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3222012,"script_address":2572062},{"address":3253952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":20,"species":286},{"level":22,"species":339},{"level":22,"species":41}],"party_address":3222028,"script_address":2304039},{"address":3253992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":317},{"level":33,"species":371}],"party_address":3222060,"script_address":2073794},{"address":3254032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":218},{"level":15,"species":283}],"party_address":3222076,"script_address":1978590},{"address":3254072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3222092,"script_address":1978317},{"address":3254112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":287},{"level":38,"species":169},{"level":39,"species":340}],"party_address":3222108,"script_address":2351441},{"address":3254152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":287},{"level":24,"species":41},{"level":25,"species":340}],"party_address":3222132,"script_address":2303440},{"address":3254192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":4,"species":306}],"party_address":3222156,"script_address":2024895},{"address":3254232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":295},{"level":6,"species":306}],"party_address":3222172,"script_address":2029715},{"address":3254272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":183}],"party_address":3222188,"script_address":2054459},{"address":3254312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183},{"level":15,"species":306},{"level":15,"species":339}],"party_address":3222196,"script_address":2045995},{"address":3254352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":306}],"party_address":3222220,"script_address":0},{"address":3254392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":307}],"party_address":3222236,"script_address":0},{"address":3254432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":307}],"party_address":3222252,"script_address":0},{"address":3254472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":296},{"level":34,"species":307}],"party_address":3222268,"script_address":0},{"address":3254512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":43}],"party_address":3222292,"script_address":2553761},{"address":3254552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":315},{"level":14,"species":306},{"level":14,"species":183}],"party_address":3222300,"script_address":2553823},{"address":3254592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325}],"party_address":3222324,"script_address":2265615},{"address":3254632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":118},{"level":39,"species":313}],"party_address":3222332,"script_address":2265646},{"address":3254672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":290},{"level":4,"species":290}],"party_address":3222348,"script_address":2024864},{"address":3254712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290}],"party_address":3222364,"script_address":2300392},{"address":3254752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":290},{"level":8,"species":301}],"party_address":3222396,"script_address":2054211},{"address":3254792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":301},{"level":28,"species":302}],"party_address":3222412,"script_address":2061137},{"address":3254832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222428,"script_address":2061168},{"address":3254872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302}],"party_address":3222444,"script_address":2061199},{"address":3254912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":301},{"level":6,"species":301}],"party_address":3222452,"script_address":2300423},{"address":3254952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":302}],"party_address":3222468,"script_address":0},{"address":3254992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":302}],"party_address":3222476,"script_address":0},{"address":3255032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":294},{"level":31,"species":302}],"party_address":3222492,"script_address":0},{"address":3255072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":311},{"level":33,"species":302},{"level":33,"species":294},{"level":33,"species":302}],"party_address":3222516,"script_address":0},{"address":3255112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":339},{"level":17,"species":66}],"party_address":3222548,"script_address":2049688},{"address":3255152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":17,"species":74},{"level":16,"species":74}],"party_address":3222564,"script_address":2049719},{"address":3255192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":66}],"party_address":3222588,"script_address":2051841},{"address":3255232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":339}],"party_address":3222604,"script_address":2051872},{"address":3255272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":74},{"level":22,"species":320},{"level":22,"species":75}],"party_address":3222620,"script_address":2557067},{"address":3255312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74}],"party_address":3222644,"script_address":2054428},{"address":3255352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":74},{"level":20,"species":318}],"party_address":3222652,"script_address":2310061},{"address":3255392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":9,"moves":[150,55,0,0],"species":313}],"party_address":3222668,"script_address":0},{"address":3255432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[16,45,0,0],"species":310},{"level":10,"moves":[44,184,0,0],"species":286}],"party_address":3222684,"script_address":0},{"address":3255472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":16,"species":74},{"level":16,"species":66}],"party_address":3222716,"script_address":2296023},{"address":3255512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":75}],"party_address":3222740,"script_address":0},{"address":3255552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":74},{"level":27,"species":74},{"level":27,"species":75},{"level":27,"species":75}],"party_address":3222772,"script_address":0},{"address":3255592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":74},{"level":30,"species":75},{"level":30,"species":75},{"level":30,"species":75}],"party_address":3222804,"script_address":0},{"address":3255632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":76}],"party_address":3222836,"script_address":0},{"address":3255672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":316},{"level":31,"species":338}],"party_address":3222868,"script_address":0},{"address":3255712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":325}],"party_address":3222884,"script_address":0},{"address":3255752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222900,"script_address":0},{"address":3255792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":386},{"level":30,"species":387}],"party_address":3222916,"script_address":0},{"address":3255832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":386},{"level":33,"species":387}],"party_address":3222932,"script_address":0},{"address":3255872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":386},{"level":36,"species":387}],"party_address":3222948,"script_address":0},{"address":3255912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":386},{"level":39,"species":387}],"party_address":3222964,"script_address":0},{"address":3255952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":118}],"party_address":3222980,"script_address":2543970},{"address":3255992,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[53,154,185,20],"species":317}],"party_address":3222988,"script_address":2103539},{"address":3256032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[117,197,93,9],"species":356},{"level":17,"moves":[9,197,93,96],"species":356}],"party_address":3223004,"script_address":2167701},{"address":3256072,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[117,197,93,7],"species":356}],"party_address":3223036,"script_address":2103508},{"address":3256112,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[33,120,124,108],"species":109},{"level":25,"moves":[33,139,124,108],"species":109}],"party_address":3223052,"script_address":2061574},{"address":3256152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[139,120,124,108],"species":109},{"level":28,"moves":[28,104,210,14],"species":302}],"party_address":3223084,"script_address":2065775},{"address":3256192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[141,154,170,91],"species":301},{"level":28,"moves":[33,120,124,108],"species":109}],"party_address":3223116,"script_address":2065806},{"address":3256232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":305},{"level":29,"species":178}],"party_address":3223148,"script_address":2202329},{"address":3256272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":358},{"level":27,"species":358},{"level":27,"species":358}],"party_address":3223164,"script_address":2202360},{"address":3256312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":392}],"party_address":3223188,"script_address":1971405},{"address":3256352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[76,219,225,93],"species":359},{"level":46,"moves":[47,18,204,185],"species":316},{"level":47,"moves":[89,73,202,92],"species":363},{"level":44,"moves":[48,85,161,103],"species":82},{"level":48,"moves":[104,91,94,248],"species":394}],"party_address":3223196,"script_address":2332607},{"address":3256392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[76,219,225,93],"species":359},{"level":49,"moves":[47,18,204,185],"species":316},{"level":50,"moves":[89,73,202,92],"species":363},{"level":47,"moves":[48,85,161,103],"species":82},{"level":51,"moves":[104,91,94,248],"species":394}],"party_address":3223276,"script_address":0},{"address":3256432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[76,219,225,93],"species":359},{"level":52,"moves":[47,18,204,185],"species":316},{"level":53,"moves":[89,73,202,92],"species":363},{"level":50,"moves":[48,85,161,103],"species":82},{"level":54,"moves":[104,91,94,248],"species":394}],"party_address":3223356,"script_address":0},{"address":3256472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[76,219,225,93],"species":359},{"level":55,"moves":[47,18,204,185],"species":316},{"level":56,"moves":[89,73,202,92],"species":363},{"level":53,"moves":[48,85,161,103],"species":82},{"level":57,"moves":[104,91,94,248],"species":394}],"party_address":3223436,"script_address":0},{"address":3256512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223516,"script_address":1986165},{"address":3256552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223548,"script_address":1986109},{"address":3256592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223580,"script_address":1986137},{"address":3256632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223612,"script_address":1986081},{"address":3256672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223644,"script_address":1986025},{"address":3256712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223676,"script_address":1986053},{"address":3256752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":31,"species":72},{"level":32,"species":331}],"party_address":3223708,"script_address":2070644},{"address":3256792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":34,"species":73}],"party_address":3223732,"script_address":2070675},{"address":3256832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":129},{"level":25,"species":129},{"level":35,"species":130}],"party_address":3223748,"script_address":2070706},{"address":3256872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":44},{"level":34,"species":184}],"party_address":3223772,"script_address":2071552},{"address":3256912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":300},{"level":34,"species":320}],"party_address":3223788,"script_address":2071583},{"address":3256952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":67}],"party_address":3223804,"script_address":2070799},{"address":3256992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":72},{"level":31,"species":72},{"level":36,"species":313}],"party_address":3223812,"script_address":2071614},{"address":3257032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":305},{"level":32,"species":227}],"party_address":3223836,"script_address":2070737},{"address":3257072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":341},{"level":33,"species":331}],"party_address":3223852,"script_address":2073040},{"address":3257112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170}],"party_address":3223868,"script_address":2073071},{"address":3257152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":308},{"level":19,"species":308}],"party_address":3223876,"script_address":0},{"address":3257192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[47,31,219,76],"species":358},{"level":35,"moves":[53,36,156,89],"species":339}],"party_address":3223892,"script_address":0},{"address":3257232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[74,78,72,73],"species":363},{"level":20,"moves":[111,205,44,88],"species":75}],"party_address":3223924,"script_address":0},{"address":3257272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[16,60,92,182],"species":294},{"level":27,"moves":[16,72,213,78],"species":292}],"party_address":3223956,"script_address":0},{"address":3257312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[94,7,244,182],"species":357},{"level":39,"moves":[8,61,156,187],"species":336}],"party_address":3223988,"script_address":0},{"address":3257352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,7,244,182],"species":357},{"level":43,"moves":[8,61,156,187],"species":336}],"party_address":3224020,"script_address":0},{"address":3257392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[94,7,244,182],"species":357},{"level":46,"moves":[8,61,156,187],"species":336}],"party_address":3224052,"script_address":0},{"address":3257432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":49,"moves":[94,7,244,182],"species":357},{"level":49,"moves":[8,61,156,187],"species":336}],"party_address":3224084,"script_address":0},{"address":3257472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[94,7,244,182],"species":357},{"level":52,"moves":[8,61,156,187],"species":336}],"party_address":3224116,"script_address":0},{"address":3257512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":33,"species":309}],"party_address":3224148,"script_address":0},{"address":3257552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170},{"level":33,"species":330}],"party_address":3224164,"script_address":0},{"address":3257592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":170},{"level":40,"species":330}],"party_address":3224180,"script_address":0},{"address":3257632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":171},{"level":43,"species":330}],"party_address":3224196,"script_address":0},{"address":3257672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":171},{"level":46,"species":331}],"party_address":3224212,"script_address":0},{"address":3257712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":51,"species":171},{"level":49,"species":331}],"party_address":3224228,"script_address":0},{"address":3257752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":118},{"level":25,"species":72}],"party_address":3224244,"script_address":0},{"address":3257792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":129},{"level":20,"species":72},{"level":26,"species":328},{"level":23,"species":330}],"party_address":3224260,"script_address":2061605},{"address":3257832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":288},{"level":8,"species":286}],"party_address":3224292,"script_address":2054707},{"address":3257872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":295},{"level":8,"species":288}],"party_address":3224308,"script_address":2054676},{"address":3257912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":129}],"party_address":3224324,"script_address":2030343},{"address":3257952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":183}],"party_address":3224332,"script_address":2036307},{"address":3257992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":72},{"level":12,"species":72}],"party_address":3224340,"script_address":2036276},{"address":3258032,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":354},{"level":14,"species":353}],"party_address":3224356,"script_address":2039032},{"address":3258072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":337},{"level":14,"species":100}],"party_address":3224372,"script_address":2039063},{"address":3258112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81}],"party_address":3224388,"script_address":2039094},{"address":3258152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":100}],"party_address":3224396,"script_address":2026463},{"address":3258192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":335}],"party_address":3224404,"script_address":2026494},{"address":3258232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":27}],"party_address":3224412,"script_address":2046975},{"address":3258272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":363}],"party_address":3224420,"script_address":2047006},{"address":3258312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306}],"party_address":3224428,"script_address":2046944},{"address":3258352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339}],"party_address":3224436,"script_address":2046913},{"address":3258392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":183},{"level":19,"species":296}],"party_address":3224444,"script_address":2050969},{"address":3258432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":227},{"level":19,"species":305}],"party_address":3224460,"script_address":2051000},{"address":3258472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":318},{"level":18,"species":27}],"party_address":3224476,"script_address":2051031},{"address":3258512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":382},{"level":18,"species":382}],"party_address":3224492,"script_address":2051062},{"address":3258552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":183}],"party_address":3224508,"script_address":2052309},{"address":3258592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3224524,"script_address":2052371},{"address":3258632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":299}],"party_address":3224532,"script_address":2052340},{"address":3258672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":14,"species":382},{"level":14,"species":337}],"party_address":3224540,"script_address":2059128},{"address":3258712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224564,"script_address":2347841},{"address":3258752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224572,"script_address":2347872},{"address":3258792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224580,"script_address":2348597},{"address":3258832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":41}],"party_address":3224588,"script_address":2348628},{"address":3258872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":339}],"party_address":3224604,"script_address":2348659},{"address":3258912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224620,"script_address":2349324},{"address":3258952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224628,"script_address":2349355},{"address":3258992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224636,"script_address":2349386},{"address":3259032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224644,"script_address":2350264},{"address":3259072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224652,"script_address":2350826},{"address":3259112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224660,"script_address":2351566},{"address":3259152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224668,"script_address":2351597},{"address":3259192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224676,"script_address":2351628},{"address":3259232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224684,"script_address":2348566},{"address":3259272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224692,"script_address":2349293},{"address":3259312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224700,"script_address":2350295},{"address":3259352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":339},{"level":28,"species":287},{"level":30,"species":41},{"level":33,"species":340}],"party_address":3224708,"script_address":2351659},{"address":3259392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":310},{"level":33,"species":340}],"party_address":3224740,"script_address":2073763},{"address":3259432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":287},{"level":43,"species":169},{"level":44,"species":340}],"party_address":3224756,"script_address":0},{"address":3259472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":72}],"party_address":3224780,"script_address":2026525},{"address":3259512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183}],"party_address":3224788,"script_address":2026556},{"address":3259552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":27},{"level":25,"species":27}],"party_address":3224796,"script_address":2033726},{"address":3259592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":309}],"party_address":3224812,"script_address":2033695},{"address":3259632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":120}],"party_address":3224828,"script_address":2034744},{"address":3259672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":309},{"level":24,"species":66},{"level":24,"species":72}],"party_address":3224836,"script_address":2034931},{"address":3259712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":338},{"level":24,"species":305},{"level":24,"species":338}],"party_address":3224860,"script_address":2034900},{"address":3259752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":227},{"level":25,"species":227}],"party_address":3224884,"script_address":2036338},{"address":3259792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":183},{"level":22,"species":296}],"party_address":3224900,"script_address":2047037},{"address":3259832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":27},{"level":22,"species":28}],"party_address":3224916,"script_address":2047068},{"address":3259872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":304},{"level":22,"species":299}],"party_address":3224932,"script_address":2047099},{"address":3259912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":18,"species":218}],"party_address":3224948,"script_address":2049891},{"address":3259952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306},{"level":18,"species":363}],"party_address":3224964,"script_address":2049922},{"address":3259992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":84},{"level":26,"species":85}],"party_address":3224980,"script_address":2053203},{"address":3260032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302},{"level":26,"species":367}],"party_address":3224996,"script_address":2053234},{"address":3260072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":64},{"level":26,"species":393}],"party_address":3225012,"script_address":2053265},{"address":3260112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3225028,"script_address":2053296},{"address":3260152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":351}],"party_address":3225044,"script_address":2053327},{"address":3260192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3225060,"script_address":2054738},{"address":3260232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":306},{"level":8,"species":295}],"party_address":3225076,"script_address":2054769},{"address":3260272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3225092,"script_address":2057834},{"address":3260312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3225100,"script_address":2057865},{"address":3260352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":356}],"party_address":3225108,"script_address":2057896},{"address":3260392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":363},{"level":33,"species":357}],"party_address":3225116,"script_address":2073825},{"address":3260432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":338}],"party_address":3225132,"script_address":2061636},{"address":3260472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":218},{"level":25,"species":339}],"party_address":3225140,"script_address":2061667},{"address":3260512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3225156,"script_address":2061698},{"address":3260552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[87,98,86,0],"species":338}],"party_address":3225164,"script_address":2065837},{"address":3260592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":356},{"level":28,"species":335}],"party_address":3225180,"script_address":2065868},{"address":3260632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":292}],"party_address":3225196,"script_address":2067487},{"address":3260672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":335},{"level":25,"species":309},{"level":25,"species":369},{"level":25,"species":288},{"level":25,"species":337},{"level":25,"species":339}],"party_address":3225212,"script_address":2067518},{"address":3260712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":286},{"level":25,"species":306},{"level":25,"species":337},{"level":25,"species":183},{"level":25,"species":27},{"level":25,"species":367}],"party_address":3225260,"script_address":2067549},{"address":3260752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":371},{"level":29,"species":365}],"party_address":3225308,"script_address":2067611},{"address":3260792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3225324,"script_address":1978255},{"address":3260832,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":321},{"level":15,"species":283}],"party_address":3225340,"script_address":1978286},{"address":3260872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[182,205,222,153],"species":76},{"level":35,"moves":[14,58,57,157],"species":140},{"level":35,"moves":[231,153,46,157],"species":95},{"level":37,"moves":[104,153,182,157],"species":320}],"party_address":3225356,"script_address":0},{"address":3260912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[182,58,157,57],"species":138},{"level":37,"moves":[182,205,222,153],"species":76},{"level":40,"moves":[14,58,57,157],"species":141},{"level":40,"moves":[231,153,46,157],"species":95},{"level":42,"moves":[104,153,182,157],"species":320}],"party_address":3225420,"script_address":0},{"address":3260952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[182,58,157,57],"species":139},{"level":42,"moves":[182,205,89,153],"species":76},{"level":45,"moves":[14,58,57,157],"species":141},{"level":45,"moves":[231,153,46,157],"species":95},{"level":47,"moves":[104,153,182,157],"species":320}],"party_address":3225500,"script_address":0},{"address":3260992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[157,63,48,182],"species":142},{"level":47,"moves":[8,205,89,153],"species":76},{"level":47,"moves":[182,58,157,57],"species":139},{"level":50,"moves":[14,58,57,157],"species":141},{"level":50,"moves":[231,153,46,157],"species":208},{"level":52,"moves":[104,153,182,157],"species":320}],"party_address":3225580,"script_address":0},{"address":3261032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[2,157,8,83],"species":68},{"level":33,"moves":[94,113,115,8],"species":356},{"level":35,"moves":[228,68,182,167],"species":237},{"level":37,"moves":[252,8,187,89],"species":336}],"party_address":3225676,"script_address":0},{"address":3261072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[2,157,8,83],"species":68},{"level":38,"moves":[94,113,115,8],"species":357},{"level":40,"moves":[228,68,182,167],"species":237},{"level":42,"moves":[252,8,187,89],"species":336}],"party_address":3225740,"script_address":0},{"address":3261112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[71,182,7,8],"species":107},{"level":43,"moves":[2,157,8,83],"species":68},{"level":43,"moves":[8,113,115,94],"species":357},{"level":45,"moves":[228,68,182,167],"species":237},{"level":47,"moves":[252,8,187,89],"species":336}],"party_address":3225804,"script_address":0},{"address":3261152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[25,8,89,83],"species":106},{"level":46,"moves":[71,182,7,8],"species":107},{"level":48,"moves":[238,157,8,83],"species":68},{"level":48,"moves":[8,113,115,94],"species":357},{"level":50,"moves":[228,68,182,167],"species":237},{"level":52,"moves":[252,8,187,89],"species":336}],"party_address":3225884,"script_address":0},{"address":3261192,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,182,86,113],"species":179},{"level":36,"moves":[205,87,153,240],"species":101},{"level":38,"moves":[48,182,87,240],"species":82},{"level":40,"moves":[44,86,87,182],"species":338}],"party_address":3225980,"script_address":0},{"address":3261232,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[87,21,240,95],"species":25},{"level":41,"moves":[87,182,86,113],"species":180},{"level":41,"moves":[205,87,153,240],"species":101},{"level":43,"moves":[48,182,87,240],"species":82},{"level":45,"moves":[44,86,87,182],"species":338}],"party_address":3226044,"script_address":0},{"address":3261272,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[87,21,240,182],"species":26},{"level":46,"moves":[87,182,86,113],"species":181},{"level":46,"moves":[205,87,153,240],"species":101},{"level":48,"moves":[48,182,87,240],"species":82},{"level":50,"moves":[44,86,87,182],"species":338}],"party_address":3226124,"script_address":0},{"address":3261312,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[129,8,9,113],"species":125},{"level":51,"moves":[87,21,240,182],"species":26},{"level":51,"moves":[87,182,86,113],"species":181},{"level":53,"moves":[205,87,153,240],"species":101},{"level":53,"moves":[48,182,87,240],"species":82},{"level":55,"moves":[44,86,87,182],"species":338}],"party_address":3226204,"script_address":0},{"address":3261352,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[59,213,113,157],"species":219},{"level":36,"moves":[53,213,76,84],"species":77},{"level":38,"moves":[59,241,89,213],"species":340},{"level":40,"moves":[59,241,153,213],"species":321}],"party_address":3226300,"script_address":0},{"address":3261392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[14,53,46,241],"species":58},{"level":43,"moves":[59,213,113,157],"species":219},{"level":41,"moves":[53,213,76,84],"species":77},{"level":43,"moves":[59,241,89,213],"species":340},{"level":45,"moves":[59,241,153,213],"species":321}],"party_address":3226364,"script_address":0},{"address":3261432,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,76,13,241],"species":228},{"level":46,"moves":[14,53,241,46],"species":58},{"level":48,"moves":[59,213,113,157],"species":219},{"level":46,"moves":[53,213,76,84],"species":78},{"level":48,"moves":[59,241,89,213],"species":340},{"level":50,"moves":[59,241,153,213],"species":321}],"party_address":3226444,"script_address":0},{"address":3261472,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":51,"moves":[14,53,241,46],"species":59},{"level":53,"moves":[59,213,113,157],"species":219},{"level":51,"moves":[46,76,13,241],"species":229},{"level":51,"moves":[53,213,76,84],"species":78},{"level":53,"moves":[59,241,89,213],"species":340},{"level":55,"moves":[59,241,153,213],"species":321}],"party_address":3226540,"script_address":0},{"address":3261512,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[113,47,29,8],"species":113},{"level":42,"moves":[59,247,38,126],"species":366},{"level":43,"moves":[42,29,7,95],"species":308},{"level":45,"moves":[63,53,85,247],"species":366}],"party_address":3226636,"script_address":0},{"address":3261552,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[59,247,38,126],"species":366},{"level":47,"moves":[113,47,29,8],"species":113},{"level":45,"moves":[252,146,203,179],"species":115},{"level":48,"moves":[42,29,7,95],"species":308},{"level":50,"moves":[63,53,85,247],"species":366}],"party_address":3226700,"script_address":0},{"address":3261592,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[59,247,38,126],"species":366},{"level":52,"moves":[113,47,29,8],"species":242},{"level":50,"moves":[252,146,203,179],"species":115},{"level":53,"moves":[42,29,7,95],"species":308},{"level":55,"moves":[63,53,85,247],"species":366}],"party_address":3226780,"script_address":0},{"address":3261632,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[59,247,38,126],"species":366},{"level":57,"moves":[182,47,29,8],"species":242},{"level":55,"moves":[252,146,203,179],"species":115},{"level":57,"moves":[36,182,126,89],"species":128},{"level":58,"moves":[42,29,7,95],"species":308},{"level":60,"moves":[63,53,85,247],"species":366}],"party_address":3226860,"script_address":0},{"address":3261672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[86,85,182,58],"species":147},{"level":38,"moves":[241,76,76,89],"species":369},{"level":41,"moves":[57,48,182,76],"species":310},{"level":43,"moves":[18,191,211,76],"species":227},{"level":45,"moves":[76,156,93,89],"species":359}],"party_address":3226956,"script_address":0},{"address":3261712,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[95,94,115,138],"species":163},{"level":43,"moves":[241,76,76,89],"species":369},{"level":45,"moves":[86,85,182,58],"species":148},{"level":46,"moves":[57,48,182,76],"species":310},{"level":48,"moves":[18,191,211,76],"species":227},{"level":50,"moves":[76,156,93,89],"species":359}],"party_address":3227036,"script_address":0},{"address":3261752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[95,94,115,138],"species":164},{"level":49,"moves":[241,76,76,89],"species":369},{"level":50,"moves":[86,85,182,58],"species":148},{"level":51,"moves":[57,48,182,76],"species":310},{"level":53,"moves":[18,191,211,76],"species":227},{"level":55,"moves":[76,156,93,89],"species":359}],"party_address":3227132,"script_address":0},{"address":3261792,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,94,115,138],"species":164},{"level":54,"moves":[241,76,76,89],"species":369},{"level":55,"moves":[57,48,182,76],"species":310},{"level":55,"moves":[63,85,89,58],"species":149},{"level":58,"moves":[18,191,211,76],"species":227},{"level":60,"moves":[143,156,93,89],"species":359}],"party_address":3227228,"script_address":0},{"address":3261832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[25,94,91,182],"species":79},{"level":49,"moves":[89,246,94,113],"species":319},{"level":49,"moves":[94,156,109,91],"species":178},{"level":50,"moves":[89,94,156,91],"species":348},{"level":50,"moves":[241,76,94,53],"species":349}],"party_address":3227324,"script_address":0},{"address":3261872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,138,29,182],"species":96},{"level":53,"moves":[25,94,91,182],"species":79},{"level":54,"moves":[89,153,94,113],"species":319},{"level":54,"moves":[94,156,109,91],"species":178},{"level":55,"moves":[89,94,156,91],"species":348},{"level":55,"moves":[241,76,94,53],"species":349}],"party_address":3227404,"script_address":0},{"address":3261912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":58,"moves":[95,138,29,182],"species":97},{"level":59,"moves":[89,153,94,113],"species":319},{"level":58,"moves":[25,94,91,182],"species":79},{"level":59,"moves":[94,156,109,91],"species":178},{"level":60,"moves":[89,94,156,91],"species":348},{"level":60,"moves":[241,76,94,53],"species":349}],"party_address":3227500,"script_address":0},{"address":3261952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":63,"moves":[95,138,29,182],"species":97},{"level":64,"moves":[89,153,94,113],"species":319},{"level":63,"moves":[25,94,91,182],"species":199},{"level":64,"moves":[94,156,109,91],"species":178},{"level":65,"moves":[89,94,156,91],"species":348},{"level":65,"moves":[241,76,94,53],"species":349}],"party_address":3227596,"script_address":0},{"address":3261992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[95,240,182,56],"species":60},{"level":46,"moves":[240,96,104,90],"species":324},{"level":48,"moves":[96,34,182,58],"species":343},{"level":48,"moves":[156,152,13,104],"species":327},{"level":51,"moves":[96,104,58,156],"species":230}],"party_address":3227692,"script_address":0},{"address":3262032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[95,240,182,56],"species":61},{"level":51,"moves":[240,96,104,90],"species":324},{"level":53,"moves":[96,34,182,58],"species":343},{"level":53,"moves":[156,12,13,104],"species":327},{"level":56,"moves":[96,104,58,156],"species":230}],"party_address":3227772,"script_address":0},{"address":3262072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[56,195,58,109],"species":131},{"level":58,"moves":[240,96,104,90],"species":324},{"level":56,"moves":[95,240,182,56],"species":61},{"level":58,"moves":[96,34,182,58],"species":343},{"level":58,"moves":[156,12,13,104],"species":327},{"level":61,"moves":[96,104,58,156],"species":230}],"party_address":3227852,"script_address":0},{"address":3262112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":61,"moves":[56,195,58,109],"species":131},{"level":63,"moves":[240,96,104,90],"species":324},{"level":61,"moves":[95,240,56,195],"species":186},{"level":63,"moves":[96,34,182,73],"species":343},{"level":63,"moves":[156,12,13,104],"species":327},{"level":66,"moves":[96,104,58,156],"species":230}],"party_address":3227948,"script_address":0},{"address":3262152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[95,98,204,0],"species":387},{"level":17,"moves":[95,98,109,0],"species":386}],"party_address":3228044,"script_address":2167732},{"address":3262192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":369}],"party_address":3228076,"script_address":2202422},{"address":3262232,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":77,"moves":[92,76,191,211],"species":227},{"level":75,"moves":[115,113,246,89],"species":319},{"level":76,"moves":[87,89,76,81],"species":384},{"level":76,"moves":[202,246,19,109],"species":389},{"level":76,"moves":[96,246,76,163],"species":391},{"level":78,"moves":[89,94,53,247],"species":400}],"party_address":3228084,"script_address":2354502},{"address":3262272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228180,"script_address":0},{"address":3262312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228188,"script_address":0},{"address":3262352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228196,"script_address":0},{"address":3262392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228204,"script_address":0},{"address":3262432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228212,"script_address":0},{"address":3262472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228220,"script_address":0},{"address":3262512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228228,"script_address":0},{"address":3262552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":27}],"party_address":3228236,"script_address":0},{"address":3262592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":320},{"level":33,"species":27},{"level":33,"species":27}],"party_address":3228252,"script_address":0},{"address":3262632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":320},{"level":35,"species":27},{"level":35,"species":27}],"party_address":3228276,"script_address":0},{"address":3262672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":320},{"level":37,"species":28},{"level":37,"species":28}],"party_address":3228300,"script_address":0},{"address":3262712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":309},{"level":30,"species":66},{"level":30,"species":72}],"party_address":3228324,"script_address":0},{"address":3262752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":66},{"level":32,"species":72}],"party_address":3228348,"script_address":0},{"address":3262792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":66},{"level":34,"species":73}],"party_address":3228372,"script_address":0},{"address":3262832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":310},{"level":36,"species":67},{"level":36,"species":73}],"party_address":3228396,"script_address":0},{"address":3262872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":120},{"level":37,"species":120}],"party_address":3228420,"script_address":0},{"address":3262912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":309},{"level":39,"species":120},{"level":39,"species":120}],"party_address":3228436,"script_address":0},{"address":3262952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":310},{"level":41,"species":120},{"level":41,"species":120}],"party_address":3228460,"script_address":0},{"address":3262992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":310},{"level":43,"species":121},{"level":43,"species":121}],"party_address":3228484,"script_address":0},{"address":3263032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":67},{"level":37,"species":67}],"party_address":3228508,"script_address":0},{"address":3263072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":335},{"level":39,"species":67},{"level":39,"species":67}],"party_address":3228524,"script_address":0},{"address":3263112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":336},{"level":41,"species":67},{"level":41,"species":67}],"party_address":3228548,"script_address":0},{"address":3263152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":336},{"level":43,"species":68},{"level":43,"species":68}],"party_address":3228572,"script_address":0},{"address":3263192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":371},{"level":35,"species":365}],"party_address":3228596,"script_address":0},{"address":3263232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":308},{"level":37,"species":371},{"level":37,"species":365}],"party_address":3228612,"script_address":0},{"address":3263272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":308},{"level":39,"species":371},{"level":39,"species":365}],"party_address":3228636,"script_address":0},{"address":3263312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":308},{"level":41,"species":372},{"level":41,"species":366}],"party_address":3228660,"script_address":0},{"address":3263352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":337},{"level":35,"species":337},{"level":35,"species":371}],"party_address":3228684,"script_address":0},{"address":3263392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":337},{"level":37,"species":338},{"level":37,"species":371}],"party_address":3228708,"script_address":0},{"address":3263432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":338},{"level":39,"species":338},{"level":39,"species":371}],"party_address":3228732,"script_address":0},{"address":3263472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":338},{"level":41,"species":338},{"level":41,"species":372}],"party_address":3228756,"script_address":0},{"address":3263512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":74},{"level":26,"species":339}],"party_address":3228780,"script_address":0},{"address":3263552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":66},{"level":28,"species":339},{"level":28,"species":75}],"party_address":3228796,"script_address":0},{"address":3263592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":66},{"level":30,"species":339},{"level":30,"species":75}],"party_address":3228820,"script_address":0},{"address":3263632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":340},{"level":33,"species":76}],"party_address":3228844,"script_address":0},{"address":3263672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":315},{"level":31,"species":287},{"level":31,"species":288},{"level":31,"species":295},{"level":31,"species":298},{"level":31,"species":304}],"party_address":3228868,"script_address":0},{"address":3263712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":315},{"level":33,"species":287},{"level":33,"species":289},{"level":33,"species":296},{"level":33,"species":299},{"level":33,"species":304}],"party_address":3228916,"script_address":0},{"address":3263752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316},{"level":35,"species":287},{"level":35,"species":289},{"level":35,"species":296},{"level":35,"species":299},{"level":35,"species":305}],"party_address":3228964,"script_address":0},{"address":3263792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":316},{"level":37,"species":287},{"level":37,"species":289},{"level":37,"species":297},{"level":37,"species":300},{"level":37,"species":305}],"party_address":3229012,"script_address":0},{"address":3263832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313},{"level":34,"species":116}],"party_address":3229060,"script_address":0},{"address":3263872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":325},{"level":36,"species":313},{"level":36,"species":117}],"party_address":3229076,"script_address":0},{"address":3263912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":325},{"level":38,"species":313},{"level":38,"species":117}],"party_address":3229100,"script_address":0},{"address":3263952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325},{"level":40,"species":314},{"level":40,"species":230}],"party_address":3229124,"script_address":0},{"address":3263992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":411}],"party_address":3229148,"script_address":2564791},{"address":3264032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":64}],"party_address":3229156,"script_address":2564822},{"address":3264072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":202}],"party_address":3229172,"script_address":0},{"address":3264112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":4}],"party_address":3229180,"script_address":0},{"address":3264152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":1}],"party_address":3229188,"script_address":0},{"address":3264192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":405}],"party_address":3229196,"script_address":0},{"address":3264232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":404}],"party_address":3229204,"script_address":0}],"warps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4":"MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0","MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2":"MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1","MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10","MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2":"MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11","MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3":"MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2","MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0":"MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4","MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3":"MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5","MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2":"MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6","MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4":"MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7","MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0":"MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8","MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9","MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2":"MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0","MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0":"MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1","MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0":"MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2","MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1":"MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3","MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2":"MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4","MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0":"MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5","MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10":"MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6","MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9":"MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7","MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0":"MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0","MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2","MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3","MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0":"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8","MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8":"MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0","MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11":"MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2","MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0","MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0","MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3","MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4","MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0","MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1","MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2","MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0","MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0":"MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0","MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0":"MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0","MAP_ALTERING_CAVE:0/MAP_ROUTE103:0":"MAP_ROUTE103:0/MAP_ALTERING_CAVE:0","MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0":"MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0","MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2":"MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1","MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1":"MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2","MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6":"MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0","MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0":"MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2","MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2":"MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0","MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0":"MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1","MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6":"MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10","MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22":"MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11","MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9":"MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12","MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18":"MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13","MAP_AQUA_HIDEOUT_B1F:14/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16":"MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15","MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15":"MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16","MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20":"MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17","MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13":"MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18","MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24":"MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19","MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1":"MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2","MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:21/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11":"MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22","MAP_AQUA_HIDEOUT_B1F:23/MAP_AQUA_HIDEOUT_B1F:17!":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19":"MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24","MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2":"MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3","MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7":"MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4","MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8":"MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5","MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10":"MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6","MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5":"MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8","MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1":"MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0","MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2":"MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1","MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3":"MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2","MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5":"MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3","MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8":"MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4","MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3":"MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5","MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7":"MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6","MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6":"MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7","MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4":"MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8","MAP_AQUA_HIDEOUT_B2F:9/MAP_AQUA_HIDEOUT_B1F:4!":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0","MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1":"MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1","MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0","MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1":"MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1","MAP_BATTLE_COLOSSEUM_2P:0,1/MAP_DYNAMIC:-1!":"","MAP_BATTLE_COLOSSEUM_4P:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:3/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0!":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2","MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2","MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0","MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0","MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0","MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0","MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0","MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0","MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0","MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0","MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0","MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0","MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0":"MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0":"MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0":"MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0":"MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0":"MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0":"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0":"MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0":"MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0":"MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0":"MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0":"MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0":"MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0":"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0":"MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0":"MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1","MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0","MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0":"MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0","MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0":"MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0","MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1":"MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0","MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3":"MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0":"MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:0/MAP_CAVE_OF_ORIGIN_1F:1!":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:1/MAP_CAVE_OF_ORIGIN_B1F:0!":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_DESERT_RUINS:0/MAP_ROUTE111:1":"MAP_ROUTE111:1/MAP_DESERT_RUINS:0","MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2":"MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1","MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1":"MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2","MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0","MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0":"MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0","MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1","MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0":"MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2","MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0":"MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3","MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0":"MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4","MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2":"MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0","MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0":"MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0","MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3":"MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0","MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4":"MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1":"MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0","MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1","MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0":"MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2","MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1":"MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1":"MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0":"MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1":"MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0":"MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1":"MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0":"MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1","MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0","MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1","MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0","MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1","MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0","MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1","MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0","MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1","MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0","MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1","MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1":"MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0":"MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1":"MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0":"MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0":"MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1":"MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0":"MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1","MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0":"MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0","MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0":"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1","MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2","MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0":"MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3","MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0":"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4","MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1":"MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0","MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3":"MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0","MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0":"MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0","MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4":"MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2":"MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1":"MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1","MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1":"MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1","MAP_FIERY_PATH:0/MAP_ROUTE112:4":"MAP_ROUTE112:4/MAP_FIERY_PATH:0","MAP_FIERY_PATH:1/MAP_ROUTE112:5":"MAP_ROUTE112:5/MAP_FIERY_PATH:1","MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0","MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0":"MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1","MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0":"MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2","MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0":"MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3","MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0":"MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4","MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0":"MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5","MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0":"MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6","MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0":"MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7","MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0":"MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8","MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8":"MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0","MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2":"MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0","MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1":"MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0","MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4":"MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0","MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5":"MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0","MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6":"MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0","MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7":"MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0","MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3":"MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0":"MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2","MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0","MAP_FORTREE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FORTREE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0":"MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0","MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0":"MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1","MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1":"MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2","MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0":"MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3","MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1":"MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0","MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2":"MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1","MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0":"MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2","MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1":"MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3","MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2":"MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4","MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3":"MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5","MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4":"MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6","MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2":"MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0","MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3":"MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1","MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4":"MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2","MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5":"MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3","MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6":"MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4","MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3":"MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0","MAP_INSIDE_OF_TRUCK:0,1,2/MAP_DYNAMIC:-1!":"","MAP_ISLAND_CAVE:0/MAP_ROUTE105:0":"MAP_ROUTE105:0/MAP_ISLAND_CAVE:0","MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2":"MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1","MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1":"MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2","MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3":"MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1","MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3":"MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3","MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0":"MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4","MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0":"MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0","MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0":"MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1","MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0":"MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2","MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3","MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0":"MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4","MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5","MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1":"MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0","MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8":"MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10","MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9":"MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11","MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10":"MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12","MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11":"MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13","MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12":"MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14","MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13":"MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15","MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14":"MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16","MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15":"MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17","MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16":"MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18","MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17":"MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19","MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0":"MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2","MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18":"MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20","MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20":"MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21","MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19":"MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22","MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21":"MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23","MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22":"MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24","MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23":"MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25","MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2":"MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3","MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4":"MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4","MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3":"MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5","MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1":"MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6","MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5":"MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7","MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6":"MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8","MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7":"MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9","MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2":"MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0","MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6":"MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1","MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12":"MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10","MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13":"MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11","MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14":"MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12","MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15":"MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13","MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16":"MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14","MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17":"MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15","MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18":"MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16","MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19":"MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17","MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20":"MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18","MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22":"MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19","MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3":"MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2","MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21":"MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20","MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23":"MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21","MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24":"MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22","MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25":"MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23","MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5":"MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3","MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4":"MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4","MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7":"MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5","MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8":"MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6","MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9":"MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7","MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10":"MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8","MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11":"MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9","MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0":"MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0","MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4":"MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0","MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2":"MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3":"MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5":"MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0","MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1","MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0":"MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10","MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0":"MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11","MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0":"MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12","MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2","MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13","MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4","MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1":"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5","MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0":"MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6","MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0":"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7","MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0":"MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8","MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0":"MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9","MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0","MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1","MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4":"MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0","MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0":"MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2","MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1":"MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1":"MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:3/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!":"","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0","MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12":"MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0","MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8":"MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0","MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9":"MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0","MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10":"MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0","MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11":"MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13":"MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0","MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7":"MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2":"MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5":"MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1","MAP_LILYCOVE_CITY_UNUSED_MART:0,1/MAP_LILYCOVE_CITY:0!":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0","MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1","MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0":"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1":"MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0":"MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2":"MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0","MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4":"MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0","MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1":"MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1","MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1":"MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2","MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0":"MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3","MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0":"MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0","MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1":"MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1","MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2":"MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2","MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0":"MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0","MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2":"MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1","MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3":"MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0","MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0":"MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1","MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0":"MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0","MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0":"MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1","MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2":"MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2","MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1":"MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0","MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1":"MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0","MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1":"MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1","MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0":"MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0","MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1":"MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1","MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0":"MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0","MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0":"MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0","MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0":"MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0","MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1","MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0":"MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2","MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0":"MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3","MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0":"MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4","MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0":"MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5","MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0":"MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6","MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2":"MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0","MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5":"MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0","MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0":"MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0","MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4":"MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0","MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6":"MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0","MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3":"MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1":"MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0":"MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0","MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0":"MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1","MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0":"MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2","MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4":"MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3","MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5":"MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4","MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0":"MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5","MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2":"MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0","MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0":"MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1","MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1":"MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2","MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2":"MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3","MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1":"MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0","MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2":"MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1","MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3":"MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2","MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0":"MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3","MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3":"MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4","MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4":"MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5","MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3":"MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0","MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5":"MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0","MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3":"MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0","MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1":"MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1","MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0":"MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0","MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1":"MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1","MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0":"MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0","MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0":"MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1","MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1":"MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0","MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0":"MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0","MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0":"MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1","MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2","MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0":"MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3","MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0":"MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4","MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0":"MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5","MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0":"MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6","MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1":"MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7","MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8","MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9":"MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2","MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0","MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1":"MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0","MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11":"MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10","MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10":"MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11","MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13":"MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12","MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12":"MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13","MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3":"MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2","MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2":"MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3","MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5":"MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4","MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4":"MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5","MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7":"MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6","MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6":"MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7","MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9":"MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8","MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8":"MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9","MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0":"MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0","MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3":"MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0","MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5":"MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0","MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7":"MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1","MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4":"MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2":"MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8":"MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2","MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0","MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6":"MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0","MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1":"MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1","MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3":"MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3","MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1":"MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1","MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0":"MAP_ROUTE122:0/MAP_MT_PYRE_1F:0","MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0":"MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1","MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0":"MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4","MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4":"MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5","MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4":"MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0","MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0":"MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1","MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4":"MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2","MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5":"MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3","MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5":"MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4","MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1":"MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0","MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1":"MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1","MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4":"MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2","MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5":"MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3","MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2":"MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4","MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3":"MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5","MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1":"MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0","MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1":"MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1","MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3":"MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2","MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4":"MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3","MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2":"MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4","MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3":"MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5","MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0":"MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0","MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0":"MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1","MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1":"MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2","MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2":"MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3","MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3":"MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4","MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0":"MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0","MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2":"MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1","MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1":"MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0","MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1":"MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1","MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1":"MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1","MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0":"MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0","MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1":"MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1","MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0":"MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0","MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2":"MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0","MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0":"MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1","MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1":"MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0","MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0":"MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1","MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1":"MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0","MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0":"MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1","MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1":"MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0","MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0":"MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1","MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1":"MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0","MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0":"MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1","MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1":"MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0","MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0":"MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1","MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1":"MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0","MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0":"MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1","MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1":"MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0","MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0":"MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1","MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1":"MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0","MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0":"MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1","MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1":"MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0","MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1":"MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1","MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0":"MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0","MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1":"MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1","MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0":"MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0","MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1":"MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1","MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0":"MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0","MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1":"MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1","MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0":"MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0","MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1":"MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1","MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0":"MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2","MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0":"MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0","MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1":"MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0","MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0":"MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0","MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0":"MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1","MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1":"MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0","MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0":"MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1","MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1":"MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0","MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0":"MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1","MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1":"MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0","MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0":"MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1","MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0":"MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0","MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0":"MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1","MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1":"MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0","MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0":"MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0","MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0":"MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1","MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2","MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0":"MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3","MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0":"MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0","MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1":"MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0","MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3":"MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2":"MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0","MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0":"MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1","MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0":"MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2","MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0":"MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3","MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0":"MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4","MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0":"MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5","MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1":"MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0","MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2":"MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0","MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3":"MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0","MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4":"MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0","MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5":"MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0":"MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0":"MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0","MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0":"MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1","MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0":"MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2","MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3","MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0":"MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4","MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0":"MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5","MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2":"MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0","MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8":"MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10","MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9":"MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12","MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16":"MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14","MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18":"MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15","MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14":"MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16","MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15":"MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18","MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3":"MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2","MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24":"MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20","MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26":"MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21","MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28":"MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22","MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30":"MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23","MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20":"MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24","MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21":"MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26","MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22":"MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28","MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2":"MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3","MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23":"MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30","MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34":"MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32","MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36":"MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33","MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32":"MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34","MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33":"MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36","MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6":"MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5","MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5":"MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6","MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10":"MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8","MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12":"MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9","MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0":"MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0","MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4":"MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0","MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5":"MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3":"MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1":"MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0","MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3":"MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1","MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5":"MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3","MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7":"MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5","MAP_RECORD_CORNER:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_ROUTE103:0/MAP_ALTERING_CAVE:0":"MAP_ALTERING_CAVE:0/MAP_ROUTE103:0","MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0":"MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0","MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0":"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1","MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1":"MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3","MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3":"MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5","MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5":"MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7","MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0":"MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0","MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1":"MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0","MAP_ROUTE105:0/MAP_ISLAND_CAVE:0":"MAP_ISLAND_CAVE:0/MAP_ROUTE105:0","MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0":"MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0","MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0":"MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0","MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0":"MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0","MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0":"MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0","MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0":"MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0","MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1","MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2","MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3","MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4","MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4":"MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5":"MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2":"MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3":"MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1":"MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:2,3/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0","MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0":"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1":"MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0":"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0","MAP_ROUTE111:1/MAP_DESERT_RUINS:0":"MAP_DESERT_RUINS:0/MAP_ROUTE111:1","MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0":"MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2","MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0":"MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3","MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0":"MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4","MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2":"MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0","MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0":"MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0","MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1":"MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1","MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1":"MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3","MAP_ROUTE112:4/MAP_FIERY_PATH:0":"MAP_FIERY_PATH:0/MAP_ROUTE112:4","MAP_ROUTE112:5/MAP_FIERY_PATH:1":"MAP_FIERY_PATH:1/MAP_ROUTE112:5","MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1":"MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1","MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0":"MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0","MAP_ROUTE113:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0":"MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0","MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0":"MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0","MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1","MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0":"MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2","MAP_ROUTE114:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1":"MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0":"MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2","MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2":"MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0","MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1":"MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0","MAP_ROUTE115:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE115:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0":"MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0","MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0":"MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1","MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2":"MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2","MAP_ROUTE116:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1":"MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0","MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0":"MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0","MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0":"MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0","MAP_ROUTE118:0/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE118:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0","MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0":"MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1","MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1":"MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0":"MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2","MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0","MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0":"MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0","MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0":"MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1","MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0":"MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0":"MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2","MAP_ROUTE122:0/MAP_MT_PYRE_1F:0":"MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0","MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0":"MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0","MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0":"MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0","MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0":"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0","MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0":"MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0","MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0","MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0":"MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0","MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0":"MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0","MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0":"MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1","MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0":"MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10","MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0":"MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11","MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0":"MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2","MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3","MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0":"MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4","MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6","MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0":"MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7","MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0":"MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8","MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0":"MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9","MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8":"MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0","MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6":"MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1","MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2","MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0","MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1","MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0","MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1":"MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0","MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0":"MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2","MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2":"MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0","MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10":"MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0","MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0":"MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2","MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2":"MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0","MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0":"MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1","MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1":"MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0","MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0":"MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0","MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7":"MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0","MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9":"MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0","MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11":"MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0","MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2":"MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3":"MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4":"MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0","MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0":"MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0","MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4":"MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1","MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2":"MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2","MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0":"MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0","MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0","MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0":"MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0","MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1":"MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:0/MAP_UNDERWATER_ROUTE128:0!":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0":"MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1","MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0":"MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1","MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0":"MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2","MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2":"MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0","MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0":"MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1","MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0":"MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2","MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0":"MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3","MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1":"MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0","MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1":"MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1","MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1":"MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2","MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1":"MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0","MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1":"MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1","MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2":"MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2","MAP_SEAFLOOR_CAVERN_ROOM4:3/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1":"MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0","MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1":"MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1","MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2":"MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2","MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2":"MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0","MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2":"MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1","MAP_SEAFLOOR_CAVERN_ROOM6:2/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3":"MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0","MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1":"MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1","MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0":"MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0","MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0":"MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1","MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0":"MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0","MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0":"MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0","MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0":"MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0","MAP_SECRET_BASE_BLUE_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0":"MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1","MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1":"MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0","MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0":"MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2","MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2":"MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0","MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0":"MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1","MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1":"MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0","MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0":"MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1","MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1":"MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2","MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1":"MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0","MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2":"MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1","MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0":"MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2","MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2":"MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0","MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0":"MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1","MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0":"MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0","MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0":"MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1","MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1":"MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0","MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0":"MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1","MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1":"MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0","MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0","MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0":"MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1","MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0":"MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10","MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2","MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0":"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3","MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0":"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4","MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7","MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0":"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6","MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0":"MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8","MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2":"MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9","MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3":"MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0","MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8":"MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0","MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9":"MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2","MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10":"MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0","MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1":"MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0","MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6":"MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7":"MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0":"MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4":"MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2":"MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0","MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0","MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0":"MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1","MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0":"MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10","MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0":"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11","MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12","MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0":"MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2","MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0":"MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3","MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0":"MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4","MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0":"MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5","MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0":"MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6","MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0":"MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7","MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0":"MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8","MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0":"MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9","MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2":"MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0","MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0":"MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2","MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2":"MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0","MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4":"MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0","MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5":"MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0","MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6":"MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0","MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7":"MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0","MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8":"MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0","MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9":"MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0","MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10":"MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0","MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11":"MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0","MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1":"MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12":"MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0":"MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1":"MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1","MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1":"MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1","MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0":"MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0","MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2":"MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1","MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4":"MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2","MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6":"MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3","MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8":"MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4","MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9":"MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5","MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10":"MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6","MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11":"MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7","MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0":"MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8","MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8":"MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0","MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0":"MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0","MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6":"MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10","MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7":"MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11","MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1":"MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2","MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2":"MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4","MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3":"MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6","MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4":"MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8","MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5":"MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9","MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1":"MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0","MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!":"","MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0":"MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1","MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!":"","MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2":"MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0","MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0":"MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1","MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1":"MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0","MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0":"MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1","MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1":"MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0","MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0":"MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1","MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1":"MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0","MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0":"MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1","MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1":"MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1","MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4":"MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0","MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0":"MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2","MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1":"MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0","MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1":"MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1","MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!":"","MAP_UNDERWATER_ROUTE105:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE105:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0":"MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0","MAP_UNDERWATER_ROUTE127:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE127:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0":"MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0","MAP_UNDERWATER_ROUTE129:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE129:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0":"MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0","MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0":"MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0","MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0":"MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0","MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!":"","MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0":"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0","MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0":"MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1","MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2","MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0":"MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3","MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1":"MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4","MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0":"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5","MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0":"MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6","MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0":"MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0","MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5":"MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0","MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6":"MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0","MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1":"MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2":"MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3":"MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0","MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2":"MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0","MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3":"MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1","MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5":"MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2","MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2":"MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3","MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4":"MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4","MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0":"MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0","MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2":"MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1","MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3":"MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2","MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1":"MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3","MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4":"MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4","MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2":"MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5","MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3":"MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6","MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0":"MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0","MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3":"MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1","MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1":"MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2","MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6":"MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3"}} +{"_comment":"DO NOT MODIFY. This file was auto-generated. Your changes will likely be overwritten.","_rom_name":"pokemon emerald version / AP 5","constants":{"ABILITIES_COUNT":78,"ABILITY_AIR_LOCK":77,"ABILITY_ARENA_TRAP":71,"ABILITY_BATTLE_ARMOR":4,"ABILITY_BLAZE":66,"ABILITY_CACOPHONY":76,"ABILITY_CHLOROPHYLL":34,"ABILITY_CLEAR_BODY":29,"ABILITY_CLOUD_NINE":13,"ABILITY_COLOR_CHANGE":16,"ABILITY_COMPOUND_EYES":14,"ABILITY_CUTE_CHARM":56,"ABILITY_DAMP":6,"ABILITY_DRIZZLE":2,"ABILITY_DROUGHT":70,"ABILITY_EARLY_BIRD":48,"ABILITY_EFFECT_SPORE":27,"ABILITY_FLAME_BODY":49,"ABILITY_FLASH_FIRE":18,"ABILITY_FORECAST":59,"ABILITY_GUTS":62,"ABILITY_HUGE_POWER":37,"ABILITY_HUSTLE":55,"ABILITY_HYPER_CUTTER":52,"ABILITY_ILLUMINATE":35,"ABILITY_IMMUNITY":17,"ABILITY_INNER_FOCUS":39,"ABILITY_INSOMNIA":15,"ABILITY_INTIMIDATE":22,"ABILITY_KEEN_EYE":51,"ABILITY_LEVITATE":26,"ABILITY_LIGHTNING_ROD":31,"ABILITY_LIMBER":7,"ABILITY_LIQUID_OOZE":64,"ABILITY_MAGMA_ARMOR":40,"ABILITY_MAGNET_PULL":42,"ABILITY_MARVEL_SCALE":63,"ABILITY_MINUS":58,"ABILITY_NATURAL_CURE":30,"ABILITY_NONE":0,"ABILITY_OBLIVIOUS":12,"ABILITY_OVERGROW":65,"ABILITY_OWN_TEMPO":20,"ABILITY_PICKUP":53,"ABILITY_PLUS":57,"ABILITY_POISON_POINT":38,"ABILITY_PRESSURE":46,"ABILITY_PURE_POWER":74,"ABILITY_RAIN_DISH":44,"ABILITY_ROCK_HEAD":69,"ABILITY_ROUGH_SKIN":24,"ABILITY_RUN_AWAY":50,"ABILITY_SAND_STREAM":45,"ABILITY_SAND_VEIL":8,"ABILITY_SERENE_GRACE":32,"ABILITY_SHADOW_TAG":23,"ABILITY_SHED_SKIN":61,"ABILITY_SHELL_ARMOR":75,"ABILITY_SHIELD_DUST":19,"ABILITY_SOUNDPROOF":43,"ABILITY_SPEED_BOOST":3,"ABILITY_STATIC":9,"ABILITY_STENCH":1,"ABILITY_STICKY_HOLD":60,"ABILITY_STURDY":5,"ABILITY_SUCTION_CUPS":21,"ABILITY_SWARM":68,"ABILITY_SWIFT_SWIM":33,"ABILITY_SYNCHRONIZE":28,"ABILITY_THICK_FAT":47,"ABILITY_TORRENT":67,"ABILITY_TRACE":36,"ABILITY_TRUANT":54,"ABILITY_VITAL_SPIRIT":72,"ABILITY_VOLT_ABSORB":10,"ABILITY_WATER_ABSORB":11,"ABILITY_WATER_VEIL":41,"ABILITY_WHITE_SMOKE":73,"ABILITY_WONDER_GUARD":25,"ACRO_BIKE":1,"BAG_ITEM_CAPACITY_DIGITS":2,"BERRY_CAPACITY_DIGITS":3,"BERRY_FIRMNESS_HARD":3,"BERRY_FIRMNESS_SOFT":2,"BERRY_FIRMNESS_SUPER_HARD":5,"BERRY_FIRMNESS_UNKNOWN":0,"BERRY_FIRMNESS_VERY_HARD":4,"BERRY_FIRMNESS_VERY_SOFT":1,"BERRY_NONE":0,"BERRY_STAGE_BERRIES":5,"BERRY_STAGE_FLOWERING":4,"BERRY_STAGE_NO_BERRY":0,"BERRY_STAGE_PLANTED":1,"BERRY_STAGE_SPARKLING":255,"BERRY_STAGE_SPROUTED":2,"BERRY_STAGE_TALLER":3,"BERRY_TREES_COUNT":128,"BERRY_TREE_ROUTE_102_ORAN":2,"BERRY_TREE_ROUTE_102_PECHA":1,"BERRY_TREE_ROUTE_103_CHERI_1":5,"BERRY_TREE_ROUTE_103_CHERI_2":7,"BERRY_TREE_ROUTE_103_LEPPA":6,"BERRY_TREE_ROUTE_104_CHERI_1":8,"BERRY_TREE_ROUTE_104_CHERI_2":76,"BERRY_TREE_ROUTE_104_LEPPA":10,"BERRY_TREE_ROUTE_104_ORAN_1":4,"BERRY_TREE_ROUTE_104_ORAN_2":11,"BERRY_TREE_ROUTE_104_PECHA":13,"BERRY_TREE_ROUTE_104_SOIL_1":3,"BERRY_TREE_ROUTE_104_SOIL_2":9,"BERRY_TREE_ROUTE_104_SOIL_3":12,"BERRY_TREE_ROUTE_104_SOIL_4":75,"BERRY_TREE_ROUTE_110_NANAB_1":16,"BERRY_TREE_ROUTE_110_NANAB_2":17,"BERRY_TREE_ROUTE_110_NANAB_3":18,"BERRY_TREE_ROUTE_111_ORAN_1":80,"BERRY_TREE_ROUTE_111_ORAN_2":81,"BERRY_TREE_ROUTE_111_RAZZ_1":19,"BERRY_TREE_ROUTE_111_RAZZ_2":20,"BERRY_TREE_ROUTE_112_PECHA_1":22,"BERRY_TREE_ROUTE_112_PECHA_2":23,"BERRY_TREE_ROUTE_112_RAWST_1":21,"BERRY_TREE_ROUTE_112_RAWST_2":24,"BERRY_TREE_ROUTE_114_PERSIM_1":68,"BERRY_TREE_ROUTE_114_PERSIM_2":77,"BERRY_TREE_ROUTE_114_PERSIM_3":78,"BERRY_TREE_ROUTE_115_BLUK_1":55,"BERRY_TREE_ROUTE_115_BLUK_2":56,"BERRY_TREE_ROUTE_115_KELPSY_1":69,"BERRY_TREE_ROUTE_115_KELPSY_2":70,"BERRY_TREE_ROUTE_115_KELPSY_3":71,"BERRY_TREE_ROUTE_116_CHESTO_1":26,"BERRY_TREE_ROUTE_116_CHESTO_2":66,"BERRY_TREE_ROUTE_116_PINAP_1":25,"BERRY_TREE_ROUTE_116_PINAP_2":67,"BERRY_TREE_ROUTE_117_WEPEAR_1":27,"BERRY_TREE_ROUTE_117_WEPEAR_2":28,"BERRY_TREE_ROUTE_117_WEPEAR_3":29,"BERRY_TREE_ROUTE_118_SITRUS_1":31,"BERRY_TREE_ROUTE_118_SITRUS_2":33,"BERRY_TREE_ROUTE_118_SOIL":32,"BERRY_TREE_ROUTE_119_HONDEW_1":83,"BERRY_TREE_ROUTE_119_HONDEW_2":84,"BERRY_TREE_ROUTE_119_LEPPA":86,"BERRY_TREE_ROUTE_119_POMEG_1":34,"BERRY_TREE_ROUTE_119_POMEG_2":35,"BERRY_TREE_ROUTE_119_POMEG_3":36,"BERRY_TREE_ROUTE_119_SITRUS":85,"BERRY_TREE_ROUTE_120_ASPEAR_1":37,"BERRY_TREE_ROUTE_120_ASPEAR_2":38,"BERRY_TREE_ROUTE_120_ASPEAR_3":39,"BERRY_TREE_ROUTE_120_NANAB":44,"BERRY_TREE_ROUTE_120_PECHA_1":40,"BERRY_TREE_ROUTE_120_PECHA_2":41,"BERRY_TREE_ROUTE_120_PECHA_3":42,"BERRY_TREE_ROUTE_120_PINAP":45,"BERRY_TREE_ROUTE_120_RAZZ":43,"BERRY_TREE_ROUTE_120_WEPEAR":46,"BERRY_TREE_ROUTE_121_ASPEAR":48,"BERRY_TREE_ROUTE_121_CHESTO":50,"BERRY_TREE_ROUTE_121_NANAB_1":52,"BERRY_TREE_ROUTE_121_NANAB_2":53,"BERRY_TREE_ROUTE_121_PERSIM":47,"BERRY_TREE_ROUTE_121_RAWST":49,"BERRY_TREE_ROUTE_121_SOIL_1":51,"BERRY_TREE_ROUTE_121_SOIL_2":54,"BERRY_TREE_ROUTE_123_GREPA_1":60,"BERRY_TREE_ROUTE_123_GREPA_2":61,"BERRY_TREE_ROUTE_123_GREPA_3":65,"BERRY_TREE_ROUTE_123_GREPA_4":72,"BERRY_TREE_ROUTE_123_LEPPA_1":62,"BERRY_TREE_ROUTE_123_LEPPA_2":64,"BERRY_TREE_ROUTE_123_PECHA":87,"BERRY_TREE_ROUTE_123_POMEG_1":15,"BERRY_TREE_ROUTE_123_POMEG_2":30,"BERRY_TREE_ROUTE_123_POMEG_3":58,"BERRY_TREE_ROUTE_123_POMEG_4":59,"BERRY_TREE_ROUTE_123_QUALOT_1":14,"BERRY_TREE_ROUTE_123_QUALOT_2":73,"BERRY_TREE_ROUTE_123_QUALOT_3":74,"BERRY_TREE_ROUTE_123_QUALOT_4":79,"BERRY_TREE_ROUTE_123_RAWST":57,"BERRY_TREE_ROUTE_123_SITRUS":88,"BERRY_TREE_ROUTE_123_SOIL":63,"BERRY_TREE_ROUTE_130_LIECHI":82,"DAILY_FLAGS_END":2399,"DAILY_FLAGS_START":2336,"FIRST_BALL":1,"FIRST_BERRY_INDEX":133,"FIRST_BERRY_MASTER_BERRY":153,"FIRST_BERRY_MASTER_WIFE_BERRY":133,"FIRST_KIRI_BERRY":153,"FIRST_MAIL_INDEX":121,"FIRST_ROUTE_114_MAN_BERRY":148,"FLAGS_COUNT":2400,"FLAG_ADDED_MATCH_CALL_TO_POKENAV":304,"FLAG_ADVENTURE_STARTED":116,"FLAG_ARRIVED_AT_MARINE_CAVE_EMERGE_SPOT":2265,"FLAG_ARRIVED_AT_NAVEL_ROCK":2273,"FLAG_ARRIVED_AT_TERRA_CAVE_ENTRANCE":2266,"FLAG_ARRIVED_ON_FARAWAY_ISLAND":2264,"FLAG_BADGE01_GET":2151,"FLAG_BADGE02_GET":2152,"FLAG_BADGE03_GET":2153,"FLAG_BADGE04_GET":2154,"FLAG_BADGE05_GET":2155,"FLAG_BADGE06_GET":2156,"FLAG_BADGE07_GET":2157,"FLAG_BADGE08_GET":2158,"FLAG_BATTLE_FRONTIER_TRADE_DONE":156,"FLAG_BEAT_MAGMA_GRUNT_JAGGED_PASS":313,"FLAG_BEAUTY_PAINTING_MADE":161,"FLAG_BERRY_MASTERS_WIFE":1197,"FLAG_BERRY_MASTER_RECEIVED_BERRY_1":1195,"FLAG_BERRY_MASTER_RECEIVED_BERRY_2":1196,"FLAG_BERRY_TREES_START":612,"FLAG_BERRY_TREE_01":612,"FLAG_BERRY_TREE_02":613,"FLAG_BERRY_TREE_03":614,"FLAG_BERRY_TREE_04":615,"FLAG_BERRY_TREE_05":616,"FLAG_BERRY_TREE_06":617,"FLAG_BERRY_TREE_07":618,"FLAG_BERRY_TREE_08":619,"FLAG_BERRY_TREE_09":620,"FLAG_BERRY_TREE_10":621,"FLAG_BERRY_TREE_11":622,"FLAG_BERRY_TREE_12":623,"FLAG_BERRY_TREE_13":624,"FLAG_BERRY_TREE_14":625,"FLAG_BERRY_TREE_15":626,"FLAG_BERRY_TREE_16":627,"FLAG_BERRY_TREE_17":628,"FLAG_BERRY_TREE_18":629,"FLAG_BERRY_TREE_19":630,"FLAG_BERRY_TREE_20":631,"FLAG_BERRY_TREE_21":632,"FLAG_BERRY_TREE_22":633,"FLAG_BERRY_TREE_23":634,"FLAG_BERRY_TREE_24":635,"FLAG_BERRY_TREE_25":636,"FLAG_BERRY_TREE_26":637,"FLAG_BERRY_TREE_27":638,"FLAG_BERRY_TREE_28":639,"FLAG_BERRY_TREE_29":640,"FLAG_BERRY_TREE_30":641,"FLAG_BERRY_TREE_31":642,"FLAG_BERRY_TREE_32":643,"FLAG_BERRY_TREE_33":644,"FLAG_BERRY_TREE_34":645,"FLAG_BERRY_TREE_35":646,"FLAG_BERRY_TREE_36":647,"FLAG_BERRY_TREE_37":648,"FLAG_BERRY_TREE_38":649,"FLAG_BERRY_TREE_39":650,"FLAG_BERRY_TREE_40":651,"FLAG_BERRY_TREE_41":652,"FLAG_BERRY_TREE_42":653,"FLAG_BERRY_TREE_43":654,"FLAG_BERRY_TREE_44":655,"FLAG_BERRY_TREE_45":656,"FLAG_BERRY_TREE_46":657,"FLAG_BERRY_TREE_47":658,"FLAG_BERRY_TREE_48":659,"FLAG_BERRY_TREE_49":660,"FLAG_BERRY_TREE_50":661,"FLAG_BERRY_TREE_51":662,"FLAG_BERRY_TREE_52":663,"FLAG_BERRY_TREE_53":664,"FLAG_BERRY_TREE_54":665,"FLAG_BERRY_TREE_55":666,"FLAG_BERRY_TREE_56":667,"FLAG_BERRY_TREE_57":668,"FLAG_BERRY_TREE_58":669,"FLAG_BERRY_TREE_59":670,"FLAG_BERRY_TREE_60":671,"FLAG_BERRY_TREE_61":672,"FLAG_BERRY_TREE_62":673,"FLAG_BERRY_TREE_63":674,"FLAG_BERRY_TREE_64":675,"FLAG_BERRY_TREE_65":676,"FLAG_BERRY_TREE_66":677,"FLAG_BERRY_TREE_67":678,"FLAG_BERRY_TREE_68":679,"FLAG_BERRY_TREE_69":680,"FLAG_BERRY_TREE_70":681,"FLAG_BERRY_TREE_71":682,"FLAG_BERRY_TREE_72":683,"FLAG_BERRY_TREE_73":684,"FLAG_BERRY_TREE_74":685,"FLAG_BERRY_TREE_75":686,"FLAG_BERRY_TREE_76":687,"FLAG_BERRY_TREE_77":688,"FLAG_BERRY_TREE_78":689,"FLAG_BERRY_TREE_79":690,"FLAG_BERRY_TREE_80":691,"FLAG_BERRY_TREE_81":692,"FLAG_BERRY_TREE_82":693,"FLAG_BERRY_TREE_83":694,"FLAG_BERRY_TREE_84":695,"FLAG_BERRY_TREE_85":696,"FLAG_BERRY_TREE_86":697,"FLAG_BERRY_TREE_87":698,"FLAG_BERRY_TREE_88":699,"FLAG_BETTER_SHOPS_ENABLED":206,"FLAG_BIRCH_AIDE_MET":88,"FLAG_CANCEL_BATTLE_ROOM_CHALLENGE":119,"FLAG_CAUGHT_DEOXYS":429,"FLAG_CAUGHT_GROUDON":480,"FLAG_CAUGHT_HO_OH":146,"FLAG_CAUGHT_KYOGRE":479,"FLAG_CAUGHT_LATIAS":457,"FLAG_CAUGHT_LATIOS":482,"FLAG_CAUGHT_LUGIA":145,"FLAG_CAUGHT_MEW":458,"FLAG_CAUGHT_RAYQUAZA":478,"FLAG_CAUGHT_REGICE":427,"FLAG_CAUGHT_REGIROCK":426,"FLAG_CAUGHT_REGISTEEL":483,"FLAG_CHOSEN_MULTI_BATTLE_NPC_PARTNER":338,"FLAG_CHOSE_CLAW_FOSSIL":336,"FLAG_CHOSE_ROOT_FOSSIL":335,"FLAG_COLLECTED_ALL_GOLD_SYMBOLS":466,"FLAG_COLLECTED_ALL_SILVER_SYMBOLS":92,"FLAG_CONTEST_SKETCH_CREATED":270,"FLAG_COOL_PAINTING_MADE":160,"FLAG_CUTE_PAINTING_MADE":162,"FLAG_DAILY_APPRENTICE_LEAVES":2356,"FLAG_DAILY_BERRY_MASTERS_WIFE":2353,"FLAG_DAILY_BERRY_MASTER_RECEIVED_BERRY":2349,"FLAG_DAILY_CONTEST_LOBBY_RECEIVED_BERRY":2337,"FLAG_DAILY_FLOWER_SHOP_RECEIVED_BERRY":2352,"FLAG_DAILY_LILYCOVE_RECEIVED_BERRY":2351,"FLAG_DAILY_PICKED_LOTO_TICKET":2346,"FLAG_DAILY_ROUTE_111_RECEIVED_BERRY":2348,"FLAG_DAILY_ROUTE_114_RECEIVED_BERRY":2347,"FLAG_DAILY_ROUTE_120_RECEIVED_BERRY":2350,"FLAG_DAILY_SECRET_BASE":2338,"FLAG_DAILY_SOOTOPOLIS_RECEIVED_BERRY":2354,"FLAG_DECLINED_BIKE":89,"FLAG_DECLINED_RIVAL_BATTLE_LILYCOVE":286,"FLAG_DECLINED_WALLY_BATTLE_MAUVILLE":284,"FLAG_DECORATION_1":174,"FLAG_DECORATION_10":183,"FLAG_DECORATION_11":184,"FLAG_DECORATION_12":185,"FLAG_DECORATION_13":186,"FLAG_DECORATION_14":187,"FLAG_DECORATION_2":175,"FLAG_DECORATION_3":176,"FLAG_DECORATION_4":177,"FLAG_DECORATION_5":178,"FLAG_DECORATION_6":179,"FLAG_DECORATION_7":180,"FLAG_DECORATION_8":181,"FLAG_DECORATION_9":182,"FLAG_DEFEATED_DEOXYS":428,"FLAG_DEFEATED_DEWFORD_GYM":1265,"FLAG_DEFEATED_ELECTRODE_1_AQUA_HIDEOUT":452,"FLAG_DEFEATED_ELECTRODE_2_AQUA_HIDEOUT":453,"FLAG_DEFEATED_ELITE_4_DRAKE":1278,"FLAG_DEFEATED_ELITE_4_GLACIA":1277,"FLAG_DEFEATED_ELITE_4_PHOEBE":1276,"FLAG_DEFEATED_ELITE_4_SIDNEY":1275,"FLAG_DEFEATED_EVIL_TEAM_MT_CHIMNEY":139,"FLAG_DEFEATED_FORTREE_GYM":1269,"FLAG_DEFEATED_GROUDON":447,"FLAG_DEFEATED_GRUNT_SPACE_CENTER_1F":191,"FLAG_DEFEATED_HO_OH":476,"FLAG_DEFEATED_KECLEON_1_ROUTE_119":989,"FLAG_DEFEATED_KECLEON_1_ROUTE_120":982,"FLAG_DEFEATED_KECLEON_2_ROUTE_119":990,"FLAG_DEFEATED_KECLEON_2_ROUTE_120":985,"FLAG_DEFEATED_KECLEON_3_ROUTE_120":986,"FLAG_DEFEATED_KECLEON_4_ROUTE_120":987,"FLAG_DEFEATED_KECLEON_5_ROUTE_120":988,"FLAG_DEFEATED_KEKLEON_ROUTE_120_BRIDGE":970,"FLAG_DEFEATED_KYOGRE":446,"FLAG_DEFEATED_LATIAS":456,"FLAG_DEFEATED_LATIOS":481,"FLAG_DEFEATED_LAVARIDGE_GYM":1267,"FLAG_DEFEATED_LUGIA":477,"FLAG_DEFEATED_MAGMA_SPACE_CENTER":117,"FLAG_DEFEATED_MAUVILLE_GYM":1266,"FLAG_DEFEATED_METEOR_FALLS_STEVEN":1272,"FLAG_DEFEATED_MEW":455,"FLAG_DEFEATED_MOSSDEEP_GYM":1270,"FLAG_DEFEATED_PETALBURG_GYM":1268,"FLAG_DEFEATED_RAYQUAZA":448,"FLAG_DEFEATED_REGICE":444,"FLAG_DEFEATED_REGIROCK":443,"FLAG_DEFEATED_REGISTEEL":445,"FLAG_DEFEATED_RIVAL_ROUTE103":130,"FLAG_DEFEATED_RIVAL_ROUTE_104":125,"FLAG_DEFEATED_RIVAL_RUSTBORO":211,"FLAG_DEFEATED_RUSTBORO_GYM":1264,"FLAG_DEFEATED_SEASHORE_HOUSE":141,"FLAG_DEFEATED_SOOTOPOLIS_GYM":1271,"FLAG_DEFEATED_SS_TIDAL_TRAINERS":247,"FLAG_DEFEATED_SUDOWOODO":454,"FLAG_DEFEATED_VOLTORB_1_NEW_MAUVILLE":449,"FLAG_DEFEATED_VOLTORB_2_NEW_MAUVILLE":450,"FLAG_DEFEATED_VOLTORB_3_NEW_MAUVILLE":451,"FLAG_DEFEATED_WALLY_MAUVILLE":190,"FLAG_DEFEATED_WALLY_VICTORY_ROAD":126,"FLAG_DELIVERED_DEVON_GOODS":149,"FLAG_DELIVERED_STEVEN_LETTER":189,"FLAG_DEOXYS_IS_RECOVERING":1258,"FLAG_DEOXYS_ROCK_COMPLETE":2260,"FLAG_DEVON_GOODS_STOLEN":142,"FLAG_DOCK_REJECTED_DEVON_GOODS":148,"FLAG_DONT_TRANSITION_MUSIC":16385,"FLAG_ENABLE_BRAWLY_MATCH_CALL":468,"FLAG_ENABLE_FIRST_WALLY_POKENAV_CALL":136,"FLAG_ENABLE_FLANNERY_MATCH_CALL":470,"FLAG_ENABLE_JUAN_MATCH_CALL":473,"FLAG_ENABLE_MOM_MATCH_CALL":216,"FLAG_ENABLE_MR_STONE_POKENAV":344,"FLAG_ENABLE_MULTI_CORRIDOR_DOOR":16386,"FLAG_ENABLE_NORMAN_MATCH_CALL":306,"FLAG_ENABLE_PROF_BIRCH_MATCH_CALL":281,"FLAG_ENABLE_RIVAL_MATCH_CALL":253,"FLAG_ENABLE_ROXANNE_FIRST_CALL":128,"FLAG_ENABLE_ROXANNE_MATCH_CALL":467,"FLAG_ENABLE_SCOTT_MATCH_CALL":215,"FLAG_ENABLE_SHIP_BIRTH_ISLAND":2261,"FLAG_ENABLE_SHIP_FARAWAY_ISLAND":2262,"FLAG_ENABLE_SHIP_NAVEL_ROCK":2272,"FLAG_ENABLE_SHIP_SOUTHERN_ISLAND":2227,"FLAG_ENABLE_TATE_AND_LIZA_MATCH_CALL":472,"FLAG_ENABLE_WALLY_MATCH_CALL":214,"FLAG_ENABLE_WATTSON_MATCH_CALL":469,"FLAG_ENABLE_WINONA_MATCH_CALL":471,"FLAG_ENTERED_CONTEST":341,"FLAG_ENTERED_ELITE_FOUR":263,"FLAG_ENTERED_MIRAGE_TOWER":2268,"FLAG_EVIL_LEADER_PLEASE_STOP":219,"FLAG_EVIL_TEAM_ESCAPED_STERN_SPOKE":271,"FLAG_EXCHANGED_SCANNER":294,"FLAG_FAN_CLUB_STRENGTH_SHARED":210,"FLAG_FLOWER_SHOP_RECEIVED_BERRY":1207,"FLAG_FORCE_MIRAGE_TOWER_VISIBLE":157,"FLAG_FORTREE_NPC_TRADE_COMPLETED":155,"FLAG_GOOD_LUCK_SAFARI_ZONE":93,"FLAG_GOT_BASEMENT_KEY_FROM_WATTSON":208,"FLAG_GOT_TM_THUNDERBOLT_FROM_WATTSON":209,"FLAG_GROUDON_AWAKENED_MAGMA_HIDEOUT":111,"FLAG_GROUDON_IS_RECOVERING":1274,"FLAG_HAS_MATCH_CALL":303,"FLAG_HIDDEN_ITEMS_START":500,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":531,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":532,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":533,"FLAG_HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":534,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":601,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":604,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":603,"FLAG_HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":602,"FLAG_HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":528,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":548,"FLAG_HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":549,"FLAG_HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":577,"FLAG_HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":576,"FLAG_HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":500,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":527,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":575,"FLAG_HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":543,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":578,"FLAG_HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":529,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":580,"FLAG_HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":579,"FLAG_HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":609,"FLAG_HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":595,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":561,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_POTION":558,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":559,"FLAG_HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":560,"FLAG_HIDDEN_ITEM_ROUTE_104_ANTIDOTE":585,"FLAG_HIDDEN_ITEM_ROUTE_104_HEART_SCALE":588,"FLAG_HIDDEN_ITEM_ROUTE_104_POKE_BALL":562,"FLAG_HIDDEN_ITEM_ROUTE_104_POTION":537,"FLAG_HIDDEN_ITEM_ROUTE_104_SUPER_POTION":544,"FLAG_HIDDEN_ITEM_ROUTE_105_BIG_PEARL":611,"FLAG_HIDDEN_ITEM_ROUTE_105_HEART_SCALE":589,"FLAG_HIDDEN_ITEM_ROUTE_106_HEART_SCALE":547,"FLAG_HIDDEN_ITEM_ROUTE_106_POKE_BALL":563,"FLAG_HIDDEN_ITEM_ROUTE_106_STARDUST":546,"FLAG_HIDDEN_ITEM_ROUTE_108_RARE_CANDY":586,"FLAG_HIDDEN_ITEM_ROUTE_109_ETHER":564,"FLAG_HIDDEN_ITEM_ROUTE_109_GREAT_BALL":551,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":552,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":590,"FLAG_HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":591,"FLAG_HIDDEN_ITEM_ROUTE_109_REVIVE":550,"FLAG_HIDDEN_ITEM_ROUTE_110_FULL_HEAL":555,"FLAG_HIDDEN_ITEM_ROUTE_110_GREAT_BALL":553,"FLAG_HIDDEN_ITEM_ROUTE_110_POKE_BALL":565,"FLAG_HIDDEN_ITEM_ROUTE_110_REVIVE":554,"FLAG_HIDDEN_ITEM_ROUTE_111_PROTEIN":556,"FLAG_HIDDEN_ITEM_ROUTE_111_RARE_CANDY":557,"FLAG_HIDDEN_ITEM_ROUTE_111_STARDUST":502,"FLAG_HIDDEN_ITEM_ROUTE_113_ETHER":503,"FLAG_HIDDEN_ITEM_ROUTE_113_NUGGET":598,"FLAG_HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":530,"FLAG_HIDDEN_ITEM_ROUTE_114_CARBOS":504,"FLAG_HIDDEN_ITEM_ROUTE_114_REVIVE":542,"FLAG_HIDDEN_ITEM_ROUTE_115_HEART_SCALE":597,"FLAG_HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":596,"FLAG_HIDDEN_ITEM_ROUTE_116_SUPER_POTION":545,"FLAG_HIDDEN_ITEM_ROUTE_117_REPEL":572,"FLAG_HIDDEN_ITEM_ROUTE_118_HEART_SCALE":566,"FLAG_HIDDEN_ITEM_ROUTE_118_IRON":567,"FLAG_HIDDEN_ITEM_ROUTE_119_CALCIUM":505,"FLAG_HIDDEN_ITEM_ROUTE_119_FULL_HEAL":568,"FLAG_HIDDEN_ITEM_ROUTE_119_MAX_ETHER":587,"FLAG_HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":506,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":571,"FLAG_HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":569,"FLAG_HIDDEN_ITEM_ROUTE_120_REVIVE":584,"FLAG_HIDDEN_ITEM_ROUTE_120_ZINC":570,"FLAG_HIDDEN_ITEM_ROUTE_121_FULL_HEAL":573,"FLAG_HIDDEN_ITEM_ROUTE_121_HP_UP":539,"FLAG_HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":600,"FLAG_HIDDEN_ITEM_ROUTE_121_NUGGET":540,"FLAG_HIDDEN_ITEM_ROUTE_123_HYPER_POTION":574,"FLAG_HIDDEN_ITEM_ROUTE_123_PP_UP":599,"FLAG_HIDDEN_ITEM_ROUTE_123_RARE_CANDY":610,"FLAG_HIDDEN_ITEM_ROUTE_123_REVIVE":541,"FLAG_HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":507,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":592,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":593,"FLAG_HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":594,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":606,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":607,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":605,"FLAG_HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":608,"FLAG_HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":535,"FLAG_HIDDEN_ITEM_TRICK_HOUSE_NUGGET":501,"FLAG_HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":511,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CALCIUM":536,"FLAG_HIDDEN_ITEM_UNDERWATER_124_CARBOS":508,"FLAG_HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":509,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":513,"FLAG_HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":538,"FLAG_HIDDEN_ITEM_UNDERWATER_124_PEARL":510,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":520,"FLAG_HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":512,"FLAG_HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":514,"FLAG_HIDDEN_ITEM_UNDERWATER_126_IRON":519,"FLAG_HIDDEN_ITEM_UNDERWATER_126_PEARL":517,"FLAG_HIDDEN_ITEM_UNDERWATER_126_STARDUST":516,"FLAG_HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":515,"FLAG_HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":518,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":523,"FLAG_HIDDEN_ITEM_UNDERWATER_127_HP_UP":522,"FLAG_HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":524,"FLAG_HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":521,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PEARL":526,"FLAG_HIDDEN_ITEM_UNDERWATER_128_PROTEIN":525,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":581,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":582,"FLAG_HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":583,"FLAG_HIDE_APPRENTICE":701,"FLAG_HIDE_AQUA_HIDEOUT_1F_GRUNTS_BLOCKING_ENTRANCE":821,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_1":977,"FLAG_HIDE_AQUA_HIDEOUT_B1F_ELECTRODE_2":978,"FLAG_HIDE_AQUA_HIDEOUT_B2F_SUBMARINE_SHADOW":943,"FLAG_HIDE_AQUA_HIDEOUT_GRUNTS":924,"FLAG_HIDE_BATTLE_FRONTIER_RECEPTION_GATE_SCOTT":836,"FLAG_HIDE_BATTLE_FRONTIER_SUDOWOODO":842,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_1":711,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_2":712,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_3":713,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_4":714,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_5":715,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_6":716,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_1":864,"FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_2":865,"FLAG_HIDE_BATTLE_TOWER_OPPONENT":888,"FLAG_HIDE_BATTLE_TOWER_REPORTER":918,"FLAG_HIDE_BIRTH_ISLAND_DEOXYS_TRIANGLE":764,"FLAG_HIDE_BRINEYS_HOUSE_MR_BRINEY":739,"FLAG_HIDE_BRINEYS_HOUSE_PEEKO":881,"FLAG_HIDE_CAVE_OF_ORIGIN_B1F_WALLACE":820,"FLAG_HIDE_CHAMPIONS_ROOM_BIRCH":921,"FLAG_HIDE_CHAMPIONS_ROOM_RIVAL":920,"FLAG_HIDE_CONTEST_POKE_BALL":86,"FLAG_HIDE_DEOXYS":763,"FLAG_HIDE_DESERT_UNDERPASS_FOSSIL":874,"FLAG_HIDE_DEWFORD_HALL_SLUDGE_BOMB_MAN":940,"FLAG_HIDE_EVER_GRANDE_POKEMON_CENTER_1F_SCOTT":793,"FLAG_HIDE_FALLARBOR_AZURILL":907,"FLAG_HIDE_FALLARBOR_HOUSE_PROF_COZMO":928,"FLAG_HIDE_FALLARBOR_TOWN_BATTLE_TENT_SCOTT":767,"FLAG_HIDE_FALLORBOR_POKEMON_CENTER_LANETTE":871,"FLAG_HIDE_FANCLUB_BOY":790,"FLAG_HIDE_FANCLUB_LADY":792,"FLAG_HIDE_FANCLUB_LITTLE_BOY":791,"FLAG_HIDE_FANCLUB_OLD_LADY":789,"FLAG_HIDE_FORTREE_CITY_HOUSE_4_WINGULL":933,"FLAG_HIDE_FORTREE_CITY_KECLEON":969,"FLAG_HIDE_GRANITE_CAVE_STEVEN":833,"FLAG_HIDE_HO_OH":801,"FLAG_HIDE_JAGGED_PASS_MAGMA_GUARD":847,"FLAG_HIDE_LANETTES_HOUSE_LANETTE":870,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL":929,"FLAG_HIDE_LAVARIDGE_TOWN_RIVAL_ON_BIKE":930,"FLAG_HIDE_LILYCOVE_CITY_AQUA_GRUNTS":852,"FLAG_HIDE_LILYCOVE_CITY_RIVAL":971,"FLAG_HIDE_LILYCOVE_CITY_WAILMER":729,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER":832,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER_REPLACEMENT":873,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_1":774,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_CONTEST_ATTENDANT_2":895,"FLAG_HIDE_LILYCOVE_CONTEST_HALL_REPORTER":802,"FLAG_HIDE_LILYCOVE_DEPARTMENT_STORE_ROOFTOP_SALE_WOMAN":962,"FLAG_HIDE_LILYCOVE_FAN_CLUB_INTERVIEWER":730,"FLAG_HIDE_LILYCOVE_HARBOR_EVENT_TICKET_TAKER":748,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_ATTENDANT":908,"FLAG_HIDE_LILYCOVE_HARBOR_FERRY_SAILOR":909,"FLAG_HIDE_LILYCOVE_HARBOR_SSTIDAL":861,"FLAG_HIDE_LILYCOVE_MOTEL_GAME_DESIGNERS":925,"FLAG_HIDE_LILYCOVE_MOTEL_SCOTT":787,"FLAG_HIDE_LILYCOVE_MUSEUM_CURATOR":775,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_1":776,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_2":777,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_3":778,"FLAG_HIDE_LILYCOVE_MUSEUM_PATRON_4":779,"FLAG_HIDE_LILYCOVE_MUSEUM_TOURISTS":780,"FLAG_HIDE_LILYCOVE_POKEMON_CENTER_CONTEST_LADY_MON":993,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCH":795,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_BIRCH":721,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CHIKORITA":838,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_CYNDAQUIL":811,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_POKEBALL_TOTODILE":812,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_RIVAL":889,"FLAG_HIDE_LITTLEROOT_TOWN_BIRCHS_LAB_UNKNOWN_0x380":896,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_POKE_BALL":817,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F_SWABLU_DOLL":815,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_BRENDAN":745,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_MOM":758,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_BEDROOM":760,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_MOM":784,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_RIVAL_SIBLING":735,"FLAG_HIDE_LITTLEROOT_TOWN_BRENDANS_HOUSE_TRUCK":761,"FLAG_HIDE_LITTLEROOT_TOWN_FAT_MAN":868,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_PICHU_DOLL":849,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_2F_POKE_BALL":818,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MAY":746,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_MOM":759,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_BEDROOM":722,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_MOM":785,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_RIVAL_SIBLING":736,"FLAG_HIDE_LITTLEROOT_TOWN_MAYS_HOUSE_TRUCK":762,"FLAG_HIDE_LITTLEROOT_TOWN_MOM_OUTSIDE":752,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_BEDROOM_MOM":757,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_1":754,"FLAG_HIDE_LITTLEROOT_TOWN_PLAYERS_HOUSE_VIGOROTH_2":755,"FLAG_HIDE_LITTLEROOT_TOWN_RIVAL":794,"FLAG_HIDE_LUGIA":800,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON":853,"FLAG_HIDE_MAGMA_HIDEOUT_4F_GROUDON_ASLEEP":850,"FLAG_HIDE_MAGMA_HIDEOUT_GRUNTS":857,"FLAG_HIDE_MAGMA_HIDEOUT_MAXIE":867,"FLAG_HIDE_MAP_NAME_POPUP":16384,"FLAG_HIDE_MARINE_CAVE_KYOGRE":782,"FLAG_HIDE_MAUVILLE_CITY_SCOTT":765,"FLAG_HIDE_MAUVILLE_CITY_WALLY":804,"FLAG_HIDE_MAUVILLE_CITY_WALLYS_UNCLE":805,"FLAG_HIDE_MAUVILLE_CITY_WATTSON":912,"FLAG_HIDE_MAUVILLE_GYM_WATTSON":913,"FLAG_HIDE_METEOR_FALLS_1F_1R_COZMO":942,"FLAG_HIDE_METEOR_FALLS_TEAM_AQUA":938,"FLAG_HIDE_METEOR_FALLS_TEAM_MAGMA":939,"FLAG_HIDE_MEW":718,"FLAG_HIDE_MIRAGE_TOWER_CLAW_FOSSIL":964,"FLAG_HIDE_MIRAGE_TOWER_ROOT_FOSSIL":963,"FLAG_HIDE_MOSSDEEP_CITY_HOUSE_2_WINGULL":934,"FLAG_HIDE_MOSSDEEP_CITY_SCOTT":788,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_STEVEN":753,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_1F_TEAM_MAGMA":756,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_STEVEN":863,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_2F_TEAM_MAGMA":862,"FLAG_HIDE_MOSSDEEP_CITY_SPACE_CENTER_MAGMA_NOTE":737,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_BELDUM_POKEBALL":968,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_INVISIBLE_NINJA_BOY":727,"FLAG_HIDE_MOSSDEEP_CITY_STEVENS_HOUSE_STEVEN":967,"FLAG_HIDE_MOSSDEEP_CITY_TEAM_MAGMA":823,"FLAG_HIDE_MR_BRINEY_BOAT_DEWFORD_TOWN":743,"FLAG_HIDE_MR_BRINEY_DEWFORD_TOWN":740,"FLAG_HIDE_MT_CHIMNEY_LAVA_COOKIE_LADY":994,"FLAG_HIDE_MT_CHIMNEY_TEAM_AQUA":926,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA":927,"FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA_BATTLEABLE":981,"FLAG_HIDE_MT_CHIMNEY_TRAINERS":877,"FLAG_HIDE_MT_PYRE_SUMMIT_ARCHIE":916,"FLAG_HIDE_MT_PYRE_SUMMIT_MAXIE":856,"FLAG_HIDE_MT_PYRE_SUMMIT_TEAM_AQUA":917,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_1":974,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_2":975,"FLAG_HIDE_NEW_MAUVILLE_VOLTORB_3":976,"FLAG_HIDE_OLDALE_TOWN_RIVAL":979,"FLAG_HIDE_PETALBURG_CITY_SCOTT":995,"FLAG_HIDE_PETALBURG_CITY_WALLY":726,"FLAG_HIDE_PETALBURG_CITY_WALLYS_DAD":830,"FLAG_HIDE_PETALBURG_CITY_WALLYS_MOM":728,"FLAG_HIDE_PETALBURG_GYM_GREETER":781,"FLAG_HIDE_PETALBURG_GYM_NORMAN":772,"FLAG_HIDE_PETALBURG_GYM_WALLY":866,"FLAG_HIDE_PETALBURG_GYM_WALLYS_DAD":824,"FLAG_HIDE_PETALBURG_WOODS_AQUA_GRUNT":725,"FLAG_HIDE_PETALBURG_WOODS_DEVON_EMPLOYEE":724,"FLAG_HIDE_PLAYERS_HOUSE_DAD":734,"FLAG_HIDE_POKEMON_CENTER_2F_MYSTERY_GIFT_MAN":702,"FLAG_HIDE_REGICE":936,"FLAG_HIDE_REGIROCK":935,"FLAG_HIDE_REGISTEEL":937,"FLAG_HIDE_ROUTE_101_BIRCH":897,"FLAG_HIDE_ROUTE_101_BIRCH_STARTERS_BAG":700,"FLAG_HIDE_ROUTE_101_BIRCH_ZIGZAGOON_BATTLE":720,"FLAG_HIDE_ROUTE_101_BOY":991,"FLAG_HIDE_ROUTE_101_ZIGZAGOON":750,"FLAG_HIDE_ROUTE_103_BIRCH":898,"FLAG_HIDE_ROUTE_103_RIVAL":723,"FLAG_HIDE_ROUTE_104_MR_BRINEY":738,"FLAG_HIDE_ROUTE_104_MR_BRINEY_BOAT":742,"FLAG_HIDE_ROUTE_104_RIVAL":719,"FLAG_HIDE_ROUTE_104_WHITE_HERB_FLORIST":906,"FLAG_HIDE_ROUTE_109_MR_BRINEY":741,"FLAG_HIDE_ROUTE_109_MR_BRINEY_BOAT":744,"FLAG_HIDE_ROUTE_110_BIRCH":837,"FLAG_HIDE_ROUTE_110_RIVAL":919,"FLAG_HIDE_ROUTE_110_RIVAL_ON_BIKE":922,"FLAG_HIDE_ROUTE_110_TEAM_AQUA":900,"FLAG_HIDE_ROUTE_111_DESERT_FOSSIL":876,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_1":796,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_2":903,"FLAG_HIDE_ROUTE_111_GABBY_AND_TY_3":799,"FLAG_HIDE_ROUTE_111_PLAYER_DESCENT":875,"FLAG_HIDE_ROUTE_111_ROCK_SMASH_TIP_GUY":843,"FLAG_HIDE_ROUTE_111_SECRET_POWER_MAN":960,"FLAG_HIDE_ROUTE_111_VICKY_WINSTRATE":771,"FLAG_HIDE_ROUTE_111_VICTORIA_WINSTRATE":769,"FLAG_HIDE_ROUTE_111_VICTOR_WINSTRATE":768,"FLAG_HIDE_ROUTE_111_VIVI_WINSTRATE":770,"FLAG_HIDE_ROUTE_112_TEAM_MAGMA":819,"FLAG_HIDE_ROUTE_115_BOULDERS":825,"FLAG_HIDE_ROUTE_116_DEVON_EMPLOYEE":947,"FLAG_HIDE_ROUTE_116_DROPPED_GLASSES_MAN":813,"FLAG_HIDE_ROUTE_116_MR_BRINEY":891,"FLAG_HIDE_ROUTE_116_WANDAS_BOYFRIEND":894,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_1":797,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_2":901,"FLAG_HIDE_ROUTE_118_GABBY_AND_TY_3":904,"FLAG_HIDE_ROUTE_118_STEVEN":966,"FLAG_HIDE_ROUTE_119_RIVAL":851,"FLAG_HIDE_ROUTE_119_RIVAL_ON_BIKE":923,"FLAG_HIDE_ROUTE_119_SCOTT":786,"FLAG_HIDE_ROUTE_119_TEAM_AQUA":890,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_BRIDGE":822,"FLAG_HIDE_ROUTE_119_TEAM_AQUA_SHELLY":915,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_1":798,"FLAG_HIDE_ROUTE_120_GABBY_AND_TY_2":902,"FLAG_HIDE_ROUTE_120_STEVEN":972,"FLAG_HIDE_ROUTE_121_TEAM_AQUA_GRUNTS":914,"FLAG_HIDE_ROUTE_128_ARCHIE":944,"FLAG_HIDE_ROUTE_128_MAXIE":945,"FLAG_HIDE_ROUTE_128_STEVEN":834,"FLAG_HIDE_RUSTBORO_CITY_AQUA_GRUNT":731,"FLAG_HIDE_RUSTBORO_CITY_DEVON_CORP_3F_EMPLOYEE":949,"FLAG_HIDE_RUSTBORO_CITY_DEVON_EMPLOYEE_1":732,"FLAG_HIDE_RUSTBORO_CITY_POKEMON_SCHOOL_SCOTT":999,"FLAG_HIDE_RUSTBORO_CITY_RIVAL":814,"FLAG_HIDE_RUSTBORO_CITY_SCIENTIST":844,"FLAG_HIDE_RUSTURF_TUNNEL_AQUA_GRUNT":878,"FLAG_HIDE_RUSTURF_TUNNEL_BRINEY":879,"FLAG_HIDE_RUSTURF_TUNNEL_PEEKO":880,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_1":931,"FLAG_HIDE_RUSTURF_TUNNEL_ROCK_2":932,"FLAG_HIDE_RUSTURF_TUNNEL_WANDA":983,"FLAG_HIDE_RUSTURF_TUNNEL_WANDAS_BOYFRIEND":807,"FLAG_HIDE_SAFARI_ZONE_SOUTH_CONSTRUCTION_WORKERS":717,"FLAG_HIDE_SAFARI_ZONE_SOUTH_EAST_EXPANSION":747,"FLAG_HIDE_SEAFLOOR_CAVERN_AQUA_GRUNTS":946,"FLAG_HIDE_SEAFLOOR_CAVERN_ENTRANCE_AQUA_GRUNT":941,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_ARCHIE":828,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE":859,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_KYOGRE_ASLEEP":733,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAGMA_GRUNTS":831,"FLAG_HIDE_SEAFLOOR_CAVERN_ROOM_9_MAXIE":829,"FLAG_HIDE_SECRET_BASE_TRAINER":173,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA":773,"FLAG_HIDE_SKY_PILLAR_TOP_RAYQUAZA_STILL":80,"FLAG_HIDE_SKY_PILLAR_WALLACE":855,"FLAG_HIDE_SLATEPORT_CITY_CAPTAIN_STERN":840,"FLAG_HIDE_SLATEPORT_CITY_CONTEST_REPORTER":803,"FLAG_HIDE_SLATEPORT_CITY_GABBY_AND_TY":835,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_AQUA_GRUNT":845,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_ARCHIE":846,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_CAPTAIN_STERN":841,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_PATRONS":905,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SS_TIDAL":860,"FLAG_HIDE_SLATEPORT_CITY_HARBOR_SUBMARINE_SHADOW":848,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_1":884,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_AQUA_GRUNT_2":885,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_ARCHIE":886,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_2F_CAPTAIN_STERN":887,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_AQUA_GRUNTS":883,"FLAG_HIDE_SLATEPORT_CITY_OCEANIC_MUSEUM_FAMILIAR_AQUA_GRUNT":965,"FLAG_HIDE_SLATEPORT_CITY_SCOTT":749,"FLAG_HIDE_SLATEPORT_CITY_STERNS_SHIPYARD_MR_BRINEY":869,"FLAG_HIDE_SLATEPORT_CITY_TEAM_AQUA":882,"FLAG_HIDE_SLATEPORT_CITY_TM_SALESMAN":948,"FLAG_HIDE_SLATEPORT_MUSEUM_POPULATION":961,"FLAG_HIDE_SOOTOPOLIS_CITY_ARCHIE":826,"FLAG_HIDE_SOOTOPOLIS_CITY_GROUDON":998,"FLAG_HIDE_SOOTOPOLIS_CITY_KYOGRE":997,"FLAG_HIDE_SOOTOPOLIS_CITY_MAN_1":839,"FLAG_HIDE_SOOTOPOLIS_CITY_MAXIE":827,"FLAG_HIDE_SOOTOPOLIS_CITY_RAYQUAZA":996,"FLAG_HIDE_SOOTOPOLIS_CITY_RESIDENTS":854,"FLAG_HIDE_SOOTOPOLIS_CITY_STEVEN":973,"FLAG_HIDE_SOOTOPOLIS_CITY_WALLACE":816,"FLAG_HIDE_SOUTHERN_ISLAND_EON_STONE":910,"FLAG_HIDE_SOUTHERN_ISLAND_UNCHOSEN_EON_DUO_MON":911,"FLAG_HIDE_SS_TIDAL_CORRIDOR_MR_BRINEY":950,"FLAG_HIDE_SS_TIDAL_CORRIDOR_SCOTT":810,"FLAG_HIDE_SS_TIDAL_ROOMS_SNATCH_GIVER":951,"FLAG_HIDE_TERRA_CAVE_GROUDON":783,"FLAG_HIDE_TRICK_HOUSE_END_MAN":899,"FLAG_HIDE_TRICK_HOUSE_ENTRANCE_MAN":872,"FLAG_HIDE_UNDERWATER_SEA_FLOOR_CAVERN_STOLEN_SUBMARINE":980,"FLAG_HIDE_UNION_ROOM_PLAYER_1":703,"FLAG_HIDE_UNION_ROOM_PLAYER_2":704,"FLAG_HIDE_UNION_ROOM_PLAYER_3":705,"FLAG_HIDE_UNION_ROOM_PLAYER_4":706,"FLAG_HIDE_UNION_ROOM_PLAYER_5":707,"FLAG_HIDE_UNION_ROOM_PLAYER_6":708,"FLAG_HIDE_UNION_ROOM_PLAYER_7":709,"FLAG_HIDE_UNION_ROOM_PLAYER_8":710,"FLAG_HIDE_VERDANTURF_TOWN_SCOTT":766,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLY":806,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WALLYS_UNCLE":809,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDA":984,"FLAG_HIDE_VERDANTURF_TOWN_WANDAS_HOUSE_WANDAS_BOYFRIEND":808,"FLAG_HIDE_VICTORY_ROAD_ENTRANCE_WALLY":858,"FLAG_HIDE_VICTORY_ROAD_EXIT_WALLY":751,"FLAG_HIDE_WEATHER_INSTITUTE_1F_WORKERS":892,"FLAG_HIDE_WEATHER_INSTITUTE_2F_AQUA_GRUNT_M":992,"FLAG_HIDE_WEATHER_INSTITUTE_2F_WORKERS":893,"FLAG_HO_OH_IS_RECOVERING":1256,"FLAG_INTERACTED_WITH_DEVON_EMPLOYEE_GOODS_STOLEN":159,"FLAG_INTERACTED_WITH_STEVEN_SPACE_CENTER":205,"FLAG_IS_CHAMPION":2175,"FLAG_ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":1100,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":1102,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":1078,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":1101,"FLAG_ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":1077,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":1095,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":1099,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":1097,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":1096,"FLAG_ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":1098,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":1124,"FLAG_ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":1071,"FLAG_ITEM_AQUA_HIDEOUT_B1F_NUGGET":1132,"FLAG_ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":1072,"FLAG_ITEM_ARTISAN_CAVE_1F_CARBOS":1163,"FLAG_ITEM_ARTISAN_CAVE_B1F_HP_UP":1162,"FLAG_ITEM_FIERY_PATH_FIRE_STONE":1111,"FLAG_ITEM_FIERY_PATH_TM_TOXIC":1091,"FLAG_ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":1050,"FLAG_ITEM_GRANITE_CAVE_B1F_POKE_BALL":1051,"FLAG_ITEM_GRANITE_CAVE_B2F_RARE_CANDY":1054,"FLAG_ITEM_GRANITE_CAVE_B2F_REPEL":1053,"FLAG_ITEM_JAGGED_PASS_BURN_HEAL":1070,"FLAG_ITEM_LILYCOVE_CITY_MAX_REPEL":1042,"FLAG_ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":1151,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":1165,"FLAG_ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":1164,"FLAG_ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":1166,"FLAG_ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":1167,"FLAG_ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":1059,"FLAG_ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":1168,"FLAG_ITEM_MAUVILLE_CITY_X_SPEED":1116,"FLAG_ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":1045,"FLAG_ITEM_METEOR_FALLS_1F_1R_MOON_STONE":1046,"FLAG_ITEM_METEOR_FALLS_1F_1R_PP_UP":1047,"FLAG_ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":1044,"FLAG_ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":1080,"FLAG_ITEM_MOSSDEEP_CITY_NET_BALL":1043,"FLAG_ITEM_MOSSDEEP_STEVENS_HOUSE_HM08":1133,"FLAG_ITEM_MT_PYRE_2F_ULTRA_BALL":1129,"FLAG_ITEM_MT_PYRE_3F_SUPER_REPEL":1120,"FLAG_ITEM_MT_PYRE_4F_SEA_INCENSE":1130,"FLAG_ITEM_MT_PYRE_5F_LAX_INCENSE":1052,"FLAG_ITEM_MT_PYRE_6F_TM_SHADOW_BALL":1089,"FLAG_ITEM_MT_PYRE_EXTERIOR_MAX_POTION":1073,"FLAG_ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":1074,"FLAG_ITEM_NEW_MAUVILLE_ESCAPE_ROPE":1076,"FLAG_ITEM_NEW_MAUVILLE_FULL_HEAL":1122,"FLAG_ITEM_NEW_MAUVILLE_PARALYZE_HEAL":1123,"FLAG_ITEM_NEW_MAUVILLE_THUNDER_STONE":1110,"FLAG_ITEM_NEW_MAUVILLE_ULTRA_BALL":1075,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MASTER_BALL":1125,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B1F_MAX_ELIXIR":1126,"FLAG_ITEM_OLD_MAGMA_HIDEOUT_B2F_NEST_BALL":1127,"FLAG_ITEM_PETALBURG_CITY_ETHER":1040,"FLAG_ITEM_PETALBURG_CITY_MAX_REVIVE":1039,"FLAG_ITEM_PETALBURG_WOODS_ETHER":1058,"FLAG_ITEM_PETALBURG_WOODS_GREAT_BALL":1056,"FLAG_ITEM_PETALBURG_WOODS_PARALYZE_HEAL":1117,"FLAG_ITEM_PETALBURG_WOODS_X_ATTACK":1055,"FLAG_ITEM_ROUTE_102_POTION":1000,"FLAG_ITEM_ROUTE_103_GUARD_SPEC":1114,"FLAG_ITEM_ROUTE_103_PP_UP":1137,"FLAG_ITEM_ROUTE_104_POKE_BALL":1057,"FLAG_ITEM_ROUTE_104_POTION":1135,"FLAG_ITEM_ROUTE_104_PP_UP":1002,"FLAG_ITEM_ROUTE_104_X_ACCURACY":1115,"FLAG_ITEM_ROUTE_105_IRON":1003,"FLAG_ITEM_ROUTE_106_PROTEIN":1004,"FLAG_ITEM_ROUTE_108_STAR_PIECE":1139,"FLAG_ITEM_ROUTE_109_POTION":1140,"FLAG_ITEM_ROUTE_109_PP_UP":1005,"FLAG_ITEM_ROUTE_110_DIRE_HIT":1007,"FLAG_ITEM_ROUTE_110_ELIXIR":1141,"FLAG_ITEM_ROUTE_110_RARE_CANDY":1006,"FLAG_ITEM_ROUTE_111_ELIXIR":1142,"FLAG_ITEM_ROUTE_111_HP_UP":1010,"FLAG_ITEM_ROUTE_111_STARDUST":1009,"FLAG_ITEM_ROUTE_111_TM_SANDSTORM":1008,"FLAG_ITEM_ROUTE_112_NUGGET":1011,"FLAG_ITEM_ROUTE_113_HYPER_POTION":1143,"FLAG_ITEM_ROUTE_113_MAX_ETHER":1012,"FLAG_ITEM_ROUTE_113_SUPER_REPEL":1013,"FLAG_ITEM_ROUTE_114_ENERGY_POWDER":1160,"FLAG_ITEM_ROUTE_114_PROTEIN":1015,"FLAG_ITEM_ROUTE_114_RARE_CANDY":1014,"FLAG_ITEM_ROUTE_115_GREAT_BALL":1118,"FLAG_ITEM_ROUTE_115_HEAL_POWDER":1144,"FLAG_ITEM_ROUTE_115_IRON":1018,"FLAG_ITEM_ROUTE_115_PP_UP":1161,"FLAG_ITEM_ROUTE_115_SUPER_POTION":1016,"FLAG_ITEM_ROUTE_115_TM_FOCUS_PUNCH":1017,"FLAG_ITEM_ROUTE_116_ETHER":1019,"FLAG_ITEM_ROUTE_116_HP_UP":1021,"FLAG_ITEM_ROUTE_116_POTION":1146,"FLAG_ITEM_ROUTE_116_REPEL":1020,"FLAG_ITEM_ROUTE_116_X_SPECIAL":1001,"FLAG_ITEM_ROUTE_117_GREAT_BALL":1022,"FLAG_ITEM_ROUTE_117_REVIVE":1023,"FLAG_ITEM_ROUTE_118_HYPER_POTION":1121,"FLAG_ITEM_ROUTE_119_ELIXIR_1":1026,"FLAG_ITEM_ROUTE_119_ELIXIR_2":1147,"FLAG_ITEM_ROUTE_119_HYPER_POTION_1":1029,"FLAG_ITEM_ROUTE_119_HYPER_POTION_2":1106,"FLAG_ITEM_ROUTE_119_LEAF_STONE":1027,"FLAG_ITEM_ROUTE_119_NUGGET":1134,"FLAG_ITEM_ROUTE_119_RARE_CANDY":1028,"FLAG_ITEM_ROUTE_119_SUPER_REPEL":1024,"FLAG_ITEM_ROUTE_119_ZINC":1025,"FLAG_ITEM_ROUTE_120_FULL_HEAL":1031,"FLAG_ITEM_ROUTE_120_HYPER_POTION":1107,"FLAG_ITEM_ROUTE_120_NEST_BALL":1108,"FLAG_ITEM_ROUTE_120_NUGGET":1030,"FLAG_ITEM_ROUTE_120_REVIVE":1148,"FLAG_ITEM_ROUTE_121_CARBOS":1103,"FLAG_ITEM_ROUTE_121_REVIVE":1149,"FLAG_ITEM_ROUTE_121_ZINC":1150,"FLAG_ITEM_ROUTE_123_CALCIUM":1032,"FLAG_ITEM_ROUTE_123_ELIXIR":1109,"FLAG_ITEM_ROUTE_123_PP_UP":1152,"FLAG_ITEM_ROUTE_123_REVIVAL_HERB":1153,"FLAG_ITEM_ROUTE_123_ULTRA_BALL":1104,"FLAG_ITEM_ROUTE_124_BLUE_SHARD":1093,"FLAG_ITEM_ROUTE_124_RED_SHARD":1092,"FLAG_ITEM_ROUTE_124_YELLOW_SHARD":1066,"FLAG_ITEM_ROUTE_125_BIG_PEARL":1154,"FLAG_ITEM_ROUTE_126_GREEN_SHARD":1105,"FLAG_ITEM_ROUTE_127_CARBOS":1035,"FLAG_ITEM_ROUTE_127_RARE_CANDY":1155,"FLAG_ITEM_ROUTE_127_ZINC":1034,"FLAG_ITEM_ROUTE_132_PROTEIN":1156,"FLAG_ITEM_ROUTE_132_RARE_CANDY":1036,"FLAG_ITEM_ROUTE_133_BIG_PEARL":1037,"FLAG_ITEM_ROUTE_133_MAX_REVIVE":1157,"FLAG_ITEM_ROUTE_133_STAR_PIECE":1038,"FLAG_ITEM_ROUTE_134_CARBOS":1158,"FLAG_ITEM_ROUTE_134_STAR_PIECE":1159,"FLAG_ITEM_RUSTBORO_CITY_X_DEFEND":1041,"FLAG_ITEM_RUSTURF_TUNNEL_MAX_ETHER":1049,"FLAG_ITEM_RUSTURF_TUNNEL_POKE_BALL":1048,"FLAG_ITEM_SAFARI_ZONE_NORTH_CALCIUM":1119,"FLAG_ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":1169,"FLAG_ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":1094,"FLAG_ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":1170,"FLAG_ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":1131,"FLAG_ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":1079,"FLAG_ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":1090,"FLAG_ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":1081,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":1113,"FLAG_ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":1112,"FLAG_ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":1082,"FLAG_ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":1083,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":1060,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":1061,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":1062,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":1063,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":1064,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":1065,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":1067,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":1068,"FLAG_ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":1069,"FLAG_ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":1084,"FLAG_ITEM_VICTORY_ROAD_1F_PP_UP":1085,"FLAG_ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":1087,"FLAG_ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":1086,"FLAG_ITEM_VICTORY_ROAD_B2F_FULL_HEAL":1088,"FLAG_KECLEON_FLED_FORTREE":295,"FLAG_KYOGRE_ESCAPED_SEAFLOOR_CAVERN":129,"FLAG_KYOGRE_IS_RECOVERING":1273,"FLAG_LANDMARK_ABANDONED_SHIP":2206,"FLAG_LANDMARK_ALTERING_CAVE":2269,"FLAG_LANDMARK_ANCIENT_TOMB":2233,"FLAG_LANDMARK_ARTISAN_CAVE":2271,"FLAG_LANDMARK_BATTLE_FRONTIER":2216,"FLAG_LANDMARK_BERRY_MASTERS_HOUSE":2243,"FLAG_LANDMARK_DESERT_RUINS":2230,"FLAG_LANDMARK_DESERT_UNDERPASS":2270,"FLAG_LANDMARK_FIERY_PATH":2218,"FLAG_LANDMARK_FLOWER_SHOP":2204,"FLAG_LANDMARK_FOSSIL_MANIACS_HOUSE":2231,"FLAG_LANDMARK_GLASS_WORKSHOP":2212,"FLAG_LANDMARK_HUNTERS_HOUSE":2235,"FLAG_LANDMARK_ISLAND_CAVE":2229,"FLAG_LANDMARK_LANETTES_HOUSE":2213,"FLAG_LANDMARK_MIRAGE_TOWER":120,"FLAG_LANDMARK_MR_BRINEY_HOUSE":2205,"FLAG_LANDMARK_NEW_MAUVILLE":2208,"FLAG_LANDMARK_OLD_LADY_REST_SHOP":2209,"FLAG_LANDMARK_POKEMON_DAYCARE":2214,"FLAG_LANDMARK_POKEMON_LEAGUE":2228,"FLAG_LANDMARK_SCORCHED_SLAB":2232,"FLAG_LANDMARK_SEAFLOOR_CAVERN":2215,"FLAG_LANDMARK_SEALED_CHAMBER":2236,"FLAG_LANDMARK_SEASHORE_HOUSE":2207,"FLAG_LANDMARK_SKY_PILLAR":2238,"FLAG_LANDMARK_SOUTHERN_ISLAND":2217,"FLAG_LANDMARK_TRAINER_HILL":2274,"FLAG_LANDMARK_TRICK_HOUSE":2210,"FLAG_LANDMARK_TUNNELERS_REST_HOUSE":2234,"FLAG_LANDMARK_WINSTRATE_FAMILY":2211,"FLAG_LATIAS_IS_RECOVERING":1263,"FLAG_LATIOS_IS_RECOVERING":1255,"FLAG_LATIOS_OR_LATIAS_ROAMING":255,"FLAG_LEGENDARIES_IN_SOOTOPOLIS":83,"FLAG_LILYCOVE_RECEIVED_BERRY":1208,"FLAG_LUGIA_IS_RECOVERING":1257,"FLAG_MAP_SCRIPT_CHECKED_DEOXYS":2259,"FLAG_MATCH_CALL_REGISTERED":348,"FLAG_MAUVILLE_GYM_BARRIERS_STATE":99,"FLAG_MET_ARCHIE_METEOR_FALLS":207,"FLAG_MET_ARCHIE_SOOTOPOLIS":308,"FLAG_MET_BATTLE_FRONTIER_BREEDER":339,"FLAG_MET_BATTLE_FRONTIER_GAMBLER":343,"FLAG_MET_BATTLE_FRONTIER_MANIAC":340,"FLAG_MET_DEVON_EMPLOYEE":287,"FLAG_MET_DIVING_TREASURE_HUNTER":217,"FLAG_MET_FANCLUB_YOUNGER_BROTHER":300,"FLAG_MET_FRONTIER_BEAUTY_MOVE_TUTOR":346,"FLAG_MET_FRONTIER_SWIMMER_MOVE_TUTOR":347,"FLAG_MET_HIDDEN_POWER_GIVER":118,"FLAG_MET_MAXIE_SOOTOPOLIS":309,"FLAG_MET_PRETTY_PETAL_SHOP_OWNER":127,"FLAG_MET_PROF_COZMO":244,"FLAG_MET_RIVAL_IN_HOUSE_AFTER_LILYCOVE":293,"FLAG_MET_RIVAL_LILYCOVE":292,"FLAG_MET_RIVAL_MOM":87,"FLAG_MET_RIVAL_RUSTBORO":288,"FLAG_MET_SCOTT_AFTER_OBTAINING_STONE_BADGE":459,"FLAG_MET_SCOTT_IN_EVERGRANDE":463,"FLAG_MET_SCOTT_IN_FALLARBOR":461,"FLAG_MET_SCOTT_IN_LILYCOVE":462,"FLAG_MET_SCOTT_IN_VERDANTURF":460,"FLAG_MET_SCOTT_ON_SS_TIDAL":464,"FLAG_MET_SCOTT_RUSTBORO":310,"FLAG_MET_SLATEPORT_FANCLUB_CHAIRMAN":342,"FLAG_MET_TEAM_AQUA_HARBOR":97,"FLAG_MET_WAILMER_TRAINER":218,"FLAG_MEW_IS_RECOVERING":1259,"FLAG_MIRAGE_TOWER_VISIBLE":334,"FLAG_MOSSDEEP_GYM_SWITCH_1":100,"FLAG_MOSSDEEP_GYM_SWITCH_2":101,"FLAG_MOSSDEEP_GYM_SWITCH_3":102,"FLAG_MOSSDEEP_GYM_SWITCH_4":103,"FLAG_MOVE_TUTOR_TAUGHT_DOUBLE_EDGE":441,"FLAG_MOVE_TUTOR_TAUGHT_DYNAMICPUNCH":440,"FLAG_MOVE_TUTOR_TAUGHT_EXPLOSION":442,"FLAG_MOVE_TUTOR_TAUGHT_FURY_CUTTER":435,"FLAG_MOVE_TUTOR_TAUGHT_METRONOME":437,"FLAG_MOVE_TUTOR_TAUGHT_MIMIC":436,"FLAG_MOVE_TUTOR_TAUGHT_ROLLOUT":434,"FLAG_MOVE_TUTOR_TAUGHT_SLEEP_TALK":438,"FLAG_MOVE_TUTOR_TAUGHT_SUBSTITUTE":439,"FLAG_MOVE_TUTOR_TAUGHT_SWAGGER":433,"FLAG_MR_BRINEY_SAILING_INTRO":147,"FLAG_MYSTERY_GIFT_1":485,"FLAG_MYSTERY_GIFT_10":494,"FLAG_MYSTERY_GIFT_11":495,"FLAG_MYSTERY_GIFT_12":496,"FLAG_MYSTERY_GIFT_13":497,"FLAG_MYSTERY_GIFT_14":498,"FLAG_MYSTERY_GIFT_15":499,"FLAG_MYSTERY_GIFT_2":486,"FLAG_MYSTERY_GIFT_3":487,"FLAG_MYSTERY_GIFT_4":488,"FLAG_MYSTERY_GIFT_5":489,"FLAG_MYSTERY_GIFT_6":490,"FLAG_MYSTERY_GIFT_7":491,"FLAG_MYSTERY_GIFT_8":492,"FLAG_MYSTERY_GIFT_9":493,"FLAG_MYSTERY_GIFT_DONE":484,"FLAG_NEVER_SET_0x0DC":220,"FLAG_NOT_READY_FOR_BATTLE_ROUTE_120":290,"FLAG_NURSE_MENTIONS_GOLD_CARD":345,"FLAG_NURSE_UNION_ROOM_REMINDER":2176,"FLAG_OCEANIC_MUSEUM_MET_REPORTER":105,"FLAG_OMIT_DIVE_FROM_STEVEN_LETTER":302,"FLAG_PACIFIDLOG_NPC_TRADE_COMPLETED":154,"FLAG_PENDING_DAYCARE_EGG":134,"FLAG_PETALBURG_MART_EXPANDED_ITEMS":296,"FLAG_POKERUS_EXPLAINED":273,"FLAG_PURCHASED_HARBOR_MAIL":104,"FLAG_RAYQUAZA_IS_RECOVERING":1279,"FLAG_RECEIVED_20_COINS":225,"FLAG_RECEIVED_6_SODA_POP":140,"FLAG_RECEIVED_ACRO_BIKE":1181,"FLAG_RECEIVED_AMULET_COIN":133,"FLAG_RECEIVED_AURORA_TICKET":314,"FLAG_RECEIVED_BADGE_1":1182,"FLAG_RECEIVED_BADGE_2":1183,"FLAG_RECEIVED_BADGE_3":1184,"FLAG_RECEIVED_BADGE_4":1185,"FLAG_RECEIVED_BADGE_5":1186,"FLAG_RECEIVED_BADGE_6":1187,"FLAG_RECEIVED_BADGE_7":1188,"FLAG_RECEIVED_BADGE_8":1189,"FLAG_RECEIVED_BELDUM":298,"FLAG_RECEIVED_BELUE_BERRY":252,"FLAG_RECEIVED_BIKE":90,"FLAG_RECEIVED_BLUE_SCARF":201,"FLAG_RECEIVED_CASTFORM":151,"FLAG_RECEIVED_CHARCOAL":254,"FLAG_RECEIVED_CHESTO_BERRY_ROUTE_104":246,"FLAG_RECEIVED_CLEANSE_TAG":282,"FLAG_RECEIVED_COIN_CASE":258,"FLAG_RECEIVED_CONTEST_PASS":150,"FLAG_RECEIVED_DEEP_SEA_SCALE":1190,"FLAG_RECEIVED_DEEP_SEA_TOOTH":1191,"FLAG_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":1172,"FLAG_RECEIVED_DEVON_SCOPE":285,"FLAG_RECEIVED_DOLL_LANETTE":131,"FLAG_RECEIVED_DURIN_BERRY":251,"FLAG_RECEIVED_EON_TICKET":474,"FLAG_RECEIVED_EXP_SHARE":272,"FLAG_RECEIVED_FANCLUB_TM_THIS_WEEK":299,"FLAG_RECEIVED_FIRST_POKEBALLS":233,"FLAG_RECEIVED_FOCUS_BAND":283,"FLAG_RECEIVED_GLASS_ORNAMENT":236,"FLAG_RECEIVED_GOLD_SHIELD":238,"FLAG_RECEIVED_GOOD_ROD":227,"FLAG_RECEIVED_GO_GOGGLES":221,"FLAG_RECEIVED_GREAT_BALL_PETALBURG_WOODS":1171,"FLAG_RECEIVED_GREAT_BALL_RUSTBORO_CITY":1173,"FLAG_RECEIVED_GREEN_SCARF":203,"FLAG_RECEIVED_HM_CUT":137,"FLAG_RECEIVED_HM_DIVE":123,"FLAG_RECEIVED_HM_FLASH":109,"FLAG_RECEIVED_HM_FLY":110,"FLAG_RECEIVED_HM_ROCK_SMASH":107,"FLAG_RECEIVED_HM_STRENGTH":106,"FLAG_RECEIVED_HM_SURF":122,"FLAG_RECEIVED_HM_WATERFALL":312,"FLAG_RECEIVED_ITEMFINDER":1176,"FLAG_RECEIVED_KINGS_ROCK":276,"FLAG_RECEIVED_LAVARIDGE_EGG":266,"FLAG_RECEIVED_LETTER":1174,"FLAG_RECEIVED_MACHO_BRACE":277,"FLAG_RECEIVED_MACH_BIKE":1180,"FLAG_RECEIVED_MAGMA_EMBLEM":1177,"FLAG_RECEIVED_MENTAL_HERB":223,"FLAG_RECEIVED_METEORITE":115,"FLAG_RECEIVED_MIRACLE_SEED":297,"FLAG_RECEIVED_MYSTIC_TICKET":315,"FLAG_RECEIVED_OLD_ROD":257,"FLAG_RECEIVED_OLD_SEA_MAP":316,"FLAG_RECEIVED_PAMTRE_BERRY":249,"FLAG_RECEIVED_PINK_SCARF":202,"FLAG_RECEIVED_POKEBLOCK_CASE":95,"FLAG_RECEIVED_POKEDEX_FROM_BIRCH":2276,"FLAG_RECEIVED_POKENAV":188,"FLAG_RECEIVED_POTION_OLDALE":132,"FLAG_RECEIVED_POWDER_JAR":337,"FLAG_RECEIVED_PREMIER_BALL_RUSTBORO":213,"FLAG_RECEIVED_QUICK_CLAW":275,"FLAG_RECEIVED_RED_OR_BLUE_ORB":212,"FLAG_RECEIVED_RED_SCARF":200,"FLAG_RECEIVED_REPEAT_BALL":256,"FLAG_RECEIVED_REVIVED_FOSSIL_MON":267,"FLAG_RECEIVED_RUNNING_SHOES":274,"FLAG_RECEIVED_SECRET_POWER":96,"FLAG_RECEIVED_SHOAL_SALT_1":952,"FLAG_RECEIVED_SHOAL_SALT_2":953,"FLAG_RECEIVED_SHOAL_SALT_3":954,"FLAG_RECEIVED_SHOAL_SALT_4":955,"FLAG_RECEIVED_SHOAL_SHELL_1":956,"FLAG_RECEIVED_SHOAL_SHELL_2":957,"FLAG_RECEIVED_SHOAL_SHELL_3":958,"FLAG_RECEIVED_SHOAL_SHELL_4":959,"FLAG_RECEIVED_SILK_SCARF":289,"FLAG_RECEIVED_SILVER_SHIELD":237,"FLAG_RECEIVED_SOFT_SAND":280,"FLAG_RECEIVED_SOOTHE_BELL":278,"FLAG_RECEIVED_SOOT_SACK":1033,"FLAG_RECEIVED_SPECIAL_PHRASE_HINT":85,"FLAG_RECEIVED_SPELON_BERRY":248,"FLAG_RECEIVED_SS_TICKET":291,"FLAG_RECEIVED_STARTER_DOLL":226,"FLAG_RECEIVED_SUN_STONE_MOSSDEEP":192,"FLAG_RECEIVED_SUPER_ROD":152,"FLAG_RECEIVED_TM_AERIAL_ACE":170,"FLAG_RECEIVED_TM_ATTRACT":235,"FLAG_RECEIVED_TM_BRICK_BREAK":121,"FLAG_RECEIVED_TM_BULK_UP":166,"FLAG_RECEIVED_TM_BULLET_SEED":262,"FLAG_RECEIVED_TM_CALM_MIND":171,"FLAG_RECEIVED_TM_DIG":261,"FLAG_RECEIVED_TM_FACADE":169,"FLAG_RECEIVED_TM_FRUSTRATION":1179,"FLAG_RECEIVED_TM_GIGA_DRAIN":232,"FLAG_RECEIVED_TM_HIDDEN_POWER":264,"FLAG_RECEIVED_TM_OVERHEAT":168,"FLAG_RECEIVED_TM_REST":234,"FLAG_RECEIVED_TM_RETURN":229,"FLAG_RECEIVED_TM_RETURN_2":1178,"FLAG_RECEIVED_TM_ROAR":231,"FLAG_RECEIVED_TM_ROCK_TOMB":165,"FLAG_RECEIVED_TM_SHOCK_WAVE":167,"FLAG_RECEIVED_TM_SLUDGE_BOMB":230,"FLAG_RECEIVED_TM_SNATCH":260,"FLAG_RECEIVED_TM_STEEL_WING":1175,"FLAG_RECEIVED_TM_THIEF":269,"FLAG_RECEIVED_TM_TORMENT":265,"FLAG_RECEIVED_TM_WATER_PULSE":172,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_1":1200,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_2":1201,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_3":1202,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_4":1203,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_5":1204,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_6":1205,"FLAG_RECEIVED_TRICK_HOUSE_REWARD_7":1206,"FLAG_RECEIVED_WAILMER_DOLL":245,"FLAG_RECEIVED_WAILMER_PAIL":94,"FLAG_RECEIVED_WATMEL_BERRY":250,"FLAG_RECEIVED_WHITE_HERB":279,"FLAG_RECEIVED_YELLOW_SCARF":204,"FLAG_RECOVERED_DEVON_GOODS":143,"FLAG_REGICE_IS_RECOVERING":1260,"FLAG_REGIROCK_IS_RECOVERING":1261,"FLAG_REGISTEEL_IS_RECOVERING":1262,"FLAG_REGISTERED_STEVEN_POKENAV":305,"FLAG_REGISTER_RIVAL_POKENAV":124,"FLAG_REGI_DOORS_OPENED":228,"FLAG_REMATCH_ABIGAIL":387,"FLAG_REMATCH_AMY_AND_LIV":399,"FLAG_REMATCH_ANDRES":350,"FLAG_REMATCH_ANNA_AND_MEG":378,"FLAG_REMATCH_BENJAMIN":390,"FLAG_REMATCH_BERNIE":369,"FLAG_REMATCH_BRAWLY":415,"FLAG_REMATCH_BROOKE":356,"FLAG_REMATCH_CALVIN":383,"FLAG_REMATCH_CAMERON":373,"FLAG_REMATCH_CATHERINE":406,"FLAG_REMATCH_CINDY":359,"FLAG_REMATCH_CORY":401,"FLAG_REMATCH_CRISTIN":355,"FLAG_REMATCH_CYNDY":395,"FLAG_REMATCH_DALTON":368,"FLAG_REMATCH_DIANA":398,"FLAG_REMATCH_DRAKE":424,"FLAG_REMATCH_DUSTY":351,"FLAG_REMATCH_DYLAN":388,"FLAG_REMATCH_EDWIN":402,"FLAG_REMATCH_ELLIOT":384,"FLAG_REMATCH_ERNEST":400,"FLAG_REMATCH_ETHAN":370,"FLAG_REMATCH_FERNANDO":367,"FLAG_REMATCH_FLANNERY":417,"FLAG_REMATCH_GABRIELLE":405,"FLAG_REMATCH_GLACIA":423,"FLAG_REMATCH_HALEY":408,"FLAG_REMATCH_ISAAC":404,"FLAG_REMATCH_ISABEL":379,"FLAG_REMATCH_ISAIAH":385,"FLAG_REMATCH_JACKI":374,"FLAG_REMATCH_JACKSON":407,"FLAG_REMATCH_JAMES":409,"FLAG_REMATCH_JEFFREY":372,"FLAG_REMATCH_JENNY":397,"FLAG_REMATCH_JERRY":377,"FLAG_REMATCH_JESSICA":361,"FLAG_REMATCH_JOHN_AND_JAY":371,"FLAG_REMATCH_KAREN":376,"FLAG_REMATCH_KATELYN":389,"FLAG_REMATCH_KIRA_AND_DAN":412,"FLAG_REMATCH_KOJI":366,"FLAG_REMATCH_LAO":394,"FLAG_REMATCH_LILA_AND_ROY":354,"FLAG_REMATCH_LOLA":352,"FLAG_REMATCH_LYDIA":403,"FLAG_REMATCH_MADELINE":396,"FLAG_REMATCH_MARIA":386,"FLAG_REMATCH_MIGUEL":380,"FLAG_REMATCH_NICOLAS":392,"FLAG_REMATCH_NOB":365,"FLAG_REMATCH_NORMAN":418,"FLAG_REMATCH_PABLO":391,"FLAG_REMATCH_PHOEBE":422,"FLAG_REMATCH_RICKY":353,"FLAG_REMATCH_ROBERT":393,"FLAG_REMATCH_ROSE":349,"FLAG_REMATCH_ROXANNE":414,"FLAG_REMATCH_SAWYER":411,"FLAG_REMATCH_SHELBY":382,"FLAG_REMATCH_SIDNEY":421,"FLAG_REMATCH_STEVE":363,"FLAG_REMATCH_TATE_AND_LIZA":420,"FLAG_REMATCH_THALIA":360,"FLAG_REMATCH_TIMOTHY":381,"FLAG_REMATCH_TONY":364,"FLAG_REMATCH_TRENT":410,"FLAG_REMATCH_VALERIE":358,"FLAG_REMATCH_WALLACE":425,"FLAG_REMATCH_WALLY":413,"FLAG_REMATCH_WALTER":375,"FLAG_REMATCH_WATTSON":416,"FLAG_REMATCH_WILTON":357,"FLAG_REMATCH_WINONA":419,"FLAG_REMATCH_WINSTON":362,"FLAG_RESCUED_BIRCH":82,"FLAG_RETURNED_DEVON_GOODS":144,"FLAG_RETURNED_RED_OR_BLUE_ORB":259,"FLAG_RIVAL_LEFT_FOR_ROUTE103":301,"FLAG_ROUTE_111_RECEIVED_BERRY":1192,"FLAG_ROUTE_114_RECEIVED_BERRY":1193,"FLAG_ROUTE_120_RECEIVED_BERRY":1194,"FLAG_RUSTBORO_NPC_TRADE_COMPLETED":153,"FLAG_RUSTURF_TUNNEL_OPENED":199,"FLAG_SCOTT_CALL_BATTLE_FRONTIER":114,"FLAG_SCOTT_CALL_FORTREE_GYM":138,"FLAG_SCOTT_GIVES_BATTLE_POINTS":465,"FLAG_SECRET_BASE_REGISTRY_ENABLED":268,"FLAG_SET_WALL_CLOCK":81,"FLAG_SHOWN_AURORA_TICKET":431,"FLAG_SHOWN_BOX_WAS_FULL_MESSAGE":2263,"FLAG_SHOWN_EON_TICKET":430,"FLAG_SHOWN_MYSTIC_TICKET":475,"FLAG_SHOWN_OLD_SEA_MAP":432,"FLAG_SMART_PAINTING_MADE":163,"FLAG_SOOTOPOLIS_ARCHIE_MAXIE_LEAVE":158,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_1":1198,"FLAG_SOOTOPOLIS_RECEIVED_BERRY_2":1199,"FLAG_SPECIAL_FLAG_UNUSED_0x4003":16387,"FLAG_SS_TIDAL_DISABLED":84,"FLAG_STEVEN_GUIDES_TO_CAVE_OF_ORIGIN":307,"FLAG_STORING_ITEMS_IN_PYRAMID_BAG":16388,"FLAG_SYS_ARENA_GOLD":2251,"FLAG_SYS_ARENA_SILVER":2250,"FLAG_SYS_BRAILLE_DIG":2223,"FLAG_SYS_BRAILLE_REGICE_COMPLETED":2225,"FLAG_SYS_B_DASH":2240,"FLAG_SYS_CAVE_BATTLE":2201,"FLAG_SYS_CAVE_SHIP":2199,"FLAG_SYS_CAVE_WONDER":2200,"FLAG_SYS_CHANGED_DEWFORD_TREND":2195,"FLAG_SYS_CHAT_USED":2149,"FLAG_SYS_CLOCK_SET":2197,"FLAG_SYS_CRUISE_MODE":2189,"FLAG_SYS_CTRL_OBJ_DELETE":2241,"FLAG_SYS_CYCLING_ROAD":2187,"FLAG_SYS_DOME_GOLD":2247,"FLAG_SYS_DOME_SILVER":2246,"FLAG_SYS_ENC_DOWN_ITEM":2222,"FLAG_SYS_ENC_UP_ITEM":2221,"FLAG_SYS_FACTORY_GOLD":2253,"FLAG_SYS_FACTORY_SILVER":2252,"FLAG_SYS_FRONTIER_PASS":2258,"FLAG_SYS_GAME_CLEAR":2148,"FLAG_SYS_MIX_RECORD":2196,"FLAG_SYS_MYSTERY_EVENT_ENABLE":2220,"FLAG_SYS_MYSTERY_GIFT_ENABLE":2267,"FLAG_SYS_NATIONAL_DEX":2198,"FLAG_SYS_PALACE_GOLD":2249,"FLAG_SYS_PALACE_SILVER":2248,"FLAG_SYS_PC_LANETTE":2219,"FLAG_SYS_PIKE_GOLD":2255,"FLAG_SYS_PIKE_SILVER":2254,"FLAG_SYS_POKEDEX_GET":2145,"FLAG_SYS_POKEMON_GET":2144,"FLAG_SYS_POKENAV_GET":2146,"FLAG_SYS_PYRAMID_GOLD":2257,"FLAG_SYS_PYRAMID_SILVER":2256,"FLAG_SYS_REGIROCK_PUZZLE_COMPLETED":2224,"FLAG_SYS_REGISTEEL_PUZZLE_COMPLETED":2226,"FLAG_SYS_RESET_RTC_ENABLE":2242,"FLAG_SYS_RIBBON_GET":2203,"FLAG_SYS_SAFARI_MODE":2188,"FLAG_SYS_SHOAL_ITEM":2239,"FLAG_SYS_SHOAL_TIDE":2202,"FLAG_SYS_TOWER_GOLD":2245,"FLAG_SYS_TOWER_SILVER":2244,"FLAG_SYS_TV_HOME":2192,"FLAG_SYS_TV_LATIAS_LATIOS":2237,"FLAG_SYS_TV_START":2194,"FLAG_SYS_TV_WATCH":2193,"FLAG_SYS_USE_FLASH":2184,"FLAG_SYS_USE_STRENGTH":2185,"FLAG_SYS_WEATHER_CTRL":2186,"FLAG_TEAM_AQUA_ESCAPED_IN_SUBMARINE":112,"FLAG_TEMP_1":1,"FLAG_TEMP_10":16,"FLAG_TEMP_11":17,"FLAG_TEMP_12":18,"FLAG_TEMP_13":19,"FLAG_TEMP_14":20,"FLAG_TEMP_15":21,"FLAG_TEMP_16":22,"FLAG_TEMP_17":23,"FLAG_TEMP_18":24,"FLAG_TEMP_19":25,"FLAG_TEMP_1A":26,"FLAG_TEMP_1B":27,"FLAG_TEMP_1C":28,"FLAG_TEMP_1D":29,"FLAG_TEMP_1E":30,"FLAG_TEMP_1F":31,"FLAG_TEMP_2":2,"FLAG_TEMP_3":3,"FLAG_TEMP_4":4,"FLAG_TEMP_5":5,"FLAG_TEMP_6":6,"FLAG_TEMP_7":7,"FLAG_TEMP_8":8,"FLAG_TEMP_9":9,"FLAG_TEMP_A":10,"FLAG_TEMP_B":11,"FLAG_TEMP_C":12,"FLAG_TEMP_D":13,"FLAG_TEMP_E":14,"FLAG_TEMP_F":15,"FLAG_TEMP_HIDE_MIRAGE_ISLAND_BERRY_TREE":17,"FLAG_TEMP_REGICE_PUZZLE_FAILED":3,"FLAG_TEMP_REGICE_PUZZLE_STARTED":2,"FLAG_TEMP_SKIP_GABBY_INTERVIEW":1,"FLAG_THANKED_FOR_PLAYING_WITH_WALLY":135,"FLAG_TOUGH_PAINTING_MADE":164,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_1":194,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_2":195,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_3":196,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_4":197,"FLAG_TRICK_HOUSE_PUZZLE_7_SWITCH_5":198,"FLAG_TV_EXPLAINED":98,"FLAG_UNLOCKED_TRENDY_SAYINGS":2150,"FLAG_USED_ROOM_1_KEY":240,"FLAG_USED_ROOM_2_KEY":241,"FLAG_USED_ROOM_4_KEY":242,"FLAG_USED_ROOM_6_KEY":243,"FLAG_USED_STORAGE_KEY":239,"FLAG_VISITED_DEWFORD_TOWN":2161,"FLAG_VISITED_EVER_GRANDE_CITY":2174,"FLAG_VISITED_FALLARBOR_TOWN":2163,"FLAG_VISITED_FORTREE_CITY":2170,"FLAG_VISITED_LAVARIDGE_TOWN":2162,"FLAG_VISITED_LILYCOVE_CITY":2171,"FLAG_VISITED_LITTLEROOT_TOWN":2159,"FLAG_VISITED_MAUVILLE_CITY":2168,"FLAG_VISITED_MOSSDEEP_CITY":2172,"FLAG_VISITED_OLDALE_TOWN":2160,"FLAG_VISITED_PACIFIDLOG_TOWN":2165,"FLAG_VISITED_PETALBURG_CITY":2166,"FLAG_VISITED_RUSTBORO_CITY":2169,"FLAG_VISITED_SLATEPORT_CITY":2167,"FLAG_VISITED_SOOTOPOLIS_CITY":2173,"FLAG_VISITED_VERDANTURF_TOWN":2164,"FLAG_WALLACE_GOES_TO_SKY_PILLAR":311,"FLAG_WALLY_SPEECH":193,"FLAG_WATTSON_REMATCH_AVAILABLE":91,"FLAG_WHITEOUT_TO_LAVARIDGE":108,"FLAG_WINGULL_DELIVERED_MAIL":224,"FLAG_WINGULL_SENT_ON_ERRAND":222,"FLAG_WONDER_CARD_UNUSED_1":317,"FLAG_WONDER_CARD_UNUSED_10":326,"FLAG_WONDER_CARD_UNUSED_11":327,"FLAG_WONDER_CARD_UNUSED_12":328,"FLAG_WONDER_CARD_UNUSED_13":329,"FLAG_WONDER_CARD_UNUSED_14":330,"FLAG_WONDER_CARD_UNUSED_15":331,"FLAG_WONDER_CARD_UNUSED_16":332,"FLAG_WONDER_CARD_UNUSED_17":333,"FLAG_WONDER_CARD_UNUSED_2":318,"FLAG_WONDER_CARD_UNUSED_3":319,"FLAG_WONDER_CARD_UNUSED_4":320,"FLAG_WONDER_CARD_UNUSED_5":321,"FLAG_WONDER_CARD_UNUSED_6":322,"FLAG_WONDER_CARD_UNUSED_7":323,"FLAG_WONDER_CARD_UNUSED_8":324,"FLAG_WONDER_CARD_UNUSED_9":325,"FLAVOR_BITTER":3,"FLAVOR_COUNT":5,"FLAVOR_DRY":1,"FLAVOR_SOUR":4,"FLAVOR_SPICY":0,"FLAVOR_SWEET":2,"GOOD_ROD":1,"ITEMS_COUNT":377,"ITEM_034":52,"ITEM_035":53,"ITEM_036":54,"ITEM_037":55,"ITEM_038":56,"ITEM_039":57,"ITEM_03A":58,"ITEM_03B":59,"ITEM_03C":60,"ITEM_03D":61,"ITEM_03E":62,"ITEM_048":72,"ITEM_052":82,"ITEM_057":87,"ITEM_058":88,"ITEM_059":89,"ITEM_05A":90,"ITEM_05B":91,"ITEM_05C":92,"ITEM_063":99,"ITEM_064":100,"ITEM_065":101,"ITEM_066":102,"ITEM_069":105,"ITEM_071":113,"ITEM_072":114,"ITEM_073":115,"ITEM_074":116,"ITEM_075":117,"ITEM_076":118,"ITEM_077":119,"ITEM_078":120,"ITEM_0EA":234,"ITEM_0EB":235,"ITEM_0EC":236,"ITEM_0ED":237,"ITEM_0EE":238,"ITEM_0EF":239,"ITEM_0F0":240,"ITEM_0F1":241,"ITEM_0F2":242,"ITEM_0F3":243,"ITEM_0F4":244,"ITEM_0F5":245,"ITEM_0F6":246,"ITEM_0F7":247,"ITEM_0F8":248,"ITEM_0F9":249,"ITEM_0FA":250,"ITEM_0FB":251,"ITEM_0FC":252,"ITEM_0FD":253,"ITEM_10B":267,"ITEM_15B":347,"ITEM_15C":348,"ITEM_ACRO_BIKE":272,"ITEM_AGUAV_BERRY":146,"ITEM_AMULET_COIN":189,"ITEM_ANTIDOTE":14,"ITEM_APICOT_BERRY":172,"ITEM_ARCHIPELAGO_PROGRESSION":112,"ITEM_ASPEAR_BERRY":137,"ITEM_AURORA_TICKET":371,"ITEM_AWAKENING":17,"ITEM_BADGE_1":226,"ITEM_BADGE_2":227,"ITEM_BADGE_3":228,"ITEM_BADGE_4":229,"ITEM_BADGE_5":230,"ITEM_BADGE_6":231,"ITEM_BADGE_7":232,"ITEM_BADGE_8":233,"ITEM_BASEMENT_KEY":271,"ITEM_BEAD_MAIL":127,"ITEM_BELUE_BERRY":167,"ITEM_BERRY_JUICE":44,"ITEM_BERRY_POUCH":365,"ITEM_BICYCLE":360,"ITEM_BIG_MUSHROOM":104,"ITEM_BIG_PEARL":107,"ITEM_BIKE_VOUCHER":352,"ITEM_BLACK_BELT":207,"ITEM_BLACK_FLUTE":42,"ITEM_BLACK_GLASSES":206,"ITEM_BLUE_FLUTE":39,"ITEM_BLUE_ORB":277,"ITEM_BLUE_SCARF":255,"ITEM_BLUE_SHARD":49,"ITEM_BLUK_BERRY":149,"ITEM_BRIGHT_POWDER":179,"ITEM_BURN_HEAL":15,"ITEM_B_USE_MEDICINE":1,"ITEM_B_USE_OTHER":2,"ITEM_CALCIUM":67,"ITEM_CARBOS":66,"ITEM_CARD_KEY":355,"ITEM_CHARCOAL":215,"ITEM_CHERI_BERRY":133,"ITEM_CHESTO_BERRY":134,"ITEM_CHOICE_BAND":186,"ITEM_CLAW_FOSSIL":287,"ITEM_CLEANSE_TAG":190,"ITEM_COIN_CASE":260,"ITEM_CONTEST_PASS":266,"ITEM_CORNN_BERRY":159,"ITEM_DEEP_SEA_SCALE":193,"ITEM_DEEP_SEA_TOOTH":192,"ITEM_DEVON_GOODS":269,"ITEM_DEVON_SCOPE":288,"ITEM_DIRE_HIT":74,"ITEM_DIVE_BALL":7,"ITEM_DOME_FOSSIL":358,"ITEM_DRAGON_FANG":216,"ITEM_DRAGON_SCALE":201,"ITEM_DREAM_MAIL":130,"ITEM_DURIN_BERRY":166,"ITEM_ELIXIR":36,"ITEM_ENERGY_POWDER":30,"ITEM_ENERGY_ROOT":31,"ITEM_ENIGMA_BERRY":175,"ITEM_EON_TICKET":275,"ITEM_ESCAPE_ROPE":85,"ITEM_ETHER":34,"ITEM_EVERSTONE":195,"ITEM_EXP_SHARE":182,"ITEM_FAB_MAIL":131,"ITEM_FAME_CHECKER":363,"ITEM_FIGY_BERRY":143,"ITEM_FIRE_STONE":95,"ITEM_FLUFFY_TAIL":81,"ITEM_FOCUS_BAND":196,"ITEM_FRESH_WATER":26,"ITEM_FULL_HEAL":23,"ITEM_FULL_RESTORE":19,"ITEM_GANLON_BERRY":169,"ITEM_GLITTER_MAIL":123,"ITEM_GOLD_TEETH":353,"ITEM_GOOD_ROD":263,"ITEM_GO_GOGGLES":279,"ITEM_GREAT_BALL":3,"ITEM_GREEN_SCARF":257,"ITEM_GREEN_SHARD":51,"ITEM_GREPA_BERRY":157,"ITEM_GUARD_SPEC":73,"ITEM_HARBOR_MAIL":122,"ITEM_HARD_STONE":204,"ITEM_HEAL_POWDER":32,"ITEM_HEART_SCALE":111,"ITEM_HELIX_FOSSIL":357,"ITEM_HM01":339,"ITEM_HM02":340,"ITEM_HM03":341,"ITEM_HM04":342,"ITEM_HM05":343,"ITEM_HM06":344,"ITEM_HM07":345,"ITEM_HM08":346,"ITEM_HM_CUT":339,"ITEM_HM_DIVE":346,"ITEM_HM_FLASH":343,"ITEM_HM_FLY":340,"ITEM_HM_ROCK_SMASH":344,"ITEM_HM_STRENGTH":342,"ITEM_HM_SURF":341,"ITEM_HM_WATERFALL":345,"ITEM_HONDEW_BERRY":156,"ITEM_HP_UP":63,"ITEM_HYPER_POTION":21,"ITEM_IAPAPA_BERRY":147,"ITEM_ICE_HEAL":16,"ITEM_IRON":65,"ITEM_ITEMFINDER":261,"ITEM_KELPSY_BERRY":154,"ITEM_KINGS_ROCK":187,"ITEM_LANSAT_BERRY":173,"ITEM_LAVA_COOKIE":38,"ITEM_LAX_INCENSE":221,"ITEM_LEAF_STONE":98,"ITEM_LEFTOVERS":200,"ITEM_LEMONADE":28,"ITEM_LEPPA_BERRY":138,"ITEM_LETTER":274,"ITEM_LIECHI_BERRY":168,"ITEM_LIFT_KEY":356,"ITEM_LIGHT_BALL":202,"ITEM_LIST_END":65535,"ITEM_LUCKY_EGG":197,"ITEM_LUCKY_PUNCH":222,"ITEM_LUM_BERRY":141,"ITEM_LUXURY_BALL":11,"ITEM_MACHO_BRACE":181,"ITEM_MACH_BIKE":259,"ITEM_MAGMA_EMBLEM":375,"ITEM_MAGNET":208,"ITEM_MAGOST_BERRY":160,"ITEM_MAGO_BERRY":145,"ITEM_MASTER_BALL":1,"ITEM_MAX_ELIXIR":37,"ITEM_MAX_ETHER":35,"ITEM_MAX_POTION":20,"ITEM_MAX_REPEL":84,"ITEM_MAX_REVIVE":25,"ITEM_MECH_MAIL":124,"ITEM_MENTAL_HERB":185,"ITEM_METAL_COAT":199,"ITEM_METAL_POWDER":223,"ITEM_METEORITE":280,"ITEM_MIRACLE_SEED":205,"ITEM_MOOMOO_MILK":29,"ITEM_MOON_STONE":94,"ITEM_MYSTIC_TICKET":370,"ITEM_MYSTIC_WATER":209,"ITEM_NANAB_BERRY":150,"ITEM_NEST_BALL":8,"ITEM_NET_BALL":6,"ITEM_NEVER_MELT_ICE":212,"ITEM_NOMEL_BERRY":162,"ITEM_NONE":0,"ITEM_NUGGET":110,"ITEM_OAKS_PARCEL":349,"ITEM_OLD_AMBER":354,"ITEM_OLD_ROD":262,"ITEM_OLD_SEA_MAP":376,"ITEM_ORANGE_MAIL":121,"ITEM_ORAN_BERRY":139,"ITEM_PAMTRE_BERRY":164,"ITEM_PARALYZE_HEAL":18,"ITEM_PEARL":106,"ITEM_PECHA_BERRY":135,"ITEM_PERSIM_BERRY":140,"ITEM_PETAYA_BERRY":171,"ITEM_PINAP_BERRY":152,"ITEM_PINK_SCARF":256,"ITEM_POISON_BARB":211,"ITEM_POKEBLOCK_CASE":273,"ITEM_POKE_BALL":4,"ITEM_POKE_DOLL":80,"ITEM_POKE_FLUTE":350,"ITEM_POMEG_BERRY":153,"ITEM_POTION":13,"ITEM_POWDER_JAR":372,"ITEM_PP_MAX":71,"ITEM_PP_UP":69,"ITEM_PREMIER_BALL":12,"ITEM_PROTEIN":64,"ITEM_QUALOT_BERRY":155,"ITEM_QUICK_CLAW":183,"ITEM_RABUTA_BERRY":161,"ITEM_RAINBOW_PASS":368,"ITEM_RARE_CANDY":68,"ITEM_RAWST_BERRY":136,"ITEM_RAZZ_BERRY":148,"ITEM_RED_FLUTE":41,"ITEM_RED_ORB":276,"ITEM_RED_SCARF":254,"ITEM_RED_SHARD":48,"ITEM_REPEAT_BALL":9,"ITEM_REPEL":86,"ITEM_RETRO_MAIL":132,"ITEM_REVIVAL_HERB":33,"ITEM_REVIVE":24,"ITEM_ROOM_1_KEY":281,"ITEM_ROOM_2_KEY":282,"ITEM_ROOM_4_KEY":283,"ITEM_ROOM_6_KEY":284,"ITEM_ROOT_FOSSIL":286,"ITEM_RUBY":373,"ITEM_SACRED_ASH":45,"ITEM_SAFARI_BALL":5,"ITEM_SALAC_BERRY":170,"ITEM_SAPPHIRE":374,"ITEM_SCANNER":278,"ITEM_SCOPE_LENS":198,"ITEM_SEA_INCENSE":220,"ITEM_SECRET_KEY":351,"ITEM_SHADOW_MAIL":128,"ITEM_SHARP_BEAK":210,"ITEM_SHELL_BELL":219,"ITEM_SHOAL_SALT":46,"ITEM_SHOAL_SHELL":47,"ITEM_SILK_SCARF":217,"ITEM_SILPH_SCOPE":359,"ITEM_SILVER_POWDER":188,"ITEM_SITRUS_BERRY":142,"ITEM_SMOKE_BALL":194,"ITEM_SODA_POP":27,"ITEM_SOFT_SAND":203,"ITEM_SOOTHE_BELL":184,"ITEM_SOOT_SACK":270,"ITEM_SOUL_DEW":191,"ITEM_SPELL_TAG":213,"ITEM_SPELON_BERRY":163,"ITEM_SS_TICKET":265,"ITEM_STARDUST":108,"ITEM_STARF_BERRY":174,"ITEM_STAR_PIECE":109,"ITEM_STICK":225,"ITEM_STORAGE_KEY":285,"ITEM_SUN_STONE":93,"ITEM_SUPER_POTION":22,"ITEM_SUPER_REPEL":83,"ITEM_SUPER_ROD":264,"ITEM_TAMATO_BERRY":158,"ITEM_TEA":369,"ITEM_TEACHY_TV":366,"ITEM_THICK_CLUB":224,"ITEM_THUNDER_STONE":96,"ITEM_TIMER_BALL":10,"ITEM_TINY_MUSHROOM":103,"ITEM_TM01":289,"ITEM_TM02":290,"ITEM_TM03":291,"ITEM_TM04":292,"ITEM_TM05":293,"ITEM_TM06":294,"ITEM_TM07":295,"ITEM_TM08":296,"ITEM_TM09":297,"ITEM_TM10":298,"ITEM_TM11":299,"ITEM_TM12":300,"ITEM_TM13":301,"ITEM_TM14":302,"ITEM_TM15":303,"ITEM_TM16":304,"ITEM_TM17":305,"ITEM_TM18":306,"ITEM_TM19":307,"ITEM_TM20":308,"ITEM_TM21":309,"ITEM_TM22":310,"ITEM_TM23":311,"ITEM_TM24":312,"ITEM_TM25":313,"ITEM_TM26":314,"ITEM_TM27":315,"ITEM_TM28":316,"ITEM_TM29":317,"ITEM_TM30":318,"ITEM_TM31":319,"ITEM_TM32":320,"ITEM_TM33":321,"ITEM_TM34":322,"ITEM_TM35":323,"ITEM_TM36":324,"ITEM_TM37":325,"ITEM_TM38":326,"ITEM_TM39":327,"ITEM_TM40":328,"ITEM_TM41":329,"ITEM_TM42":330,"ITEM_TM43":331,"ITEM_TM44":332,"ITEM_TM45":333,"ITEM_TM46":334,"ITEM_TM47":335,"ITEM_TM48":336,"ITEM_TM49":337,"ITEM_TM50":338,"ITEM_TM_AERIAL_ACE":328,"ITEM_TM_ATTRACT":333,"ITEM_TM_BLIZZARD":302,"ITEM_TM_BRICK_BREAK":319,"ITEM_TM_BULK_UP":296,"ITEM_TM_BULLET_SEED":297,"ITEM_TM_CALM_MIND":292,"ITEM_TM_CASE":364,"ITEM_TM_DIG":316,"ITEM_TM_DOUBLE_TEAM":320,"ITEM_TM_DRAGON_CLAW":290,"ITEM_TM_EARTHQUAKE":314,"ITEM_TM_FACADE":330,"ITEM_TM_FIRE_BLAST":326,"ITEM_TM_FLAMETHROWER":323,"ITEM_TM_FOCUS_PUNCH":289,"ITEM_TM_FRUSTRATION":309,"ITEM_TM_GIGA_DRAIN":307,"ITEM_TM_HAIL":295,"ITEM_TM_HIDDEN_POWER":298,"ITEM_TM_HYPER_BEAM":303,"ITEM_TM_ICE_BEAM":301,"ITEM_TM_IRON_TAIL":311,"ITEM_TM_LIGHT_SCREEN":304,"ITEM_TM_OVERHEAT":338,"ITEM_TM_PROTECT":305,"ITEM_TM_PSYCHIC":317,"ITEM_TM_RAIN_DANCE":306,"ITEM_TM_REFLECT":321,"ITEM_TM_REST":332,"ITEM_TM_RETURN":315,"ITEM_TM_ROAR":293,"ITEM_TM_ROCK_TOMB":327,"ITEM_TM_SAFEGUARD":308,"ITEM_TM_SANDSTORM":325,"ITEM_TM_SECRET_POWER":331,"ITEM_TM_SHADOW_BALL":318,"ITEM_TM_SHOCK_WAVE":322,"ITEM_TM_SKILL_SWAP":336,"ITEM_TM_SLUDGE_BOMB":324,"ITEM_TM_SNATCH":337,"ITEM_TM_SOLAR_BEAM":310,"ITEM_TM_STEEL_WING":335,"ITEM_TM_SUNNY_DAY":299,"ITEM_TM_TAUNT":300,"ITEM_TM_THIEF":334,"ITEM_TM_THUNDER":313,"ITEM_TM_THUNDERBOLT":312,"ITEM_TM_TORMENT":329,"ITEM_TM_TOXIC":294,"ITEM_TM_WATER_PULSE":291,"ITEM_TOWN_MAP":361,"ITEM_TRI_PASS":367,"ITEM_TROPIC_MAIL":129,"ITEM_TWISTED_SPOON":214,"ITEM_ULTRA_BALL":2,"ITEM_UNUSED_BERRY_1":176,"ITEM_UNUSED_BERRY_2":177,"ITEM_UNUSED_BERRY_3":178,"ITEM_UP_GRADE":218,"ITEM_USE_BAG_MENU":4,"ITEM_USE_FIELD":2,"ITEM_USE_MAIL":0,"ITEM_USE_PARTY_MENU":1,"ITEM_USE_PBLOCK_CASE":3,"ITEM_VS_SEEKER":362,"ITEM_WAILMER_PAIL":268,"ITEM_WATER_STONE":97,"ITEM_WATMEL_BERRY":165,"ITEM_WAVE_MAIL":126,"ITEM_WEPEAR_BERRY":151,"ITEM_WHITE_FLUTE":43,"ITEM_WHITE_HERB":180,"ITEM_WIKI_BERRY":144,"ITEM_WOOD_MAIL":125,"ITEM_X_ACCURACY":78,"ITEM_X_ATTACK":75,"ITEM_X_DEFEND":76,"ITEM_X_SPECIAL":79,"ITEM_X_SPEED":77,"ITEM_YELLOW_FLUTE":40,"ITEM_YELLOW_SCARF":258,"ITEM_YELLOW_SHARD":50,"ITEM_ZINC":70,"LAST_BALL":12,"LAST_BERRY_INDEX":175,"LAST_BERRY_MASTER_BERRY":162,"LAST_BERRY_MASTER_WIFE_BERRY":142,"LAST_KIRI_BERRY":162,"LAST_ROUTE_114_MAN_BERRY":152,"MACH_BIKE":0,"MAIL_NONE":255,"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":6207,"MAP_ABANDONED_SHIP_CORRIDORS_1F":6199,"MAP_ABANDONED_SHIP_CORRIDORS_B1F":6201,"MAP_ABANDONED_SHIP_DECK":6198,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":6209,"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":6210,"MAP_ABANDONED_SHIP_ROOMS2_1F":6206,"MAP_ABANDONED_SHIP_ROOMS2_B1F":6203,"MAP_ABANDONED_SHIP_ROOMS_1F":6200,"MAP_ABANDONED_SHIP_ROOMS_B1F":6202,"MAP_ABANDONED_SHIP_ROOM_B1F":6205,"MAP_ABANDONED_SHIP_UNDERWATER1":6204,"MAP_ABANDONED_SHIP_UNDERWATER2":6208,"MAP_ALTERING_CAVE":6250,"MAP_ANCIENT_TOMB":6212,"MAP_AQUA_HIDEOUT_1F":6167,"MAP_AQUA_HIDEOUT_B1F":6168,"MAP_AQUA_HIDEOUT_B2F":6169,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":6218,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":6219,"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":6220,"MAP_ARTISAN_CAVE_1F":6244,"MAP_ARTISAN_CAVE_B1F":6243,"MAP_BATTLE_COLOSSEUM_2P":6424,"MAP_BATTLE_COLOSSEUM_4P":6427,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":6686,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":6685,"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":6684,"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":6677,"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":6675,"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":6674,"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":6676,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":6689,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":6687,"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":6688,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":6680,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":6679,"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":6678,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":6691,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":6690,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":6694,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":6693,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":6695,"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":6692,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":6682,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":6681,"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":6683,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":6664,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":6663,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":6662,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":6661,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":6673,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":6672,"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":6671,"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":6698,"MAP_BATTLE_FRONTIER_LOUNGE1":6697,"MAP_BATTLE_FRONTIER_LOUNGE2":6699,"MAP_BATTLE_FRONTIER_LOUNGE3":6700,"MAP_BATTLE_FRONTIER_LOUNGE4":6701,"MAP_BATTLE_FRONTIER_LOUNGE5":6703,"MAP_BATTLE_FRONTIER_LOUNGE6":6704,"MAP_BATTLE_FRONTIER_LOUNGE7":6705,"MAP_BATTLE_FRONTIER_LOUNGE8":6707,"MAP_BATTLE_FRONTIER_LOUNGE9":6708,"MAP_BATTLE_FRONTIER_MART":6711,"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":6670,"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":6660,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":6709,"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":6710,"MAP_BATTLE_FRONTIER_RANKING_HALL":6696,"MAP_BATTLE_FRONTIER_RECEPTION_GATE":6706,"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":6702,"MAP_BATTLE_PYRAMID_SQUARE01":6444,"MAP_BATTLE_PYRAMID_SQUARE02":6445,"MAP_BATTLE_PYRAMID_SQUARE03":6446,"MAP_BATTLE_PYRAMID_SQUARE04":6447,"MAP_BATTLE_PYRAMID_SQUARE05":6448,"MAP_BATTLE_PYRAMID_SQUARE06":6449,"MAP_BATTLE_PYRAMID_SQUARE07":6450,"MAP_BATTLE_PYRAMID_SQUARE08":6451,"MAP_BATTLE_PYRAMID_SQUARE09":6452,"MAP_BATTLE_PYRAMID_SQUARE10":6453,"MAP_BATTLE_PYRAMID_SQUARE11":6454,"MAP_BATTLE_PYRAMID_SQUARE12":6455,"MAP_BATTLE_PYRAMID_SQUARE13":6456,"MAP_BATTLE_PYRAMID_SQUARE14":6457,"MAP_BATTLE_PYRAMID_SQUARE15":6458,"MAP_BATTLE_PYRAMID_SQUARE16":6459,"MAP_BIRTH_ISLAND_EXTERIOR":6714,"MAP_BIRTH_ISLAND_HARBOR":6715,"MAP_CAVE_OF_ORIGIN_1F":6182,"MAP_CAVE_OF_ORIGIN_B1F":6186,"MAP_CAVE_OF_ORIGIN_ENTRANCE":6181,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":6183,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":6184,"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":6185,"MAP_CONTEST_HALL":6428,"MAP_CONTEST_HALL_BEAUTY":6435,"MAP_CONTEST_HALL_COOL":6437,"MAP_CONTEST_HALL_CUTE":6439,"MAP_CONTEST_HALL_SMART":6438,"MAP_CONTEST_HALL_TOUGH":6436,"MAP_DESERT_RUINS":6150,"MAP_DESERT_UNDERPASS":6242,"MAP_DEWFORD_TOWN":11,"MAP_DEWFORD_TOWN_GYM":771,"MAP_DEWFORD_TOWN_HALL":772,"MAP_DEWFORD_TOWN_HOUSE1":768,"MAP_DEWFORD_TOWN_HOUSE2":773,"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":769,"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":770,"MAP_EVER_GRANDE_CITY":8,"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":4100,"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":4099,"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":4098,"MAP_EVER_GRANDE_CITY_HALL1":4101,"MAP_EVER_GRANDE_CITY_HALL2":4102,"MAP_EVER_GRANDE_CITY_HALL3":4103,"MAP_EVER_GRANDE_CITY_HALL4":4104,"MAP_EVER_GRANDE_CITY_HALL5":4105,"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":4107,"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":4097,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":4108,"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":4109,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":4106,"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":4110,"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":4096,"MAP_FALLARBOR_TOWN":13,"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":1283,"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":1282,"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":1281,"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":1286,"MAP_FALLARBOR_TOWN_MART":1280,"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":1287,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":1284,"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":1285,"MAP_FARAWAY_ISLAND_ENTRANCE":6712,"MAP_FARAWAY_ISLAND_INTERIOR":6713,"MAP_FIERY_PATH":6158,"MAP_FORTREE_CITY":4,"MAP_FORTREE_CITY_DECORATION_SHOP":3081,"MAP_FORTREE_CITY_GYM":3073,"MAP_FORTREE_CITY_HOUSE1":3072,"MAP_FORTREE_CITY_HOUSE2":3077,"MAP_FORTREE_CITY_HOUSE3":3078,"MAP_FORTREE_CITY_HOUSE4":3079,"MAP_FORTREE_CITY_HOUSE5":3080,"MAP_FORTREE_CITY_MART":3076,"MAP_FORTREE_CITY_POKEMON_CENTER_1F":3074,"MAP_FORTREE_CITY_POKEMON_CENTER_2F":3075,"MAP_GRANITE_CAVE_1F":6151,"MAP_GRANITE_CAVE_B1F":6152,"MAP_GRANITE_CAVE_B2F":6153,"MAP_GRANITE_CAVE_STEVENS_ROOM":6154,"MAP_GROUPS_COUNT":34,"MAP_INSIDE_OF_TRUCK":6440,"MAP_ISLAND_CAVE":6211,"MAP_JAGGED_PASS":6157,"MAP_LAVARIDGE_TOWN":12,"MAP_LAVARIDGE_TOWN_GYM_1F":1025,"MAP_LAVARIDGE_TOWN_GYM_B1F":1026,"MAP_LAVARIDGE_TOWN_HERB_SHOP":1024,"MAP_LAVARIDGE_TOWN_HOUSE":1027,"MAP_LAVARIDGE_TOWN_MART":1028,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":1029,"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":1030,"MAP_LILYCOVE_CITY":5,"MAP_LILYCOVE_CITY_CONTEST_HALL":3333,"MAP_LILYCOVE_CITY_CONTEST_LOBBY":3332,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":3328,"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":3329,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":3344,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":3345,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":3346,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":3347,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":3348,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":3350,"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":3349,"MAP_LILYCOVE_CITY_HARBOR":3338,"MAP_LILYCOVE_CITY_HOUSE1":3340,"MAP_LILYCOVE_CITY_HOUSE2":3341,"MAP_LILYCOVE_CITY_HOUSE3":3342,"MAP_LILYCOVE_CITY_HOUSE4":3343,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":3330,"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":3331,"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":3339,"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":3334,"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":3335,"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":3337,"MAP_LILYCOVE_CITY_UNUSED_MART":3336,"MAP_LITTLEROOT_TOWN":9,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":256,"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":257,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":258,"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":259,"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":260,"MAP_MAGMA_HIDEOUT_1F":6230,"MAP_MAGMA_HIDEOUT_2F_1R":6231,"MAP_MAGMA_HIDEOUT_2F_2R":6232,"MAP_MAGMA_HIDEOUT_2F_3R":6237,"MAP_MAGMA_HIDEOUT_3F_1R":6233,"MAP_MAGMA_HIDEOUT_3F_2R":6234,"MAP_MAGMA_HIDEOUT_3F_3R":6236,"MAP_MAGMA_HIDEOUT_4F":6235,"MAP_MARINE_CAVE_END":6247,"MAP_MARINE_CAVE_ENTRANCE":6246,"MAP_MAUVILLE_CITY":2,"MAP_MAUVILLE_CITY_BIKE_SHOP":2561,"MAP_MAUVILLE_CITY_GAME_CORNER":2563,"MAP_MAUVILLE_CITY_GYM":2560,"MAP_MAUVILLE_CITY_HOUSE1":2562,"MAP_MAUVILLE_CITY_HOUSE2":2564,"MAP_MAUVILLE_CITY_MART":2567,"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":2565,"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":2566,"MAP_METEOR_FALLS_1F_1R":6144,"MAP_METEOR_FALLS_1F_2R":6145,"MAP_METEOR_FALLS_B1F_1R":6146,"MAP_METEOR_FALLS_B1F_2R":6147,"MAP_METEOR_FALLS_STEVENS_CAVE":6251,"MAP_MIRAGE_TOWER_1F":6238,"MAP_MIRAGE_TOWER_2F":6239,"MAP_MIRAGE_TOWER_3F":6240,"MAP_MIRAGE_TOWER_4F":6241,"MAP_MOSSDEEP_CITY":6,"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":3595,"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":3596,"MAP_MOSSDEEP_CITY_GYM":3584,"MAP_MOSSDEEP_CITY_HOUSE1":3585,"MAP_MOSSDEEP_CITY_HOUSE2":3586,"MAP_MOSSDEEP_CITY_HOUSE3":3590,"MAP_MOSSDEEP_CITY_HOUSE4":3592,"MAP_MOSSDEEP_CITY_MART":3589,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":3587,"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":3588,"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":3593,"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":3594,"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":3591,"MAP_MT_CHIMNEY":6156,"MAP_MT_CHIMNEY_CABLE_CAR_STATION":4865,"MAP_MT_PYRE_1F":6159,"MAP_MT_PYRE_2F":6160,"MAP_MT_PYRE_3F":6161,"MAP_MT_PYRE_4F":6162,"MAP_MT_PYRE_5F":6163,"MAP_MT_PYRE_6F":6164,"MAP_MT_PYRE_EXTERIOR":6165,"MAP_MT_PYRE_SUMMIT":6166,"MAP_NAVEL_ROCK_B1F":6725,"MAP_NAVEL_ROCK_BOTTOM":6743,"MAP_NAVEL_ROCK_DOWN01":6732,"MAP_NAVEL_ROCK_DOWN02":6733,"MAP_NAVEL_ROCK_DOWN03":6734,"MAP_NAVEL_ROCK_DOWN04":6735,"MAP_NAVEL_ROCK_DOWN05":6736,"MAP_NAVEL_ROCK_DOWN06":6737,"MAP_NAVEL_ROCK_DOWN07":6738,"MAP_NAVEL_ROCK_DOWN08":6739,"MAP_NAVEL_ROCK_DOWN09":6740,"MAP_NAVEL_ROCK_DOWN10":6741,"MAP_NAVEL_ROCK_DOWN11":6742,"MAP_NAVEL_ROCK_ENTRANCE":6724,"MAP_NAVEL_ROCK_EXTERIOR":6722,"MAP_NAVEL_ROCK_FORK":6726,"MAP_NAVEL_ROCK_HARBOR":6723,"MAP_NAVEL_ROCK_TOP":6731,"MAP_NAVEL_ROCK_UP1":6727,"MAP_NAVEL_ROCK_UP2":6728,"MAP_NAVEL_ROCK_UP3":6729,"MAP_NAVEL_ROCK_UP4":6730,"MAP_NEW_MAUVILLE_ENTRANCE":6196,"MAP_NEW_MAUVILLE_INSIDE":6197,"MAP_OLDALE_TOWN":10,"MAP_OLDALE_TOWN_HOUSE1":512,"MAP_OLDALE_TOWN_HOUSE2":513,"MAP_OLDALE_TOWN_MART":516,"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":514,"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":515,"MAP_PACIFIDLOG_TOWN":15,"MAP_PACIFIDLOG_TOWN_HOUSE1":1794,"MAP_PACIFIDLOG_TOWN_HOUSE2":1795,"MAP_PACIFIDLOG_TOWN_HOUSE3":1796,"MAP_PACIFIDLOG_TOWN_HOUSE4":1797,"MAP_PACIFIDLOG_TOWN_HOUSE5":1798,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":1792,"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":1793,"MAP_PETALBURG_CITY":0,"MAP_PETALBURG_CITY_GYM":2049,"MAP_PETALBURG_CITY_HOUSE1":2050,"MAP_PETALBURG_CITY_HOUSE2":2051,"MAP_PETALBURG_CITY_MART":2054,"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":2052,"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":2053,"MAP_PETALBURG_CITY_WALLYS_HOUSE":2048,"MAP_PETALBURG_WOODS":6155,"MAP_RECORD_CORNER":6426,"MAP_ROUTE101":16,"MAP_ROUTE102":17,"MAP_ROUTE103":18,"MAP_ROUTE104":19,"MAP_ROUTE104_MR_BRINEYS_HOUSE":4352,"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":4353,"MAP_ROUTE104_PROTOTYPE":6912,"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":6913,"MAP_ROUTE105":20,"MAP_ROUTE106":21,"MAP_ROUTE107":22,"MAP_ROUTE108":23,"MAP_ROUTE109":24,"MAP_ROUTE109_SEASHORE_HOUSE":7168,"MAP_ROUTE110":25,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":7435,"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":7436,"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":7426,"MAP_ROUTE110_TRICK_HOUSE_END":7425,"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":7424,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":7427,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":7428,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":7429,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":7430,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":7431,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":7432,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":7433,"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":7434,"MAP_ROUTE111":26,"MAP_ROUTE111_OLD_LADYS_REST_STOP":4609,"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":4608,"MAP_ROUTE112":27,"MAP_ROUTE112_CABLE_CAR_STATION":4864,"MAP_ROUTE113":28,"MAP_ROUTE113_GLASS_WORKSHOP":7680,"MAP_ROUTE114":29,"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":5120,"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":5121,"MAP_ROUTE114_LANETTES_HOUSE":5122,"MAP_ROUTE115":30,"MAP_ROUTE116":31,"MAP_ROUTE116_TUNNELERS_REST_HOUSE":5376,"MAP_ROUTE117":32,"MAP_ROUTE117_POKEMON_DAY_CARE":5632,"MAP_ROUTE118":33,"MAP_ROUTE119":34,"MAP_ROUTE119_HOUSE":8194,"MAP_ROUTE119_WEATHER_INSTITUTE_1F":8192,"MAP_ROUTE119_WEATHER_INSTITUTE_2F":8193,"MAP_ROUTE120":35,"MAP_ROUTE121":36,"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":5888,"MAP_ROUTE122":37,"MAP_ROUTE123":38,"MAP_ROUTE123_BERRY_MASTERS_HOUSE":7936,"MAP_ROUTE124":39,"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":8448,"MAP_ROUTE125":40,"MAP_ROUTE126":41,"MAP_ROUTE127":42,"MAP_ROUTE128":43,"MAP_ROUTE129":44,"MAP_ROUTE130":45,"MAP_ROUTE131":46,"MAP_ROUTE132":47,"MAP_ROUTE133":48,"MAP_ROUTE134":49,"MAP_RUSTBORO_CITY":3,"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":2827,"MAP_RUSTBORO_CITY_DEVON_CORP_1F":2816,"MAP_RUSTBORO_CITY_DEVON_CORP_2F":2817,"MAP_RUSTBORO_CITY_DEVON_CORP_3F":2818,"MAP_RUSTBORO_CITY_FLAT1_1F":2824,"MAP_RUSTBORO_CITY_FLAT1_2F":2825,"MAP_RUSTBORO_CITY_FLAT2_1F":2829,"MAP_RUSTBORO_CITY_FLAT2_2F":2830,"MAP_RUSTBORO_CITY_FLAT2_3F":2831,"MAP_RUSTBORO_CITY_GYM":2819,"MAP_RUSTBORO_CITY_HOUSE1":2826,"MAP_RUSTBORO_CITY_HOUSE2":2828,"MAP_RUSTBORO_CITY_HOUSE3":2832,"MAP_RUSTBORO_CITY_MART":2823,"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":2821,"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":2822,"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":2820,"MAP_RUSTURF_TUNNEL":6148,"MAP_SAFARI_ZONE_NORTH":6657,"MAP_SAFARI_ZONE_NORTHEAST":6668,"MAP_SAFARI_ZONE_NORTHWEST":6656,"MAP_SAFARI_ZONE_REST_HOUSE":6667,"MAP_SAFARI_ZONE_SOUTH":6659,"MAP_SAFARI_ZONE_SOUTHEAST":6669,"MAP_SAFARI_ZONE_SOUTHWEST":6658,"MAP_SCORCHED_SLAB":6217,"MAP_SEAFLOOR_CAVERN_ENTRANCE":6171,"MAP_SEAFLOOR_CAVERN_ROOM1":6172,"MAP_SEAFLOOR_CAVERN_ROOM2":6173,"MAP_SEAFLOOR_CAVERN_ROOM3":6174,"MAP_SEAFLOOR_CAVERN_ROOM4":6175,"MAP_SEAFLOOR_CAVERN_ROOM5":6176,"MAP_SEAFLOOR_CAVERN_ROOM6":6177,"MAP_SEAFLOOR_CAVERN_ROOM7":6178,"MAP_SEAFLOOR_CAVERN_ROOM8":6179,"MAP_SEAFLOOR_CAVERN_ROOM9":6180,"MAP_SEALED_CHAMBER_INNER_ROOM":6216,"MAP_SEALED_CHAMBER_OUTER_ROOM":6215,"MAP_SECRET_BASE_BLUE_CAVE1":6402,"MAP_SECRET_BASE_BLUE_CAVE2":6408,"MAP_SECRET_BASE_BLUE_CAVE3":6414,"MAP_SECRET_BASE_BLUE_CAVE4":6420,"MAP_SECRET_BASE_BROWN_CAVE1":6401,"MAP_SECRET_BASE_BROWN_CAVE2":6407,"MAP_SECRET_BASE_BROWN_CAVE3":6413,"MAP_SECRET_BASE_BROWN_CAVE4":6419,"MAP_SECRET_BASE_RED_CAVE1":6400,"MAP_SECRET_BASE_RED_CAVE2":6406,"MAP_SECRET_BASE_RED_CAVE3":6412,"MAP_SECRET_BASE_RED_CAVE4":6418,"MAP_SECRET_BASE_SHRUB1":6405,"MAP_SECRET_BASE_SHRUB2":6411,"MAP_SECRET_BASE_SHRUB3":6417,"MAP_SECRET_BASE_SHRUB4":6423,"MAP_SECRET_BASE_TREE1":6404,"MAP_SECRET_BASE_TREE2":6410,"MAP_SECRET_BASE_TREE3":6416,"MAP_SECRET_BASE_TREE4":6422,"MAP_SECRET_BASE_YELLOW_CAVE1":6403,"MAP_SECRET_BASE_YELLOW_CAVE2":6409,"MAP_SECRET_BASE_YELLOW_CAVE3":6415,"MAP_SECRET_BASE_YELLOW_CAVE4":6421,"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":6194,"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":6195,"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":6190,"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":6227,"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":6191,"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":6193,"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":6192,"MAP_SKY_PILLAR_1F":6223,"MAP_SKY_PILLAR_2F":6224,"MAP_SKY_PILLAR_3F":6225,"MAP_SKY_PILLAR_4F":6226,"MAP_SKY_PILLAR_5F":6228,"MAP_SKY_PILLAR_ENTRANCE":6221,"MAP_SKY_PILLAR_OUTSIDE":6222,"MAP_SKY_PILLAR_TOP":6229,"MAP_SLATEPORT_CITY":1,"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":2308,"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":2307,"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":2306,"MAP_SLATEPORT_CITY_HARBOR":2313,"MAP_SLATEPORT_CITY_HOUSE":2314,"MAP_SLATEPORT_CITY_MART":2317,"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":2309,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":2311,"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":2312,"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":2315,"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":2316,"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":2310,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":2304,"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":2305,"MAP_SOOTOPOLIS_CITY":7,"MAP_SOOTOPOLIS_CITY_GYM_1F":3840,"MAP_SOOTOPOLIS_CITY_GYM_B1F":3841,"MAP_SOOTOPOLIS_CITY_HOUSE1":3845,"MAP_SOOTOPOLIS_CITY_HOUSE2":3846,"MAP_SOOTOPOLIS_CITY_HOUSE3":3847,"MAP_SOOTOPOLIS_CITY_HOUSE4":3848,"MAP_SOOTOPOLIS_CITY_HOUSE5":3849,"MAP_SOOTOPOLIS_CITY_HOUSE6":3850,"MAP_SOOTOPOLIS_CITY_HOUSE7":3851,"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":3852,"MAP_SOOTOPOLIS_CITY_MART":3844,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":3853,"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":3854,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":3842,"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":3843,"MAP_SOUTHERN_ISLAND_EXTERIOR":6665,"MAP_SOUTHERN_ISLAND_INTERIOR":6666,"MAP_SS_TIDAL_CORRIDOR":6441,"MAP_SS_TIDAL_LOWER_DECK":6442,"MAP_SS_TIDAL_ROOMS":6443,"MAP_TERRA_CAVE_END":6249,"MAP_TERRA_CAVE_ENTRANCE":6248,"MAP_TRADE_CENTER":6425,"MAP_TRAINER_HILL_1F":6717,"MAP_TRAINER_HILL_2F":6718,"MAP_TRAINER_HILL_3F":6719,"MAP_TRAINER_HILL_4F":6720,"MAP_TRAINER_HILL_ELEVATOR":6744,"MAP_TRAINER_HILL_ENTRANCE":6716,"MAP_TRAINER_HILL_ROOF":6721,"MAP_UNDERWATER_MARINE_CAVE":6245,"MAP_UNDERWATER_ROUTE105":55,"MAP_UNDERWATER_ROUTE124":50,"MAP_UNDERWATER_ROUTE125":56,"MAP_UNDERWATER_ROUTE126":51,"MAP_UNDERWATER_ROUTE127":52,"MAP_UNDERWATER_ROUTE128":53,"MAP_UNDERWATER_ROUTE129":54,"MAP_UNDERWATER_ROUTE134":6213,"MAP_UNDERWATER_SEAFLOOR_CAVERN":6170,"MAP_UNDERWATER_SEALED_CHAMBER":6214,"MAP_UNDERWATER_SOOTOPOLIS_CITY":6149,"MAP_UNION_ROOM":6460,"MAP_UNUSED_CONTEST_HALL1":6429,"MAP_UNUSED_CONTEST_HALL2":6430,"MAP_UNUSED_CONTEST_HALL3":6431,"MAP_UNUSED_CONTEST_HALL4":6432,"MAP_UNUSED_CONTEST_HALL5":6433,"MAP_UNUSED_CONTEST_HALL6":6434,"MAP_VERDANTURF_TOWN":14,"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":1538,"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":1537,"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":1536,"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":1543,"MAP_VERDANTURF_TOWN_HOUSE":1544,"MAP_VERDANTURF_TOWN_MART":1539,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":1540,"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":1541,"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":1542,"MAP_VICTORY_ROAD_1F":6187,"MAP_VICTORY_ROAD_B1F":6188,"MAP_VICTORY_ROAD_B2F":6189,"MAX_BAG_ITEM_CAPACITY":99,"MAX_BERRY_CAPACITY":999,"MAX_BERRY_INDEX":178,"MAX_ITEM_DIGITS":3,"MAX_PC_ITEM_CAPACITY":999,"MAX_TRAINERS_COUNT":864,"MOVES_COUNT":355,"MOVE_ABSORB":71,"MOVE_ACID":51,"MOVE_ACID_ARMOR":151,"MOVE_AERIAL_ACE":332,"MOVE_AEROBLAST":177,"MOVE_AGILITY":97,"MOVE_AIR_CUTTER":314,"MOVE_AMNESIA":133,"MOVE_ANCIENT_POWER":246,"MOVE_ARM_THRUST":292,"MOVE_AROMATHERAPY":312,"MOVE_ASSIST":274,"MOVE_ASTONISH":310,"MOVE_ATTRACT":213,"MOVE_AURORA_BEAM":62,"MOVE_BARRAGE":140,"MOVE_BARRIER":112,"MOVE_BATON_PASS":226,"MOVE_BEAT_UP":251,"MOVE_BELLY_DRUM":187,"MOVE_BIDE":117,"MOVE_BIND":20,"MOVE_BITE":44,"MOVE_BLAST_BURN":307,"MOVE_BLAZE_KICK":299,"MOVE_BLIZZARD":59,"MOVE_BLOCK":335,"MOVE_BODY_SLAM":34,"MOVE_BONEMERANG":155,"MOVE_BONE_CLUB":125,"MOVE_BONE_RUSH":198,"MOVE_BOUNCE":340,"MOVE_BRICK_BREAK":280,"MOVE_BUBBLE":145,"MOVE_BUBBLE_BEAM":61,"MOVE_BULK_UP":339,"MOVE_BULLET_SEED":331,"MOVE_CALM_MIND":347,"MOVE_CAMOUFLAGE":293,"MOVE_CHARGE":268,"MOVE_CHARM":204,"MOVE_CLAMP":128,"MOVE_COMET_PUNCH":4,"MOVE_CONFUSE_RAY":109,"MOVE_CONFUSION":93,"MOVE_CONSTRICT":132,"MOVE_CONVERSION":160,"MOVE_CONVERSION_2":176,"MOVE_COSMIC_POWER":322,"MOVE_COTTON_SPORE":178,"MOVE_COUNTER":68,"MOVE_COVET":343,"MOVE_CRABHAMMER":152,"MOVE_CROSS_CHOP":238,"MOVE_CRUNCH":242,"MOVE_CRUSH_CLAW":306,"MOVE_CURSE":174,"MOVE_CUT":15,"MOVE_DEFENSE_CURL":111,"MOVE_DESTINY_BOND":194,"MOVE_DETECT":197,"MOVE_DIG":91,"MOVE_DISABLE":50,"MOVE_DIVE":291,"MOVE_DIZZY_PUNCH":146,"MOVE_DOOM_DESIRE":353,"MOVE_DOUBLE_EDGE":38,"MOVE_DOUBLE_KICK":24,"MOVE_DOUBLE_SLAP":3,"MOVE_DOUBLE_TEAM":104,"MOVE_DRAGON_BREATH":225,"MOVE_DRAGON_CLAW":337,"MOVE_DRAGON_DANCE":349,"MOVE_DRAGON_RAGE":82,"MOVE_DREAM_EATER":138,"MOVE_DRILL_PECK":65,"MOVE_DYNAMIC_PUNCH":223,"MOVE_EARTHQUAKE":89,"MOVE_EGG_BOMB":121,"MOVE_EMBER":52,"MOVE_ENCORE":227,"MOVE_ENDEAVOR":283,"MOVE_ENDURE":203,"MOVE_ERUPTION":284,"MOVE_EXPLOSION":153,"MOVE_EXTRASENSORY":326,"MOVE_EXTREME_SPEED":245,"MOVE_FACADE":263,"MOVE_FAINT_ATTACK":185,"MOVE_FAKE_OUT":252,"MOVE_FAKE_TEARS":313,"MOVE_FALSE_SWIPE":206,"MOVE_FEATHER_DANCE":297,"MOVE_FIRE_BLAST":126,"MOVE_FIRE_PUNCH":7,"MOVE_FIRE_SPIN":83,"MOVE_FISSURE":90,"MOVE_FLAIL":175,"MOVE_FLAMETHROWER":53,"MOVE_FLAME_WHEEL":172,"MOVE_FLASH":148,"MOVE_FLATTER":260,"MOVE_FLY":19,"MOVE_FOCUS_ENERGY":116,"MOVE_FOCUS_PUNCH":264,"MOVE_FOLLOW_ME":266,"MOVE_FORESIGHT":193,"MOVE_FRENZY_PLANT":338,"MOVE_FRUSTRATION":218,"MOVE_FURY_ATTACK":31,"MOVE_FURY_CUTTER":210,"MOVE_FURY_SWIPES":154,"MOVE_FUTURE_SIGHT":248,"MOVE_GIGA_DRAIN":202,"MOVE_GLARE":137,"MOVE_GRASS_WHISTLE":320,"MOVE_GROWL":45,"MOVE_GROWTH":74,"MOVE_GRUDGE":288,"MOVE_GUILLOTINE":12,"MOVE_GUST":16,"MOVE_HAIL":258,"MOVE_HARDEN":106,"MOVE_HAZE":114,"MOVE_HEADBUTT":29,"MOVE_HEAL_BELL":215,"MOVE_HEAT_WAVE":257,"MOVE_HELPING_HAND":270,"MOVE_HIDDEN_POWER":237,"MOVE_HI_JUMP_KICK":136,"MOVE_HORN_ATTACK":30,"MOVE_HORN_DRILL":32,"MOVE_HOWL":336,"MOVE_HYDRO_CANNON":308,"MOVE_HYDRO_PUMP":56,"MOVE_HYPER_BEAM":63,"MOVE_HYPER_FANG":158,"MOVE_HYPER_VOICE":304,"MOVE_HYPNOSIS":95,"MOVE_ICE_BALL":301,"MOVE_ICE_BEAM":58,"MOVE_ICE_PUNCH":8,"MOVE_ICICLE_SPEAR":333,"MOVE_ICY_WIND":196,"MOVE_IMPRISON":286,"MOVE_INGRAIN":275,"MOVE_IRON_DEFENSE":334,"MOVE_IRON_TAIL":231,"MOVE_JUMP_KICK":26,"MOVE_KARATE_CHOP":2,"MOVE_KINESIS":134,"MOVE_KNOCK_OFF":282,"MOVE_LEAF_BLADE":348,"MOVE_LEECH_LIFE":141,"MOVE_LEECH_SEED":73,"MOVE_LEER":43,"MOVE_LICK":122,"MOVE_LIGHT_SCREEN":113,"MOVE_LOCK_ON":199,"MOVE_LOVELY_KISS":142,"MOVE_LOW_KICK":67,"MOVE_LUSTER_PURGE":295,"MOVE_MACH_PUNCH":183,"MOVE_MAGICAL_LEAF":345,"MOVE_MAGIC_COAT":277,"MOVE_MAGNITUDE":222,"MOVE_MEAN_LOOK":212,"MOVE_MEDITATE":96,"MOVE_MEGAHORN":224,"MOVE_MEGA_DRAIN":72,"MOVE_MEGA_KICK":25,"MOVE_MEGA_PUNCH":5,"MOVE_MEMENTO":262,"MOVE_METAL_CLAW":232,"MOVE_METAL_SOUND":319,"MOVE_METEOR_MASH":309,"MOVE_METRONOME":118,"MOVE_MILK_DRINK":208,"MOVE_MIMIC":102,"MOVE_MIND_READER":170,"MOVE_MINIMIZE":107,"MOVE_MIRROR_COAT":243,"MOVE_MIRROR_MOVE":119,"MOVE_MIST":54,"MOVE_MIST_BALL":296,"MOVE_MOONLIGHT":236,"MOVE_MORNING_SUN":234,"MOVE_MUDDY_WATER":330,"MOVE_MUD_SHOT":341,"MOVE_MUD_SLAP":189,"MOVE_MUD_SPORT":300,"MOVE_NATURE_POWER":267,"MOVE_NEEDLE_ARM":302,"MOVE_NIGHTMARE":171,"MOVE_NIGHT_SHADE":101,"MOVE_NONE":0,"MOVE_OCTAZOOKA":190,"MOVE_ODOR_SLEUTH":316,"MOVE_OUTRAGE":200,"MOVE_OVERHEAT":315,"MOVE_PAIN_SPLIT":220,"MOVE_PAY_DAY":6,"MOVE_PECK":64,"MOVE_PERISH_SONG":195,"MOVE_PETAL_DANCE":80,"MOVE_PIN_MISSILE":42,"MOVE_POISON_FANG":305,"MOVE_POISON_GAS":139,"MOVE_POISON_POWDER":77,"MOVE_POISON_STING":40,"MOVE_POISON_TAIL":342,"MOVE_POUND":1,"MOVE_POWDER_SNOW":181,"MOVE_PRESENT":217,"MOVE_PROTECT":182,"MOVE_PSYBEAM":60,"MOVE_PSYCHIC":94,"MOVE_PSYCHO_BOOST":354,"MOVE_PSYCH_UP":244,"MOVE_PSYWAVE":149,"MOVE_PURSUIT":228,"MOVE_QUICK_ATTACK":98,"MOVE_RAGE":99,"MOVE_RAIN_DANCE":240,"MOVE_RAPID_SPIN":229,"MOVE_RAZOR_LEAF":75,"MOVE_RAZOR_WIND":13,"MOVE_RECOVER":105,"MOVE_RECYCLE":278,"MOVE_REFLECT":115,"MOVE_REFRESH":287,"MOVE_REST":156,"MOVE_RETURN":216,"MOVE_REVENGE":279,"MOVE_REVERSAL":179,"MOVE_ROAR":46,"MOVE_ROCK_BLAST":350,"MOVE_ROCK_SLIDE":157,"MOVE_ROCK_SMASH":249,"MOVE_ROCK_THROW":88,"MOVE_ROCK_TOMB":317,"MOVE_ROLE_PLAY":272,"MOVE_ROLLING_KICK":27,"MOVE_ROLLOUT":205,"MOVE_SACRED_FIRE":221,"MOVE_SAFEGUARD":219,"MOVE_SANDSTORM":201,"MOVE_SAND_ATTACK":28,"MOVE_SAND_TOMB":328,"MOVE_SCARY_FACE":184,"MOVE_SCRATCH":10,"MOVE_SCREECH":103,"MOVE_SECRET_POWER":290,"MOVE_SEISMIC_TOSS":69,"MOVE_SELF_DESTRUCT":120,"MOVE_SHADOW_BALL":247,"MOVE_SHADOW_PUNCH":325,"MOVE_SHARPEN":159,"MOVE_SHEER_COLD":329,"MOVE_SHOCK_WAVE":351,"MOVE_SIGNAL_BEAM":324,"MOVE_SILVER_WIND":318,"MOVE_SING":47,"MOVE_SKETCH":166,"MOVE_SKILL_SWAP":285,"MOVE_SKULL_BASH":130,"MOVE_SKY_ATTACK":143,"MOVE_SKY_UPPERCUT":327,"MOVE_SLACK_OFF":303,"MOVE_SLAM":21,"MOVE_SLASH":163,"MOVE_SLEEP_POWDER":79,"MOVE_SLEEP_TALK":214,"MOVE_SLUDGE":124,"MOVE_SLUDGE_BOMB":188,"MOVE_SMELLING_SALT":265,"MOVE_SMOG":123,"MOVE_SMOKESCREEN":108,"MOVE_SNATCH":289,"MOVE_SNORE":173,"MOVE_SOFT_BOILED":135,"MOVE_SOLAR_BEAM":76,"MOVE_SONIC_BOOM":49,"MOVE_SPARK":209,"MOVE_SPIDER_WEB":169,"MOVE_SPIKES":191,"MOVE_SPIKE_CANNON":131,"MOVE_SPITE":180,"MOVE_SPIT_UP":255,"MOVE_SPLASH":150,"MOVE_SPORE":147,"MOVE_STEEL_WING":211,"MOVE_STOCKPILE":254,"MOVE_STOMP":23,"MOVE_STRENGTH":70,"MOVE_STRING_SHOT":81,"MOVE_STRUGGLE":165,"MOVE_STUN_SPORE":78,"MOVE_SUBMISSION":66,"MOVE_SUBSTITUTE":164,"MOVE_SUNNY_DAY":241,"MOVE_SUPERPOWER":276,"MOVE_SUPERSONIC":48,"MOVE_SUPER_FANG":162,"MOVE_SURF":57,"MOVE_SWAGGER":207,"MOVE_SWALLOW":256,"MOVE_SWEET_KISS":186,"MOVE_SWEET_SCENT":230,"MOVE_SWIFT":129,"MOVE_SWORDS_DANCE":14,"MOVE_SYNTHESIS":235,"MOVE_TACKLE":33,"MOVE_TAIL_GLOW":294,"MOVE_TAIL_WHIP":39,"MOVE_TAKE_DOWN":36,"MOVE_TAUNT":269,"MOVE_TEETER_DANCE":298,"MOVE_TELEPORT":100,"MOVE_THIEF":168,"MOVE_THRASH":37,"MOVE_THUNDER":87,"MOVE_THUNDERBOLT":85,"MOVE_THUNDER_PUNCH":9,"MOVE_THUNDER_SHOCK":84,"MOVE_THUNDER_WAVE":86,"MOVE_TICKLE":321,"MOVE_TORMENT":259,"MOVE_TOXIC":92,"MOVE_TRANSFORM":144,"MOVE_TRICK":271,"MOVE_TRIPLE_KICK":167,"MOVE_TRI_ATTACK":161,"MOVE_TWINEEDLE":41,"MOVE_TWISTER":239,"MOVE_UNAVAILABLE":65535,"MOVE_UPROAR":253,"MOVE_VICE_GRIP":11,"MOVE_VINE_WHIP":22,"MOVE_VITAL_THROW":233,"MOVE_VOLT_TACKLE":344,"MOVE_WATERFALL":127,"MOVE_WATER_GUN":55,"MOVE_WATER_PULSE":352,"MOVE_WATER_SPORT":346,"MOVE_WATER_SPOUT":323,"MOVE_WEATHER_BALL":311,"MOVE_WHIRLPOOL":250,"MOVE_WHIRLWIND":18,"MOVE_WILL_O_WISP":261,"MOVE_WING_ATTACK":17,"MOVE_WISH":273,"MOVE_WITHDRAW":110,"MOVE_WRAP":35,"MOVE_YAWN":281,"MOVE_ZAP_CANNON":192,"MUS_ABANDONED_SHIP":381,"MUS_ABNORMAL_WEATHER":443,"MUS_AQUA_MAGMA_HIDEOUT":430,"MUS_AWAKEN_LEGEND":388,"MUS_BIRCH_LAB":383,"MUS_B_ARENA":458,"MUS_B_DOME":467,"MUS_B_DOME_LOBBY":473,"MUS_B_FACTORY":469,"MUS_B_FRONTIER":457,"MUS_B_PALACE":463,"MUS_B_PIKE":468,"MUS_B_PYRAMID":461,"MUS_B_PYRAMID_TOP":462,"MUS_B_TOWER":465,"MUS_B_TOWER_RS":384,"MUS_CABLE_CAR":425,"MUS_CAUGHT":352,"MUS_CAVE_OF_ORIGIN":386,"MUS_CONTEST":440,"MUS_CONTEST_LOBBY":452,"MUS_CONTEST_RESULTS":446,"MUS_CONTEST_WINNER":439,"MUS_CREDITS":455,"MUS_CYCLING":403,"MUS_C_COMM_CENTER":356,"MUS_C_VS_LEGEND_BEAST":358,"MUS_DESERT":409,"MUS_DEWFORD":427,"MUS_DUMMY":0,"MUS_ENCOUNTER_AQUA":419,"MUS_ENCOUNTER_BRENDAN":421,"MUS_ENCOUNTER_CHAMPION":454,"MUS_ENCOUNTER_COOL":417,"MUS_ENCOUNTER_ELITE_FOUR":450,"MUS_ENCOUNTER_FEMALE":407,"MUS_ENCOUNTER_GIRL":379,"MUS_ENCOUNTER_HIKER":451,"MUS_ENCOUNTER_INTENSE":416,"MUS_ENCOUNTER_INTERVIEWER":453,"MUS_ENCOUNTER_MAGMA":441,"MUS_ENCOUNTER_MALE":380,"MUS_ENCOUNTER_MAY":415,"MUS_ENCOUNTER_RICH":397,"MUS_ENCOUNTER_SUSPICIOUS":423,"MUS_ENCOUNTER_SWIMMER":385,"MUS_ENCOUNTER_TWINS":449,"MUS_END":456,"MUS_EVER_GRANDE":422,"MUS_EVOLUTION":377,"MUS_EVOLUTION_INTRO":376,"MUS_EVOLVED":371,"MUS_FALLARBOR":437,"MUS_FOLLOW_ME":420,"MUS_FORTREE":382,"MUS_GAME_CORNER":426,"MUS_GSC_PEWTER":357,"MUS_GSC_ROUTE38":351,"MUS_GYM":364,"MUS_HALL_OF_FAME":436,"MUS_HALL_OF_FAME_ROOM":447,"MUS_HEAL":368,"MUS_HELP":410,"MUS_INTRO":414,"MUS_INTRO_BATTLE":442,"MUS_LEVEL_UP":367,"MUS_LILYCOVE":408,"MUS_LILYCOVE_MUSEUM":373,"MUS_LINK_CONTEST_P1":393,"MUS_LINK_CONTEST_P2":394,"MUS_LINK_CONTEST_P3":395,"MUS_LINK_CONTEST_P4":396,"MUS_LITTLEROOT":405,"MUS_LITTLEROOT_TEST":350,"MUS_MOVE_DELETED":378,"MUS_MT_CHIMNEY":406,"MUS_MT_PYRE":432,"MUS_MT_PYRE_EXTERIOR":434,"MUS_NONE":65535,"MUS_OBTAIN_BADGE":369,"MUS_OBTAIN_BERRY":387,"MUS_OBTAIN_B_POINTS":459,"MUS_OBTAIN_ITEM":370,"MUS_OBTAIN_SYMBOL":466,"MUS_OBTAIN_TMHM":372,"MUS_OCEANIC_MUSEUM":375,"MUS_OLDALE":363,"MUS_PETALBURG":362,"MUS_PETALBURG_WOODS":366,"MUS_POKE_CENTER":400,"MUS_POKE_MART":404,"MUS_RAYQUAZA_APPEARS":464,"MUS_REGISTER_MATCH_CALL":460,"MUS_RG_BERRY_PICK":542,"MUS_RG_CAUGHT":534,"MUS_RG_CAUGHT_INTRO":531,"MUS_RG_CELADON":521,"MUS_RG_CINNABAR":491,"MUS_RG_CREDITS":502,"MUS_RG_CYCLING":494,"MUS_RG_DEX_RATING":529,"MUS_RG_ENCOUNTER_BOY":497,"MUS_RG_ENCOUNTER_DEOXYS":555,"MUS_RG_ENCOUNTER_GIRL":496,"MUS_RG_ENCOUNTER_GYM_LEADER":554,"MUS_RG_ENCOUNTER_RIVAL":527,"MUS_RG_ENCOUNTER_ROCKET":495,"MUS_RG_FOLLOW_ME":484,"MUS_RG_FUCHSIA":520,"MUS_RG_GAME_CORNER":485,"MUS_RG_GAME_FREAK":533,"MUS_RG_GYM":487,"MUS_RG_HALL_OF_FAME":498,"MUS_RG_HEAL":493,"MUS_RG_INTRO_FIGHT":489,"MUS_RG_JIGGLYPUFF":488,"MUS_RG_LAVENDER":492,"MUS_RG_MT_MOON":500,"MUS_RG_MYSTERY_GIFT":541,"MUS_RG_NET_CENTER":540,"MUS_RG_NEW_GAME_EXIT":537,"MUS_RG_NEW_GAME_INSTRUCT":535,"MUS_RG_NEW_GAME_INTRO":536,"MUS_RG_OAK":514,"MUS_RG_OAK_LAB":513,"MUS_RG_OBTAIN_KEY_ITEM":530,"MUS_RG_PALLET":512,"MUS_RG_PEWTER":526,"MUS_RG_PHOTO":532,"MUS_RG_POKE_CENTER":515,"MUS_RG_POKE_FLUTE":550,"MUS_RG_POKE_JUMP":538,"MUS_RG_POKE_MANSION":501,"MUS_RG_POKE_TOWER":518,"MUS_RG_RIVAL_EXIT":528,"MUS_RG_ROCKET_HIDEOUT":486,"MUS_RG_ROUTE1":503,"MUS_RG_ROUTE11":506,"MUS_RG_ROUTE24":504,"MUS_RG_ROUTE3":505,"MUS_RG_SEVII_123":547,"MUS_RG_SEVII_45":548,"MUS_RG_SEVII_67":549,"MUS_RG_SEVII_CAVE":543,"MUS_RG_SEVII_DUNGEON":546,"MUS_RG_SEVII_ROUTE":545,"MUS_RG_SILPH":519,"MUS_RG_SLOW_PALLET":557,"MUS_RG_SS_ANNE":516,"MUS_RG_SURF":517,"MUS_RG_TEACHY_TV_MENU":558,"MUS_RG_TEACHY_TV_SHOW":544,"MUS_RG_TITLE":490,"MUS_RG_TRAINER_TOWER":556,"MUS_RG_UNION_ROOM":539,"MUS_RG_VERMILLION":525,"MUS_RG_VICTORY_GYM_LEADER":524,"MUS_RG_VICTORY_ROAD":507,"MUS_RG_VICTORY_TRAINER":522,"MUS_RG_VICTORY_WILD":523,"MUS_RG_VIRIDIAN_FOREST":499,"MUS_RG_VS_CHAMPION":511,"MUS_RG_VS_DEOXYS":551,"MUS_RG_VS_GYM_LEADER":508,"MUS_RG_VS_LEGEND":553,"MUS_RG_VS_MEWTWO":552,"MUS_RG_VS_TRAINER":509,"MUS_RG_VS_WILD":510,"MUS_ROULETTE":392,"MUS_ROUTE101":359,"MUS_ROUTE104":401,"MUS_ROUTE110":360,"MUS_ROUTE113":418,"MUS_ROUTE118":32767,"MUS_ROUTE119":402,"MUS_ROUTE120":361,"MUS_ROUTE122":374,"MUS_RUSTBORO":399,"MUS_SAFARI_ZONE":428,"MUS_SAILING":431,"MUS_SCHOOL":435,"MUS_SEALED_CHAMBER":438,"MUS_SLATEPORT":433,"MUS_SLOTS_JACKPOT":389,"MUS_SLOTS_WIN":390,"MUS_SOOTOPOLIS":445,"MUS_SURF":365,"MUS_TITLE":413,"MUS_TOO_BAD":391,"MUS_TRICK_HOUSE":448,"MUS_UNDERWATER":411,"MUS_VERDANTURF":398,"MUS_VICTORY_AQUA_MAGMA":424,"MUS_VICTORY_GYM_LEADER":354,"MUS_VICTORY_LEAGUE":355,"MUS_VICTORY_ROAD":429,"MUS_VICTORY_TRAINER":412,"MUS_VICTORY_WILD":353,"MUS_VS_AQUA_MAGMA":475,"MUS_VS_AQUA_MAGMA_LEADER":483,"MUS_VS_CHAMPION":478,"MUS_VS_ELITE_FOUR":482,"MUS_VS_FRONTIER_BRAIN":471,"MUS_VS_GYM_LEADER":477,"MUS_VS_KYOGRE_GROUDON":480,"MUS_VS_MEW":472,"MUS_VS_RAYQUAZA":470,"MUS_VS_REGI":479,"MUS_VS_RIVAL":481,"MUS_VS_TRAINER":476,"MUS_VS_WILD":474,"MUS_WEATHER_GROUDON":444,"NUM_BADGES":8,"NUM_BERRY_MASTER_BERRIES":10,"NUM_BERRY_MASTER_BERRIES_SKIPPED":20,"NUM_BERRY_MASTER_WIFE_BERRIES":10,"NUM_DAILY_FLAGS":64,"NUM_HIDDEN_MACHINES":8,"NUM_KIRI_BERRIES":10,"NUM_KIRI_BERRIES_SKIPPED":20,"NUM_ROUTE_114_MAN_BERRIES":5,"NUM_ROUTE_114_MAN_BERRIES_SKIPPED":15,"NUM_SPECIAL_FLAGS":128,"NUM_SPECIES":412,"NUM_TECHNICAL_MACHINES":50,"NUM_TEMP_FLAGS":32,"NUM_WATER_STAGES":4,"NUM_WONDER_CARD_FLAGS":20,"OLD_ROD":0,"PH_CHOICE_BLEND":589,"PH_CHOICE_HELD":590,"PH_CHOICE_SOLO":591,"PH_CLOTH_BLEND":565,"PH_CLOTH_HELD":566,"PH_CLOTH_SOLO":567,"PH_CURE_BLEND":604,"PH_CURE_HELD":605,"PH_CURE_SOLO":606,"PH_DRESS_BLEND":568,"PH_DRESS_HELD":569,"PH_DRESS_SOLO":570,"PH_FACE_BLEND":562,"PH_FACE_HELD":563,"PH_FACE_SOLO":564,"PH_FLEECE_BLEND":571,"PH_FLEECE_HELD":572,"PH_FLEECE_SOLO":573,"PH_FOOT_BLEND":595,"PH_FOOT_HELD":596,"PH_FOOT_SOLO":597,"PH_GOAT_BLEND":583,"PH_GOAT_HELD":584,"PH_GOAT_SOLO":585,"PH_GOOSE_BLEND":598,"PH_GOOSE_HELD":599,"PH_GOOSE_SOLO":600,"PH_KIT_BLEND":574,"PH_KIT_HELD":575,"PH_KIT_SOLO":576,"PH_LOT_BLEND":580,"PH_LOT_HELD":581,"PH_LOT_SOLO":582,"PH_MOUTH_BLEND":592,"PH_MOUTH_HELD":593,"PH_MOUTH_SOLO":594,"PH_NURSE_BLEND":607,"PH_NURSE_HELD":608,"PH_NURSE_SOLO":609,"PH_PRICE_BLEND":577,"PH_PRICE_HELD":578,"PH_PRICE_SOLO":579,"PH_STRUT_BLEND":601,"PH_STRUT_HELD":602,"PH_STRUT_SOLO":603,"PH_THOUGHT_BLEND":586,"PH_THOUGHT_HELD":587,"PH_THOUGHT_SOLO":588,"PH_TRAP_BLEND":559,"PH_TRAP_HELD":560,"PH_TRAP_SOLO":561,"SE_A":25,"SE_APPLAUSE":105,"SE_ARENA_TIMEUP1":265,"SE_ARENA_TIMEUP2":266,"SE_BALL":23,"SE_BALLOON_BLUE":75,"SE_BALLOON_RED":74,"SE_BALLOON_YELLOW":76,"SE_BALL_BOUNCE_1":56,"SE_BALL_BOUNCE_2":57,"SE_BALL_BOUNCE_3":58,"SE_BALL_BOUNCE_4":59,"SE_BALL_OPEN":15,"SE_BALL_THROW":61,"SE_BALL_TRADE":60,"SE_BALL_TRAY_BALL":115,"SE_BALL_TRAY_ENTER":114,"SE_BALL_TRAY_EXIT":116,"SE_BANG":20,"SE_BERRY_BLENDER":53,"SE_BIKE_BELL":11,"SE_BIKE_HOP":34,"SE_BOO":22,"SE_BREAKABLE_DOOR":77,"SE_BRIDGE_WALK":71,"SE_CARD":54,"SE_CLICK":36,"SE_CONTEST_CONDITION_LOSE":38,"SE_CONTEST_CURTAIN_FALL":98,"SE_CONTEST_CURTAIN_RISE":97,"SE_CONTEST_HEART":96,"SE_CONTEST_ICON_CHANGE":99,"SE_CONTEST_ICON_CLEAR":100,"SE_CONTEST_MONS_TURN":101,"SE_CONTEST_PLACE":24,"SE_DEX_PAGE":109,"SE_DEX_SCROLL":108,"SE_DEX_SEARCH":112,"SE_DING_DONG":73,"SE_DOOR":8,"SE_DOWNPOUR":83,"SE_DOWNPOUR_STOP":84,"SE_E":28,"SE_EFFECTIVE":13,"SE_EGG_HATCH":113,"SE_ELEVATOR":89,"SE_ESCALATOR":80,"SE_EXIT":9,"SE_EXP":33,"SE_EXP_MAX":91,"SE_FAILURE":32,"SE_FAINT":16,"SE_FALL":43,"SE_FIELD_POISON":79,"SE_FLEE":17,"SE_FU_ZAKU":37,"SE_GLASS_FLUTE":117,"SE_I":26,"SE_ICE_BREAK":41,"SE_ICE_CRACK":42,"SE_ICE_STAIRS":40,"SE_INTRO_BLAST":103,"SE_ITEMFINDER":72,"SE_LAVARIDGE_FALL_WARP":39,"SE_LEDGE":10,"SE_LOW_HEALTH":90,"SE_MUD_BALL":78,"SE_MUGSHOT":104,"SE_M_ABSORB":180,"SE_M_ABSORB_2":179,"SE_M_ACID_ARMOR":218,"SE_M_ATTRACT":226,"SE_M_ATTRACT2":227,"SE_M_BARRIER":208,"SE_M_BATON_PASS":224,"SE_M_BELLY_DRUM":185,"SE_M_BIND":170,"SE_M_BITE":161,"SE_M_BLIZZARD":153,"SE_M_BLIZZARD2":154,"SE_M_BONEMERANG":187,"SE_M_BRICK_BREAK":198,"SE_M_BUBBLE":124,"SE_M_BUBBLE2":125,"SE_M_BUBBLE3":126,"SE_M_BUBBLE_BEAM":182,"SE_M_BUBBLE_BEAM2":183,"SE_M_CHARGE":213,"SE_M_CHARM":212,"SE_M_COMET_PUNCH":139,"SE_M_CONFUSE_RAY":196,"SE_M_COSMIC_POWER":243,"SE_M_CRABHAMMER":142,"SE_M_CUT":128,"SE_M_DETECT":209,"SE_M_DIG":175,"SE_M_DIVE":233,"SE_M_DIZZY_PUNCH":176,"SE_M_DOUBLE_SLAP":134,"SE_M_DOUBLE_TEAM":135,"SE_M_DRAGON_RAGE":171,"SE_M_EARTHQUAKE":234,"SE_M_EMBER":151,"SE_M_ENCORE":222,"SE_M_ENCORE2":223,"SE_M_EXPLOSION":178,"SE_M_FAINT_ATTACK":190,"SE_M_FIRE_PUNCH":147,"SE_M_FLAMETHROWER":146,"SE_M_FLAME_WHEEL":144,"SE_M_FLAME_WHEEL2":145,"SE_M_FLATTER":229,"SE_M_FLY":158,"SE_M_GIGA_DRAIN":199,"SE_M_GRASSWHISTLE":231,"SE_M_GUST":132,"SE_M_GUST2":133,"SE_M_HAIL":242,"SE_M_HARDEN":120,"SE_M_HAZE":246,"SE_M_HEADBUTT":162,"SE_M_HEAL_BELL":195,"SE_M_HEAT_WAVE":240,"SE_M_HORN_ATTACK":166,"SE_M_HYDRO_PUMP":164,"SE_M_HYPER_BEAM":215,"SE_M_HYPER_BEAM2":247,"SE_M_ICY_WIND":137,"SE_M_JUMP_KICK":143,"SE_M_LEER":192,"SE_M_LICK":188,"SE_M_LOCK_ON":210,"SE_M_MEGA_KICK":140,"SE_M_MEGA_KICK2":141,"SE_M_METRONOME":186,"SE_M_MILK_DRINK":225,"SE_M_MINIMIZE":204,"SE_M_MIST":168,"SE_M_MOONLIGHT":211,"SE_M_MORNING_SUN":228,"SE_M_NIGHTMARE":121,"SE_M_PAY_DAY":174,"SE_M_PERISH_SONG":173,"SE_M_PETAL_DANCE":202,"SE_M_POISON_POWDER":169,"SE_M_PSYBEAM":189,"SE_M_PSYBEAM2":200,"SE_M_RAIN_DANCE":127,"SE_M_RAZOR_WIND":136,"SE_M_RAZOR_WIND2":160,"SE_M_REFLECT":207,"SE_M_REVERSAL":217,"SE_M_ROCK_THROW":131,"SE_M_SACRED_FIRE":149,"SE_M_SACRED_FIRE2":150,"SE_M_SANDSTORM":219,"SE_M_SAND_ATTACK":159,"SE_M_SAND_TOMB":230,"SE_M_SCRATCH":155,"SE_M_SCREECH":181,"SE_M_SELF_DESTRUCT":177,"SE_M_SING":172,"SE_M_SKETCH":205,"SE_M_SKY_UPPERCUT":238,"SE_M_SNORE":197,"SE_M_SOLAR_BEAM":201,"SE_M_SPIT_UP":232,"SE_M_STAT_DECREASE":245,"SE_M_STAT_INCREASE":239,"SE_M_STRENGTH":214,"SE_M_STRING_SHOT":129,"SE_M_STRING_SHOT2":130,"SE_M_SUPERSONIC":184,"SE_M_SURF":163,"SE_M_SWAGGER":193,"SE_M_SWAGGER2":194,"SE_M_SWEET_SCENT":236,"SE_M_SWIFT":206,"SE_M_SWORDS_DANCE":191,"SE_M_TAIL_WHIP":167,"SE_M_TAKE_DOWN":152,"SE_M_TEETER_DANCE":244,"SE_M_TELEPORT":203,"SE_M_THUNDERBOLT":118,"SE_M_THUNDERBOLT2":119,"SE_M_THUNDER_WAVE":138,"SE_M_TOXIC":148,"SE_M_TRI_ATTACK":220,"SE_M_TRI_ATTACK2":221,"SE_M_TWISTER":235,"SE_M_UPROAR":241,"SE_M_VICEGRIP":156,"SE_M_VITAL_THROW":122,"SE_M_VITAL_THROW2":123,"SE_M_WATERFALL":216,"SE_M_WHIRLPOOL":165,"SE_M_WING_ATTACK":157,"SE_M_YAWN":237,"SE_N":30,"SE_NOTE_A":67,"SE_NOTE_B":68,"SE_NOTE_C":62,"SE_NOTE_C_HIGH":69,"SE_NOTE_D":63,"SE_NOTE_E":64,"SE_NOTE_F":65,"SE_NOTE_G":66,"SE_NOT_EFFECTIVE":12,"SE_O":29,"SE_ORB":107,"SE_PC_LOGIN":2,"SE_PC_OFF":3,"SE_PC_ON":4,"SE_PIKE_CURTAIN_CLOSE":267,"SE_PIKE_CURTAIN_OPEN":268,"SE_PIN":21,"SE_POKENAV_CALL":263,"SE_POKENAV_HANG_UP":264,"SE_POKENAV_OFF":111,"SE_POKENAV_ON":110,"SE_PUDDLE":70,"SE_RAIN":85,"SE_RAIN_STOP":86,"SE_REPEL":47,"SE_RG_BAG_CURSOR":252,"SE_RG_BAG_POCKET":253,"SE_RG_BALL_CLICK":254,"SE_RG_CARD_FLIP":249,"SE_RG_CARD_FLIPPING":250,"SE_RG_CARD_OPEN":251,"SE_RG_DEOXYS_MOVE":260,"SE_RG_DOOR":248,"SE_RG_HELP_CLOSE":258,"SE_RG_HELP_ERROR":259,"SE_RG_HELP_OPEN":257,"SE_RG_POKE_JUMP_FAILURE":262,"SE_RG_POKE_JUMP_SUCCESS":261,"SE_RG_SHOP":255,"SE_RG_SS_ANNE_HORN":256,"SE_ROTATING_GATE":48,"SE_ROULETTE_BALL":92,"SE_ROULETTE_BALL2":93,"SE_SAVE":55,"SE_SELECT":5,"SE_SHINY":102,"SE_SHIP":19,"SE_SHOP":95,"SE_SLIDING_DOOR":18,"SE_SUCCESS":31,"SE_SUDOWOODO_SHAKE":269,"SE_SUPER_EFFECTIVE":14,"SE_SWITCH":35,"SE_TAILLOW_WING_FLAP":94,"SE_THUNDER":87,"SE_THUNDER2":88,"SE_THUNDERSTORM":81,"SE_THUNDERSTORM_STOP":82,"SE_TRUCK_DOOR":52,"SE_TRUCK_MOVE":49,"SE_TRUCK_STOP":50,"SE_TRUCK_UNLOAD":51,"SE_U":27,"SE_UNLOCK":44,"SE_USE_ITEM":1,"SE_VEND":106,"SE_WALL_HIT":7,"SE_WARP_IN":45,"SE_WARP_OUT":46,"SE_WIN_OPEN":6,"SPECIAL_FLAGS_END":16511,"SPECIAL_FLAGS_START":16384,"SPECIES_ABRA":63,"SPECIES_ABSOL":376,"SPECIES_AERODACTYL":142,"SPECIES_AGGRON":384,"SPECIES_AIPOM":190,"SPECIES_ALAKAZAM":65,"SPECIES_ALTARIA":359,"SPECIES_AMPHAROS":181,"SPECIES_ANORITH":390,"SPECIES_ARBOK":24,"SPECIES_ARCANINE":59,"SPECIES_ARIADOS":168,"SPECIES_ARMALDO":391,"SPECIES_ARON":382,"SPECIES_ARTICUNO":144,"SPECIES_AZUMARILL":184,"SPECIES_AZURILL":350,"SPECIES_BAGON":395,"SPECIES_BALTOY":318,"SPECIES_BANETTE":378,"SPECIES_BARBOACH":323,"SPECIES_BAYLEEF":153,"SPECIES_BEAUTIFLY":292,"SPECIES_BEEDRILL":15,"SPECIES_BELDUM":398,"SPECIES_BELLOSSOM":182,"SPECIES_BELLSPROUT":69,"SPECIES_BLASTOISE":9,"SPECIES_BLAZIKEN":282,"SPECIES_BLISSEY":242,"SPECIES_BRELOOM":307,"SPECIES_BULBASAUR":1,"SPECIES_BUTTERFREE":12,"SPECIES_CACNEA":344,"SPECIES_CACTURNE":345,"SPECIES_CAMERUPT":340,"SPECIES_CARVANHA":330,"SPECIES_CASCOON":293,"SPECIES_CASTFORM":385,"SPECIES_CATERPIE":10,"SPECIES_CELEBI":251,"SPECIES_CHANSEY":113,"SPECIES_CHARIZARD":6,"SPECIES_CHARMANDER":4,"SPECIES_CHARMELEON":5,"SPECIES_CHIKORITA":152,"SPECIES_CHIMECHO":411,"SPECIES_CHINCHOU":170,"SPECIES_CLAMPERL":373,"SPECIES_CLAYDOL":319,"SPECIES_CLEFABLE":36,"SPECIES_CLEFAIRY":35,"SPECIES_CLEFFA":173,"SPECIES_CLOYSTER":91,"SPECIES_COMBUSKEN":281,"SPECIES_CORPHISH":326,"SPECIES_CORSOLA":222,"SPECIES_CRADILY":389,"SPECIES_CRAWDAUNT":327,"SPECIES_CROBAT":169,"SPECIES_CROCONAW":159,"SPECIES_CUBONE":104,"SPECIES_CYNDAQUIL":155,"SPECIES_DELCATTY":316,"SPECIES_DELIBIRD":225,"SPECIES_DEOXYS":410,"SPECIES_DEWGONG":87,"SPECIES_DIGLETT":50,"SPECIES_DITTO":132,"SPECIES_DODRIO":85,"SPECIES_DODUO":84,"SPECIES_DONPHAN":232,"SPECIES_DRAGONAIR":148,"SPECIES_DRAGONITE":149,"SPECIES_DRATINI":147,"SPECIES_DROWZEE":96,"SPECIES_DUGTRIO":51,"SPECIES_DUNSPARCE":206,"SPECIES_DUSCLOPS":362,"SPECIES_DUSKULL":361,"SPECIES_DUSTOX":294,"SPECIES_EEVEE":133,"SPECIES_EGG":412,"SPECIES_EKANS":23,"SPECIES_ELECTABUZZ":125,"SPECIES_ELECTRIKE":337,"SPECIES_ELECTRODE":101,"SPECIES_ELEKID":239,"SPECIES_ENTEI":244,"SPECIES_ESPEON":196,"SPECIES_EXEGGCUTE":102,"SPECIES_EXEGGUTOR":103,"SPECIES_EXPLOUD":372,"SPECIES_FARFETCHD":83,"SPECIES_FEAROW":22,"SPECIES_FEEBAS":328,"SPECIES_FERALIGATR":160,"SPECIES_FLAAFFY":180,"SPECIES_FLAREON":136,"SPECIES_FLYGON":334,"SPECIES_FORRETRESS":205,"SPECIES_FURRET":162,"SPECIES_GARDEVOIR":394,"SPECIES_GASTLY":92,"SPECIES_GENGAR":94,"SPECIES_GEODUDE":74,"SPECIES_GIRAFARIG":203,"SPECIES_GLALIE":347,"SPECIES_GLIGAR":207,"SPECIES_GLOOM":44,"SPECIES_GOLBAT":42,"SPECIES_GOLDEEN":118,"SPECIES_GOLDUCK":55,"SPECIES_GOLEM":76,"SPECIES_GOREBYSS":375,"SPECIES_GRANBULL":210,"SPECIES_GRAVELER":75,"SPECIES_GRIMER":88,"SPECIES_GROUDON":405,"SPECIES_GROVYLE":278,"SPECIES_GROWLITHE":58,"SPECIES_GRUMPIG":352,"SPECIES_GULPIN":367,"SPECIES_GYARADOS":130,"SPECIES_HARIYAMA":336,"SPECIES_HAUNTER":93,"SPECIES_HERACROSS":214,"SPECIES_HITMONCHAN":107,"SPECIES_HITMONLEE":106,"SPECIES_HITMONTOP":237,"SPECIES_HOOTHOOT":163,"SPECIES_HOPPIP":187,"SPECIES_HORSEA":116,"SPECIES_HOUNDOOM":229,"SPECIES_HOUNDOUR":228,"SPECIES_HO_OH":250,"SPECIES_HUNTAIL":374,"SPECIES_HYPNO":97,"SPECIES_IGGLYBUFF":174,"SPECIES_ILLUMISE":387,"SPECIES_IVYSAUR":2,"SPECIES_JIGGLYPUFF":39,"SPECIES_JIRACHI":409,"SPECIES_JOLTEON":135,"SPECIES_JUMPLUFF":189,"SPECIES_JYNX":124,"SPECIES_KABUTO":140,"SPECIES_KABUTOPS":141,"SPECIES_KADABRA":64,"SPECIES_KAKUNA":14,"SPECIES_KANGASKHAN":115,"SPECIES_KECLEON":317,"SPECIES_KINGDRA":230,"SPECIES_KINGLER":99,"SPECIES_KIRLIA":393,"SPECIES_KOFFING":109,"SPECIES_KRABBY":98,"SPECIES_KYOGRE":404,"SPECIES_LAIRON":383,"SPECIES_LANTURN":171,"SPECIES_LAPRAS":131,"SPECIES_LARVITAR":246,"SPECIES_LATIAS":407,"SPECIES_LATIOS":408,"SPECIES_LEDIAN":166,"SPECIES_LEDYBA":165,"SPECIES_LICKITUNG":108,"SPECIES_LILEEP":388,"SPECIES_LINOONE":289,"SPECIES_LOMBRE":296,"SPECIES_LOTAD":295,"SPECIES_LOUDRED":371,"SPECIES_LUDICOLO":297,"SPECIES_LUGIA":249,"SPECIES_LUNATONE":348,"SPECIES_LUVDISC":325,"SPECIES_MACHAMP":68,"SPECIES_MACHOKE":67,"SPECIES_MACHOP":66,"SPECIES_MAGBY":240,"SPECIES_MAGCARGO":219,"SPECIES_MAGIKARP":129,"SPECIES_MAGMAR":126,"SPECIES_MAGNEMITE":81,"SPECIES_MAGNETON":82,"SPECIES_MAKUHITA":335,"SPECIES_MANECTRIC":338,"SPECIES_MANKEY":56,"SPECIES_MANTINE":226,"SPECIES_MAREEP":179,"SPECIES_MARILL":183,"SPECIES_MAROWAK":105,"SPECIES_MARSHTOMP":284,"SPECIES_MASQUERAIN":312,"SPECIES_MAWILE":355,"SPECIES_MEDICHAM":357,"SPECIES_MEDITITE":356,"SPECIES_MEGANIUM":154,"SPECIES_MEOWTH":52,"SPECIES_METAGROSS":400,"SPECIES_METANG":399,"SPECIES_METAPOD":11,"SPECIES_MEW":151,"SPECIES_MEWTWO":150,"SPECIES_MIGHTYENA":287,"SPECIES_MILOTIC":329,"SPECIES_MILTANK":241,"SPECIES_MINUN":354,"SPECIES_MISDREAVUS":200,"SPECIES_MOLTRES":146,"SPECIES_MR_MIME":122,"SPECIES_MUDKIP":283,"SPECIES_MUK":89,"SPECIES_MURKROW":198,"SPECIES_NATU":177,"SPECIES_NIDOKING":34,"SPECIES_NIDOQUEEN":31,"SPECIES_NIDORAN_F":29,"SPECIES_NIDORAN_M":32,"SPECIES_NIDORINA":30,"SPECIES_NIDORINO":33,"SPECIES_NINCADA":301,"SPECIES_NINETALES":38,"SPECIES_NINJASK":302,"SPECIES_NOCTOWL":164,"SPECIES_NONE":0,"SPECIES_NOSEPASS":320,"SPECIES_NUMEL":339,"SPECIES_NUZLEAF":299,"SPECIES_OCTILLERY":224,"SPECIES_ODDISH":43,"SPECIES_OLD_UNOWN_B":252,"SPECIES_OLD_UNOWN_C":253,"SPECIES_OLD_UNOWN_D":254,"SPECIES_OLD_UNOWN_E":255,"SPECIES_OLD_UNOWN_F":256,"SPECIES_OLD_UNOWN_G":257,"SPECIES_OLD_UNOWN_H":258,"SPECIES_OLD_UNOWN_I":259,"SPECIES_OLD_UNOWN_J":260,"SPECIES_OLD_UNOWN_K":261,"SPECIES_OLD_UNOWN_L":262,"SPECIES_OLD_UNOWN_M":263,"SPECIES_OLD_UNOWN_N":264,"SPECIES_OLD_UNOWN_O":265,"SPECIES_OLD_UNOWN_P":266,"SPECIES_OLD_UNOWN_Q":267,"SPECIES_OLD_UNOWN_R":268,"SPECIES_OLD_UNOWN_S":269,"SPECIES_OLD_UNOWN_T":270,"SPECIES_OLD_UNOWN_U":271,"SPECIES_OLD_UNOWN_V":272,"SPECIES_OLD_UNOWN_W":273,"SPECIES_OLD_UNOWN_X":274,"SPECIES_OLD_UNOWN_Y":275,"SPECIES_OLD_UNOWN_Z":276,"SPECIES_OMANYTE":138,"SPECIES_OMASTAR":139,"SPECIES_ONIX":95,"SPECIES_PARAS":46,"SPECIES_PARASECT":47,"SPECIES_PELIPPER":310,"SPECIES_PERSIAN":53,"SPECIES_PHANPY":231,"SPECIES_PICHU":172,"SPECIES_PIDGEOT":18,"SPECIES_PIDGEOTTO":17,"SPECIES_PIDGEY":16,"SPECIES_PIKACHU":25,"SPECIES_PILOSWINE":221,"SPECIES_PINECO":204,"SPECIES_PINSIR":127,"SPECIES_PLUSLE":353,"SPECIES_POLITOED":186,"SPECIES_POLIWAG":60,"SPECIES_POLIWHIRL":61,"SPECIES_POLIWRATH":62,"SPECIES_PONYTA":77,"SPECIES_POOCHYENA":286,"SPECIES_PORYGON":137,"SPECIES_PORYGON2":233,"SPECIES_PRIMEAPE":57,"SPECIES_PSYDUCK":54,"SPECIES_PUPITAR":247,"SPECIES_QUAGSIRE":195,"SPECIES_QUILAVA":156,"SPECIES_QWILFISH":211,"SPECIES_RAICHU":26,"SPECIES_RAIKOU":243,"SPECIES_RALTS":392,"SPECIES_RAPIDASH":78,"SPECIES_RATICATE":20,"SPECIES_RATTATA":19,"SPECIES_RAYQUAZA":406,"SPECIES_REGICE":402,"SPECIES_REGIROCK":401,"SPECIES_REGISTEEL":403,"SPECIES_RELICANTH":381,"SPECIES_REMORAID":223,"SPECIES_RHYDON":112,"SPECIES_RHYHORN":111,"SPECIES_ROSELIA":363,"SPECIES_SABLEYE":322,"SPECIES_SALAMENCE":397,"SPECIES_SANDSHREW":27,"SPECIES_SANDSLASH":28,"SPECIES_SCEPTILE":279,"SPECIES_SCIZOR":212,"SPECIES_SCYTHER":123,"SPECIES_SEADRA":117,"SPECIES_SEAKING":119,"SPECIES_SEALEO":342,"SPECIES_SEEDOT":298,"SPECIES_SEEL":86,"SPECIES_SENTRET":161,"SPECIES_SEVIPER":379,"SPECIES_SHARPEDO":331,"SPECIES_SHEDINJA":303,"SPECIES_SHELGON":396,"SPECIES_SHELLDER":90,"SPECIES_SHIFTRY":300,"SPECIES_SHROOMISH":306,"SPECIES_SHUCKLE":213,"SPECIES_SHUPPET":377,"SPECIES_SILCOON":291,"SPECIES_SKARMORY":227,"SPECIES_SKIPLOOM":188,"SPECIES_SKITTY":315,"SPECIES_SLAKING":366,"SPECIES_SLAKOTH":364,"SPECIES_SLOWBRO":80,"SPECIES_SLOWKING":199,"SPECIES_SLOWPOKE":79,"SPECIES_SLUGMA":218,"SPECIES_SMEARGLE":235,"SPECIES_SMOOCHUM":238,"SPECIES_SNEASEL":215,"SPECIES_SNORLAX":143,"SPECIES_SNORUNT":346,"SPECIES_SNUBBULL":209,"SPECIES_SOLROCK":349,"SPECIES_SPEAROW":21,"SPECIES_SPHEAL":341,"SPECIES_SPINARAK":167,"SPECIES_SPINDA":308,"SPECIES_SPOINK":351,"SPECIES_SQUIRTLE":7,"SPECIES_STANTLER":234,"SPECIES_STARMIE":121,"SPECIES_STARYU":120,"SPECIES_STEELIX":208,"SPECIES_SUDOWOODO":185,"SPECIES_SUICUNE":245,"SPECIES_SUNFLORA":192,"SPECIES_SUNKERN":191,"SPECIES_SURSKIT":311,"SPECIES_SWABLU":358,"SPECIES_SWALOT":368,"SPECIES_SWAMPERT":285,"SPECIES_SWELLOW":305,"SPECIES_SWINUB":220,"SPECIES_TAILLOW":304,"SPECIES_TANGELA":114,"SPECIES_TAUROS":128,"SPECIES_TEDDIURSA":216,"SPECIES_TENTACOOL":72,"SPECIES_TENTACRUEL":73,"SPECIES_TOGEPI":175,"SPECIES_TOGETIC":176,"SPECIES_TORCHIC":280,"SPECIES_TORKOAL":321,"SPECIES_TOTODILE":158,"SPECIES_TRAPINCH":332,"SPECIES_TREECKO":277,"SPECIES_TROPIUS":369,"SPECIES_TYPHLOSION":157,"SPECIES_TYRANITAR":248,"SPECIES_TYROGUE":236,"SPECIES_UMBREON":197,"SPECIES_UNOWN":201,"SPECIES_UNOWN_B":413,"SPECIES_UNOWN_C":414,"SPECIES_UNOWN_D":415,"SPECIES_UNOWN_E":416,"SPECIES_UNOWN_EMARK":438,"SPECIES_UNOWN_F":417,"SPECIES_UNOWN_G":418,"SPECIES_UNOWN_H":419,"SPECIES_UNOWN_I":420,"SPECIES_UNOWN_J":421,"SPECIES_UNOWN_K":422,"SPECIES_UNOWN_L":423,"SPECIES_UNOWN_M":424,"SPECIES_UNOWN_N":425,"SPECIES_UNOWN_O":426,"SPECIES_UNOWN_P":427,"SPECIES_UNOWN_Q":428,"SPECIES_UNOWN_QMARK":439,"SPECIES_UNOWN_R":429,"SPECIES_UNOWN_S":430,"SPECIES_UNOWN_T":431,"SPECIES_UNOWN_U":432,"SPECIES_UNOWN_V":433,"SPECIES_UNOWN_W":434,"SPECIES_UNOWN_X":435,"SPECIES_UNOWN_Y":436,"SPECIES_UNOWN_Z":437,"SPECIES_URSARING":217,"SPECIES_VAPOREON":134,"SPECIES_VENOMOTH":49,"SPECIES_VENONAT":48,"SPECIES_VENUSAUR":3,"SPECIES_VIBRAVA":333,"SPECIES_VICTREEBEL":71,"SPECIES_VIGOROTH":365,"SPECIES_VILEPLUME":45,"SPECIES_VOLBEAT":386,"SPECIES_VOLTORB":100,"SPECIES_VULPIX":37,"SPECIES_WAILMER":313,"SPECIES_WAILORD":314,"SPECIES_WALREIN":343,"SPECIES_WARTORTLE":8,"SPECIES_WEEDLE":13,"SPECIES_WEEPINBELL":70,"SPECIES_WEEZING":110,"SPECIES_WHISCASH":324,"SPECIES_WHISMUR":370,"SPECIES_WIGGLYTUFF":40,"SPECIES_WINGULL":309,"SPECIES_WOBBUFFET":202,"SPECIES_WOOPER":194,"SPECIES_WURMPLE":290,"SPECIES_WYNAUT":360,"SPECIES_XATU":178,"SPECIES_YANMA":193,"SPECIES_ZANGOOSE":380,"SPECIES_ZAPDOS":145,"SPECIES_ZIGZAGOON":288,"SPECIES_ZUBAT":41,"SUPER_ROD":2,"SYSTEM_FLAGS":2144,"TEMP_FLAGS_END":31,"TEMP_FLAGS_START":0,"TRAINERS_COUNT":855,"TRAINER_AARON":397,"TRAINER_ABIGAIL_1":358,"TRAINER_ABIGAIL_2":360,"TRAINER_ABIGAIL_3":361,"TRAINER_ABIGAIL_4":362,"TRAINER_ABIGAIL_5":363,"TRAINER_AIDAN":674,"TRAINER_AISHA":757,"TRAINER_ALAN":630,"TRAINER_ALBERT":80,"TRAINER_ALBERTO":12,"TRAINER_ALEX":413,"TRAINER_ALEXA":670,"TRAINER_ALEXIA":90,"TRAINER_ALEXIS":248,"TRAINER_ALICE":448,"TRAINER_ALIX":750,"TRAINER_ALLEN":333,"TRAINER_ALLISON":387,"TRAINER_ALVARO":849,"TRAINER_ALYSSA":701,"TRAINER_AMY_AND_LIV_1":481,"TRAINER_AMY_AND_LIV_2":482,"TRAINER_AMY_AND_LIV_3":485,"TRAINER_AMY_AND_LIV_4":487,"TRAINER_AMY_AND_LIV_5":488,"TRAINER_AMY_AND_LIV_6":489,"TRAINER_ANABEL":805,"TRAINER_ANDREA":613,"TRAINER_ANDRES_1":737,"TRAINER_ANDRES_2":812,"TRAINER_ANDRES_3":813,"TRAINER_ANDRES_4":814,"TRAINER_ANDRES_5":815,"TRAINER_ANDREW":336,"TRAINER_ANGELICA":436,"TRAINER_ANGELINA":712,"TRAINER_ANGELO":802,"TRAINER_ANNA_AND_MEG_1":287,"TRAINER_ANNA_AND_MEG_2":288,"TRAINER_ANNA_AND_MEG_3":289,"TRAINER_ANNA_AND_MEG_4":290,"TRAINER_ANNA_AND_MEG_5":291,"TRAINER_ANNIKA":502,"TRAINER_ANTHONY":352,"TRAINER_ARCHIE":34,"TRAINER_ASHLEY":655,"TRAINER_ATHENA":577,"TRAINER_ATSUSHI":190,"TRAINER_AURON":506,"TRAINER_AUSTINA":58,"TRAINER_AUTUMN":217,"TRAINER_AXLE":203,"TRAINER_BARNY":343,"TRAINER_BARRY":163,"TRAINER_BEAU":212,"TRAINER_BECK":414,"TRAINER_BECKY":470,"TRAINER_BEN":323,"TRAINER_BENJAMIN_1":353,"TRAINER_BENJAMIN_2":354,"TRAINER_BENJAMIN_3":355,"TRAINER_BENJAMIN_4":356,"TRAINER_BENJAMIN_5":357,"TRAINER_BENNY":407,"TRAINER_BERKE":74,"TRAINER_BERNIE_1":206,"TRAINER_BERNIE_2":207,"TRAINER_BERNIE_3":208,"TRAINER_BERNIE_4":209,"TRAINER_BERNIE_5":210,"TRAINER_BETH":445,"TRAINER_BETHANY":301,"TRAINER_BEVERLY":441,"TRAINER_BIANCA":706,"TRAINER_BILLY":319,"TRAINER_BLAKE":235,"TRAINER_BRANDEN":745,"TRAINER_BRANDI":756,"TRAINER_BRANDON":811,"TRAINER_BRAWLY_1":266,"TRAINER_BRAWLY_2":774,"TRAINER_BRAWLY_3":775,"TRAINER_BRAWLY_4":776,"TRAINER_BRAWLY_5":777,"TRAINER_BRAXTON":75,"TRAINER_BRENDA":454,"TRAINER_BRENDAN_LILYCOVE_MUDKIP":661,"TRAINER_BRENDAN_LILYCOVE_TORCHIC":663,"TRAINER_BRENDAN_LILYCOVE_TREECKO":662,"TRAINER_BRENDAN_PLACEHOLDER":853,"TRAINER_BRENDAN_ROUTE_103_MUDKIP":520,"TRAINER_BRENDAN_ROUTE_103_TORCHIC":526,"TRAINER_BRENDAN_ROUTE_103_TREECKO":523,"TRAINER_BRENDAN_ROUTE_110_MUDKIP":521,"TRAINER_BRENDAN_ROUTE_110_TORCHIC":527,"TRAINER_BRENDAN_ROUTE_110_TREECKO":524,"TRAINER_BRENDAN_ROUTE_119_MUDKIP":522,"TRAINER_BRENDAN_ROUTE_119_TORCHIC":528,"TRAINER_BRENDAN_ROUTE_119_TREECKO":525,"TRAINER_BRENDAN_RUSTBORO_MUDKIP":593,"TRAINER_BRENDAN_RUSTBORO_TORCHIC":599,"TRAINER_BRENDAN_RUSTBORO_TREECKO":592,"TRAINER_BRENDEN":572,"TRAINER_BRENT":223,"TRAINER_BRIANNA":118,"TRAINER_BRICE":626,"TRAINER_BRIDGET":129,"TRAINER_BROOKE_1":94,"TRAINER_BROOKE_2":101,"TRAINER_BROOKE_3":102,"TRAINER_BROOKE_4":103,"TRAINER_BROOKE_5":104,"TRAINER_BRYAN":744,"TRAINER_BRYANT":746,"TRAINER_CALE":764,"TRAINER_CALLIE":763,"TRAINER_CALVIN_1":318,"TRAINER_CALVIN_2":328,"TRAINER_CALVIN_3":329,"TRAINER_CALVIN_4":330,"TRAINER_CALVIN_5":331,"TRAINER_CAMDEN":374,"TRAINER_CAMERON_1":238,"TRAINER_CAMERON_2":239,"TRAINER_CAMERON_3":240,"TRAINER_CAMERON_4":241,"TRAINER_CAMERON_5":242,"TRAINER_CAMRON":739,"TRAINER_CARLEE":464,"TRAINER_CAROL":471,"TRAINER_CAROLINA":741,"TRAINER_CAROLINE":99,"TRAINER_CARTER":345,"TRAINER_CATHERINE_1":559,"TRAINER_CATHERINE_2":562,"TRAINER_CATHERINE_3":563,"TRAINER_CATHERINE_4":564,"TRAINER_CATHERINE_5":565,"TRAINER_CEDRIC":475,"TRAINER_CELIA":743,"TRAINER_CELINA":705,"TRAINER_CHAD":174,"TRAINER_CHANDLER":698,"TRAINER_CHARLIE":66,"TRAINER_CHARLOTTE":714,"TRAINER_CHASE":378,"TRAINER_CHESTER":408,"TRAINER_CHIP":45,"TRAINER_CHRIS":693,"TRAINER_CINDY_1":114,"TRAINER_CINDY_2":117,"TRAINER_CINDY_3":120,"TRAINER_CINDY_4":121,"TRAINER_CINDY_5":122,"TRAINER_CINDY_6":123,"TRAINER_CLARENCE":580,"TRAINER_CLARISSA":435,"TRAINER_CLARK":631,"TRAINER_CLAUDE":338,"TRAINER_CLIFFORD":584,"TRAINER_COBY":709,"TRAINER_COLE":201,"TRAINER_COLIN":405,"TRAINER_COLTON":294,"TRAINER_CONNIE":128,"TRAINER_CONOR":511,"TRAINER_CORA":428,"TRAINER_CORY_1":740,"TRAINER_CORY_2":816,"TRAINER_CORY_3":817,"TRAINER_CORY_4":818,"TRAINER_CORY_5":819,"TRAINER_CRISSY":614,"TRAINER_CRISTIAN":574,"TRAINER_CRISTIN_1":767,"TRAINER_CRISTIN_2":828,"TRAINER_CRISTIN_3":829,"TRAINER_CRISTIN_4":830,"TRAINER_CRISTIN_5":831,"TRAINER_CYNDY_1":427,"TRAINER_CYNDY_2":430,"TRAINER_CYNDY_3":431,"TRAINER_CYNDY_4":432,"TRAINER_CYNDY_5":433,"TRAINER_DAISUKE":189,"TRAINER_DAISY":36,"TRAINER_DALE":341,"TRAINER_DALTON_1":196,"TRAINER_DALTON_2":197,"TRAINER_DALTON_3":198,"TRAINER_DALTON_4":199,"TRAINER_DALTON_5":200,"TRAINER_DANA":458,"TRAINER_DANIELLE":650,"TRAINER_DAPHNE":115,"TRAINER_DARCY":733,"TRAINER_DARIAN":696,"TRAINER_DARIUS":803,"TRAINER_DARRIN":154,"TRAINER_DAVID":158,"TRAINER_DAVIS":539,"TRAINER_DAWSON":694,"TRAINER_DAYTON":760,"TRAINER_DEAN":164,"TRAINER_DEANDRE":715,"TRAINER_DEBRA":460,"TRAINER_DECLAN":15,"TRAINER_DEMETRIUS":375,"TRAINER_DENISE":444,"TRAINER_DEREK":227,"TRAINER_DEVAN":753,"TRAINER_DEZ_AND_LUKE":640,"TRAINER_DIANA_1":474,"TRAINER_DIANA_2":477,"TRAINER_DIANA_3":478,"TRAINER_DIANA_4":479,"TRAINER_DIANA_5":480,"TRAINER_DIANNE":417,"TRAINER_DILLON":327,"TRAINER_DOMINIK":152,"TRAINER_DONALD":224,"TRAINER_DONNY":384,"TRAINER_DOUG":618,"TRAINER_DOUGLAS":153,"TRAINER_DRAKE":264,"TRAINER_DREW":211,"TRAINER_DUDLEY":173,"TRAINER_DUNCAN":496,"TRAINER_DUSTY_1":44,"TRAINER_DUSTY_2":47,"TRAINER_DUSTY_3":48,"TRAINER_DUSTY_4":49,"TRAINER_DUSTY_5":50,"TRAINER_DWAYNE":493,"TRAINER_DYLAN_1":364,"TRAINER_DYLAN_2":365,"TRAINER_DYLAN_3":366,"TRAINER_DYLAN_4":367,"TRAINER_DYLAN_5":368,"TRAINER_ED":13,"TRAINER_EDDIE":332,"TRAINER_EDGAR":79,"TRAINER_EDMOND":491,"TRAINER_EDWARD":232,"TRAINER_EDWARDO":404,"TRAINER_EDWIN_1":512,"TRAINER_EDWIN_2":515,"TRAINER_EDWIN_3":516,"TRAINER_EDWIN_4":517,"TRAINER_EDWIN_5":518,"TRAINER_ELI":501,"TRAINER_ELIJAH":742,"TRAINER_ELLIOT_1":339,"TRAINER_ELLIOT_2":346,"TRAINER_ELLIOT_3":347,"TRAINER_ELLIOT_4":348,"TRAINER_ELLIOT_5":349,"TRAINER_ERIC":632,"TRAINER_ERNEST_1":492,"TRAINER_ERNEST_2":497,"TRAINER_ERNEST_3":498,"TRAINER_ERNEST_4":499,"TRAINER_ERNEST_5":500,"TRAINER_ETHAN_1":216,"TRAINER_ETHAN_2":219,"TRAINER_ETHAN_3":220,"TRAINER_ETHAN_4":221,"TRAINER_ETHAN_5":222,"TRAINER_EVERETT":850,"TRAINER_FABIAN":759,"TRAINER_FELIX":38,"TRAINER_FERNANDO_1":195,"TRAINER_FERNANDO_2":832,"TRAINER_FERNANDO_3":833,"TRAINER_FERNANDO_4":834,"TRAINER_FERNANDO_5":835,"TRAINER_FLAGS_END":2143,"TRAINER_FLAGS_START":1280,"TRAINER_FLANNERY_1":268,"TRAINER_FLANNERY_2":782,"TRAINER_FLANNERY_3":783,"TRAINER_FLANNERY_4":784,"TRAINER_FLANNERY_5":785,"TRAINER_FLINT":654,"TRAINER_FOSTER":46,"TRAINER_FRANKLIN":170,"TRAINER_FREDRICK":29,"TRAINER_GABBY_AND_TY_1":51,"TRAINER_GABBY_AND_TY_2":52,"TRAINER_GABBY_AND_TY_3":53,"TRAINER_GABBY_AND_TY_4":54,"TRAINER_GABBY_AND_TY_5":55,"TRAINER_GABBY_AND_TY_6":56,"TRAINER_GABRIELLE_1":9,"TRAINER_GABRIELLE_2":840,"TRAINER_GABRIELLE_3":841,"TRAINER_GABRIELLE_4":842,"TRAINER_GABRIELLE_5":843,"TRAINER_GARRET":138,"TRAINER_GARRISON":547,"TRAINER_GEORGE":73,"TRAINER_GEORGIA":281,"TRAINER_GERALD":648,"TRAINER_GILBERT":169,"TRAINER_GINA_AND_MIA_1":483,"TRAINER_GINA_AND_MIA_2":486,"TRAINER_GLACIA":263,"TRAINER_GRACE":450,"TRAINER_GREG":619,"TRAINER_GRETA":808,"TRAINER_GRUNT_AQUA_HIDEOUT_1":2,"TRAINER_GRUNT_AQUA_HIDEOUT_2":3,"TRAINER_GRUNT_AQUA_HIDEOUT_3":4,"TRAINER_GRUNT_AQUA_HIDEOUT_4":5,"TRAINER_GRUNT_AQUA_HIDEOUT_5":27,"TRAINER_GRUNT_AQUA_HIDEOUT_6":28,"TRAINER_GRUNT_AQUA_HIDEOUT_7":192,"TRAINER_GRUNT_AQUA_HIDEOUT_8":193,"TRAINER_GRUNT_JAGGED_PASS":570,"TRAINER_GRUNT_MAGMA_HIDEOUT_1":716,"TRAINER_GRUNT_MAGMA_HIDEOUT_10":725,"TRAINER_GRUNT_MAGMA_HIDEOUT_11":726,"TRAINER_GRUNT_MAGMA_HIDEOUT_12":727,"TRAINER_GRUNT_MAGMA_HIDEOUT_13":728,"TRAINER_GRUNT_MAGMA_HIDEOUT_14":729,"TRAINER_GRUNT_MAGMA_HIDEOUT_15":730,"TRAINER_GRUNT_MAGMA_HIDEOUT_16":731,"TRAINER_GRUNT_MAGMA_HIDEOUT_2":717,"TRAINER_GRUNT_MAGMA_HIDEOUT_3":718,"TRAINER_GRUNT_MAGMA_HIDEOUT_4":719,"TRAINER_GRUNT_MAGMA_HIDEOUT_5":720,"TRAINER_GRUNT_MAGMA_HIDEOUT_6":721,"TRAINER_GRUNT_MAGMA_HIDEOUT_7":722,"TRAINER_GRUNT_MAGMA_HIDEOUT_8":723,"TRAINER_GRUNT_MAGMA_HIDEOUT_9":724,"TRAINER_GRUNT_MT_CHIMNEY_1":146,"TRAINER_GRUNT_MT_CHIMNEY_2":579,"TRAINER_GRUNT_MT_PYRE_1":23,"TRAINER_GRUNT_MT_PYRE_2":24,"TRAINER_GRUNT_MT_PYRE_3":25,"TRAINER_GRUNT_MT_PYRE_4":569,"TRAINER_GRUNT_MUSEUM_1":20,"TRAINER_GRUNT_MUSEUM_2":21,"TRAINER_GRUNT_PETALBURG_WOODS":10,"TRAINER_GRUNT_RUSTURF_TUNNEL":16,"TRAINER_GRUNT_SEAFLOOR_CAVERN_1":6,"TRAINER_GRUNT_SEAFLOOR_CAVERN_2":7,"TRAINER_GRUNT_SEAFLOOR_CAVERN_3":8,"TRAINER_GRUNT_SEAFLOOR_CAVERN_4":14,"TRAINER_GRUNT_SEAFLOOR_CAVERN_5":567,"TRAINER_GRUNT_SPACE_CENTER_1":22,"TRAINER_GRUNT_SPACE_CENTER_2":116,"TRAINER_GRUNT_SPACE_CENTER_3":586,"TRAINER_GRUNT_SPACE_CENTER_4":587,"TRAINER_GRUNT_SPACE_CENTER_5":588,"TRAINER_GRUNT_SPACE_CENTER_6":589,"TRAINER_GRUNT_SPACE_CENTER_7":590,"TRAINER_GRUNT_UNUSED":568,"TRAINER_GRUNT_WEATHER_INST_1":17,"TRAINER_GRUNT_WEATHER_INST_2":18,"TRAINER_GRUNT_WEATHER_INST_3":19,"TRAINER_GRUNT_WEATHER_INST_4":26,"TRAINER_GRUNT_WEATHER_INST_5":596,"TRAINER_GWEN":59,"TRAINER_HAILEY":697,"TRAINER_HALEY_1":604,"TRAINER_HALEY_2":607,"TRAINER_HALEY_3":608,"TRAINER_HALEY_4":609,"TRAINER_HALEY_5":610,"TRAINER_HALLE":546,"TRAINER_HANNAH":244,"TRAINER_HARRISON":578,"TRAINER_HAYDEN":707,"TRAINER_HECTOR":513,"TRAINER_HEIDI":469,"TRAINER_HELENE":751,"TRAINER_HENRY":668,"TRAINER_HERMAN":167,"TRAINER_HIDEO":651,"TRAINER_HITOSHI":180,"TRAINER_HOPE":96,"TRAINER_HUDSON":510,"TRAINER_HUEY":490,"TRAINER_HUGH":399,"TRAINER_HUMBERTO":402,"TRAINER_IMANI":442,"TRAINER_IRENE":476,"TRAINER_ISAAC_1":538,"TRAINER_ISAAC_2":541,"TRAINER_ISAAC_3":542,"TRAINER_ISAAC_4":543,"TRAINER_ISAAC_5":544,"TRAINER_ISABELLA":595,"TRAINER_ISABELLE":736,"TRAINER_ISABEL_1":302,"TRAINER_ISABEL_2":303,"TRAINER_ISABEL_3":304,"TRAINER_ISABEL_4":305,"TRAINER_ISABEL_5":306,"TRAINER_ISAIAH_1":376,"TRAINER_ISAIAH_2":379,"TRAINER_ISAIAH_3":380,"TRAINER_ISAIAH_4":381,"TRAINER_ISAIAH_5":382,"TRAINER_ISOBEL":383,"TRAINER_IVAN":337,"TRAINER_JACE":204,"TRAINER_JACK":172,"TRAINER_JACKI_1":249,"TRAINER_JACKI_2":250,"TRAINER_JACKI_3":251,"TRAINER_JACKI_4":252,"TRAINER_JACKI_5":253,"TRAINER_JACKSON_1":552,"TRAINER_JACKSON_2":555,"TRAINER_JACKSON_3":556,"TRAINER_JACKSON_4":557,"TRAINER_JACKSON_5":558,"TRAINER_JACLYN":243,"TRAINER_JACOB":351,"TRAINER_JAIDEN":749,"TRAINER_JAMES_1":621,"TRAINER_JAMES_2":622,"TRAINER_JAMES_3":623,"TRAINER_JAMES_4":624,"TRAINER_JAMES_5":625,"TRAINER_JANI":418,"TRAINER_JANICE":605,"TRAINER_JARED":401,"TRAINER_JASMINE":359,"TRAINER_JAYLEN":326,"TRAINER_JAZMYN":503,"TRAINER_JEFF":202,"TRAINER_JEFFREY_1":226,"TRAINER_JEFFREY_2":228,"TRAINER_JEFFREY_3":229,"TRAINER_JEFFREY_4":230,"TRAINER_JEFFREY_5":231,"TRAINER_JENNA":560,"TRAINER_JENNIFER":95,"TRAINER_JENNY_1":449,"TRAINER_JENNY_2":465,"TRAINER_JENNY_3":466,"TRAINER_JENNY_4":467,"TRAINER_JENNY_5":468,"TRAINER_JEROME":156,"TRAINER_JERRY_1":273,"TRAINER_JERRY_2":276,"TRAINER_JERRY_3":277,"TRAINER_JERRY_4":278,"TRAINER_JERRY_5":279,"TRAINER_JESSICA_1":127,"TRAINER_JESSICA_2":132,"TRAINER_JESSICA_3":133,"TRAINER_JESSICA_4":134,"TRAINER_JESSICA_5":135,"TRAINER_JOCELYN":425,"TRAINER_JODY":91,"TRAINER_JOEY":322,"TRAINER_JOHANNA":647,"TRAINER_JOHNSON":754,"TRAINER_JOHN_AND_JAY_1":681,"TRAINER_JOHN_AND_JAY_2":682,"TRAINER_JOHN_AND_JAY_3":683,"TRAINER_JOHN_AND_JAY_4":684,"TRAINER_JOHN_AND_JAY_5":685,"TRAINER_JONAH":667,"TRAINER_JONAS":504,"TRAINER_JONATHAN":598,"TRAINER_JOSE":617,"TRAINER_JOSEPH":700,"TRAINER_JOSH":320,"TRAINER_JOSHUA":237,"TRAINER_JOSUE":738,"TRAINER_JUAN_1":272,"TRAINER_JUAN_2":798,"TRAINER_JUAN_3":799,"TRAINER_JUAN_4":800,"TRAINER_JUAN_5":801,"TRAINER_JULIE":100,"TRAINER_JULIO":566,"TRAINER_JUSTIN":215,"TRAINER_KAI":713,"TRAINER_KALEB":699,"TRAINER_KARA":457,"TRAINER_KAREN_1":280,"TRAINER_KAREN_2":282,"TRAINER_KAREN_3":283,"TRAINER_KAREN_4":284,"TRAINER_KAREN_5":285,"TRAINER_KATELYNN":325,"TRAINER_KATELYN_1":386,"TRAINER_KATELYN_2":388,"TRAINER_KATELYN_3":389,"TRAINER_KATELYN_4":390,"TRAINER_KATELYN_5":391,"TRAINER_KATE_AND_JOY":286,"TRAINER_KATHLEEN":583,"TRAINER_KATIE":455,"TRAINER_KAYLA":247,"TRAINER_KAYLEE":462,"TRAINER_KAYLEY":505,"TRAINER_KEEGAN":205,"TRAINER_KEIGO":652,"TRAINER_KEIRA":93,"TRAINER_KELVIN":507,"TRAINER_KENT":620,"TRAINER_KEVIN":171,"TRAINER_KIM_AND_IRIS":678,"TRAINER_KINDRA":106,"TRAINER_KIRA_AND_DAN_1":642,"TRAINER_KIRA_AND_DAN_2":643,"TRAINER_KIRA_AND_DAN_3":644,"TRAINER_KIRA_AND_DAN_4":645,"TRAINER_KIRA_AND_DAN_5":646,"TRAINER_KIRK":191,"TRAINER_KIYO":181,"TRAINER_KOICHI":182,"TRAINER_KOJI_1":672,"TRAINER_KOJI_2":824,"TRAINER_KOJI_3":825,"TRAINER_KOJI_4":826,"TRAINER_KOJI_5":827,"TRAINER_KYLA":443,"TRAINER_KYRA":748,"TRAINER_LAO_1":419,"TRAINER_LAO_2":421,"TRAINER_LAO_3":422,"TRAINER_LAO_4":423,"TRAINER_LAO_5":424,"TRAINER_LARRY":213,"TRAINER_LAURA":426,"TRAINER_LAUREL":463,"TRAINER_LAWRENCE":710,"TRAINER_LEAF":852,"TRAINER_LEAH":35,"TRAINER_LEA_AND_JED":641,"TRAINER_LENNY":628,"TRAINER_LEONARD":495,"TRAINER_LEONARDO":576,"TRAINER_LEONEL":762,"TRAINER_LEROY":77,"TRAINER_LILA_AND_ROY_1":687,"TRAINER_LILA_AND_ROY_2":688,"TRAINER_LILA_AND_ROY_3":689,"TRAINER_LILA_AND_ROY_4":690,"TRAINER_LILA_AND_ROY_5":691,"TRAINER_LILITH":573,"TRAINER_LINDA":461,"TRAINER_LISA_AND_RAY":692,"TRAINER_LOLA_1":57,"TRAINER_LOLA_2":60,"TRAINER_LOLA_3":61,"TRAINER_LOLA_4":62,"TRAINER_LOLA_5":63,"TRAINER_LORENZO":553,"TRAINER_LUCAS_1":629,"TRAINER_LUCAS_2":633,"TRAINER_LUCY":810,"TRAINER_LUIS":151,"TRAINER_LUNG":420,"TRAINER_LYDIA_1":545,"TRAINER_LYDIA_2":548,"TRAINER_LYDIA_3":549,"TRAINER_LYDIA_4":550,"TRAINER_LYDIA_5":551,"TRAINER_LYLE":616,"TRAINER_MACEY":591,"TRAINER_MADELINE_1":434,"TRAINER_MADELINE_2":437,"TRAINER_MADELINE_3":438,"TRAINER_MADELINE_4":439,"TRAINER_MADELINE_5":440,"TRAINER_MAKAYLA":758,"TRAINER_MARC":571,"TRAINER_MARCEL":11,"TRAINER_MARCOS":702,"TRAINER_MARIA_1":369,"TRAINER_MARIA_2":370,"TRAINER_MARIA_3":371,"TRAINER_MARIA_4":372,"TRAINER_MARIA_5":373,"TRAINER_MARIELA":848,"TRAINER_MARK":145,"TRAINER_MARLENE":752,"TRAINER_MARLEY":508,"TRAINER_MARTHA":473,"TRAINER_MARY":89,"TRAINER_MATT":30,"TRAINER_MATTHEW":157,"TRAINER_MAURA":246,"TRAINER_MAXIE_MAGMA_HIDEOUT":601,"TRAINER_MAXIE_MOSSDEEP":734,"TRAINER_MAXIE_MT_CHIMNEY":602,"TRAINER_MAY_LILYCOVE_MUDKIP":664,"TRAINER_MAY_LILYCOVE_TORCHIC":666,"TRAINER_MAY_LILYCOVE_TREECKO":665,"TRAINER_MAY_PLACEHOLDER":854,"TRAINER_MAY_ROUTE_103_MUDKIP":529,"TRAINER_MAY_ROUTE_103_TORCHIC":535,"TRAINER_MAY_ROUTE_103_TREECKO":532,"TRAINER_MAY_ROUTE_110_MUDKIP":530,"TRAINER_MAY_ROUTE_110_TORCHIC":536,"TRAINER_MAY_ROUTE_110_TREECKO":533,"TRAINER_MAY_ROUTE_119_MUDKIP":531,"TRAINER_MAY_ROUTE_119_TORCHIC":537,"TRAINER_MAY_ROUTE_119_TREECKO":534,"TRAINER_MAY_RUSTBORO_MUDKIP":600,"TRAINER_MAY_RUSTBORO_TORCHIC":769,"TRAINER_MAY_RUSTBORO_TREECKO":768,"TRAINER_MELINA":755,"TRAINER_MELISSA":124,"TRAINER_MEL_AND_PAUL":680,"TRAINER_MICAH":255,"TRAINER_MICHELLE":98,"TRAINER_MIGUEL_1":293,"TRAINER_MIGUEL_2":295,"TRAINER_MIGUEL_3":296,"TRAINER_MIGUEL_4":297,"TRAINER_MIGUEL_5":298,"TRAINER_MIKE_1":634,"TRAINER_MIKE_2":635,"TRAINER_MISSY":447,"TRAINER_MITCHELL":540,"TRAINER_MIU_AND_YUKI":484,"TRAINER_MOLLIE":137,"TRAINER_MYLES":765,"TRAINER_NANCY":472,"TRAINER_NAOMI":119,"TRAINER_NATE":582,"TRAINER_NED":340,"TRAINER_NICHOLAS":585,"TRAINER_NICOLAS_1":392,"TRAINER_NICOLAS_2":393,"TRAINER_NICOLAS_3":394,"TRAINER_NICOLAS_4":395,"TRAINER_NICOLAS_5":396,"TRAINER_NIKKI":453,"TRAINER_NOB_1":183,"TRAINER_NOB_2":184,"TRAINER_NOB_3":185,"TRAINER_NOB_4":186,"TRAINER_NOB_5":187,"TRAINER_NOLAN":342,"TRAINER_NOLAND":809,"TRAINER_NOLEN":161,"TRAINER_NONE":0,"TRAINER_NORMAN_1":269,"TRAINER_NORMAN_2":786,"TRAINER_NORMAN_3":787,"TRAINER_NORMAN_4":788,"TRAINER_NORMAN_5":789,"TRAINER_OLIVIA":130,"TRAINER_OWEN":83,"TRAINER_PABLO_1":377,"TRAINER_PABLO_2":820,"TRAINER_PABLO_3":821,"TRAINER_PABLO_4":822,"TRAINER_PABLO_5":823,"TRAINER_PARKER":72,"TRAINER_PAT":766,"TRAINER_PATRICIA":105,"TRAINER_PAUL":275,"TRAINER_PAULA":429,"TRAINER_PAXTON":594,"TRAINER_PERRY":398,"TRAINER_PETE":735,"TRAINER_PHIL":400,"TRAINER_PHILLIP":494,"TRAINER_PHOEBE":262,"TRAINER_PRESLEY":403,"TRAINER_PRESTON":233,"TRAINER_QUINCY":324,"TRAINER_RACHEL":761,"TRAINER_RANDALL":71,"TRAINER_RED":851,"TRAINER_REED":675,"TRAINER_RELI_AND_IAN":686,"TRAINER_REYNA":509,"TRAINER_RHETT":703,"TRAINER_RICHARD":166,"TRAINER_RICK":615,"TRAINER_RICKY_1":64,"TRAINER_RICKY_2":67,"TRAINER_RICKY_3":68,"TRAINER_RICKY_4":69,"TRAINER_RICKY_5":70,"TRAINER_RILEY":653,"TRAINER_ROBERT_1":406,"TRAINER_ROBERT_2":409,"TRAINER_ROBERT_3":410,"TRAINER_ROBERT_4":411,"TRAINER_ROBERT_5":412,"TRAINER_ROBIN":612,"TRAINER_RODNEY":165,"TRAINER_ROGER":669,"TRAINER_ROLAND":160,"TRAINER_RONALD":350,"TRAINER_ROSE_1":37,"TRAINER_ROSE_2":40,"TRAINER_ROSE_3":41,"TRAINER_ROSE_4":42,"TRAINER_ROSE_5":43,"TRAINER_ROXANNE_1":265,"TRAINER_ROXANNE_2":770,"TRAINER_ROXANNE_3":771,"TRAINER_ROXANNE_4":772,"TRAINER_ROXANNE_5":773,"TRAINER_RUBEN":671,"TRAINER_SALLY":611,"TRAINER_SAMANTHA":245,"TRAINER_SAMUEL":81,"TRAINER_SANTIAGO":168,"TRAINER_SARAH":695,"TRAINER_SAWYER_1":1,"TRAINER_SAWYER_2":836,"TRAINER_SAWYER_3":837,"TRAINER_SAWYER_4":838,"TRAINER_SAWYER_5":839,"TRAINER_SEBASTIAN":554,"TRAINER_SHANE":214,"TRAINER_SHANNON":97,"TRAINER_SHARON":452,"TRAINER_SHAWN":194,"TRAINER_SHAYLA":747,"TRAINER_SHEILA":125,"TRAINER_SHELBY_1":313,"TRAINER_SHELBY_2":314,"TRAINER_SHELBY_3":315,"TRAINER_SHELBY_4":316,"TRAINER_SHELBY_5":317,"TRAINER_SHELLY_SEAFLOOR_CAVERN":33,"TRAINER_SHELLY_WEATHER_INSTITUTE":32,"TRAINER_SHIRLEY":126,"TRAINER_SIDNEY":261,"TRAINER_SIENNA":459,"TRAINER_SIMON":65,"TRAINER_SOPHIA":561,"TRAINER_SOPHIE":708,"TRAINER_SPENCER":159,"TRAINER_SPENSER":807,"TRAINER_STAN":162,"TRAINER_STEVEN":804,"TRAINER_STEVE_1":143,"TRAINER_STEVE_2":147,"TRAINER_STEVE_3":148,"TRAINER_STEVE_4":149,"TRAINER_STEVE_5":150,"TRAINER_SUSIE":456,"TRAINER_SYLVIA":575,"TRAINER_TABITHA_MAGMA_HIDEOUT":732,"TRAINER_TABITHA_MOSSDEEP":514,"TRAINER_TABITHA_MT_CHIMNEY":597,"TRAINER_TAKAO":179,"TRAINER_TAKASHI":416,"TRAINER_TALIA":385,"TRAINER_TAMMY":107,"TRAINER_TANYA":451,"TRAINER_TARA":446,"TRAINER_TASHA":109,"TRAINER_TATE_AND_LIZA_1":271,"TRAINER_TATE_AND_LIZA_2":794,"TRAINER_TATE_AND_LIZA_3":795,"TRAINER_TATE_AND_LIZA_4":796,"TRAINER_TATE_AND_LIZA_5":797,"TRAINER_TAYLOR":225,"TRAINER_TED":274,"TRAINER_TERRY":581,"TRAINER_THALIA_1":144,"TRAINER_THALIA_2":844,"TRAINER_THALIA_3":845,"TRAINER_THALIA_4":846,"TRAINER_THALIA_5":847,"TRAINER_THOMAS":256,"TRAINER_TIANA":603,"TRAINER_TIFFANY":131,"TRAINER_TIMMY":334,"TRAINER_TIMOTHY_1":307,"TRAINER_TIMOTHY_2":308,"TRAINER_TIMOTHY_3":309,"TRAINER_TIMOTHY_4":310,"TRAINER_TIMOTHY_5":311,"TRAINER_TISHA":676,"TRAINER_TOMMY":321,"TRAINER_TONY_1":155,"TRAINER_TONY_2":175,"TRAINER_TONY_3":176,"TRAINER_TONY_4":177,"TRAINER_TONY_5":178,"TRAINER_TORI_AND_TIA":677,"TRAINER_TRAVIS":218,"TRAINER_TRENT_1":627,"TRAINER_TRENT_2":636,"TRAINER_TRENT_3":637,"TRAINER_TRENT_4":638,"TRAINER_TRENT_5":639,"TRAINER_TUCKER":806,"TRAINER_TYRA_AND_IVY":679,"TRAINER_TYRON":704,"TRAINER_VALERIE_1":108,"TRAINER_VALERIE_2":110,"TRAINER_VALERIE_3":111,"TRAINER_VALERIE_4":112,"TRAINER_VALERIE_5":113,"TRAINER_VANESSA":300,"TRAINER_VICKY":312,"TRAINER_VICTOR":292,"TRAINER_VICTORIA":299,"TRAINER_VINCENT":76,"TRAINER_VIOLET":39,"TRAINER_VIRGIL":234,"TRAINER_VITO":82,"TRAINER_VIVI":606,"TRAINER_VIVIAN":649,"TRAINER_WADE":344,"TRAINER_WALLACE":335,"TRAINER_WALLY_MAUVILLE":656,"TRAINER_WALLY_VR_1":519,"TRAINER_WALLY_VR_2":657,"TRAINER_WALLY_VR_3":658,"TRAINER_WALLY_VR_4":659,"TRAINER_WALLY_VR_5":660,"TRAINER_WALTER_1":254,"TRAINER_WALTER_2":257,"TRAINER_WALTER_3":258,"TRAINER_WALTER_4":259,"TRAINER_WALTER_5":260,"TRAINER_WARREN":88,"TRAINER_WATTSON_1":267,"TRAINER_WATTSON_2":778,"TRAINER_WATTSON_3":779,"TRAINER_WATTSON_4":780,"TRAINER_WATTSON_5":781,"TRAINER_WAYNE":673,"TRAINER_WENDY":92,"TRAINER_WILLIAM":236,"TRAINER_WILTON_1":78,"TRAINER_WILTON_2":84,"TRAINER_WILTON_3":85,"TRAINER_WILTON_4":86,"TRAINER_WILTON_5":87,"TRAINER_WINONA_1":270,"TRAINER_WINONA_2":790,"TRAINER_WINONA_3":791,"TRAINER_WINONA_4":792,"TRAINER_WINONA_5":793,"TRAINER_WINSTON_1":136,"TRAINER_WINSTON_2":139,"TRAINER_WINSTON_3":140,"TRAINER_WINSTON_4":141,"TRAINER_WINSTON_5":142,"TRAINER_WYATT":711,"TRAINER_YASU":415,"TRAINER_YUJI":188,"TRAINER_ZANDER":31},"legendary_encounters":[{"address":2538600,"catch_flag":429,"defeat_flag":428,"level":30,"species":410},{"address":2354334,"catch_flag":480,"defeat_flag":447,"level":70,"species":405},{"address":2543160,"catch_flag":146,"defeat_flag":476,"level":70,"species":250},{"address":2354112,"catch_flag":479,"defeat_flag":446,"level":70,"species":404},{"address":2385623,"catch_flag":457,"defeat_flag":456,"level":50,"species":407},{"address":2385687,"catch_flag":482,"defeat_flag":481,"level":50,"species":408},{"address":2543443,"catch_flag":145,"defeat_flag":477,"level":70,"species":249},{"address":2538177,"catch_flag":458,"defeat_flag":455,"level":30,"species":151},{"address":2347488,"catch_flag":478,"defeat_flag":448,"level":70,"species":406},{"address":2345460,"catch_flag":427,"defeat_flag":444,"level":40,"species":402},{"address":2298183,"catch_flag":426,"defeat_flag":443,"level":40,"species":401},{"address":2345731,"catch_flag":483,"defeat_flag":445,"level":40,"species":403}],"locations":{"BADGE_1":{"address":2188036,"default_item":226,"flag":1182},"BADGE_2":{"address":2095131,"default_item":227,"flag":1183},"BADGE_3":{"address":2167252,"default_item":228,"flag":1184},"BADGE_4":{"address":2103246,"default_item":229,"flag":1185},"BADGE_5":{"address":2129781,"default_item":230,"flag":1186},"BADGE_6":{"address":2202122,"default_item":231,"flag":1187},"BADGE_7":{"address":2243964,"default_item":232,"flag":1188},"BADGE_8":{"address":2262314,"default_item":233,"flag":1189},"BERRY_TREE_01":{"address":5843562,"default_item":135,"flag":612},"BERRY_TREE_02":{"address":5843564,"default_item":139,"flag":613},"BERRY_TREE_03":{"address":5843566,"default_item":142,"flag":614},"BERRY_TREE_04":{"address":5843568,"default_item":139,"flag":615},"BERRY_TREE_05":{"address":5843570,"default_item":133,"flag":616},"BERRY_TREE_06":{"address":5843572,"default_item":138,"flag":617},"BERRY_TREE_07":{"address":5843574,"default_item":133,"flag":618},"BERRY_TREE_08":{"address":5843576,"default_item":133,"flag":619},"BERRY_TREE_09":{"address":5843578,"default_item":142,"flag":620},"BERRY_TREE_10":{"address":5843580,"default_item":138,"flag":621},"BERRY_TREE_11":{"address":5843582,"default_item":139,"flag":622},"BERRY_TREE_12":{"address":5843584,"default_item":142,"flag":623},"BERRY_TREE_13":{"address":5843586,"default_item":135,"flag":624},"BERRY_TREE_14":{"address":5843588,"default_item":155,"flag":625},"BERRY_TREE_15":{"address":5843590,"default_item":153,"flag":626},"BERRY_TREE_16":{"address":5843592,"default_item":150,"flag":627},"BERRY_TREE_17":{"address":5843594,"default_item":150,"flag":628},"BERRY_TREE_18":{"address":5843596,"default_item":150,"flag":629},"BERRY_TREE_19":{"address":5843598,"default_item":148,"flag":630},"BERRY_TREE_20":{"address":5843600,"default_item":148,"flag":631},"BERRY_TREE_21":{"address":5843602,"default_item":136,"flag":632},"BERRY_TREE_22":{"address":5843604,"default_item":135,"flag":633},"BERRY_TREE_23":{"address":5843606,"default_item":135,"flag":634},"BERRY_TREE_24":{"address":5843608,"default_item":136,"flag":635},"BERRY_TREE_25":{"address":5843610,"default_item":152,"flag":636},"BERRY_TREE_26":{"address":5843612,"default_item":134,"flag":637},"BERRY_TREE_27":{"address":5843614,"default_item":151,"flag":638},"BERRY_TREE_28":{"address":5843616,"default_item":151,"flag":639},"BERRY_TREE_29":{"address":5843618,"default_item":151,"flag":640},"BERRY_TREE_30":{"address":5843620,"default_item":153,"flag":641},"BERRY_TREE_31":{"address":5843622,"default_item":142,"flag":642},"BERRY_TREE_32":{"address":5843624,"default_item":142,"flag":643},"BERRY_TREE_33":{"address":5843626,"default_item":142,"flag":644},"BERRY_TREE_34":{"address":5843628,"default_item":153,"flag":645},"BERRY_TREE_35":{"address":5843630,"default_item":153,"flag":646},"BERRY_TREE_36":{"address":5843632,"default_item":153,"flag":647},"BERRY_TREE_37":{"address":5843634,"default_item":137,"flag":648},"BERRY_TREE_38":{"address":5843636,"default_item":137,"flag":649},"BERRY_TREE_39":{"address":5843638,"default_item":137,"flag":650},"BERRY_TREE_40":{"address":5843640,"default_item":135,"flag":651},"BERRY_TREE_41":{"address":5843642,"default_item":135,"flag":652},"BERRY_TREE_42":{"address":5843644,"default_item":135,"flag":653},"BERRY_TREE_43":{"address":5843646,"default_item":148,"flag":654},"BERRY_TREE_44":{"address":5843648,"default_item":150,"flag":655},"BERRY_TREE_45":{"address":5843650,"default_item":152,"flag":656},"BERRY_TREE_46":{"address":5843652,"default_item":151,"flag":657},"BERRY_TREE_47":{"address":5843654,"default_item":140,"flag":658},"BERRY_TREE_48":{"address":5843656,"default_item":137,"flag":659},"BERRY_TREE_49":{"address":5843658,"default_item":136,"flag":660},"BERRY_TREE_50":{"address":5843660,"default_item":134,"flag":661},"BERRY_TREE_51":{"address":5843662,"default_item":142,"flag":662},"BERRY_TREE_52":{"address":5843664,"default_item":150,"flag":663},"BERRY_TREE_53":{"address":5843666,"default_item":150,"flag":664},"BERRY_TREE_54":{"address":5843668,"default_item":142,"flag":665},"BERRY_TREE_55":{"address":5843670,"default_item":149,"flag":666},"BERRY_TREE_56":{"address":5843672,"default_item":149,"flag":667},"BERRY_TREE_57":{"address":5843674,"default_item":136,"flag":668},"BERRY_TREE_58":{"address":5843676,"default_item":153,"flag":669},"BERRY_TREE_59":{"address":5843678,"default_item":153,"flag":670},"BERRY_TREE_60":{"address":5843680,"default_item":157,"flag":671},"BERRY_TREE_61":{"address":5843682,"default_item":157,"flag":672},"BERRY_TREE_62":{"address":5843684,"default_item":138,"flag":673},"BERRY_TREE_63":{"address":5843686,"default_item":142,"flag":674},"BERRY_TREE_64":{"address":5843688,"default_item":138,"flag":675},"BERRY_TREE_65":{"address":5843690,"default_item":157,"flag":676},"BERRY_TREE_66":{"address":5843692,"default_item":134,"flag":677},"BERRY_TREE_67":{"address":5843694,"default_item":152,"flag":678},"BERRY_TREE_68":{"address":5843696,"default_item":140,"flag":679},"BERRY_TREE_69":{"address":5843698,"default_item":154,"flag":680},"BERRY_TREE_70":{"address":5843700,"default_item":154,"flag":681},"BERRY_TREE_71":{"address":5843702,"default_item":154,"flag":682},"BERRY_TREE_72":{"address":5843704,"default_item":157,"flag":683},"BERRY_TREE_73":{"address":5843706,"default_item":155,"flag":684},"BERRY_TREE_74":{"address":5843708,"default_item":155,"flag":685},"BERRY_TREE_75":{"address":5843710,"default_item":142,"flag":686},"BERRY_TREE_76":{"address":5843712,"default_item":133,"flag":687},"BERRY_TREE_77":{"address":5843714,"default_item":140,"flag":688},"BERRY_TREE_78":{"address":5843716,"default_item":140,"flag":689},"BERRY_TREE_79":{"address":5843718,"default_item":155,"flag":690},"BERRY_TREE_80":{"address":5843720,"default_item":139,"flag":691},"BERRY_TREE_81":{"address":5843722,"default_item":139,"flag":692},"BERRY_TREE_82":{"address":5843724,"default_item":168,"flag":693},"BERRY_TREE_83":{"address":5843726,"default_item":156,"flag":694},"BERRY_TREE_84":{"address":5843728,"default_item":156,"flag":695},"BERRY_TREE_85":{"address":5843730,"default_item":142,"flag":696},"BERRY_TREE_86":{"address":5843732,"default_item":138,"flag":697},"BERRY_TREE_87":{"address":5843734,"default_item":135,"flag":698},"BERRY_TREE_88":{"address":5843736,"default_item":142,"flag":699},"HIDDEN_ITEM_ABANDONED_SHIP_RM_1_KEY":{"address":5497200,"default_item":281,"flag":531},"HIDDEN_ITEM_ABANDONED_SHIP_RM_2_KEY":{"address":5497212,"default_item":282,"flag":532},"HIDDEN_ITEM_ABANDONED_SHIP_RM_4_KEY":{"address":5497224,"default_item":283,"flag":533},"HIDDEN_ITEM_ABANDONED_SHIP_RM_6_KEY":{"address":5497236,"default_item":284,"flag":534},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_CALCIUM":{"address":5500100,"default_item":67,"flag":601},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_IRON":{"address":5500124,"default_item":65,"flag":604},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_PROTEIN":{"address":5500112,"default_item":64,"flag":603},"HIDDEN_ITEM_ARTISAN_CAVE_B1F_ZINC":{"address":5500088,"default_item":70,"flag":602},"HIDDEN_ITEM_FALLARBOR_TOWN_NUGGET":{"address":5435924,"default_item":110,"flag":528},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_1":{"address":5487372,"default_item":195,"flag":548},"HIDDEN_ITEM_GRANITE_CAVE_B2F_EVERSTONE_2":{"address":5487384,"default_item":195,"flag":549},"HIDDEN_ITEM_JAGGED_PASS_FULL_HEAL":{"address":5489116,"default_item":23,"flag":577},"HIDDEN_ITEM_JAGGED_PASS_GREAT_BALL":{"address":5489128,"default_item":3,"flag":576},"HIDDEN_ITEM_LAVARIDGE_TOWN_ICE_HEAL":{"address":5435672,"default_item":16,"flag":500},"HIDDEN_ITEM_LILYCOVE_CITY_HEART_SCALE":{"address":5432608,"default_item":111,"flag":527},"HIDDEN_ITEM_LILYCOVE_CITY_POKE_BALL":{"address":5432632,"default_item":4,"flag":575},"HIDDEN_ITEM_LILYCOVE_CITY_PP_UP":{"address":5432620,"default_item":69,"flag":543},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_MAX_ETHER":{"address":5490440,"default_item":35,"flag":578},"HIDDEN_ITEM_MT_PYRE_EXTERIOR_ULTRA_BALL":{"address":5490428,"default_item":2,"flag":529},"HIDDEN_ITEM_MT_PYRE_SUMMIT_RARE_CANDY":{"address":5490796,"default_item":68,"flag":580},"HIDDEN_ITEM_MT_PYRE_SUMMIT_ZINC":{"address":5490784,"default_item":70,"flag":579},"HIDDEN_ITEM_NAVEL_ROCK_TOP_SACRED_ASH":{"address":5525804,"default_item":45,"flag":609},"HIDDEN_ITEM_PETALBURG_CITY_RARE_CANDY":{"address":5428972,"default_item":68,"flag":595},"HIDDEN_ITEM_PETALBURG_WOODS_POKE_BALL":{"address":5487908,"default_item":4,"flag":561},"HIDDEN_ITEM_PETALBURG_WOODS_POTION":{"address":5487872,"default_item":13,"flag":558},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_1":{"address":5487884,"default_item":103,"flag":559},"HIDDEN_ITEM_PETALBURG_WOODS_TINY_MUSHROOM_2":{"address":5487896,"default_item":103,"flag":560},"HIDDEN_ITEM_ROUTE_104_ANTIDOTE":{"address":5438492,"default_item":14,"flag":585},"HIDDEN_ITEM_ROUTE_104_HEART_SCALE":{"address":5438504,"default_item":111,"flag":588},"HIDDEN_ITEM_ROUTE_104_POKE_BALL":{"address":5438468,"default_item":4,"flag":562},"HIDDEN_ITEM_ROUTE_104_POTION":{"address":5438480,"default_item":13,"flag":537},"HIDDEN_ITEM_ROUTE_104_SUPER_POTION":{"address":5438456,"default_item":22,"flag":544},"HIDDEN_ITEM_ROUTE_105_BIG_PEARL":{"address":5438748,"default_item":107,"flag":611},"HIDDEN_ITEM_ROUTE_105_HEART_SCALE":{"address":5438736,"default_item":111,"flag":589},"HIDDEN_ITEM_ROUTE_106_HEART_SCALE":{"address":5438932,"default_item":111,"flag":547},"HIDDEN_ITEM_ROUTE_106_POKE_BALL":{"address":5438908,"default_item":4,"flag":563},"HIDDEN_ITEM_ROUTE_106_STARDUST":{"address":5438920,"default_item":108,"flag":546},"HIDDEN_ITEM_ROUTE_108_RARE_CANDY":{"address":5439340,"default_item":68,"flag":586},"HIDDEN_ITEM_ROUTE_109_ETHER":{"address":5440016,"default_item":34,"flag":564},"HIDDEN_ITEM_ROUTE_109_GREAT_BALL":{"address":5440004,"default_item":3,"flag":551},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_1":{"address":5439992,"default_item":111,"flag":552},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_2":{"address":5440028,"default_item":111,"flag":590},"HIDDEN_ITEM_ROUTE_109_HEART_SCALE_3":{"address":5440040,"default_item":111,"flag":591},"HIDDEN_ITEM_ROUTE_109_REVIVE":{"address":5439980,"default_item":24,"flag":550},"HIDDEN_ITEM_ROUTE_110_FULL_HEAL":{"address":5441308,"default_item":23,"flag":555},"HIDDEN_ITEM_ROUTE_110_GREAT_BALL":{"address":5441284,"default_item":3,"flag":553},"HIDDEN_ITEM_ROUTE_110_POKE_BALL":{"address":5441296,"default_item":4,"flag":565},"HIDDEN_ITEM_ROUTE_110_REVIVE":{"address":5441272,"default_item":24,"flag":554},"HIDDEN_ITEM_ROUTE_111_PROTEIN":{"address":5443220,"default_item":64,"flag":556},"HIDDEN_ITEM_ROUTE_111_RARE_CANDY":{"address":5443232,"default_item":68,"flag":557},"HIDDEN_ITEM_ROUTE_111_STARDUST":{"address":5443160,"default_item":108,"flag":502},"HIDDEN_ITEM_ROUTE_113_ETHER":{"address":5444488,"default_item":34,"flag":503},"HIDDEN_ITEM_ROUTE_113_NUGGET":{"address":5444512,"default_item":110,"flag":598},"HIDDEN_ITEM_ROUTE_113_TM_DOUBLE_TEAM":{"address":5444500,"default_item":320,"flag":530},"HIDDEN_ITEM_ROUTE_114_CARBOS":{"address":5445340,"default_item":66,"flag":504},"HIDDEN_ITEM_ROUTE_114_REVIVE":{"address":5445364,"default_item":24,"flag":542},"HIDDEN_ITEM_ROUTE_115_HEART_SCALE":{"address":5446176,"default_item":111,"flag":597},"HIDDEN_ITEM_ROUTE_116_BLACK_GLASSES":{"address":5447056,"default_item":206,"flag":596},"HIDDEN_ITEM_ROUTE_116_SUPER_POTION":{"address":5447044,"default_item":22,"flag":545},"HIDDEN_ITEM_ROUTE_117_REPEL":{"address":5447708,"default_item":86,"flag":572},"HIDDEN_ITEM_ROUTE_118_HEART_SCALE":{"address":5448404,"default_item":111,"flag":566},"HIDDEN_ITEM_ROUTE_118_IRON":{"address":5448392,"default_item":65,"flag":567},"HIDDEN_ITEM_ROUTE_119_CALCIUM":{"address":5449972,"default_item":67,"flag":505},"HIDDEN_ITEM_ROUTE_119_FULL_HEAL":{"address":5450056,"default_item":23,"flag":568},"HIDDEN_ITEM_ROUTE_119_MAX_ETHER":{"address":5450068,"default_item":35,"flag":587},"HIDDEN_ITEM_ROUTE_119_ULTRA_BALL":{"address":5449984,"default_item":2,"flag":506},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_1":{"address":5451596,"default_item":68,"flag":571},"HIDDEN_ITEM_ROUTE_120_RARE_CANDY_2":{"address":5451620,"default_item":68,"flag":569},"HIDDEN_ITEM_ROUTE_120_REVIVE":{"address":5451608,"default_item":24,"flag":584},"HIDDEN_ITEM_ROUTE_120_ZINC":{"address":5451632,"default_item":70,"flag":570},"HIDDEN_ITEM_ROUTE_121_FULL_HEAL":{"address":5452540,"default_item":23,"flag":573},"HIDDEN_ITEM_ROUTE_121_HP_UP":{"address":5452516,"default_item":63,"flag":539},"HIDDEN_ITEM_ROUTE_121_MAX_REVIVE":{"address":5452552,"default_item":25,"flag":600},"HIDDEN_ITEM_ROUTE_121_NUGGET":{"address":5452528,"default_item":110,"flag":540},"HIDDEN_ITEM_ROUTE_123_HYPER_POTION":{"address":5454100,"default_item":21,"flag":574},"HIDDEN_ITEM_ROUTE_123_PP_UP":{"address":5454112,"default_item":69,"flag":599},"HIDDEN_ITEM_ROUTE_123_RARE_CANDY":{"address":5454124,"default_item":68,"flag":610},"HIDDEN_ITEM_ROUTE_123_REVIVE":{"address":5454088,"default_item":24,"flag":541},"HIDDEN_ITEM_ROUTE_123_SUPER_REPEL":{"address":5454052,"default_item":83,"flag":507},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_1":{"address":5455620,"default_item":111,"flag":592},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_2":{"address":5455632,"default_item":111,"flag":593},"HIDDEN_ITEM_ROUTE_128_HEART_SCALE_3":{"address":5455644,"default_item":111,"flag":594},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_RARE_CANDY":{"address":5517256,"default_item":68,"flag":606},"HIDDEN_ITEM_SAFARI_ZONE_NORTH_EAST_ZINC":{"address":5517268,"default_item":70,"flag":607},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_FULL_RESTORE":{"address":5517432,"default_item":19,"flag":605},"HIDDEN_ITEM_SAFARI_ZONE_SOUTH_EAST_PP_UP":{"address":5517420,"default_item":69,"flag":608},"HIDDEN_ITEM_SS_TIDAL_LOWER_DECK_LEFTOVERS":{"address":5511292,"default_item":200,"flag":535},"HIDDEN_ITEM_TRICK_HOUSE_NUGGET":{"address":5526716,"default_item":110,"flag":501},"HIDDEN_ITEM_UNDERWATER_124_BIG_PEARL":{"address":5456992,"default_item":107,"flag":511},"HIDDEN_ITEM_UNDERWATER_124_CALCIUM":{"address":5457016,"default_item":67,"flag":536},"HIDDEN_ITEM_UNDERWATER_124_CARBOS":{"address":5456956,"default_item":66,"flag":508},"HIDDEN_ITEM_UNDERWATER_124_GREEN_SHARD":{"address":5456968,"default_item":51,"flag":509},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_1":{"address":5457004,"default_item":111,"flag":513},"HIDDEN_ITEM_UNDERWATER_124_HEART_SCALE_2":{"address":5457028,"default_item":111,"flag":538},"HIDDEN_ITEM_UNDERWATER_124_PEARL":{"address":5456980,"default_item":106,"flag":510},"HIDDEN_ITEM_UNDERWATER_126_BIG_PEARL":{"address":5457140,"default_item":107,"flag":520},"HIDDEN_ITEM_UNDERWATER_126_BLUE_SHARD":{"address":5457152,"default_item":49,"flag":512},"HIDDEN_ITEM_UNDERWATER_126_HEART_SCALE":{"address":5457068,"default_item":111,"flag":514},"HIDDEN_ITEM_UNDERWATER_126_IRON":{"address":5457116,"default_item":65,"flag":519},"HIDDEN_ITEM_UNDERWATER_126_PEARL":{"address":5457104,"default_item":106,"flag":517},"HIDDEN_ITEM_UNDERWATER_126_STARDUST":{"address":5457092,"default_item":108,"flag":516},"HIDDEN_ITEM_UNDERWATER_126_ULTRA_BALL":{"address":5457080,"default_item":2,"flag":515},"HIDDEN_ITEM_UNDERWATER_126_YELLOW_SHARD":{"address":5457128,"default_item":50,"flag":518},"HIDDEN_ITEM_UNDERWATER_127_HEART_SCALE":{"address":5457224,"default_item":111,"flag":523},"HIDDEN_ITEM_UNDERWATER_127_HP_UP":{"address":5457212,"default_item":63,"flag":522},"HIDDEN_ITEM_UNDERWATER_127_RED_SHARD":{"address":5457236,"default_item":48,"flag":524},"HIDDEN_ITEM_UNDERWATER_127_STAR_PIECE":{"address":5457200,"default_item":109,"flag":521},"HIDDEN_ITEM_UNDERWATER_128_PEARL":{"address":5457288,"default_item":106,"flag":526},"HIDDEN_ITEM_UNDERWATER_128_PROTEIN":{"address":5457276,"default_item":64,"flag":525},"HIDDEN_ITEM_VICTORY_ROAD_1F_ULTRA_BALL":{"address":5493932,"default_item":2,"flag":581},"HIDDEN_ITEM_VICTORY_ROAD_B2F_ELIXIR":{"address":5494744,"default_item":36,"flag":582},"HIDDEN_ITEM_VICTORY_ROAD_B2F_MAX_REPEL":{"address":5494756,"default_item":84,"flag":583},"ITEM_ABANDONED_SHIP_CAPTAINS_OFFICE_STORAGE_KEY":{"address":2709805,"default_item":285,"flag":1100},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_1_TM_RAIN_DANCE":{"address":2709857,"default_item":306,"flag":1102},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_2_SCANNER":{"address":2709831,"default_item":278,"flag":1078},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_3_WATER_STONE":{"address":2709844,"default_item":97,"flag":1101},"ITEM_ABANDONED_SHIP_HIDDEN_FLOOR_ROOM_6_LUXURY_BALL":{"address":2709818,"default_item":11,"flag":1077},"ITEM_ABANDONED_SHIP_ROOMS_1F_HARBOR_MAIL":{"address":2709740,"default_item":122,"flag":1095},"ITEM_ABANDONED_SHIP_ROOMS_2_1F_REVIVE":{"address":2709792,"default_item":24,"flag":1099},"ITEM_ABANDONED_SHIP_ROOMS_2_B1F_DIVE_BALL":{"address":2709766,"default_item":7,"flag":1097},"ITEM_ABANDONED_SHIP_ROOMS_B1F_ESCAPE_ROPE":{"address":2709753,"default_item":85,"flag":1096},"ITEM_ABANDONED_SHIP_ROOMS_B1F_TM_ICE_BEAM":{"address":2709779,"default_item":301,"flag":1098},"ITEM_AQUA_HIDEOUT_B1F_MASTER_BALL":{"address":2710039,"default_item":1,"flag":1124},"ITEM_AQUA_HIDEOUT_B1F_MAX_ELIXIR":{"address":2710065,"default_item":37,"flag":1071},"ITEM_AQUA_HIDEOUT_B1F_NUGGET":{"address":2710052,"default_item":110,"flag":1132},"ITEM_AQUA_HIDEOUT_B2F_NEST_BALL":{"address":2710078,"default_item":8,"flag":1072},"ITEM_ARTISAN_CAVE_1F_CARBOS":{"address":2710416,"default_item":66,"flag":1163},"ITEM_ARTISAN_CAVE_B1F_HP_UP":{"address":2710403,"default_item":63,"flag":1162},"ITEM_FIERY_PATH_FIRE_STONE":{"address":2709584,"default_item":95,"flag":1111},"ITEM_FIERY_PATH_TM_TOXIC":{"address":2709597,"default_item":294,"flag":1091},"ITEM_GRANITE_CAVE_1F_ESCAPE_ROPE":{"address":2709519,"default_item":85,"flag":1050},"ITEM_GRANITE_CAVE_B1F_POKE_BALL":{"address":2709532,"default_item":4,"flag":1051},"ITEM_GRANITE_CAVE_B2F_RARE_CANDY":{"address":2709558,"default_item":68,"flag":1054},"ITEM_GRANITE_CAVE_B2F_REPEL":{"address":2709545,"default_item":86,"flag":1053},"ITEM_JAGGED_PASS_BURN_HEAL":{"address":2709571,"default_item":15,"flag":1070},"ITEM_LILYCOVE_CITY_MAX_REPEL":{"address":2709415,"default_item":84,"flag":1042},"ITEM_MAGMA_HIDEOUT_1F_RARE_CANDY":{"address":2710429,"default_item":68,"flag":1151},"ITEM_MAGMA_HIDEOUT_2F_2R_FULL_RESTORE":{"address":2710455,"default_item":19,"flag":1165},"ITEM_MAGMA_HIDEOUT_2F_2R_MAX_ELIXIR":{"address":2710442,"default_item":37,"flag":1164},"ITEM_MAGMA_HIDEOUT_3F_1R_NUGGET":{"address":2710468,"default_item":110,"flag":1166},"ITEM_MAGMA_HIDEOUT_3F_2R_PP_MAX":{"address":2710481,"default_item":71,"flag":1167},"ITEM_MAGMA_HIDEOUT_3F_3R_ECAPE_ROPE":{"address":2710507,"default_item":85,"flag":1059},"ITEM_MAGMA_HIDEOUT_4F_MAX_REVIVE":{"address":2710494,"default_item":25,"flag":1168},"ITEM_MAUVILLE_CITY_X_SPEED":{"address":2709389,"default_item":77,"flag":1116},"ITEM_METEOR_FALLS_1F_1R_FULL_HEAL":{"address":2709623,"default_item":23,"flag":1045},"ITEM_METEOR_FALLS_1F_1R_MOON_STONE":{"address":2709636,"default_item":94,"flag":1046},"ITEM_METEOR_FALLS_1F_1R_PP_UP":{"address":2709649,"default_item":69,"flag":1047},"ITEM_METEOR_FALLS_1F_1R_TM_IRON_TAIL":{"address":2709610,"default_item":311,"flag":1044},"ITEM_METEOR_FALLS_B1F_2R_TM_DRAGON_CLAW":{"address":2709662,"default_item":290,"flag":1080},"ITEM_MOSSDEEP_CITY_NET_BALL":{"address":2709428,"default_item":6,"flag":1043},"ITEM_MT_PYRE_2F_ULTRA_BALL":{"address":2709948,"default_item":2,"flag":1129},"ITEM_MT_PYRE_3F_SUPER_REPEL":{"address":2709961,"default_item":83,"flag":1120},"ITEM_MT_PYRE_4F_SEA_INCENSE":{"address":2709974,"default_item":220,"flag":1130},"ITEM_MT_PYRE_5F_LAX_INCENSE":{"address":2709987,"default_item":221,"flag":1052},"ITEM_MT_PYRE_6F_TM_SHADOW_BALL":{"address":2710000,"default_item":318,"flag":1089},"ITEM_MT_PYRE_EXTERIOR_MAX_POTION":{"address":2710013,"default_item":20,"flag":1073},"ITEM_MT_PYRE_EXTERIOR_TM_SKILL_SWAP":{"address":2710026,"default_item":336,"flag":1074},"ITEM_NEW_MAUVILLE_ESCAPE_ROPE":{"address":2709688,"default_item":85,"flag":1076},"ITEM_NEW_MAUVILLE_FULL_HEAL":{"address":2709714,"default_item":23,"flag":1122},"ITEM_NEW_MAUVILLE_PARALYZE_HEAL":{"address":2709727,"default_item":18,"flag":1123},"ITEM_NEW_MAUVILLE_THUNDER_STONE":{"address":2709701,"default_item":96,"flag":1110},"ITEM_NEW_MAUVILLE_ULTRA_BALL":{"address":2709675,"default_item":2,"flag":1075},"ITEM_PETALBURG_CITY_ETHER":{"address":2709376,"default_item":34,"flag":1040},"ITEM_PETALBURG_CITY_MAX_REVIVE":{"address":2709363,"default_item":25,"flag":1039},"ITEM_PETALBURG_WOODS_ETHER":{"address":2709467,"default_item":34,"flag":1058},"ITEM_PETALBURG_WOODS_GREAT_BALL":{"address":2709454,"default_item":3,"flag":1056},"ITEM_PETALBURG_WOODS_PARALYZE_HEAL":{"address":2709480,"default_item":18,"flag":1117},"ITEM_PETALBURG_WOODS_X_ATTACK":{"address":2709441,"default_item":75,"flag":1055},"ITEM_ROUTE_102_POTION":{"address":2708375,"default_item":13,"flag":1000},"ITEM_ROUTE_103_GUARD_SPEC":{"address":2708388,"default_item":73,"flag":1114},"ITEM_ROUTE_103_PP_UP":{"address":2708401,"default_item":69,"flag":1137},"ITEM_ROUTE_104_POKE_BALL":{"address":2708427,"default_item":4,"flag":1057},"ITEM_ROUTE_104_POTION":{"address":2708453,"default_item":13,"flag":1135},"ITEM_ROUTE_104_PP_UP":{"address":2708414,"default_item":69,"flag":1002},"ITEM_ROUTE_104_X_ACCURACY":{"address":2708440,"default_item":78,"flag":1115},"ITEM_ROUTE_105_IRON":{"address":2708466,"default_item":65,"flag":1003},"ITEM_ROUTE_106_PROTEIN":{"address":2708479,"default_item":64,"flag":1004},"ITEM_ROUTE_108_STAR_PIECE":{"address":2708492,"default_item":109,"flag":1139},"ITEM_ROUTE_109_POTION":{"address":2708518,"default_item":13,"flag":1140},"ITEM_ROUTE_109_PP_UP":{"address":2708505,"default_item":69,"flag":1005},"ITEM_ROUTE_110_DIRE_HIT":{"address":2708544,"default_item":74,"flag":1007},"ITEM_ROUTE_110_ELIXIR":{"address":2708557,"default_item":36,"flag":1141},"ITEM_ROUTE_110_RARE_CANDY":{"address":2708531,"default_item":68,"flag":1006},"ITEM_ROUTE_111_ELIXIR":{"address":2708609,"default_item":36,"flag":1142},"ITEM_ROUTE_111_HP_UP":{"address":2708596,"default_item":63,"flag":1010},"ITEM_ROUTE_111_STARDUST":{"address":2708583,"default_item":108,"flag":1009},"ITEM_ROUTE_111_TM_SANDSTORM":{"address":2708570,"default_item":325,"flag":1008},"ITEM_ROUTE_112_NUGGET":{"address":2708622,"default_item":110,"flag":1011},"ITEM_ROUTE_113_HYPER_POTION":{"address":2708661,"default_item":21,"flag":1143},"ITEM_ROUTE_113_MAX_ETHER":{"address":2708635,"default_item":35,"flag":1012},"ITEM_ROUTE_113_SUPER_REPEL":{"address":2708648,"default_item":83,"flag":1013},"ITEM_ROUTE_114_ENERGY_POWDER":{"address":2708700,"default_item":30,"flag":1160},"ITEM_ROUTE_114_PROTEIN":{"address":2708687,"default_item":64,"flag":1015},"ITEM_ROUTE_114_RARE_CANDY":{"address":2708674,"default_item":68,"flag":1014},"ITEM_ROUTE_115_GREAT_BALL":{"address":2708752,"default_item":3,"flag":1118},"ITEM_ROUTE_115_HEAL_POWDER":{"address":2708765,"default_item":32,"flag":1144},"ITEM_ROUTE_115_IRON":{"address":2708739,"default_item":65,"flag":1018},"ITEM_ROUTE_115_PP_UP":{"address":2708778,"default_item":69,"flag":1161},"ITEM_ROUTE_115_SUPER_POTION":{"address":2708713,"default_item":22,"flag":1016},"ITEM_ROUTE_115_TM_FOCUS_PUNCH":{"address":2708726,"default_item":289,"flag":1017},"ITEM_ROUTE_116_ETHER":{"address":2708804,"default_item":34,"flag":1019},"ITEM_ROUTE_116_HP_UP":{"address":2708830,"default_item":63,"flag":1021},"ITEM_ROUTE_116_POTION":{"address":2708843,"default_item":13,"flag":1146},"ITEM_ROUTE_116_REPEL":{"address":2708817,"default_item":86,"flag":1020},"ITEM_ROUTE_116_X_SPECIAL":{"address":2708791,"default_item":79,"flag":1001},"ITEM_ROUTE_117_GREAT_BALL":{"address":2708856,"default_item":3,"flag":1022},"ITEM_ROUTE_117_REVIVE":{"address":2708869,"default_item":24,"flag":1023},"ITEM_ROUTE_118_HYPER_POTION":{"address":2708882,"default_item":21,"flag":1121},"ITEM_ROUTE_119_ELIXIR_1":{"address":2708921,"default_item":36,"flag":1026},"ITEM_ROUTE_119_ELIXIR_2":{"address":2708986,"default_item":36,"flag":1147},"ITEM_ROUTE_119_HYPER_POTION_1":{"address":2708960,"default_item":21,"flag":1029},"ITEM_ROUTE_119_HYPER_POTION_2":{"address":2708973,"default_item":21,"flag":1106},"ITEM_ROUTE_119_LEAF_STONE":{"address":2708934,"default_item":98,"flag":1027},"ITEM_ROUTE_119_NUGGET":{"address":2710104,"default_item":110,"flag":1134},"ITEM_ROUTE_119_RARE_CANDY":{"address":2708947,"default_item":68,"flag":1028},"ITEM_ROUTE_119_SUPER_REPEL":{"address":2708895,"default_item":83,"flag":1024},"ITEM_ROUTE_119_ZINC":{"address":2708908,"default_item":70,"flag":1025},"ITEM_ROUTE_120_FULL_HEAL":{"address":2709012,"default_item":23,"flag":1031},"ITEM_ROUTE_120_HYPER_POTION":{"address":2709025,"default_item":21,"flag":1107},"ITEM_ROUTE_120_NEST_BALL":{"address":2709038,"default_item":8,"flag":1108},"ITEM_ROUTE_120_NUGGET":{"address":2708999,"default_item":110,"flag":1030},"ITEM_ROUTE_120_REVIVE":{"address":2709051,"default_item":24,"flag":1148},"ITEM_ROUTE_121_CARBOS":{"address":2709064,"default_item":66,"flag":1103},"ITEM_ROUTE_121_REVIVE":{"address":2709077,"default_item":24,"flag":1149},"ITEM_ROUTE_121_ZINC":{"address":2709090,"default_item":70,"flag":1150},"ITEM_ROUTE_123_CALCIUM":{"address":2709103,"default_item":67,"flag":1032},"ITEM_ROUTE_123_ELIXIR":{"address":2709129,"default_item":36,"flag":1109},"ITEM_ROUTE_123_PP_UP":{"address":2709142,"default_item":69,"flag":1152},"ITEM_ROUTE_123_REVIVAL_HERB":{"address":2709155,"default_item":33,"flag":1153},"ITEM_ROUTE_123_ULTRA_BALL":{"address":2709116,"default_item":2,"flag":1104},"ITEM_ROUTE_124_BLUE_SHARD":{"address":2709181,"default_item":49,"flag":1093},"ITEM_ROUTE_124_RED_SHARD":{"address":2709168,"default_item":48,"flag":1092},"ITEM_ROUTE_124_YELLOW_SHARD":{"address":2709194,"default_item":50,"flag":1066},"ITEM_ROUTE_125_BIG_PEARL":{"address":2709207,"default_item":107,"flag":1154},"ITEM_ROUTE_126_GREEN_SHARD":{"address":2709220,"default_item":51,"flag":1105},"ITEM_ROUTE_127_CARBOS":{"address":2709246,"default_item":66,"flag":1035},"ITEM_ROUTE_127_RARE_CANDY":{"address":2709259,"default_item":68,"flag":1155},"ITEM_ROUTE_127_ZINC":{"address":2709233,"default_item":70,"flag":1034},"ITEM_ROUTE_132_PROTEIN":{"address":2709285,"default_item":64,"flag":1156},"ITEM_ROUTE_132_RARE_CANDY":{"address":2709272,"default_item":68,"flag":1036},"ITEM_ROUTE_133_BIG_PEARL":{"address":2709298,"default_item":107,"flag":1037},"ITEM_ROUTE_133_MAX_REVIVE":{"address":2709324,"default_item":25,"flag":1157},"ITEM_ROUTE_133_STAR_PIECE":{"address":2709311,"default_item":109,"flag":1038},"ITEM_ROUTE_134_CARBOS":{"address":2709337,"default_item":66,"flag":1158},"ITEM_ROUTE_134_STAR_PIECE":{"address":2709350,"default_item":109,"flag":1159},"ITEM_RUSTBORO_CITY_X_DEFEND":{"address":2709402,"default_item":76,"flag":1041},"ITEM_RUSTURF_TUNNEL_MAX_ETHER":{"address":2709506,"default_item":35,"flag":1049},"ITEM_RUSTURF_TUNNEL_POKE_BALL":{"address":2709493,"default_item":4,"flag":1048},"ITEM_SAFARI_ZONE_NORTH_CALCIUM":{"address":2709896,"default_item":67,"flag":1119},"ITEM_SAFARI_ZONE_NORTH_EAST_NUGGET":{"address":2709922,"default_item":110,"flag":1169},"ITEM_SAFARI_ZONE_NORTH_WEST_TM_SOLAR_BEAM":{"address":2709883,"default_item":310,"flag":1094},"ITEM_SAFARI_ZONE_SOUTH_EAST_BIG_PEARL":{"address":2709935,"default_item":107,"flag":1170},"ITEM_SAFARI_ZONE_SOUTH_WEST_MAX_REVIVE":{"address":2709909,"default_item":25,"flag":1131},"ITEM_SCORCHED_SLAB_TM_SUNNY_DAY":{"address":2709870,"default_item":299,"flag":1079},"ITEM_SEAFLOOR_CAVERN_ROOM_9_TM_EARTHQUAKE":{"address":2710208,"default_item":314,"flag":1090},"ITEM_SHOAL_CAVE_ENTRANCE_BIG_PEARL":{"address":2710143,"default_item":107,"flag":1081},"ITEM_SHOAL_CAVE_ICE_ROOM_NEVER_MELT_ICE":{"address":2710195,"default_item":212,"flag":1113},"ITEM_SHOAL_CAVE_ICE_ROOM_TM_HAIL":{"address":2710182,"default_item":295,"flag":1112},"ITEM_SHOAL_CAVE_INNER_ROOM_RARE_CANDY":{"address":2710156,"default_item":68,"flag":1082},"ITEM_SHOAL_CAVE_STAIRS_ROOM_ICE_HEAL":{"address":2710169,"default_item":16,"flag":1083},"ITEM_TRICK_HOUSE_PUZZLE_1_ORANGE_MAIL":{"address":[2710221,2551006],"default_item":121,"flag":1060},"ITEM_TRICK_HOUSE_PUZZLE_2_HARBOR_MAIL":{"address":[2710234,2551032],"default_item":122,"flag":1061},"ITEM_TRICK_HOUSE_PUZZLE_2_WAVE_MAIL":{"address":[2710247,2551058],"default_item":126,"flag":1062},"ITEM_TRICK_HOUSE_PUZZLE_3_SHADOW_MAIL":{"address":[2710260,2551084],"default_item":128,"flag":1063},"ITEM_TRICK_HOUSE_PUZZLE_3_WOOD_MAIL":{"address":[2710273,2551110],"default_item":125,"flag":1064},"ITEM_TRICK_HOUSE_PUZZLE_4_MECH_MAIL":{"address":[2710286,2551136],"default_item":124,"flag":1065},"ITEM_TRICK_HOUSE_PUZZLE_6_GLITTER_MAIL":{"address":[2710299,2551162],"default_item":123,"flag":1067},"ITEM_TRICK_HOUSE_PUZZLE_7_TROPIC_MAIL":{"address":[2710312,2551188],"default_item":129,"flag":1068},"ITEM_TRICK_HOUSE_PUZZLE_8_BEAD_MAIL":{"address":[2710325,2551214],"default_item":127,"flag":1069},"ITEM_VICTORY_ROAD_1F_MAX_ELIXIR":{"address":2710338,"default_item":37,"flag":1084},"ITEM_VICTORY_ROAD_1F_PP_UP":{"address":2710351,"default_item":69,"flag":1085},"ITEM_VICTORY_ROAD_B1F_FULL_RESTORE":{"address":2710377,"default_item":19,"flag":1087},"ITEM_VICTORY_ROAD_B1F_TM_PSYCHIC":{"address":2710364,"default_item":317,"flag":1086},"ITEM_VICTORY_ROAD_B2F_FULL_HEAL":{"address":2710390,"default_item":23,"flag":1088},"NPC_GIFT_BERRY_MASTERS_WIFE":{"address":2570453,"default_item":133,"flag":1197},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_1":{"address":2570263,"default_item":153,"flag":1195},"NPC_GIFT_BERRY_MASTER_RECEIVED_BERRY_2":{"address":2570315,"default_item":154,"flag":1196},"NPC_GIFT_FLOWER_SHOP_RECEIVED_BERRY":{"address":2284375,"default_item":133,"flag":1207},"NPC_GIFT_GOT_BASEMENT_KEY_FROM_WATTSON":{"address":1971718,"default_item":271,"flag":208},"NPC_GIFT_GOT_TM_THUNDERBOLT_FROM_WATTSON":{"address":1971754,"default_item":312,"flag":209},"NPC_GIFT_LILYCOVE_RECEIVED_BERRY":{"address":1985277,"default_item":141,"flag":1208},"NPC_GIFT_RECEIVED_6_SODA_POP":{"address":2543767,"default_item":27,"flag":140},"NPC_GIFT_RECEIVED_ACRO_BIKE":{"address":2170570,"default_item":272,"flag":1181},"NPC_GIFT_RECEIVED_AMULET_COIN":{"address":2716248,"default_item":189,"flag":133},"NPC_GIFT_RECEIVED_AURORA_TICKET":{"address":2716523,"default_item":371,"flag":314},"NPC_GIFT_RECEIVED_CHARCOAL":{"address":2102559,"default_item":215,"flag":254},"NPC_GIFT_RECEIVED_CHESTO_BERRY_ROUTE_104":{"address":2028703,"default_item":134,"flag":246},"NPC_GIFT_RECEIVED_CLEANSE_TAG":{"address":2312109,"default_item":190,"flag":282},"NPC_GIFT_RECEIVED_COIN_CASE":{"address":2179054,"default_item":260,"flag":258},"NPC_GIFT_RECEIVED_DEEP_SEA_SCALE":{"address":2162572,"default_item":193,"flag":1190},"NPC_GIFT_RECEIVED_DEEP_SEA_TOOTH":{"address":2162555,"default_item":192,"flag":1191},"NPC_GIFT_RECEIVED_DEVON_GOODS_RUSTURF_TUNNEL":{"address":2295814,"default_item":269,"flag":1172},"NPC_GIFT_RECEIVED_DEVON_SCOPE":{"address":2065146,"default_item":288,"flag":285},"NPC_GIFT_RECEIVED_EON_TICKET":{"address":2716574,"default_item":275,"flag":474},"NPC_GIFT_RECEIVED_EXP_SHARE":{"address":2185525,"default_item":182,"flag":272},"NPC_GIFT_RECEIVED_FIRST_POKEBALLS":{"address":2085751,"default_item":4,"flag":233},"NPC_GIFT_RECEIVED_FOCUS_BAND":{"address":2337807,"default_item":196,"flag":283},"NPC_GIFT_RECEIVED_GOOD_ROD":{"address":2058408,"default_item":263,"flag":227},"NPC_GIFT_RECEIVED_GO_GOGGLES":{"address":2017746,"default_item":279,"flag":221},"NPC_GIFT_RECEIVED_GREAT_BALL_PETALBURG_WOODS":{"address":2300119,"default_item":3,"flag":1171},"NPC_GIFT_RECEIVED_GREAT_BALL_RUSTBORO_CITY":{"address":1977146,"default_item":3,"flag":1173},"NPC_GIFT_RECEIVED_HM_CUT":{"address":2199532,"default_item":339,"flag":137},"NPC_GIFT_RECEIVED_HM_DIVE":{"address":2252095,"default_item":346,"flag":123},"NPC_GIFT_RECEIVED_HM_FLASH":{"address":2298287,"default_item":343,"flag":109},"NPC_GIFT_RECEIVED_HM_FLY":{"address":2060636,"default_item":340,"flag":110},"NPC_GIFT_RECEIVED_HM_ROCK_SMASH":{"address":2174128,"default_item":344,"flag":107},"NPC_GIFT_RECEIVED_HM_STRENGTH":{"address":2295305,"default_item":342,"flag":106},"NPC_GIFT_RECEIVED_HM_SURF":{"address":2126671,"default_item":341,"flag":122},"NPC_GIFT_RECEIVED_HM_WATERFALL":{"address":1999854,"default_item":345,"flag":312},"NPC_GIFT_RECEIVED_ITEMFINDER":{"address":2039874,"default_item":261,"flag":1176},"NPC_GIFT_RECEIVED_KINGS_ROCK":{"address":1993670,"default_item":187,"flag":276},"NPC_GIFT_RECEIVED_LETTER":{"address":2185301,"default_item":274,"flag":1174},"NPC_GIFT_RECEIVED_MACHO_BRACE":{"address":2284472,"default_item":181,"flag":277},"NPC_GIFT_RECEIVED_MACH_BIKE":{"address":2170553,"default_item":259,"flag":1180},"NPC_GIFT_RECEIVED_MAGMA_EMBLEM":{"address":2316671,"default_item":375,"flag":1177},"NPC_GIFT_RECEIVED_MENTAL_HERB":{"address":2208103,"default_item":185,"flag":223},"NPC_GIFT_RECEIVED_METEORITE":{"address":2304222,"default_item":280,"flag":115},"NPC_GIFT_RECEIVED_MIRACLE_SEED":{"address":2300337,"default_item":205,"flag":297},"NPC_GIFT_RECEIVED_MYSTIC_TICKET":{"address":2716540,"default_item":370,"flag":315},"NPC_GIFT_RECEIVED_OLD_ROD":{"address":2012541,"default_item":262,"flag":257},"NPC_GIFT_RECEIVED_OLD_SEA_MAP":{"address":2716557,"default_item":376,"flag":316},"NPC_GIFT_RECEIVED_POKEBLOCK_CASE":{"address":2614193,"default_item":273,"flag":95},"NPC_GIFT_RECEIVED_POTION_OLDALE":{"address":2010888,"default_item":13,"flag":132},"NPC_GIFT_RECEIVED_POWDER_JAR":{"address":1962504,"default_item":372,"flag":337},"NPC_GIFT_RECEIVED_PREMIER_BALL_RUSTBORO":{"address":2200571,"default_item":12,"flag":213},"NPC_GIFT_RECEIVED_QUICK_CLAW":{"address":2192227,"default_item":183,"flag":275},"NPC_GIFT_RECEIVED_REPEAT_BALL":{"address":2053722,"default_item":9,"flag":256},"NPC_GIFT_RECEIVED_SECRET_POWER":{"address":2598914,"default_item":331,"flag":96},"NPC_GIFT_RECEIVED_SILK_SCARF":{"address":2101830,"default_item":217,"flag":289},"NPC_GIFT_RECEIVED_SOFT_SAND":{"address":2035664,"default_item":203,"flag":280},"NPC_GIFT_RECEIVED_SOOTHE_BELL":{"address":2151278,"default_item":184,"flag":278},"NPC_GIFT_RECEIVED_SOOT_SACK":{"address":2567245,"default_item":270,"flag":1033},"NPC_GIFT_RECEIVED_SS_TICKET":{"address":2716506,"default_item":265,"flag":291},"NPC_GIFT_RECEIVED_SUN_STONE_MOSSDEEP":{"address":2254406,"default_item":93,"flag":192},"NPC_GIFT_RECEIVED_SUPER_ROD":{"address":2251560,"default_item":264,"flag":152},"NPC_GIFT_RECEIVED_TM_AERIAL_ACE":{"address":2202201,"default_item":328,"flag":170},"NPC_GIFT_RECEIVED_TM_ATTRACT":{"address":2116413,"default_item":333,"flag":235},"NPC_GIFT_RECEIVED_TM_BRICK_BREAK":{"address":2269085,"default_item":319,"flag":121},"NPC_GIFT_RECEIVED_TM_BULK_UP":{"address":2095210,"default_item":296,"flag":166},"NPC_GIFT_RECEIVED_TM_BULLET_SEED":{"address":2028910,"default_item":297,"flag":262},"NPC_GIFT_RECEIVED_TM_CALM_MIND":{"address":2244066,"default_item":292,"flag":171},"NPC_GIFT_RECEIVED_TM_DIG":{"address":2286669,"default_item":316,"flag":261},"NPC_GIFT_RECEIVED_TM_FACADE":{"address":2129909,"default_item":330,"flag":169},"NPC_GIFT_RECEIVED_TM_FRUSTRATION":{"address":2124110,"default_item":309,"flag":1179},"NPC_GIFT_RECEIVED_TM_GIGA_DRAIN":{"address":2068012,"default_item":307,"flag":232},"NPC_GIFT_RECEIVED_TM_HIDDEN_POWER":{"address":2206905,"default_item":298,"flag":264},"NPC_GIFT_RECEIVED_TM_OVERHEAT":{"address":2103328,"default_item":338,"flag":168},"NPC_GIFT_RECEIVED_TM_REST":{"address":2236966,"default_item":332,"flag":234},"NPC_GIFT_RECEIVED_TM_RETURN":{"address":2113546,"default_item":315,"flag":229},"NPC_GIFT_RECEIVED_TM_RETURN_2":{"address":2124055,"default_item":315,"flag":1178},"NPC_GIFT_RECEIVED_TM_ROAR":{"address":2051750,"default_item":293,"flag":231},"NPC_GIFT_RECEIVED_TM_ROCK_TOMB":{"address":2188088,"default_item":327,"flag":165},"NPC_GIFT_RECEIVED_TM_SHOCK_WAVE":{"address":2167340,"default_item":322,"flag":167},"NPC_GIFT_RECEIVED_TM_SLUDGE_BOMB":{"address":2099189,"default_item":324,"flag":230},"NPC_GIFT_RECEIVED_TM_SNATCH":{"address":2360766,"default_item":337,"flag":260},"NPC_GIFT_RECEIVED_TM_STEEL_WING":{"address":2298866,"default_item":335,"flag":1175},"NPC_GIFT_RECEIVED_TM_THIEF":{"address":2154698,"default_item":334,"flag":269},"NPC_GIFT_RECEIVED_TM_TORMENT":{"address":2145260,"default_item":329,"flag":265},"NPC_GIFT_RECEIVED_TM_WATER_PULSE":{"address":2262402,"default_item":291,"flag":172},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_1":{"address":2550316,"default_item":68,"flag":1200},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_2":{"address":2550390,"default_item":10,"flag":1201},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_3":{"address":2550473,"default_item":204,"flag":1202},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_4":{"address":2550556,"default_item":194,"flag":1203},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_5":{"address":2550630,"default_item":300,"flag":1204},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_6":{"address":2550695,"default_item":208,"flag":1205},"NPC_GIFT_RECEIVED_TRICK_HOUSE_REWARD_7":{"address":2550769,"default_item":71,"flag":1206},"NPC_GIFT_RECEIVED_WAILMER_PAIL":{"address":2284320,"default_item":268,"flag":94},"NPC_GIFT_RECEIVED_WHITE_HERB":{"address":2028770,"default_item":180,"flag":279},"NPC_GIFT_ROUTE_111_RECEIVED_BERRY":{"address":2045493,"default_item":148,"flag":1192},"NPC_GIFT_ROUTE_114_RECEIVED_BERRY":{"address":2051680,"default_item":149,"flag":1193},"NPC_GIFT_ROUTE_120_RECEIVED_BERRY":{"address":2064727,"default_item":143,"flag":1194},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_1":{"address":1998521,"default_item":153,"flag":1198},"NPC_GIFT_SOOTOPOLIS_RECEIVED_BERRY_2":{"address":1998566,"default_item":143,"flag":1199},"POKEDEX_REWARD_001":{"address":5729368,"default_item":3,"flag":0},"POKEDEX_REWARD_002":{"address":5729370,"default_item":3,"flag":0},"POKEDEX_REWARD_003":{"address":5729372,"default_item":3,"flag":0},"POKEDEX_REWARD_004":{"address":5729374,"default_item":3,"flag":0},"POKEDEX_REWARD_005":{"address":5729376,"default_item":3,"flag":0},"POKEDEX_REWARD_006":{"address":5729378,"default_item":3,"flag":0},"POKEDEX_REWARD_007":{"address":5729380,"default_item":3,"flag":0},"POKEDEX_REWARD_008":{"address":5729382,"default_item":3,"flag":0},"POKEDEX_REWARD_009":{"address":5729384,"default_item":3,"flag":0},"POKEDEX_REWARD_010":{"address":5729386,"default_item":3,"flag":0},"POKEDEX_REWARD_011":{"address":5729388,"default_item":3,"flag":0},"POKEDEX_REWARD_012":{"address":5729390,"default_item":3,"flag":0},"POKEDEX_REWARD_013":{"address":5729392,"default_item":3,"flag":0},"POKEDEX_REWARD_014":{"address":5729394,"default_item":3,"flag":0},"POKEDEX_REWARD_015":{"address":5729396,"default_item":3,"flag":0},"POKEDEX_REWARD_016":{"address":5729398,"default_item":3,"flag":0},"POKEDEX_REWARD_017":{"address":5729400,"default_item":3,"flag":0},"POKEDEX_REWARD_018":{"address":5729402,"default_item":3,"flag":0},"POKEDEX_REWARD_019":{"address":5729404,"default_item":3,"flag":0},"POKEDEX_REWARD_020":{"address":5729406,"default_item":3,"flag":0},"POKEDEX_REWARD_021":{"address":5729408,"default_item":3,"flag":0},"POKEDEX_REWARD_022":{"address":5729410,"default_item":3,"flag":0},"POKEDEX_REWARD_023":{"address":5729412,"default_item":3,"flag":0},"POKEDEX_REWARD_024":{"address":5729414,"default_item":3,"flag":0},"POKEDEX_REWARD_025":{"address":5729416,"default_item":3,"flag":0},"POKEDEX_REWARD_026":{"address":5729418,"default_item":3,"flag":0},"POKEDEX_REWARD_027":{"address":5729420,"default_item":3,"flag":0},"POKEDEX_REWARD_028":{"address":5729422,"default_item":3,"flag":0},"POKEDEX_REWARD_029":{"address":5729424,"default_item":3,"flag":0},"POKEDEX_REWARD_030":{"address":5729426,"default_item":3,"flag":0},"POKEDEX_REWARD_031":{"address":5729428,"default_item":3,"flag":0},"POKEDEX_REWARD_032":{"address":5729430,"default_item":3,"flag":0},"POKEDEX_REWARD_033":{"address":5729432,"default_item":3,"flag":0},"POKEDEX_REWARD_034":{"address":5729434,"default_item":3,"flag":0},"POKEDEX_REWARD_035":{"address":5729436,"default_item":3,"flag":0},"POKEDEX_REWARD_036":{"address":5729438,"default_item":3,"flag":0},"POKEDEX_REWARD_037":{"address":5729440,"default_item":3,"flag":0},"POKEDEX_REWARD_038":{"address":5729442,"default_item":3,"flag":0},"POKEDEX_REWARD_039":{"address":5729444,"default_item":3,"flag":0},"POKEDEX_REWARD_040":{"address":5729446,"default_item":3,"flag":0},"POKEDEX_REWARD_041":{"address":5729448,"default_item":3,"flag":0},"POKEDEX_REWARD_042":{"address":5729450,"default_item":3,"flag":0},"POKEDEX_REWARD_043":{"address":5729452,"default_item":3,"flag":0},"POKEDEX_REWARD_044":{"address":5729454,"default_item":3,"flag":0},"POKEDEX_REWARD_045":{"address":5729456,"default_item":3,"flag":0},"POKEDEX_REWARD_046":{"address":5729458,"default_item":3,"flag":0},"POKEDEX_REWARD_047":{"address":5729460,"default_item":3,"flag":0},"POKEDEX_REWARD_048":{"address":5729462,"default_item":3,"flag":0},"POKEDEX_REWARD_049":{"address":5729464,"default_item":3,"flag":0},"POKEDEX_REWARD_050":{"address":5729466,"default_item":3,"flag":0},"POKEDEX_REWARD_051":{"address":5729468,"default_item":3,"flag":0},"POKEDEX_REWARD_052":{"address":5729470,"default_item":3,"flag":0},"POKEDEX_REWARD_053":{"address":5729472,"default_item":3,"flag":0},"POKEDEX_REWARD_054":{"address":5729474,"default_item":3,"flag":0},"POKEDEX_REWARD_055":{"address":5729476,"default_item":3,"flag":0},"POKEDEX_REWARD_056":{"address":5729478,"default_item":3,"flag":0},"POKEDEX_REWARD_057":{"address":5729480,"default_item":3,"flag":0},"POKEDEX_REWARD_058":{"address":5729482,"default_item":3,"flag":0},"POKEDEX_REWARD_059":{"address":5729484,"default_item":3,"flag":0},"POKEDEX_REWARD_060":{"address":5729486,"default_item":3,"flag":0},"POKEDEX_REWARD_061":{"address":5729488,"default_item":3,"flag":0},"POKEDEX_REWARD_062":{"address":5729490,"default_item":3,"flag":0},"POKEDEX_REWARD_063":{"address":5729492,"default_item":3,"flag":0},"POKEDEX_REWARD_064":{"address":5729494,"default_item":3,"flag":0},"POKEDEX_REWARD_065":{"address":5729496,"default_item":3,"flag":0},"POKEDEX_REWARD_066":{"address":5729498,"default_item":3,"flag":0},"POKEDEX_REWARD_067":{"address":5729500,"default_item":3,"flag":0},"POKEDEX_REWARD_068":{"address":5729502,"default_item":3,"flag":0},"POKEDEX_REWARD_069":{"address":5729504,"default_item":3,"flag":0},"POKEDEX_REWARD_070":{"address":5729506,"default_item":3,"flag":0},"POKEDEX_REWARD_071":{"address":5729508,"default_item":3,"flag":0},"POKEDEX_REWARD_072":{"address":5729510,"default_item":3,"flag":0},"POKEDEX_REWARD_073":{"address":5729512,"default_item":3,"flag":0},"POKEDEX_REWARD_074":{"address":5729514,"default_item":3,"flag":0},"POKEDEX_REWARD_075":{"address":5729516,"default_item":3,"flag":0},"POKEDEX_REWARD_076":{"address":5729518,"default_item":3,"flag":0},"POKEDEX_REWARD_077":{"address":5729520,"default_item":3,"flag":0},"POKEDEX_REWARD_078":{"address":5729522,"default_item":3,"flag":0},"POKEDEX_REWARD_079":{"address":5729524,"default_item":3,"flag":0},"POKEDEX_REWARD_080":{"address":5729526,"default_item":3,"flag":0},"POKEDEX_REWARD_081":{"address":5729528,"default_item":3,"flag":0},"POKEDEX_REWARD_082":{"address":5729530,"default_item":3,"flag":0},"POKEDEX_REWARD_083":{"address":5729532,"default_item":3,"flag":0},"POKEDEX_REWARD_084":{"address":5729534,"default_item":3,"flag":0},"POKEDEX_REWARD_085":{"address":5729536,"default_item":3,"flag":0},"POKEDEX_REWARD_086":{"address":5729538,"default_item":3,"flag":0},"POKEDEX_REWARD_087":{"address":5729540,"default_item":3,"flag":0},"POKEDEX_REWARD_088":{"address":5729542,"default_item":3,"flag":0},"POKEDEX_REWARD_089":{"address":5729544,"default_item":3,"flag":0},"POKEDEX_REWARD_090":{"address":5729546,"default_item":3,"flag":0},"POKEDEX_REWARD_091":{"address":5729548,"default_item":3,"flag":0},"POKEDEX_REWARD_092":{"address":5729550,"default_item":3,"flag":0},"POKEDEX_REWARD_093":{"address":5729552,"default_item":3,"flag":0},"POKEDEX_REWARD_094":{"address":5729554,"default_item":3,"flag":0},"POKEDEX_REWARD_095":{"address":5729556,"default_item":3,"flag":0},"POKEDEX_REWARD_096":{"address":5729558,"default_item":3,"flag":0},"POKEDEX_REWARD_097":{"address":5729560,"default_item":3,"flag":0},"POKEDEX_REWARD_098":{"address":5729562,"default_item":3,"flag":0},"POKEDEX_REWARD_099":{"address":5729564,"default_item":3,"flag":0},"POKEDEX_REWARD_100":{"address":5729566,"default_item":3,"flag":0},"POKEDEX_REWARD_101":{"address":5729568,"default_item":3,"flag":0},"POKEDEX_REWARD_102":{"address":5729570,"default_item":3,"flag":0},"POKEDEX_REWARD_103":{"address":5729572,"default_item":3,"flag":0},"POKEDEX_REWARD_104":{"address":5729574,"default_item":3,"flag":0},"POKEDEX_REWARD_105":{"address":5729576,"default_item":3,"flag":0},"POKEDEX_REWARD_106":{"address":5729578,"default_item":3,"flag":0},"POKEDEX_REWARD_107":{"address":5729580,"default_item":3,"flag":0},"POKEDEX_REWARD_108":{"address":5729582,"default_item":3,"flag":0},"POKEDEX_REWARD_109":{"address":5729584,"default_item":3,"flag":0},"POKEDEX_REWARD_110":{"address":5729586,"default_item":3,"flag":0},"POKEDEX_REWARD_111":{"address":5729588,"default_item":3,"flag":0},"POKEDEX_REWARD_112":{"address":5729590,"default_item":3,"flag":0},"POKEDEX_REWARD_113":{"address":5729592,"default_item":3,"flag":0},"POKEDEX_REWARD_114":{"address":5729594,"default_item":3,"flag":0},"POKEDEX_REWARD_115":{"address":5729596,"default_item":3,"flag":0},"POKEDEX_REWARD_116":{"address":5729598,"default_item":3,"flag":0},"POKEDEX_REWARD_117":{"address":5729600,"default_item":3,"flag":0},"POKEDEX_REWARD_118":{"address":5729602,"default_item":3,"flag":0},"POKEDEX_REWARD_119":{"address":5729604,"default_item":3,"flag":0},"POKEDEX_REWARD_120":{"address":5729606,"default_item":3,"flag":0},"POKEDEX_REWARD_121":{"address":5729608,"default_item":3,"flag":0},"POKEDEX_REWARD_122":{"address":5729610,"default_item":3,"flag":0},"POKEDEX_REWARD_123":{"address":5729612,"default_item":3,"flag":0},"POKEDEX_REWARD_124":{"address":5729614,"default_item":3,"flag":0},"POKEDEX_REWARD_125":{"address":5729616,"default_item":3,"flag":0},"POKEDEX_REWARD_126":{"address":5729618,"default_item":3,"flag":0},"POKEDEX_REWARD_127":{"address":5729620,"default_item":3,"flag":0},"POKEDEX_REWARD_128":{"address":5729622,"default_item":3,"flag":0},"POKEDEX_REWARD_129":{"address":5729624,"default_item":3,"flag":0},"POKEDEX_REWARD_130":{"address":5729626,"default_item":3,"flag":0},"POKEDEX_REWARD_131":{"address":5729628,"default_item":3,"flag":0},"POKEDEX_REWARD_132":{"address":5729630,"default_item":3,"flag":0},"POKEDEX_REWARD_133":{"address":5729632,"default_item":3,"flag":0},"POKEDEX_REWARD_134":{"address":5729634,"default_item":3,"flag":0},"POKEDEX_REWARD_135":{"address":5729636,"default_item":3,"flag":0},"POKEDEX_REWARD_136":{"address":5729638,"default_item":3,"flag":0},"POKEDEX_REWARD_137":{"address":5729640,"default_item":3,"flag":0},"POKEDEX_REWARD_138":{"address":5729642,"default_item":3,"flag":0},"POKEDEX_REWARD_139":{"address":5729644,"default_item":3,"flag":0},"POKEDEX_REWARD_140":{"address":5729646,"default_item":3,"flag":0},"POKEDEX_REWARD_141":{"address":5729648,"default_item":3,"flag":0},"POKEDEX_REWARD_142":{"address":5729650,"default_item":3,"flag":0},"POKEDEX_REWARD_143":{"address":5729652,"default_item":3,"flag":0},"POKEDEX_REWARD_144":{"address":5729654,"default_item":3,"flag":0},"POKEDEX_REWARD_145":{"address":5729656,"default_item":3,"flag":0},"POKEDEX_REWARD_146":{"address":5729658,"default_item":3,"flag":0},"POKEDEX_REWARD_147":{"address":5729660,"default_item":3,"flag":0},"POKEDEX_REWARD_148":{"address":5729662,"default_item":3,"flag":0},"POKEDEX_REWARD_149":{"address":5729664,"default_item":3,"flag":0},"POKEDEX_REWARD_150":{"address":5729666,"default_item":3,"flag":0},"POKEDEX_REWARD_151":{"address":5729668,"default_item":3,"flag":0},"POKEDEX_REWARD_152":{"address":5729670,"default_item":3,"flag":0},"POKEDEX_REWARD_153":{"address":5729672,"default_item":3,"flag":0},"POKEDEX_REWARD_154":{"address":5729674,"default_item":3,"flag":0},"POKEDEX_REWARD_155":{"address":5729676,"default_item":3,"flag":0},"POKEDEX_REWARD_156":{"address":5729678,"default_item":3,"flag":0},"POKEDEX_REWARD_157":{"address":5729680,"default_item":3,"flag":0},"POKEDEX_REWARD_158":{"address":5729682,"default_item":3,"flag":0},"POKEDEX_REWARD_159":{"address":5729684,"default_item":3,"flag":0},"POKEDEX_REWARD_160":{"address":5729686,"default_item":3,"flag":0},"POKEDEX_REWARD_161":{"address":5729688,"default_item":3,"flag":0},"POKEDEX_REWARD_162":{"address":5729690,"default_item":3,"flag":0},"POKEDEX_REWARD_163":{"address":5729692,"default_item":3,"flag":0},"POKEDEX_REWARD_164":{"address":5729694,"default_item":3,"flag":0},"POKEDEX_REWARD_165":{"address":5729696,"default_item":3,"flag":0},"POKEDEX_REWARD_166":{"address":5729698,"default_item":3,"flag":0},"POKEDEX_REWARD_167":{"address":5729700,"default_item":3,"flag":0},"POKEDEX_REWARD_168":{"address":5729702,"default_item":3,"flag":0},"POKEDEX_REWARD_169":{"address":5729704,"default_item":3,"flag":0},"POKEDEX_REWARD_170":{"address":5729706,"default_item":3,"flag":0},"POKEDEX_REWARD_171":{"address":5729708,"default_item":3,"flag":0},"POKEDEX_REWARD_172":{"address":5729710,"default_item":3,"flag":0},"POKEDEX_REWARD_173":{"address":5729712,"default_item":3,"flag":0},"POKEDEX_REWARD_174":{"address":5729714,"default_item":3,"flag":0},"POKEDEX_REWARD_175":{"address":5729716,"default_item":3,"flag":0},"POKEDEX_REWARD_176":{"address":5729718,"default_item":3,"flag":0},"POKEDEX_REWARD_177":{"address":5729720,"default_item":3,"flag":0},"POKEDEX_REWARD_178":{"address":5729722,"default_item":3,"flag":0},"POKEDEX_REWARD_179":{"address":5729724,"default_item":3,"flag":0},"POKEDEX_REWARD_180":{"address":5729726,"default_item":3,"flag":0},"POKEDEX_REWARD_181":{"address":5729728,"default_item":3,"flag":0},"POKEDEX_REWARD_182":{"address":5729730,"default_item":3,"flag":0},"POKEDEX_REWARD_183":{"address":5729732,"default_item":3,"flag":0},"POKEDEX_REWARD_184":{"address":5729734,"default_item":3,"flag":0},"POKEDEX_REWARD_185":{"address":5729736,"default_item":3,"flag":0},"POKEDEX_REWARD_186":{"address":5729738,"default_item":3,"flag":0},"POKEDEX_REWARD_187":{"address":5729740,"default_item":3,"flag":0},"POKEDEX_REWARD_188":{"address":5729742,"default_item":3,"flag":0},"POKEDEX_REWARD_189":{"address":5729744,"default_item":3,"flag":0},"POKEDEX_REWARD_190":{"address":5729746,"default_item":3,"flag":0},"POKEDEX_REWARD_191":{"address":5729748,"default_item":3,"flag":0},"POKEDEX_REWARD_192":{"address":5729750,"default_item":3,"flag":0},"POKEDEX_REWARD_193":{"address":5729752,"default_item":3,"flag":0},"POKEDEX_REWARD_194":{"address":5729754,"default_item":3,"flag":0},"POKEDEX_REWARD_195":{"address":5729756,"default_item":3,"flag":0},"POKEDEX_REWARD_196":{"address":5729758,"default_item":3,"flag":0},"POKEDEX_REWARD_197":{"address":5729760,"default_item":3,"flag":0},"POKEDEX_REWARD_198":{"address":5729762,"default_item":3,"flag":0},"POKEDEX_REWARD_199":{"address":5729764,"default_item":3,"flag":0},"POKEDEX_REWARD_200":{"address":5729766,"default_item":3,"flag":0},"POKEDEX_REWARD_201":{"address":5729768,"default_item":3,"flag":0},"POKEDEX_REWARD_202":{"address":5729770,"default_item":3,"flag":0},"POKEDEX_REWARD_203":{"address":5729772,"default_item":3,"flag":0},"POKEDEX_REWARD_204":{"address":5729774,"default_item":3,"flag":0},"POKEDEX_REWARD_205":{"address":5729776,"default_item":3,"flag":0},"POKEDEX_REWARD_206":{"address":5729778,"default_item":3,"flag":0},"POKEDEX_REWARD_207":{"address":5729780,"default_item":3,"flag":0},"POKEDEX_REWARD_208":{"address":5729782,"default_item":3,"flag":0},"POKEDEX_REWARD_209":{"address":5729784,"default_item":3,"flag":0},"POKEDEX_REWARD_210":{"address":5729786,"default_item":3,"flag":0},"POKEDEX_REWARD_211":{"address":5729788,"default_item":3,"flag":0},"POKEDEX_REWARD_212":{"address":5729790,"default_item":3,"flag":0},"POKEDEX_REWARD_213":{"address":5729792,"default_item":3,"flag":0},"POKEDEX_REWARD_214":{"address":5729794,"default_item":3,"flag":0},"POKEDEX_REWARD_215":{"address":5729796,"default_item":3,"flag":0},"POKEDEX_REWARD_216":{"address":5729798,"default_item":3,"flag":0},"POKEDEX_REWARD_217":{"address":5729800,"default_item":3,"flag":0},"POKEDEX_REWARD_218":{"address":5729802,"default_item":3,"flag":0},"POKEDEX_REWARD_219":{"address":5729804,"default_item":3,"flag":0},"POKEDEX_REWARD_220":{"address":5729806,"default_item":3,"flag":0},"POKEDEX_REWARD_221":{"address":5729808,"default_item":3,"flag":0},"POKEDEX_REWARD_222":{"address":5729810,"default_item":3,"flag":0},"POKEDEX_REWARD_223":{"address":5729812,"default_item":3,"flag":0},"POKEDEX_REWARD_224":{"address":5729814,"default_item":3,"flag":0},"POKEDEX_REWARD_225":{"address":5729816,"default_item":3,"flag":0},"POKEDEX_REWARD_226":{"address":5729818,"default_item":3,"flag":0},"POKEDEX_REWARD_227":{"address":5729820,"default_item":3,"flag":0},"POKEDEX_REWARD_228":{"address":5729822,"default_item":3,"flag":0},"POKEDEX_REWARD_229":{"address":5729824,"default_item":3,"flag":0},"POKEDEX_REWARD_230":{"address":5729826,"default_item":3,"flag":0},"POKEDEX_REWARD_231":{"address":5729828,"default_item":3,"flag":0},"POKEDEX_REWARD_232":{"address":5729830,"default_item":3,"flag":0},"POKEDEX_REWARD_233":{"address":5729832,"default_item":3,"flag":0},"POKEDEX_REWARD_234":{"address":5729834,"default_item":3,"flag":0},"POKEDEX_REWARD_235":{"address":5729836,"default_item":3,"flag":0},"POKEDEX_REWARD_236":{"address":5729838,"default_item":3,"flag":0},"POKEDEX_REWARD_237":{"address":5729840,"default_item":3,"flag":0},"POKEDEX_REWARD_238":{"address":5729842,"default_item":3,"flag":0},"POKEDEX_REWARD_239":{"address":5729844,"default_item":3,"flag":0},"POKEDEX_REWARD_240":{"address":5729846,"default_item":3,"flag":0},"POKEDEX_REWARD_241":{"address":5729848,"default_item":3,"flag":0},"POKEDEX_REWARD_242":{"address":5729850,"default_item":3,"flag":0},"POKEDEX_REWARD_243":{"address":5729852,"default_item":3,"flag":0},"POKEDEX_REWARD_244":{"address":5729854,"default_item":3,"flag":0},"POKEDEX_REWARD_245":{"address":5729856,"default_item":3,"flag":0},"POKEDEX_REWARD_246":{"address":5729858,"default_item":3,"flag":0},"POKEDEX_REWARD_247":{"address":5729860,"default_item":3,"flag":0},"POKEDEX_REWARD_248":{"address":5729862,"default_item":3,"flag":0},"POKEDEX_REWARD_249":{"address":5729864,"default_item":3,"flag":0},"POKEDEX_REWARD_250":{"address":5729866,"default_item":3,"flag":0},"POKEDEX_REWARD_251":{"address":5729868,"default_item":3,"flag":0},"POKEDEX_REWARD_252":{"address":5729870,"default_item":3,"flag":0},"POKEDEX_REWARD_253":{"address":5729872,"default_item":3,"flag":0},"POKEDEX_REWARD_254":{"address":5729874,"default_item":3,"flag":0},"POKEDEX_REWARD_255":{"address":5729876,"default_item":3,"flag":0},"POKEDEX_REWARD_256":{"address":5729878,"default_item":3,"flag":0},"POKEDEX_REWARD_257":{"address":5729880,"default_item":3,"flag":0},"POKEDEX_REWARD_258":{"address":5729882,"default_item":3,"flag":0},"POKEDEX_REWARD_259":{"address":5729884,"default_item":3,"flag":0},"POKEDEX_REWARD_260":{"address":5729886,"default_item":3,"flag":0},"POKEDEX_REWARD_261":{"address":5729888,"default_item":3,"flag":0},"POKEDEX_REWARD_262":{"address":5729890,"default_item":3,"flag":0},"POKEDEX_REWARD_263":{"address":5729892,"default_item":3,"flag":0},"POKEDEX_REWARD_264":{"address":5729894,"default_item":3,"flag":0},"POKEDEX_REWARD_265":{"address":5729896,"default_item":3,"flag":0},"POKEDEX_REWARD_266":{"address":5729898,"default_item":3,"flag":0},"POKEDEX_REWARD_267":{"address":5729900,"default_item":3,"flag":0},"POKEDEX_REWARD_268":{"address":5729902,"default_item":3,"flag":0},"POKEDEX_REWARD_269":{"address":5729904,"default_item":3,"flag":0},"POKEDEX_REWARD_270":{"address":5729906,"default_item":3,"flag":0},"POKEDEX_REWARD_271":{"address":5729908,"default_item":3,"flag":0},"POKEDEX_REWARD_272":{"address":5729910,"default_item":3,"flag":0},"POKEDEX_REWARD_273":{"address":5729912,"default_item":3,"flag":0},"POKEDEX_REWARD_274":{"address":5729914,"default_item":3,"flag":0},"POKEDEX_REWARD_275":{"address":5729916,"default_item":3,"flag":0},"POKEDEX_REWARD_276":{"address":5729918,"default_item":3,"flag":0},"POKEDEX_REWARD_277":{"address":5729920,"default_item":3,"flag":0},"POKEDEX_REWARD_278":{"address":5729922,"default_item":3,"flag":0},"POKEDEX_REWARD_279":{"address":5729924,"default_item":3,"flag":0},"POKEDEX_REWARD_280":{"address":5729926,"default_item":3,"flag":0},"POKEDEX_REWARD_281":{"address":5729928,"default_item":3,"flag":0},"POKEDEX_REWARD_282":{"address":5729930,"default_item":3,"flag":0},"POKEDEX_REWARD_283":{"address":5729932,"default_item":3,"flag":0},"POKEDEX_REWARD_284":{"address":5729934,"default_item":3,"flag":0},"POKEDEX_REWARD_285":{"address":5729936,"default_item":3,"flag":0},"POKEDEX_REWARD_286":{"address":5729938,"default_item":3,"flag":0},"POKEDEX_REWARD_287":{"address":5729940,"default_item":3,"flag":0},"POKEDEX_REWARD_288":{"address":5729942,"default_item":3,"flag":0},"POKEDEX_REWARD_289":{"address":5729944,"default_item":3,"flag":0},"POKEDEX_REWARD_290":{"address":5729946,"default_item":3,"flag":0},"POKEDEX_REWARD_291":{"address":5729948,"default_item":3,"flag":0},"POKEDEX_REWARD_292":{"address":5729950,"default_item":3,"flag":0},"POKEDEX_REWARD_293":{"address":5729952,"default_item":3,"flag":0},"POKEDEX_REWARD_294":{"address":5729954,"default_item":3,"flag":0},"POKEDEX_REWARD_295":{"address":5729956,"default_item":3,"flag":0},"POKEDEX_REWARD_296":{"address":5729958,"default_item":3,"flag":0},"POKEDEX_REWARD_297":{"address":5729960,"default_item":3,"flag":0},"POKEDEX_REWARD_298":{"address":5729962,"default_item":3,"flag":0},"POKEDEX_REWARD_299":{"address":5729964,"default_item":3,"flag":0},"POKEDEX_REWARD_300":{"address":5729966,"default_item":3,"flag":0},"POKEDEX_REWARD_301":{"address":5729968,"default_item":3,"flag":0},"POKEDEX_REWARD_302":{"address":5729970,"default_item":3,"flag":0},"POKEDEX_REWARD_303":{"address":5729972,"default_item":3,"flag":0},"POKEDEX_REWARD_304":{"address":5729974,"default_item":3,"flag":0},"POKEDEX_REWARD_305":{"address":5729976,"default_item":3,"flag":0},"POKEDEX_REWARD_306":{"address":5729978,"default_item":3,"flag":0},"POKEDEX_REWARD_307":{"address":5729980,"default_item":3,"flag":0},"POKEDEX_REWARD_308":{"address":5729982,"default_item":3,"flag":0},"POKEDEX_REWARD_309":{"address":5729984,"default_item":3,"flag":0},"POKEDEX_REWARD_310":{"address":5729986,"default_item":3,"flag":0},"POKEDEX_REWARD_311":{"address":5729988,"default_item":3,"flag":0},"POKEDEX_REWARD_312":{"address":5729990,"default_item":3,"flag":0},"POKEDEX_REWARD_313":{"address":5729992,"default_item":3,"flag":0},"POKEDEX_REWARD_314":{"address":5729994,"default_item":3,"flag":0},"POKEDEX_REWARD_315":{"address":5729996,"default_item":3,"flag":0},"POKEDEX_REWARD_316":{"address":5729998,"default_item":3,"flag":0},"POKEDEX_REWARD_317":{"address":5730000,"default_item":3,"flag":0},"POKEDEX_REWARD_318":{"address":5730002,"default_item":3,"flag":0},"POKEDEX_REWARD_319":{"address":5730004,"default_item":3,"flag":0},"POKEDEX_REWARD_320":{"address":5730006,"default_item":3,"flag":0},"POKEDEX_REWARD_321":{"address":5730008,"default_item":3,"flag":0},"POKEDEX_REWARD_322":{"address":5730010,"default_item":3,"flag":0},"POKEDEX_REWARD_323":{"address":5730012,"default_item":3,"flag":0},"POKEDEX_REWARD_324":{"address":5730014,"default_item":3,"flag":0},"POKEDEX_REWARD_325":{"address":5730016,"default_item":3,"flag":0},"POKEDEX_REWARD_326":{"address":5730018,"default_item":3,"flag":0},"POKEDEX_REWARD_327":{"address":5730020,"default_item":3,"flag":0},"POKEDEX_REWARD_328":{"address":5730022,"default_item":3,"flag":0},"POKEDEX_REWARD_329":{"address":5730024,"default_item":3,"flag":0},"POKEDEX_REWARD_330":{"address":5730026,"default_item":3,"flag":0},"POKEDEX_REWARD_331":{"address":5730028,"default_item":3,"flag":0},"POKEDEX_REWARD_332":{"address":5730030,"default_item":3,"flag":0},"POKEDEX_REWARD_333":{"address":5730032,"default_item":3,"flag":0},"POKEDEX_REWARD_334":{"address":5730034,"default_item":3,"flag":0},"POKEDEX_REWARD_335":{"address":5730036,"default_item":3,"flag":0},"POKEDEX_REWARD_336":{"address":5730038,"default_item":3,"flag":0},"POKEDEX_REWARD_337":{"address":5730040,"default_item":3,"flag":0},"POKEDEX_REWARD_338":{"address":5730042,"default_item":3,"flag":0},"POKEDEX_REWARD_339":{"address":5730044,"default_item":3,"flag":0},"POKEDEX_REWARD_340":{"address":5730046,"default_item":3,"flag":0},"POKEDEX_REWARD_341":{"address":5730048,"default_item":3,"flag":0},"POKEDEX_REWARD_342":{"address":5730050,"default_item":3,"flag":0},"POKEDEX_REWARD_343":{"address":5730052,"default_item":3,"flag":0},"POKEDEX_REWARD_344":{"address":5730054,"default_item":3,"flag":0},"POKEDEX_REWARD_345":{"address":5730056,"default_item":3,"flag":0},"POKEDEX_REWARD_346":{"address":5730058,"default_item":3,"flag":0},"POKEDEX_REWARD_347":{"address":5730060,"default_item":3,"flag":0},"POKEDEX_REWARD_348":{"address":5730062,"default_item":3,"flag":0},"POKEDEX_REWARD_349":{"address":5730064,"default_item":3,"flag":0},"POKEDEX_REWARD_350":{"address":5730066,"default_item":3,"flag":0},"POKEDEX_REWARD_351":{"address":5730068,"default_item":3,"flag":0},"POKEDEX_REWARD_352":{"address":5730070,"default_item":3,"flag":0},"POKEDEX_REWARD_353":{"address":5730072,"default_item":3,"flag":0},"POKEDEX_REWARD_354":{"address":5730074,"default_item":3,"flag":0},"POKEDEX_REWARD_355":{"address":5730076,"default_item":3,"flag":0},"POKEDEX_REWARD_356":{"address":5730078,"default_item":3,"flag":0},"POKEDEX_REWARD_357":{"address":5730080,"default_item":3,"flag":0},"POKEDEX_REWARD_358":{"address":5730082,"default_item":3,"flag":0},"POKEDEX_REWARD_359":{"address":5730084,"default_item":3,"flag":0},"POKEDEX_REWARD_360":{"address":5730086,"default_item":3,"flag":0},"POKEDEX_REWARD_361":{"address":5730088,"default_item":3,"flag":0},"POKEDEX_REWARD_362":{"address":5730090,"default_item":3,"flag":0},"POKEDEX_REWARD_363":{"address":5730092,"default_item":3,"flag":0},"POKEDEX_REWARD_364":{"address":5730094,"default_item":3,"flag":0},"POKEDEX_REWARD_365":{"address":5730096,"default_item":3,"flag":0},"POKEDEX_REWARD_366":{"address":5730098,"default_item":3,"flag":0},"POKEDEX_REWARD_367":{"address":5730100,"default_item":3,"flag":0},"POKEDEX_REWARD_368":{"address":5730102,"default_item":3,"flag":0},"POKEDEX_REWARD_369":{"address":5730104,"default_item":3,"flag":0},"POKEDEX_REWARD_370":{"address":5730106,"default_item":3,"flag":0},"POKEDEX_REWARD_371":{"address":5730108,"default_item":3,"flag":0},"POKEDEX_REWARD_372":{"address":5730110,"default_item":3,"flag":0},"POKEDEX_REWARD_373":{"address":5730112,"default_item":3,"flag":0},"POKEDEX_REWARD_374":{"address":5730114,"default_item":3,"flag":0},"POKEDEX_REWARD_375":{"address":5730116,"default_item":3,"flag":0},"POKEDEX_REWARD_376":{"address":5730118,"default_item":3,"flag":0},"POKEDEX_REWARD_377":{"address":5730120,"default_item":3,"flag":0},"POKEDEX_REWARD_378":{"address":5730122,"default_item":3,"flag":0},"POKEDEX_REWARD_379":{"address":5730124,"default_item":3,"flag":0},"POKEDEX_REWARD_380":{"address":5730126,"default_item":3,"flag":0},"POKEDEX_REWARD_381":{"address":5730128,"default_item":3,"flag":0},"POKEDEX_REWARD_382":{"address":5730130,"default_item":3,"flag":0},"POKEDEX_REWARD_383":{"address":5730132,"default_item":3,"flag":0},"POKEDEX_REWARD_384":{"address":5730134,"default_item":3,"flag":0},"POKEDEX_REWARD_385":{"address":5730136,"default_item":3,"flag":0},"POKEDEX_REWARD_386":{"address":5730138,"default_item":3,"flag":0},"TRAINER_AARON_REWARD":{"address":5602878,"default_item":104,"flag":1677},"TRAINER_ABIGAIL_1_REWARD":{"address":5602800,"default_item":106,"flag":1638},"TRAINER_AIDAN_REWARD":{"address":5603432,"default_item":104,"flag":1954},"TRAINER_AISHA_REWARD":{"address":5603598,"default_item":106,"flag":2037},"TRAINER_ALBERTO_REWARD":{"address":5602108,"default_item":108,"flag":1292},"TRAINER_ALBERT_REWARD":{"address":5602244,"default_item":104,"flag":1360},"TRAINER_ALEXA_REWARD":{"address":5603424,"default_item":104,"flag":1950},"TRAINER_ALEXIA_REWARD":{"address":5602264,"default_item":104,"flag":1370},"TRAINER_ALEX_REWARD":{"address":5602910,"default_item":104,"flag":1693},"TRAINER_ALICE_REWARD":{"address":5602980,"default_item":103,"flag":1728},"TRAINER_ALIX_REWARD":{"address":5603584,"default_item":106,"flag":2030},"TRAINER_ALLEN_REWARD":{"address":5602750,"default_item":103,"flag":1613},"TRAINER_ALLISON_REWARD":{"address":5602858,"default_item":104,"flag":1667},"TRAINER_ALYSSA_REWARD":{"address":5603486,"default_item":106,"flag":1981},"TRAINER_AMY_AND_LIV_1_REWARD":{"address":5603046,"default_item":103,"flag":1761},"TRAINER_ANDREA_REWARD":{"address":5603310,"default_item":106,"flag":1893},"TRAINER_ANDRES_1_REWARD":{"address":5603558,"default_item":104,"flag":2017},"TRAINER_ANDREW_REWARD":{"address":5602756,"default_item":106,"flag":1616},"TRAINER_ANGELICA_REWARD":{"address":5602956,"default_item":104,"flag":1716},"TRAINER_ANGELINA_REWARD":{"address":5603508,"default_item":106,"flag":1992},"TRAINER_ANGELO_REWARD":{"address":5603688,"default_item":104,"flag":2082},"TRAINER_ANNA_AND_MEG_1_REWARD":{"address":5602658,"default_item":106,"flag":1567},"TRAINER_ANNIKA_REWARD":{"address":5603088,"default_item":107,"flag":1782},"TRAINER_ANTHONY_REWARD":{"address":5602788,"default_item":106,"flag":1632},"TRAINER_ARCHIE_REWARD":{"address":5602152,"default_item":107,"flag":1314},"TRAINER_ASHLEY_REWARD":{"address":5603394,"default_item":106,"flag":1935},"TRAINER_ATHENA_REWARD":{"address":5603238,"default_item":104,"flag":1857},"TRAINER_ATSUSHI_REWARD":{"address":5602464,"default_item":104,"flag":1470},"TRAINER_AURON_REWARD":{"address":5603096,"default_item":104,"flag":1786},"TRAINER_AUSTINA_REWARD":{"address":5602200,"default_item":103,"flag":1338},"TRAINER_AUTUMN_REWARD":{"address":5602518,"default_item":106,"flag":1497},"TRAINER_AXLE_REWARD":{"address":5602490,"default_item":108,"flag":1483},"TRAINER_BARNY_REWARD":{"address":5602770,"default_item":104,"flag":1623},"TRAINER_BARRY_REWARD":{"address":5602410,"default_item":106,"flag":1443},"TRAINER_BEAU_REWARD":{"address":5602508,"default_item":106,"flag":1492},"TRAINER_BECKY_REWARD":{"address":5603024,"default_item":106,"flag":1750},"TRAINER_BECK_REWARD":{"address":5602912,"default_item":104,"flag":1694},"TRAINER_BENJAMIN_1_REWARD":{"address":5602790,"default_item":106,"flag":1633},"TRAINER_BEN_REWARD":{"address":5602730,"default_item":106,"flag":1603},"TRAINER_BERKE_REWARD":{"address":5602232,"default_item":104,"flag":1354},"TRAINER_BERNIE_1_REWARD":{"address":5602496,"default_item":106,"flag":1486},"TRAINER_BETHANY_REWARD":{"address":5602686,"default_item":107,"flag":1581},"TRAINER_BETH_REWARD":{"address":5602974,"default_item":103,"flag":1725},"TRAINER_BEVERLY_REWARD":{"address":5602966,"default_item":103,"flag":1721},"TRAINER_BIANCA_REWARD":{"address":5603496,"default_item":106,"flag":1986},"TRAINER_BILLY_REWARD":{"address":5602722,"default_item":103,"flag":1599},"TRAINER_BLAKE_REWARD":{"address":5602554,"default_item":108,"flag":1515},"TRAINER_BRANDEN_REWARD":{"address":5603574,"default_item":106,"flag":2025},"TRAINER_BRANDI_REWARD":{"address":5603596,"default_item":106,"flag":2036},"TRAINER_BRAWLY_1_REWARD":{"address":5602616,"default_item":104,"flag":1546},"TRAINER_BRAXTON_REWARD":{"address":5602234,"default_item":104,"flag":1355},"TRAINER_BRENDAN_LILYCOVE_MUDKIP_REWARD":{"address":5603406,"default_item":104,"flag":1941},"TRAINER_BRENDAN_LILYCOVE_TORCHIC_REWARD":{"address":5603410,"default_item":104,"flag":1943},"TRAINER_BRENDAN_LILYCOVE_TREECKO_REWARD":{"address":5603408,"default_item":104,"flag":1942},"TRAINER_BRENDAN_ROUTE_103_MUDKIP_REWARD":{"address":5603124,"default_item":106,"flag":1800},"TRAINER_BRENDAN_ROUTE_103_TORCHIC_REWARD":{"address":5603136,"default_item":106,"flag":1806},"TRAINER_BRENDAN_ROUTE_103_TREECKO_REWARD":{"address":5603130,"default_item":106,"flag":1803},"TRAINER_BRENDAN_ROUTE_110_MUDKIP_REWARD":{"address":5603126,"default_item":104,"flag":1801},"TRAINER_BRENDAN_ROUTE_110_TORCHIC_REWARD":{"address":5603138,"default_item":104,"flag":1807},"TRAINER_BRENDAN_ROUTE_110_TREECKO_REWARD":{"address":5603132,"default_item":104,"flag":1804},"TRAINER_BRENDAN_ROUTE_119_MUDKIP_REWARD":{"address":5603128,"default_item":104,"flag":1802},"TRAINER_BRENDAN_ROUTE_119_TORCHIC_REWARD":{"address":5603140,"default_item":104,"flag":1808},"TRAINER_BRENDAN_ROUTE_119_TREECKO_REWARD":{"address":5603134,"default_item":104,"flag":1805},"TRAINER_BRENDAN_RUSTBORO_MUDKIP_REWARD":{"address":5603270,"default_item":108,"flag":1873},"TRAINER_BRENDAN_RUSTBORO_TORCHIC_REWARD":{"address":5603282,"default_item":108,"flag":1879},"TRAINER_BRENDAN_RUSTBORO_TREECKO_REWARD":{"address":5603268,"default_item":108,"flag":1872},"TRAINER_BRENDA_REWARD":{"address":5602992,"default_item":106,"flag":1734},"TRAINER_BRENDEN_REWARD":{"address":5603228,"default_item":106,"flag":1852},"TRAINER_BRENT_REWARD":{"address":5602530,"default_item":104,"flag":1503},"TRAINER_BRIANNA_REWARD":{"address":5602320,"default_item":110,"flag":1398},"TRAINER_BRICE_REWARD":{"address":5603336,"default_item":106,"flag":1906},"TRAINER_BRIDGET_REWARD":{"address":5602342,"default_item":107,"flag":1409},"TRAINER_BROOKE_1_REWARD":{"address":5602272,"default_item":108,"flag":1374},"TRAINER_BRYANT_REWARD":{"address":5603576,"default_item":106,"flag":2026},"TRAINER_BRYAN_REWARD":{"address":5603572,"default_item":104,"flag":2024},"TRAINER_CALE_REWARD":{"address":5603612,"default_item":104,"flag":2044},"TRAINER_CALLIE_REWARD":{"address":5603610,"default_item":106,"flag":2043},"TRAINER_CALVIN_1_REWARD":{"address":5602720,"default_item":103,"flag":1598},"TRAINER_CAMDEN_REWARD":{"address":5602832,"default_item":104,"flag":1654},"TRAINER_CAMERON_1_REWARD":{"address":5602560,"default_item":108,"flag":1518},"TRAINER_CAMRON_REWARD":{"address":5603562,"default_item":104,"flag":2019},"TRAINER_CARLEE_REWARD":{"address":5603012,"default_item":106,"flag":1744},"TRAINER_CAROLINA_REWARD":{"address":5603566,"default_item":104,"flag":2021},"TRAINER_CAROLINE_REWARD":{"address":5602282,"default_item":104,"flag":1379},"TRAINER_CAROL_REWARD":{"address":5603026,"default_item":106,"flag":1751},"TRAINER_CARTER_REWARD":{"address":5602774,"default_item":104,"flag":1625},"TRAINER_CATHERINE_1_REWARD":{"address":5603202,"default_item":104,"flag":1839},"TRAINER_CEDRIC_REWARD":{"address":5603034,"default_item":108,"flag":1755},"TRAINER_CELIA_REWARD":{"address":5603570,"default_item":106,"flag":2023},"TRAINER_CELINA_REWARD":{"address":5603494,"default_item":108,"flag":1985},"TRAINER_CHAD_REWARD":{"address":5602432,"default_item":106,"flag":1454},"TRAINER_CHANDLER_REWARD":{"address":5603480,"default_item":103,"flag":1978},"TRAINER_CHARLIE_REWARD":{"address":5602216,"default_item":103,"flag":1346},"TRAINER_CHARLOTTE_REWARD":{"address":5603512,"default_item":106,"flag":1994},"TRAINER_CHASE_REWARD":{"address":5602840,"default_item":104,"flag":1658},"TRAINER_CHESTER_REWARD":{"address":5602900,"default_item":108,"flag":1688},"TRAINER_CHIP_REWARD":{"address":5602174,"default_item":104,"flag":1325},"TRAINER_CHRIS_REWARD":{"address":5603470,"default_item":108,"flag":1973},"TRAINER_CINDY_1_REWARD":{"address":5602312,"default_item":104,"flag":1394},"TRAINER_CLARENCE_REWARD":{"address":5603244,"default_item":106,"flag":1860},"TRAINER_CLARISSA_REWARD":{"address":5602954,"default_item":104,"flag":1715},"TRAINER_CLARK_REWARD":{"address":5603346,"default_item":106,"flag":1911},"TRAINER_CLAUDE_REWARD":{"address":5602760,"default_item":108,"flag":1618},"TRAINER_CLIFFORD_REWARD":{"address":5603252,"default_item":107,"flag":1864},"TRAINER_COBY_REWARD":{"address":5603502,"default_item":106,"flag":1989},"TRAINER_COLE_REWARD":{"address":5602486,"default_item":108,"flag":1481},"TRAINER_COLIN_REWARD":{"address":5602894,"default_item":108,"flag":1685},"TRAINER_COLTON_REWARD":{"address":5602672,"default_item":107,"flag":1574},"TRAINER_CONNIE_REWARD":{"address":5602340,"default_item":107,"flag":1408},"TRAINER_CONOR_REWARD":{"address":5603106,"default_item":104,"flag":1791},"TRAINER_CORY_1_REWARD":{"address":5603564,"default_item":108,"flag":2020},"TRAINER_CRISSY_REWARD":{"address":5603312,"default_item":106,"flag":1894},"TRAINER_CRISTIAN_REWARD":{"address":5603232,"default_item":106,"flag":1854},"TRAINER_CRISTIN_1_REWARD":{"address":5603618,"default_item":104,"flag":2047},"TRAINER_CYNDY_1_REWARD":{"address":5602938,"default_item":106,"flag":1707},"TRAINER_DAISUKE_REWARD":{"address":5602462,"default_item":106,"flag":1469},"TRAINER_DAISY_REWARD":{"address":5602156,"default_item":106,"flag":1316},"TRAINER_DALE_REWARD":{"address":5602766,"default_item":106,"flag":1621},"TRAINER_DALTON_1_REWARD":{"address":5602476,"default_item":106,"flag":1476},"TRAINER_DANA_REWARD":{"address":5603000,"default_item":106,"flag":1738},"TRAINER_DANIELLE_REWARD":{"address":5603384,"default_item":106,"flag":1930},"TRAINER_DAPHNE_REWARD":{"address":5602314,"default_item":110,"flag":1395},"TRAINER_DARCY_REWARD":{"address":5603550,"default_item":104,"flag":2013},"TRAINER_DARIAN_REWARD":{"address":5603476,"default_item":106,"flag":1976},"TRAINER_DARIUS_REWARD":{"address":5603690,"default_item":108,"flag":2083},"TRAINER_DARRIN_REWARD":{"address":5602392,"default_item":103,"flag":1434},"TRAINER_DAVID_REWARD":{"address":5602400,"default_item":103,"flag":1438},"TRAINER_DAVIS_REWARD":{"address":5603162,"default_item":106,"flag":1819},"TRAINER_DAWSON_REWARD":{"address":5603472,"default_item":104,"flag":1974},"TRAINER_DAYTON_REWARD":{"address":5603604,"default_item":108,"flag":2040},"TRAINER_DEANDRE_REWARD":{"address":5603514,"default_item":103,"flag":1995},"TRAINER_DEAN_REWARD":{"address":5602412,"default_item":103,"flag":1444},"TRAINER_DEBRA_REWARD":{"address":5603004,"default_item":106,"flag":1740},"TRAINER_DECLAN_REWARD":{"address":5602114,"default_item":106,"flag":1295},"TRAINER_DEMETRIUS_REWARD":{"address":5602834,"default_item":106,"flag":1655},"TRAINER_DENISE_REWARD":{"address":5602972,"default_item":103,"flag":1724},"TRAINER_DEREK_REWARD":{"address":5602538,"default_item":108,"flag":1507},"TRAINER_DEVAN_REWARD":{"address":5603590,"default_item":106,"flag":2033},"TRAINER_DEZ_AND_LUKE_REWARD":{"address":5603364,"default_item":108,"flag":1920},"TRAINER_DIANA_1_REWARD":{"address":5603032,"default_item":106,"flag":1754},"TRAINER_DIANNE_REWARD":{"address":5602918,"default_item":104,"flag":1697},"TRAINER_DILLON_REWARD":{"address":5602738,"default_item":106,"flag":1607},"TRAINER_DOMINIK_REWARD":{"address":5602388,"default_item":103,"flag":1432},"TRAINER_DONALD_REWARD":{"address":5602532,"default_item":104,"flag":1504},"TRAINER_DONNY_REWARD":{"address":5602852,"default_item":104,"flag":1664},"TRAINER_DOUGLAS_REWARD":{"address":5602390,"default_item":103,"flag":1433},"TRAINER_DOUG_REWARD":{"address":5603320,"default_item":106,"flag":1898},"TRAINER_DRAKE_REWARD":{"address":5602612,"default_item":110,"flag":1544},"TRAINER_DREW_REWARD":{"address":5602506,"default_item":106,"flag":1491},"TRAINER_DUNCAN_REWARD":{"address":5603076,"default_item":108,"flag":1776},"TRAINER_DUSTY_1_REWARD":{"address":5602172,"default_item":104,"flag":1324},"TRAINER_DWAYNE_REWARD":{"address":5603070,"default_item":106,"flag":1773},"TRAINER_DYLAN_1_REWARD":{"address":5602812,"default_item":106,"flag":1644},"TRAINER_EDGAR_REWARD":{"address":5602242,"default_item":104,"flag":1359},"TRAINER_EDMOND_REWARD":{"address":5603066,"default_item":106,"flag":1771},"TRAINER_EDWARDO_REWARD":{"address":5602892,"default_item":108,"flag":1684},"TRAINER_EDWARD_REWARD":{"address":5602548,"default_item":106,"flag":1512},"TRAINER_EDWIN_1_REWARD":{"address":5603108,"default_item":108,"flag":1792},"TRAINER_ED_REWARD":{"address":5602110,"default_item":104,"flag":1293},"TRAINER_ELIJAH_REWARD":{"address":5603568,"default_item":108,"flag":2022},"TRAINER_ELI_REWARD":{"address":5603086,"default_item":108,"flag":1781},"TRAINER_ELLIOT_1_REWARD":{"address":5602762,"default_item":106,"flag":1619},"TRAINER_ERIC_REWARD":{"address":5603348,"default_item":108,"flag":1912},"TRAINER_ERNEST_1_REWARD":{"address":5603068,"default_item":104,"flag":1772},"TRAINER_ETHAN_1_REWARD":{"address":5602516,"default_item":106,"flag":1496},"TRAINER_FABIAN_REWARD":{"address":5603602,"default_item":108,"flag":2039},"TRAINER_FELIX_REWARD":{"address":5602160,"default_item":104,"flag":1318},"TRAINER_FERNANDO_1_REWARD":{"address":5602474,"default_item":108,"flag":1475},"TRAINER_FLANNERY_1_REWARD":{"address":5602620,"default_item":107,"flag":1548},"TRAINER_FLINT_REWARD":{"address":5603392,"default_item":106,"flag":1934},"TRAINER_FOSTER_REWARD":{"address":5602176,"default_item":104,"flag":1326},"TRAINER_FRANKLIN_REWARD":{"address":5602424,"default_item":106,"flag":1450},"TRAINER_FREDRICK_REWARD":{"address":5602142,"default_item":104,"flag":1309},"TRAINER_GABRIELLE_1_REWARD":{"address":5602102,"default_item":104,"flag":1289},"TRAINER_GARRET_REWARD":{"address":5602360,"default_item":110,"flag":1418},"TRAINER_GARRISON_REWARD":{"address":5603178,"default_item":104,"flag":1827},"TRAINER_GEORGE_REWARD":{"address":5602230,"default_item":104,"flag":1353},"TRAINER_GERALD_REWARD":{"address":5603380,"default_item":104,"flag":1928},"TRAINER_GILBERT_REWARD":{"address":5602422,"default_item":106,"flag":1449},"TRAINER_GINA_AND_MIA_1_REWARD":{"address":5603050,"default_item":103,"flag":1763},"TRAINER_GLACIA_REWARD":{"address":5602610,"default_item":110,"flag":1543},"TRAINER_GRACE_REWARD":{"address":5602984,"default_item":106,"flag":1730},"TRAINER_GREG_REWARD":{"address":5603322,"default_item":106,"flag":1899},"TRAINER_GRUNT_AQUA_HIDEOUT_1_REWARD":{"address":5602088,"default_item":106,"flag":1282},"TRAINER_GRUNT_AQUA_HIDEOUT_2_REWARD":{"address":5602090,"default_item":106,"flag":1283},"TRAINER_GRUNT_AQUA_HIDEOUT_3_REWARD":{"address":5602092,"default_item":106,"flag":1284},"TRAINER_GRUNT_AQUA_HIDEOUT_4_REWARD":{"address":5602094,"default_item":106,"flag":1285},"TRAINER_GRUNT_AQUA_HIDEOUT_5_REWARD":{"address":5602138,"default_item":106,"flag":1307},"TRAINER_GRUNT_AQUA_HIDEOUT_6_REWARD":{"address":5602140,"default_item":106,"flag":1308},"TRAINER_GRUNT_AQUA_HIDEOUT_7_REWARD":{"address":5602468,"default_item":106,"flag":1472},"TRAINER_GRUNT_AQUA_HIDEOUT_8_REWARD":{"address":5602470,"default_item":106,"flag":1473},"TRAINER_GRUNT_MAGMA_HIDEOUT_10_REWARD":{"address":5603534,"default_item":106,"flag":2005},"TRAINER_GRUNT_MAGMA_HIDEOUT_11_REWARD":{"address":5603536,"default_item":106,"flag":2006},"TRAINER_GRUNT_MAGMA_HIDEOUT_12_REWARD":{"address":5603538,"default_item":106,"flag":2007},"TRAINER_GRUNT_MAGMA_HIDEOUT_13_REWARD":{"address":5603540,"default_item":106,"flag":2008},"TRAINER_GRUNT_MAGMA_HIDEOUT_14_REWARD":{"address":5603542,"default_item":106,"flag":2009},"TRAINER_GRUNT_MAGMA_HIDEOUT_15_REWARD":{"address":5603544,"default_item":106,"flag":2010},"TRAINER_GRUNT_MAGMA_HIDEOUT_16_REWARD":{"address":5603546,"default_item":106,"flag":2011},"TRAINER_GRUNT_MAGMA_HIDEOUT_1_REWARD":{"address":5603516,"default_item":106,"flag":1996},"TRAINER_GRUNT_MAGMA_HIDEOUT_2_REWARD":{"address":5603518,"default_item":106,"flag":1997},"TRAINER_GRUNT_MAGMA_HIDEOUT_3_REWARD":{"address":5603520,"default_item":106,"flag":1998},"TRAINER_GRUNT_MAGMA_HIDEOUT_4_REWARD":{"address":5603522,"default_item":106,"flag":1999},"TRAINER_GRUNT_MAGMA_HIDEOUT_5_REWARD":{"address":5603524,"default_item":106,"flag":2000},"TRAINER_GRUNT_MAGMA_HIDEOUT_6_REWARD":{"address":5603526,"default_item":106,"flag":2001},"TRAINER_GRUNT_MAGMA_HIDEOUT_7_REWARD":{"address":5603528,"default_item":106,"flag":2002},"TRAINER_GRUNT_MAGMA_HIDEOUT_8_REWARD":{"address":5603530,"default_item":106,"flag":2003},"TRAINER_GRUNT_MAGMA_HIDEOUT_9_REWARD":{"address":5603532,"default_item":106,"flag":2004},"TRAINER_GRUNT_MT_CHIMNEY_1_REWARD":{"address":5602376,"default_item":106,"flag":1426},"TRAINER_GRUNT_MT_CHIMNEY_2_REWARD":{"address":5603242,"default_item":106,"flag":1859},"TRAINER_GRUNT_MT_PYRE_1_REWARD":{"address":5602130,"default_item":106,"flag":1303},"TRAINER_GRUNT_MT_PYRE_2_REWARD":{"address":5602132,"default_item":106,"flag":1304},"TRAINER_GRUNT_MT_PYRE_3_REWARD":{"address":5602134,"default_item":106,"flag":1305},"TRAINER_GRUNT_MT_PYRE_4_REWARD":{"address":5603222,"default_item":106,"flag":1849},"TRAINER_GRUNT_MUSEUM_1_REWARD":{"address":5602124,"default_item":106,"flag":1300},"TRAINER_GRUNT_MUSEUM_2_REWARD":{"address":5602126,"default_item":106,"flag":1301},"TRAINER_GRUNT_PETALBURG_WOODS_REWARD":{"address":5602104,"default_item":103,"flag":1290},"TRAINER_GRUNT_RUSTURF_TUNNEL_REWARD":{"address":5602116,"default_item":103,"flag":1296},"TRAINER_GRUNT_SEAFLOOR_CAVERN_1_REWARD":{"address":5602096,"default_item":108,"flag":1286},"TRAINER_GRUNT_SEAFLOOR_CAVERN_2_REWARD":{"address":5602098,"default_item":108,"flag":1287},"TRAINER_GRUNT_SEAFLOOR_CAVERN_3_REWARD":{"address":5602100,"default_item":108,"flag":1288},"TRAINER_GRUNT_SEAFLOOR_CAVERN_4_REWARD":{"address":5602112,"default_item":108,"flag":1294},"TRAINER_GRUNT_SEAFLOOR_CAVERN_5_REWARD":{"address":5603218,"default_item":108,"flag":1847},"TRAINER_GRUNT_SPACE_CENTER_1_REWARD":{"address":5602128,"default_item":106,"flag":1302},"TRAINER_GRUNT_SPACE_CENTER_2_REWARD":{"address":5602316,"default_item":106,"flag":1396},"TRAINER_GRUNT_SPACE_CENTER_3_REWARD":{"address":5603256,"default_item":106,"flag":1866},"TRAINER_GRUNT_SPACE_CENTER_4_REWARD":{"address":5603258,"default_item":106,"flag":1867},"TRAINER_GRUNT_SPACE_CENTER_5_REWARD":{"address":5603260,"default_item":106,"flag":1868},"TRAINER_GRUNT_SPACE_CENTER_6_REWARD":{"address":5603262,"default_item":106,"flag":1869},"TRAINER_GRUNT_SPACE_CENTER_7_REWARD":{"address":5603264,"default_item":106,"flag":1870},"TRAINER_GRUNT_WEATHER_INST_1_REWARD":{"address":5602118,"default_item":106,"flag":1297},"TRAINER_GRUNT_WEATHER_INST_2_REWARD":{"address":5602120,"default_item":106,"flag":1298},"TRAINER_GRUNT_WEATHER_INST_3_REWARD":{"address":5602122,"default_item":106,"flag":1299},"TRAINER_GRUNT_WEATHER_INST_4_REWARD":{"address":5602136,"default_item":106,"flag":1306},"TRAINER_GRUNT_WEATHER_INST_5_REWARD":{"address":5603276,"default_item":106,"flag":1876},"TRAINER_GWEN_REWARD":{"address":5602202,"default_item":103,"flag":1339},"TRAINER_HAILEY_REWARD":{"address":5603478,"default_item":103,"flag":1977},"TRAINER_HALEY_1_REWARD":{"address":5603292,"default_item":103,"flag":1884},"TRAINER_HALLE_REWARD":{"address":5603176,"default_item":104,"flag":1826},"TRAINER_HANNAH_REWARD":{"address":5602572,"default_item":108,"flag":1524},"TRAINER_HARRISON_REWARD":{"address":5603240,"default_item":106,"flag":1858},"TRAINER_HAYDEN_REWARD":{"address":5603498,"default_item":106,"flag":1987},"TRAINER_HECTOR_REWARD":{"address":5603110,"default_item":104,"flag":1793},"TRAINER_HEIDI_REWARD":{"address":5603022,"default_item":106,"flag":1749},"TRAINER_HELENE_REWARD":{"address":5603586,"default_item":106,"flag":2031},"TRAINER_HENRY_REWARD":{"address":5603420,"default_item":104,"flag":1948},"TRAINER_HERMAN_REWARD":{"address":5602418,"default_item":106,"flag":1447},"TRAINER_HIDEO_REWARD":{"address":5603386,"default_item":106,"flag":1931},"TRAINER_HITOSHI_REWARD":{"address":5602444,"default_item":104,"flag":1460},"TRAINER_HOPE_REWARD":{"address":5602276,"default_item":104,"flag":1376},"TRAINER_HUDSON_REWARD":{"address":5603104,"default_item":104,"flag":1790},"TRAINER_HUEY_REWARD":{"address":5603064,"default_item":106,"flag":1770},"TRAINER_HUGH_REWARD":{"address":5602882,"default_item":108,"flag":1679},"TRAINER_HUMBERTO_REWARD":{"address":5602888,"default_item":108,"flag":1682},"TRAINER_IMANI_REWARD":{"address":5602968,"default_item":103,"flag":1722},"TRAINER_IRENE_REWARD":{"address":5603036,"default_item":106,"flag":1756},"TRAINER_ISAAC_1_REWARD":{"address":5603160,"default_item":106,"flag":1818},"TRAINER_ISABELLA_REWARD":{"address":5603274,"default_item":104,"flag":1875},"TRAINER_ISABELLE_REWARD":{"address":5603556,"default_item":103,"flag":2016},"TRAINER_ISABEL_1_REWARD":{"address":5602688,"default_item":104,"flag":1582},"TRAINER_ISAIAH_1_REWARD":{"address":5602836,"default_item":104,"flag":1656},"TRAINER_ISOBEL_REWARD":{"address":5602850,"default_item":104,"flag":1663},"TRAINER_IVAN_REWARD":{"address":5602758,"default_item":106,"flag":1617},"TRAINER_JACE_REWARD":{"address":5602492,"default_item":108,"flag":1484},"TRAINER_JACKI_1_REWARD":{"address":5602582,"default_item":108,"flag":1529},"TRAINER_JACKSON_1_REWARD":{"address":5603188,"default_item":104,"flag":1832},"TRAINER_JACK_REWARD":{"address":5602428,"default_item":106,"flag":1452},"TRAINER_JACLYN_REWARD":{"address":5602570,"default_item":106,"flag":1523},"TRAINER_JACOB_REWARD":{"address":5602786,"default_item":106,"flag":1631},"TRAINER_JAIDEN_REWARD":{"address":5603582,"default_item":106,"flag":2029},"TRAINER_JAMES_1_REWARD":{"address":5603326,"default_item":103,"flag":1901},"TRAINER_JANICE_REWARD":{"address":5603294,"default_item":103,"flag":1885},"TRAINER_JANI_REWARD":{"address":5602920,"default_item":103,"flag":1698},"TRAINER_JARED_REWARD":{"address":5602886,"default_item":108,"flag":1681},"TRAINER_JASMINE_REWARD":{"address":5602802,"default_item":103,"flag":1639},"TRAINER_JAYLEN_REWARD":{"address":5602736,"default_item":106,"flag":1606},"TRAINER_JAZMYN_REWARD":{"address":5603090,"default_item":106,"flag":1783},"TRAINER_JEFFREY_1_REWARD":{"address":5602536,"default_item":104,"flag":1506},"TRAINER_JEFF_REWARD":{"address":5602488,"default_item":108,"flag":1482},"TRAINER_JENNA_REWARD":{"address":5603204,"default_item":104,"flag":1840},"TRAINER_JENNIFER_REWARD":{"address":5602274,"default_item":104,"flag":1375},"TRAINER_JENNY_1_REWARD":{"address":5602982,"default_item":106,"flag":1729},"TRAINER_JEROME_REWARD":{"address":5602396,"default_item":103,"flag":1436},"TRAINER_JERRY_1_REWARD":{"address":5602630,"default_item":103,"flag":1553},"TRAINER_JESSICA_1_REWARD":{"address":5602338,"default_item":104,"flag":1407},"TRAINER_JOCELYN_REWARD":{"address":5602934,"default_item":106,"flag":1705},"TRAINER_JODY_REWARD":{"address":5602266,"default_item":104,"flag":1371},"TRAINER_JOEY_REWARD":{"address":5602728,"default_item":103,"flag":1602},"TRAINER_JOHANNA_REWARD":{"address":5603378,"default_item":104,"flag":1927},"TRAINER_JOHNSON_REWARD":{"address":5603592,"default_item":103,"flag":2034},"TRAINER_JOHN_AND_JAY_1_REWARD":{"address":5603446,"default_item":104,"flag":1961},"TRAINER_JONAH_REWARD":{"address":5603418,"default_item":104,"flag":1947},"TRAINER_JONAS_REWARD":{"address":5603092,"default_item":106,"flag":1784},"TRAINER_JONATHAN_REWARD":{"address":5603280,"default_item":104,"flag":1878},"TRAINER_JOSEPH_REWARD":{"address":5603484,"default_item":106,"flag":1980},"TRAINER_JOSE_REWARD":{"address":5603318,"default_item":103,"flag":1897},"TRAINER_JOSH_REWARD":{"address":5602724,"default_item":103,"flag":1600},"TRAINER_JOSUE_REWARD":{"address":5603560,"default_item":108,"flag":2018},"TRAINER_JUAN_1_REWARD":{"address":5602628,"default_item":109,"flag":1552},"TRAINER_JULIE_REWARD":{"address":5602284,"default_item":104,"flag":1380},"TRAINER_JULIO_REWARD":{"address":5603216,"default_item":108,"flag":1846},"TRAINER_KAI_REWARD":{"address":5603510,"default_item":108,"flag":1993},"TRAINER_KALEB_REWARD":{"address":5603482,"default_item":104,"flag":1979},"TRAINER_KARA_REWARD":{"address":5602998,"default_item":106,"flag":1737},"TRAINER_KAREN_1_REWARD":{"address":5602644,"default_item":103,"flag":1560},"TRAINER_KATELYNN_REWARD":{"address":5602734,"default_item":104,"flag":1605},"TRAINER_KATELYN_1_REWARD":{"address":5602856,"default_item":104,"flag":1666},"TRAINER_KATE_AND_JOY_REWARD":{"address":5602656,"default_item":106,"flag":1566},"TRAINER_KATHLEEN_REWARD":{"address":5603250,"default_item":108,"flag":1863},"TRAINER_KATIE_REWARD":{"address":5602994,"default_item":106,"flag":1735},"TRAINER_KAYLA_REWARD":{"address":5602578,"default_item":106,"flag":1527},"TRAINER_KAYLEY_REWARD":{"address":5603094,"default_item":104,"flag":1785},"TRAINER_KEEGAN_REWARD":{"address":5602494,"default_item":108,"flag":1485},"TRAINER_KEIGO_REWARD":{"address":5603388,"default_item":106,"flag":1932},"TRAINER_KELVIN_REWARD":{"address":5603098,"default_item":104,"flag":1787},"TRAINER_KENT_REWARD":{"address":5603324,"default_item":106,"flag":1900},"TRAINER_KEVIN_REWARD":{"address":5602426,"default_item":106,"flag":1451},"TRAINER_KIM_AND_IRIS_REWARD":{"address":5603440,"default_item":106,"flag":1958},"TRAINER_KINDRA_REWARD":{"address":5602296,"default_item":108,"flag":1386},"TRAINER_KIRA_AND_DAN_1_REWARD":{"address":5603368,"default_item":108,"flag":1922},"TRAINER_KIRK_REWARD":{"address":5602466,"default_item":106,"flag":1471},"TRAINER_KIYO_REWARD":{"address":5602446,"default_item":104,"flag":1461},"TRAINER_KOICHI_REWARD":{"address":5602448,"default_item":108,"flag":1462},"TRAINER_KOJI_1_REWARD":{"address":5603428,"default_item":104,"flag":1952},"TRAINER_KYLA_REWARD":{"address":5602970,"default_item":103,"flag":1723},"TRAINER_KYRA_REWARD":{"address":5603580,"default_item":104,"flag":2028},"TRAINER_LAO_1_REWARD":{"address":5602922,"default_item":103,"flag":1699},"TRAINER_LARRY_REWARD":{"address":5602510,"default_item":106,"flag":1493},"TRAINER_LAURA_REWARD":{"address":5602936,"default_item":106,"flag":1706},"TRAINER_LAUREL_REWARD":{"address":5603010,"default_item":106,"flag":1743},"TRAINER_LAWRENCE_REWARD":{"address":5603504,"default_item":106,"flag":1990},"TRAINER_LEAH_REWARD":{"address":5602154,"default_item":108,"flag":1315},"TRAINER_LEA_AND_JED_REWARD":{"address":5603366,"default_item":104,"flag":1921},"TRAINER_LENNY_REWARD":{"address":5603340,"default_item":108,"flag":1908},"TRAINER_LEONARDO_REWARD":{"address":5603236,"default_item":106,"flag":1856},"TRAINER_LEONARD_REWARD":{"address":5603074,"default_item":104,"flag":1775},"TRAINER_LEONEL_REWARD":{"address":5603608,"default_item":104,"flag":2042},"TRAINER_LILA_AND_ROY_1_REWARD":{"address":5603458,"default_item":106,"flag":1967},"TRAINER_LILITH_REWARD":{"address":5603230,"default_item":106,"flag":1853},"TRAINER_LINDA_REWARD":{"address":5603006,"default_item":106,"flag":1741},"TRAINER_LISA_AND_RAY_REWARD":{"address":5603468,"default_item":106,"flag":1972},"TRAINER_LOLA_1_REWARD":{"address":5602198,"default_item":103,"flag":1337},"TRAINER_LORENZO_REWARD":{"address":5603190,"default_item":104,"flag":1833},"TRAINER_LUCAS_1_REWARD":{"address":5603342,"default_item":108,"flag":1909},"TRAINER_LUIS_REWARD":{"address":5602386,"default_item":103,"flag":1431},"TRAINER_LUNG_REWARD":{"address":5602924,"default_item":103,"flag":1700},"TRAINER_LYDIA_1_REWARD":{"address":5603174,"default_item":106,"flag":1825},"TRAINER_LYLE_REWARD":{"address":5603316,"default_item":103,"flag":1896},"TRAINER_MACEY_REWARD":{"address":5603266,"default_item":108,"flag":1871},"TRAINER_MADELINE_1_REWARD":{"address":5602952,"default_item":108,"flag":1714},"TRAINER_MAKAYLA_REWARD":{"address":5603600,"default_item":104,"flag":2038},"TRAINER_MARCEL_REWARD":{"address":5602106,"default_item":104,"flag":1291},"TRAINER_MARCOS_REWARD":{"address":5603488,"default_item":106,"flag":1982},"TRAINER_MARC_REWARD":{"address":5603226,"default_item":106,"flag":1851},"TRAINER_MARIA_1_REWARD":{"address":5602822,"default_item":106,"flag":1649},"TRAINER_MARK_REWARD":{"address":5602374,"default_item":104,"flag":1425},"TRAINER_MARLENE_REWARD":{"address":5603588,"default_item":106,"flag":2032},"TRAINER_MARLEY_REWARD":{"address":5603100,"default_item":104,"flag":1788},"TRAINER_MARY_REWARD":{"address":5602262,"default_item":104,"flag":1369},"TRAINER_MATTHEW_REWARD":{"address":5602398,"default_item":103,"flag":1437},"TRAINER_MATT_REWARD":{"address":5602144,"default_item":104,"flag":1310},"TRAINER_MAURA_REWARD":{"address":5602576,"default_item":108,"flag":1526},"TRAINER_MAXIE_MAGMA_HIDEOUT_REWARD":{"address":5603286,"default_item":107,"flag":1881},"TRAINER_MAXIE_MT_CHIMNEY_REWARD":{"address":5603288,"default_item":104,"flag":1882},"TRAINER_MAY_LILYCOVE_MUDKIP_REWARD":{"address":5603412,"default_item":104,"flag":1944},"TRAINER_MAY_LILYCOVE_TORCHIC_REWARD":{"address":5603416,"default_item":104,"flag":1946},"TRAINER_MAY_LILYCOVE_TREECKO_REWARD":{"address":5603414,"default_item":104,"flag":1945},"TRAINER_MAY_ROUTE_103_MUDKIP_REWARD":{"address":5603142,"default_item":106,"flag":1809},"TRAINER_MAY_ROUTE_103_TORCHIC_REWARD":{"address":5603154,"default_item":106,"flag":1815},"TRAINER_MAY_ROUTE_103_TREECKO_REWARD":{"address":5603148,"default_item":106,"flag":1812},"TRAINER_MAY_ROUTE_110_MUDKIP_REWARD":{"address":5603144,"default_item":104,"flag":1810},"TRAINER_MAY_ROUTE_110_TORCHIC_REWARD":{"address":5603156,"default_item":104,"flag":1816},"TRAINER_MAY_ROUTE_110_TREECKO_REWARD":{"address":5603150,"default_item":104,"flag":1813},"TRAINER_MAY_ROUTE_119_MUDKIP_REWARD":{"address":5603146,"default_item":104,"flag":1811},"TRAINER_MAY_ROUTE_119_TORCHIC_REWARD":{"address":5603158,"default_item":104,"flag":1817},"TRAINER_MAY_ROUTE_119_TREECKO_REWARD":{"address":5603152,"default_item":104,"flag":1814},"TRAINER_MAY_RUSTBORO_MUDKIP_REWARD":{"address":5603284,"default_item":108,"flag":1880},"TRAINER_MAY_RUSTBORO_TORCHIC_REWARD":{"address":5603622,"default_item":108,"flag":2049},"TRAINER_MAY_RUSTBORO_TREECKO_REWARD":{"address":5603620,"default_item":108,"flag":2048},"TRAINER_MELINA_REWARD":{"address":5603594,"default_item":106,"flag":2035},"TRAINER_MELISSA_REWARD":{"address":5602332,"default_item":104,"flag":1404},"TRAINER_MEL_AND_PAUL_REWARD":{"address":5603444,"default_item":108,"flag":1960},"TRAINER_MICAH_REWARD":{"address":5602594,"default_item":107,"flag":1535},"TRAINER_MICHELLE_REWARD":{"address":5602280,"default_item":104,"flag":1378},"TRAINER_MIGUEL_1_REWARD":{"address":5602670,"default_item":104,"flag":1573},"TRAINER_MIKE_2_REWARD":{"address":5603354,"default_item":106,"flag":1915},"TRAINER_MISSY_REWARD":{"address":5602978,"default_item":103,"flag":1727},"TRAINER_MITCHELL_REWARD":{"address":5603164,"default_item":104,"flag":1820},"TRAINER_MIU_AND_YUKI_REWARD":{"address":5603052,"default_item":106,"flag":1764},"TRAINER_MOLLIE_REWARD":{"address":5602358,"default_item":104,"flag":1417},"TRAINER_MYLES_REWARD":{"address":5603614,"default_item":104,"flag":2045},"TRAINER_NANCY_REWARD":{"address":5603028,"default_item":106,"flag":1752},"TRAINER_NAOMI_REWARD":{"address":5602322,"default_item":110,"flag":1399},"TRAINER_NATE_REWARD":{"address":5603248,"default_item":107,"flag":1862},"TRAINER_NED_REWARD":{"address":5602764,"default_item":106,"flag":1620},"TRAINER_NICHOLAS_REWARD":{"address":5603254,"default_item":108,"flag":1865},"TRAINER_NICOLAS_1_REWARD":{"address":5602868,"default_item":104,"flag":1672},"TRAINER_NIKKI_REWARD":{"address":5602990,"default_item":106,"flag":1733},"TRAINER_NOB_1_REWARD":{"address":5602450,"default_item":106,"flag":1463},"TRAINER_NOLAN_REWARD":{"address":5602768,"default_item":108,"flag":1622},"TRAINER_NOLEN_REWARD":{"address":5602406,"default_item":106,"flag":1441},"TRAINER_NORMAN_1_REWARD":{"address":5602622,"default_item":107,"flag":1549},"TRAINER_OLIVIA_REWARD":{"address":5602344,"default_item":107,"flag":1410},"TRAINER_OWEN_REWARD":{"address":5602250,"default_item":104,"flag":1363},"TRAINER_PABLO_1_REWARD":{"address":5602838,"default_item":104,"flag":1657},"TRAINER_PARKER_REWARD":{"address":5602228,"default_item":104,"flag":1352},"TRAINER_PAT_REWARD":{"address":5603616,"default_item":104,"flag":2046},"TRAINER_PAXTON_REWARD":{"address":5603272,"default_item":104,"flag":1874},"TRAINER_PERRY_REWARD":{"address":5602880,"default_item":108,"flag":1678},"TRAINER_PETE_REWARD":{"address":5603554,"default_item":103,"flag":2015},"TRAINER_PHILLIP_REWARD":{"address":5603072,"default_item":104,"flag":1774},"TRAINER_PHIL_REWARD":{"address":5602884,"default_item":108,"flag":1680},"TRAINER_PHOEBE_REWARD":{"address":5602608,"default_item":110,"flag":1542},"TRAINER_PRESLEY_REWARD":{"address":5602890,"default_item":104,"flag":1683},"TRAINER_PRESTON_REWARD":{"address":5602550,"default_item":108,"flag":1513},"TRAINER_QUINCY_REWARD":{"address":5602732,"default_item":104,"flag":1604},"TRAINER_RACHEL_REWARD":{"address":5603606,"default_item":104,"flag":2041},"TRAINER_RANDALL_REWARD":{"address":5602226,"default_item":104,"flag":1351},"TRAINER_REED_REWARD":{"address":5603434,"default_item":106,"flag":1955},"TRAINER_RELI_AND_IAN_REWARD":{"address":5603456,"default_item":106,"flag":1966},"TRAINER_REYNA_REWARD":{"address":5603102,"default_item":108,"flag":1789},"TRAINER_RHETT_REWARD":{"address":5603490,"default_item":106,"flag":1983},"TRAINER_RICHARD_REWARD":{"address":5602416,"default_item":106,"flag":1446},"TRAINER_RICKY_1_REWARD":{"address":5602212,"default_item":103,"flag":1344},"TRAINER_RICK_REWARD":{"address":5603314,"default_item":103,"flag":1895},"TRAINER_RILEY_REWARD":{"address":5603390,"default_item":106,"flag":1933},"TRAINER_ROBERT_1_REWARD":{"address":5602896,"default_item":108,"flag":1686},"TRAINER_RODNEY_REWARD":{"address":5602414,"default_item":106,"flag":1445},"TRAINER_ROGER_REWARD":{"address":5603422,"default_item":104,"flag":1949},"TRAINER_ROLAND_REWARD":{"address":5602404,"default_item":106,"flag":1440},"TRAINER_RONALD_REWARD":{"address":5602784,"default_item":104,"flag":1630},"TRAINER_ROSE_1_REWARD":{"address":5602158,"default_item":106,"flag":1317},"TRAINER_ROXANNE_1_REWARD":{"address":5602614,"default_item":104,"flag":1545},"TRAINER_RUBEN_REWARD":{"address":5603426,"default_item":104,"flag":1951},"TRAINER_SAMANTHA_REWARD":{"address":5602574,"default_item":108,"flag":1525},"TRAINER_SAMUEL_REWARD":{"address":5602246,"default_item":104,"flag":1361},"TRAINER_SANTIAGO_REWARD":{"address":5602420,"default_item":106,"flag":1448},"TRAINER_SARAH_REWARD":{"address":5603474,"default_item":104,"flag":1975},"TRAINER_SAWYER_1_REWARD":{"address":5602086,"default_item":108,"flag":1281},"TRAINER_SHANE_REWARD":{"address":5602512,"default_item":106,"flag":1494},"TRAINER_SHANNON_REWARD":{"address":5602278,"default_item":104,"flag":1377},"TRAINER_SHARON_REWARD":{"address":5602988,"default_item":106,"flag":1732},"TRAINER_SHAWN_REWARD":{"address":5602472,"default_item":106,"flag":1474},"TRAINER_SHAYLA_REWARD":{"address":5603578,"default_item":108,"flag":2027},"TRAINER_SHEILA_REWARD":{"address":5602334,"default_item":104,"flag":1405},"TRAINER_SHELBY_1_REWARD":{"address":5602710,"default_item":108,"flag":1593},"TRAINER_SHELLY_SEAFLOOR_CAVERN_REWARD":{"address":5602150,"default_item":104,"flag":1313},"TRAINER_SHELLY_WEATHER_INSTITUTE_REWARD":{"address":5602148,"default_item":104,"flag":1312},"TRAINER_SHIRLEY_REWARD":{"address":5602336,"default_item":104,"flag":1406},"TRAINER_SIDNEY_REWARD":{"address":5602606,"default_item":110,"flag":1541},"TRAINER_SIENNA_REWARD":{"address":5603002,"default_item":106,"flag":1739},"TRAINER_SIMON_REWARD":{"address":5602214,"default_item":103,"flag":1345},"TRAINER_SOPHIE_REWARD":{"address":5603500,"default_item":106,"flag":1988},"TRAINER_SPENCER_REWARD":{"address":5602402,"default_item":106,"flag":1439},"TRAINER_STAN_REWARD":{"address":5602408,"default_item":106,"flag":1442},"TRAINER_STEVEN_REWARD":{"address":5603692,"default_item":109,"flag":2084},"TRAINER_STEVE_1_REWARD":{"address":5602370,"default_item":104,"flag":1423},"TRAINER_SUSIE_REWARD":{"address":5602996,"default_item":106,"flag":1736},"TRAINER_SYLVIA_REWARD":{"address":5603234,"default_item":108,"flag":1855},"TRAINER_TABITHA_MAGMA_HIDEOUT_REWARD":{"address":5603548,"default_item":104,"flag":2012},"TRAINER_TABITHA_MT_CHIMNEY_REWARD":{"address":5603278,"default_item":108,"flag":1877},"TRAINER_TAKAO_REWARD":{"address":5602442,"default_item":106,"flag":1459},"TRAINER_TAKASHI_REWARD":{"address":5602916,"default_item":106,"flag":1696},"TRAINER_TALIA_REWARD":{"address":5602854,"default_item":104,"flag":1665},"TRAINER_TAMMY_REWARD":{"address":5602298,"default_item":106,"flag":1387},"TRAINER_TANYA_REWARD":{"address":5602986,"default_item":106,"flag":1731},"TRAINER_TARA_REWARD":{"address":5602976,"default_item":103,"flag":1726},"TRAINER_TASHA_REWARD":{"address":5602302,"default_item":108,"flag":1389},"TRAINER_TATE_AND_LIZA_1_REWARD":{"address":5602626,"default_item":109,"flag":1551},"TRAINER_TAYLOR_REWARD":{"address":5602534,"default_item":104,"flag":1505},"TRAINER_THALIA_1_REWARD":{"address":5602372,"default_item":104,"flag":1424},"TRAINER_THOMAS_REWARD":{"address":5602596,"default_item":107,"flag":1536},"TRAINER_TIANA_REWARD":{"address":5603290,"default_item":103,"flag":1883},"TRAINER_TIFFANY_REWARD":{"address":5602346,"default_item":107,"flag":1411},"TRAINER_TIMMY_REWARD":{"address":5602752,"default_item":103,"flag":1614},"TRAINER_TIMOTHY_1_REWARD":{"address":5602698,"default_item":104,"flag":1587},"TRAINER_TISHA_REWARD":{"address":5603436,"default_item":106,"flag":1956},"TRAINER_TOMMY_REWARD":{"address":5602726,"default_item":103,"flag":1601},"TRAINER_TONY_1_REWARD":{"address":5602394,"default_item":103,"flag":1435},"TRAINER_TORI_AND_TIA_REWARD":{"address":5603438,"default_item":103,"flag":1957},"TRAINER_TRAVIS_REWARD":{"address":5602520,"default_item":106,"flag":1498},"TRAINER_TRENT_1_REWARD":{"address":5603338,"default_item":106,"flag":1907},"TRAINER_TYRA_AND_IVY_REWARD":{"address":5603442,"default_item":106,"flag":1959},"TRAINER_TYRON_REWARD":{"address":5603492,"default_item":106,"flag":1984},"TRAINER_VALERIE_1_REWARD":{"address":5602300,"default_item":108,"flag":1388},"TRAINER_VANESSA_REWARD":{"address":5602684,"default_item":104,"flag":1580},"TRAINER_VICKY_REWARD":{"address":5602708,"default_item":108,"flag":1592},"TRAINER_VICTORIA_REWARD":{"address":5602682,"default_item":106,"flag":1579},"TRAINER_VICTOR_REWARD":{"address":5602668,"default_item":106,"flag":1572},"TRAINER_VIOLET_REWARD":{"address":5602162,"default_item":104,"flag":1319},"TRAINER_VIRGIL_REWARD":{"address":5602552,"default_item":108,"flag":1514},"TRAINER_VITO_REWARD":{"address":5602248,"default_item":104,"flag":1362},"TRAINER_VIVIAN_REWARD":{"address":5603382,"default_item":106,"flag":1929},"TRAINER_VIVI_REWARD":{"address":5603296,"default_item":106,"flag":1886},"TRAINER_WADE_REWARD":{"address":5602772,"default_item":106,"flag":1624},"TRAINER_WALLACE_REWARD":{"address":5602754,"default_item":110,"flag":1615},"TRAINER_WALLY_MAUVILLE_REWARD":{"address":5603396,"default_item":108,"flag":1936},"TRAINER_WALLY_VR_1_REWARD":{"address":5603122,"default_item":107,"flag":1799},"TRAINER_WALTER_1_REWARD":{"address":5602592,"default_item":104,"flag":1534},"TRAINER_WARREN_REWARD":{"address":5602260,"default_item":104,"flag":1368},"TRAINER_WATTSON_1_REWARD":{"address":5602618,"default_item":104,"flag":1547},"TRAINER_WAYNE_REWARD":{"address":5603430,"default_item":104,"flag":1953},"TRAINER_WENDY_REWARD":{"address":5602268,"default_item":104,"flag":1372},"TRAINER_WILLIAM_REWARD":{"address":5602556,"default_item":106,"flag":1516},"TRAINER_WILTON_1_REWARD":{"address":5602240,"default_item":108,"flag":1358},"TRAINER_WINONA_1_REWARD":{"address":5602624,"default_item":107,"flag":1550},"TRAINER_WINSTON_1_REWARD":{"address":5602356,"default_item":104,"flag":1416},"TRAINER_WYATT_REWARD":{"address":5603506,"default_item":104,"flag":1991},"TRAINER_YASU_REWARD":{"address":5602914,"default_item":106,"flag":1695},"TRAINER_ZANDER_REWARD":{"address":5602146,"default_item":108,"flag":1311}},"maps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE":{"header_address":4766420,"warp_table_address":5496844},"MAP_ABANDONED_SHIP_CORRIDORS_1F":{"header_address":4766196,"warp_table_address":5495920},"MAP_ABANDONED_SHIP_CORRIDORS_B1F":{"header_address":4766252,"warp_table_address":5496248},"MAP_ABANDONED_SHIP_DECK":{"header_address":4766168,"warp_table_address":5495812},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS":{"fishing_encounters":{"address":5609088,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766476,"warp_table_address":5496908,"water_encounters":{"address":5609060,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS":{"header_address":4766504,"warp_table_address":5497120},"MAP_ABANDONED_SHIP_ROOMS2_1F":{"header_address":4766392,"warp_table_address":5496752},"MAP_ABANDONED_SHIP_ROOMS2_B1F":{"header_address":4766308,"warp_table_address":5496484},"MAP_ABANDONED_SHIP_ROOMS_1F":{"header_address":4766224,"warp_table_address":5496132},"MAP_ABANDONED_SHIP_ROOMS_B1F":{"fishing_encounters":{"address":5606324,"slots":[129,72,129,72,72,72,72,73,73,73]},"header_address":4766280,"warp_table_address":5496392,"water_encounters":{"address":5606296,"slots":[72,72,72,72,73]}},"MAP_ABANDONED_SHIP_ROOM_B1F":{"header_address":4766364,"warp_table_address":5496596},"MAP_ABANDONED_SHIP_UNDERWATER1":{"header_address":4766336,"warp_table_address":5496536},"MAP_ABANDONED_SHIP_UNDERWATER2":{"header_address":4766448,"warp_table_address":5496880},"MAP_ALTERING_CAVE":{"header_address":4767624,"land_encounters":{"address":5613400,"slots":[41,41,41,41,41,41,41,41,41,41,41,41]},"warp_table_address":5500436},"MAP_ANCIENT_TOMB":{"header_address":4766560,"warp_table_address":5497460},"MAP_AQUA_HIDEOUT_1F":{"header_address":4765300,"warp_table_address":5490892},"MAP_AQUA_HIDEOUT_B1F":{"header_address":4765328,"warp_table_address":5491152},"MAP_AQUA_HIDEOUT_B2F":{"header_address":4765356,"warp_table_address":5491516},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP1":{"header_address":4766728,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP2":{"header_address":4766756,"warp_table_address":4160749568},"MAP_AQUA_HIDEOUT_UNUSED_RUBY_MAP3":{"header_address":4766784,"warp_table_address":4160749568},"MAP_ARTISAN_CAVE_1F":{"header_address":4767456,"land_encounters":{"address":5613344,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500172},"MAP_ARTISAN_CAVE_B1F":{"header_address":4767428,"land_encounters":{"address":5613288,"slots":[235,235,235,235,235,235,235,235,235,235,235,235]},"warp_table_address":5500064},"MAP_BATTLE_COLOSSEUM_2P":{"header_address":4768352,"warp_table_address":5509852},"MAP_BATTLE_COLOSSEUM_4P":{"header_address":4768436,"warp_table_address":5510152},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM":{"header_address":4770228,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR":{"header_address":4770200,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY":{"header_address":4770172,"warp_table_address":5520908},"MAP_BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM":{"header_address":4769976,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR":{"header_address":4769920,"warp_table_address":5519076},"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY":{"header_address":4769892,"warp_table_address":5518968},"MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM":{"header_address":4769948,"warp_table_address":5519136},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM":{"header_address":4770312,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY":{"header_address":4770256,"warp_table_address":5521384},"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM":{"header_address":4770284,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM":{"header_address":4770060,"warp_table_address":5520116},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR":{"header_address":4770032,"warp_table_address":5519944},"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY":{"header_address":4770004,"warp_table_address":5519696},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR":{"header_address":4770368,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY":{"header_address":4770340,"warp_table_address":5521808},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_FINAL":{"header_address":4770452,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_NORMAL":{"header_address":4770424,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_ROOM_WILD_MONS":{"header_address":4770480,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM":{"header_address":4770396,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_FLOOR":{"header_address":4770116,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY":{"header_address":4770088,"warp_table_address":5520248},"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_TOP":{"header_address":4770144,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM":{"header_address":4769612,"warp_table_address":5516696},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR":{"header_address":4769584,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_ELEVATOR":{"header_address":4769556,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY":{"header_address":4769528,"warp_table_address":5516432},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM":{"header_address":4769864,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_CORRIDOR":{"header_address":4769836,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_BATTLE_TOWER_MULTI_PARTNER_ROOM":{"header_address":4769808,"warp_table_address":4160749568},"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER":{"header_address":4770564,"warp_table_address":5523056},"MAP_BATTLE_FRONTIER_LOUNGE1":{"header_address":4770536,"warp_table_address":5522812},"MAP_BATTLE_FRONTIER_LOUNGE2":{"header_address":4770592,"warp_table_address":5523220},"MAP_BATTLE_FRONTIER_LOUNGE3":{"header_address":4770620,"warp_table_address":5523376},"MAP_BATTLE_FRONTIER_LOUNGE4":{"header_address":4770648,"warp_table_address":5523476},"MAP_BATTLE_FRONTIER_LOUNGE5":{"header_address":4770704,"warp_table_address":5523660},"MAP_BATTLE_FRONTIER_LOUNGE6":{"header_address":4770732,"warp_table_address":5523720},"MAP_BATTLE_FRONTIER_LOUNGE7":{"header_address":4770760,"warp_table_address":5523844},"MAP_BATTLE_FRONTIER_LOUNGE8":{"header_address":4770816,"warp_table_address":5524100},"MAP_BATTLE_FRONTIER_LOUNGE9":{"header_address":4770844,"warp_table_address":5524152},"MAP_BATTLE_FRONTIER_MART":{"header_address":4770928,"warp_table_address":5524588},"MAP_BATTLE_FRONTIER_OUTSIDE_EAST":{"header_address":4769780,"warp_table_address":5518080},"MAP_BATTLE_FRONTIER_OUTSIDE_WEST":{"header_address":4769500,"warp_table_address":5516048},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F":{"header_address":4770872,"warp_table_address":5524308},"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F":{"header_address":4770900,"warp_table_address":5524448},"MAP_BATTLE_FRONTIER_RANKING_HALL":{"header_address":4770508,"warp_table_address":5522560},"MAP_BATTLE_FRONTIER_RECEPTION_GATE":{"header_address":4770788,"warp_table_address":5523992},"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE":{"header_address":4770676,"warp_table_address":5523528},"MAP_BATTLE_PYRAMID_SQUARE01":{"header_address":4768912,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE02":{"header_address":4768940,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE03":{"header_address":4768968,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE04":{"header_address":4768996,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE05":{"header_address":4769024,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE06":{"header_address":4769052,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE07":{"header_address":4769080,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE08":{"header_address":4769108,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE09":{"header_address":4769136,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE10":{"header_address":4769164,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE11":{"header_address":4769192,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE12":{"header_address":4769220,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE13":{"header_address":4769248,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE14":{"header_address":4769276,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE15":{"header_address":4769304,"warp_table_address":4160749568},"MAP_BATTLE_PYRAMID_SQUARE16":{"header_address":4769332,"warp_table_address":4160749568},"MAP_BIRTH_ISLAND_EXTERIOR":{"header_address":4771012,"warp_table_address":5524876},"MAP_BIRTH_ISLAND_HARBOR":{"header_address":4771040,"warp_table_address":5524952},"MAP_CAVE_OF_ORIGIN_1F":{"header_address":4765720,"land_encounters":{"address":5609868,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493440},"MAP_CAVE_OF_ORIGIN_B1F":{"header_address":4765832,"warp_table_address":5493608},"MAP_CAVE_OF_ORIGIN_ENTRANCE":{"header_address":4765692,"land_encounters":{"address":5609812,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493404},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1":{"header_address":4765748,"land_encounters":{"address":5609924,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493476},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2":{"header_address":4765776,"land_encounters":{"address":5609980,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493512},"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3":{"header_address":4765804,"land_encounters":{"address":5610036,"slots":[41,41,41,322,322,322,41,41,42,42,42,42]},"warp_table_address":5493548},"MAP_CONTEST_HALL":{"header_address":4768464,"warp_table_address":4160749568},"MAP_CONTEST_HALL_BEAUTY":{"header_address":4768660,"warp_table_address":4160749568},"MAP_CONTEST_HALL_COOL":{"header_address":4768716,"warp_table_address":4160749568},"MAP_CONTEST_HALL_CUTE":{"header_address":4768772,"warp_table_address":4160749568},"MAP_CONTEST_HALL_SMART":{"header_address":4768744,"warp_table_address":4160749568},"MAP_CONTEST_HALL_TOUGH":{"header_address":4768688,"warp_table_address":4160749568},"MAP_DESERT_RUINS":{"header_address":4764824,"warp_table_address":5486828},"MAP_DESERT_UNDERPASS":{"header_address":4767400,"land_encounters":{"address":5613232,"slots":[132,370,132,371,132,370,371,132,370,132,371,132]},"warp_table_address":5500012},"MAP_DEWFORD_TOWN":{"fishing_encounters":{"address":5611588,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758300,"warp_table_address":5435180,"water_encounters":{"address":5611560,"slots":[72,309,309,310,310]}},"MAP_DEWFORD_TOWN_GYM":{"header_address":4759952,"warp_table_address":5460340},"MAP_DEWFORD_TOWN_HALL":{"header_address":4759980,"warp_table_address":5460640},"MAP_DEWFORD_TOWN_HOUSE1":{"header_address":4759868,"warp_table_address":5459856},"MAP_DEWFORD_TOWN_HOUSE2":{"header_address":4760008,"warp_table_address":5460748},"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F":{"header_address":4759896,"warp_table_address":5459964},"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F":{"header_address":4759924,"warp_table_address":5460104},"MAP_EVER_GRANDE_CITY":{"fishing_encounters":{"address":5611892,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4758216,"warp_table_address":5434048,"water_encounters":{"address":5611864,"slots":[72,309,309,310,310]}},"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM":{"header_address":4764012,"warp_table_address":5483720},"MAP_EVER_GRANDE_CITY_DRAKES_ROOM":{"header_address":4763984,"warp_table_address":5483612},"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM":{"header_address":4763956,"warp_table_address":5483552},"MAP_EVER_GRANDE_CITY_HALL1":{"header_address":4764040,"warp_table_address":5483756},"MAP_EVER_GRANDE_CITY_HALL2":{"header_address":4764068,"warp_table_address":5483808},"MAP_EVER_GRANDE_CITY_HALL3":{"header_address":4764096,"warp_table_address":5483860},"MAP_EVER_GRANDE_CITY_HALL4":{"header_address":4764124,"warp_table_address":5483912},"MAP_EVER_GRANDE_CITY_HALL5":{"header_address":4764152,"warp_table_address":5483948},"MAP_EVER_GRANDE_CITY_HALL_OF_FAME":{"header_address":4764208,"warp_table_address":5484180},"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM":{"header_address":4763928,"warp_table_address":5483492},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F":{"header_address":4764236,"warp_table_address":5484304},"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F":{"header_address":4764264,"warp_table_address":5484444},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F":{"header_address":4764180,"warp_table_address":5484096},"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F":{"header_address":4764292,"warp_table_address":5484584},"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM":{"header_address":4763900,"warp_table_address":5483432},"MAP_FALLARBOR_TOWN":{"header_address":4758356,"warp_table_address":5435792},"MAP_FALLARBOR_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760316,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760288,"warp_table_address":4160749568},"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760260,"warp_table_address":5462376},"MAP_FALLARBOR_TOWN_COZMOS_HOUSE":{"header_address":4760400,"warp_table_address":5462888},"MAP_FALLARBOR_TOWN_MART":{"header_address":4760232,"warp_table_address":5462220},"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE":{"header_address":4760428,"warp_table_address":5462948},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F":{"header_address":4760344,"warp_table_address":5462656},"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F":{"header_address":4760372,"warp_table_address":5462796},"MAP_FARAWAY_ISLAND_ENTRANCE":{"header_address":4770956,"warp_table_address":5524672},"MAP_FARAWAY_ISLAND_INTERIOR":{"header_address":4770984,"warp_table_address":5524792},"MAP_FIERY_PATH":{"header_address":4765048,"land_encounters":{"address":5606456,"slots":[339,109,339,66,321,218,109,66,321,321,88,88]},"warp_table_address":5489344},"MAP_FORTREE_CITY":{"header_address":4758104,"warp_table_address":5431676},"MAP_FORTREE_CITY_DECORATION_SHOP":{"header_address":4762444,"warp_table_address":5473936},"MAP_FORTREE_CITY_GYM":{"header_address":4762220,"warp_table_address":5472984},"MAP_FORTREE_CITY_HOUSE1":{"header_address":4762192,"warp_table_address":5472756},"MAP_FORTREE_CITY_HOUSE2":{"header_address":4762332,"warp_table_address":5473504},"MAP_FORTREE_CITY_HOUSE3":{"header_address":4762360,"warp_table_address":5473588},"MAP_FORTREE_CITY_HOUSE4":{"header_address":4762388,"warp_table_address":5473696},"MAP_FORTREE_CITY_HOUSE5":{"header_address":4762416,"warp_table_address":5473804},"MAP_FORTREE_CITY_MART":{"header_address":4762304,"warp_table_address":5473420},"MAP_FORTREE_CITY_POKEMON_CENTER_1F":{"header_address":4762248,"warp_table_address":5473140},"MAP_FORTREE_CITY_POKEMON_CENTER_2F":{"header_address":4762276,"warp_table_address":5473280},"MAP_GRANITE_CAVE_1F":{"header_address":4764852,"land_encounters":{"address":5605988,"slots":[41,335,335,41,335,63,335,335,74,74,74,74]},"warp_table_address":5486956},"MAP_GRANITE_CAVE_B1F":{"header_address":4764880,"land_encounters":{"address":5606044,"slots":[41,382,382,382,41,63,335,335,322,322,322,322]},"warp_table_address":5487032},"MAP_GRANITE_CAVE_B2F":{"header_address":4764908,"land_encounters":{"address":5606372,"slots":[41,382,382,41,382,63,322,322,322,322,322,322]},"rock_smash_encounters":{"address":5606428,"slots":[74,320,74,74,74]},"warp_table_address":5487324},"MAP_GRANITE_CAVE_STEVENS_ROOM":{"header_address":4764936,"land_encounters":{"address":5608188,"slots":[41,335,335,41,335,63,335,335,382,382,382,382]},"warp_table_address":5487432},"MAP_INSIDE_OF_TRUCK":{"header_address":4768800,"warp_table_address":5510720},"MAP_ISLAND_CAVE":{"header_address":4766532,"warp_table_address":5497356},"MAP_JAGGED_PASS":{"header_address":4765020,"land_encounters":{"address":5606644,"slots":[339,339,66,339,351,66,351,66,339,351,339,351]},"warp_table_address":5488908},"MAP_LAVARIDGE_TOWN":{"header_address":4758328,"warp_table_address":5435516},"MAP_LAVARIDGE_TOWN_GYM_1F":{"header_address":4760064,"warp_table_address":5461036},"MAP_LAVARIDGE_TOWN_GYM_B1F":{"header_address":4760092,"warp_table_address":5461384},"MAP_LAVARIDGE_TOWN_HERB_SHOP":{"header_address":4760036,"warp_table_address":5460856},"MAP_LAVARIDGE_TOWN_HOUSE":{"header_address":4760120,"warp_table_address":5461668},"MAP_LAVARIDGE_TOWN_MART":{"header_address":4760148,"warp_table_address":5461776},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F":{"header_address":4760176,"warp_table_address":5461908},"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F":{"header_address":4760204,"warp_table_address":5462056},"MAP_LILYCOVE_CITY":{"fishing_encounters":{"address":5611512,"slots":[129,72,129,72,313,313,313,120,313,313]},"header_address":4758132,"warp_table_address":5432368,"water_encounters":{"address":5611484,"slots":[72,309,309,310,310]}},"MAP_LILYCOVE_CITY_CONTEST_HALL":{"header_address":4762612,"warp_table_address":5476560},"MAP_LILYCOVE_CITY_CONTEST_LOBBY":{"header_address":4762584,"warp_table_address":5475596},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F":{"header_address":4762472,"warp_table_address":5473996},"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F":{"header_address":4762500,"warp_table_address":5474224},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F":{"header_address":4762920,"warp_table_address":5478044},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F":{"header_address":4762948,"warp_table_address":5478228},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F":{"header_address":4762976,"warp_table_address":5478392},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F":{"header_address":4763004,"warp_table_address":5478556},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F":{"header_address":4763032,"warp_table_address":5478768},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR":{"header_address":4763088,"warp_table_address":5478984},"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP":{"header_address":4763060,"warp_table_address":5478908},"MAP_LILYCOVE_CITY_HARBOR":{"header_address":4762752,"warp_table_address":5477396},"MAP_LILYCOVE_CITY_HOUSE1":{"header_address":4762808,"warp_table_address":5477540},"MAP_LILYCOVE_CITY_HOUSE2":{"header_address":4762836,"warp_table_address":5477600},"MAP_LILYCOVE_CITY_HOUSE3":{"header_address":4762864,"warp_table_address":5477780},"MAP_LILYCOVE_CITY_HOUSE4":{"header_address":4762892,"warp_table_address":5477864},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F":{"header_address":4762528,"warp_table_address":5474492},"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F":{"header_address":4762556,"warp_table_address":5474824},"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE":{"header_address":4762780,"warp_table_address":5477456},"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F":{"header_address":4762640,"warp_table_address":5476804},"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F":{"header_address":4762668,"warp_table_address":5476944},"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB":{"header_address":4762724,"warp_table_address":5477240},"MAP_LILYCOVE_CITY_UNUSED_MART":{"header_address":4762696,"warp_table_address":5476988},"MAP_LITTLEROOT_TOWN":{"header_address":4758244,"warp_table_address":5434528},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F":{"header_address":4759588,"warp_table_address":5457588},"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F":{"header_address":4759616,"warp_table_address":5458080},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F":{"header_address":4759644,"warp_table_address":5458324},"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F":{"header_address":4759672,"warp_table_address":5458816},"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB":{"header_address":4759700,"warp_table_address":5459036},"MAP_MAGMA_HIDEOUT_1F":{"header_address":4767064,"land_encounters":{"address":5612560,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498844},"MAP_MAGMA_HIDEOUT_2F_1R":{"header_address":4767092,"land_encounters":{"address":5612616,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5498992},"MAP_MAGMA_HIDEOUT_2F_2R":{"header_address":4767120,"land_encounters":{"address":5612672,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499180},"MAP_MAGMA_HIDEOUT_2F_3R":{"header_address":4767260,"land_encounters":{"address":5612952,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499696},"MAP_MAGMA_HIDEOUT_3F_1R":{"header_address":4767148,"land_encounters":{"address":5612728,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499288},"MAP_MAGMA_HIDEOUT_3F_2R":{"header_address":4767176,"land_encounters":{"address":5612784,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499380},"MAP_MAGMA_HIDEOUT_3F_3R":{"header_address":4767232,"land_encounters":{"address":5612896,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499660},"MAP_MAGMA_HIDEOUT_4F":{"header_address":4767204,"land_encounters":{"address":5612840,"slots":[74,321,74,321,74,74,74,75,75,75,75,75]},"warp_table_address":5499600},"MAP_MARINE_CAVE_END":{"header_address":4767540,"warp_table_address":5500288},"MAP_MARINE_CAVE_ENTRANCE":{"header_address":4767512,"warp_table_address":5500236},"MAP_MAUVILLE_CITY":{"header_address":4758048,"warp_table_address":5430380},"MAP_MAUVILLE_CITY_BIKE_SHOP":{"header_address":4761520,"warp_table_address":5469232},"MAP_MAUVILLE_CITY_GAME_CORNER":{"header_address":4761576,"warp_table_address":5469640},"MAP_MAUVILLE_CITY_GYM":{"header_address":4761492,"warp_table_address":5469060},"MAP_MAUVILLE_CITY_HOUSE1":{"header_address":4761548,"warp_table_address":5469316},"MAP_MAUVILLE_CITY_HOUSE2":{"header_address":4761604,"warp_table_address":5469988},"MAP_MAUVILLE_CITY_MART":{"header_address":4761688,"warp_table_address":5470424},"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F":{"header_address":4761632,"warp_table_address":5470144},"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F":{"header_address":4761660,"warp_table_address":5470308},"MAP_METEOR_FALLS_1F_1R":{"fishing_encounters":{"address":5610796,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4764656,"land_encounters":{"address":5610712,"slots":[41,41,41,41,41,349,349,349,41,41,41,41]},"warp_table_address":5486052,"water_encounters":{"address":5610768,"slots":[41,41,349,349,349]}},"MAP_METEOR_FALLS_1F_2R":{"fishing_encounters":{"address":5610928,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764684,"land_encounters":{"address":5610844,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486220,"water_encounters":{"address":5610900,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_1R":{"fishing_encounters":{"address":5611060,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764712,"land_encounters":{"address":5610976,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5486284,"water_encounters":{"address":5611032,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_B1F_2R":{"fishing_encounters":{"address":5606596,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4764740,"land_encounters":{"address":5606512,"slots":[42,42,395,349,395,349,395,349,42,42,42,42]},"warp_table_address":5486376,"water_encounters":{"address":5606568,"slots":[42,42,349,349,349]}},"MAP_METEOR_FALLS_STEVENS_CAVE":{"header_address":4767652,"land_encounters":{"address":5613904,"slots":[42,42,42,349,349,349,42,349,42,42,42,42]},"warp_table_address":5500488},"MAP_MIRAGE_TOWER_1F":{"header_address":4767288,"land_encounters":{"address":5613008,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499732},"MAP_MIRAGE_TOWER_2F":{"header_address":4767316,"land_encounters":{"address":5613064,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499768},"MAP_MIRAGE_TOWER_3F":{"header_address":4767344,"land_encounters":{"address":5613120,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499852},"MAP_MIRAGE_TOWER_4F":{"header_address":4767372,"land_encounters":{"address":5613176,"slots":[27,332,27,332,27,332,27,332,27,332,27,332]},"warp_table_address":5499960},"MAP_MOSSDEEP_CITY":{"fishing_encounters":{"address":5611740,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758160,"warp_table_address":5433064,"water_encounters":{"address":5611712,"slots":[72,309,309,310,310]}},"MAP_MOSSDEEP_CITY_GAME_CORNER_1F":{"header_address":4763424,"warp_table_address":5481712},"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F":{"header_address":4763452,"warp_table_address":5481816},"MAP_MOSSDEEP_CITY_GYM":{"header_address":4763116,"warp_table_address":5479884},"MAP_MOSSDEEP_CITY_HOUSE1":{"header_address":4763144,"warp_table_address":5480232},"MAP_MOSSDEEP_CITY_HOUSE2":{"header_address":4763172,"warp_table_address":5480340},"MAP_MOSSDEEP_CITY_HOUSE3":{"header_address":4763284,"warp_table_address":5480812},"MAP_MOSSDEEP_CITY_HOUSE4":{"header_address":4763340,"warp_table_address":5481076},"MAP_MOSSDEEP_CITY_MART":{"header_address":4763256,"warp_table_address":5480752},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F":{"header_address":4763200,"warp_table_address":5480448},"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F":{"header_address":4763228,"warp_table_address":5480612},"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F":{"header_address":4763368,"warp_table_address":5481376},"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F":{"header_address":4763396,"warp_table_address":5481636},"MAP_MOSSDEEP_CITY_STEVENS_HOUSE":{"header_address":4763312,"warp_table_address":5480920},"MAP_MT_CHIMNEY":{"header_address":4764992,"warp_table_address":5488664},"MAP_MT_CHIMNEY_CABLE_CAR_STATION":{"header_address":4764460,"warp_table_address":5485144},"MAP_MT_PYRE_1F":{"header_address":4765076,"land_encounters":{"address":5606100,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489452},"MAP_MT_PYRE_2F":{"header_address":4765104,"land_encounters":{"address":5607796,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489712},"MAP_MT_PYRE_3F":{"header_address":4765132,"land_encounters":{"address":5607852,"slots":[377,377,377,377,377,377,377,377,377,377,377,377]},"warp_table_address":5489868},"MAP_MT_PYRE_4F":{"header_address":4765160,"land_encounters":{"address":5607908,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5489984},"MAP_MT_PYRE_5F":{"header_address":4765188,"land_encounters":{"address":5607964,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490100},"MAP_MT_PYRE_6F":{"header_address":4765216,"land_encounters":{"address":5608020,"slots":[377,377,377,377,377,377,377,377,361,361,361,361]},"warp_table_address":5490232},"MAP_MT_PYRE_EXTERIOR":{"header_address":4765244,"land_encounters":{"address":5608076,"slots":[377,377,377,377,37,37,37,37,309,309,309,309]},"warp_table_address":5490316},"MAP_MT_PYRE_SUMMIT":{"header_address":4765272,"land_encounters":{"address":5608132,"slots":[377,377,377,377,377,377,377,361,361,361,411,411]},"warp_table_address":5490656},"MAP_NAVEL_ROCK_B1F":{"header_address":4771320,"warp_table_address":5525524},"MAP_NAVEL_ROCK_BOTTOM":{"header_address":4771824,"warp_table_address":5526248},"MAP_NAVEL_ROCK_DOWN01":{"header_address":4771516,"warp_table_address":5525828},"MAP_NAVEL_ROCK_DOWN02":{"header_address":4771544,"warp_table_address":5525864},"MAP_NAVEL_ROCK_DOWN03":{"header_address":4771572,"warp_table_address":5525900},"MAP_NAVEL_ROCK_DOWN04":{"header_address":4771600,"warp_table_address":5525936},"MAP_NAVEL_ROCK_DOWN05":{"header_address":4771628,"warp_table_address":5525972},"MAP_NAVEL_ROCK_DOWN06":{"header_address":4771656,"warp_table_address":5526008},"MAP_NAVEL_ROCK_DOWN07":{"header_address":4771684,"warp_table_address":5526044},"MAP_NAVEL_ROCK_DOWN08":{"header_address":4771712,"warp_table_address":5526080},"MAP_NAVEL_ROCK_DOWN09":{"header_address":4771740,"warp_table_address":5526116},"MAP_NAVEL_ROCK_DOWN10":{"header_address":4771768,"warp_table_address":5526152},"MAP_NAVEL_ROCK_DOWN11":{"header_address":4771796,"warp_table_address":5526188},"MAP_NAVEL_ROCK_ENTRANCE":{"header_address":4771292,"warp_table_address":5525488},"MAP_NAVEL_ROCK_EXTERIOR":{"header_address":4771236,"warp_table_address":5525376},"MAP_NAVEL_ROCK_FORK":{"header_address":4771348,"warp_table_address":5525560},"MAP_NAVEL_ROCK_HARBOR":{"header_address":4771264,"warp_table_address":5525460},"MAP_NAVEL_ROCK_TOP":{"header_address":4771488,"warp_table_address":5525772},"MAP_NAVEL_ROCK_UP1":{"header_address":4771376,"warp_table_address":5525604},"MAP_NAVEL_ROCK_UP2":{"header_address":4771404,"warp_table_address":5525640},"MAP_NAVEL_ROCK_UP3":{"header_address":4771432,"warp_table_address":5525676},"MAP_NAVEL_ROCK_UP4":{"header_address":4771460,"warp_table_address":5525712},"MAP_NEW_MAUVILLE_ENTRANCE":{"header_address":4766112,"land_encounters":{"address":5610092,"slots":[100,81,100,81,100,81,100,81,100,81,100,81]},"warp_table_address":5495284},"MAP_NEW_MAUVILLE_INSIDE":{"header_address":4766140,"land_encounters":{"address":5607136,"slots":[100,81,100,81,100,81,100,81,100,81,101,82]},"warp_table_address":5495528},"MAP_OLDALE_TOWN":{"header_address":4758272,"warp_table_address":5434860},"MAP_OLDALE_TOWN_HOUSE1":{"header_address":4759728,"warp_table_address":5459276},"MAP_OLDALE_TOWN_HOUSE2":{"header_address":4759756,"warp_table_address":5459360},"MAP_OLDALE_TOWN_MART":{"header_address":4759840,"warp_table_address":5459748},"MAP_OLDALE_TOWN_POKEMON_CENTER_1F":{"header_address":4759784,"warp_table_address":5459492},"MAP_OLDALE_TOWN_POKEMON_CENTER_2F":{"header_address":4759812,"warp_table_address":5459632},"MAP_PACIFIDLOG_TOWN":{"fishing_encounters":{"address":5611816,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758412,"warp_table_address":5436288,"water_encounters":{"address":5611788,"slots":[72,309,309,310,310]}},"MAP_PACIFIDLOG_TOWN_HOUSE1":{"header_address":4760764,"warp_table_address":5464400},"MAP_PACIFIDLOG_TOWN_HOUSE2":{"header_address":4760792,"warp_table_address":5464508},"MAP_PACIFIDLOG_TOWN_HOUSE3":{"header_address":4760820,"warp_table_address":5464592},"MAP_PACIFIDLOG_TOWN_HOUSE4":{"header_address":4760848,"warp_table_address":5464700},"MAP_PACIFIDLOG_TOWN_HOUSE5":{"header_address":4760876,"warp_table_address":5464784},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F":{"header_address":4760708,"warp_table_address":5464168},"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F":{"header_address":4760736,"warp_table_address":5464308},"MAP_PETALBURG_CITY":{"fishing_encounters":{"address":5611968,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4757992,"warp_table_address":5428704,"water_encounters":{"address":5611940,"slots":[183,183,183,183,183]}},"MAP_PETALBURG_CITY_GYM":{"header_address":4760932,"warp_table_address":5465168},"MAP_PETALBURG_CITY_HOUSE1":{"header_address":4760960,"warp_table_address":5465708},"MAP_PETALBURG_CITY_HOUSE2":{"header_address":4760988,"warp_table_address":5465792},"MAP_PETALBURG_CITY_MART":{"header_address":4761072,"warp_table_address":5466228},"MAP_PETALBURG_CITY_POKEMON_CENTER_1F":{"header_address":4761016,"warp_table_address":5465948},"MAP_PETALBURG_CITY_POKEMON_CENTER_2F":{"header_address":4761044,"warp_table_address":5466088},"MAP_PETALBURG_CITY_WALLYS_HOUSE":{"header_address":4760904,"warp_table_address":5464868},"MAP_PETALBURG_WOODS":{"header_address":4764964,"land_encounters":{"address":5605876,"slots":[286,290,306,286,291,293,290,306,304,364,304,364]},"warp_table_address":5487772},"MAP_RECORD_CORNER":{"header_address":4768408,"warp_table_address":5510036},"MAP_ROUTE101":{"header_address":4758440,"land_encounters":{"address":5604388,"slots":[290,286,290,290,286,286,290,286,288,288,288,288]},"warp_table_address":4160749568},"MAP_ROUTE102":{"fishing_encounters":{"address":5604528,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758468,"land_encounters":{"address":5604444,"slots":[286,290,286,290,295,295,288,288,288,392,288,298]},"warp_table_address":4160749568,"water_encounters":{"address":5604500,"slots":[183,183,183,183,118]}},"MAP_ROUTE103":{"fishing_encounters":{"address":5604660,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4758496,"land_encounters":{"address":5604576,"slots":[286,286,286,286,309,288,288,288,309,309,309,309]},"warp_table_address":5437452,"water_encounters":{"address":5604632,"slots":[72,309,309,310,310]}},"MAP_ROUTE104":{"fishing_encounters":{"address":5604792,"slots":[129,129,129,129,129,129,129,129,129,129]},"header_address":4758524,"land_encounters":{"address":5604708,"slots":[286,290,286,183,183,286,304,304,309,309,309,309]},"warp_table_address":5438308,"water_encounters":{"address":5604764,"slots":[309,309,309,310,310]}},"MAP_ROUTE104_MR_BRINEYS_HOUSE":{"header_address":4764320,"warp_table_address":5484676},"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4764348,"warp_table_address":5484784},"MAP_ROUTE104_PROTOTYPE":{"header_address":4771880,"warp_table_address":4160749568},"MAP_ROUTE104_PROTOTYPE_PRETTY_PETAL_FLOWER_SHOP":{"header_address":4771908,"warp_table_address":4160749568},"MAP_ROUTE105":{"fishing_encounters":{"address":5604868,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758552,"warp_table_address":5438720,"water_encounters":{"address":5604840,"slots":[72,309,309,310,310]}},"MAP_ROUTE106":{"fishing_encounters":{"address":5606728,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758580,"warp_table_address":5438892,"water_encounters":{"address":5606700,"slots":[72,309,309,310,310]}},"MAP_ROUTE107":{"fishing_encounters":{"address":5606804,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758608,"warp_table_address":4160749568,"water_encounters":{"address":5606776,"slots":[72,309,309,310,310]}},"MAP_ROUTE108":{"fishing_encounters":{"address":5606880,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758636,"warp_table_address":5439324,"water_encounters":{"address":5606852,"slots":[72,309,309,310,310]}},"MAP_ROUTE109":{"fishing_encounters":{"address":5606956,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758664,"warp_table_address":5439940,"water_encounters":{"address":5606928,"slots":[72,309,309,310,310]}},"MAP_ROUTE109_SEASHORE_HOUSE":{"header_address":4771936,"warp_table_address":5526472},"MAP_ROUTE110":{"fishing_encounters":{"address":5605000,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758692,"land_encounters":{"address":5604916,"slots":[286,337,367,337,354,43,354,367,309,309,353,353]},"warp_table_address":5440928,"water_encounters":{"address":5604972,"slots":[72,309,309,310,310]}},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE":{"header_address":4772272,"warp_table_address":5529400},"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE":{"header_address":4772300,"warp_table_address":5529508},"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR":{"header_address":4772020,"warp_table_address":5526740},"MAP_ROUTE110_TRICK_HOUSE_END":{"header_address":4771992,"warp_table_address":5526676},"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE":{"header_address":4771964,"warp_table_address":5526532},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1":{"header_address":4772048,"warp_table_address":5527152},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE2":{"header_address":4772076,"warp_table_address":5527328},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE3":{"header_address":4772104,"warp_table_address":5527616},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE4":{"header_address":4772132,"warp_table_address":5528072},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE5":{"header_address":4772160,"warp_table_address":5528248},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE6":{"header_address":4772188,"warp_table_address":5528752},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7":{"header_address":4772216,"warp_table_address":5529024},"MAP_ROUTE110_TRICK_HOUSE_PUZZLE8":{"header_address":4772244,"warp_table_address":5529320},"MAP_ROUTE111":{"fishing_encounters":{"address":5605160,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758720,"land_encounters":{"address":5605048,"slots":[27,332,27,332,318,318,27,332,318,344,344,344]},"rock_smash_encounters":{"address":5605132,"slots":[74,74,74,74,74]},"warp_table_address":5442448,"water_encounters":{"address":5605104,"slots":[183,183,183,183,118]}},"MAP_ROUTE111_OLD_LADYS_REST_STOP":{"header_address":4764404,"warp_table_address":5484976},"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE":{"header_address":4764376,"warp_table_address":5484916},"MAP_ROUTE112":{"header_address":4758748,"land_encounters":{"address":5605208,"slots":[339,339,183,339,339,183,339,183,339,339,339,339]},"warp_table_address":5443604},"MAP_ROUTE112_CABLE_CAR_STATION":{"header_address":4764432,"warp_table_address":5485060},"MAP_ROUTE113":{"header_address":4758776,"land_encounters":{"address":5605264,"slots":[308,308,218,308,308,218,308,218,308,227,308,227]},"warp_table_address":5444092},"MAP_ROUTE113_GLASS_WORKSHOP":{"header_address":4772328,"warp_table_address":5529640},"MAP_ROUTE114":{"fishing_encounters":{"address":5605432,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758804,"land_encounters":{"address":5605320,"slots":[358,295,358,358,295,296,296,296,379,379,379,299]},"rock_smash_encounters":{"address":5605404,"slots":[74,74,74,74,74]},"warp_table_address":5445184,"water_encounters":{"address":5605376,"slots":[183,183,183,183,118]}},"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE":{"header_address":4764488,"warp_table_address":5485204},"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL":{"header_address":4764516,"warp_table_address":5485320},"MAP_ROUTE114_LANETTES_HOUSE":{"header_address":4764544,"warp_table_address":5485420},"MAP_ROUTE115":{"fishing_encounters":{"address":5607088,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758832,"land_encounters":{"address":5607004,"slots":[358,304,358,304,304,305,39,39,309,309,309,309]},"warp_table_address":5445988,"water_encounters":{"address":5607060,"slots":[72,309,309,310,310]}},"MAP_ROUTE116":{"header_address":4758860,"land_encounters":{"address":5605480,"slots":[286,370,301,63,301,304,304,304,286,286,315,315]},"warp_table_address":5446872},"MAP_ROUTE116_TUNNELERS_REST_HOUSE":{"header_address":4764572,"warp_table_address":5485564},"MAP_ROUTE117":{"fishing_encounters":{"address":5605620,"slots":[129,118,129,118,326,326,326,326,326,326]},"header_address":4758888,"land_encounters":{"address":5605536,"slots":[286,43,286,43,183,43,387,387,387,387,386,298]},"warp_table_address":5447656,"water_encounters":{"address":5605592,"slots":[183,183,183,183,118]}},"MAP_ROUTE117_POKEMON_DAY_CARE":{"header_address":4764600,"warp_table_address":5485624},"MAP_ROUTE118":{"fishing_encounters":{"address":5605752,"slots":[129,72,129,72,330,331,330,330,330,330]},"header_address":4758916,"land_encounters":{"address":5605668,"slots":[288,337,288,337,289,338,309,309,309,309,309,317]},"warp_table_address":5448236,"water_encounters":{"address":5605724,"slots":[72,309,309,310,310]}},"MAP_ROUTE119":{"fishing_encounters":{"address":5607276,"slots":[129,72,129,72,330,330,330,330,330,330]},"header_address":4758944,"land_encounters":{"address":5607192,"slots":[288,289,288,43,289,43,43,43,369,369,369,317]},"warp_table_address":5449460,"water_encounters":{"address":5607248,"slots":[72,309,309,310,310]}},"MAP_ROUTE119_HOUSE":{"header_address":4772440,"warp_table_address":5530360},"MAP_ROUTE119_WEATHER_INSTITUTE_1F":{"header_address":4772384,"warp_table_address":5529880},"MAP_ROUTE119_WEATHER_INSTITUTE_2F":{"header_address":4772412,"warp_table_address":5530164},"MAP_ROUTE120":{"fishing_encounters":{"address":5607408,"slots":[129,118,129,118,323,323,323,323,323,323]},"header_address":4758972,"land_encounters":{"address":5607324,"slots":[286,287,287,43,183,43,43,183,376,376,317,298]},"warp_table_address":5451160,"water_encounters":{"address":5607380,"slots":[183,183,183,183,118]}},"MAP_ROUTE121":{"fishing_encounters":{"address":5607540,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759000,"land_encounters":{"address":5607456,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5452364,"water_encounters":{"address":5607512,"slots":[72,309,309,310,310]}},"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE":{"header_address":4764628,"warp_table_address":5485732},"MAP_ROUTE122":{"fishing_encounters":{"address":5607616,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759028,"warp_table_address":5452576,"water_encounters":{"address":5607588,"slots":[72,309,309,310,310]}},"MAP_ROUTE123":{"fishing_encounters":{"address":5607748,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4759056,"land_encounters":{"address":5607664,"slots":[286,377,287,377,287,43,43,44,309,309,309,317]},"warp_table_address":5453636,"water_encounters":{"address":5607720,"slots":[72,309,309,310,310]}},"MAP_ROUTE123_BERRY_MASTERS_HOUSE":{"header_address":4772356,"warp_table_address":5529724},"MAP_ROUTE124":{"fishing_encounters":{"address":5605828,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759084,"warp_table_address":5454436,"water_encounters":{"address":5605800,"slots":[72,309,309,310,310]}},"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE":{"header_address":4772468,"warp_table_address":5530420},"MAP_ROUTE125":{"fishing_encounters":{"address":5608272,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759112,"warp_table_address":5454716,"water_encounters":{"address":5608244,"slots":[72,309,309,310,310]}},"MAP_ROUTE126":{"fishing_encounters":{"address":5608348,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759140,"warp_table_address":4160749568,"water_encounters":{"address":5608320,"slots":[72,309,309,310,310]}},"MAP_ROUTE127":{"fishing_encounters":{"address":5608424,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759168,"warp_table_address":4160749568,"water_encounters":{"address":5608396,"slots":[72,309,309,310,310]}},"MAP_ROUTE128":{"fishing_encounters":{"address":5608500,"slots":[129,72,129,325,313,325,313,222,313,313]},"header_address":4759196,"warp_table_address":4160749568,"water_encounters":{"address":5608472,"slots":[72,309,309,310,310]}},"MAP_ROUTE129":{"fishing_encounters":{"address":5608576,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759224,"warp_table_address":4160749568,"water_encounters":{"address":5608548,"slots":[72,309,309,310,314]}},"MAP_ROUTE130":{"fishing_encounters":{"address":5608708,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759252,"land_encounters":{"address":5608624,"slots":[360,360,360,360,360,360,360,360,360,360,360,360]},"warp_table_address":4160749568,"water_encounters":{"address":5608680,"slots":[72,309,309,310,310]}},"MAP_ROUTE131":{"fishing_encounters":{"address":5608784,"slots":[129,72,129,72,313,331,313,313,313,313]},"header_address":4759280,"warp_table_address":5456116,"water_encounters":{"address":5608756,"slots":[72,309,309,310,310]}},"MAP_ROUTE132":{"fishing_encounters":{"address":5608860,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759308,"warp_table_address":4160749568,"water_encounters":{"address":5608832,"slots":[72,309,309,310,310]}},"MAP_ROUTE133":{"fishing_encounters":{"address":5608936,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759336,"warp_table_address":4160749568,"water_encounters":{"address":5608908,"slots":[72,309,309,310,310]}},"MAP_ROUTE134":{"fishing_encounters":{"address":5609012,"slots":[129,72,129,72,313,331,313,116,313,313]},"header_address":4759364,"warp_table_address":4160749568,"water_encounters":{"address":5608984,"slots":[72,309,309,310,310]}},"MAP_RUSTBORO_CITY":{"header_address":4758076,"warp_table_address":5430936},"MAP_RUSTBORO_CITY_CUTTERS_HOUSE":{"header_address":4762024,"warp_table_address":5472204},"MAP_RUSTBORO_CITY_DEVON_CORP_1F":{"header_address":4761716,"warp_table_address":5470532},"MAP_RUSTBORO_CITY_DEVON_CORP_2F":{"header_address":4761744,"warp_table_address":5470744},"MAP_RUSTBORO_CITY_DEVON_CORP_3F":{"header_address":4761772,"warp_table_address":5470852},"MAP_RUSTBORO_CITY_FLAT1_1F":{"header_address":4761940,"warp_table_address":5471808},"MAP_RUSTBORO_CITY_FLAT1_2F":{"header_address":4761968,"warp_table_address":5472044},"MAP_RUSTBORO_CITY_FLAT2_1F":{"header_address":4762080,"warp_table_address":5472372},"MAP_RUSTBORO_CITY_FLAT2_2F":{"header_address":4762108,"warp_table_address":5472464},"MAP_RUSTBORO_CITY_FLAT2_3F":{"header_address":4762136,"warp_table_address":5472548},"MAP_RUSTBORO_CITY_GYM":{"header_address":4761800,"warp_table_address":5471024},"MAP_RUSTBORO_CITY_HOUSE1":{"header_address":4761996,"warp_table_address":5472120},"MAP_RUSTBORO_CITY_HOUSE2":{"header_address":4762052,"warp_table_address":5472288},"MAP_RUSTBORO_CITY_HOUSE3":{"header_address":4762164,"warp_table_address":5472648},"MAP_RUSTBORO_CITY_MART":{"header_address":4761912,"warp_table_address":5471724},"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F":{"header_address":4761856,"warp_table_address":5471444},"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F":{"header_address":4761884,"warp_table_address":5471584},"MAP_RUSTBORO_CITY_POKEMON_SCHOOL":{"header_address":4761828,"warp_table_address":5471252},"MAP_RUSTURF_TUNNEL":{"header_address":4764768,"land_encounters":{"address":5605932,"slots":[370,370,370,370,370,370,370,370,370,370,370,370]},"warp_table_address":5486644},"MAP_SAFARI_ZONE_NORTH":{"header_address":4769416,"land_encounters":{"address":5610280,"slots":[231,43,231,43,177,44,44,177,178,214,178,214]},"rock_smash_encounters":{"address":5610336,"slots":[74,74,74,74,74]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHEAST":{"header_address":4769724,"land_encounters":{"address":5612476,"slots":[190,216,190,216,191,165,163,204,228,241,228,241]},"rock_smash_encounters":{"address":5612532,"slots":[213,213,213,213,213]},"warp_table_address":4160749568},"MAP_SAFARI_ZONE_NORTHWEST":{"fishing_encounters":{"address":5610448,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769388,"land_encounters":{"address":5610364,"slots":[111,43,111,43,84,44,44,84,85,127,85,127]},"warp_table_address":4160749568,"water_encounters":{"address":5610420,"slots":[54,54,54,55,55]}},"MAP_SAFARI_ZONE_REST_HOUSE":{"header_address":4769696,"warp_table_address":5516996},"MAP_SAFARI_ZONE_SOUTH":{"header_address":4769472,"land_encounters":{"address":5606212,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515444},"MAP_SAFARI_ZONE_SOUTHEAST":{"fishing_encounters":{"address":5612428,"slots":[129,118,129,118,223,118,223,223,223,224]},"header_address":4769752,"land_encounters":{"address":5612344,"slots":[191,179,191,179,190,167,163,209,234,207,234,207]},"warp_table_address":4160749568,"water_encounters":{"address":5612400,"slots":[194,183,183,183,195]}},"MAP_SAFARI_ZONE_SOUTHWEST":{"fishing_encounters":{"address":5610232,"slots":[129,118,129,118,118,118,118,119,119,119]},"header_address":4769444,"land_encounters":{"address":5610148,"slots":[43,43,203,203,177,84,44,202,25,202,25,202]},"warp_table_address":5515260,"water_encounters":{"address":5610204,"slots":[54,54,54,54,54]}},"MAP_SCORCHED_SLAB":{"header_address":4766700,"warp_table_address":5498144},"MAP_SEAFLOOR_CAVERN_ENTRANCE":{"fishing_encounters":{"address":5609764,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765412,"warp_table_address":5491796,"water_encounters":{"address":5609736,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM1":{"header_address":4765440,"land_encounters":{"address":5609136,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5491952},"MAP_SEAFLOOR_CAVERN_ROOM2":{"header_address":4765468,"land_encounters":{"address":5609192,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492188},"MAP_SEAFLOOR_CAVERN_ROOM3":{"header_address":4765496,"land_encounters":{"address":5609248,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492456},"MAP_SEAFLOOR_CAVERN_ROOM4":{"header_address":4765524,"land_encounters":{"address":5609304,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492548},"MAP_SEAFLOOR_CAVERN_ROOM5":{"header_address":4765552,"land_encounters":{"address":5609360,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492744},"MAP_SEAFLOOR_CAVERN_ROOM6":{"fishing_encounters":{"address":5609500,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765580,"land_encounters":{"address":5609416,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492788,"water_encounters":{"address":5609472,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM7":{"fishing_encounters":{"address":5609632,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765608,"land_encounters":{"address":5609548,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5492832,"water_encounters":{"address":5609604,"slots":[72,41,41,42,42]}},"MAP_SEAFLOOR_CAVERN_ROOM8":{"header_address":4765636,"land_encounters":{"address":5609680,"slots":[41,41,41,41,41,41,41,41,42,42,42,42]},"warp_table_address":5493156},"MAP_SEAFLOOR_CAVERN_ROOM9":{"header_address":4765664,"warp_table_address":5493360},"MAP_SEALED_CHAMBER_INNER_ROOM":{"header_address":4766672,"warp_table_address":5497984},"MAP_SEALED_CHAMBER_OUTER_ROOM":{"header_address":4766644,"warp_table_address":5497608},"MAP_SECRET_BASE_BLUE_CAVE1":{"header_address":4767736,"warp_table_address":5501652},"MAP_SECRET_BASE_BLUE_CAVE2":{"header_address":4767904,"warp_table_address":5503980},"MAP_SECRET_BASE_BLUE_CAVE3":{"header_address":4768072,"warp_table_address":5506308},"MAP_SECRET_BASE_BLUE_CAVE4":{"header_address":4768240,"warp_table_address":5508636},"MAP_SECRET_BASE_BROWN_CAVE1":{"header_address":4767708,"warp_table_address":5501264},"MAP_SECRET_BASE_BROWN_CAVE2":{"header_address":4767876,"warp_table_address":5503592},"MAP_SECRET_BASE_BROWN_CAVE3":{"header_address":4768044,"warp_table_address":5505920},"MAP_SECRET_BASE_BROWN_CAVE4":{"header_address":4768212,"warp_table_address":5508248},"MAP_SECRET_BASE_RED_CAVE1":{"header_address":4767680,"warp_table_address":5500876},"MAP_SECRET_BASE_RED_CAVE2":{"header_address":4767848,"warp_table_address":5503204},"MAP_SECRET_BASE_RED_CAVE3":{"header_address":4768016,"warp_table_address":5505532},"MAP_SECRET_BASE_RED_CAVE4":{"header_address":4768184,"warp_table_address":5507860},"MAP_SECRET_BASE_SHRUB1":{"header_address":4767820,"warp_table_address":5502816},"MAP_SECRET_BASE_SHRUB2":{"header_address":4767988,"warp_table_address":5505144},"MAP_SECRET_BASE_SHRUB3":{"header_address":4768156,"warp_table_address":5507472},"MAP_SECRET_BASE_SHRUB4":{"header_address":4768324,"warp_table_address":5509800},"MAP_SECRET_BASE_TREE1":{"header_address":4767792,"warp_table_address":5502428},"MAP_SECRET_BASE_TREE2":{"header_address":4767960,"warp_table_address":5504756},"MAP_SECRET_BASE_TREE3":{"header_address":4768128,"warp_table_address":5507084},"MAP_SECRET_BASE_TREE4":{"header_address":4768296,"warp_table_address":5509412},"MAP_SECRET_BASE_YELLOW_CAVE1":{"header_address":4767764,"warp_table_address":5502040},"MAP_SECRET_BASE_YELLOW_CAVE2":{"header_address":4767932,"warp_table_address":5504368},"MAP_SECRET_BASE_YELLOW_CAVE3":{"header_address":4768100,"warp_table_address":5506696},"MAP_SECRET_BASE_YELLOW_CAVE4":{"header_address":4768268,"warp_table_address":5509024},"MAP_SHOAL_CAVE_HIGH_TIDE_ENTRANCE_ROOM":{"header_address":4766056,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_HIGH_TIDE_INNER_ROOM":{"header_address":4766084,"warp_table_address":4160749568},"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM":{"fishing_encounters":{"address":5611436,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765944,"land_encounters":{"address":5611352,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494828,"water_encounters":{"address":5611408,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM":{"header_address":4766980,"land_encounters":{"address":5612044,"slots":[41,341,41,341,41,341,346,341,42,346,42,346]},"warp_table_address":5498544},"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM":{"fishing_encounters":{"address":5611304,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4765972,"land_encounters":{"address":5611220,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5494904,"water_encounters":{"address":5611276,"slots":[72,41,341,341,341]}},"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM":{"header_address":4766028,"land_encounters":{"address":5611164,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495180},"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM":{"header_address":4766000,"land_encounters":{"address":5611108,"slots":[41,341,41,341,41,341,41,341,42,341,42,341]},"warp_table_address":5495084},"MAP_SKY_PILLAR_1F":{"header_address":4766868,"land_encounters":{"address":5612100,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498328},"MAP_SKY_PILLAR_2F":{"header_address":4766896,"warp_table_address":5498372},"MAP_SKY_PILLAR_3F":{"header_address":4766924,"land_encounters":{"address":5612232,"slots":[322,42,42,322,319,378,378,319,319,319,319,319]},"warp_table_address":5498408},"MAP_SKY_PILLAR_4F":{"header_address":4766952,"warp_table_address":5498452},"MAP_SKY_PILLAR_5F":{"header_address":4767008,"land_encounters":{"address":5612288,"slots":[322,42,42,322,319,378,378,319,319,359,359,359]},"warp_table_address":5498572},"MAP_SKY_PILLAR_ENTRANCE":{"header_address":4766812,"warp_table_address":5498232},"MAP_SKY_PILLAR_OUTSIDE":{"header_address":4766840,"warp_table_address":5498292},"MAP_SKY_PILLAR_TOP":{"header_address":4767036,"warp_table_address":5498656},"MAP_SLATEPORT_CITY":{"fishing_encounters":{"address":5611664,"slots":[129,72,129,72,313,313,313,313,313,313]},"header_address":4758020,"warp_table_address":5429836,"water_encounters":{"address":5611636,"slots":[72,309,309,310,310]}},"MAP_SLATEPORT_CITY_BATTLE_TENT_BATTLE_ROOM":{"header_address":4761212,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_CORRIDOR":{"header_address":4761184,"warp_table_address":4160749568},"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY":{"header_address":4761156,"warp_table_address":5466624},"MAP_SLATEPORT_CITY_HARBOR":{"header_address":4761352,"warp_table_address":5468328},"MAP_SLATEPORT_CITY_HOUSE":{"header_address":4761380,"warp_table_address":5468492},"MAP_SLATEPORT_CITY_MART":{"header_address":4761464,"warp_table_address":5468856},"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE":{"header_address":4761240,"warp_table_address":5466832},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F":{"header_address":4761296,"warp_table_address":5467456},"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F":{"header_address":4761324,"warp_table_address":5467856},"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F":{"header_address":4761408,"warp_table_address":5468600},"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F":{"header_address":4761436,"warp_table_address":5468740},"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB":{"header_address":4761268,"warp_table_address":5467084},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F":{"header_address":4761100,"warp_table_address":5466360},"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F":{"header_address":4761128,"warp_table_address":5466476},"MAP_SOOTOPOLIS_CITY":{"fishing_encounters":{"address":5612184,"slots":[129,72,129,129,129,129,129,130,130,130]},"header_address":4758188,"warp_table_address":5433852,"water_encounters":{"address":5612156,"slots":[129,129,129,129,129]}},"MAP_SOOTOPOLIS_CITY_GYM_1F":{"header_address":4763480,"warp_table_address":5481892},"MAP_SOOTOPOLIS_CITY_GYM_B1F":{"header_address":4763508,"warp_table_address":5482200},"MAP_SOOTOPOLIS_CITY_HOUSE1":{"header_address":4763620,"warp_table_address":5482664},"MAP_SOOTOPOLIS_CITY_HOUSE2":{"header_address":4763648,"warp_table_address":5482724},"MAP_SOOTOPOLIS_CITY_HOUSE3":{"header_address":4763676,"warp_table_address":5482808},"MAP_SOOTOPOLIS_CITY_HOUSE4":{"header_address":4763704,"warp_table_address":5482916},"MAP_SOOTOPOLIS_CITY_HOUSE5":{"header_address":4763732,"warp_table_address":5483000},"MAP_SOOTOPOLIS_CITY_HOUSE6":{"header_address":4763760,"warp_table_address":5483060},"MAP_SOOTOPOLIS_CITY_HOUSE7":{"header_address":4763788,"warp_table_address":5483144},"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE":{"header_address":4763816,"warp_table_address":5483228},"MAP_SOOTOPOLIS_CITY_MART":{"header_address":4763592,"warp_table_address":5482580},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F":{"header_address":4763844,"warp_table_address":5483312},"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F":{"header_address":4763872,"warp_table_address":5483380},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F":{"header_address":4763536,"warp_table_address":5482324},"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F":{"header_address":4763564,"warp_table_address":5482464},"MAP_SOUTHERN_ISLAND_EXTERIOR":{"header_address":4769640,"warp_table_address":5516780},"MAP_SOUTHERN_ISLAND_INTERIOR":{"header_address":4769668,"warp_table_address":5516876},"MAP_SS_TIDAL_CORRIDOR":{"header_address":4768828,"warp_table_address":5510992},"MAP_SS_TIDAL_LOWER_DECK":{"header_address":4768856,"warp_table_address":5511276},"MAP_SS_TIDAL_ROOMS":{"header_address":4768884,"warp_table_address":5511508},"MAP_TERRA_CAVE_END":{"header_address":4767596,"warp_table_address":5500392},"MAP_TERRA_CAVE_ENTRANCE":{"header_address":4767568,"warp_table_address":5500332},"MAP_TRADE_CENTER":{"header_address":4768380,"warp_table_address":5509944},"MAP_TRAINER_HILL_1F":{"header_address":4771096,"warp_table_address":5525172},"MAP_TRAINER_HILL_2F":{"header_address":4771124,"warp_table_address":5525208},"MAP_TRAINER_HILL_3F":{"header_address":4771152,"warp_table_address":5525244},"MAP_TRAINER_HILL_4F":{"header_address":4771180,"warp_table_address":5525280},"MAP_TRAINER_HILL_ELEVATOR":{"header_address":4771852,"warp_table_address":5526300},"MAP_TRAINER_HILL_ENTRANCE":{"header_address":4771068,"warp_table_address":5525100},"MAP_TRAINER_HILL_ROOF":{"header_address":4771208,"warp_table_address":5525340},"MAP_UNDERWATER_MARINE_CAVE":{"header_address":4767484,"warp_table_address":5500208},"MAP_UNDERWATER_ROUTE105":{"header_address":4759532,"warp_table_address":5457348},"MAP_UNDERWATER_ROUTE124":{"header_address":4759392,"warp_table_address":4160749568,"water_encounters":{"address":5612016,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE125":{"header_address":4759560,"warp_table_address":5457384},"MAP_UNDERWATER_ROUTE126":{"header_address":4759420,"warp_table_address":5457052,"water_encounters":{"address":5606268,"slots":[373,170,373,381,381]}},"MAP_UNDERWATER_ROUTE127":{"header_address":4759448,"warp_table_address":5457176},"MAP_UNDERWATER_ROUTE128":{"header_address":4759476,"warp_table_address":5457260},"MAP_UNDERWATER_ROUTE129":{"header_address":4759504,"warp_table_address":5457312},"MAP_UNDERWATER_ROUTE134":{"header_address":4766588,"warp_table_address":5497540},"MAP_UNDERWATER_SEAFLOOR_CAVERN":{"header_address":4765384,"warp_table_address":5491744},"MAP_UNDERWATER_SEALED_CHAMBER":{"header_address":4766616,"warp_table_address":5497568},"MAP_UNDERWATER_SOOTOPOLIS_CITY":{"header_address":4764796,"warp_table_address":5486768},"MAP_UNION_ROOM":{"header_address":4769360,"warp_table_address":5514872},"MAP_UNUSED_CONTEST_HALL1":{"header_address":4768492,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL2":{"header_address":4768520,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL3":{"header_address":4768548,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL4":{"header_address":4768576,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL5":{"header_address":4768604,"warp_table_address":4160749568},"MAP_UNUSED_CONTEST_HALL6":{"header_address":4768632,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN":{"header_address":4758384,"warp_table_address":5436044},"MAP_VERDANTURF_TOWN_BATTLE_TENT_BATTLE_ROOM":{"header_address":4760512,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_CORRIDOR":{"header_address":4760484,"warp_table_address":4160749568},"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY":{"header_address":4760456,"warp_table_address":5463128},"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE":{"header_address":4760652,"warp_table_address":5463928},"MAP_VERDANTURF_TOWN_HOUSE":{"header_address":4760680,"warp_table_address":5464012},"MAP_VERDANTURF_TOWN_MART":{"header_address":4760540,"warp_table_address":5463408},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F":{"header_address":4760568,"warp_table_address":5463540},"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F":{"header_address":4760596,"warp_table_address":5463680},"MAP_VERDANTURF_TOWN_WANDAS_HOUSE":{"header_address":4760624,"warp_table_address":5463844},"MAP_VICTORY_ROAD_1F":{"header_address":4765860,"land_encounters":{"address":5606156,"slots":[42,336,383,371,41,335,42,336,382,370,382,370]},"warp_table_address":5493852},"MAP_VICTORY_ROAD_B1F":{"header_address":4765888,"land_encounters":{"address":5610496,"slots":[42,336,383,383,42,336,42,336,383,355,383,355]},"rock_smash_encounters":{"address":5610552,"slots":[75,74,75,75,75]},"warp_table_address":5494460},"MAP_VICTORY_ROAD_B2F":{"fishing_encounters":{"address":5610664,"slots":[129,118,129,118,323,323,323,324,324,324]},"header_address":4765916,"land_encounters":{"address":5610580,"slots":[42,322,383,383,42,322,42,322,383,355,383,355]},"warp_table_address":5494704,"water_encounters":{"address":5610636,"slots":[42,42,42,42,42]}}},"misc_pokemon":[{"address":2572358,"species":385},{"address":2018148,"species":360},{"address":2323175,"species":101},{"address":2323252,"species":101},{"address":2581669,"species":317},{"address":2581574,"species":317},{"address":2581688,"species":317},{"address":2581593,"species":317},{"address":2581612,"species":317},{"address":2581631,"species":317},{"address":2581650,"species":317},{"address":2065036,"species":317},{"address":2386223,"species":185},{"address":2339323,"species":100},{"address":2339400,"species":100},{"address":2339477,"species":100}],"misc_ram_addresses":{"CB2_Overworld":134768624,"gArchipelagoDeathLinkQueued":33804824,"gArchipelagoReceivedItem":33804776,"gMain":50340544,"gPlayerParty":33703196,"gSaveBlock1Ptr":50355596,"gSaveBlock2Ptr":50355600},"misc_rom_addresses":{"FindObjectEventPaletteIndexByTag":586344,"LoadObjectEventPalette":586116,"PatchObjectPalette":586244,"gArchipelagoInfo":5912960,"gArchipelagoItemNames":5896457,"gArchipelagoNameTable":5905457,"gArchipelagoOptions":5895556,"gArchipelagoPlayerNames":5895607,"gBattleMoves":3281380,"gEvolutionTable":3318404,"gLevelUpLearnsets":3334884,"gMonBackPicTable":3174912,"gMonFootprintTable":5726932,"gMonFrontPicTable":3205844,"gMonIconPaletteIndices":5784268,"gMonIconTable":5782508,"gMonPaletteTable":3178432,"gMonShinyPaletteTable":3181952,"gObjectEventBaseOam_16x16":5311020,"gObjectEventBaseOam_16x32":5311044,"gObjectEventBaseOam_32x32":5311052,"gObjectEventGraphicsInfoPointers":5294928,"gRandomizedBerryTreeItems":5843560,"gRandomizedSoundTable":10155508,"gSpeciesInfo":3296744,"gTMHMLearnsets":3289780,"gTrainerBackAnimsPtrTable":3188308,"gTrainerBackPicPaletteTable":3188436,"gTrainerBackPicTable":3188372,"gTrainerFrontPicPaletteTable":3187332,"gTrainerFrontPicTable":3186588,"gTrainers":3230072,"gTutorMoves":6428060,"sBackAnims_Brendan":3188244,"sBackAnims_Red":3188260,"sEggHatchTiles":3344020,"sEggPalette":3343988,"sEmpty6":14929745,"sFanfares":5422580,"sNewGamePCItems":6210444,"sOamTables_16x16":5311100,"sOamTables_16x32":5311184,"sOamTables_32x32":5311268,"sObjectEventSpritePalettes":5320952,"sStarterMon":6021752,"sTMHMMoves":6432208,"sTrainerBackSpriteTemplates":3337568,"sTutorLearnsets":6428120},"species":[{"abilities":[0,0],"address":3296744,"base_stats":[0,0,0,0,0,0],"catch_rate":0,"evolutions":[],"friendship":0,"id":0,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3296772,"base_stats":[45,49,49,45,65,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":2}],"friendship":70,"id":1,"learnset":{"address":3308280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":20,"move_id":75},{"level":25,"move_id":230},{"level":32,"move_id":74},{"level":39,"move_id":235},{"level":46,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296800,"base_stats":[60,62,63,60,80,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":3}],"friendship":70,"id":2,"learnset":{"address":3308308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":38,"move_id":74},{"level":47,"move_id":235},{"level":56,"move_id":76}]},"tmhm_learnset":"00E41E0884350720","types":[12,3]},{"abilities":[65,0],"address":3296828,"base_stats":[80,82,83,80,100,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":3,"learnset":{"address":3308338,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":73},{"level":1,"move_id":22},{"level":4,"move_id":45},{"level":7,"move_id":73},{"level":10,"move_id":22},{"level":15,"move_id":77},{"level":15,"move_id":79},{"level":22,"move_id":75},{"level":29,"move_id":230},{"level":41,"move_id":74},{"level":53,"move_id":235},{"level":65,"move_id":76}]},"tmhm_learnset":"00E41E0886354730","types":[12,3]},{"abilities":[66,0],"address":3296856,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":5}],"friendship":70,"id":4,"learnset":{"address":3308368,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":19,"move_id":99},{"level":25,"move_id":184},{"level":31,"move_id":53},{"level":37,"move_id":163},{"level":43,"move_id":82},{"level":49,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296884,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":6}],"friendship":70,"id":5,"learnset":{"address":3308394,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":41,"move_id":163},{"level":48,"move_id":82},{"level":55,"move_id":83}]},"tmhm_learnset":"00A61EA4CC510623","types":[10,10]},{"abilities":[66,0],"address":3296912,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":6,"learnset":{"address":3308420,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":52},{"level":1,"move_id":108},{"level":7,"move_id":52},{"level":13,"move_id":108},{"level":20,"move_id":99},{"level":27,"move_id":184},{"level":34,"move_id":53},{"level":36,"move_id":17},{"level":44,"move_id":163},{"level":54,"move_id":82},{"level":64,"move_id":83}]},"tmhm_learnset":"00AE5EA4CE514633","types":[10,2]},{"abilities":[67,0],"address":3296940,"base_stats":[44,48,65,43,50,64],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":8}],"friendship":70,"id":7,"learnset":{"address":3308448,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":18,"move_id":44},{"level":23,"move_id":229},{"level":28,"move_id":182},{"level":33,"move_id":240},{"level":40,"move_id":130},{"level":47,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296968,"base_stats":[59,63,80,58,65,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":9}],"friendship":70,"id":8,"learnset":{"address":3308478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":37,"move_id":240},{"level":45,"move_id":130},{"level":53,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[67,0],"address":3296996,"base_stats":[79,83,100,78,85,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":9,"learnset":{"address":3308508,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":145},{"level":1,"move_id":110},{"level":4,"move_id":39},{"level":7,"move_id":145},{"level":10,"move_id":110},{"level":13,"move_id":55},{"level":19,"move_id":44},{"level":25,"move_id":229},{"level":31,"move_id":182},{"level":42,"move_id":240},{"level":55,"move_id":130},{"level":68,"move_id":56}]},"tmhm_learnset":"03B01E00CE537275","types":[11,11]},{"abilities":[19,0],"address":3297024,"base_stats":[45,30,35,45,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":11}],"friendship":70,"id":10,"learnset":{"address":3308538,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3297052,"base_stats":[50,20,55,30,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":12}],"friendship":70,"id":11,"learnset":{"address":3308548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[14,0],"address":3297080,"base_stats":[60,45,50,70,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":12,"learnset":{"address":3308560,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":77},{"level":14,"move_id":78},{"level":15,"move_id":79},{"level":18,"move_id":48},{"level":23,"move_id":18},{"level":28,"move_id":16},{"level":34,"move_id":60},{"level":40,"move_id":219},{"level":47,"move_id":318}]},"tmhm_learnset":"0040BE80B43F4620","types":[6,2]},{"abilities":[19,0],"address":3297108,"base_stats":[40,35,30,50,20,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":7,"species":14}],"friendship":70,"id":13,"learnset":{"address":3308590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[61,0],"address":3297136,"base_stats":[45,25,50,35,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":15}],"friendship":70,"id":14,"learnset":{"address":3308600,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,3]},{"abilities":[68,0],"address":3297164,"base_stats":[65,80,40,75,45,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":15,"learnset":{"address":3308612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":31},{"level":10,"move_id":31},{"level":15,"move_id":116},{"level":20,"move_id":41},{"level":25,"move_id":99},{"level":30,"move_id":228},{"level":35,"move_id":42},{"level":40,"move_id":97},{"level":45,"move_id":283}]},"tmhm_learnset":"00843E88C4354620","types":[6,3]},{"abilities":[51,0],"address":3297192,"base_stats":[40,45,40,56,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":17}],"friendship":70,"id":16,"learnset":{"address":3308638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":19,"move_id":18},{"level":25,"move_id":17},{"level":31,"move_id":297},{"level":39,"move_id":97},{"level":47,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297220,"base_stats":[63,60,55,71,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":18}],"friendship":70,"id":17,"learnset":{"address":3308664,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":43,"move_id":97},{"level":52,"move_id":119}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297248,"base_stats":[83,80,75,91,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":18,"learnset":{"address":3308690,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":28},{"level":1,"move_id":16},{"level":1,"move_id":98},{"level":5,"move_id":28},{"level":9,"move_id":16},{"level":13,"move_id":98},{"level":20,"move_id":18},{"level":27,"move_id":17},{"level":34,"move_id":297},{"level":48,"move_id":97},{"level":62,"move_id":119}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[50,62],"address":3297276,"base_stats":[30,56,35,72,25,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":20}],"friendship":70,"id":19,"learnset":{"address":3308716,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":116},{"level":27,"move_id":228},{"level":34,"move_id":162},{"level":41,"move_id":283}]},"tmhm_learnset":"00843E02ADD33E20","types":[0,0]},{"abilities":[50,62],"address":3297304,"base_stats":[55,81,60,97,50,70],"catch_rate":127,"evolutions":[],"friendship":70,"id":20,"learnset":{"address":3308738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":7,"move_id":98},{"level":13,"move_id":158},{"level":20,"move_id":184},{"level":30,"move_id":228},{"level":40,"move_id":162},{"level":50,"move_id":283}]},"tmhm_learnset":"00A43E02ADD37E30","types":[0,0]},{"abilities":[51,0],"address":3297332,"base_stats":[40,60,30,70,31,31],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":22}],"friendship":70,"id":21,"learnset":{"address":3308760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":19,"move_id":228},{"level":25,"move_id":332},{"level":31,"move_id":119},{"level":37,"move_id":65},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[51,0],"address":3297360,"base_stats":[65,90,65,100,61,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":22,"learnset":{"address":3308784,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":43},{"level":1,"move_id":31},{"level":7,"move_id":43},{"level":13,"move_id":31},{"level":26,"move_id":228},{"level":32,"move_id":119},{"level":40,"move_id":65},{"level":47,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[22,61],"address":3297388,"base_stats":[35,60,44,55,40,54],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":24}],"friendship":70,"id":23,"learnset":{"address":3308806,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":25,"move_id":103},{"level":32,"move_id":51},{"level":37,"move_id":254},{"level":37,"move_id":256},{"level":37,"move_id":255},{"level":44,"move_id":114}]},"tmhm_learnset":"00213F088E570620","types":[3,3]},{"abilities":[22,61],"address":3297416,"base_stats":[60,85,69,80,65,79],"catch_rate":90,"evolutions":[],"friendship":70,"id":24,"learnset":{"address":3308834,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":40},{"level":1,"move_id":44},{"level":8,"move_id":40},{"level":13,"move_id":44},{"level":20,"move_id":137},{"level":28,"move_id":103},{"level":38,"move_id":51},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255},{"level":56,"move_id":114}]},"tmhm_learnset":"00213F088E574620","types":[3,3]},{"abilities":[9,0],"address":3297444,"base_stats":[35,55,30,90,50,40],"catch_rate":190,"evolutions":[{"method":"ITEM","param":96,"species":26}],"friendship":70,"id":25,"learnset":{"address":3308862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":45},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":98},{"level":15,"move_id":104},{"level":20,"move_id":21},{"level":26,"move_id":85},{"level":33,"move_id":97},{"level":41,"move_id":87},{"level":50,"move_id":113}]},"tmhm_learnset":"00E01E02CDD38221","types":[13,13]},{"abilities":[9,0],"address":3297472,"base_stats":[60,90,55,100,90,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":26,"learnset":{"address":3308890,"moves":[{"level":1,"move_id":84},{"level":1,"move_id":39},{"level":1,"move_id":98},{"level":1,"move_id":85}]},"tmhm_learnset":"00E03E02CDD3C221","types":[13,13]},{"abilities":[8,0],"address":3297500,"base_stats":[50,75,85,40,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":28}],"friendship":70,"id":27,"learnset":{"address":3308900,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":23,"move_id":163},{"level":30,"move_id":129},{"level":37,"move_id":154},{"level":45,"move_id":328},{"level":53,"move_id":201}]},"tmhm_learnset":"00A43ED0CE510621","types":[4,4]},{"abilities":[8,0],"address":3297528,"base_stats":[75,100,110,65,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":28,"learnset":{"address":3308926,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":28},{"level":6,"move_id":111},{"level":11,"move_id":28},{"level":17,"move_id":40},{"level":24,"move_id":163},{"level":33,"move_id":129},{"level":42,"move_id":154},{"level":52,"move_id":328},{"level":62,"move_id":201}]},"tmhm_learnset":"00A43ED0CE514621","types":[4,4]},{"abilities":[38,0],"address":3297556,"base_stats":[55,47,52,41,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":30}],"friendship":70,"id":29,"learnset":{"address":3308952,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":44},{"level":23,"move_id":270},{"level":30,"move_id":154},{"level":38,"move_id":260},{"level":47,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297584,"base_stats":[70,62,67,56,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":31}],"friendship":70,"id":30,"learnset":{"address":3308978,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":10},{"level":8,"move_id":39},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":44},{"level":26,"move_id":270},{"level":34,"move_id":154},{"level":43,"move_id":260},{"level":53,"move_id":242}]},"tmhm_learnset":"00A43E8A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297612,"base_stats":[90,82,87,76,75,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":31,"learnset":{"address":3309004,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":34}]},"tmhm_learnset":"00B43FFEEFD37E35","types":[3,4]},{"abilities":[38,0],"address":3297640,"base_stats":[46,57,40,50,40,40],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":16,"species":33}],"friendship":70,"id":32,"learnset":{"address":3309016,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":17,"move_id":40},{"level":20,"move_id":30},{"level":23,"move_id":270},{"level":30,"move_id":31},{"level":38,"move_id":260},{"level":47,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297668,"base_stats":[61,72,57,65,55,55],"catch_rate":120,"evolutions":[{"method":"ITEM","param":94,"species":34}],"friendship":70,"id":33,"learnset":{"address":3309042,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":8,"move_id":116},{"level":12,"move_id":24},{"level":18,"move_id":40},{"level":22,"move_id":30},{"level":26,"move_id":270},{"level":34,"move_id":31},{"level":43,"move_id":260},{"level":53,"move_id":32}]},"tmhm_learnset":"00A43E0A8DD33624","types":[3,3]},{"abilities":[38,0],"address":3297696,"base_stats":[81,92,77,85,85,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":34,"learnset":{"address":3309068,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":116},{"level":1,"move_id":24},{"level":1,"move_id":40},{"level":23,"move_id":37}]},"tmhm_learnset":"00B43F7EEFD37E35","types":[3,4]},{"abilities":[56,0],"address":3297724,"base_stats":[70,45,48,35,60,65],"catch_rate":150,"evolutions":[{"method":"ITEM","param":94,"species":36}],"friendship":140,"id":35,"learnset":{"address":3309080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":227},{"level":9,"move_id":47},{"level":13,"move_id":3},{"level":17,"move_id":266},{"level":21,"move_id":107},{"level":25,"move_id":111},{"level":29,"move_id":118},{"level":33,"move_id":322},{"level":37,"move_id":236},{"level":41,"move_id":113},{"level":45,"move_id":309}]},"tmhm_learnset":"00611E27FDFBB62D","types":[0,0]},{"abilities":[56,0],"address":3297752,"base_stats":[95,70,73,60,85,90],"catch_rate":25,"evolutions":[],"friendship":140,"id":36,"learnset":{"address":3309112,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":3},{"level":1,"move_id":107},{"level":1,"move_id":118}]},"tmhm_learnset":"00611E27FDFBF62D","types":[0,0]},{"abilities":[18,0],"address":3297780,"base_stats":[38,41,40,65,50,65],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":38}],"friendship":70,"id":37,"learnset":{"address":3309122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":5,"move_id":39},{"level":9,"move_id":46},{"level":13,"move_id":98},{"level":17,"move_id":261},{"level":21,"move_id":109},{"level":25,"move_id":286},{"level":29,"move_id":53},{"level":33,"move_id":219},{"level":37,"move_id":288},{"level":41,"move_id":83}]},"tmhm_learnset":"00021E248C590630","types":[10,10]},{"abilities":[18,0],"address":3297808,"base_stats":[73,76,75,100,81,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":38,"learnset":{"address":3309152,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":98},{"level":1,"move_id":109},{"level":1,"move_id":219},{"level":45,"move_id":83}]},"tmhm_learnset":"00021E248C594630","types":[10,10]},{"abilities":[56,0],"address":3297836,"base_stats":[115,45,20,20,45,25],"catch_rate":170,"evolutions":[{"method":"ITEM","param":94,"species":40}],"friendship":70,"id":39,"learnset":{"address":3309164,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":50},{"level":19,"move_id":205},{"level":24,"move_id":3},{"level":29,"move_id":156},{"level":34,"move_id":34},{"level":39,"move_id":102},{"level":44,"move_id":304},{"level":49,"move_id":38}]},"tmhm_learnset":"00611E27FDBBB625","types":[0,0]},{"abilities":[56,0],"address":3297864,"base_stats":[140,70,45,45,75,50],"catch_rate":50,"evolutions":[],"friendship":70,"id":40,"learnset":{"address":3309194,"moves":[{"level":1,"move_id":47},{"level":1,"move_id":50},{"level":1,"move_id":111},{"level":1,"move_id":3}]},"tmhm_learnset":"00611E27FDBBF625","types":[0,0]},{"abilities":[39,0],"address":3297892,"base_stats":[40,45,35,55,30,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":42}],"friendship":70,"id":41,"learnset":{"address":3309204,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":141},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":26,"move_id":109},{"level":31,"move_id":314},{"level":36,"move_id":212},{"level":41,"move_id":305},{"level":46,"move_id":114}]},"tmhm_learnset":"00017F88A4170E20","types":[3,2]},{"abilities":[39,0],"address":3297920,"base_stats":[75,80,70,90,65,75],"catch_rate":90,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":169}],"friendship":70,"id":42,"learnset":{"address":3309232,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00017F88A4174E20","types":[3,2]},{"abilities":[34,0],"address":3297948,"base_stats":[45,50,55,30,75,65],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":44}],"friendship":70,"id":43,"learnset":{"address":3309260,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":23,"move_id":51},{"level":32,"move_id":236},{"level":39,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3297976,"base_stats":[60,65,70,40,85,75],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":45},{"method":"ITEM","param":93,"species":182}],"friendship":70,"id":44,"learnset":{"address":3309284,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":77},{"level":7,"move_id":230},{"level":14,"move_id":77},{"level":16,"move_id":78},{"level":18,"move_id":79},{"level":24,"move_id":51},{"level":35,"move_id":236},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298004,"base_stats":[75,80,85,50,100,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":45,"learnset":{"address":3309308,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":312},{"level":1,"move_id":78},{"level":1,"move_id":72},{"level":44,"move_id":80}]},"tmhm_learnset":"00441E0884354720","types":[12,3]},{"abilities":[27,0],"address":3298032,"base_stats":[35,70,55,25,45,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":24,"species":47}],"friendship":70,"id":46,"learnset":{"address":3309320,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":25,"move_id":147},{"level":31,"move_id":163},{"level":37,"move_id":74},{"level":43,"move_id":202},{"level":49,"move_id":312}]},"tmhm_learnset":"00C43E888C350720","types":[6,12]},{"abilities":[27,0],"address":3298060,"base_stats":[60,95,80,30,60,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":47,"learnset":{"address":3309346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":78},{"level":1,"move_id":77},{"level":7,"move_id":78},{"level":13,"move_id":77},{"level":19,"move_id":141},{"level":27,"move_id":147},{"level":35,"move_id":163},{"level":43,"move_id":74},{"level":51,"move_id":202},{"level":59,"move_id":312}]},"tmhm_learnset":"00C43E888C354720","types":[6,12]},{"abilities":[14,0],"address":3298088,"base_stats":[60,55,50,45,40,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":49}],"friendship":70,"id":48,"learnset":{"address":3309372,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":33,"move_id":60},{"level":36,"move_id":79},{"level":41,"move_id":94}]},"tmhm_learnset":"0040BE0894350620","types":[6,3]},{"abilities":[19,0],"address":3298116,"base_stats":[70,65,60,90,90,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":49,"learnset":{"address":3309398,"moves":[{"level":1,"move_id":318},{"level":1,"move_id":33},{"level":1,"move_id":50},{"level":1,"move_id":193},{"level":1,"move_id":48},{"level":9,"move_id":48},{"level":17,"move_id":93},{"level":20,"move_id":77},{"level":25,"move_id":141},{"level":28,"move_id":78},{"level":31,"move_id":16},{"level":36,"move_id":60},{"level":42,"move_id":79},{"level":52,"move_id":94}]},"tmhm_learnset":"0040BE8894354620","types":[6,3]},{"abilities":[8,71],"address":3298144,"base_stats":[10,55,25,95,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":26,"species":51}],"friendship":70,"id":50,"learnset":{"address":3309428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":33,"move_id":163},{"level":41,"move_id":89},{"level":49,"move_id":90}]},"tmhm_learnset":"00843EC88E110620","types":[4,4]},{"abilities":[8,71],"address":3298172,"base_stats":[35,80,50,120,50,70],"catch_rate":50,"evolutions":[],"friendship":70,"id":51,"learnset":{"address":3309452,"moves":[{"level":1,"move_id":161},{"level":1,"move_id":10},{"level":1,"move_id":28},{"level":1,"move_id":45},{"level":5,"move_id":45},{"level":9,"move_id":222},{"level":17,"move_id":91},{"level":25,"move_id":189},{"level":26,"move_id":328},{"level":38,"move_id":163},{"level":51,"move_id":89},{"level":64,"move_id":90}]},"tmhm_learnset":"00843EC88E114620","types":[4,4]},{"abilities":[53,0],"address":3298200,"base_stats":[40,45,35,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":28,"species":53}],"friendship":70,"id":52,"learnset":{"address":3309478,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":28,"move_id":185},{"level":35,"move_id":103},{"level":41,"move_id":154},{"level":46,"move_id":163},{"level":50,"move_id":252}]},"tmhm_learnset":"00453F82ADD30E24","types":[0,0]},{"abilities":[7,0],"address":3298228,"base_stats":[65,70,60,115,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":53,"learnset":{"address":3309502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":44},{"level":11,"move_id":44},{"level":20,"move_id":6},{"level":29,"move_id":185},{"level":38,"move_id":103},{"level":46,"move_id":154},{"level":53,"move_id":163},{"level":59,"move_id":252}]},"tmhm_learnset":"00453F82ADD34E34","types":[0,0]},{"abilities":[6,13],"address":3298256,"base_stats":[50,52,48,55,65,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":33,"species":55}],"friendship":70,"id":54,"learnset":{"address":3309526,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":40,"move_id":154},{"level":50,"move_id":56}]},"tmhm_learnset":"03F01E80CC53326D","types":[11,11]},{"abilities":[6,13],"address":3298284,"base_stats":[80,82,78,85,95,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":55,"learnset":{"address":3309550,"moves":[{"level":1,"move_id":346},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":1,"move_id":50},{"level":5,"move_id":39},{"level":10,"move_id":50},{"level":16,"move_id":93},{"level":23,"move_id":103},{"level":31,"move_id":244},{"level":44,"move_id":154},{"level":58,"move_id":56}]},"tmhm_learnset":"03F01E80CC53726D","types":[11,11]},{"abilities":[72,0],"address":3298312,"base_stats":[40,80,35,70,35,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":57}],"friendship":70,"id":56,"learnset":{"address":3309574,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":33,"move_id":69},{"level":39,"move_id":238},{"level":45,"move_id":103},{"level":51,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD30EA1","types":[1,1]},{"abilities":[72,0],"address":3298340,"base_stats":[65,105,60,95,60,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":57,"learnset":{"address":3309600,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":67},{"level":1,"move_id":99},{"level":9,"move_id":67},{"level":15,"move_id":2},{"level":21,"move_id":154},{"level":27,"move_id":116},{"level":28,"move_id":99},{"level":36,"move_id":69},{"level":45,"move_id":238},{"level":54,"move_id":103},{"level":63,"move_id":37}]},"tmhm_learnset":"00A23EC0CFD34EA1","types":[1,1]},{"abilities":[22,18],"address":3298368,"base_stats":[55,70,45,60,70,50],"catch_rate":190,"evolutions":[{"method":"ITEM","param":95,"species":59}],"friendship":70,"id":58,"learnset":{"address":3309628,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":7,"move_id":52},{"level":13,"move_id":43},{"level":19,"move_id":316},{"level":25,"move_id":36},{"level":31,"move_id":172},{"level":37,"move_id":270},{"level":43,"move_id":97},{"level":49,"move_id":53}]},"tmhm_learnset":"00A23EA48C510630","types":[10,10]},{"abilities":[22,18],"address":3298396,"base_stats":[90,110,80,95,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":59,"learnset":{"address":3309654,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":46},{"level":1,"move_id":52},{"level":1,"move_id":316},{"level":49,"move_id":245}]},"tmhm_learnset":"00A23EA48C514630","types":[10,10]},{"abilities":[11,6],"address":3298424,"base_stats":[40,50,40,90,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":61}],"friendship":70,"id":60,"learnset":{"address":3309666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":25,"move_id":240},{"level":31,"move_id":34},{"level":37,"move_id":187},{"level":43,"move_id":56}]},"tmhm_learnset":"03103E009C133264","types":[11,11]},{"abilities":[11,6],"address":3298452,"base_stats":[65,65,65,90,50,50],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":62},{"method":"ITEM","param":187,"species":186}],"friendship":70,"id":61,"learnset":{"address":3309690,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":95},{"level":1,"move_id":55},{"level":7,"move_id":95},{"level":13,"move_id":55},{"level":19,"move_id":3},{"level":27,"move_id":240},{"level":35,"move_id":34},{"level":43,"move_id":187},{"level":51,"move_id":56}]},"tmhm_learnset":"03B03E00DE133265","types":[11,11]},{"abilities":[11,6],"address":3298480,"base_stats":[90,85,95,70,70,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":62,"learnset":{"address":3309714,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":66},{"level":35,"move_id":66},{"level":51,"move_id":170}]},"tmhm_learnset":"03B03E40DE1372E5","types":[11,1]},{"abilities":[28,39],"address":3298508,"base_stats":[25,20,15,90,105,55],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":16,"species":64}],"friendship":70,"id":63,"learnset":{"address":3309728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":100}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298536,"base_stats":[40,35,30,105,120,70],"catch_rate":100,"evolutions":[{"method":"LEVEL","param":37,"species":65}],"friendship":70,"id":64,"learnset":{"address":3309738,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":272},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45B8E29","types":[14,14]},{"abilities":[28,39],"address":3298564,"base_stats":[55,50,45,120,135,85],"catch_rate":50,"evolutions":[],"friendship":70,"id":65,"learnset":{"address":3309766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":100},{"level":1,"move_id":134},{"level":1,"move_id":93},{"level":16,"move_id":93},{"level":18,"move_id":50},{"level":21,"move_id":60},{"level":23,"move_id":115},{"level":25,"move_id":105},{"level":30,"move_id":248},{"level":33,"move_id":347},{"level":36,"move_id":94},{"level":43,"move_id":271}]},"tmhm_learnset":"0041BF03B45BCE29","types":[14,14]},{"abilities":[62,0],"address":3298592,"base_stats":[70,80,50,35,35,35],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":28,"species":67}],"friendship":70,"id":66,"learnset":{"address":3309794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":31,"move_id":233},{"level":37,"move_id":66},{"level":40,"move_id":238},{"level":43,"move_id":184},{"level":49,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298620,"base_stats":[80,100,70,45,50,60],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":68}],"friendship":70,"id":67,"learnset":{"address":3309824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1306A1","types":[1,1]},{"abilities":[62,0],"address":3298648,"base_stats":[90,130,80,55,65,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":68,"learnset":{"address":3309854,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":67},{"level":1,"move_id":43},{"level":1,"move_id":116},{"level":7,"move_id":116},{"level":13,"move_id":2},{"level":19,"move_id":69},{"level":22,"move_id":193},{"level":25,"move_id":279},{"level":33,"move_id":233},{"level":41,"move_id":66},{"level":46,"move_id":238},{"level":51,"move_id":184},{"level":59,"move_id":223}]},"tmhm_learnset":"00A03E64CE1346A1","types":[1,1]},{"abilities":[34,0],"address":3298676,"base_stats":[50,75,35,40,70,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":21,"species":70}],"friendship":70,"id":69,"learnset":{"address":3309884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":23,"move_id":51},{"level":30,"move_id":230},{"level":37,"move_id":75},{"level":45,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298704,"base_stats":[65,90,50,55,85,45],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":71}],"friendship":70,"id":70,"learnset":{"address":3309912,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":22},{"level":1,"move_id":74},{"level":1,"move_id":35},{"level":6,"move_id":74},{"level":11,"move_id":35},{"level":15,"move_id":79},{"level":17,"move_id":77},{"level":19,"move_id":78},{"level":24,"move_id":51},{"level":33,"move_id":230},{"level":42,"move_id":75},{"level":54,"move_id":21}]},"tmhm_learnset":"00443E0884350720","types":[12,3]},{"abilities":[34,0],"address":3298732,"base_stats":[80,105,65,70,100,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":71,"learnset":{"address":3309940,"moves":[{"level":1,"move_id":22},{"level":1,"move_id":79},{"level":1,"move_id":230},{"level":1,"move_id":75}]},"tmhm_learnset":"00443E0884354720","types":[12,3]},{"abilities":[29,64],"address":3298760,"base_stats":[40,40,35,70,50,100],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":73}],"friendship":70,"id":72,"learnset":{"address":3309950,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":36,"move_id":112},{"level":43,"move_id":103},{"level":49,"move_id":56}]},"tmhm_learnset":"03143E0884173264","types":[11,3]},{"abilities":[29,64],"address":3298788,"base_stats":[80,70,65,100,80,120],"catch_rate":60,"evolutions":[],"friendship":70,"id":73,"learnset":{"address":3309976,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":48},{"level":1,"move_id":132},{"level":6,"move_id":48},{"level":12,"move_id":132},{"level":19,"move_id":51},{"level":25,"move_id":61},{"level":30,"move_id":35},{"level":38,"move_id":112},{"level":47,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03143E0884177264","types":[11,3]},{"abilities":[69,5],"address":3298816,"base_stats":[40,80,100,20,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":25,"species":75}],"friendship":70,"id":74,"learnset":{"address":3310002,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":26,"move_id":205},{"level":31,"move_id":350},{"level":36,"move_id":89},{"level":41,"move_id":153},{"level":46,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298844,"base_stats":[55,95,115,35,45,45],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":37,"species":76}],"friendship":70,"id":75,"learnset":{"address":3310030,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE110621","types":[5,4]},{"abilities":[69,5],"address":3298872,"base_stats":[80,110,130,45,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":76,"learnset":{"address":3310058,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":300},{"level":1,"move_id":88},{"level":6,"move_id":300},{"level":11,"move_id":88},{"level":16,"move_id":222},{"level":21,"move_id":120},{"level":29,"move_id":205},{"level":37,"move_id":350},{"level":45,"move_id":89},{"level":53,"move_id":153},{"level":62,"move_id":38}]},"tmhm_learnset":"00A01E74CE114631","types":[5,4]},{"abilities":[50,18],"address":3298900,"base_stats":[50,85,55,90,65,65],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":40,"species":78}],"friendship":70,"id":77,"learnset":{"address":3310086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":45,"move_id":340},{"level":53,"move_id":126}]},"tmhm_learnset":"00221E2484710620","types":[10,10]},{"abilities":[50,18],"address":3298928,"base_stats":[65,100,70,105,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":78,"learnset":{"address":3310114,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":52},{"level":5,"move_id":45},{"level":9,"move_id":39},{"level":14,"move_id":52},{"level":19,"move_id":23},{"level":25,"move_id":83},{"level":31,"move_id":36},{"level":38,"move_id":97},{"level":40,"move_id":31},{"level":50,"move_id":340},{"level":63,"move_id":126}]},"tmhm_learnset":"00221E2484714620","types":[10,10]},{"abilities":[12,20],"address":3298956,"base_stats":[90,65,65,15,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":80},{"method":"ITEM","param":187,"species":199}],"friendship":70,"id":79,"learnset":{"address":3310144,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":133},{"level":48,"move_id":94}]},"tmhm_learnset":"02709E24BE5B366C","types":[11,14]},{"abilities":[12,20],"address":3298984,"base_stats":[95,75,110,30,100,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":80,"learnset":{"address":3310168,"moves":[{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":37,"move_id":110},{"level":46,"move_id":133},{"level":54,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[42,5],"address":3299012,"base_stats":[25,35,70,45,95,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":82}],"friendship":70,"id":81,"learnset":{"address":3310194,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":32,"move_id":199},{"level":38,"move_id":129},{"level":44,"move_id":103},{"level":50,"move_id":192}]},"tmhm_learnset":"00400E0385930620","types":[13,8]},{"abilities":[42,5],"address":3299040,"base_stats":[50,60,95,70,120,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":82,"learnset":{"address":3310222,"moves":[{"level":1,"move_id":319},{"level":1,"move_id":33},{"level":1,"move_id":84},{"level":1,"move_id":48},{"level":6,"move_id":84},{"level":11,"move_id":48},{"level":16,"move_id":49},{"level":21,"move_id":86},{"level":26,"move_id":209},{"level":35,"move_id":199},{"level":44,"move_id":161},{"level":53,"move_id":103},{"level":62,"move_id":192}]},"tmhm_learnset":"00400E0385934620","types":[13,8]},{"abilities":[51,39],"address":3299068,"base_stats":[52,65,55,60,58,62],"catch_rate":45,"evolutions":[],"friendship":70,"id":83,"learnset":{"address":3310250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":6,"move_id":28},{"level":11,"move_id":43},{"level":16,"move_id":31},{"level":21,"move_id":282},{"level":26,"move_id":210},{"level":31,"move_id":14},{"level":36,"move_id":97},{"level":41,"move_id":163},{"level":46,"move_id":206}]},"tmhm_learnset":"000C7E8084510620","types":[0,2]},{"abilities":[50,48],"address":3299096,"base_stats":[35,85,45,75,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":85}],"friendship":70,"id":84,"learnset":{"address":3310278,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":33,"move_id":253},{"level":37,"move_id":65},{"level":45,"move_id":97}]},"tmhm_learnset":"00087E8084110620","types":[0,2]},{"abilities":[50,48],"address":3299124,"base_stats":[60,110,70,100,60,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":85,"learnset":{"address":3310302,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":228},{"level":1,"move_id":31},{"level":9,"move_id":228},{"level":13,"move_id":31},{"level":21,"move_id":161},{"level":25,"move_id":99},{"level":38,"move_id":253},{"level":47,"move_id":65},{"level":60,"move_id":97}]},"tmhm_learnset":"00087F8084114E20","types":[0,2]},{"abilities":[47,0],"address":3299152,"base_stats":[65,45,55,45,45,70],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":34,"species":87}],"friendship":70,"id":86,"learnset":{"address":3310326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":29},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":37,"move_id":36},{"level":41,"move_id":58},{"level":49,"move_id":219}]},"tmhm_learnset":"03103E00841B3264","types":[11,11]},{"abilities":[47,0],"address":3299180,"base_stats":[90,70,80,70,70,95],"catch_rate":75,"evolutions":[],"friendship":70,"id":87,"learnset":{"address":3310350,"moves":[{"level":1,"move_id":29},{"level":1,"move_id":45},{"level":1,"move_id":196},{"level":1,"move_id":62},{"level":9,"move_id":45},{"level":17,"move_id":196},{"level":21,"move_id":62},{"level":29,"move_id":156},{"level":34,"move_id":329},{"level":42,"move_id":36},{"level":51,"move_id":58},{"level":64,"move_id":219}]},"tmhm_learnset":"03103E00841B7264","types":[11,15]},{"abilities":[1,60],"address":3299208,"base_stats":[80,80,50,25,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":89}],"friendship":70,"id":88,"learnset":{"address":3310376,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":43,"move_id":188},{"level":53,"move_id":262}]},"tmhm_learnset":"00003F6E8D970E20","types":[3,3]},{"abilities":[1,60],"address":3299236,"base_stats":[105,105,75,50,65,100],"catch_rate":75,"evolutions":[],"friendship":70,"id":89,"learnset":{"address":3310402,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":4,"move_id":106},{"level":8,"move_id":50},{"level":13,"move_id":124},{"level":19,"move_id":107},{"level":26,"move_id":103},{"level":34,"move_id":151},{"level":47,"move_id":188},{"level":61,"move_id":262}]},"tmhm_learnset":"00A03F6ECD974E21","types":[3,3]},{"abilities":[75,0],"address":3299264,"base_stats":[30,65,100,40,45,25],"catch_rate":190,"evolutions":[{"method":"ITEM","param":97,"species":91}],"friendship":70,"id":90,"learnset":{"address":3310428,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":110},{"level":9,"move_id":48},{"level":17,"move_id":62},{"level":25,"move_id":182},{"level":33,"move_id":43},{"level":41,"move_id":128},{"level":49,"move_id":58}]},"tmhm_learnset":"02101E0084133264","types":[11,11]},{"abilities":[75,0],"address":3299292,"base_stats":[50,95,180,70,85,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":91,"learnset":{"address":3310450,"moves":[{"level":1,"move_id":110},{"level":1,"move_id":48},{"level":1,"move_id":62},{"level":1,"move_id":182},{"level":33,"move_id":191},{"level":41,"move_id":131}]},"tmhm_learnset":"02101F0084137264","types":[11,15]},{"abilities":[26,0],"address":3299320,"base_stats":[30,35,30,80,100,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":93}],"friendship":70,"id":92,"learnset":{"address":3310464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":28,"move_id":109},{"level":33,"move_id":138},{"level":36,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299348,"base_stats":[45,50,45,95,115,55],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":37,"species":94}],"friendship":70,"id":93,"learnset":{"address":3310488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"0001BF08B4970E20","types":[7,3]},{"abilities":[26,0],"address":3299376,"base_stats":[60,65,60,110,130,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":94,"learnset":{"address":3310514,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":95},{"level":1,"move_id":122},{"level":1,"move_id":180},{"level":8,"move_id":180},{"level":13,"move_id":212},{"level":16,"move_id":174},{"level":21,"move_id":101},{"level":25,"move_id":325},{"level":31,"move_id":109},{"level":39,"move_id":138},{"level":48,"move_id":194}]},"tmhm_learnset":"00A1BF08F5974E21","types":[7,3]},{"abilities":[69,5],"address":3299404,"base_stats":[35,45,160,70,30,45],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":208}],"friendship":70,"id":95,"learnset":{"address":3310540,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":328},{"level":57,"move_id":38}]},"tmhm_learnset":"00A01F508E510E30","types":[5,4]},{"abilities":[15,0],"address":3299432,"base_stats":[60,48,45,42,43,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":26,"species":97}],"friendship":70,"id":96,"learnset":{"address":3310568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":31,"move_id":139},{"level":36,"move_id":96},{"level":40,"move_id":94},{"level":43,"move_id":244},{"level":45,"move_id":248}]},"tmhm_learnset":"0041BF01F41B8E29","types":[14,14]},{"abilities":[15,0],"address":3299460,"base_stats":[85,73,70,67,73,115],"catch_rate":75,"evolutions":[],"friendship":70,"id":97,"learnset":{"address":3310594,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":95},{"level":1,"move_id":50},{"level":1,"move_id":93},{"level":10,"move_id":50},{"level":18,"move_id":93},{"level":25,"move_id":29},{"level":33,"move_id":139},{"level":40,"move_id":96},{"level":49,"move_id":94},{"level":55,"move_id":244},{"level":60,"move_id":248}]},"tmhm_learnset":"0041BF01F41BCE29","types":[14,14]},{"abilities":[52,75],"address":3299488,"base_stats":[30,105,90,50,25,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":28,"species":99}],"friendship":70,"id":98,"learnset":{"address":3310620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":34,"move_id":12},{"level":41,"move_id":182},{"level":45,"move_id":152}]},"tmhm_learnset":"02B43E408C133264","types":[11,11]},{"abilities":[52,75],"address":3299516,"base_stats":[55,130,115,75,50,50],"catch_rate":60,"evolutions":[],"friendship":70,"id":99,"learnset":{"address":3310646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":43},{"level":1,"move_id":11},{"level":5,"move_id":43},{"level":12,"move_id":11},{"level":16,"move_id":106},{"level":23,"move_id":341},{"level":27,"move_id":23},{"level":38,"move_id":12},{"level":49,"move_id":182},{"level":57,"move_id":152}]},"tmhm_learnset":"02B43E408C137264","types":[11,11]},{"abilities":[43,9],"address":3299544,"base_stats":[40,30,50,100,55,55],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":101}],"friendship":70,"id":100,"learnset":{"address":3310672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":32,"move_id":205},{"level":37,"move_id":113},{"level":42,"move_id":129},{"level":46,"move_id":153},{"level":49,"move_id":243}]},"tmhm_learnset":"00402F0285938A20","types":[13,13]},{"abilities":[43,9],"address":3299572,"base_stats":[60,50,70,140,80,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":101,"learnset":{"address":3310700,"moves":[{"level":1,"move_id":268},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":1,"move_id":49},{"level":8,"move_id":103},{"level":15,"move_id":49},{"level":21,"move_id":209},{"level":27,"move_id":120},{"level":34,"move_id":205},{"level":41,"move_id":113},{"level":48,"move_id":129},{"level":54,"move_id":153},{"level":59,"move_id":243}]},"tmhm_learnset":"00402F028593CA20","types":[13,13]},{"abilities":[34,0],"address":3299600,"base_stats":[60,40,80,40,60,45],"catch_rate":90,"evolutions":[{"method":"ITEM","param":98,"species":103}],"friendship":70,"id":102,"learnset":{"address":3310728,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":253},{"level":1,"move_id":95},{"level":7,"move_id":115},{"level":13,"move_id":73},{"level":19,"move_id":93},{"level":25,"move_id":78},{"level":31,"move_id":77},{"level":37,"move_id":79},{"level":43,"move_id":76}]},"tmhm_learnset":"0060BE0994358720","types":[12,14]},{"abilities":[34,0],"address":3299628,"base_stats":[95,95,85,55,125,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":103,"learnset":{"address":3310752,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":140},{"level":1,"move_id":95},{"level":1,"move_id":93},{"level":19,"move_id":23},{"level":31,"move_id":121}]},"tmhm_learnset":"0060BE099435C720","types":[12,14]},{"abilities":[69,31],"address":3299656,"base_stats":[50,50,95,35,40,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":28,"species":105}],"friendship":70,"id":104,"learnset":{"address":3310766,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":125},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":29,"move_id":99},{"level":33,"move_id":206},{"level":37,"move_id":37},{"level":41,"move_id":198},{"level":45,"move_id":38}]},"tmhm_learnset":"00A03EF4CE513621","types":[4,4]},{"abilities":[69,31],"address":3299684,"base_stats":[60,80,110,45,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":105,"learnset":{"address":3310798,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":125},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":125},{"level":13,"move_id":29},{"level":17,"move_id":43},{"level":21,"move_id":116},{"level":25,"move_id":155},{"level":32,"move_id":99},{"level":39,"move_id":206},{"level":46,"move_id":37},{"level":53,"move_id":198},{"level":61,"move_id":38}]},"tmhm_learnset":"00A03EF4CE517621","types":[4,4]},{"abilities":[7,0],"address":3299712,"base_stats":[50,120,53,87,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":106,"learnset":{"address":3310830,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":24},{"level":6,"move_id":96},{"level":11,"move_id":27},{"level":16,"move_id":26},{"level":20,"move_id":280},{"level":21,"move_id":116},{"level":26,"move_id":136},{"level":31,"move_id":170},{"level":36,"move_id":193},{"level":41,"move_id":203},{"level":46,"move_id":25},{"level":51,"move_id":179}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[51,0],"address":3299740,"base_stats":[50,105,79,76,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":107,"learnset":{"address":3310862,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":4},{"level":7,"move_id":97},{"level":13,"move_id":228},{"level":20,"move_id":183},{"level":26,"move_id":9},{"level":26,"move_id":8},{"level":26,"move_id":7},{"level":32,"move_id":327},{"level":38,"move_id":5},{"level":44,"move_id":197},{"level":50,"move_id":68}]},"tmhm_learnset":"00A03E40C61306A1","types":[1,1]},{"abilities":[20,12],"address":3299768,"base_stats":[90,55,75,30,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":108,"learnset":{"address":3310892,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":122},{"level":7,"move_id":48},{"level":12,"move_id":111},{"level":18,"move_id":282},{"level":23,"move_id":23},{"level":29,"move_id":35},{"level":34,"move_id":50},{"level":40,"move_id":21},{"level":45,"move_id":103},{"level":51,"move_id":287}]},"tmhm_learnset":"00B43E76EFF37625","types":[0,0]},{"abilities":[26,0],"address":3299796,"base_stats":[40,65,95,35,60,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":35,"species":110}],"friendship":70,"id":109,"learnset":{"address":3310920,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":41,"move_id":153},{"level":45,"move_id":194},{"level":49,"move_id":262}]},"tmhm_learnset":"00403F2EA5930E20","types":[3,3]},{"abilities":[26,0],"address":3299824,"base_stats":[65,90,120,60,85,70],"catch_rate":60,"evolutions":[],"friendship":70,"id":110,"learnset":{"address":3310946,"moves":[{"level":1,"move_id":139},{"level":1,"move_id":33},{"level":1,"move_id":123},{"level":1,"move_id":120},{"level":9,"move_id":123},{"level":17,"move_id":120},{"level":21,"move_id":124},{"level":25,"move_id":108},{"level":33,"move_id":114},{"level":44,"move_id":153},{"level":51,"move_id":194},{"level":58,"move_id":262}]},"tmhm_learnset":"00403F2EA5934E20","types":[3,3]},{"abilities":[31,69],"address":3299852,"base_stats":[80,85,95,25,30,30],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":42,"species":112}],"friendship":70,"id":111,"learnset":{"address":3310972,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":43,"move_id":36},{"level":52,"move_id":89},{"level":57,"move_id":224}]},"tmhm_learnset":"00A03E768FD33630","types":[4,5]},{"abilities":[31,69],"address":3299880,"base_stats":[105,130,120,40,45,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":112,"learnset":{"address":3310998,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":39},{"level":1,"move_id":23},{"level":1,"move_id":31},{"level":10,"move_id":23},{"level":15,"move_id":31},{"level":24,"move_id":184},{"level":29,"move_id":350},{"level":38,"move_id":32},{"level":46,"move_id":36},{"level":58,"move_id":89},{"level":66,"move_id":224}]},"tmhm_learnset":"00B43E76CFD37631","types":[4,5]},{"abilities":[30,32],"address":3299908,"base_stats":[250,5,5,50,35,105],"catch_rate":30,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":242}],"friendship":140,"id":113,"learnset":{"address":3311024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":287},{"level":13,"move_id":135},{"level":17,"move_id":3},{"level":23,"move_id":107},{"level":29,"move_id":47},{"level":35,"move_id":121},{"level":41,"move_id":111},{"level":49,"move_id":113},{"level":57,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[34,0],"address":3299936,"base_stats":[65,55,115,60,100,40],"catch_rate":45,"evolutions":[],"friendship":70,"id":114,"learnset":{"address":3311054,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":275},{"level":1,"move_id":132},{"level":4,"move_id":79},{"level":10,"move_id":71},{"level":13,"move_id":74},{"level":19,"move_id":77},{"level":22,"move_id":22},{"level":28,"move_id":20},{"level":31,"move_id":72},{"level":37,"move_id":78},{"level":40,"move_id":21},{"level":46,"move_id":321}]},"tmhm_learnset":"00C43E0884354720","types":[12,12]},{"abilities":[48,0],"address":3299964,"base_stats":[105,95,80,90,40,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":115,"learnset":{"address":3311084,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":4},{"level":1,"move_id":43},{"level":7,"move_id":44},{"level":13,"move_id":39},{"level":19,"move_id":252},{"level":25,"move_id":5},{"level":31,"move_id":99},{"level":37,"move_id":203},{"level":43,"move_id":146},{"level":49,"move_id":179}]},"tmhm_learnset":"00B43EF6EFF37675","types":[0,0]},{"abilities":[33,0],"address":3299992,"base_stats":[30,40,70,60,70,25],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":32,"species":117}],"friendship":70,"id":116,"learnset":{"address":3311110,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":36,"move_id":97},{"level":43,"move_id":56},{"level":50,"move_id":349}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[38,0],"address":3300020,"base_stats":[55,65,95,85,95,45],"catch_rate":75,"evolutions":[{"method":"ITEM","param":201,"species":230}],"friendship":70,"id":117,"learnset":{"address":3311134,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[33,41],"address":3300048,"base_stats":[45,67,60,63,35,50],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":119}],"friendship":70,"id":118,"learnset":{"address":3311158,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":38,"move_id":127},{"level":43,"move_id":32},{"level":52,"move_id":97}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,41],"address":3300076,"base_stats":[80,92,65,68,65,80],"catch_rate":60,"evolutions":[],"friendship":70,"id":119,"learnset":{"address":3311182,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":39},{"level":1,"move_id":346},{"level":1,"move_id":48},{"level":10,"move_id":48},{"level":15,"move_id":30},{"level":24,"move_id":175},{"level":29,"move_id":31},{"level":41,"move_id":127},{"level":49,"move_id":32},{"level":61,"move_id":97}]},"tmhm_learnset":"03101E0084137264","types":[11,11]},{"abilities":[35,30],"address":3300104,"base_stats":[30,45,55,85,70,55],"catch_rate":225,"evolutions":[{"method":"ITEM","param":97,"species":121}],"friendship":70,"id":120,"learnset":{"address":3311206,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":6,"move_id":55},{"level":10,"move_id":229},{"level":15,"move_id":105},{"level":19,"move_id":293},{"level":24,"move_id":129},{"level":28,"move_id":61},{"level":33,"move_id":107},{"level":37,"move_id":113},{"level":42,"move_id":322},{"level":46,"move_id":56}]},"tmhm_learnset":"03500E019593B264","types":[11,11]},{"abilities":[35,30],"address":3300132,"base_stats":[60,75,85,115,100,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":121,"learnset":{"address":3311236,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":229},{"level":1,"move_id":105},{"level":1,"move_id":129},{"level":33,"move_id":109}]},"tmhm_learnset":"03508E019593F264","types":[11,14]},{"abilities":[43,0],"address":3300160,"base_stats":[40,45,65,90,100,120],"catch_rate":45,"evolutions":[],"friendship":70,"id":122,"learnset":{"address":3311248,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":112},{"level":5,"move_id":93},{"level":9,"move_id":164},{"level":13,"move_id":96},{"level":17,"move_id":3},{"level":21,"move_id":113},{"level":21,"move_id":115},{"level":25,"move_id":227},{"level":29,"move_id":60},{"level":33,"move_id":278},{"level":37,"move_id":271},{"level":41,"move_id":272},{"level":45,"move_id":94},{"level":49,"move_id":226},{"level":53,"move_id":219}]},"tmhm_learnset":"0041BF03F5BBCE29","types":[14,14]},{"abilities":[68,0],"address":3300188,"base_stats":[70,110,80,105,55,80],"catch_rate":45,"evolutions":[{"method":"ITEM","param":199,"species":212}],"friendship":70,"id":123,"learnset":{"address":3311286,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":17},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00847E8084134620","types":[6,2]},{"abilities":[12,0],"address":3300216,"base_stats":[65,50,35,95,115,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":124,"learnset":{"address":3311314,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":1,"move_id":142},{"level":1,"move_id":181},{"level":9,"move_id":142},{"level":13,"move_id":181},{"level":21,"move_id":3},{"level":25,"move_id":8},{"level":35,"move_id":212},{"level":41,"move_id":313},{"level":51,"move_id":34},{"level":57,"move_id":195},{"level":67,"move_id":59}]},"tmhm_learnset":"0040BF01F413FA6D","types":[15,14]},{"abilities":[9,0],"address":3300244,"base_stats":[65,83,57,105,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":125,"learnset":{"address":3311342,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":1,"move_id":9},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":36,"move_id":103},{"level":47,"move_id":85},{"level":58,"move_id":87}]},"tmhm_learnset":"00E03E02D5D3C221","types":[13,13]},{"abilities":[49,0],"address":3300272,"base_stats":[65,95,57,93,100,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":126,"learnset":{"address":3311364,"moves":[{"level":1,"move_id":52},{"level":1,"move_id":43},{"level":1,"move_id":123},{"level":1,"move_id":7},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":33,"move_id":241},{"level":41,"move_id":53},{"level":49,"move_id":109},{"level":57,"move_id":126}]},"tmhm_learnset":"00A03E24D4514621","types":[10,10]},{"abilities":[52,0],"address":3300300,"base_stats":[65,125,100,85,55,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":127,"learnset":{"address":3311390,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":11},{"level":1,"move_id":116},{"level":7,"move_id":20},{"level":13,"move_id":69},{"level":19,"move_id":106},{"level":25,"move_id":279},{"level":31,"move_id":280},{"level":37,"move_id":12},{"level":43,"move_id":66},{"level":49,"move_id":14}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,6]},{"abilities":[22,0],"address":3300328,"base_stats":[75,100,95,110,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":128,"learnset":{"address":3311416,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":39},{"level":8,"move_id":99},{"level":13,"move_id":30},{"level":19,"move_id":184},{"level":26,"move_id":228},{"level":34,"move_id":156},{"level":43,"move_id":37},{"level":53,"move_id":36}]},"tmhm_learnset":"00B01E7687F37624","types":[0,0]},{"abilities":[33,0],"address":3300356,"base_stats":[20,10,55,80,15,20],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":130}],"friendship":70,"id":129,"learnset":{"address":3311442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"0000000000000000","types":[11,11]},{"abilities":[22,0],"address":3300384,"base_stats":[95,125,79,81,60,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":130,"learnset":{"address":3311456,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":37},{"level":20,"move_id":44},{"level":25,"move_id":82},{"level":30,"move_id":43},{"level":35,"move_id":239},{"level":40,"move_id":56},{"level":45,"move_id":240},{"level":50,"move_id":349},{"level":55,"move_id":63}]},"tmhm_learnset":"03B01F3487937A74","types":[11,2]},{"abilities":[11,75],"address":3300412,"base_stats":[130,85,80,60,85,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":131,"learnset":{"address":3311482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":45},{"level":1,"move_id":47},{"level":7,"move_id":54},{"level":13,"move_id":34},{"level":19,"move_id":109},{"level":25,"move_id":195},{"level":31,"move_id":58},{"level":37,"move_id":240},{"level":43,"move_id":219},{"level":49,"move_id":56},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E0295DB7274","types":[11,15]},{"abilities":[7,0],"address":3300440,"base_stats":[48,48,48,48,48,48],"catch_rate":35,"evolutions":[],"friendship":70,"id":132,"learnset":{"address":3311510,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":144}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[50,0],"address":3300468,"base_stats":[55,55,50,55,45,65],"catch_rate":45,"evolutions":[{"method":"ITEM","param":96,"species":135},{"method":"ITEM","param":97,"species":134},{"method":"ITEM","param":95,"species":136},{"method":"FRIENDSHIP_DAY","param":0,"species":196},{"method":"FRIENDSHIP_NIGHT","param":0,"species":197}],"friendship":70,"id":133,"learnset":{"address":3311520,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":45},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":226},{"level":42,"move_id":36}]},"tmhm_learnset":"00001E00AC530620","types":[0,0]},{"abilities":[11,0],"address":3300496,"base_stats":[130,65,60,65,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":134,"learnset":{"address":3311542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":55},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":62},{"level":42,"move_id":114},{"level":47,"move_id":151},{"level":52,"move_id":56}]},"tmhm_learnset":"03101E00AC537674","types":[11,11]},{"abilities":[10,0],"address":3300524,"base_stats":[65,65,60,130,110,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":135,"learnset":{"address":3311568,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":84},{"level":23,"move_id":98},{"level":30,"move_id":24},{"level":36,"move_id":42},{"level":42,"move_id":86},{"level":47,"move_id":97},{"level":52,"move_id":87}]},"tmhm_learnset":"00401E02ADD34630","types":[13,13]},{"abilities":[18,0],"address":3300552,"base_stats":[65,130,60,65,95,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":136,"learnset":{"address":3311594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":52},{"level":23,"move_id":98},{"level":30,"move_id":44},{"level":36,"move_id":83},{"level":42,"move_id":123},{"level":47,"move_id":43},{"level":52,"move_id":53}]},"tmhm_learnset":"00021E24AC534630","types":[10,10]},{"abilities":[36,0],"address":3300580,"base_stats":[65,60,70,40,85,75],"catch_rate":45,"evolutions":[{"method":"ITEM","param":218,"species":233}],"friendship":70,"id":137,"learnset":{"address":3311620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":159},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[33,75],"address":3300608,"base_stats":[35,40,100,35,90,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":139}],"friendship":70,"id":138,"learnset":{"address":3311646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":43,"move_id":321},{"level":49,"move_id":246},{"level":55,"move_id":56}]},"tmhm_learnset":"03903E5084133264","types":[5,11]},{"abilities":[33,75],"address":3300636,"base_stats":[70,60,125,55,115,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":139,"learnset":{"address":3311672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":1,"move_id":44},{"level":13,"move_id":44},{"level":19,"move_id":55},{"level":25,"move_id":341},{"level":31,"move_id":43},{"level":37,"move_id":182},{"level":40,"move_id":131},{"level":46,"move_id":321},{"level":55,"move_id":246},{"level":65,"move_id":56}]},"tmhm_learnset":"03903E5084137264","types":[5,11]},{"abilities":[33,4],"address":3300664,"base_stats":[30,80,90,55,55,45],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":141}],"friendship":70,"id":140,"learnset":{"address":3311700,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":43,"move_id":319},{"level":49,"move_id":72},{"level":55,"move_id":246}]},"tmhm_learnset":"01903ED08C173264","types":[5,11]},{"abilities":[33,4],"address":3300692,"base_stats":[60,115,105,80,65,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":141,"learnset":{"address":3311726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":71},{"level":13,"move_id":71},{"level":19,"move_id":43},{"level":25,"move_id":341},{"level":31,"move_id":28},{"level":37,"move_id":203},{"level":40,"move_id":163},{"level":46,"move_id":319},{"level":55,"move_id":72},{"level":65,"move_id":246}]},"tmhm_learnset":"03943ED0CC177264","types":[5,11]},{"abilities":[69,46],"address":3300720,"base_stats":[80,105,65,130,60,75],"catch_rate":45,"evolutions":[],"friendship":70,"id":142,"learnset":{"address":3311754,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":8,"move_id":97},{"level":15,"move_id":44},{"level":22,"move_id":48},{"level":29,"move_id":246},{"level":36,"move_id":184},{"level":43,"move_id":36},{"level":50,"move_id":63}]},"tmhm_learnset":"00A87FF486534E32","types":[5,2]},{"abilities":[17,47],"address":3300748,"base_stats":[160,110,65,30,65,110],"catch_rate":25,"evolutions":[],"friendship":70,"id":143,"learnset":{"address":3311778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":133},{"level":10,"move_id":111},{"level":15,"move_id":187},{"level":19,"move_id":29},{"level":24,"move_id":281},{"level":28,"move_id":156},{"level":28,"move_id":173},{"level":33,"move_id":34},{"level":37,"move_id":335},{"level":42,"move_id":343},{"level":46,"move_id":205},{"level":51,"move_id":63}]},"tmhm_learnset":"00301E76F7B37625","types":[0,0]},{"abilities":[46,0],"address":3300776,"base_stats":[90,85,100,85,95,125],"catch_rate":3,"evolutions":[],"friendship":35,"id":144,"learnset":{"address":3311812,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":181},{"level":13,"move_id":54},{"level":25,"move_id":97},{"level":37,"move_id":170},{"level":49,"move_id":58},{"level":61,"move_id":115},{"level":73,"move_id":59},{"level":85,"move_id":329}]},"tmhm_learnset":"00884E9184137674","types":[15,2]},{"abilities":[46,0],"address":3300804,"base_stats":[90,90,85,100,125,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":145,"learnset":{"address":3311836,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":84},{"level":13,"move_id":86},{"level":25,"move_id":97},{"level":37,"move_id":197},{"level":49,"move_id":65},{"level":61,"move_id":268},{"level":73,"move_id":113},{"level":85,"move_id":87}]},"tmhm_learnset":"00C84E928593C630","types":[13,2]},{"abilities":[46,0],"address":3300832,"base_stats":[90,100,90,90,125,85],"catch_rate":3,"evolutions":[],"friendship":35,"id":146,"learnset":{"address":3311860,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":17},{"level":1,"move_id":52},{"level":13,"move_id":83},{"level":25,"move_id":97},{"level":37,"move_id":203},{"level":49,"move_id":53},{"level":61,"move_id":219},{"level":73,"move_id":257},{"level":85,"move_id":143}]},"tmhm_learnset":"008A4EB4841B4630","types":[10,2]},{"abilities":[61,0],"address":3300860,"base_stats":[41,64,45,50,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":148}],"friendship":35,"id":147,"learnset":{"address":3311884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":36,"move_id":97},{"level":43,"move_id":219},{"level":50,"move_id":200},{"level":57,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[61,0],"address":3300888,"base_stats":[61,84,65,70,70,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":149}],"friendship":35,"id":148,"learnset":{"address":3311910,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":56,"move_id":200},{"level":65,"move_id":63}]},"tmhm_learnset":"01101E2685DB7664","types":[16,16]},{"abilities":[39,0],"address":3300916,"base_stats":[91,134,95,80,100,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":149,"learnset":{"address":3311936,"moves":[{"level":1,"move_id":35},{"level":1,"move_id":43},{"level":1,"move_id":86},{"level":1,"move_id":239},{"level":8,"move_id":86},{"level":15,"move_id":239},{"level":22,"move_id":82},{"level":29,"move_id":21},{"level":38,"move_id":97},{"level":47,"move_id":219},{"level":55,"move_id":17},{"level":61,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BC5EF6C7DB7677","types":[16,2]},{"abilities":[46,0],"address":3300944,"base_stats":[106,110,90,130,154,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":150,"learnset":{"address":3311964,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":50},{"level":11,"move_id":112},{"level":22,"move_id":129},{"level":33,"move_id":244},{"level":44,"move_id":248},{"level":55,"move_id":54},{"level":66,"move_id":94},{"level":77,"move_id":133},{"level":88,"move_id":105},{"level":99,"move_id":219}]},"tmhm_learnset":"00E18FF7F7FBFEED","types":[14,14]},{"abilities":[28,0],"address":3300972,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":151,"learnset":{"address":3311992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":10,"move_id":144},{"level":20,"move_id":5},{"level":30,"move_id":118},{"level":40,"move_id":94},{"level":50,"move_id":246}]},"tmhm_learnset":"03FFFFFFFFFFFFFF","types":[14,14]},{"abilities":[65,0],"address":3301000,"base_stats":[45,49,65,45,49,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":153}],"friendship":70,"id":152,"learnset":{"address":3312012,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":22,"move_id":235},{"level":29,"move_id":34},{"level":36,"move_id":113},{"level":43,"move_id":219},{"level":50,"move_id":76}]},"tmhm_learnset":"00441E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301028,"base_stats":[60,62,80,60,63,80],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":32,"species":154}],"friendship":70,"id":153,"learnset":{"address":3312038,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":39,"move_id":113},{"level":47,"move_id":219},{"level":55,"move_id":76}]},"tmhm_learnset":"00E41E01847D8720","types":[12,12]},{"abilities":[65,0],"address":3301056,"base_stats":[80,82,100,80,83,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":154,"learnset":{"address":3312064,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":75},{"level":1,"move_id":115},{"level":8,"move_id":75},{"level":12,"move_id":115},{"level":15,"move_id":77},{"level":23,"move_id":235},{"level":31,"move_id":34},{"level":41,"move_id":113},{"level":51,"move_id":219},{"level":61,"move_id":76}]},"tmhm_learnset":"00E41E01867DC720","types":[12,12]},{"abilities":[66,0],"address":3301084,"base_stats":[39,52,43,65,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":14,"species":156}],"friendship":70,"id":155,"learnset":{"address":3312090,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":19,"move_id":98},{"level":27,"move_id":172},{"level":36,"move_id":129},{"level":46,"move_id":53}]},"tmhm_learnset":"00061EA48C110620","types":[10,10]},{"abilities":[66,0],"address":3301112,"base_stats":[58,64,58,80,80,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":157}],"friendship":70,"id":156,"learnset":{"address":3312112,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":42,"move_id":129},{"level":54,"move_id":53}]},"tmhm_learnset":"00A61EA4CC110631","types":[10,10]},{"abilities":[66,0],"address":3301140,"base_stats":[78,84,78,100,109,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":157,"learnset":{"address":3312134,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":1,"move_id":108},{"level":1,"move_id":52},{"level":6,"move_id":108},{"level":12,"move_id":52},{"level":21,"move_id":98},{"level":31,"move_id":172},{"level":45,"move_id":129},{"level":60,"move_id":53}]},"tmhm_learnset":"00A61EA4CE114631","types":[10,10]},{"abilities":[67,0],"address":3301168,"base_stats":[50,65,64,43,44,48],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":18,"species":159}],"friendship":70,"id":158,"learnset":{"address":3312156,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":20,"move_id":44},{"level":27,"move_id":184},{"level":35,"move_id":163},{"level":43,"move_id":103},{"level":52,"move_id":56}]},"tmhm_learnset":"03141E80CC533265","types":[11,11]},{"abilities":[67,0],"address":3301196,"base_stats":[65,80,80,58,59,63],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":160}],"friendship":70,"id":159,"learnset":{"address":3312180,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":37,"move_id":163},{"level":45,"move_id":103},{"level":55,"move_id":56}]},"tmhm_learnset":"03B41E80CC533275","types":[11,11]},{"abilities":[67,0],"address":3301224,"base_stats":[85,105,100,78,79,83],"catch_rate":45,"evolutions":[],"friendship":70,"id":160,"learnset":{"address":3312204,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":99},{"level":1,"move_id":55},{"level":7,"move_id":99},{"level":13,"move_id":55},{"level":21,"move_id":44},{"level":28,"move_id":184},{"level":38,"move_id":163},{"level":47,"move_id":103},{"level":58,"move_id":56}]},"tmhm_learnset":"03B41E80CE537277","types":[11,11]},{"abilities":[50,51],"address":3301252,"base_stats":[35,46,34,20,35,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":15,"species":162}],"friendship":70,"id":161,"learnset":{"address":3312228,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":17,"move_id":270},{"level":24,"move_id":21},{"level":31,"move_id":266},{"level":40,"move_id":156},{"level":49,"move_id":133}]},"tmhm_learnset":"00143E06ECF31625","types":[0,0]},{"abilities":[50,51],"address":3301280,"base_stats":[85,76,64,90,45,55],"catch_rate":90,"evolutions":[],"friendship":70,"id":162,"learnset":{"address":3312254,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":111},{"level":1,"move_id":98},{"level":4,"move_id":111},{"level":7,"move_id":98},{"level":12,"move_id":154},{"level":19,"move_id":270},{"level":28,"move_id":21},{"level":37,"move_id":266},{"level":48,"move_id":156},{"level":59,"move_id":133}]},"tmhm_learnset":"00B43E06EDF37625","types":[0,0]},{"abilities":[15,51],"address":3301308,"base_stats":[60,30,30,50,36,56],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":164}],"friendship":70,"id":163,"learnset":{"address":3312280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":22,"move_id":115},{"level":28,"move_id":36},{"level":34,"move_id":93},{"level":48,"move_id":138}]},"tmhm_learnset":"00487E81B4130620","types":[0,2]},{"abilities":[15,51],"address":3301336,"base_stats":[100,50,50,70,76,96],"catch_rate":90,"evolutions":[],"friendship":70,"id":164,"learnset":{"address":3312304,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":193},{"level":1,"move_id":64},{"level":6,"move_id":193},{"level":11,"move_id":64},{"level":16,"move_id":95},{"level":25,"move_id":115},{"level":33,"move_id":36},{"level":41,"move_id":93},{"level":57,"move_id":138}]},"tmhm_learnset":"00487E81B4134620","types":[0,2]},{"abilities":[68,48],"address":3301364,"base_stats":[40,20,30,55,40,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":166}],"friendship":70,"id":165,"learnset":{"address":3312328,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":22,"move_id":113},{"level":22,"move_id":115},{"level":22,"move_id":219},{"level":29,"move_id":226},{"level":36,"move_id":129},{"level":43,"move_id":97},{"level":50,"move_id":38}]},"tmhm_learnset":"00403E81CC3D8621","types":[6,2]},{"abilities":[68,48],"address":3301392,"base_stats":[55,35,50,85,55,110],"catch_rate":90,"evolutions":[],"friendship":70,"id":166,"learnset":{"address":3312356,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":48},{"level":8,"move_id":48},{"level":15,"move_id":4},{"level":24,"move_id":113},{"level":24,"move_id":115},{"level":24,"move_id":219},{"level":33,"move_id":226},{"level":42,"move_id":129},{"level":51,"move_id":97},{"level":60,"move_id":38}]},"tmhm_learnset":"00403E81CC3DC621","types":[6,2]},{"abilities":[68,15],"address":3301420,"base_stats":[40,60,40,30,40,40],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":22,"species":168}],"friendship":70,"id":167,"learnset":{"address":3312384,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":23,"move_id":141},{"level":30,"move_id":154},{"level":37,"move_id":169},{"level":45,"move_id":97},{"level":53,"move_id":94}]},"tmhm_learnset":"00403E089C350620","types":[6,3]},{"abilities":[68,15],"address":3301448,"base_stats":[70,90,70,40,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":168,"learnset":{"address":3312410,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":81},{"level":1,"move_id":184},{"level":1,"move_id":132},{"level":6,"move_id":184},{"level":11,"move_id":132},{"level":17,"move_id":101},{"level":25,"move_id":141},{"level":34,"move_id":154},{"level":43,"move_id":169},{"level":53,"move_id":97},{"level":63,"move_id":94}]},"tmhm_learnset":"00403E089C354620","types":[6,3]},{"abilities":[39,0],"address":3301476,"base_stats":[85,90,80,130,70,80],"catch_rate":90,"evolutions":[],"friendship":70,"id":169,"learnset":{"address":3312436,"moves":[{"level":1,"move_id":103},{"level":1,"move_id":141},{"level":1,"move_id":48},{"level":1,"move_id":310},{"level":6,"move_id":48},{"level":11,"move_id":310},{"level":16,"move_id":44},{"level":21,"move_id":17},{"level":28,"move_id":109},{"level":35,"move_id":314},{"level":42,"move_id":212},{"level":49,"move_id":305},{"level":56,"move_id":114}]},"tmhm_learnset":"00097F88A4174E20","types":[3,2]},{"abilities":[10,35],"address":3301504,"base_stats":[75,38,38,67,56,56],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":27,"species":171}],"friendship":70,"id":170,"learnset":{"address":3312464,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":29,"move_id":109},{"level":37,"move_id":36},{"level":41,"move_id":56},{"level":49,"move_id":268}]},"tmhm_learnset":"03501E0285933264","types":[11,13]},{"abilities":[10,35],"address":3301532,"base_stats":[125,58,58,67,76,76],"catch_rate":75,"evolutions":[],"friendship":70,"id":171,"learnset":{"address":3312490,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":86},{"level":1,"move_id":48},{"level":5,"move_id":48},{"level":13,"move_id":175},{"level":17,"move_id":55},{"level":25,"move_id":209},{"level":32,"move_id":109},{"level":43,"move_id":36},{"level":50,"move_id":56},{"level":61,"move_id":268}]},"tmhm_learnset":"03501E0285937264","types":[11,13]},{"abilities":[9,0],"address":3301560,"base_stats":[20,40,15,60,35,35],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":25}],"friendship":70,"id":172,"learnset":{"address":3312516,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":84},{"level":1,"move_id":204},{"level":6,"move_id":39},{"level":8,"move_id":86},{"level":11,"move_id":186}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[56,0],"address":3301588,"base_stats":[50,25,28,15,45,55],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":35}],"friendship":140,"id":173,"learnset":{"address":3312532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":204},{"level":4,"move_id":227},{"level":8,"move_id":47},{"level":13,"move_id":186}]},"tmhm_learnset":"00401E27BC7B8624","types":[0,0]},{"abilities":[56,0],"address":3301616,"base_stats":[90,30,15,15,40,20],"catch_rate":170,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":39}],"friendship":70,"id":174,"learnset":{"address":3312548,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":47},{"level":1,"move_id":204},{"level":4,"move_id":111},{"level":9,"move_id":1},{"level":14,"move_id":186}]},"tmhm_learnset":"00401E27BC3B8624","types":[0,0]},{"abilities":[55,32],"address":3301644,"base_stats":[35,20,65,20,40,65],"catch_rate":190,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":176}],"friendship":70,"id":175,"learnset":{"address":3312564,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C01E27B43B8624","types":[0,0]},{"abilities":[55,32],"address":3301672,"base_stats":[55,40,85,40,80,105],"catch_rate":75,"evolutions":[],"friendship":70,"id":176,"learnset":{"address":3312590,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":118},{"level":1,"move_id":45},{"level":1,"move_id":204},{"level":6,"move_id":118},{"level":11,"move_id":186},{"level":16,"move_id":281},{"level":21,"move_id":227},{"level":26,"move_id":266},{"level":31,"move_id":273},{"level":36,"move_id":219},{"level":41,"move_id":38}]},"tmhm_learnset":"00C85EA7F43BC625","types":[0,2]},{"abilities":[28,48],"address":3301700,"base_stats":[40,50,45,70,70,45],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":178}],"friendship":70,"id":177,"learnset":{"address":3312616,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":30,"move_id":273},{"level":30,"move_id":248},{"level":40,"move_id":109},{"level":50,"move_id":94}]},"tmhm_learnset":"0040FE81B4378628","types":[14,2]},{"abilities":[28,48],"address":3301728,"base_stats":[65,75,70,95,95,70],"catch_rate":75,"evolutions":[],"friendship":70,"id":178,"learnset":{"address":3312638,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":43},{"level":10,"move_id":101},{"level":20,"move_id":100},{"level":35,"move_id":273},{"level":35,"move_id":248},{"level":50,"move_id":109},{"level":65,"move_id":94}]},"tmhm_learnset":"0048FE81B437C628","types":[14,2]},{"abilities":[9,0],"address":3301756,"base_stats":[55,40,40,35,65,45],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":15,"species":180}],"friendship":70,"id":179,"learnset":{"address":3312660,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":84},{"level":16,"move_id":86},{"level":23,"move_id":178},{"level":30,"move_id":113},{"level":37,"move_id":87}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[9,0],"address":3301784,"base_stats":[70,55,55,45,80,60],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":181}],"friendship":70,"id":180,"learnset":{"address":3312680,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":36,"move_id":113},{"level":45,"move_id":87}]},"tmhm_learnset":"00E01E02C5D38221","types":[13,13]},{"abilities":[9,0],"address":3301812,"base_stats":[90,75,75,55,115,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":181,"learnset":{"address":3312700,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":84},{"level":1,"move_id":86},{"level":9,"move_id":84},{"level":18,"move_id":86},{"level":27,"move_id":178},{"level":30,"move_id":9},{"level":42,"move_id":113},{"level":57,"move_id":87}]},"tmhm_learnset":"00E01E02C5D3C221","types":[13,13]},{"abilities":[34,0],"address":3301840,"base_stats":[75,80,85,50,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":182,"learnset":{"address":3312722,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":230},{"level":1,"move_id":78},{"level":1,"move_id":345},{"level":44,"move_id":80},{"level":55,"move_id":76}]},"tmhm_learnset":"00441E08843D4720","types":[12,12]},{"abilities":[47,37],"address":3301868,"base_stats":[70,20,50,40,20,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":18,"species":184}],"friendship":70,"id":183,"learnset":{"address":3312736,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":21,"move_id":61},{"level":28,"move_id":38},{"level":36,"move_id":240},{"level":45,"move_id":56}]},"tmhm_learnset":"03B01E00CC533265","types":[11,11]},{"abilities":[47,37],"address":3301896,"base_stats":[100,50,80,50,50,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":184,"learnset":{"address":3312762,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":111},{"level":1,"move_id":39},{"level":1,"move_id":55},{"level":3,"move_id":111},{"level":6,"move_id":39},{"level":10,"move_id":55},{"level":15,"move_id":205},{"level":24,"move_id":61},{"level":34,"move_id":38},{"level":45,"move_id":240},{"level":57,"move_id":56}]},"tmhm_learnset":"03B01E00CC537265","types":[11,11]},{"abilities":[5,69],"address":3301924,"base_stats":[70,100,115,30,30,65],"catch_rate":65,"evolutions":[],"friendship":70,"id":185,"learnset":{"address":3312788,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":102},{"level":9,"move_id":175},{"level":17,"move_id":67},{"level":25,"move_id":157},{"level":33,"move_id":335},{"level":41,"move_id":185},{"level":49,"move_id":21},{"level":57,"move_id":38}]},"tmhm_learnset":"00A03E50CE110E29","types":[5,5]},{"abilities":[11,6],"address":3301952,"base_stats":[90,75,75,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":186,"learnset":{"address":3312812,"moves":[{"level":1,"move_id":55},{"level":1,"move_id":95},{"level":1,"move_id":3},{"level":1,"move_id":195},{"level":35,"move_id":195},{"level":51,"move_id":207}]},"tmhm_learnset":"03B03E00DE137265","types":[11,11]},{"abilities":[34,0],"address":3301980,"base_stats":[35,35,40,50,35,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":188}],"friendship":70,"id":187,"learnset":{"address":3312826,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":20,"move_id":73},{"level":25,"move_id":178},{"level":30,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302008,"base_stats":[55,45,50,80,45,65],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":27,"species":189}],"friendship":70,"id":188,"learnset":{"address":3312854,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":29,"move_id":178},{"level":36,"move_id":72}]},"tmhm_learnset":"00401E8084350720","types":[12,2]},{"abilities":[34,0],"address":3302036,"base_stats":[75,55,70,110,55,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":189,"learnset":{"address":3312882,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":235},{"level":1,"move_id":39},{"level":1,"move_id":33},{"level":5,"move_id":235},{"level":5,"move_id":39},{"level":10,"move_id":33},{"level":13,"move_id":77},{"level":15,"move_id":78},{"level":17,"move_id":79},{"level":22,"move_id":73},{"level":33,"move_id":178},{"level":44,"move_id":72}]},"tmhm_learnset":"00401E8084354720","types":[12,2]},{"abilities":[50,53],"address":3302064,"base_stats":[55,70,55,85,40,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":190,"learnset":{"address":3312910,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":39},{"level":6,"move_id":28},{"level":13,"move_id":310},{"level":18,"move_id":226},{"level":25,"move_id":321},{"level":31,"move_id":154},{"level":38,"move_id":129},{"level":43,"move_id":103},{"level":50,"move_id":97}]},"tmhm_learnset":"00A53E82EDF30E25","types":[0,0]},{"abilities":[34,0],"address":3302092,"base_stats":[30,30,30,30,30,30],"catch_rate":235,"evolutions":[{"method":"ITEM","param":93,"species":192}],"friendship":70,"id":191,"learnset":{"address":3312936,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":6,"move_id":74},{"level":13,"move_id":72},{"level":18,"move_id":275},{"level":25,"move_id":283},{"level":30,"move_id":241},{"level":37,"move_id":235},{"level":42,"move_id":202}]},"tmhm_learnset":"00441E08843D8720","types":[12,12]},{"abilities":[34,0],"address":3302120,"base_stats":[75,75,55,30,105,85],"catch_rate":120,"evolutions":[],"friendship":70,"id":192,"learnset":{"address":3312960,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":1,"move_id":1},{"level":6,"move_id":74},{"level":13,"move_id":75},{"level":18,"move_id":275},{"level":25,"move_id":331},{"level":30,"move_id":241},{"level":37,"move_id":80},{"level":42,"move_id":76}]},"tmhm_learnset":"00441E08843DC720","types":[12,12]},{"abilities":[3,14],"address":3302148,"base_stats":[65,65,45,95,75,45],"catch_rate":75,"evolutions":[],"friendship":70,"id":193,"learnset":{"address":3312984,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":193},{"level":7,"move_id":98},{"level":13,"move_id":104},{"level":19,"move_id":49},{"level":25,"move_id":197},{"level":31,"move_id":48},{"level":37,"move_id":253},{"level":43,"move_id":17},{"level":49,"move_id":103}]},"tmhm_learnset":"00407E80B4350620","types":[6,2]},{"abilities":[6,11],"address":3302176,"base_stats":[55,45,45,15,25,25],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":195}],"friendship":70,"id":194,"learnset":{"address":3313010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":21,"move_id":133},{"level":31,"move_id":281},{"level":36,"move_id":89},{"level":41,"move_id":240},{"level":51,"move_id":54},{"level":51,"move_id":114}]},"tmhm_learnset":"03D01E188E533264","types":[11,4]},{"abilities":[6,11],"address":3302204,"base_stats":[95,85,85,35,65,65],"catch_rate":90,"evolutions":[],"friendship":70,"id":195,"learnset":{"address":3313036,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":39},{"level":11,"move_id":21},{"level":16,"move_id":341},{"level":23,"move_id":133},{"level":35,"move_id":281},{"level":42,"move_id":89},{"level":49,"move_id":240},{"level":61,"move_id":54},{"level":61,"move_id":114}]},"tmhm_learnset":"03F01E58CE537265","types":[11,4]},{"abilities":[28,0],"address":3302232,"base_stats":[65,65,60,110,130,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":196,"learnset":{"address":3313062,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":93},{"level":23,"move_id":98},{"level":30,"move_id":129},{"level":36,"move_id":60},{"level":42,"move_id":244},{"level":47,"move_id":94},{"level":52,"move_id":234}]},"tmhm_learnset":"00449E01BC53C628","types":[14,14]},{"abilities":[28,0],"address":3302260,"base_stats":[95,65,110,65,60,130],"catch_rate":45,"evolutions":[],"friendship":35,"id":197,"learnset":{"address":3313088,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":39},{"level":1,"move_id":270},{"level":8,"move_id":28},{"level":16,"move_id":228},{"level":23,"move_id":98},{"level":30,"move_id":109},{"level":36,"move_id":185},{"level":42,"move_id":212},{"level":47,"move_id":103},{"level":52,"move_id":236}]},"tmhm_learnset":"00451F00BC534E20","types":[17,17]},{"abilities":[15,0],"address":3302288,"base_stats":[60,85,42,91,85,42],"catch_rate":30,"evolutions":[],"friendship":35,"id":198,"learnset":{"address":3313114,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":9,"move_id":310},{"level":14,"move_id":228},{"level":22,"move_id":114},{"level":27,"move_id":101},{"level":35,"move_id":185},{"level":40,"move_id":269},{"level":48,"move_id":212}]},"tmhm_learnset":"00097F80A4130E28","types":[17,2]},{"abilities":[12,20],"address":3302316,"base_stats":[95,75,80,30,100,110],"catch_rate":70,"evolutions":[],"friendship":70,"id":199,"learnset":{"address":3313138,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":174},{"level":1,"move_id":281},{"level":1,"move_id":33},{"level":6,"move_id":45},{"level":15,"move_id":55},{"level":20,"move_id":93},{"level":29,"move_id":50},{"level":34,"move_id":29},{"level":43,"move_id":207},{"level":48,"move_id":94}]},"tmhm_learnset":"02F09E24FE5B766D","types":[11,14]},{"abilities":[26,0],"address":3302344,"base_stats":[60,60,60,85,85,85],"catch_rate":45,"evolutions":[],"friendship":35,"id":200,"learnset":{"address":3313162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":149},{"level":6,"move_id":180},{"level":11,"move_id":310},{"level":17,"move_id":109},{"level":23,"move_id":212},{"level":30,"move_id":60},{"level":37,"move_id":220},{"level":45,"move_id":195},{"level":53,"move_id":288}]},"tmhm_learnset":"0041BF82B5930E28","types":[7,7]},{"abilities":[26,0],"address":3302372,"base_stats":[48,72,48,48,72,48],"catch_rate":225,"evolutions":[],"friendship":70,"id":201,"learnset":{"address":3313188,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":237}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[23,0],"address":3302400,"base_stats":[190,33,58,33,33,58],"catch_rate":45,"evolutions":[],"friendship":70,"id":202,"learnset":{"address":3313198,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":243},{"level":1,"move_id":219},{"level":1,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[39,48],"address":3302428,"base_stats":[70,80,65,85,90,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":203,"learnset":{"address":3313208,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":7,"move_id":310},{"level":13,"move_id":93},{"level":19,"move_id":23},{"level":25,"move_id":316},{"level":31,"move_id":97},{"level":37,"move_id":226},{"level":43,"move_id":60},{"level":49,"move_id":242}]},"tmhm_learnset":"00E0BE03B7D38628","types":[0,14]},{"abilities":[5,0],"address":3302456,"base_stats":[50,65,90,15,35,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":31,"species":205}],"friendship":70,"id":204,"learnset":{"address":3313234,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":36,"move_id":153},{"level":43,"move_id":191},{"level":50,"move_id":38}]},"tmhm_learnset":"00A01E118E358620","types":[6,6]},{"abilities":[5,0],"address":3302484,"base_stats":[75,90,140,40,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":205,"learnset":{"address":3313258,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":182},{"level":1,"move_id":120},{"level":8,"move_id":120},{"level":15,"move_id":36},{"level":22,"move_id":229},{"level":29,"move_id":117},{"level":39,"move_id":153},{"level":49,"move_id":191},{"level":59,"move_id":38}]},"tmhm_learnset":"00A01E118E35C620","types":[6,8]},{"abilities":[32,50],"address":3302512,"base_stats":[100,70,70,45,65,65],"catch_rate":190,"evolutions":[],"friendship":70,"id":206,"learnset":{"address":3313282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":4,"move_id":111},{"level":11,"move_id":281},{"level":14,"move_id":137},{"level":21,"move_id":180},{"level":24,"move_id":228},{"level":31,"move_id":103},{"level":34,"move_id":36},{"level":41,"move_id":283}]},"tmhm_learnset":"00A03E66AFF3362C","types":[0,0]},{"abilities":[52,8],"address":3302540,"base_stats":[65,75,105,85,35,65],"catch_rate":60,"evolutions":[],"friendship":70,"id":207,"learnset":{"address":3313308,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":6,"move_id":28},{"level":13,"move_id":106},{"level":20,"move_id":98},{"level":28,"move_id":185},{"level":36,"move_id":163},{"level":44,"move_id":103},{"level":52,"move_id":12}]},"tmhm_learnset":"00A47ED88E530620","types":[4,2]},{"abilities":[69,5],"address":3302568,"base_stats":[75,85,200,30,55,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":208,"learnset":{"address":3313332,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":103},{"level":9,"move_id":20},{"level":13,"move_id":88},{"level":21,"move_id":106},{"level":25,"move_id":99},{"level":33,"move_id":201},{"level":37,"move_id":21},{"level":45,"move_id":231},{"level":49,"move_id":242},{"level":57,"move_id":38}]},"tmhm_learnset":"00A41F508E514E30","types":[8,4]},{"abilities":[22,50],"address":3302596,"base_stats":[60,80,50,30,40,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":23,"species":210}],"friendship":70,"id":209,"learnset":{"address":3313360,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":26,"move_id":46},{"level":34,"move_id":99},{"level":43,"move_id":36},{"level":53,"move_id":242}]},"tmhm_learnset":"00A23F2EEFB30EB5","types":[0,0]},{"abilities":[22,22],"address":3302624,"base_stats":[90,120,75,45,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":210,"learnset":{"address":3313386,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":184},{"level":4,"move_id":39},{"level":8,"move_id":204},{"level":13,"move_id":44},{"level":19,"move_id":122},{"level":28,"move_id":46},{"level":38,"move_id":99},{"level":49,"move_id":36},{"level":61,"move_id":242}]},"tmhm_learnset":"00A23F6EEFF34EB5","types":[0,0]},{"abilities":[38,33],"address":3302652,"base_stats":[65,95,75,85,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":211,"learnset":{"address":3313412,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":191},{"level":1,"move_id":33},{"level":1,"move_id":40},{"level":10,"move_id":106},{"level":10,"move_id":107},{"level":19,"move_id":55},{"level":28,"move_id":42},{"level":37,"move_id":36},{"level":46,"move_id":56}]},"tmhm_learnset":"03101E0AA4133264","types":[11,3]},{"abilities":[68,0],"address":3302680,"base_stats":[70,130,100,65,55,80],"catch_rate":25,"evolutions":[],"friendship":70,"id":212,"learnset":{"address":3313434,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":6,"move_id":116},{"level":11,"move_id":228},{"level":16,"move_id":206},{"level":21,"move_id":97},{"level":26,"move_id":232},{"level":31,"move_id":163},{"level":36,"move_id":14},{"level":41,"move_id":104},{"level":46,"move_id":210}]},"tmhm_learnset":"00A47E9084134620","types":[6,8]},{"abilities":[5,0],"address":3302708,"base_stats":[20,10,230,5,10,230],"catch_rate":190,"evolutions":[],"friendship":70,"id":213,"learnset":{"address":3313462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":132},{"level":1,"move_id":110},{"level":9,"move_id":35},{"level":14,"move_id":227},{"level":23,"move_id":219},{"level":28,"move_id":117},{"level":37,"move_id":156}]},"tmhm_learnset":"00E01E588E190620","types":[6,5]},{"abilities":[68,62],"address":3302736,"base_stats":[80,125,75,85,40,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":214,"learnset":{"address":3313482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":43},{"level":6,"move_id":30},{"level":11,"move_id":203},{"level":17,"move_id":31},{"level":23,"move_id":280},{"level":30,"move_id":68},{"level":37,"move_id":36},{"level":45,"move_id":179},{"level":53,"move_id":224}]},"tmhm_learnset":"00A43E40CE1346A1","types":[6,1]},{"abilities":[39,51],"address":3302764,"base_stats":[55,95,55,115,35,75],"catch_rate":60,"evolutions":[],"friendship":35,"id":215,"learnset":{"address":3313508,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":269},{"level":8,"move_id":98},{"level":15,"move_id":103},{"level":22,"move_id":185},{"level":29,"move_id":154},{"level":36,"move_id":97},{"level":43,"move_id":196},{"level":50,"move_id":163},{"level":57,"move_id":251},{"level":64,"move_id":232}]},"tmhm_learnset":"00B53F80EC533E69","types":[17,15]},{"abilities":[53,0],"address":3302792,"base_stats":[60,80,50,40,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":217}],"friendship":70,"id":216,"learnset":{"address":3313536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43F80CE130EB1","types":[0,0]},{"abilities":[62,0],"address":3302820,"base_stats":[90,130,75,55,75,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":217,"learnset":{"address":3313562,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":43},{"level":1,"move_id":122},{"level":1,"move_id":154},{"level":7,"move_id":122},{"level":13,"move_id":154},{"level":19,"move_id":313},{"level":25,"move_id":185},{"level":31,"move_id":156},{"level":37,"move_id":163},{"level":43,"move_id":173},{"level":49,"move_id":37}]},"tmhm_learnset":"00A43FC0CE134EB1","types":[0,0]},{"abilities":[40,49],"address":3302848,"base_stats":[40,40,40,20,70,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":38,"species":219}],"friendship":70,"id":218,"learnset":{"address":3313588,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":43,"move_id":157},{"level":50,"move_id":34}]},"tmhm_learnset":"00821E2584118620","types":[10,10]},{"abilities":[40,49],"address":3302876,"base_stats":[50,50,120,30,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":219,"learnset":{"address":3313612,"moves":[{"level":1,"move_id":281},{"level":1,"move_id":123},{"level":1,"move_id":52},{"level":1,"move_id":88},{"level":8,"move_id":52},{"level":15,"move_id":88},{"level":22,"move_id":106},{"level":29,"move_id":133},{"level":36,"move_id":53},{"level":48,"move_id":157},{"level":60,"move_id":34}]},"tmhm_learnset":"00A21E758611C620","types":[10,5]},{"abilities":[12,0],"address":3302904,"base_stats":[50,50,40,50,30,30],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":33,"species":221}],"friendship":70,"id":220,"learnset":{"address":3313636,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":316},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":37,"move_id":54},{"level":46,"move_id":59},{"level":55,"move_id":133}]},"tmhm_learnset":"00A01E518E13B270","types":[15,4]},{"abilities":[12,0],"address":3302932,"base_stats":[100,100,80,50,60,60],"catch_rate":75,"evolutions":[],"friendship":70,"id":221,"learnset":{"address":3313658,"moves":[{"level":1,"move_id":30},{"level":1,"move_id":316},{"level":1,"move_id":181},{"level":1,"move_id":203},{"level":10,"move_id":181},{"level":19,"move_id":203},{"level":28,"move_id":36},{"level":33,"move_id":31},{"level":42,"move_id":54},{"level":56,"move_id":59},{"level":70,"move_id":133}]},"tmhm_learnset":"00A01E518E13F270","types":[15,4]},{"abilities":[55,30],"address":3302960,"base_stats":[55,55,85,35,65,85],"catch_rate":60,"evolutions":[],"friendship":70,"id":222,"learnset":{"address":3313682,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":6,"move_id":106},{"level":12,"move_id":145},{"level":17,"move_id":105},{"level":17,"move_id":287},{"level":23,"move_id":61},{"level":28,"move_id":131},{"level":34,"move_id":350},{"level":39,"move_id":243},{"level":45,"move_id":246}]},"tmhm_learnset":"00B01E51BE1BB66C","types":[11,5]},{"abilities":[55,0],"address":3302988,"base_stats":[35,65,35,65,65,35],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":224}],"friendship":70,"id":223,"learnset":{"address":3313710,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":199},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":33,"move_id":116},{"level":44,"move_id":58},{"level":55,"move_id":63}]},"tmhm_learnset":"03103E2494137624","types":[11,11]},{"abilities":[21,0],"address":3303016,"base_stats":[75,105,75,45,105,75],"catch_rate":75,"evolutions":[],"friendship":70,"id":224,"learnset":{"address":3313734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":11,"move_id":132},{"level":22,"move_id":60},{"level":22,"move_id":62},{"level":22,"move_id":61},{"level":25,"move_id":190},{"level":38,"move_id":116},{"level":54,"move_id":58},{"level":70,"move_id":63}]},"tmhm_learnset":"03103E2C94137724","types":[11,11]},{"abilities":[72,55],"address":3303044,"base_stats":[45,55,45,75,65,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":225,"learnset":{"address":3313760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":217}]},"tmhm_learnset":"00083E8084133265","types":[15,2]},{"abilities":[33,11],"address":3303072,"base_stats":[65,40,70,70,80,140],"catch_rate":25,"evolutions":[],"friendship":70,"id":226,"learnset":{"address":3313770,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":145},{"level":8,"move_id":48},{"level":15,"move_id":61},{"level":22,"move_id":36},{"level":29,"move_id":97},{"level":36,"move_id":17},{"level":43,"move_id":352},{"level":50,"move_id":109}]},"tmhm_learnset":"03101E8086133264","types":[11,2]},{"abilities":[51,5],"address":3303100,"base_stats":[65,80,140,70,40,70],"catch_rate":25,"evolutions":[],"friendship":70,"id":227,"learnset":{"address":3313794,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":64},{"level":10,"move_id":28},{"level":13,"move_id":129},{"level":16,"move_id":97},{"level":26,"move_id":31},{"level":29,"move_id":314},{"level":32,"move_id":211},{"level":42,"move_id":191},{"level":45,"move_id":319}]},"tmhm_learnset":"008C7F9084110E30","types":[8,2]},{"abilities":[48,18],"address":3303128,"base_stats":[45,60,30,65,80,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":24,"species":229}],"friendship":35,"id":228,"learnset":{"address":3313820,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":25,"move_id":44},{"level":31,"move_id":316},{"level":37,"move_id":185},{"level":43,"move_id":53},{"level":49,"move_id":242}]},"tmhm_learnset":"00833F2CA4710E30","types":[17,10]},{"abilities":[48,18],"address":3303156,"base_stats":[75,90,50,95,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":229,"learnset":{"address":3313846,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":52},{"level":1,"move_id":336},{"level":7,"move_id":336},{"level":13,"move_id":123},{"level":19,"move_id":46},{"level":27,"move_id":44},{"level":35,"move_id":316},{"level":43,"move_id":185},{"level":51,"move_id":53},{"level":59,"move_id":242}]},"tmhm_learnset":"00A33F2CA4714E30","types":[17,10]},{"abilities":[33,0],"address":3303184,"base_stats":[75,95,95,85,95,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":230,"learnset":{"address":3313872,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":108},{"level":1,"move_id":43},{"level":1,"move_id":55},{"level":8,"move_id":108},{"level":15,"move_id":43},{"level":22,"move_id":55},{"level":29,"move_id":239},{"level":40,"move_id":97},{"level":51,"move_id":56},{"level":62,"move_id":349}]},"tmhm_learnset":"03101E0084137264","types":[11,16]},{"abilities":[53,0],"address":3303212,"base_stats":[90,60,60,40,40,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":25,"species":232}],"friendship":70,"id":231,"learnset":{"address":3313896,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":36},{"level":33,"move_id":205},{"level":41,"move_id":203},{"level":49,"move_id":38}]},"tmhm_learnset":"00A01E5086510630","types":[4,4]},{"abilities":[5,0],"address":3303240,"base_stats":[90,120,120,50,60,60],"catch_rate":60,"evolutions":[],"friendship":70,"id":232,"learnset":{"address":3313918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":316},{"level":1,"move_id":30},{"level":1,"move_id":45},{"level":9,"move_id":111},{"level":17,"move_id":175},{"level":25,"move_id":31},{"level":33,"move_id":205},{"level":41,"move_id":229},{"level":49,"move_id":89}]},"tmhm_learnset":"00A01E5086514630","types":[4,4]},{"abilities":[36,0],"address":3303268,"base_stats":[85,80,90,60,105,95],"catch_rate":45,"evolutions":[],"friendship":70,"id":233,"learnset":{"address":3313940,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":176},{"level":1,"move_id":33},{"level":1,"move_id":160},{"level":9,"move_id":97},{"level":12,"move_id":60},{"level":20,"move_id":105},{"level":24,"move_id":111},{"level":32,"move_id":199},{"level":36,"move_id":161},{"level":44,"move_id":278},{"level":48,"move_id":192}]},"tmhm_learnset":"00402E82B5F37620","types":[0,0]},{"abilities":[22,0],"address":3303296,"base_stats":[73,95,62,85,85,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":234,"learnset":{"address":3313966,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":43},{"level":13,"move_id":310},{"level":19,"move_id":95},{"level":25,"move_id":23},{"level":31,"move_id":28},{"level":37,"move_id":36},{"level":43,"move_id":109},{"level":49,"move_id":347}]},"tmhm_learnset":"0040BE03B7F38638","types":[0,0]},{"abilities":[20,0],"address":3303324,"base_stats":[55,20,35,75,20,45],"catch_rate":45,"evolutions":[],"friendship":70,"id":235,"learnset":{"address":3313992,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":166},{"level":11,"move_id":166},{"level":21,"move_id":166},{"level":31,"move_id":166},{"level":41,"move_id":166},{"level":51,"move_id":166},{"level":61,"move_id":166},{"level":71,"move_id":166},{"level":81,"move_id":166},{"level":91,"move_id":166}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[62,0],"address":3303352,"base_stats":[35,35,35,35,35,35],"catch_rate":75,"evolutions":[{"method":"LEVEL_ATK_LT_DEF","param":20,"species":107},{"method":"LEVEL_ATK_GT_DEF","param":20,"species":106},{"method":"LEVEL_ATK_EQ_DEF","param":20,"species":237}],"friendship":70,"id":236,"learnset":{"address":3314020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"00A03E00C61306A0","types":[1,1]},{"abilities":[22,0],"address":3303380,"base_stats":[50,95,95,70,35,110],"catch_rate":45,"evolutions":[],"friendship":70,"id":237,"learnset":{"address":3314030,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":279},{"level":1,"move_id":27},{"level":7,"move_id":116},{"level":13,"move_id":228},{"level":19,"move_id":98},{"level":20,"move_id":167},{"level":25,"move_id":229},{"level":31,"move_id":68},{"level":37,"move_id":97},{"level":43,"move_id":197},{"level":49,"move_id":283}]},"tmhm_learnset":"00A03E10CE1306A0","types":[1,1]},{"abilities":[12,0],"address":3303408,"base_stats":[45,30,15,65,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":124}],"friendship":70,"id":238,"learnset":{"address":3314058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":122},{"level":9,"move_id":186},{"level":13,"move_id":181},{"level":21,"move_id":93},{"level":25,"move_id":47},{"level":33,"move_id":212},{"level":37,"move_id":313},{"level":45,"move_id":94},{"level":49,"move_id":195},{"level":57,"move_id":59}]},"tmhm_learnset":"0040BE01B413B26C","types":[15,14]},{"abilities":[9,0],"address":3303436,"base_stats":[45,63,37,95,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":125}],"friendship":70,"id":239,"learnset":{"address":3314086,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":43},{"level":9,"move_id":9},{"level":17,"move_id":113},{"level":25,"move_id":129},{"level":33,"move_id":103},{"level":41,"move_id":85},{"level":49,"move_id":87}]},"tmhm_learnset":"00C03E02D5938221","types":[13,13]},{"abilities":[49,0],"address":3303464,"base_stats":[45,75,37,83,70,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":126}],"friendship":70,"id":240,"learnset":{"address":3314108,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":7,"move_id":43},{"level":13,"move_id":123},{"level":19,"move_id":7},{"level":25,"move_id":108},{"level":31,"move_id":241},{"level":37,"move_id":53},{"level":43,"move_id":109},{"level":49,"move_id":126}]},"tmhm_learnset":"00803E24D4510621","types":[10,10]},{"abilities":[47,0],"address":3303492,"base_stats":[95,80,105,100,40,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":241,"learnset":{"address":3314134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":45},{"level":8,"move_id":111},{"level":13,"move_id":23},{"level":19,"move_id":208},{"level":26,"move_id":117},{"level":34,"move_id":205},{"level":43,"move_id":34},{"level":53,"move_id":215}]},"tmhm_learnset":"00B01E52E7F37625","types":[0,0]},{"abilities":[30,32],"address":3303520,"base_stats":[255,10,10,55,75,135],"catch_rate":30,"evolutions":[],"friendship":140,"id":242,"learnset":{"address":3314160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":45},{"level":4,"move_id":39},{"level":7,"move_id":287},{"level":10,"move_id":135},{"level":13,"move_id":3},{"level":18,"move_id":107},{"level":23,"move_id":47},{"level":28,"move_id":121},{"level":33,"move_id":111},{"level":40,"move_id":113},{"level":47,"move_id":38}]},"tmhm_learnset":"00E19E76F7FBF66D","types":[0,0]},{"abilities":[46,0],"address":3303548,"base_stats":[90,85,75,115,115,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":243,"learnset":{"address":3314190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":84},{"level":21,"move_id":46},{"level":31,"move_id":98},{"level":41,"move_id":209},{"level":51,"move_id":115},{"level":61,"move_id":242},{"level":71,"move_id":87},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E138DD34638","types":[13,13]},{"abilities":[46,0],"address":3303576,"base_stats":[115,115,85,100,90,75],"catch_rate":3,"evolutions":[],"friendship":35,"id":244,"learnset":{"address":3314216,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":52},{"level":21,"move_id":46},{"level":31,"move_id":83},{"level":41,"move_id":23},{"level":51,"move_id":53},{"level":61,"move_id":207},{"level":71,"move_id":126},{"level":81,"move_id":347}]},"tmhm_learnset":"00E40E358C734638","types":[10,10]},{"abilities":[46,0],"address":3303604,"base_stats":[100,75,115,85,90,115],"catch_rate":3,"evolutions":[],"friendship":35,"id":245,"learnset":{"address":3314242,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":11,"move_id":61},{"level":21,"move_id":240},{"level":31,"move_id":16},{"level":41,"move_id":62},{"level":51,"move_id":54},{"level":61,"move_id":243},{"level":71,"move_id":56},{"level":81,"move_id":347}]},"tmhm_learnset":"03940E118C53767C","types":[11,11]},{"abilities":[62,0],"address":3303632,"base_stats":[50,64,50,41,45,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":247}],"friendship":35,"id":246,"learnset":{"address":3314268,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":36,"move_id":184},{"level":43,"move_id":242},{"level":50,"move_id":89},{"level":57,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[61,0],"address":3303660,"base_stats":[70,84,70,51,65,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":55,"species":248}],"friendship":35,"id":247,"learnset":{"address":3314294,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":56,"move_id":89},{"level":65,"move_id":63}]},"tmhm_learnset":"00801F10CE134E20","types":[5,4]},{"abilities":[45,0],"address":3303688,"base_stats":[100,134,110,61,95,100],"catch_rate":45,"evolutions":[],"friendship":35,"id":248,"learnset":{"address":3314320,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":201},{"level":1,"move_id":103},{"level":8,"move_id":201},{"level":15,"move_id":103},{"level":22,"move_id":157},{"level":29,"move_id":37},{"level":38,"move_id":184},{"level":47,"move_id":242},{"level":61,"move_id":89},{"level":75,"move_id":63}]},"tmhm_learnset":"00B41FF6CFD37E37","types":[5,17]},{"abilities":[46,0],"address":3303716,"base_stats":[106,90,130,110,90,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":249,"learnset":{"address":3314346,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":16},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":56},{"level":55,"move_id":240},{"level":66,"move_id":129},{"level":77,"move_id":177},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"03B8CE93B7DFF67C","types":[14,2]},{"abilities":[46,0],"address":3303744,"base_stats":[106,130,90,90,110,154],"catch_rate":3,"evolutions":[],"friendship":0,"id":250,"learnset":{"address":3314374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":18},{"level":11,"move_id":219},{"level":22,"move_id":16},{"level":33,"move_id":105},{"level":44,"move_id":126},{"level":55,"move_id":241},{"level":66,"move_id":129},{"level":77,"move_id":221},{"level":88,"move_id":246},{"level":99,"move_id":248}]},"tmhm_learnset":"00EA4EB7B7BFC638","types":[10,2]},{"abilities":[30,0],"address":3303772,"base_stats":[100,100,100,100,100,100],"catch_rate":45,"evolutions":[],"friendship":100,"id":251,"learnset":{"address":3314402,"moves":[{"level":1,"move_id":73},{"level":1,"move_id":93},{"level":1,"move_id":105},{"level":1,"move_id":215},{"level":10,"move_id":219},{"level":20,"move_id":246},{"level":30,"move_id":248},{"level":40,"move_id":226},{"level":50,"move_id":195}]},"tmhm_learnset":"00448E93B43FC62C","types":[14,12]},{"abilities":[0,0],"address":3303800,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":252,"learnset":{"address":3314422,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303828,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":253,"learnset":{"address":3314432,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303856,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":254,"learnset":{"address":3314442,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303884,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":255,"learnset":{"address":3314452,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303912,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":256,"learnset":{"address":3314462,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303940,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":257,"learnset":{"address":3314472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303968,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":258,"learnset":{"address":3314482,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3303996,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":259,"learnset":{"address":3314492,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304024,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":260,"learnset":{"address":3314502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304052,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":261,"learnset":{"address":3314512,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304080,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":262,"learnset":{"address":3314522,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304108,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":263,"learnset":{"address":3314532,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304136,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":264,"learnset":{"address":3314542,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304164,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":265,"learnset":{"address":3314552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304192,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":266,"learnset":{"address":3314562,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304220,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":267,"learnset":{"address":3314572,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304248,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":268,"learnset":{"address":3314582,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304276,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":269,"learnset":{"address":3314592,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304304,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":270,"learnset":{"address":3314602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304332,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":271,"learnset":{"address":3314612,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304360,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":272,"learnset":{"address":3314622,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304388,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":273,"learnset":{"address":3314632,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304416,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":274,"learnset":{"address":3314642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304444,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":275,"learnset":{"address":3314652,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[0,0],"address":3304472,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":276,"learnset":{"address":3314662,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33}]},"tmhm_learnset":"0000000000000000","types":[0,0]},{"abilities":[65,0],"address":3304500,"base_stats":[40,45,35,70,65,55],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":278}],"friendship":70,"id":277,"learnset":{"address":3314672,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":228},{"level":21,"move_id":103},{"level":26,"move_id":72},{"level":31,"move_id":97},{"level":36,"move_id":21},{"level":41,"move_id":197},{"level":46,"move_id":202}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304528,"base_stats":[50,65,45,95,85,65],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":279}],"friendship":70,"id":278,"learnset":{"address":3314700,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":41,"move_id":21},{"level":47,"move_id":197},{"level":53,"move_id":206}]},"tmhm_learnset":"00E41EC0CC7D0721","types":[12,12]},{"abilities":[65,0],"address":3304556,"base_stats":[70,85,65,120,105,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":279,"learnset":{"address":3314730,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":98},{"level":6,"move_id":71},{"level":11,"move_id":98},{"level":16,"move_id":210},{"level":17,"move_id":228},{"level":23,"move_id":103},{"level":29,"move_id":348},{"level":35,"move_id":97},{"level":43,"move_id":21},{"level":51,"move_id":197},{"level":59,"move_id":206}]},"tmhm_learnset":"00E41EC0CE7D4733","types":[12,12]},{"abilities":[66,0],"address":3304584,"base_stats":[45,60,40,45,70,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":281}],"friendship":70,"id":280,"learnset":{"address":3314760,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":7,"move_id":116},{"level":10,"move_id":52},{"level":16,"move_id":64},{"level":19,"move_id":28},{"level":25,"move_id":83},{"level":28,"move_id":98},{"level":34,"move_id":163},{"level":37,"move_id":119},{"level":43,"move_id":53}]},"tmhm_learnset":"00A61EE48C110620","types":[10,10]},{"abilities":[66,0],"address":3304612,"base_stats":[60,85,60,55,85,60],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":282}],"friendship":70,"id":281,"learnset":{"address":3314788,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":39,"move_id":163},{"level":43,"move_id":119},{"level":50,"move_id":327}]},"tmhm_learnset":"00A61EE4CC1106A1","types":[10,1]},{"abilities":[66,0],"address":3304640,"base_stats":[80,120,70,80,110,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":282,"learnset":{"address":3314818,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":10},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":52},{"level":7,"move_id":116},{"level":13,"move_id":52},{"level":16,"move_id":24},{"level":17,"move_id":64},{"level":21,"move_id":28},{"level":28,"move_id":339},{"level":32,"move_id":98},{"level":36,"move_id":299},{"level":42,"move_id":163},{"level":49,"move_id":119},{"level":59,"move_id":327}]},"tmhm_learnset":"00A61EE4CE1146B1","types":[10,1]},{"abilities":[67,0],"address":3304668,"base_stats":[50,70,50,40,50,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":16,"species":284}],"friendship":70,"id":283,"learnset":{"address":3314852,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":19,"move_id":193},{"level":24,"move_id":300},{"level":28,"move_id":36},{"level":33,"move_id":250},{"level":37,"move_id":182},{"level":42,"move_id":56},{"level":46,"move_id":283}]},"tmhm_learnset":"03B01E408C533264","types":[11,11]},{"abilities":[67,0],"address":3304696,"base_stats":[70,85,70,50,60,70],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":36,"species":285}],"friendship":70,"id":284,"learnset":{"address":3314882,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":37,"move_id":330},{"level":42,"move_id":182},{"level":46,"move_id":89},{"level":53,"move_id":283}]},"tmhm_learnset":"03B01E408E533264","types":[11,4]},{"abilities":[67,0],"address":3304724,"base_stats":[100,110,90,60,85,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":285,"learnset":{"address":3314914,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":189},{"level":1,"move_id":55},{"level":6,"move_id":189},{"level":10,"move_id":55},{"level":15,"move_id":117},{"level":16,"move_id":341},{"level":20,"move_id":193},{"level":25,"move_id":300},{"level":31,"move_id":36},{"level":39,"move_id":330},{"level":46,"move_id":182},{"level":52,"move_id":89},{"level":61,"move_id":283}]},"tmhm_learnset":"03B01E40CE537275","types":[11,4]},{"abilities":[50,0],"address":3304752,"base_stats":[35,55,35,35,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":287}],"friendship":70,"id":286,"learnset":{"address":3314946,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":21,"move_id":46},{"level":25,"move_id":207},{"level":29,"move_id":184},{"level":33,"move_id":36},{"level":37,"move_id":269},{"level":41,"move_id":242},{"level":45,"move_id":168}]},"tmhm_learnset":"00813F00AC530E30","types":[17,17]},{"abilities":[22,0],"address":3304780,"base_stats":[70,90,70,70,60,60],"catch_rate":127,"evolutions":[],"friendship":70,"id":287,"learnset":{"address":3314978,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":336},{"level":1,"move_id":28},{"level":1,"move_id":44},{"level":5,"move_id":336},{"level":9,"move_id":28},{"level":13,"move_id":44},{"level":17,"move_id":316},{"level":22,"move_id":46},{"level":27,"move_id":207},{"level":32,"move_id":184},{"level":37,"move_id":36},{"level":42,"move_id":269},{"level":47,"move_id":242},{"level":52,"move_id":168}]},"tmhm_learnset":"00A13F00AC534E30","types":[17,17]},{"abilities":[53,0],"address":3304808,"base_stats":[38,30,41,60,30,41],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":20,"species":289}],"friendship":70,"id":288,"learnset":{"address":3315010,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":21,"move_id":300},{"level":25,"move_id":42},{"level":29,"move_id":343},{"level":33,"move_id":175},{"level":37,"move_id":156},{"level":41,"move_id":187}]},"tmhm_learnset":"00943E02ADD33624","types":[0,0]},{"abilities":[53,0],"address":3304836,"base_stats":[78,70,61,100,50,61],"catch_rate":90,"evolutions":[],"friendship":70,"id":289,"learnset":{"address":3315040,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":45},{"level":1,"move_id":39},{"level":1,"move_id":29},{"level":5,"move_id":39},{"level":9,"move_id":29},{"level":13,"move_id":28},{"level":17,"move_id":316},{"level":23,"move_id":300},{"level":29,"move_id":154},{"level":35,"move_id":343},{"level":41,"move_id":163},{"level":47,"move_id":156},{"level":53,"move_id":187}]},"tmhm_learnset":"00B43E02ADD37634","types":[0,0]},{"abilities":[19,0],"address":3304864,"base_stats":[45,45,35,20,20,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_SILCOON","param":7,"species":291},{"method":"LEVEL_CASCOON","param":7,"species":293}],"friendship":70,"id":290,"learnset":{"address":3315070,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":81},{"level":5,"move_id":40}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[61,0],"address":3304892,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":292}],"friendship":70,"id":291,"learnset":{"address":3315082,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[68,0],"address":3304920,"base_stats":[60,70,50,65,90,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":292,"learnset":{"address":3315094,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":10,"move_id":71},{"level":13,"move_id":16},{"level":17,"move_id":78},{"level":20,"move_id":234},{"level":24,"move_id":72},{"level":27,"move_id":18},{"level":31,"move_id":213},{"level":34,"move_id":318},{"level":38,"move_id":202}]},"tmhm_learnset":"00403E80B43D4620","types":[6,2]},{"abilities":[61,0],"address":3304948,"base_stats":[50,35,55,15,25,25],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":10,"species":294}],"friendship":70,"id":293,"learnset":{"address":3315122,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":106}]},"tmhm_learnset":"0000000000000000","types":[6,6]},{"abilities":[19,0],"address":3304976,"base_stats":[60,50,70,65,50,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":294,"learnset":{"address":3315134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":10,"move_id":93},{"level":13,"move_id":16},{"level":17,"move_id":182},{"level":20,"move_id":236},{"level":24,"move_id":60},{"level":27,"move_id":18},{"level":31,"move_id":113},{"level":34,"move_id":318},{"level":38,"move_id":92}]},"tmhm_learnset":"00403E88B435C620","types":[6,3]},{"abilities":[33,44],"address":3305004,"base_stats":[40,30,30,30,40,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":296}],"friendship":70,"id":295,"learnset":{"address":3315162,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":21,"move_id":54},{"level":31,"move_id":240},{"level":43,"move_id":72}]},"tmhm_learnset":"00503E0084373764","types":[11,12]},{"abilities":[33,44],"address":3305032,"base_stats":[60,50,50,50,60,70],"catch_rate":120,"evolutions":[{"method":"ITEM","param":97,"species":297}],"friendship":70,"id":296,"learnset":{"address":3315184,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":3,"move_id":45},{"level":7,"move_id":71},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":154},{"level":31,"move_id":346},{"level":37,"move_id":168},{"level":43,"move_id":253},{"level":49,"move_id":56}]},"tmhm_learnset":"03F03E00C4373764","types":[11,12]},{"abilities":[33,44],"address":3305060,"base_stats":[80,70,70,70,90,100],"catch_rate":45,"evolutions":[],"friendship":70,"id":297,"learnset":{"address":3315212,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":45},{"level":1,"move_id":71},{"level":1,"move_id":267}]},"tmhm_learnset":"03F03E00C4377765","types":[11,12]},{"abilities":[34,48],"address":3305088,"base_stats":[40,40,50,30,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":14,"species":299}],"friendship":70,"id":298,"learnset":{"address":3315222,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":21,"move_id":235},{"level":31,"move_id":241},{"level":43,"move_id":153}]},"tmhm_learnset":"00C01E00AC350720","types":[12,12]},{"abilities":[34,48],"address":3305116,"base_stats":[70,70,40,60,60,40],"catch_rate":120,"evolutions":[{"method":"ITEM","param":98,"species":300}],"friendship":70,"id":299,"learnset":{"address":3315244,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":3,"move_id":106},{"level":7,"move_id":74},{"level":13,"move_id":267},{"level":19,"move_id":252},{"level":25,"move_id":259},{"level":31,"move_id":185},{"level":37,"move_id":13},{"level":43,"move_id":207},{"level":49,"move_id":326}]},"tmhm_learnset":"00E43F40EC354720","types":[12,17]},{"abilities":[34,48],"address":3305144,"base_stats":[90,100,60,80,90,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":300,"learnset":{"address":3315272,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":106},{"level":1,"move_id":74},{"level":1,"move_id":267}]},"tmhm_learnset":"00E43FC0EC354720","types":[12,17]},{"abilities":[14,0],"address":3305172,"base_stats":[31,45,90,40,30,30],"catch_rate":255,"evolutions":[{"method":"LEVEL_NINJASK","param":20,"species":302},{"method":"LEVEL_SHEDINJA","param":20,"species":303}],"friendship":70,"id":301,"learnset":{"address":3315282,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":206},{"level":31,"move_id":189},{"level":38,"move_id":232},{"level":45,"move_id":91}]},"tmhm_learnset":"00440E90AC350620","types":[6,4]},{"abilities":[3,0],"address":3305200,"base_stats":[61,90,45,160,50,50],"catch_rate":120,"evolutions":[],"friendship":70,"id":302,"learnset":{"address":3315308,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":141},{"level":1,"move_id":28},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":20,"move_id":104},{"level":20,"move_id":210},{"level":20,"move_id":103},{"level":25,"move_id":14},{"level":31,"move_id":163},{"level":38,"move_id":97},{"level":45,"move_id":226}]},"tmhm_learnset":"00443E90AC354620","types":[6,2]},{"abilities":[25,0],"address":3305228,"base_stats":[1,90,45,40,30,30],"catch_rate":45,"evolutions":[],"friendship":70,"id":303,"learnset":{"address":3315340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":5,"move_id":141},{"level":9,"move_id":28},{"level":14,"move_id":154},{"level":19,"move_id":170},{"level":25,"move_id":180},{"level":31,"move_id":109},{"level":38,"move_id":247},{"level":45,"move_id":288}]},"tmhm_learnset":"00442E90AC354620","types":[6,7]},{"abilities":[62,0],"address":3305256,"base_stats":[40,55,30,85,30,30],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":305}],"friendship":70,"id":304,"learnset":{"address":3315366,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":26,"move_id":283},{"level":34,"move_id":332},{"level":43,"move_id":97}]},"tmhm_learnset":"00087E8084130620","types":[0,2]},{"abilities":[62,0],"address":3305284,"base_stats":[60,85,60,125,50,50],"catch_rate":45,"evolutions":[],"friendship":70,"id":305,"learnset":{"address":3315390,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":116},{"level":1,"move_id":98},{"level":4,"move_id":116},{"level":8,"move_id":98},{"level":13,"move_id":17},{"level":19,"move_id":104},{"level":28,"move_id":283},{"level":38,"move_id":332},{"level":49,"move_id":97}]},"tmhm_learnset":"00087E8084134620","types":[0,2]},{"abilities":[27,0],"address":3305312,"base_stats":[60,40,60,35,40,60],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":23,"species":307}],"friendship":70,"id":306,"learnset":{"address":3315414,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":28,"move_id":77},{"level":36,"move_id":74},{"level":45,"move_id":202},{"level":54,"move_id":147}]},"tmhm_learnset":"00411E08843D0720","types":[12,12]},{"abilities":[27,0],"address":3305340,"base_stats":[60,130,80,70,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":307,"learnset":{"address":3315442,"moves":[{"level":1,"move_id":71},{"level":1,"move_id":33},{"level":1,"move_id":78},{"level":1,"move_id":73},{"level":4,"move_id":33},{"level":7,"move_id":78},{"level":10,"move_id":73},{"level":16,"move_id":72},{"level":22,"move_id":29},{"level":23,"move_id":183},{"level":28,"move_id":68},{"level":36,"move_id":327},{"level":45,"move_id":170},{"level":54,"move_id":223}]},"tmhm_learnset":"00E51E08C47D47A1","types":[12,1]},{"abilities":[20,0],"address":3305368,"base_stats":[60,60,60,60,60,60],"catch_rate":255,"evolutions":[],"friendship":70,"id":308,"learnset":{"address":3315472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":253},{"level":12,"move_id":185},{"level":16,"move_id":60},{"level":23,"move_id":95},{"level":27,"move_id":146},{"level":34,"move_id":298},{"level":38,"move_id":244},{"level":45,"move_id":38},{"level":49,"move_id":175},{"level":56,"move_id":37}]},"tmhm_learnset":"00E1BE42FC1B062D","types":[0,0]},{"abilities":[51,0],"address":3305396,"base_stats":[40,30,30,85,55,30],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":25,"species":310}],"friendship":70,"id":309,"learnset":{"address":3315502,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":31,"move_id":98},{"level":43,"move_id":228},{"level":55,"move_id":97}]},"tmhm_learnset":"00087E8284133264","types":[11,2]},{"abilities":[51,0],"address":3305424,"base_stats":[60,50,100,65,85,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":310,"learnset":{"address":3315524,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":346},{"level":1,"move_id":17},{"level":3,"move_id":55},{"level":7,"move_id":48},{"level":13,"move_id":17},{"level":21,"move_id":54},{"level":25,"move_id":182},{"level":33,"move_id":254},{"level":33,"move_id":256},{"level":47,"move_id":255},{"level":61,"move_id":56}]},"tmhm_learnset":"00187E8284137264","types":[11,2]},{"abilities":[33,0],"address":3305452,"base_stats":[40,30,32,65,50,52],"catch_rate":200,"evolutions":[{"method":"LEVEL","param":22,"species":312}],"friendship":70,"id":311,"learnset":{"address":3315552,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":25,"move_id":61},{"level":31,"move_id":97},{"level":37,"move_id":54},{"level":37,"move_id":114}]},"tmhm_learnset":"00403E00A4373624","types":[6,11]},{"abilities":[22,0],"address":3305480,"base_stats":[70,60,62,60,80,82],"catch_rate":75,"evolutions":[],"friendship":70,"id":312,"learnset":{"address":3315576,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":98},{"level":1,"move_id":230},{"level":1,"move_id":346},{"level":7,"move_id":98},{"level":13,"move_id":230},{"level":19,"move_id":346},{"level":26,"move_id":16},{"level":33,"move_id":184},{"level":40,"move_id":78},{"level":47,"move_id":318},{"level":53,"move_id":18}]},"tmhm_learnset":"00403E80A4377624","types":[6,2]},{"abilities":[41,12],"address":3305508,"base_stats":[130,70,35,60,70,35],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":40,"species":314}],"friendship":70,"id":313,"learnset":{"address":3315602,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":1,"move_id":150},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":41,"move_id":323},{"level":46,"move_id":133},{"level":50,"move_id":56}]},"tmhm_learnset":"03B01E4086133274","types":[11,11]},{"abilities":[41,12],"address":3305536,"base_stats":[170,90,45,60,90,45],"catch_rate":60,"evolutions":[],"friendship":70,"id":314,"learnset":{"address":3315634,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":205},{"level":5,"move_id":45},{"level":10,"move_id":55},{"level":14,"move_id":205},{"level":19,"move_id":250},{"level":23,"move_id":310},{"level":28,"move_id":352},{"level":32,"move_id":54},{"level":37,"move_id":156},{"level":44,"move_id":323},{"level":52,"move_id":133},{"level":59,"move_id":56}]},"tmhm_learnset":"03B01E4086137274","types":[11,11]},{"abilities":[56,0],"address":3305564,"base_stats":[50,45,45,50,35,35],"catch_rate":255,"evolutions":[{"method":"ITEM","param":94,"species":316}],"friendship":70,"id":315,"learnset":{"address":3315666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":3,"move_id":39},{"level":7,"move_id":213},{"level":13,"move_id":47},{"level":15,"move_id":3},{"level":19,"move_id":274},{"level":25,"move_id":204},{"level":27,"move_id":185},{"level":31,"move_id":343},{"level":37,"move_id":215},{"level":39,"move_id":38}]},"tmhm_learnset":"00401E02ADFB362C","types":[0,0]},{"abilities":[56,0],"address":3305592,"base_stats":[70,65,65,70,55,55],"catch_rate":60,"evolutions":[],"friendship":70,"id":316,"learnset":{"address":3315696,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":213},{"level":1,"move_id":47},{"level":1,"move_id":3}]},"tmhm_learnset":"00E01E02ADFB762C","types":[0,0]},{"abilities":[16,0],"address":3305620,"base_stats":[60,90,70,40,60,120],"catch_rate":200,"evolutions":[],"friendship":70,"id":317,"learnset":{"address":3315706,"moves":[{"level":1,"move_id":168},{"level":1,"move_id":39},{"level":1,"move_id":310},{"level":1,"move_id":122},{"level":1,"move_id":10},{"level":4,"move_id":20},{"level":7,"move_id":185},{"level":12,"move_id":154},{"level":17,"move_id":60},{"level":24,"move_id":103},{"level":31,"move_id":163},{"level":40,"move_id":164},{"level":49,"move_id":246}]},"tmhm_learnset":"00E5BEE6EDF33625","types":[0,0]},{"abilities":[26,0],"address":3305648,"base_stats":[40,40,55,55,40,70],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":36,"species":319}],"friendship":70,"id":318,"learnset":{"address":3315734,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":37,"move_id":322},{"level":45,"move_id":153}]},"tmhm_learnset":"00408E51BE339620","types":[4,14]},{"abilities":[26,0],"address":3305676,"base_stats":[60,70,105,75,70,120],"catch_rate":90,"evolutions":[],"friendship":70,"id":319,"learnset":{"address":3315764,"moves":[{"level":1,"move_id":100},{"level":1,"move_id":93},{"level":1,"move_id":106},{"level":1,"move_id":229},{"level":3,"move_id":106},{"level":5,"move_id":229},{"level":7,"move_id":189},{"level":11,"move_id":60},{"level":15,"move_id":317},{"level":19,"move_id":120},{"level":25,"move_id":246},{"level":31,"move_id":201},{"level":36,"move_id":63},{"level":42,"move_id":322},{"level":55,"move_id":153}]},"tmhm_learnset":"00E08E51BE33D620","types":[4,14]},{"abilities":[5,42],"address":3305704,"base_stats":[30,45,135,30,45,90],"catch_rate":255,"evolutions":[],"friendship":70,"id":320,"learnset":{"address":3315796,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":7,"move_id":106},{"level":13,"move_id":88},{"level":16,"move_id":335},{"level":22,"move_id":86},{"level":28,"move_id":157},{"level":31,"move_id":201},{"level":37,"move_id":156},{"level":43,"move_id":192},{"level":46,"move_id":199}]},"tmhm_learnset":"00A01F5287910E20","types":[5,5]},{"abilities":[73,0],"address":3305732,"base_stats":[70,85,140,20,85,70],"catch_rate":90,"evolutions":[],"friendship":70,"id":321,"learnset":{"address":3315824,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":52},{"level":4,"move_id":123},{"level":7,"move_id":174},{"level":14,"move_id":108},{"level":17,"move_id":83},{"level":20,"move_id":34},{"level":27,"move_id":182},{"level":30,"move_id":53},{"level":33,"move_id":334},{"level":40,"move_id":133},{"level":43,"move_id":175},{"level":46,"move_id":257}]},"tmhm_learnset":"00A21E2C84510620","types":[10,10]},{"abilities":[51,0],"address":3305760,"base_stats":[50,75,75,50,65,65],"catch_rate":45,"evolutions":[],"friendship":35,"id":322,"learnset":{"address":3315856,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":10},{"level":5,"move_id":193},{"level":9,"move_id":101},{"level":13,"move_id":310},{"level":17,"move_id":154},{"level":21,"move_id":252},{"level":25,"move_id":197},{"level":29,"move_id":185},{"level":33,"move_id":282},{"level":37,"move_id":109},{"level":41,"move_id":247},{"level":45,"move_id":212}]},"tmhm_learnset":"00C53FC2FC130E2D","types":[17,7]},{"abilities":[12,0],"address":3305788,"base_stats":[50,48,43,60,46,41],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":30,"species":324}],"friendship":70,"id":323,"learnset":{"address":3315888,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":189},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":31,"move_id":89},{"level":36,"move_id":248},{"level":41,"move_id":90}]},"tmhm_learnset":"03101E5086133264","types":[11,4]},{"abilities":[12,0],"address":3305816,"base_stats":[110,78,73,60,76,71],"catch_rate":75,"evolutions":[],"friendship":70,"id":324,"learnset":{"address":3315918,"moves":[{"level":1,"move_id":321},{"level":1,"move_id":189},{"level":1,"move_id":300},{"level":1,"move_id":346},{"level":6,"move_id":300},{"level":6,"move_id":346},{"level":11,"move_id":55},{"level":16,"move_id":222},{"level":21,"move_id":133},{"level":26,"move_id":156},{"level":26,"move_id":173},{"level":36,"move_id":89},{"level":46,"move_id":248},{"level":56,"move_id":90}]},"tmhm_learnset":"03B01E5086137264","types":[11,4]},{"abilities":[33,0],"address":3305844,"base_stats":[43,30,55,97,40,65],"catch_rate":225,"evolutions":[],"friendship":70,"id":325,"learnset":{"address":3315948,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":204},{"level":12,"move_id":55},{"level":16,"move_id":97},{"level":24,"move_id":36},{"level":28,"move_id":213},{"level":36,"move_id":186},{"level":40,"move_id":175},{"level":48,"move_id":219}]},"tmhm_learnset":"03101E00841B3264","types":[11,11]},{"abilities":[52,75],"address":3305872,"base_stats":[43,80,65,35,50,35],"catch_rate":205,"evolutions":[{"method":"LEVEL","param":30,"species":327}],"friendship":70,"id":326,"learnset":{"address":3315974,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":32,"move_id":269},{"level":35,"move_id":152},{"level":38,"move_id":14},{"level":44,"move_id":12}]},"tmhm_learnset":"01B41EC8CC133A64","types":[11,11]},{"abilities":[52,75],"address":3305900,"base_stats":[63,120,85,55,90,55],"catch_rate":155,"evolutions":[],"friendship":70,"id":327,"learnset":{"address":3316004,"moves":[{"level":1,"move_id":145},{"level":1,"move_id":106},{"level":1,"move_id":11},{"level":1,"move_id":43},{"level":7,"move_id":106},{"level":10,"move_id":11},{"level":13,"move_id":43},{"level":20,"move_id":61},{"level":23,"move_id":182},{"level":26,"move_id":282},{"level":34,"move_id":269},{"level":39,"move_id":152},{"level":44,"move_id":14},{"level":52,"move_id":12}]},"tmhm_learnset":"03B41EC8CC137A64","types":[11,17]},{"abilities":[33,0],"address":3305928,"base_stats":[20,15,20,80,10,55],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":30,"species":329}],"friendship":70,"id":328,"learnset":{"address":3316034,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":150},{"level":15,"move_id":33},{"level":30,"move_id":175}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[63,0],"address":3305956,"base_stats":[95,60,79,81,100,125],"catch_rate":60,"evolutions":[],"friendship":70,"id":329,"learnset":{"address":3316048,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":55},{"level":5,"move_id":35},{"level":10,"move_id":346},{"level":15,"move_id":287},{"level":20,"move_id":352},{"level":25,"move_id":239},{"level":30,"move_id":105},{"level":35,"move_id":240},{"level":40,"move_id":56},{"level":45,"move_id":213},{"level":50,"move_id":219}]},"tmhm_learnset":"03101E00845B7264","types":[11,11]},{"abilities":[24,0],"address":3305984,"base_stats":[45,90,20,65,65,20],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":30,"species":331}],"friendship":35,"id":330,"learnset":{"address":3316078,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":31,"move_id":36},{"level":37,"move_id":207},{"level":43,"move_id":97}]},"tmhm_learnset":"03103F0084133A64","types":[11,17]},{"abilities":[24,0],"address":3306012,"base_stats":[70,120,40,95,95,40],"catch_rate":60,"evolutions":[],"friendship":35,"id":331,"learnset":{"address":3316104,"moves":[{"level":1,"move_id":43},{"level":1,"move_id":44},{"level":1,"move_id":99},{"level":1,"move_id":116},{"level":7,"move_id":99},{"level":13,"move_id":116},{"level":16,"move_id":184},{"level":22,"move_id":242},{"level":28,"move_id":103},{"level":33,"move_id":163},{"level":38,"move_id":269},{"level":43,"move_id":207},{"level":48,"move_id":130},{"level":53,"move_id":97}]},"tmhm_learnset":"03B03F4086137A74","types":[11,17]},{"abilities":[52,71],"address":3306040,"base_stats":[45,100,45,10,45,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":333}],"friendship":70,"id":332,"learnset":{"address":3316134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":44},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":41,"move_id":91},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A01E508E354620","types":[4,4]},{"abilities":[26,26],"address":3306068,"base_stats":[50,70,50,70,50,50],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":45,"species":334}],"friendship":70,"id":333,"learnset":{"address":3316158,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":49,"move_id":201},{"level":57,"move_id":63}]},"tmhm_learnset":"00A85E508E354620","types":[4,16]},{"abilities":[26,26],"address":3306096,"base_stats":[80,100,80,100,80,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":334,"learnset":{"address":3316184,"moves":[{"level":1,"move_id":44},{"level":1,"move_id":28},{"level":1,"move_id":185},{"level":1,"move_id":328},{"level":9,"move_id":28},{"level":17,"move_id":185},{"level":25,"move_id":328},{"level":33,"move_id":242},{"level":35,"move_id":225},{"level":41,"move_id":103},{"level":53,"move_id":201},{"level":65,"move_id":63}]},"tmhm_learnset":"00A85E748E754622","types":[4,16]},{"abilities":[47,62],"address":3306124,"base_stats":[72,60,30,25,20,30],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":24,"species":336}],"friendship":70,"id":335,"learnset":{"address":3316210,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":28,"move_id":282},{"level":31,"move_id":265},{"level":37,"move_id":187},{"level":40,"move_id":203},{"level":46,"move_id":69},{"level":49,"move_id":179}]},"tmhm_learnset":"00B01E40CE1306A1","types":[1,1]},{"abilities":[47,62],"address":3306152,"base_stats":[144,120,60,50,40,60],"catch_rate":200,"evolutions":[],"friendship":70,"id":336,"learnset":{"address":3316242,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":116},{"level":1,"move_id":28},{"level":1,"move_id":292},{"level":4,"move_id":28},{"level":10,"move_id":292},{"level":13,"move_id":233},{"level":19,"move_id":252},{"level":22,"move_id":18},{"level":29,"move_id":282},{"level":33,"move_id":265},{"level":40,"move_id":187},{"level":44,"move_id":203},{"level":51,"move_id":69},{"level":55,"move_id":179}]},"tmhm_learnset":"00B01E40CE1346A1","types":[1,1]},{"abilities":[9,31],"address":3306180,"base_stats":[40,45,40,65,65,40],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":26,"species":338}],"friendship":70,"id":337,"learnset":{"address":3316274,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":28,"move_id":46},{"level":33,"move_id":44},{"level":36,"move_id":87},{"level":41,"move_id":268}]},"tmhm_learnset":"00603E0285D30230","types":[13,13]},{"abilities":[9,31],"address":3306208,"base_stats":[70,75,60,105,105,60],"catch_rate":45,"evolutions":[],"friendship":70,"id":338,"learnset":{"address":3316304,"moves":[{"level":1,"move_id":86},{"level":1,"move_id":43},{"level":1,"move_id":336},{"level":1,"move_id":33},{"level":4,"move_id":86},{"level":9,"move_id":43},{"level":12,"move_id":336},{"level":17,"move_id":98},{"level":20,"move_id":209},{"level":25,"move_id":316},{"level":31,"move_id":46},{"level":39,"move_id":44},{"level":45,"move_id":87},{"level":53,"move_id":268}]},"tmhm_learnset":"00603E0285D34230","types":[13,13]},{"abilities":[12,0],"address":3306236,"base_stats":[60,60,40,35,65,45],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":33,"species":340}],"friendship":70,"id":339,"learnset":{"address":3316334,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":35,"move_id":89},{"level":41,"move_id":53},{"level":49,"move_id":38}]},"tmhm_learnset":"00A21E748E110620","types":[10,4]},{"abilities":[40,0],"address":3306264,"base_stats":[70,100,70,40,105,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":340,"learnset":{"address":3316360,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":33},{"level":1,"move_id":52},{"level":1,"move_id":222},{"level":11,"move_id":52},{"level":19,"move_id":222},{"level":25,"move_id":116},{"level":29,"move_id":36},{"level":31,"move_id":133},{"level":33,"move_id":157},{"level":37,"move_id":89},{"level":45,"move_id":284},{"level":55,"move_id":90}]},"tmhm_learnset":"00A21E748E114630","types":[10,4]},{"abilities":[47,0],"address":3306292,"base_stats":[70,40,50,25,55,50],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":342}],"friendship":70,"id":341,"learnset":{"address":3316388,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":59},{"level":49,"move_id":329}]},"tmhm_learnset":"03B01E4086533264","types":[15,11]},{"abilities":[47,0],"address":3306320,"base_stats":[90,60,70,45,75,70],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":44,"species":343}],"friendship":70,"id":342,"learnset":{"address":3316416,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":47,"move_id":59},{"level":55,"move_id":329}]},"tmhm_learnset":"03B01E4086533274","types":[15,11]},{"abilities":[47,0],"address":3306348,"base_stats":[110,80,90,65,95,90],"catch_rate":45,"evolutions":[],"friendship":70,"id":343,"learnset":{"address":3316444,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":45},{"level":1,"move_id":55},{"level":1,"move_id":227},{"level":7,"move_id":227},{"level":13,"move_id":301},{"level":19,"move_id":34},{"level":25,"move_id":62},{"level":31,"move_id":258},{"level":39,"move_id":156},{"level":39,"move_id":173},{"level":50,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"03B01E4086537274","types":[15,11]},{"abilities":[8,0],"address":3306376,"base_stats":[50,85,40,35,85,40],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":32,"species":345}],"friendship":35,"id":344,"learnset":{"address":3316472,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":33,"move_id":191},{"level":37,"move_id":302},{"level":41,"move_id":178},{"level":45,"move_id":201}]},"tmhm_learnset":"00441E1084350721","types":[12,12]},{"abilities":[8,0],"address":3306404,"base_stats":[70,115,60,55,115,60],"catch_rate":60,"evolutions":[],"friendship":35,"id":345,"learnset":{"address":3316504,"moves":[{"level":1,"move_id":40},{"level":1,"move_id":43},{"level":1,"move_id":71},{"level":1,"move_id":74},{"level":5,"move_id":71},{"level":9,"move_id":74},{"level":13,"move_id":73},{"level":17,"move_id":28},{"level":21,"move_id":42},{"level":25,"move_id":275},{"level":29,"move_id":185},{"level":35,"move_id":191},{"level":41,"move_id":302},{"level":47,"move_id":178},{"level":53,"move_id":201}]},"tmhm_learnset":"00641E1084354721","types":[12,17]},{"abilities":[39,0],"address":3306432,"base_stats":[50,50,50,50,50,50],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":42,"species":347}],"friendship":70,"id":346,"learnset":{"address":3316536,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":37,"move_id":258},{"level":43,"move_id":59}]},"tmhm_learnset":"00401E00A41BB264","types":[15,15]},{"abilities":[39,0],"address":3306460,"base_stats":[80,80,80,80,80,80],"catch_rate":75,"evolutions":[],"friendship":70,"id":347,"learnset":{"address":3316564,"moves":[{"level":1,"move_id":181},{"level":1,"move_id":43},{"level":1,"move_id":104},{"level":1,"move_id":44},{"level":7,"move_id":104},{"level":10,"move_id":44},{"level":16,"move_id":196},{"level":19,"move_id":29},{"level":25,"move_id":182},{"level":28,"move_id":242},{"level":34,"move_id":58},{"level":42,"move_id":258},{"level":53,"move_id":59},{"level":61,"move_id":329}]},"tmhm_learnset":"00401F00A61BFA64","types":[15,15]},{"abilities":[26,0],"address":3306488,"base_stats":[70,55,65,70,95,85],"catch_rate":45,"evolutions":[],"friendship":70,"id":348,"learnset":{"address":3316594,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":95},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":94},{"level":43,"move_id":248},{"level":49,"move_id":153}]},"tmhm_learnset":"00408E51B61BD228","types":[5,14]},{"abilities":[26,0],"address":3306516,"base_stats":[70,95,85,70,55,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":349,"learnset":{"address":3316620,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":7,"move_id":93},{"level":13,"move_id":88},{"level":19,"move_id":83},{"level":25,"move_id":149},{"level":31,"move_id":322},{"level":37,"move_id":157},{"level":43,"move_id":76},{"level":49,"move_id":153}]},"tmhm_learnset":"00428E75B639C628","types":[5,14]},{"abilities":[47,37],"address":3306544,"base_stats":[50,20,40,20,20,40],"catch_rate":150,"evolutions":[{"method":"FRIENDSHIP","param":0,"species":183}],"friendship":70,"id":350,"learnset":{"address":3316646,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":145},{"level":1,"move_id":150},{"level":3,"move_id":204},{"level":6,"move_id":39},{"level":10,"move_id":145},{"level":15,"move_id":21},{"level":21,"move_id":55}]},"tmhm_learnset":"01101E0084533264","types":[0,0]},{"abilities":[47,20],"address":3306572,"base_stats":[60,25,35,60,70,80],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":32,"species":352}],"friendship":70,"id":351,"learnset":{"address":3316666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":1,"move_id":150},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":34,"move_id":94},{"level":37,"move_id":156},{"level":37,"move_id":173},{"level":43,"move_id":340}]},"tmhm_learnset":"0041BF03B4538E28","types":[14,14]},{"abilities":[47,20],"address":3306600,"base_stats":[80,45,65,80,90,110],"catch_rate":60,"evolutions":[],"friendship":70,"id":352,"learnset":{"address":3316696,"moves":[{"level":1,"move_id":150},{"level":1,"move_id":149},{"level":1,"move_id":316},{"level":1,"move_id":60},{"level":7,"move_id":149},{"level":10,"move_id":316},{"level":16,"move_id":60},{"level":19,"move_id":244},{"level":25,"move_id":109},{"level":28,"move_id":277},{"level":37,"move_id":94},{"level":43,"move_id":156},{"level":43,"move_id":173},{"level":55,"move_id":340}]},"tmhm_learnset":"0041BF03B453CE29","types":[14,14]},{"abilities":[57,0],"address":3306628,"base_stats":[60,50,40,95,85,75],"catch_rate":200,"evolutions":[],"friendship":70,"id":353,"learnset":{"address":3316726,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":313},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[58,0],"address":3306656,"base_stats":[60,40,50,95,75,85],"catch_rate":200,"evolutions":[],"friendship":70,"id":354,"learnset":{"address":3316756,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":98},{"level":1,"move_id":45},{"level":4,"move_id":86},{"level":10,"move_id":98},{"level":13,"move_id":270},{"level":19,"move_id":209},{"level":22,"move_id":227},{"level":28,"move_id":204},{"level":31,"move_id":268},{"level":37,"move_id":87},{"level":40,"move_id":226},{"level":47,"move_id":97}]},"tmhm_learnset":"00401E0285D38220","types":[13,13]},{"abilities":[52,22],"address":3306684,"base_stats":[50,85,85,50,55,55],"catch_rate":45,"evolutions":[],"friendship":70,"id":355,"learnset":{"address":3316786,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":6,"move_id":313},{"level":11,"move_id":44},{"level":16,"move_id":230},{"level":21,"move_id":11},{"level":26,"move_id":185},{"level":31,"move_id":226},{"level":36,"move_id":242},{"level":41,"move_id":334},{"level":46,"move_id":254},{"level":46,"move_id":256},{"level":46,"move_id":255}]},"tmhm_learnset":"00A01F7CC4335E21","types":[8,8]},{"abilities":[74,0],"address":3306712,"base_stats":[30,40,55,60,40,55],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":37,"species":357}],"friendship":70,"id":356,"learnset":{"address":3316818,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":117},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":38,"move_id":244},{"level":42,"move_id":179},{"level":48,"move_id":105}]},"tmhm_learnset":"00E01E41F41386A9","types":[1,14]},{"abilities":[74,0],"address":3306740,"base_stats":[60,60,75,80,60,75],"catch_rate":90,"evolutions":[],"friendship":70,"id":357,"learnset":{"address":3316848,"moves":[{"level":1,"move_id":7},{"level":1,"move_id":9},{"level":1,"move_id":8},{"level":1,"move_id":117},{"level":1,"move_id":96},{"level":1,"move_id":93},{"level":1,"move_id":197},{"level":4,"move_id":96},{"level":9,"move_id":93},{"level":12,"move_id":197},{"level":18,"move_id":237},{"level":22,"move_id":170},{"level":28,"move_id":347},{"level":32,"move_id":136},{"level":40,"move_id":244},{"level":46,"move_id":179},{"level":54,"move_id":105}]},"tmhm_learnset":"00E01E41F413C6A9","types":[1,14]},{"abilities":[30,0],"address":3306768,"base_stats":[45,40,60,50,40,75],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":35,"species":359}],"friendship":70,"id":358,"learnset":{"address":3316884,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":38,"move_id":119},{"level":41,"move_id":287},{"level":48,"move_id":195}]},"tmhm_learnset":"00087E80843B1620","types":[0,2]},{"abilities":[30,0],"address":3306796,"base_stats":[75,70,90,80,70,105],"catch_rate":45,"evolutions":[],"friendship":70,"id":359,"learnset":{"address":3316912,"moves":[{"level":1,"move_id":64},{"level":1,"move_id":45},{"level":1,"move_id":310},{"level":1,"move_id":47},{"level":8,"move_id":310},{"level":11,"move_id":47},{"level":18,"move_id":31},{"level":21,"move_id":219},{"level":28,"move_id":54},{"level":31,"move_id":36},{"level":35,"move_id":225},{"level":40,"move_id":349},{"level":45,"move_id":287},{"level":54,"move_id":195},{"level":59,"move_id":143}]},"tmhm_learnset":"00887EA4867B5632","types":[16,2]},{"abilities":[23,0],"address":3306824,"base_stats":[95,23,48,23,23,48],"catch_rate":125,"evolutions":[{"method":"LEVEL","param":15,"species":202}],"friendship":70,"id":360,"learnset":{"address":3316944,"moves":[{"level":1,"move_id":68},{"level":1,"move_id":150},{"level":1,"move_id":204},{"level":1,"move_id":227},{"level":15,"move_id":68},{"level":15,"move_id":243},{"level":15,"move_id":219},{"level":15,"move_id":194}]},"tmhm_learnset":"0000000000000000","types":[14,14]},{"abilities":[26,0],"address":3306852,"base_stats":[20,40,90,25,30,90],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":37,"species":362}],"friendship":35,"id":361,"learnset":{"address":3316962,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":38,"move_id":261},{"level":45,"move_id":212},{"level":49,"move_id":248}]},"tmhm_learnset":"0041BF00B4133E28","types":[7,7]},{"abilities":[46,0],"address":3306880,"base_stats":[40,70,130,25,60,130],"catch_rate":90,"evolutions":[],"friendship":35,"id":362,"learnset":{"address":3316990,"moves":[{"level":1,"move_id":20},{"level":1,"move_id":43},{"level":1,"move_id":101},{"level":1,"move_id":50},{"level":5,"move_id":50},{"level":12,"move_id":193},{"level":16,"move_id":310},{"level":23,"move_id":109},{"level":27,"move_id":228},{"level":34,"move_id":174},{"level":37,"move_id":325},{"level":41,"move_id":261},{"level":51,"move_id":212},{"level":58,"move_id":248}]},"tmhm_learnset":"00E1BF40B6137E29","types":[7,7]},{"abilities":[30,38],"address":3306908,"base_stats":[50,60,45,65,100,80],"catch_rate":150,"evolutions":[],"friendship":70,"id":363,"learnset":{"address":3317020,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":71},{"level":5,"move_id":74},{"level":9,"move_id":40},{"level":13,"move_id":78},{"level":17,"move_id":72},{"level":21,"move_id":73},{"level":25,"move_id":345},{"level":29,"move_id":320},{"level":33,"move_id":202},{"level":37,"move_id":230},{"level":41,"move_id":275},{"level":45,"move_id":92},{"level":49,"move_id":80},{"level":53,"move_id":312},{"level":57,"move_id":235}]},"tmhm_learnset":"00441E08A4350720","types":[12,3]},{"abilities":[54,0],"address":3306936,"base_stats":[60,60,60,30,35,35],"catch_rate":255,"evolutions":[{"method":"LEVEL","param":18,"species":365}],"friendship":70,"id":364,"learnset":{"address":3317058,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E5B336A5","types":[0,0]},{"abilities":[72,0],"address":3306964,"base_stats":[80,80,80,90,55,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":36,"species":366}],"friendship":70,"id":365,"learnset":{"address":3317082,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":116},{"level":1,"move_id":227},{"level":1,"move_id":253},{"level":7,"move_id":227},{"level":13,"move_id":253},{"level":19,"move_id":154},{"level":25,"move_id":203},{"level":31,"move_id":163},{"level":37,"move_id":68},{"level":43,"move_id":264},{"level":49,"move_id":179}]},"tmhm_learnset":"00A41EA6E7B33EB5","types":[0,0]},{"abilities":[54,0],"address":3306992,"base_stats":[150,160,100,100,95,65],"catch_rate":45,"evolutions":[],"friendship":70,"id":366,"learnset":{"address":3317108,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":281},{"level":1,"move_id":227},{"level":1,"move_id":303},{"level":7,"move_id":227},{"level":13,"move_id":303},{"level":19,"move_id":185},{"level":25,"move_id":133},{"level":31,"move_id":343},{"level":36,"move_id":207},{"level":37,"move_id":68},{"level":43,"move_id":175}]},"tmhm_learnset":"00A41EA6E7B37EB5","types":[0,0]},{"abilities":[64,60],"address":3307020,"base_stats":[70,43,53,40,43,53],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":26,"species":368}],"friendship":70,"id":367,"learnset":{"address":3317134,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":28,"move_id":92},{"level":34,"move_id":254},{"level":34,"move_id":255},{"level":34,"move_id":256},{"level":39,"move_id":188}]},"tmhm_learnset":"00A11E0AA4371724","types":[3,3]},{"abilities":[64,60],"address":3307048,"base_stats":[100,73,83,55,73,83],"catch_rate":75,"evolutions":[],"friendship":70,"id":368,"learnset":{"address":3317164,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":281},{"level":1,"move_id":139},{"level":1,"move_id":124},{"level":6,"move_id":281},{"level":9,"move_id":139},{"level":14,"move_id":124},{"level":17,"move_id":133},{"level":23,"move_id":227},{"level":26,"move_id":34},{"level":31,"move_id":92},{"level":40,"move_id":254},{"level":40,"move_id":255},{"level":40,"move_id":256},{"level":48,"move_id":188}]},"tmhm_learnset":"00A11E0AA4375724","types":[3,3]},{"abilities":[34,0],"address":3307076,"base_stats":[99,68,83,51,72,87],"catch_rate":200,"evolutions":[],"friendship":70,"id":369,"learnset":{"address":3317196,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":16},{"level":7,"move_id":74},{"level":11,"move_id":75},{"level":17,"move_id":23},{"level":21,"move_id":230},{"level":27,"move_id":18},{"level":31,"move_id":345},{"level":37,"move_id":34},{"level":41,"move_id":76},{"level":47,"move_id":235}]},"tmhm_learnset":"00EC5E80863D4730","types":[12,2]},{"abilities":[43,0],"address":3307104,"base_stats":[64,51,23,28,51,23],"catch_rate":190,"evolutions":[{"method":"LEVEL","param":20,"species":371}],"friendship":70,"id":370,"learnset":{"address":3317224,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":1},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":21,"move_id":48},{"level":25,"move_id":23},{"level":31,"move_id":103},{"level":35,"move_id":46},{"level":41,"move_id":156},{"level":41,"move_id":214},{"level":45,"move_id":304}]},"tmhm_learnset":"00001E26A4333634","types":[0,0]},{"abilities":[43,0],"address":3307132,"base_stats":[84,71,43,48,71,43],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":40,"species":372}],"friendship":70,"id":371,"learnset":{"address":3317254,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":43,"move_id":46},{"level":51,"move_id":156},{"level":51,"move_id":214},{"level":57,"move_id":304}]},"tmhm_learnset":"00A21F26E6333E34","types":[0,0]},{"abilities":[43,0],"address":3307160,"base_stats":[104,91,63,68,91,63],"catch_rate":45,"evolutions":[],"friendship":70,"id":372,"learnset":{"address":3317284,"moves":[{"level":1,"move_id":1},{"level":1,"move_id":253},{"level":1,"move_id":310},{"level":1,"move_id":336},{"level":5,"move_id":253},{"level":11,"move_id":310},{"level":15,"move_id":336},{"level":23,"move_id":48},{"level":29,"move_id":23},{"level":37,"move_id":103},{"level":40,"move_id":63},{"level":45,"move_id":46},{"level":55,"move_id":156},{"level":55,"move_id":214},{"level":63,"move_id":304}]},"tmhm_learnset":"00A21F26E6337E34","types":[0,0]},{"abilities":[75,0],"address":3307188,"base_stats":[35,64,85,32,74,55],"catch_rate":255,"evolutions":[{"method":"ITEM","param":192,"species":374},{"method":"ITEM","param":193,"species":375}],"friendship":70,"id":373,"learnset":{"address":3317316,"moves":[{"level":1,"move_id":128},{"level":1,"move_id":55},{"level":1,"move_id":250},{"level":1,"move_id":334}]},"tmhm_learnset":"03101E0084133264","types":[11,11]},{"abilities":[33,0],"address":3307216,"base_stats":[55,104,105,52,94,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":374,"learnset":{"address":3317326,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":44},{"level":15,"move_id":103},{"level":22,"move_id":352},{"level":29,"move_id":184},{"level":36,"move_id":242},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03111E4084137264","types":[11,11]},{"abilities":[33,0],"address":3307244,"base_stats":[55,84,105,52,114,75],"catch_rate":60,"evolutions":[],"friendship":70,"id":375,"learnset":{"address":3317350,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":250},{"level":8,"move_id":93},{"level":15,"move_id":97},{"level":22,"move_id":352},{"level":29,"move_id":133},{"level":36,"move_id":94},{"level":43,"move_id":226},{"level":50,"move_id":56}]},"tmhm_learnset":"03101E00B41B7264","types":[11,11]},{"abilities":[46,0],"address":3307272,"base_stats":[65,130,60,75,75,60],"catch_rate":30,"evolutions":[],"friendship":35,"id":376,"learnset":{"address":3317374,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":5,"move_id":43},{"level":9,"move_id":269},{"level":13,"move_id":98},{"level":17,"move_id":13},{"level":21,"move_id":44},{"level":26,"move_id":14},{"level":31,"move_id":104},{"level":36,"move_id":163},{"level":41,"move_id":248},{"level":46,"move_id":195}]},"tmhm_learnset":"00E53FB6A5D37E6C","types":[17,17]},{"abilities":[15,0],"address":3307300,"base_stats":[44,75,35,45,63,33],"catch_rate":225,"evolutions":[{"method":"LEVEL","param":37,"species":378}],"friendship":35,"id":377,"learnset":{"address":3317404,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":282},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":37,"move_id":185},{"level":44,"move_id":247},{"level":49,"move_id":289},{"level":56,"move_id":288}]},"tmhm_learnset":"0041BF02B5930E28","types":[7,7]},{"abilities":[15,0],"address":3307328,"base_stats":[64,115,65,65,83,63],"catch_rate":45,"evolutions":[],"friendship":35,"id":378,"learnset":{"address":3317432,"moves":[{"level":1,"move_id":282},{"level":1,"move_id":103},{"level":1,"move_id":101},{"level":1,"move_id":174},{"level":8,"move_id":103},{"level":13,"move_id":101},{"level":20,"move_id":174},{"level":25,"move_id":180},{"level":32,"move_id":261},{"level":39,"move_id":185},{"level":48,"move_id":247},{"level":55,"move_id":289},{"level":64,"move_id":288}]},"tmhm_learnset":"0041BF02B5934E28","types":[7,7]},{"abilities":[61,0],"address":3307356,"base_stats":[73,100,60,65,100,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":379,"learnset":{"address":3317460,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":7,"move_id":122},{"level":10,"move_id":44},{"level":16,"move_id":342},{"level":19,"move_id":103},{"level":25,"move_id":137},{"level":28,"move_id":242},{"level":34,"move_id":305},{"level":37,"move_id":207},{"level":43,"move_id":114}]},"tmhm_learnset":"00A13E0C8E570E20","types":[3,3]},{"abilities":[17,0],"address":3307384,"base_stats":[73,115,60,90,60,60],"catch_rate":90,"evolutions":[],"friendship":70,"id":380,"learnset":{"address":3317488,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":4,"move_id":43},{"level":7,"move_id":98},{"level":10,"move_id":14},{"level":13,"move_id":210},{"level":19,"move_id":163},{"level":25,"move_id":228},{"level":31,"move_id":306},{"level":37,"move_id":269},{"level":46,"move_id":197},{"level":55,"move_id":206}]},"tmhm_learnset":"00A03EA6EDF73E35","types":[0,0]},{"abilities":[33,69],"address":3307412,"base_stats":[100,90,130,55,45,65],"catch_rate":25,"evolutions":[],"friendship":70,"id":381,"learnset":{"address":3317518,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":8,"move_id":55},{"level":15,"move_id":317},{"level":22,"move_id":281},{"level":29,"move_id":36},{"level":36,"move_id":300},{"level":43,"move_id":246},{"level":50,"move_id":156},{"level":57,"move_id":38},{"level":64,"move_id":56}]},"tmhm_learnset":"03901E50861B726C","types":[11,5]},{"abilities":[5,69],"address":3307440,"base_stats":[50,70,100,30,40,40],"catch_rate":180,"evolutions":[{"method":"LEVEL","param":32,"species":383}],"friendship":35,"id":382,"learnset":{"address":3317546,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":34,"move_id":182},{"level":39,"move_id":319},{"level":44,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307468,"base_stats":[60,90,140,40,50,50],"catch_rate":90,"evolutions":[{"method":"LEVEL","param":42,"species":384}],"friendship":35,"id":383,"learnset":{"address":3317578,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":45,"move_id":319},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41ED28E530634","types":[8,5]},{"abilities":[5,69],"address":3307496,"base_stats":[70,110,180,50,60,60],"catch_rate":45,"evolutions":[],"friendship":35,"id":384,"learnset":{"address":3317610,"moves":[{"level":1,"move_id":33},{"level":1,"move_id":106},{"level":1,"move_id":189},{"level":1,"move_id":29},{"level":4,"move_id":106},{"level":7,"move_id":189},{"level":10,"move_id":29},{"level":13,"move_id":232},{"level":17,"move_id":334},{"level":21,"move_id":46},{"level":25,"move_id":36},{"level":29,"move_id":231},{"level":37,"move_id":182},{"level":50,"move_id":319},{"level":63,"move_id":38}]},"tmhm_learnset":"00B41EF6CFF37E37","types":[8,5]},{"abilities":[59,0],"address":3307524,"base_stats":[70,70,70,70,70,70],"catch_rate":45,"evolutions":[],"friendship":70,"id":385,"learnset":{"address":3317642,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":10,"move_id":55},{"level":10,"move_id":52},{"level":10,"move_id":181},{"level":20,"move_id":240},{"level":20,"move_id":241},{"level":20,"move_id":258},{"level":30,"move_id":311}]},"tmhm_learnset":"00403E36A5B33664","types":[0,0]},{"abilities":[35,68],"address":3307552,"base_stats":[65,73,55,85,47,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":386,"learnset":{"address":3317666,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":109},{"level":9,"move_id":104},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":294},{"level":25,"move_id":324},{"level":29,"move_id":182},{"level":33,"move_id":270},{"level":37,"move_id":38}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[12,0],"address":3307580,"base_stats":[65,47,55,85,73,75],"catch_rate":150,"evolutions":[],"friendship":70,"id":387,"learnset":{"address":3317694,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":33},{"level":5,"move_id":230},{"level":9,"move_id":204},{"level":13,"move_id":236},{"level":17,"move_id":98},{"level":21,"move_id":273},{"level":25,"move_id":227},{"level":29,"move_id":260},{"level":33,"move_id":270},{"level":37,"move_id":343}]},"tmhm_learnset":"00403E82E5B78625","types":[6,6]},{"abilities":[21,0],"address":3307608,"base_stats":[66,41,77,23,61,87],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":389}],"friendship":70,"id":388,"learnset":{"address":3317722,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":310},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":43,"move_id":246},{"level":50,"move_id":254},{"level":50,"move_id":255},{"level":50,"move_id":256}]},"tmhm_learnset":"00001E1884350720","types":[5,12]},{"abilities":[21,0],"address":3307636,"base_stats":[86,81,97,43,81,107],"catch_rate":45,"evolutions":[],"friendship":70,"id":389,"learnset":{"address":3317750,"moves":[{"level":1,"move_id":310},{"level":1,"move_id":132},{"level":1,"move_id":51},{"level":1,"move_id":275},{"level":8,"move_id":132},{"level":15,"move_id":51},{"level":22,"move_id":275},{"level":29,"move_id":109},{"level":36,"move_id":133},{"level":48,"move_id":246},{"level":60,"move_id":254},{"level":60,"move_id":255},{"level":60,"move_id":256}]},"tmhm_learnset":"00A01E5886354720","types":[5,12]},{"abilities":[4,0],"address":3307664,"base_stats":[45,95,50,75,40,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":40,"species":391}],"friendship":70,"id":390,"learnset":{"address":3317778,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":10},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":43,"move_id":210},{"level":49,"move_id":163},{"level":55,"move_id":350}]},"tmhm_learnset":"00841ED0CC110624","types":[5,6]},{"abilities":[4,0],"address":3307692,"base_stats":[75,125,100,45,70,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":391,"learnset":{"address":3317806,"moves":[{"level":1,"move_id":10},{"level":1,"move_id":106},{"level":1,"move_id":300},{"level":1,"move_id":55},{"level":7,"move_id":106},{"level":13,"move_id":300},{"level":19,"move_id":55},{"level":25,"move_id":232},{"level":31,"move_id":182},{"level":37,"move_id":246},{"level":46,"move_id":210},{"level":55,"move_id":163},{"level":64,"move_id":350}]},"tmhm_learnset":"00A41ED0CE514624","types":[5,6]},{"abilities":[28,36],"address":3307720,"base_stats":[28,25,25,40,45,35],"catch_rate":235,"evolutions":[{"method":"LEVEL","param":20,"species":393}],"friendship":35,"id":392,"learnset":{"address":3317834,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":93},{"level":1,"move_id":45},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":31,"move_id":286},{"level":36,"move_id":248},{"level":41,"move_id":95},{"level":46,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307748,"base_stats":[38,35,35,50,65,55],"catch_rate":120,"evolutions":[{"method":"LEVEL","param":30,"species":394}],"friendship":35,"id":393,"learnset":{"address":3317862,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":40,"move_id":248},{"level":47,"move_id":95},{"level":54,"move_id":138}]},"tmhm_learnset":"0041BF03B49B8E28","types":[14,14]},{"abilities":[28,36],"address":3307776,"base_stats":[68,65,65,80,125,115],"catch_rate":45,"evolutions":[],"friendship":35,"id":394,"learnset":{"address":3317890,"moves":[{"level":1,"move_id":45},{"level":1,"move_id":93},{"level":1,"move_id":104},{"level":1,"move_id":100},{"level":6,"move_id":93},{"level":11,"move_id":104},{"level":16,"move_id":100},{"level":21,"move_id":347},{"level":26,"move_id":94},{"level":33,"move_id":286},{"level":42,"move_id":248},{"level":51,"move_id":95},{"level":60,"move_id":138}]},"tmhm_learnset":"0041BF03B49BCE28","types":[14,14]},{"abilities":[69,0],"address":3307804,"base_stats":[45,75,60,50,40,30],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":30,"species":396}],"friendship":35,"id":395,"learnset":{"address":3317918,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":99},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":33,"move_id":225},{"level":37,"move_id":184},{"level":41,"move_id":242},{"level":49,"move_id":337},{"level":53,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[69,0],"address":3307832,"base_stats":[65,95,100,50,60,50],"catch_rate":45,"evolutions":[{"method":"LEVEL","param":50,"species":397}],"friendship":35,"id":396,"learnset":{"address":3317948,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":56,"move_id":242},{"level":69,"move_id":337},{"level":78,"move_id":38}]},"tmhm_learnset":"00A41EE4C4130632","types":[16,16]},{"abilities":[22,0],"address":3307860,"base_stats":[95,135,80,100,110,80],"catch_rate":45,"evolutions":[],"friendship":35,"id":397,"learnset":{"address":3317980,"moves":[{"level":1,"move_id":99},{"level":1,"move_id":44},{"level":1,"move_id":43},{"level":1,"move_id":29},{"level":5,"move_id":44},{"level":9,"move_id":43},{"level":17,"move_id":29},{"level":21,"move_id":116},{"level":25,"move_id":52},{"level":30,"move_id":182},{"level":38,"move_id":225},{"level":47,"move_id":184},{"level":50,"move_id":19},{"level":61,"move_id":242},{"level":79,"move_id":337},{"level":93,"move_id":38}]},"tmhm_learnset":"00AC5EE4C6534632","types":[16,2]},{"abilities":[29,0],"address":3307888,"base_stats":[40,55,80,30,35,60],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":20,"species":399}],"friendship":35,"id":398,"learnset":{"address":3318014,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36}]},"tmhm_learnset":"0000000000000000","types":[8,14]},{"abilities":[29,0],"address":3307916,"base_stats":[60,75,100,50,55,80],"catch_rate":3,"evolutions":[{"method":"LEVEL","param":45,"species":400}],"friendship":35,"id":399,"learnset":{"address":3318024,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":36},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":50,"move_id":309},{"level":56,"move_id":97},{"level":62,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307944,"base_stats":[80,135,130,70,95,90],"catch_rate":3,"evolutions":[],"friendship":35,"id":400,"learnset":{"address":3318052,"moves":[{"level":1,"move_id":36},{"level":1,"move_id":93},{"level":1,"move_id":232},{"level":1,"move_id":184},{"level":20,"move_id":93},{"level":20,"move_id":232},{"level":26,"move_id":184},{"level":32,"move_id":228},{"level":38,"move_id":94},{"level":44,"move_id":334},{"level":55,"move_id":309},{"level":66,"move_id":97},{"level":77,"move_id":63}]},"tmhm_learnset":"00E40ED9F613C620","types":[8,14]},{"abilities":[29,0],"address":3307972,"base_stats":[80,100,200,50,50,100],"catch_rate":3,"evolutions":[],"friendship":35,"id":401,"learnset":{"address":3318080,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":88},{"level":1,"move_id":153},{"level":9,"move_id":88},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E52CF994621","types":[5,5]},{"abilities":[29,0],"address":3308000,"base_stats":[80,50,100,50,100,200],"catch_rate":3,"evolutions":[],"friendship":35,"id":402,"learnset":{"address":3318106,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":196},{"level":1,"move_id":153},{"level":9,"move_id":196},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00E02C79B7261","types":[15,15]},{"abilities":[29,0],"address":3308028,"base_stats":[80,75,150,50,75,150],"catch_rate":3,"evolutions":[],"friendship":35,"id":403,"learnset":{"address":3318132,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":232},{"level":1,"move_id":153},{"level":9,"move_id":232},{"level":17,"move_id":174},{"level":25,"move_id":276},{"level":33,"move_id":246},{"level":41,"move_id":334},{"level":41,"move_id":133},{"level":49,"move_id":192},{"level":57,"move_id":199},{"level":65,"move_id":63}]},"tmhm_learnset":"00A00ED2C79B4621","types":[8,8]},{"abilities":[2,0],"address":3308056,"base_stats":[100,100,90,90,150,140],"catch_rate":5,"evolutions":[],"friendship":0,"id":404,"learnset":{"address":3318160,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":352},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":34},{"level":30,"move_id":347},{"level":35,"move_id":58},{"level":45,"move_id":56},{"level":50,"move_id":156},{"level":60,"move_id":329},{"level":65,"move_id":38},{"level":75,"move_id":323}]},"tmhm_learnset":"03B00E42C79B727C","types":[11,11]},{"abilities":[70,0],"address":3308084,"base_stats":[100,150,140,90,100,90],"catch_rate":5,"evolutions":[],"friendship":0,"id":405,"learnset":{"address":3318190,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":341},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":163},{"level":30,"move_id":339},{"level":35,"move_id":89},{"level":45,"move_id":126},{"level":50,"move_id":156},{"level":60,"move_id":90},{"level":65,"move_id":76},{"level":75,"move_id":284}]},"tmhm_learnset":"00A60EF6CFF946B2","types":[4,4]},{"abilities":[77,0],"address":3308112,"base_stats":[105,150,90,95,150,90],"catch_rate":3,"evolutions":[],"friendship":0,"id":406,"learnset":{"address":3318220,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":239},{"level":5,"move_id":184},{"level":15,"move_id":246},{"level":20,"move_id":337},{"level":30,"move_id":349},{"level":35,"move_id":242},{"level":45,"move_id":19},{"level":50,"move_id":156},{"level":60,"move_id":245},{"level":65,"move_id":200},{"level":75,"move_id":63}]},"tmhm_learnset":"03BA0EB6C7F376B6","types":[16,2]},{"abilities":[26,0],"address":3308140,"base_stats":[80,80,90,110,110,130],"catch_rate":3,"evolutions":[],"friendship":90,"id":407,"learnset":{"address":3318250,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":273},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":346},{"level":30,"move_id":287},{"level":35,"move_id":296},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":204}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[26,0],"address":3308168,"base_stats":[80,90,80,110,130,110],"catch_rate":3,"evolutions":[],"friendship":90,"id":408,"learnset":{"address":3318280,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":149},{"level":5,"move_id":262},{"level":10,"move_id":270},{"level":15,"move_id":219},{"level":20,"move_id":225},{"level":25,"move_id":182},{"level":30,"move_id":287},{"level":35,"move_id":295},{"level":40,"move_id":94},{"level":45,"move_id":105},{"level":50,"move_id":349}]},"tmhm_learnset":"035C5E93B7BBD63E","types":[16,14]},{"abilities":[32,0],"address":3308196,"base_stats":[100,100,100,100,100,100],"catch_rate":3,"evolutions":[],"friendship":100,"id":409,"learnset":{"address":3318310,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":273},{"level":1,"move_id":93},{"level":5,"move_id":156},{"level":10,"move_id":129},{"level":15,"move_id":270},{"level":20,"move_id":94},{"level":25,"move_id":287},{"level":30,"move_id":156},{"level":35,"move_id":38},{"level":40,"move_id":248},{"level":45,"move_id":322},{"level":50,"move_id":353}]},"tmhm_learnset":"00408E93B59BC62C","types":[8,14]},{"abilities":[46,0],"address":3308224,"base_stats":[50,150,50,150,150,50],"catch_rate":3,"evolutions":[],"friendship":0,"id":410,"learnset":{"address":3318340,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":43},{"level":1,"move_id":35},{"level":5,"move_id":101},{"level":10,"move_id":104},{"level":15,"move_id":282},{"level":20,"move_id":228},{"level":25,"move_id":94},{"level":30,"move_id":129},{"level":35,"move_id":97},{"level":40,"move_id":105},{"level":45,"move_id":354},{"level":50,"move_id":245}]},"tmhm_learnset":"00E58FC3F5BBDE2D","types":[14,14]},{"abilities":[26,0],"address":3308252,"base_stats":[65,50,70,65,95,80],"catch_rate":45,"evolutions":[],"friendship":70,"id":411,"learnset":{"address":3318370,"moves":[{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":0},{"level":1,"move_id":35},{"level":6,"move_id":45},{"level":9,"move_id":310},{"level":14,"move_id":93},{"level":17,"move_id":36},{"level":22,"move_id":253},{"level":25,"move_id":281},{"level":30,"move_id":149},{"level":33,"move_id":38},{"level":38,"move_id":215},{"level":41,"move_id":219},{"level":46,"move_id":94}]},"tmhm_learnset":"00419F03B41B8E28","types":[14,14]}],"tmhm_moves":[264,337,352,347,46,92,258,339,331,237,241,269,58,59,63,113,182,240,202,219,218,76,231,85,87,89,216,91,94,247,280,104,115,351,53,188,201,126,317,332,259,263,290,156,213,168,211,285,289,315,15,19,57,70,148,249,127,291],"trainers":[{"address":3230072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[],"party_address":4160749568,"script_address":0},{"address":3230112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":74}],"party_address":3211124,"script_address":2304511},{"address":3230152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":286}],"party_address":3211132,"script_address":2321901},{"address":3230192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":330}],"party_address":3211140,"script_address":2323326},{"address":3230232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211156,"script_address":2323373},{"address":3230272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211164,"script_address":2324386},{"address":3230312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":286}],"party_address":3211172,"script_address":2326808},{"address":3230352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211180,"script_address":2326839},{"address":3230392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":41}],"party_address":3211188,"script_address":2328040},{"address":3230432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":315},{"level":26,"species":286},{"level":26,"species":288},{"level":26,"species":295},{"level":26,"species":298},{"level":26,"species":304}],"party_address":3211196,"script_address":2314251},{"address":3230472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":286}],"party_address":3211244,"script_address":0},{"address":3230512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":300}],"party_address":3211252,"script_address":2067580},{"address":3230552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":310},{"level":30,"species":178}],"party_address":3211268,"script_address":2068523},{"address":3230592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":380},{"level":30,"species":379}],"party_address":3211284,"script_address":2068554},{"address":3230632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":330}],"party_address":3211300,"script_address":2328071},{"address":3230672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3211308,"script_address":2069620},{"address":3230712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":286}],"party_address":3211316,"script_address":0},{"address":3230752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3211324,"script_address":2570959},{"address":3230792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":286},{"level":27,"species":330}],"party_address":3211340,"script_address":2572093},{"address":3230832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":286},{"level":26,"species":41},{"level":26,"species":330}],"party_address":3211356,"script_address":2572124},{"address":3230872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":330}],"party_address":3211380,"script_address":2157889},{"address":3230912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":41},{"level":14,"species":330}],"party_address":3211388,"script_address":2157948},{"address":3230952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":339}],"party_address":3211404,"script_address":2254636},{"address":3230992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211412,"script_address":2317522},{"address":3231032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211420,"script_address":2317553},{"address":3231072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":286},{"level":30,"species":330}],"party_address":3211428,"script_address":2317584},{"address":3231112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330}],"party_address":3211444,"script_address":2570990},{"address":3231152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3211452,"script_address":2323414},{"address":3231192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3211460,"script_address":2324427},{"address":3231232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":335},{"level":30,"species":67}],"party_address":3211468,"script_address":2068492},{"address":3231272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":287},{"level":34,"species":42}],"party_address":3211484,"script_address":2324250},{"address":3231312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":336}],"party_address":3211500,"script_address":2312702},{"address":3231352,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":330},{"level":28,"species":287}],"party_address":3211508,"script_address":2572155},{"address":3231392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":331},{"level":37,"species":287}],"party_address":3211524,"script_address":2327156},{"address":3231432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":287},{"level":41,"species":169},{"level":43,"species":331}],"party_address":3211540,"script_address":2328478},{"address":3231472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":351}],"party_address":3211564,"script_address":2312671},{"address":3231512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211572,"script_address":2026085},{"address":3231552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":363},{"level":14,"species":306},{"level":14,"species":363}],"party_address":3211588,"script_address":2058784},{"address":3231592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,0,0,0],"species":357},{"level":43,"moves":[29,89,0,0],"species":319}],"party_address":3211612,"script_address":2335547},{"address":3231632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":363},{"level":26,"species":44}],"party_address":3211644,"script_address":2068148},{"address":3231672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":363}],"party_address":3211660,"script_address":0},{"address":3231712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":306},{"level":28,"species":44},{"level":28,"species":363}],"party_address":3211676,"script_address":0},{"address":3231752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":306},{"level":31,"species":44},{"level":31,"species":363}],"party_address":3211700,"script_address":0},{"address":3231792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307},{"level":34,"species":44},{"level":34,"species":363}],"party_address":3211724,"script_address":0},{"address":3231832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,163,28,40],"species":28}],"party_address":3211748,"script_address":2046490},{"address":3231872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[60,120,201,246],"species":318},{"level":27,"moves":[91,163,28,40],"species":27},{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211764,"script_address":2065682},{"address":3231912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[91,163,28,40],"species":27},{"level":25,"moves":[91,163,28,40],"species":28}],"party_address":3211812,"script_address":2033540},{"address":3231952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[91,163,28,40],"species":28}],"party_address":3211844,"script_address":0},{"address":3231992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[91,163,28,40],"species":28}],"party_address":3211860,"script_address":0},{"address":3232032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[91,163,28,40],"species":28}],"party_address":3211876,"script_address":0},{"address":3232072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[91,163,28,40],"species":28}],"party_address":3211892,"script_address":0},{"address":3232112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":81},{"level":17,"species":370}],"party_address":3211908,"script_address":0},{"address":3232152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":81},{"level":27,"species":371}],"party_address":3211924,"script_address":0},{"address":3232192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":82},{"level":30,"species":371}],"party_address":3211940,"script_address":0},{"address":3232232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":82},{"level":33,"species":371}],"party_address":3211956,"script_address":0},{"address":3232272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82},{"level":36,"species":371}],"party_address":3211972,"script_address":0},{"address":3232312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[49,86,63,85],"species":82},{"level":39,"moves":[54,23,48,48],"species":372}],"party_address":3211988,"script_address":0},{"address":3232352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":350}],"party_address":3212020,"script_address":2036011},{"address":3232392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212036,"script_address":2036121},{"address":3232432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212044,"script_address":2036152},{"address":3232472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183},{"level":26,"species":183}],"party_address":3212052,"script_address":0},{"address":3232512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":183},{"level":29,"species":183}],"party_address":3212068,"script_address":0},{"address":3232552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":183},{"level":32,"species":183}],"party_address":3212084,"script_address":0},{"address":3232592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":35,"species":184}],"party_address":3212100,"script_address":0},{"address":3232632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":13,"moves":[28,29,39,57],"species":288}],"party_address":3212116,"script_address":2035901},{"address":3232672,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":350},{"level":12,"species":183}],"party_address":3212132,"script_address":2544001},{"address":3232712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3212148,"script_address":2339831},{"address":3232752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[28,42,39,57],"species":289}],"party_address":3212156,"script_address":0},{"address":3232792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[28,42,39,57],"species":289}],"party_address":3212172,"script_address":0},{"address":3232832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[28,42,39,57],"species":289}],"party_address":3212188,"script_address":0},{"address":3232872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[28,42,39,57],"species":289}],"party_address":3212204,"script_address":0},{"address":3232912,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[98,97,17,0],"species":305}],"party_address":3212220,"script_address":2131164},{"address":3232952,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[42,146,8,0],"species":308}],"party_address":3212236,"script_address":2131228},{"address":3232992,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[47,68,247,0],"species":364}],"party_address":3212252,"script_address":2131292},{"address":3233032,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[116,163,0,0],"species":365}],"party_address":3212268,"script_address":2131356},{"address":3233072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[116,98,17,27],"species":305},{"level":28,"moves":[44,91,185,72],"species":332},{"level":28,"moves":[205,250,54,96],"species":313},{"level":28,"moves":[85,48,86,49],"species":82},{"level":28,"moves":[202,185,104,207],"species":300}],"party_address":3212284,"script_address":2068117},{"address":3233112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":322},{"level":44,"species":357},{"level":44,"species":331}],"party_address":3212364,"script_address":2565920},{"address":3233152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":355},{"level":46,"species":121}],"party_address":3212388,"script_address":2565982},{"address":3233192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":337},{"level":17,"species":313},{"level":17,"species":335}],"party_address":3212404,"script_address":2046693},{"address":3233232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":345},{"level":43,"species":310}],"party_address":3212428,"script_address":2332685},{"address":3233272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":82},{"level":43,"species":89}],"party_address":3212444,"script_address":2332716},{"address":3233312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":305},{"level":42,"species":355},{"level":42,"species":64}],"party_address":3212460,"script_address":2334375},{"address":3233352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":85},{"level":42,"species":64},{"level":42,"species":101},{"level":42,"species":300}],"party_address":3212484,"script_address":2335423},{"address":3233392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":317},{"level":42,"species":75},{"level":42,"species":314}],"party_address":3212516,"script_address":2335454},{"address":3233432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":337},{"level":26,"species":313},{"level":26,"species":335}],"party_address":3212540,"script_address":0},{"address":3233472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338},{"level":29,"species":313},{"level":29,"species":335}],"party_address":3212564,"script_address":0},{"address":3233512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":338},{"level":32,"species":313},{"level":32,"species":335}],"party_address":3212588,"script_address":0},{"address":3233552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":338},{"level":35,"species":313},{"level":35,"species":336}],"party_address":3212612,"script_address":0},{"address":3233592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":297}],"party_address":3212636,"script_address":2073950},{"address":3233632,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[185,95,0,0],"species":316}],"party_address":3212652,"script_address":2131420},{"address":3233672,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[111,38,247,0],"species":40}],"party_address":3212668,"script_address":2131484},{"address":3233712,"battle_type":2,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":26,"moves":[14,163,0,0],"species":380}],"party_address":3212684,"script_address":2131548},{"address":3233752,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[226,185,57,44],"species":355},{"level":29,"moves":[72,89,64,73],"species":363},{"level":29,"moves":[19,55,54,182],"species":310}],"party_address":3212700,"script_address":2068086},{"address":3233792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":383},{"level":45,"species":338}],"party_address":3212748,"script_address":2565951},{"address":3233832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":309},{"level":17,"species":339},{"level":17,"species":363}],"party_address":3212764,"script_address":2046803},{"address":3233872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":322}],"party_address":3212788,"script_address":2065651},{"address":3233912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3212796,"script_address":2332747},{"address":3233952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":319}],"party_address":3212804,"script_address":2334406},{"address":3233992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":321},{"level":42,"species":357},{"level":42,"species":297}],"party_address":3212812,"script_address":2334437},{"address":3234032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":227},{"level":43,"species":322}],"party_address":3212836,"script_address":2335485},{"address":3234072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":28},{"level":42,"species":38},{"level":42,"species":369}],"party_address":3212852,"script_address":2335516},{"address":3234112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":26,"species":339},{"level":26,"species":363}],"party_address":3212876,"script_address":0},{"address":3234152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":339},{"level":29,"species":363}],"party_address":3212900,"script_address":0},{"address":3234192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":339},{"level":32,"species":363}],"party_address":3212924,"script_address":0},{"address":3234232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":340},{"level":34,"species":363}],"party_address":3212948,"script_address":0},{"address":3234272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":348}],"party_address":3212972,"script_address":2564729},{"address":3234312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":361},{"level":30,"species":377}],"party_address":3212988,"script_address":2068461},{"address":3234352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":361},{"level":29,"species":377}],"party_address":3213004,"script_address":2067284},{"address":3234392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":322}],"party_address":3213020,"script_address":2315745},{"address":3234432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":377}],"party_address":3213028,"script_address":2315532},{"address":3234472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":322},{"level":31,"species":351}],"party_address":3213036,"script_address":0},{"address":3234512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":351},{"level":35,"species":322}],"party_address":3213052,"script_address":0},{"address":3234552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":351},{"level":40,"species":322}],"party_address":3213068,"script_address":0},{"address":3234592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":361},{"level":42,"species":322},{"level":42,"species":352}],"party_address":3213084,"script_address":0},{"address":3234632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213108,"script_address":2030087},{"address":3234672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[213,186,175,96],"species":325},{"level":39,"moves":[213,219,36,96],"species":325}],"party_address":3213116,"script_address":2265894},{"address":3234712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":287},{"level":28,"species":287},{"level":30,"species":339}],"party_address":3213148,"script_address":2254717},{"address":3234752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":11,"moves":[33,39,0,0],"species":288}],"party_address":3213172,"script_address":0},{"address":3234792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":40,"species":119}],"party_address":3213188,"script_address":2265677},{"address":3234832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":363}],"party_address":3213196,"script_address":2361019},{"address":3234872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213204,"script_address":0},{"address":3234912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213212,"script_address":0},{"address":3234952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213220,"script_address":0},{"address":3234992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213228,"script_address":0},{"address":3235032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":183}],"party_address":3213244,"script_address":2304387},{"address":3235072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3213252,"script_address":2304418},{"address":3235112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":339}],"party_address":3213260,"script_address":2304449},{"address":3235152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[20,122,154,185],"species":317},{"level":29,"moves":[86,103,137,242],"species":379}],"party_address":3213268,"script_address":2067377},{"address":3235192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":118}],"party_address":3213300,"script_address":2265708},{"address":3235232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":184}],"party_address":3213308,"script_address":2265739},{"address":3235272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[78,250,240,96],"species":373},{"level":37,"moves":[13,152,96,0],"species":326},{"level":39,"moves":[253,154,252,96],"species":296}],"party_address":3213316,"script_address":2265770},{"address":3235312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":330},{"level":39,"species":331}],"party_address":3213364,"script_address":2265801},{"address":3235352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":35,"moves":[20,122,154,185],"species":317},{"level":35,"moves":[86,103,137,242],"species":379}],"party_address":3213380,"script_address":0},{"address":3235392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[20,122,154,185],"species":317},{"level":38,"moves":[86,103,137,242],"species":379}],"party_address":3213412,"script_address":0},{"address":3235432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[20,122,154,185],"species":317},{"level":41,"moves":[86,103,137,242],"species":379}],"party_address":3213444,"script_address":0},{"address":3235472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[20,122,154,185],"species":317},{"level":44,"moves":[86,103,137,242],"species":379}],"party_address":3213476,"script_address":0},{"address":3235512,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":7,"species":288}],"party_address":3213508,"script_address":2029901},{"address":3235552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":324},{"level":33,"species":356}],"party_address":3213516,"script_address":2074012},{"address":3235592,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":45,"species":184}],"party_address":3213532,"script_address":2360988},{"address":3235632,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":27,"species":289}],"party_address":3213540,"script_address":0},{"address":3235672,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":289}],"party_address":3213548,"script_address":0},{"address":3235712,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":289}],"party_address":3213556,"script_address":0},{"address":3235752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[154,44,60,28],"species":289}],"party_address":3213564,"script_address":0},{"address":3235792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3213580,"script_address":2051965},{"address":3235832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":116}],"party_address":3213588,"script_address":2340108},{"address":3235872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":111}],"party_address":3213604,"script_address":2312578},{"address":3235912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":339}],"party_address":3213612,"script_address":2304480},{"address":3235952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":383}],"party_address":3213620,"script_address":0},{"address":3235992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":383},{"level":29,"species":111}],"party_address":3213628,"script_address":0},{"address":3236032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":383},{"level":32,"species":111}],"party_address":3213644,"script_address":0},{"address":3236072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":384},{"level":35,"species":112}],"party_address":3213660,"script_address":0},{"address":3236112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213676,"script_address":2033571},{"address":3236152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":72}],"party_address":3213684,"script_address":2033602},{"address":3236192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":72}],"party_address":3213692,"script_address":2034185},{"address":3236232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":24,"species":309},{"level":24,"species":72}],"party_address":3213708,"script_address":2034479},{"address":3236272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213732,"script_address":2034510},{"address":3236312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":73}],"party_address":3213740,"script_address":2034776},{"address":3236352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":330}],"party_address":3213748,"script_address":2034807},{"address":3236392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3213756,"script_address":2035777},{"address":3236432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309}],"party_address":3213772,"script_address":2069178},{"address":3236472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3213788,"script_address":2069209},{"address":3236512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":73}],"party_address":3213796,"script_address":2069789},{"address":3236552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":116}],"party_address":3213804,"script_address":2069820},{"address":3236592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213812,"script_address":2070163},{"address":3236632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":31,"species":309},{"level":31,"species":330}],"party_address":3213820,"script_address":2070194},{"address":3236672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213844,"script_address":2073229},{"address":3236712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310}],"party_address":3213852,"script_address":2073359},{"address":3236752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213860,"script_address":2073390},{"address":3236792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":73},{"level":33,"species":313}],"party_address":3213876,"script_address":2073291},{"address":3236832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3213892,"script_address":2073608},{"address":3236872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":342}],"party_address":3213900,"script_address":2073857},{"address":3236912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":341}],"party_address":3213908,"script_address":2073576},{"address":3236952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":130}],"party_address":3213916,"script_address":2074089},{"address":3236992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":309},{"level":33,"species":73}],"party_address":3213924,"script_address":0},{"address":3237032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":72},{"level":33,"species":313}],"party_address":3213948,"script_address":2069381},{"address":3237072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":331}],"party_address":3213964,"script_address":0},{"address":3237112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":331}],"party_address":3213972,"script_address":0},{"address":3237152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120},{"level":36,"species":331}],"party_address":3213980,"script_address":0},{"address":3237192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":121},{"level":39,"species":331}],"party_address":3213996,"script_address":0},{"address":3237232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3214012,"script_address":2095275},{"address":3237272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":66},{"level":32,"species":67}],"party_address":3214020,"script_address":2074213},{"address":3237312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":336}],"party_address":3214036,"script_address":2073701},{"address":3237352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":66},{"level":28,"species":67}],"party_address":3214044,"script_address":2052921},{"address":3237392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214060,"script_address":2052952},{"address":3237432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":67}],"party_address":3214068,"script_address":0},{"address":3237472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":66},{"level":29,"species":67}],"party_address":3214076,"script_address":0},{"address":3237512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":66},{"level":31,"species":67},{"level":31,"species":67}],"party_address":3214092,"script_address":0},{"address":3237552,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":33,"species":66},{"level":33,"species":67},{"level":33,"species":67},{"level":33,"species":68}],"party_address":3214116,"script_address":0},{"address":3237592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":335},{"level":26,"species":67}],"party_address":3214148,"script_address":2557758},{"address":3237632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":66}],"party_address":3214164,"script_address":2046662},{"address":3237672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":336}],"party_address":3214172,"script_address":2315359},{"address":3237712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[98,86,209,43],"species":337},{"level":17,"moves":[12,95,103,0],"species":100}],"party_address":3214180,"script_address":2167608},{"address":3237752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":286},{"level":31,"species":41}],"party_address":3214212,"script_address":2323445},{"address":3237792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":330}],"party_address":3214228,"script_address":2324458},{"address":3237832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":100},{"level":17,"species":81}],"party_address":3214236,"script_address":2167639},{"address":3237872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":337},{"level":30,"species":371}],"party_address":3214252,"script_address":2068709},{"address":3237912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81},{"level":15,"species":370}],"party_address":3214268,"script_address":2058956},{"address":3237952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":81},{"level":25,"species":370},{"level":25,"species":81}],"party_address":3214284,"script_address":0},{"address":3237992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81},{"level":28,"species":371},{"level":28,"species":81}],"party_address":3214308,"script_address":0},{"address":3238032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":82},{"level":31,"species":371},{"level":31,"species":82}],"party_address":3214332,"script_address":0},{"address":3238072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82},{"level":34,"species":372},{"level":34,"species":82}],"party_address":3214356,"script_address":0},{"address":3238112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214380,"script_address":2103394},{"address":3238152,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":218},{"level":22,"species":218}],"party_address":3214388,"script_address":2103601},{"address":3238192,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3214404,"script_address":2103446},{"address":3238232,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214412,"script_address":2103570},{"address":3238272,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":218}],"party_address":3214420,"script_address":2103477},{"address":3238312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309}],"party_address":3214428,"script_address":2052075},{"address":3238352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":218},{"level":26,"species":309}],"party_address":3214444,"script_address":0},{"address":3238392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310}],"party_address":3214460,"script_address":0},{"address":3238432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":218},{"level":32,"species":310}],"party_address":3214476,"script_address":0},{"address":3238472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":219},{"level":35,"species":310}],"party_address":3214492,"script_address":0},{"address":3238512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[91,28,40,163],"species":27}],"party_address":3214508,"script_address":2046366},{"address":3238552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":21,"moves":[229,189,60,61],"species":318},{"level":21,"moves":[40,28,10,91],"species":27},{"level":21,"moves":[229,189,60,61],"species":318}],"party_address":3214524,"script_address":2046428},{"address":3238592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":299}],"party_address":3214572,"script_address":2049829},{"address":3238632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27},{"level":18,"species":299}],"party_address":3214580,"script_address":2051903},{"address":3238672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":317}],"party_address":3214596,"script_address":2557005},{"address":3238712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":288},{"level":20,"species":304}],"party_address":3214604,"script_address":2310199},{"address":3238752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":306}],"party_address":3214620,"script_address":2310337},{"address":3238792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":27}],"party_address":3214628,"script_address":2046600},{"address":3238832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":288},{"level":26,"species":304}],"party_address":3214636,"script_address":0},{"address":3238872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":289},{"level":29,"species":305}],"party_address":3214652,"script_address":0},{"address":3238912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":305},{"level":31,"species":289}],"party_address":3214668,"script_address":0},{"address":3238952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":28},{"level":34,"species":289}],"party_address":3214692,"script_address":0},{"address":3238992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":311}],"party_address":3214716,"script_address":2061044},{"address":3239032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":290},{"level":24,"species":291},{"level":24,"species":292}],"party_address":3214724,"script_address":2061075},{"address":3239072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":290},{"level":27,"species":293},{"level":27,"species":294}],"party_address":3214748,"script_address":2061106},{"address":3239112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":311},{"level":27,"species":311},{"level":27,"species":311}],"party_address":3214772,"script_address":2065541},{"address":3239152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":294},{"level":16,"species":292}],"party_address":3214796,"script_address":2057595},{"address":3239192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":311},{"level":31,"species":311}],"party_address":3214812,"script_address":0},{"address":3239232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":311},{"level":34,"species":311},{"level":34,"species":312}],"party_address":3214836,"script_address":0},{"address":3239272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":311},{"level":36,"species":290},{"level":36,"species":311},{"level":36,"species":312}],"party_address":3214860,"script_address":0},{"address":3239312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":311},{"level":38,"species":294},{"level":38,"species":311},{"level":38,"species":312},{"level":38,"species":292}],"party_address":3214892,"script_address":0},{"address":3239352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[237,0,0,0],"species":63}],"party_address":3214932,"script_address":2038374},{"address":3239392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3214948,"script_address":2244488},{"address":3239432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":392}],"party_address":3214956,"script_address":2244519},{"address":3239472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3214964,"script_address":2244550},{"address":3239512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":392},{"level":26,"species":393}],"party_address":3214972,"script_address":2314189},{"address":3239552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3214996,"script_address":2564698},{"address":3239592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":349}],"party_address":3215012,"script_address":2068179},{"address":3239632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":64},{"level":33,"species":349}],"party_address":3215020,"script_address":0},{"address":3239672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":64},{"level":38,"species":349}],"party_address":3215036,"script_address":0},{"address":3239712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":64},{"level":41,"species":349}],"party_address":3215052,"script_address":0},{"address":3239752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":349},{"level":45,"species":65}],"party_address":3215068,"script_address":0},{"address":3239792,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[237,0,0,0],"species":63}],"party_address":3215084,"script_address":2038405},{"address":3239832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":393}],"party_address":3215100,"script_address":2244581},{"address":3239872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":178}],"party_address":3215108,"script_address":2244612},{"address":3239912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3215116,"script_address":2244643},{"address":3239952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":202},{"level":26,"species":177},{"level":26,"species":64}],"party_address":3215124,"script_address":2314220},{"address":3239992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":393},{"level":41,"species":178}],"party_address":3215148,"script_address":2564760},{"address":3240032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":64},{"level":30,"species":348}],"party_address":3215164,"script_address":2068289},{"address":3240072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":64},{"level":34,"species":348}],"party_address":3215180,"script_address":0},{"address":3240112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":64},{"level":37,"species":348}],"party_address":3215196,"script_address":0},{"address":3240152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":64},{"level":40,"species":348}],"party_address":3215212,"script_address":0},{"address":3240192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":348},{"level":43,"species":65}],"party_address":3215228,"script_address":0},{"address":3240232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":338}],"party_address":3215244,"script_address":2067174},{"address":3240272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":338},{"level":44,"species":338}],"party_address":3215252,"script_address":2360864},{"address":3240312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":380}],"party_address":3215268,"script_address":2360895},{"address":3240352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":338}],"party_address":3215276,"script_address":0},{"address":3240392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[29,28,60,154],"species":289},{"level":36,"moves":[98,209,60,46],"species":338}],"party_address":3215284,"script_address":0},{"address":3240432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[29,28,60,154],"species":289},{"level":39,"moves":[98,209,60,0],"species":338}],"party_address":3215316,"script_address":0},{"address":3240472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[29,28,60,154],"species":289},{"level":41,"moves":[154,50,93,244],"species":55},{"level":41,"moves":[98,209,60,46],"species":338}],"party_address":3215348,"script_address":0},{"address":3240512,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,38,28,242],"species":287},{"level":48,"moves":[3,104,207,70],"species":300},{"level":46,"moves":[73,185,46,178],"species":345},{"level":48,"moves":[57,14,70,7],"species":327},{"level":49,"moves":[76,157,14,163],"species":376}],"party_address":3215396,"script_address":2274753},{"address":3240552,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[69,109,174,182],"species":362},{"level":49,"moves":[247,32,5,185],"species":378},{"level":50,"moves":[247,104,101,185],"species":322},{"level":49,"moves":[247,94,85,7],"species":378},{"level":51,"moves":[247,58,157,89],"species":362}],"party_address":3215476,"script_address":2275380},{"address":3240592,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[227,34,2,45],"species":342},{"level":50,"moves":[113,242,196,58],"species":347},{"level":52,"moves":[213,38,2,59],"species":342},{"level":52,"moves":[247,153,2,58],"species":347},{"level":53,"moves":[57,34,58,73],"species":343}],"party_address":3215556,"script_address":2276062},{"address":3240632,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[61,81,182,38],"species":396},{"level":54,"moves":[38,225,93,76],"species":359},{"level":53,"moves":[108,93,57,34],"species":230},{"level":53,"moves":[53,242,225,89],"species":334},{"level":55,"moves":[53,81,157,242],"species":397}],"party_address":3215636,"script_address":2276724},{"address":3240672,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":12,"moves":[33,111,88,61],"species":74},{"level":12,"moves":[33,111,88,61],"species":74},{"level":15,"moves":[79,106,33,61],"species":320}],"party_address":3215716,"script_address":2187976},{"address":3240712,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":16,"moves":[2,67,69,83],"species":66},{"level":16,"moves":[8,113,115,83],"species":356},{"level":19,"moves":[36,233,179,83],"species":335}],"party_address":3215764,"script_address":2095066},{"address":3240752,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":20,"moves":[205,209,120,95],"species":100},{"level":20,"moves":[95,43,98,80],"species":337},{"level":22,"moves":[48,95,86,49],"species":82},{"level":24,"moves":[98,86,95,80],"species":338}],"party_address":3215812,"script_address":2167181},{"address":3240792,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[59,36,222,241],"species":339},{"level":24,"moves":[59,123,113,241],"species":218},{"level":26,"moves":[59,33,241,213],"species":340},{"level":29,"moves":[59,241,34,213],"species":321}],"party_address":3215876,"script_address":2103186},{"address":3240832,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[42,60,7,227],"species":308},{"level":27,"moves":[163,7,227,185],"species":365},{"level":29,"moves":[163,187,7,29],"species":289},{"level":31,"moves":[68,25,7,185],"species":366}],"party_address":3215940,"script_address":2129756},{"address":3240872,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[195,119,219,76],"species":358},{"level":29,"moves":[241,76,76,235],"species":369},{"level":30,"moves":[55,48,182,76],"species":310},{"level":31,"moves":[28,31,211,76],"species":227},{"level":33,"moves":[89,225,93,76],"species":359}],"party_address":3216004,"script_address":2202062},{"address":3240912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[89,246,94,113],"species":319},{"level":41,"moves":[94,241,109,91],"species":178},{"level":42,"moves":[113,94,95,91],"species":348},{"level":42,"moves":[241,76,94,53],"species":349}],"party_address":3216084,"script_address":0},{"address":3240952,"battle_type":1,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[96,213,186,175],"species":325},{"level":41,"moves":[240,96,133,89],"species":324},{"level":43,"moves":[227,34,62,96],"species":342},{"level":43,"moves":[96,152,13,43],"species":327},{"level":46,"moves":[96,104,58,156],"species":230}],"party_address":3216148,"script_address":2262245},{"address":3240992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":392}],"party_address":3216228,"script_address":2054242},{"address":3241032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3216236,"script_address":2554598},{"address":3241072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":339},{"level":15,"species":43},{"level":15,"species":309}],"party_address":3216244,"script_address":2554629},{"address":3241112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":392},{"level":26,"species":356}],"party_address":3216268,"script_address":0},{"address":3241152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":393},{"level":29,"species":356}],"party_address":3216284,"script_address":0},{"address":3241192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":393},{"level":32,"species":357}],"party_address":3216300,"script_address":0},{"address":3241232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":393},{"level":34,"species":378},{"level":34,"species":357}],"party_address":3216316,"script_address":0},{"address":3241272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":306}],"party_address":3216340,"script_address":2054490},{"address":3241312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":306},{"level":16,"species":292}],"party_address":3216348,"script_address":2554660},{"address":3241352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":306},{"level":26,"species":370}],"party_address":3216364,"script_address":0},{"address":3241392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":306},{"level":29,"species":371}],"party_address":3216380,"script_address":0},{"address":3241432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":307},{"level":32,"species":371}],"party_address":3216396,"script_address":0},{"address":3241472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":307},{"level":35,"species":372}],"party_address":3216412,"script_address":0},{"address":3241512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[95,60,146,42],"species":308},{"level":32,"moves":[8,25,47,185],"species":366}],"party_address":3216428,"script_address":0},{"address":3241552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":15,"moves":[45,39,29,60],"species":288},{"level":17,"moves":[33,116,36,0],"species":335}],"party_address":3216460,"script_address":0},{"address":3241592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[45,39,29,60],"species":288},{"level":30,"moves":[33,116,36,0],"species":335}],"party_address":3216492,"script_address":0},{"address":3241632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[45,39,29,60],"species":288},{"level":33,"moves":[33,116,36,0],"species":335}],"party_address":3216524,"script_address":0},{"address":3241672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[45,39,29,60],"species":289},{"level":36,"moves":[33,116,36,0],"species":335}],"party_address":3216556,"script_address":0},{"address":3241712,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[45,39,29,60],"species":289},{"level":38,"moves":[33,116,36,0],"species":336}],"party_address":3216588,"script_address":0},{"address":3241752,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":16,"species":304},{"level":16,"species":288}],"party_address":3216620,"script_address":2045785},{"address":3241792,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":15,"species":315}],"party_address":3216636,"script_address":2026353},{"address":3241832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[18,204,185,215],"species":315},{"level":36,"moves":[18,204,185,215],"species":315},{"level":40,"moves":[18,204,185,215],"species":315},{"level":12,"moves":[18,204,185,215],"species":315},{"level":30,"moves":[18,204,185,215],"species":315},{"level":42,"moves":[18,204,185,215],"species":316}],"party_address":3216644,"script_address":2360833},{"address":3241872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":315}],"party_address":3216740,"script_address":0},{"address":3241912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":315}],"party_address":3216748,"script_address":0},{"address":3241952,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316}],"party_address":3216756,"script_address":0},{"address":3241992,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":38,"species":316}],"party_address":3216764,"script_address":0},{"address":3242032,"battle_type":3,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":17,"species":363}],"party_address":3216772,"script_address":2045890},{"address":3242072,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":30,"species":25}],"party_address":3216780,"script_address":2067143},{"address":3242112,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":350},{"level":37,"species":183},{"level":39,"species":184}],"party_address":3216788,"script_address":2265832},{"address":3242152,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":353},{"level":14,"species":354}],"party_address":3216812,"script_address":2038890},{"address":3242192,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":26,"species":353},{"level":26,"species":354}],"party_address":3216828,"script_address":0},{"address":3242232,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":29,"species":353},{"level":29,"species":354}],"party_address":3216844,"script_address":0},{"address":3242272,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":32,"species":353},{"level":32,"species":354}],"party_address":3216860,"script_address":0},{"address":3242312,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":35,"species":353},{"level":35,"species":354}],"party_address":3216876,"script_address":0},{"address":3242352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":336}],"party_address":3216892,"script_address":2052811},{"address":3242392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[36,26,28,91],"species":336}],"party_address":3216900,"script_address":0},{"address":3242432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[36,26,28,91],"species":336}],"party_address":3216916,"script_address":0},{"address":3242472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[36,187,28,91],"species":336}],"party_address":3216932,"script_address":0},{"address":3242512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[36,187,28,91],"species":336}],"party_address":3216948,"script_address":0},{"address":3242552,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[136,96,93,197],"species":356}],"party_address":3216964,"script_address":2046100},{"address":3242592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":356},{"level":21,"species":335}],"party_address":3216980,"script_address":2304277},{"address":3242632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":356},{"level":30,"species":335}],"party_address":3216996,"script_address":0},{"address":3242672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":357},{"level":33,"species":336}],"party_address":3217012,"script_address":0},{"address":3242712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":357},{"level":36,"species":336}],"party_address":3217028,"script_address":0},{"address":3242752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":357},{"level":39,"species":336}],"party_address":3217044,"script_address":0},{"address":3242792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":286}],"party_address":3217060,"script_address":2024678},{"address":3242832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":288},{"level":7,"species":298}],"party_address":3217068,"script_address":2029684},{"address":3242872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[33,0,0,0],"species":74}],"party_address":3217084,"script_address":2188154},{"address":3242912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3217100,"script_address":2188185},{"address":3242952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":66}],"party_address":3217116,"script_address":2054180},{"address":3242992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[29,28,45,85],"species":288},{"level":17,"moves":[133,124,25,1],"species":367}],"party_address":3217124,"script_address":2167670},{"address":3243032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[213,58,85,53],"species":366},{"level":43,"moves":[29,182,5,92],"species":362}],"party_address":3217156,"script_address":2332778},{"address":3243072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,94,85,91],"species":394},{"level":43,"moves":[89,247,76,24],"species":366}],"party_address":3217188,"script_address":2332809},{"address":3243112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":332}],"party_address":3217220,"script_address":2050594},{"address":3243152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":382}],"party_address":3217228,"script_address":2050625},{"address":3243192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":287}],"party_address":3217236,"script_address":0},{"address":3243232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":305},{"level":30,"species":287}],"party_address":3217244,"script_address":0},{"address":3243272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":305},{"level":29,"species":289},{"level":33,"species":287}],"party_address":3217260,"script_address":0},{"address":3243312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":32,"species":289},{"level":36,"species":287}],"party_address":3217284,"script_address":0},{"address":3243352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":16,"species":288}],"party_address":3217308,"script_address":2553792},{"address":3243392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":3,"species":304}],"party_address":3217324,"script_address":2024926},{"address":3243432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":382},{"level":13,"species":337}],"party_address":3217340,"script_address":2039000},{"address":3243472,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[240,67,38,59],"species":314},{"level":55,"moves":[92,56,188,58],"species":73},{"level":56,"moves":[202,57,73,104],"species":297},{"level":56,"moves":[89,57,133,63],"species":324},{"level":56,"moves":[93,89,63,57],"species":130},{"level":58,"moves":[105,57,58,92],"species":329}],"party_address":3217356,"script_address":2277575},{"address":3243512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":10,"species":72},{"level":15,"species":129}],"party_address":3217452,"script_address":2026322},{"address":3243552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":129},{"level":6,"species":129},{"level":7,"species":129}],"party_address":3217476,"script_address":2029653},{"address":3243592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":129},{"level":17,"species":118},{"level":18,"species":323}],"party_address":3217500,"script_address":2052185},{"address":3243632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":10,"species":129},{"level":7,"species":72},{"level":10,"species":129}],"party_address":3217524,"script_address":2034247},{"address":3243672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72}],"party_address":3217548,"script_address":2034357},{"address":3243712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":72},{"level":14,"species":313},{"level":11,"species":72},{"level":14,"species":313}],"party_address":3217556,"script_address":2038546},{"address":3243752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3217588,"script_address":2052216},{"address":3243792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":72},{"level":25,"species":330}],"party_address":3217596,"script_address":2058894},{"address":3243832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":72}],"party_address":3217612,"script_address":2058925},{"address":3243872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":313},{"level":25,"species":73}],"party_address":3217620,"script_address":2036183},{"address":3243912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":72},{"level":27,"species":130},{"level":27,"species":130}],"party_address":3217636,"script_address":0},{"address":3243952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":130},{"level":26,"species":330},{"level":26,"species":72},{"level":29,"species":130}],"party_address":3217660,"script_address":0},{"address":3243992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":130},{"level":30,"species":330},{"level":30,"species":73},{"level":31,"species":130}],"party_address":3217692,"script_address":0},{"address":3244032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":130},{"level":33,"species":331},{"level":33,"species":130},{"level":35,"species":73}],"party_address":3217724,"script_address":0},{"address":3244072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":129},{"level":21,"species":130},{"level":23,"species":130},{"level":26,"species":130},{"level":30,"species":130},{"level":35,"species":130}],"party_address":3217756,"script_address":2073670},{"address":3244112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":100},{"level":6,"species":100},{"level":14,"species":81}],"party_address":3217804,"script_address":2038577},{"address":3244152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81}],"party_address":3217828,"script_address":2038608},{"address":3244192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217844,"script_address":2038639},{"address":3244232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":81}],"party_address":3217852,"script_address":0},{"address":3244272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":81}],"party_address":3217860,"script_address":0},{"address":3244312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":82}],"party_address":3217868,"script_address":0},{"address":3244352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":82}],"party_address":3217876,"script_address":0},{"address":3244392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":81}],"party_address":3217884,"script_address":2038780},{"address":3244432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":81},{"level":14,"species":81},{"level":6,"species":100}],"party_address":3217892,"script_address":2038749},{"address":3244472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":81}],"party_address":3217916,"script_address":0},{"address":3244512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":81}],"party_address":3217924,"script_address":0},{"address":3244552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":82}],"party_address":3217932,"script_address":0},{"address":3244592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":82}],"party_address":3217940,"script_address":0},{"address":3244632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217948,"script_address":2057375},{"address":3244672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217956,"script_address":0},{"address":3244712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3217964,"script_address":0},{"address":3244752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3217972,"script_address":0},{"address":3244792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3217980,"script_address":0},{"address":3244832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3217988,"script_address":2057485},{"address":3244872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":84}],"party_address":3217996,"script_address":0},{"address":3244912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":84}],"party_address":3218004,"script_address":0},{"address":3244952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":85}],"party_address":3218012,"script_address":0},{"address":3244992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":85}],"party_address":3218020,"script_address":0},{"address":3245032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218028,"script_address":2070582},{"address":3245072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":288},{"level":25,"species":337}],"party_address":3218044,"script_address":2340077},{"address":3245112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218060,"script_address":2071332},{"address":3245152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":120},{"level":33,"species":120}],"party_address":3218068,"script_address":2070380},{"address":3245192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218084,"script_address":2072978},{"address":3245232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218100,"script_address":0},{"address":3245272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218108,"script_address":0},{"address":3245312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218116,"script_address":0},{"address":3245352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218124,"script_address":0},{"address":3245392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218132,"script_address":2070318},{"address":3245432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309},{"level":34,"species":120}],"party_address":3218140,"script_address":2070613},{"address":3245472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3218156,"script_address":2073545},{"address":3245512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":120}],"party_address":3218164,"script_address":2071442},{"address":3245552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":309},{"level":33,"species":120}],"party_address":3218172,"script_address":2073009},{"address":3245592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":120}],"party_address":3218188,"script_address":0},{"address":3245632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":120}],"party_address":3218196,"script_address":0},{"address":3245672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":121}],"party_address":3218204,"script_address":0},{"address":3245712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":121}],"party_address":3218212,"script_address":0},{"address":3245752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":359},{"level":37,"species":359}],"party_address":3218220,"script_address":2292701},{"address":3245792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":359}],"party_address":3218236,"script_address":0},{"address":3245832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":359},{"level":44,"species":359}],"party_address":3218252,"script_address":0},{"address":3245872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":46,"species":395},{"level":46,"species":359},{"level":46,"species":359}],"party_address":3218268,"script_address":0},{"address":3245912,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":49,"species":359},{"level":49,"species":359},{"level":49,"species":396}],"party_address":3218292,"script_address":0},{"address":3245952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[225,29,116,52],"species":395}],"party_address":3218316,"script_address":2074182},{"address":3245992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":309}],"party_address":3218332,"script_address":2059066},{"address":3246032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":369}],"party_address":3218340,"script_address":2061450},{"address":3246072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":305}],"party_address":3218356,"script_address":2061481},{"address":3246112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":84},{"level":27,"species":227},{"level":27,"species":369}],"party_address":3218364,"script_address":2202267},{"address":3246152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":227}],"party_address":3218388,"script_address":2202391},{"address":3246192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":369},{"level":33,"species":178}],"party_address":3218396,"script_address":2070085},{"address":3246232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":84},{"level":29,"species":310}],"party_address":3218412,"script_address":2202298},{"address":3246272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":309},{"level":28,"species":177}],"party_address":3218428,"script_address":2065338},{"address":3246312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":358}],"party_address":3218444,"script_address":2065369},{"address":3246352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":305},{"level":36,"species":310},{"level":36,"species":178}],"party_address":3218452,"script_address":2563257},{"address":3246392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":305}],"party_address":3218476,"script_address":2059097},{"address":3246432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":177},{"level":32,"species":358}],"party_address":3218492,"script_address":0},{"address":3246472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":177},{"level":35,"species":359}],"party_address":3218508,"script_address":0},{"address":3246512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":177},{"level":38,"species":359}],"party_address":3218524,"script_address":0},{"address":3246552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":359},{"level":41,"species":178}],"party_address":3218540,"script_address":0},{"address":3246592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":177},{"level":33,"species":305}],"party_address":3218556,"script_address":2074151},{"address":3246632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":369}],"party_address":3218572,"script_address":2073981},{"address":3246672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302}],"party_address":3218580,"script_address":2061512},{"address":3246712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302},{"level":25,"species":109}],"party_address":3218588,"script_address":2061543},{"address":3246752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[29,89,0,0],"species":319},{"level":43,"moves":[85,89,0,0],"species":171}],"party_address":3218604,"script_address":2335578},{"address":3246792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3218636,"script_address":2341860},{"address":3246832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,123,120],"species":109},{"level":17,"moves":[139,33,124,120],"species":109}],"party_address":3218644,"script_address":2050766},{"address":3246872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":109},{"level":18,"species":302}],"party_address":3218692,"script_address":2050876},{"address":3246912,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":24,"moves":[139,33,124,120],"species":109},{"level":24,"moves":[139,33,124,0],"species":109},{"level":24,"moves":[139,33,124,120],"species":109},{"level":26,"moves":[33,124,0,0],"species":109}],"party_address":3218708,"script_address":0},{"address":3246952,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,120],"species":109},{"level":27,"moves":[139,33,124,0],"species":109},{"level":29,"moves":[33,124,0,0],"species":109}],"party_address":3218772,"script_address":0},{"address":3246992,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":30,"moves":[139,33,124,0],"species":109},{"level":32,"moves":[33,124,0,0],"species":109}],"party_address":3218836,"script_address":0},{"address":3247032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[139,33,124,0],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":33,"moves":[139,33,124,120],"species":109},{"level":35,"moves":[33,124,0,0],"species":110}],"party_address":3218900,"script_address":0},{"address":3247072,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218964,"script_address":2095313},{"address":3247112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3218972,"script_address":2095351},{"address":3247152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":335}],"party_address":3218980,"script_address":2053062},{"address":3247192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":356}],"party_address":3218996,"script_address":2557727},{"address":3247232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3219004,"script_address":2557789},{"address":3247272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3219012,"script_address":0},{"address":3247312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":356},{"level":29,"species":335}],"party_address":3219028,"script_address":0},{"address":3247352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":357},{"level":32,"species":336}],"party_address":3219044,"script_address":0},{"address":3247392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":357},{"level":35,"species":336}],"party_address":3219060,"script_address":0},{"address":3247432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":19,"moves":[52,33,222,241],"species":339}],"party_address":3219076,"script_address":2050656},{"address":3247472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":363},{"level":28,"species":313}],"party_address":3219092,"script_address":2065713},{"address":3247512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[240,55,87,96],"species":385}],"party_address":3219108,"script_address":2065744},{"address":3247552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":29,"moves":[52,33,222,241],"species":339}],"party_address":3219124,"script_address":0},{"address":3247592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[52,36,222,241],"species":339}],"party_address":3219140,"script_address":0},{"address":3247632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[73,72,64,241],"species":363},{"level":34,"moves":[53,36,222,241],"species":339}],"party_address":3219156,"script_address":0},{"address":3247672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[73,202,76,241],"species":363},{"level":37,"moves":[53,36,89,241],"species":340}],"party_address":3219188,"script_address":0},{"address":3247712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":313}],"party_address":3219220,"script_address":2033633},{"address":3247752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":183}],"party_address":3219236,"script_address":2033664},{"address":3247792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":313}],"party_address":3219244,"script_address":2034216},{"address":3247832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":309},{"level":25,"species":118}],"party_address":3219252,"script_address":2034620},{"address":3247872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219268,"script_address":2034651},{"address":3247912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":116},{"level":25,"species":183}],"party_address":3219276,"script_address":2034838},{"address":3247952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3219292,"script_address":2034869},{"address":3247992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":118},{"level":24,"species":309},{"level":24,"species":118}],"party_address":3219300,"script_address":2035808},{"address":3248032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3219324,"script_address":2069240},{"address":3248072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":183}],"party_address":3219332,"script_address":2069350},{"address":3248112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219340,"script_address":2069851},{"address":3248152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219348,"script_address":2069882},{"address":3248192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":183},{"level":33,"species":341}],"party_address":3219356,"script_address":2070225},{"address":3248232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":118}],"party_address":3219372,"script_address":2070256},{"address":3248272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":118},{"level":33,"species":341}],"party_address":3219380,"script_address":2073260},{"address":3248312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":325}],"party_address":3219396,"script_address":2073421},{"address":3248352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219404,"script_address":2073452},{"address":3248392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":184}],"party_address":3219412,"script_address":2073639},{"address":3248432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219420,"script_address":2070349},{"address":3248472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":119}],"party_address":3219436,"script_address":2073888},{"address":3248512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":116},{"level":33,"species":117}],"party_address":3219444,"script_address":2073919},{"address":3248552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":171},{"level":34,"species":310}],"party_address":3219460,"script_address":0},{"address":3248592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":325},{"level":33,"species":325}],"party_address":3219476,"script_address":2074120},{"address":3248632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":119}],"party_address":3219492,"script_address":2071676},{"address":3248672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":313}],"party_address":3219500,"script_address":0},{"address":3248712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":313}],"party_address":3219508,"script_address":0},{"address":3248752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":120},{"level":43,"species":313}],"party_address":3219516,"script_address":0},{"address":3248792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":313},{"level":45,"species":121}],"party_address":3219532,"script_address":0},{"address":3248832,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[91,28,40,163],"species":27},{"level":22,"moves":[229,189,60,61],"species":318}],"party_address":3219556,"script_address":2046397},{"address":3248872,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":22,"moves":[28,40,163,91],"species":27},{"level":22,"moves":[205,61,39,111],"species":183}],"party_address":3219588,"script_address":2046459},{"address":3248912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":304},{"level":17,"species":296}],"party_address":3219620,"script_address":2049860},{"address":3248952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":183},{"level":18,"species":296}],"party_address":3219636,"script_address":2051934},{"address":3248992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":315},{"level":23,"species":358}],"party_address":3219652,"script_address":2557036},{"address":3249032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":306},{"level":19,"species":43},{"level":19,"species":358}],"party_address":3219668,"script_address":2310092},{"address":3249072,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[194,219,68,243],"species":202}],"party_address":3219692,"script_address":2315855},{"address":3249112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":306},{"level":17,"species":183}],"party_address":3219708,"script_address":2046631},{"address":3249152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":306},{"level":25,"species":44},{"level":25,"species":358}],"party_address":3219724,"script_address":0},{"address":3249192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":307},{"level":28,"species":44},{"level":28,"species":358}],"party_address":3219748,"script_address":0},{"address":3249232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307},{"level":31,"species":44},{"level":31,"species":358}],"party_address":3219772,"script_address":0},{"address":3249272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":307},{"level":40,"species":45},{"level":40,"species":359}],"party_address":3219796,"script_address":0},{"address":3249312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":353},{"level":15,"species":354}],"party_address":3219820,"script_address":0},{"address":3249352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":353},{"level":27,"species":354}],"party_address":3219836,"script_address":0},{"address":3249392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":298},{"level":6,"species":295}],"party_address":3219852,"script_address":0},{"address":3249432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":292},{"level":26,"species":294}],"party_address":3219868,"script_address":0},{"address":3249472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":353},{"level":9,"species":354}],"party_address":3219884,"script_address":0},{"address":3249512,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[101,50,0,0],"species":361},{"level":10,"moves":[71,73,0,0],"species":306}],"party_address":3219900,"script_address":0},{"address":3249552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":353},{"level":30,"species":354}],"party_address":3219932,"script_address":0},{"address":3249592,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[209,12,57,14],"species":353},{"level":33,"moves":[209,12,204,14],"species":354}],"party_address":3219948,"script_address":0},{"address":3249632,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,12,57,14],"species":353},{"level":36,"moves":[87,12,204,14],"species":354}],"party_address":3219980,"script_address":0},{"address":3249672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":309},{"level":12,"species":66}],"party_address":3220012,"script_address":2035839},{"address":3249712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309}],"party_address":3220028,"script_address":2035870},{"address":3249752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":309},{"level":33,"species":67}],"party_address":3220036,"script_address":2069913},{"address":3249792,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":66},{"level":11,"species":72}],"party_address":3220052,"script_address":2543939},{"address":3249832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":44,"species":73},{"level":44,"species":67}],"party_address":3220076,"script_address":2360255},{"address":3249872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":66},{"level":43,"species":310},{"level":43,"species":67}],"party_address":3220092,"script_address":2360286},{"address":3249912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":341},{"level":25,"species":67}],"party_address":3220116,"script_address":2340984},{"address":3249952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":309},{"level":36,"species":72},{"level":36,"species":67}],"party_address":3220132,"script_address":0},{"address":3249992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":310},{"level":39,"species":72},{"level":39,"species":67}],"party_address":3220156,"script_address":0},{"address":3250032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":310},{"level":42,"species":72},{"level":42,"species":67}],"party_address":3220180,"script_address":0},{"address":3250072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":310},{"level":45,"species":67},{"level":45,"species":73}],"party_address":3220204,"script_address":0},{"address":3250112,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":23,"species":339}],"party_address":3220228,"script_address":2103632},{"address":3250152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[175,96,216,213],"species":328},{"level":39,"moves":[175,96,216,213],"species":328}],"party_address":3220236,"script_address":2265863},{"address":3250192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":376}],"party_address":3220268,"script_address":2068647},{"address":3250232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[92,87,120,188],"species":109}],"party_address":3220276,"script_address":2068616},{"address":3250272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":31,"moves":[241,55,53,76],"species":385}],"party_address":3220292,"script_address":2068585},{"address":3250312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":338},{"level":33,"species":68}],"party_address":3220308,"script_address":2070116},{"address":3250352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":341}],"party_address":3220324,"script_address":2074337},{"address":3250392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":34,"moves":[44,46,86,85],"species":338}],"party_address":3220340,"script_address":2074306},{"address":3250432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":356},{"level":33,"species":336}],"party_address":3220356,"script_address":2074275},{"address":3250472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313}],"party_address":3220372,"script_address":2074244},{"address":3250512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":170},{"level":33,"species":336}],"party_address":3220380,"script_address":2074043},{"address":3250552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":296},{"level":14,"species":299}],"party_address":3220396,"script_address":2038436},{"address":3250592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":380},{"level":18,"species":379}],"party_address":3220412,"script_address":2053172},{"address":3250632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":340},{"level":38,"species":287},{"level":40,"species":42}],"party_address":3220428,"script_address":0},{"address":3250672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":299}],"party_address":3220452,"script_address":0},{"address":3250712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":299}],"party_address":3220468,"script_address":0},{"address":3250752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":299}],"party_address":3220484,"script_address":0},{"address":3250792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":297},{"level":35,"species":300}],"party_address":3220500,"script_address":0},{"address":3250832,"battle_type":3,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[76,219,225,93],"species":359},{"level":43,"moves":[47,18,204,185],"species":316},{"level":44,"moves":[89,73,202,92],"species":363},{"level":41,"moves":[48,85,161,103],"species":82},{"level":45,"moves":[104,91,94,248],"species":394}],"party_address":3220516,"script_address":2332529},{"address":3250872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220596,"script_address":2025759},{"address":3250912,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":218},{"level":18,"species":309},{"level":20,"species":278}],"party_address":3220604,"script_address":2039798},{"address":3250952,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":310},{"level":31,"species":278}],"party_address":3220628,"script_address":2060578},{"address":3250992,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220652,"script_address":2025703},{"address":3251032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220660,"script_address":2039742},{"address":3251072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220684,"script_address":2060522},{"address":3251112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220708,"script_address":2025731},{"address":3251152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220716,"script_address":2039770},{"address":3251192,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220740,"script_address":2060550},{"address":3251232,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":277}],"party_address":3220764,"script_address":2025675},{"address":3251272,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":218},{"level":20,"species":278}],"party_address":3220772,"script_address":2039622},{"address":3251312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":218},{"level":29,"species":296},{"level":31,"species":278}],"party_address":3220796,"script_address":2060420},{"address":3251352,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":280}],"party_address":3220820,"script_address":2025619},{"address":3251392,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":309},{"level":18,"species":296},{"level":20,"species":281}],"party_address":3220828,"script_address":2039566},{"address":3251432,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":310},{"level":29,"species":296},{"level":31,"species":281}],"party_address":3220852,"script_address":2060364},{"address":3251472,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":283}],"party_address":3220876,"script_address":2025647},{"address":3251512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":218},{"level":20,"species":284}],"party_address":3220884,"script_address":2039594},{"address":3251552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":218},{"level":31,"species":284}],"party_address":3220908,"script_address":2060392},{"address":3251592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":370},{"level":11,"species":288},{"level":11,"species":382},{"level":11,"species":286},{"level":11,"species":304},{"level":11,"species":335}],"party_address":3220932,"script_address":2057155},{"address":3251632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":127}],"party_address":3220980,"script_address":2068678},{"address":3251672,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[153,115,113,94],"species":348},{"level":43,"moves":[153,115,113,247],"species":349}],"party_address":3220988,"script_address":2334468},{"address":3251712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":371},{"level":22,"species":289},{"level":22,"species":382},{"level":22,"species":287},{"level":22,"species":305},{"level":22,"species":335}],"party_address":3221020,"script_address":0},{"address":3251752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":371},{"level":25,"species":289},{"level":25,"species":382},{"level":25,"species":287},{"level":25,"species":305},{"level":25,"species":336}],"party_address":3221068,"script_address":0},{"address":3251792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":371},{"level":28,"species":289},{"level":28,"species":382},{"level":28,"species":287},{"level":28,"species":305},{"level":28,"species":336}],"party_address":3221116,"script_address":0},{"address":3251832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":371},{"level":31,"species":289},{"level":31,"species":383},{"level":31,"species":287},{"level":31,"species":305},{"level":31,"species":336}],"party_address":3221164,"script_address":0},{"address":3251872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":11,"species":309},{"level":11,"species":306},{"level":11,"species":183},{"level":11,"species":363},{"level":11,"species":315},{"level":11,"species":118}],"party_address":3221212,"script_address":2057265},{"address":3251912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":322},{"level":43,"species":376}],"party_address":3221260,"script_address":2334499},{"address":3251952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":28}],"party_address":3221276,"script_address":2341891},{"address":3251992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":309},{"level":22,"species":306},{"level":22,"species":183},{"level":22,"species":363},{"level":22,"species":315},{"level":22,"species":118}],"party_address":3221284,"script_address":0},{"address":3252032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":310},{"level":25,"species":307},{"level":25,"species":183},{"level":25,"species":363},{"level":25,"species":316},{"level":25,"species":118}],"party_address":3221332,"script_address":0},{"address":3252072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":310},{"level":28,"species":307},{"level":28,"species":183},{"level":28,"species":363},{"level":28,"species":316},{"level":28,"species":118}],"party_address":3221380,"script_address":0},{"address":3252112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":310},{"level":31,"species":307},{"level":31,"species":184},{"level":31,"species":363},{"level":31,"species":316},{"level":31,"species":119}],"party_address":3221428,"script_address":0},{"address":3252152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":307}],"party_address":3221476,"script_address":2061230},{"address":3252192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":298},{"level":28,"species":299},{"level":28,"species":296}],"party_address":3221484,"script_address":2065479},{"address":3252232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":345}],"party_address":3221508,"script_address":2563288},{"address":3252272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":307}],"party_address":3221516,"script_address":0},{"address":3252312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":307}],"party_address":3221524,"script_address":0},{"address":3252352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":307}],"party_address":3221532,"script_address":0},{"address":3252392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":317},{"level":39,"species":307}],"party_address":3221540,"script_address":0},{"address":3252432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":44},{"level":26,"species":363}],"party_address":3221556,"script_address":2061340},{"address":3252472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":295},{"level":28,"species":296},{"level":28,"species":299}],"party_address":3221572,"script_address":2065510},{"address":3252512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":358},{"level":38,"species":363}],"party_address":3221596,"script_address":2563226},{"address":3252552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":44},{"level":30,"species":363}],"party_address":3221612,"script_address":0},{"address":3252592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":44},{"level":33,"species":363}],"party_address":3221628,"script_address":0},{"address":3252632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":44},{"level":36,"species":363}],"party_address":3221644,"script_address":0},{"address":3252672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":182},{"level":39,"species":363}],"party_address":3221660,"script_address":0},{"address":3252712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":21,"species":81}],"party_address":3221676,"script_address":2310306},{"address":3252752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":287},{"level":35,"species":42}],"party_address":3221684,"script_address":2327187},{"address":3252792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":313},{"level":31,"species":41}],"party_address":3221700,"script_address":0},{"address":3252832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":30,"species":41}],"party_address":3221716,"script_address":2317615},{"address":3252872,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":286},{"level":22,"species":339}],"party_address":3221732,"script_address":2309993},{"address":3252912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3221748,"script_address":2188216},{"address":3252952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":66}],"party_address":3221764,"script_address":2095389},{"address":3252992,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":356}],"party_address":3221772,"script_address":2095465},{"address":3253032,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":335}],"party_address":3221780,"script_address":2095427},{"address":3253072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":356}],"party_address":3221788,"script_address":2244674},{"address":3253112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":330}],"party_address":3221796,"script_address":2070287},{"address":3253152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[87,86,98,0],"species":338},{"level":32,"moves":[57,168,0,0],"species":289}],"party_address":3221804,"script_address":2070768},{"address":3253192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":73}],"party_address":3221836,"script_address":2071645},{"address":3253232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":41}],"party_address":3221844,"script_address":2304070},{"address":3253272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":331}],"party_address":3221852,"script_address":2073102},{"address":3253312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":203}],"party_address":3221860,"script_address":0},{"address":3253352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":351}],"party_address":3221868,"script_address":2244705},{"address":3253392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":64}],"party_address":3221876,"script_address":2244829},{"address":3253432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":203}],"party_address":3221884,"script_address":2244767},{"address":3253472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":202}],"party_address":3221892,"script_address":2244798},{"address":3253512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":41},{"level":31,"species":286}],"party_address":3221900,"script_address":2254605},{"address":3253552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221916,"script_address":2254667},{"address":3253592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":41}],"party_address":3221924,"script_address":2257768},{"address":3253632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":287}],"party_address":3221932,"script_address":2257818},{"address":3253672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":318}],"party_address":3221940,"script_address":2257868},{"address":3253712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":177}],"party_address":3221948,"script_address":2244736},{"address":3253752,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3221956,"script_address":1978559},{"address":3253792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3221972,"script_address":1978621},{"address":3253832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":305},{"level":33,"species":307}],"party_address":3221988,"script_address":2073732},{"address":3253872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":120}],"party_address":3222004,"script_address":2069651},{"address":3253912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":41},{"level":27,"species":286}],"party_address":3222012,"script_address":2572062},{"address":3253952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":20,"species":286},{"level":22,"species":339},{"level":22,"species":41}],"party_address":3222028,"script_address":2304039},{"address":3253992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":317},{"level":33,"species":371}],"party_address":3222060,"script_address":2073794},{"address":3254032,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":218},{"level":15,"species":283}],"party_address":3222076,"script_address":1978590},{"address":3254072,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":309},{"level":15,"species":277}],"party_address":3222092,"script_address":1978317},{"address":3254112,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":287},{"level":38,"species":169},{"level":39,"species":340}],"party_address":3222108,"script_address":2351441},{"address":3254152,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":287},{"level":24,"species":41},{"level":25,"species":340}],"party_address":3222132,"script_address":2303440},{"address":3254192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":288},{"level":4,"species":306}],"party_address":3222156,"script_address":2024895},{"address":3254232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":295},{"level":6,"species":306}],"party_address":3222172,"script_address":2029715},{"address":3254272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":183}],"party_address":3222188,"script_address":2054459},{"address":3254312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183},{"level":15,"species":306},{"level":15,"species":339}],"party_address":3222196,"script_address":2045995},{"address":3254352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":296},{"level":26,"species":306}],"party_address":3222220,"script_address":0},{"address":3254392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":296},{"level":29,"species":307}],"party_address":3222236,"script_address":0},{"address":3254432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":296},{"level":32,"species":307}],"party_address":3222252,"script_address":0},{"address":3254472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":305},{"level":34,"species":296},{"level":34,"species":307}],"party_address":3222268,"script_address":0},{"address":3254512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":43}],"party_address":3222292,"script_address":2553761},{"address":3254552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":315},{"level":14,"species":306},{"level":14,"species":183}],"party_address":3222300,"script_address":2553823},{"address":3254592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325}],"party_address":3222324,"script_address":2265615},{"address":3254632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":118},{"level":39,"species":313}],"party_address":3222332,"script_address":2265646},{"address":3254672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":4,"species":290},{"level":4,"species":290}],"party_address":3222348,"script_address":2024864},{"address":3254712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290},{"level":3,"species":290}],"party_address":3222364,"script_address":2300392},{"address":3254752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":290},{"level":8,"species":301}],"party_address":3222396,"script_address":2054211},{"address":3254792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":301},{"level":28,"species":302}],"party_address":3222412,"script_address":2061137},{"address":3254832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222428,"script_address":2061168},{"address":3254872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":302}],"party_address":3222444,"script_address":2061199},{"address":3254912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":6,"species":301},{"level":6,"species":301}],"party_address":3222452,"script_address":2300423},{"address":3254952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":302}],"party_address":3222468,"script_address":0},{"address":3254992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":302}],"party_address":3222476,"script_address":0},{"address":3255032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":311},{"level":31,"species":294},{"level":31,"species":302}],"party_address":3222492,"script_address":0},{"address":3255072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":311},{"level":33,"species":302},{"level":33,"species":294},{"level":33,"species":302}],"party_address":3222516,"script_address":0},{"address":3255112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":339},{"level":17,"species":66}],"party_address":3222548,"script_address":2049688},{"address":3255152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":17,"species":74},{"level":16,"species":74}],"party_address":3222564,"script_address":2049719},{"address":3255192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":66}],"party_address":3222588,"script_address":2051841},{"address":3255232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":74},{"level":18,"species":339}],"party_address":3222604,"script_address":2051872},{"address":3255272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":74},{"level":22,"species":320},{"level":22,"species":75}],"party_address":3222620,"script_address":2557067},{"address":3255312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74}],"party_address":3222644,"script_address":2054428},{"address":3255352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":20,"species":74},{"level":20,"species":318}],"party_address":3222652,"script_address":2310061},{"address":3255392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":9,"moves":[150,55,0,0],"species":313}],"party_address":3222668,"script_address":0},{"address":3255432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":10,"moves":[16,45,0,0],"species":310},{"level":10,"moves":[44,184,0,0],"species":286}],"party_address":3222684,"script_address":0},{"address":3255472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":74},{"level":16,"species":74},{"level":16,"species":66}],"party_address":3222716,"script_address":2296023},{"address":3255512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":74},{"level":24,"species":75}],"party_address":3222740,"script_address":0},{"address":3255552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":74},{"level":27,"species":74},{"level":27,"species":75},{"level":27,"species":75}],"party_address":3222772,"script_address":0},{"address":3255592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":74},{"level":30,"species":75},{"level":30,"species":75},{"level":30,"species":75}],"party_address":3222804,"script_address":0},{"address":3255632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":75},{"level":33,"species":76}],"party_address":3222836,"script_address":0},{"address":3255672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":316},{"level":31,"species":338}],"party_address":3222868,"script_address":0},{"address":3255712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":325},{"level":45,"species":325}],"party_address":3222884,"script_address":0},{"address":3255752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":386},{"level":25,"species":387}],"party_address":3222900,"script_address":0},{"address":3255792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":386},{"level":30,"species":387}],"party_address":3222916,"script_address":0},{"address":3255832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":386},{"level":33,"species":387}],"party_address":3222932,"script_address":0},{"address":3255872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":386},{"level":36,"species":387}],"party_address":3222948,"script_address":0},{"address":3255912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":386},{"level":39,"species":387}],"party_address":3222964,"script_address":0},{"address":3255952,"battle_type":2,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":118}],"party_address":3222980,"script_address":2543970},{"address":3255992,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[53,154,185,20],"species":317}],"party_address":3222988,"script_address":2103539},{"address":3256032,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[117,197,93,9],"species":356},{"level":17,"moves":[9,197,93,96],"species":356}],"party_address":3223004,"script_address":2167701},{"address":3256072,"battle_type":2,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":23,"moves":[117,197,93,7],"species":356}],"party_address":3223036,"script_address":2103508},{"address":3256112,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":25,"moves":[33,120,124,108],"species":109},{"level":25,"moves":[33,139,124,108],"species":109}],"party_address":3223052,"script_address":2061574},{"address":3256152,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[139,120,124,108],"species":109},{"level":28,"moves":[28,104,210,14],"species":302}],"party_address":3223084,"script_address":2065775},{"address":3256192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":28,"moves":[141,154,170,91],"species":301},{"level":28,"moves":[33,120,124,108],"species":109}],"party_address":3223116,"script_address":2065806},{"address":3256232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":305},{"level":29,"species":178}],"party_address":3223148,"script_address":2202329},{"address":3256272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":358},{"level":27,"species":358},{"level":27,"species":358}],"party_address":3223164,"script_address":2202360},{"address":3256312,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":16,"species":392}],"party_address":3223188,"script_address":1971405},{"address":3256352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[76,219,225,93],"species":359},{"level":46,"moves":[47,18,204,185],"species":316},{"level":47,"moves":[89,73,202,92],"species":363},{"level":44,"moves":[48,85,161,103],"species":82},{"level":48,"moves":[104,91,94,248],"species":394}],"party_address":3223196,"script_address":2332607},{"address":3256392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[76,219,225,93],"species":359},{"level":49,"moves":[47,18,204,185],"species":316},{"level":50,"moves":[89,73,202,92],"species":363},{"level":47,"moves":[48,85,161,103],"species":82},{"level":51,"moves":[104,91,94,248],"species":394}],"party_address":3223276,"script_address":0},{"address":3256432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[76,219,225,93],"species":359},{"level":52,"moves":[47,18,204,185],"species":316},{"level":53,"moves":[89,73,202,92],"species":363},{"level":50,"moves":[48,85,161,103],"species":82},{"level":54,"moves":[104,91,94,248],"species":394}],"party_address":3223356,"script_address":0},{"address":3256472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[76,219,225,93],"species":359},{"level":55,"moves":[47,18,204,185],"species":316},{"level":56,"moves":[89,73,202,92],"species":363},{"level":53,"moves":[48,85,161,103],"species":82},{"level":57,"moves":[104,91,94,248],"species":394}],"party_address":3223436,"script_address":0},{"address":3256512,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223516,"script_address":1986165},{"address":3256552,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223548,"script_address":1986109},{"address":3256592,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223580,"script_address":1986137},{"address":3256632,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":218},{"level":32,"species":310},{"level":34,"species":278}],"party_address":3223612,"script_address":1986081},{"address":3256672,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":310},{"level":32,"species":297},{"level":34,"species":281}],"party_address":3223644,"script_address":1986025},{"address":3256712,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":369},{"level":32,"species":297},{"level":32,"species":218},{"level":34,"species":284}],"party_address":3223676,"script_address":1986053},{"address":3256752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":313},{"level":31,"species":72},{"level":32,"species":331}],"party_address":3223708,"script_address":2070644},{"address":3256792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":330},{"level":34,"species":73}],"party_address":3223732,"script_address":2070675},{"address":3256832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":129},{"level":25,"species":129},{"level":35,"species":130}],"party_address":3223748,"script_address":2070706},{"address":3256872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":44},{"level":34,"species":184}],"party_address":3223772,"script_address":2071552},{"address":3256912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":300},{"level":34,"species":320}],"party_address":3223788,"script_address":2071583},{"address":3256952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":67}],"party_address":3223804,"script_address":2070799},{"address":3256992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":72},{"level":31,"species":72},{"level":36,"species":313}],"party_address":3223812,"script_address":2071614},{"address":3257032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":305},{"level":32,"species":227}],"party_address":3223836,"script_address":2070737},{"address":3257072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":341},{"level":33,"species":331}],"party_address":3223852,"script_address":2073040},{"address":3257112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170}],"party_address":3223868,"script_address":2073071},{"address":3257152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":308},{"level":19,"species":308}],"party_address":3223876,"script_address":0},{"address":3257192,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[47,31,219,76],"species":358},{"level":35,"moves":[53,36,156,89],"species":339}],"party_address":3223892,"script_address":0},{"address":3257232,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":18,"moves":[74,78,72,73],"species":363},{"level":20,"moves":[111,205,44,88],"species":75}],"party_address":3223924,"script_address":0},{"address":3257272,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":27,"moves":[16,60,92,182],"species":294},{"level":27,"moves":[16,72,213,78],"species":292}],"party_address":3223956,"script_address":0},{"address":3257312,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[94,7,244,182],"species":357},{"level":39,"moves":[8,61,156,187],"species":336}],"party_address":3223988,"script_address":0},{"address":3257352,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[94,7,244,182],"species":357},{"level":43,"moves":[8,61,156,187],"species":336}],"party_address":3224020,"script_address":0},{"address":3257392,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[94,7,244,182],"species":357},{"level":46,"moves":[8,61,156,187],"species":336}],"party_address":3224052,"script_address":0},{"address":3257432,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":49,"moves":[94,7,244,182],"species":357},{"level":49,"moves":[8,61,156,187],"species":336}],"party_address":3224084,"script_address":0},{"address":3257472,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[94,7,244,182],"species":357},{"level":52,"moves":[8,61,156,187],"species":336}],"party_address":3224116,"script_address":0},{"address":3257512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":184},{"level":33,"species":309}],"party_address":3224148,"script_address":0},{"address":3257552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":170},{"level":33,"species":330}],"party_address":3224164,"script_address":0},{"address":3257592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":170},{"level":40,"species":330}],"party_address":3224180,"script_address":0},{"address":3257632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":45,"species":171},{"level":43,"species":330}],"party_address":3224196,"script_address":0},{"address":3257672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":48,"species":171},{"level":46,"species":331}],"party_address":3224212,"script_address":0},{"address":3257712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":51,"species":171},{"level":49,"species":331}],"party_address":3224228,"script_address":0},{"address":3257752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":27,"species":118},{"level":25,"species":72}],"party_address":3224244,"script_address":0},{"address":3257792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":129},{"level":20,"species":72},{"level":26,"species":328},{"level":23,"species":330}],"party_address":3224260,"script_address":2061605},{"address":3257832,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":288},{"level":8,"species":286}],"party_address":3224292,"script_address":2054707},{"address":3257872,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":8,"species":295},{"level":8,"species":288}],"party_address":3224308,"script_address":2054676},{"address":3257912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":9,"species":129}],"party_address":3224324,"script_address":2030343},{"address":3257952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":183}],"party_address":3224332,"script_address":2036307},{"address":3257992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":12,"species":72},{"level":12,"species":72}],"party_address":3224340,"script_address":2036276},{"address":3258032,"battle_type":0,"data_type":"ITEM_DEFAULT_MOVES","party":[{"level":14,"species":354},{"level":14,"species":353}],"party_address":3224356,"script_address":2039032},{"address":3258072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":337},{"level":14,"species":100}],"party_address":3224372,"script_address":2039063},{"address":3258112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":81}],"party_address":3224388,"script_address":2039094},{"address":3258152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":100}],"party_address":3224396,"script_address":2026463},{"address":3258192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":335}],"party_address":3224404,"script_address":2026494},{"address":3258232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":27}],"party_address":3224412,"script_address":2046975},{"address":3258272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":363}],"party_address":3224420,"script_address":2047006},{"address":3258312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306}],"party_address":3224428,"script_address":2046944},{"address":3258352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339}],"party_address":3224436,"script_address":2046913},{"address":3258392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":183},{"level":19,"species":296}],"party_address":3224444,"script_address":2050969},{"address":3258432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":227},{"level":19,"species":305}],"party_address":3224460,"script_address":2051000},{"address":3258472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":318},{"level":18,"species":27}],"party_address":3224476,"script_address":2051031},{"address":3258512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":382},{"level":18,"species":382}],"party_address":3224492,"script_address":2051062},{"address":3258552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":296},{"level":18,"species":183}],"party_address":3224508,"script_address":2052309},{"address":3258592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":323}],"party_address":3224524,"script_address":2052371},{"address":3258632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":19,"species":299}],"party_address":3224532,"script_address":2052340},{"address":3258672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":14,"species":288},{"level":14,"species":382},{"level":14,"species":337}],"party_address":3224540,"script_address":2059128},{"address":3258712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224564,"script_address":2347841},{"address":3258752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224572,"script_address":2347872},{"address":3258792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224580,"script_address":2348597},{"address":3258832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":41}],"party_address":3224588,"script_address":2348628},{"address":3258872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":318},{"level":28,"species":339}],"party_address":3224604,"script_address":2348659},{"address":3258912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224620,"script_address":2349324},{"address":3258952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224628,"script_address":2349355},{"address":3258992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":286}],"party_address":3224636,"script_address":2349386},{"address":3259032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224644,"script_address":2350264},{"address":3259072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224652,"script_address":2350826},{"address":3259112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224660,"script_address":2351566},{"address":3259152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224668,"script_address":2351597},{"address":3259192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":41}],"party_address":3224676,"script_address":2351628},{"address":3259232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":287}],"party_address":3224684,"script_address":2348566},{"address":3259272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":339}],"party_address":3224692,"script_address":2349293},{"address":3259312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":318}],"party_address":3224700,"script_address":2350295},{"address":3259352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":339},{"level":28,"species":287},{"level":30,"species":41},{"level":33,"species":340}],"party_address":3224708,"script_address":2351659},{"address":3259392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":310},{"level":33,"species":340}],"party_address":3224740,"script_address":2073763},{"address":3259432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":42,"species":287},{"level":43,"species":169},{"level":44,"species":340}],"party_address":3224756,"script_address":0},{"address":3259472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":72}],"party_address":3224780,"script_address":2026525},{"address":3259512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":15,"species":183}],"party_address":3224788,"script_address":2026556},{"address":3259552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":27},{"level":25,"species":27}],"party_address":3224796,"script_address":2033726},{"address":3259592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":304},{"level":25,"species":309}],"party_address":3224812,"script_address":2033695},{"address":3259632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":120}],"party_address":3224828,"script_address":2034744},{"address":3259672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":309},{"level":24,"species":66},{"level":24,"species":72}],"party_address":3224836,"script_address":2034931},{"address":3259712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":24,"species":338},{"level":24,"species":305},{"level":24,"species":338}],"party_address":3224860,"script_address":2034900},{"address":3259752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":227},{"level":25,"species":227}],"party_address":3224884,"script_address":2036338},{"address":3259792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":183},{"level":22,"species":296}],"party_address":3224900,"script_address":2047037},{"address":3259832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":27},{"level":22,"species":28}],"party_address":3224916,"script_address":2047068},{"address":3259872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":22,"species":304},{"level":22,"species":299}],"party_address":3224932,"script_address":2047099},{"address":3259912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":339},{"level":18,"species":218}],"party_address":3224948,"script_address":2049891},{"address":3259952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":306},{"level":18,"species":363}],"party_address":3224964,"script_address":2049922},{"address":3259992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":84},{"level":26,"species":85}],"party_address":3224980,"script_address":2053203},{"address":3260032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":302},{"level":26,"species":367}],"party_address":3224996,"script_address":2053234},{"address":3260072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":64},{"level":26,"species":393}],"party_address":3225012,"script_address":2053265},{"address":3260112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":356},{"level":26,"species":335}],"party_address":3225028,"script_address":2053296},{"address":3260152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":18,"species":356},{"level":18,"species":351}],"party_address":3225044,"script_address":2053327},{"address":3260192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":74},{"level":8,"species":74}],"party_address":3225060,"script_address":2054738},{"address":3260232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":8,"species":306},{"level":8,"species":295}],"party_address":3225076,"script_address":2054769},{"address":3260272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":84}],"party_address":3225092,"script_address":2057834},{"address":3260312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":392}],"party_address":3225100,"script_address":2057865},{"address":3260352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":17,"species":356}],"party_address":3225108,"script_address":2057896},{"address":3260392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":363},{"level":33,"species":357}],"party_address":3225116,"script_address":2073825},{"address":3260432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":338}],"party_address":3225132,"script_address":2061636},{"address":3260472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":218},{"level":25,"species":339}],"party_address":3225140,"script_address":2061667},{"address":3260512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":118}],"party_address":3225156,"script_address":2061698},{"address":3260552,"battle_type":0,"data_type":"NO_ITEM_CUSTOM_MOVES","party":[{"level":30,"moves":[87,98,86,0],"species":338}],"party_address":3225164,"script_address":2065837},{"address":3260592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":356},{"level":28,"species":335}],"party_address":3225180,"script_address":2065868},{"address":3260632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":294},{"level":29,"species":292}],"party_address":3225196,"script_address":2067487},{"address":3260672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":335},{"level":25,"species":309},{"level":25,"species":369},{"level":25,"species":288},{"level":25,"species":337},{"level":25,"species":339}],"party_address":3225212,"script_address":2067518},{"address":3260712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":25,"species":286},{"level":25,"species":306},{"level":25,"species":337},{"level":25,"species":183},{"level":25,"species":27},{"level":25,"species":367}],"party_address":3225260,"script_address":2067549},{"address":3260752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":29,"species":371},{"level":29,"species":365}],"party_address":3225308,"script_address":2067611},{"address":3260792,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":295},{"level":15,"species":280}],"party_address":3225324,"script_address":1978255},{"address":3260832,"battle_type":3,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":13,"species":321},{"level":15,"species":283}],"party_address":3225340,"script_address":1978286},{"address":3260872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":32,"moves":[182,205,222,153],"species":76},{"level":35,"moves":[14,58,57,157],"species":140},{"level":35,"moves":[231,153,46,157],"species":95},{"level":37,"moves":[104,153,182,157],"species":320}],"party_address":3225356,"script_address":0},{"address":3260912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":37,"moves":[182,58,157,57],"species":138},{"level":37,"moves":[182,205,222,153],"species":76},{"level":40,"moves":[14,58,57,157],"species":141},{"level":40,"moves":[231,153,46,157],"species":95},{"level":42,"moves":[104,153,182,157],"species":320}],"party_address":3225420,"script_address":0},{"address":3260952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[182,58,157,57],"species":139},{"level":42,"moves":[182,205,89,153],"species":76},{"level":45,"moves":[14,58,57,157],"species":141},{"level":45,"moves":[231,153,46,157],"species":95},{"level":47,"moves":[104,153,182,157],"species":320}],"party_address":3225500,"script_address":0},{"address":3260992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[157,63,48,182],"species":142},{"level":47,"moves":[8,205,89,153],"species":76},{"level":47,"moves":[182,58,157,57],"species":139},{"level":50,"moves":[14,58,57,157],"species":141},{"level":50,"moves":[231,153,46,157],"species":208},{"level":52,"moves":[104,153,182,157],"species":320}],"party_address":3225580,"script_address":0},{"address":3261032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":33,"moves":[2,157,8,83],"species":68},{"level":33,"moves":[94,113,115,8],"species":356},{"level":35,"moves":[228,68,182,167],"species":237},{"level":37,"moves":[252,8,187,89],"species":336}],"party_address":3225676,"script_address":0},{"address":3261072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[2,157,8,83],"species":68},{"level":38,"moves":[94,113,115,8],"species":357},{"level":40,"moves":[228,68,182,167],"species":237},{"level":42,"moves":[252,8,187,89],"species":336}],"party_address":3225740,"script_address":0},{"address":3261112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[71,182,7,8],"species":107},{"level":43,"moves":[2,157,8,83],"species":68},{"level":43,"moves":[8,113,115,94],"species":357},{"level":45,"moves":[228,68,182,167],"species":237},{"level":47,"moves":[252,8,187,89],"species":336}],"party_address":3225804,"script_address":0},{"address":3261152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[25,8,89,83],"species":106},{"level":46,"moves":[71,182,7,8],"species":107},{"level":48,"moves":[238,157,8,83],"species":68},{"level":48,"moves":[8,113,115,94],"species":357},{"level":50,"moves":[228,68,182,167],"species":237},{"level":52,"moves":[252,8,187,89],"species":336}],"party_address":3225884,"script_address":0},{"address":3261192,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":36,"moves":[87,182,86,113],"species":179},{"level":36,"moves":[205,87,153,240],"species":101},{"level":38,"moves":[48,182,87,240],"species":82},{"level":40,"moves":[44,86,87,182],"species":338}],"party_address":3225980,"script_address":0},{"address":3261232,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":39,"moves":[87,21,240,95],"species":25},{"level":41,"moves":[87,182,86,113],"species":180},{"level":41,"moves":[205,87,153,240],"species":101},{"level":43,"moves":[48,182,87,240],"species":82},{"level":45,"moves":[44,86,87,182],"species":338}],"party_address":3226044,"script_address":0},{"address":3261272,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":44,"moves":[87,21,240,182],"species":26},{"level":46,"moves":[87,182,86,113],"species":181},{"level":46,"moves":[205,87,153,240],"species":101},{"level":48,"moves":[48,182,87,240],"species":82},{"level":50,"moves":[44,86,87,182],"species":338}],"party_address":3226124,"script_address":0},{"address":3261312,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[129,8,9,113],"species":125},{"level":51,"moves":[87,21,240,182],"species":26},{"level":51,"moves":[87,182,86,113],"species":181},{"level":53,"moves":[205,87,153,240],"species":101},{"level":53,"moves":[48,182,87,240],"species":82},{"level":55,"moves":[44,86,87,182],"species":338}],"party_address":3226204,"script_address":0},{"address":3261352,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":38,"moves":[59,213,113,157],"species":219},{"level":36,"moves":[53,213,76,84],"species":77},{"level":38,"moves":[59,241,89,213],"species":340},{"level":40,"moves":[59,241,153,213],"species":321}],"party_address":3226300,"script_address":0},{"address":3261392,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":41,"moves":[14,53,46,241],"species":58},{"level":43,"moves":[59,213,113,157],"species":219},{"level":41,"moves":[53,213,76,84],"species":77},{"level":43,"moves":[59,241,89,213],"species":340},{"level":45,"moves":[59,241,153,213],"species":321}],"party_address":3226364,"script_address":0},{"address":3261432,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[46,76,13,241],"species":228},{"level":46,"moves":[14,53,241,46],"species":58},{"level":48,"moves":[59,213,113,157],"species":219},{"level":46,"moves":[53,213,76,84],"species":78},{"level":48,"moves":[59,241,89,213],"species":340},{"level":50,"moves":[59,241,153,213],"species":321}],"party_address":3226444,"script_address":0},{"address":3261472,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":51,"moves":[14,53,241,46],"species":59},{"level":53,"moves":[59,213,113,157],"species":219},{"level":51,"moves":[46,76,13,241],"species":229},{"level":51,"moves":[53,213,76,84],"species":78},{"level":53,"moves":[59,241,89,213],"species":340},{"level":55,"moves":[59,241,153,213],"species":321}],"party_address":3226540,"script_address":0},{"address":3261512,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":42,"moves":[113,47,29,8],"species":113},{"level":42,"moves":[59,247,38,126],"species":366},{"level":43,"moves":[42,29,7,95],"species":308},{"level":45,"moves":[63,53,85,247],"species":366}],"party_address":3226636,"script_address":0},{"address":3261552,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":47,"moves":[59,247,38,126],"species":366},{"level":47,"moves":[113,47,29,8],"species":113},{"level":45,"moves":[252,146,203,179],"species":115},{"level":48,"moves":[42,29,7,95],"species":308},{"level":50,"moves":[63,53,85,247],"species":366}],"party_address":3226700,"script_address":0},{"address":3261592,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":52,"moves":[59,247,38,126],"species":366},{"level":52,"moves":[113,47,29,8],"species":242},{"level":50,"moves":[252,146,203,179],"species":115},{"level":53,"moves":[42,29,7,95],"species":308},{"level":55,"moves":[63,53,85,247],"species":366}],"party_address":3226780,"script_address":0},{"address":3261632,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":57,"moves":[59,247,38,126],"species":366},{"level":57,"moves":[182,47,29,8],"species":242},{"level":55,"moves":[252,146,203,179],"species":115},{"level":57,"moves":[36,182,126,89],"species":128},{"level":58,"moves":[42,29,7,95],"species":308},{"level":60,"moves":[63,53,85,247],"species":366}],"party_address":3226860,"script_address":0},{"address":3261672,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":40,"moves":[86,85,182,58],"species":147},{"level":38,"moves":[241,76,76,89],"species":369},{"level":41,"moves":[57,48,182,76],"species":310},{"level":43,"moves":[18,191,211,76],"species":227},{"level":45,"moves":[76,156,93,89],"species":359}],"party_address":3226956,"script_address":0},{"address":3261712,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":43,"moves":[95,94,115,138],"species":163},{"level":43,"moves":[241,76,76,89],"species":369},{"level":45,"moves":[86,85,182,58],"species":148},{"level":46,"moves":[57,48,182,76],"species":310},{"level":48,"moves":[18,191,211,76],"species":227},{"level":50,"moves":[76,156,93,89],"species":359}],"party_address":3227036,"script_address":0},{"address":3261752,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[95,94,115,138],"species":164},{"level":49,"moves":[241,76,76,89],"species":369},{"level":50,"moves":[86,85,182,58],"species":148},{"level":51,"moves":[57,48,182,76],"species":310},{"level":53,"moves":[18,191,211,76],"species":227},{"level":55,"moves":[76,156,93,89],"species":359}],"party_address":3227132,"script_address":0},{"address":3261792,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,94,115,138],"species":164},{"level":54,"moves":[241,76,76,89],"species":369},{"level":55,"moves":[57,48,182,76],"species":310},{"level":55,"moves":[63,85,89,58],"species":149},{"level":58,"moves":[18,191,211,76],"species":227},{"level":60,"moves":[143,156,93,89],"species":359}],"party_address":3227228,"script_address":0},{"address":3261832,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":48,"moves":[25,94,91,182],"species":79},{"level":49,"moves":[89,246,94,113],"species":319},{"level":49,"moves":[94,156,109,91],"species":178},{"level":50,"moves":[89,94,156,91],"species":348},{"level":50,"moves":[241,76,94,53],"species":349}],"party_address":3227324,"script_address":0},{"address":3261872,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":53,"moves":[95,138,29,182],"species":96},{"level":53,"moves":[25,94,91,182],"species":79},{"level":54,"moves":[89,153,94,113],"species":319},{"level":54,"moves":[94,156,109,91],"species":178},{"level":55,"moves":[89,94,156,91],"species":348},{"level":55,"moves":[241,76,94,53],"species":349}],"party_address":3227404,"script_address":0},{"address":3261912,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":58,"moves":[95,138,29,182],"species":97},{"level":59,"moves":[89,153,94,113],"species":319},{"level":58,"moves":[25,94,91,182],"species":79},{"level":59,"moves":[94,156,109,91],"species":178},{"level":60,"moves":[89,94,156,91],"species":348},{"level":60,"moves":[241,76,94,53],"species":349}],"party_address":3227500,"script_address":0},{"address":3261952,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":63,"moves":[95,138,29,182],"species":97},{"level":64,"moves":[89,153,94,113],"species":319},{"level":63,"moves":[25,94,91,182],"species":199},{"level":64,"moves":[94,156,109,91],"species":178},{"level":65,"moves":[89,94,156,91],"species":348},{"level":65,"moves":[241,76,94,53],"species":349}],"party_address":3227596,"script_address":0},{"address":3261992,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":46,"moves":[95,240,182,56],"species":60},{"level":46,"moves":[240,96,104,90],"species":324},{"level":48,"moves":[96,34,182,58],"species":343},{"level":48,"moves":[156,152,13,104],"species":327},{"level":51,"moves":[96,104,58,156],"species":230}],"party_address":3227692,"script_address":0},{"address":3262032,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":50,"moves":[95,240,182,56],"species":61},{"level":51,"moves":[240,96,104,90],"species":324},{"level":53,"moves":[96,34,182,58],"species":343},{"level":53,"moves":[156,12,13,104],"species":327},{"level":56,"moves":[96,104,58,156],"species":230}],"party_address":3227772,"script_address":0},{"address":3262072,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":56,"moves":[56,195,58,109],"species":131},{"level":58,"moves":[240,96,104,90],"species":324},{"level":56,"moves":[95,240,182,56],"species":61},{"level":58,"moves":[96,34,182,58],"species":343},{"level":58,"moves":[156,12,13,104],"species":327},{"level":61,"moves":[96,104,58,156],"species":230}],"party_address":3227852,"script_address":0},{"address":3262112,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":61,"moves":[56,195,58,109],"species":131},{"level":63,"moves":[240,96,104,90],"species":324},{"level":61,"moves":[95,240,56,195],"species":186},{"level":63,"moves":[96,34,182,73],"species":343},{"level":63,"moves":[156,12,13,104],"species":327},{"level":66,"moves":[96,104,58,156],"species":230}],"party_address":3227948,"script_address":0},{"address":3262152,"battle_type":0,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":17,"moves":[95,98,204,0],"species":387},{"level":17,"moves":[95,98,109,0],"species":386}],"party_address":3228044,"script_address":2167732},{"address":3262192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":369}],"party_address":3228076,"script_address":2202422},{"address":3262232,"battle_type":3,"data_type":"ITEM_CUSTOM_MOVES","party":[{"level":77,"moves":[92,76,191,211],"species":227},{"level":75,"moves":[115,113,246,89],"species":319},{"level":76,"moves":[87,89,76,81],"species":384},{"level":76,"moves":[202,246,19,109],"species":389},{"level":76,"moves":[96,246,76,163],"species":391},{"level":78,"moves":[89,94,53,247],"species":400}],"party_address":3228084,"script_address":2354502},{"address":3262272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228180,"script_address":0},{"address":3262312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228188,"script_address":0},{"address":3262352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228196,"script_address":0},{"address":3262392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228204,"script_address":0},{"address":3262432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228212,"script_address":0},{"address":3262472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228220,"script_address":0},{"address":3262512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":398}],"party_address":3228228,"script_address":0},{"address":3262552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":27},{"level":31,"species":27}],"party_address":3228236,"script_address":0},{"address":3262592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":320},{"level":33,"species":27},{"level":33,"species":27}],"party_address":3228252,"script_address":0},{"address":3262632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":320},{"level":35,"species":27},{"level":35,"species":27}],"party_address":3228276,"script_address":0},{"address":3262672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":320},{"level":37,"species":28},{"level":37,"species":28}],"party_address":3228300,"script_address":0},{"address":3262712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":309},{"level":30,"species":66},{"level":30,"species":72}],"party_address":3228324,"script_address":0},{"address":3262752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":32,"species":310},{"level":32,"species":66},{"level":32,"species":72}],"party_address":3228348,"script_address":0},{"address":3262792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":310},{"level":34,"species":66},{"level":34,"species":73}],"party_address":3228372,"script_address":0},{"address":3262832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":310},{"level":36,"species":67},{"level":36,"species":73}],"party_address":3228396,"script_address":0},{"address":3262872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":120},{"level":37,"species":120}],"party_address":3228420,"script_address":0},{"address":3262912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":309},{"level":39,"species":120},{"level":39,"species":120}],"party_address":3228436,"script_address":0},{"address":3262952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":310},{"level":41,"species":120},{"level":41,"species":120}],"party_address":3228460,"script_address":0},{"address":3262992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":310},{"level":43,"species":121},{"level":43,"species":121}],"party_address":3228484,"script_address":0},{"address":3263032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":67},{"level":37,"species":67}],"party_address":3228508,"script_address":0},{"address":3263072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":335},{"level":39,"species":67},{"level":39,"species":67}],"party_address":3228524,"script_address":0},{"address":3263112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":336},{"level":41,"species":67},{"level":41,"species":67}],"party_address":3228548,"script_address":0},{"address":3263152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":43,"species":336},{"level":43,"species":68},{"level":43,"species":68}],"party_address":3228572,"script_address":0},{"address":3263192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":371},{"level":35,"species":365}],"party_address":3228596,"script_address":0},{"address":3263232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":308},{"level":37,"species":371},{"level":37,"species":365}],"party_address":3228612,"script_address":0},{"address":3263272,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":308},{"level":39,"species":371},{"level":39,"species":365}],"party_address":3228636,"script_address":0},{"address":3263312,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":308},{"level":41,"species":372},{"level":41,"species":366}],"party_address":3228660,"script_address":0},{"address":3263352,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":337},{"level":35,"species":337},{"level":35,"species":371}],"party_address":3228684,"script_address":0},{"address":3263392,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":337},{"level":37,"species":338},{"level":37,"species":371}],"party_address":3228708,"script_address":0},{"address":3263432,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":39,"species":338},{"level":39,"species":338},{"level":39,"species":371}],"party_address":3228732,"script_address":0},{"address":3263472,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":338},{"level":41,"species":338},{"level":41,"species":372}],"party_address":3228756,"script_address":0},{"address":3263512,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":26,"species":74},{"level":26,"species":339}],"party_address":3228780,"script_address":0},{"address":3263552,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":28,"species":66},{"level":28,"species":339},{"level":28,"species":75}],"party_address":3228796,"script_address":0},{"address":3263592,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":30,"species":66},{"level":30,"species":339},{"level":30,"species":75}],"party_address":3228820,"script_address":0},{"address":3263632,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":67},{"level":33,"species":340},{"level":33,"species":76}],"party_address":3228844,"script_address":0},{"address":3263672,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":31,"species":315},{"level":31,"species":287},{"level":31,"species":288},{"level":31,"species":295},{"level":31,"species":298},{"level":31,"species":304}],"party_address":3228868,"script_address":0},{"address":3263712,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":33,"species":315},{"level":33,"species":287},{"level":33,"species":289},{"level":33,"species":296},{"level":33,"species":299},{"level":33,"species":304}],"party_address":3228916,"script_address":0},{"address":3263752,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":35,"species":316},{"level":35,"species":287},{"level":35,"species":289},{"level":35,"species":296},{"level":35,"species":299},{"level":35,"species":305}],"party_address":3228964,"script_address":0},{"address":3263792,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":37,"species":316},{"level":37,"species":287},{"level":37,"species":289},{"level":37,"species":297},{"level":37,"species":300},{"level":37,"species":305}],"party_address":3229012,"script_address":0},{"address":3263832,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":34,"species":313},{"level":34,"species":116}],"party_address":3229060,"script_address":0},{"address":3263872,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":36,"species":325},{"level":36,"species":313},{"level":36,"species":117}],"party_address":3229076,"script_address":0},{"address":3263912,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":38,"species":325},{"level":38,"species":313},{"level":38,"species":117}],"party_address":3229100,"script_address":0},{"address":3263952,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":40,"species":325},{"level":40,"species":314},{"level":40,"species":230}],"party_address":3229124,"script_address":0},{"address":3263992,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":411}],"party_address":3229148,"script_address":2564791},{"address":3264032,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":378},{"level":41,"species":64}],"party_address":3229156,"script_address":2564822},{"address":3264072,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":41,"species":202}],"party_address":3229172,"script_address":0},{"address":3264112,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":4}],"party_address":3229180,"script_address":0},{"address":3264152,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":1}],"party_address":3229188,"script_address":0},{"address":3264192,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":405}],"party_address":3229196,"script_address":0},{"address":3264232,"battle_type":0,"data_type":"NO_ITEM_DEFAULT_MOVES","party":[{"level":5,"species":404}],"party_address":3229204,"script_address":0}],"warps":{"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4":"MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0","MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2":"MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1","MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10","MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2":"MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11","MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3":"MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2","MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0":"MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4","MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3":"MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5","MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2":"MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6","MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4":"MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7","MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0":"MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8","MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9","MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2":"MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0","MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0":"MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1","MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0":"MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2","MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1":"MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3","MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2":"MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4","MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0":"MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5","MAP_ABANDONED_SHIP_CORRIDORS_B1F:6/MAP_ABANDONED_SHIP_CORRIDORS_1F:10":"MAP_ABANDONED_SHIP_CORRIDORS_1F:10/MAP_ABANDONED_SHIP_CORRIDORS_B1F:6","MAP_ABANDONED_SHIP_CORRIDORS_B1F:7/MAP_ABANDONED_SHIP_CORRIDORS_1F:9":"MAP_ABANDONED_SHIP_CORRIDORS_1F:9/MAP_ABANDONED_SHIP_CORRIDORS_B1F:7","MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0":"MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0","MAP_ABANDONED_SHIP_DECK:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_1F:0,1/MAP_ABANDONED_SHIP_DECK:2","MAP_ABANDONED_SHIP_DECK:3/MAP_ABANDONED_SHIP_CORRIDORS_1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_1F:2,3/MAP_ABANDONED_SHIP_DECK:3","MAP_ABANDONED_SHIP_DECK:4/MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0":"MAP_ABANDONED_SHIP_CAPTAINS_OFFICE:0,1/MAP_ABANDONED_SHIP_DECK:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0,1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:0/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:0","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2,3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:1/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:2","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4,5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:2/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:4","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:3/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:6","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:4/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:7","MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5":"MAP_ABANDONED_SHIP_HIDDEN_FLOOR_CORRIDORS:5/MAP_ABANDONED_SHIP_HIDDEN_FLOOR_ROOMS:8","MAP_ABANDONED_SHIP_ROOMS2_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:8":"MAP_ABANDONED_SHIP_CORRIDORS_1F:8/MAP_ABANDONED_SHIP_ROOMS2_1F:0","MAP_ABANDONED_SHIP_ROOMS2_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:11":"MAP_ABANDONED_SHIP_CORRIDORS_1F:11/MAP_ABANDONED_SHIP_ROOMS2_1F:2","MAP_ABANDONED_SHIP_ROOMS2_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:1":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:1/MAP_ABANDONED_SHIP_ROOMS2_B1F:0","MAP_ABANDONED_SHIP_ROOMS2_B1F:2,3/MAP_ABANDONED_SHIP_CORRIDORS_B1F:0":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:0/MAP_ABANDONED_SHIP_ROOMS2_B1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_1F:4/MAP_ABANDONED_SHIP_ROOMS_1F:0","MAP_ABANDONED_SHIP_ROOMS_1F:2/MAP_ABANDONED_SHIP_CORRIDORS_1F:6":"MAP_ABANDONED_SHIP_CORRIDORS_1F:6/MAP_ABANDONED_SHIP_ROOMS_1F:2","MAP_ABANDONED_SHIP_ROOMS_1F:3,5/MAP_ABANDONED_SHIP_CORRIDORS_1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_1F:5/MAP_ABANDONED_SHIP_ROOMS_1F:3","MAP_ABANDONED_SHIP_ROOMS_1F:4/MAP_ABANDONED_SHIP_CORRIDORS_1F:7":"MAP_ABANDONED_SHIP_CORRIDORS_1F:7/MAP_ABANDONED_SHIP_ROOMS_1F:4","MAP_ABANDONED_SHIP_ROOMS_B1F:0/MAP_ABANDONED_SHIP_CORRIDORS_B1F:2":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:2/MAP_ABANDONED_SHIP_ROOMS_B1F:0","MAP_ABANDONED_SHIP_ROOMS_B1F:1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:3":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:3/MAP_ABANDONED_SHIP_ROOMS_B1F:1","MAP_ABANDONED_SHIP_ROOMS_B1F:2/MAP_ABANDONED_SHIP_CORRIDORS_B1F:4":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:4/MAP_ABANDONED_SHIP_ROOMS_B1F:2","MAP_ABANDONED_SHIP_ROOM_B1F:0,1/MAP_ABANDONED_SHIP_CORRIDORS_B1F:5":"MAP_ABANDONED_SHIP_CORRIDORS_B1F:5/MAP_ABANDONED_SHIP_ROOM_B1F:0","MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0":"MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0","MAP_ABANDONED_SHIP_UNDERWATER2:0/MAP_ABANDONED_SHIP_UNDERWATER1:0":"MAP_ABANDONED_SHIP_UNDERWATER1:0,1/MAP_ABANDONED_SHIP_UNDERWATER2:0","MAP_ALTERING_CAVE:0/MAP_ROUTE103:0":"MAP_ROUTE103:0/MAP_ALTERING_CAVE:0","MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0":"MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0","MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2":"MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1","MAP_ANCIENT_TOMB:2/MAP_ANCIENT_TOMB:1":"MAP_ANCIENT_TOMB:1/MAP_ANCIENT_TOMB:2","MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6":"MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0","MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0":"MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2","MAP_AQUA_HIDEOUT_B1F:0/MAP_AQUA_HIDEOUT_1F:2":"MAP_AQUA_HIDEOUT_1F:2/MAP_AQUA_HIDEOUT_B1F:0","MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0":"MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1","MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6":"MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10","MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22":"MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11","MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9":"MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12","MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18":"MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13","MAP_AQUA_HIDEOUT_B1F:14/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16":"MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15","MAP_AQUA_HIDEOUT_B1F:16/MAP_AQUA_HIDEOUT_B1F:15":"MAP_AQUA_HIDEOUT_B1F:15/MAP_AQUA_HIDEOUT_B1F:16","MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20":"MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17","MAP_AQUA_HIDEOUT_B1F:18/MAP_AQUA_HIDEOUT_B1F:13":"MAP_AQUA_HIDEOUT_B1F:13/MAP_AQUA_HIDEOUT_B1F:18","MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24":"MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19","MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1":"MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2","MAP_AQUA_HIDEOUT_B1F:20/MAP_AQUA_HIDEOUT_B1F:17":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:21/MAP_AQUA_HIDEOUT_B1F:12!":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B1F:22/MAP_AQUA_HIDEOUT_B1F:11":"MAP_AQUA_HIDEOUT_B1F:11/MAP_AQUA_HIDEOUT_B1F:22","MAP_AQUA_HIDEOUT_B1F:23/MAP_AQUA_HIDEOUT_B1F:17!":"MAP_AQUA_HIDEOUT_B1F:17/MAP_AQUA_HIDEOUT_B1F:20","MAP_AQUA_HIDEOUT_B1F:24/MAP_AQUA_HIDEOUT_B1F:19":"MAP_AQUA_HIDEOUT_B1F:19/MAP_AQUA_HIDEOUT_B1F:24","MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2":"MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3","MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7":"MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4","MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8":"MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5","MAP_AQUA_HIDEOUT_B1F:6/MAP_AQUA_HIDEOUT_B1F:10":"MAP_AQUA_HIDEOUT_B1F:10/MAP_AQUA_HIDEOUT_B1F:6","MAP_AQUA_HIDEOUT_B1F:7/MAP_AQUA_HIDEOUT_B1F:4":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_AQUA_HIDEOUT_B1F:8/MAP_AQUA_HIDEOUT_B1F:5":"MAP_AQUA_HIDEOUT_B1F:5/MAP_AQUA_HIDEOUT_B1F:8","MAP_AQUA_HIDEOUT_B1F:9/MAP_AQUA_HIDEOUT_B1F:12":"MAP_AQUA_HIDEOUT_B1F:12/MAP_AQUA_HIDEOUT_B1F:9","MAP_AQUA_HIDEOUT_B2F:0/MAP_AQUA_HIDEOUT_B1F:1":"MAP_AQUA_HIDEOUT_B1F:1/MAP_AQUA_HIDEOUT_B2F:0","MAP_AQUA_HIDEOUT_B2F:1/MAP_AQUA_HIDEOUT_B1F:2":"MAP_AQUA_HIDEOUT_B1F:2/MAP_AQUA_HIDEOUT_B2F:1","MAP_AQUA_HIDEOUT_B2F:2/MAP_AQUA_HIDEOUT_B1F:3":"MAP_AQUA_HIDEOUT_B1F:3/MAP_AQUA_HIDEOUT_B2F:2","MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5":"MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3","MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8":"MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4","MAP_AQUA_HIDEOUT_B2F:5/MAP_AQUA_HIDEOUT_B2F:3":"MAP_AQUA_HIDEOUT_B2F:3/MAP_AQUA_HIDEOUT_B2F:5","MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7":"MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6","MAP_AQUA_HIDEOUT_B2F:7/MAP_AQUA_HIDEOUT_B2F:6":"MAP_AQUA_HIDEOUT_B2F:6/MAP_AQUA_HIDEOUT_B2F:7","MAP_AQUA_HIDEOUT_B2F:8/MAP_AQUA_HIDEOUT_B2F:4":"MAP_AQUA_HIDEOUT_B2F:4/MAP_AQUA_HIDEOUT_B2F:8","MAP_AQUA_HIDEOUT_B2F:9/MAP_AQUA_HIDEOUT_B1F:4!":"MAP_AQUA_HIDEOUT_B1F:4/MAP_AQUA_HIDEOUT_B1F:7","MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0","MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1":"MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1","MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0","MAP_ARTISAN_CAVE_B1F:1/MAP_ARTISAN_CAVE_1F:1":"MAP_ARTISAN_CAVE_1F:1/MAP_ARTISAN_CAVE_B1F:1","MAP_BATTLE_COLOSSEUM_2P:0,1/MAP_DYNAMIC:-1!":"","MAP_BATTLE_COLOSSEUM_4P:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1!":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:3/MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0!":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:2","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR:0,1/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:2","MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0","MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2/MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM:0,1/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:2","MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0","MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0","MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0","MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0","MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0","MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0","MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0","MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0","MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0","MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0","MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0/MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:0","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1/MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_ARENA_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:1","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10/MAP_BATTLE_FRONTIER_LOUNGE8:0":"MAP_BATTLE_FRONTIER_LOUNGE8:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:10","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11/MAP_BATTLE_FRONTIER_LOUNGE9:0":"MAP_BATTLE_FRONTIER_LOUNGE9:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:11","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13/MAP_ARTISAN_CAVE_1F:0":"MAP_ARTISAN_CAVE_1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:13","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2/MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PALACE_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:2","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3/MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:3","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0":"MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5/MAP_BATTLE_FRONTIER_LOUNGE1:0":"MAP_BATTLE_FRONTIER_LOUNGE1:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:5","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6/MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0":"MAP_BATTLE_FRONTIER_EXCHANGE_SERVICE_CORNER:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:6","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7/MAP_BATTLE_FRONTIER_LOUNGE5:0":"MAP_BATTLE_FRONTIER_LOUNGE5:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:7","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8/MAP_BATTLE_FRONTIER_LOUNGE6:0":"MAP_BATTLE_FRONTIER_LOUNGE6:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:8","MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9/MAP_BATTLE_FRONTIER_LOUNGE3:0":"MAP_BATTLE_FRONTIER_LOUNGE3:0/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:9","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0/MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_PIKE_LOBBY:0,1,2/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:0","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1/MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_DOME_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:1","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10/MAP_ARTISAN_CAVE_B1F:0":"MAP_ARTISAN_CAVE_B1F:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:10","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2/MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0":"MAP_BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:2","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3/MAP_BATTLE_FRONTIER_LOUNGE2:0":"MAP_BATTLE_FRONTIER_LOUNGE2:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:3","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4/MAP_BATTLE_FRONTIER_MART:0":"MAP_BATTLE_FRONTIER_MART:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:4","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0":"MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6/MAP_BATTLE_FRONTIER_LOUNGE4:0":"MAP_BATTLE_FRONTIER_LOUNGE4:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:6","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7/MAP_BATTLE_FRONTIER_LOUNGE7:0":"MAP_BATTLE_FRONTIER_LOUNGE7:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:7","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8","MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1":"MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:12/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0/MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2":"MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F:2/MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:0","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_BATTLE_FRONTIER_RANKING_HALL:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4":"MAP_BATTLE_FRONTIER_OUTSIDE_EAST:4/MAP_BATTLE_FRONTIER_RANKING_HALL:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:0/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:8/MAP_BATTLE_FRONTIER_RECEPTION_GATE:0","MAP_BATTLE_FRONTIER_RECEPTION_GATE:1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:9/MAP_BATTLE_FRONTIER_RECEPTION_GATE:1","MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0,1/MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5":"MAP_BATTLE_FRONTIER_OUTSIDE_WEST:5/MAP_BATTLE_FRONTIER_SCOTTS_HOUSE:0","MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0":"MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0","MAP_BIRTH_ISLAND_HARBOR:0/MAP_BIRTH_ISLAND_EXTERIOR:0":"MAP_BIRTH_ISLAND_EXTERIOR:0/MAP_BIRTH_ISLAND_HARBOR:0","MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1":"MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0","MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3":"MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0","MAP_CAVE_OF_ORIGIN_ENTRANCE:1/MAP_CAVE_OF_ORIGIN_1F:0":"MAP_CAVE_OF_ORIGIN_1F:0/MAP_CAVE_OF_ORIGIN_ENTRANCE:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:0/MAP_CAVE_OF_ORIGIN_1F:1!":"MAP_CAVE_OF_ORIGIN_1F:1/MAP_CAVE_OF_ORIGIN_B1F:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP1:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1":"MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP2:1/MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:0","MAP_CAVE_OF_ORIGIN_UNUSED_RUBY_SAPPHIRE_MAP3:1/MAP_CAVE_OF_ORIGIN_B1F:0!":"MAP_CAVE_OF_ORIGIN_B1F:0/MAP_CAVE_OF_ORIGIN_1F:1","MAP_DESERT_RUINS:0/MAP_ROUTE111:1":"MAP_ROUTE111:1/MAP_DESERT_RUINS:0","MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2":"MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1","MAP_DESERT_RUINS:2/MAP_DESERT_RUINS:1":"MAP_DESERT_RUINS:1/MAP_DESERT_RUINS:2","MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0","MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0":"MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0","MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1","MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0":"MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2","MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0":"MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3","MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0":"MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4","MAP_DEWFORD_TOWN_GYM:0,1/MAP_DEWFORD_TOWN:2":"MAP_DEWFORD_TOWN:2/MAP_DEWFORD_TOWN_GYM:0","MAP_DEWFORD_TOWN_HALL:0,1/MAP_DEWFORD_TOWN:0":"MAP_DEWFORD_TOWN:0/MAP_DEWFORD_TOWN_HALL:0","MAP_DEWFORD_TOWN_HOUSE1:0,1/MAP_DEWFORD_TOWN:3":"MAP_DEWFORD_TOWN:3/MAP_DEWFORD_TOWN_HOUSE1:0","MAP_DEWFORD_TOWN_HOUSE2:0,1/MAP_DEWFORD_TOWN:4":"MAP_DEWFORD_TOWN:4/MAP_DEWFORD_TOWN_HOUSE2:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0,1/MAP_DEWFORD_TOWN:1":"MAP_DEWFORD_TOWN:1/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0":"MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0/MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2":"MAP_DEWFORD_TOWN_POKEMON_CENTER_1F:2/MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:0","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_DEWFORD_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0","MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1","MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0":"MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2","MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1":"MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1":"MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0","MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0":"MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1":"MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0","MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0":"MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1":"MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0","MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0":"MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1","MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0","MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1","MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1":"MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0","MAP_EVER_GRANDE_CITY_HALL2:1/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL2:1","MAP_EVER_GRANDE_CITY_HALL3:0,2,3/MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1":"MAP_EVER_GRANDE_CITY_GLACIAS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL3:0","MAP_EVER_GRANDE_CITY_HALL3:1/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL3:1","MAP_EVER_GRANDE_CITY_HALL4:0/MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1":"MAP_EVER_GRANDE_CITY_DRAKES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL4:0","MAP_EVER_GRANDE_CITY_HALL4:1/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL4:1","MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0","MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0":"MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1","MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0/MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1":"MAP_EVER_GRANDE_CITY_CHAMPIONS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL_OF_FAME:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0/MAP_EVER_GRANDE_CITY_HALL1:1":"MAP_EVER_GRANDE_CITY_HALL1:1/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:0","MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1/MAP_EVER_GRANDE_CITY_HALL2:0":"MAP_EVER_GRANDE_CITY_HALL2:0,2,3/MAP_EVER_GRANDE_CITY_PHOEBES_ROOM:1","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0,1/MAP_EVER_GRANDE_CITY:1":"MAP_EVER_GRANDE_CITY:1/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2":"MAP_EVER_GRANDE_CITY_POKEMON_CENTER_1F:2/MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0,1/MAP_EVER_GRANDE_CITY:0":"MAP_EVER_GRANDE_CITY:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2,3/MAP_EVER_GRANDE_CITY_HALL5:0":"MAP_EVER_GRANDE_CITY_HALL5:0,2,3/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:2","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4":"MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F:4/MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:0","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0/MAP_EVER_GRANDE_CITY_HALL5:1":"MAP_EVER_GRANDE_CITY_HALL5:1/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:0","MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1/MAP_EVER_GRANDE_CITY_HALL1:0":"MAP_EVER_GRANDE_CITY_HALL1:0,2,3/MAP_EVER_GRANDE_CITY_SIDNEYS_ROOM:1","MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0":"MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0","MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0":"MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1","MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2","MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0":"MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3","MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0":"MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4","MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_FALLARBOR_TOWN:1":"MAP_FALLARBOR_TOWN:1/MAP_FALLARBOR_TOWN_BATTLE_TENT_LOBBY:0","MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0,1/MAP_FALLARBOR_TOWN:3":"MAP_FALLARBOR_TOWN:3/MAP_FALLARBOR_TOWN_COZMOS_HOUSE:0","MAP_FALLARBOR_TOWN_MART:0,1/MAP_FALLARBOR_TOWN:0":"MAP_FALLARBOR_TOWN:0/MAP_FALLARBOR_TOWN_MART:0","MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0,1/MAP_FALLARBOR_TOWN:4":"MAP_FALLARBOR_TOWN:4/MAP_FALLARBOR_TOWN_MOVE_RELEARNERS_HOUSE:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0,1/MAP_FALLARBOR_TOWN:2":"MAP_FALLARBOR_TOWN:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0/MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2":"MAP_FALLARBOR_TOWN_POKEMON_CENTER_1F:2/MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:0","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FALLARBOR_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1":"MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1","MAP_FARAWAY_ISLAND_INTERIOR:0,1/MAP_FARAWAY_ISLAND_ENTRANCE:0,1":"MAP_FARAWAY_ISLAND_ENTRANCE:0,1/MAP_FARAWAY_ISLAND_INTERIOR:0,1","MAP_FIERY_PATH:0/MAP_ROUTE112:4":"MAP_ROUTE112:4/MAP_FIERY_PATH:0","MAP_FIERY_PATH:1/MAP_ROUTE112:5":"MAP_ROUTE112:5/MAP_FIERY_PATH:1","MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0","MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0":"MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1","MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0":"MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2","MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0":"MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3","MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0":"MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4","MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0":"MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5","MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0":"MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6","MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0":"MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7","MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0":"MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8","MAP_FORTREE_CITY_DECORATION_SHOP:0,1/MAP_FORTREE_CITY:8":"MAP_FORTREE_CITY:8/MAP_FORTREE_CITY_DECORATION_SHOP:0","MAP_FORTREE_CITY_GYM:0,1/MAP_FORTREE_CITY:2":"MAP_FORTREE_CITY:2/MAP_FORTREE_CITY_GYM:0","MAP_FORTREE_CITY_HOUSE1:0,1/MAP_FORTREE_CITY:1":"MAP_FORTREE_CITY:1/MAP_FORTREE_CITY_HOUSE1:0","MAP_FORTREE_CITY_HOUSE2:0,1/MAP_FORTREE_CITY:4":"MAP_FORTREE_CITY:4/MAP_FORTREE_CITY_HOUSE2:0","MAP_FORTREE_CITY_HOUSE3:0,1/MAP_FORTREE_CITY:5":"MAP_FORTREE_CITY:5/MAP_FORTREE_CITY_HOUSE3:0","MAP_FORTREE_CITY_HOUSE4:0,1/MAP_FORTREE_CITY:6":"MAP_FORTREE_CITY:6/MAP_FORTREE_CITY_HOUSE4:0","MAP_FORTREE_CITY_HOUSE5:0,1/MAP_FORTREE_CITY:7":"MAP_FORTREE_CITY:7/MAP_FORTREE_CITY_HOUSE5:0","MAP_FORTREE_CITY_MART:0,1/MAP_FORTREE_CITY:3":"MAP_FORTREE_CITY:3/MAP_FORTREE_CITY_MART:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:0,1/MAP_FORTREE_CITY:0":"MAP_FORTREE_CITY:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:0","MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0":"MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2","MAP_FORTREE_CITY_POKEMON_CENTER_2F:0/MAP_FORTREE_CITY_POKEMON_CENTER_1F:2":"MAP_FORTREE_CITY_POKEMON_CENTER_1F:2/MAP_FORTREE_CITY_POKEMON_CENTER_2F:0","MAP_FORTREE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_FORTREE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0":"MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0","MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0":"MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1","MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1":"MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2","MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0":"MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3","MAP_GRANITE_CAVE_B1F:0/MAP_GRANITE_CAVE_1F:1":"MAP_GRANITE_CAVE_1F:1/MAP_GRANITE_CAVE_B1F:0","MAP_GRANITE_CAVE_B1F:1/MAP_GRANITE_CAVE_1F:2":"MAP_GRANITE_CAVE_1F:2/MAP_GRANITE_CAVE_B1F:1","MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0":"MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2","MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1":"MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3","MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2":"MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4","MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3":"MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5","MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4":"MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6","MAP_GRANITE_CAVE_B2F:0/MAP_GRANITE_CAVE_B1F:2":"MAP_GRANITE_CAVE_B1F:2/MAP_GRANITE_CAVE_B2F:0","MAP_GRANITE_CAVE_B2F:1/MAP_GRANITE_CAVE_B1F:3":"MAP_GRANITE_CAVE_B1F:3/MAP_GRANITE_CAVE_B2F:1","MAP_GRANITE_CAVE_B2F:2/MAP_GRANITE_CAVE_B1F:4":"MAP_GRANITE_CAVE_B1F:4/MAP_GRANITE_CAVE_B2F:2","MAP_GRANITE_CAVE_B2F:3/MAP_GRANITE_CAVE_B1F:5":"MAP_GRANITE_CAVE_B1F:5/MAP_GRANITE_CAVE_B2F:3","MAP_GRANITE_CAVE_B2F:4/MAP_GRANITE_CAVE_B1F:6":"MAP_GRANITE_CAVE_B1F:6/MAP_GRANITE_CAVE_B2F:4","MAP_GRANITE_CAVE_STEVENS_ROOM:0/MAP_GRANITE_CAVE_1F:3":"MAP_GRANITE_CAVE_1F:3/MAP_GRANITE_CAVE_STEVENS_ROOM:0","MAP_INSIDE_OF_TRUCK:0,1,2/MAP_DYNAMIC:-1!":"","MAP_ISLAND_CAVE:0/MAP_ROUTE105:0":"MAP_ROUTE105:0/MAP_ISLAND_CAVE:0","MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2":"MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1","MAP_ISLAND_CAVE:2/MAP_ISLAND_CAVE:1":"MAP_ISLAND_CAVE:1/MAP_ISLAND_CAVE:2","MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3":"MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1","MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3":"MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3","MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0":"MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4","MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0":"MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0","MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0":"MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1","MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0":"MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2","MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3","MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0":"MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4","MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5","MAP_LAVARIDGE_TOWN_GYM_1F:0,1/MAP_LAVARIDGE_TOWN:1":"MAP_LAVARIDGE_TOWN:1/MAP_LAVARIDGE_TOWN_GYM_1F:0","MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8":"MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10","MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9":"MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11","MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10":"MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12","MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11":"MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13","MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12":"MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14","MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13":"MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15","MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14":"MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16","MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15":"MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17","MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16":"MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18","MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17":"MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19","MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0":"MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2","MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18":"MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20","MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20":"MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21","MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19":"MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22","MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21":"MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23","MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22":"MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24","MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23":"MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25","MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2":"MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3","MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4":"MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4","MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3":"MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5","MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1":"MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6","MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5":"MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7","MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6":"MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8","MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7":"MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9","MAP_LAVARIDGE_TOWN_GYM_B1F:0/MAP_LAVARIDGE_TOWN_GYM_1F:2":"MAP_LAVARIDGE_TOWN_GYM_1F:2/MAP_LAVARIDGE_TOWN_GYM_B1F:0","MAP_LAVARIDGE_TOWN_GYM_B1F:1/MAP_LAVARIDGE_TOWN_GYM_1F:6":"MAP_LAVARIDGE_TOWN_GYM_1F:6/MAP_LAVARIDGE_TOWN_GYM_B1F:1","MAP_LAVARIDGE_TOWN_GYM_B1F:10/MAP_LAVARIDGE_TOWN_GYM_1F:12":"MAP_LAVARIDGE_TOWN_GYM_1F:12/MAP_LAVARIDGE_TOWN_GYM_B1F:10","MAP_LAVARIDGE_TOWN_GYM_B1F:11/MAP_LAVARIDGE_TOWN_GYM_1F:13":"MAP_LAVARIDGE_TOWN_GYM_1F:13/MAP_LAVARIDGE_TOWN_GYM_B1F:11","MAP_LAVARIDGE_TOWN_GYM_B1F:12/MAP_LAVARIDGE_TOWN_GYM_1F:14":"MAP_LAVARIDGE_TOWN_GYM_1F:14/MAP_LAVARIDGE_TOWN_GYM_B1F:12","MAP_LAVARIDGE_TOWN_GYM_B1F:13/MAP_LAVARIDGE_TOWN_GYM_1F:15":"MAP_LAVARIDGE_TOWN_GYM_1F:15/MAP_LAVARIDGE_TOWN_GYM_B1F:13","MAP_LAVARIDGE_TOWN_GYM_B1F:14/MAP_LAVARIDGE_TOWN_GYM_1F:16":"MAP_LAVARIDGE_TOWN_GYM_1F:16/MAP_LAVARIDGE_TOWN_GYM_B1F:14","MAP_LAVARIDGE_TOWN_GYM_B1F:15/MAP_LAVARIDGE_TOWN_GYM_1F:17":"MAP_LAVARIDGE_TOWN_GYM_1F:17/MAP_LAVARIDGE_TOWN_GYM_B1F:15","MAP_LAVARIDGE_TOWN_GYM_B1F:16/MAP_LAVARIDGE_TOWN_GYM_1F:18":"MAP_LAVARIDGE_TOWN_GYM_1F:18/MAP_LAVARIDGE_TOWN_GYM_B1F:16","MAP_LAVARIDGE_TOWN_GYM_B1F:17/MAP_LAVARIDGE_TOWN_GYM_1F:19":"MAP_LAVARIDGE_TOWN_GYM_1F:19/MAP_LAVARIDGE_TOWN_GYM_B1F:17","MAP_LAVARIDGE_TOWN_GYM_B1F:18/MAP_LAVARIDGE_TOWN_GYM_1F:20":"MAP_LAVARIDGE_TOWN_GYM_1F:20/MAP_LAVARIDGE_TOWN_GYM_B1F:18","MAP_LAVARIDGE_TOWN_GYM_B1F:19/MAP_LAVARIDGE_TOWN_GYM_1F:22":"MAP_LAVARIDGE_TOWN_GYM_1F:22/MAP_LAVARIDGE_TOWN_GYM_B1F:19","MAP_LAVARIDGE_TOWN_GYM_B1F:2/MAP_LAVARIDGE_TOWN_GYM_1F:3":"MAP_LAVARIDGE_TOWN_GYM_1F:3/MAP_LAVARIDGE_TOWN_GYM_B1F:2","MAP_LAVARIDGE_TOWN_GYM_B1F:20/MAP_LAVARIDGE_TOWN_GYM_1F:21":"MAP_LAVARIDGE_TOWN_GYM_1F:21/MAP_LAVARIDGE_TOWN_GYM_B1F:20","MAP_LAVARIDGE_TOWN_GYM_B1F:21/MAP_LAVARIDGE_TOWN_GYM_1F:23":"MAP_LAVARIDGE_TOWN_GYM_1F:23/MAP_LAVARIDGE_TOWN_GYM_B1F:21","MAP_LAVARIDGE_TOWN_GYM_B1F:22/MAP_LAVARIDGE_TOWN_GYM_1F:24":"MAP_LAVARIDGE_TOWN_GYM_1F:24/MAP_LAVARIDGE_TOWN_GYM_B1F:22","MAP_LAVARIDGE_TOWN_GYM_B1F:23/MAP_LAVARIDGE_TOWN_GYM_1F:25":"MAP_LAVARIDGE_TOWN_GYM_1F:25/MAP_LAVARIDGE_TOWN_GYM_B1F:23","MAP_LAVARIDGE_TOWN_GYM_B1F:3/MAP_LAVARIDGE_TOWN_GYM_1F:5":"MAP_LAVARIDGE_TOWN_GYM_1F:5/MAP_LAVARIDGE_TOWN_GYM_B1F:3","MAP_LAVARIDGE_TOWN_GYM_B1F:4/MAP_LAVARIDGE_TOWN_GYM_1F:4":"MAP_LAVARIDGE_TOWN_GYM_1F:4/MAP_LAVARIDGE_TOWN_GYM_B1F:4","MAP_LAVARIDGE_TOWN_GYM_B1F:5/MAP_LAVARIDGE_TOWN_GYM_1F:7":"MAP_LAVARIDGE_TOWN_GYM_1F:7/MAP_LAVARIDGE_TOWN_GYM_B1F:5","MAP_LAVARIDGE_TOWN_GYM_B1F:6/MAP_LAVARIDGE_TOWN_GYM_1F:8":"MAP_LAVARIDGE_TOWN_GYM_1F:8/MAP_LAVARIDGE_TOWN_GYM_B1F:6","MAP_LAVARIDGE_TOWN_GYM_B1F:7/MAP_LAVARIDGE_TOWN_GYM_1F:9":"MAP_LAVARIDGE_TOWN_GYM_1F:9/MAP_LAVARIDGE_TOWN_GYM_B1F:7","MAP_LAVARIDGE_TOWN_GYM_B1F:8/MAP_LAVARIDGE_TOWN_GYM_1F:10":"MAP_LAVARIDGE_TOWN_GYM_1F:10/MAP_LAVARIDGE_TOWN_GYM_B1F:8","MAP_LAVARIDGE_TOWN_GYM_B1F:9/MAP_LAVARIDGE_TOWN_GYM_1F:11":"MAP_LAVARIDGE_TOWN_GYM_1F:11/MAP_LAVARIDGE_TOWN_GYM_B1F:9","MAP_LAVARIDGE_TOWN_HERB_SHOP:0,1/MAP_LAVARIDGE_TOWN:0":"MAP_LAVARIDGE_TOWN:0/MAP_LAVARIDGE_TOWN_HERB_SHOP:0","MAP_LAVARIDGE_TOWN_HOUSE:0,1/MAP_LAVARIDGE_TOWN:4":"MAP_LAVARIDGE_TOWN:4/MAP_LAVARIDGE_TOWN_HOUSE:0","MAP_LAVARIDGE_TOWN_MART:0,1/MAP_LAVARIDGE_TOWN:2":"MAP_LAVARIDGE_TOWN:2/MAP_LAVARIDGE_TOWN_MART:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0,1/MAP_LAVARIDGE_TOWN:3":"MAP_LAVARIDGE_TOWN:3/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3/MAP_LAVARIDGE_TOWN:5":"MAP_LAVARIDGE_TOWN:5/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:3","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2":"MAP_LAVARIDGE_TOWN_POKEMON_CENTER_1F:2/MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:0","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LAVARIDGE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0","MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1","MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0":"MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10","MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0":"MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11","MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0":"MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12","MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2","MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13","MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4","MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1":"MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5","MAP_LILYCOVE_CITY:6/MAP_AQUA_HIDEOUT_1F:0":"MAP_AQUA_HIDEOUT_1F:0,1/MAP_LILYCOVE_CITY:6","MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0":"MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7","MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0":"MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8","MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0":"MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9","MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0","MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3":"MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1","MAP_LILYCOVE_CITY_CONTEST_LOBBY:0,1/MAP_LILYCOVE_CITY:4":"MAP_LILYCOVE_CITY:4/MAP_LILYCOVE_CITY_CONTEST_LOBBY:0","MAP_LILYCOVE_CITY_CONTEST_LOBBY:2/MAP_LILYCOVE_CITY_CONTEST_HALL:0":"MAP_LILYCOVE_CITY_CONTEST_HALL:0,2/MAP_LILYCOVE_CITY_CONTEST_LOBBY:2","MAP_LILYCOVE_CITY_CONTEST_LOBBY:3/MAP_LILYCOVE_CITY_CONTEST_HALL:1":"MAP_LILYCOVE_CITY_CONTEST_HALL:1,3/MAP_LILYCOVE_CITY_CONTEST_LOBBY:3","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0,1/MAP_LILYCOVE_CITY:1":"MAP_LILYCOVE_CITY:1/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:0","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2","MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2":"MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F:2/MAP_LILYCOVE_CITY_COVE_LILY_MOTEL_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0,1/MAP_LILYCOVE_CITY:0":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:3/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_2F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_3F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_4F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:0","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:1/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0!":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR:0,1/MAP_DYNAMIC:-1!":"","MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2":"MAP_LILYCOVE_CITY_DEPARTMENT_STORE_5F:2/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:0","MAP_LILYCOVE_CITY_HARBOR:0,1/MAP_LILYCOVE_CITY:12":"MAP_LILYCOVE_CITY:12/MAP_LILYCOVE_CITY_HARBOR:0","MAP_LILYCOVE_CITY_HOUSE1:0,1/MAP_LILYCOVE_CITY:8":"MAP_LILYCOVE_CITY:8/MAP_LILYCOVE_CITY_HOUSE1:0","MAP_LILYCOVE_CITY_HOUSE2:0,1/MAP_LILYCOVE_CITY:9":"MAP_LILYCOVE_CITY:9/MAP_LILYCOVE_CITY_HOUSE2:0","MAP_LILYCOVE_CITY_HOUSE3:0,1/MAP_LILYCOVE_CITY:10":"MAP_LILYCOVE_CITY:10/MAP_LILYCOVE_CITY_HOUSE3:0","MAP_LILYCOVE_CITY_HOUSE4:0,1/MAP_LILYCOVE_CITY:11":"MAP_LILYCOVE_CITY:11/MAP_LILYCOVE_CITY_HOUSE4:0","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1/MAP_LILYCOVE_CITY:3,13":"MAP_LILYCOVE_CITY:3,13/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:0,1","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2","MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2":"MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_1F:2/MAP_LILYCOVE_CITY_LILYCOVE_MUSEUM_2F:0","MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0,1/MAP_LILYCOVE_CITY:7":"MAP_LILYCOVE_CITY:7/MAP_LILYCOVE_CITY_MOVE_DELETERS_HOUSE:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0,1/MAP_LILYCOVE_CITY:2":"MAP_LILYCOVE_CITY:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0":"MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0/MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2":"MAP_LILYCOVE_CITY_POKEMON_CENTER_1F:2/MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:0","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:0,1/MAP_LILYCOVE_CITY:5":"MAP_LILYCOVE_CITY:5/MAP_LILYCOVE_CITY_POKEMON_TRAINER_FAN_CLUB:1","MAP_LILYCOVE_CITY_UNUSED_MART:0,1/MAP_LILYCOVE_CITY:0!":"MAP_LILYCOVE_CITY:0/MAP_LILYCOVE_CITY_DEPARTMENT_STORE_1F:0","MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0","MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1","MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0":"MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:1":"MAP_LITTLEROOT_TOWN:1/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:0,1/MAP_LITTLEROOT_TOWN:0":"MAP_LITTLEROOT_TOWN:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:1","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2","MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2":"MAP_LITTLEROOT_TOWN_MAYS_HOUSE_1F:2/MAP_LITTLEROOT_TOWN_MAYS_HOUSE_2F:0","MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0,1/MAP_LITTLEROOT_TOWN:2":"MAP_LITTLEROOT_TOWN:2/MAP_LITTLEROOT_TOWN_PROFESSOR_BIRCHS_LAB:0","MAP_MAGMA_HIDEOUT_1F:0/MAP_JAGGED_PASS:4":"MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0","MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1":"MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1","MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1":"MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2","MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0":"MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3","MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0":"MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0","MAP_MAGMA_HIDEOUT_2F_1R:1/MAP_MAGMA_HIDEOUT_1F:1":"MAP_MAGMA_HIDEOUT_1F:1/MAP_MAGMA_HIDEOUT_2F_1R:1","MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2":"MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2","MAP_MAGMA_HIDEOUT_2F_2R:0/MAP_MAGMA_HIDEOUT_2F_1R:0":"MAP_MAGMA_HIDEOUT_2F_1R:0/MAP_MAGMA_HIDEOUT_2F_2R:0","MAP_MAGMA_HIDEOUT_2F_2R:1/MAP_MAGMA_HIDEOUT_1F:2":"MAP_MAGMA_HIDEOUT_1F:2/MAP_MAGMA_HIDEOUT_2F_2R:1","MAP_MAGMA_HIDEOUT_2F_3R:0/MAP_MAGMA_HIDEOUT_1F:3":"MAP_MAGMA_HIDEOUT_1F:3/MAP_MAGMA_HIDEOUT_2F_3R:0","MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0":"MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1","MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0":"MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0","MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0":"MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1","MAP_MAGMA_HIDEOUT_3F_1R:2/MAP_MAGMA_HIDEOUT_2F_1R:2":"MAP_MAGMA_HIDEOUT_2F_1R:2/MAP_MAGMA_HIDEOUT_3F_1R:2","MAP_MAGMA_HIDEOUT_3F_2R:0/MAP_MAGMA_HIDEOUT_3F_1R:1":"MAP_MAGMA_HIDEOUT_3F_1R:1/MAP_MAGMA_HIDEOUT_3F_2R:0","MAP_MAGMA_HIDEOUT_3F_3R:0/MAP_MAGMA_HIDEOUT_2F_3R:1":"MAP_MAGMA_HIDEOUT_2F_3R:1/MAP_MAGMA_HIDEOUT_3F_3R:0","MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1":"MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1","MAP_MAGMA_HIDEOUT_4F:0/MAP_MAGMA_HIDEOUT_3F_1R:0":"MAP_MAGMA_HIDEOUT_3F_1R:0/MAP_MAGMA_HIDEOUT_4F:0","MAP_MAGMA_HIDEOUT_4F:1/MAP_MAGMA_HIDEOUT_3F_3R:1":"MAP_MAGMA_HIDEOUT_3F_3R:1/MAP_MAGMA_HIDEOUT_4F:1","MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0":"MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0","MAP_MARINE_CAVE_ENTRANCE:0/MAP_MARINE_CAVE_END:0":"MAP_MARINE_CAVE_END:0/MAP_MARINE_CAVE_ENTRANCE:0","MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0":"MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0","MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1","MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0":"MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2","MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0":"MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3","MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0":"MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4","MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0":"MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5","MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0":"MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6","MAP_MAUVILLE_CITY_BIKE_SHOP:0,1/MAP_MAUVILLE_CITY:2":"MAP_MAUVILLE_CITY:2/MAP_MAUVILLE_CITY_BIKE_SHOP:0","MAP_MAUVILLE_CITY_GAME_CORNER:0,1/MAP_MAUVILLE_CITY:5":"MAP_MAUVILLE_CITY:5/MAP_MAUVILLE_CITY_GAME_CORNER:0","MAP_MAUVILLE_CITY_GYM:0,1/MAP_MAUVILLE_CITY:0":"MAP_MAUVILLE_CITY:0/MAP_MAUVILLE_CITY_GYM:0","MAP_MAUVILLE_CITY_HOUSE1:0,1/MAP_MAUVILLE_CITY:4":"MAP_MAUVILLE_CITY:4/MAP_MAUVILLE_CITY_HOUSE1:0","MAP_MAUVILLE_CITY_HOUSE2:0,1/MAP_MAUVILLE_CITY:6":"MAP_MAUVILLE_CITY:6/MAP_MAUVILLE_CITY_HOUSE2:0","MAP_MAUVILLE_CITY_MART:0,1/MAP_MAUVILLE_CITY:3":"MAP_MAUVILLE_CITY:3/MAP_MAUVILLE_CITY_MART:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0,1/MAP_MAUVILLE_CITY:1":"MAP_MAUVILLE_CITY:1/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0":"MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0/MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2":"MAP_MAUVILLE_CITY_POKEMON_CENTER_1F:2/MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:0","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MAUVILLE_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0":"MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0","MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0":"MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1","MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0":"MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2","MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4":"MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3","MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5":"MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4","MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0":"MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5","MAP_METEOR_FALLS_1F_2R:0/MAP_METEOR_FALLS_1F_1R:2":"MAP_METEOR_FALLS_1F_1R:2/MAP_METEOR_FALLS_1F_2R:0","MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0":"MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1","MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1":"MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2","MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2":"MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3","MAP_METEOR_FALLS_B1F_1R:0/MAP_METEOR_FALLS_1F_2R:1":"MAP_METEOR_FALLS_1F_2R:1/MAP_METEOR_FALLS_B1F_1R:0","MAP_METEOR_FALLS_B1F_1R:1/MAP_METEOR_FALLS_1F_2R:2":"MAP_METEOR_FALLS_1F_2R:2/MAP_METEOR_FALLS_B1F_1R:1","MAP_METEOR_FALLS_B1F_1R:2/MAP_METEOR_FALLS_1F_2R:3":"MAP_METEOR_FALLS_1F_2R:3/MAP_METEOR_FALLS_B1F_1R:2","MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0":"MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3","MAP_METEOR_FALLS_B1F_1R:4/MAP_METEOR_FALLS_1F_1R:3":"MAP_METEOR_FALLS_1F_1R:3/MAP_METEOR_FALLS_B1F_1R:4","MAP_METEOR_FALLS_B1F_1R:5/MAP_METEOR_FALLS_1F_1R:4":"MAP_METEOR_FALLS_1F_1R:4/MAP_METEOR_FALLS_B1F_1R:5","MAP_METEOR_FALLS_B1F_2R:0/MAP_METEOR_FALLS_B1F_1R:3":"MAP_METEOR_FALLS_B1F_1R:3/MAP_METEOR_FALLS_B1F_2R:0","MAP_METEOR_FALLS_STEVENS_CAVE:0/MAP_METEOR_FALLS_1F_1R:5":"MAP_METEOR_FALLS_1F_1R:5/MAP_METEOR_FALLS_STEVENS_CAVE:0","MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3":"MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0","MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1":"MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1","MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0":"MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0","MAP_MIRAGE_TOWER_2F:1/MAP_MIRAGE_TOWER_1F:1":"MAP_MIRAGE_TOWER_1F:1/MAP_MIRAGE_TOWER_2F:1","MAP_MIRAGE_TOWER_3F:0/MAP_MIRAGE_TOWER_2F:0":"MAP_MIRAGE_TOWER_2F:0/MAP_MIRAGE_TOWER_3F:0","MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0":"MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1","MAP_MIRAGE_TOWER_4F:0/MAP_MIRAGE_TOWER_3F:1":"MAP_MIRAGE_TOWER_3F:1/MAP_MIRAGE_TOWER_4F:0","MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0":"MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0","MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0":"MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1","MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2","MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0":"MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3","MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0":"MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4","MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0":"MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5","MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0":"MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6","MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1":"MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7","MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8","MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0,1/MAP_MOSSDEEP_CITY:9":"MAP_MOSSDEEP_CITY:9/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:0","MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0":"MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2","MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0/MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2":"MAP_MOSSDEEP_CITY_GAME_CORNER_1F:2/MAP_MOSSDEEP_CITY_GAME_CORNER_B1F:0","MAP_MOSSDEEP_CITY_GYM:0,1/MAP_MOSSDEEP_CITY:1":"MAP_MOSSDEEP_CITY:1/MAP_MOSSDEEP_CITY_GYM:0","MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11":"MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10","MAP_MOSSDEEP_CITY_GYM:11/MAP_MOSSDEEP_CITY_GYM:10":"MAP_MOSSDEEP_CITY_GYM:10/MAP_MOSSDEEP_CITY_GYM:11","MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13":"MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12","MAP_MOSSDEEP_CITY_GYM:13/MAP_MOSSDEEP_CITY_GYM:12":"MAP_MOSSDEEP_CITY_GYM:12/MAP_MOSSDEEP_CITY_GYM:13","MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3":"MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2","MAP_MOSSDEEP_CITY_GYM:3/MAP_MOSSDEEP_CITY_GYM:2":"MAP_MOSSDEEP_CITY_GYM:2/MAP_MOSSDEEP_CITY_GYM:3","MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5":"MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4","MAP_MOSSDEEP_CITY_GYM:5/MAP_MOSSDEEP_CITY_GYM:4":"MAP_MOSSDEEP_CITY_GYM:4/MAP_MOSSDEEP_CITY_GYM:5","MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7":"MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6","MAP_MOSSDEEP_CITY_GYM:7/MAP_MOSSDEEP_CITY_GYM:6":"MAP_MOSSDEEP_CITY_GYM:6/MAP_MOSSDEEP_CITY_GYM:7","MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9":"MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8","MAP_MOSSDEEP_CITY_GYM:9/MAP_MOSSDEEP_CITY_GYM:8":"MAP_MOSSDEEP_CITY_GYM:8/MAP_MOSSDEEP_CITY_GYM:9","MAP_MOSSDEEP_CITY_HOUSE1:0,1/MAP_MOSSDEEP_CITY:0":"MAP_MOSSDEEP_CITY:0/MAP_MOSSDEEP_CITY_HOUSE1:0","MAP_MOSSDEEP_CITY_HOUSE2:0,1/MAP_MOSSDEEP_CITY:3":"MAP_MOSSDEEP_CITY:3/MAP_MOSSDEEP_CITY_HOUSE2:0","MAP_MOSSDEEP_CITY_HOUSE3:0,1/MAP_MOSSDEEP_CITY:5":"MAP_MOSSDEEP_CITY:5/MAP_MOSSDEEP_CITY_HOUSE3:0","MAP_MOSSDEEP_CITY_HOUSE4:0,1/MAP_MOSSDEEP_CITY:7":"MAP_MOSSDEEP_CITY:7/MAP_MOSSDEEP_CITY_HOUSE4:1","MAP_MOSSDEEP_CITY_MART:0,1/MAP_MOSSDEEP_CITY:4":"MAP_MOSSDEEP_CITY:4/MAP_MOSSDEEP_CITY_MART:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:2":"MAP_MOSSDEEP_CITY:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0/MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2":"MAP_MOSSDEEP_CITY_POKEMON_CENTER_1F:2/MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:0","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0,1/MAP_MOSSDEEP_CITY:8":"MAP_MOSSDEEP_CITY:8/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:0","MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0":"MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2","MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0/MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2":"MAP_MOSSDEEP_CITY_SPACE_CENTER_1F:2/MAP_MOSSDEEP_CITY_SPACE_CENTER_2F:0","MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0,1/MAP_MOSSDEEP_CITY:6":"MAP_MOSSDEEP_CITY:6/MAP_MOSSDEEP_CITY_STEVENS_HOUSE:0","MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1":"MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1","MAP_MT_CHIMNEY:2,3/MAP_JAGGED_PASS:2,3":"MAP_JAGGED_PASS:2,3/MAP_MT_CHIMNEY:2,3","MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1/MAP_MT_CHIMNEY:0,1":"MAP_MT_CHIMNEY:0,1/MAP_MT_CHIMNEY_CABLE_CAR_STATION:0,1","MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0":"MAP_ROUTE122:0/MAP_MT_PYRE_1F:0","MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0":"MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1","MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0":"MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4","MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4":"MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5","MAP_MT_PYRE_2F:0/MAP_MT_PYRE_1F:4":"MAP_MT_PYRE_1F:4/MAP_MT_PYRE_2F:0","MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0":"MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1","MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4":"MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2","MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5":"MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3","MAP_MT_PYRE_2F:4/MAP_MT_PYRE_1F:5":"MAP_MT_PYRE_1F:5/MAP_MT_PYRE_2F:4","MAP_MT_PYRE_3F:0/MAP_MT_PYRE_2F:1":"MAP_MT_PYRE_2F:1/MAP_MT_PYRE_3F:0","MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1":"MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1","MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4":"MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2","MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5":"MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3","MAP_MT_PYRE_3F:4/MAP_MT_PYRE_2F:2":"MAP_MT_PYRE_2F:2/MAP_MT_PYRE_3F:4","MAP_MT_PYRE_3F:5/MAP_MT_PYRE_2F:3":"MAP_MT_PYRE_2F:3/MAP_MT_PYRE_3F:5","MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1":"MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0","MAP_MT_PYRE_4F:1/MAP_MT_PYRE_3F:1":"MAP_MT_PYRE_3F:1/MAP_MT_PYRE_4F:1","MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3":"MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2","MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4":"MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3","MAP_MT_PYRE_4F:4/MAP_MT_PYRE_3F:2":"MAP_MT_PYRE_3F:2/MAP_MT_PYRE_4F:4","MAP_MT_PYRE_4F:5/MAP_MT_PYRE_3F:3":"MAP_MT_PYRE_3F:3/MAP_MT_PYRE_4F:5","MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0":"MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0","MAP_MT_PYRE_5F:1/MAP_MT_PYRE_4F:0":"MAP_MT_PYRE_4F:0/MAP_MT_PYRE_5F:1","MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1":"MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2","MAP_MT_PYRE_5F:3/MAP_MT_PYRE_4F:2":"MAP_MT_PYRE_4F:2/MAP_MT_PYRE_5F:3","MAP_MT_PYRE_5F:4/MAP_MT_PYRE_4F:3":"MAP_MT_PYRE_4F:3/MAP_MT_PYRE_5F:4","MAP_MT_PYRE_6F:0/MAP_MT_PYRE_5F:0":"MAP_MT_PYRE_5F:0/MAP_MT_PYRE_6F:0","MAP_MT_PYRE_6F:1/MAP_MT_PYRE_5F:2":"MAP_MT_PYRE_5F:2/MAP_MT_PYRE_6F:1","MAP_MT_PYRE_EXTERIOR:0/MAP_MT_PYRE_1F:1":"MAP_MT_PYRE_1F:1,3/MAP_MT_PYRE_EXTERIOR:0","MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1":"MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1","MAP_MT_PYRE_SUMMIT:0,1,2/MAP_MT_PYRE_EXTERIOR:1":"MAP_MT_PYRE_EXTERIOR:1,2/MAP_MT_PYRE_SUMMIT:1","MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0":"MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0","MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1":"MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1","MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0":"MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0","MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2":"MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0","MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0":"MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1","MAP_NAVEL_ROCK_DOWN02:0/MAP_NAVEL_ROCK_DOWN01:1":"MAP_NAVEL_ROCK_DOWN01:1/MAP_NAVEL_ROCK_DOWN02:0","MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0":"MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1","MAP_NAVEL_ROCK_DOWN03:0/MAP_NAVEL_ROCK_DOWN02:1":"MAP_NAVEL_ROCK_DOWN02:1/MAP_NAVEL_ROCK_DOWN03:0","MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0":"MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1","MAP_NAVEL_ROCK_DOWN04:0/MAP_NAVEL_ROCK_DOWN03:1":"MAP_NAVEL_ROCK_DOWN03:1/MAP_NAVEL_ROCK_DOWN04:0","MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0":"MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1","MAP_NAVEL_ROCK_DOWN05:0/MAP_NAVEL_ROCK_DOWN04:1":"MAP_NAVEL_ROCK_DOWN04:1/MAP_NAVEL_ROCK_DOWN05:0","MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0":"MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1","MAP_NAVEL_ROCK_DOWN06:0/MAP_NAVEL_ROCK_DOWN05:1":"MAP_NAVEL_ROCK_DOWN05:1/MAP_NAVEL_ROCK_DOWN06:0","MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0":"MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1","MAP_NAVEL_ROCK_DOWN07:0/MAP_NAVEL_ROCK_DOWN06:1":"MAP_NAVEL_ROCK_DOWN06:1/MAP_NAVEL_ROCK_DOWN07:0","MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0":"MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1","MAP_NAVEL_ROCK_DOWN08:0/MAP_NAVEL_ROCK_DOWN07:1":"MAP_NAVEL_ROCK_DOWN07:1/MAP_NAVEL_ROCK_DOWN08:0","MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0":"MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1","MAP_NAVEL_ROCK_DOWN09:0/MAP_NAVEL_ROCK_DOWN08:1":"MAP_NAVEL_ROCK_DOWN08:1/MAP_NAVEL_ROCK_DOWN09:0","MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0":"MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1","MAP_NAVEL_ROCK_DOWN10:0/MAP_NAVEL_ROCK_DOWN09:1":"MAP_NAVEL_ROCK_DOWN09:1/MAP_NAVEL_ROCK_DOWN10:0","MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1":"MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1","MAP_NAVEL_ROCK_DOWN11:0/MAP_NAVEL_ROCK_BOTTOM:0":"MAP_NAVEL_ROCK_BOTTOM:0/MAP_NAVEL_ROCK_DOWN11:0","MAP_NAVEL_ROCK_DOWN11:1/MAP_NAVEL_ROCK_DOWN10:1":"MAP_NAVEL_ROCK_DOWN10:1/MAP_NAVEL_ROCK_DOWN11:1","MAP_NAVEL_ROCK_ENTRANCE:0/MAP_NAVEL_ROCK_B1F:0":"MAP_NAVEL_ROCK_B1F:0/MAP_NAVEL_ROCK_ENTRANCE:0","MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1":"MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1","MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0":"MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0","MAP_NAVEL_ROCK_EXTERIOR:1/MAP_NAVEL_ROCK_ENTRANCE:1":"MAP_NAVEL_ROCK_ENTRANCE:1/MAP_NAVEL_ROCK_EXTERIOR:1","MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0":"MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0","MAP_NAVEL_ROCK_FORK:1/MAP_NAVEL_ROCK_B1F:1":"MAP_NAVEL_ROCK_B1F:1/MAP_NAVEL_ROCK_FORK:1","MAP_NAVEL_ROCK_FORK:2/MAP_NAVEL_ROCK_DOWN01:0":"MAP_NAVEL_ROCK_DOWN01:0/MAP_NAVEL_ROCK_FORK:2","MAP_NAVEL_ROCK_HARBOR:0/MAP_NAVEL_ROCK_EXTERIOR:0":"MAP_NAVEL_ROCK_EXTERIOR:0/MAP_NAVEL_ROCK_HARBOR:0","MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1":"MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0","MAP_NAVEL_ROCK_UP1:0/MAP_NAVEL_ROCK_FORK:0":"MAP_NAVEL_ROCK_FORK:0/MAP_NAVEL_ROCK_UP1:0","MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0":"MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1","MAP_NAVEL_ROCK_UP2:0/MAP_NAVEL_ROCK_UP1:1":"MAP_NAVEL_ROCK_UP1:1/MAP_NAVEL_ROCK_UP2:0","MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0":"MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1","MAP_NAVEL_ROCK_UP3:0/MAP_NAVEL_ROCK_UP2:1":"MAP_NAVEL_ROCK_UP2:1/MAP_NAVEL_ROCK_UP3:0","MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0":"MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1","MAP_NAVEL_ROCK_UP4:0/MAP_NAVEL_ROCK_UP3:1":"MAP_NAVEL_ROCK_UP3:1/MAP_NAVEL_ROCK_UP4:0","MAP_NAVEL_ROCK_UP4:1/MAP_NAVEL_ROCK_TOP:0":"MAP_NAVEL_ROCK_TOP:0/MAP_NAVEL_ROCK_UP4:1","MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0":"MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0","MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0":"MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1","MAP_NEW_MAUVILLE_INSIDE:0/MAP_NEW_MAUVILLE_ENTRANCE:1":"MAP_NEW_MAUVILLE_ENTRANCE:1/MAP_NEW_MAUVILLE_INSIDE:0","MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0":"MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0","MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0":"MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1","MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2","MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0":"MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3","MAP_OLDALE_TOWN_HOUSE1:0,1/MAP_OLDALE_TOWN:0":"MAP_OLDALE_TOWN:0/MAP_OLDALE_TOWN_HOUSE1:0","MAP_OLDALE_TOWN_HOUSE2:0,1/MAP_OLDALE_TOWN:1":"MAP_OLDALE_TOWN:1/MAP_OLDALE_TOWN_HOUSE2:0","MAP_OLDALE_TOWN_MART:0,1/MAP_OLDALE_TOWN:3":"MAP_OLDALE_TOWN:3/MAP_OLDALE_TOWN_MART:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0,1/MAP_OLDALE_TOWN:2":"MAP_OLDALE_TOWN:2/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0":"MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0/MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2":"MAP_OLDALE_TOWN_POKEMON_CENTER_1F:2/MAP_OLDALE_TOWN_POKEMON_CENTER_2F:0","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_OLDALE_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0","MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0":"MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1","MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0":"MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2","MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0":"MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3","MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0":"MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4","MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0":"MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5","MAP_PACIFIDLOG_TOWN_HOUSE1:0,1/MAP_PACIFIDLOG_TOWN:1":"MAP_PACIFIDLOG_TOWN:1/MAP_PACIFIDLOG_TOWN_HOUSE1:0","MAP_PACIFIDLOG_TOWN_HOUSE2:0,1/MAP_PACIFIDLOG_TOWN:2":"MAP_PACIFIDLOG_TOWN:2/MAP_PACIFIDLOG_TOWN_HOUSE2:0","MAP_PACIFIDLOG_TOWN_HOUSE3:0,1/MAP_PACIFIDLOG_TOWN:3":"MAP_PACIFIDLOG_TOWN:3/MAP_PACIFIDLOG_TOWN_HOUSE3:0","MAP_PACIFIDLOG_TOWN_HOUSE4:0,1/MAP_PACIFIDLOG_TOWN:4":"MAP_PACIFIDLOG_TOWN:4/MAP_PACIFIDLOG_TOWN_HOUSE4:0","MAP_PACIFIDLOG_TOWN_HOUSE5:0,1/MAP_PACIFIDLOG_TOWN:5":"MAP_PACIFIDLOG_TOWN:5/MAP_PACIFIDLOG_TOWN_HOUSE5:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0,1/MAP_PACIFIDLOG_TOWN:0":"MAP_PACIFIDLOG_TOWN:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2":"MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_1F:2/MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:0","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PACIFIDLOG_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0":"MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0","MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0":"MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1","MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0":"MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2","MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3","MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0":"MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4","MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0":"MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5","MAP_PETALBURG_CITY_GYM:0,1/MAP_PETALBURG_CITY:2":"MAP_PETALBURG_CITY:2/MAP_PETALBURG_CITY_GYM:0","MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8":"MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10","MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9":"MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12","MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16":"MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14","MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18":"MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15","MAP_PETALBURG_CITY_GYM:16,17/MAP_PETALBURG_CITY_GYM:14":"MAP_PETALBURG_CITY_GYM:14/MAP_PETALBURG_CITY_GYM:16","MAP_PETALBURG_CITY_GYM:18,19/MAP_PETALBURG_CITY_GYM:15":"MAP_PETALBURG_CITY_GYM:15/MAP_PETALBURG_CITY_GYM:18","MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3":"MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2","MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24":"MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20","MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26":"MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21","MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28":"MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22","MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30":"MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23","MAP_PETALBURG_CITY_GYM:24,25/MAP_PETALBURG_CITY_GYM:20":"MAP_PETALBURG_CITY_GYM:20/MAP_PETALBURG_CITY_GYM:24","MAP_PETALBURG_CITY_GYM:26,27/MAP_PETALBURG_CITY_GYM:21":"MAP_PETALBURG_CITY_GYM:21/MAP_PETALBURG_CITY_GYM:26","MAP_PETALBURG_CITY_GYM:28,29/MAP_PETALBURG_CITY_GYM:22":"MAP_PETALBURG_CITY_GYM:22/MAP_PETALBURG_CITY_GYM:28","MAP_PETALBURG_CITY_GYM:3,4/MAP_PETALBURG_CITY_GYM:2":"MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3","MAP_PETALBURG_CITY_GYM:30,31/MAP_PETALBURG_CITY_GYM:23":"MAP_PETALBURG_CITY_GYM:23/MAP_PETALBURG_CITY_GYM:30","MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34":"MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32","MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36":"MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33","MAP_PETALBURG_CITY_GYM:34,35/MAP_PETALBURG_CITY_GYM:32":"MAP_PETALBURG_CITY_GYM:32/MAP_PETALBURG_CITY_GYM:34","MAP_PETALBURG_CITY_GYM:36,37/MAP_PETALBURG_CITY_GYM:33":"MAP_PETALBURG_CITY_GYM:33/MAP_PETALBURG_CITY_GYM:36","MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6":"MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5","MAP_PETALBURG_CITY_GYM:6,7/MAP_PETALBURG_CITY_GYM:5":"MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6","MAP_PETALBURG_CITY_GYM:8/MAP_PETALBURG_CITY_GYM:10":"MAP_PETALBURG_CITY_GYM:10,11/MAP_PETALBURG_CITY_GYM:8","MAP_PETALBURG_CITY_GYM:9/MAP_PETALBURG_CITY_GYM:12":"MAP_PETALBURG_CITY_GYM:12,13/MAP_PETALBURG_CITY_GYM:9","MAP_PETALBURG_CITY_HOUSE1:0,1/MAP_PETALBURG_CITY:0":"MAP_PETALBURG_CITY:0/MAP_PETALBURG_CITY_HOUSE1:0","MAP_PETALBURG_CITY_HOUSE2:0,1/MAP_PETALBURG_CITY:4":"MAP_PETALBURG_CITY:4/MAP_PETALBURG_CITY_HOUSE2:0","MAP_PETALBURG_CITY_MART:0,1/MAP_PETALBURG_CITY:5":"MAP_PETALBURG_CITY:5/MAP_PETALBURG_CITY_MART:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0,1/MAP_PETALBURG_CITY:3":"MAP_PETALBURG_CITY:3/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0":"MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0/MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2":"MAP_PETALBURG_CITY_POKEMON_CENTER_1F:2/MAP_PETALBURG_CITY_POKEMON_CENTER_2F:0","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_PETALBURG_CITY_WALLYS_HOUSE:0,1/MAP_PETALBURG_CITY:1":"MAP_PETALBURG_CITY:1/MAP_PETALBURG_CITY_WALLYS_HOUSE:0","MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3":"MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1","MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5":"MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3","MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7":"MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5","MAP_RECORD_CORNER:0,1,2,3/MAP_DYNAMIC:-1!":"","MAP_ROUTE103:0/MAP_ALTERING_CAVE:0":"MAP_ALTERING_CAVE:0/MAP_ROUTE103:0","MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0":"MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0","MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0":"MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1","MAP_ROUTE104:2,3/MAP_PETALBURG_WOODS:0,1":"MAP_PETALBURG_WOODS:0,1/MAP_ROUTE104:2,3","MAP_ROUTE104:4,5/MAP_PETALBURG_WOODS:2,3":"MAP_PETALBURG_WOODS:2,3/MAP_ROUTE104:4,5","MAP_ROUTE104:6,7/MAP_PETALBURG_WOODS:4,5":"MAP_PETALBURG_WOODS:4,5/MAP_ROUTE104:6,7","MAP_ROUTE104_MR_BRINEYS_HOUSE:0,1/MAP_ROUTE104:0":"MAP_ROUTE104:0/MAP_ROUTE104_MR_BRINEYS_HOUSE:0","MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0,1/MAP_ROUTE104:1":"MAP_ROUTE104:1/MAP_ROUTE104_PRETTY_PETAL_FLOWER_SHOP:0","MAP_ROUTE105:0/MAP_ISLAND_CAVE:0":"MAP_ISLAND_CAVE:0/MAP_ROUTE105:0","MAP_ROUTE106:0/MAP_GRANITE_CAVE_1F:0":"MAP_GRANITE_CAVE_1F:0/MAP_ROUTE106:0","MAP_ROUTE108:0/MAP_ABANDONED_SHIP_DECK:0":"MAP_ABANDONED_SHIP_DECK:0,1/MAP_ROUTE108:0","MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0":"MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0","MAP_ROUTE109_SEASHORE_HOUSE:0,1/MAP_ROUTE109:0":"MAP_ROUTE109:0/MAP_ROUTE109_SEASHORE_HOUSE:0","MAP_ROUTE110:0/MAP_NEW_MAUVILLE_ENTRANCE:0":"MAP_NEW_MAUVILLE_ENTRANCE:0/MAP_ROUTE110:0","MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1","MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2","MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3","MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4","MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2":"MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0,1/MAP_ROUTE110:4":"MAP_ROUTE110:4/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2,3/MAP_ROUTE110:5":"MAP_ROUTE110:5/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE:2","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0,1/MAP_ROUTE110:2":"MAP_ROUTE110:2/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:0","MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2,3/MAP_ROUTE110:3":"MAP_ROUTE110:3/MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1":"MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0","MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:2,3/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0","MAP_ROUTE110_TRICK_HOUSE_END:1/MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0":"MAP_ROUTE110_TRICK_HOUSE_CORRIDOR:0,1/MAP_ROUTE110_TRICK_HOUSE_END:1","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0,1/MAP_ROUTE110:1":"MAP_ROUTE110:1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:0","MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2/MAP_ROUTE110_TRICK_HOUSE_END:0":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE2:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE3:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE4:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE5:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE6:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:11/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:12","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:3/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:4","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:5/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:6","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:7/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:8","MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10":"MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:10/MAP_ROUTE110_TRICK_HOUSE_PUZZLE7:9","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:0,1/MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2!":"MAP_ROUTE110_TRICK_HOUSE_ENTRANCE:2/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:0","MAP_ROUTE110_TRICK_HOUSE_PUZZLE8:2/MAP_ROUTE110_TRICK_HOUSE_END:0!":"MAP_ROUTE110_TRICK_HOUSE_END:0/MAP_ROUTE110_TRICK_HOUSE_PUZZLE1:2","MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0":"MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0","MAP_ROUTE111:1/MAP_DESERT_RUINS:0":"MAP_DESERT_RUINS:0/MAP_ROUTE111:1","MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0":"MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2","MAP_ROUTE111:3/MAP_MIRAGE_TOWER_1F:0":"MAP_MIRAGE_TOWER_1F:0/MAP_ROUTE111:3","MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0":"MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4","MAP_ROUTE111_OLD_LADYS_REST_STOP:0,1/MAP_ROUTE111:2":"MAP_ROUTE111:2/MAP_ROUTE111_OLD_LADYS_REST_STOP:0","MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0,1/MAP_ROUTE111:0":"MAP_ROUTE111:0/MAP_ROUTE111_WINSTRATE_FAMILYS_HOUSE:0","MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1":"MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1","MAP_ROUTE112:2,3/MAP_JAGGED_PASS:0,1":"MAP_JAGGED_PASS:0,1/MAP_ROUTE112:2,3","MAP_ROUTE112:4/MAP_FIERY_PATH:0":"MAP_FIERY_PATH:0/MAP_ROUTE112:4","MAP_ROUTE112:5/MAP_FIERY_PATH:1":"MAP_FIERY_PATH:1/MAP_ROUTE112:5","MAP_ROUTE112_CABLE_CAR_STATION:0,1/MAP_ROUTE112:0,1":"MAP_ROUTE112:0,1/MAP_ROUTE112_CABLE_CAR_STATION:0,1","MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0":"MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0","MAP_ROUTE113:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE113_GLASS_WORKSHOP:0,1/MAP_ROUTE113:0":"MAP_ROUTE113:0/MAP_ROUTE113_GLASS_WORKSHOP:0","MAP_ROUTE114:0/MAP_METEOR_FALLS_1F_1R:0":"MAP_METEOR_FALLS_1F_1R:0/MAP_ROUTE114:0","MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1","MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0":"MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2","MAP_ROUTE114:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0,1/MAP_ROUTE114:1":"MAP_ROUTE114:1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:0","MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0":"MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0,1/MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2":"MAP_ROUTE114_FOSSIL_MANIACS_HOUSE:2/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:0","MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2/MAP_DESERT_UNDERPASS:0":"MAP_DESERT_UNDERPASS:0/MAP_ROUTE114_FOSSIL_MANIACS_TUNNEL:2","MAP_ROUTE114_LANETTES_HOUSE:0,1/MAP_ROUTE114:2":"MAP_ROUTE114:2/MAP_ROUTE114_LANETTES_HOUSE:0","MAP_ROUTE115:0/MAP_METEOR_FALLS_1F_1R:1":"MAP_METEOR_FALLS_1F_1R:1/MAP_ROUTE115:0","MAP_ROUTE115:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE115:2/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0":"MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0","MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0":"MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1","MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2":"MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2","MAP_ROUTE116:3/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116:4/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE116_TUNNELERS_REST_HOUSE:0,1/MAP_ROUTE116:1":"MAP_ROUTE116:1/MAP_ROUTE116_TUNNELERS_REST_HOUSE:0","MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0":"MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0","MAP_ROUTE117_POKEMON_DAY_CARE:0,1/MAP_ROUTE117:0":"MAP_ROUTE117:0/MAP_ROUTE117_POKEMON_DAY_CARE:0","MAP_ROUTE118:0/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE118:1/MAP_TERRA_CAVE_ENTRANCE:0!":"MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!","MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0","MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0":"MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1","MAP_ROUTE119_HOUSE:0,1/MAP_ROUTE119:1":"MAP_ROUTE119:1/MAP_ROUTE119_HOUSE:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:0,1/MAP_ROUTE119:0":"MAP_ROUTE119:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:0","MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0":"MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2","MAP_ROUTE119_WEATHER_INSTITUTE_2F:0/MAP_ROUTE119_WEATHER_INSTITUTE_1F:2":"MAP_ROUTE119_WEATHER_INSTITUTE_1F:2/MAP_ROUTE119_WEATHER_INSTITUTE_2F:0","MAP_ROUTE120:0/MAP_ANCIENT_TOMB:0":"MAP_ANCIENT_TOMB:0/MAP_ROUTE120:0","MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0":"MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1","MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0":"MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0","MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2,3/MAP_ROUTE121:0":"MAP_ROUTE121:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:2","MAP_ROUTE122:0/MAP_MT_PYRE_1F:0":"MAP_MT_PYRE_1F:0,2/MAP_ROUTE122:0","MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0":"MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0","MAP_ROUTE123_BERRY_MASTERS_HOUSE:0,1/MAP_ROUTE123:0":"MAP_ROUTE123:0/MAP_ROUTE123_BERRY_MASTERS_HOUSE:0","MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0":"MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0","MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0,1/MAP_ROUTE124:0":"MAP_ROUTE124:0/MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE:0","MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0","MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0":"MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0","MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0":"MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0","MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0":"MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1","MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0":"MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10","MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0":"MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11","MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0":"MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2","MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3","MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0":"MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4","MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6","MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0":"MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7","MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0":"MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8","MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0":"MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9","MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0,1/MAP_RUSTBORO_CITY:8":"MAP_RUSTBORO_CITY:8/MAP_RUSTBORO_CITY_CUTTERS_HOUSE:0","MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1/MAP_RUSTBORO_CITY:5,6":"MAP_RUSTBORO_CITY:5,6/MAP_RUSTBORO_CITY_DEVON_CORP_1F:0,1","MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2","MAP_RUSTBORO_CITY_DEVON_CORP_2F:0/MAP_RUSTBORO_CITY_DEVON_CORP_1F:2":"MAP_RUSTBORO_CITY_DEVON_CORP_1F:2/MAP_RUSTBORO_CITY_DEVON_CORP_2F:0","MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0":"MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1","MAP_RUSTBORO_CITY_DEVON_CORP_3F:0/MAP_RUSTBORO_CITY_DEVON_CORP_2F:1":"MAP_RUSTBORO_CITY_DEVON_CORP_2F:1/MAP_RUSTBORO_CITY_DEVON_CORP_3F:0","MAP_RUSTBORO_CITY_FLAT1_1F:0,1/MAP_RUSTBORO_CITY:1":"MAP_RUSTBORO_CITY:1/MAP_RUSTBORO_CITY_FLAT1_1F:0","MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0":"MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2","MAP_RUSTBORO_CITY_FLAT1_2F:0/MAP_RUSTBORO_CITY_FLAT1_1F:2":"MAP_RUSTBORO_CITY_FLAT1_1F:2/MAP_RUSTBORO_CITY_FLAT1_2F:0","MAP_RUSTBORO_CITY_FLAT2_1F:0,1/MAP_RUSTBORO_CITY:10":"MAP_RUSTBORO_CITY:10/MAP_RUSTBORO_CITY_FLAT2_1F:0","MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0":"MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2","MAP_RUSTBORO_CITY_FLAT2_2F:0/MAP_RUSTBORO_CITY_FLAT2_1F:2":"MAP_RUSTBORO_CITY_FLAT2_1F:2/MAP_RUSTBORO_CITY_FLAT2_2F:0","MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0":"MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1","MAP_RUSTBORO_CITY_FLAT2_3F:0/MAP_RUSTBORO_CITY_FLAT2_2F:1":"MAP_RUSTBORO_CITY_FLAT2_2F:1/MAP_RUSTBORO_CITY_FLAT2_3F:0","MAP_RUSTBORO_CITY_GYM:0,1/MAP_RUSTBORO_CITY:0":"MAP_RUSTBORO_CITY:0/MAP_RUSTBORO_CITY_GYM:0","MAP_RUSTBORO_CITY_HOUSE1:0,1/MAP_RUSTBORO_CITY:7":"MAP_RUSTBORO_CITY:7/MAP_RUSTBORO_CITY_HOUSE1:0","MAP_RUSTBORO_CITY_HOUSE2:0,1/MAP_RUSTBORO_CITY:9":"MAP_RUSTBORO_CITY:9/MAP_RUSTBORO_CITY_HOUSE2:0","MAP_RUSTBORO_CITY_HOUSE3:0,1/MAP_RUSTBORO_CITY:11":"MAP_RUSTBORO_CITY:11/MAP_RUSTBORO_CITY_HOUSE3:0","MAP_RUSTBORO_CITY_MART:0,1/MAP_RUSTBORO_CITY:2":"MAP_RUSTBORO_CITY:2/MAP_RUSTBORO_CITY_MART:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0,1/MAP_RUSTBORO_CITY:3":"MAP_RUSTBORO_CITY:3/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0":"MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0/MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2":"MAP_RUSTBORO_CITY_POKEMON_CENTER_1F:2/MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:0","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0,1/MAP_RUSTBORO_CITY:4":"MAP_RUSTBORO_CITY:4/MAP_RUSTBORO_CITY_POKEMON_SCHOOL:0","MAP_RUSTURF_TUNNEL:0/MAP_ROUTE116:0":"MAP_ROUTE116:0/MAP_RUSTURF_TUNNEL:0","MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4":"MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1","MAP_RUSTURF_TUNNEL:2/MAP_ROUTE116:2":"MAP_ROUTE116:2/MAP_RUSTURF_TUNNEL:2","MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0":"MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0","MAP_SAFARI_ZONE_SOUTH:0/MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0":"MAP_ROUTE121_SAFARI_ZONE_ENTRANCE:0,1/MAP_SAFARI_ZONE_SOUTH:0","MAP_SAFARI_ZONE_SOUTHWEST:0/MAP_SAFARI_ZONE_REST_HOUSE:0":"MAP_SAFARI_ZONE_REST_HOUSE:0,1/MAP_SAFARI_ZONE_SOUTHWEST:0","MAP_SCORCHED_SLAB:0/MAP_ROUTE120:1":"MAP_ROUTE120:1/MAP_SCORCHED_SLAB:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:0/MAP_UNDERWATER_ROUTE128:0!":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0":"MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1","MAP_SEAFLOOR_CAVERN_ROOM1:0/MAP_SEAFLOOR_CAVERN_ENTRANCE:1":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0":"MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1","MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0":"MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2","MAP_SEAFLOOR_CAVERN_ROOM2:0/MAP_SEAFLOOR_CAVERN_ROOM1:2":"MAP_SEAFLOOR_CAVERN_ROOM1:2/MAP_SEAFLOOR_CAVERN_ROOM2:0","MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0":"MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1","MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0":"MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2","MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0":"MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3","MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1":"MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0","MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1":"MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1","MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1":"MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2","MAP_SEAFLOOR_CAVERN_ROOM4:0/MAP_SEAFLOOR_CAVERN_ROOM2:1":"MAP_SEAFLOOR_CAVERN_ROOM2:1/MAP_SEAFLOOR_CAVERN_ROOM4:0","MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1":"MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1","MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2":"MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2","MAP_SEAFLOOR_CAVERN_ROOM4:3/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM5:0/MAP_SEAFLOOR_CAVERN_ROOM1:1":"MAP_SEAFLOOR_CAVERN_ROOM1:1/MAP_SEAFLOOR_CAVERN_ROOM5:0","MAP_SEAFLOOR_CAVERN_ROOM5:1/MAP_SEAFLOOR_CAVERN_ROOM4:1":"MAP_SEAFLOOR_CAVERN_ROOM4:1/MAP_SEAFLOOR_CAVERN_ROOM5:1","MAP_SEAFLOOR_CAVERN_ROOM5:2/MAP_SEAFLOOR_CAVERN_ROOM4:2":"MAP_SEAFLOOR_CAVERN_ROOM4:2/MAP_SEAFLOOR_CAVERN_ROOM5:2","MAP_SEAFLOOR_CAVERN_ROOM6:0/MAP_SEAFLOOR_CAVERN_ROOM2:2":"MAP_SEAFLOOR_CAVERN_ROOM2:2/MAP_SEAFLOOR_CAVERN_ROOM6:0","MAP_SEAFLOOR_CAVERN_ROOM6:1/MAP_SEAFLOOR_CAVERN_ROOM3:2":"MAP_SEAFLOOR_CAVERN_ROOM3:2/MAP_SEAFLOOR_CAVERN_ROOM6:1","MAP_SEAFLOOR_CAVERN_ROOM6:2/MAP_SEAFLOOR_CAVERN_ENTRANCE:1!":"MAP_SEAFLOOR_CAVERN_ENTRANCE:1/MAP_SEAFLOOR_CAVERN_ROOM1:0","MAP_SEAFLOOR_CAVERN_ROOM7:0/MAP_SEAFLOOR_CAVERN_ROOM2:3":"MAP_SEAFLOOR_CAVERN_ROOM2:3/MAP_SEAFLOOR_CAVERN_ROOM7:0","MAP_SEAFLOOR_CAVERN_ROOM7:1/MAP_SEAFLOOR_CAVERN_ROOM3:1":"MAP_SEAFLOOR_CAVERN_ROOM3:1/MAP_SEAFLOOR_CAVERN_ROOM7:1","MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0":"MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0","MAP_SEAFLOOR_CAVERN_ROOM8:1/MAP_SEAFLOOR_CAVERN_ROOM3:0":"MAP_SEAFLOOR_CAVERN_ROOM3:0/MAP_SEAFLOOR_CAVERN_ROOM8:1","MAP_SEAFLOOR_CAVERN_ROOM9:0/MAP_SEAFLOOR_CAVERN_ROOM8:0":"MAP_SEAFLOOR_CAVERN_ROOM8:0/MAP_SEAFLOOR_CAVERN_ROOM9:0","MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0":"MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0","MAP_SEALED_CHAMBER_OUTER_ROOM:0/MAP_SEALED_CHAMBER_INNER_ROOM:0":"MAP_SEALED_CHAMBER_INNER_ROOM:0/MAP_SEALED_CHAMBER_OUTER_ROOM:0","MAP_SECRET_BASE_BLUE_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BLUE_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_BROWN_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_RED_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_SHRUB4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_TREE4:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE1:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE2:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE3:0/MAP_DYNAMIC:-2!":"","MAP_SECRET_BASE_YELLOW_CAVE4:0/MAP_DYNAMIC:-2!":"","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0/MAP_ROUTE125:0":"MAP_ROUTE125:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:6","MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7/MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_ENTRANCE_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:7","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:4/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:1","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:5/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:2","MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3/MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0":"MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_LOWER_ROOM:3","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:0","MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1/MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2":"MAP_SHOAL_CAVE_LOW_TIDE_INNER_ROOM:2/MAP_SHOAL_CAVE_LOW_TIDE_STAIRS_ROOM:1","MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1":"MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0","MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0":"MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2","MAP_SKY_PILLAR_2F:0/MAP_SKY_PILLAR_1F:2":"MAP_SKY_PILLAR_1F:2/MAP_SKY_PILLAR_2F:0","MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0":"MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1","MAP_SKY_PILLAR_3F:0/MAP_SKY_PILLAR_2F:1":"MAP_SKY_PILLAR_2F:1/MAP_SKY_PILLAR_3F:0","MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0":"MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1","MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1":"MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2","MAP_SKY_PILLAR_4F:0/MAP_SKY_PILLAR_3F:1":"MAP_SKY_PILLAR_3F:1/MAP_SKY_PILLAR_4F:0","MAP_SKY_PILLAR_4F:1/MAP_SKY_PILLAR_3F:2":"MAP_SKY_PILLAR_3F:2/MAP_SKY_PILLAR_4F:1","MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0":"MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2","MAP_SKY_PILLAR_5F:0/MAP_SKY_PILLAR_4F:2":"MAP_SKY_PILLAR_4F:2/MAP_SKY_PILLAR_5F:0","MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0":"MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1","MAP_SKY_PILLAR_ENTRANCE:0/MAP_ROUTE131:0":"MAP_ROUTE131:0/MAP_SKY_PILLAR_ENTRANCE:0","MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0":"MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1","MAP_SKY_PILLAR_OUTSIDE:0/MAP_SKY_PILLAR_ENTRANCE:1":"MAP_SKY_PILLAR_ENTRANCE:1/MAP_SKY_PILLAR_OUTSIDE:0","MAP_SKY_PILLAR_OUTSIDE:1/MAP_SKY_PILLAR_1F:0":"MAP_SKY_PILLAR_1F:0,1/MAP_SKY_PILLAR_OUTSIDE:1","MAP_SKY_PILLAR_TOP:0/MAP_SKY_PILLAR_5F:1":"MAP_SKY_PILLAR_5F:1/MAP_SKY_PILLAR_TOP:0","MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0","MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0":"MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1","MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0":"MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10","MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2","MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0":"MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3","MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0":"MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4","MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7","MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0":"MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6","MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0":"MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8","MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2":"MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9","MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0,1/MAP_SLATEPORT_CITY:3":"MAP_SLATEPORT_CITY:3/MAP_SLATEPORT_CITY_BATTLE_TENT_LOBBY:0","MAP_SLATEPORT_CITY_HARBOR:0,1/MAP_SLATEPORT_CITY:8":"MAP_SLATEPORT_CITY:8/MAP_SLATEPORT_CITY_HARBOR:0","MAP_SLATEPORT_CITY_HARBOR:2,3/MAP_SLATEPORT_CITY:9":"MAP_SLATEPORT_CITY:9/MAP_SLATEPORT_CITY_HARBOR:2","MAP_SLATEPORT_CITY_HOUSE:0,1/MAP_SLATEPORT_CITY:10":"MAP_SLATEPORT_CITY:10/MAP_SLATEPORT_CITY_HOUSE:0","MAP_SLATEPORT_CITY_MART:0,1/MAP_SLATEPORT_CITY:1":"MAP_SLATEPORT_CITY:1/MAP_SLATEPORT_CITY_MART:0","MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0,1/MAP_SLATEPORT_CITY:6":"MAP_SLATEPORT_CITY:6/MAP_SLATEPORT_CITY_NAME_RATERS_HOUSE:0","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1/MAP_SLATEPORT_CITY:5,7":"MAP_SLATEPORT_CITY:5,7/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:0,1","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2","MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2":"MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_1F:2/MAP_SLATEPORT_CITY_OCEANIC_MUSEUM_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0,1/MAP_SLATEPORT_CITY:0":"MAP_SLATEPORT_CITY:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0":"MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0/MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2":"MAP_SLATEPORT_CITY_POKEMON_CENTER_1F:2/MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:0","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0,1/MAP_SLATEPORT_CITY:4":"MAP_SLATEPORT_CITY:4/MAP_SLATEPORT_CITY_POKEMON_FAN_CLUB:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0,1/MAP_SLATEPORT_CITY:2":"MAP_SLATEPORT_CITY:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:0","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2","MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2":"MAP_SLATEPORT_CITY_STERNS_SHIPYARD_1F:2/MAP_SLATEPORT_CITY_STERNS_SHIPYARD_2F:0","MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0","MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0":"MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1","MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0":"MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10","MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0":"MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11","MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12","MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0":"MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2","MAP_SOOTOPOLIS_CITY:3/MAP_CAVE_OF_ORIGIN_ENTRANCE:0":"MAP_CAVE_OF_ORIGIN_ENTRANCE:0/MAP_SOOTOPOLIS_CITY:3","MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0":"MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4","MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0":"MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5","MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0":"MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6","MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0":"MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7","MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0":"MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8","MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0":"MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9","MAP_SOOTOPOLIS_CITY_GYM_1F:0,1/MAP_SOOTOPOLIS_CITY:2":"MAP_SOOTOPOLIS_CITY:2/MAP_SOOTOPOLIS_CITY_GYM_1F:0","MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0":"MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2","MAP_SOOTOPOLIS_CITY_GYM_B1F:0/MAP_SOOTOPOLIS_CITY_GYM_1F:2":"MAP_SOOTOPOLIS_CITY_GYM_1F:2/MAP_SOOTOPOLIS_CITY_GYM_B1F:0","MAP_SOOTOPOLIS_CITY_HOUSE1:0,1/MAP_SOOTOPOLIS_CITY:4":"MAP_SOOTOPOLIS_CITY:4/MAP_SOOTOPOLIS_CITY_HOUSE1:0","MAP_SOOTOPOLIS_CITY_HOUSE2:0,1/MAP_SOOTOPOLIS_CITY:5":"MAP_SOOTOPOLIS_CITY:5/MAP_SOOTOPOLIS_CITY_HOUSE2:0","MAP_SOOTOPOLIS_CITY_HOUSE3:0,1/MAP_SOOTOPOLIS_CITY:6":"MAP_SOOTOPOLIS_CITY:6/MAP_SOOTOPOLIS_CITY_HOUSE3:0","MAP_SOOTOPOLIS_CITY_HOUSE4:0,1/MAP_SOOTOPOLIS_CITY:7":"MAP_SOOTOPOLIS_CITY:7/MAP_SOOTOPOLIS_CITY_HOUSE4:0","MAP_SOOTOPOLIS_CITY_HOUSE5:0,1/MAP_SOOTOPOLIS_CITY:8":"MAP_SOOTOPOLIS_CITY:8/MAP_SOOTOPOLIS_CITY_HOUSE5:0","MAP_SOOTOPOLIS_CITY_HOUSE6:0,1/MAP_SOOTOPOLIS_CITY:9":"MAP_SOOTOPOLIS_CITY:9/MAP_SOOTOPOLIS_CITY_HOUSE6:0","MAP_SOOTOPOLIS_CITY_HOUSE7:0,1/MAP_SOOTOPOLIS_CITY:10":"MAP_SOOTOPOLIS_CITY:10/MAP_SOOTOPOLIS_CITY_HOUSE7:0","MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0,1/MAP_SOOTOPOLIS_CITY:11":"MAP_SOOTOPOLIS_CITY:11/MAP_SOOTOPOLIS_CITY_LOTAD_AND_SEEDOT_HOUSE:0","MAP_SOOTOPOLIS_CITY_MART:0,1/MAP_SOOTOPOLIS_CITY:1":"MAP_SOOTOPOLIS_CITY:1/MAP_SOOTOPOLIS_CITY_MART:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0,1/MAP_SOOTOPOLIS_CITY:12":"MAP_SOOTOPOLIS_CITY:12/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:0","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2","MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2":"MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_1F:2/MAP_SOOTOPOLIS_CITY_MYSTERY_EVENTS_HOUSE_B1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0,1/MAP_SOOTOPOLIS_CITY:0":"MAP_SOOTOPOLIS_CITY:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2":"MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_1F:2/MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:0","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_SOOTOPOLIS_CITY_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1":"MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1","MAP_SOUTHERN_ISLAND_INTERIOR:0,1/MAP_SOUTHERN_ISLAND_EXTERIOR:0,1":"MAP_SOUTHERN_ISLAND_EXTERIOR:0,1/MAP_SOUTHERN_ISLAND_INTERIOR:0,1","MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0":"MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0","MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2":"MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1","MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4":"MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2","MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6":"MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3","MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8":"MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4","MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9":"MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5","MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10":"MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6","MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11":"MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7","MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0":"MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8","MAP_SS_TIDAL_LOWER_DECK:0/MAP_SS_TIDAL_CORRIDOR:8":"MAP_SS_TIDAL_CORRIDOR:8/MAP_SS_TIDAL_LOWER_DECK:0","MAP_SS_TIDAL_ROOMS:0,1/MAP_SS_TIDAL_CORRIDOR:0":"MAP_SS_TIDAL_CORRIDOR:0/MAP_SS_TIDAL_ROOMS:0","MAP_SS_TIDAL_ROOMS:10/MAP_SS_TIDAL_CORRIDOR:6":"MAP_SS_TIDAL_CORRIDOR:6/MAP_SS_TIDAL_ROOMS:10","MAP_SS_TIDAL_ROOMS:11/MAP_SS_TIDAL_CORRIDOR:7":"MAP_SS_TIDAL_CORRIDOR:7/MAP_SS_TIDAL_ROOMS:11","MAP_SS_TIDAL_ROOMS:2,3/MAP_SS_TIDAL_CORRIDOR:1":"MAP_SS_TIDAL_CORRIDOR:1/MAP_SS_TIDAL_ROOMS:2","MAP_SS_TIDAL_ROOMS:4,5/MAP_SS_TIDAL_CORRIDOR:2":"MAP_SS_TIDAL_CORRIDOR:2/MAP_SS_TIDAL_ROOMS:4","MAP_SS_TIDAL_ROOMS:6,7/MAP_SS_TIDAL_CORRIDOR:3":"MAP_SS_TIDAL_CORRIDOR:3/MAP_SS_TIDAL_ROOMS:6","MAP_SS_TIDAL_ROOMS:8/MAP_SS_TIDAL_CORRIDOR:4":"MAP_SS_TIDAL_CORRIDOR:4/MAP_SS_TIDAL_ROOMS:8","MAP_SS_TIDAL_ROOMS:9/MAP_SS_TIDAL_CORRIDOR:5":"MAP_SS_TIDAL_CORRIDOR:5/MAP_SS_TIDAL_ROOMS:9","MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1":"MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0","MAP_TERRA_CAVE_ENTRANCE:0/MAP_DYNAMIC:-1!":"","MAP_TERRA_CAVE_ENTRANCE:1/MAP_TERRA_CAVE_END:0":"MAP_TERRA_CAVE_END:0/MAP_TERRA_CAVE_ENTRANCE:1","MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!":"","MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2":"MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0","MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0":"MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1","MAP_TRAINER_HILL_2F:0/MAP_TRAINER_HILL_1F:1":"MAP_TRAINER_HILL_1F:1/MAP_TRAINER_HILL_2F:0","MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0":"MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1","MAP_TRAINER_HILL_3F:0/MAP_TRAINER_HILL_2F:1":"MAP_TRAINER_HILL_2F:1/MAP_TRAINER_HILL_3F:0","MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0":"MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1","MAP_TRAINER_HILL_4F:0/MAP_TRAINER_HILL_3F:1":"MAP_TRAINER_HILL_3F:1/MAP_TRAINER_HILL_4F:0","MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0":"MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1","MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1":"MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1","MAP_TRAINER_HILL_ENTRANCE:0,1/MAP_ROUTE111:4":"MAP_ROUTE111:4/MAP_TRAINER_HILL_ENTRANCE:0","MAP_TRAINER_HILL_ENTRANCE:2/MAP_TRAINER_HILL_1F:0":"MAP_TRAINER_HILL_1F:0/MAP_TRAINER_HILL_ENTRANCE:2","MAP_TRAINER_HILL_ROOF:0/MAP_TRAINER_HILL_4F:1":"MAP_TRAINER_HILL_4F:1/MAP_TRAINER_HILL_ROOF:0","MAP_TRAINER_HILL_ROOF:1/MAP_TRAINER_HILL_ELEVATOR:1":"MAP_TRAINER_HILL_ELEVATOR:0,1/MAP_TRAINER_HILL_ROOF:1","MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!":"","MAP_UNDERWATER_ROUTE105:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE105:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE125:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0":"MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0","MAP_UNDERWATER_ROUTE127:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE127:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0":"MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0","MAP_UNDERWATER_ROUTE129:0/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE129:1/MAP_UNDERWATER_MARINE_CAVE:0!":"MAP_UNDERWATER_MARINE_CAVE:0/MAP_DYNAMIC:-1!","MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0":"MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0","MAP_UNDERWATER_SEAFLOOR_CAVERN:0/MAP_UNDERWATER_ROUTE128:0":"MAP_UNDERWATER_ROUTE128:0/MAP_UNDERWATER_SEAFLOOR_CAVERN:0","MAP_UNDERWATER_SEALED_CHAMBER:0/MAP_UNDERWATER_ROUTE134:0":"MAP_UNDERWATER_ROUTE134:0/MAP_UNDERWATER_SEALED_CHAMBER:0","MAP_UNDERWATER_SOOTOPOLIS_CITY:0,1/MAP_UNDERWATER_ROUTE126:0":"MAP_UNDERWATER_ROUTE126:0/MAP_UNDERWATER_SOOTOPOLIS_CITY:0","MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!":"","MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0":"MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0","MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0":"MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1","MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2","MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0":"MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3","MAP_VERDANTURF_TOWN:4/MAP_RUSTURF_TUNNEL:1":"MAP_RUSTURF_TUNNEL:1/MAP_VERDANTURF_TOWN:4","MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0":"MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5","MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0":"MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6","MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0,1/MAP_VERDANTURF_TOWN:0":"MAP_VERDANTURF_TOWN:0/MAP_VERDANTURF_TOWN_BATTLE_TENT_LOBBY:0","MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0,1/MAP_VERDANTURF_TOWN:5":"MAP_VERDANTURF_TOWN:5/MAP_VERDANTURF_TOWN_FRIENDSHIP_RATERS_HOUSE:0","MAP_VERDANTURF_TOWN_HOUSE:0,1/MAP_VERDANTURF_TOWN:6":"MAP_VERDANTURF_TOWN:6/MAP_VERDANTURF_TOWN_HOUSE:0","MAP_VERDANTURF_TOWN_MART:0,1/MAP_VERDANTURF_TOWN:1":"MAP_VERDANTURF_TOWN:1/MAP_VERDANTURF_TOWN_MART:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0,1/MAP_VERDANTURF_TOWN:2":"MAP_VERDANTURF_TOWN:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0/MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2":"MAP_VERDANTURF_TOWN_POKEMON_CENTER_1F:2/MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:0","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:1/MAP_UNION_ROOM:0!":"MAP_UNION_ROOM:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_POKEMON_CENTER_2F:2/MAP_TRADE_CENTER:0!":"MAP_TRADE_CENTER:0,1/MAP_DYNAMIC:-1!","MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0,1/MAP_VERDANTURF_TOWN:3":"MAP_VERDANTURF_TOWN:3/MAP_VERDANTURF_TOWN_WANDAS_HOUSE:0","MAP_VICTORY_ROAD_1F:0/MAP_EVER_GRANDE_CITY:2":"MAP_EVER_GRANDE_CITY:2/MAP_VICTORY_ROAD_1F:0","MAP_VICTORY_ROAD_1F:1/MAP_EVER_GRANDE_CITY:3":"MAP_EVER_GRANDE_CITY:3/MAP_VICTORY_ROAD_1F:1","MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5":"MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2","MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2":"MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3","MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4":"MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4","MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0":"MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0","MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2":"MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1","MAP_VICTORY_ROAD_B1F:2/MAP_VICTORY_ROAD_1F:3":"MAP_VICTORY_ROAD_1F:3/MAP_VICTORY_ROAD_B1F:2","MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1":"MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3","MAP_VICTORY_ROAD_B1F:4/MAP_VICTORY_ROAD_1F:4":"MAP_VICTORY_ROAD_1F:4/MAP_VICTORY_ROAD_B1F:4","MAP_VICTORY_ROAD_B1F:5/MAP_VICTORY_ROAD_1F:2":"MAP_VICTORY_ROAD_1F:2/MAP_VICTORY_ROAD_B1F:5","MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3":"MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6","MAP_VICTORY_ROAD_B2F:0/MAP_VICTORY_ROAD_B1F:0":"MAP_VICTORY_ROAD_B1F:0/MAP_VICTORY_ROAD_B2F:0","MAP_VICTORY_ROAD_B2F:1/MAP_VICTORY_ROAD_B1F:3":"MAP_VICTORY_ROAD_B1F:3/MAP_VICTORY_ROAD_B2F:1","MAP_VICTORY_ROAD_B2F:2/MAP_VICTORY_ROAD_B1F:1":"MAP_VICTORY_ROAD_B1F:1/MAP_VICTORY_ROAD_B2F:2","MAP_VICTORY_ROAD_B2F:3/MAP_VICTORY_ROAD_B1F:6":"MAP_VICTORY_ROAD_B1F:6/MAP_VICTORY_ROAD_B2F:3"}} From d1624679eedb62789e7e7bf86d8803fd53f83f8f Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Sun, 28 Sep 2025 12:39:18 -0700 Subject: [PATCH 0747/1218] Pokemon Emerald: Set all abilities to Cacophony if all are blacklisted (#5488) --- worlds/pokemon_emerald/pokemon.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/worlds/pokemon_emerald/pokemon.py b/worlds/pokemon_emerald/pokemon.py index 6f2676500d66..b39f8c2abf6e 100644 --- a/worlds/pokemon_emerald/pokemon.py +++ b/worlds/pokemon_emerald/pokemon.py @@ -397,6 +397,10 @@ def randomize_abilities(world: "PokemonEmeraldWorld") -> None: ability_blacklist = {ability_label_to_value[label] for label in ability_blacklist_labels} ability_whitelist = [a.ability_id for a in data.abilities if a.ability_id not in ability_blacklist] + # If every ability is blacklisted, set all abilities to Cacophony, effectively disabling abilities + if len(ability_whitelist) == 0: + ability_whitelist = [data.constants["ABILITY_CACOPHONY"]] + if world.options.abilities == RandomizeAbilities.option_follow_evolutions: already_modified: Set[int] = set() From 1d861d1d063b19a3e5ce64c8176a4420f69667a3 Mon Sep 17 00:00:00 2001 From: palex00 <32203971+palex00@users.noreply.github.com> Date: Sun, 28 Sep 2025 23:18:06 +0200 Subject: [PATCH 0748/1218] =?UTF-8?q?Pok=C3=A9mon=20RB:=20Update=20Slot=20?= =?UTF-8?q?Data=20(#5494)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worlds/pokemon_rb/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/pokemon_rb/__init__.py b/worlds/pokemon_rb/__init__.py index a455e38f2934..3f5a24cc173a 100644 --- a/worlds/pokemon_rb/__init__.py +++ b/worlds/pokemon_rb/__init__.py @@ -713,7 +713,8 @@ def fill_slot_data(self) -> dict: "require_pokedex": self.options.require_pokedex.value, "area_1_to_1_mapping": self.options.area_1_to_1_mapping.value, "blind_trainers": self.options.blind_trainers.value, - "v5_update": True, + "game_version": self.options.game_version.value, + "exp_all": self.options.exp_all.value, } if self.options.type_chart_seed == "random" or self.options.type_chart_seed.value.isdigit(): From 6099869c59224d8c3660cc4020e61658e8177957 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 30 Sep 2025 01:52:12 +0200 Subject: [PATCH 0749/1218] Core: new cx_freeze (#5316) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 81eee0172afc..98b9dd604a1c 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ # This is a bit jank. We need cx-Freeze to be able to run anything from this script, so install it -requirement = 'cx-Freeze==8.0.0' +requirement = 'cx-Freeze==8.4.0' try: import pkg_resources try: From 47b2242c3c05dea6534ea80bddc31d66a59d7417 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 29 Sep 2025 21:53:10 -0400 Subject: [PATCH 0750/1218] TUNIC: Add archipelago.json (#5482) * add archipelago.json * newline * Add authors * Make it a list --- worlds/tunic/archipelago.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 worlds/tunic/archipelago.json diff --git a/worlds/tunic/archipelago.json b/worlds/tunic/archipelago.json new file mode 100644 index 000000000000..4c4d8dd93109 --- /dev/null +++ b/worlds/tunic/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "TUNIC", + "authors": ["SilentSR", "ScipioWright"], + "minimum_ap_version": "0.6.4", + "world_version": "4.1.0" +} From 25baa578500c91f4c50b0beb280d057760886070 Mon Sep 17 00:00:00 2001 From: Felix R <50271878+FelicitusNeko@users.noreply.github.com> Date: Mon, 29 Sep 2025 22:53:31 -0300 Subject: [PATCH 0751/1218] meritous: Create manifest (#5497) --- worlds/meritous/archipelago.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 worlds/meritous/archipelago.json diff --git a/worlds/meritous/archipelago.json b/worlds/meritous/archipelago.json new file mode 100644 index 000000000000..7b2c54572624 --- /dev/null +++ b/worlds/meritous/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Meritous", + "authors": ["KewlioMZX"], + "world_version": "1.0.0", + "minimum_ap_version": "0.6.4" +} From f9083d930774848c8dc44fe92f663249a2b161fe Mon Sep 17 00:00:00 2001 From: Felix R <50271878+FelicitusNeko@users.noreply.github.com> Date: Mon, 29 Sep 2025 22:53:47 -0300 Subject: [PATCH 0752/1218] bumpstik: Create manifest (#5496) --- worlds/bumpstik/archipelago.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 worlds/bumpstik/archipelago.json diff --git a/worlds/bumpstik/archipelago.json b/worlds/bumpstik/archipelago.json new file mode 100644 index 000000000000..64dc1b9cbbef --- /dev/null +++ b/worlds/bumpstik/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Bumper Stickers", + "authors": ["KewlioMZX"], + "world_version": "1.0.0", + "minimum_ap_version": "0.6.4" +} From 2f23dc72f9f7e585822c1934164c73daa5670390 Mon Sep 17 00:00:00 2001 From: Justus Lind Date: Tue, 30 Sep 2025 11:54:14 +1000 Subject: [PATCH 0753/1218] Muse Dash: Update song list to Legendary Voyage, Mystic Treasure. Add manifest. (#5498) * Legendary Voyage, Mystic Treasure Update * Add manifest * Correct Manifest version. * Fix file encoding --- worlds/musedash/MuseDashData.py | 6 ++++++ worlds/musedash/archipelago.json | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 worlds/musedash/archipelago.json diff --git a/worlds/musedash/MuseDashData.py b/worlds/musedash/MuseDashData.py index 6943b281f1cc..f3a6becb6a26 100644 --- a/worlds/musedash/MuseDashData.py +++ b/worlds/musedash/MuseDashData.py @@ -665,4 +665,10 @@ "Midnight Blue": SongData(2900789, "88-1", "MUSE RADIO FM106", True, 2, 5, 7), "overwork feat.Woonoo": SongData(2900790, "88-2", "MUSE RADIO FM106", True, 2, 6, 8), "SUPER CITYLIGHTS": SongData(2900791, "88-3", "MUSE RADIO FM106", True, 5, 7, 10), + "Flametide": SongData(2900792, "89-0", "Legendary Voyage, Mystic Treasure", True, 5, 7, 9), + "Embrace feat. Kiyon": SongData(2900793, "89-1", "Legendary Voyage, Mystic Treasure", True, 2, 5, 8), + "Magazines feat. Nia Suzune": SongData(2900794, "89-2", "Legendary Voyage, Mystic Treasure", True, 3, 6, 8), + "Temptation": SongData(2900795, "89-3", "Legendary Voyage, Mystic Treasure", False, 5, 8, 10), + "PwP": SongData(2900796, "89-4", "Legendary Voyage, Mystic Treasure", True, 3, 6, 9), + "I Can Show You": SongData(2900797, "89-5", "Legendary Voyage, Mystic Treasure", False, 5, 7, 9), } diff --git a/worlds/musedash/archipelago.json b/worlds/musedash/archipelago.json new file mode 100644 index 000000000000..d10e8369d6dd --- /dev/null +++ b/worlds/musedash/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Muse Dash", + "authors": ["DeamonHunter"], + "world_version": "1.5.25", + "minimum_ap_version": "0.6.3" +} \ No newline at end of file From ab2097960d183fcebc9028bf24a515cab412ca21 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Mon, 29 Sep 2025 21:54:32 -0400 Subject: [PATCH 0754/1218] Jak and Daxter: Add manifest #5492 --- worlds/jakanddaxter/archipelago.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 worlds/jakanddaxter/archipelago.json diff --git a/worlds/jakanddaxter/archipelago.json b/worlds/jakanddaxter/archipelago.json new file mode 100644 index 000000000000..8b0adcd10556 --- /dev/null +++ b/worlds/jakanddaxter/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Jak and Daxter: The Precursor Legacy", + "world_version": "1.0.0", + "minimum_ap_version": "0.6.2", + "authors": ["markustulliuscicero"] +} From 053f876e8478753a0bfe0dd4c83127ecdfdb330a Mon Sep 17 00:00:00 2001 From: Bryce Wilson Date: Mon, 29 Sep 2025 19:10:45 -0700 Subject: [PATCH 0755/1218] Pokemon Emerald: Add manifest (#5487) --- worlds/pokemon_emerald/archipelago.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 worlds/pokemon_emerald/archipelago.json diff --git a/worlds/pokemon_emerald/archipelago.json b/worlds/pokemon_emerald/archipelago.json new file mode 100644 index 000000000000..ed11b8d8cc8c --- /dev/null +++ b/worlds/pokemon_emerald/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Pokemon Emerald", + "world_version": "2.4.1", + "minimum_ap_version": "0.6.1", + "authors": ["Zunawe"] +} From c30a5b206e8c3ad34380ad44eee03bdd94be9c90 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Mon, 29 Sep 2025 22:12:19 -0400 Subject: [PATCH 0756/1218] Noita: Add archipelago.json (#5483) * Add archipelago.json * Add authors * make it a list --- worlds/noita/archipelago.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 worlds/noita/archipelago.json diff --git a/worlds/noita/archipelago.json b/worlds/noita/archipelago.json new file mode 100644 index 000000000000..3bda5245087c --- /dev/null +++ b/worlds/noita/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Noita", + "authors": ["Heinermann", "ScipioWright"], + "minimum_ap_version": "0.6.4", + "world_version": "1.4.0" +} From 580370c3a04adfb017d75d364f0beb460584197b Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Mon, 29 Sep 2025 22:43:59 -0400 Subject: [PATCH 0757/1218] Jak and Daxter: close Power Cell loophole in trades test #5493 --- worlds/jakanddaxter/test/test_trades.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/worlds/jakanddaxter/test/test_trades.py b/worlds/jakanddaxter/test/test_trades.py index 0277a92353f9..92552f9d0eb6 100644 --- a/worlds/jakanddaxter/test/test_trades.py +++ b/worlds/jakanddaxter/test/test_trades.py @@ -6,7 +6,8 @@ class TradesCostNothingTest(JakAndDaxterTestBase): "enable_orbsanity": 2, "global_orbsanity_bundle_size": 10, "citizen_orb_trade_amount": 0, - "oracle_orb_trade_amount": 0 + "oracle_orb_trade_amount": 0, + "start_inventory": {"Power Cell": 100}, } def test_orb_items_are_filler(self): @@ -24,7 +25,8 @@ class TradesCostEverythingTest(JakAndDaxterTestBase): "enable_orbsanity": 2, "global_orbsanity_bundle_size": 10, "citizen_orb_trade_amount": 120, - "oracle_orb_trade_amount": 150 + "oracle_orb_trade_amount": 150, + "start_inventory": {"Power Cell": 100}, } def test_orb_items_are_progression(self): From 5345937966764c86e64fcff0bd5b5fd732ef9505 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Tue, 30 Sep 2025 04:45:59 +0200 Subject: [PATCH 0758/1218] The Witness: Remove two things from slot_data that nothing uses anymore #5502 --- worlds/witness/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/worlds/witness/__init__.py b/worlds/witness/__init__.py index bce9bb515146..6aaf2fdc0a17 100644 --- a/worlds/witness/__init__.py +++ b/worlds/witness/__init__.py @@ -104,7 +104,6 @@ def _get_slot_data(self) -> Dict[str, Any]: "item_id_to_door_hexes": static_witness_items.get_item_to_door_mappings(), "door_items_in_the_pool": self.player_items.get_door_item_ids_in_pool(), "doors_that_shouldnt_be_locked": [int(h, 16) for h in self.player_logic.FORBIDDEN_DOORS], - "symbols_not_in_the_game": self.player_items.get_symbol_ids_not_in_pool(), "disabled_entities": [int(h, 16) for h in self.player_logic.COMPLETELY_DISABLED_ENTITIES], "hunt_entities": [int(h, 16) for h in self.player_logic.HUNT_ENTITIES], "log_ids_to_hints": self.log_ids_to_hints, @@ -112,7 +111,6 @@ def _get_slot_data(self) -> Dict[str, Any]: "progressive_item_lists": self.player_items.get_progressive_item_ids_in_pool(), "obelisk_side_id_to_EPs": static_witness_logic.OBELISK_SIDE_ID_TO_EP_HEXES, "precompleted_puzzles": [int(h, 16) for h in self.player_logic.EXCLUDED_ENTITIES], - "entity_to_name": static_witness_logic.ENTITY_ID_TO_NAME, "panel_hunt_required_absolute": self.panel_hunt_required_count } From d9955d624b03bbc2db958995eee9f69cba3847a3 Mon Sep 17 00:00:00 2001 From: gaithern <36639398+gaithern@users.noreply.github.com> Date: Mon, 29 Sep 2025 22:10:29 -0500 Subject: [PATCH 0759/1218] KH1: Fix Slot 2 Level Checks description #5451 --- worlds/kh1/Options.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/kh1/Options.py b/worlds/kh1/Options.py index 1bdc478a4e2f..f64e927fe1e9 100644 --- a/worlds/kh1/Options.py +++ b/worlds/kh1/Options.py @@ -547,9 +547,9 @@ class RemoteItems(Choice): class Slot2LevelChecks(Range): """ - Determines how many levels have an additional item. Usually, this item is an ability. + Determines how many levels have an additional item. - If Remote Items is OFF, these checks will only contain abilities. + If Remote Items is OFF, these checks will only contain abilities or items for other players. """ display_name = "Slot 2 Level Checks" default = 0 From a30b43821f939ec860a1cb165796a3fa7447b429 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Tue, 30 Sep 2025 11:30:26 -0500 Subject: [PATCH 0760/1218] KDL3, MM2: set goal condition before generate basic (#5382) * move goal kdl3 * mm2 * missed the singular important line --- worlds/kdl3/__init__.py | 4 ---- worlds/kdl3/rules.py | 9 ++++++++- worlds/mm2/__init__.py | 8 +++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/worlds/kdl3/__init__.py b/worlds/kdl3/__init__.py index 1b5acbe97a3c..7642ec231303 100644 --- a/worlds/kdl3/__init__.py +++ b/worlds/kdl3/__init__.py @@ -303,9 +303,6 @@ def create_items(self) -> None: def generate_basic(self) -> None: self.stage_shuffle_enabled = self.options.stage_shuffle > 0 - goal = self.options.goal.value - goal_location = self.multiworld.get_location(location_name.goals[goal], self.player) - goal_location.place_locked_item(KDL3Item("Love-Love Rod", ItemClassification.progression, None, self.player)) for level in range(1, 6): self.multiworld.get_location(f"Level {level} Boss - Defeated", self.player) \ .place_locked_item( @@ -313,7 +310,6 @@ def generate_basic(self) -> None: self.multiworld.get_location(f"Level {level} Boss - Purified", self.player) \ .place_locked_item( KDL3Item(f"Level {level} Boss Purified", ItemClassification.progression, None, self.player)) - self.multiworld.completion_condition[self.player] = lambda state: state.has("Love-Love Rod", self.player) # this can technically be done at any point before generate_output if self.options.allow_bb: if self.options.allow_bb == self.options.allow_bb.option_enforced: diff --git a/worlds/kdl3/rules.py b/worlds/kdl3/rules.py index 828740859e9b..0be4784175ed 100644 --- a/worlds/kdl3/rules.py +++ b/worlds/kdl3/rules.py @@ -1,6 +1,8 @@ +from BaseClasses import ItemClassification from worlds.generic.Rules import set_rule, add_rule -from .names import location_name, enemy_abilities, animal_friend_spawns +from .items import KDL3Item from .locations import location_table +from .names import location_name, enemy_abilities, animal_friend_spawns from .options import GoalSpeed import typing @@ -111,6 +113,11 @@ def can_fix_angel_wings(state: "CollectionState", player: int, copy_abilities: t def set_rules(world: "KDL3World") -> None: + goal = world.options.goal.value + goal_location = world.multiworld.get_location(location_name.goals[goal], world.player) + goal_location.place_locked_item(KDL3Item("Love-Love Rod", ItemClassification.progression, None, world.player)) + world.multiworld.completion_condition[world.player] = lambda state: state.has("Love-Love Rod", world.player) + # Level 1 set_rule(world.multiworld.get_location(location_name.grass_land_muchi, world.player), lambda state: can_reach_chuchu(state, world.player)) diff --git a/worlds/mm2/__init__.py b/worlds/mm2/__init__.py index 4a43ee8df0f0..529810d41047 100644 --- a/worlds/mm2/__init__.py +++ b/worlds/mm2/__init__.py @@ -133,6 +133,9 @@ def create_regions(self) -> None: Consumables.option_all): stage.add_locations(energy_pickups[region], MM2Location) self.multiworld.regions.append(stage) + goal_location = self.get_location(dr_wily) + goal_location.place_locked_item(MM2Item("Victory", ItemClassification.progression, None, self.player)) + self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) def create_item(self, name: str) -> MM2Item: item = item_table[name] @@ -189,11 +192,6 @@ def generate_early(self) -> None: f"Incompatible starting Robot Master, changing to " f"{self.options.starting_robot_master.current_key.replace('_', ' ').title()}") - def generate_basic(self) -> None: - goal_location = self.get_location(dr_wily) - goal_location.place_locked_item(MM2Item("Victory", ItemClassification.progression, None, self.player)) - self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) - def fill_hook(self, progitempool: List["Item"], usefulitempool: List["Item"], From 516ebc53ce32f38aaeb6c51dd4c5702e908c969f Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Tue, 30 Sep 2025 12:31:49 -0400 Subject: [PATCH 0761/1218] LADX: fix local lvl 2 sword on the beach turning into a lvl 0 shield #5334 https://github.com/daid/LADXR/commit/e3e49b16d6af03818d6820e14db8f2ba7f0a424d --- worlds/ladx/LADXR/locations/beachSword.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/worlds/ladx/LADXR/locations/beachSword.py b/worlds/ladx/LADXR/locations/beachSword.py index 51fc4388e325..0835672cf7fb 100644 --- a/worlds/ladx/LADXR/locations/beachSword.py +++ b/worlds/ladx/LADXR/locations/beachSword.py @@ -11,19 +11,18 @@ def __init__(self) -> None: super().__init__(0x0F2) def patch(self, rom: ROM, option: str, *, multiworld: Optional[int] = None) -> None: - if option != SWORD or multiworld is not None: - # Set the heart piece data - super().patch(rom, option, multiworld=multiworld) + # Set the heart piece data + super().patch(rom, option, multiworld=multiworld) - # Patch the room to contain a heart piece instead of the sword on the beach - re = RoomEditor(rom, 0x0F2) - re.removeEntities(0x31) # remove sword - re.addEntity(5, 5, 0x35) # add heart piece - re.store(rom) + # Patch the room to contain a heart piece instead of the sword on the beach + re = RoomEditor(rom, 0x0F2) + re.removeEntities(0x31) # remove sword + re.addEntity(5, 5, 0x35) # add heart piece + re.store(rom) - # Prevent shield drops from the like-like from turning into swords. - rom.patch(0x03, 0x1B9C, ASM("ld a, [$DB4E]"), ASM("ld a, $01"), fill_nop=True) - rom.patch(0x03, 0x244D, ASM("ld a, [$DB4E]"), ASM("ld a, $01"), fill_nop=True) + # Prevent shield drops from the like-like from turning into swords. + rom.patch(0x03, 0x1B9C, ASM("ld a, [$DB4E]"), ASM("ld a, $01"), fill_nop=True) + rom.patch(0x03, 0x244D, ASM("ld a, [$DB4E]"), ASM("ld a, $01"), fill_nop=True) def read(self, rom: ROM) -> str: re = RoomEditor(rom, 0x0F2) From 1d2ad1f9c92b6ff3b1a1ddf8c9c16a8d3b28269b Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Tue, 30 Sep 2025 10:32:50 -0600 Subject: [PATCH 0762/1218] Docs: More type annotation changes (#5301) * Update docs annotations * Update settings recommendation * Remove Dict in comment --- docs/entrance randomization.md | 4 ++-- docs/network protocol.md | 13 +++++++------ docs/settings api.md | 2 +- docs/style.md | 6 ++++-- docs/world api.md | 10 +++++----- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/docs/entrance randomization.md b/docs/entrance randomization.md index 0f9d76471635..d9f278bf1ee0 100644 --- a/docs/entrance randomization.md +++ b/docs/entrance randomization.md @@ -352,14 +352,14 @@ direction_matching_group_lookup = { Terrain matching or dungeon shuffle: ```python -def randomize_within_same_group(group: int) -> List[int]: +def randomize_within_same_group(group: int) -> list[int]: return [group] identity_group_lookup = bake_target_group_lookup(world, randomize_within_same_group) ``` Directional + area shuffle: ```python -def get_target_groups(group: int) -> List[int]: +def get_target_groups(group: int) -> list[int]: # example group: LEFT | CAVE # example result: [RIGHT | CAVE, DOOR | CAVE] direction = group & Groups.DIRECTION_MASK diff --git a/docs/network protocol.md b/docs/network protocol.md index b40cf31b8568..c3fc578a896c 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -79,7 +79,7 @@ Sent to clients when they connect to an Archipelago server. | generator_version | [NetworkVersion](#NetworkVersion) | Object denoting the version of Archipelago which generated the multiworld. | | tags | list\[str\] | Denotes special features or capabilities that the sender is capable of. Example: `WebHost` | | password | bool | Denoted whether a password is required to join this room. | -| permissions | dict\[str, [Permission](#Permission)\[int\]\] | Mapping of permission name to [Permission](#Permission), keys are: "release", "collect" and "remaining". | +| permissions | dict\[str, [Permission](#Permission)\] | Mapping of permission name to [Permission](#Permission), keys are: "release", "collect" and "remaining". | | hint_cost | int | The percentage of total locations that need to be checked to receive a hint from the server. | | location_check_points | int | The amount of hint points you receive per item/location check completed. | | games | list\[str\] | List of games present in this multiworld. | @@ -662,13 +662,14 @@ class SlotType(enum.IntFlag): An object representing static information about a slot. ```python -import typing +from collections.abc import Sequence +from typing import NamedTuple from NetUtils import SlotType -class NetworkSlot(typing.NamedTuple): +class NetworkSlot(NamedTuple): name: str game: str type: SlotType - group_members: typing.List[int] = [] # only populated if type == group + group_members: Sequence[int] = [] # only populated if type == group ``` ### Permission @@ -686,8 +687,8 @@ class Permission(enum.IntEnum): ### Hint An object representing a Hint. ```python -import typing -class Hint(typing.NamedTuple): +from typing import NamedTuple +class Hint(NamedTuple): receiving_player: int finding_player: int location: int diff --git a/docs/settings api.md b/docs/settings api.md index d701c0175801..36520fe683f5 100644 --- a/docs/settings api.md +++ b/docs/settings api.md @@ -28,7 +28,7 @@ if it does not exist. ## Global Settings All non-world-specific settings are defined directly in settings.py. -Each value needs to have a default. If the default should be `None`, define it as `typing.Optional` and assign `None`. +Each value needs to have a default. If the default should be `None`, annotate it using `T | None = None`. To access a "global" config value, with correct typing, use one of ```python diff --git a/docs/style.md b/docs/style.md index bb1526faf50c..e38be9d649db 100644 --- a/docs/style.md +++ b/docs/style.md @@ -15,8 +15,10 @@ * Prefer [format string literals](https://peps.python.org/pep-0498/) over string concatenation, use single quotes inside them: `f"Like {dct['key']}"` * Use type annotations where possible for function signatures and class members. -* Use type annotations where appropriate for local variables (e.g. `var: List[int] = []`, or when the - type is hard or impossible to deduce.) Clear annotations help developers look up and validate API calls. +* Use type annotations where appropriate for local variables (e.g. `var: list[int] = []`, or when the + type is hard or impossible to deduce). Clear annotations help developers look up and validate API calls. +* Prefer new style type annotations for new code (e.g. `var: dict[str, str | int]` over + `var: Dict[str, Union[str, int]]`). * If a line ends with an open bracket/brace/parentheses, the matching closing bracket should be at the beginning of a line at the same indentation as the beginning of the line with the open bracket. ```python diff --git a/docs/world api.md b/docs/world api.md index 832ad05d4f66..db6da50cf41f 100644 --- a/docs/world api.md +++ b/docs/world api.md @@ -76,8 +76,8 @@ webhost: * `game_info_languages` (optional) list of strings for defining the existing game info pages your game supports. The documents must be prefixed with the same string as defined here. Default already has 'en'. -* `options_presets` (optional) `Dict[str, Dict[str, Any]]` where the keys are the names of the presets and the values - are the options to be set for that preset. The options are defined as a `Dict[str, Any]` where the keys are the names +* `options_presets` (optional) `dict[str, dict[str, Any]]` where the keys are the names of the presets and the values + are the options to be set for that preset. The options are defined as a `dict[str, Any]` where the keys are the names of the options and the values are the values to be set for that option. These presets will be available for users to select from on the game's options page. @@ -753,7 +753,7 @@ from BaseClasses import CollectionState, MultiWorld from worlds.AutoWorld import LogicMixin class MyGameState(LogicMixin): - mygame_defeatable_enemies: Dict[int, Set[str]] # per player + mygame_defeatable_enemies: dict[int, set[str]] # per player def init_mixin(self, multiworld: MultiWorld) -> None: # Initialize per player with the corresponding "nothing" value, such as 0 or an empty set. @@ -882,11 +882,11 @@ item/location pairs is unnecessary since the AP server already retains and freel that request it. The most common usage of slot data is sending option results that the client needs to be aware of. ```python -def fill_slot_data(self) -> Dict[str, Any]: +def fill_slot_data(self) -> dict[str, Any]: # In order for our game client to handle the generated seed correctly we need to know what the user selected # for their difficulty and final boss HP. # A dictionary returned from this method gets set as the slot_data and will be sent to the client after connecting. - # The options dataclass has a method to return a `Dict[str, Any]` of each option name provided and the relevant + # The options dataclass has a method to return a `dict[str, Any]` of each option name provided and the relevant # option's value. return self.options.as_dict("difficulty", "final_boss_hp") ``` From 92ff0ddba8ae300fe9164ee13b37d6a0d531db7a Mon Sep 17 00:00:00 2001 From: Phaneros <31861583+MatthewMarinets@users.noreply.github.com> Date: Tue, 30 Sep 2025 09:34:26 -0700 Subject: [PATCH 0763/1218] SC2: Launcher bugfixes after content merge (#5409) * sc2: Fixing Launcher.py launch not properly handling command-line arguments * sc2: Fixing some old option names in webhost * sc2: Switching to common client url parameter handling --- worlds/sc2/client.py | 20 ++++++++------------ worlds/sc2/options.py | 4 ++-- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/worlds/sc2/client.py b/worlds/sc2/client.py index d64d44aea1f9..e9f46f93b7a9 100644 --- a/worlds/sc2/client.py +++ b/worlds/sc2/client.py @@ -21,10 +21,11 @@ import concurrent.futures import time import uuid +import argparse from pathlib import Path # CommonClient import first to trigger ModuleUpdater -from CommonClient import CommonContext, server_loop, ClientCommandProcessor, gui_enabled, get_base_parser +from CommonClient import CommonContext, server_loop, ClientCommandProcessor, gui_enabled, get_base_parser, handle_url_arg from Utils import init_logging, is_windows, async_start from .item import item_names, item_parents, race_to_item_type from .item.item_annotations import ITEM_NAME_ANNOTATIONS @@ -1298,20 +1299,15 @@ class CompatItemHolder(typing.NamedTuple): quantity: int = 1 -def parse_uri(uri: str) -> str: - if "://" in uri: - uri = uri.split("://", 1)[1] - return uri.split('?', 1)[0] - - -async def main(): +async def main(args: typing.Sequence[str] | None): multiprocessing.freeze_support() parser = get_base_parser() parser.add_argument('--name', default=None, help="Slot Name to connect as.") - args, uri = parser.parse_known_args() + args, uri = parser.parse_known_args(args) if uri and uri[0].startswith('archipelago://'): - args.connect = parse_uri(' '.join(uri)) + args.url = uri[0] + handle_url_arg(args, parser) ctx = SC2Context(args.connect, args.password) ctx.auth = args.name @@ -2346,7 +2342,7 @@ def force_settings_save_on_close() -> None: _has_forced_save = True -def launch(): +def launch(*args: str): colorama.just_fix_windows_console() - asyncio.run(main()) + asyncio.run(main(args)) colorama.deinit() diff --git a/worlds/sc2/options.py b/worlds/sc2/options.py index 08be7e187a35..00dd4ba742b7 100644 --- a/worlds/sc2/options.py +++ b/worlds/sc2/options.py @@ -170,7 +170,7 @@ class TwoStartPositions(Toggle): If turned on and 'grid', 'hopscotch', or 'golden_path' mission orders are selected, removes the first mission and allows both of the next two missions to be played from the start. """ - display_name = "Start with two unlocked missions on grid" + display_name = "Two start missions" default = Toggle.option_false @@ -1053,7 +1053,7 @@ class VictoryCache(Range): Controls how many additional checks are awarded for completing a mission. Goal missions are unaffected by this option. """ - display_name = "Victory Checks" + display_name = "Victory Cache" range_start = 0 range_end = 10 default = 0 From 897d5ab0893c685ef7773eb98eb5da638e090875 Mon Sep 17 00:00:00 2001 From: Ziktofel Date: Tue, 30 Sep 2025 18:35:26 +0200 Subject: [PATCH 0764/1218] SC2: Fix Conviction logic for Grant Story Tech (#5419) * Fix Conviction logic for Grant Story Tech - Kinetic Blast and Crushing Grip is available for the mission if story tech is granted * Review updates --- worlds/sc2/locations.py | 15 +++++------ worlds/sc2/rules.py | 42 +++++++++++++++++------------- worlds/sc2/test/test_generation.py | 1 + worlds/sc2/test/test_usecases.py | 40 +++++++++++++++++++++++++++- 4 files changed, 70 insertions(+), 28 deletions(-) diff --git a/worlds/sc2/locations.py b/worlds/sc2/locations.py index 203d4d26218c..6b505d9c974a 100644 --- a/worlds/sc2/locations.py +++ b/worlds/sc2/locations.py @@ -2341,8 +2341,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2HOTS_LOC_ID_OFFSET + 200, LocationType.VICTORY, lambda state: logic.basic_kerrigan(state) - or kerriganless - or logic.grant_story_tech == GrantStoryTech.option_grant, + or kerriganless, hard_rule=logic.zerg_any_units_back_in_the_saddle_requirement, ), make_location_data( @@ -2351,8 +2350,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2HOTS_LOC_ID_OFFSET + 201, LocationType.EXTRA, lambda state: logic.basic_kerrigan(state) - or kerriganless - or logic.grant_story_tech == GrantStoryTech.option_grant, + or kerriganless, hard_rule=logic.zerg_any_units_back_in_the_saddle_requirement, ), make_location_data( @@ -2379,8 +2377,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2HOTS_LOC_ID_OFFSET + 205, LocationType.EXTRA, lambda state: logic.basic_kerrigan(state) - or kerriganless - or logic.grant_story_tech == GrantStoryTech.option_grant, + or kerriganless, hard_rule=logic.zerg_any_units_back_in_the_saddle_requirement, ), make_location_data( @@ -2446,7 +2443,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: lambda state: ( logic.zerg_competent_comp(state) and logic.zerg_competent_anti_air(state) - and (logic.basic_kerrigan(state) or kerriganless) + and (logic.basic_kerrigan(state, False) or kerriganless) and logic.zerg_defense_rating(state, False, False) >= 3 and logic.zerg_power_rating(state) >= 5 ), @@ -3530,7 +3527,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: kerriganless or ( logic.two_kerrigan_actives(state) - and (logic.basic_kerrigan(state) or logic.grant_story_tech == GrantStoryTech.option_grant) + and logic.basic_kerrigan(state) and logic.kerrigan_levels(state, 25) ) ), @@ -3554,7 +3551,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: kerriganless or ( logic.two_kerrigan_actives(state) - and (logic.basic_kerrigan(state) or logic.grant_story_tech == GrantStoryTech.option_grant) + and logic.basic_kerrigan(state) and logic.kerrigan_levels(state, 25) ) ), diff --git a/worlds/sc2/rules.py b/worlds/sc2/rules.py index e6068ab22801..2a03d65d8d59 100644 --- a/worlds/sc2/rules.py +++ b/worlds/sc2/rules.py @@ -1127,8 +1127,10 @@ def kerrigan_levels(self, state: CollectionState, target: int, story_levels_avai return levels >= target - def basic_kerrigan(self, state: CollectionState) -> bool: - # One active ability that can be used to defeat enemies directly on Standard + def basic_kerrigan(self, state: CollectionState, story_tech_available=True) -> bool: + if story_tech_available and self.grant_story_tech == GrantStoryTech.option_grant: + return True + # One active ability that can be used to defeat enemies directly if not state.has_any( ( item_names.KERRIGAN_LEAPING_STRIKE, @@ -1149,7 +1151,9 @@ def basic_kerrigan(self, state: CollectionState) -> bool: return True return False - def two_kerrigan_actives(self, state: CollectionState) -> bool: + def two_kerrigan_actives(self, state: CollectionState, story_tech_available=True) -> bool: + if story_tech_available and self.grant_story_tech == GrantStoryTech.option_grant: + return True count = 0 for i in range(7): if state.has_any(kerrigan_logic_active_abilities, self.player): @@ -2396,7 +2400,7 @@ def zerg_hand_of_darkness_requirement(self, state: CollectionState) -> bool: return ( self.zerg_competent_comp(state) and (self.zerg_competent_anti_air(state) or self.advanced_tactics and self.zerg_moderate_anti_air(state)) - and (self.basic_kerrigan(state) or self.zerg_power_rating(state) >= 4) + and (self.basic_kerrigan(state, False) or self.zerg_power_rating(state) >= 4) ) def protoss_hand_of_darkness_requirement(self, state: CollectionState) -> bool: @@ -2412,7 +2416,7 @@ def protoss_planetfall_requirement(self, state: CollectionState) -> bool: return self.protoss_deathball(state) and self.protoss_power_rating(state) >= 8 def zerg_the_reckoning_requirement(self, state: CollectionState) -> bool: - if not (self.zerg_power_rating(state) >= 6 or self.basic_kerrigan(state)): + if not (self.zerg_power_rating(state) >= 6 or self.basic_kerrigan(state, False)): return False if self.take_over_ai_allies: return ( @@ -2460,20 +2464,22 @@ def protoss_can_attack_behind_chasm(self, state: CollectionState) -> bool: def the_infinite_cycle_requirement(self, state: CollectionState) -> bool: return ( - self.grant_story_tech == GrantStoryTech.option_grant - or not self.kerrigan_unit_available - or ( - state.has_any( - ( - item_names.KERRIGAN_KINETIC_BLAST, - item_names.KERRIGAN_SPAWN_BANELINGS, - item_names.KERRIGAN_LEAPING_STRIKE, - item_names.KERRIGAN_SPAWN_LEVIATHAN, - ), - self.player, + self.kerrigan_levels(state, 70) + and ( + self.grant_story_tech == GrantStoryTech.option_grant + or not self.kerrigan_unit_available + or ( + state.has_any( + ( + item_names.KERRIGAN_KINETIC_BLAST, + item_names.KERRIGAN_SPAWN_BANELINGS, + item_names.KERRIGAN_LEAPING_STRIKE, + item_names.KERRIGAN_SPAWN_LEVIATHAN, + ), + self.player, + ) + and self.basic_kerrigan(state) ) - and self.basic_kerrigan(state) - and self.kerrigan_levels(state, 70) ) ) diff --git a/worlds/sc2/test/test_generation.py b/worlds/sc2/test/test_generation.py index 67e302fec0eb..110fa93715ff 100644 --- a/worlds/sc2/test/test_generation.py +++ b/worlds/sc2/test/test_generation.py @@ -2,6 +2,7 @@ Unit tests for world generation """ from typing import * + from .test_base import Sc2SetupTestBase from .. import mission_groups, mission_tables, options, locations, SC2Mission, SC2Campaign, SC2Race, unreleased_items, \ diff --git a/worlds/sc2/test/test_usecases.py b/worlds/sc2/test/test_usecases.py index a87d176674ac..b51758774ab0 100644 --- a/worlds/sc2/test/test_usecases.py +++ b/worlds/sc2/test/test_usecases.py @@ -6,7 +6,9 @@ from .. import get_all_missions, mission_tables, options from ..item import item_groups, item_tables, item_names from ..mission_tables import SC2Race, SC2Mission, SC2Campaign, MissionFlag -from ..options import EnabledCampaigns, MasteryLocations +from ..options import EnabledCampaigns, MasteryLocations, MissionOrder, EnableRaceSwapVariants, ShuffleCampaigns, \ + ShuffleNoBuild, StarterUnit, RequiredTactics, KerriganPresence, KerriganLevelItemDistribution, GrantStoryTech, \ + GrantStoryLevels class TestSupportedUseCases(Sc2SetupTestBase): @@ -490,3 +492,39 @@ def test_mercs_only(self) -> None: self.assertTupleEqual(terran_nonmerc_units, ()) self.assertTupleEqual(zerg_nonmerc_units, ()) + + def test_all_kerrigan_missions_are_nobuild_and_grant_story_tech_is_on(self) -> None: + # The actual situation the bug got caught + world_options = { + 'mission_order': MissionOrder.option_vanilla_shuffled, + 'selected_races': [ + SC2Race.TERRAN.get_title(), + SC2Race.ZERG.get_title(), + SC2Race.PROTOSS.get_title(), + ], + 'enabled_campaigns': [ + SC2Campaign.WOL.campaign_name, + SC2Campaign.PROPHECY.campaign_name, + SC2Campaign.HOTS.campaign_name, + SC2Campaign.PROLOGUE.campaign_name, + SC2Campaign.LOTV.campaign_name, + SC2Campaign.EPILOGUE.campaign_name, + SC2Campaign.NCO.campaign_name, + ], + 'enable_race_swap': EnableRaceSwapVariants.option_shuffle_all_non_vanilla, # Causes no build Kerrigan missions to be present, only nobuilds remain + 'shuffle_campaigns': ShuffleCampaigns.option_true, + 'shuffle_no_build': ShuffleNoBuild.option_true, + 'starter_unit': StarterUnit.option_balanced, + 'required_tactics': RequiredTactics.option_standard, + 'kerrigan_presence': KerriganPresence.option_vanilla, + 'kerrigan_levels_per_mission_completed': 0, + 'kerrigan_levels_per_mission_completed_cap': -1, + 'kerrigan_level_item_sum': 87, + 'kerrigan_level_item_distribution': KerriganLevelItemDistribution.option_size_7, + 'kerrigan_total_level_cap': -1, + 'start_primary_abilities': 0, + 'grant_story_tech': GrantStoryTech.option_grant, + 'grant_story_levels': GrantStoryLevels.option_additive, + } + self.generate_world(world_options) + # Just check that the world itself generates under those rules and no exception is thrown From 49f2d30587db2d09c2ad2f20283b917a60858733 Mon Sep 17 00:00:00 2001 From: Phaneros <31861583+MatthewMarinets@users.noreply.github.com> Date: Tue, 30 Sep 2025 09:36:41 -0700 Subject: [PATCH 0765/1218] Sc2: [performance] change default options (#5424) * sc2: Changing default campaign options to something more performative and desirable for new players * sc2: Fixing broken test that was missed in roundup * SC2: Update tests for new defaults * SC2: Fix incomplete test * sc2: Updating description for enabled campaigns to mention which are free to play * sc2: PR comments; Updating additional unit tests that were affected by a default change * sc2: Adding a comment to the Enabled Campaigns option to list all the valid campaign names * sc2: Adding quotes wrapping sample values in enabled_campaigns comment to aid copy-pasting --------- Co-authored-by: Salzkorn --- worlds/sc2/options.py | 24 ++++++-- worlds/sc2/test/test_base.py | 15 ++++- worlds/sc2/test/test_custom_mission_orders.py | 5 ++ worlds/sc2/test/test_generation.py | 59 +++++++++++++++---- worlds/sc2/test/test_item_filtering.py | 3 + worlds/sc2/test/test_rules.py | 1 + worlds/sc2/test/test_usecases.py | 9 ++- 7 files changed, 98 insertions(+), 18 deletions(-) diff --git a/worlds/sc2/options.py b/worlds/sc2/options.py index 00dd4ba742b7..74ea67c0a359 100644 --- a/worlds/sc2/options.py +++ b/worlds/sc2/options.py @@ -63,7 +63,7 @@ def __len__(self) -> int: return self.value.__len__() -class SelectRaces(OptionSet): +class SelectedRaces(OptionSet): """ Pick which factions' missions and items can be shuffled into the world. """ @@ -152,6 +152,7 @@ class MissionOrder(Choice): option_golden_path = 10 option_hopscotch = 11 option_custom = 99 + default = option_golden_path class MaximumCampaignSize(Range): @@ -251,10 +252,21 @@ class PlayerColorNova(ColorChoice): class EnabledCampaigns(OptionSet): - """Determines which campaign's missions will be used""" + """ + Determines which campaign's missions will be used. + Wings of Liberty, Prophecy, and Prologue are the only free-to-play campaigns. + Valid campaign names: + - 'Wings of Liberty' + - 'Prophecy' + - 'Heart of the Swarm' + - 'Whispers of Oblivion (Legacy of the Void: Prologue)' + - 'Legacy of the Void' + - 'Into the Void (Legacy of the Void: Epilogue)' + - 'Nova Covert Ops' + """ display_name = "Enabled Campaigns" valid_keys = {campaign.campaign_name for campaign in SC2Campaign if campaign != SC2Campaign.GLOBAL} - default = valid_keys + default = set((SC2Campaign.WOL.campaign_name,)) class EnableRaceSwapVariants(Choice): @@ -1342,7 +1354,7 @@ class Starcraft2Options(PerGameCommonOptions): player_color_zerg: PlayerColorZerg player_color_zerg_primal: PlayerColorZergPrimal player_color_nova: PlayerColorNova - selected_races: SelectRaces + selected_races: SelectedRaces enabled_campaigns: EnabledCampaigns enable_race_swap: EnableRaceSwapVariants mission_race_balancing: EnableMissionRaceBalancing @@ -1436,7 +1448,7 @@ class Starcraft2Options(PerGameCommonOptions): ShuffleCampaigns, AllInMap, TwoStartPositions, - SelectRaces, + SelectedRaces, ExcludeVeryHardMissions, EnableMissionRaceBalancing, ]), @@ -1548,7 +1560,7 @@ def get_option_value(world: Union['SC2World', None], name: str) -> int: def get_enabled_races(world: Optional['SC2World']) -> Set[SC2Race]: - race_names = world.options.selected_races.value if world and len(world.options.selected_races.value) > 0 else SelectRaces.valid_keys + race_names = world.options.selected_races.value if world and len(world.options.selected_races.value) > 0 else SelectedRaces.valid_keys return {race for race in SC2Race if race.get_title() in race_names} diff --git a/worlds/sc2/test/test_base.py b/worlds/sc2/test/test_base.py index 6110814c3b01..f0f778dc798c 100644 --- a/worlds/sc2/test/test_base.py +++ b/worlds/sc2/test/test_base.py @@ -8,8 +8,9 @@ from test.general import gen_steps, call_all from test.bases import WorldTestBase -from .. import SC2World +from .. import SC2World, SC2Campaign from .. import client +from .. import options class Sc2TestBase(WorldTestBase): game = client.SC2Context.game @@ -24,6 +25,18 @@ class Sc2SetupTestBase(unittest.TestCase): This allows potentially generating multiple worlds in one test case, useful for tracking down a rare / sporadic crash. """ + ALL_CAMPAIGNS = { + 'enabled_campaigns': options.EnabledCampaigns.valid_keys, + } + TERRAN_CAMPAIGNS = { + 'enabled_campaigns': {SC2Campaign.WOL.campaign_name, SC2Campaign.NCO.campaign_name,} + } + ZERG_CAMPAIGNS = { + 'enabled_campaigns': {SC2Campaign.HOTS.campaign_name,} + } + PROTOSS_CAMPAIGNS = { + 'enabled_campaigns': {SC2Campaign.PROPHECY.campaign_name, SC2Campaign.PROLOGUE.campaign_name, SC2Campaign.LOTV.campaign_name,} + } seed: Optional[int] = None game = SC2World.game player = 1 diff --git a/worlds/sc2/test/test_custom_mission_orders.py b/worlds/sc2/test/test_custom_mission_orders.py index f431e909a730..524e6481e579 100644 --- a/worlds/sc2/test/test_custom_mission_orders.py +++ b/worlds/sc2/test/test_custom_mission_orders.py @@ -6,10 +6,12 @@ from .. import MissionFlag from ..item import item_tables, item_names from BaseClasses import ItemClassification +from .. import options class TestCustomMissionOrders(Sc2SetupTestBase): def test_mini_wol_generates(self): world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': 'custom', 'custom_mission_order': { 'Mini Wings of Liberty': { @@ -137,6 +139,7 @@ def test_start_inventory_and_necessary_item_appears_once(self): test_item = item_names.ZERGLING_METABOLIC_BOOST world_options = { 'mission_order': 'custom', + 'enabled_campaigns': set(options.EnabledCampaigns.valid_keys), 'start_inventory': { test_item: 1 }, 'custom_mission_order': { 'test': { @@ -164,6 +167,7 @@ def test_start_inventory_and_locked_and_necessary_item_appears_once(self): test_item = item_names.ZERGLING_METABOLIC_BOOST world_options = { 'mission_order': 'custom', + 'enabled_campaigns': set(options.EnabledCampaigns.valid_keys), 'start_inventory': { test_item: 1 }, 'locked_items': { test_item: 1 }, 'custom_mission_order': { @@ -192,6 +196,7 @@ def test_key_item_rule_creates_correct_item_amount(self): test_item = item_names.ZERGLING test_amount = 3 world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': 'custom', 'locked_items': { test_item: 1 }, # Make sure it is generated as normal 'custom_mission_order': { diff --git a/worlds/sc2/test/test_generation.py b/worlds/sc2/test/test_generation.py index 110fa93715ff..61de392c0c6f 100644 --- a/worlds/sc2/test/test_generation.py +++ b/worlds/sc2/test/test_generation.py @@ -16,6 +16,7 @@ class TestItemFiltering(Sc2SetupTestBase): def test_explicit_locks_excludes_interact_and_set_flags(self): world_options = { + **self.ALL_CAMPAIGNS, 'locked_items': { item_names.MARINE: 0, item_names.MARAUDER: 0, @@ -116,6 +117,8 @@ def test_excluding_groups_excludes_all_items_in_group(self): def test_excluding_mission_groups_excludes_all_missions_in_group(self): world_options = { + **self.ZERG_CAMPAIGNS, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'excluded_missions': [ mission_groups.MissionGroupNames.HOTS_ZERUS_MISSIONS, ], @@ -158,6 +161,8 @@ def test_starter_unit_populates_start_inventory(self): def test_excluding_all_terran_missions_excludes_all_terran_items(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'excluded_missions': [ @@ -173,6 +178,8 @@ def test_excluding_all_terran_missions_excludes_all_terran_items(self) -> None: def test_excluding_all_terran_build_missions_excludes_all_terran_units(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'excluded_missions': [ @@ -191,6 +198,8 @@ def test_excluding_all_terran_build_missions_excludes_all_terran_units(self) -> def test_excluding_all_zerg_and_kerrigan_missions_excludes_all_zerg_items(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'excluded_missions': [ @@ -206,6 +215,8 @@ def test_excluding_all_zerg_and_kerrigan_missions_excludes_all_zerg_items(self) def test_excluding_all_zerg_build_missions_excludes_zerg_units(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'excluded_missions': [ @@ -225,6 +236,8 @@ def test_excluding_all_zerg_build_missions_excludes_zerg_units(self) -> None: def test_excluding_all_protoss_missions_excludes_all_protoss_items(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'accessibility': 'locations', @@ -242,6 +255,8 @@ def test_excluding_all_protoss_missions_excludes_all_protoss_items(self) -> None def test_excluding_all_protoss_build_missions_excludes_protoss_units(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, + 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'accessibility': 'locations', @@ -287,6 +302,7 @@ def test_vanilla_items_only_excludes_terran_progressives(self) -> None: def test_vanilla_items_only_includes_only_nova_equipment_and_vanilla_and_filler_items(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, # Avoid options that lock non-vanilla items for logic @@ -516,6 +532,7 @@ def test_disabling_speedrun_locations_removes_them_from_the_pool(self) -> None: def test_nco_and_wol_picks_correct_starting_mission(self): world_options = { + 'mission_order': MissionOrder.option_vanilla, 'enabled_campaigns': { SC2Campaign.WOL.campaign_name, SC2Campaign.NCO.campaign_name @@ -530,7 +547,7 @@ def test_excluding_mission_short_name_excludes_all_variants_of_mission(self): mission_tables.SC2Mission.ZERO_HOUR.mission_name.split(" (")[0] ], 'mission_order': options.MissionOrder.option_grid, - 'selected_races': options.SelectRaces.valid_keys, + 'selected_races': options.SelectedRaces.valid_keys, 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'enabled_campaigns': { SC2Campaign.WOL.campaign_name, @@ -549,7 +566,7 @@ def test_excluding_mission_variant_excludes_just_that_variant(self): mission_tables.SC2Mission.ZERO_HOUR.mission_name ], 'mission_order': options.MissionOrder.option_grid, - 'selected_races': options.SelectRaces.valid_keys, + 'selected_races': options.SelectedRaces.valid_keys, 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'enabled_campaigns': { SC2Campaign.WOL.campaign_name, @@ -757,7 +774,7 @@ def test_weapon_armor_upgrades_generic_upgrade_missions_no_countermeasure_needed def test_kerrigan_levels_per_mission_triggering_pre_fill(self): world_options = { - # Vanilla WoL with all missions + **self.ALL_CAMPAIGNS, 'mission_order': options.MissionOrder.option_custom, 'custom_mission_order': { 'campaign': { @@ -798,7 +815,7 @@ def test_kerrigan_levels_per_mission_triggering_pre_fill(self): def test_kerrigan_levels_per_mission_and_generic_upgrades_both_triggering_pre_fill(self): world_options = { - # Vanilla WoL with all missions + **self.ALL_CAMPAIGNS, 'mission_order': options.MissionOrder.option_custom, 'custom_mission_order': { 'campaign': { @@ -843,10 +860,9 @@ def test_kerrigan_levels_per_mission_and_generic_upgrades_both_triggering_pre_fi self.assertNotIn(item_names.KERRIGAN_LEVELS_70, itempool) self.assertNotIn(item_names.KERRIGAN_LEVELS_70, starting_inventory) - - def test_locking_required_items(self): world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': options.MissionOrder.option_custom, 'custom_mission_order': { 'campaign': { @@ -892,7 +908,7 @@ def test_fully_balanced_mission_races(self): 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': campaign_size, 'enabled_campaigns': EnabledCampaigns.valid_keys, - 'selected_races': options.SelectRaces.valid_keys, + 'selected_races': options.SelectedRaces.valid_keys, 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'mission_race_balancing': options.EnableMissionRaceBalancing.option_fully_balanced, } @@ -924,6 +940,7 @@ def test_setting_filter_weight_to_zero_excludes_that_item(self) -> None: }, 'max_number_of_upgrades': 2, 'mission_order': options.MissionOrder.option_grid, + **self.ALL_CAMPAIGNS, 'selected_races': { SC2Race.TERRAN.get_title(), }, @@ -960,6 +977,7 @@ def test_shields_filler_doesnt_appear_if_no_protoss_missions_appear(self) -> Non }, 'max_number_of_upgrades': 2, 'mission_order': options.MissionOrder.option_grid, + **self.ALL_CAMPAIGNS, 'selected_races': { SC2Race.TERRAN.get_title(), SC2Race.ZERG.get_title(), @@ -990,6 +1008,7 @@ def test_weapon_armor_upgrade_items_capped_by_max_upgrade_level(self) -> None: }, 'max_upgrade_level': MAX_LEVEL, 'mission_order': options.MissionOrder.option_grid, + **self.ALL_CAMPAIGNS, 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'generic_upgrade_items': options.GenericUpgradeItems.option_bundle_weapon_and_armor } @@ -1016,12 +1035,13 @@ def test_weapon_armor_upgrade_items_capped_by_max_upgrade_level(self) -> None: def test_ghost_of_a_chance_generates_without_nco(self) -> None: world_options = { + **self.TERRAN_CAMPAIGNS, 'mission_order': MissionOrder.option_custom, 'nova_ghost_of_a_chance_variant': NovaGhostOfAChanceVariant.option_auto, 'custom_mission_order': { 'test': { 'type': 'column', - 'size': 1, # Give the generator some space to place the key + 'size': 1, 'mission_pool': [ SC2Mission.GHOST_OF_A_CHANCE.mission_name ] @@ -1037,12 +1057,13 @@ def test_ghost_of_a_chance_generates_without_nco(self) -> None: def test_ghost_of_a_chance_generates_using_nco_nova(self) -> None: world_options = { + **self.TERRAN_CAMPAIGNS, 'mission_order': MissionOrder.option_custom, 'nova_ghost_of_a_chance_variant': NovaGhostOfAChanceVariant.option_nco, 'custom_mission_order': { 'test': { 'type': 'column', - 'size': 2, # Give the generator some space to place the key + 'size': 2, 'mission_pool': [ SC2Mission.LIBERATION_DAY.mission_name, # Starter mission SC2Mission.GHOST_OF_A_CHANCE.mission_name, @@ -1058,12 +1079,13 @@ def test_ghost_of_a_chance_generates_using_nco_nova(self) -> None: def test_ghost_of_a_chance_generates_with_nco(self) -> None: world_options = { + **self.TERRAN_CAMPAIGNS, 'mission_order': MissionOrder.option_custom, 'nova_ghost_of_a_chance_variant': NovaGhostOfAChanceVariant.option_auto, 'custom_mission_order': { 'test': { 'type': 'column', - 'size': 3, # Give the generator some space to place the key + 'size': 3, 'mission_pool': [ SC2Mission.LIBERATION_DAY.mission_name, # Starter mission SC2Mission.GHOST_OF_A_CHANCE.mission_name, @@ -1080,7 +1102,9 @@ def test_ghost_of_a_chance_generates_with_nco(self) -> None: def test_exclude_overpowered_items(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': MissionOrder.option_grid, + 'maximum_campaign_size': MaximumCampaignSize.range_end, 'exclude_overpowered_items': ExcludeOverpoweredItems.option_true, 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'selected_races': [SC2Race.TERRAN.get_title()], @@ -1096,7 +1120,9 @@ def test_exclude_overpowered_items(self) -> None: def test_exclude_overpowered_items_not_excluded(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': MissionOrder.option_grid, + 'maximum_campaign_size': MaximumCampaignSize.range_end, 'exclude_overpowered_items': ExcludeOverpoweredItems.option_false, 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'selected_races': [SC2Race.TERRAN.get_title()], @@ -1112,7 +1138,9 @@ def test_exclude_overpowered_items_not_excluded(self) -> None: def test_exclude_overpowered_items_vanilla_only(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': MissionOrder.option_grid, + 'maximum_campaign_size': MaximumCampaignSize.range_end, 'exclude_overpowered_items': ExcludeOverpoweredItems.option_true, 'vanilla_items_only': VanillaItemsOnly.option_true, 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, @@ -1129,7 +1157,9 @@ def test_exclude_overpowered_items_vanilla_only(self) -> None: def test_exclude_locked_overpowered_items(self) -> None: locked_item = item_names.BATTLECRUISER_ATX_LASER_BATTERY world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': MissionOrder.option_grid, + 'maximum_campaign_size': MaximumCampaignSize.range_end, 'exclude_overpowered_items': ExcludeOverpoweredItems.option_true, 'locked_items': [locked_item], 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, @@ -1147,7 +1177,9 @@ def test_unreleased_item_quantity(self) -> None: Checks if all unreleased items are marked properly not to generate """ world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': MissionOrder.option_grid, + 'maximum_campaign_size': MaximumCampaignSize.range_end, 'exclude_overpowered_items': ExcludeOverpoweredItems.option_false, 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, } @@ -1165,7 +1197,9 @@ def test_unreleased_item_quantity_locked(self) -> None: Locking overrides this behavior - if they're locked, they must appear """ world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': MissionOrder.option_grid, + 'maximum_campaign_size': MaximumCampaignSize.range_end, 'exclude_overpowered_items': ExcludeOverpoweredItems.option_false, 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, 'locked_items': {item_name: 0 for item_name in unreleased_items}, @@ -1180,10 +1214,12 @@ def test_unreleased_item_quantity_locked(self) -> None: def test_merc_excluded_excludes_merc_upgrades(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': MissionOrder.option_grid, 'maximum_campaign_size': MaximumCampaignSize.range_end, 'excluded_items': [item_name for item_name in item_groups.terran_mercenaries], 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'selected_races': [SC2Race.TERRAN.get_title()], } self.generate_world(world_options) @@ -1193,6 +1229,7 @@ def test_merc_excluded_excludes_merc_upgrades(self) -> None: def test_unexcluded_items_applies_over_op_items(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': MissionOrder.option_grid, 'maximum_campaign_size': MaximumCampaignSize.range_end, 'exclude_overpowered_items': ExcludeOverpoweredItems.option_true, @@ -1216,11 +1253,13 @@ def test_unexcluded_items_applies_over_op_items(self) -> None: def test_exclude_overpowered_items_and_not_allow_unit_nerfs(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': MissionOrder.option_grid, 'maximum_campaign_size': MaximumCampaignSize.range_end, 'exclude_overpowered_items': ExcludeOverpoweredItems.option_true, 'war_council_nerfs': options.WarCouncilNerfs.option_false, 'enable_race_swap': options.EnableRaceSwapVariants.option_shuffle_all, + 'selected_races': [SC2Race.PROTOSS.get_title()], } self.generate_world(world_options) diff --git a/worlds/sc2/test/test_item_filtering.py b/worlds/sc2/test/test_item_filtering.py index 898fb6da69c4..7f8251c52a59 100644 --- a/worlds/sc2/test/test_item_filtering.py +++ b/worlds/sc2/test/test_item_filtering.py @@ -15,6 +15,7 @@ def test_excluding_all_barracks_units_excludes_infantry_upgrades(self) -> None: }, 'required_tactics': 'standard', 'min_number_of_upgrades': 1, + **self.TERRAN_CAMPAIGNS, 'selected_races': { SC2Race.TERRAN.get_title() }, @@ -54,6 +55,7 @@ def test_excluding_one_item_of_multi_parent_doesnt_filter_children(self) -> None }, 'min_number_of_upgrades': 2, 'required_tactics': 'standard', + **self.ALL_CAMPAIGNS, 'selected_races': { SC2Race.PROTOSS.get_title() }, @@ -75,6 +77,7 @@ def test_excluding_all_items_in_multiparent_excludes_child_items(self) -> None: }, 'min_number_of_upgrades': 2, 'required_tactics': 'standard', + **self.PROTOSS_CAMPAIGNS, 'selected_races': { SC2Race.PROTOSS.get_title() }, diff --git a/worlds/sc2/test/test_rules.py b/worlds/sc2/test/test_rules.py index d43a4d4e2bbc..abd005c1718b 100644 --- a/worlds/sc2/test/test_rules.py +++ b/worlds/sc2/test/test_rules.py @@ -116,6 +116,7 @@ def _get_world( test_world.options.take_over_ai_allies.value = take_over_ai_allies test_world.options.kerrigan_presence.value = kerrigan_presence test_world.options.spear_of_adun_passive_ability_presence.value = spear_of_adun_passive_presence + test_world.options.enabled_campaigns.value = set(options.EnabledCampaigns.valid_keys) test_world.logic = SC2Logic(test_world) # type: ignore return test_world diff --git a/worlds/sc2/test/test_usecases.py b/worlds/sc2/test/test_usecases.py index b51758774ab0..7f3ac70fc211 100644 --- a/worlds/sc2/test/test_usecases.py +++ b/worlds/sc2/test/test_usecases.py @@ -272,7 +272,7 @@ def test_excluding_faction_on_vanilla_order_excludes_epilogue(self) -> None: def test_race_swap_pick_one_has_correct_length_and_includes_swaps(self) -> None: world_options = { - 'selected_races': options.SelectRaces.valid_keys, + 'selected_races': options.SelectedRaces.valid_keys, 'enable_race_swap': options.EnableRaceSwapVariants.option_pick_one, 'enabled_campaigns': { SC2Campaign.WOL.campaign_name, @@ -343,6 +343,7 @@ def test_start_inventory_upgrade_level_includes_only_correct_bundle(self) -> Non def test_kerrigan_max_active_abilities(self): target_number: int = 8 world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'selected_races': { @@ -361,6 +362,7 @@ def test_kerrigan_max_active_abilities(self): def test_kerrigan_max_passive_abilities(self): target_number: int = 3 world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'selected_races': { @@ -379,6 +381,7 @@ def test_kerrigan_max_passive_abilities(self): def test_spear_of_adun_max_active_abilities(self): target_number: int = 8 world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'selected_races': { @@ -398,6 +401,7 @@ def test_spear_of_adun_max_active_abilities(self): def test_spear_of_adun_max_autocasts(self): target_number: int = 2 world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'selected_races': { @@ -417,6 +421,7 @@ def test_spear_of_adun_max_autocasts(self): def test_nova_max_weapons(self): target_number: int = 3 world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'selected_races': { @@ -436,6 +441,7 @@ def test_nova_max_weapons(self): def test_nova_max_gadgets(self): target_number: int = 3 world_options = { + **self.ALL_CAMPAIGNS, 'mission_order': options.MissionOrder.option_grid, 'maximum_campaign_size': options.MaximumCampaignSize.range_end, 'selected_races': { @@ -453,6 +459,7 @@ def test_nova_max_gadgets(self): def test_mercs_only(self) -> None: world_options = { + **self.ALL_CAMPAIGNS, 'selected_races': [ SC2Race.TERRAN.get_title(), SC2Race.ZERG.get_title(), From 448f214cdbc08e46798506debf299020b401d94e Mon Sep 17 00:00:00 2001 From: Katelyn Gigante Date: Wed, 1 Oct 2025 02:39:04 +1000 Subject: [PATCH 0766/1218] core: Option to skip "unused" item links (#4608) * core: Option to skip "unused" item links * Update worlds/generic/docs/advanced_settings_en.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update BaseClasses.py Co-authored-by: Scipio Wright --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: Scipio Wright --- BaseClasses.py | 3 +++ Options.py | 1 + worlds/generic/docs/advanced_settings_en.md | 5 +++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index ca717b60f25f..855efc6009cf 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -261,6 +261,7 @@ def set_item_links(self): "local_items": set(item_link.get("local_items", [])), "non_local_items": set(item_link.get("non_local_items", [])), "link_replacement": replacement_prio.index(item_link["link_replacement"]), + "skip_if_solo": item_link.get("skip_if_solo", False), } for _name, item_link in item_links.items(): @@ -284,6 +285,8 @@ def set_item_links(self): for group_name, item_link in item_links.items(): game = item_link["game"] + if item_link["skip_if_solo"] and len(item_link["players"]) == 1: + continue group_id, group = self.add_group(group_name, game, set(item_link["players"])) group["item_pool"] = item_link["item_pool"] diff --git a/Options.py b/Options.py index 47d6c2d38708..dc1e8c907c78 100644 --- a/Options.py +++ b/Options.py @@ -1446,6 +1446,7 @@ class ItemLinks(OptionList): Optional("local_items"): [And(str, len)], Optional("non_local_items"): [And(str, len)], Optional("link_replacement"): Or(None, bool), + Optional("skip_if_solo"): Or(None, bool), } ]) diff --git a/worlds/generic/docs/advanced_settings_en.md b/worlds/generic/docs/advanced_settings_en.md index db93981bc9c8..2594307624b8 100644 --- a/worlds/generic/docs/advanced_settings_en.md +++ b/worlds/generic/docs/advanced_settings_en.md @@ -214,12 +214,13 @@ Timespinner: progression_balancing: 50 item_links: # Share part of your item pool with other players. - name: TSAll - item_pool: + item_pool: - Everything local_items: - Twin Pyramid Key - Timespinner Wheel replacement_item: null + skip_if_solo: true ``` #### This is a fully functional yaml file that will do all the following things: @@ -262,7 +263,7 @@ Timespinner: * For `Timespinner` all players in the `TSAll` item link group will share their entire item pool and the `Twin Pyramid Key` and `Timespinner Wheel` will be forced among the worlds of those in the group. The `null` replacement item will, instead of forcing a specific chosen item, allow the generator to randomly pick a filler item to replace the - player items. + player items. This item link will only be created if there are at least two players in the group. * `triggers` allows us to define a trigger such that if our `smallkey_shuffle` option happens to roll the `any_world` result it will also ensure that `bigkey_shuffle`, `map_shuffle`, and `compass_shuffle` are also forced to the `any_world` result. More information on triggers can be found in the From 5cec3f45f593e7a006fa18a6c6ffd756acdda776 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Tue, 30 Sep 2025 12:39:53 -0400 Subject: [PATCH 0767/1218] LADX: reorganize options page (#4851) * init * merge upstream/main * improve option tooltips, clean up file a bit * ladx feels like more of an ocean game * one more * more cleanup * some reorg * Apply suggestions from code review Co-authored-by: Scipio Wright * clean up accidental newlines * rewording * dont do the ohko alias --------- Co-authored-by: Scipio Wright --- worlds/ladx/Options.py | 416 ++++++++++++++++++++++------------------ worlds/ladx/__init__.py | 2 +- 2 files changed, 231 insertions(+), 187 deletions(-) diff --git a/worlds/ladx/Options.py b/worlds/ladx/Options.py index 8abfb0fbc958..2352e0fb91bb 100644 --- a/worlds/ladx/Options.py +++ b/worlds/ladx/Options.py @@ -23,11 +23,24 @@ def to_ladxr_option(self, all_options): class Logic(Choice, LADXROption): """ Affects where items are allowed to be placed. - [Normal] Playable without using any tricks or glitches. Can require knowledge from a vanilla playthrough, such as how to open Color Dungeon. - [Hard] More advanced techniques may be required, but glitches are not. Examples include tricky jumps, killing enemies with only pots. - [Glitched] Advanced glitches and techniques may be required, but extremely difficult or tedious tricks are not required. Examples include Bomb Triggers, Super Jumps and Jesus Jumps. - [Hell] Obscure knowledge and hard techniques may be required. Examples include featherless jumping with boots and/or hookshot, sequential pit buffers and unclipped superjumps. Things in here can be extremely hard to do or very time consuming.""" + + **Normal:** Playable without using any tricks or glitches. Can require + knowledge from a vanilla playthrough, such as how to open Color Dungeon. + + **Hard:** More advanced techniques may be required, but glitches are not. + Examples include tricky jumps, killing enemies with only pots. + + **Glitched:** Advanced glitches and techniques may be required, but + extremely difficult or tedious tricks are not required. Examples include + Bomb Triggers, Super Jumps and Jesus Jumps. + + **Hell:** Obscure knowledge and hard techniques may be required. Examples + include featherless jumping with boots and/or hookshot, sequential pit + buffers and unclipped superjumps. Things in here can be extremely hard to do + or very time consuming. + """ display_name = "Logic" + rich_text_doc = True ladxr_name = "logic" # option_casual = 0 option_normal = 1 @@ -40,8 +53,8 @@ class Logic(Choice, LADXROption): class TradeQuest(DefaultOffToggle, LADXROption): """ - [On] adds the trade items to the pool (the trade locations will always be local items) - [Off] (default) doesn't add them + Trade quest items are randomized. Each NPC takes its normal trade quest + item and gives a randomized item in return. """ display_name = "Trade Quest" ladxr_name = "tradequest" @@ -49,40 +62,32 @@ class TradeQuest(DefaultOffToggle, LADXROption): class TextShuffle(DefaultOffToggle): """ - [On] Shuffles all the text in the game - [Off] (default) doesn't shuffle them. + Shuffles all text in the game. """ display_name = "Text Shuffle" class Rooster(DefaultOnToggle, LADXROption): """ - [On] Adds the rooster to the item pool. - [Off] The rooster spot is still a check giving an item. But you will never find the rooster. In that case, any rooster spot is accessible without rooster by other means. + Adds the rooster to the item pool. If disabled, the overworld will be + modified so that any location requiring the rooster is accessible by other + means. """ display_name = "Rooster" ladxr_name = "rooster" -class Boomerang(Choice): - """ - [Normal] requires Magnifying Lens to get the boomerang. - [Gift] The boomerang salesman will give you a random item, and the boomerang is shuffled. +class EntranceShuffle(Choice, LADXROption): """ - display_name = "Boomerang" + Randomizes where overworld entrances lead. - normal = 0 - gift = 1 - default = gift + **Simple:** Single-entrance caves/houses that have items are shuffled + amongst each other. - -class EntranceShuffle(Choice, LADXROption): + If *Dungeon Shuffle* is enabled, then dungeons will be shuffled with all the + non-connector entrances in the pool. Note, some entrances can lead into water, use + the warp-to-home from the save&quit menu to escape this. """ - [WARNING] Experimental, may fail to fill - Randomizes where overworld entrances lead to. - [Simple] Single-entrance caves/houses that have items are shuffled amongst each other. - If random start location and/or dungeon shuffle is enabled, then these will be shuffled with all the non-connector entrance pool. - Note, some entrances can lead into water, use the warp-to-home from the save&quit menu to escape this.""" # [Advanced] Simple, but two-way connector caves are shuffled in their own pool as well. # [Expert] Advanced, but caves/houses without items are also shuffled into the Simple entrance pool. @@ -94,22 +99,22 @@ class EntranceShuffle(Choice, LADXROption): # option_expert = 3 # option_insanity = 4 default = option_none - display_name = "Experimental Entrance Shuffle" + display_name = "Entrance Shuffle" ladxr_name = "entranceshuffle" + rich_text_doc = True class DungeonShuffle(DefaultOffToggle, LADXROption): """ - [WARNING] Experimental, may fail to fill - Randomizes dungeon entrances within eachother + Randomizes dungeon entrances with each other. """ - display_name = "Experimental Dungeon Shuffle" + display_name = "Dungeon Shuffle" ladxr_name = "dungeonshuffle" class APTitleScreen(DefaultOnToggle): """ - Enables AP specific title screen and disables the intro cutscene + Enables AP specific title screen and disables the intro cutscene. """ display_name = "AP Title Screen" @@ -124,6 +129,7 @@ class BossShuffle(Choice): class DungeonItemShuffle(Choice): display_name = "Dungeon Item Shuffle" + rich_text_doc = True option_original_dungeon = 0 option_own_dungeons = 1 option_own_world = 2 @@ -138,12 +144,15 @@ class DungeonItemShuffle(Choice): class ShuffleNightmareKeys(DungeonItemShuffle): """ - Shuffle Nightmare Keys - [Original Dungeon] The item will be within its original dungeon - [Own Dungeons] The item will be within a dungeon in your world - [Own World] The item will be somewhere in your world - [Any World] The item could be anywhere - [Different World] The item will be somewhere in another world + **Original Dungeon:** The item will be within its original dungeon. + + **Own Dungeons:** The item will be within a dungeon in your world. + + **Own World:** The item will be somewhere in your world. + + **Any World:** The item could be anywhere. + + **Different World:** The item will be somewhere in another world. """ display_name = "Shuffle Nightmare Keys" ladxr_item = "NIGHTMARE_KEY" @@ -151,12 +160,15 @@ class ShuffleNightmareKeys(DungeonItemShuffle): class ShuffleSmallKeys(DungeonItemShuffle): """ - Shuffle Small Keys - [Original Dungeon] The item will be within its original dungeon - [Own Dungeons] The item will be within a dungeon in your world - [Own World] The item will be somewhere in your world - [Any World] The item could be anywhere - [Different World] The item will be somewhere in another world + **Original Dungeon:** The item will be within its original dungeon. + + **Own Dungeons:** The item will be within a dungeon in your world. + + **Own World:** The item will be somewhere in your world. + + **Any World:** The item could be anywhere. + + **Different World:** The item will be somewhere in another world. """ display_name = "Shuffle Small Keys" ladxr_item = "KEY" @@ -164,12 +176,15 @@ class ShuffleSmallKeys(DungeonItemShuffle): class ShuffleMaps(DungeonItemShuffle): """ - Shuffle Dungeon Maps - [Original Dungeon] The item will be within its original dungeon - [Own Dungeons] The item will be within a dungeon in your world - [Own World] The item will be somewhere in your world - [Any World] The item could be anywhere - [Different World] The item will be somewhere in another world + **Original Dungeon:** The item will be within its original dungeon. + + **Own Dungeons:** The item will be within a dungeon in your world. + + **Own World:** The item will be somewhere in your world. + + **Any World:** The item could be anywhere. + + **Different World:** The item will be somewhere in another world. """ display_name = "Shuffle Maps" ladxr_item = "MAP" @@ -177,12 +192,15 @@ class ShuffleMaps(DungeonItemShuffle): class ShuffleCompasses(DungeonItemShuffle): """ - Shuffle Dungeon Compasses - [Original Dungeon] The item will be within its original dungeon - [Own Dungeons] The item will be within a dungeon in your world - [Own World] The item will be somewhere in your world - [Any World] The item could be anywhere - [Different World] The item will be somewhere in another world + **Original Dungeon:** The item will be within its original dungeon. + + **Own Dungeons:** The item will be within a dungeon in your world. + + **Own World:** The item will be somewhere in your world. + + **Any World:** The item could be anywhere. + + **Different World:** The item will be somewhere in another world. """ display_name = "Shuffle Compasses" ladxr_item = "COMPASS" @@ -190,12 +208,15 @@ class ShuffleCompasses(DungeonItemShuffle): class ShuffleStoneBeaks(DungeonItemShuffle): """ - Shuffle Owl Beaks - [Original Dungeon] The item will be within its original dungeon - [Own Dungeons] The item will be within a dungeon in your world - [Own World] The item will be somewhere in your world - [Any World] The item could be anywhere - [Different World] The item will be somewhere in another world + **Original Dungeon:** The item will be within its original dungeon. + + **Own Dungeons:** The item will be within a dungeon in your world. + + **Own World:** The item will be somewhere in your world. + + **Any World:** The item could be anywhere. + + **Different World:** The item will be somewhere in another world. """ display_name = "Shuffle Stone Beaks" ladxr_item = "STONE_BEAK" @@ -203,13 +224,17 @@ class ShuffleStoneBeaks(DungeonItemShuffle): class ShuffleInstruments(DungeonItemShuffle): """ - Shuffle Instruments - [Original Dungeon] The item will be within its original dungeon - [Own Dungeons] The item will be within a dungeon in your world - [Own World] The item will be somewhere in your world - [Any World] The item could be anywhere - [Different World] The item will be somewhere in another world - [Vanilla] The item will be in its vanilla location in your world + **Original Dungeon:** The item will be within its original dungeon. + + **Own Dungeons:** The item will be within a dungeon in your world. + + **Own World:** The item will be somewhere in your world. + + **Any World:** The item could be anywhere. + + **Different World:** The item will be somewhere in another world. + + **Vanilla:** The item will be in its vanilla location in your world. """ display_name = "Shuffle Instruments" ladxr_item = "INSTRUMENT" @@ -220,12 +245,18 @@ class ShuffleInstruments(DungeonItemShuffle): class Goal(Choice, LADXROption): """ - The Goal of the game - [Instruments] The Wind Fish's Egg will only open if you have the required number of Instruments of the Sirens, and play the Ballad of the Wind Fish. - [Seashells] The Egg will open when you bring 20 seashells. The Ballad and Ocarina are not needed. - [Open] The Egg will start pre-opened. + The Goal of the game. + + **Instruments:** The Wind Fish's Egg will only open if you have the required + number of Instruments of the Sirens, and play the Ballad of the Wind Fish. + + **Seashells:** The Egg will open when you bring 20 seashells. The Ballad and + Ocarina are not needed. + + **Open:** The Egg will start pre-opened. """ display_name = "Goal" + rich_text_doc = True ladxr_name = "goal" option_instruments = 1 option_seashells = 2 @@ -242,7 +273,7 @@ def to_ladxr_option(self, all_options): class InstrumentCount(Range, LADXROption): """ - Sets the number of instruments required to open the Egg + Sets the number of instruments required to open the Egg. """ display_name = "Instrument Count" ladxr_name = None @@ -253,7 +284,8 @@ class InstrumentCount(Range, LADXROption): class NagMessages(DefaultOffToggle, LADXROption): """ - Controls if nag messages are shown when rocks and crystals are touched. Useful for glitches, annoying for everyone else. + Controls if nag messages are shown when rocks and crystals are touched. + Useful for glitches, annoying for everything else. """ display_name = "Nag Messages" ladxr_name = "nagmessages" @@ -262,31 +294,30 @@ class NagMessages(DefaultOffToggle, LADXROption): class MusicChangeCondition(Choice): """ Controls how the music changes. - [Sword] When you pick up a sword, the music changes - [Always] You always have the post-sword music + + **Sword:** When you pick up a sword, the music changes. + + **Always:** You always have the post-sword music. """ display_name = "Music Change Condition" + rich_text_doc = True option_sword = 0 option_always = 1 default = option_always -# Setting('hpmode', 'Gameplay', 'm', 'Health mode', options=[('default', '', 'Normal'), ('inverted', 'i', 'Inverted'), ('1', '1', 'Start with 1 heart'), ('low', 'l', 'Low max')], default='default', -# description=""" -# [Normal} health works as you would expect. -# [Inverted] you start with 9 heart containers, but killing a boss will take a heartcontainer instead of giving one. -# [Start with 1] normal game, you just start with 1 heart instead of 3. -# [Low max] replace heart containers with heart pieces."""), - - class HardMode(Choice, LADXROption): """ - [Oracle] Less iframes and health from drops. Bombs damage yourself. Water damages you without flippers. No piece of power or acorn. - [Hero] Switch version hero mode, double damage, no heart/fairy drops. - [One hit KO] You die on a single hit, always. + **Oracle:** Less iframes and health from drops. Bombs damage yourself. Water + damages you without flippers. No pieces of power or acorns. + + **Hero:** Switch version hero mode, double damage, no heart/fairy drops. + + **OHKO:** You die on a single hit, always. """ display_name = "Hard Mode" ladxr_name = "hardmode" + rich_text_doc = True option_none = 0 option_oracle = 1 option_hero = 2 @@ -294,44 +325,26 @@ class HardMode(Choice, LADXROption): default = option_none -# Setting('steal', 'Gameplay', 't', 'Stealing from the shop', -# options=[('always', 'a', 'Always'), ('never', 'n', 'Never'), ('default', '', 'Normal')], default='default', -# description="""Effects when you can steal from the shop. Stealing is bad and never in logic. -# [Normal] requires the sword before you can steal. -# [Always] you can always steal from the shop -# [Never] you can never steal from the shop."""), -class Bowwow(Choice): - """Allows BowWow to be taken into any area. Certain enemies and bosses are given a new weakness to BowWow. - [Normal] BowWow is in the item pool, but can be logically expected as a damage source. - [Swordless] The progressive swords are removed from the item pool. - """ - display_name = "BowWow" - normal = 0 - swordless = 1 - default = normal - - class Overworld(Choice, LADXROption): """ - [Open Mabe] Replaces rock on the east side of Mabe Village with bushes, allowing access to Ukuku Prairie without Power Bracelet. + **Open Mabe:** Replaces rock on the east side of Mabe Village with bushes, + allowing access to Ukuku Prairie without Power Bracelet. """ display_name = "Overworld" ladxr_name = "overworld" + rich_text_doc = True option_normal = 0 option_open_mabe = 1 default = option_normal -# Setting('superweapons', 'Special', 'q', 'Enable super weapons', default=False, -# description='All items will be more powerful, faster, harder, bigger stronger. You name it.'), - - class Quickswap(Choice, LADXROption): """ - Adds that the SELECT button swaps with either A or B. The item is swapped with the top inventory slot. The map is not available when quickswap is enabled. + Instead of opening the map, the *SELECT* button swaps the top item of your inventory on to your *A* or *B* button. """ display_name = "Quickswap" ladxr_name = "quickswap" + rich_text_doc = True option_none = 0 option_a = 1 option_b = 2 @@ -340,10 +353,11 @@ class Quickswap(Choice, LADXROption): class TextMode(Choice, LADXROption): """ - [Fast] Makes text appear twice as fast + **Fast:** Makes text appear twice as fast. """ display_name = "Text Mode" ladxr_name = "textmode" + rich_text_doc = True option_normal = 0 option_fast = 1 default = option_fast @@ -363,7 +377,8 @@ class LowHpBeep(Choice, LADXROption): class NoFlash(DefaultOnToggle, LADXROption): """ - Remove the flashing light effects from Mamu, shopkeeper and MadBatter. Useful for capture cards and people that are sensitive to these things. + Remove the flashing light effects from Mamu, shopkeeper and MadBatter. + Useful for capture cards and people that are sensitive to these things. """ display_name = "No Flash" ladxr_name = "noflash" @@ -371,23 +386,34 @@ class NoFlash(DefaultOnToggle, LADXROption): class BootsControls(Choice): """ - Adds additional button to activate Pegasus Boots (does nothing if you haven't picked up your boots!) - [Vanilla] Nothing changes, you have to equip the boots to use them - [Bracelet] Holding down the button for the bracelet also activates boots (somewhat like Link to the Past) - [Press A] Holding down A activates boots - [Press B] Holding down B activates boots + Adds an additional button to activate Pegasus Boots (does nothing if you + haven't picked up your boots!) + + **Vanilla:** Nothing changes, you have to equip the boots to use them. + + **Bracelet:** Holding down the button for the bracelet also activates boots + (somewhat like Link to the Past). + + **Press A:** Holding down A activates boots. + + **Press B:** Holding down B activates boots. """ display_name = "Boots Controls" + rich_text_doc = True option_vanilla = 0 option_bracelet = 1 option_press_a = 2 + alias_a = 2 option_press_b = 3 + alias_b = 3 class LinkPalette(Choice, LADXROption): """ - Sets link's palette - A-D are color palettes usually used during the damage animation and can change based on where you are. + Sets Link's palette. + + A-D are color palettes usually used during the damage animation and can + change based on where you are. """ display_name = "Link's Palette" ladxr_name = "linkspalette" @@ -408,14 +434,21 @@ def to_ladxr_option(self, all_options): class TrendyGame(Choice): """ - [Easy] All of the items hold still for you - [Normal] The vanilla behavior - [Hard] The trade item also moves - [Harder] The items move faster - [Hardest] The items move diagonally - [Impossible] The items move impossibly fast, may scroll on and off the screen + **Easy:** All of the items hold still for you. + + **Normal:** The vanilla behavior. + + **Hard:** The trade item also moves. + + **Harder:** The items move faster. + + **Hardest:** The items move diagonally. + + **Impossible:** The items move impossibly fast, may scroll on and off the + screen. """ display_name = "Trendy Game" + rich_text_doc = True option_easy = 0 option_normal = 1 option_hard = 2 @@ -435,15 +468,24 @@ class GfxMod(DefaultOffToggle): class Palette(Choice): """ Sets the palette for the game. - Note: A few places aren't patched, such as the menu and a few color dungeon tiles. - [Normal] The vanilla palette - [1-Bit] One bit of color per channel - [2-Bit] Two bits of color per channel - [Greyscale] Shades of grey - [Pink] Aesthetic - [Inverted] Inverted + + Note: A few places aren't patched, such as the menu and a few color dungeon + tiles. + + **Normal:** The vanilla palette. + + **1-Bit:** One bit of color per channel. + + **2-Bit:** Two bits of color per channel. + + **Greyscale:** Shades of grey. + + **Pink:** Aesthetic. + + **Inverted:** Inverted. """ display_name = "Palette" + rich_text_doc = True option_normal = 0 option_1bit = 1 option_2bit = 2 @@ -454,12 +496,15 @@ class Palette(Choice): class Music(Choice, LADXROption): """ - [Vanilla] Regular Music - [Shuffled] Shuffled Music - [Off] No music + **Vanilla:** Regular Music + + **Shuffled:** Shuffled Music + + **Off:** No music """ display_name = "Music" ladxr_name = "music" + rich_text_doc = True option_vanilla = 0 option_shuffled = 1 option_off = 2 @@ -475,10 +520,14 @@ def to_ladxr_option(self, all_options): class Warps(Choice): """ - [Improved] Adds remake style warp screen to the game. Choose your warp destination on the map after jumping in a portal and press B to select. - [Improved Additional] Improved warps, and adds a warp point at Crazy Tracy's house (the Mambo teleport spot) and Eagle's Tower. + **Improved:** Adds remake style warp screen to the game. Choose your warp + destination on the map after jumping in a portal and press *B* to select. + + **Improved Additional:** Improved warps, and adds a warp point at Crazy + Tracy's house (the Mambo teleport spot) and Eagle's Tower. """ display_name = "Warps" + rich_text_doc = True option_vanilla = 0 option_improved = 1 option_improved_additional = 2 @@ -487,19 +536,24 @@ class Warps(Choice): class InGameHints(DefaultOnToggle): """ - When enabled, owl statues and library books may indicate the location of your items in the multiworld. + When enabled, owl statues and library books may indicate the location of + your items in the multiworld. """ display_name = "In-game Hints" class TarinsGift(Choice): """ - [Local Progression] Forces Tarin's gift to be an item that immediately opens up local checks. - Has little effect in single player games, and isn't always necessary with randomized entrances. - [Bush Breaker] Forces Tarin's gift to be an item that can destroy bushes. - [Any Item] Tarin's gift can be any item for any world + **Local Progression:** Forces Tarin's gift to be an item that immediately + opens up local checks. Has little effect in single player games, and isn't + always necessary with randomized entrances. + + **Bush Breaker:** Forces Tarin's gift to be an item that can destroy bushes. + + **Any Item:** Tarin's gift can be any item for any world """ display_name = "Tarin's Gift" + rich_text_doc = True option_local_progression = 0 option_bush_breaker = 1 option_any_item = 2 @@ -508,67 +562,69 @@ class TarinsGift(Choice): class StabilizeItemPool(DefaultOffToggle): """ - By default, rupees in the item pool may be randomly swapped with bombs, arrows, powders, or capacity upgrades. This option disables that swapping, which is useful for plando. + By default, some rupees in the item pool are randomly swapped with bombs, + arrows, powders, or capacity upgrades. This set of items is also used as + filler. This option disables that swapping and makes *Nothing* the filler + item. """ display_name = "Stabilize Item Pool" + rich_text_doc = True class ForeignItemIcons(Choice): """ Choose how to display foreign items. - [Guess By Name] Foreign items can look like any Link's Awakening item. - [Indicate Progression] Foreign items are either a Piece of Power (progression) or Guardian Acorn (non-progression). + + **Guess By Name:** Foreign items can look like any Link's Awakening item. + + **Indicate Progression:** Foreign items are either a Piece of Power + (progression) or Guardian Acorn (non-progression). """ display_name = "Foreign Item Icons" + rich_text_doc = True option_guess_by_name = 0 option_indicate_progression = 1 default = option_guess_by_name ladx_option_groups = [ - OptionGroup("Goal Options", [ - Goal, - InstrumentCount, + OptionGroup("Gameplay Adjustments", [ + InGameHints, + TarinsGift, + HardMode, + TrendyGame, ]), - OptionGroup("Shuffles", [ + OptionGroup("World Layout", [ + Overworld, + Warps, + DungeonShuffle, + EntranceShuffle, + ]), + OptionGroup("Item Pool", [ ShuffleInstruments, ShuffleNightmareKeys, ShuffleSmallKeys, ShuffleMaps, ShuffleCompasses, - ShuffleStoneBeaks - ]), - OptionGroup("Warp Points", [ - Warps, - ]), - OptionGroup("Miscellaneous", [ + ShuffleStoneBeaks, TradeQuest, Rooster, - TarinsGift, - Overworld, - TrendyGame, - InGameHints, - NagMessages, StabilizeItemPool, - Quickswap, - HardMode, - BootsControls ]), - OptionGroup("Experimental", [ - DungeonShuffle, - EntranceShuffle - ]), - OptionGroup("Visuals & Sound", [ + OptionGroup("Quality of Life & Aesthetic", [ + NagMessages, + Quickswap, + BootsControls, + ForeignItemIcons, + GfxMod, LinkPalette, Palette, - TextShuffle, - ForeignItemIcons, APTitleScreen, - GfxMod, + TextShuffle, + TextMode, Music, MusicChangeCondition, LowHpBeep, - TextMode, NoFlash, ]) ] @@ -576,24 +632,12 @@ class ForeignItemIcons(Choice): @dataclass class LinksAwakeningOptions(PerGameCommonOptions): logic: Logic - # 'heartpiece': DefaultOnToggle, # description='Includes heart pieces in the item pool'), - # 'seashells': DefaultOnToggle, # description='Randomizes the secret sea shells hiding in the ground/trees. (chest are always randomized)'), - # 'heartcontainers': DefaultOnToggle, # description='Includes boss heart container drops in the item pool'), - # 'instruments': DefaultOffToggle, # description='Instruments are placed on random locations, dungeon goal will just contain a random item.'), - tradequest: TradeQuest # description='Trade quest items are randomized, each NPC takes its normal trade quest item, but gives a random item'), - # 'witch': DefaultOnToggle, # description='Adds both the toadstool and the reward for giving the toadstool to the witch to the item pool'), - rooster: Rooster # description='Adds the rooster to the item pool. Without this option, the rooster spot is still a check giving an item. But you will never find the rooster. Any rooster spot is accessible without rooster by other means.'), - # 'boomerang': Boomerang, - # 'randomstartlocation': DefaultOffToggle, # 'Randomize where your starting house is located'), - experimental_dungeon_shuffle: DungeonShuffle # 'Randomizes the dungeon that each dungeon entrance leads to'), + tradequest: TradeQuest + rooster: Rooster + experimental_dungeon_shuffle: DungeonShuffle experimental_entrance_shuffle: EntranceShuffle - # 'bossshuffle': BossShuffle, - # 'minibossshuffle': BossShuffle, goal: Goal instrument_count: InstrumentCount - # 'itempool': ItemPool, - # 'bowwow': Bowwow, - # 'overworld': Overworld, link_palette: LinkPalette warps: Warps trendy_game: TrendyGame diff --git a/worlds/ladx/__init__.py b/worlds/ladx/__init__.py index f17b602ed13d..58d6c1681f25 100644 --- a/worlds/ladx/__init__.py +++ b/worlds/ladx/__init__.py @@ -71,7 +71,7 @@ class LinksAwakeningWebWorld(WebWorld): "setup/en", ["zig"] )] - theme = "dirt" + theme = "ocean" option_groups = ladx_option_groups options_presets: typing.Dict[str, typing.Dict[str, typing.Any]] = { "Keysanity": { From 50c9d056c9ab1097d658714176d5f835634661c7 Mon Sep 17 00:00:00 2001 From: Goblin God <37878138+esutley@users.noreply.github.com> Date: Tue, 30 Sep 2025 11:40:20 -0500 Subject: [PATCH 0768/1218] KH1: Fix a small error in option descriptions #5445 --- worlds/kh1/Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/kh1/Options.py b/worlds/kh1/Options.py index f64e927fe1e9..879ea4c331f3 100644 --- a/worlds/kh1/Options.py +++ b/worlds/kh1/Options.py @@ -257,7 +257,7 @@ class KeybladeStats(Choice): """ Determines whether Keyblade stats should be randomized. - Randomize: Randomly generates STR and MP bonuses for each keyblade between the defined minimums and maximums. + Randomize: Randomly generates stats for each keyblade between the defined minimums and maximums. Shuffle: Shuffles the stats of the vanilla keyblades amongst each other. From f26fcc0edab7c63f684104e46322e9732084e134 Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Tue, 30 Sep 2025 12:47:17 -0400 Subject: [PATCH 0769/1218] LADX: use generic slot name for slots 101+ (#5208) * init * we already had the generic name, just use it * cap hints at 101 * nevermind, the name is just baked in here --- LinksAwakeningClient.py | 6 +++--- worlds/ladx/LADXR/generator.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/LinksAwakeningClient.py b/LinksAwakeningClient.py index 14aaa415f1da..293e782f59ea 100644 --- a/LinksAwakeningClient.py +++ b/LinksAwakeningClient.py @@ -412,10 +412,10 @@ async def recved_item_from_ap(self, item_id, from_player, next_index): status = (await self.gameboy.async_read_memory_safe(LAClientConstants.wLinkStatusBits))[0] item_id -= LABaseID - # The player name table only goes up to 100, so don't go past that + # The player name table only goes up to 101, so don't go past that # Even if it didn't, the remote player _index_ byte is just a byte, so 255 max - if from_player > 100: - from_player = 100 + if from_player > 101: + from_player = 101 next_index += 1 self.gameboy.write_memory(LAClientConstants.wLinkGiveItem, [ diff --git a/worlds/ladx/LADXR/generator.py b/worlds/ladx/LADXR/generator.py index 4ae31d584941..f4023469d72b 100644 --- a/worlds/ladx/LADXR/generator.py +++ b/worlds/ladx/LADXR/generator.py @@ -271,9 +271,9 @@ def generateRom(base_rom: bytes, args, patch_data: Dict): mw = None if spot.item_owner != spot.location_owner: mw = spot.item_owner - if mw > 100: + if mw > 101: # There are only 101 player name slots (99 + "The Server" + "another world"), so don't use more than that - mw = 100 + mw = 101 spot.patch(rom, spot.item, multiworld=mw) patches.enemies.changeBosses(rom, patch_data["world_setup"]["boss_mapping"]) patches.enemies.changeMiniBosses(rom, patch_data["world_setup"]["miniboss_mapping"]) From 0882c0fa9724f418636478341112c4bb829a01cc Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 30 Sep 2025 19:27:43 +0200 Subject: [PATCH 0770/1218] Core: only store persistent changes if there are changes (#5311) --- Utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Utils.py b/Utils.py index d8dab4fcb070..a14e737c28d0 100644 --- a/Utils.py +++ b/Utils.py @@ -323,11 +323,13 @@ def get_options() -> Settings: return get_settings() -def persistent_store(category: str, key: str, value: typing.Any): - path = user_path("_persistent_storage.yaml") +def persistent_store(category: str, key: str, value: typing.Any, force_store: bool = False): storage = persistent_load() + if not force_store and category in storage and key in storage[category] and storage[category][key] == value: + return # no changes necessary category_dict = storage.setdefault(category, {}) category_dict[key] = value + path = user_path("_persistent_storage.yaml") with open(path, "wt") as f: f.write(dump(storage, Dumper=Dumper)) From e6fb7d9c6a08a5cf481b34e61f9a0c216c7cae0d Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Tue, 30 Sep 2025 20:23:33 +0200 Subject: [PATCH 0771/1218] Core: Add an "options" arg to setup_multiworld so that non-default options can be set in it #5414 --- test/general/__init__.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/test/general/__init__.py b/test/general/__init__.py index 92ffc77ee6d9..53f77a516afb 100644 --- a/test/general/__init__.py +++ b/test/general/__init__.py @@ -1,5 +1,5 @@ from argparse import Namespace -from typing import List, Optional, Tuple, Type, Union +from typing import Any, List, Optional, Tuple, Type from BaseClasses import CollectionState, Item, ItemClassification, Location, MultiWorld, Region from worlds import network_data_package @@ -31,8 +31,8 @@ def setup_solo_multiworld( return setup_multiworld(world_type, steps, seed) -def setup_multiworld(worlds: Union[List[Type[World]], Type[World]], steps: Tuple[str, ...] = gen_steps, - seed: Optional[int] = None) -> MultiWorld: +def setup_multiworld(worlds: list[type[World]] | type[World], steps: tuple[str, ...] = gen_steps, + seed: int | None = None, options: dict[str, Any] | list[dict[str, Any]] = None) -> MultiWorld: """ Creates a multiworld with a player for each provided world type, allowing duplicates, setting default options, and calling the provided gen steps. @@ -40,20 +40,27 @@ def setup_multiworld(worlds: Union[List[Type[World]], Type[World]], steps: Tuple :param worlds: Type/s of worlds to generate a multiworld for :param steps: Gen steps that should be called before returning. Default calls through pre_fill :param seed: The seed to be used when creating this multiworld + :param options: Options to set on each world. If just one dict of options is passed, it will be used for all worlds. :return: The generated multiworld """ if not isinstance(worlds, list): worlds = [worlds] + + if options is None: + options = [{}] * len(worlds) + elif not isinstance(options, list): + options = [options] * len(worlds) + players = len(worlds) multiworld = MultiWorld(players) multiworld.game = {player: world_type.game for player, world_type in enumerate(worlds, 1)} multiworld.player_name = {player: f"Tester{player}" for player in multiworld.player_ids} multiworld.set_seed(seed) args = Namespace() - for player, world_type in enumerate(worlds, 1): + for player, (world_type, option_overrides) in enumerate(zip(worlds, options), 1): for key, option in world_type.options_dataclass.type_hints.items(): updated_options = getattr(args, key, {}) - updated_options[player] = option.from_any(option.default) + updated_options[player] = option.from_any(option_overrides.get(key, option.default)) setattr(args, key, updated_options) multiworld.set_options(args) multiworld.state = CollectionState(multiworld) From 6a63de2f0f5e46335c3a03712e24fb77e193c270 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Tue, 30 Sep 2025 15:39:41 -0400 Subject: [PATCH 0772/1218] TUNIC: Fuse and Bell Shuffle (#5420) * Making the fix better (thanks medic) * Make it actually return false if it gets to the backup lists and fails them * Fix stuff after merge * Add outlet regions, create new regions as needed for them * Put together part of decoupled and direction pairs * make direction pairs work * Make decoupled work * Make fixed shop work again * Fix a few minor bugs * Fix a few minor bugs * Fix plando * god i love programming * Reorder portal list * Update portal sorter for variable shops * Add missing parameter * Some cleanup of prints and functions * Fix typo * it's aliiiiiive * Make seed groups not sync decoupled * Add test with full-shop plando * Fix bug with vanilla portals * Handle plando connections and direction pair errors * Update plando checking for decoupled * Fix typo * Fix exception text to be shorter * Add some more comments * Add todo note * Remove unused safety thing * Remove extra plando connections definition in options * Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log * Fix weird edge case that is technically user error * Add note to fixed shop * Fix parsing shop names in UT * Remove debug print * Actually make UT work * multiworld. to world. * Fix typo from merge * Make it so the shops show up in the entrance hints * Fix bug in ladder storage rules * Remove blank line * # Conflicts: # worlds/tunic/__init__.py # worlds/tunic/er_data.py # worlds/tunic/er_rules.py # worlds/tunic/er_scripts.py # worlds/tunic/rules.py # worlds/tunic/test/test_access.py * Fix issues after merge * Update plando connections stuff in docs * Make early bushes only contain grass * Fix library mistake * Backport changes to grass rando (#20) * Backport changes to grass rando * add_rule instead of set_rule for the special cases, add special cases for back of swamp laurels area cause I should've made a new region for the swamp upper entrance * Remove item name group for grass * Update grass rando option descriptions - Also ignore grass fill for single player games * Ignore grass fill option for solo rando * Update er_rules.py * Fix pre fill issue * Remove duplicate option * Add excluded grass locations back * Hide grass fill option from simple ui options page * Check for start with sword before setting grass rules * Update worlds/tunic/options.py Co-authored-by: Scipio Wright * has_stick -> has_melee * has_stick -> has_melee * Add a failsafe for direction pairing * Fix playthrough crash bug * Remove init from logicmixin * Updates per code review (thanks hesto) * has_stick to has_melee in newer update * has_stick to has_melee in newer update * Exclude grass from get_filler_item_name - non-grass rando games were accidentally seeing grass items get shuffled in as filler, which is funny but probably shouldn't happen * Update worlds/tunic/__init__.py Co-authored-by: Scipio Wright * Apply suggestions from code review Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Co-authored-by: Scipio Wright * change the rest of grass_fill to local_fill * Filter out grass from filler_items * remove -> discard * Update worlds/tunic/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Starting out * Rules for breakable regions * # Conflicts: # worlds/tunic/__init__.py # worlds/tunic/combat_logic.py # worlds/tunic/er_data.py # worlds/tunic/er_rules.py # worlds/tunic/er_scripts.py * Cleanup more stuff after merge * Revert "Cleanup more stuff after merge" This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d. * Revert "# Conflicts:" This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30. * Cleanup more stuff after merge * change has_stick to has_melee * Update grass list with combat logic regions * More fixes from combat logic merge * Fix some dumb stuff (#21) * Reorganize pre fill for grass * make the rest of it work, it's pr ready, boom * Make it work in not pot shuffle * Merge grass rando * multiworld -> world get_location, use has_any * Swap out region for West Garden Before Terry grass * Adjust west garden rules to add west combat region * Adjust grass regions for south checkpoint grass * Adjust grass regions for after terry grass * Adjust grass regions for west combat grass * Adjust grass regions for dagger house grass * Adjust grass regions for south checkpoint grass, adjust regions and rules for some related locations * Finish the remainder of the west garden grass, reformat ruined atoll a little * More hex quest updates - Implement page ability shuffle for hex quest - Fix keys behind bosses if hex goal is less than 3 - Added check to fix conflicting hex quest options - Add option to slot data * Change option comparison * Change option checking and fix some stuff - also keep prayer first on low hex counts * Update option defaulting * Update option checking * Fix option assignment again * Merge in hex hunt * Merge in changes * Clean up imports * Add ability type to UT stuff * merge it all * Make local fill work across pot and grass (to be adjusted later) * Make separate pools for the grass and non-grass fills * Fix id overlap * Update option description * Fix default * Reorder localfill option desc * Load the purgatory ones in * Adjustments after merge * Fully remove logicrules * Fix UT support with fixed shop option * Add breakable shuffle to the ut stuff * Make it load in a specific number of locations * Add Silent's spoiler log ability thing * Fix for groups * Fix for groups * Fix typo * Fix hex quest UT support * Use .get * UT fixes, classification fixes * Rename some locations * Adjust guard house names * Adjust guard house names * Rework create_item * Fix for plando connections * Rename, add new breakables * Rename more stuff * Time to rename them again * Fix issue with fixed shop + decoupled * Put in an exception to catch that error in the future * Update create_item to match main * Update spoiler log lines for hex abilities * Burn the signs down * Bring over the combat logic fix * Merge in combat logic fix * Silly static method thing * Move a few areas to before well instead of east forest * Add an all_random hidden option for dev stuff * Port over changes from main * Fix west courtyard pot regions * Remove debug prints * Fix fortress courtyard and beneath the fortress loc groups again * Add exception handling to deal with duplicate apworlds * Fix typo * More missing loc group conversions * Initial fuse shuffle stuff * Fix gun missing from combat_items, add new for combat logic cache, very slight refactor of check_combat_reqs to let it do the changeover in a less complicated fashion, fix area being a boss area rather than non-boss area for a check * Add fuse shuffle logic * reorder atoll statue rule * Update traversal reqs * Remove fuse shuffle from temple door * Combine rules and option checking * Add bell shuffle; fix fuse location groups * Fix portal rules not requiring prayer * Merge the grass laurels exit grass PR * Merge in fortress bridge PR * Do a little clean up * Fix a regression * Update after merge * Some more stuff * More Silent changes * Update more info section in game info page * Fix rules for atoll and swamp fuses * Precollect cathedral fuse in ER * actually just make the fuse useful instead of progression * Add it to the swamp and cath rules too * Fix cath fuse name * Minor fixes and edits * Some UT stuff * Fix a couple more groups * Move a bunch of UT stuff to its own file * Fix up a couple UT things * Couple minor ER fixes * Formatting change * UT poptracker stuff enabled since it's optional in one of the releases * Add author string to world class * Adjust local fill option name * Update ut_stuff to match the PR * Add exception handling for UT with old apworld * Fix missing tracker_world * Remove extra entrance from cath main -> elevator Entry <-> Elev exists, Entry <-> Main exists So no connection is needed between Main and Elev * Fix so that decoupled doesn't incorrectly use get_portal_info and get_paired_portal * Fix so that decoupled doesn't incorrectly use get_portal_info and get_paired_portal * Update for breakables poptracker * Backup and warnings instead * Update typing * Delete old regions and rules, move stuff to logic_helpers and constants * Delete now much less useful tests * Fix breakables map tracking * Add more comments to init * Add todo to grass.py * Fix up tests * Fully remove fixed_shop * Finish hard deprecating FixedShop * Fix zig skip showing up in decoupled fixed shop * Make local_fill show up on the website * Merge with main * Fixes after merge * More fixes after merge * oh right that's why it was there, circular imports * Swap {} to () * Add fuse and bell shuffle to seed groups since they're logically significant for entrance pairing --------- Co-authored-by: silent-destroyer Co-authored-by: Silent <110704408+silent-destroyer@users.noreply.github.com> Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> --- worlds/tunic/__init__.py | 56 ++++++++---- worlds/tunic/bells.py | 39 ++++++++ worlds/tunic/er_data.py | 2 +- worlds/tunic/er_rules.py | 65 +++++++------- worlds/tunic/er_scripts.py | 16 ++-- worlds/tunic/fuses.py | 147 +++++++++++++++++++++++++------ worlds/tunic/items.py | 25 ++++++ worlds/tunic/locations.py | 8 +- worlds/tunic/logic_helpers.py | 39 ++++++-- worlds/tunic/options.py | 22 ++++- worlds/tunic/test/test_access.py | 2 +- worlds/tunic/ut_stuff.py | 4 +- 12 files changed, 323 insertions(+), 102 deletions(-) create mode 100644 worlds/tunic/bells.py diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 9fca0a7d59f6..1d59eeaecadf 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -7,13 +7,13 @@ from settings import Group, Bool, FilePath from worlds.AutoWorld import WebWorld, World -# from .bells import bell_location_groups, bell_location_name_to_id +from .bells import bell_location_groups, bell_location_name_to_id from .breakables import breakable_location_name_to_id, breakable_location_groups, breakable_location_table from .combat_logic import area_data, CombatState from .er_data import portal_mapping, RegionInfo, tunic_er_regions from .er_rules import set_er_location_rules from .er_scripts import create_er_regions, verify_plando_directions -# from .fuses import fuse_location_name_to_id, fuse_location_groups +from .fuses import fuse_location_name_to_id, fuse_location_groups from .grass import grass_location_table, grass_location_name_to_id, grass_location_name_groups, excluded_grass_locations from .items import (item_name_to_id, item_table, item_name_groups, fool_tiers, filler_items, slot_data_item_names, combat_items) @@ -75,6 +75,8 @@ class SeedGroup(TypedDict): entrance_layout: int # entrance layout value has_decoupled_enabled: bool # for checking that players don't have conflicting options plando: list[PlandoConnection] # consolidated plando connections for the seed group + bell_shuffle: bool # off controls + fuse_shuffle: bool # off controls class TunicWorld(World): @@ -98,17 +100,17 @@ class TunicWorld(World): location_name_groups.setdefault(group_name, set()).update(members) for group_name, members in breakable_location_groups.items(): location_name_groups.setdefault(group_name, set()).update(members) - # for group_name, members in fuse_location_groups.items(): - # location_name_groups.setdefault(group_name, set()).update(members) - # for group_name, members in bell_location_groups.items(): - # location_name_groups.setdefault(group_name, set()).update(members) + for group_name, members in fuse_location_groups.items(): + location_name_groups.setdefault(group_name, set()).update(members) + for group_name, members in bell_location_groups.items(): + location_name_groups.setdefault(group_name, set()).update(members) item_name_to_id = item_name_to_id location_name_to_id = standard_location_name_to_id.copy() location_name_to_id.update(grass_location_name_to_id) location_name_to_id.update(breakable_location_name_to_id) - # location_name_to_id.update(fuse_location_name_to_id) - # location_name_to_id.update(bell_location_name_to_id) + location_name_to_id.update(fuse_location_name_to_id) + location_name_to_id.update(bell_location_name_to_id) player_location_table: dict[str, int] ability_unlocks: dict[str, int] @@ -227,11 +229,11 @@ def replace_connection(old_cxn: PlandoConnection, new_cxn: PlandoConnection, ind self.player_location_table.update({name: num for name, num in breakable_location_name_to_id.items() if not name.startswith("Purgatory")}) - # if self.options.shuffle_fuses: - # self.player_location_table.update(fuse_location_name_to_id) - # - # if self.options.shuffle_bells: - # self.player_location_table.update(bell_location_name_to_id) + if self.options.shuffle_fuses: + self.player_location_table.update(fuse_location_name_to_id) + + if self.options.shuffle_bells: + self.player_location_table.update(bell_location_name_to_id) @classmethod def stage_generate_early(cls, multiworld: MultiWorld) -> None: @@ -259,7 +261,9 @@ def stage_generate_early(cls, multiworld: MultiWorld) -> None: laurels_at_10_fairies=tunic.options.laurels_location == LaurelsLocation.option_10_fairies, entrance_layout=tunic.options.entrance_layout.value, has_decoupled_enabled=bool(tunic.options.decoupled), - plando=tunic.options.plando_connections.value.copy()) + plando=tunic.options.plando_connections.value.copy(), + bell_shuffle=bool(tunic.options.shuffle_bells), + fuse_shuffle=bool(tunic.options.shuffle_fuses)) continue # I feel that syncing this one is worse than erroring out if bool(tunic.options.decoupled) != cls.seed_groups[group]["has_decoupled_enabled"]: @@ -277,6 +281,12 @@ def stage_generate_early(cls, multiworld: MultiWorld) -> None: # laurels at 10 fairies changes logic for secret gathering place placement if tunic.options.laurels_location == 3: cls.seed_groups[group]["laurels_at_10_fairies"] = True + # off is more restrictive + if not tunic.options.shuffle_bells: + cls.seed_groups[group]["bell_shuffle"] = False + # off is more restrictive + if not tunic.options.shuffle_fuses: + cls.seed_groups[group]["fuse_shuffle"] = False # fixed shop and direction pairs override standard, but conflict with each other if tunic.options.entrance_layout: if cls.seed_groups[group]["entrance_layout"] == EntranceLayout.option_standard: @@ -428,6 +438,19 @@ def remove_filler(amount: int) -> None: ladder_count += 1 remove_filler(ladder_count) + if self.options.shuffle_fuses: + for item_name, item_data in item_table.items(): + if item_data.item_group == "Fuses": + if item_name == "Cathedral Elevator Fuse" and self.options.entrance_rando: + tunic_items.append(self.create_item(item_name, ItemClassification.useful)) + continue + items_to_create[item_name] = 1 + + if self.options.shuffle_bells: + for item_name, item_data in item_table.items(): + if item_data.item_group == "Bells": + items_to_create[item_name] = 1 + if self.options.hexagon_quest: # Replace pages and normal hexagons with filler for replaced_item in list(filter(lambda item: "Pages" in item or item in hexagon_locations, items_to_create)): @@ -480,7 +503,6 @@ def remove_filler(amount: int) -> None: # pull out the filler so that we can place it manually during pre_fill self.fill_items = [] if self.options.local_fill > 0 and self.multiworld.players > 1: - # skip items marked local or non-local, let fill deal with them in its own way all_filler: list[TunicItem] = [] non_filler: list[TunicItem] = [] for tunic_item in tunic_items: @@ -709,8 +731,8 @@ def fill_slot_data(self) -> dict[str, Any]: "entrance_rando": int(bool(self.options.entrance_rando.value)), "decoupled": self.options.decoupled.value if self.options.entrance_rando else 0, "shuffle_ladders": self.options.shuffle_ladders.value, - # "shuffle_fuses": self.options.shuffle_fuses.value, - # "shuffle_bells": self.options.shuffle_bells.value, + "shuffle_fuses": self.options.shuffle_fuses.value, + "shuffle_bells": self.options.shuffle_bells.value, "grass_randomizer": self.options.grass_randomizer.value, "combat_logic": self.options.combat_logic.value, "Hexagon Quest Prayer": self.ability_unlocks["Pages 24-25 (Prayer)"], diff --git a/worlds/tunic/bells.py b/worlds/tunic/bells.py new file mode 100644 index 000000000000..2687d9bf1d7d --- /dev/null +++ b/worlds/tunic/bells.py @@ -0,0 +1,39 @@ +from typing import NamedTuple, TYPE_CHECKING + +from worlds.generic.Rules import set_rule + +from .constants import base_id +from .logic_helpers import has_melee + + +if TYPE_CHECKING: + from . import TunicWorld + + +class TunicLocationData(NamedTuple): + region: str + er_region: str + + +bell_location_table: dict[str, TunicLocationData] = { + "Forest Belltower - Ring the East Bell": TunicLocationData("Forest Belltower", "Forest Belltower Upper"), + "Overworld - [West] Ring the West Bell": TunicLocationData("Overworld", "Overworld Belltower at Bell"), +} + +bell_location_base_id = base_id + 11000 +bell_location_name_to_id: dict[str, int] = {name: bell_location_base_id + index + for index, name in enumerate(bell_location_table)} + +bell_location_groups: dict[str, set[str]] = {} +for location_name, location_data in bell_location_table.items(): + bell_location_groups.setdefault(location_data.region, set()).add(location_name) + bell_location_groups.setdefault("Bells", set()).add(location_name) + + +def set_bell_location_rules(world: "TunicWorld") -> None: + player = world.player + + set_rule(world.get_location("Forest Belltower - Ring the East Bell"), + lambda state: has_melee(state, player) or state.has("Magic Wand", player)) + set_rule(world.get_location("Overworld - [West] Ring the West Bell"), + lambda state: has_melee(state, player) or state.has("Magic Wand", player)) diff --git a/worlds/tunic/er_data.py b/worlds/tunic/er_data.py index cfa215a34129..3641658ab132 100644 --- a/worlds/tunic/er_data.py +++ b/worlds/tunic/er_data.py @@ -735,7 +735,7 @@ class DeadEnd(IntEnum): "Rooted Ziggurat Lower Entry": RegionInfo("ziggurat2020_3"), # the vanilla entry point side "Rooted Ziggurat Lower Front": RegionInfo("ziggurat2020_3"), # the front for combat logic "Rooted Ziggurat Lower Mid Checkpoint": RegionInfo("ziggurat2020_3"), # the mid-checkpoint before double admin - "Rooted Ziggurat Lower Miniboss Platform": RegionInfo("ziggurat2020_3"), # the double admin platform + "Rooted Ziggurat Lower Miniboss Platform": RegionInfo("ziggurat2020_3"), # the double admin platform "Rooted Ziggurat Lower Back": RegionInfo("ziggurat2020_3"), # the boss side "Zig Skip Exit": RegionInfo("ziggurat2020_3", dead_end=DeadEnd.special, outlet_region="Rooted Ziggurat Lower Entry", is_fake_region=True), # for use with fixed shop on "Rooted Ziggurat Portal Room Entrance": RegionInfo("ziggurat2020_3", outlet_region="Rooted Ziggurat Lower Back"), # the door itself on the zig 3 side diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index 6d238693cc05..ad26e10c9e9e 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -3,11 +3,11 @@ from BaseClasses import Region from worlds.generic.Rules import set_rule, add_rule, forbid_item -# from .bells import set_bell_location_rules +from .bells import set_bell_location_rules from .combat_logic import has_combat_reqs from .constants import * from .er_data import Portal, get_portal_outlet_region -# from .fuses import set_fuse_location_rules, has_fuses +from .fuses import set_fuse_location_rules from .grass import set_grass_location_rules from .ladder_storage_data import ow_ladder_groups, region_ladders, easy_ls, medium_ls, hard_ls from .logic_helpers import (has_ability, has_ladder, has_melee, has_sword, has_lantern, has_mask, has_fuses, @@ -17,9 +17,6 @@ if TYPE_CHECKING: from . import TunicWorld -fuses_option = False # replace with options.shuffle_fuses when fuse shuffle is in -bells_option = False # replace with options.shuffle_bells when bell shuffle is in - def set_er_region_rules(world: "TunicWorld", regions: dict[str, Region], portal_pairs: dict[Portal, Portal]) -> None: player = world.player @@ -334,8 +331,8 @@ def get_paired_portal(portal_sd: str) -> tuple[str, str]: # nmg: ice grapple through temple door regions["Overworld"].connect( connecting_region=regions["Overworld Temple Door"], - rule=lambda state: (state.has_all(("Ring Eastern Bell", "Ring Western Bell"), player) and not bells_option) - or (state.has_all(("East Bell", "West Bell"), player) and bells_option) + rule=lambda state: (state.has_all(("Ring Eastern Bell", "Ring Western Bell"), player) and not options.shuffle_bells) + or (state.has_all(("East Bell", "West Bell"), player) and options.shuffle_bells) or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) regions["Overworld Temple Door"].connect( @@ -671,9 +668,9 @@ def get_paired_portal(portal_sd: str) -> tuple[str, str]: and (has_sword(state, player) or state.has_any((gun, fire_wand), player))) # shoot fuse and have the shot hit you mid-LS or (can_ladder_storage(state, world) and state.has(fire_wand, player) - and options.ladder_storage >= LadderStorage.option_hard))) and not fuses_option) + and options.ladder_storage >= LadderStorage.option_hard))) and not options.shuffle_fuses) or (state.has_all((atoll_northwest_fuse, atoll_northeast_fuse, atoll_southwest_fuse, atoll_southeast_fuse), player) - and fuses_option)) + and options.shuffle_fuses)) ) regions["Ruined Atoll Statue"].connect( @@ -804,12 +801,12 @@ def get_paired_portal(portal_sd: str) -> tuple[str, str]: connecting_region=regions["Fortress Exterior from Overworld"], rule=lambda state: state.has(laurels, player) or (has_ability(prayer, state, world) and state.has(fortress_exterior_fuse_1, player) - and fuses_option)) + and options.shuffle_fuses)) regions["Fortress Exterior from Overworld"].connect( connecting_region=regions["Fortress Exterior near cave"], rule=lambda state: state.has(laurels, player) or (has_ability(prayer, state, world) and state.has(fortress_exterior_fuse_1, player) - if fuses_option else has_ability(prayer, state, world))) + if options.shuffle_fuses else has_ability(prayer, state, world))) # shoot far fire pot, enemy gets aggro'd regions["Fortress Exterior near cave"].connect( @@ -880,7 +877,7 @@ def get_paired_portal(portal_sd: str) -> tuple[str, str]: rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_easy, state, world) or (has_fuses("Activate Eastern Vault West Fuses", state, world) and has_fuses("Activate Eastern Vault East Fuse", state, world) - and fuses_option)) + and options.shuffle_fuses)) fort_grave_entry_to_combat = regions["Fortress Grave Path Entry"].connect( connecting_region=regions["Fortress Grave Path Combat"]) @@ -1027,18 +1024,18 @@ def get_paired_portal(portal_sd: str) -> tuple[str, str]: connecting_region=regions["Rooted Ziggurat Lower Miniboss Platform"]) zig_low_miniboss_to_mid = regions["Rooted Ziggurat Lower Miniboss Platform"].connect( connecting_region=regions["Rooted Ziggurat Lower Mid Checkpoint"], - rule=lambda state: state.has(ziggurat_miniboss_fuse, player) if fuses_option + rule=lambda state: state.has(ziggurat_miniboss_fuse, player) if options.shuffle_fuses else (has_sword(state, player) and has_ability(prayer, state, world))) # can ice grapple to the voidlings to get to the double admin fight, still need to pray at the fuse zig_low_miniboss_to_back = regions["Rooted Ziggurat Lower Miniboss Platform"].connect( connecting_region=regions["Rooted Ziggurat Lower Back"], - rule=lambda state: state.has(laurels, player) or (state.has(ziggurat_miniboss_fuse, player) and fuses_option) - or (has_sword(state, player) and has_ability(prayer, state, world) and not fuses_option)) + rule=lambda state: state.has(laurels, player) or (state.has(ziggurat_miniboss_fuse, player) and options.shuffle_fuses) + or (has_sword(state, player) and has_ability(prayer, state, world) and not options.shuffle_fuses)) regions["Rooted Ziggurat Lower Back"].connect( connecting_region=regions["Rooted Ziggurat Lower Miniboss Platform"], rule=lambda state: state.has(laurels, player) or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world) - or (state.has(ziggurat_miniboss_fuse, player) and fuses_option)) + or (state.has(ziggurat_miniboss_fuse, player) and options.shuffle_fuses)) regions["Rooted Ziggurat Lower Back"].connect( connecting_region=regions["Rooted Ziggurat Portal Room Entrance"], @@ -1086,8 +1083,8 @@ def get_paired_portal(portal_sd: str) -> tuple[str, str]: and state.can_reach_region("Overworld Beach", player))))) and (not options.combat_logic or has_combat_reqs("Swamp", state, player)) - and not fuses_option) - or (state.has_all((swamp_fuse_1, swamp_fuse_2, swamp_fuse_3), player) and fuses_option) + and not options.shuffle_fuses) + or (state.has_all((swamp_fuse_1, swamp_fuse_2, swamp_fuse_3), player) and options.shuffle_fuses) or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) if options.ladder_storage >= LadderStorage.option_hard and options.shuffle_ladders: @@ -1096,7 +1093,7 @@ def get_paired_portal(portal_sd: str) -> tuple[str, str]: regions["Swamp to Cathedral Main Entrance Region"].connect( connecting_region=regions["Swamp Mid"], rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_easy, state, world) - or (state.has_all((swamp_fuse_1, swamp_fuse_2, swamp_fuse_3), player) and fuses_option)) + or (state.has_all((swamp_fuse_1, swamp_fuse_2, swamp_fuse_3), player) and options.shuffle_fuses)) # grapple push the enemy by the door down, then grapple to it. Really jank regions["Swamp Mid"].connect( @@ -1142,7 +1139,7 @@ def get_paired_portal(portal_sd: str) -> tuple[str, str]: cath_entry_to_elev = regions["Cathedral Entry"].connect( connecting_region=regions["Cathedral to Gauntlet"], - rule=lambda state: ((state.has(cathedral_elevator_fuse, player) if fuses_option else has_ability(prayer, state, world)) + rule=lambda state: ((state.has(cathedral_elevator_fuse, player) if options.shuffle_fuses else has_ability(prayer, state, world)) or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)) or options.entrance_rando) # elevator is always there in ER regions["Cathedral to Gauntlet"].connect( @@ -1444,17 +1441,17 @@ def ls_connect(origin_name: str, portal_sdt: str) -> None: lambda state: has_combat_reqs("Rooted Ziggurat", state, player)) set_rule(zig_low_miniboss_to_back, lambda state: state.has(laurels, player) - or (state.has(ziggurat_miniboss_fuse, player) if fuses_option + or (state.has(ziggurat_miniboss_fuse, player) if options.shuffle_fuses else (has_ability(prayer, state, world) and has_combat_reqs("Rooted Ziggurat", state, player)))) set_rule(zig_low_miniboss_to_mid, - lambda state: state.has(ziggurat_miniboss_fuse, player) if fuses_option + lambda state: state.has(ziggurat_miniboss_fuse, player) if options.shuffle_fuses else (has_ability(prayer, state, world) and has_combat_reqs("Rooted Ziggurat", state, player))) # only activating the fuse requires combat logic set_rule(cath_entry_to_elev, lambda state: options.entrance_rando or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world) - or (state.has(cathedral_elevator_fuse, player) if fuses_option + or (state.has(cathedral_elevator_fuse, player) if options.shuffle_fuses else (has_ability(prayer, state, world) and has_combat_reqs("Swamp", state, player)))) set_rule(cath_entry_to_main, @@ -1535,11 +1532,11 @@ def set_er_location_rules(world: "TunicWorld") -> None: if options.grass_randomizer: set_grass_location_rules(world) - # if options.shuffle_fuses: - # set_fuse_location_rules(world) - # - # if options.shuffle_bells: - # set_bell_location_rules(world) + if options.shuffle_fuses: + set_fuse_location_rules(world) + + if options.shuffle_bells: + set_bell_location_rules(world) forbid_item(world.get_location("Secret Gathering Place - 20 Fairy Reward"), fairies, player) @@ -1702,7 +1699,7 @@ def set_er_location_rules(world: "TunicWorld") -> None: and (state.has(laurels, player) or options.entrance_rando))) set_rule(world.get_location("Rooted Ziggurat Lower - After Guarded Fuse"), - lambda state: state.has(ziggurat_miniboss_fuse, player) if fuses_option + lambda state: state.has(ziggurat_miniboss_fuse, player) if options.shuffle_fuses else has_sword(state, player) and has_ability(prayer, state, world)) # Bosses @@ -1745,12 +1742,12 @@ def set_er_location_rules(world: "TunicWorld") -> None: lambda state: state.has(laurels, player)) # Events - if not bells_option: + if not options.shuffle_bells: set_rule(world.get_location("Eastern Bell"), lambda state: (has_melee(state, player) or state.has(fire_wand, player))) set_rule(world.get_location("Western Bell"), lambda state: (has_melee(state, player) or state.has(fire_wand, player))) - if not fuses_option: + if not options.shuffle_fuses: set_rule(world.get_location("Furnace Fuse"), lambda state: has_ability(prayer, state, world)) set_rule(world.get_location("South and West Fortress Exterior Fuses"), @@ -1877,7 +1874,7 @@ def combat_logic_to_loc(loc_name: str, combat_req_area: str, set_instead: bool = # could just do the last two, but this outputs better in the spoiler log # dagger is maybe viable here, but it's sketchy -- activate ladder switch, save to reset enemies, climb up - if not fuses_option: + if not options.shuffle_fuses: combat_logic_to_loc("Upper and Central Fortress Exterior Fuses", "Eastern Vault Fortress") combat_logic_to_loc("Beneath the Vault Fuse", "Beneath the Vault") combat_logic_to_loc("Eastern Vault West Fuses", "Eastern Vault Fortress") @@ -1896,10 +1893,10 @@ def combat_logic_to_loc(loc_name: str, combat_req_area: str, set_instead: bool = and (state.has(laurels, player) or world.options.entrance_rando)) or has_combat_reqs("Rooted Ziggurat", state, player)) set_rule(world.get_location("Rooted Ziggurat Lower - After Guarded Fuse"), - lambda state: state.has(ziggurat_miniboss_fuse, player) if fuses_option + lambda state: state.has(ziggurat_miniboss_fuse, player) if options.shuffle_fuses else (has_ability(prayer, state, world) and has_combat_reqs("Rooted Ziggurat", state, player))) - if fuses_option: + if options.shuffle_fuses: set_rule(world.get_location("Rooted Ziggurat Lower - [Miniboss] Activate Fuse"), lambda state: has_ability(prayer, state, world) and has_combat_reqs("Rooted Ziggurat", state, player)) combat_logic_to_loc("Beneath the Fortress - Activate Fuse", "Beneath the Vault") diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index 81fb90d8f0ec..a1b8b2fefdbc 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -113,13 +113,13 @@ def place_event_items(world: "TunicWorld", regions: dict[str, Region]) -> None: location.place_locked_item( TunicERItem("Unseal the Heir", ItemClassification.progression, None, world.player)) elif event_name.endswith("Bell"): - # if world.options.shuffle_bells: - # continue + if world.options.shuffle_bells: + continue location.place_locked_item( TunicERItem("Ring " + event_name, ItemClassification.progression, None, world.player)) elif event_name.endswith("Fuse") or event_name.endswith("Fuses"): - # if world.options.shuffle_fuses: - # continue + if world.options.shuffle_fuses: + continue location.place_locked_item( TunicERItem("Activate " + event_name, ItemClassification.progression, None, world.player)) region.locations.append(location) @@ -200,10 +200,8 @@ def pair_portals(world: "TunicWorld", regions: dict[str, Region]) -> dict[Portal entrance_layout = world.options.entrance_layout laurels_location = world.options.laurels_location decoupled = world.options.decoupled - # shuffle_fuses = bool(world.options.shuffle_fuses.value) - # shuffle_bells = bool(world.options.shuffle_bells.value) - shuffle_fuses = False - shuffle_bells = False + shuffle_fuses = bool(world.options.shuffle_fuses.value) + shuffle_bells = bool(world.options.shuffle_bells.value) traversal_reqs = deepcopy(traversal_requirements) has_laurels = True waterfall_plando = False @@ -216,6 +214,8 @@ def pair_portals(world: "TunicWorld", regions: dict[str, Region]) -> dict[Portal ladder_storage = seed_group["ladder_storage"] entrance_layout = seed_group["entrance_layout"] laurels_location = "10_fairies" if seed_group["laurels_at_10_fairies"] is True else False + shuffle_bells = seed_group["bell_shuffle"] + shuffle_fuses = seed_group["fuse_shuffle"] logic_tricks: tuple[bool, int, int] = (laurels_zips, ice_grappling, ladder_storage) diff --git a/worlds/tunic/fuses.py b/worlds/tunic/fuses.py index 4f223582daf7..566dffcb0ab4 100644 --- a/worlds/tunic/fuses.py +++ b/worlds/tunic/fuses.py @@ -1,30 +1,123 @@ +from typing import NamedTuple, TYPE_CHECKING + +from BaseClasses import CollectionState +from worlds.generic.Rules import set_rule + from .constants import * +from .logic_helpers import has_ability, has_sword, fuse_activation_reqs + +if TYPE_CHECKING: + from . import TunicWorld + -# for fuse locations and reusing event names to simplify er_rules -fuse_activation_reqs: dict[str, list[str]] = { - swamp_fuse_2: [swamp_fuse_1], - swamp_fuse_3: [swamp_fuse_1, swamp_fuse_2], - fortress_exterior_fuse_2: [fortress_exterior_fuse_1], - beneath_the_vault_fuse: [fortress_exterior_fuse_1, fortress_exterior_fuse_2], - fortress_candles_fuse: [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse], - fortress_door_left_fuse: [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse, - fortress_candles_fuse], - fortress_courtyard_upper_fuse: [fortress_exterior_fuse_1], - fortress_courtyard_lower_fuse: [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse], - fortress_door_right_fuse: [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse, fortress_courtyard_lower_fuse], - quarry_fuse_2: [quarry_fuse_1], - "Activate Furnace Fuse": [west_furnace_fuse], - "Activate South and West Fortress Exterior Fuses": [fortress_exterior_fuse_1, fortress_exterior_fuse_2], - "Activate Upper and Central Fortress Exterior Fuses": [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse, - fortress_courtyard_lower_fuse], - "Activate Beneath the Vault Fuse": [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse], - "Activate Eastern Vault West Fuses": [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse, - fortress_candles_fuse, fortress_door_left_fuse], - "Activate Eastern Vault East Fuse": [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse, - fortress_courtyard_lower_fuse, fortress_door_right_fuse], - "Activate Quarry Connector Fuse": [quarry_fuse_1], - "Activate Quarry Fuse": [quarry_fuse_1, quarry_fuse_2], - "Activate Ziggurat Fuse": [ziggurat_teleporter_fuse], - "Activate West Garden Fuse": [west_garden_fuse], - "Activate Library Fuse": [library_lab_fuse], +class TunicLocationData(NamedTuple): + loc_group: str + er_region: str + + +fuse_location_table: dict[str, TunicLocationData] = { + "Overworld - [Southeast] Activate Fuse": TunicLocationData("Overworld", "Overworld"), + "Swamp - [Central] Activate Fuse": TunicLocationData("Swamp", "Swamp Mid"), + "Swamp - [Outside Cathedral] Activate Fuse": TunicLocationData("Swamp", "Swamp Mid"), + "Cathedral - Activate Fuse": TunicLocationData("Cathedral", "Cathedral Main"), + "West Furnace - Activate Fuse": TunicLocationData("West Furnace", "Furnace Fuse"), + "West Garden - [South Highlands] Activate Fuse": TunicLocationData("West Garden", "West Garden South Checkpoint"), + "Ruined Atoll - [Northwest] Activate Fuse": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - [Northeast] Activate Fuse": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Ruined Atoll - [Southeast] Activate Fuse": TunicLocationData("Ruined Atoll", "Ruined Atoll Ladder Tops"), + "Ruined Atoll - [Southwest] Activate Fuse": TunicLocationData("Ruined Atoll", "Ruined Atoll"), + "Library Lab - Activate Fuse": TunicLocationData("Library Lab", "Library Lab"), + "Fortress Courtyard - [From Overworld] Activate Fuse": TunicLocationData("Fortress Courtyard", "Fortress Exterior from Overworld"), + "Fortress Courtyard - [Near Cave] Activate Fuse": TunicLocationData("Fortress Courtyard", "Fortress Exterior from Overworld"), + "Fortress Courtyard - [Upper] Activate Fuse": TunicLocationData("Fortress Courtyard", "Fortress Courtyard Upper"), + "Fortress Courtyard - [Central] Activate Fuse": TunicLocationData("Fortress Courtyard", "Fortress Courtyard"), + "Beneath the Fortress - Activate Fuse": TunicLocationData("Beneath the Fortress", "Beneath the Vault Back"), + "Eastern Vault Fortress - [Candle Room] Activate Fuse": TunicLocationData("Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - [Left of Door] Activate Fuse": TunicLocationData("Eastern Vault Fortress", "Eastern Vault Fortress"), + "Eastern Vault Fortress - [Right of Door] Activate Fuse": TunicLocationData("Eastern Vault Fortress", "Eastern Vault Fortress"), + "Quarry Entryway - Activate Fuse": TunicLocationData("Quarry Connector", "Quarry Connector"), + "Quarry - Activate Fuse": TunicLocationData("Quarry", "Quarry Entry"), + "Rooted Ziggurat Lower - [Miniboss] Activate Fuse": TunicLocationData("Rooted Ziggurat Lower", "Rooted Ziggurat Lower Miniboss Platform"), + "Rooted Ziggurat Lower - [Before Boss] Activate Fuse": TunicLocationData("Rooted Ziggurat Lower", "Rooted Ziggurat Lower Back"), } + +fuse_location_base_id = base_id + 10000 +fuse_location_name_to_id: dict[str, int] = {name: fuse_location_base_id + index + for index, name in enumerate(fuse_location_table)} + +fuse_location_groups: dict[str, set[str]] = {} +for location_name, location_data in fuse_location_table.items(): + fuse_location_groups.setdefault(location_data.loc_group, set()).add(location_name) + fuse_location_groups.setdefault("Fuses", set()).add(location_name) + + +# to be deduplicated in the big refactor +def has_ladder(ladder: str, state: CollectionState, world: "TunicWorld") -> bool: + return not world.options.shuffle_ladders or state.has(ladder, world.player) + + +def set_fuse_location_rules(world: "TunicWorld") -> None: + player = world.player + + set_rule(world.get_location("Overworld - [Southeast] Activate Fuse"), + lambda state: state.has(laurels, player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Swamp - [Central] Activate Fuse"), + lambda state: state.has_all(fuse_activation_reqs[swamp_fuse_2], player) + and has_ability(prayer, state, world) + and has_sword(state, player)) + set_rule(world.get_location("Swamp - [Outside Cathedral] Activate Fuse"), + lambda state: state.has_all(fuse_activation_reqs[swamp_fuse_3], player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Cathedral - Activate Fuse"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("West Furnace - Activate Fuse"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("West Garden - [South Highlands] Activate Fuse"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("Ruined Atoll - [Northwest] Activate Fuse"), + lambda state: state.has_any([grapple, laurels], player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Ruined Atoll - [Northeast] Activate Fuse"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("Ruined Atoll - [Southeast] Activate Fuse"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("Ruined Atoll - [Southwest] Activate Fuse"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("Library Lab - Activate Fuse"), + lambda state: has_ability(prayer, state, world) + and has_ladder("Ladders in Library", state, world)) + set_rule(world.get_location("Fortress Courtyard - [From Overworld] Activate Fuse"), + lambda state: has_ability(prayer, state, world)) + set_rule(world.get_location("Fortress Courtyard - [Near Cave] Activate Fuse"), + lambda state: state.has(fortress_exterior_fuse_1, player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Fortress Courtyard - [Upper] Activate Fuse"), + lambda state: state.has(fortress_exterior_fuse_1, player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Fortress Courtyard - [Central] Activate Fuse"), + lambda state: state.has_all(fuse_activation_reqs[fortress_courtyard_lower_fuse], player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Beneath the Fortress - Activate Fuse"), + lambda state: state.has_all(fuse_activation_reqs[beneath_the_vault_fuse], player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Eastern Vault Fortress - [Candle Room] Activate Fuse"), + lambda state: state.has_all(fuse_activation_reqs[fortress_candles_fuse], player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Eastern Vault Fortress - [Left of Door] Activate Fuse"), + lambda state: state.has_all(fuse_activation_reqs[fortress_door_left_fuse], player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Eastern Vault Fortress - [Right of Door] Activate Fuse"), + lambda state: state.has_all(fuse_activation_reqs[fortress_door_right_fuse], player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Quarry Entryway - Activate Fuse"), + lambda state: state.has(grapple, player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Quarry - Activate Fuse"), + lambda state: state.has_all(fuse_activation_reqs[quarry_fuse_2], player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Rooted Ziggurat Lower - [Miniboss] Activate Fuse"), + lambda state: has_sword(state, player) + and has_ability(prayer, state, world)) + set_rule(world.get_location("Rooted Ziggurat Lower - [Before Boss] Activate Fuse"), + lambda state: has_ability(prayer, state, world)) diff --git a/worlds/tunic/items.py b/worlds/tunic/items.py index fe1e33e97df0..e8f201b92670 100644 --- a/worlds/tunic/items.py +++ b/worlds/tunic/items.py @@ -173,6 +173,31 @@ class TunicItemData(NamedTuple): "Ladders in Lower Quarry": TunicItemData(IC.progression, 0, 149, "Ladders"), "Ladders in Swamp": TunicItemData(IC.progression, 0, 150, "Ladders"), "Grass": TunicItemData(IC.filler, 0, 151), + "Swamp Fuse 1": TunicItemData(IC.progression, 0, 157, "Fuses"), + "Swamp Fuse 2": TunicItemData(IC.progression, 0, 158, "Fuses"), + "Swamp Fuse 3": TunicItemData(IC.progression, 0, 159, "Fuses"), + "Cathedral Elevator Fuse": TunicItemData(IC.progression, 0, 160, "Fuses"), + "Quarry Fuse 1": TunicItemData(IC.progression, 0, 161, "Fuses"), + "Quarry Fuse 2": TunicItemData(IC.progression, 0, 162, "Fuses"), + "Ziggurat Miniboss Fuse": TunicItemData(IC.progression, 0, 163, "Fuses"), + "Ziggurat Teleporter Fuse": TunicItemData(IC.progression, 0, 164, "Fuses"), + "Fortress Exterior Fuse 1": TunicItemData(IC.progression, 0, 165, "Fuses"), + "Fortress Exterior Fuse 2": TunicItemData(IC.progression, 0, 166, "Fuses"), + "Fortress Courtyard Upper Fuse": TunicItemData(IC.progression, 0, 167, "Fuses"), + "Fortress Courtyard Fuse": TunicItemData(IC.progression, 0, 168, "Fuses"), + "Beneath the Vault Fuse": TunicItemData(IC.progression, 0, 169, "Fuses"), + "Fortress Candles Fuse": TunicItemData(IC.progression, 0, 170, "Fuses"), + "Fortress Door Left Fuse": TunicItemData(IC.progression, 0, 171, "Fuses"), + "Fortress Door Right Fuse": TunicItemData(IC.progression, 0, 172, "Fuses"), + "West Furnace Fuse": TunicItemData(IC.progression, 0, 173, "Fuses"), + "West Garden Fuse": TunicItemData(IC.progression, 0, 174, "Fuses"), + "Atoll Northeast Fuse": TunicItemData(IC.progression, 0, 175, "Fuses"), + "Atoll Northwest Fuse": TunicItemData(IC.progression, 0, 176, "Fuses"), + "Atoll Southeast Fuse": TunicItemData(IC.progression, 0, 177, "Fuses"), + "Atoll Southwest Fuse": TunicItemData(IC.progression, 0, 178, "Fuses"), + "Library Lab Fuse": TunicItemData(IC.progression, 0, 179, "Fuses"), + "East Bell": TunicItemData(IC.progression, 0, 180, "Bells"), + "West Bell": TunicItemData(IC.progression, 0, 181, "Bells") } # items to be replaced by fool traps diff --git a/worlds/tunic/locations.py b/worlds/tunic/locations.py index 93c6164b88fd..dea2e603c119 100644 --- a/worlds/tunic/locations.py +++ b/worlds/tunic/locations.py @@ -1,9 +1,9 @@ from typing import NamedTuple -# from .bells import bell_location_table +from .bells import bell_location_table from .breakables import breakable_location_table from .constants import base_id -# from .fuses import fuse_location_table +from .fuses import fuse_location_table from .grass import grass_location_table @@ -329,8 +329,8 @@ class TunicLocationData(NamedTuple): all_locations = location_table.copy() all_locations.update(grass_location_table) all_locations.update(breakable_location_table) -# all_locations.update(fuse_location_table) -# all_locations.update(bell_location_table) +all_locations.update(fuse_location_table) +all_locations.update(bell_location_table) location_name_groups: dict[str, set[str]] = {} for loc_name, loc_data in location_table.items(): diff --git a/worlds/tunic/logic_helpers.py b/worlds/tunic/logic_helpers.py index 1752bf8eb43d..7370c9ace540 100644 --- a/worlds/tunic/logic_helpers.py +++ b/worlds/tunic/logic_helpers.py @@ -3,7 +3,6 @@ from BaseClasses import CollectionState from .constants import * -from .fuses import fuse_activation_reqs from .options import HexagonQuestAbilityUnlockType, IceGrappling if TYPE_CHECKING: @@ -89,10 +88,38 @@ def can_get_past_bushes(state: CollectionState, world: "TunicWorld") -> bool: return has_sword(state, world.player) or state.has_any((fire_wand, laurels, gun), world.player) +# for fuse locations and reusing event names to simplify er_rules +fuse_activation_reqs: dict[str, list[str]] = { + swamp_fuse_2: [swamp_fuse_1], + swamp_fuse_3: [swamp_fuse_1, swamp_fuse_2], + fortress_exterior_fuse_2: [fortress_exterior_fuse_1], + beneath_the_vault_fuse: [fortress_exterior_fuse_1, fortress_exterior_fuse_2], + fortress_candles_fuse: [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse], + fortress_door_left_fuse: [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse, + fortress_candles_fuse], + fortress_courtyard_upper_fuse: [fortress_exterior_fuse_1], + fortress_courtyard_lower_fuse: [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse], + fortress_door_right_fuse: [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse, fortress_courtyard_lower_fuse], + quarry_fuse_2: [quarry_fuse_1], + "Activate Furnace Fuse": [west_furnace_fuse], + "Activate South and West Fortress Exterior Fuses": [fortress_exterior_fuse_1, fortress_exterior_fuse_2], + "Activate Upper and Central Fortress Exterior Fuses": [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse, + fortress_courtyard_lower_fuse], + "Activate Beneath the Vault Fuse": [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse], + "Activate Eastern Vault West Fuses": [fortress_exterior_fuse_1, fortress_exterior_fuse_2, beneath_the_vault_fuse, + fortress_candles_fuse, fortress_door_left_fuse], + "Activate Eastern Vault East Fuse": [fortress_exterior_fuse_1, fortress_courtyard_upper_fuse, + fortress_courtyard_lower_fuse, fortress_door_right_fuse], + "Activate Quarry Connector Fuse": [quarry_fuse_1], + "Activate Quarry Fuse": [quarry_fuse_1, quarry_fuse_2], + "Activate Ziggurat Fuse": [ziggurat_teleporter_fuse], + "Activate West Garden Fuse": [west_garden_fuse], + "Activate Library Fuse": [library_lab_fuse], +} + + def has_fuses(fuse_event: str, state: CollectionState, world: "TunicWorld") -> bool: - player = world.player - fuses_option = False # replace fuses_option with world.options.shuffle_fuses when fuse shuffle is in - if fuses_option: - return state.has_all(fuse_activation_reqs[fuse_event], player) + if world.options.shuffle_fuses: + return state.has_all(fuse_activation_reqs[fuse_event], world.player) - return state.has(fuse_event, player) + return state.has(fuse_event, world.player) diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index ef0130d0eb10..f705979a4436 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -198,6 +198,24 @@ class ShuffleLadders(Toggle): display_name = "Shuffle Ladders" +class ShuffleFuses(Toggle): + """ + Praying at a fuse will reward a check instead of turning on the power. The power from each fuse gets turned into an + item that must be found in order to restore power for that part of the path. + """ + internal_name = "shuffle_fuses" + display_name = "Shuffle Fuses" + + +class ShuffleBells(Toggle): + """ + The East and West bells are shuffled into the item pool and must be found in order to unlock the Sealed Temple. + Ringing the bells will instead now reward a check. + """ + internal_name = "shuffle_bells" + display_name = "Shuffle Bells" + + class GrassRandomizer(Toggle): """ Turns over 6,000 blades of grass and bushes in the game into checks. @@ -357,8 +375,8 @@ class TunicOptions(PerGameCommonOptions): hexagon_quest_ability_type: HexagonQuestAbilityUnlockType shuffle_ladders: ShuffleLadders - # shuffle_fuses: ShuffleFuses - # shuffle_bells: ShuffleBells + shuffle_fuses: ShuffleFuses + shuffle_bells: ShuffleBells grass_randomizer: GrassRandomizer breakable_shuffle: BreakableShuffle local_fill: LocalFill diff --git a/worlds/tunic/test/test_access.py b/worlds/tunic/test/test_access.py index f5d429ac73db..6cafae174335 100644 --- a/worlds/tunic/test/test_access.py +++ b/worlds/tunic/test/test_access.py @@ -2,7 +2,7 @@ from .bases import TunicTestBase -class TestAccess(TunicTestBase): +class TestWells(TunicTestBase): options = {options.CombatLogic.internal_name: options.CombatLogic.option_off} # test that the wells function properly. Since fairies is written the same way, that should succeed too diff --git a/worlds/tunic/ut_stuff.py b/worlds/tunic/ut_stuff.py index 1192b30d1778..9096f037d8e5 100644 --- a/worlds/tunic/ut_stuff.py +++ b/worlds/tunic/ut_stuff.py @@ -25,8 +25,8 @@ def setup_options_from_slot_data(world: "TunicWorld") -> None: world.options.hexagon_quest_ability_type.value = world.passthrough.get("hexagon_quest_ability_type", 0) world.options.entrance_rando.value = world.passthrough["entrance_rando"] world.options.shuffle_ladders.value = world.passthrough["shuffle_ladders"] - # world.options.shuffle_fuses.value = world.passthrough.get("shuffle_fuses", 0) - # world.options.shuffle_bells.value = world.passthrough.get("shuffle_bells", 0) + world.options.shuffle_fuses.value = world.passthrough.get("shuffle_fuses", 0) + world.options.shuffle_bells.value = world.passthrough.get("shuffle_bells", 0) world.options.grass_randomizer.value = world.passthrough.get("grass_randomizer", 0) world.options.breakable_shuffle.value = world.passthrough.get("breakable_shuffle", 0) world.options.entrance_layout.value = EntranceLayout.option_standard From 76b0197462a6335a22f28ef61d3bc34693cf9a5c Mon Sep 17 00:00:00 2001 From: Phaneros <31861583+MatthewMarinets@users.noreply.github.com> Date: Tue, 30 Sep 2025 13:18:42 -0700 Subject: [PATCH 0773/1218] SC2: any_unit and item parent bugfixes (#5480) * sc2: Fixing a Reaver item being classified as a scout item * sc2: any_units now requires any AA in the first 5 units * Fixing Shoot the Messenger not requiring AA in a hard rule * Fixing any_unit zerg still allowing unupgraded mercs * sc2: Fixed an issue where terran was requiring zerg anti-air in any_units --- worlds/sc2/item/item_tables.py | 2 +- worlds/sc2/locations.py | 24 ++++-- worlds/sc2/rules.py | 135 ++++++++++++++++++--------------- 3 files changed, 93 insertions(+), 68 deletions(-) diff --git a/worlds/sc2/item/item_tables.py b/worlds/sc2/item/item_tables.py index 7fb198ea58ac..d63b00489f01 100644 --- a/worlds/sc2/item/item_tables.py +++ b/worlds/sc2/item/item_tables.py @@ -1860,7 +1860,7 @@ def get_full_item_list(): item_names.DARK_TEMPLAR_ARCHON_MERGE: ItemData(417 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 27, SC2Race.PROTOSS, classification=ItemClassification.progression, parent=item_names.DARK_TEMPLAR), item_names.ASCENDANT_ARCHON_MERGE: ItemData(418 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 28, SC2Race.PROTOSS, classification=ItemClassification.progression_skip_balancing, parent=item_names.ASCENDANT), item_names.SCOUT_SUPPLY_EFFICIENCY: ItemData(419 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_4, 29, SC2Race.PROTOSS, parent=item_names.SCOUT), - item_names.REAVER_BARGAIN_BIN_PRICES: ItemData(420 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_5, 0, SC2Race.PROTOSS, parent=item_names.SCOUT), + item_names.REAVER_BARGAIN_BIN_PRICES: ItemData(420 + SC2LOTV_ITEM_ID_OFFSET, ProtossItemType.Forge_5, 0, SC2Race.PROTOSS, parent=item_names.REAVER), # War Council diff --git a/worlds/sc2/locations.py b/worlds/sc2/locations.py index 6b505d9c974a..34245d863751 100644 --- a/worlds/sc2/locations.py +++ b/worlds/sc2/locations.py @@ -2535,6 +2535,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: lambda state: ( logic.zerg_common_unit(state) and logic.zerg_competent_anti_air(state) ), + hard_rule=logic.zerg_any_anti_air, ), make_location_data( SC2Mission.SHOOT_THE_MESSENGER.mission_name, @@ -2569,6 +2570,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: lambda state: ( logic.zerg_common_unit(state) and logic.zerg_competent_anti_air(state) ), + hard_rule=logic.zerg_any_anti_air, ), make_location_data( SC2Mission.SHOOT_THE_MESSENGER.mission_name, @@ -2610,6 +2612,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2HOTS_LOC_ID_OFFSET + 510, LocationType.CHALLENGE, logic.zerg_competent_comp_competent_aa, + hard_rule=logic.zerg_any_anti_air, flags=LocationFlag.BASEBUST, ), make_location_data( @@ -2618,6 +2621,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2HOTS_LOC_ID_OFFSET + 511, LocationType.CHALLENGE, logic.zerg_competent_comp_competent_aa, + hard_rule=logic.zerg_any_anti_air, flags=LocationFlag.BASEBUST, ), make_location_data( @@ -2626,6 +2630,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2HOTS_LOC_ID_OFFSET + 512, LocationType.CHALLENGE, logic.zerg_competent_comp_competent_aa, + hard_rule=logic.zerg_any_anti_air, flags=LocationFlag.BASEBUST, ), make_location_data( @@ -10042,6 +10047,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: logic.terran_common_unit(state) and logic.terran_competent_anti_air(state) ), + hard_rule=logic.terran_any_anti_air, ), make_location_data( SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, @@ -10079,6 +10085,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: logic.terran_common_unit(state) and logic.terran_competent_anti_air(state) ), + hard_rule=logic.terran_any_anti_air, ), make_location_data( SC2Mission.SHOOT_THE_MESSENGER_T.mission_name, @@ -10122,7 +10129,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2_RACESWAP_LOC_ID_OFFSET + 6710, LocationType.CHALLENGE, lambda state: logic.terran_beats_protoss_deathball(state) - and logic.terran_common_unit(state), + and logic.terran_common_unit(state), flags=LocationFlag.BASEBUST, ), make_location_data( @@ -10131,8 +10138,9 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2_RACESWAP_LOC_ID_OFFSET + 6711, LocationType.CHALLENGE, lambda state: logic.terran_beats_protoss_deathball(state) - and logic.terran_competent_ground_to_air(state) - and logic.terran_common_unit(state), + and logic.terran_competent_ground_to_air(state) + and logic.terran_common_unit(state), + hard_rule=logic.terran_any_anti_air, flags=LocationFlag.BASEBUST, ), make_location_data( @@ -10141,8 +10149,9 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2_RACESWAP_LOC_ID_OFFSET + 6712, LocationType.CHALLENGE, lambda state: logic.terran_beats_protoss_deathball(state) - and logic.terran_competent_ground_to_air(state) - and logic.terran_common_unit(state), + and logic.terran_competent_ground_to_air(state) + and logic.terran_common_unit(state), + hard_rule=logic.terran_any_anti_air, flags=LocationFlag.BASEBUST, ), make_location_data( @@ -10154,6 +10163,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: logic.protoss_common_unit(state) and logic.protoss_anti_armor_anti_air(state) ), + hard_rule=logic.protoss_any_anti_air_unit, ), make_location_data( SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, @@ -10191,6 +10201,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: logic.protoss_common_unit(state) and logic.protoss_anti_armor_anti_air(state) ), + hard_rule=logic.protoss_any_anti_air_unit, ), make_location_data( SC2Mission.SHOOT_THE_MESSENGER_P.mission_name, @@ -10238,6 +10249,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2_RACESWAP_LOC_ID_OFFSET + 6810, LocationType.CHALLENGE, logic.protoss_competent_comp, + hard_rule=logic.protoss_any_anti_air_unit, flags=LocationFlag.BASEBUST, ), make_location_data( @@ -10246,6 +10258,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2_RACESWAP_LOC_ID_OFFSET + 6811, LocationType.CHALLENGE, logic.protoss_competent_comp, + hard_rule=logic.protoss_any_anti_air_unit, flags=LocationFlag.BASEBUST, ), make_location_data( @@ -10254,6 +10267,7 @@ def get_locations(world: Optional["SC2World"]) -> Tuple[LocationData, ...]: SC2_RACESWAP_LOC_ID_OFFSET + 6812, LocationType.CHALLENGE, logic.protoss_competent_comp, + hard_rule=logic.protoss_any_anti_air_unit, flags=LocationFlag.BASEBUST, ), make_location_data( diff --git a/worlds/sc2/rules.py b/worlds/sc2/rules.py index 2a03d65d8d59..2298c2cea669 100644 --- a/worlds/sc2/rules.py +++ b/worlds/sc2/rules.py @@ -3367,65 +3367,74 @@ def end_game_requirement(self, state: CollectionState) -> bool: def has_terran_units(self, target: int) -> Callable[["CollectionState"], bool]: def _has_terran_units(state: CollectionState) -> bool: - return (state.count_from_list_unique(item_groups.terran_units + item_groups.terran_buildings, self.player) >= target) and ( - # Anything that can hit buildings - state.has_any(( - # Infantry - item_names.MARINE, - item_names.FIREBAT, - item_names.MARAUDER, - item_names.REAPER, - item_names.HERC, - item_names.DOMINION_TROOPER, - item_names.GHOST, - item_names.SPECTRE, - # Vehicles - item_names.HELLION, - item_names.VULTURE, - item_names.SIEGE_TANK, - item_names.WARHOUND, - item_names.GOLIATH, - item_names.DIAMONDBACK, - item_names.THOR, - item_names.PREDATOR, - item_names.CYCLONE, - # Ships - item_names.WRAITH, - item_names.VIKING, - item_names.BANSHEE, - item_names.RAVEN, - item_names.BATTLECRUISER, - # RG - item_names.SON_OF_KORHAL, - item_names.AEGIS_GUARD, - item_names.EMPERORS_SHADOW, - item_names.BULWARK_COMPANY, - item_names.SHOCK_DIVISION, - item_names.BLACKHAMMER, - item_names.SKY_FURY, - item_names.NIGHT_WOLF, - item_names.NIGHT_HAWK, - item_names.PRIDE_OF_AUGUSTRGRAD, - ), self.player) - or state.has_all((item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY), self.player) - or state.has_all((item_names.EMPERORS_GUARDIAN, item_names.LIBERATOR_RAID_ARTILLERY), self.player) - or state.has_all((item_names.VALKYRIE, item_names.VALKYRIE_FLECHETTE_MISSILES), self.player) - or state.has_all((item_names.WIDOW_MINE, item_names.WIDOW_MINE_DEMOLITION_PAYLOAD), self.player) - or ( + return ( + state.count_from_list_unique( + item_groups.terran_units + item_groups.terran_buildings, self.player + ) >= target + and ( + target < 5 + or self.terran_any_anti_air(state) + ) + and ( + # Anything that can hit buildings state.has_any(( - # Mercs with shortest initial cooldown (300s) - item_names.WAR_PIGS, - item_names.DEATH_HEADS, - item_names.HELS_ANGELS, - item_names.WINGED_NIGHTMARES, + # Infantry + item_names.MARINE, + item_names.FIREBAT, + item_names.MARAUDER, + item_names.REAPER, + item_names.HERC, + item_names.DOMINION_TROOPER, + item_names.GHOST, + item_names.SPECTRE, + # Vehicles + item_names.HELLION, + item_names.VULTURE, + item_names.SIEGE_TANK, + item_names.WARHOUND, + item_names.GOLIATH, + item_names.DIAMONDBACK, + item_names.THOR, + item_names.PREDATOR, + item_names.CYCLONE, + # Ships + item_names.WRAITH, + item_names.VIKING, + item_names.BANSHEE, + item_names.RAVEN, + item_names.BATTLECRUISER, + # RG + item_names.SON_OF_KORHAL, + item_names.AEGIS_GUARD, + item_names.EMPERORS_SHADOW, + item_names.BULWARK_COMPANY, + item_names.SHOCK_DIVISION, + item_names.BLACKHAMMER, + item_names.SKY_FURY, + item_names.NIGHT_WOLF, + item_names.NIGHT_HAWK, + item_names.PRIDE_OF_AUGUSTRGRAD, ), self.player) - # + 2 upgrades that allow getting faster/earlier mercs - and state.count_from_list(( - item_names.RAPID_REINFORCEMENT, - item_names.PROGRESSIVE_FAST_DELIVERY, - item_names.ROGUE_FORCES, - # item_names.SIGNAL_BEACON, # Probably doesn't help too much on the first unit - ), self.player) >= 2 + or state.has_all((item_names.LIBERATOR, item_names.LIBERATOR_RAID_ARTILLERY), self.player) + or state.has_all((item_names.EMPERORS_GUARDIAN, item_names.LIBERATOR_RAID_ARTILLERY), self.player) + or state.has_all((item_names.VALKYRIE, item_names.VALKYRIE_FLECHETTE_MISSILES), self.player) + or state.has_all((item_names.WIDOW_MINE, item_names.WIDOW_MINE_DEMOLITION_PAYLOAD), self.player) + or ( + state.has_any(( + # Mercs with shortest initial cooldown (300s) + item_names.WAR_PIGS, + item_names.DEATH_HEADS, + item_names.HELS_ANGELS, + item_names.WINGED_NIGHTMARES, + ), self.player) + # + 2 upgrades that allow getting faster/earlier mercs + and state.count_from_list(( + item_names.RAPID_REINFORCEMENT, + item_names.PROGRESSIVE_FAST_DELIVERY, + item_names.ROGUE_FORCES, + # item_names.SIGNAL_BEACON, # Probably doesn't help too much on the first unit + ), self.player) >= 2 + ) ) ) @@ -3451,6 +3460,10 @@ def _has_zerg_units(state: CollectionState) -> bool: ) return ( num_units >= target + and ( + target < 5 + or self.zerg_any_anti_air(state) + ) and ( # Anything that can hit buildings state.has_any(( @@ -3468,11 +3481,6 @@ def _has_zerg_units(state: CollectionState) -> bool: item_names.INFESTED_DIAMONDBACK, item_names.INFESTED_SIEGE_TANK, item_names.INFESTED_BANSHEE, - # Mercs with <= 300s first drop time - item_names.DEVOURING_ONES, - item_names.HUNTER_KILLERS, - item_names.CAUSTIC_HORRORS, - item_names.HUNTERLING, ), self.player) or state.has_all((item_names.INFESTOR, item_names.INFESTOR_INFESTED_TERRAN), self.player) or self.morph_baneling(state) @@ -3512,6 +3520,9 @@ def _has_protoss_units(state: CollectionState) -> bool: return ( state.count_from_list_unique(item_groups.protoss_units + item_groups.protoss_buildings + [item_names.NEXUS_OVERCHARGE], self.player) >= target + ) and ( + target < 5 + or self.protoss_any_anti_air_unit(state) ) and ( # Anything that can hit buildings state.has_any(( From 4893ac3e512a0ea28741e6619eb49d28525ab36f Mon Sep 17 00:00:00 2001 From: Ziktofel Date: Wed, 1 Oct 2025 02:40:30 +0200 Subject: [PATCH 0774/1218] SC2: Fix Terran global upgrades present even if no Terran build missions are rolled (#5452) * Fix Terran global upgrades present even if no Terran build missions are rolled * Code cleanup --- worlds/sc2/__init__.py | 9 ++-- worlds/sc2/test/test_usecases.py | 74 ++++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/worlds/sc2/__init__.py b/worlds/sc2/__init__.py index 984c716e7501..9bf2f7910410 100644 --- a/worlds/sc2/__init__.py +++ b/worlds/sc2/__init__.py @@ -468,7 +468,8 @@ def flag_excludes_by_faction_presence(world: SC2World, item_list: List[FilterIte for item in item_list: # Catch-all for all of a faction's items - if not terran_missions and item.data.race == SC2Race.TERRAN: + # Unit upgrades required for no-builds will get the FilterExcluded lifted when flagging AllowedOrphan + if not terran_build_missions and item.data.race == SC2Race.TERRAN: if item.name not in item_groups.nova_equipment: item.flags |= ItemFilterFlags.FilterExcluded continue @@ -483,10 +484,6 @@ def flag_excludes_by_faction_presence(world: SC2World, item_list: List[FilterIte continue # Faction units - if (not terran_build_missions - and item.data.type in (item_tables.TerranItemType.Unit, item_tables.TerranItemType.Building, item_tables.TerranItemType.Mercenary) - ): - item.flags |= ItemFilterFlags.FilterExcluded if (not zerg_build_missions and item.data.type in (item_tables.ZergItemType.Unit, item_tables.ZergItemType.Mercenary, item_tables.ZergItemType.Evolution_Pit) ): @@ -661,6 +658,7 @@ def flag_allowed_orphan_items(world: SC2World, item_list: List[FilterItem]) -> N item_names.MEDIC_STABILIZER_MEDPACKS, item_names.MARINE_LASER_TARGETING_SYSTEM, ): item.flags |= ItemFilterFlags.AllowedOrphan + item.flags &= ~ItemFilterFlags.FilterExcluded # These rules only trigger on Standard tactics if SC2Mission.BELLY_OF_THE_BEAST in missions and world.options.required_tactics == RequiredTactics.option_standard: for item in item_list: @@ -670,6 +668,7 @@ def flag_allowed_orphan_items(world: SC2World, item_list: List[FilterItem]) -> N item_names.FIREBAT_NANO_PROJECTORS, item_names.FIREBAT_JUGGERNAUT_PLATING, item_names.FIREBAT_PROGRESSIVE_STIMPACK ): item.flags |= ItemFilterFlags.AllowedOrphan + item.flags &= ~ItemFilterFlags.FilterExcluded if SC2Mission.EVIL_AWOKEN in missions and world.options.required_tactics == RequiredTactics.option_standard: for item in item_list: if item.name in (item_names.STALKER_PHASE_REACTOR, item_names.STALKER_INSTIGATOR_SLAYER_DISINTEGRATING_PARTICLES, item_names.STALKER_INSTIGATOR_SLAYER_PARTICLE_REFLECTION): diff --git a/worlds/sc2/test/test_usecases.py b/worlds/sc2/test/test_usecases.py index 7f3ac70fc211..bf79dbea010d 100644 --- a/worlds/sc2/test/test_usecases.py +++ b/worlds/sc2/test/test_usecases.py @@ -6,9 +6,14 @@ from .. import get_all_missions, mission_tables, options from ..item import item_groups, item_tables, item_names from ..mission_tables import SC2Race, SC2Mission, SC2Campaign, MissionFlag -from ..options import EnabledCampaigns, MasteryLocations, MissionOrder, EnableRaceSwapVariants, ShuffleCampaigns, \ - ShuffleNoBuild, StarterUnit, RequiredTactics, KerriganPresence, KerriganLevelItemDistribution, GrantStoryTech, \ - GrantStoryLevels +from ..options import ( + EnabledCampaigns, MasteryLocations, MissionOrder, EnableRaceSwapVariants, ShuffleCampaigns, + ShuffleNoBuild, StarterUnit, RequiredTactics, KerriganPresence, KerriganLevelItemDistribution, GrantStoryTech, + GrantStoryLevels, BasebustLocations, ChallengeLocations, DifficultyCurve, EnableMorphling, ExcludeOverpoweredItems, + ExcludeVeryHardMissions, ExtraLocations, GenericUpgradeItems, GenericUpgradeResearch, GenericUpgradeResearchSpeedup, + KerriganPrimalStatus, KeyMode, MissionOrderScouting, EnableMissionRaceBalancing, + NovaGhostOfAChanceVariant, PreventativeLocations, SpeedrunLocations, TakeOverAIAllies, VanillaItemsOnly +) class TestSupportedUseCases(Sc2SetupTestBase): @@ -500,6 +505,69 @@ def test_mercs_only(self) -> None: self.assertTupleEqual(terran_nonmerc_units, ()) self.assertTupleEqual(zerg_nonmerc_units, ()) + def test_zerg_hots_no_terran_items(self) -> None: + # The actual situation the bug got caught + world_options = { + 'basebust_locations': BasebustLocations.option_enabled, + 'challenge_locations': ChallengeLocations.option_enabled, + 'difficulty_curve': DifficultyCurve.option_standard, + 'enable_morphling': EnableMorphling.option_false, + 'enable_race_swap': EnableRaceSwapVariants.option_disabled, + 'enabled_campaigns': [SC2Campaign.HOTS.campaign_name], + 'ensure_generic_items': 25, + 'exclude_overpowered_items': ExcludeOverpoweredItems.option_false, + 'exclude_very_hard_missions': ExcludeVeryHardMissions.option_default, + 'excluded_missions': [ + SC2Mission.SUPREME.mission_name + ], + 'extra_locations': ExtraLocations.option_enabled, + 'generic_upgrade_items': GenericUpgradeItems.option_individual_items, + 'generic_upgrade_missions': 0, + 'generic_upgrade_research': GenericUpgradeResearch.option_auto_in_no_build, + 'generic_upgrade_research_speedup': GenericUpgradeResearchSpeedup.option_false, + 'grant_story_levels': GrantStoryLevels.option_disabled, + 'grant_story_tech': GrantStoryTech.option_no_grant, + 'kerrigan_level_item_distribution': KerriganLevelItemDistribution.option_size_14, + 'kerrigan_level_item_sum': 86, + 'kerrigan_levels_per_mission_completed': 0, + 'kerrigan_levels_per_mission_completed_cap': -1, + 'kerrigan_max_active_abilities': 12, + 'kerrigan_max_passive_abilities': 5, + 'kerrigan_presence': KerriganPresence.option_vanilla, + 'kerrigan_primal_status': KerriganPrimalStatus.option_vanilla, + 'kerrigan_total_level_cap': -1, + 'key_mode': KeyMode.option_progressive_questlines, + 'mastery_locations': MasteryLocations.option_disabled, + 'max_number_of_upgrades': -1, + 'max_upgrade_level': 4, + 'maximum_campaign_size': 40, + 'min_number_of_upgrades': 2, + 'mission_order': MissionOrder.option_mini_campaign, + 'mission_order_scouting': MissionOrderScouting.option_none, + 'mission_race_balancing': EnableMissionRaceBalancing.option_semi_balanced, + 'nova_ghost_of_a_chance_variant': NovaGhostOfAChanceVariant.option_wol, + 'preventative_locations': PreventativeLocations.option_enabled, + 'required_tactics': RequiredTactics.option_standard, + 'shuffle_campaigns': ShuffleCampaigns.option_true, + 'shuffle_no_build': ShuffleNoBuild.option_true, + 'speedrun_locations': SpeedrunLocations.option_disabled, + 'start_primary_abilities': 0, + 'starter_unit': StarterUnit.option_balanced, + 'starting_supply_per_item': 2, + 'take_over_ai_allies': TakeOverAIAllies.option_false, + 'vanilla_items_only': VanillaItemsOnly.option_false, + 'victory_cache': 0, + } + self.generate_world(world_options) + + world_item_names = [item.name for item in self.multiworld.itempool] + + self.assertNotIn(item_names.COMMAND_CENTER_SCANNER_SWEEP, world_item_names) + self.assertNotIn(item_names.COMMAND_CENTER_EXTRA_SUPPLIES, world_item_names) + self.assertNotIn(item_names.ULTRA_CAPACITORS, world_item_names) + self.assertNotIn(item_names.ORBITAL_DEPOTS, world_item_names) + self.assertNotIn(item_names.DOMINION_TROOPER, world_item_names) + def test_all_kerrigan_missions_are_nobuild_and_grant_story_tech_is_on(self) -> None: # The actual situation the bug got caught world_options = { From 33b485c0c3021175de6958042e821ab72ee92cb8 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Tue, 30 Sep 2025 19:47:08 -0500 Subject: [PATCH 0775/1218] Core: expose world version to world classes and yaml (#5484) * support version on new manifest * apply world version from manifest * Update Generate.py * docs * reduce mm2 version again * wrong version * validate game in world_types * Update Generate.py * let unknown game fall through to later exception * hide real world version behind property * named tuple is immutable * write minimum world version to template yaml, fix gen edge cases * punctuation * check for world version in autoworldregister * missed one --------- Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- Generate.py | 17 ++++++++++++++- Main.py | 4 +++- Options.py | 7 ++++-- data/options.yaml | 4 ++++ worlds/AutoWorld.py | 8 ++++++- worlds/__init__.py | 24 ++++++++++++++++++++- worlds/generic/docs/advanced_settings_en.md | 9 +++++--- worlds/mm2/__init__.py | 1 - worlds/mm2/archipelago.json | 5 +++++ 9 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 worlds/mm2/archipelago.json diff --git a/Generate.py b/Generate.py index 5d65a688c7af..8e8132038509 100644 --- a/Generate.py +++ b/Generate.py @@ -486,7 +486,22 @@ def roll_settings(weights: dict, plando_options: PlandoOptions = PlandoOptions.b if required_plando_options: raise Exception(f"Settings reports required plando module {str(required_plando_options)}, " f"which is not enabled.") - + games = requirements.get("game", {}) + for game, version in games.items(): + if game not in AutoWorldRegister.world_types: + continue + if not version: + raise Exception(f"Invalid version for game {game}: {version}.") + if isinstance(version, str): + version = {"min": version} + if "min" in version and tuplize_version(version["min"]) > AutoWorldRegister.world_types[game].world_version: + raise Exception(f"Settings reports required version of world \"{game}\" is at least {version['min']}, " + f"however world is of version " + f"{AutoWorldRegister.world_types[game].world_version.as_simple_string()}.") + if "max" in version and tuplize_version(version["max"]) < AutoWorldRegister.world_types[game].world_version: + raise Exception(f"Settings reports required version of world \"{game}\" is no later than {version['max']}, " + f"however world is of version " + f"{AutoWorldRegister.world_types[game].world_version.as_simple_string()}.") ret = argparse.Namespace() for option_key in Options.PerGameCommonOptions.type_hints: if option_key in weights and option_key not in Options.CommonOptions.type_hints: diff --git a/Main.py b/Main.py index 6d81ff23a034..d872a3c15953 100644 --- a/Main.py +++ b/Main.py @@ -59,7 +59,9 @@ def main(args, seed=None, baked_server_options: dict[str, object] | None = None) for name, cls in AutoWorld.AutoWorldRegister.world_types.items(): if not cls.hidden and len(cls.item_names) > 0: - logger.info(f" {name:{longest_name}}: Items: {len(cls.item_names):{item_count}} | " + logger.info(f" {name:{longest_name}}: " + f"v{cls.world_version.as_simple_string()} |" + f"Items: {len(cls.item_names):{item_count}} | " f"Locations: {len(cls.location_names):{location_count}}") del item_count, location_count diff --git a/Options.py b/Options.py index dc1e8c907c78..282f75761684 100644 --- a/Options.py +++ b/Options.py @@ -1710,7 +1710,7 @@ def generate_yaml_templates(target_folder: typing.Union[str, "pathlib.Path"], ge from jinja2 import Template from worlds import AutoWorldRegister - from Utils import local_path, __version__ + from Utils import local_path, __version__, tuplize_version full_path: str @@ -1753,7 +1753,10 @@ def yaml_dump_scalar(scalar) -> str: res = template.render( option_groups=option_groups, - __version__=__version__, game=game_name, yaml_dump=yaml_dump_scalar, + __version__=__version__, + game=game_name, + world_version=world.world_version.as_simple_string(), + yaml_dump=yaml_dump_scalar, dictify_range=dictify_range, cleandoc=cleandoc, ) diff --git a/data/options.yaml b/data/options.yaml index f2621124c890..3278a3c5c1e7 100644 --- a/data/options.yaml +++ b/data/options.yaml @@ -33,6 +33,10 @@ description: {{ yaml_dump("Default %s Template" % game) }} game: {{ yaml_dump(game) }} requires: version: {{ __version__ }} # Version of Archipelago required for this yaml to work as expected. + {%- if world_version != "0.0.0" %} + game: + {{ yaml_dump(game) }}: {{ world_version }} # Version of the world required for this yaml to work as expected. + {%- endif %} {%- macro range_option(option) %} # You can define additional values between the minimum and maximum values. diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 676171b7ff16..1805b11a0924 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -12,7 +12,7 @@ from Options import item_and_loc_options, ItemsAccessibility, OptionGroup, PerGameCommonOptions from BaseClasses import CollectionState -from Utils import deprecate +from Utils import Version if TYPE_CHECKING: from BaseClasses import MultiWorld, Item, Location, Tutorial, Region, Entrance @@ -75,6 +75,10 @@ def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> Aut if "required_client_version" in base.__dict__: dct["required_client_version"] = max(dct["required_client_version"], base.__dict__["required_client_version"]) + if "world_version" in dct: + if dct["world_version"] != Version(0, 0, 0): + raise RuntimeError(f"{name} is attempting to set 'world_version' from within the class. world_version " + f"can only be set from manifest.") # construct class new_class = super().__new__(mcs, name, bases, dct) @@ -337,6 +341,8 @@ class World(metaclass=AutoWorldRegister): """If loaded from a .apworld, this is the Path to it.""" __file__: ClassVar[str] """path it was loaded from""" + world_version: ClassVar[Version] = Version(0, 0, 0) + """Optional world version loaded from archipelago.json""" def __init__(self, multiworld: "MultiWorld", player: int): assert multiworld is not None diff --git a/worlds/__init__.py b/worlds/__init__.py index c363d7f20c6d..b9ef225f52e7 100644 --- a/worlds/__init__.py +++ b/worlds/__init__.py @@ -7,10 +7,11 @@ import zipimport import time import dataclasses +import json from typing import List from NetUtils import DataPackage -from Utils import local_path, user_path, Version, version_tuple +from Utils import local_path, user_path, Version, version_tuple, tuplize_version local_folder = os.path.dirname(__file__) user_folder = user_path("worlds") if user_path() != local_path() else user_path("custom_worlds") @@ -111,8 +112,25 @@ def load(self) -> bool: else: world_source.load() + from .AutoWorld import AutoWorldRegister +for world_source in world_sources: + if not world_source.is_zip: + # look for manifest + manifest = {} + for dirpath, dirnames, filenames in os.walk(world_source.resolved_path): + for file in filenames: + if file.endswith("archipelago.json"): + manifest = json.load(open(os.path.join(dirpath, file), "r")) + break + if manifest: + break + game = manifest.get("game") + if game in AutoWorldRegister.world_types: + AutoWorldRegister.world_types[game].world_version = Version(*tuplize_version(manifest.get("world_version", + "0.0.0"))) + if apworlds: # encapsulation for namespace / gc purposes def load_apworlds() -> None: @@ -164,6 +182,10 @@ def fail_world(game_name: str, reason: str, add_as_failed_to_load: bool = True) add_as_failed_to_load=False) else: apworld_source.load() + if apworld.game in AutoWorldRegister.world_types: + # world could fail to load at this point + if apworld.world_version: + AutoWorldRegister.world_types[apworld.game].world_version = apworld.world_version load_apworlds() del load_apworlds diff --git a/worlds/generic/docs/advanced_settings_en.md b/worlds/generic/docs/advanced_settings_en.md index 2594307624b8..bc8754b9c644 100644 --- a/worlds/generic/docs/advanced_settings_en.md +++ b/worlds/generic/docs/advanced_settings_en.md @@ -81,7 +81,8 @@ are `description`, `name`, `game`, `requires`, and the name of the games you wan * `requires` details different requirements from the generator for the YAML to work as you expect it to. Generally this is good for detailing the version of Archipelago this YAML was prepared for. If it is rolled on an older version, options may be missing and as such it will not work as expected. If any plando is used in the file then requiring it - here to ensure it will be used is good practice. + here to ensure it will be used is good practice. Specific versions of custom worlds can also be required, ensuring + that the generator is using a compatible version. ## Game Options @@ -165,7 +166,9 @@ game: A Link to the Past: 10 Timespinner: 10 requires: - version: 0.4.1 + version: 0.6.4 + game: + A Link to the Past: 0.6.4 A Link to the Past: accessibility: minimal progression_balancing: 50 @@ -229,7 +232,7 @@ Timespinner: * `name` is `Example Player` and this will be used in the server console when sending and receiving items. * `game` has an equal chance of being either `A Link to the Past` or `Timespinner` with a 10/20 chance for each. This is because each game has a weight of 10 and the total of all weights is 20. -* `requires` is set to required release version 0.3.2 or higher. +* `requires` is set to require Archipelago release version 0.6.4 or higher, as well as A Link to the Past version 0.6.4. * `accessibility` for both games is set to `minimal` which will set this seed to beatable only, so some locations and items may be completely inaccessible but the seed will still be completable. * `progression_balancing` for both games is set to 50, the default value, meaning we will likely receive important items diff --git a/worlds/mm2/__init__.py b/worlds/mm2/__init__.py index 529810d41047..5389fc8af741 100644 --- a/worlds/mm2/__init__.py +++ b/worlds/mm2/__init__.py @@ -96,7 +96,6 @@ class MM2World(World): location_name_groups = location_groups web = MM2WebWorld() rom_name: bytearray - world_version: Tuple[int, int, int] = (0, 3, 2) wily_5_weapons: Dict[int, List[int]] def __init__(self, multiworld: MultiWorld, player: int): diff --git a/worlds/mm2/archipelago.json b/worlds/mm2/archipelago.json new file mode 100644 index 000000000000..75c098fdf964 --- /dev/null +++ b/worlds/mm2/archipelago.json @@ -0,0 +1,5 @@ +{ + "game": "Mega Man 2", + "world_version": "0.3.2", + "minimum_ap_version": "0.6.4" +} From b162095f89139d71e703a0d535645b2fb2a32cd7 Mon Sep 17 00:00:00 2001 From: qwint Date: Wed, 1 Oct 2025 14:54:41 -0500 Subject: [PATCH 0776/1218] Launcher: Rework apworld install popup #5508 --- worlds/LauncherComponents.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index b2187298ff15..58c724ac2bf2 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -5,7 +5,7 @@ from enum import Enum, auto from typing import Optional, Callable, List, Iterable, Tuple -from Utils import local_path, open_filename, is_frozen +from Utils import local_path, open_filename, is_frozen, is_kivy_running class Type(Enum): @@ -177,10 +177,9 @@ def _install_apworld(apworld_src: str = "") -> Optional[Tuple[pathlib.Path, path if module_name == loaded_name: found_already_loaded = True break - if found_already_loaded: - raise Exception(f"Installed APWorld successfully, but '{module_name}' is already loaded,\n" - "so a Launcher restart is required to use the new installation.\n" - "If the Launcher is not open, no action needs to be taken.") + if found_already_loaded and is_kivy_running(): + raise Exception(f"Installed APWorld successfully, but '{module_name}' is already loaded, " + "so a Launcher restart is required to use the new installation.") world_source = worlds.WorldSource(str(target), is_zip=True) bisect.insort(worlds.world_sources, world_source) world_source.load() @@ -197,7 +196,7 @@ def install_apworld(apworld_path: str = "") -> None: source, target = res except Exception as e: import Utils - Utils.messagebox(e.__class__.__name__, str(e), error=True) + Utils.messagebox("Notice", str(e), error=True) logging.exception(e) else: import Utils From 50f6cf04f691d4dd70737bac47221a093387ba50 Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Thu, 2 Oct 2025 02:36:33 -0500 Subject: [PATCH 0777/1218] Core: "Build APWorlds" cleanup (#5507) * allow filtered build, subprocess * component description * correct name * move back to running directly --- worlds/LauncherComponents.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index 58c724ac2bf2..5d50cdeff4f1 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -244,17 +244,32 @@ def install_apworld(apworld_path: str = "") -> None: } if not is_frozen(): - def _build_apworlds(): + def _build_apworlds(*launch_args: str): import json import os import zipfile from worlds import AutoWorldRegister from worlds.Files import APWorldContainer + from Launcher import open_folder + + import argparse + parser = argparse.ArgumentParser("Build script for APWorlds") + parser.add_argument("worlds", type=str, default=(), nargs="*", help="Names of APWorlds to build.") + args = parser.parse_args(launch_args) + + if args.worlds: + games = [(game, AutoWorldRegister.world_types.get(game, None)) for game in args.worlds] + else: + games = [(worldname, worldtype) for worldname, worldtype in AutoWorldRegister.world_types.items() + if not worldtype.zip_path] apworlds_folder = os.path.join("build", "apworlds") os.makedirs(apworlds_folder, exist_ok=True) - for worldname, worldtype in AutoWorldRegister.world_types.items(): + for worldname, worldtype in games: + if not worldtype: + logging.error(f"Requested APWorld \"{worldname}\" does not exist.") + continue file_name = os.path.split(os.path.dirname(worldtype.__file__))[1] world_directory = os.path.join("worlds", file_name) if os.path.isfile(os.path.join(world_directory, "archipelago.json")): @@ -269,12 +284,15 @@ def _build_apworlds(): apworld.manifest_path = f"{file_name}/archipelago.json" with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED, compresslevel=9) as zf: - for path in pathlib.Path(world_directory).rglob("*.*"): + for path in pathlib.Path(world_directory).rglob("*"): relative_path = os.path.join(*path.parts[path.parts.index("worlds") + 1:]) if "__MACOSX" in relative_path or ".DS_STORE" in relative_path or "__pycache__" in relative_path: continue if not relative_path.endswith("archipelago.json"): zf.write(path, relative_path) zf.writestr(apworld.manifest_path, json.dumps(manifest)) + open_folder(apworlds_folder) + - components.append(Component('Build apworlds', func=_build_apworlds, cli=True,)) + components.append(Component('Build APWorlds', func=_build_apworlds, cli=True, + description="Build APWorlds from loose-file world folders.")) From 6d7abb3780e48677c28b648fdc1e84dd9676d878 Mon Sep 17 00:00:00 2001 From: qwint Date: Thu, 2 Oct 2025 18:56:11 -0500 Subject: [PATCH 0778/1218] Webhost: Ignore Invalid Worlds in Webhost (#5433) * filter world types at top of webhost so worlds that aren't loadable in webhost are "uninstalled" * mark invalid worlds, show error if any, then filter to exclude them --- WebHost.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/WebHost.py b/WebHost.py index fd8daeb371bd..db465be61beb 100644 --- a/WebHost.py +++ b/WebHost.py @@ -109,6 +109,13 @@ def copy_tutorials_files_to_static() -> None: logging.exception(e) logging.warning("Could not update LttP sprites.") app = get_app() + from worlds import AutoWorldRegister + # Update to only valid WebHost worlds + invalid_worlds = {name for name, world in AutoWorldRegister.world_types.items() + if not hasattr(world.web, "tutorials")} + if invalid_worlds: + logging.error(f"Following worlds not loaded as they are invalid for WebHost: {invalid_worlds}") + AutoWorldRegister.world_types = {k: v for k, v in AutoWorldRegister.world_types.items() if k not in invalid_worlds} create_options_files() copy_tutorials_files_to_static() if app.config["SELFLAUNCH"]: From 83cfb803a79cc9538c518459541dbb0294c31baa Mon Sep 17 00:00:00 2001 From: Kaito Sinclaire Date: Thu, 2 Oct 2025 17:05:29 -0700 Subject: [PATCH 0779/1218] SMZ3: Fix forced fill behaviors (GT junk fill, initial Super/PB front fill) (#5361) * SMZ3: Make GT fill behave like upstream SMZ3 multiworld GT fill This means: All items local, 50% guaranteed filler, followed by possible useful items, never progression. * Fix item links * SMZ3: Ensure in all cases, we remove the right item from the pool Previously front fill would cause erratic errors on frozen, with the cause immediately revealed by, on source, tripping the assert that was added in #5109 * SMZ3: Truly, *properly* fix GT junk fill After hours of diving deep into the upstream SMZ3 randomizer, it finally behaves identically to how it does there --- worlds/smz3/TotalSMZ3/Item.py | 2 - .../TotalSMZ3/Regions/Zelda/GanonsTower.py | 6 +- worlds/smz3/__init__.py | 61 +++++++++---------- 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/worlds/smz3/TotalSMZ3/Item.py b/worlds/smz3/TotalSMZ3/Item.py index 28e9658ce1d0..7e6a11861fd4 100644 --- a/worlds/smz3/TotalSMZ3/Item.py +++ b/worlds/smz3/TotalSMZ3/Item.py @@ -424,7 +424,6 @@ def CreateKeycards(world): ] for item in itemPool: - item.Progression = True item.World = world return itemPool @@ -439,7 +438,6 @@ def CreateSmMaps(world): ] for item in itemPool: - item.Progression = True item.World = world return itemPool diff --git a/worlds/smz3/TotalSMZ3/Regions/Zelda/GanonsTower.py b/worlds/smz3/TotalSMZ3/Regions/Zelda/GanonsTower.py index e17d7072258c..7cd178874bc9 100644 --- a/worlds/smz3/TotalSMZ3/Regions/Zelda/GanonsTower.py +++ b/worlds/smz3/TotalSMZ3/Regions/Zelda/GanonsTower.py @@ -145,8 +145,12 @@ def CanComplete(self, items: Progression): def CanFill(self, item: Item): if (self.Config.Multiworld): + # changed for AP becuase upstream only uses CanFill for filling progression-related items + # note that item.Progression does not include all items with progression classification # item.World will be None for item created by create_item for item links - if (item.World is not None and (item.World != self.world or item.Progression)): + if (item.World is not None and item.World != self.world and (item.Progression or item.IsDungeonItem() or item.IsKeycard() or item.IsSmMap())): + return False + if (item.World is not None and item.World == self.world and item.Progression): return False if (self.Config.Keysanity and not ((item.Type == ItemType.BigKeyGT or item.Type == ItemType.KeyGT) and item.World == self.world) and (item.IsKey() or item.IsBigKey() or item.IsKeycard())): return False diff --git a/worlds/smz3/__init__.py b/worlds/smz3/__init__.py index 4d0b63f33c36..c4a1f313fa0a 100644 --- a/worlds/smz3/__init__.py +++ b/worlds/smz3/__init__.py @@ -260,13 +260,19 @@ def set_rules(self): l.always_allow = lambda state, item, loc=loc: \ item.game == "SMZ3" and \ loc.alwaysAllow(item.item, state.smz3state[self.player]) - old_rule = l.item_rule - l.item_rule = lambda item, loc=loc, region=region: (\ + l.item_rule = lambda item, loc=loc, region=region, old_rule=l.item_rule: (\ item.game != "SMZ3" or \ loc.allow(item.item, None) and \ region.CanFill(item.item)) and old_rule(item) set_rule(l, lambda state, loc=loc: loc.Available(state.smz3state[self.player])) + # In multiworlds, GT is disallowed from having progression items. + # This item rule replicates this behavior for non-SMZ3 games + for loc in self.smz3World.GetRegion("Ganon's Tower").Locations: + l = self.locations[loc.Name] + l.item_rule = lambda item, old_rule=l.item_rule: \ + (item.game == "SMZ3" or not item.advancement) and old_rule(item) + def create_regions(self): self.create_locations(self.player) startRegion = self.create_region(self.multiworld, self.player, 'Menu') @@ -589,29 +595,18 @@ def write_spoiler(self, spoiler_handle: TextIO): ])) def JunkFillGT(self, factor): - poolLength = len(self.multiworld.itempool) - junkPoolIdx = [i for i in range(0, poolLength) - if self.multiworld.itempool[i].classification in (ItemClassification.filler, ItemClassification.trap)] + junkPoolIdx = [idx for idx, i in enumerate(self.multiworld.itempool) if i.excludable] + self.random.shuffle(junkPoolIdx) + junkLocations = [loc for loc in self.locations.values() if loc.name in self.locationNamesGT and loc.item is None] + self.random.shuffle(junkLocations) toRemove = [] - for loc in self.locations.values(): - # commenting this for now since doing a partial GT pre fill would allow for non SMZ3 progression in GT - # which isnt desirable (SMZ3 logic only filters for SMZ3 items). Having progression in GT can only happen in Single Player. - # if len(toRemove) >= int(len(self.locationNamesGT) * factor * self.smz3World.TowerCrystals / 7): - # break - if loc.name in self.locationNamesGT and loc.item is None: - poolLength = len(junkPoolIdx) - # start looking at a random starting index and loop at start if no match found - start = self.multiworld.random.randint(0, poolLength) - itemFromPool = None - for off in range(0, poolLength): - i = (start + off) % poolLength - candidate = self.multiworld.itempool[junkPoolIdx[i]] - if junkPoolIdx[i] not in toRemove and loc.can_fill(self.multiworld.state, candidate, False): - itemFromPool = candidate - toRemove.append(junkPoolIdx[i]) - break - assert itemFromPool is not None, "Can't find anymore item(s) to pre fill GT" - self.multiworld.push_item(loc, itemFromPool, False) + for loc in junkLocations: + # Note: Upstream GT junk fill uses FastFill, which ignores item rules + if len(junkPoolIdx) == 0 or len(toRemove) >= int(len(junkLocations) * factor * self.smz3World.TowerCrystals / 7): + break + itemFromPool = self.multiworld.itempool[junkPoolIdx[0]] + toRemove.append(junkPoolIdx.pop(0)) + loc.place_locked_item(itemFromPool) toRemove.sort(reverse = True) for i in toRemove: self.multiworld.itempool.pop(i) @@ -622,15 +617,15 @@ def FillItemAtLocation(self, itemPool, itemType, location): raise Exception(f"Tried to place item {itemType} at {location.Name}, but there is no such item in the item pool") else: location.Item = itemToPlace - itemFromPool = next((i for i in self.multiworld.itempool if i.player == self.player and i.name == itemToPlace.Type.name), None) - if itemFromPool is not None: + itemPoolIdx = next((idx for idx, i in enumerate(self.multiworld.itempool) if i.player == self.player and i.name == itemToPlace.Type.name), None) + if itemPoolIdx is not None: + itemFromPool = self.multiworld.itempool.pop(itemPoolIdx) self.multiworld.get_location(location.Name, self.player).place_locked_item(itemFromPool) - self.multiworld.itempool.remove(itemFromPool) else: - itemFromPool = next((i for i in self.smz3DungeonItems if i.player == self.player and i.name == itemToPlace.Type.name), None) - if itemFromPool is not None: + itemPoolIdx = next((idx for idx, i in enumerate(self.smz3DungeonItems) if i.player == self.player and i.name == itemToPlace.Type.name), None) + if itemPoolIdx is not None: + itemFromPool = self.smz3DungeonItems.pop(itemPoolIdx) self.multiworld.get_location(location.Name, self.player).place_locked_item(itemFromPool) - self.smz3DungeonItems.remove(itemFromPool) itemPool.remove(itemToPlace) def FrontFillItemInOwnWorld(self, itemPool, itemType): @@ -640,10 +635,10 @@ def FrontFillItemInOwnWorld(self, itemPool, itemType): raise Exception(f"Tried to front fill {item.Name} in, but no location was available") location.Item = item - itemFromPool = next((i for i in self.multiworld.itempool if i.player == self.player and i.name == item.Type.name and i.advancement == item.Progression), None) - if itemFromPool is not None: + itemPoolIdx = next((idx for idx, i in enumerate(self.multiworld.itempool) if i.player == self.player and i.name == item.Type.name and i.advancement == item.Progression), None) + if itemPoolIdx is not None: + itemFromPool = self.multiworld.itempool.pop(itemPoolIdx) self.multiworld.get_location(location.Name, self.player).place_locked_item(itemFromPool) - self.multiworld.itempool.remove(itemFromPool) itemPool.remove(item) def InitialFillInOwnWorld(self): From 6a08064a520fb4a1a1f9d83fe0280c22e8c3d95b Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 4 Oct 2025 03:04:23 +0200 Subject: [PATCH 0780/1218] Core: Assert that if an apworld manifest file exists, it has a game field (#5478) * Assert that if an apworld manifest file exists, it has a game field * god damnit * Update worlds/LauncherComponents.py Co-authored-by: Fabian Dill * Update setup.py Co-authored-by: Fabian Dill --------- Co-authored-by: Fabian Dill --- setup.py | 9 +++++++++ worlds/LauncherComponents.py | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/setup.py b/setup.py index 98b9dd604a1c..0233c2472268 100644 --- a/setup.py +++ b/setup.py @@ -383,6 +383,15 @@ def run(self) -> None: world_directory = self.libfolder / "worlds" / file_name if os.path.isfile(world_directory / "archipelago.json"): manifest = json.load(open(world_directory / "archipelago.json")) + + assert "game" in manifest, ( + f"World directory {world_directory} has an archipelago.json manifest file, but it" + "does not define a \"game\"." + ) + assert manifest["game"] == worldtype.game, ( + f"World directory {world_directory} has an archipelago.json manifest file, but value of the" + f"\"game\" field ({manifest['game']} does not equal the World class's game ({worldtype.game})." + ) else: manifest = {} # this method creates an apworld that cannot be moved to a different OS or minor python version, diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index 5d50cdeff4f1..527208ccff98 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -274,6 +274,15 @@ def _build_apworlds(*launch_args: str): world_directory = os.path.join("worlds", file_name) if os.path.isfile(os.path.join(world_directory, "archipelago.json")): manifest = json.load(open(os.path.join(world_directory, "archipelago.json"))) + + assert "game" in manifest, ( + f"World directory {world_directory} has an archipelago.json manifest file, but it" + "does not define a \"game\"." + ) + assert manifest["game"] == worldtype.game, ( + f"World directory {world_directory} has an archipelago.json manifest file, but value of the" + f"\"game\" field ({manifest['game']} does not equal the World class's game ({worldtype.game})." + ) else: manifest = {} From 91e97b68d402e595459c72c2202b8816a4a49e04 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Sun, 5 Oct 2025 01:49:56 +0000 Subject: [PATCH 0781/1218] Webhost: eagerly free resources in customserver (#5512) * Unref some locals that would live long for no reason. * Limit scope of db_session in init_save. --- WebHostLib/customserver.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/WebHostLib/customserver.py b/WebHostLib/customserver.py index 156c12523d9e..45aca124f51b 100644 --- a/WebHostLib/customserver.py +++ b/WebHostLib/customserver.py @@ -97,6 +97,7 @@ def listen_to_db_commands(self): self.main_loop.call_soon_threadsafe(cmdprocessor, command.commandtext) command.delete() commit() + del commands time.sleep(5) @db_session @@ -146,13 +147,13 @@ def load(self, room_id: int): self.location_name_groups = static_location_name_groups return self._load(multidata, game_data_packages, True) - @db_session def init_save(self, enabled: bool = True): self.saving = enabled if self.saving: - savegame_data = Room.get(id=self.room_id).multisave - if savegame_data: - self.set_save(restricted_loads(Room.get(id=self.room_id).multisave)) + with db_session: + savegame_data = Room.get(id=self.room_id).multisave + if savegame_data: + self.set_save(restricted_loads(Room.get(id=self.room_id).multisave)) self._start_async_saving(atexit_save=False) threading.Thread(target=self.listen_to_db_commands, daemon=True).start() @@ -304,6 +305,7 @@ async def start_room(room_id): with db_session: room = Room.get(id=ctx.room_id) room.last_port = port + del room else: ctx.logger.exception("Could not determine port. Likely hosting failure.") with db_session: @@ -322,6 +324,7 @@ async def start_room(room_id): with db_session: room = Room.get(id=room_id) room.last_port = -1 + del room logger.exception(e) raise else: @@ -333,11 +336,12 @@ async def start_room(room_id): ctx.save_dirty = False # make sure the saving thread does not write to DB after final wakeup ctx.exit_event.set() # make sure the saving thread stops at some point # NOTE: async saving should probably be an async task and could be merged with shutdown_task - with (db_session): + with db_session: # ensure the Room does not spin up again on its own, minute of safety buffer room = Room.get(id=room_id) room.last_activity = datetime.datetime.utcnow() - \ datetime.timedelta(minutes=1, seconds=room.timeout) + del room logging.info(f"Shutting down room {room_id} on {name}.") finally: await asyncio.sleep(5) From ae4426af08fda82b01be11e4f62c2ef1cb4da46a Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Sat, 4 Oct 2025 20:46:26 -0600 Subject: [PATCH 0782/1218] Core: Pad version string in world printout #5511 --- Main.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Main.py b/Main.py index d872a3c15953..892baa8d4fa5 100644 --- a/Main.py +++ b/Main.py @@ -54,13 +54,16 @@ def main(args, seed=None, baked_server_options: dict[str, object] | None = None) logger.info(f"Found {len(AutoWorld.AutoWorldRegister.world_types)} World Types:") longest_name = max(len(text) for text in AutoWorld.AutoWorldRegister.world_types) - item_count = len(str(max(len(cls.item_names) for cls in AutoWorld.AutoWorldRegister.world_types.values()))) - location_count = len(str(max(len(cls.location_names) for cls in AutoWorld.AutoWorldRegister.world_types.values()))) + world_classes = AutoWorld.AutoWorldRegister.world_types.values() + + version_count = max(len(cls.world_version.as_simple_string()) for cls in world_classes) + item_count = len(str(max(len(cls.item_names) for cls in world_classes))) + location_count = len(str(max(len(cls.location_names) for cls in world_classes))) for name, cls in AutoWorld.AutoWorldRegister.world_types.items(): if not cls.hidden and len(cls.item_names) > 0: logger.info(f" {name:{longest_name}}: " - f"v{cls.world_version.as_simple_string()} |" + f"v{cls.world_version.as_simple_string():{version_count}} | " f"Items: {len(cls.item_names):{item_count}} | " f"Locations: {len(cls.location_names):{location_count}}") From 7a652518a328e5ba57a60162855d6e5870f92428 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Sat, 4 Oct 2025 22:59:52 -0400 Subject: [PATCH 0783/1218] [Website docs] Update wording of "adding a game to archipelago" section --- WebHostLib/static/assets/faq/en.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/WebHostLib/static/assets/faq/en.md b/WebHostLib/static/assets/faq/en.md index 96e526612be6..588750065666 100644 --- a/WebHostLib/static/assets/faq/en.md +++ b/WebHostLib/static/assets/faq/en.md @@ -66,7 +66,7 @@ is to ensure items necessary to complete the game will be accessible to the play rules allowing certain items to be placed in normally unreachable locations, provided the player has indicated they are comfortable exploiting certain glitches in the game. -## I want to add a game to the Archipelago randomizer. How do I do that? +## I want to develop a game implementation for Archipelago. How do I do that? The best way to get started is to take a look at our code on GitHub: [Archipelago GitHub Page](https://github.com/ArchipelagoMW/Archipelago). @@ -77,4 +77,5 @@ There, you will find examples of games in the `worlds` folder: You may also find developer documentation in the `docs` folder: [/docs Folder in Archipelago Code](https://github.com/ArchipelagoMW/Archipelago/tree/main/docs). -If you have more questions, feel free to ask in the **#ap-world-dev** channel on our Discord. +If you have more questions regarding development of a game implementation, feel free to ask in the **#ap-world-dev** +channel on our Discord. From 7996fd8d19930734aec17e86b349e6a47d424352 Mon Sep 17 00:00:00 2001 From: PinkSwitch <52474902+PinkSwitch@users.noreply.github.com> Date: Sat, 4 Oct 2025 22:01:56 -0500 Subject: [PATCH 0784/1218] Core: Update start inventory description to mention item quantities (#5460) * SNIClient: new SnesReader interface * fix Python 3.8 compatibility `bisect_right` * move to worlds because we don't have good separation importable modules and entry points * `read` gives object that contains data * remove python 3.10 implementation and update typing * remove obsolete comment * freeze _MemRead and assert type of get parameter * some optimization in `SnesData.get` * pass context to `read` so that we can have a static instance of `SnesReader` * add docstring to `SnesReader` * remove unused import * break big reads into chunks * some minor improvements - `dataclass` instead of `NamedTuple` for `Read` - comprehension in `SnesData.__init__` - `slots` for dataclasses * Change descriptions * Fix sni client? --------- Co-authored-by: beauxq Co-authored-by: Doug Hoskisson --- Options.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Options.py b/Options.py index 282f75761684..c0c04952d715 100644 --- a/Options.py +++ b/Options.py @@ -1380,7 +1380,7 @@ class NonLocalItems(ItemSet): class StartInventory(ItemDict): - """Start with these items.""" + """Start with the specified amount of these items. Example: "Bomb: 1" """ verify_item_name = True display_name = "Start Inventory" rich_text_doc = True @@ -1388,7 +1388,7 @@ class StartInventory(ItemDict): class StartInventoryPool(StartInventory): - """Start with these items and don't place them in the world. + """Start with the specified amount of these items and don't place them in the world. Example: "Bomb: 1" The game decides what the replacement items will be. """ From a547c8dd7d9ad66501410ca3f77df72634a9cc77 Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Sat, 4 Oct 2025 21:02:26 -0600 Subject: [PATCH 0785/1218] Core: Add location count field for world to spoiler log (#5440) * Add location count * Only count non-events * Add total count --- BaseClasses.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/BaseClasses.py b/BaseClasses.py index 855efc6009cf..3e6904ba6ad7 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1858,6 +1858,9 @@ def write_option(option_key: str, option_obj: Options.AssembleOptions) -> None: Utils.__version__, self.multiworld.seed)) outfile.write('Filling Algorithm: %s\n' % self.multiworld.algorithm) outfile.write('Players: %d\n' % self.multiworld.players) + if self.multiworld.players > 1: + loc_count = len([loc for loc in self.multiworld.get_locations() if not loc.is_event]) + outfile.write('Total Location Count: %d\n' % loc_count) outfile.write(f'Plando Options: {self.multiworld.plando_options}\n') AutoWorld.call_stage(self.multiworld, "write_spoiler_header", outfile) @@ -1866,6 +1869,9 @@ def write_option(option_key: str, option_obj: Options.AssembleOptions) -> None: outfile.write('\nPlayer %d: %s\n' % (player, self.multiworld.get_player_name(player))) outfile.write('Game: %s\n' % self.multiworld.game[player]) + loc_count = len([loc for loc in self.multiworld.get_locations(player) if not loc.is_event]) + outfile.write('Location Count: %d\n' % loc_count) + for f_option, option in self.multiworld.worlds[player].options_dataclass.type_hints.items(): write_option(f_option, option) From ec9145e61d97e8e482c5b048352fcd9d0f90ab25 Mon Sep 17 00:00:00 2001 From: Duck <31627079+duckboycool@users.noreply.github.com> Date: Sat, 4 Oct 2025 21:04:02 -0600 Subject: [PATCH 0786/1218] Region: Use Mapping type for adding locations/exits #5354 --- BaseClasses.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 3e6904ba6ad7..ee2f73ca5106 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1346,8 +1346,7 @@ def get_connecting_entrance(self, is_main_entrance: Callable[[Entrance], bool]) for entrance in self.entrances: # BFS might be better here, trying DFS for now. return entrance.parent_region.get_connecting_entrance(is_main_entrance) - def add_locations(self, locations: Dict[str, Optional[int]], - location_type: Optional[type[Location]] = None) -> None: + def add_locations(self, locations: Mapping[str, int | None], location_type: type[Location] | None = None) -> None: """ Adds locations to the Region object, where location_type is your Location class and locations is a dict of location names to address. @@ -1435,8 +1434,8 @@ def create_er_target(self, name: str) -> Entrance: entrance.connect(self) return entrance - def add_exits(self, exits: Union[Iterable[str], Dict[str, Optional[str]]], - rules: Dict[str, Callable[[CollectionState], bool]] = None) -> List[Entrance]: + def add_exits(self, exits: Iterable[str] | Mapping[str, str | None], + rules: Mapping[str, Callable[[CollectionState], bool]] | None = None) -> List[Entrance]: """ Connects current region to regions in exit dictionary. Passed region names must exist first. @@ -1444,7 +1443,7 @@ def add_exits(self, exits: Union[Iterable[str], Dict[str, Optional[str]]], created entrances will be named "self.name -> connecting_region" :param rules: rules for the exits from this region. format is {"connecting_region": rule} """ - if not isinstance(exits, Dict): + if not isinstance(exits, Mapping): exits = dict.fromkeys(exits) return [ self.connect( From bdef410eb2d12bcbc7562cbd37fa5b6c2e54a1db Mon Sep 17 00:00:00 2001 From: DJ-lennart Date: Sun, 5 Oct 2025 05:07:11 +0200 Subject: [PATCH 0787/1218] Civilization VI: Update for the setup instructions #5286 --- worlds/civ_6/docs/setup_en.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/worlds/civ_6/docs/setup_en.md b/worlds/civ_6/docs/setup_en.md index fb8404190ff1..c34a45403b8f 100644 --- a/worlds/civ_6/docs/setup_en.md +++ b/worlds/civ_6/docs/setup_en.md @@ -14,25 +14,27 @@ The following are required in order to play Civ VI in Archipelago: - A copy of the game `Civilization VI` including the two expansions `Rise & Fall` and `Gathering Storm` (both the Steam and Epic version should work). -## Enabling the tuner - -In the main menu, navigate to the "Game Options" page. On the "Game" menu, make sure that "Tuner (disables achievements)" is enabled. - ## Mod Installation 1. Download and unzip the latest release of the mod from [GitHub](https://github.com/hesto2/civilization_archipelago_mod/releases/latest). 2. Copy the folder containing the mod files to your Civ VI mods folder. On Windows, this is usually located at `C:\Users\YOUR_USER\Documents\My Games\Sid Meier's Civilization VI\Mods`. If you use OneDrive, check if the folder is instead located in your OneDrive file structure, and use that path when relevant in future steps. -3. After the Archipelago host generates a game, you should be given a `.apcivvi` file. Associate the file with the Archipelago Launcher and double click it. +3. After the Archipelago host generates a game, you should be given a `.apcivvi` file. You can open it as a zip file, you can do this by either right clicking it and opening it with a program that handles zip files (if you associate that file with the program it will open it with that program in the future by double clicking it), or by right clicking and renaming the file extension from `apcivvi` to `zip` (only works if you are displaying file extensions). You can also associate the file with the Archipelago Launcher and double click it and it will create a folder with the mod files inside of it. + +4. Copy the contents of the zip file or folder it generated (the name of the folder should be the same as the apcivvi file) into your Civilization VI Archipelago Mod folder (there should be five files placed there from the `.apcivvi` file, overwrite if asked). + +5. Your mod path should look something like `C:\Users\YOUR_USER\Documents\My Games\Sid Meier's Civilization VI\Mods\civilization_archipelago_mod`. If everything was done correctly you can now connect to the game. -4. Copy the contents of the new folder it generates (it will have the same name as the `.apcivvi` file) into your Civilization VI Archipelago Mod folder. If double clicking the `.apcivvi` file doesn't generate a folder, you can instead open it as a zip file. You can do this by either right clicking it and opening it with a program that handles zip files, or by right clicking and renaming the file extension from `apcivvi` to `zip`. +## Connecting to a game -5. Place the files generated from the `.apcivvi` in your archipelago mod folder (there should be five files placed there from the apcivvi file, overwrite if asked). Your mod path should look something like `C:\Users\YOUR_USER\Documents\My Games\Sid Meier's Civilization VI\Mods\civilization_archipelago_mod`. +1. In the main menu, navigate to the "Game Options" page. On the "Game" menu, make sure that "Tuner (disables achievements)" is enabled. -## Configuring your game +2. In the main menu, navigate to the "Additional Content" page, then go to "Mods" and make sure the Archipelago mod is enabled. -Make sure you enable the mod in the main title under Additional Content > Mods. When configuring your game, make sure to start the game in the Ancient Era and leave all settings related to starting technologies and civics as the defaults. Other than that, configure difficulty, AI, etc. as you normally would. +3. When starting the game make sure you are on the Gathering Storm ruleset in a Single Player game. Additionally you must start in the ancient era, other settings and game modes can be customised to your own liking. An important thing to note is that settings preset saves the mod list from when you created it, so if you want to use a setting preset with this you must create it after installing the Archipelago mod. + +4. To connect to the room open the Archipelago Launcher, from within the launcher open the Civ6 client and connect to the room. Once connected to the room enter your slot name and if everything went right you should now be connected. ## Troubleshooting @@ -51,3 +53,8 @@ Make sure you enable the mod in the main title under Additional Content > Mods. - If you still have any errors make sure the two expansions Rise & Fall and Gathering Storm are active in the mod selector (all the official DLC works without issues but Rise & Fall and Gathering Storm are required for the mod). - If boostsanity is enabled and those items are not being sent out but regular techs are, make sure you placed the files from your new room in the mod folder. + +- If you are neither receiving or sending items, make sure you have the correct client open. The client should be the Civ6 and NOT the Text Client. + +- This should be compatible with a lot of other mods, but if you are having issues try disabling all mods other than the Archipelago mod and see if the problem still persists. + From 1cbc5d66492fb60a47c93170f75880f6528a9a39 Mon Sep 17 00:00:00 2001 From: Branden Wood <44546325+BrandenEK@users.noreply.github.com> Date: Sat, 4 Oct 2025 23:08:15 -0400 Subject: [PATCH 0788/1218] Short Hike: improve setup guide docs #5470 --- worlds/shorthike/docs/setup_en.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/shorthike/docs/setup_en.md b/worlds/shorthike/docs/setup_en.md index 96e4d8dbbd1d..066a9cf38294 100644 --- a/worlds/shorthike/docs/setup_en.md +++ b/worlds/shorthike/docs/setup_en.md @@ -13,8 +13,8 @@ ## Installation -Open the [Randomizer Repository](https://github.com/BrandenEK/AShortHike.Randomizer) and follow -the installation instructions listed there. +1. Read the [Randomizer readme](https://github.com/BrandenEK/AShortHike.Randomizer) to see all required dependencies +1. Read the [Mod Installer readme](https://github.com/BrandenEK/AShortHike.Modding.Installer) to see how to download the required mods ## Connecting From 3eb25a59dcfd959ef9f1b6a8c787624fefe7a465 Mon Sep 17 00:00:00 2001 From: Louis M Date: Sat, 4 Oct 2025 23:08:34 -0400 Subject: [PATCH 0789/1218] Aquaria: Updating documentation to add latest clients informations (#5438) * Updating Aquaria documentation to add latest clients informations * Typo in the permission explanation --- worlds/aquaria/docs/setup_en.md | 37 +++++++++++++++++++++++------- worlds/aquaria/docs/setup_fr.md | 40 ++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/worlds/aquaria/docs/setup_en.md b/worlds/aquaria/docs/setup_en.md index b5a71f1ab5f1..7d974e70f062 100644 --- a/worlds/aquaria/docs/setup_en.md +++ b/worlds/aquaria/docs/setup_en.md @@ -23,7 +23,7 @@ game you play will make sure that every game has its own save game. Unzip the Aquaria randomizer release and copy all unzipped files in the Aquaria game folder. The unzipped files are: - aquaria_randomizer.exe - OpenAL32.dll -- override (directory) +- randomizer_files (directory) - SDL2.dll - usersettings.xml - wrap_oal.dll @@ -32,7 +32,10 @@ Unzip the Aquaria randomizer release and copy all unzipped files in the Aquaria If there is a conflict between files in the original game folder and the unzipped files, you should overwrite the original files with the ones from the unzipped randomizer. -Finally, to launch the randomizer, you must use the command line interface (you can open the command line interface +There is multiple way to start the game. The easiest one is using the launcher. To do that, just run +the `aquaria_randomizer.exe` file. + +You can also launch the randomizer using the command line interface (you can open the command line interface by typing `cmd` in the address bar of the Windows File Explorer). Here is the command line used to start the randomizer: @@ -49,15 +52,17 @@ aquaria_randomizer.exe --name YourName --server theServer:thePort --password th ### Linux when using the AppImage If you use the AppImage, just copy it into the Aquaria game folder. You then have to make it executable. You -can do that from command line by using: +can do that from the command line by using: ```bash chmod +x Aquaria_Randomizer-*.AppImage ``` -or by using the Graphical Explorer of your system. +or by using the Graphical file Explorer of your system (the permission can generally be set in the file properties). + +To launch the randomizer using the integrated launcher, just execute the AppImage file. -To launch the randomizer, just launch in command line: +You can also use command line arguments to set the server and slot of your game: ```bash ./Aquaria_Randomizer-*.AppImage --name YourName --server theServer:thePort @@ -79,7 +84,7 @@ the original game will stop working. Copying the folder will guarantee that the Untar the Aquaria randomizer release and copy all extracted files in the Aquaria game folder. The extracted files are: - aquaria_randomizer -- override (directory) +- randomizer_files (directory) - usersettings.xml - cacert.pem @@ -87,7 +92,7 @@ If there is a conflict between files in the original game folder and the extract the original files with the ones from the extracted randomizer files. Then, you should use your system package manager to install `liblua5`, `libogg`, `libvorbis`, `libopenal` and `libsdl2`. -On Debian base system (like Ubuntu), you can use the following command: +On Debian base systems (like Ubuntu), you can use the following command: ```bash sudo apt install liblua5.1-0-dev libogg-dev libvorbis-dev libopenal-dev libsdl2-dev @@ -97,7 +102,9 @@ Also, if there are certain `.so` files in the original Aquaria game folder (`lib `libSDL-1.2.so.0` and `libstdc++.so.6`), you should remove them from the Aquaria Randomizer game folder. Those are old libraries that will not work on the recent build of the randomizer. -To launch the randomizer, just launch in command line: +To launch the randomizer using the integrated launcher, just execute the `aquaria_randomizer` file. + +You can also use command line arguments to set the server and slot of your game: ```bash ./aquaria_randomizer --name YourName --server theServer:thePort @@ -115,6 +122,20 @@ sure that your executable has executable permission: ```bash chmod +x aquaria_randomizer ``` +### Steam deck + +On the Steamdeck, go in desktop mode and follow the same procedure as the Linux Appimage. + + +### No sound on Linux/Steam deck + +If your game play without problems, but with no sound, the game probably does not use the correct +driver for the sound system. To fix that, you can use `ALSOFT_DRIVERS=pulse` before your command +line to make it work. Something like this (depending on the way you launch the randomizer): + +```bash +ALSOFT_DRIVERS=pulse ./Aquaria_Randomizer-*.AppImage --name YourName --server theServer:thePort +``` ## Auto-Tracking diff --git a/worlds/aquaria/docs/setup_fr.md b/worlds/aquaria/docs/setup_fr.md index 7433dc5dce36..a72e1e2e9149 100644 --- a/worlds/aquaria/docs/setup_fr.md +++ b/worlds/aquaria/docs/setup_fr.md @@ -2,12 +2,12 @@ ## Logiciels nécessaires -- Une copie du jeu Aquaria non-modifiée (disponible sur la majorité des sites de ventes de jeux vidéos en ligne) +- Une copie du jeu Aquaria non modifiée (disponible sur la majorité des sites de ventes de jeux vidéos en ligne) - Le client du Randomizer d'Aquaria [Aquaria randomizer](https://github.com/tioui/Aquaria_Randomizer/releases/latest) ## Logiciels optionnels -- De manière optionnel, pour pouvoir envoyer des [commandes](/tutorial/Archipelago/commands/en) comme `!hint`: utilisez le client texte de [la version la plus récente d'Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases/latest) +- De manière optionnelle, pour pouvoir envoyer des [commandes](/tutorial/Archipelago/commands/en) comme `!hint`: utilisez le client texte de [la version la plus récente d'Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases/latest) - [Aquaria AP Tracker](https://github.com/palex00/aquaria-ap-tracker/releases/latest), pour utiliser avec [PopTracker](https://github.com/black-sliver/PopTracker/releases/latest) ## Procédures d'installation et d'exécution @@ -25,7 +25,7 @@ Désarchiver le randomizer d'Aquaria et copier tous les fichiers de l'archive da fichier d'archive devrait contenir les fichiers suivants: - aquaria_randomizer.exe - OpenAL32.dll -- override (directory) +- randomizer_files (directory) - SDL2.dll - usersettings.xml - wrap_oal.dll @@ -34,7 +34,10 @@ fichier d'archive devrait contenir les fichiers suivants: S'il y a des conflits entre les fichiers de l'archive zip et les fichiers du jeu original, vous devez utiliser les fichiers contenus dans l'archive zip. -Finalement, pour lancer le randomizer, vous devez utiliser la ligne de commande (vous pouvez ouvrir une interface de +Il y a plusieurs manières de lancer le randomizer. Le plus simple consiste à utiliser le lanceur intégré en +exécutant simplement le fichier `aquaria_randomizer.exe`. + +Il est également possible de lancer le randomizer en utilisant la ligne de commande (vous pouvez ouvrir une interface de ligne de commande, entrez l'adresse `cmd` dans la barre d'adresse de l'explorateur de fichier de Windows). Voici la ligne de commande à utiliser pour lancer le randomizer: @@ -57,9 +60,12 @@ le mettre exécutable. Vous pouvez mettre le fichier exécutable avec la command chmod +x Aquaria_Randomizer-*.AppImage ``` -ou bien en utilisant l'explorateur graphique de votre système. +ou bien en utilisant l'explorateur de fichier graphique de votre système (la permission d'exécution est +généralement dans les propriétés du fichier). + +Pour lancer le randomizer en utilisant le lanceur intégré, seulement exécuter le fichier AppImage. -Pour lancer le randomizer, utiliser la commande suivante: +Vous pouvez également lancer le randomizer en spécifiant les informations de connexion dans les arguments de la ligne de commande: ```bash ./Aquaria_Randomizer-*.AppImage --name VotreNom --server LeServeur:LePort @@ -83,7 +89,7 @@ avant de déposer le randomizer à l'intérieur permet de vous assurer de garder Désarchiver le fichier tar et copier tous les fichiers qu'il contient dans le répertoire du jeu d'origine d'Aquaria. Les fichiers extraient du fichier tar devraient être les suivants: - aquaria_randomizer -- override (directory) +- randomizer_files (directory) - usersettings.xml - cacert.pem @@ -102,7 +108,10 @@ Notez également que s'il y a des fichiers ".so" dans le répertoire d'Aquaria ( `libSDL-1.2.so.0` and `libstdc++.so.6`), vous devriez les retirer. Il s'agit de vieille version des librairies qui ne sont plus fonctionnelles dans les systèmes modernes et qui pourrait empêcher le randomizer de fonctionner. -Pour lancer le randomizer, utiliser la commande suivante: +Pour lancer le randomizer en utilisant le lanceur intégré, seulement exécuter le fichier `aquaria_randomizer`. + +Vous pouvez également lancer le randomizer en spécifiant les information de connexion dans les arguments de la +ligne de commande: ```bash ./aquaria_randomizer --name VotreNom --server LeServeur:LePort @@ -120,6 +129,21 @@ pour vous assurer que votre fichier est exécutable: ```bash chmod +x aquaria_randomizer ``` +### Steam Deck + +Pour installer le randomizer sur la Steam Deck, seulement suivre la procédure pour les fichiers AppImage +indiquée précédemment. + +### Aucun son sur Linux/Steam Deck + +Si le jeu fonctionne sans problème, mais qu'il n'y a aucun son, c'est probablement parce que le jeu +n'arrive pas à utiliser le bon pilote de son. Généralement, le problème est réglé en ajoutant la +variable d'environnement `ALSOFT_DRIVERS=pulse`. Voici un exemple (peut varier en fonction de la manière +que le randomizer est lancé): + +```bash +ALSOFT_DRIVERS=pulse ./Aquaria_Randomizer-*.AppImage --name VotreNom --server LeServeur:LePort +``` ## Tracking automatique From 60070c2f1e467728023b33a829fe19e3ccb558fd Mon Sep 17 00:00:00 2001 From: Benny D <78334662+benny-dreamly@users.noreply.github.com> Date: Sat, 4 Oct 2025 21:13:04 -0600 Subject: [PATCH 0790/1218] PyCharm: add a run config for the new apworld builder workflow (#5489) * add Build APWorld PyCharm run config * change casing of the argument * Update Build APWorld.run.xml --------- Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- .run/Build APWorld.run.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .run/Build APWorld.run.xml diff --git a/.run/Build APWorld.run.xml b/.run/Build APWorld.run.xml new file mode 100644 index 000000000000..db6a305e7bb3 --- /dev/null +++ b/.run/Build APWorld.run.xml @@ -0,0 +1,24 @@ + + + + + From f8f30f41b76435c20040087fbd23d9e0ea2c14e7 Mon Sep 17 00:00:00 2001 From: Katelyn Gigante Date: Sun, 5 Oct 2025 14:30:52 +1100 Subject: [PATCH 0791/1218] Launcher: Newly installed custom worlds are not relative #4989 Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> --- worlds/LauncherComponents.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/LauncherComponents.py b/worlds/LauncherComponents.py index 527208ccff98..be58b048e5b5 100644 --- a/worlds/LauncherComponents.py +++ b/worlds/LauncherComponents.py @@ -180,7 +180,7 @@ def _install_apworld(apworld_src: str = "") -> Optional[Tuple[pathlib.Path, path if found_already_loaded and is_kivy_running(): raise Exception(f"Installed APWorld successfully, but '{module_name}' is already loaded, " "so a Launcher restart is required to use the new installation.") - world_source = worlds.WorldSource(str(target), is_zip=True) + world_source = worlds.WorldSource(str(target), is_zip=True, relative=False) bisect.insort(worlds.world_sources, world_source) world_source.load() From a2460b7fe717f1dd41f8449dfa26015190d3f2c7 Mon Sep 17 00:00:00 2001 From: James White Date: Sun, 5 Oct 2025 04:33:52 +0100 Subject: [PATCH 0792/1218] Pokemon RB: Add client tracking for tracker relevant events (#5495) * Pokemon RB: Add client tracking for tracker relevant events * Pokemon RB: Use list for tracker events * Pokemon RB: Use correct bill event * Pokemon RB: Add champion event tracking --- worlds/pokemon_rb/client.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/worlds/pokemon_rb/client.py b/worlds/pokemon_rb/client.py index 2eb56f539840..36db00b3a884 100644 --- a/worlds/pokemon_rb/client.py +++ b/worlds/pokemon_rb/client.py @@ -36,6 +36,26 @@ "CrashCheck4": (0x16DD, 1), } +TRACKER_EVENT_FLAGS = [ + 0x77, # EVENT_BEAT_BROCK + 0xbf, # EVENT_BEAT_MISTY + 0x167, # EVENT_BEAT_LT_SURGE + 0x1a9, # EVENT_BEAT_ERIKA + 0x259, # EVENT_BEAT_KOGA + 0x361, # EVENT_BEAT_SABRINA + 0x299, # EVENT_BEAT_BLAINE + 0x51, # EVENT_BEAT_VIRIDIAN_GYM_GIOVANNI + + 0x38, # EVENT_OAK_GOT_PARCEL + 0x525, # EVENT_BEAT_ROUTE22_RIVAL_1ST_BATTLE + 0x117, # EVENT_RESCUED_MR_FUJI + 0x55c, # EVENT_GOT_SS_TICKET + 0x78f, # EVENT_BEAT_SILPH_CO_GIOVANNI + 0x901, # EVENT_BEAT_CHAMPION_RIVAL +] + +assert len(TRACKER_EVENT_FLAGS) <= 32 + location_map = {"Rod": {}, "EventFlag": {}, "Missable": {}, "Hidden": {}, "list": {}, "DexSanityFlag": {}} location_bytes_bits = {} for location in location_data: @@ -61,6 +81,7 @@ def __init__(self): super().__init__() self.auto_hints = set() self.locations_array = None + self.tracker_bitfield = 0 self.disconnect_pending = False self.set_deathlink = False self.banking_command = None @@ -236,6 +257,22 @@ async def game_watcher(self, ctx): await ctx.send_msgs([{"cmd": "Bounce", "slots": [ctx.slot], "data": {"currentMap": data["CurrentMap"][0]}}]) self.current_map = data["CurrentMap"][0] + # TRACKER + tracker_bitfield = 0 + for i, flag in enumerate(TRACKER_EVENT_FLAGS): + if data["EventFlag"][flag // 8] & (1 << (flag % 8)): + tracker_bitfield |= 1 << i + + if tracker_bitfield != self.tracker_bitfield: + await ctx.send_msgs([{ + "cmd": "Set", + "key": f"pokemon_rb_events_{ctx.team}_{ctx.slot}", + "default": 0, + "want_reply": False, + "operations": [{"operation": "or", "value": tracker_bitfield}], + }]) + self.tracker_bitfield = tracker_bitfield + # VICTORY if data["EventFlag"][280] & 1 and not ctx.finished_game: From f07fea2771c2fe5092570e9da417c163fe6f87bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bolduc?= <16137441+Jouramie@users.noreply.github.com> Date: Sat, 4 Oct 2025 23:39:30 -0400 Subject: [PATCH 0793/1218] CommonClient: Move command marker to last_autofillable_command (#4907) * handle autocomplete command when press question * fix test * add docstring to get_input_text_from_response * fix line lenght --- Utils.py | 11 ++++++++++- kvui.py | 6 +++--- test/general/test_client_server_interaction.py | 8 ++++---- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Utils.py b/Utils.py index a14e737c28d0..08e5dba8cdb8 100644 --- a/Utils.py +++ b/Utils.py @@ -721,13 +721,22 @@ def get_intended_text(input_text: str, possible_answers) -> typing.Tuple[str, bo def get_input_text_from_response(text: str, command: str) -> typing.Optional[str]: + """ + Parses the response text from `get_intended_text` to find the suggested input and autocomplete the command in + arguments with it. + + :param text: The response text from `get_intended_text`. + :param command: The command to which the input text should be added. Must contain the prefix used by the command + (`!` or `/`). + :return: The command with the suggested input text appended, or None if no suggestion was found. + """ if "did you mean " in text: for question in ("Didn't find something that closely matches", "Too many close matches"): if text.startswith(question): name = get_text_between(text, "did you mean '", "'? (") - return f"!{command} {name}" + return f"{command} {name}" elif text.startswith("Missing: "): return text.replace("Missing: ", "!hint_location ") return None diff --git a/kvui.py b/kvui.py index 013cd3360939..86297c497940 100644 --- a/kvui.py +++ b/kvui.py @@ -838,15 +838,15 @@ def __init__(self, ctx: context_type): self.log_panels: typing.Dict[str, Widget] = {} # keep track of last used command to autofill on click - self.last_autofillable_command = "hint" - autofillable_commands = ("hint_location", "hint", "getitem") + self.last_autofillable_command = "!hint" + autofillable_commands = ("!hint_location", "!hint", "!getitem") original_say = ctx.on_user_say def intercept_say(text): text = original_say(text) if text: for command in autofillable_commands: - if text.startswith("!" + command): + if text.startswith(command): self.last_autofillable_command = command break return text diff --git a/test/general/test_client_server_interaction.py b/test/general/test_client_server_interaction.py index 17de91517409..209ef92a1e08 100644 --- a/test/general/test_client_server_interaction.py +++ b/test/general/test_client_server_interaction.py @@ -6,9 +6,9 @@ class TestClient(unittest.TestCase): def test_autofill_hint_from_fuzzy_hint(self) -> None: tests = ( - ("item", ["item1", "item2"]), # Multiple close matches - ("itm", ["item1", "item21"]), # No close match, multiple option - ("item", ["item1"]), # No close match, single option + ("item", ["item1", "item2"]), # Multiple close matches + ("itm", ["item1", "item21"]), # No close match, multiple option + ("item", ["item1"]), # No close match, single option ("item", ["\"item\" 'item' (item)"]), # Testing different special characters ) @@ -16,7 +16,7 @@ def test_autofill_hint_from_fuzzy_hint(self) -> None: item_name, usable, response = get_intended_text(input_text, possible_answers) self.assertFalse(usable, "This test must be updated, it seems get_fuzzy_results behavior changed") - hint_command = get_input_text_from_response(response, "hint") + hint_command = get_input_text_from_response(response, "!hint") self.assertIsNotNone(hint_command, "The response to fuzzy hints is no longer recognized by the hint autofill") self.assertEqual(hint_command, f"!hint {item_name}", From adb5a7d632f3b61d4ee005baec31aa2ed2a4a841 Mon Sep 17 00:00:00 2001 From: PoryGone <98504756+PoryGone@users.noreply.github.com> Date: Sun, 5 Oct 2025 00:47:01 -0400 Subject: [PATCH 0794/1218] SA2B, DKC3, SMW, Celeste 64, Celeste (Open World): Manifest manifests --- worlds/celeste64/LICENSE | 27 +++++++++++++++++++++ worlds/celeste64/archipelago.json | 6 +++++ worlds/celeste_open_world/LICENSE | 27 +++++++++++++++++++++ worlds/celeste_open_world/archipelago.json | 6 +++++ worlds/dkc3/LICENSE | 27 +++++++++++++++++++++ worlds/dkc3/archipelago.json | 6 +++++ worlds/sa2b/LICENSE | 28 ++++++++++++++++++++++ worlds/sa2b/archipelago.json | 6 +++++ worlds/smw/LICENSE | 28 ++++++++++++++++++++++ worlds/smw/archipelago.json | 6 +++++ 10 files changed, 167 insertions(+) create mode 100644 worlds/celeste64/LICENSE create mode 100644 worlds/celeste64/archipelago.json create mode 100644 worlds/celeste_open_world/LICENSE create mode 100644 worlds/celeste_open_world/archipelago.json create mode 100644 worlds/dkc3/LICENSE create mode 100644 worlds/dkc3/archipelago.json create mode 100644 worlds/sa2b/LICENSE create mode 100644 worlds/sa2b/archipelago.json create mode 100644 worlds/smw/LICENSE create mode 100644 worlds/smw/archipelago.json diff --git a/worlds/celeste64/LICENSE b/worlds/celeste64/LICENSE new file mode 100644 index 000000000000..733fbe11ed97 --- /dev/null +++ b/worlds/celeste64/LICENSE @@ -0,0 +1,27 @@ +Modified MIT License + +Copyright (c) 2025 PoryGone + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, and/or distribute copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +No copy or substantial portion of the Software shall be sublicensed or relicensed +without the express written permission of the copyright holder(s) + +No copy or substantial portion of the Software shall be sold without the express +written permission of the copyright holder(s) + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/worlds/celeste64/archipelago.json b/worlds/celeste64/archipelago.json new file mode 100644 index 000000000000..fdc1c98e43bd --- /dev/null +++ b/worlds/celeste64/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Celeste 64", + "authors": [ "PoryGone" ], + "minimum_ap_version": "0.6.3", + "world_version": "1.3.1" +} \ No newline at end of file diff --git a/worlds/celeste_open_world/LICENSE b/worlds/celeste_open_world/LICENSE new file mode 100644 index 000000000000..733fbe11ed97 --- /dev/null +++ b/worlds/celeste_open_world/LICENSE @@ -0,0 +1,27 @@ +Modified MIT License + +Copyright (c) 2025 PoryGone + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, and/or distribute copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +No copy or substantial portion of the Software shall be sublicensed or relicensed +without the express written permission of the copyright holder(s) + +No copy or substantial portion of the Software shall be sold without the express +written permission of the copyright holder(s) + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/worlds/celeste_open_world/archipelago.json b/worlds/celeste_open_world/archipelago.json new file mode 100644 index 000000000000..12e1f288a4f7 --- /dev/null +++ b/worlds/celeste_open_world/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Celeste (Open World)", + "authors": [ "PoryGone" ], + "minimum_ap_version": "0.6.3", + "world_version": "1.0.5" +} \ No newline at end of file diff --git a/worlds/dkc3/LICENSE b/worlds/dkc3/LICENSE new file mode 100644 index 000000000000..733fbe11ed97 --- /dev/null +++ b/worlds/dkc3/LICENSE @@ -0,0 +1,27 @@ +Modified MIT License + +Copyright (c) 2025 PoryGone + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, and/or distribute copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +No copy or substantial portion of the Software shall be sublicensed or relicensed +without the express written permission of the copyright holder(s) + +No copy or substantial portion of the Software shall be sold without the express +written permission of the copyright holder(s) + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/worlds/dkc3/archipelago.json b/worlds/dkc3/archipelago.json new file mode 100644 index 000000000000..1d3880a2e719 --- /dev/null +++ b/worlds/dkc3/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Donkey Kong Country 3", + "authors": [ "PoryGone" ], + "minimum_ap_version": "0.6.3", + "world_version": "1.1.0" +} \ No newline at end of file diff --git a/worlds/sa2b/LICENSE b/worlds/sa2b/LICENSE new file mode 100644 index 000000000000..a3648a0f5d19 --- /dev/null +++ b/worlds/sa2b/LICENSE @@ -0,0 +1,28 @@ +Modified MIT License + +Copyright (c) 2025 PoryGone +Copyright (c) 2025 RaspberrySpaceJam + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, and/or distribute copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +No copy or substantial portion of the Software shall be sublicensed or relicensed +without the express written permission of the copyright holder(s) + +No copy or substantial portion of the Software shall be sold without the express +written permission of the copyright holder(s) + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/worlds/sa2b/archipelago.json b/worlds/sa2b/archipelago.json new file mode 100644 index 000000000000..8d69868792e6 --- /dev/null +++ b/worlds/sa2b/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Sonic Adventure 2 Battle", + "authors": [ "PoryGone", "RaspberrySpaceJam" ], + "minimum_ap_version": "0.6.3", + "world_version": "2.4.2" +} \ No newline at end of file diff --git a/worlds/smw/LICENSE b/worlds/smw/LICENSE new file mode 100644 index 000000000000..cf087c45fe9f --- /dev/null +++ b/worlds/smw/LICENSE @@ -0,0 +1,28 @@ +Modified MIT License + +Copyright (c) 2025 PoryGone +Copyright (c) 2025 lx5 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, and/or distribute copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +No copy or substantial portion of the Software shall be sublicensed or relicensed +without the express written permission of the copyright holder(s) + +No copy or substantial portion of the Software shall be sold without the express +written permission of the copyright holder(s) + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/worlds/smw/archipelago.json b/worlds/smw/archipelago.json new file mode 100644 index 000000000000..b3d25d484797 --- /dev/null +++ b/worlds/smw/archipelago.json @@ -0,0 +1,6 @@ +{ + "game": "Super Mario World", + "authors": [ "PoryGone", "lx5" ], + "minimum_ap_version": "0.6.3", + "world_version": "2.1.1" +} \ No newline at end of file From 8decde03704e779cb5e3ae70b96984f099bc4b65 Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Sun, 5 Oct 2025 14:07:12 +0100 Subject: [PATCH 0795/1218] Core: Don't waste swaps by swapping two copies of the same item (#5516) There is a limit to the number of times an item can be swapped to prevent swapping going on potentially forever. Swapping an item with a copy of itself is assumed to be a pointless swap, and was wasting possible swaps in cases where there were multiple copies of an item being placed. This swapping behaviour was noticed from debugging solo LADX generations that was wasting swaps by swapping copies of the same item. This patch adds a check that if the placed_item and item_to_place are equal, then the location is skipped and no attempt to swap is made. If worlds do intend to have seemingly equal items to actually have different logical behaviour, those worlds should override __eq__ on their Item subclasses so that the item instances are not considered equal. Generally, fill_restrictive should only be used with progression items, so it is assumed that swapping won't have to deal with multiple copies of an item where some copies are progression and some are not. This is relevant because Item.__eq__ only compares .name and .player. --- Fill.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Fill.py b/Fill.py index 7a079fbc82db..48ed7253d9d1 100644 --- a/Fill.py +++ b/Fill.py @@ -129,6 +129,10 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati for i, location in enumerate(placements)) for (i, location, unsafe) in swap_attempts: placed_item = location.item + if item_to_place == placed_item: + # The number of allowed swaps is limited, so do not allow a swap of an item with a copy of + # itself. + continue # Unplaceable items can sometimes be swapped infinitely. Limit the # number of times we will swap an individual item to prevent this swap_count = swapped_items[placed_item.player, placed_item.name, unsafe] From fd879408f3e419677f23697a1be550cc173e4cb4 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Sun, 5 Oct 2025 09:38:57 -0400 Subject: [PATCH 0796/1218] WebHost: Improve user friendliness of generation failure webpage (#4964) * Improve user friendliness of generation failure webpage. * Add details to other render for seedError.html. * Refactor css to avoid !important tags. * Update WebHostLib/static/styles/themes/ocean-island.css Co-authored-by: qwint * Update WebHostLib/generate.py Co-authored-by: qwint * use f words * small refactor * Update WebHostLib/generate.py Co-authored-by: qwint * Fix whitespace. * Update one new use of seedError template for pickling errors. --------- Co-authored-by: qwint --- WebHostLib/generate.py | 32 +++++++++++++++---- .../static/styles/themes/ocean-island.css | 10 ++++++ WebHostLib/static/styles/waitSeed.css | 4 +++ WebHostLib/templates/seedError.html | 12 ++++--- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/WebHostLib/generate.py b/WebHostLib/generate.py index 6ca8c1c8a15f..a5147f66844d 100644 --- a/WebHostLib/generate.py +++ b/WebHostLib/generate.py @@ -72,6 +72,10 @@ def generate(race=False): return render_template("generate.html", race=race, version=__version__) +def format_exception(e: BaseException) -> str: + return f"{e.__class__.__name__}: {e}" + + def start_generation(options: dict[str, dict | str], meta: dict[str, Any]): results, gen_options = roll_options(options, set(meta["plando_options"])) @@ -92,7 +96,11 @@ def start_generation(options: dict[str, dict | str], meta: dict[str, Any]): except PicklingError as e: from .autolauncher import handle_generation_failure handle_generation_failure(e) - return render_template("seedError.html", seed_error=("PicklingError: " + str(e))) + meta["error"] = format_exception(e) + if e.__cause__: + meta["source"] = format_exception(e.__cause__) + details = json.dumps(meta, indent=4).strip() + return render_template("seedError.html", seed_error=meta["error"], details=details) commit() @@ -104,7 +112,11 @@ def start_generation(options: dict[str, dict | str], meta: dict[str, Any]): except BaseException as e: from .autolauncher import handle_generation_failure handle_generation_failure(e) - return render_template("seedError.html", seed_error=(e.__class__.__name__ + ": " + str(e))) + meta["error"] = format_exception(e) + if e.__cause__: + meta["source"] = format_exception(e.__cause__) + details = json.dumps(meta, indent=4).strip() + return render_template("seedError.html", seed_error=meta["error"], details=details) return redirect(url_for("view_seed", seed=seed_id)) @@ -175,9 +187,11 @@ def task(): if gen is not None: gen.state = STATE_ERROR meta = json.loads(gen.meta) - meta["error"] = ( - "Allowed time for Generation exceeded, please consider generating locally instead. " + - e.__class__.__name__ + ": " + str(e)) + meta["error"] = ("Allowed time for Generation exceeded, " + + "please consider generating locally instead. " + + format_exception(e)) + if e.__cause__: + meta["source"] = format_exception(e.__cause__) gen.meta = json.dumps(meta) commit() except BaseException as e: @@ -187,7 +201,9 @@ def task(): if gen is not None: gen.state = STATE_ERROR meta = json.loads(gen.meta) - meta["error"] = (e.__class__.__name__ + ": " + str(e)) + meta["error"] = format_exception(e) + if e.__cause__: + meta["source"] = format_exception(e.__cause__) gen.meta = json.dumps(meta) commit() raise @@ -204,7 +220,9 @@ def wait_seed(seed: UUID): if not generation: return "Generation not found." elif generation.state == STATE_ERROR: - return render_template("seedError.html", seed_error=generation.meta) + meta = json.loads(generation.meta) + details = json.dumps(meta, indent=4).strip() + return render_template("seedError.html", seed_error=meta["error"], details=details) return render_template("waitSeed.html", seed_id=seed_id) diff --git a/WebHostLib/static/styles/themes/ocean-island.css b/WebHostLib/static/styles/themes/ocean-island.css index 2b45fb9d167c..3216e5e3e2df 100644 --- a/WebHostLib/static/styles/themes/ocean-island.css +++ b/WebHostLib/static/styles/themes/ocean-island.css @@ -72,3 +72,13 @@ code{ padding-right: 0.25rem; color: #000000; } + +code.grassy { + background-color: #b5e9a4; + border: 1px solid #2a6c2f; + white-space: preserve; + text-align: left; + display: block; + font-size: 14px; + line-height: 20px; +} diff --git a/WebHostLib/static/styles/waitSeed.css b/WebHostLib/static/styles/waitSeed.css index 85d281b20dff..0b4e4c328c34 100644 --- a/WebHostLib/static/styles/waitSeed.css +++ b/WebHostLib/static/styles/waitSeed.css @@ -13,3 +13,7 @@ min-height: 360px; text-align: center; } + +h2, h4 { + color: #ffffff; +} diff --git a/WebHostLib/templates/seedError.html b/WebHostLib/templates/seedError.html index a5eec1a4cc53..6953eef60828 100644 --- a/WebHostLib/templates/seedError.html +++ b/WebHostLib/templates/seedError.html @@ -4,16 +4,20 @@ {% block head %} Generation failed, please retry. - + {% endblock %} {% block body %} {% include 'header/oceanIslandHeader.html' %}
    -

    Generation failed

    -

    please retry

    - {{ seed_error }} +

    Generation Failed

    +

    Please try again!

    +

    {{ seed_error }}

    +

    More details:

    +

    + {{ details }} +

    {% endblock %} From 60617c682e5ac5fe0d02600b585a248a126661b9 Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Sun, 5 Oct 2025 19:05:52 +0000 Subject: [PATCH 0797/1218] WebHost: fix log fetching extra characters when there is non-ascii (#5515) --- WebHostLib/misc.py | 8 ++++---- WebHostLib/templates/hostRoom.html | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/WebHostLib/misc.py b/WebHostLib/misc.py index b3088267792f..b56b11dd6f47 100644 --- a/WebHostLib/misc.py +++ b/WebHostLib/misc.py @@ -271,9 +271,9 @@ def host_room(room: UUID): or "Discordbot" in request.user_agent.string or not any(browser_token in request.user_agent.string for browser_token in browser_tokens)) - def get_log(max_size: int = 0 if automated else 1024000) -> str: + def get_log(max_size: int = 0 if automated else 1024000) -> Tuple[str, int]: if max_size == 0: - return "…" + return "…", 0 try: with open(os.path.join("logs", str(room.id) + ".txt"), "rb") as log: raw_size = 0 @@ -284,9 +284,9 @@ def get_log(max_size: int = 0 if automated else 1024000) -> str: break raw_size += len(block) fragments.append(block.decode("utf-8")) - return "".join(fragments) + return "".join(fragments), raw_size except FileNotFoundError: - return "" + return "", 0 return render_template("hostRoom.html", room=room, should_refresh=should_refresh, get_log=get_log) diff --git a/WebHostLib/templates/hostRoom.html b/WebHostLib/templates/hostRoom.html index c5996d181ee0..10ff5e84470a 100644 --- a/WebHostLib/templates/hostRoom.html +++ b/WebHostLib/templates/hostRoom.html @@ -58,8 +58,7 @@ Open Log File...
    - {% set log = get_log() -%} - {%- set log_len = log | length - 1 if log.endswith("…") else log | length -%} + {% set log, log_len = get_log() -%}
    {{ log }}

    X?{kJ@$Fj8%cu@+Ts? zvW{r7_v^~RD>^SAw0CMFtV0)xJc*TZEX)3nDC=jOjYvyOw3x0@#&KR8I~7l^jT2+_ z=shl&BL=)RJZJ<(9V>OK-uBvI$PEuCU0=EcvePGYgP!%-gO+P3(rb*ZsUY4b*T{Bg zM^(@FTHQ^PJ>=od*pwj>SJCz#FmTdoUViWZXA^qBwzVhe8PeV5+c0WAM>T3i5=!82 z+(4)p=}^5&5Pk5HU_5o%O)ITxLpNeU1k_qObKh^}iTAwoHokjj^d0Dcx_yhP6%+`Z8J1Pz}_4o4?NqpaE;ADuX!6ChVF7u!E*>K@ri zw0ig*ay6ov|FzC%U>j$Zcy`h(IHE~JxE*xnw_%oDrNzDRe4!R`t&NDxcVaHnwT=)# zKD{Y@-?Gt@*-R1PkWU^75yC3vfC; zz+oJ|G~arBYP^o8u2o?l`&oYQ94F2fZvnhh`WkQtO{$i8!;v~|p<($!?VRf{eodNV zs1hEE(5ou5ujTo2Gx%sN0Eekng$`=C&%l#dEoX}2!Svf2{9;$q7`jaw_qpN>_`3uA zb`)D#*o$?`1DZXDd2RnWI;9@0`r;0bR}MjIpXfL8D`d`?ynis2+`x0Pb1iW{5H`<7 z&bHhuBYU~_|5&+We`h=0#xz2<`UlzB%F#(q_yHPS*aNji{`pQS>rG@ zOI#vZMBu*228vdOaa;?0^%R6EF3743-+eb-sX7dvKvOF!84eYwn(`@TEsZ2@%J^Nc zNk4kd@M9#Tr_G?IhiIr_@dH2DBcs!dhkz?0F*e4;dF9Ten8koXl9pf#e~jrI!RHN6 zZSq$?_^=+X`diboA|iw5`KE5mx>8|g!?v{@-2K$Byox77iK&GWri+`8zbRM5DUm9( znjUQ3!Q$u09R&6V_$IhQjJ@uwR`bJyx!So^ldbi=^C_LMgP&hOO(po2%Sf=g>v_cq z9W_1mDdK~kyeEQ_-* z!7_ACWu)s7O@%0={!+Fu!DLL^!)VWi%9HHhQ0i1*f!X;-JJ+P{#@~IJanSDabJPKu z;#3eF_$WID*6V;OvVFk`*=?<3NDAs-g|O8YCKddY>SVb>F}DrmC`iEasLOs82yS>r z9#n?aZ`KwcP16*i6LMaT6Syo&G}HY>1O{=@!WVgo_HkOop`!F@l}P)WPZl*N7TfiG zq8`N`7gBm6Uu-Z?N&grKIz1AaxcqA4kv|cVT3o{Imvm-tJ;eq8l@*kH)Oha2nUIWJY>=2>aDUzxyy|lN8HL;E zmKNc(bVWuoM*|J{bhOzAbXB_$Bh==x%WPNxq`lN~E>~%Roe~_(C$4<5E|MLV=-m*+ zn@lL7sCZ62SMrloff4tadyr}__D0KJFCiaFYcQT-SSWKMR0)`kVw4hgn?6P+1V}sD zb^aj0jF6dLi8m_yinzk|P^?t@geb9G5-lxky zAlv0IBjce*FVJqKKv$3MmxnR_$@c4SE=;E%#4wi*gr3(dvr~(}HZ7Ci9^_rkV*Spl zm5B^y@}RC|Ep;1f6`R~PEEgUqJl3ibvK~<-t4IUi_y=4UqJeiOY$YPtd+jPIJlSOUvp$G#6wA7klb>E(M|h$gR9!xq=2M+t+t?jl-Cb)Y#`Y05MsKB&n8Gpq-^Z@1}i?5 zsMw)MIJFKnn*Q}p!S2j6EH#)N1W`da?!gVZX5j!5G(!Xkqp!Q8!d|5F7|x8XhWlau zSTx^0J6OM^XBzj>YxQ)7g3fDw!3;pq4%}{VWLd4yck}C1T;zR}f9p42+Vj+xsBj?Qp{Lb-9EcO_Fs>tJ<3-^~Vs zqSqt0T${>@7UCg?Q-dm4!~s7(tg1M{1A#r#LjW!=bU#9WKRip3AHBvg*qNjo>=2hF zPC>=B|NeO)fe#p+hNdOoBlm!H3m6z{Fa~gd ztza${a~#D$NxnFY+rDrtqzgiZv2UYEhhv~IB5_PS%dTjDqx#GSyLet-I<`>uJrT<4 zcO1qx;Y;#s@;$$?w|)Yf%1K&&xKu0|N?1{*wJGY}_J_A%t_!aPi!5I5fC?#@cf=3BU=b>L`uirNdyN+Z6qbS}0# zG1<|LF8xt80SjXe0;K~l&v9$M8?I;sSOp7gpi^C8Mjl9wuF&LI@$KwR{<$~msc<_W z^nH?2d}4s-Da`8#E-ldr+};dagq1;MBEWoi0zpPt(=`iHV)>J)VhuJQlKPqdgWor8fN^UXk1la2OB|S2{%{;G&8Rjit!P+?NjcG z0u@b#T?j{xt%*HdG;c^;+?e~W37?yrYiKegw8AW!vbb+%)!8G)b1}L|{Jw(xrdF?s z3i9soPY;1NZsKeJI;mW+dpL9;VoCl)K5mHwbvwfHO<)#}Vi2YB5MpmQtP<$grjT%p zU*^xfQ=Wr6da&vDU);;u{@gcY+cNpyTF3(^W!$6(+3t_AfxF_@mDJJ0r1B$&XTtWr zbCfQ`PjRxNcm0TFGWR6ADkd?r-e#vA)jI1U^JS_!PSMQ!#<)rPjrLg7f6uEGHB#~Q z#+q3CaqvCHyo1N$?{r{@r^t@v>N$j;>hAXAIJE)C6>ReNFOE%i1E!!G9b3Pq&NmS-_j-Sht@X2w5+vF!4?4+&C%4fP;UHT2^E^gVnBmpH51 zS!$Y3-P|ZK-P$^v)ZhD04efAhtkJyry#XO>>-b}jXJ?onRu;=0?&ncR2caE(fEtI? zd%gdG(WlTJs^!o9?x_K(t6a#J;0o9z8)gbkqdxrtJLy{kbQ1FCiS%ZZ8>f9>9tfRd zkoCzp_%=s-?6DL-CGn_%`#{&E2gQ!abSfty5Z&p3SW?Sxez- z#*Id~WNip})fg!7(MOa-oLNMifb-|RW5mx&I0>S8o?$fnnpj+h#PUXCo^~c%HK1G)3f!QY1Uvg=sil3M_2PT?IFe(!W$x% zV7~1D4zVH)z}yDg?r~|zty@h~Z%>D#f!j1S->=-wS<|Kg@1BG0iCwjm)oL8VHi*S@ z2XhPf0=KsT?9}LbvM3{th~Xk*f==m3;vNJ4!Jjes0_py-rQIst@R!K#cNqSS{)H_M z`fmoSZ4e~H7{j!a~lhK>MszWpfvG6g7~cEJ!?I>yN6}X;so^43EsDM6Ta|_(XYfQ z6g6NBiw59aU2hD9v;$!5RD15O30%4-Sz{Sl*-C(%KOQypVK4@J@NoQ{CM9p?bPq~{ zxvhTMY9#?O;AhdA3*CO)hyecnFRcTQv9-U)dJXOPt#pmKhIGcK+tpdUS_HEENK!(^ z>b9l%Hfkt2l(!_?<=Az*(3KGdQz(7__uI4*f&6Gxjv}h>2CE#~c zD^h2I-~>cx-uV;v1J}`IErVJ5^!E&G7bTla0@dVQo#DNm+Mdp+_VOs5KS_R3ibBS6&l5ZRnl5EUoYzHRHOzCZ4+`Rpt&-f$TelTb6{T+W zSn3)|OZx2#ukRC4-dVT5XqZyjA-Aw0+dFwbjCXp)rGbQezb!BhLHyK|qxS8?TjiqK zyPkWdbhSTS1j;-B4L0YgXr$QnL>lmt+SuKcj48k*f#s-ZXuB?hsxx22(EZ23EQVhj zd?;g8%_M82R|*rITFOhJZ$AMO=4^EWeQ#C%7o;EHH_p@BTS1=W!d?##9mvWt8-7<4 z`GbRl%JuKxfF31N%&pM*)-Jm4w^s%(KenyP;C@t&df}9{!`#}Yk;`X-YNmh}f7|Iu z6=zR3Ytw2B+qw9Bx34SF-nGvLPCtsTHBQ*D#j;;A(D`Uc9B}^FRsHy@MQbBB(Lx|U z8C{(@ilJ~@BXvVe2L~eVg7XcxQ|yQrq*8g*AUz*V zHcu8+v08U^NcGcFI-Av6eaz<0EauXC{OwM{w_1fV^LX0&=Gp?Vml4T9nZR%<))D=8 z1|9W7A)^%8F)e{nHkG5CetmuSUnwJ3}D&Zr$9=&CSD=Q9ho->7_Q{9xekB%-A&Af?zNX<%5=S$C8U+rGHkaT>Kg9r)0 zOM&?tI1%-5E*UnjhNRmuSFmAQ93xM49n=W@V=`448i1=nLgbc%0+}K!yUAW8hNE;u zxV;gxR>#$UVjzQOd4mCzH&<2Q18blK@1$BIvKGJ1_faYkzg;HaFTa35ma(1&p1dKy zmY09gu)y%ruf39nWaDRFrLWkdO7}7eU)e4my!Xk& z?4KG)RQT9Xvx<8n!VGZp^}+Kf0bH%H3zjhQ%KT_`RM-uHo~1&2DwY=+EC-5;op3s` z3@11D8LUZbX)Zx#@r6=;qXQ zAsJ-_aa|H<_{Nr2pPcCqgMWgNkbf^MSk9j@?k+Saa^Ypv7ny!o#QpXs(~y7Pq=>cU_ILi<5XA3EP?Z|8wVKK*WWZF>xM^SI~TM%2f8%T~@cgc#p44(D;N29KScUV%Xd7CQ)@j+Dtp7DM@jb&)DZz! z9GsO66nVvBQ@g$5}Dj%4IumLGOEc*dbbB9=CxP+t%dQ? zC!1_;Sf7@9-p!M~WP%WX$Jv*$VA9v-tHklf3{8?L{%!m-LyT+?xl@!75S!3N;S=D%f8M`&gC_F- z$s)09jf6#~x0S;0SLxs3%CPEDAg*xIaeJKb7UwCZ7llzcChYS~SvT`Xa?ME0c(uX3 zyICTi(W?@?nG*ji`d0+&^%ILx1@Guq+|whPQKZy6!q&cYuZvM4S6hFHtT z+&=xBilZ4PVc@@9xKHJ`(Fm0M8qM zXCq}fn_=C;KO@{YkdQtH%}H0Vf^;E6_EC^~cQcjy7iZ9EA}{8%kH`$~&-=@2NiWf4u!4#p?4or4)k|UxjU= z)h}^{4#3_&pEPHnrqugXEfX*ut(nE?YH z6YpUJm6zet!ZEf!E9ajW0DIv9Nl4S!+voeT@!b?7^B;_ooTInfK}Y`tVWCg=fGK3` zD*+wp9Q`hbB2%b6RG`d`!Ksc85A+>C@1j~Lto(1lxt_OU$w$6L16Fi~!dI&AL}84c zzp`&O0Tfdj=ya$fme`0H-00 zJ9l;SGkZD!>di=!9H0D`A288PXGjMDfc=vc&Q05<0tt9tI5=d;x+J_9GBOGP!Tc-- zLMsKYgL!lQ`}R&xzBU5yd) zxN`pk2EfL9)Kz%EruF<<`oG~A11&)ePe^PwM&HPb10=baqFo9VYRCRnkcK(`qtZ#B zXin1OvylhiGFI0w^9nu9R*^U6a_`Dvt5n`4SQ_S)DHBN}Xg zrd0J>p#ujte-K5>Kk?go0Q388@jf0!zVtxi}CxG}V%5rgspmi1`r z6&}-i=kB22X8N%8+s{lUtmt2i@p~WITC0Oe^TGC`?tM(fw=|6?czZuyJGx6q(iZq_s=Qr z05$?mJyaXPPoz&=uI|K2Q{&_bTbVxS=PxPf-HWP$eLvWHWl(G%XjDs6o z0jj8!f3Cz(lmrMSCfqXOg2_aF^PrwZIoy64((o#{#)@fTMhk7}sXBUg23mJx^f?^kq%Gau{$_L@sJ|yl z#4GQpvuT^9qrFA53p-De=}dEK?~LY#=?rhwK9oI7RiX7GhO=)>5T-Ru7_?uV-`gd3a0}75m$L;BVEAPdbsC;>dx9XWj27s|mZYN0Km2 z+5Ds5P=h_=Kq2AB3?iYq&1au`ReBaF`BK$Z6?CPi_9g~`bSkPbI_LD$?J- zs5ompRL~5D$-W2v-Ne2VBq8-2dL7IcF?D=1q&*zK*$#(oe4}v7OHCB#FtLOK) z+=D%G8-7tSF_JV!{}hpvB+sXl^f*mdJ9YML;(F~cOb%>U$e5__Ezhktb3Gv6HzL05 z8EL5R8!7Cf@34YEVR@%9YG_Q8E+1_bgpv~&!K!j%tUc~@b01#^2*sR9;G|RnaV8=h z9v+2K(AMFeVgELUvt4DQJ>ODB==(6D@3rr%h9a$~*8IgRu#a0tdb719<_L*S6p(yL zdfLjWY!eTCX7?PPxd*>!!0twsSZd9mGK$oP&=?1kdgPoghY)WI7nVd>IX5p&W1+?-c=^^jb>NbV{<>0*XW7gVdg6V_!F2YiNJHItTfqC3a ziq{tZtz^vRl?S%wQ-@6UTX_S9_mDew?lxwDTXJ`V5P)0sFXLs=rg5uE6F0W#SZ3#aLAfZO{cY za10W?Z9NN7B}(pbQ`{uViF^pL$KVO9UhW4@{BxfN6;!N z!&rP8N4dQKlPdr(hq8IL$5Td_^kcf-&;8=x)JqP7 z^-~flRc7CWkS)s4O+C_GP1qtOV97YBC-d6^H)U=X+xB9iuuox%fg;#D? zHa>H#?B0EqfI=2+w-;k5iHw-?Pe#X|-IyU_-?}~*q969th_0D58?0YGj@pnp&7x@E zFEPqNQ&Ti>i`BUgE`%7Y3(}b;W_>l*teuN&a65O&!MzvewDN-OlX;RIW^wO?ezy1P z?QYwM2|b=#&VMultD6 z;Ts2?8|_-Rq%wZ@cz*Ysex;p+)qa_u5DS;@JS0KbO=xHj^)lAn@{^cN_soX1LslP~ zxbzh#Y(M#DA)nkHQ)PXU9|;!tE0BF@XA-G377C>N!^Cg^e2{)az`P;s{d98pYDG>4 z^MO3N9#qcqyP3WoY{lz3yPjnlRsz6`Gq)&G2>t{yQVL(weO28Zlx@}gZj&UXqp(;f zT=HBSJpnC%s3^nZqxRR>w>E_c2t`4hl;Mdf(B4c{{15w|H9=f<9B_>zTT(} zNY=jX#OVFjZ3t#M+9J$9yQnjly4G-SHq~RsDtoCm&yd5)ZufL^bMs0luFG~VkmjO{ zR(*P8s7SC#pW4oh?R=5TJY9t;2g-+R;O`7yyMewn42h{xYAMRwUz2{6BTBm=iHt%X z-Mmepwq^XUDFb-3T7WBjbQlLGz<-gCf4mx{^Le~29UAE<3TxuAt?d%@OD~vj37&ha zsbHLED)>oXi*{r7H8c=;1`fCl)tlZ}wEP>_5ff89dxT8hS9jR^>2k-5NH72lzPa47 z8l23YIZ|_RuS#G~qqX_`!{yQ3L_s|~I-8y7p#Gsg$3BIr61it4|Av!~@zWl|=tTIO zv5sPr!77V3`=_L@SfU8cAeJj@+Pm(dolL?33_;{I#NbVIv6C>h*k#c|djT~(LOM%J znEOLlQt_Df2z9X}JO6Ss*-c>qm^cOB8m2YaH2hXn@n*teO3lIja)3)Cb@EpHftmfJ9T8${9{EQ8Ix|5vDb$8tZoC2>jS0sNyle^R>7v zg-H#2asQ+Sjf{^-Xb2VA1&{q~POQ<$k25{Sn{9U23{~BZpSG37eNMU)o133%y$6{a1#6 zFf6K~KOgwbIuJ!2z&J~W>k}5(gUtOkM$$l-zy$qm;#=QIy~#k-E#3M|rl=Ehc%vTR zuqGPj9CPk?gy2lM!F;2nn*GezNJRnVhet4@H;!5C(F;Yj#ih5Z;?>SD)#u$>y<2M0B9^`FJ=j4Fnr&I$PDRsqwLedJqf(=?&Q ztV(D}`h9?HKaHl3)*hJh*yISWx;(ElJzZ`i+S`=eKyq3^8A~9%xe3JY- zTbiD|lxvXYanHNamfPnAiNveAD)ytj1gY&=Q%B-O1r}is2B-G1S)Dv6P7swt>tV+@ zr3c z_E!s~*4yB<6+Op89H2qv1;T+A<5ePquT^3ZBMs3jHMCL#2V#le&-poP(;P>Bt*}&Q>pldS( z$lzgLL7)hJ>Ly5-xhagAPq3^*bm|ok;*bRp%J8EuQPQq1kg8r2MHrb96y^?V@sXgW zLQ0DA_EAN_bI{j1m?_!Q7D(|MfWucDV{kmx?K-mK5zVVmPSAw8mFfGDV4*^M-mZV2 z3iL=DWLLjE1Hs4lH(5H-{Nez_t;y@Mq z5~FU4j6gMyWmkdC_o>l;((Gh<()~m??CjXcJ6`{M!B&;O&e*C_Vxn7i#bMEs8+Heg zGp1w%x0%jxIFx_`+@Od{CA5DhdXFS(6!r;JLX?Mq;p}dOiCmaLb~l0iB{Aqbt@L37 z#cy4(&%57S?+mdW*LkExPmlde>?PE*pZz;@09{3OaX|5@Sw1_B2O0gobbSX(O{kv`r)!H zrLXrF9+rE9GSTwsS7}fE5H@A>jOQZharhJ+B|Me7A&H>g`A6}SmOSj4NwzT&jR?&IKSv<>#ip&o22Y5~)d zSEeb3{mGhWv3%Eot3-KKU+sn|_NB(WSQX!hv^19=FnF55Vd_8%5Nzf^fgUr0N(fZ@ z@&6h$zmfW?=sr<1RpE^3ITj{Ghm1l5Y!_}uF!6zt(GG4zR^9Nw(uE0dE!7E80S}`g z*oz}7OG)&h=_?d}1n|AmF-5Cy|xQ$IgNd=|E4SU0w2n7OG+rx)1nAdqa81p6|rioFb2C&EWB3nLAZNajK=*? z6~8^toeTRbW^kMj>uk^gsD0LIQH3kFdTe-+PL*HE=n38>5XJ=gkT09TTw;IzQilFZ zjBpkl3Qe!RoE)s@C{W zE>cbpdWkDGs}JSdYa`)%+ltEe6wfDnOnB;c+X#njNiMKa*0%8yY%jVnS1`E?gSzqT z^FtCf}@qVBkzLbTBM8&aT`*~T@&S?u3J!z#pnY`p@>!5nVXtY~p( z;2bmtWts86P{OR#C1n{|8jpxNGx`E;C#Osm0Wtjua<;vtmtLL6%(bq?=_xk%MV8%Fjw5n#eabP{$%{a)pLX0#`4>i?2wK*VwAeey9f zJa%4a1W27Qy=3UY?y-R67ub9<%+7K)H%O0YZZ)vO@@-}OmmDX@;{r`J{j;xD!6&7U59P2=FhmJ<7o5D7aylp~6nkN}CC9xoU~qvLEN(`zLhZJ&G>S zJ1$dP&}t)qBGVQ`R9NO8deA_^h0>k}Y!^Tdgo^DhsDNK(?Nx~^ST)M=qh-EUI2E}0 zZqt{}#bYg=h=w@^xqLs?h5mt3x3vn*rx`wUR85FpK0EV;#dS_l){`bsI6QAYOopD-c$E;c__xh#Q)gYkl+2H?$TDu(X0e?opdMbg8T3c##S!{; zCHfrsoyIe~@jRy;LQ?DXVy?|M_}?(BYNyv^+kr$4SoVm2s;43(k_2bFR(rux+ID@Z z`(SvcU5?Nz^W|TVM=ddcxe12d)qe&(w!{EBJHwFqqPNmpIl@PznJDMFKb8WKEt5!R zcoP1lFn#z%N2!iR^;wEBM|?Ni-oqH67U4WhE0O*yz$DXD99Onyeu84g?blJAU09^a zTS+dX?Q^f#u7=-UQ_x*I?_+|z-zWvT=(JN6{{KN$`T-28!2hy_U|6;O>*f;-s*dxj zTn~N-0eWFzwOwuc-_lr*f^CW>Bd3q>R*Z6;M56NR_}bdvKY4~uotb?a1|&yOtf7u* z0f#KO!%p3CcBm`>oD?3IPGx{A!BnFU1MHj$(HFQ%n6Nbrf@SwSC+l||BIm+NKHiRq zQhI>b159=&NMNfzdS=IYz?eAAFoS~lFy-##3I%+C_ybxtc5{jgPGm8FzVRV@!+)~? zrCVm>%Rl{z1feG<$Bm_&Kd1yff;kQ_+)(Fyg3dtg zAGbCxKTA6Cl%5o7TpA-)ikR#X!Tc>h`02cy$+My_+_1r$Z6xDhg5vWDObBnOyQs&Y zqQ1b$#V!DqPxOlk-KoR+g6W#)!sbco8L=u=-6A>lS z?BR?ku$UJHPq4)}z=1W;e~8$p@FTO9EHY+H!dVK=P5N!p_@tBJce2qThG7z(?B__0 zIw)2l)F;vfYpN2LEYAQ{NMsdkC*5gQO5LAkI+$0ib@C7~90QKMIjEe$N@gjUP%9>{ ztykxB)nj9wxgn*0iktiNEUtk+_Pp!zf7p7*=uEy~dpLMv+qRR5Gf5^kC$?=nPi)(^ zZF6EL6Whte)<3^{?}zup`?1gJbyl6~s?*(7d++0haTnpWi^3|az8jon4YaQclpBLCtejQr5D>wY8x)M0+ zq+{@Z@CkCAF>{l@XqC=7J{+qd4~%t1FStj9sV!yD-CAo`w94~=jf5%JQCB?5J)$QdH_lB$JQ=fp#JE^ zpEF92*8MHtSvA_DtG^Z<`OD$`tvRhM?`A?p*Cdj6(D;)2>xC2Ofbc6-L(wNv-r@Jy zy8hsCrAdk-0nNAr586xc36nGalBKsiO zxcjNEu6;6gvatw+Fw$3oPj>vA)vJ>O2i@H%*4{1yP$r_)PPIsV+<13ia|^J)*GXTy ztf`tSC~7A0M@$R&*Ja{DZF2gB)4Y>%dZaeuA{FDa=P{40<$9Fr+4%LH?hHkq(C5Yb z^}_h}V9Yp!-y^70K8J7f8L6e?&N^MTfwz*eourt%=eL6^FP1VGt4t4B+VtCZe%$0-D6~zoTNmg9`?L7+yI4vWh9tg)YqIB__tm z&1g0Baj0eg7_Mv8(J+-UC5X#OaPX~n-MiSsi=4yIw` zYVa{q4?WVAyf)Q0Q|KjKU6%oja+NWe6J;8AlM)0o=^eYgnPw2pPBEID=x1n0X{GM( zds8KJ18OP28tDGvX_|A~!4iIl3>^BXGaL5liAtj_oxky(2G%>rcvtlQTiZD^vTii# zM_oh3KDz$gz&~umnfWYkVc%K}6H((guQRrOaa-KK>Z*4lOAAkMR6L}8*=z623!dhjq}!QsM0 zTG9+)(^O=CmS^lT>#!;>%)|-F7CSj8|32APsWzi9F&{I`QgN3{XYQ$pzc>@rT36w( zm!zWLxGBOue92)nrqMOCr~k%f^xm~N(T}=7O=%=8>w6PMi7wpjBwyU1V&M&}U-IG7 z0blpFGgRm@%GdQF)*m$3MiP@NF-t*@SKyOF5#GkeDolp>fyXxDK7R#Fmu>~3Z|!@# ze8lKUl@3?qhInwXqOkv5a#aWV>JF&ooef*Vn1ek*~S+(ra0> z^$;+&)vyLXhm3uhx=THHd||S)Wh&?}0gv}#kKGj$FtZQbxQd(%H*;CZmmG`gFGh>n ztnp6e-O&fv#(nop0#V~FmFfna5rS&!CbqgznQ$W@8hF-6RHo5H**Ah4=_MREOo2(J zG7E5s#*-TS3-r260x_{4@3?xK$!#c5Wk}g~-vSM~F=kw2l?b?1f#!0W82-YCz*OK8 zd@@sDio8y6(XZOyQWQz#Or#_}WjGa<#3j!^Up)jHhDk>Yrx4C+$KENKU$i8O9UeCG zL>(2QL<`qcIDMOoFrz9~oeaT}L1J_Tp@SHq)zn(^b^bV)|_pe6`fs9Itp7Obc&ChlupXST&zjGRUtg?!nNnh|>4-2#_ za-58WD<_6SewJty%Q$vXr4W^{W~Y5U1?!?ka?EnD;CbaRs7Zb*2{jaDH~D1++nT)M znQkqN$BINO)DS6=l1py?;}wDW(fErztuykcv7er8GQ_o|J8uxCLCAH}%2ELR=r z$u%P7&HKyItV=CEpB&(DGC4m@rY`?cXSDKK-d&im;i>eyH2DFQNl>-KiRMiQ=WTAH z&Sgm-*^Jt@lQVU{=|_G051=Adzq^lnk#u`e8$jC2Wly^g1UjM* z`xuz95k3k}T4sq()LpNQWN)xrEe2P#`jP5y3x<`bmjRi&K?gug?Xw08L;wG|4I~vM z5)7@?&IZgK2{;K40y0(pKk^$O?pc>Qf_4Wj7%7*{-JK4ZC4y_Dr5btEnpmJ0vWB(( zn4*niq>+Z5>y#3);4vYrgH>W##cZzG!t1~0g}*U4%i3>fo+sU{Ia+zGx-H%fTt^Z` zB9iFhtQ?>QHsP<&&o|wpPlRTp>p91l*XOdnm$wtZQ9)#zJED-&KnCB-8#;m1Gz$5D zMe;2Rr8l~-;2X#`M1=Yy$S_y#XDNf%zwHr5VrWKE2>03TXrmY!YdX{rpx34+^AH8K zbe#gEFr~y55DQ7azneoRVZM*HP&$G=n$O}6COsEO0j%F-pfzQmDufcxXmKue>{m}( z9WrYIRjO$j1wwm*>d#jVYWAu&@l527GyWwBU9n;F9KpM_W8j&LnTwvdY<6s%St^La z6O`z*e)8Dh_BRlAB8H#{vNMYW9;1v1KR+!2A8uPpH8Lkpu0HcqT6MIl_mHE7k?_|2 zHrBQU;KUa4j{`XHCSCX|n&T~LwaY3xOU`qE9xI3=a1`Su`y^OS==2RSd9)~coM15L zlb4>ZX-;^Bn3I~Jw%P5dN>{{Ay7fam_gdM~no37f_se1J-zU@@St<)Tr-dwg;w>`< zH_HR_Qdi=?)|th=9=w{n9;M?c>bn{>ZKAV;f;9{#Y%GU<4x|30E7NcUVsONih-%LO z>5R9{_o-Gi(0^(;!%bzK$j)N0n%Xik0{aARt`0}!DTP7Ds^QJ zvfd!7=dMOmH`L*puhw2=i@E!C72Kg zzl|pI?}-DZSE=3B^yO?_Txv+a5m*l4-84?@0qcl>KRUDR5606Y{_09cmPHVF37Xck zh>H11TZ@{U^g^E#PTgHG1<43T_rMJL8lm@<20gZEtb^qbd6w1d$Q-plKwqs!-J5bz z$?zKJ%{haV=-_$Te#N@q4KF9A)x_MD`Vcx=5^^?Nr6rZQvhnaRn)yx*-^&}UPx6i# z`F;YAKP#LZt@e!3ef4%ZR2(IbGCpr9QSe{J+QU zjPSe%^-4;yw+a)wsMbVi*Fh*60P9}ADo$Q`c(T5;(U+ZxlHK@*=kk+gO_VD$N>e?F z=P>p(s$eZo2y7#P+j0`|3|PopN6P+uJ;KZ}2lbT@%2A9O@Y%wbtX3spu3zN)uz)%A zL7x{(QAJBE?E=`wfM!<`p2lR~4x?$YGjm}*>!MutuJ6e@F$D1#>s6L2kb~HF4Z44e zYfX=ZgtMF2^7Z-@9y04YCH(6Uv)FfE^Ql@2-j7HK>u;l-8{1e5xm=Zi(4_j)v7)Is z(6yI6FV~qLovGs#;#Z_K&R*g@?eVrmimwpaw5NSuUo&#T`>U(-;etI*ZE<$%CJmg_}h#K zgB`@xN)w?W8QpcnA#+Uqp(`t`BnPwQg&yrBdt@xoCJBB6Q%Z`h3z~01Wl3kjWv0st zEhM>EvRaGx^?&-5Ubw$y=%OJ}4-KM$gm9N{@rB78(pRCdei*cdaDl0A8=MjC@&Y( zF_vRXi;+Jz$a19OeCAgG5{mO9I{YK?EROFRj7x7K@NwRZ>QOtZHN=d{Ly14t0|uS*!j|VmIntdL zhaEY3jf+zuf-uL1^5CZzixPu;?!zIBl^=nct`VzVt09y3Rwf{O)dkGiN8#IJslNA z8$ZYBWhrUQ+mFiw6HW4WTBY#;_oPh8Rp|}N%x6@)vkPn|JjH_&&}8@v7|a_ll)b*w zn~3QK|Flk6JNm%HJ*KwOr*KgW31%TN?vOivd^c|M>)s zk^^LQX5*=^cBC&x5Ae+bv359L*!0;!6>GD3GvOt-?-Ef!O- zvHsR6xY#kq!$5}w zxznyY_5HE$y60CH4T=YP!&B~*()gOAW%XsvN9)Q_`2a<$~Dc^H(X>yNq%=6wX1;VZ-S@q z^u$h15#Y~ae;ED7+B2=)3>$>TlHG3aX!j2~0yRHkbH2V`g^&`scZcWnD~DD4UKLiC z!ry-t;Rf1)Qw@Fp;rZc1S@_ig_?)_KllzkcnI(awSoX>mHaXb#%}oWI-2_`T@l7qC zFv)5dZc>+=)NK1NJRL|sDm&~+bK?XYrDJ*2w=Ri2id-4CrST7jGCJ!69+xTEAq73Y z(B4Sb%37Cu3_@9;Zh6{iM$Q0H_1x*{1H5gGaPVK`spl<%m^b_Jd8A_{Q01D^(+(4| zqk zW*;y(@?gFyb!W~vhY?})(jz5_T^TH%bKm&_@xhwjSaS$0O(EA+2#_uy`fv`qNOury z#?n&UmY3oY-BX3bH*gT*jm3eD@KmddQ(b8}xt7Sla1LB+6kPGfsI1ap@zL>k6l(){ z0om7-B@P8;mz;)tm1NM}Id~8jz@{!^=ab`155~P?bJ#_U;!J-7a$;+N>FjSbTeHm9 z3l<5lva14v7Mo#Hp1nhasT0K=uGD>fbm&odep_scI@tm%0yAt^xA9sZSNcAc&nvAS zF0S(5UqjY%!|qd>PlyGx=bgH=DOu&r)G%o(wsdpW*WYnb(PwY)pP=qrKf+|p1pTwk zOVYCV^H=HB4pu~556O$NxA#|e?WhU(xGp}fVPJrv-8BE=>%@24^09WD@J0CKtnEUK zK2Q2%E1Y)thb1Rvcmk+T*34b1xsJSAW7_?VR4syPaCl6)Mx~UJW)!b~`+5m~H1IGs z6l_94u4NPPaEFum%B&9Ty5ygEI!#J(c2wYeJMGQTLw04X=rIA0H7e;I2g^Ef4Rjm6 zb{a@;mOzM&H8Lrm343;1eNs}BzJ}$F|IawDD&ZP!MuXajenDxGw(V7Ko{*@KD%J)3 z0aY8%?U8(Bp@#`*TZ4P0Y8kXsmg6W`L6~NCv-YmjbabB2B-Q6ho?E|{F1*X4cbCn~ z)Yqv7rhTkpe}*Ym+}zgZ$Xla6z2nG zCzVT=`fClgH&Wj1JT`Fni?@dFqNnwps{hbn*DQA^(i}v4mOK22`WcKRAOg-R8pfaK z%7R>rk(wSz&$gbR@Njll3v!e49|7Sfp>j{_H|*d7G<8S{fDN3qZs>%WFhgf7hDP@% zUW+yU;Uy48AJGu1l46~NkLT9hxt@OJII6-oco4KRgu+GQu={Ig+FuEgSb=K*A{;zI zU@wXbqW8?Pb=^iSwNm?E#bNjUsVuk$P)VBjo@rFv)$gvUeFc`yHvnasY17;nXiVfX_EH#77>011uH` z#QL&KSxMB{V2R#(6=A9!eddDB2nE)h2{~GAi>FSS3SC)?PW?tCC=uP+SX=-cVsGsY zAm}ziOeITL3tb647>UbSAxv4!W2$5%S;9{3C@9Jh-h zKQ{^1I4+cM{7K$E=WWiinuZ9`Q$Oz(G(_vTOH>_1Z^mFzH&JR?s6T~j%X1wQ}sJ*H;mnliZ19=TY9BRxnszl~_qZX44!fO1L`9uLj*cDC2LAELs>;)k*Vh_ZOb|}frV4^1MVpqO=J2MRw zu;w@;TFAt<&ym&W@KPG!ulE3hJ;Q5GxjYQG6%>F1VrKlaFhIq zf~GXlZOTvRK~BX`0em|nI(}e)ggFXGVp{vpsY5KOUgHiL$N7V13_5pJCVb9Tx_J5$|AerE@W)9bO z&W2)59mGml`mG5q-=8~gwXc*?eUrfmfIM=I*U{Q>Y&w=yZYm#74oUF~-WM#rM@}KD z*rB|2Ia#50pF4-w{aU+zPcaMEQ9}-Cv-FdLx5&lb=`6Af!(axP^R0@Gx6@G+G!l+V z2_IrLnp~82aa>v%KDPLYpoVa|eNHql$VBKf6N>OrxfBP1IKF9}i*b6-$-Btiz}L08 zo1GJ1=ODKss&R zpxjT99QYDTiM)NJ#U6`GLqxPe0sE{*KBImTxESZg_gBFA-6ii~#6olxqUf^UzK~v5 zM2GrEDMgfL`$VO1sQ*1z!o4Hw;4-J{Fg9kRCC$JKRv@)KqS7!nd=)_Y8*TK11m;%~ z7&|BF2E0t21kLbZq^OyU1m+a>;FxBYk)_{M^^Tu4GW_%8OXfp~cP@9c6fg*F+f@}y zj&O?MPl=lz=3qp7e~vdRR<7G5>A$q*@=P$>#QVWBNcXTdA9`tkkgrd*zCVE@4Ns4%K=~{`5DUS4ocV$>77xHjZ8mH)Nq9_JDSt6S1Jdt^>u?o6hExkn ziHal2+{XSXP?|0#UJQ}Z14K@<=+N#rOU-MCBUT(SV!H9hI)RbY`H^}5QZi={D_6SF zODP@rJH2d6rny|D==9D%q-4Cu8&iT-D(KuA`x+1uW7@V-`s=LN_(!z#MY%u1U6(hH zP9#2pky=AlLVcYVk}%<#QPiLl4_qj(CVr5-bL{yJ$|nkGCRc_ zjJ!gFLr%AO!p){)f9vyb`Bc7#RLG#SjM)wG#Xjlgfy@s24)-@gbJx9PmG|uOn^wac z!E`gdr;|b{rmYO`sj>p_i@i!lpud@)>Iyt>lk82JY82WFFX6k%39n?-C<@J_Vp?>% z+m}US(o%7QUR5Kk1|E(%tqT6dkP0h#mTw>XM0=N2MAv2S#KaxlKGQ3x7>ZcljgdXb%jJ^=GEQI`2Ok;eFNAMxC7e@k$C9_@x z@-Ocu4{_2C+(_!6$1xA`o=d8dvurJ zg#}@3anvV4uBpZ798Q2kr}CGzmT@QDFI9i*vnvAG1ChYXnQg(rjGdoFABKc&$eCG{ zPDi=Ed13NJTmDp~Y#4g96MDM?SF10nuo?hbU;-pAw2Nape==n+W|hEoNK^@B+b$CcAhN%4k-~icl_s?>$s=>x`j;`CABE(SB{1B2LNCZk@(AB_ zhV_>=ntZA)MKl|8g0ZryjAhBe^CW-q_Jt%zKkaMQy}F?;zvaUvWJ^$jWJxdojnYOs z17@PAFf1pYzn3I}FS-v79s6u1%0Spoov2@xtkKKVquH6SF*y-~WrC8RliC>(z9uYP zG48Cs8#&dqZ3Qvv;fD)p`GT9I-@5Hk`+&MJRKDWXf>d9f5z z@v)6e%s3xnz&(sD7bIY*d~qqL>IJJ6qZS+z$xnTmLL=K+guD~YG*nOh4{Ej5MiVdy zD!lz&GdKJH)Xb;8X{#8i-CNQ7e;wvAZQ{X(v7u*&1VGpQFE@2z-N4BNt%hU+np$bZ z2h;P_$Y_(A)>A98!AOCwFwmXCim_LGpIfD-^(zFU+&e2ez67@u!#P;G$Gz{2-44-u z;_tV!V2uaU(f892_qNVSpI~T)U67p2Mq$sK_z&h%`&#^#b6h79`<_nx%4~S%|1x|z z2_C>kDcCF}FWFKx$3l5uSG31$dCqiZH0{kL$2u+!pM;}EukVPy7Voss9My2A%oqj}W9s5ixV!bLfbYD&f!DG8S3 zH6v6PVX`T+F^EYiQK-TYX`M|=xh^PfOSvr%?5VKfp_c-6=pd9bSW!YQHLcX9xFL(S zrjR=jWVu*YgGc_ow5PaRWcFQ%xSEn?UKJ37>sAVyl~rC|YM7m5_MX2q-!}*IEu4($ zExv0`O46F&A9iry6Um4!hu}Y=|o8G{cvF zc)dly%8PHh_vn*;*(g?jn^nc8MG4w{PkO16LAlXgj=v;gCrS8mY^tLai=eRlYkw~Cm(z?>PY7KzbH}rwSvl|bLQb;{i{i)->@|b z*kD4e&{y#21%f8kvXaP-Li1FG{dF$?y`Gr7+rKwC*5LHI&1*l@-|s>_eXSs4=%P*8 zULWc+^dj4(dN1?&sJmN=hYz?o7WC0Ha+Kr>YvFAMUmPHGofk9Nv|g=~?zf-VK^f56 ztIKo7580$V)W@M!*xuO385M28AFAbmfXMP7UV3(HPWWor7?;K9W2ll_^v-Gyv~2Ro zQ!7z~g}?wAfl3jvYzCNpS^rUTVXV_i~f0e)3#7(&@m4)B_K}YDs7-~5H_A{7Y z$ZZP~rWSf~8YIOi!Ork&S-R4NwZywS@v>Z3GlBo*5 zyc(-4stNZGPcs>pxpZOCw3Gv#(VU7vcwxzg#_U}F&U_17;cMl&rn2@xN8Dx2NW%tD z1Ps~83@3cnc2zjs?nUktRB#WVwol;XYWLA(r{391^J3-}Yc&6x|F?IiCzUJ5MNF+Z zD;eT7za!z=3I|fg&1tA@j45@*H|b1{uy(MU3s&c1e_)F9nSF%Ogqn1bX(QxIh396r z$sYVUH=*`OxjkEalbsLr5$`k@TTBQ^T<+$V?wD5FVj)XsilZY7843`y)gOR!OcXN1 zpJC*Fz|kv*f{23WjhP4ctJgoG91m6L_9bG7Ze}Onu%<_V45{5r)c+uw9V~nL`gQEx z&+Nz{`fWgf#o%7`(s+|>8-?!r)f*{fi6!{om^!=V+Xcrzcur{-BXE$(Eo{-o3 z_P+mSY=2*zh?kq2+ZR~04`)ZQ->Z2mxV*L>lMDdI%k#8YLH&N{vP-{ztec zQmwN$ee#8$5E!9@nMh6IG@)@U{|*y7kC6lj8I6jJPlpgR4TJD@_;Z+KM^Ms==|Sr> zc|TA9|><^8vWzw=@cHnTH9>)HzCSsGhj+i*XjK`Jw4wbdeOVE!YN>K5KL*MEu5Hb0ME)hzhfFJEUQ^7C=)9c%O`K>7P%RFKGm0 zj(`Ri#7=itX8{sHVjr#yhRj9ng!5X!m%tF-@th)bUR(IT80dt(K|F)`v%W?co7eio z2?$nZ$|_{a8y|q4!DAyZM?xcl{@nWtiG|h)2>|eM9ncL4Z-Y+90eK49hD!0#{v56f zYzZWYfQq_Hts1&a^0EpJ9BYf@1VC>ffVlpUI9m1;g)TdH<5oMC3a9IQ|j-Kex*M7h=vm}xQ#a= zP8>T(X#3OUB5vZ`meK*n>QOnoIi5`hM&t+joz6Vy@FWWsPB2`_9Al!xpr|l?Biqk$LkfRjo3}68_Al+3 zUenCm!){olhXPv=nn8oij~~H_czvoFjg-1*-oWxcs@NfK)hhJmA!^(Sr#eR=97NWC zpeNHL`G@2O9(`fb;$*S4$CN2l2aalK53F^E5N>~7lF7tI7AEiX%}A!*ofObq9G1Z; zg?6gIgMy<1!w;#%v8xG^>`jjs_ft9=TB8_o(&ZNJ59P)e6<@JA&Eu6S8+rQJAOB=M zn*+0{sHTIw0=Y4V{oUOuoQD8rwv*VpP`MSLP3@fciLfIAsEAwU*w;=+v$O{P>R6m^ zE&uUWbm$|b6nh2Ub?4U2P#LC*GiX05OLa-UK+Z?s0324-Q@)U%A8aGy3_1vX9Xkme z&7kQ+en`?_^qitw;jZTngQWd{FCE(~_X9#5mbr(oP6QpkqrDkG^r?f95lWE0?9v+* z^yV5>r7e!FofKD4G-4J(yO&E86%B+Z9G16MMRym%Bx9OYr;g;dp(BQ;sWTF<*cds*Q8E1wkniXKP3 zlwo%9dQeJtTnr`8a`%cWfkceu&ID{}9Rp_I?GO6R;X#!V0mu#9toeePkVk-zFJ>Xg zL!mKgpF}#s;$xEi7RV#?OlS@MQs;nluMU)ZxZ+(9iNR}{w5vKXAS6ywlQWLMPKicj1G=eQHNJR}=BP>FauWV=wbt^#_wJ@9>#H(enI!oygD>knUg zgMDRC@U7ZSb}Qy~z9q2dA%8*frZ(9cp|_J<(`0(bb4C)I>i6Q)QdPCzM~Lb<<_e221B2OAu0Ge13If!~SZSGkY z_1)h7dN&J6yvZjDnP)fG?fDq;ON2b8(dcuqqRV0Em)SeoKHWgX&(g!}{aagK)lcHq zOnYD;bBKjw#JvriFt1tP?5?#zm>xVfC$E0j&J=SoY)SEP%tWjK8=5CxWHm2U6svxg zjqnM}K|em9TT~UFnvny+EAGDNDm?ZmA+vMiqdy7m#td}&K<><^c?;((BR_NO=Vh;{ z7XxpE!qcXYJ|SPPNz01k%E}Or&QIsq&m&;1rxyb&vXC4;-`YP}2T@CIU5(NZi zQ8Hy|t*M;9BgmAkY0a30#ZNA23}s8~qC`tGYvWD`*vnaPRB*8hZqwnhpo5wUD}N0b z$_5>##RIS-@({hyQ8p0@(`VO*xX-gyjY2UXg-Ezpknv*(MTl6eG=WUk?M5a}X$z6n?+(@Vxf@trd0?=3bPFD)9UXshM(# z>xXA*^SgYD?^|kl@Sbd6_GAmqp9#Jlp*Qc+J&easxK%jINfyYDkFJ~TQk=411((3|m(*ZtfR z=yslL3Z&N*l5c44CF0;dvFAotBnMQM!Al>YCYLc_Sr)LMqJI&mC*E+Db;^Th<^CJ- z?8rclu<(K>0GbNSuvb0wbfdkUCH?c10=}blcbhU=3MJJ%kWTsNheiHJ z6a{5HQ9u;iGlcuLsV^`-c5h0OFQlSJ=UeNBdvR;81uD@$g{329dT6+>ajQP-&PD1e zp5&l~D94K;h%Rlg9R4yBnGo?fzyun~rDzad+xkwisHWb?&$9+d@*{J$bJ@N_S!Ez4 zO5wwt()sGNwjYtMf8CEo!19GBXZi29GeR*I4Im%0Vnt?Et_vPrPnfmH!9oj#A{7pB zn+I6`j2bjndb`Bs{4`Y<>|x0#YVd}bRCCcz<@pCbHRMKY$|jwPbXZ1gPsrcS^VHzFwE=dwZbVB?8PtpXZKgZi?tKX@JMvA9JI(e1V{qM4`?%%ok1_qfm$>gZ5=pT8Zdqq^(WA4!c5hmKD(BlD> zQk2_$Zld1?TO=BGo1UH7v$((Gx?9q{jJZP)AEc+RJm>wfmNbpShb*g-e;^$a> zhd>rM@H=yMZ245HT<4l+%dLvnzfHhVXdzkT>$oblb_#RSG0xlwxgsVq(a`(eUQizC zm)L`Oq-y-`*${q3@rdbdJ6-&B>iNzl_U$Dn#5MI$oH!?Fm#3`SyTAIqu|nL?2P`0hWqq3tgF^BPW=`A>E)&@&tNO5IV!&7W zr*oQ@D($`hE)5EZXDDty!B}a^jCTXLr4iE9^WQ zNG1Q&@LU}IpRM+s$kYowTL*EnF!yt2@%&Xbf?9{d<5a0#Fr7#9P(uW@!Q~F&Gd+RY zgsaq|!3A$?8psuUV|@-eX(iUHSCpQ17Jjc$vWl~2>z8uKMRkTcaP_j3fS;UQz&+-; zpl!hKfNKMf*?!*it}j+sCuJ7G8%iC$fPwbN`U8U#)KAVOgwnm9<34;^A)A47{6}EYmJxdy|1{m0k!cJm<~OSr|Z z0YWapgqAVM<=nPwaL&k?FU@?VYJpNBui+`TKM-v15MY!gf~VT8qb-g4!$*v?rQl^P zSe!y+8u-U}_@#H47CS?pI>*e_9k5PN%sZ3xxM`;Y)LL;k1kD*#>w7~njpy?xwB*WevocLP*si>S$5yz&s z90nNEaTjdHTqQ?Fy`WzH1XgdsJ;?|d%hu5yHf!FIGV%051JCWrC)%Z|= zH4yGAKlF6}1M*&v;=U8(rAq>n?2}{xs`uyD^S{8c&DbkhqAd!d_>-+}n4FDvAnq+tzKZxF-;=XEjU_%^N(;3V2_1zURWqc1I93; z2b+qQ9QOCe2;N0jl(G;@8%?wXJFo;Jk$5Q%k^qMaQHe}rLI#U%H&ZnabJySQ8Ulq!i?=Jsc{<2sF5+rtsLXKb zyV=nrYY}K5U@W)g-F0w2S*~KV5xqPz*6k5y{(9CT+UjTxT}p&`bO%=%20SMD{iF0lO0fp3WS-G*iFTCXFkWHbig~X~k3cIA2by1gb;Gm2J+&inR9G zQ{OvS>+Z@q2M1SvTi7(m7HE2Xi`o=N&o=%-Bf$F$;Q5&bOjt4;z+&JdDxIKM2^^yY z)kI@YYhq@X&iKT)Ft4bZn2`R>)we@|l{RJ#KYYwm8UkWzYSnIOqiUO3;;6K&Yg22WIB= z0SH<@TAWjQN=q>)h?vnxsal!JFlhax`LvUd zos4CP%p8V3nGgw$Dr>sTX%CojI`*!Ex7(4`qngwdo>owfz9o{Ry!+d3b5R&z)X!{- zo=Xurog5vs*X+em0WB^a^50->@UFL-LC=Lv^0yMJ=2ALZWEDOR@}<;J+4Sl~e7nBF zdxMMcwSRf*G#-3+uUOohY?37*F7DjsTFQJ?wbfCprr4I_QMD0`XT}Wi$G8jWx+e#N zwG1Ria_`c+HFwnDv^{i(&%f_~)zp8UDTeEwbZ?Nr+RqvS8mBj8@EXKTsm?dchi~R* zmV0n7tLhE0D9HG5kspdUaVUu3;9nfCB>t=; zM*4%3?pWG@lg5?(cC@Vr{qm8vRlC96CH@G`3zt9nHY=D~+_Sr9mw3n~odc;1)(u{x zuCb*n74>BFGbmruu8whbfs?1px6Q}!2j{oV*)z~Fcihg;!M>)@D%*cmR$M4C+7Cv5 zcHRThSDM48kpG?$yeR=fN1mm)mY=JQOSz#z7VsAho~9PLonfI`6&~1CJnX|1Q@s!W zauvM1E+Tcc<*mYwZtFwZ9V}6pFZC=>bBiviS*e(^YnCh|8frDS%5>8B7IW%Qx07Uk z`foY=A6R>4qtf-5cKVKCb!;s=zx&sxHv+W-@KFJO zNZS9FpQUG%mwPPf5Y<|CgwpE^G?cz}tJQ9eUUi>YY!L_H*U#WxI8E}?Ox?X8Jf;G5 zd~RUhvg+h>v==H~fJY_wQPs-Td*NBq2ikt=7)-#FcP8Z1jhI z=4Tj9!od_K7nNgf2s(^+6@ceuRG`vgiRc0N2Mr%Q{ zMX|Zb7-lRJvL42CKhN98ffwK?It6uwwY3Ch#_)7>heh(U1*~UTjRh4G!;hwje`Pz$ zr#a7H2trXVDT=$5@nKZ)WQ1hgK@j!oARr)MJa)`7&u4)nuslCGNm0Ge0N+4TIDb&b zkMehOV>KC|!|oL@Md#VCKsAk#&F?X1NF&R_ zouI4^KPuFmrRb|O8{}z*s&vwF+cL<70qxIDI+#FRmaAYd{H%@;2ym_=!L^1p$-?@GF27V%lkB#Rte;d^=hU-V8hA z=Woh3^P0esPZ??LCge%gv5_85`US_nrT&OA_w8e6P5vRe5D2bonjY#54>!<`t z!fsyZu#Fa&eBwbl5)!7L!N#3R&u;Si9t<*wWRovzD3Ayaa{-Vd3qnq}*th=7^{L;U z1u8lbup#pZhbXzUiqX>46M`g!RzhfS#1m&=VjjS;K;Jy^!K>r7f|8e5wVjqd@ zIfeW!1V3$3{H1(x^VI8qh;Tk!W1otgWsJw9Xqc8|RIpKy&oQLa*?cpAFJ?JByTNS0 z5OSp3wHTo&W$?hqZ2qT^(?&aL7@+{?6j(tV(8LA*6%94bLvCB>Tefqd*8??yH*(K2vyixRA^zY+0*?8{981NqOR+iGE{|P+z8tPge>sYQqJUP9_uV`Zjg6J0l4}% zgqm!MB)HxGAy{thka>QC#p2QovW^>mu_e@29SO10n>}=H_%e=+lDfW*Tkl(9@|d}a zs0#~c=*U};KIHM|^1SerfdNYts-e0WW6+K}UC0!~QkHyqUFbd5*8vE@wJR@?@p}|X z$kASN6m-A84R$z4VdW3{zemIldcbLlZ%=R0#`>hd_OK0!!r>xM`8SL3sM;v!xXzwf zl>5!eSjG>wrK7V=w+A2@GO06L<70U@NoFq?iBI7^m zaEZF3Oc9qH;>*+JczZB|98i&4Tf+AkE*2gFmlTg3ym6X5g&9L;pplt{XYITd4?-G(@cy z4;vh&8x`*~EJ}onh#(tA$zO%>WC;j7`8%&rmhMLSdmPnNt0~S0 zoi%v!JkrdqH-+LAPR5xEbY>$X0N`UkK8r?n#Sd)wTii!}1sq0)N#fTDT)mQDH`9>F z^-ofk;i^42{Iu-J@M00vf=XFY6t9KiDX^3m#1lh^Q2b?hKf52mp_e&$M*d>?%a>|Q z%?T=m@AKZQt}DJi)NXp1c6)EFp!NuH5>x&QJ7tBGaeNSCxJd*WXoS8XG>APsG%+00 za-uolMn4T*1yG9@5OTzi`nDJ0nqse#&eVye$v@R??oGWe!lTZJ98DFW)mA|I>2}R}PIM zpbmxZY|OvJB{2$I5QgF;aLHtpY9b05{@6Yqc1HNlXa-!WaX{+MB50^GCL^0?+7l1h zhX1233oLQJobX`V=xoAdlr^KTP||1*;rw5vm-0f3G#Wiu*jAq4?Jsflt+4b!wj;35^i>`imGnyw>2 zXChbgl0u$FUGP{;?ISFty5SS+Q>10mm5%%QmnW-9jD_eiPcxohUr&;e zBQBjmtL9@aEn()3bSBks)UTEVZ3 zgl$7iAj$-=&zGINdmhY5^tE=aq9gjwxshxhM<9$l&*K;Zo2wiDL#$T`Rb-s}5ezoL_5lJuZmUlI!z zg7*xFzzXI2??U_r^Vz*^CTtMI=@+JQ_I1XhCo z3*hV>>5QzO(<7<7j~9qgLhAE5_!;lc>(Kip8Hf}Bn<7E^&NVc|KO?n5KY)k zGH(bO|9>w6(`iH_Vl;ld-<(Fq({KSBiLtDFNg4!?0d2GU;p}lKa8tCb)9i+zx?;`Q z4wR7diuzwMGq~*u*2Z+6m4BROfJQ|<=cA5mk;hSrZGr{-*{#PyxnbV**y8XJN>r1i zoMM#Y5Mvg;;S)bOGn54}3a}N}#!=`}oSSHSCGkj`94cE1a|~ysVO#Fmicp08Vsc}F z7mwU}cKKVVgu75M9D zO`K9gC&2jtQL8Pr-|o)Wmt5I!z+`jp z7;F#0n8!Z_sGq=6C!>7CMs zKm?m;{!$AGO)HttN`_O;lm2og&5j(Zr8Y6;xjHn!*hisYoyM>JJd2TLO`?UKTyyu> zCrK&p?6M9T>40o$;y($N8oURs@Of^nx3;0zV>+5lq2Ry+pR5WQm6-0nQ3<&i6y_;c zMIrNuoKnuZkvx+c7a(3cjei~ENZHfa{T^po$< zKuIM4b5{4<4spP>+uI0v&8a_yNfk+4oAO&!l{>|7_BDc`k&XLkiy{f*9be87UR_4= z4fCgX#tG0ubD3npEqnQI%FDxGOf#}wq>3NaZqCYnxD?p9lE?kpVFy4{;8=7`r3g8@E z%hvOv+=w#|&#=az*4~~DNx^0n;bEqE6XVJu(gWIEK^Qd)FfH(+zg7p1_bIn!DQ*Ev% zAxwYa1^qQG?T>&cbf2$d+?$In( zb|0g#5Joof;~jtg)*QV?H~bW=FmtgKs0Y3nHXyq^lw`KN(TmTd_y#d~wcdElCae-r z>RaLfdH-n_qW$3XPrnK6byblcZI%$MIA|L8@+BS!kX2jtkLHIhmyg6Es<6je>H07x z1kD+E+#9q>Y+T3;Ujc+xq^)|UZFnbU8^(Yf6XzgaI>&D}Q%)1ar0i~+_CGKpR*~fW zFfyUH+UiIgz4)&ZPvS2Z?%lH6F5+3-EkyLE9;Wa@&;RJmHX%Uxe9xKdC#m}N2the~ z2Yt+@nV5fLPPr3!lco84!kGQ?I@MzM(|#pLNk`EfFT;qoIhVZ3Dvf#$BOO)TTMw$I zY>Zv*p1s-Sz9lR0wYq&>0~{556&O4RjsbrC0nC^KmlO&;?Smg~_W<9gj1RavD-j%2pONM9@}1_z&U+u>iqs$IqmOmn7*{&qZ*%5bC?~xY074G zaJir)m(MR{qZ)VY!Arn+yu&p=<{Qr{eDu*5D%&?e&0m<1KMqWp2UmviuZmhoB%T7E z&4Y`9=7<;>vwDS}Gb`QIaKv-bWa z@IWvy93WU4~I;xVc{f!0%Eb) z0cpvID_t_5(jL*raw#N}OQ^Q+H$%qd6`e*NPCXy^7`ddJ!xmw@b&3gbpHh>{sOnb; zy|)HB#|JttDupmh8w!AQqxBmKGPuu43PW4xt3zlInGiae6 zo&!lH__9}g_z{O3=PaYAGy!Q{X?K)Nv#APpJ{YNi+4 z7vAMQ05aAnXLC_?!xJ^>aJbCTZm3z9nU$b-9ZH}x=7oGQHXZ6U#{e*BsMCW)eFz8c zz9^q)jcoWrn9?7&tfr6jQ1OtVlzA92ldZ@zuF&S~mNG{yNnbnfUc?BZR33tY1jI~B z_h4vx4)))tD&5A1>zxWU16XC37)^T+*^L3&S7Imr(u$$1!kTQD6X7eoMrcFnBetFn zwIDT2n5_H_P=7wAJ!I)1t}*P2`oFlEg!;i>;9?PYnKymKqbw=8(8IqQf0&N5Kt#-M zUjFxx4|EJF0+HRBbT=o6tWPw_^o6D-jJk)BUbBe%T@E2a*0pVr!k+19IM2q=5P(~i z!JO}^-?LgQ_*)LUdR-1h(x(uR(C$C}&NRDkEi)@~MAmD9ipmjqN&cjVS110) zVJp00f9h63q+X3NA(C?K!sd-}0c*4dI?>Q(g|($n-%l^4`-mc2yJQtZ7uKc%@GN2S z4szlT9a|cHS1MKwvK)sIQ@~^f*FJW4(X#v+{yF&HQlaf`dPvRTzdjjN8@QDZJIv8P zK7kxp>}(*F3X;|;AX1}tkLqarbh%N!Vhu+?u+V0H5Eu2 zcPH9~p(#DAOf>9hMyN?5J{D;>m%{7ph{t!jVQK7z4>yZsWwO=hen0X3x7lxgVeitj zFp>>?)U420(#$z-Bd5JrCiJ8v;)_zOu8sI%%I9YU8nYa@qmBZEtn=zC8mCBzhWuP9 zOUAgHPEv@V#Z7dkr~p9PGh1{kFVa}PIQYi3Zj87A3uyl>yt(kU4RI+lNcmq%WRWhI zTN;?P@?4u$kDb=U&sk(#w&@_lScQrK9vjhzRPmy#{|EsT1Uq@3G|e4fxONv=riAgh9%^4!WXm$ zF5l^rn8@DIcV65*toDUB@r!Ff!Ha9m#Z)c`9)VavAMsPg^H-7yG{qEbyu#iq!xM*K zcA&Flq2dA|Zgd4|Rw;WC{(e^-V%EB5s$@>My<@UQsaggdCV9p<8+(G@O`%XLXLZ+altXrB|8|qnL8+ z_H-rFS&&A*al(>$Z7x|CB_9rH1^GKOk{H(X^OgRs2{w$@?pP{<)rr7soDb!{eEYTt zG=VO^WyBqvY{E{Hj93?O4W#=NsX^b1Q#C`Rdys^RX%JnPp2b;00!*nIKm=>||45q+ zPtQe30Nc4Oa`Pt$gnd*IYnhJ2&uXD>STRPNpNp2YP=i}Ceo6ZLMhPRN-#b;<=SthR zzFMcp5(oFccoLq-E7Y8`*Y|LbulsLj0>6t7bZK>P^qzFJqJdaFaU(I3P}-SBeZ{~$ zl-pQbo$F)~&j9^0KKfN99d4VDQBK3a+(cjGbNBUDO35!t-qH|YqN>Sn@)~-#yS*4x zSKy!96*mst09Cp*j5HHy#3F2{$8Cnsm)e!cSsm?jm&RqiM|F5aGyLoCsDxU{D?_-Y zyhBy^!?Y=X8Mb<*?rcVE8UgRN!_ja>~?I)VAA)TM6$+a2v&YP%l@lcF_Zap9U>l!J1p9O8wi9Icr`HBM_sWA+F{Kg ze@JnoZowemNfro6+10ZqJA?pUVmgy5Y$DNNmvNC$v^ZQsqpF)AC}u4+kZsy}A$r+e z6{yWK0aE2|ec<~pD{c($u`R{(t|5|DC7|H0`hI@VxNlhM^b;8mq;xJ;sqr?7!|BK5 z^MFdG|B*{&0k0|60`i$^N@}ubx+KH#$V9?mrw@WMl$F07`}MZ01HwVdH3-T@e$+L6 zl{>ec>?AT7C~2U@L%;!;F|w_yuD&PD`=bg{3LHA>X683ICv0P$>+^&5ZLQc z=)bW-n*9!u+kT4kSwHAw9ds}Breo_&OtAaD`RybCBKNB>zSh9yQ%*=ni*VI=fMM_+ z5U~w*$N%Y>by-FDZ&|H5bFKu7k}2By?|b&u{2a&FNh*K->;w;4vuc~1NwwZyc^8o< zUH;26&kFrsxi9A*^?g85!&sFgyqLej2tJ{5io_40xnrR^As*^Xyb}BCCW*;fbxTFI zULaAKe5!fOv`}mlh2F_DkpenluW_OY;K!{x)c__loS6dX{(@fIKFeP5ocFr;qhHcI zV882{=I!Nr^4V4Q(n29yZ?6iWKb`yZWQil6d2#`V-akL(kGa%E%#p!_?G=3U&%X1N zJ`9-x?~Qpcu|;ZIEWb8D(|vAIn!t8+s1YJF^6A%IC#260*DM7D$#L!7&0RJZz$aZI z_HE4kw~T-cg>|oB_B@qh38XXb4()+m5^zF8fsU`2i4Pd1?f$Qa^@9o&5&@s53!6~B zMrgXEyb2e-iut|r$a}*}X)ZU&_H(Sg7oYr@{Ze!?cSYxrr6_wVK*?V@HMWmjagHaT z9-3hd*<`N#>Ou$yKbpJ(cbYr^@B`!Z^3!HGk90)?LalW%zG)U>@nLU8zoJb#I$C9+q|TA7rvIg-ucn4n>%sSDqZbXFt3 zPTFv^^czvX+O-$D6#=y_fEJ(j6!xj?dU(?LZI65k{*Fw8gm9r$OSsQ$hs2+2Qj^X`0QP}KaBM{zQqPb<Xx8vuMvx z;++vJ+_zcsDBU6tFuGGaL9KC0uz-@a1z_>Jd6}?x{TeJ8Q@U|~y6KHvSh7;80L`ex zZ13>N4DiOrdZSaj_zYff%AWSUh6+>^moPma&aA@hn4kPm$p3giKy@=iOaQ6AMj&>a|SBc6ruV9glM$V6sXk6WNlZ;mBp2k zICAfJk&yStL3{wuAr3g^%uPX=O;HzqTecYHJ7=1M8GlWfJV9L^yb{O4b4_8sFnxxN zsTRa@C!Ckwb%vNzSd|ziHqp89!7@n{hNHBPbcn64#>)_la5a8EnVq-|j_oZL_~vA) zrU*^aoS2sLCd1Rl6*gE7>qmQZZ+b{`J`v?oNgaS?mkEyUU2c(deD{=PA( z*4UYSXMTK4Iiu&-_5YqaJ^%1PRJyvfgc@BZbgtEx%)dS&`3eV=IrAnuNHRl32|SN>X#gl!rK(D$j>UNmO znafRdO}m7IQQ;vy@l(@I99ZYpO+gkA_`~sh0%wMPTZG(zpJMwH04F?Y zkmRbr6^N_l}W~fvgy~AQJK&>!-DW-QQ0LvD zC+`M!ZI9hp7pnmk)iPgSR+rT@9aK6G_%UKJqr4_UCipGd5Xl1ggQUY!1?$PR+IHPl zKP9ZTsYe3TCu~vpkGP=zcFIMz+~+vt!_pVf|qIxn{w2RraN8 zX30>H+dR*X$E`E9o*~pj+~-*%c(IfF8L#vSrZt9G4)t3@^W2nTpC~lS6&S$52}s8F zpkwfEFfdi%S2-j(z;+{5$aqZDMV)d;X%@mvAt#uk^(F9z&#6~OUQ^4lwn1Od$RVM_=y!(<^KP{)plKgEC6Oo&LSXdSyv0-> z!?AIY2i1`UbQ^|mi+tu)C%QA(an)f5J7a+1{B8@HcwVD>V8WH`?kgHYJu6Ks`TlH? zNyKwf&5J;vY$|-iMR<}F$O%GEei<@+7IqVYiitqv$?k63osf36>4Bf=ByAbTle}RO zmUXCt@Z`+^JgO7YyG|1u zX&ufpAtykEJa5$7mg!obEYz?ex~Oj7={&O?^I2Yh)zOySvSf*p($SsgO>8}W_}^K; z#C*kyn&Ufh>@U%`hwDP*&XYTIhGMGo_|NqYWsW53=CPn7G% z_=nq3(B~+()TI>S>|Q{#Lpu5ay=I>5qC7MO$w@;1f8OuDM2TcMIh<`e*k*Rfu}7sQ zv}T?6Bj>LG?lS;{A23`*kqsl_jxYe&uyLfER5YtHP)KELQPG(DJ2sySw0G0zOH!zy>Eqk}~>i!LF4L2C@? z4|j=b`SKmCGzHiWMm3s-R4$@Cg8aQoDfBp*n|#-1!^EH-&~EZdJ)` z^4Wu7%E>|{k2WKDCV`-Yj)jsz*o-*eXORV415Nf(cbjkV4Eb2y;L;kAwJLLjZfp+zg=EUTP zQ!INBVB+bH>*%iI|9%|m*4HiTNpFU*B&5CLc7@odsziAri{?#~Z-CcQl3_}Do23$g zY(V6T!s-rR^o}d^Za2HaD+1{ucXAk01Qk!GV0v&lxG;}=JT4m8g9!LuhFGwJ*| z0jPEM1U7r$yh+6k4qKo6G95wvWVS!T4LwFiosJE1&KC2H);Rr_iI6f&h8cNmN+)Vo z$>8Tm)+Svm>UAk^z-aq;=;D6_=mu+M4{I@;>bPAHYe_fpym_wA?rt@d4K}Ieg`EXE z#Qldq)i#>_rNiVTOdoLrfJLf<8*|jEEfqw0I1jWpWt|#qXwB)yS+w|tO>VL zK8obi%!NS*G0X@NN2L(ptAy$w95wPDRp5rI!z``_fA+i|{68}czJedobNWS>94EEx z$1V2cA0bpI>xJywc9l6CzMe z0Kd|=eHz!^1FsM7th3DW&$crsD*^~49pJjEdz1<;TFgag1q{8CMmaKySFD(>4ZA3! z{_L(mr3FFpj8Sb!LT|p|_98AI}tm4T4| z4KBty615qXX<@Ye6wdel_bUBuWX+50v=--ujyd+86!f95k>XC16>a5pc=2H&!V^^2 z6T+}o(O(XL*f=Q=?(SBfEe0Fmrp2shlFEcDoXtM1NlN~Ua!T_mfDDx6X7(l}qGFhP zu=HN~k@Gl#RD>Wi(Vi7eEi@mK_TY)vZKF@bv+_-Xa{BMJu-}hlu3z+bd%QSeQ}5Eu zkw1@nJWnW)wV}Wr(~7a}^<=(54fds*=i~-FN&z~1g17V$!$ba;-g6EjFXc{%W$$1O zMSl(OR+gG;XNS^-zOW+NgFDp?zp>DCs<(Nf$Z(!Ym+qVMSC zj@i}c;|cJ_5XXRM*cwi=o$05d-0{#SVT#4~Qcu>E1RGx8N#@%iP+BTLKq>AzN@d`+ zC8h$}A8l0OTMO+#WKlQNPP(vTKvE!cvaTINx~R5Y`23%h7R{);Jd$7rMtP+=2^ONR zOYTsP6ErCZ=_X#RD4h1~&@50Qr20gyf=tVbPP1f!G z^nT^#hE6=naQY^tamus~6zBioHSD`|>Hj8>4MWNp8K^433WPCsk;zJFb>oQ(jm55o z?8>zeiL3>|?&YF}oWX^AoU@jq1N+#zTHr%WlSYnv9?T-sRYg4RNqt34}4qTo(PtpB#tx4qte-y)*`7@F9RX15yH)EEcSZ2vwFD)Ren|^x1?@Idkm&e(k zB6CIk=lsKUzZ9$Mx-a_u=)0}-aWAbVrjNiaV~P}Ogho*JM%dm_U+h!xA}reCJh1Z9A& zpmF>FEqk<{!aq>2_Gu-tYA*AsqO;51^$Fl1U)&+co%V1USCMckiWSaE3LU}fE*PF@ z?viZmfpiYol3DDI(aO4a#3i+<_4VFs?b z&M`K`Zvbe{vhbc%Qhi=gpRmhKoH9qymql%}ZLZBGj6JQ`=W?p2qIco0@oT2aBQwFh zPcS4pnTm&0-S1Vrn;2P#`&9yyXMRx}=RuHB=&%|+!9nz`wmZ>YyS)O4;#>EiWzwVL z5NYJ~n@9~En?Ff@`uRm9y{mE(sy-WWEzS3NjSZ04e8*p!??hT<_cV=CWh`@Rs+qwV zC}N#dN)d~dcS<*?fbXxWX?0O+BblSFGjYW`XK~&#iOum^+8!VyNTU1{HyZ^mRWY$% znWb@bXU=7-D0kc zv;q=yA2-GI6%($oL77$)qJa9@zCkHFbifwQcq2no1Mp>7BcGkT;3V;Om^$(H;AD=N zU#Xy!Cr@$AJB1%lNHJf)`{9t4dF#A(c2p;y(<(06M$vPEvI^dd7i^;uW4J%inRcFYadp6Du3Bcc@`~ zAL@Oh1o;`+6cnidpcJ z5@k?>v3>q($0=Rp-+LaCuRK)w#D3+Q#p*S*ATzuVhW zlN_QbVY17R_+BD$N0{MgNWFK!>skI6#NpT6)B6rl#yem+{cHbP@G>}F;OqOz*Ufz) zy$Q@+iIJPD3KsR)L&E|Q4q%EGg6){%OSISF!Zn2?0!A9}3DM^*z+TFhkka6oQq9X$ zF?KJ0H(Rm<_6b|(&`y4=HJeC~dmy1>GyQ^EHIwZHU}su z5u&tCQ)8PfvE9{B0Uf-0_WWHv<`}@EGqVwkGo zQ~U2!aoGI{yPn%VE__#DjI)WCBMnnH{n2gxNt4Wq7#9d%9Umin#4#Tz0$Hg0+y=Uw z!pv2(`JcI#GoXpY=ib@B7Ab&a^#?hr>K=G;wp+iUTj|jlz|IQ=M*qJp9X6dm5Xl#) zRTEbfS=JGGl-=>uN*L;tP94?1K!bK$`;3RDnDREuyz0?kqqM~MKU-$S*|vuAP-3s5 zzS<#!*)qDNFKwrRt+F`k%YTrwH;v%iHoM7PcO-1FKfUE(C%C12_>)K{jG*tyNcmKW zFlYS#vK5$HYMq!_pjY3Yb+l;|Hp5ZdyXf%IQpD4}tl%_HslARO-l8OTecDV#Aptus z8^hQcM*v_W%zgikytl59!_Enx)op5g!MHS;GiSfZ&;o8?QuIDic283=|JRk1N|db% z40?m)Y!~W+Bn1QTxGZ5SB#E&?!?$qyHs-yYt5Y!jfeu$$gL9>g0h1cuQmI9wPP1&! zQA6p)5_s0aJpI{U1pF*bYtYOs;wcq0Qps+Gt6VRu1U2WJe59@R%EIy{tvUD*P0|~y zr0J&%y)*W^NEk}p#hmhDtmoOi=GDAzJt9{_VZukn-OtML#Hh1DNGpHbn>pO8@sJi{wvW8XX}_>z^V?}51?&B zYBsXHtnGj-X*+~gwkIf;a?>OWaLU~jav+jkVo{urSPyce)ZG`A@+!jJ=mMmChm2(Y zXLT}KTxS4aRkwmbBq%?rG-vqlttGt~13$!UgQYc8R5G4~Z(^X1XFO3RC{)g>6%E&& zlbK)>wgx0g#);MeWuzKzi0JDmb~c9ToK0^#cx80A_^F>4mT49P#x+hQ6i;SVwfUFw&vUki zDP2?VPosan0=mr^w`zJo5ot5vUiP-yI!X<6v(Ygzy)+SNCjn1S15HfFJS&CQ86lIAitrb%R>nj361SJr@4jCc0WK>iMtY>9MbREq#yF9D=Mksuid)8B>#gW?0ALI+s>3BVC1pMs z`o;L5-?XtmSa5m%m>cHFsj_xA6|6%4T0P(`$4fC8@HyFMn3(n*#JK$qk&=GCCZuhx z_rrRaCi)*1s^q-qR=f&5Z{0v8WhXW+mwX~^hHfiFNyZ@^i*3c@Cr_jb0F{??Yv-qy z@$zwQzt;ushOSA8?K*Fqd5Hw;e8k!MtVcRwL}bS@Q;WsOINKI%9d^Wa=oS^AU{{rcsV0?=g=K-5FT3c+T*r;aME!}0OqwjpqKd4NRGG_ z$y=8PZ|xy}vYT;<%6+YxkHGjhC>rYNTVZcy>ptlHj4A6NDEhdj1=J?7yGN7yke1w% z(ZyUTaa)^K;p5s>^k^ft-{yX@@T@tH7!ZPy38t$ec}*XSI;nyIF2BQ`YY1nAucU|} z*m_aM2oZ#-@Y>OmKIp1Qd=y4b|ExjkGS507>Hff@mi&MTjSb^i6-F$u9e&8gH7QN| zN6p)N>G$V)&P^S3La8|n)=6AOP{ujSa)UUGhUnKD9ADJ10veE{nJrIp(zE!EbF%V_ zYfZGu(?LI=h9Lq*JDF&I1*#x~Vl#TiCrA8d5x@?T=8b3%((>Q}IX{=OEaC(bYONu- zTZF~0N3PFev#GEhGos2tccP=h_9FKN$_NrL6I^OUtMYagO^XFPTWu=566}5MG+Z&u zu=MzAk`oqDxLzb}u;)|QMhb3W#$ORNcRqYxK|XFOo1zcjmHHFwT0IH=2QzsX?nAE%XM4C6+LCb2xx`;Szf7*|yp9hA0{ z85v&{h%M{s&88ba;JqZS);_EDp2ZaX&r$+Ez~lT;zprjI&|sOZ1)3qQIF8frp7YE| zl(y#poSpKhz+%^D6<%Toco8}ZZN?AsHgDDv$It}UJHhk>;QIAk&)v~b+Pq<2JsA5d zjn$(sXs+2smNCH+Uv%{+v|QU@)yf@*zwiCw*Lx8tmxE6Hld{G>iB3mlRDY^tuV}2d zT+~Km5N(g3QNWrRuqK@hEoJ^(P~zd_ioLK4c)X(W5FVo{VEp|w(WJ0FP0iJ5+ni;a zYFR+*-73?3J-+C*wdggx=#~0gPsRFX)0R;)IUN7Z(Y;FKON*K4W__HpfI6n^ZxXX} z(Mf<$09A-YhpFn17X(4Axe(DjS;n-BFCqnOmKU+0lA3?d#DZO3Uke9*O8J8Rce|-l z0Hp#!pIu$Bi`;?{6Myoe4+RvM<_&z^vR>{xtc9Dh-7%B2XjDEcj$)SquIB!N#}U?? ze$!y>NE>Lk9Q*XVNe%X*Q9B-$%u@Ah7`D7H4#h{s-`gQESim-kE5m-M(}sf^a}{sW zAF{qf)5&sF862yACPd`?37KU=I;^${fXK(P*d(I!yldf#!U~3L7hUb~nG58cx}#47 zZez|f-BL96g}K88?DC#`5BPwS>OsbdNbAo?vn4OgR;XDudnE=pWPjRcE-M0zwES=v zRpDb7I`7ge=GAP5fp6h1nGqbmgJzz{OJ91;$Twz_r%lrcUKGDkWC%hG=KlGp0LH(u z;gp~5H2p*-;5HlP&_*p;DW`d-f=KbEr>2)1;oTvw98@)iLRwKEkN}kN3gs1-D=ia@ zyHUQxM01$Kp+0-|W$27E6UvQZh@{59edC6}7t(XiZ?sBb1?-7+=YZRc3?}?+Ez~9}z&;0AOC*=is+UbswY}sEejB6JJa5N%bHn8i&NC1OC`E zbsaoEObB@wp~9urc`_v`+oOZe>Tuo%e6$K)a`VS6?KGN6s<|Dp_|sCuW7e4pB4NMn zodx0y7!Hsd&EG@mRfB+yoPgmF^(#m-GiTKadi?%RTgH7z&71tTW4$bQ7$~#bdlp${ zASyHj5kTTNh5F7{_{`#cWjB=txy!7umKk)74lX_4rz@x$heRhaO zeh$kaM7p{)kj+Z<&tirEj{Gb-%n99}k_9{grSb{Bgt_>o@r?8n)GQmw&`!7%^6GUD zi$ur@w_X%UVzU-fiBXrC1MD^)Gs)~|v#}9q z5A-HKSiw-V7alBfj3uUk>o79JCZ4mnTe?&hBZ@v08tx_5P&zR;hZHE0+cP+2qS{px zbYnlIqJ{0S!>3rvH+v}A$rlkBvSe46hjSDvMC%x|5eC~7E2_cTT0-s{O-%|BQ+m$a zDFJgjsx{^=e|HwD`gsCcI0!VtL4#^{or9;_Ga1Z3R)gKOYA>n?dt~^Kx^tS%=;BRv zt~is|=3FD>?{9C6s@m0TpiQE~S!5CFoRYTq7oM-H!4#lEm(nyf7DDATd(8JO+RX2x zr;4B&8{;I=cJRBm!mHlGf3o0udts#grT{FxWp9$>El=X(`Vo2ImWGd5^W!=Z89NmFA~5RLQ7H(K zV`t-^+#RQ2qT_afq!0Yr!iACwWNm2*ZQG73EI~W7!KCnLnOn8}@Lyko`KGTLVCtTI zj}@ThZ~|&fNX4s_7Wv3nRt!|Sj^y3VXX`_ra3^cv>rdYMehpN-k<#p|uj{mgrm9@0PUWi-&?ot zBfo00y*Ed7v#a@lmiD2PTPq(H!&wG(!7gn9h>c34c+jqwe>Chc0z6Ber3B{xK@=;J zD`AQDF|lTO>*y;$4>mUF9kEcE7WCJwrt?3IhQ8<~^kTH!Y1Y=^WkoQ9g@nK#r zd7FwWTH9-1ERHB=XSRz98pRc#$__t30m`3TtNgiK+C81F{$hX;T@7VrlGJ$#fjtxY~kQky$VyGE%S+@l`0jzb&~P z)aCFDWE>JK4K(a6taQ&eoZTQ)oNe%1NM)nzWqAb;4KEK54~IE#Ieee;t~afn=auLF z%_kt?G$akUVJJ{?8ZsMfseNx6(ij}9rX7F^u>uAd`&wPvBrP64Xv(+bG1b*TWNO?*M+LU~eI{dda$Mx!`v>E>_{nrT1$=!so%*HO#=`{(thUc(C4jQ#oRkY%fb z!(1dZ@5^6e?>hK;5Zj(!BeH&ELn+6oF}RH>qUI%%N0FRgNkl?^8#f(za^h%`hnz#V zYBWCJOizZXdbDw|6TkP;g!JZU*1v_DPhm)ZD=YC+3G+2NZF9xVz3{hI#@}u|`cZ|? z=ri&eU{mVYxwAvE6|17l8Tq@Df*GM&gsbS%qJ=l*HHAp(B2*zjv@d%>zGEWbjJ;xg z5dB?PWXd(o?6Gp!D^PHZG@JXyN_;NGL{SI8uYt#TLH@O4rrAB9@Lkeq*WEiJMSM#V zG08ympw;=;_D~UdL^6*$(Nt59Y4$u6h6d5FnG4#tacwEb7)z+mfhD(8{%Y&aqHX13 zD9t!@%zhfR@AMt=Nd8~xlD2%NjbVjTnFS?w<;W`UFD37rcIWA0_-q}6JUfAmp= zB-Syp0WiDs@25Az2g4-?iOAPNFE^iCeq$)afBNl;zb$9wmr>+7pE_@bn&mVQbvKse z$i<-g41vTq;L(N-VJT_i*Pd=QS%KvM?{~~GdyzZv<9KT#{#PQnvYJ$MY!=Jh_;?*- z^O)bc%(FZNcVz@qawl|?h|PE#!ohWJ5sEHs#WcW%9z*@X5()m1PWUut?R;Y&Y-=Gg zd8tXfiK%1c^Ve631EbtZvf{;IOxB=T9s;vzNM5VhL&%><*4f8#RP;6s6n%q$U1?d@ zkd!fwk(0(Rcp+V1tvE{!la8b49m5zaA1Tp}9Idi5F^t^^9NH{-ZpB6xBaXqplTE(g z0^)KhI_O(zAH*!AOXN(oYZPd4(=cH)53ML>xEj}dAx^?Hojy2K@Hr2FFw%~*r-aS9 zyNK#%356N+2s;R=6o%1fIl|ZgSrSFsnH#add79&iSvGfhMJw6CfUOuG>!})aT4U%}B0%yR6Ll$al2FH~My-pI5uRVC`Jr4S3%ykn78jj^a@YHQ1+bdS{a+xqrW>B)5sMB(L+EIe@#rX z{Y5JHizGgAEb{d9W^fO%w-D+_@`qsT+2XIFjHDz5*=wir3(ugP6x?RsEyiw-fN8Ey z?&yf9F$AU6DL;W_CX5^*EyStr@pJf(P%%`l+2Im%wV^GRn9)1JTK*#a4gx`NXRD-l zH&`EH4yy7Jm7z7a1GQk&t9R##;feJ|ZC+FJp0nqH-)ud5{vwJ1j?o$?(Qy&dvI7}aSI+Cf;$9QT!On>@Su0! z@2h+3?vJghI%nrh_jLE1>79Na$luMo{WrYM7nD}Z75aro z{1jZN?zi|qB6D}@%%fx|Xq=5X^0*}Qx=bMzFVIV9eTTvB%JxXGJiDv87)P(54reV) zy7%G&5jO~8wBl)gE3ans1sqemn6V&Jd}U)_2bB0y0(} z%XUKyfcqe+`!W)>a|AnsSa(N+dXdyS9_&K88NW(?^QZelL#BMwhf;FAZVSE|C?uu@ z`XUD#9a`n|JruK_*Kb;@#cAJ|(oV#Uw!TlE>YMK?n)oQ2?9APjsd5I*&-+jUn)2%e ze7$g+<@Mx2^IozWi1)8}AEohsV#tU@21m_q4b&Te=ZDgGcVqCrpT&fc=&l` ze4erPR8|E?Yb2xwW_TJ@WZk1z55PyxG38mRlqh(E9n>zC(g}Om5V&PX(K2L4}Tw0T(*&)Pvj*jL?X{c zL@G0jx;6W|;;JiLgu{Pui-WnL*P}K#bSqkCb#l61!*l-f@pHuh=E6b=AWkRxm zDLc$6j8Mh%JnsH^tG6XCjOXqIz~N$~8-7A`?SuqH zFaq|5qSm8k@*rSRO_L^}nkWy=1GFt*g{yB(uUdlwS0O3uvwk_TdY`s$R%z|J_Utv_ zboy_h4SgtNknPI|%-3zP$CCSAxVV*b!-Gm+M3~_~stlrQ=n3F=QI^%5(^@E&Ztfa) z+D$ZGKE8S;&+$QJ0I<0h3c2f|3V4C8q8|42B(sn7=dN(3wkR>!id0i(lxl|Ej8Mq%?0nO^sbJFMPi+jBNgU zG4{^f<&0XKX)^6%o?a^wru$=!r=v1m-UUi7S$TtyRy>!`fl`e0!6wcMQIsTD==U8UcVo@*X8A3VS{1CLU6+zR~k%1 z;W}&de(rq5JZ(4HSX``F4^FQpd(5=laPAB|U8uYgHo6Gd_S-DtuZ!O+=7%AY84rEB zKHDAO+HI#!i~#}E^G!Mm4Lg_<)7@1E2vjZ5etr48F|RZn4OtboaQ@^M1pAB|>!h71Z+pY%~d+|YTc)5p7gl3{i|G`uPuAEqZy41Ch1FqQ``i|DD zwWc2zO}%@sOV@?=YnE|~c=2c;RN1Dex3#DrPVv+_YVl6Ki6Zm6Wbe>N%Wfo&R9Y?} zM{yEqC)#oVYp?^az?r0TGIg%4VAxVV!`TF&|KCQ#DoFTGR8*N~F9O~g0yrRQSnM6+ z$VaHj(BNLgry&k)w819%<(dn$MRZv2ba&+Ey?&fIG{wW2*m~$9)zpf`V9xDeT35T@ zH8tsvVXuY8e@U%t*M}%O9~`-nsebvT*>R|!7lj_c``N&0L#eLzQ%i=#itFGdN$B_D zji@kP;ubg@6*;rDeE0#t8wR+3&=sux*QX7}j94L?g=I73PKBGvyv}mTYT;2U9uNQv z5zNXDHh4ic*{Rsic*-Gc_(Qb+pBI5zz^1J0!lDLxv|G`4J(m=@O0$nuMesPJAdie=Q5JBdKgbt|5etgDJ^QBT^tqa7`$x5@)#zy3_(oX;y_0f!xcUg^)Hrc(f&`i}hqHGgF^XihEhzph04oggU z8^z;Im(e6Sk!f9&fP?+Nbse6y)6M)y0uzf5PKa#M{kNc_a_5OJP87?15`P$>9NE(v zwH{W)eP^^phRo3Is~48=JkYc;OY~qp?AH$RJe-?+h!ahx4bSdPc3ziec3bl;RQmQ7 z-Y@c}y$I6B(s-h{W`zO2wxso3UV(U9a8)oyFKr*>u%DoDaoymU-cC7*YE; ztj5d2a=@Ocsp;nDWfk+F?$_SMM7vb`pr6pxv-+?hmM)dEUt-EeEXJg<}9Dt*qBVy->a@M_l>mQd=CqYLUy8^SP}1-HuH0ZT)h4+|28A zS@*x)?Cx~Q;)gP8NaIhC3v2G&F=MHSk1)|5sryWla?N2g$o_j6neK&}((UJUCENbd zZWem}Oo)w{pwHIaTM}{s=gt!R*$r)_JI-%9YVBzlVRh9+y9FBnwN}01RQ*gaEs1m$ zjv`k+tEW!+J6%L|NtFg(SOUTo`hAtS-BWVKnaFENi#ldeqQD;B;hB zx#){*mHF55Ls@vH!Y$}CLGwdWEEpn9cgTLk;OMt(o>1Ap$ zLZN7Y%ai}i!W{+!x-sp=EVhXs4F3|Zcq;~BB9+BVpKMAPB z-6XI@9J3h|{*yh%_Ygo$zt}>HYKx|B_fk5z$TvHDt>1WF0@zf=d39l$9;TLT>q;MB2d zra-F(S!tXY8chZqyad2yAou`|#J)vbzWx{k5V`pf;RlC@lTnKOYRDjeQfd?oL^J)( zP*Wa*L?fIfK5X%u?1=fy=R6t@%0eK4vX$MtI$?Y@eT2X>Fz8E{DYktXCu!e3?lkIh zMl5L0Yx)`mI6`KT`iB?P17X7cmDT?Tm_i534($z$JcRQ@Dd`eSeu~f#v!(+g9l=q3 zu79`iI{!`}&{By4P5%Nv?+ulQ3=}(pBZZ~`8Xdv$3E~3yX>bbAjvkz(i(^!9emYe! z?};KKcG|Bmok;kMpf$gv>hlJ++*S#k3yhsw~B;Y~S72@37sk%f+dxRzkrs*A7#O z_(GJ2DF8{yy$+i?!<*-&UdDu4%-UjlVxJ?{Hp(_vk0{e~ua+5gNo-hPrPe|~@@%ID z(Th^=)H=;UbfU7J*B^TU1*V*XwmD`Hhp)GZ?UJK~?pR|gnj82H!84$DHjyXK9Jpn5 zh9GPj0_RKKe0g9OQmW3P{4JnuGZ^7;pR`|o17L!7eD~{>)c_bwvPAXKp_T~s`nhXWY%fosHG;MLK$tORczH^bvN*Ohl-|WW*ACQdEFdg9@r$cT{!T>hDOVZ z;b&}p?%YSPF8{pvPJjO6iu8l3>}fCgGbw}7B9xJxJ7nCGR&qb{Jdsz05u`?}4=@_j z?^l9ZnYk7~n)eg@1ij>zWl8N{aGji0&^(^`(eC^ZM|}K@J$LY7Ein%qdJ^|1?EuMZmuKz^-h^nccwNg zBE<0S_w95$+)a}Nja^w|=B$WwwZRXEbMS!qd8jDua;XV8eHd^qF4xy zzJ_%BKoF?gyv5mwf;E;Mbrq|R2VBwG{%J8q(adEJKYA@cp&{0Fw__Zjt%+`M?ma7QyEABTDS)Hib!SyB>7a~Hev=Oj7k8zXxMSVb;P_%CVM@rP&KnOeP7?<{)w#ho?r(eEUVyc9;ht8 zu~WxT@`*fYh)Q~u4+*mt26*9N9vwnFy@K}JP$XgaH_i( zhwvOXf%&5az=k+}2_b|49EUF$_9A0e6|^7+B`-m6PPIHjP6z^<7uVTjxJ-Yf6k$Zo z)shA|+RU7vF>6K+dEjpOb82U!@8xEJqj2s+AQP^>g#fyz zRQdo6|_YEPheV`fAk`zE0og)ci`o$^1;D1+hVET@losOZ~v=r$l0@unVf zzA3vacTb=yRQ5kz$=ZOifw}dE_Uw{lZiQ|aunSKCS*!eI6cGFBR~3jjK9@f^&Q;2RqPSp#Z_*C@{tYLz2#~#Q3Pc!04376PtM;aQV|6{@H8N1 z$V3MDRoJQx+!q4DNi!lE$&0k9l0!&agzI;=JnvcrHtDkd;)HC1>ZjE_-`X5Kp#TsO z;6eyuC{-3QD43FYN8zeDXM7dXKSYk02@s!`X1+0s<2j(2{Ux<^Mw%t`w11kK!i04A zg-N_9b*dF~3vt6s!lMwT14P}P=`teoV|HT5ozqCF>FA<*Kj1A2wMH?QR(Tswy0|}s zAfClqfMq+E-(P-WvB%uAQD-C7)b-Y ze`_q*91Nn#cs-MbM1h*`28?822P2Db;9j4(r93}Vh+&kX(B7%$kESEu zdBvh}cxH(>7ZqW@^!I+*q+Z}C+CuE|>s(&PJ9K>oHI=mti%&sr*?1OEIbO~U6RzSf zXSlOWFJkl#pGL}waH74V4LuC)L3KCbsxo~T>%hzjh*Z@h|Giv= zZ%GQx8XAEA8^G0@A;ywm#85DKP8ynJ;tJz9%0>opx^J;oCM2bs5nm8vAxSynCab63 zfr_zK&XKRh8uH5Zd>dvL9j{k98t%ukLY?8CEEpQDx;=Tc`y`Zf=&3N&e$JDdF4K*D zi_;FMcNL5V_rmgb1-d_+zn+i(^RbyWfdE9@t=;0Y<%{vyp$u6pBdb`${Oa8?a{>}O zPxL*xQDBw3@aN8D3Dc`4x+SE=)X04Zivg)EZ!)C=Wtv)0$Ub8d((P$+(`7r`auoUA z)K@Ap=?=#XI}RV1Ur!|qxU86mrXi2l4{iW}=dc?v)(RtfsK8LB+l*t@dMS}yTJ945 z;3;f(*vIH?7BE+4`d8Soh)>#%d69P0 z^s0?F3gi&FtYUK%o;^fb@A)6A+8AM@dN!GV+GoFR_aAeE=|VIb9roY;ZG2fn~D zuwyskbo@*UG;5`d+#AHRx3vX?f9bPLeM?hD1}}6-JPtFKrR*CGuoerb@&dG>e5jwa zgV?vfnxnHFkZh*3%pR%+y@pB?c2mAhlHmyl#iuE`i7JrcePUg!_{ZrcnM!60+Ti3e z`K64Bd&@Jp-IM;Vtco%;on8hZ7}<+^&2mwpauX&_yFEHes{jbST#h&0x)i9G%~Q;C z-RwKwnBUxWF>m0ioMeq~cLGvI@P`LP(($kLYvQhB#axS!Ql(X+RH9y`O4j-?~$DC?!j`hd8=pXf1D`I4#;m_~YbfW+`7h%v{lnygq zYftM6i;=rvF0NVsp5%|TUEUpR%g<#=nITWq<)3np$SBl2OsHSS!^T{{Z9@1(M#?N_ z<2+I|!w@uJ9e0%J7AOfY^^*BIb>qD77OJpR-{;~wT@N+~I#*6x(0<`sgfjrr;@MPd zC>t(Pes!W;(?SbPI!gk|b)Qtd92kVUQ~2LC+4qb8+wyG~Be@_`mRpUf$NVGE+Csj3 zX>t_TP&MU=yv?{X4a0Rof^=20=|-Rp6?VWK_h;mf7QE2XCj`=7Jw!f1v=+{6^y6na z%W?-R%Ev$v_MU;Ve{y-&Q6uy9DcKddgzH9OhZLW_bEbHXy#S)cr?=v$^jJpBXIJjR zSb&sYlzE8@xzqwau_#Zal=sRJz{3f~z?Ty0#dH-& z1F_3~`FpX9H3G!3Z%Qyr?YL`qz5eO7{{98pr^|$M*vPgPDRo&l#u)QA6}hPb4`(fo zKta&ev_k4#;C1EV{$+wnwe?Q*Gf1Du0a1$Uc*rK|2tP4&;Nhm-mB>FCwg)YwKu$CO zLS(NH{y6wx{3}&FCm&y>6T12Wc&eAMSMfk|?~!!aTn9Mcr`Os`f;RuaZfph&lQWtF z3#_VV5Ct36MHHQWV(nYuW+B%MbF6lSegC&Bo2O?yHIx#f16c`y%pwwtnPS@QdUb92 z2}WlnMRLYe;ap7l_Fa_x;KP}sR|EwG?)y=KiQ;~iWlFgNe5@(P3{yLojo%gT;+00C z;=RQuD1gx`j%Yd$*LbkoV~MHPoi)m(vFJS$`P9CH6VY77aa8n&5h5#}O)fXqmf>$( z5$0Ee_i~`%7R}yjo(fIaTAvC_EeNB9Dl9kfw|`a?Vpu72{EC8*;7} z=jCkTNTf9-g{5CEX4mV0+;wHHv~Bykb%96CI;Wnwe@CSS6C2ypcOx#B`ISrO(TS;? zsO}()C=U{&^0Aql)a{G2udZi0IjkRu1yls8|8ENg*ZK_C2@NR1go4WFfd0QbD5L*L z;@1iJ82jO1BmJ)Oi${*gT^1Hck|+*El1)gZ4@3LDW)!qW*tXHI;o;Q;BNGNsnHy7M z3a$53$`R9H<>w@;ygYOA6Eb-z62pR{!(ULS)Hdf>~>jDrp{PbL2B zN);%HvPS|F^@K-@fbT0->WKn)zwdMpG9&HS!PW<@p)xinD4$yc`n0D}mn(_%Vd#neHBu&iM_<;B$i8(F4ygTEWzu z9D7pfnI0eh5-+pAt7DRS=CJ+lKJY_X+32`Wrfh_CulOa=&;+(umuIe&uAJSHpD;m* z*bA2cKh8WRK4ahfdmF)^J5jneT&a=9Ym;>6IkjS?$MRV5H_=Z`XK={S+9wV3oRaoh@~U&oTHf1!~r!rT8kl$ zBz@)q<{WQ0Hl@w7-?0%3MetvrjvgKaB(#DxJpE|*R%ZPAjnp#(i?AAo^VN}IA}SP) zWnZ=>wxVd%rV-}yf_IF)R`1D=?l&qxM~@Wqmz#lK9Z%8I^;iZL=BG;`~XYOO?#8gfv& z8$fH-LR<{_TE|9*>)#~PSt#DQG9W`y4^xx8hK83d!j=pVos>!K)&JtJ)A0mYdT|dz zYp4IM*OIw5DuX)Vl@Kr1%dp%wvV=m>(bF<$NTLr$W_^DIx(7uQ7)kZ;4;{nd_fn~~ zA69+EsYUVNKrCU$N4rlpThhI^6PBQuC{r-_Pr)L(b*C&N+aOvx`q!+%Zy1E-5_t1) z6D>&|x|xG99mU*R(`LGf`v42iERW*!7DG0Eod;+vg^NP6g}HP6$jz_zMffIxGva&b zuB!8K6H;srg`jXoM{=p7!c|EX;7y2T1)l8m9XWt)s&L5|CY0Vv02tm7O;Te221Z2V zz6=p^P?VWLnaG#|Ln^+RP@D1X@9QlG#=y@L0tvFtAIudHM2sL?K-CGPK)XK2*1HsC zc-!zpkcEFQhf!SD3!bK~BG36e`}q5bfi zM*Y`G-)U~ZZMnWg;Tt>?j>vvY`wN}au`Rv{yQDWg+V!Y9qmT9|yGSh~SD zx${?ru)^!f;XgO{mM~YHcMuE_!!s>YBKpl_aUmRo$aa0dxaH8Z4e%X1VXPlAMa~rk zOu2w1>^V7mv%4USm5ZNV2L`H4Vp~LsyK0YwJGn&O){#|XEXrFh7L4xdo|AE(gJ&Yw278pKei_Ls54G^wK2)hRD2$G5bqi73LN~M^6wBWCyW4!OCiCdoB-{$-iW;s8+F2na`D3f|NEB!+e$Q$ zk|~ictDFU{KMYlOEhi*od~O6GloaV9%hH0H&IYh35iKx+>rS0m)Ixp8Tl1-=whe_k zzY^sA4R%K_(U~hcohWqCS#&2oTMN2?gex9=jK=tJxOn%}1I@`)WhYsE1HiWibj=e2 zKQW4qwr0qw`LTYaO6Lv)zx$D=!pXy`a($wN9XDJ^sO30+J9%^ua$uh08JCw+Qjv63 zoHB0jKsAvTs77d)O_I#)6hC#W#8S`m_|Iz+UD5Z7ls;C839!O2_nIIAvqRd!bwQv( z`^tN+R_y~4GVU2&A^<*wJV8$tr+`?u)jkJ-^uSO-Os5REfa#)&_7 zEusyQ5vxUzTpnuGV7<)fi6e@iNPoc?uK<}Y&oo(GNPOvq{`SCuC~3Shknjs4&e(^v z026re?1-IG8XyquW+1~rY*4MQI=F@anS}U7QLtTLItr;stGO%s_%z|&N0n?$;v(MG zM?Ay}@&QUX_VH5cB9KhT!?z=JLuJ>$`|@=z--A<$FfVRn23YPW6be(_5vL}9lwHLLI?avClP zcvjn#evdBpK@R@1%N+5d9!9lS+iVlMceB&K0ry%j6XECPoNCG}&3vLiRtzYvAdAoG zn|;lN;(i0^G2YEd+@j|3aps^eqq<8pQ3>`ABs}?qco4K{S-e4(u~+yOYgcgJR&MDW zft{-vDx5uGDS=b~d5Za~A2np)P(}SK_(?=FRYY?eaQFc4B#79_OpthA^<;{h0KoPi zV>igE;V#`V^ayCSZwyPZba)~{bv|ECXHKrZ;HQPNQWY(Jusp;oz70?J~k`^(pQ5`WfHHf zHlscVAL@^0^ND|09DR>uGXmdVkbdFArOUX+u|9w=y)hd2(U`4epOZf%Qeb z?$#GeD(Z}deg*G!oP8DZxF7j`_O+TDit&jqe~*;w_&F0%o!KWi;`ZuBmTIDd^oeWq zyAyIa&P0oFfX^kyh(*3!1)G|Xu7KLu$?saRwy?74<0;J}vfXzFfJAuYL2Sumqt0ht zpGu*>weo>S`A?+YsShAoyFy!BX;xf0GZQ*(@;XN6Y{I#`V3$m9QoU9dQkR$B!y$0L z342C`r%=BEd^KF-l}zZ>z}hzEA(L73V-s*sAjP7iEifs6;Ha0L9X~kfN6XkP829U; zS-(Br9uAsxwUetMfG(k?na2#2SHh1&jEA5; z4mU{yY*vzLwuqc~^>rG_0aXJ_7RO0#2C;zBa#8=YSkvp@<>3tDTT(WCi;9fMlX$J; z6_8xMSnE+Hpv|J5Aa&ck2a}2C7vVR5b0-%m5?I=LH6i!Qxzx2#DrA$!E}{Aw7&hTv zy`+h^2Esp8n<}H7_}x4;z{p>x-DzPdgHDZcavv z{plv{44`!vH{=$gZPb$EA8$mBe~?Oo&kjI+@WU#P20wY(+J zSz{jUK5V+1;q*Y!^sS7k3BptAsX5EjloDD`y2sST12D4AF8_PyR(yEkjQB=l3u@%| z1`Nf)y#J$}xy6DB3K@^6d8R$f?D|CI5$^n@-ZqP)`MgiWC+q#@H{ zbD6Y>+rz;6_|Gqa7P-wd`nu#|?#RvQXL;V}gQsee)ZLAe&$ZH6cJTAYEW^dzyP|-j zR5L8)yU4gOCBhqK*ehRDjQY{Zde_2%eLzRyH$7Utn;7-${p};*N!_FF%}oWQyyPfV zfcF?DA_Z4^yAwaNRH=er{BkS}5s8LKsLxBzPWZ0}PUfi&b9LXI1AMEU6G+UrNE;|T zo+{n*4^i5n@pJ(P`fkDsy6EpuH@$zZEkaD>Lwx%?H)iD@qNc8q*x=rbf5tafy=N98mVv4*Xks*-^0FJ~TO2FV` z3n&>Wf~fkKa;dc}d#ZzSTn-%IIUw?Y#-a6QGK0jcdQg;u#~%7jxp2wQkYc}{M=O^9WZ#T7eMuFtGILQ z+3{vx{`yz`z>4jVx%0hF4^#IcFIk>^Ea!5DvBpO%bn;jdPcnTOb7-;4o%UqqjNTK@ikRu=dr_5ZRO{H?06(a?YdEGVc` z-2X4DkwDEy_;3yePg)N$hr*Rc6sp3-z$HKQM;RT2@WvKP)BkQH=0*J6vc7nE`CD7Z ztE$R|Q-Yqn&JYt@Jt8^e6DWiU8^i54{17s=GnQeyn>anb^v~*v4QHSc#@az$9fMMB zo?D05$2$Z=OJ@;qP6*Yf_u3I7c62=|k&mC(FZRmV{WDxF;AyWP=QFL2_dJu$T=m~C zx1XF|_F+(@j-NZl*EtD<)}he%VAoMNz@>SD1mqV#LMR4m`V13?IPVzGf%+{B4@?lc z1toSJa58OA^Mbesy=s0#3PB|ejZKr{c3r(O@gdT-^){KDBA@AoP=`4fe zBi=#?@@4Aei8T{Te8-hABd~44T$A8!bj{sQiL=UKgT>y?RX<72AXxzVE+-6={OY=X{(`Ql^@I( z*7aoZ&#%-*WzTeE{_D*(NuF36w#AhNxKm~>n@g(+`&^}yRh=PO&Kn3C*DWHp3jkClmXXghs3dPFcE{Fe^YJl#i$~zJ z84$?+C011J5zt5L0Y!hZPWye1RU!_td|u`o4tSTgD{})9a6NL-V;(pWG~gRa66Pik zOu5qq;yW@cEf<{E9l&lQ*0EZ~AS@*9xaiD9)AwhzhAv!pwGHfW_zJCG{1$v)a`^QP zS^)~JJX>}Qj&^(Y?C>;-gunix7(xTf2J(Y&93pIhpaxIeeP0S?`@ zou>3JICV_zIPdfmX9Wn#JbuQxkFm4ha_DD*-d>$Lx-#R4AqI4@X6~1(_sSbug!wF! zg~yZ7lX3NY~$v4>~wE^^=`miKRhUOv0!GwM^>U) zryimf-jKt;xE$E{^W^ZCVs2prVB|R$08w1vPj@zWw%F1o=>uOTbak2yM;1F0C?0$t;=s>r2aCA- zm}a~h;Y6CQHR8#!IBj7Y$60oJLCLYECZUDTTuL}`YuEqQe8iH(Yth)HF$7}h9nh5AOB;g;v1cYnI=;V}LS z(z<>z_hXSI8m5ej^#JrZXVMHbgZP&Xd7VtH8W;rIf&l8%5#Z3kgiPxNauahxe-=WX zHQwVR#-VkR*xQ*kB9H0!udFVkKTt}x{&neYqF|LF%hbSp7(RCy&Q8Rzvpf%@{cFw~ zGB?W8m;}L>O%ly@(PCOsYH21z0*6G4XHrMAhRq^M-4FQ5Jiyc_z0vzbKjf>)2Lx|w zf$XlJV>#-83&#cVg%DdxQs_Q;#@Vu#D!U81QOLMgE&J;TekvF(0#!^>$#EEDabU{c z&b9cyF;;2IqT@J&zj(kmjnA+gp0h9{G&yPb^+I@5nmXaDu_XXcUmLpcHbBTn&I40< z;2Q*7)i8isRjGD}n$(7cl%4^Lpw54BX4n&~$*AqNh$gR?lMHr3f{eOf-@`hsC|CZ- zK9*C!fdf<<68N7ga%#Iiv>LiHlbTd!Wnf$A;n05-d1kOra%uIi;JapkU>+HD@`EWBw-+AOBzlFuIA6M^tA>Cu~jCC7uv zcz3_y1QbQm;wA6h_r0-$3v3%)*)3r@U|Xr1Ph=F2Y{63m#KR9Hab#d{`hOc2^-D`` za2mbNv+dt_FVzklALZjsIQ*TdFx6@)EsnyzW<9~;);{QYv4iLa7G;fDD^F!T7RyYV zT^ol7fD@&C+cC@T0d?Fd00p?aA5O1s1`a{Z&~TV;d<4nf0BE)3%{^<|trCng*8z>k z_$nl7%DQ|%5+N%bX1rIeK|fi`wsUN3Neprxm)31PeKgX%`Fln3>9Tu)9ma|!IuzF= z&yI8Kn^=Y8fWDVk9r+o{u;E2^(B1-6s+t49~K^aBM z>ZEgvlHW)nCbA>k#~V+i`N?DLphbDny{-C-|Jq+F=GS82~{+348VA&2QI58I1`qL^)O{FyTh61mUYGwgZ)t&Eg@EuV1f3gZpjOA&J0`}0`FQazIfj@h7@qrIIf(t@4+zKsqF=4+7G9>F2eKrc7y34`w?H4Wu zb4g42r!bF^-js_6Kkj_KC{6a6aZT`NYnK`dkLNwLI4O;Wp->?E3XX<@Awzk7dUQB$ zCk6EL_grCG@||MV1Zb^}y4=Y0x5vW>&yCi9XJpwLb>TeO%Lu*8!@rB=KNuxNxkiV- z{o;Ppu&k{pr7d`UII&@3hc>}g&0{&l)CSi#kpf|fQcIFG+JNz)%Q&+>R$eC@xTN-F z(6wj&D=xRvN<-bJw`J<(^JWv8-#R&E%Q`aG9S8be7?CxIADg7Ae<+|h;8Cev5!y}gIHb0&b{ zdKNhw5Q~9lPe8>#H37%nc1Xn_al$9e7f11xvd zqFTwS70aF?RWr8}>F92Y3xmFNF zwcth{NGoIAd&Q4(79VBi+!{mPAXLyA|2cYnq(y)p&~Ljy6%{pnYKE43r^=ooV*Yj3 z;_ih^Rkx437)ug65y6(KOCkWthgQX`cd>Gv6U?jXu)tq zqHPw7o~e2KJ>+#+o4|k^6b@KU!ReIyal<)AE8SKExXSQ5ma`P)4eAu5NIVAL*5R|I z(@=1Y{0gryJxEw@n=w|Lgm>mT?0Fd>>CPJ3{X+3Rf@Z@_V$|(@|NNb4Sx#psBh+J& zF!(RgFHcf57enhZA$KaDZGY#k_1|jj!G3qAjLyk~NgTa6pGC6EKB!-d zgSj8yaQb+{GQPB9AE~B&ZA2kibYmk`FtR7;qgZPL%HtHqrG5O4moS$0KC> zcZa%M;Ah_zD4=!oh}AJ5anz1cI?d64x8GY4BVrdd0!0w=Y;6<`mh@ z&*YK2MNaRk#A@@HDH}sJXjNaJm*NcQyE0-X0VSl`;&4g}W1qCatV{$V&~9NVpfWPe)dZIo_q6_6a5AtrP{QA?DMl-FT47_DG@q?C-fSr)s zDNj~=er&=I_H15WeFfKUe+oaoIYq9yGOyWdRoCQKhe9ni9d}j6bWfmub4qt-@9IO+ z?(|HgF?)W=JGpNYS;u@fFiltSv#A*f;FDrf`br{fu}{D7sfZ|w(LRR4$@AaMhBLoz=+hmZq8XZlU-@T`yRpRg zKUEThYv8b3mo0x2vA;iHp?I7}G_ug6Gf$P8WJV0>)*Yfva^Q*ZnLk5O8Y}*-Dcwb~ z33>*>mV-@}0Pyj2Ur+q5r)6;J_4Rrc6!T-Zl&i}9GUxF!3TsQ-j6~jDqdTbPXo@QM z&Rvdur6oy;AHKdc(0f%j&5%8g@9hTxM9aj>jH-@j@%1K7sn--QDgO})rMBcYBA~Fm zdJ6W=Xa3=J?_`QIBX|r~1E9e3&1vy|W1|(-lu{0a0?depZb2Z(hE`CWJ``LNc z(>}cP_3iQbOG+~=)AVkXAo$f|qxT)%3f|Y3qL1;Of=5$~F`cH~3Rko12?KfrbI~NRRh_@$J9i^umN*`-B*Q&T>1b=*_}<8 zb`sf16#y70h<0CGyN{l>cNgz#wSi!;W{U0S_LF8UmwI~R3zrHY>5nzF9raxxnv3RD zwx8P25e1RjsfH@a@XnP)@|R~x62EXeG1)IU@O}r(;~u=FLVim!)QR@Pk_!vb7xGaz zCJsI{-Y6WpoINfd; z#TE!2D=0jYCJ*)dSL;cO2{WX;04z-L>$IlYg?-P$*m0(M(1QM-N0*iHgGZ@}uL0V^ zEFVO8LQaQh&?Q{AY~C69{|p&hkJZ>g(&HzF}@tN(cdIa;yp+-vp+S% z=NT}|P|b2RrAs(Aok+~amva7;LOfOEgCDi8f*ZWZELv~!N{k$tY6Ru3GoWPcX@0uz zMW@|p^?)m7WngVkNi$C<&6RdLq=>V;#Wl;xIK-OV>C%CCz*2bQeFfXG$7%)L$Sk|Y z``Do*>zLNMpFh2;CC7OO-JkpcYa|*m@?Q#vrH#x2wgVbE3kafurv{*pvv&Rwp+J&G zR!>(!8h6v2*Ju@5n-@8`)SG}tZl~;rjwQyfFywa&`=mqdyndrYPVpYfd_Q8uwaB9d zsUWR)@E>8dvz$IVHR<-h@9Dg7k{m<-Sl=%&dPmm%Y_;|Z?8U=xeL52SkiG+zH8Cy6 zF|7?RlCY+Qk&mFY_W|b8qyF*~lj$e0aE)k)cA06O%S0CqHm8H0%yp+Cj0aX2W1PIZ zwWgwRM_M_H48|8-9VJb6+jsPQ!gk1m{yWBc5e{~uGJVQ0{2rA%11wEyIK!1Uft-ic zKWJbaH#;Vwpch2U%J;mq<3J@i#bzbYPW9-+gsrnl_`ZE~1rX!8JyXEvQ!WO)=H+i8 zV3iG2d6uNDJH>AgdH8u=;jdYPbqSH8ObqK|!m!Xt?%<`KX(yRJj&?tSZ*91G^J{zu zsh^YT?_YCj104J~Hjal*aNrV%nk2me(t2(gGV9Mg=#1K2MHa^(+2Ky?Mms+xXfsQX zpdX9Ll+~l6hV+>dX6@3wsU9-|I^pgsBvHvK2G_?|FPIDt4`Iv#2?%jgj#td1*GwIv z>Guv;NUNpwH<0Tr-8NhTp5_5xJXm^ZwVVDsV>}u*D;AZZdUdbvI#YJeRCk@d_aqxt2nNDi zYaL;<+|iMIW^B??1sI1hDfNYRV}XtsFj^nvlX$!o2a1n%zJ1h8!U(o}{`qFb3+^}$ z<;r5EheCr>1;_sywEB`Vd50_N2$7$XIS8rYH%{QGjRI{_+63&W#*Bpy#<$mNr+PW5 zx_k3rLD;Jq{RrNiRMat9r#@e8;Qrt2oHp_}``eRZHjeL!fWKf{3C`G`HSsNRxKNMp z12LGsYg-K+uLa9Q$1;x4r)Eb~;Uu9a<5V82ua%?bBRJ3H%I{4}SA@-w_qnO=R2lak zF=PIV2_FH8l!HBLBMhi5YNio#%ziyot7a`eIHs#9G zf{um-LnlQQ<3L4srz<4Cq&*@hurJEhEb|Q6kE^s!u_GKS43SdCSq+B(>iqWDFh7Hd zswfnWjSAY^r({-6h`d@dr(`N$7O2NROwGP9@Rdtm>?f=xO~={2W8{H{vV1 z>41Y?o-hhrKm`H~J{HGWZN*LdU|dh}e*08WR7OY`e8!}0GKRJOxGVmgy**{ej9|4X z@S7>SG3aYJZ$|iYsP~u~jMF##v2wAJ#~3-2wP3_E-4adRB%YkYWChIxDhqVrBYg}# z4xX1i`pNJ5O!8=`nSL^i9ceavV;=6;6Jn56*BFl!T|uQ0;MXGs?^9{BjMOzubNn*> z2da->j0+6K@Q_`#RW;H4G#f=iVI1KDXSfTUtm)SzLiW9M!Ti_RlaPIZ$Hy4E!Q5#d zH$SHApc!q;BJc~~OBg+h$YKnzrfQ3ehV?0#2fVUmM^Q0^ zFsANIAvA8rlK!C}q_edJ^P;XcD8^s9XM-TL{%B;|Rd#m!0wf@|~6YoO{){+kh{oA4PB(Ea5U1^6Cah6c~9pYR>TmUpTtoKSh)y>@>y zW;kIsC$+Gt&Bj1Pe`zRq{pH$Uw`Vdo8;qomRw9scr(0}L<$gUj`W0<>>eLN(2D{|u z5fhr9w89gvQWwk#KcD&lPyMI=E zB@t|Y+?rf}MI#k%Hravja&yEDxke0mXcAmHH^n&oeznBN`)50!iw}_B!UwRB*!7*z z069oTnDD%W!X9&tA5yF_kliGr7WdGPIsd#x{hp5&J-?(QY|~7bIs0rh^~Z{XWY(?! zAbEU{2{izO>4JG^fr;qNmlchN9y=E7kQ&0}@hxnbkBNO#rN(sfsF@+gf}YZ-rdx2I zc1)Swpf^nH;@$Km%0HW`MiwqsX%r`4A}dY$$F44oe`n@Dr(O(>O8FD7W+xUbvm#N2 zR9WbYe^^`T~Q-lO*_TqMGiql0RCYVdesEX7fkBD|=H=jy~Ve)`ZA=<4OMLy<6#if6C z|N42RjkJ?N#BM^OFKBEdN79`)Oe|TyK&tD*ul>qQ8vpRy@1e*8hD$bY!HHfGbM;IV ze-%PjE^Po7Sxr*{SC+gZ55EU%G%gbF?R4K1NHaD>A=Lvw_IgH1`0c|jeUN~xlT6Rs zhlUkF^DF9N5oH`X8$+rn{ZU$RPkAdmIUukPRQMMR$FAJ z^XFthTfXO=tv%72=P(FB3Nw^{xtX&I<*LxjL=>!)nuGj(OA9AUfH?M!0FU%h{IVbt zRD}s&7uL-mHF@ODGhF20C7%dsje|2cUJ+&r-`EX}TpXU(n^u5GJi?Xgo>{=en8v>q zo!7pD&Ot0M@FTb{bP7z=4F$XAo#YM2TDogB|As1ERH94$e<75jbJc;CZylpY~_3Y=0(`!5wNJPc6~G88qCn z0>dM3rmbmjtS>mz)!%&ujfWCF^Go?5iI!Z$^NFx;w`spt_xzJgB$BP~Qnk(jZ4USX ze-ebogOiyd+qHWWGNhQixlFV=c4Z7$?d88MN*CFAAlYf9-#OI;jFshbni0eCO?mde zdn+oGRPP?U4Wlvhkx(Td#soTKkFcqSugHEn^*N?nXqFy-4f~HBsij>8>F<{;6dDUJ z4&TROcwKH7#g0bY;v%c9w82_X`lvXciuquM61~rWCsn31Z|FKP-t}3hrt6Op`IF|g+gidO zUkno$PM>Z~h+esJkVcXzK2+RbvNtDMv%)XQQQJjj+7 z*uSPAKy$>ck&agnL=yi4*jt2<9+EGk(sf#hW;bS#}J zXK{xpw@vKJu&WV7fyOu)csS>k8w_e?%O89HFvf&r5^{C<{n>f$+-c)O+sxqOFI4T(@8z_pcceu%yoBRQ4ly?dp zU7&plA-jiFbGL{cA=qDDf|y|B5l+Dieb$vdAR9aznH{k5UL3yh%w_vPvp7&h|KEFM z3Oo)BPs&yX6im~VGZ;7yX`bTZ3Js=GrIJe*RHH7jgjEvPX|OB*-2rr6cRQ~*pZN9K zkA)VB_W@0(P=bbl4n-atD}um4MS|W=b}dCle(m2&RAuJ6AYc+RG-Pr)K|CT;>H3zz zX*M}@ndxi`Kp+o!^N2S%eA=%e`vG_|_=pAB2OAtd<4jXW)G16JiJCAL4vx!tx~AiPO+PF2u0#j8q>>f z{|vEH6phi9J(h;k%QWReqAU3#^h|ggk!EYat4IoziIIHo494XK0P*?(gM2k%se3U6Yq=6qWJHHe3blkLu!XWx| z(2%gKU8C~6n|Kxz8;uIPvSZP@x#o07EPowYMZ!N%gR4>9^FNJ6{44j~CH#-K({J}T z{H5{=sgj=$DUWW@DIm?HkM}%%eJPw-#Mz^%&&uRQBdCENKAO)xS*{5;dMSB1syc5u z#tRlXOW5KlTKRULQp{B*mxFXjY~fh0X9}{5a^flLX9hc}?AC_A)KFSl zhu(gFrc)&uTn{^HY$LXBP1`7xDi3){bFCBf{>^}bByB9pOme44%Ro-|Ga&u<;m#yw z{0Dy}8FFWO5b=X+jlUbBB)jsm;a&Z&xw%<}jd|{Wnct;Uf{xjOj0?JM3tA@B4DYI! zgSRVi943DNe=z5}0LyG}!UrbT7L;#}ZpLsTx!Mi3Bj-}^%Sbr69M}Y;+CAxn%b+yErOKt<;hW*+4?H3O7>9`^!c=y9jvl^Ncn+O~n80hw;2N_!>Sx zI<1onDXABR6p33RFn(sN$bMH6F@& z85?mzJYbY861%DwOj&>dgYuZ(cZ8yKwvxP5FE3+lHGwrKG&ohV@0=>izG8$wGcE?e zDe6m3|26d|OrbHI&g!YaxYW`^uOWxF4LTo0TD0w|*Cz)RMG!X(mb{|Ovl&7Qv ze<~x=qXzNc6~RhdNi5oE4owqDa#)2c)ufPkFiK9vp=VSyP0=7!cS7lA}Jo@3GP$&iv=BI z)7bL#*#BH*2rUAa@G?Z#M_$!1;-_lICxH41d_An7PM=LG=H?d(R&kEupX;OaK*{GI zrrgjmEMX(A<3ygIAK%G*o+I($q_VYSTN%|NcFkj?TF7fso;R$Hez&~ST#4w-b85Kv zc_LBIsIs`tyXPNjd{)H32Dp;1fEdHplBcOLPp40tQ{xV*dp$<fs#fRb)DpNXj!Rr&sa26Nu?UFF6v4X_?wq7p52T7TamW@PytL|1Up?`+nfx7 zyz@#=CA++0&~a>H?2X=+`FkAvce38bf`VSA$S>gfjM)O~s})nR&c?Qe zEI^A{x$Yq`gFg7oW6DdN*$&lqA?`HGmxe_WYQP+1LS@wCohO`_Tkui2Y6)5-vyl_9 z#C^v{QRw3p#rfTKFOrZA2##N8K%m5Mnl`s7Be7rGD51Xw0S3t}Ha1GSkBlg~OGw#I zG@HU8%Gd)%h1vLfE_R5>CsgRvH}j$YmG?TC12t!e^9kIIN2H_<{({|BKSJrJ7XPo; zb#122KDrtKI!(3I^A~+mm-ET`y%{yRu{jXq)P(-CrDi; z7@1F2G#Q&BpiCGI@HK4?8Yb4^%kjD|nNNa+vcX>5$STbzDUP`s0LKew(|5#f#M>zN za+!#~&gW1^Bl&thhScM9)M4$Vx>t$Iwa8_u^w<+>ZK({+UITKar?V3&rGjzb83n{eqcyk20 zxeo+{W+KfxigJ#ilcBx&CNrUm;9YM-u29 z5qMNh8|0wa>fmRfUym@W`~AiZTUe(cY)Gu}mi(>siv9LaYLO52Z_;lxBS@ghe3*iF z#I6q}Au#fJj1TJ&i<3vb@`#5S^4%9?(A5L+;%m^=5Aj0Y^$`krr{ePtfIb>}d+C5f zm^34Ll{$97j*`RqAje&rdb+n_swTZY)zCET+FCRy@9y^ni@HPcFJEK&<~&_aP!s}T zd{;=ookaX)(FiNH5u`*ofQJff%p**(Jh2mbP>F(_Q&EdFaXW9qFL|~x# z0FJF~LYnA*n(GFthrR!O3o~}ZF?h~YT4M~?SsQ%rb=mj)-cE5Dn8Qk!?XBu?$v)7r z1BxQMz*%fAY0>a{h(FN3UZyzo_Y4X5WEf*SKveTrpHXTDX+)0vya@Y{iNisLOqR75wFJ=pIC)lKO_-J@cG& zSh?wTF&c%J-R6G!GEuf@yVmM_TPhF5`+CHC*M}J5(j=IA>eVL`m|!qW{pVwym;WX} zHpm_*0Zr&(-SL98+`(qLyO@T@`odP&pXY_QAZx;- z?WU59TU;E$i<;_%SMaTV*WkPVcQ%(7qdeejSI*;uS=o8U4LQ;U7eW*Hhw)5`+WV z52}YDovkm_#HOC~v(q^sE<$BkXm&E*$zAiwojEhaqw^8nwK&p>Hy>&NIn3+vArUsh zjciG!UR&U40SRs9K;3XNo!l~2c#7D)h_J<(l<{P^3yuES6gjZBKIQq|83K?TfFZZ! zh8`5Kc)&!|-ecbTDXb0HIIxm87eq=nAX&@9N=9iWgf~EbAK?PY!Ev?{$!b+M9>$oK z?u`C+#T7l7g3cKzd%HWw`z5*&_Qv+kAYjbJd;wcDg&TH>7=e(V_qA}_^!%q|E)1Kr zF*|jHLcVKi%FAP&`_zq9!vT-TqdR9m*d!d!5ulvM9JApC`WO_V`5$x66s| zL^Rc;iuT(UX-rAiIQf zbcWe-z>Lsc#5dFM6f_(K{UDY-#qZ`R-y$G?6LRu`N>1j3_P(6YTPc-)*pBJc@xglLj8Hv_B|iH$)`9h(tp!e%qx zjdE*IUy*RTij?|JY~~m}w#LO8f0z)OlQ1lQ@nVf*BLkFO>IbWUI8bxZOgqOsc7DrK zbHl8xXp#J0__8~Hw&EVuH;(tA-Ej5$ESMm#+@>d2t2&%WTt7GXW_Ky9_4P$R$>7We z1TQgq;`#H(I@>s8ZvMQ6Pe5D7#=P(^s8oFEViw5?nCu3{!#iH0QK=d$5em;cYC^*F zV%ywlgkkCy#12S?MAA(>%Gx31$@uSdHe@)DV*v^^D zk|i-}CUOSMLlC_E_e}Z0N654S7EWT{c!h4Bg4o`t%-yMol z&28)Ji07En0dk6hnVQxqechHuj9#S_zSP6w(dhE0Ea3%Yamnf9wq|?gQ#+<*zS{R> zAc!h}ybJu9fJ3du*H{v&TY^J1Nl@Lys42u*WVBBp-BjIL#0LR_Pe3{iMCMNLVvQT7 z>Q>>~fJJ2TNoV-)%TUP<39hiE#@e9P8RoK2M18Xx?pTP^A?&qB1SxKIB4(JaL#{vu zPxu>D3(DM6GYLILUflXufN~6$P!}Dta@4G+!!WYl*Y2iGE!OC>sOb4`6%YvXiyNQt z4dgxv|HlXj0RaO(Ng)o0B2EF52Eru2z;LA)B16NZ99lq%|DV2OM>sSRBuE0xf+2VC zf2IE85nPSlZ6r8&V&k;n2`Qq@)!5kJT8}VxeMl{%SSFKGWOB)XK@8W&CrWEf`j1D@ zj9*mg4i@R|PfEwJ${no7=Ht=Nf&%Lmu6vats_f5YhD_JLvmUc=ef#opWJbYdT5Qhtg13vj~2l(VFnn#s1lbNkV()LVt!2mtQsDGu#TEKR?;0oZpk8* zVr2H&n#B5!paZ@@b=k=Wd<1mI-N^?<@Q&s_xCD8<@#uaH6F2jwu90ffPeq>5<8+N6 zDdhK#2;9Ijp5Sl!PBVid1DHCnP=O2t57}1q&Z_e*P$VJ0E0Uwo@cg#YxrIsI36d9q z=FUo5rTOnRx_I2`urceu86Qf32sjjGdRYrmE%BNlfB617iR?w|C^hcQ??=;)Xn4OA z?e00Qs%wQl3lk3|oA}c~fjfMj%vUB05G}*{$PfR-_H<2ALM%LScJ#9VT6*)Px!Fa` zTzDIV^aXlUa6W23iC--tjz_fy=v?t#pod$`v*uA@N;IQ!wNC**IUQUpfh?GOU8rQL z?df5lw%f*(2=wq+tZ!z^5RP$Px^-~VI-tP)`?F7^@+E#92Mi$ERQQ*Th6Wr`{p>~i z*_qZrx~&;-9W>J;T+X-WaVr^0p*rpffU60I?p8^vB>*`=q3@wq$rW$AIo0hGjjUs) zg8HYr@U2VMtCjM%e+^rTR@jP|-DCpw0@Xoy!{mEy7+XbE%c^EJQ(75}^N!mMNG>+# z4M=YF)m6t(e9y6K-F-+cNWrMrccGaPkw3$&w~T_;03_%3W|Q7?(U#zw#2%~Q8qM8% z1S_i@f(xSaY0O*bW!>s5ww)O8=q~E$ycx~kv%HAl+%Ir=b1{QntMg=@KkmCgM(#qi z)Xr8+c>A8P0U>V5Yzx6Z5z1P@)9HwEukCu(UfDQGw`;9Z?~3iZ{T`(Dw%MiMdjn?W z18$J6;_Uf?r{QD}Cpb=iX&4X~jum=ov90M>A3onQTIaeC z$&Bz&$2>h-`A(Y~0yu|0Wx3%CTr=efd2|ya&UUO3GNVRN`^PtiYeQ+IiTU%2&8A0X zg~kAmL|u*stTq@o*(gZNhuk_?Y&O0gv;*yya0uk2x*G#1N4p3VLD;g{> zW(?NN(8mdLTZ8rd;QMDyD%>MaC=c^k7exkC7wHsYzkp|}TZmfW>Ggz)U2hN(y24Zz zIo@`a2;j7RAqU+4LZEZUtInUZoio2(+FO8@oJJq zGTpfl9CMu)3re3g=O$K7JzL9cLncTeL5$3p&oET3B~pm%zul zHHUW;!MA15xJOf*C+ZWYpHDmta7(5`n5$u31?FkvfaKA4ma~N`7thA47L|uO%jc6O zllCC51=*~e^O~YwTQL1{y#Fm6kbW2ut2Ag}LI2R#)dl4PC7bA8KVRjx1i> z3|*%n+-6R^;d4;~?P=4BSQFK##MVu#&k!URs&kr)Uv8SPP#VGKXncW$mtc(C;UBC< z6V~(TmQqPABOrBhSy%x7!*XTG=>l~P3|eTh)Se3rMZ)FtZo6_KvEYGb z4Eq$+H#_E$IsIXU#4_w&%cLkQyrW!T#!n&YSwv1D>xD&T=f&H5K$=TI$i0_+fS{)3Ay>XYoWnz$%lW#%=XSsjm(TJ;R3J}#KvbZCZ)!zD zYLn*PLuljWIzz0)`4ySWL;hz01PwOkf-)@+vGUiiDChG3ZyqkaGC_*2s*M<0uB++) zwH6Jz0)C8p+UXfwie2Osx}HSj6sjIDy7~b&{2B!iIVCjb@5=To+FXS<9}0Ho@4_Pb>Zx#=E zNoJO}O!x`B*oRWst4Cit35ab9#W17osp#x(7ekm*gMqy&%rE|x)EF$!Apc?~!K4># zS{3$ZGk@ajZ_S@iBk%AE*&CpTo?SCDv>dOio;uD1nBMK_G2Tep%!aQ00r&B*$L*?8 z$50MW;WG~S7{_%}4uQLdKomQ(dS06RDd}!pqx2tDl$3|qb$t6;Gfa}&C&_%VGe`THQ(H~k^14|e z*H-tTQ2e_TF$f7GU-}a8?P`h~M$M_J6!1oIgAPK#8k)Qwq9%^i>YCy$+U(SB>Z;Tu zp$)g@GUvB~+U3_{=PI&Yx)LViC|}M^Z&a5H{}%4~q@;gBd?hf92N8ACI3Knx7r1>j zsCHNN0`F$zXi$Y8?cZ+{Uy&VR0LF!nR;+=&2wDQ8r!8_0+|9ie%Y{S~CzAwOSjoXu z7@i>b3MbZrF;h!-F<$9Cq03)?2B(S>Y4-TgZg_tn&O&P}-1O3?DY{T^V+pa0i!mHB zwdqKA_qLczg;~Trfletoe&9x;DD(fgnl~g2|Fp+O{YOs_c|_GB@T5m1Uu40N8g@#R zzL~_dIpMoK9gi15hkB^=W2tubW^uD*%tySB_dPWdQQmoE;BJ`$5jxGQ-w9vVK~T$6 zoqG}60$qWF*6B)&>&d>^dGPM-3ueJKtV7LL2TjB&D+5rAA;{s+qw0kz1hUEtRph@y z^#=l)*F``OUs_XL9qIYNk%F;l}P*-F_$9{8Ex zyr1^YK6uG?Ulr7jS$e4i(el~!NS{;X^`pBs%o})fega++s}=CKkq3H`&N{b_Fb$~t zOfiNuR? zJC20PUa_UkHy-)v6ZOXiJ&emwr?)d$hl*U6&QIR7FmWh8+Hf-uaZQ! zHUt~hoL4zvgZvX$o~CT>Q?C9P5W3ndGF^U`56 z`mtuO%(5ccb%Qz5=^q@{%=M1DBFuKJRv8cdpn0$z$Qy@2U~<745q^?$wWu*BPTKy- zz(@p-1_#Rd_|RY=t;n70L+kGvd2|fjHIgVHuBt7xQ6d?+4{Q1j0r>WtjAlc}>^nM2 z#n+HSRy%*b?vTq7BGnBW-~?JY&CC1%C-P$X?d{(T$F&pVzK?A#3;!egd`iroI-9IQ0GYZP)cyOZ);ga0;@p4?ml6nbh5_ z`_#CY)YOO`?T)u7iP~}Xl46b}ei?3C-95G{w|TKj$y4};UE^f?onM2Hm6Xv{_S12R%7<4MzwO)jy;H`e!sZt81 zzW_@Z^X%ywwfCNX@Vt#goNFoa#VZe%jc2|292fD2sP(&PM49 zD%?cAUfDR!LK!9K(1c5Owwm=w_!ZTldu0w{6U7ynI%7Dc!XvgT>toDx%Lp!{MYmZw zTvh^L?)xp1w*>A+veDxA6JEjIsL;b7Ap1-hJa!g2d8K#;pd}RxFgBqljEPFH@-hU_ zXT=qSC!lY|(`5#+%Of}1(m8UXdN-%2k)HpWAM(_?AJJF$4tI%^RQFc*QKOAI1LGwu zO~+z>+al9ArZ52}2)4ywVPo-cel2yE($=*VwZyzl+eGCi0uh?%@&sl0;9VjxNAnYb z&HuY>fpGZWC9?S}bf6ks$Ujw=8zvERIt8!Z#PQ&sL~G%FEr1&>v5yf{ zj)N%XeWy5I)IS{RH9gE64-ocYoVR0aN@7sVA&RtpMU2y%7k&5O({oQ8?=t<*nPDq1 zSMiLdX7(e1bh>|VQ*4woeNZn}F*F9|&!X(|K6+zj1ImEDPk6HLqdM#OZ;co2 zX0h!mmR?i8{3i|iBP9yDBkZ6faI27^WD+tm)tmSHoCM)7+4 z3k7a4b$sCQ+HHDE2H6ARG>9>z9XE7?6y^!6uoS`Db5o7YLgqgTRL`4gk>3x^ZBdj< zA2iA5+y4GI?m{;WN_@dW{t8F`{#C5}E%7CQ`@eGyWtWr0k2(sq*wU;n5dr_8rH>ka z3i3IlpumrOno{&jYs8xSG4z*V;q=b8c|gy0NO$5V^gLOOZVFgnl)33!CiE;MNFipe z5vSO-gA#iy-{v`uh5P(G3k4v2#2XOu5sD*_#wX|oBW;dUC)YbnOqeo zY5{%q?fN2wgXR0V@nZ*yh(lFOaxvO;GN>jrcNGaL7DwU#Oo22`q)<0`qBhLhAq1L^ z0Acf=j;QzFBWC{Y>1HJmv9T5PS%e!=lfi>Yy$!3>dak#5BwT}uC+V#GL1~B`BU(Dr z05ub*UrYSsw(Dtw)fKRNeYf0^1Vzl6NF_FtVWsTl`MRq=2!w~O;woNa*RCRKdu3#g zyobxZ_W1e7eQ_vC2N8;ZSwAb~j+fLM&{x8K&VkkFD~RV4ZL*%C#m#-stQ8ocNXhF5 zqcjU`I@h$8v`cLegvtjIK*?A9^(SDN1ET@R3|dGf(pZ0?M;aQ0LXy>HWqV~Djcm}=s(ypS9%lxxSXu}pNlr3}th*g% z$8WPHTP{|#9T}W69x3Pa4TfWp*MU=9wzJz;}ipc9?))x4KME6tb5<7RUq;Uji&4*0RpA|w|sr}uh zs6X(oaaLBorYSFm?IEG2_M7EPf^u&1%FG2r5+>Ea0Heo?a4#x0$7;x60B7#x^OCbW zyM|Row;LXUC7Z|6)guOi*E_mIVUL-a=L*K($og^R3x zX#F3QKpb-|rR(hJ(%}A$M-i+F@uZ~W`)l8?<#PhTf2(FSy zZROY6X#^0-{Hp-K4nggt4BT0YkM}1`y0FZ}U%<#H*MIb?e?Pl$Zk4oOml~>6|NIvX zY~Q`VXzcY>pfQsDIUsUfxI|hEbg@Qw$Q#3>`I$6}8ksgNK%eK`A8ABTh&E5CAHALb zyd`cxWEIFJc`Pmh$oLYxcoG59sj^7bS>33vRRwptiNU@Zo}8;M!d}A$u4y-&02SW< zAQnITUvK7@J%hXI=0*N6bR^KdyxNVw!JT-XrAd%_6&-#x^f@c@UGkgao(XHFXq2rL zb75Ey@f>4{`XSb6`yrx>g~=YxIT~NFdi715#YAwu74l8t*cDi$2V(ghM}qdiZI+-q zDmn_o!tWRNIB>5+GI8V|>b(4uM@g##^A)SvV9Nzcb3)NpYRJE!zS7)+IhTW-eLF zq1d>mB|E3Iw8(w%-%Du_+3pA_%h(BuCPu_^JT%-I@z5BzZDqAJi)J=DOG;;N%~PY_ zM0{i&K8?i;{D@RcpTy1Qv0{d|uaPv%m&4ROT4~~`!UjcL@hdsiU;?d# zV{OvyFqq9yNU9IQNia{^5p1*xAFV6nuHBEsnKG{(g#qWfExL@jxT}ua`J;$$(HuOj zMI#>2WY2euneFZ!d(!E&4oG%rKnt)003O$*EfgAe5RadwAk5S=5$C!p5S_J^K$HuX2- zUpOV%s};;`n92bbv%sz`iSl>}MtV9TgIzU`IFFYSz;I|`vGGkN2|W&SnA?g3k*GZq@w7E zp}=3GhUI9jxgAtRz;pzaq>>gD^xs0X9A%(bw5qRJ4kKFidzn;LkP8@w$W=Uf+>w6l z2>TN(xI39amTGLYpIBu=z!U3jl9LS^u2l7MRQbDvOmFt;NQpZtH3gh4xf|i7^*~+Y z?YB{3{d;Xnhxb3zu@T0?Z;WRTV$A}E>}upmvimSLpGI-ho78^kj!?z)|Gxeuku?Vm zF!mbkGo|D#p)o=XI&z0ESJbWkK2w~+mwhwMGCiW28#U!u)Ci5Hab8~;7Vuu@^bXRg zvvZC=&dBzO9QW{O3%IQEKcN3l3gC6@@HID^G>lPea%g9IX&+XHNkTYv4Nk=BJ8H6a z>aemL$e+tnn?L2UDqajS0FRt|O<$ko8yQB(3-G zTigUm;J|azHdwRF;`A+d4hx5As{8GLx2*z5)k2he#uqLwyI@=++->ka)ZGzm{XQP@ zBU{?YCXt!3J@T8BId~0!Zbkc5QS$7jt$>-^KTMV$k(yhXai}TQv*kjTeiwmHXd6;EyAAA3_DZgVrNhIJrJ8HX`O8I3y*6EX|jYK~E@Dt!ASv zh}L{|W!?H@=tO^3bDWKY4U#~Mqit!tn8=Bj-3iFaB>Afvk_>&zmZGNk?ei-Wi_{FN zRy4jO_^H0)nKOt+KP$eNckt*wqFQaXr*9KU*(n$JnRhg+{#@TV_|wpC{d})@UR%8v zXSDq0jM27`Q~#zCKgrlvBuk5$Lz!N|34f)h!KJtJWHnAN-^hSjl_?GC;RpVHS(ZrS zbcSD8a425`g9fx>2!ZM!VKEsmJo*n1HUbVB2{!FddiBqosLl?}pEQ21;aN<2MYS2S zT7r2lEGz8~M#m$@=dZ)oB+swn7_D5bAU!k)2+gPeZ!=U+F5!z5 zf$b$2*(NLI%TSUDhU^sZK2h>Kg!zk%{_Vv{DCiAav5fN2z>4{um^Nc;Bma!`hEVwi zBfs`Ueudne>LX=&UNXNvOL|!^$>^LEKQDWF+?3>{un*NVayO{N^y-&cC~7jOSbE8M*ga)^^dDdZcaSRp3XSR4l;_ z{|dlwW!A*Rw)B)jXrsAk1Jny?Zp7y*Hhp0J=HtSzm3}hRj63rqhg++{|B~Wa0ZsCS z*+Q%f#u)~W*rVk095w*`(6FpG5+5GC7F$g*w1ySJ{F1!zaXWe7EhUK-)JvG(^&y*5 zWexiq5-!EE650;bN4Wm!o|p1fnW)()(&tfxnYA;eZ`4xgrtO0hg|r&a`?f#<2ZRfA{{9l} zIvJ{E3@VCU%!`SETjLK$5wL(#-4XoK!F9_H6j0M)iH-f zeE7oNNFopdn@dNK;P;^8tw|JcV!kILjE;R6!}u^x&&PfPv9L@?GzP--@@9v&<6xrHVS4$O0_BzWJ=mQzr{tW9&{t3&jSC)zIU9^a z$`<_om$5%>IQ-?Nr`mWDS{$XBwKMgt3-os%ESxELKm3*c7~S3XnT1?OnogHk0c{*L zkN^A!BRsygKxP|&SkIu^UsgBkix^@J^@Cb!9CQzQ_H1Yb0H0x;_^j6^&sW7r@(zgK zMgu~?zizY7;}6+hkD0*dpclsPGv}a>pMQN&fmYe-K5q<(`O_{JIa;*a1KTIFEC^2i z#8`h}XJ=Sl<-va(-XT@wJtG9?`V+7xp?4FaFdjs&yGHrt^+pb7Hkb5FvlrWczg$uv zHVi3;?vn}Nk5?iV)j4A}#ujmvZtlA5t_IZ#p`qaX?w3@Ms&6m`l)X9igA;}K@bls@ z$7i<8Du9uSpv(X4on5krrzl!|zX3u3-7vRqskXX47014?JG#}Q>Hb_jPf`{?W_BqU zROfDj9|6ys?yiE8N1HepPoyw_M#tpoFS=Lm5Vk_t75_1D*zEdVwge;YUu`ND^ zfbWNbNay-U4I3G<;qmhDJD9=HjKh#ztAf^3u0Ty3Z%>qONmpm0&BI1&MXrf2(6R;s zE;is(L&Iv2ctZ6$awu^pNHk;v8Th#7@?WR*8%>grt|uHG7uzUQNKEZ zyW}D@EGz=hHuytIHC13K3Bg&O!I9esHZcrPDBBX>fr+Z3@k ztbFd7`P!@lHY^A2o|TXTBY)?nD;fZsfY&uK2g?eo}FeG z`S&K4GvZk<6!1t&97IoG>VVeC68Uzb^Lpnvi|JyW$c|vvT{ej%6;+J*OK=Bwi>H+# z^VhDxIpH9F7$~#@uT$5lP@5KAFA}zY5C$x+tR`esg0uJLyC%cnq1TMU!qks)RlQRm zcmHn)extl+>9?^DwcWrix5xLgLH0M@kp7vE9_hDo7+P;NxkcFylW)$s zwjDxD?n@;csQCQ;x@>T%ofot~ zo14hxq+4bP5*BUYzr4qPi@iT~S53Y;*?xxGM#?YwBu57Zp04?DgecWwa1Nrfw0g3* z*xAnzpB(Omb$)-m_#T>VQl`c{-_r>`_^~Sma@7UVVMwZLIfv5agN}1W^YoD!zjYga%Uuf%w^Jsno)Am)c>Ebv{E!D#r7dI>S+FsQ@3A z`ecgVk>c-_{|{4d8Pw+Yg=?4ME-jGaP^7p^pg6^y7I$~|0uS!)65QS0io3fNcPLU^ z%E|Bi=gj+l%1kD+^X#=H+52AWx|3RVD=O1aD@AtiB5T+H16XlA4F+-C62dKmc*CqE znLn$rFRpCW<$?Rwy9f8s{|51S1umL}H^(TNaM|3X z2IG%an@}H$GaD?2bH;(jwQ#GU*~XtJ9Y2kAT>8y^EbZBhIw)wXRML;pye(whbruYV zd(bY^uBfjAaNBdW6_b|&#VXWwW6XNA_G;|K1MX2?+YYm=+8!z0K5Enn&Vvuzc+3$C zt2vnX+F=jdojD6|)NgQGM`zmsGzz3&y`C}MOt|BK20Q8?QGfrRr_ELi zQPiXWr=+ZuV|VoD^n?6hbkgX3tOb(GwV!4ttVSl8bttJo3`4YYA|C2mF!v!n6+@sAfwT0Z@2l{)H%HLEqw{l zH;Y`XgRpq>R?mu=i|azDKcr_@PnMk@>0dBg4BY=zhGfovaJ{B^@;v_@F|))_Iu~L3 zRQ+I8Yt5d5*m1lt5+O+F3WuodE&q2(Z*r`|zYti*x$_Y<98v!#mA-&FVG&x{N-+aC z7Q$S%(!D18sd@vCmZalf6}r>v6$lUAdiBn(c8hPo-v8Whj<)*_V@NZv-UPhw_Rd!F zV+8U>>S=6_nP%yT3pF(Lkk2LAT+fNOB$*zAX)0a{jJ=Y+T2T8RakLjelYKa+{?Z?V z2x^l@#Ep9OmwQ=SF!$94WDOKdgol80E0(_%Uo;v`=Y08sWCKMTssl7B2h0<%9@qVi za{`m=T@K&L=*}`Em_@ftWL0~UjF%WTcq5zB;WYgTNta`BrB+~Qy-U0vz|J2j@Wy`W z`xfUQqrEamkYeKL(}ni+f*}Y;j?cEnk*$FQOE^v=S$+5M1>bx}`#}T9e7Lln zbD^b_IWQTyj;bjj^qt7u;5o-a`O4{Bj>$cWT#O`{CcyfU>B3%HQp`bz6njH(2a)E@S#I zY>jF(;=i4soFb}#xxKVZ#Tb9UYJgs~%Tg>^(1E?;9h}wt7y7EqjUxRa%O3rmkn%mz z0mayno17{vVwaP)+PHwO-z?A*UxMBDaWpvvK{8MN&fh)%=*$!97~(yz9?44%V;<svK+IsX>|Tx$If`2ZzPLr5l_=t0hv7 zt&L8WX1n<*L5Afj$!uDa#Ix-7A@j0}UjOxraf`raM6H95;>i_CQ$^29QA1aiQ@{Ox zb=MZG@>5mvG?AvaC=+esN6|dNAe=GQ5?N7h?a}fDsmp6hJJ<>pGlFDZRH_HkZ!&w^ z%xl@IB~_6)DoF#&iW>mmM9?S9%j@rEN&5mcl`A(;V8LFaki#zVK!UHF*C@OL<2#cM z=+|TWkWfIXvk^a@*ptXvT{(XT%`ILAnyC0<;=Qj3&!CPNFPGPlHB#Z5&p@o#hPZ{G z9vSUA@MC@Hzwn!RRdhA#{hSqdT|lE(h`oqB74o(ySqW;IIRd=vl>5KArsFw@sz$5v zs9R#nK9ADdBx65&F%Jem{p!zK5W($}@*tbBk$#SUE;aPjtdE=spWVvi0OM=hdgjwP zH2pBoE!H_VC^b2qT6CiYpG=+(`1aYQPu9>Vmfl{N$yV?2b541h_u|JF`YB9?qfoEY zoazM!m)a?nbx3C-J&9*56CY!}UqY z-#(FYbP7R{pg(U9rY~?_<2G!Il2qGvDhjWcbWNsy;I8mAqMl7+h~de&uHZ6zt!0Q{lw;)9&<`CDjImpXLOn9pZ6suf9GeJ!a&`O|2t5GKF-^j6ipEOla@Xgo$M!8sHJP?dEAxjL~hfiO5Fh-7}^jSSdCGty6E?PZS&Ps7Y)k5cm6Ix;@ev3m| z#GaD7t6z_}Db5k;kF~NUOR8iT5NCknpPzMd)WrUMSG;Vxxsm-wtE#wJ%g80nhrgsU z3|^tTN#B4nvtW?3! Pz0jp7T6oY;-Z6&crtol4V*(7ld$#~#bV*+nDF2#H=`pi8 z;*~&(?z)-QnKkfa*km;00Oc0%k8t?K4eL^ z0mb*3tCSf%Fvq!tChb|Haw^L?B9`rI8tc&fDGS0Dc`dR5l{L!PQ-&BM`cM^P5ROQ7 zvg>oWn(bO%8p8Q|?<{0$loVS$|KTMiIB*_oygMxu#sg8~eWf-ysfp9}h>O}|fKC$< z8S0AQ<%dz{B}plujFsS2CTNcUHv`WZN>@4nafkgZXxQ>ZO}7N0M`uAl{<&Ti)%&=$ zRMknI+W7{_j~x7l3nQ*N8_?A-93>aS^)c2eEqXhgWz;zWPCVqec9{}xD2HXX$sq|v z(fUt1Ya7GdE2yyC7pe4nrFdiF0BS5uhnRzl8Q*{t0veF8$6;B!=5_qei4iS@fkuag z;RuR-N`}xcfjIXc=suUw>TK|;`cz}cjKCDpWd2k^gB1sB)&9Q;*!4m@Y*u}H<5`i4 z)HCxr5^k#ct?x*@%~9^D2igt;QcW8#h}BK|2d_9FD&MA0<`PUGjv=y6)oc>CTmN